summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alvarez <pedro.alvarez@codethink.co.uk>2014-12-22 00:55:04 +0000
committerPedro Alvarez <pedro.alvarez@codethink.co.uk>2014-12-22 00:56:42 +0000
commit54eea31d0053620bab65153ab39d61e5575aaf1b (patch)
tree5f97c96dffdb6b27df36795689abfb9086011585
parentc16297b7cfb0c1708f1d84b5d0f90be0844d07ce (diff)
downloadgcc-tarball-baserock/pedroalvarez/4.9.1.tar.gz
Add gmp, mpc and mpfr sourcesbaserock/pedroalvarez/4.9.1
-rw-r--r--gmp/.gdbinit43
-rw-r--r--gmp/AUTHORS100
-rw-r--r--gmp/COPYING674
-rw-r--r--gmp/COPYING.LESSERv3165
-rw-r--r--gmp/COPYINGv2339
-rw-r--r--gmp/COPYINGv3674
-rw-r--r--gmp/ChangeLog32941
-rw-r--r--gmp/INSTALL80
-rw-r--r--gmp/INSTALL.autoconf228
-rw-r--r--gmp/Makefile.am445
-rw-r--r--gmp/Makefile.in1412
-rw-r--r--gmp/NEWS891
-rw-r--r--gmp/README116
-rw-r--r--gmp/acinclude.m43984
-rw-r--r--gmp/aclocal.m49302
-rw-r--r--gmp/assert.c59
-rw-r--r--gmp/bootstrap.c146
-rw-r--r--gmp/compat.c60
-rwxr-xr-xgmp/config.guess1021
-rw-r--r--gmp/config.in640
-rwxr-xr-xgmp/config.sub165
-rwxr-xr-xgmp/configfsf.guess1568
-rw-r--r--gmp/configfsf.sub1793
-rwxr-xr-xgmp/configure29770
-rw-r--r--gmp/configure.ac3816
-rw-r--r--gmp/cxx/Makefile.am40
-rw-r--r--gmp/cxx/Makefile.in556
-rw-r--r--gmp/cxx/dummy.cc33
-rw-r--r--gmp/cxx/isfuns.cc116
-rw-r--r--gmp/cxx/ismpf.cc145
-rw-r--r--gmp/cxx/ismpq.cc67
-rw-r--r--gmp/cxx/ismpz.cc63
-rw-r--r--gmp/cxx/ismpznw.cc73
-rw-r--r--gmp/cxx/limits.cc62
-rw-r--r--gmp/cxx/osdoprnti.cc68
-rw-r--r--gmp/cxx/osfuns.cc124
-rw-r--r--gmp/cxx/osmpf.cc71
-rw-r--r--gmp/cxx/osmpq.cc48
-rw-r--r--gmp/cxx/osmpz.cc48
-rw-r--r--gmp/demos/Makefile.am50
-rw-r--r--gmp/demos/Makefile.in731
-rw-r--r--gmp/demos/calc/Makefile.am47
-rw-r--r--gmp/demos/calc/Makefile.in583
-rw-r--r--gmp/demos/calc/README65
-rw-r--r--gmp/demos/calc/calc-common.h35
-rw-r--r--gmp/demos/calc/calc-config-h.in21
-rw-r--r--gmp/demos/calc/calc.c2254
-rw-r--r--gmp/demos/calc/calc.h145
-rw-r--r--gmp/demos/calc/calc.y318
-rw-r--r--gmp/demos/calc/calclex.c1917
-rw-r--r--gmp/demos/calc/calclex.l113
-rw-r--r--gmp/demos/calc/calcread.c146
-rw-r--r--gmp/demos/expr/Makefile.am54
-rw-r--r--gmp/demos/expr/Makefile.in576
-rw-r--r--gmp/demos/expr/README501
-rw-r--r--gmp/demos/expr/expr-impl.h125
-rw-r--r--gmp/demos/expr/expr.c834
-rw-r--r--gmp/demos/expr/expr.h142
-rw-r--r--gmp/demos/expr/exprf.c123
-rw-r--r--gmp/demos/expr/exprfa.c191
-rw-r--r--gmp/demos/expr/exprq.c155
-rw-r--r--gmp/demos/expr/exprqa.c100
-rw-r--r--gmp/demos/expr/exprv.c57
-rw-r--r--gmp/demos/expr/exprz.c206
-rw-r--r--gmp/demos/expr/exprza.c108
-rw-r--r--gmp/demos/expr/run-expr.c242
-rw-r--r--gmp/demos/expr/t-expr.c510
-rw-r--r--gmp/demos/factorize.c446
-rw-r--r--gmp/demos/isprime.c68
-rw-r--r--gmp/demos/perl/GMP.pm671
-rw-r--r--gmp/demos/perl/GMP.xs3212
-rw-r--r--gmp/demos/perl/GMP/Mpf.pm106
-rw-r--r--gmp/demos/perl/GMP/Mpq.pm89
-rw-r--r--gmp/demos/perl/GMP/Mpz.pm101
-rw-r--r--gmp/demos/perl/GMP/Rand.pm44
-rw-r--r--gmp/demos/perl/INSTALL88
-rw-r--r--gmp/demos/perl/Makefile.PL82
-rw-r--r--gmp/demos/perl/sample.pl54
-rw-r--r--gmp/demos/perl/test.pl2179
-rw-r--r--gmp/demos/perl/test2.pl75
-rw-r--r--gmp/demos/perl/typemap108
-rw-r--r--gmp/demos/pexpr-config-h.in45
-rw-r--r--gmp/demos/pexpr.c1378
-rw-r--r--gmp/demos/primes.c387
-rw-r--r--gmp/demos/primes.h552
-rw-r--r--gmp/demos/qcn.c172
-rw-r--r--gmp/doc/Makefile.am36
-rw-r--r--gmp/doc/Makefile.in766
-rw-r--r--gmp/doc/configuration390
-rw-r--r--gmp/doc/fdl-1.3.texi506
-rw-r--r--gmp/doc/gmp.info181
-rw-r--r--gmp/doc/gmp.info-17073
-rw-r--r--gmp/doc/gmp.info-23865
-rw-r--r--gmp/doc/gmp.texi10887
-rw-r--r--gmp/doc/isa_abi_headache128
-rwxr-xr-xgmp/doc/mdate-sh225
-rw-r--r--gmp/doc/projects.html476
-rw-r--r--gmp/doc/stamp-vti4
-rw-r--r--gmp/doc/tasks.html896
-rw-r--r--gmp/doc/texinfo.tex10079
-rw-r--r--gmp/doc/version.texi4
-rw-r--r--gmp/errno.c70
-rw-r--r--gmp/extract-dbl.c311
-rw-r--r--gmp/gen-bases.c251
-rw-r--r--gmp/gen-fac.c285
-rw-r--r--gmp/gen-fib.c156
-rw-r--r--gmp/gen-jacobitab.c128
-rw-r--r--gmp/gen-psqr.c586
-rw-r--r--gmp/gen-trialdivtab.c300
-rw-r--r--gmp/gmp-h.in2301
-rw-r--r--gmp/gmp-impl.h5203
-rw-r--r--gmp/gmpxx.h3336
-rwxr-xr-xgmp/install-sh527
-rw-r--r--gmp/invalid.c83
-rw-r--r--gmp/longlong.h2183
-rw-r--r--gmp/ltmain.sh9655
-rw-r--r--gmp/memory.c146
-rw-r--r--gmp/mini-gmp/README77
-rw-r--r--gmp/mini-gmp/mini-gmp.c4386
-rw-r--r--gmp/mini-gmp/mini-gmp.h294
-rw-r--r--gmp/mini-gmp/tests/Makefile60
-rw-r--r--gmp/mini-gmp/tests/hex-random.c434
-rw-r--r--gmp/mini-gmp/tests/hex-random.h50
-rw-r--r--gmp/mini-gmp/tests/mini-random.c142
-rw-r--r--gmp/mini-gmp/tests/mini-random.h33
-rwxr-xr-xgmp/mini-gmp/tests/run-tests123
-rw-r--r--gmp/mini-gmp/tests/t-add.c57
-rw-r--r--gmp/mini-gmp/tests/t-aorsmul.c77
-rw-r--r--gmp/mini-gmp/tests/t-bitops.c103
-rw-r--r--gmp/mini-gmp/tests/t-cmp_d.c283
-rw-r--r--gmp/mini-gmp/tests/t-comb.c164
-rw-r--r--gmp/mini-gmp/tests/t-cong.c212
-rw-r--r--gmp/mini-gmp/tests/t-div.c254
-rw-r--r--gmp/mini-gmp/tests/t-div_2exp.c82
-rw-r--r--gmp/mini-gmp/tests/t-double.c138
-rw-r--r--gmp/mini-gmp/tests/t-gcd.c176
-rw-r--r--gmp/mini-gmp/tests/t-import.c99
-rw-r--r--gmp/mini-gmp/tests/t-invert.c98
-rw-r--r--gmp/mini-gmp/tests/t-lcm.c73
-rw-r--r--gmp/mini-gmp/tests/t-limbs.c106
-rw-r--r--gmp/mini-gmp/tests/t-logops.c112
-rw-r--r--gmp/mini-gmp/tests/t-mul.c113
-rw-r--r--gmp/mini-gmp/tests/t-powm.c61
-rw-r--r--gmp/mini-gmp/tests/t-pprime_p.c182
-rw-r--r--gmp/mini-gmp/tests/t-reuse.c663
-rw-r--r--gmp/mini-gmp/tests/t-root.c95
-rw-r--r--gmp/mini-gmp/tests/t-scan.c90
-rw-r--r--gmp/mini-gmp/tests/t-signed.c142
-rw-r--r--gmp/mini-gmp/tests/t-sqrt.c181
-rw-r--r--gmp/mini-gmp/tests/t-str.c307
-rw-r--r--gmp/mini-gmp/tests/t-sub.c71
-rw-r--r--gmp/mini-gmp/tests/testutils.c173
-rw-r--r--gmp/mini-gmp/tests/testutils.h37
-rwxr-xr-xgmp/missing331
-rw-r--r--gmp/mp_bpl.c35
-rw-r--r--gmp/mp_clz_tab.c49
-rw-r--r--gmp/mp_dv_tab.c78
-rw-r--r--gmp/mp_get_fns.c48
-rw-r--r--gmp/mp_minv_tab.c59
-rw-r--r--gmp/mp_set_fns.c50
-rw-r--r--gmp/mpf/Makefile.am47
-rw-r--r--gmp/mpf/Makefile.in575
-rw-r--r--gmp/mpf/abs.c59
-rw-r--r--gmp/mpf/add.c184
-rw-r--r--gmp/mpf/add_ui.c153
-rw-r--r--gmp/mpf/ceilfloor.c126
-rw-r--r--gmp/mpf/clear.c39
-rw-r--r--gmp/mpf/clears.c49
-rw-r--r--gmp/mpf/cmp.c117
-rw-r--r--gmp/mpf/cmp_d.c60
-rw-r--r--gmp/mpf/cmp_si.c118
-rw-r--r--gmp/mpf/cmp_ui.c100
-rw-r--r--gmp/mpf/div.c138
-rw-r--r--gmp/mpf/div_2exp.c139
-rw-r--r--gmp/mpf/div_ui.c111
-rw-r--r--gmp/mpf/dump.c53
-rw-r--r--gmp/mpf/eq.c150
-rw-r--r--gmp/mpf/fits_s.h75
-rw-r--r--gmp/mpf/fits_sint.c36
-rw-r--r--gmp/mpf/fits_slong.c36
-rw-r--r--gmp/mpf/fits_sshort.c36
-rw-r--r--gmp/mpf/fits_u.h74
-rw-r--r--gmp/mpf/fits_uint.c35
-rw-r--r--gmp/mpf/fits_ulong.c35
-rw-r--r--gmp/mpf/fits_ushort.c35
-rw-r--r--gmp/mpf/get_d.c47
-rw-r--r--gmp/mpf/get_d_2exp.c61
-rw-r--r--gmp/mpf/get_dfl_prec.c39
-rw-r--r--gmp/mpf/get_prc.c38
-rw-r--r--gmp/mpf/get_si.c87
-rw-r--r--gmp/mpf/get_str.c330
-rw-r--r--gmp/mpf/get_ui.c102
-rw-r--r--gmp/mpf/init.c42
-rw-r--r--gmp/mpf/init2.c44
-rw-r--r--gmp/mpf/inits.c49
-rw-r--r--gmp/mpf/inp_str.c93
-rw-r--r--gmp/mpf/int_p.c59
-rw-r--r--gmp/mpf/iset.c62
-rw-r--r--gmp/mpf/iset_d.c42
-rw-r--r--gmp/mpf/iset_si.c58
-rw-r--r--gmp/mpf/iset_str.c44
-rw-r--r--gmp/mpf/iset_ui.c53
-rw-r--r--gmp/mpf/mul.c96
-rw-r--r--gmp/mpf/mul_2exp.c133
-rw-r--r--gmp/mpf/mul_ui.c182
-rw-r--r--gmp/mpf/neg.c62
-rw-r--r--gmp/mpf/out_str.c117
-rw-r--r--gmp/mpf/pow_ui.c54
-rw-r--r--gmp/mpf/random2.c67
-rw-r--r--gmp/mpf/reldiff.c65
-rw-r--r--gmp/mpf/set.c56
-rw-r--r--gmp/mpf/set_d.c60
-rw-r--r--gmp/mpf/set_dfl_prec.c40
-rw-r--r--gmp/mpf/set_prc.c69
-rw-r--r--gmp/mpf/set_prc_raw.c40
-rw-r--r--gmp/mpf/set_q.c155
-rw-r--r--gmp/mpf/set_si.c53
-rw-r--r--gmp/mpf/set_str.c402
-rw-r--r--gmp/mpf/set_ui.c49
-rw-r--r--gmp/mpf/set_z.c57
-rw-r--r--gmp/mpf/size.c39
-rw-r--r--gmp/mpf/sqrt.c113
-rw-r--r--gmp/mpf/sqrt_ui.c109
-rw-r--r--gmp/mpf/sub.c419
-rw-r--r--gmp/mpf/sub_ui.c51
-rw-r--r--gmp/mpf/swap.c57
-rw-r--r--gmp/mpf/trunc.c75
-rw-r--r--gmp/mpf/ui_div.c128
-rw-r--r--gmp/mpf/ui_sub.c336
-rw-r--r--gmp/mpf/urandomb.c69
-rw-r--r--gmp/mpn/Makeasm.am118
-rw-r--r--gmp/mpn/Makefile.am59
-rw-r--r--gmp/mpn/Makefile.in686
-rw-r--r--gmp/mpn/README44
-rw-r--r--gmp/mpn/alpha/README208
-rw-r--r--gmp/mpn/alpha/add_n.asm164
-rw-r--r--gmp/mpn/alpha/addmul_1.asm99
-rw-r--r--gmp/mpn/alpha/alpha-defs.m4107
-rw-r--r--gmp/mpn/alpha/aorslsh1_n.asm164
-rw-r--r--gmp/mpn/alpha/aorslsh2_n.asm167
-rw-r--r--gmp/mpn/alpha/bdiv_dbm1c.asm282
-rw-r--r--gmp/mpn/alpha/cntlz.asm55
-rw-r--r--gmp/mpn/alpha/com.asm176
-rw-r--r--gmp/mpn/alpha/copyd.asm88
-rw-r--r--gmp/mpn/alpha/copyi.asm86
-rw-r--r--gmp/mpn/alpha/default.m4127
-rw-r--r--gmp/mpn/alpha/dive_1.c115
-rw-r--r--gmp/mpn/alpha/divrem_2.asm177
-rw-r--r--gmp/mpn/alpha/ev5/diveby3.asm332
-rw-r--r--gmp/mpn/alpha/ev5/gmp-mparam.h187
-rw-r--r--gmp/mpn/alpha/ev6/add_n.asm283
-rw-r--r--gmp/mpn/alpha/ev6/aorslsh1_n.asm172
-rw-r--r--gmp/mpn/alpha/ev6/aorsmul_1.asm398
-rw-r--r--gmp/mpn/alpha/ev6/gmp-mparam.h209
-rw-r--r--gmp/mpn/alpha/ev6/mod_1_4.asm337
-rw-r--r--gmp/mpn/alpha/ev6/mul_1.asm496
-rw-r--r--gmp/mpn/alpha/ev6/nails/README65
-rw-r--r--gmp/mpn/alpha/ev6/nails/addmul_1.asm396
-rw-r--r--gmp/mpn/alpha/ev6/nails/addmul_2.asm146
-rw-r--r--gmp/mpn/alpha/ev6/nails/addmul_3.asm169
-rw-r--r--gmp/mpn/alpha/ev6/nails/addmul_4.asm210
-rw-r--r--gmp/mpn/alpha/ev6/nails/aors_n.asm233
-rw-r--r--gmp/mpn/alpha/ev6/nails/gmp-mparam.h72
-rw-r--r--gmp/mpn/alpha/ev6/nails/mul_1.asm364
-rw-r--r--gmp/mpn/alpha/ev6/nails/submul_1.asm396
-rwxr-xr-xgmp/mpn/alpha/ev6/slot.pl318
-rw-r--r--gmp/mpn/alpha/ev6/sub_n.asm283
-rw-r--r--gmp/mpn/alpha/ev67/gcd_1.asm145
-rw-r--r--gmp/mpn/alpha/ev67/hamdist.asm111
-rw-r--r--gmp/mpn/alpha/ev67/popcount.asm101
-rw-r--r--gmp/mpn/alpha/gmp-mparam.h86
-rw-r--r--gmp/mpn/alpha/invert_limb.asm95
-rw-r--r--gmp/mpn/alpha/lshift.asm182
-rw-r--r--gmp/mpn/alpha/mod_34lsub1.asm164
-rw-r--r--gmp/mpn/alpha/mode1o.asm209
-rw-r--r--gmp/mpn/alpha/mul_1.asm102
-rw-r--r--gmp/mpn/alpha/rshift.asm180
-rw-r--r--gmp/mpn/alpha/sec_tabselect.asm137
-rw-r--r--gmp/mpn/alpha/sqr_diag_addlsh1.asm93
-rw-r--r--gmp/mpn/alpha/sub_n.asm164
-rw-r--r--gmp/mpn/alpha/submul_1.asm99
-rw-r--r--gmp/mpn/alpha/umul.asm44
-rw-r--r--gmp/mpn/alpha/unicos.m4131
-rw-r--r--gmp/mpn/arm/README35
-rw-r--r--gmp/mpn/arm/aors_n.asm112
-rw-r--r--gmp/mpn/arm/aorslsh1_n.asm167
-rw-r--r--gmp/mpn/arm/aorsmul_1.asm135
-rw-r--r--gmp/mpn/arm/arm-defs.m491
-rw-r--r--gmp/mpn/arm/bdiv_dbm1c.asm113
-rw-r--r--gmp/mpn/arm/cnd_aors_n.asm134
-rw-r--r--gmp/mpn/arm/com.asm75
-rw-r--r--gmp/mpn/arm/copyd.asm84
-rw-r--r--gmp/mpn/arm/copyi.asm79
-rw-r--r--gmp/mpn/arm/dive_1.asm151
-rw-r--r--gmp/mpn/arm/gmp-mparam.h127
-rw-r--r--gmp/mpn/arm/invert_limb.asm93
-rw-r--r--gmp/mpn/arm/logops_n.asm139
-rw-r--r--gmp/mpn/arm/lshift.asm88
-rw-r--r--gmp/mpn/arm/lshiftc.asm95
-rw-r--r--gmp/mpn/arm/mod_34lsub1.asm121
-rw-r--r--gmp/mpn/arm/mode1o.asm92
-rw-r--r--gmp/mpn/arm/mul_1.asm94
-rw-r--r--gmp/mpn/arm/neon/README2
-rw-r--r--gmp/mpn/arm/neon/hamdist.asm194
-rw-r--r--gmp/mpn/arm/neon/lorrshift.asm279
-rw-r--r--gmp/mpn/arm/neon/lshiftc.asm257
-rw-r--r--gmp/mpn/arm/neon/popcount.asm166
-rw-r--r--gmp/mpn/arm/neon/sec_tabselect.asm140
-rw-r--r--gmp/mpn/arm/rsh1aors_n.asm124
-rw-r--r--gmp/mpn/arm/rshift.asm86
-rw-r--r--gmp/mpn/arm/sec_tabselect.asm131
-rw-r--r--gmp/mpn/arm/udiv.asm104
-rw-r--r--gmp/mpn/arm/v5/gcd_1.asm120
-rw-r--r--gmp/mpn/arm/v5/mod_1_1.asm129
-rw-r--r--gmp/mpn/arm/v5/mod_1_2.asm156
-rw-r--r--gmp/mpn/arm/v6/addmul_1.asm111
-rw-r--r--gmp/mpn/arm/v6/addmul_2.asm138
-rw-r--r--gmp/mpn/arm/v6/addmul_3.asm187
-rw-r--r--gmp/mpn/arm/v6/dive_1.asm149
-rw-r--r--gmp/mpn/arm/v6/gmp-mparam.h157
-rw-r--r--gmp/mpn/arm/v6/mode1o.asm95
-rw-r--r--gmp/mpn/arm/v6/mul_1.asm114
-rw-r--r--gmp/mpn/arm/v6/mul_2.asm131
-rw-r--r--gmp/mpn/arm/v6/popham.asm138
-rw-r--r--gmp/mpn/arm/v6/sqr_basecase.asm518
-rw-r--r--gmp/mpn/arm/v6/submul_1.asm125
-rw-r--r--gmp/mpn/arm/v6t2/divrem_1.asm212
-rw-r--r--gmp/mpn/arm/v6t2/gcd_1.asm115
-rw-r--r--gmp/mpn/arm/v7a/cora15/addmul_1.asm145
-rw-r--r--gmp/mpn/arm/v7a/cora15/aors_n.asm162
-rw-r--r--gmp/mpn/arm/v7a/cora15/cnd_aors_n.asm158
-rw-r--r--gmp/mpn/arm/v7a/cora15/com.asm180
-rw-r--r--gmp/mpn/arm/v7a/cora15/gmp-mparam.h197
-rw-r--r--gmp/mpn/arm/v7a/cora15/logops_n.asm253
-rw-r--r--gmp/mpn/arm/v7a/cora15/mul_1.asm104
-rw-r--r--gmp/mpn/arm/v7a/cora15/neon/aorsorrlsh1_n.asm43
-rw-r--r--gmp/mpn/arm/v7a/cora15/neon/aorsorrlsh2_n.asm43
-rw-r--r--gmp/mpn/arm/v7a/cora15/neon/aorsorrlshC_n.asm144
-rw-r--r--gmp/mpn/arm/v7a/cora15/neon/com.asm97
-rw-r--r--gmp/mpn/arm/v7a/cora15/neon/copyd.asm110
-rw-r--r--gmp/mpn/arm/v7a/cora15/neon/copyi.asm90
-rw-r--r--gmp/mpn/arm/v7a/cora15/neon/rsh1aors_n.asm177
-rw-r--r--gmp/mpn/arm/v7a/cora15/submul_1.asm159
-rw-r--r--gmp/mpn/arm/v7a/cora9/gmp-mparam.h209
-rw-r--r--gmp/mpn/arm64/aors_n.asm98
-rw-r--r--gmp/mpn/arm64/aorsmul_1.asm122
-rw-r--r--gmp/mpn/arm64/cnd_aors_n.asm99
-rw-r--r--gmp/mpn/arm64/copyd.asm93
-rw-r--r--gmp/mpn/arm64/copyi.asm77
-rw-r--r--gmp/mpn/arm64/gcd_1.asm125
-rw-r--r--gmp/mpn/arm64/invert_limb.asm83
-rw-r--r--gmp/mpn/arm64/logops_n.asm106
-rw-r--r--gmp/mpn/arm64/mul_1.asm98
-rw-r--r--gmp/mpn/asm-defs.m41761
-rwxr-xr-xgmp/mpn/cpp-ccas118
-rw-r--r--gmp/mpn/cray/README121
-rw-r--r--gmp/mpn/cray/add_n.c91
-rw-r--r--gmp/mpn/cray/cfp/addmul_1.c49
-rw-r--r--gmp/mpn/cray/cfp/mul_1.c48
-rw-r--r--gmp/mpn/cray/cfp/mulwwc90.s254
-rw-r--r--gmp/mpn/cray/cfp/mulwwj90.s253
-rw-r--r--gmp/mpn/cray/cfp/submul_1.c49
-rw-r--r--gmp/mpn/cray/gmp-mparam.h79
-rw-r--r--gmp/mpn/cray/hamdist.c43
-rw-r--r--gmp/mpn/cray/ieee/addmul_1.c112
-rw-r--r--gmp/mpn/cray/ieee/gmp-mparam.h73
-rw-r--r--gmp/mpn/cray/ieee/invert_limb.c128
-rw-r--r--gmp/mpn/cray/ieee/mul_1.c104
-rw-r--r--gmp/mpn/cray/ieee/mul_basecase.c108
-rw-r--r--gmp/mpn/cray/ieee/sqr_basecase.c106
-rw-r--r--gmp/mpn/cray/ieee/submul_1.c112
-rw-r--r--gmp/mpn/cray/lshift.c59
-rw-r--r--gmp/mpn/cray/mulww.f63
-rw-r--r--gmp/mpn/cray/popcount.c43
-rw-r--r--gmp/mpn/cray/rshift.c59
-rw-r--r--gmp/mpn/cray/sub_n.c91
-rw-r--r--gmp/mpn/generic/add.c34
-rw-r--r--gmp/mpn/generic/add_1.c34
-rw-r--r--gmp/mpn/generic/add_err1_n.c101
-rw-r--r--gmp/mpn/generic/add_err2_n.c117
-rw-r--r--gmp/mpn/generic/add_err3_n.c132
-rw-r--r--gmp/mpn/generic/add_n.c90
-rw-r--r--gmp/mpn/generic/add_n_sub_n.c173
-rw-r--r--gmp/mpn/generic/addmul_1.c139
-rw-r--r--gmp/mpn/generic/bdiv_dbm1c.c59
-rw-r--r--gmp/mpn/generic/bdiv_q.c77
-rw-r--r--gmp/mpn/generic/bdiv_q_1.c126
-rw-r--r--gmp/mpn/generic/bdiv_qr.c85
-rw-r--r--gmp/mpn/generic/binvert.c102
-rw-r--r--gmp/mpn/generic/broot.c196
-rw-r--r--gmp/mpn/generic/brootinv.c140
-rw-r--r--gmp/mpn/generic/bsqrt.c48
-rw-r--r--gmp/mpn/generic/bsqrtinv.c105
-rw-r--r--gmp/mpn/generic/cmp.c34
-rw-r--r--gmp/mpn/generic/cnd_add_n.c70
-rw-r--r--gmp/mpn/generic/cnd_sub_n.c70
-rw-r--r--gmp/mpn/generic/com.c45
-rw-r--r--gmp/mpn/generic/comb_tables.c48
-rw-r--r--gmp/mpn/generic/copyd.c41
-rw-r--r--gmp/mpn/generic/copyi.c43
-rw-r--r--gmp/mpn/generic/dcpi1_bdiv_q.c160
-rw-r--r--gmp/mpn/generic/dcpi1_bdiv_qr.c177
-rw-r--r--gmp/mpn/generic/dcpi1_div_q.c87
-rw-r--r--gmp/mpn/generic/dcpi1_div_qr.c249
-rw-r--r--gmp/mpn/generic/dcpi1_divappr_q.c257
-rw-r--r--gmp/mpn/generic/div_q.c323
-rw-r--r--gmp/mpn/generic/div_qr_1.c126
-rw-r--r--gmp/mpn/generic/div_qr_1n_pi1.c277
-rw-r--r--gmp/mpn/generic/div_qr_1n_pi2.c195
-rw-r--r--gmp/mpn/generic/div_qr_1u_pi2.c228
-rw-r--r--gmp/mpn/generic/div_qr_2.c332
-rw-r--r--gmp/mpn/generic/div_qr_2n_pi1.c85
-rw-r--r--gmp/mpn/generic/div_qr_2u_pi1.c77
-rw-r--r--gmp/mpn/generic/dive_1.c148
-rw-r--r--gmp/mpn/generic/diveby3.c174
-rw-r--r--gmp/mpn/generic/divexact.c294
-rw-r--r--gmp/mpn/generic/divis.c201
-rw-r--r--gmp/mpn/generic/divrem.c108
-rw-r--r--gmp/mpn/generic/divrem_1.c255
-rw-r--r--gmp/mpn/generic/divrem_2.c119
-rw-r--r--gmp/mpn/generic/dump.c100
-rw-r--r--gmp/mpn/generic/fib2_ui.c189
-rw-r--r--gmp/mpn/generic/gcd.c310
-rw-r--r--gmp/mpn/generic/gcd_1.c199
-rw-r--r--gmp/mpn/generic/gcd_subdiv_step.c205
-rw-r--r--gmp/mpn/generic/gcdext.c558
-rw-r--r--gmp/mpn/generic/gcdext_1.c328
-rw-r--r--gmp/mpn/generic/gcdext_lehmer.c337
-rw-r--r--gmp/mpn/generic/get_d.c412
-rw-r--r--gmp/mpn/generic/get_str.c553
-rw-r--r--gmp/mpn/generic/gmp-mparam.h33
-rw-r--r--gmp/mpn/generic/hgcd.c183
-rw-r--r--gmp/mpn/generic/hgcd2.c447
-rw-r--r--gmp/mpn/generic/hgcd2_jacobi.c366
-rw-r--r--gmp/mpn/generic/hgcd_appr.c268
-rw-r--r--gmp/mpn/generic/hgcd_jacobi.c244
-rw-r--r--gmp/mpn/generic/hgcd_matrix.c266
-rw-r--r--gmp/mpn/generic/hgcd_reduce.c247
-rw-r--r--gmp/mpn/generic/hgcd_step.c128
-rw-r--r--gmp/mpn/generic/invert.c91
-rw-r--r--gmp/mpn/generic/invertappr.c314
-rw-r--r--gmp/mpn/generic/jacbase.c243
-rw-r--r--gmp/mpn/generic/jacobi.c295
-rw-r--r--gmp/mpn/generic/jacobi_2.c352
-rw-r--r--gmp/mpn/generic/logops_n.c78
-rw-r--r--gmp/mpn/generic/lshift.c73
-rw-r--r--gmp/mpn/generic/lshiftc.c74
-rw-r--r--gmp/mpn/generic/matrix22_mul.c322
-rw-r--r--gmp/mpn/generic/matrix22_mul1_inverse_vector.c65
-rw-r--r--gmp/mpn/generic/mod_1.c281
-rw-r--r--gmp/mpn/generic/mod_1_1.c332
-rw-r--r--gmp/mpn/generic/mod_1_2.c149
-rw-r--r--gmp/mpn/generic/mod_1_3.c157
-rw-r--r--gmp/mpn/generic/mod_1_4.c171
-rw-r--r--gmp/mpn/generic/mod_34lsub1.c131
-rw-r--r--gmp/mpn/generic/mode1o.c236
-rw-r--r--gmp/mpn/generic/mu_bdiv_q.c271
-rw-r--r--gmp/mpn/generic/mu_bdiv_qr.c289
-rw-r--r--gmp/mpn/generic/mu_div_q.c185
-rw-r--r--gmp/mpn/generic/mu_div_qr.c416
-rw-r--r--gmp/mpn/generic/mu_divappr_q.c363
-rw-r--r--gmp/mpn/generic/mul.c428
-rw-r--r--gmp/mpn/generic/mul_1.c97
-rw-r--r--gmp/mpn/generic/mul_basecase.c166
-rw-r--r--gmp/mpn/generic/mul_fft.c1014
-rw-r--r--gmp/mpn/generic/mul_n.c97
-rw-r--r--gmp/mpn/generic/mullo_basecase.c52
-rw-r--r--gmp/mpn/generic/mullo_n.c256
-rw-r--r--gmp/mpn/generic/mulmid.c256
-rw-r--r--gmp/mpn/generic/mulmid_basecase.c83
-rw-r--r--gmp/mpn/generic/mulmid_n.c62
-rw-r--r--gmp/mpn/generic/mulmod_bnm1.c355
-rw-r--r--gmp/mpn/generic/neg.c34
-rw-r--r--gmp/mpn/generic/nussbaumer_mul.c71
-rw-r--r--gmp/mpn/generic/perfpow.c417
-rw-r--r--gmp/mpn/generic/perfsqr.c240
-rw-r--r--gmp/mpn/generic/popham.c126
-rw-r--r--gmp/mpn/generic/pow_1.c134
-rw-r--r--gmp/mpn/generic/powlo.c174
-rw-r--r--gmp/mpn/generic/powm.c590
-rw-r--r--gmp/mpn/generic/pre_divrem_1.c146
-rw-r--r--gmp/mpn/generic/pre_mod_1.c62
-rw-r--r--gmp/mpn/generic/random.c51
-rw-r--r--gmp/mpn/generic/random2.c106
-rw-r--r--gmp/mpn/generic/redc_1.c57
-rw-r--r--gmp/mpn/generic/redc_2.c110
-rw-r--r--gmp/mpn/generic/redc_n.c81
-rw-r--r--gmp/mpn/generic/remove.c172
-rw-r--r--gmp/mpn/generic/rootrem.c415
-rw-r--r--gmp/mpn/generic/rshift.c70
-rw-r--r--gmp/mpn/generic/sbpi1_bdiv_q.c100
-rw-r--r--gmp/mpn/generic/sbpi1_bdiv_qr.c119
-rw-r--r--gmp/mpn/generic/sbpi1_div_q.c303
-rw-r--r--gmp/mpn/generic/sbpi1_div_qr.c110
-rw-r--r--gmp/mpn/generic/sbpi1_divappr_q.c199
-rw-r--r--gmp/mpn/generic/scan0.c60
-rw-r--r--gmp/mpn/generic/scan1.c60
-rw-r--r--gmp/mpn/generic/sec_aors_1.c60
-rw-r--r--gmp/mpn/generic/sec_div.c133
-rw-r--r--gmp/mpn/generic/sec_invert.c195
-rw-r--r--gmp/mpn/generic/sec_mul.c49
-rw-r--r--gmp/mpn/generic/sec_pi1_div.c173
-rw-r--r--gmp/mpn/generic/sec_powm.c438
-rw-r--r--gmp/mpn/generic/sec_sqr.c48
-rw-r--r--gmp/mpn/generic/sec_tabselect.c55
-rw-r--r--gmp/mpn/generic/set_str.c374
-rw-r--r--gmp/mpn/generic/sizeinbase.c50
-rw-r--r--gmp/mpn/generic/sqr.c99
-rw-r--r--gmp/mpn/generic/sqr_basecase.c325
-rw-r--r--gmp/mpn/generic/sqrmod_bnm1.c313
-rw-r--r--gmp/mpn/generic/sqrtrem.c357
-rw-r--r--gmp/mpn/generic/sub.c34
-rw-r--r--gmp/mpn/generic/sub_1.c34
-rw-r--r--gmp/mpn/generic/sub_err1_n.c101
-rw-r--r--gmp/mpn/generic/sub_err2_n.c117
-rw-r--r--gmp/mpn/generic/sub_err3_n.c132
-rw-r--r--gmp/mpn/generic/sub_n.c90
-rw-r--r--gmp/mpn/generic/submul_1.c139
-rw-r--r--gmp/mpn/generic/tdiv_qr.c389
-rw-r--r--gmp/mpn/generic/toom22_mul.c210
-rw-r--r--gmp/mpn/generic/toom2_sqr.c146
-rw-r--r--gmp/mpn/generic/toom32_mul.c323
-rw-r--r--gmp/mpn/generic/toom33_mul.c316
-rw-r--r--gmp/mpn/generic/toom3_sqr.c226
-rw-r--r--gmp/mpn/generic/toom42_mul.c234
-rw-r--r--gmp/mpn/generic/toom42_mulmid.c238
-rw-r--r--gmp/mpn/generic/toom43_mul.c234
-rw-r--r--gmp/mpn/generic/toom44_mul.c236
-rw-r--r--gmp/mpn/generic/toom4_sqr.c164
-rw-r--r--gmp/mpn/generic/toom52_mul.c257
-rw-r--r--gmp/mpn/generic/toom53_mul.c331
-rw-r--r--gmp/mpn/generic/toom54_mul.c143
-rw-r--r--gmp/mpn/generic/toom62_mul.c311
-rw-r--r--gmp/mpn/generic/toom63_mul.c232
-rw-r--r--gmp/mpn/generic/toom6_sqr.c182
-rw-r--r--gmp/mpn/generic/toom6h_mul.c263
-rw-r--r--gmp/mpn/generic/toom8_sqr.c226
-rw-r--r--gmp/mpn/generic/toom8h_mul.c306
-rw-r--r--gmp/mpn/generic/toom_couple_handling.c81
-rw-r--r--gmp/mpn/generic/toom_eval_dgr3_pm1.c73
-rw-r--r--gmp/mpn/generic/toom_eval_dgr3_pm2.c98
-rw-r--r--gmp/mpn/generic/toom_eval_pm1.c90
-rw-r--r--gmp/mpn/generic/toom_eval_pm2.c131
-rw-r--r--gmp/mpn/generic/toom_eval_pm2exp.c128
-rw-r--r--gmp/mpn/generic/toom_eval_pm2rexp.c102
-rw-r--r--gmp/mpn/generic/toom_interpolate_12pts.c361
-rw-r--r--gmp/mpn/generic/toom_interpolate_16pts.c527
-rw-r--r--gmp/mpn/generic/toom_interpolate_5pts.c199
-rw-r--r--gmp/mpn/generic/toom_interpolate_6pts.c240
-rw-r--r--gmp/mpn/generic/toom_interpolate_7pts.c266
-rw-r--r--gmp/mpn/generic/toom_interpolate_8pts.c212
-rw-r--r--gmp/mpn/generic/trialdiv.c132
-rw-r--r--gmp/mpn/generic/udiv_w_sdiv.c142
-rw-r--r--gmp/mpn/generic/zero.c42
-rw-r--r--gmp/mpn/ia64/README281
-rw-r--r--gmp/mpn/ia64/add_n_sub_n.asm309
-rw-r--r--gmp/mpn/ia64/addmul_1.asm602
-rw-r--r--gmp/mpn/ia64/addmul_2.asm708
-rw-r--r--gmp/mpn/ia64/aors_n.asm856
-rw-r--r--gmp/mpn/ia64/aorsorrlsh1_n.asm48
-rw-r--r--gmp/mpn/ia64/aorsorrlsh2_n.asm48
-rw-r--r--gmp/mpn/ia64/aorsorrlshC_n.asm397
-rw-r--r--gmp/mpn/ia64/bdiv_dbm1c.asm516
-rw-r--r--gmp/mpn/ia64/cnd_aors_n.asm259
-rw-r--r--gmp/mpn/ia64/copyd.asm186
-rw-r--r--gmp/mpn/ia64/copyi.asm182
-rw-r--r--gmp/mpn/ia64/dive_1.asm236
-rw-r--r--gmp/mpn/ia64/divrem_1.asm477
-rw-r--r--gmp/mpn/ia64/divrem_2.asm280
-rw-r--r--gmp/mpn/ia64/gcd_1.asm234
-rw-r--r--gmp/mpn/ia64/gmp-mparam.h204
-rw-r--r--gmp/mpn/ia64/hamdist.asm365
-rw-r--r--gmp/mpn/ia64/ia64-defs.m4147
-rw-r--r--gmp/mpn/ia64/invert_limb.asm105
-rw-r--r--gmp/mpn/ia64/logops_n.asm292
-rw-r--r--gmp/mpn/ia64/lorrshift.asm358
-rw-r--r--gmp/mpn/ia64/lshiftc.asm463
-rw-r--r--gmp/mpn/ia64/mod_34lsub1.asm236
-rw-r--r--gmp/mpn/ia64/mode1o.asm342
-rw-r--r--gmp/mpn/ia64/mul_1.asm584
-rw-r--r--gmp/mpn/ia64/mul_2.asm620
-rw-r--r--gmp/mpn/ia64/popcount.asm200
-rw-r--r--gmp/mpn/ia64/rsh1aors_n.asm447
-rw-r--r--gmp/mpn/ia64/sec_tabselect.asm150
-rw-r--r--gmp/mpn/ia64/sqr_diag_addlsh1.asm144
-rw-r--r--gmp/mpn/ia64/submul_1.asm647
-rw-r--r--gmp/mpn/lisp/gmpasm-mode.el385
-rwxr-xr-xgmp/mpn/m4-ccas107
-rw-r--r--gmp/mpn/m68k/README138
-rw-r--r--gmp/mpn/m68k/aors_n.asm99
-rw-r--r--gmp/mpn/m68k/gmp-mparam.h76
-rw-r--r--gmp/mpn/m68k/lshift.asm175
-rw-r--r--gmp/mpn/m68k/m68k-defs.m4230
-rw-r--r--gmp/mpn/m68k/mc68020/aorsmul_1.asm101
-rw-r--r--gmp/mpn/m68k/mc68020/mul_1.asm96
-rw-r--r--gmp/mpn/m68k/mc68020/udiv.asm45
-rw-r--r--gmp/mpn/m68k/mc68020/umul.asm44
-rw-r--r--gmp/mpn/m68k/rshift.asm175
-rw-r--r--gmp/mpn/m68k/t-m68k-defs.pl91
-rw-r--r--gmp/mpn/m88k/README61
-rw-r--r--gmp/mpn/m88k/add_n.s113
-rw-r--r--gmp/mpn/m88k/mc88110/add_n.S209
-rw-r--r--gmp/mpn/m88k/mc88110/addmul_1.s70
-rw-r--r--gmp/mpn/m88k/mc88110/mul_1.s68
-rw-r--r--gmp/mpn/m88k/mc88110/sub_n.S285
-rw-r--r--gmp/mpn/m88k/mul_1.s136
-rw-r--r--gmp/mpn/m88k/sub_n.s115
-rw-r--r--gmp/mpn/minithres/gmp-mparam.h109
-rw-r--r--gmp/mpn/mips32/add_n.asm124
-rw-r--r--gmp/mpn/mips32/addmul_1.asm101
-rw-r--r--gmp/mpn/mips32/gmp-mparam.h72
-rw-r--r--gmp/mpn/mips32/lshift.asm99
-rw-r--r--gmp/mpn/mips32/mips-defs.m480
-rw-r--r--gmp/mpn/mips32/mips.m480
-rw-r--r--gmp/mpn/mips32/mul_1.asm89
-rw-r--r--gmp/mpn/mips32/rshift.asm96
-rw-r--r--gmp/mpn/mips32/sub_n.asm123
-rw-r--r--gmp/mpn/mips32/submul_1.asm101
-rw-r--r--gmp/mpn/mips32/umul.asm45
-rw-r--r--gmp/mpn/mips64/README60
-rw-r--r--gmp/mpn/mips64/add_n.asm134
-rw-r--r--gmp/mpn/mips64/addmul_1.asm101
-rw-r--r--gmp/mpn/mips64/gmp-mparam.h72
-rw-r--r--gmp/mpn/mips64/lshift.asm99
-rw-r--r--gmp/mpn/mips64/mul_1.asm92
-rw-r--r--gmp/mpn/mips64/rshift.asm96
-rw-r--r--gmp/mpn/mips64/sqr_diagonal.asm77
-rw-r--r--gmp/mpn/mips64/sub_n.asm134
-rw-r--r--gmp/mpn/mips64/submul_1.asm101
-rw-r--r--gmp/mpn/mips64/umul.asm45
-rw-r--r--gmp/mpn/pa32/README162
-rw-r--r--gmp/mpn/pa32/add_n.asm63
-rw-r--r--gmp/mpn/pa32/gmp-mparam.h61
-rw-r--r--gmp/mpn/pa32/hppa1_1/addmul_1.asm106
-rw-r--r--gmp/mpn/pa32/hppa1_1/gmp-mparam.h72
-rw-r--r--gmp/mpn/pa32/hppa1_1/mul_1.asm102
-rw-r--r--gmp/mpn/pa32/hppa1_1/pa7100/add_n.asm83
-rw-r--r--gmp/mpn/pa32/hppa1_1/pa7100/addmul_1.asm201
-rw-r--r--gmp/mpn/pa32/hppa1_1/pa7100/lshift.asm95
-rw-r--r--gmp/mpn/pa32/hppa1_1/pa7100/rshift.asm92
-rw-r--r--gmp/mpn/pa32/hppa1_1/pa7100/sub_n.asm84
-rw-r--r--gmp/mpn/pa32/hppa1_1/pa7100/submul_1.asm207
-rw-r--r--gmp/mpn/pa32/hppa1_1/sqr_diagonal.asm60
-rw-r--r--gmp/mpn/pa32/hppa1_1/submul_1.asm115
-rw-r--r--gmp/mpn/pa32/hppa1_1/udiv.asm102
-rw-r--r--gmp/mpn/pa32/hppa1_1/umul.asm47
-rw-r--r--gmp/mpn/pa32/hppa2_0/add_n.asm107
-rw-r--r--gmp/mpn/pa32/hppa2_0/gmp-mparam.h167
-rw-r--r--gmp/mpn/pa32/hppa2_0/sqr_diagonal.asm112
-rw-r--r--gmp/mpn/pa32/hppa2_0/sub_n.asm107
-rw-r--r--gmp/mpn/pa32/lshift.asm75
-rw-r--r--gmp/mpn/pa32/pa-defs.m464
-rw-r--r--gmp/mpn/pa32/rshift.asm72
-rw-r--r--gmp/mpn/pa32/sub_n.asm64
-rw-r--r--gmp/mpn/pa32/udiv.asm291
-rw-r--r--gmp/mpn/pa64/README78
-rw-r--r--gmp/mpn/pa64/addmul_1.asm693
-rw-r--r--gmp/mpn/pa64/aors_n.asm130
-rw-r--r--gmp/mpn/pa64/aorslsh1_n.asm228
-rw-r--r--gmp/mpn/pa64/gmp-mparam.h247
-rw-r--r--gmp/mpn/pa64/lshift.asm114
-rw-r--r--gmp/mpn/pa64/mul_1.asm646
-rw-r--r--gmp/mpn/pa64/rshift.asm111
-rw-r--r--gmp/mpn/pa64/sqr_diagonal.asm191
-rw-r--r--gmp/mpn/pa64/submul_1.asm700
-rw-r--r--gmp/mpn/pa64/udiv.asm125
-rw-r--r--gmp/mpn/pa64/umul.asm98
-rw-r--r--gmp/mpn/power/add_n.asm83
-rw-r--r--gmp/mpn/power/addmul_1.asm126
-rw-r--r--gmp/mpn/power/gmp-mparam.h69
-rw-r--r--gmp/mpn/power/lshift.asm61
-rw-r--r--gmp/mpn/power/mul_1.asm113
-rw-r--r--gmp/mpn/power/rshift.asm59
-rw-r--r--gmp/mpn/power/sdiv.asm39
-rw-r--r--gmp/mpn/power/sub_n.asm85
-rw-r--r--gmp/mpn/power/submul_1.asm131
-rw-r--r--gmp/mpn/power/umul.asm43
-rw-r--r--gmp/mpn/powerpc32/750/com.asm79
-rw-r--r--gmp/mpn/powerpc32/750/gmp-mparam.h192
-rw-r--r--gmp/mpn/powerpc32/750/lshift.asm155
-rw-r--r--gmp/mpn/powerpc32/750/rshift.asm153
-rw-r--r--gmp/mpn/powerpc32/README180
-rw-r--r--gmp/mpn/powerpc32/addlsh1_n.asm100
-rw-r--r--gmp/mpn/powerpc32/addmul_1.asm155
-rw-r--r--gmp/mpn/powerpc32/aix.m482
-rw-r--r--gmp/mpn/powerpc32/aors_n.asm157
-rw-r--r--gmp/mpn/powerpc32/bdiv_dbm1c.asm131
-rw-r--r--gmp/mpn/powerpc32/darwin.m491
-rw-r--r--gmp/mpn/powerpc32/diveby3.asm93
-rw-r--r--gmp/mpn/powerpc32/divrem_2.asm182
-rw-r--r--gmp/mpn/powerpc32/eabi.m486
-rw-r--r--gmp/mpn/powerpc32/elf.m497
-rw-r--r--gmp/mpn/powerpc32/gmp-mparam.h217
-rw-r--r--gmp/mpn/powerpc32/invert_limb.asm142
-rw-r--r--gmp/mpn/powerpc32/lshift.asm166
-rw-r--r--gmp/mpn/powerpc32/lshiftc.asm168
-rw-r--r--gmp/mpn/powerpc32/mod_34lsub1.asm145
-rw-r--r--gmp/mpn/powerpc32/mode1o.asm127
-rw-r--r--gmp/mpn/powerpc32/mul_1.asm101
-rw-r--r--gmp/mpn/powerpc32/p3-p7/aors_n.asm186
-rw-r--r--gmp/mpn/powerpc32/p3/gmp-mparam.h155
-rw-r--r--gmp/mpn/powerpc32/p4/gmp-mparam.h204
-rw-r--r--gmp/mpn/powerpc32/p5/gmp-mparam.h156
-rw-r--r--gmp/mpn/powerpc32/p6/gmp-mparam.h165
-rw-r--r--gmp/mpn/powerpc32/p7/gmp-mparam.h159
-rw-r--r--gmp/mpn/powerpc32/powerpc-defs.m4104
-rw-r--r--gmp/mpn/powerpc32/rshift.asm164
-rw-r--r--gmp/mpn/powerpc32/sec_tabselect.asm141
-rw-r--r--gmp/mpn/powerpc32/sqr_diag_addlsh1.asm80
-rw-r--r--gmp/mpn/powerpc32/sublsh1_n.asm101
-rw-r--r--gmp/mpn/powerpc32/submul_1.asm147
-rw-r--r--gmp/mpn/powerpc32/umul.asm50
-rw-r--r--gmp/mpn/powerpc32/vmx/copyd.asm203
-rw-r--r--gmp/mpn/powerpc32/vmx/copyi.asm198
-rw-r--r--gmp/mpn/powerpc32/vmx/logops_n.asm310
-rw-r--r--gmp/mpn/powerpc32/vmx/mod_34lsub1.asm386
-rw-r--r--gmp/mpn/powerpc32/vmx/popcount.asm34
-rw-r--r--gmp/mpn/powerpc64/README166
-rw-r--r--gmp/mpn/powerpc64/aix.m497
-rw-r--r--gmp/mpn/powerpc64/com.asm136
-rw-r--r--gmp/mpn/powerpc64/copyd.asm84
-rw-r--r--gmp/mpn/powerpc64/copyi.asm78
-rw-r--r--gmp/mpn/powerpc64/darwin.m4119
-rw-r--r--gmp/mpn/powerpc64/elf.m4123
-rw-r--r--gmp/mpn/powerpc64/logops_n.asm151
-rw-r--r--gmp/mpn/powerpc64/lshift.asm207
-rw-r--r--gmp/mpn/powerpc64/lshiftc.asm210
-rw-r--r--gmp/mpn/powerpc64/mode32/add_n.asm86
-rw-r--r--gmp/mpn/powerpc64/mode32/addmul_1.asm79
-rw-r--r--gmp/mpn/powerpc64/mode32/mul_1.asm73
-rw-r--r--gmp/mpn/powerpc64/mode32/p4/gmp-mparam.h173
-rw-r--r--gmp/mpn/powerpc64/mode32/sqr_diagonal.asm117
-rw-r--r--gmp/mpn/powerpc64/mode32/sub_n.asm88
-rw-r--r--gmp/mpn/powerpc64/mode32/submul_1.asm82
-rw-r--r--gmp/mpn/powerpc64/mode64/aors_n.asm189
-rw-r--r--gmp/mpn/powerpc64/mode64/aorsmul_1.asm225
-rw-r--r--gmp/mpn/powerpc64/mode64/aorsorrlsh1_n.asm43
-rw-r--r--gmp/mpn/powerpc64/mode64/aorsorrlsh2_n.asm43
-rw-r--r--gmp/mpn/powerpc64/mode64/aorsorrlshC_n.asm187
-rw-r--r--gmp/mpn/powerpc64/mode64/bdiv_dbm1c.asm132
-rw-r--r--gmp/mpn/powerpc64/mode64/cnd_aors_n.asm196
-rw-r--r--gmp/mpn/powerpc64/mode64/dive_1.asm132
-rw-r--r--gmp/mpn/powerpc64/mode64/divrem_1.asm274
-rw-r--r--gmp/mpn/powerpc64/mode64/divrem_2.asm187
-rw-r--r--gmp/mpn/powerpc64/mode64/gcd_1.asm122
-rw-r--r--gmp/mpn/powerpc64/mode64/gmp-mparam.h82
-rw-r--r--gmp/mpn/powerpc64/mode64/invert_limb.asm88
-rw-r--r--gmp/mpn/powerpc64/mode64/mod_1_1.asm164
-rw-r--r--gmp/mpn/powerpc64/mode64/mod_1_4.asm270
-rw-r--r--gmp/mpn/powerpc64/mode64/mod_34lsub1.asm132
-rw-r--r--gmp/mpn/powerpc64/mode64/mode1o.asm117
-rw-r--r--gmp/mpn/powerpc64/mode64/mul_1.asm168
-rw-r--r--gmp/mpn/powerpc64/mode64/mul_basecase.asm708
-rw-r--r--gmp/mpn/powerpc64/mode64/p3/gmp-mparam.h179
-rw-r--r--gmp/mpn/powerpc64/mode64/p4/gmp-mparam.h208
-rw-r--r--gmp/mpn/powerpc64/mode64/p5/gmp-mparam.h219
-rw-r--r--gmp/mpn/powerpc64/mode64/p6/aorsmul_1.asm183
-rw-r--r--gmp/mpn/powerpc64/mode64/p6/gmp-mparam.h160
-rw-r--r--gmp/mpn/powerpc64/mode64/p6/mul_basecase.asm589
-rw-r--r--gmp/mpn/powerpc64/mode64/p7/aormul_2.asm135
-rw-r--r--gmp/mpn/powerpc64/mode64/p7/aors_n.asm128
-rw-r--r--gmp/mpn/powerpc64/mode64/p7/aorsorrlsh1_n.asm43
-rw-r--r--gmp/mpn/powerpc64/mode64/p7/aorsorrlsh2_n.asm43
-rw-r--r--gmp/mpn/powerpc64/mode64/p7/aorsorrlshC_n.asm129
-rw-r--r--gmp/mpn/powerpc64/mode64/p7/gcd_1.asm110
-rw-r--r--gmp/mpn/powerpc64/mode64/p7/gmp-mparam.h243
-rw-r--r--gmp/mpn/powerpc64/mode64/rsh1aors_n.asm172
-rw-r--r--gmp/mpn/powerpc64/mode64/sqr_basecase.asm863
-rw-r--r--gmp/mpn/powerpc64/p6/lshift.asm132
-rw-r--r--gmp/mpn/powerpc64/p6/lshiftc.asm136
-rw-r--r--gmp/mpn/powerpc64/p6/rshift.asm131
-rw-r--r--gmp/mpn/powerpc64/p7/copyd.asm128
-rw-r--r--gmp/mpn/powerpc64/p7/copyi.asm129
-rw-r--r--gmp/mpn/powerpc64/p7/hamdist.asm110
-rw-r--r--gmp/mpn/powerpc64/p7/popcount.asm90
-rw-r--r--gmp/mpn/powerpc64/rshift.asm207
-rw-r--r--gmp/mpn/powerpc64/sec_tabselect.asm147
-rw-r--r--gmp/mpn/powerpc64/umul.asm53
-rw-r--r--gmp/mpn/powerpc64/vmx/popcount.asm230
-rw-r--r--gmp/mpn/s390_32/README37
-rw-r--r--gmp/mpn/s390_32/addmul_1.asm93
-rw-r--r--gmp/mpn/s390_32/copyd.asm145
-rw-r--r--gmp/mpn/s390_32/copyi.asm69
-rw-r--r--gmp/mpn/s390_32/esame/addmul_1.asm72
-rw-r--r--gmp/mpn/s390_32/esame/aors_n.asm137
-rw-r--r--gmp/mpn/s390_32/esame/aorslsh1_n.asm173
-rw-r--r--gmp/mpn/s390_32/esame/bdiv_dbm1c.asm65
-rw-r--r--gmp/mpn/s390_32/esame/gmp-mparam.h207
-rw-r--r--gmp/mpn/s390_32/esame/mul_1.asm66
-rw-r--r--gmp/mpn/s390_32/esame/mul_basecase.asm130
-rw-r--r--gmp/mpn/s390_32/esame/sqr_basecase.asm203
-rw-r--r--gmp/mpn/s390_32/esame/submul_1.asm70
-rw-r--r--gmp/mpn/s390_32/gmp-mparam.h138
-rw-r--r--gmp/mpn/s390_32/logops_n.asm295
-rw-r--r--gmp/mpn/s390_32/lshift.asm144
-rw-r--r--gmp/mpn/s390_32/lshiftc.asm156
-rw-r--r--gmp/mpn/s390_32/mul_1.asm85
-rw-r--r--gmp/mpn/s390_32/rshift.asm138
-rw-r--r--gmp/mpn/s390_32/submul_1.asm93
-rw-r--r--gmp/mpn/s390_64/README88
-rw-r--r--gmp/mpn/s390_64/addmul_1.asm72
-rw-r--r--gmp/mpn/s390_64/aorrlsh1_n.asm168
-rw-r--r--gmp/mpn/s390_64/aors_n.asm136
-rw-r--r--gmp/mpn/s390_64/bdiv_dbm1c.asm65
-rw-r--r--gmp/mpn/s390_64/copyd.asm144
-rw-r--r--gmp/mpn/s390_64/copyi.asm68
-rw-r--r--gmp/mpn/s390_64/gmp-mparam.h175
-rw-r--r--gmp/mpn/s390_64/invert_limb.asm94
-rw-r--r--gmp/mpn/s390_64/logops_n.asm291
-rw-r--r--gmp/mpn/s390_64/lshift.asm196
-rw-r--r--gmp/mpn/s390_64/lshiftc.asm207
-rw-r--r--gmp/mpn/s390_64/mod_34lsub1.asm109
-rw-r--r--gmp/mpn/s390_64/mul_1.asm66
-rw-r--r--gmp/mpn/s390_64/mul_basecase.asm130
-rw-r--r--gmp/mpn/s390_64/rshift.asm195
-rw-r--r--gmp/mpn/s390_64/sqr_basecase.asm203
-rw-r--r--gmp/mpn/s390_64/sublsh1_n.asm169
-rw-r--r--gmp/mpn/s390_64/submul_1.asm70
-rw-r--r--gmp/mpn/s390_64/z10/gmp-mparam.h231
-rw-r--r--gmp/mpn/sh/add_n.asm59
-rw-r--r--gmp/mpn/sh/sh2/addmul_1.asm65
-rw-r--r--gmp/mpn/sh/sh2/mul_1.asm62
-rw-r--r--gmp/mpn/sh/sh2/submul_1.asm65
-rw-r--r--gmp/mpn/sh/sub_n.asm59
-rw-r--r--gmp/mpn/sparc32/README71
-rw-r--r--gmp/mpn/sparc32/add_n.asm245
-rw-r--r--gmp/mpn/sparc32/addmul_1.asm155
-rw-r--r--gmp/mpn/sparc32/gmp-mparam.h67
-rw-r--r--gmp/mpn/sparc32/lshift.asm105
-rw-r--r--gmp/mpn/sparc32/mul_1.asm146
-rw-r--r--gmp/mpn/sparc32/rshift.asm102
-rw-r--r--gmp/mpn/sparc32/sparc-defs.m479
-rw-r--r--gmp/mpn/sparc32/sub_n.asm335
-rw-r--r--gmp/mpn/sparc32/submul_1.asm155
-rw-r--r--gmp/mpn/sparc32/udiv.asm167
-rw-r--r--gmp/mpn/sparc32/udiv_nfp.asm202
-rw-r--r--gmp/mpn/sparc32/ultrasparct1/add_n.asm70
-rw-r--r--gmp/mpn/sparc32/ultrasparct1/addmul_1.asm90
-rw-r--r--gmp/mpn/sparc32/ultrasparct1/gmp-mparam.h153
-rw-r--r--gmp/mpn/sparc32/ultrasparct1/mul_1.asm83
-rw-r--r--gmp/mpn/sparc32/ultrasparct1/sqr_diagonal.asm55
-rw-r--r--gmp/mpn/sparc32/ultrasparct1/sub_n.asm70
-rw-r--r--gmp/mpn/sparc32/ultrasparct1/submul_1.asm91
-rw-r--r--gmp/mpn/sparc32/umul.asm77
-rw-r--r--gmp/mpn/sparc32/v8/addmul_1.asm131
-rw-r--r--gmp/mpn/sparc32/v8/gmp-mparam.h73
-rw-r--r--gmp/mpn/sparc32/v8/mul_1.asm112
-rw-r--r--gmp/mpn/sparc32/v8/submul_1.asm67
-rw-r--r--gmp/mpn/sparc32/v8/supersparc/gmp-mparam.h73
-rw-r--r--gmp/mpn/sparc32/v8/supersparc/udiv.asm131
-rw-r--r--gmp/mpn/sparc32/v8/udiv.asm131
-rw-r--r--gmp/mpn/sparc32/v8/umul.asm40
-rw-r--r--gmp/mpn/sparc32/v9/README4
-rw-r--r--gmp/mpn/sparc32/v9/add_n.asm129
-rw-r--r--gmp/mpn/sparc32/v9/addmul_1.asm306
-rw-r--r--gmp/mpn/sparc32/v9/gmp-mparam.h204
-rw-r--r--gmp/mpn/sparc32/v9/mul_1.asm287
-rw-r--r--gmp/mpn/sparc32/v9/sqr_diagonal.asm462
-rw-r--r--gmp/mpn/sparc32/v9/sub_n.asm129
-rw-r--r--gmp/mpn/sparc32/v9/submul_1.asm316
-rw-r--r--gmp/mpn/sparc32/v9/udiv.asm52
-rw-r--r--gmp/mpn/sparc64/README125
-rw-r--r--gmp/mpn/sparc64/copyd.asm89
-rw-r--r--gmp/mpn/sparc64/copyi.asm86
-rw-r--r--gmp/mpn/sparc64/dive_1.c158
-rw-r--r--gmp/mpn/sparc64/divrem_1.c243
-rw-r--r--gmp/mpn/sparc64/gcd_1.asm135
-rw-r--r--gmp/mpn/sparc64/gmp-mparam.h139
-rw-r--r--gmp/mpn/sparc64/lshift.asm140
-rw-r--r--gmp/mpn/sparc64/lshiftc.asm147
-rw-r--r--gmp/mpn/sparc64/mod_1.c239
-rw-r--r--gmp/mpn/sparc64/mod_1_4.c236
-rw-r--r--gmp/mpn/sparc64/mode1o.c197
-rw-r--r--gmp/mpn/sparc64/rshift.asm142
-rw-r--r--gmp/mpn/sparc64/sec_tabselect.asm162
-rw-r--r--gmp/mpn/sparc64/sparc64.h219
-rw-r--r--gmp/mpn/sparc64/ultrasparc1234/add_n.asm241
-rw-r--r--gmp/mpn/sparc64/ultrasparc1234/addmul_1.asm606
-rw-r--r--gmp/mpn/sparc64/ultrasparc1234/addmul_2.asm551
-rw-r--r--gmp/mpn/sparc64/ultrasparc1234/lshiftc.asm165
-rw-r--r--gmp/mpn/sparc64/ultrasparc1234/mul_1.asm580
-rw-r--r--gmp/mpn/sparc64/ultrasparc1234/sqr_diagonal.asm342
-rw-r--r--gmp/mpn/sparc64/ultrasparc1234/sub_n.asm241
-rw-r--r--gmp/mpn/sparc64/ultrasparc1234/submul_1.asm68
-rw-r--r--gmp/mpn/sparc64/ultrasparc34/gmp-mparam.h219
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/add_n.asm68
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/addlsh1_n.asm41
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/addlsh2_n.asm41
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/addlshC_n.asm69
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/addmul_1.asm86
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/gmp-mparam.h154
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/mul_1.asm82
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/rsblsh1_n.asm41
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/rsblsh2_n.asm41
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/rsblshC_n.asm69
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/sub_n.asm68
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/sublsh1_n.asm41
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/sublsh2_n.asm41
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/sublshC_n.asm69
-rw-r--r--gmp/mpn/sparc64/ultrasparct1/submul_1.asm86
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/add_n.asm126
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/addmul_1.asm182
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/aormul_2.asm228
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/aormul_4.asm219
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/aorslsh_n.asm147
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/bdiv_dbm1c.asm147
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/cnd_aors_n.asm143
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/dive_1.asm129
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/hamdist.asm78
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/invert_limb.asm92
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/missing.asm77
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/missing.m488
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/mod_1_4.asm233
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/mod_34lsub1.asm117
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/mode1o.asm82
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/mul_1.asm174
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/popcount.asm70
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/sqr_diag_addlsh1.asm93
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/sub_n.asm144
-rw-r--r--gmp/mpn/sparc64/ultrasparct3/submul_1.asm170
-rw-r--r--gmp/mpn/thumb/add_n.asm63
-rw-r--r--gmp/mpn/thumb/sub_n.asm63
-rw-r--r--gmp/mpn/vax/add_n.asm64
-rw-r--r--gmp/mpn/vax/addmul_1.asm124
-rw-r--r--gmp/mpn/vax/elf.m454
-rw-r--r--gmp/mpn/vax/gmp-mparam.h60
-rw-r--r--gmp/mpn/vax/lshift.asm59
-rw-r--r--gmp/mpn/vax/mul_1.asm118
-rw-r--r--gmp/mpn/vax/rshift.asm57
-rw-r--r--gmp/mpn/vax/sub_n.asm64
-rw-r--r--gmp/mpn/vax/submul_1.asm124
-rw-r--r--gmp/mpn/x86/README525
-rw-r--r--gmp/mpn/x86/aors_n.asm202
-rw-r--r--gmp/mpn/x86/aorsmul_1.asm156
-rw-r--r--gmp/mpn/x86/atom/aorrlsh1_n.asm53
-rw-r--r--gmp/mpn/x86/atom/aorrlsh2_n.asm53
-rw-r--r--gmp/mpn/x86/atom/aorrlshC_n.asm156
-rw-r--r--gmp/mpn/x86/atom/aors_n.asm159
-rw-r--r--gmp/mpn/x86/atom/aorslshC_n.asm247
-rw-r--r--gmp/mpn/x86/atom/bdiv_q_1.asm35
-rw-r--r--gmp/mpn/x86/atom/cnd_add_n.asm113
-rw-r--r--gmp/mpn/x86/atom/cnd_sub_n.asm124
-rw-r--r--gmp/mpn/x86/atom/dive_1.asm34
-rw-r--r--gmp/mpn/x86/atom/gmp-mparam.h201
-rw-r--r--gmp/mpn/x86/atom/logops_n.asm151
-rw-r--r--gmp/mpn/x86/atom/lshift.asm218
-rw-r--r--gmp/mpn/x86/atom/lshiftc.asm159
-rw-r--r--gmp/mpn/x86/atom/mmx/copyd.asm34
-rw-r--r--gmp/mpn/x86/atom/mmx/copyi.asm34
-rw-r--r--gmp/mpn/x86/atom/mmx/hamdist.asm34
-rw-r--r--gmp/mpn/x86/atom/mod_34lsub1.asm34
-rw-r--r--gmp/mpn/x86/atom/mode1o.asm34
-rw-r--r--gmp/mpn/x86/atom/rshift.asm152
-rw-r--r--gmp/mpn/x86/atom/sse2/aorsmul_1.asm174
-rw-r--r--gmp/mpn/x86/atom/sse2/bdiv_dbm1c.asm34
-rw-r--r--gmp/mpn/x86/atom/sse2/divrem_1.asm34
-rw-r--r--gmp/mpn/x86/atom/sse2/mod_1_1.asm34
-rw-r--r--gmp/mpn/x86/atom/sse2/mod_1_4.asm34
-rw-r--r--gmp/mpn/x86/atom/sse2/mul_1.asm124
-rw-r--r--gmp/mpn/x86/atom/sse2/mul_basecase.asm501
-rw-r--r--gmp/mpn/x86/atom/sse2/popcount.asm35
-rw-r--r--gmp/mpn/x86/atom/sse2/sqr_basecase.asm634
-rw-r--r--gmp/mpn/x86/atom/sublsh1_n.asm34
-rw-r--r--gmp/mpn/x86/atom/sublsh2_n.asm57
-rw-r--r--gmp/mpn/x86/bd1/gmp-mparam.h208
-rw-r--r--gmp/mpn/x86/bd2/gmp-mparam.h209
-rw-r--r--gmp/mpn/x86/bdiv_dbm1c.asm129
-rw-r--r--gmp/mpn/x86/bdiv_q_1.asm208
-rw-r--r--gmp/mpn/x86/bobcat/gmp-mparam.h197
-rw-r--r--gmp/mpn/x86/cnd_aors_n.asm124
-rw-r--r--gmp/mpn/x86/copyd.asm91
-rw-r--r--gmp/mpn/x86/copyi.asm99
-rw-r--r--gmp/mpn/x86/core2/gmp-mparam.h200
-rw-r--r--gmp/mpn/x86/coreihwl/gmp-mparam.h210
-rw-r--r--gmp/mpn/x86/coreinhm/gmp-mparam.h224
-rw-r--r--gmp/mpn/x86/coreisbr/gmp-mparam.h203
-rw-r--r--gmp/mpn/x86/darwin.m482
-rw-r--r--gmp/mpn/x86/dive_1.asm189
-rw-r--r--gmp/mpn/x86/divrem_1.asm233
-rw-r--r--gmp/mpn/x86/divrem_2.asm199
-rw-r--r--gmp/mpn/x86/fat/com.c32
-rw-r--r--gmp/mpn/x86/fat/fat.c473
-rw-r--r--gmp/mpn/x86/fat/fat_entry.asm220
-rw-r--r--gmp/mpn/x86/fat/gcd_1.c32
-rw-r--r--gmp/mpn/x86/fat/gmp-mparam.h71
-rw-r--r--gmp/mpn/x86/fat/lshiftc.c32
-rw-r--r--gmp/mpn/x86/fat/mod_1.c32
-rw-r--r--gmp/mpn/x86/fat/mod_1_1.c36
-rw-r--r--gmp/mpn/x86/fat/mod_1_2.c36
-rw-r--r--gmp/mpn/x86/fat/mod_1_4.c36
-rw-r--r--gmp/mpn/x86/fat/mode1o.c32
-rw-r--r--gmp/mpn/x86/fat/mullo_basecase.c32
-rw-r--r--gmp/mpn/x86/fat/redc_1.c32
-rw-r--r--gmp/mpn/x86/fat/redc_2.c32
-rw-r--r--gmp/mpn/x86/geode/gmp-mparam.h141
-rw-r--r--gmp/mpn/x86/gmp-mparam.h38
-rw-r--r--gmp/mpn/x86/i486/gmp-mparam.h69
-rw-r--r--gmp/mpn/x86/k10/gmp-mparam.h211
-rw-r--r--gmp/mpn/x86/k6/README251
-rw-r--r--gmp/mpn/x86/k6/aors_n.asm337
-rw-r--r--gmp/mpn/x86/k6/aorsmul_1.asm391
-rwxr-xr-xgmp/mpn/x86/k6/cross.pl182
-rw-r--r--gmp/mpn/x86/k6/divrem_1.asm203
-rw-r--r--gmp/mpn/x86/k6/gcd_1.asm362
-rw-r--r--gmp/mpn/x86/k6/gmp-mparam.h166
-rw-r--r--gmp/mpn/x86/k6/k62mmx/copyd.asm118
-rw-r--r--gmp/mpn/x86/k6/k62mmx/lshift.asm294
-rw-r--r--gmp/mpn/x86/k6/k62mmx/rshift.asm293
-rw-r--r--gmp/mpn/x86/k6/mmx/com.asm103
-rw-r--r--gmp/mpn/x86/k6/mmx/dive_1.asm281
-rw-r--r--gmp/mpn/x86/k6/mmx/logops_n.asm226
-rw-r--r--gmp/mpn/x86/k6/mmx/lshift.asm130
-rw-r--r--gmp/mpn/x86/k6/mmx/popham.asm236
-rw-r--r--gmp/mpn/x86/k6/mmx/rshift.asm130
-rw-r--r--gmp/mpn/x86/k6/mod_34lsub1.asm190
-rw-r--r--gmp/mpn/x86/k6/mode1o.asm175
-rw-r--r--gmp/mpn/x86/k6/mul_1.asm292
-rw-r--r--gmp/mpn/x86/k6/mul_basecase.asm612
-rw-r--r--gmp/mpn/x86/k6/pre_mod_1.asm146
-rw-r--r--gmp/mpn/x86/k6/sqr_basecase.asm680
-rw-r--r--gmp/mpn/x86/k7/README174
-rw-r--r--gmp/mpn/x86/k7/addlsh1_n.asm196
-rw-r--r--gmp/mpn/x86/k7/aors_n.asm258
-rw-r--r--gmp/mpn/x86/k7/aorsmul_1.asm167
-rw-r--r--gmp/mpn/x86/k7/bdiv_q_1.asm244
-rw-r--r--gmp/mpn/x86/k7/dive_1.asm207
-rw-r--r--gmp/mpn/x86/k7/gcd_1.asm186
-rw-r--r--gmp/mpn/x86/k7/gmp-mparam.h241
-rw-r--r--gmp/mpn/x86/k7/invert_limb.asm193
-rw-r--r--gmp/mpn/x86/k7/mmx/com.asm125
-rw-r--r--gmp/mpn/x86/k7/mmx/copyd.asm144
-rw-r--r--gmp/mpn/x86/k7/mmx/copyi.asm157
-rw-r--r--gmp/mpn/x86/k7/mmx/divrem_1.asm832
-rw-r--r--gmp/mpn/x86/k7/mmx/lshift.asm481
-rw-r--r--gmp/mpn/x86/k7/mmx/popham.asm213
-rw-r--r--gmp/mpn/x86/k7/mmx/rshift.asm480
-rw-r--r--gmp/mpn/x86/k7/mod_1_1.asm221
-rw-r--r--gmp/mpn/x86/k7/mod_1_4.asm260
-rw-r--r--gmp/mpn/x86/k7/mod_34lsub1.asm188
-rw-r--r--gmp/mpn/x86/k7/mode1o.asm180
-rw-r--r--gmp/mpn/x86/k7/mul_1.asm237
-rw-r--r--gmp/mpn/x86/k7/mul_basecase.asm602
-rw-r--r--gmp/mpn/x86/k7/sqr_basecase.asm635
-rw-r--r--gmp/mpn/x86/k7/sublsh1_n.asm173
-rw-r--r--gmp/mpn/x86/k8/gmp-mparam.h198
-rw-r--r--gmp/mpn/x86/lshift.asm106
-rw-r--r--gmp/mpn/x86/mmx/sec_tabselect.asm163
-rw-r--r--gmp/mpn/x86/mod_34lsub1.asm183
-rw-r--r--gmp/mpn/x86/mul_1.asm140
-rw-r--r--gmp/mpn/x86/mul_basecase.asm223
-rw-r--r--gmp/mpn/x86/nano/gmp-mparam.h162
-rw-r--r--gmp/mpn/x86/p6/README125
-rw-r--r--gmp/mpn/x86/p6/aors_n.asm156
-rw-r--r--gmp/mpn/x86/p6/aorsmul_1.asm320
-rw-r--r--gmp/mpn/x86/p6/bdiv_q_1.asm286
-rw-r--r--gmp/mpn/x86/p6/copyd.asm178
-rw-r--r--gmp/mpn/x86/p6/dive_1.asm266
-rw-r--r--gmp/mpn/x86/p6/gcd_1.asm156
-rw-r--r--gmp/mpn/x86/p6/gmp-mparam.h194
-rw-r--r--gmp/mpn/x86/p6/lshsub_n.asm169
-rw-r--r--gmp/mpn/x86/p6/mmx/divrem_1.asm767
-rw-r--r--gmp/mpn/x86/p6/mmx/gmp-mparam.h198
-rw-r--r--gmp/mpn/x86/p6/mmx/lshift.asm38
-rw-r--r--gmp/mpn/x86/p6/mmx/popham.asm39
-rw-r--r--gmp/mpn/x86/p6/mmx/rshift.asm38
-rw-r--r--gmp/mpn/x86/p6/mod_34lsub1.asm190
-rw-r--r--gmp/mpn/x86/p6/mode1o.asm169
-rw-r--r--gmp/mpn/x86/p6/mul_basecase.asm607
-rw-r--r--gmp/mpn/x86/p6/p3mmx/popham.asm42
-rw-r--r--gmp/mpn/x86/p6/sqr_basecase.asm649
-rw-r--r--gmp/mpn/x86/p6/sse2/addmul_1.asm37
-rw-r--r--gmp/mpn/x86/p6/sse2/gmp-mparam.h197
-rw-r--r--gmp/mpn/x86/p6/sse2/mod_1_1.asm34
-rw-r--r--gmp/mpn/x86/p6/sse2/mod_1_4.asm34
-rw-r--r--gmp/mpn/x86/p6/sse2/mul_1.asm38
-rw-r--r--gmp/mpn/x86/p6/sse2/mul_basecase.asm35
-rw-r--r--gmp/mpn/x86/p6/sse2/popcount.asm35
-rw-r--r--gmp/mpn/x86/p6/sse2/sqr_basecase.asm35
-rw-r--r--gmp/mpn/x86/p6/sse2/submul_1.asm35
-rw-r--r--gmp/mpn/x86/pentium/README181
-rw-r--r--gmp/mpn/x86/pentium/aors_n.asm203
-rw-r--r--gmp/mpn/x86/pentium/aorsmul_1.asm144
-rw-r--r--gmp/mpn/x86/pentium/bdiv_q_1.asm260
-rw-r--r--gmp/mpn/x86/pentium/com.asm181
-rw-r--r--gmp/mpn/x86/pentium/copyd.asm146
-rw-r--r--gmp/mpn/x86/pentium/copyi.asm164
-rw-r--r--gmp/mpn/x86/pentium/dive_1.asm272
-rw-r--r--gmp/mpn/x86/pentium/gmp-mparam.h76
-rw-r--r--gmp/mpn/x86/pentium/hamdist.asm143
-rw-r--r--gmp/mpn/x86/pentium/logops_n.asm176
-rw-r--r--gmp/mpn/x86/pentium/lshift.asm243
-rw-r--r--gmp/mpn/x86/pentium/mmx/gmp-mparam.h163
-rw-r--r--gmp/mpn/x86/pentium/mmx/hamdist.asm40
-rw-r--r--gmp/mpn/x86/pentium/mmx/lshift.asm463
-rw-r--r--gmp/mpn/x86/pentium/mmx/mul_1.asm371
-rw-r--r--gmp/mpn/x86/pentium/mmx/rshift.asm468
-rw-r--r--gmp/mpn/x86/pentium/mod_34lsub1.asm192
-rw-r--r--gmp/mpn/x86/pentium/mode1o.asm266
-rw-r--r--gmp/mpn/x86/pentium/mul_1.asm177
-rw-r--r--gmp/mpn/x86/pentium/mul_2.asm150
-rw-r--r--gmp/mpn/x86/pentium/mul_basecase.asm143
-rw-r--r--gmp/mpn/x86/pentium/popcount.asm134
-rw-r--r--gmp/mpn/x86/pentium/rshift.asm243
-rw-r--r--gmp/mpn/x86/pentium/sqr_basecase.asm528
-rw-r--r--gmp/mpn/x86/pentium4/README124
-rw-r--r--gmp/mpn/x86/pentium4/copyd.asm71
-rw-r--r--gmp/mpn/x86/pentium4/copyi.asm93
-rw-r--r--gmp/mpn/x86/pentium4/mmx/lshift.asm39
-rw-r--r--gmp/mpn/x86/pentium4/mmx/popham.asm203
-rw-r--r--gmp/mpn/x86/pentium4/mmx/rshift.asm39
-rw-r--r--gmp/mpn/x86/pentium4/sse2/add_n.asm101
-rw-r--r--gmp/mpn/x86/pentium4/sse2/addlsh1_n.asm108
-rw-r--r--gmp/mpn/x86/pentium4/sse2/addmul_1.asm189
-rw-r--r--gmp/mpn/x86/pentium4/sse2/bdiv_dbm1c.asm141
-rw-r--r--gmp/mpn/x86/pentium4/sse2/bdiv_q_1.asm233
-rw-r--r--gmp/mpn/x86/pentium4/sse2/cnd_add_n.asm95
-rw-r--r--gmp/mpn/x86/pentium4/sse2/cnd_sub_n.asm114
-rw-r--r--gmp/mpn/x86/pentium4/sse2/dive_1.asm215
-rw-r--r--gmp/mpn/x86/pentium4/sse2/divrem_1.asm645
-rw-r--r--gmp/mpn/x86/pentium4/sse2/gmp-mparam.h206
-rw-r--r--gmp/mpn/x86/pentium4/sse2/mod_1_1.asm166
-rw-r--r--gmp/mpn/x86/pentium4/sse2/mod_1_4.asm269
-rw-r--r--gmp/mpn/x86/pentium4/sse2/mod_34lsub1.asm175
-rw-r--r--gmp/mpn/x86/pentium4/sse2/mode1o.asm174
-rw-r--r--gmp/mpn/x86/pentium4/sse2/mul_1.asm164
-rw-r--r--gmp/mpn/x86/pentium4/sse2/mul_basecase.asm662
-rw-r--r--gmp/mpn/x86/pentium4/sse2/popcount.asm280
-rw-r--r--gmp/mpn/x86/pentium4/sse2/rsh1add_n.asm126
-rw-r--r--gmp/mpn/x86/pentium4/sse2/sqr_basecase.asm705
-rw-r--r--gmp/mpn/x86/pentium4/sse2/sub_n.asm119
-rw-r--r--gmp/mpn/x86/pentium4/sse2/submul_1.asm182
-rw-r--r--gmp/mpn/x86/rshift.asm108
-rw-r--r--gmp/mpn/x86/sec_tabselect.asm115
-rw-r--r--gmp/mpn/x86/sqr_basecase.asm359
-rwxr-xr-xgmp/mpn/x86/t-zdisp.sh71
-rwxr-xr-xgmp/mpn/x86/t-zdisp2.pl147
-rw-r--r--gmp/mpn/x86/udiv.asm52
-rw-r--r--gmp/mpn/x86/umul.asm51
-rw-r--r--gmp/mpn/x86/x86-defs.m4999
-rw-r--r--gmp/mpn/x86_64/README74
-rw-r--r--gmp/mpn/x86_64/addaddmul_1msb0.asm170
-rw-r--r--gmp/mpn/x86_64/addmul_2.asm184
-rw-r--r--gmp/mpn/x86_64/aorrlsh1_n.asm170
-rw-r--r--gmp/mpn/x86_64/aorrlsh2_n.asm53
-rw-r--r--gmp/mpn/x86_64/aorrlshC_n.asm160
-rw-r--r--gmp/mpn/x86_64/aorrlsh_n.asm176
-rw-r--r--gmp/mpn/x86_64/aors_err1_n.asm225
-rw-r--r--gmp/mpn/x86_64/aors_err2_n.asm172
-rw-r--r--gmp/mpn/x86_64/aors_err3_n.asm156
-rw-r--r--gmp/mpn/x86_64/aors_n.asm169
-rw-r--r--gmp/mpn/x86_64/aorsmul_1.asm180
-rw-r--r--gmp/mpn/x86_64/atom/addmul_2.asm186
-rw-r--r--gmp/mpn/x86_64/atom/aorrlsh1_n.asm238
-rw-r--r--gmp/mpn/x86_64/atom/aorrlsh2_n.asm191
-rw-r--r--gmp/mpn/x86_64/atom/aors_n.asm37
-rw-r--r--gmp/mpn/x86_64/atom/aorsmul_1.asm190
-rw-r--r--gmp/mpn/x86_64/atom/com.asm37
-rw-r--r--gmp/mpn/x86_64/atom/copyd.asm37
-rw-r--r--gmp/mpn/x86_64/atom/copyi.asm37
-rw-r--r--gmp/mpn/x86_64/atom/dive_1.asm37
-rw-r--r--gmp/mpn/x86_64/atom/gmp-mparam.h220
-rw-r--r--gmp/mpn/x86_64/atom/lshift.asm123
-rw-r--r--gmp/mpn/x86_64/atom/lshiftc.asm127
-rw-r--r--gmp/mpn/x86_64/atom/mul_1.asm143
-rw-r--r--gmp/mpn/x86_64/atom/mul_2.asm186
-rw-r--r--gmp/mpn/x86_64/atom/popcount.asm35
-rw-r--r--gmp/mpn/x86_64/atom/redc_1.asm574
-rw-r--r--gmp/mpn/x86_64/atom/rsh1aors_n.asm287
-rw-r--r--gmp/mpn/x86_64/atom/rshift.asm121
-rw-r--r--gmp/mpn/x86_64/atom/sublsh1_n.asm242
-rw-r--r--gmp/mpn/x86_64/bd1/README11
-rw-r--r--gmp/mpn/x86_64/bd1/aorrlsh1_n.asm37
-rw-r--r--gmp/mpn/x86_64/bd1/aorsmul_1.asm181
-rw-r--r--gmp/mpn/x86_64/bd1/com.asm37
-rw-r--r--gmp/mpn/x86_64/bd1/copyd.asm37
-rw-r--r--gmp/mpn/x86_64/bd1/copyi.asm37
-rw-r--r--gmp/mpn/x86_64/bd1/gcd_1.asm37
-rw-r--r--gmp/mpn/x86_64/bd1/gmp-mparam.h236
-rw-r--r--gmp/mpn/x86_64/bd1/hamdist.asm38
-rw-r--r--gmp/mpn/x86_64/bd1/mul_1.asm184
-rw-r--r--gmp/mpn/x86_64/bd1/mul_2.asm192
-rw-r--r--gmp/mpn/x86_64/bd1/mul_basecase.asm416
-rw-r--r--gmp/mpn/x86_64/bd1/popcount.asm38
-rw-r--r--gmp/mpn/x86_64/bd1/sec_tabselect.asm37
-rw-r--r--gmp/mpn/x86_64/bd1/sublsh1_n.asm37
-rw-r--r--gmp/mpn/x86_64/bd2/gmp-mparam.h237
-rw-r--r--gmp/mpn/x86_64/bdiv_dbm1c.asm106
-rw-r--r--gmp/mpn/x86_64/bdiv_q_1.asm167
-rw-r--r--gmp/mpn/x86_64/bobcat/aors_n.asm150
-rw-r--r--gmp/mpn/x86_64/bobcat/aorsmul_1.asm183
-rw-r--r--gmp/mpn/x86_64/bobcat/copyd.asm91
-rw-r--r--gmp/mpn/x86_64/bobcat/copyi.asm94
-rw-r--r--gmp/mpn/x86_64/bobcat/gmp-mparam.h208
-rw-r--r--gmp/mpn/x86_64/bobcat/mul_1.asm187
-rw-r--r--gmp/mpn/x86_64/bobcat/mul_basecase.asm486
-rw-r--r--gmp/mpn/x86_64/bobcat/redc_1.asm502
-rw-r--r--gmp/mpn/x86_64/bobcat/sqr_basecase.asm565
-rw-r--r--gmp/mpn/x86_64/cnd_aors_n.asm183
-rw-r--r--gmp/mpn/x86_64/com.asm95
-rw-r--r--gmp/mpn/x86_64/copyd.asm93
-rw-r--r--gmp/mpn/x86_64/copyi.asm92
-rw-r--r--gmp/mpn/x86_64/core2/aorrlsh1_n.asm53
-rw-r--r--gmp/mpn/x86_64/core2/aorrlsh2_n.asm53
-rw-r--r--gmp/mpn/x86_64/core2/aorrlsh_n.asm38
-rw-r--r--gmp/mpn/x86_64/core2/aors_err1_n.asm225
-rw-r--r--gmp/mpn/x86_64/core2/aors_n.asm141
-rw-r--r--gmp/mpn/x86_64/core2/aorsmul_1.asm178
-rw-r--r--gmp/mpn/x86_64/core2/copyd.asm37
-rw-r--r--gmp/mpn/x86_64/core2/copyi.asm37
-rw-r--r--gmp/mpn/x86_64/core2/divrem_1.asm237
-rw-r--r--gmp/mpn/x86_64/core2/gcd_1.asm144
-rw-r--r--gmp/mpn/x86_64/core2/gmp-mparam.h217
-rw-r--r--gmp/mpn/x86_64/core2/lshift.asm149
-rw-r--r--gmp/mpn/x86_64/core2/lshiftc.asm159
-rw-r--r--gmp/mpn/x86_64/core2/mul_basecase.asm975
-rw-r--r--gmp/mpn/x86_64/core2/mullo_basecase.asm427
-rw-r--r--gmp/mpn/x86_64/core2/popcount.asm35
-rw-r--r--gmp/mpn/x86_64/core2/redc_1.asm425
-rw-r--r--gmp/mpn/x86_64/core2/rsh1aors_n.asm169
-rw-r--r--gmp/mpn/x86_64/core2/rshift.asm147
-rw-r--r--gmp/mpn/x86_64/core2/sec_tabselect.asm37
-rw-r--r--gmp/mpn/x86_64/core2/sqr_basecase.asm984
-rw-r--r--gmp/mpn/x86_64/core2/sublsh1_n.asm47
-rw-r--r--gmp/mpn/x86_64/core2/sublsh2_n.asm47
-rw-r--r--gmp/mpn/x86_64/core2/sublshC_n.asm158
-rw-r--r--gmp/mpn/x86_64/coreihwl/addmul_2.asm238
-rw-r--r--gmp/mpn/x86_64/coreihwl/aorsmul_1.asm198
-rw-r--r--gmp/mpn/x86_64/coreihwl/gmp-mparam.h237
-rw-r--r--gmp/mpn/x86_64/coreihwl/mul_1.asm155
-rw-r--r--gmp/mpn/x86_64/coreihwl/mul_2.asm173
-rw-r--r--gmp/mpn/x86_64/coreihwl/mul_basecase.asm441
-rw-r--r--gmp/mpn/x86_64/coreihwl/mullo_basecase.asm426
-rw-r--r--gmp/mpn/x86_64/coreihwl/redc_1.asm433
-rw-r--r--gmp/mpn/x86_64/coreihwl/sqr_basecase.asm506
-rw-r--r--gmp/mpn/x86_64/coreinhm/aorrlsh_n.asm200
-rw-r--r--gmp/mpn/x86_64/coreinhm/aorsmul_1.asm187
-rw-r--r--gmp/mpn/x86_64/coreinhm/gmp-mparam.h231
-rw-r--r--gmp/mpn/x86_64/coreinhm/hamdist.asm38
-rw-r--r--gmp/mpn/x86_64/coreinhm/popcount.asm38
-rw-r--r--gmp/mpn/x86_64/coreinhm/redc_1.asm544
-rw-r--r--gmp/mpn/x86_64/coreinhm/sec_tabselect.asm37
-rw-r--r--gmp/mpn/x86_64/coreisbr/addmul_2.asm224
-rw-r--r--gmp/mpn/x86_64/coreisbr/aorrlsh1_n.asm54
-rw-r--r--gmp/mpn/x86_64/coreisbr/aorrlsh2_n.asm56
-rw-r--r--gmp/mpn/x86_64/coreisbr/aorrlshC_n.asm173
-rw-r--r--gmp/mpn/x86_64/coreisbr/aorrlsh_n.asm215
-rw-r--r--gmp/mpn/x86_64/coreisbr/aors_n.asm198
-rw-r--r--gmp/mpn/x86_64/coreisbr/aorsmul_1.asm209
-rw-r--r--gmp/mpn/x86_64/coreisbr/divrem_1.asm37
-rw-r--r--gmp/mpn/x86_64/coreisbr/gmp-mparam.h224
-rw-r--r--gmp/mpn/x86_64/coreisbr/lshift.asm37
-rw-r--r--gmp/mpn/x86_64/coreisbr/lshiftc.asm37
-rw-r--r--gmp/mpn/x86_64/coreisbr/mul_1.asm161
-rw-r--r--gmp/mpn/x86_64/coreisbr/mul_2.asm163
-rw-r--r--gmp/mpn/x86_64/coreisbr/mul_basecase.asm407
-rw-r--r--gmp/mpn/x86_64/coreisbr/mullo_basecase.asm384
-rw-r--r--gmp/mpn/x86_64/coreisbr/popcount.asm118
-rw-r--r--gmp/mpn/x86_64/coreisbr/redc_1.asm541
-rw-r--r--gmp/mpn/x86_64/coreisbr/rsh1aors_n.asm193
-rw-r--r--gmp/mpn/x86_64/coreisbr/rshift.asm37
-rw-r--r--gmp/mpn/x86_64/coreisbr/sec_tabselect.asm37
-rw-r--r--gmp/mpn/x86_64/coreisbr/sqr_basecase.asm484
-rw-r--r--gmp/mpn/x86_64/darwin.m481
-rw-r--r--gmp/mpn/x86_64/div_qr_1n_pi1.asm247
-rw-r--r--gmp/mpn/x86_64/div_qr_2n_pi1.asm158
-rw-r--r--gmp/mpn/x86_64/div_qr_2u_pi1.asm200
-rw-r--r--gmp/mpn/x86_64/dive_1.asm158
-rw-r--r--gmp/mpn/x86_64/divrem_1.asm306
-rw-r--r--gmp/mpn/x86_64/divrem_2.asm189
-rw-r--r--gmp/mpn/x86_64/dos64.m4100
-rw-r--r--gmp/mpn/x86_64/fastavx/copyd.asm171
-rw-r--r--gmp/mpn/x86_64/fastavx/copyi.asm168
-rw-r--r--gmp/mpn/x86_64/fastsse/README21
-rw-r--r--gmp/mpn/x86_64/fastsse/com-palignr.asm302
-rw-r--r--gmp/mpn/x86_64/fastsse/com.asm161
-rw-r--r--gmp/mpn/x86_64/fastsse/copyd-palignr.asm251
-rw-r--r--gmp/mpn/x86_64/fastsse/copyd.asm145
-rw-r--r--gmp/mpn/x86_64/fastsse/copyi-palignr.asm295
-rw-r--r--gmp/mpn/x86_64/fastsse/copyi.asm166
-rw-r--r--gmp/mpn/x86_64/fastsse/lshift-movdqu2.asm182
-rw-r--r--gmp/mpn/x86_64/fastsse/lshift.asm169
-rw-r--r--gmp/mpn/x86_64/fastsse/lshiftc-movdqu2.asm193
-rw-r--r--gmp/mpn/x86_64/fastsse/lshiftc.asm179
-rw-r--r--gmp/mpn/x86_64/fastsse/rshift-movdqu2.asm201
-rw-r--r--gmp/mpn/x86_64/fastsse/sec_tabselect.asm192
-rw-r--r--gmp/mpn/x86_64/fat/fat.c368
-rw-r--r--gmp/mpn/x86_64/fat/fat_entry.asm204
-rw-r--r--gmp/mpn/x86_64/fat/gmp-mparam.h72
-rw-r--r--gmp/mpn/x86_64/fat/mod_1.c32
-rw-r--r--gmp/mpn/x86_64/fat/mul_basecase.c32
-rw-r--r--gmp/mpn/x86_64/fat/mullo_basecase.c32
-rw-r--r--gmp/mpn/x86_64/fat/redc_1.c32
-rw-r--r--gmp/mpn/x86_64/fat/redc_2.c32
-rw-r--r--gmp/mpn/x86_64/fat/sqr_basecase.c32
-rw-r--r--gmp/mpn/x86_64/gcd_1.asm163
-rw-r--r--gmp/mpn/x86_64/gmp-mparam.h218
-rw-r--r--gmp/mpn/x86_64/invert_limb.asm115
-rw-r--r--gmp/mpn/x86_64/invert_limb_table.asm50
-rw-r--r--gmp/mpn/x86_64/k10/gcd_1.asm37
-rw-r--r--gmp/mpn/x86_64/k10/gmp-mparam.h222
-rw-r--r--gmp/mpn/x86_64/k10/hamdist.asm103
-rw-r--r--gmp/mpn/x86_64/k10/lshift.asm37
-rw-r--r--gmp/mpn/x86_64/k10/lshiftc.asm37
-rw-r--r--gmp/mpn/x86_64/k10/popcount.asm138
-rw-r--r--gmp/mpn/x86_64/k10/rshift.asm37
-rw-r--r--gmp/mpn/x86_64/k10/sec_tabselect.asm37
-rw-r--r--gmp/mpn/x86_64/k8/aorrlsh_n.asm217
-rw-r--r--gmp/mpn/x86_64/k8/div_qr_1n_pi1.asm249
-rw-r--r--gmp/mpn/x86_64/k8/gmp-mparam.h236
-rw-r--r--gmp/mpn/x86_64/k8/mul_basecase.asm469
-rw-r--r--gmp/mpn/x86_64/k8/mullo_basecase.asm436
-rw-r--r--gmp/mpn/x86_64/k8/mulmid_basecase.asm559
-rw-r--r--gmp/mpn/x86_64/k8/redc_1.asm590
-rw-r--r--gmp/mpn/x86_64/k8/sqr_basecase.asm807
-rw-r--r--gmp/mpn/x86_64/logops_n.asm244
-rw-r--r--gmp/mpn/x86_64/lshift.asm247
-rw-r--r--gmp/mpn/x86_64/lshiftc.asm182
-rw-r--r--gmp/mpn/x86_64/lshsub_n.asm172
-rw-r--r--gmp/mpn/x86_64/missing-call.m453
-rw-r--r--gmp/mpn/x86_64/missing-inline.m4100
-rw-r--r--gmp/mpn/x86_64/missing.asm130
-rw-r--r--gmp/mpn/x86_64/mod_1_1.asm235
-rw-r--r--gmp/mpn/x86_64/mod_1_2.asm238
-rw-r--r--gmp/mpn/x86_64/mod_1_4.asm269
-rw-r--r--gmp/mpn/x86_64/mod_34lsub1.asm205
-rw-r--r--gmp/mpn/x86_64/mode1o.asm171
-rw-r--r--gmp/mpn/x86_64/mul_1.asm183
-rw-r--r--gmp/mpn/x86_64/mul_2.asm192
-rw-r--r--gmp/mpn/x86_64/mulx/adx/addmul_1.asm149
-rw-r--r--gmp/mpn/x86_64/mulx/aorsmul_1.asm161
-rw-r--r--gmp/mpn/x86_64/mulx/mul_1.asm154
-rw-r--r--gmp/mpn/x86_64/nano/copyd.asm37
-rw-r--r--gmp/mpn/x86_64/nano/copyi.asm37
-rw-r--r--gmp/mpn/x86_64/nano/dive_1.asm166
-rw-r--r--gmp/mpn/x86_64/nano/gcd_1.asm37
-rw-r--r--gmp/mpn/x86_64/nano/gmp-mparam.h243
-rw-r--r--gmp/mpn/x86_64/nano/popcount.asm35
-rw-r--r--gmp/mpn/x86_64/pentium4/aors_n.asm196
-rw-r--r--gmp/mpn/x86_64/pentium4/aorslsh1_n.asm50
-rw-r--r--gmp/mpn/x86_64/pentium4/aorslsh2_n.asm50
-rw-r--r--gmp/mpn/x86_64/pentium4/aorslshC_n.asm203
-rw-r--r--gmp/mpn/x86_64/pentium4/gmp-mparam.h231
-rw-r--r--gmp/mpn/x86_64/pentium4/lshift.asm166
-rw-r--r--gmp/mpn/x86_64/pentium4/lshiftc.asm179
-rw-r--r--gmp/mpn/x86_64/pentium4/mod_34lsub1.asm167
-rw-r--r--gmp/mpn/x86_64/pentium4/popcount.asm35
-rw-r--r--gmp/mpn/x86_64/pentium4/rsh1aors_n.asm334
-rw-r--r--gmp/mpn/x86_64/pentium4/rshift.asm169
-rw-r--r--gmp/mpn/x86_64/pentium4/sec_tabselect.asm37
-rw-r--r--gmp/mpn/x86_64/popham.asm177
-rw-r--r--gmp/mpn/x86_64/rsh1aors_n.asm189
-rw-r--r--gmp/mpn/x86_64/rshift.asm176
-rw-r--r--gmp/mpn/x86_64/sec_tabselect.asm176
-rw-r--r--gmp/mpn/x86_64/sqr_diag_addlsh1.asm116
-rw-r--r--gmp/mpn/x86_64/sublsh1_n.asm160
-rw-r--r--gmp/mpn/x86_64/x86_64-defs.m4354
-rw-r--r--gmp/mpq/Makefile.am41
-rw-r--r--gmp/mpq/Makefile.in563
-rw-r--r--gmp/mpq/abs.c56
-rw-r--r--gmp/mpq/aors.c113
-rw-r--r--gmp/mpq/canonicalize.c63
-rw-r--r--gmp/mpq/clear.c41
-rw-r--r--gmp/mpq/clears.c52
-rw-r--r--gmp/mpq/cmp.c126
-rw-r--r--gmp/mpq/cmp_si.c67
-rw-r--r--gmp/mpq/cmp_ui.c100
-rw-r--r--gmp/mpq/div.c115
-rw-r--r--gmp/mpq/equal.c69
-rw-r--r--gmp/mpq/get_d.c175
-rw-r--r--gmp/mpq/get_den.c43
-rw-r--r--gmp/mpq/get_num.c45
-rw-r--r--gmp/mpq/get_str.c76
-rw-r--r--gmp/mpq/init.c49
-rw-r--r--gmp/mpq/inits.c49
-rw-r--r--gmp/mpq/inp_str.c76
-rw-r--r--gmp/mpq/inv.c71
-rw-r--r--gmp/mpq/md_2exp.c111
-rw-r--r--gmp/mpq/mul.c103
-rw-r--r--gmp/mpq/neg.c58
-rw-r--r--gmp/mpq/out_str.c54
-rw-r--r--gmp/mpq/set.c51
-rw-r--r--gmp/mpq/set_d.c166
-rw-r--r--gmp/mpq/set_den.c45
-rw-r--r--gmp/mpq/set_f.c107
-rw-r--r--gmp/mpq/set_num.c45
-rw-r--r--gmp/mpq/set_si.c65
-rw-r--r--gmp/mpq/set_str.c69
-rw-r--r--gmp/mpq/set_ui.c61
-rw-r--r--gmp/mpq/set_z.c49
-rw-r--r--gmp/mpq/swap.c71
-rw-r--r--gmp/mpz/2fac_ui.c100
-rw-r--r--gmp/mpz/Makefile.am67
-rw-r--r--gmp/mpz/Makefile.in614
-rw-r--r--gmp/mpz/abs.c55
-rw-r--r--gmp/mpz/add.c33
-rw-r--r--gmp/mpz/add_ui.c33
-rw-r--r--gmp/mpz/and.c244
-rw-r--r--gmp/mpz/aors.h124
-rw-r--r--gmp/mpz/aors_ui.h121
-rw-r--r--gmp/mpz/aorsmul.c164
-rw-r--r--gmp/mpz/aorsmul_i.c255
-rw-r--r--gmp/mpz/array_init.c50
-rw-r--r--gmp/mpz/bin_ui.c143
-rw-r--r--gmp/mpz/bin_uiui.c696
-rw-r--r--gmp/mpz/cdiv_q.c53
-rw-r--r--gmp/mpz/cdiv_q_ui.c103
-rw-r--r--gmp/mpz/cdiv_qr.c65
-rw-r--r--gmp/mpz/cdiv_qr_ui.c119
-rw-r--r--gmp/mpz/cdiv_r.c61
-rw-r--r--gmp/mpz/cdiv_r_ui.c110
-rw-r--r--gmp/mpz/cdiv_ui.c103
-rw-r--r--gmp/mpz/cfdiv_q_2exp.c113
-rw-r--r--gmp/mpz/cfdiv_r_2exp.c164
-rw-r--r--gmp/mpz/clear.c40
-rw-r--r--gmp/mpz/clears.c49
-rw-r--r--gmp/mpz/clrbit.c116
-rw-r--r--gmp/mpz/cmp.c54
-rw-r--r--gmp/mpz/cmp_d.c145
-rw-r--r--gmp/mpz/cmp_si.c70
-rw-r--r--gmp/mpz/cmp_ui.c78
-rw-r--r--gmp/mpz/cmpabs.c54
-rw-r--r--gmp/mpz/cmpabs_d.c130
-rw-r--r--gmp/mpz/cmpabs_ui.c77
-rw-r--r--gmp/mpz/com.c88
-rw-r--r--gmp/mpz/combit.c103
-rw-r--r--gmp/mpz/cong.c183
-rw-r--r--gmp/mpz/cong_2exp.c150
-rw-r--r--gmp/mpz/cong_ui.c116
-rw-r--r--gmp/mpz/dive_ui.c69
-rw-r--r--gmp/mpz/divegcd.c157
-rw-r--r--gmp/mpz/divexact.c91
-rw-r--r--gmp/mpz/divis.c44
-rw-r--r--gmp/mpz/divis_2exp.c61
-rw-r--r--gmp/mpz/divis_ui.c81
-rw-r--r--gmp/mpz/dump.c49
-rw-r--r--gmp/mpz/export.c190
-rw-r--r--gmp/mpz/fac_ui.c108
-rw-r--r--gmp/mpz/fdiv_q.c53
-rw-r--r--gmp/mpz/fdiv_q_ui.c101
-rw-r--r--gmp/mpz/fdiv_qr.c65
-rw-r--r--gmp/mpz/fdiv_qr_ui.c118
-rw-r--r--gmp/mpz/fdiv_r.c60
-rw-r--r--gmp/mpz/fdiv_r_ui.c108
-rw-r--r--gmp/mpz/fdiv_ui.c101
-rw-r--r--gmp/mpz/fib2_ui.c50
-rw-r--r--gmp/mpz/fib_ui.c152
-rw-r--r--gmp/mpz/fits_s.h61
-rw-r--r--gmp/mpz/fits_sint.c36
-rw-r--r--gmp/mpz/fits_slong.c36
-rw-r--r--gmp/mpz/fits_sshort.c36
-rw-r--r--gmp/mpz/fits_uint.c34
-rw-r--r--gmp/mpz/fits_ulong.c34
-rw-r--r--gmp/mpz/fits_ushort.c34
-rw-r--r--gmp/mpz/gcd.c167
-rw-r--r--gmp/mpz/gcd_ui.c85
-rw-r--r--gmp/mpz/gcdext.c124
-rw-r--r--gmp/mpz/get_d.c44
-rw-r--r--gmp/mpz/get_d_2exp.c54
-rw-r--r--gmp/mpz/get_si.c53
-rw-r--r--gmp/mpz/get_str.c119
-rw-r--r--gmp/mpz/get_ui.c34
-rw-r--r--gmp/mpz/getlimbn.c34
-rw-r--r--gmp/mpz/hamdist.c175
-rw-r--r--gmp/mpz/import.c180
-rw-r--r--gmp/mpz/init.c45
-rw-r--r--gmp/mpz/init2.c61
-rw-r--r--gmp/mpz/inits.c49
-rw-r--r--gmp/mpz/inp_raw.c173
-rw-r--r--gmp/mpz/inp_str.c174
-rw-r--r--gmp/mpz/invert.c73
-rw-r--r--gmp/mpz/ior.c230
-rw-r--r--gmp/mpz/iset.c59
-rw-r--r--gmp/mpz/iset_d.c42
-rw-r--r--gmp/mpz/iset_si.c59
-rw-r--r--gmp/mpz/iset_str.c52
-rw-r--r--gmp/mpz/iset_ui.c59
-rw-r--r--gmp/mpz/jacobi.c211
-rw-r--r--gmp/mpz/kronsz.c138
-rw-r--r--gmp/mpz/kronuz.c130
-rw-r--r--gmp/mpz/kronzs.c93
-rw-r--r--gmp/mpz/kronzu.c89
-rw-r--r--gmp/mpz/lcm.c88
-rw-r--r--gmp/mpz/lcm_ui.c79
-rw-r--r--gmp/mpz/limbs_finish.c40
-rw-r--r--gmp/mpz/limbs_modify.c39
-rw-r--r--gmp/mpz/limbs_read.c38
-rw-r--r--gmp/mpz/limbs_write.c39
-rw-r--r--gmp/mpz/lucnum2_ui.c90
-rw-r--r--gmp/mpz/lucnum_ui.c209
-rw-r--r--gmp/mpz/mfac_uiui.c140
-rw-r--r--gmp/mpz/millerrabin.c124
-rw-r--r--gmp/mpz/mod.c68
-rw-r--r--gmp/mpz/mul.c157
-rw-r--r--gmp/mpz/mul_2exp.c73
-rw-r--r--gmp/mpz/mul_i.h107
-rw-r--r--gmp/mpz/mul_si.c34
-rw-r--r--gmp/mpz/mul_ui.c34
-rw-r--r--gmp/mpz/n_pow_ui.c533
-rw-r--r--gmp/mpz/neg.c57
-rw-r--r--gmp/mpz/nextprime.c129
-rw-r--r--gmp/mpz/oddfac_1.c427
-rw-r--r--gmp/mpz/out_raw.c173
-rw-r--r--gmp/mpz/out_str.c112
-rw-r--r--gmp/mpz/perfpow.c39
-rw-r--r--gmp/mpz/perfsqr.c35
-rw-r--r--gmp/mpz/popcount.c35
-rw-r--r--gmp/mpz/pow_ui.c53
-rw-r--r--gmp/mpz/powm.c283
-rw-r--r--gmp/mpz/powm_sec.c104
-rw-r--r--gmp/mpz/powm_ui.c292
-rw-r--r--gmp/mpz/pprime_p.c164
-rw-r--r--gmp/mpz/primorial_ui.c164
-rw-r--r--gmp/mpz/prodlimbs.c109
-rw-r--r--gmp/mpz/random.c40
-rw-r--r--gmp/mpz/random2.c51
-rw-r--r--gmp/mpz/realloc.c71
-rw-r--r--gmp/mpz/realloc2.c60
-rw-r--r--gmp/mpz/remove.c147
-rw-r--r--gmp/mpz/roinit_n.c44
-rw-r--r--gmp/mpz/root.c93
-rw-r--r--gmp/mpz/rootrem.c101
-rw-r--r--gmp/mpz/rrandomb.c103
-rw-r--r--gmp/mpz/scan0.c130
-rw-r--r--gmp/mpz/scan1.c124
-rw-r--r--gmp/mpz/set.c50
-rw-r--r--gmp/mpz/set_d.c117
-rw-r--r--gmp/mpz/set_f.c72
-rw-r--r--gmp/mpz/set_q.c35
-rw-r--r--gmp/mpz/set_si.c55
-rw-r--r--gmp/mpz/set_str.c145
-rw-r--r--gmp/mpz/set_ui.c53
-rw-r--r--gmp/mpz/setbit.c105
-rw-r--r--gmp/mpz/size.c35
-rw-r--r--gmp/mpz/sizeinbase.c43
-rw-r--r--gmp/mpz/sqrt.c77
-rw-r--r--gmp/mpz/sqrtrem.c85
-rw-r--r--gmp/mpz/sub.c33
-rw-r--r--gmp/mpz/sub_ui.c33
-rw-r--r--gmp/mpz/swap.c55
-rw-r--r--gmp/mpz/tdiv_q.c93
-rw-r--r--gmp/mpz/tdiv_q_2exp.c68
-rw-r--r--gmp/mpz/tdiv_q_ui.c84
-rw-r--r--gmp/mpz/tdiv_qr.c107
-rw-r--r--gmp/mpz/tdiv_qr_ui.c103
-rw-r--r--gmp/mpz/tdiv_r.c98
-rw-r--r--gmp/mpz/tdiv_r_2exp.c78
-rw-r--r--gmp/mpz/tdiv_r_ui.c99
-rw-r--r--gmp/mpz/tdiv_ui.c85
-rw-r--r--gmp/mpz/tstbit.c81
-rw-r--r--gmp/mpz/ui_pow_ui.c59
-rw-r--r--gmp/mpz/ui_sub.c96
-rw-r--r--gmp/mpz/urandomb.c48
-rw-r--r--gmp/mpz/urandomm.c105
-rw-r--r--gmp/mpz/xor.c194
-rw-r--r--gmp/nextprime.c167
-rw-r--r--gmp/primesieve.c295
-rw-r--r--gmp/printf/Makefile.am41
-rw-r--r--gmp/printf/Makefile.in562
-rw-r--r--gmp/printf/asprintf.c48
-rw-r--r--gmp/printf/asprntffuns.c72
-rw-r--r--gmp/printf/doprnt.c627
-rw-r--r--gmp/printf/doprntf.c390
-rw-r--r--gmp/printf/doprnti.c137
-rw-r--r--gmp/printf/fprintf.c49
-rw-r--r--gmp/printf/obprintf.c59
-rw-r--r--gmp/printf/obprntffuns.c72
-rw-r--r--gmp/printf/obvprintf.c52
-rw-r--r--gmp/printf/printf.c49
-rw-r--r--gmp/printf/printffuns.c80
-rw-r--r--gmp/printf/repl-vsnprintf.c396
-rw-r--r--gmp/printf/snprintf.c54
-rw-r--r--gmp/printf/snprntffuns.c160
-rw-r--r--gmp/printf/sprintf.c55
-rw-r--r--gmp/printf/sprintffuns.c95
-rw-r--r--gmp/printf/vasprintf.c117
-rw-r--r--gmp/printf/vfprintf.c42
-rw-r--r--gmp/printf/vprintf.c42
-rw-r--r--gmp/printf/vsnprintf.c48
-rw-r--r--gmp/printf/vsprintf.c51
-rw-r--r--gmp/rand/Makefile.am38
-rw-r--r--gmp/rand/Makefile.in556
-rw-r--r--gmp/rand/rand.c52
-rw-r--r--gmp/rand/randbui.c57
-rw-r--r--gmp/rand/randclr.c38
-rw-r--r--gmp/rand/randdef.c38
-rw-r--r--gmp/rand/randiset.c39
-rw-r--r--gmp/rand/randlc2s.c93
-rw-r--r--gmp/rand/randlc2x.c333
-rw-r--r--gmp/rand/randmt.c416
-rw-r--r--gmp/rand/randmt.h51
-rw-r--r--gmp/rand/randmts.c165
-rw-r--r--gmp/rand/randmui.c86
-rw-r--r--gmp/rand/rands.c42
-rw-r--r--gmp/rand/randsd.c39
-rw-r--r--gmp/rand/randsdui.c44
-rw-r--r--gmp/scanf/Makefile.am38
-rw-r--r--gmp/scanf/Makefile.in555
-rw-r--r--gmp/scanf/doscan.c768
-rw-r--r--gmp/scanf/fscanf.c48
-rw-r--r--gmp/scanf/fscanffuns.c62
-rw-r--r--gmp/scanf/scanf.c48
-rw-r--r--gmp/scanf/sscanf.c53
-rw-r--r--gmp/scanf/sscanffuns.c124
-rw-r--r--gmp/scanf/vfscanf.c42
-rw-r--r--gmp/scanf/vscanf.c43
-rw-r--r--gmp/scanf/vsscanf.c61
-rw-r--r--gmp/tal-debug.c151
-rw-r--r--gmp/tal-notreent.c130
-rw-r--r--gmp/tal-reent.c82
-rw-r--r--gmp/tests/Makefile.am39
-rw-r--r--gmp/tests/Makefile.in992
-rw-r--r--gmp/tests/amd64call.asm167
-rw-r--r--gmp/tests/amd64check.c106
-rw-r--r--gmp/tests/arm32call.asm83
-rw-r--r--gmp/tests/arm32check.c96
-rw-r--r--gmp/tests/cxx/Makefile.am81
-rw-r--r--gmp/tests/cxx/Makefile.in887
-rw-r--r--gmp/tests/cxx/clocale.c60
-rw-r--r--gmp/tests/cxx/t-assign.cc604
-rw-r--r--gmp/tests/cxx/t-binary.cc466
-rw-r--r--gmp/tests/cxx/t-cast.cc57
-rw-r--r--gmp/tests/cxx/t-constr.cc756
-rw-r--r--gmp/tests/cxx/t-cxx11.cc220
-rw-r--r--gmp/tests/cxx/t-do-exceptions-work-at-all-with-this-compiler.cc38
-rw-r--r--gmp/tests/cxx/t-headers.cc26
-rw-r--r--gmp/tests/cxx/t-iostream.cc107
-rw-r--r--gmp/tests/cxx/t-istream.cc599
-rw-r--r--gmp/tests/cxx/t-locale.cc195
-rw-r--r--gmp/tests/cxx/t-misc.cc398
-rw-r--r--gmp/tests/cxx/t-mix.cc83
-rw-r--r--gmp/tests/cxx/t-ops.cc723
-rw-r--r--gmp/tests/cxx/t-ops2.cc256
-rw-r--r--gmp/tests/cxx/t-ops3.cc133
-rw-r--r--gmp/tests/cxx/t-ostream.cc450
-rw-r--r--gmp/tests/cxx/t-prec.cc217
-rw-r--r--gmp/tests/cxx/t-rand.cc149
-rw-r--r--gmp/tests/cxx/t-ternary.cc735
-rw-r--r--gmp/tests/cxx/t-unary.cc133
-rw-r--r--gmp/tests/devel/Makefile.am34
-rw-r--r--gmp/tests/devel/Makefile.in606
-rw-r--r--gmp/tests/devel/README37
-rw-r--r--gmp/tests/devel/anymul_1.c256
-rw-r--r--gmp/tests/devel/aors_n.c263
-rw-r--r--gmp/tests/devel/copy.c226
-rw-r--r--gmp/tests/devel/divmod_1.c200
-rw-r--r--gmp/tests/devel/divrem.c119
-rw-r--r--gmp/tests/devel/logops_n.c230
-rw-r--r--gmp/tests/devel/shift.c245
-rw-r--r--gmp/tests/devel/try.c3608
-rw-r--r--gmp/tests/devel/tst-addsub.c98
-rw-r--r--gmp/tests/memory.c247
-rw-r--r--gmp/tests/misc.c565
-rw-r--r--gmp/tests/misc/Makefile.am33
-rw-r--r--gmp/tests/misc/Makefile.in665
-rw-r--r--gmp/tests/misc/t-locale.c201
-rw-r--r--gmp/tests/misc/t-printf.c948
-rw-r--r--gmp/tests/misc/t-scanf.c1616
-rw-r--r--gmp/tests/mpf/Makefile.am31
-rw-r--r--gmp/tests/mpf/Makefile.in867
-rw-r--r--gmp/tests/mpf/reuse.c219
-rw-r--r--gmp/tests/mpf/t-add.c108
-rw-r--r--gmp/tests/mpf/t-cmp_d.c104
-rw-r--r--gmp/tests/mpf/t-cmp_si.c107
-rw-r--r--gmp/tests/mpf/t-conv.c143
-rw-r--r--gmp/tests/mpf/t-div.c186
-rw-r--r--gmp/tests/mpf/t-dm2exp.c119
-rw-r--r--gmp/tests/mpf/t-eq.c218
-rw-r--r--gmp/tests/mpf/t-fits.c333
-rw-r--r--gmp/tests/mpf/t-get_d.c106
-rw-r--r--gmp/tests/mpf/t-get_d_2exp.c121
-rw-r--r--gmp/tests/mpf/t-get_si.c223
-rw-r--r--gmp/tests/mpf/t-get_ui.c128
-rw-r--r--gmp/tests/mpf/t-gsprec.c62
-rw-r--r--gmp/tests/mpf/t-inp_str.c192
-rw-r--r--gmp/tests/mpf/t-int_p.c84
-rw-r--r--gmp/tests/mpf/t-mul_ui.c165
-rw-r--r--gmp/tests/mpf/t-muldiv.c159
-rw-r--r--gmp/tests/mpf/t-set.c113
-rw-r--r--gmp/tests/mpf/t-set_q.c127
-rw-r--r--gmp/tests/mpf/t-set_si.c91
-rw-r--r--gmp/tests/mpf/t-set_ui.c90
-rw-r--r--gmp/tests/mpf/t-sqrt.c194
-rw-r--r--gmp/tests/mpf/t-sqrt_ui.c113
-rw-r--r--gmp/tests/mpf/t-sub.c206
-rw-r--r--gmp/tests/mpf/t-trunc.c271
-rw-r--r--gmp/tests/mpf/t-ui_div.c152
-rw-r--r--gmp/tests/mpn/Makefile.am38
-rw-r--r--gmp/tests/mpn/Makefile.in1029
-rw-r--r--gmp/tests/mpn/logic.c134
-rw-r--r--gmp/tests/mpn/t-aors_1.c311
-rw-r--r--gmp/tests/mpn/t-asmtype.c64
-rw-r--r--gmp/tests/mpn/t-bdiv.c368
-rw-r--r--gmp/tests/mpn/t-broot.c105
-rw-r--r--gmp/tests/mpn/t-brootinv.c106
-rw-r--r--gmp/tests/mpn/t-div.c505
-rw-r--r--gmp/tests/mpn/t-divrem_1.c124
-rw-r--r--gmp/tests/mpn/t-fat.c311
-rw-r--r--gmp/tests/mpn/t-get_d.c498
-rw-r--r--gmp/tests/mpn/t-hgcd.c407
-rw-r--r--gmp/tests/mpn/t-hgcd_appr.c564
-rw-r--r--gmp/tests/mpn/t-instrument.c416
-rw-r--r--gmp/tests/mpn/t-invert.c161
-rw-r--r--gmp/tests/mpn/t-iord_u.c221
-rw-r--r--gmp/tests/mpn/t-matrix22.c207
-rw-r--r--gmp/tests/mpn/t-minvert.c179
-rw-r--r--gmp/tests/mpn/t-mod_1.c129
-rw-r--r--gmp/tests/mpn/t-mp_bases.c105
-rw-r--r--gmp/tests/mpn/t-mul.c101
-rw-r--r--gmp/tests/mpn/t-mullo.c142
-rw-r--r--gmp/tests/mpn/t-mulmid.c93
-rw-r--r--gmp/tests/mpn/t-mulmod_bnm1.c218
-rw-r--r--gmp/tests/mpn/t-perfsqr.c117
-rw-r--r--gmp/tests/mpn/t-scan.c145
-rw-r--r--gmp/tests/mpn/t-sizeinbase.c108
-rw-r--r--gmp/tests/mpn/t-sqrmod_bnm1.c191
-rw-r--r--gmp/tests/mpn/t-toom2-sqr.c6
-rw-r--r--gmp/tests/mpn/t-toom22.c10
-rw-r--r--gmp/tests/mpn/t-toom3-sqr.c6
-rw-r--r--gmp/tests/mpn/t-toom32.c8
-rw-r--r--gmp/tests/mpn/t-toom33.c11
-rw-r--r--gmp/tests/mpn/t-toom4-sqr.c6
-rw-r--r--gmp/tests/mpn/t-toom42.c8
-rw-r--r--gmp/tests/mpn/t-toom43.c8
-rw-r--r--gmp/tests/mpn/t-toom44.c11
-rw-r--r--gmp/tests/mpn/t-toom52.c8
-rw-r--r--gmp/tests/mpn/t-toom53.c8
-rw-r--r--gmp/tests/mpn/t-toom54.c8
-rw-r--r--gmp/tests/mpn/t-toom6-sqr.c8
-rw-r--r--gmp/tests/mpn/t-toom62.c8
-rw-r--r--gmp/tests/mpn/t-toom63.c8
-rw-r--r--gmp/tests/mpn/t-toom6h.c13
-rw-r--r--gmp/tests/mpn/t-toom8-sqr.c8
-rw-r--r--gmp/tests/mpn/t-toom8h.c18
-rw-r--r--gmp/tests/mpn/toom-shared.h158
-rw-r--r--gmp/tests/mpn/toom-sqr-shared.h129
-rw-r--r--gmp/tests/mpq/Makefile.am34
-rw-r--r--gmp/tests/mpq/Makefile.in761
-rw-r--r--gmp/tests/mpq/io.c137
-rw-r--r--gmp/tests/mpq/reuse.c230
-rw-r--r--gmp/tests/mpq/t-aors.c183
-rw-r--r--gmp/tests/mpq/t-cmp.c102
-rw-r--r--gmp/tests/mpq/t-cmp_si.c118
-rw-r--r--gmp/tests/mpq/t-cmp_ui.c117
-rw-r--r--gmp/tests/mpq/t-equal.c147
-rw-r--r--gmp/tests/mpq/t-get_d.c295
-rw-r--r--gmp/tests/mpq/t-get_str.c143
-rw-r--r--gmp/tests/mpq/t-inp_str.c172
-rw-r--r--gmp/tests/mpq/t-inv.c61
-rw-r--r--gmp/tests/mpq/t-md_2exp.c245
-rw-r--r--gmp/tests/mpq/t-set_f.c170
-rw-r--r--gmp/tests/mpq/t-set_str.c103
-rw-r--r--gmp/tests/mpz/Makefile.am42
-rw-r--r--gmp/tests/mpz/Makefile.in1187
-rw-r--r--gmp/tests/mpz/bit.c406
-rw-r--r--gmp/tests/mpz/convert.c170
-rw-r--r--gmp/tests/mpz/dive.c101
-rw-r--r--gmp/tests/mpz/dive_ui.c87
-rw-r--r--gmp/tests/mpz/io.c139
-rw-r--r--gmp/tests/mpz/logic.c195
-rw-r--r--gmp/tests/mpz/reuse.c722
-rw-r--r--gmp/tests/mpz/t-addsub.c122
-rw-r--r--gmp/tests/mpz/t-aorsmul.c422
-rw-r--r--gmp/tests/mpz/t-bin.c266
-rw-r--r--gmp/tests/mpz/t-cdiv_ui.c159
-rw-r--r--gmp/tests/mpz/t-cmp.c182
-rw-r--r--gmp/tests/mpz/t-cmp_d.c293
-rw-r--r--gmp/tests/mpz/t-cmp_si.c102
-rw-r--r--gmp/tests/mpz/t-cong.c227
-rw-r--r--gmp/tests/mpz/t-cong_2exp.c209
-rw-r--r--gmp/tests/mpz/t-div_2exp.c224
-rw-r--r--gmp/tests/mpz/t-divis.c168
-rw-r--r--gmp/tests/mpz/t-divis_2exp.c133
-rw-r--r--gmp/tests/mpz/t-export.c206
-rw-r--r--gmp/tests/mpz/t-fac_ui.c106
-rw-r--r--gmp/tests/mpz/t-fdiv.c147
-rw-r--r--gmp/tests/mpz/t-fdiv_ui.c159
-rw-r--r--gmp/tests/mpz/t-fib_ui.c156
-rw-r--r--gmp/tests/mpz/t-fits.c202
-rw-r--r--gmp/tests/mpz/t-gcd.c454
-rw-r--r--gmp/tests/mpz/t-gcd_ui.c63
-rw-r--r--gmp/tests/mpz/t-get_d.c74
-rw-r--r--gmp/tests/mpz/t-get_d_2exp.c223
-rw-r--r--gmp/tests/mpz/t-get_si.c122
-rw-r--r--gmp/tests/mpz/t-hamdist.c124
-rw-r--r--gmp/tests/mpz/t-import.c176
-rw-r--r--gmp/tests/mpz/t-inp_str.c199
-rw-r--r--gmp/tests/mpz/t-invert.c121
-rw-r--r--gmp/tests/mpz/t-io_raw.c287
-rw-r--r--gmp/tests/mpz/t-jac.c1012
-rw-r--r--gmp/tests/mpz/t-lcm.c185
-rw-r--r--gmp/tests/mpz/t-limbs.c233
-rw-r--r--gmp/tests/mpz/t-lucnum_ui.c97
-rw-r--r--gmp/tests/mpz/t-mfac_uiui.c136
-rw-r--r--gmp/tests/mpz/t-mul.c219
-rw-r--r--gmp/tests/mpz/t-mul_i.c135
-rw-r--r--gmp/tests/mpz/t-nextprime.c222
-rw-r--r--gmp/tests/mpz/t-oddeven.c88
-rw-r--r--gmp/tests/mpz/t-perfpow.c243
-rw-r--r--gmp/tests/mpz/t-perfsqr.c155
-rw-r--r--gmp/tests/mpz/t-popcount.c168
-rw-r--r--gmp/tests/mpz/t-pow.c218
-rw-r--r--gmp/tests/mpz/t-powm.c184
-rw-r--r--gmp/tests/mpz/t-powm_ui.c128
-rw-r--r--gmp/tests/mpz/t-pprime_p.c190
-rw-r--r--gmp/tests/mpz/t-primorial_ui.c97
-rw-r--r--gmp/tests/mpz/t-remove.c147
-rw-r--r--gmp/tests/mpz/t-root.c174
-rw-r--r--gmp/tests/mpz/t-scan.c132
-rw-r--r--gmp/tests/mpz/t-set_d.c140
-rw-r--r--gmp/tests/mpz/t-set_f.c126
-rw-r--r--gmp/tests/mpz/t-set_si.c97
-rw-r--r--gmp/tests/mpz/t-set_str.c109
-rw-r--r--gmp/tests/mpz/t-sizeinbase.c90
-rw-r--r--gmp/tests/mpz/t-sqrtrem.c116
-rw-r--r--gmp/tests/mpz/t-tdiv.c146
-rw-r--r--gmp/tests/mpz/t-tdiv_ui.c159
-rw-r--r--gmp/tests/rand/Makefile.am89
-rw-r--r--gmp/tests/rand/Makefile.in801
-rw-r--r--gmp/tests/rand/findlc.c252
-rw-r--r--gmp/tests/rand/gen.c481
-rw-r--r--gmp/tests/rand/gmpstat.h75
-rw-r--r--gmp/tests/rand/spect.c137
-rw-r--r--gmp/tests/rand/stat.c407
-rw-r--r--gmp/tests/rand/statlib.c837
-rw-r--r--gmp/tests/rand/t-iset.c68
-rw-r--r--gmp/tests/rand/t-lc2exp.c217
-rw-r--r--gmp/tests/rand/t-mt.c83
-rw-r--r--gmp/tests/rand/t-rand.c290
-rw-r--r--gmp/tests/rand/t-urbui.c65
-rw-r--r--gmp/tests/rand/t-urmui.c75
-rw-r--r--gmp/tests/rand/t-urndmm.c159
-rw-r--r--gmp/tests/rand/zdiv_round.c44
-rw-r--r--gmp/tests/refmpf.c428
-rw-r--r--gmp/tests/refmpn.c2578
-rw-r--r--gmp/tests/refmpq.c41
-rw-r--r--gmp/tests/refmpz.c298
-rw-r--r--gmp/tests/spinner.c129
-rw-r--r--gmp/tests/t-bswap.c71
-rw-r--r--gmp/tests/t-constants.c352
-rw-r--r--gmp/tests/t-count_zeros.c87
-rw-r--r--gmp/tests/t-gmpmax.c69
-rw-r--r--gmp/tests/t-hightomask.c43
-rw-r--r--gmp/tests/t-modlinv.c84
-rw-r--r--gmp/tests/t-parity.c67
-rw-r--r--gmp/tests/t-popc.c80
-rw-r--r--gmp/tests/t-sub.c115
-rw-r--r--gmp/tests/tests.h442
-rw-r--r--gmp/tests/trace.c318
-rw-r--r--gmp/tests/x86call.asm153
-rw-r--r--gmp/tests/x86check.c112
-rw-r--r--gmp/tune/Makefile.am181
-rw-r--r--gmp/tune/Makefile.in860
-rw-r--r--gmp/tune/README501
-rw-r--r--gmp/tune/alpha.asm59
-rw-r--r--gmp/tune/common.c2659
-rw-r--r--gmp/tune/div_qr_1_tune.c47
-rw-r--r--gmp/tune/div_qr_1n_pi1_1.c39
-rw-r--r--gmp/tune/div_qr_1n_pi1_2.c39
-rw-r--r--gmp/tune/divrem1div.c42
-rw-r--r--gmp/tune/divrem1inv.c42
-rw-r--r--gmp/tune/divrem2div.c41
-rw-r--r--gmp/tune/divrem2inv.c41
-rw-r--r--gmp/tune/freq.c894
-rw-r--r--gmp/tune/gcdext_double.c39
-rw-r--r--gmp/tune/gcdext_single.c39
-rw-r--r--gmp/tune/gcdextod.c40
-rw-r--r--gmp/tune/gcdextos.c40
-rw-r--r--gmp/tune/hgcd_appr_lehmer.c40
-rw-r--r--gmp/tune/hgcd_lehmer.c40
-rw-r--r--gmp/tune/hgcd_reduce_1.c41
-rw-r--r--gmp/tune/hgcd_reduce_2.c40
-rw-r--r--gmp/tune/hppa.asm42
-rw-r--r--gmp/tune/hppa2.asm44
-rw-r--r--gmp/tune/hppa2w.asm44
-rw-r--r--gmp/tune/ia64.asm47
-rw-r--r--gmp/tune/jacbase1.c38
-rw-r--r--gmp/tune/jacbase2.c38
-rw-r--r--gmp/tune/jacbase3.c38
-rw-r--r--gmp/tune/jacbase4.c38
-rw-r--r--gmp/tune/many.pl1334
-rw-r--r--gmp/tune/mod_1_1-1.c41
-rw-r--r--gmp/tune/mod_1_1-2.c41
-rw-r--r--gmp/tune/mod_1_div.c46
-rw-r--r--gmp/tune/mod_1_inv.c46
-rw-r--r--gmp/tune/modlinv.c178
-rw-r--r--gmp/tune/noop.c68
-rw-r--r--gmp/tune/pentium.asm60
-rw-r--r--gmp/tune/powerpc.asm53
-rw-r--r--gmp/tune/powerpc64.asm49
-rw-r--r--gmp/tune/powm_mod.c39
-rw-r--r--gmp/tune/powm_redc.c41
-rw-r--r--gmp/tune/pre_divrem_1.c41
-rw-r--r--gmp/tune/set_strb.c48
-rw-r--r--gmp/tune/set_strp.c43
-rw-r--r--gmp/tune/set_strs.c44
-rw-r--r--gmp/tune/sparcv9.asm45
-rw-r--r--gmp/tune/speed-ext.c233
-rw-r--r--gmp/tune/speed.c1384
-rw-r--r--gmp/tune/speed.h3646
-rw-r--r--gmp/tune/time.c1597
-rw-r--r--gmp/tune/tune-gcd-p.c225
-rw-r--r--gmp/tune/tuneup.c2912
-rw-r--r--gmp/tune/x86_64.asm55
-rw-r--r--gmp/version.c34
-rwxr-xr-xgmp/ylwrap226
-rw-r--r--mpc/AUTHORS6
-rw-r--r--mpc/COPYING.LESSER165
-rw-r--r--mpc/ChangeLog0
-rw-r--r--mpc/INSTALL101
-rw-r--r--mpc/Makefile.am29
-rw-r--r--mpc/Makefile.in831
-rw-r--r--mpc/Makefile.vc426
-rw-r--r--mpc/NEWS154
-rw-r--r--mpc/README11
-rw-r--r--mpc/TODO40
-rw-r--r--mpc/aclocal.m41051
-rwxr-xr-xmpc/ar-lib270
-rwxr-xr-xmpc/config.guess1530
-rw-r--r--mpc/config.h.in123
-rwxr-xr-xmpc/config.sub1782
-rwxr-xr-xmpc/configure16404
-rw-r--r--mpc/configure.ac242
-rwxr-xr-xmpc/depcomp708
-rw-r--r--mpc/doc/Makefile.am20
-rw-r--r--mpc/doc/Makefile.in702
-rw-r--r--mpc/doc/fdl-1.3.texi506
-rwxr-xr-xmpc/doc/mdate-sh205
-rw-r--r--mpc/doc/mpc.info1799
-rw-r--r--mpc/doc/mpc.texi1165
-rw-r--r--mpc/doc/stamp-vti4
-rw-r--r--mpc/doc/texinfo.tex10074
-rw-r--r--mpc/doc/version.texi4
-rwxr-xr-xmpc/install-sh527
-rw-r--r--mpc/ltmain.sh9661
-rw-r--r--mpc/m4/ax_c_check_flag.m486
-rw-r--r--mpc/m4/ax_gcc_option.m4130
-rw-r--r--mpc/m4/ax_gcc_version.m465
-rw-r--r--mpc/m4/libtool.m47851
-rw-r--r--mpc/m4/ltoptions.m4369
-rw-r--r--mpc/m4/ltsugar.m4123
-rw-r--r--mpc/m4/ltversion.m423
-rw-r--r--mpc/m4/lt~obsolete.m498
-rw-r--r--mpc/m4/mpc.m4242
-rw-r--r--mpc/m4/valgrind-tests.m440
-rwxr-xr-xmpc/missing331
-rw-r--r--mpc/src/Makefile.am34
-rw-r--r--mpc/src/Makefile.in683
-rw-r--r--mpc/src/abs.c28
-rw-r--r--mpc/src/acos.c228
-rw-r--r--mpc/src/acosh.c76
-rw-r--r--mpc/src/add.c33
-rw-r--r--mpc/src/add_fr.c33
-rw-r--r--mpc/src/add_si.c32
-rw-r--r--mpc/src/add_ui.c33
-rw-r--r--mpc/src/arg.c27
-rw-r--r--mpc/src/asin.c226
-rw-r--r--mpc/src/asinh.c55
-rw-r--r--mpc/src/atan.c367
-rw-r--r--mpc/src/atanh.c52
-rw-r--r--mpc/src/clear.c28
-rw-r--r--mpc/src/cmp.c33
-rw-r--r--mpc/src/cmp_si_si.c34
-rw-r--r--mpc/src/conj.c32
-rw-r--r--mpc/src/cos.c27
-rw-r--r--mpc/src/cosh.c35
-rw-r--r--mpc/src/div.c449
-rw-r--r--mpc/src/div_2si.c32
-rw-r--r--mpc/src/div_2ui.c32
-rw-r--r--mpc/src/div_fr.c39
-rw-r--r--mpc/src/div_ui.c32
-rw-r--r--mpc/src/exp.c202
-rw-r--r--mpc/src/fma.c191
-rw-r--r--mpc/src/fr_div.c39
-rw-r--r--mpc/src/fr_sub.c33
-rw-r--r--mpc/src/get_prec.c28
-rw-r--r--mpc/src/get_prec2.c29
-rw-r--r--mpc/src/get_version.c48
-rw-r--r--mpc/src/get_x.c236
-rw-r--r--mpc/src/imag.c27
-rw-r--r--mpc/src/init2.c28
-rw-r--r--mpc/src/init3.c28
-rw-r--r--mpc/src/inp_str.c239
-rw-r--r--mpc/src/log.c217
-rw-r--r--mpc/src/log10.c286
-rw-r--r--mpc/src/logging.c147
-rw-r--r--mpc/src/mem.c46
-rw-r--r--mpc/src/mpc-impl.h194
-rw-r--r--mpc/src/mpc-log.h51
-rw-r--r--mpc/src/mpc.h269
-rw-r--r--mpc/src/mul.c639
-rw-r--r--mpc/src/mul_2si.c32
-rw-r--r--mpc/src/mul_2ui.c32
-rw-r--r--mpc/src/mul_fr.c43
-rw-r--r--mpc/src/mul_i.c80
-rw-r--r--mpc/src/mul_si.c32
-rw-r--r--mpc/src/mul_ui.c32
-rw-r--r--mpc/src/neg.c32
-rw-r--r--mpc/src/norm.c182
-rw-r--r--mpc/src/out_str.c39
-rw-r--r--mpc/src/pow.c819
-rw-r--r--mpc/src/pow_d.c38
-rw-r--r--mpc/src/pow_fr.c37
-rw-r--r--mpc/src/pow_ld.c38
-rw-r--r--mpc/src/pow_si.c30
-rw-r--r--mpc/src/pow_ui.c169
-rw-r--r--mpc/src/pow_z.c47
-rw-r--r--mpc/src/proj.c34
-rw-r--r--mpc/src/real.c27
-rw-r--r--mpc/src/set.c32
-rw-r--r--mpc/src/set_prec.c28
-rw-r--r--mpc/src/set_str.c42
-rw-r--r--mpc/src/set_x.c104
-rw-r--r--mpc/src/set_x_x.c78
-rw-r--r--mpc/src/sin.c27
-rw-r--r--mpc/src/sin_cos.c402
-rw-r--r--mpc/src/sinh.c47
-rw-r--r--mpc/src/sqr.c324
-rw-r--r--mpc/src/sqrt.c364
-rw-r--r--mpc/src/strtoc.c89
-rw-r--r--mpc/src/sub.c32
-rw-r--r--mpc/src/sub_fr.c34
-rw-r--r--mpc/src/sub_ui.c33
-rw-r--r--mpc/src/swap.c29
-rw-r--r--mpc/src/tan.c284
-rw-r--r--mpc/src/tanh.c47
-rw-r--r--mpc/src/uceil_log2.c33
-rw-r--r--mpc/src/ui_div.c36
-rw-r--r--mpc/src/ui_ui_sub.c34
-rw-r--r--mpc/src/urandom.c32
-rw-r--r--mpc/tests/Makefile.am52
-rw-r--r--mpc/tests/Makefile.in1208
-rw-r--r--mpc/tests/abs.dat84
-rw-r--r--mpc/tests/acos.dat127
-rw-r--r--mpc/tests/acosh.dat121
-rw-r--r--mpc/tests/add.dat115
-rw-r--r--mpc/tests/add_fr.dat122
-rw-r--r--mpc/tests/arg.dat74
-rw-r--r--mpc/tests/asin.dat126
-rw-r--r--mpc/tests/asinh.dat120
-rw-r--r--mpc/tests/atan.dat148
-rw-r--r--mpc/tests/atanh.dat112
-rw-r--r--mpc/tests/comparisons.c45
-rw-r--r--mpc/tests/conj.dat114
-rw-r--r--mpc/tests/cos.dat85
-rw-r--r--mpc/tests/cosh.dat133
-rw-r--r--mpc/tests/div.dat2486
-rw-r--r--mpc/tests/div_fr.dat368
-rw-r--r--mpc/tests/exp.dat118
-rw-r--r--mpc/tests/fma.dat32
-rw-r--r--mpc/tests/fr_div.dat381
-rw-r--r--mpc/tests/fr_sub.dat373
-rw-r--r--mpc/tests/inp_str.dat163
-rw-r--r--mpc/tests/log.dat190
-rw-r--r--mpc/tests/log10.dat179
-rw-r--r--mpc/tests/mpc-tests.h235
-rwxr-xr-xmpc/tests/mul.dat178
-rw-r--r--mpc/tests/mul_fr.dat368
-rw-r--r--mpc/tests/neg.dat109
-rw-r--r--mpc/tests/norm.dat166
-rw-r--r--mpc/tests/pow.dat469
-rw-r--r--mpc/tests/pow_fr.dat74
-rw-r--r--mpc/tests/pow_si.dat29
-rw-r--r--mpc/tests/pow_ui.dat102
-rw-r--r--mpc/tests/proj.dat73
-rw-r--r--mpc/tests/random.c160
-rw-r--r--mpc/tests/read_data.c1059
-rw-r--r--mpc/tests/sin.dat163
-rw-r--r--mpc/tests/sinh.dat84
-rw-r--r--mpc/tests/sqr.dat170
-rw-r--r--mpc/tests/sqrt.dat139
-rw-r--r--mpc/tests/strtoc.dat168
-rw-r--r--mpc/tests/sub.dat94
-rw-r--r--mpc/tests/sub_fr.dat378
-rw-r--r--mpc/tests/tabs.c36
-rw-r--r--mpc/tests/tacos.c36
-rw-r--r--mpc/tests/tacosh.c57
-rw-r--r--mpc/tests/tadd.c70
-rw-r--r--mpc/tests/tadd_fr.c72
-rw-r--r--mpc/tests/tadd_si.c68
-rw-r--r--mpc/tests/tadd_ui.c68
-rw-r--r--mpc/tests/tan.dat135
-rw-r--r--mpc/tests/tanh.dat81
-rw-r--r--mpc/tests/targ.c36
-rw-r--r--mpc/tests/tasin.c36
-rw-r--r--mpc/tests/tasinh.c57
-rw-r--r--mpc/tests/tatan.c68
-rw-r--r--mpc/tests/tatanh.c57
-rw-r--r--mpc/tests/tconj.c36
-rw-r--r--mpc/tests/tcos.c65
-rw-r--r--mpc/tests/tcosh.c134
-rw-r--r--mpc/tests/tdiv.c36
-rw-r--r--mpc/tests/tdiv_2si.c35
-rw-r--r--mpc/tests/tdiv_2ui.c35
-rw-r--r--mpc/tests/tdiv_fr.c36
-rw-r--r--mpc/tests/tdiv_ui.c35
-rw-r--r--mpc/tests/texp.c36
-rw-r--r--mpc/tests/tfma.c107
-rw-r--r--mpc/tests/tfr_div.c34
-rw-r--r--mpc/tests/tfr_sub.c35
-rw-r--r--mpc/tests/tgeneric.c1412
-rw-r--r--mpc/tests/tget_version.c62
-rw-r--r--mpc/tests/timag.c35
-rw-r--r--mpc/tests/tio_str.c252
-rw-r--r--mpc/tests/tlog.c37
-rw-r--r--mpc/tests/tlog10.c37
-rw-r--r--mpc/tests/tmul.c201
-rw-r--r--mpc/tests/tmul_2si.c35
-rw-r--r--mpc/tests/tmul_2ui.c35
-rw-r--r--mpc/tests/tmul_fr.c36
-rw-r--r--mpc/tests/tmul_i.c96
-rw-r--r--mpc/tests/tmul_si.c34
-rw-r--r--mpc/tests/tmul_ui.c35
-rw-r--r--mpc/tests/tneg.c35
-rw-r--r--mpc/tests/tnorm.c110
-rw-r--r--mpc/tests/tpow.c71
-rw-r--r--mpc/tests/tpow_d.c61
-rw-r--r--mpc/tests/tpow_fr.c63
-rw-r--r--mpc/tests/tpow_ld.c43
-rw-r--r--mpc/tests/tpow_si.c89
-rw-r--r--mpc/tests/tpow_ui.c118
-rw-r--r--mpc/tests/tpow_z.c62
-rw-r--r--mpc/tests/tprec.c69
-rw-r--r--mpc/tests/tproj.c36
-rw-r--r--mpc/tests/treal.c35
-rw-r--r--mpc/tests/treimref.c48
-rw-r--r--mpc/tests/tset.c447
-rw-r--r--mpc/tests/tsin.c36
-rw-r--r--mpc/tests/tsin_cos.c35
-rw-r--r--mpc/tests/tsinh.c36
-rw-r--r--mpc/tests/tsqr.c191
-rw-r--r--mpc/tests/tsqrt.c36
-rw-r--r--mpc/tests/tstrtoc.c166
-rw-r--r--mpc/tests/tsub.c36
-rw-r--r--mpc/tests/tsub_fr.c36
-rw-r--r--mpc/tests/tsub_ui.c35
-rw-r--r--mpc/tests/tswap.c54
-rw-r--r--mpc/tests/ttan.c216
-rw-r--r--mpc/tests/ttanh.c36
-rw-r--r--mpc/tests/tui_div.c102
-rw-r--r--mpc/tests/tui_ui_sub.c35
-rw-r--r--mpfr/AUTHORS23
-rw-r--r--mpfr/BUGS73
-rw-r--r--mpfr/COPYING674
-rw-r--r--mpfr/COPYING.LESSER165
-rw-r--r--mpfr/ChangeLog65716
-rw-r--r--mpfr/INSTALL651
-rw-r--r--mpfr/Makefile.am32
-rw-r--r--mpfr/Makefile.in844
-rw-r--r--mpfr/NEWS314
-rw-r--r--mpfr/PATCHES0
-rw-r--r--mpfr/README84
-rw-r--r--mpfr/TODO434
-rw-r--r--mpfr/VERSION1
-rw-r--r--mpfr/acinclude.m4918
-rw-r--r--mpfr/aclocal.m41053
-rwxr-xr-xmpfr/compile343
-rwxr-xr-xmpfr/config.guess1530
-rwxr-xr-xmpfr/config.sub1782
-rwxr-xr-xmpfr/configure17228
-rw-r--r--mpfr/configure.ac561
-rwxr-xr-xmpfr/depcomp708
-rw-r--r--mpfr/doc/FAQ.html389
-rw-r--r--mpfr/doc/Makefile.am18
-rw-r--r--mpfr/doc/Makefile.in716
-rw-r--r--mpfr/doc/fdl.texi454
-rw-r--r--mpfr/doc/mpfr.info4266
-rw-r--r--mpfr/doc/mpfr.texi3658
-rw-r--r--mpfr/doc/texinfo.tex9977
-rw-r--r--mpfr/examples/ReadMe1
-rw-r--r--mpfr/examples/divworst.c97
-rw-r--r--mpfr/examples/rndo-add.c91
-rw-r--r--mpfr/examples/sample.c56
-rw-r--r--mpfr/examples/version.c111
-rwxr-xr-xmpfr/install-sh527
-rw-r--r--mpfr/ltmain.sh9661
-rw-r--r--mpfr/m4/libtool.m47999
-rw-r--r--mpfr/m4/ltoptions.m4384
-rw-r--r--mpfr/m4/ltsugar.m4123
-rw-r--r--mpfr/m4/ltversion.m423
-rw-r--r--mpfr/m4/lt~obsolete.m498
-rw-r--r--mpfr/m4/size_max.m472
-rwxr-xr-xmpfr/missing331
-rw-r--r--mpfr/src/Makefile.am93
-rw-r--r--mpfr/src/Makefile.in935
-rw-r--r--mpfr/src/abort_prec_max.c32
-rw-r--r--mpfr/src/acos.c146
-rw-r--r--mpfr/src/acosh.c158
-rw-r--r--mpfr/src/add.c111
-rw-r--r--mpfr/src/add1.c538
-rw-r--r--mpfr/src/add1sp.c387
-rw-r--r--mpfr/src/add_d.c52
-rw-r--r--mpfr/src/add_ui.c58
-rw-r--r--mpfr/src/agm.c319
-rw-r--r--mpfr/src/ai.c664
-rw-r--r--mpfr/src/amd/amdfam10/mparam.h236
-rw-r--r--mpfr/src/amd/athlon/mparam.h90
-rw-r--r--mpfr/src/amd/k8/mparam.h236
-rw-r--r--mpfr/src/arm/mparam.h232
-rw-r--r--mpfr/src/asin.c125
-rw-r--r--mpfr/src/asinh.c119
-rw-r--r--mpfr/src/atan.c437
-rw-r--r--mpfr/src/atan2.c281
-rw-r--r--mpfr/src/atanh.c130
-rw-r--r--mpfr/src/bernoulli.c80
-rw-r--r--mpfr/src/buildopt.c63
-rw-r--r--mpfr/src/cache.c145
-rw-r--r--mpfr/src/cbrt.c153
-rw-r--r--mpfr/src/check.c80
-rw-r--r--mpfr/src/clear.c31
-rw-r--r--mpfr/src/clears.c61
-rw-r--r--mpfr/src/cmp.c104
-rw-r--r--mpfr/src/cmp2.c243
-rw-r--r--mpfr/src/cmp_abs.c94
-rw-r--r--mpfr/src/cmp_d.c38
-rw-r--r--mpfr/src/cmp_ld.c38
-rw-r--r--mpfr/src/cmp_si.c101
-rw-r--r--mpfr/src/cmp_ui.c101
-rw-r--r--mpfr/src/comparisons.c78
-rw-r--r--mpfr/src/const_catalan.c153
-rw-r--r--mpfr/src/const_euler.c221
-rw-r--r--mpfr/src/const_log2.c200
-rw-r--r--mpfr/src/const_pi.c128
-rw-r--r--mpfr/src/constant.c28
-rw-r--r--mpfr/src/copysign.c38
-rw-r--r--mpfr/src/cos.c298
-rw-r--r--mpfr/src/cosh.c128
-rw-r--r--mpfr/src/cot.c96
-rw-r--r--mpfr/src/coth.c93
-rw-r--r--mpfr/src/csc.c76
-rw-r--r--mpfr/src/csch.c79
-rw-r--r--mpfr/src/d_div.c50
-rw-r--r--mpfr/src/d_sub.c50
-rw-r--r--mpfr/src/digamma.c378
-rw-r--r--mpfr/src/dim.c48
-rw-r--r--mpfr/src/div.c790
-rw-r--r--mpfr/src/div_2exp.c33
-rw-r--r--mpfr/src/div_2si.c60
-rw-r--r--mpfr/src/div_2ui.c61
-rw-r--r--mpfr/src/div_d.c51
-rw-r--r--mpfr/src/div_ui.c281
-rw-r--r--mpfr/src/dump.c30
-rw-r--r--mpfr/src/eint.c319
-rw-r--r--mpfr/src/eq.c141
-rw-r--r--mpfr/src/erf.c262
-rw-r--r--mpfr/src/erfc.c277
-rw-r--r--mpfr/src/exceptions.c360
-rw-r--r--mpfr/src/exp.c164
-rw-r--r--mpfr/src/exp10.c29
-rw-r--r--mpfr/src/exp2.c151
-rw-r--r--mpfr/src/exp3.c335
-rw-r--r--mpfr/src/exp_2.c421
-rw-r--r--mpfr/src/expm1.c179
-rw-r--r--mpfr/src/extract.c55
-rw-r--r--mpfr/src/factorial.c113
-rw-r--r--mpfr/src/fits_intmax.c107
-rw-r--r--mpfr/src/fits_s.h89
-rw-r--r--mpfr/src/fits_sint.c28
-rw-r--r--mpfr/src/fits_slong.c28
-rw-r--r--mpfr/src/fits_sshort.c28
-rw-r--r--mpfr/src/fits_u.h67
-rw-r--r--mpfr/src/fits_uint.c27
-rw-r--r--mpfr/src/fits_uintmax.c77
-rw-r--r--mpfr/src/fits_ulong.c27
-rw-r--r--mpfr/src/fits_ushort.c27
-rw-r--r--mpfr/src/fma.c302
-rw-r--r--mpfr/src/fms.c304
-rw-r--r--mpfr/src/frac.c144
-rw-r--r--mpfr/src/free_cache.c59
-rw-r--r--mpfr/src/frexp.c56
-rw-r--r--mpfr/src/gamma.c439
-rw-r--r--mpfr/src/gammaonethird.c191
-rw-r--r--mpfr/src/gen_inverse.h106
-rw-r--r--mpfr/src/generic/mparam.h69
-rw-r--r--mpfr/src/get_d.c183
-rw-r--r--mpfr/src/get_d64.c400
-rw-r--r--mpfr/src/get_exp.c31
-rw-r--r--mpfr/src/get_f.c148
-rw-r--r--mpfr/src/get_flt.c123
-rw-r--r--mpfr/src/get_ld.c222
-rw-r--r--mpfr/src/get_patches.c29
-rw-r--r--mpfr/src/get_si.c69
-rw-r--r--mpfr/src/get_sj.c123
-rw-r--r--mpfr/src/get_str.c2555
-rw-r--r--mpfr/src/get_ui.c65
-rw-r--r--mpfr/src/get_uj.c82
-rw-r--r--mpfr/src/get_z.c61
-rw-r--r--mpfr/src/get_z_exp.c79
-rw-r--r--mpfr/src/gmp_op.c489
-rw-r--r--mpfr/src/grandom.c198
-rw-r--r--mpfr/src/hppa/mparam.h233
-rw-r--r--mpfr/src/hypot.c194
-rw-r--r--mpfr/src/ia64/mparam.h233
-rw-r--r--mpfr/src/ieee_floats.h80
-rw-r--r--mpfr/src/init.c29
-rw-r--r--mpfr/src/init2.c69
-rw-r--r--mpfr/src/inits.c62
-rw-r--r--mpfr/src/inits2.c66
-rw-r--r--mpfr/src/inp_str.c89
-rw-r--r--mpfr/src/int_ceil_log2.c42
-rw-r--r--mpfr/src/isinf.c29
-rw-r--r--mpfr/src/isinteger.c59
-rw-r--r--mpfr/src/isnan.c29
-rw-r--r--mpfr/src/isnum.c29
-rw-r--r--mpfr/src/isqrt.c84
-rw-r--r--mpfr/src/isregular.c29
-rw-r--r--mpfr/src/iszero.c29
-rw-r--r--mpfr/src/jn.c329
-rw-r--r--mpfr/src/jyn_asympt.c269
-rw-r--r--mpfr/src/li2.c634
-rw-r--r--mpfr/src/lngamma.c738
-rw-r--r--mpfr/src/log.c171
-rw-r--r--mpfr/src/log10.c150
-rw-r--r--mpfr/src/log1p.c158
-rw-r--r--mpfr/src/log2.c142
-rw-r--r--mpfr/src/logging.c124
-rw-r--r--mpfr/src/min_prec.c33
-rw-r--r--mpfr/src/minmax.c92
-rw-r--r--mpfr/src/modf.c102
-rw-r--r--mpfr/src/mp_clz_tab.c38
-rw-r--r--mpfr/src/mparam_h.in92
-rw-r--r--mpfr/src/mpf2mpfr.h175
-rw-r--r--mpfr/src/mpfr-gmp.c386
-rw-r--r--mpfr/src/mpfr-gmp.h411
-rw-r--r--mpfr/src/mpfr-impl.h1924
-rw-r--r--mpfr/src/mpfr-intmax.h40
-rw-r--r--mpfr/src/mpfr-longlong.h1943
-rw-r--r--mpfr/src/mpfr-thread.h48
-rw-r--r--mpfr/src/mpfr.h1059
-rw-r--r--mpfr/src/mpn_exp.c174
-rw-r--r--mpfr/src/mul.c547
-rw-r--r--mpfr/src/mul_2exp.c33
-rw-r--r--mpfr/src/mul_2si.c59
-rw-r--r--mpfr/src/mul_2ui.c66
-rw-r--r--mpfr/src/mul_d.c52
-rw-r--r--mpfr/src/mul_ui.c133
-rw-r--r--mpfr/src/mulders.c495
-rw-r--r--mpfr/src/neg.c39
-rw-r--r--mpfr/src/next.c150
-rw-r--r--mpfr/src/out_str.c98
-rw-r--r--mpfr/src/pow.c715
-rw-r--r--mpfr/src/pow_si.c250
-rw-r--r--mpfr/src/pow_ui.c164
-rw-r--r--mpfr/src/pow_z.c373
-rw-r--r--mpfr/src/powerof2.c49
-rw-r--r--mpfr/src/powerpc32/mparam.h232
-rw-r--r--mpfr/src/powerpc64/mparam.h233
-rw-r--r--mpfr/src/print_raw.c129
-rw-r--r--mpfr/src/print_rnd_mode.c46
-rw-r--r--mpfr/src/printf.c215
-rw-r--r--mpfr/src/rec_sqrt.c556
-rw-r--r--mpfr/src/reldiff.c73
-rw-r--r--mpfr/src/rem1.c229
-rw-r--r--mpfr/src/rint.c437
-rw-r--r--mpfr/src/root.c205
-rw-r--r--mpfr/src/round_near_x.c233
-rw-r--r--mpfr/src/round_p.c123
-rw-r--r--mpfr/src/round_prec.c240
-rw-r--r--mpfr/src/round_raw_generic.c259
-rw-r--r--mpfr/src/scale2.c91
-rw-r--r--mpfr/src/sec.c34
-rw-r--r--mpfr/src/sech.c40
-rw-r--r--mpfr/src/set.c80
-rw-r--r--mpfr/src/set_d.c255
-rw-r--r--mpfr/src/set_d64.c224
-rw-r--r--mpfr/src/set_dfl_prec.c41
-rw-r--r--mpfr/src/set_exp.c37
-rw-r--r--mpfr/src/set_f.c99
-rw-r--r--mpfr/src/set_flt.c34
-rw-r--r--mpfr/src/set_inf.c33
-rw-r--r--mpfr/src/set_ld.c331
-rw-r--r--mpfr/src/set_nan.c31
-rw-r--r--mpfr/src/set_prc_raw.c31
-rw-r--r--mpfr/src/set_prec.c55
-rw-r--r--mpfr/src/set_q.c133
-rw-r--r--mpfr/src/set_rnd.c40
-rw-r--r--mpfr/src/set_si.c30
-rw-r--r--mpfr/src/set_si_2exp.c73
-rw-r--r--mpfr/src/set_sj.c52
-rw-r--r--mpfr/src/set_str.c42
-rw-r--r--mpfr/src/set_str_raw.c55
-rw-r--r--mpfr/src/set_ui.c30
-rw-r--r--mpfr/src/set_ui_2exp.c72
-rw-r--r--mpfr/src/set_uj.c123
-rw-r--r--mpfr/src/set_z.c30
-rw-r--r--mpfr/src/set_z_exp.c180
-rw-r--r--mpfr/src/set_zero.c31
-rw-r--r--mpfr/src/setmax.c41
-rw-r--r--mpfr/src/setmin.c38
-rw-r--r--mpfr/src/setsign.c30
-rw-r--r--mpfr/src/sgn.c40
-rw-r--r--mpfr/src/si_op.c57
-rw-r--r--mpfr/src/signbit.c30
-rw-r--r--mpfr/src/sin.c183
-rw-r--r--mpfr/src/sin_cos.c662
-rw-r--r--mpfr/src/sinh.c184
-rw-r--r--mpfr/src/sinh_cosh.c161
-rw-r--r--mpfr/src/sparc64/mparam.h233
-rw-r--r--mpfr/src/sqr.c112
-rw-r--r--mpfr/src/sqrt.c231
-rw-r--r--mpfr/src/sqrt_ui.c54
-rw-r--r--mpfr/src/stack_interface.c104
-rw-r--r--mpfr/src/strtofr.c851
-rw-r--r--mpfr/src/sub.c116
-rw-r--r--mpfr/src/sub1.c657
-rw-r--r--mpfr/src/sub1sp.c810
-rw-r--r--mpfr/src/sub_d.c51
-rw-r--r--mpfr/src/sub_ui.c60
-rw-r--r--mpfr/src/subnormal.c163
-rw-r--r--mpfr/src/sum.c316
-rw-r--r--mpfr/src/swap.c54
-rw-r--r--mpfr/src/tan.c89
-rw-r--r--mpfr/src/tanh.c153
-rw-r--r--mpfr/src/uceil_exp2.c65
-rw-r--r--mpfr/src/uceil_log2.c63
-rw-r--r--mpfr/src/ufloor_log2.c53
-rw-r--r--mpfr/src/ui_div.c103
-rw-r--r--mpfr/src/ui_pow.c41
-rw-r--r--mpfr/src/ui_pow_ui.c95
-rw-r--r--mpfr/src/ui_sub.c68
-rw-r--r--mpfr/src/urandom.c147
-rw-r--r--mpfr/src/urandomb.c108
-rw-r--r--mpfr/src/vasprintf.c2086
-rw-r--r--mpfr/src/version.c29
-rw-r--r--mpfr/src/volatile.c36
-rw-r--r--mpfr/src/x86/core2/mparam.h234
-rw-r--r--mpfr/src/x86/mparam.h233
-rw-r--r--mpfr/src/x86_64/core2/mparam.h236
-rw-r--r--mpfr/src/x86_64/pentium4/mparam.h160
-rw-r--r--mpfr/src/yn.c426
-rw-r--r--mpfr/src/zeta.c466
-rw-r--r--mpfr/src/zeta_ui.c230
-rw-r--r--mpfr/tests/Makefile.am90
-rw-r--r--mpfr/tests/Makefile.in2208
-rw-r--r--mpfr/tests/cmp_str.c37
-rw-r--r--mpfr/tests/inp_str.data64
-rw-r--r--mpfr/tests/memory.c193
-rw-r--r--mpfr/tests/mpf_compat.c25
-rw-r--r--mpfr/tests/mpf_compat.h236
-rw-r--r--mpfr/tests/mpfr-test.h173
-rw-r--r--mpfr/tests/mpfr_compat.c25
-rw-r--r--mpfr/tests/random2.c144
-rw-r--r--mpfr/tests/reuse.c685
-rw-r--r--mpfr/tests/rnd_mode.c70
-rw-r--r--mpfr/tests/tabs.c176
-rw-r--r--mpfr/tests/tacos.c187
-rw-r--r--mpfr/tests/tacosh.c219
-rw-r--r--mpfr/tests/tadd.c1120
-rw-r--r--mpfr/tests/tadd1sp.c189
-rw-r--r--mpfr/tests/tadd_d.c161
-rw-r--r--mpfr/tests/tadd_ui.c116
-rw-r--r--mpfr/tests/tagm.c277
-rw-r--r--mpfr/tests/tai.c109
-rw-r--r--mpfr/tests/tasin.c285
-rw-r--r--mpfr/tests/tasinh.c161
-rw-r--r--mpfr/tests/tatan.c643
-rw-r--r--mpfr/tests/tatanh.c189
-rw-r--r--mpfr/tests/taway.c497
-rw-r--r--mpfr/tests/tbuildopt.c89
-rw-r--r--mpfr/tests/tcan_round.c127
-rw-r--r--mpfr/tests/tcbrt.c219
-rw-r--r--mpfr/tests/tcheck.c125
-rw-r--r--mpfr/tests/tcmp.c220
-rw-r--r--mpfr/tests/tcmp2.c348
-rw-r--r--mpfr/tests/tcmp_d.c104
-rw-r--r--mpfr/tests/tcmp_ld.c105
-rw-r--r--mpfr/tests/tcmp_ui.c346
-rw-r--r--mpfr/tests/tcmpabs.c149
-rw-r--r--mpfr/tests/tcomparisons.c131
-rw-r--r--mpfr/tests/tconst_catalan.c59
-rw-r--r--mpfr/tests/tconst_euler.c116
-rw-r--r--mpfr/tests/tconst_log2.c201
-rw-r--r--mpfr/tests/tconst_pi.c186
-rw-r--r--mpfr/tests/tcopysign.c116
-rw-r--r--mpfr/tests/tcos.c383
-rw-r--r--mpfr/tests/tcosh.c204
-rw-r--r--mpfr/tests/tcot.c144
-rw-r--r--mpfr/tests/tcoth.c213
-rw-r--r--mpfr/tests/tcsc.c95
-rw-r--r--mpfr/tests/tcsch.c110
-rw-r--r--mpfr/tests/td_div.c209
-rw-r--r--mpfr/tests/td_sub.c129
-rw-r--r--mpfr/tests/tdigamma.c68
-rw-r--r--mpfr/tests/tdim.c114
-rw-r--r--mpfr/tests/tdiv.c1136
-rw-r--r--mpfr/tests/tdiv_d.c155
-rw-r--r--mpfr/tests/tdiv_ui.c237
-rw-r--r--mpfr/tests/teint.c216
-rw-r--r--mpfr/tests/teq.c208
-rw-r--r--mpfr/tests/terf.c662
-rw-r--r--mpfr/tests/tests.c958
-rw-r--r--mpfr/tests/texceptions.c446
-rw-r--r--mpfr/tests/texp.c1022
-rw-r--r--mpfr/tests/texp10.c318
-rw-r--r--mpfr/tests/texp2.c379
-rw-r--r--mpfr/tests/texpm1.c173
-rw-r--r--mpfr/tests/tfactorial.c287
-rw-r--r--mpfr/tests/tfits.c273
-rw-r--r--mpfr/tests/tfma.c731
-rw-r--r--mpfr/tests/tfmod.c384
-rw-r--r--mpfr/tests/tfms.c644
-rw-r--r--mpfr/tests/tfprintf.c445
-rw-r--r--mpfr/tests/tfrac.c301
-rw-r--r--mpfr/tests/tfrexp.c141
-rw-r--r--mpfr/tests/tgamma.c1069
-rw-r--r--mpfr/tests/tgeneric.c506
-rw-r--r--mpfr/tests/tgeneric_ui.c130
-rw-r--r--mpfr/tests/tget_d.c294
-rw-r--r--mpfr/tests/tget_d_2exp.c121
-rw-r--r--mpfr/tests/tget_f.c390
-rw-r--r--mpfr/tests/tget_flt.c385
-rw-r--r--mpfr/tests/tget_ld_2exp.c145
-rw-r--r--mpfr/tests/tget_set_d64.c349
-rw-r--r--mpfr/tests/tget_sj.c281
-rw-r--r--mpfr/tests/tget_str.c1268
-rw-r--r--mpfr/tests/tget_z.c201
-rw-r--r--mpfr/tests/tgmpop.c1265
-rw-r--r--mpfr/tests/tgrandom.c140
-rw-r--r--mpfr/tests/thyperbolic.c385
-rw-r--r--mpfr/tests/thypot.c326
-rw-r--r--mpfr/tests/tinits.c62
-rw-r--r--mpfr/tests/tinp_str.c94
-rw-r--r--mpfr/tests/tinternals.c161
-rw-r--r--mpfr/tests/tisnan.c212
-rw-r--r--mpfr/tests/tisqrt.c94
-rw-r--r--mpfr/tests/tj0.c135
-rw-r--r--mpfr/tests/tj1.c88
-rw-r--r--mpfr/tests/tjn.c307
-rw-r--r--mpfr/tests/tl2b.c174
-rw-r--r--mpfr/tests/tlgamma.c403
-rw-r--r--mpfr/tests/tli2.c208
-rw-r--r--mpfr/tests/tlngamma.c238
-rw-r--r--mpfr/tests/tlog.c361
-rw-r--r--mpfr/tests/tlog10.c122
-rw-r--r--mpfr/tests/tlog1p.c150
-rw-r--r--mpfr/tests/tlog2.c84
-rw-r--r--mpfr/tests/tmin_prec.c102
-rw-r--r--mpfr/tests/tminmax.c171
-rw-r--r--mpfr/tests/tmodf.c236
-rw-r--r--mpfr/tests/tmul.c697
-rw-r--r--mpfr/tests/tmul.dat3
-rw-r--r--mpfr/tests/tmul_2exp.c339
-rw-r--r--mpfr/tests/tmul_d.c136
-rw-r--r--mpfr/tests/tmul_ui.c282
-rw-r--r--mpfr/tests/tnext.c168
-rw-r--r--mpfr/tests/tout_str.c171
-rw-r--r--mpfr/tests/toutimpl.c122
-rw-r--r--mpfr/tests/tpow.c1588
-rw-r--r--mpfr/tests/tpow3.c126
-rw-r--r--mpfr/tests/tpow_all.c778
-rw-r--r--mpfr/tests/tpow_z.c379
-rw-r--r--mpfr/tests/tprintf.c505
-rw-r--r--mpfr/tests/trandom.c184
-rw-r--r--mpfr/tests/trec_sqrt.c210
-rw-r--r--mpfr/tests/tremquo.c291
-rw-r--r--mpfr/tests/trint.c448
-rw-r--r--mpfr/tests/troot.c334
-rw-r--r--mpfr/tests/tround_prec.c124
-rw-r--r--mpfr/tests/tsec.c172
-rw-r--r--mpfr/tests/tsech.c190
-rw-r--r--mpfr/tests/tset.c209
-rw-r--r--mpfr/tests/tset_d.c225
-rw-r--r--mpfr/tests/tset_exp.c67
-rw-r--r--mpfr/tests/tset_f.c207
-rw-r--r--mpfr/tests/tset_ld.c312
-rw-r--r--mpfr/tests/tset_q.c170
-rw-r--r--mpfr/tests/tset_si.c464
-rw-r--r--mpfr/tests/tset_sj.c195
-rw-r--r--mpfr/tests/tset_str.c870
-rw-r--r--mpfr/tests/tset_z.c142
-rw-r--r--mpfr/tests/tset_z_exp.c132
-rw-r--r--mpfr/tests/tsgn.c131
-rw-r--r--mpfr/tests/tsi_op.c146
-rw-r--r--mpfr/tests/tsin.c377
-rw-r--r--mpfr/tests/tsin_cos.c725
-rw-r--r--mpfr/tests/tsinh.c109
-rw-r--r--mpfr/tests/tsinh_cosh.c143
-rw-r--r--mpfr/tests/tsprintf.c1239
-rw-r--r--mpfr/tests/tsqr.c178
-rw-r--r--mpfr/tests/tsqrt.c709
-rw-r--r--mpfr/tests/tsqrt_ui.c56
-rw-r--r--mpfr/tests/tstckintc.c228
-rw-r--r--mpfr/tests/tstdint.c63
-rw-r--r--mpfr/tests/tstrtofr.c1211
-rw-r--r--mpfr/tests/tsub.c658
-rw-r--r--mpfr/tests/tsub1sp.c515
-rw-r--r--mpfr/tests/tsub_d.c128
-rw-r--r--mpfr/tests/tsub_ui.c144
-rw-r--r--mpfr/tests/tsubnormal.c222
-rw-r--r--mpfr/tests/tsum.c320
-rw-r--r--mpfr/tests/tswap.c51
-rw-r--r--mpfr/tests/ttan.c163
-rw-r--r--mpfr/tests/ttanh.c138
-rw-r--r--mpfr/tests/ttrunc.c133
-rw-r--r--mpfr/tests/tui_div.c206
-rw-r--r--mpfr/tests/tui_pow.c262
-rw-r--r--mpfr/tests/tui_sub.c301
-rw-r--r--mpfr/tests/turandom.c249
-rw-r--r--mpfr/tests/tvalist.c76
-rw-r--r--mpfr/tests/tversion.c84
-rw-r--r--mpfr/tests/ty0.c98
-rw-r--r--mpfr/tests/ty1.c98
-rw-r--r--mpfr/tests/tyn.c192
-rw-r--r--mpfr/tests/tzeta.c406
-rw-r--r--mpfr/tests/tzeta_ui.c122
-rwxr-xr-xmpfr/tools/ck-copyright-notice54
-rwxr-xr-xmpfr/tools/ck-version-info67
-rwxr-xr-xmpfr/tools/get_patches.sh34
-rw-r--r--mpfr/tune/Makefile.am38
-rw-r--r--mpfr/tune/Makefile.in553
-rw-r--r--mpfr/tune/bidimensional_sample.c468
-rw-r--r--mpfr/tune/speed.c283
-rw-r--r--mpfr/tune/tuneup.c1187
2612 files changed, 815286 insertions, 0 deletions
diff --git a/gmp/.gdbinit b/gmp/.gdbinit
new file mode 100644
index 0000000000..473d74f590
--- /dev/null
+++ b/gmp/.gdbinit
@@ -0,0 +1,43 @@
+# Copyright 1999 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+define pz
+set __gmpz_dump ($)
+end
+
+define pq
+set __gmpz_dump ($->_mp_num)
+echo /
+set __gmpz_dump ($->_mp_den)
+end
+
+define pf
+set __gmpf_dump ($)
+end
+
diff --git a/gmp/AUTHORS b/gmp/AUTHORS
new file mode 100644
index 0000000000..fbe298d61b
--- /dev/null
+++ b/gmp/AUTHORS
@@ -0,0 +1,100 @@
+Authors of GNU MP (in chronological order of initial contribution)
+
+Torbjörn Granlund Main author
+
+John Amanatides Original version of mpz/pprime_p.c
+
+Paul Zimmermann mpn/generic/mul_fft.c, now defunct dc_divrem_n.c,
+ rootrem.c, old mpz/powm.c, old toom3 code.
+
+Ken Weber Now defunct mpn/generic/bdivmod.c, old mpn/generic/gcd.c
+
+Bennet Yee Previous versions of mpz/jacobi.c mpz/legendre.c
+
+Andreas Schwab mpn/m68k/lshift.asm, mpn/m68k/rshift.asm
+
+Robert Harley Old mpn/generic/mul_n.c, previous versions of files in
+ mpn/arm
+
+Linus Nordberg Random number framework, original autoconfery
+
+Kent Boortz MacOS 9 port, now defunct.
+
+Kevin Ryde Most x86 assembly, new autoconfery, and countless other
+ things (please see the GMP manual for complete list)
+
+Gerardo Ballabio gmpxx.h and C++ istream input
+
+Pedro Gimeno Mersenne Twister random generator, other random number
+ revisions
+
+Jason Moxham Previous versions of mpz/fac_ui.c and gen-fac_ui.c
+
+Niels Möller gen-jacobitab.c,
+ mpn/generic/hgcd2.c, hgcd.c, hgcd_step.c,
+ hgcd_appr.c, hgcd_matrix.c, hgcd_reduce.c,
+ gcd.c, gcdext.c, matrix22_mul.c,
+ gcdext_1.c, gcd_subdiv_step.c, gcd_lehmer.c,
+ gcdext_subdiv_step.c, gcdext_lehmer.c,
+ jacobi_2.c, jacbase.c, hgcd_jacobi.c, hgcd2_jacobi.c
+ matrix22_mul1_inverse_vector.c,
+ toom_interpolate_7pts, mulmod_bnm1.c, dcpi1_bdiv_qr.c,
+ dcpi1_bdiv_q.c, sbpi1_bdiv_qr.c, sbpi1_bdiv_q.c,
+ sec_invert.c,
+ toom_eval_dgr3_pm1.c, toom_eval_dgr3_pm2.c,
+ toom_eval_pm1.c, toom_eval_pm2.c, toom_eval_pm2exp.c,
+ divexact.c, mod_1_1.c, div_qr_2.c,
+ div_qr_2n_pi1.c, div_qr_2u_pi1.c, broot.c,
+ brootinv.c,
+ mpn/x86/k7/invert_limb.asm, mod_1_1.asm,
+ mpn/x86_64/invert_limb.asm,
+ invert_limb_table.asm, mod_1_1.asm,
+ div_qr_2n_pi1.asm, div_qr_2u_pi1.asm,
+ mpn/x86_64/core2/aorsmul_1.asm,
+ mpz/nextprime.c, divexact.c, gcd.c, gcdext.c,
+ jacobi.c, combit.c, mini-gmp/mini-gmp.c.
+
+Marco Bodrato mpn/generic/toom44_mul.c, toom4_sqr.c, toom53_mul.c,
+ toom62_mul.c, toom43_mul.c, toom52_mul.c, toom54_mul.c,
+ toom_interpolate_6pts.c, toom_couple_handling.c,
+ toom63_mul.c, toom_interpolate_8pts.c,
+ toom6h_mul.c, toom6_sqr.c, toom_interpolate_12pts.c,
+ toom8h_mul.c, toom8_sqr.c, toom_interpolate_16pts.c,
+ mulmod_bnm1.c, sqrmod_bnm1.c, nussbaumer_mul.c,
+ toom_eval_pm2.c, toom_eval_pm2rexp.c,
+ mullo_n.c, invert.c, invertappr.c;
+ mpz/fac_ui.c, 2fac_ui.c, mfac_uiui.c, oddfac_1.c,
+ primorial_ui.c, prodlimbs.c, goetgheluck_bin_uiui.c.
+
+David Harvey mpn/generic/add_err1_n.c, add_err2_n.c,
+ add_err3_n.c, sub_err1_n.c, sub_err2_n.c,
+ sub_err3_n.c, mulmid_basecase.c, mulmid_n.c,
+ toom42_mulmid.c,
+ mpn/x86_64/mul_basecase.asm, aors_err1_n.asm,
+ aors_err2_n.asm, aors_err3_n.asm,
+ mulmid_basecase.asm,
+ mpn/x86_64/core2/aors_err1_n.asm.
+
+Martin Boij mpn/generic/perfpow.c
+
+Marc Glisse gmpxx.h improvements
+
+David Miller mpn/sparc32/ultrasparct1/{addmul_1,mul_1,submul_1}.asm
+ mpn/sparc64/ultrasparct3/{mul_1,addmul_1,submul_1}.asm
+ mpn/sparc64/ultrasparct3/{add_n,sub_n}.asm
+ mpn/sparc64/ultrasparct3/{popcount,hamdist}.asm
+ mpn/sparc64/ultrasparct3/cnd_aors_n.asm
+ mpn/sparc64/{rshift,lshift,lshiftc}.asm
+ mpn/sparc64/tabselect.asm
+
+Mark Sofroniou mpn/generic/mul_fft.c type cleanup.
+
+Ulrich Weigand Changes to support powerpc64le:
+ configure.ac, mpn/powerpc64/{elf,aix,darwin}.m4,
+ mpn/powerpc32/{darwin,elf}.m4,
+ mpn/powerpc64/mode64/{dive_1,divrem_1,divrem_2}.asm,
+ mpn/powerpc64/mode64/{gcd_1,invert_limb,mode1o}.asm,
+ mpn/powerpc64/mode64/{mod_1_1,mod_1_4}.asm,
+ mpn/powerpc64/mode64/p7/gcd_1.asm,
+ mpn/powerpc64/p6/{lshift,lshiftc,rshift}.asm,
+ mpn/powerpc64/vmx/popcount.asm.
diff --git a/gmp/COPYING b/gmp/COPYING
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/gmp/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/gmp/COPYING.LESSERv3 b/gmp/COPYING.LESSERv3
new file mode 100644
index 0000000000..fc8a5de7ed
--- /dev/null
+++ b/gmp/COPYING.LESSERv3
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/gmp/COPYINGv2 b/gmp/COPYINGv2
new file mode 100644
index 0000000000..d159169d10
--- /dev/null
+++ b/gmp/COPYINGv2
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/gmp/COPYINGv3 b/gmp/COPYINGv3
new file mode 100644
index 0000000000..2a000655e9
--- /dev/null
+++ b/gmp/COPYINGv3
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<https://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/gmp/ChangeLog b/gmp/ChangeLog
new file mode 100644
index 0000000000..540c025c51
--- /dev/null
+++ b/gmp/ChangeLog
@@ -0,0 +1,32941 @@
+2014-03-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * Version 6.0.0 released.
+
+ * mpn: Update countless gmp-mparam.h files.
+
+2014-03-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*): Bump version info.
+ * gmp-h.in: Bump version.
+
+2014-03-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac: Remove clipper, i960, ns32k, pyr, a29k, z8000.
+ * mpn/clipper: Remove directory and all its files.
+ * mpn/i960: Likewise.
+ * mpn/ns32k: Likewise.
+ * mpn/pyr: Likewise.
+ * mpn/a29k: Likewise.
+ * mpn/z8000: Likewise.
+ * mpn/Makefile.am (TARG_DIST): Purge removed directories.
+ * doc/gmp.texi: Remove special mentions of removed architectures.
+
+2014-03-12 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c (mpz_probab_prime_p): Micro-optimisation.
+
+2014-03-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/bd2/gmp-mparam.h: New file.
+ * mpn/x86_64/bd2/gmp-mparam.h: New file.
+
+2014-03-06 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-pprime_p.c (check_composites): New function.
+ (check_primes): New function.
+ (main): Call them. Also use TESTS_REPS.
+
+ * mini-gmp/mini-gmp.c (gmp_millerrabin): New internal function.
+ (mpz_probab_prime_p): New function.
+ * mini-gmp/mini-gmp.h (mpz_probab_prime_p): Declare it.
+ * mini-gmp/tests/t-pprime_p.c: New test program.
+ * mini-gmp/tests/Makefile (CHECK_PROGRAMS): Added t-pprime_p.
+
+2014-03-03 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/mini-gmp.c (mpz_congruent_p): New function.
+ * mini-gmp/mini-gmp.h: Declare it.
+ * mini-gmp/tests/t-cong.c: New file, based on tests/mpz/t-cong.c.
+ * mini-gmp/tests/Makefile (CHECK_PROGRAMS): Added t-cong.
+
+ * mini-gmp/tests/testutils.c (dump): New function. Deleted static
+ functions in other files.
+ (mpz_set_str_or_abort): Moved function here, from...
+ * mini-gmp/tests/t-cmp_d.c: ... old location.
+
+ * mini-gmp/tests/t-reuse.c (dump3): Renamed, from ...
+ (dump): ...old name.
+
+2014-03-01 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/sec_powm.c (mpn_sec_powm): Clarify comment and
+ asserts.
+
+2014-02-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat.c (fake_cpuid): Handle id 7, make bold claims.
+
+2014-02-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat_entry.asm: Zero ecx for the benefit of new BMI2
+ feature test.
+
+ * mpn/x86_64/fat/fat.c (__gmpn_cpuvec_init): Run CPUVEC_SETUP_coreihwl
+ conditionally on BMI2 availability.
+
+ * config.guess: Revert "coreihwl" to "coreisbr" if cpuid indicates that
+ BMI2 is missing.
+ (x86 cpuid, 2 variants): Zero ecx for the benefit of new BMI2 feature
+ test.
+
+2014-02-21 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c (mpn_sqrtrem): New function.
+ * mini-gmp/mini-gmp.h: Declare it.
+ * mini-gmp/tests/t-sqrt.c: Test it.
+
+2014-02-17 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/div_qr_1.c (mpn_div_qr_1): Revert yesterday's fix.
+ Hopefully no longer needed.
+
+ * mpn/s390_64/gmp-mparam.h (DIV_QR_1_NORM_THRESHOLD): Up to 1.
+ * mpn/s390_64/z10/gmp-mparam.h (DIV_QR_1_NORM_THRESHOLD): Up to 1.
+
+ * tune/tuneup.c (tune_div_qr_1): Ensure DIV_QR_1_NORM_THRESHOLD,
+ DIV_QR_1_UNNORM_THRESHOLD >= 1.
+
+2014-02-16 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/div_qr_1.c: Disallow DIV_QR_1_NORM_THRESHOLD==0.
+
+2014-02-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/t-div.c: Fix typo.
+
+2014-02-15 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * doc/gmp.texi (mpz_roinit_n, MPZ_ROINIT_N): Document that
+ at least a readable limb is required.
+ * mini-gmp/mini-gmp.c (mpz_div_qr): init + set = init_set .
+
+2014-02-14 Niels Möller <nisse@lysator.liu.se>
+
+ * doc/gmp.texi (Low-level Functions): Update docs for
+ mpn_sec_powm, to specify that left-over exponent bits must be
+ zero.
+
+2014-02-11 Niels Möller <nisse@lysator.liu.se>
+
+ * Makefile.am (EXTRA_DIST): Distribute COPYING.LESSERv3,
+ COPYINGv2, and COPYINGv3.
+
+ * doc/gmp.texi (Low-level Functions): Updated mpn_sec_powm docs.
+
+ * mpn/generic/sec_powm.c (mpn_sec_powm): Replaced exponent limb
+ count argument by bit count. Don't leak high exponent bits, and
+ drop the requirement that the most significant exponent limb is
+ non-zero.
+ (mpn_sec_powm_itch): Analogous interface change.
+ * gmp-h.in: Updated prototypes.
+ * mpz/powm_sec.c (mpz_powm_sec): Update mpn_sec_powm* calls.
+ * tune/tuneup.c (tune_powm_sec): Likewise. Also deleted code
+ fiddling with the high exponent bits.
+
+2014-02-10 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/tests/t-limbs.c: New test for mpz_limbs_*.
+ * mini-gmp/tests/Makefile (CHECK_PROGRAMS): Add it.
+
+2014-02-09 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tuneup.c (tune_powm_sec): Avoid timing of the nonsensical
+ parameters nbits = 1, winsize = 2. Decrement tabulated values, to
+ better match the > comparison when the table is used.
+
+ * mpn/generic/sec_powm.c (win_size): Comment why we always get
+ win_size(eb) <= eb. Make the table const.
+ (mpn_sec_powm): Deleted handling of winsize > initial ebi. For
+ now, replaced with an ASSERT_ALWAYS.
+
+2014-02-08 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c (mpz_realloc2, mpz_limbs_read, mpz_limbs_modify
+ mpz_limbs_write, mpz_limbs_finish, mpz_roinit_n): New functions.
+ (mpn_perfect_square_p): New function.
+ * mini-gmp/mini-gmp.h: Declare them.
+
+ * mini-gmp/tests/t-mul.c: Use roinit and limbs_read to test mpn.
+ * mini-gmp/tests/t-sqrt.c: Test also mpn_perfect_square_p.
+
+2014-02-08 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/sec_invert.c (mpn_cnd_neg_itch): #if:ed out unused
+ function.
+
+ * mpn/generic/sec_div.c: Simplified code for the normalized case.
+
+ * tests/mpn/t-div.c (main): Test mpn_sec_div_qr and mpn_sec_div_r
+ with normalized d.
+
+2014-02-04 Niels Möller <nisse@lysator.liu.se>
+
+ * doc/gmp.texi (Low-level Functions): Document mpn_sec_add_1 and
+ mpn_sec_sub_1.
+
+2014-02-03 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c (mpn_rootrem): Allow NULL argument.
+
+ * mini-gmp/mini-gmp.c (mpn_zero): New function.
+ (mpz_perfect_square_p): New function.
+ * mini-gmp/mini-gmp.h: Declare them.
+
+ * mini-gmp/tests/t-sqrt.c: Test mpz_perfect_square_p.
+ * mini-gmp/tests/t-root.c: Test also 1-th root, allow perfect powers.
+
+2014-01-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Floating-point Functions): Revise.
+
+2014-01-29 Niels Möller <nisse@lysator.liu.se>
+
+ * README: Don't refer to specific COPYING* files, instead refer to
+ manual for details.
+
+ * COPYING.LIB: Renamed, to...
+ * COPYING.LESSERv3: ... new name.
+ * COPYING: Renamed, to...
+ * COPYINGv3: ... new name.
+ * COPYINGv2: New file, GPLv2.
+
+ * doc/gmp.texi (Copying): Document dual licensing.
+
+2014-01-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * Update library files license to use LGPL3+ and GPL2+.
+
+2014-01-27 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpn/t-aors_1.c: Check sec_aors_1 red zones (not smart).
+
+ * mpn/generic/sec_aors_1.c: Mark the 2nd argument as const.
+ * gmp-h.in (mpn_sec_add_1, mpn_sec_sub_1): Likewise.
+
+2014-01-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat.c (fake_cpuid_table): Use proper steamroller and
+ excavator values.
+
+ * config.guess: Amend last AMD change.
+
+ * mpn/s390_64/lshift.asm: Align loop.
+ * mpn/s390_64/rshift.asm: Likewise.
+ * mpn/s390_64/lshiftc.asm: Likewise.
+ * mpn/s390_64: Add z10 cycle numbers.
+
+2014-01-23 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * printf/repl-vsnprintf.c: Feed case 'z' in switch (type) with case 'z'
+ in switch (fchar).
+
+ * mini-gmp/tests/t-aorsmul.c: New file, test for mpz_{add,sub}mul{,_ui}
+ * mini-gmp/tests/Makefile: Add t-aorsmul.
+
+2014-01-21 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * acinclude.m4 (GMP_FUNC_VSNPRINTF): Get rid of varargs.
+
+2014-01-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat.c (__gmpn_cpuvec_init): Fix duplicate entries for
+ AMD "jaguar".
+
+ * demos/expr: Get rid of varargs code and references.
+
+2014-01-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Add new AMD CPUs (piledriver, steamroller, excavator,
+ jaguar).
+ * config.sub: Corresponding updates.
+ * configure.ac: Likewise.
+ * acinclude.m4 (X86_64_PATTERN): Likewise.
+ * mpn/x86_64/fat/fat.c: Likewise.
+
+ * Rename mpn_sec_minvert => mpn_sec_invert, many files affected.
+ * mpn/generic/sec_invert.c: New name for sec_minvert.c.
+
+ * doc/gmp.texi: Undocument mpz_array_init.
+
+ * acinclude.m4 (GMP_C_STDARG): Comment out.
+ * configure.ac: Suppress GMP_C_STDARG invocation.
+
+ * Get rid of varargs code and references, many file affected.
+
+ * Use mpq_t in favour of MP_RAT, many mpq files affected.
+
+ * Get rid of BYTES_PER_MP_LIMB, most files affected.
+
+ * mpz/iset.c: Avoid overflow in allocation computation.
+ * mpz/mul.c: Likewise.
+ * mpf/init.c: Likewise.
+ * mpf/init2.c: Likewise.
+ * mpf/iset.c: Likewise.
+ * mpf/iset_d.c: Likewise.
+ * mpf/iset_si.c: Likewise.
+ * mpf/iset_str.c: Likewise.
+ * mpf/iset_ui.c: Likewise.
+
+ * mpz/array_init.c: Avoid two overflow scenarios in allocation
+ computation.
+
+ * mpn/s390_64/z10/gmp-mparam.h: New file.
+
+ * mpz/clears.c: Call __gmp_free_func ourselves instead of via
+ mpz_clears.
+ * mpf/clears.c: Analogous change.
+ * mpq/clears.c: Analogous change.
+
+ * mpz/clear.c: Add cast to avoid overflow of (later ignored) argument.
+ * mpf/clear.c: Likewise.
+
+2014-01-19 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c (mpn_popcount): New function.
+ (mpz_popcount): Use it.
+ (mpz_addmul_ui, mpz_addmul, mpz_submul_ui, mpz_submul): Added.
+ * mini-gmp/mini-gmp.h: Declare them.
+
+2014-01-18 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/t-aors_1.c: Test also mpn_sec_add_1 and mpn_sec_sub_1.
+
+ * tests/mpn/t-minvert.c (main): Pass smallest allowed bit_size
+ argument to mpn_sec_minvert.
+
+2014-01-18 Marc Glisse <marc.glisse@inria.fr>
+
+ * doc/gmp.texi (C++ Interface Limitations): Warn against C++11 auto.
+
+2014-01-18 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/t-parity.c: Use 1UL to generate unsigned constants.
+ * tests/t-constants.c: Disable a non portable (unneeded) check.
+
+2014-01-18 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/sec_aors_1.c (mpn_sec_add_1, mpn_sec_sub_1): New
+ file.
+
+ * mpn/generic/sec_minvert.c (mpn_sec_add_1_itch, mpn_sec_add_1):
+ Deleted static definitions.
+ (mpn_cnd_swap): Use volatile.
+
+ * configure.ac (gmp_mpn_functions): sec_add_1 and sec_sub_1.
+ (GMP_MULFUNC_CHOICES): Set up for sec_aors_1.
+
+2014-01-16 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/common.c (speed_mpn_sec_minvert): New function.
+ * tune/speed.h: Declare it.
+ (SPEED_ROUTINE_MPN_SEC_MINVERT): New macro.
+ * tune/speed.c (routine): Added mpn_sec_minvert.
+
+ * mini-gmp/mini-gmp.c (mp_bits_per_limb): New const value.
+ * mini-gmp/mini-gmp.h: Declare it.
+
+2014-01-12 Marc Glisse <marc.glisse@inria.fr>
+
+ * demos/expr/expr.h: Add extern "C" for C++.
+
+2014-01-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Notes for Particular Systems): Add items about old
+ NetBSD and current FreeBSD m4 problems. Add item about FreeBSD's
+ broken limits.h.
+
+2014-01-05 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h: Declare all _itch functions using ATTRIBUTE_CONST.
+
+2014-01-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac (alpha): Set extra_functions conditionally.
+
+ * gmp-h.in (mpn_sec_minvert): Remove formal parameters.
+
+ * doc/gmp.texi: Improve doc for several functions.
+
+ * mpn/generic/sec_tabselect.c: Declare input arg using 'const'.
+ * gmp-h.in: Analogous change.
+
+ * gmp-h.in: Declare all itch functions using __GMP_ATTRIBUTE_PURE.
+ * gmp-impl.h: Likewise.
+
+2014-01-05 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpn/t-minvert.c: Always compare with mpz_invert results,
+ add red zone to scratch.
+ * tests/mpn/t-sizeinbase.c: New test.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-sizeinbase.c .
+ * tests/mpn/t-div.c: Use mpn_sec_div_*_itch().
+
+ * mpn/generic/pow_1.c: Micro-optimisation.
+
+2014-01-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * acinclude.m4 (GMP_PROG_M4): Avoid hex output, since case varies.
+
+2014-01-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Support newer haswell, broadwell, silvermont.
+ * mpn/x86_64/fat/fat.c (__gmpn_cpuvec_init): Likewise.
+
+ * acinclude.m4 (GMP_PROG_M4): Check that eval's radix argument work.
+
+ * mpz/invert.c: Rely on gcdext for all operands, removing faulty
+ special case.
+ * tests/mpz/t-invert.c: Enforce correct behaviour for |mod| = 1.
+
+2014-01-02 Niels Möller <nisse@lysator.liu.se>
+
+ * doc/gmp.texi (Low-level Functions): Document mpn_sizeinbase.
+
+ Enable previously unused mpn_sizeinbase function.
+ * configure.ac (gmp_mpn_functions): Added sizeinbase.
+ * gmp-h.in (mpn_sizeinbase): New prototype.
+
+2014-01-02 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmp-impl.h: Always include <limits.h>.
+ * tests/mpn/t-get_d.c: Remove comment about <limits.h>
+
+ * gmp-h.in (__GMP_USHRT_MAX): Use the promoted type.
+ * gmp-impl.h (USHRT_HIGHBIT, SHRT_MIN, SHRT_MAX): Likewise.
+ * tests/t-constants.c: Adapt printf strings.
+ * tests/t-gmpmax.c: Likewise.
+
+ * tests/mpn/t-hgcd_appr.c (hgcd_appr_valid_p): Add parentheses.
+
+2014-01-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Low-level Functions for cryptography): Update interface
+ for mpn_sec_div_qr and fix typos in mpn_sec_minvert text.
+
+ * mpn/generic/sec_div.c: Rewrite to make mpn_sec_div_qr return high
+ quotient limb.
+ * gmp-h.in (mpn_sec_div_qr): Update declaration.
+ * tests/mpn/t-div.c: Adapt.
+
+2013-12-31 Niels Möller <nisse@lysator.liu.se>
+
+ * doc/gmp.texi (Low-level Functions for cryptography): Document
+ mpn_sec_minvert.
+
+2013-12-30 Marc Glisse <marc.glisse@inria.fr>
+
+ * doc/gmp.texi (C++ interface internals): Break long line.
+
+2013-12-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Low-level Functions for cryptography): New section.
+
+2013-12-29 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-minvert.
+ * tests/mpn/t-minvert.c: New file.
+
+ * configure.ac (gmp_mpn_functions): Added sec_minvert.
+ * gmp-h.in (mpn_sec_minvert, mpn_sec_minvert_itch): New
+ declarations.
+ * mpn/generic/sec_minvert.c (mpn_sec_minvert)
+ (mpn_sec_minvert_itch): New functions.
+ (mpn_sec_add_1, mpn_cnd_neg, mpn_cnd_swap, mpn_sec_eq_ui): New
+ helper functions.
+
+2013-12-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/sec_powm.c: Fix an ASSERT.
+
+ * gmp-h.in (mpn_sec_mul, mpn_sec_mul_itch): New declarations.
+ * gmp-h.in (mpn_sec_sqr, mpn_sec_sqr_itch): Likewise.
+ * mpn/generic/sec_mul.c: New file.
+ * mpn/generic/sec_sqr.c: New file.
+
+ * gmp-h.in (mpn_sec_powm, mpn_sec_powm_itch): New declarations.
+ * gmp-h.in (mpn_sec_div_qr, mpn_sec_div_qr_itch): Likewise.
+ * gmp-h.in (mpn_sec_div_r, mpn_sec_div_r_itch): Likewise.
+ * gmp-impl: Remove declarations of above functions.
+
+ * configure.ac (gmp_mpn_functions): Add sec_mul and sec_sqr.
+
+2013-12-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * Update many file's encoding to UTF-8.
+ * doc/tasks.html: Update <meta content> accordingly.
+ * doc/projects.html: Likewise.
+
+2013-12-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac: Rename mpn_blah_sec to mpn_sec_blah.
+ * gmp-impl.h: Corresponding changes.
+ * mpn/asm-defs.m4: Corresponding changes.
+ * tune/Makefile.am: Corresponding changes.
+ * tune/common.c: Corresponding changes.
+ * tune/speed.c: Corresponding changes.
+ * tune/speed.h: Corresponding changes.
+ * tune/tuneup.c: Corresponding changes.
+ * mpz/powm_sec.c: Update calls.
+ * tests/mpn/t-div.c: Likewise.
+
+ * mpn/generic/sec_powm.c: New name for mpn/generic/powm_sec.c.
+ * mpn/generic/sec_div.c: New name for mpn/generic/sb_div_sec.c.
+ * mpn/generic/sec_pi1_div.c: New name for mpn/generic/sbpi1_div_sec.c.
+ * mpn/generic/sec_tabselect.c: New name for mpn/generic/tabselect.c.
+
+ * mpn/alpha/sec_tabselect.asm: New name for tabselect.asm.
+ * mpn/arm/neon/sec_tabselect.asm: New name for tabselect.asm.
+ * mpn/arm/sec_tabselect.asm: New name for tabselect.asm.
+ * mpn/ia64/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/powerpc32/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/powerpc64/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/sparc64/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86/mmx/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86_64/bd1/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86_64/core2/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86_64/coreinhm/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86_64/coreisbr/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86_64/fastsse/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86_64/k10/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86_64/pentium4/sec_tabselect.asm: New name for tabselect.asm
+ * mpn/x86_64/sec_tabselect.asm: New name for tabselect.asm
+
+2013-12-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/powm_sec.c: Handle 0^e mod m specially.
+ * mpn/generic/powm_sec.c: ASSERT that the base is non-zero.
+
+2013-12-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm_sec.c (redcify): Use passed scratch instead of
+ locally allocated.
+ (mpn_powm_sec_itch): Accommodate mpn_sb_div_r_sec's scratch needs.
+
+2013-12-20 Mark Sofroniou <marks@wolfram.com>
+
+ * mpn/generic/mul_fft.c: Major overhaul of types.
+
+2013-12-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Low-level Functions): Rewrite mpn_set_str docs.
+
+2013-12-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * mpn/powerpc32/darwin.m4: Allow (and ignore) optional
+ 'toc' parameter to PROLOGUE_cpu.
+ * mpn/powerpc32/elf.m4: Likewise.
+
+2013-12-09 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * configure.ac: Check for ELFv2 ABI on PowerPC.
+ * mpn/powerpc64/elf.m4: Set assembler ABI version for ELFv2
+ and use appropriate PROLOGUE_cpu/EPILOGUE_cpu sequences.
+ Support optional 'toc' parameter to PROLOGUE_cpu.
+ * mpn/powerpc64/aix.m4: Allow (and ignore) optional
+ 'toc' parameter to PROLOGUE_cpu.
+ * mpn/powerpc64/darwin.m4: Likewise.
+
+ * mpn/powerpc64/mode64/dive_1.asm (mpn_divexact_1): Add 'toc'
+ parameter to PROLOGUE.
+ * mpn/powerpc64/mode64/divrem_1.asm (mpn_divrem_1): Likewise.
+ * mpn/powerpc64/mode64/divrem_2.asm (mpn_divrem_2): Likewise.
+ * mpn/powerpc64/mode64/gcd_1.asm (mpn_gcd_1): Likewise.
+ * mpn/powerpc64/mode64/invert_limb.asm (mpn_invert_limb): Likewise.
+ * mpn/powerpc64/mode64/mod_1_1.asm (mpn_mod_1_1p_cps): Likewise.
+ * mpn/powerpc64/mode64/mod_1_4.asm (mpn_mod_1s_4p_cps): Likewise.
+ * mpn/powerpc64/mode64/mode1o.asm (mpn_modexact_1c_odd): Likewise.
+ * mpn/powerpc64/mode64/p7/gcd_1.asm (mpn_gcd_1): Likewise.
+ * mpn/powerpc64/p6/lshift.asm (mpn_lshift): Likewise.
+ * mpn/powerpc64/p6/lshiftc.asm (mpn_lshiftc): Likewise.
+ * mpn/powerpc64/p6/rshift.asm (mpn_rshift): Likewise.
+ * mpn/powerpc64/vmx/popcount.asm (mpn_popcount): Likewise.
+
+2013-12-07 Niels Möller <nisse@lysator.liu.se>
+
+ * configfsf.sub: Updated to version 2013-10-01, from gnulib.
+ * configfsf.guess: Updated to version 2013-11-29, from gnulib.
+
+2013-12-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/div_qr_1.c: Make constant args asm inlines become limbs.
+ * mpn/generic/div_qr_1n_pi1.c: Likewise.
+ * mpn/generic/div_qr_2.c: Likewise.
+ * mpn/generic/div_qr_2.c: Likewise.
+ * mpn/generic/mod_1_1.c: Likewise.
+ * mpn/generic/mod_1_2.c: Likewise.
+ * mpn/generic/mod_1_3.c: Likewise.
+ * mpn/generic/mod_1_4.c: Likewise.
+ * mpn/generic/mulmid_basecase.c: Likewise.
+ * mpn/generic/mulmod_bnm1.c: Likewise.
+ * mpn/generic/sqrmod_bnm1.c: Likewise.
+ * mpn/sparc64/divrem_1.c: Likewise.
+ * mpn/sparc64/mod_1_4.c: Likewise.
+
+ * mpn/generic/toom_interpolate_7pts.c (BINVERT_15): Fix typo.
+
+2013-11-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/dos64.m4 (CALL): Provide to override default.
+
+2013-11-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/x86_64-defs.m4 (CALL): Swap PIC test and macro defn.
+
+ * mpn/generic/div_qr_2.c: Test HAVE_HOST_CPU_FAMILY_x86, not i386.
+
+ * doc/gmp.texi: Update many URLs.
+
+2013-11-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac: Set symbol OPENBSD for x86-openbsd hosts.
+ * mpn/x86_64/fat/fat_entry.asm (PRETEND_PIC): New name for
+ PIC_OR_DARWIN.
+ (PRETEND_PIC): Set also for OPENBSD.
+
+2013-10-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * printf/doprnt.c (__gmp_doprnt): Use memcpy instead of strcpy.
+
+2013-10-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/div_qr_1u_pi2.c: New file.
+ * mpn/generic/div_qr_1n_pi2.c: New file.
+
+2013-10-24 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/div_qr_1n_pi1.asm: Bugfixes, for case n == 1 and
+ in-place operation.
+ * mpn/x86_64/k8/div_qr_1n_pi1.asm: Likewise.
+
+ * mpn/generic/div_qr_1n_pi1.c (mpn_div_qr_1n_pi1): Bug fixes,
+ off-by-one MPN_INCR_U, and support for in-place operation.
+
+2013-10-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/fat/fat.c (fake_cpuid_table): Add Haswell.
+
+2013-10-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/x86_64-defs.m4 (oplist): New define, data from `regnum'.
+ (regnum): Use x86_lookup, feed oplist.
+
+2013-10-22 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/devel/try.c: Support mpn_div_qr_1n_pi1.
+
+ * mpn/x86_64/k8/div_qr_1n_pi1.asm: Moved the below k10 file here.
+ Applied tweak from Torbjörn to get it to run well on k8.
+
+ * mpn/x86_64/k10/div_qr_1n_pi1.asm: New file (renamed above).
+ Differs from generic x86_64 version by using cmov.
+
+ * mpn/x86_64/div_qr_1n_pi1.asm: Reordered arguments to second mul.
+ Deleted misleading cycle annotations.
+
+2013-10-21 Niels Möller <nisse@lysator.liu.se>
+
+ * configure.ac: Add HAVE_NATIVE_mpn_div_qr_1n_pi1 to config.in.
+
+ * mpn/generic/div_qr_1n_pi1.c (mpn_div_qr_1n_pi1): Fix typos
+ affecting ASSERT.
+
+2013-10-20 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/div_qr_1n_pi1.asm: New file.
+
+ * tune/div_qr_1_tune.c (__gmpn_div_qr_1n_pi1): Check
+ div_qr_1n_pi1_method only when !HAVE_NATIVE_mpn_div_qr_1n_pi1.
+
+ * mpn/asm-defs.m4 (define_mpn): Add div_qr_1n_pi1.
+
+ * tune/common.c (speed_mpn_div_qr_1): New function, replacing...
+ (speed_mpn_div_qr_1n, speed_mpn_div_qr_1u): ... deleted functions
+ (speed_mpn_div_qr_1n_pi1, speed_mpn_div_qr_1n_pi1_1)
+ (speed_mpn_div_qr_1n_pi1_2): New functions.
+ * gmp-impl.h [TUNE_PROGRAM_BUILD]: Declare div_qr_1-related tuning
+ variables.
+ * tune/tuneup.c (speed_mpn_div_qr_1_tune, tune_div_qr_1): New
+ functions.
+ (div_qr_1n_pi1_method, div_qr_1_norm_threshold)
+ (div_qr_1_unnorm_threshold): New globals.
+ * tune/speed.c (routine): Replaced mpn_div_qr_1n and mpn_div_qr_1u
+ by mpn_div_qr_1, requiring ".r" parameter. Added mpn_div_qr_1n_pi1
+ and variants.
+ * tune/speed.h (SPEED_ROUTINE_MPN_DIV_QR_1): Use the "r" parameter
+ as divisor.
+ * tune/div_qr_1n_pi1_2.c: New file.
+ * tune/div_qr_1n_pi1_1.c: New file.
+ * tune/div_qr_1_tune.c: New file.
+ * tune/Makefile.am (libspeed_la_SOURCES): Added div_qr_1n_pi1_1.c,
+ div_qr_1n_pi1_2.c, and div_qr_1_tune.c.
+
+ * tune/speed.c (routine): Added mpn_div_qr_1n and mpn_div_qr_1u.
+ * tune/speed.h (SPEED_ROUTINE_MPN_DIV_QR_1): New macro.
+ (speed_mpn_div_qr_1n, speed_mpn_div_qr_1u): Declare.
+ * tune/common.c (speed_mpn_div_qr_1n, speed_mpn_div_qr_1u): New
+ functions.
+
+ * gmp-impl.h (mpn_div_qr_1n_pi1): Declare function.
+ * gmp-h.in (mpn_div_qr_1): Declare function.
+ * configure.ac (gmp_mpn_functions): Added div_qr_1 and
+ div_qr_1n_pi1.
+ * mpn/generic/div_qr_1.c (mpn_div_qr_1): New file and function.
+ * mpn/generic/div_qr_1n_pi1.c (mpn_div_qr_1n_pi1): New file and
+ function.
+ * tests/mpn/t-div.c (main): Test mpn_div_qr_1.
+
+2013-10-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac (alpha): Pass -mieee via gcc_cflags_maybe.
+
+2013-10-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Let AMD64 cpuid bit override pessimistic cpu guesses.
+
+ * mpn/alpha/unicos.m4 (DATASTART): Accept optional align parameter.
+ * mpn/alpha/divrem_2.asm: Use provided gp mechanisms.
+ * mpn/alpha/default.m4 (PROLOGUE): Provide "..ng" post-gp label.
+ * mpn/alpha/invert_limb.asm: Align table to 8-byte boundary. Make code
+ work if table is not fully aligned. Properly test for BWX.
+
+2013-10-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/alpha/default.m4 (DATASTART): Use RODATA instead of DATA;
+ accept optional align parameter.
+ * mpn/alpha/invert_limb.asm: Align table.
+ * mpn/alpha/ev5/diveby3.asm: Likewise.
+
+2013-10-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/mod_1_1.asm: Use 'subl' form to avoid ambiguity.
+ * mpn/x86/k7/mod_1_4.asm: Likewise.
+
+ * configure.ac (X86_64_PATTERN): Append "cc" to cclist_64 and
+ cclist_x32.
+
+2013-10-08 Torbjorn Granlund <tege@gmplib.org>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ * tests/mpf/reuse.c (main): Compare addresses instead of names.
+ Use larger numbers for exponents.
+
+2013-10-08 Marc Glisse <marc.glisse@inria.fr>
+
+ * doc/mdate-sh, doc/texinfo.tex, install-sh, missing, ylwrap: Remove.
+ * .bootstrap: Use autoreconf (and in particular automake -a).
+
+ * gmp-h.in: Remove __need_size_t. Include <stddef.h>, not <cstddef>.
+
+ * tests/mpf/reuse.c (main): Use small numbers as exponents.
+
+2013-10-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/aorsmul_1.asm: Slight tweak.
+
+ * doc/gmp.texi (ABI and ISA): Document x32.
+
+ * mpn/sparc64/ultrasparct3/dive_1.asm: Use our register names.
+
+2013-09-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/redc_1.asm: New file.
+
+2013-09-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bobcat/redc_1.asm: Make the code for 1 <= n <= 3 work.
+
+2013-09-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/redc_1.asm: Slightly tweak basecase code.
+
+ * mpn/x86_64/core2/redc_1.asm: New file.
+
+ * mpn/x86_64/bobcat/redc_1.asm: New file.
+
+2013-09-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreinhm/redc_1.asm: New file.
+
+2013-09-21 Marc Glisse <marc.glisse@inria.fr>
+
+ * tests/mpn/t-mulmid.c: Cast arguments of printf to int to match %d.
+ * tests/rand/t-urbui.c: Use 1UL for unsigned constant.
+ * mpn/generic/get_str.c: Avoid temporarily pointing outside an array.
+
+2013-09-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/redc_1.asm: New file.
+
+ * mpn/x86_64/k8/redc_1.asm: Complete rewrite.
+
+ * mpn/x86_64/coreisbr/mullo_basecase.asm: Postpone pushes, short-
+ circuit a branch.
+ * mpn/x86_64/coreihwl/mullo_basecase.asm: Short-circuit a branch.
+
+ * mpn/x86_64/core2/mullo_basecase.asm: New file.
+
+2013-09-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fastsse/copyi-palignr.asm: Allocate more stack under DOS.
+
+2013-09-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/core2/mul_basecase.asm: New file.
+ * mpn/x86_64/core2/sqr_basecase.asm: New file.
+
+ * mpn/x86_64/coreihwl/mullo_basecase.asm: New file.
+ * mpn/x86_64/coreisbr/mullo_basecase.asm: New file.
+
+2013-09-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fastsse/copyi-palignr.asm: Preserve xmm6-xmm8 under DOS.
+
+2013-09-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/tabselect.asm: Use R8 for bit testing.
+
+ * mpn/x86_64/coreihwl/mul_basecase.asm: Replace mul_1 code.
+
+ * mpn/x86_64/coreisbr/aorsmul_1.asm: Rewrite.
+
+2013-09-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/ia64/gcd_1.asm: Use dep for combining table base and low bits.
+
+ * mpn/x86_64/fastsse/com-palignr.asm: Implement temp fix to properly
+ handle overlap.
+
+2013-09-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fastsse/copyi-palignr.asm: Rewrite rp != up (mod 16) code
+ to make it handle any allowed overlap.
+
+2013-09-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/com.asm: New file, grabbing fastsse code.
+
+ * mpn/x86_64/bd1/copyi.asm: New file, grabbing fastsse code.
+ * mpn/x86_64/bd1/copyd.asm: Likewise.
+ * mpn/x86_64/bd1/com.asm: Likewise.
+
+ * mpn/x86_64/fastavx/copyi.asm: New file.
+ * mpn/x86_64/fastavx/copyd.asm: New file.
+
+2013-09-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreihwl/aorsmul_1.asm: Streamline.
+
+2013-09-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreihwl/sqr_basecase.asm: Implement larger "corner".
+ Misc tuning.
+
+2013-09-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreihwl/redc_1.asm: New file.
+
+ * mpn/x86_64/x86_64-defs.m4 (mulx): Handle negative offsets.
+
+2013-08-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/sqr_basecase.asm: New file.
+
+ * mpn/x86_64/sqr_diag_addlsh1.asm: New file.
+
+2013-08-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/mul_basecase.c: New file.
+ * mpn/x86_64/fat/sqr_basecase.c: New file.
+ * mpn/x86_64/fat/mullo_basecase.c: New file.
+ * mpn/x86_64/fat/redc_1.c: New file.
+
+2013-08-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/k8/mul_basecase.asm: Move top-level basecase file to k8
+ subdir.
+ * mpn/x86_64/k8/sqr_basecase.asm: Likewise.
+ * mpn/x86_64/k8/redc_1.asm: Likewise.
+ * mpn/x86_64/k8/mullo_basecase.asm: Likewise.
+ * mpn/x86_64/k8/mulmid_basecase.asm: Likewise.
+
+ * mpn/ia64/aors_n.asm: Clean up some bundlings.
+
+ * mpn/x86_64/fat/fat.c (__gmpn_cpuvec_init): Support Haswell.
+ (fake_cpuid_table): Likewise.
+
+ * configure.ac (x86): Remove any mulx paths. Let bwl path = hwl path.
+ (fat_path): Add coreihwl.
+
+ * mpn/x86_64/coreihwl/aorsmul_1.asm: Move from `mulx' directory, use
+ mulx() macro.
+ * mpn/x86_64/coreihwl/mul_1.asm: Likewise.
+ * mpn/x86_64/coreihwl/mul_2.asm: Likewise.
+ * mpn/x86_64/coreihwl/mul_basecase.asm: Likewise.
+ * mpn/x86_64/coreihwl/sqr_basecase.asm: Likewise.
+
+ * mpn/x86_64/x86_64-defs.m4 (mulx): New macro.
+ (regnum, regnumh, ix): Supporting macros.
+
+2013-08-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/divrem_1.asm: New file.
+
+2013-08-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fastsse/com-palignr.asm: New file, closely based on
+ copyi-palignr.asm.
+
+ * mpn/x86_64/fastsse/copyi.asm Use "test R8(reg)" instead of "bt".
+ * mpn/x86_64/fastsse/copyd-palignr.asm: Likewise.
+ * mpn/x86_64/fastsse/copyi-palignr.asm: Likewise.
+ * mpn/x86_64/fastsse/lshift-movdqu2.asm: Likewise.
+ * mpn/x86_64/fastsse/lshiftc-movdqu2.asm: Likewise.
+ * mpn/x86_64/fastsse/rshift-movdqu2.asm: Likewise.
+ * mpn/x86_64/fastsse/tabselect.asm: Likewise.
+
+ * mpn/sparc64/ultrasparct3/sqr_diag_addlsh1.asm: New file.
+
+ * mpn/alpha/aorslsh2_n.asm: New file.
+ * mpn/alpha/aorslsh1_n.asm: Rewrite.
+ * mpn/alpha/ev6/aorslsh1_n.asm: New file.
+
+2013-08-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/alpha/sqr_diag_addlsh1.asm: New file.
+ * mpn/alpha/sqr_diagonal.asm: Remove.
+ * mpn/alpha/ev6/sqr_diagonal.asm: Remove.
+
+2013-08-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc32/sqr_diag_addlsh1.asm: New file.
+ * mpn/powerpc32/sqr_diagonal.asm: Remove.
+
+2013-08-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreihwl/mulx/sqr_basecase.asm: New file.
+
+2013-08-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/aors_n.asm: Complete rewrite.
+
+2013-08-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreihwl/mulx/mul_basecase.asm: New file.
+
+ * mpn/x86_64/bd1/mul_2.asm: New file.
+
+ * mpn/x86_64/coreihwl/gmp-mparam.h: New file.
+
+2013-08-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreihwl/mulx/mul_2.asm: New file.
+ * mpn/x86_64/coreihwl/mulx/addmul_2.asm: New file.
+
+ * mpn/x86_64/coreinhm/aorsmul_1.asm: New file.
+
+ * mpn/x86_64/coreisbr/mul_basecase.asm: Save some O(n) and O(1) cycles.
+
+ * mpn/x86_64/coreisbr/mul_2.asm: New file.
+
+2013-08-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/addmul_2.asm: Complete rewrite.
+
+2013-08-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bd1/mul_basecase.asm: New file.
+
+ * mpn/x86_64/coreisbr/mul_basecase.asm: New file.
+
+ * mpn/x86_64/coreihwl/aorsmul_1.asm: New file.
+
+2013-07-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/mul_2.asm: New file.
+ * mpn/x86_64/atom/addmul_2.asm: New file.
+ * mpn/x86_64/atom/mul_1.asm: New file.
+ * mpn/x86_64/atom/aorsmul_1.asm: New file.
+
+ * mpn/x86_64/coreihwl/mul_1.asm: New file.
+
+ * configure.ac (x86): Add Haswell-specific path.
+
+ * configure.in (fat_functions): Add cnd_add_n, cnd_sub_n..
+ * gmp-impl.h (struct cpuvec_t): Add fields for new fat functions.
+ * gmp-impl.h: Adjust corresponding declarations.
+
+ * mpn/x86_64/x86_64-defs.m4 (CPUVEC_FUNCS_LIST): Add new fat functions.
+ * mpn/x86/x86-defs.m4 (CPUVEC_FUNCS_LIST): Likewise.
+ * mpn/x86_64/fat/fat.c (__gmpn_cpuvec): Likewise.
+ * mpn/x86/fat/fat.c (__gmpn_cpuvec): Likewise.
+
+2013-07-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/popcount.asm: New file.
+
+2013-07-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bobcat/aors_n.asm: New file.
+
+ * mpn/x86_64/pentium4/aorslshC_n.asm: Remove a spurious emms insn.
+
+ * mpn/x86_64/bd1/aorrlsh1_n.asm: New file.
+ * mpn/x86_64/bd1/sublsh1_n.asm: New file.
+
+2013-07-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/mod_1_1.asm: Handle little-endian mode.
+ * mpn/powerpc64/mode64/mod_1_4.asm: Likewise.
+
+2013-07-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi: Declare countless of function arguments as 'const'.
+
+2013-07-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/core2/aors_n.asm: Rewrite.
+
+ * mpn/generic/sb_div_sec.c: Compute inverse as floor(B^2/(dh+1)), per
+ Niels' suggestion.
+ * mpn/generic/sbpi1_div_sec.c: Remove inverse rounding-up code.
+
+2013-07-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/divrem_1.asm: Remove explicit nop after CALL.
+ * mpn/powerpc64/mode64/divrem_2.asm: Likewise.
+ * mpn/powerpc64/mode64/mod_1_1.asm: Likewise.
+ * mpn/powerpc64/mode64/mod_1_4.asm: Likewise.
+
+2013-07-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/atom/cnd_add_n.asm: New file.
+ * mpn/x86/atom/cnd_sub_n.asm: New file.o
+
+2013-07-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/sbpi1_div_sec.c: Partial rewrite.
+
+2013-07-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/cnd_aors_n.asm: Tweak for better speed on K8, bobcat, bd1,
+ NHM, Atom.
+
+2013-07-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/p7/copyi.asm: Handle n = 0.
+ * mpn/powerpc64/p7/copyd.asm: Likewise.
+
+2013-07-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/p7/aormul_2.asm: New file.
+
+ * mpn/powerpc64/darwin.m4 (EXTRA_REGISTER): New define.
+ * mpn/powerpc64/aix.m4: New define (actually undefine).
+ * mpn/powerpc64/elf.m4: Likewise.
+
+2013-07-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/com.asm: Rewrite.
+
+ * mpn/powerpc64/p7/copyi.asm: New file.
+ * mpn/powerpc64/p7/copyd.asm: New file.
+
+2013-07-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/gcd_1.asm: New file.
+ * mpn/powerpc64/mode64/p7/gcd_1.asm: New file.
+
+2013-07-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac: Comment out AC_PROG_F77.
+
+ * mpn/powerpc64/mode64/rsh1add_n.asm: Remove.
+ * mpn/powerpc64/mode64/rsh1sub_n.asm: Remove.
+ * mpn/powerpc64/mode64/rsh1aors_n.asm: New file, code not based on
+ removed files.
+
+2013-06-28 Marc Glisse <marc.glisse@inria.fr>
+
+ * cxx/ismpf.cc: Use GMP_DECIMAL_POINT.
+ * cxx/osmpf.cc: Likewise.
+ * tests/cxx/t-locale.cc: Likewise.
+
+2013-06-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/p7/aorsorrlshC_n.asm: New file.
+ * mpn/powerpc64/mode64/p7/aorsorrlsh1_n.asm: New file.
+ * mpn/powerpc64/mode64/p7/aorsorrlsh2_n.asm: New file.
+
+ * mpn/powerpc64/mode64/aorsorrlshC_n.asm: Use alias regname.
+
+2013-06-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/p7/aors_n.asm: New file.
+
+2013-06-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * aorslshC_n.asm, aorslsh2_n.asm, aorslsh1_n.asm: Remove.
+ * aorsorrlshC_n.asm, aorsorrlsh1_n.asm, aorsorrlsh2_n.asm: New files.
+
+2013-06-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/p6/lshift.asm: Rewrite switching-into-loop code.
+ * mpn/powerpc64/p6/rshift.asm: Likewise.
+ * mpn/powerpc64/p6/lshiftc.asm: Likewise.
+
+2013-06-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/p6/lshift.asm: Fix typo in label reference.
+ For 32-bit mode, zero extend `n' argument and split retval.
+ * mpn/powerpc64/p6/rshift.asm: Likewise.
+ * mpn/powerpc64/p6/lshiftc.asm: Likewise.
+
+2013-06-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mu_div_q.c: Remove obsolete comment.
+
+2013-06-09 Marc Glisse <marc.glisse@inria.fr>
+
+ * mpn/generic/get_d.c (mpn_get_d): Avoid signed overflow.
+ * mpz/kronzs.c (mpz_kronecker_si): Use ABS_CAST.
+
+2013-05-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mu_div_q.c: Call mpn_mu_divappr_q for entire division,
+ never just for tail. (This fixes performance issues at the expense of
+ memory needs.)
+
+2013-05-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac (*sparc*-*-*): Major overhaul.
+
+2013-05-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Reporting Bugs): Ask for configure's output.
+
+ * mpn/ia64/divrem_2.asm: Don't clobber f16-f18.
+
+2013-05-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/udiv.asm: Change spacing to work around binutils bug.
+
+2013-05-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*): Bump version info.
+
+ * tests/misc.c (tests_hardware_getround, tests_hardware_setround):
+ Avoid assembly dependency unless WANT_ASSEMBLY.
+
+ * configure.ac (WANT_ASSEMBLY): Conditionally define.
+
+2013-05-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac (arm1156): Don't fall back to plain v6 compiler option.
+
+2013-05-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/mul_1.asm: Handle n = 1 for DOS64. Streamline.
+ * mpn/x86_64/coreisbr/aorsmul_1.asm: Streamline.
+
+2013-05-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/aorsmul_1.asm: Fix, then enable DOS64 support.
+ * mpn/x86_64/coreisbr/mul_1.asm: Enable DOS64 support.
+
+ * mpn/x86/p6/mmx/gmp-mparam.h: Set down SQR_TOOM2_THRESHOLD to parent
+ directory value.
+
+2013-05-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac (--enable-fake-cpuid): New option.
+ * mpn/x86_64/fat/fat.c (WANT_FAKE_CPUID): Remove defaulting.
+ * mpn/x86/fat/fat.c (WANT_FAKE_CPUID): Likewise.
+
+ * mpn/x86_64/bd1/mul_1.asm: Fix typo.
+
+2013-05-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat.c (fake_cpuid): Handle 0x80000001 request.
+ (fake_cpuid_available): Remove unused function.
+
+ * mpn/generic/mod_1_1.c: Cast constant udiv_rnnd_preinv arguments.
+ * mpn/generic/mod_1_2.c: Likewise.
+ * mpn/generic/mod_1_3.c: Likewise.
+ * mpn/generic/mod_1_4.c: Likewise.
+ * mpn/generic/divrem_2.c: Likewise.
+
+2013-05-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess (power*): Handle all ppc970 variants.
+
+2013-05-03 David S. Miller <davem@davemloft.net>
+
+ * tune/common.c (speed_mpn_addlsh1_n, speed_mpn_sublsh1_n,
+ speed_mpn_rsblsh1_n, speed_mpn_addlsh2_n, speed_mpn_sublsh2_n,
+ speed_mpn_rsblsh2_n): Don't define if these routines are macros.
+ * tune/speed.c (routine): Likewise don't table if they are macros.
+
+ * mpn/sparc64/ultrasparct3/addmul_1.asm: Add T4 and T3 timings.
+ * mpn/sparc64/ultrasparct3/aormul_4.asm: Likewise.
+ * mpn/sparc64/ultrasparct3/aorslsh_n.asm: Likewise.
+ * mpn/sparc64/ultrasparct3/cnd_aors_n.asm: Likewise.
+ * mpn/sparc64/ultrasparct3/submul_1.asm: Likewise.
+
+2013-05-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparct3/aorslsh_n.asm: Invoke INITCY where it has
+ effect.
+
+ * gmp-impl.h: Amend last change.
+ * tests/devel/try.c (choice_array): Don't try to table addlsh1_n etc if
+ a macro.
+
+2013-05-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/copyd.asm: Suppress dead pointer update.
+ * mpn/arm/copyi.asm: Likewise.
+ * mpn/arm/neon/logops_n.asm: Likewise.
+ * mpn/arm/neon/tabselect.asm: Likewise.
+ * mpn/arm/rshift.asm: Likewise.
+ * mpn/arm/tabselect.asm: Likewise.
+ * mpn/arm/v6/dive_1.asm: Likewise
+ * mpn/arm/v7a/cora15/neon/copyi.asm: Likewise.
+
+ * mpn/arm/v7a/cora15/neon/com.asm: New file.
+
+2013-05-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparct3/aormul_4.asm: New file.
+
+ * configure.ac (GMP_MULFUNC_CHOICES): Support mul_3 + addmul_3 and
+ mul_4 + addmul_4.
+
+ * mpn/sparc64/ultrasparct3/aormul_2.asm: Optimise lead-in code.
+
+ * mpn/sparc64/ultrasparct3/missing.m4 (addxccc): Allow g2 as input.
+ (umulxhi): Save and restore o7 to allow it as in/out parameter.
+
+2013-04-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v7a/cora15/cnd_aors_n.asm: New file, was mis-named.
+
+ * mpn/sparc64/ultrasparct3/addmul_1.asm: Rewrite.
+
+ * mpn/sparc64/ultrasparct3/submul_1.asm: Rewrite.
+
+ * mpn/sparc64/ultrasparct3/cnd_aors_n.asm: New file.
+
+ * gmp-impl.h: Override mpn_addlsh1_n, mpn_addlsh2_n, mpn_sublsh1_n, etc
+ with mpn_addlsh_n, etc when !HAVE_NATIVE the former but HAVE_NATIVE the
+ latter.
+
+ * mpn/sparc64/ultrasparct3/aorslsh_n.asm: New file.
+
+ * configure.ac (sparc-*-*): Recognise t5 along with t3 and t4.
+ Remove sparc64/ultrasparct1 from path_64 for T3, T3, and T5.
+
+2013-04-27 Mike Frysinger <vapier@gentoo.org>
+
+ * configure.ac (arm*-*-*): Set up path also for plainest CPU variants.
+
+2013-04-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v6/popham.asm: New file.
+
+ * mpn/arm/v7a/cora15/cnd-aors_n.asm: New file.
+
+2013-04-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/mod_34lsub1.asm: Clear carry smarter.
+
+ * mpn/arm/v7a/cora15/logops_n.asm: Conditionally suppress conditionally
+ used code.
+
+ * mpn/arm/v7a/cora15/submul_1.asm: New file.
+
+2013-04-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v7a/cora15/com.asm: New file.
+
+ * mpn/arm/v7a/cora15/logops_n.asm: New file.
+
+2013-04-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v7a/cora15/aors_n.asm: New file.
+
+ * mpn/arm/v7a/cora15/addmul_1.asm: Rewrite.
+
+2013-04-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/alpha/tabselect.asm: New file.
+
+2013-04-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc32/tabselect.asm: New file.
+
+ * longlong.h (arm64 count_trailing_zeros): New.
+
+ * mpn/arm64/invert_limb.asm: New file.
+
+ * mpn/generic/dive_1.c: Rewrite to use Hensel division also for
+ size = 1.
+
+ * mpn/generic/mod_1_1.c (add_mssaaaa): Provide VIS3 variant.
+
+ * configure.ac: Remove "missing" from extra_functions_64 for coreibwl.
+
+ * mpn/sparc64/ultrasparct3/mul_1.asm: Decrease loop alignment.
+ * mpn/sparc64/ultrasparct3/aormul_2.asm: Likewise.
+
+2013-04-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/alpha/invert_limb.asm: Generate table.
+ * mpn/powerpc64/mode64/invert_limb.asm: Likewise.
+ * mpn/s390_64/invert_limb.asm: Likewise.
+ * mpn/sparc64/ultrasparct3/invert_limb.asm: Likewise.
+ * mpn/x86_64/invert_limb_table.asm: Likewise.
+
+2013-04-15 David S. Miller <davem@davemloft.net>
+
+ * mpn/sparc32/sparc-defs.m4 (LEA64): New macro.
+ * mpn/sparc64/gcd_1.asm: Use it.
+ * mpn/sparc64/ultrasparct3/dive_1.asm: Likewise.
+ * mpn/sparc64/ultrasparct3/invert_limb.asm: Likewise.
+ * mpn/sparc64/ultrasparct3/mode1o.asm: Likewise.
+
+ * mpn/sparc64/gcd_1.asm: Use RODATA, TYPE, and SIZE.
+
+2013-04-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparct3/invert_limb.asm: Avoid addend for GOT entry,
+ it is not portable.
+
+ * mpn/sparc64/tabselect.asm: New file.
+
+ * mpn/x86/mmx/tabselect.asm: New file.
+ * configure.ac (x86): Add x86/mmx to path for relevant CPUs.
+
+ * mpn/sparc64/gcd_1.asm: Use rdpc for PIC.
+ * mpn/sparc64/ultrasparct3/mode1o.asm: Use rdpc for PIC.
+ * mpn/sparc64/ultrasparct3/dive_1.asm: Use rdpc for PIC.
+ * mpn/sparc64/ultrasparct3/invert_limb.asm: Handle PIC, use rdpc.
+
+ * Revert remaining parts of recent sparc LEA changes.
+
+2013-04-14 David S. Miller <davem@davemloft.net>
+
+ * mpn/sparc32/v9/sqr_diagonal.asm: Revert LEA and INT32 changes.
+ * mpn/sparc64/gcd_1.asm: Likewise.
+
+2013-04-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bd1/tabselect.asm: New file.
+ * mpn/x86_64/coreisbr/tabselect.asm: New file.
+ * mpn/x86_64/k10/tabselect.asm: New file.
+ * mpn/x86_64/coreinhm/tabselect.asm: New file.
+ * mpn/x86_64/core2/tabselect.asm: New file.
+ * mpn/x86_64/pentium4/tabselect.asm: New file.
+
+ * mpn/x86_64/fastsse/tabselect.asm: New file.
+ * mpn/arm/neon/tabselect.asm: Rewrite.
+ * mpn/arm/tabselect.asm: Rewrite.
+ * mpn/powerpc64/tabselect.asm: Rewrite.
+ * mpn/x86_64/tabselect.asm: Rewrite.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_TABSELECT): Implement special code,
+ making .r argument be table width.
+
+2013-04-11 David S. Miller <davem@davemloft.net>
+
+ * mpn/sparc32/sparc-defs.m4 (LEA): Remove unused local label.
+ (LEA_LEAF): Likewise.
+
+2013-04-11 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/arm/v6/submul_1.asm: New file, using the corresponding
+ addmul_1 loop + complement trick.
+
+2013-04-10 David S. Miller <davem@davemloft.net>
+
+ * acinclude.m4 (GMP_ASM_SPARC_GOTDATA,
+ GMP_ASM_SPARC_SHARED_THUNKS): New feature tests.
+ * configure.ac: Call GMP_ASM_SPARC_GOTDATA and
+ GMP_ASM_SPARC_SHARED_THUNKS on sparc.
+ * mpn/sparc32/sparc-defs.m4 (LEA, LEA_LEAF, LEA_THUNK): New macros.
+ * mpn/sparc32/udiv.asm: Convert over to LEA, LEA_LEAF, and LEA_THUNK.
+ * mpn/sparc32/v8/addmul_1.asm: Likewise.
+ * mpn/sparc32/v8/mul_1.asm: Likewise.
+ * mpn/sparc32/v8/supersparc/udiv.asm: Likewise.
+ * mpn/sparc32/v8/udiv.asm: Likewise.
+ * mpn/sparc64/gcd_1.asm: Likewise.
+ * mpn/sparc64/ultrasparct3/dive_1.asm: Likewise.
+ * mpn/sparc64/ultrasparct3/invert_limb.asm: Likewise.
+ * mpn/sparc64/ultrasparct3/mode1o.asm: Likewise.
+ * mpn/sparc32/v9/sqr_diagonal.asm: Likewise and use INT32.
+
+2013-04-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * longlong.h (sparc64): Test __VIS__ instead of __sparc_vis3.
+
+ * config.guess (sparc*): Invoke set_cc_for_build to get $dummy.
+
+2013-04-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Rework tmp file names, make sure to remove tmp files.
+
+ * mpn/arm/dive_1.asm: Rewrite count-trailing-zeros code, using private
+ table.
+
+ * mpn/arm: Canonicalise arm assembly to use old style "mov ... lsl" for
+ shift ops.
+
+2013-04-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparct3/mod_34lsub1.asm: New file.
+
+ * longlong.h (sparc64): Define umul_ppmm, add_ssaaaa, and
+ count_leading_zeros conditionally under the symbol __sparc_vis3.
+
+ * mpn/arm/dive_1.asm: New file.
+ * mpn/arm/v6/dive_1.asm: New file.
+
+ * mpn/arm/v6t2/mode1o.asm: Make trivial change to avoid v6t2...
+ * mpn/arm/v6/mode1o.asm: ...instruction, move file accordingly.
+
+ * mpn/powerpc64/mode64/invert_limb.asm: Put all multiplies low-limb first.
+
+2013-04-04 David S. Miller <davem@davemloft.net>
+
+ * mpn/sparc64/ultrasparct3/add_n.asm: Rewrite.
+ * mpn/sparc64/ultrasparct3/sub_n.asm: Rewrite.
+
+ * mpn/sparc64/ultrasparct3/invert_limb.asm: Align table.
+
+2013-04-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc32/sparc-defs.m4: Provide dummy lzcnt.
+
+ * tests/mpn/logic.c: Seed using RANDS, then use mpz_rrandomb.
+
+ * tests/mpn/t-div.c (random_word): Remove. Let callers invoke urandom.
+
+ * mpn/sparc64/ultrasparct3/mul_1.asm: Rewrite.
+
+ * mpn/sparc64/ultrasparct3/bdiv_dbm1c.asm: New file.
+ * mpn/sparc64/ultrasparct3/dive_1.asm: New file.
+ * mpn/sparc64/ultrasparct3/invert_limb.asm: New file.
+ * mpn/sparc64/ultrasparct3/mod_1_4.asm: New file.
+ * mpn/sparc64/ultrasparct3/mode1o.asm: New file.
+
+2013-04-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparct3/aormul_2.asm: Reschedule for better speed.
+
+2013-04-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparct3/missing.m4: Misc tweaks.
+ (lzcnt): New.
+ * mpn/sparc64/ultrasparct3/missing.asm (__gmpn_lzcnt): New function.
+
+ * mpn/sparc32/sparc-defs.m4: Put FAKE_T3 stuff here...
+ * mpn/sparc64/ultrasparct3/aormul_2.asm: ...moved from here.
+
+ * mpn/sparc64/ultrasparc1234/lshift.asm: Remove.
+ * mpn/sparc64/ultrasparc1234/rshift.asm: Remove.
+
+2013-04-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparct3/missing.m4 (umulxhi): Don't clobber retaddr,
+ allowing use in functions that does not do save/restore.
+
+ * mpn/sparc64/gcd_1.asm: Tweak for tighter loop.
+
+2013-03-31 David S. Miller <davem@davemloft.net>
+
+ * mpn/sparc64/lshift.asm: New file.
+ * mpn/sparc64/rshift.asm: New file.
+ * mpn/sparc64/lshiftc.asm: New file.
+
+2013-03-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparct1/lshift.asm: Remove.
+ * mpn/sparc64/ultrasparct1/rshift.asm: Remove.
+ * mpn/sparc64/ultrasparct1/lshiftc.asm: Remove.
+
+2013-03-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparct3/aormul_2.asm: Always do mulx before umulxhi.
+
+2013-03-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/mod_1_4.c (mpn_mod_1s_4p): Make precomputed arg 'const'.
+ (mpn_mod_1s_4p_cps): Update from generic code.
+
+2013-03-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/trialdiv.c: Make variables 'const' to match tables.
+
+ * mpn/generic/mod_1_1.c (mpn_mod_1_1p): Make precomputed arg 'const'.
+ * mpn/generic/mod_1_2.c (mpn_mod_1s_2p): Likewise.
+ * mpn/generic/mod_1_3.c (mpn_mod_1s_3p): Likewise.
+ * mpn/generic/mod_1_4.c (mpn_mod_1s_4p): Likewise.
+ * gmp-impl.h: Update prototypes.
+
+ * mpn/x86_64/mulx/aorsmul_1.asm: New file.
+ * mpn/x86_64/mulx/addmul_1.asm: Remove.
+
+2013-03-26 Niels Möller <nisse@lysator.liu.se>
+
+ Make mpn_cnd_add_n and mpn_cnd_sub_n public.
+ * doc/gmp.texi (Low-level Functions): Document mpn_cnd_add_n and
+ mpn_cnd_sub_n.
+ * gmp-h.in (mpn_cnd_add_n, mpn_cnd_sub_n): Moved prototypes
+ here...
+ * gmp-impl.h: ... from here.
+
+2013-03-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/pentium4/sse2/cnd_add_n.asm: New file.
+ * mpn/x86/pentium4/sse2/cnd_sub_n.asm: New file.
+ * mpn/x86/cnd_aors_n.asm: New file.
+
+2013-03-25 David S. Miller <davem@davemloft.net>
+
+ * mpn/sparc64/ultrasparct3/hamdist.asm: New file.
+ * mpn/sparc64/ultrasparct3/popcount.asm: New file.
+
+2013-03-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/ia64/aorsorrlshC_n.asm: Generalised from aorslshC_n.asm.
+ * mpn/ia64/aorsorrlsh1_n.asm: Generalised from aorslsh1_n.asm.
+ * mpn/ia64/aorsorrlsh2_n.asm: Generalised from aorslsh2_n.asm.
+
+2013-03-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v7a/cora15/neon/aorsorrlshC_n.asm: New file.
+ * mpn/arm/v7a/cora15/neon/aorsorrlsh2_n.asm: New file.
+ * mpn/arm/v7a/cora15/neon/aorsorrlsh1_n.asm: New file.
+ * mpn/arm/v7a/cora15/neon/rsh1aors_n.asm: New file.
+
+ * configure.ac (GMP_MULFUNC_CHOICES): Support add+sub+rsb lsh files.
+
+ * tests/refmpn.c (refmpn_addlsh_nc, refmpn_sublsh_nc): Remove silly
+ assert of mp_limb being non-negative.
+
+2013-03-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/neon/lshiftc.asm: New file.
+
+ * mpn/arm/v6/sqr_basecase.asm: Trim 'sqr_diag_addlsh1' loop.
+
+ * gen-trialdivtab.c: Output just raw data, remove actual variables.
+ * mpn/generic/trialdiv.c: Put variables from gen-trialdivtab.c here,
+ and make them 'const'.
+
+2013-03-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Rework arm CPU recognition.
+ * config.sub: Corresponding updates.
+ * configure.ac: Likewise.
+
+ * mpn/x86_64/mulx/adx/addmul_1.asm: Let FAKE_MULXADX be off by default.
+
+ * mpn/arm/v7a/cora15/neon/copyi.asm: Move from "..".
+ * mpn/arm/v7a/cora15/neon/copyd.asm: Likewise.
+
+ * config.guess: Tack on "neon" for appropriate arm CPUs.
+ * configure.ac (arm*-*-*): Recognise neon suffix for a8, a9, and a15.
+
+2013-03-19 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpf/fits_u.h: Accept numbers truncating to zero before checking the
+ sign.
+ * tests/mpf/t-fits.c: Check new edges.
+
+2013-03-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/arm32check.c: Get printing of clobbered register right.
+
+ * mpn/arm/neon/popcount.asm: New file.
+ * mpn/arm/neon/hamdist.asm: New file.
+
+ * tests/Makefile.am (EXTRA_libtests_la_SOURCES): Add arm32call.asm and
+ arm32check.c.
+
+2013-03-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac (arm*-*-*): Define CALLING_CONVENTIONS_OBJS.
+
+ * tests/arm32call.asm: New file.
+ * tests/arm32check.c: New file.
+
+ * mpn/arm/arm-defs.m4 (LEA): Rewrite to properly handle repeated use.
+ (EPILOGUE_cpu): Define.
+
+ * mpn/arm/v6/addmul_3.asm: Make code work for PIC.
+
+ * tests/x86call.asm: Modernise asm syntax.
+ * tests/amd64call.asm: Likewise.
+
+ * mpn/x86/darwin.m4 (m4append): Move definition from here...
+ * mpn/asm-defs.m4: ...to here.
+
+2013-03-18 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * doc/gmp.texi (--enable-fat): No quote in concept index.
+
+ * mpf/swap.c: Reduce the number of variables.
+
+2012-03-17 Marc Glisse <marc.glisse@inria.fr>
+
+ * tests/cxx/t-do-exceptions-work-at-all-with-this-compiler.cc: New file.
+ * tests/cxx/Makefile.am: Add new file. Reorder the tests.
+
+2013-03-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mul_fft.c: Use TMP_BALLOC*, but combine several areas.
+
+ * mpz/powm_ui.c (mod): Use TMP_BALLOC in mu code.
+
+ * mpn/arm/v6/addmul_3.asm: New file.
+
+ * mpn/arm/v7a/cora15/copyd.asm: Tweak.
+
+ * mpn/arm64/copyi.asm: New file.
+ * mpn/arm64/copyd.asm: New file.
+
+2013-03-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v6/addmul_2.asm: Tweak for better A9 performance.
+
+2013-03-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/ia64/cnd_aors_n.asm: New file.
+
+ * mpn/arm64/cnd_aors_n.asm: New file.
+
+ * mpn/arm64/aors_n.asm (ADDSUB): Remove unused definition.
+
+ * mpn/ia64/aors_n.asm: Remove a redundant ASM_START.
+
+ * mpn/arm/cnd_aors_n.asm: Avoid ARM conditional insn execution.
+
+ * mpn/x86_64/missing.asm: Move from mulx/adx since we cannot currently
+ prune missing.asm from path.
+ * mpn/x86_64/mulx/adx/missing-call.m4: Likewise.
+ * mpn/x86_64/mulx/adx/missing-inline.m4: Likewise.
+ * mpn/x86_64/mulx/adx/addmul_1.asm: Update hardwired path.
+
+2013-03-13 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/cong_2exp.c: Write loops in a cleaner way.
+ * mini-gmp/mini-gmp.c: Likewise.
+ * gmp-impl.h (mpz_zero_p): Likewise.
+
+2013-03-12 Niels Möller <nisse@lysator.liu.se>
+
+ New names mpn_cnd_add_n and mpn_cnd_sub_n.
+ * mpn/generic/cnd_add_n.c (mpn_cnd_add_n): Renamed file and
+ function, from addcnd.c:mpn_addcnd_n.
+ * mpn/generic/cnd_sub_n.c (mpn_cnd_sub_n): Renamed, from
+ subcnd.c:mpn_subcnd_n.
+ * mpn/arm/cnd_aors_n.asm: Renamed file, from aorscnd.asm, and
+ renamed functions.
+ * mpn/x86_64/cnd_aors_n.asm: Analogous renaming.
+ * mpn/powerpc64/mode64/cnd_aors_n.asm: Analogous renaming.
+ * gmp-impl.h (mpn_cnd_add_n, mpn_cnd_add_n): Updated prototypes
+ with new names.
+ * configure.ac: Updated for new names.
+ * tests/refmpn.c (refmpn_cnd_add_n): Renamed, from refmpn_addcnd_n.
+ (refmpn_cnd_sub_n): Renamed, from refmpn_subcnd_n.
+ * tests/tests.h (refmpn_cnd_add_n, refmpn_cnd_sub_n): Updated
+ prototypes with new names.
+ * tune/common.c (speed_mpn_cnd_add_n): Renamed, from
+ speed_mpn_addcnd_n, call mpn_cnd_add_n.
+ (speed_mpn_cnd_sub_n): Renamed, from speed_mpn_subcnd_n, call
+ mpn_cnd_sub_n.
+ * tune/speed.h (speed_mpn_cnd_add_n, speed_mpn_cnd_sub_n): Updated
+ prototypes with new names.
+ * tune/speed.c (routine): Updated list with new names.
+ * tests/devel/try.c: Updated for new mpn_cnd_* names.
+ * mpn/generic/sbpi1_div_sec.c: Likewise.
+ * mpn/generic/powm_sec.c: Likewise.
+
+2013-03-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac: Add "missing" to extra_functions_64 for coreibwl.
+
+ * mpn/x86_64/mulx/adx/addmul_1.asm: Simplify. Make FAKE_MULXADX the
+ default awaiting proper qemu behaviour.
+
+2013-03-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/aorscnd_n.asm: Read 32 bits for 'n' arguments on DOS64.
+
+ * tests/mpz/t-powm_ui.c: Test larger arguments. General cleanup.
+
+ * mpz/powm_ui.c (mod): Adhere to mpn_mu_div_qr's overlap requirements.
+
+2013-03-10 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/sbpi1_div_sec.c: Update calls of mpn_addcnd_n and
+ mpn_subcnd_n.
+ * mpn/generic/powm_sec.c (MPN_REDC_1_SEC, MPN_REDC_2_SEC)
+ (mpn_powm_sec): Update calls of mpn_subcnd_n.
+
+ * tests/tests.h (refmpn_addcnd_n, refmpn_subcnd_n): Update
+ declarations.
+ * tests/refmpn.c (refmpn_addcnd_n, refmpn_subcnd_n): Similar
+ reorder of arguments.
+ * tests/devel/try.c (call): Pass condition first, for
+ TYPE_ADDCND_N and TYPE_SUBCND_N.
+
+ * tune/common.c (speed_mpn_addcnd_n, speed_mpn_subcnd_n): Update
+ to pass condition as first argument.
+
+ * gmp-impl.h (mpn_addcnd_n, mpn_subcnd_n): Updated declarations.
+
+ * mpn/generic/addcnd_n.c (mpn_addcnd_n): Reordered arguments, make
+ condition the first argument.
+ * mpn/generic/subcnd_n.c (mpn_subcnd_n): Likewise.
+ * mpn/arm/aorscnd_n.asm: Likewise.
+ * mpn/x86_64/aorscnd_n.asm: Likewise.
+ * mpn/powerpc64/mode64/aorscnd_n.asm: Likewise.
+
+2013-03-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mulx/adx/missing.asm: Simulate some mulx/adx insns.
+ * mpn/x86_64/mulx/adx/missing-call.m4: Call variant.
+ * mpn/x86_64/mulx/adx/missing-inline.m4: Inline variant.
+
+ * mpn/sparc64/ultrasparct3/missing.asm: Simulate some v9-2011 insns.
+ * mpn/sparc64/ultrasparct3/missing.m4: Inline or invoke missing.asm for
+ v9-2011 insn.
+
+ * configure.ac: Strip `haswell' from paths for now.
+
+ * mpn/x86_64/mulx/addmul_1.asm: New.
+ * mpn/x86_64/mulx/mul_1.asm: Rewrite file from `haswell' subdir.
+ * mpn/x86_64/mulx/adx/addmul_1.asm: Likewise.
+ * mpn/x86_64/haswell: Remove.
+
+ * mpn/arm/v7a/cora15/mul_1.asm: New file.
+ * mpn/arm/v7a/cora15/addmul_1.asm: New file.
+
+2013-03-09 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpz/t-cong_2exp.c: Improve coverage.
+
+2013-03-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparc1234/add_n.asm: Use g5 instead of g4.
+ * mpn/sparc64/ultrasparc1234/sub_n.asm: Likewise.
+
+ * mpn/sparc64/ultrasparct3/aormul_2.asm: Fix a typo.
+
+2013-03-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v7a/cora9/gmp-mparam.h: New file.
+
+ * configure.ac (GMP_MULFUNC_CHOICES): Support mul_2 + addmul_2.
+
+ * mpn/sparc64/ultrasparct3/aormul_2.asm: New file.
+
+ * mpn/sparc64/ultrasparct3/submul_1.asm: Optimise out two carry
+ propagating adds.
+
+2013-03-06 David Miller <davem@davemloft.net>
+
+ * config.guess: Recognize UltraSparc T4 under Linux.
+ * configure.ac: Add sparc64/ultrasparct3 to path_64 when T3 or T4.
+ Append -xarch=v8plusd or -xarch=v9d to command line, as needed.
+ * mpn/sparc64/ultrasparct3/mul_1.asm: New file.
+ * mpn/sparc64/ultrasparct3/addmul_1.asm: New file.
+ * mpn/sparc64/ultrasparct3/submul_1.asm: New file.
+ * mpn/sparc64/ultrasparct3/add_n.asm: New file.
+ * mpn/sparc64/ultrasparct3/sub_n.asm: New file.
+
+ * mpn/sparc32/ultrasparct1/mul_1.asm: Unroll main loop one time, add
+ T2/T3/T4 timings.
+ * mpn/sparc32/ultrasparct1/addmul_1.asm: Likewise.
+ * mpn/sparc32/ultrasparct1/submul_1.asm: Likewise.
+
+2013-03-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/neon/lorrshift.asm: New file.
+
+2013-03-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v7a/cora15/copyd.asm: New file.
+ * mpn/arm/v7a/cora15/copyi.asm: New file.
+
+ * mpn/arm64/logops_n.asm: New file.
+ * mpn/arm64/gcd_1.asm: New file.
+ * mpn/arm64/aorsmul_1.asm: New file.
+ * mpn/arm64/addmul_1.asm: Remove.
+ * mpn/arm64/aors_n.asm: Complete rewrite.
+
+ * mpn/arm/tabselect.asm: New file.
+ * mpn/arm/neon/tabselect.asm: New file.
+
+ * mpn/arm/copyi.asm: Software pipeline.
+ * mpn/arm/copyd.asm: Likewise.
+
+ * config.guess: Rework tmp file handling to resemble configfsf.guess's.
+
+2013-03-03 Niels Möller <nisse@lysator.liu.se>
+
+ * doc/gmp.texi (Integer Special Functions): Document
+ mpz_limbs_read, mpz_limbs_write, mpz_limbs_modify,
+ mpz_limbs_finish, mpz_roinit_n and MPZ_ROINIT_N.
+
+ * mpz/roinit_n.c (mpz_roinit_n): Normalize the input.
+
+2013-02-27 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/common.c (speed_measure): Increase repetition count if we
+ get a zero measurement.
+
+2013-02-27 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c (mpz_div_q_2exp): Adjust only if needed.
+ (mpn_common_scan): New service function to unify scan loops.
+ (mpz_scan0, mpz_scan1): Simplify by using mpn_common_scan.
+ (mpz_make_odd): Simplify, assume in-place operation on positive.
+ (mpn_scan0, mpn_scan1): New functions.
+ * mini-gmp/mini-gmp.h (mpn_scan0, mpn_scan1): New declarations.
+ * mini-gmp/tests/t-scan.c: Test also mpn_scan0 and mpn_scan1.
+
+2013-02-26 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-limbs.c (check_roinit): Test MPZ_ROINIT_N only if
+ compiler supports c99.
+
+2013-02-25 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/tests/t-double.c (testmain): Declare double variables
+ as volatile, to drop extended precision.
+
+ * mini-gmp/tests/testutils.c (testfree): New function. Use it
+ everywhere where test programs deallocate storage allocated via
+ the mini-gmp allocation functions, including uses of mpz_get_str
+ for various test failure messages.
+
+ * mpz/limbs_finish.c (mpz_limbs_finish): New file and function.
+ * mpz/limbs_modify.c (mpz_limbs_modify): New file and function.
+ * mpz/limbs_read.c (mpz_limbs_read): New file and function.
+ * mpz/limbs_write.c (mpz_limbs_write): New file and function.
+ * mpz/roinit_n.c (mpz_roinit_n): New file and function.
+ * gmp-h.in: Declare new functions.
+ (MPZ_ROINIT_N): New macro.
+ * mpz/Makefile.am (libmpz_la_SOURCES): Added new files.
+ * Makefile.am (MPZ_OBJECTS): Added new object files.
+
+ * tests/mpz/t-limbs.c: New testcase.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Added t-limbs.
+
+2013-02-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac: Fix typo in adx/mulx path stripping code.
+ * config.sub: Match coreibwl.
+
+2013-02-20 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpq/t-get_d.c (check_random): Rewrote to make test less
+ dependent on float operations. Fixes problem with m68k-linux and
+ extended float precision.
+
+2013-02-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/haswell/mulx/adx/addmul_1.asm: New file.
+
+ * configure.ac: Support coreibwl. Use proper name for ADX extension.
+ * acinclude.m4 (GMP_ASM_X86_ADX): Rename from GMP_ASM_X86_ADOX.
+
+ * tests/tests.h (TESTS_REPS): Keep count >= 1.
+
+2013-02-19 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c: Move asserts to work-around a compiler bug.
+ (mpz_export): Reorder branches.
+ (mpz_mul_ui): Avoid temporary allocation (mpn_mul_1 can work in-place).
+
+ * mini-gmp/tests/t-reuse.c: Fix typo causing the same negation
+ condition to be applied to all operands. (See 2013-02-03, Torbjorn)
+
+2013-02-17 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmpxx.h (mpq_class, mpf_class) [init_ui, init_si, assign_si]:
+ Optimise _si using _ui for positive arguments.
+ (__gmp_hypot_function): Use _mul_ui to square an ui, abs for si.
+
+ * mini-gmp/mini-gmp.c (mpz_mul): Read sizes just once.
+ (mpn_set_str_other): Remove a redundant variable.
+ (mpz_abs_add): Use SWAP once, to order sizes.
+ (mpz_mul_ui): Micro-optimisation.
+ (mpz_rootrem): Use _init2 before _setbit.
+ (mpz_set_str): Optimise-out a variable.
+ (mpz_import): Normalise only if needed.
+ (mpn_div_qr_1): Speed-up the d=1 case, delaying a branch.
+
+ * rand/randmts.c: Use init2, as size of variables is known in advance.
+ (mangle_seed): Get a single argument.
+
+ * mpz/remove.c: Delay allocation in the generic case; use swap
+ instead of set.
+ * mpn/generic/remove.c: Delay (possibly smaller) allocation.
+
+2013-02-17 Marc Glisse <marc.glisse@inria.fr>
+
+ * cxx/osdoprnti.cc: Use <stdarg.h> and <string.h> rather than <cstdarg>
+ and <cstring> (revert 2002-12-21).
+
+ * tests/cxx/Makefile.am: Link with libm.
+ * tests/cxx/t-ops2.cc: Comment about more tests. Use <math.h> rather
+ than <cmath> and using namespace. Don't include <iostream>.
+
+ * gmpxx.h (__GMPXX_BITS_TO_LIMBS, __GMPQ_NUM_DBL_LIMBS,
+ __GMPQ_DEN_DBL_LIMBS, __GMPXX_TMPQ_D): New macros.
+ (__gmp_binary_plus, __gmp_binary_minus, __gmp_binary_multiplies,
+ __gmp_binary_divides, __gmp_binary_equal, __gmp_binary_less,
+ __gmp_cmp_function): Use __GMPXX_TMPQ_D.
+ * tests/cxx/t-ops2.cc: Test __GMPXX_TMPQ_D on DBL_MIN, DBL_MAX.
+
+ * gmpxx.h (__gmp_binary_multiplies, __gmp_binary_divides): Use
+ __GMPXX_CONSTANT_TRUE.
+
+2013-02-16 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h: Include <algorithm>.
+
+2013-02-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/Makefile.am (TARG_DIST): Add arm64.
+
+ * mpn/x86_64/x86_64-defs.m4 (PROTECT): Emit '.hidden' instead of
+ '.protected" to please Sun's assembler, but also for semantic reasons.
+
+2013-02-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac (arm64*-*-*): Match this.
+
+ * mpn/arm64/aors_n.asm: New file.
+ * mpn/arm64/addmul_1.asm: New file.
+ * mpn/arm64/mul_1.asm: New file.
+
+2013-02-15 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS,
+ __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS): New macros.
+ (mpz_class, mpq_class, mpf_class) [init_ui, init_si, init_d,
+ assign_ui, assign_si, assign_d]: New functions.
+ (__gmp_expr::__gmp_expr, __gmp_expr::operator=): Replace with macros.
+ (__GMPXX_CONSTANT_TRUE): New macro.
+
+2013-02-15 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h (NEG_CAST, ABS_CAST): Use __GMP_CAST.
+ * mpz/fits_s.h: Use NEG_CAST.
+
+2013-02-14 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__gmp_binary_greater): Forward to __gmp_binary_less.
+ (__gmp_binary_equal): Forward to itself after swapping operands.
+
+2013-02-14 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mp_dv_tab.c (__gmp_digit_value_tab): Remove a line of unused values.
+ * mpf/set_str.c: Update offset accordingly.
+ * mpz/inp_str.c: Likewise.
+ * mpz/set_str.c: Likewise.
+
+ * gmp-h.in (mpq_cmp_ui): Optimise comparison with 1/1.
+ * tests/mpq/t-cmp_ui.c: Test special comparisons: 0/1, 1/1.
+
+ * mpz/clrbit.c: Reorganise branches.
+ * mpz/setbit.c: Likewise.
+ * mpz/combit.c: Same micro-optimisations as in set/clr.
+
+ * mpz/aors_ui.h: No realloc if size was zero.
+ * mpz/ior.c: Use macros: MPZ_REALLOC and MPN_INCR_U.
+
+ * gmp-impl.h (NEG_CAST): New macro, used by ABS_CAST.
+ * mpq/cmp_si.c: Use NEG_CAST.
+ * mpz/cmp_si.c: Reorganise branches.
+
+2013-02-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * acinclude.m4 (GMP_ASM_X86_MULX, GMP_ASM_X86_ADOX): New feature tests.
+ * configure.ac: Use new feature tests.
+
+ * mpn/x86_64/haswell/mulx/mul_1.asm: File moved to cope with older
+ assemblers.
+ * configure.ac: Update haswell path to include "mulx".
+
+2013-02-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac: Recognise haswell.
+ * config.guess: Recognise haswell.
+ * config.sub: Match haswell.
+
+ * mpn/x86_64/haswell/mul_1.asm: New file, mainly for testing HNI.
+
+2013-02-12 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h (MPZ_PROVOKE_REALLOC): Remove unused macro.
+ * gen-fac.c (gen_consts): Remove obsolete code, use swap instead of set.
+ * mini-gmp/mini-gmp.c (fac_ui, bin_uiui): Use shorter and faster code.
+
+ * mpn/generic/mulmod_bnm1.c: Reorganise branches.
+ * mini-gmp/mini-gmp.c: Reduce branches.
+
+ * mpz/bin_ui.c: Avoid a copy when n < 0.
+ * mpz/mfac_uiui.c: Reduce memory usage.
+ * mpz/primorial_ui.c: Use MPZ_NEWALLOC.
+
+ * mpz/import.c: Use BITS_TO_LIMBS and MPZ_NEWALLOC.
+ * mpz/inp_raw.c: Likewise.
+ * mpz/rrandomb.c: Likewise.
+ * mpz/urandomb.c: Likewise.
+ * mpn/generic/random2.c: Likewise.
+
+ * mpn/generic/brootinv.c: Micro-optimisation.
+
+ * mpf/set_str.c: Don't chech base==0 when base is strictly positive.
+
+2013-02-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * Version 5.1.1 released.
+
+2013-02-07 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_MUL): Use operands from struct s.
+ * tune/README: Document new parameter syntax mpn_mul.<#> .
+
+2013-02-06 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-jac.c (check_large_quotients): Rewrote. Now uses a
+ more efficient method for generating the test inputs.
+
+2013-02-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/t-div.c: Limit random dbits to avoid an infinite loop.
+
+2013-02-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/reuse.c: Fix typo causing the same negation condition to be
+ applied to all operands. Fix condition for when to invoke mpz_remove.
+ Make different-size random operands.
+
+2013-02-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/remove.c: Correct the sign in case of reuse.
+
+2013-02-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (DIGITS_IN_BASE_PER_LIMB): Add a cast.
+ (LIMBS_PER_DIGIT_IN_BASE): Likewise.
+
+ * tests/refmpn.c (refmpn_mul): Use toom6h instead of toom44 for the
+ largest operands.
+
+2013-01-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom44_mul.c: Revert last change in favour of a simple
+ change (thanks Marco!).
+ * mpn/generic/toom4_sqr.c: Likewise.
+
+2013-01-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom44_mul.c (MAYBE_mul_toom44): Take toom6h and toom8h
+ into account, using new macro MUL_NEXTALG_THRESHOLD.
+ * mpn/generic/toom4_sqr.c (MAYBE_sqr_toom4): Likewise.
+
+2013-01-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/remove.c: init+set=init_set, cast before shifting.
+
+ * mpz/cmp_si.c: Use ABS_CAST.
+
+2013-01-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/logic.c: Set things up to always test library logops, not
+ gmp-impl.h's inlined variants. Test also mpn_com.
+
+ * tests/mpn/t-mod_1.c: Test also mpn_mod_1s_3p.
+
+ * mpn/generic/mod_1_3.c: Swap some lines to make it similar to mod_4.c.
+
+ * tests/mpz/reuse.c: Fix typo in last change.
+
+2013-01-23 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c (mpz_cmpabs_d, mpz_cmp_d): Simplify.
+ (mpz_set_str): Behaviour more adherent to the real GMP.
+
+ * mini-gmp/tests/t-str.c: Cast size_t to unsigned long, for printf.
+ * mini-gmp/tests/t-import.c: Likewise.
+ * mini-gmp/tests/t-comb.c: Remove an unused var.
+ * mini-gmp/tests/t-div.c: Remove unused args passed to fprintf.
+ * mini-gmp/tests/t-double.c: Use float immediates with float vars.
+
+2013-01-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*): Bump version info.
+ * gmp-h.in: Bump version.
+
+ * tests/mpz/reuse.c: Delete always zero 'failures' and code depending
+ on it. Replace rotating progress with real measure.
+
+ * Makefile.am (check-mini-gmp): Fix typo in last change.
+
+2013-01-22 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/mini-gmp.c (mpz_cmp_d): Simplified, just sort out
+ signs, then call mpz_cmpabs_d.
+
+ * mini-gmp/tests/testutils.h: Include stdio.h and stdlib.h.
+ (numberof): New define.
+
+ * mini-gmp/tests/t-cmp_d.c: New file, copied from
+ tests/mpz/t-cmp_d.c with minor changes.
+ * mini-gmp/tests/Makefile (CHECK_PROGRAMS): Added t-cmp_d,
+
+ * mini-gmp/mini-gmp.c (mpz_cmpabs_d): New function.
+ * mini-gmp/mini-gmp.h: Declare it.
+
+2013-01-21 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/tests/t-str.c (testmain): Test mpz_out_str, using
+ the tmpfile function for i/o.
+
+2013-01-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * Makefile.am (check-mini-gmp): Set also DYLD_LIBRARY_PATH for the
+ benefit of Darwin.
+
+ * tests/mpn/t-div.c: Test mpn_sb_div_qr_sec and mpn_sb_div_r_sec.
+ (main): Separate divisor into normalised (dnp) and unnormalised (dup),
+ pass appropriate variant to each function.
+ (main): Make negative `test' index value mean divisor bits, for better
+ small operands coverage.
+ (main): Put random junk at qp[] instead of zeroing.
+
+ * tests/mpz/t-remove.c: Back out last change which left `divisor_size'
+ uninitialised; achieve change's aim with a parameter tweak.
+
+2013-01-20 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/tests/testutils.c (testhalves): New function, test default
+ memory functions.
+ * mini-gmp/tests/testutils.h (testhalves): Declare it
+ * mini-gmp/tests/t-logops.c: Use testhalves.
+
+ * mini-gmp/mini-gmp.c (mpz_init_set_str): New function.
+ * mini-gmp/mini-gmp.h (mpz_init_set_str): Declare it.
+ * mini-gmp/tests/t-str.c: Test mpz_init_set_str.
+
+2013-01-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/memory.c (PTRLIMB): New macro, used for conformant casting.
+
+2013-01-19 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/tests/t-double.c (testmain): Get the current free
+ function using mp_get_memory_functions.
+ * mini-gmp/tests/t-str.c (testmain): Likewise.
+
+ * mini-gmp/tests/testutils.h (tu_free): Remove declaration.
+
+ * mini-gmp/tests/testutils.c (block_check, tu_free): Mark static.
+
+ * tests/mpz/t-set_str.c: Check also failing conditions.
+
+ * tests/mpz/t-remove.c: Test removal of 1.
+
+2013-01-18 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/tests/t-str.c (test_small): New function, exercising
+ parsing of whitespace and base prefixes.
+ (testmain): Call it.
+
+ * mini-gmp/tests/t-gcd.c (gcdext_valid_p): Fixed memory leak.
+
+ * mini-gmp/tests/t-double.c (testmain): Call tu_free rather than
+ free, for storage allocated by mpz_get_str.
+ * mini-gmp/tests/t-str.c (testmain): Likewise.
+
+ * mini-gmp/tests/testutils.c (block_init, block_check): New
+ functions.
+ (tu_alloc, tu_realloc, tu_free): New functions.
+ (main): Use mp_set_memory_functions.
+ * mini-gmp/tests/testutils.h (tu_free): Declare.
+
+ * mini-gmp/tests/testutils.h: New file, declarations for test
+ programs.
+
+ * mini-gmp/tests/testutils.c (main): New file, with shared main
+ function for all the test programs. Also includes mini-gmp.c.
+ Calls testmain after initialization. All other test programs
+ updated to define testmain rather than main.
+
+2013-01-18 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/tests/t-signed.c: Slightly larger coverage.
+ * mini-gmp/tests/t-double.c: Test also mpz_init_set_d.
+
+2013-01-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/set_str.c (normalization_steps): Eliminate set-but-unused
+ variable.
+
+ * mini-gmp/tests/t-div.c: Test mpz_divisible_p and mpz_divisible_ui_p.
+
+ * tests/tests.h (TESTS_REPS): Fix printf argument type clashes.
+
+ * mini-gmp/tests/t-div.c: Test also mpz_mod, mpz_mod_ui. Compare
+ mpz_divisible_p just to ceil, to save time.
+
+ * mini-gmp/mini-gmp.c: Prefix some names with GMP_.
+
+2013-01-16 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/tests/t-double.c: Test mpz_cmp_d.
+ * mini-gmp/mini-gmp.c (mpz_cmp_d): Correct multiword comparison.
+
+ * mini-gmp/mini-gmp.c (mpz_set_str): Handle the empty string.
+ * mini-gmp/tests/t-str.c: Test base <= 0.
+
+2013-01-15 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/tests/t-str.c (main): Use x->_mp_d rather than x[0]._mp_d.
+ * mini-gmp/tests/t-invert.c (main): Likewise.
+
+ * mini-gmp/tests/t-mul.c (main): Test mpn_mul_n and mpn_sqr.
+
+ * mini-gmp/tests/hex-random.h (enum hex_random_op): New value
+ OP_SQR.
+
+ * mini-gmp/tests/mini-random.c (mini_random_op3): Renamed, from...
+ (mini_random_op): ... old name. Updated callers.
+ (mini_random_op2): New function.
+
+ * mini-gmp/tests/hex-random.c (hex_random_op3): Renamed, from...
+ (hex_random_op): ... old name. Updated callers.
+ (hex_random_op2): New function.
+
+2013-01-15 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/tests/t-logops.c: Improve popcount/hamdist testing.
+ * mini-gmp/tests/t-signed.c: Test more cases.
+
+2013-01-15 Torbjorn Granlund <tege@gmplib.org>
+
+ From Mike Frysinger:
+ * configure.ac: Add x32 ABI for x86_64.
+
+2013-01-14 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/tests/t-str.c (main): Added tests for mpn_get_str and
+ mpn_set_str.
+
+2013-01-14 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * doc/gmp.texi (gmp_version): Remove "was used" repetition.
+ (Upward compatibility): Mention mpn_bdivmod, GMP 4 -> GMP 5.
+
+2013-01-13 Marc Glisse <marc.glisse@inria.fr>
+
+ * doc/gmp.texi: Let mpn_sqrtrem reference mpn_perfect_square_p instead
+ of mpz_perfect_square_p.
+
+2013-01-11 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/tests/t-comb.c: New test program, testing both
+ mpz_fac_ui and mpz_bin_uiui.
+ * mini-gmp/tests/Makefile (CHECK_PROGRAMS): Added t-comb.
+
+ * mini-gmp/mini-gmp.c (mpz_mul_si): Simplify.
+ (mpz_mul_ui, mpz_mul, mpz_div_qr): Replace init+REALLOC with init2.
+
+ * mini-gmp/mini-gmp.c (NEG_CAST): New macro.
+ (mpz_mul_si, mpz_set_si, mpz_cmp_si): Use NEG_CAST.
+
+ * mini-gmp/mini-gmp.c (mpz_set_si, mpz_cmp_si): Simplify by using
+ the _ui variant.
+
+ * mini-gmp/tests/t-root.c: Use mpz_ui_pow_ui, when base fits an ui.
+
+ * mini-gmp/tests/t-mul.c: Test also mpz_mul_si.
+ * mini-gmp/tests/t-sub.c: Test also mpz_ui_sub.
+
+ * mini-gmp/mini-gmp.c (mpz_fits_slong_p): Correct range.
+ * mini-gmp/tests/t-signed.c: New test program, for get/set/cmp_si.
+ * mini-gmp/tests/Makefile (CHECK_PROGRAMS): Added t-signed.
+
+ * mini-gmp/mini-gmp.c (mpz_hamdist): Handle different sizes.
+ * mini-gmp/tests/t-logops.c: Test also popcount and hamdist.
+
+2013-01-10 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/export.c: Less restrictive ASSERTs.
+ * mini-gmp/mini-gmp.c (mpz_export, mpz_import): Likewise.
+ * mini-gmp/tests/t-import.c: Test also size=0 or count=0.
+
+2013-01-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mini-gmp/tests/t-import.c (main): Don't drop off function end.
+
+ * Makefile.am (check-mini-gmp): Set LD_LIBRARY_PATH to allow testing
+ with dynamic main GMP build.
+
+2013-01-09 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c (mpz_export): Support op=0 countp=NULL.
+
+2013-01-08 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/tests/t-import.c: New test program, testing both
+ mpz_import and mpz_export.
+ * mini-gmp/tests/Makefile (CHECK_PROGRAMS): Added t-import.
+
+ * mini-gmp/tests/mini-random.c (mini_rrandomb_export): New
+ function.
+ * mini-gmp/tests/mini-random.h: Declare it.
+ * mini-gmp/tests/hex-random.c (hex_rrandomb_export): New function.
+ * mini-gmp/tests/hex-random.h: Declare it.
+
+ * mini-gmp/mini-gmp.c (mpz_export): Compute accurate word count up
+ front, to avoid generating any high zero words.
+
+2013-01-07 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/README: Document base limitation for conversions.
+ * mini-gmp/mini-gmp.c (mpz_set_str): Remove goto.
+ (mpz_import, mpz_export): Correctly use order/endianness.
+
+2013-01-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * longlong.h (aarch64): Make add_ssaaaa and sub_ddmmss actually work.
+
+2013-01-04 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ From shuax:
+ * mini-gmp/mini-gmp.c (mpz_import): Reset limb after storing it.
+
+2013-01-04 Torbjorn Granlund <tege@gmplib.org>
+
+ From Marko Lindqvist:
+ * configure.ac: Use AC_CONFIG_HEADERS instead of the obsolete
+ AM_CONFIG_HEADER.
+
+2013-01-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpz/bit.c: Wider testing for mpz_combit.
+ * tests/mpz/logic.c: Check the -2^n case.
+
+ * mpz/ior.c: Fixed an allocation bug in the -2^n case.
+
+2012-12-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/get_d.c: Minor reorg, add vax D code.
+
+ * gmp-impl.h (double_extract): New union type for vax D floats.
+
+ * tests/mpq/t-get_d.c (check_random): Limit exponents on vax.
+
+2012-12-30 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpz/bit.c (check_clr_extend): Check _set shrink.
+
+2012-12-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * demos/calc/calc.c: Remove generated file from repo.
+ * demos/calc/calc.h: Likewise.
+ * demos/calc/calclex.c: Likewise.
+
+2012-12-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/get_d.c: Complete rewrite of non-IEEE code.
+
+ * tests/mpq/t-get_d.c (main): Suppress check_random for vax.
+
+2012-12-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bdiv_q_1.asm: Use LEA for binvert_limb_table.
+
+2012-12-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-get_d.c (check_onebit): Decrease vax limit to avoid
+ overflow in last, unused 'want' value.
+
+ * config.guess: Recognise AMD family 22 as a future bobcat.
+
+2012-12-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.ac: Rename configure.in.
+
+2012-12-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * Version 5.1.0 released.
+
+ * configure.in (none-*-*): Allow this again, but print a warning.
+
+2012-12-17 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/n_pow_ui.c: Fix typos in an ASSERT.
+
+2012-12-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mu_div_qr.c (mpn_preinv_mu_div_qr): Explicitly use
+ MPN_COPY_INCR for slightly overlapping copy.
+
+2012-12-15 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpn/toom-sqr-shared.h: Skip ALLOCs if the test is skipped.
+
+2012-12-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/dos64.m4 (PIC): Move definition early.
+ (JMPENT): Remove PIC variant.
+
+ * mpn/x86_64/darwin.m4 (JUMPTABSECT): Define to .text, instead of
+ something sensible.
+
+2012-12-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/x86_64-defs.m4 (JMPENT): New macro.
+ * mpn/x86_64/dos64.m4: Likewise.
+ * mpn/x86_64/darwin.m4: Likewise.
+ * mpn/x86_64/mod_34lsub1.asm: Use JMPENT to properly support PIC.
+ * mpn/x86_64/mullo_basecase.asm: Likewise.
+ * mpn/x86_64/sqr_basecase.asm: Likewise.
+
+2012-12-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mod_34lsub1.asm: Try different jump table for the benefit
+ of broken Apple linkers.
+
+2012-12-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Make GMP_NONSTD_ABI ABI specific.
+
+2012-12-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*): Bump version info.
+ * gmp-h.in: Bump version.
+
+2012-12-06 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpq/reuse.c: New test (adapted from mpf/reuse.c).
+ * tests/mpq/Makefile.am (check_PROGRAMS): Add reuse.
+
+ * mpz/abs.c: Use NEWALLOC.
+ * mpz/neg.c: Likewise.
+ * mpz/com.c: Reduce branches.
+
+2012-12-05 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/brootinv.c (mpn_brootinv): Make valgrind happier, at
+ the cost of a redundant MPN_ZERO.
+
+ * mpz/jacobi.c (mpz_jacobi): Check for asize == 0 or bsize == 0
+ before using the low limbs.
+
+2012-12-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/set_str.c (mpn_dc_set_str): Work around a valgrind issue.
+
+ * mpz/powm_ui.c: Don't assume >= 2 limbs in mod argument.
+
+ * tests/tests.h (TESTS_REPS): Handle float GMP_CHECK_REPFACTOR.
+
+ * longlong.h: Refine cpp test for vax.
+ * tests/mpn/t-get_d.c: Likewise.
+ * tests/mpz/t-get_d.c: Likewise.
+ * tests/mpz/t-cmp_d.c: Likewise.
+ * tests/mpz/t-get_d.c: Likewise.
+ * tests/mpq/t-get_d.c: Likewise.
+ * tests/mpf/t-get_d.c: Likewise.
+
+2012-11-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * gen-fac.c (gen_consts): Correct printf types.
+
+ * mpn/arm/v7a/cora15/gmp-mparam.h: New file.
+
+ * configure.in (arm*-*-*): New compiler optional "tune". Pass value for
+ selected processors. Add more specific path components.
+
+2012-11-29 Torbjorn Granlund <tege@gmplib.org>
+
+ From Andoni Morales Alastruey:
+ * longlong.h: Conditionalise ARM asm on !__thumb__.
+
+2012-11-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess (arm*-*-*): Support specific ARM processors.
+ * config.sub: Match arm CPUs.
+ * configure.in (arm*-*-*): Likewise.
+
+ * mpz/powm.c: Move new_b out since it lives on through b.
+
+ * configure.in (arm*-*-*): Pass -marm to deal with compilers defaulting
+ to thumb code.
+
+2012-11-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/cxx/t-ops2.cc (checkz): Reduce huge numbers to avoid vax
+ overflow.
+
+2012-11-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/get_d.c: Reinsert non-IEEE code.
+
+ * mpn/vax/add_n.asm: New file.
+ * mpn/vax/add_n.s: Remove.
+ * mpn/vax/addmul_1.asm: New file.
+ * mpn/vax/addmul_1.s: Remove.
+ * mpn/vax/lshift.asm: New file.
+ * mpn/vax/lshift.s: Remove.
+ * mpn/vax/mul_1.asm: New file.
+ * mpn/vax/mul_1.s: Remove.
+ * mpn/vax/rshift.asm: New file.
+ * mpn/vax/rshift.s: Remove.
+ * mpn/vax/sub_n.asm: New file.
+ * mpn/vax/sub_n.s: Remove.
+ * mpn/vax/submul_1.asm: New file.
+ * mpn/vax/submul_1.s: Remove.
+
+ * mpn/vax/elf.m4: New file.
+ * configure.in (vax*-*-*elf*): New case, grabbing vax/elf.m4.
+
+ * tests/mpn/t-get_d.c (check_onebit): Get vax bounds right.
+ (main): Switch off check_rand for vax.
+
+2012-11-22 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/tests/run-tests: Copied latest version from GNU Nettle.
+ Minor fix to the use of $EMULATOR, and proper copyright notice.
+
+2012-11-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm_sec.c (redcify): Use mpn_sb_div_r_sec.
+
+ * mpn/generic/sb_div_sec.c: New file.
+ * mpn/generic/sbpi1_div_sec.c: New file.
+ * configure.in (gmp_mpn_functions): Add new files.
+ * gmp-impl.h: Declare new functions.
+
+2012-11-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * longlong.h: Add ARM64 support.
+ * longlong.h: Add AVR support.
+
+ * mpn/powerpc64/mode64/divrem_1.asm: Tune, simplify.
+
+ * mpq/md_2exp.c: Use MPN_COPY_INCR, not MPN_COPY_DECR.
+ * tests/mpq/t-md_2exp.c (check_random): New function.
+
+2012-11-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/remove.c (mpn_bdiv_qr_wrap): Make static.
+
+2012-11-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/powm_ui.c: Rewrite.
+
+2012-11-01 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/brootinv.c (mpn_brootinv): Input size in limbs
+ rather than bits. Use single-precision iterations for the first
+ limb.
+ * mpn/generic/perfpow.c (is_kth_power): Update mpn_brootinv call.
+ * tests/mpn/t-brootinv.c (main): Likewise.
+ * tune/speed.h (SPEED_ROUTINE_MPN_BROOTINV): Likewise.
+ * gmp-impl.h (mpn_brootinv): Updated prototype.
+
+ * mpn/generic/hgcd2.c (mpn_hgcd2): Removed redundant loop exit
+ tests in the single-precision loop.
+
+ * mpz/combit.c (mpz_combit): Rewrite, optimizing for the common
+ case.
+
+2012-10-31 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-brootinv.
+ * tests/mpn/t-brootinv.c: New file
+
+ * mpn/generic/broot.c (mpn_broot_invm1): Avoid a mullo_n in the
+ loop, and do powering as a plain mpn_sqr followed by mpn_powlo.
+
+ * tune/speed.c (routine): Added mpn_broot, mpn_broot_invm1,
+ mpn_brootinv.
+
+ * tune/common.c (speed_mpn_broot, speed_mpn_broot_invm1)
+ (speed_mpn_brootinv): New functions.
+ * tune/speed.h (SPEED_ROUTINE_MPN_BROOT)
+ (SPEED_ROUTINE_MPN_BROOTINV): New macros.
+
+ * mpn/generic/broot.c (mpn_broot_invm1): Made non-static (mainly
+ for benchmarking).
+ * gmp-impl.h (mpn_broot_invm1): Declare it.
+
+2012-10-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (gmp_mpn_functions): Add new files.
+ * gmp-impl.h: Declare new functions.
+ * mpn/generic/perfpow.c: Overhaul.
+ (binv_root, binv_sqroot): Remove.
+ * mpn/generic/brootinv.c: New file, code from overhauled binv_root.
+ * mpn/generic/bsqrtinv.c: New file, code from overhauled binv_sqroot.
+ * mpn/generic/bsqrt.c: New file.
+
+ * tests/mpn/t-broot.c: Add a forgotten TMP_MARK.
+
+2012-10-28 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/broot.c (mpn_broot): New file and function.
+ * configure.in (gmp_mpn_functions): Add broot.
+ * gmp-impl.h (mpn_broot): Declare.
+ * tests/mpn/t-broot.c: New testcase.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-broot.
+
+2012-10-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/remove.c: Get remainder allocation right.
+
+2012-10-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * longlong.h: De-support old POWER asm syntax.
+
+ * tests/mpz/t-remove.c: Run more tests, but use a tad smaller operands.
+
+ * mpn/generic/remove.c (mpn_bdiv_qr_wrap): New function.
+ (mpn_remove): Call mpn_bdiv_qr_wrap.
+ * mpz/remove.c: Enable suppressed mpn_remove call.
+
+2012-10-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/powm_ui.c (mpz_powm_ui): Deflect to mpz_powm for large exponent.
+
+2012-09-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * demos/factorize.c: Rewrite no more current form. Implement Lucas
+ prime proving, and make its use the default.
+ * demos/primes.h: New file.
+
+2012-08-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * demos/factorize.c: Overhaul.
+
+2012-08-06 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * doc/gmp.texi (mpn_neg): Correctly document returned type.
+
+ * gmp-impl.h (_mpz_newalloc, log_n_max): mark with inline (spotted by Niels).
+
+2012-07-28 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (std::common_type): New partial specializations with builtin
+ types.
+ * tests/cxx/t-cxx11.cc: Test it.
+
+2012-07-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc32/vmx/mod_34lsub1.asm: Fix r0 clobbering issue with
+ "large" code affecting elf+darwin PIC.
+
+2012-07-21 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__GMPXX_CONSTANT): Disable for g++-3.4.
+
+2012-06-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * Makefile.am (LIBMP_LT_*): Remove these.
+
+2012-06-26 Marc Glisse <marc.glisse@inria.fr>
+
+ * Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*): Update comment for 5.1.0.
+
+2012-06-24 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * configure.in (CALLING_CONVENTIONS_OBJS): Disable any use of
+ assembly code with the --disable-assembly option.
+ * mpz/oddfac_1.c: Use the ASSERT_CODE macro.
+ * gen-trialdivtab.c (mpz_log2): Use mpz_sizeinbase (., 2).
+
+ * gmp-impl.h (MPN_SIZEINBASE_16): Replace with MPN_SIZEINBASE_2EXP
+ from mpz/export.c .
+ * mpz/export.c (MPN_SIZEINBASE_2EXP): Removed.
+ * mpn/generic/sizeinbase.c: Use MPN_SIZEINBASE.
+
+ * mpz/nextprime.c: Use MPN_SIZEINBASE_2EXP to count bits.
+ * mpn/generic/perfpow.c: Likewise.
+ * mpn/generic/rootrem.c: Likewise.
+ * mpz/get_d_2exp.c: Likewise.
+ * mpn/generic/powm_sec.c: Likewise, nailify.
+ * mpn/generic/powlo.c: Likewise.
+ * mpn/generic/powm.c: Likewise.
+
+ * mini-gmp/mini-gmp.c (mpz_div_r_2exp, mpz_div_q_2exp): Improve
+ adjustment condition.
+
+2012-06-23 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (numeric_limits): Make content public.
+ * cxx/limits.cc: New file, proper declarations.
+ * Makefile.am: List new file.
+ * cxx/Makefile.am: Likewise.
+ * cxx/t-misc.cc: Add minimal test for numeric_limits.
+
+2012-06-09 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__gmp_resolve_expr::srcptr_type): New typedef.
+ (__gmp_temp): Wrapper for mp*_class, the constructor copies the
+ precision of its second argument for mpf_t.
+ (__gmp_expr::eval(p, prec)): Remove.
+ (__gmp_expr::eval(p)): Use __gmp_temp.
+ (__gmp_set_expr): Never pass prec to eval().
+
+2012-06-08 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h (__GMP_WITHIN_CONFIGURE): Use the same #if as in gmp-h.in.
+ (MPN_NORMALIZE_NOT_ZERO): Tighter ASSERT.
+ (MPZ_NEWALLOC): New macro.
+ * mpq: Use the new macro when possible.
+ * mpz/bin_uiui.c: Likewise.
+ * mpz/oddfac_1.c: Likewise.
+ * mpz/prodlimbs.c: Likewise.
+
+ * mini-gmp/mini-gmp.c (mpz_realloc): remove a branch.
+
+2012-06-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/aix.m4 (ASM_START): Claim machine type "any".
+
+2012-06-03 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext.c (mpn_gcdext): Deleted code for handling
+ impossible case u1 == 0, Simplified test for unlikely case u0 == 0.
+
+2012-06-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/lshiftc.asm: New file.
+
+2012-06-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/aorslsh1_n.asm: Use cmp/cmn instead of subs/adds in more
+ places.
+
+ * mpz/get_str.c: Don't strip leading zeros since current mpn_get_str
+ won't generate any. Misc streamlining.
+ * mpz/out_str.c: Analogous changes.
+
+ * tests/mpz/io.c: Use a wider range of bases.
+
+ * tests/mpz/t-cong.c (check_random): Rewrite random generation for
+ exponentially distributed operand sizes.
+
+2012-06-01 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpq: Use more macros and MPZ_REALLOC return value when possible.
+
+ * gmp-impl.h (LIMBS): Removed, was an alias for PTR.
+ * mpz/combit.c: Use PTR and CNST_LIMB.
+
+ * tests/mpn/t-bdiv.c: Test also mpn_bdiv_qr.
+ * mpn/generic/bdiv_qr.c: Add an ASSERT.
+
+ * mpn/generic/remove.c: Add a zero limb to use bdiv_qr...
+
+2012-05-31 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (mpq_class::mpq_class): Handle mpq_class(0,1).
+ * tests/cxx/t-constr.cc: Test it.
+
+2012-05-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64 (FUNC_ENTRY): New name for DOS64_ENTRY.
+ * mpn/x86_64 (FUNC_EXIT): New name for DOS64_EXIT.
+
+2012-05-29 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/remove.c: Optimise branches.
+
+ * mpn/generic/toom6h_mul.c: less branches in the LIKELY balanced path.
+ * mpn/generic/toom8h_mul.c: Likewise.
+
+2012-05-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v5/mod_1_1.asm: New file.
+
+2012-05-28 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext.c (compute_v): Simplified carry handling a
+ bit, reduced stated scratch need from 2n+1 to 2n. Also comment and
+ ASSERT improvements.
+
+2012-05-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Add new x86 CPUs.
+ * mpn/x86/fat/fat.c: Likewise.
+ * mpn/x86_64/fat/fat.c: Likewise.
+
+2012-05-27 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86_64/fat/fat.c: abort iff longmode-capable-bit is turned off.
+
+ * mpn/generic/toom8h_mul.c: mark UNLIKELY branches.
+
+2012-05-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz: Use MPZ_REALLOC return value when possible.
+
+2012-05-25 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/tests/t-div.c: Test all _qr, _q, _r variants.
+ * mini-gmp/tests/t-lcm.c: Test the _ui variant.
+
+ * mini-gmp/mini-gmp.c (mpz_mod, mpz_mod_ui): New functions.
+ * mini-gmp/mini-gmp.h (mpz_mod, mpz_mod_ui): Prototypes.
+
+ * mpz/scan1.c: Simplify, and add a shortcut for scan1(z, 0).
+
+2012-05-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/n_pow_ui.c: Cast non-limb count_leading_zeros argument.
+
+2012-05-24 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/remove.c: Support negative divisor.
+ * tests/mpz/t-remove.c: Test negative divisor.
+
+2012-05-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/reuse.c: Major rewrite.
+
+2012-05-23 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/sqrt.c: Further simplify.
+ * mpz/sqrtrem.c: Likewise.
+
+ * Mark failing branches with UNLIKELY. Many files affected.
+
+2012-05-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/sqrt.c: Allocate less for overlapping operands, simplify.
+ * mpz/sqrtrem.c: Likewise.
+
+2012-05-21 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom8_sqr.c: Reduce branches for recursion.
+ * mpn/generic/toom8h_mul.c: Likewise.
+
+ * tests/mpn/t-toom8h.c: Don't use GMP_NUMB_BITS when not yet defined.
+
+2012-05-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-gcd.c: Rewrite.
+
+2012-05-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-gcd.c: Generate larger operands for better gcd code
+ coverage; distribute size exponentially.
+
+2012-05-17 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpf/pow_ui.c: Simplify.
+ * tests/mpf/reuse.c (dsi_func): Exercise pow_ui.
+
+ * tests/mpf/t-set_ui.c (check_data): LONG_HIGHBIT -> ULONG_HIGHBIT.
+ * tests/mpf/t-set.c (check_random): New check, both set and init_set.
+
+ * tests/cxx/t-ops.cc (check_mpq): Check squaring.
+ * tests/mpq/t-equal.c (check_various): Check different den-size.
+
+ * mpn/generic/mullo_n.c: Disable MAYBE_ if WANT_FAT_BINARY.
+ * mpz/cmpabs_d.c: Remove an unused branch.
+
+ * tests/mpz/t-get_d_2exp.c (check_zero): New check.
+ * tests/mpz/t-inp_str.c: A few more cases.
+ * tests/mpz/t-cmp_d.c: More bases and symbols, a few cases.
+
+ * mpz/rootrem.c: Correctly handle odd roots of negatives.
+ * tests/mpz/t-root.c: Test it.
+
+2012-05-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpf/t-eq.c (check_random): New function, meat from old main().
+ (check_data): New function.
+
+2012-05-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/rsh1aors_n.asm: New file.
+ * mpn/arm/v5/mod_1_2.asm: New file.
+
+2012-05-11 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (explicit operator bool): New functions.
+ * tests/cxx/t-cxx11.cc: Test the above.
+
+2012-05-10 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h (__gmpn_cpuvec_initialized): Was __gmpn_cpuvec.initialized
+ * mpn/x86/fat/fat.c: Use separated _initialized variable.
+ * mpn/x86_64/fat/fat.c: Likewise.
+ * tests/mpn/t-fat.c: Likewise.
+
+ * mpn/generic/toom2_sqr.c: Override global __gmpn_cpuvec_initialized.
+ * mpn/generic/toom22_mul.c: Likewise.
+ * mpn/generic/toom3_sqr.c: Likewise.
+ * mpn/generic/toom33_mul.c: Likewise.
+
+2012-05-09 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c: merge mpz_rootrem and mpz_sqrtrem.
+
+ * mpn/generic/sqrtrem.c (invsqrttab): Reduce size removing common byte.
+
+ * mpz/bin_uiui.c (mul3, mul4, mul8): Remove unneeded shifts.
+ (MAXFACS): Redefine, using the shared (safer) log_n_max.
+
+2012-05-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/minithres/gmp-mparam.h (REDC_1_TO_REDC_N_THRESHOLD): Up to 9, for
+ coherency with ASSERT in mpn/generic/redc_n.c.
+
+2012-05-07 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/minithres/gmp-mparam.h: Updated TOOM6 and FAC_DSC.
+ * tests/mpn/toom-sqr-shared.h: Don't test if no range.
+
+ * mpz/oddfac_1.c: Add ASSERTs to warn about small threshold.
+ * tune/tuneup.c: Update minimal threshold for FAC_DSC.
+
+2012-05-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v6/sqr_basecase.asm: Simplify n=4 code.
+
+2012-05-05 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/invert.c: Mark a branch UNLIKELY.
+ * tune/tuneup.c (tune_fac_u): Update DSC_THRESHOLD minimum.
+ * gmp-impl.h (FAC_???_THRESHOLD): Update default values.
+ (ABOVE_THRESHOLD): New definition with __builtin_constant_p.
+
+ * mpn/generic/toom22_mul.c: Disable MAYBE_ if WANT_FAT_BINARY.
+ * mpn/generic/toom33_mul.c: Likewise.
+ * mpn/generic/toom2_sqr.c: Likewise.
+ * mpn/generic/toom3_sqr.c: Likewise.
+
+2012-05-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c: Measure POWM_SEC_TABLE after the REDC thresholds.
+
+2012-05-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm_sec.c: Use redc_2.
+ (INNERLOOP): Use this mechanism, like plain powm.c.
+ (WANT_CACHE_SECURITY): Remove, feature now unconditional.
+
+2012-05-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/bin_uiui.c: Make use of CNST_LIMB.
+
+2012-05-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/mfac_uiui.c: Support limb != ui.
+
+2012-05-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/logops_n.asm: Work around register clobbering issue.
+
+ * mpn/arm/aorscnd_n.asm: New file.
+
+2012-05-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Put arm dirs in path in proper prio order.
+
+ * mpn/arm/logops_n.asm: New file.
+
+ * mpz/2fac_ui.c: Fix assumed typo.
+
+ * mpn/arm/v6/gmp-mparam.h: New file.
+
+ * mpn/arm/v5/gcd_1.asm: Hack for undefined BMOD_1_TO_MOD_1_THRESHOLD.
+ * mpn/arm/v6t2/gcd_1.asm: Likewise.
+
+2012-04-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v6/sqr_basecase.asm: New file.
+
+2012-04-30 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/comb_tables.c: New file.
+ * configure.in: Add it.
+ * gen-fac.c: Define table limits.
+ * gmp-impl.h: Declare tables.
+ (log_n_max): New static function.
+ * mpz/2fac_ui.c: Use shared tables.
+ * mpz/bin_uiui.c: Likewise.
+ * mpz/oddfac_1.c: Likewise.
+ * mpz/primorial_ui.c: Likewise.
+
+ * mpz/mfac_uiui.c: New file.
+ * Makefile.am: Compile it.
+ * mpz/Makefile.am (libmpz_la_SOURCES): Add mpz_mfac_uiui.c
+ * gmp-h.in (mpz_mfac_uiui): Declare.
+
+ * tests/mpz/t-mfac_uiui.c: New file.
+ * tests/mpz/Makefile.am: Run it.
+
+ * doc/gmp.texi: Document mpz_mfac_uiui, collapsing with other factorial functions.
+
+ * tests/mpz/t-lcm.c: Test zero too.
+
+ * mpz/prodlimbs.c: Simplify threshold (should be tuned, not guessed).
+
+2012-04-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/aors_n.asm: Tune for more stable performance.
+
+ * mpn/arm/aorslsh1_n.asm: New file.
+
+ * mpn/arm/mod_34lsub1.asm: New file.
+
+ * mpn/arm/v6t2/divrem_1.asm: New file.
+
+2012-04-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/thumb/add_n.asm: New file.
+ * mpn/thumb/sub_n.asm: New file.
+ * mpn/thumb/add_n.s: Remove broken code.
+ * mpn/thumb/sub_n.s: Likewise.
+
+ * mpn/arm/v6/addmul_1.asm: Rewrite for stable speed, smaller size.
+ * mpn/arm/v6/mul_1.asm: Likewise.
+
+2012-04-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Search arm/v6t2 for arm7.
+
+ * mpn/arm/v5/gcd_1.asm: New file.
+ * mpn/arm/v6t2/gcd_1.asm: New file.
+
+ * mpn/arm/mode1o.asm: New file.
+ * mpn/arm/v6t2/mode1o.asm: New file.
+
+ * mpn/arm/arm-defs.m4 (LEA): New define.
+ * mpn/arm/invert_limb.asm: Use LEA.
+
+2012-04-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/bin_uiui.c (bc_bin_uiui): Nail support.
+ * tests/cxx/t-ops2.cc: Test 0/3.
+ * oddfac_1.c: assume n > 26.
+ * tests/mpz/t-jac.c (mpn_jacobi_n): Enlarge tested sizes.
+
+2012-04-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/v6/addmul_2.asm: New file.
+ * mpn/arm/v6/mul_2.asm: New file.
+
+2012-04-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/aorsmul_1.asm: Tweak loop control for a 6% speed increase.
+
+2012-04-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Recognise ARM sub-architectures.
+
+ * configfsf.guess: Update to current FSF version.
+ * configfsf.sub: Likewise.
+
+ * mpn/arm/bdiv_dbm1c.asm: New file.
+
+ * mpn/arm/v6/mul_1.asm: New file.
+ * mpn/arm/v6/addmul_1.asm: New file.
+
+2012-04-22 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gen-fac.c: Renamed, was gen-fac_ui.c .
+ * Makefile.am: Renamed gen-fac.c and fac_table.h .
+ * gmp-impl.h: #include "fac_table.h".
+ * mpz/oddfac_1.c: Use generated constant.
+ * mpz/bin_ui.c: Small optimisations.
+
+ * tune/common.c (speed_mpz_bin_ui): New function.
+ * tune/speed.h: Declare it.
+ * tune/speed.c: Use it.
+
+2012-04-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/mul_1.asm: Cleanup.
+ * mpn/arm/copyi.asm: Cleanup, assume allocate-on-write cache.
+ * mpn/arm/copyd.asm: Likewise.
+
+ * mpn/arm/add_n.asm: Delete.
+ * mpn/arm/sub_n.asm: Delete.
+ * mpn/arm/aors_n.asm: New file, made from old files.
+
+ * mpn/arm/addmul_1.asm: Delete.
+ * mpn/arm/submul_1.asm: Delete.
+ * mpn/arm/aorsmul_1.asm: New file, made from old files.
+
+ * mpn/arm/com.asm: New file.
+ * mpn/arm/lshift.asm: New file.
+ * mpn/arm/rshift.asm: New file.
+
+2012-04-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpq/io.c: New file.
+ * tests/mpq/Makefile.am: Run it.
+
+ * mpz/clrbit.c: Simplify along the lines of setbit.c.
+
+2012-04-20 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/setbit.c: Simplify.
+
+ * gmp-impl.h (LOG2C): Define.
+ * mpz/fac_ui.c (LOG2C): Remove.
+ * mpz/2fac_ui.c (LOG2C): Remove.
+ * mpz/oddfac_1.c (LOG2C): Remove.
+ * mpn/generic/binvert.c (LOG2C): Remove.
+ * mpn/generic/invertappr.c (LOG2C): Remove.
+
+ * mpz/bin_uiui.c (mpz_goetgheluck_bin_uiui): Move declarations,
+ and assume that n and k are not small.
+
+2012-04-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add t-remove.
+
+ * tests/mpz/t-remove.c: Clear out mpz variables.
+
+ * tests/mpz/t-cong.c (check_random): Use much larger numbers.
+ (check_data): Check congruences mod 0.
+
+ * tests/mpz/t-divis.c: Test divisibility by zero.
+
+ * tests/mpz/reuse.c: Test mpz_mod.
+
+ * mpz/setbit.c: Remove dead code. Use CNST_LIMB.
+ * mpz/clrbit.c: Use CNST_LIMB.
+
+2012-04-19 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * primesieve.c: New file, with functions from mpz/oddfac_1.c .
+ * mpz/oddfac_1.c (bitwise_primesieve): Re-moved.
+ * Makefile.am (libgmp_la_SOURCES): Add primesieve.c .
+ * gmp-impl.h (gmp_primesieve): Declare.
+
+ * mpz/bin_uiui.c (mpz_goetgheluck_bin_uiui): New, factor-based
+ implementation.
+ * tests/mpz/t-bin.c: Extend tests, to cover _goetgheluck.
+
+ * mpz/primorial_ui.c: New file.
+ * mpz/Makefile.am (libmpz_la_SOURCES): Add mpz/primorial_ui.c
+ * Makefile.am (MPZ_OBJECTS): Add mpz/primorial_ui$U.lo
+ * gmp-h.in (mpz_primorial_ui): Declare.
+ * tests/mpz/t-primorial_ui.c: New test for the new function.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add t-primorial_ui.
+ * doc/gmp.texi: Short documentation for the new function.
+
+2012-04-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/aorsmul_1.asm: Fix some DOS64 issues.
+ * mpn/x86_64/coreisbr/mul_1.asm: Likewise.
+
+ * mpn/x86_64/fastsse/lshiftc-movdqu2.asm: Adhere to DOS64 register
+ partitioning rules.
+
+ * mpn/x86_64/fastsse/copyi-palignr.asm: Implement temporary workaround
+ to overlap issue.
+
+2012-04-17 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/bin_uiui.c: Support small limbs (fallback on bin_ui).
+
+ * tests/mpn/toom-sqr-shared.h: Use a restricted range.
+ * tests/mpn/t-toom2-sqr.c: Specify correct range.
+ * tests/mpn/t-toom3-sqr.c: Likewise.
+ * tests/mpn/t-toom4-sqr.c: Likewise.
+ * tests/mpn/t-toom6-sqr.c: Likewise.
+ * tests/mpn/t-toom8-sqr.c: Likewise, but extended.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add t-toom?-sqr tests.
+
+ * mpn/generic/sbpi1_bdiv_q.c: Move ASSERTs, to support qp = np.
+
+2012-04-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/copyd.asm: Rewrite.
+ * mpn/x86_64/copyi.asm: Rewrite.
+
+2012-04-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fastsse/lshift-movdqu2.asm: Add DOS entry/exit sequences.
+ * mpn/x86_64/fastsse/rshift-movdqu2.asm: Likewise.
+ * mpn/x86_64/fastsse/lshiftc-movdqu2.asm: Likewise.
+
+ * mpn/x86_64/x86_64-defs.m4 (palignr): New macro.
+ (x86_opcode_regxmm, x86_opcode_regxmm_list): New, made from x86 mmx
+ counterparts.
+ (x86_lookup): Copy from x86/x86-defs.m4.
+ * mpn/x86_64/fastsse/copyd-palignr.asm: Use palignr macro.
+ * mpn/x86_64/fastsse/copyi-palignr.asm: Likewise.
+
+2012-04-15 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpz/t-bin.c: Add more tests on small values.
+ * mpz/bin_uiui.c (mpz_bdiv_bin_uiui): Smaller temporary areas.
+
+2012-04-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fastsse/copyd-palignr.asm: New file.
+ * mpn/x86_64/fastsse/copyi-palignr.asm: New file.
+ * mpn/x86_64/core2/copyd.asm: New file.
+ * mpn/x86_64/core2/copyi.asm: New file.
+ * mpn/x86_64/nano/copyd.asm: New file.
+ * mpn/x86_64/nano/copyi.asm: New file.
+ * mpn/x86_64/atom/copyd.asm: New file.
+ * mpn/x86_64/atom/copyi.asm: New file.
+
+2012-04-13 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/bin_uiui.c: Rewrite (some parts are Torbjorn's).
+ * gen-fac_ui.c: Generate new constants for bin_uiui.
+
+ * mini-gmp/mini-gmp.h (mpz_fac_ui, mpz_bin_uiui): New definitions.
+ * mini-gmp/mini-gmp.c (mpz_fac_ui, mpz_bin_uiui): Trivial
+ implementation.
+
+ * tests/mpz/t-fac_ui.c: Check Wilson's theorem on a big value.
+
+ * mpn/generic/invert.c: Remove support for scratch == NULL.
+ * tune/speed.h (SPEED_ROUTINE_MPN_MUPI_DIV_QR): Allocate scratch
+ space for mpn_invert.
+
+ * mpz/mul_i.h: Small clean-up.
+
+ * tests/mpn/toom-sqr-shared.h: New file.
+ * tests/mpn/t-toom2-sqr.c: New file.
+ * tests/mpn/t-toom3-sqr.c: New file.
+ * tests/mpn/t-toom4-sqr.c: New file.
+ * tests/mpn/t-toom6-sqr.c: New file.
+ * tests/mpn/t-toom8-sqr.c: New file.
+ * tests/mpn/Makefile.am (EXTRA_DIST): Add toom-sqr-shared.h .
+
+ * mpn/generic/toom62_mul.c: Use add_n, sub_n, when possible.
+
+2012-04-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fastsse/lshift-movdqu2.asm: New file.
+ * mpn/x86_64/fastsse/rshift-movdqu2.asm: New file.
+ * mpn/x86_64/fastsse/lshiftc-movdqu2.asm: New file.
+ * mpn/x86_64/coreisbr/lshift.asm: New file.
+ * mpn/x86_64/coreisbr/rshift.asm: New file.
+ * mpn/x86_64/coreisbr/lshiftc.asm: New file.
+ * mpn/x86_64/k10/lshift.asm: New file.
+ * mpn/x86_64/k10/rshift.asm: New file.
+ * mpn/x86_64/k10/lshiftc.asm: New file.
+
+ * mpn/x86_64/fastsse/lshift.asm: Simplify to very basic form.
+
+2012-04-11 Niels Möller <nisse@lysator.liu.se>
+
+ * Makefile.am (check-mini-gmp): Pass -I../.. in EXTRA_CFLAGS, to
+ locate gmp.h.
+
+2012-04-11 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.h (mpz_root, mpz_rootrem): define (correctly).
+ * mini-gmp/mini-gmp.c (mpz_rootrem): Extended code from _root.
+ (mpz_root): Use mpz_rootrem.
+ (mpz_mul_ui): Correctly handle negative operands.
+
+ * mini-gmp/tests/Makefile (CHECK_PROGRAMS): add t-root.
+ * mini-gmp/tests/t-root.c: New file.
+ * mini-gmp/tests/t-reuse.c: Enable root{,rem} tests.
+
+2012-04-10 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gen-fac_ui.c (mpz_root): Remove.
+ * mini-gmp/mini-gmp.c (mpz_root): New, support negative operands.
+ * mini-gmp/mini-gmp.h (mpz_root): define.
+ (mpz_out_str): Test also __STDIO_LOADED (for VMS).
+ * mpz/2fac_ui.c: Cosmetic change.
+
+2012-04-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/ia64/gcd_1.asm: Rewrite inner loop to use ctz table.
+
+2012-04-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/p7/popcount.asm: Properly extend arg n for mode32.
+ * mpn/powerpc64/p7/hamdist.asm: Likewise.
+
+2012-04-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/p7/popcount.asm: New file.
+ * mpn/powerpc64/p7/hamdist.asm: New file.
+
+ * longlong.h (ARM count_leading_zeros): Enable for more arch versions.
+
+ * mpn/x86_64/gcd_1.asm: Make room for DOS64 regparm shadow area.
+ * mpn/x86_64/core2/gcd_1.asm: Likewise.
+
+2012-04-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/aorrlsh_n.asm: Make it actually work for DOS64.
+
+2012-04-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/oddfac_1.c: Initialize size for ASSERT.
+
+2012-04-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (_GMP_H_HAVE_FILE): Test also __STDIO_LOADED (for VMS).
+
+ * gmp-impl.h (doprnt_format_t, etc): Remove bogus __GMP_DECLSPECs.
+
+2012-03-30 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86_64/sqr_basecase.asm: Speed-up for small cases.
+
+2012-03-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/gcd_1.asm: New file.
+
+2012-03-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Fix typo in coreisbr recognition.
+
+2012-03-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86_64/gcd_1.asm: Reduce latency.
+ * mpn/x86_64/mul_basecase.asm: Save one jump.
+
+ * mpz/iset_ui.c: Don't realloc.
+
+2012-03-20 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mp_clz_tab.c: Add __clz_tab[128].
+ * longlong.h (count_trailing_zeros): Use it in pure C variant.
+
+2012-03-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (x86 fat_path): Add many missing directories.
+ * mpn/x86/fat/fat.c (__gmpn_cpuvec_init): Rewrite.
+ (fake_cpuid_table): Add many more CPUs.
+
+ * mpn/x86_64/fat/fat.c (__gmpn_cpuvec_init): Minor spacing cleanup.
+
+2012-03-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/x86-defs.m4 (CALL, PIC_WITH_EBX): New macros.
+ * mpn/x86/darwin.m4: Likewise.
+ * mpn/x86/k7/gcd_1.asm: Use new macros to support PIC.
+ * mpn/x86/p6/gcd_1.asm: Likewise.
+
+2012-03-19 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gen-fac_ui.c: Generate more constants (possible mini-mpz_root).
+ * mpz/oddfac_1.c: Improve ASSERTs.
+ (log_n_max): Use precomputed table.
+
+ * longlong.h (_PROTO): Remove.
+
+2012-03-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * longlong.h (count_trailing_zeros): Write better pure C default
+ variant.
+
+ * mpn/x86/p6/gcd_1.asm: Remove forgotten x86_64 reference.
+
+ * mpn/x86/p6/gmp-mparam.h: Update, to get BMOD_1_TO_MOD_1_THRESHOLD
+ defined for fat binaries.
+
+2012-03-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/gcd_1.asm: Rewrite.
+ * mpn/x86/p6/gcd_1.asm: New file.
+
+ * mpn/x86_64/core2/gcd_1.asm: Conditionally suppress reduction calls.
+ * mpn/x86_64/gcd_1.asm: Rewrite.
+
+2012-03-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/gcd_1.c: Parameterise zerotab code.
+
+ * mpn/x86_64/nano/gcd_1.asm: New file, grabbing core2 asm file.
+
+ * mpn/x86_64/core2/gcd_1.asm: Speed up loop code, simplify non-loop
+ code.
+
+2012-03-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/core2/gcd_1.asm: Add hack to support fat builds.
+
+ * mpn/x86_64/core2/gcd_1.asm: Shorten critical path.
+
+2012-03-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/core2/gcd_1.asm: New file.
+ * mpn/x86_64/k10/gcd_1.asm: New file, grabbing core2 asm file.
+ * mpn/x86_64/bd1/gcd_1.asm: Likewise.
+
+ * mpn/x86_64/bobcat/sqr_basecase.asm: New file.
+ * mpn/x86_64/bobcat/mul_basecase.asm: Minor tuning.
+
+2012-03-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (fat_functions): Add addlsh1_n, addlsh2_n, addmul_2,
+ mullo_basecase, redc_1, redc_2, sublsh1_n.
+
+ * gmp-impl.h (struct cpuvec_t): Add fields for new fat functions.
+ * gmp-impl.h: Adjust corresponding declarations.
+
+ * mpn/generic/redc_2.c (mpn_addmul_2): Make static.
+
+ * mpn/x86_64/fat/fat_entry.asm (FAT_INIT): Expand before fat_init to
+ reduce branch offsets. Pass plain 0,1,3... in %al since we'd else run
+ out of 8-bit range.
+
+ * mpn/x86_64/fat/fat_entry.asm (fat_init): Scale passed index value.
+ * mpn/x86/fat/fat_entry.asm (fat_init): Use movzbl for expanding index
+ value.
+
+ * mpn/x86_64/x86_64-defs.m4 (CPUVEC_FUNCS_LIST): Add new fat functions.
+ * mpn/x86/x86-defs.m4 (CPUVEC_FUNCS_LIST): Likewise.
+ * mpn/x86_64/fat/fat.c (__gmpn_cpuvec): Likewise.
+ * mpn/x86/fat/fat.c (__gmpn_cpuvec): Likewise.
+
+ * mpn/x86_64/fat/redc_2.c: New file.
+ * mpn/x86/fat/mullo_basecase.c: New file.
+ * mpn/x86/fat/redc_1.c: New file.
+ * mpn/x86/fat/redc_2.c: New file.
+
+ * tests/mpn/t-fat.c: Test mullo_basecase.
+
+2012-03-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/addmul_2.asm: Port to DOS64.
+
+2012-02-29 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h: Ignore partial C++11 support in g++-4.6.
+ * tests/cxx/t-cxx11.cc: Likewise.
+
+ * gmpxx.h (operator""): New functions.
+ * tests/cxx/t-cxx11.cc: Test the above.
+ * doc/gmp.texi: Document the above.
+
+2012-03-08 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * acinclude.m4 (GMP_H_ANSI): Remove.
+ * configure.in: Don't use GMP_H_ANSI.
+ * gmp-h.in (__GMP_HAVE_PROTOTYPES): Remove.
+
+2012-03-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat.c (fake_cpuid_table): Recognise "bulldozer".
+ (__gmpn_cpuvec_init): Overhaul to match configure.in.
+
+ * configure.in: Adjust bulldozer path_64.
+
+2012-03-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (x86_64 fat_path): List recently added AMD directories.
+
+ * mpn/x86_64/bobcat/copyi.asm: New file.
+ * mpn/x86_64/bobcat/copyd.asm: New file.
+
+ * config.guess: Handle AMD 11h correctly.
+
+ * tune/tuneup.c (tune_redc): Better handle situation where redc_2 is
+ never faster.
+
+2012-03-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bobcat/mul_basecase.asm: New file.
+
+2012-03-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bobcat/mul_1.asm: New file.
+ * mpn/x86_64/bobcat/aorsmul_1.asm: New file.
+
+2012-03-04 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/invert.c: Remove mod 0 branch.
+ * tests/mpz/t-invert.c: Avoid testing mod 0.
+ * doc/gmp.texi (mpz_invert): Specify mod 0 is not handled.
+
+ * gmp-h.in (__gmp_signed, __gmp_const): Remove.
+ (__GMP_HAVE_TOKEN_PASTE, __GMP_HAVE_CONST): Remove.
+ * gmp-impl.h: Strip __GMP_HAVE_TOKEN_PASTE and __GMP_HAVE_CONST.
+ * demos/expr/: Strip __gmp_const usage from all files.
+
+ * tests/mpz/t-powm.c (allsizes_seen): Require unsigned*.
+
+2012-03-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/k8/gmp-mparam.h: New file.
+ * mpn/x86_64/k10/gmp-mparam.h: New file.
+
+ * mpn/generic/hgcd_step.c (mpn_hgcd_step): Remove unused variables.
+ * mpn/generic/hgcd_jacobi.c (hgcd_jacobi_step): Likewise.
+ * mpn/generic/hgcd_reduce.c (hgcd_matrix_apply): Likewise.
+ * mpn/generic/mu_bdiv_qr.c: Likewise.
+ * mpz/jacobi.c: Likewise.
+ * mpz/mod.c: Likewise.
+
+ * mpn/generic/toom42_mul.c: Remove unread variable.
+ * mpn/generic/set_str.c (mpn_set_str_compute_powtab): Likewise.
+ * mpn/generic/rootrem.c (mpn_rootrem_internal): Likewise.
+ * tests/refmpn.c (refmpn_mul): Likewise.
+ * mpn/generic/hgcd_appr.c (mpn_hgcd_appr): Propagate mask computation
+ into ASSERT, remove variable.
+
+ * gmp-h.in (__GMP_PROTO): Remove.
+ * Strip __GMP_PROTO usage from all files.
+ * Strip prototype parameter names from all files.
+
+2012-03-01 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * doc/gmp.texi (mpz_invert): Correctly document result range.
+ * tests/mpz/t-invert.c: Small range correction.
+
+2012-03-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mullo_basecase.asm: New file.
+
+2012-02-29 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (std::numeric_limits): New partial specialization.
+
+2012-02-29 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp/tests/t-reuse.c: New test case, based on
+ tests/mpz/reuse.c.
+
+ * mini-gmp/mini-gmp.c (mpz_cdiv_r_ui): New function.
+ (mpz_fdiv_r_ui): New function.
+ (mpz_tdiv_r_ui): New function.
+ (mpz_powm_ui): New function.
+ (mpz_pow_ui): New function.
+ (mpz_ui_pow_ui): Use mpz_pow_ui.
+ (mpz_gcdext): Fixed input/output overlap, for the case of one
+ input being zero.
+ (mpz_sqrtrem): Fix for the case r NULL, U zero.
+
+ * Makefile.am (check-mini-gmp): Use $(MAKE).
+ (clean-mini-gmp): New target.
+ (clean-local, distclean-local): New automake targets. Depend on
+ clean-mini-gmp.
+
+2012-02-28 Niels Möller <nisse@lysator.liu.se>
+
+ * Makefile.am (check-mini-gmp): New target, for running the
+ mini-gmp testsuite.
+
+ * mini-gmp/tests/Makefile (srcdir, MINI_GMP_DIR): New make
+ variables. These can be overridden when using a separate build
+ directory.
+ (EXTRA_CFLAGS): Renamed, was OPTFLAGS.
+
+ * mini-gmp/mini-gmp.c (mpz_abs_add): Don't cache limb pointers
+ over MPZ_REALLOC, since that breaks in-place operation. Bug
+ spotted by Torbjörn.
+ (mpz_and, mpz_ior, mpz_xor): Likewise.
+ (mpz_cmp): Fixed comparison of negative numbers.
+
+2012-02-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fastsse/lshiftc.asm: New file.
+ * mpn/x86_64/fastsse/com.asm: New file.
+
+ * mpn/x86_64/bd1/popcount.asm: New file.
+ * mpn/x86_64/bd1/hamdist.asm: New file.
+
+ * mpn/x86_64/fastsse/copyi.asm: New file.
+ * mpn/x86_64/fastsse/copyd.asm: New file.
+ * mpn/x86_64/fastsse/lshift.asm: New file.
+
+2012-02-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/addmul_2.asm: New file.
+
+ * tests/devel/try.c (param_init): Don't require addmul_N to handle
+ overlap.
+
+ * mpn/x86_64/bd1/mul_1.asm: New file.
+ * mpn/x86_64/bd1/aorsmul_1.asm: New file.
+
+2012-02-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/2fac_ui.c: New file: implements n!!.
+ * Makefile.am (MPZ_OBJECTS): Add mpz/2fac_ui.
+ * gmp-h.in: Declare mpz_2fac_ui.
+ * tests/mpz/t-fac.c: Test mpz_2fac_ui.
+ * doc/gmp.texi: Document mpz_2fac_ui.
+ * mpz/Makefile.am (libmpz_la_SOURCES): Add 2fac_ui.c.
+
+ * mpz/oddfac_1.c (mpz_oddfac_1): Use umul_ppmm when size = 2.
+
+2012-02-26 Niels Möller <nisse@lysator.liu.se>
+
+ * mini-gmp: New subdirectory. For use by GMP bootstrap, and as a
+ fallback for applications needing bignums but not high
+ performance.
+
+ * bootstrap.c: New file, replacing dumbmp.c. Uses mini-gmp for the
+ standard GMP functions, and then defines the few functions
+ particular for the bootstrap.
+ * dumbmp.c: Deleted file. A few functions moved to bootstrap.c.
+
+ * gen-bases.c: Include bootstrap.c, not dumbmp.c.
+ * gen-fac_ui.c: Likewise.
+ * gen-trialdivtab.c: Likewise.
+ * gen-fib.c: Include bootstrap.c, not dumbmp.c. Use assert rather
+ than ASSERT. Deleted casts of xmalloc return value.
+ * gen-psqr.c: Likewise.
+ (COLLAPSE_ELEMENT): Use memmove rather than mem_copyi.
+
+ * Makefile.am: Replaced all uses of dumbmp.c by bootstrap.c.
+ (EXTRA_DIST, dist-hook): Arrange for distribution of the mini-gmp
+ files.
+
+2012-02-24 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/invert.c: Use ABSIZ, MPZ_EQUAL_1_P.
+ * mpz/abs.c: Collapse MPZ_REALLOC(x,.) and PTR(x).
+ * mpz/aors_ui.h: Likewise.
+ * mpz/com.c: Likewise.
+ * mpz/neg.c: Likewise.
+
+ * mpz/invert.c: Reply "no-inverse" when modulus is zero.
+ * tests/mpz/t-invert.c: Add more checks.
+ * doc/gmp.texi (mpz_invert): Inverse can not be zero.
+
+2012-02-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/logic.c: New file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add logic.
+
+ * tests/mpz/t-invert.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add t-invert.
+
+2012-02-24 Marc Glisse <marc.glisse@inria.fr>
+
+ * tests/mpq/t-cmp.c: Move NUM and DEN macros...
+ * tests/mpq/t-cmp_ui.c: Likewise...
+ * gmp-impl.h: ... to here.
+
+ * mpq/abs.c: Use NUM, DEN, SIZ, ALLOC, PTR, MPZ_REALLOC.
+ * mpq/aors.c: Likewise.
+ * mpq/canonicalize.c: Likewise.
+ * mpq/clear.c: Likewise.
+ * mpq/cmp.c: Likewise.
+ * mpq/cmp_si.c: Likewise.
+ * mpq/cmp_ui.c: Likewise.
+ * mpq/div.c: Likewise.
+ * mpq/equal.c: Likewise.
+ * mpq/get_d.c: Likewise.
+ * mpq/get_den.c: Likewise.
+ * mpq/get_num.c: Likewise.
+ * mpq/get_str.c: Likewise.
+ * mpq/init.c: Likewise.
+ * mpq/inp_str.c: Likewise.
+ * mpq/inv.c: Likewise.
+ * mpq/md_2exp.c: Likewise.
+ * mpq/mul.c: Likewise.
+ * mpq/neg.c: Likewise.
+ * mpq/set.c: Likewise.
+ * mpq/set_d.c: Likewise.
+ * mpq/set_den.c: Likewise.
+ * mpq/set_f.c: Likewise.
+ * mpq/set_num.c: Likewise.
+ * mpq/set_si.c: Likewise.
+ * mpq/set_str.c: Likewise.
+ * mpq/set_ui.c: Likewise.
+ * mpq/set_z.c: Likewise.
+ * mpq/swap.c: Likewise.
+
+ * tests/mpq/t-inv.c: New test file.
+ * tests/mpq/Makefile.am: Add the above.
+
+ * gmpxx.h (__gmp_set_expr): Use mpq_set_z.
+
+ * mpq/md_2exp.c: Collapse MPZ_REALLOC(x,.) and PTR(x).
+ * mpq/set_d.c: Likewise.
+ * mpq/set_f.c: Likewise.
+
+2012-02-24 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/core2/aorsmul_1.asm: Added mpn_addmul_1c and
+ mpn_submul_1c entry points.
+
+2012-02-23 Marc Glisse <marc.glisse@inria.fr>
+
+ * mpz/abs.c: Use ALLOC, SIZ, ABSIZ, PTR, MPZ_REALLOC.
+ * mpz/aors_ui.h: Likewise.
+ * mpz/array_init.c: Likewise.
+ * mpz/cdiv_q.c: Likewise.
+ * mpz/cdiv_qr.c: Likewise.
+ * mpz/cdiv_r.c: Likewise.
+ * mpz/clear.c: Likewise.
+ * mpz/clrbit.c: Likewise.
+ * mpz/cmp_si.c: Likewise.
+ * mpz/com.c: Likewise.
+ * mpz/fdiv_q.c: Likewise.
+ * mpz/fdiv_qr.c: Likewise.
+ * mpz/fdiv_r.c: Likewise.
+ * mpz/get_si.c: Likewise.
+ * mpz/get_str.c: Likewise.
+ * mpz/init.c: Likewise.
+ * mpz/inp_str.c: Likewise.
+ * mpz/iset.c: Likewise.
+ * mpz/iset_d.c: Likewise.
+ * mpz/iset_si.c: Likewise.
+ * mpz/iset_str.c: Likewise.
+ * mpz/iset_ui.c: Likewise.
+ * mpz/mod.c: Likewise.
+ * mpz/neg.c: Likewise.
+ * mpz/out_str.c: Likewise.
+ * mpz/random2.c: Likewise.
+ * mpz/set_si.c: Likewise.
+ * mpz/set_str.c: Likewise.
+ * mpz/set_ui.c: Likewise.
+ * mpz/setbit.c: Likewise.
+ * mpz/sqrt.c: Likewise.
+ * mpz/swap.c: Likewise.
+ * mpz/tdiv_r_2exp.c: Likewise.
+
+ * tests/cxx/t-ops.cc: Test mpz_abs reallocation.
+
+2012-02-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/core2/rsh1aors_n.asm: Complete rewrite.
+ * mpn/x86_64/coreisbr/rsh1aors_n.asm: Move old core2 code here.
+
+ * mpn/x86_64/redc_1.asm: Make it work for DOS64 (broken in last edit).
+
+2012-02-20 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom_interpolate_8pts.c: Compute carry iif non-trivial.
+
+ * mpz/gcdext.c: Adapt to relaxed mpn_gcdext's input requirements.
+
+ * mpz/and.c: Use mpn_ logic everywhere. Reduce branches.
+ * mpz/ior.c: Likewise.
+ * mpz/xor.c: Likewise.
+
+2012-02-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreisbr/mul_1.asm: New file.
+
+ * mpn/x86_64/coreisbr/aorsmul_1.asm: New file.
+
+ * mpn/x86_64/mod_34lsub1.asm: Avoid ",pt" branch hint since many
+ assemblers don't support it.
+
+2012-02-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/redc_1.c: Put back mpn_add_n call, return its carry.
+ Reintroduce previously removed RP argument.
+ * mpn/x86_64/redc_1.asm: Likewise.
+
+ * mpn/generic/redc_2.c: Remove mpn_sub_n call, return carry from
+ mpn_add_n call.
+
+ * gmp-impl.h (mpn_redc_1, mpn_redc_2): Now return an mp_limb_t.
+
+ * tune/speed.h (SPEED_ROUTINE_REDC_1): Adopt to pass RP argument.
+
+ * tests/refmpn.c (refmpn_redc_1): Adopt to new redc_1 interface.
+
+ * mpn/generic/powm.c (MPN_REDC_1): Pass rp parameter to mpn_redc_1.
+ * mpn/generic/powm_sec.c (MPN_REDC_1_SEC): Likewise.
+ * mpn/generic/powm.c (MPN_REDC_2): New macro, use for mpn_redc_2.
+
+2012-02-18 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (std::common_type): New partial specialization in C++11.
+ * tests/cxx/t-cxx11.cc: Test it.
+
+ * gmpxx.h: Don't declare long double functions that are never defined.
+
+ * gmpxx.h (__gmp_binary_expr): Let things happen in place: q=q*q+z*z
+ becomes tmp=z*z, q=q*q, q+=tmp.
+ * tests/cxx/t-binary.cc: More variable reuse tests.
+
+2012-02-17 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmp-h.in (__GMP_WITHIN_GMP): Test with #ifdef instead of #if, for
+ the benefit of applications using gcc -Wundef.
+ (__GMP_WITHIN_GMPXX): Likewise.
+
+2012-02-16 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__gmp_binary_expr): Let things happen in place: e=a*b-c*d
+ becomes tmp=c*d, e=a*b, e-=tmp.
+ * tests/cxx/t-binary.cc: More variable reuse tests.
+
+2012-02-15 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tuneup.c (mul_toom43_to_toom54_threshold): New global.
+ (tune_mul): Added tuning of MUL_TOOM43_TO_TOOM54_THRESHOLD.
+ * tune/speed.h (SPEED_ROUTINE_MPN_TOOM43_FOR_TOOM54_MUL): New macro.
+ (SPEED_ROUTINE_MPN_TOOM54_FOR_TOOM43_MUL): New macro.
+ Prototypes for corresponding functions.
+ * tune/common.c (speed_mpn_toom43_for_toom54_mul): New function.
+ (speed_mpn_toom54_for_toom43_mul): New function.
+
+ * gmp-impl.h (MPN_TOOM43_MUL_MINSIZE): Corrected constant.
+ (MPN_TOOM53_MUL_MINSIZE): Likewise.
+ (MPN_TOOM54_MUL_MINSIZE): New constant.
+ (mpn_toom54_mul): Added prototype.
+ (MUL_TOOM43_TO_TOOM54_THRESHOLD): New threshold. Default value and
+ tuning setup.
+
+2012-02-14 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/toom54_mul.c: New file, originally contributed by
+ Marco.
+ * gmp-impl.h (mpn_toom54_mul_itch): New function.
+ * configure.in (gmp_mpn_functions): Added toom54_mul.
+ * tests/mpn/t-toom54.c: New file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-toom54.
+
+2012-02-13 Niels Möller <nisse@lysator.liu.se>
+
+ * configure.in: Display summary of options.
+
+2012-02-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/tests.h (TESTS_REPS): Print any non-standard repetitions.
+
+2012-02-11 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * doc/gmp.texi (Factorial): Shortly describe current algorithm.
+ (Multiplication Algorithms): Add Toom[68]'n'half, (too) shortly.
+ * gmp-impl.h (ASSERT_ALWAYS): Consider failures UNLIKELY.
+
+2012-02-10 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-gcd.c (gcdext_valid_p): Enforce slightly stricter
+ bound for cofactors.
+
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_hook): Corrected
+ handling of unlikely (maybe impossible?) case u1n < un. Related to
+ the 2012-02-05 bugfix of gcdext_subdiv_step.c in the gmp-5.0 repo.
+
+2012-02-09 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h (mpn_toom3*_itch): Support any recursion depth.
+ * tests/refmpn.c (refmpn_mul): Restore tight allocations.
+
+ * mpz/oddfac_1.c (mpz_oddfac_1): Get ready for n!!
+ * gmp-impl.h (mpz_oddfac_1): Update signature.
+ * mpz/fac_ui.c (mpz_fac_ui): Update call to mpz_oddfac_1.
+
+2012-02-09 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmp-impl.h (ABS_CAST): New macro.
+ * mpf/cmp_si.c: Use ABS_CAST.
+ * mpf/get_si.c: Use ABS_CAST.
+ * mpf/iset_si.c: Use ABS_CAST.
+ * mpf/set_si.c: Use ABS_CAST.
+ * mpq/set_si.c: Use ABS_CAST.
+ * mpz/cmp_si.c: Use ABS_CAST.
+ * mpz/get_si.c: Use ABS_CAST.
+ * mpz/iset_si.c: Use ABS_CAST.
+ * mpz/mul_i.h: Use ABS_CAST.
+ * mpz/set_si.c: Use ABS_CAST.
+
+2012-02-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc32/divrem_2.asm: Fix off-by-one condition in invert_limb
+ code.
+
+2012-02-08 Niels Möller <nisse@lysator.liu.se>
+
+ * doc/gmp.texi (mpz_gcdext): Clarified corner cases in cofactor
+ canonicalization.
+
+2012-02-07 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext.c (mpn_gcdext): Fixed assert, related to the
+ special case A = (2k+1) G, B = 2 G. Fix copied from gmp-5.0 repo.
+
+2012-02-06 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd_matrix.c (hgcd_matrix_update_q): Fixed carry
+ handling bug. Fix copied from gmp-5.0 repo, where the function is
+ found in hgcd.c.
+
+ * tests/mpz/t-gcd.c (main): Use mpz_rrandomb for test operands,
+ not mpz_urandomb. Change copied from gmp-5.0 repo.
+ * tests/mpn/t-hgcd.c (main): Likewise.
+
+2012-02-04 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/refmpn.c (refmpn_mul): More conservative allocations.
+
+2012-02-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bd1/gmp-mparam.h: New file.
+
+ * longlong.h (udiv_qrnnd from sdiv_qrnnd): Declare udiv_w_sdiv.
+
+ * mpn/generic/udiv_w_sdiv.c: Use c89 function header.
+
+2012-02-03 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/fac_ui.c: mpz_oddfac_1 removed, with many related functions.
+ * mpz/oddfac_1.c: New file, mpz_oddfac_1 implementation.
+ * gmp-impl.h: mpz_oddfac_1 declaration.
+ * Makefile.am (MPZ_OBJECTS): add mpz/oddfac_1$U.lo .
+ * mpz/Makefile.am (libmpz_la_SOURCES): add oddfac_1.c .
+ * tune/Makefile.am (fac_ui.c): include mpz/oddfac_1.c .
+
+2012-02-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom_interpolate_16pts.c: Correct an unlikely 32-bit bug.
+
+2012-02-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom63_mul.c: Allow s+t==n by adjusting an ASSERT.
+ * mpn/generic/toom_interpolate_8pts.c: Perform final incr iff s+t!=n.
+
+ * tests/mpn/t-toom6h.c (MIN_BN): Make more consistent with ASSERT in
+ tested function.
+
+2012-02-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/t-mul.c: New file.
+ * tests/mpn/Makefile.am: Compile it.
+
+2012-02-01 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h: Remove check for g++ older than 2.91.
+
+2012-02-01 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/mul.c: Added diagram on where toom functions can be
+ called.
+
+2012-02-01 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__gmp_unary_expr): Make the constructor explicit.
+ (__gmp_expr(__gmp_expr&&)): New move constructors.
+ (__gmp_expr::operator=(__gmp_expr&&)): New move assignments.
+ (swap): Mark as noexcept.
+ (__GMPXX_USE_CXX11): New macro.
+ (__GMPXX_NOEXCEPT): New macro.
+ * tests/cxx/t-cxx11.cc: New file.
+ * tests/cxx/Makefile.am: Added t-cxx11.
+
+2012-01-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm_sec.c (SQR_BASECASE_LIM): New name for
+ SQR_BASECASE_MAX.
+ (SQR_BASECASE_LIM, fat variant): Define to read __gmpn_cpuvec.
+ (SQR_BASECASE_LIM, native variant): Define to SQR_TOOM2_THRESHOLD
+ straight, without arithmetic.
+ (mpn_local_sqr): Use BELOW_THRESHOLD as per Marco's suggestion.
+
+2012-01-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-powm.c: Ensure all sizes are seen.
+
+2012-01-30 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__gmp_binary_expr): Let things happen in place: d=a+b+c
+ when d != c.
+ * tests/cxx/t-binary.cc: Test variable reuse: c=a+b+c.
+
+2012-01-28 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h: Don't compute -LONG_MIN.
+
+ * doc/gmp.texi (gmp_randclass::get_z_bits): Use mp_bitcnt_t.
+ * gmpxx.h: Replace unsigned long with mp_bitcnt_t.
+
+2012-01-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * Upgrade to libtool 2.4.2.
+
+2012-01-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpz/t-fac_ui.c: Increase default test cases.
+
+ * mpz/prodlimbs.c: New file, mpz_prodlimbs implementation.
+ * gmp-impl.h: mpz_prodlimbs declaration.
+ * Makefile.am (MPZ_OBJECTS): add mpz/prodlimbs$U.lo .
+ * mpz/Makefile.am (libmpz_la_SOURCES): add prodlimbs.c .
+ (fac_ui.h): remove target (moved up one directory).
+ * mpz/fac_ui.c: mpz_prodlimbs removed, micro-optimisations.
+
+2012-01-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c: Remove unused tuneup variables.
+
+2012-01-20 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/fac_ui.c: Reduce branches in basecases.
+
+2012-01-18 Marc Glisse <marc.glisse@inria.fr>
+
+ * doc/gmp.texi (mpf_class::mpf_class): Use mp_bitcnt_t.
+
+2012-01-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Add ultrasparc T4 support.
+
+ * demos/isprime.c (main): Run 25 millerrabin tests.
+
+2012-01-16 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/fac_ui.c (SIEVE_SEED): Define value for small limb size.
+ (mpz_oddswing_1): Reduce the number of divisions.
+ (mpz_oddfac_1): Reduce memory usage.
+ * mpn/minithres/gmp-mparam.h: Correct minimum for FAC_DSC_.
+ * tune/tuneup.c (tune_fac_ui): Likewise.
+
+2012-01-15 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/scan0.c (mpz_scan0): Use ~(mp_bitcnt_t) 0, rather than
+ ULONG_MAX, when returning "infinity".
+ * mpz/scan1.c (mpz_scan1): Likewise.
+
+2012-01-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/t-popc.c: Test longer bit strings.
+
+2012-01-12 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/divexact.c: Tight realloc, delayed if variables are reused.
+ * mpz/lcm.c: Smaller temp space, avoid goto.
+ * gmp-impl.h (popc_limb): avoid double & (for 8-bits limb).
+
+2012-01-10 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/minithres/gmp-mparam.h: New FAC_ODD_ and FAC_DSC_ thresholds.
+ * tune/tuneup.c (tune_fac_ui): Correct minimum for FAC_DSC_.
+
+2012-01-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/mul_2exp.c: Rewrite.
+ * mpz/tdiv_q_2exp.c: Rewrite.
+
+2012-01-05 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gen-fac_ui.c: Remove currently unused constants; add new odd
+ double factorial table.
+ * mpz/fac_ui.c (RECURSIVE_PROD_THRESHOLD): Increase default.
+ (mpz_oddfac_1): New function: a merge of _bc_odd and _dsc_odd.
+ (mpz_prodlimbs): More in-place computations.
+
+ * tune/tuneup.c (tune_fac_ui): min_is_always for FAC_ODD_.
+
+2012-01-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tune/tuneup.c (tune_fac_ui): Compute FAC_DSC before FAC_ODD.
+
+2011-12-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * Makefile.am (fac_ui.h): Put file in top-level dir, not in mpz.
+
+2011-12-31 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tune/Makefile.am (fac_ui.c): New target.
+ (nodist_tuneup_SOURCES,CLEANFILES): Add fac_ui.c.
+ * tune/tuneup.c (mpz_fac_ui_tune): Declare prototype.
+ (fac_odd_threshold,fac_dsc_threshold): New global variables.
+ (speed_mpz_fac_ui_tune,tune_fac_ui): New functions.
+ (all): Call tune_fac_ui.
+ * gmp-impl.h (FAC_ODD_THRESHOLD,FAC_DSC_THRESHOLD):
+ New thresholds: default values, and setup for tuning.
+ (FAC_DSC_THRESHOLD_LIMIT): Define (when tuning).
+ * mpz/fac_ui.c (FAC_ODD_THRESHOLD,FAC_DSC_THRESHOLD):
+ Default values removed.
+
+2011-12-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/hamdist.c: Fix typo in a return statement.
+
+ * mpn/generic/powm_sec.c (SQR_BASECASE_MAX): Set safely from
+ SQR_TOOM2_THRESHOLD.
+
+2011-12-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-perfpow.c: Decrease default # of tests.
+
+2011-12-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/refmpn.c (AORS_1): Fix typo in variable type.
+
+2011-12-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/sbpi1_bdiv_q.c: Delay quotient limb stores in order to
+ allow quotient and dividend to completely overlap.
+ * mpn/generic/sbpi1_bdiv_qr.c: Likewise.
+
+2011-12-10 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/fac_ui.c: fac_bc_ui inlined in fac_ui.
+
+2011-12-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm_sec.c: Handle fat binaries better.
+
+ * mpz/fac_ui.c (mpz_bc_fac_1): Fix typo in allocation size.
+
+ * mpn/x86/fat/com.c: New file.
+
+ * mpn/x86_64/pentium4/aors_n.asm: Make it actually work for DOS64.
+ * mpn/x86_64/pentium4/rsh1aors_n.asm: Conditionalise jump on DOS64
+ to avoid overhead for standard ABIs.
+
+ * mpn/x86_64/gcd_1.asm: Support DOS64.
+
+2011-12-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Fix typo making HAVE_NATIVE_mpn_X fail for fat
+ functions.
+
+ * mpn/x86_64/fat/fat.c (__gmpn_cpuvec_init): Add a missing break.
+
+2011-12-07 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gen-fac_ui.c: Generate two more tables: odd factorial, swing.
+
+ * mpz/fac_ui.c: Rewrite.
+
+2011-12-06 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (mpn_hgcd): Use hgcd_reduce for first
+ recursive call.
+
+2011-12-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/mod_1_1-1.c: Redefine the mpn_ functions, not __gmpn_ (for the
+ benefit of fat builds).
+ * tune/mod_1_1-2.c: Likewise.
+
+2011-12-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/fat/lshiftc.c: New file.
+ * mpn/x86/fat/mod_1_1.c: New file.
+ * mpn/x86/fat/mod_1_2.c: New file.
+ * mpn/x86/fat/mod_1_4.c: New file.
+
+ * mpn/x86/fat/diveby3.c: Remove no longer fat function.
+ * mpn/x86_64/fat/diveby3.c: Likewise.
+
+ * mpn/x86_64/fat/gcd_1.c: Remove since always provided as asm.
+ * mpn/x86_64/fat/mode1o.c: Likewise.
+
+ * configure.in (fat_functions): Update to more relevant function set.
+ Add special handling for mod_1_N_cps functions.
+ * gmp-impl.h (struct cpuvec_t) : Corresponding changes. Also add
+ vrious declarations for new functions.
+ * mpn/x86/x86-defs.m4 (CPUVEC_FUNCS_LIST): Corresponding changes.
+ * mpn/x86_64/x86_64-defs.m4 (CPUVEC_FUNCS_LIST): Corresponding changes.
+ * mpn/x86/fat/fat.c (__gmpn_cpuvec): Corresponding changes.
+ * mpn/x86_64/fat/fat.c (__gmpn_cpuvec): Corresponding changes.
+
+ * mpn/x86_64: Port most remaining x86_64 files to DOS64.
+
+ * mpn/x86_64/coreisbr/aors_n.asm: Add forgotten DOS64_EXIT.
+
+ * mpn/x86_64/x86_64-defs.m4 (LEA): Handle non-PIC code.
+ * mpn/x86_64/darwin.m4 (LEA): Likewise.
+
+2011-12-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat.c (MAKE_FMS): Rewrite to handle modern CPUs.
+ * mpn/x86/fat/fat.c (MAKE_FMS): Likewise.
+
+ * mpn/x86_64/darwin.m4 (PROTECT): Define to potentially useful value.
+
+2011-12-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/invert_limb_table.asm: Use PROTECT.
+ * mpn/x86_64/invert_limb.asm: Likewise.
+
+ * mpn/x86_64/darwin.m4 (PROTECT, IFELF): New defines.
+ * mpn/x86_64/dos64.m4 (PROTECT, IFELF): New defines.
+ * mpn/x86_64/x86_64-defs.m4 (PROTECT, IFELF): New defines.
+
+2011-12-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat.c: Copy fake cpuid code from x86/fat/fat.c.
+
+ * mpn/x86_64 (STD64, IFSTD): New names for ELF64, IFELF (since these
+ denote all standard calling conventions).
+
+ * mpn/x86_64: Add DOS64 ABI support to more files.
+
+ * mpn/x86_64/mod_1_1.asm: Finish DOS64 support.
+ * mpn/x86_64/mod_1_2.asm: Likewise.
+ * mpn/x86_64/mod_1_4.asm: Likewise.
+
+ * configure.in: Add GMP_NONSTD_ABI also for fat builds.
+
+ * mpn/x86_64/fat/fat_entry.asm: Rewrite to support DOS64.
+
+ * mpn/x86_64/dos64.m4 (IFDOS, IFSTD): New defines.
+ * mpn/x86_64/x86_64-defs (IFDOS, IFSTD): New defines.
+
+ * mpn/x86_64/dive_1.asm: Add DOS64 ABI support.
+ * mpn/x86_64/mode1o.asm: Likewise.
+
+ * mpn/x86_64/mod_34lsub1.asm: Enable for DOS64.
+
+ * mpn/x86_64/invert_limb.asm: Wrap .protected decl.
+
+ * gmp-impl.h (DECL_divexact_1): Fix typo in return type.
+
+ * mpn/x86_64/dos64.m4 (LEA): New define.
+ (PIC): Define.
+
+2011-11-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64: Add DOS64 ABI support to most files.
+
+2011-11-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mul_basecase.asm: Support ABI DOS64.
+ * mpn/x86_64/sqr_basecase.asm: Support ABI DOS64.
+ * mpn/x86_64/aorsmul_1.asm: Support ABI DOS64.
+ * mpn/x86_64/mul_1.asm: Support ABI DOS64.
+
+ * mpn/x86_64/x86_64-defs.m4 (DOS64_ENTRY, DOS64_EXIT): New, empty defs.
+
+ * mpn/x86_64/dos64.m4: New file.
+
+ * mpn/asm-defs.m4 (ABI_SUPPORT): New dummy macro.
+
+ * configure.in (64-bit mingw/cygwin): Define HOST_DOS64,GMP_NONSTD_ABI.
+ No longer clear out path_64.
+ (mpn code selection loop): Handle GMP_NONSTD_ABI.
+
+ * mpn/generic/udiv_w_sdiv.c: Use CNST_LIMB for some constants.
+
+2011-11-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * x86/*: Many new gmp-mparam.h file for 64-bit CPUs in 32-bit mode.
+
+ * configure.in: Overhaul x86/x86_64 support, merging three case
+ statements into one.
+
+2011-11-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Formatted Output Strings): Clarify rules for mpf_t
+ precision.
+
+ * mpn/powerpc32/p7/gmp-mparam.h: New file.
+
+ * tune/tuneup.c (tune_mu_div, tune_mu_bdiv): Up min_size to karatsuba's
+ threshold.
+
+2011-11-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/p6/aorsmul_1.asm: New file.
+
+ * configure.in: Don't fail fat builds under 64-bit DOS.
+
+ * mpn/powerpc64/mode64/aors_n.asm: Align loop for slightly better
+ power5 performance.
+
+2011-11-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (__GNU_MP_RELEASE): Renamed from typo name.
+
+2011-11-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Split x86 CPUs into more subtypes for more accurate
+ passing of gcc flags.
+
+ * mpn/powerpc32/p3-p7/aors_n.asm: New file.
+
+ * configure.in: Pass -m32 for powerpc64 with abi=32, using via _maybe
+ mechanism.
+
+ * configure.in: Support powerpc32/p3-p7 directory for affected CPUs.
+
+2011-11-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.c (routine): Add mpn_tabselect.
+ * tune/common.c (speed_mpn_tabselect): New function.
+ * tune/speed.h (SPEED_ROUTINE_MPN_COPY_CALL): New macro, made from
+ old SPEED_ROUTINE_MPN_COPY.
+ (SPEED_ROUTINE_MPN_COPY): Just invoke SPEED_ROUTINE_MPN_COPY_CALL.
+ (SPEED_ROUTINE_MPN_TABSELECT): New macro.
+
+2011-11-17 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tuneup.c (tune_hgcd_appr): Increase stop_since_change.
+
+2011-11-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc32/tabselect.asm: New file.
+
+ * mpn/powerpc64/mode64/aorscnd_n.asm: New file.
+
+2011-11-15 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/speed.h (speed_mpn_hgcd_appr_lehmer): New prototype.
+ (mpn_hgcd_lehmer_itch): Likewise.
+ (mpn_hgcd_appr_lehmer): Likewise.
+ (mpn_hgcd_appr_lehmer_itch): Likewise.
+ (MPN_HGCD_LEHMER_ITCH): Deleted macro.
+
+ * tune/speed.c (routine): Added mpn_hgcd_appr_lehmer.
+
+ * tune/common.c (speed_mpn_hgcd_lehmer): Use mpn_hgcd_lehmer_itch
+ rather than similarly named macro.
+ (speed_mpn_hgcd_appr_lehmer): New function.
+
+ * tune/Makefile.am (libspeed_la_SOURCES): Added
+ hgcd_appr_lehmer.c.
+
+ * tune/hgcd_appr_lehmer.c: New file.
+
+ * tune/tuneup.c (tune_hgcd_appr): Increased min_size to 50; some
+ machines got small thresholds which appear to be bogus.
+
+2011-11-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm_sec.c (mpn_local_sqr): Remove forgotten TMP_* calls.
+ (redcify): Likewise.
+ (mpn_powm_sec): Likewise.
+
+ * mpn/generic/powm_sec.c (mpn_powm_sec): Rework scratch usage
+ (mpn_powm_sec_itch): Rewrite.
+
+ * mpn/generic/powm_sec.c (mpn_powm_sec): Use mpn_tabselect also in
+ initialisation.
+
+ * configure.in: Amend 2011-11-03 gcc_cflags change.
+
+ * mpn/powerpc64/tabselect.asm: New file.
+ * mpn/x86_64/tabselect.asm: New file.
+ * mpn/x86/tabselect.asm: New file.
+ * mpn/ia64/tabselect.asm: New file.
+
+ * mpn/asm-defs.m4 (define_mpn): Add tabselect.
+
+ * configure.in (gmp_mpn_functions): Add tabselect.
+ (HAVE_NATIVE): Add entries for addncd_n, subcnd_n, tabselect.
+
+ * mpn/generic/powm_sec.c: Remove mpn_tabselect implementation.
+ * mpn/generic/tabselect.c: New file with removed code.
+
+2011-11-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add powm_sec.c.
+
+ * mpn/generic/powm_sec.c (win_size): Use POWM_SEC_TABLE
+ (POWM_SEC_TABLE): Define default.
+
+ * tune/tuneup.c (tune_powm_sec): New function computing POWM_SEC_TABLE.
+ (all): Call new function.
+
+ * mpn/generic/powm_sec.c (win_size): Define only when
+ TUNE_PROGRAM_BUILD is not set.
+
+2011-11-13 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tuneup.c (tune_hgcd_appr): Use default min_size.
+ (tune_hgcd_reduce): Increase max_size and step_factor, to 7000
+ and 0.04, respectively.
+
+2011-11-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/sqr_diag_addlsh1.asm: Remove.
+
+2011-11-11 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/hgcd_reduce_2.c: New file.
+ * tune/hgcd_reduce_1.c: New file.
+
+ * tune/tuneup.c (hgcd_appr_threshold): New threshold variable.
+ (hgcd_reduce_threshold): Likewise.
+ (tune_hgcd_appr): New function.
+ (tune_hgcd_reduce): New function.
+ (all): Call tune_hgcd_appr and tune_hgcd_reduce.
+
+ * tune/speed.h (speed_mpn_hgcd_reduce): Declaration.
+ (speed_mpn_hgcd_reduce_[12]): Likewise.
+ (mpn_hgcd_reduce_[12]): Likewise.
+ (SPEED_ROUTINE_MPN_HGCD_REDUCE_CALL): New macro.
+
+ * tune/speed.c (routine): Added mpn_hgcd_reduce,
+ mpn_hgcd_reduce_1, and mpn_hgcd_reduce_2.
+
+ * tune/common.c (speed_mpn_hgcd_reduce): New function.
+ (speed_mpn_hgcd_reduce_[12]): Likewise.
+
+ * tune/Makefile.am (libspeed_la_SOURCES): Added hgcd_reduce_1.c
+ hgcd_reduce_2.c.
+ (TUNE_MPN_SRCS_BASIC): Added hgcd_appr.c and hgcd_reduce.c.
+
+ * mpn/generic/hgcd_appr.c (submul, hgcd_matrix_apply): Deleted
+ functions, earlier copied to hgcd_reduce.c.
+ (mpn_hgcd_appr): Use hgcd_reduce.
+
+2011-11-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/sqr_basecase.asm: New file.
+
+ * mpn/x86_64/aorscnd_n.asm: New file.
+
+ * tune/speed.c (routine): Add measuring of mpn_addcnd_n, mpn_subcnd_n.
+ * tune/common.c (speed_mpn_addcnd_n,speed_mpn_subcnd_n): New functions.
+ * tune/speed.h: Declare them.
+
+ * tests/devel/try.c: Add tests for mpn_addcnd_n and mpn_subcnd_n.
+ * tests/refmpn.c (refmpn_addcnd_n, refmpn_subcnd_n): New functions.
+ * tests/tests.h: Declare them.
+
+ * configure.in (gmp_mpn_functions): Add addcnd_n and subcnd_n.
+
+2011-11-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/redc_1.c: Just reduce U operand using Hensel norm, but
+ not fully canonically; leave add_n and conditional sub_n to caller.
+ Therefore omit R argument.
+
+ * mpn/generic/redc_1_sec.c: Remove.
+
+ * gmp-impl.h (mpn_redc_1): Update declaration.
+ (mpn_redc_1_sec): Remove declaration.
+
+ * configure.in (gmp_mpn_functions): Remove redc_1.
+
+ * mpn/x86_64/redc_1.asm: Adopt to new defined functionality/interface.
+ * tune/speed.h (SPEED_ROUTINE_REDC_1): Likewise.
+
+ * tests/refmpn.c (refmpn_redc_1): Likewise; also call refmpn_addmul_1
+ instead of mpn_addmul_1.
+
+ * mpn/generic/powm.c (MPN_REDC_1): New macro, use for mpn_redc_1.
+ * mpn/generic/powm_sec.c (MPN_REDC_1_SEC): New macro, use for
+ mpn_redc_1_sec.
+
+2011-11-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * dumbmp.c (mpz_sub): Abort for non-handled case.
+
+ * mpn/powerpc64/mode64/lshiftc.asm: Move file from here...
+ * mpn/powerpc64/lshiftc.asm: ...to here, with trivial modifications.
+
+ * configure.in: Pass -m32 in more cases, using _maybe mechanism.
+ Inherit default gcc_cflags in more places.
+
+ * mpn/powerpc64/mode64/p7/gmp-mparam.h: New file.
+
+2011-11-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_64/invert_limb.asm: Slight optimisation.
+
+ * configure.in (s390): Set gcc_32_cflags_maybe.
+
+ * mpn/s390_32/gmp-mparam.h: Put in proper data.
+ * mpn/s390_32/esame/gmp-mparam.h: New file.
+
+ * mpn/x86_64/bobcat/gmp-mparam.h: New file.
+
+ * mpn/s390_32/lshift.asm: New file.
+ * mpn/s390_32/rshift.asm: New file.
+ * mpn/s390_32/lshiftc.asm: New file.
+
+2011-10-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/sqr_diagonal.asm: Move from here...
+ * mpn/powerpc64/mode32/sqr_diagonal.asm: ...to here.
+
+ * mpn/powerpc64/mode64/sqr_diag_addlsh1.asm: New file.
+
+ * mpn/s390_64/sqr_basecase.asm: Rewrite sqr_diag_addlsh1 code.
+ * mpn/s390_32/esame/sqr_basecase.asm: Likewise.
+
+2011-10-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_64/lshift.asm: Complete rewrite.
+ * mpn/s390_64/rshift.asm: Likewise.
+
+ * mpn/s390_64/lshiftc.asm: New file.
+
+2011-10-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_32/esame/aors_n.asm: New file, with rewritten add/sub code.
+
+2011-10-27 Torbjorn Granlund <tege@gmplib.org>
+
+ From Per Olofsson:
+ * gmp-impl.h (BSWAP_LIMB): Rename variable to avoid BSWAP_LIMB_FETCH
+ clash.
+
+ * mpn/s390_32/esame/mul_basecase.asm: New file.
+
+ * mpn/s390_32/esame/sqr_basecase.asm: New file.
+
+ * mpn/s390_32/logops_n.asm: New file.
+
+ * mpn/s390_64/logops_n.asm: Fix rp=up code. Remove a leftover insn.
+
+2011-10-26 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h (mpn_hgcd_reduce, mpn_hgcd_reduce_itch): Added
+ prototypes.
+ (HGCD_APPR_THRESHOLD): Set up threshold for tuning.
+ (HGCD_REDUCE_THRESHOLD): Likewise.
+
+ * configure.in (gmp_mpn_functions): Added hgcd_reduce.
+
+ * mpn/generic/hgcd_reduce.c: New file.
+
+2011-10-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/sqr_basecase.asm: Put intermediate result into R, don't
+ allocate any stack space.
+
+2011-10-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_64/logops_n.asm: Use nc, oc, xc when possible.
+
+ * tune/common.c (speed_mpn_and_n, speed_mpn_andn_n, etc):
+ Pass correct input args.
+
+ * mpn/s390_64/mod_34lsub1.asm: Use llgfr for zero extensions.
+
+ * mpn/s390_64/mul_basecase.asm: New file.
+
+ * mpn/s390_64/sqr_basecase.asm: New file.
+ * mpn/s390_64/sqr_diag_addlsh1.asm: Removed, lives on in sqr_basecase.
+
+ * mpn/s390_64/bdiv_dbm1c.asm: Shave off 1 c/l.
+
+ * mpn/s390_64/aorrlsh1_n.asm: New file, developed from aorslsh1_n.asm.
+ * mpn/s390_64/sublsh1_n.asm: New file.
+ * mpn/s390_64/aorslsh1_n.asm: Remove file.
+
+2011-10-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_64/logops_n.asm: New file.
+
+ * mpn/s390_64/aors_n.asm: New file, with rewritten add/sub code.
+
+2011-10-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_SQR_DIAL_ADDLSH1_CALL): New macro.
+ * tune/common.c (speed_mpn_sqr_diag_addlsh1): New function.
+ * tune/speed.c (routine): Measure mpn_sqr_diag_addlsh1.
+
+ * mpn/s390_64/sqr_diag_addlsh1.asm: Rewrite like s390_32/esame code.
+
+ * mpn/s390_32/esame/sqr_diag_addlsh1.asm: Save just needed registers.
+
+2011-10-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_32/esame/add_n.asm: Rewrite, similar to s390_64 code.
+ * mpn/s390_32/esame/add_n.asm: Likewise.
+
+2011-10-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_32/esame/aorslsh1_n.asm: New file.
+
+2011-10-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_32/esame/sqr_diag_addlsh1.asm: New file.
+
+ * mpn/s390_32/copyi.asm: New file.
+ * mpn/s390_32/copyd.asm: New file.
+
+ * mpn/s390_64/copyd.asm: Optimise.
+
+ * mpn/s390_64/copyi.asm: Rewrite along the lines of glibc memcpy.
+
+ * mpn/s390_64/aorslsh1_n.asm: New file.
+
+ * mpn/s390_64/mod_34lsub1.asm: New file.
+
+ * mpn/s390_64/sqr_diag_addlsh1.asm: New file.
+
+2011-10-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (s390): Rewrite support to handle known CPUs.
+ * config.guess: Recognise s390 CPUs.
+ * config.sub: Match s390 CPUs.
+ * acinclude.m4 (S390_PATTERN, S390X_PATTERN): New defines.
+
+2011-10-14 Torbjorn Granlund <tege@gmplib.org>
+
+ From Per Olofsson:
+ * mpn/generic/popham.c: Add __GMP_NOTHROW to make it match gmp.h.
+ * mpn/generic/gcd_1.c: Separate declarations and initialisers for the
+ benefit of C++.
+
+ * configure.in: AC_DEFINE HAVE_HOST_CPU_s390_zarch.
+ * longlong.h (s390): Use it.
+ (s390 umul_ppmm): Fix typo in pure C variant.
+
+2011-10-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * longlong.h (s390): Put back an accidentally deleted #else.
+
+ * configure.in (s390): Unset extra_functions for s390x.
+
+2011-10-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_64/lshift.asm: Reduce register usage.
+ * mpn/s390_64/rshift.asm: Likewise.
+
+ * longlong.h (s390 umul_ppmm): With new-enough gcc, avoid asm.
+
+ From Andreas Krebbel:
+ * longlong.h (s390 umul_ppmm): Support 32-bit limbs with gcc using
+ 64-bit registers.
+ (s390 udiv_qrnnd): Likewise.
+
+2011-10-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (s390x): Pass -mzarch to gcc in 32-bit mode.
+
+ * longlong.h (s390x): Add __CLOBBER_CC for relevant asm patterns.
+ * mpn/generic/mod_1_1.c (s390x add_mssaaaa): Likewise.
+
+ * mpn/s390_64/copyd.asm: New file.
+
+2011-10-10 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd_appr.c: Deleted debugging code.
+
+ * tests/mpn/t-hgcd_appr.c (main): Added -v flag.
+ (hgcd_appr_valid_p): Increased margin of non-minimality for
+ divide-and-conquer algorithm. Display bit counts only if
+ -v is used.
+
+ * mpn/generic/hgcd_appr.c (submul): New (static) function.
+ (hgcd_matrix_apply): New function.
+ (mpn_hgcd_appr_itch): Account for divide-and-conquer algorithm.
+ (mpn_hgcd_appr): Implemented divide-and-conquer.
+
+2011-10-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mod_1_1.c (add_mssaaaa): Add s390x variant. Put arm code
+ inside __GNUC__.
+
+ * tune/time.c (STCK): Use proper memory constraint.
+
+ From Marco Trudel:
+ * tests/mpz/t-scan.c (check_ref): Fix loop end bound.
+
+2011-10-10 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h: (HGCD_APPR_THRESHOLD): New threshold.
+
+ * mpn/generic/hgcd_appr.c (mpn_hgcd_appr): Interface change.
+ Destroy inputs, let caller make working copies if needed.
+ (mpn_hgcd_appr_itch): Reduced scratch need.
+ * gmp-impl.h: Updated mpn_hgcd_appr prototype.
+ * tests/mpn/t-hgcd_appr.c (one_test): Make working copies for
+ hgcd_appr.
+ * tune/common.c (speed_mpn_hgcd_appr): Use SPEED_ROUTINE_MPN_HGCD_CALL.
+ * tune/speed.h (SPEED_ROUTINE_MPN_HGCD_APPR_CALL): Deleted.
+
+2011-10-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_64/copyi.asm: New file.
+ * mpn/s390_64/lshift.asm: New file.
+ * mpn/s390_64/rshift.asm: New file.
+
+ * mpn/s390_64/add_n.asm: Rewrite using lmg/stmg.
+ * mpn/s390_64/sub_n.asm: Likewise.
+
+ * mpn/s390_64/invert_limb.asm: Save a callee-saves register less.
+
+ * tune/time.c (getrusage_backwards_p): Properly cast printed values.
+
+ * longlong.h (s390x): Put back UDItype casts to make gcc reloading use
+ right more for constants.
+ (s390x count_leading_zeros): Disable until we support z10 specifically.
+ (s390x add_ssaaaa): Remove algsi/slgsi until we support z10.
+
+2011-10-09 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd_matrix.c (mpn_hgcd_matrix_adjust): Declare
+ matrix argument const.
+
+2011-10-08 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/t-hgcd_appr.c (hgcd_appr_valid_p): Adjusted the
+ allowed margin of non-minimality for hgcd_appr.
+
+ * mpn/generic/hgcd_appr.c (mpn_hgcd_appr): Fixed handling of
+ extra_bits, starting at zero, to ensure that we don't produce too
+ small remainders. Added a final reduction loop when we we
+ otherwise terminate with extra_bits > 0, to make the returned
+ remainders closer to minimal.
+
+2011-10-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * longlong.h (s390): Add 32-bit zarch umul_ppmm and udiv_qrnnd.
+ (s390): Overhaul 32-bit and 64-bit code.
+
+2011-10-07 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/speed.h (speed_mpn_hgcd_appr): New prototype.
+ (SPEED_ROUTINE_MPN_HGCD_APPR_CALL): New macro.
+ * tune/common.c (speed_mpn_hgcd_appr): New function.
+ * tune/speed.c (routine): Added mpn_hgcd_appr.
+
+ * tests/mpn/t-hgcd_appr.c: New file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-hgcd_appr.
+
+ * configure.in (gmp_mpn_functions): Added hgcd_step and hgcd_appr.
+
+ * gmp-impl.h: Added prototypes for mpn_hgcd_step,
+ mpn_hgcd_appr_itch and mpn_hgcd_appr.
+
+ * mpn/generic/hgcd_appr.c: New file.
+
+ * mpn/generic/hgcd_step.c: New file, extracted from hgcd.c.
+ (mpn_hgcd_step): Renamed, from...
+ * mpn/generic/hgcd.c (hgcd_step): ...old name. Renamed and moved
+ to hgcd_step.c.
+ (hgcd_hook): Also moved to hgcd_step.c.
+ (mpn_hgcd): Updated for hgcd_step renaming.
+
+2011-10-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_64/invert_limb.asm: New file.
+
+2011-10-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/s390_64/submul_1.asm: New file.
+ * mpn/s390_32/esame/submul_1.asm: New file.
+
+ * mpn/generic/mulmid.c (mpn_mulmid): Move a TMP_DECL to block start.
+
+ * mpn/Makefile.am (TARG_DIST): Add s390_32 and s390_64, remove s390 and
+ z8000x.
+
+ * doc/gmp.texi (Custom Allocation): Rephrase a paragraph.
+
+ * demos/factorize.c: Run 25 Miller-Rabin tests.
+
+ * mpz/nextprime.c: Run 25 mpz_millerrabin tests (was 10).
+
+2011-10-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Support s390x.
+
+ * longlong.h: Add support for 64-bit s390x.
+
+ * mpn/s390_64: New directory.
+ * mpn/s390_64/add_n.asm: New file.
+ * mpn/s390_64/sub_n.asm: New file.
+ * mpn/s390_64/mul_1.asm: New file.
+ * mpn/s390_64/addmul_1.asm: New file.
+ * mpn/s390_64/bdiv_dbm1c.asm: New file.
+ * mpn/s390_64/gmp-mparam.h: New file, taken from x86_64.
+
+ * mpn/s390_32: Directory renamed from mpn/s390.
+ * mpn/s390_32/gmp-mparam.h: New file, taken from x86_64.
+ * mpn/s390_32/esame/add_n.asm: New file.
+ * mpn/s390_32/esame/sub_n.asm: New file.
+ * mpn/s390_32/esame/mul_1.asm: New file.
+ * mpn/s390_32/esame/addmul_1.asm: New file.
+ * mpn/s390_32/esame/bdiv_dbm1c.asm: New file.
+
+2011-10-03 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-mulmid.
+ * tests/mpn/t-mulmid.c: New file.
+
+ mulmid-related assembly for x86_64, from David Harvey:
+ * mpn/asm-defs.m4 (define_mpn): Added [add,sub]_err[1,2,3]_n and
+ mulmid_basecase. Also use m4_not_for_expansion on the
+ corresponding OPERATION_* symbols.
+ * mpn/x86_64/aors_err1_n.asm: New file.
+ * mpn/x86_64/aors_err2_n.asm: Likewise.
+ * mpn/x86_64/aors_err3_n.asm: Likewise.
+ * mpn/x86_64/mulmid_basecase.asm: Likewise.
+ * mpn/x86_64/core2/aors_err1_n.asm: Likewise.
+ * mpn/x86_64/gmp-mparam.h (MULMID_TOOM42_THRESHOLD): New value.
+ * mpn/x86_64/core2/gmp-mparam.h (MULMID_TOOM42_THRESHOLD): Likewise.
+
+ Tuning of mulmid, from David Harvey:
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Added mulmid.c
+ mulmid_n.c toom42_mulmid.c.
+ * tune/speed.h: Prototypes for mulmid-related functions.
+ (struct speed_params): Increased max number of sources to 5.
+ (SPEED_ROUTINE_MPN_BINARY_ERR_N_CALL): New macro.
+ (SPEED_ROUTINE_MPN_BINARY_ERR1_N): Likewise.
+ (SPEED_ROUTINE_MPN_BINARY_ERR2_N): Likewise.
+ (SPEED_ROUTINE_MPN_BINARY_ERR3_N): Likewise.
+ (SPEED_ROUTINE_MPN_MULMID): Likewise.
+ (SPEED_ROUTINE_MPN_MULMID_N): Likewise.
+ (SPEED_ROUTINE_MPN_TOOM42_MULMID): Likewise.
+ * tune/common.c (mpn_[add,sub]_err[1,2,3]_n): New functions.
+ (speed_mpn_mulmid_basecase): New function.
+ (speed_mpn_mulmid): New function.
+ (speed_mpn_mulmid_n): New function.
+ (speed_mpn_toom42_mulmid): New function.
+ * tune/speed.c (routine): Added mpn_[add,sub]_err[1,2,3]_n,
+ mpn_mulmid_basecase, mpn_toom42_mulmid, mpn_mulmid_n, and
+ mpn_mulmid.
+ * tune/tuneup.c (mulmid_toom42_threshold): New threshold variable.
+ (tune_mulmid): New function.
+ (all): Call tune_mulmid.
+
+ Testing of mulmid, from David Harvey:
+ * tests/refmpn.c (AORS_ERR1_N): New macro.
+ (refmpn_add_err1_n, refmpn_sub_err1_n): New functions.
+ (AORS_ERR2_N): New macro.
+ (refmpn_add_err2_n, refmpn_sub_err2_n): New functions.
+ (AORS_ERR3_N): New macro.
+ (refmpn_add_err3_n, refmpn_sub_err3_n): New functions.
+ (refmpn_mulmid_basecase): New function.
+ (refmpn_toom42_mulmid): New function, wrapper for
+ refmpn_mulmid_basecase.
+ (refmpn_mulmid_n): Likewise.
+ (refmpn_mulmid): Likewise.
+ * tests/tests.h: Prototypes for new functions.
+ * tests/devel/try.c (NUM_SOURCES): Increased to 5.
+ (struct try_t): Use NUM_SOURCES and NUM_DESTS constants.
+ (SIZE_4, SIZE_6, SIZE_DIFF_PLUS_3, SIZE_ODD): New constants.
+ (OVERLAP_NOT_DST2): New flag.
+ (param_init): New mulmid-related operation types.
+ (mpn_toom42_mulmid_fun): New function.
+ (choice_array): Added mulmid-related entries.
+ (overlap_array): Extended for larger NUM_SOURCES.
+ (OVERLAP_COUNT): Handle OVERLAP_NOT_DST2.
+ (call): Support mulmid-related functions.
+ (pointer_setup): Handle SIZE_4, SIZE_6, and SIZE_DIFF_PLUS_3.
+ (SIZE_ITERATION): Handle SIZE_ODD.
+ (SIZE2_FIRST): Handle SIZE_CEIL_HALF.
+ (SIZE2_LAST): Likewise.
+
+ Implementation of mulmid, from David Harvey:
+ * mpn/generic/add_err1_n.c (mpn_add_err1_n): New file and function.
+ * mpn/generic/add_err2_n.c (mpn_add_err2_n): Likewise.
+ * mpn/generic/add_err3_n.c (mpn_add_err3_n): Likewise.
+ * mpn/generic/sub_err1_n.c (mpn_sub_err1_n): Likewise.
+ * mpn/generic/sub_err2_n.c (mpn_sub_err2_n): Likewise.
+ * mpn/generic/sub_err3_n.c (mpn_sub_err3_n): Likewise.
+ * mpn/generic/mulmid_basecase.c (mpn_mulmid_basecase): Likewise.
+ * mpn/generic/mulmid_n.c (mpn_mulmid_n): Likewise.
+ * mpn/generic/toom42_mulmid.c (mpn_toom42_mulmid): Likewise.
+ * configure.in (gmp_mpn_functions): Added mulmid-related
+ functions.
+ (GMP_MULFUNC_CHOICES): Handle aors_err1_n, aors_err2_n, and
+ aors_err3_n.
+ * gmp-impl.h: Added prototypes for mulmid functions.
+ (MPN_TOOM42_MULMID_MINSIZE): New constant.
+ (MULMID_TOOM42_THRESHOLD): New threshold.
+ (mpn_toom42_mulmid_itch): New macro.
+
+2011-10-03 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tune-gcd-p.c (main): Fixed broken loop conditions.
+
+2011-09-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sh/sh2/submul_1.asm: Make this old submul_1 implementation
+ actually compute intended function.
+
+ * longlong.h (SH): Recognise predefs for all SH processors as defined
+ by current gcc versions.
+
+2011-09-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sh: Migrate files to '.asm'.
+ * configure.in: Recognise sh3 and sh4.
+
+2011-09-21 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (mpz_class::swap): New function.
+ (mpq_class::swap): Likewise.
+ (mpf_class::swap): Likewise.
+ (swap): New function.
+ * tests/cxx/t-assign.cc: Test the above.
+ * doc/gmp.texi (swap): Document the above.
+
+2011-08-21 Marc Glisse <marc.glisse@inria.fr>
+
+ * tests/cxx/t-ops2.cc: check mul-div by 2.
+
+ * gmpxx.h (__GMPXX_CONSTANT): New macro (__builtin_constant_p).
+ (__gmp_binary_lshift): Move before multiplication. Optimize x << 0.
+ (__gmp_binary_rshift): Move before division. Optimize x >> 0.
+ (__gmp_binary_plus): Optimize x + 0. Rewrite rational + integer.
+ (__gmp_binary_minus): Optimize x - 0 and 0 - x.
+ Rewrite rational - integer.
+ (__gmp_binary_multiplies): Optimize x * 2^n.
+ (__gmp_binary_divides): Optimize x / 2^n.
+ (__gmp_binary_*): Deduplicate code for symmetric operations.
+
+2011-08-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * printf/doprntf.c (__gmp_doprnt_mpf): For DOPRNT_CONV_FIXED, ask for
+ one more digit.
+
+2011-08-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpf/sub.c: Fix typo in copy condition. Delay an allocation.
+
+2011-08-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (LIMBS_PER_DIGIT_IN_BASE): Fix typo.
+
+2011-08-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (DIGITS_IN_BASEGT2_FROM_BITS): New.
+ (DIGITS_IN_BASE_FROM_BITS): Compute more accurate result.
+ (MPN_SIZEINBASE): Use DIGITS_IN_BASEGT2_FROM_BITS.
+
+ * tests/rand/t-lc2exp.c (check_bigc): Call abort after reporting error.
+
+2011-08-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/out_str.c (mpz_out_str): Reinsert accidentally deleted str_size
+ adjustment.
+
+ * gmp-impl.h (DIGITS_IN_BASE_FROM_BITS): Simplify, also avoiding
+ overflow for base 2.
+
+2011-08-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (struct bases): Add log2b and logb2 field, remove
+ chars_per_limb_exactly field.
+ (DIGITS_IN_BASE_FROM_BITS): New.
+ (DIGITS_IN_BASE_PER_LIMB): New.
+ (LIMBS_PER_DIGIT_IN_BASE): New.
+ * gen-bases.c: Generate log2b and logb2 fields; do not generate
+ chars_per_limb_exactly field.
+ * mpf/get_str.c mpf/out_str.c mpf/set_str.c mpn/generic/get_str.c
+ mpn/generic/sizeinbase.c mpq/get_str.c mpz/inp_str.c mpz/out_str.c
+ mpz/set_str.c printf/doprntf.c tune/speed.h tune/tuneup.c:
+ Use new macros.
+
+2011-08-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * dumbmp.c (mpz_root): Reinsert accidentally removed line.
+
+2011-08-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * dumbmp.c (mpz_tdiv_qr): Correctly handle dividend value being equal
+ to divisor value.
+ (mpz_root): Create reasonable starting approximation.
+ (mpz_sqrt): New function.
+ (mpz_mul_2exp): Add faster block shifting code, disabled for now.
+
+2011-07-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/arm/invert_limb.asm: Swap around some registers to silence 'as'
+ warnings.
+
+2011-07-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/dcpi1_bdiv_q.c (mpn_dcpi1_bdiv_q): Get mpn_sub_1 size
+ argument right.
+
+2011-07-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/misc/t-locale.c: Disable test for mingw.
+
+ * configure.in (x86_64 *-*-mingw*): Handle also cygwin here; clear out
+ extra_functions_64.
+
+2011-07-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Don't print newline in x86 cpuid function.
+ Rewrite x86-64 cpu recognition asm code to work under Windoze.
+
+2011-06-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * acinclude.m4 (GMP_ASM_RODATA): Fix typo in 2011-04-20 change.
+
+ * configure.in: Surround tr ranges with [] for portability.
+
+2011-05-25 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tune-gcd-p.c (search): New function to search for minimum.
+ (main): Replaced slow linear search.
+
+2011-05-24 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/Makefile.am (EXTRA_PROGRAMS): Added tune-gcd-p. Also added
+ related automake variables.
+
+ * mpn/Makefile.am (tune-gcd-p): Deleted target.
+
+ * tune/tune-gcd-p.c: New file, extracted from mpn/generic/gcd.c
+ and updated.
+ * mpn/generic/gcd.c: Deleted the corresponding code, including
+ main function.
+
+2011-05-23 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/jacobi.c (mpz_jacobi): Simplified by swapping operands when
+ needed, to get asize >= bsize. Use the reciprocity law generalized
+ to work when one operand is even.
+
+2011-05-22 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/jacobi.c (mpz_jacobi): Another bugfix for the asize == 1
+ case. Sometimes, powers of two in b were taken into account twice.
+
+2011-05-21 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/jacobi.c (mpz_jacobi): The handling of asize == 1 was
+ broken. Rewrote it.
+
+ * tests/mpz/t-jac.c (mpz_nextprime_step): Sanity check that prime
+ candidate and step has no common factor.
+ (check_data): Added some test cases related to the asize == 1 case
+ in mpz_jacobi.
+
+2011-05-20 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h: Jacobi-related prototypes.
+
+ * configure.in (gmp_mpn_functions): Added jacobi_2, jacobi,
+ hgcd2_jacobi, hgcd_jacobi, and removed jacobi_lehmer.
+
+ * mpz/jacobi.c (STRIP_TWOS): Deleted macro.
+ (mpz_jacobi): Partially rewritten, to no longer makes the A
+ operand odd. Use new mpn_jacobi_n.
+
+ * mpn/generic/jacobi_lehmer.c: Deleted file.
+
+ * mpn/generic/jacobi.c (mpn_jacobi_n): New subquadratic jacobi
+ implementation. Supersedes jacobi_lehmer.c.
+
+ * mpn/generic/hgcd_jacobi.c (mpn_hgcd_jacobi): New file and
+ function. A copy of mpn_hgcd, using mpn_hgcd2_jacobi, and with calls to
+ mpn_jacobi_update when appropriate.
+
+ * mpn/generic/jacobi_2.c (mpn_jacobi_2): New file. Extracted from
+ jacobi_lehmer.c.
+ * mpn/generic/hgcd2_jacobi.c (mpn_hgcd2_jacobi): Likewise.
+
+ * mpn/generic/hgcd.c (hgcd_hook): Avoid using NULL.
+
+2011-05-19 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/hgcd_lehmer.c (__gmpn_hgcd_itch): Don't rename symbols for
+ the functions moved to hgcd_matrix.c.
+
+ * configure.in (gmp_mpn_functions): Added hgcd_matrix.
+
+ * mpn/generic/hgcd.c (hgcd_matrix_update_1): Deleted. Several other
+ helper functions moved to hgcd_matrix.c, see below.
+ (hgcd_hook): New function.
+ (hgcd_step): Simplified, using mpn_gcd_subdiv_step and hgcd_hook.
+
+ * mpn/generic/hgcd_matrix.c: New file.
+ (mpn_hgcd_matrix_init): Moved here, from hgcd.c.
+ (mpn_hgcd_matrix_update_q): Likewise.
+ (mpn_hgcd_matrix_mul_1): Likewise.
+ (mpn_hgcd_matrix_mul): Likewise.
+ (mpn_hgcd_matrix_adjust): Likewise.
+
+ * mpn/generic/gcd_subdiv_step.c (mpn_gcd_subdiv_step): New
+ argument s, for use by hgcd.
+ * gmp-impl.h (mpn_gcd_subdiv_step): Update declaration.
+
+ * mpn/generic/gcd.c (mpn_gcd): Pass s = 0 to mpn_gcd_subdiv_step.
+ * mpn/generic/gcdext.c (mpn_gcdext): Likewise. Also added an ASSERT.
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_lehmer_n): Likewise.
+ (mpn_gcdext_hook): Added some ASSERTs.
+ * mpn/generic/jacobi_lehmer.c (mpn_jacobi_lehmer): Likewise.
+
+2011-05-17 Niels Möller <nisse@lysator.liu.se>
+
+ * doc/gmp.texi (mpn_gcd, mpn_gcdext): Document input requirements:
+ Must have un >= vn > 0, and V normalized.
+ * mpn/generic/gcdext.c (mpn_gcdext): Added ASSERT for input
+ normalization.
+ * mpn/generic/gcd.c (mpn_gcd): Added ASSERTs for input
+ requirements.
+
+2011-05-15 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (operator<<): Dedup.
+ * tests/cxx/t-iostream.cc: Test on compound types.
+
+ * gmpxx.h (__gmp_binary_expr): Let things happen in place: c=(a+b)/2.
+
+2011-05-10 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__gmp_unary_expr): Let things happen in place: c=-(a+b).
+ (operator>>): Clean the commenting out.
+ * tests/cxx/t-iostream.cc: New file.
+ * tests/cxx/Makefile.am: Added t-iostream.
+
+2011-05-10 Niels Möller <nisse@lysator.liu.se>
+
+ * doc/gmp.texi (mpz_gcd): Document that gcd(0,0) = 0.
+ (mpz_gcdext): Document range for cofactors.
+
+2011-05-09 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/gcdext.c (mpz_gcdext): Increased sp allocation to bsize+1 limbs.
+ * doc/gmp.texi (mpn_gcdext): Fixed documentation of allocation
+ requirements; one extra limb is still needed for S.
+
+2011-05-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/fat/gmp-mparam.h (BMOD_1_TO_MOD_1_THRESHOLD): Define.
+ * mpn/x86_64/fat/gmp-mparam.h (BMOD_1_TO_MOD_1_THRESHOLD): Define.
+
+2011-05-08 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h: Replace unsigned long with mp_bitcnt_t in many places.
+ * doc/gmp.texi: Likewise.
+
+2011-05-06 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (mpz_class): Make constructor from mp[qf]_class explicit.
+ (mpq_class): Make constructor from mpf_class explicit.
+ * doc/gmp.texi: Document the above.
+ * NEWS: Likewise, and mention the EOF istream fix.
+ * tests/cxx/t-mix.cc: New file.
+ * tests/cxx/Makefile.am: Added t-mix.
+
+ * tests/cxx/t-assign.cc: Minor tweak.
+ * tests/cxx/t-misc.cc: Likewise.
+
+ * gmpxx.h (__gmp_resolve_temp): Remove.
+ (__gmp_set_expr): Remove some overloads.
+ (mpq_class): mpz_init_set the numerator and denominator instead of
+ mpq_init + mpq_set.
+ (mpz_class): Dedup the string constructors.
+ (mpq_class): Likewise.
+
+ * tests/cxx/t-ops3.cc: New file.
+ * tests/cxx/Makefile.am: Added t-ops3.
+
+2011-05-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/gcdext.c: Correct sgn computation.
+ Use MPZ_REALLOC.
+
+2011-05-05 Marc Glisse <marc.glisse@inria.fr>
+
+ * mpn/x86_64/fat/fat.c: Update for Sandy Bridge.
+ * config.guess: warning to keep it in sync with fat.c.
+
+2011-05-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat_entry.asm (PIC_OR_DARWIN): New symbol. Use it to
+ work around Darwin problems.
+
+2011-05-04 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/gcdext.c (mpz_gcdext): Reduced temporary allocations. Use
+ mpz_divexact when computing the second cofactor.
+
+2011-05-03 David Harvey <dmharvey@cims.nyu.edu>
+
+ * configure.in: make invert_limb_table work correctly with
+ --disable-assembly (from Niels Möller)
+
+2011-05-02 Marc Glisse <marc.glisse@inria.fr>
+
+ * .bootstrap: libtoolize doesn't need -c.
+
+ * configfsf.guess: Update to version of 2011-02-02.
+ * configfsf.sub: Update to version of 2011-03-23.
+
+2011-05-02 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/gcdext.c (mpz_gcdext): Don't allocate extra limbs at the end
+ of mpn_gcdext parameters.
+
+ * doc/gmp.texi (mpn_gcdext): Updated doc.
+
+2011-05-01 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/div_qr_2u_pi1.c (mpn_div_qr_2u_pi1): Fixed ASSERT.
+
+2011-04-30 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmp-h.in (mpz_cdiv_q_2exp): Use mp_bitcnt_t to match the definition
+ and the documentation.
+ (mpz_remove): Likewise.
+ (mpf_eq): Likewise.
+
+ * ltmain.sh: Remove.
+ * .bootstrap: Let libtoolize generate ltmain.sh.
+
+ * tests/cxx/t-ops2.cc: Add a couple tests.
+ * tests/cxx/t-rand.cc: Likewise.
+
+ * doc/gmp.texi (mpf_urandomb): Explicit the fact that it does not
+ change the precision.
+
+ * gmp-h.in (__GMP_EXTERN_INLINE): Recent g++ uses gnu_inline.
+
+2011-04-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (x86_64): Support bobcat specifically.
+ (x86): Match bobcat and bulldozer, handle like k10.
+
+2011-04-28 David Harvey <dmharvey@cims.nyu.edu>
+
+ * README.HG: update autotools version numbers.
+
+2011-04-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.h (speed_cyclecounter): Always use PIC variant when
+ compiled with Apple's GCC.
+
+ * mpn/x86/darwin.m4 (LEA): Complete rewrite.
+ (m4append): New macro.
+
+2011-04-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc32/sparc-defs.m4 (changecom): Don't redefine '!' as it
+ interferes with expressions.
+
+2011-04-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * acinclude.m4 (GMP_ASM_RODATA): Make 'foo' larger to avoid clang
+ problems.
+
+2011-04-12 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/invert_limb.asm [PIC]: Declare mpn_invert_limb_table
+ as .protected.
+
+2011-04-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/invert_limb.asm: Use deflit for Darwin bug workaround.
+ Undo 2011-03-28 change.
+
+ * mpn/asm-defs.m4 (define_mpn): Use deflit.
+
+2011-04-10 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/asm-defs.m4 (define_mpn): Added invert_limb_table.
+
+ * configure.in: Add invert_limb_table to extra_functions_64 on
+ x86_64.
+
+ * mpn/x86_64/invert_limb.asm: Changed references from approx_tab
+ mpn_invert_limb_table.
+
+ * mpn/x86_64/invert_limb_table.asm (mpn_invert_limb_table): New
+ file. Extracted approximation table from invert_limb.asm, renamed
+ and made global.
+
+2011-03-30 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/div_qr_2u_pi1.asm: New file.
+
+ * configure.in (gmp_mpn_functions): Add div_qr_2u_pi1.
+
+ * gmp-impl.h (mpn_div_qr_2u_pi1): Declare.
+
+ * mpn/generic/div_qr_2u_pi1.c (mpn_div_qr_2u_pi1): Moved to
+ separate file, from...
+ * mpn/generic/div_qr_2.c: ... old location.
+
+ * mpn/generic/div_qr_2n_pi1.c: Renamed file, from...
+ * mpn/generic/div_qr_2_pi1_norm.c: ...old name.
+ * mpn/x86_64/div_qr_2n_pi1.asm: Renamed file, from...
+ * mpn/x86_64/div_qr_2_pi1_norm.asm: ...old name.
+
+ * gmp-impl.h (mpn_div_qr_2n_pi1): Use new name in declaration.
+ * tune/speed.h (speed_mpn_div_qr_2n): Likewise.
+ (speed_mpn_div_qr_2u): Likewise.
+
+ * tune/tuneup.c (tune_div_qr_2): Use new name speed_mpn_div_qr_2n.
+
+ * tune/speed.c (routine): Use new names mpn_div_qr_2n and
+ mpn_div_qr_2u, also on the command line.
+
+ * tune/common.c (speed_mpn_div_qr_2n): Renamed, from...
+ (speed_mpn_div_qr_2_norm): ... old name.
+ (speed_mpn_div_qr_2u): Renamed, from...
+ (speed_mpn_div_qr_2_unnorm): ... old name.
+
+ * mpn/generic/div_qr_2_pi1_norm.c (mpn_div_qr_2n_pi1): Renamed,
+ from...
+ (mpn_div_qr_2_pi1_norm): ...old name.
+ * mpn/x86_64/div_qr_2_pi1_norm.asm: Likewise.
+
+ * mpn/generic/div_qr_2.c (mpn_div_qr_2n_pi2): Renamed, from...
+ (mpn_div_qr_2_pi2_norm): ... old name.
+ (mpn_div_qr_2u_pi1): Renamed, from...
+ (mpn_div_qr_2_pi1_unnorm): ... old name.
+ (mpn_div_qr_2): Call functions using new names.
+
+ * mpn/asm-defs.m4: Renamed div_qr_2-functions to new names.
+
+2011-03-29 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/div_qr_2_pi1_norm.asm: Updated to use a separate rp
+ argument.
+
+ * gmp-impl.h (mpn_div_qr_2_pi1_norm): Updated declaration.
+ * gmp-h.in (mpn_div_qr_2): Likewise.
+
+ * tests/mpn/t-div.c (main): Adapted to new mpn_div_qr2 interface.
+ * tune/speed.h (SPEED_ROUTINE_MPN_DIV_QR_2): Likewise.
+
+ * mpn/generic/div_qr_2.c (mpn_div_qr_2_pi2_norm): Added rp
+ argument. Don't clobber the input dividend.
+ (mpn_div_qr_2_pi1_unnorm): Likewise.
+ (mpn_div_qr_2): Likewise.
+ * mpn/generic/div_qr_2_pi1_norm.c (mpn_div_qr_2_pi1_norm): Likewise.
+
+2011-03-29 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86/k7/invert_limb.asm: Use mov rather than push and pop.
+ Earlier load of divisor from stack.
+
+2011-03-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/invert_limb.asm: Protect movzwl register parameters from
+ being interpreted as m4 macro parameters.
+
+2011-03-22 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/div_qr_2_pi1_norm.asm: Copied optimized inner loop
+ from divrem_2.asm.
+
+ * mpn/x86_64/div_qr_2_pi1_norm.asm: First working, but poorly
+ optimized, implementation.
+
+ * mpn/asm-defs.m4 (define_mpn): Added div_qr_2_pi[12]_*norm.
+
+ * mpn/generic/div_qr_2_pi1_norm.c (mpn_div_qr_2_pi1_norm): Moved
+ to separate file, from...
+ * mpn/generic/div_qr_2.c: ... old location.
+
+ * gmp-impl.h (mpn_div_qr_2_pi1_norm): Declare.
+
+ * configure.in (gmp_mpn_functions): Added div_qr_2_pi1_norm.
+
+2011-03-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (powerpc): Reinsert lost AIX cpu_path 32-bit handling.
+ Reinsert lost linux/bsd cpu_path handling.
+
+ * mpn/generic/mod_1_1.c: Disable powerpc asm for _LONG_LONG_LIMB.
+ * mpn/generic/div_qr_2.c: Likewise.
+
+ * mpn/generic/div_qr_2.c: Use asm just for gcc.
+ Make powerpc add_sssaaaa work for 32-bit case, and use less strict
+ constraints.
+
+2011-03-21 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tuneup.c (div_qr_2_pi2_threshold): New global variable.
+ (tune_div_qr_2): New function.
+ (all): Call tune_div_qr_2.
+
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Added div_qr_2.c.
+
+ * gmp-impl.h (DIV_QR_2_PI2_THRESHOLD): Setup for tuning.
+
+ New 4/2 division loop, based on Torbjörn's work:
+ * mpn/generic/div_qr_2.c (add_sssaaaa, add_csaac): New macros.
+ (udiv_qr_4by2): New macro.
+ (invert_4by2): New function.
+ (mpn_div_qr_2_pi2_norm): New function.
+ (DIV_QR_2_PI2_THRESHOLD): New threshold.
+ (mpn_div_qr_2_pi1_norm): Renamed, from...
+ (mpn_div_qr_2_norm): ... old name.
+ (mpn_div_qr_2_pi1_unnorm): Renamed, from...
+ (mpn_div_qr_2_unnorm): ... old name.
+ (mpn_div_qr_2): Use mpn_div_qr_2_pi2_norm for large enough
+ normalized divisors.
+
+ * gmp-impl.h (udiv_qr_3by2): Avoid a copy.
+
+2011-03-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (hppa): Under linux, treat 64-bit processors as if they
+ were 32-bit processors.
+
+ * mpn/generic/addcnd_n.c: New file.
+ * mpn/asm-defs.m4 (define_mpn): Add addcnd_n and subcnd_n.
+ * configure.in (gmp_mpn_functions): Add addcnd_n.
+ * gmp-impl.h (mpn_addcnd_n): Declare.
+
+ * mpn/generic/subcnd_n.c: Combine nails and non-nails functions.
+
+ * gmp-impl.h (invert_pi1): Prepend _ to local variables, protect
+ parameters within () where necessary.
+
+ * mpn/asm-defs.m4 (define_mpn): Add div_qr_2.
+ * configure.in (gmp_mpn_functions): Reinsert mercurial-bug-removed
+ line.
+
+2011-03-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (powerpc): Add cpu_path for all three ABIs.
+ Rename "aix64" to "mode64" for consistency.
+
+2011-03-16 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__gmp_binary_not_equal): Remove, use !__gmp_binary_equal.
+ (__gmp_binary_less_equal): Remove, use !__gmp_binary_greater.
+ (__gmp_binary_greater_equal): Remove, use !__gmp_binary_less.
+ * tests/cxx/t-ops2.cc: Typo.
+
+2011-03-20 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/common.c (speed_mpn_div_qr_2_norm): New function.
+ (speed_mpn_div_qr_2_unnorm): New function.
+ * tune/speed.c (routine): Recognize above functions.
+ * tune/speed.h: Declarations for above functions.
+ (SPEED_ROUTINE_MPN_DIV_QR_2): New macro.
+
+ * tests/mpn/t-div.c (main): Added tests for mpn_divrem_2 and
+ mpn_div_qr_2.
+
+ * mpn/generic/div_qr_2.c (mpn_div_qr_2): New file and function.
+ Intended to eventually replace divrem_2.
+ * configure.in (gmp_mpn_functions): Add div_qr_2.
+
+2011-03-16 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__gmp_set_expr): Remove broken declarations.
+
+2011-03-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/fac_ui.c (mpz_fac_ui): Use MPZ_REALLOC for standard, conditional
+ reallocation.
+
+2011-03-19 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/divrem_2.c (mpn_divrem_2): Fixed comment and assert
+ regarding q and n overlap.
+
+2011-03-16 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__mpz_set_ui_safe): New inline function.
+ (__mpz_set_si_safe): Likewise.
+ (__GMPXX_TMPZ_UI): Use the new function.
+ (__GMPXX_TMPZ_SI): Likewise.
+ (__GMPXX_TMPQ_UI): Likewise.
+ (__GMPXX_TMPQ_SI): Likewise.
+ * tests/cxx/t-ops2.cc: test converting 0 to stack mpq_t.
+
+2011-03-15 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h (__GMPXX_TMPQ_UI): New macro.
+ (__GMPXX_TMPQ_SI): New macro.
+ (struct __gmp_binary_multiplies): Rewrite, using the new macros.
+ (struct __gmp_binary_divides): Likewise.
+
+ * gmpxx.h (__GMPZ_ULI_LIMBS): Rewrite.
+ * tests/cxx/t-ops2.cc: test converting ULONG_MIN to stack mpq_t.
+
+2011-03-15 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom_interpolate_16pts.c: Remove ambiguity.
+
+2011-03-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mul): Set tuning min size considering print skew.
+
+ * doc/gmp.texi: Make reference to "Formatted I/O" chapters from type
+ specific I/O sections.
+
+ * mpn/alpha/add_n.asm: Add _nc entry point.
+ * mpn/alpha/sub_n.asm: Likewise.
+ * mpn/mips64/add_n.asm: Likewise.
+ * mpn/mips64/sub_n.asm: Likewise.
+ * mpn/sparc64/ultrasparc1234/add_n.asm: Likewise.
+ * mpn/sparc64/ultrasparc1234/sub_n: Likewise.
+
+2011-03-13 Marc Glisse <marc.glisse@inria.fr>
+
+ * tests/cxx/t-ops2.cc: New file.
+ * tests/cxx/Makefile.am: Added t-ops2.
+
+2011-03-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom32_mul.c (mpn_toom32_mul): Make 'hi' be limb-sized
+ for better code.
+
+ * gmp-impl.h (MPN_IORD_U): Handle x86_64 as well as x86_32. Generate
+ no code for incrementing by constant 0.
+
+2011-03-12 Marc Glisse <marc.glisse@inria.fr>
+
+ * gmpxx.h: Rename __GMPXX_TMP_* to __GMPXX_TMPZ_*. Use in more places.
+
+2011-03-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/rshift.asm: Accept/return values correctly also for
+ 32-bit ABI.
+ * mpn/powerpc64/lshift.asm: Likewise.
+
+ * tune/powerpc.asm: Use powerpc syntax, not power syntax.
+
+ * tune/common.c (speed_udiv_qrnnd_preinv1, etc): Remove.
+ * tune/speed.c (routine): Remove udiv_qrnnd_preinv1, etc.
+
+2011-03-12 Marc Glisse <marc.glisse@inria.fr>
+
+ * tests/cxx/t-istream.cc: Restrict mpq test in t-istream -s.
+
+ * gmpxx.h: Remove leftover #undefs.
+
+2011-03-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (udiv_qrnnd_preinv1, udiv_qrnnd_preinv2,
+ udiv_qrnnd_preinv2gen): Remove obsolete macros.
+ (udiv_qrnnd_preinv): New name for udiv_qrnnd_preinv3.
+
+2011-03-11 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h: Declare many mpn_{sub,add}lsh*_n_ip[12] functions/macros.
+ * mpn/generic/toom_interpolate_5pts.c: Use mpn_sublsh1_n_ip1.
+
+ * tests/devel/try.c: Tests for {add,sub}lsh*_n_ip[12].
+ * tests/refmpn.c: New reference for mpn_{add,sub}lsh*_n_ip[12].
+ * tests/tests.h: Declarations for reference functions above.
+
+ * tune/common.c: New speed_mpn_{add,sub}lsh*_n_ip[12] functions.
+ * tune/speed.h: Prototypes for functions above.
+ * tune/speed.c: Support for mpn_{add,sub}lsh*_n_ip[12].
+
+ * mpn/x86/k7/sublsh1_n.asm: Replaced generic sublsh1 code with faster _ip1.
+ * mpn/x86/atom/sublsh1_n.asm: Changed PROLOGUE accordingly.
+
+ * configure.in: Define HAVE_NATIVE_mpn_addlsh*_n*_ip[12].
+ * mpn/asm-defs.m4: Declare mpn_addlsh*_n*_ip[12].
+
+2011-03-10 Marc Glisse <marc.glisse@inria.fr>
+
+ * tests/cxx/t-istream.cc: Explicit conversion to streampos.
+
+2011-03-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/atom/sse2/mul_basecase.asm: Suppress wind-down rp updates.
+
+ * Move new aorrlsh_n.asm to new k8 dir. Revert
+ mpn/x86_64/aorrlsh_n.asm.
+ * configure.in: Setup path for new k8 directory.
+
+2011-03-10 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/pentium4/sse2/bdiv_dbm1c.asm: New file, was in atom.
+ * mpn/x86/atom/sse2/bdiv_dbm1c.asm: Grab file above.
+
+2011-03-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/aorrlsh_n.asm: Complete rewrite.
+
+ * mpn/x86_64/core2/aorrlsh_n.asm: New file, grabbing another asm file.
+
+2011-03-09 Marc Glisse <marc.glisse@inria.fr>
+
+ * tests/cxx/t-ostream.cc: Use bool instead of int.
+ * tests/cxx/t-istream.cc: Likewise.
+ * tests/cxx/t-misc.cc: Likewise.
+
+ * cxx/ismpznw.cc: Don't clear eofbit.
+ * cxx/ismpq.cc: Likewise.
+ * cxx/ismpf.cc: Likewise.
+ * tests/cxx/t-istream.cc: Test accordingly.
+
+2011-03-09 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/sse2/bdiv_dbm1c.asm: New file.
+
+2011-03-09 Marc Glisse <marc.glisse@inria.fr>
+
+ * doc/gmp.texi: Remove void return type from constructors. Document
+ explicit constructors. Document mpf_class::mpf_class(mpf_t).
+
+2011-03-07 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/sse2/sqr_basecase.asm: Postponed pushes. Cleaned
+ outer loop exit.
+
+2011-03-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/gcd_1.asm: Workaround Oracle assembler bug.
+
+ * mpn/x86/atom/sse2/mul_basecase.asm: Replace addmul_1 loops.
+ Tweak outer loop rp updates.
+
+2011-03-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/atom/sse2/sqr_basecase.asm: New file.
+
+2011-03-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bdiv_dbm1c.asm: Write proper feed-in code.
+
+2011-03-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/addmul_2.asm: Rewrite for linear performance.
+
+2011-03-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mod_1_1.c (add_mssaaaa): Canonicalise layout. Add arm
+ variant. Enable sparc64 code and powerpc code (the latter for 32-bit
+ and 64-bit).
+
+ * mpn/generic/sqrtrem.c (mpn_dc_sqrtrem): Use mpn_addlsh1_n.
+
+ * gmp-impl.h (mpn_addlsh_nc, mpn_rsblsh_nc): Declare.
+ * mpn/asm-defs.m4: Likewise.
+
+ * mpn/x86_64/coreisbr/aorrlsh_n.asm: Disable mpn_rsblsh_n due to
+ carry-in issues.
+ * mpn/x86_64/coreinhm/aorrlsh_n.asm: Likewise.
+ * mpn/x86_64/coreisbr/aorrlsh2_n.asm: Likewise.
+
+2011-03-03 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/mod_1_1.c (add_mssaaaa): For x86 and x86_64, treat m
+ as in output operand only. Added sparc32 implementation. Also
+ added #if:ed out attempts at sparc64 and powerpc64.
+
+ * tune/tuneup.c (tune_mod_1): Record result of MOD_1_1P_METHOD
+ measurement for use by mpn_mod_1_tune. And omit measurement if
+ mpn_mod_1_1p is native assembly code.
+
+ * mpn/generic/mod_1.c (mpn_mod_1_1p) [TUNE_PROGRAM_BUILD]: Macro
+ to check mod_1_1p_method and call the right function.
+ (mpn_mod_1_1p_cps) [TUNE_PROGRAM_BUILD]: Likewise.
+
+ * gmp-impl.h (MOD_1_1P_METHOD) [TUNE_PROGRAM_BUILD]: Define macro.
+ (mod_1_1p_method) [TUNE_PROGRAM_BUILD]: Declare variable.
+
+2011-03-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/coreinhm/aorrlsh_n.asm: New file.
+ * mpn/x86_64/coreisbr/aorrlsh_n.asm: New file.
+
+2011-03-01 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/mod_1_1.asm (mpn_mod_1_1p_cps): Eliminated a neg and
+ two mov instructions.
+
+ * mpn/x86/k7/mod_1_1.asm (mpn_mod_1_1p_cps): Simplified
+ computation, analogous to recent x86_64/mod_1_1.asm changes.
+ (mpn_mod_1_1p): Corresponding changes. Don't shift b.
+
+ * mpn/sparc64/mod_1_4.c (mpn_mod_1s_4p_cps): Use udiv_rnnd_preinv
+ rather than udiv_rnd_preinv.
+ (mpn_mod_1s_4p): Likewise.
+
+2011-03-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/pentium4/sse2/mul_1.asm: Swap entry insns to share more code
+ between entry points.
+ * mpn/x86/pentium4/sse2/addmul_1.asm: Likewise.
+
+ * mpz/divegcd.c: Rewrite, as per Marc Glisse's suggestion. Also fix
+ problem with passing a longlong limb to a _ui function.
+
+ * gmp-impl.h (udiv_qrnnd_preinv3): Cast truth value to mask's type.
+ (udiv_rnnd_preinv): Likewise.
+ * mpn/generic/mod_1_1.c (mpn_mod_1_1p): Likewise.
+
+2011-02-28 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/mod_1_1.c (add_mssaaaa): Typo fix, define
+ add_mssaaaa, not add_sssaaaa.
+
+ * tune/tuneup.c (tune_mod_1): Measure mpn_mod_1_1_1 and
+ mpn_mod_1_1_2, to set MOD_1_1P_METHOD.
+
+ * tune/speed.c (routine): Added mpn_mod_1_1_1 and mpn_mod_1_1_2.
+
+ * tune/speed.h: Declare speed_mpn_mod_1_1_1, speed_mpn_mod_1_1_2,
+ mpn_mod_1_1p_1, mpn_mod_1_1p_2, mpn_mod_1_1p_cps_1, and
+ mpn_mod_1_1p_cps_2.
+
+ * tune/common.c (speed_mpn_mod_1_1_1): New function.
+ (speed_mpn_mod_1_1_2): New function.
+
+ * tune/Makefile.am (libspeed_la_SOURCES): Added mod_1_1-1.c
+ mod_1_1-2.c.
+
+ * tune/mod_1_1-1.c: New file.
+ * tune/mod_1_1-2.c: New file.
+
+ * mpn/generic/mod_1_1.c: Implemented an algorithm with fewer
+ multiplications, configured via MOD_1_1P_METHOD.
+
+ * mpn/x86_64/mod_1_1.asm (mpn_mod_1_1p_cps): Simplified
+ computation of B2modb, use B^2 mod (normalized b).
+ (mpn_mod_1_1p): Corresponding changes. Don't shift b.
+
+ * mpn/generic/mod_1_1.c (mpn_mod_1_1p_cps): Use udiv_rnnd_preinv rather
+ than udiv_rnd_preinv.
+ (mpn_mod_1_1p): Likewise.
+ * mpn/generic/mod_1_4.c: Analogous changes.
+ * mpn/generic/mod_1_3.c: Analogous changes.
+ * mpn/generic/mod_1_2.c: Analogous changes.
+ * mpn/generic/mod_1.c: Analogous changes.
+ * mpn/generic/pre_mod_1.c: Analogous changes.
+
+ * gmp-impl.h (udiv_qrnnd_preinv3): Eliminated unpredictable branch
+ using masking logic. Further optimization of the nl == constant 0
+ case, similar to udiv_rnd_preinv.
+ (udiv_rnnd_preinv): Likewise.
+ (udiv_rnd_preinv): Deleted, use udiv_rnnd_preinv with nl == 0
+ instead.
+
+ * tests/mpn/t-divrem_1.c (check_data): Added testcase to exercise
+ the nl == constant 0 special case in udiv_qrnnd_preinv3.
+
+2011-02-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/rootrem.c (mpn_rootrem): Combine two similar scalar
+ divisions. Misc minor cleanup.
+
+ * mpn/x86/atom/sse2/aorsmul_1.asm: Shorten software pipeline.
+
+ * mpn/x86/atom/mul_basecase.asm: Remove file no longer used.
+
+ * mpn/generic/rootrem.c (mpn_rootrem_internal): Delay O(log(U))
+ allocations until they are known to be needed.
+
+2011-02-27 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/sse2/mul_1.asm: New code.
+
+2011-02-27 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h (udiv_rnnd_preinv): New macro.
+
+2011-02-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/atom/sse2/mul_basecase.asm: New file.
+
+2011-02-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/sse2/aorsmul_1.asm: Optimise non-loop code.
+
+2011-02-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/aorsmul_1.asm: Add MULFUNC_PROLOGUE.
+ * mpn/m68k/mc68020/aorsmul_1.asm: Likewise.
+
+ * mpn/powerpc64/mode64/aorsmul_1.asm: Add missing MULFUNC_PROLOGUE.
+ * mpn/m68k/mc68020/aorsmul_1.asm: Likewise.
+
+2011-02-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/atom/sse2/aorsmul_1.asm: New file.
+ * mpn/x86/atom/aorsmul_1.asm: File removed.
+
+2011-02-25 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/sse2/divrem_1.asm: New file (was in x86/atom).
+ * mpn/x86/atom/sse2/mul_1.asm: Likewise.
+ * mpn/x86/atom/sse2/popcount.asm: Likewise.
+ * mpn/x86/atom/divrem_1.asm: ReMoved (in sse2/ now).
+ * mpn/x86/atom/mul_1.asm: Likewise.
+ * mpn/x86/atom/popcount.asm: Likewise.
+
+ * configure.in: Set up mmx path for atom.
+ * mpn/x86/atom/mmx/copyd.asm: New file (was in x86/atom).
+ * mpn/x86/atom/mmx/copyi.asm: Likewise.
+ * mpn/x86/atom/mmx/hamdist.asm: Likewise.
+ * mpn/x86/atom/copyd.asm: ReMoved (in mmx/ now).
+ * mpn/x86/atom/copyi.asm: Likewise.
+ * mpn/x86/atom/hamdist.asm: Likewise.
+
+2011-02-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/atom/sse2/mod_1_1.asm: New file.
+ * mpn/x86/atom/sse2/mod_1_4.asm: New file.
+ * configure.in: Set up sse2 path for atom.
+
+ * mpn/x86/p6/sse2/mod_1_1.asm: New file.
+ * mpn/x86/p6/sse2/mod_1_4.asm: Fix typo in MULFUNC_PROLOGUE.
+
+2011-02-24 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86/k7/mod_1_1.asm (mpn_mod_1_1p): Rewrite using the same
+ algorithm as the x86_64 version.
+
+2011-02-23 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/logops_n.asm: New file (same loop as aors_n).
+
+2011-02-23 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/mod_1_1.asm (mpn_mod_1_1p): Shaved off one
+ instruction and one register in the inner loop. Rearranged
+ registers slightly, and no longer needs the callee-save register
+ %r12.
+
+2011-02-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Export SHLD_SLOW and SHRD_SLOW to config.m4, also
+ fixing typo in exporting code.
+
+ * mpn/x86_64/nano/gmp-mparam.h (SHLD_SLOW, SHRD_SLOW): Define.
+ * mpn/x86_64/atom/gmp-mparam.h (SHLD_SLOW, SHRD_SLOW): Define.
+
+2011-02-22 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/mod_1_1.asm (mpn_mod_1_1p): Rewrite.
+
+2011-02-22 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/lshiftc.asm: New file (a copy of lshift.asm with a handful of neg added).
+
+2011-02-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/aors_n.asm: Move _nc entry to after main code. Align loop
+ and _n entry for claimed performance. Normalise mnemonic usage.
+
+ * mpn/x86/atom/aorrlsh1_n.asm: New file (code from rsblsh_1, slightly
+ slower for addlsh_1 for large operands, but much faster for small).
+ * mpn/x86/atom/addlsh1_n.asm: Remove.
+ * mpn/x86/atom/rsblsh1_n.asm: Remove.
+
+2011-02-20 Marc Glisse <marc.glisse@inria.fr>
+
+ * mpq/aors.c: Rewrite to remove redundant division.
+
+2011-02-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/atom/lshift.asm: New file.
+ * mpn/x86/atom/rshift.asm: Normalise mnemonic usage.
+
+ * gmp-impl.h (mpn_divexact_by7): Relax inclusion condition.
+
+ * mpz/divegcd.c (mpz_divexact_by5): New conditionally enabled function.
+ (mpz_divexact_by3): Wrap inside appropriate conditions.
+ (mpz_divexact_gcd): Rewrite.
+
+ * mpn/x86/bdiv_dbm1c.asm: Save a jump.
+
+2011-02-20 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/aorslshC_n.asm: New file.
+ * mpn/x86/atom/sublsh2_n.asm: New file.
+
+ * mpn/x86/atom/aors_n.asm: New code.
+ * mpn/x86/atom/rshift.asm: Atom64 code adapted to 32-bit.
+ * mpn/x86/atom/lshift.asm: Likewise.
+
+2011-02-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/rsh1aors_n.asm: New file.
+
+ * mpn/x86_64/atom/lshift.asm: New file.
+ * mpn/x86_64/atom/rshift.asm: New file.
+ * mpn/x86_64/atom/lshiftc.asm: New file.
+
+2011-02-17 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/aorsmul_1.asm: Small improvements for small sizes.
+ * mpn/x86/atom/aorrlshC_n.asm: Tiny size improvements.
+
+2011-02-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Fix k8/k10 32-bit path setup problem.
+
+2011-02-16 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/aorsmul_1.asm: Revive an old k7/aorsmul.
+
+2011-02-14 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h (mpn_sublsh_n): Declare.
+ * mpn/asm-defs.m4: Likewise.
+
+ * mpn/x86/atom/aorrlshC_n.asm: New file (was k7).
+ * mpn/x86/k7/aorrlshC_n.asm: ReMoved.
+ * mpn/x86/atom/aorrlsh2_n.asm: Grab atom/aorrlshC_n.asm.
+ * mpn/x86/atom/rsblsh1_n.asm: Grab atom/aorrlshC_n.asm.
+
+2011-02-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/aorrlsh2_n.asm: New file.
+
+2011-02-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/aorrlsh_n.asm: Minor tweaks, update c/l numbers.
+
+ * mpn/x86_64/atom/sublsh1_n.asm: New file.
+
+ * mpn/x86_64/atom/aorrlsh1_n.asm: New file.
+
+2011-02-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/mod_1_1.asm: Fix Darwin syntax issues.
+
+2011-02-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/mod_1_4.asm: Tune away a cycle for 970.
+
+2011-02-11 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/k7/addlsh1_n.asm: Faster core loop (Torbjorn's).
+
+ * configure.in: Add HAVE_NATIVE_{add,sub,rsb}lsh{,1,2}_nc.
+ * tests/tests.h: refmpn_{add,sub,rsb}lsh{,1,2}_nc prototypes.
+ * tests/refmpn.c: New refmpn_{add,sub,rsb}lsh{,1,2}_nc.
+ * tests/devel/try.c: Tests for mpn_{add,sub,rsb}lsh{,1,2}_nc.
+
+ * mpn/x86/k7/aorrlshC_n.asm: New file.
+ * mpn/x86/atom/aorrlsh2_n.asm: Grab k7/aorrlshC_n.asm.
+ * mpn/x86/atom/rsblsh1_n.asm: Grab k7/aorrlshC_n.asm.
+
+2011-02-06 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/k7/addlsh1_n.asm: New file.
+ * mpn/x86/k7/sublsh1_n.asm: New file.
+ * mpn/x86/atom/addlsh1_n.asm: Grab k7/addlsh1_n.asm.
+ * mpn/x86/atom/sublsh1_n.asm: Grab k7/sublsh1_n.asm.
+
+2011-02-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (mpn_addlsh1_nc, mpn_addlsh2_nc, mpn_sublsh1_nc,
+ mpn_sublsh2_nc, mpn_rsblsh1_nc, mpn_rsblsh2_nc): Declare.
+ * mpn/asm-defs.m4: Likewise.
+
+ * mpn/x86_64/coreisbr/aorrlshC_n.asm: New file.
+ * mpn/x86_64/coreisbr/aorrlsh1_n.asm: New file.
+ * mpn/x86_64/coreisbr/aorrlsh2_n.asm: New file.
+
+ * mpn/x86_64/coreisbr/aors_n.asm: New file, based on old
+ atom/aors_n.asm.
+ * mpn/x86_64/atom/aors_n.asm: Grab coreisbr/aors_n.asm.
+
+2011-02-05 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h (mpn_toom6_mul_n_itch): Handle threshold == zero.
+ (mpn_toom8_mul_n_itch): Likewise.
+ (MPN_TOOM6H_MIN, MPN_TOOM8H_MIN): Define.
+ * tests/mpn/t-toom6h.c: No tests below MPN_TOOM6H_MIN.
+ * tests/mpn/t-toom8h.c: No tests below MPN_TOOM8H_MIN.
+
+ * mpz/lucnum_ui.c: Use mpn_addlsh2_n.
+
+2011-02-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/rsh1aors_n.asm: Add a MULFUNC_PROLOGUE.
+ * mpn/x86_64/atom/dive_1.asm: Likewise.
+ * mpn/x86_64/atom/popcount.asm: Likewise.
+ * mpn/x86_64/core2/popcount.asm: Likewise.
+ * mpn/x86_64/coreinhm/hamdist.asm: Likewise.
+ * mpn/x86_64/coreinhm/popcount.asm: Likewise.
+ * mpn/x86_64/nano/popcount.asm: Likewise.
+ * mpn/x86_64/pentium4/popcount.asm: Likewise.
+
+2011-02-04 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/mode1o.asm: New file, grabbing another asm file.
+ * mpn/x86/atom/mul_1.asm: Claim mul_1c.
+
+2011-02-02 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_HGCD_CALL): Fixed one
+ speed_operand_dst call.
+
+2011-02-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.h (struct speed_params): Allow for 4 dst operands.
+ * tune/common.c (TOLERANCE): Increase from 0.5% to 1%.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_HGCD_CALL): New macro, mainly based
+ on old speed_mpn_hgcd, but with speed_operand_src calls (as suggested
+ by Niels).
+ * tune/common.c (speed_mpn_hgcd): Invoke SPEED_ROUTINE_MPN_HGCD_CALL.
+ (speed_mpn_hgcd_lehmer): Likewise.
+
+ * configure.in: Set up 32-bit x86 paths for new corei* CPU strings.
+
+2011-01-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Recognise new Intel processors.
+
+ * config.guess: Support 'coreinhm' and 'coreisbr'.
+ * config.sub: Likewise.
+ * configure.in: Likewise.
+
+2011-01-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Support x86/geode.
+ * mpn/x86/geode/gmp-mparam.h: New file.
+
+2011-01-29 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/addlsh1_n.asm: Removed.
+ * mpn/x86/atom/rsh1add_n.asm: Likewise.
+
+2011-01-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/alpha/ev6/slot.pl: Add some missing insns.
+
+2011-01-28 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/atom/copyd.asm: New file, grabbing another asm file.
+ * mpn/x86/atom/copyi.asm: Likewise.
+ * mpn/x86/atom/aors_n.asm: Likewise.
+ * mpn/x86/atom/addlsh1_n.asm: Likewise.
+ * mpn/x86/atom/aorsmul_1.asm: Likewise.
+ * mpn/x86/atom/bdiv_q_1.asm: Likewise.
+ * mpn/x86/atom/dive_1.asm: Likewise.
+ * mpn/x86/atom/divrem_1.asm: Likewise.
+ * mpn/x86/atom/hamdist.asm: Likewise.
+ * mpn/x86/atom/logops_n.asm: Likewise.
+ * mpn/x86/atom/lshift.asm: Likewise.
+ * mpn/x86/atom/mod_34lsub1.asm: Likewise.
+ * mpn/x86/atom/mul_1.asm: Likewise.
+ * mpn/x86/atom/mul_basecase.asm: Likewise.
+ * mpn/x86/atom/popcount.asm: Likewise.
+ * mpn/x86/atom/rsh1add_n.asm: Likewise.
+ * mpn/x86/atom/rshift.asm: Likewise.
+ * mpn/x86/atom/sqr_basecase.asm: Likewise.
+
+2011-01-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/rsh1aors_n.asm: New file, grabbing another asm file.
+ * mpn/x86_64/atom/popcount.asm: Likewise.
+ * mpn/x86_64/atom/dive_1.asm: Likewise.
+ * mpn/x86_64/nano/popcount.asm: Likewise.
+
+2011-01-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/alpha/invert_limb.asm: Complete rewrite.
+
+2011-01-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc32/invert_limb.asm: New file.
+
+2011-01-25 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/pentium4/sse2/bdiv_q_1.asm: New file.
+ * mpn/x86/k7/bdiv_q_1.asm: New file.
+
+2011-01-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mul_n, tune_sqr): Loop, re-measuring thresholds
+ until no tiny ranges remain.
+
+2011-01-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/ia64/mul_2.asm: Tweak to 1.5 c/l, less overhead.
+
+ * mpn/ia64/addmul_2.asm: Rewrite, adding mpn_addmul_2s entry point.
+
+2011-01-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/ia64/aors_n.asm: Fix some incorrect bundle types.
+
+ * mpn/ia64/sqr_diagonal.asm: Remove.
+
+ * mpn/ia64/sqr_diag_addlsh1.asm: New file.
+
+ * mpn/ia64/ia64-defs.m4: Define some shorter convenience mnemonics.
+
+ * mpn/generic/sqr_basecase.c (MPN_SQR_DIAG_ADDLSH1): New macro, using
+ new function mpn_sqr_diag_addlsh1 or defining its equivalent.
+
+ * gmp-impl.h (mpn_addmul_2s): Declare.
+ (mpn_sqr_diag_addlsh1): Declare.
+ * mpn/asm-defs.m4 (define_mpn): Add addmul_2s and sqr_diag_addlsh1.
+
+ * configure.in: Add HAVE_NATIVEs for mpn_sqr_diag_addlsh1 and
+ mpn_addmul_2s.
+ (gmp_mpn_functions_optional): Add sqr_diag_addlsh1.
+
+2011-01-21 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/devel/try.c: Initial support for mpn_bdiv_q_1.
+ * mpn/x86/pentium/bdiv_q_1.asm: New file.
+ * mpn/x86/p6/bdiv_q_1.asm: New file.
+
+2011-01-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.c (run_gnuplot): Update to current gnuplot syntax.
+
+ * mpn/powerpc64/mode64/aorsmul_1.asm: Trim away 0.5 c/l for submul_1
+ for POWER5.
+
+2011-01-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/core2/rsh1aors_n.asm: New file.
+
+2011-01-18 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/x86/bdiv_q_1.asm: New file (same core alg. as dive_1).
+
+2011-01-15 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/divexact.c: Avoid COPY if not needed.
+
+2011-01-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (struct cpuvec_t): Add field bmod_1_to_mod_1_threshold.
+ * configure.in (fat_thresholds): Add BMOD_1_TO_MOD_1_THRESHOLD.
+
+2011-01-13 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/mul.c: Remove redundant size computation.
+
+2011-01-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/devel/try.c (types enum): Add TYPE_MUL_5 and TYPE_MUL_6.
+ (param_init): Support new types.
+ (choice_array): Support testing of mpn_mul_5 and mpn_mul_6.
+ (call): Support new routines.
+
+ * tests/refmpn.c (refmpn_mul_5, refmpn_mul_6): New functions.
+ * tests/tests.h (refmpn_mul_5, refmpn_mul_6): Declare.
+ Remove parameter names from some other functions.
+
+ * gmp-impl.h (mpn_mul_5, mpn_mul_6): Declare.
+ * mpn/asm-defs.m4: Likewise, also declare mpn_addmul_5, mpn_addmul_6,
+ mpn_addmul_7, and mpn_addmul_8.
+
+ * configure.in (gmp_mpn_functions_optional): Add mul_5 and mul_6.
+
+ * tune/speed.c (routine): Add measuring of mpn_mul_5 and mpn_mul_6.
+ * tune/common.c (speed_mpn_mul_5, speed_mpn_mul_6): New functions.
+ * tune/speed.h: Declare new functions.
+
+2011-01-03 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpz/aors.h: Remove #ifdef BERKELEY_MP, and cleanup.
+ * mpz/cmp.c: Likewise.
+ * mpz/gcd.c: Likewise.
+ * mpz/mul.c: Likewise.
+ * mpz/powm.c: Likewise.
+ * mpz/set.c: Likewise.
+ * mpz/sqrtrem.c: Likewise.
+ * mpz/tdiv_qr.c: Likewise.
+
+2010-12-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/minithres/gmp-mparam.h: Update with several recent thresholds.
+
+2010-12-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/mod_1_1.asm: Canonicalise cmov forms.
+ * mpn/x86/k7/mod_1_4.asm: Likewise.
+ * mpn/x86/pentium4/sse2/mod_1_1.asm: Likewise.
+ * mpn/x86/pentium4/sse2/mod_1_4.asm: Likewise.
+ * mpn/x86_64/core2/divrem_1.asm: Likewise.
+ * mpn/x86_64/divrem_1.asm: Likewise.
+ * mpn/x86_64/mod_1_1.asm: Likewise.
+ * mpn/x86_64/mod_1_2.asm: Likewise.
+ * mpn/x86_64/mod_1_4.asm: Likewise.
+
+ * mpn/x86/k7/gcd_1.asm: Rewrite. Remove slow 'div' loop. Call
+ mpn_mod_1 for operands with mode than BMOD_1_TO_MOD_1_THRESHOLD limbs.
+ Misc cleanups.
+
+2010-12-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/gcd_1.asm: Call mpn_mod_1 for operands with mode than
+ BMOD_1_TO_MOD_1_THRESHOLD limbs.
+
+ * configure.in: Generalise code for putting THRESHOLDs in config.m4.
+ Add BMOD_1_TO_MOD_1_THRESHOLD to list.
+
+ * mpn/x86_64/core2/divrem_1.asm: Tweak slightly, correct cycle counts.
+
+ * mpn/x86_64/addmul_2.asm: Remove constant index.
+ * mpn/x86_64/lshiftc.asm: Likewise.
+ * mpn/x86_64/pentium4/lshift.asm: Likewise.
+ * mpn/x86_64/pentium4/lshiftc.asm: Likewise.
+ * mpn/x86_64/pentium4/rshift.asm: Likewise.
+
+2010-12-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mod_34lsub1.asm: Complete rewrite.
+ * mpn/x86_64/pentium4/mod_34lsub1.asm: New file, old
+ mpn/x86_64/mod_34lsub1.asm.
+
+2010-12-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/vmx/popcount.asm: Rewrite to use vperm count table.
+
+2010-12-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * mp-h.in: Remove.
+ * configure.in: Remove mp-h.in from AC_OUTPUT invocation.
+
+2010-12-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/mod.c: Rewrite.
+
+ * mpn/x86_64/corei/popcount.asm: New file.
+ * mpn/x86_64/corei/hamdist.asm: New file.
+
+ * mpn/x86_64/k10/hamdist.asm: New file.
+
+ * configure.in: Amend last change for lame /bin/sh.
+
+2010-12-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Comment out M4=m4-not-needed.
+
+ * mpn/x86_64/k10/popcount.asm: New file.
+ * configure.in: Setup special path for k10 and later AMD CPUs.
+ Remove special x86_64'k8' path, since directory is non-existent.
+
+2010-12-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc32/ultrasparct1: New directory.
+ * mpn/sparc32/ultrasparct1/add_n.asm: New file.
+ * mpn/sparc32/ultrasparct1/sub_n.asm: New file.
+ * mpn/sparc32/ultrasparct1/mul_1.asm: New file.
+ * mpn/sparc32/ultrasparct1/addmul_1.asm: New file.
+ * mpn/sparc32/ultrasparct1/submul_1.asm: New file.
+ * mpn/sparc32/ultrasparct1/sqr_diagonal.asm: New file.
+
+ * config.guess: Support Ultrasparc T2 and T3.
+ * config.sub: Likewise.
+ * configure.in: Likewise.
+
+ * config.guess: Generalise BSD Sparc recognition by allowing any
+ caps (needed for OpenBSD which spells things innovatively).
+
+2010-12-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Match new AMD processors, allow finer distinctions
+ among old ones.
+ * acinclude.m4 (X86_64_PATTERN): Likewise.
+ * config.sub: Likewise.
+ * configure.in: Rudimentarily support new AMD processors.
+
+ * configure.in (--enable_assembly): New option.
+ (target none-*-*): Disable, give error.
+
+2010-11-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/x86-defs.m4 (LEA): Support non-PIC code.
+ * mpn/x86/darwin.m4 (LEA): Likewise.
+
+ * tests/amd64call.asm: Rewrite for code size, and to match calls and
+ returns.
+
+ * tests/x86call.asm: Rewrite for code size, to support PIC, and to
+ match calls and returns.
+ * tests/x86check.c: Rewrite.
+
+2010-11-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/get_str.c: Make all bases either work or return an error.
+ * mpz/out_str.c: Likewise.
+ * mpq/get_str.c: Likewise.
+ * mpf/get_str.c: Likewise.
+
+2010-11-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/misc/t-printf.c: Add explicit casts for type conversions.
+ * mpn/generic/toom62_mul.c: Likewise.
+
+2010-11-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/get_d.c: Misc cleanup. Fail with a syntax error for
+ non-IEEE fp formats.
+
+ * tests/devel/try.c (malloc_region): Add explicit casts for type
+ conversions.
+
+ * acinclude.m4 (GMP_ASM_RODATA): Make test code snippet C++ compatible.
+ (GMP_C_DOUBLE_FORMAT): Likewise.
+ (GMP_FUNC_VSNPRINTF): Likewise.
+
+ * config.guess (x86): Make test C snippet C++ compatible.
+
+2010-11-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * Makefile.am: Remove mpbsd.
+ * configure.in: Remove mpbsd.
+ * doc/configuration: Remove mpbsd mentions.
+ * doc/gmp.texi: Remove mpbsd docs.
+ * tests/Makefile.am: Remove mpbsd.
+ * libmp.sym: Remove.
+ * mpbsd: Remove directory and files.
+ * tests/mpbsd: Remove directory and files.
+
+2010-11-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/aors_n.asm: Don't rely on ZF after 'bt' insn.
+ Use 64-bit 'test' to support operands of 2^32 limbs and more.
+
+ * rand: New directory, move rand*.c and randmt.h here.
+ * rand/Makefile.am: New file.
+ * Makefile.am (SUBDIRS): Add rand.
+ (RANDOM_OBJECTS): New variable.
+ (libgmp_la_SOURCES): Remove random objects.
+ (libgmp_la_DEPENDENCIES): Add RANDOM_OBJECTS.
+ * configure.in (AC_OUTPUT): Add rand/Makefile.
+
+ * ansi2knr.1: File removed.
+ * ansi2knr.c: File removed.
+
+2010-11-10 Torbjorn Granlund <tege@gmplib.org>
+
+ Make it possible to compile GMP with g++:
+
+ * gmp-impl.h: Declare __gmp_digit_value_tab here.
+ * mpbsd/min.c: ...not here.
+ * mpbsd/xtom.c: ...nor here.
+ * mpf/set_str.c: ...nor here.
+ * mpz/inp_str.c: ...nor here.
+ * mpz/set_str.c: ...nor here.
+
+ * mpn/generic/toom43_mul.c: Add casts for logical operations on enums.
+ * mpn/generic/toom44_mul.c: Likewise.
+ * mpn/generic/toom4_sqr.c: Likewise.
+ * mpn/generic/toom52_mul.c: Likewise.
+ * mpn/generic/toom53_mul.c: Likewise.
+ * mpn/generic/toom62_mul.c: Likewise.
+
+ * mpz/clrbit.c: Clean up typing using MPZ_REALLOC.
+ * mpz/setbit.c: Likewise.
+
+ * mpz/powm.c: Avoid variable name 'new'.
+
+ * randlc2x.c: Add explicit casts for type conversions.
+ * tests/misc/t-printf.c: Likewise.
+ * tests/misc/t-scanf.c: Likewise.
+ * tests/misc.c: Likewise.
+ * tests/mpz/convert.c: Likewise.
+ * tests/refmpn.c: Likewise.
+
+ * tests/tests.h: Unconditionally use <sstream> for now.
+
+ * tests/memory.c: Include "tests.h.
+
+ * mp_get_fns.c: Add a __GMP_NOTHROW for coherency with prototype.
+ * mp_set_fns.c: Likewise.
+ * mpf/cmp.c: Likewise.
+ * mpf/cmp_si.c: Likewise.
+ * mpf/cmp_ui.c: Likewise.
+ * mpf/fits_s.h: Likewise.
+ * mpf/fits_u.h: Likewise.
+ * mpf/get_dfl_prec.c: Likewise.
+ * mpf/get_prc.c: Likewise.
+ * mpf/get_si.c: Likewise.
+ * mpf/get_ui.c: Likewise.
+ * mpf/int_p.c: Likewise.
+ * mpf/set_dfl_prec.c: Likewise.
+ * mpf/set_prc_raw.c: Likewise.
+ * mpf/size.c: Likewise.
+ * mpf/swap.c: Likewise.
+ * mpq/equal.c: Likewise.
+ * mpq/swap.c: Likewise.
+ * mpz/cmp.c: Likewise.
+ * mpz/cmp_si.c: Likewise.
+ * mpz/cmp_ui.c: Likewise.
+ * mpz/cmpabs.c: Likewise.
+ * mpz/cmpabs_ui.c: Likewise.
+ * mpz/cong_2exp.c: Likewise.
+ * mpz/divis_2exp.c: Likewise.
+ * mpz/fits_s.h: Likewise.
+ * mpz/get_si.c: Likewise.
+ * mpz/hamdist.c: Likewise.
+ * mpz/scan0.c: Likewise.
+ * mpz/scan1.c: Likewise.
+ * mpz/sizeinbase.c: Likewise.
+ * mpz/swap.c: Likewise.
+ * mpz/tstbit.c: Likewise.
+ * tal-reent.c: Likewise.
+
+2010-11-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Get rid of K&R support.
+ * Makefile.am: Likewise.
+ * mpn/Makefile.am: Likewise.
+ * doc/configuration: Update docs wrt K&R support.
+ * doc/gmp.texi: Likewise.
+
+ * configure.in (AC_INIT): Amend bug reporting address with manual
+ reference.
+
+2010-11-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: If cpuid says we have 32bit-only x86 but
+ configfsf.guess return x86_64, return the latter.
+
+ * mpn/x86_64/aors_n.asm: Rewrite not to rely on ZF after 'bt' insn.
+
+2010-10-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/trialdiv.c: Update documentation.
+
+2010-10-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/gcd_1.asm: Use m4_lshift to avoid << operator.
+ * mpn/x86_64/aorrlshC_n.asm: Likewise.
+ * mpn/x86_64/pentium4/aorslshC_n.asm: Likewise.
+ * mpn/x86/k7/gcd_1.asm: Likewise.
+
+2010-08-20 Niels Möller <nisse@lysator.liu.se>
+
+ Suggested by Ozkan Sezer:
+ * configure.in: If $M4 is already set in the environment, don't
+ touch it. Fixed the case that no assembler files are used, and
+ GMP_PROG_M4 is omitted.
+
+2010-08-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/fat/fat.c: Recognise many more processors.
+
+2010-06-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/divrem_2.asm: Tune.
+
+2010-06-19 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_MOD_1_1): Pass normalized
+ divisor to the benchmarked function.
+
+2010-06-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mod_1_1.asm (mpn_mod_1_1p_cps): Rewrite.
+ * mpn/x86_64/mod_1_2.asm (mpn_mod_1s_2p_cps): Rewrite.
+ * mpn/x86_64/mod_1_4.asm (mpn_mod_1s_4p_cps): Rewrite.
+
+ * gmp-impl.h (udiv_rnd_preinv): Simplify.
+
+ * mpn/x86/k7/mod_1_1.asm: New file.
+ * mpn/x86/pentium4/sse2/mod_1_1.asm (mpn_mod_1_1p_cps): Rewrite.
+ * mpn/x86/k7/mod_1_4.asm (mpn_mod_1s_4p_cps): Rewrite.
+ * mpn/x86/pentium4/sse2/mod_1_4.asm (mpn_mod_1s_4p_cps): Rewrite.
+
+ * mpn/generic/mod_1_1.c (mpn_mod_1_1p_cps): Store results as they are
+ computed.
+ * mpn/generic/mod_1_2.c (mpn_mod_1s_2p_cps): Likewise.
+ * mpn/generic/mod_1_4.c (mpn_mod_1s_4p_cps): Likewise.
+
+ * mpn/x86/k7/invert_limb.asm: Moved from mpn/x86/invert_limb.asm.
+
+2010-06-15 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-mod_1.
+ * tests/mpn/t-mod_1.c: New file.
+
+2010-05-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mu_div_qr.c (mpn_preinv_mu_div_qr_itch): Trim out space
+ for inverse, since that is passed in already.
+
+2010-05-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mu_div_qr.c (mpn_preinv_mu_div_qr_itch): New function.
+ * gmp-impl.h: Declare it.
+ * tune/common.c (speed_mpn_mupi_div_qr): Use new itch function.
+ * tune/speed.h (SPEED_ROUTINE_MPN_MUPI_DIV_QR): Pass parameters right
+ for new itch function.
+
+ * mpn/powerpc32/lshiftc.asm: New file.
+
+2010-05-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mod_1): Revert to version of 2010-05-06.
+
+2010-05-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (ia64): Get 32-bit sizeof test right.
+
+ * tune/tuneup.c (tune_mod_1): Undo unintensional change to tuning of
+ PREINV_MOD_1_TO_MOD_1_THRESHOLD.
+
+2010-05-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/mod_1.c: Rewrite.
+ * mpn/sparc64/sparc64.h (umul_ppmm_s): New macro.
+ * mpn/sparc64/mod_1_4.c: New file.
+
+ * mpn/generic/divrem_1.c: Minor cleanup.
+ * mpn/generic/mod_1.c: Likewise.
+ * mpn/generic/mod_1_1.c: Likewise.
+ * mpn/generic/mod_1_2.c: Likewise.
+ * mpn/generic/mod_1_3.c: Likewise.
+ * mpn/generic/mod_1_4.c: Likewise.
+
+ * configure.in (ia64-hpux): Do sizeof tests for 32-bit and 64-bit ABI.
+
+ * tune/tuneup.c (tune_mod_1): Completely finish MOD_1_N tuning before
+ tuning MOD_1U_TO_MOD_1_1_THRESHOLD.
+
+2010-05-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/redc_2.c: Use asm code just for GNU C.
+
+2010-05-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64/ultrasparc1234: New directory. Move all code that uses
+ floating-point into this directory.
+ * configure.in: Point to ultrasparc1234 for appropriate CPUs.
+
+ * mpn/sparc64/ultrasparct1/add_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/addlsh2_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/addmul_1.asm: New file.
+ * mpn/sparc64/ultrasparct1/lshift.asm: New file.
+ * mpn/sparc64/ultrasparct1/mul_1.asm: New file.
+ * mpn/sparc64/ultrasparct1/rsblsh2_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/rshift.asm: New file.
+ * mpn/sparc64/ultrasparct1/sublsh1_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/sublshC_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/addlsh1_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/addlshC_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/lshiftc.asm: New file.
+ * mpn/sparc64/ultrasparct1/rsblsh1_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/rsblshC_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/sub_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/sublsh2_n.asm: New file.
+ * mpn/sparc64/ultrasparct1/submul_1.asm: New file.
+ * mpn/sparc64/ultrasparct1/gmp-mparam.h: New file.
+
+ * configure.in: Give ultrasparct1 and ultrasparct2 special code path.
+
+ * mpn/x86_64/pentium4/gmp-mparam.h: Disable mpn_addlsh_n, mpn_rsblsh_n.
+
+2010-05-12 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/jacobi.c (mpz_jacobi): Fixed off-by-one error in use of
+ scratch space.
+
+ * tune/common.c (speed_mpz_powm_sec): New function.
+ * tune/speed.h: Declare speed_mpz_powm_sec.
+ * tune/speed.c (routine): Added speed_mpz_powm_sec.
+
+ * tune/common.c (speed_mpn_addlsh_n, speed_mpn_sublsh_n)
+ (speed_mpn_rsblsh_n): New functions.
+ * tune/speed.h: Declare new functions.
+ * tune/speed.c (routine): Add new functions.
+
+2010-05-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mod_1_4.asm: Tune for more processors.
+
+ * mpn/x86_64/pentium4/lshiftc.asm: New file.
+
+2010-05-11 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/jacobi.c (mpz_jacobi): Deleted old implementation.
+ Reorganized new implementation, to handle small inputs efficiently.
+
+ * tests/mpz/t-jac.c (check_large_quotients): Reduced test sizes.
+ (check_data): One more input pair related to a fixed bug.
+ (main): Enable check_large_quotients.
+
+2010-05-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/aorrlsh2_n.asm: Fix typo.
+
+2010-05-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/aorrlshC_n.asm: New file based on aorrlsh2_n.asm.
+ * mpn/x86_64/aorrlsh2_n.asm: Now just include aorrlshC_n.asm.
+ * mpn/x86_64/core2/aorrlsh1_n.asm: New file, include ../aorrlshC_n.asm.
+ * mpn/x86_64/core2/aorrlsh2_n.asm: Likewise.
+
+ * mpn/x86_64/core2/sublshC_n.asm: New file based on aorslsh1_n.asm.
+ * mpn/x86_64/core2/aorslsh1_n.asm: Remove.
+ * mpn/x86_64/core2/sublsh1_n.asm: Just include sublshC_n.asm.
+ * mpn/x86_64/core2/sublsh2_n.asm: Likewise.
+
+2010-05-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/gmp-mparam.h: Disable mpn_rsh1add_n, mpn_rsh1sub_n.
+
+ * mpn/x86_64/pentium4/aorslshC_n.asm: New file based on aorslsh1_n.asm.
+ * mpn/x86_64/pentium4/aorslsh1_n.asm: Now just include aorslshC_n.asm.
+ * mpn/x86_64/pentium4/aorslsh2_n.asm: New file.
+
+2010-05-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/sparc64: Support operands of >= 2^32 limbs.
+
+ * mpn/sparc64/lshiftc.asm: New file.
+
+ * mpn/ia64/divrem_2.asm: Complete rewrite.
+
+2010-05-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (all): Don't call tune_divrem_2.
+
+ * mpn/generic/divrem_2.c: Complete rewrite.
+
+ * tune/tuneup.c (tune_mod_1): Fix typo.
+
+2010-05-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mod_1_1.asm (mpn_mod_1_1p): Use macro register names.
+ (mpn_mod_1_1p_cps): Rewrite.
+
+ * mpn/generic/mod_1_1.c (mpn_mod_1_1p_cps): Micro-optimise.
+
+ * longlong.h: Undo 2009-03-01 change for powerpc64, it gives poor code.
+
+ * mpn/x86/pentium4/sse2/mod_1_1.asm: New file.
+
+ * mpn/powerpc64/mode64/mod_1_1.asm: New file.
+
+ * tune/tuneup.c (tune_mod_1): Use more typical divisor, for the benefit
+ of machines with early-out multipliers.
+
+2010-05-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mod_1): Fix typo.
+
+ * mpn/generic/mod_1_1.c: Undo last change.
+ * mpn/x86_64/mod_1_1.asm: Likewise.
+
+2010-05-03 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/jacobi_lehmer.c (jacobi_hook): New function.
+ (mpn_jacobi_subdiv_step): Deleted function.
+ (mpn_jacobi_lehmer): Use general mpn_gcd_subdiv_step.
+
+ * mpn/generic/gcd_subdiv_step.c (mpn_gcd_subdiv_step): Reorganized
+ to use a single hook function.
+ * mpn/generic/gcdext.c (mpn_gcdext): Adapted to new hook
+ interface.
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_hook): New unified hook
+ function.
+ * mpn/generic/gcd.c (gcd_hook): Renamed from gcd_done, and adapted
+ to new hook interface.
+ * gmp-impl.h (gcd_subdiv_step_hook): New typedef, now a function
+ type, not a struct.
+ (mpn_gcdext_hook): Declare.
+
+2010-05-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mod_1_1.c: Avoid multiply for 2 limb feed-in.
+ * mpn/generic/mod_1_2.c: Likewise.
+ * mpn/generic/mod_1_3.c: Likewise.
+ * mpn/generic/mod_1_4.c: Likewise.
+ * mpn/x86_64/mod_1_1.asm: Likewise.
+ * mpn/x86_64/mod_1_2.asm: Likewise.
+ * mpn/x86_64/mod_1_4.asm: Likewise.
+ * mpn/x86/k7/mod_1_4.asm: Likewise.
+ * mpn/x86/pentium4/sse2/mod_1_4.asm: Likewise.
+ * mpn/alpha/ev6/mod_1_4.asm: Likewise.
+
+ * tune/tuneup.c (tune_mod_1): Measure MOD_1_1_TO_MOD_1_2_THRESHOLD and
+ MOD_1_2_TO_MOD_1_4_THRESHOLD before MOD_1U_TO_MOD_1_1_THRESHOLD for
+ correctness.
+
+ * mpn/powerpc64/sqr_diagonal.asm: Complete rewrite.
+
+ * mpn/powerpc64/mode64/mod_1_4.asm: New file.
+
+2010-05-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Recognise power7.
+
+ * configure.in: Major overhaul of powerpc support.
+
+ * mpn/powerpc64/p6/lshift.asm: New file.
+ * mpn/powerpc64/p6/lshiftc.asm: Likewise.
+ * mpn/powerpc64/p6/rshift.asm: Likewise.
+
+2010-04-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (powerpc64): Support CPU specific mode-less subdirs.
+
+ * mpn/powerpc64/aix.m4 (PROLOGUE_cpu): Use "named csect" making
+ requested alignment actually honoured.
+
+2010-04-30 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/jacobi_lehmer.c (mpn_jacobi_2): Fixed handling of
+ the case bl == 1. Fixed missing application of reciprocity.
+
+2010-04-29 Niels Möller <nisse@lysator.liu.se>
+
+ * configure.in (gmp_mpn_functions): Deleted gcdext_subdiv_step.
+
+ * mpn/generic/gcdext.c (mpn_gcdext): Use new generalized
+ mpn_gcd_subdiv_step.
+
+ * mpn/generic/gcdext_lehmer.c (gcdext_update): New function.
+ (gcdext_done): New function.
+ (gcdext_hook): New const hook struct.
+ (mpn_gcdext_lehmer_n): Use new generalized mpn_gcd_subdiv_step.
+
+ * mpn/generic/gcd.c (gcd_done): New function.
+ (gcd_hook): New const hook struct.
+ (mpn_gcd): Adapted to new mpn_gcd_subdiv_step interface.
+
+ * mpn/generic/gcd_subdiv_step.c (mpn_gcd_subdiv_step): Reorganized
+ function. Added hook function pointers to the argument list, so
+ the same function can be used for gcd, gcdext, and jacobi.
+
+ * gmp-impl.h (struct gcd_subdiv_step_hook): New struct.
+ (mpn_gcdext_subdiv_step): Deleted prototype.
+ (struct gcdext_ctx): New struct.
+ (gcdext_hook): Declare const struct.
+ (mpn_gcd_subdiv_step): Updated prototype.
+
+ * mpn/generic/gcdext_subdiv_step.c: Deleted file.
+
+2010-04-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/lshift.asm: Rewrite.
+ * mpn/powerpc64/rshift.asm: Likewise.
+ * mpn/powerpc64/mode64/lshiftc.asm: New file.
+
+ * mpn/powerpc64/aix.m4: Align functions to 32-byte boundary.
+ * mpn/powerpc64/darwin.m4: Likewise.
+ * mpn/powerpc64/elf.m4: Likewise.
+
+2010-04-28 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-jac.c (check_data): Added some more test cases.
+
+ * mpn/generic/jacobi_lehmer.c (mpn_jacobi_2): Bugfix, count
+ trailing zeros, not leading.
+
+2010-04-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/p6/mul_basecase.asm: New file.
+
+2010-04-23 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h (MPN_GCD_LEHMER_N_ITCH): Deleted.
+ (mpn_gcd_lehmer_n): Deleted declaration.
+
+ * mpn/generic/gcd.c (gcd_2): Moved from gcd_lehmer.c.
+ (mpn_gcd): Inlined the code from mpn_gcd_lehmer_n. Also use
+ MPN_GCD_SUBDIV_STEP_ITCH rather than MPN_GCD_LEHMER_N_ITCH.
+
+2010-04-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/bdiv_dbm1c.asm: Swap multiply insns to make them
+ consecutive, for the benefit of POWER6.
+
+ * mpn/powerpc64/mode64/p6/gmp-mparam.h: New file.
+
+2010-04-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/gcd_lehmer.c: Deleted file.
+
+ * mpn/powerpc64/mode64/divrem_1.asm: Swap multiply insns to make them
+ consecutive, for the benefit of POWER6.
+ * mpn/powerpc64/mode64/dive_1.asm: Likewise.
+ * mpn/powerpc64/mode64/divrem_2.asm: Likewise.
+ * mpn/powerpc64/mode64/mul_1.asm: Likewise.
+ * mpn/powerpc64/mode64/aorsmul_1.asm: Likewise.
+
+ * mpn/powerpc64/mode64/aorslshC_n.asm: Swap ldx operands as a temporary
+ workaround for POWER6 pipeline glitch.
+
+2010-04-19 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/jacobi.c (mpz_jacobi): New implementation using
+ mpn_jacobi_lehmer. Currently #if:ed out.
+
+ * mpn/generic/jacbase.c (mpn_jacobi_base)
+ [JACOBI_BASE_METHOD < 4]: Support inputs with a >= b.
+
+ * gmp-impl.h (mpn_jacobi_lehmer): Added prototype.
+ (jacobi_table): Declare.
+ (mpn_jacobi_init): New inline function.
+ (mpn_jacobi_finish): Likewise.
+ (mpn_jacobi_update): Likewise.
+
+ * mpn/generic/jacobi_lehmer.c (mpn_jacobi_lehmer): New file, new
+ function.
+
+ * configure.in (gmp_mpn_functions): Added jacobi_lehmer.
+
+2010-04-14 Niels Möller <nisse@lysator.liu.se>
+
+ * configure.in (gmp_mpn_functions): Added
+ matrix22_mul1_inverse_vector.
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Added
+ matrix22_mul1_inverse_vector.c.
+
+ * gmp-impl.h (mpn_matrix22_mul1_inverse_vector): Updated for
+ rename of mpn_matrix22_mul1_inverse_vector.
+ * mpn/generic/gcd_lehmer.c (mpn_gcd_lehmer_n): Likewise.
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_lehmer_n): Likewise.
+ * mpn/generic/hgcd.c (hgcd_step): Likewise.
+
+ * mpn/generic/matrix22_mul1_inverse_vector.c
+ (mpn_matrix22_mul1_inverse_vector): New file, function moved and
+ renamed...
+ * mpn/generic/hgcd2.c (mpn_hgcd_mul_matrix1_inverse_vector):
+ ...from here.
+
+2010-04-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/t-toom6h.c (SIZE_LOG): Define.
+ * tests/mpn/t-toom8h.c (SIZE_LOG): Likewise.
+
+2010-04-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/ia64/lorrshift.asm: Rewrite feed-in and wind-down code.
+
+ * mpn/ia64/aorslsh1_n.asm: Adapt to new aorslsh1_n.
+ * mpn/ia64/aorslsh1_n.asm: Likewise.
+
+ * mpn/ia64/aors_n.asm: Complete rewrite.
+ * mpn/ia64/aorslsh1_n.asm: Likewise.
+
+ * mpn/ia64/add_n_sub_n.asm: Misc cleanups. Add slotting comments.
+
+ * mpn/ia64/lshiftc.asm: New file.
+
+ * mpn/x86_64/pentium4/gmp-mparam.h: No longer disable rsh1add_n and
+ rsh1sub_n; instead disable rsblsh1_n, addlsh2_n, rsblsh2_n.
+
+ * mpn/x86/divrem_2.asm: Use "orb" instead of "or" to work around
+ Solaris assembler bug.
+ * mpn/x86_64/mpn/x86_64/divrem_2.asm: Likewise.
+
+ * mpn/x86/aors_n.asm: Use operand-less shift-by-1 insn form.
+ * mpn/x86/pentium/aors_n.asm: Likewise.
+ * mpn/x86_64/invert_limb.asm: Likewise.
+
+ * mpn/x86_64/pentium4/aors_n.asm: Let non-nc code fall into nc code.
+
+ * mpn/x86_64/pentium4/rsh1aors_n.asm: New file.
+
+2010-03-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/ia64/add_n_sub_n.asm: New file.
+
+ * mpn/generic/toom33_mul.c: Fix mpn_add_n_sub_n usage.
+ * mpn/generic/toom3_sqr.c: Likewise.
+ * mpn/generic/toom63_mul.c: Likewise.
+
+ * mpn/generic/add_n_sub_n.c: Renamed from addsub_n.c.
+
+2010-03-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/divrem_2.asm: Use mpn_invert_limb instead of div insn.
+
+ * mpn/ia64/aorslshC_n.asm: New file, generalised from last iteration of
+ aorslsh1_n.asm.
+ * mpn/ia64/aorslsh1_n.asm: Use aorslshC_n.asm.
+ * mpn/ia64/aorslsh1_n.asm: New file, use aorslshC_n.asm.
+
+2010-03-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/invert_limb.asm: Rewrite to exploit cancellation
+ in the Newton iteration.
+
+2010-03-20 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom_interpolate_8pts.c: Use mpn_sublsh2_n.
+
+2010-03-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/aorslshC_n.asm: New file, generalised from
+ last iteration of aorslsh1_n.asm.
+ * mpn/powerpc64/mode64/aorslsh1_n.asm: Use aorslshC_n.asm.
+ * mpn/powerpc64/mode64/aorslsh1_n.asm: New file, use aorslshC_n.asm.
+
+2010-03-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/nano/dive_1.asm: New file.
+
+ * mpn/x86_64/divrem_1.asm: Avoid shld since it is slow on several CPU
+ types. Unconditionally provide code for normalised and unnormalised
+ divisors. Cleanup labels.
+
+ * mpn/x86_64/core2/divrem_1.asm: Remove special code for normalised
+ divisors. Cleanup labels.
+
+ * mpn/generic/toom_interpolate_6pts.c: Call mpn_sublsh2_n and
+ mpn_sublsh_n with correct args.
+
+ * tests/devel/try.c: Use enum for TYPE_*.
+
+ * tests/devel/try.c: Test mpn_sublsh2_n.
+ * tests/refmpn.c (refmpn_sublsh2_n): New function.
+ * tests/tests.h (refmpn_sublsh2_n): Declare.
+
+ * mpn/powerpc64/mode64/aorslsh1_n.asm: New file, with faster
+ mpn_addlsh1_n and mpn_sublsh1_n.
+ * mpn/powerpc64/mode64/addlsh1_n.asm: Delete.
+ * mpn/powerpc64/mode64/sublsh1_n.asm: Delete.
+
+2010-03-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (*-*-aix): Define gcc_32_cflags_maybe, ar_32_flags and
+ nm_32_flags.
+
+ * mpn/x86/pentium4/sse2/addlsh1_n.asm: Tune for slightly better speed.
+ Misc cleanups. Add cycle table.
+
+ * mpn/x86_64/copyi.asm: Update cycle table.
+ * mpn/x86_64/copyd.asm: Likewise.
+ * mpn/x86_64/rsh1aors_n.asm: Likewise.
+ * mpn/x86_64/dive_1.asm: Likewise.
+
+ * mpn/x86/pentium4/sse2/add_n.asm: Misc cleanups. Add cycle table.
+ * mpn/x86/pentium4/sse2/sub_n.asm: Likewise.
+
+2010-03-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/divrem_1.asm: Use mpn_invert_limb instead of div insn.
+ * mpn/x86_64/core2/divrem_1.asm: Likewise.
+
+ * tune/speed.c (routine): Add FLAG_R_OPTIONAL for many binops.
+
+2010-03-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/alpha/ev6/mod_1_4.asm (mpn_mod_1s_4p_cps): Rewrite.
+
+ * mpn/ia64/aors_n.asm: Insert explicitly typed nops to trigger intended
+ bundling.
+ * mpn/ia64/aorslsh1_n.asm: Likewise.
+ * mpn/ia64/dive_1.asm: Likewise.
+
+2010-03-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/pentium4/sse2/submul_1.asm: Rewrite.
+
+ * mpn/powerpc64/mode64/aorsmul_1.asm: New file, faster than old code
+ for both mpn_addmul_1 and mpn_submul_1.
+ * mpn/powerpc64/mode64/addmul_1.asm: Remove.
+ * mpn/powerpc64/mode64/submul_1.asm: Remove.
+
+2010-03-11 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcd_lehmer.c (gcd_2): Use sub_ddmmss.
+
+ * mpn/generic/jacbase.c (mpn_jacobi_base): Reorganized the
+ JACOBI_BASE_METHOD 4 slightly. Now requires that b > 1.
+
+2010-03-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/divrem_1.asm: Make fraction code take documented # of
+ cycles. Annotate code for more CPUs. Misc cleanups.
+ * mpn/x86_64/core2/divrem_1.asm: Annotate code for more CPUs.
+
+ * mpn/alpha/ev6/mod_1_4.asm: New file.
+
+ * mpn/ia64/mod_34lsub1.asm: New file.
+
+ * doc/gmp.texi (Language Bindings): Update Python site, add Ruby.
+
+2010-03-10 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tuneup.c (tune_jacobi_base): Consider mpn_jacobi_base_4.
+ * tune/speed.c (routine): Added mpn_jacobi_base_4.
+ * tune/common.c (speed_mpn_jacobi_base_4): New function.
+ * tune/speed.h (speed_mpn_jacobi_base_4): Declare it.
+ * tune/Makefile.am (libspeed_la_SOURCES): Added jacbase4.c.
+ * tune/jacbase4.c: New file.
+
+ * mpn/generic/jacbase.c (mpn_jacobi_base): New function, for
+ JACOBI_BASE_METHOD 4.
+
+2010-03-09 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-jac.c (check_large_quotients): Also generate inputs
+ with large quotients and a large gcd.
+
+2010-03-09 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpz/t-bin.c (randomwalk): New test-generator function.
+
+2010-03-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.c (routine): Force r argument for several mod_1 calls.
+
+2010-03-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/divrem_1.asm: Disable SPECIAL_CODE_FOR_NORMALIZED_DIVISOR.
+ Misc clean up.
+
+ * mpn/x86_64/mod_1_1.asm: New file.
+ * mpn/x86_64/mod_1_2.asm: New file.
+ * mpn/x86_64/mod_1_4.asm: Update cycle counts.
+
+ * tests/tests.h (TESTS_REPS): Fix typo.
+
+2010-03-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/core2/divrem_1.asm: New file.
+
+2010-02-26 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/speed.c (routine): Added udiv_qrnnd_preinv3.
+
+ * tune/common.c (speed_udiv_qrnnd_preinv3): New function.
+ * tune/speed.h: Added prototype for it.
+
+2010-02-26 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-jac.c (check_large_quotients): New test. Currently
+ disabled, since it's quite slow.
+ (mpz_nextprime_step): New function.
+
+2010-02-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/pa64/aors_n.asm: Fix typo in last change.
+
+2010-02-25 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-jac.c (ref_jacobi): New reference implementation,
+ using factorization and legendre symbols computed by powm.
+
+ * tests/devel/try.c (param_init, call): Don't pass negative values
+ for the second argument to mpz_jacobi and refmpz_jacobi.
+
+ * tests/refmpz.c (refmpz_jacobi): Require that b is odd and positive.
+
+ * tests/devel/try.c (param_init): Support mpz_legendre.
+ (choice_array): Added mpz_kronecker (apparently forgotten) and
+ mpz_legendre.
+ (call): Added TYPE_MPZ_LEGENDRE.
+ (try_one): Added support for DATA_SRC1_ODD_PRIME.
+
+ * tests/refmpz.c (refmpz_legendre): Rewrote using powm.
+
+2010-02-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Make "corei" default for unrecognised Intel P6 CPUs.
+
+ * tests/mpz/t-perfpow.c (check_random): Use mp_limb_t type for limb
+ variables.
+
+ * tests/mpn/t-toom6h.c (COUNT): Define.
+ * tests/mpn/t-toom8h.c (COUNT): Define.
+
+ * tests/mpn/t-div.c: Cast a switch index to placate HP's cc.
+ * tests/mpn/t-bdiv.c: Likewise.
+
+ * mpn/pa64/aors_n.asm: Fix support of the 2.0n ABI.
+
+2010-02-24 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpz/t-bin.c (data): Replace (2k,k), tested by twos ().
+ * tests/mpf/t-inp_str.c (data): Test also "+" in the exponent.
+
+2010-02-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mod_1_3.c: Cast a switch index to placate HP's cc.
+
+ * mpn/generic/sqrtrem.c: Use CNST_LIMB.
+
+2010-02-20 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/speed.h (mpn_gcd_accel): Deleted prototype.
+ (mpn_hgcd_lehmer): New prototype.
+ (MPN_HGCD_LEHMER_ITCH): New macro (previously in gmp-impl.h).
+
+ * tune/Makefile.am (libspeed_la_SOURCES): Added hgcd_lehmer.c.
+ * tune/hgcd_lehmer.c: New file.
+ * tune/gcd_accel.c: Deleted obsolete file.
+
+ * gmp-impl.h (MPN_HGCD_LEHMER_ITCH): Deleted macro.
+
+ * mpn/generic/hgcd.c (mpn_hgcd_lehmer): Deleted function,
+ (mpn_hgcd): Don't call mpn_hgcd_lehmer, instead use inlined loop
+ around hgcd_step.
+ (mpn_hgcd_itch): Substitute n for MPN_HGCD_LEHMER_ITCH (n).
+
+2010-02-19 Niels Möller <nisse@lysator.liu.se>
+
+ * Makefile.am (mpn/jacobitab.h): Added the rules needed to
+ generate this file.
+
+ * gen-jacobitab.c: New file.
+
+2010-02-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm.c: Honour SQR_BASECASE_THRESHOLD in innerloop
+ expansions.
+
+2010-02-16 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/time.c (cgt_works_p): Added rudimentary sanity check for
+ clock_gettime working.
+
+2010-02-15 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/time.c (speed_time_init): Make use of cycle counter
+ configurable, via the speed_option_cycles_broken flag.
+ * tune/common.c (speed_option_cycles_broken): New global variable.
+ (speed_option_set): Recognize option "cycles-broken".
+
+ * tune/time.c (cycles_works_p): Deleted hack to disable cycle
+ counter on linux. Needs to be replaced by something more
+ selective.
+
+2010-02-11 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/time.c (speed_time_init): Fix speed_time_string when using
+ clock_gettime.
+ (cycles_works_p): On linux, don't use the cycle counter.
+
+ * tune/Makefile.am: Add $(TUNE_LIBS) when linking programs.
+
+ * configure.in: Check if -lrt is needed for clock_gettime, and if
+ so, add that flag to TUNE_LIBS.
+
+2010-02-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_redc): Set min_size and min_is_always when
+ measuring REDC_1_TO_REDC_2_THRESHOLD.
+ (tune_mod_1): Set min_size for PREINV_MOD_1_TO_MOD_1_THRESHOLD.
+
+ * mpn/x86_64/aorrlsh_n.asm (cnt): Fix a typo.
+ * mpn/x86_64/lshsub_n.asm: Likewise.
+
+2010-02-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * Version 5.0.1 released.
+
+ * mpn/generic/powm.c: Use rp target area for power table computation in
+ order to use less scratch.
+
+ * mpn/generic/binvert.c (mpn_binvert_itch): Enable more economical
+ mpn_mulmod_bnm1_itch call.
+
+ * mpn/generic/mu_div_qr.c: Remove always true #if.
+ * mpn/generic/mu_divappr_q.c: Likewise.
+ * mpn/generic/mu_bdiv_q.c: Likewise.
+ * mpn/generic/mu_bdiv_qr.c: Likewise.
+
+2010-02-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*, LIBMP_LT_*):
+ Bump version info.
+
+ * mpn/powerpc64/mode64/gmp-mparam.h: Remove {MUL,SQR}_FFT_TABLE2.
+ * mpn/x86/p6/gmp-mparam.h: Likewise.
+ * mpn/x86/p6/mmx/gmp-mparam.h: Likewise.
+ * mpn/generic/mul_fft.c: Don't depend on FFT_TABLE2, it was broken.
+
+2010-01-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mul_fft.c (mpn_mul_fft_internal): Remove arguments n, m,
+ k and rec; add argument sqr. Don't call mpn_mul_fft_decompose here,
+ instead do that in all callers.
+ (mpn_mul_fft): Trim allocation when squaring, and use TMP_ALLOC*, not
+ explicit alloc/free.
+ (mpn_fft_div_2exp_modF): Avoid a scalar division.
+ (mpn_fft_mul_modF_K): Replace some multiplies by K with shifting by k.
+ (mpn_fft_mul_2exp_modF): Make function more symmetrical.
+
+2010-01-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mu_div_q.c (mpn_mu_div_q_itch): Rewrite.
+ * mpn/generic/mu_div_qr.c (mpn_mu_div_qr_itch): Re-enable
+ better mulmod itch estimate.
+ * mpn/generic/mu_divappr_q.c (mpn_mu_divappr_q_itch): Likewise.
+ * mpn/generic/mu_bdiv_qr.c (mpn_mu_bdiv_qr_itch): Likewise.
+ * mpn/generic/mu_bdiv_q.c (mpn_mu_bdiv_q_itch): Likewise.
+
+2010-01-27 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mu_div_qr.c (mpn_mu_div_qr_itch): Disabled guessed
+ estimate, enabled a conservative one.
+ * mpn/generic/mu_divappr_q.c (mpn_mu_divappr_q_itch): Likewise.
+ * mpn/generic/mu_bdiv_qr.c (mpn_mu_bdiv_qr_itch): Likewise.
+ * mpn/generic/mu_bdiv_q.c (mpn_mu_bdiv_q_itch): Likewise.
+
+2010-01-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mulmod_bnm1.c (mpn_mulmod_bnm1): Partial rewrite to
+ reduce memory usage.
+ * mpn/generic/sqrmod_bnm1.c (mpn_sqrmod_bnm1): Likewise.
+ (mpn_sqrmod_bnm1_next_size): New function.
+
+ * gmp-impl.h (mpn_mulmod_bnm1_itch): Accepts 3 parameters now.
+ (mpn_sqrmod_bnm1_itch): New inline function.
+ (mpn_sqrmod_bnm1_next_size): Declaration and mangling.
+ * mpn/generic/nussbaumer_mul.c: Use the new functions.
+
+ * mpn/generic/invertappr.c (mpn_ni_invertappr): Use new syntax for
+ mpn_mulmod_bnm1_itch.
+ * mpn/generic/mu_divappr_q.c (mpn_mu_divappr_q_itch): Likewise.
+ * mpn/generic/mu_bdiv_qr.c (mpn_mu_bdiv_qr_itch): Likewise.
+ * mpn/generic/mu_bdiv_q.c (mpn_mu_bdiv_q_itch): Likewise.
+ * mpn/generic/mu_div_qr.c (mpn_mu_div_qr_itch): Likewise.
+ * mpn/generic/binvert.c (mpn_binvert_itch): Likewise.
+ * tune/speed.h (SPEED_ROUTINE_MPN_MULMOD_BNM1_CALL): Likewise.
+ (SPEED_ROUTINE_MPN_MULMOD_BNM1_ROUNDED): Likewise.
+
+ * tests/mpn/t-sqrmod_bnm1.c, tests/mpn/t-mulmod_bnm1.c: Test
+ reduced memory usage.
+
+2010-01-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (INSERT_FFTTAB): New macro, like old insertion code but
+ also inserting a sentinel.
+ (fftmes): Use INSERT_FFTTAB for inserting new measurements.
+ Limit k range to best_k - 4 ... best_k + 4.
+
+2010-01-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (__GNU_MP_VERSION_PATCHLEVEL): Bump.
+ (__GMP_MP_RELEASE): New macro.
+
+ * mpf/div.c: Rewrite to use mpn_div_q.
+
+2010-01-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * Add FFT_TABLE3 tables for a basic set of machines.
+
+ * configure.in: Use -mtune=nocona for 64-bit pentium4.
+
+ * config.guess: Recognise many more Intel processors.
+
+ * tune/common.c: Whitespace cleanup.
+ (speed_mpn_matrix22_mul): Rewrite.
+
+2010-01-21 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/nussbaumer_mul.c (mpn_nussbaumer_mul): Take
+ advantage of new mpn_mulmod_bnm1 interface, to reduce allocation.
+
+ * tests/mpn/t-mulmod_bnm1.c (ref_mulmod_bnm1, main): Adapted to
+ mpn_mulmod_bnm1 interface change.
+
+ * mpn/generic/mulmod_bnm1.c (mpn_mulmod_bnm1): Interface change,
+ in case an + bn < rn, only write an + bn output limbs. New input
+ requirement, an + bn > rn/2.
+ * mpn/generic/sqrmod_bnm1.c (mpn_sqrmod_bnm1): Corresponding
+ changes.
+
+2010-01-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (fftmes): Round up initial n according to initial k.
+ Limit k to 24 in loop. Remove an obsolete always-true condition.
+ Remove a redundant trace printout.
+
+2010-01-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (fftmes): New function
+ (fft): Rewrite.
+ (mpn_mul_fft_lcm): New function, copied from mpn/generic/mul_fft.c.
+ (fftfill): New function, code taken from mul_fft.c (mpn_mul_fft).
+ (cached_measure): New function.
+
+ * gmp-impl.h (struct fft_table_nk): Moved from mul_fft.c.
+ (MUL_FFT_TABLE3, SQR_FFT_TABLE3): Provide dummy versions for tuneup
+ builds.
+ (FFT_TABLE3_SIZE): Increase value for tuneup builds.
+
+ * mpn/generic/mul_fft.c: Handle a new FFT threshold table type ("3").
+ Misc cleanups to old table type code.
+
+2010-01-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/darwin.m4: Fix typo in last change.
+
+2010-01-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (__GMP_EXTERN_INLINE): Remove "extern" for newer Sun C.
+
+ * gmp-impl.h (GMP_LIMB_BYTES): New define.
+
+ * mpn/x86_64/darwin.m4 (LEA): New define.
+
+ * mpn/x86/invert_limb.asm (approx_tab): Use DEF_OBJECT.
+ Rename and globalise it to work around Mac OS bug.
+
+ With Philip McLaughlin:
+ * mpn/x86_64/gcd_1.asm (ctz_table): Don't use local prefix, but
+ use DEF_OBJECT...END_OBJECT.
+ Keep stack pointer at ABI mandated alignment over call.
+
+2010-01-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.c (routine): Remove obsolete mpn_dc_tdiv_qr and
+ mpn_dc_div_qr_n.
+ * tune/common.c (speed_mpn_dc_tdiv_qr, speed_mpn_dcpi1_div_qr_n):
+ Remove now unused functions.
+ * tune/speed.h (SPEED_ROUTINE_MPN_DC_DIVREM_N,
+ SPEED_ROUTINE_MPN_DC_DIVREM_SB, SPEED_ROUTINE_MPN_DC_TDIV_QR): Remove
+ now unused macros.
+
+ * mpn/x86_64/fat/fat_entry.asm (mpn_cpuid_available): Remove function.
+
+ * ltmain.sh: Upgrade from 1.5.24 to 2.2.6b.
+ * ylwrap: New file.
+ * .bootstrap: Remove explicit versions.
+
+ * doc/gmp.texi (Block-wise Barrett Division): New node.
+
+ * mpn/generic/powm.c: Change some #if to plain 'if' to avoid fat build
+ problems.
+
+2010-01-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_PI1_DIV): Accept arguments for size
+ restrictions.
+ * tune/common.c (speed_mpn_sbpi1_div_qr, speed_mpn_dcpi1_div_qr,
+ (speed_mpn_sbpi1_divappr_q, speed_mpn_dcpi1_divappr_q): Pass size
+ limits for SPEED_ROUTINE_MPN_PI1_DIV.
+
+ * tune/speed.c (routine): Allow .r argument for mpn_sbpi1_divappr_q and
+ mpn_dcpi1_divappr_q.
+
+2010-01-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * Version 5.0.0 released.
+
+ * mpn/generic/div_q.c: Handle mpn_*_divappr_q returning high limb
+ everywhere.
+
+2010-01-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * Update MUL_FFT_TABLE2 and SQR_FFT_TABLE2 for many machines.
+
+ * mpn/generic/mu_div_q.c: Account for divisor truncation error as well
+ as mpn_mu_divappr_q's error.
+
+ * mpn/generic/mu_div_q.c: Handle mpn_preinv_mu_divappr_q returning a
+ high limb.
+
+ * tests/mpn/t-bdiv.c: Move a random call for debugability.
+ * tests/mpn/t-div.c: Likewise.
+
+ * mpn/generic/mu_divappr_q.c: Rewrite quotient round-up code.
+
+ * mpn/generic/mu_div_qr.c: Handle carry-out from a carry propagation
+ subtract.
+ * mpn/generic/mu_divappr_q.c: Likewise.
+
+ * mpn/generic/mu_divappr_q.c
+ (mpn_preinv_mu_divappr_q, mpn_mu_divappr_q): Declare dividend constant.
+ * gmp-impl.h: Likewise.
+
+ * perfpow.c (mpn_perfect_power_p): Call mpn_divexact instead of
+ mpn_bdiv_q (with too little scratch space!).
+
+ From Niels Möller:
+ * tests/mpn/t-div.c (check_one): Get rid of the poorly managed variable
+ tn.
+
+ * mpn/minithres/gmp-mparam.h: Add all lately defined thresholds.
+
+ * mpn/generic/div_q.c: Use SB division for small quotients as well as
+ small divisors. Fix typo in itch call.
+
+2010-01-06 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/t-div.c (check_one): Checking based on multiplication,
+ refmpn_mul, rather than refmpn_tdiv_qr.
+
+2010-01-06 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom8h_mul.c: Avoid overflows of mp_size_t.
+
+2010-01-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (__GNU_MP__): Bump.
+ (__GNU_MP_VERSION,__GNU_MP_VERSION_MINOR,__GNU_MP_VERSION_PATCHLEVEL):
+ Bump version info.
+ * mp-h.in (__GNU_MP__): Bump.
+ * Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*, LIBMP_LT_*):
+ Bump version info.
+
+ * doc/gmp.texi: Rewrite mpn_gcdext text. Remove some out-of-date
+ text in Algorithms chapter.
+
+ * mpn/generic/div_q.c: Properly handle np=scratch. Fix critical typo
+ in final adjustment code. Misc cleanups.
+
+ * mpn/generic/rootrem.c: Use mpn_div_q.
+ * mpz/tdiv_q.c: Likewise.
+
+ * tests/mpn/t-div.c: Test mpn_div_q.
+ (SIZE_LOG): Up to 17.
+
+ * mpn/generic/div_q.c: New file.
+ * configure.in (gmp_mpn_functions): Add div_q.
+
+ * mpn/generic/mu_div_q.c: Actually declare dividend constant.
+
+2010-01-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (fft): Separate tuning of modf and full products.
+ (struct fft_param_t): New field, mul_modf_function.
+ (tune_fft_sqr): Fix typo.
+ (tune_fft_mul, tune_fft_sqr): Initialise mul_modf_function field.
+ * tune/common.c (speed_mpn_fft_mul, speed_mpn_fft_sqr): New functions.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_MULMOD_BNM1_ROUNDED): Clean up.
+
+ * mpn/generic/mul.c: Simplify rational expression.
+
+ * gmp-impl.h: Cleanup threshold variables; remove obsolete ones and
+ make all possibly needed definitions for existing ones.
+ * tune/tuneup.c (tune_mul): Write fractions-compensated values to
+ threshold variables.
+
+2010-01-03 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tune/common.c, tune/speed.c, tune/speed.h: Support measuring
+ mpn_toom43_mul.
+
+ * mpn/generic/toom_interpolate_6pts.c: Small reorganisation.
+
+2010-01-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD): Default to
+ INV_MULMOD_BNM1_THRESHOLD/2 instead.
+
+ * gmp-impl.h (INV_APPR_THRESHOLD, INV_MULMOD_BNM1_THRESHOLD): Default
+ here...
+ * mpn/generic/invert.c, mpn/generic/invertappr.c: ...not here.
+
+ * tests/mpn/t-div.c: Rewrite operand generation code.
+
+2010-01-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD): Default to
+ INV_MULMOD_BNM1_THRESHOLD.
+
+2010-01-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/dcpi1_div_q.c: Handle divappr approximation problem more
+ efficiently.
+ * mpn/generic/mu_div_q.c: Likewise.
+
+ * mpn/generic/invert.c: Remove duplicated code.
+
+2010-01-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD): Default to 0.
+
+ * mpn/generic/mu_div_qr.c: Rewrite to use mpn_mulmod_bnm1. Clean up
+ scratch usage. Improve itch functions.
+ * mpn/generic/mu_divappr_q.c: Likewise.
+ * mpn/generic/mu_bdiv_qr.c: Likewise.
+ * mpn/generic/mu_div_q.c: Likewise.
+
+ * mpn/generic/dcpi1_bdiv_qr.c: Add parameter ASSERTs.
+ * mpn/generic/dcpi1_bdiv_q.c: Likewise.
+
+ * tests/mpn/t-bdiv.c: Replace with unit testing code, based on t-div.c.
+ Increase COUNT to 500.
+
+ * tests/mpn/t-div.c: Avoid generating too small test operands.
+ Move SB suppression limit downwards. Increase COUNT to 200.
+
+2009-12-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/tdiv_qr.c: Handle numerator/remainder overlap in MU case.
+
+ * tests/tests.h (TESTS_REPS): New macro.
+ * tests/mpz/dive.c: Use larger operands, decrease default reps, use
+ TESTS_REPS.
+ * tests/mpz/convert.c: Likewise.
+ * tests/mpz/t-sqrtrem.c: Likewise.
+ * tests/mpz/reuse: Likewise.
+ * tests/mpz/t-root.c: Likewise.
+ * tests/mpz/t-tdiv.c: Likewise.
+ * tests/mpz/t-gcd.c: Likewise.
+ * tests/mpz/t-powm.c: Likewise.
+
+2009-12-31 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom8_sqr.c (SQR_TOOM8_MAX): Avoid overflow.
+ * mpn/generic/toom6_sqr.c (SQR_TOOM6_MAX): Likewise.
+
+ * mpn/generic/mulmod_bnm1.c: Don't mention MISUSE any more,
+ simply consider UNLIKELY any unexpected size.
+
+2009-12-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (speed_mpn_sbordcpi1_div_qr): New function.
+ (tune_mu_div): Use it.
+
+2009-12-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mu_bdiv, tune_dc_bdiv, tune_mu_div)
+ (tune_dc_div): Clear global s.r to make speed functions do 2n/n.
+
+ * tune/speed.c (routine): New entries for mpn_mu_div_qr and
+ mpn_mupi_div_qr. Allow .r parameter for mpn_sbpi1_div_qr,
+ mpn_dcpi1_div_qr.
+ * tune/speed.h (SPEED_ROUTINE_MPN_PI1_DIV, SPEED_ROUTINE_MPN_MU_DIV_QR)
+ (SPEED_ROUTINE_MPN_MUPI_DIV_QR): Handle .r parameter.
+
+ * tests/mpz/t-tdiv.c: Increase operands size again.
+
+ * mpn/generic/tdiv_qr.c: Attempt to choose between DC and MU cleverer.
+
+ * mpn/generic/tdiv_qr.c: Don't overwrite rp with unnecessary temporary
+ alloc.
+
+2009-12-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mu_div): Tune MUPI_DIV_QR_THRESHOLD.
+ * tune/speed.h (struct speed_params): Allow 3 source operands.
+ (SPEED_ROUTINE_MPN_MUPI_DIV_QR): New macro.
+ * tune/common.c (speed_mpn_mupi_div_qr): New function.
+
+ * mpn/generic/tdiv_qr.c: Call mpn_mu_div_qr.
+
+ * tests/mpz/t-tdiv.c: Use larger test operands.
+
+ * mpn/generic/mu_div_qr.c (mpn_mu_div_qr2): Remove code for dn==1.
+
+ * mpz/mul.c: Call mpn_sqr directly. Use PTR,SIZ,ALLOC.
+
+ * tune/tuneup.c (tune_mu_div): Set min_size to 6, DC functions require
+ this.
+
+ * tests/mpn/t-div.c: Call mu_div functions with operands that generate
+ a high quotient limb.
+
+ * mpn/generic/mu_div_qr.c: Rewrite to return a high quotient limb,
+ to let dividend argument be constant, and as a general cleanup.
+ * mpn/generic/mu_divappr_q.c: Likewise.
+ * mpn/generic/mu_div_q.c: Likewise.
+ * gmp-impl.h: Update declarations of changed functions.
+
+ * mpn/generic/invertappr.c (mpn_invertappr): Allocate scratch space
+ when caller passed NULL.
+
+2009-12-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom_couple_handling.c: Prefix name with mpn_.
+ * gmp-impl.h: Likewise.
+ * mpn/generic/toom63_mul.c: Likewise.
+ * mpn/generic/toom6_sqr.c: Likewise.
+ * mpn/generic/toom6h_mul.c: Likewise.
+ * mpn/generic/toom8_sqr.c: Likewise.
+ * mpn/generic/toom8h_mul.c: Likewise.
+
+ * configure.in (gmp_mpn_functions_optional) Move "com" from here...
+ (gmp_mpn_functions): ...to here.
+ * mpn/generic/com.c: New file.
+ * (mpn_com): New name for mpn_com_n. Make public.
+ * (mpn_neg): Analogous changes.
+
+ * tune/tuneup.c (tune_mu_div, tune_mu_bdiv): Set step_factor.
+
+ * tune/common.c, tune/speed.c, tune/speed.h: Support measuring
+ mpn_lshiftc.
+
+ * tests/devel/try.c: Test mpn_lshiftc.
+ * tests/refmpn.c (refmpn_com): New function.
+ (refmpn_lshiftc): Likewise.
+
+ * configure.in (gmp_mpn_functions_optional) Move lshiftc from here...
+ (gmp_mpn_functions): ...to here.
+ * mpn/generic/lshiftc.c: New file.
+ * mpn/x86_64/lshiftc.asm: New file.
+ * mpn/x86_64/core2/lshiftc.asm: New file.
+ * mpn/generic/mul_fft.c (mpn_lshiftc): Remove.
+
+ * mpn/x86_64/core2/lshift.asm: Tweak for better Core iN performance.
+ * mpn/x86_64/core2/rshift.asm: Likewise.
+
+2009-12-27 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mul.c: Use toom6h and toom8h for almost balanced.
+
+ * mpn/generic/mullo_n.c (mpn_dc_mullo_n): New ratio, to be used in
+ Toom-8 range.
+
+2009-12-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * (mpn_sqr): New name for mpn_sqr_n. Many files affected.
+
+ * tune/tuneup.c (tune_mullo): Up step_factor for MULLO_MUL_N_THRESHOLD.
+ (tune_invertappr, tune_invert, tune_binvert): Let max_size default.
+
+ * tune/tuneup.c (tune_mu_div, tune_mu_bdiv) New functions.
+ * tune/speed.h (SPEED_ROUTINE_MPN_MU_DIV_Q): New macro.
+ (SPEED_ROUTINE_MPN_MU_DIV_QR): Likewise.
+ (SPEED_ROUTINE_MPN_MU_BDIV_Q): Likewise.
+ (SPEED_ROUTINE_MPN_MU_BDIV_QR): Likewise.
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add bdiv_q.c and bdiv_qr.c.
+ * tune/common.c (speed_mpn_mu_div_qr): New function.
+ (speed_mpn_mu_divappr_q): Likewise.
+ (speed_mpn_mu_div_q): Likewise.
+ (speed_mpn_mu_bdiv_q): Likewise.
+ (speed_mpn_mu_bdiv_qr): Likewise.
+
+ * mpn/*/gmp-mparam.h: Fix incorrect MOD_1U_TO_MOD_1_1_THRESHOLD 0
+ values.
+
+ * gmp-impl.h (MODEXACT_1_ODD_THRESHOLD): Remove.
+ (BMOD_1_TO_MOD_1_THRESHOLD): New parameter, with the reverse meaning of
+ MODEXACT_1_ODD_THRESHOLD.
+ (MPN_MOD_OR_MODEXACT_1_ODD): Use BMOD_1_TO_MOD_1_THRESHOLD.
+ * mpn/generic/divis.c, mpz/{cong.c,cong_ui.c,divis_ui.c}: Likewise.
+ * tune/tuneup.c (tune_modexact_1_odd): Tune BMOD_1_TO_MOD_1_THRESHOLD;
+ Do not assume native mpn_modexact_1_odd is faster than mpn_mod_1.
+ (tuned_speed_mpn_mod_1): Remove variable.
+ (tune_mod_1): Fix thinkos. Suppress printing of "always" etc.
+ (all): Measure for divrem_1, mod_1, divexact_1, etc first, since Toom
+ depends on some of them.
+
+ * mpn/generic/toom22_mul.c (TOOM22_MUL_REC): New name for
+ TOOM22_MUL_MN_REC.
+
+2009-12-26 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/t-toom32.c (MIN_AN, MIN_BN, MAX_BN): Relax
+ requirements a bit.
+
+ * mpn/generic/toom32_mul.c (mpn_toom32_mul): Relax requirement on
+ input sizes, to support s+t>=n (used to be s+t>=n+2). Keep high
+ limbs of the evaluated values in scalar variables.
+
+ * mpn/generic/sbpi1_divappr_q.c (mpn_sbpi1_divappr_q): Remove
+ unused variables.
+
+ * mpn/generic/toom32_mul.c (mpn_toom32_mul): Fixed left-over use
+ of mpn_addsub_n which should be mpn_add_n_sub_n.
+
+2009-12-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add new toom files (spotted by Torbjorn).
+
+ * gmp-impl.h (mpn_toom6_sqr_itch): Rename to mpn_toom6_mul_n_itch and redefine.
+ (mpn_toom8_sqr_itch): Rename to mpn_toom8_mul_n_itch and redefine.
+ * mpn/generic/mul_n.c: Use renamed _itch macros.
+
+2009-12-25 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/t-toom32.c (MIN_AN, MIN_BN, MAX_BN): Tightened requirements.
+ * gmp-impl.h (mpn_toom32_mul_itch): Updated. Less scratch needed
+ by toom32 itself, and also the pointwise multiplications are
+ currently mpn_mul_n with no supplied scratch.
+ * mpn/generic/toom32_mul.c (mpn_toom32_mul): Reorganized
+ interpolation to use less scratch space. No longer supports the
+ most extreme size ratios.
+
+2009-12-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_preinv_mod_1): Purge.
+ (tune_mod_1): Use speed_mpn_mod_1_tune for
+ PREINV_MOD_1_TO_MOD_1_THRESHOLD
+
+ * mpn/generic/dcpi1_divappr_q.c: Handle 2n/n properly. Don't use full
+ precision in mpn_sbpi1_divappr_q call. Misc cleanup.
+
+ * tune/tuneup.c (tune_mod_1): Add a check_size for
+ PREINV_MOD_1_TO_MOD_1_THRESHOLD.
+
+2009-12-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/mod_1_div.c (MOD_1N_TO_MOD_1_1_THRESHOLD,
+ (MOD_1U_TO_MOD_1_1_THRESHOLD): Set.
+ * tune/mod_1_inv.c (MOD_1N_TO_MOD_1_1_THRESHOLD,
+ (MOD_1U_TO_MOD_1_1_THRESHOLD): Set.
+
+ * gmp-impl.h (USE_PREINV_MOD_1): Remove.
+ (MPN_MOD_OR_PREINV_MOD_1): Define to choose functions dynamically in
+ terms of PREINV_MOD_1_TO_MOD_1_THRESHOLD (used to choose statically
+ using USE_PREINV_MOD_1).
+ * mpn/generic/perfsqr.c (PERFSQR_MOD_PP): Corresponding updates.
+
+ * tune/tuneup.c (tune_mod_1): Rewrite.
+ * gmp-impl.h (MOD_1N_TO_MOD_1_1_THRESHOLD): New.
+ (MOD_1U_TO_MOD_1_1_THRESHOLD): New name for MOD_1_1_THRESHOLD.
+ (MOD_1_1_TO_MOD_1_2_THRESHOLD): Mew name for MOD_1_2_THRESHOLD.
+ (MOD_1_2_TO_MOD_1_4_THRESHOLD): New name for MOD_1_4_THRESHOLD.
+ * mpn/generic/mod_1.c: Corresponding updates.
+
+2009-12-24 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mul_n.c: Use also toom6h and toom8h.
+ * mpn/generic/sqr_n.c: Use also toom6 and toom8.
+ * gmp-impl.h: Initial support for tuning of Toom-6half and Toom-8half.
+ * tune/tuneup.c: Tune Toom-6half and Toom-8half thresholds.
+
+2009-12-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mod_1_4.c: Get ASSERT right.
+ * mpn/generic/mod_1_3.c: Likewise.
+ * mpn/generic/mod_1_2.c: Likewise.
+
+ * mpn/generic/powm_sec.c: Use SQR_TOOM2_THRESHOLD as limit for a native
+ mpn_sqr_basecase, not TUNE_SQR_TOOM2_MAX.
+
+2009-12-23 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tune/common.c, tune/speed.c, tune/speed.h: Support for measuring
+ mpn_toom8h_mul and mpn_toom8_sqr speed.
+
+ * mpn/generic/toom_eval_pm2exp.c: Fix ASSERTs.
+
+ * mpn/generic/toom8h_mul.c: New file.
+ * mpn/generic/toom8_sqr.c: New file.
+ * mpn/generic/toom_interpolate_16pts.c: New file.
+ * gmp-impl.h: Provide corresponding declarations.
+ * configure.in (gmp_mpn_functions): List toom_interpolate_16pts,
+ toom8h_mul, and toom8h_sqr.
+ * tests/mpn/t-toom8h.c: New test program.
+
+ * mpn/generic/toom6_sqr.c: New file, was part of toom6h_mul.
+ * mpn/generic/toom6h_mul.c: Removed _sqr.
+
+ * mpn/generic/mulmod_bnm1.c: Nailify CRT.
+ * mpn/generic/sqrmod_bnm1.c: Likewise.
+
+ * mpn/generic/mullo_n.c: Split dc_mullo_n function;
+ ALLOC memory at once.
+
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Update.
+
+ * mpn/generic/toom6h_mul.c: Add prefix to toom_interpolate_12pts.
+ * mpn/generic/toom_interpolate_12pts.c: Likewise.
+
+ * mpn/generic/invertappr.c (mpn_bc_invertappr): Use mpn_divrem_2.
+ * mpn/generic/invert.c: Faster basecase, use mpn_sbpi1_div_q.
+
+ * mpn/generic/toom_eval_pm2exp.c: Assert support for degree 3.
+ * mpn/generic/toom6h_mul.c: Avoid obsolete _itch function.
+
+2009-12-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/common.c, tune/speed.c, tune/speed.h: Support for measuring
+ mpn_mod_1_1p, mpn_mod_1s_2p, mpn_mod_1s_3p, mpn_mod_1s_4p.
+
+ * tests/mpz/t-powm.c: Test mpz_powm_sec.
+
+ * mpz/powm_sec.c: New file.
+ * gmp-h.in: Declare it.
+ * Makefile.am, mpz/Makefile.am: Compile it.
+ * doc/gmp.texi: Document it.
+
+ * mpn/generic/powm_sec.c (mpn_powm_sec_itch): New function.
+ (mpn_powm_sec): Use passed scratch, no local allocation.
+ Allow exp argument = 1.
+ (win_size): Start loop from 1.
+
+ * mpn/generic/powm.c (win_size): Start loop from 1.
+
+2009-12-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/t-div.c: New file.
+ * tests/mpn/Makefile.am: Compile it.
+
+ * mpn/generic/mu_divappr_q.c: Handle quotient overflow.
+
+ * mpn/generic/mu_div_q.c (mpn_mu_div_q_itch): New function.
+
+2009-12-22 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/sbpi1_div_q.c: Use udiv_qr_3by2. Intended to change
+ nothing after preprocessing.
+
+ * mpn/generic/sbpi1_divappr_q.c: For the last call to udiv_qr_3by2,
+ avoid using memory locations as output parameters, and revert to
+ explicitly copying n1 and n0 to memory.
+
+ * gmp-impl.h (udiv_qr_3by2): Tweaked to expand to precisely the
+ same code as was used before the introduction of this macro.
+ Eliminated some local variables, instead do multiple updates to
+ the output parameters.
+
+2009-12-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/t-toom6h.c (MIN_AN): Set to MUL_TOOM6H_THRESHOLD to avoid
+ invalid recursive sizes.
+
+ * tests/mpn/t-bdiv.c: Get itch function calls right.
+
+ * mpn/generic/mu_bdiv_q.c (mpn_mu_bdiv_q_itch): Rewrite.
+ * mpn/generic/mu_bdiv_qr.c (mpn_mu_bdiv_qr_itch): Simplify.
+
+ * mpn/generic/bdiv_qr.c (mpn_bdiv_qr): Simplify, don't allocate.
+ (mpn_bdiv_qr_itch): Conditionalise on MU_BDIV_QR_THRESHOLD.
+
+2009-12-18 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/t-bdiv.c: Add red-zones.
+
+2009-12-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/sbpi1_div_q.c: Fix fixup code to work for qn = 0.
+
+ * mpn/generic/dcpi1_divappr_q.c: Handle qn = 1 and qn = 2 for initial
+ quotient block (code block copied from dcpi1_div_qr.c).
+
+ * mpn/generic/dcpi1_div_qr.c: Rewrite singular case giving q limb of
+ GMP_NUMB_MAX. Remove an impossible qn = 0 case.
+
+ * mpn/generic/dcpi1_bdiv_q.c: Remove a spurious mpn_sub_1.
+
+ * mpn/generic/mul.c: Put back call to mpn_mul_n.
+
+ * tune/tuneup.c (all): Call tune_mulmod_bnm1 before tuning fft due to
+ dependency on mulmod_bnm1 from both mul_fft_mul and from mullo_n.
+
+ * mpn/generic/dcpi1_divappr_q.c: ASSERT that dn >= 6 and nn > dn.
+ * mpn/generic/dcpi1_div_q.c: ASSERT that dn >= 6 and nn-dn >= 3.
+ * mpn/generic/dcpi1_div_qr.c: ASSERT that dn >= 6 and nn-dn >= 3.
+
+ * mpn/generic/bdiv_q_1.c (mpn_pi1_bdiv_q_1): Renamed from
+ mpn_bdiv_q_1_pi1.
+ * All references changed.
+
+ * configure.in: Add --enable-old-fft-full.
+ * tune/speed.c (routine): Conditionalise mpn_mul_fft_full references on
+ WANT_OLD_FFT_FULL.
+ * tune/common.c (speed_mpn_mul_fft_full)
+ (speed_mpn_mul_fft_full_sqr): Likewise.
+ * mpn/generic/mul_fft.c (mpn_mul_fft_full): Include iff
+ WANT_OLD_FFT_FULL.
+
+2009-12-21 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h (mpn_toom6h_mul_itch): New inline function.
+ (MUL_TOOM6H_THRESHOLD): Default value.
+ (SQR_TOOM6_THRESHOLD): Default value.
+ * mpn/generic/toom6h_mul.c: Remove definitions moved to gmp-impl.h.
+ * tune/common.c, tune/speed.c, tune/speed.h: Support for measuring
+ mpn_toom6h_mul and mpn_toom6_sqr speed.
+
+ * mpn/generic/toom63_mul.c: Remove unused TMP_*.
+
+ * mpn/generic/toom_eval_pm2rexp.c: New file.
+ * gmp-impl.h: Provide corresponding declaration.
+ * configure.in (gmp_mpn_functions): List toom_eval_pm2rexp.
+ * mpn/generic/toom6h_mul.c: Use shared toom_eval_pm2rexp.
+
+ * mpn/generic/toom_couple_handling.c: New file, helper function
+ for high degree Toom.
+ * gmp-impl.h: Provide corresponding declaration.
+ * configure.in (gmp_mpn_functions): List toom_couple_handling.
+ * mpn/generic/toom6h_mul.c: Use shared toom_couple_handling.
+ * mpn/generic/toom63_mul.c: Likewise.
+
+ * mpn/generic/toom6h_mul.c: New file.
+ * mpn/generic/toom_interpolate_12pts.c: New file.
+ * gmp-impl.h: Provide corresponding declarations.
+ * configure.in (gmp_mpn_functions): List toom_interpolate_12pts,
+ toom6h_mul.
+ * tests/mpn/t-toom6h.c: New test program.
+
+ * tests/mpn/t-mulmod_bnm1.c (ref_mulmod_bnm1): Use ref_mul.
+ * tests/mpn/t-sqrmod_bnm1.c (ref_sqrmod_bnm1): Likewise.
+
+2009-12-20 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mulmod_bnm1.c (mpn_mulmod_bnm1): New CRT.
+ * mpn/generic/sqrmod_bnm1.c (mpn_sqrmod_bnm1): Likewise.
+
+2009-12-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * Change all bit counts for bignums to use mp_bitcnt_t.
+
+ * mpn/generic/bdivmod.c: File removed. All references purged.
+
+ * mpn/generic/mul_fft.c (mpn_mul_fft_full): Disable.
+
+ * gmp-impl.h: Define mpn_fft_mul as an alias for mpn_nussbaumer_mul.
+ * mpn/generic/mul.c: Refer mpn_fft_mul.
+ * mpn/generic/mul_n.c: Likewise.
+ * mpn/generic/sqr_n.c: Likewise.
+ * mpn/generic/mullo_n.c: Likewise.
+
+ * mpn/generic/mul.c: Loop also over mpn_nussbaumer_mul, as suggested by
+ Marco. Use TMP_SALLOC_LIMBS in more places. Clean up ws allocation.
+
+2009-12-19 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom_interpolate_8pts.c: Nailify.
+
+2009-12-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mul.c: Major rewrite. Use toom43, toom53, toom63.
+ Call mpn_nussbaumer_mul for largest operands.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_TOOM32_FOR_TOOM43_MUL): New macro.
+ (SPEED_ROUTINE_MPN_TOOM43_FOR_TOOM32_MUL): New macro.
+ (SPEED_ROUTINE_MPN_TOOM32_FOR_TOOM53_MUL): New macro.
+ (SPEED_ROUTINE_MPN_TOOM53_FOR_TOOM32_MUL): New macro.
+ (SPEED_ROUTINE_MPN_TOOM42_FOR_TOOM53_MUL): New macro.
+ (SPEED_ROUTINE_MPN_TOOM53_FOR_TOOM42_MUL): New macro.
+ * tune/common.c (speed_mpn_toom63_mul): New function.
+ (speed_mpn_toom32_for_toom43_mul): New function.
+ (speed_mpn_toom43_for_toom32_mul): New function.
+ (speed_mpn_toom32_for_toom53_mul): New function.
+ (speed_mpn_toom53_for_toom32_mul): New function.
+ (speed_mpn_toom42_for_toom53_mul): New function.
+ (speed_mpn_toom53_for_toom42_mul): New function.
+ * tune/tuneup.c (tune_mul_n): New name for old tune_mul.
+ (tune_sqr_n): New name for old tune_sqr.
+ (tune_mul): New function, for unbalanced multiplication.
+ * gmp-impl.h: Provide declarations for corresponding threshold vars.
+
+ * gmp-impl.h (mpn_rsh1add_nc, mpn_rsh1sub_nc): Declare.
+ * mpn/asm-defs.m4: Likewise.
+ * configure.in: Add corresponding HAVE_NATIVEs.
+ * mpn/x86_64/rsh1aors_n.asm: Add _nc entry point.
+
+2009-12-18 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/divexact.c: Rewrite to use mpn_divexact.
+
+ * mpn/generic/bdiv_q_1.c (mpn_bdiv_q_1): Deleted some unused
+ variables.
+
+ * mpn/generic/toom52_mul.c (mpn_toom52_mul)
+ [HAVE_NATIVE_mpn_add_n_sub_n]: Moved declaration of cy to avoid a
+ compiler warning.
+
+ * gmp-impl.h (gmp_pi1_t): Eliminated inv21 member.
+ (invert_pi1): ...and don't store it here.
+
+ * mpn/generic/toom63_mul.c (mpn_toom63_mul): Simplified
+ calculation of block size n.
+ * gmp-impl.h (mpn_toom63_mul_itch): Likewise.
+
+ * mpn/generic/toom_eval_pm2exp.c (mpn_toom_eval_pm2exp): Fixed
+ output asserts.
+
+2009-12-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/t-toom63.c: New test program.
+
+2009-12-18 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/invert.c: Nailify.
+ * mpn/generic/invertappr.c: Nailify.
+ * mpn/generic/mulmod_bnm1.c: Nailify.
+ * mpn/generic/sqrmod_bnm1.c: Nailify.
+
+ * tests/mpn/t-invert.c: New test program.
+
+ * mpn/generic/toom63_mul.c: New file.
+ * mpn/generic/toom_interpolate_8pts.c: New file.
+ * gmp-impl.h: Provide corresponding declarations.
+ * configure.in (gmp_mpn_functions): List toom_interpolate_8pts and
+ toom63_mul.
+
+2009-12-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mul.c: Move allocation of ws to where it is used.
+ Identify toom22, 32, 42, in that order (in two places). Use midline
+ between toom22, 32, 42.
+ * mpn/generic/toom22_mul.c (TOOM22_MUL_MN_REC): Call also
+ mpn_toom32_mul.
+
+ * doc/gmp.texi: Update References section. Update Contributors
+ section. Misc updates.
+
+ * gmp-impl.h: Renew default values for all THRESHOLDs.
+
+2009-12-17 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/divexact.c (mpn_divexact): Don't require that the
+ dividend is normalized. Use MPN_DIVREM_OR_PREINV_DIVREM_1. When
+ shifting, allocate and process only the low qn+1 limbs. Eliminated
+ code for the impossible case nn < qn.
+
+ * mpn/generic/dcpi1_div_qr.c (mpn_dcpi1_div_qr): Added some input
+ asserts.
+
+ * mpn/generic/dcpi1_div_qr.c (mpn_dcpi1_div_qr): In the case that
+ the initial quotient block is a single limb, use 3/2 division,
+ thereby eliminating the only use of gmp_pi1_t->inv21.
+
+2009-12-17 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/invert.c: Added some comment.
+ * mpn/generic/invertappr.c: Slightly better threshold handling.
+ * gmp-impl.h (INV_NEWTON_THRESHOLD): Default to 200.
+
+ * mpn/generic/nussbaumer_mul.c: New file.
+ * configure.in (gmp_mpn_functions): Add nussbaumer_mul.
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add nussbaumer_mul.
+ * gmp-impl.h (mpn_nussbaumer_mul): Added prototype and name-mangling.
+ * tune/speed.h (speed_mpn_nussbaumer_mul): Declare function.
+ * tune/common.c (speed_mpn_nussbaumer_mul): New function.
+ * tune/speed.c (routine): Add speed_mpn_nussbaumer_mul.
+
+ * mpn/generic/sqrmod_bnm1.c: New file.
+ * configure.in (gmp_mpn_functions): Add sqrmod_bnm1.
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add sqrmod_bnm1.
+ * gmp-impl.h (mpn_sqrmod_bnm1): Added prototype and name-mangling.
+ (SQRMOD_BNM1_THRESHOLD): support for the new threshold.
+ * tune/speed.h (speed_mpn_sqrmod_bnm1): Declare function.
+ * tune/common.c (speed_mpn_sqrmod_bnm1): New function.
+ * tune/speed.c (routine): Add speed_mpn_sqrmod_bnm1.
+ * tests/mpn/t-mulmod_bnm1.c: Attribution.
+ * tests/mpn/t-sqrmod_bnm1.c: New test file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add t-sqrmod_bnm1.
+
+ * tune/tuneup.c: Tune SQRMOD_BNM1_THRESHOLD.
+
+ * mpn/generic/nussbaumer_mul.c (mpn_nussbaumer_mul): Mimic fft_mul,
+ use squaring if operands coincide.
+ * tune/speed.h (speed_mpn_nussbaumer_mul_sqr): Declare function.
+ * tune/common.c (speed_mpn_nussbaumer_mul_sqr): New function.
+ * tune/speed.c (routine): Add speed_mpn_nussbaumer_mul_sqr.
+
+2009-12-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/bdiv_q.c (mpn_bdiv_q_itch): Rewrite.
+
+2009-12-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpn/t-bdiv.c (bdiv_q_valid_p, bdiv_qr_valid_p): Call refmpn_mul
+ instead of refmpn_mul_basecase.
+ * tests/mpn/toom-shared.h: Likewise.
+ * tests/refmpn.c (refmpn_mullo_n,refmpn_sqr,refmpn_mul_any): Likewise.
+
+ * minithres/gmp-mparam.h: Add new thresholds, trim old values.
+
+ * mpn/generic/powm.c: Use mp_bitcnt_t for bit counts.
+ Handle REDC_1_TO_REDC_N_THRESHOLD < MUL_TOOM22_THRESHOLD in
+ non-WANT_REDC_2 INNERLOOP expansion code.
+ * mpn/generic/powm_sec.c: Use mp_bitcnt_t for bit counts.
+
+2009-12-16 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-gcd.c (main): Added test case to exercise the
+ unlikely u0 == u1 case in mpn_gcdext_lehmer_n.
+
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_lehmer_n): Get ASSERT
+ right.
+
+2009-12-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-mul.c: Misc cleanups.
+ (mul_basecase): Remove.
+ (ref_mpn_mul): Remove.
+ * tests/refmpn.c (refmpn_mul): New function, mainly from t-mul.c's
+ ref_mpn_mul.
+ (refmpn_mullo_n): Add a missing free.
+
+ * tune/speed.c (routine): Measure speed_mpn_{sb,dc}pi1_div_qr,
+ mpn_{sb,dc}pi1_divappr_q, mpn_{sb,dc}pi1_bdiv_qr, and
+ mpn_{sb,dc}pi1_bdiv_q.
+
+ * mpn/generic/invertappr.c: New file, meat from invert.c.
+ * mpn/generic/invert.c: Leave just mpn_invert.c.
+ * configure.in (gmp_mpn_functions): Add invertappr.
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add invertappr.c.
+ * gmp-impl.h (mpn_invert_itch, mpn_invertappr_itch): New macros.
+
+2009-12-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/gcdext_subdiv_step.c: Get an ASSERT right.
+
+2009-12-15 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/sbpi1_div_qr.c (mpn_sbpi1_div_qr): A very small step
+ towards nail support.
+
+2009-12-15 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h (mpn_ni_invertappr): Added prototype and name-mangling.
+ * mpn/generic/mulmod_bnm1.c: Comment representation of class [0].
+
+2009-12-14 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/sbpi1_divappr_q.c (mpn_sbpi1_divappr_q): Use
+ udiv_qr_3by2.
+
+2009-12-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_binvert): Remove BINV_MULMOD_BNM1_THRESHOLD
+ tuning, it was always zero and caused BINV_NEWTON_THRESHOLD to be
+ wrong (as pointed out by Marco).
+ * (BINV_MULMOD_BNM1_THRESHOLD): Clean from other files too.
+
+2009-12-14 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/invert.c: Improved comments.
+ (mpn_bc_invertappr): Conditionally re-enable mpn_dcpi1_divappr_q.
+
+2009-12-14 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h (udiv_qr_3by2): Fix typo in argument list.
+
+2009-12-13 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h (udiv_qr_3by2): New macro.
+ * mpn/generic/sbpi1_div_qr.c (mpn_sbpi1_div_qr): Use udiv_qr_3by2.
+
+2009-12-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/dcpi1_divappr_q.c (mpn_dcpi1_divappr_q): Avoid a buffer
+ overrun.
+
+ * mpn/generic/mul_fft.c (mpn_mul_fft_full): Handle carry-out from 2nd
+ mpn_mul_fft, add an ASSERT for the 1st mpn_mul_fft. Replace some
+ comments on cc's range with ASSERTs.
+
+ * mpn/generic/gcdext.c (compute_v): Normalise tp[] after mpn_mul.
+
+ * mpz/powm.c: Rework buffer handling.
+
+2009-12-13 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/toom-shared.h (main): Use refmpn_mul_basecase to check
+ results (slow!). Iteration counts of all toom tests reduced
+ considerably.
+
+2009-12-13 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/invert.c (mpn_invertapp): Split in _bc and _ni.
+ (mpn_bc_invertappr): New function, the basecase.
+ (mpn_ni_invertapp): New function, Newton iteration.
+ (mpn_invert): Use mpn_ni_invertapp.
+ * tune/tuneup.c (tune_invert): Min for INV_APPR_THRESHOLD.
+ (tune_invertappr): Min for INV_NEWTON_THRESHOLD.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_NI_INVERTAPPR): New macro.
+ (speed_mpn_ni_invertappr): Declare function.
+ * tune/common.c (speed_mpn_ni_invertappr): New function.
+ * tune/speed.c (routine): Add speed_mpn_ni_invertappr.
+
+ * tune/tuneup.c (tune_invertappr): Use speed_mpn_ni_invertappr to
+ tune INV_MULMOD_BNM1_THRESHOLD.
+
+2009-12-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mu_bdiv_qr.c (mpn_mu_bdiv_qr_itch): Rewrite.
+
+2009-12-12 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpn/t-mulmod_bnm1.c (main): Disable B^n+1 stressing test
+ for odd sizes.
+
+ * mpn/generic/invert.c: Complete rewrite. Uses Newton iterations.
+ * gmp-impl.h (mpn_invertappr): Added prototype and name-mangling.
+ (mpn_invertappr_itch): Added prototype and name-mangling.
+ (INV_APPR_THRESHOLD): Support for a new tunable const.
+ * tune/speed.h (SPEED_ROUTINE_MPN_INVERTAPPR): New macro.
+ (speed_mpn_invertappr): Declare function.
+ * tune/common.c (speed_mpn_invertappr): New function.
+ * tune/speed.c (routine): Add speed_mpn_invertappr.
+ * tune/tuneup.c (tune_invertappr): New function: was tune_invert.
+ (tune_invert): Now tune only INV_APPR_THRESHOLD.
+ (all): Enable call to tune_invert and tune_invertappr.
+
+2009-12-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/binvert.c: Use mpn_mulmod_bnm1 instead of FFT wrapping.
+ Old, evidently broken wrapping code removed.
+ * tune/tuneup.c (tune_binvert): Tune BINV_MULMOD_BNM1_THRESHOLD.
+ * gmp-impl.h: Provide declarations for corresponding threshold var.
+
+ * tests/mpn/t-bdiv.c (COUNT): Decrease to keep run time reasonable.
+
+ * tune/tuneup.c (tune_invert): Tune INV_MULMOD_BNM1_THRESHOLD.
+ * gmp-impl.h: Provide declarations for corresponding threshold var.
+
+ * tests/mpn/t-mulmod_bnm1.c: Avoid a division by zero.
+
+ * configure.in: Set up different paths for different 64-bit sparc
+ processors.
+ * mpn/sparc64/ultrasparc34/gmp-mparam.h: New file.
+
+2009-12-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/*/gmp-mparam.h: Regenerate many of these files.
+
+2009-12-10 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h (mpn_divexact): Removed scratch pointer from
+ prototype.
+ * mpn/generic/gcdext.c (divexact): Deleted, moved to...
+ * mpn/generic/divexact.c (mpn_divexact): New implementation (moved
+ from gcdext.c). The bidirectional divexact is kept but #if:ed out.
+ Interface change, since the new code doesn't take a scratch
+ argument.
+
+ * tests/mpn/t-mulmod_bnm1.c (main): Ensure that an >= bn. Lowered
+ MIN_N to 1. Various fixes to handle n == 1 properly.
+
+ * mpn/generic/mulmod_bnm1.c (mpn_mulmod_bnm1): Small interface
+ change, require an >= bn.
+
+ * mpn/generic/mulmod_bnm1.c (mpn_mulmod_bnm1): Fixed non-recursive
+ case to not write beyond end of result area.
+
+2009-12-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_MULMOD_BNM1_CALL): New macro, made
+ from now deleted SPEED_ROUTINE_MPN_MULMOD_BNM1.
+ * tune/common.c (speed_mpn_bc_mulmod_bnm1): New function.
+ (speed_mpn_mulmod_bnm1): Use SPEED_ROUTINE_MPN_MULMOD_BNM1_CALL.
+ * tune/speed.c (routine): Add mpn_bc_mulmod_bnm1.
+
+ * mpn/generic/mulmod_bnm1.c (mpn_mulmod_bnm1_next_size): Rewrite.
+
+ * tune/tuneup.c (tune_mulmod_bnm1): Rewrite.
+
+2009-12-08 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mulmod_bnm1.c (mpn_bc_mulmod_bnm1,
+ mpn_bc_mulmod_bnp1): Added a parameter for scratch area, possibly
+ same as result area (as suggested by Niels Möller).
+ (mpn_mulmod_bnm1): Calls changed accordingly.
+
+2009-12-08 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext_1.c (mpn_gcdext_1) [GCDEXT_1_USE_BINARY]: Use
+ table lookup for count_trailing_zeros. Binary algorithm still
+ disabled by default.
+
+ * mpn/generic/gcdext.c (divexact): Local definition of divexact,
+ using mpn_bdiv_q.
+ (compute_v): Use it.
+
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-bdiv.
+
+ * tests/mpn/t-bdiv.c: New file.
+
+ * mpn/generic/bdiv_q.c (mpn_bdiv_q): Fixed bad quotient length,
+ should have qn == nn.
+
+ * mpn/generic/bdiv_qr.c (mpn_bdiv_qr): Pass correct nn length to
+ the lower-level functions.
+
+2009-12-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_MULMOD_BNM1_ROUNDED): New define.
+ * tune/common.c (speed_mpn_mulmod_bnm1_rounded): New function.
+ * tune/speed.c (routine): Add mpn_mulmod_bnm1_rounded for measuring
+ mpn_mulmod_bnm1 at recommended sizes.
+
+ * mpn/generic/mulmod_bnm1.c (mpn_mulmod_bnm1_next_size): Rewrite.
+ (mpn_bc_mulmod_bnm1): Use mpn_add_n instead of mpn_add.
+
+ * tune/speed.c (routine): Add mpn_invert.
+
+ * tune/tuneup.c (tune_invert): New function.
+ * tune/speed.h (SPEED_ROUTINE_MPN_INVERT): New macro.
+ * tune/common.c (speed_mpn_invert): New function.
+ * gmp-impl.h: Provide declarations for corresponding threshold var.
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add invert.c.
+
+2009-12-08 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/devel/try.c: Test mpn_addlsh2_n and mpn_{add,sub}lsh_n;
+ mpn_rsblsh_n now tests all shift values.
+ * tests/refmpn.c (refmpn_addlsh_n, refmpn_sublsh_n): New functions.
+ (refmpn_addlsh1_n): Use generic refmpn_addlsh_n.
+ (refmpn_sublsh1_n): Use generic refmpn_sublsh_n.
+ (refmpn_addlsh2_n): New function.
+ * tests/tests.h: Declare new functions.
+
+2009-12-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mulmod_bnm1): Up min_size to 12.
+
+ * Globally: Rename *mullow* to *mullo*, *MULLOW* to *MULLO*.
+
+ * configure.in: Don't include ev5 directory for ev6* and ev7. Misc
+ alpha path cleanups.
+ * mpn/alpha/add_n.asm: Replaced by mpn/alpha/ev5/add_n.asm.
+ * mpn/alpha/sub_n.asm: Replaced by mpn/alpha/ev5/sub_n.asm.
+ * mpn/alpha/lshift.asm: Replaced by mpn/alpha/ev5/lshift.asm.
+ * mpn/alpha/rshift.asm: Replaced by mpn/alpha/ev5/rshift.asm.
+ * mpn/alpha/com_n.asm: New, moved from mpn/alpha/ev5/rshift.asm.
+ * mpn/alpha/ev5/diveby3.asm: New, moved from mpn/alpha/diveby3.asm.
+
+ * mpn/powerpc64/mode64/diveby3.asm: Remove, it is slower than
+ mpn_bdiv_dbm1c on all hardware.
+
+ * mpn/generic/powm_sec.c: Rework logic for mpn_sqr_basecase size limit.
+
+ * gmp-impl.h (mpn_redc_1_sec): Declare.
+ * configure.in (gmp_mpn_functions): Add redc_1_sec.
+
+2009-12-06 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/devel/try.c (try_one): DATA_SRC0_HIGHBIT sets the high bit.
+
+2009-12-05 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom_eval_dgr3_pm1.c: Change return value: 0 or ~0.
+ * mpn/generic/toom_eval_dgr3_pm2.c: Likewise.
+ * mpn/generic/toom_eval_pm1.c: Likewise.
+ * mpn/generic/toom_eval_pm2exp.c: Likewise.
+ * mpn/generic/toom_eval_pm2.c: Rewrite to use mpn_addlsh2_n.
+
+ * mpn/generic/toom_interpolate_5pts.c: Param sa is a flag, not a sign.
+
+ * mpn/generic/toom33_mul.c: Adapt to changes above.
+ * mpn/generic/toom3_sqr.c: Likewise.
+ * mpn/generic/toom42_mul.c: Likewise.
+ * mpn/generic/toom43_mul.c: Reduce branches.
+ * mpn/generic/toom44_mul.c: Likewise.
+ * mpn/generic/toom53_mul.c: Likewise.
+ * mpn/generic/toom62_mul.c: Likewise.
+
+ * mpn/generic/toom52_mul.c: Use toom_eval_ functions.
+
+ * mpn/generic/toom4_sqr.c: Avoid C99 construct.
+ * mpn/generic/toom_interpolate_7pts.c: Likewise.
+
+2009-12-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/redc_1_sec.c: New file.
+ * mpn/generic/powm_sec.c: Use redc_1_sec. Use dummy full subtract
+ instead of mpn_cmp since the latter leaks to the side channel.
+ (mpn_local_sqr_n): New function, with associated macros.
+ (mpn_powm_sec): Use mpn_local_sqr_n.
+
+ * configure.in (HAVE_NATIVE): Add missing functions, then sort.
+
+2009-12-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_dc_div): Up min_size to 6.
+ (tune_mod_1): Set MOD_1_1_THRESHOLD min_size to 2.
+
+ * tune/speed.h: Negate "binvert"-type inverses, as required.
+
+ * mpn/generic/redc_1.c: Add ASSERTs.
+ * mpn/generic/redc_2.c: Likewise.
+
+ * mpn/generic/sbpi1_bdiv_q.c: Simplify loops, indexing.
+
+2009-12-03 Yann Droneaud <yann@droneaud.fr>
+
+ * acinclude.m4 ([long long reliability test 1]): Add a "static" for C99
+ inline semantics compatibility.
+
+2009-12-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Move intptr_t test into common AC_CHECK_TYPES.
+
+ * mpn/generic/gcdext.c: Add a TMP_FREE.
+
+2009-12-03 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext_1.c (mpn_gcdext_1) [GCDEXT_1_USE_BINARY]:
+ Added various masking tricks.
+
+ * mpn/generic/gcdext_1.c (mpn_gcdext_1) [GCDEXT_1_USE_BINARY]:
+ Reimplemented binary gcdext, with proper canonicalization.
+
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_lehmer_n): Handle v == 0
+ from mpn_gcdext_1.
+ * mpn/generic/gcdext_1.c (mpn_gcdext_1): Allow inputs with a < b,
+ assertions fixed accordingly.
+
+2009-12-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c: Tune DC_DIVAPPR_Q_THRESHOLD. Rewrite
+ DC_DIV_QR_THRESHOLD tuning code.
+ (tune_dc_div): Rewrite.
+ * tune/speed.h (SPEED_ROUTINE_MPN_PI1_DIV): New macro.
+ * tune/common.c (speed_mpn_sbpi1_div_qr, speed_mpn_dcpi1_div_qr,
+ speed_mpn_sbpi1_divappr_q, speed_mpn_sbpi1_bdiv_qr): New functions.
+ * gmp-impl.h: Provide declarations for corresponding threshold vars.
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add dcpi1_divappr_q.c.
+
+ * tune/tuneup.c (tune_binvert): Up max_size.
+
+2009-12-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/devel/try.c: Test mpn_rsblsh2_n and mpn_rsblsh_n.
+ * tests/refmpn.c (refmpn_rsblsh_n, refmpn_rsblsh2_n): New functions.
+ (refmpn_rsblsh1_n): Use generic refmpn_rsblsh_n.
+ * tests/tests.h: Declare new functions.
+
+2009-12-03 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext_subdiv_step.c (mpn_gcdext_subdiv_step):
+ Select the right cofactor in the cases A == B or A == 2B.
+
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_lehmer_n): Deleted
+ handling of ap[0] == 0 and bp[0] == 0; these cases don't happen.
+ Select the right cofactor in the case ap[0] == bp[0].
+ * mpn/generic/gcdext.c (mpn_gcdext): Analogous changes.
+
+2009-12-02 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-h.in (mpn_gcdext_1): Updated prototype.
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_lehmer_n): Updated for
+ signed cofactors from gcdext_1.
+ * mpn/generic/gcdext_1.c (mpn_gcdext_1): Use Euclid's algorithm,
+ and return signed cofactors.
+
+2009-12-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Low-level Functions): Document mpn_sqr_n.
+
+ * tune/speed.c (routine): Add mpn_binvert.
+
+ * tune/tuneup.c: Tune BINV_NEWTON_THRESHOLD.
+ (tune_binvert): New function.
+ * tune/speed.h (SPEED_ROUTINE_MPN_BINVERT): New macro.
+ * tune/common.c (speed_mpn_binvert): New function.
+ * gmp-impl.h: Provide declarations for corresponding threshold var.
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add binvert.c.
+
+ * tune/tuneup.c: Tune DC_BDIV_QR_THRESHOLD and DC_BDIV_Q_THRESHOLD.
+ (tune_dc_bdiv): New function.
+ (tune_dc_div): New name for tune_dc.
+ * tune/speed.h (SPEED_ROUTINE_MPN_PI1_BDIV_QR,
+ SPEED_ROUTINE_MPN_PI1_BDIV_Q): New macros.
+ * tune/common.c (speed_mpn_sbpi1_bdiv_qr, speed_mpn_dcpi1_bdiv_qr,
+ speed_mpn_sbpi1_bdiv_q, speed_mpn_dcpi1_bdiv_q): New functions.
+ * gmp-impl.h: Provide declarations for corresponding threshold vars.
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add dcpi1_bdiv_qr.c and
+ dcpi1_bdiv_q.c.
+
+2009-12-01 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom53_mul.c: Removed double computation of vinf.
+
+ * mpn/x86_64/aorrlsh_n.asm: Correct return value for rsblsh_n.
+ * mpn/asm-defs.m4 (define_mpn): Add rsblsh_n.
+ * gmp-impl.h (mpn_rsblsh_n): Added prototype and name-mangling.
+
+ * mpn/generic/fib2_ui.c: Reduce the amount of temporary storage.
+ Use mpn_rsblsh_n.
+
+2009-12-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/redc_n.c: Rework temp allocation.
+
+ * mpn/generic/dcpi1_bdiv_qr.c (mpn_dcpi1_bdiv_qr_n_itch): Add pi1 also
+ to this function.
+
+ * mpn/generic/dcpi1_bdiv_q.c: Get the mpn_sbpi1_bdiv_q call right.
+ Misc cleanups.
+
+ * tune/speed.c (routine): Fix typo in last change.
+ Add mpn_redc_2.
+
+ * tune/speed.h (SPEED_ROUTINE_REDC_N): Set min size properly.
+
+2009-12-01 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/speed.c (routine): Added mpn_toom42_mul and mpn_redc_n.
+ * tune/speed.h (SPEED_ROUTINE_MPN_TOOM42_MUL): New macro.
+ (speed_mpn_toom42_mul): Declare function.
+ * tune/common.c (speed_mpn_toom42_mul): New function.
+ * gmp-impl.h (MPN_TOOM42_MUL_MINSIZE): New constant.
+
+2009-11-30 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/fib2_ui.c: Use mpn_rsblsh2_n.
+
+2009-11-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/pentium4/gmp-mparam.h
+ (HAVE_NATIVE_mpn_addlsh1_n, HAVE_NATIVE_mpn_sublsh1_n): Don't undef.
+
+ * Makefile.am (EXTRA_DIST): Remove macos.
+
+2009-11-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_redc): Set min_size to 16 for redc_n tuning.
+
+ * mpn/x86_64/sqr_basecase.asm (SQR_TOOM2_THRESHOLD_MAX): Avoid quoting
+ to allow configure.in parse it more easily. Trim from 120 to 80.
+
+2009-11-28 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mulmod_bnm1.c: Basecases made simpler, this also corrects
+ a bug affecting previous version.
+
+2009-11-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Handle atom also in 32-bit mode.
+ * mpn/x86/atom/gmp-mparam.h: New file.
+
+ * gmp-impl.h (MULMOD_BNM1_THRESHOLD): Default.
+
+ * mpn/generic/redc_n.c: Use mpn_mulmod_bnm1 instead of mpn_mul_n.
+
+ * Use TMP_ALLOC_LIMBS consistently.
+ * Finish renaming BITS_PER_MP_LIMB to GMP_LIMB_BITS.
+
+ * macos: Remove entire directory.
+
+2009-11-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/corei/gmp-mparam.h: New file.
+ * mpn/x86_64/core2/gmp-mparam.h: Now for just core2.
+ * mpn/powerpc64/mode64/p3/gmp-mparam.h: New file.
+ * mpn/powerpc64/mode64/p4/gmp-mparam.h: New file.
+ * mpn/powerpc64/mode64/p5/gmp-mparam.h: New file.
+
+ * config.guess: Return "corei" for core i7 and core i5.
+ * config.sub: Recognise "corei".
+ * acinclude.m4 (X86_64_PATTERN): Add corei.
+ * configure.in (powerpc): Set up more CPU-specific paths.
+ (x86): Handle corei.
+
+ * mpz/powm.c: Allow input operand overlap also when exponent = 1.
+ Misc cleanups.
+
+2009-11-26 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * tests/mpn/t-mulmod_bnm1.c: New test file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add t-mulmod_bnm1.
+
+ * mpn/generic/mullow_n.c: Comments on Mulders' trick implementation.
+
+2009-11-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm.c: Make comments reflect current code state.
+
+ * tests/devel/try.c: Make mpn_mullow_n testing actually work.
+
+2009-11-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/powm.c: Clean up unused defs.
+
+2009-11-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_redc): Rewrite.
+ * mpn/generic/powm.c: Use REDC_1_TO_REDC_2_THRESHOLD,
+ REDC_1_TO_REDC_N_THRESHOLD, and REDC_2_TO_REDC_N_THRESHOLD.
+ Get rid of previous REDC params, including LOCAL_REDC_N_THRESHOLD.
+ (WANT_REDC_2): Define.
+ * gmp-impl.h: Corresponding changes.
+
+2009-11-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm.c: Fix typo.
+ Define LOCAL_REDC_N_THRESHOLD, use in REDC_2_THRESHOLD...
+ REDC_N_THRESHOLD chain.
+
+2009-11-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mullow): Set min_size to 1.
+
+ * mpn/generic/powm_sec.c: Use just mpn_mul_basecase and
+ mpn_sqr_basecase for multiplication and squaring.
+
+ * tune/tuneup.c: Tune REDC_2_THRESHOLD and REDC_N_THRESHOLD.
+ (tune_redc): New function.
+ (tune_powm): Remove function.
+ * tune/speed.h (SPEED_ROUTINE_REDC_2, SPEED_ROUTINE_REDC_N): New.
+ * tune/common.c (speed_mpn_redc_2, speed_mpn_redc_n): New.
+
+ * mpz/powm.c: Complete rewrite. Use mpn_powm and mpn_powlo.
+ * mpn/generic/powm.c: Rewrite.
+ * mpn/generic/redc_n.c: New file.
+ * configure.in (gmp_mpn_functions): Add redc_n.
+ * gmp-impl.h (REDC_2_THRESHOLD, REDC_N_THRESHOLD): Default, and define
+ for tuneup.
+
+2009-11-21 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mullow_n.c: Disable Mulders' trick for small operands,
+ use fft for bigger ones.
+ * tests/mpn/t-mullo.c: New test file.
+
+2009-11-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mullow): Rewrite.
+
+2009-11-21 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * gmp-impl.h: Removed unused macros (CACHED_ABOVE_THRESHOLD and
+ CACHED_BELOW_THRESHOLD).
+
+ * mpn/generic/mullow_n.c: Use Mulders' trick.
+ * tune/tuneup.c (tune_mullow): MULLOW_MUL_N_THRESHOLD range of
+ search depends on FFT tuning;
+ (all): Anticipate tune_fft_{mul,sqr}.
+
+ * tune/speed.c (routine): Add entry related to mpn_mulmod_bnm1.
+
+2009-11-19 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/toom_eval_dgr3_pm2.c (mpn_toom_eval_dgr3_pm2)
+ [HAVE_NATIVE_mpn_add_n_sub_n]: Fixed typo in mpn_add_n_sub_n call
+ (spotted by Marco Bodrato).
+ * mpn/generic/toom_eval_pm2.c (mpn_toom_eval_pm2): Likewise.
+ * mpn/generic/toom_eval_pm2exp.c (mpn_toom_eval_pm2exp): Likewise.
+
+ * mpn/generic/toom_eval_pm2.c (mpn_toom_eval_pm2) [HAVE_NATIVE_mpn_addlsh_n]:
+ Fixed missing declaration.
+
+ * mpn/asm-defs.m4 (define_mpn): Add addlsh_n.
+ * gmp-impl.h (mpn_addlsh_n): Added prototype and name-mangling.
+
+2009-11-19 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/toom_eval_pm2.c (mpn_toom_eval_pm2): New file.
+ * mpn/generic/toom53_mul.c (mpn_toom53_mul): Use mpn_toom_eval_pm2.
+ * mpn/generic/toom62_mul.c (mpn_toom62_mul): Likewise.
+ * configure.in (gmp_mpn_functions): Added toom_eval_dgr3_pm2.
+
+2009-11-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (mpn_and_n, etc): Adapt to now-public logic functions.
+
+ * config.guess: Recognise VIA nano.
+ * config.sub: Likewise.
+ * configure.in: Generalise x86_64 support; recognise VIA nano.
+
+2009-11-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.c (routine): Add measurement of mpn_addlsh2_n,
+ mpn_sublsh2_n, mpn_rsblsh2_n.
+ * tune/common.c: Add speed routines for lsh2 functions.
+
+ * mpn/generic/divis.c: Use MU_BDIV_QR_THRESHOLD.
+
+ * configure.in (gmp_mpn_functions_optional): Add *lsh_n functions.
+
+ * mpn/generic/toom_eval_pm2exp.c: Make HAVE_NATIVE_mpn_addlsh_n code
+ work.
+
+ * mpn/x86_64/aorrlsh2_n.asm: Optimise inner loop.
+
+ * configure.in (gmp_mpn_functions_optional): Remove copyi,copyd, they
+ are now in gmp_mpn_functions. Analogously move logical functions.
+
+2009-11-16 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom53_mul.c: Use addlsh2 for evaluation (and fix typo).
+ * mpn/generic/toom_eval_dgr3_pm2.c: Likewise (affects toom44 and 43).
+
+ * mpn/asm-defs.m4: Fix comments for op_lsh2 new functions.
+ * gmp-impl.h: Likewise.
+ * tests/mpz/t-fac_ui.c: Fix a comment.
+
+2009-11-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/aorrlsh2_n.asm: New file.
+ * configure.in: Add support for addlsh2_n, sublsh2_n, and rsblsh2_n,
+ including mulfuncs.
+ * gmp-impl.h (mpn_addlsh2_n, mpn_sublsh2_n, mpn_rsblsh2_n): Declare.
+ * mpn/asm-defs.m4: Likewise.
+
+ * mpn/generic/copyi.c: New file.
+ * mpn/generic/copyd.c: Likewise.
+ * mpn/generic/zero.c: Likewise.
+ * gmp-h.in: Declare new functions.
+ * configure.in (gmp_mpn_functions): Add new functions.
+
+2009-11-15 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mulmod_bnm1.c (mpn_mulmod_bnm1_next_size): fix typo
+
+ * mpn/generic/toom33_mul.c: Use rsblsh1 for evaluation.
+ * mpn/generic/toom3_sqr.c: Likewise.
+
+2009-11-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom52_mul.c: Use mpn_addlsh1_n.
+
+ * mpn/generic/toom52_mul.c: Toggle the right flag bit in an
+ HAVE_NATIVE_mpn_add_n_sub_n arm.
+
+ * tests/mpz/t-remove.c: New file.
+
+ * mpn/generic/remove.c: Major overhaul. Add parameter 'cap'.
+
+ * mpn/generic/binvert.c: Fix typo in last change.
+
+ * mpn/generic/bdiv_qr.c: Make it actually work. Also use passed-in
+ scratch space.
+
+ * mpn/generic/mu_bdiv_qr.c: Reset FFT parameters for each call.
+
+2009-11-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/gcd_1.asm (MASK): Compute from MAXSHIFT.
+
+2009-11-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/binvert.c: Simplify, fix comments.
+
+ * tests/devel/try.c: Test mpn_invert and mpn_binvert.
+
+ * tests/refmpn.c (refmpn_invert, refmpn_binvert): New functions.
+ * tests/tests.h: Declare new functions.
+
+2009-11-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Supply compiler options for atom in 32-bit mode.
+
+ * acinclude.m4 (X86_64_PATTERN): New.
+ * configure.in: Setup and use X86_64_PATTERN.
+
+ * mpn/x86_64/fat/fat.c: New file.
+ * mpn/x86_64/fat/fat_entry.asm: New file.
+ * mpn/x86_64/fat: Copy C placeholder files from mpn/x86/fat.
+ * mpn/x86_64/x86_64-defs.m4 (CPUVEC_FUNCS_LIST): New, copied from
+ mpn/x86/x86-defs.m4.
+ * configure.in: Move down x86 fat setup code until after ABI has been
+ determined; generalise to handle x86_64.
+
+2009-11-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/fat/mod_1.c: New file.
+
+ * acinclude.m4 (GMP_C_FOR_BUILD_ANSI): Avoid poor quoting.
+
+2009-11-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (MPN_LOGOPS_N_INLINE): Rewrite, update interface. Callers
+ updated.
+ * mpn/generic/logops_n.c: New file.
+ * doc/gmp.texi (Low-level Functions): Document logical mpn functions.
+
+2009-11-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_MULMOD_BNM1): Adapt to new
+ mpn_mulmod_bnm1 interface.
+
+2009-11-07 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mulmod_bnm1.c: New interface, with size
+ specified for all operands in mpn_mulmod_bnm1.
+ * gmp-impl.h: Changed mpn_mulmod_bnm1 prototype.
+
+2009-11-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/gcd_1.asm: Actually use div-reduced value.
+ Mnemonic cleanup.
+
+ * mpn/x86_64/gcd_1.asm: New file.
+
+2009-11-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add sqr_n.c.
+
+2009-11-03 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom_interpolate_6pts.c: removed an addmul_1 and cleanup.
+
+2009-11-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (gmp_mpn_functions): Remove obsolete functions
+ dc_divrem_n and sb_divrem_mn.
+ * gmp-impl.h: Misc cleanup.
+ (mpn_sb_divrem_mn, mpn_dc_divrem_n): Remove.
+ (DIV_DC_THRESHOLD): Remove.
+ * mpn/generic/dc_divrem_n.c: Remove.
+ * mpn/generic/sb_divrem_mn.c: Remove.
+ * mpn/generic/tdiv_qr.c: Use DC_DIV_QR_THRESHOLD, not DIV_DC_THRESHOLD.
+
+ * tests/devel/try.c: Replace mpn_sb_divrem_mn by mpn_sbpi1_div_qr.
+ * tests/refmpn.c (refmpn_sb_div_qr): New name for refmpn_sb_divrem_mn.
+
+ * tune/Makefile.am (libspeed_la_SOURCES): Remove sb_div.c and sb_inv.c.
+ (TUNE_MPN_SRCS_BASIC): Remove sb_divrem_mn.c.
+ * tune/common.c (speed_mpn_dcpi1_div_qr_n): New function.
+ Remove mpn_sb_divrem_mn related functions.
+ * tune/speed.c (routine): Remove entries related to mpn_dc_divrem and
+ mpn_sb_divrem.
+ (routine): New entry for mpn_dc_div_qr_n.
+ * tune/speed.h (SPEED_ROUTINE_MPN_DC_DIVREM_CALL): Compute inverse
+ needed by pi1 calls.
+ (SPEED_ROUTINE_MPN_SB_DIVREM_M3): Remove.
+ * tune/tuneup.c (tune_sb_preinv): Remove.
+ (tune_dc): Update to measure DC_DIV_QR_THRESHOLD.
+
+ * mpn/generic/sb_divappr_q.c: Remove.
+
+2009-11-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h: Misc minor cleanups.
+
+2009-10-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (toom itch functions): Simplify, make some into macros.
+ (MPN_KARA_MUL_N_TSIZE, MPN_KARA_SQR_N_TSIZE): Remove.
+ * mpn/generic/mul_n.c (mpn_toom3_mul_n, mpn_toom3_sqr_n): Remove.
+ * mpn/generic/mul_n.c (mpn_sqr_n): Move from here...
+ * mpn/generic/sqr_n.c: ...to this new file.
+ * configure.in (gmp_mpn_functions): Add sqr_n.
+
+ * Globally change
+ MUL_TOOM3_THRESHOLD => MUL_TOOM33_THRESHOLD,
+ MUL_KARATSUBA_THRESHOLD => MUL_TOOM22_THRESHOLD,
+ SQR_KARATSUBA_THRESHOLD => SQR_TOOM2_THRESHOLD,
+ and associated names analogously.
+
+2009-10-31 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/toom_interpolate_7pts.c: Changed evaluation points,
+ replacing -1/2 by -2.
+ * mpn/generic/toom44_mul.c: Updated to use new evaluation points,
+ and use mpn_toom_eval_dgr3_pm2.
+ * mpn/generic/toom4_sqr.c (mpn_toom4_sqr): Likewise.
+ * mpn/generic/toom53_mul.c (mpn_toom53_mul): Updated to use new
+ evaluation points, and use mpn_toom_eval_pm1 and
+ mpn_toom_eval_pm2exp.
+ * mpn/generic/toom62_mul.c (mpn_toom62_mul): Likewise.
+
+ * mpn/generic/toom_eval_pm2exp.c: New file.
+ * mpn/generic/toom_eval_pm1.c: New file.
+
+ * mpn/generic/toom43_mul.c (mpn_toom43_mul): Use
+ mpn_toom_eval_dgr3_pm2.
+
+2009-10-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add toom2* and toom3* files.
+
+2009-10-30 Niels Möller <nisse@lysator.liu.se>
+
+ * configure.in (gmp_mpn_functions): Added toom_eval_dgr3_pm2.
+ * gmp-impl.h: Added prototype for mpn_toom_eval_dgr3_pm2.
+ * mpn/generic/toom_eval_dgr3_pm2.c: New file.
+
+2009-10-29 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/toom43_mul.c (mpn_toom43_mul): Use
+ mpn_toom_eval_dgr3_pm1.
+ * mpn/generic/toom42_mul.c (mpn_toom42_mul): Likewise.
+
+2009-10-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mulmod_bnm1.c: Replace some add_1 by INCR.
+
+ * gmp-impl.h (mpn_mulmod_bnm1_itch): New macro.
+
+ * mpn/generic/mulmod_bnm1.c (mpn_mulmod_bnm1): Call mpn_mul_fft.
+ (mpn_mulmod_bnm1_next_size): Adopt to SS FFT.
+
+ * mpn/generic/mul_fft.c (mpn_mul_fft): Make it return high limb.
+ (mpn_mul_fft_internal): Likewise.
+
+ * mpn/generic/mulmod_bnm1.c: New file, by Niels Möller.
+ * configure.in (gmp_mpn_functions): Add mulmod_bnm1.
+ * gmp-impl.h: Add related declarations.
+ * tune/tuneup.c: Tune MULMOD_BNM1_THRESHOLD.
+ * tune/speed.h (SPEED_ROUTINE_MPN_MULMOD_BNM1): New macro.
+ * tune/common.c (speed_mpn_mulmod_bnm1): New function.
+ * Makefile.am (TUNE_MPN_SRCS_BASIC): Add mulmod_bnm1.c.
+
+ * gmp-impl.h (mpn_kara_mul_n, mpn_kara_sqr_n): Remove declarations.
+ * tune/common.c: Remove/rename kara functions.
+ * tune/speed.h: Likewise.
+
+ * tests/devel/try.c: Clean up usage of %p printf arguments.
+
+ * gmp-impl.h: Update MUL/SQR MINSIZE macros to reflect new function
+ names and limitations
+ * tune/tuneup.c: Use updated macro names.
+ * tune/speed.h: Likewise.
+ * tests/devel/try.c: Test new mul/sqr functions, remove old tests.
+
+2009-10-29 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/speed.c: Added support for mpn_toom4_sqr,
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_TOOM4_SQR): New macro.
+ (SPEED_ROUTINE_MPN_KARA_MUL_N): Deleted.
+ (SPEED_ROUTINE_MPN_TOOM3_MUL_N): Deleted.
+ (SPEED_ROUTINE_MPN_TOOM2_SQR): Use mpn_toom2_sqr_itch.
+
+ * gmp-impl.h (mpn_toom3_mul_n, mpn_toom3_sqr_n): Remove
+ declarations.
+ (mpn_toom2_sqr_itch): Add margin for recursive calls.
+
+2009-10-28 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/mul_n.c (mpn_kara_mul_n): Deleted old Karatsuba
+ implementation.
+ (mpn_kara_sqr_n): Likewise deleted.
+
+ * mpn/generic/mul_n.c (mpn_sqr_n): Use mpn_toom2_sqr and
+ mpn_toom3_sqr, not the old implementations.
+
+ * gmp-impl.h (MPN_TOOM3_MUL_N_TSIZE): Deleted, replaced by
+ mpn_toom33_mul_itch.
+ (MPN_TOOM3_SQR_N_TSIZE): Deleted, replaced by
+ mpn_toom3_sqr_itch.
+ (mpn_toom33_mul_itch): Needs more scratch.
+ (mpn_toom3_sqr_itch): Likewise.
+ * tune/speed.h (SPEED_ROUTINE_MPN_TOOM3_MUL_N): Use
+ mpn_toom33_mul_itch.
+ (SPEED_ROUTINE_MPN_TOOM3_SQR_N): Use mpn_toom3_sqr_itch.
+ * mpn/generic/mul_n.c (mpn_mul_n): Use mpn_toom33_mul_itch.
+ (mpn_sqr_n): Use mpn_toom3_sqr_itch.
+
+ * mpn/generic/toom33_mul.c (mpn_toom33_mul): Avoid TMP_ALLOC. Needs
+ some more supplied scratch instead.
+ * mpn/generic/toom3_sqr.c (mpn_toom3_sqr): Likewise.
+
+2009-10-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (invert_pi1): Streamline, as suggested by Niels.
+
+2009-10-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/bdiv_q.c: Update to call new functions.
+ * mpn/generic/bdiv_qr.c: Likewise.
+ * mpn/generic/binvert.c: Likewise.
+ * mpn/generic/divexact.c: Likewise.
+ * mpn/generic/divis.c: Likewise.
+ * mpn/generic/perfpow.c: Likewise.
+ * mpn/generic/tdiv_qr.c: Likewise.
+ * mpn/generic/dcpi1_bdiv_q.c: New file.
+ * mpn/generic/dcpi1_bdiv_qr.c: New file.
+ * mpn/generic/dcpi1_div_q.c: New file.
+ * mpn/generic/dcpi1_div_qr.c: New file.
+ * mpn/generic/dcpi1_divappr_q.c: New file.
+ * mpn/generic/sbpi1_bdiv_q.c: New file.
+ * mpn/generic/sbpi1_bdiv_qr.c: New file.
+ * mpn/generic/sbpi1_div_q.c: New file.
+ * mpn/generic/sbpi1_div_qr.c: New file.
+ * mpn/generic/sbpi1_divappr_q.c: New file.
+ * mpn/generic/dc_bdiv_q.c: Removed.
+ * mpn/generic/dc_bdiv_qr.c: Removed.
+ * mpn/generic/dc_div_q.c: Removed.
+ * mpn/generic/dc_div_qr.c: Removed.
+ * mpn/generic/dc_divappr_q.c: Removed.
+ * mpn/generic/sb_bdiv_q.c: Removed.
+ * mpn/generic/sb_bdiv_qr.c: Removed.
+ * mpn/generic/sb_div_q.c: Removed.
+ * mpn/generic/sb_div_qr.c: Removed.
+
+ * configure.in (gmp_mpn_functions): Add new division functions, remove
+ obsolete division functions.
+
+ * gmp-impl.h: Add declarations of new division functions, remove
+ corresponding obsolete declarations.
+ (gmp_pi1_t, gmp_pi2_t): New types.
+ (invert_pi1): New macro for computing 2/1 and 3/2 inverses.
+
+2009-10-23 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h (mpn_toom62_mul_itch): New function.
+
+ * tests/mpn/t-toom53.c: New test program.
+ * tests/mpn/t-toom62.c: New test program.
+
+2009-10-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/get_d.c: Fix code handling denorms for 64-bit machines.
+ * tests/mpf/t-get_d.c (test_denorms): New function.
+
+2009-10-23 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/toom52_mul.c (mpn_toom52_mul): Use supplied scratch
+ space, not TMP_ALLOC. Interface change, now requires input sizes
+ such that s + t >= 5.
+
+ * gmp-impl.h (mpn_toom52_mul_itch): New function.
+
+ * tests/mpn/t-toom52.c: New test program.
+
+2009-10-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/sqr_basecase.asm: Tune for speed and a 7% size decrease.
+
+2009-10-22 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/t-toom44.c: New test program.
+ * tests/mpn/t-toom33.c: New test program.
+
+ * tests/mpn/toom-shared.h (main): Reorganized input generation.
+ Users are now supposed to define macros MAX_AN, MIN_BN and MAX_BN.
+ Updated existing toom test programs.
+
+2009-10-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/devel/try.c: Fix typos in last change.
+
+2009-10-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/asm-defs.m4 (define_mpn): Add mullow_basecase.
+
+ * tests/devel/try.c: Test mpn_mullow_n.
+
+ * tests/refmpn.c (refmpn_mullow_n): New function.
+ * tests/tests.h: Declare it.
+
+2009-10-21 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/toom-shared.h (main): Check for writes outside of the
+ product or scratch area.
+
+ * gmp-impl.h (mpn_toom43_mul_itch): New function.
+
+ * mpn/generic/toom43_mul.c (mpn_toom43_mul): Use supplied scratch
+ space, not TMP_ALLOC. Interface change, now requires input sizes
+ such that s + t >= 5.
+
+2009-10-20 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/toom-shared.h (MIN_BLOCK): New constant, which can be
+ overridden by users. Needed by t-toom42 and t-toom43.
+
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-toom32,
+ t-toom42 and t-toom43.
+ * tests/mpn/t-toom43.c: New test program.
+ * tests/mpn/t-toom42.c: New test program.
+ * tests/mpn/t-toom32.c: New test program.
+
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-toom22.
+ * tests/mpn/t-toom22.c: New test file.
+ * tests/mpn/toom-shared.h: New file. Test framework for Toom
+ functions.
+
+2009-10-14 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (mpn_hgcd_itch): Thanks to the new
+ mpn_matrix22_mul_strassen, the scratch need is reduced by 16%.
+
+2009-10-14 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/matrix22_mul.c (mpn_matrix22_mul_strassen): New
+ Strassen-like algorithm, to reduce the amount of temporary
+ storage.
+ (mpn_matrix22_mul_itch): Updated to reflect the reduced storage
+ need.
+
+2009-10-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * Rename mpn_addsub_n to mpn_add_n_sub_n.
+
+2009-10-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/tdiv_qr.c: Call mpn_divrem_1 and mpn_dc_div_qr instead of
+ old functions.
+
+ * mpn/generic/mul_n.c: Call toom22 and toom33 instead of old functions.
+
+ * mpn/generic/toom42_mul.c (TOOM42_MUL_N_REC): Renamed from
+ TOOM22_MUL_N_REC. Unconditionally call the generic mpn_mul_n.
+ * mpn/generic/toom32_mul.c: Analogous changes.
+
+2009-09-28 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86_64/invert_limb.asm: Rewrite. Exploit cancellation in the
+ Newton iteration.
+
+2009-09-27 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86/invert_limb.asm: Reduce register usage. Eliminated $1
+ arguments to add, sub and shift.
+
+2009-09-25 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86/invert_limb.asm: New file.
+
+2009-09-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom33_mul.c: Use new toom functions for all recursive
+ products.
+ * mpn/generic/toom3_sqr.c: Likewise.
+ * mpn/generic/toom44_mul.c: Likewise.
+ * mpn/generic/toom4_sqr.c: Likewise.
+
+ * mpn/generic/add_n.c: Relax operand overlap ASSERTs.
+ * mpn/generic/sub_n.c: Likewise.
+
+2009-09-15 Torbjorn Granlund <tege@gmplib.org>
+
+ Suggested by Uwe Mueller:
+ * printf/doprnt.c: Use "%ld" for exponent printing.
+ * printf/doprntf.c (__gmp_doprnt_mpf): Make expval "long".
+
+2009-09-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Handle mingw64.
+ * gmp-impl.h (gmp_intptr_t): Declare.
+ * tests/amd64check.c (calling_conventions_values): Use CNST_LIMB.
+ * tests/memory.c: Use gmp_intptr_t; print pointers using C90 "%p".
+ * tests/misc.c: Use gmp_intptr_t.
+ * tests/mpq/t-get_str.c: Print pointers using C90 "%p".
+
+2009-08-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mod_1_1.c (mpn_mod_1_1p_cps): Remove silly ASSERT code.
+
+ * mpn/asm-defs.m4 (define_mpn): Remove mod_1s_1p, add mod_1_1p.
+
+ * mpn/arm/invert_limb.asm: Complete rewrite.
+
+ * longlong.h: Document LONGLONG_STANDALONE and NO_ASM.
+
+2009-08-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/dive_ui.c (check_random): Avoid zero divisors.
+
+2009-07-31 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mod_1_1.c: Tweak to handle any modulus (possibility
+ pointed out by Per Austrin).
+ (mpn_mod_1_1p): Renamed from mpn_mod_1s_1p.
+ (mpn_mod_1_1p_cps): Renamed from mpn_mod_1s_1p_cps.
+ *mpn/generic/mod_1.c (mpn_mod_1): Reorganise to call mpn_mod_1_1p for
+ any modulus.
+
+2009-07-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Pass arch for x86 also in 64-bit mode.
+
+2009-07-26 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess (_cpuid): Recognise more Intel "Core" processors.
+
+2009-07-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpf/eq.c: Rewrite.
+
+ * tests/mpf/t-eq.c: New test.
+
+2009-07-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (__mp_bases): Remove this alias.
+
+ * mpf/get_str.c: Use less overflow prone expression for computing limb
+ allocation.
+ * mpz/inp_str.c: Likewise.
+ * mpf/set_str.c: Likewise.
+ * mpz/set_str.c: Likewise.
+
+2009-07-03 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcd_1.c (mpn_gcd_1): Use masking tricks to reduce
+ the number of branches in the loop.
+
+2009-06-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * demos/factorize.c (factor_using_pollard_rho): Rewrite.
+
+ * mpz/clears.c: New file.
+ * mpq/clears.c: New file.
+ * mpf/clears.c: New file.
+ * gmp-h.in (mpz_clears, mpq_clears, mpf_clears): Declare.
+ * mpz/Makefile.am: Add clears.c.
+ * mpq/Makefile.am: Add clears.c.
+ * mpf/Makefile.am: Add clears.c.
+ * Makefile.am: Add these also to respective OBJECTS variables.
+ * doc/gmp.texi: Document inits function and clears functions.
+
+2009-06-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mp-h.in (mp_bitcnt_t): Declare here too.
+
+2009-06-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpq/inits.c: New file.
+ * mpf/inits.c: New file.
+ * gmp-h.in (mpz_inits, mpq_inits, mpf_inits): Declare .
+
+ * mpn/generic/remove.c: New file.
+ * configure.in (gmp_mpn_functions): Add remove.
+ * gmp-impl.h (mpn_remove): Declare.
+
+ * gmp-h.in (mp_bitcnt_t): New basic type.
+ * mpn/generic/perfpow.c (mp_bitcnt_t): Remove private definition.
+
+ * mpn/generic/bdiv_qr.c: Make it actually work.
+
+ * mpn/x86_64/core2/aorsmul_1.asm: Rewrite to use shorter pipeline and
+ to need fewer registers.
+
+2009-06-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/rsh1aors_n.asm: New file.
+ * mpn/x86_64/rsh1add_n.asm: Remove.
+ * mpn/x86_64/rsh1sub_n.asm: Remove.
+
+ * mpz/inits.c: New file.
+
+ * gen-trialdivtab.c: Wrap limb constants into CNST_LIMB.
+
+ With Martin Boij:
+ * mpn/generic/perfpow.c (binv_root, binv_sqroot): Change from being
+ recursive to being iterative.
+ (mpn_perfect_power_p): Reorganise temp memory usage to avoid a buffer
+ overrun. Trim allocation of next and prev. Never create oversize
+ products in the multiplicity binary search.
+
+ * mpn/generic/dc_div_q.c: Add missing TMP_FREE.
+
+2009-06-16 Torbjorn Granlund <tege@gmplib.org>
+
+ Revert:
+ * mpn/generic/perfpow.c (perfpow): Test exponents up to ub, inclusive.
+
+2009-06-16 Martin Boij <mboij@kth.se>
+
+ * mpn/generic/perfpow.c (logs): Use more conservative table.
+
+2009-06-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/pa64/aors_n.asm: New file.
+ * mpn/pa64/add_n.asm: Remove.
+ * mpn/pa64/sub_n.asm: Remove.
+
+ * mpn/generic/perfpow.c (perfpow): Test exponents up to ub, inclusive.
+
+2009-06-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bdiv_q_1.asm: Optimise away a mov insn.
+ * mpn/x86_64/dive_1.asm: Likewise.
+
+ * mpn/generic/perfpow.c (binv_root): Use mpn_bdiv_q_1, not
+ mpn_divexact_itch for 2-adic division.
+ (all functions): Micro optimise.
+
+ * Makefile.am (libmp_la_SOURCES): Add nextprime.c.
+
+2009-06-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (mpn_perfect_power_p): Declare.
+ * configure.in (gmp_mpn_functions): Add perfpow.
+ * mpz/perfpow.c: Now trivial, simply calls mpn_perfect_power_p.
+
+2009-06-13 Martin Boij <mboij@kth.se>
+
+ * mpn/generic/perfpow.c: New file.
+ * tests/mpz/t-perfpow.c: Rewrite.
+
+2009-06-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/bdiv_qr.c: New file.
+ * mpn/generic/bdiv_q.c: New file.
+ * configure.in (gmp_mpn_functions): Add bdiv_qr and bdiv_q.
+ * gmp-impl.h: Declare new functions.
+
+ * nextprime.c: New file.
+ * gmp-impl.h (gmp_primesieve_t, gmp_init_primesieve, gmp_nextprime):
+ Declare.
+ * Makefile.am (libgmp_la_SOURCES): Add nextprime.c.
+
+2009-06-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/trialdiv.c: New file.
+ * gen-trialdivtab.c: New file.
+ * configure.in (gmp_mpn_functions): Add trialdiv.
+ * gmp-impl.h (mpn_trialdiv): Declare
+ * Makefile.am: Add rules for gen-trialdivtab and trialdiv.
+
+ * longlong.h (arm count_leading_zeros): Define for armv5.
+
+ * gmp-impl.h: Move down toom itch functions to after we've #defined
+ all THRESHOLDs.
+
+ * dumbmp.c (isprime): Replace with slightly less inefficient code.
+ (mpz_tdiv_r): New function.
+
+2009-06-11 Niels Möller <nisse@lysator.liu.se>
+
+ Support for mpn_toom32_mul in speed:
+ * tune/speed.c (routine): Added mpn_toom32_mul.
+ * tune/speed.h (SPEED_ROUTINE_MPN_TOOM32_MUL): New macro.
+ * tune/common.c (speed_mpn_toom32_mul): New function.
+
+ * gmp-impl.h (mpn_toom32_mul_itch): Count scratch space needed
+ for the calls to mpn_toom22_mul.
+ (ABOVE_THRESHOLD): Moved this and related macros so it can be used
+ by mpn_toom32_mul_itch.
+ (mpn_toom22_mul_itch): Count scratch space for recursive calls.
+
+2009-06-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/mod_1_4.asm: New file, mainly for k7, but perhaps useful
+ also for k6 and non-sse p6.
+
+2009-06-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mod_1_4.asm: Minor size reducing tweaks.
+
+ * mpn/x86/mod_1.asm: Remove obsolete file.
+ * mpn/x86/k7/mmx/mod_1.asm: Likewise.
+ * mpn/x86/pentium4/sse2/mod_1.asm: Likewise.
+ * mpn/x86/p6/mod_1.asm: Likewise.
+ * mpn/x86/pentium/mod_1.asm: Likewise.
+
+2009-06-08 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/toom4_sqr.c (mpn_toom4_sqr): Reorganized, to reduce
+ the need for scratch space, and get rid of TMP_ALLOC. Also use
+ mpn_toom_eval_dgr3_pm1.
+
+ * mpn/generic/toom_interpolate_6pts.c (mpn_toom_interpolate_6pts):
+ Stricter ASSERTs based on maximum size of polynomial coefficients.
+ Improved comments on the signedness of intermediate values.
+
+2009-06-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom2_sqr.c: Make it actually work.
+
+ * mpn/generic/toom3_sqr.c: Reduce local scratch space.
+
+2009-06-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mul_fft.c (FFT_TABLE2_SIZE): Default to 200.
+ (MUL_FFT_TABLE2_SIZE, SQR_FFT_TABLE2_SIZE): Let these decide
+ FFT_TABLE2_SIZE if they are defined.
+ (struct nk): Use bit field.
+
+2009-06-05 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/toom44_mul.c (mpn_toom44_mult): Use
+ mpn_toom_eval_dgr3_pm1.
+
+ * mpn/generic/toom_eval_dgr3_pm1.c: New file.
+
+ * mpn/generic/toom_interpolate_7pts.c (mpn_toom_interpolate_7pts):
+ Minor cleanup, use mpn_add rather than mpn_add_n + MPN_INCR_U.
+
+ * mpn/generic/toom44_mul.c (mpn_toom44_mul): Reorganized, to
+ reduce the need for scratch space, and get rid of TMP_ALLOC.
+
+2009-06-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom_interpolate_7pts.c: Fall back mpn_divexact_byN to
+ mpn_bdiv_q_1_pi1, if the latter is NATIVE.
+
+2009-06-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/bdiv_q_1.asm: New file.
+
+ * configure.in (HAVE_NATIVE): Add recently added functions.
+ (GMP_MULFUNC_CHOICES): Handle addlsh_n, sublsh_n, rsblsh_n.
+
+ * tune/common.c (speed_mpn_bdiv_q_1, speed_mpn_bdiv_q_1_pi1):
+ New functions.
+ * tune/speed.c (routine): Add mpn_bdiv_q_1 and mpn_bdiv_q_1_pi1.
+ * tune/speed.h (SPEED_ROUTINE_MPN_BDIV_Q_1_PI1): New #define.
+ (SPEED_ROUTINE_MPN_BDIV_Q_1): Mew #define.
+
+ * configure.in (gmp_mpn_functions): Add bdiv_q_1.
+ * mpn/generic/bdiv_q_1.c: New file.
+ * mpn/asm-defs.m4 (define_mpn): Add mpn_bdiv_q_1 and mpn_bdiv_q_1_pi1.
+ * gmp-impl.h (mpn_bdiv_q_1, mpn_bdiv_q_1_pi1): Declare.
+
+ * mpn/x86_64/lshift.asm: Cleanup.
+ * mpn/x86_64/rshift.asm: Cleanup.
+
+ * mpn/x86_64/addlsh1_n.asm: Removed.
+ * mpn/x86_64/aorrlsh1_n.asm: Generalised addlsh1_n.asm to handle
+ addlsh1_n and rsblsh1_n functionality.
+
+ * tests/refmpn.c (refmpn_rsblsh1_n): New function.
+ * tests/devel/try.c: Test mpn_rsblsh1_n.
+ * tests/tests.h: Declare refmpn_rsblsh1_n.
+ * tune/common.c (speed_mpn_rsblsh1_n): New function.
+ * tune/speed.c (routine): Add mpn_rsblsh1_n.
+ * tune/speed.h (mpn_rsblsh1_n): Declare.
+
+ * configure.in (gmp_mpn_functions_optional): Add rsblsh1_n.
+ (GMP_MULFUNC_CHOICES): Handle rsblsh1_n defined with a mulfunc.
+ * mpn/asm-defs.m4 (define_mpn): Add rsblsh1_n.
+ * gmp-impl.h (mpn_rsblsh1_n): Declare.
+
+ * mpn/generic/toom32_mul.c: Consistently use TOOM22_MUL_N_REC.
+
+2009-06-03 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom43_mul.c: New file.
+ * mpn/generic/toom52_mul.c: New file.
+ * mpn/generic/toom_interpolate_6pts.c: New file.
+
+2009-06-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (gmp_mpn_functions): Add toom43_mul, toom52_mul, and
+ toom_interpolate_6pts, but also some previously forgotten functions.
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Likewise.
+ * gmp-impl.h: Declare new functions. Sort toom function declarations.
+
+ * gmp-impl.h: Rename toom4_* flags enum to toom7_*. Relevant C files
+ updated.
+
+ * mpn/generic/toom_interpolate_7pts (divexact_2exp): Remove.
+
+2009-06-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * demos/factorize.c: Add -q command line option.
+
+2009-06-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/toom_interpolate_7pts.c: Streamline, resulting in speed
+ improvements.
+
+ * mpn/generic/toom_interpolate_5pts.c: Likewise, but also completely
+ do away with explicit scratch space.
+ * gmp-impl.h (mpn_toom_interpolate_5pts): Update prototype.
+
+ * mpn/generic/mul_n.c (mpn_toom3_sqr_n, mpn_toom3_mul_n):
+ Update toom_interpolate_5pts call without scratch space parameter.
+ * mpn/generic/toom3_sqr.c: Likewise.
+ * mpn/generic/toom42_mul.c: Likewise.
+ * mpn/generic/toom33_mul.c: Likewise.
+
+ * mpn/generic/toom33_mul.c: Reduce local scratch space.
+ * mpn/generic/toom32_mul.c: Rewrite to not use local scratch space.
+
+2009-06-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom22_mul.c (TOOM22_MUL_MN_REC): New macro, use it for
+ oo point.
+
+2009-06-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mul.c: Loop to avoid excessive recursion in toom33 and
+ toom44 slicing code.
+
+ * mpz/remove.c: Correctly handle multiplicity that does not fit an int.
+
+ * Makefile.am (dist-hook): Check library version consistency.
+
+ * mpn/generic/mul.c: Rewrite.
+
+2009-05-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-divis.c (check_random): Create huge test operands.
+
+ * mpn/generic/toom44_mul.c: Allocate temp space using one TMP_ALLOC
+ call, not multiple TMP_SALLOC.
+ * mpn/generic/toom4_sqr.c: Likewise.
+
+ * gmp-impl.h (mpn_toom22_mul_itch): Replace totally wrong code.
+
+ * mpn/generic/mullow_n.c: Relax overlap requirement implied by ASSERT.
+
+ * mpn/generic/divis.c: Rewrite.
+
+ * gmp-impl.h (mpn_mu_bdiv_qr): Now returns mp_limb_t.
+ (mpn_toom2_sqr_itch): Simplify.
+
+ * mpn/generic/mu_bdiv_qr.c: Implement properly.
+
+2009-05-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mod_1_1.c: Add proper ASSERT functionality cps function.
+ * mpn/generic/mod_1_2.c: Likewise.
+ * mpn/generic/mod_1_3.c: Likewise.
+ * mpn/generic/mod_1_4.c: Likewise.
+
+ * tune: Add speed measuring of toom22, toom33, and toom44.
+
+ * mpn/generic/toom22_mul.c: Handle potentially unbalanced coefficient
+ product better.
+
+2009-05-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-mul.c (ref_mpn_mul): Use mpn_toom44_mul in FFT range for
+ better huge-operands performance.
+
+2009-05-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * acinclude.m4 (GMP_ASM_LSYM_PREFIX): Try "$L" too, before "$".
+
+2009-05-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (mpn_mod_1s_1p,mpn_mod_1s_2p,mpn_mod_1s_3p,mpn_mod_1s_4p):
+ Declare using __GMP_ATTRIBUTE_PURE.
+
+ * tune/tuneup.c (tune_mod_1): Specify check_size for measuring mod_1_N
+ functions.
+ (one): Remove redundant size loop exit condition.
+
+2009-05-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/pentium4/sse2/mod_1_4.asm: New file.
+ * mpn/x86/p6/sse2/mod_1_4.asm: New file (grabbing pentium4 code).
+
+2009-05-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (__GNU_MP_VERSION_MINOR): Bump to 4.
+ (__GNU_MP_VERSION_PATCHLEVEL): Set to -1.
+
+ * mpn/x86_64/mod_1_4.asm: New file.
+
+ * mpn/asm-defs.m4: Correct names for mod_1_N functions.
+ Add defines for corresponding cps functions.
+
+ * mpn/generic/mod_1_2.c: Support any sizes > 1.
+ * mpn/generic/mod_1_3.c: Likewise.
+ * mpn/generic/mod_1_4.c: Likewise.
+
+2009-05-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * Version 4.3.1 released.
+
+2009-05-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (__GNU_MP_VERSION_MINOR): Bump.
+
+ * Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*, LIBMP_LT_*):
+ Bump version info.
+
+2009-05-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz: Add MPZ_CHECK_FORMAT to many tests.
+
+2009-05-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/pentium4/sse2/mul_basecase.asm: Avoid L(ret), "ret" is
+ defined in x86-defs.m4.
+
+2009-05-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/p6/aors_n.asm: Use L() for labels.
+ * mpn/x86/pentium4/sse2/addmul_1.asm: Likewise.
+ * mpn/x86/pentium4/sse2/mul_1.asm: Likewise.
+ * mpn/x86/pentium4/sse2/mul_basecase.asm: Likewise.
+ * mpn/x86/pentium4/sse2/sqr_basecase.asm: Likewise.
+ * mpn/x86_64/lshift.asm: Likewise.
+ * mpn/x86_64/rshift.asm: Likewise.
+
+ * tests/cxx/t-locale.cc (point_string): Declare as extern "C" to
+ placate compilers that mangle variable names.
+
+2009-05-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-gcd.c: Generate operands that are multiple of each other.
+
+2009-05-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (__GMP_EXTERN_INLINE): Support for more systems.
+ (gmp_randinit_set): Add missing __GMP_DECLSPEC.
+
+2009-04-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/neg_n.c: New file.
+ * configure.in (gmp_mpn_functions): Add neg_n.
+ * mpn/asm-defs.m4 (define_mpn): Add neg_n.
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Add neg_n.c.
+ * gmp-h.in: Handle mpn_neg_n properly.
+
+ * mpn/generic/toom_interpolate_7pts.c (divexact_2exp): Nailify.
+
+ * mpn/generic/gcdext.c: Change some MPN_NORMALIZE to
+ MPN_NORMALIZE_NOT_ZERO.
+ * mpn/generic/gcdext_lehmer.c: Likewise.
+ Add a MPN_NORMALIZE_NOT_ZERO.
+
+ * mpn/generic/binvert.c: Remove own mpn_neg_n.
+
+ * tests/mpz/t-gcd.c: Add some MPZ_CHECK_FORMAT calls.
+
+2009-04-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/Makefile.am (TARG_DIST): Add minithres.
+
+ * mpn/generic/bdiv_dbm1c.c: Handle nails.
+
+2009-04-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Recognise more POWER processor types.
+
+2009-04-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/pentium4/sse2/popcount.asm: Work around Apple reloc bug.
+ * mpn/x86/darwin.m4: Define symbol "DARWIN".
+
+2009-04-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm.c (mpn_redc_n): Use ASSERT_ALWAYS, not abort().
+ * mpn/generic/powm_sec.c: Likewise.
+
+ * mpn/powerpc64/aix.m4 (EXTERN_FUNC): New define. Add dummy variants
+ for other m4 files.
+ * mpn/powerpc64/mode64/divrem_1.asm: Use EXTERN_FUNC.
+ * mpn/powerpc64/mode64/divrem_1.asm: Likewise.
+
+2009-04-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/x86_64-defs.m4 (JUMPTABSECT): New define.
+ * mpn/x86_64/darwin.m4: Likewise.
+ * mpn/x86_64/sqr_basecase.asm: Rework switch code using JUMPTABSECT.
+
+ * tune/common.c (speed_mpn_hgcd, speed_mpn_hgcd_lehmer):
+ Remove an unused variable.
+
+ * mpn/x86/x86-defs.m4 (LEA): Get SIZE arguments right.
+
+2009-04-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * Version 4.3.0 released.
+
+ * scanf/doscan.c (__gmp_doscan): Pad 3-operand scanf call with dummy
+ argument.
+ * scanf/sscanffuns.c (scan): Disable vsscanf variant for now.
+
+2009-04-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * scanf/sscanffuns.c (scan): Rewrite to use stdarg.
+
+ * tests/mpz/t-root.c: Rewrite. Add unconditional gcc 4.3.2 tests.
+
+2009-04-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/powm.c: New file.
+ * mpn/generic/powlo.c: New file.
+ * mpn/generic/powm_sec.c: New file.
+ * configure.in (gmp_mpn_functions): List new functions.
+
+2009-04-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/urandomm.c: Amend last fix.
+
+2009-04-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Support Sun cc for x86_64.
+
+ * mpz/urandomm.c: Handle operand overlap.
+
+2009-03-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (powerpc): Brave removing -Wa,-mppc64, in the hope that
+ GCC now passes the proper options.
+
+2009-03-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/divrem_1.asm: Add a nop to save a cycle in unnormalised
+ case.
+
+2009-03-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * ia64/gmp-mparam.h, arm/gmp-mparam.h, x86/p6/mmx/gmp-mparam.h,
+ pa32/hppa2_0/gmp-mparam.h sparc32/v9/gmp-mparam.h: Update.
+
+2009-03-03 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/ia64/bdiv_dbm1c.asm: Accept/return carry.
+
+2009-03-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (64-bit sparc/solaris): Pass -xO3, not -O3 to solaris
+ system compiler.
+
+2009-03-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * longlong.h (mips, powerpc): Provide assembly-free umul_ppmm for newer
+ gcc.
+
+2009-02-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/redc_2.c: Remove code for testing and timing. Update
+ to current FSF header.
+ * mpn/generic/redc_1.c: Update to current FSF header.
+
+2009-01-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/powm.c (redc): Remove.
+ (mpz_powm): Use mpn_redc_1 instead of redc.
+
+ * tests/mpz/t-powm.c: Rewrite reference code.
+
+2009-01-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz: Increase reps for many tests.
+
+ * mpn/generic/rootrem.c (mpn_rootrem_internal): Use MPN_DECR_U instead of
+ mpn_sub_1 (works around gcc 4.3 bugs and is also faster).
+
+2009-01-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/tests.h: Declare refmpn_divrem_2.
+
+2009-01-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/perfpow.c: Add TMP_FREE before every return statement.
+
+ * mpn/generic/rootrem.c (mpn_rootrem_internal): Add a missing TMP_FREE.
+
+ * configure.in (gcc_cflags, gcc_64_cflags): Revert from -O3 to -O2,
+ the change was accidental and cause too much miscompilation.
+
+2009-01-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mod_1): Run MOD_1_x_THRESHOLD tests also when
+ longlong.h specified UDIV_PREINV_ALWAYS.
+
+ * mpn/generic/mod_1.c (mpn_mod_1): Properly check for normalisation
+ divisor.
+
+2009-01-13 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_mod_1): Tune for MOD_1_1_THRESHOLD,
+ MOD_1_2_THRESHOLD, and MOD_1_4_THRESHOLD.
+
+ * mpn/generic/mod_1.c: Rewrite.
+ * mpn/generic/mod_1_1.c: New file.
+ * mpn/generic/mod_1_2.c: New file.
+ * mpn/generic/mod_1_3.c: New file.
+ * mpn/generic/mod_1_4.c: New file.
+ * configure.in (gmp_mpn_functions): Add mod_1_*.
+ * mpn/asm-defs.m4 (define_mpn): Add mod_1_*.
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Add mod_1_*.c.
+ * gmp-impl.h: Declare new mpn_mod_1s_* functions and associated
+ THRESHOLD macros.
+ (udiv_rnd_preinv): New macro.
+
+2009-01-12 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/tuneup.c (tune_gcd_dc,tune_gcdext_dc): Lower step_factor to 0.1.
+
+2009-01-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-nextprime.c: New test file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add t-nextprime.
+
+ From Niels Möller:
+ * mpz/nextprime.c: Handle large prime gaps by limiting incr.
+
+2009-01-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/and.c, mpz/ior.c, mpz/xor.c: Re-read only necessary source
+ pointers after reallocation. Misc cleanup.
+
+ * gmp-impl.h (MPN_TOOM44_MAX_N): New define, replaces MPN_TOOM3_MAX_N.
+
+ * mpn/x86/fat/diveby3.c: New file.
+
+2008-12-30 Niels Möller <nisse@lysator.liu.se>
+
+ * doc/gmp.texi (Greatest Common Divisor Algorithms): Updated
+ section on GCD algorithms.
+
+2008-12-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Multiplication Algorithms): Add descriptions of Toom-4
+ and unbalanced multiplication.
+ (Radix to Binary): Add warning that text is outdated,
+ (Contributors): Fix typos.
+
+ * mpn/generic/toom*.c: Use coherent MAYBE_ macros for trimming
+ unreachable recursive functions.
+ * gmp-impl.h: Update toom itch functions.
+
+ * mpn/x86_64/sqr_basecase.asm: Slightly increase stack allocation, to
+ placate tuneup.
+
+2008-12-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/pentium4/aors_n.asm: Tune prologue code.
+
+ * mpn/x86_64/pentium4/aorslsh1_n.asm: New file.
+
+ * mpn/x86_64/darwin.m4: Define symbol "DARWIN".
+ * mpn/x86_64/invert_limb.asm: Work around darwin quirks.
+
+ * mpn/x86_64/sqr_basecase.asm: Further optimize, support Darwin.
+
+ * mpn/x86_64/invert_limb.asm: New file.
+
+2008-12-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/core2/aorslsh1_n.asm: New file.
+
+2008-12-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/perfpow.c: Handle negative arguments properly.
+ * tests/mpz/t-perfpow.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add t-perfpow.
+
+2008-12-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-mul.c (dump_abort): Improve error message.
+
+ * gcd.c gcd_subdiv_step.c gcdext.c gcdext_subdiv_step.c:
+ Remove private mpn_zero_p.
+
+ * tune/tuneup.c (tune_mul): Tune for MUL_TOOM44_THRESHOLD.
+ (tune_sqr): Tune for SQR_TOOM4_THRESHOLD.
+
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Add toom44_mul.c and
+ toom4_sqr.c.
+
+ * configure.in (gmp_mpn_functions): Toom function updates.
+
+ * Rename mpn/mul_toomMN.c to mpn/toomMN_mul.c. Function names changed
+ accordingly.
+
+ * mpn/toomMN_mul.c: Add scratch parameter. Do recursive multiplies
+ properly. Misc tuning. Remove CHECK and TIMING code.
+
+ * mpn/toom2_sqr.c, mpn/toom3_sqr.c, mpn/toom4_sqr.c: New files.
+
+ * gmp-impl.h (mpn_toomMN_mul_itch): Several new functions.
+ (mpn_zero_p): New functions.
+ Add various TOOM4/TOOM44 related parameters.
+ Update mpn_toomMN_mul prototypes.
+
+ * mpn/generic/mul_n.c (mpn_mul_n): Call mpn_toom44_mul. Use TMP_BALLOC
+ instead of malloc.
+ (mpn_sqr_n): Analogous changes.
+
+ * mpn/generic/mul.c: Update unbalanced toom code to pass scratch space.
+
+2008-12-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/nextprime.c: Add TMP_SDECL/MARK/FREE.
+
+2008-12-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/sqrtrem.c (mpn_sqrtrem1): Rewrite, improve interface.
+ (invsqrttab): New table, remove table approx_tab.
+ (mpn_sqrtrem2): Optimize, update mpn_sqrtrem1 call.
+ (mpn_sqrtrem): Update mpn_sqrtrem1 call.
+
+2008-12-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/nextprime.c: Run 10 mpz_millerrabin tests (was 5).
+ Give credit to authors.
+
+ * mpn/x86_64/redc_1.asm: Align stack as mandated by ABI.
+
+ * mpn/x86_64/divrem_2.asm: Add some comments.
+
+ * mpn/x86_64/darwin.m4: New file.
+ * configure.in: Use x86_64/darwin.m4.
+
+2008-12-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/projects.html: Remove GCD and division projects, update text on
+ multiplication.
+
+ * doc/tasks.html: Add a caution about that the file is somewhat
+ outdated.
+
+2008-12-14 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/alpha/ev6/aorsmul_1.asm: New file (same code for mpn_addmul_1,
+ much improved for mpn_submul_1).
+ * mpn/alpha/ev6/addmul_1: File removed.
+ * mpn/alpha/ev6/submul_1: File removed.
+
+2008-12-09 Torbjorn Granlund <tege@gmplib.org>
+
+ From David Harvey:
+ * mpn/x86_64/mul_basecase.asm: Further tweaks for code size and speed.
+
+ * mpn/powerpc64/mode64/divrem_1.asm: Rewrite.
+
+ * mpn/powerpc64/mode64/mul_basecase.asm: New file.
+
+2008-12-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/powerpc64/mode64/gmp-mparam.h: New file.
+
+ * gmp-impl.h: Additional cleanups.
+ (mpn_set_str_compute_powtab): New prototype.
+ (mpn_powm, mpn_powlo): New prototypes.
+
+ * mpz/pow_ui.c: Handle some small exponents locally.
+
+2008-12-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/set_str.c: Remove prototypes (they are in gmp-impl.h).
+
+ * tune/set_strs.c, tune/set_strb.c: Make prototypes effective by moving
+ the #define mpn_set_str* before including gmp-impl.h.
+
+ * All files: Change _PROTO => __GMP_PROTO.
+
+ * tune/speed.c (routine): Remove non-working choice mpn_set_str_subquad.
+ * tune/common.c (speed_mpn_dc_set_str): Remove, it is broken.
+
+ * mpn/generic/toom_interpolate_7pts.c (divexact_2exp): Make this static,
+ and inline it.
+
+ * gmp-impl.h: Major cleanup.
+ (Remove formal parameter names. Use __GMP_PROTO consistently. Move
+ __GMP_PROTO and __MPN use to adjacent lines for declared function.
+ Fix typos. Remove code inside #if 0.)
+
+ * configure.in (gmp_mpn_functions): Add mul_toom33. Reformat.
+
+2008-12-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/redc_1.c: New file.
+ * mpn/generic/redc_2.c: New file.
+
+ * configure.in (gmp_mpn_functions): List redc_1 and redc_2.
+ (HAVE_NATIVE): Likewise.
+
+ * tune/common.c (speed_mpn_redc_1): Renamed from speed_redc.
+ * tune/speed.c (routine): Remove "redc", and "mpn_redc_1".
+ * tune/speed.h (SPEED_ROUTINE_REDC_1): Renamed from SPEED_ROUTINE_REDC.
+ Updated call.
+ * tune/tuneup.c (tune_powm): Update redc call.
+
+2008-12-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/sqr_basecase.asm: Inline a combined diagonal product code
+ and addlsh1 loop. Misc cleanup.
+
+2008-12-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/sqr_basecase.asm: New file.
+
+2008-11-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/sqr_basecase.c: Fix typo in mpn_addmul_2s variant.
+
+2008-11-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/redc_1.asm: Rewrite.
+
+2008-11-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/refmpn.c (refmpn_redc_1): New function.
+
+2008-11-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/aorsmul_1.asm: Actually handle mpn_submul_1.
+
+2008-11-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/divrem_1.asm: Rewrite.
+
+ * alpha/divrem_2.asm: New file.
+ * powerpc32/divrem_2.asm: New file.
+ * powerpc64/mode64/divrem_2.asm: New file.
+ * x86/divrem_2.asm: New file.
+ * x86_64/divrem_2.asm: New file.
+ * tests/refmpn.c (refmpn_divrem_2): New function.
+
+2008-11-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k7/mul_1.asm: Rewrite for smaller size and better speed.
+ * mpn/x86/k7/aorsmul_1.asm: Likewise.
+
+ * acinclude.m4 (GMP_VERSION): Include last component even when zero.
+
+2008-11-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/README: Rewrite.
+
+ * tests/devel/try.c (malloc_region, mprotect_maybe): Add casts for
+ printf type correctness.
+
+ * gmp-h.in (__GNU_MP_VERSION_MINOR): Bump.
+
+ * Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*, LIBMP_LT_*):
+ Bump version info.
+
+2008-11-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h: Rename modlimb_invert to binvert_limb.
+ * tune/speed.h: Likewise.
+ * tune/modlinv.c: Likewise.
+ * tune/common.c: Likewise.
+ * tests/t-modlinv.c: Likewise.
+ * tests/t-constants.c: Likewise.
+ * mpn/sparc64/mode1o.c: Likewise.
+ * mpn/alpha/dive_1.c: Likewise.
+ * mpn/sparc64/dive_1.c: Likewise.
+ * mpn/generic/mode1o.c: Likewise.
+ * mpn/generic/dive_1.c: Likewise.
+ * mpn/generic/bdivmod.c: Likewise.
+ * mpn/alpha/mode1o.asm: Likewise.
+ * mpn/asm-defs.m4: Likewise.
+ * mpn/ia64/mode1o.asm: Likewise.
+ * mpn/powerpc32/README: Likewise.
+ * mpn/powerpc32/mode1o.asm: Likewise.
+ * mpn/powerpc64/mode64/dive_1.asm: Likewise.
+ * mpn/powerpc64/mode64/mode1o.asm: Likewise.
+ * mpn/x86/dive_1.asm: Likewise.
+ * mpn/x86/k6/mmx/dive_1.asm: Likewise.
+ * mpn/x86/k6/mode1o.asm: Likewise.
+ * mpn/x86/k7/dive_1.asm: Likewise.
+ * mpn/x86/k7/mode1o.asm: Likewise.
+ * mpn/x86/p6/dive_1.asm: Likewise.
+ * mpn/x86/p6/mode1o.asm: Likewise.
+ * mpn/x86/pentium/dive_1.asm: Likewise.
+ * mpn/x86/pentium/mode1o.asm: Likewise.
+ * mpn/x86/pentium4/sse2/dive_1.asm: Likewise.
+ * mpn/x86/pentium4/sse2/mode1o.asm: Likewise.
+ * mpn/x86_64/dive_1.asm: Likewise.
+ * mpn/x86_64/mode1o.asm: Likewise.
+
+ * mpn/x86_64/aors_n.asm: Replace with slightly faster, more alignment
+ neutral loop.
+
+2008-11-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Remove gcd_finda related declarations.
+ * gmp-impl.h (mpn_gcd_finda): Remove declaration.
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Remove gcd_finda.
+ * mpn/asm-defs.m4: Remove define_mpn(gcd_finda).
+ * mpn/x86/k6/gcd_finda.asm: Remove file.
+ * tests/devel/try.c (param_init): Remove mpn_gcd_finda.
+ (choice_array): Remove mpn_gcd_finda.
+ * tests/mpn/t-instrument.c (check): Remove testing of mpn_gcd_finda.
+ * tests/refmpn.c (refmpn_gcd_finda): Remove.
+ * tests/tests.h (refmpn_gcd_finda): Remove declaration.
+ * tune/common.c (speed_mpn_gcd_finda): Remove.
+ * tune/gcd_finda_gen.c: Remove file.
+ * tune/speed.h (speed_mpn_gcd_finda): Remove declaration.
+ * tune/speed.c (routine): Remove mpn_gcd_finda entry.
+
+ * tests/mpz/t-powm.c: Print test number when failing a test.
+
+ * mpn/x86_64/redc_1.asm (CALL): Move from here...
+ * mpn/x86_64/x86_64-defs.m4: ...to here.
+
+ * gmp-impl.h (mpn_jacobi_base): Remove parameter names.
+
+2008-11-11 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpf/t-conv.c: Add some specific tests, supplementing the random
+ tests.
+
+2008-11-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpf/set_str.c: Default 'base' before letting exp_base inherit it.
+
+ * tests/cxx/t-prec.cc: Use the right precision for all float constants.
+
+2008-11-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi (Float Comparison): Update mpf_eq documentation.
+
+ * mpf/eq.c: Compare the right number of bits.
+
+2008-11-02 Torbjorn Granlund <tege@gmplib.org>
+
+ Undo, it made testing too slow:
+ * tests/mpz/t-mul.c: Use slower geometric progression for operand
+ sizes.
+
+ * mpn/x86/k7/mod_34lsub1.asm: Use movzb for masking low 8 bits.
+
+2008-10-31 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd2.c (div1): New function (taken from old gcdext
+ implementation)
+ (mpn_hgcd2): Use single precision for the second half of the work.
+
+2008-10-30 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/p6/sse2/gmp-mparam.h: New file.
+
+2008-10-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (x86 fat_path): Add "x86/p6/sse2".
+
+ * mpn/x86/fat/fat.c (__gmpn_cpuvec_init): Recognize sse2 capable p6
+ (pentiumm, core2).
+
+ * mpn/x86/p6/sse2/mul_1.asm: New file.
+ * mpn/x86/p6/sse2/addmul_1.asm: New file.
+ * mpn/x86/p6/sse2/submul_1.asm: New file.
+ * mpn/x86/p6/sse2/mul_basecase.asm: New file.
+ * mpn/x86/p6/sse2/sqr_basecase.asm: New file.
+ * mpn/x86/p6/sse2/popcount.asm: New file.
+
+ * mpn/x86/fat/fat.c (__gmpn_cpuvec_init): Handle "extended" fields for
+ model and family.
+
+2008-10-28 Torbjorn Granlund <tege@gmplib.org>
+
+ From Mickael Gastineau:
+ * gmp-h.in (gmp_urandomm_ui, gmp_urandomb_ui): Add __GMP_DECLSPEC.
+
+2008-10-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (mpn_gcdext_1): Remove bogus __GMP_ATTRIBUTE_PURE.
+
+2008-10-27 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/common.c (speed_mpn_hgcd): Call mpn_hgcd_matrix_init once
+ for each call to mpn_hgcd.
+ (speed_mpn_hgcd_lehmer): Likewise.
+
+2008-10-26 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Point to p6/sse2 for pentiumm and core2.
+
+ * gmp-impl.h (mpn_add_nc, mpn_sub_nc): Move these macros to after fat
+ definitions.
+
+ * tune/common.c, tune/speed.c, tune/speed.h:
+ Add speed measurement of mpn_bdiv_dbm1c.
+
+2008-10-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/gmp-mparam.h (MUL_FFT_TABLE2, SQR_FFT_TABLE2): Extend.
+
+ * mpz/nextprime.c: Move declarations to function beginning.
+
+2008-10-23 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h (DECL_gcdext_1): Deleted.
+
+2008-10-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/atom/aors_n.asm: New file.
+ * mpn/x86_64/atom/gmp-mparam.h: New file.
+
+2008-10-21 Torbjorn Granlund <tege@gmplib.org>
+
+ With Neils Möller:
+ * mpz/nextprime.c: Rewrite.
+
+ * tests/devel/try.c (main): Use strtol for 's' and 'S' optargs.
+
+ * mpn/x86_64/pentium4/rshift.asm: Misc cleanups.
+ * mpn/x86_64/pentium4/lshift.asm: Likewise.
+
+ * mpn/x86_64/pentium4/aors_n.asm: Use fewer registers.
+
+ * configure.in: Set up specific path for x86_64/atom.
+
+2008-10-21 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Removed
+ qstack.c.
+ * mpn/generic/qstack.c: Deleted obsolete file.
+
+2008-10-20 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/core2/aorsmul_1.asm: New file.
+
+2008-10-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/aors_n.asm: Remove redundant MULFUNC_PROLOGUE.
+
+ * gmp-impl.h (popc_limb): Remove redundant checks of GMP_LIMB_BITS
+ inside several of these macros.
+
+2008-10-17 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-mul.c: Use slower geometric progression for operand
+ sizes. Do every other tests for same size operands.
+
+2008-10-15 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/mul_basecase.asm: Simplify addressing in epilogue.
+
+ * mpn/mips64/divrem_1.asm: Remove file, it is n32-only, and uses an old
+ algorithm.
+
+ * config.guess, config.sub, configure.in: Support Intel Atom processor.
+
+2008-10-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpq/mul.c: Fix typo in last change.
+
+2008-10-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/refmpn.c (refmpn_sb_divrem_mn): Work around a gcc bug.
+
+2008-10-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpq/mul.c: Use TMP_ALLOC. Cleanup.
+ * mpq/div.c: Likewise.
+
+ * mpn/x86_64/mul_basecase.asm: Use lea directly for loading entry point
+ addresses.
+
+2008-10-09 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/x86/k7/gmp-mparam.h: Updated GCD-related values.
+
+2008-10-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mul_fft.c (mpn_mul_fft_internal): Do store
+ mpn_fft_norm_modF return value, if (rec).
+
+2008-10-04 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/aorsmul_1.asm: Replace with faster code.
+ * mpn/x86_64/mul_1.asm: Likewise.
+ * mpn/x86_64/addmul_2.asm: Likewise.
+ * mpn/x86_64/mul_2.asm: Likewise.
+ * mpn/x86_64/mul_basecase.asm: Likewise.
+
+2008-10-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/minithres/gmp-mparam.h: Update FFT values.
+
+2008-10-02 Niels Möller <nisse@lysator.liu.se>
+
+ * hgcd.c (mpn_hgcd_matrix_mul): Fixed normalization bug.
+
+2008-09-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Handle --enable-minithres.
+ * mpn/minithres/gmp-mparam.h: Update all values.
+
+2008-09-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * tune/speed.c (routine): New entry for mpn_mul.
+ * tune/speed.h (SPEED_ROUTINE_MPN_MUL): Renamed from
+ SPEED_ROUTINE_MPN_MUL_BASECASE.
+ (speed_mpn_mul): Renamed from speed_mpn_mul_basecase.
+ (SPEED_ROUTINE_MPN_MUL): Allocate our own memory of xp operand.
+
+ * tune/common.c: Corresponding changes.
+
+2008-09-22 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext.c (hgcd_mul_matrix_vector): New function,
+ replaces addmul2_n. Needs less copying.
+ (mpn_gcdext): Use hgcd_mul_matrix_vector. Updated for interface
+ change in mpn_gcdext_subdiv_step
+
+ * mpn/generic/hgcd.c (hgcd_matrix_mul_1): Rewritten to use
+ mpn_hgcd_mul_matrix1_vector.
+ (hgcd_step): Updated for interface change in
+ mpn_hgcd_mul_matrix1_inverse_vector.
+
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_lehmer_n): Updated for
+ interface changes in mpn_hgcd_mul_matrix1_vector,
+ mpn_hgcd_mul_matrix1_inverse_vector and mpn_gcdext_subdiv_step.
+
+ * mpn/generic/gcd_lehmer.c (mpn_gcd_lehmer_n): Updated for
+ interface change in mpn_hgcd_mul_matrix1_inverse_vector.
+
+ * mpn/generic/gcdext_subdiv_step.c (mpn_gcdext_subdiv_step): Use
+ separate scratch arguments for the quotient and for the cofactor
+ update.
+
+ * mpn/generic/hgcd2.c (mpn_hgcd_mul_matrix1_vector): Interface
+ change. Store first element in rp and leave ap unmodified. No
+ additional scratch space or copying needed. Callers that require
+ modification in place still need to copy one of the inputs.
+ (mpn_hgcd_mul_matrix1_inverse_vector): Likewise.
+
+2008-09-22 Niels Möller <nisse@lysator.liu.se> <nisse@king.swox.se>
+
+ * mpn/generic/hgcd.c (hgcd_matrix_mul_1): Use mpn_addaddmul_1msb0.
+ * mpn/generic/hgcd2.c (mpn_hgcd_mul_matrix1_vector): Likewise.
+
+ * mpn/generic/gcd.c: Use libspeed for timing measurements.
+
+ * gmp-impl.h: Declare mpn_addaddmul_1msb0.
+ * mpn/asm-defs.m4: Added addaddmul_1msb0.
+ * mpn/x86_64/addaddmul_1msb0.asm: New file.
+ * configure.in (gmp_mpn_functions_optional): Added
+ addaddmul_1msb0.
+ (HAVE_NATIVE): List addaddmul_1msb0.
+
+2008-09-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/get_str.c (GET_STR_DC_THRESHOLD): Remove default.
+ (GET_STR_PRECOMPUTE_THRESHOLD): Likewise.
+ Misc code cleanups.
+
+ * gmp-impl.h (mpn_dc_set_str_itch): Allocate GMP_LIMB_BITS more limbs.
+
+ Revert:
+ * mpn/generic/set_str.c:
+ (mpn_dc_set_str): Remove impossible case, replace by an ASSERT.
+
+2008-09-18 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/alpha/ev6/gmp-mparam.h (DIVEXACT_BY3_METHOD): Define.
+
+ * mpn/ia64/diveby3.asm: Remove.
+ * mpn/x86/diveby3.asm: Remove.
+ * mpn/x86/k6/diveby3.asm: Remove.
+ * mpn/x86/k7/diveby3.asm: Remove.
+ * mpn/x86/p6/diveby3.asm: Remove.
+ * mpn/x86/pentium/diveby3.asm: Remove.
+ * mpn/x86_64/diveby3.asm: Remove.
+ * mpn/x86/pentium4/sse2/diveby3.asm: Remove.
+
+ * configure.in (HAVE_NATIVE): List divexact_by3c.
+
+ * gmp-impl.h (mpn_divexact_by3c): Override gmp-h.in's definition.
+ (DIVEXACT_BY3_METHOD): Don't default to 0 if
+ HAVE_NATIVE_mpn_divexact_by3c.
+
+2008-09-18 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcd.c (main): Added code for tuning of CHOOSE_P.
+
+ * mpn/generic/hgcd.c (mpn_hgcd_matrix_mul): Assert that inputs are
+ normalized.
+
+2008-09-17 Niels Möller <nisse@lysator.liu.se> <nisse@king.swox.se>
+
+ * mpn/generic/gcdext.c (mpn_gcdext): p = n/5 caused a
+ slowdown for large inputs. As a compromise, use p = n/2 for the
+ first iteration, and p = n/3 for the rest. Handle the first
+ iteration specially, since the initial u0 and u1 are trivial.
+
+ * mpn/x86_64/gmp-mparam.h (GCDEXT_DC_THRESHOLD): Reduced threshold
+ from 409 to 390.
+
+ * mpn/generic/gcdext.c (CHOOSE_P): New macro. Use p = n/5.
+ (mpn_gcdext): Use CHOOSE_P, and generalized the calculation of
+ scratch space.
+
+ * tune/tuneup.c (tune_hgcd): Use default step factor.
+
+ * mpn/x86_64/gmp-mparam.h: (GCD_DC_THRESHOLD): Reduced from 493 to
+ 412.
+
+ * mpn/generic/gcd.c (CHOOSE_P): New macro, to determine the
+ split when calling hgcd. Use p = 2n/3, as that seems better than
+ the more obvious split p = n/2.
+ (mpn_gcd): Use CHOOSE_P, and generalized the calculation of
+ scratch space.
+
+2008-09-16 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom_interpolate_7pts.c: Use new mpn_divexact_byN
+ functions.
+
+ * gmp-impl.h (mpn_divexact_by3, mpn_divexact_by5, mpn_divexact_by7,
+ mpn_divexact_by9, mpn_divexact_by11, mpn_divexact_by13,
+ mpn_divexact_by15): New macros, defined in terms of mpn_bdiv_dbm1.
+
+ * configure.in (gmp_mpn_functions): List bdiv_dbm1c.
+ (HAVE_NATIVE): Likewise.
+ * mpn/asm-defs.m4: Define bdiv_dbm1c.
+ * gmp-impl.h (mpn_bdiv_dbm1c): Declare.
+ (mpn_bdiv_dbm1): New macro.
+ * mpn/generic/bdiv_dbm1c.c: New file.
+ * mpn/alpha/bdiv_dbm1c.asm: New file.
+ * mpn/ia64/bdiv_dbm1c.asm: New file.
+ * mpn/powerpc32/bdiv_dbm1c.asm: New file.
+ * mpn/powerpc64/mode64/bdiv_dbm1c.asm: New file.
+ * mpn/x86/bdiv_dbm1c.asm: New file.
+ * mpn/x86_64/bdiv_dbm1c.asm: New file.
+
+ * mpn/generic/diveby3.c: Add mpn_bdiv_dbm1c based function.
+ Choose function depending on DIVEXACT_BY3_METHOD.
+ * gmp-impl.h (DIVEXACT_BY3_METHOD): Provide default.
+
+2008-09-16 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (mpn_hgcd_addmul2_n): Moved function to
+ gcdext.c, where it is used.
+ * mpn/generic/gcdext.c (addmul2_n): Moved and renamed, was
+ mpn_hgcd_addmul2_n. Made static. Deleted input normalization.
+ Deleted rn argument.
+ (mpn_gcdext): Updated calls to addmul2_n, and added assertions.
+
+ * gmp-impl.h (MPN_HGCD_MATRIX_INIT_ITCH): Increased storage by 4 limbs.
+ (MPN_HGCD_LEHMER_ITCH): Reduced storage by one limb.
+ (MPN_GCD_SUBDIV_STEP_ITCH): Likewise.
+ (MPN_GCD_LEHMER_N_ITCH): Likewise.
+
+ * mpn/generic/hgcd.c (mpn_hgcd_matrix_init): Use two extra limbs.
+ (hgcd_step): Use overlapping arguments to mpn_tdiv_qr.
+ (mpn_hgcd_matrix_mul): Deleted normalization code. Tighter bounds
+ for the element size of the product. Needs two extra limbs of
+ storage for the elements.
+ (mpn_hgcd_itch): Updated storage calculation.
+
+ * mpn/generic/gcd_subdiv_step.c (mpn_gcd_subdiv_step): Use
+ overlapping arguments to mpn_tdiv_qr. Use mpn_zero_p.
+
+ * mpn/generic/gcd.c (mpn_gcd): Use mpn_zero_p.
+
+2008-09-15 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (mpn_hgcd_matrix_init): Updated for deleted
+ tp pointer.
+ (hgcd_matrix_update_q): Likewise.
+ (mpn_hgcd_matrix_mul): Likewise.
+ (mpn_hgcd_itch): Updated calculation of scratch space.
+
+ * gmp-impl.h (struct hgcd_matrix): Deleted tp pointer.
+ (MPN_HGCD_MATRIX_INIT_ITCH): Reduced storage.
+ (mpn_hgcd_step, MPN_HGCD_STEP_ITCH): Deleted declarations.
+
+2008-09-15 Niels Möller <nisse@lysator.liu.se> <nisse@king.swox.se>
+
+ * mpn/x86_64/gmp-mparam.h (MATRIX22_STRASSEN_THRESHOLD): New
+ threshold.
+
+ * mpn/generic/hgcd.c (mpn_hgcd_matrix_mul): Use mpn_matrix22_mul.
+ (mpn_hgcd_itch): Updated calculation of scratch space. Use
+ count_leading_zeros to get the recursion depth.
+
+ * mpn/generic/gcd.c (mpn_gcd): Fixed calculation of scratch space,
+ and use mpn_hgcd_itch.
+
+2008-09-15 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tuneup.c (tune_matrix22_mul): New function.
+ (all): Use it.
+
+ * tune/common.c (speed_mpn_matrix22_mul): New function.
+
+ * tune/Makefile.am (TUNE_MPN_SRCS_BASIC): Added matrix22_mul.c.
+
+ * tests/mpn/t-matrix22.c: Use MATRIX22_STRASSEN_THRESHOLD to
+ select sizes for tests.
+
+ * gmp-impl.h (MATRIX22_STRASSEN_THRESHOLD): New threshold
+
+ * configure.in (gmp_mpn_functions): Added matrix22_mul.
+ * gmp-impl.h: Added declarations for mpn_matrix22_mul and related
+ functions.
+
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Added
+ matrix22_mul.c.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Added t-matrix22.
+
+ * tests/mpn/t-matrix22.c: New file.
+ * mpn/generic/matrix22_mul.c: New file.
+
+2008-09-11 Niels Möller <nisse@king.swox.se>
+
+ * tune/tuneup.c: Updated tuning of gcdext.
+
+ * mpn/x86_64/gmp-mparam.h (GCDEXT_DC_THRESHOLD): Reduced threshold
+ from 713 to 409.
+
+2008-09-11 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h: Updated for gcdext changes.
+ (GCDEXT_DC_THRESHOLD): New constant, renamed from
+ GCDEXT_SCHOENHAGE_THRESHOLD.
+
+ * mpn/generic/gcdext.c (compute_v): Accept non-normalized a and b
+ as inputs.
+ (mpn_gcdext): Rewrote and simplified. Now uses the new mpn_hgcd
+ interface.
+
+ * mpn/generic/hgcd.c (mpn_hgcd_addmul2_n): Renamed from addmul2_n
+ and made non-static. Changed interface to take non-normalized
+ inputs, and only two size arguments.
+ (mpn_hgcd_matrix_mul): Simplified using new mpn_hgcd_addmul2_n.
+
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_lehmer_itch): Deleted
+ function.
+ (mpn_gcdext_lehmer_n): Renamed from mpn_gcd_lehmer. Now takes
+ inputs of equal size. Moved the code for the division step to a
+ separate function...
+ * mpn/generic/gcdext_subdiv_step.c (mpn_gcdext_subdiv_step): New
+ file, new function.
+
+ * configure.in (gmp_mpn_functions): Added gcdext_subdiv_step.
+
+2008-09-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/devel/anymul_1.c: Include <string.h>.
+
+ * gmp-h.in: Unconditionally include <cstdio>.
+
+2008-09-10 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/common.c: #if:ed out speed_mpn_gcd_binary and
+ speed_mpn_gcd_accel.
+ * tune/speed.c (routine): #if:ed out mpn_gcd_binary, mpn_gcd_accel
+ and find_a.
+ * tune/Makefile.am (libspeed_la_SOURCES): Removed gcd_bin.c
+ gcd_accel.c gcd_finda_gen.c.
+ * tune/tuneup.c: Enable tuning of GCD_DC_THRESHOLD.
+
+ * mpn/generic/gcd.c (mpn_gcd): Rewrote and simplified. Now uses
+ the new mpn_hgcd interface.
+
+ * */gmp-mparam.h: Renamed GCD_SCHOENHAGE_THRESHOLD to
+ GCD_DC_THRESHOLD.
+
+ * mpn/generic/gcd_lehmer.c (mpn_gcd_lehmer_n): Renamed (was
+ mpn_gcd_lehmer). Now takes inputs of equal size.
+
+ * mpn/generic/gcd_lehmer.c (mpn_gcd_lehmer): Reintroduced gcd_2,
+ to get better performance for small inputs.
+
+ * mpn/generic/hgcd.c: Don't hardcode small HGCD_THRESHOLD.
+ * mpn/x86_64/gmp-mparam.h (HGCD_THRESHOLD): Reduced from 145 to
+ 120.
+ * */gmp-mparam.h: Renamed HGCD_SCHOENHAGE_THRESHOLD to
+ HGCD_THRESHOLD.
+
+2008-09-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * doc/gmp.texi: Fix a typo and clarify mpn_gcdext docs.
+
+2008-09-09 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/common.c (speed_mpn_hgcd, speed_mpn_hgcd_lehmer): Adapted
+ to new hgcd interface.
+
+ * gmp-impl.h (MPN_HGCD_LEHMER_ITCH): New macro.
+
+ * hgcd.c (mpn_hgcd_lehmer): Renamed function, from hgcd_base. Made
+ non-static.
+
+ * gcd_lehmer.c (mpn_gcd_lehmer): Use hgcd2 also for n == 2.
+
+ * gcdext_lehmer.c (mpn_gcdext_lehmer): Simplified code for
+ division step. Added proper book-keeping of swaps, which affect
+ the sign of the returned cofactor.
+
+ * tests/mpz/t-gcd.c (one_test): Display co-factor when mpn_gcdext
+ fails.
+
+ * gcd_lehmer.c (mpn_gcd_lehmer): At end of loop, need to handle
+ the special case n == 1 correctly.
+
+ * gcd_subdiv_step.c (mpn_gcd_subdiv_step): Simplified function.
+ The special cancellation logic is not needed here.
+
+2008-09-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/invert.c: Add working but slow code.
+
+ * mpn/x86_64/x86_64-defs.m4 (R32, R8): New macros.
+
+ * mpn/ia64/submul_1.asm: Move some labels for broader assembler
+ compatibility.
+
+ * gmp-impl.h (mpn_mul_3, mpn_mul_4): Declare.
+ * tests/tests.h (refmpn_mul_3, refmpn_mul_4): Declare.
+ * tests/try.c (param_init): Set things up for mpn_mul_3 and mpn_mul_4.
+ (choice_array): Likewise.
+ (call): Likewise.
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES):
+ Add mul_3.c and mul_4.
+ * mpn/asm-defs.m4: Define mul_3 and mul_4.
+ * tests/refmpn.c (refmpn_mul_N): New function.
+ (refmpn_mul_2): Remove old definition, call refmpn_mul_N.
+ (refmpn_mul_3, refmpn_mul_4): New functions.
+ * tune/common.c (speed_mpn_mul_3, speed_mpn_mul_4): New functions.
+ * tune/speed.h (speed_mpn_mul_3, speed_mpn_mul_4): Declare.
+ * tune/speed.c (routine): New entries for mpn_mul_2 and mpn_mul_3.
+
+ * ltmain.sh: Update to libtool 1.5.24.
+
+ * mpn/generic/mul_toom22.c: Compute s and t more cleverly.
+
+2008-09-08 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/t-hgcd.c: Updated tests. Rewrite of hgcd_ref.
+
+ * mpn/generic/gcdext_lehmer.c (mpn_gcdext_lehmer_itch): New function.
+ (mpn_gcdext_lehmer): Various bugfixes.
+
+ * gcdext.c (mpn_gcdext): Allocate scratch space for gcdext_lehmer.
+
+ * mpn/generic/gcd_lehmer.c (gcd_2): ASSERT that inputs are odd.
+ (mpn_gcd_lehmer): Added tp argument, for scratch space. Make both
+ arguments odd before calling gcd_2.
+
+ * mpn/generic/hgcd.c (mpn_hgcd): Allow the trivial case n <= 2,
+ and return 0 immediately.
+
+ * gmp-impl.h (MPN_EXTRACT_NUMB): New macro.
+
+ * configure.in (gmp_mpn_functions): Added gcdext_lehmer.
+
+2008-09-05 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/toom_interpolate_7pts.c: Use mpn_divexact_by3c instead of
+ divexact_odd.
+
+ * doc/texinfo.tex: Update to 2007-06-29.13.
+
+ * doc/gmp.texi: Update GMP site URL. Fix some typos.
+
+ * demos/pexpr.c (main): Allow bases up to 62.
+
+ * gmp-impl.h: Remove formal parameter names from function prototypes.
+
+ * config.guess: Recognize recent AMD and Itanium CPUs.
+ Default X86 CPU recognition to configfsf.guess' value.
+
+ * configure.in: Handle core2 separately from athlon64.
+
+2008-09-05 Niels Möller <nisse@lysator.liu.se>
+
+ * */Makefile.in, configure, aclocal.m4, config.in: Removed files
+ from repository. They're instead generated by automake and
+ autoconf before distribution.
+
+2008-08-25 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpf/set_str.c: Allocate mantissa space based on mantissa size,
+ not on destination variable space.
+ * mpf/set_str.c: Accept unary plus before exponent.
+
+2008-08-06 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mul_toom22.c: Add statistics gathering functionality,
+ triggered by cpp predef STAT.
+
+ From David Harvey:
+ * mpn/generic/mul_toom22.c: Decrease scratch space usage.
+
+2008-08-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/misc/t-scanf.c: Avoid negative arguments to _ui functions.
+ * tests/misc/t-printf.c: Likewise.
+
+ * acinclude.m4 (X86_PATTERN): Add geode.
+
+ * acinclude.m4 (CL_AS_NOEXECSTACK): Avoid -q flag to grep.
+
+2008-08-01 Torbjorn Granlund <tege@gmplib.org>
+
+ * acinclude.m4 (CL_AS_NOEXECSTACK): New.
+ * configure.in: Use CL_AS_NOEXECSTACK.
+ * mpn/Makeasm.am: Use ASM_FLAGS (defined by CL_AS_NOEXECSTACK).
+
+ * gmpxx.h (__GMP_DBL_LIMBS): Use DBL_MAX_EXP instead of
+ std::numeric_limits<double>::max_exponent for better portability.
+
+2008-07-29 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmpxx.h (__GMP_DBL_LIMBS): New #define.
+ (__GMP_ULI_LIMBS): New #define.
+ (__GMPXX_TMP_UI): New macro.
+ (__GMPXX_TMP_SI): New macro.
+ (__GMPXX_TMP_D): New macro.
+ (struct __gmp_binary_and): Rewrite, using the new macros.
+ (struct __gmp_binary_ior): Likewise.
+ (struct __gmp_binary_xor): Likewise.
+
+2008-07-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/cxx/t-binary.cc: Add some tests for logical operations.
+
+2008-07-24 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmpxx.h: Use __GMPZ_* instead of __GMPZZ_* for bitwise ops, remove
+ __GMPZZ_*.
+ Remove repeated #undefs.
+ (__gmp_alloc_cstring): Declare freefunc as extern "C".
+
+2008-07-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-h.in (__GMP_CC): New define, undocumented for now.
+ (__GMP_CFLAGS): Likewise.
+
+2008-07-21 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/amd64check.c: Fix a printf type clash.
+
+ * mpz/realloc.c: Amend last fix.
+
+ * gmp-h.in: Include <cstdlib> for C++.
+ * gmp-h.in: Handle new gcc 4.3 inline semantics defaults.
+
+ * configfsf.guess: Update to version of 2008-04-14.
+ * configfsf.sub: Update to version of 2008-06-16.
+
+ * configure.in: Separate core2 and athlon64 flags handling.
+
+2008-06-19 Torbjorn Granlund <tege@gmplib.org>
+
+ * config.guess: Recognize pentiumm and AMD geode.
+ * config.sub: Likewise.
+ * configure.in: Likewise.
+
+2008-06-02 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in: Disallow odd nails sizes.
+ * configure.in: Inherit default gcc_cflags/gcc_64_cflags everywhere.
+
+2008-05-23 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/init2.c: Rewrite to avoid internal overflow and to detect mpz_t
+ overflow.
+ * mpz/realloc2.c: Likewise.
+ * mpz/realloc.c: Detect mpz_t overflow.
+
+2008-05-22 Torbjorn Granlund <tege@gmplib.org>
+
+ * configure.in (sparc): Remove -fast, it causes documented
+ miscompilation.
+
+ * config.guess: Properly handle the "extended" variants of x86 cpuid.
+
+2008-05-09 Torbjorn Granlund <tege@gmplib.org>
+
+ * gmp-impl.h (mpn_mul_fft): Now void.
+ (udiv_qrnnd_preinv3): Special case for constant (nl).
+
+2008-05-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/generic/mul_fft.c: Clean up types in TRACE (printf (...)).
+ (TRACE): Redefine to allow command line control.
+ (mpn_mul_fft_internal): Now void, remove return value.
+ (mpn_mul_fft): Likewise.
+ (MPN_FFT_TABLE2_SIZE): Up size fro 256 to 512.
+ (mpn_fft_fft): Call mpn_fft_mul_2exp_modF just once instead of twice,
+ then add/subtract result. Get rid of temp allocation as a result.
+ Remove some redundant CNST_LIMB.
+ (mpn_fft_fftinv): Analogous changes.
+ (mpn_fft_sub_modF): Re-enable, now needed by mpn_fft_fft and
+ mpn_fft_fftinv.
+
+2008-03-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/mpz/t-mul.c (main): Let GMP_CHECK_FFT mean largest allowed
+ power-of-2 of test operands.
+
+2008-02-28 Torbjorn Granlund <tege@gmplib.org>
+
+ * tests/cxx/t-binary.cc (check_mpz): Expect floor rounding for right
+ shift.
+
+2008-02-27 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpz/mul_i.h: Check sml's size (not the signed small_mult).
+
+ * longlong.h (umul_ppmm) [alpha]: Define using __builtin_alpha_umulh
+ when possible.
+
+ * longlong.h (count_trailing_zeros): Force destination register mode.
+
+ * gmpxx.h (struct __gmp_binary_rshift): Use floor rounding, not
+ truncation.
+
+ * gmpxx.h (__gmp_binary_and, __gmp_binary_ior, __gmp_binary_xor):
+ Add variants with unsigned long int argument.
+
+ * config.sub: Recog geode.
+ * config.guess: Likewise.
+ * acinclude.m4 (X86_PATTERN): Likewise.
+
+2008-02-10 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/p6/aors_n.asm: Use Zdisp to work around GNU as bug.
+ * mpn/x86/x86-defs.m4 (Zdisp): Add more instructions.
+
+2008-02-08 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86_64/aors_n.asm: New file.
+ * mpn/x86_64/add_n.asm: Delete.
+ * mpn/x86_64/sub_n.asm: Delete.
+
+2008-02-07 Torbjorn Granlund <tege@gmplib.org>
+
+ * mpn/x86/k6/mmx/dive_1.asm: Fix typo in last change.
+
+2007-12-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/set_str.c (mpf_set_str): Write own code for converting the
+ exponent, avoids strtol base < 36 limitation.
+
+2007-10-28 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (mpn_dc_get_str_itch): New macro.
+ (mpn_dc_get_str_powtab_alloc): New macro.
+ (struct powers): Add field "shift".
+
+ * mpn/generic/get_str.c: Compute powers without low zero limbs; all
+ functions modified. Correct temporary allocation. Misc cleanups.
+
+ * mpn/generic/set_str.c: Compute powers without low zero limbs; all
+ functions modified.
+ (mpn_dc_set_str): Remove impossible case, replace by an ASSERT.
+
+2007-10-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/set_str.c: Remove default thresholds, not in gmp-impl.h.
+ (mpn_dc_set_str): Insert ASSERT_ALWAYS in a presumably dead code arm.
+
+2007-10-22 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (mpn_add_nc): Define as inline function, unless NATIVE.
+ (mpn_sub_nc): Likewise.
+
+2007-10-17 Torbjorn Granlund <tege@swox.com>
+
+ * tests/misc/t-printf.c: Fix a printf type clash.
+ * tests/mpq/t-get_str.c: Likewise.
+ * tests/mpz/t-import.c: Likewise.
+
+ * acinclude.m4: Conditionally disable some tests when compiled by a C++
+ compiler.
+
+ * gmp-impl.h (udiv_qrnnd_preinv3): Remove an unused variable.
+
+ * mpn/generic/hgcd.c: Add some WANT_ASSERTs to shut up warnings.
+
+2007-10-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/elf.m4 (LEAL): Define as an alias for LEA.
+ * mpn/powerpc32/darwin.m4 (LEAL): Likewise.
+ * mpn/powerpc64/aix.m4: Likewise.
+
+ * mpn/powerpc64/vmx/popcount.asm: Use LEAL.
+
+ * mpn/powerpc64/darwin.m4 (LEAL): New name for LEA, since it is only
+ usable for local symbols.
+ (LEA): Replace with code for external references.
+
+ * mpn/powerpc32/vmx/mod_34lsub1.asm: Use LEAL.
+
+2007-10-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/dive_1.asm: Use LEA, remove explicit movl_eip_*.
+ * mpn/x86/k6/mode1o.asm: Likewise.
+ * mpn/x86/k6/mmx/dive_1.asm: Likewise.
+ * mpn/x86/k7/dive_1.asm: Likewise.
+ * mpn/x86/k7/mode1o.asm: Likewise.
+ * mpn/x86/p6/dive_1.asm: Likewise.
+ * mpn/x86/p6/mode1o.asm: Likewise.
+ * mpn/x86/pentium4/sse2/dive_1.asm: Likewise.
+ * mpn/x86/pentium4/sse2/mode1o.asm: Likewise.
+ * mpn/x86/pentium4/sse2/popcount.asm: Likewise.
+
+ * mpn/x86/p6/aors_n.asm: Table cycle counts.
+
+ * mpn/x86/k7/mod_34lsub1.asm: Fix over-optimistic cycle count claims.
+
+ * mpn/x86/x86-defs.m4 (DEF_OBJECT, END_OBJECT): New define's.
+
+ * mpn/x86/darwin.m4 (LEA): Put also movl_eip_XX into EPILOGUE_cpu.
+ Expect target register to have prepended %.
+
+ * mpn/x86_64/add_n.asm: Use L() for labels.
+ * mpn/x86_64/addlsh1_n.asm: Likewise.
+ * mpn/x86_64/addmul_2.asm: Likewise.
+ * mpn/x86_64/aorrlsh_n.asm: Likewise.
+ * mpn/x86_64/aorsmul_1.asm: Likewise.
+ * mpn/x86_64/com_n.asm: Likewise.
+ * mpn/x86_64/copyd.asm: Likewise.
+ * mpn/x86_64/copyi.asm: Likewise.
+ * mpn/x86_64/diveby3.asm: Likewise.
+ * mpn/x86_64/logops_n.asm: Likewise.
+ * mpn/x86_64/lshsub_n.asm: Likewise.
+ * mpn/x86_64/mul_1.asm: Likewise.
+ * mpn/x86_64/mul_2.asm: Likewise.
+ * mpn/x86_64/mul_basecase.asm: Likewise.
+ * mpn/x86_64/popham.asm: Likewise.
+ * mpn/x86_64/redc_1.asm: Likewise.
+ * mpn/x86_64/rsh1add_n.asm: Likewise.
+ * mpn/x86_64/rsh1sub_n.asm: Likewise.
+ * mpn/x86_64/rshift.asm: Likewise.
+ * mpn/x86_64/sub_n.asm: Likewise.
+ * mpn/x86_64/sublsh1_n.asm Likewise.
+ * mpn/x86_64/pentium4/aors_n.asm: Likewise.
+ * mpn/x86_64/pentium4/lshift.asm: Likewise.
+ * mpn/x86_64/pentium4/rshift.asm: Likewise.
+
+ * mpn/x86_64/x86_64-defs.m4: New file, defining LEA, DEF_OBJECT, and
+ END_OBJECT.
+
+ * mpn/generic/mul.c: Put TMP_DECL as last decl.
+
+2007-10-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/popcount.asm: New file.
+
+2007-09-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/get_str.c: Cast a char index to int to shut up compilers.
+
+ * mpn/generic/dc_div_qr.c: Pass dummy scratch argument to mpn_invert.
+ * mpn/generic/dc_divappr_q.c: Likewise.
+ * mpn/generic/mu_div_qr.c: Likewise.
+ * mpn/generic/mu_divappr_q.c: Likewise.
+ * mpn/generic/mu_div_q.c: Likewise.
+ * mpn/generic/divexact.c: Likewise.
+
+ * mpn/generic/invert.c: New file, placeholder for now.
+
+2007-09-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/toom_interpolate_5pts.c: New file, contents from
+ mpn/generic/mul_n.c
+ * mpn/generic/mul_n.c (mpn_toom3_interpolate): Function removed.
+
+ * mpn/generic/toom_interpolate_7pts.c: New file.
+
+ * mpn/x86/k7/mmx/popham.asm: Table cycle counts.
+
+ * mpn/x86/k6/README: Update URLs.
+
+ * mpn/powerpc32/README: Update URL's, company names.
+
+ * mpn/generic/get_d.c: Complete rewrite.
+
+ * mpn/generic/mul_toom33.c: New file.
+
+ * mpn/generic/mul_toom22.c: Make orthogonal with other toomXY files.
+ * mpn/generic/mul_toom32.c: Likewise.
+ * mpn/generic/mul_toom42.c: Likewise.
+
+ * mpn/alpha/invert_limb.asm: Update cycle counts. Fix a comment typo.
+
+ * mpf/get_str.c: Include stdlib.h, not stdio.h for NULL.
+
+ * doc/gmp.texi: Fix a typo.
+
+ * memory.c (__gmp_default_allocate, __gmp_default_reallocate):
+ Cast size operands in error fprintf's.
+
+ * longlong.h (sub_ddmmss) [powerpc 64]: Add more variants for constant
+ args.
+
+ * gmp-impl.h (udiv_qrnnd_preinv3): New define.
+ * gmp-impl.h (ULONG_PARITY): Exclude masquerading __INTEL_COMPILER from
+ ia64 asm.
+
+ * gmp-h.in (mpn_neg_n): New function.
+
+2007-09-18 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (main): Add -v option.
+ (enum op_t): New tag TIMING.
+ (mpz_eval_expr): Execute TIMING.
+ (fns): Add TIMING entry.
+
+ * gmp-impl.h: Add decls and THRESHOLDs for new toom multiplication
+ functions and division functions.
+
+2007-09-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/addlsh1_n.asm: Use L() for labels.
+ * mpn/powerpc32/sublsh1_n.asm: Likewise.
+
+2007-09-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/x86-defs.m4 (LEA): New define.
+ * mpn/x86/darwin.m4: New file, for now just defining LEA.
+ * configure.in: Pick up x86/darwin.m4.
+ * mpn/x86/*: Use LEA for PIC references.
+
+ * configure.in: For X86/32, treat core2 like pentium3.
+
+2007-09-06 Torbjorn Granlund <tege@swox.com>
+
+ * tests/amd64check.c (calling_conventions_values): Put constants,
+ dynamic values in this array (was in scalars).
+ (calling_conventions_check): Corresponding changes.
+ * tests/amd64call.asm: Rewrite to be PIC, smaller, using amd64check.c's
+ array.
+
+2007-09-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/mul_basecase.asm: Misc cleanups.
+ * mpn/x86/pentium4/sse2/sqr_basecase.asm: Likewise.
+
+ * mpn/x86_64/mod_34lsub1.asm: Optimize loop, reduce code size.
+
+ * tests/amd64call.asm: Remove bogus no-op moves.
+
+2007-09-03 Torbjorn Granlund <tege@swox.com>
+
+ From Richard Guenther:
+ * gmp-h.in (__GMP_EXTERN_INLINE): Declare conditionally on
+ __GNUC_STDC_INLINE__.
+
+ * tests/cxx/t-locale.cc: #include <cstdlib>, for abort.
+
+ * mpn/x86_64/core2/popcount.asm: New file.
+ * mpn/x86_64/pentium4/popcount.asm: New file.
+
+ * mpn/x86_64/addmul_2.asm: New file.
+ * mpn/x86_64/mul_2.asm: New file.
+
+ * mpn/x86_64/aorsmul_1.asm: Use 32-bit mov for zeroing registers
+ (saves space).
+
+2007-09-01 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Handle athlon64, core2, and pentium4 separately for
+ 64-bit ABI.
+
+ * config.sub: Recog athlon64, core2, and opteron.
+
+ * config.guess: Do two x86 variants, for 32-bit ABI and 64-bit ABI.
+ Return "athlon64" and "core2", not x86_64.
+
+2007-08-31 Torbjorn Granlund <tege@swox.com>
+
+ From Patrick Pelissier:
+ * gmp-h.in: Don't refer to FILE from C++ unless we've seen FILE.
+
+2007-08-30 Torbjorn Granlund <tege@swox.com>
+
+ * demos/isprime.c: Include string.h for strcmp.
+
+ * demos/factorize.c (main): Declare to int.
+
+2007-06-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/pentium4/lshift.asm: Minor tuning.
+ * mpn/x86_64/pentium4/rshift.asm: Likewise.
+
+2007-05-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/aors_n.asm: Add _nc entry points.
+
+2007-05-22 Torbjorn Granlund <tege@swox.com>
+
+ * tests/memory.c: Cast calls to new mem* calls to avoid unaligned ops.
+
+2007-05-16 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/convert.c: Tweak operand sizes for best coverage.
+
+ * tests/memory.c: Add red zones around allocations.
+
+2007-05-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mul_1.asm: Make mul_1c entry point actually work.
+
+ * mpn/generic/set_str.c (mpn_dc_set_str): Avoid calling mpn_add_n when
+ ln == 0.
+
+ * tests/mpz/convert.c (string_urandomb): New function.
+ (main): Use it by enabling ifdef'ed out code.
+
+2007-04-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/mul_basecase.asm: Complete rewrite.
+
+ * mpn/x86_64/copyi.asm: Use short shift-by-one form. Misc cleanups.
+ * mpn/x86_64/copyi.asm: Likewise.
+ * mpn/x86_64/popham.asm: Likewise.
+
+ * mpn/x86_64/aorsmul_1.asm: Cleanup formatting.
+
+2007-04-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/divexact.c: Handle undefined case of |N| < |D| to avoid segfaults.
+
+2007-02-24 Torbjorn Granlund <tege@swox.com>
+
+ * doc/gmp.texi (Toom 3-Way Multiplication): Fix typo.
+ (mpz_scan0, mpz_scan1): Fix typos.
+ (Float Internals): Rewrite paragraph about struct types.
+
+2007-02-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/sqr_basecase.asm: Complete rewrite (except
+ diagonal code).
+
+2007-02-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_fft.c (mpn_fft_fft): New name for mpn_fft_fft_sqr,
+ old mpn_fft_fft removed.
+ (mpn_mul_fft_internal): Call mpn_fft_fft separately for each operand.
+ (mpn_fft_add_modF): Rewrite to avoid random branches.
+ (mpn_fft_sub_modF): Likewise.
+
+ * mpn/x86/pentium4/sse2/addmul_1.asm: Complete rewrite.
+ * mpn/x86/pentium4/sse2/mul_1.asm: Complete rewrite.
+ * mpn/x86/pentium4/sse2/mul_basecase.asm: Complete rewrite, based on
+ new addmul and mul code.
+
+2007-01-31 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c (mpn_sb_get_str): Get loop count for frac
+ development right.
+
+ * mpn/powerpc32/vmx/mod_34lsub1.asm: New file.
+
+ * mpn/powerpc32/aors_n.asm: New file, complete rewrite.
+ * mpn/powerpc32/add_n.asm: Remove.
+ * mpn/powerpc32/sub_n.asm: Remove.
+
+2007-01-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/core2/aors_n.asm: Add _nc entry points, minor cleanups.
+
+ * mpn/x86_64/core2/lshift.asm: Rewrite.
+ * mpn/x86_64/core2/rshift.asm: Rewrite.
+
+ * mpn/x86_64/pentium4/lshift.asm: Swap some loop insns for a small
+ speedup.
+ * mpn/x86_64/pentium4/rshift.asm: New file, based on lshift.asm.
+
+ * mpn/x86_64/pentium4/gmp-mparam.h: New file.
+
+ * mpn/x86_64/pentium4/aors_n.asm: Complete rewrite of add/subtract
+ code.
+ * mpn/x86_64/pentium4/add_n.asm: Remove.
+ * mpn/x86_64/pentium4/sub_n.asm: Remove.
+
+2007-01-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/lshift.asm: Add special case for cnt=1.
+
+2007-01-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/aorsmul_1.asm: New file, written from scratch, finally at
+ 3.0 c/l on K8 (addmul_1 was 3.3; submul_1 was 3.5).
+ * mpn/x86_64/addmul_1.asm: Remove.
+ * mpn/x86_64/submul_1.asm: Remove.
+
+2006-12-29 Torbjorn Granlund <tege@swox.com>
+
+ * randmt.c (__gmp_randclear_mt): Initialize ALLOC field, like in
+ __gmp_randinit_mt_noseed.
+ (__gmp_randclear_mt, __gmp_randinit_mt_noseed): Make similar functions
+ look similar.
+ (__gmp_randclear_mt): Pass actually allocated size.
+
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Add mul_toom22.c,
+ mul_toom32.c, mul_toom42.c.
+
+ * configure.in: Recognize athlon64 and core2 as alternatives to x86_64.
+ Provide special settings for core2.
+
+ * configure.in (gmp_mpn_functions): Add mul_toom22, mul_toom32,
+ mul_toom42.
+
+ * mpn/generic/mul_toom22.c: New file.
+ * mpn/generic/mul.c: Use mpn_mul_toom22. Trim cutoff points between
+ the mpn_mul_toomN2 functions. Handle balanced operands at function
+ entry.
+
+2006-12-29 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+ * mpn/generic/mul_n.c: Rewrite interpolation code.
+
+2006-12-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_toom32.c: New file.
+ * mpn/generic/mul_toom42.c: New file.
+ * mpn/generic/mul.c: Use mpn_mul_toom32 and mpn_mul_toom42 for
+ unbalanced operands.
+
+2006-12-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/aorrlsh_n.asm: New file.
+ * mpn/x86_64/lshsub_n.asm: New file.
+
+ * mpn/x86_64/core2/aors_n.asm: New file.
+ * mpn/x86_64/core2/lshift.asm: New file.
+ * mpn/x86_64/core2/rshift.asm: New file.
+
+ * mpn/x86/p6/aors_n.asm: Replace K7 grabbing code with P6 specific
+ code.
+
+ * mpn/x86/p6/lshsub_n.asm: New file.
+
+2006-11-23 Torbjorn Granlund <tege@swox.com>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_MUL_BASECASE): Allocate space for xp
+ locally, s->xp might be insufficient.
+
+2006-11-22 Torbjorn Granlund <tege@swox.com>
+
+ * randmt.c (__gmp_randinit_mt_noseed): Initialize ALLOC field of result
+ param.
+
+2006-11-06 Torbjorn Granlund <tege@swox.com>
+
+ * tune/set_strp.c: New file.
+
+2006-11-04 Torbjorn Granlund <tege@swox.com>
+
+ * extract-dbl.c: Rewrite to handle nails better, and for general
+ optimization.
+
+ * mpz/bin_uiui.c: Simplify.
+
+ * longlong.h (umul_ppmm) [mmix]: New.
+
+ * tune/tuneup.c, tune/common.c, tune/speed.c, tune/speed.h,
+ tune/set_strb.c, tune/set_strs.c: Add tuning and speed measurements
+ of separate SET_STR_DC_THRESHOLD and SET_STR_PRECOMPUTE_THRESHOLD.
+ Add tuning and speed measurement of mpn_addsub_n.
+
+2006-10-31 Torbjorn Granlund <tege@swox.com>
+
+ * gmpxx.h: Remove ternary stuff, it is hardly an optimization and it
+ writes to destination before reading all source operands.
+
+2006-10-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/set_str.c: Complete rewrite.
+ * mpn/generic/get_str.c: Likewise.
+
+ * gmp-impl.h (struct powers, powers_t): New types.
+ Restructure GET_STR_* and SET_STR_* thresholds.
+
+2006-09-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/rootrem.c: Remove some redundant casts.
+
+2006-07-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/nails/addmul_2.asm: Make it run at claimed speed.
+ * mpn/alpha/ev6/nails/addmul_4.asm: Likewise.
+
+ * mpf/get_str.c: Avoid copying result when not needed. Misc cleanups.
+
+ * tests/amd64call.asm: Use jmp instead of jmpq to placate Solaris.
+
+2006-06-30 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (powerpc-*): Remove repeated path component.
+
+2006-06-15 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: (ia64-*-linux*): Don't use -O3.
+
+2006-06-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpq/get_str.c: Fix upper base limit boundary in an ASSERT.
+
+ * tests/refmpn.c (refmpn_sb_divrem_mn): Use ASSERT_CARRY for add-back.
+
+2006-05-31 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-set_d.c (check_data): Add more data points.
+
+ * mpz/set_d.c: Handle negative return values from __gmp_extract_double.
+
+2006-05-17 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Clear out gcc_cflags_cpu and gcc_cflags_arch for a fat
+ build.
+
+2006-05-16 Torbjorn Granlund <tege@swox.com>
+
+ * demos/primes.c (find_primes): Increase mpz_probab_prime_p cnt to 10.
+
+ * mpn/generic/addsub_n.c: Fix criteria form when to call _nc functions.
+
+2006-05-12 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Recognize more ppc processor types.
+
+2006-05-11 Torbjorn Granlund <tege@swox.com>
+
+ * tune/speed.c (usage): Update URL for gnuplot and quickplot.
+
+2006-05-10 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (powerpc-*-*): Pass -maltivec to assembler for
+ appropriate CPUs.
+
+2006-05-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/aix.m4 (LEA): Remove [RW] attribute.
+
+2006-05-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/vmx/popcount.asm: Conditionally zero extend n.
+
+2006-04-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/divexact.c: Call mpz_tdiv_q for large operands.
+
+ * configure.in (powerpc-*-darwin): Remove -fast, it affects PIC.
+
+2006-04-26 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Try to recognize Ultrasparc T1 (as ultrasparct1).
+ * config.sub: Handle ultrasparct1.
+
+2006-04-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/gmp-mparam.h: Retune, without separation of GNUC and
+ non-GNUC data.
+
+2006-04-20 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/convert.c: Increase operands range.
+
+2006-04-19 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Support powerpc eABI.
+ * mpn/powerpc32/eabi.m4: New file.
+
+ * configure.in: Support powerpc *bsd.
+ * mpn/powerpc64/elf.m4: New name for mpn/powerpc64/linux64.m4.
+ * mpn/powerpc32/elf.m4: New name for mpn/powerpc32/linux.m4.
+
+ * mpn/powerpc64/linux64.m4 (ASM_END): Quote TOC_ENTRY.
+
+2006-04-18 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (gmp_mpn_functions_optional): Add lshiftc.
+ (HAVE_NATIVE): Add lshiftc.
+
+ * mpn/powerpc64/mode64/invert_limb.asm: Use LEA, not LDSYM.
+ * mpn/powerpc64/mode64/mode1o.asm: Likewise.
+ * mpn/powerpc64/mode64/dive_1.asm: Likewise.
+
+ * mpn/powerpc64/linux64.m4 (TOC_ENTRY): Define to empty.
+ * mpn/powerpc64/aix.m4 (TOC_ENTRY): Likewise.
+ * mpn/powerpc32/aix.m4 (TOC_ENTRY): Likewise.
+
+ * mpn/powerpc32/aix.m4 (EXTERN): New, copied form powerpc64/aix.m4.
+ * mpn/powerpc32/mode1o.asm: Use EXTERN.
+ * mpn/powerpc32/linux.m4 (EXTERN): Provide dummy definition.
+ * mpn/powerpc32/darwin.m4 (EXTERN): Likewise.
+
+2006-04-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_fft.c: Use new thresholds mechanism if MUL_FFT_TABLE2
+ is defined.
+ (mpn_lshiftc): New name for mpn_lshift_com (for consistency with some
+ stuff already in 4.1.4.
+ (mpn_fft_mul_2exp_modF): Reorganize initial operand reductions to avoid
+ divisions.
+
+ * tests/devel/try.c (choice_array): Add mpn_addsub_n[c].
+
+2006-04-11 Torbjorn Granlund <tege@swox.com>
+
+ * aclocal.m4: Regenerate with patched libtool.
+
+ * mpn/asm-defs.m4 (ASM_END): Provide (empty) default.
+
+2006-04-08 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (gmp_mpn_functions_optional): Add addsub.
+
+ * gmpxx.h: Remove missed MPFR references.
+
+ * gmp-impl.h (LIMBS_PER_DOUBLE): Adjust formula to not be pessimistic.
+
+ * gmp-impl.h (TMP_*, WANT_TMP_DEBUG): Don't expect marker argument;
+ define TMP_SALLOC and TMP_BALLOC.
+
+ * mpn/minithres/gmp-mparam.h: New file.
+
+ * tests/mpz/t-io_raw.c: Fix printf type/arg mismatches.
+ * tests/mpz/t-export.c: Likewise.
+ * tests/mpz/io.c: Likewise.
+ * tests/t-constants.c: Likewise.
+
+ * mpn/ia64/popcount.asm: Append "cond.dptk" to conditional branches to
+ placate icc.
+ * mpn/ia64/hamdist.asm: Likewise.
+ * mpn/ia64/lorrshift.asm: Likewise.
+ * mpn/ia64/dive_1.asm: Likewise.
+
+2006-04-05 Torbjorn Granlund <tege@swox.com>
+
+ * tal-notreent.c (__gmp_tmp_mark): Add "struct" tag for tmp_marker.
+ (__gmp_tmp_free): Likewise.
+
+ * mpn/generic/mul_fft.c: Optimize many scalar divisions and mod
+ operations into masks and shifts.
+ (mpn_fft_mul_modF_K): Fix a spurious ASSERT_NOCARRY.
+
+2006-03-26 Torbjorn Granlund <tege@swox.com>
+
+ * Version 4.2 released.
+
+ * mpn/powerpc64/aix.m4 (LEA): Renamed from LDSYM.
+ * mpn/powerpc64/darwin.m4: Likewise.
+ * mpn/powerpc64/linux64.m4: Likewise.
+ * mpn/powerpc64/vmx/popcount.asm: Use LEA, not LDSYM.
+
+2006-03-23 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h: (class gmp_allocated_string): Prefix strlen with std::.
+
+ * gmpxx.h (__GMP_DEFINE_TERNARY_EXPR2): Remove for now.
+ (struct __gmp_ternary_addmul2): Likewise.
+ (struct __gmp_ternary_submul2): Likewise.
+
+ * gmpxx.h: #include <cstring>.
+ (struct __gmp_alloc_cstring): Prefix strlen with std::.
+
+ * mpn/x86/pentium/com_n.asm: Add TEXT and ALIGN.
+ * mpn/x86/pentium/copyi.asm: Likewise.
+ * mpn/x86/pentium/copyd.asm: Likewise.
+
+2006-03-22 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-h.in: Add a "using std::FILE" for C++.
+ (_GMP_H_HAVE_FILE): Check also _ISO_STDIO_ISO_H.
+
+ * gmpxx.h: Remove mpfr code.
+ * tests/cxx: Likewise.
+
+ * gmp-impl.h (FORCE_DOUBLE): Rename a tempvar to avoid a clash with
+ GNU/Linux public include file.
+
+ * configure.in (powerpc64, darwin): New optional, gcc_cflags_subtype.
+ Grab powerpc32/darwin.m4 for ABI=mode32.
+
+ * configure.in: Use host_cpu whenever just the cpu type is needed.
+
+2006-03-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/get_si.c: Fix a typo.
+
+ * tests/mpq/t-get_d.c (check_random): Improve random generation for
+ nails.
+
+2006-02-28 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpq/t-get_d.c (check_random): New function.
+ (main): Call check_random.
+
+ * mpq/set_d.c: Make choices based on LIMBS_PER_DOUBLE, not
+ BITS_PER_MP_LIMB. Make it work for LIMBS_PER_DOUBLE == 4.
+ Use MPZ_REALLOC.
+
+ * mpz/set_d.c: Make it work for LIMBS_PER_DOUBLE == 4.
+
+ * extract-dbl.c: Make it work for LIMBS_PER_DOUBLE > 3.
+
+2006-02-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/cmp_d.c: Declare `i'.
+ * mpz/cmpabs_d.c: Likewise.
+
+2006-02-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/vmx/copyd.asm: Set right VRSAVE bits.
+ * mpn/powerpc32/vmx/copyi.asm: Likewise.
+
+2006-02-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/vmx/logops_n.asm: New file.
+
+ * mpn/powerpc32/diveby3.asm: Rewrite.
+
+2006-02-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/vmx/copyi.asm: New file.
+ * mpn/powerpc32/vmx/copyd.asm: New file.
+
+2006-02-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/nails/aors_n.asm (CYSH): Import proper setting from
+ deleted mpn_sub_n.
+
+2006-02-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/addmul_1.asm: Correct slotting comments.
+
+2006-02-15 Torbjorn Granlund <tege@swox.com>
+
+ * tests/devel/anymul_1.c: Copy error reporting code from addmul_N.c.
+
+ * tests/devel/addmul_N.c: New file.
+ * tests/devel/mul_N.c: New file.
+
+ * mpn/alpha/default.m4 (PROLOGUE_cpu): Align functions at 16-byte
+ boundary.
+
+ * mpn/alpha/ev6/nails/aors_n.asm: New file.
+ * mpn/alpha/ev6/nails/add_n.asm: Remove.
+ * mpn/alpha/ev6/nails/sub_n.asm: Remove.
+
+ * mpn/alpha/ev6/nails/addmul_1.asm: Rewrite.
+ * mpn/alpha/ev6/nails/submul_1.asm: Likewise.
+ * mpn/alpha/ev6/nails/mul_1.asm: Likewise.
+
+ * mpn/alpha/ev6/nails/addmul_2.asm: Use L() for labels.
+ * mpn/alpha/ev6/nails/addmul_3.asm: Use L() for labels.
+ * mpn/alpha/ev6/nails/addmul_4.asm: Use L() for labels.
+
+2006-02-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/diveby3.asm: Trivially reorder loop insns to save
+ 1 c/l.
+
+ * mpn/x86_64/dive_1.asm: Use movabsq to support large model non-PIC.
+
+ * mpn/x86_64/rsh1add_n.asm: Replace high register with rbx.
+ * mpn/x86_64/rsh1sub_n.asm: Likewise.
+
+2006-02-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/sqr_diagonal.asm: Software pipeline.
+
+ * mpn/powerpc64/vmx/popcount.asm: Add prefetching.
+
+2006-02-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/diveby3.asm: Rewrite.
+
+2006-02-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/vmx/popcount.asm: Remove mpn_hamdist partial code.
+ Move compare for huge n so that it is always executed.
+
+2006-02-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/linux.m4 (LEA): Add support for PIC.
+
+ * configure.in (powerpc): New optional, gcc_cflags_subtype.
+
+ * mpn/x86_64/pentium4/add_n.asm: New file.
+ * mpn/x86_64/pentium4/sub_n.asm: New file.
+ * mpn/x86_64/pentium4/lshift.asm: New file.
+
+ * mpn/powerpc64/linux64.m4 (PROLOGUE_cpu): Align function start to
+ 16-multiple.
+ * mpn/powerpc64/aix.m4: Likewise.
+ * mpn/powerpc64/darwin.m4: Likewise.
+
+ * mpn/powerpc64/copyi.asm: Align loop to 16-multiple.
+ * mpn/powerpc64/copyd.asm: Likewise
+
+ * configure.in (powerpc): Add vmx to relevant paths.
+
+ * mpn/powerpc64/linux64.m4 (DEF_OBJECT): Accept 2nd argument, for
+ alignment.
+ * mpn/powerpc64/aix.m4: Likewise.
+ * mpn/powerpc64/darwin.m4: Likewise.
+
+ * mpn/powerpc32/linux.m4 (DEF_OBJECT, END_OBJECT): New macros,
+ inherited from powerpc64 versions.
+ * mpn/powerpc32/aix.m4: Likewise.
+ * mpn/powerpc32/darwin.m4: Likewise.
+
+ * mpn/powerpc64/vmx/popcount.asm: New file, for ppc32 and ppc64.
+ * mpn/powerpc32/vmx/popcount.asm: New file, grabbing above file.
+
+2006-01-22 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Generalize OS-dependent patterns for powerpcs.
+
+2006-01-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/popham.asm: Optimize.
+
+ * config.guess: Recognize power4 and up under linux-gnu.
+ * config.sub: Generalize power recognition code.
+ * acinclude.m4 (POWERPC64_PATTERN): Add 64-bit powerpc processors.
+ * configure.in: Recognize powerpc processors masquerading as power
+ processors.
+
+2006-01-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/logops_n.asm: Rewrite for more stable speed and smaller
+ code.
+ * mpn/x86_64/com_n.asm: Likewise.
+
+2006-01-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/addlsh1_n.asm: Rewrite to use indexed addressing.
+ * mpn/x86_64/sublsh1_n.asm: Likewise.
+
+2006-01-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/diveby3.c: Use GMP standard parameter names. Nailify
+ alternative code. Use restrict for params.
+
+ * configure.in: Recognize andn_n as not needing nailification.
+
+ * tests/mpq/t-equal.c (check_various): Disable a test that gives common
+ factors for GMP_NUMB_BITS == 62.
+
+2006-01-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c (mpn_sb_get_str): Fix digit count computation,
+ was inaccurate for nails.
+
+2006-01-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/mode1o.asm: Remove unneeded carry register zeroing.
+
+2006-01-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/sqr_diagonal.asm: New file.
+
+2006-01-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/mod_34lsub1.asm: Tune to 1.5 c/l.
+
+ * mpn/generic/mullow_n.c (MUL_BASECASE_ALLOC): New #define.
+ (mpn_mullow_n): Use it.
+
+ * mpn/powerpc64/mode64/dive_1.asm: Use EXTERN.
+ * mpn/powerpc64/mode64/mode1o.asm: Likewise.
+
+ * mpn/powerpc64/aix.m4 (EXTERN): Define to import symbol.
+ (LDSYM): Remove [RW] attribute.
+ * mpn/powerpc64/linux64.m4 (EXTERN): Dummy definition.
+ * mpn/powerpc64/darwin.m4 (EXTERN): Likewise.
+
+2006-01-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/mode1o.asm: New file.
+
+ * mpn/powerpc64/mode64/dive_1.asm: Use L() for labels. Invoke ASM_END.
+
+ * mpn/powerpc64/mode64/invert_limb.asm: Invoke ASM_END.
+
+ * mpn/powerpc64/linux64.m4: Move toc entry generation from direct at
+ DEF_OBJECT to delayed via LDSYM, define ASM_END to output it.
+ * mpn/powerpc64/aix.m4: Likewise.
+ * mpn/powerpc64/darwin.m4: Define a dummy ASM_END.
+
+ * mpn/powerpc64/mode64/addmul_1.asm: Add POWER5 timings.
+ * mpn/powerpc64/mode64/mul_1.asm: Likewise.
+
+ * mpn/powerpc64/mode64/submul_1.asm: Tweak to save 1.5 c/l for POWER5.
+
+2006-01-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/dive_1.asm: New file.
+
+ * mpn/powerpc64/mode64/invert_limb.asm: Add missing ASM_START.
+
+ * mpn/powerpc64/mode64/addmul_1.asm: Fix a comment typo.
+
+ * mpn/x86_64/diveby3.asm: Rewrite.
+
+2006-01-03 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Update bugs reporting address.
+
+ * mpn/powerpc64/mode64/diveby3.asm: Trim a cycle off of POWER4 timing.
+ Misc cleanup.
+
+2006-01-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/linux64.m4 (CALL): New macro.
+ * mpn/powerpc64/aix.m4: Likewise.
+ * mpn/powerpc64/darwin.m4: Likewise, also define macro "DARWIN".
+
+2005-12-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/mod_34lsub1.asm: New file.
+
+2005-12-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/mod_34lsub1.asm: New file.
+
+2005-12-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86_64/submul_1.asm: Save a push/pop by not using register r12.
+ Use addq instead of leaq for pointer updates; schedule them. (These
+ changes shaves one cycle of overhead and 0.25 c/l.)
+
+2005-12-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/ui_div.c: Implement workaround for GCC bug triggered on alpha.
+ * mpf/set_q.c: Likewise.
+
+2005-12-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/tdiv_qr.c: Remove statement with no effect.
+ Rename dead variable to `dummy'.
+
+2005-12-15 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (setup_error_handler): Add a missing ";".
+
+2005-11-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul.c: Crudely call mpn_mul_fft_full before checking
+ for unbalanced operands.
+
+ * mpn/generic/mul_fft.c: Remove many scalar divisions.
+ (mpn_mul_fft_lcm): Simplify.
+ (mpn_mul_fft_decompose): Rewrite to handle arbitrarily unbalanced
+ operands.
+
+2005-11-22 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Properly recognize all 32-bit Solaris releases.
+
+2005-11-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_fft.c: Inline mpn_fft_mul_2exp_modF,
+ mpn_fft_add_modF and mpn_fft_normalize.
+
+2005-11-02 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/reuse.c: Increase operand size, decrease # of reps.
+
+ * mpz/rootrem.c: Adapt to new mpn_rootrem.
+ * mpz/root.c: Likewise.
+
+ * tests/mpz/reuse.c: Test mpz_rootrem.
+
+ With Paul Zimmermann:
+ * mpn/generic/rootrem.c: Complete rewrite.
+
+2005-10-31 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/pprime_p.c (mpz_probab_prime_p): Considerably limit trial
+ dividing.
+
+ * mpz/perfpow.c (mpz_perfect_power_p): Use mpz_divisible_ui_p instead
+ of mpz_tdiv_ui.
+
+ * mpz/divegcd.c: Correct probability number for GCD == 1.
+
+ * mpn/x86_64/mul_basecase.asm: Remove an obsolete comment.
+
+ * mpn/x86: Add cycle counts for array of x86 processors.
+
+ * mpn/x86/k7/mod_34lsub1.asm: Remove spurious mentions of ebp.
+
+ * mpn/powerpc32: Add POWER5 timings.
+
+ * mpn/powerpc32/README: Describe global reference variations.
+
+ * mpn/ia64/divrem_2.asm: Add some comments.
+
+ * mpn/ia64/divrem_1.asm: Reformat.
+
+ * mpn/ia64/addmul_2.asm: Correct a comment on slotting.
+ * mpn/ia64/logops_n.asm: Likewise.
+
+ * mpn/ia64/addmul_1.asm: Remove a redundant preg mutex decl.
+
+ * mpn/generic/dive_1.c: Whitespace cleanup.
+
+ * mpn/alpha/ev6/nails/addmul_1.asm: Correct comments on slotting.
+ * mpn/alpha/ev6/nails/addmul_2.asm: Likewise.
+ * mpn/alpha/ev6/nails/addmul_4.asm: Likewise.
+
+ * mpf/out_str.c: List some allocation improvement ideas.
+
+ * doc/gmp.texi: Update many URLs and email addresses.
+
+ * gmp-h.in (_GMP_H_HAVE_FILE): Check also _STDIO_H_INCLUDED.
+
+2005-10-26 Torbjorn Granlund <tege@swox.com>
+
+ * tune/tuneup.c (tune_mullow): Update param.max_size for each threshold
+ measurement.
+
+ * configure.in (POWERPC64_PATTERN/*-*-darwin*): Set
+ SPEED_CYCLECOUNTER_OBJ_mode64 and cyclecounter_size_mode64.
+ (POWERPC64_PATTERN/*-*-linux*): Likewise.
+
+2005-10-03 Torbjorn Granlund <tege@swox.com>
+
+ * demos/factorize.c (factor_using_division_2kp): Honor verbose flag.
+ (factor_using_pollard_rho): Divide out new factor before it's
+ clobbered. Don't stop factoring after a composite factor was found.
+
+2005-09-17 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (fns): Add factorial keywords.
+
+2005-08-16 Torbjorn Granlund <tege@swox.com>
+
+ * tune/Makefile.am (EXTRA_DIST): Change "amd64" => "x86_64".
+ * mpn/Makefile.am (TARG_DIST): Change "amd64" => "x86_64".
+
+2005-08-15 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Change "amd64" => "x86_64".
+
+2005-06-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/pre_mod_1.c: Canonicalize variable names.
+
+ * mpn/generic/divrem.c: Rate qxn test as UNLIKELY.
+
+ * mpn/generic/gcdext.c (sanity_check_row): Invoke TMP_MARK.
+
+ * tune/tuneup.c (tune_mullow): Fix all max_size fields.
+
+ * gmp-impl.h (SQR_TOOM3_THRESHOLD_LIMIT): New #define.
+ * tune/tuneup.c (tune_sqr): Use SQR_TOOM3_THRESHOLD_LIMIT.
+ (sqr_toom3_threshold): Initialize from SQR_TOOM3_THRESHOLD_LIMIT.
+
+ * mpn/generic/mul_n.c (mpn_sqr_n): Use SQR_TOOM3_THRESHOLD_LIMIT.
+
+ * gmp-impl.h (mpn_nand_n, mpn_iorn_n, mpn_nior_n, mpn_xnor_n):
+ Handle nails.
+
+2005-06-13 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext.c (gcdext_schoenhage): Check for the
+ (unlikely) case that one of the hgcd/euclid steps results in two
+ remainders of one limb each. Then use gcdext_1.
+
+2005-06-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/sub_n.asm: Analogous changes as to add_n.asm last.
+
+2005-06-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/add_n.asm: Rewrite inner loop to load later.
+ Add mpn_add_nc entry.
+
+ * mpn/alpha/ev6/addmul_1.asm: Remove redundant initial loads.
+
+2005-06-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/dive_1.asm: Fix issues with HP-UX.
+
+2005-06-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/diveby3.asm: Update TODO list.
+
+ * mpn/ia64/mode1o.asm: Fix comment typos.
+
+ * mpn/ia64/dive_1.asm: New file.
+
+2005-06-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mode1o.asm: Add prefetching.
+
+ * mpn/generic/dive_1.c: Use variable h for upper umul_ppmm result.
+
+2005-06-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/hamdist.asm: Complete rewrite.
+ * mpn/ia64/popcount.asm: Rewrite to use multi-pronged feed-in.
+
+ * mpn/ia64/aors_n.asm: Rewrite feed-in code.
+ * mpn/ia64/rsh1aors_n.asm: Likewise.
+ * mpn/ia64/aorslsh1_n.asm: Likewise.
+ * mpn/ia64/lorrshift.asm: Likewise.
+
+2005-06-04 Torbjorn Granlund <tege@swox.com>
+
+ * tests/devel/try.c (choice_array): Exclude mpn_preinv_mod_1 unless
+ USE_PREINV_MOD_1.
+ (choice_array): Exclude mpn_sqr_basecase if SQR_KARATSUBA_THRESHOLD
+ is zero.
+
+2005-06-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/addmul_1.asm: Prefix all labels with "$".
+ * mpn/alpha/ev6/mul_1.asm: Likewise.
+
+2005-06-02 Torbjorn Granlund <tege@swox.com>
+
+ * tests/refmpn.c (refmpn_divmod_1c_workaround): Implement workaround
+ to gcc 3.4.x bug triggered on powerpc64 with 32-bit ABI.
+
+2005-06-01 Torbjorn Granlund <tege@swox.com>
+
+ * tests/devel/try.c (main): Fix a typo.
+
+2005-05-31 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/addmul_1.asm: Rewrite for L1 cache, add prefetch.
+
+2005-05-30 Torbjorn Granlund <tege@swox.com>
+
+ * tests/misc.c (tests_rand_start): Mask random seed to 32 bits.
+
+2005-05-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode32/mul_1.asm: Handle BROKEN_LONGLONG_PARAM.
+ * mpn/powerpc64/mode32/addmul_1.asm: Likewise.
+ * mpn/powerpc64/mode32/submul_1.asm: Likewise.
+
+ * mpn/powerpc32/mode1o.asm: Rewrite to actually work.
+
+ * mpn/powerpc32/aix.m4 (LEA): New macro.
+ (ASM_END): New macro.
+
+ * mpn/powerpc32/linux.m4: New file.
+ * mpn/powerpc32/darwin.m4: New file.
+ * configure.in: Use linux.m4 and darwin.m4.
+ (powerpc64-linux-gnu): Add support for mode32.
+
+2005-05-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mullow_n.c: Remove FIXME mentioning fixed flaw.
+
+ * tests/mpz/t-cmp_d.c (check_one): Fix printf fmt string typo.
+
+ * demos/isprime.c: #include stdlib.h.
+ * tests/rand/t-urbui.c: Likewise.
+ * tests/rand/t-urmui.c: Likewise.
+
+ * tests/mpz/t-popcount.c (check_random): Remove spurious printf arg.
+
+ * mpn/ia64/lorrshift.asm: Cleanup code layout.
+ * mpn/ia64/popcount.asm: Likewise.
+
+2005-05-24 Torbjorn Granlund <tege@swox.com>
+
+ * tests/devel/try.c (param_init) [TYPE_GET_STR]: Set retval field.
+ (compare): Handle SIZE_GET_STR as SIZE_RETVAL.
+
+ * tests/refmpn.c (refmpn_get_str): Rewrite to make it work.
+
+2005-05-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/add_n.asm: Add mpn_add_nc entry point.
+ * mpn/amd64/sub_n.asm: Add mpn_sub_nc entry point.
+
+ * longlong.h (many places): Remove lvalue casts.
+
+ * gmp-impl.h (MPF_SIGNIFICANT_DIGITS): Cast prec to avoid overflow
+ for > 4G digits.
+
+ * mpn/alpha/ev6/add_n.asm: Prefetch using ldl.
+ * mpn/alpha/ev6/sub_n.asm: Likewise.
+
+ * mpn/alpha/ev6/slot.pl (optable): Recognize negq and ldl.
+
+ * mpn/ia64/aors_n.asm: Prefetch using lfetch.
+ * mpn/ia64/lorrshift.asm: Likewise.
+ * mpn/ia64/popcount.asm: Likewise.
+ * mpn/ia64/diveby3.asm: Likewise.
+
+2005-05-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev67/popcount.asm: Prefetch.
+ * mpn/alpha/ev67/hamdist.asm: Prefetch.
+
+ * longlong.h (add_ssaaaa) [x86]: Remove lvalue casts.
+ (sub_ddmmss) [x86]: Likewise.
+
+ * tests/devel/try.c (param_init) [TYPE_MPZ_JACOBI]: Add DATA_SRC1_ODD.
+ (param_init) [TYPE_MPZ_KRONECKER]: Clear inherited DATA_SRC1_ODD.
+ (param_init) [TYPE_DIVEXACT_1]: Use symbolic name DIVISOR_LIMB.
+
+2005-05-21 Torbjorn Granlund <tege@swox.com>
+
+ * tests/devel/try.c (param_init) [TYPE_MPZ_JACOBI]: Initialize divisor
+ field according to UDIV_NEEDS_NORMALIZATION.
+
+ * mpz/mul_i.h: Remove left-over TMP_XXXX marker arguments.
+
+2005-05-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/addmul_1.asm (mpn_addmul_1c): Put carry in
+ proper register.
+
+ * mpn/generic/sqr_basecase.c (mpn_sqr_basecase, addmul_2 version):
+ Avoid accesses out-of-bound in MPN_SQR_DIAGONAL applicate code.
+
+2005-05-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/diveby3.asm: Make it actually work.
+
+ * gmp-impl.h (MULLOW_BASECASE_THRESHOLD_LIMIT): New #define.
+ * mpn/generic/mullow_n.c: Use fixed stack allocation for the smallest
+ operands; use TMP_S* allocation for medium operands.
+
+ * gmp-impl.h: Remove nested TUNE_PROGRAM_BUILD test.
+
+2005-05-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_n.c: Make squaring and multiplication code more
+ similar. Use TMP_S* functions.
+
+ * gmp-impl.h (TMP_DECL, TMP_MARK, TMP_FREE): Get rid of argument.
+ (TMP_SALLOC): New macro for "small" allocations.
+ (TMP_BALLOC): New macro for "big" allocations.
+ (TMP_SDECL, TMP_SMARK, TMP_SFREE): New macros for functions that use
+ just TMP_SALLOC.
+ (WANT_TMP_ALLOCA): Make default functions choose alloca or reentrant
+ functions, depending on size.
+
+ * *.c: Remove TMP_XXXX marker arguments.
+
+ * acinclude.m4 (WANT_TMP): Want tal-reent.lo also for alloca case.
+
+2005-05-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/gmp-mparam.h: Further extend FFT tables.
+
+2005-05-15 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (udiv_qrnnd_preinv2): Pull an add into add_ssaaaa.
+ (udiv_qrnnd_preinv2gen): Likewise.
+
+2005-05-14 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (add_ssaaaa) [x86_64]: Restrict allowed immediate
+ operands.
+ * (sub_ddmmss) [x86_64]: Likewise.
+
+2005-05-02 Torbjorn Granlund <tege@swox.com>
+
+ * acinclude.m4 (GMP_HPC_HPPA_2_0): Make gmp_tmp_v1 sed pattern handle
+ version numbers like B.11.X.32509-32512.GP.
+
+ * mpn/m68k/aors_n.asm: Correct MULFUNC_PROLOGUE.
+
+ * mpn/powerpc64/mode64/aors_n.asm: Add a MULFUNC_PROLOGUE.
+
+ * mpf/inp_str.c: Use plain int for mpf_set_str return value (works
+ around gcc 4 bug).
+
+ * acinclude.m4 (GMP_ASM_POWERPC_PIC_ALWAYS): Handle darwin's assembly
+ syntax.
+ (long long reliability test 1): New GMP_PROG_CC_WORKS_PART test.
+ (long long reliability test 2): New GMP_PROG_CC_WORKS_PART test.
+
+ * configure.in: Add mode64 support for darwin. Use darwin.m4.
+ Add cflags_opt flags for mode32 darwin.
+
+ * mpn/powerpc64: Use L() for all asm files.
+
+ * mpn/asm-defs.m4 (PIC_ALWAYS): Define PIC just iff PIC_ALWAYS = "yes".
+
+ * mpn/powerpc64/darwin.m4: New file.
+
+ * mpn/powerpc64/linux64.m4: Remove TOCREF, add LDSYM.
+ Rework DEF_OBJECT to need just one argument.
+ * mpn/powerpc64/aix.m4: Likewise.
+
+ * mpn/powerpc64/mode64/invert_limb.asm: Load approx_tab address with
+ LDSYM. Optimize somewhat. Remove 2nd DEF_OBJECT operand.
+
+2005-05-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/popham.c: Compute final summation differently for 64-bit.
+
+ * tests/mpz/t-popcount.c (check_random): New function.
+ (main): Call it.
+
+2005-04-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/add_n.asm: Use r9 instead of rbx to save push/pop.
+ * mpn/amd64/sub_n.asm: Likewise.
+
+2005-04-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/copyi.asm: If HAVE_ABI_mode32, ignore upper 32 bits of
+ mp_size_t argument.
+ * mpn/powerpc64/copyd.asm: Likewise.
+ * mpn/powerpc64/sqr_diagonal.asm: Likewise.
+ * mpn/powerpc64/lshift.asm: Likewise.
+ * mpn/powerpc64/rshift.asm: Likewise.
+ * mpn/powerpc64/logops_n.asm: Likewise.
+ * mpn/powerpc64/com_n.asm: Likewise.
+
+2005-04-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/rootrem.c: Allocate PP_ALLOC limbs also for qp.
+
+2005-04-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/add_n.asm: Add nc entry point.
+ * mpn/powerpc32/sub_n.asm: Likewise.
+
+ * mpn/amd64/*.asm: Add Prescott/Nocona cycle/limb numbers.
+
+ * mpn/alpha/add_n.asm: Add correct cycle/limb numbers.
+ * mpn/alpha/sub_n.asm: Likewise.
+ * mpn/alpha/ev5/add_n.asm: Likewise.
+ * mpn/alpha/ev5/sub_n.asm: Likewise.
+
+2005-03-31 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/k7/gmp-mparam.h: Fix typo in last change.
+
+2005-03-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/gmp-mparam.h: Update.
+
+ * mpn/alpha/gmp-mparam.h: Update.
+ * mpn/alpha/ev5/gmp-mparam.h: Update.
+ * mpn/alpha/ev6/gmp-mparam.h: Update.
+
+ * mpn/ia64/gmp-mparam.h: Update.
+
+ * mpn/x86/p6/mmx/gmp-mparam.h: Update.
+ * mpn/x86/pentium4/sse2/gmp-mparam.h: Update.
+ * mpn/x86/k7/gmp-mparam.h: Update.
+
+ * tests/mpz/t-gcd.c (main): Honor command line reps argument.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_GCD_CALL): Simplify and correct code
+ for generating test operands.
+
+2005-03-17 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (qstack_adjust): New argument d, saying how much
+ to adjust the top quotient.
+ (hgcd_adjust): The quotient can be off by either 1 or 2.
+
+2005-03-16 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-gcd.c (MAX_SCHOENHAGE_THRESHOLD): Set to largest of
+ gcd,gcdext thresholds.
+
+2005-03-15 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext.c (gcdext_schoenhage): When calling gcdext_lehmer,
+ reuse all temporary limb storage, including the storage used for the
+ qstack.
+
+2005-03-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/logops_n.asm: Add MULFUNC_PROLOGUE.
+
+2005-03-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/gmp-mparam.h: Extend MUL_FFT_TABLE and SQR_FFT_TABLE.
+ * mpn/ia64/gmp-mparam.h: Likewise.
+
+2005-02-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/divrem_1.asm: Add preinv entry point.
+
+2005-01-13 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (MPN_SIZEINBASE): Count bits in type size_t.
+ (MPN_SIZEINBASE_16): Likewise.
+
+2004-12-17 Torbjorn Granlund <tege@swox.com>
+
+ * tune/speed.c (run_gnuplot): Use lines, not linespoints.
+ Output a reset gnuplot command initially.
+
+2004-12-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/random2.c (gmp_rrandomb): Rework again.
+ * mpz/rrandomb.c (gmp_rrandomb): Likewise.
+
+ * mpn/amd64/redc_1.asm: Call via PLT when PIC.
+
+2004-11-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/divrem_1.asm: Add preinv entry point.
+ * mpn/amd64/gmp-mparam.h: Set USE_PREINV_DIVREM_1 to 1.
+
+2004-11-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/diveby3.asm: Use correct prefetch instruction.
+
+2004-11-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/diveby3.asm: Add ",gp" glue in PROLOGUE.
+ Add r31 dummy operand to `br' instruction.
+
+2004-11-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/addmul_1.asm: Rewrite.
+ * mpn/powerpc64/mode64/mul_1.asm: Rewrite.
+
+ * configure.in: Invoke AC_C_RESTRICT.
+
+2004-11-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/diveby3.asm: New file.
+
+2004-11-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/popham.asm: New file.
+
+2004-11-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/add_n.asm: Correct cycle count.
+ * mpn/amd64/sub_n.asm: Likewise.
+
+ * mpn/amd64/dive_1.asm: Speed divisors with many factors of 2.
+
+2004-11-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/dive_1.asm: New file.
+
+2004-11-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/popham.c: Add comment.
+
+2004-11-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/com_n.asm: New file.
+
+ * mpn/amd64/logops_n.asm: New file.
+
+2004-11-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/com_n.asm: New file.
+
+2004-11-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/diveby3.asm: New file.
+
+ * config.guess: Strip any PPC string in /proc/cpuinfo.
+ Recognize 970 in that code.
+
+2004-11-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/mul_basecase.asm: New file.
+
+ * mpn/amd64/redc_1.asm: New file.
+
+2004-10-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/addlsh1_n.asm: Correct cycle counts.
+
+ * mpn/powerpc64/README: Update POWER5/PPC970 pipeline information.
+
+ * mpn/generic/mul_basecase.c (MAX_LEFT): Add comment.
+
+ * doc/gmp.texi: Consistently use "x86" denotation.
+ (Assembler SIMD Instructions): Mention SSE2 usage.
+
+ * demos/pexpr.c (main): Handle "negative" base in mpz_sizeinbase call.
+
+2004-10-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/submul_1.asm: Shave 2 cycles/limb with new carry
+ inversion trick.
+
+2004-10-16 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Support icc under x86.
+ (ia64-*-linux*): Pass -no-gcc to icc.
+
+2004-10-15 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (ia64 umul_ppmm): Add version for icc.
+
+ * configure.in: Support icc under ia64-*-linux*.
+
+ * acinclude.m4: New "compiler works" test for icc 8.1 bug.
+ (GMP_PROG_CC_IS_GNU): Don't let Intel's icc fool us it is GCC.
+
+2004-10-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/gcdext.c: Add a few missing TMP_MARK.
+
+2004-10-14 Torbjorn Granlund <tege@swox.com>
+
+ * acinclude.m4 (GMP_ASM_W32): Try also "data4".
+
+ * mpn/ia64/logops_n.asm: Don't use naked "br", rejected by Intel
+ assembler.
+ * mpn/ia64/aors_n.asm: Likewise.
+
+ * mpn/ia64/divrem_2.asm: Add ".prologue".
+
+ * mpn/ia64/hamdist.asm: Put alloc first in bundle, enforced by the
+ Intel assembler.
+
+ * longlong.h: Exclude masquerading __INTEL_COMPILER from ia64 asm.
+ * gmp-impl.h: Likewise.
+
+2004-10-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mul_2.asm: Rewrite function entry code, write new code for
+ n=2.
+ * mpn/ia64/addmul_2.asm: Likewise.
+
+ * tests/devel/try.c: Handle mpn_mul_2 like mpn_addmul_2.
+
+ * tune/speed.c (routine): Make R parameter optional for mpn_mul_2.
+
+2004-10-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/addmul_1.asm: Update a comment.
+
+ * tests/devel/aors_n.c: #include tests.h.
+ * tests/devel/anymul_1.c: Likewise.
+ * tests/devel/shift.c: Likewise.
+ * tests/devel/copy.c: Likewise.
+
+ * tests/devel/aors_n.c: Handle also mpn_addlsh1_n, mpn_sublsh1_n,
+ mpn_rsh1add_n, and mpn_rsh1sub_n.
+
+ * mpn/ia64/submul_1.asm: Add TODO item.
+
+ * mpn/ia64/aors_n.asm: Rewrite function entry code (again).
+ * mpn/ia64/aorslsh1_n.asm: Likewise.
+ * mpn/ia64/logops_n.asm: Likewise.
+
+ * mpn/ia64/rsh1aors_n.asm: Tune function entry and feed-in code.
+ * mpn/ia64/lorrshift.asm: Likewise. Remove several spurious loads.
+
+ * tests/devel/Makefile.am (EXTRA_PROGRAMS): Updates for yesterday's
+ file removals and additions.
+
+2004-10-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/copyi.asm: Tune function entry code.
+ * mpn/ia64/copyd.asm: Likewise.
+
+ * mpn/ia64/logops_n.asm: Tune function entry and feed-in code for speed
+ and size.
+ * mpn/ia64/aors_n.asm: Likewise.
+
+ * mpn/powerpc64/logops_n.asm: Correct cycles counts.
+ * mpn/powerpc64/mode64/aors_n.asm: Likewise.
+
+ * tests/devel/copy.c: Handle both MPN_COPY_INCR and MPN_COPY_DECR.
+
+ * tests/devel/logops_n.c: New file, handle all logical operations.
+
+ * tests/devel/anymul_1.c: New file, handle mpn_mul_1, mpn_addmul_1, and
+ mpn_submul_1
+ * tests/devel/mul_1.c: Remove.
+ * tests/devel/addmul_1.c: Remove.
+ * tests/devel/submul_1.c: Remove.
+
+ * tests/devel/shift.c: New file, handle mpn_lshift and mpn_rshift.
+ * tests/devel/lshift.c: Remove.
+ * tests/devel/rshift.c: Remove.
+
+ * tests/devel/aors_n.c: New file, handle mpn_add_n and mpn_sub_n.
+ * tests/devel/add_n.c: Remove.
+ * tests/devel/sub_n.c: Remove.
+
+2004-10-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/linux64.m4: Define DEF_OBJECT, END_OBJECT, and TOCREF.
+ * mpn/powerpc64/aix.m4: Likewise.
+ * mpn/powerpc64/mode64/invert_limb.asm: Use DEF_OBJECT, END_OBJECT, and
+ TOCREF for approx_tab.
+
+ * mpn/amd64/mul_1.asm: Add mpn_mul_1c entry point.
+
+2004-10-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/copyi.asm: New file.
+ * mpn/powerpc64/copyd.asm: New file.
+ * gmp-h.in: Remove PPC MPN_COPY variants.
+ * gmp-impl.h: Likewise.
+
+ * mpn/powerpc64/logops_n.asm: New file.
+
+ * mpn/powerpc64/mode64/invert_limb.asm: New file.
+
+2004-10-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/aors_n.asm: New file, optimized for POWER4 and
+ its derivatives.
+ * mpn/powerpc64/mode64/add_n.asm: Delete.
+ * mpn/powerpc64/mode64/sub_n.asm: Delete.
+
+ * configfsf.guess: Patch HP-UX code to accommodate HP compiler's new
+ inability to read from stdin.
+
+ * mpn/powerpc64/mode64/addsub_n.asm: Remove accidentally added file.
+
+2004-10-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/README: Update for new developments, fix typos.
+
+ * mpn/amd64/mul_1.asm: Tweak addressing (3.25 => 3.0 cycles/limb).
+
+ * mpn/amd64/addmul_1.asm: Remove unreachable code block.
+
+2004-09-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/addmul_1.asm: Rewrite, now 3.25 cycles/limb.
+
+ * mpn/ia64/addmul_1.asm: Slightly enhance cross-jumping for code
+ density.
+ * mpn/ia64/mul_1.asm: Analogous changes.
+
+2004-09-29 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (x86 ULONG_PARITY): Work around GCC change of "q" register
+ flag.
+
+2004-09-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/divrem_1.asm: Add cycle counts to loop.
+
+ * mpn/ia64/divrem_2.asm: New file.
+
+2004-09-28 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpn/generic/mul_fft.c (mpn_mul_fft): Fix a bug in the choice of the
+ recursive fft parameters.
+
+2004-09-20 Torbjorn Granlund <tege@swox.com>
+
+ * tests/misc.c (tests_rand_start): Default to strtoul for re-seeding.
+
+ * tests/mpz/t-mul.c (ref_mpn_mul): Fudge tmp allocation for toom3.
+
+2004-09-19 Torbjorn Granlund <tege@swox.com>
+
+ * tests/misc.c (tests_rand_start): Shift tv_usec for better seeding.
+
+2004-09-18 Torbjorn Granlund <tege@swox.com>
+
+ * tests/misc.c (tests_rand_start): Invoke fflush after printing seed.
+
+ * tests/mpz/t-mul.c (main): Check environment for GMP_CHECK_FFT, run
+ extra FFT tests if set.
+ (ref_mpn_mul): Use library code for kara and toom, but skewded so that
+ we never use the same algorithm that we're testing.
+ (mul_kara): Delete.
+ (debug_mp): Print just one line of large numbers.
+ (ref_mpn_mul): Rework usage of tp temporary space.
+
+2004-09-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mul_2.asm: For HAVE_ABI_32, convert vp.
+ * mpn/ia64/addmul_2.asm: Likewise.
+
+2004-09-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/invert_limb.asm: Rewrite.
+
+ * mpn/ia64/logops_n.asm: Insert some more stops.
+
+2004-09-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/gmp-mparam.h: Update.
+ * mpn/amd64/gmp-mparam.h: Update.
+
+ * mpn/ia64/sqr_diagonal.asm: Shave off a few cycles.
+
+2004-09-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mul_2.asm: New file.
+ * mpn/ia64/addmul_2.asm: New file.
+
+ * mpn/ia64/addmul_1.asm: Tune a cycle from prologue.
+
+ * mpn/ia64/lorrshift.asm: Insert stops after several branches.
+ * mpn/ia64/aorslsh1_n.asm: Likewise.
+ * mpn/ia64/rsh1aors_n.asm: Likewise.
+
+ * mpn/generic/sqr_basecase.c: In variant for HAVE_NATIVE_mpn_addmul_2,
+ accumulate carry also for when HAVE_NATIVE_mpn_addlsh1_n.
+
+2004-09-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/submul_1.asm: Rewrite.
+
+ * mpn/ia64/addmul_1.asm: Format to placate HP-UX assembler.
+ * mpn/ia64/mul_1.asm: Likewise.
+
+2004-09-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mul_1.asm: Optimize feed-in code.
+ * mpn/ia64/addmul_1.asm: Rewrite feed-in code.
+
+2004-08-29 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-sizeinbase.c: Disable mpz_fake_bits and check_sample.
+
+2004-07-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/addmul_1.asm: Format to placate HP-UX assembler.
+
+2004-06-17 Kevin Ryde <kevin@swox.se>
+
+ * doc/gmp.texi: Use @. when sentence ends with a capital, for good
+ spacing in tex.
+ (Language Bindings): Add gmp-d, reported by Ben Hinkle. Update SWI
+ Prolog URL, reported by Jan Wielemaker.
+
+2004-06-09 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Handle --enable-fat. Use that to enable x86 fat
+ builds, remove magic meaning of i386-*-*.
+
+2004-06-03 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (memset): Use a local char* pointer, in case parameter is
+ something else (eg. tune/common.c). Reported by Emmanuel Thomé.
+
+2004-06-01 Kevin Ryde <kevin@swox.se>
+
+ * config.guess (i?86-*-*): Avoid "Illegal instruction" message which
+ goes to stdout on 80386 freebsd4.9.
+
+2004-05-23 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext.c (gcdext_1_u): New function.
+ (mpn_gcdext): Use it.
+
+2004-05-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/gcdext.c (gcdext_1_odd): Use masking to avoid jumps.
+
+2004-05-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/addmul_1.asm: Add Prescott cycle numbers.
+
+ * mpn/amd64/divrem_1.asm: Shave a cycle from fraction development code.
+
+ * mpn/powerpc32/lshift.asm: Add more cycle numbers.
+ * mpn/powerpc32/rshift.asm: Likewise.
+
+ * mpn/ia64/addmul_1.asm: Reformat.
+
+2004-05-21 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (mpn_mullow_n, mpn_mullow_basecase): Declare.
+
+ * tune/Makefile.am: Compile gcdext.c.
+
+ * gmp-impl.h (GET_STR_THRESHOLD_LIMIT): Lower outrageous value to 150.
+ (GCDEXT_SCHOENHAGE_THRESHOLD): Set reasonable default. Override when
+ TUNE_PROGRAM_BUILD.
+ (GCDEXT_THRESHOLD): Remove.
+
+ * tune/tuneup.c (gcdext_schoenhage_threshold): New variable.
+ (gcdext_threshold): Remove variable.
+ (tune_gcd_schoenhage): Lower step_factor to 0.1.
+ (tune_gcdext_schoenhage): New function, based on tune_gcd_schoenhage.
+ (tune_gcdext): Remove function.
+ (all): Corresponding changes.
+
+2004-05-21 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/gcdext.c: Complete rewrite. Uses fast Lehmer code for
+ small operands, and Schoenhage code for large operands.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_GCD_CALL): Ensure first operand is
+ not smaller than 2nd operand.
+
+2004-05-17 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (mpz_get_ui): Use #if instead of plain if, and for nails
+ use ?: same as normal case, to avoid warnings from Borland C++ 6.0.
+ Reported by delta trinity.
+
+2004-05-15 Kevin Ryde <kevin@swox.se>
+
+ * tune/time.c (getrusage_backwards_p): New function
+ (speed_time_init): Use it to exclude broken netbsd1.4.1 getrusage.
+ * configure.in (m68*-*-netbsd1.4*): Remove code pretending getrusage
+ doesn't exist.
+ * tune/README (NetBSD 1.4.1 m68k): Update notes.
+
+ * configure.in (mips*-*-* ABI=n32): Remove gcc_n32_ldflags and
+ cc_n32_ldflags, libtool knows to put the linker in n32 mode.
+
+2004-05-15 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess (powerpc*-*-*): Add more processor types to mfpvr code.
+ * configure.in: Generalize powerpc subtype matching code.
+
+ * mpz/fac_ui.c: Misc cleanups, spelling corrections.
+
+2004-05-14 Kevin Ryde <kevin@swox.se>
+
+ * mpf/sub.c: When one operand cancels high limbs of the other, strip
+ high zeros on the balance before truncating to destination precision.
+ Truncating first loses accuracy and can lead to a result 0 despite
+ operands being not equal. Reported by John Abbott.
+ Also, ensure exponent is zero when result is zero, for instance if
+ operands are exactly equal.
+ * tests/mpf/t-sub.c (check_data): New function, exercising these.
+
+2004-05-12 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_PROG_RANLIB): New macro, supposedly required by
+ automake, though it doesn't complain.
+
+ * demos/expr/Makefile.am (ARFLAGS): Add a default setting, to
+ workaround an automake bug.
+
+2004-05-10 Kevin Ryde <kevin@swox.se>
+
+ * */Makefile.in, install-sh, aclocal.m4: Update to automake 1.8.4.
+
+ * doc/gmp.texi (Demonstration Programs): Add a remark about expression
+ evaluation in the main gmp library.
+
+ * demos/expr/exprfa.c (mpf_expr_a): Correction to mpX_init, use
+ mpf_init2 to follow requested precision.
+ * demos/expr/exprza.c, demos/expr/exprqa.c: Use wrappers for mpX_init,
+ to make parameters match.
+
+ * demos/expr/run-expr.c: Don't use getopt, to avoid needing configury
+ for optarg declaration. Remove TRY macro, rename foo and bar to var_a
+ and var_b, for clarity.
+ * demos/expr/expr-impl.h: Don't use expr-config.h.
+ * configure.in (demos/expr/expr-config.h): Remove.
+ * demos/expr/expr-config.in: Remove file.
+
+2004-05-08 Kevin Ryde <kevin@swox.se>
+
+ * doc/configuration (Configure): Update for current automake not
+ copying acinclude.m4 into aclocal.m4.
+
+ * configure.in, Makefile.am, doc/gmp.texi, doc/configuration,
+ tests/cxx/Makefile.am, demos/expr/Makefile.am, demos/expr/README,
+ demos/expr/expr.c, demos/expr/expr.h, demos/expr/expr-config-h.in,
+ demos/expr/expr-impl.h, demos/expr/run-expr.c, demos/expr/t-expr.c:
+ MPFR now published separately, remove various bits.
+ * mpfr/*, tests/cxx/t-headfr.cc, demos/expr/exprfr.c,
+ demos/expr/exprfra.c: Remove.
+
+2004-05-07 Kevin Ryde <kevin@swox.se>
+
+ * tests/cxx/Makefile.am (TESTS_ENVIRONMENT): Amend c++ shared library
+ path hack, on k62-unknown-dragonfly1.0 /usr/bin/make runs its commands
+ "set -e", so we need an "|| true" in case there's nothing to copy (for
+ instance in a static build).
+
+2004-05-06 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/mode1o.c: Remove, in favour of ...
+ * mpn/alpha/mode1o.asm: New file.
+ * mpn/alpha/alpha-defs.m4 (bwx_available_p): New macro.
+
+ * tune/amd64.asm: Save rbx in r10 rather than on the stack.
+
+ * configure.in (x86_64-*-*): Try also "-march=k8 -mno-sse2", in case
+ we're in ABI=32 on an old OS not supporting xmm regs.
+ (GMP_GCC_PENTIUM4_SSE2, GMP_OS_X86_XMM): Run these tests under
+ -march=k8 too, and not under ABI=64.
+
+ * doc/gmp.texi (Converting Integers): For mpz_get_d, note truncation
+ and overflows. For mpz_get_d_2exp note truncation, note result if
+ OP==0, and cross reference libc frexp.
+ (Rational Conversions): For mpq_get_d, note truncation and overflows.
+ (Converting Floats): For mpf_get_d, note truncation and overflows.
+ For mpf_get_d_2exp, note truncation, note result if OP==0.
+ (Assembler Code Organisation): Note nails subdirectories.
+ Clarification of get_d_2exp OP==0 reported by Sylvain Pion.
+
+2004-05-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mullow_n.c, mpn/generic/mullow_basecase.c: New files
+ (mainly by Niels Möller).
+ * configure.in, mpn/Makefile.am: Add them.
+
+ * gmp-impl.h (MULLOW_BASECASE_THRESHOLD, MULLOW_DC_THRESHOLD,
+ MULLOW_MUL_N_THRESHOLD): Override for TUNE_PROGRAM_BUILD.
+
+ * tune/Makefile.am: Compile mullow_n.c.
+ * tune/common.c (speed_mpn_mullow_n, speed_mpn_mullow_basecase):
+ New functions.
+ * tune/speed.c (routine): Add entries for mpn_mullow_n and
+ mpn_mullow_basecase.
+ * tune/speed.h (SPEED_ROUTINE_MPN_MULLOW_N_CALL,
+ SPEED_ROUTINE_MPN_MULLOW_BASECASE): New #defines.
+ * tune/tuneup.c (tune_mullow): New function.
+
+ * gmp-impl.h (invert_limb): Compute branch-freely.
+
+2004-05-02 Kevin Ryde <kevin@swox.se>
+
+ * mpn/amd64/mode1o.asm: Use movabsq to support large model non-PIC.
+ Use 32-bit insns to save code bytes, and to save a couple of cycles on
+ the initial setup multiplies.
+
+2004-05-01 Kevin Ryde <kevin@swox.se>
+
+ * doc/gmp.texi (References): Update gcc online docs url to
+ gcc.gnu.org.
+
+ * configure.in (mips*-*-irix[6789]*): Correction to m4 quoting of this
+ pattern. (Believe the mips64*-*-* part also used picks up all current
+ irix6 tuples anyway.) Reported by Rainer Orth.
+
+2004-04-30 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_PROG_CC_X86_GOT_EAX_EMITTED,
+ GMP_ASM_X86_GOT_EAX_OK): New macros.
+ (GMP_PROG_CC_WORKS): Use them to detect an old gas bug tickled by
+ recent gcc. Reported by David Newman.
+
+ * doc/gmp.texi (Reentrancy): Note also gmp_randinit_default as an
+ alternative to gmp_randinit.
+
+2004-04-29 Torbjorn Granlund <tege@swox.com>
+
+ * configfsf.guess: Update to 2004-03-12.
+ * configfsf.sub: Likewise.
+
+2004-04-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/rrandomb.c (gmp_rrandomb): Rework to avoid extra limb allocation
+ and to generate even numbers.
+ * mpn/generic/random2.c (gmp_rrandomb): Likewise.
+
+2004-04-25 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (FORCE_DOUBLE): Don't use an asm with a match constraint
+ on a memory output, apparently not supported and provokes a warning
+ from gcc 3.4.
+
+2004-04-24 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h (count_leading_zeros_gcc_clz,
+ count_trailing_zeros_gcc_ctz): New macros.
+ (count_leading_zeros, count_trailing_zeros) [x86]: Use them on gcc
+ 3.4.
+
+ * configure.in (x86-*-* gcc_cflags_cpu): Give a -mtune at the start of
+ each option list, for use by gcc 3.4 to avoid deprecation warnings
+ about -mcpu.
+
+ * mpz/aorsmul.c, mpz/aorsmul_i.c, mpz/cfdiv_q_2exp.c,
+ mpz/cfdiv_r_2exp.c, mpq/aors.c, mpf/ceilfloor.c: Give REGPARM_ATTR()
+ on function definition too, as demanded by gcc 3.4.
+
+2004-04-22 Kevin Ryde <kevin@swox.se>
+
+ * tests/rand/t-lc2exp.c (check_bigc1): New test.
+
+ * doc/fdl.texi: Tweak @appendixsubsec -> @appendixsec to match our
+ preference for this in an @appendix, and because texi2pdf doesn't
+ support @appendixsubsec directly within an @appendix.
+
+2004-04-20 Kevin Ryde <kevin@swox.se>
+
+ * doc/texinfo.tex: Update to 2004-04-07.08 from texinfo 4.7.
+ * doc/gmp.texi, mpfr/mpfr.texi (@copying): Don't put a line break in
+ @ref within @copying, recent texinfo.tex doesn't like that.
+
+ * demos/perl/GMP.xs (static_functable): Treat cygwin the same as mingw
+ DLLs.
+
+ * */Makefile.in, install-sh: Update to automake 1.8.3.
+ * ltmain.sh, aclocal.m4, configure: Update to libtool 1.5.6.
+
+ * gmp-impl.h (LIMB_HIGHBIT_TO_MASK): Use a compile-time constant
+ expression, rather than a configure test.
+ * acinclude.m4, configure.in (GMP_C_RIGHT_SHIFT): Remove, no longer
+ needed.
+ * tests/t-hightomask.c: New file.
+ * tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * macos/configure (parse_top_configure): Look for PACKAGE_NAME and
+ PACKAGE_VERSION now used by autoconf.
+ (what_objects): Only demand 9 object files, as for instance occurs in
+ the scanf directory.
+ (asm files): Transform labels L(foo) -> Lfoo. Take func name from
+ PROLOGUE to support empty "EPILOGUE()". Recognise and substitute
+ register name "define()"s.
+ * macos/Makefile.in (CmnObjs): Add tal-notreent.o.
+
+2004-04-19 Torbjorn Granlund <tege@swox.com>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_ROOTREM): New #define.
+ (speed_mpn_rootrem): Declare.
+ * tune/common.c (speed_mpn_rootrem): New function.
+ * tune/speed.c (routine): Add entry for mpn_rootrem.
+
+2004-04-16 Kevin Ryde <kevin@swox.se>
+
+ * doc/fdl.texi: Update from FSF, just fixing a couple of typos.
+
+ * macos/configure, macos/Makefile.in: Add printf and scanf directories.
+
+ * tests/mpz/t-gcd.c (check_data): New function, exercising K6
+ gcd_finda bug.
+
+2004-04-14 Kevin Ryde <kevin@swox.se>
+
+ * doc/gmp.texi (Reentrancy, Random State Initialization): Note
+ gmp_randinit use of gmp_errno is not thread safe. Reported by Vincent
+ Lefèvre.
+
+ * doc/gmp.texi (Random State Initialization): Add index entries for
+ gmp_errno and constants.
+
+ * mpn/m68k/README: Update _SHORT_LIMB -> __GMP_SHORT_LIMB.
+
+ * configure.in (--enable-mpbsd): Typo Berkley -> Berkeley in help msg.
+
+2004-04-12 Kevin Ryde <kevin@swox.se>
+
+ * demos/perl/GMP.xs (static_functable): New macro, use it for all
+ function tables, to support mingw DLL builds.
+ * demos/perl/INSTALL (NOTES FOR PARTICULAR SYSTEMS): Remove note on
+ DLLs, should be ok now.
+
+ * demos/perl/sample.pl: Print the module and library versions in use.
+
+ * demos/perl/GMP.pm, Makefile.PL (VERSION): Set to '2.00'.
+ * demos/perl/GMP.pm (COPYRIGHT): New in the doc section.
+
+ * Makefile.am: Note 4.1.3 libtool versioning info, and REVISION policy.
+
+ * tal-debug.c: Add <stdlib.h> for abort.
+
+2004-04-07 Torbjorn Granlund <tege@swox.com>
+
+ * tests/refmpf.c (refmpf_add_ulp): Adjust exponent when needed.
+
+ * mpn/generic/random2.c: Rewrite (clone mpz/rrandomb.c).
+
+2004-04-07 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k6/gcd_finda.asm: Correction jbe -> jb in initial setups.
+ Zero flag is wrong here, it relects only the high limb of the compare,
+ leading to n1>=n2 not satisfied and wrong results. cp[1]==0x7FFFFFFF
+ with cp[0]>=0x80000001 provokes this.
+
+ * doc/gmp.texi (BSD Compatible Functions): Note "pow" name clash under
+ the pow function description too.
+ (Language Bindings): Add XEmacs (betas at this stage). Reported by
+ Jerry James.
+
+ * tests/refmpn.c (refmpn_mod2): Correction to ASSERTs, r==a is allowed.
+
+ * gen-psqr.c (generate_mod): Cast mpz_invert_ui_2exp args, for K&R.
+ * gen-bases.c, gen-fib.c, gen-psqr.c: For mpz_out_str, use stdout
+ instead of 0, in case a K&R treats int and FILE* params differently.
+
+2004-04-04 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (BSWAP_LIMB) [amd64]: New macro.
+ (FORCE_DOUBLE): Use this for amd64 too.
+
+ * tests/amd64check.c, tests/amd64call.asm: New files, derived in part
+ from x86check.c and x86call.asm.
+ * tests/Makefile.am (EXTRA_libtests_la_SOURCES): Add them.
+ * configure.in (x86_64-*-* ABI=64): Use them.
+
+2004-04-03 Kevin Ryde <kevin@swox.se>
+
+ * mpn/amd64/mode1o.asm: New file.
+ * mpn/amd64/amd64-defs.m4 (ASSERT): New macro.
+
+ * mpn/x86/k7/mmx/divrem_1.asm, mpn/x86/pentium4/sse2/divrem_1.asm: Add
+ note on how "dr" part of algorithm is handled.
+
+ * mpn/x86/k7/dive_1.asm, mpn/x86/k7/mod_34lsub1.asm,
+ mpn/x86/k7/mode1o.asm: Note Hammer (32-bit mode) speeds.
+
+2004-03-31 Kevin Ryde <kevin@swox.se>
+
+ * doc/gmp.texi (Language Bindings): Add GOO, MLGMP and Numerix.
+
+ * mpf/mul_2exp.c, mpf/div_2exp.c: Rate u==0 as UNLIKELY.
+
+2004-03-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/divrem_1.asm: Trim a few cycles.
+
+2004-03-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/sublsh1_n.asm: Fix typo.
+
+ * mpn/generic/divrem_1.c: Fix typo.
+
+ * mpn/generic/sqr_basecase.c: Fix typo.
+
+ * mpn/amd64/divrem_1.asm: New file.
+
+2004-03-20 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h (power, powerpc): Add comments on how we select this code.
+
+ * gmp-h.in (mpz_get_ui): Use ?: instead of mask style, gcc treats the
+ two identically but ?: is a bit clearer.
+
+ * insert-dbl.c: Remove file, no longer used, scaling is now integrated
+ in mpn_get_d.
+ * Makefile.am (libgmp_la_SOURCES): Remove insert-dbl.c.
+ * gmp-impl.h (__gmp_scale2): Remove prototype.
+
+2004-03-17 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/fat/fat.c (__gmpn_cpuvec_init, fake_cpuid_table): Add x86_64.
+
+ * mpq/get_d.c: Use mpn_tdiv_qr, demand den>0 per canonical form.
+
+2004-03-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/sqr_basecase.c: Add versions using mpn_addmul_2 and
+ mpn_addmul_2s.
+
+2004-03-14 Kevin Ryde <kevin@swox.se>
+
+ * mpf/mul_ui.c: Incorporate carry from low limbs, for exactness.
+ * tests/mpf/t-mul_ui.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpf/div.c: Use mpn_tdiv_qr. Use just one TMP_ALLOC. Use full
+ divisor, since truncating can lose accuracy.
+ * tests/mpf/t-div.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+
+ * tests/mpf/t-set_q.c, tests/mpf/t-ui_div.c (check_various): Amend
+ bogus 99/4 test.
+ * tests/mpf/t-ui_div.c (check_rand): Exercise r==v overlap.
+
+ * tests/refmpf.c, tests/tests.h (refmpf_set_overlap): New function.
+
+ * mpf/cmp_si.c [nails]: Correction, cast vval in exp comparisons, for
+ when vval=-0x800..00 and limb==longlong.
+
+ * mpf/cmp_si.c [nails]: Correction, return usign instead of 1 when
+ uexp==2 but value bigger than an mp_limb_t.
+ * tests/mpf/t-cmp_si.c (check_data): Add test cases.
+
+ * tests/trace.c (mpf_trace): Use ABS(mp_trace_base) to allow for
+ negative bases used for upper case hex in integer traces.
+
+2004-03-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/sb_divrem_mn.c: Correct header comment.
+
+2004-03-11 Kevin Ryde <kevin@swox.se>
+
+ * aclocal.m4, configure, ltmain.sh: Downgrade to libtool 1.5, version
+ 1.5.2 doesn't remove .libs/*.a files when rebuilding, which is bad for
+ development when changing contents or with duplicate named files like
+ we have.
+
+ Revert this, ie restore AR_FLAGS=cq:
+ * acinclude.m4 (GMP_PROG_AR): Remove AR_FLAGS=cq, libtool 1.5.2 now
+ does this itself on detecting duplicate object filenames in piecewise
+ linking mode.
+
+ * randbui.c, randmui.c [longlong+nails]: Correction to conditionals
+ for second limb.
+
+ * mpz/aors_ui.h, mpz/cdiv_q_ui.c, mpz/cdiv_qr_ui.c, mpz/cdiv_r_ui.c,
+ mpz/cdiv_ui.c, mpz/fdiv_q_ui.c, mpz/fdiv_qr_ui.c, mpz/fdiv_r_ui.c,
+ mpz/fdiv_ui.c, mpz/gcd_ui.c, mpz/iset_ui.c, mpz/lcm_ui.c,
+ mpz/set_ui.c, mpz/tdiv_q_ui.c, mpz/tdiv_qr_ui.c, mpz/tdiv_r_ui.c,
+ mpz/tdiv_ui.c, mpz/ui_sub.c, mpf/div_ui.c, mpf/mul_ui.c
+ [longlong+nails]: Amend #if to avoid warnings about shift amount.
+
+2004-03-07 Kevin Ryde <kevin@swox.se>
+
+ * mpf/reldiff.c: Use rprec+ysize limbs for d, to ensure accurate
+ result. Inline mpf_abs(d,d) and mpf_cmp_ui(x,0), and rate the latter
+ UNLIKELY.
+
+ * mpf/ui_div.c: Use mpn_tdiv_qr. Use just one TMP_ALLOC. Use full
+ divisor, since truncating can lose accuracy.
+ * tests/mpf/t-ui_div.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpf/set_q.c: Expand TMP_ALLOC_LIMBS_2, to make conditional clearer
+ and avoid 1 limb alloc when not wanted.
+
+ * gmp-impl.h (WANT_TMP_DEBUG): Define to 0 if not defined.
+ (TMP_ALLOC_LIMBS_2): Use "if" within macro rather than "#if", for less
+ preprocessor conditionals.
+
+ * mpf/mul_2exp.c, mpf/div_2exp.c: Add some comments.
+
+ * tests/refmpn.c (refmpn_sb_divrem_mn, refmpn_tdiv_qr): Nailify.
+
+2004-03-04 Kevin Ryde <kevin@swox.se>
+
+ * gen-psqr.c (print): Add CNST_LIMB in PERFSQR_MOD_TEST, for benefit
+ of K&R.
+ * tests/mpn/t-perfsqr.c (PERFSQR_MOD_1): Use CNST_LIMB for K&R.
+
+ * doc/configuration (Configure): Remove mkinstalldirs, no longer used.
+
+ * acinclude.m4 (GMP_PROG_AR): Remove AR_FLAGS=cq, libtool 1.5.2 now
+ does this itself on detecting duplicate object filenames in piecewise
+ linking mode.
+
+ * configure.in (hppa2.0*-*-*): Test sizeof(long) == 4 or 8 to verify
+ ABI=2.0n versus ABI=2.0w. In particular this lets CC=cc_bundled
+ correctly fall back to ABI=2.0n (we don't automatically add CC=+DD64
+ to that compiler, currently).
+
+ * doc/gmp.texi (Reentrancy): Note C++ mpf_class constructors using
+ global default precision.
+ (Random State Miscellaneous): Describe gmp_urandomb_ui as giving N
+ bits.
+ (C++ Interface Floats): Describe operator= copying the value, not the
+ precision, and what this can mean about copy constructor versus
+ default constructor plus assignment.
+
+ * mpf/set_q.c: Use mpn_tdiv_qr rather than mpn_divrem, so no shifting.
+ Don't truncate the divisor, it can make the result inaccurate.
+ * tests/mpf/t-set_q.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpf/set.c: Use MPN_COPY_INCR, in case r==u and ABSIZ(u) > PREC(r)+1.
+ No actual bug here, because MPN_COPY has thusfar been an alias for
+ MPN_COPY_INCR, only an ASSERT failure.
+ * tests/mpf/t-set.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpf/set.c, mpf/iset.c: Do MPN_COPY last, for possible tail call.
+
+ * mpf/set_d.c: Rate d==0 as UNLIKELY. Store size before extract call,
+ to shorten lifespan of "negative".
+
+ * mpf/init.c, mpf/init2.c, mpf/iset_d.c, mpf/iset_si.c,
+ mpf/iset_str.c, mpf/iset_ui.c: Store prec before alloc call, for one
+ less live quantity across that call.
+ * mpf/init.c, mpf/init2.c, mpf/iset_str.c: Store size and exp before
+ alloc call, to overlap with other operations.
+
+ * tests/refmpf.c, tests/tests.h (refmpf_fill, refmpf_normalize,
+ refmpf_validate, refmpf_validate_division): New functions.
+
+ * tests/refmpn.c, tests/tests.h (refmpn_copy_extend,
+ refmpn_lshift_or_copy_any, refmpn_rshift_or_copy_any): New functions.
+
+ * tal-debug.c: Add <string.h> for strcmp.
+
+ * tests/cxx/t-istream.cc (check_mpz, check_mpq, check_mpf): Use size_t
+ for loop index, to quieten g++ warning.
+
+2004-03-02 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpn/t-hgcd.c: Use __GMP_PROTO on prototypes.
+
+2004-03-01 Torbjorn Granlund <tege@swox.com>
+
+ With Karl Hasselström:
+ * mpn/generic/dc_divrem_n.c (mpn_dc_div_2_by_1): New function, with
+ meat from old mpn_dc_divrem_n. Accept scratch parameter. Rewrite to
+ avoid a recursive call.
+ (mpn_dc_div_3_by_2): New function, with meat from old
+ mpn_dc_div_3_halves_by_2. Accept scratch parameter.
+ (mpn_dc_divrem_n): Now just allocate scratch space and call new
+ mpn_dc_div_2_by_1.
+
+2004-02-29 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h (count_leading_zeros) [alpha gcc]: New version, inlining
+ mpn/alpha/cntlz.asm cmpbge technique.
+
+ * aclocal.m4, configure, install-sh, missing, ltmain.sh,
+ */Makefile.in: Update to automake 1.8.2 and libtool 1.5.2.
+
+ * doc/gmp.texi (C++ Interface Integers): Note / and % rounding follows
+ C99 / and %.
+ (Exact Remainder): Index entries for divisibility testing algorithm.
+
+ * tune/time.c (speed_endtime): Return 0.0 for negative time measured.
+ Revise usage comments for clarity.
+ * tune/common.c (speed_measure): Recognise speed_endtime 0.0 for
+ failed measurement.
+
+ * tests/mpn/t-get_d.c (check_rand): Correction to nhigh_mask setup.
+
+2004-02-27 Torbjorn Granlund <tege@swox.com>
+
+ * tune/tuneup.c (tune_dc, tune_set_str): Up param.step_factor.
+
+ * tests/mpz/t-gcd.c: Decrease # of tests to 50.
+
+2004-02-27 Kevin Ryde <kevin@swox.se>
+
+ * tests/devel/try.c: Add a comment that this is not for Cray systems.
+
+ * mpf/set_q.c: Don't support den(q)<0, demand canonical form in the
+ usual way.
+
+2004-02-24 Torbjorn Granlund <tege@swox.com>
+
+ From Kevin:
+ * mpn/generic/mul_fft.c (mpn_fft_add_modF): Loop until normalization
+ criterion met.
+
+2004-02-22 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS, GMP_OS_X86_XMM, GMP_PROG_CXX_WORKS):
+ Remove files that might look like compiler output, so our "||"
+ alternatives are not fooled.
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Add test for lshift_com code
+ mis-compiled by certain IA-64 HP cc at +O3.
+
+ * gmp-impl.h (USE_LEADING_REGPARM): Disable under prof or gprof, for
+ the benefit of freebsd where .mcount clobbers registers. Spotted by
+ Torbjorn.
+ * configure.in (WANT_PROFILING_PROF, WANT_PROFILING_GPROF): New
+ AC_DEFINEs.
+
+2004-02-21 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (sparc64-*-*bsd*): Amend -m32 setup for ABI=32, so it's
+ not used in ABI=64 on the BSD systems.
+
+2004-02-18 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-gcd.c (gcdext_valid_p): New function.
+ (ref_mpz_gcd): Deleted function.
+ (one_test): Rearranged to call mpz_gcdext first, so that the
+ returned value can be validated.
+ (main): Don't use ref_mpz_gcd.
+
+2004-02-18 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (MPN_TOOM3_MAX_N): Move to !WANT_FFT section.
+
+ * tests/mpz/t-mul.c: Exclude special huge operands unless WANT_FFT.
+
+ * mpz/rrandomb.c (gmp_rrandomb): Rewrite.
+
+ * mpn/generic/mul_n.c (mpn_toom3_sqr_n): Remove write-only variable c5.
+
+2004-02-18 Kevin Ryde <kevin@swox.se>
+
+ * mpf/iset_si.c, mpf/iset_ui.c, mpf/set_si.c, mpf/set_ui.c [nails]:
+ Always store second limb, to avoid a conditional.
+
+ * tests/mpf/t-get_ui.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+ * tests/mpf/t-get_si.c (check_limbdata): Further tests.
+ * gmp-impl.h (MP_EXP_T_MAX, MP_EXP_T_MIN): New defines.
+
+ * mpf/get_ui.c, mpf/get_si.c: Remove size==0 test, it's covered by
+ other conditions. Attempt greater clarity by expressing conditions as
+ based on available data range.
+ * mpf/get_si.c [nails]: Correction, don't bail on exp > abs_size,
+ since may still have second limb above radix point available.
+ * mpf/get_ui.c: Nailify.
+
+2004-02-16 Kevin Ryde <kevin@swox.se>
+
+ * mpz/scan0.c, mpz/scan1.c: Use count_trailing_zeros, instead of
+ count_leading_zeros on limb&-limb.
+
+ * mpf/sqrt.c: Use "/ 2" for exp, avoiding C undefined behaviour on
+ ">>" of negatives. Correction to comment, exp is rounded upwards.
+ SIZ(r) always prec now, no need for tsize expression. Store EXP(r)
+ and SIZ(r) where calculated to reduce variable lifespans. Make tsize
+ mp_size_t not mp_exp_t, though of course those are currently the same.
+
+ * gmp-h.in (GMP_ERROR_ALLOCATE, GMP_ERROR_BAD_STRING,
+ GMP_ERROR_UNUSED_ERROR): Remove, never used or documented, and we
+ don't want to use globals for communicating error information.
+
+ * mpz/gcd_ui.c [nails]: Correction, actually return a value.
+
+ * mpn/generic/addmul_1.c, mpn/generic/submul_1.c [nails==1]: Add code.
+
+2004-02-15 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpz/t-jac.c (check_data): Remove unnecessary variable
+ "answer".
+
+2004-02-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/aors_n.asm: Break a group with a RAW conflict.
+
+2004-02-14 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_C_RIGHT_SHIFT): Note that it's "long"s which we're
+ concerned about.
+
+ * mpn/generic/mul_n.c: Add some remarks about toom3 high zero
+ stripping.
+
+ * mpn/generic/scan0.c, mpn/generic/scan1.c: Remove design issue
+ remarks. What to do about going outside `up' space is a problem, but
+ anything to address it would be an incompatible change.
+
+2004-02-12 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpn/t-hgcd.c: Remove unused variables.
+
+ * mpn/ia64/hamdist.asm: Remove bundling incompatible with HP-UX
+ assembler. Misc HP-UX changes.
+ * mpn/ia64/gcd_1.asm: Add some syntax to placid the HP-UX assembler.
+
+2004-02-11 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h (power, powerpc): Use HAVE_HOST_CPU_FAMILY_power and
+ HAVE_HOST_CPU_FAMILY_powerpc rather than various cpp defines.
+
+ * gmp-impl.h: Add remarks about limits.h and Cray etc.
+
+ * mpn/ia64/mul_1.asm: Don't put .pred directives on labelled lines,
+ hpux 11.23 assembler doesn't like that.
+ * mpn/ia64/README: Add a note on this.
+
+ * dumbmp.c (mpz_mul): Set ALLOC(r) for new data block used. Reported
+ by Jason Moxham.
+
+ * mpn/pa32/README, mpn/pa64/README (REFERENCES): New sections.
+
+2004-02-10 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-gcd.c: Decrease # of tests run.
+
+ * mpn/*/gmp-mparam.h: Add HGCD values, update TOOM values.
+
+2004-02-01 Torbjorn Granlund <tege@swox.com>
+
+ From Kevin:
+ * config.guess: Recognize AMD's hammer processors, return x86_64.
+
+2004-01-31 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (mpn_cmp_sum3): Declare static.
+
+2004-01-25 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add t-hgcd.
+
+ * mpn/generic/hgcd.c (hgcd_jebelean): Simplify, use mpn_cmp_sum3.
+ (mpn_cmp_sum3): New function.
+ (mpn_diff_smaller_p): Remove.
+ (hgcd_final, hgcd_jebelean, hgcd_small_1, hgcd_small_2, euclid_step):
+ Remove tp,talloc arguments. Callers changed.
+
+2004-01-25 Torbjorn Granlund <tege@swox.com>
+
+ * tune/tuneup.c (all): Reenable calls of tune_gcd_schoenhage and
+ tune_hgcd.
+
+ * mpn/generic/gcd.c: Reenable Schoenhage code.
+
+ With Niels Möller:
+ * mpn/generic/hgcd.c: Add const and inline to several functions.
+ (qstack_push_start qstack_push_end qstack_push_quotient): Remove.
+ (euclid_step): Insert removed functions here.
+ (hgcd_adjust): Simplify, don't handle d != 1.
+ (qstack_adjust): Corresponding changes.
+ (mpn_hgcd2_lehmer_step): Remove redundant tests for bh against zero.
+ (hgcd_start_row_p): Tweak.
+ (hgcd_final): Shorten life of ralloc.
+
+2004-01-24 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpf/t-sqrt.c (check_rand1): Further diagnostic printouts.
+
+ * mpn/generic/sqrtrem.c (mpn_sqrtrem): Add ASSERT_MPN.
+ (mpn_dc_sqrtrem): Add casts for K&R.
+
+ * mpf/sqrt_ui.c: Nailify.
+
+ * mpf/set_z.c: Do MPN_COPY last, for possible tail call.
+
+ * doc/gmp.texi (Miscellaneous Float Functions): For mpf_random2, note
+ exponent is in limbs.
+
+ * mpn/ia64/README: Add remark about concentrating on itanium-2.
+
+2004-01-22 Kevin Ryde <kevin@swox.se>
+
+ * mpf/sqrt.c: Change tsize calculation to get prec limbs result
+ always, previously got prec+1 when exp was odd.
+ * tests/mpf/t-sqrt.c (check_rand1): New function, code from main.
+ (check_rand2): New function.
+
+ * mpf/sqrt_ui.c: Change rsize calculation to get prec limbs result,
+ previously got prec+1.
+ * tests/mpf/t-sqrt_ui.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+
+ * tests/refmpf.c, tests/tests.h (refmpf_add_ulp,
+ refmpf_set_prec_limbs): New functions.
+
+ * mpz/get_d_2exp.c, mpf/get_d_2exp.c: Remove x86+m68k force to double,
+ mpn_get_d now does this. Remove res==1.0 check for round upwards,
+ mpn_get_d now rounds towards zero. Move exp store to make mpn_get_d a
+ tail call.
+
+ * configure.in (x86-*-*): Use ABI=32 rather than ABI=standard.
+ Use gcc -m32 when available, to force mode on bi-arch amd64 gcc.
+ * configure.in, acinclude.m4 (x86_64-*-*): Merge into plain x86 setups
+ as ABI=64. Support ABI=32, using athlon code. Use gcc -mcpu=k8,
+ -march=k8.
+ (amd64-*-*): Remove pattern, config.sub only gives x86_64.
+ * doc/gmp.texi (ABI and ISA): Add x86_64 dual ABIs.
+
+ * mpn/amd64/README: Add reference to ABI spec.
+
+2004-01-17 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (hgcd_adjust): Backed out mpn_addlsh1_n
+ change for now.
+
+ * mpn/generic/hgcd.c (hgcd_adjust): Fixed calls of mpn_addlsh1_n.
+
+2004-01-17 Kevin Ryde <kevin@swox.se>
+
+ * tune/README: Remove open/mpn versions of toom3, no longer exist.
+ * tune/powerpc64.asm: Remove unused L(again).
+ * tune/time.c (mftb): Note single mftb possible for powerpc64.
+
+ * mpn/generic/mode1o.c: Use "c<s" to do underflow detection in last
+ step, for better parallelism.
+
+ * mpn/generic/get_d.c: Preserve comments about hppa fcnv,udw,dbl from
+ previous mpz_get_d code.
+
+ * tune/freq.c: Add some comments about systems not covered.
+
+ * gmp-h.in (_GMP_H_HAVE_FILE): Add _MSL_STDIO_H for Metrowerks.
+ Reported by Tomas Zahradnicky.
+
+2004-01-16 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (mpn_diff_smaller_p): Use MPN_DECR_U.
+ (hgcd_adjust): Use mpn_addlsh1_n when available.
+
+2004-01-16 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (powerpc64-*-linux*): Try gcc64. Try -m64 with
+ "cflags_maybe" to get it used in all probing. Add sizeof-long-8 test
+ to check the mode is right if -m64 is not applicable.
+
+2004-01-15 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (--with-readline=detect): Check for readline/readline.h
+ and readline/history.h. Report result of detection.
+
+2004-01-14 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/speed.c (routine): Disabled speed_mpn_hgcd_lehmer.
+ * tune/common.c (speed_mpn_hgcd_lehmer): Disabled function.
+
+ * mpn/generic/hgcd.c (mpn_hgcd_lehmer_itch, mpn_hgcd_lehmer)
+ (mpn_hgcd_equal): Deleted functions.
+
+ * mpn/generic/gcd.c (hgcd_start_row_p): Deleted function.
+ (gcd_schoenhage): Deleted assertion code using mpn_hgcd_lehmer.
+
+ * mpn/generic/hgcd.c (hgcd_final): Fixed ASSERT typos.
+ (mpn_hgcd): To use Lehmer's algorithm, call hgcd_final directly,
+ not mpn_hgcd_lehmer.
+
+ * mpn/generic/gcd.c (gcd_schoenhage): Updated for changes to
+ mpn_hgcd and mpn_hgcd_fix. (Schoenhage code is still disabled).
+
+ * gmp-impl.h (mpn_hgcd_fix): Updated prototype.
+
+ * mpn/generic/hgcd.c (mpn_hgcd_fix): Replaced a bunch of arguments
+ by a pointer const struct hgcd_row *s. Updated callers.
+
+ * mpn/generic/hgcd.c (hgcd_start_row_p): Use const for the input.
+ Moved function definition before hgcd_jebelean.
+ (hgcd_jebelean): Interface change, analogous to hgcd2.
+ (mpn_hgcd_fix): Normalize v. Require that v > 0.
+ (hgcd_adjust): Fix bug in carry update.
+ (mpn_hgcd): Reorganized again, to adapt to mpn_hgcd/hgcd_jebelean
+ now sometimes returning 1. Reintroduced hgcd_adjust.
+
+ * mpn/generic/hgcd.c (hgcd_final): Streamlined logic for the first
+ hgcd2 call.
+
+ * mpn/generic/hgcd2.c (mpn_hgcd2): Interface change. Return 1
+ instead of 2, in the no progress case r0=A, r1=B.
+
+ * mpn/generic/hgcd.c (hgcd_adjust): Changed arguments and return
+ value. Now takes a struct hgcd_row * and the uv size, and returns
+ updated uvsize.
+ (hgcd_final): Special handling of the case hgcd2 returning 1. Now
+ uses hgcd_adjust, instead of a full Euclid division.
+
+2004-01-13 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (euclid_step, hgcd_case0): Merged into a
+ single function euclid_step.
+ (mpn_hgcd): Reorganized the logic for the second recursive call.
+ Avoid unnecessary Euclid steps.
+
+ * tests/mpn/t-hgcd.c (hgcd_values): One more test value.
+
+ * tests/mpn/t-hgcd.c (hgcd_values): Added values that trigged the
+ hgcd_jebelean bug.
+
+ * mpn/generic/hgcd.c (hgcd_jebelean): Fixed off by one error.
+ (mpn_hgcd): Simplified the logic for the first recursive call. Now
+ it uses only the correct values from the recursive call, and
+ doesn't do tricks with hgcd_adjust (hgcd_adjust will probably be
+ reintroduced later, though).
+
+ * tests/mpn/t-hgcd.c (mpz_mpn_equal, hgcd_ref_equal)
+ (hgcd_ref_init, hgcd_ref_clear): New functions.
+ (hgcd_ref): Reference implementation of hgcd, using mpz.
+ (one_test): Use hgcd_ref. Don't use mpn_hgcd_lehmer.
+ (main): Skip one_step if both input values are zero.
+
+2004-01-12 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (hgcd_final): Rewritten, now uses Lehmer
+ steps instead of a division loop.
+ (mpn_hgcd_lehmer): Deleted old Lehmer code, instead just
+ initialize and then call hgcd_final.
+
+ * tests/tests.h: Added refmpn_free_limbs prototype.
+ * tests/refmpn.c (refmpn_free_limbs): New function.
+
+ * tests/mpn/t-hgcd.c: Try the same kind of random inputs as for
+ mpz/t-gcd.
+
+2004-01-11 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (mpn_hgcd_lehmer): Rewritten, after some more
+ analysis of the size reduction for one Lehmer step.
+
+ * tests/mpn/t-hgcd.c: New file.
+
+2004-01-11 Torbjorn Granlund <tege@swox.com>
+
+ With Niels Möller:
+ * mpn/generic/hgcd.c (hgcd_normalize): Fix ASSERTs.
+ (hgcd_mul): Normalize R[1].uvp[1]. Add some more ASSERTs.
+ (hgcd_update_uv): Streamline. ASSERT that input and output is
+ normalized.
+
+2004-01-11 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/ev6/slot.pl: New file, derived in part from
+ mpn/x86/k6/cross.pl.
+
+ * mpn/alpha/alpha-defs.m4 (ASSERT): New macro.
+
+ * mpn/asm-defs.m4 (m4_ifdef): New macro, avoiding OSF 4.0 m4 bug.
+ (m4_assert_defined): Use it.
+
+ * mpn/alpha/default.m4, mpn/alpha/unicos.m4 (LDGP): New macro.
+ * mpn/alpha/ev67/gcd_1.asm: Use it to re-establish gp after jsr.
+
+ * configure.in, demos/calc/Makefile.am: Use -lcurses or -lncurses with
+ readline, when available.
+
+ * longlong.h (sub_ddmmss) [generic]: Use al<bl for the borrow rather
+ than __x>al, since the former can be done without waiting for __x,
+ helping superscalar chips, in particular alpha ev5 and ev6.
+
+ * longlong.h (sub_ddmmss) [ia64]: New macro.
+
+ * tests/t-sub.c: New file.
+ * tests/Makefile.am (check_PROGRAMS): Add it.
+ * tests/refmpn.c, tests/tests.h (refmpn_sub_ddmmss): New function.
+
+2004-01-09 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/p6/mod_34lsub1.asm: New file, derived in part from
+ mpn/x86/mod_34lsub1.asm.
+
+ * configure.in (IA64_PATTERN): Use -mtune on gcc 3.4.
+
+2004-01-07 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in, mp-h.in (__GMP_SHORT_LIMB): Renamed from _SHORT_LIMB, to
+ keep in our namespace. (Not actually used anywhere currently.)
+ Reported by Patrick Pelissier.
+
+ * mp-h.in: Use "! defined (__GMP_WITHIN_CONFIGURE)" in the same style
+ as gmp-h.in (though mp-h.in is not actually used during configure).
+
+ * mp-h.in (__GMP_DECLSPEC_EXPORT, __GMP_DECLSPEC_IMPORT) [__GNUC__]:
+ Use __dllexport__ and __dllimport__ to keep out of application
+ namespace. Same previously done in gmp-h.in.
+
+2004-01-06 Kevin Ryde <kevin@swox.se>
+
+ * configfsf.sub, configfsf.guess: Update to 2004-01-05.
+ * configure.in (amd64-*-* | x86_64-*-*): Update comments on what
+ configfsf.sub does.
+
+2004-01-04 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/README (REFERENCES): Add tru64 assembly manuals.
+ (ASSEMBLY RULES): Note what gcc says about !literal! etc.
+
+2004-01-03 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/ev67/gcd_1.asm: New file.
+
+ * mpn/x86/pentium4/sse2/rsh1add_n.asm: New file, derived in part from
+ mpn/x86/pentium4/sse2/addlsh1_n.asm.
+
+ * mpn/x86/p6/p3mmx/popham.asm: Note measured speeds.
+
+ * mpn/ia64/hamdist.asm: Correction to inputs vs locals in alloc (makes
+ no difference to the generated code). Corrections to a couple of
+ comments.
+
+ * mpn/x86/pentium4/sse2/addlsh1_n.asm (PARAM_CARRY): Remove macro, not
+ used, no such parameter.
+
+ * mpn/generic/gcd.c: Use <stdio.h> for NULL.
+
+ * doc/gmp.texi (Single Limb Division): Correction to tex expression
+ for (1/2)x1. And minor wording tweaks elsewhere.
+
+ * gmp-impl.h (mpn_rsh1add_n, mpn_rsh1sub_n): Correction to comments
+ about how carries returned.
+
+ * longlong.h (umul_ppmm) [generic]: Add comments about squaring
+ (dropped from tasks list)
+
+2003-12-31 Kevin Ryde <kevin@swox.se>
+
+ * demos/perl/GMP.xs (scan0, scan1): Return ~0 for not-found.
+ * demos/perl/GMP.pm: Describe this, remove the note about ULONG_MAX
+ being the same as ~0 (which is not true in old perl).
+ * demos/perl/test.pl: Update tests.
+ * demos/perl/typemap (gmp_UV): New type.
+
+ * demos/perl/test.pl (fits_slong_p): Comment out uv_max test, it won't
+ necessarily exceed a long.
+
+ * demos/perl/GMP.pm: Add a remark about get_str to the bugs section.
+
+ * mpn/generic/sqrtrem.c, mpz/fac_ui.c, tests/mpf/reuse.c: Add casts
+ for K&R.
+ * tests/mpf/t-muldiv.c: Make ulimb, vlimb into ulongs, which is how
+ they're used, for the benefit of K&R calling.
+
+ * doc/gmp.texi (Square Root Algorithm): Add a summary of the algorithm.
+ And add further index entries in various places.
+
+ * mpz/lucnum_ui.c, mpz/lucnum2_ui.c: Use mpn_addlsh1_n when available.
+
+ * gmp-impl.h, mpn/generic/mul_n.c (mpn_addlsh1_n, mpn_sublsh1_n,
+ mpn_rsh1add_n, mpn_rsh1sub_n): Move descriptions to gmp-impl.h with
+ the prototypes, for ease of locating.
+
+2003-12-30 Torbjorn Granlund <tege@swox.com>
+
+ * tune/tuneup.c (all): Disable calls of tune_gcd_schoenhage and
+ tune_hgcd for now.
+
+2003-12-29 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-gcd.c: Rewrite, based on suggestions by Kevin.
+
+ * mpn/ia64/mul_1.asm: Amend TODO list.
+
+ * mpn/sparc64/README: Remove mpn_Xmul_2, done.
+ Add blurb about L1 cache conflicts.
+
+ * mpn/generic/gcd.c: Disable Schoenhage code for now.
+
+2003-12-29 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/mul_fft.c, mpz/root.c, mpq/cmp_ui.c: Add casts for K&R.
+
+2003-12-27 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpz/t-mul.c (mul_kara, mul_basecase): Use __GMP_PROTO.
+
+ * mpn/generic/gcd.c (NHGCD_SWAP4_2, NHGCD_SWAP3_LEFT),
+ mpn/generic/hgcd.c (HGCD_SWAP4_LEFT, HGCD_SWAP4_RIGHT, HGCD_SWAP4_2,
+ HGCD_SWAP3_LEFT): Aggregate initializers for automatics is an
+ ANSI-ism, avoid.
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Restore this, giving no directory on
+ ansi2knr to avoid a circular build rule.
+ * configure.in (AM_INIT_AUTOMAKE): Note options also in Makefile.am.
+
+ * configure.in (cflags_maybe): Don't loop adding cflags_maybe if the
+ user has set CFLAGS.
+
+2003-12-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/gcd.c (gcd_schoenhage_itch): Avoid unary "+".
+ (mpn_gcd): Allocate scratch space on heap for gcd_schoenhage.
+ (mpn_gcd): Don't invoke MPN_NORMALIZE on input operands.
+
+2003-12-23 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (*sparc*-*-*): Test sizeof(long)==4 or 8 for ABIs, to
+ get the right mode when the user sets the CFLAGS.
+ (testlist): Introduce "any_<abi>_testlist" to apply to all compilers.
+
+ * demos/perl/typemap (MPZ_ASSUME, MPQ_ASSUME, MPF_ASSUME): Remove
+ output rules, these are only meant for inputs.
+ (MPZ_MUTATE): Remove, not used since changes for magic.
+
+ * demos/perl/GMP.xs (mpz_class_hv, mpq_class_hv, mpf_class_hv): New
+ variables, initialized in BOOT.
+ * demos/perl/GMP.xs, demos/perl/typemap: Use them and explicit
+ sv_bless, to save a gv_stashpv for every new object.
+
+2003-12-22 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/mode1o.c, mpn/alpha/dive_1.c: Moved from ev5/mode1o.c and
+ ev5/dive_1.c, these are good for ev4, and would like them in a generic
+ alpha build.
+
+2003-12-21 Kevin Ryde <kevin@swox.se>
+
+ * doc/gmp.texi (Integer Logic and Bit Fiddling): Say "bitwise" in
+ mpz_and, mpz_ior and mpz_xor, to avoid any confusion with what C means
+ by "logical". Reported by Rüdiger Schütz.
+
+ * gmp-h.in (_GMP_H_HAVE_FILE): Note why defined(EOF) is not good.
+
+2003-12-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/hgcd.c (mpn_diff_smaller_p): Use mpn_cmp instead of
+ mpn_sub_n where possible. Use mp_size_t for relevant variables.
+
+2003-12-20 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.h (SPEED_TMP_ALLOC_LIMBS): Correction to last change,
+ don't want "- 1" on the TMP_ALLOC_LIMBS.
+
+ * demos/expr/expr.h: Test #ifdef MPFR_VERSION_MAJOR for when mpfr.h is
+ included, not GMP_RNDZ which is now an enum.
+
+ * demos/expr/exprfra.c (e_mpfr_ulong_p): Use mpfr_integer_p and
+ mpfr_fits_ulong_p.
+ (e_mpfr_get_ui_fits): Use mpfr_get_ui.
+
+ * mpfr/*: Update to mpfr cvs head 2003-12-20.
+
+ * configure, config.in: Update to autoconf 2.59.
+ * */Makefile.in, configure, aclocal.m4, ansi2knr.c, install-sh,
+ doc/mdate-sh: Update to automake 1.8.
+
+ * mkinstalldirs: Remove, not required by automake 1.8.
+ * doc/gmp.texi (Build Options): HTML is a usual target in automake 1.8.
+
+ * configure.in (AC_PREREQ): Require autoconf 2.59.
+ (AM_INIT_AUTOMAKE): Require automake 1.8.
+ (AC_C_INLINE): Use rather than GMP_C_INLINE, now has #ifndef
+ __cplusplus we want.
+ (gettimeofday): Use AC_CHECK_FUNCS rather than our workaround code,
+ autoconf now ok.
+
+ * acinclude.m4 (GMP_C_INLINE): Remove.
+ (GMP_H_EXTERN_INLINE): Use AC_C_INLINE.
+ (GMP_PROG_AR): Comment on automake $ARFLAGS.
+
+2003-12-19 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (mpn_diff_smaller_p): Rewrote function. Tried
+ to explain how it works.
+ (slow_diff_smaller_p, wrap_mpn_diff_smaller_p) [WANT_ASSERT]: Use
+ CPP to wrap assertion checks around all calls to
+ mpn_diff_smaller_p.
+
+ * mpn/generic/hgcd.c (mpn_addmul2_n_1) [nails]: Fixed carry handling.
+
+ * mpn/generic/hgcd.c (mpn_diff_smaller_p) [nails]: Use
+ GMP_NUMB_MAX, not MP_LIMB_T_MAX.
+ (mpn_hgcd_itch): Improved size calculation.
+ (mpn_hgcd_max_recursion): Moved function from qstack.c. Should to
+ be recompiled when HGCD_SCHOENHAGE_THRESHOLD is tuned.
+
+ * mpn/generic/qstack.c (mpn_hgcd_max_recursion): ... moved from
+ here.
+
+2003-12-19 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpf/t-get_d.c: Print message before aborting.
+
+ * mpn/generic/hgcd2.c (mpn_hgcd2): Substitute always-zero variable
+ with 0. Remove bogus comment.
+
+ * mpn/generic/get_d.c: Make ONE_LIMB case actually work for nails.
+
+2003-12-18 Niels Möller <niels@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (hgcd_update_r): Assert that the output r2 is
+ smaller than the input r1.
+
+2003-12-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/get_d.c: Don't include longlong.h.
+
+ * tests/mpz/t-mul.c (ref_mpn_mul): Handle un == vn specially, to avoid
+ a dummy r/w outside of allocated area.
+
+2003-12-18 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/unicos.m4 (ALIGN): Add comments on what GCC does.
+
+ * configure.in (fat setups), acinclude.m4 (GMP_INIT): Obscure
+ include() from automake 1.8 aclocal.
+ * acinclude.m4: Quote names in AC_DEFUN, for automake 1.8 aclocal.
+
+2003-12-17 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/common.c (speed_mpn_hgcd, speed_mpn_hgcd_lehmer) [nails]:
+ Enabled code also for GMP_NAIL_BITS > 0.
+ * tune/speed.c [nails]: Enable speed_mpn_hgcd and
+ speed_mpn_hgcd_lehmer.
+ * tune/tuneup.c (tune_hgcd) [nails]: Likewise.
+
+ * mpn/generic/gcd.c [nails]: Use Schönhage's algorithm also for
+ GMP_NAIL_BITS > 0.
+
+ * mpn/generic/hgcd.c [nails]: Enable the code for GMP_NAIL_BITS > 0.
+ (MPN_EXTRACT_LIMB) [nails]: Handle nails.
+ (__gmpn_hgcd_sanity): Allocate temporaries on the heap, not on the
+ stack. Also check that r[i] >= r[i+1].
+ (mpn_hgcd2_lehmer_step) [nails]: Handle nails.
+ (mpn_hgcd_lehmer): When we temporarily have r3 > r2, avoid
+ trigging that assert in __gmpn_hgcd_sanity.
+ (mpn_hgcd): Likewise.
+
+ * mpn/generic/hgcd2.c (div2) [nails]: Alternative nail-aware
+ version.
+ (SUB_2): New macro of Kevin's, which reduces do sub_ddmmss in the
+ non-nail case.
+ (HGCD2_STEP): Use SUB_2, not sub_ddmmss. Added alternative version
+ for K&R compilers.
+ (mpn_hgcd2) [nails]: Use SUB_2, not sub_ddmmss. New nail-aware
+ code for checking Jebelean's condition.
+
+2003-12-13 Kevin Ryde <kevin@swox.se>
+
+ * mpq/get_d.c: Amend comments per mpn_get_d change.
+ (limb2dbl): Remove, no longer used.
+
+ * gmp-impl.h (DIVREM_1_NORM_THRESHOLD etc) [nails]: Correction to
+ comments, MP_SIZE_T_MAX means preinv never.
+
+ * gmp-impl.h (DIVEXACT_1_THRESHOLD, MODEXACT_1_ODD_THRESHOLD) [nails]:
+ Remove overrides, divexact_1 and modexact_1 have been nailified.
+
+ * mpz/inp_str.c (mpz_inp_str_nowhite): Use ASSERT_ALWAYS for EOF value
+ requirement.
+
+ * tests/refmpn.c (refmpn_rsh1add_n, refmpn_rsh1sub_n): Parens around
+ GMP_NUMB_BITS - 1 with ">>", to quieten gcc -Wall.
+ * tests/t-constants.c (main), tests/t-count_zeros.c (check_clz),
+ tests/t-modlinv.c (one), tests/mpz/t-jac.c (try_si_zi),
+ tests/mpq/t-get_d.c (check_onebit): : Correction to printfs.
+ * tests/mpn/t-fat.c: Add <string.h> for memcpy.
+ * tests/mpz/t-scan.c (check_ref): Remove unused variable "isigned".
+ * tests/mpq/t-get_d.c (check_onebit): Remove unused variable "limit".
+ * tests/mpf/t-set_si.c, tests/mpf/t-set_ui.c (check_data): Braces for
+ initializers.
+ * tests/devel/try.c (mpn_divexact_by3_fun, mpn_modexact_1_odd_fun):
+ Correction to return values.
+
+ * doc/gmp.texi (Miscellaneous Integer Functions): Note mpz_sizeinbase
+ can be used to locate the most significant bit. Reword a bit for
+ clarity.
+
+2003-12-12 Niels Möller <niels@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (__gmpn_hgcd_sanity): Fixed stack buffer
+ overrun.
+ * mpn/generic/hgcd.c: Improved comments.
+
+2003-12-11 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h: Change asm => __asm__, tabify.
+ * mpz/get_d_2exp.c: Likewise.
+ * mpf/get_d_2exp.c: Likewise.
+
+ * tests/cxx/t-ops.cc: #if .. #endif out tests that cause ambiguities.
+
+2003-12-10 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-gcd.c: Generate operands with sizes as a geometric
+ progression, to allow for larger operands and less varying timing.
+
+ * tune/tuneup.c (tune_gcd_schoenhage): Set param.step_factor.
+ (tune_hgcd): Likewise.
+
+2003-12-10 Kevin Ryde <kevin@swox.se>
+
+ * demos/perl/test.pl: Should be $] for perl version in old perl.
+
+ * configure.in (sparc64-*-*): Single block of gcc configs for all
+ systems, on unknown systems try both ABI 32 and 64.
+
+ * configure.in (LIBGMP_LDFLAGS, LIBGMPXX_LDFLAGS): New AC_SUBSTs with
+ options to generate .def files with windows DLLs.
+ * Makefile.am (libgmp_la_LDFLAGS, libgmpxx_la_LDFLAGS): Use them.
+
+ * mpn/generic/gcd.c: Use ABOVE_THRESHOLD / BELOW_THRESHOLD, to follow
+ convention and cooperate with tune/tuneup.c.
+
+ * tune/tuneup.c (tune_gcd_schoenhage): Increase max_size to 3000, side
+ default 1000 is approx the crossover point on athlon.
+
+ * tune/common.c, tune/speed.c, tune/speed.h, tune/speed-ext.c,
+ tune/tuneup.c (SPEED_TMP_ALLOC_LIMBS): Take variable as parameter
+ rather than returning a value, avoids alloca in a function call.
+ * tune/common.c, tune/speed.h (speed_tmp_alloc_adjust): Remove, now
+ inline in SPEED_TMP_ALLOC_LIMBS, and using ptr-NULL for alignment
+ extraction.
+
+ * gmpxx.h (__gmp_binary_equal, __gmp_binary_not_equal,
+ __gmp_binary_less, __gmp_binary_less_equal, __gmp_binary_greater,
+ __gmp_binary_greater_equal, __gmp_cmp_function): Use mpfr_cmp_si and
+ mpfr_cmp_d.
+ * tests/cxx/t-ops.cc: Exercise this.
+
+ * demos/perl/Makefile.PL: Don't install sample.pl and test2.pl.
+
+ * demos/perl/GMP.xs (use_sv): Prefer PV over IV or NV to avoid any
+ rounding.
+ * demos/perl/test.pl: Exercise this.
+
+ * demos/perl/GMP/Mpf.pm (overload_string): Corrections to $# usage.
+ * demos/perl/test.pl: Exercise this.
+
+2003-12-08 Kevin Ryde <kevin@swox.se>
+
+ * demos/perl/GMP.pm: Correction to canonicalize example.
+
+ * demos/perl/GMP.xs: New type check scheme, support magic scalars,
+ support UV when available. Remove some unused local variables.
+ (coerce_long): Check range of double.
+ (get_d_2exp): Remove stray printf.
+
+ * demos/perl/test.pl: Exercise magic, rearrange to make it clearer
+ what's being tested.
+
+2003-12-07 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/hgcd.c (mpn_hgcd): Use BELOW_THRESHOLD, to follow the
+ convention of N<THRESH for the lower algorithm, not <=. Fixes
+ algorithm selection in tuneup.c.
+
+ * tune/common.c (speed_mpn_hgcd, speed_mpn_hgcd_lehmer): Use intended
+ align_xp, align_yp.
+
+ * tune/tuneup.c (mul_toom3_threshold): Use MUL_TOOM3_THRESHOLD_LIMIT,
+ for the benefit of ASSERT in mpn_mul_n.
+
+ * tune/tuneup.c (tune_mul): Correction to toom3 param.min_size, should
+ use MPN_TOOM3_MUL_N_MINSIZE.
+
+ * tune/speed.c (check_align_option): Correction to printf format.
+ * tune/freq.c (freq_sysctl_hw_model): Remove unused "i" variable.
+
+ * scanf/doscan.c: Correction to a couple of trace printfs.
+ Add <stdlib.h> for strtol.
+
+ * tests/misc/t-scanf.c (test_sscanf_eof_ok): New function.
+ (check_misc): Use it to suppress tests broken by libc.
+ And should be EOF rather than -1 in various places.
+
+2003-12-06 Torbjorn Granlund <tege@swox.com>
+
+ * tune/common.c (speed_mpn_hgcd, speed_mpn_hgcd_lehmer):
+ Move SPEED_TMP_ALLOC_LIMBS invocations out from calls.
+
+ * mpn/generic/get_str.c (mpn_get_str, POW2_P case):
+ Don't append extra '\0' byte.
+
+2003-12-05 Niels Möller <niels@lysator.liu.se>
+
+ * tune/common.c (speed_mpn_hgcd_lehmer, speed_mpn_hgcd):
+ Updated for the renaming hgcd_sanity -> ASSERT_HGCD.
+
+ * mpn/generic/gcd.c (gcd_schoenhage): TMP_DECL must be the final
+ declaration in the declaration section of a block.
+
+ * tune/speed.h (mpn_gcd_accel): Added prototype.
+
+2003-12-05 Torbjorn Granlund <tege@swox.com>
+
+ * randmt.c (__gmp_mt_recalc_buffer): Put parens around "&" expressions
+ inside "!=".
+
+ * mpf/get_str.c: Remove unused variable "fracn".
+
+2003-12-03 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, Makefile.am (LIBGMP_LDFLAGS, LIBGMPXX_LDFLAGS): New
+ AC_SUBSTs, use them to create .def files with Windows DLLs.
+ * doc/gmp.texi (Notes for Particular Systems): Update notes on mingw
+ DLL with MS C.
+
+ * mpz/export.c: Allow NULL for countp.
+ * doc/gmp.texi (Integer Import and Export): Describe this.
+ Suggested by Jack Lloyd.
+
+ * mpn/x86/p6/aors_n.asm: New file, grabbing the K7 code.
+ Superiority of this reported by Patrick Pelissier.
+
+2003-11-30 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/ev67/popcount.asm, mpn/alpha/ev67/hamdist.asm: New files.
+
+ * mpn/alpha/ev67: New directory.
+ * configure.in (alphaev67, alphaev68, alphaev7*): Use it.
+
+ * doc/gmp.texi (GMPrefu, GMPpxrefu): Change back to plain ref and
+ pxref, remove macros.
+ (GMPreftopu, GMPpxreftopu): Remove URL parameter, rename to GMPreftop
+ and GMPpxreftop.
+ (Debugging): Remove debauch, seems to have disappeared.
+ (Language Bindings): Corrections to URLs for CLN, Omni F77, Pike.
+
+2003-11-29 Kevin Ryde <kevin@swox.se>
+
+ * demos/perl/GMP/Mpf.pm (overload_string): Use $OFMT to avoid warnings
+ about $#.
+
+ * demos/perl/GMP.xs (fits_slong_p): Use LONG_MAX+1 to avoid possible
+ rounding of 0x7F..FF in a double on 64-bit systems.
+
+ * configure.in (ppc601-*-*): Remove this case, it never matched
+ anything, the name adopted is powerpc601.
+ (powerpc601-*-*): Use gcc -mcpu=601, xlc -qarch=601.
+
+ * configure.in: Introduce ${cc}_cflags_maybe, used if they work.
+ (*sparc*-*-*) [ABI=32]: Add gcc_cflags_maybe=-m32 to force that mode.
+
+ * doc/gmp.texi (Introduction to GMP): Add AMD64 to optimizations list.
+ (Build Options): Add cpu types alphaev7 and amd64. Update texinfo
+ html cross reference.
+
+2003-11-28 Niels Möller <nisse@lysator.liu.se>
+
+ * tune/tuneup.c (tune_hgcd): Disable if GMP_NAIL_BITS > 0.
+ * tune/speed.c (routine): Likewise.
+ * tune/common.c (speed_mpn_hgcd, speed_mpn_hgcd_lehmer): Likewise.
+
+ * mpn/generic/gcd.c, mpn/generic/hgcd.c, mpn/generic/hgcd2.c
+ [GMP_NAIL_BITS]: Disabled new code if we have nails.
+
+ * mpn/generic/gcd.c (MPN_LEQ_P): Copied macro definition (needed
+ for compilation with --enable-assert).
+
+ * tune/tuneup.c (hgcd_schoenhage_threshold,
+ gcd_schoenhage_threshold): New variables.
+ (tune_hgcd, tune_gcd_schoenhage): New functions.
+ (all): Call tune_hgcd and tune_gcd_schoenhage.
+
+ * tune/common.c (speed_mpn_hgcd, speed_mpn_hgcd_lehmer)
+ (speed_mpn_gcd_accel): New functions.
+ * tune/speed.c (routine): Added mpn_hgcd, mpn_hgcd_lehmer and
+ mpn_gcd _accel.
+ * tune/speed.h: Added corresponding prototypes.
+
+ * tune/gcd_accel.c: New file.
+
+ * tune/gcd_bin.c (GCD_SCHOENHAGE_THRESHOLD): Set to MP_SIZE_T_MAX.
+
+ * tune/Makefile.am (libspeed_la_SOURCES): Added gcd_accel.c.
+ (TUNE_MPN_SRCS_BASIC): Added hgcd.c.
+
+ * mpn/x86/k7/gmp-mparam.h (HGCD_SCHOENHAGE_THRESHOLD)
+ (GCD_SCHOENHAGE_THRESHOLD): Tuned values.
+
+ * mpn/generic/gcd.c (mpn_gcd, gcd_binary_odd): Renamed the
+ old mpn_gcd function (which implements accelerated binary gcd) to
+ gcd_binary_odd.
+ (gcd_binary): New function, with the additional book keeping
+ needed when using gcd_binary_odd to compute the gcd of non-odd
+ numbers.
+ (hgcd_tdiv): New function.
+ (gcd_lehmer): New function, currently #if:ed out.
+ (hgcd_start_row_p): New function, duplicated from hgcd.c.
+ (gcd_schoenhage_itch): New function.
+ (gcd_schoenhage): New function.
+ (mpn_gcd): New advertised gcd function, which calls
+ mpn_gcd_binary_odd or mpn_gcd_schoenhage, depending on the size of
+ the input.
+
+ * mpn/generic/hgcd.c (mpn_hgcd2_lehmer_step): Renamed function
+ (was lehmer_step), and made non-static. Updated callers.
+
+ * gmp-impl.h (GCD_LEHMER_THRESHOLD): #if:ed out this macro.
+ (mpn_hgcd2_lehmer_step): Added prototype.
+
+2003-11-27 Niels Möller <nisse@lysator.liu.se>
+
+ * tests/mpz/t-gcd.c (gcd_values): Moved definition, so that we
+ don't need to forward declare the array.
+
+2003-11-26 Niels Möller <nisse@lysator.liu.se>
+
+ * mpn/generic/hgcd.c (mpn_hgcd2_fix): Deleted duplicate definition
+ (the function belongs to hgcd2.c).
+
+2003-11-26 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-gcd.c: Generate random operands up to 32767 bits;
+ decrease # of test to 1000.
+ (gcd_values): Remove oversize test case.
+
+2003-11-26 Niels Möller <niels@lysator.liu.se>
+
+ * gmp-impl.h: Added name mangling for hgcd-related functions. Also
+ use __GMP_PROTO.
+ (MPN_LEQ_P, MPN_EXTRACT_LIMB): Moved macros to hgcd.c.
+ * mpn/generic/hgcd.c, mpn/generic/hgcd2.c, mpn/generic/qstack.c:
+ Adapted to name changes.
+
+ * tests/mpz/t-gcd.c (main): Added some tests with non-random
+ input.
+
+2003-11-25 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-impl.h (MPN_LEQ_P, MPN_EXTRACT_LIMB): New macros.
+ (struct qstack, struct hgcd2_row, struct hgcd2, struct hgcd_row)
+ (struct hgcd): New structs. Also added prototypes for new hgcd,
+ hgcd2, qstack and gcd functions.
+
+ * configure.in (gmp_mpn_functions): Added hgcd2, hgcd and qstack.
+
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Added hgcd2.c,
+ hgcd.c and qstack.c.
+
+ * mpn/generic/hgcd.c, mpn/generic/hgcd2.c, mpn/generic/qstack.c:
+ New files, needed for the sub-quadratic gcd.
+
+2003-11-25 Kevin Ryde <kevin@swox.se>
+
+ * doc/gmp.texi (Language Bindings): Add Axiom.
+
+2003-11-22 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/README: More notes on assembler syntax variations.
+
+ * mpn/alpha/alpha-defs.m4, mpn/alpha/unicos.m4 (unop): Should be ldq_u
+ not bis, and move to alpha-defs.m4 since it can be happily used
+ everywhere.
+
+ * mpn/alpha/alpha-defs.m4, mpn/alpha/default.m4, mpn/alpha/unicos.m4
+ (bigend): Move to alpha-defs.m4 and base it on HAVE_LIMB_BIG_ENDIAN or
+ HAVE_LIMB_LITTLE_ENDIAN, so as not to hard code system endianness.
+
+ * mpn/alpha/alpha-defs.m4: New file.
+ * configure.in (alpha*-*-*): Use it.
+
+2003-11-21 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr-2-0-2-branch 2003-11-21.
+
+ * mpn/alpha/ev5/com_n.asm: Change "not" to "ornot r31", since "not"
+ isn't recognised by on Cray Unicos. Add missing "gp" to PROLOGUE.
+ * mpn/alpha/README: Add a note on "not".
+
+2003-11-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/aorslsh1_n.asm: Slightly rework feed-in code, avoiding
+ spurious reads beyond operand limits.
+
+ * mpn/alpha/ev5/com_n.asm: Add ASM_START/ASM_END.
+
+ * mpn/generic/mul_fft.c (mpn_fft_zero_p): Remove unused function.
+ (mpn_lshift_com): Make static, nailify properly.
+
+2003-11-19 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/diveby3.c: Use a "q" variable to make it clearer what
+ the code is doing.
+
+ * mpn/powerpc32/750/lshift.asm, mpn/powerpc32/750/rshift.asm: New
+ files.
+
+ * mpn/alpha/ev5/com_n.asm: New file.
+
+ * doc/gmp.texi (Assembler Functional Units, Assembler Writing Guide):
+ New sections by Torbjorn, tweaked by me.
+
+2003-11-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32: Add power4/powerpc970 cycle counts.
+ Use cmpwi instead of cmpi to placate darwin.
+
+2003-11-15 Kevin Ryde <kevin@swox.se>
+
+ * config.guess: Add comments on MacOS "machine" command.
+
+ * tests/devel/try.c (main): Use gmp_randinit_default explicitly on
+ __gmp_rands, since RANDS doesn't allow seeding.
+
+ * doc/gmp.texi (Assigning Integers): Remove notes on possible change
+ to disallow whitespace, this would be an incompatible change and
+ really can't be made.
+ (Toom 3-Way Multiplication): Updates for Paul's new code.
+
+ * mpn/generic/mul_n.c (toom3_interpolate, mpn_toom3_mul_n): Put
+ if/else braces around whole of #if code, for readability.
+
+ * tests/refmpn.c (refmpn_addlsh1_n, refmpn_sublsh1_n,
+ refmpn_rsh1add_n, refmpn_rsh1sub_n): Add ASSERTs for operand overlaps
+ etc.
+
+ * mpfr/*: Update to mpfr-2-0-2-branch 2003-11-15.
+
+2003-11-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/aorslsh1_n.asm: Use Cray-friendly syntax for "br".
+
+2003-11-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/aorslsh1_n.asm: New file.
+
+2003-11-12 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Add case provoking AIX power2
+ assembler, test code by Torbjorn.
+ * configure.in (power*-*-*): Add a comment about -mcpu=rios2 fallback.
+
+ * tune/speed.c (main): Use gmp_randinit_default explicitly on
+ __gmp_rands, since RANDS doesn't allow seeding.
+
+ * mpfr/*: Update to mpfr-2-0-2-branch 2003-11-12.
+
+ * gmp-impl.h, randmt.h (__gmp_randinit_mt_noseed): Move prototype to
+ gmp-impl.h, for use by RANDS.
+
+ * mpn/Makeasm.am (.s, .S, .asm): Quote $< in test -f, per automake.
+ (.obj): Use test -f and $(CYGPATH_W) as per automake.
+
+2003-11-11 Kevin Ryde <kevin@swox.se>
+
+ * configure.in: Make umul and udiv standard-optional objects, rather
+ than under various extra_functions.
+
+ * mpn/pa32/hppa1_1/pa7100/add_n.asm,
+ mpn/pa32/hppa1_1/pa7100/addmul_1.asm,
+ mpn/pa32/hppa1_1/pa7100/lshift.asm,
+ mpn/pa32/hppa1_1/pa7100/rshift.asm,
+ mpn/pa32/hppa1_1/pa7100/sub_n.asm,
+ mpn/pa32/hppa1_1/pa7100/submul_1.asm: Use LDEF for labels.
+
+ * mpf/set_str.c: Don't use memcmp for decimal point testing, just a
+ loop is enough and avoids any chance of memcmp reading past the end of
+ the given string.
+
+ * randmts.c, randmt.h: New files.
+ * Makefile.am (libgmp_la_SOURCES): Add them.
+ * randmt.c: Move seeding to randmts.c, common defines in randmt.h.
+ * gmp-impl.h (RANDS): Use __gmp_randinit_mt_noseed.
+ * tests/misc.c (tests_rand_start): Use gmp_randinit_default
+ explicitly, not RANDS.
+
+ * mpn/ia64/ia64-defs.m4 (PROLOGUE_cpu): Use 32-byte alignment, for the
+ benefit of itanium 2.
+ * mpn/ia64/gcd_1.asm: Remove own .align 32.
+
+ * mpn/ia64/ia64-defs.m4 (ALIGN): New define, using IA64_ALIGN_OK.
+ * mpn/ia64/hamdist.asm: Use ALIGN instead of .align.
+
+ * acinclude.m4 (GMP_ASM_IA64_ALIGN_OK): New macro.
+ * configure.in (IA64_PATTERN): Use it.
+ * mpn/ia64/README: Add notes on gas big endian align problem.
+
+2003-11-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mul_1.asm: Rewrite.
+
+2003-11-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/aors_n.asm: Align loop to a multiple of 16. Also align
+ M4_function_n to a multiple of 16, to minimize alignment padding.
+ Update P6 cycle counts reflecting improvements with new alignment.
+
+2003-11-07 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (HAVE_HOST_CPU_alpha_CIX): New define.
+ (ULONG_PARITY, popc_limb): Use it, to pick up ev7 as well as 67 and 68.
+ * longlong.h (count_leading_zeros, count_trailing_zeros): Ditto.
+
+ * doc/gmp.texi (Notes for Package Builds): Add notes on multi-ABI
+ system packaging.
+ (ABI and ISA): Add GNU/Linux ABI=64.
+ (Binary GCD): Add notes on 1x1 GCD algorithms.
+
+ * mpn/alpha/README: Add some literature references.
+
+ * mpn/ia64/mode1o.asm: Various corrections to initial checkin.
+ * mpn/ia64/ia64-defs.m4 (ASSERT): Correction to arg quoting.
+
+2003-11-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/linux64.m4: New file.
+ * configure.in (POWERPC64_PATTERN): Handle *-*-linux*.
+ Use linux64.m4.
+
+ * mpn/ia64/logops_n.asm: New file.
+
+2003-11-05 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c (freq_sysctl_hw_model): Relax to just look for "%u MHz",
+ for the benefit of sparc cypress under netbsd 1.6.1.
+
+ * mpfr/*: Update to mpfr-2-0-2-branch 2003-11-05.
+
+ * mpn/alpha/ev5/dive_1.c: New file.
+
+ * configure.in (x86_64-*-*): Accept together with amd64-*-*.
+
+ * tune/speed.c: Check range of -x,-y,-w,-W alignment specifiers.
+ * tune/speed.h (CACHE_LINE_SIZE): Amend comments.
+
+2003-11-04 Torbjorn Granlund <tege@swox.com>
+
+ * tune/speed.c: Fix typo in testing HAVE_NATIVE_mpn_modexact_1_odd.
+
+2003-11-03 Kevin Ryde <kevin@swox.se>
+
+ * mpn/ia64/hamdist.asm: New file.
+ * mpn/ia64/mode1o.asm: New file.
+ * mpn/ia64/ia64-defs.m4 (ASSERT): New macro.
+
+ * tests/mpz/t-set_d.c (check_2n_plus_1): New test.
+
+2003-11-01 Kevin Ryde <kevin@swox.se>
+
+ * mpz/fac_ui.c (BSWAP_ULONG) [limb==2*long]: Remove this case, it
+ provokes code gen problems on HP cc.
+ (BSWAP_ULONG) [generic]: Rename __dst variable to avoid conflicts with
+ BITREV_ULONG.
+ Fix by Jason Moxham.
+
+ * mpn/powerpc32/mode1o.asm: Use 16-bit i*i for early out, no need to
+ truncate divisor. Amend stated 750/7400 speeds, and note operands
+ that give the extremes.
+
+ * mpz/set_d.c: Don't use a special case for d < MP_BASE_AS_DOUBLE, gcc
+ 3.3 -mpowerpc64 on darwin gets ulonglong->double casts wrong.
+
+ * mpn/generic/diveby3.c: Show a better style carry handling in the
+ alternative pipelined sample code.
+
+ Revert this, the longlong.h macros need -mpowerpc64:
+ * acinclude.m4 (GMP_GCC_POWERPC64): New macro.
+ * configure.in (powerpc64-*-darwin*): Use it to exclude -mpowerpc64
+ when bad.
+
+2003-10-31 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode64/submul_1.asm: Move an instruction to save a
+ cycle on POWER4.
+
+ * mpn/powerpc64/mode64/divrem_1.asm: Fix several syntax problems
+ revealed on Mac OS X.
+
+ * mpn/powerpc64/mode64/*.asm: Add cycle counts for POWER4.
+
+ * mpn/powerpc64/sqr_diagonal.asm: Rewrite to save a cycle on POWER4.
+
+2003-10-31 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr-2-0-2-branch 2003-10-31.
+
+ * mpn/powerpc64/README: Add subdirectory organisation notes.
+
+ * tests/mpn/t-get_d.c: Don't use limits.h, LONG_MIN is wrong on gcc
+ 2.95 with -mcpu=ultrasparc.
+
+ * acinclude.m4 (GMP_GCC_POWERPC64): New macro.
+ * configure.in (powerpc64-*-darwin*): Use it to exclude -mpowerpc64
+ when bad.
+
+ * configure.in (powerpc64-*-darwin*) [ABI=mode32]: Use gcc -mcpu flags.
+
+ * mpn/ia64/divrem_1.asm, mpn/ia64/gcd_1.asm: Use "C" for comments.
+ * mpn/ia64/README, mpn/ia64/ia64-defs.m4: Note this.
+
+ * mpn/ia64/ia64-defs.m4: Renamed from default.m4, per other defs files.
+ * configure.in (IA64_PATTERN): Update GMP_INCLUDE_MPN.
+
+ * doc/gmp.texi (Notes for Particular Systems): Remove m68k ABI notes
+ for -mshort and PalmOS, now works.
+ (References): Correction, GMP Square Root proof already there, just
+ wanting URL from RRRR 4475.
+
+2003-10-29 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (sparc*-*-*): Use gcc -m32 when that option works, to
+ force 32-bit mode on dual 32/64 configurations like GNU/Linux.
+ (sparc64-*-linux*): Add support for ABI=64.
+
+ * mpn/generic/pre_divrem_1.c: In fraction part, use CNST_LIMB(0) with
+ udiv_qrnnd_preinv to avoid warning about shift > type.
+
+ * mpfr/*: Update to mpfr-2-0-2-branch 2003-10-29.
+
+ * tests/cxx/t-istream.cc: Avoid tellg() checks if putback() doesn't
+ update that, avoids certain g++ 2.96 problems.
+
+ * tests/mpn/t-fat.c: New file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add it.
+
+ * configure.in (CPUVEC_INSTALL, ITERATE_FAT_THRESHOLDS): New macros
+ for fat.h.
+ * mpn/x86/fat/fat.c (__gmpn_cpuvec_init): Use CPUVEC_INSTALL instead
+ of memcpy. Correction to location of "initialized" set. Improve
+ various comments.
+
+2003-10-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/mul_1.asm: Change addcc => add in a few places.
+ * mpn/sparc64/addmul_1.asm: Likewise.
+
+ * mpn/sparc32/v9/mul_1.asm: Apply cross-jumping.
+ * mpn/sparc32/v9/addmul_1.asm: Likewise.
+ * mpn/sparc32/v9/submul_1.asm: Likewise.
+ * mpn/sparc32/v9/sqr_diagonal.asm: Likewise.
+
+2003-10-27 Kevin Ryde <kevin@swox.se>
+
+ * tests/cxx/t-misc.cc: Don't use <climits>, on g++ 2.95.4 (debian 3.0)
+ -mcpu=ultrasparc LONG_MIN is wrong and kills the compile.
+
+ * tests/cxx/t-istream.cc: Correction to tellg tests, don't assume
+ streampos is zero based.
+
+ * configure.in (HAVE_HOST_CPU_FAMILY_alpha): New define for config.h.
+ * mpn/generic/get_d.c: Use it instead of __alpha for alpha workaround,
+ since Cray cc doesn't define __alpha.
+
+ * mpn/x86/README: Revise PIC coding notes a bit, add gcc visibility
+ attribute.
+
+2003-10-25 Kevin Ryde <kevin@swox.se>
+
+ * mpn/ia64/gcd_1.asm: New file.
+
+ * tune/many.pl: Allow for PROLOGUE(fun,...), as used on alpha.
+
+ * doc/gmp.texi (C++ Formatted Input): Describe base indicator handling.
+
+ * tests/cxx/t-istream.cc: New file.
+ * tests/cxx/Makefile.am: Add it.
+
+ * cxx/ismpznw.cc: New file, integer input without whitespace ...
+ * cxx/ismpz.cc: ... from here.
+ * gmp-impl.h (__gmpz_operator_in_nowhite): Add prototype.
+ * cxx/ismpq.cc: Rewrite using mpz input routines. Change to accept a
+ separate base indicator on numerator and denominator. Fix base
+ indicator case where "123/0456" would stop at "123/0".
+ * Makefile.am, cxx/Makefile.am: Add cxx/ismpznw.cc.
+
+ * tests/mpz/t-set_d.c: New file, derived from tests/mpz/t-set_si.c
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpn/m68k/lshift.asm, mpn/m68k/rshift.asm: Support 16-bit int and
+ stack alignment.
+ * mpn/m68k/README: Add notes on this.
+ * configure.in (SIZEOF_UNSIGNED): New define in config.m4.
+ * mpn/m68k/m68k-defs.m4 (m68k_definsn): Add cmpw, movew.
+ Reported by Patrick Pelissier.
+
+ * mpn/m68k/t-m68k-defs.pl: Don't use -> with hashes, to avoid
+ deprecation warnings from perl 5.8.
+
+ * configure.in (viac3-*-*): Use just x86/pentium in $path not x86/p6.
+ If gcc is to be believed the old C3s don't have cmov.
+
+ * Makefile.am: Amend comments about not building from libtool
+ convenience libraries.
+
+ * mpn/asm-defs.m4 (PROLOGUE): Use m4_file_seen, for correct filename
+ in missing EPILOGUE error messages.
+ (m4_file_seen): Amend comments about where used.
+
+ * Makefile.am (CXX_OBJECTS): Remove $U, C++ files are not subject to
+ ansi2knr rules.
+
+ * gmp-h.in (mpn_divmod_1): Use __GMP_CAST, to avoid warnings in
+ applications using g++ -Wold-style-cast.
+
+ * mpn/z8000/README: New file.
+
+2003-10-22 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/get_d.c (CONST_1024, CONST_NEG_1023,
+ CONST_NEG_1022_SUB_53): Replace ALPHA_WORKAROUND with a non-gcc-ism,
+ and use on Cray Unicos alpha too, which has the same problem.
+
+ * configure.in (powerpc64-*-darwin*): Make ABI=32 available as the
+ final fallback, remove mode64 until we know how it will work.
+
+ * doc/gmp.texi (Build Options): Add powerpc970 to available CPUs.
+ (ABI and ISA): Add mode32 for Darwin.
+
+ * configure.in (gettimeofday): Use an explicit AC_TRY_LINK, to avoid
+ known autoconf 2.57 problems with gettimeofday in AC_CHECK_FUNCS on
+ HP-UX.
+
+ * configure.in (powerpc*-*-*): Use ABI=32 instead of ABI=standard for
+ the default 32-bit ABI. Fixes powerpc64-*-aix* which is documented as
+ choices "aix64 32" but had "aix64 standard".
+
+ * mpfr/*: Update to mpfr-2-0-2-branch 2003-10-22.
+
+ * doc/gmp.texi (Notes for Particular Systems): Note m68k gcc -mshort
+ and PalmOS calling conventions not supported. Reported by Patrick
+ Pelissier.
+ (References): Add Paul Zimmermann's Inria 4475 paper.
+
+2003-10-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/submul_1.asm: Slightly reschedule loop to accommodate
+ Itanium 2 getf.sig latency.
+
+2003-10-21 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpn/t-instrument.c: Add mpn_addlsh1_n, mpn_rsh1add_n,
+ mpn_rsh1sub_n, mpn_sub_nc, mpn_sublsh1_n. Typo in mpn_preinv_divrem_1
+ conditional.
+
+2003-10-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/mode32/add_n.asm: New file.
+ * mpn/powerpc64/mode32/sub_n.asm: New file.
+ * mpn/powerpc64/mode32/mul_1.asm: New file.
+ * mpn/powerpc64/mode32/addmul_1.asm: New file.
+ * mpn/powerpc64/mode32/submul_1.asm: New file.
+
+2003-10-19 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (AMD64): __x86_64__ => __amd64__.
+ (64-bit powerpc): Only define carry-dependent macros if
+ !_LONG_LONG_LIMB.
+
+ * acinclude.m4 (POWERPC64_PATTERN): Add powerpc970-*-*.
+
+ * configure.in (POWERPC64_PATTERN): Handle *-*-darwin*.
+ (POWERPC64_PATTERN, *-*-aix*): Prepend powerpc64/mode64 to path_aix64.
+
+ * mpn/powerpc64/mode64/mul_1.asm: Change cal => addi.
+ * mpn/powerpc64/mode64/addmul_1.asm: Likewise.
+ * mpn/powerpc64/mode64/submul_1.asm: Likewise.
+ * mpn/powerpc64/sqr_diagonal.asm: Likewise.
+
+ * mpn/powerpc64/mode64/mul_1.asm: Move from "..".
+ * mpn/powerpc64/mode64/addmul_1.asm: Likewise.
+ * mpn/powerpc64/mode64/submul_1.asm: Likewise.
+ * mpn/powerpc64/mode64/divrem_1.asm: Likewise.
+ * mpn/powerpc64/mode64/rsh1sub_n.asm: Likewise.
+ * mpn/powerpc64/mode64/add_n.asm: Likewise.
+ * mpn/powerpc64/mode64/addsub_n.asm: Likewise.
+ * mpn/powerpc64/mode64/sub_n.asm: Likewise.
+ * mpn/powerpc64/mode64/addlsh1_n.asm: Likewise.
+ * mpn/powerpc64/mode64/diveby3.asm: Likewise.
+ * mpn/powerpc64/mode64/rsh1add_n.asm: Likewise.
+ * mpn/powerpc64/mode64/sublsh1_n.asm: Likewise.
+
+ * mpn/powerpc64/lshift.asm: Handle mode32 ABI.
+ * mpn/powerpc64/rshift.asm: Likewise.
+ * mpn/powerpc64/umul.asm: Likewise.
+
+ * tune/powerpc64.asm: Make it actually work.
+
+2003-10-19 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/get_d.c: Add a workaround for alpha gcc signed constant
+ comparison bug.
+
+ * gmpxx.h (gmp_randclass gmp_randinit_lc_2exp_size constructor): Throw
+ std::length_error if size is too big.
+ * tests/cxx/t-rand.cc (check_randinit): Exercise this.
+
+ * mpn/x86/pentium4/sse2/addlsh1_n.asm: New file, derived in part from
+ mpn/x86/pentium4/sse2/add_n.asm.
+
+ * doc/gmp.texi (C++ Interface Integers, C++ Interface Rationals, C++
+ Interface Floats): Note std::invalid_argument exception for invalid
+ strings to constructors and operator=.
+ (C++ Interface Random Numbers): Note std::length_error exception for
+ size too big in gmp_randinit_lc_2exp_size.
+
+2003-10-18 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr-2-0-2-branch 2003-10-18.
+
+ * gmpxx.h (mpz_class, mpq_class, mpf_class, mpfr_class constructors
+ and operator= taking string or char*): Throw std::invalid_argument if
+ string cannot be converted.
+ * tests/cxx/t-constr.cc, tests/cxx/t-assign.cc: Exercise this.
+
+ * cxx/ismpz.cc, cxx/ismpq.cc, cxx/ismpf.cc: Use istream std::locale
+ ctype facet for isspace when available. Only accept space at the
+ start of the input, same as g++ libstdc++. Use ASSERT_NOCARRY to
+ check result of mpz_set_str etc.
+ * cxx/ismpf.cc: Don't accept "@" for exponent indicator.
+
+ * tune/speed.c, tune/speed.h, tune/common.c, tune/Makefile.am: Remove
+ _open and _mpn variants of mpn_toom3_mul_n, only one style now.
+ * tune/mul_n_open.c, tune/mul_n_mpn.c: Remove files.
+
+ * gmp-impl.h (LIMB_HIGHBIT_TO_MASK): New macro.
+ (udiv_qrnnd_preinv2, udiv_qrnnd_preinv2gen): Use it.
+
+ * tests/mpz/t-import.c, tests/mpz/t-export.c: Use octal for character
+ constants, hex is an ANSI-ism.
+
+ * mpn/alpha/ev5/mode1o.c: Corrections to ASSERTs, as per
+ mpn/generic/mode1o.c.
+
+ * mpn/generic/diveby3.c: Add commented out alternative code and notes
+ for taking the multiply off the dependent chain. Amend/clarify some
+ of the other comments.
+
+ * configure.in (powerpc970-*-*): Use gcc -mcpu=970 when available.
+ (powerpc7400-*-*): Fallback on gcc -mcpu=750 if -mcpu=7400 not
+ available.
+
+ * doc/gmp.texi (C++ Formatted Input): Note locale digit grouping not
+ supported.
+ (C++ Formatted Input, C++ Formatted Output): Cross reference class
+ interface on overloading.
+
+ * mpn/m68k/README: Add various ideas from doc/tasks.html.
+
+ * mpn/m88k/README: New file.
+
+2003-10-16 Torbjorn Granlund <tege@swox.com>
+
+ * config.sub: Recognize powerpc970.
+
+2003-10-15 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Recognize powerpc970 under MacOS.
+
+2003-10-15 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, acinclude.m4 (GMP_C_RIGHT_SHIFT): New test.
+ * gmp-impl.h (LIMB_HIGHBIT_TO_MASK): New macro.
+ (udiv_qrnnd_preinv2, udiv_qrnnd_preinv2gen): Use it.
+
+ * mpn/amd64/amd64-defs.m4: New file, with a non-aligning PROLOGUE.
+ * configure.in (amd64-*-*): Use it.
+ * mpn/amd64/addlsh1_n.asm: Add ALIGN(16).
+
+ * mpfr/*: Update to mpfr cvs 2003-10-15.
+
+ * mpn/generic/get_d.c: Rewrite, simplifying and truncating towards
+ zero unconditionally.
+ * tests/mpn/t-get_d.c: Add various further tests.
+ * gmp-impl.h (FORCE_DOUBLE): New macro.
+
+ * gmp-h.in (__mpz_struct): Add comment on __mpz_struct getting into
+ C++ mangled function names.
+
+ * doc/gmp.texi (Build Options): Update notes for new doc subdir.
+ (Low-level Functions): Note mpn functions don't check for zero limbs
+ etc, it's up to an application to strip.
+
+ * doc/configuration (Configure): mdate-sh now in doc subdir, add
+ generated fat.h.
+
+2003-10-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/lorrshift.asm: Rewrite.
+
+ * mpn/ia64/diveby3.asm: Remove explicit bundling; add branch hints.
+
+2003-10-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/diveby3.asm: New file.
+
+2003-10-13 Kevin Ryde <kevin@swox.se>
+
+ * mpn/powerpc32/mod_34lsub1.asm: New file.
+
+ * mpn/powerpc32/diveby3.asm, mpn/powerpc64/diveby3.asm: src[] in
+ second operand of mullw, to allow possible early-out, which the
+ 0xAA..AB inverse cannot give. This improvement noticed by Torbjorn.
+
+ * acinclude.m4 (GMP_ASM_LSYM_PREFIX): Print to config.log whether
+ local label is purely temporary or appears in object files, for
+ development purposes.
+
+ * doc/gmp.texi, doc/fdl.texi, doc/texinfo.tex, doc/mdate-sh: Moved
+ from top-level.
+ * doc/Makefile.am: New file.
+ * configure.in (AC_OUTPUT): Add doc/Makefile.
+ * Makefile.am (SUBDIRS): Move doc subdirectory from EXTRA_DIST.
+ (info_TEXINFOS, gmp_TEXINFOS): Moved to doc/Makefile.am.
+ * mpfr/Makefile.am (mpfr_TEXINFOS): fdl.texi now in doc subdir.
+ (TEXINFO_TEX): texinfo.tex now in doc subdir.
+ (AM_MAKEINFOFLAGS): Set -I to doc subdir.
+
+ * mpz/and.c: For positive/positive, use mpn_and_n, rate a realloc as
+ UNLIKELY.
+
+ * mpn/generic/mul_n.c (mpn_toom3_mul_n, mpn_toom3_sqr_n): Don't test
+ for high zero limbs.
+
+2003-10-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/diveby3.asm: New file (trivial edits of
+ powerpc32/diveby3.asm).
+
+ * mpn/powerpc32/diveby3.asm: Update cycle counts with more processors.
+ * mpn/powerpc32/sqr_diagonal.asm: Likewise.
+
+ * mpn/pa64/add_n.asm: Correct PA8500 cycle counts.
+ * mpn/pa64/sub_n.asm: Likewise.
+
+ * mpn/m68k/aors_n.asm (INPUT PARAMETERS): Fix typo.
+ * mpn/m68k/lshift.asm: Likewise.
+ * mpn/m68k/rshift.asm: Likewise.
+
+ * mpn/m68k/README: Correct an URL; add some STATUS comments.
+
+ * mpn/ia64/aorslsh1_n.asm: Avoid shrp when shl/shr works just as well.
+
+ * mpn/powerpc32/addlsh1_n.asm: New file.
+ * mpn/powerpc32/sublsh1_n.asm: New file.
+
+2003-10-12 Kevin Ryde <kevin@swox.se>
+
+ * mpn/sparc64/divrem_1.c, mpn/sparc64/mod_1.c: New files.
+ * mpn/sparc64/sparc64.h (HALF_ENDIAN_ADJ, count_leading_zeros_32,
+ invert_half_limb, udiv_qrnnd_half_preinv): New macros.
+
+ * gmp-impl.h (udiv_qrnnd_preinv2): Use a ? : for getting the n1 bit,
+ so as not to depend on signed right shifts being arithmetic.
+
+ * mpn/powerpc32/diveby3.asm: New file.
+
+ * mpn/generic/divrem_1.c: Use CNST_LIMB(0) to avoid warnings from
+ udiv_qrnnd_preinv about shift count when int<long. Do the same with
+ udiv_qrnnd, for consistency.
+
+ * Makefile.am (install-data-hook): Print a warning recommending "make
+ check" to watch out for compiler bugs. Proposed by Torbjorn.
+
+ * mpn/ia64/README (mpn_lshift, mpn_rshift): Amend prospective itanium2
+ speed, 0.75 c/l with shrp plus shl/shr.
+
+ * mpn/ia64/popcount.asm: Add comment on optimality.
+
+2003-10-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/rsh1aors_n.asm: New file.
+
+ * mpn/asm-defs.m4: Handle rsh1aors_n.
+
+ * configure.in (tmp_mulfunc): Handle rsh1aors_n.
+
+2003-10-11 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium4/sse2/diveby3.asm: Remove non-PIC RODATA memory
+ access for 0xAAAAAAAB constant.
+
+ * gmp-impl.h (popc_limb, ULONG_PARITY) [ev67, ev68]: Add gcc asm
+ versions using ctpop.
+
+ * mpn/x86/k6/aorsmul_1.asm: Tweak some comments, remove M4_description
+ and M4_desc_retval used only in comments.
+
+ * mpn/x86/k6/mul_basecase.asm: Add comment on using mpn_mul_1.
+
+2003-10-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/addlsh1_n.asm: Tweak for 0.25 c/l better loop speed.
+ * mpn/powerpc64/sublsh1_n.asm: Likewise.
+
+2003-10-09 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-10-09.
+
+ * tests/devel/try.c (_SC_PAGESIZE): Define from _SC_PAGE_SIZE on
+ systems which use that, eg. hpux 9.
+
+2003-10-07 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c (freq_sysctl_hw_model): Correction to last sscanf change.
+
+ * configure.in: Check for psp_iticksperclktick in struct pst_processor.
+ * tune/freq.c (freq_pstat_getprocessor): Use this.
+
+ * tests/devel/try.c (divisor_array): Add a couple of half-limb values.
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Correction to last change, need to
+ set result "yes" when cross compiling.
+
+2003-10-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_n.c: Use __GMPN_ADD_1/_GMPN_SUB_1 instead of
+ mpn_add_1 and mpn_sub_1.
+
+ * mpn/pa64/aorslsh1_n.asm: Schedule register save and restore code.
+
+2003-10-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64/mul_1.asm: Misc comment cleanups.
+ * mpn/pa64/addmul_1.asm: Likewise.
+ * mpn/pa64/submul_1.asm: Likewise.
+
+ * mpn/pa64/README: Correct cycle counts.
+
+ * mpn/pa64/aorslsh1_n.asm: New file.
+
+2003-10-04 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c (freq_sysctl_hw_model, freq_sunos_sysinfo,
+ freq_sco_etchw, freq_bsd_dmesg, freq_irix_hinv): Demand matching of
+ MHz etc at end of sscanf format string. In particular need this for
+ freq_bsd_dmesg on i486-pc-freebsd4.7 to avoid the 486 cpu being used
+ for the frequency.
+
+ * tests/misc.c, tests/tests.h (tests_setjmp_sigfpe,
+ tests_sigfpe_handler, tests_sigfpe_done, tests_sigfpe_target,
+ tests_dbl_mant_bits): New.
+
+ * configure.in (viac3*-*-*): Add gcc VIA c3 options.
+
+ * mpfr/*: Update to mpfr cvs 2003-10-04.
+
+ * tests/refmpn.c (refmpn_addlsh1_n, refmpn_sublsh1_n,
+ refmpn_rsh1add_n, refmpn_rsh1sub_n): Add ASSERTs for operand overlaps.
+ * tests/tests.h (refmpn_addlsh1_n, refmpn_sublsh1_n, refmpn_rsh1add_n,
+ refmpn_rsh1sub_n): Add prototypes.
+
+ * tests/devel/try.c, tune/many.pl: Add mpn_addlsh1_n, mpn_sublsh1_n,
+ mpn_rsh1add_n, mpn_rsh1sub_n.
+
+2003-10-03 Torbjorn Granlund <tege@swox.com>
+
+ * tests/refmpn.c (refmpn_addlsh1_n, refmpn_sublsh1_n, refmpn_rsh1add_n,
+ refmpn_rsh1sub_n): New functions.
+
+2003-10-03 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpn/generic/mul_n.c (toom3_interpolate): Use mpn_add_1/mpn_sub_1
+ instead of MPN_INCR_/MPN_DECR_U.
+
+2003-10-02 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (ia64*-*-hpux*): Fall back to +O1, not +O.
+
+2003-10-02 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (ia64*-*-hpux*): For cc, let +O optimization level
+ fallback if +O3 doesn't work.
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Add a test of __builtin_alloca
+ when available, to pick up Itanium HP-UX cc internal errors in +O2.
+ Provoking code by Torbjorn.
+
+2003-10-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/gmp-mparam.h: Retune.
+
+ * mpn/asm-defs.m4: Handle aorslsh1_n.
+
+ * configure.in (tmp_mulfunc): Handle aorslsh1_n.
+
+ * mpn/ia64/aorslsh1_n.asm: New file.
+
+ * mpn/ia64/aors_n.asm: New file, complete rewrite of mpn_add_n and
+ mpn_sub_n.
+ * mpn/ia64/add_n.asm: Replace by aors_n.asm.
+ * mpn/ia64/sub_n.asm: Replace by aors_n.asm.
+
+2003-10-01 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_C_DOUBLE_FORMAT): Make bad ARM last byte into a
+ separate case and consider it non-IEEE, since it looks like this is
+ due to some sort of restricted or incorrect software floats.
+
+ * demos/calc/Makefile.am: Use automake yacc/lex support, seems fine in
+ separate objdir now.
+
+ * cxx/dummy.cc: Moved from top-level dummy.cc.
+ * Makefile.am (libgmpxx_la_SOURCES): Update to cxx/dummy.cc,
+ correction to comment about this.
+
+2003-09-30 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c: Correct documentation of -split.
+ (TIME): Remove cast of result to double.
+ (main): Change timing variables to int.
+ (main): #ifdef LIMIT_RESOURCE_USAGE, don't convert numbers of more than
+ 100000 digits.
+
+2003-09-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/*/*.asm: Clean up spacing, tabify.
+
+ * mpn/alpha/rshift.asm: Table cycle counts.
+ * mpn/alpha/lshift.asm: Likewise.
+ * mpn/alpha/ev5/rshift.asm: Likewise.
+ * mpn/alpha/ev5/lshift.asm: Likewise.
+ * mpn/alpha/ev6/add_n.asm: Likewise.
+ * mpn/alpha/ev6/sub_n.asm: Likewise.
+
+ * mpn/ia64/lorrshift.asm: Amend comments about performance.
+
+ * mpn/pa64/mul_1.asm: Fix comment typo.
+ * mpn/pa64/addmul_1.asm: Likewise.
+ * mpn/pa64/submul_1.asm: Likewise.
+
+ * mpn/amd64/addlsh1_n.asm: Save/restore carry using two insn to break
+ recurrency. Add remarks about possible further speedup.
+ * mpn/amd64/sublsh1_n.asm: Likewise.
+
+ * mpn/amd64/rsh1add_n.asm: Add remarks about possible further speedup.
+ * mpn/amd64/rsh1sub_n.asm: Likewise.
+
+2003-09-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/README: Update with POWER4/PPC970 pipeline info.
+
+ * mpn/powerpc64/rsh1add_n.asm: New file.
+ * mpn/powerpc64/rsh1sub_n.asm: New file.
+ * mpn/powerpc64/rshift.asm: Rewrite.
+ * mpn/powerpc64/lshift.asm: Rewrite.
+
+2003-09-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/addlsh1_n.asm: New file.
+ * mpn/powerpc64/sublsh1_n.asm: New file.
+
+2003-09-25 Torbjorn Granlund <tege@swox.com>
+
+ * tune/common.c (speed_mpn_addlsh1_n, speed_mpn_sublsh1_n,
+ speed_mpn_rsh1add_n, speed_mpn_rsh1sub_n): Conditionalize on
+ corresponding HAVE_NATIVE_*.
+
+2003-09-25 Kevin Ryde <kevin@swox.se>
+
+ * mpz/combit.c: Use GMP_NUMB_BITS not BITS_PER_MP_LIMB.
+
+ * demos/expr/exprfr.c: Allow for mpfr_inf_p, mpfr_nan_p and
+ mpfr_number_p merely returning non-zero, rather than 1 or 0.
+
+ * demos/expr/exprfr.c, demos/expr/t-expr.c: Add erf, integer_p, zeta.
+
+ * demos/expr/Makefile.am (LDADD): Update comments on $(LIBM).
+
+2003-09-24 Torbjorn Granlund <tege@swox.com>
+
+ * tune/speed.c (routine): Add entries for mpn_addlsh1_n, mpn_sublsh1_n,
+ mpn_rsh1add_n, and mpn_rsh1sub_n.
+
+ * tune/speed.h: Declare speed_mpn_addlsh1_n, speed_mpn_sublsh1_n,
+ speed_mpn_rsh1add_n, and speed_mpn_rsh1sub_n.
+
+ * tune/common.c (speed_mpn_addlsh1_n, speed_mpn_sublsh1_n,
+ speed_mpn_rsh1add_n, speed_mpn_rsh1sub_n): New functions.
+
+ * gmp-impl.h: Declare mpn_addlsh1_n, mpn_sublsh1_n, mpn_rsh1add_n, and
+ mpn_rsh1sub_n.
+
+ * mpn/asm-defs.m4: Add define_mpn's for addlsh1_n, sublsh1_n,
+ rsh1add_n, and rsh1sub_n.
+
+ * mpn/powerpc64/*.asm: Add cycle counts in consistent style. Misc
+ styling edits.
+
+ * mpn/amd64/gmp-mparam.h: Retune.
+
+ * configure.in: Add #undefs for HAVE_NATIVE_mpn_addlsh1_n,
+ HAVE_NATIVE_mpn_sublsh1_n, HAVE_NATIVE_mpn_rsh1add_n,
+ HAVE_NATIVE_mpn_rsh1sub_n.
+ (gmp_mpn_functions_optional): List addlsh1_n, sublsh1_n, rsh1add_n,
+ and rsh1sub_n.
+
+ * mpn/amd64/addlsh1_n.asm: New file.
+ * mpn/amd64/sublsh1_n.asm: New file.
+ * mpn/amd64/rsh1add_n.asm: New file.
+ * mpn/amd64/rsh1sub_n.asm: New file.
+
+2003-09-24 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-09-24.
+
+ * acinclude.m4 (GMP_C_DOUBLE_FORMAT): Remove conftest* temporary files.
+
+2003-09-23 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (MUL_TOOM3_THRESHOLD, SQR_TOOM3_THRESHOLD): Now 128.
+
+2003-09-23 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (gmp_randinit_set): Use __gmp_const rather than const.
+
+2003-09-22 Torbjorn Granlund <tege@swox.com>
+
+ * tune/mul_n_mpn.c: (__gmpn_sqr_n): New #define.
+ * tune/mul_n_open.c (__gmpn_sqr_n): New #define.
+
+ * mpn/generic/mul.c (mpn_sqr_n): Move from here...
+ * mpn/generic/mul_n.c (mpn_sqr_n): ...to here.
+ (mpn_sqr_n): Allocate workspace for toom3 using TMP_* mechanism except
+ for very large operands when !WANT_FFT.
+
+ * mpn/generic/mul_n.c: Add a missing ";". Misc comment fixes.
+
+ * mpn/generic/mul.c: Remove spurious #include <stdio.h>.
+
+ * mpn/x86/k7/gmp-mparam.h: Retune.
+
+ * mpn/generic/mul_n.c (mpn_mul_n): Allocate workspace for toom3 using
+ TMP_* mechanism except for very large operands when !WANT_FFT.
+
+ * gmp-impl.h (MPN_TOOM3_MUL_N_TSIZE, MPN_TOOM3_SQR_N_TSIZE):
+ Define conditionally on WANT_FFT and HAVE_NATIVE_mpn_sublsh1_n.
+ (MPN_TOOM3_MAX_N): New #define.
+
+ * mpn/amd64/gmp-mparam.h: Retune.
+
+ * mpn/Makefile.am (TARG_DIST): Add amd64.
+
+ * mpn/generic/sqr_basecase.c: Use mpn_addlsh1_n when available.
+
+ * mpn/generic/mul_n.c: Use proper form for HAVE_NATIVE macros.
+
+2003-09-22 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-09-22.
+
+2003-09-21 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium4/sse2/gmp-mparam.h (USE_PREINV_DIVREM_1,
+ USE_PREINV_MOD_1): Set to 1 for new asm versions.
+
+ * mpfr/*: Update to mpfr cvs 2003-09-21.
+
+2003-09-21 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpn/generic/mul_n.c (mpn_toom3_mul_n): Conditionally use
+ mpn_sublsh1_n, mpn_rsh1add_n and mpn_rsh1sub_n, in addition to
+ mpn_addlsh1_n. Avoid all copying, at the expense of some additional
+ workspace.
+
+ * gmp-impl.h (MPN_TOOM3_MUL_N_TSIZE, MPN_TOOM3_SQR_N_TSIZE): Accommodate
+ latest toom3 code.
+
+2003-09-19 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium4/sse2/divrem_1.asm, mpn/x86/pentium4/sse2/mod_1.asm:
+ New files.
+
+2003-09-16 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.c (run_one): Don't scale the -1.0 not-available return.
+ Print "n/a" for times not-available.
+
+2003-09-13 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpn/generic/mul_n.c (toom3_interpolate): New function.
+ (mpn_toom3_mul_n, mpn_toom3_sqr_n): Call toom3_interpolate.
+
+2003-09-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_n.c (mpn_toom3_mul_n, mpn_toom3_sqr_n): Remove unused
+ variables.
+ (mpn_toom3_mul_n, mpn_toom3_sqr_n): Use offset `+ 1', not `+ 2' in last
+ MPN_DECR_U calls.
+
+2003-09-12 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpn/generic/mul_n.c (mpn_toom3_mul_n, mpn_toom3_sqr_n): Rewrite.
+
+2003-09-12 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (MPN_KARA_MUL_N_TSIZE, MPN_KARA_SQR_N_TSIZE): Reformulate
+ to use the same form as MPN_TOOM3_MUL_N_TSIZE.
+ (MPN_TOOM3_MUL_N_TSIZE, MPN_TOOM3_SQR_N_TSIZE): Update for new Toom3
+ code requirements.
+ * mpn/generic/mul_n.c (evaluate3, interpolate3, add2Times): Remove.
+ (USE_MORE_MPN): Remove.
+
+2003-08-31 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-08-31.
+
+2003-08-30 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-08-30.
+
+2003-08-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/copyi.asm: New file.
+ * mpn/amd64/copyd.asm: New file.
+ * mpn/amd64/README: New file.
+
+2003-08-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/lshift.asm: New file.
+ * mpn/amd64/rshift.asm: New file.
+ * mpn/amd64/gmp-mparam.h: Retune.
+
+2003-08-23 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c (freq_getsysinfo): Correction to speed_cycletime value
+ established.
+
+ * mpz/rootrem.c, gmp-h.in, gmp.texi (mpz_rootrem): Don't return
+ exactness indication, can get that from testing the remainder.
+
+ * mpn/x86/k7/aors_n.asm, mpn/x86/k7/mmx/copyi.asm: Amend to comments
+ about loads and stores and what speed should be possible.
+
+2003-08-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/amd64/add_n.asm: New file.
+ * mpn/amd64/sub_n.asm: New file.
+ * mpn/amd64/mul_1.asm: New file.
+ * mpn/amd64/addmul_1.asm: New file.
+ * mpn/amd64/submul_1.asm: New file.
+
+2003-08-19 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h (add_ssaaaa, sub_ddmmss) [hppa 64]: Move down into main
+ __GNUC__ block. Exclude for _LONG_LONG_LIMB (ie. ABI=2.0n) since
+ these forms are only for ABI=2.0w.
+
+ * longlong.h (count_leading_zeros) [__mcpu32__]: Check __mcpu32__ to
+ avoid bfffo on GCC 3.4 in CPU32 mode. Reported by Bernardo Innocenti.
+
+ * longlong.h (count_trailing_zeros) [x86_64]: Use "%q0" to force
+ 64-bit register destination. Pointed out by Torbjorn.
+
+ * mpz/combit.c: Correction to carry handling when extending a
+ negative, and use __GMPN_ADD_1. Correction to complement limb for a
+ negative when there's a non-zero low limb.
+ * tests/mpz/bit.c (check_clr_extend, check_com_negs): Exercise these.
+
+ * demos/perl/GMP.xs, demos/perl/GMP.pm, demos/perl/test.pl: Add
+ get_d_2exp.
+ * demos/perl/GMP.xs, demos/perl/GMP.pm, demos/perl/GMP/Rand.pm,
+ demos/perl/test.pl: Add gmp_urandomb_ui, gmp_urandomm_ui.
+ (GMP::Rand::randstate): Accept a randstate object to copy.
+ * demos/perl/GMP.xs, demos/perl/GMP.pm, demos/perl/GMP/Mpz.pm,
+ demos/perl/test.pl: Add combit, rootrem.
+
+2003-08-19 Torbjorn Granlund <tege@swox.com>
+
+ * tune/Makefile.am (EXTRA_DIST): Add amd64.asm.
+
+2003-08-17 Kevin Ryde <kevin@swox.se>
+
+ * gmpxx.h [__MPFR_H]: Include full <iostream> for inlines.
+ * tests/cxx/t-headfr.cc: New file, exercising this.
+ * tests/cxx/Makefile.am: Add it.
+
+ * tests/cxx/t-constr.cc: Include config.h for WANT_MPFR.
+
+ * gmpxx.h: Correction to temp variable type in mpf -> mpfr assignment.
+ Reported by Derrick Bass.
+ * tests/cxx/t-assign.cc (check_mpfr): Exercise this.
+
+ * configure.in (WANT_MPFR): AC_DEFINE this, for the benefit of
+ tests/cxx/t-*.cc. (Was always meant to have been defined.)
+ * tests/cxx/Makefile.am (INCLUDES): Add -I$(top_srcdir)/mpfr.
+
+ * gmpxx.h: __gmp_default_rounding_mode -> __gmpfr_default_rounding_mode
+ (struct __gmp_hypot_function): Correction to mpfr_hypot addition.
+ * tests/cxx/t-misc.cc (check_mpfr_hypot): Corrections to mpfr/long
+ tests.
+
+2003-08-16 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (amd64): New.
+
+ * mpn/amd64/gmp-mparam.h: New file.
+
+ * tune/amd64.asm: New file, derived in part from tune/pentium.asm.
+
+2003-08-15 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c (freq_irix_hinv): Reinstate, for the benefit of IRIX 6.2.
+ (freq_attr_get_invent): Conditionalize on INFO_LBL_DETAIL_INVENT too.
+
+2003-08-14 Kevin Ryde <kevin@swox.se>
+
+ * mpq/get_d.c: Use mpn_get_d.
+ * tests/mpq/t-get_d.c (check_onebit): New test.
+
+ * gmp.texi (Notes for Particular Systems): Under x86 cpu types, note
+ i386 is a fat binary, remove pentium4 recommendation since i386 is now
+ quite reasonable for p4.
+ (Notes for Particular Systems): Under Windows DLLs, remove caveat
+ about --enable-cxx now ok, update .lib creation for new libtool,
+ remove .exp not needed for MS C.
+ (Notes for Package Builds): i386 is a fat binary.
+ (Reentrancy): Remove SCO ctype.h note, don't want to list every system
+ misfeature, and was quite possibly for non-threading mode anyway.
+ (Autoconf): Remove notes on gmp 2 detection, too old to want to
+ encourage anyone to use.
+ (Karatsuba Multiplication): Correction to threshold increase/decrease
+ for a and b terms. Reported by Richard Brent and Paul Zimmermann.
+ Also add various further index entries.
+
+ * tune/freq.c (freq_attr_get_invent): New function.
+ (freq_irix_hinv): Remove, in favour or freq_attr_get_invent.
+ * configure.in (AC_CHECK_FUNCS): Add attr_get.
+ (AC_CHECK_HEADERS): Add invent.h, sys/attributes.h, sys/iograph.h.
+
+2003-08-03 Kevin Ryde <kevin@swox.se>
+
+ * tune/tuneup.c (tune_mul): Use MUL_KARATSUBA_THRESHOLD_LIMIT.
+
+2003-08-02 Kevin Ryde <kevin@swox.se>
+
+ * mpn/asm-defs.m4: Tweak some comments, add hpux11 to m4wrap 0xFF
+ problem systems.
+
+ * configure.in (*-*-sco3.2v5*): Remove lt_cv_archive_cmds_need_lc=no,
+ since libtool no longer uses it. This was a workaround fixing ctype.h
+ in SCO 5 shared libraries; not sure if libtool now gets it right on
+ its own, let's hope so.
+
+ * configure.in, acinclude.m4 (GMP_PROG_HOST_CC): Remove, libtool no
+ longer demands HOST_CC.
+
+ * configure.in: When C or C++ compiler not found, refer user to
+ config.log.
+
+ * configure.in (i386-*-*): Turn i386 into a fat binary build.
+ * mpn/x86/fat/fat.c, mpn/x86/fat/fat_entry.asm,
+ mpn/x86/fat/gmp-mparam.h, mpn/x86/fat/gcd_1.c, mpn/x86/fat/mode1o.c:
+ New files.
+ * gmp-impl.h (struct cpuvec_t) [x86 fat]: New structure.
+ * longlong.h (COUNT_LEADING_ZEROS_NEED_CLZ_TAB) [x86 fat]: Define.
+ * mpn/asm-defs.m4 (foreach): New macro.
+ * mpn/x86/x86-defs.m4 (CPUVEC_FUNCS_LIST): New define.
+ * mpn/x86/sqr_basecase.asm: New file, primarily as a fallback for fat
+ binaries.
+ * mpn/x86/p6/gmp-mparam.h, mpn/x86/p6/mmx/gmp-mparam.h: Add comments
+ about fat binary SQR_KARATSUBA_THRESHOLD for p6 and p6/mmx.
+
+ * configure.in: Add various supports for fat binaries, via fat_path,
+ fat_functions and fat_thresholds variables.
+ * acinclude.m4 (GMP_STRIP_PATH): Mung $fat_path too.
+ (GMP_FAT_SUFFIX, GMP_REMOVE_FROM_LIST): New macros.
+ * gmp-impl.h: Add various supports for fat binaries.
+ (DECL_add_n etc): New macros.
+ (mpn_mul_basecase etc): Define only if not already defined.
+ * mpn/asm-defs.m4 (m4_config_gmp_mparam): Mention fat binary.
+ (MPN): Use m4_unquote, for the benefit of fat binary name expansion.
+ * doc/configuration: Notes on fat binaries.
+ * gmp-impl.h (MUL_TOOM3_THRESHOLD_LIMIT): Define always.
+ (MUL_KARATSUBA_THRESHOLD_LIMIT): New define.
+ * mpn/generic/mul.c, mpn/generic/mul_n.c: Use these.
+ * tune/divrem1div.c, tune/divrem1inv.c, tune/mod_1_div.c,
+ tune/mod_1_inv.c: Define OPERATION_divrem_1 and OPERATION_mod_1, to
+ tell fat.h what's being done.
+
+ * config.guess (alpha-*-*): Update comments on what configfsf.guess
+ does and doesn't do for us.
+
+2003-07-31 Kevin Ryde <kevin@swox.se>
+
+ * config.guess: Remove $dummy.o files everywhere, in case vendor
+ compilers produce that even when not asked.
+
+ * demos/perl/GMP.xs (class_or_croak): Rename "class" parameter to
+ avoid C++ keyword.
+ (coerce_ulong, coerce_long): Move croaks to stop g++ 3.3 complaining
+ about uninitialized variables.
+
+ * demos/perl/INSTALL: Add notes on building with a DLL.
+
+ * longlong.h (count_trailing_zeros) [x86_64]: Ensure bsfq destination
+ is a 64-bit register. Diagnosed by Francois G. Dorais.
+
+2003-07-31 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h [ppc]: Remove nested test for vxworks.
+
+2003-07-24 Kevin Ryde <kevin@swox.se>
+
+ * gmpxx.h (struct __gmp_binary_multiplies): Use mpz_mul_si for
+ mpz*long and long*mpz.
+ * tests/cxx/t-ops.cc (check_mpz): Exercise mpz*long and mpz*ulong.
+
+ * cxx/ismpf.cc: Use std::locale decimal point when available. Expect
+ localeconv available always.
+ * tests/cxx/t-locale.cc: Enable check_input tests.
+
+ * gmpxx.h (struct __gmp_hypot_function): Use mpfr_hypot.
+ * tests/cxx/t-misc.cc (check_mpfr_hypot): New tests.
+
+ * tests/cxx/t-assign.cc, tests/cxx/t-binary.cc, tests/cxx/t-ops.cc,
+ tests/cxx/t-prec.cc, tests/cxx/t-ternary.cc, tests/cxx/t-unary.cc:
+ Include config.h for WANT_MPFR.
+
+ * tests/mpz/bit.c (check_single): Correction to a diagnostic print.
+
+2003-07-24 Niels Möller <nisse@lysator.liu.se>
+
+ * mpz/combit.c: New file.
+ * Makefile.am, mpz/Makefile.am: Add it.
+ * gmp-h.in (mpz_combit): Add prototype.
+ * tests/mpz/bit.c (check_single): Exercise mpz_combit.
+
+2003-07-16 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/get_d.c: Correction to infinity handling for large exp.
+
+2003-07-14 Kevin Ryde <kevin@swox.se>
+
+ * mpz/get_d.c, mpz/get_d_2exp.c, mpf/get_d.c, mpf/get_d_2exp.c: Use
+ mpn_get_d.
+
+ * mpn/generic/get_d.c: New file, based on mpz/get_d.c and insert-dbl.c.
+ * configure.in, mpn/Makefile.am: Add it.
+ * gmp-impl.h (mpn_get_d): Add prototype.
+
+ * tests/mpn/t-get_d.c: New file.
+ * tests/mpn/Makefile.am: Add it.
+
+ * tests/mpz/t-get_d_2exp.c (check_onebit, check_round): Test negatives.
+ (check_onebit): Add a few more bit sizes.
+
+ * tests/misc.c, tests/tests.h (tests_isinf): New function.
+
+2003-07-12 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (GMP_PROG_CXX_WORKS): Include $CPPFLAGS, same as
+ automake does in the actual build.
+
+ * acinclude.m4 (GMP_PROG_CXX_WORKS): In the namespace test, declare
+ namespace before trying to use. In std iostream test, provoke a
+ failure from Compaq C++ in pre-standard mode.
+
+2003-07-08 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Use separate compiles for various
+ known problems, and indicate to the user the reason for rejecting.
+ (GMP_PROG_CXX_WORKS): Ditto, and insist on being able to execute each
+ compiled program.
+
+2003-07-05 Kevin Ryde <kevin@swox.se>
+
+ * config.sub: Add comments to our alias transformations.
+
+ * configfsf.sub, configfsf.guess: Update to 2003-07-04.
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS, GMP_PROG_CC_WORKS_LONGLONG): Show
+ failing program in config.log, per other autoconf tests.
+
+ * configure.in (i786-*-*): Recognise as pentium4, per configfsf.sub.
+
+2003-06-28 Kevin Ryde <kevin@swox.se>
+
+ * mpz/get_d_2exp.c, mpf/get_d_2exp.c: Avoid res==1.0 when floats round
+ upwards.
+
+ * tests/mpz/t-get_d_2exp.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add it.
+ * tests/mpf/t-get_d_2exp.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+ * tests/x86call.asm, test/tests.h (x86_fldcw, x86_fstcw): New
+ functions.
+ * tests/misc.c, tests/tests.h (tests_hardware_getround,
+ tests_hardware_setround): New functions.
+
+2003-06-25 Kevin Ryde <kevin@swox.se>
+
+ * mpn/sparc64/dive_1.c: New file.
+
+ * mpn/sparc64/sparc64.h: New file.
+ * mpn/sparc64/mode1o.c: Remove things now in sparc64.h.
+
+ * mpfr/*: Update to mpfr cvs 2003-06-25.
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): In last change provoking gnupro
+ gcc, don't use ANSI style function definition.
+
+2003-06-22 Kevin Ryde <kevin@swox.se>
+
+ * mpn/pa32/hppa1_1/udiv.asm: Remove .proc, .entry, .exit and .procend,
+ handled by PROLOGUE and EPILOGUE. Comment out .callinfo, per other
+ asm files.
+
+ * gmpxx.h (mpz_class __gmp_binary_divides, __gmp_binary_modulus): Fix
+ long/mpz and long%mpz for dividend==LONG_MIN divisor==-LONG_MIN.
+ (mpz_class __gmp_binary_modulus): Fix mpz%long for negative dividend.
+ * tests/cxx/t-ops.cc (check_mpz): Add test cases for these, merging
+ operator/ and operator% sections for clarity.
+
+2003-06-21 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-06-21.
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Add code by Torbjorn provoking an
+ ICE from gcc 2.9-gnupro-99r1 under -O2 -mcpu=ev6.
+ * configure.in (alpha*-*-* gcc_cflags_cpu): Fallback on -mcpu=ev56 for
+ this compiler.
+
+ * gmpxx.h (get_d): Remove comments about long double, double is
+ correct for get_d, a future long double form would be get_ld.
+
+2003-06-19 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-06-19.
+
+ * mpn/generic/dive_1.c: Share src[0] fetch among all cases. No need
+ for separate final umul_ppmm in even case, make it part of the loop.
+
+ * mpz/get_d_2exp.c, mpq/set_si.c, mpq/set_ui.c: Nailify.
+
+ * mpf/iset_si.c: Rewrite using mpf/set_si.c code, in particular this
+ nailifies it.
+ * tests/mpf/t-set_si.c: Nailify tests.
+
+ * mpf/iset_ui.c: Nailify, as per mpf/set_ui.c
+ * tests/mpf/t-set_ui.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+
+2003-06-15 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-06-15.
+
+ * mpn/x86/k6/mode1o.asm: Remove a bogus ASSERT.
+
+2003-06-12 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (--enable-assert): Emit WANT_ASSERT to config.m4.
+ * mpn/powerpc32/powerpc-defs.m4, mpn/x86/x86-defs.m4 (ASSERT): Check
+ WANT_ASSERT is defined.
+
+ * mpn/sparc32/v9/udiv.asm: Amend heading, this file is for sparc v9.
+
+ * tests/cxx/Makefile.am (TESTS_ENVIRONMENT): In libtool openbsd hack,
+ discard error messages from cp, for the benefit of --disable-shared or
+ systems not using names libgmp.so.*.
+
+ * tests/devel/try.c (try_one): When overlapping, copy source data
+ after filling dst. Previously probably used only DEADVAL in
+ overlapping cases.
+
+2003-06-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/random2.c: Rewrite. Ignore sign of exp parameter.
+
+2003-06-10 Kevin Ryde <kevin@swox.se>
+
+ * mpn/sparc64/mode1o.c: New file.
+
+2003-06-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/lshift.asm: Add more cycle counts.
+ * mpn/powerpc32/rshift.asm: Add more cycle counts.
+
+ * mpn/ia64/addmul_1.asm: Reformat comments for 80 columns.
+
+ * gmp-impl.h (udiv_qrnnd_preinv1): New name for udiv_qrnnd_preinv.
+ (udiv_qrnnd_preinv2): New name for udiv_qrnnd_preinv2norm.
+ (udiv_qrnnd_preinv): New #define, making udiv_qrnnd_preinv2
+ the default.
+ * tune/speed.c: Corresponding changes.
+ * tune/speed.h: Likewise.
+ * tune/common.c: Likewise.
+
+ * mpf/get_str.c: Simplify `off' computation.
+
+ * longlong.h: Tabify.
+
+2003-06-09 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (ABI and ISA): FreeBSD has sparc64 too, just say "BSD" to
+ cover all flavours.
+ * configure.in: Ditto in some comments.
+
+ * mpfr/*: Update to mpfr cvs 2003-06-09.
+
+ * tests/cxx/Makefile.am (LDADD): Add -L$(top_builddir)/$(LIBS), for
+ the benefit of gcc 3.2 on itanium2-hp-hpux11.22.
+
+ * tune/many.pl (mul_2): Add speed routine settings.
+ (MAKEFILE): Close when done, for the benefit of development hackery.
+
+2003-06-08 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-06-08.
+
+ * mpn/x86/x86-defs.m4 (femms): Remove fallback to emms.
+ (cmovCC, psadbw): Remove simulated versions.
+ (cmov_available_p, psadbw_available_p): Remove.
+ This trickery was only ever for development purposes on machines
+ without those instructions. Removing it simplifies gmp and in
+ particular avoids complications for fat binary builds. Development
+ can be done with a wrapper around "as" if really needed.
+
+ * mpn/x86/divrem_1.asm: Don't use loop_or_decljnz, now K6 has its own
+ mpn/x86/k6/divrem_1.asm. Amend K6 comments now moved to there.
+ * mpn/x86/x86-defs.m4 (loop_or_decljnz): Remove, no longer used.
+
+ * mpn/x86/k6/divrem_1.asm: New file, derived from mpn/x86/divrem_1.asm.
+
+ * mpn/x86/k6/pre_mod_1.asm: Remove comments now in mpn/x86/mod_1.asm.
+
+ * mpn/x86/mod_1.asm: Put mpn_mod_1c after mpn_mod_1 for better branch
+ prediction. Put done_zero at end for less wastage in alignment. Use
+ decl+jnz unconditionally since in fact it's ok on k6. Amend comments.
+
+2003-06-07 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/mode1o.c: Fix ASSERTs on return value.
+
+ * gmp.texi (Build Options): Add viac3 and viac32 cpu types.
+ (ABI and ISA): Note on sparcv9 ABI=32 vs ABI=64 speed. More indexing.
+
+ * configfsf.guess, configfsf.sub: Update to 2003-06-06.
+ * config.guess: Remove $RANDOM hack supporting netbsd 1.4, not needed
+ by new configfsf.guess.
+
+2003-06-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/submul_1.asm: Add branch over .align block.
+
+2003-06-05 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (add_ssaaaa) [pa64]: Output zero operand as register 0.
+ Allow more immediate operands.
+ (sub_ddmmss) [pa64]: Likewise.
+ (add_ssaaaa) [pa32]: Likewise.
+ (sub_ddmmss) [pa32]: Likewise.
+
+ * mpn/pa64: Change ".level 2.0W" to ".level 2.0w" to please
+ picky GNU assembler.
+
+2003-06-05 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Integer Special Functions): In mpz_array_init, fix type
+ shown for integer_array and give an example use.
+
+2003-06-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/set_str.c (mpf_set_str): Work around gcc 2 bug triggered on
+ alpha.
+
+2003-06-03 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/README: Add 7 c/l mmx mul_1, tweak wordings.
+
+ * acinclude.m4 (GMP_C_DOUBLE_FORMAT): Use octal char constants in test
+ program, hex is not supported by K&R.
+
+2003-06-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/mips64/divrem_1.asm: New file.
+
+2003-06-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/lshift.asm: Reformat code.
+ * mpn/powerpc32/rshift.asm: Reformat code.
+
+2003-05-30 Kevin Ryde <kevin@swox.se>
+
+ * tests/misc.c (tests_start): Set stdout and stderr to unbuffered, to
+ avoid any chance of losing output on segv etc.
+
+2003-05-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/get_str.c: Move label `done' to match TMP_MARK and TMP_FREE.
+ Remove redundant variable prec.
+
+2003-05-26 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/convert.c: Test bases up to 62.
+
+ * tests/mpf/t-conv.c: Test bases up to 62.
+
+ * demos/pexpr.c: Don't iterate to get accurate timing.
+
+ * mpf/set_str.c (mpn_pow_1_highpart): Cleanup.
+
+ * mp_dv_tab.c: Fix typo.
+
+ * mpf/get_str.c: Rewrite (now sub-quadratic).
+
+2003-05-22 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpn/t-divrem_1.c: New file.
+ * tests/mpn/Makefile.am: Add it.
+
+2003-05-22 Torbjorn Granlund <tege@swox.com>
+
+ * config.sub: Recognize viac3* processors.
+
+2003-05-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/addmul_2.asm: New file.
+
+2003-05-19 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Recognize alphaev7* as alphaev67.
+
+ * config.guess: Recognize viac3* processors.
+ * configure.in: Set up path for viac3* processors.
+ * acinclude.m4 (X86_PATTERN): Include viac3* processors.
+
+2003-05-19 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c (freq_pstat_getprocessor): New function.
+ (freq_all): Use it.
+ * configure.in (AC_CHECK_HEADERS): Add sys/pstat.h.
+ (AC_CHECK_FUNCS): Add pstat_getprocessor.
+
+2003-05-15 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/mul_fft.c (mpn_mul_fft_decompose): Remove "inline",
+ since the code is a bit too big. gcc doesn't actually inline when
+ alloca (TMP_ALLOC) is used anyway.
+
+2003-05-13 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Notes for Particular Systems): Libtool directory is .libs
+ not _libs for mingw dll. Reported by Andreas Fabri.
+
+2003-05-07 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Add code to generate sse2/xmm code
+ from gcc -march=pentium4, to check the assembler supports that.
+ (GMP_GCC_PENTIUM4_SSE2, GMP_OS_X86_XMM): New macros.
+ * configure.in (pentium4-*-*): Use them to see if gcc -march=pentium4
+ (with sse2) is ok.
+
+2003-05-06 Kevin Ryde <kevin@swox.se>
+
+ * mpz/com.c: Rate size==0 as UNLIKELY, fix comment to mpn_add_1.
+
+ * tune/freq.c (<sys/sysinfo.h>): Include only when needed for
+ getsysinfo(), to avoid a problem with this file on AIX 5.1.
+
+2003-05-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/set_str.c: Do not ignore supposedly superfluous digits (in part
+ reverting last change).
+
+2003-05-03 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi: Use @code for files in @cindex entries, it looks nicer
+ than @file.
+
+ * Makefile.am: Note gmp 4.1.1 and 4.1.2 version info.
+
+ * configure.in, acinclude.m4 (GMP_CRAY_OPTIONS): New macro for Cray
+ system setups, letting AC_REQUIRE do its job instead of a hard coded
+ AC_PROG_EGREP.
+
+ * config.guess: Amend fake RANDOM to avoid ". configfsf.guess" which
+ segfaults on Debian "ash" 0.4.16.
+
+2003-05-01 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_CHECK_FUNCS): Add getsysinfo.
+ (AC_CHECK_HEADERS): Add sys/sysinfo.h and machine/hal_sysinfo.h.
+ * tune/freq.c (freq_getsysinfo): New function.
+ (freq_all): Use it.
+ (freq_sysctlbyname_i586_freq, freq_sysctlbyname_tsc_freq,
+ freq_sysctl_hw_cpufrequency, freq_sysctl_hw_model): Set
+ speed_cycletime before trying to print it, when verbose.
+
+2003-04-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/set_str.c: Major overhaul.
+ (mpn_pow_1_highpart): New helper function, meat extracted from
+ mpf_set_str.
+
+2003-04-24 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_GCC_ARM_UMODSI): Quote result string against m4.
+
+ * configure, ltmain.sh, aclocal.m4: Update to libtool 1.5.
+
+ * longlong.h (add_ssaaaa) [all]: Remove first "%" commutative in each,
+ since gcc only supports one per asm.
+
+ * printf/doprnt.c: Add M for mp_limb_t.
+ * tests/misc/t-printf.c: Exercise this.
+
+ * tests/mpz/t-cmp_d.c: Test infinities.
+ * tests/mpf/t-cmp_d.c: New file.
+ * tests/mpf/Makefile.am: Add it.
+
+ * mpz/cmp_d.c, mpz/cmpabs_d.c, mpf/cmp_d.c: NaN invalid, Inf bigger
+ than any value.
+ * mpz/set_d.c, mpq/set_d.c, mpf/set_d.c: Nan or Inf invalid.
+
+ * configure.in (AC_CHECK_FUNCS): Add raise.
+ * invalid.c: New file.
+ * Makefile.am: Add it.
+ * gmp-impl.h (__gmp_invalid_operation): Add prototype.
+ (DOUBLE_NAN_INF_ACTION): New macro.
+
+ * tests/trace.c, tests/tests.h (d_trace): New function.
+ * tests/misc.c, tests/tests.h (tests_infinity_d): New function.
+ * tests/misc.c (mpz_erandomb, mpz_errandomb): Use gmp_urandomm_ui.
+
+ * tune/tuneup.c, tune/common.c, tests/devel/try.c: Cast various
+ mp_size_t values for printf %ld in case mp_size_t==int. Use
+ gmp_printf for mp_limb_t values.
+
+ * gmp.texi (Nomenclature and Types): Add mp_exp_t, mp_size_t,
+ gmp_randstate_t. Note ulong for bit counts and size_t for byte
+ counts. Don't bother with @noindent.
+ (Debugging): New valgrind is getting MMX/SSE.
+ (Integer Comparisons): mpz_cmp_d and mpz_cmpabs_d on NaNs and Infs.
+ (Float Comparison): mpf_cmp_d behaviour on NaNs and Infs.
+ (Low-level Functions): Note with mpn_hamdist what hamming distance is.
+ (Formatted Output Strings): Add type M.
+ (Internals): Remove remarks on ulong bits and size_t bytes. Move int
+ field remarks to ...
+ (Integer Internals, Float Internals): ... here.
+
+2003-04-19 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (*sparc*-*-* ABI=32): Add umul to extra_functions.
+
+ * mpn/x86/p6/mul_basecase.asm: New file.
+
+2003-04-18 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (m68060-*-*): Fallback to gcc -m68000 when -m68060 not
+ available, and don't use mpn/m68k/mc68020 asm routines. (Avoids 32x32
+ mul and 64/32 div which trap to the kernel on 68060. Advice by
+ Richard Zidlicky.)
+ * mpn/m68k/README: Update notes on directory usage.
+
+ * tests/cxx/Makefile.am (TESTS_ENVIRONMENT): Add a hack to let the
+ test programs run with a shared libgmpxx on openbsd 3.2.
+
+ * gmp.texi (Language Bindings): Add Guile.
+
+2003-04-12 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (cygwin*, mingw*, pw32*, os2*): Add
+ -Wl,--export-all-symbols to GMP_LDFLAGS, no longer the default in
+ latest mingw and libtool.
+
+ * acinclude.m4 (GMP_ASM_COFF_TYPE): New macro.
+ * configure.in (x86s): Use it.
+ * mpn/x86/x86-defs.m4 (COFF_TYPE): New macro.
+ (PROLOGUE_cpu): Use it, for the benefit of mingw DLLs.
+
+ * gmp-impl.h (mpn_copyi, mpn_copyd): Add __GMP_DECLSPEC.
+
+ * gmp.texi (Known Build Problems): Remove windows test program .exe
+ repeated built, fixed by new libtool. Remove MacOS C++ shared library
+ creation, fixed by new libtool.
+ (Notes for Package Builds, Known Build Problems): Remove DESTDIR notes
+ on libgmpxx, fixed in new libtool.
+
+2003-04-10 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Match turbosparc.
+ * config.guess: Recognize turbosparc (just for *bsd for now).
+
+2003-04-09 Kevin Ryde <kevin@swox.se>
+
+ * mpf/mul_ui.c [nails]: Call mpf_mul to handle v > GMP_NUMB_MAX.
+
+ * tests/mpz/t-mul.c (main): Don't try FFT sizes when FFT disabled via
+ MP_SIZE_T_MAX, eg. for nails.
+
+ * tests/cxx/t-ternary.cc: Split up tests to help compile speed and
+ memory usage.
+
+ * tests/devel/try.c: Print seed under -R, add -E to reseed, use ulong
+ for seed not uint.
+
+ * gmp.texi: Add @: after various abbreviations, more index entries.
+ (leftarrow): New macro, for non-tex.
+ (Random State Initialization): Remove commented gmp_randinit_lc, not
+ going to be implemented.
+ (Random Number Algorithms): New section.
+ (References): Add Matsumoto and Nishimura on Mersenne Twister, add
+ Bertot, Magaud and Zimmermann on GMP Square Root.
+
+2003-04-06 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpz/t-gcd_ui.c: New file.
+ * tests/mpz/Makefile.am: Add it.
+
+ * mpz/gcd_ui.c: Correction to return value on longlong limb systems,
+ limb might not fit a ulong.
+
+2003-04-04 Kevin Ryde <kevin@swox.se>
+
+ * configure, aclocal.m4, ltmain.sh: Update to libtool cvs snapshot
+ 2003-04-02.
+
+2003-04-02 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (*-*-cygwin*): No longer force lt_cv_sys_max_cmd_len,
+ libtool has addressed this now.
+ (AC_PROVIDE_AC_LIBTOOL_WIN32_DLL): Remove this, libtool _LT_AC_LOCK
+ no longer needs it.
+
+ * acinclude.m4 (GMP_PROG_AR): Also set ac_cv_prog_AR and
+ ac_cv_prog_ac_ct_AR when adding flags to AR, so they're not lost by
+ libtool's call to AC_CHECK_TOOL.
+
+2003-04-01 Kevin Ryde <kevin@swox.se>
+
+ * configure, aclocal.m4, ltmain.sh: Update to libtool cvs snapshot
+ 2003-03-31.
+
+ * configure.in (AC_PROG_F77): Add a dummy AC_PROVIDE to stop libtool
+ running F77 probes.
+
+ * randlc2x.c (gmp_rand_lc_struct): Add comments about what exactly is
+ in each field.
+ (randseed_lc): Rename seedp to seedz to avoid confusion with seedp in
+ the lc function. Suggested by Pedro Gimeno.
+ (gmp_randinit_lc_2exp): Use __GMP_ALLOCATE_FUNC_TYPE. No need for
+ "+1" in mpz_init2 of _mp_seed. Don't bother with mpz_init2 for _mp_a.
+
+2003-03-29 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (m68k-*-*): Use -O2, no longer need to fallback to -O.
+ * acinclude.m4 (GMP_GCC_M68K_OPTIMIZE): Remove macro.
+
+ * configure.in (AC_CHECK_TYPES): Add notes on why tested.
+
+ * gmp.texi (GMPrefu, GMPpxrefu, GMPreftopu, GMPpxreftopu): New macros,
+ use them for all external references to get URLs into HTML output.
+ (Random State Initialization): Add gmp_randinit_set.
+ (Random State Miscellaneous): New section.
+
+2003-03-29 Kevin Ryde <kevin@swox.se>
+
+ * randbui.c, randmui.c: New files.
+ * Makefile.am: Add them.
+ * gmp-h.in (gmp_urandomb_ui, gmp_urandomm_ui): Add prototypes.
+ * tests/rand/t-urbui.c, tests/rand/t-urmui.c: New files.
+ * tests/rand/Makefile.am: Add them.
+
+ * gmp-impl.h (gmp_randstate_srcptr): New typedef.
+ (gmp_randfnptr_t): Add randiset_fn.
+ * randiset.c: New file.
+ * Makefile.am: Add it.
+ * gmp-h.in (gmp_randinit_set): Add prototype.
+ * randlc2x.c, randmt.c: Add gmp_randinit_set support.
+ * tests/rand/t-iset.c: New file.
+ * tests/rand/Makefile.am: Add it.
+
+ * tests/misc.c, tests/tests.h (call_rand_algs): New function.
+
+2003-03-27 Kevin Ryde <kevin@swox.se>
+
+ * mpz/bin_uiui.c: Use plain "*" for kacc products rather than
+ umul_ppmm since high not needed, except for an ASSERT now amended.
+
+2003-03-26 Kevin Ryde <kevin@swox.se>
+
+ * demos/expr/exprfr.c (cbrt, cmpabs, exp2, gamma, nextabove,
+ nextbelow, nexttoward): New functions.
+ * demos/expr/t-expr.c: Exercise these.
+
+ * mpfr/*: Update to mpfr cvs 2003-03-26.
+
+ * gmp-impl.h (MPZ_REALLOC): Use UNLIKELY, to expect no realloc.
+
+ * tune/time.c (cycles_works_p): Scope variables down to relevant part
+ to avoid warnings about unused.
+
+ * configfsf.guess, configfsf.sub: Update to 2003-02-22.
+ * config.guess: Fake a $RANDOM variable when running configfsf.guess,
+ to workaround a problem on m68k NetBSD 1.4.1.
+
+ * mpz/fac_ui.c: Remove unused variable "z1".
+
+ * tune/freq.c (freq_irix_hinv): Allow "Processor 0" line from IRIX 6.5.
+
+2003-03-24 Torbjorn Granlund <tege@swox.com>
+
+ * randlc2x.c (randget_lc): Remove write-only variable rn.
+ * mpf/eq.c: Remove write-only variable usign.
+ * gen-psqr.c (main): Remove write-only variable numb_bits.
+
+2003-03-17 Torbjorn Granlund <tege@swox.com>
+
+ * Makefile.am (libgmp_la_SOURCES): Add mp_dv_tab.c.
+ (libmp_la_SOURCES): Add mp_dv_tab.c.
+
+ * mpn/alpha/invert_limb.asm: Add a few comments.
+
+ * mp_dv_tab.c: New file, defining __gmp_digit_value_tab.
+
+ * mpz/set_str.c: Get rid of function digit_value_in_base and use table
+ __gmp_digit_value_tab instead.
+ * mpz/inp_str.c: Likewise.
+ * mpf/set_str.c: Likewise.
+ * mpbsd/min.c: Likewise.
+ * mpbsd/xtom.c: Likewise.
+
+ * mpz/set_str.c: Allow bases <= 62. Return error for invalid bases.
+ * mpz/inp_str.c: Likewise.
+ * mpf/set_str.c: Likewise.
+ * mpz/out_str.c: Likewise.
+ * mpz/get_str.c: Likewise.
+ * mpf/get_str.c: Likewise.
+
+ * mpz/inp_str.c: Restructure to allocate more string space just
+ before needed.
+ * mpbsd/min.c: Likewise.
+
+ * longlong.h (__udiv_qrnnd_c): Remove redundant casts.
+ (32-bit sparc): Test HAVE_HOST_CPU_supersparc in addition to various
+ sparc_v8 spellings.
+
+2003-03-17 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-03-17.
+
+2003-03-15 Kevin Ryde <kevin@swox.se>
+
+ * Makefile.am (EXTRA_libgmp_la_SOURCES): Use this for TMP_ALLOC
+ sources, instead of a libdummy.la.
+
+2003-03-16 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Recognize supersparc and microsparc for *BSD systems.
+ Generalize some superscalar recognition patterns.
+
+2003-03-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/udiv.asm: New file.
+
+2003-03-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64: Table cycle counts. Update some comments.
+
+ * mpn/powerpc64/divrem_1.asm: New file.
+
+2003-03-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul.c (mpn_mul): Don't blindly expect
+ MUL_KARATSUBA_THRESHOLD to be a constant.
+
+2003-03-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul.c (mpn_mul): New operand splitting code for
+ avoiding cache misses when un >> MUL_KARATSUBA_THRESHOLD > vn.
+ (MUL_BASECASE_MAX_UN): New #define, default to 500 for now.
+
+2003-03-07 Kevin Ryde <kevin@swox.se>
+
+ * Makefile.am: Put gmp.h and mp.h under $(exec_prefix)/include.
+ * gmp.texi (Build Options): Add notes on this.
+ Reported by Vincent Lefèvre.
+
+2003-03-06 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (alpha*-*-* gcc): Add asm option before testing -mcpu,
+ for the benefit of gcc 2.9-gnupro-99r1 on alphaev68-dec-osf5.1 which
+ doesn't otherwise put the assembler in the right mode for -mcpu=ev6.
+
+2003-03-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/powerpc-defs.m4: Set up renaming for v registers.
+
+ * mpz/powm.c (redc): Instead of repeated mpn_incr_u invocations,
+ accumulate carries and add at the end.
+ (mpz_powm): Trim tp allocation, now as redc doesn't need carry guard.
+
+2003-02-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/copyd.asm: Correct header comment.
+
+ * mpn/arm/addmul_1.asm: Correct cycle counts.
+ * mpn/arm/submul_1.asm: Likewise.
+
+2003-02-20 Kevin Ryde <kevin@swox.se>
+
+ * demos/factorize.c (factor_using_pollard_rho): Test k>0 to avoid
+ infinite loop if k=0 and gcd!=1 reveals a factor. Reported by John
+ Pongsajapan.
+
+ * gmp.texi, fdl.texi: Update to FDL version 1.2.
+
+2003-02-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/arm/mul_1.asm: Fix typo introduced in last change.
+
+2003-02-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/gmp-mparam.h: Retune.
+
+ * mpn/sparc64/copyi.asm: Add some header comments.
+ * mpn/sparc64/copyd.asm: Likewise.
+
+ * mpn/arm/mul_1.asm: Put vl operand last for umull/umlal.
+ Add some header comments.
+ * mpn/arm/addmul_1.asm: Rewrite.
+ * mpn/arm/submul_1.asm: Rewrite.
+ * mpn/arm/gmp-mparam.h: Retune.
+
+2003-02-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/arm/copyi.asm: New file.
+ * mpn/arm/copyd.asm: New file.
+
+2003-02-16 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_C_DOUBLE_FORMAT): Tolerate incorrect last data
+ byte seen on an arm system.
+
+2003-02-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/arm/gmp-mparam.h: Retune.
+
+2003-02-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/750/com_n.asm: Add more cycle counts.
+
+2003-02-13 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_PREREQ): Bump to 2.57.
+
+ * configure.in, acinclude.m4 (GMP_GCC_WA_OLDAS): New macro, applying
+ -Wa,-oldas only when necessary.
+
+ * configure.in (powerpc*-*-*): Don't use -Wa,-mppc with gcc, it
+ overrides options recent gcc adds for -mcpu, making generated code
+ fail to assemble.
+
+ * tune/tuneup.c (mpn_fft_table): Remove definition, it's in mul_fft.c.
+
+2003-02-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/gmp-mparam.h: Retune.
+ * mpn/x86/k7/gmp-mparam.h: Retune.
+ * mpn/x86/k6/gmp-mparam.h: Retune.
+ * mpn/x86/p6/gmp-mparam.h: Retune.
+ * mpn/x86/p6/mmx/gmp-mparam.h: Retune.
+
+ * tests/mpz/t-mul.c (main): Rewrite FFT testing code.
+
+2003-02-10 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Recognize "power2" systems.
+
+ * mpn/powerpc64/gmp-mparam.h: Fix indentation.
+ * mpn/power/gmp-mparam.h: Retune.
+ * mpn/alpha/ev6/nails/gmp-mparam.h: Retune.
+ * mpn/sparc64/gmp-mparam.h: Retune.
+ * mpn/pa64/gmp-mparam.h: Retune.
+ * mpn/sparc32/v8/supersparc/gmp-mparam.h: Retune.
+ * mpn/sparc32/v8/gmp-mparam.h: Retune.
+ * mpn/mips64/gmp-mparam.h: Retune.
+ * mpn/alpha/ev6/gmp-mparam.h: Retune.
+ * mpn/powerpc32/gmp-mparam.h: Retune.
+ * mpn/powerpc32/750/gmp-mparam.h: Retune.
+ * mpn/alpha/ev5/gmp-mparam.h: Retune.
+ * mpn/m68k/gmp-mparam.h: Retune.
+ * mpn/cray/gmp-mparam.h: Set GET_STR_PRECOMPUTE_THRESHOLD.
+
+ * configure.in: Undo this, problem doesn't happen any more:
+ (mips64*-*-*): Pass just -O1 to cc, to work around compiler bug.
+
+2003-02-03 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (MPN_NORMALIZE, MPN_NORMALIZE_NOT_ZERO): Add parens
+ around macro parameters. Reported by Jason Moxham.
+
+2003-02-01 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Low-level Functions): No overlap permitted by mpn_mul_n.
+ Reported by Jason Moxham.
+ (Formatted Input Strings): Correction to strtoul cross reference
+ formatting.
+ (BSD Compatible Functions): Add index entry for MINT.
+
+2003-01-29 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (mpn_mul_fft): Now returns int.
+
+2003-01-29 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpn/generic/mul_fft.c: Major rewrite.
+
+2003-01-25 Kevin Ryde <kevin@swox.se>
+
+ * config.guess (powerpc*-*-*): Remove $dummy.core file when mfpvr
+ fails on NetBSD.
+ (trap): Remove $dummy.core on abnormal termination too.
+
+ * mpfr/*: Update to mpfr cvs 2003-01-25.
+
+2003-01-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/README: Update cycle counts to match current code.
+
+2003-01-18 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-01-18.
+
+2003-01-17 Torbjorn Granlund <tege@swox.com>
+
+ * gmp.texi: Canonicalize URLs.
+
+2003-01-15 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Notes for Particular Systems): Add hardware floating point
+ precision mode.
+
+ * mpfr/*, configure, aclocal.m4, config.in: Update to mpfr cvs
+ 2003-01-15.
+
+2003-01-11 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to mpfr cvs 2003-01-11.
+
+2003-01-09 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/get_str.c: Update to mpfr cvs 2003-01-09.
+
+ * doc/configuration: Various updates.
+
+2003-01-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/copyi.asm: Avoid `nop' mnemonic, unsupported on Cray.
+ * mpn/alpha/copyd.asm: Likewise.
+
+2003-01-05 Kevin Ryde <kevin@swox.se>
+
+ * demos/expr/t-expr.c (check_r): Tolerate mpfr_set_str new return
+ value.
+
+ * configure, aclocal.m4 (*-*-osf4*, *-*-osf5*): Regenerate with
+ libtool patch to avoid bash printf option problem when building shared
+ libraries with cxx.
+
+ * configure.in (pentium4-*-*): Use "-march=pentium4 -mno-sse2" since
+ sse2 causes buggy code from gcc 3.2.1 and is only supported on new
+ enough kernels.
+
+ * acinclude.m4 (GMP_PROG_NM): Add some notes about failures, per
+ report by Krzysztof Kozminski.
+
+ * gmp-h.in (mpz_mdivmod_ui, mpz_mmod_ui): Add parens around "r".
+
+ * gmp-h.in (__GMP_CAST): New macro, clean to g++ -Wold-style-cast.
+ (GMP_NUMB_MASK, mpz_cmp_si, mpq_cmp_si, mpz_odd_p, mpn_divexact_by3,
+ mpn_divmod): Use it. Reported by Krzysztof Kozminski.
+ (mpz_odd_p): No need for the outermost cast to "int".
+ * tests/cxx/t-cast.cc: New file.
+ * tests/cxx/Makefile.am: Add it.
+
+2003-01-04 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/set_str.c: Update to mpfr cvs 2003-01-04.
+
+ * demos/expr/exprfra.c (e_mpfr_number): Tolerate recent mpfr_set_str
+ returning count of characters accepted.
+
+2003-01-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/copyi.asm: New file.
+ * mpn/alpha/copyd.asm: New file.
+
+2003-01-03 Kevin Ryde <kevin@swox.se>
+
+ * demos/expr/t-expr.c: Use __gmpfr on some mpfr internals that have
+ changed.
+
+ * mpfr/*, aclocal.m4, config.in, configure: Update to mpfr cvs
+ 2003-01-03.
+
+ * gmp.texi (Introduction to GMP): Mention release announcements
+ mailing list, and put home page and ftp before mailing lists.
+
+2002-12-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_fft.c (mpn_fft_next_size): Simplify.
+
+2002-12-28 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (M68K_PATTERN): New macro.
+ (GMP_GCC_M68K_OPTIMIZE): Use it to avoid m6811 and friends.
+ * configure.in: Ditto.
+
+ * tests/mpz/t-import.c, tests/mpz/t-export.c: Use '\xHH' to avoid
+ warnings about char overflows.
+ * acinclude.m4 (GMP_C_DOUBLE_FORMAT): Ditto.
+
+2002-12-28 Pedro Gimeno <pggimeno@wanadoo.es>
+
+ * randmt.c (randseed_mt, default_state): Fix off-by-one bug on padding.
+ (randseed_mt): Add ASSERT checking result of mpz_export.
+
+2002-12-24 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Integer Import and Export): Clarify treatment of signs,
+ reported by Kent Boortz.
+
+ * randmt.c: Use gmp_uint_least32_t.
+ (randseed_mt): Add nails to mpz_export in case mt[i] more than 32 bits.
+
+ * gmp-impl.h (gmp_uint_least32_t): New typedef, replacing GMP_UINT32.
+ * configure.in (AC_CHECK_TYPES): Add uint_least32_t.
+ (AC_CHECK_SIZEOF): Add unsigned short.
+
+2002-12-22 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (ULONG_PARITY) [generic C]: Mask result to a single bit.
+ (ULONG_PARITY) [_CRAY, __ia64]: New macros.
+ * tests/t-parity.c: New test.
+ * tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * longlong.h (count_trailing_zeros) [ia64]: New macro.
+
+ * tests/t-count_zeros.c (check_various): Remove unused variable "n".
+
+ * mpn/x86/README: Revise notes on PIC, PLT and GOT.
+
+ * demos/perl/GMP.xs, demos/perl/GMP.pm, demos/perl/test.pl: Add "mt"
+ to GMP::Rand::randstate.
+
+2002-12-22 Pedro Gimeno <pggimeno@wanadoo.es>
+
+ * randmt.c (randseed_mt): Fix bug that might cause the generator to
+ return all zeros with certain seeds. Fix WARM_UP==0 case.
+ (gmp_randinit_mt): Initialize to a known state by default.
+ (randget_mt): Remove check for uninitialized buffer: no longer needed.
+ (recalc_buffer): Use ?: instead of two-element array.
+
+ * tests/rand/t-mt.c: New test.
+ * tests/rand/Makefile.am (check_PROGRAMS): Add it.
+
+2002-12-21 Kevin Ryde <kevin@swox.se>
+
+ * cxx/osdoprnti.cc: Use <cstdarg> and <cstring> rather than <stdarg.h>
+ and <string.h>. No need for <stdio.h>.
+
+ * demos/expr/expr.c, demos/expr/exprfa.c, demos/expr/exprfra.c,
+ demos/expr/exprza.c: Use mp_get_memory_functions, not
+ __gmp_allocate_func etc.
+ * demos/expr/t-expr.c: Don't use gmp-impl.h.
+ (numberof): New macro.
+
+ * gmp-h.in, gmp-impl.h (__gmp_allocate_func, __gmp_reallocate_func,
+ __gmp_free_func): Move declarations to gmp-impl.h
+
+ * mp_get_fns.c: New file.
+ * Makefile.am (libgmp_la_SOURCES, libmp_la_SOURCES): Add it.
+ * gmp-h.in (mp_get_memory_functions): Add prototype.
+ * gmp.texi (Custom Allocation): Add mp_get_memory_functions, refer to
+ "free" not "deallocate" function.
+ * gmpxx.h (struct __gmp_alloc_cstring): Use mp_get_memory_functions,
+ not __gmp_free_func.
+
+ * gmp-impl.h [__cplusplus]: Add <cstring> for strlen.
+ (gmp_allocated_string): Hold length in a field.
+ * cxx/osdoprnti.cc, cxx/osmpf.cc: Use this.
+
+2002-12-20 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-perfsqr.c (check_sqrt): Print more variables upon
+ failure.
+
+ * mpn/generic/rootrem.c: In Newton loop, pad qp with leading zero.
+
+2002-12-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/rootrem.c: Allocate 1.585 (log2(3)) times more space
+ for pp temporary to allow for worst case overestimate of root.
+ Add some asserts.
+
+ * tests/mpz/t-root.c: Generalize and speed up.
+
+2002-12-19 Kevin Ryde <kevin@swox.se>
+
+ * tests/cxx/t-rand.cc (check_randinit): Add gmp_randinit_mt test.
+
+ * gmp-h.in: Don't bother trying to support Compaq C++ in pre-standard
+ I/O mode.
+ * gmp.texi (Notes for Particular Systems): Compaq C++ must be used in
+ "standard" iostream mode.
+
+2002-12-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/mod_34lsub1.asm: Add code for big-endian, using existing
+ little-endian code only if HAVE_LIMB_LITTLE_ENDIAN is defined.
+
+2002-12-18 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (HAVE_LIMB_BIG_ENDIAN, HAVE_LIMB_LITTLE_ENDIAN): New
+ defines in config.m4.
+
+2002-12-17 Torbjorn Granlund <tege@swox.com>
+
+ * printf/printffuns.c (gmp_fprintf_reps): Make it actually work
+ for padding > 256.
+
+2002-12-17 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c: Add <string.h> for memcmp.
+
+ * mpz/pprime_p.c: Use MPN_MOD_OR_MODEXACT_1_ODD.
+
+ * gmp.texi (Formatted Output Strings): %a and %A are C99 not glibc.
+ (Formatted Input Strings): Type "l" is for double too. Hex floats are
+ accepted for mpf_t.
+ (Formatted Input Functions): Describe tightened parse rule, clarify
+ return value a bit.
+
+ * scanf/doscan.c: Add hex floats, tighten matching to follow C99, for
+ instance "0x" is no longer acceptable to "%Zi".
+ Rename "invalid" label to avoid "invalid" variable, SunOS cc doesn't
+ like them the same.
+ * tests/misc/t-scanf.c: Update tests.
+ * tests/misc/t-locale.c (check_input): Don't let "0x" appear from fake
+ decimal point.
+
+ * config.guess (sparc*-*-*): Look at BSD sysctl hw.model to recognise
+ ultrasparcs.
+
+ * mpfr/tests/dummy.c: New file.
+ * mpfr/tests/Makefile.am (libfrtests_a_SOURCES): Add it.
+
+2002-12-14 Kevin Ryde <kevin@swox.se>
+
+ * mpbsd/Makefile.am (nodist_libmpbsd_la_SOURCES): Move these mpz
+ sources to libmpbsd_la_SOURCES directly, automake 1.7.2 now gets the
+ ansi2knr setups right for sources in other directories.
+
+ * mpfr/tests/Makefile.am: Add libfrtests.a in preparation for new mpfr.
+
+2002-12-13 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/Makefile.am (mpfr_TEXINFOS, AM_MAKEINFOFLAGS): Allow for
+ fdl.texi in recent mpfr.
+
+ * configure.in (AC_PROG_EGREP): Ensure this is run outside the Cray
+ conditional AC_EGREP_CPP.
+
+ * configure.in (alpha*-*-*): Use gcc -Wa,-oldas if it works, to avoid
+ problems with new compaq "as" on OSF 5.1.
+
+ * mpn/Makefile.am (EXTRA_DIST): Remove Makeasm.am, automake 1.7.2 does
+ it automatically.
+
+ * acinclude.m4 (AC_LANG_FUNC_LINK_TRY(C)): Remove this hack, fixed by
+ autoconf 2.57.
+
+ * configure.in (AC_CONFIG_LIBOBJ_DIR): Set to mpfr, for the benefit of
+ new mpfr using LIBOBJ.
+
+ * configure.in: (AM_INIT_AUTOMAKE): Use "gnu no-dependencies
+ $(top_builddir)/ansi2knr".
+ * */Makefile.am (AUTOMAKE_OPTIONS): Remove, now in configure.in.
+
+ * configure, config.in, INSTALL.autoconf: Update to autoconf 2.57.
+ * */Makefile.in, configure, aclocal.m4, install-sh, mkinstalldirs:
+ Update to automake 1.7.2.
+
+ * gmp.texi (Build Options): Add hppa64 to cpu types.
+ (ABI and ISA): Add gcc to hppa 2.0.
+ (Debugging): Add maximum debuggability config options.
+ (Language Bindings): Add Arithmos, reported by Johan Vervloet.
+ (Formatted Output Strings): 128 bits is about 40 digits, ll is only
+ for long long not long double.
+ (Formatted Input Strings): ll is only for long long not long double.
+
+ * mpz/divis.c, mpz/divis_ui.c, mpz/cong.c, mpz/cong_ui.c: Allow d=0,
+ under the rule n==c mod d iff exists q satisfying n=c+q*d.
+ * gmp.texi (Integer Division): Describe this.
+ Suggested by Jason Moxham.
+
+2002-12-13 Pedro Gimeno <pggimeno@wanadoo.es>
+
+ * randlc2x.c (lc): Remove check for seedn < an, which is now
+ superfluous. Add ASSERT to ensure it's correct. Add ASSERT to check
+ precondition of __GMPN_ADD.
+ (gmp_randinit_lc_2exp): Avoid reallocation by allocating one extra bit
+ for both seed and a. Simplify seedn < p->_cn case.
+
+ * tests/rand/t-lc2exp.c (check_bigs): Test negative seeds.
+
+2002-12-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa32/pa-defs.m4 (PROLOGUE_cpu): Zap spurious argument to `.proc'.
+ Add empty `.callinfo'.
+
+2002-12-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/addmul_1.asm: Don't reuse `ret' symbol for a
+ label.
+
+2002-12-11 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (hppa*-*-*): Don't use gcc -mpa-risc-2-0 in ABI=1.0.
+
+ * mpn/pa32/pa-defs.m4: New file, arranging for .proc/.procend.
+ * configure.in (hppa*-*-*): Use it.
+
+ * printf/doprnt.c: Comments on "ll" versus "L".
+
+ * tests/mpz/t-div_2exp.c: Reduce tests, especially the random ones.
+
+2002-12-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/get_d.c (limb2dbl): New macro for conversion to `double'.
+ Define it to something non-trivial for 64-bit hppa.
+ * mpq/get_d.c: Likewise.
+ * mpf/get_d.c: Likewise.
+
+ * mpn/x86/pentium4/sse2/addmul_1.asm: Unroll to save one c/l.
+
+2002-12-09 Kevin Ryde <kevin@swox.se>
+
+ * tune/Makefile.am: Don't use -static under --disable-static, it tends
+ not to work.
+ * configure.in (ENABLE_STATIC): New AM_CONDITIONAL.
+
+ * gmp-h.in: Use <iostream> instead of <iosfwd> with Compaq C++ in
+ pre-standard I/O mode.
+
+ * tests/mpz/t-jac.c, tests/mpz/t-scan.c: Reduce tests.
+
+2002-12-08 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (*-*-ultrix*): Remove forcible --disable-shared,
+ believe this was a generic problem with libtool, now gone.
+
+2002-12-08 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (USE_LEADING_REGPARM): Disable for PIC code generation.
+
+2002-12-07 Torbjorn Granlund <tege@swox.com>
+
+ * tests/cxx/t-misc.cc (check_mpq): Use 0/1 for canonical 0 in
+ mpq_cmp_ui calls.
+
+ * configure.in (hppa2.0*-*-*): Pass +O2 instead of +O3 to work around
+ compiler bug with mpfr/tests/tdiv.
+
+2002-12-07 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (hppa2.0*-*-* ABI=2.0n): Make -mpa-risc-2-0 optional.
+ New hppa-level-2.0 test using GMP_HPPA_LEVEL_20 to detect assembler
+ support for 2.0n.
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Add code that provokes an error
+ from gcc -mpa-risc-2-0 if the assembler doesn't know 2.0 instructions.
+ (GMP_HPPA_LEVEL_20): New macro.
+
+2002-12-07 Pedro Gimeno <pggimeno@wanadoo.es>
+
+ * gmp-impl.h (gmp_randfnptr_t.randseed_fn) Return void.
+ (LIMBS_PER_ULONG, MPN_SET_UI): New macros.
+ (MPZ_FAKE_UI): Rename couple of parameters.
+
+ * randlc2x.c (gmp_rand_lc_struct): _mp_c and _mp_c_limbs replaced
+ with mpn style _cp and _cn. All callers changed.
+ (randseed_lc): Fix limbs(seed) > bits_to_limbs(m2exp) case.
+ Remove return value.
+ (gmp_randinit_lc_2exp): Attempt to avoid redundant reallocation.
+
+ * randmt.c (mangle_seed): New function by Kevin.
+ (randseed_mt): Use it instead of mpz_powm, for performance. Remove
+ return value. Remove commented out code (an inferior alternative to
+ mpz_export).
+
+ * randsdui.c (gmp_randseed_ui): Use MPZ_FAKE_UI.
+
+ * tests/rand/t-lc2exp.c (check_bigm, check_bigs): New tests.
+ * tests/rand/t-urndmm.c: Add L to constants in calls, for K&R.
+
+2002-12-06 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Remove -g.
+ (hppa*-*-*): Pass -Wl,+vnocompatwarnings with +DA2.0.
+
+2002-12-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64/sqr_diagonal.asm: Remove .entry, .proc, .procend.
+ * mpn/pa64/udiv.asm: Likewise.
+
+2002-12-05 Kevin Ryde <kevin@swox.se>
+
+ * mpn/pa64/sub_n.asm: Remove space in "sub, db" which gas objects to.
+ * mpn/pa64/*.asm, tune/hppa2.asm: Use ".level 2.0" for 2.0n, since gas
+ doesn't like ".level 2.0N".
+
+ * configure.in (hppa*-*-*): Group path and flags choices, for clarity.
+ (hppa1.0*-*-*): Use gcc -mpa-risc-1-0 when available.
+ (hppa2.0*-*-*): Ditto -mpa-risc-2-0.
+ (*-*-hpux*): Exclude ABI=2.0w for hpux[1-9] and hpux10, rather than
+ the converse of allowing it for hpux1[1-9]; ie. list the bad systems
+ rather than try to guess the good systems.
+ (hppa2.0*-*-*) [ABI=2.0n ABI=2.0w]: Add gcc to likely compilers.
+ (hppa*-*-*) [gcc]: Test sizeof(long) to differentiate a 32-bit or
+ 64-bit build of the compiler.
+ (hppa64-*-*): Add this as equivalent to hppa2.0-*-*.
+ * acinclude.m4 (GMP_C_TEST_SIZEOF): New macro.
+
+ * tests/tests.h (ostringstream::str): Must null-terminate
+ ostrstream::str() for the string constructor.
+
+2002-12-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa32/hppa1_1/udiv.asm: Don't wrap symbol to INT64 in L() stuff.
+
+ * longlong.h (mpn_udiv_qrnnd_r based udiv_qrnnd): Fix typo.
+
+ * mpn/powerpc32/powerpc-defs.m4: Define float registers with `f'
+ prefix.
+
+2002-12-04 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Floating-point Functions): Note the mantissa is binary and
+ decimal fractions cannot be represented exactly. Suggested by Serge
+ Winitzki.
+ (Known Build Problems): Note libtool stripping options when linking.
+ Reported by Vincent Lefevre.
+
+ * acinclude.m4 (GMP_ASM_LABEL_SUFFIX): Don't make an empty result a
+ failure, that's a valid result.
+ (GMP_ASM_GLOBL): Establish this from the host cpu type.
+ (IA64_PATTERN): New macro.
+ (GMP_PROG_EXEEXT_FOR_BUILD, GMP_C_FOR_BUILD_ANSI,
+ GMP_CHECK_LIBM_FOR_BUILD): Remove temporary files created.
+ * configure.in: Use IA64_PATTERN.
+
+2002-12-03 Torbjorn Granlund <tege@swox.com>
+
+ * tune/hppa.asm: Use config.m4.
+ * tune/hppa2.asm: Likewise.
+ * tune/hppa2w.asm: Likewise.
+
+ * mpn/pa64: Use LDEF.
+
+2002-12-03 Kevin Ryde <kevin@swox.se>
+
+ * INSTALL: Use return rather than exit in the example programs.
+ Suggested by Richard Dawe.
+
+ * gmp.texi (Build Options): Move non-unix notes to ...
+ (Notes for Particular Systems): ... here. Mention MS Interix,
+ reported by Paul Leyland.
+ (C++ Interface Random Numbers): Add gmp_randinit_mt to examples.
+
+ * acinclude.m4 (GMP_ASM_LABEL_SUFFIX): Must test empty suffix first,
+ for the benefit of hppa hp-ux.
+ (GMP_ASM_UNDERSCORE): Grep the output of "nm" instead of trying to
+ construct an asm file, and in case of failure fallback on no
+ underscore and a warning.
+
+ * longlong.h (count_leading_zeros, count_trailing_zeros) [ev67, ev68]:
+ Restrict __asm__ ctlz and cttz to __GNUC__.
+
+ * gen-psqr.c (HAVE_CONST, const): New macros.
+
+ * tests/cxx/t-rand.cc (check_randinit): Add gmp_randinit_mt.
+
+2002-12-02 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h: Split popc_limb again, combined version gives too many
+ compiler warnings.
+
+2002-12-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/gcdext.c (div1): Disable unused function.
+
+ * mpz/root.c: Don't include stdlib.h or longlong.h.
+ * mpz/rootrem.c: Likewise.
+
+ * extract-dbl.c: abort => ASSERT_ALWAYS.
+ * mpz/set_d.c: Likewise.
+ * mpn/generic/tdiv_qr.c: Likewise.
+
+ * gen-psqr.c (f_cmp_fraction, f_cmp_divisor): Change parameter to
+ `const void *', to match qsort spec.
+
+2002-12-01 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Integer Division): Fix a couple of @math's for tex.
+ Use @dots in more places.
+
+ * tests/cxx/t-locale.cc: Test non std::locale systems too.
+ * tests/cxx/clocale.c: New file, reinstating what was localeconv.c,
+ and subverting nl_langinfo too.
+ * tests/cxx/Makefile.am (t_locale_SOURCES): Add it.
+
+ * tests/tests.h (ostringstream, istringstream): Provide fakes of these
+ if <sstream> not available.
+ * tests/cxx/t-locale.cc, tests/cxx/t-ostream.cc: Remove <sstream>.
+ * configure.in (AC_CHECK_HEADERS) [C++]: Add <sstream>.
+
+2002-11-30 Torbjorn Granlund <tege@swox.com>
+
+ * printf/doprnt.c (__gmp_doprnt): Comment out a `break' to shut up
+ compiler warnings.
+
+ * mpn/ia64/invert_limb.asm: Add `many' hints to return insns.
+
+ * mpn/ia64/divrem_1.asm: Allocate more local registers; put b0 in
+ one of them.
+
+ * mpn/ia64/popcount.asm: Properly restore register ar.lc.
+
+ * longlong.h (umul_ppmm) [ia64]: Form both product parts in asm.
+
+ * mpz/bin_uiui.c: Cast umul_ppmm operands.
+
+ * scanf/doscan.c (gmpscan): Remove unused label store_get_digits.
+
+ * gmp-impl.h: #undef MIN and MAX before #defining.
+
+ * mpn/ia64/copyi.asm: Add `;' after bundle declarators.
+ * mpn/ia64/copyd.asm: Likewise.
+
+ * mpn/ia64/divrem_1.asm: Add some syntax to placid the HP-UX assembler.
+
+2002-11-30 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_CHECK_HEADERS): Add nl_types.h.
+ * tests/misc/t-locale.c: Use this, for nl_item on netbsd 1.4.1.
+
+2002-11-29 Torbjorn Granlund <tege@swox.com>
+
+ * tests/devel/addmul_1.c: Provide prototype for mpn_print.
+ (OPS): Account for function overhead.
+ * tests/devel/{submul_1.c,mul_1.c,add_n.c,sub_n.c}: Likewise.
+
+ * mpn/ia64/addmul_1.asm: Rewrite.
+
+2002-11-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/sqr_diagonal.asm: Don't allocate any registers.
+
+ * mpn/ia64/submul_1.asm: Adapt to Itanium 2.
+
+ * mpn/ia64/mul_1.asm: Fix typo in HAVE_ABI_32 code.
+
+ * mpn/ia64/add_n.asm: Rewrite.
+ * mpn/ia64/sub_n.asm: Rewrite.
+
+2002-11-28 Kevin Ryde <kevin@swox.se>
+
+ * mpn/Makefile.am (nodist_EXTRA_libmpn_la_SOURCES): Use this rather
+ than libdummy.
+ * tests/Makefile.am (EXTRA_libtests_la_SOURCES): Use this for
+ x86call.asm and x86check.c rather than libdummy.
+
+2002-11-27 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-mul.c: Implement reference Karatsuba multiplication.
+ Rewrite testing scheme to run fewer really huge tests.
+
+2002-11-26 Torbjorn Granlund <tege@swox.com>
+
+ * tests: Decrease repetition count for some of the slowest tests.
+
+ * mpn/ia64/divrem_1.asm: New file.
+
+2002-11-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpfr/tests/tdiv.c: Decrease number of performed tests.
+
+2002-11-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mul_1.asm: Rewrite.
+
+2002-11-23 Kevin Ryde <kevin@swox.se>
+
+ * mpn/ia64/README: Add some references.
+
+ * gmp.texi (Build Options): Add itanium and itanium2, mention DocBook
+ and XML from makeinfo, add texinfo top level cross reference.
+ (Integer Division): Try to clarify 2exp functions a bit.
+ (C++ Interface Floats): Giving bad string to constructor is undefined.
+ (C++ Interface Integers, C++ Interface Rationals): Ditto, and show
+ default base in prototype, not the description.
+
+ * config.sub, config.guess, configure.in (itanium, itanium2): New cpu
+ types.
+
+ * tests/misc/t-printf.c, tests/misc/t-scanf.c (check_misc): Suppress
+ %zd test on glibc prior to 2.1, it's not supported.
+
+2002-11-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/copyi.asm: Optimize for Itanium 2.
+ * mpn/ia64/copyd.asm: Likewise.
+
+2002-11-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/sqr_diagonal.asm: New file.
+
+ * mpn/ia64/submul_1.asm: Handle vl == 0 specially.
+
+2002-11-20 Kevin Ryde <kevin@swox.se>
+
+ * tests/cxx/t-locale.cc: Test with locales imbued into stream, use
+ <sstream>, eliminated some C-isms. istream tests disabled, not yet
+ locale-ized.
+ * tests/cxx/Makefile.am (t_locale_SOURCES): Remove localeconv.c.
+ * tests/cxx/localeconv.c: Remove file.
+
+ * configure.in (AC_CHECK_TYPES) [C++]: Add std::locale.
+ * printf/doprntf.c: Add decimal point parameter, remove localeconv use.
+ * gmp-impl.h (__gmp_doprnt_mpf): Update prototype, bump symbol to
+ __gmp_doprnt_mpf2 to protect old libgmpxx.
+ * cxx/osmpf.cc: Use this with ostream locale decimal_point facet.
+ * printf/doprnt.c: Ditto, with GMP_DECIMAL_POINT.
+
+ * gmp-h.in: More comments on __declspec for windows DLLs.
+
+ * mpf/set_str.c, scanf/doscan.c: Cast through "unsigned char" for
+ decimal point string, same as input chars.
+
+ * configure.in (AC_CHECK_HEADERS): Add langinfo.h.
+ (AC_CHECK_FUNCS): Add nl_langinfo.
+ * gmp-impl.h (GMP_DECIMAL_POINT): New macro.
+ * mpf/out_str.c, mpf/set_str.c, scanf/doscan.c: Use it, and don't
+ bother with special code for non-locale systems.
+ * tests/misc/t-locale.c: Subvert nl_langinfo too.
+
+ * configure.in, acinclude.m4 (GMP_ASM_X86_GOT_UNDERSCORE): New macro.
+ * mpn/x86/x86-defs.m4 (_GLOBAL_OFFSET_TABLE_): New macro, inserting
+ extra underscore for OpenBSD.
+ * mpn/x86/README (_GLOBAL_OFFSET_TABLE_): Update notes.
+ Reported by Christian Weisgerber.
+
+ * tests/cxx/t-rand.cc (check_randinit): New function, collecting up
+ constructor tests.
+
+ * tests/cxx/t-ostream.cc: Use <sstream> instead of <strstream>, use
+ compare instead of strcmp.
+
+ * gmpxx.h (__gmp_randinit_lc_2exp_size_t): Return type is int.
+
+2002-11-18 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.c (r_string): Use CNST_LIMB with <N>bits, spotted by
+ Torbjorn.
+
+2002-11-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mul_1.asm: Remove redundant cmp from prologue code.
+ Streamline prologue.
+ * mpn/ia64/addmul_1.asm: Likewise.
+ * mpn/ia64/submul_1.asm: New file.
+ * mpn/ia64/submul_1.c: Remove.
+
+2002-11-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/popham.c: New file, using new faster algorithm.
+ * mpn/generic/popcount.c: Remove.
+ * mpn/generic/hamdist.c: Remove.
+
+ * mpn/ia64/addmul_1.asm: Don't clobber callee-saves register f16.
+ * mpn/ia64/mul_1.asm: Likewise.
+
+ * mpn/ia64/addmul_1.asm: Add pred.rel declarations. Resolve RAW
+ hazards for condition code registers, duplicating code as needed. Add
+ prediction to all branches.
+ * mpn/ia64/mul_1.asm: Likewise.
+ * mpn/ia64/add_n.asm: Likewise.
+ * mpn/ia64/sub_n.asm: Likewise.
+ * mpn/ia64/copyi.asm: Likewise.
+ * mpn/ia64/copyd.asm: Likewise.
+
+ * mpn/generic/random2.c: Add a cast to silence some compilers.
+
+2002-11-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/powm.c: Cap allocation by limiting k to 10 (512 precomputed
+ values).
+
+2002-11-16 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, gmp.texi: Remove powerpc64 ABI=32L, doesn't work and
+ is unlikely to ever do so.
+ * configure.in: Allow ABI=32 for powerpc64.
+ Reported by David Edelsohn.
+
+2002-11-14 Kevin Ryde <kevin@swox.se>
+
+ * mpn/Makefile.am (nodist_libdummy_la_SOURCES): Add addmul_2.c
+ addmul_3.c addmul_4.c addmul_5.c addmul_6.c addmul_7.c addmul_8.c.
+
+ * gmp-h.in (__GMP_DECLSPEC_EXPORT, __GMP_DECLSPEC_IMPORT) [__GNUC__]:
+ Use __dllexport__ and __dllimport__ to keep out of application
+ namespace.
+
+2002-11-14 Gerardo Ballabio <gerardo.ballabio@unimib.it>
+
+ * gmpxx.h (__gmp_randinit_default_t, __gmp_randinit_lc_2exp_t,
+ __gmp_randinit_lc_2exp_size_t): Use extern "C" { typedef ... }, for
+ the benefit of g++ prior to 3.2.
+
+2002-11-12 Kevin Ryde <kevin@swox.se>
+
+ * gmpxx.h (gmp_randclass constructors): Patch from Roberto Bagnara to
+ use extern "C" on C function pointer arguments.
+
+2002-11-09 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, Makefile.am, printf/Makefile.am,
+ printf/repl-vsnprintf.c: Handle vsnprintf replacement with C
+ conditionals.
+
+ * acinclude.m4 (AC_LANG_FUNC_LINK_TRY(C)): Workaround troubles recent
+ HP cc +O3 causes for AC_CHECK_FUNCS.
+
+ * gmp.texi (Notes for Particular Systems): Add Sparc app regs.
+ (Debugging): Note gcc -fstack options to detect overflow.
+ (Formatted Output Strings, Formatted Input Strings): Format strings
+ are not multibyte.
+
+2002-11-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/tdiv_qr.c: Remove a bogus assert.
+
+2002-11-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/tdiv_qr.c: Remove two dead mpn_divrem_2 calls.
+
+2002-11-04 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_C_INLINE): Don't define "inline" for C++.
+
+ * demos/expr/expr-impl.h (stdarg.h): Test __DECC same as gmp.h.
+
+ * mpbsd/mtox.c, printf/obprintf.c, printf/obvprintf.c,
+ scanf/vsscanf.c, demos/expr/expr.c, demos/expr/exprf.c,
+ demos/expr/exprfa.c, demos/expr/exprfr.c, demos/expr/exprq.c,
+ demos/expr/exprz.c, demos/expr/exprza.c: Add <string.h> for strlen and
+ memcpy.
+
+2002-11-02 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h: Test __x86_64__ not __x86_64. Reported by Andreas
+ Jaeger.
+
+ * mpz/import.c, mpz/export.c: Use char* subtract from NULL to get
+ pointer alignment, for the benefit of Cray vector systems.
+
+ * cxx/ismpf.cc: Use <clocale>.
+ * tests/cxx/t-locale.cc: No need to conditionalize <clocale>.
+
+ * scanf/doscan.c: Don't use isascii, rely on C99 ctype.h.
+
+ * gmp.texi (Build Options): Describe CC_FOR_BUILD, cross reference
+ texinfo manual.
+ (ABI and ISA): Add powerpc620 and powerpc630 to powerpc64, add NetBSD
+ and OpenBSD sparc64.
+ (Notes for Package Builds): Cross reference libtool manual.
+ (Notes for Particular Systems): Add OpenBSD to non-MMX versions of gas.
+ (Known Build Problems): Add MacOS X C++ shared libraries.
+
+2002-10-31 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h, tune/speed.c, tune/speed.h, tune/common.c, tune/many.pl,
+ tests/devel/try.c, tests/tests.h, tests/refmpn.c (mpn_addmul_5,
+ mpn_addmul_6, mpn_addmul_7, mpn_addmul_8): Add testing and measuring.
+ * configure.in (config.in): Add #undefs of HAVE_NATIVE_mpn_addmul_5,
+ HAVE_NATIVE_mpn_addmul_6, HAVE_NATIVE_mpn_addmul_7,
+ HAVE_NATIVE_mpn_addmul_8.
+ (gmp_mpn_functions_optional): Add addmul_5 addmul_6 addmul_7 addmul_8.
+
+ * tests/devel/try.c (ASSERT_CARRY): Remove, now in gmp-impl.h
+ (try_one): Do dest setups after sources, for benefit of
+ dst0_from_src1.
+
+2002-11-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/tdiv_qr.c: Avoid quadratic behaviour for
+ sub-division when numerator is more than twice the size of the
+ denominator. Simplify loop logic for the same case. Clean up a
+ few comments.
+
+2002-10-29 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (*-cray-unicos*): Pass -hnofastmd again.
+
+2002-10-25 Torbjorn Granlund <tege@swox.com>
+
+ * tests/tadd.c: Disable test of denorms.
+
+2002-10-23 Linus Nordberg <linus@swox.se>
+
+ * gmp.texi (Introduction to GMP): Update section about mailing
+ lists.
+
+2002-10-23 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (__GMP_ATTRIBUTE_PURE): Suppress this when
+ __GMP_NO_ATTRIBUTE_CONST_PURE is defined.
+ * gmp-impl.h (ATTRIBUTE_CONST): Ditto.
+ * tune/common.c: Use __GMP_NO_ATTRIBUTE_CONST_PURE.
+
+ * tune/speed.h, tune/many.pl: Remove ATTRIBUTEs from prototypes.
+ * tune/speed.h: Remove various "dummy" variables attempting to keep
+ "pure" calls live, no longer necessary. They weren't sufficient for
+ recent MacOS cc anyway.
+
+2002-10-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/cray/ieee/addmul_1.c: Handle overlap as in mul_1.c.
+ * mpn/cray/ieee/submul_1.c: Likewise.
+
+2002-10-19 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (sparcv9 etc -*-*bsd*): Add support for NetBSD and
+ OpenBSD sparc64. Reported by Christian Weisgerber.
+ (AC_CHECK_HEADERS): Add sys/param.h for sys/sysctl.h on *BSD.
+
+ * demos/calc/calc.y: Change ={ to {, needed for bison 1.50.
+
+ * longlong.h (count_leading_zeros, count_trailing_zeros) [x86_64]:
+ Should be UDItype.
+
+ * mpz/set_str.c, mpf/set_str.c, mpbsd/xtom.c, scanf/sscanffuns.c: Cast
+ chars through "unsigned char" to zero extend, required by C99 ctype.h.
+
+2002-10-18 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-root.c: Test also mpz_rootrem.
+
+ * mpn/generic/rootrem.c: Avoid overflow problem when n is huge.
+
+ * mpz/root.c: Avoid overflow problems in allocation computation; also
+ simplify it. Misc cleanups.
+
+ * mpz/rootrem.c: New file.
+ * Makefile.am, mpz/Makefile.am, gmp-h.in: Add them.
+
+2002-10-17 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (popc_limb): Combine variants.
+
+2002-10-14 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_CHECK_HEADERS): Add sys/time.h for sys/resource.h
+ test, needed by SunOS, and next autoconf will insist headers actually
+ compile.
+
+2002-10-08 Kevin Ryde <kevin@swox.se>
+
+ * tune/time.c (speed_time_init): Allow for Cray times() apparently
+ being a cycle counter.
+
+ * dumbmp.c (mpz_get_str): Fix buf size allocation.
+
+ * tests/trace.c, tests/tests.h (mp_limb_trace): New function.
+
+ * tune/speed-ext.c (SPEED_EXTRA_PROTOS): Use __GMP_PROTO.
+ * tests/devel/try.c (malloc_region): Add a cast for SunOS cc.
+
+ * configure.in (AC_CHECK_FUNCS): Add strerror.
+ (AC_CHECK_DECLS): Add sys_errlist, sys_nerr.
+ * tune/time.c, tests/devel/try.c: Use them.
+
+2002-10-05 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_CHECK_HEADERS): Test float.h, not in SunOS cc.
+ * printf/repl-vsnprintf.c: Use this.
+
+ * configure.in (*sparc*-*-*): Collect up various options for clarity,
+ use gcc -mcpu=supersparc and ultrasparc3, use cc -xchip, don't use
+ -xtarget=native, use cc configs with acc, merge SunOS bundled cc and
+ SunPRO cc configs.
+
+ * gmp-impl.h (gmp_randfnptr_t): Use __GMP_PROTO.
+ (MPZ_REALLOC): Cast _mpz_realloc return value to mp_ptr, for the
+ benefit of SunOS cc which requires pointers of the same type on the
+ two legs of a ?:.
+
+ * dumbmp.c (mpz_realloc): Add a cast to avoid a warning from SunOS cc.
+
+ * acinclude.m4: Allow for i960 b.out default cc output.
+
+ * gmp.texi (Random State Initialization): Add gmp_randinit_mt.
+ (Perfect Square Algorithm): Describe new mpn_mod_34lsub1 use.
+ (Factorial Algorithm): Describe Jason's new code.
+ (Binomial Coefficients Algorithm): Ideas about improvements
+ moved to doc/projects.html.
+ (Contributors): Add Jason Moxham and Pedro Gimeno.
+
+2002-10-03 Kevin Ryde <kevin@swox.se>
+
+ * gen-psqr.c: New file.
+ * Makefile.am, mpn/Makefile.am: Use it to generate mpn/perfsqr.h.
+ * mpn/generic/perfsqr.c: Use generated data, put mod 256 data into
+ limbs to save space, use mpn_mod_34lsub1 when good.
+ * tests/mpn/t-perfsqr.c: New file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add it.
+ * tests/mpz/t-perfsqr.c (check_modulo): New test.
+ (check_sqrt): New function holding current tests.
+
+ * configure.in (AC_INIT): Modernize to package name and version here
+ rather than AM_INIT_AUTOMAKE, add bug report email.
+ (AC_CONFIG_SRCDIR): New macro.
+
+ * gmp-impl.h (ROUND_UP_MULTIPLE): Fix for non-power-of-2 moduli (not
+ normal in current uses), clarify the comments a bit.
+
+2002-09-30 Kevin Ryde <kevin@swox.se>
+
+ * mpn/Makeasm.am (.s.lo): Add --tag=CC for the benefit of CCAS!=CC,
+ same as .S.lo and .asm.lo.
+
+ * Makefile.am (gen-fac_ui, gen-fib, gen-bases): Quote source files in
+ test -f stuff to avoid Sun make rewriting them.
+
+2002-09-28 Kevin Ryde <kevin@swox.se>
+
+ * tests/devel/try.c, tune/speed.c: Avoid strings longer than C99
+ guarantees.
+
+ * tests/refmpn.c, tests/tests.h (refmpn_zero_extend, refmpn_normalize,
+ refmpn_sqrtrem): New functions.
+ * tests/devel/try.c (TYPE_SQRTREM): Use refmpn_sqrtrem.
+ (compare): Correction to tr->dst_size subscripting.
+
+ * dumbmp.c: Add several new functions, allow for initial n<d in
+ mpz_tdiv_q (now in mpz_tdiv_qr actually).
+
+ * gen-bases.c (chars_per_limb): Get GMP_NUMB_BITS for base==2,
+ similarly other powers of 2, which this was in the past.
+ * tests/refmpn.c (refmpn_chars_per_limb): Ditto.
+ * tests/mpn/t-mp_bases.c: Test chars_per_limb for power-of-2 bases too.
+
+ * Makefile.am, mpz/Makefile.am: Setups for gen-fac_ui.c generating
+ mpz/fac_ui.h.
+
+2002-09-28 Jason Moxham <J.L.Moxham@maths.soton.ac.uk>
+
+ * dumbmp.c (mpz_pow_ui, mpz_addmul_ui, mpz_root): New functions.
+ * gen-fac_ui.c: New file.
+ * mpz/fac_ui.c: Rewrite.
+
+2002-09-26 Kevin Ryde <kevin@swox.se>
+
+ * tests/cxx/localeconv.c: New file, split from t-locale.cc.
+ * tests/cxx/t-locale.cc: Use it.
+ * tests/cxx/Makefile.am (t_locale_SOURCES): Add it.
+
+ * tests/cxx/Makefile.am: Updates for Gerardo's new test programs.
+
+2002-09-26 Gerardo Ballabio <gerardo.ballabio@unimib.it>
+
+ * gmpxx.h (__gmp_cmp_function): Bug fixes in double/mpq and
+ double/mpfr comparisons.
+
+ * tests/cxx/t-assign.cc, tests/cxx/t-binary.cc, tests/cxx/t-constr.cc,
+ tests/cxx/t-ternary.cc, tests/cxx/t-unary.cc: Revise and add various
+ tests, including some for mpfr, some split from t-expr.cc.
+ * tests/cxx/t-locale.cc: Modernize include files.
+ * tests/cxx/t-ostream.cc: Modernize include files, use cout rather
+ than printf for diagnostics.
+ * tests/cxx/t-misc.cc, tests/cxx/t-rand.cc: New file, split from
+ t-allfuns.cc.
+ * tests/cxx/t-ops.cc: New file, some split from t-allfuns.cc.
+ * tests/cxx/t-prec.cc: New file.
+ * tests/cxx/t-allfuns.cc, tests/cxx/t-expr.cc: Remove files.
+
+2002-09-25 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (*-cray-unicos*): Remove -hscalar0, it causes too much
+ performance loss. Let's trust Cray to fix their compilers.
+
+2002-09-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/add_n.asm: Rewrite.
+ * mpn/powerpc32/sub_n.asm: Rewrite.
+
+2002-09-24 Pedro Gimeno <pggimeno@wanadoo.es>
+
+ * randlc2x.c: Prepare for nails by changing type of _mp_c to mpz_t,
+ make _mp_seed fixed-size, disallow SIZ(a)==0 to optimize comparisons
+ for mpn_mul.
+ * gmp-impl.h (MPZ_FAKE_UI): New macro.
+
+ * randmt.c: Some constants made long for K&R compliance; remove UL at
+ the end of other constants; use mp_size_t where appropriate; use
+ mpz_export to split the seed.
+
+ * gmp-impl.h: Remove type cast in RNG_FNPTR and RNG_STATE, to allow
+ them to be used as lvalues.
+ * randclr.c, randlc2x.c, randmt.c, randsd.c: All callers changed.
+
+ * mpz/urandomm.c: Replace mpn_cmp with MPN_CMP.
+
+ * tests/rand/gen.c: Get rid of gmp_errno.
+
+2002-09-24 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Custom Allocation): Keep allocate_function etc out of the
+ function index by using @deftypevr.
+ More index entries.
+
+2002-09-24 Gerardo Ballabio <gerardo.ballabio@unimib.it>
+
+ * gmpxx.h (mpfr_class constructors from strings): Precision was set
+ incorrectly, fixed.
+
+2002-09-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/urandomb.c: Don't crash for overlarge nbits argument.
+ Let nbits==0 mean to fill number with random bits.
+
+2002-09-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/mod_34lsub1.asm: Add r31 dummy operand to `br' instruction.
+
+2002-09-20 Gerardo Ballabio <gerardo.ballabio@unimib.it>
+
+ * gmpxx.h (__gmp_binary_equal, __gmp_binary_not_equal): Fix broken
+ mpq/double functions.
+
+2002-09-18 Torbjorn Granlund <tege@swox.com>
+
+ * randmt.c (randget_mt): Fix typo.
+
+2002-09-18 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (_gmp_rand): Avoid evaluating "state" more than once, for
+ the benefit places calling it with RANDS.
+
+ * randmt.c (randseed_mt): Use mpz_init for mod and seed1, for safety.
+
+ * tune/tuneup.c (sqr_karatsuba_threshold): Initialize to
+ TUNE_SQR_KARATSUBA_MAX so mpn_sqr_n works for randmt initialization.
+
+ * gmp.texi (Integer Comparisons): Remove mention of non-existent
+ mpz_cmpabs_si, reported by Conrad Curry.
+
+ * tune/speed.c, tune/speed.h, tune/common.c: Add gmp_randseed,
+ gmp_randseed_ui and mpz_urandomb.
+
+2002-09-18 Pedro Gimeno <pggimeno@wanadoo.es>
+
+ * tests/rand/gen.c: Add mt, remove lc and bbs.
+
+ * Makefile.am (libgmp_la_SOURCES): Add randmt.c, remove randlc.c and
+ randraw.c.
+
+ * randmt.c: New file.
+ * gmp-h.in (gmp_randinit_mt): Add prototype.
+ * randdef.c: Use gmp_randinit_mt.
+
+ * gmp-impl.h (RNG_FNPTR, RNG_STATE): New macros.
+ (gmp_randfnptr_t): New structure.
+ (_gmp_rand): Now a macro not a function.
+ * gmp-h.in (__gmp_randata_lc): Remove, now internal to randlc2x.c.
+ (__gmp_randstate_struct): Revise comments on field usage.
+ * randsd.c, randclr.c: Use function pointer scheme.
+ * randsdui.c: Use gmp_randseed.
+ * randraw.c: Remove file.
+ * randlc2x.c: Collect up lc_2exp related code from randsd.c, randclr.c
+ and randraw.c, use function pointer scheme, integrate seed==0/a==0
+ into main case and fix case where bits(a) < m2exp.
+
+ * randlc.c: Remove file, never documented and never worked.
+ * gmp-h.in (gmp_randinit_lc): Remove prototype.
+
+2002-09-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/mod_34lsub1.asm: New file.
+
+2002-09-16 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, acinclude.m4 (GMP_C_RESTRICT): Remove this, not
+ currently used, and #define restrict upsets Microsoft C headers on
+ win64. Reported by David Librik.
+
+ * configure.in (x86): Add gcc 3.2 -march and -mcpu flags, remove some
+ unnecessary -march=i486 fallbacks.
+
+ * gmp.texi (Notes for Particular Systems): Note cl /MD is required for
+ Microsoft C and MINGW to cooperate on I/O. Explained by David Librik.
+ (Language Bindings): Add linbox.
+ * gmp.texi (Language Bindings):
+
+2002-09-12 Kevin Ryde <kevin@swox.se>
+
+ * mpz/aorsmul_i.c: Allow for w==x overlap with nails. Test
+ BITS_PER_ULONG > GMP_NUMB_BITS rather than GMP_NAIL_BITS != 0.
+ * tests/mpz/t-aorsmul.c: Test this.
+
+ * tune/common.c: mpn_mod_34lsub1 only exists for GMP_NUMB_BITS%4==0
+ * tune/speed.c: Add mpn_mod_34lsub1.
+
+2002-09-10 Pedro Gimeno <pggimeno@wanadoo.es>
+
+ * rand.c: Remove old disabled BBS code.
+ * mpf/urandomb.c: Use BITS_TO_LIMBS.
+
+2002-09-10 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Multiplication Algorithms): FFT is now enabled by default.
+
+2002-09-10 Pedro Gimeno <pggimeno@wanadoo.es>
+
+ * mpz/urandomm.c: Use mpn level functions, avoid an infinite loop if
+ _gmp_rand forever returns all "1" bits.
+ * tests/rand/t-urndmm.c: New file
+ * tests/rand/Makefile.am (check_PROGRAMS): Add it.
+
+ * gmp-impl.h (BITS_TO_LIMBS): New macro.
+ * mpz/urandomb.c: Use it, and use MPZ_REALLOC.
+
+2002-09-08 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_GCC_WA_MCPU): New macro.
+ * configure.in (alpha*-*-*): Use it to avoid -Wa,-mev67 if gas isn't
+ new enough to know ev67. Reported by David Bremner.
+
+2002-07-30 Gerardo Ballabio <gerardo.ballabio@unimib.it>
+
+ * gmpxx.h (__gmpz_value etc): Remove, use mpz_t etc instead.
+ (__gmp_expr): Reorganise specializations, use __gmp_expr<T,T> not
+ mpz_class etc.
+ (mpfr evals): Remove mode parameter, was always
+ __gmp_default_rounding_mode anyway.
+
+2002-09-07 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in, mp-h.in: Use #ifdef for tests, for the benefit of
+ applications using gcc -Wundef.
+
+ * longlong.h: Define COUNT_LEADING_ZEROS_NEED_CLZ_TAB for all alphas,
+ since mpn/alpha/cntlz.asm always goes into libgmp.so, even for ev67
+ and ev68 which don't need it. Reported by David Bremner.
+
+ * gmp.texi (Demonstration Programs): New section, expanding on what
+ was under "Build Options".
+ (Converting Floats): Don't need \ for _ in @var within @math.
+ Add and amend various index entries.
+
+ * demos/qcn.c: Add -p prime limit option.
+
+2002-08-30 Kevin Ryde <kevin@swox.se>
+
+ * mpz/pprime_p.c: Handle small negatives with isprime, in particular
+ must do so for n==-2.
+ * tests/mpz/t-pprime_p.c: New file.
+ * tests/mpz/Makefile.am: Add it.
+
+2002-08-26 Torbjorn Granlund <tege@swox.com>
+
+ * gmp.texi (Converting Floats): Fix typo in mpf_get_d_2exp docs,
+ reported by Paul Zimmermann.
+
+2002-08-26 Kevin Ryde <kevin@swox.se>
+
+ * configure.in: Echo the ABI being tried for the compilers.
+ (powerpc*-*-*): Use powerpc64/aix.m4 for ABI=aix64 too.
+ (AC_CHECK_FUNCS): Add strtol, for tests/rand/gen.c.
+
+2002-08-24 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (HAVE_HOST_CPU_, HAVE_HOST_CPU_FAMILY_, HAVE_NATIVE_):
+ Setup templates for these using AH_VERBATIM rather than acconfig.h,
+ preferred by latest autoconf. Prune lists to just things used.
+ * acconfig.h: Remove file.
+
+ * mpn/powerpc32/mode1o.asm: Forgot ASM_START.
+
+ * tune/time.c (have_cgt_id): Renamed from HAVE_CGT_ID so avoid
+ confusion with autoconf outputs, and turn it into a "const" variable.
+
+2002-08-23 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Choose powerpc32/aix.m4 or powerpc64/aix.m4 based on
+ ABI, not configuration triple.
+
+ * mpz/pprime_p.c: Partially undo last change--handle small and
+ negative numbers in the same test.
+
+2002-08-22 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (MUL_FFT_THRESHOLD, SQR_FFT_THRESHOLD): Note
+ mpn/generic/mul_fft.c is not nails-capable, and don't bother setting
+ other FFT data for nails.
+
+ * configfsf.guess: Update to 2002-08-19.
+ * configfsf.sub: Update to 2002-08-20.
+
+ * config.guess (powerpc*-*-*): Use a { } construct to suppress SIGILL
+ message on AIX.
+
+2002-08-20 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Build Options): Add ia64 under cpu types.
+ (ABI and ISA): Describe IRIX 6 ABI=o32.
+ (Notes for Particular Systems): Remove -march=pentiumpro, now ok.
+ (Known Build Problems): Binutils 2.12 is ok for libgmp.a.
+ (Emacs): New section.
+ (Language Bindings): Update MLton URL, reported by Stephen Weeks.
+ (Prime Testing Algorithm): New section.
+ Don't put a blank line after @item in @table since it can make a page
+ break between the heading and the entry.
+ Misc tweaks elsewhere, in particular more index entries.
+
+ * mpz/millerrabin.c: Need x to be size+1 for change to urandomm.
+
+ * gmp-impl.h: Comments on the use of __GMP_DECLSPEC.
+
+ * tune/time.c (freq_measure_mftb_one): Use struct_timeval, for the
+ benefit of mingw.
+
+ * tests/refmpn.c, tests/tests.h (ref_addc_limb, ref_subc_limb):
+ Renamed from add and sub, following gmp-impl.h ADDC_LIMB and SUBC_LIMB.
+
+2002-08-17 Kevin Ryde <kevin@swox.se>
+
+ * mpn/powerpc32/mode1o.asm: New file.
+ * configure.in, acinclude.m4 (GMP_ASM_POWERPC_PIC_ALWAYS): New macro.
+ * mpn/asm-defs.m4: Use it to help setting up PIC.
+
+ * configure.in (AC_PREREQ): Bump to 2.53.
+
+ * mpn/powerpc32/powerpc-defs.m4 (ASSERT): New macro.
+ (PROLOGUE_cpu): New macro, giving ALIGN(4) not 8.
+
+2002-08-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/m68k/lshift.asm: Fix typo in !scale_available_p code.
+ * mpn/m68k/rshift.asm: Likewise.
+
+2002-08-16 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (--enable-profiling=instrument): New option.
+ * gmp.texi (Profiling): Describe it.
+ * mpn/x86/x86-defs.m4 (PROLOGUE_cpu, call_instrument, ret_internal):
+ Add support.
+ (call_mcount): Share PIC setups with call_instrument.
+ * mpn/x86/*.asm: Use ret_internal.
+ * mpn/asm-defs.m4 (m4_unquote): New macro.
+ * tests/mpn/t-instrument.c: New file.
+ * tests/mpn/Makefile.am: Add it.
+
+ * mpn/alpha/umul.asm: Add ASM_END.
+
+2002-08-12 Kevin Ryde <kevin@swox.se>
+
+ * mpz/pprime_p.c: Fake up a local mpz_t to take abs(n), rather than
+ using mpz_init etc.
+
+ * mpz/millerrabin.c: Use mpz_urandomm for uniform selection of x,
+ reported by Jason Moxham. Exclude x==n-1, ie. -1 mod n. Use
+ gmp_randinit_default.
+
+ * mpn/alpha/umul.asm: Use "r" registers, for the benefit of Unicos.
+
+ * tests/devel/try.c: Add mpn_copyi and mpn_copyd.
+
+2002-08-09 Kevin Ryde <kevin@swox.se>
+
+ * Makefile.am: Remove configure.lineno from DISTCLEANFILES and gmp.tmp
+ from MOSTLYCLEANFILES, automake does these itself now.
+
+ * */Makefile.in, aclocal.m4, configure, install-sh, missing,
+ mkinstalldirs: Update to automake 1.6.3.
+
+ * mpn/ia64/README: Some notes on assembler syntax.
+
+ * mpn/ia64/add_n.asm, mpn/ia64/sub_n.asm: Add .body.
+ * mpn/ia64/add_n.asm, mpn/ia64/addmul_1.asm, mpn/ia64/mul_1.asm,
+ mpn/ia64/sub_n.asm: Position .save ar.lc just before relevant
+ instruction.
+ * mpn/ia64/addmul_1.asm, mpn/ia64/mul_1.asm: Add .save ar.pfs and pr.
+ * mpn/ia64/copyd.asm, mpn/ia64/copyi.asm: Correction to .body position.
+ * mpn/ia64/lorrshift.asm: Add .prologue stuff.
+
+ * configure.in (*-*-unicos*): Remove forcible --disable-shared,
+ libtool gets this right itself now.
+
+2002-08-07 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/mmx/hamdist.asm: New file, adapted from
+ mpn/x86/pentium/mmx/popham.asm.
+ * mpn/x86/pentium/mmx/popham.asm: Remove file, not faster than plain
+ mpn/x86/pentium/popcount.asm for the popcount.
+
+ * mpn/alpha/umul.asm: Use PROLOGUE/EPILOGUE, rename it mpn_umul_ppmm.
+ * configure.in (alpha*-*-*): Add umul to extra_functions.
+
+ * mpz/remove.c: Make src==0 return 0, not do DIVIDE_BY_ZERO.
+
+2002-08-05 Torbjorn Granlund <tege@swox.com>
+
+ * acconfig.h: Remove spurious undefs for mpn_divrem_newton and
+ mpn_divrem_classic.
+
+2002-08-05 Kevin Ryde <kevin@swox.se>
+
+ * tests/refmpn.c, tests/tests.h, tests/misc/t-printf.c,
+ tests/mpf/t-trunc.c, tests/mpn/t-mp_bases.c, tests/mpn/t-scan.c,
+ tests/mpq/t-cmp_ui.c, tests/mpz/bit.c, tests/mpz/t-aorsmul.c,
+ tests/mpz/t-powm_ui.c tests/mpz/t-root.c, tests/mpz/t-scan.c: More
+ care with long and mp_size_t parameters, for the benefit of K&R.
+
+ * demos/perl/GMP.pm, demos/perl/GMP.xs, demos/perl/GMP/Mpz.pm,
+ demos/perl/test.pl: Add mpz_import and mpz_export.
+ * demos/perl/GMP.pm: Remove "preliminary" warning.
+
+ * mpn/lisp/gmpasm-mode.el: Set add-log-current-defun-header-regexp to
+ pick up m4 defines etc.
+
+ * Makefile.am (libgmpxx_la_DEPENDENCIES): libgmp.la should be here,
+ not libgmpxx_la_LIBADD, for the benefit of "make -j2".
+
+ * mpn/ia64/*.asm [hpux ABI=32]: Extend 32-bit operands to 64-bits, not
+ optimal and might not be sufficient, but seems to work.
+
+2002-08-03 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Profiling): Use a table and expand for clarity.
+ (Integer Special Functions): New section for mpz_array_init,
+ _mpz_realloc, mpz_getlimbn and mpz_size, to discourage their use.
+
+ * configure.in (*-*-msdosdjgpp*): Remove forcible --disable-shared,
+ libtool gets this right itself now.
+
+2002-07-30 Kevin Ryde <kevin@swox.se>
+
+ * mpn/powerpc32/lshift.asm, mpn/powerpc32/rshift.asm: Lose final mr,
+ and make final stwu into an stw.
+
+ * gmp.texi (Known Build Problems): An easier workaround for DESTDIR,
+ using LD_LIBRARY_PATH.
+ (C++ Interface MPFR): Remove mpfrxx.h.
+
+ * mpfrxx.h: Remove file.
+ * Makefile.am: Remove mpfrxx.h.
+ * tests/cxx/Makefile.am: Add Gerardo's new test programs.
+
+2002-07-30 Gerardo Ballabio <gerardo.ballabio@unimib.it>
+
+ * gmpxx.h: Use mpz_addmul etc for ternary a+b*c etc. Reorganise some
+ macros for maintainability. Merge mpfrxx.h.
+ * tests/cxx/t-constr.cc, tests/cxx/t-expr.cc: Various updates.
+ * tests/cxx/t-assign.cc, tests/cxx/t-binary.cc,
+ tests/cxx/t-ternary.cc, tests/cxx/t-unary.cc: New files.
+
+2002-07-27 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h (count_trailing_zeros) [ia64 __GNUC__]: Don't use
+ __builtin_ffs for now, doesn't seem to work.
+
+ * configure.in: Establish CONFIG_SHELL to avoid a problem with
+ AC_LIBTOOL_SYS_MAX_CMD_LEN on ia64-*-hpux*.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_GCD_FINDA): Don't let calls to
+ mpn_gcd_finda go dead.
+
+ * mpn/generic/tdiv_qr.c: Inline mpn_rshift and MPN_COPY of 2 limbs.
+
+2002-07-24 Kevin Ryde <kevin@swox.se>
+
+ * demos/primes.c: Use __GMP_PROTO and don't use signed, for the
+ benefit of K&R.
+
+ * demos/calc/calclex.l: Add <string.h> for strcmp.
+
+ * mpn/ia64/invert_limb.asm: Use .rodata which works on ia64-*-hpux*
+ and should be standard, rather than worrying about RODATA.
+
+ * gmp.texi (Function Classes): Add cross references.
+ (Integer Import and Export): Fix return value grouping.
+
+ * mpn/lisp/gmpasm-mode.el (gmpasm-comment-start-regexp): Add // for
+ ia64. Add notes on what the various styles are for.
+
+ * mpn/ia64/default.m4 (ASM_START): Define to empty, not dnl, so as not
+ to kill text on the same line.
+ (EPILOGUE_cpu): Force a newline after "#", so as not to suppress macro
+ expansion in the rest of the EPILOGUE line.
+
+2002-07-21 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.h: Fix some missing _PROTOs.
+
+ * Makefile.am (DISTCLEANFILES): Add configure.lineno.
+
+ * acinclude.m4 (GMP_C_DOUBLE_FORMAT): Define
+ HAVE_DOUBLE_IEEE_BIG_ENDIAN and HAVE_DOUBLE_IEEE_LITTLE_ENDIAN in
+ config.m4 too.
+ * mpn/ia64/invert_limb.asm: Add big-endian data.
+
+ * tests/mpz/t-jac.c (try_si_zi): Correction to "a" parameter type.
+
+2002-07-20 Kevin Ryde <kevin@swox.se>
+
+ * mpz/bin_ui.c, mpz/jacobi.c, mpz/pprime_p.c, mpn/generic/divis.c:
+ More care with long and mp_size_t parameters, for the benefit of K&R.
+
+ * gmp-impl.h (invert_limb): Use parens around macro arguments.
+ (mpn_invert_limb): Give prototype and define unconditionally.
+
+ * gmp-impl.h (CACHED_ABOVE_THRESHOLD, CACHED_BELOW_THRESHOLD): New
+ macros.
+ * mpn/generic/sb_divrem_mn.c: Use them to help gcc let preinv code go
+ dead when not wanted.
+
+2002-07-17 Kevin Ryde <kevin@swox.se>
+
+ * tests/refmpz.c (refmpz_hamdist): Ensure mp_size_t parameters are
+ that type, for the benefit of hpux ia64 bundled cc ABI=64.
+
+ * configure.in (ia64*-*-hpux*): Need +DD64 in cc_64_cppflags to get
+ the right headers for ansi2knr.
+
+ * acinclude.m4 (GMP_TRY_ASSEMBLE, GMP_ASM_UNDERSCORE): Use $CPPFLAGS
+ with $CCAS and when linking, as done by the makefiles.
+ (GMP_ASM_X86_MMX, GMP_ASM_X86_SSE2): Show $CPPFLAGS in diagnostics.
+
+ * gmp-impl.h (ieee_double_extract): Setup using HAVE_DOUBLE_IEEE_*.
+ (GMP_UINT32): New define, 32 bit type for ieee_double_extract.
+ * configure.in: Add AC_CHECK_SIZEOF unsigned.
+ * configure.in, acinclude.m4 (GMP_IMPL_H_IEEE_FLOATS): Remove.
+ (GMP_C_DOUBLE_FORMAT): Instead warn about unknown float here.
+
+ * configure.in, acinclude.m4 (GMP_C_SIZES): Remove.
+ * acinclude.m4 (GMP_INCLUDE_GMP_H_BITS_PER_MP_LIMB): Remove this
+ scheme, not required.
+ * configure.in (unsigned long, mp_limb_t): Run AC_CHECK_SIZEOF for
+ these unconditionally, check mp_limb_t against gmp-mparam.h values.
+ * gmp-impl.h (BYTES_PER_MP_LIMB, BITS_PER_MP_LIMB): Define based on
+ SIZEOF_MP_LIMB_T if not provided by gmp-mparam.h.
+ (BITS_PER_ULONG): Define here now.
+
+ * gmp.texi (ABI and ISA): Add HP-UX IA-64 choices.
+ (Random State Initialization): Typo in m2exp described for
+ gmp_randinit_lc_2exp_size.
+ (Formatted Output Functions): Clarify gmp_obstack_printf a bit.
+ (Formatted Input Strings): Typo in %n summary.
+
+ * mpz/inp_raw.c (NTOH_LIMB_FETCH): Use simple generic default, since
+ endianness detection is now cross-compile friendly.
+ * mpz/out_raw.c (HTON_LIMB_STORE): Ditto.
+
+ * mpz/fib_ui.c: Nailify.
+ * mpz/random.c: Nailify.
+
+ * mpfr/acinclude.m4 (MPFR_CONFIGS): Patch by Vincent for an apparent
+ float rounding gremlin on powerpc.
+
+2002-07-15 Kevin Ryde <kevin@swox.se>
+
+ * Makefile.am (PRINTF_OBJECTS): Avoid ending in a backslash, hpux ia64
+ make doesn't like that.
+
+ * mpn/ia64/*.asm: Add .sptk to unconditional branches, add ";" after
+ .mib etc, for the benefit of hpux.
+
+ * configure.in (ia64*-*-*): Use ABI=64 on non-HPUX systems, for
+ consistency.
+
+ * gmp-impl.h (ieee_double_extract): Test __sparc__, used by gcc 3.1.
+ Reported by nix@esperi.demon.co.uk.
+ * mpfr/mpfr-math.h (_MPFR_NAN_BYTES etc): Ditto.
+
+2002-07-13 Kevin Ryde <kevin@swox.se>
+
+ * mpn/powerpc32/rshift.asm: Rewrite, transformed from lshift.asm.
+
+ * tune/tuneup.c (DIVEXACT_1_THRESHOLD, MODEXACT_1_ODD_THRESHOLD):
+ Always zero for native mpn_divexact_1, mpn_modexact_1_odd.
+
+ * gmp-h.in (__GMP_EXTERN_INLINE): Don't use this during configure,
+ ie. __GMP_WITHIN_CONFIGURE, to avoid needing dependent routines.
+ * acinclude.m4 (GMP_H_EXTERN_INLINE): Consequent changes.
+
+ * gmp-impl.h, mpn/asm-defs.m4 (mpn_addmul_2, mpn_addmul_3,
+ mpn_addmul_4): Add prototypes and defines.
+
+ * gmp.texi (Number Theoretic Functions): Clarify return value.
+ Reported by Peter Keller.
+
+2002-07-10 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, acinclude.m4 (GMP_PROG_LEX): Remove this in favour of
+ AM_PROG_LEX, now ok when lex is missing.
+
+ * longlong.h (count_leading_zeros) [pentiummmx]: Don't use __clz_tab
+ variant under LONGLONG_STANDALONE.
+ (count_trailing_zeros) [ia64 __GNUC__]: Use __builtin_ffs.
+
+ * gmp-impl.h (popc_limb): Add an ia64 asm version.
+ (DItype): Use HAVE_LONG_LONG to choose long long, avoiding _LONGLONG
+ which is in gcc but means something unrelated in MS Visual C 7.0.
+ Reported by David Librik.
+
+ * mpz/divexact.c: Add an ASSERT that den divides num.
+
+ * mpn/asm-defs.m4 (LDEF): New macro.
+ (INT32, INT64): Use it.
+ * mpn/pa32/*.asm: Use it.
+ * mpn/pa32/README: Update notes on labels.
+
+ * tests/refmpn.c, tests/tests.h, tests/t-bswap.c (ref_bswap_limb):
+ Renamed from refmpn_bswap_limb.
+ * tests/t-bswap.c: Add tests_start/tests_end for randomization.
+
+ * tests/refmpn.c, tests/tests.h (ref_popc_limb): New function.
+ * tests/t-popc.c: New file.
+ * tests/Makefile.am: Add it.
+
+ * mpn/ia64/invert_limb.asm: Use RODATA since ".section .rodata" is not
+ accepted by ia64-*-hpux*.
+
+ * acinclude.m4 (GMP_ASM_BYTE): New macro.
+ (GMP_ASM_ALIGN_LOG, GMP_ASM_W32): Use it.
+ (GMP_ASM_LABEL_SUFFIX): Use test compiles, not $host.
+ (GMP_ASM_GLOBL): Ditto, and add .global for ia64-*-hpux*.
+ (GMP_ASM_GLOBL_ATTR): Use GMP_ASM_GLOBL result, not $host.
+ (GMP_ASM_LSYM_PREFIX): Allow any "a-z" nm symbol code, add ".text" to
+ test program, required by ia64-*-hpux*.
+ (GMP_ASM_LABEL_SUFFIX): Make LABEL_SUFFIX just the value, not a "$1:",
+ the former being how it's currently being used in fact.
+
+ * configure.in, acinclude.m4 (GMP_PROG_CC_WORKS_LONGLONG): New macro.
+ * configure.in (ia64-*-hpux*): Add 32 and 64 bit ABI modes.
+
+2002-07-06 Kevin Ryde <kevin@swox.se>
+
+ * tests/cxx/t-allfuns.cc: New file.
+ * tests/cxx/Makefile.am: Add it.
+
+ * mpz/clrbit.c, mpz/setbit.c: Only MPN_NORMALIZE if high limb changes
+ to zero. Use _mpz_realloc return value.
+
+ * gmp.texi (Build Options, C++ Formatted Output, C++ Formatted Input):
+ Cross reference to Headers and Libraries for libgmpxx stuff.
+ (Low-level Functions): mpn_divexact_by3 result based on GMP_NUMB_BITS.
+ mpn_set_str takes "unsigned char *", reported by Mark Sofroniou.
+ (C++ Interface General): Describe linking with libgmpxx and libgmp.
+
+2002-07-01 Kevin Ryde <kevin@swox.se>
+
+ * tune/tuneup.c, gmp-impl.h: Eliminate the array of thresholds in
+ one(), tune just one at a time and let the callers hand dependencies.
+ Eliminate the second_start_min hack, handle SQR_KARATSUBA_THRESHOLD
+ oddities in tune_sqr() instead.
+
+ * mpn/pa64/umul.asm, mpn/pa64/udiv.asm, mpn/asm-defs.m4, acconfig.h,
+ longlong.h, tune/speed.c, tune/speed.h, tune/common.c, tune/many.pl,
+ tests/devel/try.c: Introduce mpn_umul_ppmm_r and mpn_udiv_qrnnd_r
+ rather than having variant parameter order for mpn_umul_ppmm and
+ mpn_udiv_qrnnd on pa64.
+
+ * gmp-h.in (mpz_export): Remove a spurious parameter name.
+ * gmp-impl.h (mpn_rootrem): Use __MPN.
+
+2002-06-29 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h (udiv_qrnnd) [hppa32]: Remove mpn_udiv_qrnnd version, the
+ general mechanism for that suffices.
+
+ * mpf/inp_str.c: Fix returned count of chars read, reported by Paul
+ Zimmermann. Also fix a memory leak for invalid input.
+ * tests/mpf/t-inp_str.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+
+ * tests/devel/try.c (mpn_mod_34lsub1): Only exists for
+ GMP_NUMB_BITS%4==0.
+ (SIZE2_FIRST): Respect option_firstsize2 for "fraction" case.
+
+ * mpn/generic/diveby3.c: Further nailifications.
+ * gmp-impl.h (MODLIMB_INVERSE_3): Allow for GMP_NUMB_BITS odd.
+ (GMP_NUMB_CEIL_MAX_DIV3, GMP_NUMB_CEIL_2MAX_DIV3): New constants.
+ * tests/t-constants.c: Check them.
+
+ * gmp-h.in (__GMP_CRAY_Pragma): New macro.
+ (__GMPN_COPY_REST): Use it.
+ * gmp-impl.h (CRAY_Pragma): Use it.
+
+2002-06-25 Kevin Ryde <kevin@swox.se>
+
+ * mpz/import.c, mpz/export.c: Cast data pointer through "char *" in
+ alignment tests, for the benefit of Cray vector systems.
+
+ * configure.in (x86-*-*): Remove -march=pentiumpro check, seems ok
+ with current code.
+ * acinclude.m4 (GMP_GCC_MARCH_PENTIUMPRO, GMP_GCC_VERSION_GE): Remove
+ macros, no longer needed
+
+ * acinclude.m4 (GMP_ASM_RODATA): Remove temporary files.
+
+ * configure.in (GMP_ASM_GLOBL_ATTR): Reposition to avoid duplication
+ through AC_REQUIRE.
+
+2002-06-23 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpz/t-fib_ui.c (check_fib_table): Check table values, not just
+ that they're non-zero.
+
+ * acinclude.m4 (GMP_GCC_ARM_UMODSI): Match bad "gcc --version" output
+ exactly, rather than parsing it with GMP_GCC_VERSION_GE.
+ (GMP_ASM_UNDERSCORE): Use GLOBL_ATTR.
+
+ * mpn/pa32/udiv.asm, mpn/pa32/hppa1_1/udiv.asm, mpn/pa64/udiv.asm:
+ Renamed from udiv_qrnnd.asm, for consistency with other udiv's.
+ * mpn/pa64/umul.asm: Renamed from umul_ppmm.asm likewise.
+ * configure.in (hppa*-*-*): Update extra_functions.
+ (NAILS_SUPPORT): Remove umul_ppmm, udiv_qrnnd, udiv_fp, udiv_nfp from
+ nails-neutral list, no longer needed.
+
+ * gmp-h.in (__DECC): Add notes on testing this for ANSI-ness.
+ (__GMP_EXTERN_INLINE): Add static __inline for DEC C.
+ (mpz_mod_ui): Move up to main section, it's still documented.
+
+2002-06-22 Kevin Ryde <kevin@swox.se>
+
+ * mpz/jacobi.c, mpz/kronsz.c, mpz/kronuz.c, mpz/kronzs.c,
+ mpz/kronzu.c: Allow for odd GMP_NUMB_BITS, tweak a few variable setups.
+ * gmp-impl.h (JACOBI_STRIP_LOW_ZEROS): New macro.
+
+ * mpn/generic/mod_34lsub1.c: Nailify.
+ * tests/devel/try.c (CNST_34LSUB1): Nailify.
+ * gmp-impl.h (ADDC_LIMB): New macro.
+
+ * gmpxx.h (mpf_class::get_str): Make exponent mp_exp_t&, default
+ base=10 and ndigits=0.
+ (mpz_class::set_str, mpq_class::set_str, mpf_class::set_str): Add
+ versions accepting "const char *".
+ * mpfrxx.h (mpfr_class::get_str, mpfr_class::set_str): Ditto, and
+ uncommenting set_str and operator=.
+ * gmp.texi (C++ Interface Integers, C++ Interface Rationals)
+ (C++ Interface Floats): Update.
+
+ * gmp-impl.h (modlimb_invert): Merge the <=64bits and general versions.
+ (const, signed): Move to near top of file, fixes --enable-alloca=debug
+ on K&R.
+
+ * gen-fib.c: New file, derived from mainline in mpn/generic/fib2_ui.c.
+ * dumbmp.c (mpz_init_set_ui): New function.
+ * Makefile.am, mpn/Makefile.am: Generate fib_table.h, mpn/fib_table.c.
+ * gmp-impl.h: Use fib_table.h, add __GMP_DECLSPEC to __gmp_fib_table
+ (for the benefit of tests/mpz/t-fib_ui.c).
+ * mpn/generic/fib2_ui.c: Remove __gmp_fib_table and generating code.
+
+ * Makefile.am: Add mp.h to BUILT_SOURCES, distclean all BUILT_SOURCES,
+ use += more.
+
+ * acinclude.m4 (GMP_ASM_M68K_INSTRUCTION, GMP_ASM_M68K_BRANCHES):
+ Don't let "unknown" get into the cache variables.
+ (GMP_ASM_TEXT): See what assembles, don't hard-code hpux and aix.
+ (GMP_PROG_EXEEXT_FOR_BUILD): Add ,ff8 for RISC OS, per autoconf cvs.
+ (GMP_PROG_CPP_FOR_BUILD): Restructure per AC_PROG_CPP, print correct
+ result if CPP_FOR_BUILD overrides the cache variable.
+ (GMP_PROG_CC_FOR_BUILD_WORKS): New macro split from
+ GMP_PROG_CC_FOR_BUILD. Allow for "conftest" default compiler output.
+ * configure.in, acinclude.m4 (GMP_PROG_HOST_CC): Reinstate this,
+ separating HOST_CC establishment from GMP_PROG_CC_FOR_BUILD.
+
+ * configure.in (mpn_objs_in_libgmp): Move mpn/mp_bases.lo ...
+ * Makefile.am (MPN_OBJECTS): ... to here, add $U, and arrange
+ MPN_OBJECTS to be common between libgmp and libmp.
+
+2002-06-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_n.c (TOOM3_MUL_REC, TOOM3_SQR_REC): Don't check if
+ basecase is to be invoked when *_TOOM3_THRESHOLD is more than 3 times
+ the corresponding *_THRESHOLD.
+
+2002-06-20 Kevin Ryde <kevin@swox.se>
+
+ * mpn/ia64/submul_1.c: Add missing TMP_DECL, TMP_MARK, TMP_FREE.
+ Reported by Paul Zimmermann.
+
+ * configure.in, acinclude.m4 (AC_DEFINE): Make templates read "Define
+ to 1", for clarity as per autoconf.
+ * acinclude.m4 (GMP_OPTION_ALLOCA): Group WANT_TMP templates.
+
+2002-06-20 Gerardo Ballabio <gerardo.ballabio@unimib.it>
+
+ * gmpxx.h, mpfrxx.h: Remove mpz_classref, let mpq_class::get_num and
+ mpq_class::get_den return mpz_class& as per the documentation.
+ Reported by Roberto Bagnara.
+
+2002-06-18 Kevin Ryde <kevin@swox.se>
+
+ * tests/rand/t-lc2exp.c: New file.
+ * tests/rand/Makefile.am: Add it, and use tests/libtests.la.
+
+ * randraw.c (lc): Pad seed==0 case with zero limbs, return same
+ (m2exp+1)/2 bits as normal, right shift "c" result as normal.
+
+ * configure.in: Don't bother with line numbers in some diagnostics.
+ (*-*-mingw*): Use -mno-cygwin if it works, suggested by delta trinity.
+
+ * tests/mpz/Makefile.am, tests/mpq/Makefile.am,
+ tests/misc/Makefile.am, (CLEANFILES): Set to *.tmp for test program
+ temporaries, to get t-scanf.tmp and reduce future maintenance.
+
+2002-06-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c (mpn_dc_get_str): Pass scratch memory area in
+ new `tmp' parameter. Trim allocation needs by reusing input parameter.
+
+2002-06-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v9/udiv.asm: New file.
+
+2002-06-15 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_GCC_VERSION_GE): Correction to recognising mingw
+ gcc 3.1 version number. Reported by Jim Fougeron.
+
+ * configure.in (AC_PROVIDE_AC_LIBTOOL_WIN32_DLL): New define, to make
+ AC_LIBTOOL_WIN32_DLL work with autoconf 2.53.
+
+ * acinclude.m4 (GMP_C_SIZES): Establish BITS_PER_MP_LIMB as a value,
+ not an expression, for the benefit of the gen-bases invocation.
+
+ * config.guess (CC_FOR_BUILD): Try c99, same as configfsf.guess.
+
+2002-06-15 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpfr/set_q.c: Allow for 1 bit numerator or denominator.
+
+2002-06-14 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_C_BIGENDIAN): Use new style action parameters.
+
+ * randlc2x.c: Allow for a<0, allow for c>=2^m2exp.
+ * randraw.c (lc): Allow for a==0.
+
+ * mpn/sparc32/udiv.asm: Renamed from udiv_fp.asm. Don't know if float
+ is the best way for v7, but it's what configure has chosen since gmp 3.
+ * configure.in (*sparc*-*-* ABI=32): extra_functions="udiv" for all,
+ in particular sparc32/v8/udiv.asm is faster (on ultrasparc2) than
+ udiv_fp previously used for v9 chips.
+
+ * gen-bases.c: New file, derived from mpn/mp_bases.c.
+ * dumbmp.c: New file, mostly by Torbjorn, some by me.
+ * configure.in, acinclude.m4 (GMP_PROG_CC_FOR_BUILD,
+ GMP_PROG_CPP_FOR_BUILD, GMP_PROG_EXEEXT_FOR_BUILD,
+ GMP_C_FOR_BUILD_ANSI, GMP_CHECK_LIBM_FOR_BUILD): New macros.
+ (GMP_PROG_HOST_CC): Remove, superceded by GMP_PROG_CC_FOR_BUILD.
+ * Makefile.am: Run gen-bases to create mp_bases.h and mpn/mp_bases.c.
+ * gmp-impl.h: Use mp_bases.h.
+ * mpn/mp_bases.c: Remove file.
+ * mpn/Makefile.am: mp_bases.c now in nodist_libmpn_la_SOURCES.
+
+ * tests/mpz/t-cmp_d.c (check_one_2exp): Use volatile to force to
+ double, fixes gcc 3.1 with -O4. Reported by Michael Lee.
+ * configure.in (AC_C_VOLATILE): New macro.
+
+ * tests/misc/t-scanf.c: (fromstring_gmp_fscanf): Add missing va_end.
+ Don't mix varargs and fixed args functions, not good on x86_64.
+ Reported by Marcus Meissner.
+
+ * Makefile.am (EXTRA_DIST): Remove mpfr/README, now in mpfr/Makefile.in
+
+ * configure, config.in, INSTALL.autoconf: Update to autoconf 2.53.
+ * */Makefile.in, install-sh, mdate-sh, missing, aclocal.m4, configure:
+ Update to automake 1.6.1.
+ * configfsf.guess, configfsf.sub: Update to 2002-05-29.
+
+2002-06-12 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_GCC_VERSION_GE): Recognise mingw gcc 3.1 version.
+ (GMP_PROG_CC_WORKS): Allow for a_out.exe, as per autoconf.
+ (GMP_GCC_NO_CPP_PRECOMP, GMP_ASM_UNDERSCORE): Ditto, plus a.exe.
+
+2002-06-09 Torbjorn Granlund <tege@swox.com>
+
+ * randraw.c (lc): Remove broken ASSERT_ALWAYS.
+
+ * mpn/x86: Update gmp-mparam.h files with current measures *_THRESHOLD
+ values.
+ * mpn/x86/p6/mmx/gmp-mparam.h: New file.
+
+2002-06-09 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/*/gmp-mparam.h (USE_PREINV_DIVREM_1): Add tuned settings.
+
+ * acconfig.h (HAVE_NATIVE_mpn_preinv_divrem_1): New template.
+
+ * tests/refmpn.c, tests/tests.h (refmpn_chars_per_limb,
+ refmpn_big_base): New functions.
+ * tests/mpn/t-mp_bases.c: Use them, and don't test big_base_inverted
+ unless it's being used.
+
+ * gmp.texi (Notes for Particular Systems): Using Microsoft C with DLLs.
+ (Known Build Problems): Notes on MacOS and GCC.
+ (Integer Logic and Bit Fiddling): Use ULONG_MAX for maximum ulong.
+ (Low-level Functions): mpn_get_str accepts base==256.
+ (Formatted Output Functions): Note output is not atomic.
+ (Internals): Note mp_size_t for limb counts.
+
+ * mp-h.in, gmp-h.in (mp_ptr, mp_srcptr, mp_size_t, mp_exp_t): Remove
+ these types from mp.h, not needed.
+
+ * mpfr/tests/tadd.c, mpfr/tests/tmul.c (check): Apply a hack to the
+ parameter order to make sparc gcc 2.95.2 happy.
+
+ * doc/configuration: Notes on bootstrapping.
+
+2002-06-08 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/tests/tsqrt.c, mpfr/tests/tsqrt_ui.c: Suppress tests if sqrt is
+ not affected by mpfr_set_machine_rnd_mode.
+
+ * mpfr/mul_2si.c: Workaround a mips gcc 2.95.3 bug under -O2 -mabi=n32.
+
+ * configure.in (alphev56): Fix to use ev5 path.
+
+2002-06-06 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in: Use __gmp_const not const, in a number of places.
+
+ * configure.in (sparc): Use ABI=32 instead of ABI=standard on v7 and
+ v8, for consistency with v9 choices.
+ (sparc64): Restrict GMP_ASM_SPARC_REGISTER to ABI=64.
+ (x86): Move MMX $path munging to before printout.
+ (CCAS): Move upward to support this.
+
+ * gmp-impl.h (modlimb_invert): Merge macros for specific limb sizes,
+ add a version for arbitrary limb size, use GMP_NUMB_BITS.
+ (modlimb_invert, MODLIMB_INVERSE_3): Fix comments to say GMP_NUMB_BITS.
+
+ * gmp-h.in (__GMP_LIKELY, __GMP_UNLIKELY): New macros.
+ (mpz_getlimbn, mpz_perfect_square_p, mpz_popcount): Use them, make the
+ fetch or mpn call likely, unconditionally calculate the alternative so
+ as to avoid an "else" clause.
+ * gmp-impl.h (LIKELY, UNLIKELY): Aliases.
+
+ * configure.in, mpfr/tests/Makefile.am: Add $LIBM to $LIBS for
+ MPFR_CONFIGS so it detects fesetround, and let it go through to
+ $MPFR_LIBS.
+ * mpfr/rnd_mode.c: Use gmp-impl.h to get MPFR_HAVE_FESETROUND.
+
+ * tests/mpz/t-sizeinbase.c: Disable fake bits test, such pointer
+ setups are bogus and have been seen failing on hppa.
+
+ * tests/misc.c, tests/refmpz.c, tests.tests.h, tests/mpz/t-cong.c:
+ Rename mpz_flipbit to refmpz_combit and move from misc.c to refmpz.c.
+
+2002-06-05 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-powm_ui.c Print proper routine name in error message.
+
+2002-06-03 Kevin Ryde <kevin@swox.se>
+
+ * tune/time.c, tune/freq.c, tune/speed.h: Add powerpc mftb support.
+ (FREQ_MEASURE_ONE): Move to speed.h, fix tv_sec factor.
+ (freq_measure): Use for mftb measuring too.
+ * tune/powerpc.asm, tune/powerpc64.asm: New files.
+ * configure.in, tune/Makefile.am: Add them.
+
+ * gmp-impl.h (popc_limb): Add versions for Cray and fallback for
+ arbitrary limb size.
+
+ * mpn/sparc32/sparc-defs.m4: New file.
+ * configure.in (sparc*-*-*): Use it.
+ * acinclude.m4 (GMP_ASM_SPARC_REGISTER): New macro.
+ * configure.in (sparc64): Use it. Also, use -Wc,-m64 for linking.
+ * mpn/sparc64/add_n.asm, mpn/sparc64/addmul_1.asm,
+ mpn/sparc64/copyd.asm, mpn/sparc64/copyi.asm, mpn/sparc64/lshift.asm,
+ mpn/sparc64/mul_1.asm, mpn/sparc64/rshift.asm,
+ mpn/sparc64/sqr_diagonal.asm, mpn/sparc64/sub_n.asm,
+ mpn/sparc64/submul_1.asm: Use REGISTER for .register.
+
+2002-06-01 Kevin Ryde <kevin@swox.se>
+
+ * mpz/powm_ui.c: Fix for result range in certain circumstances.
+
+ * mpn/x86/k6/diveby3.asm: Speedup to 10 c/l, same as divexact_1.
+ Anomaly pointed out by Alexander Kruppa.
+
+2002-05-31 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/export.c: Cast pointer via `unsigned long' when checking
+ alignment to avoid compiler warnings.
+
+2002-05-29 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (BSWAP_LIMB): Versions for m68k, powerpc, and arbitrary
+ limb size.
+ * configure.in, acconfig.h (HAVE_HOST_CPU_FAMILY_m68k): New define.
+
+2002-05-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_basecase.c: Improve MAX_LEFT handling, returning
+ when possible. Add code for mpn_addmul_5 and mpn_addmul_6.
+
+2002-05-25 Kevin Ryde <kevin@swox.se>
+
+ * tune/tuneup.c: Misc nailifications, and disable preinv thresholds
+ with nails.
+ * tune/speed.h: Use GMP_NUMB_HIGHBIT with mpn_sb_divrem_mn and
+ mpn_divrem_2.
+ * mpz/powm.c (redc): Nailify q.
+
+ * tests/mpn/t-scan.c: Reduce the amount of testing, to go faster.
+
+2002-05-23 Torbjorn Granlund <tege@swox.com>
+
+ * Version 4.1 released.
+
+ * mpn/alpha/ev6/nails/gmp-mparam.h: New file.
+
+ * tests/devel/add_n.c (refmpn_add_n): Nailify.
+ * tests/devel/sub_n.c (refmpn_sub_n): Nailify.
+ * tests/devel/addmul_1.c (refmpn_addmul_1): Nailify.
+ * tests/devel/submul_1.c (refmpn_submul_1): Nailify.
+
+ * mpn/alpha/ev6/nails/add_n.asm: New file.
+ * mpn/alpha/ev6/nails/sub_n.asm: New file.
+ * mpn/alpha/ev6/nails/mul_1.asm: New file.
+ * mpn/alpha/ev6/nails/submul_1.asm: New file.
+
+2002-05-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/nails/addmul_1.asm: New file.
+
+ * mpz/inp_str.c (mpz_inp_str_nowhite): Nailify.
+
+ * mpn/generic/mul_basecase.c: Update pointers before conditional
+ MAX_LEFT break statements.
+
+2002-05-21 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-gcd.c: Test mpz_gcd_ui.
+
+ * mpz/lcm_ui.c: Nailify.
+
+ * mpz/gcd_ui.c: Nailify. Make it work as documented, allowing
+ NULL to be passed for result parameter. Fix gcd(0,0) case.
+
+ * mpz/set_str.c: Nailify.
+
+ * randlc2x.c (gmp_randinit_lc_2exp): Nailify.
+
+ From Jakub Jelinek:
+ * longlong.h (add_ssaaaa,sub_ddmmss) [64-bit sparc]:
+ Make it actually work.
+
+2002-05-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/ui_div.c: Shut up compiler warning.
+
+ * mpn/generic/mul_basecase.c: Use mpn_addmul_2, mpn_addmul_3, and
+ mpn_addmul_4, as available.
+
+ * mpn/alpha/ev6/nails/addmul_2.asm: Adjust NAILS_SUPPORT decls.
+ * mpn/alpha/ev6/nails/addmul_3.asm: Likewise
+ * mpn/alpha/ev6/nails/addmul_4.asm: Likewise.
+
+ * configure.in (*-cray-unicos*): Back again to -hscalar0.
+ (gmp_mpn_functions_optional): Add mul_3, mul_4, addmul_2, addmul_3,
+ and addmul_4.
+ * acconfig.h: Add #undefs for new optional mpn functions.
+
+2002-05-18 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Integer Import and Export): Mention Cray unfilled words.
+
+ * mpz/set_d.c, mpq/set_d.c: Use LIMBS_PER_DOUBLE for the output of
+ __gmp_extract_double. Reported by Henrik Johansson.
+
+2002-05-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/nails/addmul_2.asm: New file.
+ * mpn/alpha/ev6/nails/addmul_3.asm: New file.
+ * mpn/alpha/ev6/nails/addmul_4.asm: New file.
+
+ * mpn/generic/dump.c: Rewrite and nailify.
+
+2002-05-16 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/Makefile.am (EXTRA_DIST): Add BUGS file.
+
+2002-05-15 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (*-cray-unicos*): Remove -hscalar0, add -hnofastmd
+ as workaround for compiler bug.
+ (mips64*-*-*): Pass just -O1 to cc, to work around compiler bug.
+
+2002-05-14 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (*-cray-unicos*): Pass -hscalar0 to work around
+ compiler bug for mpz/import.c.
+
+2002-05-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/import.c: Cast pointer via `unsigned long' when checking
+ alignment to avoid compiler warnings.
+
+ * mpn/generic/rootrem.c: Adjust allocation of qp temporary area.
+
+2002-05-09 Kevin Ryde <kevin@swox.se>
+
+ * mpz/import.c: Corrections to size store, special case tests, and
+ general case ACCUMULATE.
+ * tests/mpz/t-import.c, tests/mpz/t-export.c: More test data.
+
+2002-05-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/rootrem.c: Use temp space for root, copy value in place
+ before returning.
+ * mpz/root.c: Don't allocate extra limb for root value.
+ * mpz/perfpow.c: Undo last change.
+
+2002-05-08 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (powerpc BSWAP_LIMB_FETCH): Rename local variable to make
+ it not clash with caller.
+
+ * mpn/generic/rootrem.c: New file.
+ * configure.in (gmp_mpn_functions): Add rootrem and pow_1.
+ * mpn/Makefile.am (nodist_libdummy_la_SOURCES): Add rootrem.c and
+ pow_1.c
+ * gmp-impl.h (mpn_rootrem): Add declaration.
+ * mpz/perfpow.c: Amend allocations for mpn_rootrem requirements.
+ * mpz/root.c: Rewrite to use mpn_rootrem.
+
+2002-05-08 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (MUL_KARATSUBA_THRESHOLD etc): Remove forced nail values.
+
+ * mpf/fits_u.h, mpf/fits_s.h, tests/mpf/t-fits.c: Ignore fraction
+ part, making the code match the documentation.
+
+ * gmpxx.h (struct __gmp_binary_minus): Use mpz_ui_sub.
+
+2002-05-07 Kevin Ryde <kevin@swox.se>
+
+ * mpn/powerpc32/README: New file.
+
+ * mpz/root.c: Use unsigned long with mpz_sub_ui not mp_limb_t.
+
+ * tune/README: Misc updates including sparc32/v9 smoothness, low res
+ timebase, and mpn_add_n operand overlaps.
+ * tune/many.pl: Add udiv.asm support.
+
+ * gmp.texi (Build Options): A couple of --build better as --host.
+ (Known Build Problems, Notes for Package Builds): Add DESTDIR problem.
+ (Compatibility with older versions): Compatible with 4.x versions.
+ (Converting Integers): Remove mpz_get_ui + mpz_tdiv_q_2exp decompose.
+ (Integer Import and Export): New section.
+ (Miscellaneous Integer Functions): Clarify mpz_sizeinbase returns 1
+ for operand of 0.
+ (Language Bindings): Add GNU Pascal.
+ (Low-level Functions): Add GMP_NUMB_MAX.
+
+ * tests/mpz/t-import.c, tests/mpz/t-export.c, tests/mpz/t-get_d.c:
+ New tests.
+ * tests/mpz/Makefile.am: Add them.
+
+ * mpz/import.c, mpz/export.c: New files.
+ * Makefile.am, mpz/Makefile.am, gmp-h.in: Add them.
+
+ * gmp-h.in, gmp-impl.h (GMP_NUMB_MAX): Move to gmp.h.
+ * gmp-impl.h (CNST_LIMB): Add cast to mp_limb_t to ensure unsigned.
+ (CRAY_Pragma, MPN_REVERSE, MPN_BSWAP, MPN_BSWAP_REVERSE,
+ ASSERT_ALWAYS_LIMB, ASSERT_ALWAYS_MPN): New macros.
+ (MPZ_CHECK_FORMAT): Use ASSERT_ALWAYS_MPN.
+
+2002-05-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/aors_ui.h: Nailify.
+
+ * tests/mpz/t-addsub.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add t-addsub.
+
+ * mpz/ui_sub.c: New file.
+ * mpz/Makefile.am (libmpz_la_SOURCES): Add ui_sub.c.
+ * Makefile.am (MPZ_OBJECTS): Ditto.
+ * gmp-h.in (mpz_ui_sub): Add declaration.
+
+ * gmp-impl.h (MPZ_REALLOC): Rewrite to allow the use of _mpz_realloc
+ return value.
+
+ * gmp-h.in (mpn_pow_1): Add declaration.
+
+ * mpn/generic/pow_1.c: Handle exp <= 1. Reverse rp/tp parity scheme
+ for bn == 1 arm.
+
+ * Rename MP_LIMB_T_HIGHBIT => GMP_LIMB_HIGHBIT.
+
+2002-05-06 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (main): Don't call mpz_sizeinbase with negative base.
+
+ * randraw.c (lc): Remove an unused variable.
+
+ * mpn/generic/get_str.c: Clarify an algorithm description.
+
+ * tests/mpf/t-trunc.c: Nailify.
+ * tests/mpf/t-set_si.c: Disable for nails.
+
+ * mpf/cmp_si.c: Nailify.
+ * mpf/cmp_ui.c: Nailify.
+ * mpf/div.c: Nailify.
+ * mpf/div_2exp.c: Nailify.
+ * mpf/div_ui.c: Nailify.
+ * mpf/eq.c: Nailify.
+ * mpf/get_d.c: Nailify.
+ * mpf/get_d_2exp.c: Nailify.
+ * mpf/get_si.c: Nailify.
+ * mpf/get_str.c: Nailify.
+ * mpf/get_ui.c: Nailify.
+ * mpf/mul_2exp.c: Nailify.
+ * mpf/random2.c: Nailify.
+ * mpf/set_q.c: Nailify.
+ * mpf/set_si.c: Nailify.
+ * mpf/set_str.c: Nailify.
+ * mpf/set_ui.c: Nailify.
+ * mpf/sub.c: Nailify.
+ * mpf/ui_div.c: Nailify.
+ * mpf/ui_sub.c: Nailify.
+ * mpf/urandomb.c: Nailify.
+
+ * gmp-impl.h (__GMPF_BITS_TO_PREC, __GMPF_PREC_TO_BITS): Nailify.
+
+ * mpz/get_si.c: Misc variable name changes.
+
+ * mpf/fits_u.h: Rewrite - nailify.
+ * mpf/fits_s.h: Likewise.
+
+ * mpz/mod.c: Disambiguate if-statement with extra {}.
+
+ * mpf/int_p.c: Fix type of size variables.
+ * mpf/get_ui: Likewise.
+ * mpf/get_si: Likewise.
+ * mpq/equal.c: Likewise.
+ * mpq/get_d.c: Likewise.
+ * mpz/cmp_d.c: Likewise.
+ * mpz/cmpabs_d.c: Likewise.
+ * mpz/divis_2exp.c: Likewise.
+ * mpz/kronuz.c: Likewise.
+ * mpz/kronzu.c: Likewise.
+ * mpz/kronzs.c: Likewise.
+ * mpz/kronsz.c: Likewise.
+ * mpz/scan0.c: Likewise.
+ * mpz/scan1.c: Likewise.
+ * mpz/tstbit.c: Likewise.
+ * mpz/cong_2exp.c: Likewise.
+ * mpz/divis.c: Likewise.
+
+2002-05-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/gcd.c: Additional nailify changes.
+
+2002-05-04 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (__GNU_MP_VERSION): Set to 4.1.
+ * Makefile.am (-version-info): Bump for new release.
+
+2002-04-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/divrem_1.c: Additional nailify changes.
+ * mpn/generic/mod_1.c: Likewise.
+
+ * tests/mpq/t-get_d.c: Print floats with all 16 digits.
+
+ * mpq/get_d.c: Nailify.
+
+ * tests/mpq/t-set_f.c: Disable for nails.
+
+ * mpz/get_d.c: Nailify.
+
+ * gmp-impl.h (LIMBS_PER_DOUBLE, MP_BASE_AS_DOUBLE): Nailify.
+
+ * gmp-h.in (__GMPZ_FITS_UTYPE_P): Cast maxval to before shifting it.
+
+ * extract-dbl.c: Nailify.
+
+2002-04-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpq/md_2exp.c (mord_2exp): Nailify.
+
+ * mpq/cmp_ui.c: Nailify.
+
+ * mpq/cmp.c (mpq_cmp): Nailify.
+
+ * mpn/generic/gcd.c: Nailify. GNUify code layout.
+
+ * mpn/generic/gcdext.c: Nailify. Misc changes.
+
+ * tests/mpz/t-sqrtrem.c: Let argv[1] mean # of repetitions.
+ * tests/mpz/t-gcd.c: Likewise.
+
+ * mpz/gcd.c: Nailify.
+
+ * mpn/generic/random.c: Nailify.
+
+ * gmp-impl.h (modlimb_invert): Nailify.
+
+2002-04-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/gcdext.c (div2): Remove qh parameter.
+ (mpn_gcdext): Streamline double-limb code.
+ Move GCDEXT_THRESHOLD check to after initial division.
+
+2002-04-27 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (JACOBI_MOD_OR_MODEXACT_1_ODD): Allow for odd
+ GMP_NUMB_BITS.
+
+ * tune/time.c (sgi_works_p): Allow for 64-bit counter, and fix
+ SGI_CYCLECNTR_SIZE handling.
+
+ * demos/expr/exprfr.c: Add nan and inf constants.
+ * demos/expr/t-expr.c: Exercise them.
+
+2002-04-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/cmp_ui.c: Fix overflow conditions for nails.
+
+ * gmp-h.in (mpz_get_ui): Fix typo from last change.
+
+ * mpz/n_pow_ui.c: Adjust allocation for nails.
+ (GMP_NUMB_HALFMAX): Renamed from MP_LIMB_T_HALFMAX.
+ Fix umul_ppmm invocation for for nails.
+
+2002-04-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/gcdext.c: Simplify by using mpn_tdiv_qr instead of
+ mpn_divmod.
+
+2002-04-24 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (*-*-cygwin*): Give a sensible default command line
+ limit, to avoid blowups reported by Jim Fougeron on windows 9x.
+ (--enable-nails): Make the default 2, since mp_bases has data for that.
+
+ * mpfr/mpfr-math.h (__mpfr_nan): Use a "double" for the bytes, to
+ avoid a mis-conversion on alpha gcc 3.0.2.
+ (_MPFR_INFP_BYTES, _MPFR_INFM_BYTES): Should be a zero mantissa.
+
+2002-04-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/dive_ui.c: Fix typo.
+
+ * mpz/fits_s.h: Rewrite.
+
+ * mpz/jacobi.c: Nailify.
+ * mpz/kronuz.c: Additional nailify changes.
+ * mpz/kronsz.c: Likewise.
+
+2002-04-23 Kevin Ryde <kevin@swox.se>
+
+ * demos/expr/Makefile.am (LDADD): Add $(LIBM) for the benefit of mpfr.
+
+ * mpz/divis_ui.c, mpz/cong_ui.c: Nailify.
+ * mpn/generic/bdivmod.c, mpz/divexact.c, mpz/dive_ui.c: Nailify.
+ * mpn/generic/sb_divrem_mn.c, mpn/generic/divrem.c,
+ mpn/generic/divrem_2.c: Nailify ASSERTs.
+ * mpn/x86/k6/mmx/logops_n.asm, mpn/x86/k6/mmx/com_n.asm: Nailify.
+ * mpz/inp_raw.c, mpz/out_raw.c: Nailify.
+ * mpz/kronzu.c, mpz/kronuz.c, mpz/kronzs.c, mpz/kronsz.c: Nailify.
+ * mpn/generic/divis.c, mpz/cong.c, mpz/cong_2exp.c: Nailify.
+ * gmp-impl.h (NEG_MOD): Nailify.
+
+ * gmp-impl.h, mpn/mp_bases.c: Add back GMP_NUMB_BITS==30 bases data.
+
+ * mpfr/get_d.c: Patch from Paul to avoid problem with constant folding
+ in gcc on OSF.
+
+ * mpn/lisp/gmpasm-mode.el: Remove mention of defunct LF macro.
+
+2002-04-22 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c: Handle "binomial" operator.
+
+ * mpz/cmp_ui.c: Move assignments of `up' out of conditionals.
+
+ * mpn/generic/gcdext.c: Fix fencepost error in STAT code.
+
+ * gmp-impl.h (mpn_com_n): Nailify.
+
+ * tests/mpz/t-cdiv_ui.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add t-cdiv_ui.
+ * mpz/cdiv_qr_ui.c: Nailify.
+ * mpz/cdiv_q_ui.c: Nailify.
+ * mpz/cdiv_r_ui.c: Nailify.
+ * mpz/cdiv_ui.c: Nailify.
+
+ * tests/misc/t-printf.c (CHECK_N): Add cast to allow `char' to be an
+ unsigned type.
+ * tests/misc/t-scanf.c: Likewise.
+
+ * mpz/mul_i.h: Rework nails code to handle parameter overlap.
+
+ * tests/mpz/t-set_f.c: Disable for nails.
+
+2002-04-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/set_si.c: Add cast to support LONG_LONG_LIMB.
+ * mpz/iset_si.c: Likewise.
+
+ * mpz/bin_ui.c: Nailify.
+ * mpz/bin_uiui.c: Nailify.
+
+ * mpz/cmpabs_ui.c: Nailify.
+
+ * tests/mpz/t-aorsmul.c: Nailify.
+ * mpz/aorsmul_i.c (mpz_addmul_ui, mpz_submul_ui): Nailify better.
+
+2002-04-20 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-fdiv_ui.c: Check mpz_fdiv_ui.
+ * tests/mpz/t-tdiv_ui.c: Check mpz_tdiv_ui.
+
+ * mpz/tdiv_ui.c: Rewrite nails code.
+ * mpz/fdiv_ui.c: Nailify.
+
+ * tests/mpz/t-tdiv_ui.c: Check returned remainders.
+ * tests/mpz/t-fdiv_ui.c: Merge in recent t-tdiv_ui changes.
+
+ * mpz/tdiv_q_ui.c: Remove spurious TMP_* calls.
+
+ * mpz/fdiv_qr_ui.c: Nailify.
+ * mpz/fdiv_q_ui.c: Nailify.
+ * mpz/fdiv_r_ui.c: Nailify.
+
+ * mpz/get_si.c: Misc nailify changes to shut up compiler warnings.
+
+ * mpz/ui_pow_ui.c: Fix typo in last change.
+
+2002-04-20 Kevin Ryde <kevin@swox.se>
+
+ * tests/misc/t-printf.c, tests/misc/t-scanf.c: Check all %n types.
+
+ * mpn/x86/k7/mmx/divrem_1.asm, mpn/x86/p6/mmx/divrem_1.asm
+ (mpn_preinv_divrem_1): New entrypoint.
+ (mpn_divrem_1): Avoid a branch when testing high<divisor.
+ * mpn/asm-defs.m4: Add define_mpn(preinv_divrem_1).
+ * configure.in: Allow divrem_1.asm to provide mpn_preinv_divrem_1.
+
+ * gmp-impl.h [nails]: Add #undefs of MUL_KARATSUBA_THRESHOLD etc, to
+ override CPU gmp-mparam.h. Remove JACOBI_BASE_METHOD override since
+ it's nails-neutral.
+
+ * tests/mpn/t-mp_bases.c: New file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add it.
+ * tests/t-constants.c: Move MP_BASES constants checks to it.
+
+ * mpn/mp_bases.c: Fix big_base_inverted values for nails.
+ * gmp-impl.h (MP_BASES_BIG_BASE_INVERTED_10,
+ MP_BASES_NORMALIZATION_STEPS_10): Fix nails values.
+ (MP_BASES_*): Remove GMP_NUMB_BITS == 30 data.
+
+ * mpn/x86/pentium/com_n.asm, mpn/x86/pentium/logops_n.asm: Add
+ NAILS_SUPPORT indicators.
+
+ * configure.in: Grep for NAILS_SUPPORT in cpu-specific code, and look
+ in "nails" subdirectories, print path used.
+ * mpn/asm-defs.m4 (NAILS_SUPPORT): New macro.
+
+ * mpfr/mpfr-test.h: Include config.h, for the benefit of test programs
+ not using gmp-impl.h.
+
+2002-04-19 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-scan.c: Nailify.
+
+ * mpz/tdiv_qr_ui.c: Nailify.
+ * mpz/tdiv_q_ui.c: Nailify.
+ * mpz/tdiv_r_ui.c: Nailify.
+ * mpz/tdiv_ui.c: Nailify.
+
+ * mpz/cmp_ui.c: Nailify.
+
+ * mpz/ui_pow_ui.c: Misc nailify changes to shut up compiler warnings.
+
+ * mpz/scan0.c: Nailify.
+ * mpz/scan1.c: Nailify.
+
+ * tests/mpz/t-sizeinbase.c (mpz_fake_bits): Nailify.
+
+2002-04-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/aorsmul_i.c: Nailify.
+
+ * mpz/cmp_si.c: Nailify (botched).
+
+ * mpz/ui_pow_ui.c: Nailify.
+
+ * gmp-h.in (__GMPZ_FITS_UTYPE_P): Nailify.
+
+ * mpz/fits_s.h: Nailify.
+
+ * tests/mpz/bit.c (check_tstbit): Nailify.
+
+ From Paul Zimmermann:
+ * mpn/generic/sqrtrem.c: Nailify.
+
+ * mpz/n_pow_ui.c: Nailify.
+
+ * mpz/cfdiv_r_2exp.c: Nailify.
+
+ * randraw.c (lc): Undo: Let mpn_rshift put result in place to avoid
+ extra MPN_COPY.
+
+2002-04-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/clrbit.c: Add two GMP_NUMB_MASK masks after addition.
+
+ * mpn/generic/random2.c (LOGBITS_PER_BLOCK): Decrease to 4.
+
+ * gmp-impl.h (nail DIV_DC_THRESHOLD): Decrease to 50 to allow fast
+ division.
+
+ * mpn/generic/random2.c: Nailify.
+
+ * mpz/fac_ui.c: Nailify.
+
+ * mpz/mul_i.h: #if ... #endif code block to shut up gcc warnings.
+
+ * mpn/generic/sqrtrem.c: Adopt to GNU coding standards.
+ (mpn_dc_sqrtrem): New name for mpn_dq_sqrtrem.
+ Partial nailification.
+
+ * configure.in: As a temporary hack, clear extra_functions for nails
+ builds.
+
+ * gmp-h.in (mpz_get_ui): #if ... #endif else code block to shut up gcc
+ warnings.
+
+2002-04-17 Kevin Ryde <kevin@swox.se>
+
+ * texinfo.tex: Update to 2002-03-26.08 per texinfo 4.2.
+ * gmp.texi: Must have @top in @ifnottex (or @contents doesn't come out
+ in one run).
+
+ * mpn/generic/scan0.c, mpn/generic/scan1.c: Nailify.
+
+ * tests/mpn/t-scan.c: New file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add it.
+
+ * tests/refmpn.c, tests/tests.h (refmpn_tstbit): Use unsigned long for
+ bit index.
+ (refmpn_setbit, refmpn_clrbit, refmpn_scan0, refmpn_scan1): New
+ functions.
+
+ * mpfr/cmp_ui.c (mpfr_cmp_si_2exp): Fix b==0 i!=0 case.
+
+2002-04-17 Gerardo Ballabio <gerardo.ballabio@unimib.it>
+
+ * gmpxx.h, mpfrxx.h: Remove mpfr_class bool combinations, remove
+ mpfr_class::get_str2, use mp_rnd_t for rounding modes, use
+ 8*sizeof(double) for mpfr_t's holding doubles.
+
+2002-04-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/powm.c: Nailify.
+ * mpz/powm_ui.c: Nailify.
+
+2002-04-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/hamdist.c: Nailify.
+ * tests/misc.c (urandom): Nailify.
+
+ * mpz/get_si.c: Nailify.
+ * gmp-h.in (mpz_get_ui): Nailify. Streamline (and probably upset
+ memory checkers).
+
+ * gmp-impl.h (mp_bases[10] values): Add versions for GMP_NUMB_BITS
+ being 28, 60, and 63.
+ * mpn/mp_bases.c: Add tables for GMP_NUMB_BITS being 28, 60, and 63.
+
+ * mpz/iset_si.c: Nailify.
+ * mpz/iset_ui.c: Nailify
+
+ * tests/mpz/convert.c (main): Print test number in error message.
+
+ * mpn/generic/get_str.c (mpn_sb_get_str): Shift up `frac' into nails
+ field after bignum division.
+
+2002-04-16 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in, gmp-impl.h (GMP_NAIL_MASK): Move to gmp.h.
+
+ * gmp.texi: Use @documentdescription and @copying, per texinfo 4.2.
+ (Low-level Functions): Clarify mpn_gcd overlap requirements, rewrite
+ mpn_set_str description, add nails section.
+ (C++ Interface General): Remove bool from types that mix with classes.
+ (Language Bindings): Add STklos, GNU Smalltalk, Regina.
+ (Binary to Radix, Radix to Binary): Describe new code.
+ (Assembler Cache Handling): More notes, mostly by Torbjorn.
+
+ * macos/configure (%vars): Remove __GMP from substitutions, per change
+ to main configure.
+
+ * mpn/generic/dive_1.c: Nailify.
+ * mpn/generic/mode1o.c: Nailify, remove bogus ASSERT in commented-out
+ alternate implementation.
+ * gmp-impl.h (SUBC_LIMB): New macro.
+
+ * tests/devel/try.c (validate_divexact_1): Correction to compare.
+ (udiv_qrnnd): New testing.
+ (SHIFT_LIMIT): Nailify.
+ (-b): New option, remove spurious "H" from getopt string.
+
+ * mpz/clrbit.c: Nailify.
+ * tests/mpz/t-hamdist.c: Nailify.
+ * gmp-impl.h (MPN_FIB2_SIZE): Nailify.
+ (PP): Nailify conditionals.
+ * tests/mpz/t-fib_ui.c (MPZ_FIB_SIZE_FLOAT): Nailify.
+
+ * configure.in, acinclude.m4: Establish GMP_NAIL_BITS and
+ GMP_LIMB_BITS for gmp-h.in configure tests.
+
+ * mpfr/*, configure.in: Update to final mpfr 2.0.1.
+ * mpfr/acinclude.m4 (MPFR_CONFIGS): Use $host, not uname stuff.
+ * mpfr/tests/tout_str.c: Patch from Paul for denorm fprintf tests.
+
+2002-04-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/divrem_1.c (EXTRACT): Remove.
+
+ * tests/mpz/t-tdiv_ui.c (dump_abort): Accept argument for error string.
+
+ * mpz/rrandomb.c: Nailify. Needs further work.
+
+ * mpn/generic/mod_1.c: Nailify.
+
+ * gmp-impl.h: Set various *_THRESHOLD values to be used for nails to
+ avoid not yet qualified algorithms.
+ (MPZ_CHECK_FORMAT): Check that nail part is zero.
+
+ * tests/mpz/t-mul.c (main): Test squaring even for huge operands.
+ (base_mul): Nailify.
+ (dump_abort): Accept argument for error string. Print product
+ difference.
+
+ * mpn/generic/set_str.c: Nailify.
+
+ * gmp-h.in (__GMPN_ADD, __GMPN_SUB): Nailify.
+
+2002-04-14 Torbjorn Granlund <tege@swox.com>
+
+ * randraw.c (lc): Return non-nonsense return value for seed=0 case.
+ Check for m2exp being non-zero early; remove all other tests of m2exp.
+ Remove redundant MPN_ZERO call.
+ Let mpn_rshift put result in place to avoid extra MPN_COPY.
+ Remove confusing comment before function `lc' describing BBS algorithm.
+ Misc simplification and cleanups.
+ Nailify. Needs further work.
+
+ * mpz/set_si.c: Nailify.
+ * mpz/set_ui.c: Nailify.
+ * mpz/mul_i.h: Nailify.
+
+ * tests/mpz/t-mul_i.c: Actually test _ui routines. Add some more test
+ values.
+
+ * mpn/generic/mul_n.c: Finish nailifying toom3 code.
+
+2002-04-13 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*: Update to another new mpfr 2.0.1.
+ * configure.in, Makefile.am, mpfr/Makefile.am, mpfr/tests/Makefile.am:
+ Use MPFR_CONFIGS macro, establish separate MPFR_CFLAGS for mpfr build.
+
+ * mpfr/tests/Makefile.am: Correction to convenience rule for libmpfr.a.
+
+2002-04-11 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/set_q.c: gmp-impl.h before mpfr.h to avoid _PROTO redefine.
+
+ * mpfr/*, configure.in: Update to new mpfr 2.0.1.
+
+ * tests/refmpn.c (refmpn_udiv_qrnnd, refmpn_divmod_1c_workaround):
+ Fixes for nails.
+
+ * tests/t-constants.c (MODLIMB_INVERSE_3): Nailify tests.
+ (MP_BASES_BIG_BASE_INVERTED_10, MP_BASES_NORMALIZATION_STEPS_10): Only
+ check these under USE_PREINV_DIVREM_1.
+ * tests/t-modlinv.c: Nailify tests.
+
+2002-04-11 Gerardo Ballabio <gerardo.ballabio@unimib.it>
+
+ * gmpxx.h: Remove bool combinations, remove mpf_class::get_str2, only
+ need <iosfwd> now.
+
+2002-04-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/diveby3.c: Nailify.
+ * gmp-impl.h (MODLIMB_INVERSE_3): Nailify.
+
+ * mpn/generic/mul_n.c: Nailify Toom3 code.
+
+2002-04-10 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (MPN_KARA_MUL_N_MINSIZE, MPN_KARA_SQR_N_MINSIZE): Set to
+ 3, as needed by nails case.
+
+ * mpn/generic/addmul_1.c, mpn/generic/submul_1.c [nails]: Fix vl
+ assert, add rp,n and up,n asserts.
+
+ * mpfr/Makefile.am: Add new mpfr-math.h, install mpf2mpfr.h.
+
+2002-04-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/divrem_1.c: Nailify. Update mp_size_t variables to use
+ `n' suffix instead of `size' suffix.
+ * mpn/generic/divrem_2.c: Likewise.
+ * mpn/generic/sb_divrem_mn.c: Nailify.
+ * mpn/generic/tdiv_qr.c: Nailify.
+ (SHL): Remove silly macro.
+
+ * mpn/generic/mul_n.c (mpn_kara_mul_n): Replace open-coded increment by
+ mpn_incr_u call. Handle nails in ws[n] increment.
+ * mpn/generic/mul_n.c (mpn_kara_sqr_n): Likewise.
+
+ * gmp-h.in (GMP_NUMB_MASK): New #define.
+ (__GMPN_AORS_1): Add version for nails.
+
+ * gmp-impl.h (GMP_NUMB_MASK): Comment out, now in gmp.h.
+ (mpn_incr_u): Don't assume `incr' is non-zero.
+ (mpn_decr_u): Similarly.
+
+2002-04-09 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/*, configure.in: Update to mpfr 2.0.1.
+
+ * tests/refmpn.c (refmpn_mul_1c, lshift_make): Corrections for nails.
+ * tssts/refmpn.c, tests/tests.h (refmpn_cmp_allowzero): New function.
+
+ * mpn/generic/mul_1.c [nails]: Fix vl assert, add {up,n} assert.
+
+ * mpn/pa32/hppa1_1/pa7100/addmul_1.asm,
+ mpn/pa32/hppa1_1/pa7100/submul_1.asm: Rename "size" define, to avoid
+ ELF .size directive. Reported by LaMont Jones.
+
+ * tests/mpz/t-set_si.c: Add nails support.
+
+2002-04-05 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h: Replace nail mpn_incr_u, mpn_decr_u with faster versions.
+ (mp_bases[10] values): Check GMP_NUMB_BITS instead of BITS_PER_MP_LIMB.
+ Add GMP_NUMB_BITS == 30 version.
+ (__gmp_doprnt, etc): Remove parameter names.
+
+ * mpn/generic/mul_n.c: Nailify Karatsuba code.
+ * mpn/generic/get_str.c: Nailify.
+ * mpn/generic/sqr_basecase.c: Nailify.
+ * mpn/generic/lshift.c: Nailify.
+ * mpn/generic/rshift.c: Likewise.
+ * mpn/generic/add_n.c: Nailify. Revamp non-nail code.
+ * mpn/generic/sub_n.c: Likewise.
+ * mpn/generic/mul_1.c: Likewise.
+ * mpn/generic/addmul_1.c: Likewise.
+ * mpn/generic/submul_1.c: Likewise.
+
+2002-04-02 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (BSWAP_LIMB_FETCH, BSWAP_LIMB_STORE) [powerpc]:
+ Corrections to constraints, and restrict to bigendian.
+
+2002-03-31 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpz/dive.c: Better diagnostics.
+
+ * tests/devel/try.c (mpn_get_str, mpn_umul_ppmm_r): New tests.
+
+ * tests/misc.c, tests/tests.h (byte_diff_lowest, byte_diff_highest):
+ New functions.
+
+ * tests/t-bswap.c: New file.
+ * tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * tests/mpn/t-aors_1.c, tests/mpn/t-iord_u.c: Add nails support.
+
+ * gmp-impl.h (MPN_IORD_U) [x86]: Eliminate unnecessary jiord and iord,
+ rename "n" to incr per generic versions, restrict to nails==0.
+ (mpn_incr_u, mpn_decr_u): Add nails support.
+ (GMP_NAIL_LOWBIT, GMP_NUMB_MAX): New macros.
+
+ * tests/trace.c, tests/tests.h (byte_trace, byte_tracen): New
+ functions.
+ * tests/trace.c: Handle NULL operands.
+
+ * tests/refmpn.c, tests/devel/try.c, tune/speed.c: Add preliminary
+ nail support.
+
+ * tests/refmpn.c, test/tests.h (byte_overlap_p, refmpn_equal_anynail,
+ refmpn_umul_ppmm_r, refmpn_udiv_qrnnd_r, refmpn_get_str,
+ refmpn_bswap_limb, refmpn_random, refmpn_random2, refmpn_bswap_limb):
+ New functions.
+
+ * gmp-impl.h, tests/refmpn.c (ASSERT_LIMB): Renamed from
+ ASSERT_MP_LIMB_T.
+
+ * mpn/x86/*/*.asm, mpn/powerpc32/*/*.asm, mpn/powerpc64/*/*.asm: Put
+ speeds after the copyright notice, so as to keep that clear.
+
+2002-03-29 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (powerpc*-*-aix*): Correction to xlc -qarch selection,
+ for 32-bit mode.
+
+2002-03-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn: Fix spacing in many files.
+
+ * mpn/generic/aorsmul_1.c: Split into addmul_1.c and submul_1.c.
+ * mpn/generic/aors_n.c: Split into add_n.c and sub_n.c.
+
+ * mpn/pa64/add_n.asm: Trim another 0.125 cycle/limb. Fix a comment.
+ * mpn/pa64/sub_n.asm: Likewise.
+
+ * mpn/pa64/mul_1.asm: Change comclr, comb to proper forms cmpclr, cmpb.
+ * mpn/pa64/addmul_1.asm: Likewise.
+ * mpn/pa64/submul_1.asm: Likewise.
+
+2002-03-28 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Converting Integers): Fix type of exp in mpz_get_d_2exp,
+ reported by epl@unimelb.edu.au.
+ (References): Update Burnikel and Ziegler URL, reported by Keith
+ Briggs.
+
+ * gmp-h.in, mp-h.in, configure.in, acinclude.m4: Remove __GMP from
+ AC_SUBSTs, since autoconf says leading "_" in makefile variables is
+ not portable.
+
+ * demos/expr/run-expr.c: Declare optarg, optind, opterr if necessary.
+ * configure.in, demos/expr/expr-config-h.in: Configs for this.
+
+2002-03-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/Makefile.am (TARG_DIST): Remove pa64w and hppa, add pa32.
+
+ * configure.in (path_20w): Remove pa64w.
+
+ * mpn/pa64/udiv_qrnnd.asm: Tweak for PA8000 performance comparative to
+ that on PA8500.
+
+2002-03-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa32: New name for mpn/hppa.
+ * configure.in: Corresponding changes.
+
+ * mpn/pa64/umul_ppmm.asm: New file, generalized for both 2.0N and 2.0W.
+ * mpn/pa64/umul_ppmm.S: Remove.
+
+ * mpn/pa64/udiv_qrnnd.asm: Generalize for both 2.0N and 2.0W.
+ * mpn/pa64w/udiv_qrnnd.asm: Remove.
+
+2002-03-26 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/tests/tdiv.c, mpfr/tests/tui_div.c: Don't depend on nan and inf
+ handling in "double", for the benefit of alpha.
+
+ * configure (hppa2.0w): Set path to "pa64w pa64".
+
+ * acinclude.m4, configure.in (GMP_C_INLINE): New macro.
+ * acinclude.m4 (GMP_H_EXTERN_INLINE): Use it, and fix "yes" handling.
+
+2002-03-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64w/add_n.s: Remove.
+ * mpn/pa64w/sub_n.s: Remove.
+ * mpn/pa64w/lshift.s: Remove.
+ * mpn/pa64w/rshift.s: Remove.
+ * mpn/pa64w/mul_1.S: Remove.
+ * mpn/pa64w/addmul_1.S: Remove.
+ * mpn/pa64w/submul_1.S: Remove.
+ * mpn/pa64w/sqr_diagonal.asm: Remove.
+
+ * mpn/pa64/mul_1.asm: New file with twice faster code; generalized
+ for both 2.0N and 2.0W.
+ * mpn/pa64/submul_1.asm: Likewise.
+ * mpn/pa64/mul_1.S: Remove.
+ * mpn/pa64/submul_1.S: Remove.
+
+ * mpn/pa64/sqr_diagonal.asm: Generalize for both 2.0N and 2.0W.
+
+ * mpn/pa64/add_n.asm: New file, generalized for both 2.0N and 2.0W.
+ * mpn/pa64/sub_n.asm: Likewise.
+ * mpn/pa64/lshift.asm: Likewise.
+ * mpn/pa64/rshift.asm: Likewise.
+ * mpn/pa64/add_n.s: Remove.
+ * mpn/pa64/sub_n.s: Remove.
+ * mpn/pa64/lshift.s: Remove.
+ * mpn/pa64/rshift.s: Remove.
+
+2002-03-24 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (BSWAP_LIMB_FETCH, BSWAP_LIMB_STORE): New macros.
+ * mpz/inp_raw.c, mpz/out_raw.c: Use them.
+ * acconfig.h (HAVE_HOST_CPU): Add some powerpc types.
+
+ * mpn/powerpc32/750/com_n.asm: New file.
+
+ * mpfr/tests/tout_str.c: Disable random tests, since they fail on
+ alphaev56-unknown-freebsd4.1 and do nothing by default.
+
+ * mpfr/tests/tsqrt.c: Don't depend on nan, inf or -0 in "double", for
+ the benefit of alpha.
+ * mpfr/sqrt.c: Clear nan flag on -0.
+
+ * demos/factorize.c: Use mpn_random() instead of random(), to avoid
+ portability problems.
+
+ * demos/isprime.c (print_usage_and_exit): Declare as "void" to avoid
+ warnings.
+
+ * demos/pexpr.c (setup_error_handler): Corrections to sigstack code.
+
+ * demos/calc/calc.y: Add some `;'s to make bison 1.34 happy.
+
+2002-03-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64/addmul_1.asm: New file with twice faster code; generalized
+ for both 2.0N and 2.0W.
+
+2002-03-22 Kevin Ryde <kevin@swox.se>
+
+ * tune/time.c: Add SGI hardware counter measuring method, change some
+ abort()s into ASSERT_FAIL()s.
+
+ * configure.in (AC_CHECK_HEADERS): Add fcntl.h and sys/syssgi.h.
+ (AC_CHECK_FUNCS): Add syssgi.
+
+ * configure.in, mpfr/Makefile.am, mpfr/tests/Makefile.am: Use
+ -mieee-with-inexact or -ieee_with_inexact for mpfr on alpha, so
+ denorms work.
+
+ * mpfr/isinteger.c: Fix a memory leak.
+
+2002-03-21 Torbjorn Granlund <tege@swox.com>
+
+ * tune/speed.c (struct choice_t): Make `r' an mp_limb_t.
+
+2002-03-21 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (HAVE_LIMB_BIG_ENDIAN, HAVE_LIMB_LITTLE_ENDIAN): Use an
+ AH_VERBATIM and better explanation.
+ * acinclude.m4 (GMP_C_DOUBLE_FORMAT): Similarly for the HAVE_DOUBLE
+ constants.
+
+ * gmp.texi (Number Theoretic Functions): Clarify sign of GCD returned
+ by mpz_gcdext.
+
+ * demos/pexpr.c, demos/pexpr-config-h.in, configure.in: Use an
+ autoconf test for stack_t.
+
+ * configure.in, gmp-h.in, mp-h.in, macos/configure, tests/mpz/reuse.c,
+ tests/mpf/reuse.c: Use __GMP_LIBGMP_DLL to enable windows declspec,
+ don't require _WIN32 (etc), remove __GMP_LIBGMP_SHARED and
+ __GMP_LIBGMP_STATIC.
+
+ * gmp-impl.h (mp_bases): Add __GMP_DECLSPEC, for the benefit of
+ tests/t-constants.c.
+
+ * tune/many.pl, tune/speed.h: Remove suffix hack for back.asm.
+
+2002-03-21 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpfr/sin_cos.c (mpfr_sin_cos): New file.
+ * mpfr/mpfr.h, mpfr/mpfr.texi, mpfr/Makefile.am: Add it.
+ * mpfr/tan.c: Fix sign in 2nd and 4th quadrants.
+
+ * mpfr/log10.c: Fix hangs on certain inputs.
+
+2002-03-20 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (setup_error_handler): Declare `s', the first
+ sigaltstack parameter, using `stack_t' just on AIX.
+
+2002-03-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/mul_1.asm: Use free caller-saves registers instead
+ of the callee-saves r30 and r31.
+
+2002-03-19 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c (freq_proc_cpuinfo): Recognise powerpc "clock", where
+ previously got the wrong result from "bogomips".
+
+ * mpn/powerpc32/add_n.asm, mpn/powerpc32/sub_n.asm: Rewrite, faster on
+ 750, and smaller too.
+ * mpn/powerpc32/*.asm: Use L(), add some measured speeds.
+
+ * longlong.h (count_trailing_zeros) [vax]: Add a version using ffs,
+ but commented out.
+
+2002-03-17 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.c, tune/speed.h, tune/common.c, many.pl: Use optional
+ ".r" to specify operand overlaps for mpn_add_n, mpn_sub_n and logops.
+ Remove mpn_add_n_inplace and mpn_add_n_self.
+ * tune/many.pl: Fix MULFUNC_PROLOGUE parsing.
+
+ * gmp.texi (Known Build Problems): Note `make' problem with long
+ libgmp.la dependencies list.
+
+ * printf/doprnt.c, scanf/doscan.c (%zn): Remove test of non-existent
+ HAVE_SIZE_T, just use size_t unconditionally.
+ * printf/doprnt.c (%zd etc): Fix 'z' type parsing.
+ * tests/misc/t-printf.c, tests/misc/t-scanf.c: More tests.
+
+ * configure.in: Use AC_COPYRIGHT.
+ Add m4_pattern_allow(GMP_MPARAM_H_SUGGEST).
+
+ * tune/Makefile.am (libdummy.la): Remove this, sqr_basecase.c already
+ gets an ansi2knr rule from nodist_tuneup_SOURCES.
+
+ * longlong.h (count_leading_zeros) [pentiumpro gcc<3]: Test
+ HAVE_HOST_CPU_i686 too.
+
+ * mpz/out_raw.c (HTON_LIMB_STORE): Fix a typo in big endian #if.
+
+2002-03-14 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/com_n.asm, mpn/x86/pentium/logops_n.asm,
+ mpn/x86/k6/mmx/com_n.asm: Add nails support.
+
+ * texinfo.tex: Update to 2002-03-01.06 (per texinfo 4.1).
+ * gmp.texi (@ma): Remove, @math does this now.
+
+ * mpfr/tests/reuse.c: Clear op1 and op2 flags only in their respective
+ outer loops.
+
+ * configure.in (--enable-cxx): Correction to the default stated in the
+ help string.
+ (power*-*-aix*, not powerpc): Use aix.m4, don't run
+ GMP_ASM_POWERPC_R_REGISTERS or use powerpc-defs.m4.
+
+2002-03-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/gmp-mparam.h: New file.
+
+2002-03-13 Kevin Ryde <kevin@swox.se>
+
+ * demos/expr/exprfr.c: More mpfr functions, corrections to agm, cos,
+ sin, rename log2 constant to loge2 to make room for log2 function.
+ * demos/expr/t-expr.c: More tests.
+
+ * mpz/inp_raw.c (NTOH_LIMB_FETCH) [generic 16bit]: Remove spurious "+".
+
+ * mpfr/acos.c: Avoid a memory leak for certain operands.
+
+ * acinclude.m4, configure.in (GMP_C_DOUBLE_FORMAT): New macro.
+
+ * acinclude.m4 (GMP_HPC_HPPA_2_0, GMP_ASM_UNDERSCORE,
+ GMP_ASM_ALIGN_LOG, GMP_ASM_LSYM_PREFIX, GMP_ASM_W32, GMP_ASM_X86_MMX):
+ Change ac_objext to OBJEXT, which is the documented variable.
+
+ * config.guess (powerpc*-*-*): Use #ifdef on constants POWER_630 etc
+ in the AIX test, since old versions don't have them all.
+
+2002-03-11 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (LIBC211): New AC_DEFINE, for mpfr.
+
+ * configure.in (mips*-*-*): Support ABI=o32 on irix 6, allow gcc 2.7.2
+ to fall back on it, but detect it doesn't work with gcc 2.95. Use
+ single mips-defs.m4 for both mips32 and mips64.
+ * acinclude.m4 (GMP_GCC_MIPS_O32): New macro.
+ * mpn/mips32/mips-defs.m4: Renamed from mips.m4.
+ * mpn/mips64/mips.m4: Remove (was a copy of mips32/mips.m4).
+
+ * mpn/powerpc32/750: New directory.
+ * configure.in (powerpc740, powerpc750, powerpc7400): Use it.
+ * mpn/powerpc32/750/gmp-mparam.h: New file.
+
+ * config.sub, gmp.texi (ultrasparc1): Remove this, just use plain
+ "ultrasparc".
+
+2002-03-10 Kevin Ryde <kevin@swox.se>
+
+ * mpfr: Update to 20020301, except internal_ceil_exp2.c,
+ internal_ceil_log2.c, internal_floor_log2.c renamed to i_ceil_exp2.c,
+ i_ceil_log2.c, i_floor_log2.c to be unique in DOS 8.3. And sqrtrem.c
+ removed since no longer required.
+ * mpfr/mpfr.texi: Fix some formatting.
+ * mpfr/tests/reuse.c: Patch by Paul to fix test4 variable handling.
+ * mpfr/sinh.c: Patch by Paul to fix err calculation when t==0.
+ * mpfr/tests/tget_d.c: Disable until portability of rnd_mode.c can be
+ sorted out.
+
+ * configure.in (powerpc*-*-*): Separate gcc and xlc cpu flags setups
+ for clarity.
+
+ * longlong.h (count_leading_zeros, count_trailing_zeros) [x86_64]: New
+ macros.
+
+2002-03-07 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Build Options): Note all the ultrasparcs accepted.
+ (Language Bindings): Add Math::BigInt::GMP.
+
+ * config.sub (ultrasparc2i): New cpu type.
+ * config.guess (sparc-*-*, sparc64-*-*): Add some exact CPU detection.
+
+2002-03-05 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h (count_leading_zeros, count_trailing_zeros) [alphaev67,
+ alphaev68]: Use ctlz and cttz insns (as per gcc longlong.h).
+ (count_leading_zeros) [sparclite]: Fix parameter order (as per gcc
+ longlong.h).
+ * acconfig.h (HAVE_HOST_CPU_alphaev68): New define.
+
+ * config.guess [i?86-*-*]: Suppress error messages if compiler not
+ found or test program won't run.
+ [rs6000-*-*, powerpc-*-*]: Force code alignment for mfpvr test.
+
+2002-03-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/pow_1.c: New file.
+
+2002-03-03 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Build Options): Note compiler must be able to fully link,
+ add alphapca57 and alphaev68, give a clearer example of MPN_PATH
+ (Debugging): Add notes on valgrind.
+ (C++ Formatted Output): Clarify mpf showbase handling, in particular
+ note "00.4" in octal.
+
+ * printf/doprntf.c: Do a showbase on octal float fractions, for
+ instance "00.4" where previously it gave "0.4".
+ * tests/cxx/t-ostream.cc: Update.
+
+ * gmp-h.in, mp-h.in (__GMP_DECLSPEC, __GMP_DECLSPEC_XX): Test
+ __WIN32__ for Borland C, reported by "delta trinity".
+
+ * gmp-h.in, mp-h.in: Use <cstddef> for size_t under C++, suggested by
+ Hans Aberg some time ago.
+ * gmp-h.in (<iosfwd>): Move to top of file for clarity.
+
+ * Makefile.am (libgmpxx_la_SOURCES): Use dummy.cc to force C++.
+ (CXX_OBJECTS): Add osfuns$U.lo.
+ * dummy.cc: New file.
+ * cxx/Makefile.am (INCLUDES): Use __GMP_WITHIN_GMPXX.
+ (libcxx_la_SOURCES): Add osfuns.cc.
+ * gmp-h.in (__GMP_DECLSPEC_XX): New define, use it on libgmpxx funs.
+ * gmp-impl.h: Add __GMP_DECLSPEC to libgmp functions used by libgmpxx.
+
+ * longlong.h (COUNT_TRAILING_ZEROS_TIME): Remove, no longer used.
+
+ * gmp-impl.h (MPN_SIZEINBASE, MPN_SIZEINBASE_16): Correction to
+ __totbits for nails.
+
+ * gmp-impl.h (JACOBI_LS0): Test size before limb, to pacify valgrind.
+ (JACOBI_0LS): Ditto, and fix parens around arguments.
+
+ * mpn/x86/x86-defs.m4 (call_mcount): Add a counter to make data labels
+ unique, since simplified L() scheme no longer gives that effect.
+ (notl_or_xorl_GMP_NUMB_MASK): New macro.
+ Add m4_assert_numargs in a few places.
+
+ * configure.in (*sparc*): Fix cycle counter setups for ABI=64.
+
+2002-02-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/vax/gmp-mparam.h: New file.
+
+2002-02-28 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (gmp_errno, gmp_version): Move into extern "C" block,
+ reported by librik@panix.com.
+
+ * gmp-h.in, mp-h.in (__GMP_DECLSPEC_EXPORT, __GMP_DECLSPEC_IMPORT):
+ Use __declspec(dllexport) and __declspec(dllimport) on Borland.
+ * gmp-h.in (_GMP_H_HAVE_FILE): Test __STDIO_H for Borland.
+ Reported by "delta trinity".
+
+ * gmp-impl.h (va_copy): Fall back on memcpy, not "=".
+
+ * mpn/generic/pre_mod_1.c: Add a comment about obsolescence.
+
+ * tune/time.c (MICROSECONDS_P): Don't trust time differences of 1
+ microsecond.
+
+ * tests/cxx/t-ostream.cc: Use "const char *" not just "char *" for
+ test data strings, avoids warnings on Sun CC.
+
+2002-02-27 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: For sparc under solaris2.[7-9], pass -fsimple=1 to
+ disable some crazy -fast optimizations.
+
+2002-02-25 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: For sparc under solaris2.[7-9], pass -fns=no to enable
+ denorm handling under -fast.
+
+2002-02-25 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (alpha*-*-*): Rearrange -mcpu selection for gcc,
+ provide an ev67 -> ev6 fallback. Fix -arch,-tune selection for DEC C.
+ Allow ~ for space in optional options lists.
+
+ * tune/tuneup.c (tune_preinv_divrem_1): Compare against an assembler
+ mpn_divrem_1 if it exists, not the generic C mpn_divrem_1_div.
+ (tune_preinv_mod_1): Ditto with mpn_mod_1.
+
+ * tune/time.c (DIFF_SECS_ROUTINE): Eliminate the unused "type"
+ parameter, try to make the code a bit clearer.
+
+ * tune/freq.c: Reduce the period measured for cycles versus
+ gettimeofday, add cycles versus microsecond getrusage.
+
+ * mpz/array_init.c: "i" should be mp_size_t, noticed by E. Khong.
+
+2002-02-24 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: For sparc under solaris2.[7-9], pass -fast instead of
+ other optimization options.
+
+2002-02-23 Kevin Ryde <kevin@swox.se>
+
+ * mpn/asm-defs.m4 (GMP_NUMB_MASK): New macro.
+ (PROLOGUE, EPILOGUE): Relax quoting for the benefit of tune/many.pl
+ when GSYM_PREFIX non-empty.
+
+ * tune/time.c, tune/speed.h (speed_time_init): Include clock tick
+ period in speed_time_string.
+ * tune/time.c, configure.in (clock_gettime): New measuring method.
+
+ * tune/many.pl: Add -DHAVE_NATIVE_mpn_foo to C objects, to avoid
+ conflicts with a macro version in gmp-impl.h, eg. mpn_com_n.
+
+2002-02-22 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c: Increase RLIMIT_STACK to 4Mibyte.
+
+2002-02-22 Kevin Ryde <kevin@swox.se>
+
+ * tune/tuneup.c: Don't confuse gcc with mipspro cc in diagnostic.
+
+2002-02-20 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (mips*-*-irix[6789]*]): Set `extra_functions_n32', not
+ `extra_functions'.
+
+ * printf/doprnt.c: Conditionally include inttypes.h.
+ * printf/repl-vsnprintf.c: Likewise.
+ * scanf/doscan.c: Likewise.
+
+2002-02-20 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k7/mmx/com_n.asm: New file.
+
+ * mpz/n_pow_ui.c (SWAP_RP_TP): Use ASSERT_CODE on ralloc and talloc,
+ to ensure they needn't live past the initial allocs in a normal build.
+
+ * mpn/generic/mod_34lsub1.c: Note this is for internal use.
+
+2002-02-19 Torbjorn Granlund <tege@swox.com>
+
+ * Clean up *_THRESHOLD names. Many files affected.
+
+ * mpn/mips32: Asm-ify 32-bit mips code.
+ Move files from `mips2' to `mips32' directory.
+ * mpn/mips64: Move files from `mips3' to `mips64' directory.
+ * configure.in: Change `mips2' => `mips32' and `mips3' => `mips64'.
+
+2002-02-19 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4, configure.in (GMP_PROG_LEX): New macro.
+
+ * tune/tuneup.c (one): Start next threshold at a max of previous ones,
+ in order to get a good starting point for TOOM3_SQR_THRESHOLD if
+ KARATSUBA_SQR_THRESHOLD is 0 (ie. using mpn_mul_basecase only).
+
+ * configure.in, tune/tuneup.c (GMP_MPARAM_H_SUGGEST): New AC_DEFINE
+ replacing GMP_MPARAM_H_FILENAME. Suggest a new file in a cpu specific
+ subdirectory rather than mpn/generic.
+
+ * acinclude.m4 (POWERPC64_PATTERN): New macro.
+ * configure.in (powerpc*-*-*): Use it.
+ (powerpc*-*-*): Use umul in 32L and aix64.
+ (mips*-*-*): Use umul, 32 and 64 bit versions.
+
+2002-02-18 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h: Add basic x86-64 support.
+
+2002-02-17 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c: Support `-X' for upper case hex, make `-x' output
+ lower case hex.
+
+ * mpn/mips2/umul.s: Make it actually work.
+ * mpn/mips3/umul.asm: New file.
+
+ * mpn/mips2/gmp-mparam.h: New file.
+
+2002-02-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c (mpn_sb_get_str): Round frac upwards after
+ umul_ppmm calls.
+
+2002-02-16 Kevin Ryde <kevin@swox.se>
+
+ * config.guess (alpha-*-*): Do alpha exact cpu probes on any system,
+ and only if configfsf.guess gives a plain "alpha".
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Detect a gcc 3.0.3 powerpc64
+ linker invocation problem.
+
+2002-02-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c (mpn_sb_get_str): For base 10, develop initial
+ digits using umul_ppmm, then switch to plain multiplication.
+
+ * config.guess: Rewrite Alpha subtype detection code for *bsd systems.
+
+2002-02-15 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Build Options): Note powerpc exact cpu types.
+ (Debugging): Advertise DEBUG in memory.c.
+
+ * config.sub, config.guess: Add some powerpc exact cpus.
+ * configure.in: Add configs for them.
+
+ * memory.c [__NeXT__]: Remove unused #define of "static".
+ (__gmp_default_allocate, __gmp_default_reallocate): Print size if
+ allocation fails, don't use perror.
+
+ * gmp-h.in: g++ 3 demands __GMP_NOTHROW is before other attributes.
+
+2002-02-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/mul_1.asm: Fix typo preventing build on T3E systems.
+
+2002-02-14 Kevin Ryde <kevin@swox.se>
+
+ * tune/tuneup.c (tune_set_str): Increase max_size, for the benefit of
+ alpha.
+
+ * macos/README: Bug reports to bug-gmp@gnu.org, clarify MacOS X a bit.
+
+ * mpn/generic/gcdext.c [WANT_GCDEXT_ONE_STEP]: Add missing TMP_FREE.
+
+ * tune/speed.c, tune/tuneup.c: Allow for speed_cycletime of 0.0 in
+ some diagnostic printouts.
+ * tune/time.c (speed_cycletime): Note can be 0.0.
+
+2002-02-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/mul_1.asm: Add mpn_mul_1c entry.
+
+ * mpn/pa64w/sqr_diagonal.asm: Use L() for labels.
+
+2002-02-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c (mpn_sb_get_str): Change declaration of rp to
+ accommodate tuneup compiles.
+
+2002-02-11 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/default.m4, mpn/alpha/unicos.m4 (PROLOGUE_cpu): Add
+ noalign option.
+ * mpn/alpha/default.m4 (PROLOGUE_cpu): use ALIGN instead of ".align".
+
+ * gmp.texi (Debugging): Notes on Checker.
+ (Other Multiplication): Move note on float FFTs to here.
+ (Assembler Floating Point): New text and revisions by Torbjorn,
+ picture formatting by me.
+ Simplify tex pictures elsewhere a bit, share heights, eliminate some
+ gaps at line joins.
+
+2002-02-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c (mpn_sb_get_str): Rewrite to generate fraction
+ limbs and use multiplication for digit development. Trim allocation of
+ buf. Get rid of code for !USE_MULTILIMB.
+
+2002-02-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/set_str.c (mpn_set_str): Undo this:
+ Change invocations of mpn_add_1 to instead use mpn_incr_u.
+
+ * tests/mpz/convert.c: Free str only after it is used in error message.
+
+ * mpn/generic/get_str.c (mpn_sb_get_str): Combine tail code for base 10
+ and generic bases.
+
+ * mpn/mp_bases.c: Add entries for base 256. Remove __ prefix from
+ table name.
+ * gmp-impl.h (__mp_bases): Remove superfluous mp_ part of name, making
+ it __gmpn_bases instead of __gmpn_mp_bases.
+ (mp_bases): New #define.
+ * tune/speed.h (SPEED_ROUTINE_MPN_SET_STR): Allow bases up to 256.
+ (SPEED_ROUTINE_MPN_GET_STR): Likewise.
+
+2002-02-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/set_str.c (mpn_set_str): Use mpn_mul_1c if available.
+ Change invocations of mpn_add_1 to instead use mpn_incr_u.
+
+2002-02-09 Kevin Ryde <kevin@swox.se>
+
+ * mpz/array_init.c, mpz/cfdiv_q_2exp.c, mpz/cfdiv_r_2exp.c,
+ mpz/cong_2exp.c, mpz/divis_2exp.c, mpz/hamdist.c, mpz/init2.c,
+ mpz/mul_2exp.c, mpz/realloc2.c, mpz/scan0.c, mpz/scan1.c,
+ mpz/setbit.c, mpz/tdiv_q_2exp.c, mpz/tdiv_r_2exp.c, mpz/tstbit.c,
+ mpz/urandomb.c: Use GMP_NUMB_BITS.
+
+ * mpz/iset_str.c [__CHECKER__]: Store a dummy value to the low limb to
+ stop it appearing uninitialized.
+
+ * gmp-h.in (__GMP_NOTHROW): New macro.
+ (mp_set_memory_functions, mpz_cmp, mpz_cmp_si, mpz_cmp_ui, mpz_cmpabs,
+ mpz_cmpabs_ui, mpz_congruent_2exp_p, mpz_divisible_2exp_p,
+ mpz_fits_sint_p, mpz_fits_slong_p, mpz_fits_sshort_p, mpz_fits_uint_p,
+ mpz_fits_ulong_p, mpz_fits_ushort_p, mpz_get_si, mpz_get_ui,
+ mpz_getlimbn, mpz_hamdist, mpz_popcount, mpz_scan0, mpz_scan1,
+ mpz_size, mpz_sizeinbase, mpz_swap, mpz_tstbit, mpq_equal, mpq_swap,
+ mpf_cmp, mpf_cmp_si, mpf_cmp_ui, mpf_fits_sint_p, mpf_fits_slong_p,
+ mpf_fits_sshort_p, mpf_fits_uint_p, mpf_fits_ulong_p,
+ mpf_fits_ushort_p, mpf_get_default_prec, mpf_get_prec, mpf_get_si,
+ mpf_get_ui, mpf_integer_p, mpf_set_default_prec, mpf_set_prec_raw,
+ mpf_size, mpf_swap, mpn_add_1, mpn_cmp, mpn_hamdist, mpn_popcount,
+ mpn_sub_1): Use it.
+
+ * gmp-impl.h (MPN_SIZEINBASE, MPN_SIZEINBASE_16): New macros from
+ mpn_sizeinbase, and use GMP_NUMB_BITS.
+ * mpz/get_str.c, mpz/sizeinbase.c, mpbsd/mout.c, tune/speed.h: Use
+ MPN_SIZEINBASE.
+ * mpbsd/mtox.c: Use MPN_SIZEINBASE_16.
+
+ * configure.in, mpn/Makefile.am, gmp-impl.h (mpn_sizeinbase): Remove.
+ * mpn/generic/sizeinbase.c: Remove file.
+
+ * gmp-impl.h (MPN_GET_STR_SIZE): Remove.
+ * tests/mpn/t-g_str_size.c: Remove file.
+ * tests/mpn/Makefile.am: Update.
+
+ * Makefile.am (dist-hook): Don't distribute cvs merge ".#" files.
+
+2002-02-08 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Override extra_functions for all sparcv8 systems, not
+ just supersparc.
+
+2002-02-06 Kevin Ryde <kevin@swox.se>
+
+ * tune/tuneup.c (tune_mul, tune_sqr): Disable FFTs until tuned.
+ * tune/speed.h (SPEED_ROUTINE_MPN_SET_STR): Fix memory clobber in
+ destination cache priming.
+
+ * printf/doprnt.c: Fix parsing of %s and %p conversions.
+ * tests/misc/t-printf.c (check_misc): Add some tests.
+
+2002-02-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v8/udiv.asm: New file, from v8/supersparc.
+
+ * mpn/generic/set_str.c: Rename indigits_per_limb => chars_per_limb.
+ Remove redundant chars_per_limb. Reverse 4 loops in basecase code for
+ speed. Use MP_BASES_CHARS_PER_LIMB_10.
+
+2002-02-03 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_PROG_NM): Ensure -B or -p get used when doing a
+ cross compile with the native nm, helps OSF for instance.
+ (GMP_ASM_LSYM_PREFIX): Remove ".byte 0" for the benefit of irix 6,
+ allow "N" from nm for OSF, allow for "t" for other systems, but prefer
+ no mention of the symbol at all.
+
+ * tune/tuneup.c (print_define_remark): New function.
+ Turn some "#if"s into plain "if"s.
+
+ * tune/tuneup.c, gmp-impl.h, tune/Makefile.am
+ (GET_STR_BASECASE_THRESHOLD, GET_STR_PRECOMPUTE_THRESHOLD): Tune these.
+ * mpn/generic/get_str.c [TUNE_PROGRAM_BUILD]: Cope with non-constant
+ GET_STR_PRECOMPUTE_THRESHOLD.
+
+2002-02-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c (mpn_get_str): Fix typo in a declaration.
+
+2002-02-02 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/set_str.c: Use MP_PTR_SWAP and POW2_P, add __GMP_PROTO
+ to convert_blocks prototype, disable SET_STR_BLOCK_SIZE sanity check.
+
+ * tune/set_strb.c, tune/set_strs.c: New files.
+ * tune/speed.h, tune/speed.c, tune/common.c,tune/Makefile.am: Add them.
+ * tune/tuneup.c: Tune SET_STR_THRESHOLD.
+ (DEFAULT_MAX_SIZE): Renamed from MAX_SIZE, allow any param.max_size[].
+
+2002-02-01 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/convert.c: Increase operand size. Add (yet disabled) code
+ for testing with random strings.
+
+ * mpn/generic/get_str.c (mpn_get_str): Rewrite to become sub-quadratic.
+ (mpn_dc_get_str, mpn_sb_get_str): New functions.
+
+2002-01-31 Kevin Ryde <kevin@swox.se>
+
+ * gmpxx.h (cmp): Renamed from "compare".
+
+ * configure.in (AC_C_BIGENDIAN): Don't abort when cross compiling.
+ (PROLOGUE): Allow new style optional second parameter when grepping.
+
+ * acinclude.m4 (GMP_HPC_HPPA_2_0, GMP_ASM_UNDERSCORE,
+ GMP_ASM_ALIGN_LOG, GMP_ASM_LSYM_PREFIX, GMP_ASM_W32, GMP_ASM_X86_MMX):
+ Use $ac_objext for object filenames.
+ (GMP_ASM_UNDERSCORE): Use CCAS to assemble.
+
+ * demos/pexpr-config-h.in: New file.
+ * configure.in: Generate demos/pexpr-config.h.
+ (AC_CHECK_FUNCS): Add clock, cputime, setrlimit, sigaction,
+ sigaltstack, sigstack.
+ * acinclude.m4 (GMP_SUBST_CHECK_FUNCS, GMP_SUBST_CHECK_HEADERS): New
+ macros.
+ * demos/pexpr.c: Use pexpr-config.h, not various #ifdefs.
+ (setup_error_handler): Use signal if sigaction not available, allow
+ for SIGBUS missing on mingw.
+ (main): Use time() for random seed if gettimeofday not available.
+ (cleanup_and_exit): Move SIGFPE out of LIMIT_RESOURCE_USAGE.
+
+2002-01-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/set_str.c: Rewrite to become sub-quadratic.
+ (convert_blocks): New function.
+
+2002-01-30 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (GMP_NUMB_MASK, GMP_NAIL_MASK, GMP_NUMB_HIGHBIT,
+ ASSERT_MPN, ASSERT_MP_LIMB_T): New macros.
+
+ * mpn/generic/fib2_ui.c: Use GMP_NUMB_BITS, simplify the data
+ generator program, share __gmp_fib_table initializers between bit
+ sizes, cope with bit sizes other than those specifically setup.
+ * gmp-impl.h (FIB_TABLE_LIMIT, FIB_TABLE_LUCNUM_LIMIT): Corresponding
+ rearrangement of conditionals.
+ * tests/mpz/t-fib_ui.c (check_fib_table): New test.
+
+2002-01-28 Kevin Ryde <kevin@swox.se>
+
+ * mpz/set_si.c, mpz/iset_si.c: Store to _mp_d[0] unconditionally, use
+ an expression for _mp_size.
+
+ * mpz/init.c, mpz/init2.c, mpz/iset.c, mpq/init.c [__CHECKER__]: Store
+ dummy values to low limbs to stop them appearing uninitialized.
+
+2002-01-26 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/mpfr-test.h (MAX, MIN, ABS): Use instead a patch from Paul and
+ Vincent.
+
+2002-01-24 Kevin Ryde <kevin@swox.se>
+
+ * configure.in: Extra quoting to get argument help messages right.
+
+ * gmp.texi (Efficiency): Suggest hex or octal for input and output.
+ (Formatted Output Strings): Mention "*" for width and precision.
+
+ * mpn/generic/sizeinbase.c: New file, adapted from mpz/sizeinbase.c.
+ Use POW2_P, use __mp_bases[base].big_base for log2(base).
+ * configure.in, mpn/Makefile.am: Add it.
+ * gmp-impl.h: Add prototype.
+ * mpz/sizeinbase.c, tune/speed.h, mpn/generic/get_str.c,
+ mpz/get_str.c, mpbsd/mout.c, mpbsd/mtox.c: Use it.
+ * mpz/get_str.c: Write directly to user buffer, skip at most one
+ leading zero, eliminate special case for x==0.
+ * mpbsd/mtox.c: Allocate exact result space at the start, eliminate
+ special case for x==0.
+ * mpbsd/mout.c: Only need to skip one high zero with mpn_sizeinbase.
+
+ * configure.in (--enable-nails): New option.
+ (GMP_NAIL_BITS, GMP_LIMB_BITS, GMP_NUMB_BITS): New defines for gmp.h
+ and config.m4.
+ * gmp-h.in: Add templates.
+
+ * mpfr/mpfr-test.h (MAX, MIN, ABS): Use #ifndef to avoid a redefine
+ error on AIX xlc.
+
+2002-01-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c: Correct type of `out_len'.
+
+2002-01-22 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/pre_divrem_1.c: Corrections to some ASSERTs.
+
+ * mpfr/mul_ui.c: Don't call mpn_lshift with 0 shift.
+
+ * mpfr/mpz_set_fr.c: Produce correct mpz_t for f==0.
+
+2002-01-21 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (32-bit powerpc add_ssaaaa): Remove spurious commutative
+ declaration.
+ (64-bit powerpc add_ssaaaa): Likewise.
+
+2002-01-20 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_FUNC_VSNPRINTF): Use %n to better detect sparc
+ solaris 2.7 problems.
+
+2002-01-19 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (mpz_eval_expr): Optimize s^rhs for -1 <= s <= 1.
+ (cleanup_and_exit): Improve error message wording.
+
+2002-01-19 Kevin Ryde <kevin@swox.se>
+
+ * mpfr/mpfr.h (_PROTO): Use __GMP_PROTO, for compatibility with
+ gmp-impl.h.
+
+2002-01-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpfr/mpfr-test.h: Test "__hpux", not "hpux". Mask off mrand48
+ return value to 31 bits to work around sloppy mpfr #include practices.
+
+ * mpfr/tests/*.c: Use #include "", not <>, for gmp.h and mpfr.h.
+ Make sure to #include mpfr-test.h from all files that use random().
+
+2002-01-17 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (__GMP_REALLOCATE_FUNC_MAYBE_TYPE): New macro.
+ * gmp-impl.h, mpz/get_str.c, mpz/out_raw.c, mpq/get_str.c,
+ mpq/set_str.c, mpf/get_str.c, printf/asprntffuns.c, printf/doprnt.c,
+ printf/repl-vsnprintf.c, printf/snprntffuns.c, scanf/doscan.c,
+ mpbsd/mtox.c: Some fixes to compile as C++.
+
+ * mpn/generic/jacbase.c (JACOBI_BASE_METHOD): New tuned parameter,
+ replacing COUNT_TRAILING_ZEROS_TIME test. Add a third method too.
+ * tune/speed.c, tune/speed.h, tune/common.c, tune/Makefile.am: Add
+ measuring of mpn_jacobi_base methods.
+ * tune/jacbase1.c, tune/jacbase2.c, tune/jacbase3.c: New files.
+ * tune/tuneup.c (JACOBI_BASE_METHOD): Tune this.
+ * mpn/x86/*/gmp-mparam.h (COUNT_TRAILING_ZEROS_TIME): Remove macro.
+
+ * gmp-h.in: Use __gmp prefix on variables in inlines.
+
+ * gmp-impl.h (MPN_COPY_INCR, MPN_COPY_DECR): Remove __i, unused.
+
+ * mpn/generic/mul_fft.c: Use HAVE_NATIVE_mpn_addsub_n, not ADDSUB.
+ Use CNST_LIMB for some constants.
+
+2002-01-15 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpbsd/Makefile.am: Add a convenience rule for ../libtests.la.
+
+ * printf/Makefile.am: libdummy.la should be in EXTRA_LTLIBRARIES.
+
+ * mpf/out_str.c: Use MPF_SIGNIFICANT_DIGITS, so mpf_out_str and
+ mpf_get_str give the same for ndigits==0.
+
+ * mpfr/exceptions.c (mpfr_set_emin, mpfr_set_emax): Work around a
+ powerpc64 gcc 3.0 -O2 bug.
+
+ * tests/memory.c, tests/tests.h (tests_memory_validate): New function.
+
+2002-01-14 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/sb_divrem_mn.c, mpn/generic/divrem_1.c,
+ mpn/generic/divrem_2.c, mpn/generic/mod_1.c: Don't use UMUL_TIME and
+ UDIV_TIME, just default to preinv.
+ * gmp-impl.h (USE_PREINV_DIVREM_1, USE_PREINV_MOD_1): Ditto.
+ (DIVEXACT_1_THRESHOLD, MODEXACT_1_ODD_THRESHOLD): Don't use UMUL_TIME
+ and UDIV_TIME, make default thresholds 0.
+ (UDIV_NORM_PREINV_TIME, UDIV_UNNORM_PREINV_TIME): Remove macros.
+ * mpn/x86/*/gmp-mparam.h (UMUL_TIME, UDIV_TIME,
+ UDIV_NORM_PREINV_TIME): Remove macros.
+
+ * gmp.texi (Headers and Libraries): New section, being the header
+ notes from "GMP Basics" and some new stuff.
+ (Parameter Conventions): Notes on "const" parameters.
+ (Formatted Output Strings): Add type N, tweak some wording.
+
+ * tests/refmpn.c (refmpn_divmod_1c): Avoid a bug in i386 gcc 3.0.
+
+2002-01-12 Kevin Ryde <kevin@swox.se>
+
+ * mpz/root.c: Add <stdlib.h>, for abort().
+
+ * mpfr/tests/Makefile.am (AUTOMAKE_OPTIONS): Add ansi2knr.
+ * mpfr/mpfr.h, mpfr/mpfr-tests.h, reuse.c, tadd.c, tadd_ui.c, tagm.c,
+ tatan.c, tcmp2.c, tcos.c, tdiv.c, tdiv_ui.c, teq.c, texp.c,
+ tget_str.c, thyperbolic.c, tlog.c, tmul.c, tout_str.c, tpow.c,
+ trandom.c, tset_z.c, tsin.c, tsqrt.c, tsqrt_ui.c, tsub_ui.c, ttan.c,
+ tui_div.c: Fixes for K&R.
+
+ * tests/misc/t-scanf.c (check_misc, check_misc):
+
+ * tests/mpz/t-inp_str.c, tests/mpq/t-inp_str.c, tests/misc/t-scanf.c:
+ Avoid strings in ASSERT, not enjoyed by K&R.
+ * gmp-impl.h (ASSERT): Note this.
+
+ * tests/tests.h (refmpn_mod_34lsub1): Add __GMP_PROTO.
+
+ * mpbsd/Makefile.am: Avoid an automake problem with ansi2knr and
+ sources in a different directory.
+
+ * printf/repl-vsnprintf.c: Test HAVE_LONG_DOUBLE for long double.
+
+ * mpn/Makefile.am (nodist_libdummy_la_SOURCES): Add mod_34lsub1.c,
+ mul_2.c, pre_divrem_1.c.
+
+ * gmp-h.in, gmp-impl.h (mpn_add_nc, mpn_addmul_1c, mpn_addsub_n,
+ mpn_addsub_nc, mpn_divrem_1c, mpn_dump, mpn_mod_1c, mpn_mul_1c,
+ mpn_mul_basecase, mpn_sqr_n, mpn_sqr_basecase, mpn_sub_nc,
+ mpn_submul_1c): Move to gmp-impl.h, since they're undocumented.
+
+ * gmp-impl.h (mpn_reciprocal): Remove, unused.
+
+ * tune/many.pl (cntlz, cnttz): Use new SPEED_ROUTINE_COUNT_ZEROS.
+
+2002-01-11 Kevin Ryde <kevin@swox.se>
+
+ * mpn/hppa/*.asm, mpn/pa64/*.asm, mpn/pa64w/*.asm: Use L().
+
+2002-01-08 Kevin Ryde <kevin@swox.se>
+
+ * mpn/asm-defs.m4 (PROLOGUE, EPILOGUE): New scheme, optional function
+ name to EPILOGUE, check for missing or wrong function name EPILOGUE.
+ * mpn/alpha/unicos.m4, mpn/alpha/default.m4, mpn/m68k/m68k-defs.m4,
+ mpn/mips3/mips.m4, mpn/ia64/default.m4, mpn/powerpc32/aix.m4,
+ mpn/powerpc64/aix.m4, mpn/x86/x86-defs.m4: Consequent updates, add a
+ few more asserts.
+ * mpn/alpha/unicos.m4, mpn/alpha/default.m4, mpn/alpha/cntlz.asm,
+ mpn/alpha/invert_limb.asm (PROLOGUE_GP): Change to an optional "gp"
+ parameter on plain PROLOGUE.
+
+ * gmp.texi (Low-level Functions): mpn_get_str doesn't clobber an extra
+ limb, and doesn't clobber at all for power of 2 bases.
+ (Language Bindings): Add python gmpy.
+
+ * mpz/get_str.c: Determine realloc size arithmetically.
+
+ * mpbsd/mtox.c: Size memory block returned to actual space needed.
+ * gmp.texi (BSD Compatible Functions): Describe this.
+
+ * mpz/get_str.c: Don't copy mpn_get_str input for power of 2 bases.
+ * mpbsd/mtox.c: Ditto, and as a side effect avoid a memory leak from a
+ missing TMP_FREE.
+
+ * mpz/get_str.c, mpbsd/mout.c: No longer need for +1 limb for
+ mpn_get_str clobber.
+
+ * gmp-impl.h (MPN_GET_STR_SIZE): New macro.
+ * mpn/generic/get_str.c, mpz/get_str.c, mpbsd/mout.c, mpbsd/mtox.c,
+ tune/speed.h: Use it.
+ * tests/mpn/t-g_str_size.c: New test.
+ * tests/mpn/Makefile.am: Add it.
+
+ * gmp-impl.h (POW2_P): New macro.
+ * mpn/generic/get_str.c, tests/misc.c: Use it.
+
+ * printf/doprnt.c: Add "N" for mpn, share some code between N, Q and Z.
+ * tests/misc/t-printf.c: Add tests.
+ * gmp-impl.h (ASSERT_CODE): New macro.
+
+ * tests/mpbsd/t-mtox.c: New test.
+ * tests/mpbsd/Makefile.am: Add it.
+ (allfuns_LDADD): Don't link against libgmp when testing everything in
+ libmp can link.
+
+2002-01-07 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (MPN_COPY_INCR, MPN_COPY_DECR): Rewrite generic versions.
+
+2002-01-06 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/pre_divrem_1.c: Don't support size==0.
+ * tests/devel/try.c: Update.
+
+ * mpn/generic/get_str.c: Add special case for base==10.
+ * gmp-impl.h (MP_BASES_CHARS_PER_LIMB_10, MP_BASES_BIG_BASE_10,
+ MP_BASES_BIG_BASE_INVERTED_10, MP_BASES_NORMALIZATION_STEPS_10): New
+ constants.
+ * tests/t-constants.c: Add checks.
+ * mpn/mp_bases.c [GENERATE_TABLE]: Print defines for gmp-impl.h, print
+ all standard bits-per-limb by default.
+
+ * demos/pexpr.c, demos/expr/expr.h, demos/expr/expr-impl.h: Use
+ __GMP_PROTO.
+
+ * gmp-h.in (mpn_divexact_by3c): Remove variables from prototype, to
+ keep out of application namespace.
+
+2002-01-04 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h: Move _PROTO declaration to before its first usages.
+
+2002-01-04 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in, mp-h.in, tests/tests.h: Rename _PROTO to __GMP_PROTO, and
+ don't use #ifndef just define it ourselves.
+ * gmp-impl.h: Provide _PROTO as an alias for __GMP_PROTO, to avoid big
+ edits internally, for the moment.
+
+2002-01-03 Torbjorn Granlund <tege@swox.com>
+
+ * tune/speed.c (usage): Insert "\n\" into a string.
+
+2001-12-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64/udiv_qrnnd.c: Remove file.
+ * mpn/pa64w/udiv_qrnnd.c: Remove file.
+
+ * gmp-impl.h (MPN_IORD_U): Change formatting (labels in pos 0, insns
+ indented by tab).
+ (MPN_INCR_U): Use "addl $1,foo; jc", not "incl foo; jz".
+
+ * gmp-impl.h (udiv_qrnnd_preinv): Use plain subtract, not sub_ddmmss,
+ in one more case.
+
+2001-12-30 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/get_str.c (udiv_qrnd_unnorm): New macro.
+ Use "do while" for dig_per_u loop since it's non-zero.
+ * acconfig.h (HAVE_HOST_CPU_m68k etc): Add templates.
+
+ * mpn/generic/mul_basecase.c, mpz/mul.c, mpz/n_pow_ui.c,
+ mpn/x86/pentium/mul_2.asm, tests/devel/try.c, tests/tests.h,
+ tests/refmpn.c, tune/speed.c, tune/speed.h, tune/common.c,
+ tune/many.pl (mpn_mul_2): New parameter style.
+ * gmp-impl.h (mpn_mul_2): Add prototype.
+ * configure.in (gmp_mpn_functions_optional): Add mul_2.
+
+ * longlong.h (__vxworks__): Remove from powerpc tests, not correct,
+ not on its own at least.
+
+ * tune/speed.c: Add "aas" to specify 0xAA..AA data.
+
+ * tune/tuneup.c (print_define_end): Indicate "never" and "always".
+
+2001-12-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpq/set_d.c: ANSI-fy.
+ * mpz/invert.c: Use PTR and SIZ (cosmetic change).
+
+ * mpz/cong.c: Rename `xor' to `sign' to avoid C++ reserved word.
+
+2001-12-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/sqr_diagonal.asm: New file.
+
+2001-12-28 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/get_str.c: Avoid one mpn_divrem_1 by running main loop
+ only until msize==1.
+
+ * tune/tuneup.c: Break up all() for clarity.
+ (USE_PREINV_DIVREM_1, USE_PREINV_MOD_1): Compare against plain
+ division udiv_qrnnd, not the tuned and possibly preinv version.
+
+ * tune/freq.c: Split sysctl and sysctlbyname probes into separate
+ functions, shorten some identifiers, put descriptions inside
+ functions, define functions unconditionally and do nothing if
+ requisites not available.
+
+ * mpz/inp_raw.c: Avoid a gcc 3.0 powerpc64 bug on AIX.
+
+ * acinclude.m4, configure.in (GMP_C_RESTRICT): New macro.
+
+ * mpfr/sin.c: Patch from Paul to fix sign of sin(3pi/2).
+
+ * demos/calc/calc.y: Improve some error messages.
+
+2001-12-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/mul_1.asm: Rename r72 -> r80.
+ * mpn/sparc64/addmul_1.asm: Likewise.
+
+2001-12-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/tdiv_qr.c: Misc formatting cleanups.
+ For switch case 2, replace `dn' with its value (2).
+
+2001-12-25 Torbjorn Granlund <tege@swox.com>
+
+ * tests/devel/mul_1.c: Add FIXED_XLIMB.
+ * tests/devel/addmul_1.c: Likewise.
+ * tests/devel/submul_1.c: Likewise.
+
+ * tests/devel/add_n.c: Improve error message.
+ Accept command line argument for # of tests.
+ * tests/devel/sub_n.c: Likewise.
+
+ * tests/devel/: Remove CLOCK settings.
+
+ * mpn/sparc32/v9/mul_1.asm: Rewrite.
+ * mpn/sparc32/v9/addmul_1.asm: Rewrite.
+ * mpn/sparc32/v9/submul_1.asm: Rewrite.
+
+2001-12-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/mul_1.asm: Get rid of global constant 0.0 (L(noll)).
+ * mpn/sparc64/addmul_1.asm: Likewise.
+
+2001-12-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c: Move final ASSERT to just before zero fill
+ loop.
+
+2001-12-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/get_str.c: Move ASSERTs out of loops. Split digit
+ generation code into two loops, saving a test of msize in the loop.
+
+2001-12-22 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/x86-defs.m4, mpn/x86/*/*.asm: Remove L / LF scheme putting
+ function name in local labels.
+
+ * mpn/generic/get_str.c: Use mpn_preinv_divrem_1, add a couple of
+ ASSERTs.
+
+ * mpn/generic/pre_divrem_1.c: New file.
+ * configure.in (gmp_mpn_functions): Add it.
+ * gmp-impl.h (mpn_preinv_divrem_1): Add prototype.
+ (USE_PREINV_DIVREM_1, MPN_DIVREM_OR_PREINV_DIVREM_1): New macros.
+ * tests/devel/try.c, tune/speed.c, tune/speed.h, tune/common.c,
+ tune/many.pl, tune/Makefile.am (mpn_preinv_divrem_1): Add testing and
+ measuring.
+ * tune/tuneup.c: Determine USE_PREINV_DIVREM_1.
+ * tune/pre_divrem_1.c: New file.
+ * tests/refmpn.c, tests/tests.h (refmpn_preinv_divrem_1): New function.
+
+ * tests/mpz/t-io_raw.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpz/inp_raw.c, mpz/out_raw.c: Rewrite.
+ * acinclude.m4, configure.in (AC_C_BIGENDIAN): New test.
+ * gmp-impl.h (BSWAP_LIMB): New macro.
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): For a native compile, demand
+ executables will run, per AC_PROG_CC. This detects ABI=64 is unusable
+ in a native sparc solaris 7 build with the kernel in 32-bit mode.
+ * gmp.texi (ABI and ISA): Add notes on this, add an example configure
+ setting an ABI.
+
+ * tune/tuneup.c, configure.in: Print the gmp-mparam.h filename.
+ * tune/tuneup.c: Print the CPU frequency.
+
+ * tune/time.c, tune/speed.h: Add s390 "stck" method, flatten
+ conditionals in speed_time_init a bit, use have_* variables to let
+ some code go dead in speed_starttime and speed_endtime.
+
+ * tune/freq.c (speed_cpu_frequency_irix_hinv): New function.
+
+ * Makefile.am, configure.in: Restore mpfr.
+
+ * configure.in: Add --with-readline, AC_PROG_YACC and AM_PROG_LEX.
+ * demos/calc/calc.y, demos/calc/calclex.l: Add readline support, add
+ lucnum function.
+ * demos/calc/Makefile.am: Add calcread.c, calc-common.h, use $(YACC),
+ $(LEX) and $(LEXLIB).
+ * demos/calc/calcread.c, demos/calc/calc-common.h,
+ demos/calc/calc-config-h.in, demos/calc/README: New files.
+
+ * configure.in: Put demos/expr configs in expr-config.h.
+ * demos/expr/expr-config-h.in: New file.
+ * demos/expr/expr-impl.h: Renamed from expr-impl-h.in, get configs
+ from expr-config.h.
+ * demos/expr/Makefile.am: Update.
+
+ * demos/expr/exprfr.c: Use mpfr_sin and mpfr_cos, remove some spurious
+ returns.
+
+2001-12-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/mul_1.asm: Trim an instruction.
+ * mpn/sparc64/addmul_1.asm: Likewise.
+
+ * mpn/ia64/add_n.asm: Rewrite.
+ * mpn/ia64/sub_n.asm: Rewrite.
+
+2001-12-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/mul_1.asm: Rewrite.
+ * mpn/ia64/addmul_1.asm: Rewrite.
+ * mpn/ia64/submul_1.c: Use TMP_ALLOC_LIMBS.
+
+ * tests/devel/mul_1.c: Improve error message.
+ Accept command line argument for # of tests.
+ * tests/devel/addmul_1.c: Likewise.
+ * tests/devel/submul_1.c: Likewise.
+
+2001-12-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/mips3/mul_1.asm: Add NOPs to save a cycle on R1x000.
+
+2001-12-18 Kevin Ryde <kevin@swox.se>
+
+ * gmpxx.h (gmp_randclass): Don't allow copy constructors or "=",
+ implementation by Gerardo.
+
+ * gmp-h.in (operator<<, operator>>): Remove parameter names from
+ prototypes, to keep out of user namespace.
+
+ * acinclude.m4 (GMP_FUNC_VSNPRINTF): Let the test program work as C++.
+
+2001-12-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/mul_1.asm: Rewrite.
+ * mpn/sparc64/addmul_1.asm: Rewrite.
+ * mpn/sparc64/submul_1.asm: Rewrite.
+
+ * mpn/sparc64/addmul1h.asm: Remove.
+ * mpn/sparc64/submul1h.asm: Remove.
+ * mpn/sparc64/mul1h.asm: Remove.
+
+2001-12-15 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (mpn_add, mpn_add_1, mpn_cmp, mpn_sub, mpn_sub_1): Follow
+ __GMP_INLINE_PROTOTYPES for whether to give prototype with inline.
+
+ * configure.in (i686*-*-*, pentiumpro-*-*, pentium[23]-*-*,
+ athlon-*-*, pentium4-*-*): Fall back on -march=pentium if
+ -march=pentiumpro or higher is not good (eg. solaris cmov).
+
+2001-12-12 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (MPN_ZERO): Rewrite generic version to be similar to
+ powerpc version.
+
+2001-12-12 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Detect cmov problems with gcc
+ -march=pentiumpro on solaris 2.8.
+
+ * tune/common.c, tune/speed.h: Allow for commas in count_leading_zeros
+ and count_trailing_zeros macros.
+
+ * demos/expr/Makefile.am: Distribute exprfr.c and exprfra.c.
+
+ * tune/Makefile.am (speed_ext_SOURCES): Should be speed-ext.c.
+
+2001-12-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/s390/addmul_1.asm: New file.
+ * mpn/s390/submul_1.asm: New file.
+ * mpn/s390/mul_1.asm: New file.
+ * mpn/s390/gmp-mparam.h: Update.
+
+2001-12-07 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in, mp-h.in, gmp-impl.h: __GMP_DECLSPEC at start of
+ prototypes, for the benefit of Microsoft C.
+
+ * gmp.texi (Introduction to GMP): Mention ABI and ISA section.
+ (Known Build Problems): Recommend GNU sed on solaris 2.6.
+ (Assigning Integers): Direct feedback to bug-gmp.
+ (References): Typo Knuth vol 2 is from 1998.
+
+ * gmpxx.h (gmp_randclass): Add initializers for gmp_randinit_default
+ and gmp_randinit_lc_2exp_size.
+ gmp.texi (C++ Interface Random Numbers): Describe them.
+
+ * tests/misc/t-locale.c, tests/cxx/t-locale.cc: Ensure mpf_clear is
+ done when the localconv override doesn't work. Reported by Mike
+ Jetzer.
+
+ * printf/doprnti.c: Don't showbase on a zero mpq denominator.
+ * tests/misc/t-printf.c, tests/cxx/t-ostream.c: Add test cases.
+
+2001-12-04 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Known Build Problems): Update to gmp_randinit_lc_2exp_size
+ for the sparc solaris 2.7 problem.
+ (Reentrancy): SCO ctype.h affects all text-based input functions.
+ (Formatted Output Strings): Correction to the mpf example.
+ (Single Limb Division): Correction, should be q-1 not q+1.
+ (Extended GCD): Clarify why single-limb is inferior.
+ (Raw Output Internals): Clarify size is twos complement, note limb
+ order means _mp_d doesn't get directly read or written.
+ (Contributors): Clarify mpz_jacobi.
+ And a couple of formatting tweaks elsewhere.
+
+ * tests/cxx/t-headers.cc: New file.
+ * tests/cxx/Makefile.am: Add it.
+
+ * gmpxx.h: Add <strstream>, needed by mpf_class::get_str2.
+
+ * gmp-h.in (mpq_inp_str, mpn_hamdist): Add __GMP_DECLSPEC.
+
+2001-12-01 Torbjorn Granlund <tege@swox.com>
+
+ * Version 4.0 released.
+
+ * mpfr/README: Replace contents with explanation of why mpfr is gone.
+
+2001-12-01 Kevin Ryde <kevin@swox.se>
+
+ * Makefile.am, configure.in: Temporarily remove mpfr, just leave a
+ README.
+
+ * mpn/Makefile.am (EXTRA_DIST): Add Makeasm.am.
+
+2001-11-30 Gerardo Ballabio <ballabio@sissa.it>
+
+ * tests/cxx/t-constr.cc, tests/cxx/t-expr.cc: New files.
+ * tests/cxx/Makefile.am (check_PROGRAMS): Add them.
+
+2001-11-30 Kevin Ryde <kevin@swox.se>
+
+ * mpfr: Update to 2001-11-16. Patch TMP handling of agm.c and sqrt.c,
+ use plain mpn_sqrtrem in sqrt.c, separate .c files for floor and ceil,
+ disable an expression style assert in add1.c.
+
+ * mpn/s370: Rename to s390.
+ * configure.in (s3[6-9]0*-*-*): Update.
+ * mpn/Makefile.am (TARG_DIST): Add s390.
+
+ * mpz/fits_s.c, mpf/fits_s.c, mpf/fits_u.c: Remove files, unused since
+ change to .h style.
+
+2001-11-29 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-h.in: Declare mpz_get_d_2exp and mpf_get_d_2exp.
+ * Makefile.am: Add mpz/get_d_2exp$U.lo and mpf/get_d_2exp$U.lo.
+ * mpf/Makefile.am: Add get_d_2exp.c.
+ * mpz/Makefile.am: Add get_d_2exp.c.
+
+2001-11-29 Kevin Ryde <kevin@swox.se>
+
+ * mpn/*/gmp-mparam.h: Update measured thresholds.
+ * mpn/s370/gmp-mparam.h: New file.
+
+ * mpz/millerrabin.c: Mark for internal use only, for now.
+ * gmp.texi (Number Theoretic Functions): Remove documentation.
+
+2001-11-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/get_d_2exp.c: New file.
+ * mpz/get_d_2exp.c: New file.
+
+ * mpz/realloc2.c: Fix typo. Make more similar to mpz_realloc.
+ * mpz/realloc.c: Use __GMP_REALLOCATE_FUNC_LIMBS.
+
+2001-11-27 Gerardo Ballabio <ballabio@sissa.it>
+
+ * gmpxx.h, mpfrxx.h: Various updates and improvements.
+
+2001-11-27 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Useful Macros and Constants): Add gmp_version, add @findex
+ for mp_bits_per_limb.
+
+ * demos/perl/GMP.pm, demos/perl/GMP.xs: Use new style gmp_randinit's.
+ * demos/perl/test.pl: Update for this, and for mpz_perfect_power_p
+ handling of 0 and 1.
+
+2001-11-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/realloc.c: Clear variable when decreasing allocation to less than
+ needed. Misc updates.
+
+2001-11-25 Kevin Ryde <kevin@swox.se>
+
+ * tests/misc/t-locale.c: Avoid printf in the normal case, since the
+ replacement localeconv breaks it on SunOS 4.
+
+ * gmp.texi (Build Options, Notes for Package Builds): Note libgmpxx
+ depends on libgmp from same GMP version.
+
+ * acinclude.m4, configure.in (GMP_FUNC_SSCANF_WRITABLE_INPUT): New
+ test.
+ * scanf/sscanf.c, scanf/vsscanf.c: Use it to ensure sscanf input is
+ writable, if necessary.
+
+ * tests/misc/t-scanf.c: Ensure sscanf arguments are writable, always.
+ * configure.in (AC_CHECK_DECLS): Remove sscanf, no longer required.
+
+ * configure.in (none-*-*): Fix default CFLAGS setups.
+
+ * doc/configuration: Misc updates.
+
+2001-11-23 Kevin Ryde <kevin@swox.se>
+
+ * mpz/init2.c, mpz/realloc2.c: New files.
+ * Makefile.am, mpz/Makefile.am: Add them.
+ * gmp-h.in: Add prototypes.
+ * gmp.texi (Efficiency): Mention these instead of _mpz_realloc.
+ (Initializing Integers): Add documentation, reword other parts.
+
+2001-11-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/cray/ieee/addmul_1.c: Fix logic for more_carries scalar loop.
+ * mpn/cray/ieee/submul_1.c: Likewise.
+
+2001-11-20 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Known Build Problems): Note an out of memory on DJGPP.
+ (Function Classes): Update function counts.
+ Misc tweaks elsewhere.
+
+ * configure.in (AC_CHECK_DECLS): Add sscanf.
+ * tests/misc/t-scanf.c: Use it, for the benefit of SunOS 4.
+
+ * tal-debug.c, gmp-impl.h: More checks of TMP_DECL/TMP_MARK/TMP_FREE
+ consistency.
+
+ * mpfr/Makefile.am (AR): Explicit AR=@AR@ to override automake
+ default, necessary for powerpc64 ABI=aix64.
+
+2001-11-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/powm.c: Move TMP_MARK to before any TMP_ALLOCs.
+
+2001-11-18 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (--enable-fft): Make this the default.
+ * gmp.texi (Build Options): Update.
+
+ * Makefile.am (libmp_la_DEPENDENCIES): Revise mpz objects needed by
+ new mpz/powm.c.
+
+ * gmp.texi (Random State Initialization): Add gmp_randinit_default and
+ gmp_randinit_lc_2exp_size, mark gmp_randinit as obsolete.
+ (Random State Seeding): New section, taken from "Random State
+ Initialization" and "Random Number Functions".
+
+ * configure.in (AC_CHECK_DECLS): Add fgetc, fscanf, ungetc.
+ * scanf/fscanffuns.c: Use these, for the benefit of SunOS 4.
+
+ * gmp-impl.h, gmp-h.in (__gmp_default_fp_limb_precision): Move back to
+ gmp-impl.h now not required for inlined mpf.
+
+ * randlc2s.c (gmp_randinit_lc_2exp_size): New file, the size-based LC
+ selection from rand.c.
+ * rand.c (gmp_randinit): Use it.
+ * randdef.c (gmp_randinit_default): New file.
+ * gmp-impl.h (RANDS): Use it.
+ (ASSERT_CARRY): New macro.
+ * gmp-h.in (gmp_randinit_default, gmp_randinit_lc_2exp_size: Add
+ prototypes.
+ * Makefile.am (libgmp_la_SOURCES): Add randdef.c and randlc2s.c.
+
+ * printf/asprntffuns.c: Include config.h before using its defines.
+
+ * gmp-impl.h: Move C++ <string> to top of file to avoid the memset
+ redefine upsetting configure tests. Remove <iostream> since <iosfwd>
+ in gmp.h suffices.
+
+2001-11-16 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Integer Exponentiation): mpz_powm supports negative
+ exponents.
+ (Assigning Floats, I/O of Floats, C++ Formatted Output, C++ Formatted
+ Input): Decimal point follows locale.
+ (Formatted Output Strings): %n accepts any type.
+ (Formatted Input Strings): New section.
+ (Formatted Input Functions): New section.
+ (C++ Class Interface): Corrections and clarifications suggested by
+ Gerardo.
+
+ * scanf/doscan.c, scanf/fscanf.c, scanf/fscanffuns.c, scanf/scanf.c,
+ scanf/sscanf.c, scanf/sscanffuns.c, scanf/vfscanf.c, scanf/vscanf.c,
+ scanf/vsscanf.c, scanf/Makefile.am, tests/misc/t-scanf.c: New files.
+ * gmp-h.in, gmp-impl.h, Makefile.am, configure.in: Consequent
+ additions.
+
+ * tests/misc: New directory.
+ * tests/misc/Makefile.am: New file.
+ * tests/misc/t-locale.c: New file.
+ * tests/misc/t-printf.c: Moved from tests/printf.
+ * tests/printf: Remove directory.
+ * configure.in, tests/Makefile.am: Update.
+
+ * tests/cxx/t-locale.cc: New file.
+ * tests/cxx/Makefile.am: Add it.
+
+ * mpf/set_str.c, cxx/ismpf.cc: Use localeconv for the decimal point.
+
+ * acinclude.m4 (GMP_ASM_X86_MCOUNT): Update to $lt_prog_compiler_pic
+ for current libtool, recognise non-PIC style mcount in windows DLLs.
+
+ * gmp-impl.h (__gmp_replacement_vsnprintf): Add prototype.
+
+ * gmp-impl.h (__gmp_rands, __gmp_rands_initialized,
+ modlimb_invert_table): Add __GMP_DECLSPEC for the benefit of test
+ programs using them from a windows DLL.
+ * longlong.h (__clz_tab): Ditto.
+
+ * mpn/x86/t-zdisp2.pl: New file.
+
+ * mpn/x86/pentium4/README: New file.
+
+2001-11-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/powm.c (HANDLE_NEGATIVE_EXPONENT): #define to 1.
+ * tests/mpz/reuse.c (main): Use mpz_invert to avoid undefined mpz_powm
+ cases.
+
+2001-11-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/powm_ui.c: Rewrite along the lines of mpz/powm.c (except still no
+ redc).
+ * mpz/powm.c: Adjust for negative b, after exponentiation done. Add
+ (still disabled) code for handling negative exponents. Misc cleanups.
+
+2001-11-14 Kevin Ryde <kevin@swox.se>
+
+ * mpf/out_str.c: Use localeconv for the decimal point.
+
+ * tests/misc.c (tests_rand_end): Use time() if gettimeofday() not
+ available (eg. on mingw).
+
+2001-11-11 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in: Remove parameter names from prototypes, to keep out of
+ application namespace.
+
+2001-11-08 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_GCC_VERSION_GE): Fix sed regexps to work on
+ Solaris 8.
+
+ * printf/doprnt.c: Support %n of all types, per glibc.
+
+ * gmp-h.in, gmp-impl.h, mpf/abs.c, mpf/neg.c, mpf/get_prc.c,
+ mpf/get_dfl_prec.c, mpf/set_dfl_prec.c, mpf/set_prc_raw.c,
+ mpf/set_si.c, mpf/set_ui.c, mpf/size.c: Revert mpf inlining, in order
+ to leave open the possibility of keeping binary compatibility if mpf
+ becomes mpfr.
+
+ * mpn/x86/k7/mmx/lshift.asm, mpn/x86/k7/mmx/rshift.asm: Use Zdisp to
+ force code size for computed jumps.
+ * mpn/x86/k6/mod_34lsub1.asm, mpn/x86/k6/k62mmx/copyd.asm: Use Zdisp
+ to force good code alignment.
+ * mpn/x86/x86-defs.m4 (Zdisp): More instructions.
+
+ * mpn/x86/pentium/sqr_basecase.asm, mpn/x86/k7/mmx/mod_1.asm,
+ mpn/x86/k7/mmx/popham.asm: Remove some unnecessary "0" address offsets.
+
+ * mpq/set_si.c, mpq/set_ui.c: Set _mp_den._mp_size correctly if den==0.
+
+2001-11-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/hppa/hppa1_1/udiv_qrnnd.asm: Work around gas bug.
+
+ * mpn/asm-defs.m4 (PROLOGUE): Change alignment to 8 (probably a good
+ idea in general; required for hppa/hppa1_1/udiv_qrnnd.asm).
+
+2001-11-06 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (MPN_COPY_INCR): Prepend local variable by `__'.
+ (MPN_COPY_DECR): Likewise.
+
+2001-11-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/powm.c: Call mpn functions, not mpz functions, for computation
+ mod m. Streamline allocations to use a mixture of stack allocation and
+ heap allocation. Add currently disabled phi(m) exponent reduction
+ code. Misc optimizations and cleanups.
+
+2001-11-05 Kevin Ryde <kevin@swox.se>
+
+ * mpq/inp_str.c: Remove unused variable "ret".
+
+ * mpn/x86/k7/sqr_basecase.asm: Fix a 0(%edi) to use Zdisp, so the
+ computed jumps hit the right spot on old gas.
+
+ * mpq/canonicalize.c: DIVIDE_BY_ZERO if denominator is zero.
+
+ * mpn/lisp/gmpasm-mode.el (comment-start-skip): Correction to the way
+ the first \( \) pair is setup.
+ (gmpasm-font-lock-keywords): Don't fontify the space before a "#" etc.
+ Misc tweaks to some comments.
+
+2001-11-03 Torbjorn Granlund <tege@swox.com>
+
+ * tests/refmpn.c (refmpn_overlap_p): Reverse return values.
+
+2001-11-02 Kevin Ryde <kevin@swox.se>
+
+ * tune/many.pl: Setup CFLAGS_PIC and ASMFLAGS_PIC, since that's no
+ longer done by configure.
+
+ * mpn/x86/pentium4/mmx/popham.asm: New file.
+
+ * mpn/x86/x86-defs.m4 (psadbw): New macro.
+ * mpn/x86/k7/mmx/popham.asm: Use it.
+
+ * tests/refmpn.c (refmpn_overlap_p): New function, independent of
+ MPN_OVERLAP_P.
+
+2001-10-31 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-powm.c: Print proper error message when finding
+ discrepancy.
+
+2001-10-31 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/mod_34lsub1.asm: New file.
+ * mpn/x86/k7/mod_34lsub1.asm: New file.
+ * mpn/x86/mod_34lsub1.asm: New file.
+
+2001-10-30 Kevin Ryde <kevin@swox.se>
+
+ * tests/printf/t-printf.c (check_misc): Add checks from the glibc docs.
+ (check_vasprintf, check_vsnprintf): Run these unconditionally.
+
+ * gmp-impl.h (ASSERT_MPQ_CANONICAL): New macro.
+ * mpq/cmp.c, mpq/cmp_si.c, mpq/cmp_ui.c, mpq/equal.c: Add ASSERTs for
+ canonical inputs, where correctness depends on it.
+
+ * mpn/lisp/gmpasm-mode.el (comment-start-skip): Add "dnl".
+
+2001-10-27 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c: Remove some unused variables.
+ (main): Allocate more buffer space to accommodate minus sign.
+
+2001-10-27 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h, mpn/asm-defs.m4, configure.in, tune/speed.h,
+ tune/speed.c, tune/common.c, tune/many.pl, tests/devel/try.c: Add
+ mpn_mod_34lsub1.
+ * tests/refmpn.c, tests/tests.h (refmpn_mod_34lsub1): New function.
+
+ * mpn/generic/mod_34lsub1.c: New file.
+ * mpn/x86/k6/mod_34lsub1.asm: New file.
+ * mpn/x86/pentium4/sse2/mod_34lsub1.asm: New file.
+ * mpn/x86/x86-defs.m4 (Zdisp): Add another instruction.
+
+ * gmp-h.in, gmpxx.h: Use <iosfwd> not whole <iostream>.
+
+ * gmp.texi (Known Build Problems): Add note on test programs with
+ Windows DLLs.
+
+2001-10-26 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpq/t-get_d.c: Limit the size of "eps" for vax.
+
+ * gmp.texi (maybepagebreak): New macro, use it in a few places.
+ (Notes for Particular Systems): C++ Windows DLLs are not supported.
+ (Known Build Problems): Note sparc solaris 2.7 gcc 2.95.2 shared
+ library problems.
+ (Autoconf): Tweak version numbers shown.
+ (Integer Roots): mpz_perfect_square_p and mpz_perfect_power_p consider
+ 0 and 1 perfect powers, mpz_perfect_power_p accepts negatives.
+ (Number Theoretic Functions): Add mpz_millerrabin, combined with a
+ reworded mpz_probab_prime_p.
+ (Formatted Output Strings): Misc clarifications.
+ (Formatted Output Functions): gmp_asprintf, gmp_vasprintf,
+ gmp_snprintf, gmp_vsnprintf always available.
+ (C++ Formatted Output): Misc rewordings.
+ (Formatted Input): New chapter.
+ (C++ Class Interface): New chapter, by Gerardo and me.
+ (Language Bindings): Update GMP++ now in GMP.
+ (C++ Interface Internals): New section, by Gerardo and me.
+
+ * printf/repl-vsnprintf.c: New file.
+ * configure.in, acinclude.m4, Makefile.am, printf/Makefile.am: Use it
+ if libc vsnprintf missing or bad.
+ * configure.in (AC_CHECK_FUNCS): Add strnlen.
+
+ * printf/snprntffuns.c, printf/vasprintf.c: Use
+ __gmp_replacement_vsnprintf if libc vsnprintf not available.
+ * printf/asprintf.c, printf/snprintf.c, printf/vasprintf.c,
+ printf/vsnprintf.c: Provide these functions unconditionally.
+ * acinclude.m4 (GMP_FUNC_VSNPRINTF): Remove warning about omissions
+ when vsnprintf not available.
+
+2001-10-24 Kevin Ryde <kevin@swox.se>
+
+ * configure, aclocal.m4: Regenerate with a libtool patch for a stray
+ quote in AC_LIBTOOL_PROG_LD_SHLIBS under mingw and cygwin.
+
+ * gmp-impl.h (modlimb_invert): More comments.
+
+ * printf/doprnt.c, printf/doprnti.c: Use the precision field to print
+ leading zeros.
+ * tests/printf/t-printf.c: Test this.
+ * cxx/osdoprnti.cc, gmp-impl.h: Ignore precision in operator<<.
+
+ * tune/speed.c, tune/speed.h, tune/common.c: Add mpn_mul_1_inplace.
+
+2001-10-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/pprime_p.c (mpz_millerrabin): Remove function and its descendant.
+
+ * mpz/millerrabin.c: New file with code from pprime.c.
+ * mpz/Makefile.am: Compile millerrabin.c.
+ * Makefile.am (MPZ_OBJECTS): Ditto.
+ * gmp-h.in: Declare mpz_millerrabin.
+
+2001-10-22 Torbjorn Granlund <tege@swox.com>
+
+ * tests/mpz/t-perfsqr.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add it.
+
+ * demos/factorize.c (factor): Check for number to factor == 0.
+ (main): When invoked without arguments, read from stdin.
+
+ * mpz/perfpow.c: Add code to handle negative perfect powers ((-b)^odd).
+ Treat 0 and 1 as perfect powers.
+
+ * mpn/sparc32/v9/sqr_diagonal.asm: Jump past .align.
+
+2001-10-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/perfsqr.c (sq_res_0x100): Remove bogus final `,'.
+ (mpn_perfect_square_p): Suppress superfluous `&1' in sq_res_0x100 test.
+ (mpn_perfect_square_p, O(n) test): Improve comments. Combine remainder
+ tests for some small primes. Don't share code for different limb
+ sizes. Use single `if' with many `||' for better code density.
+
+2001-10-22 Kevin Ryde <kevin@swox.se>
+
+ * demos/perl/GMP.xs (mutate_mpz, tmp_mpf_grow): Make these "static".
+
+ * mpn/x86/pentium/popcount.asm, mpn/x86/pentium/hamdist.asm
+ (mpn_popcount_table): Use GSYM_PREFIX.
+
+2001-10-19 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/*.asm: Add some measured speeds on various x86s.
+
+ * tests/mpz/reuse.c, tests/mpf/reuse.c: Disable tests when using a
+ windows DLL, because certain global variable usages won't compile.
+
+ * configure.in (AC_CHECK_FUNCS): Add alarm.
+ * tests/spinner.c: Conditionalize alarm and SIGALRM availability, for
+ the benefit of mingw32.
+
+ * acinclude.m4 (GMP_ASM_TYPE, GMP_ASM_SIZE): Suppress .type and .size
+ on COFF.
+
+ * acinclude.m4 (GMP_PROG_HOST_CC): New macro.
+ * configure.in: Use it for windows DLL cross-compiles.
+ * aclocal.m4, configure: Regenerate with libtool patch to hold HOST_CC
+ in the generated libtool script.
+
+ * aclocal.m4, configure: Regenerate with libtool patch to suppress
+ warnings when probing command line limit on FreeBSD.
+
+ * demos/qcn.c (M_PI): Define if not already provided, helps mingw32.
+
+2001-10-17 Kevin Ryde <kevin@swox.se>
+
+ * printf/doprnt.c: Use <stdint.h> for intmax_t.
+
+ * longlong.h: Recognise __sparcv8 for gcc on Solaris. Reported by
+ Mark Mentovai <mark@mentovai.com>.
+
+ * gmp-impl.h (gmp_allocated_string): No need for inline on member funs.
+
+2001-10-16 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Debugging): Add mpatrol.
+ (Integer Comparisons, Comparing Rationals, Float Comparison): Index
+ entries for sign tests.
+ (I/O of Floats): Clarify mpf_out_str exponent is in decimal.
+ (C++ Formatted Output): mpf_t operator<< exponent now in decimal.
+ (FFT Multiplication): Use an ascii art sigma.
+ (Contributors): Add Gerardo Ballabio.
+
+ * cxx/osfuns.cc (__gmp_doprnt_params_from_ios): Always give mpf_t
+ exponent in decimal, irrespective of ios::hex or ios::oct.
+ * tests/cxx/t-ostream.cc (check_mpf): Update.
+
+ * printf/doprnt.c: Support %lln and %hhn.
+
+ * mpn/x86/pentium4/sse2/submul_1.asm: Use a psubq to negate the
+ initial carry (helps the submul_1c case), and improve the comments.
+
+2001-10-11 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4, configure.in (GMP_IMPL_H_IEEE_FLOATS): New macro.
+
+ * ltmain.sh: Send some rm errors to /dev/null, helps during compiles
+ on Solaris 2.7 and HP-UX 10.
+
+ * tal-notreent.c: Renamed from stack-alloc.c.
+ * Makefile.am, acinclude.m4, gmp-impl.h: Update.
+
+ * gmp-h.in: Don't give both prototypes and inlines, except on gcc.
+
+ * gmp-h.in, gmp-impl.h: Use #includes to get necessary standard
+ classes, add std:: to prototypes.
+ * cxx/*.cc, tests/cxx/t-ostream.cc: Add "use namespace std".
+ * acinclude.m4 (GMP_PROG_CXX_WORKS): Ditto.
+
+ * tests/*/Makefile.in, mpfr/tests/Makefile.in: Regenerate with
+ automake patch to avoid Ultrix problem with empty $(TESTS).
+
+ * */Makefile.in: Regenerate with automake patch to only rm *_.c in
+ "make clean" when ansi2knr actually in use, helps DOS 8.3.
+
+ * Makefile.in: Regenerate with automake patch to fix stamp-h
+ numbering, avoiding an unnecessary config.status run.
+
+2001-10-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/hppa/hppa1_1/udiv_qrnnd.asm: Use L macros for labels.
+ Quote L reloc operator.
+
+ * gmp-impl.h: Declare class string.
+
+ * mpn/asm-defs.m4 (INT32, INT64): Quote $1 to prevent further
+ expansion.
+
+ * mpn/alpha/ev6/mul_1.asm: New file.
+
+2001-10-09 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Introduction to GMP): Add pentium 4 to optimized CPUs.
+ (Build Options): Note macos directory.
+ (Notes for Package Builds): GMP 4 series binary compatible with 3.
+ (Known Build Problems): Remove $* and ansi2knr note, now fixed, except
+ possibly under --host=none.
+ (Formatted Output Strings): Remove -1 prec for all digits.
+
+ * mpz/add.c, mpz/sub.c: Don't use mpz path on #include (helps macos).
+ * mpbsd/Makefile.am (INCLUDES): Add -I$(top_srcdir)/mpz.
+
+ * printf/doprnt.c, tests/printf/t-printf.c: Remove support for %.*Fe
+ prec -1 meaning all digits.
+
+ * acinclude.m4 (GMP_PROG_AR): Override libtool, use AR_FLAGS="cq".
+ (GMP_HPC_HPPA_2_0): Print version string to config.log.
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Remove check-news (permission notice
+ in NEWS file is too big).
+ (dist-hook): Don't distribute numbered or unnumbered emacs backups.
+
+ * Makefile.am, cxx/Makefile.am: Updates for Gerardo's stuff.
+
+2001-10-09 Gerardo Ballabio <ballabio@sissa.it>
+
+ * cxx/isfuns.cc: New file.
+ * gmp-impl.h: Add prototypes.
+ * cxx/ismpf.cc, cxx/ismpq.cc, cxx/ismpz.cc: New files.
+ * gmp-h.in: Add prototypes.
+ * gmpxx.h, mpfrxx.h: New files.
+
+2001-10-08 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (with_tags): Establish a default based on --enable-cxx.
+
+ * aclocal.m4: Regenerate with libtool patches for sed char range to
+ help Cray, LTCC quotes and +Z warnings grep to help HP-UX.
+
+ * gmp-impl.h (doprnt_format_t, doprnt_memory_t, doprnt_reps_t,
+ doprnt_final_t): Use _PROTO.
+
+2001-10-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/asm-defs.m4 (INT32, INT64): Use LABEL_SUFFIX.
+
+ * mpn/hppa: Convert files to `.asm'.
+
+2001-10-05 Kevin Ryde <kevin@swox.se>
+
+ * mpn/Makeasm.am (.S files): Revert to separate CPP and CCAS, use
+ cpp-ccas, and only pass CPPFLAGS to CPP, not whole CFLAGS.
+ * mpn/cpp-ccas: New file.
+ * mpn/Makefile.am (EXTRA_DIST): Add it.
+
+ * tune/common.c, tune/speed.h: Change SPEED_ROUTINE_MPN_COPY_CALL uses
+ to SPEED_ROUTINE_MPN_COPY or new SPEED_ROUTINE_MPN_COPY_BYTES. Avoids
+ macro expansion problems on Cray.
+
+ * configure.in (AC_PROG_CXXCPP): Add this, to make libtool happier.
+
+2001-10-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/rrandomb.c (gmp_rrandomb): Change bit_pos to be 0-based (was
+ 1-based); shift 2 (was 1) when making bit mask. These two changes
+ avoid undefined shift counts.
+ (gmp_rrandomb): Avoid most calls to _gmp_rand by caching random values.
+
+ * mpn/generic/random2.c: Changes for mirroring mpz/rrandomb.c.
+
+2001-10-04 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Build Options): Add --enable-cxx.
+ (Notes for Particular Systems): Mention pentium4 performance and SSE2.
+ (Known Build Problems): Remove vax jsobgtr note, no longer needed.
+ (Converting Floats): Tweak mpf_get_str description.
+ (Low-level Functions): Correction to mpn_gcdext destination space
+ requirements.
+ (C++ Formatted Output): New section.
+ (Language Bindings): Add ALP
+ (Contributors): Add Paul Zimmermann's square root, update my things.
+
+ * acinclude.m4 (GMP_PROG_CC_IS_GNU, GMP_PROG_CXX_WORKS): Send compiler
+ errors to config.log.
+
+ * mpq/Makefile.am (INCLUDES): Remove -DOPERATION_$*, not needed.
+
+ * mpn/x86/*.asm: Change references to old README.family to just README.
+
+ * mpz/README: Remove file, now adequately covered in the manual.
+
+2001-10-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/copyi.asm: New file.
+ * mpn/x86/pentium4/copyd.asm: New file.
+
+ * gmp-impl.h: Implement separate MPN_COPY_INCR and MPN_COPY_DECR
+ macros for CRAY systems.
+ (CRAY _MPN_COPY): Delete.
+
+2001-10-02 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpz/t-popcount.c (check_data): Use "~ (unsigned long) 0" to
+ avoid compiler warnings on sco.
+
+ * mpbsd/Makefile.am: Compile mpz files directly, no copying.
+ Use mpz/add.c and mpz/sub.c rather than mpz/aors.c.
+ (INCLUDES): Remove -DOPERATION_$*, no longer needed (by mpz).
+
+ * mpz/aors.h: Renamed from mpz/aors.c.
+ * mpz/add.c, mpz/sub.c: New files, using mpz/aors.h.
+ * mpz/aors_ui.h: Renamed from mpz/aors_ui.c.
+ * mpz/add_ui.c, mpz/sub_ui.c: New files, using mpz/aors_ui.h.
+ * mpz/fits_s.h: Renamed and adapted from mpz/fits_s.c.
+ * mpz/fits_sshort.c, mpz/fits_sint.c, mpz/fits_slong.c: New files.
+ * mpz/mul_i.h: Renamed from mpz/mul_siui.c.
+ * mpz/mul_ui.c, mpz/mul_ui.c: New files, using mpz/mul_i.h.
+ * mpz/Makefile.am: Consequent updates.
+ (INCLUDES): Remove -DOPERATION_$*.
+
+ * mpf/fits_s.h: Renamed and adapted from mpf/fits_s.c.
+ * mpf/fits_sshort.c, mpf/fits_sint.c, mpf/fits_slong.c: New files.
+ * mpf/fits_u.h: Renamed and adapted from mpf/fits_u.c.
+ * mpf/fits_ushort.c, mpf/fits_uint.c, mpf/fits_ulong.c: New files.
+ * mpf/Makefile.am: Consequent updates.
+ (INCLUDES): Remove -DOPERATION_$*.
+
+ * cxx/osfuns.cc (__gmp_doprnt_params_from_ios): Don't use ios::hex etc
+ as cases in a switch, they're not constant in g++ 3.0.
+
+ * mpn/Makeasm.am (.s.o, .s.obj, .S.o, .S.obj, .asm.o, .asm.obj):
+ Locate source file with test -f the same as automake.
+ (.S): Let CCAS do the preprocessing, and run libtool for .S.lo.
+ (.asm.lo): Run libtool via m4-ccas to get new style foo.lo right.
+ (COMPILE_FLAGS): Add $(DEFAULT_INCLUDES), per new automake.
+ * mpn/m4-ccas: New file.
+ * mpn/Makefile.am (EXTRA_DIST): Add it.
+ * mpn/asm-defs.m4: Add m4_not_for_expansion(`DLL_EXPORT').
+ * mpn/x86/x86-defs.m4: Undefine PIC if DLL_EXPORT is set.
+ * configure.in (CFLAGS_PIC, ASMFLAGS_PIC): Remove, no longer needed.
+
+ * acinclude.m4 (GMP_FUNC_VSNPRINTF): Warn what's omitted when
+ vsnprintf not available.
+
+ * mpn/underscore.h: Remove file, not used since m68k converted to asm.
+ * mpn/Makefile.am (EXTRA_DIST): Remove it.
+
+ * tests/refmpz.c: Add <stdlib.h>, for free().
+
+2001-10-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/submul_1.asm: Apply some algebraic
+ simplifications.
+ * mpn/x86/pentium4/sse2/addmul_1.asm: Comment.
+
+2001-10-01 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (--enable-cxx): New option for C++ support.
+ Add cxx and tests/cxx subdirectories.
+ * ltmain.sh, aclocal.m4: Update to libtool 2001-09-30.
+
+ * cxx/Makefile.am, cxx/Makefile.in, cxx/osdoprnti.cc, cxx/osfuns.cc,
+ cxx/osmpf.cc, cxx/osmpq.cc, cxx/osmpz.cc: New files.
+ * Makefile.am: Add them, in new libgmpxx.
+ * gmp-h.in, gmp-impl.h: Prototypes and support.
+ * tests/cxx/Makefile.am, tests/cxx/Makefile.in,
+ tests/cxx/t-ostream.cc: New files.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_GCD_CALL,
+ SPEED_ROUTINE_MPN_GCDEXT_ONE): mpn_gcdext needs size+1 for
+ destinations. Found by Torbjorn.
+
+ * gmp-h.in (__GNU_MP__, __GNU_MP_VERSION): Bump to 4.0.
+ * mp-h.in (__GNU_MP__): Ditto.
+ * gmp.texi, Makefile.am, compat.c: Amend version 3.2 to 4.0.
+
+ * acinclude.m4 (GMP_PROG_CXX_WORKS): New macro.
+ (GMP_PROG_CC_WORKS): Write "conftest" test program, not a.out.
+
+ * gmp-impl.h (struct gmp_asprintf_t): Moved from printf/vasprintf.c.
+ (GMP_ASPRINTF_T_INIT): New macro.
+ (GMP_ASPRINTF_T_NEED): New macro, adapted from vasprintf.c NEED().
+ * printf/vasprintf.c: Use these.
+
+ * printf/asprntffuns.c: New file.
+ * printf/Makefile.am, Makefile.am: Add it.
+ * printf/asprntffuns.c, printf/vasprintf.c, gmp-impl.h
+ (__gmp_asprintf_memory, __gmp_asprintf_reps, __gmp_asprintf_final):
+ Move to asprntffuns.c, rename to __gmp and make global, remove
+ spurious formal parameters from __gmp_asprintf_final.
+
+ * configure.in (j90-*-*, sv1-*-*): Don't duplicate $path in $add_path.
+ (*-*-mingw*): Don't assemble with -DPIC (as per cygwin).
+
+ * printf/snprntffuns.c (gmp_snprintf_final): Remove spurious formal
+ parameters.
+
+ * tune/tuneup.c (POWM_THRESHOLD): Reduce stop_factor to 1.1 to help
+ Cray vector systems.
+
+ * tests/misc.c (tests_rand_start): Print GMP_CHECK_RANDOMIZE=NN to
+ facilitate cut and paste when re-running.
+ * tests/mpz/t-inp_str.c (check_data): Add more diagnostic prints.
+
+2001-09-30 Kent Boortz <kent@swox.com>
+
+ * macos/configure, macos/Makefile.in, macos/README: Updates for gmp 4.
+ * gmp-h.in (_GMP_H_HAVE_FILE): Recognise Apple MPW.
+
+2001-09-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/cray/ieee/submul_1.c: Rewrite. Streamline multiplications;
+ use `majority' logic.
+
+2001-09-27 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-h.in (__GMPN_AORS_1): Rewrite to work around Cray compiler bug.
+
+2001-09-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/gmp-mparam.h: New file.
+
+2001-09-26 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium4/sse2/dive_1.asm: New file.
+ * mpn/x86/pentium4/sse2/submul_1.asm: New file.
+ * mpn/x86/pentium4/sse2/sqr_basecase.asm: New file.
+
+ * mpn/x86/pentium/copyi.asm: New file, based on past work by Torbjorn.
+ * mpn/x86/pentium/copyi.asm: New file, ditto.
+ * mpn/x86/pentium/com_n.asm: Rewrite, ditto.
+
+ * printf/snprntffuns.c (gmp_snprintf_format): Copy va_list in case
+ vsnprintf trashes it.
+ * printf/vasprintf.c (gmp_asprintf_format): Ditto.
+ * gmp-impl.h, doprnt.c (va_copy): Move to gmp-impl.h.
+
+ * tests/mpz/t-cmp_d.c (check_low_z_one): Patch by Torbjorn for vax
+ limited float range.
+
+2001-09-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/vax/lshift.s: Change `jsob*' to `sob*'.
+ * mpn/vax/rshift.s: Likewise.
+
+2001-09-23 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium4/sse2/mul_basecase.asm: Some simple but real code.
+
+ * printf/doprnt.c: Use va_copy for va_list variables, copy function
+ parameter in case it's call-by-reference.
+
+ * tune/freq.c (speed_cpu_frequency_bsd_dmesg): New function.
+ (speed_cpu_frequency_table): Use it.
+
+ * tune/many.pl (popcount, hamdist): Fix declared return value.
+ (sb_divrem_mn): Remove a spurious duplicate entry.
+ (CLEAN): Add tmp-$objbase.c when using that for .h files.
+ (macro_speed): Give a default for .h files.
+ Add ATTRIBUTE_CONST or __GMP_ATTRIBUTE_PURE as appropriate.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_MOD_CALL,
+ SPEED_ROUTINE_MPN_PREINV_MOD_1, SPEED_ROUTINE_MPN_POPCOUNT,
+ SPEED_ROUTINE_MPN_HAMDIST, SPEED_ROUTINE_MPN_GCD_1N,
+ SPEED_ROUTINE_MPN_GCD_1_CALL, SPEED_ROUTINE_MPZ_JACOBI): Use return
+ values so gcc 3 won't discard calls to pure or const functions.
+ (mpn_mod_1_div, mpn_mod_1_inv): Add __GMP_ATTRIBUTE_PURE.
+
+2001-09-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/mul_basecase.asm: New file, placeholder
+ for real code, hiding the default x86 mul_basecase.asm.
+
+2001-09-22 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_PREREQ): Bump to 2.52.
+ (m4_pattern_forbid, m4_pattern_allow): New calls, forbid GMP_.
+ (AC_CHECK_HEADERS): Remove sys/types.h, already done by autoconf.
+ * acinclude.m4, configure.in (GMP_GCC_NO_CPP_PRECOMP): New macro.
+
+ * tests/devel/try.c (TYPE_PREINV_MOD_1): Don't run size==0.
+ (malloc_region): Need fd=-1 for mmap MAP_ANON on BSD.
+
+2001-09-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/cong.c (mpz_congruent_p): Fix one-limb c<d test.
+
+ * longlong.h: Rewrite __i370__ smul_ppmm; enable also for __s390__.
+
+ * configure.in: Add support for IBM 360, 370, 390 families.
+
+2001-09-20 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium4/sse2/diveby3.asm: New file.
+ * mpn/x86/pentium4/sse2/mode1o.asm: New file.
+
+2001-09-16 Kevin Ryde <kevin@swox.se>
+
+ * printf/doprnt.c: '#' means showpoint and showtrailing for %e, %f, %g.
+ * tests/printf/t-printf.c (check_f): More test cases.
+
+2001-09-15 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-h.in (__GMPN_AORS_1): Remove param TEST, add OP and CB.
+ Postpone zeroing of (cout).
+ (__GMPN_ADD_1, __GMPN_SUB_1): Corresponding changes.
+
+2001-09-14 Kevin Ryde <kevin@swox.se>
+
+ * ChangeLog: Merge in tests/rand/ChangeLog.
+ * tests/rand/ChangeLog: Remove file.
+
+ * printf/doprnt.c: Fix handling of a plain format after a GMP one; no
+ need to protect against negative precision internally.
+ * tests/printf/t-printf.c (check_misc): More checks.
+
+2001-09-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/cray/ieee/invert_limb.c: Add a PROLOGUE in a comment to have
+ HAVE_NATIVE_... defined.
+
+2001-09-11 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, gmp-h.in (__GMP_HAVE_HOST_CPU_FAMILY_power,
+ __GMP_HAVE_HOST_CPU_FAMILY_powerpc): New AC_SUBSTs.
+ * gmp-h.in (__GMPN_COPY_INCR): Use them to select the power/powerpc
+ code, rather than preprocessor defines.
+
+ * acinclude.m4, configure.in (GMP_H_ANSI): New macro.
+
+ * gmp-h.in (__GMP_EXTERN_INLINE): Add a definition for SCO 8 cc.
+
+ * gmp-h.in, version.c (gmp_version): Make the pointer "const" as well
+ as the string.
+
+ * acinclude.m4, configure.in (GMP_PROG_CC_IS_XLC): Recognise xlc when
+ invoked under another name (cc, xlc128, etc).
+ * acinclude.m4 (GMP_PROG_CC_IS_GCC): Print a message when recognised.
+
+2001-09-11 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-h.in: Let __DECC mean __GMP_HAVE_CONST, etc.
+ * mp-h.in: Likewise.
+
+2001-09-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/mmx/lshift.asm: New file.
+ * mpn/x86/pentium4/mmx/rshift.asm: New file.
+
+ * tests/mpn/t-iord_u.c (check_incr_data): Work around HP compiler bug.
+ (check_decr_data): Likewise.
+
+2001-09-08 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Integer Logic and Bit Fiddling): Update mpz_hamdist
+ behaviour, clarify mpz_popcount a touch.
+ (Language Bindings): Add mlton, fix alphabetical order.
+ (Single Limb Division): Describe 2 or 1/2 limbs at a time style.
+
+ * configure.in (AC_CHECK_FUNCS): Add mmap.
+ * tests/devel/try.c (malloc_region): Use mmap if available.
+
+ * tests/refmpz.c, tests/tests.h (refmpz_hamdist): New function.
+ * tests/mpz/t-hamdist.c: New file.
+ * tests/mpz/Makefile.am: Add it.
+
+ * mpz/hamdist.c: Support neg/neg operands.
+
+ * macos/Makefile.in: Remove dual compile of mpq/aors.c and
+ mpn/generic/popham.c.
+
+ * gmp-impl.h (popc_limb): New macro, adapted from mpn/generic/popham.c.
+ For 64-bits reuse 0x33...33 constant.
+ * mpn/generic/popcount.c, mpn/generic/hamdist.c: Split from popham.c,
+ use popc_limb macro, remove unused "i", don't bother with "register"
+ qualifiers.
+ * mpn/generic/popham.c: Remove file.
+
+ * ltmain.sh, configure, aclocal.m4: Update to libtool 1.4.1, with one
+ ltdll.c generation patch.
+ * doc/configuration: Misc updates, note libtool patch used.
+
+ * mpn/x86/pentium4/sse2/mul_1.asm: Use pointer increments not indexed
+ addressing, to get 4.0 c/l flat.
+
+ * tests/mpq/t-cmp_si.c (check_data): Use ULONG_MAX for denominators.
+
+ * tests/misc.c (mpz_negrandom): Use given rstate, not RANDS.
+
+2001-09-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/pentium4/sse2/addmul_1.asm: New file.
+
+2001-09-04 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c: Define a HAVE for each speed_cpu_frequency routine to
+ avoid duplicating conditionals.
+ (speed_cpu_frequency_sco_etchw): New function.
+ (speed_cpu_frequency_table): Use it.
+ * tune/README: Mention SCO openunix 8 /etc/hw.
+
+ * mpz/fib_ui.c: Use ?: to avoid a gcc 3 bug on powerpc64.
+ Store back a carry for limb<long.
+
+ * mpn/x86/k7/mmx/divrem_1.asm, mpn/x86/k7/mmx/mod_1.asm,
+ mpn/x86/p6/mmx/divrem_1.asm: Fix a couple of comments.
+
+ * config.guess: Give m68020 for 68020 or better, not m68k.
+ * configfsf.guess: Update to 2001-09-04.
+
+2001-09-02 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (m68k-*-*): Let m68k mean 68000, not 68020.
+ * gmp.texi (Notes for Particular Systems): Update.
+
+ * gmp-impl.h (union ieee_double_extract) [m68k]: Use longs, since int
+ might be only 16 bits.
+
+ * tests/mpq/t-aors.c: New file.
+ * tests/mpq/Makefile.am: Add it.
+
+ * tests/refmpq.c: New file.
+ * tests/Makefile.am: Add it.
+ * tests/tests.h: Add prototypes.
+
+ * mpq/aors.c: Share object code for mpq_add and mpq_sub.
+ * Makefile.am, mpq/Makefile.am: Single mpq/aors.lo now.
+
+ * tests/devel/try.c (TYPE_SUBMUL_1): Use correct reference routine.
+
+2001-08-30 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/x86-defs.m4 (cmov_available_p): Add pentium4.
+
+ * gmp-h.in: Put #define renamings with prototypes.
+ Remove commented out #defines of gmp-impl.h things.
+ (mpn_invert_limb): Remove #define, already in gmp-impl.h.
+ (mpn_lshiftc, mpn_rshiftc): Remove #defines, unused.
+ (mpn_addsub_nc): Add prototype to #define.
+
+2001-08-28 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi: Switch to GFDL.
+ (Top): Arrange copyright and conditions to appear here too. For
+ clarity have all this before the miscellaneous macro definitions.
+ (Copying): Refer to COPYING.LIB file, mention plain GPL2 in demo
+ programs.
+ (Contributors, References): Use @appendix rather than @unnumbered.
+ (GNU Free Documentation License): New appendix.
+ (@contents): Move to start of document, use only for tex (not html).
+ (Debugging): Add leakbug.
+ (Build Options): Add pentium4.
+ (I/O of Rationals): Add mpq_inp_str.
+
+ * fdl.texi: New file, with two @appendix directive tweaks.
+ * Makefile.am (gmp_TEXINFOS): Add it.
+
+ * tests/mpz/io.c: Check mpz_inp_str return against ftell, send error
+ messages just to stdout.
+
+ * mpz/inp_str.c, gmp-impl.h (__gmpz_inp_str_nowhite): New function,
+ and share a __gmp_free_func call.
+ * mpq/inp_str.c: New file.
+ * Makefile.am, mpq/Makefile.am: Add it.
+ * tests/mpq/t-inp_str.c: New file.
+ * tests/mpq/Makefile.am (check_PROGRAMS): Add it.
+
+ * configure.in, acconfig.h (HAVE_HOST_CPU_FAMILY_power,
+ HAVE_HOST_CPU_FAMILY_powerpc, HAVE_HOST_CPU_FAMILY_x86): AC_DEFINEs
+ for processor families.
+ * gmp-impl.h: Use them, rather than cpp defines.
+
+ * demos/Makefile.am (primes_LDADD): Use $(LIBM), for log().
+
+ * tune/many.pl, tune/Makefile.am: Fix some from clean and distclean.
+
+2001-08-26 Kevin Ryde <kevin@swox.se>
+
+ * tests/devel/try.c (ARRAY_ITERATION): Make types match on "?:" legs.
+ (TYPE_MPZ_JACOBI, TYPE_MPZ_KRONECKER): Remove some superseded code.
+
+ * tests/printf/t-printf.c (check_plain): Don't compare "all digits"
+ precision against plain printf.
+
+ * tune/Makefile.am: Eliminate empty TUNE_MPZ_SRCS.
+
+ * configure, config.in, INSTALL.autoconf: Update to autoconf 2.52.
+ * */Makefile.in, mdate-sh, missing, aclocal.m4, configure: Update to
+ automake 1.5.
+ * configfsf.guess, configfsf.sub: Update to 2001-08-23.
+
+2001-08-24 Torbjorn Granlund <tege@swox.com>
+
+ * demos/primes.c: Complete rewrite.
+
+2001-08-24 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h: Test __ppc__ for apple darwin cc, reported by Jon
+ Becker. Also test __POWERPC__, PPC and __vxworks__.
+
+ * tune/speed.h (speed_cyclecounter) [x86]: Don't clobber ebx in PIC.
+
+2001-08-22 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (x86 mmx): Correction to mmx path stripping.
+
+2001-08-17 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, acinclude.m4, Makefile.am, printf/Makefile.am,
+ tests/printf/Makefile.am, gmp-h.in, gmp-impl.h, gmp.texi: Remove C++
+ support, for the time being.
+ * printf/doprntfx.cc, doprntix.cc, osfuns.cc, osmpf.cc, osmpq.cc,
+ osmpz.cc, tests/printf/t-ostream.cc: Remove files.
+
+ * printf/doprnt.c, printf/doprntf.c, gmp-impl.h: Use a single
+ __gmp_doprnt_mpf, rather than a separate ndigits calculation.
+ * printf/doprnt.c, printf/doprntf.c, gmp-impl.h, gmp.texi,
+ tests/printf/t-printf.c: Let empty or -1 prec mean all digits for mpf.
+ * printf/doprnt.c, tests/printf/t-printf.c: Accept h or l in %n; let
+ negative "*" style width mean left justify.
+
+ * gmp-impl.h, mpf/get_str.c (MPF_SIGNIFICANT_DIGITS): New macro,
+ extracted from mpf/get_str.c.
+
+ * libmp.sym: New file.
+ * Makefile.am (libmp_la_LDFLAGS): Use it.
+ (DISTCLEANFILES): Remove asm-syntax.h, no longer generated.
+ Remove some comments about "make check".
+
+ * demos/perl/GMP.pm, GMP.xs, GMP/Mpf.pm: Add printf and sprintf,
+ change get_str to string/exponent for floats, remove separate
+ mpf_get_str.
+ * demos/perl/GMP/Mpf.pm (overload_string): Use $# (default "%.g").
+ * demos/perl/typemap: Fix some duplicate string entries.
+ * demos/perl/test.pl: Update tests, split overloaded constants into ...
+ * demos/perl/test2.pl: ... this new file.
+ * demos/perl/Makefile.PL (clean): Add test.tmp.
+
+2001-08-16 Kevin Ryde <kevin@swox.se>
+
+ * printf/snprntffuns.c (gmp_snprintf_format): Correction to bufsize-1
+ return value handling.
+
+ * demos/calc/calc.y: Reposition "%{" so copyright notice gets into
+ generated files.
+
+ * INSTALL: Use gmp_printf.
+
+2001-08-14 Kevin Ryde <kevin@swox.se>
+
+ * mpz/inp_str.c: Fix return value (was 1 too big).
+ * tests/mpz/t-inp_str.c: New file.
+ * tests/mpz/Makefile.am: Add it.
+
+ * mpn/x86/pentium4/sse2/add_n.asm: New file.
+ * mpn/x86/pentium4/sse2/sub_n.asm: New file.
+ * mpn/x86/pentium4/sse2/mul_1.asm: New file.
+
+2001-08-12 Kevin Ryde <kevin@swox.se>
+
+ * printf/sprintffuns.c, printf/doprntf.c: Don't use sprintf return
+ value (it's a pointer on SunOS 4).
+
+ * acinclude.m4 (GMP_ASM_X86_SSE2, GMP_STRIP_PATH): New macros.
+ * configure.in: Add pentium4 support.
+ * mpn/x86/pentium4, mpn/x86/pentium4/mmx, mpn/x86/pentium4/sse2: New
+ directories.
+ * mpn/x86/README: Update.
+
+2001-08-10 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (setup_error_handler): Catch also SIGABRT.
+
+2001-07-31 Kevin Ryde <kevin@swox.se>
+
+ * tests/refmpn.c (refmpn_mul_1c): Allow low to high overlaps.
+
+ * gmp-h.in, gmp-impl.h (_gmp_rand): Move prototype to gmp-impl.h.
+
+ * tune/Makefile.am (EXTRA_DIST): Add many.pl.
+
+2001-07-28 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Random Number Functions): Old rand functions no longer use
+ the C library.
+
+ * configure.in, acinclude.m4 (GMP_FUNC_VSNPRINTF): New macro.
+
+ * mpn/generic/get_str.c: Add an ASSERT for high limb non-zero.
+
+2001-07-24 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Build Options): Add --enable-cxx.
+ (Converting Floats): Note mpf_get_str only generates accurately
+ representable digits.
+ (Low-level Functions): Note mpn_get_str requires non-zero high limb.
+ (Formatted Output): New chapter.
+ (Multiplication Algorithms): Use @quotation with @multitable.
+ (Toom-Cook 3-Way Multiplication): Ditto.
+
+ * tests/memory.c (tests_free_nosize): New function.
+ * tests/tests.h (tests_allocate etc): Add prototypes.
+
+ * tests/printf: New directory.
+ * tests/printf/Makefile.am, t-printf.c, t-ostream.cc: New files.
+ * configure.in, tests/Makefile.am: Add them.
+
+ * configure.in, acinclude.m4 (GMP_PROG_CXX): New macro.
+ * configure.in (--enable-cxx): New option.
+ (AC_CHECK_HEADERS): Add locale.h and sys/types.h, remove unistd.h.
+ (AC_CHECK_TYPES): Add intmax_t, long double, long long, ptrdiff_t,
+ quad_t.
+ (AC_CHECK_FUNCS): Add localeconv, memset, obstack_vprintf, snprintf,
+ strchr, vsnprintf.
+ (AC_CHECK_DECLS): Add vfprintf.
+
+ * gmp-h.in, gmp-impl.h: Additions for gmp_printf etc.
+
+ * printf: New directory.
+ * printf/Makefile.am, asprintf.c, doprnt.c, doprntf.c, doprntfx.cc,
+ doprnti.c, doprntix.cc, fprintf.c, obprintf.c, obprntffuns.c,
+ obvprintf.c, osfuns.cc, osmpf.cc, osmpq.cc, osmpz.cc, printf.c,
+ printffuns.c, snprintf.c, snprntffuns.c, sprintf.c, sprintffuns.c,
+ vasprintf.c, vfprintf.c, vprintf.c, vsnprintf.c, vsprintf.c: New
+ files.
+ * configure.in, Makefile.am: Add them.
+
+ * configure.in (HAVE_INLINE): Remove AC_DEFINE, unused.
+ (AC_CHECK_TYPES): Don't test for void, assume it always exists.
+
+ * gmp-impl.h (__GMP_REALLOCATE_FUNC_MAYBE): New macro.
+ * mpz/get_str.c, mpq/get_str.c, mpf/get_str.c: Use it.
+
+ * gmp-impl.h (mpn_fib2_ui): Use __MPN.
+ (MPN_COPY_DECR): Fix an ASSERT.
+ (CAST_TO_VOID): Remove macro.
+
+ * gmp-h.in (mpq_out_str): Give #define even without prototype.
+ (mpz_cmp_d, mpz_cmpabs_d): Corrections to #defines.
+
+ * tests/devel/try.c: Add mpn_add and mpn_sub, don't use CAST_TO_VOID.
+
+2001-07-23 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Recognize pentium4.
+ * config.sub: Recognize pentium4.
+
+2001-07-17 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (__GMPN_AORS_1): Remove x86 and gcc versions, leave just
+ one version.
+ (__GMPN_ADD, __GMPN_SUB): New macros, rewrite of mpn_add and mpn_sub.
+ (mpn_add, mpn_sub): Use them.
+ (__GMPN_COPY_REST): New macro.
+
+ * gmp-h.in, gmp-impl.h, acinclude.m4: Remove __GMP_ASM_L and
+ __GMP_LSYM_PREFIX, revert to ASM_L in gmp-impl.h and AC_DEFINE of
+ LSYM_PREFIX.
+
+2001-07-11 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (__GMPN_ADD_1 etc) [x86]: Don't use this on egcs 2.91.
+
+ * mpz/fits_uint.c, fits_ulong.c, mpz/fits_ushort.c: Split up fits_u.c.
+ * mpz/fits_u.c: Remove file.
+ * mpz/Makefile.am, macos/Makefile.in: Update.
+
+ * tests/refmpn.c,tests.h (refmpn_copy): New function.
+ * tests/devel/try.c (TYPE_ZERO): No return value from call.
+ (TYPE_MODEXACT_1_ODD, TYPE_MODEXACT_1C_ODD): Share call with
+ TYPE_MOD_1 and TYPE_MOD_1C.
+ (MPN_COPY, __GMPN_COPY, __GMPN_COPY_INCR): Add testing.
+
+2001-07-10 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (__GMPN_COPY): Add form to help gcc on power and powerpc.
+ * gmp-impl.h (MPN_COPY_INCR, MPN_COPY_DECR, MPN_ZERO): Ditto.
+ * mpn/powerpc64/copyi.asm, mpn/powerpc64/copyd.asm: Remove files.
+
+ * mpz/tdiv_ui.c: Eliminate some local variables (seems to save code on
+ i386 gcc 2.95.x), remove a bogus comment about quotient.
+
+ * errno.c, gmp-impl.h (__gmp_exception, __gmp_divide_by_zero,
+ __gmp_sqrt_of_negative): New functions.
+ * gmp-impl.h (GMP_ERROR, DIVIDE_BY_ZERO, SQRT_OF_NEGATIVE): Use them.
+
+ * randclr.c, randraw.c: Use ASSERT(0) for unrecognised algorithms.
+
+2001-07-07 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (powerpc*-*-*): Use -no-cpp-precomp for Darwin.
+
+ * tests/mpbsd/t-itom.c: Renamed from t-misc.c.
+ * tests/mpbsd/t-misc.c: Remove file.
+ * tests/mpbsd/Makefile.am: Update.
+
+ * tests/mpf/t-set_si.c,t-cmp_si.c,t-gsprec.c: Split from t-misc.c.
+ * tests/mpf/t-misc.c: Remove file.
+ * tests/mpf/Makefile.am: Update.
+
+ * tests/mpz/t-oddeven.c,t-set_si.c,t-cmp_si.c: Split from t-misc.c.
+ * tests/mpz/t-misc.c: Remove file.
+ * tests/mpz/Makefile.am: Update.
+
+ * stack-alloc.c: Add some alignment ASSERTs.
+
+ * gmp-impl.h (MPN_NORMALIZE): Add notes on x86 repe/scasl slow.
+
+ * tests/devel/try.c (MPN_ZERO): Add testing.
+ * tune/speed.c,speed.h,common.c,many.pl (MPN_ZERO): Add measuring.
+
+ * mpn/x86/divrem_1.asm: Update a remark about gcc and "loop".
+
+ * tests/mpq/t-cmp_si.c: New file.
+ * tests/mpq/Makefile.am: Add it.
+
+ * tests/misc.c,tests.h (mpq_set_str_or_abort): New function.
+
+ * mpq/cmp_si.c: New file.
+ * Makefile.am, mpq/Makefile.am: Add it.
+ * gmp-h.in (mpq_cmp_si): Add prototype.
+ * gmp.texi (Comparing Rationals): Add doco.
+
+ * gmp-h.in (_GMP_H_HAVE_FILE): Add _FILE_DEFINED for microsoft, add
+ notes on what symbols are for what systems.
+
+2001-07-06 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (ibm032 umul_ppmm): Fix typo.
+ * longlong.h (sparclite sdiv_qrnnd): Fix typo.
+
+2001-07-03 Kevin Ryde <kevin@swox.se>
+
+ * mpz/bin_ui.c (DIVIDE): Use MPN_DIVREM_OR_DIVEXACT_1.
+ * mpz/bin_uiui.c (MULDIV): Ditto, and use local variables for size and
+ pointer.
+
+ * acinclude.m4 (GMP_INCLUDE_GMP_H): New macro, use it everywhere gmp.h
+ is wanted at configure time.
+ * acinclude.m4, configure.in (GMP_H_EXTERN_INLINE, GMP_H_HAVE_FILE):
+ New macros.
+
+ * gmp-h.in (__GMP_EXTERN_INLINE): Set to "inline" for C++.
+ (mpn_add, mpn_sub): Use new style __GMP_EXTERN_INLINE.
+ * gmp-h.in, mp-h.in, gmp-impl.h (_EXTERN_INLINE): Remove, unused.
+ * mpn/generic/add.c, mpn/generic/sub.c: New files.
+ * mpn/generic/inlines.c: Remove file.
+ * configure.in, mpn/Makefile.am: Update.
+
+ * gmp.texi (GMP Basics): Note the need for stdio.h to get FILE
+ prototypes.
+
+2001-07-01 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Build Options, Reentrancy): Updates for new
+ --enable-alloca behaviour.
+ (Debugging): Describe --enable-alloca=debug.
+ (Miscellaneous Integer Functions): Note mpz_sizeinbase ignores signs.
+ (Low-level Functions): Give a formula for mpn_gcdext cofactor.
+ (Factorial Algorithm): New section.
+ (Binomial Coefficients Algorithm): New section.
+ Misc tweaks elsewhere.
+
+ * mpf/set_prc.c: Merge the two truncation conditionals, misc cleanups,
+ no functional changes.
+
+ * mpn/*/gmp-mparam.h (DIVEXACT_1_THRESHOLD): Add tuned values.
+ * gmp-impl.h (DIVEXACT_1_THRESHOLD): Make the default 0 when
+ 2*UMUL_TIME < UDIV_TIME.
+
+ * mpn/x86/p6/dive_1.asm: New file.
+
+ * mpn/x86/dive_1.asm: New file.
+ * mpn/x86/gmp-mparam.h (DIVEXACT_1_THRESHOLD): Use it always.
+
+ * tests/refmpn.c, tests.h (refmpn_zero): New function.
+ * tests/devel/try.c: Use it.
+
+ * tests/refmpn.c (refmpn_sb_divrem_mn): Use refmpn_cmp, not mpn_cmp.
+
+ * tests/mpf/t-get_d.c (main): Use || not |.
+
+ * tests/misc.c, tests/t-modlinv.c, tests/mpq/t-get_str.c,
+ tests/mpf/reuse.c: Add string.h.
+
+2001-06-29 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_FIB2_UI,
+ SPEED_ROUTINE_COUNT_ZEROS_C): Corrections to TMP block handling.
+
+ * gmp-impl.h (MPN_TOOM3_MUL_N_MINSIZE, MPN_TOOM3_SQR_N_MINSIZE):
+ Corrections to these to account for adding tD into E.
+ (MPN_INCR_U, MPN_DECR_U) [WANT_ASSERT]: Add size
+ assertions, since mpn_add_1 and mpn_sub_1 from gmp.h don't get them.
+ (MPN_DIVREM_OR_DIVEXACT_1): Add an assert of no remainder.
+
+ * assert.c: Add stdlib.h for abort prototype.
+ * tests/spinner.c, trace.c, t-constants.c, t-count_zeros.c,
+ t-gmpmax.c, t-modlinv.c: Ditto.
+ * tests/mpz/t-bin.c, t-cmp.c, t-get_si.c, t-misc.c, t-popcount.c,
+ t-set_str.c, t-sizeinbase.c: Ditto.
+ * tests/mpq/t-equal.c, t-get_str.c, t-set_f.c, t-set_str.c: Ditto.
+ * tests/mpf/t-fits.c, t-get_d.c, t-get_si.c, t-int_p.c, t-misc.c,
+ t-trunc.c: Ditto.
+ * tests/mpbsd/allfuns.c, t-misc.c: Ditto.
+
+ * mpn/generic/mul_n.c, mpz/cfdiv_r_2exp.c: Use MPN_INCR_U rather than
+ mpn_incr_u.
+
+ * tests/devel/try.c (TYPE_SB_DIVREM_MN): More fixes for calling method.
+
+ * mpn/x86/k6/cross.pl: More insn exceptions.
+
+2001-06-23 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (__GMPN_ADD_1, __GMPN_SUB_1) [i386]: Fix some asm output
+ constraints.
+
+ * gmp-impl.h (modlimb_invert): Mask after shifting, so mask constant
+ fits a signed byte.
+
+ * tests/devel/try.c (TYPE_SB_DIVREM_MN): Fix initial fill of quotient
+ with garbage.
+
+2001-06-20 Kevin Ryde <kevin@swox.se>
+
+ * config.guess (rs6000-*-aix4* | powerpc-*-aix4*): Suppress error
+ messages if $CC_FOR_BUILD or program don't work.
+
+ * mpz/sqrt.c,sqrtrem.c: Special case for op==0, to avoid TMP_ALLOC(0).
+ * tests/refmpf.c (refmpf_add, refmpf_sub): Avoid TMP_ALLOC(0).
+
+ * tests/mpn/t-aors_1.c: New file.
+ * tests/mpn/Makefile.am: Add it.
+
+ * gmp-h.in (__GMPN_ADD_1, __GMPN_SUB_1): New macros, rewrite of
+ mpn_add_1 and mpn_sub_1, better code for src==dst and/or n==1,
+ separate versions for gcc x86, gcc generic, and non-gcc.
+ (mpn_add_1, mpn_sub_1): Use them.
+ (mpn_add, mpn_sub): Ditto, to get inlines on all compilers.
+ (extern "C") [__cplusplus]: Let this encompass the extern inlines too.
+ * mpn/generic/add_1.c,sub_1.c: New files, force code from gmp.h.
+ * configure.in, mpn/Makefile.am: Add them.
+
+ * acinclude.m4 (GMP_ASM_LSYM_PREFIX): AC_SUBST __GMP_LSYM_PREFIX
+ rather than AC_DEFINE LSYM_PREFIX.
+ * gmp-h.in (__GMP_LSYM_PREFIX): New substitution.
+ (__GMP_ASM_L): New macro.
+ * gmp-impl.h (ASM_L): Use it.
+
+ * acinclude.m4, configure.in (GMP_C_ATTRIBUTE_MALLOC): New macro.
+ * gmp-impl.h: Use it for all the malloc based TMP_ALLOCs.
+
+ * stack-alloc.h: Remove file.
+ * tal-reent.c: New file.
+ * Makefile.am: Update.
+
+ * acinclude.m4, configure.in (GMP_OPTION_ALLOCA): New macro, add
+ malloc-reentrant method, use stack-alloc.c as malloc-notreentrant,
+ make "reentrant" the default.
+ * gmp-impl.h (__TMP_ALIGN): Moved from stack-alloc.c, use a union to
+ determine the value, and demand only 4 bytes align on 32-bit systems.
+ * gmp-impl.h (WANT_TMP_NOTREENTRANT): Move global parts of
+ stack-alloc.h to here, allow non power-of-2 __TMP_ALIGN in TMP_ALLOC.
+ * gmp-impl.h: Extend extern "C" to TMP_ALLOC declarations.
+ * stack-alloc.c (tmp_stack): Move private parts of stack-alloc.h to
+ here, use gmp-impl.h.
+
+ * gmp-impl.h (TMP_ALLOC_LIMBS_2): New macro.
+ * mpz/fib_ui.c, mpz/jacobi.c, mpq/cmp.c, mpn/generic/fib2_ui.c: Use it.
+
+ * mpfr/exp2.c: Patch by Paul to match TMP_MARK and TMP_FREE in loop.
+ * mpfr/sqrt.c: Scope nested TMP_DECL into nested { } block, patch by
+ Paul, tweaked by me.
+ * mpfr/agm.c: Ditto, and add a final TMP_FREE(marker2).
+
+ * gmp-h.in (mpn_cmp): Add __GMP_ATTRIBUTE_PURE.
+
+ * INSTALL: Clarify "make install", tweak formatting a bit.
+
+2001-06-17 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, Makefile.am, gmp-impl.h: Add a debugging TMP_ALLOC,
+ selected with --enable-alloca=debug.
+ * tal-debug.c: New file.
+ * configure.in, Makefile.am: Compile stack-alloc.c only for
+ --disable-alloca.
+ * assert.c (__gmp_assert_header): New function, split from
+ __gmp_assert_fail.
+
+ * mpz/lcm.c: Don't TMP_MARK and then just return. Remove unnecessary
+ _mpz_realloc prototype.
+
+ * mpn/generic/mul.c (mpn_sqr_n): Use __gmp_allocate_func for toom3
+ temporary workspace.
+
+2001-06-15 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpz/t-set_f.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpz/set_f.c: Share MPN_COPY between pad and trunc cases, do exp<=0
+ test earlier, store SIZ(w) earlier.
+
+ * tests/t-count_zeros.c: New file.
+ * tests/t-gmpmax.c: New file.
+ * tests/Makefile.am (check_PROGRAMS): Add them.
+
+ * mp_clz_tab.c: Compile the table only if longlong.h says it's needed;
+ add an internal-use-only comment.
+ * tune/common.c: Force a __clz_tab for convenience when testing.
+
+ * mpn/x86/pentium/gmp-mparam.h, mpn/x86/pentium/mmx/gmp-mparam.h: Add
+ COUNT_LEADING_ZEROS_NEED_CLZ_TAB, for mod_1.asm.
+
+ * longlong.h (count_leading_zeros) [pentium]: Decide to go with float
+ method for p54.
+ (count_leading_zeros) [alpha]: Add COUNT_LEADING_ZEROS_NEED_CLZ_TAB.
+ (__clz_tab): Provide a prototype only if it's needed.
+
+ * tests/trace.c (mpz_trace): Don't use = on structures.
+ (mpn_trace): Set _mp_alloc when creating mpz.
+
+2001-06-12 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/divrem_1.asm: Amend some comments about P5 speed.
+
+ * tune/README: Clarify reconfigure on gmp-mparam.h update.
+
+ * mpn/x86/p6/copyd.asm: New file.
+ * mpn/x86/p6/README: Update copyd and mod_1.
+ * mpn/x86/copyd.asm: Amend some comments.
+
+ * gmp-impl.h (__builtin_constant_p): Add dummy for non-gcc.
+ (mpn_incr_u, mpn_decr_u): Recognise incr==1 at compile time in the
+ generic code on gcc.
+
+ * gmp-impl.h (ASSERT_ZERO_P, ASSERT_MPN_NONZERO_P): New macros.
+ * mpn/generic/gcd_1.c, mpn/generic/mul_fft.c: Use them.
+ * mpz/get_d.c: Add a private mpn_zero_p.
+ * mpfr/trunc.c: Use own mpn_zero_p.
+ * tune/speed.h (SPEED_ROUTINE_MPN_GCD_1N): Use refmpn_zero_p.
+ * gmp-impl.h (mpn_zero_p): Remove, no longer needed.
+
+ * gmp-h.in, gmp-impl.h: Move MPN_CMP to gmp.h as __GMPN_CMP, leave an
+ MPN_CMP alias in gmp-impl.h.
+ * gmp-h.in (mpn_cmp): Add an inline version.
+ * mpn/generic/cmp.c: Use __GMP_FORCE_mpn_cmp to get code from gmp.h.
+
+ * acinclude.m4 (GMP_C_ATTRIBUTE_MODE): New macro.
+ * configure.in: Call it.
+ * gmp-impl.h (SItype etc): Use it.
+
+ * randraw.c (lc): Change mpn_mul_basecase->mpn_mul,
+ mpn_incr_u->MPN_INCR_U, abort->ASSERT_ALWAYS(0).
+
+ * longlong.h (count_leading_zeros) [pentiumpro]: Work around a partial
+ register stall on gcc < 3.
+
+ * gmp.texi (Introduction to GMP): Add IA-64.
+ (Notes for Particular Systems): i386 means generic x86.
+
+ * tests/t-modlinv.c: Use tests_start and tests_end.
+
+2001-06-10 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Number Theoretic Functions): mpz_jacobi only defined for b
+ odd. Separate the jacobi/legendre/kronecker descriptions.
+ (Low-level Functions): Document mpn_mul_1 "incr" overlaps.
+ (Language Bindings): New chapter.
+
+ * mpz/jacobi.c: Don't retaining old behaviour of mpz_jacobi on even b
+ (it wasn't documented in 3.1.1).
+ * mpz/jacobi.c, gmp-h.in (mpz_kronecker, mpz_legendre): Remove
+ separate entrypoints, just #define to mpz_jacobi.
+ * compat.c (__gmpz_legendre): Add compatibility entrypoint.
+
+ * mpn/generic/mul_1.c: Allow "incr" style overlaps.
+ * tests/devel/try.c (param_init): Test this.
+
+ * mpf/mul_ui.c: Do size==0 test earlier.
+
+2001-06-08 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (ULONG_HIGHBIT, UINT_HIGHBIT, USHRT_HIGHBIT): Cast
+ ULONG_MAX etc to unsigned long etc before attempting to right shift.
+
+ * acinclude.m4 (GMP_ASM_LSYM_PREFIX): Add an AC_DEFINE of LSYM_PREFIX.
+ * gmp-impl.h (ASM_L): New macro.
+ (mpn_incr_u, mpn_decr_u, MPN_INCR_U, MPN_DECR_U): Add i386 optimized
+ versions.
+
+ * mpn/hppa/*.s,S,asm: Use .label so the code works with gas on hppa
+ GNU/Linux too, reported by LaMont Jones <lamont@smallone.fc.hp.com>.
+ * mpn/hppa/README: Add some notes on this.
+ * acinclude.m4 (GMP_ASM_LABEL_SUFFIX): Ditto.
+
+ * mpn/Makefile.am (nodist_libdummy_la_SOURCES): Add dive_1.c,
+ fib2_ui.c.
+
+ * tests/mpn/t-iord_u.c: New file.
+ * tests/mpn/Makefile.am (check_PROGRAMS): Add it.
+
+ * configure.in (mips*-*-irix[6789]*): Make ABI=n32 the default, same
+ as in gmp 3.1.
+ * gmp.texi (ABI and ISA): Update.
+
+ * gmp.texi (Build Options): Misc tweaks.
+ (Notes for Particular Systems): Describe windows DLL handling.
+ (Known Build Problems): DJGPP needs bash 2.04.
+ (Number Theoretic Functions): mpz_invert returns 0<=r<modulus; add
+ mpz_fib2_ui, mpz_lucnum_ui, mpz_lucnum2_ui.
+ (Fibonacci Numbers Algorithm): Update for new formulas used.
+ (Lucas Numbers Algorithm): New section.
+
+ * tune/speed.c,speed.h,common.c,many.pl: Add mpn_fib2_ui, mpz_fib2_ui,
+ mpz_lucnum_ui, mpz_lucnum2_ui.
+ * demos/expr/exprz.c,README: Add lucnum.
+ * demos/perl/GMP.pm,GMP.xs,GMP/Mpz.pm,test.pl: Add fib2, lucnum,
+ lucnum2.
+
+ * tests/mpz/t-lucnum_ui.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add it.
+ * tests/mpz/t-fib_ui.c: Check mpz_fib2_ui too, updates for new style
+ MPN_FIB2_SIZE.
+
+ * tune/tuneup.c, tune/Makefile.am, gmp-impl.h, mpn/*/gmp-mparam.h:
+ Remove FIB_THRESHOLD, no longer required.
+
+ * mpz/fib2_ui.c, mpz/lucnum_ui.c mpz/lucnum2_ui.c: New files.
+ * Makefile.am, mpz/Makefile.am: Add them.
+ * gmp-h.in (mpz_fib2_ui, mpz_lucnum_ui, mpz_lucnum2_ui): Add
+ prototypes.
+
+ * mpn/generic/fib2_ui.c: New file.
+ * configure.in (gmp_mpn_functions): Add it.
+ * gmp-impl.h (mpn_fib2_ui, FIB_TABLE, etc): Add these.
+ * mpz/fib_ui.c: Rewrite.
+
+ * acinclude.m4 (GMP_C_SIZES): Fix _LONG_LONG_LIMB define for mp_limb_t
+ size test.
+ (GMP_FUNC_ALLOCA): Add dummy __GMP_BITS_PER_MP_LIMB for gmp-h.in work.
+
+ * configure.in (CPPFLAGS): Remove -D__GMP_WITHIN_GMP, don't want it
+ everywhere.
+ * Makefile.am, mpn/Makefile.am, mpz/Makefile.am, mpq/Makefile.am,
+ mpf/Makefile.am, mpbsd/Makefile.am (INCLUDES): Set -D__GMP_WITHIN_GMP.
+
+ * configure.in (*-*-msdosdjgpp*): Forcibly disable shared libraries,
+ to make libtests.la work.
+
+ * acconfig.h (_LONG_LONG_LIMB, HAVE_MPFR): Remove dummy defines, no
+ longer needed.
+
+ * mpz/set_ui.c: Store to _mp_d[0] unconditionally.
+
+2001-05-27 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, gmp-h.in, mp-h.in: Add support for windows DLLs.
+
+2001-05-26 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (ABI and ISA, Reentrancy): Minor tweaks
+ (Notes for Package Builds): Note gmp.h is a generated file.
+ (Notes for Particular Systems): -march=pentiumpro is used for gcc
+ 2.95.4 and up.
+ (Assembler Loop Unrolling): Mention non power-of-2 unrolling.
+ (Internals): New chapter.
+ * mpf/README: Remove file.
+
+ * demos/expr/README: Miscellaneous rewordings.
+
+ * demos/perl: New directory.
+ * demos/Makefile.am: Add it.
+ * demos/perl/INSTALL, Makefile.PL, GMP.pm, GMP.xs, typemap,
+ GMP/Mpz.pm, GMP/Mpq.pm, GMP/mpf.pm, GMP/Rand.pm, sample.pl, test.pl:
+ New files.
+
+ * configure, aclocal.m4: Update to autoconf 2.50.
+
+ * configure, aclocal.m4, ltmain.sh: Update to libtool 1.4.
+
+ * configure, aclocal.m4, missing, ansi2knr.c, */Makefile.in: Update to
+ automake 1.4f.
+ * Makefile.am: Conditionalize mpfr in $(SUBDIRS) to handle mpfr.info.
+ * mpfr/Makefile.am (INFO_DEPS): Remove previous mpfr.info handling.
+ * mpn/Makefile.am (GENERIC_SOURCES): Remove this, just put mp_bases.c
+ in libmpn_la_SOURCES.
+ * tests/Makefile.am (tests.h): Move from EXTRA_HEADERS to
+ libtests_la_SOURCES.
+ * ltconfig: Remove file, no longer needed.
+
+ * Makefile.am (gmp-impl.h, longlong.h, stack-alloc.h): Move from
+ EXTRA_DIST to libgmp_la_SOURCES, so they get included in TAGS.
+ * tests/rand/Makefile.am (gmpstat.h): Move to libstat_la_SOURCES
+ similarly.
+
+ * config.guess (68k-*-*): Use $SHELL not "sh", tweak some comments.
+
+ * mpfr/mpfr.texi (Introduction to MPFR): Tweak table formatting, note
+ non-free programs must be able to be re-linked.
+
+2001-05-20 Kevin Ryde <kevin@swox.se>
+
+ * mpn/powerpc64/addmul_1.asm, mpn/powerpc64/mul_1.asm,
+ mpn/powerpc64/submul_1.asm: Add carry-in entrypoints.
+
+2001-05-17 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (ge): Fix definition for info.
+ (Notes for Particular Systems): Mention 68k dragonball and cpu32.
+ (Efficiency): Add static linking, more about in-place operations,
+ describe mpq+/-integer using addmul.
+ (Reporting Bugs): A couple of words about self-contained reports.
+ (Floating-point Functions): Note exponent limitations of mpf_get_str
+ and mpf_set_str.
+ (Initializing Floats): Clarify mpf_get_prec, mpf_set_prec and
+ mpf_set_prec_raw a bit.
+ (Float Comparison): Note current mpf_eq deficiencies.
+
+ * gmp-h.in (__GMP_HAVE_CONST, __GMP_HAVE_PROTOTYPES,
+ __GMP_HAVE_TOKEN_PASTE): Merge GNU ansidecl.h tests for ANSI compilers.
+ * demos/expr/expr-impl-h.in: Ditto.
+
+ * gmp-impl.h (BITS_PER_MP_LIMB): Define from __GMP_BITS_PER_MP_LIMB if
+ not already in gmp-mparam.h.
+ * tests/t-constants.c (BITS_PER_MP_LIMB, __GMP_BITS_PER_MP_LIMB):
+ Check these are the same.
+
+ * gmp-h.in (mpf_get_default_prec, mpf_get_prec, mpf_set_default_prec,
+ mpf_set_prec_raw): Provide "extern inline" versions, use __GMPF on the
+ macros.
+ * mpf/get_dfl_prc.c, mpf/get_prc.c, mpf/set_dfl_prc.c,
+ mpf/set_prc_raw.c: Get code from gmp.h using __GMP_FORCE.
+
+ * gmp-h.in, gmp-impl.h (__gmp_default_fp_limb_precision): Move from
+ gmp-impl.h to gmp-h.in.
+ (__GMPF_BITS_TO_PREC, __GMPF_PREC_TO_BITS): Ditto, and use __GMPF
+ prefix and add a couple of casts.
+ * gmp-h.in (__GMP_MAX): New macro.
+ * mpf/init2.c mpf/set_prc.c: Update for __GMPF prefix.
+
+ * gmp-h.in (__GMP_BITS_PER_MP_LIMB): New templated define.
+ * acinclude.m4 (GMP_C_SIZES): Add AC_SUBST __GMP_BITS_PER_MP_LIMB,
+ remove AC_DEFINE BITS_PER_MP_LIMB.
+
+2001-05-13 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in, gmp.texi, Makefile.am, mpz/Makefile.am, tests/mpz/t-pow.c:
+ Remove mpz_si_pow_ui, pending full si support.
+ * mpz/si_pow_ui.c: Remove file.
+
+2001-05-11 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/dive_1.asm: New file.
+
+ * mpn/powerpc32/umul.asm: Use r on registers.
+ * mpn/powerpc64/umul.asm: New file.
+ * configure.in (powerpc*-*-*): Enable umul in extra_functions.
+
+ * tests/refmpn.c, tests/tests.h (refmpn_umul_ppmm): Use same arguments
+ as normal mpn_umul_ppmm.
+ (refmpn_mul_1c): Update.
+ * tests/devel/try.c, tune/many.pl: Add some umul_ppmm testing support.
+
+ * mpn/x86/k6/mmx/popham.asm, mpn/x86/k7/mmx/popham.asm: Don't support
+ size==0.
+ * mpn/x86/pentium/popcount.asm, mpn/x86/pentium/hamdist.asm: Ditto,
+ and shave a couple of cycles from the PIC entry code.
+
+ * mpz/mul.c: Use mpn_mul_1 for size==1 and mpn_mul_2 (if available)
+ for size==2, to avoid copying; do vsize==0 test earlier.
+
+ * mpf/sub.c: Test r!=u before calling mpf_set.
+ * mpf/add.c: Ditto, and share mpf_set between usize==0 and vsize==0.
+
+ * mpn/generic/tdiv_qr.c, mpq/get_d.c, mpf/div.c, mpf/set_q.c,
+ mpf/set_str.c, mpf/ui_div.c: Test for high bit set, not for
+ count_leading_zeros zero.
+
+ * acinclude.m4 (GMP_PROG_AR, GMP_PROG_NM): Print a message if extra
+ flags are added.
+
+ * tests/mpz/t-mul_i.c: New file.
+ * tests/mpz/Makefile.am: Add it.
+
+ * mpz/mul_siui.c (mpz_mul_si): Fix for -0x80..00 on long long limb.
+
+ * gmp-h.in (mpf_set_si, mpf_set_ui): Revert last change, set exp to 0
+ when n==0.
+ * mpf/ceilfloor.c, mpf/trunc.c: Fix exp to 0 when setting r to 0.
+ * gmp-impl.h (MPF_CHECK_FORMAT): Check exp==0 when size==0.
+
+2001-05-07 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in (mpf_set_si, mpf_set_ui): Don't bother setting _mp_exp to 0
+ when n==0 (use 1 unconditionally).
+ * tests/mpf/t-misc.c (check_mpf_set_si): Don't demand anything of
+ _mp_exp when _mp_size is zero.
+
+ * mpn/x86/README: Note gas _GLOBAL_OFFSET_TABLE_ with leal problem.
+
+ * gmp-h.in (mpz_fits_uint_p, mpz_fits_ulong_p, mpz_fits_ushort_p):
+ Provide these as "extern inline"s.
+ (__GMP_UINT_MAX, __GMP_ULONG_MAX, __GMP_USHRT_MAX): New macros.
+ (mpz_popcount): Use __GMP_ULONG_MAX.
+ * gmp-impl.h (UINT_MAX, ULONG_MAX, USHRT_MAX): Use __GMP_U*_MAX, if
+ not already defined.
+ * mpz/fits_u.c: Use the code from gmp.h.
+
+2001-05-06 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k7/dive_1.asm: New file.
+ * mpn/x86/k7/gcd_1.asm: New file.
+ * mpn/asm-defs.m4 (m4_count_trailing_zeros): New macro.
+
+ * gmp-h.in (mpz_get_ui, mpz_getlimbn, mpz_set_q, mpz_perfect_square_p,
+ mpz_popcount, mpz_size, mpf_set_ui, mpf_set_si, mpf_size): Provide
+ these as "extern inlines".
+ Use just one big extern "C" block.
+ * mpz/getlimbn.c, mpz/get_ui.c, mpz/perfsqr.c, mpz/popcount.c
+ mpz/set_q.c, mpz/size.c, mpf/set_si.c, mpf/set_ui.c, mpf/size.c: Use
+ __GMP_FORCE to get code from gmp.h.
+
+2001-05-03 Kevin Ryde <kevin@swox.se>
+
+ * extract-dbl.c: Add ASSERT d>=0.
+
+ * gmp.texi (Efficiency): Add mpz_addmul etc for mpz+=integer, add
+ mpz_neg etc in-place.
+ (Integer Arithmetic): Add mpz_addmul, mpz_submul, mpz_submul_ui.
+ (Initializing Rationals): Add mpq_set_str.
+ (Low-level Functions): mpn_set_str requires strsize >= 1.
+
+ * gmp-h.in (__GMP_EXTERN_INLINE, __GMP_ABS): New macros.
+ (mpz_abs, mpq_abs, mpf_abs, mpz_neg, mpq_neg, mpf_neg): Provide inline
+ versions.
+ * mpz/abs.c, mpq/abs.c, mpf/abs.c, mpz/neg.c, mpq/neg.c, mpf/neg.c:
+ Add suitable __GMP_FORCE to turn off inline versions.
+
+ * tests/mpz/t-aorsmul.c,t-cmp_d.c,t-popcount,t-set_str.c: New files.
+ * tests/mpz/Makefile.am: Add them.
+
+ * mpz/aorsmul_i.c: New file, rewrite of addmul_ui.c. Add
+ mpz_submul_ui entrypoint, share more code between some of the
+ conditionals, use mpn_mul_1c if available.
+ * mpz/addmul_ui.c: Remove file.
+ * mpz/aorsmul.c: New file.
+ * Makefile.am, mpz/Makefile.am: Update.
+ * gmp-h.in (mpz_addmul, mpz_submul, mpz_submul_ui): Add prototypes.
+ * gmp-impl.h (mpz_aorsmul_1): Add prototype.
+
+ * tests/mpq/t-set_str.c: New file.
+ * tests/mpq/Makefile.am: Add it.
+
+ * mpq/set_str.c: New file.
+ * Makefile.am, mpq/Makefile.am: Add it.
+ * gmp-h.in (mpq_set_str): Add prototype.
+
+ * mpz/set_str.c: Fix for trailing white space on zero, eg. "0 ".
+ * mpn/generic/set_str.c: Add ASSERT str_len >= 1.
+
+ * gmp-h.in, gmp-impl.h (mpn_incr_u, mpn_decr_u): Move to gmp-impl.h.
+ * gmp-impl.h (MPN_INCR_U, MPN_DECR_U): New macros.
+
+2001-04-30 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpz/t-lcm.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpz/lcm.c: Add one limb special case.
+
+ * mpz/lcm_ui.c: New file.
+ * Makefile.am, mpz/Makefile.am: Add it.
+ * gmp-h.in (mpz_lcm_ui): Add prototype.
+ * gmp.texi (Number Theoretic Functions): Add mpz_lcm_ui, document lcm
+ now always positive.
+
+ * mp-h.in (mp_size_t, mp_exp_t): Fix typedefs to match gmp-h.in.
+
+ * gmp-h.in (mpn_add_1, mpn_add, mpn_sub_1, mpn_sub): Remove K&R
+ function defines (ansi2knr will handle mpn/inline.c, and just ansi is
+ enough for gcc extern inline).
+
+ * gmp-h.in (__GMP_HAVE_TOKEN_PASTE): New macro.
+ (__MPN): Use it.
+ * gmp-impl.h (CNST_LIMB): Ditto.
+
+ * gmp-h.in, mp-h.in (__gmp_const, __gmp_signed, _PROTO, __MPN): Use
+ ANSI forms on Microsoft C.
+ (__GMP_HAVE_CONST): New define.
+ * gmp-impl.h (const, signed): Use it.
+
+ * demos/expr/expr-impl-h.in (<stdarg.h>): Use this with Microsoft C.
+ (HAVE_STDARG): New define.
+ * demos/expr/expr.c,exprz.c,exprq.c,exprf.c,exprfr.c: Use it.
+
+ * acinclude.m4 (GMP_C_STDARG): New macro.
+ * configure.in: Call it.
+ * rand.c: Use it.
+
+ * configure.in (AC_PROG_CC_STDC): New test.
+
+2001-04-25 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k6/mmx/dive_1.asm: New file.
+ * mpn/x86/x86-defs.m4 (Zdisp): Two more insns.
+
+ * mpn/x86/pentium/mul_2.asm: New file.
+ * mpn/asm-defs.m4: Add define_mpn(mul_2).
+ * acconfig.h (HAVE_NATIVE_mpn_divexact_1, mul_2): Add templates.
+
+ * configure.in (ABI): Use AC_ARG_VAR.
+
+ * tests/devel/try.c: Run reference function when validate fails.
+
+ * mpq/get_str.c: Fixes for negative bases.
+ * tests/mpq/t-get_str.c: Check negative bases.
+ * tests/misc.c,tests.h (__gmp_allocate_strdup, strtoupper): New
+ functions.
+
+2001-04-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/lcm.c (mpz_lcm): Make result always positive.
+
+ * gmp-h.in (mpz_inp_binary, mpz_out_binary): Remove declarations.
+
+2001-04-22 Kevin Ryde <kevin@swox.se>
+
+ * mpn/powerpc64/addsub_n.asm: Use config.m4 not asm-syntax.m4.
+
+ * mpz/cmp_d.c, mpz/cmpabs_d.c: New files.
+ * Makefile.am, mpz/Makefile.am: Add them.
+ * mpf/cmp_d.c, mpf/get_dfl_prec.c: New files.
+ * Makefile.am, mpf/Makefile.am: Add them.
+ * gmp-h.in (mpz_cmp_d, mpz_cmpabs_d, mpf_cmp_d, mpf_get_default_prec):
+ Add prototypes.
+ * gmp.texi: Add documentation.
+
+ * mpf/set_prc.c: Avoid a realloc call if already the right precision.
+
+ * gmp-impl.h (MPF_BITS_TO_PREC, MPF_PREC_TO_BITS): New macros.
+ * mpf/get_prc.c, init2.c, set_dfl_prec.c, set_prc.c, set_prc_raw.c:
+ Use them.
+
+2001-04-20 Kevin Ryde <kevin@swox.se>
+
+ * tests/devel/try.c: Don't test size==0 on mpn_popcount and
+ mpn_hamdist; add testing for mpn_divexact_1; print some limb values
+ with mpn_trace not printf.
+
+ * mpz/popcount.c, mpz/hamdist.c: Don't pass size==0 to mpn_popcount
+ and mpn_hamdist.
+ * mpn/generic/popham.c: Don't support size==0.
+
+ * config.guess (m68k-*-*): Detect m68010, return m68360 for cpu32,
+ cleanup the nesting a bit.
+
+ * gmp.texi (Integer Division): Fix mpz_congruent_2exp_p "c" type.
+ (Integer Division): Add mpz_divexact_ui.
+ (Number Theoretic Functions): Fix mpz_nextprime return type.
+ (Exact Remainder): Divisibility tests now implemented.
+ And more index entries in a few places.
+
+ * tests/mpz/dive_ui.c: New file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpz/dive_ui.c: New file.
+ * Makefile.am, mpz/Makefile.am: Add it.
+ * gmp-h.in (mpz_divexact_ui): Add prototype.
+
+ * tune/many.pl, tune/speed.h: Add special mpn_back_to_back for
+ development.
+
+ * gmp-impl.h (MPN_DIVREM_OR_DIVEXACT_1): New macro.
+ * mpz/divexact.c: Use it.
+
+ * gmp-impl.h (DIVEXACT_1_THRESHOLD): New threshold.
+ * tune/tuneup.c: Tune it.
+
+ * tune/speed.c,speed.h,common.c,many.pl: Add measuring of
+ mpn_divexact_1, mpn_copyi, mpn_copyd.
+
+ * mpn/generic/dive_1.c: New file.
+ * configure.in (gmp_mpn_functions): Add it.
+ * gmp-impl.h (mpn_divexact_1): Add prototype.
+ * mpn/asm-defs.m4: Add define_mpn(divexact_1).
+
+ * tests/mpn: New directory.
+ * tests/Makefile.am: Add it.
+ * tests/mpn/Makefile.am: New file.
+ * configure.in (AC_OUTPUT): Add it.
+ * tests/mpn/t-asmtype.c: New file.
+
+ * configure, config.in: Update to autoconf 2.49d.
+
+ * configure.in, gmp-h.in, mp-h.in, demos/expr/expr-impl-h.in: Revert
+ to generating gmp.h, mp.h and expr-impl.h with AC_OUTPUT and AC_SUBST.
+
+ * configure.in (m68*-*-*): Oops, m683?2 is 68000, m68360 is cpu32.
+ * mpn/m68k/m68k-defs.m4 (scale_available_p): Ditto.
+
+ * configure.in (underscore, asm_align): Remove these variables, unused.
+ (GMP_ASM_*): Sort by AC_REQUIREs, to avoid duplication.
+ * acinclude.m4 (GMP_ASM_UNDERSCORE, GMP_ASM_ALIGN_LOG): Remove support
+ for actions, no longer needed.
+
+2001-04-17 Kevin Ryde <kevin@swox.se>
+
+ * config.guess (m68k-*-*): Look for cpu in linux kernel /proc/cpuinfo.
+
+ * acinclude.m4 (GMP_GCC_MARCH_PENTIUMPRO): The -mpentiumpro problem is
+ fixed in 2.95.4, so test for that.
+ (GMP_ASM_TYPE): Amend some comments.
+
+ * tune/freq.c (speed_cpu_frequency_sysctl): Avoid having unused
+ variables on GNU/Linux.
+
+ * mpn/asm-defs.m4 (m4_instruction_wrapper): Fix a quoting problem if
+ the name of the file is a macro.
+
+2001-04-15 Kevin Ryde <kevin@swox.se>
+
+ * mpn/powerpc64/*.asm: Add speeds on ppc630.
+
+ * acconfig.h: Add dummy templates for _LONG_LONG_LIMB and HAVE_MPFR.
+ * configure.in: Ensure config.in is the last AM_CONFIG_HEADER,
+ which autoheader requires.
+
+ * mpn/x86/pentium/popcount.asm: New file.
+ * mpn/x86/pentium/hamdist.asm: New file.
+
+ * mpn/asm-defs.m4: (m4_popcount): New macro.
+ Amend a few comments elsewhere.
+
+ * acinclude.m4 (GMP_ASM_RODATA): If possible, grep compiler output for
+ the right directive.
+
+ * tune/speed.c: Print clock speed in MHz, not cycle time.
+
+ * configure.in (AC_CHECK_HEADERS): Check for sys/processor.h.
+ * tune/freq.c (speed_cpu_frequency_processor_info): Require
+ <sys/processor.h> to exist, to differentiate the different
+ processor_info on Darwin.
+ (speed_cpu_frequency_sysctlbyname): Remove hw.model test which is in
+ speed_cpu_frequency_sysctl.
+ (speed_cpu_frequency_sysctl): Add hw.cpufrequency for Darwin.
+
+ * gmp-impl.h (MPN_LOGOPS_N_INLINE, mpn_and_n ... mpn_xnor_n): Use a
+ single expression argument for the different operations, necessary for
+ the Darwin "smart" preprocessor.
+
+ * mpn/m68k/t-m68k-defs.pl: Allow white space in m4_definsn and
+ m4_defbranch.
+
+ * tune/many.pl: Change RM_TMP_S to RM_TMP to match mpn/Makeasm.am,
+ avoid a possibly undefined array in a diagnostic, add more renaming to
+ hamdist.
+
+2001-04-13 Kevin Ryde <kevin@swox.se>
+
+ * ltmain.sh, aclocal.m4, configure, config.in: Update to libtool 1.3d.
+ * configure.in: Change ac_ to lt_ in lt_cv_archive_cmds_need_lc and
+ lt_cv_proc_cc_pic.
+
+ * config.guess (m68*-*-*): Detect exact cpu with BSD sysctl hw.model,
+ detect 68000/68010 with trapf, detect 68302 with bfffo.
+
+2001-04-11 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_ASM_M68K_INSTRUCTION, GMP_ASM_M68K_ADDRESSING,
+ GMP_ASM_M68K_BRANCHES): New macros.
+ * configure.in: Use them, remove old 68k configs, use mc68020 udiv and
+ umul.
+
+ * mpn/m68k/m68k-defs.m4: New file.
+ * mpn/m68k/t-m68k-defs.pl: New file.
+ * mpn/m68k/*.asm: New files, converted from .S. Merge add_n and sub_n
+ to aors_n, ditto mc68020 addmul_1 and submul_1 to aorsmul_1. No
+ object code changes (except .type and .size now used on NetBSD 1.4).
+ * mpn/m68k/README: New file.
+ * mpn/m68k/*.S, */*.S, syntax.h: Remove files.
+
+ * configure.in (m68*-*-netbsd1.4*): Pretend getrusage doesn't exist.
+ * tune/README: Update.
+
+ * configure.in (powerpc*-*-*): For the benefit of Darwin 1.3, add cc
+ to cclist, make gcc_cflags -Wa,-mppc optional.
+
+2001-04-06 Kevin Ryde <kevin@swox.se>
+
+ * mpn/lisp/gmpasm-mode.el (gmpasm-comment-start-regexp): Add | for 68k.
+ (gmpasm-mode-syntax-table): Add to comments.
+
+ * tests/mpz/reuse.c (dsi_div_func_names): Add names for cdiv_[qr]_2exp.
+
+2001-04-04 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_M4_M4WRAP_SPURIOUS): Fix test so as to actually
+ detect the problem, add notes on m68k netbsd 1.4.1.
+
+ * gmp.texi (Compatibility with older versions): Note libmp
+ compatibility.
+
+2001-04-03 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpz/reuse.c: Add mpz_cdiv_q_2exp and mpz_cdiv_r_2exp.
+
+ * tests/mpz/t-pow.c: Drag in refmpn.o when testing mpz_pow_ui etc with
+ refmpn_mul_2.
+
+ * tune/speed.c,speed.h,common.c,many.pl: Add measuring of mpn_com_n
+ and mpn_mul_2.
+ * tests/devel/try.c: Add testing of mpn_mul_2, and a
+ DATA_MULTIPLE_DIVISOR attribute.
+
+ * gmp.texi (Build Options): List more m68k's.
+ (Build Options): Add cross reference to tex2html.
+ (Notes for Particular Systems): Add m68k means 68020 or up.
+ (Rational Conversions): New section, with mpq_get_d, mpq_set_d and
+ mpq_set_f from Miscellaneous, and new mpq_set_str.
+ (Applying Integer Functions): Move mpq_get_num, mpq_get_den,
+ mpq_set_num and mpq_set_den from Misc.
+ (Miscellaneous Rational Functions): Remove section.
+ (Custom Allocation): Partial rewrite for various clarifications.
+ (References): Improve line breaks near URLs.
+
+ * acinclude.m4 (GMP_GCC_M68K_OPTIMIZE): New macro.
+ * configure.in (m68*-*-*): Use it to run gcc 2.95.x at -O not -O2.
+ (m680?0-*-*, m683?2-*-*, m68360-*-*): Add optional gcc -m options.
+
+ * tests/mpz/t-cmp.c: New file.
+ * tests/mpz/t-sizeinbase.c: New file.
+ * tests/mpz/Makefile.am: Add them.
+
+ * gmp-impl.h (MPN_CMP): New macro.
+ * mpz/cmp.c,cmpabs.c: Use it, and minor cleanups too.
+
+ * tests/mpq/t-equal.c: New file.
+ * tests/mpq/t-get_str.c: New file.
+ * tests/mpq/Makefile.am: Add them.
+
+ * mpq/get_str.c: New file.
+ * Makefile.am, mpq/Makefile.am: Add it.
+ * gmp-h.in (mpq_get_str): Add prototype.
+
+ * mpq/equal.c: Rewrite using inline compare loops.
+
+ * tests/refmpn.c,tests.h (refmpn_mul_2): Fix parameter order.
+ * mpz/n_pow_ui.c: Fix mpn_mul_2 calls parameter order.
+
+2001-03-29 Kevin Ryde <kevin@swox.se>
+
+ * tests/mpf/t-trunc.c: New file.
+ * tests/mpf/Makefile.am (check_PROGRAMS): Add it.
+ * gmp-impl.h (MPF_CHECK_FORMAT): New macro.
+
+ * mpf/trunc.c: New file, rewrite of integer.c, preserve prec+1 in
+ copy, don't copy if unnecessary.
+ * mpf/ceilfloor.c: New file likewise, and use common subroutine for
+ ceil and floor.
+ * mpf/integer.c: Remove file.
+ * Makefile.am, mpf/Makefile.am, macos/Makefile.in: Update.
+
+ * acinclude.m4 (GMP_GCC_VERSION_GE): New macro.
+ (GMP_GCC_MARCH_PENTIUMPRO): Use it, remove CCBASE parameter (don't
+ bother checking it's gcc).
+ (GMP_GCC_ARM_UMODSI): New macro.
+ * configure.in (GMP_GCC_MARCH_PENTIUMPRO): Update parameters.
+ (arm*-*-*): Use GMP_GCC_ARM_UMODSI.
+ * gmp.texi (Notes for Particular Systems): Add arm gcc requirements.
+
+2001-03-28 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Converting Integers): Document mpz_getlimbn using absolute
+ value and giving zero for N out of range, move to end of section.
+
+ * tests/refmpn.c (refmpn_tdiv_qr): Use refmpn_divmod_1 rather than
+ refmpn_divrem_1.
+ * tests/tests.h: Add some prototypes that were missing.
+
+ * mpz/tdiv_q_ui.c: Remove a comment that belonged to mpz_tdiv_r_ui.
+
+2001-03-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/gcdext.c: Handle carry overflow after m*n multiply code
+ in both arms. Partially combine multiply arms.
+
+2001-03-24 Kevin Ryde <kevin@swox.se>
+
+ * longlong.h: Add comments to P5 count_leading_zeros.
+
+ * demos/expr/exprz.c,t-expr.c,README: Add congruent_p and divisible_p.
+
+2001-03-23 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (GMPceil, GMPfloor, ge, le): New macros.
+ (Integer Division, mpn_cmp, mpn_sqrtrem, Algorithms): Use them.
+ (mpn_bdivmod): Refer to mp_bits_per_limb, not BITS_PER_MP_LIMB, and
+ improve formatting a bit.
+ (mpn_lshift, mpn_rshift): Clarify the return values, and use {rp,n}
+ for the destination.
+ Miscellaneous minor rewordings in a few places.
+
+ * mpn/arm/arm-defs.m4: New file.
+ * configure.in (arm*-*-*): Use it.
+ * mpn/arm/*.asm: Use changecom and registers from arm-defs.m4, use L()
+ for local labels.
+
+ * mpn/x86/k6/mmx/com_n.asm: Relax code alignment (same speed).
+
+ * gmp-h.in (__GMP_ATTRIBUTE_PURE): Use __pure__ to avoid application
+ namespace.
+
+ * gmp-impl.h (ABS): Add parens around argument.
+
+2001-03-20 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_PROG_M4): Use AC_ARG_VAR on $M4.
+
+ * acinclude.m4 (GMP_M4_M4WRAP_SPURIOUS): New macro.
+ * configure.in: Use it.
+ * mpn/asm-defs.m4: Ditto.
+
+2001-03-18 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/logops_n.asm: New file.
+
+ * mpn/x86/k6/k62mmx/copyd.asm: Rewrite, smaller and simpler, faster on
+ small sizes, slower on big sizes (about half the time).
+ * mpn/x86/k6/k62mmx/copyi.asm: Remove file, in favour of generic x86.
+ * mpn/x86/copyi.asm: Add some comments.
+ * mpn/x86/k6/README: Update.
+
+ * mpn/x86/k6/gcd_1.asm: New file.
+
+ * gmp-impl.h (NEG_MOD): Fix type of __dnorm.
+
+ * acinclude.m4 (GMP_C_SIZES): Fix use of __GMP_WITHIN_CONFIGURE.
+
+2001-03-15 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (GMPabs): New macro.
+ (Float Comparison - mpf_reldiff): Use it.
+ (Integer Comparisons - mpz_cmpabs): Ditto, puts "abs" in info.
+ (Reentrancy): Update notes on old random functions.
+ (Karatsuba Multiplication): Better characterize the effect of basecase
+ speedups on the thresholds, pointed out by Torbjorn.
+
+ * tune/README: Notes on the 1x1 div threshold for mpn_gcd_1.
+
+ * tests/misc.c (mpz_pow2abs_p, mpz_flipbit, mpz_errandomb,
+ mpz_errandomb_nonzero, mpz_negrandom): New functions.
+ (mpz_erandomb, mpz_erandomb_nonzero): Use urandom().
+ * tests/spinner.c (spinner_wanted, spinner_tick): Make global.
+ * tests/tests.h: Update prototypes.
+
+ * tests/mpz/t-cong.c, tests/mpz/t-cong_2exp.c: New files.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add them.
+
+ * mpz/cong.c, mpz/cong_2exp.c, mpz/cong_ui.c: New files.
+ * Makefile.am, mpz/Makefile.am: Add them.
+ * gmp-impl.h (NEG_MOD): New macro.
+ * gmp-h.in (mpz_congruent_p, mpz_congruent_2exp_p,
+ mpz_congruent_ui_p): Add prototypes.
+ * gmp.texi (Integer Division, Efficiency): Add documentation.
+
+ * mpq/aors.c: No need for ABS on denominator sizes.
+
+ * gmp-impl.h (mpn_divisible_p): Use __MPN.
+
+ * gmp-impl.h (LOW_ZEROS_MASK): New macro.
+ * mpz/divis_ui.c, mpn/generic/divis.c: Use it.
+
+ * mpz/setbit.c: Fix normalization for case of a negative ending up
+ with a zero high limb.
+ * tests/mpz/bit.c (check_single): New test for this problem.
+
+ * configure.in (none-*-*): Fix cclist for default ABI=long.
+
+2001-03-10 Kevin Ryde <kevin@swox.se>
+
+ * mpz/cfdiv_q_2exp.c: Don't scan for non-zero limbs if they don't
+ matter to the rounding.
+
+ * mpz/get_ui.c: Fetch _mp_d[0] unconditionally, so the code can come
+ out branch-free.
+
+2001-03-08 Kevin Ryde <kevin@swox.se>
+
+ * tests/devel/try.c (param_init): Fix reference functions for and_n
+ and nand_n.
+
+ * tune/speed.c, tests/devel/try.c: Seed RANDS, not srandom etc.
+ * configure.in (AC_CHECK_FUNCS): Remove srand48 and srandom.
+ * macos/configure (coptions): Remove random/srandom, now unnecessary.
+
+ * configure.in (gmp.h, mp.h, demos/expr/expr-impl.h): Generate using
+ AM_CONFIG_HEADER.
+ (_LONG_LONG_LIMB, HAVE_MPFR): Change to AC_DEFINEs.
+ * gmp-h.in, mp-h.in, demos/expr/expr-impl-h.in: Change to #undef's.
+ * acinclude.m4 (GMP_FUNC_ALLOCA, GMP_C_SIZES): Use gmp-h.in, not gmp.h.
+ * Makefile.am (EXTRA_DIST): Remove gmp-h.in and mp-h.in, now done
+ automatically.
+ * acinclude.m4 (GMP_FUNC_ALLOCA), gmp-impl.h: Set and use
+ __GMP_WITHIN_CONFIGURE rather than GMP_FUNC_ALLOCA_TEST.
+
+ * mpf/random2.c: Use _gmp_rand and RANDS instead of random() for the
+ exponent, ensures full range of values too.
+
+ * tests/mpz/t-div_2exp.c (check_various): Start with d based on i, but
+ don't let it go negative.
+
+ * tune/tuneup.c (KARATSUBA_MUL_THRESHOLD): Limit probing to
+ TOOM3_MUL_THRESHOLD_LIMIT, the size of the workspace in mul_n.c.
+ Use a -1 with this too, so size<LIMIT not <=.
+
+2001-03-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/cray/cfp/mul_1.c: Don't call mpn_add_n with size 0.
+ * mpn/cray/cfp/addmul_1.c: Likewise.
+ * mpn/cray/cfp/submul_1.c: Don't call mpn_sub_n with size 0.
+
+ * tests/mpz/t-div_2exp.c (check_various): Start 2nd d loop from 0
+ (avoid problems with Cray compilers).
+
+2001-03-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/cray/ieee/submul_1.c: Don't call mpn_sub_n with size 0.
+
+ * mpn/cray/ieee/mul_basecase.c: New file.
+ * mpn/cray/ieee/sqr_basecase.c: New file, derived from mul_basecase.c.
+
+2001-03-06 Kevin Ryde <kevin@swox.se>
+
+ * tests/devel/try.c (pointer_setup): Allow dst_size == SIZE_SIZE2 for
+ the benefit of mpn_tdiv_qr.
+
+ * tune/tuneup.c (all): Start karatsuba probing at size==4, for the
+ benefit of cray t90 ieee which has speed oddities at size==2.
+
+ * gmp-impl.h (USE_LEADING_REGPARM): Use __GMP_GNUC_PREREQ.
+ Use __GMP_ATTRIBUTE_PURE and ATTRIBUTE_CONST in a few places.
+
+ * gmp-h.in (__GMP_GNUC_PREREQ) New macro.
+ (__GMP_ATTRIBUTE_PURE): New macro, use it in many places.
+
+ * gmp-impl.h, gmp-h.in (mpn_jacobi_base): Move prototype to
+ gmp-impl.h, use ATTRIBUTE_CONST.
+
+ * tune/speed.h (speed_cyclecounter): Inline asm version for i386.
+
+ * mpz/cfdiv_r_2exp.c (cfdiv_r_2exp): Only reread "up" after second
+ realloc, first is under w!=u.
+
+2001-03-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/cray/sub_n.c: Rewrite using `majority' logic.
+
+ * mpz/cfdiv_r_2exp.c (cfdiv_r_2exp): Reread `up' after realloc of w.
+
+ * mpn/cray/ieee/mul_1.c: Rewrite. Streamline multiplications;
+ use `majority' logic.
+ * mpn/cray/ieee/addmul_1.c: Likewise.
+
+ * mpn/cray/add_n.c: Rewrite using `majority' logic.
+
+2001-03-04 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (CRAY udiv_qrnnd): No longer conditional on CRAYMPP.
+ (64-bit hppa add_ssaaaa): New.
+ (64-bit hppa sub_ddmmss): New.
+
+ * mpn/cray/ieee/invert_limb.c: New file.
+
+ * gmp-impl.h (RANDS): Add a `,0' to make it compile on more compilers.
+
+2001-03-03 Kevin Ryde <kevin@swox.se>
+
+ * mpz/n_pow_ui.c (ULONG_PARITY): Move to gmp-impl.h.
+ * gmp-impl.h (ULONG_PARITY): i386 part from n_pow_ui.c, new generic
+ form by Torbjorn.
+
+ * tests/mpz/t-div_2exp.c: New file, rewrite of t-2exp.c.
+ * tests/mpz/t-2exp.c: Remove file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Update.
+
+ * gmp-h.in (mpz_cdiv_q_2exp, mpz_cdiv_q_2exp): Add prototypes.
+ * gmp.texi (Integer Division): Add mpz_cdiv_q_2exp and mpz_cdiv_q_2exp.
+
+ * mpz/cfdiv_q_2exp.c: New file, partial rewrite of fdiv_q_2exp.c, add
+ mpz_cdiv_q_2exp entrypoint.
+ * mpz/cfdiv_r_2exp.c: New file, rewrite of fdiv_r_2exp.c, use all mpn,
+ add mpz_cdiv_r_2exp entrypoint.
+ * mpz/fdiv_q_2exp.c, mpz/fdiv_r_2exp.c: Remove files.
+ * mpz/Makefile.am (libmpz_la_SOURCES): Update.
+ * Makefile.am (MPZ_OBJECTS): Ditto.
+
+ * gmp-impl.h (USE_LEADING_REGPARM): Use __i386__ same as longlong.h
+ (REGPARM_2_1, REGPARM_3_1, REGPARM_ATTR): New macros.
+ * mpz/jacobi.c (jac_or_kron): Use them.
+
+ * configure.in (HAVE_ABI_$ABI): Re-enable this for config.m4, with
+ dots changed to underscores (necessary for hppa).
+
+ * tests/mpz/t-divis.c, tests/mpz/t-divis_2exp.c: New files.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Add them.
+
+ * gmp-h.in (mpz_divisible_p, mpz_divisible_ui_p,
+ mpz_divisible_2exp_p): Add prototypes.
+ * gmp.texi (Integer Division): Add mpz_divisible_p.
+ (Efficiency): Add remarks about divisibility testing.
+
+ * mpz/divis.c, mpz/divis_ui.c, mpz/divis_2exp.c: New files.
+ * mpz/Makefile.am (libmpz_la_SOURCES): Add them.
+ * Makefile.am (MPZ_OBJECTS): Ditto.
+
+ * mpn/generic/divis.c: New file.
+ * configure.in (gmp_mpn_functions): Add it.
+ * mpn/Makefile.am (nodist_libdummy_la_SOURCES): Ditto.
+ * gmp-impl.h (mpn_divisible_p): Add prototype.
+
+ * urandom.h: Remove file.
+ * Makefile.am (EXTRA_DIST): Remove it.
+
+ * tests/mpz/convert.c, dive.c, io.c, logic.c, reuse.c, t-2exp.c,
+ t-fdiv.c, t-fdiv_ui.c, t-gcd.c, t-jac.c, t-mul.c, t-pow.c,
+ t-powm.c, t-powm_ui.c, t-root.c, t-sqrtrem.c, t-tdiv.c,
+ t-tdiv_ui.c: Use RANDS, initialized by tests_rand_start.
+
+ * tests/mpz/t-pow.c: New file, being t-pow_ui renamed and with some
+ further tests added.
+ * tests/mpz/t-pow_ui.c: Remove file.
+ * tests/mpz/Makefile.am (check_PROGRAMS): Update.
+
+ * tests/t-modlinv.c: Don't use urandom.h.
+ * tests/mpz/bit.c, tests/mpz/t-scan.c: Ditto.
+ * tests/mpq/t-cmp.c, tests/mpq/t-cmp_ui.c, tests/mpq/t-get_d.c: Ditto.
+ * tests/mpf/reuse.c, t-add.c, t-conv.c, t-dm2exp.c, t-muldiv.c,
+ t-sqrt.c, t-sub.c: Ditto.
+
+ * tests/misc.c (tests_rand_start, tests_rand_end): New functions.
+ (tests_start, tests_end): Use them.
+ (urandom): New function.
+ * tests/tests.h: Add prototypes.
+
+ * mpz/random.c: Rewrite using mpz_urandomb and RANDS.
+ * mpn/generic/random.c: Rewrite using _gmp_rand and RANDS.
+ * mpn/generic/random2.c: Use RANDS not random() etc.
+
+ * gmp-impl.h (__gmp_rands, __gmp_rands_initialized): Add externs.
+ (gmp_randstate_ptr): New typedef.
+ (RANDS, RANDS_CLEAR): New macros.
+
+ * rands.c: New file.
+ * Makefile.am (libgmp_la_SOURCES): Add it.
+
+ * configure.in (mpn_objs_in_libmp): New AC_SUBST.
+ * Makefile.am (libmp_la_DEPENDENCIES): Use it.
+
+2001-03-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64/udiv_qrnnd.asm: New file.
+
+2001-03-01 Kevin Ryde <kevin@swox.se>
+
+ * mpbsd/rpow.c: New file.
+ * mpbsd/Makefile.am (libmpbsd_la_SOURCES): Add it
+ (nodist_libmpbsd_la_SOURCES): Remove pow_ui.c.
+ * Makefile.am (MPBSD_OBJECTS): Add rpow.lo, remove pow_ui.lo.
+ (libmp_la_DEPENDENCIES): Add mpz/n_pow_ui.lo.
+
+ * mpz/ui_pow_ui.c: Rewrite using mpz_n_pow_ui.
+ * mpz/pow_ui.c: Ditto, and no longer provide rpow for mpbsd.
+
+ * mpz/n_pow_ui.c: New file, rewrite of pow_ui.c and ui_pow_ui.c. Use
+ less temporary memory, strip factors of 2 from the base, use mpn_mul_2
+ if available.
+ * mpz/si_pow_ui.c: New file.
+ * mpz/Makefile.am (libmpz_la_SOURCES): Add them.
+ * Makefile.am (MPZ_OBJECTS): Ditto.
+ * gmp-impl.h (mpz_n_pow_ui): Add prototype.
+ * gmp-h.in (mpz_si_pow_ui): Add prototype.
+ * gmp.texi (Integer Exponentiation): Add mpz_si_pow_ui.
+
+ * acinclude.m4 (GMP_C_SIZES): Add BITS_PER_ULONG.
+ Correction to mp_limb_t working check.
+ * configure.in (limb_chosen): New variable.
+ * tests/t-constants.c (BITS_PER_ULONG): Check this value.
+ Add some reminders about tests that fail on Cray.
+
+ * tests/refmpn.c (refmpn_mul_2): New function.
+ * tests/refmpz.c (refmpz_pow_ui): Copied from tests/mpz/t-pow_ui.c
+ * tests/tests.h: Add prototypes.
+
+ * configure.in (none-*-*): Add ABI=longlong.
+ * doc/configuration (Long long limb testing): Describe it.
+
+ * gmp.texi (Low-level Functions): Move some commented out remarks ...
+ * mpn/generic/mul_basecase.c: ... to here.
+
+ * mpn/x86/README: Note "%=" as an alternative to "1:" in __asm__.
+
+ * tests/trace.c (mp_trace_start): Print "bin" for binary.
+
+ * mpn/generic/dump.c: Add a couple of casts to keep gcc quiet.
+
+ * gmp-h.in (mpn_incr_u, mpn_decr_u): Add parens around arguments.
+
+ * mpbsd/mout.c, mpbsd/mtox.c (num_to_text): Remove unused variable.
+
+ * mpfr/set_d.c (mpfr_get_d2): Declare "q" for 64-bit limbs.
+
+2001-02-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64w/udiv_qrnnd.asm: Tune.
+
+2001-02-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64w/udiv_qrnnd.asm: New file.
+
+2001-02-26 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (arm): Optimize sub_ddmmss by testing for constant
+ operands.
+ * mpn/arm/invert_limb.asm: New file.
+
+2001-02-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/lshift.c: Rewrite.
+ * mpn/generic/rshift.c: Rewrite.
+
+ * longlong.h: Use UWtype for external interfaces that expect mp_limb_t.
+
+ * longlong.h (arm): #define invert_limb.
+
+ * mpn/arm: Make labels have local scope.
+
+ * configure.in (arm*-*-*): Set extra_functions.
+ * longlong.h (arm): #define udiv_qrnnd.
+ * mpn/arm/udiv.asm: New file.
+
+2001-02-24 Kevin Ryde <kevin@swox.se>
+
+ * tune/many.pl: Add mpn_count_leading_zeros, mpn_count_trailing_zeros
+ and mpn_invert_limb. Add count_leading_zeros, count_trailing_zeros
+ from a .h file. Correction to modexact_1_odd prototype. Support
+ ansi2knr.
+ * tune/speed.h, tune/common.c: Consequent changes.
+
+ * demos/expr/*: Make a few more functions available in expressions,
+ create only libexpr.a, misc minor updates.
+
+ * mpn/Makeasm.am: Add some comments about suffix ordering.
+
+ * tests/refmpn.c (rshift_make, lshift_make): No need to compare
+ unsigned to zero.
+
+ * mpq/mul.c: Detect and optimize squaring.
+
+2001-02-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/mips3: Convert files to `.asm'.
+
+ * mpn/arm: Convert files to `.asm'. Misc cleanups.
+ * mpn/arm/submul_1.asm: New file.
+
+2001-02-21 Kevin Ryde <kevin@swox.se>
+
+ * tune/tuneup.c (all): Only one compiler print should match, no need
+ for #undef PRINTED_COMPILER.
+
+ * mpfr/mpfr.h (mpfr_sgn): Use mpfr_cmp_ui (patch from Paul).
+
+ * mpz/fib_ui.c: Update some remarks about alternative algorithms.
+ * gmp.texi (Fibonacci Numbers Algorithm): Ditto.
+ (Assigning Floats): Clarify mpf_swap swaps the precisions too.
+ (Low-level Functions): Try to be clearer about negative cofactors.
+
+2001-02-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/copyi.asm: Streamline for small operands.
+ * mpn/sparc64/add_n.asm: Likewise.
+ * mpn/sparc64/sub_n.asm: Likewise.
+
+ * mpn/sparc64/copyd.asm: New file.
+
+2001-02-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/lshift.asm: Rewrite.
+ * mpn/sparc64/rshift.asm: Rewrite.
+
+2001-02-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/add_n.asm: Rewrite using `majority' logic.
+ * mpn/sparc64/sub_n.asm: Likewise.
+
+ * tune/tuneup.c (all): Recognise DECC and MIPSpro compilers.
+
+ * mpn/pa64/sqr_diagonal.asm: Use PROLOGUE/EPILOGUE.
+ * mpn/pa642/sqr_diagonal.asm: Likewise.
+
+ * configure.in (HAVE_ABI_$abi): Disable for now.
+
+ * mpn/asm-defs.m4 (PROLOGUE): Use LABEL_SUFFIX.
+
+ * acinclude.m4 (GMP_ASM_ATTR): New check, for hppa oddities.
+
+2001-02-18 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/hppa/hppa1_1/gmp-mparam.h: New file.
+ * mpn/hppa/hppa2_0/gmp-mparam.h: New file.
+
+ * mpn/pa64/sqr_diagonal.asm: New file.
+ * mpn/pa64w/sqr_diagonal.asm: New file.
+ * mpn/hppa/hppa1_1/sqr_diagonal.asm: New file.
+ * mpn/hppa/hppa2_0/sqr_diagonal.asm: New file.
+
+ * mpn/sparc32/v9/add_n.asm: Use `fitod' instead of `fxtod' for dummy
+ FA-pipeline insns.
+ * mpn/sparc32/v9/sub_n.asm: Likewise.
+
+2001-02-18 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Known Build Problems): Notes on make, $* and K&R, misc
+ tweaks elsewhere.
+ (Low-level Functions): Use {} notation in mpn_sqrtrem.
+ (Basecase Multiplication): Mention BASECASE_SQR_THRESHOLD.
+
+ * mpfr/isnan.c (mpfr_number_p): Infinity is not a number.
+ * mpfr/out_str.c: Pass strlen+1 for the block size to free.
+ * mpfr/get_str.c: Correction for realloc to strlen+1.
+
+ * acinclude.m4 (GMP_C_SIZES): Generate an error if mp_limb_t doesn't
+ seem to work for some reason.
+
+2001-02-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v9/gmp-mparam.h: Retune.
+
+ * mpn/sparc32/v9/add_n.asm: New file.
+ * mpn/sparc32/v9/sub_n.asm: New file.
+
+ * mpn/sparc32/v9/mul_1.asm: Tune function entry.
+ * mpn/sparc32/v9/addmul_1.asm: Likewise.
+ * mpn/sparc32/v9/submul_1.asm: Likewise.
+
+ * mpn/sparc32/v9/sqr_diagonal.asm: New file.
+
+2001-02-16 Kevin Ryde <kevin@swox.se>
+
+ * configure.in: Fix flags selection when $CC is a compiler known to us.
+
+ * demos/expr/exprfr.c (e_mpfr_cos, e_mpfr_sin): mpfr_sin_cos now
+ allows NULL for one parameter.
+
+ * mpfr/*: Update to 20010215.
+ * mpfr/trunc.c: Use -DOPERATION scheme, and gmp mpn_zero_p.
+ * mpfr/sqrt.c: Use plain mpn_sqrtrem, not mpn_sqrtrem_new.
+ * mpfr/sqrtrem.c: Remove file.
+ * mpfr/Makefile.am (libmpfr_a_SOURCES): Add isnan.c and set_ui.c,
+ remove sqrtrem.c and srandom.h.
+
+ * configfsf.guess: Update to 2001-02-13.
+ * configfsf.sub: Update to 2001-02-16.
+ * config.sub (j90, t90): Remove special handing, configfsf.sub now ok.
+
+ * Makefile.am (MPF_OBJECTS): Add a couple of missing $U's.
+
+ * tune/tuneup.c: Identify compiler used (GCC and Sun C so far).
+
+2001-02-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v9/mul_1.asm: Change `ld' to `lduw' and `st' to `stw'.
+ * mpn/sparc32/v9/addmul_1.asm: Likewise.
+ * mpn/sparc32/v9/submul_1.asm: Likewise.
+
+2001-02-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/mips3/mips.m4: New file.
+ * configure.in (mips*-*-irix[6789]*): Use mips3/mips.m4.
+
+ * mpn/powerpc64/sqr_diagonal.asm: New file.
+
+ * mpn/mips3/sqr_diagonal.asm: New file.
+
+2001-02-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/sqr_diagonal.asm: New file.
+
+ * mpn/generic/sqr_basecase.c: Remove declaration of mpn_sqr_diagonal.
+ Fix typo in header comment.
+
+2001-02-12 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/mul.c, mpn/generic/mul_n.c, gmp-impl.h: Use
+ mpn_mul_basecase for squaring below new BASECASE_SQR_THRESHOLD.
+ * tune/tuneup.c gmp-impl.h: Tune BASECASE_SQR_THRESHOLD.
+
+ * Makefile.am (libgmp.la, libmp.la): Revert change to build from
+ mpn/libmpn.la etc, go back to explicitly listed objects.
+
+ * configure.in: Recognise sparc64-*-*, not just sparc64-*-linux*.
+
+2001-02-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/asm-defs.m4 (sqr_diagonal): New define_mpn.
+
+ * mpn/alpha/sqr_diagonal.asm: New file.
+
+2001-02-11 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Low-level Functions): Note mpn_get_str clobbers its input
+ plus 1 extra limb.
+
+ * mpfr/add.c,agm.c,exp2.c,exp3.c,generic.c,log2.c,pi.c,print_raw.c,
+ set_d.c,sin_cos.c,sqrtrem.c,sub.c: Apply some tweaks for K&R.
+ * tests/mpz/reuse.c, tests/mpq/t-md_2exp.c, demos/pexpr.c,
+ demos/expr/t-expr.c: Ditto.
+
+ * configure.in (HAVE_ABI_$abi): New define in config.m4.
+
+ * gmp-impl.h (mpn_sqr_diagonal): Add prototype and define.
+ * tune/speed.c,speed.h,common.c,many.pl: Add measuring of
+ mpn_sqr_diagonal.
+
+ * gmp.texi, acinclude.m4: Mention x86 solaris 2.7 has the reg->reg
+ movq bug the same as 2.6.
+
+ * mpfr/Makefile.am (EXTRA_DIST): Add mpfr-test.h and mpf2mpfr.h.
+
+ * mpn/x86/README: Merge contents of README.family.
+ * mpn/x86/README.family: Remove file.
+
+ * mpn/Makefile.am (nodist_libdummy_la_SOURCES): Add mode1o, gcd_finda,
+ invert_limb, sqr_diagonal; remove mod_1_rs; sort alphabetically.
+
+2001-02-10 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (gmp_mpn_functions_optional): List sqr_diagonal.
+
+ * mpn/powerpc32/aix.m4: Use unnamed csects.
+ * mpn/powerpc64/aix.m4: Likewise.
+
+ * acconfig.h: Add #undef of mpn_sqr_diagonal.
+ Remove lots of spacing.
+
+ * configure.in (syntax testing section): Match power* instead of
+ powerpc*.
+ * mpn/power: Convert files to `.asm'.
+ Prefix umul_ppmm and sdiv_qrnnd.
+ Update some comments.
+
+2001-02-09 Kevin Ryde <kevin@swox.se>
+
+ * acconfig.h: Add HAVE_NATIVE_mpn_modexact_1_odd and
+ HAVE_NATIVE_mpn_modexact_1c_odd.
+
+ * configure.in (CCAS): Don't override a user selection.
+
+ * mpq/cmp_ui.c: DIVIDE_BY_ZERO if den2==0.
+
+2001-02-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/sqr_basecase.c: Use mpn_sqr_diagonal when appropriate.
+
+2001-02-07 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Low-level Functions): mpn_preinv_mod_1 now undocumented.
+
+ * mpn/generic/random2.c (myrandom): Use rand() on mingw.
+
+ * mpn/alpha/gmp-mparam.h: Update tuned parameters.
+
+2001-02-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/gmp-mparam.h: Retune.
+
+2001-02-05 Kevin Ryde <kevin@swox.se>
+
+ * Makefile.am (libgmp, libmp): Construct from mpn/libmpn.la etc rather
+ than explicitly listed objects.
+
+ * urandom.h: Use rand() on mingw.
+
+ * mpn/powerpc64/lshift.asm,addsub_n.asm: Use r1 not 1.
+
+2001-02-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/copyi.asm: New file.
+ * mpn/ia64/copyd.asm: New file.
+
+2001-02-04 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/ev5/gmp-mparam.h, mpn/mips3/gmp-mparam.h,
+ mpn/powerpc32/gmp-mparam.h, mpn/powerpc64/gmp-mparam.h,
+ mpn/sparc64/gmp-mparam.h, mpn/x86/*/gmp-mparam.h:
+ Update tuned parameters.
+
+ * mpn/x86/i486: New directory.
+ * configure.in (i486-*-*): Use it.
+ * mpn/x86/i486/gmp-mparam.h: New file.
+
+ * mpn/x86/pentium/mode1o.asm: New file.
+ * mpn/x86/p6/mode1o.asm: New file.
+
+ * tune/many.pl: Use $(ASMFLAGS_PIC) and $(CFLAGS_PIC).
+
+ * gmp.texi (Integer Division): Another rewording of 2exp divisions.
+
+2001-02-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/arm/gmp-mparam.h: Tune.
+
+ * mpn/ia64/popcount.asm: Put a `;;' break at end of main loop.
+
+ * configure.in (arm*-*-*): Set gcc_cflags in order to pass
+ $fomit_frame_pointer.
+
+ * tests/mpz/t-mul.c (base_mul): Remove an unused variable.
+
+2001-02-02 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (TIME): New macro.
+ (main): Use TIME--print timing more accurately.
+ (setup_error_handler): Increase RLIMIT_DATA to 16 Mibyte.
+
+ * longlong.h (arm): Add __CLOBBER_CC to add_ssaaaa and sub_ddmmss.
+
+2001-02-02 Kevin Ryde <kevin@swox.se>
+
+ * configure.in: Don't remove gmp-mparam.h and mpn source links under
+ --no-create since in that case they're not re-created.
+
+ * demos/expr: New directory.
+ * Makefile.am (SUBDIRS, allprogs): Add it.
+ * demos/expr/README, Makefile.am, expr.c, exprv.c, exprz.c, exprza.c,
+ exprq.c, exprqa.c, exprfa.c, exprf.c, exprfr.c, exprfra.c, expr.h,
+ expr-impl-h.in, run-expr.c, t-expr.c: New files.
+ * configure.in: Generate demos/expr/Makefile & demos/expr/expr-impl.h.
+
+ * Makefile.am: Remove mpfr from main libgmp.
+ * mpfr/Makefile.am: Build and install separate libmpfr.a.
+ * mpfr/*: Update to mpfr 2001.
+
+ * gmp-h.in (__GNU_MP_VERSION_MINOR): Bump to 2.
+ * Makefile.am (libtool -version-info): Bump appropriately.
+ * NEWS: Updates.
+
+ * tune/divrem1div.c, tune/divrem1inv.c, tune/divrem2div.c,
+ tune/divrem2inv.c: Renamed from divrem_1_div.c, divrem_1_inv.c,
+ divrem_2_div.c, divrem_2_inv.c, to be unique in DOS 8.3 filenames.
+ * tune/Makefile.am (libspeed_la_SOURCES): Update.
+
+ * mpn/x86/*/README, mpn/x86/README.family: Misc updates.
+ * tune/README: Misc updates.
+ * doc/configuration: Misc updates.
+
+ * mpn/x86/pentium/mmx/gmp-mparam.h: Change UDIV_PREINV_TIME to
+ UDIV_NORM_PREINV_TIME.
+
+ * mpz/pprime_p.c: Use ASSERT_ALWAYS instead of abort.
+
+ * rand.c (__gmp_rand_lc_scheme): Add "const".
+ (struct __gmp_rand_lc_scheme_struct): Make astr "const char *".
+
+ * demos/calc/calc.y, demos/calc/calclex.l: Add kron function.
+
+ * tests/devel/try.c: Partial rewrite, new scheme of function types,
+ allow result validation functions, add sqrtrem and jacobi testing.
+ * tune/many.pl: Corresponding updates.
+ * tests/devel/Makefile.am: Add a convenience rule for libtests.la.
+
+ * tests/refmpz.c: New file.
+ * tests/Makefile.am: Add it.
+ * tests/misc.c (mpz_erandomb, mpz_erandomb_nonzero): New functions.
+ * tests/tests.h: Add prototypes.
+
+ * mpn/x86/k6/cross.pl: Add a couple more exceptions.
+
+ * gmp.texi: Don't use @nicode{'\0'}, it doesn't come out right in tex.
+ (Introduction to GMP): Mention Cray vector systems.
+ (Build Options): Describe --enable-mpfr, refer to its manual. Add
+ Crays under supported CPUs.
+ (Debugging): Add notes on source file paths.
+ (Autoconf): New section.
+ (Assigning Integers): Note truncation by mpz_set_d, mpz_set_q and
+ mpz_set_f.
+ (Converting Integers): Note the size mpz_get_str allocates.
+ (Floating-point Functions): Rewrite introduction, clarifying some
+ points about precision handling.
+ (Converting Floats): Note the size mpf_get_str allocates, and that it
+ gives an empty string for zero. Add mpf_get_si and mpf_get_ui.
+ (Float Comparison): Give the formula mpf_reldiff calculates.
+ (Miscellaneous Float Functions): Add mpf_integer_p and mpf_fits_*_p.
+ (Random Number Functions): Misc rewordings for clarity.
+ (Random State Initialization): Ditto.
+ (Custom Allocation): Remove note on deallocate_function called with 0,
+ misc rewording and clarifications.
+ (Exact Remainder): New section.
+ (Binary GCD): A few words on initial reduction using division.
+ (Accelerated GCD): Refer to exact remainder section.
+ (Extended GCD): Extra remarks on single versus double selection.
+ (Jacobi Symbol): Update for mpz/jacobi.c rewrite and modexact_1_odd.
+ (Modular Powering Algorithm): Refer to exact remainder section.
+ (Assembler SIMD Instructions): Update remarks on MMX.
+ (Contributors): Amend to "Divide and Conquer" division.
+ (References): Tweak some formatting. Add "Proof of GMP Fast Division
+ and Square Root Implementations" by Paul Zimmermann.
+
+2001-01-31 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in: Don't ever pass -mips3; let ABI flags imply ISA.
+
+2001-01-31 Kevin Ryde <kevin@swox.se>
+
+ * tune/time.c: Remove unnecessary longlong.h.
+ (speed_endtime): Add some extra diagnostics.
+
+ * tests/mpz/t-fdiv_ui.c, tests/mpz/t-tdiv_ui.c: Use unsigned long for
+ the divisor, not mp_limb_t.
+ * tests/mpz/t-jac.c (try_base): Use %llu for long long limb.
+ * tests/trace.c: Add <string.h> for strlen.
+
+ * tune/freq.c (speed_cpu_frequency_proc_cpuinfo): Ignore "cycle
+ frequency" of 0, allow "BogoMIPS" as well as "bogomips".
+
+ * macos/Makefile.in: Add mpf/fits_s.c and mpf/fits_u.c objects.
+
+2001-01-30 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h: Add add_ssaaaa and sub_ddmmss for 64-bit sparc.
+
+2001-01-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/addmul_1.asm: Prefix registers with an `r'.
+ * mpn/powerpc64/submul_1.asm: Likewise.
+ * mpn/powerpc64/mul_1.asm: Likewise.
+
+ * configure.in (alpha*-*-*): Amend last change to handle pca*.
+
+2001-01-29 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.h (SPEED_ROUTINE_INVERT_LIMB_CALL): Don't let the
+ compiler optimize everything away.
+
+ * tune/speed.c, tune/speed.h, tune/common.c, tune/Makefile.am: Measure
+ operator_div, operator_mod, mpn_divrem_2_div, mpn_divrem_2_inv,
+ mpn_sb_divrem_m3, mpn_sb_divrem_m3_div, mpn_sb_divrem_m3_inv,
+ mpn_dc_divrem_sb_div, mpn_dc_divrem_sb_inv.
+ * tune/divrem_2_div.c, tune/divrem_2_inv.c, tune/sb_div.c,
+ tune/sb_inv.c: New files.
+
+ * tune/tuneup.c, gmp-impl.h, tune/speed.h, tune/common.c,
+ tune/Makefile.am: Tune SB_PREINV_THRESHOLD and DIVREM_2_THRESHOLD.
+
+ * mpn/generic/divrem_2.c: Use new DIVREM_2_THRESHOLD.
+ * mpn/generic/sb_divrem_mn.c: Use new SB_PREINV_THRESHOLD.
+
+ * mpn/x86/p6/mmx/lshift.asm, mpn/x86/p6/mmx/rshift.asm: New files,
+ just m4 include()ing the P55 code.
+ * configure.in (pentium[23]-*-*): Remove x86/pentium/mmx from path.
+
+2001-01-27 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_CHECK_FUNCS): Add srand48.
+ * tune/speed.c: Use this test.
+
+ * acinclude.m4 (GMP_GCC_MARCH_PENTIUMPRO): Allow "egcs-" prefix on gcc
+ --version, warn if the format is unrecognised.
+ (GMP_COMPARE_GE): Guard against empty $1 not only on last arg.
+ (GMP_INIT, GMP_FINISH, GMP_PROG_M4): Obscure or eliminate literal
+ "dnl"s since autoconf thinks they indicate faulty macros.
+
+ * mpz/get_str.c, mpf/get_str.c: Make allocated string block exactly
+ strlen(str)+1 bytes.
+ * mpz/dump.c, mpf/dump.c, tests/mpz/convert.c: Use this size when
+ freeing.
+ * tests/mpf/t-conv.c: Ditto, and ensure x==0 is exercised.
+
+ * tests/mpz/t-fits.c: New file.
+ * tests/mpz/Makefile.am: Add it.
+
+ * tests/mpf/t-fits.c: New file.
+ * tests/mpf/t-get_si.c: New file.
+ * tests/mpf/t-int.c: New file.
+ * tests/mpf/Makefile.am: Add them.
+
+ * mpf/fits_s.c: New file.
+ * mpf/fits_u.c: New file.
+ * mpf/get_si.c: New file.
+ * mpf/get_ui.c: New file.
+ * mpf/int_p.c: New file.
+ * Makefile.am, mpf/Makefile.am: Add them.
+ * gmp-h.in (mpf_fits_*_p, mpf_get_si, mpf_get_ui, mpf_integer_p): Add
+ prototypes.
+
+ * tests/memory.c (tests_allocate, tests_reallocate): Guard against
+ size==0.
+
+ * tests/mpz/*.c, tests/mpq/*.c, tests/mpf/*.c: Uses tests_start and
+ tests_end.
+
+ * gmp-impl.h (USE_LEADING_REGPARM): Fix conditionals.
+
+2001-01-23 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, mpn/Makeasm.am (ASMFLAGS_PIC): New substitution,
+ allowing -DPIC to be suppressed on cygwin.
+ (CFLAGS_PIC): New substitution, use it and $(CCAS) directly, rather
+ than $(LIBTOOL), avoiding a problem with FreeBSD 2.2.8.
+
+ * mpn/x86/k6/mode1o.asm, mpn/x86/k7/mode1o.asm: Remove an unnecessary
+ +[.-L(here)] from _GLOBAL_OFFSET_TABLE_, avoids a segv from gas 1.92.3.
+ * mpn/x86/README.family: Add notes on the problem.
+
+2001-01-20 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (alpha*-*-*): Default `flavour' to ev4.
+
+2001-01-19 Kevin Ryde <kevin@swox.se>
+
+ * assert.c, gmp-impl.h (__gmp_assert_fail): Change return type to
+ void, since it's no longer used in expressions.
+
+ * mpn/x86/addsub_n.S: Remove file, since it doesn't work and it upsets
+ tune/many.pl.
+
+ * mpz/jacobi.c: Rewrite, but still binary algorithm; accept zero and
+ negative denominators; merge mpz_jacobi and mpz_legendre, add
+ mpz_kronecker; use mpn directly, add special cases for size==1.
+ * gmp.texi (Number Theoretic Functions): Update.
+ * gmp-h.in (mpz_kronecker): Add prototype.
+ * gmp-impl.h (USE_LEADING_REGPARM): New macro.
+ * tests/mpz/t-jac.c: Test mpz_kronecker.
+ * mpz/legendre.c: Remove file.
+ * Makefile.am, mpz/Makefile.am: Update.
+
+ * longlong.h (alpha count_leading_zeros): Use __attribute__ ((const))
+ when possible, add parameter to prototype.
+ (ia64 udiv_qrnnd): Use for all compilers, not just gcc.
+ (pentium count_trailing_zeros): Use count_leading_zeros.
+
+ * acinclude.m4 (GMP_C_ATTRIBUTE_CONST, GMP_C_ATTRIBUTE_NORETURN): New
+ macros.
+ * configure.in: Use them.
+ * gmp-impl.h (ATTRIBUTE_CONST, ATTRIBUTE_NORETURN): New macros.
+ (mpn_invert_limb): Add ATTRIBUTE_CONST.
+ (__gmp_assert_fail): Add ATTRIBUTE_NORETURN.
+
+2001-01-18 Kevin Ryde <kevin@swox.se>
+
+ * gmp-h.in, gmp-impl.h (__gmp_allocate_func, __gmp_reallocate_func,
+ __gmp_free_func): Move prototypes from gmp-impl.h to gmp-h.in, for the
+ benefit of gmp++.h.
+
+ * gmp-impl.h, tests/misc.c, tests/tests.h: Move MPZ_SET_STR_OR_ABORT
+ and MPF_SET_STR_OR_ABORT to mpz_set_str_or_abort and
+ mpf_set_str_or_abort in libtests.
+ * tests/mpz/convert.c, tests/mpz/t-bin.c, tests/mpz/t-get_si.c,
+ tests/mpz/t-jac.c, tests/mpz/t-misc.c, tests/mpq/t-md_2exp.c,
+ tests/mpq/t-set_f.c, tests/mpf/t-conv.c, tests/mpf/t-misc.c: Update.
+
+ * mpn/generic/sqrtrem.c: Use MPN_COPY_INCR (for when rp==NULL).
+
+ * tests/mpz/reuse.c: Only run mpz_divexact_gcd on positive divisors.
+
+2001-01-18 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (main): Accept -vml option.
+ (fns): List `hamdist', `pow', `nextprime'.
+ (mpz_eval_expr): Return -1 for `popc' of negative.
+ (mpz_eval_expr): Handle `hamdist', `pow', `nextprime'.
+
+2001-01-15 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/ev5/mode1o.c: New file.
+
+ * tune/freq.c (speed_cpu_frequency_measure): Check cycles_works_p
+ before running speed_cyclecounter.
+ * tune/speed.h (cycles_works_p): Add prototype.
+
+2001-01-13 Torbjorn Granlund <tege@swox.com>
+
+ * tests/rand/t-rand.c (farr): Fix typo.
+ (zarr): Fix typo.
+
+2001-01-12 Kevin Ryde <kevin@swox.se>
+
+ * mpz/kronsz.c: Don't depend on right shifting a negative.
+
+ * mpn/x86/gmp-mparam.h: New file.
+
+ * mpn/x86/pentium/mmx/mul_1.asm: New file.
+
+2001-01-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/kronsz.c: Temporary workaround for Cray right shift oddities.
+ Explicitly compare against zero in tests.
+
+2001-01-10 Kevin Ryde <kevin@swox.se>
+
+ * mpz/kronzs.c: Don't depend on right shifting a negative.
+
+2001-01-09 Torbjorn Granlund <tege@swox.com>
+
+ * tests/t-constants.c: Disable some undefined tests.
+ (CHECK_MAX_S): Remove workaround for gcc 2.95.2 bug recently added.
+
+2001-01-09 Kevin Ryde <kevin@swox.se>
+
+ * tests/t-constants.c: Add more diagnostics.
+ (CHECK_MAX_S): Fix for gcc 2.95.2 -mpowerpc64 -maix64.
+
+ * mpn/x86/k6/mode1o.asm: New file.
+ * mpn/x86/k7/mode1o.asm: New file.
+
+ * mpn/asm-defs.m4 (modexact_1_odd, modexact_1c_odd): New define_mpn's.
+ (__clz_tab, modlimb_invert_table, PROLOGUE, EPILOGUE): Add asserts for
+ GSYM_PREFIX.
+ * mpn/x86/x86-defs.m4 (Zdisp): Add a movzbl.
+
+ * tests/mpz/t-jac.c (check_a_zero): New test.
+ (check_squares_zi): Fix to use (a^2/b), not (a*b/b); revert last
+ change avoiding a,b=0, both are fine.
+ (try_2den): Don't use mpz_kronecker_ui for the expected answer.
+ (try_*): Call abort rather than exit.
+
+ * mpz/kronzu.c, mpz/kronzs.c: Fix for a=0.
+
+ * tune/tuneup.c (USE_PREINV_MOD_1): Fix to use new DATA_HIGH_LT_R.
+
+2001-01-08 Torbjorn Granlund <tege@swox.com>
+
+ * urandom.h: Amend 2000-11-21 change to also handle cygwin.
+
+2001-01-08 Kevin Ryde <kevin@swox.se>
+
+ * tune/many.pl: Updates for move to tests/devel, add modexact_1_odd,
+ don't assume C files can't have carry-in entrypoints, remove
+ $(TRY_TESTS_OBJS) now in libtests.
+
+ * tests/devel/try.c, tests/refmpn.c, tests/tests.h: Remove
+ mpn_mod_1_rshift testing.
+
+ * tune/tuneup.c (fft_step_size): Test for overflow using the actual
+ mp_size_t, don't use BITS_PER_INT.
+
+ * tune/speed.c (r_string): "r" is a limb, use BITS_PER_MP_LIMB and
+ change LONG_ONES to LIMB_ONES.
+ * tune/time.c (M_2POWU): Use INT_MAX rather than BITS_PER_INT.
+
+ * extract-dbl.c (BITS_PER_PART): Use BITS_PER_MP_LIMB not
+ BITS_PER_LONGINT.
+
+ * mpz/inp_raw.c, mpz/out_raw.c: Add private defines of BITS_PER_CHAR.
+ * mpz/fac_ui.c, tests/mpz/t-fac_ui.c: Don't use BITS_PER_LONGINT.
+ * tests/mpz/t-get_si.c: Don't use BITS_PER_LONGINT, do the LONG_MAX
+ tests with some explicit code.
+
+ * mpn/*/gmp-mparam.h, acinclude.m4, tests/t-constants.c
+ (BITS_PER_LONGINT, BITS_PER_INT, BITS_PER_SHORTINT, BITS_PER_CHAR):
+ Remove defines, remove probings, remove tests.
+
+ * tune/tuneup.c (MODEXACT_1_ODD_THRESHOLD): Add tuning.
+
+ * tune/speed.c,speed.h,common.c: Add measuring of mpn_modexact_1_odd,
+ mpn_gcd_finda, and an "N" form for mpn_gcd_1.
+
+ * tests/mpz/t-jac.c (check_squares_zi): Ensure random a,b != 0.
+
+2001-01-07 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (gmp_mpn_functions): Add mode1o, remove mod_1_rs.
+
+ * mpn/generic/mod_1_rs.c: Remove file, no longer needed.
+ * gmp-h.in (mpn_mod_1_rshift): Remove prototype and define.
+
+ * mpq/set_f.c: Use MPN_STRIP_LOW_ZEROS_NOT_ZERO.
+
+ * mpz/kronzu.c, mpz/kronzs.c, mpz/kronuz.c, mpz/kronsz.c: Use
+ mpn_modexact_1_odd, new style MPN_STRIP_LOW_ZEROS_NOT_ZERO, and new
+ JACOBI macros. Various rearrangements supporting all this.
+
+ * mpn/generic/gcd_1.c: Use mpn_modexact_1_odd, reduce u%v if u much
+ bigger than v when size==1, some rearrangements supporting this.
+
+ * gmp-impl.h (JACOBI_*): More macros, add some casts to "int".
+ (MPN_STRIP_LOW_ZEROS_NOT_ZERO): Add a "low" parameter.
+ (mpn_modexact_1_odd, mpn_modexact_1c_odd): Add prototype and defines.
+ (MODEXACT_1_ODD_THRESHOLD): New threshold.
+ (MPN_MOD_OR_MODEXACT_1_ODD, JACOBI_MOD_OR_MODEXACT_1_ODD): New macros.
+
+ * mpn/generic/mode1o.c: New file.
+
+ * tests/mpz/reuse.c: Add testing of mpz_divexact_gcd.
+ * tests/mpz/t-fac_ui.c: Use libtests for memory leak checking.
+ * tests/mpz/t-fib_ui.c: Add a usage comment.
+
+ * tests/mpz/bit.c: Use libtests.
+ * tests/mpz/t-scan.c: Remove unused subroutines.
+ * tests/devel/try.c: Use libtests, define PROT_NONE if the system
+ doesn't.
+
+ * tests/spinner.c, tests/x86check.c: Use tests.h.
+ * tests/trace.c: Use tests.h, add mpf_trace.
+ * tests/refmpn.c: Use tests.h, add refmpn_malloc_limbs_aligned,
+ refmpn_tstbit, refmpn_neg.
+
+ * tune/common.c, tune/speed.h: Update for functions moved to
+ tests/misc.c.
+
+ * tune/Makefile.am, tests/mpz/Makefile.am, tests/mpq/Makefile.am,
+ tests/mpf/Makefile.am: Use tests/libtests.la.
+
+ * configure.in (AC_OUTPUT): Update for new directories.
+ (x86 CALLING_CONVENTIONS_OBJS): Use .lo for libtests.la, allow
+ ansi2knr on x86check.c.
+
+ * tests/Makefile.am: Establish new libtests.la convenience library,
+ add mpz, mpq, mpf, mpbsd subdirectories.
+ * tests/tests.h: New file.
+ * mpn/tests/ref.h,try.h: Remove files, now in tests.h.
+
+ * tests/mpf/ref.c: Move to tests/refmpf.c, rename functions to refmpf.
+ * tests/mpf/t-add.c, tests/mpf/t-sub.c: Use libtests.
+ * tests/mpf/Makefile.am: Update.
+
+ * tests/memory.c: New file.
+ * tests/misc.c: New file, a few subroutines from the test programs.
+
+ * mpz/tests, mpq/tests, mpf/tests, mpbsd/tests: Move directories to
+ tests/mpz etc.
+ * mpz/Makefile.am, mpq/Makefile.am, mpf/Makefile.am, mpbsd/Makefile.am
+ (SUBDIRS): Remove.
+
+ * tests/devel: New directory.
+ * mpn/tests/*.c: Move programs to tests/devel.
+ * mpn/tests/Makefile.am, mpn/tests/README: Move to tests/devel, update.
+
+ * mpn/tests/ref.c: Move to tests/refmpn.c.
+ * mpn/tests/spinner.c,trace.c,x86call.asm,x86check.c: Move to tests
+ directory.
+
+ * tests/t-constants.c: Add checks of HIGHBIT, MAX and MIN constants,
+ simplify ANSI vs K&R stringizing, use correct printf format types, do
+ all tests before aborting.
+
+2001-01-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/cray/ieee/gmp-mparam.h: Retune.
+
+2001-01-05 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (mp.h): Only create this under --enable-mpbsd.
+
+ * demos/calc: New subdirectory, move demos/calc* to it.
+ * demos/calc/Makefile.am: New file, split from demos/Makefile.am.
+ * demos/Makefile.am: Update.
+ * configure.in (AC_OUTPUT): Add demos/calc/Makefile.
+
+ * tests/t-constants.c (CALC_BITS_PER_TYPE etc): Use a run-time test
+ for how many bits work in a give type, don't assume bits==8*sizeof.
+
+2001-01-04 Kevin Ryde <kevin@swox.se>
+
+ * mpz/fits_s.c, mpz/fits_u.c: New files, split from fits.c, use plain
+ UINT_MAX etc, not MPZ_FITS_UTYPE_SDT etc.
+ * mpz/fits.c: Remove file.
+ * mpz/Makefile.am, macos/Makefile.in: Update.
+
+ * gmp-impl.h (UNSIGNED_TYPE_MAX etc): Remove these generic forms.
+ (MPZ_FITS_[SU]TYPE_SDT): Remove these.
+ (UINT_MAX etc): Provide a full set of defaults.
+ * gmp-h.in (__GMP_MP_SIZE_T_INT): New define.
+
+ * mpz/tests/t-scan.c: New file.
+ * mpz/tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpz/scan0.c, mpz/scan1.c: Rewrite, don't read beyond allocated
+ memory, support negatives, return ULONG_MAX for no bit found.
+ * gmp.texi (Integer Logic and Bit Fiddling): Update.
+
+2001-01-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/dive.c: Generate test operands using new random functions.
+ * mpz/tests/io.c: Likewise.
+ * mpz/tests/logic.c: Likewise.
+ * mpz/tests/t-2exp.c: Likewise.
+
+ * stack-alloc.c (__gmp_tmp_alloc): Round `now' to required alignment.
+
+ * stack-alloc.h (__TMP_ALIGN): Append `L'.
+
+ * gmp-impl.h: For Cray, #include limits.h.
+ (LONG_MIN): New #define.
+ (ULONG_HIGHBIT): #define in terms of ULONG_MAX.
+ (LONG_HIGHBIT): #define as LONG_MIN.
+ (USHRT_MAX): New name for USHORT_MAX.
+ (SHRT_MAX): New name for SHORT_MAX.
+ (SHRT_MIN): New #define.
+ (USHORT_HIGHBIT,SHORT_HIGHBIT): Removed.
+
+ * mpbsd/tests/t-misc.c (check_itom [data]): *SHORT* => *SHRT*;
+ remove code disabling a test for Cray.
+
+ * tests/t-constants.c (CHECK_CONSTANT): Cast parameters to long.
+
+ * mpn/generic/mul_n.c (mpn_kara_sqr_n): Remove unused variable `t'.
+ (mpn_kara_mul_n): Likewise.
+
+ * mpz/fac_ui.c (MPZ_SET_1_NZ): Actually use `__z'.
+
+ * mpz/tests/t-jac.c
+ (main, check_squares_zi): Generate test operands using new random
+ functions.
+
+ All changes below on this date for enabling `make; make check'
+ with C++ compilers:
+
+ * mpz/tests/t-pow_ui.c (debug_mp, ref_mpz_pow_ui): Provide prototypes.
+
+ * mpz/tests/t-mul.c (debug_mp, base_mul, ref_mpz_mul):
+ Provide prototypes.
+ (dump_abort): Provide prototype and declare properly for C++.
+
+ * mpz/tests/t-jac.c: #include stdlib.h and sys/time.h.
+
+ * mpz/tests/t-fdiv.c
+ (dump_abort): Provide prototype and declare properly for C++.
+ (debug_mp): Provide prototype.
+ * mpz/tests/t-fdiv_ui.c: Likewise.
+ * mpz/tests/t-gcd.c: Likewise.
+ * mpz/tests/t-powm.c: Likewise.
+ * mpz/tests/t-powm_ui.c: Likewise.
+ * mpz/tests/t-sqrtrem.c: Likewise.
+ * mpz/tests/t-tdiv_ui.c: Likewise.
+ * mpz/tests/t-tdiv.c: Likewise.
+
+ * mpz/tests/t-2exp.c: #include stdlib.h and sys/time.h.
+ Remove #include of longlong.h.
+
+ * mpz/tests/io.c: #include config.h, stdlib.h, sys/time.h, and
+ conditionally unistd.h.
+
+ * mpz/tests/dive.c: #include stdlib.h and sys/time.h.
+ (dump_abort): Provide prototype and declare properly for C++.
+ (debug_mp): Provide prototype.
+ * mpz/tests/logic.c: Likewise.
+
+ * mpz/tests/convert.c (debug_mp): Provide prototype.
+ * mpz/tests/t-root.c (debug_mp): Likewise.
+
+ * mpz/tests/bit.c: #include stdlib.h and sys/time.h.
+
+ * mpq/tests/t-get_d.c: #include stdlib.h and sys/time.h.
+ (dump): Provide prototype and declare properly for C++.
+
+ * mpq/tests/t-cmp_ui.c: #include stdio.h, stdlib.h and sys/time.h.
+ (ref_mpq_cmp_ui): Declare properly for C++.
+
+ * mpq/tests/t-cmp.c: #include stdlib.h and sys/time.h.
+ (ref_mpq_cmp): Declare properly for C++.
+ (dump): Delete unused function.
+
+ * mpf/random2.c (myrandom): New function.
+ (mpf_random2): Use it.
+
+ * mpn/generic/random2.c: #include stdlib.h (for random/mrand48).
+ (myrandom): New function.
+ (mpn_random2): Use it.
+
+ * mpf/tests/t-add.c: #include stdlib.h and sys/time.h.
+ (oo): Remove unused function.
+ * mpf/tests/t-conv.c: Likewise.
+ * mpf/tests/t-sub.c: Likewise.
+ * mpf/tests/t-dm2exp.c: Likewise.
+ * mpf/tests/t-muldiv.c: Likewise.
+ * mpf/tests/t-sqrt.c: Likewise.
+
+ * mpf/tests/reuse.c: #include stdlib.h and sys/time.h.
+ Use PROTO on some typedefs.
+ (oo): Remove function.
+ (dump_abort): Call mpf_dump instead of oo.
+
+ * mpf/set_str.c: #include stdlib.h (for strtol).
+
+ * mpf/random2.c: #include stdlib.h (for random/mrand48).
+ * mpn/alpha/udiv_arnnd: File deleted.
+
+ * Remove K&R function headers.
+
+2001-01-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul.c: Clean up spacing and indentation.
+
+ * mpn/generic/mul_fft.c (mpn_fft_add_modF): Use mpn_decr_u.
+ Clean up spacing and indentation.
+
+ * extract-dbl.c: Generalize to handle smaller limb sizes.
+
+2001-01-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpbsd/mout.c: Output newline after "0".
+
+2000-12-31 Torbjorn Granlund <tege@swox.com>
+
+ * ltmain.sh: Remove space between `#!' and `$SHELL' when generating
+ `libtool'.
+
+ * mpbsd/tests/t-misc.c (check_itom): Exclude test for all Cray
+ vector systems. Correct comment.
+
+2000-12-31 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (ABI and ISA): New enough gcc needed for mips n32 etc, gcc
+ 2.95 needed for sparc 64-bit ABI, gcc 2.8 needed for -mv8plus.
+
+ * configure.in ([cjt]90,sv1-cray-unicos*): Preserve user specified
+ MPN_PATH, amend test program indenting.
+ (none-*-*): Add -DNO_ASM to gcc to disable longlong.h asm macros in
+ generic C.
+
+ * config.sub (j90, t90): Preserve these, don't let configfsf.sub turn
+ them into c90.
+
+ * config.guess (m68k-*-nextstep*,m68k-*-openstep*): Don't transform
+ m68k to m68020, since m68k is already interpreted as 68020.
+
+2000-12-30 Kevin Ryde <kevin@swox.se>
+
+ * mpq/neg.c: Rewrite, use mpn, avoid denominator copy if unnecessary.
+
+ * mpz/tstbit.c: Rewrite, slightly simplified.
+ * mpz/tests/bit.c (check_tstbit): New test, and add a couple more
+ diagnostics elsewhere.
+
+ * configure.in (x86 gcc_cflags_cpu): Add -m486 for gcc 2.7.2.
+ (ccbase): Only use a known compiler in eval statements (avoids
+ problems with non-symbol characters).
+ (ccbase): Use GMP_PROG_CC_IS_GNU to identify gcc installed under a
+ different name.
+ (cclist): Use same style $abi as other variables.
+
+ * acinclude.m4 (GMP_PROG_CC_IS_GNU): New macro.
+ (GMP_GCC_MARCH_PENTIUMPRO): Use $ccbase to identify gcc.
+ (GMP_ASM_TYPE): Define TYPE to empty, not "dnl", when no .type needed.
+ (GMP_ASM_SIZE): Ditto for SIZE, which ensures EPILOGUE on the last
+ line of a file doesn't leave a tab and no newline.
+ (GMP_ASM_UNDERSCORE): Add a prototype for C++.
+
+ * configure.in (sys/mman.h, mprotect): New tests.
+ * mpn/tests/try.c: Use them, and HAVE_UNISTD_H too.
+
+ * configure.in (getopt.h): Remove test.
+ * tune/speed.c, mpn/tests/try.c (getopt.h): Remove include, since
+ plain getopt() is in <unistd.h>.
+
+ * configure.in, gmp-h.in (mips*-*-irix6*): Set limb_n32=longlong
+ rather than using _ABIN32.
+
+2000-12-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/reuse.c: Rename dump_abort => dump.
+ * mpz/tests/reuse.c: Generate operands using gmp_rand*.
+ * mpz/tests/convert.c: Likewise.
+
+ * configure.in: Detect T90-ieee systems; move Cray path
+ selection to after AC_PROG_CC. Invoke AC_PROG_CPP.
+ * mpn/cray/cfp: New directory. Move cfp specific files here.
+ * mpn/cray/cfp/mulwwc90.s: New file.
+ * mpn/cray/cfp/mulwwj90.s: New file.
+ * mpn/cray/mulww.s: Delete.
+
+2000-12-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/cray/ieee/mul_1.c: New file.
+ * mpn/cray/ieee/addmul_1.c: New file.
+ * mpn/cray/ieee/submul_1.c: New file.
+ * mpn/cray/ieee/gmp-mparam.h: New file.
+
+ * mpn/cray/gmp-mparam.h: Disable UMUL_TIME and UDIV_TIME.
+
+ * mpn/cray/hamdist.c: New file.
+ * mpn/cray/popcount.c: New file.
+ * mpn/cray/rshift.c: New file.
+ * mpn/cray/lshift.c: New file.
+
+ * longlong.h: Add count_leading_zeros for _CRAY.
+ Reorganize _CRAY stuff.
+
+2000-12-24 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (alpha*-cray-unicos*): Disable SPEED_CYCLECOUNTER_OBJ,
+ as tune/alpha.asm doesn't suit.
+
+ * mpn/generic/sqrtrem.c, mpz/pow_ui.c, mpz/powm_ui.c, mpf/get_str.c,
+ mpf/set_str.c: Use mpn_sqr_n when applicable, not mpn_mul_n.
+
+2000-12-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_fft.c: Reformat.
+ (mpn_fft_neg_modF): Remove.
+ (mpn_fft_mul_2exp_modF): Inline mpn_fft_neg_modF.
+
+ * mpn/cray/gmp-mparam.h: Retune.
+
+ * configure.in (*-cray-unicos*): Pass `-O3 -htask0'.
+ (vax*-*-*): Fix typo.
+
+ * mpn/cray/mul_1.c: Use dynamic arrays, get rid of TMP_*.
+ * mpn/cray/addmul_1.c: Likewise.
+ * mpn/cray/submul_1.c: Likewise.
+ * mpn/cray/add_n.c: Likewise.
+ * mpn/cray/sub_n.c: Likewise.
+
+ * configure.in (default cc_cflags,cc_64_cflags): Remove -g/add -O.
+ (mips*-*-irix[6789]*]): Remove -g from cc_*_cflags.
+
+2000-12-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_n.c: Delete K&R function headers.
+
+ * mpn/generic/mul_n.c (mpn_kara_mul_n): Clean up type confusion
+ between mp_limb_t and mp_size_t.
+ (mpn_kara_sqr_n): Likewise.
+
+ * mpn/generic/mul_n.c (mpn_kara_mul_n): Use mpn_incr_u.
+ (mpn_kara_sqr_n): Likewise.
+
+ * mpn/generic/mul_n.c (mpn_kara_mul_n): Change handling of `sign'
+ to work around GCC 2.8.1 MIPS bug.
+
+ * configure.in (implied alpha*-cray-unicos*): Remove -g from cc_cflags.
+
+2000-12-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/invert_limb.asm: Simplify a bit.
+ Add handling of bigend systems.
+ * mpn/alpha/unicos.m4: Define `bigend'.
+ * mpn/alpha/default.m4: Define `bigend' (to expand to nothing).
+
+ * tests/t-constants.c (CHECK_CONSTANT): Print using %lx.
+
+ * mpn/alpha/gmp-mparam.h: Remove sizes for plain C types.
+ * mpn/alpha/ev5/gmp-mparam.h: Likewise.
+ * mpn/alpha/ev6/gmp-mparam.h: Likewise.
+
+ * mpn/alpha/unicos.m4: Define LEA.
+ * mpn/alpha/default.m4: Likewise.
+ * mpn/alpha/invert_limb.asm: Use LEA for loading symbolic addresses.
+ * mpn/alpha/cntlz.asm: Likewise.
+
+ * mpn/alpha/cntlz.asm: Don't use `ldbu', use slightly slower
+ `ldq_u' + `extbl' instead.
+
+ * mpn/alpha/unicos.m4: Define EXTERN.
+ * mpn/alpha/default.m4: Define EXTERN (to expand to nothing).
+ * mpn/alpha/cntlz.asm: Declare __clz_tab usign `EXTERN' (for the
+ benefit of Unicos).
+
+2000-12-21 Kevin Ryde <kevin@swox.se>
+
+ * mpn/alpha/unicos.m4 (GSYM_PREFIX): Define for the benefit of
+ __clz_tab.
+
+2000-12-20 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h: Add udiv_qrnnd and count_leading_zeros for _CRAYMPP
+ systems.
+
+2000-12-19 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (*sparc*-*-*): Remove -g from cc_cflags and acc_cflags.
+
+ * mpn/generic/sqrtrem.c (mpn_sqrtrem): Separate `limb' values from
+ `size' values.
+
+ * configure.in (*-cray-unicos*): Add `-Wa,-B' to cc_cflags.
+
+ * demos/pexpr.c (rstate): New variable.
+ (main): Initialize rstate.
+ (enum op_t): Add RANDOM.
+ (fns): Add field for RANDOM.
+ (mpz_eval_expr): Handle RANDOM.
+
+2000-12-19 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/sqrtrem.c: Rewrite by Paul Zimmermann, based on his
+ Karatsuba Square Root algorithm.
+ * gmp.texi (Square Root Algorithm): Update.
+
+ * tune/many.pl: New file.
+
+ * mpn/tests/try.c,ref.[ch] (mpn_preinv_mod_1, mpn_sb_divrem_mn,
+ mpn_tdiv_qr, mpn_gcd_finda, mpn_kara_mul_n, mpn_kara_sqr_n,
+ mpn_toom3_mul_n, mpn_toom3_sqr_n): Add testing.
+ * mpn/tests/ref.c: Cast some "0"s in function calls.
+
+ * mpn/x86/k7/mmx/mod_1.asm: Add preinv_mod_1 entrypoint, remove extra
+ variable for loop termination.
+
+ * mpn/x86/p6/mmx/mod_1.asm: Remove file, in favour of the following.
+ * mpn/x86/p6/mod_1.asm: New file.
+
+ * mpn/x86/pentium/mod_1.asm: New file.
+
+2000-12-18 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (mips*-*-irix[6789]*): Pass options to compiler using
+ `-Wc'.
+
+2000-12-18 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k6/pre_mod_1.asm: New file.
+
+ * tune/tuneup.c (USE_PREINV_MOD_1): Tune this, rearrange mpn_divrem_1
+ and mpn_mod_1 handling in support of it.
+ * tune/Makefile.am: Consequent changes to divrem_1.c and mod_1.c.
+
+ * gmp-impl.h (USE_PREINV_MOD_1, MPN_MOD_OR_PREINV_MOD_1): New macros.
+ * mpn/generic/perfsqr.c, mpz/pprime_p.c: Use MPN_MOD_OR_PREINV_MOD_1.
+
+ * configure.in: Let an asm mod_1 provide a preinv_mod_1 entrypoint.
+
+ * mpn/alpha/default.m4: Remove some newlines, add some asserts.
+ (r0 etc, f0 etc): Use defreg and deflit.
+ (PROLOGUE, PROLOGUE_GP, EPILOGUE): Use GSYM_PREFIX.
+ * mpn/alpha/unicos.m4: Remove some newlines, add some asserts.
+ * mpn/alpha/invert_limb.asm: Remove unused second DATASTART parameter.
+ * mpn/alpha/cntlz.asm: Use mpn_count_leading_zeros and __clz_tab.
+
+ * mpn/asm-defs.m4 (changecom): Comments on portability.
+ (__clz_tab, modlimb_invert_table): New macros, matching gmp-impl.h.
+ (count_leading_zeros, count_trailing_zeros): New define_mpn's.
+ (PROLOGUE etc): Comments on usage, add some asserts.
+ (OPERATION_[lr]shift): Use m4_not_for_expansion, for the benefit of
+ lorrshift multifunc.
+
+ * mpn/Makeasm.am (RM_TMP): New variable controlling tmp-*.s
+ removal, for development purposes.
+
+ * mpz/fac_ui.c: Fix for long long limb by using mpn_mul_1 not
+ mpz_mul_ui, and note some possible enhancements.
+
+ * mpz/tests/t-fac_ui.c: New test.
+ * mpz/tests/Makefile.am (check_PROGRAMS): Add it.
+ * macos/Makefile.in: Ditto, and add t-fib_ui too.
+
+ * mpn/generic/[lr]shift.c: Remove some DEBUG code adequately covered
+ by new parameter ASSERTs.
+
+ * longlong.h (count_trailing_zeros): Assert x!=0.
+
+ * doc/configuration: Updates for new configure things, add some notes
+ on test setups.
+
+2000-12-16 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (*-*-aix): Pass -qmaxmem=20000 to xlc also for 64-bit
+ compiles.
+ * configure.in: Disable shared libs for *-*-ultrix*.
+
+2000-12-15 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (powerpc*-*-*): Pass -Wa,-mppc when using gcc.
+
+ * gmp-impl.h (_EXTERN_INLINE): #define different for GCC and other
+ compilers.
+
+ * gmp-h.in (__gmp_inline): Remove.
+ * mp-h.in: Likewise.
+ * mpn/generic/gcd.c: Use `inline' instead of `__gmp_inline'.
+
+ * configure.in (mips*-*-irix[6789]*): Define *_ldflags.
+
+2000-12-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/pre_mod_1.c: Use proper type for udiv_qrnnd
+ parameter `dummy'.
+
+ * mpn/generic/divrem_1.c: Use explicit `!= 0' in if statement.
+ * mpn/generic/mod_1.c: Likewise.
+
+2000-12-14 Kevin Ryde <kevin@swox.se>
+
+ * config.guess (mips-*-irix[6789]*): Transform to mips64.
+ (m68k-*-nextstep* | m68k-*-openstep*): Transform to m68020.
+
+2000-12-13 Torbjorn Granlund <tege@swox.com>
+
+ * tests/t-constants.c (main): Conditionalize use of PP_INVERTED.
+
+ * mpn/mp_bases.c: Handle 4-bit limbs.
+ (main): Add code for generating tables.
+
+ * mpn/generic/popham.c: Handle limb bitsizes of 4, 8, 16.
+ Suffix all 32-bit constant with `L'.
+ Use CNST_LIMB for 64-bit constants.
+
+2000-12-13 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (FIB_THRESHOLD): Defaults for 4,8,16 bits per limb, and
+ an arbitrary fallback default.
+ (modlimb_invert): Add efficient code for 8,16 (or 4) bits per limb.
+
+ * configure.in (mips3, mips64): Don't bother with o32 (mips2 32-bit
+ limb) on IRIX 6.
+
+ * Makefile.am (SUBDIRS): Put "tests" first so tests/t-constants.c is
+ run first, to pick up any limb size mismatch.
+
+ * tune/tuneup.c (DIVREM_1, MOD_1): Fix result values, were off by 1.
+
+ * mpz/fib_ui.c (table1, table2): Add data for 4,8,16 bits per limb.
+
+2000-12-12 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (LIMBS_PER_DOUBLE): Define for any limb bitsize.
+
+2000-12-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/mp_bases.c: Add tables for 8-bit and 16-bit limbs.
+ Round existing `double' values properly.
+
+ * gmp-h.in (__gmp_randstate_struct): Prefix field names with _mp_
+ to keep out of user name space.
+ (__gmp_randata_lc): Likewise.
+ * randclr.c, randlc.c, randlc2x.c, randraw.c, randsd.c, randsdui.c:
+ Corresponding changes.
+
+ * gmp-impl.h (PP): #define for machines with BITS_PER_MP_LIMB
+ of 2, 4, 8, and 16.
+ (PP_FIRST_OMITTED): New, define for various BITS_PER_MP_LIMB.
+ (PP_MASK): Remove.
+ (PP_MAXPRIME): Remove.
+
+ * mpn/generic/perfsqr.c: Generalize PP handling for machines with
+ limbs of < 32 bits. Allow PP_INVERTED to be undefined.
+ * mpz/pprime_p.c: Likewise.
+
+2000-12-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_1.c: Declare parameters in C89 style.
+
+2000-12-10 Kevin Ryde <kevin@swox.se>
+
+ * tune/Makefile.am (speed_LDFLAGS, speed_ext_LDFLAGS, tune_LDFLAGS):
+ Don't use -all-static, as gcc 2.95.2 on i386 solaris 8 doesn't like
+ it.
+
+ * configure.in (mips3,mips64): Add ABI=64, name the others ABI=n32 and
+ ABI=o32.
+ * mpn/mips3/gmp-mparam.h (BITS_PER_LONGINT): Remove #define and let
+ configure determine it, since it varies with ABI=64 or ABI=n32.
+ * gmp.texi (ABI and ISA): Update.
+ (mpz_mod_ui): Remark that it's identical to mpz_fdiv_r_ui.
+ (mpn_divexact_by3): Qualify a statement needing mp_bits_per_limb even.
+
+ * mul_fft.c (mpn_fft_mul_modF_K etc): Patch by Paul Zimmermann to fix
+ results in certain cases of recursing into a further FFT.
+
+2000-12-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/cmpabs.c: Remove unused variable.
+ * mpz/rrandomb.c: Likewise.
+ * mpz/xor.c: Likewise.
+
+2000-12-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/gcdext.c: Handle double carry when computing s1.
+ Merge two code blocks for computing s0 and s1.
+
+2000-12-07 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (hppa*-*-*): Remove -Aa -D_HPUX_SOURCE from
+ cc_cflags/cppflags, and instead let AM_C_PROTOTYPES add it, or -Ae,
+ whichever works.
+
+ * configure.in (*-*-aix[34]*): Disable shared by default, but let
+ the user override that, if desired.
+ * gmp.texi (Notes for Particular Systems): Update.
+
+2000-12-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpq/cmp_ui.c: Streamline.
+
+2000-12-06 Kevin Ryde <kevin@swox.se>
+
+ * tune/divrem_1_div.c,divrem_1_inv.c,mod_1_div.c,mod_1_inv.c,
+ gcdext_double.c: New files for measuring.
+ * tune/Makefile.am (libspeed_la_SOURCES): Add them.
+ * tune/speed.c,speed.h,common.c: Add measuring of them.
+ (mpn_preinv_mod_1, mpz_jacobi, mpz_powm_ui): Add measuring.
+
+ * speed.c (getopt_long): Don't use this, just plain getopt.
+ * configure.in (getopt_long): Remove test.
+
+ * gmp-impl.h (MPN_KARA_MUL_N_TSIZE, MPN_KARA_MUL_N_MINSIZE,
+ MPN_TOOM3_MUL_N_TSIZE, MPN_TOOM3_MUL_N_MINSIZE): New macros, and
+ assume toom3 square tsize was meant to be the same as the mul (both
+ are overestimates).
+ * tune/tuneup.c, mpn/generic/mul.c, mpn/generic/mul_n.c: Use them.
+ * mpn/generic/mul_n.c (mpn_toom3_sqr_n): Fix an ASSERT to use
+ TOOM3_SQR_THRESHOLD not TOOM3_MUL_THRESHOLD, add a few that might
+ be more realistic size checks.
+ * tune/speed.h (SPEED_ROUTINE_MPN_MUL_N_TSPACE etc): Use minsize.
+
+ * mpn/generic/divrem_1.c: Partial rewrite, merge fractional part
+ calculation, skip a divide step in more cases, introduce
+ DIVREM_1_NORM_THRESHOLD and DIVREM_1_UNNORM_THRESHOLD.
+ * mpn/generic/mod_1.c: Partial rewrite, skip a divide step in more
+ cases, introduce MOD_1_NORM_THRESHOLD, MOD_1_UNNORM_THRESHOLD.
+ * longlong.h (UDIV_PREINV_ALWAYS): New define, set for alpha and ia64.
+ * tune/tuneup.c (DIVREM_1_NORM_THRESHOLD, DIVREM_1_UNNORM_THRESHOLD,
+ MOD_1_NORM_THRESHOLD, MOD_1_UNNORM_THRESHOLD): Tune these.
+ * gmp-impl.h [TUNE_PROGRAM_BUILD]: Support for this.
+ * tune/Makefile.am (TUNE_MPN_SRCS): Add divrem_1.c and mod_1.c.
+
+ * gmp-impl.h (UDIV_NORM_PREINV_TIME): Renamed from UDIV_PREINV_TIME.
+ * mpn/generic/perfsqr.c, mpn/generic/sb_divrem_mn.c,
+ mpn/x86/*/gmp-mparam.h: Ditto.
+ * gmp-impl.h (UDIV_UNNORM_PREINV_TIME): New define.
+
+ * configure.in (AC_C_INLINE, HAVE_INLINE): New test and define.
+ * gmp-impl.h (inline): Remove, use config.h.
+ (_EXTERN_INLINE): Redefine based on HAVE_INLINE.
+ (mpn_zero_p): Use HAVE_INLINE.
+
+ * acinclude.m4 (GMP_PROG_AR, GMP_PROG_NM): Don't add flags to a user
+ selected $AR or $NM.
+
+ * tune/tuneup.c (all): Print how long the tuning took.
+
+ * configure.in (AM_C_PROTOTYPES): Use this, not GMP_ANSI2KNR.
+ * acinclude.m4 (GMP_ANSI2KNR): Remove.
+
+ * Makefile.am (gmp.h, mp.h): In DISTCLEANFILES not CLEANFILES.
+
+ * gmp-h.in (mpn_divmod, mpn_divmod_1, mpn_divexact_by3): Cast some
+ zeros, for the benefit of K&R if long!=int.
+
+ * mpn/lisp/gmpasm-mode.el (gmpasm-comment-start-regexp): Add "*" for
+ the benefit of cray.
+
+ * compat.c (mpn_divexact_by3, mpn_divmod_1): Return types should be
+ mp_limb_t, not int, and need an actual "return".
+
+2000-12-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v8/supersparc/gmp-mparam.h: Retune.
+ * mpn/alpha/gmp-mparam.h: Tune for 21064.
+
+ * longlong.h: Reformat to avoid newlines within strings.
+
+ * gmp-impl.h (inline): Disable if GCC has defined __STRICT_ANSI__.
+
+ * configure.in: Do a `mkdir tune' before creating tune/sqr_basecase.c.
+
+ * Makefile.am: Treat mp.h analogously to gmp.h.
+
+ configure.in (*-*-aix): Pass -qmaxmem=20000 to xlc.
+
+ * mp-h.in: Renamed from mp.h.
+ Add #define for _LONG_LONG_LIMB.
+ Move some other fixes from gmp-h.in.
+ * mp.h: Removed.
+ * configure.in: Generate mp.h from mp-h.in like we handle
+ gmp-h.in/gmp.h.
+
+2000-12-04 Torbjorn Granlund <tege@swox.com>
+
+ * acinclude.m4: Fix typo testing for bad HP compiler.
+
+2000-12-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpbsd/tests/t-misc.c (check_itom): Exclude some tests for Cray
+ CFP systems.
+
+ * longlong.h (CRAYIEEE umul_ppmm): New.
+
+ * mpn/cray/gmp-mparam.h (BITS_PER_SHORTINT): 32 => 64.
+ (*_THRESHOLD): Tune.
+
+ * configure.in: Disable shared libs for *-*-unicos*.
+
+2000-12-03 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, tune/Makefile.am: Create tune/sqr_basecase.c during
+ configure, and use it unconditionally in $(nodist_tuneup_SOURCES).
+ Fixes a problem with sqr_basecase.lo under --disable-static.
+
+2000-12-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/tests/t-get_d.c (LOW_BOUND,HIGH_BOUND): #define for non-IEEE
+ Cray systems.
+
+ * gmp-impl.h (union ieee_double_extract): Test for _CRAYIEEE.
+
+2000-11-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/t-mul.c (base_mul): Fix re-evaluation problems in macro
+ invocations.
+ (ref_mpz_mul): New name from mpz_refmul. Make static.
+ (base_mul): New name for _mpn_mul_classic.
+
+2000-11-30 Kevin Ryde <kevin@swox.se>
+
+ * configure.in: Rewrite of CC/CFLAGS selection scheme, introduce a
+ notion of ABI, merge compiler and mpn path selection, add flags
+ selection for AR and NM, let CC without CFLAGS work.
+ (AC_PROG_CC): Use this, not GMP_SELECT_CC.
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Don't use AC_TRY_COMPILE, combine
+ cc/cflags parameter.
+ (GMP_PROG_CC_FIND, GMP_CHECK_CC_64BIT, GMP_PROG_CC_SELECT): Remove.
+ * gmp.texi (Installing GMP): Updates for new scheme.
+
+ * configure.in (AC_CANONICAL_HOST): Use this and $host, not $target.
+ * acinclude.m4, acconfig.h, longlong.h, mpn/x86/x86-defs.m4,
+ mpn/x86/k7/mmx/popham.asm: Ditto, renaming HAVE_TARGET_CPU to
+ HAVE_HOST_CPU.
+ * gmp.texi (Build Options, and elsewhere): Update.
+
+ * acinclude.m4 (GMP_COMPARE_GE): New macro.
+ (GMP_GCC_MARCH_PENTIUMPRO): Use it, add CC parameter, check for GCC.
+ (GMP_HPC_HPPA_2_0): New macro, adapted from GMP_CHECK_CC_64BIT.
+
+ * acinclude.m4 (GMP_PROG_AR): New macro, using AC_CHECK_TOOL, adding
+ GMP flags.
+ * configure.in: Use it
+
+ * gmp-h.in: Renamed from gmp.h.
+ (@define_LONG_LONG_LIMB@): Placeholder for instantiation.
+ (__GNU_MP__): Bump to 3.
+ * acinclude.m4 (GMP_VERSION): Get version from gmp-h.in.
+ * configure.in: Create gmp.h from gmp-h.in to set _LONG_LONG_LIMB.
+ * gmp.texi.h (ABI and ISA): Mention this.
+ * acconfig.h (_LONG_LONG_LIMB): Remove undef.
+ * Makefile.am: Distribute gmp-h.in, not gmp.h.
+
+ * configure.in (AC_PROG_CPP, AC_PROG_INSTALL, AC_PROG_LN_S): Remove,
+ dragged in by other macros.
+ (gmp_asm_syntax_testing): Renamed from gmp_no_asm_syntax_testing.
+ (AC_EXEEXT, AC_OBJEXT): Remove, done automatically by libtool.
+ * configure.in, acinclude.m4: Remove "" from "`foo`", being
+ unnecessary and not portable.
+
+ * configure.in (GMP_LDFLAGS): New AC_SUBST flags for libtool link.
+ (powerpc64*-*-aix*): Use for -Wc,-maix to fix shared library creation,
+ but can't build shared and static at the same time.
+ * Makefile.am (libgmp_la_LDFLAGS, libmp_la_LDFLAGS): Use
+ $(GMP_LDFLAGS).
+ * gmp.texi (Notes for Particular Systems): Update AIX problem
+
+ * configure.in (AC_CONFIG_LINKS): Use where needed, not via gmp_links.
+ (gmp_srclinks): Build up as needed, not via gmp_links.
+
+ * acinclude.m4 (GMP_INIT): Do CONFIG_TOP_SRCDIR and asm-defs.m4 here.
+ * configure.in (asm-defs.m4): Consequent changes.
+
+ * acinclude.m4 (GMP_INCLUDE_MPN): Using include_mpn(), replacing
+ GMP_INCLUDE and GMP_SINCLUDE.
+ * configure.in (gmp_m4postinc): Remove this scheme, use
+ GMP_INCLUDE_MPN instead.
+
+ * configure.in (*-*-sco3.2v5*): Force ac_cv_archive_cmds_need_lc=no,
+ until libtool does this itself.
+ * gmp.texi (Known Build Problems): Remove SCO -lc problem.
+
+ * configure, INSTALL.autoconf, etc: Update to autoconf 2000-11-29.
+ * acinclude.m4 (GMP_C_SIZES): Use AC_CHECK_SIZEOF.
+ * gmp.texi (Known Build Problems): Remove version.c sed/config.h
+ problem, fixed.
+
+ * ltmain.sh, aclocal.m4: Update to libtool 2000-11-25.
+ * ltconfig: No longer required, but leave an empty dummy for automake.
+ * gmp.texi (Known Build Problems): Remove SunOS native ar ranlib
+ problem, fixed.
+
+ * */Makefile.in, aclocal.m4: Update to automake 2000-11-25.
+ * mpbsd/tests/Makefile.am, mpfr/tests/Makefile.am (check_PROGRAMS):
+ Remove dummy, no longer required.
+ * mpbsd/tests/dummy.c, mpfr/tests/dummy.c: Remove files.
+ * depcomp: Remove file, no longer required (with no-dependencies).
+
+ * texinfo.tex: Update to 2000-11-09.
+ * gmp.texi (Build Options): Mention PDF from gmp.texi.
+ * Makefile.am (MOSTLYCLEANFILES): Add gmp.tmp, from new texinfo.tex.
+
+ * gmp.texi (Build Options): List alphaev56, alphapca56, alphaev67,
+ hppa2.0n and power among supported CPUs.
+
+2000-11-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/t-mul.c: Increase max operand size from 2^17 bits
+ to 2^19 bits. Misc cleanups.
+
+2000-11-26 Kevin Ryde <kevin@swox.se>
+
+ * tune/tuneup.c (FIB_THRESHOLD): Cope better with different speeds of
+ odd and even sizes.
+
+ * longlong.h (alpha): Use udiv_qrnnd and count_leading_zeros on all
+ compilers, not just gcc.
+
+ * pre_mod_1.c: Use conditional subtract to always skip a division.
+ (UMUL_TIME, UDIV_TIME): Remove defaults, now in longlong.h.
+
+2000-11-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64w/gmp-mparam.h: Retune.
+ * mpn/pa64/gmp-mparam.h: Retune.
+ * mpn/sparc64/gmp-mparam.h: Retune.
+
+2000-11-22 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (ABOVE_THRESHOLD, BELOW_THRESHOLD): New macros.
+ * mpn/generic/gcdext.c: Use them.
+
+ * mpn/generic/gcdext.c [WANT_GCDEXT_ONE_STEP]: Force only one step.
+ * tune/gcdextos.c, tune/gcdextod.c: New files, one step gcdext, single
+ and double.
+ * tune/Makefile.am (libspeed_la_SOURCES): Add them.
+ (TUNE_MPN_SRCS): Remove gcdext.c.
+ * tune/speed.h, tune/common.c, tune/speed.c: Add measuring.
+ * tune/tuneup.c: Use for GCDEXT_THRESHOLD, plus check if double limb
+ is ever better. Should be more accurate, and hopefully faster.
+
+ * tune/gcdext_single.c: New file, gcdext forced to single limbs.
+ * tune/Makefile.am: Add it.
+ * tune/speed.h, tune/common.c, tune/speed.c: Add measuring, and of
+ invert_limb.
+
+ * tune/speed.h (speed_params r): Use mp_limb_t, not long.
+ * tune/speed.h, tune/common.c: Don't "switch" on "r".
+ * tune/speed.c (r_string): Accept limb sized constants.
+ (choice scale): Add a scale factor (eg. "2.33*mpn_add_n").
+ * tune/common.c (SPEED_ROUTINE_UDIV_QRNND_A): Default r to
+ __mp_bases[10].big_base, being a full limb value.
+
+ * configure.in (alphapca56*-*-*): Use ev5 mpn path.
+ (am29000*-*-*): Remove this, leave the canonical a29k.
+ (z8k*-*-*, z8kx*-*-*): Changed from z8000, since z8k is canonical.
+ (gmp_mpn_functions_optional): Add invert_limb, use for alpha and ia64.
+
+ * configure.in (alloca): Accept yes/no/detect, generate an error if
+ "yes" but not available.
+ * gmp.texi (Build Options): Update.
+
+ * acinclude.m4 (GMP_TRY_ASSEMBLE): Make conftest.out available.
+ (GMP_ASM_ALIGN_FILL_0x90): Use it.
+
+ * acinclude.m4 (GMP_ASM_X86_MMX) [*-*-solaris*]: Check for solaris
+ 2.6 "as" movq bug.
+ * gmp.texi (Notes for Particular Systems): Update x86 MMX note.
+
+2000-11-21 Torbjorn Granlund <tege@swox.com>
+
+ * tune/Makefile.am (EXTRA_DIST): List hppa2w.asm.
+
+ * tune/hppa2.asm: Change level directive to "2.0n".
+ * tune/hppa2w.asm: New file.
+ * configure.in [SPEED_CYCLECOUNTER_OBJS switch]: Separate out hppa2.0w.
+
+ * mpn/pa64/gmp-mparam.h (BITS_PER_LONGINT): 64 => 32.
+
+2000-11-21 Kevin Ryde <kevin@swox.se>
+
+ * urandom.h (random): No prototype if glibc stdlib.h has already
+ provided it (avoids an int32_t/long conflict).
+
+ * tune/Makefile.am (LDFLAGS): Use -all-static.
+ (speed-dynamic): Dynamic linked version of speed.c.
+ * tune/README: Update.
+
+ * mpn/generic/gcd.c (find_a): Use native version if available.
+ * acconfig.h (HAVE_NATIVE_mpn_gcd_finda): Add #undef.
+ * gmp-impl.h (mpn_gcd_finda): Add prototype and define.
+ * mpn/asm-defs.m4 (mpn_gcd_finda): New define_mpn.
+ * tune/gcd_finda_gen.c: #undef any HAVE_NATIVE_mpn_gcd_finda.
+ * configure.in (gmp_mpn_functions_optional): Add gcd_finda.
+ * mpn/x86/k6/gcd_finda.asm: New file.
+
+ * tune/tuneup.c (POWM_THRESHOLD): Slightly bigger size steps.
+
+ * gmp-impl.h (__GMP_IMPL_H__): Protect against multiple inclusion.
+ * tune/gcd_bin.c, tune/powm_mod.c, tune/powm_redc.c: Use #undef after
+ gmp-impl.h to force thresholds.
+ * tune/tuneup.c (print_define, fft): No need for #ifndefs on
+ thresholds any more.
+
+2000-11-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/t-powm.c: Analogous changes as made 2000-11-12 to t-mul.c.
+ * mpz/tests/t-powm_ui.c: Likewise.
+ * mpz/tests/t-pow_ui.c: Likewise.
+ * mpz/tests/t-root.c: Likewise.
+
+ * configure.in [compiler switch]: Pass "-Aa -D_HPUX_SOURCE" to cc for
+ all hppa versions.
+
+ * mpn/hppa/hppa1_1/udiv_qrnnd.S: Reference data using PC relative
+ addressing (was r19 relative addressing).
+
+2000-11-18 Torbjorn Granlund <tege@swox.com>
+
+ * rand.c: (__gmp_rand_lc_scheme): Convert strings to hexadecimal.
+ (gmp_randinit): Expect strings in hexadecimal.
+
+2000-11-18 Kevin Ryde <kevin@swox.se>
+
+ * configfsf.guess, configfsf.sub: Update to 2000-11-16.
+ * config.guess (alpha*-*-openbsd*): Do exact cpu detection.
+
+2000-11-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/t-fdiv.c: Analogous changes as made 2000-11-12 to t-mul.c.
+ * mpz/tests/t-tdiv_ui.c: Likewise.
+ * mpz/tests/t-fdiv_ui.c: Likewise.
+ * mpz/tests/t-sqrtrem.c: Likewise.
+ * mpz/tests/t-gcd.c: Likewise.
+
+2000-11-13 Kevin Ryde <kevin@swox.se>
+
+ * mpn/Makeasm.am: New file, splitting out assembler rules.
+ * mpn/Makefile.am, tune/Makefile.am: Use it.
+
+ * mpn/Makefile.am (@CPP@): Remove this, automake already gives it.
+
+ * configure.in (AC_CHECK_LIBM): New test, and AC_SUBST it.
+ * Makefile.am (MPFR_LIBADD_OPTION): Use it.
+ * demos/Makefile.am (qcn_LDADD): Ditto.
+ * tune/Makefile.am (libspeed_la_LIBADD): Ditto.
+ * tests/rand/Makefile.am (libstat_la_LIBADD): Ditto.
+
+ * tune/time.c (timeval_diff_secs): Better calculation.
+ (read_real_time): New measuring method for AIX power/powerpc.
+ (speed_endtime): Protect against negative times.
+ * tune/common.c (speed_measure): Protect against big reps.
+ * tune/freq.c (speed_cpu_frequency_measure_one): Better timeval diff.
+ * tune/speed.h (TIMEVAL_DIFF_SEC,USEC): Remove macros.
+ * configure.in: (sys/systemcfg.h, read_real_time): New tests.
+
+2000-11-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/t-mul.c: Remove #include urandom.h.
+ * mpz/tests/t-tdiv.c: Likewise.
+
+ * configure.in [SPEED_CYCLECOUNTER_OBJS switch]:
+ Declare hppa.asm as just 32 bits (cyclecounter_size=1).
+
+2000-11-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/t-mul.c
+ (main): Generate random numbers using gmp_rand* functions.
+ (main): Distribute random numbers non-uniformly.
+ (main): Seed by current time if GMP_CHECK_RANDOMIZE is set.
+ (_mpn_mul_classic): Streamline.
+ * mpz/tests/t-tdiv.c: Analogous changes.
+
+ * demos/pexpr.c (HAVE_sigaltstack): Fix typo in testing for _UNICOS.
+ Also test for __hpux.
+
+2000-11-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev5/gmp-mparam.h: Retune.
+
+ * mpn/alpha/ev6/gmp-mparam.h: Retune.
+
+ * mpn/alpha/ev6/add_n.asm: Misc cleanups.
+
+ * mpn/alpha/ev6/sub_n.asm: New file.
+
+2000-11-10 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in [path switch] (alphaev6*-*-*): Add alpha/ev5 to path.
+
+ * mpn/alpha/ev6/add_n.asm: New file.
+
+2000-11-10 Kevin Ryde <kevin@swox.se>
+
+ * mpz/powm.c (redc): Make global under WANT_REDC_GLOBAL.
+ * tune/powm_mod.c, tune/powm_redc.c: New files.
+ * tune/Makefile.am (libspeed_la_SOURCES): Add them.
+ * tune/*: Add measuring of redc, mpz_mod, mpz_powm_mod, mpz_powm_redc.
+
+ * tune/tuneup.c (POWM_THRESHOLD): Determine from redc and mpz_mod.
+ * tune/Makefile.am (TUNE_MPZ_SRCS): Remove powm.
+
+2000-11-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/mips3/gmp-mparam.h: Retune.
+
+ * configure.in (os_64bit): Rename to check_64bit_compiler.
+
+2000-11-09 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in [SPEED_CYCLECOUNTER_OBJS switch]: Choose hppa/hppa2 code
+ depending on $CC64.
+
+2000-11-09 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/mul_1.asm: Unroll 2x, saving 1 c/l when in L1.
+ Add 1c entrypoint.
+ * mpn/x86/pentium/aorsmul_1.asm: Add 1c entrypoints, shave a couple
+ of cycles at entry and exit.
+
+ * configure.in (power1,2,2sc): Support these as synonyms for plain
+ power.
+
+ * acinclude.m4 (GMP_ASM_X86_SHLDL_CL): GMP_DEFINE WANT_SHLDL_CL here.
+ (GMP_ASM_X86_MMX, GMP_ASM_X86_SHLDL_CL): Add X86 into the names.
+ * configure.in: Consequent changes.
+
+ * gmp.texi (Notes for Particular Systems): Remarks about power/powerpc.
+ (Reentrancy): Remarks about simultaneous writing.
+ (Reporting Bugs): Ask for configfsf.guess.
+
+2000-11-08 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_FUNC_ALLOCA): New macro.
+ * configure.in: Use it.
+ * gmp-impl.h (alloca): Conditionals and setups as per autoconf
+ (should make alloca available on more non-gcc compilers).
+
+ * acinclude.m4: Misc reformatting, simplify some quoting.
+ (GMP_ASM_UNDERSCORE, GMP_ASM_X86_MCOUNT): Use $CC $CFLAGS $CPPFLAGS.
+ (GMP_ASM_UNDERSCORE, GMP_ASM_ALIGN_FILL_0x90, GMP_ASM_RODATA): Put
+ AC_REQUIREs outside AC_CACHE_CHECK.
+ (GMP_C_SIZES): Use $srcdir/gmp.h, not -I; use $CPPFLAGS.
+ (GMP_ASM_UNDERSCORE): Use "gmp_compile" variable, and only rm
+ conftes1* conftes2*.
+ (GMP_PROG_NM): New macro, require it in appropriate GMP_ASM_*.
+ (GMP_TRY_ASSEMBLE): New macro, use it in various GMP_ASM_*.
+ * configure.in: Use GMP_PROG_NM.
+
+ * mpn/tests/spinner.c (spinner_signal): Use RETSIGTYPE.
+ (spinner_init): Force output to unbuffered.
+
+ * mpn/x86/README.family: Notes about GOT table and imul, misc updates.
+ * mpn/x86/k7/diveby3.asm: Change to 3 operands for immediate imul.
+ * mpn/x86/k6/diveby3.asm: Ditto.
+
+2000-11-06 Torbjorn Granlund <tege@swox.com>
+
+ * urandom.h: Simplify and make it work properly for 64-bit
+ machines also in environments without `random'.
+
+2000-11-04 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in [path switch]: Don't match rs6000-*-*, in
+ particular don't assume POWER.
+
+ * tune/tuneup.c (fft): Remove usleep calls.
+
+ * config.guess: Don't pass "$@" when it is known to be empty.
+
+ * Makefile.am (EXTRA_DIST): List configfsf.guess and configfsf.sub.
+
+2000-11-04 Kevin Ryde <kevin@swox.se>
+
+ * configfsf.guess, configfsf.sub: Moved from config.guess and
+ config.sub.
+ * config.guess, config.sub: New files, wrappers around around
+ configfsf versions.
+ * configfsf.guess: Update to FSF 2000-10-23.
+ * configfsf.sub: Update to FSF 2000-10-25.
+
+ * acinclude.m4 (GMP_ASM_POWERPC_R_REGISTERS): New macro.
+ * mpn/powerpc32/powerpc-defs.m4: New file, regmap.m4 r0 etc macros
+ conditionalized by GMP_ASM_POWERPC_R_REGISTERS.
+ * mpn/powerpc32/regmap.m4: Remove file.
+ * configure.in (powerpc*-*-*): Use all this.
+
+ * mpz/divegcd.c: New file, providing mpz_divexact_gcd.
+ * Makefile.am, mpz/Makefile.am: Add it.
+ * gmp-impl.h (mpz_divexact_gcd): Add prototype.
+ * mpq/aors.c,canonicalize.c,div.c,mul.c: Use it.
+
+ * longlong.h [pentium] (count_leading_zeros): New macro.
+ (__clz_tab): Always provide prototype.
+ * acconfig.h (HAVE_TARGET_CPU_): Add x86s.
+
+ * tune/speed.[ch],common.c (count_leading_zeros,
+ count_trailing_zeros, __udiv_qrnnd_c): Add measuring.
+
+ * configure.in (X86_PATTERN): Move from here ...
+ * acinclude.m4 (X86_PATTERN): ... to here.
+ (GMP_ASM_RODATA): Use it.
+
+ * configure.in (srandom): New test.
+ * mpn/tests/try.c: Use it.
+ * tune/speed.c: Ditto, and conditionalize getrusage and headers.
+
+2000-11-02 Kevin Ryde <kevin@swox.se>
+
+ * mpn/Makefile.am (nodist_libdummy_la_SOURCES): Add udiv_qrnnd.c
+ and udiv_w_sdiv.c.
+
+ * mpn/generic/mul_n.c (mpn_kara_sqr_n): Remove a duplicate
+ subtract at the evaluate stage.
+
+2000-11-01 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in [compiler switch] (sparc64-*-linux*): Spell
+ gmp_xoptcflags_gcc properly, and pass same options as for other
+ sparcv9 configs.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_GET_STR): Fix type of wsize.
+
+2000-10-31 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in [compiler switch] (sparc64-*-linux*): Remove -mvis
+ from gmp_xoptflags_gcc, this might not be an ultrasparc.
+ Remove -m32 from gmp_cflags_gcc; add -Wa,-xarch=v8plus.
+
+2000-10-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/lorrshift.asm: New file.
+
+ * configure.in: New mulfunc `lorrshift' for lshift and rshift.
+
+2000-10-29 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/mul_n.c (mpn_kara_sqr_n): Delete code performing
+ superfluous mpn_sub_n calls.
+
+ * configure.in (found_asm, M4): Account for SPEED_CYCLECOUNTER_OBJ,
+ for the benefit of targets whose only .asm is a cycle counter.
+
+ * tune/tuneup.c (fft): Remove bogus usleep calls.
+
+2000-10-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/invert_limb.asm: Get return value for 0x800...00 right.
+
+ * tune/Makefile.am (EXTRA_DIST): Add ia64.asm.
+
+ * tune/ia64.asm: Fix typo.
+
+ * add_n.asm addmul_1.asm mul_1.asm popcount.asm sub_n.asm:
+ Preserve ar.lc as required by ABI.
+ * longlong.h (ia64 udiv_qrnnd): New.
+
+ * configure.in [path switch] (ia64*-*-*): Set extra_functions.
+ * mpn/ia64/invert_limb.asm: New file.
+
+2000-10-27 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in [compiler switch]:
+ Get rid of c89 for all hppa flavours--it is an evil compiler!
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_SET_STR): Fix type of xp.
+ (SPEED_ROUTINE_MPN_GET_STR): Fix type of wp.
+
+2000-10-27 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Fibonacci Number Algorithm): New section.
+
+ * mpz/tests/t-fib_ui.c: New file.
+ * mpz/tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpz/fib_ui.c: Rewrite, same formulas but using mpn functions and
+ some lookup tables, much faster at small to moderate sizes.
+ * gmp-impl.h (MPZ_FIB_SIZE): New macro.
+ (FIB_THRESHOLD): Establish default here.
+ * tune/tuneup.c (FIB_THRESHOLD): Start search after the new table
+ data.
+
+ * mpn/x86/x86-defs.m4 (mcount_movl_GOT_ebx): Rename from movl_GOT_ebx,
+ and don't use GSYM_PREFIX with _GLOBAL_OFFSET_TABLE_.
+
+ * tune/freq.c (speed_cpu_frequency_measure): New test comparing
+ gettimeofday and speed_cyclecounter, should cover many systems.
+
+2000-10-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/gmp-mparam.h: Retune.
+
+2000-10-26 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (ia64): Set UMUL_TIME and UDIV_TIME.
+
+ * mpn/ia64/submul_1.c: Fix typo.
+
+2000-10-25 Kevin Ryde <kevin@swox.se>
+
+ * tune/freq.c (speed_cpu_frequency_sysctl): New test, supporting
+ hw.model for BSD flavours.
+ * configure.in (sysctl, sys/param.h): New tests.
+
+2000-10-24 Torbjorn Granlund <tege@swox.com>
+
+ * tune/freq.c: Explicitly #include config.h before other include files.
+
+ * mpz/tests/reuse.c (FAIL2): New #define.
+ (main): Use FAIL2. Now this test properly returns non-zero exit
+ status when it fails.
+
+ * mpn/powerpc32/gmp-mparam.h: Retune.
+ * mpn/powerpc64/gmp-mparam.h: Retune.
+
+2000-10-24 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k6/cross.pl: Support 8 and 16 byte code alignment.
+
+ * mpq/aors.c, mpq/canonicalize.c: Skip two mpz_divexact calls if
+ gcd gives 1, which should be 60% of the time.
+ * gmp-impl.h (MPZ_EQUAL_1_P): New macro.
+ * mpq/mul.c, mpq/div.c: Use it, and a new DIV_OR_SET.
+
+ * tune/tuneup.c (xp_block, yp_block): Initialize these with random
+ data. Fixes GCD_ACCEL and GCDEXT thresholds, and latest POWM.
+
+2000-10-23 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in [SPEED_CYCLECOUNTER_OBJS switch]: Add ia64 case.
+
+ * mpn/ia64/gmp-mparam.h: Fill in some parameters.
+
+ * mpn/ia64/submul_1.c: New file.
+
+ * tune/ia64.asm: New file.
+
+ * gmp-impl.h (union ieee_double_extract): Handle ia64.
+
+ * mpn/mp_bases.c: Decrease chars_per_bit_exactly for entry 1 to
+ work around buggy ia64-linux.
+
+ * longlong.h (ia64 umul_ppmm): Update register flags to match new GCC.
+
+2000-10-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/gmp-mparam.h (DC_THRESHOLD): Update.
+ * mpn/alpha/ev6/submul_1.asm: New file.
+
+2000-10-22 Kevin Ryde <kevin@swox.se>
+
+ * tune/gcd_bin.c: New file.
+ * tune/gcd_finda_gen.c: New file.
+ * tune/Makefile.am (libspeed_la_SOURCES): Add them.
+ * tune/speed.[ch],common.c (mpn_gcd_binary, find_a): Add measuring.
+
+ * * (__gmp_allocate_func etc): Rename from _mp_allocate_func etc.
+ (__gmp_default_allocate etc): Rename from _mp_default_allocate etc.
+ * gmp-impl.h (__GMP_REALLOCATE_FUNC_TYPE,
+ __GMP_REALLOCATE_FUNC_LIMBS): New macros.
+
+ * gmp-impl.h (DC_THRESHOLD): Establish default here, set to 3*KARA
+ since that's the measured average.
+ * mpn/generic/dc_divrem_n.c, mpn/generic/tdiv_qr.c (DC_THRESHOLD):
+ Remove default.
+
+2000-10-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/Makefile.am (TARG_DIST): Add ia64.
+
+2000-10-21 Kevin Ryde <kevin@swox.se>
+
+ * *: Change BZ -> DC.
+ * mpn/generic/dc_divrem_n.c: Renamed from bz_divrem_n.c.
+
+ * doc/multiplication: Remove file, now in the manual.
+ * doc/assembly_code: Ditto.
+ * tune/README: Remove some parts now in the manual.
+
+ * gmp.texi (@m etc): Add and use some new macros.
+ (Integer Division - mpz_[cft]div_*): Merge descriptions, for brevity
+ and to emphasise similarities.
+ (Low-Level Functions - mpn_[lr]shift): Specify count as 1 to
+ mp_bits_per_limb-1.
+ (Algorithms): New chapter.
+ (References): Add some papers.
+
+ * mpn/generic/mul_n.c (mpn_toom3_mul_n, mpn_toom3_sqr_n): Remove some
+ unused variables.
+ * mpn/generic/mul_fft.c (mpn_fft_best_k): Ditto.
+
+ * tune/freq.c: New file, split from time.c.
+ * tune/time.c: Rewrite, now more automated.
+ * configure.in, tune/*: Consequent changes.
+
+2000-10-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/default.m4: New file.
+ * configure.in [config.m4 switch] (ia64*-*-*): Use ia64/default.m4.
+
+ * mpn/ia64/mul_1.asm: New file.
+ * mpn/ia64/addmul_1.asm: New file.
+ * mpn/ia64/add_n.asm: New file.
+ * mpn/ia64/sub_n.asm: New file.
+ * mpn/ia64/popcount.asm: New file.
+ * mpn/ia64/README: New file.
+
+ * mpn/alpha/cntlz.asm: Override `.set noat' from ASM_START.
+
+ * configure.in (HAVE_TARGET_CPU_*): Support hppa1.0, hppa1.1, hppa2.0
+ by sed'ing the period into `_'.
+
+ * acconfig.h: Add #undefs for hppa targets.
+
+ * longlong.h (udiv_qrnnd): Fix typo in last change.
+
+ * mpz/tstbit.c: Rewrite (partly to work around GCC 2.95.2 HPPA bug).
+
+ * configure.in [path switch]:
+ (hppa2.0*-*-*): For non-CC64 case, update path.
+
+ * configure.in [compiler switch]:
+ (hppa2.0w-*-*): Match with same regexp in both places.
+ (hppa*-*-*): New case.
+ (all hppa alternatives): Don't inherit default gmp_cflags_cc,
+ gmp_cflags_c89.
+
+2000-10-18 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (alpha*-*-*): Define gmp_xoptcflags_gcc like for
+ alpha*-*-osf*.
+
+ * longlong.h (x86 udiv_qrnnd): Change `d' => `dx' to avoid K&R C
+ stringification.
+
+2000-10-15 Kevin Ryde <kevin@swox.se>
+
+ * doc/configuration: Updates.
+
+ * demos/calc.y: Remove some comments.
+
+2000-10-14 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Parameter Conventions, Memory Management): New sections
+ split from "Variable Conventions".
+ (Efficiency, Debugging, Profiling): New sections in "GMP Basics".
+ (Reentrancy): Some rewording, add note on standard I/O.
+ (Build options): Add --enable-assert and --enable-profiling.
+
+ * configure.in (--enable-profiling): New option.
+ * acinclude.m4 (GMP_ASM_X86_MCOUNT): New macro, finding how to profile.
+ * mpn/x86/x86-defs.m4 (PROLOGUE_cpu, call_mcount): Profiling support.
+
+ * acinclude.m4, configure.in (GMP_ASM_*): Rename from GMP_CHECK_ASM_*,
+ to follow autoconf conventions.
+
+ * configure.in: Run GMP_CHECK_ASM tests only if needed.
+ * acinclude.m4 (GMP_CHECK_ASM_MMX): Don't use GMP_CHECK_ASM_TEXT.
+
+ * mpn/x86/x86-defs.m4 (ASSERT): Allow no condition, to just emit code.
+
+2000-10-13 Kevin Ryde <kevin@swox.se>
+
+ * mpq/md_2exp.c: New file.
+ * mpq/Makefile.am (libmpq_la_SOURCES): Add it.
+ * Makefile.am (MPQ_OBJECTS): Ditto.
+ * gmp.h (mpq_mul_2exp, mpq_div_2exp): Add prototypes.
+ * gmp.texi (Rational Arithmetic): Add documentation.
+
+ * mpq/tests/t-md_2exp.c: New file.
+ * mpq/tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpn/generic/perfsqr.c: Add/amend some comments.
+
+ * gmp.texi (Known Build Problems): Note VERSION problem with old
+ sed, do some minor rewording.
+ (Build Options): Add cygwin and djgpp URLs, mention INSTALL.autoconf,
+ mention HTML.
+ (Getting the Latest Version of GMP): Move this ...
+ (Introduction to GMP): ... to here.
+ (Compatibility with older versions): Just refer to 2.x and 3.x, not
+ every minor version.
+ (Initializing Integers): Note restrictions on mpz_array_init'ed
+ variables.
+ (Integer Logic and Bit Fiddling): Note bits are numbered from 0.
+
+ * INSTALL.autoconf: New file.
+ * Makefile.am (EXTRA_DIST): Add it.
+
+ * tune/Makefile.am, tune/tuneup.c, configure.in, gmp-impl.h: New
+ scheme for recompiled objects used by tune program. Don't use
+ libgmptune.a, make better use of libtool, work with ansi2knr.
+
+ * tune/speed.h,common.c (SPEED_ROUTINE_MPZ_POWM): Use s->yp and
+ s->xp_block, make exponent a fixed size.
+
+2000-10-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/mips3/gmp-mparam.h: Retune.
+
+ * mpn/generic/mul_n.c (USE_MORE_MPN): Revert last change.
+
+2000-10-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/mips3/add_n.s: Decrease carry recurrence from 4 to 3 cycles.
+ * mpn/mips3/sub_n.s: Likewise.
+
+2000-10-04 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (sparc64-*-linux*): Set path according to CC64.
+
+2000-10-04 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_ASM_UNDERSCORE): Use LABEL_SUFFIX, not a
+ hard-coded ":".
+
+ * config.sub: Don't demand "86" in CPU name for SCO.
+
+ * configure.in (supersparc-*-*): Remove -DSUPERSPARC.
+ * longlong.h: Use HAVE_TARGET_CPU_supersparc.
+
+ * configure.in (HAVE_TARGET_CPU_*): AC_DEFINE from $target_cpu.
+ * acconfig.h: Add #undefs, but only for targets of interest.
+
+2000-10-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/cntlz.asm: Rewrite.
+
+ * mp_clz_tab.c (__clz_tab): Half table size to 128 entires.
+ * longlong.h (count_leading_zeros): Demand just 128 entries from
+ __clz_tab.
+
+ * configure.in (mips-sgi-irix6.*): Pass -mips3 in addition to options
+ for n32 ABI.
+
+ * longlong.h: Move NO_ASM test around all assembly code.
+ From gcc:
+ * longlong.h (count_leading_zeros): Sparclite scan instruction was
+ being invoked incorrectly.
+ Replace __mc68332__ with __mcpu32__.
+ Add ARC support.
+
+2000-10-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/mips3/gmp-mparam.h: Retune for both gcc and cc.
+
+ * mpn/generic/mul_n.c (USE_MORE_MPN): Remove exception for __mips.
+ (interpolate3): Cast mp_limb_t variables to mp_limb_signed_t
+ when testing sign bit.
+
+ * mpn/alpha/ev6/gmp-mparam.h: Retune.
+ * mpn/powerpc32/gmp-mparam.h: Retune.
+ * mpn/powerpc64/gmp-mparam.h: Retune.
+ * mpn/x86/pentium/gmp-mparam.h: Retune.
+ * mpn/x86/pentium/mmx/gmp-mparam.h: Retune.
+ * mpn/sparc32/v9/gmp-mparam.h: Retune.
+ * mpn/x86/k6/gmp-mparam.h: Retune.
+ * mpn/x86/p6/gmp-mparam.h: Retune.
+ * mpn/x86/k7/gmp-mparam.h: Retune.
+ * mpn/sparc64/gmp-mparam.h: Retune.
+
+ * mpn/m68k/gmp-mparam.h: New file.
+ * mpn/alpha/ev5/gmp-mparam.h: New file.
+
+ * gmp-impl.h (default MPN_COPY): Remove final `;'.
+
+ * tune/time.c (speed_endtime): Rewrite.
+
+ * tune/speed.h (SPEED_ROUTINE_MPZ_POWM): Set base to a large value,
+ not 2.
+
+ * demos/pexpr.c (setup_error_handler): Fix typo.
+
+ * mpz/powm.c (redc): New function, based on old mpz_redc. Don't
+ multiply here.
+ (mpz_redc): Remove.
+ (mpz_powm): Major changes, partially reverting to mpn calls.
+ Multiply before calling redc.
+ (mpz_powm): Use TMP_ allocation.
+ (mpz_powm): Refine calculation of k (width of exponent window).
+ (mpz_powm): Cast constants to mp_limb_t before left shifting.
+
+ * longlong.h: Use ia64 count_leading_zeros just when __GNUC__.
+
+2000-09-29 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_C_SIZES): New macro.
+ * configure.in: Use it.
+ * acconfig.in (BYTES_PER_MP_LIMB etc): Add #undefs.
+ * mpn/generic/gmp-mparam.h (BYTES_PER_MP_LIMB etc): Remove #defines.
+ * gmp.texi (Known Build Problems): Remove 64-bit generic C
+ gmp-mparam.h problem, now fixed.
+
+ * configure.in: Only run GMP_PROG_M4 if it's actually needed.
+
+2000-09-27 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c: Clean up code for systems not supporting
+ sigaltstack. Handle old Linux without sigaltstack. Properly
+ disable all stuff related to sigaltstack under Unicos.
+
+ * mpn/alpha/ev6/addmul_1.asm: Use explicit offset for all load and
+ store insns. Helps old gas.
+
+ * longlong.h (count_leading_zeros): Define for ia64.
+
+2000-09-27 Paul Zimmermann <Paul.Zimmermann@loria.fr>
+
+ * mpn/generic/bz_divrem_n.c: Fix qhl handling, simplify.
+
+2000-09-27 Kevin Ryde <kevin@swox.se>
+
+ * mpn/Makefile.in (.SUFFIXES): Regenerate with patched automake to
+ get .s before .c, which is needed to override ansi2knr .c rules.
+
+ * gmp.texi (mpn_sqrtrem): Fix r2p==NULL return value description
+ to match the code (change by Torbjorn).
+ (mpn_gcd, mpn_gcdext, mpn_sqrtrem, mpn_tdiv_qr): Note most
+ significant limbs must be non-zero.
+ (mpn_gcd, mpn_gcdext, mpn_sqrtrem): Clarify destination size
+ requirements.
+ (mpn_gcd_1): Clarify value must be non-zero, not just size.
+
+ * gmp-impl.h (mpn_zero_p): New inline function.
+ * mpn/generic/inlines.c: Add gmp-impl.h.
+ * mpf/integer.c, mpz/get_d.c, mpn/generic/mul_fft.c: Use it.
+
+ * mpn/generic/gcd.c: Use MPN_COPY_INCR not MPN_COPY.
+ * mpf/add_ui.c: Ditto.
+ * mpf/add.c: Ditto, and fix test to skip copy.
+
+2000-09-26 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h, longlong.h, mpn/generic/*.c: Add ASSERTs for various
+ parameter restrictions.
+
+ * gmp-impl.h (UDIV_PREINV_TIME): New macro.
+ * mpn/generic/sb_divrem_mn.c: Use it.
+ * mpn/generic/perfsqr.c: Ditto.
+ * mpn/x86/*/gmp-mparam.h (UDIV_PREINV_TIME): Add values.
+
+ * macos/Makefile.in: Add mpz/tests/t-get_si.c, mpf/tests/t-set_f.c,
+ and new multi-function mpz and mpq files.
+
+2000-09-25 Kevin Ryde <kevin@swox.se>
+
+ * randlc.c, randlc2x.c, randsd.c, mpz/urandomb.c, mpz/urandomm.c:
+ Use mpz_ptr and mpz_srcptr for parameters.
+ * gmp.h (gmp_randinit_lc, gmp_randinit_lc_2exp, gmp_randseed,
+ mpz_urandomb, mpz_urandomm): Corresponding change to prototypes.
+ * randsdui.c: Remove wrong K&R parameters part.
+
+2000-09-12 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (mpn_tdiv_qr): Move prototype from here ...
+ * gmp.h (mpn_tdiv_qr): ... to here.
+
+ * gmp.texi (Miscellaneous Rational Functions): Comment-out and
+ move version 1 compatibility note to "Compatibility" section.
+ (Rational Number Functions): Ditto for canonicalization note.
+
+2000-09-10 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/com_n.asm: New file.
+
+ * gmp.texi (Rational Arithmetic): Add mpq_abs.
+ (Miscellaneous Rational Functions): Merge and simplify descriptions of
+ mpq_get_num, mpq_get_den, mpq_set_num, mpq_set_den.
+
+ * mpq/abs.c: New file.
+ * mpq/Makefile.am (libmpq_la_SOURCES): Add it.
+ * Makefile.am (MPQ_OBJECTS): Add it.
+ * gmp.h (mpq_abs): Add prototype.
+
+ * mpq/set_den.c: Don't discard sign when copying, this makes the
+ code match the manual.
+
+2000-09-07 Torbjorn Granlund <tege@swox.com>
+
+ * tune/alpha.asm: Rewrite to actually work right.
+
+2000-09-07 Kevin Ryde <kevin@swox.se>
+
+ * tune/common.c,speed.[ch]: Add measuring of mpn_sqrtrem,
+ mpn_get_str, mpn_set_str.
+ * tune/README: Various updates.
+
+2000-09-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/fits.c: Correct type of `data'.
+
+2000-09-06 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Build Options): Clarify where to find CFLAGS.
+ (Known Build Problems): Note SCO -lc problem.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_GCD_CALL): Fix for sizes > 512 limbs.
+
+ * doc/multiplication: Corrections and additions suggested by Paul.
+
+ * tune/modlinv.c: New file with alternate modlimb_inverts.
+ * tune/Makefile.am, tune/speed.[ch]: Add measuring of them.
+ * tune/speed.c (FLAG_NODATA): New attribute, use for mpz_bin_uiui,
+ mpz_fib_ui, mpz_fac_ui.
+
+ * mpn/x86/t-zdisp.sh: New file.
+
+ * tests/t-modlinv.c: New file.
+ * tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpq/tests/t-set_f.c: New file.
+ * mpq/tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * gmp-impl.h (MPQ_CHECK_FORMAT): New macro.
+ * mpq/tests/t-get_d.c: Use it.
+
+ * mpq/set_f.c: New file.
+ * mpq/Makefile.am (libmpq_la_SOURCES): Add it.
+ * Makefile.am (MPQ_OBJECTS): Ditto.
+ * gmp.h: Add prototype.
+ * gmp.texi (Miscellaneous Rational Functions): Document mpq_set_f,
+ correct return type of mpq_set_d.
+
+2000-09-03 Kevin Ryde <kevin@swox.se>
+
+ * mpz/aors_ui.c: New file merging add_ui.c and sub_ui.c, no object
+ code changes.
+ * mpz/add_ui.c, mpz/sub_ui.c: Remove files.
+ * mpz/Makefile.am: Update.
+
+ * gmp-impl.h (MPZ_FITS_STYPE_SDT, MPZ_FITS_UTYPE_SDT): New macros.
+ * mpz/fits.c: New file merging six separate fits*.c.
+ * mpz/fits_sshort_p.c, fits_sint_p.c, fits_slong_p.c, fits_ushort_p.c,
+ fits_uint_p.c, fits_ulong_p.c: Remove files
+ * mpz/Makefile.am: Use new fits.c, change object names from
+ fits_*_p.lo to fits_*.lo to avoid SunOS 4 native "ar" warnings.
+ * Makefile.am (MPZ_OBJECTS): Change from fits_*_p.lo to fits_*.lo.
+
+ * acinclude.m4 (GMP_CHECK_ASM_RODATA): New macro, defining RODATA.
+ * configure.in: Use it.
+ * mpn/x86/k[67]/mmx/popham.asm: Use it.
+
+ * mpn/x86/*/*.asm: Use "TEXT" not ".text".
+
+2000-09-02 Kevin Ryde <kevin@swox.se>
+
+ * mpq/aors.c: New file merging add.c and sub.c, no object code changes.
+ * mpq/add.c, mpq/sub.c: Remove files.
+ * mpq/Makefile.am: Update.
+
+ * mpz/aors.c: New file merging add.c and sub.c, no object code changes.
+ * mpz/add.c, mpz/sub.c: Remove files.
+ * mpz/Makefile.am, mpbsd/Makefile.am: Update.
+
+ * configure.in: Re-apply "PROLOGUE.*" regexp change for the
+ benefit of alpha PROLOGUE_GP, lost in path search reorganisation.
+
+ * mpn/x86/x86-defs.m4 (jadcl0, cmov_simulate, ASSERT,
+ movl_text_address): Don't use "1:" style labels.
+ (Zdisp): Rearrange a bit, switch to all hex.
+ * mpn/x86/README.family: Note SCO "as" doesn't support "1:" style
+ local labels, misc rewordings.
+
+2000-08-29 Torbjorn Granlund <tege@swox.com>
+
+ * demos/primes.c: Include string.h.
+
+ * config.guess (x86 variant recog code): Remove dummy*.o files
+ generated by some compilers.
+
+2000-08-28 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_ASM_ALIGN_FILL_0x90): Fix Solaris 2.8
+ warning message suppression, add notes about SCO.
+
+ * Makefile.am (MPZ_OBJECTS etc): Move some comments.
+
+2000-08-25 Kevin Ryde <kevin@swox.se>
+
+ * mpz/pprime_p.c (mpz_millerrabin): Fix a TMP_FREE.
+
+ * gmp.texi (Copying): Refer to Lesser not Library GPL.
+ (GMP and Reentrancy): Note stack-alloc.c is not reentrant, and
+ that SCO <ctype.h> is potentially not reentrant.
+
+ * acinclude.m4 (GMP_CHECK_ASM_UNDERSCORE): Test by attempting to
+ link with or without an underscore.
+ * gmp.texi (Known Build Problems): Remove SunOS 4 native grep
+ GSYM_PREFIX problem, now fixed.
+
+ * gmp-impl.h (MODLIMB_INVERSE_3): New constant.
+ * mpn/generic/diveby3.c: Use it instead of own INVERSE_3.
+ * mpn/generic/mul_n.c: Ditto.
+ * tests/t-constants.c: Check it, and PP_INVERTED too.
+
+ * acinclude.m4 (GMP_GCC_MARCH_PENTIUMPRO): New macro.
+ * configure.in [p6 and athlon] (gmp_optcflags_gcc): Use it to
+ possibly add -march=pentiumpro.
+
+ * gmp-impl.h (MPZ_SET_STR_OR_ABORT, MPF_SET_STR_OR_ABORT): New macros.
+ * mpz/tests/t-bin.c, mpz/tests/t-get_si.c, mpz/tests/t-jac.c,
+ mpz/tests/t-misc.c: Use them.
+ * mpf/tests/t-conv.c, mpf/tests/t-misc.c: Ditto.
+ * mpz/tests/convert.c: Ditto and amend diagnostics slightly.
+ * mpz/tests/t-misc.c (check_mpz_set_si): Remove a superfluous init.
+ * mpz/tests/io.c: Differentiate between I/O and data conversion errors.
+
+ * mpn/generic/aors_n.c: New file merging add_n and sub_n, no
+ object code changes.
+ * mpn/generic/add_n.c: Remove file.
+ * mpn/generic/sub_n.c: Remove file.
+
+ * mpn/generic/aorsmul_1.c: New file merging addmul_1 and submul_1,
+ no object code changes.
+ * mpn/generic/addmul_1.c: Remove file.
+ * mpn/generic/submul_1.c: Remove file.
+
+ * mpn/generic/popham.c: New file merging popcount and hamdist, no
+ object code changes.
+ * mpn/generic/popcount.c: Remove file.
+ * mpn/generic/hamdist.c: Remove file.
+
+2000-08-24 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (mpn_com_n): Fix typo.
+
+2000-08-23 Torbjorn Granlund <tege@swox.com>
+
+ * demos/primes.c (main): Don't call mpz_probab_prime_p for numbers
+ that are known to be prime after sieving.
+ (main): Declare and initialize max_s_prime_squared.
+ (MAX_S_PRIME): Increase.
+ (ST_SIZE): Increase.
+
+2000-08-23 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (ASSERT_ALWAYS): Change to statement style.
+ (JACOBI_TWO_U_BIT1): Remove ASSERT.
+ (MPZ_CHECK_FORMAT): Use ASSERT_ALWAYS as a statement.
+
+2000-08-21 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (ASSERT): Use do..while for dummy version.
+
+ * mpf/get_str.c: Don't set n_digits from digits_computed_so_far
+ when the converted operand becomes zero. Misc cleanups.
+
+2000-08-21 Kevin Ryde <kevin@swox.se>
+
+ * mpz/fdiv_r_2exp.c, mpz/lcm.c, mpz/urandomm.c: Add missing
+ TMP_MARK/FREE, avoiding memory leak when using stack-alloc.c.
+
+2000-08-20 Kevin Ryde <kevin@swox.se>
+
+ * mpz/set.c [BERKELEY_MP] (move): Add conditionals to build as
+ "move" for libmp.
+ * mpbsd/Makefile.am: Use mpz/set.c, not move.c.
+ * Makefile.am (MPBSD_OBJECTS): Corresponding change.
+ * mpbsd/move.c: Remove file.
+
+ * mpn/Makefile.am, mpz/Makefile.am, mpq/Makefile.am, mpf/Makefile.am,
+ mpbsd/Makefile.am (-DOPERATION_foo): Use "foo" even for ansi2knr
+ "foo_" objects. Do this with the makefiles to keep the sources
+ cleaner.
+ * mpz/mul_siui.c, mpf/integer.c: Revert to plain OPERATION_* forms.
+
+ * mpn/lisp/gmpasm-mode.el (gmpasm-remove-from-list): Renamed from
+ gmpasm-delete-from-list, because it's non-destructive.
+ (gmpasm-font-lock-keywords): Add some more keywords.
+
+2000-08-16 Kevin Ryde <kevin@swox.se>
+
+ * tune/mul_n_mpn.c, tune/mul_n_open.c: New files, being forced
+ open-coded and mpn #includes of mpn/generic/mul_n.c.
+ * tune/*: Add measuring of them.
+ * tune/speed.c: Print command line into *.gnuplot file.
+
+ * mpn/generic/mul_n.c (USE_MORE_MPN): Change to #if not #ifdef for
+ using the value, add #ifndef for providing the default.
+ * mpn/sparc64/gmp-mparam.h (USE_MORE_MPN): Add #ifndef.
+
+ * tests/t-constants.c: New file.
+ * tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpz/get_si.c: Use LONG_MAX, not BITS_PER_MP_LIMB, so the result
+ doesn't depend on limb size when outside the range of a long
+ (though such results are not actually documented).
+ * mpz/tests/t-get_si.c: New file.
+ * mpz/tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpn/tests/try.c (call): Cast popcount and hamdist calls,
+ for the benefit of long long limb.
+
+2000-08-15 Kevin Ryde <kevin@swox.se>
+
+ * mp.h (mp_set_memory_functions): Add missing #define.
+ * mpbsd/tests/allfuns.c (mp_set_memory_functions): Verify its
+ existence.
+
+ * mpf/tests/t-misc.c (check_mpf_getset_prec): New test, verifying
+ reverted behaviour of mpf_get_prec.
+
+ * mpn/tests/ref.c (refmpn_strip_twos): Use refmpn_copyi, not
+ MPN_COPY_INCR.
+
+ * mpz/mul_siui.c, mpf/integer.c: Recognise OPERATION_*_ forms
+ produced under ansi2knr.
+
+ * configure.in (mpn_objects, mpn_objs_in_libgmp): Add $U to .c
+ objects when ansi2knr in use.
+
+ * mpn/Makefile.am (AUTOMAKE_OPTIONS): Enable ansi2knr.
+ (libdummy.la): Add this, not built, to create ansi2knr style rules
+ for all potential .c files.
+ * mpz/Makefile.am, mpq/Makefile.am, mpf/Makefile.am, mpfr/Makefile.am,
+ mpbsd/Makefile.am, mpq/tests/Makefile.am, tests/Makefile.am
+ (AUTOMAKE_OPTIONS): Enable ansi2knr (now everywhere).
+ * Makefile.am (MPZ_OBJECTS, MPQ_OBJECTS, MPF_OBJECTS, MPFR_OBJECTS,
+ MPBSD_OBJECTS, libmp_la_DEPENDENCIES): Add $U to all .lo filenames.
+
+2000-08-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev6/addmul_1.asm: Correct number of cycles to 3.5/28.
+
+2000-08-02 Torbjorn Granlund <tege@swox.com>
+
+ * Version 3.1 released.
+
+ * gmp.texi: Rephrase mpf_urandomb documentation.
+
+ * mpn/alpha/ev6: New directory with ev6/21264 optimized code.
+ * mpn/alpha/ev6/addmul_1.asm: New file.
+ * mpn/alpha/ev6/gmp-mparam.h: New file.
+
+2000-08-02 Kevin Ryde <kevin@swox.se>
+
+ * demos/factorize.c (random): Don't use "inline".
+
+ * mpfr/log.c, mpfr/mul_ui.c, mpfr/round.c, mpfr/set.c, mpfr/set_d.c:
+ Corrections to K&R parts.
+
+ * Makefile.am (EXTRA_HEADERS): Omit $(MPFR_HEADERS_OPTION).
+ * mpfr/Makefile.am (EXTRA_DIST): Add mpfr.h.
+
+ * gmp.texi (Known Build Problems): Note problem stripping libgmp.a.
+
+2000-08-02 Kent Boortz <kent@swox.com>
+
+ * mpfr: Integrated experimental version of mpfr-0.4.
+ * configure.in: Changes for option --enable-mpfr.
+ * Makefile.am: Changes for option --enable-mpfr.
+
+2000-08-01 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/popcount.c: Disable SPARC v9 popc_limb pattern.
+ * mpn/generic/hamdist.c: Likewise.
+
+2000-08-01 Kevin Ryde <kevin@swox.se>
+
+ * mpn/tests/try.c (try_init): Account for ALIGNMENTS when sizing
+ source and dest regions.
+
+2000-07-31 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/get_str.c: Develop three extra digits, not just one.
+
+2000-07-31 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (References): Add URL for invariant division.
+
+2000-07-30 Kevin Ryde <kevin@swox.se>
+
+ * tune/time.c (speed_cpu_frequency_proc_cpuinfo): Add support for
+ alpha linux "cycle frequency".
+
+ * mpn/sparc64/gmp-mparam.h: Re-run tune program for FFT thresholds.
+
+2000-07-29 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (ABI and ISA): Add sparc64-*-linux*.
+ * configure.in [sparc64-*-linux*] (gmp_cflags64_gcc): Same flags
+ as under solaris.
+
+ * configure.in (--enable-fft): New option, default "no".
+ * gmp.texi (Build Options): Describe it.
+ * mpn/generic/mul.c, mpn/generic/mul_n.c [WANT_FFT]: Use it.
+ * tune/tuneup.c [WANT_FFT]: By default don't probe FFTs if not enabled.
+ * NEWS: Multiplication optionally using FFT.
+
+ * tune/README: Notes on FFT and GCD thresholds, other minor updates.
+
+ * Makefile.am: Expunge the macos generated files update stuff.
+
+2000-07-28 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/*/gmp-mparam.h: Add some FFT thresholds.
+
+2000-07-28 Kent Boortz <kent@swox.se>
+
+ * macos/Asm*, macos/CmnObj, macos/Mp*: Delete directories.
+ * macos/Makefile: Delete file.
+ * macos/Makefile.cw: Delete file.
+ * macos/config.h: Delete file.
+ * macos/Asm/*.s: Delete files.
+ * macos/configure: Create target directories. Don't transform
+ '(C)' to '(;)' in a 'dnl' line comment in .asm file.
+ * Makefile.am: Delete macos targets.
+ * macos/README: Reflect that we reverted back to a build
+ process that require ""macos/configure" to run on MacOS.
+ This imply that MacPerl is needed for a build in MacOS.
+
+2000-07-27 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/mul_fft.c: New file, by Paul Zimmermann, minor mods
+ applied.
+ * configure.in (gmp_mpn_functions): Add it.
+ * mpn/generic/mul.c, mpn/generic/mul_n.c: Use it.
+ * doc/multiplication: Describe it (briefly).
+
+ * gmp-impl.h (FFT_MUL_THRESHOLD etc): New thresholds.
+ (mpn_fft_best_k, mpn_fft_next_size, mpn_mul_fft, mpn_mul_fft_full):
+ New functions.
+ (numberof, TMP_ALLOC_TYPE etc, _MP_ALLOCATE_FUNC_TYPE etc,
+ UNSIGNED_TYPE_MAX etc): New macros.
+
+ * tune/*: Add FFT threshold tuning and speed measuring.
+ * tune/common.c: Avoid huge macro expansions for umul and udiv.
+
+ * mpz/tests/t-bin.c, mpz/tests/t-jac.c, mpz/tests/t-misc.c,
+ mpbsd/tests/t-misc.c, mpf/tests/t-misc.c, mpn/tests/try.c,
+ mpn/tests/spinner.c: Use new gmp-impl.h macros.
+
+ * demos/Makefile.am (BUILT_SOURCES): Don't need calc.c etc under this.
+
+2000-07-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/ia64/gmp-mparam.h: New file.
+
+2000-07-26 Torbjorn Granlund <tege@swox.com>
+
+ * demos/isprime.c: Handle any number of arguments and print
+ classification for each. Add `-q' option for old behaviour.
+
+2000-07-26 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Build Options): Mention djgpp stack size.
+ (Notes for Package Builds): New section.
+ (Compatibility with older versions): Update for 3.1, add mpf_get_prec.
+
+ * demos/factorize.c [__GLIBC__]: Don't declare random() under glibc.
+
+ * gmp.h (gmp_version): Add prototype and define.
+
+ * Makefile.am: Keep macos directory generated files up-to-date
+ during development and on a "make dist".
+
+2000-07-25 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/hppa/gmp-mparam.h: Update threshold values from new `tune' run.
+
+ * mpn/pa64/gmp-mparam.h: Fill in values from `make tune' run.
+ * mpn/pa64w/gmp-mparam.h: Likewise.
+ * mpn/mips3/gmp-mparam.h: Likewise.
+
+ * tune/hppa2.asm: Fix typo in .level directive.
+
+ * configure.in: Add sparc64-*-linux* support (from Jakub Jelinek).
+ * configure: Regenerate.
+
+ * mpn/sparc64/rshift.asm: Use %g5 instead of volatile stack frame area
+ for return value (from Jakub Jelinek).
+ * mpn/sparc64/lshift.asm: Likewise.
+
+ * mpf/get_prc.c: Revert Aug 8, 1996 change.
+
+ * version.c: No longer static.
+
+ * mpn/pa64/gmp-mparam.h: Only #define *_THRESHOLD if not already
+ defined.
+ * mpn/pa64w/gmp-mparam.h: Likewise.
+ * mpn/arm/gmp-mparam.h: Likewise.
+ * mpn/mips3/gmp-mparam.h: Likewise.
+
+2000-07-25 Kevin Ryde <kevin@swox.se>
+
+ * INSTALL: It's "info -f ./gmp.info" to be sure of hitting the
+ gmp.info in the current directory.
+
+ * Makefile.am (libmp_la_DEPENDENCIES): Add mpz/cmp.lo, for last
+ mpz/powm.c fix.
+
+ * mpn/sparc64/addmul1h.asm, mpn/sparc64/submul1h.asm: Renamed from
+ addmul_1h.asm, submul_1h.asm to avoid name conflicts on an 8.3
+ filesystem.
+ * mpn/sparc64/addmul_1.asm, mpn/sparc64/submul_1.asm,
+ mpn/sparc64/mul_1.asm: Update include_mpn()s.
+
+2000-07-24 Torbjorn Granlund <tege@swox.com>
+
+ * Update header of all files previously under the Library GPL
+ to instead be under the Lesser GPL.
+
+ * COPYING.LIB: Now Lesser GPL.
+ * demos/primes.c: Change license to GPL (was Library GPL).
+ * demos/isprime.c: Change license to GPL (was Library GPL).
+
+ * gmp.h (error code enum): Add GMP_ERROR_BAD_STRING (currently unused).
+
+ * mpz/tests/t-mul.c: Default SIZE to a function of TOOM3_MUL_THRESHOLD.
+ Improve error messages. Decrease reps.
+
+2000-07-22 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.h: Decrease the amount of data used for gcd and powm
+ measuring, to make the tune go a bit faster.
+
+2000-07-21 Kent Boortz <kent@swox.se>
+
+ * macos/Asm*, macos/CmnObj, macos/Mp*: Directories no longer created
+ from configure script, now part of dist.
+ * macos/Makefile
+ * macos/Makefile.cw
+ * macos/config.h
+ * macos/Asm/*.s
+ New files and directories that is the output from configure. This way
+ no Perl installation is required to build on MacOS, just MPW.
+ * macos/configure: Added prefix '__g' to exported assembler labels.
+ Changed to handle new m4 syntax instead of the old cpp syntax in asm.
+ * macos/Makefile.in: Corrected 'clean' target, added 'distclean'
+ and 'maintainer_clean'. Added "mpn/mp_bases.c" to build.
+ * macos/README: Reflect the new build process without configure.
+ Corrected the file structure for Apple MPW installation.
+
+2000-07-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/tests/t-muldiv.c: Relax error limit. Make precision depend
+ on SIZE. Misc changes.
+
+ * configure: Regenerate.
+
+2000-07-20 Kent Boortz <kent@swox.com>
+
+ * macos/Makefile.in: Removed hard coded targets, added special
+ targets found in Makefile.am files.
+ * macos/configure: Generate targets from top configure script and
+ Makefile.am files. Made script runnable from Unix for testing.
+ * macos/README: Notes about search paths for includes, contributed
+ by Marco Bambini.
+ * configure.in: Added comment about lines that the "macos/configure"
+ script depend on.
+
+2000-07-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/powm.c (mpz_powm): After final mpz_redc call, subtract `mod'
+ from result if it is greater than `mod'.
+
+2000-07-19 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/hppa/gmp-mparam.h: Fill in values from `make tune' run.
+ * mpn/alpha/gmp-mparam.h: Likewise.
+ * mpn/powerpc32/gmp-mparam.h: Likewise.
+
+ * tune/hppa.asm: New file.
+ * tune/hppa2.asm: New file.
+ * configure.in (SPEED_CYCLECOUNTER_OBJS): Set for hppa2*-*-* and
+ hppa*-*-*.
+ * tune/Makefile.am (EXTRA_DIST): Add hppa.asm and hppa2.asm.
+
+ * tune/speed.h (SPEED_ROUTINE_MPN_BZ_DIVREM_CALL): Declare `marker';
+ invoke TMP_FREE.
+
+ * mpn/hppa/hppa1_1/udiv_qrnnd.S: Use "%" instead of "'" for
+ reloc/symbol delimiter.
+
+2000-07-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/gmp-mparam.h: Update with output from tune utility.
+ * mpn/powerpc64/copyi.asm: New file.
+ * mpn/powerpc64/copyd.asm: New file.
+
+2000-07-16 Kevin Ryde <kevin@swox.se>
+
+ * tune/*: Add measuring for umul_ppmm and udiv_qrnnd.
+
+2000-07-14 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k6/k62mmx: New directory.
+ * configure.in (k6[23]*-*-*): Use it.
+ * mpn/x86/k6/k62mmx/copyi.asm, mpn/x86/k6/k62mmx/copyd.asm: Move from
+ mmx directory, improve code alignment a bit.
+ * mpn/x86/k6/k62mmx/lshift.asm, mpn/x86/k6/k62mmx/rshift.asm: Ditto,
+ and improve addressing modes for pre-CXT cores.
+ * mpn/x86/x86-defs.m4 (Zdisp): Add an instruction.
+ * mpn/x86/k6/mmx/lshift.asm, mpn/x86/k6/mmx/rshift.asm: New files,
+ suiting plain K6.
+ * mpn/x86/README, mpn/x86/k6/README: Updates.
+ * mpn/x86/k6/mmx/*.asm: Update some comments.
+
+ * mpn/tests/Makefile.am: Use $(MAKE) in .asm rules, not "m".
+ * tune/Makefile.am: Use $(EXEEXT) and libtool --config objdir, for
+ the benefit of djgpp.
+
+ * */Makefile.in: Regenerate with patched automake that adds
+ $(EXEEXT) to EXTRA_PROGRAMS.
+
+ * mpn/tests/try.c: Add #ifdef to SIGBUS, for the benefit of djgpp.
+ * config.guess: Recognise pc:*:*:* as an x86, for djgpp.
+
+ * configure: Regenerate with patched autoconf to fix temp file
+ ".hdr" which is invalid on a DOS 8.3 filesystem, and to fix two
+ sed substitutes that clobbered a ":" in $srcdir (eg. a DOS drive
+ spec).
+
+ * mpz/tests/io.c: Use one fp opened "w+", since separately opened
+ input and output doesn't work on MS-DOS 6.21.
+
+ * tests/rand/Makefile.am (allprogs): Pseudo-target to build everything.
+ (CLEANFILES): Add EXTRA_PROGRAMS and EXTRA_LTLIBRARIES.
+ (manual-test, manual-bigtest): Add $(EXEEXT) to dependencies.
+
+ * tests/rand/*/Makefile.in: Regenerate with patched automake that adds
+ $(EXEEXT) to EXTRA_PROGRAMS.
+
+2000-07-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/t-root.c: Also test mpz_perfect_power_p.
+ Generate `nth' so that there will be fewer trivial values.
+
+ * mpz/root.c: Reverse return value in tests for detecting root of +1
+ and -1.
+
+ * mpz/perfpow.c: Use TMP_ALLOC interface.
+
+2000-07-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/perfpow.c (primes): Make it const.
+
+2000-07-06 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k6/cross.pl: New file.
+
+ * mpn/x86/*/gmp-mparam.h: Updates to thresholds, conditionalize
+ all _TIME defines.
+ * mpn/x86/pentium/mmx/gmp-mparam.h: New file.
+ * mpn/sparc64/gmp-mparam.h: Update thresholds.
+ * mpn/sparc32/v9/gmp-mparam.h: Ditto.
+
+2000-07-04 Kevin Ryde <kevin@swox.se>
+
+ * NEWS: Updates.
+ * mpn/x86/*/README: Miscellaneous updates.
+
+ * tune/speed-ext.c: New file.
+ * tune/Makefile.am: Add it.
+ * tune/README: Updates.
+ * tune/speed.h (SPEED_ROUTINE_MPN_DIVREM_2): Bug fixes.
+
+ * demos/calc.y,calclex.l: New files.
+ * demos/calc.c,calc.h,calclex.c: New files, generated from .y and .l.
+ * demos/Makefile.am: Add them.
+
+ * gmp.h (mpq_swap, mpf_swap): Add prototypes and defines.
+
+2000-07-01 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (ABI and ISA): New section, bringing together ABI notes.
+ (Build Options): Add MPN_PATH, various updates.
+ (Build Options): Add note on setting CFLAGS when setting CC.
+ (Notes for Particular Systems): Add -march=pentiumpro problem.
+ (Known Build Problems): Note on gmp-mparam.h for 64-bit generic C.
+ (GMP Variable Conventions): Add some info on user defined functions.
+ (Reporting Bugs): Minor rewording.
+
+ * configure.in (MPN_PATH): Renamed from mpn_path.
+
+ * gmp-impl.h (ULONG_MAX,ULONG_HIGHBIT,...,SHORT_MAX): New defines.
+ * mp[zf]/tests/t-misc.c: Use them.
+
+ * mpbsd/tests/t-misc.c: New file.
+ * mpbsd/tests/Makefile.am: Add it.
+
+ * Makefile.am (LIBGMP_LT_*, LIBMP_LT_*): Bump version info.
+ * gmp.h (__GNU_MP_VERSION_*): Bump to 3.1.
+
+ * mpf/tests/Makefile.am (AUTOMAKE_OPTIONS): Add ansi2knr.
+
+ * Makefile.am (libmp_la_SOURCES): Add mp_set_fns.c, accidentally
+ omitted in gmp 3.0.x.
+ * gmp.texi (Custom Allocation): Note this is available in mpbsd,
+ and some minor rewording.
+
+2000-06-30 Torbjorn Granlund <tege@swox.com>
+
+ * demos/factorize.c (random): New function, defined conditionally.
+ (factor_using_pollard_rho): Use it, not mrand48.
+
+ * mpn/cray/README: New file.
+
+2000-06-30 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/aorsmul_1.asm: Add MULFUNC_PROLOGUE.
+
+ * mpz/tests/t-jac.c: Test limbs on mpn_jacobi_base, not just ulongs.
+
+ * gmp-impl.h, mpn/tests/try.c, mpn/tests/spinner.c, tune/speed.c:
+ Use config.h unconditionally, not under HAVE_CONFIG_H.
+
+ * demos/pexpr.c [__DJGPP__]: Patch by Richard Dawe to not use
+ setup_error_handler on djgpp.
+
+ * tune/*: Locate data to help direct-mapped caches, add measuring
+ of mpz_init/clear, mpz_add and mpz_bin_uiui, various cleanups.
+ * configure.in (AC_CHECK_FUNCS): Add popen.
+
+2000-06-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/mul_2exp.c: Streamline criterion for whether to use mpn_lshift or
+ mpn_rshift. Increase precision when exp is a multiple of
+ BITS_PER_MP_LIMB primarily to make exp==0 be a noop.
+ * mpf/div_2exp.c: Analogous changes.
+
+ * mpf/tests/t-dm2exp.c: Set u randomly in loop. Perform more
+ mpf_mul_2exp testing.
+
+ * configure.in: Recognize cray vector processors with a broad `*';
+ move after alpha* not to match that.
+
+2000-06-28 Kevin Ryde <kevin@swox.se>
+
+ * mpz/tests/io.c: Use a disk file, not a pipe, switch to ansi2knr
+ style, switch from MP_INT to mpz_t, add a couple of error checks.
+ * mpz/tests/Makefile.am (CLEANFILES): Add io.tmp, in case io.c fails.
+
+2000-06-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/tests/t-get_d.c: Be more lax about relative error, to handle Cray
+ floating point format.
+
+ * mpq/tests/t-get_d.c: Decrease default reps to 1000.
+
+ * mpf/tests/t-conv.c: Correct type of `bexp'.
+
+ * configure.in (cray vector machines): Don't inherit gmp_cflags_cc.
+
+ * tune/Makefile.am (EXTRA_DIST): Delete sparc64.asm.
+
+ * configure.in (cray vector machines): Set extra_functions.
+
+ * mpn/cray/mulww.f: New file with vectorizing cray code.
+ * mpn/cray/mulww.s: Generated from mulww.f.
+ * mpn/cray/mul_1.c: New file.
+ * mpn/cray/addmul_1.c: New file.
+ * mpn/cray/submul_1.c: New file.
+ * mpn/cray/add_n.c: New file.
+ * mpn/cray/sub_n.c: New file.
+
+2000-06-26 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_ASM_ALIGN_FILL_0x90): Fix so it actually
+ detects solaris 2.6, and also suppress warning on solaris 2.8.
+ * configure.in (SPEED_CYCLECOUNTER): Remove spurious "athlon" from
+ sparc case.
+
+ * mpn/lisp/gmpasm-mode.el: Move keymap to the top of the docstring.
+
+2000-06-21 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/mul_n.c (mpn_kara_mul_n, mpn_kara_sqr_n): Use
+ mp_size_t for n2.
+ (mpn_toom3_mul_n, mpn_toom3_sqr_n): Use mp_size_t for size
+ parameters and "l" variables.
+ * gmp-impl.h (mpn_toom3_mul_n, mpn_toom3_sqr_n): Update prototypes.
+
+ * mpbsd/itom.c, mpbsd/sdiv.c: Add casts for correct handling of
+ -0x80...00 on systems with sizeof(short)==sizeof(int).
+
+ * mpz/tests/t-misc.c: Move "bin" test from here ...
+ * mpz/tests/t-bin.c: ... to here, and add a new (2k,k) test too.
+ * mpz/tests/Makefile.am (check_PROGRAMS): Add t-bin.
+
+ * mpz/bin_ui.c [_LONG_LONG_LIMB]: Use mpn_divrem_1, since kacc is
+ a limb not a ulong.
+ * mpz/bin_uiui.c [_LONG_LONG_LIMB]: Ditto, and use mpn_mul_1 too,
+ since nacc is a limb.
+
+ * mpf/tests/t-misc.c (check_mpf_set_si, check_mpf_cmp_si):
+ New file, testing mpf_set_si, mpf_init_set_si, and mpf_cmp_si.
+ * mpf/tests/Makefile.am (check_PROGRAMS): Add it.
+
+ * mpz/tests/t-misc.c (check_mpz_set_si, check_mpz_cmp_si):
+ New tests, for mpz_set_si, mpz_init_set_si, and mpz_cmp_si.
+
+ * mpz/set_si.c, mpz/iset_si.c, mpz/cmp_si.c [_LONG_LONG_LIMB]: Fix
+ handling of -0x80..00.
+ * mpf/set_si.c, mpf/iset_si.c, mpf/cmp_si.c [_LONG_LONG_LIMB]: Ditto.
+
+2000-06-19 Torbjorn Granlund <tege@swox.com>
+
+ * demos/primes.c: Properly handle arguments `m +n'.
+
+2000-06-17 Torbjorn Granlund <tege@swox.com>
+
+ * config.sub: Recognize k5 and k6 with common pattern.
+
+ * mpq/tests/t-get_d.c: Also test mpq_set_d. Misc improvements.
+
+ * mpq/set_d.c: Special case 0.0. Don't call mpn_rshift with 0 count.
+ Allocate correct amount of memory for numerator. Delete spurious
+ ASSERT_ALWAYS(1).
+
+2000-06-17 Kevin Ryde <kevin@swox.se>
+
+ * mpz/perfsqr.c: Fix so that zero is considered a perfect square.
+ (Was wrongly calling mpn_perfect_square_p with size==0.)
+
+2000-06-16 Kevin Ryde <kevin@swox.se>
+
+ * configure.in: Set k5*-*-* to use basic i386 code until there's
+ something specific. Add path=x86 as a default for x86s.
+
+ * acinclude.m4 (GMP_CHECK_ASM_ALIGN_LOG): Generate
+ ALIGN_LOGARITHMIC setting, not a full ALIGN definition.
+ (GMP_CHECK_ASM_ALIGN_FILL_0x90): New test.
+ * configure.in [x86-*-*]: Use GMP_CHECK_ASM_ALIGN_FILL_0x90.
+ * mpn/asm-defs.m4 (ALIGN): New macro.
+ * mpn/x86/x86-defs.m4 (ALIGN): Remove supplementary definition.
+
+ * tune/*: Plain "unsigned" for speed_cyclecounter.
+ * configure.in: Use tune/sparcv9.asm for 32 and 64 bit modes.
+ * tune/sparc64.asm: Remove file.
+
+2000-06-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/k7/mmx/copyi.asm: Use `testb' instead of `test'.
+ * mpn/x86/k7/mmx/copyd.asm: Likewise.
+
+ * mpn/x86/k7/mmx/lshift.asm: Avoid using `~' (Solaris as problems).
+ * mpn/x86/k7/mmx/rshift.asm: Likewise.
+ * mpn/x86/k6/aors_n.asm: Likewise.
+ * mpn/x86/k7/aors_n.asm: Likewise.
+ * mpn/x86/k7/mul_basecase.asm: Likewise.
+
+2000-06-13 Torbjorn Granlund <tege@swox.com>
+
+ * tune/sparcv9.asm: Tune, deleting two instructions.
+
+ * tune/alpha.asm: Update to unified speed_cyclecounter.
+
+2000-06-11 Kevin Ryde <kevin@swox.se>
+
+ * mpz/tests/reuse.c (FAIL): Add a K&R version.
+ Use _PROTO on some typedefs.
+ * mpz/tests/t-misc.c: Add gmp-impl.h for "const".
+
+ * configure.in: Rework mpn multi-function and optional files.
+ Names standardized, no need for explicit declarations, all picked
+ up in one $path traversal.
+ * doc/configuration: Updates.
+
+ * tests/rand/t-rand.c (main): Change "usage" to work with K&R.
+
+2000-06-10 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/mmx/popham.asm, mpn/x86/p6/mmx/popham.asm,
+ mpn/x86/p6/p3mmx/popham.asm, mpn/x86/p6/diveby3.asm: Add
+ MULFUNC_PROLOGUE for correct HAVE_NATIVE_* matching.
+
+ * mpn/x86/x86-defs.m4 (cmov_bytes_tttn): Use eval() on expressions.
+ (cmov_available_p): Switch to list CPUs which do have cmov.
+ * mpn/x86/p6/sqr_basecase.asm, mpn/x86/k6/sqr_basecase.asm,
+ mpn/x86/k7/sqr_basecase.asm: Use eval() for multiplication.
+ * mpn/x86/README.family: Various updates.
+
+2000-06-09 Kevin Ryde <kevin@swox.se>
+
+ * mpbsd/tests/allfuns.c (main): Call exit() instead of doing return.
+
+ * doc/tasks.html, doc/projects.html: Moved from projects directory.
+ * doc/multiplication: New file.
+ * Makefile.am (EXTRA_DIST): Remove projects, add doc.
+
+ * Makefile.am (libgmp_la_LIBADD, libmp_la_LIBADD): Remove
+ unnecessary -lm.
+ * INSTALL: Remove -lm from instructions.
+ * demos/Makefile.am (qcn_LDADD): Add -lm.
+
+ * tune/*: Add measuring for mpn_divrem_2 and modlimb_invert,
+ improve addsub_n. Switch to unified speed_cyclecounter.
+ * configure.in: Update configs for speed_cyclecounter.
+
+ * gmp-impl.h (MP_LIMB_T_MAX, MP_LIMB_T_HIGHBIT): New macros.
+ * mpn/generic/diveby3.c, mpn/generic/mul_n.c, mpn/generic/gcd.c,
+ tune/speed.c, mpn/tests/ref.c: Use them.
+
+ * mpn/tests/spinner.c: Remove setitimer, just alarm is enough.
+ * configure.in (AC_CHECK_FUNCS): Remove setitimer.
+ * mpn/tests/x86call.asm: Start with junk in %eax, %ecx, %edx.
+ * mpn/tests/ref.[ch] (refmpn_addsub_nc): New function.
+ * mpn/tests/try.c: Add some support for mpn_addsub_nc.
+ * mpn/tests/Makefile.am (EXTRA_PROGRAMS): Remove addsub_n and
+ addsub_n_2 which don't currently build.
+ * mpn/tests/copy.c: Test MPN_COPY_INCR, not __gmpn_copy.
+
+ * tests/rand/Makefile.am (libstat_la_LIBADD): Add -lm, no longer on
+ libgmp.la.
+ (findlc_LDADD): Use libstat.la.
+ (AUTOMAKE_OPTIONS): Use ansi2knr.
+
+2000-06-08 Torbjorn Granlund <tege@swox.com>
+
+ * configure.in (alpha*-*-osf*): Default `flavour' to ev6 for ev6 and
+ higher.
+ (alpha*-*-*): Likewise.
+ (alpha*-*-osf*: gmp_optcflags_cc): Move -arch/-tune flags from
+ gmp_xoptcflags_gcc.
+
+ * mpn/Makefile.am (TARG_DIST): Add pa64w.
+
+ * longlong.h: Wrap 64-bit hppa code in #ifndef LONGLONG_STANDALONE.
+
+2000-06-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/remove.c: Fail for `src' being zero.
+
+ * mpz/tests/reuse.c: Test more functions.
+ (FAIL): New define.
+
+ * mpz/tests/t-powm.c: Loop during operand generation while they
+ are mathematically ill-defined (used to just skip such tests).
+
+ * mpz/powm.c (mpz_redc): Clean up argument declarations.
+
+ * configure.in (gmp_cflags64_gcc): Don't add bogus -mWHAT option.
+ (sparcv9-*-solaris2.[7-9]], gmp_cflags64_gcc):
+ Inherit from previous gmp_cflags64_gcc; pass `-m64 -mptr64'.
+ (ia64*-*-*): New.
+
+ * mpn/generic/dump.c: Make it work when an mp_limb_t is not `long'.
+
+ * mpf/set_prc.c: MPN_COPY => MPN_COPY_INCR.
+
+2000-06-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_n.c (mpn_toom3_mul_n, mpn_toom3_sqr_n):
+ Use mpn_incr_u for final carry propagation.
+
+ * mpz/tests/t-gcd.c: Add calls to mpz_gcdext with argument t == NULL.
+
+ * mpz/tests/reuse.c: Major rewrite; test many more functions.
+
+ * mpz/powm_ui.c: When exp is 0, change res assign order in order
+ to handle argument overlap.
+ * mpz/powm.c: When exp is 0, change res assign order in order
+ to handle argument overlap. Handle negative exp and mod arguments.
+
+ * mpz/gcdext.c: Rework code after mpn_gcdext call to handle
+ argument overlap.
+
+ * mpz/fdiv_qr.c: Read dividend->_mp_size before calling mpz_tdiv_qr
+ in order to handle argument overlap.
+ * mpz/cdiv_qr.c: Likewise.
+
+ * mpf/tests/reuse.c: Fix typo that effectively disabled `dis_funcs'
+ tests. Clean up test for mpf_ui_div.
+
+2000-06-06 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/p6/sqr_basecase.asm: New file.
+ * mpn/x86/mod_1.asm: Avoid one conditional jump.
+ * mpn/x86/p6/gmp-mparam.h: Update thresholds, #ifndef UMUL_TIME
+ and UDIV_TIME, add COUNT_TRAILING_ZEROS_TIME.
+
+ * mp_minv_tab.c: New file.
+ * Makefile.am (libgmp_la_SOURCES, libmp_la_SOURCES): Add it.
+ * gmp-impl.h (modlimb_invert): New macro.
+ * mpz/powm.c: Remove mpz_dmprepare, use modlimb_invert instead.
+ * mpn/generic/bdivmod.c: Use modlimb_invert instead of a loop.
+ * mpn/generic/gcd.c: Inline two small mpn_bdivmod calls, use
+ MPN_COPY_INCR not MPN_COPY in one place.
+
+2000-06-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/tests/reuse.c (dsi_funcs): Add mpf_mul_2exp and mpf_div_2exp.
+ (main): Clean up test for mpf_div_ui.
+
+ * mpf/mul_2exp.c: Correct criterion for whether to use mpn_lshift or
+ mpn_rshift. MPN_COPY => MPN_COPY_INCR. Coerce the two assignments to
+ r->_mp_size.
+
+ * mpf/div_2exp.c: Use mpn_rshift instead of mpn_lshift when overlap
+ so requires. MPN_COPY => MPN_COPY_INCR.
+
+ * mpf/tests/t-dm2exp.c: Correct type of res_prec.
+
+2000-06-04 Kevin Ryde <kevin@swox.se>
+
+ * mpz/bin_uiui.c: Fix result for n==0 and n==k.
+ * mpz/bin_ui.c: Fix result for k>n, add support for n<0.
+ * gmp.texi (Number Theoretic Functions): Update mpz_bin_ui to
+ note n<0 is supported.
+
+ * mpz/tests/t-misc.c: New file.
+ * mpz/tests/Makefile.am (check_PROGRAMS): Add it.
+
+2000-05-31 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.* (FLAG_R_OPTIONAL): New option for routines, use on
+ mpn_gcd_1 and mpn_mul_basecase.
+ * tune/README: Update.
+
+ * tune/alpha.asm: New file, by Torbjorn.
+ * tune/Makefile.am (EXTRA_DIST): Add it.
+ * configure.in (alpha*-*-*): Use it.
+
+2000-05-31 Linus Nordberg <linus@swox.se>
+
+ * doc/configuration: New file.
+
+2000-05-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_basecase.c: Call mpn_mul_2 and mpn_addmul_2
+ if available. Don't include longlong.h.
+
+ * doc/isa_abi_headache: New file.
+
+2000-05-30 Linus Nordberg <linus@swox.se>
+
+ * configure.in (NM): Use AC_PROG_NM rather than AC_CHECK_TOOL to
+ find `nm'. (AC_PROG_NM comes with Libtool and is needed to get
+ the `-B' option (BSD compatible output) included in $NM.)
+ (AR): Use AC_CHECK_PROG rather than AC_CHECK_TOOL to find `ar'.
+ (Now that NM isn't a cross compilation tool, don't give the
+ impression that we know how to cross compile.)
+ (CCAS): Remove spurious comment.
+
+ * gmp.texi (Notes for Particular Systems): Remove comment about
+ using GNU `nm' on AIX since system nm now works.
+
+2000-05-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/power/mul_1.s: Remove [PR] from first word in function
+ descriptor.
+ * mpn/power/addmul_1.s: Likewise.
+ * mpn/power/submul_1.s: Likewise.
+
+2000-05-28 Kevin Ryde <kevin@swox.se>
+
+ * configure.in, tune/*: Change pentium rdtsc cycle scheme to
+ HAVE_SPEED_CYCLECOUNTER and SPEED_CYCLECOUNTER_OBJS.
+ * tune/pentium.asm: Renamed and converted from rdtsc.asm.
+ * tune/sparcv9.asm: New file, by Torbjorn.
+ * tune/sparc64.asm: New file.
+ * tune/tuneup.c: Put a limit on gcdext search.
+
+ * gmp.h (mp_set_memory_functions): Add extern "C".
+ * mp.h (__GNU_MP__): Bump to "3".
+ * mpz/add.c,mul.c,powm.c,sub.c,sqrtrem.c,tdiv_qr.c [BERKELEY_MP]:
+ Include mp.h for mpbsd compile.
+ * mpz/gcd.c: Ditto, and remove _mpz_realloc declaration.
+
+ * gmp.texi (Integer Functions): Flatten @subsections into @sections.
+ (Floating-point Functions): Ditto.
+ (Integer Random Numbers): Split from miscellaneous as a sep section.
+ (Installing GMP): Make nodes for the sections.
+ Add more "@cindex"s.
+ (Known Build Problems): Remove SunOS get_d problem, believed fixed.
+ (Notes for Particular Systems): Remove HPPA note since now PIC.
+ (References): URL for Jebelean.
+
+2000-05-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64w: New directory, contents based on corresponding mpn/pa64
+ files.
+ * configure.in (hppa2.0w-*-*): New.
+ * mpz/tests/io.c (_INCLUDE_POSIX_SOURCE): Define when __hpux before
+ including stdio.h.
+ * gmp-impl.h: Always define DItype and UDItype.
+
+2000-05-27 Kevin Ryde <kevin@swox.se>
+
+ * tune/common.c (speed_measure): Correction to array sorting,
+ better diagnostic when measuring fails.
+ * tune/time.c: Add microsecond accurate getrusage method.
+
+ * tune/time.c (speed_cpu_frequency_processor_info): New function.
+ * configure.in (AC_CHECK_FUNCS): Add processor_info.
+
+2000-05-26 Linus Nordberg <linus@swox.se>
+
+ * gmp.texi (Installing GMP): Shared libraries work for AIX < 4.3
+ if using GNU nm.
+
+2000-05-26 Torbjorn Granlund <tege@swox.com>
+
+ * tune/tuneup.c (SIGNED_TYPE_MAX): Shift `-1' instead of `1' to
+ avoid signed overflow.
+
+ * demos/pexpr.c (setup_error_handler): Don't call sigaltstack on
+ Unicos.
+
+2000-05-25 Torbjorn Granlund <tege@swox.com>
+
+ * insert-dbl.c: Work around GCC 2.8 bug.
+ * extract-dbl.c: Likewise.
+
+ * config.sub: Allow i586, i686, i786 again.
+
+ * config.guess: Use X86CPU for lots more systems.
+
+2000-05-25 Linus Nordberg <linus@swox.se>
+
+ * mpbsd/tests/dummy.c (main): Call exit() instead of doing return
+ (some old SysV machines don't get this correct, I've heard.)
+
+2000-05-25 Kevin Ryde <kevin@swox.se>
+
+ * mpf/iset_str.c: Initialize _mp_size and _mp_exp to 0, in case no
+ digits in string, so it's the same as a separate init and set_str.
+
+2000-05-24 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/reuse.c: Use mpz_random2 instead of mpz_random.
+
+ * mpz/divexact.c: Read pointers after reallocation.
+ Compare `quot' and `den' instead of `qp' and `dp' in overlap check.
+ Use MPN_COPY_INCR for copying from `np'.
+
+ (*-*-aix4.[3-9]*): Disable shared libs just for problematic AIX
+ versions.
+ * configure.in (*-cray-unicos*): Disable asm syntax checking; set
+ compiler explicitly.
+ * configure.in (hppa*-*-*): Remove code disabling shared libs.
+
+2000-05-24 Linus Nordberg <linus@swox.se>
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): Don't report progress to user
+ when doing the AIX specific test to avoid "nested output".
+
+2000-05-22 Kevin Ryde <kevin@swox.se>
+
+ * mp.h (_PROTO): Copy from gmp.h, use on prototypes.
+ Add extern "C" too.
+ * mpbsd/tests/Makefile.am (AUTOMAKE_OPTIONS): Enable ansi2knr.
+ * mpbsd/tests/allfuns.c: Don't execute mout, just link to it.
+ (main): ANSI style definition.
+
+ * gmp-impl.h (MP_BASE_AS_DOUBLE): Change the expression to
+ something that works on SunOS native cc. Seems to fix the
+ mp*_get_d problems.
+
+ * mpn/tests/ref.c (refmpn_strip_twos): Use MPN_COPY_INCR.
+ * mpn/tests/Makefile.am: Let .asm.o rules work with absolute $srcdir.
+
+2000-05-21 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k7/sqr_basecase.asm: Replace file with K7 specific code.
+ * mpn/x86/k7/README: Update.
+ * mpn/x86/k7/gmp-mparam.h: Tune thresholds.
+ (COUNT_TRAILING_ZEROS_TIME): New define.
+ * mpn/x86/k6/gmp-mparam.h: Ditto.
+
+ * mpn/x86/pentium/mmx/popham.asm: New file (include_mpn of K6 version).
+ * mpn/x86/p6/diveby3.asm: New file (include_mpn of P5 version).
+ * mpn/x86/p6/mmx/popham.asm: New file (include_mpn of K6 version).
+ * mpn/x86/p6/p3mmx/popham.asm: New file (include_mpn of K7 version).
+ * configure.in (pentium3-*-*): Add p3mmx to $path.
+
+ * gmp.texi (Integer Arithmetic): Clarify mpz_jacobi op2; add
+ mpz_*_kronecker_*.
+ (Miscellaneous Integer Functions): Add mpz_odd_p and mpz_even_p.
+ (Low-level Functions): Put mpn_divmod_1 with mpn_divrem_1 and note
+ it's now a macro.
+ (References): Add Henri Cohen.
+
+ * gmp.h (mpn_addmul_1c, mpn_divrem_1c, mpn_mod_1c, mpn_mul_1c,
+ mpn_submul_1c): Add prototypes.
+ (mpz_odd_p, mpz_even_p): New macros.
+
+ * mpn/asm-defs.m4 (m4wrap_prepend): New macro.
+ (m4_error): Use it.
+ (m4_not_for_expansion): Corrections to OPERATION symbols.
+ More comments about variations between m4 versions.
+ * mpn/x86/x86-defs.m4 (PROLOGUE): Use m4wrap_prepend (fixes error
+ exit under BSD m4, previously m4_error printed the message but the
+ exit code was 0).
+
+ * gmp.h (mpn_divmod_1): Change to a macro calling mpn_divrem_1.
+ * mpn/generic/divrem_1.c: Move divmod_1.c code to here, make it
+ static and call it __gmpn_divmod_1_internal.
+ * mpn/generic/divmod_1.c: Remove file.
+ * configure.in (gmp_mpn_functions): Remove divmod_1.
+ * mpn/asm-defs.m4 (define_mpn): Remove divmod_1 and divmod_1c.
+ * compat.c (mpn_divmod_1): Add compatibility function.
+ * tune/*: Remove mpn_divmod_1 measuring (leave just divrem_1).
+
+ * acconfig.h (HAVE_NATIVE_mpn_*): Add some missing carry-in
+ variants, remove divmod_1.
+
+ * mpn/x86/diveby3.asm: Use imul, update comments.
+
+ * demos/qcn.c: New file.
+ * demos/Makefile.am (EXTRA_PROGRAMS): Add it.
+
+ * mpz/tests/t-jac.c: New file.
+ * mpz/tests/Makefile.am (check_PROGRAMS): Add it. Enable ansi2knr.
+
+ * mpz/kronsz.c: New file.
+ * mpz/kronuz.c: New file.
+ * mpz/kronzs.c: New file.
+ * mpz/kronzu.c: New file.
+ * mpz/Makefile.am (libmpz_la_SOURCES): Add them.
+ * Makefile.am (MPZ_OBJECTS): Add them.
+ * gmp-impl.h (JACOBI_*, MPN_STRIP_LOW_ZEROS_NOT_ZERO): New macros.
+ * gmp.h (mpz_*_kronecker_*): New defines and prototypes.
+
+ * mpn/generic/jacbase.c: New file.
+ * mpn/generic/mod_1_rs.c: New file.
+ * configure.in (gmp_mpn_functions): Add them.
+ * gmp.h (mpn_jacobi_base, mpn_mod_1_rshift): New defines and
+ prototypes.
+ * longlong.h (COUNT_TRAILING_ZEROS_TIME): New define.
+ * mpn/tests/ref.c (refmpn_mod_1_rshift): New function.
+ * mpn/tests/try.c: Add mpn_mod_1_rshift.
+ * tune/*: Add measuring for mpn_jacobi_base.
+
+ * acinclude.m4 (GMP_FINISH): Add ifdefs to allow multiple
+ inclusion of config.m4.
+ (GMP_PROG_M4): Put "good" message through to config.log.
+
+ * mpz/powm.c: Use a POWM_THRESHOLD for where redc stops.
+ * tune/*: Add mpz_powm measuring, and tune POWM_THRESHOLD.
+ * gmp-impl.h [TUNE_PROGRAM_BUILD] (POWM_THRESHOLD): Conditional
+ redefinition for use when tuning.
+
+ * mpz/powm_ui.c: Use DIVIDE_BY_ZERO.
+
+ * mpz/iset_str.c: Initialize _mp_size to 0, in case no digits in
+ string; this makes it the same as a separate init and set_str.
+
+2000-05-20 Kevin Ryde <kevin@swox.se>
+
+ * mpn/asm-defs.m4: Note &,|,^ aren't bitwise in BSD m4 eval().
+ * mpn/x86/k6/sqr_basecase.asm: Use "%" not "&" in m4 eval()s.
+
+ * mpn/x86/x86-defs.m4 (Zdisp): Yet more instruction forms.
+
+2000-05-19 Linus Nordberg <linus@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_CC_64BIT): Don't use shell variable
+ `ac_compile' for our own compile command string since other
+ Autoconf macros may depend on it.
+
+2000-05-19 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/mul_n.c (mpn_toom3_mul_n, mpn_toom3_sqr_n): Fix
+ carry propagation in final coefficient additions.
+
+2000-05-18 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Set NM before looking for compiler since
+ GMP_CHECK_CC_64BIT needs it.
+
+ * acinclude.m4 (GMP_CHECK_CC_64BIT): Don't execute on target.
+ (GMP_PROG_CC_FIND): Before checking if the compiler knows how to
+ produce 64-bit code, verify that it works at all. The background
+ is that /usr/ucb/cc on Solaris 7 successfully compiles in 64-bit
+ mode but fails when doing final link.
+ (GMP_PROG_CC_WORKS): Report to user what's happening.
+
+2000-05-17 Linus Nordberg <linus@swox.se>
+
+ * config.guess: Use X86CPU for x86 Cygwin.
+
+2000-05-16 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/p6/mmx/divrem_1.asm: New file.
+ * mpn/x86/p6/mmx/mod_1.asm: New file.
+ * mpn/x86/p6/README: Update.
+ * mpn/x86/divrem_1.asm: Update comments.
+ * mpn/x86/mod_1.asm: Ditto.
+
+2000-05-14 Kevin Ryde <kevin@swox.se>
+
+ * tune/speed.h: Run gcd functions on a set of data.
+
+ * mpn/tests/try.c: New file.
+ * mpn/tests/try.h: New file.
+ * mpn/tests/spinner.c: New file.
+ * mpn/tests/trace.c: New file.
+ * mpn/tests/x86call.asm: New file.
+ * mpn/tests/x86check.c: New file.
+ * mpn/tests/ref.c (refmpn_hamdist): Allow size==0.
+ (refmpn_gcd): New function, and other additions supporting it.
+ * mpn/tests/ref.h: More prototypes.
+ * mpn/tests/Makefile.am: Add try program, use ansi2knr.
+
+ * mpn/x86/k7/mmx/popham.asm: New file.
+ * mpn/x86/k6/mmx/popham.asm: New file.
+ * mpn/x86/k6/sqr_basecase.asm: Unroll the addmul, for approx 1.3x
+ speedup above 15 limbs.
+ * mpn/x86/k7/README: Update.
+ * mpn/x86/k6/README: Update, and add notes on plain K6 and pre-CXT
+ K6-2 problems.
+ * configure.in (k6*-*-*, athlon-*-*): Add popham.
+
+ * mpn/x86/pentium/diveby3.asm: New file.
+ * mpn/x86/pentium/README: Update.
+
+ * gmp.texi (Installing GMP): Add note on bad OpenBSD 2.6 m4.
+ (Reporting Bugs): Ask for config.m4 if asm file related.
+ (I/O of Rationals): New section, add mpq_out_str.
+ (References): Add url for on-line gcc manuals.
+ A few node and menu updates.
+
+ * INSTALL: Better command line argument checking for test progs.
+ Change MP -> GMP.
+
+ * configure.in (WANT_ASSERT, USE_STACK_ALLOC, HAVE_PENTIUM_RDTSC):
+ Put descriptions here, not in acconfig.h.
+ (CALLING_CONVENTIONS_OBJS): New AC_SUBST (for mpn/tests/try).
+ (HAVE_CALLING_CONVENTIONS): New AC_DEFINE.
+ (AC_CHECK_HEADERS): Add sys/time.h.
+ (AC_CHECK_FUNCS): Add getpagesize, setitimer.
+ (KARATSUBA_SQR_THRESHOLD): Strip trailing comments from the
+ #define when passing through to config.m4.
+ * acconfig.h (PACKAGE, VERSION, WANT_ASSERT, USE_STACK_ALLOC,
+ HAVE_PENTIUM_RDTSC): No need for #undefs, autoheader gets them
+ from configure.in.
+
+ * acinclude.m4 (GMP_PROG_M4): Check for broken OpenBSD 2.6 m4
+ eval(), put messages into config.log.
+ * mpn/asm-defs.m4: Add notes and test for OpenBSD 2.6 m4.
+
+ * mpq/out_str.c: New file.
+ * mpq/Makefile.am (libmpq_la_SOURCES): Add it.
+ * Makefile.am (MPQ_OBJECTS): Ditto.
+ * gmp.h (mpq_out_str): New define and prototype.
+
+2000-05-12 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (CONFIG_TOP_SRCDIR): Fix to use $srcdir not
+ $top_srcdir (which doesn't exist).
+ * acinclude.m4 (GMP_C_ANSI2KNR): Fix setting U=_.
+ * gmp-impl.h (mpn_com_n, MPN_LOGOPS_N_INLINE): Fix missing "do"
+ (not currently used, probably no ill effect anyway).
+
+2000-05-11 Torbjorn Granlund <tege@swox.com>
+
+ * randraw.c (lc): Major overhaul (pending rewrite).
+ (_gmp_rand): Rewrite.
+
+2000-05-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/convert.c: Call free via _mp_free_func.
+ * mpf/tests/t-conv.c: Likewise.
+
+ * memory.c: Add code enabled for DEBUG that adds special patterns
+ around allocated blocks.
+
+2000-05-05 Linus Nordberg <linus@swox.se>
+
+ * gmp.texi (Miscellaneous Float Functions): Correct parameter list
+ for mpf_urandomb().
+
+ * configure.in: Invoke AC_REVISION.
+
+2000-05-05 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi: Use @dircategory and @direntry.
+ (Installing GMP): Clarification for --target, updates on SunOS
+ problems.
+ (Integer Arithmetic): Add mpz_mul_si.
+ (Initializing Rationals): Add mpq_swap.
+ (Assigning Floats): Add mpf_swap.
+ (Low-level Functions): Add mpn_divexact_by3c, and details of what
+ the calculation actually gives.
+ (Low-level Functions): Note extra space needed by mpn_gcdext,
+ clarify the details a bit.
+
+ * compat.c: New file, entry points for upward binary compatibility.
+ (mpn_divexact_by3): Compatibility function.
+ * Makefile.am (libgmp_la_SOURCES): Add compat.c.
+
+ * mpn/tests/ref.c: Rearrange macros for ansi2knr.
+ (div1): Renamed from div to avoid library function.
+ (refmpn_divexact_by3c, refmpn_gcd_1, refmpn_popcount,
+ refmpn_hamdist): New functions.
+ * mpn/tests/ref.h: Add extern "C", add new prototypes.
+
+ * gmp.h (gmp_randinit, etc): Add extern "C".
+ (_mpq_cmp_ui): Fix prototype name from mpq_cmp_ui.
+ (mpn_divexact_by3): Now a macro calling mpn_divexact_by3c.
+ (mpn_divexact_by3c): New prototype and define.
+
+ * mpn/x86/diveby3.asm: Change to mpn_divexact_by3c.
+ * mpn/x86/k6/diveby3.asm: Ditto.
+ * mpn/generic/diveby3.c: Ditto.
+ * mpn/asm-defs.m4: Ditto on the define_mpn.
+ * acconfig.h (HAVE_NATIVE_mpn_divexact_by3c): New define.
+
+ * mpq/swap.c: New file, derived from mpz/swap.c.
+ * mpf/swap.c: Ditto.
+ * mpq/Makefile.am: Add swap.c.
+ * mpf/Makefile.am: Ditto.
+ * Makefile.am: Add two new "swap.lo"s.
+
+ * mpn/x86/k6/mmx/com_n.asm: Fix an addressing bug (fortunately
+ this code hasn't been used anywhere yet).
+
+ * mpn/x86/k7/mmx/divrem_1.asm: New file.
+ * mpn/x86/k7/mmx/mod_1.asm: New file.
+ * mpn/x86/k7/diveby3.asm: New file.
+ * mpn/x86/k7/README: Update.
+
+ * mpn/x86/k7/aorsmul_1.asm: Use new cmovCC, no object code change.
+ * mpn/x86/k7/mul_basecase.asm: Ditto.
+ * mpn/x86/p6/aorsmul_1.asm: Ditto.
+
+ * mpn/x86/x86-defs.m4 (defframe_empty_if_zero): Eval the argument.
+ (cmovCC): New macros, replacing individual cmovCC_reg_reg forms.
+ (Zdisp): Recognise more instructions.
+ (shldl,etc): Use m4_instruction_wrapper().
+ (ASSERT, movl_text_address): New macros.
+
+ * mpn/asm-defs.m4: Add remarks on SunOS /usr/bin/m4 and new
+ OpenBSD m4.
+ (m4_assert_numargs_internal_check): Remove a spurious parameter.
+ (m4_empty_if_zero): Eval the argument.
+ (m4_assert, m4_assert_numargs_range, m4_config_gmp_mparam,
+ m4_instruction_wrapper): New macros.
+
+2000-05-04 Linus Nordberg <linus@swox.se>
+
+ * gmp.texi (Reporting Bugs): Be explicit about output from running
+ a command.
+
+2000-05-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/bz_divrem_n.c (mpn_bz_divrem_n): Handle non-zero return
+ from first mpn_bz_div_3_halves_by_2 call.
+ (mpn_bz_divrem_aux): Likewise.
+
+2000-04-30 Kevin Ryde <kevin@swox.se>
+
+ * tune/* (GCD_ACCEL_THRESHOLD, GCDEXT_THRESHOLD): Tune these.
+
+ * mpn/generic/gcdext.c (GCDEXT_THRESHOLD): Rename from THRESHOLD,
+ use with >=, adjust default to 17 accordingly.
+ Use new *_SWAP macros.
+
+ * mpn/generic/gcd.c (GCD_ACCEL_THRESHOLD): Rename from
+ ACCEL_THRESHOLD, use with >=, adjust default to 5 accordingly.
+ Use new *_SWAP macros.
+
+ * mpf/get_str.c, mpf/set_str.c, mpf/sub.c, mpz/add.c, mpz/ior.c,
+ mpz/and.c, mpz/sub.c, mpz/xor.c, mpz/ui_pow_ui.c,
+ mpn/generic/mul.c: Use new *_SWAP macros.
+
+ * stack-alloc.h: Add extern "C" around prototypes.
+
+ * gmp-impl.h: (MP_PTR_SWAP, etc): New macros.
+ (_mp_allocate_func, etc): Use _PROTO.
+ [TUNE_PROGRAM_BUILD]: More changes in tune program build part.
+
+2000-04-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/pa64/add_n.s: Add `,entry' to export directive.
+ * mpn/pa64/addmul_1.S, mpn/pa64/lshift.s, mpn/pa64/mul_1.S,
+ mpn/pa64/rshift.s, mpn/pa64/sub_n.s, mpn/pa64/submul_1.S,
+ mpn/pa64/umul_ppmm.S: Likewise.
+ * mpn/hppa/hppa1_1/udiv_qrnnd.S: New name for udiv_qrnnd.s.
+ Add PIC support.
+
+2000-04-29 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h [TUNE_PROGRAM_BUILD] (TOOM3_MUL_THRESHOLD_LIMIT): New
+ define.
+ * mpn/generic/mul_n.c [TUNE_PROGRAM_BUILD] (mpn_mul_n): Use
+ TOOM3_MUL_THRESHOLD_LIMIT, not a hard coded 500.
+
+ * memory.c: Use <stdlib.h> for malloc etc, and use _PROTO.
+ * stack-alloc.c: Don't use C++ reserved word "this".
+ * urandom.h: Put extern "C" around prototypes.
+ * mpz/powm.c: Switch a couple of parameters to "const", which they
+ are, to satisfy g++.
+
+ * randraw.c, stack-alloc.c, mpbsd/mout.c, mpbsd/mtox.c: Add casts to
+ help g++.
+
+ * stack-alloc.c: Provide dual ANSI/K&R function definitions.
+ * mpz/addmul_ui.c,get_d.c,inp_str.c,perfpow.c,powm.c,pprime_p.c,
+ rrandomb.c,set_str.c,ui_pow_ui.c: Ditto.
+ * mpf/integer.c,set_str.c: Ditto.
+ * mpbsd/min.c,xtom.c: Ditto.
+ * mpn/generic/bz_divrem_n.c,dump.c,gcd_1.c,get_str.c,hamdist.c,
+ popcount.c,random.c,random2.c,set_str.c: Ditto.
+
+ * rand.c: Use <stdio.h> for NULL.
+ * mpz/gcd_ui.c,gcdext.c,mul.c,perfpow.c,powm_ui.c,root.c,sqrt.c,
+ sqrtrem.c: Ditto
+ * mpf/sqrt.c,sqrt_ui.c: Ditto.
+ * mpn/generic/perfsqr.c,sqrtrem.c: Ditto.
+
+ * gmp-impl.h (NULL, malloc, realloc, free): Don't define/declare.
+ (extern "C"): Add around function prototypes.
+ (mpn_kara_mul_n, mpn_kara_sqr_n, mpn_toom3_mul_n, mpn_toom3_sqr_n):
+ Add prototypes.
+ [TUNE_PROGRAM_BUILD] (FIB_THRESHOLD): Add necessary redefinitions for
+ use by tune program.
+ * mpn/generic/mul_n.c: Remove mpn_toom3_mul_n prototype.
+
+ * acinclude.m4 (GMP_C_ANSI2KNR): New macro.
+ (GMP_CHECK_ASM_MMX, GMP_CHECK_ASM_SHLDL_CL): Fix to use
+ $gmp_cv_check_asm_text which is what GMP_CHECK_ASM_TEXT sets.
+ * configure.in (GMP_C_ANSI2KNR): Use this instead of AM_C_PROTOTYPES,
+ for reasons described with its definition.
+
+ * demos/Makefile.am (ansi2knr): Use $(top_builddir) nor $(top_srcdir).
+
+ * mpz/fib_ui.c (FIB_THRESHOLD): Rename from FIB_THRES, for consistency.
+ (FIB_THRESHOLD): Conditionalize so gmp-mparam.h can define a value.
+ (mpz_fib_bigcase): Use >= FIB_THRESHOLD, same as main mpz_fib_ui.
+ * tune/tuneup.c,Makefile.am (FIB_THRESHOLD): Tune this.
+
+ * configure.in (*-*-aix* gmp_m4postinc): Fix setting (don't overwrite
+ a value just stored).
+
+2000-04-26 Kevin Ryde <kevin@swox.se>
+
+ * mpn/sparc32/udiv_fp.asm: Use mpn_udiv_qrnnd macro.
+ * mpn/sparc32/udiv_nfp.asm: Ditto.
+ * mpn/sparc32/v8/supersparc/udiv.asm: Ditto.
+ * mpn/sparc32/umul.asm: Name the function mpn_umul_ppmm.
+ * mpn/sparc32/v8/umul.asm: Ditto.
+ * mpn/powerpc32/umul.asm: Ditto.
+
+ * mpn/x86/syntax.h: Remove file, since now unused.
+
+ * configure.in (x86): Remove -DBROKEN_ALIGN and -DOLD_GAS
+ previously used by .S files.
+ (x86 extra_functions): Add udiv and umul.
+ (GMP_PROG_M4): Use this instead of AC_CHECK_PROG(M4,m4,...)
+ (HAVE_NATIVE_*): Loosen up the regexp to "PROLOGUE.*" so as to
+ accept PROLOGUE_GP on alpha.
+
+ * acconfig.h (HAVE_NATIVE_mpn_umul_ppmm, udiv_qrnnd, invert_limb):
+ New template defines.
+ * mpn/asm-defs.m4 (mpn_umul_ppmm, mpn_udiv_qrnnd): New define_mpn()s.
+ * longlong.h (umul_ppmm, udiv_qrnnd): Use a library version if
+ it's available and an asm macro isn't.
+ * gmp-impl.h (invert_limb): Ditto.
+
+ * gmp-impl.h (ASSERT_NOREALLOC): Not a good idea, remove it.
+
+ * acinclude.m4 (GMP_PROG_M4): New macro.
+
+2000-04-25 Linus Nordberg <linus@swox.se>
+
+ * gmp.texi (Random State Initialization): Correct arguments to
+ `gmp_randinit'.
+
+ * acinclude.m4 (GMP_VERSION): Change `eval' --> `m4_eval'. Fix
+ from Kevin.
+ * aclocal.m4: Regenerate.
+
+2000-04-25 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/aors_n.asm: Remove parentheses around an immediate that
+ Solaris "as" doesn't like, change by Torbjorn.
+
+2000-04-24 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (AC_CHECK_FUNCS): Add strtoul.
+
+ * mpn/generic/mul_n.c [TUNE_PROGRAM_BUILD] (mpn_mul_n): Bigger
+ array for karatsuba temporary space for tune program build.
+ (mpn_toom3_sqr_n) Remove an unused variable.
+
+ * demos/Makefile.am (AUTOMAKE_OPTIONS): Add ansi2knr.
+ Add "allprogs:" pseudo-target.
+ * demos/factorize.c, demos/isprime.c: Switch to ANSI functions,
+ rely on ansi2knr.
+
+ * gmp.texi (Getting the Latest Version of GMP): Add reference to
+ ftp.gnu.org mirrors list.
+ * INSTALL: Add arg count check to example programs.
+
+ * mpn/x86/*/*.asm: Convert to FORTRAN ... or rather to
+ FORTRAN-style "C" commenting to support Solaris "as".
+ * mpn/x86/x86-defs.m4: Ditto, and add another Zdisp insn.
+ * mpn/asm-defs.m4 (C): Update comments.
+ * mpn/x86/README.family: Add a note on commenting, remove
+ description of .S files.
+
+ * mpn/sparc64/addmul_1.asm, mul_1.asm, submul_1.asm: Use
+ include_mpn().
+
+2000-04-23 Torbjorn Granlund <tege@swox.com>
+
+ * config.sub: Merge with FSF version of April 23.
+
+ * mpn/powerpc32: Use dnl/C instead of `#' for comments.
+
+ * config.guess: Get "model" limit between pentium 2 and pentium3 right.
+ Get rid of code determining `_' prefix; use double labels instead.
+ * config.guess: Partially merge with FSF version of April 22.
+ (Don't bring over NetBSD changes for now.)
+
+2000-04-23 Kevin Ryde <kevin@swox.se>
+
+ * tune/Makefile.am, tune/README, tune/common.c, tune/rdtsc.asm,
+ tune/speed.c, tune/speed.h, tune/time.c, tune/tuneup.c: New files.
+ * tune/Makefile.in: New file, generated from Makefile.am.
+
+ * gmp-impl.h (ASSERT_NOREALLOC,TMP_ALLOC_LIMBS): New macros.
+ [TUNE_PROGRAM_BUILD] Further mods for tune program builds.
+
+ * mpz/Makefile.am: Add -DOPERATION_$* for new mul_siui.c.
+ Add rules to build mul_si and mul_ui from a common mul_siui.c.
+ * mpz/mul_siui.c: New file, derived from and replacing mul_ui.c.
+ * gmp.h (mpz_mul_si): New prototype and define.
+
+ * mpn/tests/*.c [__i386__] (CLOCK): Don't use floating point in
+ CLOCK because cpp can't handle floats in #if's (TIMES is derived
+ from CLOCK by default).
+
+ * mpn/asm-defs.m4 (include_mpn): New macro.
+ (m4_assert_numargs) Changes to implementation.
+
+ * mpf/Makefile.am: Add -DOPERATION_$* for new integer.c.
+ Remove explicit rules for floor.o etc.
+ * mpf/integer.c: Use OPERATION_$* for floor/ceil/trunc.
+
+ * mpn/Makefile.am: Put "tests" in SUBDIRS.
+ * mpn/tests/Makefile.am: New file providing rules to build test
+ programs, nothing done in a "make all" or "make check" though.
+ * mpn/tests/README: New file.
+
+ * acconfig.h (HAVE_PENTIUM_RDTSC): New define.
+
+ * configure.in (x86): Rearrange target cases.
+ Add mulfunc aors_n and aorsmul_1 for x86 and pentium (now all x86s).
+ Remove asm-syntax.h generation not needed.
+ Remove now unused family=x86.
+ (sparc) Remove unused family=sparc.
+ (HAVE_PENTIUM_RDTSC) New AC_DEFINE and AM_CONDITIONAL.
+ (AM_C_PROTOTYPES) New test, supporting ansi2knr.
+ (AC_CHECK_HEADERS) Add getopt.h, unistd.h and sys/sysctl.h for
+ tune progs.
+ (AC_CHECK_FUNCS) Add getopt_long, sysconf and sysctlbyname for
+ tune progs.
+ (config.m4 CONFIG_TOP_SRCDIR) Renamed from CONFIG_SRCDIR.
+ (config.m4 asm-defs.m4) Use CONFIG_TOP_SRCDIR and include().
+ (gmp_m4postinc) Use include_mpn().
+ (gmp_links) Omit asm-defs.m4/asm.m4 and gmp_m4postinc's.
+ (MULFUNC_PROLOGUE) Fix regexps so all functions get AC_DEFINE'd.
+ (PROLOGUE) Ditto (native copyi and copyd were unused in gmp 3).
+ (KARATSUBA_SQR_THRESHOLD) Copy from gmp-mparam.h into config.m4.
+ (AC_OUTPUT) Add tune/Makefile, mpn/tests/Makefile.
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Add ansi2knr.
+ (SUBDIRS): Add tune, reorder directories.
+ (MPZ_OBJECTS): Add mpz/mul_si.lo.
+ (libmp_la_SOURCES): Use this for top-level objects, not .lo's.
+ * ansi2knr.c, ansi2knr.1: New files, provided by automake.
+
+ * mpn/x86/aors_n.asm: Convert add_n.S and sub_n.S to a
+ multi-function aors_n.asm, no object code change.
+ * mpn/x86/pentium/aors_n.asm: Ditto.
+ * mpn/x86/aorsmul_1.asm: Ditto for addmul/submul.
+ * mpn/x86/pentium/aorsmul_1.asm: Ditto.
+
+ * mpn/x86/lshift.asm, mpn/x86/mul_1.asm, mpn/x86/mul_basecase.asm,
+ mpn/x86/rshift.asm: Convert from .S, no object code change.
+ * mpn/x86/pentium/lshift.asm, mpn/x86/pentium/mul_1.asm,
+ mpn/x86/pentium/mul_basecase.asm, mpn/x86/pentium/rshift.asm: Ditto.
+
+ * gmp.texi (Reporting Bugs): Itemize the list of things to include.
+ (Miscellaneous Float Functions): Correct typo in mpf_ceil etc
+ argument types.
+ Change @ifinfo -> @ifnottex for benefit of makeinfo --html.
+ Remove unnecessary @iftex's around @tex.
+
+2000-04-22 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Generalize x86 cpu determination code.
+ Now works on Solaris.
+
+ * mpz/nextprime.c: Rewrite still disabled code.
+
+ * configure.in: Specifically match freebsd[3-9].
+
+2000-04-21 Torbjorn Granlund <tege@swox.com>
+
+ * rand.c: Call mpz_clear for otherwise leaking mpz_t.
+
+ * mpz/pprime_p.c (mpz_probab_prime_p): Merge handling of negative
+ n into code for handling small positive n. Merge variables m and n.
+ After dividing, simply call mpz_millerrabin.
+ (isprime): Local variables now use attribute `long'.
+ (mpz_millerrabin): New static function, based on code from
+ mpz_probab_prime_p.
+ (millerrabin): Now simple workhorse for mpz_millerrabin.
+
+2000-04-19 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h: Fix parenthesis error in test for __APPLE_CC__.
+
+2000-04-18 Linus Nordberg <linus@swox.se>
+
+ * NEWS: Add info about shared libraries. Remove reference to
+ gmp_randinit_lc.
+
+2000-04-17 Torbjorn Granlund <tege@swox.com>
+
+ * Version 3.0 released.
+
+ * mpn/arm/add_n.S: New version from Robert Harley.
+ * mpn/arm/addmul_1.S: Likewise.
+ * mpn/arm/mul_1.S: Likewise.
+ * mpn/arm/sub_n.S: Likewise.
+
+ * gmp.h (__GNU_MP_VERSION_PATCHLEVEL): Now 0.
+
+2000-04-17 Linus Nordberg <linus@swox.se>
+
+ * configure.in (hppa2.0*-*-*): Pass `+O3' to cc/c89 in 64-bit mode
+ to avoid compiler bug.
+ (ns32k*-*-*): Fix typo in path. Change by Kevin.
+ (alpha*-*-osf*): New case. Pass assembly flags for architecture
+ to gcc.
+ (alpha*-*-*): Don't bother searching for cc.
+ * configure: Regenerate.
+
+ * Makefile.am (EXTRA_DIST): Add `macos', `.gdbinit'.
+ * Makefile.in: Regenerate.
+ * mpn/Makefile.am (EXTRA_DIST): Add `m88k', `lisp'.
+ * mpn/Makefile.in: Regenerate.
+
+2000-04-16 Kevin Ryde <kevin@swox.se>
+
+ * README: Updates, and don't duplicate the example in INSTALL.
+ * INSTALL: Minor updates.
+ * gmp.texi (Installing MP): Minor edits, restore CC/CFLAGS description.
+
+2000-04-16 Linus Nordberg <linus@swox.se>
+
+ * configure.in (*-*-cygwin*): Select BSD_SYNTAX to avoid
+ .type/.size in PROLOGUE for ELF_SYNTAX. Override ALIGN definition
+ from x86/syntax.h.
+ (gmp_xoptcflags_${CC}): New set of variables, indicating
+ ``exclusive optional cflags''.
+ (most sparcs): Use gmp_xoptcflags instead of gmp_optcflags to
+ ensure that we pass CPU type to older gcc.
+ (CFLAGS): CFLAGS on the command line was spoiled.
+ * configure: Regenerate.
+
+2000-04-16 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Invoke AC_PROG_LIBTOOL directly.
+
+ * acinclude.m4 (GMP_PROG_CC_FIND): Quote source variable when
+ setting CC64 and CFLAGS64.
+ (GMP_PROG_CC_SELECT): Cache result.
+ (GMP_PROG_LIBTOOL): Remove.
+
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+2000-04-16 Linus Nordberg <linus@swox.se>
+
+ * tests/rand/t-rand.c (main): Add non-ANSI function declaration.
+ Don't use `const'.
+
+2000-04-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/dump.c: Suppress output of leading zeros.
+
+ * mpz/inp_str.c: Fix memory leakage.
+
+ * mpz/tests/reuse.c (dss_func_division): Add a final 1.
+
+ * longlong.h (alpha count_leading_zeros): Wrap in __MPN.
+ * mpn/alpha/cntlz.asm: Use __gmpn prefix (by means of __MPN).
+
+ * longlong.h (__umul_ppmm, __udiv_qrnnd): Wrap in __MPN.
+ * mpn/alpha/udiv_qrnnd.S: Use __gmpn prefix.
+ * mpn/hppa/udiv_qrnnd.s: Likewise.
+ * mpn/hppa/hppa1_1/udiv_qrnnd.s: Likewise.
+ * mpn/pa64/udiv_qrnnd.c: Likewise (by means of __MPN).
+ * mpn/pa64/umul_ppmm.S: Likewise.
+ * mpn/sparc32/udiv_fp.asm: Likewise (by means of MPN).
+ * mpn/sparc32/udiv_nfp.asm: Likewise (by means of MPN).
+ * mpn/sparc32/v8/supersparc/udiv.asm: Likewise (by means of MPN).
+
+ * mpn/generic/tdiv_qr.c: Work around gcc 2.7.2.3 i386 register handling
+ bug.
+
+ * mpn/generic/tdiv_qr.c: Use udiv_qrnnd instead of mpn_divrem_1
+ when computing appropriate quotient; mpn_divrem_1 writes too
+ many quotient limbs.
+
+ * mpn/asm-defs.m4: invert_normalized_limb => invert_limb.
+ * mpn/alpha/invert_limb.asm: mpn_invert_normalized_limb =>
+ mpn_invert_limb.
+ * gmp.h: Likewise.
+ * gmp-impl.h (alpha specific): invert_normalized_limb => invert_limb;
+ wrap with __MPN.
+ * longlong.h (alpha udiv_qrnnd): Likewise.
+
+2000-04-16 Kevin Ryde <kevin@swox.se>
+
+ * gmp.h (mp_set_memory_functions,mp_bits_per_limb,gmp_errno): Add
+ #defines so the library symbols are __gmp_*.
+ * errno.c: Include gmp.h.
+ * gmp-impl.h (_mp_allocate_func,etc): Add #defines to __gmp_*.
+ (__clz_tab): New #define to __MPN(clz_tab).
+ * stack-alloc.c (__gmp_allocate_func,etc): Change from _mp_*.
+
+ * Makefile.am (libmp_la_DEPENDENCIES): Add some mpz files needed
+ for new mpz_powm (pow in libmp).
+ (EXTRA_DIST): Add projects directory.
+
+ * mpn/*: Change __mpn to __gmpn.
+ * gmp.h (__MPN): Ditto.
+ * stack_alloc.c,stack-alloc.h: Change __tmp to __gmp_tmp.
+
+ * mpn/generic/sb_divrem_mn.c (mpn_sb_divrem_mn): Avoid gcc 2.7.2.3
+ i386 register handling bug (same as previously in mpn_divrem_classic).
+
+ * mpn/generic/divrem.c: Now contains mpn_divrem, which is not an
+ internal function, so remove warning comment.
+
+ * gmp.texi (Compatibility with Version 2.0.x): Source level only.
+
+2000-04-16 Linus Nordberg <linus@swox.se>
+
+ * configure.in (hppa1.0*): Prefer c89 to cc.
+ * configure: Regenerate.
+
+2000-04-15 Linus Nordberg <linus@swox.se>
+
+ * configure.in: If `mpn_path' is set by user on configure command
+ line, use that as path.
+ * configure: Regenerate.
+
+2000-04-15 Linus Nordberg <linus@swox.se>
+
+ * configure.in (hppa2.0*): Use path "hppa/hppa1_1 hppa" if no
+ 64-bit compiler was found.
+ * configure: Regenerate.
+
+2000-04-15 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Honor `CC' and `CFLAGS' set by user on configure
+ command line.
+ * acinclude.m4: (GMP_PROG_CC_SELECT): Set CFLAGS if not set already.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+2000-04-15 Linus Nordberg <linus@swox.se>
+
+ * acinclude.m4 (GMP_PROG_CC_FIND): Remove debug output. Remove
+ commented out code.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+ * configure.in: Make all `-mcpu' options to gcc optional.
+ * configure: Regenerate.
+
+ * tests/rand/Makefile.am: Don't do anything for target 'all'.
+ * tests/rand/Makefile.in: Regenerate.
+
+2000-04-15 Kevin Ryde <kevin@swox.se>
+
+ * README: Small updates.
+ * NEWS: Add some things about 3.0.
+
+ * mpz/Makefile.am (EXTRA_DIST): Remove dmincl.c.
+
+ * Makefile.am: Use -version-info on libraries, not -release.
+
+ * mpz/tdiv_qr.c: Add mdiv function header #ifdef BERKELEY_MP.
+ * mpbsd/Makefile.am: Use mpz/tdiv_qr.c, not mdiv.c.
+ * Makefile.am (MPBSD_OBJECTS): Change mdiv.lo to tdiv_qr.lo.
+ (libmp_la_DEPENDENCIES): Add mp_clz_tab.lo.
+ * mpbsd/mdiv.c: Remove file.
+
+ * config/mt-linux,mt-m68k,mt-m88110,mt-ppc,mt-ppc64-aix,mt-pwr,
+ mt-sprc8-gcc,mt-sprc9-gcc,mt-supspc-gcc,mt-vax,mt-x86,
+ mpn/config/mt-pa2hpux,mt-sprc9,t-oldgas,t-ppc-aix,t-pwr-aix:
+ Remove configure fragments not used since change to autoconf.
+
+ * mpn/generic/bz_divrem_n.c,sb_divrem_mn.c: Add comment that
+ internal functions are changeable and shouldn't be used directly.
+
+2000-04-15 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Remove debug output.
+ * configure: Regenerate.
+
+2000-04-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/tdiv_qr.c: Don't use alloca directly.
+
+ * mpz/tdiv_qr.c: Fix typo.
+ * mpz/tdiv_r.c: Fix typo.
+ * mpz/tdiv_q.c: Fix typo.
+
+ * configure.in: Disable -march=pentiumpro due to apparent compiler
+ problems.
+
+ * mpz/powm.c: Replace with new code from Paul Zimmermann.
+
+ * mpz/tdiv_q.c: Remove debug code.
+
+ * mpn/generic/divrem.c: Remove C++ style `//' commented-out code.
+ * mpn/generic/sb_divrem_mn.c: Likewise.
+
+2000-04-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/cdiv_q.c: Change temp allocation for new requirements of
+ mpz_tdiv_qr.
+ * mpz/fdiv_q.c: Likewise.
+
+ * mpn/sparc64/gmp-mparam.h: Set up parameters for TOOM3.
+
+ * mpz/dmincl.c: Delete file.
+ * mpz/tdiv_qr.c: Rewrite using mpn_tdiv_qr.
+ * mpz/tdiv_r.c: Likewise.
+ * mpz/tdiv_q.c: Likewise.
+
+ * mpn/generic/tdiv_qr.c: New file.
+ * mpn/generic/bz_divrem_n.c: New file.
+ * mpn/generic/sb_divrem_mn.c: New file.
+
+ * gmp-impl.h (MPZ_REALLOC): New macro.
+ (mpn_sb_divrem_mn): Declare.
+ (mpn_bz_divrem_n): Declare.
+ (mpn_tdiv_qr): Declare.
+
+ * configure.in (gmp_mpn_functions): Delete divrem_newt and divrem_1n;
+ add tdiv_qr, bz_divrem_n, and sb_divrem_mn.
+ * mpn/generic/divrem_newt.c: Delete file.
+ * mpn/generic/divrem_1n.c: Delete file.
+
+ * gmp.h (mpn_divrem_newton): Remove declaration.
+ (mpn_divrem_classic): Remove declaration.
+
+ * gmp.h (mpn_divrem): Remove function definition.
+ * mpn/generic/divrem.c: Replace mpn_divrem_classic with a
+ mpn_divrem wrapper.
+
+2000-04-14 Kevin Ryde <kevin@swox.se>
+
+ * mpf/dump.c, mpz/dump.c, mpn/generic/dump.c,
+ mpn/generic/divrem.c, mpn/generic/divrem_1n.c,
+ mpn/generic/divrem_2.c, mpn/generic/divrem_newt.c,
+ mpn/generic/mul.c, mpn/generic/mul_basecase.c,
+ mpn/generic/mul_n.c, mpn/generic/sqr_basecase.c,
+ mpn/generic/udiv_w_sdiv.c: Add comment that internal functions are
+ changeable and shouldn't be used directly.
+
+ * mpq/div.c: Use DIVIDE_BY_ZERO (previously didn't get an
+ exception on zero divisor).
+
+ * mpf/tests/t-get_d.c, mpz/tests/reuse.c: Add K&R function
+ definitions.
+ * mpz/tests/t-2exp.c: Don't use ANSI-ism 2ul.
+
+ * gmp.texi (Installing MP): Build problem notes for GSYM_PREFIX
+ and ranlib on native SunOS.
+ Particular systems notes about AIX and HPPA shared libraries
+ disabled.
+ (MP Basics): Add that undocumented things shouldn't be used.
+ (Introduction to MP): Add to CPUs listed.
+
+ * acinclude.m4 (GMP_CHECK_ASM_UNDERSCORE): Don't depend on C
+ having "void".
+
+2000-04-13 Linus Nordberg <linus@swox.se>
+
+ * mpn/pa64/udiv_qrnnd.c (__udiv_qrnnd64): Add K&R function
+ definition.
+
+ * configure.in: Disable shared libraries for hppa*.
+ (mips-sgi-irix6.*): Fix flags for 64-bit gcc.
+ (hppa2.0*-*-*): Prefer c89 to cc.
+ * configure: Regenerate.
+
+ * gmp.h (gmp_randalg_t): Remove comma after last element.
+
+ * tests/rand/t-rand.c: Add copyright notice.
+
+2000-04-13 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/mul_n.c, mpn/generic/gcdext.c, mpz/nextprime.c,
+ mpz/remove.c, mpz/root.c: Add K&R function definitions.
+ * mpz/rrandomb.c: Fix typo in K&R part.
+ * stack-alloc.c: Add K&R style function pointer declarations.
+
+ * mpz/root.c: Use SQRT_OF_NEGATIVE on even roots of negatives.
+ Use DIVIDE_BY_ZERO on a "zero'th" root.
+
+ * configure: Regenerate with autoconf backpatched to fix --srcdir
+ absolute path wildcards that bash doesn't like, change by Linus.
+
+ * gmp.texi (Integer Arithmetic): Document mpz_nextprime.
+ (Miscellaneous Integer Functions): Fix mpz_fits_* formatting.
+ (Installing MP): Comment-out CC and CFLAGS description.
+
+2000-04-13 Linus Nordberg <linus@swox.se>
+
+ * rand.c (gmp_randinit): Don't combine va_alist with ordinary
+ arguments for non STDC.
+
+2000-04-13 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/nextprime.c: Use proper names of new random types and functions.
+
+ * mpz/rrandomb.c: New file.
+ * mpz/Makefile.am: List it.
+ * mpz/Makefile.in: Regenerate.
+ * Makefile.am: Here too.
+ * Makefile.in: Regenerate.
+ * gmp.h: Declare mpz_rrandomb.
+
+2000-04-12 Linus Nordberg <linus@swox.se>
+
+ * Makefile.am, demos/Makefile.am, mpbsd/Makefile.am,
+ mpbsd/tests/Makefile.am, mpf/Makefile.am, mpf/tests/Makefile.am,
+ mpn/Makefile.am, mpq/Makefile.am, mpq/tests/Makefile.am,
+ mpz/Makefile.am, mpz/tests/Makefile.am, tests/Makefile.am,
+ tests/rand/Makefile.am (AUTOMAKE_OPTIONS): Add 'no-dependencies'.
+
+ * Makefile.in, demos/Makefile.in, mpbsd/Makefile.in,
+ mpbsd/tests/Makefile.in, mpf/Makefile.in, mpf/tests/Makefile.in,
+ mpn/Makefile.in, mpq/Makefile.in, mpq/tests/Makefile.in,
+ mpz/Makefile.in, mpz/tests/Makefile.in, tests/Makefile.in,
+ tests/rand/Makefile.in: Regenerate.
+
+2000-04-12 Linus Nordberg <linus@swox.se>
+
+ * randlc.c (gmp_randinit_lc): Disable function.
+ * gmp.texi (Random State Initialization): Remove gmp_randinit_lc.
+
+ * acinclude.m4 (GMP_CHECK_CC_64BIT): Compiling an empty main
+ successfully with `-n32' will have to suffice on irix6.
+ * aclocal.m4: Regenerate.
+
+ * configure.in (sparc): Don't pass -D_LONG_LONG_LIMB to compiler.
+ (mips-sgi-irix6.*): Use compiler option `-n32' rather than `-64'
+ for 64-bit `cc'. Add options for gcc.
+ * configure: Regenerate.
+
+ * mpf/urandomb.c (mpf_urandomb): Add third parameter 'nbits'. If
+ 'nbits' doesn't make even limbs, shift up result before
+ normalizing.
+
+ * gmp.h (mpf_urandomb): Add parameter to prototype.
+
+ * mpf/urandom.c: Rename file to ...
+ * mpf/urandomb.c: ... this.
+ * Makefile.am (MPF_OBJECTS): Change urandom.lo --> urandomb.lo.
+ * Makefile.in: Regenerate.
+ * mpf/Makefile.am (libmpf_la_SOURCES): Change urandom.c --> urandomb.c.
+ * mpf/Makefile.in: Regenerate.
+
+ * config.in: Regenerate for HAVE_DECL_OPTARG.
+
+ * randraw.c (_gmp_rand): Fix bug with _LONG_LONG_LIMB.
+ (lc): Change return type.
+ Use one temporary storage instead of two.
+ Handle seed of size 0.
+ Avoid modulus operation in some cases.
+ Abort if M is not a power of 2.
+ Fix bug with 64-bit limbs.
+ Fix bug with small seed, small A and large M.
+
+ * tests/rand/gen.c (main): Include gmp.h. Remove macros MIN, MAX. Add
+ option '-q'. Don't demand argument N. Change parameters in call
+ to mpf_urandomb.
+
+ * tests/rand/t-rand.c: New file for testing random number generation.
+
+ * tests/rand/Makefile.am: Run t-rand for 'make check'.
+ (test, bigtest): Rename to manual-test, manual-bigtest.
+ * tests/rand/Makefile.in: Regenerate.
+
+2000-04-12 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h: Include config.h before TMP_ALLOC, so
+ --disable-alloca works.
+
+ * mpbsd/Makefile.am: Don't recompile top-level sources here.
+ * Makefile.am (libmp_la_DEPENDENCIES): Put objects here instead,
+ add errno.lo and stack-alloc.lo.
+
+ * mpn/asm-defs.m4: Add a test and message for the unsuitable SunOS m4.
+ * gmp.texi (Installing MP): Update note on SunOS m4 failure.
+
+ * acconfig.h: Add copyright notice using @TOP@.
+
+ * stack-alloc.c: Use _mp_allocate_func, not malloc.
+ * gmp.texi (Installing MP): Note this under --disable-alloca.
+
+ * gmp.texi (Comparison Functions): mpz_cmp_abs => mpz_cmpabs.
+ (Integer Arithmetic): mpz_prime_p not yet implemented, comment out.
+ (Float Arithmetic): mpf_pow_ui now implemented, uncomment-out.
+ (Miscellaneous Float Functions): Add mpf_ceil, mpf_floor, mpf_trunc.
+ (Low-level Functions): Add mpn_random2, with mpn_random.
+
+ * mpn/m68k/mc68020/udiv.S: Rename from udiv.s.
+ * mpn/m68k/mc68020/umul.S: Ditto.
+
+ * mpn/alpha/umul.asm: Rename from umul.s, remove .file and
+ compiler identifiers.
+
+ * mpn/powerpc32/syntax.h: Removed, no longer used.
+
+ * mpn/a29k/udiv.s: Remove .file and compiler identifiers.
+ * mpn/a29k/umul.s: Ditto.
+
+ * mpn/tests/ref.c: Use WANT_ASSERT.
+ * mpn/tests/ref.h: Use _PROTO.
+
+ * mpbsd/configure.in: Removed, no longer required.
+
+ * mpf/div.c: Use DIVIDE_BY_ZERO.
+ * mpf/div_ui.c: Ditto.
+ * mpf/ui_div.c: Ditto.
+ * mpq/inv.c: Ditto.
+ * mpf/sqrt.c: Use SQRT_OF_NEGATIVE.
+ * mpz/sqrt.c: Ditto.
+ * mpz/sqrtrem.c: Ditto.
+
+ * gmp-impl.h (GMP_ERROR,SQRT_OF_NEGATIVE): New macros.
+ (DIVIDE_BY_ZERO): Use GMP_ERROR.
+ (__mp_bases): #define to __MPN(mp_bases).
+
+2000-04-11 Linus Nordberg <linus@swox.se>
+
+ * tests/rand/stat.c (main): Initialize `l1runs' at declaration.
+
+2000-04-11 Kevin Ryde <kevin@swox.se>
+
+ * mpz/fib_ui.c: Add K&R function definitions.
+
+ * mpbsd/tests/Makefile.am (TESTS): Add a dummy test to avoid a
+ shell problem with an empty "for tst in $(TESTS) ; ...".
+ * mpbsd/tests/dummy.c: New file.
+
+2000-04-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/bin_uiui.c: Delete several unused variables.
+ Add copyright notice.
+ * mpz/bin_ui.c: Add copyright notice.
+
+ * longlong.h: Declare __count_leading_zeros for alpha.
+
+2000-04-10 Linus Nordberg <linus@swox.se>
+
+ * rand.c (gmp_randinit): Change parameter list to (rstate, alg, ...).
+ * gmp.h: Change prototype accordingly.
+ * mpz/pprime_p.c (millerrabin): Change call accordingly.
+
+ * configure.in: Check for `optarg'.
+ * configure: Regenerate.
+
+ * mpn/Makefile.am: Remove incorrect comment.
+ * mpn/Makefile.in: Regenerate.
+
+ * gmp.h: Rename most of the random number functions, structs and some
+ of the struct members.
+ * rand.c (gmp_randinit): Likewise.
+ * randclr.c (gmp_randclear): Likewise.
+ * randlc.c (gmp_randinit_lc): Likewise.
+ * randlc2x.c (gmp_randinit_lc_2exp): Likewise.
+ * randraw.c (lc): Likewise.
+ (_gmp_rand_getraw): Likewise.
+ * randsd.c (gmp_randseed): Likewise.
+ * randsdui.c (gmp_randseed_ui): Likewise.
+ * gmp.texi: Likewise.
+
+ * gmp.texi: Use three hyphens for a dash.
+ (Low-level Functions): Remove documentation for gmp_rand_getraw.
+ (Random Number Functions): Add info on where to find documentation
+ on the random number functions.
+
+ * tests/rand/Makefile.am (test, bigtest): Quote argument to grep.
+ * tests/rand/Makefile.in: Regenerate.
+
+ * tests/rand/gen.c: Declare optarg, optind, opterr if not already
+ declared.
+ (main): Use new names for the random stuff.
+ (main): Don't use strtoul() if we don't have it. Use strtol()
+ instead, if we have it. Otherwise, use atoi().
+ (main): Use srandom/srandomdev for __FreeBSD__ only.
+ (main): Use new parameter order to gmp_randinit().
+
+ * tests/rand/stat.c: Declare optarg, optind, opterr if not already
+ declared.
+
+2000-04-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/pprime_p.c: Pass 0L for mpz_scan1. mpz_mmod => mpz_mod.
+ (millerrabin): Use new random interface.
+ (millerrabin): ... and don't forget to call gmp_randclear.
+
+ * mpz/nextprime.c: New file.
+ * gmp.h: Declare mpz_nextprime.
+ * mpz/Makefile.am: List nextprime.c.
+ * mpz/Makefile.in: Regenerate.
+ * Makefile.am: List mpz/nextprime.lo.
+ * Makefile.in: Regenerate.
+
+2000-04-10 Kevin Ryde <kevin@swox.se>
+
+ * move-if-change, mpz/tests/move-if-change, mpq/tests/move-if-change,
+ mpf/tests/move-if-change: Remove, no longer used.
+
+ * Makefile.am (SUBDIRS): Add tests, demos, mpbsd.
+ (libmp.la): New target, conditional on WANT_MPBSD.
+ (libgmp_la_LIBADD): Add -lm.
+ (AUTOMAKE_OPTIONS): Add check-news.
+ (include_HEADERS): Setup to install gmp.h and possibly mp.h.
+ (DISTCLEANFILES): Add generated files.
+ (check): Remove explicit target (now uses check-recursive).
+
+ * configure.in: Use AM_CONFIG_HEADER.
+ Add --enable-mpbsd setting automake conditional WANT_MPBSD.
+ Output demos/Makefile, mpbsd/Makefile and mpbsd/tests/Makefile.
+
+ * mpz/Makefile.am: Add SUBDIRS=tests, shorten INCLUDES since now
+ using AM_CONFIG_HEADER.
+ * mpq/Makefile.am: Ditto.
+ * mpf/Makefile.am: Ditto, and add DISTCLEANFILES.
+ * mpn/Makefile.am: Shorten INCLUDES, amend some comments.
+ * mpz/tests/Makefile.am: Use TESTS and $(top_builddir).
+ * mpf/tests/Makefile.am: Ditto.
+ * mpq/tests/Makefile.am: Ditto.
+ * demos/Makefile.am: New file.
+
+ * mpbsd/Makefile.am: New file, derived from old mpbsd/Makefile.in.
+ * mpbsd/Makefile.in: Now generated from Makefile.am.
+ * mpbsd/realloc.c: Removed, use mpz/realloc.c instead.
+ * mpbsd/tests/Makefile.am: New file.
+ * mpbsd/tests/Makefile.in: New file, generated from Makefile.am.
+ * mpbsd/tests/allfuns.c: New file.
+
+ * gmp.texi (Top): Use @ifnottex, to help makeinfo --html.
+ (Installing MP): Describe --enable-mpbsd and demo programs.
+
+ * tests/rand/statlib.c: mpz_cmp_abs => mpz_cmpabs.
+
+ * tests/rand/Makefile.am (LDADD): Don't need -lm (now in libgmp.la).
+ (EXTRA_PROGRAMS): Not noinst_PROGRAMS.
+ (INCLUDES): Shorten to -I$(top_srcdir) now using AM_CONFIG_HEADER.
+
+2000-04-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/urandomm.c: Get type of count right.
+ Simplify computation of nbits.
+
+2000-04-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/urandomb.c: Fix reallocation condition.
+ Simplify size computation.
+
+2000-04-08 Linus Nordberg <linus@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_CC_64BIT): Add special handling for
+ HPUX.
+ (GMP_CHECK_ASM_W32): Ditto.
+ * aclocal.m4: Regenerate.
+
+ * mpn/Makefile.am: Use $(CCAS) for assembling.
+ (.asm.obj): Add rule.
+ * mpn/Makefile.in: Regenerate.
+
+ * gmp.texi (Miscellaneous Integer Functions): Fix typos.
+
+ * configure.in: Never pass `-h' to grep.
+ (mips-sgi-irix6.[2-9]*): Try to find 64-bit compiler.
+ (hppa1.0*-*-*): New flag for cc.
+ (hppa2.0*-*-*): Try to find 64-bit compiler. Chose path, set
+ CCAS.
+ * configure: Regenerate.
+
+2000-04-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/bin_ui.c: Don't depend on ANSI C features.
+ * mpz/bin_uiui.c: Likewise.
+
+ * Makefile.am (MPZ_OBJECTS): mpz/cmp_abs* => mpz/cmpabs*.
+ (MPQ_OBJECTS): Add mpq/set_d.lo.
+ (MPZ_OBJECTS): Add mpz/fits*.lo.
+ * Makefile.in: Regenerate.
+
+ * mpz/cmpabs.c: New name for mpz/cmp_abs.c.
+ * mpz/cmpabs_ui.c: New name for mpz/cmp_abs_ui.c.
+ * mpz/Makefile.am: Corresponding changes.
+ * mpz/Makefile.in: Regenerate.
+ * gmp.h: mpz_cmp_abs* => mpz_cmpabs*.
+
+ * mpz/addmul_ui.c (mpn_neg1): Don't depend on ANSI C features.
+
+ * mpz/invert.c: Use TMP_MARK since we invoke MPZ_TMP_INIT.
+
+ * gmp.h (mpq_set_d): Declare correctly.
+ (mpz_root): Use _PROTO.
+ (mpz_remove): Use _PROTO.
+ (mpf_pow_iu): Use _PROTO.
+
+ * mpn/asm-defs.m4 (MPN_PREFIX): Revert previous change.
+ * gmp.h (__MPN): Revert previous change.
+
+ * mpz/perfpow.c: De-ANSI-fy. Add copyright notice.
+
+ * mpz/set_d.c: Misc cleanups.
+
+ * mpq/set_d: New file.
+ * gmp.h: Declare mpq_set_d.
+ * mpq/Makefile.am: List set_d.c.
+ * mpq/Makefile.in: Regenerate.
+
+2000-04-07 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/fits_sint_p.c: New file.
+ * mpz/fits_slong_p.c: New file.
+ * mpz/fits_sshort_p.c: New file.
+ * mpz/fits_uint_p.c: New file.
+ * mpz/fits_ulong_p.c: New file.
+ * mpz/fits_ushort_p.c: New file.
+ * gmp.h: Declare mpz_fits_*.
+ * mpz/Makefile.am: List fits_* files.
+ * mpz/Makefile.in: Regenerate.
+
+2000-04-06 Kevin Ryde <kevin@swox.se>
+
+ * gmp.texi (Installing MP): Add known build problem SunOS 4.1.4 m4
+ failure.
+
+ * mpn/x86/pentium/gmp-mparam.h: Tune thresholds.
+ * mpn/x86/p6/gmp-mparam.h: Ditto.
+ * mpn/x86/k6/gmp-mparam.h: Tune thresholds, add UMUL_TIME, UDIV_TIME.
+ * mpn/x86/k7/gmp-mparam.h: Tune thresholds, amend UMUL_TIME.
+
+ * mpn/generic/mul_n.c (mpn_kara_mul_n): Add an ASSERT.
+ (mpn_kara_sqr_n): Add an ASSERT, use KARATSUBA_SQR_THRESHOLD.
+ (mpn_toom3_sqr_n): Eliminate second evaluate3.
+
+ * gmp-impl.h (mpn_com_n,MPN_LOGOPS_N_INLINE): Don't allow size==0.
+ (tune_mul_threshold,tune_sqr_threshold): Conditionalize
+ declarations on TUNE_PROGRAM_BUILD.
+
+ * mpn/generic/sqr_basecase.c: Add an assert.
+
+2000-04-05 Torbjorn Granlund <tege@swox.com>
+
+ * gmp.h, mpn/asm-defs.m4: List the same functions for __MPN, but
+ leave some commented out.
+
+ * gmp-impl.h (MPN_LOGOPS_N_INLINE): Optimize.
+ (mpn_com_n): Optimize.
+
+ * gmp.h (__MPN): Make it use __gmpn instead of __mpn for consistency.
+ * mpn/asm-defs.m4 (MPN_PREFIX): Likewise.
+
+ * gmp.h (GMP_ERROR_ALLOCATE): New errcode.
+
+ * gmp-impl.h (MPN_MUL_N_RECURSE): Delete.
+ (MPN_SQR_RECURSE): Delete.
+
+ * gmp-impl.h (TARGET_REGISTER_STARVED): New define.
+
+ * gmp-impl.h (mpn_kara_sqr_n): Remap with __MPN.
+ (mpn_toom3_sqr_n): Likewise.
+ (mpn_kara_mul_n): Likewise.
+ (mpn_toom3_mul_n): Likewise.
+ (mpn_reciprocal): Likewise.
+
+ * gmp-impl.h (__gmpn_mul_n): Remove declaration.
+ (__gmpn_sqr): Likewise.
+ * gmp.h (mpn_sqr_n): Declare/remap.
+ * mpn/generic/mul.c (mpn_sqr_n): New name for mpn_sqr.
+
+ * gmp.h (mpn_udiv_w_sdiv): Move __MPN remap from here...
+ * gmp-impl.h: ...to here.
+
+2000-04-05 Linus Nordberg <linus@swox.se>
+
+ * gmp.texi (Top): Add `Random Number Functions' to menu.
+ (Introduction to MP): Fix typo.
+ (MP Basics): Create menu for all sections. Move `Random Number
+ Functions' to its own chapter. Add nodes for all sections.
+ (Function Classes): Mention random generation functions under
+ miscellaneous.
+ (Miscellaneous Integer Functions): Update mpz_urandomb,
+ mpz_urandomm.
+ (Low-level Functions): Remove mpn_rawrandom.
+ (Random State Initialization): Update.
+
+ * mpf/urandom.c (mpf_urandomb): Remove SIZE parameter. Normalize
+ result correctly.
+
+ * gmp.h (mpf_urandomb): Remove SIZE parameter.
+
+ * randraw.c (gmp_rand_getraw): Handle the case where (1) the LC
+ scheme doesn't generate even limbs and (2) more than one LC
+ invocation is necessary to produce the requested number of bits.
+
+2000-04-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/mul_n.c (INVERSE_3): New name for THIRD, define for
+ any BITS_PER_MP_LIMB.
+ (MP_LIMB_T_MAX): New.
+ (mpn_divexact3_n): Remove.
+ (interpolate3): Use mpn_divexact_by3 instead of mpn_divexact3_n.
+
+2000-04-05 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h (KARATSUBA_MUL_THRESHOLD<2): Remove cpp test.
+ (tune_mul_threshold,tune_sqr_threshold): Add declarations, used in
+ development only.
+
+ * mpn/x86/k7/sqr_basecase.asm: New file, only a copy of k6 for now.
+
+2000-04-04 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (TOOM3_MUL_THRESHOLD): Provide default.
+ (TOOM3_SQR_THRESHOLD): Provide default.
+
+ * mpn/generic/mul_n.c: Rewrite (mostly by Robert Harley).
+ * mpn/generic/mul.c: Rewrite (mostly by Robert Harley).
+
+ * configure.in (sparcv9 64-bit OS): Set extra_functions.
+
+2000-04-04 Linus Nordberg <linus@swox.se>
+
+ * mpn/generic/rawrandom.c: Remove file and replace with randraw.c
+ on top level.
+ (mpn_rawrandom): Rename to gmp_rand_getraw.
+
+ * randraw.c: New file; essentially a copy of
+ mpn/generic/rawrandom.c.
+ (gmp_rand_getraw): New function (formerly known as mpn_rawrandom).
+
+ * mpz/urandomb.c (mpz_urandomb): Change mpn_rawrandom -->
+ gmp_rand_getraw.
+ * mpz/urandomm.c (mpz_urandomb): Ditto.
+ * mpf/urandom.c (mpf_urandomb): Ditto.
+
+ * gmp.h (gmp_rand_getraw): Add function prototype.
+ (mpn_rawrandom): Remove function prototype.
+
+ * Makefile.am (libgmp_la_SOURCES): Add randraw.c.
+ * Makefile.in: Regenerate.
+
+ * configure.in (gmp_mpn_functions): Remove rawrandom.
+ * configure: Regenerate.
+
+2000-04-04 Linus Nordberg <linus@swox.se>
+
+ * gmp.h (GMP_ERROR enum): Remove comma after last enumeration
+ since the AIX compiler (xlc) doesn't like that.
+
+ * randlc.c (gmp_rand_init_lc): Allocate enough space for seed to
+ hold any upcoming seed.
+ * randlc2x.c (gmp_rand_init_lc_2exp): Likewise.
+
+ * mpn/generic/rawrandom.c: Remove debugging code.
+ (mpn_lc): Don't reallocate seed.
+
+ * mpz/urandomm.c (mpz_urandomm): Implement function.
+
+ * mpz/urandomb.c (mpz_urandomb): Fix typo in function definition.
+
+2000-04-04 Kevin Ryde <kevin@swox.se>
+
+ * make.bat: Removed (no longer works, no longer supported).
+ * mpn/msdos/asm-syntax.h: Removed (was used only by make.bat).
+
+2000-04-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/brandom.c: New file, replacing random2.
+
+2000-04-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v9/submul_1.asm: Change some carry-form instructions
+ into their plain counterparts.
+
+ * mpn/sparc64/copyi.asm: Avoid executing ALIGN.
+
+ * mpn/sparc64/mul_1.asm: Handle overlap of rp/sp.
+ * mpn/sparc64/addmul_1.asm: Likewise.
+ * mpn/sparc64/submul_1.asm: Likewise.
+
+2000-04-01 Linus Nordberg <linus@swox.se>
+
+ * gmp.h: Fix function prototypes for randomization functions.
+ (__gmp_rand_lc_scheme_struct): Replace `m' with `m2exp'. Remove
+ unused `bits'.
+ (__gmp_rand_data_lc): Add `m2exp' as another way of representing
+ the modulus.
+ (__gmp_rand_state_struct): Remove unused `size'.
+
+ * rand.c (__gmp_rand_scheme): Use better multipliers. Remove test
+ schemes. Replace `m' with `m2exp'.
+ (gmp_rand_init): Change parameters and return type. Use `m2exp'
+ instead of `m'. Set `gmp_errno' on error. Disable BBS algorithm.
+
+ * randlc.c (gmp_rand_init_lc): Don't use malloc(). Change
+ parameters.
+
+ * randclr.c (gmp_rand_clear): Don't use free(). Disable BBS
+ algorithm. Set `gmp_errno' on error.
+
+ * randlc2x.c (gmp_rand_init_lc_2exp): New function.
+ * randsd.c (gmp_rand_seed): New function.
+ * randsdui.c (gmp_rand_seed_ui): New function.
+ * randlcui.c: Remove unused file.
+
+ * mpn/generic/rawrandom.c (mpn_rawrandom): Rewrite.
+ (mpn_lc): New static function.
+
+ * mpz/urandomb.c (mpz_urandomb): Use ABSIZ() instead of SIZ() for
+ determining size of ROP.
+
+ * mpf/urandom.c (mpf_urandomb): Add third parameter, nbits. (Not
+ used yet!)
+ Change parameter order to mpn_rawrandom().
+
+ * Makefile.am (libgmp_la_SOURCES): Add errno.c, randlc2x.c,
+ randsd.c, randsdui.c. Remove randui.c.
+ (MPZ_OBJECTS): Rename urandom.lo --> urandomb.lo. Add urandomm.lo.
+ * Makefile.in: Regenerate.
+
+ * mpz/Makefile.am (libmpz_la_SOURCES): Change urandom.c -->
+ urandomb.c. Add urandomm.c.
+ * mpz/Makefile.in: Regenerate.
+
+ * tests/rand/Makefile.am (noinst_PROGRAMS): Change findcl --> findlc.
+ Add gen.static.
+ * tests/rand/Makefile.in: Regenerate.
+
+ * tests/rand/gen.c (main): Add mpz_urandomm. Add command line options
+ `-C', `-m', extend `-a'. Use *mp*_*rand*() with new parameters. Call
+ gmp_rand_seed().
+
+2000-04-01 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_ASM_DATA): Plain .data for hpux.
+ * configure.in (CCAS): No CFLAGS, they're added when it's used.
+ (CONFIG_SRCDIR): New define for config.m4.
+ * mpn/sparc64/addmul_1.asm: Use it for an include().
+ * mpn/sparc64/submul_1.asm: Ditto.
+ * mpn/sparc64/mul_1.asm: Ditto.
+
+2000-03-31 Linus Nordberg <linus@swox.se>
+
+ * mpz/urandom.c: Rename to...
+ * mpz/urandomb.c: ...this.
+
+ * mpz/urandomb.c (mpz_urandomb): Change operand order in call to
+ mpn_rawrandom(). Use ABSIZ() instead of SIZ() when checking size
+ of ROP.
+
+ * mpz/urandomm.c: New file.
+
+2000-03-31 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_ASM_MMX): Give a warning when mmx code
+ will be omitted.
+
+2000-03-30 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/mul_1h.asm: New file.
+ * mpn/sparc64/addmul_1h.asm: New file.
+ * mpn/sparc64/submul_1h.asm: New file.
+ * mpn/sparc64/mul_1.asm: Rewrite.
+ * mpn/sparc64/addmul_1.asm: Rewrite.
+ * mpn/sparc64/submul_1.asm: Rewrite.
+
+2000-03-28 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v9/mul_1.asm: Fix typo in branch prediction.
+ * mpn/sparc32/v9/addmul_1.asm: Likewise.
+ * mpn/sparc32/v9/submul_1.asm: Likewise.
+
+2000-03-25 Kevin Ryde <kevin@swox.se>
+
+ * mpn/lisp/gmpasm-mode.el: Fix some comment detection, use custom,
+ fontify more keywords, turn into a standalone mode.
+
+ * stamp-vti: New file, generated together with version.texi.
+
+ * acinclude.m4 (GMP_VERSION,GMP_HEADER_GETVAL): New macros.
+ * configure.in (AM_INIT_AUTOMAKE): Use GMP_VERSION.
+
+2000-03-24 Kevin Ryde <kevin@swox.se>
+
+ * INSTALL: Updates for new configure system.
+
+ * configure.in: Add gmp_optcflags_gcc for the x86s, setting -mcpu
+ and -march.
+
+2000-03-23 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (mpz_eval_expr): Properly initialize rhs/lhs
+ for ROOT.
+
+2000-03-23 Kevin Ryde <kevin@swox.se>
+
+ * config.guess (i?86:*:*:*): Use uname -m if detection program fails.
+
+ * mpn/x86/README: Remove remarks on the now implemented MMX shifts.
+ * mpn/x86/k6/README: Add speed of mpn_divexact_by3, update mpn_mul_1.
+
+ * gmp.texi (Installing MP): Corrections to target CPUs.
+
+ * version.c: Use VERSION from config.h, add copyright comment,
+ restore "const" somehow lost.
+
+ * configure.in (a29k*-*-*): Fix directory name.
+
+2000-03-22 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (op_t): Add ROOT.
+ (fns): Add ROOT.
+ (mpz_eval_expr): Add ROOT.
+
+ * mpz/root.c: Handle roots of negative numbers.
+ Fix other border cases.
+ Fix rare memory leakage.
+
+ * errno.c: New file.
+
+2000-03-21 Torbjorn Granlund <tege@swox.com>
+
+ * gmp.h (error number enum): New anonymous enum.
+ (gmp_errno): New.
+
+ * gmp.h (__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR): Bump for GMP 3.0.
+
+2000-03-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/unicos.m4 (FLOAT64): New define.
+ * mpn/alpha/default.m4 (FLOAT64): New define.
+ * mpn/alpha/invert_limb.asm (C36): Use FLOAT64.
+
+2000-03-21 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k6/diveby3.asm: Tiny speedup.
+
+ * acinclude.m4 (GMP_CHECK_ASM_SHLDL_CL): New macro.
+ * configure.in: Use it, set WANT_SHLDL_CL in config.m4.
+ * mpn/x86/x86-defs.m4 (shldl,shrdl,shldw,shrdw): New macros, using
+ WANT_SHLDL_CL.
+ * mpn/x86/k6/mmx/lshift.asm: Use shldl macro.
+ * mpn/x86/k7/mmx/lshift.asm: Ditto.
+ * mpn/x86/pentium/mmx/lshift.asm: Ditto.
+ * mpn/x86/k6/mmx/rshift.asm: Use shrdl macro.
+ * mpn/x86/k7/mmx/rshift.asm: Ditto.
+ * mpn/x86/pentium/mmx/rshift.asm: Ditto.
+ * mpn/x86/README.family: Add a note about this.
+
+2000-03-20 Linus Nordberg <linus@swox.se>
+
+ * mpn/generic/rawrandom.c (mpn_rawrandom): Handle seed value of 0
+ correctly.
+
+ * configure.in: Fix detection of alpha flavour.
+ Set compiler options for `sparcv8'.
+ * configure: Regenerate.
+
+ * rand.c (__gmp_rand_scheme): Clean up some. Use slightly better
+ multipliers.
+
+ * configure.in (AC_OUTPUT): Add tests/Makefile and
+ tests/rand/Makefile.
+
+ * acinclude.m4 (AC_CANONICAL_BUILD): Define to
+ `_AC_CANONICAL_BUILD' to deal with incompatibilities between
+ Autoconf and Libtool.
+ (AC_CHECK_TOOL_PREFIX): Likewise.
+
+ * Makefile.am (EXTRA_DIST): Add directory `tests'.
+
+ * mkinstalldirs: Update (Automake 2000-03-17).
+ * ltconfig: Update (Libtool 2000-03-17).
+ * ltmain.sh: Ditto.
+
+ * configure: Regenerate with new autoconf/-make/libtool suite.
+ * aclocal.m4: Ditto.
+ * config.in: Ditto.
+ * all Makefile.in's: Ditto.
+
+2000-03-20 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (main): Don't allow `-N' for base, require `-bN'.
+
+ * mpn/alpha/unicos.m4 (cvttqc): New define.
+ * mpn/alpha/invert_limb.asm: Use new define for cvttqc.
+
+2000-03-19 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k6/sqr_basecase.asm: Tiny amendments for 3x3 case.
+
+ * gmp.texi: Use @include version.texi.
+ Use @email and @uref.
+ (Installing MP): Rewrite for new configure.
+ (Low-level Functions): Add mpn_divexact_by3.
+
+ * configure.in (--enable-alloca): New option.
+ * acconfig.h (USE_STACK_ALLOC): For --disable-alloca.
+
+2000-03-18 Kent Boortz <kent@swox.com>
+
+ * macos: New directory with macos port files.
+
+2000-03-17 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (union ieee_double_extract): Check _CRAYMPP.
+
+ * mpn/asm-defs.m4 (invert_normalized_limb): Define.
+
+ * mpn/alpha: Translate `.s' files to `.asm'.
+
+ * configure: Regenerate.
+
+ * mpn/alpha/invert_limb.asm: Replace dash in file name with underscore.
+ * configure.in: Corresponding change.
+
+ * configure.in: Assign special "path" for alphaev6.
+
+ * mpn/alpha/unicos.m4: New file.
+ * configure.in (alpha*-cray-unicos*): [This part of the change
+ commited 2000-03-13 by linus]
+ * mpn/alpha/default.m4: New file.
+ * configure.in (alpha*-*-*): Use it.
+
+2000-03-17 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/rshift.S: Use plain rcrl (not rcrl $1) for
+ shift-by-1 case, significant speedup.
+ * mpn/x86/pentium/README: Add shift-by-1 speed.
+
+2000-03-16 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Handle Cray T3D/E.
+
+2000-03-15 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/diveby3.c: New file.
+ * mpn/x86/diveby3.asm: New file.
+ * mpn/x86/k6/diveby3.asm: New file.
+ * gmp.h (mpn_divexact_by3): Prototype and define.
+ * mpn/asm-defs.m4: define_mpn(divexact_by3).
+ * configure.in (gmp_mpn_functions): Add diveby3.
+
+ * mpn/x86/pentium/sqr_basecase.asm: A few better addressing modes.
+
+ * configure.in: Add AC_C_STRINGIZE and AC_CHECK_TYPES((void)).
+ * gmp-impl.h (ASSERT): Use them.
+
+ * mpn/x86/k7/mmx/lshift.asm: New file.
+ * mpn/x86/k7/mmx/rshift.asm: Rewrite simple loop and return value
+ handling, add some pictures.
+
+2000-03-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v8/mul_1.asm: Make PIC actually work.
+ * mpn/sparc32/v8/addmul_1.asm: Likewise.
+
+ * mpn/sparc32/v8/mul_1.asm: Use m4 ifdef, not cpp #if.
+ * mpn/sparc32/v8/addmul_1.asm: Likewise.
+
+ * mpn/asm-defs.m4 (C): New define for comments.
+ * mpn/sparc32: Start comments with `C'.
+
+ * config.guess: Remove `SunOS 6' handling.
+ Recognize sun4m and sun4d architectures under old SunOS.
+
+2000-03-14 Linus Nordberg <linus@swox.se>
+
+ * configure.in (gmp_srclinks): Set to list of links created by
+ configure.
+ * configure: Regenerate.
+
+ * Makefile.am (libgmp_la_LDFLAGS): Set version info.
+ (DISTCLEANFILES): Include @gmp_srclinks@.
+ * Makefile.in: Regenerate.
+
+2000-03-13 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Remove some changequote's by quoting the strings
+ containing `[]'.
+ Add support for `alpha*-cray-unicos*'.
+ AC_DEFINE `_LONG_LONG_LIMB' instead of passing it in CFLAGS.
+ Conditionalize the assembler syntax checks.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+ * acinclude.m4 (GMP_PROG_CCAS): Remove macro.
+ * aclocal.m4: Regenerate.
+
+2000-03-13 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/p6/README: New file.
+
+ * mpn/x86/k6/mul_1.asm: Rewrite, smaller and slightly faster.
+
+ * mpn/lisp/gmpasm-mode.el: Rewrite assembler comment detection and
+ handling.
+
+ * configure.in: Separate mmx directories for each x86 flavour.
+ * configure: Regenerate.
+
+2000-03-12 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/x86-defs.m4 (ALIGN): Supplement definition from
+ config.m4 so as to pad with nops not zeros on old gas.
+
+ * mpn/x86/k7/mmx/copyd.asm: Use plain emms (femms is just an alias
+ for emms now).
+ * mpn/x86/k7/mmx/copyi.asm: Ditto.
+ * mpn/x86/k7/mmx/rshift.asm: Ditto.
+ * mpn/x86/x86-defs.m4: Amend comments.
+
+ * mpn/x86/mod_1.asm: Add comments on speeds.
+
+ * mpn/x86/pentium/mmx/lshift.asm: New file.
+ * mpn/x86/pentium/mmx/rshift.asm: New file.
+ * mpn/x86/pentium/README: Add speeds of various routines.
+
+2000-03-10 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Reorganize.
+ Use AC_CHECK_TOOL to find `ar'.
+ Add post-includes `regmap.m4' and `aix.m4' for AIX targets.
+ asm-syntax.h is not needed for PPC or sparc anymore.
+ (powerpc64-*-aix*): Compiler is always 64-bit. Use `-q64
+ -qtune=pwr3' to xlc and `-maix64 -mpowerpc64' to gcc. Pass `-X
+ 64' to `ar' and `nm'.
+ (pentiummmx): Use GMP_CHECK_ASM_MMX and avoid MMX assembly path if
+ assembler is not MMX capable.
+ (pentium[23]): Likewise.
+ (athlon): Likewise.
+ (k6*): Likewise.
+ * configure: Regenerate.
+
+ * acinclude.m4 (GMP_PROG_CC_WORKS): New macro.
+ (GMP_PROG_CC_FIND): Use GMP_PROG_CC_WORKS instead of
+ AC_TRY_COMPILER. Make sure that the *first* working 32-bit
+ compiler is used if no 64-bit compiler is found.
+ (GMP_CHECK_ASM_MMX): New macro.
+ * aclocal.m4: Regenerate.
+
+ * Makefile.in: Regenerate. (CC_TEST removed.)
+ * mpf/Makefile.in: Likewise.
+ * mpn/Makefile.in: Likewise.
+ * mpq/Makefile.in: Likewise.
+ * mpz/Makefile.in: Likewise.
+ * mpf/tests/Makefile.in: Likewise.
+ * mpq/tests/Makefile.in: Likewise.
+ * mpz/tests/Makefile.in: Likewise.
+
+ * acconfig.h (_LONG_LONG_LIMB): Add.
+
+ * gmp-impl.h: Include config.h only if HAVE_CONFIG_H is defined.
+
+2000-03-09 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/pentium/mul_basecase.S: Small speedup by avoiding an AGI.
+
+ * mpn/x86/k7/mmx/copyd.asm: Tiny speedup by avoiding popl.
+ * mpn/x86/k7/mmx/copyi.asm: Ditto.
+ * mpn/x86/k7/mul_basecase.asm: Ditto.
+
+2000-03-07 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Better recognize POWER/PowerPC processor type.
+
+2000-03-07 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/addsub_n.c: Use HAVE_NATIVE_* now in config.h.
+
+ * mpn/asm-defs.m4: Add comments about SysV m4.
+ (m4_log2): Don't use <<.
+ (m4_lshift,m4_rshift): New macros.
+
+2000-03-06 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/regmap.m4: Map cr0 => `0', etc.
+
+2000-03-06 Kevin Ryde <kevin@swox.se>
+
+ * mpn/tests/ref.c (refmpn_divexact_by3): New function.
+ * mpn/tests/ref.h: Prototype.
+
+ * acconfig.h (WANT_ASSERT): New define.
+ * configure.in (--enable-assert): Turn on WANT_ASSERT.
+ * assert.c: New file.
+ * Makefile.am: Add to build.
+ * gmp-impl.h (ASSERT): New macro.
+ (ASSERT_NOCARRY) Renamed from assert_nocarry.
+ (MPZ_CHECK_FORMAT): Use ASSERT_ALWAYS.
+ * mpn/tests/ref.c: Use ASSERT.
+ * mpf/get_str.c: Use ASSERT_ALWAYS.
+ * mpf/set_str.c: Remove old assert macro.
+
+ * mpn/x86/x86-defs.m4 (cmovnz_ebx_ecx): New macro.
+ * mpn/x86/p6/aorsmul_1.asm: Use cmov.
+
+ * mpn/x86/lshift.S: Use %dl with testb, not %edx. No object code
+ change, testb was still getting generated.
+ * mpn/x86/rshift.S: Ditto.
+
+2000-03-03 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h: Add IA-64 support.
+
+ * mpn/powerpc32: Misc cleanups.
+ * mpn/powerpc32/aix.m4: New file (mainly by Linus).
+ * mpn/powerpc64/aix.m4: New file (mainly by Linus).
+ * mpn/powerpc64: Translate `.S' files to `.asm'.
+
+ * configure.in: Fix tyops.
+ * configure: Regenerate.
+
+2000-03-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc32/regmap.m4: New file.
+ * mpn/powerpc32: Translate `.S' files to `.asm'.
+ * configure.in: Use mpn/powerpc32/regmap.m4 for powerpc targets
+ except some weird ones.
+
+2000-03-03 Kevin Ryde <kevin@swox.se>
+
+ * mpn/lisp/gmpasm-mode.el: Suppress postscript comment prefixes in
+ filladapt.
+
+ * mpn/x86/pentium/sqr_basecase.asm: New file.
+ * mpn/x86/pentium/gmp-mparam.h (KARATSUBA_SQR_THRESHOLD): Update.
+
+ * configure.in: Add --enable-assert, enable k6 logops functions.
+
+ * mpn/x86/k6/mmx/copyi.asm: Use m4 for divide, not as.
+ * mpn/x86/k6/mmx/copyd.asm: Ditto.
+ * mpn/x86/README.family: Add a note on this.
+
+2000-03-02 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k6/aors_n.asm: Don't use stosl.
+ * mpn/x86/copyi.asm: Use cld to clear direction flag.
+ * mpn/x86/divrem_1.asm: Ditto.
+ * mpn/x86/README.family: Add a note on this.
+
+ * mpn/x86/k6/mmx/copyi.asm: Rewrite.
+ * mpn/x86/k6/mmx/copyd.asm: New file.
+ * mpn/x86/k6/README: Update, and small amendments.
+
+ * mpn/x86/x86-defs.m4 (Zdisp): New macro.
+ * mpn/asm-defs.m4 (m4_stringequal_p): New macro.
+
+ * mpn/x86/p6/aorsmul_1.asm: Use Zdisp to force zero displacements.
+ * mpn/x86/k6/aorsmul_1.asm: Ditto.
+ * mpn/x86/k6/mul_1.asm: Ditto.
+ * mpn/x86/k6/mul_basecase.asm: Ditto.
+ * mpn/x86/k7/aors_n.asm: Ditto.
+ * mpn/x86/k7/aorsmul_1.asm: Ditto.
+ * mpn/x86/k7/mul_1.asm: Ditto.
+ * mpn/x86/k7/mul_basecase.asm: Ditto.
+ * mpn/x86/README.family: Add a note on this.
+
+2000-02-27 Kevin Ryde <kevin@swox.se>
+
+ * mpn/generic/divrem.c (mpn_divrem_classic): Patch to avoid gcc
+ 2.7.2.3 i386 register handling bug.
+
+ * mpn/x86/k6/aors_n.asm: Rewrite.
+ * mpn/x86/k6/mmx/lshift.asm: Rewrite.
+ * mpn/x86/k6/mmx/rshift.asm: Rewrite.
+ * mpn/x86/k6/README: Update.
+
+ * mpn/x86/k7/mmx/copyd.asm: Support size==0.
+ * mpn/x86/k7/mmx/copyi.asm: Ditto.
+ * mpn/x86/k6/mmx/copyi.asm: Ditto.
+ * gmp-impl.h: Comment size==0 allowed in MPN_COPY_INCR and
+ MPN_COPY_DECR.
+ * configure.in: Enable x86 copyi, copyd; add k6 com_n.
+
+2000-02-25 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (power): Move factorial handing code from `factor'
+ to `power'.
+
+ * demos/factorize.c (factor_using_pollard_rho): Move resetting of `c'
+ to before checking for a non-zero gcd.
+
+2000-02-25 Kevin Ryde <kevin@swox.se>
+
+ * mpn/asm-defs.m4 (MULFUNC_PROLOGUE): New macro by Linus.
+ * mpn/x86/k6/aors_n.asm: Use MULFUNC_PROLOGUE.
+ * mpn/x86/k6/aorsmul_1.asm: Ditto.
+ * mpn/x86/k7/aors_n.asm: Ditto.
+ * mpn/x86/k7/aorsmul_1.asm: Ditto.
+ * mpn/x86/p6/aorsmul_1.asm: Ditto.
+
+ * mpn/tests/ref.c (refmpn_copyi,refmpn_copyd): Allow size==0.
+
+ * gmp-impl.h: Move mpn_and_n, mpn_andn_n, mpn_com_n, mpn_ior_n,
+ mpn_iorn_n, mpn_nand_n, mpn_nior_n, mpn_xor_n and mpn_xorn_n here
+ from gmp.h. Use HAVE_NATIVE_mpn_* to make these functions or
+ inlines.
+
+ * gmp-impl.h: Move mpn_copyd, mpn_copyi here from gmp.h.
+ * gmp-impl.h (MPN_COPY_INCR): Use mpn_copyi if available.
+ * gmp-impl.h (MPN_COPY_DECR): Use mpn_copyd if available.
+
+ * mpn/x86/k6/mmx/com_n.asm: Moved into mmx subdirectory.
+ * mpn/x86/k6/mmx/copyi.asm: Ditto.
+ * mpn/x86/k6/mmx/lshift.asm: Ditto.
+ * mpn/x86/k6/mmx/rshift.asm: Ditto.
+ * mpn/x86/k7/mmx/rshift.asm: Ditto.
+ * mpn/x86/k6/mmx/logops_n.asm: New file.
+ * configure.in (k6*-*-*): Add logops_n.asm.
+ * mpn/x86/k6/README: Update.
+
+ * mpn/x86/k7/mmx/copyi.asm: New file.
+ * mpn/x86/k7/mmx/copyd.asm: New file.
+ * mpn/x86/k7/README: Update.
+
+2000-02-24 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/x86-defs.m4 (femms): Generate emms if 3dnow not available.
+ * mpn/x86/x86-defs.m4 (FRAME_popl): New macro.
+
+ * Makefile.am: Add info_TEXINFOS = gmp.texi
+
+ * mpn/x86/divrem_1.asm: Moved from mpn/x86/k6, allow size==0,
+ conditionalize loop versus decl/jnz.
+ * mpn/x86/mod_1.asm: Ditto.
+ * mpn/x86/divmod_1.asm: Removed.
+ * gmp.texi (mpn_divrem_1,mpn_mod_1): Add that size==0 is allowed.
+ * mpn/tests/ref.c (refmpn_divrem_1c,etc): Allow size==0.
+
+ * mpn/x86/k6/aors_n.asm: Avoid gas 1.92.3 leal displacement
+ expression problem.
+ * mpn/x86/k6/aorsmul_1.asm: Ditto.
+ * mpn/x86/k6/mul_1.asm: Ditto.
+ * mpn/x86/k6/mul_basecase.asm: Ditto
+ * mpn/x86/k7/aors_n.asm: Ditto.
+ * mpn/x86/k7/aorsmul_1.asm: Ditto.
+ * mpn/x86/k7/mul_1.asm: Ditto.
+ * mpn/x86/k7/mul_basecase.asm: Ditto.
+ * mpn/x86/k7/rshift.asm: Ditto.
+ * mpn/x86/p6/aorsmul_1.asm: Ditto.
+ * mpn/x86/README.family: Describe problem.
+
+2000-02-24 Linus Nordberg <linus@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_ASM_LSYM_PREFIX): Add dummy symbol to
+ testcase to avoid nm failure. Try nm before piping to grep.
+
+ * acconfig.h: Undef HAVE_NATIVE_func for every mpn function found
+ in gmp.h.
+
+ * configure.in: Invoke AC_CONFIG_HEADERS.
+ Don't invoke AM_CONFIG_HEADER; it makes autoconf confused.
+ Dig out entry points declared in assembly code and AC_DEFINE proper
+ HAVE_NATIVE_func.
+
+ * mpn/asm-defs.m4 (MULFUNC_PROLOGUE): New macro.
+
+ * mpn/x86/p6/aorsmul_1.asm: Use MULFUNC_PROLOGUE.
+ * mpn/x86/k6/aors_n.asm: Likewise.
+
+ * Makefile.am (EXTRA_DIST): Add config.in; needed when we don't
+ use AM_CONFIG_HEADER in configure.in.
+
+ * mpn/Makefile.am (INCLUDES): Add `-I..' for config.h and
+ gmp-mparam.h.
+ * mpf/Makefile.am: Likewise.
+ * mpq/Makefile.am: Likewise.
+ * mpz/Makefile.am: Likewise.
+
+ * mpf/tests/Makefile.am (INCLUDES): Add `-I../..' for config.h and
+ gmp-mparam.h.
+ * mpq/tests/Makefile.am: Likewise.
+ * mpz/tests/Makefile.am: Likewise.
+
+ * configure: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * Makefile.in: Regenerate.
+ * mpf/Makefile.in: Regenerate.
+ * mpn/Makefile.in: Regenerate.
+ * mpq/Makefile.in: Regenerate.
+ * mpz/Makefile.in: Regenerate.
+ * mpf/tests/Makefile.in: Regenerate.
+ * mpq/tests/Makefile.in: Regenerate.
+ * mpz/tests/Makefile.in: Regenerate.
+
+2000-02-23 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/addmul_1.S: Amend comments, this code no longer used by
+ PentiumPro.
+ * mpn/x86/submul_1.S: Ditto.
+
+ * mpn/x86/k6/com_n.asm: Rewrite, smaller but same speed.
+
+ * mpn/x86/addmul_1.S: Add PROLOGUE and EPILOGUE to get .type and
+ .size for ELF. Rename #define size to n to avoid .size.
+ * mpn/x86/lshift.S: Ditto.
+ * mpn/x86/mul_1.S: Ditto.
+ * mpn/x86/mul_basecase.S: Ditto.
+ * mpn/x86/rshift.S: Ditto.
+ * mpn/x86/submul_1.S: Ditto.
+ * mpn/x86/udiv.S: Ditto.
+ * mpn/x86/umul.S: Ditto.
+ * mpn/x86/pentium/add_n.S: Ditto.
+ * mpn/x86/pentium/addmul_1.S: Ditto.
+ * mpn/x86/pentium/lshift.S: Ditto.
+ * mpn/x86/pentium/mul_1.S: Ditto.
+ * mpn/x86/pentium/mul_basecase.S: Ditto.
+ * mpn/x86/pentium/rshift.S: Ditto.
+ * mpn/x86/pentium/sub_n.S: Ditto.
+ * mpn/x86/pentium/submul_1.S: Ditto.
+
+2000-02-22 Linus Nordberg <linus@swox.se>
+
+ * acinclude.m4 (GMP_INIT): Use temporary file cnfm4p.tmp for
+ post-defines.
+ (GMP_FINISH): Ditto.
+ (GMP_DEFINE): Add third optional argument specifying location in
+ outfile.
+ (GMP_DEFINE_RAW): New macro.
+ * aclocal.m4: Regenerate.
+
+ * configure.in: Add `HAVE_TARGET_CPU_$target_cpu' using
+ GMP_DEFINE_RAW.
+ * configure: Regenerate.
+
+ * mpz/tests/Makefile.am: New test t-root.
+ * mpz/tests/Makefile.in: Regenerate.
+
+2000-02-22 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/root.c: Complete rewrite; still primitive, but at least correct.
+ * mpz/tests/t-root.c: New test.
+
+2000-02-22 Kevin Ryde <kevin@swox.se>
+
+ * mpn/x86/k7/mul_basecase.asm: New file.
+ * mpn/x86/k7/README: Add mpn_mul_basecase speed.
+ * mpn/x86/k7/gmp-mparam.h: New file.
+
+ * mpn/x86/x86-defs.m4 (loop_or_decljnz,cmov_bytes): New macros.
+ * mpn/asm-defs.m4 (m4_ifdef_anyof_p): New macro.
+
+ * mpn/x86/k6/aorsmul_1.asm: New file.
+ * mpn/x86/k6/addmul_1.S: Removed (was a copy of pentium version).
+ * mpn/x86/k6/submul_1.S: Removed (was a copy of pentium version).
+
+ * mpn/x86/p6/aorsmul_1.asm: Use OPERATION_addmul_1 and
+ OPERATION_submul_1.
+ * mpn/x86/k6/aors_n.asm: Use OPERATION_add_n and OPERATION_sub_n.
+ * configure.in: Declare multi-function files for k6 and p6.
+
+ * configure.in: Add HAVE_TARGET_CPU_$target_cpu for config.m4.
+ * mpn/asm-defs.m4 (define_not_for_expansion): New macro.
+
+ * mpn/generic/divrem_1n.c (__gmpn_divrem_1n): New file, split from
+ mpn/generic/divrem_1.c.
+ * mpn/generic/divrem_1.c: Ditto.
+ * configure.in (gmp_mpn_functions): Ditto.
+
+2000-02-21 Torbjorn Granlund <tege@swox.com>
+
+ * gmp.h: Undo 1996-10-06 NeXT change, it was clearly improperly
+ written.
+
+2000-02-21 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Link <src>/mpn/asm-defs.m4 to <build>mpn/asm.m4.
+ * configure: Regenerate.
+
+2000-02-21 Linus Nordberg <linus@swox.se>
+
+ * mpn/x86/k7/aorsmul_1.asm: Change OPERATION_ADDMUL -->
+ OPERATION_addmul_1. Change OPERATION_SUBMUL -->
+ OPERATION_submul_1.
+
+ * mpn/x86/k7/aors_n.asm: Change OPERATION_ADD --> OPERATION_add_n.
+ Change OPERATION_SUB --> OPERATION_sub_n.
+
+ * mpn/Makefile.am: Pass -DOPERATION_$* to preprocessors.
+ * mpn/Makefile.in: Regenerate.
+
+ * configure.in: Symlink mpn/asm-defs.m4 to build-dir/mpn. Link
+ multi-function files to mpn/<function>.asm and remove function
+ name from `gmp_mpn_functions'.
+ * configure: Regenerate.
+
+ * acinclude.m4 (GMP_FINISH): Tell user what we're doing.
+ * aclocal.m4: Regenerate.
+
+2000-02-21 Kevin Ryde <kevin@swox.se>
+
+ * gmp-impl.h: Rename __gmpn_mul_basecase to mpn_mul_basecase and
+ __gmpn_sqr_basecase to mpn_sqr_basecase, remove __gmpn prototypes.
+ * mpn/x86/mul_basecase.S: Ditto.
+ * mpn/x86/pentium/mul_basecase.S: Ditto.
+
+ * configure.in (gmp_m4postinc): Use x86-defs.m4 on athlon-*-* too.
+
+2000-02-20 Kevin Ryde <kevin@swox.se>
+
+ * acinclude.m4 (GSYM_PREFIX): Drop $1, change by Linus.
+ * mpn/asm-defs.m4 (PROLOGUE,EPILOGUE): Use GSYM_PREFIX as a
+ string, change by Linus.
+ * mpn/x86/x86-defs.m4: Use GSYM_PREFIX as a string.
+
+ * mpn/x86/k6/gmp-mparam.h: New file.
+ * mpn/asm-defs.m4 (m4_warning): New macro.
+
+ * mpn/x86/README: Amendments per new code and directories.
+ * mpn/x86/README.family: New file.
+ * mpn/x86/k6/README: New file.
+ * mpn/x86/k7/README: New file.
+
+ * mpn/generic/mul_n.c: Rename __gmpn_mul_basecase to
+ mpn_mul_basecase and __gmpn_sqr_basecase to mpn_sqr_basecase.
+ * mpn/generic/mul_basecase.c: Ditto.
+ * mpn/generic/sqr_basecase.c: Ditto.
+ * mpn/generic/mul.c: Ditto.
+
+2000-02-19 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Don't try to symlink more than one multi-func
+ file.
+ * configure: Regenerate.
+
+2000-02-18 Linus Nordberg <linus@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_ASM_UNDERSCORE): GMP_DEFINE
+ `GSYM_PREFIX'. Run ACTIONs even when value is found in cache.
+ (GMP_CHECK_ASM_ALIGN_LOG): GMP_DEFINE `ALIGN'. Run ACTIONs even
+ when value is found in cache.
+ * aclocal.m4: Regenerate.
+
+ * configure.in: Don't define GSYM_PREFIX or ALIGN.
+ Add mechanism for multi-function files.
+ * configure: Regenerate.
+
+2000-02-18 Kevin Ryde <kevin@swox.se>
+
+ * configure.in (gmp_m4postinc): Enable x86-defs.m4.
+ * mpn/x86/k7/mul_1.asm: Fix include.
+ * mpn/x86/k6/mul_basecase.S: Removed (copy of the pentium version).
+ * mpn/x86/k6/mul_basecase.asm: New file.
+ * mpn/x86/k6/sqr_basecase.asm: New file.
+ * mpn/x86/k6/com_n.asm: New file.
+ * mpn/x86/k6/copyi.asm: New file.
+ * gmp.texi (Low-level Functions): Clarify mpn overlaps permitted.
+ * gmp-impl.h (MPN_OVERLAP_P): New macro.
+ * gmp-impl.h (assert_nocarry): New macro.
+ * mpn/tests/ref.c: New file, based in part on other mpn/tests/*.c.
+ * mpn/tests/ref.h: New file.
+
+2000-02-17 Linus Nordberg <linus@swox.se>
+
+ * Makefile.am (dist-hook): Don't include any emacs backup files
+ (*.~*) in dist.
+ * Makefile.in: Regenerate.
+
+2000-02-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v9/mul_1.asm: Use `rd' to get current PC; get rid of
+ getpc function.
+ * mpn/sparc32/v9/addmul_1.asm: Likewise.
+ * mpn/sparc32/v9/submul_1.asm: Likewise.
+
+2000-02-17 Kevin Ryde <kevin@swox.se>
+
+ * gmp.h: Add prototypes and defines for mpn_and_n, mpn_andn_n,
+ mpn_com_n, mpn_copyd, mpn_copyi, mpn_ior_n, mpn_iorn_n,
+ mpn_mul_basecase, mpn_nand_n, mpn_nior_n, mpn_sqr_basecase,
+ mpn_xor_n, mpn_xorn_n.
+
+ * mpn/asm-defs.m4: Many additions making up initial version.
+ * mpn/asm-defs.m4 (L): Use defn(`LSYM_PREFIX').
+ * mpn/x86/x86-defs.m4: New file.
+ * mpn/x86/k6/aors_n.asm: New file.
+ * mpn/x86/k6/divmod_1.asm: New file.
+ * mpn/x86/k6/divrem_1.asm: New file.
+ * mpn/x86/k6/lshift.S: Removed (was a copy of the pentium version).
+ * mpn/x86/k6/lshift.asm: New file.
+ * mpn/x86/k6/mod_1.asm: New file.
+ * mpn/x86/k6/mul_1.S: Removed (was a copy of the pentium version).
+ * mpn/x86/k6/mul_1.asm: New file.
+ * mpn/x86/k6/rshift.S: Removed (was a copy of the pentium version).
+ * mpn/x86/k6/rshift.asm: New file.
+ * mpn/x86/k7/aors_n.asm: New file.
+ * mpn/x86/k7/aorsmul_1.asm: New file.
+ * mpn/x86/k7/mul_1.asm: New file.
+ * mpn/x86/k7/rshift.asm: New file.
+ * mpn/x86/p6/aorsmul_1.asm: New file.
+ * mpn/x86/copyi.asm: New file.
+ * mpn/x86/copyd.asm: New file.
+ * mpn/lisp/gmpasm-mode.el: New file.
+
+2000-02-16 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/v9/mul_1.asm: Conditionalize for PIC.
+ * mpn/sparc32/v9/addmul_1.asm: Likewise.
+ * mpn/sparc32/v9/submul_1.asm: Likewise.
+ * mpn/sparc32/v8/supersparc/udiv.asm: Likewise.
+ * mpn/sparc32/udiv_fp.asm: Likewise.
+
+2000-02-16 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Add mechanism for including target specific
+ m4-files in config.m4.
+ * configure: Regenerate.
+
+ * acinclude.m4 (GMP_PROG_CCAS): Begin assembly lines (except
+ labels) with a tab character. HP-UX demands it.
+ (GMP_CHECK_ASM_SIZE): Ditto.
+ (GMP_CHECK_ASM_LSYM_PREFIX): Ditto.
+ (GMP_CHECK_ASM_LABEL_SUFFIX): Set to empty string for HP-UX.
+ (GMP_CHECK_ASM_GLOBL): Change `.xport' --> `.export'.
+ * aclocal.m4: Regenerate.
+
+2000-02-16 Linus Nordberg <linus@swox.se>
+
+ * acinclude.m4 (GMP_CHECK_ASM_LSYM_PREFIX): Define LSYM_PREFIX as
+ the prefix only, no argument.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+ * mpn/asm-defs.m4 (L): No argument to LSYM_PREFIX.
+
+2000-02-15 Linus Nordberg <linus@swox.se>
+
+ * acinclude.m4: Prefix all temporary shell variables with
+ `gmp_tmp_'.
+ (GMP_PROG_CC_FIND): Use defaults if no arguments are passed.
+ Quote use of arguments.
+ (GMP_PROG_CCAS): New macro.
+ (GMP_INIT): New macro.
+ (GMP_FINISH): New macro.
+ (GMP_INCLUDE): New macro.
+ (GMP_SINCLUDE): New macro.
+ (GMP_DEFINE): New macro.
+ (GMP_CHECK_ASM_LABEL_SUFFIX): New macro.
+ (GMP_CHECK_ASM_TEXT): New macro.
+ (GMP_CHECK_ASM_DATA): New macro.
+ (GMP_CHECK_ASM_GLOBL): New macro.
+ (GMP_CHECK_ASM_TYPE): New macro.
+ (GMP_CHECK_ASM_SIZE): New macro.
+ (GMP_CHECK_ASM_LSYM_PREFIX): New macro.
+ (GMP_CHECK_ASM_W32): New macro.
+ * aclocal.m4: Regenerate.
+
+ * configure.in: Find m4 and nm for target.
+ Use new macros to create config.m4.
+ Prefix all temporary shell variables with `tmp_'.
+ Pass `-X 64' to nm for 64-bit PPC target with 64-bit compiler.
+ * configure: Regenerate.
+
+ * Makefile.am (dist-hook): *Really* remove all CVS dirs in
+ dist.
+ * Makefile.in: Regenerate.
+
+ * mpn/Makefile.am: Add target for building .lo and .o from
+ .asm.
+ Pass -DPIC to preprocessor (CPP/m4) when building .lo.
+ Build .o a second time for target .lo, without -DPIC to
+ preprocessor.
+ (SUFFIX): Add `.asm'.
+ (EXTRA_DIST): Add asm-defs.m4.
+ * mpn/Makefile.in: Regenerate.
+
+ * mpf/Makefile.in: Regenerate.
+ * mpf/tests/Makefile.in: Regenerate.
+ * mpq/Makefile.in: Regenerate.
+ * mpq/tests/Makefile.in: Regenerate.
+ * mpz/Makefile.in: Regenerate.
+ * mpz/tests/Makefile.in: Regenerate.
+
+2000-02-15 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc32/udiv_fp.asm: Change `RODATA' to `DATA'.
+ * mpn/sparc32/v8/supersparc/udiv.asm: Likewise.
+ * mpn/sparc32/v9/addmul_1.asm: Likewise.
+ * mpn/sparc32/v9/submul_1.asm: Likewise.
+ * mpn/sparc32/v9/mul_1.asm: Likewise.
+
+ * mpn/sparc32/add_n.asm: Rename `size' -> `n'.
+ * mpn/sparc32/sub_n.asm: Likewise.
+
+ * sparc32: Rename `.s' and `.S' files to `.asm'.
+ * sparc64: Rename `.s' and `.S' files to `.asm'.
+
+2000-02-11 Torbjorn Granlund <tege@swox.com>
+
+ * config.sub: Adopt to new config.guess sparc naming conventions.
+
+ * config.guess (sun4u:SunOS:5.*:*): Change `sparc9' to `sparcv9'.
+ * config.guess (sun4m:SunOS:5.*:*): Change to sun4[md]:SunOS:5.*:* and
+ change `sparc8' to `sparcv8'.
+
+ * mpn/x86/add_n.S: Use PROLOGUE/EPILOGUE.
+ * mpn/x86/sub_n.S: Likewise.
+
+ * mpn/x86/syntax.h (PROLOGUE): New name for PROLOG.
+ * mpn/x86/syntax.h (EPILOGUE): New name for EPILOG.
+
+2000-02-11 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Better path for 64-bit sparc without 64-bit cc.
+ Change sparc8 --> sparcv8.
+ Change sparc9 --> sparcv9.
+ * configure: Regenerate.
+
+2000-02-10 Linus Nordberg <linus@swox.se>
+
+ * configure.in: Use Autoconf.
+ * Makefile.am: New file.
+
+ * AUTHORS: New file.
+ * COPYING: New file.
+ * acinclude.m4: New file.
+ * acconfig.h: New file.
+
+ * configure: Generate.
+ * Makefile.in: Generate.
+ * aclocal.m4: Generate.
+ * config.in: Generate.
+
+ * install.sh: Remove.
+ * install-sh: New file from Automake.
+ * missing: New file from Automake.
+ * ltconfig: New file from Libtool.
+ * ltmain.sh: New file from Libtool.
+
+ * mpf/Makefile.am: New file.
+ * mpf/Makefile.in: Generate.
+ * mpf/configure.in: Remove.
+ * mpf/tests/Makefile.am: New file.
+ * mpf/tests/Makefile.in: Generate.
+ * mpf/tests/configure.in: Remove.
+
+ * mpn/Makefile.am: New file.
+ * mpn/Makefile.in: Generate.
+ * mpn/configure.in: Remove.
+
+ * mpq/Makefile.am: New file.
+ * mpq/Makefile.in: Generate.
+ * mpq/configure.in: Remove.
+ * mpq/tests/Makefile.am: New file.
+ * mpq/tests/Makefile.in: Generate.
+ * mpq/tests/configure.in: Remove.
+
+ * mpz/Makefile.am: New file.
+ * mpz/Makefile.in: Generate.
+ * mpz/configure.in: Remove.
+ * mpz/tests/Makefile.am: New file.
+ * mpz/tests/Makefile.in: Generate.
+ * mpz/tests/configure.in: Remove.
+
+2000-02-10 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/add_n.S: Don't use label L0 twice.
+ * mpn/x86/sub_n.S: Likewise.
+
+2000-01-20 Linus Nordberg <linus@swox.se>
+
+ * demos/pexpr.c: Don't use setup_error_handler() in windoze.
+
+2000-01-19 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (sigaltstack): #define to sigstack for AIX.
+ (setup_error_handler): Don't write to ss_size and ss_flags
+ on AIX.
+
+2000-01-11 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/configure.in (hppa2.0*-*-*): Move assignment of
+ target_makefile_frag to where it belongs.
+
+1999-12-21 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (v9 umul_ppmm): New #define.
+ (v9 udiv_qrnnd): New #define.
+
+1999-12-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/divmod_1.c: Use invert_limb.
+ * mpn/generic/mod_1.c: Use invert_limb.
+
+ * gmp-impl.h (invert_limb): Put definition here.
+ * mpn/generic/divrem.c (invert_limb): Delete definition.
+ * mpn/generic/divrem_2.c (invert_limb): Delete definition.
+
+ * gmp.h (mpn_divrem): Inhibit for non-gcc.
+ But declare (undo 1999-11-22 change).
+
+ * gmp-impl.h (DItype,UDItype): Do these also if _LONG_LONG_LIMB.
+
+ * longlong.h: Move 64-bit hppa code out of __GNUC__ conditional.
+
+ * stack-alloc.c (HSIZ): New #define.
+ (__tmp_alloc): Use HSIZ instead of sizeof(tmp_stack).
+
+1999-12-10 Torbjorn Granlund <tege@swox.com>
+
+ * config.sub: Clean up handling of x86 CPUs: Properly recognize
+ Amd CPUs as unique entities. Use manufacturer's names of
+ processors ("pentium", etc); still match ambiguous names like
+ "i586", "i686", "p6" but be conservative in interpreting them.
+
+ * configure.in: Recognize x86 CPU types known by config.guess.
+ * mpn/configure.in: Likewise. Add x86/mmx path component as
+ appropriate.
+ (athlon-*-*): Fix typo.
+
+ * config.guess: Update x86 recog code to initially match
+ more than just i386.
+ Call K6-2 and K6-III for "k62" and "k63" respectively.
+
+ * config.guess: Recognize x86 CPU types.
+ Update code for FreeBSD, NetBSD, OpenBSD, Linux.
+
+1999-12-08 Torbjorn Granlund <tege@swox.com>
+
+ * mpf/pow_ui.c: Avoid final squaring in loop.
+
+1999-12-07 Torbjorn Granlund <tege@swox.com>
+
+ * gmp-impl.h (udiv_qrnnd_preinv2gen): Prefix local variables with `_'.
+ (udiv_qrnnd_preinv2norm): Likewise.
+ From Kevin Ryde:
+ (HAVE_ALLOCA): #define also if defined (alloca).
+
+1999-12-04 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/tests/add_n.c: Set OPS from CLOCK.
+ * mpn/tests/sub_n.c: Likewise.
+ * mpn/tests/mul_1.c: Likewise.
+ * mpn/tests/addmul_1.c: Likewise.
+ * mpn/tests/submul_1.c: Likewise.
+
+ * mpn/tests/lshift.c: Update from add_n.c.
+ * mpn/tests/rshift.c: Likewise.
+
+1999-12-03 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/powerpc64/copy.S: New file.
+
+1999-12-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/copy.s: New file.
+
+ * mpn/tests/copy.c: New file.
+
+ * mpn/configure.in: Recognize more Amd CPUs; Set special paths for
+ k7 CPU.
+
+ * configure.in: Recognize Amd x86 CPUs.
+
+ * mpz/fdiv_r_2exp.c: In rounding code, read in->_mp_size before
+ writing to res->_mp_size.
+
+ * mpn/powerpc64/*.S: Clean up assembly syntax, add function headers.
+ * mpn/powerpc64/gmp-mparam.h: (KARATSUBA_MUL_THRESHOLD): #define.
+ (KARATSUBA_SQR_THRESHOLD): #define.
+
+ * mpn/tests/add_n.c (main): Only print test number if TIMES==1
+ and not printing.
+ (main): Don't run reference code if NOCHECK.
+ * mpn/tests/sub_n.c: Likewise.
+ * mpn/tests/mul_1.c: Likewise.
+ * mpn/tests/addmul_1.c: Likewise.
+ * mpn/tests/submul_1.c: Likewise.
+
+ * mpn/tests/lshift.c: (main): Only print test number if TIMES==1
+ and not printing.
+ * mpn/tests/rshift.c: Likewise.
+
+1999-11-22 Torbjorn Granlund <tege@swox.com>
+
+ * gmp.h (mpz_init_set_str): Declare using __gmp_const.
+ (mpz_set_str): Likewise.
+ (mpf_init_set_str): Likewise.
+ (mpf_set_str): Likewise.
+ (mpn_set_str): Likewise.
+ (__gmp_0): Likewise.
+ (mpn_divrem): Remove separate declaration; it's defined later in
+ this file.
+
+ * gmp.h: Replace "defined (__STD__)' by (__STDC__-0) in
+ expressions involving more than one term, to handle Sun's compiler
+ that most helpfully sets __STDC__ to 0.
+ * gmp-impl.h: Likewise.
+ * longlong.h: Likewise.
+
+1999-11-21 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/gmp-mparam.h (KARATSUBA_MUL_THRESHOLD): #define.
+ (KARATSUBA_SQR_THRESHOLD): #define.
+
+ * mpn/sparc64/lshift.s: Compensate stack references for odd stack ptr.
+ * mpn/sparc64/rshift.s: Likewise.
+
+ * mpn/sparc64/addmul_1.s: Propagate carry properly.
+ * mpn/sparc64/submul_1.s: Likewise.
+
+ * mpn/sparc64/sub_n.s: Rewrite.
+
+ * mpn/sparc64/sub_n.s: Get operand order for main subcc right
+ (before scrapping this code for new code).
+
+1999-11-20 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/sparc64/add_n.s: Rewrite.
+
+1999-11-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/syntax.h (PROLOG): New #define.
+ (EPILOG): New #define.
+
+ * gmp.h (mpn_addsub_n): Declare.
+ * gmp.h (mpn_add_nc): Declare.
+ * gmp.h (mpn_sub_nc): Declare.
+ * mpn/powerpc64/addsub_n.S: New file.
+
+1999-11-17 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/gmp-mparam.h
+ (KARATSUBA_MUL_THRESHOLD): Only #define #ifndef.
+ (KARATSUBA_SQR_THRESHOLD): Likewise.
+
+1999-11-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/mul_1.S: Unroll and optimize for P6 and K7.
+
+1999-11-09 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/x86/p6/gmp-mparam.h
+ (KARATSUBA_MUL_THRESHOLD): Only #define #ifndef.
+ (KARATSUBA_SQR_THRESHOLD): Likewise.
+
+1999-11-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/addsub_n.c: New file.
+
+1999-11-02 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Handle alpha:FreeBSD with alpha:NetBSD.
+
+ * configure.in (vax*-*-*): New case.
+ * config/mt-vax: New file.
+ * mpn/vax/add_n.s: Rewrite.
+ * mpn/vax/sub_n.s: Rewrite.
+
+1999-10-31 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/vax/rshift.s: New file.
+ * mpn/vax/lshift.s: New file.
+
+1999-10-29 Torbjorn Granlund <tege@swox.com>
+
+ * config.sub: Handle k5 and k6.
+ * mpn/configure.in: Recognize k6.
+
+ * mpf/tests/t-get_d.c (LOW_BOUND, HIGH_BOUND): New #defines.
+ (main): Tighten error bounds to 14 digits.
+
+ * longlong.h (default umul_ppmm, when smul_ppmm exists):
+ Rename __m0 => __xm0, __m1 => __xm1.
+ (default smul_ppmm): Likewise.
+
+1999-10-11 Torbjorn Granlund <tege@swox.com>
+
+ * config.guess: Reverse the test for POWER vs PowerPC.
+ * config.guess (sun4m:SunOS:5.*:*): New case.
+ * config.guess (sun4u:SunOS:5.*:*): New case.
+
+1999-09-29 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/divrem_2.c: Clean up comments.
+
+1999-09-23 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/Makefile.in: Use move-if-change when generating binaries.
+ * mpf/tests/Makefile.in: Likewise.
+ * mpq/tests/Makefile.in: Likewise.
+ * mpz/tests/move-if-change: New file.
+ * mpf/tests/move-if-change: New file.
+ * mpq/tests/move-if-change: New file.
+
+ * gmp.h (mpn_incr_u): New macro (from mpn/generic/mul_n.c).
+ (mpn_decr_u): New macro.
+
+ * mpn/generic/mul_n.c (mpn_incr): Delete.
+ * mpn/generic/mul_n.c: Update usages mpn_incr => mpn_incr_u.
+ * mpn/generic/divrem_newt.c: Use mpn_incr_u and mpn_decr_u instead of
+ mpn_add_1 and mpn_sub_1.
+ * mpn/generic/sqrtrem.c: Likewise.
+ * mpz/cdiv_q_ui.c: Likewise.
+ * mpz/cdiv_qr_ui.c: Likewise.
+ * mpz/fdiv_q_ui.c: Likewise.
+ * mpz/fdiv_qr_ui.c: Likewise.
+
+ * mpn/generic/sqrtrem.c: Start single-limb Newton iteration from 18
+ bits.
+
+1999-07-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/divrem_1.c (__gmpn_divrem_1n): New function.
+
+ * mpn/generic/divrem_2.c: New file, code from divrem.c, `case 2:'.
+ * mpn/Makefile.in: Compile divrem_2.c.
+ * make.bat: Compile divrem_2.c.
+ * mpn/configure.in (functions): Add divrem_2.
+ * gmp.h: Declare mpn_divrem_2.
+
+ * mpn/generic/divrem.c: Delete special cases, handle just divisors
+ of more than 2 limbs.
+ * gmp.h (mpn_divrem): Call mpn_divrem_1, mpn_divrem_2, as appropriate.
+
+ * mpn/generic/divrem.c: Rework variable usage for better register
+ allocation.
+
+1999-07-26 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/alpha/ev5/add_n.s: Rewrite for better ev6 speed.
+ * mpn/alpha/ev5/sub_n.s: Likewise.
+
+1999-07-21 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (alpha): Define umul_ppmm for cc.
+
+ * gmp-impl.h (DItype, UDItype): Define for non-gcc if _LONGLONG is
+ defined.
+
+1999-07-15 Torbjorn Granlund <tege@swox.com>
+
+ * longlong.h (powerpc64 count_leading_zeros): Fix typo.
+ (powerpc64 add_ssaaaa): Fix typos.
+ (powerpc64 sub_ddmmss): Fix typos.
+
+1999-07-14 Torbjorn Granlund <tege@swox.com>
+
+ * mpz/tests/Makefile.in: Pass XCFLAGS when linking.
+ * mpf/tests/Makefile.in: Likewise.
+ * mpq/tests/Makefile.in: Likewise.
+ * mpn/Makefile.in (.S.o): Pass XCFLAGS.
+
+ * longlong.h: Add support for 64-bit PowerPC.
+ * config.sub: Handle "powerpc64".
+ * configure.in: Likewise.
+ * mpn/configure.in: Suppress use of config/t-ppc-aix for now,
+ it seems compiler passes proper options.
+ * mpn/powerpc64/*.S: New files.
+
+ * Makefile.in (FLAGS_TO_PASS): Pass "AR=$(AR)".
+
+1999-07-07 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (factor): Change alloca call to a malloc/free pair.
+
+ * mpn/powerpc32/syntax.h: Add #define's for crN.
+
+ * gmp.h (gmp_rand_algorithm): Remove spurious `,'.
+
+1999-07-05 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/generic/divrem_1.c: Normalize divisor when needed.
+
+1999-07-02 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/configure.in (powerpc*-apple-mach): New configuration.
+ * mpn/powerpc32/*: Add support for apple-macho syntax.
+ * mpn/powerpc32/syntax.h: New file.
+ * gmp-impl.h: Don't use `__attribute__' syntax for Apple's perversion
+ of GCC.
+
+1999-05-26 Linus Nordberg <linus@swox.se>
+
+ * rand.c (gmp_rand_init): Fix typo.
+
+ * mpn/generic/rawrandom.c (mpn_rawrandom): Count bits, not limbs,
+ to keep track of how many rounds to do in loop. Clean up
+ temporary allocation. Update `seedsize' inside loop. Mask off
+ the correct number of bits from final result. Init `mcopyp' even
+ when not normalizing `m'.
+
+ * randlc.c (gmp_rand_init_lc): Fix typo (don't call
+ mpz_init_set_ui()).
+
+ * mpn/generic/rawrandom.c (mpn_rawrandom): Set SIZ(s->seed) when
+ reallocating.
+
+ * tests/rand/Makefile (test, bigtest): Add 33-bit tests.
+
+ * tests/rand/gen.c (main): Set precision of variable passed to
+ mpf_urandomb(). Add option `-p'.
+
+1999-05-25 Linus Nordberg <linus@swox.se>
+
+ * randcm.c: Remove.
+ * randcmui.c: Remove.
+ * Makefile.in: Remove randcm and randcmui.
+ * make.bat: Ditto.
+ * gmp-impl.h: Remove prototypes for __gmp_rand_init_common() and
+ __gmp_rand_init_common_ui().
+ * randlc.c (gmp_rand_init_lc): Don't call
+ __gmp_rand_init_common().
+
+ * randlcui.c (gmp_rand_init_lc_ui): Don't call
+ __gmp_rand_init_common_ui().
+
+ * gmp.h (__gmp_rand_state_struct): Remove unused member `maxval'.
+ * randclr.c (gmp_rand_clear): Remove reference to s->maxval.
+ * randcm.c (__gmp_rand_init_common): Ditto
+
+ * mpn/generic/rawrandom.c (mpn_rawrandom): Don't calculate nlimbs
+ twice.
+
+ * gmp.h (__gmp_rand_dist): Remove.
+
+1999-05-24 Linus Nordberg <linus@swox.se>
+
+ * mpn/generic/rawrandom.c: Clean up comments.
+
+ * gmp.texi: Add documentation for random number generation.
+
+1999-05-21 Linus Nordberg <linus@swox.se>
+
+ * gmp.h: Typedef `gmp_rand_state' as an array with one element.
+ Change prototypes accordingly.
+ * gmp-impl.h: Change prototypes using `gmp_rand_state'.
+ * rand.c (gmp_rand_init): Take `gmp_rand_state' as argument
+ instead of a pointer to a `gmp_rand_state'.
+ * mpf/urandom.c (mpf_urandomb): Ditto.
+ * mpz/urandom.c (mpz_urandomb): Ditto.
+ * mpn/generic/rawrandom.c (mpn_rawrandom): Ditto.
+ * randcmui.c (__gmp_rand_init_common_ui): Ditto.
+ * randlc.c (gmp_rand_init_lc): Ditto.
+ * randlcui.c (gmp_rand_init_lc_ui): Ditto.
+ * randui.c (gmp_rand_init_ui): Ditto.
+ * randcm.c (__gmp_rand_init_common): Ditto.
+ * randclr.c (gmp_rand_clear): Ditto.
+
+ * tests/rand/gen.c (main): Pass `s' to rand-funcs instead of address
+ of `s'.
+
+1999-05-20 Linus Nordberg <linus@swox.se>
+
+ * Makefile.in: Rename randi.c --> rand.c, randi_lc.c --> randlc.c,
+ randicom.c --> randcm.c. Add randui.c, randcmui.c, randlcui.c.
+ * make.bat: Ditto.
+
+ * gmp.h: Add prototypes for gmp_rand_init_ui() and
+ gmp_rand_init_lc_ui().
+ * gmp-impl.h: Add prototypes for __gmp_rand_init_common() and
+ __gmp_rand_init_common_ui().
+
+ * randlc.c, randcm.c, randclr.c, rand.c: Change #include of
+ <gmp.h> to "gmp.h".
+ * randclr.c: Include stdlib.h for free().
+ * rand.c: Include gmp-impl.h.
+
+1999-05-12 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/configure.in: Put generic m68k alternative last.
+
+1999-05-04 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c (setup_error_handler): Use sigemptyset to create
+ empty set (for portability).
+ (fns): Fix typo '#if #if'.
+ (mpz_eval_expr): Implement FERMAT and MERSENNE.
+
+ * demos/pexpr.c: Cast longjmp argument via long to silent warnings on
+ 64-bit hosts.
+
+1999-05-03 Torbjorn Granlund <tege@swox.com>
+
+ * demos/pexpr.c: Add #defines for GMP 1.x and 2.0 compatibility.
+
+ * demos/pexpr.c (setup_error_handler): New function; take signal
+ handler setup code from main(), with major modifications to use modern
+ signal interface.
+ (main): Remove signal handler setup code; call setup_error_handler.
+
+1999-04-29 Linus Nordberg <linus@swox.se>
+
+ * tests/rand/findcl.c (main): Add option '-i' for interval factor.
+ Separate v and merit lose figures. Add '-v' for version.
+
+1999-04-28 Linus Nordberg <linus@swox.se>
+
+ * tests/rand/statlib.c: Change debugging stuff.
+
+ * tests/rand/gmpstat.h: Add debug values definitions.
+
+ * tests/rand/findcl.c (main): Print low and high merit on startup.
+ Print version string on startup. Catch SEGV and HUP. Add option -d
+ for debug. Fix bug making test for v too hard.
+ (sh_status): New function.
+ (sh_status): Flush stdout. Add RCSID.
+
+1999-04-27 Linus Nordberg <linus@swox.se>
+
+ * tests/rand/Makefile (clean): Add target.
+
+1999-04-27 Linus Nordberg <linus.nordberg@canit.se>
+
+ * tests/rand/stat.c: Include gmpstat.h.
+ Add global int g_debug.
+
+ * tests/rand/spect.c: Include <unistd.h>.
+
+ * tests/rand/findcl.c (main): Input is `m', not all factors of `m'.
+ Print only the very first matching multiplier. Include <unistd.h>.
+ Flush stdout. Print "done." when done.
+
+ * tests/rand/spect.c: Move everything but main() to statlib.c.
+
+ * tests/rand/findcl.c: New file.
+
+ * tests/rand/gmpstat.h: New file.
+
+ * tests/rand/statlib.c (merit, merit_u, f_floor, vz_dot,
+ spectral_test): New functions.
+
+1999-04-27 Torbjorn Granlund <tege@swox.com>
+
+ * mpn/configure.in: Fix typo, "sparc-*)" was "sparc)".
+
+1999-04-21 Torbjorn Granlund <tege@swox.com>
+
+ * config.sub: Recognize ev6.
+
+1999-04-12 Linus Nordberg <linus.nordberg@canit.se>
+
+ * urandom.c: Split up into randclr.c, randi.c, randi_lc.c,
+ randicom.c.
+ * randclr.c, randi.c, randi_lc.c, randicom.c: New files.
+ * Makefile.in: Remove urandom. Add randclr, randi, randi_lc,
+ randicom.
+ * make.bat: Ditto
+
+1999-03-31 Torbjorn Granlund <tege@matematik.su.se>
+
+ * configure.in (sparc9-*-solaris2.[789]*, etc): New alternative.
+ * mpn/configure.in: Use mt-sprc9 also for ultrasparc*-*-solaris2*.
+
+1999-03-30 Linus Nordberg <linus.nordberg@canit.se>
+
+ * urandom.c (__gmp_rand_scheme): Change NULL->0.
+ Include "gmp.h" instead of <gmp.h>.
+
+1999-03-29 Linus Nordberg <linus.nordberg@canit.se>
+
+ * gmp.h (__gmp_rand_data_lc): Now holds a, c, m instead of scheme
+ struct.
+ (__gmp_rand_lc_scheme_struct): Remove mpz_t's `a' and `m'.
+
+ * tests/rand/stat.c (f_freq): Don't print 2nd level results if doing
+ 1st level.
+
+ * tests/rand/gen.c (main): Set default algorithm to mpz_urandomb.
+ (main): Add option -c.
+
+1999-03-24 Linus Nordberg <linus.nordberg@canit.se>
+
+ * tests/rand/Makefile (GMPINC): Rename to GMPH.
+ (GMPH): Add gmp-mparam.h.
+ (CFLAGS): Add -I$(GMPLIBDIR)/mpn
+
+1999-03-23 Linus Nordberg <linus.nordberg@canit.se>
+
+ * Makefile.in: Compile top-dir/urandom.c.
+ * make.bat: Ditto.
+
+ * mpn/Makefile.in: Compile rawrandom.c.
+ * make.bat: Ditto.
+
+ * mpn/configure.in (functions): Add rawrandom.
+
+ * gmp.h (__gmp_rand_scheme_struct): Rename to
+ __gmp_rand_lc_scheme_struct.
+ (__gmp_rand_data_lc): Remove member 'n'. Allocate a
+ __gmp_rand_lc_scheme_struct instead of a pointer to one.
+ Add prototype for gmp_rand_init_lc(), mpn_rawrandom().
+ New prototype for mpz_urandomb().
+
+ * urandom.c: New file.
+ (__gmp_rand_init_common): New function.
+ (gmp_rand_init_lc): New function.
+ (gmp_rand_init): Don't init data_lc->n. Call gmp_rand_init_lc()
+ and __gmp_rand_init_common().
+ (gmp_rand_clear): Remove reference to data_lc->n.
+
+ * mpz/urandom.c (gmp_rand_init, gmp_rand_clear): Move to new file
+ urandom.c in top-dir.
+ (mpz_urandomb): Add function parameter nbits. Call mpn_rawrandom().
+
+ * mpf/urandom.c (mpf_urandomb): Call mpn_rawrandom().
+
+ * mpn/generic/rawrandom.c: New file.
+ (mpn_rawrandom): New function.
+
+1999-03-17 Torbjorn Granlund <tege@matematik.su.se>
+
+ * extract-dbl.c: When packing result, adjust exp when sc == 0.
+
+ * mpf/tests/t-get_d.c: New file.
+ * mpf/tests/Makefile.in: Compile t-get_d.c.
+
+1999-03-16 Linus Nordberg <linus.nordberg@canit.se>
+
+ * mpz/urandom.c (__gmp_rand_scheme): Add extra braces around the
+ mpz_t members.
+
+ * make.bat: Compile mpz/urandom.c and mpf/urandom.c
+
+ * tests/rand/statlib.c (ks_table): Use mpf_pow_ui() and exp().
+
+ * tests/rand/gen.c: Include unistd.h for getopt.
+
+1999-03-15 Linus Nordberg <linus.nordberg@canit.se>
+
+ * mpz/urandom.c (gmp_rand_init): New function.
+ (gmp_rand_clear): New function.
+ (mpz_urandomb): New function.
+
+ * mpz/Makefile.in: Compile urandom.c
+
+ * mpf/urandom.c (mpf_urandomb): New function.
+
+ * mpf/Makefile.in: Compile urandom.c.
+
+ * gmp.h (__gmp_rand_state_struct, __gmp_rand_scheme_struct): New
+ structs for randomization functions.
+ (gmp_rand_dist, gmp_rand_alogrithm): New enums for randomization
+ functions.
+ (mpz_urandomb, mpf_urandomb): Add prototype.
+ (gmp_rand_init, gmp_rand_clear): Add prototype.
+
+ * tests/rand/gen.c, stat.c, statlib.c, statlib.h: New files.
+ * tests/rand/Makefile, tests/rand/ChangeLog: New files.
+
+1999-03-15 Torbjorn Granlund <tege@matematik.su.se>
+
+ * .gdbinit: New file.
+
+ * mpz/dump.c: New file.
+ * mpz/Makefile.in: Compile dump.c.
+ * make.bat: Likewise.
+ * gmp.h (mpz_dump): Declare.
+
+1999-03-14 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/tests/reuse.c: Also test mpz_invert and mpz_divexact.
+
+ * mpz/tests/convert.c: Update to GMP 2 variable syntax.
+
+1999-03-13 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/README: New file.
+ * mpz/README: New file.
+
+ * mpf/pow_ui.c: New file.
+ * mpf/Makefile.in: Compile pow_ui.c.
+ * make.bat: Likewise.
+ * gmp.h (mpf_pow_ui): Declare.
+
+1999-03-12 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/configure.in: Stage 1 of rewrite.
+ * mpn/underscore.h: New name for bsd.h.
+ * mpn/sysv.h: Deleted.
+
+ * mpn/m68k/*: Don't include sysdep.h.
+
+ * mpn/pa64/README: New file.
+
+1999-03-11 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/powerpc32/add_n.S: Add support for both AIX and ELF syntax.
+ Renamed from `.s'.
+ * mpn/powerpc32/sub_n.S: Likewise.
+ * mpn/powerpc32/lshift.S: Likewise.
+ * mpn/powerpc32/rshift.S: Likewise.
+ * mpn/powerpc32/mul_1.S: Likewise.
+ * mpn/powerpc32/addmul_1.S: Likewise.
+ * mpn/powerpc32/submul_1.S: Likewise.
+
+ * mpn/powerpc32/umul.S: New file.
+ * mpn/sparc32/v8/umul.S: New file.
+ * mpn/sparc32/umul.S: New file.
+ * mpn/x86/umul.S: New file.
+ * mpn/x86/udiv.S: New file.
+
+ * mpn/Makefile.in (mul_basecase.o): Delete rule.
+
+1999-02-22 Torbjorn Granlund <tege@matematik.su.se>
+
+ * configure.in (hppa2.0*-*-*): Force use of GCC.
+
+ * extract-dbl.c: Handle IEEE denormalized numbrs. Clean up.
+
+1998-12-02 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/Makefile.in (CCAS): New macro.
+ (.s.o): Use CCAS.
+ (.S.o): Likewise.
+
+ * mpn/Makefile.in (mul_basecase.o): Add dependency.
+ (sqr_basecase.o): Likewise.
+ (mod_1.o): Likewise.
+
+ * demos/pexpr.c (cputime): Test also __hpux.
+ (cleanup_and_exit): Check SIGXCPU only #ifdef LIMIT_RESOURCE_USAGE.
+
+ * mpz/tests/t-2exp.c: Use urandom, not random.
+
+ * mpn/configure.in (arm*-*-*): New alternative.
+
+1998-11-30 Torbjorn Granlund <tege@matematik.su.se>
+
+ * gmp-impl.h (union ieee_double_extract): Special case for
+ little-endian arm.
+ (LIMBS): Alias for PTR.
+
+1998-11-26 Torbjorn Granlund <tege@matematik.su.se>
+
+ * longlong.h (m68000 umul_ppmm): Use `muluw', not `mulu'.
+ (m68k stuff): Clean up; add coldfire support.
+
+1998-11-23 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/mips3/gmp-mparam.h (KARATSUBA_MUL_THRESHOLD): #define.
+ (KARATSUBA_SQR_THRESHOLD): #define.
+
+ * mpn/sparc32/v9/README: New file.
+
+1998-11-20 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/x86/README: New file.
+
+ * mpn/arm/gmp-mparam.h: New file.
+ * mpn/pa64/gmp-mparam.h: New file.
+ * mpn/hppa/gmp-mparam.h: New file.
+ * mpn/x86/pentium/gmp-mparam.h: New file.
+ * mpn/sparc32/v9/gmp-mparam.h: New file.
+ * mpn/powerpc32/gmp-mparam.h: New file.
+ * mpn/x86/p6/gmp-mparam.h: New file.
+
+ * mpn/alpha/gmp-mparam.h (KARATSUBA_MUL_THRESHOLD): #define.
+ (KARATSUBA_SQR_THRESHOLD): #define.
+
+ * mpn/configure.in: Point to x86/p6 when appropriate.
+
+ * mpn/power/umul.s: New file.
+ * mpn/power/sdiv.s: New file.
+ * mpn/pa64/addmul_1.S: New file.
+ * mpn/pa64/submul_1.S: New file.
+ * mpn/pa64/mul_1.S: New file.
+ * mpn/pa64/udiv_qrnnd.c: New file.
+ * mpn/pa64/umul_ppmm.S: New file.
+ * mpn/mips2/umul.s: New file.
+ * mpn/m68k/mc68020/umul.s: New file.
+ * mpn/m68k/mc68020/udiv.s: New file.
+ * mpn/hppa/hppa1_1/umul.s: New file.
+ * mpn/alpha/umul.s: New file.
+ * mpn/a29k/udiv.s: New file.
+ * mpn/a29k/umul.s: New file.
+
+1998-11-17 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/x86/mul_basecase.S: New file for non-pentiums.
+ * mpn/x86/mul_basecase.S: Move to mpn/x86/pentium.
+
+1998-11-16 Torbjorn Granlund <tege@matematik.su.se>
+
+ * make.bat: Compile mul_basecase.c and sqr_basecase.c.
+
+1998-11-10 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/invert.c: Defer writing to parameter `invert' until
+ end.
+
+1998-11-03 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/pa64/udiv_qrnnd.c: Handle more border cases.
+
+1998-10-29 Torbjorn Granlund <tege@matematik.su.se>
+
+ * insert-dbl.c: Special case biased exponents < 1; Get boundary for
+ Inf right.
+
+ * longlong.h (COUNT_LEADING_ZEROS_NEED_CLZ_TAB): New #define.
+
+1998-10-28 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/powerpc32/submul_1.s: Rewrite, optimizing for PPC604.
+ * mpn/powerpc32/addmul_1.s: Likewise.
+ * mpn/powerpc32/lshift.s: Likewise.
+
+1998-10-23 Torbjorn Granlund <tege@matematik.su.se>
+
+ * config/mt-sprc9-gcc (XCFLAGS): Add -Wa,-xarch=v8plus.
+
+ * mpn/sparc32/v9/submul_1.s: New file.
+
+1998-10-21 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/config/mt-pa2hpux: New file.
+ * mpn/configure.in (hppa2.0*-*-*): Use new 64-bit code.
+
+ * config.sub: Recognize hppa2.0 as CPU type.
+
+ * longlong.h (64-bit hppa): Add umul_ppmm and udiv_qrnnd.
+ * mpn/pa64/mul_1.S: New file.
+ * mpn/pa64/addmul_1.S: New file.
+ * mpn/pa64/submul_1.S: New file.
+ * mpn/pa64/umul_ppmm.S: New file.
+ * mpn/pa64/udiv_qrnnd.c: New file.
+
+1998-10-20 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/pprime_p.c: Pass 1L, not 1, to mpz_cmp_ui.
+
+ * mpz/fdiv_q_2exp.c: Cast `long' argument to `mp_limb_t' for mpn calls.
+ * mpz/gcd_ui.c: Likewise.
+ * mpz/add_ui.c: Likewise.
+ * mpz/sub_ui.c: Likewise.
+
+1998-10-19 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/generic/bdivmod.c: Avoid using switch statement with mp_limb_t
+ index.
+
+1998-10-17 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/sparc32/v9/mul_1.s: Misc cleanups.
+ * mpn/sparc32/v9/addmul_1.s: Misc cleanups.
+
+1998-10-16 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/tests/{add,sub,}mul_1.c: Print xlimb using mpn_print.
+
+ * mpz/tests/t-powm.c (SIZE): Increase to 50.
+ (EXP_SIZE): New parameter; use it for computing exp_size.
+
+1998-10-15 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/generic/divrem_newt.c: Use TMP_ALLOC interface.
+
+ * mpn/generic/sqrtrem.c: Check BITS_PER_MP_LIMB before defining
+ assembly variants of SQRT.
+
+1998-10-14 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/tests: Clean up timing routines. Don't include longlong.h
+ where it is not needed.
+ (mpn_print): Handle printing when _LONG_LONG_LIMB.
+ * mpn/tests/{add,sub,}mul_1.c: Generate xlimb with mpn_random2
+ and do it whether TIMES != 1 or not.
+
+ * mpn/generic/mul_n.c: Delay assignment of `sign' for lower
+ register pressure.
+
+ * mpn/sparc32/v9/mul_1.s: New file.
+
+ * config/mt-sprc9-gcc: New file.
+ * configure.in: Use it.
+
+ * mpn/configure.in: Use sparc64 for Solaris 2.7 and later with a
+ sparc v9 CPU.
+ * mpn/configure.in: Use sparc32/v9 for Solaris 2.6 or earlier with
+ a sparc v9 CPU.
+
+ * mpf/sub.c: In initial code for ediff == 0, limit precision
+ before jumping to `normalize'.
+
+1998-10-13 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/hppa/hppa2_0/add_n.s: New file.
+ * mpn/hppa/hppa2_0/sub_n.s: New file.
+ * mpn/configure.in: Handle hppa2.0 (32-bit code for now).
+
+ * config.guess: Update from egcs 1.1.
+ (9000/[3478]??:HP-UX:*:*): Properly return 2.0 for all known 2.0
+ machines.
+
+1998-10-07 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/root.c (mpz_root): New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_root): Declare.
+
+ * mpz/perfpow.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_perfect_power_p): Declare.
+
+ * mpz/remove.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_remove): Declare.
+
+ * mpz/bin_ui.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_bin_ui): Declare.
+
+ * mpz/bin_uiui.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_bin_uiui): Declare.
+
+1998-09-16 Torbjorn Granlund <tege@matematik.su.se>
+
+ * longlong.h: Test for __powerpc__ in addition to _ARCH_PPC.
+
+Sat Sep 5 17:22:28 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/cmp_si.c: Compare most significant mantissa limb before
+ trying to deduce anything from the limb count.
+ * mpf/cmp_ui.c: Likewise.
+
+Tue Aug 18 10:24:39 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/pprime_p.c (mpz_probab_prime_p): Add new code block
+ for doing more dividing.
+
+Sat Aug 15 18:43:17 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/generic/divrem_newt.c: New name for divrem_newton.c.
+ * mpn/Makefile.in: Corresponding changes.
+ * mpn/configure.in: Likewise.
+
+Wed Aug 12 23:07:09 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * config.guess: Handle powerpc for NetBSD.
+
+Tue Jul 28 23:10:55 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/fib_ui.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_fib_ui): Declare.
+
+Wed Jun 17 22:52:58 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * make.bat: Fix typo, `asm-synt.h' => `asm-syntax.h'.
+
+Wed Jun 3 11:27:32 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * config/mt-pwr: New file.
+ * config/mt-ppc: New file.
+ * configure.in: Use the new files.
+
+Tue Jun 2 13:04:17 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/sparc32/v9/addmul_1.s: New file.
+ * mpn/config/mt-sprc9: New file.
+ * mpn/configure.in: Use mt-sprc9.
+
+Tue May 26 11:24:18 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * demos/factorize.c (factor_using_pollard_rho): Pass correct
+ parameters in recursive calls; join the two recursion arms.
+
+ * mpf/set_q.c: Set result sign.
+ When normalizing the numerator, don't allow it to increase in size
+ beyond prec.
+
+Tue May 19 17:28:14 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * demos/factorize.c (factor_using_division): Call fflush
+ also for the factor 2.
+
+Mon May 18 15:51:01 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * make.bat: Pass -fomit-frame-pointer. Do not pass -g.
+
+Tue May 5 01:42:50 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/Makefile.in (LOCAL_CC): Remove definition.
+
+ * gmp.h: Get rid of GMP_SMALL stuff.
+ * mpz/Makefile.in: Likewise.
+ * mpq/Makefile.in: Likewise.
+ * mpf/Makefile.in: Likewise.
+
+ * mpz/invert.c: Fix typo in comment.
+
+Mon May 4 23:05:32 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/generic/sqrtrem.c: Check that __arch64__ is not defined
+ before defining sparc SQRT.
+
+Mon Apr 20 19:16:17 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/generic/gcdext.c: Allow gp to be NULL.
+
+1998-04-03 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/configure.in: Recognize `alphaev5*', not `alphaev5'.
+
+ * config.guess: Handle CPU variants for NetBSD.
+
+Mon Mar 16 13:07:54 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/pprime_p.c: Use mpn_mod_1/mpn_preinv_mod_1 for computing mod PP,
+ not mpz_tdiv_r_ui (which expects an `unsigned long').
+ (mpz_probab_prime_p): Change type of `r' to mp_limb_t.
+
+Thu Mar 12 17:19:04 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * gmp.h (mpf_ceil, mpf_floor, mpf_trunc): Add declarations.
+
+ * config.guess: Update from FSF version.
+ * config.sub: Likewise.
+
+ * config.guess: Add special handling of alpha-*-NetBSD.
+
+Wed Mar 11 00:55:34 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/inp_str.c: Update from set_str.c.
+ Properly increment `nread' when skipping minus sign.
+
+ * mpz/set_str.c: Check for empty string after having skipped
+ leading zeros.
+
+Mon Mar 9 19:28:00 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/set_str.c: Skip leading zeros.
+
+Wed Mar 4 19:29:16 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * gmp.h (mpz_cmp_si): Cast argument before calling mpz_cmp_ui.
+
+ * demos/factorize.c: Rewrite.
+
+1998-02-04 Torbjorn Granlund <tege@matematik.su.se>
+
+ * configure.in (i[3456]86* etc): Check if using gcc before
+ choosing mt-x86.
+
+ * configure.in (m68*-*-*): New alternative.
+ * config/mt-m68k: New file.
+
+ * mpn/alpha/invert-limb.s: Put tables in text segment,
+ since not all systems support "rdata".
+
+Wed Feb 4 02:20:57 1998 Torbjorn Granlund <tege@matematik.su.se>
+
+ * gmp.h (__GNU_MP_VERSION_SNAP): New #define.
+ (__GNU_MP_VERSION_MINOR): Now 1.
+
+Wed Jan 28 22:29:36 1998 Torbjorn Granlund <tege@tunnis.tmg.se>
+
+ * longlong.h (alpha udiv_qrnnd): #define UDIV_NEEDS_NORMALIZATION.
+
+Wed Jan 28 20:28:19 1998 Torbjorn Granlund <tege@sophie.matematik.su.se>
+
+ * mpz/pprime_p.c (mpz_probab_prime_p): Delete 59 from tried divisors.
+
+Mon Jan 26 01:39:02 1998 Torbjorn Granlund <tege@tunnis.tmg.se>
+
+ * mpz/pprime_p.c (mpz_probab_prime_p): Major overhaul: Check small
+ numbers specifically; check small factors, then perform a fermat test.
+
+Tue Jan 13 14:58:28 1998 Torbjorn Granlund <tege@tunnis.tmg.se>
+
+ * longlong.h (alpha udiv_qrnnd): Call __mpn_invert_normalized_limb
+ and udiv_qrnnd_preinv.
+
+Wed Jan 7 01:52:54 1998 Torbjorn Granlund <tege@tunnis.tmg.se>
+
+ * mpn/configure.in (alpha*, extra_functions): Add invert-limb and
+ remove udiv_qrnnd.
+
+ * mpn/tests/divrem.c: Get allocations right.
+
+ * mpn/generic/divrem.c: Conditionally pre-invert most significant
+ divisor limb.
+
+Tue Jan 6 23:08:54 1998 Torbjorn Granlund <tege@tunnis.tmg.se>
+
+ * mpn/generic/divrem_1.c: Rename variables to comply to conventions.
+ Make `i' have type `mp_size_t'.
+
+Tue Dec 30 22:21:42 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/tdiv_qr_ui.c: Return the remainder.
+ * mpz/tdiv_r_ui.c: Likewise.
+ * mpz/tdiv_q_ui.c: Likewise.
+ * gmp.h: Change return type of mpz_tdiv_qr_ui, mpz_tdiv_r_ui,
+ mpz_tdiv_q_ui.
+
+ * mpz/tdiv_ui.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_tdiv_ui): Declare.
+
+Fri Nov 7 04:21:15 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/integer.c (FUNC_NAME): Fix bogus test for mpf_trunc.
+
+ * demos/isprime.c: New file.
+
+ Sat Nov 1 19:32:25 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/cmp_abs.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_cmp_abs): Declare.
+
+ * mpz/cmp_abs_ui.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_cmp_abs_ui): Declare.
+
+Sat Sep 27 04:49:52 1997 Torbjorn Granlund <tege@tunnis.tmg.se>
+
+ * mpz/fdiv_r_2exp.c: Get allocation for `tmp' right.
+
+ * mpz/fdiv_q_2exp.c: In final result adjustment code, handle
+ that intermediate result is zero.
+
+ * mpz/tests/t-2exp.c: New file.
+ * mpz/tests/Makefile.in: Handle t-2exp.c.
+
+Fri Sep 26 16:29:21 1997 Torbjorn Granlund <tege@tunnis.tmg.se>
+
+ * mpz/divexact.c: Fix typo in test for whether to copy numerator to
+ quotient and move that statement to after handling quotient and
+ denominator overlap. Misc cleanups.
+
+ * mpn/generic/gcd.c: Change count argument of mpn_lshift/mpn_rshift
+ calls to `unsigned int'.
+ * mpz/divexact.c: Likewise.
+
+Mon Sep 22 02:19:52 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpz/tests/t-powm.c: Decrease `reps' to 2500.
+
+ * mpz/tests/t-pow_ui.c: New file.
+ * mpz/tests/Makefile.in: Handle t-pow_ui.c.
+
+ * mpz/ui_pow_ui.c: Get special cases for exponent and base right.
+
+ * mpz/pow_ui.c: Increase temp space allocation by 1 limb.
+ Split `rsize' into two variables; compute space allocation into
+ `ralloc'.
+
+Sun Sep 7 04:15:12 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpn/pa64/lshift.s: New file.
+ * mpn/pa64/rshift.s: New file.
+ * mpn/pa64/sub_n.s: New file.
+
+Sat Sep 6 19:14:13 1997 Torbjorn Granlund <tege@gmp.tmg.se>
+
+ * mpn/pa64/add_n.s: New file.
+ * mpn/pa64: New directory.
+
+Tue Aug 19 16:17:09 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpz/swap.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_swap): Declare.
+
+ * mpn/generic/mul_n.c: Push assignment of x and y pointers into the
+ if/else clauses in several places. (Decreases register pressure.)
+
+Mon Aug 18 03:29:50 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpn/thumb/add_n.s: New file.
+ * mpn/thumb/sub_n.s: New file.
+ * mpn/arm/add_n.s: New file.
+ * mpn/arm/sub_n.s: New file.
+
+ * mpz/powm.c: After mpn_mul_n and mpn_mul calls, adjust product size
+ if most significant limb is zero.
+ * mpz/powm_ui.c: Likewise.
+
+Fri Aug 15 02:13:57 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpn/arm/m/mul_1.s: New file.
+ * mpn/arm/m/addmul_1.s: New file.
+
+ * mpn/powerpc32/mul_1.s: Rewrite.
+
+ * mpn/alpha/mul_1.s: Prefix labels with `.'.
+
+Mon Aug 11 02:37:16 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpn/powerpc32/add_n.s: Rewrite.
+ * mpn/powerpc32/sub_n.s: Rewrite.
+
+Sun Aug 10 17:07:15 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpn/powerpc32/addmul_1.s: Delete obsolete comments.
+ * mpn/powerpc32/submul_1.s: Likewise.
+
+Fri Jul 25 20:07:54 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpz/addmul_ui.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_addmul_ui): Declare.
+
+ * mpz/setbit.c: Add missing code after final `else'.
+
+Tue Jul 22 17:45:01 1997 Torbjorn Granlund <tege@tunnis.tmg.se>
+
+ * mpn/sh/add_n.s: Fix typo.
+ * mpn/sh/sub_n.s: Likewise.
+
+ * longlong.h (ns32k count_trailing_zeros): Fix typo.
+
+ * insert-dbl.c: Check for exponent overflow and return Inf.
+
+ * mpz/get_d.c: Rewrite to avoid rounding errors.
+
+Thu May 29 11:51:07 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpq/add.c: Swap some usages of tmp1 and tmp2 to make sure
+ their allocation suffices.
+ * mpq/sub.c: Likewise.
+
+Wed Apr 16 02:24:25 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * demos/pexpr.c: New file.
+
+ * mpn/generic/mul_n.c: Misc optimizations from Robert Harley.
+
+ * gmp-impl.h (MPZ_PROVOKE_REALLOC): New #define.
+
+Sat Apr 12 17:54:04 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * mpz/tstbit.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_tstbit): Declare.
+
+ * mpz/tests/logic.c: Use MPZ_CHECK_FORMAT.
+ * mpz/tests/bit.c: New test.
+ * mpz/tests/Makefile.in: Handle bit.c.
+
+ * mpz/ior.c: In -OP2,+OP1 case, normalize OP2 after call to mpn_sub_1.
+
+ * gmp-impl.h (MPZ_CHECK_FORMAT): New #define.
+
+Thu Apr 10 00:30:14 1997 Torbjorn Granlund <tege@tmg.se>
+
+ * longlong.h (POWER/PowerPC): Test _ARCH_PWR instead of _IBMR2.
+
+Wed Apr 9 18:23:31 1997 Torbjorn Granlund <tege@pro.tmg.se>
+
+ * gmp-impl.h: Move defaulting of UMUL_TIME and UDIV_TIME from here...
+ * longlong.h: ...to here.
+
+Sun Mar 30 12:16:23 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/generic/next_prime.c: New file.
+
+ * mpn/generic/perfsqr.c: Remove definitions of PP and PP_INVERTED.
+ * gmp-impl.h: Put them here.
+
+Fri Mar 28 08:18:05 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * gmp-impl.h (MPN_COPY_INCR, MPN_COPY_DECR): Define as inline asm for
+ for x86, but leave disabled for now.
+
+Fri Feb 28 02:39:47 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/Makefile.in (.S.o): Pass SFLAGS and CFLAGS also to compiler
+ for assembly phase.
+ (.s.o): Pass SFLAGS.
+
+Wed Feb 26 06:46:08 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/configure.in: For Pentium Pro, use default code, not Pentium
+ optimized code.
+
+ * mpn/x86/addmul_1.S: Unroll and optimize for Pentium Pro.
+ * mpn/x86/submul_1.S: Likewise.
+
+Thu Feb 13 08:26:09 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/Makefile.in: Compile floor.o, ceil.o and trunc.o (from
+ integer.c).
+ * make.bat: Likewise.
+
+Wed Feb 5 05:58:44 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/configure.in (alpha*): Add cntlz to extra_functions.
+
+Wed Feb 4 03:30:45 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/integer.c: New file (supporting mpf_floor, mpf_ceil, mpf_trunc).
+
+Mon Feb 3 14:21:36 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * make.bat: Fix typo, set_dfl_prc => set_dfl_prec.
+
+Sun Feb 2 02:34:33 1997 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/out_str.c: After outputting `-', decrement n_digits.
+
+Wed Jan 8 02:50:20 1997 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/generic/divrem.c: qextra_limbs => qxn.
+
+Wed Dec 18 07:50:46 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpz/tests/t-tdiv.c (SIZE): Increase to 200.
+
+Tue Dec 17 19:32:48 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/generic/divrem.c (mpn_divrem_classic): New name for mpn_divrem.
+ * gmp.h (mpn_divrem): New function.
+ * mpn/generic/divrem_newton.c: New file.
+ * mpn/configure.in (functions): Add divrem_newton.
+ * make.bat: Likewise.
+
+Thu Dec 12 17:55:13 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * gmp.h (_GMP_H_HAVE_FILE): Test also __dj_include_stdio_h_.
+
+Sat Dec 7 09:40:06 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/alpha/invert-limb.s: New file.
+
+Thu Dec 5 01:25:31 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpz/ui_pow_ui.c (mpz_pow2): New (static) function.
+ (mpz_ui_pow_ui): Rewrite.
+
+ * make.bat: `pre_mod_1.c' => `pre_mod_.c'. Fix typo in path to
+ gmp-mpar.h.
+
+Fri Nov 15 00:49:55 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpz/ui_pow_ui.c: Rewrite for better speed.
+
+Fri Nov 1 16:36:56 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * Makefile.in (recursive make rules): Use `&&' instead of `;' as
+ delimiter.
+
+Fri Oct 25 17:12:36 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * gmp-impl.h (Cray/uxp MPN_COPY): Really declare as inline.
+
+Thu Oct 24 15:08:19 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/fujitsu/rshift.c: Fix typo in loop boundaries.
+
+Fri Oct 18 03:13:54 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/configure.in: Recognize `nextstep' for m68k variants; likewise
+ for x86 variants.
+
+ * mpn/x86/syntax.h (INSND): New macro.
+ * mpn/x86/[lr]shift.S: Use INSND.
+ * mpn/x86/pentium/[lr]shift.S: Likewise.
+ * mpn/config/t-oldgas (SFLAGS): Pass -DOLD_GAS.
+
+ * gmp-impl.h: In code for determining endianness, test also
+ __BIG_ENDIAN__ and __hppa__. Remove test of __NeXT__.
+
+Wed Oct 16 03:50:34 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpf/set_str.c: Let `prec' determine precision used in
+ exponentiation code; decrease allocation accordingly.
+
+ * mpn/vax: Change `jsob*' to `sob*' in all files.
+
+Tue Oct 15 03:54:06 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * longlong.h (m88110 udiv_qrnnd): Change type of intermediate quotient
+ to DImode (divu.d generates a 64-bit quotient).
+
+ * configure.in (m88110*): Fix typo.
+
+ * mpf/get_str.c: Compute exp_in_base using `double' to avoid overflow.
+
+ * gmp-impl.h (struct bases): Change type of chars_per_bit_exactly from
+ float to double.
+ * mpn/mp_bases.c (__mp_bases): Give 17 digits for chars_per_bit_exactly
+ field.
+
+ * mpf/get_str.c: Let `prec' determine precision used in
+ exponentiation code; decrease allocation accordingly.
+
+Sun Oct 13 03:31:53 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * longlong.h: Major cleanup.
+ (__udiv_qrnnd_c): Compute remainders using multiply and subtract,
+ not explicit `%' operator.
+ (C umul_ppmm): Get rid of a redundant __ll_lowpart.
+
+ * mpz/invert.c: Properly detect all operands that would yield an
+ undefined inverse; make sure the inverse is always positive.
+
+ * mpz/xor.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_xor): Declare.
+
+ * mpz/tests/logic.c: Also test mpz_xor.
+
+ * mpz/lcm.c: Special case for when either operand equals 0.
+
+Sat Oct 12 01:57:09 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/generic/gcd.c (find_a): Don't inline on x86.
+
+ * Makefile.in (CFLAGS): Default to just `-g'.
+
+ * configure.in: Recognize 386 and 486 wherever other x86 cpus are
+ recognized.
+ * configure.in: Use mt-x86 for all x86 cpus.
+ * config/mt-x86: New file.
+
+ * mpn/alpha/cntlz.s: New file.
+
+Tue Oct 8 00:16:18 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * longlong.h: Define smul_ppmm for Fujitsu vpp/uxp.
+ Rewrite umul_ppmm to actually work on the hardware.
+
+ * mpn/x86/sub_n.S: Avoid parens around displacement of `leal'.
+ * mpn/x86/add_n.S: Likewise.
+
+ * mpn/x86/syntax.h (R): Define differently depending on __STDC__.
+
+Mon Oct 7 16:48:08 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * longlong.h: Don't test for __NeXT__ in outer 68k conditional;
+ add test for __m68k__.
+
+Sun Oct 6 00:59:09 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * gmp.h: Declare mpn_random.
+ * make.bat: Compile mpn/generic/random.c.
+
+ * longlong.h: Define umul_ppmm for Fujitsu vpp/uxp.
+
+ * gmp-impl.h: Protect definitions using `__attribute__ ((mode (...)))'
+ with test also for __GNUC_MINOR__.
+
+ * gmp.h: Don't define macros using __builtin_constant_p when using
+ NeXT's compiler.
+
+Fri Oct 4 16:53:50 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpz/lcm.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h (mpz_lcm): Declare.
+
+Wed Sep 25 00:06:21 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpq/tests/t-cmp_ui.c: Make sure numerator and denominator of `b' is
+ within limits of an `unsigned long int'.
+
+ * mpz/tests/t-powm_ui.c: Change type of exp2 to `unsigned long int'.
+
+Tue Sep 24 18:58:20 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpz/powm_ui.c: Make result always positive.
+
+ * urandom.h (urandom): Make it return mp_limb_t.
+
+ * gmp-impl.h (CNST_LIMB): New macro.
+ * mpn/mp_bases.c: Use CNST_LIMB.
+ * mpn/generic/hamdist.c (popc_limb): Likewise.
+ * mpn/generic/popcount.c (popc_limb): Likewise.
+ * mpn/generic/perfsqr.c: Likewise.
+
+Fri Sep 20 03:08:10 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpz/pprime_p.c: When n <= 3, don't clear out n before using it.
+
+Wed Sep 18 11:22:45 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/fujitsu/mul_1.c: New file.
+ * mpn/fujitsu/addmul_1.c: New file.
+ * mpn/fujitsu/sub_n.c: New file.
+ * mpn/fujitsu/add_n.c: Mew file.
+
+Sun Sep 15 03:13:02 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/generic/random.c: New file.
+ * mpn/configure.in (functions): Add `random'.
+
+ * gmp-impl.h (MPN_COPY): Define as annotated inline function for
+ Crays and Fujitsu VPPs.
+
+ * gmp.h (mp_size_t): Define as `int' for non-MPP Cray.
+ (mp_exp_t): Likewise.
+
+ * configure.in: Add support for Fujitsu VPP machines.
+ * mpn/configure.in: Likewise.
+ * config.guess: Likewise.
+ * config.sub: Likewise.
+
+ * mpn/fujitsu/rshift.c: New file.
+ * mpn/fujitsu/lshift.c: New file.
+ * mpn/fujitsu: New directory, for Fujitsu VPP machines.
+
+Wed Sep 11 11:34:38 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/generic/mul_n.c (__gmpn_mul_n): New name for impn_mul_n.
+ Call __gmpn_mul_basecase, not impn_mul_n_basecase; update parameter
+ list to work with __gmpn_mul_basecase.
+ (__gmpn_sqr): New name for impn_sqr_n.
+ Call __gmpn_sqr_basecase, not impn_sqr_n_basecase; update parameter
+ list to work with __gmpn_sqr_basecase.
+ (mpn_mul_n): Update calls to match new names and parameter conventions.
+ * gmp-impl.h (MPN_MUL_N_RECURSE): Likewise.
+ (MPN_SQR_RECURSE): New name for MPN_SQR_N_RECURSE.
+ Update calls to match new names and parameter conventions.
+ * mpn/generic/mul.c: Never perform multiply explicitly here, call
+ __gmpn_mul_basecase instead.
+ Update calls to match new names and parameter conventions.
+
+ * mpn/x86/mul_basecase.S: New file.
+ * mpn/generic/mul_basecase.c: New file.
+ * mpn/generic/sqr_basecase.c: New file.
+
+Wed Sep 4 02:59:21 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpz/set_str.c: Let `0b' and `0B' mean base 2.
+
+Fri Aug 30 00:44:00 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * longlong.h (x86 umul_ppmm): Work around GCC bug that was
+ triggered by Aug 28 change.
+
+ * mpbsd/min.c (digit_value_in_base): New function.
+
+ * mpz/set_str.c: Refine allocation size computation, use
+ chars_per_bit_exactly instead of chars_per_limb.
+
+ * mpbsd/Makefile.in (.c.o): Add -D_mpz_realloc=_mp_realloc.
+
+Wed Aug 28 02:52:14 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * longlong.h (x86 umul_ppmm): Don't cast result operands.
+ (x86 udiv_qrnnd): Likewise.
+ (default smul_ppmm): Fix typo, umul_ppmm => smul_ppmm.
+ (default umul_ppmm): New #define using smul_ppmm.
+ (vax smul_ppmm): New #define.
+ (vax umul_ppmm): Delete.
+ (POWER umul_ppmm): Delete.
+ (IBM 370 smul_ppmm): New #define.
+ (IBM 370 umul_ppmm): Delete.
+ (IBM RT/ROMP smul_ppmm): New #define.
+ (IBM RT/ROMP umul_ppmm): Delete.
+
+Tue Aug 27 01:03:25 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * gmp-impl.h (__gmp_0): Make it `const'.
+
+ * mpn/Makefile.in (clean mostlyclean): Comment out recursive clean
+ of `tests'.
+
+ * mpn/generic/mul.c: Identify when we do squaring, and call
+ impn_sqr_n_basecase/impn_sqr_n as appropriate. Use
+ KARATSUBA_MUL_THRESHOLD and KARATSUBA_SQR_THRESHOLD.
+ Don't #define KARATSUBA_THRESHOLD.
+
+ * mpn/generic/mul_n.c: Don't #define KARATSUBA_THRESHOLD.
+ (impn_mul_n, impn_sqr_n): Rewrite, based on code contributed by
+ Robert Harley.
+ (impn_sqr_n_basecase): Rewrite.
+
+ * gmp-impl.h (KARATSUBA_MUL_THRESHOLD): New #define.
+ (KARATSUBA_SQR_THRESHOLD): Likewise.
+ (MPN_SQR_N_RECURSE): Use KARATSUBA_SQR_THRESHOLD.
+ (MPN_MUL_N_RECURSE): Use KARATSUBA_MUL_THRESHOLD.
+
+ * configure.in: Fix typo in last change.
+
+Mon Aug 26 22:25:18 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpn/generic/random2.c: Fix typo, `alpha__' => `__alpha'.
+ * mpf/random2.c: Likewise.
+
+Sun Aug 25 00:07:09 1996 Torbjorn Granlund <tege@quiet.matematik.su.se>
+
+ * mpz/tests/t-mul.c: Also test squaring.
+
+Fri Aug 16 05:12:08 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mp_clz_tab.c (__clz_tab): Declare as `const'.
+ * version.c (gmp_version): Likewise.
+ * mpn/generic/sqrtrem.c (even_approx_tab, odd_approx_tab): Likewise.
+
+Thu Aug 15 02:34:47 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp.h: Fix typo, `mips__' => `__mips'.
+
+ * mpf/set_str.c: Allow a number to start with a period, if next
+ position contains a digit.
+
+Tue Aug 13 18:41:25 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/gcdext.c: Get cofactor sign right for negative input operands.
+ Clean up code for computing tt.
+
+ * mpz/invert.c: Get rid of variable `rv'.
+
+ * mpz/divexact.c: Test for zero divisor in special case for zero
+ dividend.
+
+Mon Aug 12 18:04:07 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/?div_*_ui.c: Special case for division by 0.
+ * mpz/tdiv_q.c: Likewise.
+
+Sat Aug 10 14:45:26 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/dmincl.c: Special case for division by 0.
+
+ * mpz/tdiv_*_ui.c: Delete special case for dividend being 0; handle
+ it when computing size after mpn_divmod_1 call.
+
+ * mp_bpl.c: (__gmp_junk): New variable.
+ (__gmp_0): New constant.
+
+ * gmp-impl.h (DIVIDE_BY_ZERO): New #define.
+
+Fri Aug 9 20:03:27 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/divexact.c: Test for dividend being zero before testing
+ for small divisors.
+
+Thu Aug 8 13:20:23 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * configure.in: Require operating system specification for cpus
+ where assembly syntax differs between system.
+
+ * Makefile.in (many targets): Change `-' action prefix to `@'.
+
+ * mpn/Makefile.in: (distclean): Fix typo.
+
+ * mpq/cmp_ui.c: Rename function to _mpq_cmp_ui.
+ (mpq_cmp_ui): #undef deleted.
+ * mpz/cmp_si.c: Rename function to _mpz_cmp_si.
+ (mpz_cmp_si): #undef deleted.
+ * mpz/cmp_ui.c: Rename function to _mpz_cmp_ui.
+ (mpz_cmp_ui): #undef deleted.
+ * Makefile.in: Corresponding changes.
+
+ * mpf/get_prc.c: Return the *highest* precision achievable.
+
+ * mpf/get_str.c: Complete rewrite.
+
+ * mpf/set_str.c (swapptr): New #define.
+ (assert): New #define.
+ * mpf/set_str.c: Set prec to one more than the saved _mp_prec.
+ Misc cleanups.
+
+ * mpz/set_str.c: #include string.h.
+ * mpf/out_str.c: #include string.h.
+ * mpbsd/xtom.c: #include string.h and ctype.h.
+ * mpbsd/mout.c: #include string.h.
+
+Wed Aug 7 11:46:04 EDT 1996 Ken Weber <kweber@mcs.kent.edu>
+
+ * mpn/generic/gcd.c: Reorder mpn_gcd argument list.
+ * mpz/gcd.c: Change call to mpn_gcd.
+ * gmp.texi: Update manual entry on mpn_gcd.
+ * mpn/generic/bdivmod.c: Delete limb cache to make mpn_bdivmod
+ reentrant.
+
+Wed Aug 7 02:15:38 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/get_str.c: Rewrite code for converting integral part of a
+ number with both an integral and fractional part.
+
+ * mpf/set_str.c: Get rid of variable xxx. New variables madj and radj.
+ In exp_in_base==0 case, add madj to msize for EXP field.
+
+ * mpz/tests/t-gcd.c: Test deleted. Rename t-gcd2.c to t-gcd.c.
+ Increase reps to 2000.
+ * mpz/tests/t-gcd2.c: Get rid of mpz_refgcd.
+
+ * mpf/set_str.c: Ignore excess limbs in MP,MSIZE.
+
+Thu Jul 25 04:39:10 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/configure.in: Fix typo in setting path, "sparc" => "sparc32".
+
+Wed Jul 24 02:27:02 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/gcdext.c: Reorganize and clean up. Get rid of all
+ signed limb arithmetic.
+
+Mon Jul 22 02:39:56 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/gcdext.c (mpn_gcdext): For large enough operands,
+ work with most significant *two* limbs.
+ (div2): New function (two variants).
+ (THRESHOLD): New #define.
+
+ * mpz/gcdext.c: Fix typo in MPZ_TMP_INIT call.
+
+ * longlong.h (alpha UMUL_TIME): Now 30.
+ (alpha UDIV_TIME): Now 350.
+ (x86 UMUL_TIME): Now 10 (let Pentium decide).
+ (SuperSPARC UDIV_TIME): Override default.
+
+ * extract-dbl.c (MP_BASE_AS_DOUBLE): Don't redefine here.
+
+ * extract-dbl.c: New name for extract-double.c.
+ * insert-dbl.c: New name for insert-double.c.
+ * Makefile.in: Corresponding changes.
+ * make.bat: Likewise.
+
+ * mpz/Makefile.in (.c.o): Don't pass non-portable `-f' to cp.
+ * mpq/Makefile.in: Likewise.
+ * mpf/Makefile.in: Likewise.
+
+Sat Jul 20 01:35:18 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/getlimbn.c: Take ABS of integer->_mp_size.
+
+ * mpz/divexact.c: Use mpn_divmod_1 if divisor is a single limb.
+
+Thu Jul 18 00:31:15 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/popcount.c (popc_limb): Use different masking trick
+ for first step (due to David Seal).
+ * mpn/generic/hamdist.c (popc_limb): Likewise.
+
+Wed Jul 17 23:21:48 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/divrem.c: In MPN_COPY_DECR call, copy dsize - 1 limbs.
+
+Sun Jul 14 17:47:46 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * configure.in: Handle sparc9, sparc64, and ultrasparc like sparc8.
+
+Thu Jul 11 14:05:54 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * longlong.h (mc680x0): Define umul_ppmm, udiv_qrnnd, sdiv_qrnnd
+ for the '020, '030, '040, and '332. Define count_leading_zeros
+ for the '020, '030, '040, and '060.
+
+Sun Jul 14 15:24:53 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ From Joe Keane:
+ * mpq/equal.c: Take ABS of num1_size before passing it to mpn_cmp.
+
+Fri Jul 12 17:11:17 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/sqrtrem.c (SQRT): New asm for x86, but leave it
+ disabled for now.
+
+ * mpn/generic/sqrtrem.c: Use MP_BASE_AS_DOUBLE.
+
+Wed Jul 10 03:17:45 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * cre-mparam.c: Delete obsolete file.
+
+ * gmp.h: #define _LONG_LONG_LIMB if __mips && _ABIN32.
+ * longlong.h: Test __mips instead of __mips__.
+
+Sun Jul 7 23:19:13 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * longlong.h (_PROTO): Define, unless already defined.
+ (alpha __udiv_qrnnd): Declare using _PROTO.
+ (hppa __udiv_qrnnd): Likewise.
+ (sparc __udiv_qrnnd): Likewise.
+
+Mon Jul 1 01:44:30 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * config.guess: Update from master version; add Cray x90 handling.
+
+Wed Jun 26 05:35:02 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/power/add_n.s (__mpn_add_n): Work around GAS bug.
+ * mpn/power/sub_n.s (__mpn_sub_n): Likewise.
+
+ * insert-double.c: Rework loop to avoid potential overflow.
+
+ * mpq/get_d.c: For vax, if qsize > N_QLIMBS, ignore excess limbs.
+
+ * mpq/tests/t-get_d.c (SIZE): Special case for vax.
+
+ * gmp.h (mpX_cmp_ui): #define also when ! __GNUC__.
+
+Mon Jun 24 17:13:21 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * longlong.h (vax sdiv_qrnnd): Fix typo.
+
+Sat Jun 15 01:33:33 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp.h: Support `small' and `large' type and function variants,
+ controlled by GMP_SMALL.
+
+ * mpz/Makefile.in (.c.o): Compile each function twice, for small and
+ large variant.
+ (MPZS_OBJS): New variable.
+ (libmpz.a): Include MPZS_OBJS in archive.
+ * mpf/Makefile.in: Analogous changes.
+ * mpq/Makefile.in: Analogous changes.
+
+ * gmp.h: Prefix all functions with __gmp, to allow namespace-clean
+ internal calls.
+
+ * mp.h: Rip out __MP_SMALL__ stuff.
+ (__mpz_struct): mp_size_t => int.
+
+ * mpz/invert.c: #include "gmp-impl.h".
+ Use MPZ_TMP_INIT, not mpz_init.
+
+ * mpz/gcdext.c: Rewrite to call mpn_gcdext.
+
+Fri Jun 14 18:05:29 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/gcdext.c (s0size): New parameter.
+ * gmp.h (mpn_gcdext): Update prototype.
+
+ * mpn/generic/gcdext.c: Major rewrite.
+
+Mon Jun 10 00:14:27 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/dump.c: Add missing `else'.
+
+Fri Jun 7 03:35:12 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * Makefile.in (gmp_toc.html): Pass -expandinfo to texi2html.
+
+Thu Jun 6 19:00:53 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * Version 2.0.2 released.
+
+ * install.sh: New file.
+ * Makefile.in (INSTALL): Use install.sh.
+ (install-normal): New name for target `install'.
+ (install): New dummy target.
+
+ * mpz/pow_ui.c: Swap tests for (e == 0) and (bsize == 0).
+ * mpz/ui_pow_ui.c: Swap tests for (e == 0) and (blimb == 0).
+
+ * config/mt-linux (AR_FLAGS): New file.
+ * configure.in: Use config/mt-linux for all linux systems.
+
+Tue Jun 4 03:42:18 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * Version 2.0.1 released.
+
+ * mpf/tests/ref.c: Cast result of TMP_ALLOC to the right pointer type.
+
+ * extract-double.c: Test _GMP_IEEE_FLOATS with #if, not plain if.
+
+ * insert-double.c: Don't #include stdlib.h.
+
+ * gmp-impl.h (union ieee_double_extract): Test sparc and __sparc.
+ Do not test __sparc__.
+
+ * mpf/reldiff.c: Change declaration to work around irix5 compiler bug.
+ * mpq/equal.c: Likewise.
+
+ * mpn/generic/gcd.c: Delete spurious comma at end of enumeration.
+
+ * mpn/generic/gcdext.c: Add K&R declaration syntax.
+ * stack-alloc.h: Likewise.
+ * insert-double.c: Likewise.
+ * extract-double.c: Likewise.
+ * mpf/tests/reuse.c: Likewise.
+ * mpz/tests/reuse.c: Likewise.
+ * mpf/tests/t-sub.c: Likewise.
+ * mpf/tests/t-add.c: Likewise.
+ * mpf/tests/t-muldiv.c: Likewise.
+ * mpf/tests/t-conv.c: Likewise.
+ * mpf/tests/ref.c: Likewise.
+
+ * mpn/config/t-oldgas: Renamed from t-freebsd.
+ * mpn/configure.in: Use t-oldgas for freebsd, netbsd, and some linux
+ configurations.
+
+ * mpn/powerpc32/mul_1.s: Really clear cy before entering loop.
+ * mpn/powerpc32/*.s: Fix power/powerpc syntax issues.
+
+ * mpn/config/t-ppc-aix: New file.
+ * mpn/configure.in: Use t-ppc-aix for powerpc like t-pwr-aix for power.
+
+Wed May 29 02:07:31 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp.h (mp_bits_per_limb): Change qualifier from `const' to
+ __gmp_const.
+
+ * gmp.h (mpf_init_set_str): Add `const' qualifier for 2nd parameter.
+ * mpf/iset_str.c: Likewise.
+
+Mon May 27 00:15:58 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp-impl.h: Declare __gmp_extract_double.
+
+ * mpz/set_q.c: Delete unused variables.
+
+ * gmp.h (mpq_equal): Declare.
+
+ * mpf/eq.c: mpf_cmp2 -> mpf_eq.
+
+Fri May 24 03:20:44 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/iset_d.c: Don't include <math.h>.
+
+ * insert-double.c (__gmp_scale2): New name for scal2.
+ * mpz/get_d.c: Corresponding change.
+ * mpf/get_d.c: Likewise.
+ * mpq/get_d.c: Likewise.
+ * gmp-impl.h: Declare __gmp_scale2.
+
+ * mpn/generic/scan0.c: Clarify comment.
+
+ * mpz/set_q.c: New file.
+ * Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h: Declare mpz_set_q.
+
+ * insert-double.c: New file.
+ * Makefile.in: Compile it.
+ * make.bat: Likewise.
+
+ * mpz/get_d.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h: Declare mpz_get_d.
+
+ * mpf/get_d.c: New file.
+ * mpf/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h: Declare mpf_get_d.
+
+ * make.bat: Compile things in alphabetical order.
+
+ * gmp-impl.h (MP_BASE_AS_DOUBLE): New #define.
+ (LIMBS_PER_DOUBLE): New #define.
+
+ * extract-double.c: New file.
+ * Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * mpz/set_d.c: Rewrite to use __gmp_extract_double.
+ * mpf/set_d.c: Likewise.
+
+ * mpn/configure.in: Use t-pwr-aix also for aix 3.2.4 and up.
+
+Wed May 22 02:48:35 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp-impl.h: Rework code for defining ieee_double_extract.
+ (IEEE_DOUBLE_BIG_ENDIAN): Macro removed.
+ (_GMP_IEEE_FLOATS): New macro.
+ * mpn/vax/gmp-mparam.h: Delete.
+
+ * mpn/config/t-pwr-aix: New file.
+ * mpn/configure.in: Use t-pwr-aix for aix 4 and later.
+
+Mon May 20 16:30:31 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp.h: In code for setting _GMP_H_HAVE_FILE, test more symbols.
+
+ * mpf/tests/t-add.c (oo): Add some `l' printf modifiers.
+ * mpf/tests/t-sub.c (oo): Likewise.
+ * mpf/tests/t-conv.c (oo): Likewise.
+ * mpf/tests/t-sqrt.c (oo): Likewise.
+
+ * mpz/tests/t-mul.c (_mpn_mul_classic): Remove unused variables.
+
+ * mpn/{pyr,i960,clipper}/*.s: Add missing copyright headers.
+
+Fri May 17 02:24:43 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/set_d.c: Call _mpz_realloc.
+
+ * mpq/set_z.c: New file.
+ * mpq/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h: Declare mpq_set_z.
+
+ * mp?/Makefile.in (libmp?.a): Depend on Makefile, not Makefile.in.
+ * mpf/Makefile.in (test): Delete spurious target.
+ * mpq/Makefile.in (test): Likewise.
+
+ * mpf/out_str.c: Use `e' to separate exponent when base <= 10.
+
+ * mpn/configure.in: Treat ultrasparc just like sparc v8,
+ until 64-bit compilers are ready.
+
+ * mpf/set_d.c: Make it work for 64-bit machines.
+
+Thu May 16 20:53:57 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp-impl.h: Set IEEE_DOUBLE_BIG_ENDIAN to 0 for little-endian
+ machines.
+ * mpn/x86/gmp-mparam.h: Delete file.
+
+ * configure.in: Treat microsparc like sparc8.
+
+ * urandom.h: Test __alpha instead of __alpha__, since the former
+ is the standard symbol.
+ * mpn/generic/random2.c: Likewise.
+ * mpf/random2.c: Likewise.
+
+Tue May 14 13:42:39 1996 Torbjorn Granlund (tege@tiny.matematik.su.se)
+
+ * mpz/set_f.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * gmp.h: Declare mpz_set_f.
+
+ * mpf/set_q.c: Simplify expression in rsize == nsize if-then-else arms.
+
+Tue May 14 13:03:07 1996 Torbjorn Granlund (tege@tiny.matematik.su.se)
+
+ * make.bat: Add all new files.
+
+Sun May 12 22:24:36 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/set_z.c: New file.
+ * mpf/Makefile.in: Compile it.
+ * gmp.h: Declare mpf_set_z.
+
+Sat May 11 19:26:25 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp.h: Declare mpf_set_q.
+
+ * mpf/set_q.c: Compute prec-1 limbs in mpn_divrem call.
+
+Fri May 10 17:37:38 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/set_q.c: New file.
+ * mpf/Makefile.in: Compile it.
+
+ * config.sub: Recognize sparc8.
+
+Wed May 8 09:19:11 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/tests/t-dm2exp.c: New file.
+
+ * mpf/tests/t-add.c: Correct header comment.
+ * mpf/tests/t-sub.c: Likewise.
+ * mpf/tests/t-sqrt.c: Likewise.
+
+ * mpf/div.c: Misc variable name cleanups.
+ * mpf/div_ui.c: Base more closely on mpf/div.c.
+ * mpf/ui_div.c: Likewise.
+
+ * mpz/tests/Makefile.in (check): Depend on Makefile.
+ * mpq/tests/Makefile.in (check): Likewise.
+ * mpf/tests/Makefile.in (check): Likewise.
+
+ * mpf/tests/t-muldiv.c: New file.
+ * mpf/tests/Makefile.in: Compile and run `t-muldiv'.
+ (t-ref.o): Delete spurious rule.
+
+ * mpf/sqrt.c: Properly detect negative input operand.
+
+ * mpf/sqrt_ui.c: Delete spurious header comment.
+ * mpf/sqrt.c: Likewise.
+ * mpz/sqrt.c: Likewise.
+
+ * mpz/tests/reuse.c (main): Read `reps' from command line.
+
+ * mpf/tests/reuse.c: New file.
+ * mpf/tests/Makefile.in: Compile and run `reuse'.
+
+ * mpf/mul_ui.c: Disable code for removing low zero limbs.
+
+ * mpf/div.c: Fix condition for when vp and qp overlaps.
+
+ * mpf/add_ui.c: When sum equals u, copy up to prec+1 limbs.
+
+ * mpf/out_str.c: Don't output '\n' after exponent.
+
+ * mpf/add_ui.c: New special case for when U is completely cancelled.
+
+Wed Apr 24 05:33:28 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * Version 2.0 released.
+
+ * All files: Update FSF's address.
+
+ * Makefile.in (gmp_toc.html): New name for gmp.html.
+ (TAGS): Depend on force.
+
+ * mpf/tests/t-conv.c: Pass -base to mpf_set_str.
+
+Sat Apr 20 03:54:06 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * Makefile.in (ps): New target, depend on gmp.ps.
+
+Fri Apr 19 14:03:15 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/out_str.c: Print `@' before exponent, not `e'.
+
+ * make.bat: Update from Makefiles.
+
+Thu Apr 18 01:22:05 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/set_str.c: If parameter `base' is negative, expect exponent
+ to be decimal, otherwise in the same base as the mantissa.
+
+Wed Apr 17 17:28:36 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/set_dfl_prec.c: Don't return anything.
+ * gmp.h: Corresponding changes.
+
+ * mpf/set_dfl_prec.c: Use `unsigned long int' for bit counts.
+ * mpf/init2.c: Likewise.
+ * mpf/get_prc.c: Likewise.
+ * mpf/set_prc.c: Likewise.
+ * mpf/set_prc_raw.c: Likewise.
+ * mpz/popcount.c: Likewise.
+ * mpz/hamdist.c: Likewise.
+ * mpz/scan1.c: Likewise.
+ * mpz/scan0.c: Likewise.
+ * mpn/generic/popcount.c: Likewise.
+ * mpn/generic/hamdist.c: Likewise.
+ * mpn/generic/scan1.c: Likewise.
+ * mpn/generic/scan0.c: Likewise.
+ * gmp.h: Likewise.
+
+ * mpf/eq.c: New file, based on mpf/diff.c.
+ * mpf/diff.c: Delete.
+ * mpf/Makefile.in: Corresponding changes.
+ * gmp.h: Likewise.
+
+ * mpf/reldiff.c: New file.
+ * mpf/Makefile.in: Compile it.
+ * gmp.h: Declare mpf_reldiff.
+
+ * mpz/iset_d.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * gmp.h: Declare mpz_init_set_d.
+
+Tue Apr 16 16:28:31 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * Makefile.in (gmp.html): Pass -acc to texi2html.
+
+Mon Apr 15 16:20:24 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/set_str.c: Switch off code for defaulting the base from the
+ leading characters.
+
+ * gmp.h (mp?_sign): Delete.
+ (mp?_sgn): New macros.
+
+Fri Apr 12 17:23:33 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * Makefile.in (gmp.dvi): Delete tmp.* at end of rule.
+
+Wed Apr 10 22:52:02 1996 Torbjorn Granlund (tege@tiny.matematik.su.se)
+
+ * mpf/random2.c: Change of `exp' param, mp_size_t => mp_exp_t.
+ * gmp.h: Corresponding change.
+
+ * gmp.h (mp_bits_per_limb): Make it const.
+
+Sat Mar 30 01:20:23 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * configure.in: Re-enable recognition of with_gcc.
+
+ * mpf/Makefile.in (.c.o): Pass XCFLAGS.
+ * mpn/Makefile.in (.c.o): Likewise.
+ * mpz/Makefile.in (.c.o): Likewise.
+ * mpq/Makefile.in (.c.o): Likewise.
+ * mpbsd/Makefile.in (.c.o): Likewise.
+ * mpf/tests/Makefile.in (.c.o): Likewise.
+ * mpz/tests/Makefile.in (.c.o): Likewise.
+ * mpq/tests/Makefile.in (.c.o): Likewise.
+
+ * Makefile.in (XCFLAGS): Default to empty.
+ (FLAGS_TO_PASS): Pass on XCFLAGS.
+ (.c.o): Pass XCFLAGS.
+
+ * config/mt-m88110 (XCFLAGS): Define instead of CC.
+ * config/mt-sprc8-gcc (XCFLAGS): Likewise.
+ * config/mt-supspc-gcc (XCFLAGS): Likewise.
+
+ * configure: Don't default CC to "gcc -O2" is -with-gcc=no was
+ specified.
+
+Mon Mar 25 01:07:54 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * urandom.h: Test for __SVR4 in addition to __svr4__.
+
+ * mp_bpl.c (mp_bits_per_limb): Declare as `const'.
+
+ * Makefile.in (CFLAGS): `-O2' => `-O'.
+ * mpn/Makefile.in (CFLAGS): Likewise.
+
+ * gmp-impl.h: Get rid of obsolete field access macros.
+
+ * mpn/mp_bases.c (__mp_bases): 1e39 => 1e38 to work around Solaris
+ cc compiler bug.
+
+ * gmp.h (__MPN): Make it work also for non-ANSI compilers.
+
+Thu Mar 21 01:07:54 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/sub.c: New special case for ediff <= 1 before generic code.
+ Simplify generic code for ediff == 0.
+ Rename uexp => exp.
+
+Mon Mar 11 18:24:57 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/tests/*.c: Use ref_mpf_sub for error calculation.
+ * mpf/tests/Makefile.in: Link ref.o to all executables.
+
+ * mpf/tests/t-sub.c: Make u = v + 1 with 50% probability.
+
+Sun Mar 10 21:03:17 1996 Torbjorn Granlund (tege@tiny.matematik.su.se)
+
+ * mpf/get_str.c: In digit development loop for fractions, change
+ loop condition from `<' to `<='.
+
+Thu Mar 7 04:58:11 1996 Torbjorn Granlund <tege@tiny.matematik.su.se>
+
+ * mpn/mp_bases.c (__mp_bases): 1e100 => 1e39 to avoid overflow warning.
+
+Wed Mar 6 01:10:42 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpf/tests/t-sqrt.c: New file.
+ * mpf/tests/Makefile.in: Corresponding changes.
+
+ * mpf/sqrt.c: Special case for square root of zero.
+
+ * mpq/add.c: Clean up variable names.
+ * mpq/sub.c: Update from mpq/add.c.
+
+ * mpz/divexact.c: abs => ABS.
+ * mpz/gcd.c: Likewise. Rewrite final fixup code, to decrease
+ allocation. Misc cleanups.
+
+Tue Mar 5 22:24:56 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/configure.in: Recognize linuxoldld as a synonym for linuxaout.
+
+ * gmp.h (mpn_add, mpn_add_1, mpn_sub, mpn_sub_1): Add prototypes.
+
+ * mpn/configure.in: Use t-freebsd also for netbsd.
+
+Mon Mar 4 15:13:28 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpq/Makefile.in (cmp.o): Depend on longlong.h.
+
+ * mpq/equal.c: New file.
+ * mpq/Makefile.in: Corresponding changes.
+
+ * mpf/tests/t-add.c: New file.
+ * mpf/tests/t-sub.c: Renamed from t-addsub.c.
+ * mpf/tests/ref.c: New file.
+ * mpf/tests/Makefile.in: Corresponding changes.
+
+ * gmp-impl.h (SIZ, ABSIZ, PTR, EXP, PREC, ALLOC): New #defines.
+
+Sun Mar 3 07:45:46 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/set_str.c: In exponentiation code, allocate 3 extra
+ limbs, not just 2.
+
+ * mpf/get_str.c: Allocate sufficient space for tstr.
+ When calculating exp_in_base, round result down.
+
+ * mpf/tests/t-conv.c: New file.
+ * mpf/tests/Makefile.in: Corresponding changes.
+
+ * mp_bpl.c: New file.
+ * gmp.h: Declare it.
+ * Makefile.in: Corresponding changes.
+
+Sat Mar 2 06:27:56 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/set_prc_raw.c: New file.
+ * mpf/set_prc.c: Renamed from set_prec.c.
+ * mpf/get_prc.c: New file.
+ * mpf/Makefile.in: Corresponding changes.
+ * gmp.h: Declare new functions.
+
+ * mpn/generic/gcdext.c: Add copyright header.
+
+Fri Mar 1 01:22:24 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/configure.in: For ppc601, search "power" before "powerpc32".
+
+ * mp?/Makefile.in (AR_FLAGS): New variable.
+ (libmp?.a): Use it.
+
+ * make.bat: New file.
+ * mpn/msdos: New directory.
+ * mpn/msdos/asm-syntax.h: New file.
+
+ * mpn/Makefile.in (distclean maintainer-clean): Delete asm-syntax.h.
+
+ * config.sub: Recognize [ctj]90-cray.
+
+ * mpn/configure.in: Recognize [ctj]90-cray-unicos*.
+
+ * mpn/generic/gcdext.c: Don't use alloca directly, use TMP_* macros.
+
+ * mpn/generic/gcd.c: Split increment from use of USIZE to avoid
+ undefined behaviour.
+
+Thu Feb 29 04:11:24 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * Makefile.in (install-info-files): Update for new install-info
+ behaviour.
+
+ * mpn/power/add_n.s: Rewrite.
+ * mpn/power/sub_n.s: Rewrite.
+
+Wed Feb 28 01:34:30 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/pow_ui.c: Compute allocation more aggressively for small bases.
+ * mpz/ui_pow_ui.c: Likewise.
+
+ * mpn/mp_bases.c (__mp_bases): Put huge value in 2nd field for index 1.
+
+ * mpn/generic/sqrtrem.c: sizeof (mp_limb_t) => BYTES_PER_MP_LIMB.
+ * mpn/generic/gcd.c: Likewise.
+ (SIGN_BIT): Compute differently.
+
+Mon Feb 26 00:07:36 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * All files: mp_limb => mp_limb_t, mp_limb_signed => mp_limb_signed_t.
+
+ * Makefile.in (install, install-bsdmp, install-info-files): Depend
+ on installdirs. chmod all installed files.
+
+Sun Feb 25 01:47:41 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpbsd/configure.in: Delete debugging code.
+
+ * All Makefile.in: Update clean targets.
+
+ * Makefile.in (AR_FLAGS): New variable.
+ (libgmp.a): Use it.
+ (libmp.a): Likewise.
+
+ * VERSION: Delete file.
+
+ * Makefile.in (installdirs): New target.
+ * mkinstalldirs: New file (from the texinfo package).
+
+ * Makefile.in (INSTALL, INSTALL_DATA, INSTALL_PROGRAM): New variables.
+ (MAKEINFO, MAKEINFOFLAGS, TEXI2DVI): New variables.
+ (install-info): New target.
+ (install, install-bsdmp): Depend on install-info.
+ ($(srcdir)/gmp.info): Changed from plain gmp.info; put info files
+ into source directory.
+ (distclean, mostlyclean): New targets.
+ (maintainer-clean): New name for realclean.
+ (uninstall): New target.
+ (TAGS): New target.
+ (info, dvi): New targets.
+ (.PHONY): Assign.
+
+ * Makefile.in (install, install-bsdmp): Use INSTALL_DATA.
+
+ * mp{n,z,f,bsd}/move-if-change: Delete.
+
+ * mpbsd/Makefile.in (stamp-stddefh): Delete target.
+
+ * Makefile.in (.c.o): Pass CFLAGS last.
+ * mpbsd/Makefile.in (.c.o): Likewise.
+ * mpf/Makefile.in (.c.o): Likewise.
+ * mpq/Makefile.in (.c.o): Likewise.
+ * mpz/Makefile.in (.c.o): Likewise.
+ * mpn/Makefile.in (.c.o): Likewise.
+ (.S.o): Likewise.
+
+ * memory.c: Change allocation error message.
+
+ * Makefile.in (install): Prefix gmp.h with $(srcdir).
+ (install-bsdmp): Prefix mp.h with $(srcdir).
+
+ * mp{n,z,f,bsd}/{configure,config.sub}: Delete.
+
+ * Makefile.in (gmp.dvi): Set TEXINPUTS also for 2nd tex invocation
+ (install targets): Install gmp.info-N.
+
+Sat Feb 24 03:36:52 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/get_str.c: Fix typo.
+
+ * mpz/legendre.c: Clarify expression with extra parens.
+
+ * version.c (gmp_version): Not static.
+
+ * mpf/iset_str.c: Properly return error code.
+
+ * mpf/add.c: Delete unused variables.
+ * mpf/inp_str.c: Likewise.
+ * mpq/get_d.c: Likewise.
+
+ * mpn/generic/dump.c: #include <stdio.h>.
+ * mpf/dump.c: Likewise.
+ * mpf/set_str.c: #include <ctype.h>.
+ (strtol): Declare.
+
+ * gmp.h: mpn_sqrt => mpn_sqrtrem.
+
+ * Makefile.in (clean, realclean): Clean in mpbsd.
+ (check): Test in mpf.
+
+ * mpf/Makefile.in (clean): Clean in tests.
+ * mpq/Makefile.in (clean): Clean in tests.
+
+ * mpf/tests/Makefile.in: New file.
+ * mpf/tests/configure.in: New file.
+ * mpf/tests/t-addsub.c: New file.
+
+ * mpf/sub_ui.c: Simply call mpf_sub for now.
+
+ * mpf/sub.c: Increase prec by 1.
+ * mpf/ui_sub.c: Likewise.
+
+Fri Feb 23 00:59:54 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpf/ui_sub.c: Fix typos.
+
+ * mpf/get_str.c: When allocating space for tmp, allow for an extra
+ limb. In code for fraction conversion, add special case for bases
+ that are a power of 2.
+
+ * mpf/out_str.c: Output leading "0.".
+ Default base to 10, before computing string allocation.
+
+ * mpf/get_str.c: Make variables for string size have type size_t.
+ * gmp.h: Corresponding change.
+
+ * mpf/random2.c: Allow creation of prec+1 large mantissas.
+
+ * mpf/add_ui.c: Don't abort if u < 0; special case for u <= 0.
+ Fix typo in MPN_COPY offset.
+ * mpf/sub_ui.c: Analogous changes.
+
+ * mpf/set_prec.c: Rewrite.
+
+ * mpf/init2.c: Compute precision as in set_prec.c.
+
+ * mpf/div_2exp.c: Special case for u == 0.
+ * mpf/mul_2exp.c: Likewise. Write r->_mp_size always.
+
+ * mpf/sqrt_ui.c: mpn_sqrt => mpn_sqrtrem.
+ * mpf/sqrt.c: Likewise. When computing new exponent, round quotient
+ towards -infinity.
+
+ * mpf/add.c: Fix typos.
+ * mpf/sub.c: Fix typos.
+
+Thu Feb 22 00:24:48 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/Makefile.in (stamp-stddefh): Delete target.
+ (test): Delete target.
+ * Makefile.in (stamp-stddefh): Delete target.
+ (cre-stddefh.o): Delete target.
+ (gmp.dvi): Set TEXINPUTS before invoking tex.
+
+ * cre-stddefh.c: Delete.
+
+ * mpz/sqrt.c: Fix typo.
+
+ * mpz/powm.c: Special case for mod == 0.
+ * mpz/powm_ui.c: Likewise.
+
+ * mpz/get_si.c: Handle -0x80000000 correctly.
+
+ * mpz/inp_str.c: Now returns size_t.
+ Make it return number of bytes read or error indication.
+ * mpf/inp_str.c: Likewise.
+
+ * mpz/out_raw.c: Replace by mpz/out_binary.c, with modifications.
+ * mpz/inp_raw.c: Rewrite, using mpz/inp_binary as a base.
+ * mpz/inp_binary.c: Delete.
+
+ * mpn/Makefile.in (XCFLAGS): Remove variable.
+ (.c.o): Don't pass XCFLAGS.
+ (SFLAGS): Set to nothing.
+ (.S.o): Pass SFLAGS, not XCFLAGS.
+
+ * mpn/config/t-freebsd (SFLAGS): New name for XCFLAGS.
+
+ * mpf/out_str.c: Make return number of bytes written or error
+ indication.
+ * mpz/out_str.c: Likewise.
+ * gmp.h: Corresponding changes.
+
+ * gmp.h (__mpz_struct): mp_size_t => int.
+ (__mpq_struct): Likewise.
+ (__mpf_struct): Likewise.
+ (mp_size_t): int => long int.
+
+ * mpn/cray: New directory.
+ * mpn/cray/gmp-mparam.h: New file.
+ * mpn/configure.in: Recognize cray variants.
+
+ * Makefile.in: Set defaults for prefix, libdir, etc.
+ (install): New target.
+ (install-bsdmp): New target.
+ (gmp.html): New target.
+
+ * stack-alloc.c (__tmp_alloc): Cast void ptrs to char * in comparison.
+
+Wed Feb 21 04:35:02 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * gmp.h: Sort mpn declarations.
+ (mpn_gcdext): Add declaration.
+
+ * mpn/generic/divrem_1.c: New file.
+ * mpn/Makefile.in (divrem_1.o): New rule.
+ * configure.in (functions): Add divrem_1.
+
+ * mpn/generic/divmod.c: Delete file.
+ * mpn/configure.in (functions): Delete divmod.
+ * Makefile.in (divmod.o): Delete rule.
+ * gmp.h (mpn_divmod): New #define.
+
+ * gmp.h (mpn_next_bit_set): Delete spurious declaration.
+
+ * mpn/generic/divrem.c (default case): In code assigning
+ most_significant_q_limb, move reassignment of n0 into if statement.
+
+ * gmp.h (mpf_inp_str): Fix typo.
+ (mpf_out_str): Make prototype match reality.
+ * mpf/inp_str.c: New file.
+ * mpf/out_str.c: New file.
+ * mpf/Makefile.in: Compile new files.
+
+ * mpn/Makefile.in (dump.o): Fix dependency path.
+ (inlines.o): Likewise.
+
+ * mpn/configure.in: Make m68060 be the same as m68000. Clean up
+ m68k configs.
+
+Tue Feb 20 01:35:11 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/generic/sqrtrem.c: Renamed from sqrt.
+ * mpn/configure.in (functions): Corresponding change.
+ * mpn/Makefile.in: Likewise.
+ * mpz/sqrtrem.c: Likewise.
+ * mpz/sqrt.c: Likewise.
+ * mpn/generic/perfsqr.c: Likewise.
+
+ * Makefile.in (clean): Also remove libmp.a.
+ Don't compile cre-conv-tab.c or mp_bases.c.
+ cre-conv-tab.c: Delete file.
+ (gmp.ps): New rule.
+
+ * mpn/mp_bases.c: New file.
+ * mpn/Makefile.in: Compile mp_bases.c.
+
+ * mpz/set_str.c: Skip initial whitespace.
+ * mpf/set_str.c: Likewise.
+ * mpbsd/xtom.c: Likewise.
+
+ * gmp.h: Add missing mpz declarations.
+ Delete all formal parameter names from declarations.
+
+ * mpn/Makefile.in: Add dependencies for .c files.
+
+ * Makefile.in (check): Write recursive make calls separately, not as
+ a loop.
+ (FLAGS_TO_PASS): New variable. Use it for most recursive makes.
+
+Mon Feb 19 01:02:20 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpn/Makefile.in (.S.o): Pipe cpp output to grep in order to delete
+ lines starting with #.
+ (CPP): Set to $(CC) -E to avoid gcc dependency.
+
+ * mpn/m68k/syntax.h (moveql): Define to moveq for MIT_SYNTAX.
+
+ * mpn/hppa/hppa1_1/pa7100/addmul_1.S: Fix typo in s1_ptr alignment
+ code.
+ * mpn/hppa/hppa1_1/pa7100/submul_1.S: Likewise.
+
+ * gmp.h: Fix typos in #defines of recently added mpn functions.
+
+ * mpz/inp_str.c: Skip all whitespace, not just plain space.
+ * mpbsd/min.c: Likewise.
+
+ * mpn/configure.in (functions): Add gcdext.
+ * mpn/generic/gcdext.c: New file.
+
+ * mpz/legendre.c: mpz_div_2exp => mpz_tdiv_q_2exp.
+
+ * gmp.h: Surround mpn declarations with extern "C" { ... }.
+
+ * Makefile.in (check): New target.
+
+ * mpq/get_d.c: Update comments. Use rsize instead of dsize + N_QLIMBS
+ when possible. Add special case for nsize == 0.
+
+ * gmp.h (mpq_get_d): Add declaration.
+ (mpq_canonicalize): Likewise.
+ (mpq_cmp_ui): Likewise.
+ (mpf_diff): Likewise.
+ (mpf_ui_sub): Likewise.
+ (mpf_set_prec): Likewise.
+ (mpf_random2): Likewise.
+
+ * gmp.h (mpz_cmp_ui): New #define.
+ (mpz_cmp_si): New #define.
+ (mpq_cmp_ui): New #define.
+ (mpz_sign): New #define.
+ (mpq_sign): New #define.
+ (mpf_sign): New #define.
+ (mpq_numref): New #define.
+ (mpq_denref): New #define.
+
+ * mpq/set_z.c: File deleted.
+ * mpq/Makefile.in: Corresponding changes.
+
+Sun Feb 18 01:34:47 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpbsd/sdiv.c: Use _mp_realloc, not _mpz_realloc.
+
+ * mpz/inp_binary.c: Default stream to stdin.
+ * mpz/inp_str.c: Likewise.
+ * mpz/inp_raw.c: Likewise.
+ * mpz/out_binary.c: Default stream to stdout.
+ * mpz/out_raw.c: Likewise.
+ * mpz/out_str.c: Likewise.
+
+ * mpbsd/realloc.c: New file.
+ * mpbsd/Makefile.in: Corresponding changes.
+
+ * mpbsd/min.c: Rewrite (base on mpz/inp_str.c).
+ * mpbsd/mtox.c: Rewrite (base on mpz/get_str.c).
+
+ * mpbsd/mout.c: Rewrite (base on mpz/out_str) but make it output
+ spaces in each 10th position.
+ * mpbsd/xtom.c: Rewrite (base on mpz/set_str).
+
+ * mpq/tests/Makefile.in (st-cmp): New file.
+ * mpq/tests/configure.in (srcname): New file.
+
+ * mpz/tests/configure.in (srcname): Fix typo.
+
+ * mpq/cmp.c: Add check using number of significant bits, to avoid
+ general multiplication.
+
+Sat Feb 17 11:58:30 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpq/cmp_ui.c: Store cy_limb after the mpn_mul_1 calls.
+
+ * mpq/tests: New directory.
+ * mpq/tests/t-cmp.c: New file.
+ * mpq/tests/t-cmp_ui.c: New file.
+
+ * mpz/tests/dive.c (main): Generate zero numerator.
+ (get_random_size) : Delete.
+
+ * mpz/divexact.c: Add special case for 0/x.
+
+ * gmp.h (mpz_mod): Add declaration.
+
+Fri Feb 16 18:18:39 1996 Andreas Schwab <schwab@informatik.uni-dortmund.de>
+
+ * mpn/m68k/*: Rewrite code not to use the INSN macros.
+ (L): New macro to properly prefix local labels for ELF.
+
+Fri Feb 16 00:20:56 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * gmp-impl.h (ieee_double_extract): Use plain `unsigned int' for
+ fields.
+ * mpn/generic/inlines.c (_FORCE_INLINES): New #define. Delete
+ conditional __GNUC__.
+ * gmp.h (mpn_add, mpn_sub, mpn_add_1, mpn_sub_1):
+ Only define these if __GNUC__ || _FORCE_INLINES.
+ * mpf/random2.c: Add missing parameter in non-ANSI header.
+ * mpn/generic/gcd.c (SIGN_BIT): Do as #define to work around bug
+ in AIX compilers.
+ * mpq/get_d.c: #define N_QLIMBS.
+ * mpz/divexact.c: Obscure division by 0 to silent compiler warnings.
+ * stack-alloc.c: Cast void* pointer to char* before doing arithmetic
+ on it.
+
+ * Makefile.in (mpbsd/libmpbsd.a): New rule.
+ * configure.in (configdirs): Add mpbsd.
+
+ * gmp.h: Add declarations for a few missing mpn functions.
+
+ * Makefile.in (libmp.a): New rule.
+
+ * mpbsd/mdiv.c: #include "dmincl.c", not "mpz_dmincl.c"
+ * gmp.h: Move #define of __GNU_MP__ into the `#if __GNU_MP__' block.
+ * mp.h: Likewise. Update typedefs from gmp.h.
+ * mpbsd/configure.in: New file.
+ * mpbsd/Makefile.in: New file.
+ * mpbsd/configure: Link to master configure.
+ * mpbsd/config.sub: Link to master config.sub.
+
+ * Makefile.in: Set RANLIB_TEST.
+ * (libgmp.a): Use it.
+ * (libgmp.a): Do ranlib before moving the libgmp.a to the build
+ directory.
+ * mp?/Makefile.in: Don't use or set RANLIB.
+
+Thu Feb 15 16:38:41 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/add_ui.c: MP_INT => mpz_t.
+ * mpz/cmp_ui.c: Likewise.
+ * mpz/fac_ui.c: Likewise.
+ * mpz/inp_binary.c: Likewise.
+ * mpz/inp_raw.c: Likewise.
+ * mpz/legendre.c: Likewise.
+ * mpz/jacobi.c: Likewise.
+ * mpz/out_binary.c: Likewise.
+ * mpz/out_raw.c: Likewise.
+ * mpz/random2.c: Likewise.
+ * mpz/random.c: Likewise.
+ * mpz/realloc.c: Likewise.
+
+ * mpz/legendre.c: __mpz_2factor(X) => mpz_scan1(X,0),
+ __mpz_odd_less1_2factor => mpz_scan1(X,1).
+ * mpz/ntsup.c: File deleted.
+ * mpz/Makefile.in: Corresponding changes.
+
+ * mpz/pprime_p: Use mpz_scan1 to avoid looping.
+
+ * mpz/fac_ui.c: Type of `k' and `p' is `unsigned long'.
+ * mpz/pprime_p.c: Pass long to *_ui functions.
+ * mpz/gcdext.c: Likewise.
+ * mpz/fdiv_r_2exp.c: Likewise.
+ * mpz/fac_ui.c: Likewise.
+
+ * mpz/powm.c: Don't use mpn_rshift when mod_shift_cnt is 0.
+
+ * mpz/tests/Makefile.in (st-sqrtrem): Fix typo.
+
+ * mpz/cmp_ui.c: #undef mpz_cmp_ui.
+ * mpz/cmp_si.c: #undef mpz_cmp_si.
+ * gmp.h (mpz_cmp_ui): New #define.
+ (mpz_cmp_si): New #define.
+
+Wed Feb 14 22:11:24 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * gmp.h: Test __cplusplus in addition to __STDC__.
+ * gmp-impl.h: Likewise.
+
+ * gmp.h: Surround declarations with extern "C" { ... }.
+
+Tue Feb 13 15:20:45 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/fdiv_r_2exp.c: Use MPN_NORMALIZE.
+ * mpz/tdiv_r_2exp.c: Likewise.
+
+ * mpz/fdiv_r_2exp.c: New file.
+ * mpz/fdiv_q_2exp.c: New file.
+ * mpz/tdiv_r_2exp.c: Renamed from mpz/mod_2exp.c.
+ * mpz/tdiv_q_2exp.c: Renamed from mpz/div_2exp.c
+ * mpz/Makefile.in: Corresponding changes.
+
+ * mpz/scan0.c,scan1.c: New files.
+ * mpz/Makefile.in: Compile them.
+
+ * gmp.h (mpn_normal_size): Delete.
+
+ * config.guess: Update from Cygnus version.
+
+ * mpn/m68k/rshift.S: Use INSN2 macro for lea instructions.
+ * mpn/m68k/lshift.S: Likewise.
+
+ * mpn/configure.in: Fix configuration for plain 68000.
+
+Mon Feb 12 01:06:06 1996 Torbjorn Granlund <tege@matematik.su.se>
+
+ * mpz/tests/t-powm.c: Generate negative BASE operand.
+
+ * mpz/powm.c: Make result always positive.
+
+Sun Feb 11 01:44:56 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/tests/*.c: Add t- prefix.
+ * mpz/tests/Makefile.in: Corresponding changes.
+ * mpz/tests/configure.in: Update srctrigger.
+
+ * mpz/tests/gcd.c: Generate negative operands.
+ * mpz/tests/gcd2.c: Likewise.
+
+ * mpz/gcdext.c: At end, if G is negative, negate all G, S, and T.
+
+Thu Feb 8 17:16:12 UTC 1996 Ken Weber <kweber@mat.ufrgs.br>
+
+ * mp{z,n}/gcd.c: Change mpn_gcd interface.
+ * gmp.h: Ditto.
+ * gmp.texi: update documentation.
+
+Mon Feb 7 23:58:43 1996 Andreas Schwab <schwab@informatik.uni-dortmund.de>
+
+ * mpn/m68k/{lshift,rshift}.S: New files.
+ * mpn/m68k/syntax.h: New ELF_SYNTAX macros.
+ (MEM_INDX, R, PROLOG, EPILOG): New macros.
+ * mpn/m68k/*.S: Use R macro with register name. Use PROLOG and EPILOG
+ macros. Rename `size' to `s_size' or s1_size to avoid clash with ELF
+ .size directive.
+ * mpn/configure.in: New target m68k-*-linux*.
+
+Wed Feb 7 07:41:31 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * Makefile.in (cre-conv-tab): Workaround for SunOS make.
+
+ * mpz/tests/reuse.c: New file.
+ * mpz/tests/Makefile.in: Handle reuse.c.
+
+Tue Feb 6 11:56:24 UTC 1996 Ken Weber <kweber@mat.ufrgs.br>
+
+ * mpz/gcd.c: Fix g->size when one op is 0 and g == other op.
+
+Tue Feb 6 01:36:39 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp.h (mpz_divexact): Delete parameter names.
+ (mpz_lcm): Delete spurious declaration.
+
+ * mpz/dmincl.c: Fix typo.
+
+Mon Feb 5 01:11:56 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/gcd.c (gcd_2): Declare consistently.
+
+ * mpz/tdiv_q.c: Optimize division by a single-limb divisor.
+ * mpz/dmincl.c: Likewise.
+
+ * mpz/add.c: Use MPN_NORMALIZE instead of mpn_normal_size.
+ * mpz/sub.c: Likewise.
+ * mpn/generic/sqrt.c: Likewise.
+
+ * mpn/tests/{add_n,sub_n,lshift,rshift}.c: Put garbage in the
+ destination arrays.
+
+Fri Feb 2 02:21:27 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/{jacobi.c,legendre.c,ntsup.c,invert.c}: New files.
+ * mpz/Makefile.in: Compile them.
+
+ * mpn/Makefile.in (INCLUDES): Don't search in `generic'.
+
+Thu Feb 1 02:15:11 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ Change from Ken Weber:
+ * mpz/divexact.c: Make it work when quot is identical to either input.
+
+ * mpf/ui_sub.c: New file.
+ * mpf/Makefile.in: Compile it.
+
+ * gmp-impl.h (MPZ_TMP_INIT): alloca -> TMP_ALLOC.
+ * mpz/{c,f}div_{q,qr,r}.c: Use TMP_DECL/TMP_MARK/TMP_FREE since
+ these use MPZ_TMP_INIT.
+ * mpz/mod.c: Likewise.
+ * mpq/{add,sub}.c: Likewise.
+ * mpq/canonicalize: Likewise.
+
+ * mpq/{add,sub,mul,div}.c: Use mpz_divexact. MP_INT -> mpz_t.
+ * mpq/canonicalize.c: Likewise.
+
+Wed Jan 31 01:45:00 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/gcd.c: Misc changes from Ken.
+
+ * mpz/tests/gcd2.c: New file.
+ * mpz/tests/Makefile.in: Handle gcd2.c.
+
+ * mpn/generic/gcd.c (mpn_gcd): When GCD == ORIG_V, return vsize,
+ not orig_vsize. Fix parameter declaration.
+
+ * mpz/mod_ui.c: Delete file.
+ * mpz/Makefile.in: Don't try to compile mod_ui.
+
+ * mpz/cdiv_*_ui.c): Make them work right.
+ * gmp.h: Declare cdiv*.
+
+Tue Jan 30 02:22:56 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/{cdiv_q.c,cdiv_q_ui.c,cdiv_qr.c,cdiv_qr_ui.c,cdiv_r.c,
+ cdiv_r_ui.c,cdiv_ui.c}: New files.
+ * mpz/Makefile.in: Compile them.
+
+ * All files: Make file permissions right.
+
+ Changes from Ken Weber:
+ * mpn/generic/accelgcd.c: Delete.
+ * mpn/generic/bingcd.c: Delete.
+ * mpn/generic/numbits.c: Delete.
+ * mpn/generic/gcd.c: New file.
+ * mpn/configure.in (functions): Update accordingly.
+ * mpz/divexact.c: New file.
+ * mpz/Makefile.in: Compile divexact.c.
+ * mpz/gcd.c: Rewrite to accommodate for gcd changes in mpn.
+ * gmp.h: declare new functions, delete obsolete declarations.
+ * mpz/tests/dive.c: New file.
+ * mpz/tests/Makefile.in: Handle dive.c.
+
+Mon Jan 29 03:53:24 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/random.c: Handle negative SIZE parameter.
+
+ * mpz/tests/tdiv(_ui).c: New name for tst-dm(_ui).c.
+ * mpz/tests/tst-mdm(_ui).c: Delete.
+ * mpz/tests/fdiv(_ui).c: New test based in tst-mdm(_ui).
+ * mpz/tests/*.c: Get rid of tst- prefix for DOS 8+3 naming.
+ * mpz/tests/Makefile.in: Corresponding changes.
+ * mpz/tests/configure.in: Update srctrigger.
+
+ * mpn/generic/divmod.c: Update from divrem.
+ * mpn/generic/divrem.c: Misc cleanups.
+
+Sun Jan 28 03:25:08 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * All files: Use new TMP_ALLOC interface.
+
+ * mpz/powm_ui.c: Make Jan 25 changes to powm.c also here.
+
+ * mpz/tests/powm_ui.c: New file.
+ * mpz/tests/Makefile.in: Add rules for tst-powm and tst-powm_ui.
+
+ * Makefile.in: Update dependency list.
+ * mpf/Makefile.in: Likewise.
+ * mpz/Makefile.in: Likewise.
+ * mpq/Makefile.in: Likewise.
+ * Makefile.in: Set RANLIB simply to ranlib, and allow configure
+ to override it.
+
+ * mpz/Makefile.in (conf): Delete spurious target.
+ (mp_bases.c): Delete.
+ (cre-conv-tab rules): Delete.
+
+ * Makefile.in (cre-conv-tab): Greatly simplify.
+
+Sat Jan 27 13:38:15 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * stack-alloc.c: New file.
+ * stack-alloc.h: New file.
+
+ * gmp.h (__gmp_inline): Define using __inline__.
+
+Thu Jan 25 00:28:37 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/generic/scan0.c: New file.
+ * mpn/generic/scan1.c: Renamed from next_bit.c.
+ * mpn/configure.in (functions): Include scan0 and scan1.
+
+ * mpn/m68k/*: #include sysdep.h. Use C_GLOBAL_NAME.
+
+ * configure: Update from Cygnus version.
+ * config.guess: Likewise.
+ * config.sub: Likewise.
+ * configure: Pass --nfp to recursive configures.
+
+ * mpz/tests/tst-*.c: Adjust SIZE and reps.
+
+ * mpz/powm.c: Move esize==0 test earlier.
+ In final reduction of rp,rsize, don't call mpn_divmod unless
+ reduction is really needed.
+
+ * mpz/tests/tst-powm.c: Fix thinko in checking code.
+
+ * All files: Get rid of `__' prefix from mpn_* calls and declarations.
+ * gmp.h: #define __MPN.
+ * gmp.h: Use __MPN in #defines for mpn calls.
+
+ * mpn/generic/mul_n.c: Prepend `i' to internal routines.
+ * gmp-impl.h: Add #defines using __MPN for those internal routines.
+
+ * mpn/generic/sqrt.c: Change call to mpn_mul to mpn_mul_n.
+
+Wed Jan 24 13:28:19 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/sparc32/udiv_fp.S: New name for udiv_qrnnd.S.
+ * mpn/sparc32/udiv_nfp.S: New name for v8/udiv_qrnnd.S.
+ * mpn/sparc32/v8/supersparc: New directory.
+ * mpn/sparc32/v8/supersparc/udiv.S: New file.
+
+Tue Jan 23 01:10:11 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ This major contribution is from Ken Weber:
+ * mpn/generic/accelgcd.c: New file.
+ * mpn/generic/bdivmod.c: New file.
+ * mpn/generic/bingcd.c: New file.
+ * mpn/generic/gcd_1.c: Rewrite.
+ * mpn/generic/numbits.c: New file (to go away soon).
+ * mpz/gcd.c: Rewrite.
+ * mpz/tests/tst-gcd.c (SIZE): Now 128.
+ * gmp.h: Declare new functions.
+ * mpn/configure.in (functions): List new files.
+ * gmp-impl.h (MPN_SWAP): Delete.
+ (MPN_LESS_BITS_LIMB, MPN_LESS_BITS, MPN_MORE_BITS): Delete.
+ (MPN_COMPL_INCR, MPN_COMPL): Delete.
+
+Mon Jan 22 02:04:59 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp.h (mpn_name): New #define.
+
+ * mpn/m88k/mc88110/addmul_1.s: New file.
+ * mpn/m88k/mc88110/add_n.S: New file.
+ * mpn/m88k/mc88110/sub_n.S: New file.
+
+ * mpn/m88k/sub_n.s: Correctly initialize carry.
+
+ * mpn/sparc32/{add_n.S,sub_n.S,lshift.S,rshift.S): `beq' => `be'.
+
+Sun Jan 21 00:04:35 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/sparc64/addmul_1.s: New file.
+ * mpn/sparc64/submul_1.s: New file.
+ * mpn/sparc64/rshift.s: New file.
+
+Sat Jan 20 00:32:54 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpz/iset.c: Fix typo introduced Dec 25.
+
+Wed Jan 17 13:16:44 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * config/mt-sprc8-gcc: New name for mt-sparc8-gcc.
+ * config/mt-sparcv8-gcc: Delete.
+ * configure.in: Corresponding changes.
+
+Tue Jan 16 16:31:01 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp-impl.h: #include alloca.h when necessary.
+
+ * longlong.h: Test __alpha instead of __alpha__, since the former
+ is the standard symbol.
+
+Mon Jan 15 18:06:57 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/sparc64/mul_1.s: Swap operands of mulx instructions.
+ * mpn/sparc64/lshift.s: New file.
+
+Fri Dec 29 17:34:03 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/x86/pentium/add_n.S: Get rid of #defines for register names.
+ * mpn/x86/pentium/sub_n.S: Likewise.
+
+Thu Dec 28 03:16:57 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/x86/pentium/mul_1.S: Rework loop to avoid AGI between update
+ of loop induction variable and load insn at beginning of loop.
+ * mpn/x86/pentium/addmul_1.S: Likewise.
+ * mpn/x86/pentium/submul_1.S: Likewise.
+
+Mon Dec 25 23:22:55 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * All files: Prefix user-visible structure fields with _mp_.
+
+Fri Dec 22 20:42:17 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/configure.in (m68k configs): Terminate path variable with
+ plain "m68k".
+
+Fri Dec 22 03:29:33 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/sparc32/add_n.S: Update from sub_n.S to fix bugs, and to
+ clean things up.
+
+ * mpn/configure.in (m68k configs): Update #include path for new
+ mpn directory organization.
+
+Tue Dec 12 02:53:02 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * gmp.h: Prefix all structure field with _mp_.
+ * gmp-impl.h: Define access macros for these fields.
+
+Sun Dec 10 00:47:17 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/alpha/addmul_1.s: Prefix labels with `.'.
+ * mpn/alpha/submul_1.s: Likewise.
+ * mpn/alpha/[lr]shift.s: Likewise.
+ * mpn/alpha/udiv_qrnnd.S: Likewise.
+ * mpn/alpha/ev5/[lr]shift.s: Likewise.
+
+ * mpn/alpha/ev5/lshift.s: Fix typos.
+
+Fri Dec 1 14:28:20 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/Makefile.in (.SUFFIXES): Define.
+
+Wed Nov 29 23:11:57 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/sparc64/{add_n.s, sub_n.s}: New files.
+
+Tue Nov 28 06:03:13 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/x86/syntax.h: Handle ELF_SYNTAX.
+ Rename GAS_SYNTAX => BSD_SYNTAX.
+
+ * mpn/configure.in: Handle linuxelf and SysV for x86 variants.
+
+Mon Nov 27 01:32:12 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/hppa/hppa1_1/pa7100/submul_1.S: New file.
+
+Sun Nov 26 04:30:47 1995 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * mpn/hppa/hppa1_1/pa7100/addmul_1.S: New file.
+
+ * mpn/sparc32/add_n.S: Rewrite to use 64 bit loads/stores.
+ * mpn/sparc32/sub_n.S: Likewise.
+
+Fri Nov 17 00:18:46 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/configure.in: Handle m68k on NextStep.
+
+Thu Nov 16 02:30:26 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn: Reorganize machine-specific directories.
+ * mpn/configure.in: Corresponding changes.
+ (sh, sh2): Handle these.
+ (m68k targets): Create asm-syntax.h.
+
+Thu Nov 9 02:20:50 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/generic/mul_n.c (____mpn_sqr_n): Delete code that calls abort.
+ (____mpn_mul_n): Likewise.
+
+Tue Nov 7 03:25:12 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpf/get_str.c: In exponentiation code (two places), don't swap
+ input and output areas when calling mpn_mul_1.
+ * mpf/set_str.c: Likewise.
+
+Fri Nov 3 02:35:58 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpf/Makefile.in: Make sure all objects are listed in dependency list;
+ delete spurious entries.
+
+ * mpf/mul.c: Handle U or V being 0. Allow prec+1 for result precision.
+
+ * mpf/set_prec.c: New computation of limb precision.
+ * mpf/set_dfl_prec.c: Likewise.
+
+ * mpf/random2.c: Fix typo computing exp.
+ * mpf/get_str.c: In (uexp > usize) case, set n_limbs as a function of
+ the user-requested number of digits, n_digits.
+
+Thu Nov 2 16:25:07 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/generic/divrem.c (case 2): Don't move np vector back, it is
+ never read.
+ (default case): Put most significant limb from np in new variable n2;
+ decrease size argument for MPN_COPY_DECR; use n2 instead of np[dsize].
+
+Wed Nov 1 02:59:53 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/sparc/[lr]shift.S: New files.
+
+Tue Oct 31 00:08:12 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpz/gcd_ui.c: Set w->size unconditionally when v is zero.
+
+ * gmp-impl.h (assert): Delete definition.
+
+ * mpf/sub.c: Delete all assert calls. Delete variable `cy'.
+
+ * mpf/neg.c: Use prec+1 as precision. Optimize for when arguments
+ are the same.
+ * mpf/abs.c: Likewise.
+ * mpf/{set,neg,abs}.c: Make structure and variable names similar.
+
+Mon Oct 30 12:45:26 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpf/random2.c (random): Test __SVR4 in addition to __svr4__.
+ * mpn/generic/random2.c (random): Likewise.
+
+Sun Oct 29 01:54:28 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpf/div.c: Special handle U or V being 0.
+
+ * mpf/random2.c: New file.
+
+ * longlong.h (i860 rshift_rhlc): Define.
+ (i960 udiv_qrnnd): Define.
+ (i960 count_leading_zeros): Define.
+ (i960 add_ssaaaa): Define.
+ (i960 sub_ddmmss): Define.
+ (i960 rshift_rhlc): Define.
+
+Sat Oct 28 19:09:15 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/pentium/rshift.S: Fix and generalize condition for when to use
+ special code for shift by 1.
+ * mpn/pentium/lshift.S: Likewise.
+
+Thu Oct 26 00:02:56 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * gmp.h: #undef __need_size_t.
+ * mp.h: Update from gmp.h.
+
+Wed Oct 25 00:17:27 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpf/Makefile.in: Compile set_prec.c.
+ * mpf/realloc.c: Delete this file.
+ * mpf/Makefile.in: Delete mentions of realloc.c.
+
+ * gmp.h (__mpf_struct): Get rid of `alloc' field.
+ * mpf/clear.c: Likewise.
+ * mpf/init*.c: Likewise.
+ * mpf/set_prec.c: Likewise.
+ * mpf/iset*.c: Likewise.
+
+ * mpf/iset_str.c: New file.
+
+ * mpn/configure.in: Handle pyramid.
+
+ * mpf/set.c: Use prec+1 as precision.
+
+ * mpf/set_prec.c: New file.
+
+Tue Oct 24 00:56:41 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/generic/divrem.c: New file. Will replace mpn/generic/divmod.c
+ when rest of source is converted.
+ * mpn/configure.in (functions): Add `divrem'
+ * mpn/generic/set_str.c: Never call __mpn_mul_1 with zero size.
+
+ * mpf/get_str.c: Completely rewritten.
+ * mpf/add.c: Fix several problems.
+ * mpf/sub.c: Compare operands from most significant end until
+ first difference, exclude skipped limbs from computation.
+ Accordingly simplify normalization code.
+ * mpf/set_str.c: Fix several problems.
+ * mpf/dump.c: New file.
+ * mpf/Makefile.in: Compile dump.c.
+ * mpf/init2.c: Set prec field correctly.
+
+Sun Oct 22 03:02:09 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * cre-conv-tab.c: #include math.h; don't declare log and floor.
+
+Sat Oct 21 23:04:10 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpf/mul_ui.c: Handle U being 0.
+
+Wed Oct 18 19:39:27 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/generic/set_str.c: Correctly handle input like "000000000000".
+ Misc cleanups.
+
+Tue Oct 17 15:14:13 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * longlong.h: Define COUNT_LEADING_ZEROS_0 for machines where
+ appropriate.
+
+Mon Oct 16 19:14:43 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpf/add.c: Rewrite.
+ * mpf/set_str.c: New file. Needs more work.
+
+Sat Oct 14 00:14:04 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpf/div_2exp.c: Vastly simplify.
+ * mpf/mul_2exp.c: Likewise.
+
+ * mpf/sub.c: Rewrite.
+
+ * gmp-impl.h (udiv_qrnnd_preinv2gen): Terminate comment.
+
+ * mpf/dump.c: Free allocated memory.
+
+ * gmp-impl.h (assert): Define.
+
+Wed Oct 11 13:31:00 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/pentium/rshift.S: Install new code to optimize shift-by-1.
+
+Tue Oct 10 00:37:21 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/pentium/lshift.S: Install new code to optimize shift-by-1.
+
+ * mpn/powerpc32/{lshift.s,rshift.s}: New files.
+
+ * configure.in: Fix typo.
+
+Sat Oct 7 08:17:09 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * longlong.h (smul_ppmm): Correct type of __m0 and __m1.
+
+Wed Oct 4 16:31:28 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/configure.in: Handle alphaev5.
+ * mpn/ev4: New name for alpha subdir.
+ * mpn/ev5: New subdir.
+ * mpn/ev5/lshift.s: New file.
+
+Tue Oct 3 15:06:45 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/alpha/mul_1.s: Avoid static increments of pointers; use
+ corresponding offsets in ldq and stq instructions instead.
+ (Loop): Swap cmpult and stq to save one cycle on EV5.
+
+ * mpn/tests/{add_n.s,sub_n.s,lshift.s,rshift.s,mul_1.s,addmul_1.s,
+ submul_1.s}: Don't check results if NOCHECK is defined.
+
+Mon Oct 2 11:40:18 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * longlong.h (mips umul_ppmm [32 and 64 bit versions]):
+ Make new variants, based on GCC version number, that use `l' and `h'
+ constraints instead of explicit mflo and mfhi instructions
+
+Sun Oct 1 00:17:47 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/mc88100/add_n.s: Decrease unrolling factor from 16 to 8.
+ * mpn/mc88100/sub_n.s: Likewise.
+
+ * config/mt-m88110: New file.
+ * configure.in: Use it.
+
+ * mpn/mc88110/mul_1.s: Fix thinko.
+
+Sat Sep 30 21:28:19 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpz/set_d.c: Declare `size' at function start.
+
+ * experimental: New directory for mpx and mpz2.
+
+ * mpz/tdiv_q.c: Clarify comments.
+ * mpz/{mod.c,mod_ui.c}: New file, for math mod function.
+
+ * mpn/sh2/{mul_1.s,addmul_1.s,submul_1.s}: New files.
+
+ * mpn/sh/{add_n.s,sub_n.s}: New files.
+
+ * mpn/pyr/{add_n.s,sub_n.s,mul_1.s,addmul_1.s}: New files.
+
+ * mpn/i960/{add_n.s,sub_n.s}: New files.
+
+ * mpn/alpha/addmul_1.s (Loop): Move decrement of r18 to before umulh,
+ to save cycles on EV5.
+ * mpn/alpha/submul_1.s: Ditto.
+ * mpn/alpha/mul_1.s: Ditto.
+
+Thu Sep 28 02:48:59 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * gmp.h (mp_limb, mp_limb_signed): Define as `long long' if
+ _LONG_LONG_LIMB is defined.
+
+ * longlong.h (m88110): Test __m88110__, not __mc88110__
+
+ * mpn/mc88110/mul_1.s: Rewrite.
+
+Tue Sep 26 23:29:05 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * config.sub: Update from current Cygnus version.
+
+ * mpn/configure.in: Recognize canonical m88*, not mc88*.
+
+Fri Sep 22 14:58:05 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpz/set_d.c: New file.
+ * mpz/Makefile.in: Build new files.
+
+ * mpq/get_d.c: Replace usage of scalbn with ldexp.
+
+ * mpn/{vax,i386}/gmp-mparam.h: New files.
+ * gmp-impl.h (ieee_double_extract): Define here.
+ * mpf/set_d.c (ieee_double_extract): Not here.
+
+Thu Sep 21 00:56:36 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * longlong.h (C umul_ppmm): Use UWtype, not USItype for temps.
+ (udiv_qrnnd): For cases implemented with call to __udiv_qrnnd,
+ protect with new symbol LONGLONG_STANDALONE.
+ (68000 umul_ppmm): Use %# prefix for immediate constants.
+
+Wed Sep 20 15:36:23 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/generic/divmod_1.c: Handle
+ divisor_limb == 1 << (BITS_PER_MP_LIMB - 1)
+ specifically also when normalization_steps != 0.
+
+Mon Sep 18 15:42:30 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpq/get_d.c: New file.
+
+Sun Sep 17 02:04:36 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * longlong.h (pyr): Botch up for now.
+
+Sat Sep 16 00:11:50 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/clipper/mul_1.s: New file.
+ * mpn/clipper/add_n.s: New file.
+ * mpn/clipper/sub_n.s: New file.
+ * mpn/configure.in: Handle clipper*-*-*.
+
+ * mpn/configure.in: Recognize rs6000-*-*.
+
+Fri Sep 15 00:41:34 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/alpha/add_n.s: New file.
+ * mpn/alpha/sub_n.s: New file.
+
+ * mpn/mips3: New name for mpn/r4000.
+ * mpn/mips2: New name for mpn/r3000.
+ * mpn/configure.in: Corresponding changes.
+
+ * mpn/generic/perfsqr.c (primes): Delete.
+ (residue_map): Delete.
+
+Thu Sep 14 00:07:58 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/r3000/sub_n.s: Fix typo.
+
+ * dm_trunc.c: Delete spurious file.
+
+ * mpz/out_binary.c: Fix typo.
+
+ * mpn/configure.in (per-target): Make mips*-*-irix6* imply r4000.
+
+ * gmp-impl.h: For sparc and sgi, include alloca.h.
+
+ * mpn/z8000/mul_1.s: Replace `test r' with `and r,r'. Replace
+ `ldk r,#0' with `xor r,r'.
+
+Wed Sep 6 00:58:38 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpz/inp_binary.c: New file.
+ * mpz/out_binary.c: New file.
+ * mpz/Makefile.in: Build new files.
+
+Tue Sep 5 22:53:51 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * gmp.h (__mpz_struct): Change `long int' => `mp_size_t' for alloc
+ and size fields.
+
+Sat Sep 2 17:47:59 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/r4000/{add_n.s,sub_n.s}: Optimize away some pointer arithmetic.
+ * mpn/r3000/{add_n.s,sub_n.s,lshift.s,rshift.s}: New files,
+ derived from r4000 code.
+
+Fri Sep 1 05:35:52 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/r3000/mul_1.s: Fix typo.
+
+ * mpn/powerpc32: Fix some old vs new mnemonic issues.
+
+ * mpn/powerpc32/{add_n.s,sub_n.s}: New files.
+ * mpn/r4000/{add_n.s,sub_n.s,lshift.s,rshift.s}: New files.
+
+Wed Aug 30 10:43:47 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/r3000/mul_1.s ($LC1): Use addiu for immediate add.
+ * mpn/r4000/{mul_1.s,addmul_1.s,submul_1.s}: New files.
+
+ * config.guess: Update to latest FSF revision.
+
+Mon Aug 28 02:18:13 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpz/out_str.c: Cast str to char * in fputs call.
+
+ * gmp-impl.h: Define UQItype, SItype, and USItype also
+ when not __GNUC__.
+
+Fri Aug 25 01:45:04 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/i386/syntax.h: Renamed from asm-syntax.h.
+ * mpn/mc68020/syntax.h: Renamed from asm-syntax.h.
+ * mpn/configure.in: Corresponding changes.
+
+Sun Aug 13 19:20:04 1995 Torbjorn Granlund <tege@bozo.matematik.su.se>
+
+ * mpn/generic/random2.c: Test __hpux, not hpux.
+
+Sat Apr 15 20:50:33 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/sparc/add_n.S: Make it work for PIC.
+ * mpn/sparc/sub_n.s: Likewise.
+ * mpn/sparc8/addmul_1.S: Likewise.
+ * mpn/sparc8/mul_1.S: Likewise.
+ * mpn/i386/add_n.S: Likewise.
+ * mpn/i386/sub_n.S: Likewise.
+
+Thu Apr 13 23:15:03 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/configure.in: Don't search power subdir for generic ppc configs.
+ Add some ppc cpu-specific configs. Misc clean up.
+
+Mon Apr 10 00:16:35 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/ui_pow_ui.c: Delete spurious code to handle negative results.
+
+Sun Apr 9 12:38:11 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h (SPARC v8 udiv_qrnnd): Generate remainder in C,
+ not in asm.
+
+ * mpn/generic/sqrt.c (SQRT): Test for __SOFT_FLOAT.
+
+Tue Mar 28 00:19:52 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/generic/hamdist.c (popc_limb): Make Mar 16 change here too.
+
+Fri Mar 17 23:29:22 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h (SH umul_ppmm): Define.
+
+Thu Mar 16 16:40:44 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/generic/popcount.c (popc_limb): Rearrange 32 bit case
+ to help CSE.
+
+Fri Mar 10 20:03:49 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/powerpc32/mul_1.s: Clear cy before entering loop.
+ Rearrange loop to save a cycle.
+ * mpn/powerpc32/addmul_1.s: New file.
+ * mpn/powerpc32/submul_1.s: New file.
+
+Fri Feb 17 22:44:45 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/configure.in: Set target_makefile_frag for freebsd
+ in new case stmt.
+ * mpn/config/t-freebsd: New file.
+ * mpn/Makefile.in: Add #### for frag insertion.
+ (XCFLAGS): Clear by default.
+ (.c.o, .S.o rules): Pass XCFLAGS.
+
+Tue Feb 7 16:27:50 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h (68000 umul_ppmm): Merge improvements from henderson.
+
+Tue Jan 24 04:23:20 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h (default umul_ppmm): Store input parameters in temporaries
+ to avoid reading them twice.
+ (default smul_ppmm): New definition.
+
+Thu Dec 29 04:20:07 1994 Jim Meyering (meyering@comco.com)
+
+ * generic/perfsqr.c (__mpn_perfect_square_p): Remove declaration
+ of unused variable.
+ * generic/pre_mod_1.c (__mpn_preinv_mod_1): Likewise.
+ * mpz/powm.c (pow): Likewise.
+
+ * mpz/and.c (mpz_and): Use {} instead of `;' for empty else clause
+ to placate `gcc -Wall'.
+ * mpz/ior.c (mpz_ior): Likewise.
+
+Wed Dec 28 13:31:40 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/m*68*/*.S: #include asm-syntax.h, not asm.h.
+
+Mon Dec 26 17:15:36 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h: Test for more symbols, in __mc68000__ case.
+
+ * mpn/mpn/config.sub: Recognize m68060.
+ * mpn/configure.in: Change mc* to m* for 68k targets.
+ * mpn/Makefile.in (.S.o): Delete spurious creation of temp .c file.
+
+Mon Dec 19 01:56:30 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * config.sub: Recognize pentium as a valid CPU.
+ * mpn/configure.in: Handle pentium specifically, to use new assembly
+ code.
+
+Mon Dec 19 00:13:01 1994 Jim Meyering (meyering@comco.com)
+
+ * gmp.h: Define _GMP_H_HAVE_FILE if FILE, __STDIO_H__, or H_STDIO
+ is defined.
+ * gmp.h: test _GMP_H_HAVE_FILE instead of FILE everywhere else.
+
+Mon Dec 19 00:04:54 1994 Kent Boortz (boortz@sics.se)
+
+ * Makefile.in (recursive makes): Pass CFLAGS.
+
+Sun Dec 18 22:34:49 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/pentium: New directory.
+
+ * mpz/pprime.c: Make sure to mpz_clear all temporaries.
+
+ * longlong.h: Don't use udiv instruction when SUPERSPARC is defined.
+ * configure.in: Handle supersparc*-.
+ * config/mt-supspc-gcc: New file.
+ * config/mt-sparc8-gcc: New name for mt-sparcv8-gcc.
+
+Mon Dec 12 22:22:10 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/i386/*.S: #include "asm-syntax.h", not "asm.h".
+ #include sysdep.h before asm-syntax.h.
+
+ * mpn/mc68020/asm-syntax.h: #undef ALIGN before defining it.
+ * mpn/i386/asm-syntax.h: Likewise.
+
+ * mpn/mc68020/asm-syntax.h: New name for asm.h.
+ * mpn/i386/asm-syntax.h: New name for asm.h.
+
+Tue Dec 6 21:55:25 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/array_init.c: Fix typo in declaration.
+
+Fri Nov 18 19:50:52 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/Makefile.in (.S.o): Pass CFLAGS and INCLUDES.
+
+Mon Nov 14 00:34:12 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/generic/random2.c (random): Test for __svr4__.
+
+Wed Oct 12 23:28:16 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * cre-conv-tab.c (main): Avoid upper-case X in printf format string.
+
+Tue Aug 23 17:16:35 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/perfsqr.c: Use mpn_perfect_square_p.
+ * mpn/generic/perfsqr.c: New file.
+
+Wed Jul 6 13:46:51 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/array_init.c: New file.
+ * mpz/Makefile.in: Compile array_init.
+ * gmp.h: Declare mpz_array_init.
+
+Mon Jul 4 01:10:03 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/add.c: Fix bogus comment.
+ * mpz/sub.c: Likewise.
+
+Sat Jul 2 02:14:56 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpn/generic/pre_mod_1.c: New file.
+ * mpz/perfsqr.c: Use __mpn_preinv_mod_1 when faster.
+
+Fri Jul 01 22:10:19 1994 Richard Earnshaw (rwe11@cl.cam.ac.uk)
+
+ * longlong.h (arm umul_ppmm): Fix typos in last change. Mark
+ hard-coded registers with "%|"
+
+Thu Jun 30 03:59:33 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/perfsqr.c: Define PP, etc, for machines with 64 bit limbs.
+ Use __mpn_mod_1.
+ * mpz/perfsqr.c: Don't clobber REM in quadratic residue check loop.
+
+Wed Jun 29 18:45:41 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpn/generic/sqrt.c (SQRT): New asm for IBM POWER2.
+
+ * mpz/gcd_ui.c: Return 0 if result does not fit an unsigned long.
+
+ * gmp.h: Use "defined (__STDC__)" consistently.
+
+Tue Jun 28 18:44:58 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * gmp.h (mpz_get_si): Don't use "signed" keyword for return type.
+
+ * mpz/tests/Makefile.in: Use CFLAGS for linking.
+
+ * Makefile.in (CFLAGS): Use -O2 here.
+ * mpn/Makefile (CFLAGS): Not here.
+
+ * mpq/cmp_ui.c: Fix typo.
+ * mpq/canonicalize.c: Fix typo.
+ * mpz/gcd_ui.c: Handle gcd(0,v) and gcd(u,0) correctly.
+ * mpn/generic/gcd_1.c: Fix braino in last change.
+
+Mon Jun 27 16:10:27 1994 Torbjorn Granlund (tege@rtl.cygnus.com)
+
+ * mpz/gcd_ui.c: Change return type and return result.
+ Allow destination param to be NULL.
+ * gmp.h: Corresponding change.
+ * mpn/generic/gcd_1.c: Handle zero return from mpn_mod_1.
+
+Tue Jun 14 02:17:43 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/i386/asm.h (ALIGN): Make it take a parameter.
+ * mpn/i386/*.S: Use ALIGN to align all loops.
+
+ * mpn/i386/*.S: Move colon inside C_GLOBAL_NAME expression.
+ (Makes old versions of GAS happy.)
+
+Sat May 28 01:43:54 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * Many files: Delete unused variables and labels.
+ * mpn/generic/dump.c: cast printf width argument to int.
+
+Wed May 25 00:42:37 1994 Torbjorn Granlund (tege@thepub.cygnus.com)
+
+ * mpz/gcd.c (mpz_gcd): Normalize after __mpn_sub calls.
+ (xmod): Ignore return value of __mpn_divmod.
+ (xmod): Improve normalization code.
+
+Sat May 21 01:30:09 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/gcdext.c: Cosmetic changes.
+
+ * mpz/fdiv_ui.c: New file.
+
+Fri May 20 00:24:53 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/tests/Makefile.in: Use explicit rules for running tests,
+ not a shell loop.
+ (clean): Delete stmp-*.
+
+ * mpz/Makefile.in: Update.
+
+ * mpz/div_ui.c: Don't include longlong.h.
+ * mpz/dm_ui.c: Likewise.
+
+ * mpz/fdiv_q.c, mpz/fdiv_q_ui.c, mpz/fdiv_qr.c, mpz/fdiv_qr_ui.c,
+ mpz/fdiv_r.c, mpz/fdiv_r_ui.c: New files. Code partly from deleted
+ mdm.c, mdm_ui.c, etc, partly rewritten.
+ * mpz/dm_floor_ui.c, mpz/dm_floor.c: Delete.
+ * mpz/mdm.c, mpz/mdm_ui.c, mpz/mdiv.c, mpz/mdiv_ui.c, mpz/mmod.c,
+ mpz/mmod_ui.c: Delete.
+
+ * mpz/tdiv_q.c, mpz/tdiv_q_ui.c, mpz/tdiv_qr.c, mpz/tdiv_qr_ui.c,
+ mpz/tdiv_r.c, mpz/tdiv_r_ui.c:
+ New names for files implementing truncating division.
+ * mpz/div_ui.c, mpz/dm_ui.c, mpz/mod_ui.c: Simplify.
+
+ * mpn/Makefile.in (.S.o): Don't rely on CPP being defined, use CC
+ instead.
+ (clean): Delete tmp-*.
+
+Thu May 19 01:37:44 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/cmp.c: Call __mpn_cmp.
+
+ * mpz/popcount.c: Fix typo.
+
+ * mpz/powm_ui.c: Simplify main loop. Keep principal operand size
+ smaller than MSIZE when possible.
+ * mpz/powm.c: Likewise.
+
+ * mpn/generic/sqrt.c: Move alloca calls into where the memory is
+ needed. Simplify.
+
+ * gmp.h: (_PROTO): New macro.
+ Add many function declarations; use _PROTO macro in all declarations.
+
+ * mpf/*.c: Prepend mpn calls with __.
+
+Wed May 18 20:57:06 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpf/*ui*.c: Make ui argument `long' for consistency with mpz
+ functions.
+
+ * mpf/div_ui.c: Simplify.
+
+Tue May 17 01:05:14 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/*.c: Prepend mpn calls with __.
+
+ * mpz/mul_ui.c: Use mpn_mul_1.
+
+Mon May 16 17:19:41 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpn/i386/mul_1.S: Use C_GLOBAL_NAME.
+ * mpn/i386/mul_1.S, mpn/i386/addmul_1.S, mpn/i386/submul_1.S:
+ Nuke use of LAB.
+
+Sat May 14 14:21:02 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * gmp-impl.h: Don't define abort here.
+
+ * mpz/pow_ui.c: Increase temporary allocation.
+ * mpz/ui_pow_ui.c: Likewise.
+
+ * gmp.h (mpz_add_1, mpz_sub_1): Don't call memcpy.
+
+ * All Makefile.in: Delete spurious -I arguments.
+ Update dependencies.
+
+ * mpz/popcount.c: New file.
+ * mpz/hamdist.c: New file.
+
+ * All configure: Latest version from Cygnus.
+
+ * mpq/Makefile.in: New file.
+ * mpq/configure.in: New file.
+ * Makefile.in, configure.in: Enable compilation of mpq.
+
+ * mpq/set_z.c: Fix typos.
+ * mpq/canonicalize.c: Fix typos.
+ * mpq/cmp_ui.c: Fix typos.
+
+ * mpf/add_ui.c: Read U->D into UP always. Delete spurious MPN_COPY.
+ * mpf/sub_ui.c: Likewise.
+
+ * gmp-impl.h: Don't redefine alloca.
+
+ * COPYING.LIB: Renamed from COPYING.
+
+Wed May 11 01:45:44 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/powm_ui.c: When shifting E left by C+1, handle out-of-range
+ shift counts. Fix typo when testing negative_result.
+ * mpz/powm.c: Likewise.
+
+ * mpz/ui_pow_ui.c: New file.
+ * mpz/Makefile.in: Update.
+
+ * mpz/pow_ui.c: Call __mpn_mul_n instead of __mpn_mul when possible.
+
+ * mpz/div.c, mpz/div_ui.c, mpz/gcd.c: Prefix external mpn calls.
+ * mpz/gcd.c: Declare mpn_xmod.
+
+ * mpz/powm.c: Major changes to accommodate changed mpn semantics.
+ * mpz/powm_ui.c: Update from mpz/powm.c.
+
+ * mpz/tests/tst-io.c: New file.
+ * mpz/tests/tst-logic: New file.
+ * mpz/tests/Makefile.in: Update.
+
+ * mpz/inp_str.c: Get base right when checking for first digit.
+ * mpz/inp_str.c: Allocate more space for DEST when needed.
+
+ * mpz/com.c: Use mpn_add_1 and mpn_sub_1.
+ * mpz/and.c, mpz/ior.c: Likewise. Simplify somewhat.
+
+ * mpz/add_ui.c: Use mpn_add_1 and mpn_sub_1.
+ Rename parameters to be consistent with mpz/sub_ui.
+ General simplifications.
+ * mpz/sub_ui.x: Likewise.
+
+Tue Aug 10 19:41:16 1993 Torbjorn Granlund (tege@prudens.matematik.su.se)
+
+ * mpf: New directory.
+ * mpf/*.c: Merge basic set of mpf functions.
+
+ * Many logs missing...
+
+Sun Apr 25 18:40:26 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * memory.c: Use #if instead of #ifdef for __STDC__ for consistency.
+ * bsd/xtom.c: Likewise.
+
+ * mpz/div.c: Remove free_me and free_me_size and their usage.
+ Use mpn_divmod for division; corresponding changes in return value
+ convention.
+ * mpz/powm.c: `carry_digit' => `carry_limb'.
+ * bsd/sdiv.c: Clarify comment.
+
+Sun Apr 25 00:31:28 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * longlong.h (__udiv_qrnnd_c): Make all variables `unsigned long int'.
+
+Sat Apr 24 16:23:33 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * longlong.h (__udiv_qrnnd_c): Make all variables `unsigned long int'.
+
+ * gmp-impl.h: #define ABS.
+ * (Many files): Use ABS instead of abs.
+
+ * mpn/generic/sqrt.c, mpz/clrbit.c, mpz/get_si.c, mpz/mod_2exp.c,
+ mpz/pow_ui.c: Cast 1 to mp_limb before shifting.
+
+ * mpz/perfsqr.c: Use #if, not plain if for exclusion of code for
+ non-32-bit machines.
+
+Tue Apr 20 13:13:58 1993 Torbjorn Granlund (tege@du.nada.kth.se)
+
+ * mpn/generic/sqrt.c: Handle overflow for intermediate quotients by
+ rounding them down to fit.
+
+ * mpz/perfsqr.c (PP): Define in hexadecimal to avoid GCC warnings.
+
+ * mpz/inp_str.c (char_ok_for_base): New function.
+ (mpz_inp_str): Use it.
+
+Sun Mar 28 21:54:06 1993 Torbjorn Granlund (tege@cyklop.nada.kth.se)
+
+ * mpz/inp_raw.c: Allocate x_index, not xsize limbs.
+
+Mon Mar 15 11:44:06 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * mpz/pprime.c: Declare param `const'.
+ * gmp.h: Add declarations for mpz_com.
+
+Thu Feb 18 14:10:34 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * mpq/add.c, mpq/sub.c: Call mpz_clear for t.
+
+Fri Feb 12 20:27:34 1993 Torbjorn Granlund (tege@cyklop.nada.kth.se)
+
+ * mpz/inp_str.c: Recog minus sign as first character.
+
+Wed Feb 3 01:36:02 1993 Torbjorn Granlund (tege@cyklop.nada.kth.se)
+
+ * mpz/iset.c: Handle 0 size.
+
+Tue Feb 2 13:03:33 1993 Torbjorn Granlund (tege@cyklop.nada.kth.se)
+
+ * mpz/mod_ui.c: Initialize dividend_size before it's used.
+
+Mon Jan 4 09:11:15 1993 Torbjorn Granlund (tege@sics.se)
+
+ * bsd/itom.c: Declare param explicitly 'signed'.
+ * bsd/sdiv.c: Likewise.
+
+ * mpq/cmp.c: Remove unused variable tmp_size.
+ * mpz/powm_ui.c: Fix typo in esize==0 if stmt.
+ * mpz/powm.c: Likewise.
+
+Sun Nov 29 01:16:11 1992 Torbjorn Granlund (tege@sics.se)
+
+ * mpn/generic/divmod_1.c (mpn_divmod_1): Handle
+ divisor_limb == 1 << (BITS_PER_MP_LIMB - 1)
+ specifically.
+
+ * Reorganize sources. New directories mpn, mpn/MACH, mpn/generic,
+ mpz, mpq, bsd. Use full file name for change logs hereafter.
+
+Wed Oct 28 17:40:04 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ * longlong.h (__hppa umul_ppmm): Fix typos.
+ (__hppa sub_ddmmss): Swap input arguments.
+
+ * mpz_perfsqr.c (mpz_perfect_square_p): Avoid , before } in
+ initializator.
+
+Sun Oct 25 20:30:06 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ * mpz_pprime.c (mpz_probab_prime_p): Handle numbers <= 3
+ specifically (used to consider all negative numbers prime).
+
+ * mpz_powm_ui: `carry_digit' => `carry_limb'.
+
+ * sdiv: Handle zero dividend specifically. Replace most code in
+ this function with a call to mpn_divmod_1.
+
+Fri Sep 11 22:15:55 1992 Torbjorn Granlund (tege@tarrega.sics.se)
+
+ * mpq_clear: Don't free the MP_RAT!
+
+ * mpn_lshift, mpn_rshift, mpn_rshiftci: Remove `long' from 4:th arg.
+
+Thu Sep 3 01:47:07 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ * All files: Remove leading _ from mpn function names.
+
+Wed Sep 2 22:21:16 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ Fix from Jan-Hein Buhrman:
+ * mpz_mdiv.c, mpz_mmod.c, mpz_mdm.c: Make them work as documented.
+
+ * mpz_mmod.c, mpz_mdm.c: Move decl of TEMP_DIVISOR to reflect its
+ life.
+
+Sun Aug 30 18:37:15 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ * _mpz_get_str: Use mpz_sizeinbase for computing out_len.
+ * _mpz_get_str: Don't remove leading zeros. Abort if there are some.
+
+Wed Mar 4 17:56:56 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp.h: Change definition of MP_INT to make the & before params
+ optional. Use typedef to define it.
+ * mp.h: Use typedef to define MINT.
+
+Tue Feb 18 14:38:39 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ longlong.h (hppa umul_ppmm): Add missing semicolon. Declare type
+ of __w1 and __w0.
+
+Fri Feb 14 21:33:21 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Make default count_leading_zeros work for machines >
+ 32 bits. Prepend `__' before local variables to avoid conflicts
+ with users' variables.
+
+ * mpn_dm_1.c: Remove udiv_qrnnd_preinv ...
+ * gmp-impl.h: ... and put it here.
+ * mpn_mod_1: Use udiv_qrnnd_preinv if it is faster than udiv_qrnnd.
+
+Tue Feb 11 17:20:12 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: Enhance base case by handling small multiplicands.
+ * mpn_dm_1.c: Revert last change.
+
+Mon Feb 10 11:55:15 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_dm_1.c: Don't define udiv_qrnnd_preinv unless needed.
+
+Fri Feb 7 16:26:16 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: Replace code for base case.
+
+Thu Feb 6 15:10:42 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_dm_1.c (_mpn_divmod_1): Add code for avoiding division by
+ pre-inverting divisor.
+
+Sun Feb 2 11:10:25 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Make __LLDEBUG__ work differently.
+ (_IBMR2): Reinsert old code.
+
+Sat Feb 1 16:43:00 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (#ifdef _IBMR2): Replace udiv_qrnnd with new code
+ using floating point operations. Don't define
+ UDIV_NEEDS_NORMALIZATION any longer.
+
+Fri Jan 31 15:09:13 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Define UMUL_TIME and UDIV_TIME for most machines.
+ * longlong.h (#ifdef __hppa): Define umul_ppmm.
+
+Wed Jan 29 16:41:36 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_cmp: Only one length parameter, assume operand lengths are
+ the same. Don't require normalization.
+ * mpq_cmp, mpz_add, mpz_sub, mpz_gcd, mpn_mul, mpn_sqrt: Change for
+ new mpn_cmp definition.
+
+Tue Jan 28 11:18:55 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_get_str: Fix typo in comment.
+
+Mon Jan 27 09:44:16 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Makefile.in: Add new files.
+
+ * mpn_dm_1.c: New file with function _mpn_divmod_1.
+ * mpz_dm_ui.c (mpz_divmod_ui): Use _mpn_divmod_1.
+ * mpz_div_ui: Likewise.
+
+ * mpn_mod_1.c: New file with function _mpn_mod_1.
+ * mpz_mod_ui: Use _mpn_mod_1.
+
+Thu Jan 23 18:54:09 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Bug found by Paul Zimmermann (zimmermann@inria.inria.fr):
+ * mpz_div_ui.c (mpz_div_ui), mpz_dm_ui.c (mpz_divmod_ui):
+ Handle dividend == 0.
+
+Wed Jan 22 12:02:26 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_pprime.c: Use "" for #include.
+
+Sun Jan 19 13:36:55 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_rshiftci.c (header): Correct comment.
+
+Wed Jan 15 18:56:04 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_powm, mpz_powm_ui (if (bsize > msize)): Do alloca (bsize + 1)
+ to make space for ignored quotient at the end. (The quotient might
+ always be an extra limb.)
+
+Tue Jan 14 21:28:48 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_powm_ui: Fix comment.
+ * mpz_powm: Likewise.
+
+Mon Jan 13 18:16:25 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * tests/Makefile.in: Prepend $(TEST_PREFIX) to Makefile target.
+
+Sun Jan 12 13:54:28 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Fixes from Kazumaro Aoki:
+ * mpz_out_raw: Take abs of size to handle negative values.
+ * mpz_inp_raw: Reallocate before reading ptr from X.
+ * mpz_inp_raw: Store, don't read, size to x->size.
+
+Tue Jan 7 17:50:25 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp.h, mp.h: Remove parameter names from prototypes.
+
+Sun Dec 15 00:09:36 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * tests/Makefile.in: Prepend "./" to file names when executing
+ tests.
+
+ * Makefile.in: Fix many problems.
+
+Sat Dec 14 01:00:02 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_sqrt.c: New file with _mpn_sqrt.
+ * mpz_sqrt, mpz_sqrtrem, mpz_perfect_square_p: Use _mpn_sqrt.
+ * msqrt.c: Delete. Create from mpz_sqrtrem.c in Makefile.in.
+ * mpz_do_sqrt.c: Delete.
+ * Makefile.in: Update to reflect these changes.
+
+ * Makefile.in, configure, configure.subr: New files
+ (from bothner@cygnus.com).
+ * dist-Makefile: Delete.
+
+ * mpz_fac_ui: Fix comment.
+
+ * mpz_random2: Rewrite a bit to make it possible for the most
+ significant limb to be == 1.
+
+ * mpz_pprime.c (mpz_probab_prime_p): Remove \t\n.
+
+Fri Dec 13 23:10:02 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_do_sqrt: Simplify special case for U == 0.
+ * m*sqrt*.c, mpz_perfsqr.c (mpz_perfect_square_p):
+ Rename _mpz_impl_sqrt to _mpz_do_sqrt.
+
+Fri Dec 13 12:52:28 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp-impl.h (MPZ_TMP_INIT): Cast to the right type.
+
+Thu Dec 12 22:17:29 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_add, mpn_sub, mpn_mul, mpn_div: Change type of several
+ variables to mp_size.
+
+Wed Dec 11 22:00:34 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_rshift.c: Fix header comments.
+
+Mon Dec 9 17:46:10 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.2.
+
+ * gmp-impl.h (MPZ_TMP_INIT): Cast alloca return value.
+
+ * dist-Makefile: Add missing dependency for cre-mparam.
+
+ * mpz_mdiv.c, mpz_mmod.c, mpz_mdm.c, mpz_mdiv_ui.c,
+ mpz_mmod_ui.c, mpz_mdm_ui.c: Remove obsolete comment.
+
+ * dist-Makefile (clean): clean in tests subdir too.
+ * tests/Makefile: Define default values for ROOT and SUB.
+
+ * longlong.h (__a29k__ udiv_qrnnd): Change "q" to "1" for operand
+ 2 constraint.
+
+Mon Nov 11 00:06:05 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_sizeinb.c (mpz_sizeinbase): Special code for size == 0.
+
+Sat Nov 9 23:47:38 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.1.94.
+
+ * dist-Makefile, Makefile, tests/Makefile: Merge tests into
+ distribution.
+
+Fri Nov 8 22:57:19 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp.h: Don't use keyword `signed' for non-ANSI compilers.
+
+Thu Nov 7 22:06:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Cosmetic changes to keep it identical to gcc2 version
+ of longlong.h.
+ * longlong.h (__ibm032__): Fix operand order for add_ssaaaa and
+ sub_ddmmss.
+
+Mon Nov 4 00:36:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: Fix indentation.
+
+ * mpz_do_sqrt: Don't assume 32 bit limbs (had constant
+ 4294967296.0).
+ * mpz_do_sqrt: Handle overflow in conversion from double returned
+ by SQRT to mp_limb.
+
+ * gmp.h: Add missing function definitions.
+
+Sun Nov 3 18:25:25 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_pow_ui: Change type of `i' to int.
+
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+Stack overflow.
+
+ * mpz_pow_ui.c: Fix typo in comment.
+
+ * dist-Makefile: Create rpow.c from mpz_powm_ui.c.
+ * mpz_powm_ui.c: Add code for rpow.
+ * rpow.c: Delete this file. The rpow function is now implemented
+ in mpz_powm_ui.c.
+
+ * mpz_fac_ui.c: New file.
+ * gmp.h, dist-Makefile: Add stuff for mpz_fac_ui.
+
+ Bug found by John Amanatides (amana@sasquatch.cs.yorku.ca):
+ * mpz_powm_ui, mpz_powm: Call _mpn_mul in the right way, with
+ the first argument not smaller than the second.
+
+Tue Oct 29 13:56:55 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * cre-conv-tab.c (main), cre-mparam.c (main): Fix typo in output
+ header text.
+
+Mon Oct 28 00:35:29 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_random2: Handle size == 0.
+
+ * gmp-impl.h (struct __mp_bases): Rename chars_per_limb_exactly to
+ chars_per_bit_exactly, and change its definition.
+ * cre-conv-tab.c (main): Output field according to its new
+ definition.
+ * mpz_out_str, _mpz_get_str, mpz_sizeinb, mout:
+ Use chars_per_bit_exactly.
+
+ * mpz_random2: Change the loop termination condition in order to
+ get a large most significant limb with higher probability.
+
+ * gmp.h: Add declaration of new mpz_random2 and mpz_get_si.
+ * mpz_get_si.c: New file.
+ * dist-Makefile: Add mpz_random2 and mpz_get_si.
+
+ * mpz_sizeinb.c (mpz_sizeinbase): Special code for base being a
+ power of 2, giving exact result.
+
+ * mpn_mul: Fix MPN_MUL_VERIFY in various ways.
+ * mpn_mul: New macro KARATSUBA_THRESHOLD.
+ * mpn_mul (karatsuba's algorithm): Don't write intermediate results
+ to prodp, use temporary pp instead. (Intermediate results can be
+ larger than the final result, possibly writing into hyperspace.)
+ * mpn_mul: Make smarter choice between Karatsuba's algorithm and the
+ shortcut algorithm.
+ * mpn_mul: Fix typo, cy instead of xcy. Unify carry handling code.
+
+Sun Oct 27 19:57:32 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: In non-classical case, choose Karatsuba's algorithm only
+ when usize > 1.5 vsize.
+
+ * mpn_mul: Break between classical and Karatsuba's algorithm at
+ KARATSUBA_THRESHOLD, if defined. Default to 8.
+
+ * mpn_div: Kludge to fix stray memory read.
+
+Sat Oct 26 20:06:14 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_gcdext: Handle a = b = 0. Remove memory leakage by calling
+ mpz_clear for all temporary variables.
+
+ * mpz_gcd: Reduce w_bcnt in _mpn_lshift call to hold that
+ function's argument constraints. Compute wsize correctly.
+
+ * mpz_gcd: Fix typo in comment.
+
+ * memory.c (_mp_default_allocate, _mp_default_reallocate): Call
+ abort if allocation fails, don't just exit.
+
+Fri Oct 25 22:17:20 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_random2.c: New file.
+
+Thu Oct 17 18:06:42 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Bugs found by Pierre-Joseph Gailly (pjg@sunbim.be):
+ * mpq_cmp: Take sign into account, don't just compare the
+ magnitudes.
+ * mpq_cmp: Call _mpn_mul in the right way, with the first argument
+ not smaller than the second.
+
+Wed Oct 16 19:27:32 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_random: Ensure the result is normalized.
+
+Tue Oct 15 14:55:13 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_clrbit: Support non-ANSI compilers.
+
+Wed Oct 9 18:03:28 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (68k add_ssaaaa, sub_ddmmss): Generalize constraints.
+
+Tue Oct 8 17:42:59 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_mdm_ui: Add comments.
+
+ * mpz_mdiv: Use MPZ_TMP_INIT instead of mpz_init.
+ * mpz_init_ui: Change spacing and header comment.
+
+Thu Oct 3 18:36:13 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * dist-Makefile: Prepend `./' before some filenames.
+
+Sun Sep 29 14:02:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.1 (public).
+
+ * mpz_com: New name of mpz_not.
+ * dist-Makefile: Change mpz_not to mpz_com.
+
+Tue Sep 24 12:44:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Fix header comment.
+
+Mon Sep 9 15:16:24 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.0.92.
+
+ * mpn_mul.c (_mpn_mul): Handle leading zero limbs in non-Karatsuba
+ case.
+
+ * longlong.h (m68000 umul_ppmm): Clobber one register less by
+ slightly rearranging the code.
+
+Sun Sep 1 18:53:25 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * dist-Makefile (stamp-stddefh): Fix typo.
+
+Sat Aug 31 20:41:31 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.0.91.
+
+ * mpz_mdiv.c, mpz_mmod.c, mpz_mdm.c, mpz_mdiv_ui.c,
+ mpz_mmod_ui.c, mpz_mdm_ui.c: New files and functions.
+ * gmp.h, gmp.texi: Define the new functions.
+
+Fri Aug 30 08:32:56 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_gcdext: Compute t argument from the other quantities at the
+ end, of the function, not in the loop. New feature: Allow t to be
+ NULL.
+
+ * mpz_add.c, mpz_sub.c, mpz_mul.c, mpz_powm.c, mpz_gcd.c: Don't
+ include "mp.h". Use type name `MP_INT' always.
+
+ * dist-Makefile, mpz_cmp.c: Merge mcmp.c from mpz_cmp.c.
+
+Wed Aug 28 00:45:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * dist-Makefile (documentation): Go via tmp.texi to avoid the
+ creation of gmp.dvi if any errors occur. Make tex read input
+ from /dev/null.
+
+Fri Aug 23 15:58:52 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (68020, i386): Don't define machine-dependent
+ __umulsidi3 (so the default definition is used).
+ * longlong.h (all machines): Cast all operands, sources and
+ destinations, to `unsigned long int'.
+ * longlong.h: Add gmicro support.
+
+Thu Aug 22 00:28:29 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Rename BITS_PER_LONG to LONG_TYPE_SIZE.
+ * longlong.h (__ibm032__): Define count_leading_zeros and umul_ppmm.
+ * longlong.h: Define UMUL_TIME and UDIV_TIME for some CPUs.
+ * _mpz_get_str.c: Add code to do division by big_base using only
+ umul_qrnnd, if that is faster. Use UMUL_TIME and UDIV_TIME to
+ decide which variant to use.
+
+Wed Aug 21 15:45:23 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (__sparc__ umul_ppmm): Move two insn from end to the
+ nops. (Saves two insn.)
+
+ * longlong.h (__sparc__ umul_ppmm): Rewrite in order to avoid
+ branch, and to permit input/output register overlap.
+
+ * longlong.h (__29k__): Remove duplicated udiv_qrnnd definition.
+ * longlong.h (__29k__ umul_ppmm): Split asm instructions into two
+ asm statements (gives better code if either the upper or lower
+ part of the product is unused.
+
+Tue Aug 20 17:57:59 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_get_str.c (outside of functions): Remove
+ num_to_ascii_lower_case and num_to_ascii_upper_case. Use string
+ constants in the function instead.
+
+Mon Aug 19 00:37:42 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * cre-conv-tab.c (main): Output table in hex. Output 4 fields, not
+ 3, for components 0 and 1.
+
+ * gmp.h: Add declaration of mpq_neg.
+
+ Released 1.0beta.13.
+
+ * _mpz_set_str.c (mpz_set_str): Cast EOF and SPC to char before
+ comparing to enum literals SPC and EOF. This makes the code work
+ for compilers where `char' is unsigned. (Bug found by Brian
+ Beuning).
+
+ Released 1.0beta.12.
+
+ * mpz_mod_ui: Remove references to quot. Remove quot_ptr, quot_size
+ declarations and assignment code.
+
+Sun Aug 18 14:44:26 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_mod_ui: Handle dividend < 0.
+
+ Released 1.0beta.11.
+
+ * mpz_dm_ui, mpz_div_ui, mpz_mod_ui, sdiv: Make them share the same
+ general structure, variable names, etc.
+
+ * sdiv: Un-normalize the remainder in n1 before it is negated.
+
+ * longlong.h: Mention UDIV_NEEDS_NORMALIZATION in description of
+ udiv_qrnnd.
+
+ * mpz_dm_ui.c (mpz_divmod_ui), mpz_div_ui.c (mpz_div_ui): Increment
+ the quotient size if the dividend size is incremented. (Bug found
+ by Brian Beuning.)
+
+ * mpz_mod_ui: Shift back the remainder, if UDIV_NEEDS_NORMALIZATION.
+ (Bug found by Brian Beuning.)
+
+ * mpz_mod_ui: Replace "digit" by "limb".
+
+ * mpz_perfsqr.c (mpz_perfect_square_p): Disable second test case
+ for non-32-bit machines (PP is hardwired for such machines).
+ * mpz_perfsqr.c (outside of functions): Define PP value with an L.
+
+ * mpn_mul.c (_mpn_mul): Add verification code that is activated if
+ DEBUG is defined. Replace "digit" by "limb".
+ * mpn_mul.c (_mpn_mul: Karatsuba's algorithm: 4.): Normalize temp
+ after the addition.
+ * mpn_mul.c (_mpn_mul: Karatsuba's algorithm: 1.): Compare u0_size
+ and v0_size, and according to the result, swap arguments in
+ recursive call. (Don't violate mpn_mul's own argument
+ constraints.)
+
+Fri Aug 16 13:47:12 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.0beta.10.
+
+ * longlong.h (IBMR2): Add udiv_qrnnd.
+
+ * mpz_perfsqr: Remove unused variables.
+
+ * mpz_and (case for different signs): Initialize loop variable i!
+
+ * dist-Makefile: Update automatically generated dependencies.
+ * dist-Makefile (madd.c, msub.c, pow.c, mult.c, gcd.c): Add mp.h,
+ etc to dependency file lists.
+
+ * longlong.h (add_ssaaaa, sub_ddmmss [C default versions]): Make __x
+ `unsigned long int'.
+ * longlong.h: Add `int' after `unsigned' and `long' everywhere.
+
+Wed Aug 14 18:06:48 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Add ARM, i860 support.
+
+ * mpn_lshift, mpn_rshift, mpn_rshiftci: Rename *_word with *_limb.
+
+Tue Aug 13 21:57:43 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_get_str.c, _mpz_set_str.c, mpz_sizeinb.c (mpz_sizeinbase),
+ mpz_out_str.c, mout.c: Remove declaration of __mp_bases.
+ * gmp-impl.h: Put it here, and make it `const'.
+ * cre-conv-tab.c (main): Make struct __mp_bases `const'.
+
+Mon Aug 12 17:11:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * cre-conv-tab.c (main): Use %lu in printf for long ints.
+
+ * dist-Makefile: Fix cre-* dependencies.
+
+ * cre-conv-tab.c (main): Output field big_base_inverted.
+
+ * gmp-impl.h (struct bases): New field big_base_inverted.
+ * gmp-impl.h (struct bases): Change type of chars_per_limb_exactly
+ to float (in order to keep the structure smaller).
+
+ * mp.h, gmp.h: Change names of macros for avoiding multiple
+ includes.
+
+Fri Aug 9 18:01:36 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_get_str: Only shift limb array if normalization_steps != 0
+ (optimization).
+
+ * longlong.h (sparc umul_ppmm): Use __asm__, not asm.
+ * longlong.h (IBMR2 umul_ppmm): Refer to __m0 and __m1, not to m0
+ and m1 (overlap between output and input operands did not work).
+ * longlong.h: Add VAX, ROMP and HP-PA support.
+ * longlong.h: Sort the machine dependent code in alphabetical order
+ on the CPU name.
+ * longlong.h: Hack comments.
+
+Thu Aug 8 14:13:36 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.0beta.9.
+
+ * longlong.h: Define BITS_PER_LONG to 32 if it's not already
+ defined.
+ * Define __BITS4 to BITS_PER_LONG / 4.
+ * Don't assume 32 bit word size in "count_leading_zeros" C macro.
+ Use __BITS4 and BITS_PER_LONG instead.
+
+ * longlong.h: Don't #undef internal macros (reverse change of Aug 3).
+
+ * longlong.h (68k): Define add_ssaaaa sub_ddmmss, and umul_ppmm
+ even for plain mc68000.
+
+ * mpq_div: Flip the sign of the numerator *and* denominator of the
+ result if the intermediate denominator is negative.
+
+ * mpz_and.c, mpz_ior.c: Use MPN_COPY for all copying operations.
+
+ * mpz_and.c: Compute the result size more conservatively.
+ * mpz_ior.c: Likewise.
+
+ * mpz_realloc: Never allocate zero space even if NEW_SIZE == 0.
+
+ * dist-Makefile: Remove madd.c, msub.c, pow.c, mult.c, gcd.c from
+ BSDMP_SRCS.
+
+ * dist-Makefile: Create mult.c from mpz_mul.c.
+ * mult.c: Delete this file.
+
+ * _mpz_set_str: Normalize the result (for bases 2, 4, 8... it was
+ not done properly if the input string had many leading zeros).
+
+Sun Aug 4 16:54:14 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * dist-Makefile (gcd.c, pow.c, madd.c, msub.c): Make these targets
+ work with VPATH and GNU MP.
+
+ * mpz_gcd: Don't call mpz_set; inline its functionality.
+
+ * mpq_mul, mpq_div: Fix several serious typos.
+
+ * mpz_dmincl, mpz_div: Don't normalize the quotient if it's already
+ zero.
+
+ * mpq_neg.c: New file.
+
+ * dist-Makefile: Remove obsolete dependencies.
+
+ * mpz_sub: Fix typo.
+
+ Bugs found by Pierre-Joseph Gailly (pjg@sunbim.be):
+ * mpq_mul, mpq_div: Initialize tmp[12] variables even when the gcd
+ is just 1.
+ * mpz_gcd: Handle gcd(0,v) and gcd(u,0) in special cases.
+
+Sat Aug 3 23:45:28 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Clean up comments.
+ * longlong.h: #undef internal macros.
+
+Fri Aug 2 18:29:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpq_set_si, mpq_set_ui: Canonicalize 0/x to 0/1.
+ * mpq_set_si, mpq_set_ui: Cosmetic formatting changes.
+
+ * mpz_dmincl.c: Normalize the remainder before shifting it back.
+
+ * mpz_dm_ui.c (mpz_divmod_ui): Handle rem == dividend.
+
+ * mpn_div.c: Fix comment.
+
+ * mpz_add.c, mpz_sub.c: Use __MP_INT (not MP_INT) for intermediate
+ type, in order to work for both GNU and Berkeley functions.
+
+ * dist-Makefile: Create gcd.c from mpz_gcd.c, pow.c from mpz_powm,
+ madd.c from mpz_add.c, msub.c from mpz_sub.c.
+ respectively.
+ * pow.c, gcd.c, mpz_powmincl.c, madd.c, msub.c: Remove these.
+ * mpz_powm.c, mpz_gcd.c, mpz_add.c, mpz_sub.c: #ifdef for GNU and
+ Berkeley function name variants.
+ * dist-Makefile: Add created files to "clean" target.
+
+Tue Jul 16 15:19:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpq_get_den: No need for absolute value of the size, the
+ denominator is always positive.
+
+ * mpz_get_ui: If the operand is zero, return zero. Don't read the
+ limb array!
+
+ * mpz_dmincl.c: Don't ignore the return value from _mpn_rshift, it
+ is the size of the remainder.
+
+Mon Jul 15 11:08:05 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Several files: Remove unused variables and functions.
+
+ * gmp-impl.h: Declare _mpz_impl_sqrt.
+
+ * mpz_dm_ui (mpz_divmod_ui), sdiv: Shift back the remainder if
+ UDIV_NEEDS_NORMALIZATION. (Fix from Brian Beuning.)
+
+ * mpz_dm_ui.c, sdiv: Replace *digit with *limb.
+
+ * mpz_ior: Add missing else statement in -OP1 | -OP2 case.
+ * mpz_ior: Add missing else statement in OP1 | -OP2 case.
+ * mpz_ior: Swap also OP1 and OP2 pointers in -OP1 & OP2 case.
+ * mpz_ior: Duplicate _mpz_realloc code.
+
+ * mpz_and: Add missing else statement in -OP1 & -OP2 case.
+ * mpz_and: Rewrite OP1 & -OP2 case.
+ * mpz_and: Swap also OP1 and OP2 pointers in -OP1 & OP2 case.
+
+ * mpz_gcdext: Loop in d1.size (not b->size). (Fix from Brian
+ Beuning.)
+
+ * mpz_perfsqr: Fix argument order in _mpz_impl_sqrt call. (Fix from
+ Brian Beuning.)
+
+Fri Jul 12 17:10:33 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpq_set.c, mpq_set_ui.c, mpq_set_si.c, mpq_inv.c,
+ mpq_get_num.c, mpq_get_den.c, mpq_set_num.c, mpq_set_den.c:
+ New files.
+
+ * mpz_dmincl.c: Remove second re-allocation of rem->d. It
+ was never executed.
+
+ * dist-Makefile: Use `-r' instead of `-x' for test for ranlib (as
+ some unixes' test doesn't have the -r option).
+
+ * *.*: Cast allocated pointers to the appropriate type (makes old C
+ compilers happier).
+
+ * cre-conv-tab.c (main): Divide max_uli by 2 and multiply again
+ after conversion to double. (Kludge for broken C compilers.)
+
+ * dist-Makefile (stamp-stddefh): New target. Test if "stddef.h"
+ exists in the system and creates a minimal one if it does not
+ exist.
+ * cre-stddefh.c: New file.
+ * dist-Makefile: Make libgmp.a and libmp.a depend on stamp-stddefh.
+ * dist-Makefile (clean): Add some more.
+ * gmp.h, mp.h: Unconditionally include "stddef.h".
+
+Thu Jul 11 10:08:21 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * min: Do ungetc of last read character.
+ * min.c: include stdio.h.
+
+ * dist-Makefile: Go via tmp- files for cre* redirection.
+ * dist-Makefile: Add tmp* to "clean" target.
+
+ * dist-Makefile: Use LOCAL_CC for cre*, to simplify cross
+ compilation.
+
+ * gmp.h, mp.h: Don't define NULL here.
+ * gmp-impl.h: Define it here.
+
+Wed Jul 10 14:13:33 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_mod_2exp: Don't copy too much, overwriting most significant
+ limb.
+
+ * mpz_and, mpz_ior: Don't read op[12]_ptr from op[12] when
+ reallocating res, if op[12]_ptr got their value from alloca.
+
+ * mpz_and, mpz_ior: Clear up comments.
+
+ * cre-mparam.c: Output parameters for `short int' and `int'.
+
+ * mpz_and, mpz_ior: Negate negative op[12]_size in several places.
+
+Tue Jul 9 18:40:30 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp.h, mp.h: Test for _SIZE_T defined before typedef'ing size_t.
+ (Fix for Sun lossage.)
+
+ * gmp.h: Add declaration of mpq_clear.
+
+ * dist-Makefile: Check if "ranlib" exists, before using it.
+ * dist-Makefile: Add mpz_sqrtrem.c and mpz_size.c.
+ * mpz_powm: Fix typo, "pow" instead of "mpz_powm".
+
+Fri Jul 5 19:08:09 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * move: Remove incorrect comment.
+
+ * mpz_free, mpq_free: Rename to *_clear.
+ * dist-Makefile: Likewise.
+ * mpq_add, mpq_sub, mpq_mul, mpq_div: Likewise.
+
+ * mpz_dmincl.c: Don't call "move", inline its functionality.
+
+Thu Jul 4 00:06:39 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Makefile: Include dist-Makefile. Fix dist target to include
+ dist-Makefile (with the name "Makefile" in the archive).
+
+ * dist-Makefile: New file made from Makefile. Add new mpz_...
+ functions.
+
+ * mpz_powincl.c New file for mpz_powm (Berkeley MP pow)
+ functionality. Avoids code duplication.
+ * pow.c, mpz_powm.c: Include mpz_powincl.c
+
+ * mpz_dmincl.c: New file containing general division code. Avoids
+ code duplication.
+ * mpz_dm.c (mpz_divmod), mpz_mod.c (mpz_mod), mdiv.c (mdiv): Include
+ mpz_dmincl.c.
+
+ * _mpz_get_str: Don't call memmove, unless HAS_MEMMOVE is defined.
+ Instead, write the overlapping memory copying inline.
+
+ * mpz_dm_ui.c: New name for mpz_divmod_ui.c (SysV file name limit).
+
+ * longlong.h: Don't use #elif.
+ * mpz_do_sqrt.c: Likewise.
+
+ * longlong.h: Use __asm__ instead of asm.
+ * longlong.h (sparc udiv_qrnnd): Make it to one string over several
+ lines.
+
+ * longlong.h: Preend __ll_ to B, highpart, and lowpart.
+
+ * longlong.h: Move array t in count_leading_zeros to the new file
+ mp_clz_tab.c. Rename the array __clz_tab.
+ * All files: #ifdef for traditional C compatibility.
+
+Wed Jul 3 11:42:14 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_and: Initialize res_ptr always (used to be initialized only
+ when reallocating).
+
+ * longlong.h (umul_ppmm [C variant]): Make __ul...__vh
+ `unsigned int', and cast the multiplications. This way
+ compilers more easily can choose cheaper multiplication
+ instructions.
+
+ * mpz_mod_2exp: Handle input argument < modulo argument.
+ * mpz_many: Make sure mp_size is the type for sizes, not int.
+
+ * mpz_init, mpz_init_set*, mpq_init, mpq_add, mpq_sub, mpq_mul,
+ mpq_div: Change mpz_init* interface. Structure pointer as first
+ arg to initialization function, no longer *return* struct.
+
+Sun Jun 30 19:21:44 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Rename mpz_impl_sqrt.c to mpz_do_sqrt.c to satisfy SysV 14
+ character file name length limit.
+
+ * Most files: Rename MINT to MP_INT. Rename MRAT to MP_RAT.
+ * mpz_sizeinb.c: New file with function mpz_sizeinbase.
+ * mp_bases.c: New file, with array __mp_bases.
+ * _mpz_get_str, _mpz_set_str: Remove struct bases, use extern
+ __mp_bases instead.
+ * mout, mpz_out_str: Use array __mp_bases instead of function
+ _mpz_get_cvtlen.
+ * mpz_get_cvtlen.c: Remove.
+ * Makefile: Update.
+
+Sat Jun 29 21:57:28 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (__sparc8__ umul_ppmm): Insert 3 nop:s for wr delay.
+ * longlong.h (___IBMR2__): Define umul_ppmm, add_ssaaaa, sub_ddmmss.
+ * longlong.h (__sparc__): Don't call .umul; expand asm instead.
+ Don't define __umulsidi3 (i.e. use default definition).
+
+Mon Jun 24 17:37:23 1991 Torbjorn Granlund (tege@amon.sics.se)
+
+ * _mpz_get_str.c (num_to_ascii_lower_case, num_to_ascii_upper_case):
+ Swap 't' and 's'.
+
+Sat Jun 22 13:54:01 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_gcdext.c: New file.
+
+ * mpn_mul: Handle carry and unexpected operand sizes in last
+ additions/subtractions. (Bug trigged when v1_size == 1.)
+
+ * mp*_alloc*: Rename functions to mp*_init* (files to mp*_iset*.c).
+ * mpq_*: Call mpz_init*.
+
+ * mpz_pow_ui, rpow: Use _mpn_mul instead of mult. Restructure.
+
+Wed May 29 20:32:33 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_get_cvtlen: multiply by size.
+
+Sun May 26 15:01:15 1991 Torbjorn Granlund (tege@bella.nada.kth.se)
+
+ Alpha-release 0.95.
+
+ Fixes from Doug Lea (dl@g.oswego.edu):
+ * mpz_mul_ui: Loop to MULT_SIZE (not PROD_SIZE). Adjust PROD_SIZE
+ correctly.
+ * mpz_div: Prepend _ to mpz_realloc.
+ * mpz_set_xs, mpz_set_ds: Fix typos in function name.
+
+Sat May 25 22:51:16 1991 Torbjorn Granlund (tege@bella.nada.kth.se)
+
+ * mpz_divmod_ui: New function.
+
+ * sdiv: Make the sign of the remainder correct.
+
+Thu May 23 15:28:24 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Alpha-release 0.94.
+
+ * mpz_mul_ui: Include longlong.h.
+
+ * mpz_perfsqr.c (mpz_perfect_square_p): Call _mpz_impl_sqrt instead
+ of msqrt.
+
+ * mpz_impl_sqrt: Don't call "move", inline its functionality.
+
+ * mdiv: Use MPN_COPY instead of memcpy.
+ * rpow, mpz_mul, mpz_mod_2exp: Likewise.
+ * pow.c: Likewise, and fix bug in the size arg.
+
+ * xtom: Don't use mpz_alloc, inline needed code instead. Call
+ _mpz_set_str instead of mpz_set_str.
+
+ * Makefile: Make two libraries, libmp.a and libgmp.a.
+
+Thu May 22 20:25:29 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Add manual to distribution.
+ * Fold in many missing routines described in the manual.
+ * Update Makefile.
+
+Wed May 22 13:48:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_set_str: Make it handle 0x prefix OK.
+
+Sat May 18 18:31:02 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * memory.c (_mp_default_reallocate): Swap OLD_SIZE and NEW_SIZE
+ arguments.
+ * mpz_realloc (_mpz_realloc): Swap in call to _mp_reallocate_func.
+ * min: Likewise.
+
+Thu May 16 20:43:05 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * memory.c: Make the default allocations functions global.
+ * mp_set_fns (mp_set_memory_functions): Make a NULL pointer mean the
+ default memory function.
+
+Wed May 8 20:02:42 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_div: Handle DEN the same as QUOT correctly by copying DEN->D
+ even if no normalization is needed.
+ * mpz_div: Rework reallocation scheme, to avoid excess copying.
+
+ * mpz_sub_ui.c, mpz_add_ui.c: New files.
+
+ * mpz_cmp.c, mpz_cmp_ui.c: New files.
+
+ * mpz_mul_2exp: Handle zero input MINT correctly.
+
+ * mpn_rshiftci: Don't handle shift counts > BITS_PER_MP_DIGIT.
+
+ * mpz_out_raw.c, mpz_inp_raw.c: New files for raw I/O.
+
+Tue May 7 15:44:58 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_rshift: Don't handle shift counts > BITS_PER_MP_DIGIT.
+ * mpz_div_2exp: Don't call _mpn_rshift with cnt > BITS_PER_MP_DIGIT.
+ * gcd, mpz_gcd: Likewise.
+
+ * gcd, mpz_gcd: Handle common 2 factors correctly.
+
+Mon May 6 20:22:59 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp-impl.h (MPN_COPY): Inline a loop instead of calling memcpy.
+
+ * gmp-impl.h, mpz_get_str, rpow: Swap DST and SRC in TMPCOPY* macros.
+
+Sun May 5 15:16:23 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_div: Remove test for QUOT == 0.
+
+Sun Apr 28 20:21:04 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * pow: Don't make MOD normalization in place, as it's a bad idea to
+ write on an input parameter.
+ * pow: Reduce BASE if it's > MOD.
+ * pow, mult, mpz_mul: Simplify realloc code.
+
+Sat Apr 27 21:03:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Install multiplication using Karatsuba's algorithm as default.
+
+Fri Apr 26 01:03:57 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * msqrt: Store in ROOT even for U==0, to make msqrt(0) defined.
+
+ * mpz_div_2exp.c, mpz_mul_2exp.c: New files for shifting right and
+ left, respectively.
+ * gmp.h: Add definitions for mpz_div_2exp and mpz_mul_2exp.
+
+ * mlshift.c, mrshift.c: Remove.
+
+Wed Apr 24 21:39:22 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: Check only for m2_size == 0 in function header.
+
+Mon Apr 22 01:31:57 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * karatsuba.c: New file for Karatsuba's multiplication algorithm.
+
+ * mpz_random, mpz_init, mpz_mod_2exp: New files and functions.
+
+ * mpn_cmp: Fix header comment.
+
+Sun Apr 21 00:10:44 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * pow: Switch off initial base reduction.
+
+Sat Apr 20 22:06:05 1991 Torbjorn Granlund (tege@echnaton.sics.se)
+
+ * mpz_get_str: Don't generate initial zeros for initial word.
+ Used to write outside of allocated storage.
+
+Mon Apr 15 15:48:08 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_realloc: Make it accept size in number of mp_digits.
+ * Most functions: Use new _mpz_realloc definition.
+
+ * mpz_set_str: Remove calls _mp_free_func.
+
+ * Most functions: Rename mpn_* to _mpn_*. Rename mpz_realloc to
+ _mpz_realloc.
+ * mpn_lshift: Redefine _mpn_lshift to only handle small shifts.
+ * mdiv, mpz_div, ...: Changes for new definition of _mpn_lshift.
+ * msqrt, mp*_*shift*: Define cnt as unsigned (for speed).
+
+Sat Apr 6 14:05:16 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * mpn_mul: Multiply by the first digit in M2 in a special
+ loop instead of zeroing the product area.
+
+ * mpz_abs.c: New file.
+
+ * sdiv: Implement as mpz_div_si for speed.
+
+ * mpn_add: Make it work for second source operand == 0.
+
+ * msub: Negate the correct operand, i.e. V before swapping, not
+ the smaller of U and V!
+ * madd, msub: Update abs_* when swapping operands, and not after
+ (optimization).
+
+Fri Apr 5 00:19:36 1991 Torbjorn Granlund (tege@black.nada.kth.se)
+
+ * mpn_sub: Make it work for subtrahend == 0.
+
+ * madd, msub: Rewrite to minimize mpn_cmp calls. Ensure
+ mpn_cmp is called with positive sizes (used to be called
+ incorrectly with negative sizes sometimes).
+
+ * msqrt: Make it divide by zero if fed with a negative number.
+ * Remove if statement at end of precision calculation that was
+ never true.
+
+ * itom, mp.h: The argument is of type short, not int.
+
+ * mpz_realloc, gmp.h: Make mpz_realloc return the new digit pointer.
+
+ * mpz_get_str.c, mpz_set_str.c, mpz_new_str.c: Don't include mp.h.
+
+ * Add COPYING to distribution.
+
+ * mpz_div_ui.c, mpz_div_si.c, mpz_new_ui.c, mpz_new_si.c: New files.
+
+Fri Mar 15 00:26:29 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * Add Copyleft headers to all files.
+
+ * mpn_mul.c, mpn_div.c: Add header comments.
+ * mult.c, mdiv.c: Update header comments.
+
+ * mpq_add.c, mpq_sub.c, mpq_div.c, mpq_new.c, mpq_new_ui.c,
+ mpq_free.c: New files for rational arithmetics.
+
+ * mpn_lshift.c: Avoid writing the most significant word if it is 0.
+
+ * mdiv.c: Call mpn_lshift for the normalization.
+ * mdiv.c: Remove #ifdefs.
+
+ * Makefile: Add ChangeLog to DISTFILES.
+
+ * mpn_div.c: Make the add_back code work (by removing abort()).
+ * mpn_div.c: Make it return if the quotient is size as compared
+ with the difference NSIZE - DSIZE. If the stored quotient is
+ larger than that, return 1, otherwise 0.
+ * gmp.h: Fix mpn_div declaration.
+ * mdiv.c: Adopt call to mpn_div.
+ * mpz_div.c: New file (developed from mdiv.c).
+
+ * README: Update routine names.
+
+Thu Mar 14 18:45:28 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * mpq_mul.c: New file for rational multiplication.
+
+ * gmp.h: Add definitions for rational arithmetics.
+
+ * mpn_div: Kludge the case where the high numerator digit > the
+ high denominator digit. (This code is going to be optimized later.)
+
+ * New files: gmp.h for GNU specific functions, gmp-common.h for
+ definitions common for mp.h and gmp.h.
+
+ * Ensure mp.h just defines what BSD mp.h defines.
+
+ * pow.c: Fix typo for bp allocation.
+
+ * Rename natural number functions to mpn_*, integer functions to
+ mpz_*.
+
+Tue Mar 5 18:47:04 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * mdiv.c (_mp_divide, case 2): Change test for estimate of Q from
+ "n0 >= r" to "n0 > r".
+
+ * msqrt: Tune the increasing precision scheme, to do fewer steps.
+
+Tue Mar 3 18:50:10 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * msqrt: Use the low level routines. Use low precision in the
+ beginning, and increase the precision as the result converges.
+ (This optimization gave a 6-fold speedup.)
diff --git a/gmp/INSTALL b/gmp/INSTALL
new file mode 100644
index 0000000000..75199a1aba
--- /dev/null
+++ b/gmp/INSTALL
@@ -0,0 +1,80 @@
+Copyright 1996, 1997, 1999-2002, 2006 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ INSTALLING GNU MP
+ =================
+
+
+These instructions are only for the impatient. Others should read the install
+instructions in gmp.info. Use
+
+ info -f doc/gmp.info
+
+from the gmp source directory.
+
+Here are some brief instructions on how to install GMP. First you need to
+compile. Since you're impatient, try this
+
+ ./configure
+ make
+ make check <= VERY IMPORTANT!!
+
+If that fails, or you care about the performance of GMP, you need to read the
+full instructions in the chapter "Installing GMP" in the manual.
+
+You should not skip the "make check" part; the risk that the GMP sources are
+miscompiled are unfortunately quite high. And if they indeed are, "make check"
+is very likely to trigger the compiler-introduced bug.
+
+Optionally, you can install the library with the following command. This will
+be to /usr/local by default, and you'll probably need to be "root" to be able
+to write there.
+
+ make install
+
+To create the printable documentation from the texinfo source, type "make
+gmp.dvi" or "make gmp.ps". This requires various "tex" commands.
+
+If you are new to GMP, it is a good idea you at least read the chapter "GMP
+Basics" in the manual.
+
+Some known build problems are noted in the "Installing GMP" chapter of
+the manual. Please report other problems to gmp-bugs@gmplib.org.
+
+The GMP web site is located here: https://gmplib.org/.
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 78
+End:
diff --git a/gmp/INSTALL.autoconf b/gmp/INSTALL.autoconf
new file mode 100644
index 0000000000..0600b32390
--- /dev/null
+++ b/gmp/INSTALL.autoconf
@@ -0,0 +1,228 @@
+Copyright (C) 1994-1996, 1999-2002 Free Software Foundation, Inc.
+
+ This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/gmp/Makefile.am b/gmp/Makefile.am
new file mode 100644
index 0000000000..8567c0e3f6
--- /dev/null
+++ b/gmp/Makefile.am
@@ -0,0 +1,445 @@
+## Process this file with automake to generate Makefile.in
+
+
+# Copyright 1991, 1993, 1994, 1996, 1997, 1999-2004, 2006-2009, 2011-2014 Free
+# Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# The following options are the same as AM_INIT_AUTOMAKE in configure.in,
+# except no $(top_builddir) on ansi2knr. That directory is wanted for the
+# Makefiles in subdirectories, but here we must omit it so automake gives
+# the actual ansi2knr build rule, not "cd $(top_builddir) && make ansi2knr".
+#
+# AUTOMAKE_OPTIONS = 1.8 gnu no-dependencies
+
+
+# Libtool -version-info for libgmp.la and libmp.la. See "Versioning" in the
+# libtool manual.
+#
+# CURRENT:REVISION:AGE
+#
+# 1. No interfaces changed, only implementations (good): Increment REVISION.
+#
+# 2. Interfaces added, none removed (good): Increment CURRENT, increment
+# AGE, set REVISION to 0.
+#
+# 3. Interfaces removed (BAD, breaks upward compatibility): Increment
+# CURRENT, set AGE and REVISION to 0.
+#
+# Do this separately for libgmp, libgmpxx and libmp, and only for releases.
+#
+# GMP -version-info
+# release libgmp libgmpxx libmp
+# 2.0.x - - -
+# 3.0 3:0:0 - 3:0:0
+# 3.0.1 3:1:0 - 3:0:0
+# 3.1 4:0:1 - 4:0:1
+# 3.1.1 4:1:1 - 4:1:1
+# 4.0 5:0:2 3:0:0 4:2:1
+# 4.0.1 5:1:2 3:1:0 4:3:1
+# 4.1 6:0:3 3:2:0 4:4:1
+# 4.1.1 6:1:3 3:3:0 4:5:1
+# 4.1.2 6:2:3 3:4:0 4:6:1
+# 4.1.3 6:3:3 3:5:0 4:7:1
+# 4.1.4 6:3:3 3:5:0 4:7:1 WRONG, same as 4.1.3!
+# 4.2 6:0:3 3:2:0 4:4:1 REALLY WRONG, same as 4.1!
+# 4.2.1 7:1:4 4:1:1 4:10:1 WRONG for libgmpxx
+# 4.2.2 7:2:4 4:2:0 4:11:1
+# 4.2.3 7:3:4 4:3:0 4:12:1
+# 4.2.4 7:4:4 4:4:0 4:13:1
+# 4.3.0 8:0:5 5:0:1 4:14:1
+# 4.3.1 8:1:5 5:1:1 4:15:1 WRONG Really used same as 4.3.0
+# 4.3.2 8:2:5 5:2:1 4:16:1
+# 5.0.0 9:0:6 6:0:2 4:20:1 Should have been 10:0:0
+# 5.0.1 10:1:0 6:1:2 4:21:1
+# 5.0.2 10:2:0 6:2:2 4:22:1
+# 5.0.3 10:3:0 6:3:2 4:23:1
+# 5.0.4 10:4:0 6:4:2 4:24:1
+# 5.0.5 10:5:0 6:5:2 4:25:1
+# 5.1.0 11:0:1 7:0:3 -
+# 5.1.1 11:1:1 7:1:3 -
+# 5.1.2 11:2:1 7:2:3 -
+# 6.0.0 12:0:2 8:0:4 -
+#
+# Starting at 3:0:0 is a slight abuse of the versioning system, but it
+# ensures we're past soname libgmp.so.2, which was used on Debian GNU/Linux
+# packages of gmp 2. Pretend gmp 2 was 2:0:0, so the interface changes for
+# gmp 3 mean 3:0:0 is right.
+#
+# We interpret "implementation changed" in item "1." above as meaning any
+# release, ie. the REVISION is incremented every time (if nothing else).
+# Even if we thought the code generated will be identical on all systems,
+# it's still good to get the shared library filename (like
+# libgmpxx.so.3.0.4) incrementing, to make it clear which GMP it's from.
+
+LIBGMP_LT_CURRENT = 12
+LIBGMP_LT_REVISION = 0
+LIBGMP_LT_AGE = 2
+
+LIBGMPXX_LT_CURRENT = 8
+LIBGMPXX_LT_REVISION = 0
+LIBGMPXX_LT_AGE = 4
+
+
+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc
+
+EXTRA_DIST = configfsf.guess configfsf.sub .gdbinit INSTALL.autoconf \
+ COPYING.LESSERv3 COPYINGv2 COPYINGv3
+
+
+if WANT_CXX
+GMPXX_HEADERS_OPTION = gmpxx.h
+endif
+EXTRA_DIST += gmpxx.h
+
+# gmp.h and mp.h are architecture dependent, mainly since they encode the
+# limb size used in libgmp. For that reason they belong under $exec_prefix
+# not $prefix, strictly speaking.
+#
+# $exec_prefix/include is not in the default include path for gcc built to
+# the same $prefix and $exec_prefix, which might mean gmp.h is not found,
+# but anyone knowledgeable enough to be playing with exec_prefix will be able
+# to address that.
+#
+includeexecdir = $(exec_prefix)/include
+include_HEADERS = $(GMPXX_HEADERS_OPTION)
+nodist_includeexec_HEADERS = gmp.h
+lib_LTLIBRARIES = libgmp.la $(GMPXX_LTLIBRARIES_OPTION)
+
+BUILT_SOURCES = gmp.h
+
+DISTCLEANFILES = $(BUILT_SOURCES) config.m4 @gmp_srclinks@
+
+# Tell gmp.h it's building gmp, not an application, used by windows DLL stuff.
+INCLUDES=-D__GMP_WITHIN_GMP
+
+
+MPF_OBJECTS = mpf/init$U.lo mpf/init2$U.lo mpf/inits$U.lo mpf/set$U.lo \
+ mpf/set_ui$U.lo mpf/set_si$U.lo mpf/set_str$U.lo mpf/set_d$U.lo \
+ mpf/set_z$U.lo mpf/iset$U.lo mpf/iset_ui$U.lo mpf/iset_si$U.lo \
+ mpf/iset_str$U.lo mpf/iset_d$U.lo mpf/clear$U.lo mpf/clears$U.lo \
+ mpf/get_str$U.lo mpf/dump$U.lo mpf/size$U.lo mpf/eq$U.lo mpf/reldiff$U.lo \
+ mpf/sqrt$U.lo mpf/random2$U.lo mpf/inp_str$U.lo mpf/out_str$U.lo \
+ mpf/add$U.lo mpf/add_ui$U.lo mpf/sub$U.lo mpf/sub_ui$U.lo mpf/ui_sub$U.lo \
+ mpf/mul$U.lo mpf/mul_ui$U.lo mpf/div$U.lo mpf/div_ui$U.lo \
+ mpf/cmp$U.lo mpf/cmp_d$U.lo mpf/cmp_ui$U.lo mpf/cmp_si$U.lo \
+ mpf/mul_2exp$U.lo mpf/div_2exp$U.lo mpf/abs$U.lo mpf/neg$U.lo \
+ mpf/set_q$U.lo mpf/get_d$U.lo mpf/get_d_2exp$U.lo mpf/set_dfl_prec$U.lo \
+ mpf/set_prc$U.lo mpf/set_prc_raw$U.lo mpf/get_dfl_prec$U.lo \
+ mpf/get_prc$U.lo mpf/ui_div$U.lo mpf/sqrt_ui$U.lo \
+ mpf/ceilfloor$U.lo mpf/trunc$U.lo mpf/pow_ui$U.lo \
+ mpf/urandomb$U.lo mpf/swap$U.lo \
+ mpf/fits_sint$U.lo mpf/fits_slong$U.lo mpf/fits_sshort$U.lo \
+ mpf/fits_uint$U.lo mpf/fits_ulong$U.lo mpf/fits_ushort$U.lo \
+ mpf/get_si$U.lo mpf/get_ui$U.lo \
+ mpf/int_p$U.lo
+
+MPZ_OBJECTS = mpz/abs$U.lo mpz/add$U.lo mpz/add_ui$U.lo \
+ mpz/aorsmul$U.lo mpz/aorsmul_i$U.lo mpz/and$U.lo mpz/array_init$U.lo \
+ mpz/bin_ui$U.lo mpz/bin_uiui$U.lo \
+ mpz/cdiv_q$U.lo mpz/cdiv_q_ui$U.lo \
+ mpz/cdiv_qr$U.lo mpz/cdiv_qr_ui$U.lo \
+ mpz/cdiv_r$U.lo mpz/cdiv_r_ui$U.lo mpz/cdiv_ui$U.lo \
+ mpz/cfdiv_q_2exp$U.lo mpz/cfdiv_r_2exp$U.lo \
+ mpz/clear$U.lo mpz/clears$U.lo mpz/clrbit$U.lo \
+ mpz/cmp$U.lo mpz/cmp_d$U.lo mpz/cmp_si$U.lo mpz/cmp_ui$U.lo \
+ mpz/cmpabs$U.lo mpz/cmpabs_d$U.lo mpz/cmpabs_ui$U.lo \
+ mpz/com$U.lo mpz/combit$U.lo \
+ mpz/cong$U.lo mpz/cong_2exp$U.lo mpz/cong_ui$U.lo \
+ mpz/divexact$U.lo mpz/divegcd$U.lo mpz/dive_ui$U.lo \
+ mpz/divis$U.lo mpz/divis_ui$U.lo mpz/divis_2exp$U.lo mpz/dump$U.lo \
+ mpz/export$U.lo mpz/mfac_uiui$U.lo \
+ mpz/2fac_ui$U.lo mpz/fac_ui$U.lo mpz/oddfac_1$U.lo mpz/prodlimbs$U.lo \
+ mpz/fdiv_q_ui$U.lo mpz/fdiv_qr$U.lo mpz/fdiv_qr_ui$U.lo \
+ mpz/fdiv_r$U.lo mpz/fdiv_r_ui$U.lo mpz/fdiv_q$U.lo \
+ mpz/fdiv_ui$U.lo mpz/fib_ui$U.lo mpz/fib2_ui$U.lo mpz/fits_sint$U.lo \
+ mpz/fits_slong$U.lo mpz/fits_sshort$U.lo mpz/fits_uint$U.lo \
+ mpz/fits_ulong$U.lo mpz/fits_ushort$U.lo mpz/gcd$U.lo \
+ mpz/gcd_ui$U.lo mpz/gcdext$U.lo mpz/get_d$U.lo mpz/get_d_2exp$U.lo \
+ mpz/get_si$U.lo mpz/get_str$U.lo mpz/get_ui$U.lo mpz/getlimbn$U.lo \
+ mpz/hamdist$U.lo \
+ mpz/import$U.lo mpz/init$U.lo mpz/init2$U.lo mpz/inits$U.lo \
+ mpz/inp_raw$U.lo mpz/inp_str$U.lo mpz/invert$U.lo \
+ mpz/ior$U.lo mpz/iset$U.lo mpz/iset_d$U.lo mpz/iset_si$U.lo \
+ mpz/iset_str$U.lo mpz/iset_ui$U.lo mpz/jacobi$U.lo mpz/kronsz$U.lo \
+ mpz/kronuz$U.lo mpz/kronzs$U.lo mpz/kronzu$U.lo \
+ mpz/lcm$U.lo mpz/lcm_ui$U.lo mpz/limbs_finish$U.lo \
+ mpz/limbs_modify$U.lo mpz/limbs_read$U.lo mpz/limbs_write$U.lo \
+ mpz/lucnum_ui$U.lo mpz/lucnum2_ui$U.lo \
+ mpz/millerrabin$U.lo mpz/mod$U.lo mpz/mul$U.lo mpz/mul_2exp$U.lo \
+ mpz/mul_si$U.lo mpz/mul_ui$U.lo \
+ mpz/n_pow_ui$U.lo mpz/neg$U.lo mpz/nextprime$U.lo \
+ mpz/out_raw$U.lo mpz/out_str$U.lo mpz/perfpow$U.lo mpz/perfsqr$U.lo \
+ mpz/popcount$U.lo mpz/pow_ui$U.lo mpz/powm$U.lo mpz/powm_sec$U.lo \
+ mpz/powm_ui$U.lo mpz/primorial_ui$U.lo \
+ mpz/pprime_p$U.lo mpz/random$U.lo mpz/random2$U.lo \
+ mpz/realloc$U.lo mpz/realloc2$U.lo mpz/remove$U.lo mpz/roinit_n$U.lo \
+ mpz/root$U.lo mpz/rootrem$U.lo mpz/rrandomb$U.lo mpz/scan0$U.lo \
+ mpz/scan1$U.lo mpz/set$U.lo mpz/set_d$U.lo mpz/set_f$U.lo \
+ mpz/set_q$U.lo mpz/set_si$U.lo mpz/set_str$U.lo mpz/set_ui$U.lo \
+ mpz/setbit$U.lo \
+ mpz/size$U.lo mpz/sizeinbase$U.lo mpz/sqrt$U.lo \
+ mpz/sqrtrem$U.lo mpz/sub$U.lo mpz/sub_ui$U.lo mpz/swap$U.lo \
+ mpz/tdiv_ui$U.lo mpz/tdiv_q$U.lo mpz/tdiv_q_2exp$U.lo \
+ mpz/tdiv_q_ui$U.lo mpz/tdiv_qr$U.lo mpz/tdiv_qr_ui$U.lo \
+ mpz/tdiv_r$U.lo mpz/tdiv_r_2exp$U.lo mpz/tdiv_r_ui$U.lo \
+ mpz/tstbit$U.lo mpz/ui_pow_ui$U.lo mpz/ui_sub$U.lo mpz/urandomb$U.lo \
+ mpz/urandomm$U.lo mpz/xor$U.lo
+
+MPQ_OBJECTS = mpq/abs$U.lo mpq/aors$U.lo \
+ mpq/canonicalize$U.lo mpq/clear$U.lo mpq/clears$U.lo \
+ mpq/cmp$U.lo mpq/cmp_si$U.lo mpq/cmp_ui$U.lo mpq/div$U.lo \
+ mpq/get_d$U.lo mpq/get_den$U.lo mpq/get_num$U.lo mpq/get_str$U.lo \
+ mpq/init$U.lo mpq/inits$U.lo mpq/inp_str$U.lo mpq/inv$U.lo \
+ mpq/md_2exp$U.lo mpq/mul$U.lo mpq/neg$U.lo mpq/out_str$U.lo \
+ mpq/set$U.lo mpq/set_den$U.lo mpq/set_num$U.lo \
+ mpq/set_si$U.lo mpq/set_str$U.lo mpq/set_ui$U.lo \
+ mpq/equal$U.lo mpq/set_z$U.lo mpq/set_d$U.lo \
+ mpq/set_f$U.lo mpq/swap$U.lo
+
+MPN_OBJECTS = mpn/fib_table$U.lo mpn/mp_bases$U.lo
+
+PRINTF_OBJECTS = \
+ printf/asprintf$U.lo printf/asprntffuns$U.lo \
+ printf/doprnt$U.lo printf/doprntf$U.lo printf/doprnti$U.lo \
+ printf/fprintf$U.lo \
+ printf/obprintf$U.lo printf/obvprintf$U.lo printf/obprntffuns$U.lo \
+ printf/printf$U.lo printf/printffuns$U.lo \
+ printf/snprintf$U.lo printf/snprntffuns$U.lo \
+ printf/sprintf$U.lo printf/sprintffuns$U.lo \
+ printf/vasprintf$U.lo printf/vfprintf$U.lo printf/vprintf$U.lo \
+ printf/vsnprintf$U.lo printf/vsprintf$U.lo \
+ printf/repl-vsnprintf$U.lo
+
+SCANF_OBJECTS = \
+ scanf/doscan$U.lo scanf/fscanf$U.lo scanf/fscanffuns$U.lo \
+ scanf/scanf$U.lo scanf/sscanf$U.lo scanf/sscanffuns$U.lo \
+ scanf/vfscanf$U.lo scanf/vscanf$U.lo scanf/vsscanf$U.lo
+
+RANDOM_OBJECTS = \
+ rand/rand$U.lo rand/randclr$U.lo rand/randdef$U.lo rand/randiset$U.lo \
+ rand/randlc2s$U.lo rand/randlc2x$U.lo rand/randmt$U.lo \
+ rand/randmts$U.lo rand/rands$U.lo rand/randsd$U.lo rand/randsdui$U.lo \
+ rand/randbui$U.lo rand/randmui$U.lo
+
+# no $U for C++ files
+CXX_OBJECTS = \
+ cxx/isfuns.lo cxx/ismpf.lo cxx/ismpq.lo cxx/ismpz.lo cxx/ismpznw.lo \
+ cxx/limits.lo cxx/osdoprnti.lo cxx/osfuns.lo \
+ cxx/osmpf.lo cxx/osmpq.lo cxx/osmpz.lo
+
+# In libtool 1.5 it doesn't work to build libgmp.la from the convenience
+# libraries like mpz/libmpz.la. Or rather it works, but it ends up putting
+# PIC objects into libgmp.a if shared and static are both built. (The PIC
+# objects go into mpz/.libs/libmpz.a, and thence into .libs/libgmp.a.)
+#
+# For now the big lists of objects above are used. Something like mpz/*.lo
+# would probably work, but might risk missing something out or getting
+# something extra. The source files for each .lo are listed in the
+# Makefile.am's in the subdirectories.
+#
+# Currently, for libgmp, unlike libmp below, we're not using
+# -export-symbols, since the tune and speed programs, and perhaps some of
+# the test programs, want to access undocumented symbols.
+
+libgmp_la_SOURCES = gmp-impl.h longlong.h \
+ assert.c compat.c errno.c extract-dbl.c invalid.c memory.c \
+ mp_bpl.c mp_clz_tab.c mp_dv_tab.c mp_minv_tab.c mp_get_fns.c mp_set_fns.c \
+ version.c nextprime.c primesieve.c
+EXTRA_libgmp_la_SOURCES = tal-debug.c tal-notreent.c tal-reent.c
+libgmp_la_DEPENDENCIES = @TAL_OBJECT@ \
+ $(MPF_OBJECTS) $(MPZ_OBJECTS) $(MPQ_OBJECTS) \
+ $(MPN_OBJECTS) @mpn_objs_in_libgmp@ \
+ $(PRINTF_OBJECTS) $(SCANF_OBJECTS) $(RANDOM_OBJECTS)
+libgmp_la_LIBADD = $(libgmp_la_DEPENDENCIES)
+libgmp_la_LDFLAGS = $(GMP_LDFLAGS) $(LIBGMP_LDFLAGS) \
+ -version-info $(LIBGMP_LT_CURRENT):$(LIBGMP_LT_REVISION):$(LIBGMP_LT_AGE)
+
+
+# We need at least one .cc file in $(libgmpxx_la_SOURCES) so automake will
+# use $(CXXLINK) rather than the plain C $(LINK). cxx/dummy.cc is that
+# file.
+
+if WANT_CXX
+GMPXX_LTLIBRARIES_OPTION = libgmpxx.la
+endif
+libgmpxx_la_SOURCES = cxx/dummy.cc
+libgmpxx_la_DEPENDENCIES = $(CXX_OBJECTS) libgmp.la
+libgmpxx_la_LIBADD = $(libgmpxx_la_DEPENDENCIES)
+libgmpxx_la_LDFLAGS = $(GMP_LDFLAGS) $(LIBGMPXX_LDFLAGS) \
+ -version-info $(LIBGMPXX_LT_CURRENT):$(LIBGMPXX_LT_REVISION):$(LIBGMPXX_LT_AGE)
+
+
+
+install-data-hook:
+ @echo ''
+ @echo '+-------------------------------------------------------------+'
+ @echo '| CAUTION: |'
+ @echo '| |'
+ @echo '| If you have not already run "make check", then we strongly |'
+ @echo '| recommend you do so. |'
+ @echo '| |'
+ @echo '| GMP has been carefully tested by its authors, but compilers |'
+ @echo '| are all too often released with serious bugs. GMP tends to |'
+ @echo '| explore interesting corners in compilers and has hit bugs |'
+ @echo '| on quite a few occasions. |'
+ @echo '| |'
+ @echo '+-------------------------------------------------------------+'
+ @echo ''
+
+
+# The "test -f" support for srcdir!=builddir is similar to the automake .c.o
+# etc rules, but with each foo.c explicitly, since $< is not portable
+# outside an inference rule.
+#
+# A quoted 'foo.c' is used with the "test -f"'s to avoid Sun make rewriting
+# it as part of its VPATH support. See the autoconf manual "Limitations of
+# Make".
+#
+# Generated .h files which are used by gmp-impl.h are BUILT_SOURCES since
+# they must exist before anything can be compiled.
+#
+# Other generated .h files are also BUILT_SOURCES so as to get all the
+# build-system stuff over and done with at the start. Also, dependencies on
+# the .h files are not properly expressed for the various objects that use
+# them.
+
+EXTRA_DIST += bootstrap.c
+
+fac_table.h: gen-fac$(EXEEXT_FOR_BUILD)
+ ./gen-fac $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >fac_table.h || (rm -f fac_table.h; exit 1)
+BUILT_SOURCES += fac_table.h
+
+gen-fac$(EXEEXT_FOR_BUILD): gen-fac$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-fac$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-fac$(U_FOR_BUILD).c -o gen-fac$(EXEEXT_FOR_BUILD)
+DISTCLEANFILES += gen-fac$(EXEEXT_FOR_BUILD)
+EXTRA_DIST += gen-fac.c
+
+
+fib_table.h: gen-fib$(EXEEXT_FOR_BUILD)
+ ./gen-fib header $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >fib_table.h || (rm -f fib_table.h; exit 1)
+BUILT_SOURCES += fib_table.h
+
+mpn/fib_table.c: gen-fib$(EXEEXT_FOR_BUILD)
+ ./gen-fib table $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >mpn/fib_table.c || (rm -f mpn/fib_table.c; exit 1)
+BUILT_SOURCES += mpn/fib_table.c
+
+gen-fib$(EXEEXT_FOR_BUILD): gen-fib$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-fib$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-fib$(U_FOR_BUILD).c -o gen-fib$(EXEEXT_FOR_BUILD)
+DISTCLEANFILES += gen-fib$(EXEEXT_FOR_BUILD)
+EXTRA_DIST += gen-fib.c
+
+
+mp_bases.h: gen-bases$(EXEEXT_FOR_BUILD)
+ ./gen-bases header $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >mp_bases.h || (rm -f mp_bases.h; exit 1)
+BUILT_SOURCES += mp_bases.h
+
+mpn/mp_bases.c: gen-bases$(EXEEXT_FOR_BUILD)
+ ./gen-bases table $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >mpn/mp_bases.c || (rm -f mpn/mp_bases.c; exit 1)
+BUILT_SOURCES += mpn/mp_bases.c
+
+gen-bases$(EXEEXT_FOR_BUILD): gen-bases$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-bases$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-bases$(U_FOR_BUILD).c -o gen-bases$(EXEEXT_FOR_BUILD) $(LIBM_FOR_BUILD)
+DISTCLEANFILES += gen-bases$(EXEEXT_FOR_BUILD)
+EXTRA_DIST += gen-bases.c
+
+
+trialdivtab.h: gen-trialdivtab$(EXEEXT_FOR_BUILD)
+ ./gen-trialdivtab $(GMP_LIMB_BITS) 8000 >trialdivtab.h || (rm -f trialdivtab.h; exit 1)
+BUILT_SOURCES += trialdivtab.h
+
+gen-trialdivtab$(EXEEXT_FOR_BUILD): gen-trialdivtab$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-trialdivtab$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-trialdivtab$(U_FOR_BUILD).c -o gen-trialdivtab$(EXEEXT_FOR_BUILD) $(LIBM_FOR_BUILD)
+DISTCLEANFILES += gen-trialdivtab$(EXEEXT_FOR_BUILD)
+EXTRA_DIST += gen-trialdivtab.c
+
+
+mpn/jacobitab.h: gen-jacobitab$(EXEEXT_FOR_BUILD)
+ ./gen-jacobitab >mpn/jacobitab.h || (rm -f mpn/jacobitab.h; exit 1)
+BUILT_SOURCES += mpn/jacobitab.h
+
+gen-jacobitab$(EXEEXT_FOR_BUILD): gen-jacobitab$(U_FOR_BUILD).c
+ $(CC_FOR_BUILD) `test -f 'gen-jacobitab$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-jacobitab$(U_FOR_BUILD).c -o gen-jacobitab$(EXEEXT_FOR_BUILD)
+DISTCLEANFILES += gen-jacobitab$(EXEEXT_FOR_BUILD)
+EXTRA_DIST += gen-jacobitab.c
+
+
+mpn/perfsqr.h: gen-psqr$(EXEEXT_FOR_BUILD)
+ ./gen-psqr $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >mpn/perfsqr.h || (rm -f mpn/perfsqr.h; exit 1)
+BUILT_SOURCES += mpn/perfsqr.h
+
+gen-psqr$(EXEEXT_FOR_BUILD): gen-psqr$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-psqr$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-psqr$(U_FOR_BUILD).c -o gen-psqr$(EXEEXT_FOR_BUILD) $(LIBM_FOR_BUILD)
+DISTCLEANFILES += gen-psqr$(EXEEXT_FOR_BUILD)
+EXTRA_DIST += gen-psqr.c
+
+# Distribute mini-gmp. Test sources copied by dist-hook.
+EXTRA_DIST += mini-gmp/README mini-gmp/mini-gmp.c mini-gmp/mini-gmp.h \
+ mini-gmp/tests/Makefile mini-gmp/tests/run-tests
+
+# Avoid: CVS - cvs directories
+# *~ - emacs backups
+# .#* - cvs merge originals
+#
+# *~ and .#* only occur when a whole directory without it's own Makefile.am
+# is distributed, like "doc" or the mpn cpu subdirectories.
+#
+dist-hook:
+ -find $(distdir) \( -name CVS -type d \) -o -name "*~" -o -name ".#*" \
+ | xargs rm -rf
+ cp "$(srcdir)"/mini-gmp/tests/*.[ch] "$(distdir)/mini-gmp/tests"
+# grep -F $(VERSION) $(srcdir)/Makefile.am \
+# | grep -q "^# *$(VERSION) *$(LIBGMP_LT_CURRENT):$(LIBGMP_LT_REVISION):$(LIBGMP_LT_AGE) *$(LIBGMPXX_LT_CURRENT):$(LIBGMPXX_LT_REVISION):$(LIBGMPXX_LT_AGE)"
+# test -z "`sed -n 's/^# *[0-9]*\.[0-9]*\.[0-9]* *\([0-9]*:[0-9]*:[0-9]*\) *\([0-9]*:[0-9]*:[0-9]*\) *\([0-9]*:[0-9]*:[0-9]*\).*/A\1\nB\2\nC\3/p' $(srcdir)/Makefile.am | grep -v 'A6:3:3\|B3:5:0\|C4:7:1' | sort | uniq -d`"
+
+.PHONY: check-mini-gmp clean-mini-gmp
+
+check-mini-gmp:
+ abs_srcdir="`cd $(srcdir) && pwd`" ; \
+ $(MKDIR_P) mini-gmp/tests \
+ && cd mini-gmp/tests \
+ && LD_LIBRARY_PATH="../../.libs:$$LD_LIBRARY_PATH" \
+ DYLD_LIBRARY_PATH="../../.libs:$$DYLD_LIBRARY_PATH" \
+ $(MAKE) -f "$$abs_srcdir/mini-gmp/tests/Makefile" \
+ VPATH="$$abs_srcdir/mini-gmp/tests" \
+ srcdir="$$abs_srcdir/mini-gmp/tests" \
+ MINI_GMP_DIR="$$abs_srcdir/mini-gmp" \
+ LDFLAGS="-L../../.libs" \
+ LIBS="-lgmp -lm" \
+ CC="$(CC_FOR_BUILD)" EXTRA_CFLAGS="-g -I../.." check
+
+clean-mini-gmp:
+ if [ -d mini-gmp/tests ] ; then \
+ abs_srcdir="`cd $(srcdir) && pwd`" ; \
+ cd mini-gmp/tests \
+ && $(MAKE) -f "$$abs_srcdir/mini-gmp/tests/Makefile" clean ; \
+ fi
+
+clean-local: clean-mini-gmp
+distclean-local: clean-mini-gmp
diff --git a/gmp/Makefile.in b/gmp/Makefile.in
new file mode 100644
index 0000000000..122305d624
--- /dev/null
+++ b/gmp/Makefile.in
@@ -0,0 +1,1412 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 1991, 1993, 1994, 1996, 1997, 1999-2004, 2006-2009, 2011-2014 Free
+# Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+# The following options are the same as AM_INIT_AUTOMAKE in configure.in,
+# except no $(top_builddir) on ansi2knr. That directory is wanted for the
+# Makefiles in subdirectories, but here we must omit it so automake gives
+# the actual ansi2knr build rule, not "cd $(top_builddir) && make ansi2knr".
+#
+# AUTOMAKE_OPTIONS = 1.8 gnu no-dependencies
+
+# Libtool -version-info for libgmp.la and libmp.la. See "Versioning" in the
+# libtool manual.
+#
+# CURRENT:REVISION:AGE
+#
+# 1. No interfaces changed, only implementations (good): Increment REVISION.
+#
+# 2. Interfaces added, none removed (good): Increment CURRENT, increment
+# AGE, set REVISION to 0.
+#
+# 3. Interfaces removed (BAD, breaks upward compatibility): Increment
+# CURRENT, set AGE and REVISION to 0.
+#
+# Do this separately for libgmp, libgmpxx and libmp, and only for releases.
+#
+# GMP -version-info
+# release libgmp libgmpxx libmp
+# 2.0.x - - -
+# 3.0 3:0:0 - 3:0:0
+# 3.0.1 3:1:0 - 3:0:0
+# 3.1 4:0:1 - 4:0:1
+# 3.1.1 4:1:1 - 4:1:1
+# 4.0 5:0:2 3:0:0 4:2:1
+# 4.0.1 5:1:2 3:1:0 4:3:1
+# 4.1 6:0:3 3:2:0 4:4:1
+# 4.1.1 6:1:3 3:3:0 4:5:1
+# 4.1.2 6:2:3 3:4:0 4:6:1
+# 4.1.3 6:3:3 3:5:0 4:7:1
+# 4.1.4 6:3:3 3:5:0 4:7:1 WRONG, same as 4.1.3!
+# 4.2 6:0:3 3:2:0 4:4:1 REALLY WRONG, same as 4.1!
+# 4.2.1 7:1:4 4:1:1 4:10:1 WRONG for libgmpxx
+# 4.2.2 7:2:4 4:2:0 4:11:1
+# 4.2.3 7:3:4 4:3:0 4:12:1
+# 4.2.4 7:4:4 4:4:0 4:13:1
+# 4.3.0 8:0:5 5:0:1 4:14:1
+# 4.3.1 8:1:5 5:1:1 4:15:1 WRONG Really used same as 4.3.0
+# 4.3.2 8:2:5 5:2:1 4:16:1
+# 5.0.0 9:0:6 6:0:2 4:20:1 Should have been 10:0:0
+# 5.0.1 10:1:0 6:1:2 4:21:1
+# 5.0.2 10:2:0 6:2:2 4:22:1
+# 5.0.3 10:3:0 6:3:2 4:23:1
+# 5.0.4 10:4:0 6:4:2 4:24:1
+# 5.0.5 10:5:0 6:5:2 4:25:1
+# 5.1.0 11:0:1 7:0:3 -
+# 5.1.1 11:1:1 7:1:3 -
+# 5.1.2 11:2:1 7:2:3 -
+# 6.0.0 12:0:2 8:0:4 -
+#
+# Starting at 3:0:0 is a slight abuse of the versioning system, but it
+# ensures we're past soname libgmp.so.2, which was used on Debian GNU/Linux
+# packages of gmp 2. Pretend gmp 2 was 2:0:0, so the interface changes for
+# gmp 3 mean 3:0:0 is right.
+#
+# We interpret "implementation changed" in item "1." above as meaning any
+# release, ie. the REVISION is incremented every time (if nothing else).
+# Even if we thought the code generated will be identical on all systems,
+# it's still good to get the shared library filename (like
+# libgmpxx.so.3.0.4) incrementing, to make it clear which GMP it's from.
+
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(am__include_HEADERS_DIST) \
+ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/config.in $(srcdir)/gmp-h.in $(top_srcdir)/configure \
+ AUTHORS COPYING ChangeLog INSTALL NEWS config.guess config.sub \
+ install-sh ltmain.sh missing ylwrap
+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)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = gmp.h gmp-mparam.h
+CONFIG_CLEAN_VPATH_FILES =
+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__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" \
+ "$(DESTDIR)$(includeexecdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 = $(MPF_OBJECTS) $(MPZ_OBJECTS) $(MPQ_OBJECTS) \
+ $(MPN_OBJECTS) $(PRINTF_OBJECTS) $(SCANF_OBJECTS) \
+ $(RANDOM_OBJECTS)
+am_libgmp_la_OBJECTS = assert.lo compat.lo errno.lo extract-dbl.lo \
+ invalid.lo memory.lo mp_bpl.lo mp_clz_tab.lo mp_dv_tab.lo \
+ mp_minv_tab.lo mp_get_fns.lo mp_set_fns.lo version.lo \
+ nextprime.lo primesieve.lo
+libgmp_la_OBJECTS = $(am_libgmp_la_OBJECTS)
+libgmp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libgmp_la_LDFLAGS) $(LDFLAGS) -o $@
+am_libgmpxx_la_OBJECTS = dummy.lo
+libgmpxx_la_OBJECTS = $(am_libgmpxx_la_OBJECTS)
+libgmpxx_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(libgmpxx_la_LDFLAGS) $(LDFLAGS) -o $@
+@WANT_CXX_TRUE@am_libgmpxx_la_rpath = -rpath $(libdir)
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp =
+am__depfiles_maybe =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libgmp_la_SOURCES) $(EXTRA_libgmp_la_SOURCES) \
+ $(libgmpxx_la_SOURCES)
+DIST_SOURCES = $(libgmp_la_SOURCES) $(EXTRA_libgmp_la_SOURCES) \
+ $(libgmpxx_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__include_HEADERS_DIST = gmpxx.h
+HEADERS = $(include_HEADERS) $(nodist_includeexec_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+LIBGMP_LT_CURRENT = 12
+LIBGMP_LT_REVISION = 0
+LIBGMP_LT_AGE = 2
+LIBGMPXX_LT_CURRENT = 8
+LIBGMPXX_LT_REVISION = 0
+LIBGMPXX_LT_AGE = 4
+SUBDIRS = tests mpn mpz mpq mpf printf scanf rand cxx demos tune doc
+
+# The "test -f" support for srcdir!=builddir is similar to the automake .c.o
+# etc rules, but with each foo.c explicitly, since $< is not portable
+# outside an inference rule.
+#
+# A quoted 'foo.c' is used with the "test -f"'s to avoid Sun make rewriting
+# it as part of its VPATH support. See the autoconf manual "Limitations of
+# Make".
+#
+# Generated .h files which are used by gmp-impl.h are BUILT_SOURCES since
+# they must exist before anything can be compiled.
+#
+# Other generated .h files are also BUILT_SOURCES so as to get all the
+# build-system stuff over and done with at the start. Also, dependencies on
+# the .h files are not properly expressed for the various objects that use
+# them.
+
+# Distribute mini-gmp. Test sources copied by dist-hook.
+EXTRA_DIST = configfsf.guess configfsf.sub .gdbinit INSTALL.autoconf \
+ COPYING.LESSERv3 COPYINGv2 COPYINGv3 gmpxx.h bootstrap.c \
+ gen-fac.c gen-fib.c gen-bases.c gen-trialdivtab.c \
+ gen-jacobitab.c gen-psqr.c mini-gmp/README mini-gmp/mini-gmp.c \
+ mini-gmp/mini-gmp.h mini-gmp/tests/Makefile \
+ mini-gmp/tests/run-tests
+@WANT_CXX_TRUE@GMPXX_HEADERS_OPTION = gmpxx.h
+
+# gmp.h and mp.h are architecture dependent, mainly since they encode the
+# limb size used in libgmp. For that reason they belong under $exec_prefix
+# not $prefix, strictly speaking.
+#
+# $exec_prefix/include is not in the default include path for gcc built to
+# the same $prefix and $exec_prefix, which might mean gmp.h is not found,
+# but anyone knowledgeable enough to be playing with exec_prefix will be able
+# to address that.
+#
+includeexecdir = $(exec_prefix)/include
+include_HEADERS = $(GMPXX_HEADERS_OPTION)
+nodist_includeexec_HEADERS = gmp.h
+lib_LTLIBRARIES = libgmp.la $(GMPXX_LTLIBRARIES_OPTION)
+BUILT_SOURCES = gmp.h fac_table.h fib_table.h mpn/fib_table.c \
+ mp_bases.h mpn/mp_bases.c trialdivtab.h mpn/jacobitab.h \
+ mpn/perfsqr.h
+DISTCLEANFILES = $(BUILT_SOURCES) config.m4 @gmp_srclinks@ \
+ gen-fac$(EXEEXT_FOR_BUILD) gen-fib$(EXEEXT_FOR_BUILD) \
+ gen-bases$(EXEEXT_FOR_BUILD) \
+ gen-trialdivtab$(EXEEXT_FOR_BUILD) \
+ gen-jacobitab$(EXEEXT_FOR_BUILD) gen-psqr$(EXEEXT_FOR_BUILD)
+
+# Tell gmp.h it's building gmp, not an application, used by windows DLL stuff.
+INCLUDES = -D__GMP_WITHIN_GMP
+MPF_OBJECTS = mpf/init$U.lo mpf/init2$U.lo mpf/inits$U.lo mpf/set$U.lo \
+ mpf/set_ui$U.lo mpf/set_si$U.lo mpf/set_str$U.lo mpf/set_d$U.lo \
+ mpf/set_z$U.lo mpf/iset$U.lo mpf/iset_ui$U.lo mpf/iset_si$U.lo \
+ mpf/iset_str$U.lo mpf/iset_d$U.lo mpf/clear$U.lo mpf/clears$U.lo \
+ mpf/get_str$U.lo mpf/dump$U.lo mpf/size$U.lo mpf/eq$U.lo mpf/reldiff$U.lo \
+ mpf/sqrt$U.lo mpf/random2$U.lo mpf/inp_str$U.lo mpf/out_str$U.lo \
+ mpf/add$U.lo mpf/add_ui$U.lo mpf/sub$U.lo mpf/sub_ui$U.lo mpf/ui_sub$U.lo \
+ mpf/mul$U.lo mpf/mul_ui$U.lo mpf/div$U.lo mpf/div_ui$U.lo \
+ mpf/cmp$U.lo mpf/cmp_d$U.lo mpf/cmp_ui$U.lo mpf/cmp_si$U.lo \
+ mpf/mul_2exp$U.lo mpf/div_2exp$U.lo mpf/abs$U.lo mpf/neg$U.lo \
+ mpf/set_q$U.lo mpf/get_d$U.lo mpf/get_d_2exp$U.lo mpf/set_dfl_prec$U.lo \
+ mpf/set_prc$U.lo mpf/set_prc_raw$U.lo mpf/get_dfl_prec$U.lo \
+ mpf/get_prc$U.lo mpf/ui_div$U.lo mpf/sqrt_ui$U.lo \
+ mpf/ceilfloor$U.lo mpf/trunc$U.lo mpf/pow_ui$U.lo \
+ mpf/urandomb$U.lo mpf/swap$U.lo \
+ mpf/fits_sint$U.lo mpf/fits_slong$U.lo mpf/fits_sshort$U.lo \
+ mpf/fits_uint$U.lo mpf/fits_ulong$U.lo mpf/fits_ushort$U.lo \
+ mpf/get_si$U.lo mpf/get_ui$U.lo \
+ mpf/int_p$U.lo
+
+MPZ_OBJECTS = mpz/abs$U.lo mpz/add$U.lo mpz/add_ui$U.lo \
+ mpz/aorsmul$U.lo mpz/aorsmul_i$U.lo mpz/and$U.lo mpz/array_init$U.lo \
+ mpz/bin_ui$U.lo mpz/bin_uiui$U.lo \
+ mpz/cdiv_q$U.lo mpz/cdiv_q_ui$U.lo \
+ mpz/cdiv_qr$U.lo mpz/cdiv_qr_ui$U.lo \
+ mpz/cdiv_r$U.lo mpz/cdiv_r_ui$U.lo mpz/cdiv_ui$U.lo \
+ mpz/cfdiv_q_2exp$U.lo mpz/cfdiv_r_2exp$U.lo \
+ mpz/clear$U.lo mpz/clears$U.lo mpz/clrbit$U.lo \
+ mpz/cmp$U.lo mpz/cmp_d$U.lo mpz/cmp_si$U.lo mpz/cmp_ui$U.lo \
+ mpz/cmpabs$U.lo mpz/cmpabs_d$U.lo mpz/cmpabs_ui$U.lo \
+ mpz/com$U.lo mpz/combit$U.lo \
+ mpz/cong$U.lo mpz/cong_2exp$U.lo mpz/cong_ui$U.lo \
+ mpz/divexact$U.lo mpz/divegcd$U.lo mpz/dive_ui$U.lo \
+ mpz/divis$U.lo mpz/divis_ui$U.lo mpz/divis_2exp$U.lo mpz/dump$U.lo \
+ mpz/export$U.lo mpz/mfac_uiui$U.lo \
+ mpz/2fac_ui$U.lo mpz/fac_ui$U.lo mpz/oddfac_1$U.lo mpz/prodlimbs$U.lo \
+ mpz/fdiv_q_ui$U.lo mpz/fdiv_qr$U.lo mpz/fdiv_qr_ui$U.lo \
+ mpz/fdiv_r$U.lo mpz/fdiv_r_ui$U.lo mpz/fdiv_q$U.lo \
+ mpz/fdiv_ui$U.lo mpz/fib_ui$U.lo mpz/fib2_ui$U.lo mpz/fits_sint$U.lo \
+ mpz/fits_slong$U.lo mpz/fits_sshort$U.lo mpz/fits_uint$U.lo \
+ mpz/fits_ulong$U.lo mpz/fits_ushort$U.lo mpz/gcd$U.lo \
+ mpz/gcd_ui$U.lo mpz/gcdext$U.lo mpz/get_d$U.lo mpz/get_d_2exp$U.lo \
+ mpz/get_si$U.lo mpz/get_str$U.lo mpz/get_ui$U.lo mpz/getlimbn$U.lo \
+ mpz/hamdist$U.lo \
+ mpz/import$U.lo mpz/init$U.lo mpz/init2$U.lo mpz/inits$U.lo \
+ mpz/inp_raw$U.lo mpz/inp_str$U.lo mpz/invert$U.lo \
+ mpz/ior$U.lo mpz/iset$U.lo mpz/iset_d$U.lo mpz/iset_si$U.lo \
+ mpz/iset_str$U.lo mpz/iset_ui$U.lo mpz/jacobi$U.lo mpz/kronsz$U.lo \
+ mpz/kronuz$U.lo mpz/kronzs$U.lo mpz/kronzu$U.lo \
+ mpz/lcm$U.lo mpz/lcm_ui$U.lo mpz/limbs_finish$U.lo \
+ mpz/limbs_modify$U.lo mpz/limbs_read$U.lo mpz/limbs_write$U.lo \
+ mpz/lucnum_ui$U.lo mpz/lucnum2_ui$U.lo \
+ mpz/millerrabin$U.lo mpz/mod$U.lo mpz/mul$U.lo mpz/mul_2exp$U.lo \
+ mpz/mul_si$U.lo mpz/mul_ui$U.lo \
+ mpz/n_pow_ui$U.lo mpz/neg$U.lo mpz/nextprime$U.lo \
+ mpz/out_raw$U.lo mpz/out_str$U.lo mpz/perfpow$U.lo mpz/perfsqr$U.lo \
+ mpz/popcount$U.lo mpz/pow_ui$U.lo mpz/powm$U.lo mpz/powm_sec$U.lo \
+ mpz/powm_ui$U.lo mpz/primorial_ui$U.lo \
+ mpz/pprime_p$U.lo mpz/random$U.lo mpz/random2$U.lo \
+ mpz/realloc$U.lo mpz/realloc2$U.lo mpz/remove$U.lo mpz/roinit_n$U.lo \
+ mpz/root$U.lo mpz/rootrem$U.lo mpz/rrandomb$U.lo mpz/scan0$U.lo \
+ mpz/scan1$U.lo mpz/set$U.lo mpz/set_d$U.lo mpz/set_f$U.lo \
+ mpz/set_q$U.lo mpz/set_si$U.lo mpz/set_str$U.lo mpz/set_ui$U.lo \
+ mpz/setbit$U.lo \
+ mpz/size$U.lo mpz/sizeinbase$U.lo mpz/sqrt$U.lo \
+ mpz/sqrtrem$U.lo mpz/sub$U.lo mpz/sub_ui$U.lo mpz/swap$U.lo \
+ mpz/tdiv_ui$U.lo mpz/tdiv_q$U.lo mpz/tdiv_q_2exp$U.lo \
+ mpz/tdiv_q_ui$U.lo mpz/tdiv_qr$U.lo mpz/tdiv_qr_ui$U.lo \
+ mpz/tdiv_r$U.lo mpz/tdiv_r_2exp$U.lo mpz/tdiv_r_ui$U.lo \
+ mpz/tstbit$U.lo mpz/ui_pow_ui$U.lo mpz/ui_sub$U.lo mpz/urandomb$U.lo \
+ mpz/urandomm$U.lo mpz/xor$U.lo
+
+MPQ_OBJECTS = mpq/abs$U.lo mpq/aors$U.lo \
+ mpq/canonicalize$U.lo mpq/clear$U.lo mpq/clears$U.lo \
+ mpq/cmp$U.lo mpq/cmp_si$U.lo mpq/cmp_ui$U.lo mpq/div$U.lo \
+ mpq/get_d$U.lo mpq/get_den$U.lo mpq/get_num$U.lo mpq/get_str$U.lo \
+ mpq/init$U.lo mpq/inits$U.lo mpq/inp_str$U.lo mpq/inv$U.lo \
+ mpq/md_2exp$U.lo mpq/mul$U.lo mpq/neg$U.lo mpq/out_str$U.lo \
+ mpq/set$U.lo mpq/set_den$U.lo mpq/set_num$U.lo \
+ mpq/set_si$U.lo mpq/set_str$U.lo mpq/set_ui$U.lo \
+ mpq/equal$U.lo mpq/set_z$U.lo mpq/set_d$U.lo \
+ mpq/set_f$U.lo mpq/swap$U.lo
+
+MPN_OBJECTS = mpn/fib_table$U.lo mpn/mp_bases$U.lo
+PRINTF_OBJECTS = \
+ printf/asprintf$U.lo printf/asprntffuns$U.lo \
+ printf/doprnt$U.lo printf/doprntf$U.lo printf/doprnti$U.lo \
+ printf/fprintf$U.lo \
+ printf/obprintf$U.lo printf/obvprintf$U.lo printf/obprntffuns$U.lo \
+ printf/printf$U.lo printf/printffuns$U.lo \
+ printf/snprintf$U.lo printf/snprntffuns$U.lo \
+ printf/sprintf$U.lo printf/sprintffuns$U.lo \
+ printf/vasprintf$U.lo printf/vfprintf$U.lo printf/vprintf$U.lo \
+ printf/vsnprintf$U.lo printf/vsprintf$U.lo \
+ printf/repl-vsnprintf$U.lo
+
+SCANF_OBJECTS = \
+ scanf/doscan$U.lo scanf/fscanf$U.lo scanf/fscanffuns$U.lo \
+ scanf/scanf$U.lo scanf/sscanf$U.lo scanf/sscanffuns$U.lo \
+ scanf/vfscanf$U.lo scanf/vscanf$U.lo scanf/vsscanf$U.lo
+
+RANDOM_OBJECTS = \
+ rand/rand$U.lo rand/randclr$U.lo rand/randdef$U.lo rand/randiset$U.lo \
+ rand/randlc2s$U.lo rand/randlc2x$U.lo rand/randmt$U.lo \
+ rand/randmts$U.lo rand/rands$U.lo rand/randsd$U.lo rand/randsdui$U.lo \
+ rand/randbui$U.lo rand/randmui$U.lo
+
+
+# no $U for C++ files
+CXX_OBJECTS = \
+ cxx/isfuns.lo cxx/ismpf.lo cxx/ismpq.lo cxx/ismpz.lo cxx/ismpznw.lo \
+ cxx/limits.lo cxx/osdoprnti.lo cxx/osfuns.lo \
+ cxx/osmpf.lo cxx/osmpq.lo cxx/osmpz.lo
+
+
+# In libtool 1.5 it doesn't work to build libgmp.la from the convenience
+# libraries like mpz/libmpz.la. Or rather it works, but it ends up putting
+# PIC objects into libgmp.a if shared and static are both built. (The PIC
+# objects go into mpz/.libs/libmpz.a, and thence into .libs/libgmp.a.)
+#
+# For now the big lists of objects above are used. Something like mpz/*.lo
+# would probably work, but might risk missing something out or getting
+# something extra. The source files for each .lo are listed in the
+# Makefile.am's in the subdirectories.
+#
+# Currently, for libgmp, unlike libmp below, we're not using
+# -export-symbols, since the tune and speed programs, and perhaps some of
+# the test programs, want to access undocumented symbols.
+libgmp_la_SOURCES = gmp-impl.h longlong.h \
+ assert.c compat.c errno.c extract-dbl.c invalid.c memory.c \
+ mp_bpl.c mp_clz_tab.c mp_dv_tab.c mp_minv_tab.c mp_get_fns.c mp_set_fns.c \
+ version.c nextprime.c primesieve.c
+
+EXTRA_libgmp_la_SOURCES = tal-debug.c tal-notreent.c tal-reent.c
+libgmp_la_DEPENDENCIES = @TAL_OBJECT@ \
+ $(MPF_OBJECTS) $(MPZ_OBJECTS) $(MPQ_OBJECTS) \
+ $(MPN_OBJECTS) @mpn_objs_in_libgmp@ \
+ $(PRINTF_OBJECTS) $(SCANF_OBJECTS) $(RANDOM_OBJECTS)
+
+libgmp_la_LIBADD = $(libgmp_la_DEPENDENCIES)
+libgmp_la_LDFLAGS = $(GMP_LDFLAGS) $(LIBGMP_LDFLAGS) \
+ -version-info $(LIBGMP_LT_CURRENT):$(LIBGMP_LT_REVISION):$(LIBGMP_LT_AGE)
+
+
+# We need at least one .cc file in $(libgmpxx_la_SOURCES) so automake will
+# use $(CXXLINK) rather than the plain C $(LINK). cxx/dummy.cc is that
+# file.
+@WANT_CXX_TRUE@GMPXX_LTLIBRARIES_OPTION = libgmpxx.la
+libgmpxx_la_SOURCES = cxx/dummy.cc
+libgmpxx_la_DEPENDENCIES = $(CXX_OBJECTS) libgmp.la
+libgmpxx_la_LIBADD = $(libgmpxx_la_DEPENDENCIES)
+libgmpxx_la_LDFLAGS = $(GMP_LDFLAGS) $(LIBGMPXX_LDFLAGS) \
+ -version-info $(LIBGMPXX_LT_CURRENT):$(LIBGMPXX_LT_REVISION):$(LIBGMPXX_LT_AGE)
+
+all: $(BUILT_SOURCES) config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .o .obj
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu --ignore-deps'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu --ignore-deps \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @if test ! -f $@; then rm -f stamp-h1; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
+
+stamp-h1: $(srcdir)/config.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+gmp.h: $(top_builddir)/config.status $(srcdir)/gmp-h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libgmp.la: $(libgmp_la_OBJECTS) $(libgmp_la_DEPENDENCIES) $(EXTRA_libgmp_la_DEPENDENCIES)
+ $(libgmp_la_LINK) -rpath $(libdir) $(libgmp_la_OBJECTS) $(libgmp_la_LIBADD) $(LIBS)
+libgmpxx.la: $(libgmpxx_la_OBJECTS) $(libgmpxx_la_DEPENDENCIES) $(EXTRA_libgmpxx_la_DEPENDENCIES)
+ $(libgmpxx_la_LINK) $(am_libgmpxx_la_rpath) $(libgmpxx_la_OBJECTS) $(libgmpxx_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ $(LTCXXCOMPILE) -c -o $@ $<
+
+dummy.lo: cxx/dummy.cc
+ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dummy.lo `test -f 'cxx/dummy.cc' || echo '$(srcdir)/'`cxx/dummy.cc
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+install-nodist_includeexecHEADERS: $(nodist_includeexec_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(nodist_includeexec_HEADERS)'; test -n "$(includeexecdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includeexecdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includeexecdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includeexecdir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includeexecdir)" || exit $$?; \
+ done
+
+uninstall-nodist_includeexecHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nodist_includeexec_HEADERS)'; test -n "$(includeexecdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(includeexecdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) config.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) config.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @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
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod u+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includeexecdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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:
+
+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)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-local distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-includeHEADERS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES \
+ install-nodist_includeexecHEADERS
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \
+ uninstall-nodist_includeexecHEADERS
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
+ ctags-recursive install install-am install-data-am \
+ install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am am--refresh check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-local ctags \
+ ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-hook \
+ dist-lzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \
+ distcheck distclean distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-local distclean-tags \
+ distcleancheck distdir distuninstallcheck dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-hook install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-includeHEADERS install-info install-info-am \
+ install-libLTLIBRARIES install-man \
+ install-nodist_includeexecHEADERS install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am \
+ uninstall-includeHEADERS uninstall-libLTLIBRARIES \
+ uninstall-nodist_includeexecHEADERS
+
+
+install-data-hook:
+ @echo ''
+ @echo '+-------------------------------------------------------------+'
+ @echo '| CAUTION: |'
+ @echo '| |'
+ @echo '| If you have not already run "make check", then we strongly |'
+ @echo '| recommend you do so. |'
+ @echo '| |'
+ @echo '| GMP has been carefully tested by its authors, but compilers |'
+ @echo '| are all too often released with serious bugs. GMP tends to |'
+ @echo '| explore interesting corners in compilers and has hit bugs |'
+ @echo '| on quite a few occasions. |'
+ @echo '| |'
+ @echo '+-------------------------------------------------------------+'
+ @echo ''
+
+fac_table.h: gen-fac$(EXEEXT_FOR_BUILD)
+ ./gen-fac $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >fac_table.h || (rm -f fac_table.h; exit 1)
+
+gen-fac$(EXEEXT_FOR_BUILD): gen-fac$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-fac$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-fac$(U_FOR_BUILD).c -o gen-fac$(EXEEXT_FOR_BUILD)
+
+fib_table.h: gen-fib$(EXEEXT_FOR_BUILD)
+ ./gen-fib header $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >fib_table.h || (rm -f fib_table.h; exit 1)
+
+mpn/fib_table.c: gen-fib$(EXEEXT_FOR_BUILD)
+ ./gen-fib table $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >mpn/fib_table.c || (rm -f mpn/fib_table.c; exit 1)
+
+gen-fib$(EXEEXT_FOR_BUILD): gen-fib$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-fib$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-fib$(U_FOR_BUILD).c -o gen-fib$(EXEEXT_FOR_BUILD)
+
+mp_bases.h: gen-bases$(EXEEXT_FOR_BUILD)
+ ./gen-bases header $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >mp_bases.h || (rm -f mp_bases.h; exit 1)
+
+mpn/mp_bases.c: gen-bases$(EXEEXT_FOR_BUILD)
+ ./gen-bases table $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >mpn/mp_bases.c || (rm -f mpn/mp_bases.c; exit 1)
+
+gen-bases$(EXEEXT_FOR_BUILD): gen-bases$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-bases$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-bases$(U_FOR_BUILD).c -o gen-bases$(EXEEXT_FOR_BUILD) $(LIBM_FOR_BUILD)
+
+trialdivtab.h: gen-trialdivtab$(EXEEXT_FOR_BUILD)
+ ./gen-trialdivtab $(GMP_LIMB_BITS) 8000 >trialdivtab.h || (rm -f trialdivtab.h; exit 1)
+
+gen-trialdivtab$(EXEEXT_FOR_BUILD): gen-trialdivtab$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-trialdivtab$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-trialdivtab$(U_FOR_BUILD).c -o gen-trialdivtab$(EXEEXT_FOR_BUILD) $(LIBM_FOR_BUILD)
+
+mpn/jacobitab.h: gen-jacobitab$(EXEEXT_FOR_BUILD)
+ ./gen-jacobitab >mpn/jacobitab.h || (rm -f mpn/jacobitab.h; exit 1)
+
+gen-jacobitab$(EXEEXT_FOR_BUILD): gen-jacobitab$(U_FOR_BUILD).c
+ $(CC_FOR_BUILD) `test -f 'gen-jacobitab$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-jacobitab$(U_FOR_BUILD).c -o gen-jacobitab$(EXEEXT_FOR_BUILD)
+
+mpn/perfsqr.h: gen-psqr$(EXEEXT_FOR_BUILD)
+ ./gen-psqr $(GMP_LIMB_BITS) $(GMP_NAIL_BITS) >mpn/perfsqr.h || (rm -f mpn/perfsqr.h; exit 1)
+
+gen-psqr$(EXEEXT_FOR_BUILD): gen-psqr$(U_FOR_BUILD).c bootstrap.c
+ $(CC_FOR_BUILD) `test -f 'gen-psqr$(U_FOR_BUILD).c' || echo '$(srcdir)/'`gen-psqr$(U_FOR_BUILD).c -o gen-psqr$(EXEEXT_FOR_BUILD) $(LIBM_FOR_BUILD)
+
+# Avoid: CVS - cvs directories
+# *~ - emacs backups
+# .#* - cvs merge originals
+#
+# *~ and .#* only occur when a whole directory without it's own Makefile.am
+# is distributed, like "doc" or the mpn cpu subdirectories.
+#
+dist-hook:
+ -find $(distdir) \( -name CVS -type d \) -o -name "*~" -o -name ".#*" \
+ | xargs rm -rf
+ cp "$(srcdir)"/mini-gmp/tests/*.[ch] "$(distdir)/mini-gmp/tests"
+# grep -F $(VERSION) $(srcdir)/Makefile.am \
+# | grep -q "^# *$(VERSION) *$(LIBGMP_LT_CURRENT):$(LIBGMP_LT_REVISION):$(LIBGMP_LT_AGE) *$(LIBGMPXX_LT_CURRENT):$(LIBGMPXX_LT_REVISION):$(LIBGMPXX_LT_AGE)"
+# test -z "`sed -n 's/^# *[0-9]*\.[0-9]*\.[0-9]* *\([0-9]*:[0-9]*:[0-9]*\) *\([0-9]*:[0-9]*:[0-9]*\) *\([0-9]*:[0-9]*:[0-9]*\).*/A\1\nB\2\nC\3/p' $(srcdir)/Makefile.am | grep -v 'A6:3:3\|B3:5:0\|C4:7:1' | sort | uniq -d`"
+
+.PHONY: check-mini-gmp clean-mini-gmp
+
+check-mini-gmp:
+ abs_srcdir="`cd $(srcdir) && pwd`" ; \
+ $(MKDIR_P) mini-gmp/tests \
+ && cd mini-gmp/tests \
+ && LD_LIBRARY_PATH="../../.libs:$$LD_LIBRARY_PATH" \
+ DYLD_LIBRARY_PATH="../../.libs:$$DYLD_LIBRARY_PATH" \
+ $(MAKE) -f "$$abs_srcdir/mini-gmp/tests/Makefile" \
+ VPATH="$$abs_srcdir/mini-gmp/tests" \
+ srcdir="$$abs_srcdir/mini-gmp/tests" \
+ MINI_GMP_DIR="$$abs_srcdir/mini-gmp" \
+ LDFLAGS="-L../../.libs" \
+ LIBS="-lgmp -lm" \
+ CC="$(CC_FOR_BUILD)" EXTRA_CFLAGS="-g -I../.." check
+
+clean-mini-gmp:
+ if [ -d mini-gmp/tests ] ; then \
+ abs_srcdir="`cd $(srcdir) && pwd`" ; \
+ cd mini-gmp/tests \
+ && $(MAKE) -f "$$abs_srcdir/mini-gmp/tests/Makefile" clean ; \
+ fi
+
+clean-local: clean-mini-gmp
+distclean-local: clean-mini-gmp
+
+# 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/gmp/NEWS b/gmp/NEWS
new file mode 100644
index 0000000000..5f77bce1e1
--- /dev/null
+++ b/gmp/NEWS
@@ -0,0 +1,891 @@
+Copyright 1996, 1999-2014 Free Software Foundation, Inc.
+
+Verbatim copying and distribution of this entire article is permitted in any
+medium, provided this notice is preserved.
+
+
+Changes between GMP version 5.1.* and 6.0.0
+
+ BUGS FIXED
+ * The function mpz_invert now considers any number invertible in Z/1Z.
+
+ * The mpn multiply code now handles operands of more than 2^31 limbs
+ correctly. (Note however that the mpz code is limited to 2^32 bits on
+ 32-bit hosts and 2^37 bits on 64-bit hosts.)
+
+ * Contains all fixes from release 5.1.3.
+
+ SPEEDUPS
+ * Plain division of large operands is faster and more monotonous in operand
+ size.
+
+ * Major speedup for ARM, in particular ARM Cortex-A15, thanks to improved
+ assembly.
+
+ * Major speedup for SPARC T4/T5 and speedup also for T3, thanks to a lot of
+ new assembly.
+
+ * Speedup for Intel Sandy Bridge, Ivy Bridge, Haswell, thanks to rewritten
+ and vastly expanded assembly support. Speedup also for the older Core 2
+ and Nehalem.
+
+ * Faster mixed arithmetic between mpq_class and double.
+
+ * With g++, optimise more operations when one argument is a simple constant.
+
+ FEATURES
+ * Support for new Intel and AMD CPUs.
+
+ * Support for ARM64 alias Aarch64 alias ARMv8.
+
+ * New public functions mpn_sec_mul and mpn_sec_sqr, implementing side-channel
+ silent multiplication and squaring.
+
+ * New public functions mpn_sec_div_qr and mpn_sec_div_r, implementing
+ side-channel silent division.
+
+ * New public functions mpn_cnd_add_n and mpn_cnd_sub_n. Side-channel silent
+ conditional addition and subtraction.
+
+ * New public function mpn_sec_powm, implementing side-channel silent modexp.
+
+ * New public function mpn_sec_invert, implementing side-channel silent
+ modular inversion.
+
+ * Better support for applications which use the mpz_t type, but nevertheless
+ need to call some of the lower-level mpn functions. See the documentation
+ for mpz_limbs_read and related functions.
+
+ MISC
+ * This release will not work on NetBSD 5.x, FreeBSD 7.x, 8.x or 9 series
+ before 9.3. The reason is that the m4 command is not correctly
+ implemented. (Workaround: Use an older GMP release, or install GNU m4 from
+ /usr/ports and tell GMP to use it.)
+
+ * This release will not build properly on FreeBSD/amd64 before version 10
+ using the 32-bit ABI (once a working m4 is installed). The reason is
+ broken limits.h. (Workaround: Use an older GMP release if using the 32-bit
+ ABI on these FreeBSD releases is important.)
+
+ * This release will not work reliably on FreeBSD 10.0 for i386 or amd64 using
+ the 32-bit ABI. The reason is bugs in the compiler 'clang'. Depending on
+ CPU-dependent compiler flags, GMP may or may not be miscompiled in a
+ particular build. (Workaround: Compiling gcc from /usr/ports should work,
+ except that gcc circularly depends on GMP; we have not been able to test
+ that workaround due to FreeBSD 10.0 bugs affecting its ability to run under
+ KVM and Xen.)
+
+ * This release will not compile on FreeBSD before version 10 for i386,
+ targeting any modern AMD processor. The reason is bugs in the old gcc
+ bundled with FreeBSD. (Workaround: install a less obsolete gcc from
+ /usr/ports and tell GMP to use it, or override the -march=amdfam10
+ GMP configure command line argument.)
+
+
+Changes between GMP version 5.1.2 and 5.1.3
+
+ BUGS FIXED
+ * The internal functions mpn_sbpi1_div_qr_sec mpn_sbpi1_div_r_sec could
+ compute garbage with a low probability. They are now rewritten, and the
+ test code has been improved.
+
+ * A bug in the ia64 implementation of mpn_divrem_2, clobbering some
+ callee-save registers, has been fixed. This is an internal
+ function, with the bug manifesting itself as miscomputation in,
+ e.g., mpn_sqrtrem.
+
+ * The documentation now correctly says 'const' for input arguments.
+
+ SPEEDUPS
+ * None.
+
+ FEATURES
+ * None.
+
+ MISC
+ * None.
+
+
+Changes between GMP version 5.1.1 and 5.1.2
+
+ BUGS FIXED
+ * A bug in mpz_powm_ui triggered by base arguments of at least 15000 decimal
+ digits or mod arguments of at least 7500 decimal digits has been fixed.
+
+ * An AMD Bulldozer specific bug affecting the 64-bit Windows ABI has been
+ fixed. This bug was in a key function (mpn_mul_1) and made both Bulldozer
+ specific builds and fat builds run on Bulldozer completely non-functional.
+
+ SPEEDUPS
+ * None.
+
+ FEATURES
+ * None.
+
+ MISC
+ * Fixes and generalisations to the test suite.
+
+ * Minor portability enhancements.
+
+
+Changes between GMP version 5.1.0 and 5.1.1
+
+ BUGS FIXED
+ * On Windows 64-bit, an error causing link errors about
+ __gmp_binvert_limb_table has been fixed.
+
+ * Aarch64 alias ARM64 support now works.
+
+ * A possible buffer overrun in mpz_ior has been fixed.
+
+ * A rare sign flip in mpz_remove has been fixed.
+
+ * A bug causing problems with mpf numbers with absolute value >= 2^31 has
+ been fixed.
+
+ * Several bugs in mini-gmp have been fixed.
+
+ * A bug caused by automake, related to the 'distcheck' target, has been fixed
+ by upgrading the automake used for GMP release engineering.
+
+ SPEEDUPS
+ * None.
+
+ FEATURES
+ * Preliminary support for the x32 ABI under x86-64.
+
+ MISC
+ * The mini-gmp testsuite now tests the entire set of functions.
+
+ * Various improvements of the GMP testsuite.
+
+
+Changes between GMP version 5.0.* and 5.1.0
+
+ BUGS FIXED
+ * When reading a C++ number (like mpz_class) in an istream reaches the end
+ of the stream, the eofbit is now set.
+
+ * The result sign of mpz_rootrem's remainder is now always correct.
+
+ * The mpz_remove function now handles negative divisors.
+
+ * Contains all fixes from release 5.0.5.
+
+ SPEEDUPS
+ * The n-factorial and n-over-k functions have been reimplemented for great
+ speedups for small and large operands.
+
+ * New subquadratic algorithm for the Kronecker/Jacobi/Legendre symbol.
+
+ * Major speedup for ARM, in particular ARM Cortex-A9 and A15, thanks to broad
+ assembly support.
+
+ * Significant speedup for POWER6 and POWER7 thanks to improved assembly.
+
+ * The performance under M$ Windows' 64-bit ABI has been greatly improved
+ thanks to complete assembly support.
+
+ * Minor speed improvements of many functions and for many platforms.
+
+ FEATURES
+ * Many new CPUs recognised.
+
+ * New functions for multi-factorials, and primorial: mpz_2fac_ui,
+ mpz_mfac_uiui and mpz_primorial_ui.
+
+ * The mpz_powm_sec function now uses side-channel silent division for
+ converting into Montgomery residues.
+
+ * The fat binary mechanism is now more robust in its CPU recognition.
+
+ MISC
+ * Inclusion of assembly code is now controlled by the configure options
+ --enable-assembly and --disable-assembly. The "none" CPU target is gone.
+
+ * In C++, the conversions mpq_class->mpz_class, mpf_class->mpz_class and
+ mpf_class->mpq_class are now explicit.
+
+ * Includes "mini-gmp", a small, portable, but less efficient, implementation
+ of a subset of GMP's mpn and mpz interfaces. Used in GMP bootstrap, but it
+ can also be bundled with applications as a fallback when the real GMP
+ library is unavailable.
+
+ * The ABIs under AIX are no longer called aix32 and aix64, but mode64 and 32.
+ This is more consistent with other powerpc systems.
+
+ * The coverage of the testsuite has been improved, using the lcov tool. See
+ also https://gmplib.org/devel/lcov/.
+
+ * It is now possible to compile GMP using a C++ compiler.
+
+ * K&R C compilers are no longer supported.
+
+ * The BSD MP compatibility functions have been removed.
+
+
+Changes between GMP version 5.0.4 and 5.0.5
+
+ BUGS FIXED
+ * A bug causing AMD 11h processors to be treated like AMD 10h has been fixed.
+ The 11h processors do not correctly handle all 10h (aka K10) instructions,
+ and GMP's use of these instructions results in major miscomputations (not
+ as one would have hoped CPU traps of some 'illegal instruction' sort).
+
+ * A bug affecting recent Intel Sandy Bridge CPUs resulting in configuration
+ failures has been fixed.
+
+ SPEEDUPS
+ * None.
+
+ FEATURES
+ * A couple of tests added to the self-check suite.
+
+ MISC
+ * None.
+
+
+Changes between GMP version 5.0.3 and 5.0.4
+
+ BUGS FIXED
+ * Thresholds in mpn_powm_sec for both fat and non-fat builds are now used
+ safely, plugging a one-word buffer overrun introduced in the 5.0.3 release
+ (for non-fat) and a multi-word buffer overrun that existed since 5.0 (for
+ fat). (We have not been able to provoke malign stack smashing in any of
+ the ~100 configurations explored by the GMP nightly builds, but the bug
+ should be assumed to be exploitable.)
+
+ * Two bugs in multiplication code causing incorrect computation with
+ extremely low probability have been fixed.
+
+ * A bug in the test suite causing buffer overruns during "make check",
+ sometimes leading to subsequent malloc crashes, has been fixed.
+
+ * Two bugs in the gcd code have been fixed. They could lead to incorrect
+ results, but for uniformly distributed random operands, the likelihood for
+ that is infinitesimally small. (There was also a third bug, but that was
+ an incorrect ASSERT, which furthermore was not enabled by default.)
+
+ * A bug affecting 32-bit PowerPC division has been fixed. The bug caused
+ miscomputation for certain divisors in the range 2^32 ... 2^64-1 (about 1
+ in 2^30 of these).
+
+ SPEEDUPS
+ * None, except indirectly through recognition of new CPUs, and through better
+ tuning parameters.
+
+ FEATURES
+ * Some more tests added to the self-check suite.
+
+ * The AMD "Bulldozer" CPU is now recognised.
+
+ MISC
+ * None.
+
+
+Changes between GMP version 5.0.2 and 5.0.3
+
+ BUGS FIXED
+ * A few minor bugs related to portability fixed.
+
+ * A slight timing leak of the powm_sec functions have been sealed. (This
+ leak could possibly be used to extract the most significant few bits of the
+ exponent. "Few" here means at most 10.)
+
+ * The mpz_nextprime function now runs a safer number of pseudo-random prime
+ tests.
+
+ * A bug in division code possibly causing incorrect computation was fixed.
+
+ SPEEDUPS
+ * None, except indirectly through recognition of new CPUs, and through better
+ tuning parameters.
+
+ FEATURES
+ * New CPUs recognised.
+
+ * IBM S/390 are now supported in both 31/32-bit and 64-bit mode. (We have
+ not been able to fully test this on any multilib machine, since IBM expired
+ our guest account a few days before our release.)
+
+ MISC
+ * None.
+
+
+Changes between GMP version 5.0.1 and 5.0.2
+
+ BUGS FIXED
+ * Many minor bugs related to portability fixed.
+
+ * The support for HPPA 2.0N now works, after an assembly bug fix.
+
+ * A test case type error has been fixed. The symptom of this bug was
+ spurious 'make check' failures.
+
+ SPEEDUPS
+ * None, except indirectly through recognition of new CPUs.
+
+ FEATURES
+ * Fat builds are now supported for 64-bit x86 processors also under Darwin.
+
+ MISC
+ * None.
+
+
+Changes between GMP version 5.0.0 and 5.0.1
+
+ BUGS FIXED
+ * Fat builds fixed.
+
+ * Fixed crash for huge multiplies when old FFT_TABLE2 type of parameter
+ selection tables' sentinel was smaller than multiplied operands.
+
+ * The solib numbers now reflect the removal of the documented but preliminary
+ mpn_bdivmod function; we correctly flag incompatibility with GMP 4.3. GMP
+ 5.0.0 has this wrong, and should perhaps be uninstalled to avoid confusion.
+
+ SPEEDUPS
+ * Multiplication of large numbers has indirectly been sped up through better
+ FFT tuning and processor recognition. Since many operations depend on
+ multiplication, there will be a general speedup.
+
+ FEATURES
+ * More Core i3, i5 an Core i7 processor models are recognised.
+
+ * Fixes and workarounds for Mac OS quirks should make this GMP version build
+ using many of the different versions of "Xcode".
+
+ MISC
+ * The amount of scratch memory needed for multiplication of huge numbers has
+ been reduced substantially (but is still larger than in GMP 4.3.)
+
+ * Likewise, the amount of scratch memory needed for division of large numbers
+ has been reduced substantially.
+
+ * The FFT tuning code of tune/tuneup.c has been completely rewritten, and
+ new, large FFT parameter selection tables are provided for many machines.
+
+ * Upgraded to the latest autoconf, automake, libtool.
+
+
+Changes between GMP version 4.3.X and 5.0.0
+
+ BUGS FIXED
+ * None (contains the same fixes as release 4.3.2).
+
+ SPEEDUPS
+ * Multiplication has been overhauled:
+ (1) Multiplication of larger same size operands has been improved with
+ the addition of two new Toom functions and a new internal function
+ mpn_mulmod_bnm1 (computing U * V mod (B^n-1), B being the word base.
+ This latter function is used for the largest products, waiting for a
+ better Schoenhage-Strassen U * V mod (B^n+1) implementation.
+ (2) Likewise for squaring.
+ (3) Multiplication of different size operands has been improved with the
+ addition of many new Toom function, and by selecting underlying
+ functions better from the main multiply functions.
+
+ * Division and mod have been overhauled:
+ (1) Plain "schoolbook" division is reimplemented using faster quotient
+ approximation.
+ (2) Division Q = N/D, R = N mod D where both the quotient and remainder
+ are needed now runs in time O(M(log(N))). This is an improvement of
+ a factor log(log(N))
+ (3) Division where just the quotient is needed is now O(M(log(Q))) on
+ average.
+ (4) Modulo operations using Montgomery REDC form now take time O(M(n)).
+ (5) Exact division Q = N/D by means of mpz_divexact has been improved
+ for all sizes, and now runs in time O(M(log(N))).
+
+ * The function mpz_powm is now faster for all sizes. Its complexity has
+ gone from O(M(n)log(n)m) to O(M(n)m) where n is the size of the modulo
+ argument and m is the size of the exponent. It is also radically
+ faster for even modulus, since it now partially factors such modulus
+ and performs two smaller modexp operations, then uses CRT.
+
+ * The internal support for multiplication yielding just the lower n limbs
+ has been improved by using Mulders' algorithm.
+
+ * Computation of inverses, both plain 1/N and 1/N mod B^n have been
+ improved by using well-tuned Newton iterations, and wrap-around
+ multiplication using mpn_mulmod_bnm1.
+
+ * A new algorithm makes mpz_perfect_power_p asymptotically faster.
+
+ * The function mpz_remove uses a much faster algorithm, is better tuned,
+ and also benefits from the division improvements.
+
+ * Intel Atom and VIA Nano specific optimisations.
+
+ * Plus hundreds of smaller improvements and tweaks!
+
+ FEATURES
+ * New mpz function: mpz_powm_sec for side-channel quiet modexp
+ computations.
+
+ * New mpn functions: mpn_sqr, mpn_and_n, mpn_ior_n, mpn_xor_n, mpn_nand_n,
+ mpn_nior_n, mpn_xnor_n, mpn_andn_n, mpn_iorn_n, mpn_com, mpn_neg,
+ mpn_copyi, mpn_copyd, mpn_zero.
+
+ * The function mpn_tdiv_qr now allows certain argument overlap.
+
+ * Support for fat binaries for 64-bit x86 processors has been added.
+
+ * A new type, mp_bitcnt_t for bignum bit counts, has been introduced.
+
+ * Support for Windows64 through mingw64 has been added.
+
+ * The cofactors of mpz_gcdext and mpn_gcdext are now more strictly
+ normalised, returning to how GMP 4.2 worked. (Note that also release
+ 4.3.2 has this change.)
+
+ MISC
+ * The mpn_mul function should no longer be used for squaring,
+ instead use the new mpn_sqr.
+
+ * The algorithm selection has been improved, the number of thresholds have
+ more than doubled, and the tuning and use of existing thresholds have
+ been improved.
+
+ * The tune/speed program can measure many of new functions.
+
+ * The mpn_bdivmod function has been removed. We do not consider this an
+ incompatible change, since the function was marked as preliminary.
+
+ * The testsuite has been enhanced in various ways.
+
+
+Changes between GMP version 4.3.1 and 4.3.2
+
+ Bugs:
+ * Fixed bug in mpf_eq.
+ * Fixed overflow issues in mpz_set_str, mpz_inp_str, mpf_set_str, and
+ mpf_get_str.
+ * Avoid unbounded stack allocation for unbalanced multiplication.
+ * Fixed bug in FFT multiplication.
+
+ Speedups:
+ * None, except that proper processor recognition helps affected processors.
+
+ Features:
+ * Recognise more "Core 2" processor variants.
+ * The cofactors of mpz_gcdext and mpn_gcdext are now more strictly
+ normalised, returning to how GMP 4.2 worked.
+
+
+Changes between GMP version 4.3.0 and 4.3.1
+
+ Bugs:
+ * Fixed bug in mpn_gcdext, affecting also mpz_gcdext and mpz_invert.
+ The bug could cause a cofactor to have a leading zero limb, which
+ could lead to crashes or miscomputation later on.
+ * Fixed some minor documentation issues.
+
+ Speedups:
+ * None.
+
+ Features:
+ * Workarounds for various issues with Mac OS X's build tools.
+ * Recognise more IBM "POWER" processor variants.
+
+
+Changes between GMP version 4.2.X and 4.3.0
+
+ Bugs:
+ * Fixed bug in mpz_perfect_power_p with recognition of negative perfect
+ powers that can be written both as an even and odd power.
+ * We might accidentally have added bugs since there is a large amount of
+ new code in this release.
+
+ Speedups:
+ * Vastly improved assembly code for x86-64 processors from AMD and Intel.
+ * Major improvements also for many other processor families, such as
+ Alpha, PowerPC, and Itanium.
+ * New sub-quadratic mpn_gcd and mpn_gcdext, as well as improved basecase
+ gcd code.
+ * The multiply FFT code has been slightly improved.
+ * Balanced multiplication now uses 4-way Toom in addition to schoolbook,
+ Karatsuba, 3-way Toom, and FFT.
+ * Unbalanced multiplication has been vastly improved.
+ * Improved schoolbook division by means of faster quotient approximation.
+ * Several new algorithms for division and mod by single limbs, giving
+ many-fold speedups.
+ * Improved nth root computations.
+ * The mpz_nextprime function uses sieving and is much faster.
+ * Countless minor tweaks.
+
+ Features:
+ * Updated support for fat binaries for x86_32 include current processors
+ * Lots of new mpn internal interfaces. Some of them will become public
+ in a future GMP release.
+ * Support for the 32-bit ABI under x86-apple-darwin.
+ * x86 CPU recognition code should now default better for future
+ processors.
+ * The experimental nails feature does not work in this release, but
+ it might be re-enabled in the future.
+
+ Misc:
+ * The gmp_version variable now always contains three parts. For this
+ release, it is "4.3.0".
+
+
+Changes between GMP version 4.2.3 and 4.2.4
+
+ Bugs:
+ * Fix bug with parsing exponent '+' sign in mpf.
+ * Fix an allocation bug in mpf_set_str, also affecting mpf_init_set_str, and
+ mpf_inp_str.
+
+ Speedups:
+ * None, except that proper processor recognition helps affected processors.
+
+ Features:
+ * Recognize new AMD processors.
+
+
+Changes between GMP version 4.2.2 and 4.2.3
+
+ Bugs:
+ * Fix x86 CPU recognition code to properly identify recent AMD and Intel
+ 64-bit processors.
+ * The >> operator of the C++ wrapper gmpxx.h now does floor rounding, not
+ truncation.
+ * Inline semantics now follow the C99 standard, and works with recent GCC
+ releases.
+ * C++ bitwise logical operations work for more types.
+ * For C++, gmp.h now includes cstdio, improving compiler compatibility.
+ * Bases > 36 now work properly in mpf_set_str.
+
+ Speedups:
+ * None, except that proper processor recognition helps affected processors.
+
+ Features:
+ * The allocation functions now detect overflow of the mpz_t type. This means
+ that overflow will now cause an abort, except when the allocation
+ computation itself overflows. (Such overflow can probably only happen in
+ powering functions; we will detect powering overflow in the future.)
+
+
+Changes between GMP version 4.2.1 and 4.2.2
+
+ * License is now LGPL version 3.
+
+ Bugs:
+ * Shared library numbers corrected for libcxx.
+ * Fixed serious bug in gmpxx.h where a=a+b*c would generate garbage.
+ Note that this only affects C++ programs.
+ * Fix crash in mpz_set_d for arguments with large negative exponent.
+ * Fix 32-bit ABI bug with Itanium assembly for popcount and hamdist.
+ * Fix assembly syntax problem for powerpc-ibm-aix with AIX native assembler.
+ * Fix problems with x86 --enable-fat, where the compiler where told to
+ generate code for the build machine, not plain i386 code as it should.
+ * Improved recognition of powerpc systems wrt Altivec/VMX capability.
+ * Misc minor fixes, mainly workarounds for compiler/assembler bugs.
+
+ Speedups:
+ * "Core 2" and Pentium 4 processors, running in 64-bit mode will get a
+ slight boost as they are now specifically recognized.
+
+ Features:
+ * New support for x86_64-solaris
+ * New, rudimentary support for x86-apple-darwin and x86_64-apple-darwin.
+ (Please see https://gmplib.org/macos.html for more information.)
+
+
+Changes between GMP version 4.2 and 4.2.1
+
+ Bugs:
+ * Shared library numbers corrected.
+ * Broken support for 32-bit AIX fixed.
+ * Misc minor fixes.
+
+ Speedups:
+ * Exact division (mpz_divexact) now falls back to plain division for large
+ operands.
+
+ Features:
+ * Support for some new systems.
+
+
+Changes between GMP version 4.1.4 and 4.2
+
+ Bugs:
+ * Minor bug fixes and code generalizations.
+ * Expanded and improved test suite.
+
+ Speedups:
+ * Many minor optimizations, too many to mention here.
+ * Division now always subquadratic.
+ * Computation of n-factorial much faster.
+ * Added basic x86-64 assembly code.
+ * Floating-point output is now subquadratic for all bases.
+ * FFT multiply code now about 25% faster.
+ * Toom3 multiply code faster.
+
+ Features:
+ * Much improved configure.
+ * Workarounds for many more compiler bugs.
+ * Temporary allocations are now made on the stack only if small.
+ * New systems supported: HPPA-2.0 gcc, IA-64 HP-UX, PowerPC-64 Darwin,
+ Sparc64 GNU/Linux.
+ * New i386 fat binaries, selecting optimised code at runtime (--enable-fat).
+ * New build option: --enable-profiling=instrument.
+ * New memory function: mp_get_memory_functions.
+ * New Mersenne Twister random numbers: gmp_randinit_mt, also now used for
+ gmp_randinit_default.
+ * New random functions: gmp_randinit_set, gmp_urandomb_ui, gmp_urandomm_ui.
+ * New integer functions: mpz_combit, mpz_rootrem.
+ * gmp_printf etc new type "M" for mp_limb_t.
+ * gmp_scanf and friends now accept C99 hex floats.
+ * Numeric input and output can now be in bases up to 62.
+ * Comparisons mpz_cmp_d, mpz_cmpabs_d, mpf_cmp_d recognise infinities.
+ * Conversions mpz_get_d, mpq_get_d, mpf_get_d truncate towards zero,
+ previously their behaviour was unspecified.
+ * Fixes for overflow issues with operands >= 2^31 bits.
+
+ Caveats:
+ * mpfr is gone, and will from now on be released only separately. Please see
+ www.mpfr.org.
+
+
+Changes between GMP version 4.1.3 and 4.1.4
+
+* Bug fix to FFT multiplication code (crash for huge operands).
+* Bug fix to mpf_sub (miscomputation).
+* Support for powerpc64-gnu-linux.
+* Better support for AMD64 in 32-bit mode.
+* Upwardly binary compatible with 4.1.3, 4.1.2, 4.1.1, 4.1, 4.0.1, 4.0,
+ and 3.x versions.
+
+
+Changes between GMP version 4.1.2 and 4.1.3
+
+* Bug fix for FFT multiplication code (miscomputation).
+* Bug fix to K6 assembly code for gcd.
+* Bug fix to IA-64 assembly code for population count.
+* Portability improvements, most notably functional AMD64 support.
+* mpz_export allows NULL for countp parameter.
+* Many minor bug fixes.
+* mpz_export allows NULL for countp parameter.
+* Upwardly binary compatible with 4.1.2, 4.1.1, 4.1, 4.0.1, 4.0, and 3.x
+ versions.
+
+
+Changes between GMP version 4.1.1 and 4.1.2
+
+* Bug fixes.
+
+
+Changes between GMP version 4.1 and 4.1.1
+
+* Bug fixes.
+* New systems supported: NetBSD and OpenBSD sparc64.
+
+
+Changes between GMP version 4.0.1 and 4.1
+
+* Bug fixes.
+* Speed improvements.
+* Upwardly binary compatible with 4.0, 4.0.1, and 3.x versions.
+* Asymptotically fast conversion to/from strings (mpz, mpq, mpn levels), but
+ also major speed improvements for tiny operands.
+* mpn_get_str parameter restrictions relaxed.
+* Major speed improvements for HPPA 2.0 systems.
+* Major speed improvements for UltraSPARC systems.
+* Major speed improvements for IA-64 systems (but still sub-optimal code).
+* Extended test suite.
+* mpfr is back, with many bug fixes and portability improvements.
+* New function: mpz_ui_sub.
+* New functions: mpz_export, mpz_import.
+* Optimization for nth root functions (mpz_root, mpz_perfect_power_p).
+* Optimization for extended gcd (mpz_gcdext, mpz_invert, mpn_gcdext).
+* Generalized low-level number format, reserving a `nails' part of each
+ limb. (Please note that this is really experimental; some functions
+ are likely to compute garbage when nails are enabled.)
+* Nails-enabled Alpha 21264 assembly code, allowing up to 75% better
+ performance. (Use --enable-nails=4 to enable it.)
+
+
+Changes between GMP version 4.0 and 4.0.1
+
+* Bug fixes.
+
+
+Changes between GMP version 3.1.1 and 4.0
+
+* Bug fixes.
+* Speed improvements.
+* Upwardly binary compatible with 3.x versions.
+* New CPU support: IA-64, Pentium 4.
+* Improved CPU support: 21264, Cray vector systems.
+* Support for all MIPS ABIs: o32, n32, 64.
+* New systems supported: Darwin, SCO, Windows DLLs.
+* New divide-and-conquer square root algorithm.
+* New algorithms chapter in the manual.
+* New malloc reentrant temporary memory method.
+* New C++ class interface by Gerardo Ballabio (beta).
+* Revamped configure, featuring ABI selection.
+* Speed improvements for mpz_powm and mpz_powm_ui (mainly affecting small
+ operands).
+* mpz_perfect_power_p now properly recognizes 0, 1, and negative perfect
+ powers.
+* mpz_hamdist now supports negative operands.
+* mpz_jacobi now accepts non-positive denominators.
+* mpz_powm now supports negative exponents.
+* mpn_mul_1 operand overlap requirements relaxed.
+* Float input and output uses locale specific decimal point where available.
+* New gmp_printf, gmp_scanf and related functions.
+* New division functions: mpz_cdiv_q_2exp, mpz_cdiv_r_2exp, mpz_divexact_ui.
+* New divisibility tests: mpz_divisible_p, mpz_divisible_ui_p,
+ mpz_divisible_2exp_p, mpz_congruent_p, mpz_congruent_ui_p,
+ mpz_congruent_2exp_p.
+* New Fibonacci function: mpz_fib2_ui.
+* New Lucas number functions: mpz_lucnum_ui, mpz_lucnum2_ui.
+* Other new integer functions: mpz_cmp_d, mpz_cmpabs_d, mpz_get_d_2exp,
+ mpz_init2, mpz_kronecker, mpz_lcm_ui, mpz_realloc2.
+* New rational I/O: mpq_get_str, mpq_inp_str, mpq_out_str, mpq_set_str.
+* Other new rational functions: mpq_abs, mpq_cmp_si, mpq_div_2exp,
+ mpq_mul_2exp, mpq_set_f.
+* New float tests: mpf_integer_p, mpf_fits_sint_p, mpf_fits_slong_p,
+ mpf_fits_sshort_p, mpf_fits_uint_p, mpf_fits_ulong_p, mpf_fits_ushort_p.
+* Other new float functions: mpf_cmp_d, mpf_get_default_prec, mpf_get_si,
+ mpf_get_ui, mpf_get_d_2exp.
+* New random functions: gmp_randinit_default, gmp_randinit_lc_2exp_size.
+* New demo expression string parser (see demos/expr).
+* New preliminary perl interface (see demos/perl).
+* Tuned algorithm thresholds for many more CPUs.
+
+
+Changes between GMP version 3.1 and 3.1.1
+
+* Bug fixes for division (rare), mpf_get_str, FFT, and miscellaneous minor
+ things.
+
+
+Changes between GMP version 3.0 and 3.1
+
+* Bug fixes.
+* Improved `make check' running more tests.
+* Tuned algorithm cutoff points for many machines. This will improve speed for
+ a lot of operations, in some cases by a large amount.
+* Major speed improvements: Alpha 21264.
+* Some speed improvements: Cray vector computers, AMD K6 and Athlon, Intel P5
+ and Pentium Pro/II/III.
+* The mpf_get_prec function now works as it did in GMP 2.
+* New utilities for auto-tuning and speed measuring.
+* Multiplication now optionally uses FFT for very large operands. (To enable
+ it, pass --enable-fft to configure.)
+* Support for new systems: Solaris running on x86, FreeBSD 5, HP-UX 11, Cray
+ vector computers, Rhapsody, Nextstep/Openstep, MacOS.
+* Support for shared libraries on 32-bit HPPA.
+* New integer functions: mpz_mul_si, mpz_odd_p, mpz_even_p.
+* New Kronecker symbol functions: mpz_kronecker_si, mpz_kronecker_ui,
+ mpz_si_kronecker, mpz_ui_kronecker.
+* New rational functions: mpq_out_str, mpq_swap.
+* New float functions: mpf_swap.
+* New mpn functions: mpn_divexact_by3c, mpn_tdiv_qr.
+* New EXPERIMENTAL function layer for accurate floating-point arithmetic, mpfr.
+ To try it, pass --enable-mpfr to configure. See the mpfr subdirectory for
+ more information; it is not documented in the main GMP manual.
+
+
+Changes between GMP version 3.0 and 3.0.1
+
+* Memory leaks in gmp_randinit and mpz_probab_prime_p fixed.
+* Documentation for gmp_randinit fixed. Misc documentation errors fixed.
+
+
+Changes between GMP version 2.0 and 3.0
+
+* Source level compatibility with past releases (except mpn_gcd).
+* Bug fixes.
+* Much improved speed thanks to both host independent and host dependent
+ optimizations.
+* Switch to autoconf/automake/libtool.
+* Support for building libgmp as a shared library.
+* Multiplication and squaring using 3-way Toom-Cook.
+* Division using the Burnikel-Ziegler method.
+* New functions computing binomial coefficients: mpz_bin_ui, mpz_bin_uiui.
+* New function computing Fibonacci numbers: mpz_fib_ui.
+* New random number generators: mpf_urandomb, mpz_rrandomb, mpz_urandomb,
+ mpz_urandomm, gmp_randclear, gmp_randinit, gmp_randinit_lc_2exp,
+ gmp_randseed, gmp_randseed_ui.
+* New function for quickly extracting limbs: mpz_getlimbn.
+* New functions performing integer size tests: mpz_fits_sint_p,
+ mpz_fits_slong_p, mpz_fits_sshort_p, mpz_fits_uint_p, mpz_fits_ulong_p,
+ mpz_fits_ushort_p.
+* New mpf functions: mpf_ceil, mpf_floor, mpf_pow_ui, mpf_trunc.
+* New mpq function: mpq_set_d.
+* New mpz functions: mpz_addmul_ui, mpz_cmpabs, mpz_cmpabs_ui, mpz_lcm,
+ mpz_nextprime, mpz_perfect_power_p, mpz_remove, mpz_root, mpz_swap,
+ mpz_tdiv_ui, mpz_tstbit, mpz_xor.
+* New mpn function: mpn_divexact_by3.
+* New CPU support: DEC Alpha 21264, AMD K6 and Athlon, HPPA 2.0 and 64,
+ Intel Pentium Pro and Pentium-II/III, Sparc 64, PowerPC 64.
+* Almost 10 times faster mpz_invert and mpn_gcdext.
+* The interface of mpn_gcd has changed.
+* Better support for MIPS R4x000 and R5000 under Irix 6.
+* Improved support for SPARCv8 and SPARCv9 processors.
+
+
+Changes between GMP version 2.0 and 2.0.2
+
+* Many bug fixes.
+
+
+Changes between GMP version 1.3.2 and 2.0
+
+* Division routines in the mpz class have changed. There are three classes of
+ functions, that rounds the quotient to -infinity, 0, and +infinity,
+ respectively. The first class of functions have names that begin with
+ mpz_fdiv (f is short for floor), the second class' names begin with mpz_tdiv
+ (t is short for trunc), and the third class' names begin with mpz_cdiv (c is
+ short for ceil).
+
+ The old division routines beginning with mpz_m are similar to the new
+ mpz_fdiv, with the exception that some of the new functions return useful
+ values.
+
+ The old function names can still be used. All the old functions names will
+ now do floor division, not trunc division as some of them used to. This was
+ changed to make the functions more compatible with common mathematical
+ practice.
+
+ The mpz_mod and mpz_mod_ui functions now compute the mathematical mod
+ function. I.e., the sign of the 2nd argument is ignored.
+
+* The mpq assignment functions do not canonicalize their results. A new
+ function, mpq_canonicalize must be called by the user if the result is not
+ known to be canonical.
+* The mpn functions are now documented. These functions are intended for
+ very time critical applications, or applications that need full control over
+ memory allocation. Note that the mpn interface is irregular and hard to
+ use.
+* New functions for arbitrary precision floating point arithmetic. Names
+ begin with `mpf_'. Associated type mpf_t.
+* New and improved mpz functions, including much faster GCD, fast exact
+ division (mpz_divexact), bit scan (mpz_scan0 and mpz_scan1), and number
+ theoretical functions like Jacobi (mpz_jacobi) and multiplicative inverse
+ (mpz_invert).
+* New variable types (mpz_t and mpq_t) are available that makes syntax of
+ mpz and mpq calls nicer (no need for & before variables). The MP_INT and
+ MP_RAT types are still available for compatibility.
+* Uses GNU configure. This makes it possible to choose target architecture
+ and CPU variant, and to compile into a separate object directory.
+* Carefully optimized assembly for important inner loops. Support for DEC
+ Alpha, Amd 29000, HPPA 1.0 and 1.1, Intel Pentium and generic x86, Intel
+ i960, Motorola MC68000, MC68020, MC88100, and MC88110, Motorola/IBM
+ PowerPC, National NS32000, IBM POWER, MIPS R3000, R4000, SPARCv7,
+ SuperSPARC, generic SPARCv8, and DEC VAX. Some support also for ARM,
+ Clipper, IBM ROMP (RT), and Pyramid AP/XP.
+* Faster. Thanks to the assembler code, new algorithms, and general tuning.
+ In particular, the speed on machines without GCC is improved.
+* Support for machines without alloca.
+* Now under the LGPL.
+
+INCOMPATIBILITIES BETWEEN GMP 1 AND GMP 2
+
+* mpq assignment functions do not canonicalize their results.
+* mpz division functions round differently.
+* mpz mod functions now really compute mod.
+* mpz_powm and mpz_powm_ui now really use mod for reduction.
diff --git a/gmp/README b/gmp/README
new file mode 100644
index 0000000000..013899dc09
--- /dev/null
+++ b/gmp/README
@@ -0,0 +1,116 @@
+Copyright 1991, 1996, 1999, 2000, 2007 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+
+ THE GNU MP LIBRARY
+
+
+GNU MP is a library for arbitrary precision arithmetic, operating on signed
+integers, rational numbers, and floating point numbers. It has a rich set of
+functions, and the functions have a regular interface.
+
+GNU MP is designed to be as fast as possible, both for small operands and huge
+operands. The speed is achieved by using fullwords as the basic arithmetic
+type, by using fast algorithms, with carefully optimized assembly code for the
+most common inner loops for lots of CPUs, and by a general emphasis on speed
+(instead of simplicity or elegance).
+
+GNU MP is believed to be faster than any other similar library. Its advantage
+increases with operand sizes for certain operations, since GNU MP in many
+cases has asymptotically faster algorithms.
+
+GNU MP is free software and may be freely copied on the terms contained in the
+files COPYING* (see the manual for information on which license(s) applies to
+which components of GNU MP).
+
+
+
+ OVERVIEW OF GNU MP
+
+There are five classes of functions in GNU MP.
+
+ 1. Signed integer arithmetic functions (mpz). These functions are intended
+ to be easy to use, with their regular interface. The associated type is
+ `mpz_t'.
+
+ 2. Rational arithmetic functions (mpq). For now, just a small set of
+ functions necessary for basic rational arithmetics. The associated type
+ is `mpq_t'.
+
+ 3. Floating-point arithmetic functions (mpf). If the C type `double'
+ doesn't give enough precision for your application, declare your
+ variables as `mpf_t' instead, set the precision to any number desired,
+ and call the functions in the mpf class for the arithmetic operations.
+
+ 4. Positive-integer, hard-to-use, very low overhead functions are in the
+ mpn class. No memory management is performed. The caller must ensure
+ enough space is available for the results. The set of functions is not
+ regular, nor is the calling interface. These functions accept input
+ arguments in the form of pairs consisting of a pointer to the least
+ significant word, and an integral size telling how many limbs (= words)
+ the pointer points to.
+
+ Almost all calculations, in the entire package, are made by calling these
+ low-level functions.
+
+ 5. Berkeley MP compatible functions.
+
+ To use these functions, include the file "mp.h". You can test if you are
+ using the GNU version by testing if the symbol __GNU_MP__ is defined.
+
+For more information on how to use GNU MP, please refer to the documentation.
+It is composed from the file doc/gmp.texi, and can be displayed on the screen
+or printed. How to do that, as well how to build the library, is described in
+the INSTALL file in this directory.
+
+
+
+ REPORTING BUGS
+
+If you find a bug in the library, please make sure to tell us about it!
+
+You should first check the GNU MP web pages at https://gmplib.org/, under
+"Status of the current release". There will be patches for all known serious
+bugs there.
+
+Report bugs to gmp-bugs@gmplib.org. What information is needed in a useful bug
+report is described in the manual. The same address can be used for suggesting
+modifications and enhancements.
+
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 78
+End:
diff --git a/gmp/acinclude.m4 b/gmp/acinclude.m4
new file mode 100644
index 0000000000..227712a5db
--- /dev/null
+++ b/gmp/acinclude.m4
@@ -0,0 +1,3984 @@
+dnl GMP specific autoconf macros
+
+
+dnl Copyright 2000-2006, 2009, 2011, 2013, 2014 Free Software Foundation, Inc.
+dnl
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Some tests use, or must delete, the default compiler output. The
+dnl possible filenames are based on what autoconf looks for, namely
+dnl
+dnl a.out - normal unix style
+dnl b.out - i960 systems, including gcc there
+dnl a.exe - djgpp
+dnl a_out.exe - OpenVMS DEC C called via GNV wrapper (gnv.sourceforge.net)
+dnl conftest.exe - various DOS compilers
+
+
+define(IA64_PATTERN,
+[[ia64*-*-* | itanium-*-* | itanium2-*-*]])
+
+dnl Need to be careful not to match m6811, m6812, m68hc11 and m68hc12, all
+dnl of which config.sub accepts. (Though none of which are likely to work
+dnl with GMP.)
+dnl
+define(M68K_PATTERN,
+[[m68k-*-* | m68[0-9][0-9][0-9]-*-*]])
+
+define(POWERPC64_PATTERN,
+[[powerpc64-*-* | powerpc64le-*-* | powerpc620-*-* | powerpc630-*-* | powerpc970-*-* | power[3-9]-*-*]])
+
+define(S390_PATTERN,
+[[s390-*-* | z900esa-*-* | z990esa-*-* | z9esa-*-* | z10esa-*-* | z196esa-*-*]])
+
+define(S390X_PATTERN,
+[[s390x-*-* | z900-*-* | z990-*-* | z9-*-* | z10-*-* | z196-*-*]])
+
+define(X86_PATTERN,
+[[i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-*]])
+
+define(X86_64_PATTERN,
+[[athlon64-*-* | k8-*-* | k10-*-* | bobcat-*-* | jaguar-*-* | bulldozer-*-* | piledriver-*-* | steamroller-*-* | excavator-*-* | pentium4-*-* | atom-*-* | core2-*-* | corei*-*-* | x86_64-*-* | nano-*-*]])
+
+dnl GMP_FAT_SUFFIX(DSTVAR, DIRECTORY)
+dnl ---------------------------------
+dnl Emit code to set shell variable DSTVAR to the suffix for a fat binary
+dnl routine from DIRECTORY. DIRECTORY can be a shell expression like $foo
+dnl etc.
+dnl
+dnl The suffix is directory separators / or \ changed to underscores, and
+dnl if there's more than one directory part, then the first is dropped.
+dnl
+dnl For instance,
+dnl
+dnl x86 -> x86
+dnl x86/k6 -> k6
+dnl x86/k6/mmx -> k6_mmx
+
+define(GMP_FAT_SUFFIX,
+[[$1=`echo $2 | sed -e '/\//s:^[^/]*/::' -e 's:[\\/]:_:g'`]])
+
+
+dnl GMP_REMOVE_FROM_LIST(listvar,item)
+dnl ----------------------------------
+dnl Emit code to remove any occurrence of ITEM from $LISTVAR. ITEM can be a
+dnl shell expression like $foo if desired.
+
+define(GMP_REMOVE_FROM_LIST,
+[remove_from_list_tmp=
+for remove_from_list_i in $[][$1]; do
+ if test $remove_from_list_i = [$2]; then :;
+ else
+ remove_from_list_tmp="$remove_from_list_tmp $remove_from_list_i"
+ fi
+done
+[$1]=$remove_from_list_tmp
+])
+
+
+dnl GMP_STRIP_PATH(subdir)
+dnl ----------------------
+dnl Strip entries */subdir from $path and $fat_path.
+
+define(GMP_STRIP_PATH,
+[GMP_STRIP_PATH_VAR(path, [$1])
+GMP_STRIP_PATH_VAR(fat_path, [$1])
+])
+
+define(GMP_STRIP_PATH_VAR,
+[tmp_path=
+for i in $[][$1]; do
+ case $i in
+ */[$2]) ;;
+ *) tmp_path="$tmp_path $i" ;;
+ esac
+done
+[$1]="$tmp_path"
+])
+
+
+dnl GMP_INCLUDE_GMP_H
+dnl -----------------
+dnl Expand to the right way to #include gmp-h.in. This must be used
+dnl instead of gmp.h, since that file isn't generated until the end of the
+dnl configure.
+dnl
+dnl Dummy value for GMP_LIMB_BITS is enough
+dnl for all current configure-time uses of gmp.h.
+
+define(GMP_INCLUDE_GMP_H,
+[[#define __GMP_WITHIN_CONFIGURE 1 /* ignore template stuff */
+#define GMP_NAIL_BITS $GMP_NAIL_BITS
+#define GMP_LIMB_BITS 123
+$DEFN_LONG_LONG_LIMB
+#include "$srcdir/gmp-h.in"]
+])
+
+
+dnl GMP_HEADER_GETVAL(NAME,FILE)
+dnl ----------------------------
+dnl Expand at autoconf time to the value of a "#define NAME" from the given
+dnl FILE. The regexps here aren't very rugged, but are enough for gmp.
+dnl /dev/null as a parameter prevents a hang if $2 is accidentally omitted.
+
+define(GMP_HEADER_GETVAL,
+[patsubst(patsubst(
+esyscmd([grep "^#define $1 " $2 /dev/null 2>/dev/null]),
+[^.*$1[ ]+],[]),
+[[
+ ]*$],[])])
+
+
+dnl GMP_VERSION
+dnl -----------
+dnl The gmp version number, extracted from the #defines in gmp-h.in at
+dnl autoconf time. Two digits like 3.0 if patchlevel <= 0, or three digits
+dnl like 3.0.1 if patchlevel > 0.
+
+define(GMP_VERSION,
+[GMP_HEADER_GETVAL(__GNU_MP_VERSION,gmp-h.in)[]dnl
+.GMP_HEADER_GETVAL(__GNU_MP_VERSION_MINOR,gmp-h.in)[]dnl
+.GMP_HEADER_GETVAL(__GNU_MP_VERSION_PATCHLEVEL,gmp-h.in)])
+
+
+dnl GMP_SUBST_CHECK_FUNCS(func,...)
+dnl ------------------------------
+dnl Setup an AC_SUBST of HAVE_FUNC_01 for each argument.
+
+AC_DEFUN([GMP_SUBST_CHECK_FUNCS],
+[m4_if([$1],,,
+[_GMP_SUBST_CHECK_FUNCS(ac_cv_func_[$1],HAVE_[]m4_translit([$1],[a-z],[A-Z])_01)
+GMP_SUBST_CHECK_FUNCS(m4_shift($@))])])
+
+dnl Called: _GMP_SUBST_CHECK_FUNCS(cachevar,substvar)
+AC_DEFUN([_GMP_SUBST_CHECK_FUNCS],
+[case $[$1] in
+yes) AC_SUBST([$2],1) ;;
+no) [$2]=0 ;;
+esac
+])
+
+
+dnl GMP_SUBST_CHECK_HEADERS(foo.h,...)
+dnl ----------------------------------
+dnl Setup an AC_SUBST of HAVE_FOO_H_01 for each argument.
+
+AC_DEFUN([GMP_SUBST_CHECK_HEADERS],
+[m4_if([$1],,,
+[_GMP_SUBST_CHECK_HEADERS(ac_cv_header_[]m4_translit([$1],[./],[__]),
+HAVE_[]m4_translit([$1],[a-z./],[A-Z__])_01)
+GMP_SUBST_CHECK_HEADERS(m4_shift($@))])])
+
+dnl Called: _GMP_SUBST_CHECK_HEADERS(cachevar,substvar)
+AC_DEFUN([_GMP_SUBST_CHECK_HEADERS],
+[case $[$1] in
+yes) AC_SUBST([$2],1) ;;
+no) [$2]=0 ;;
+esac
+])
+
+
+dnl GMP_COMPARE_GE(A1,B1, A2,B2, ...)
+dnl ---------------------------------
+dnl Compare two version numbers A1.A2.etc and B1.B2.etc. Set
+dnl $gmp_compare_ge to yes or no according to the result. The A parts
+dnl should be variables, the B parts fixed numbers. As many parts as
+dnl desired can be included. An empty string in an A part is taken to be
+dnl zero, the B parts should be non-empty and non-zero.
+dnl
+dnl For example,
+dnl
+dnl GMP_COMPARE($major,10, $minor,3, $subminor,1)
+dnl
+dnl would test whether $major.$minor.$subminor is greater than or equal to
+dnl 10.3.1.
+
+AC_DEFUN([GMP_COMPARE_GE],
+[gmp_compare_ge=no
+GMP_COMPARE_GE_INTERNAL($@)
+])
+
+AC_DEFUN([GMP_COMPARE_GE_INTERNAL],
+[ifelse(len([$3]),0,
+[if test -n "$1" && test "$1" -ge $2; then
+ gmp_compare_ge=yes
+fi],
+[if test -n "$1"; then
+ if test "$1" -gt $2; then
+ gmp_compare_ge=yes
+ else
+ if test "$1" -eq $2; then
+ GMP_COMPARE_GE_INTERNAL(m4_shift(m4_shift($@)))
+ fi
+ fi
+fi])
+])
+
+
+dnl GMP_PROG_AR
+dnl -----------
+dnl GMP additions to $AR.
+dnl
+dnl A cross-"ar" may be necessary when cross-compiling since the build
+dnl system "ar" might try to interpret the object files to build a symbol
+dnl table index, hence the use of AC_CHECK_TOOL.
+dnl
+dnl A user-selected $AR is always left unchanged. AC_CHECK_TOOL is still
+dnl run to get the "checking" message printed though.
+dnl
+dnl If extra flags are added to AR, then ac_cv_prog_AR and
+dnl ac_cv_prog_ac_ct_AR are set too, since libtool (cvs 2003-03-31 at
+dnl least) will do an AC_CHECK_TOOL and that will AR from one of those two
+dnl cached variables. (ac_cv_prog_AR is used if there's an ac_tool_prefix,
+dnl or ac_cv_prog_ac_ct_AR is used otherwise.) FIXME: This is highly
+dnl dependent on autoconf internals, perhaps it'd work to put our extra
+dnl flags into AR_FLAGS instead.
+dnl
+dnl $AR_FLAGS is set to "cq" rather than leaving it to libtool "cru". The
+dnl latter fails when libtool goes into piecewise mode and is unlucky
+dnl enough to have two same-named objects in separate pieces, as happens
+dnl for instance to random.o (and others) on vax-dec-ultrix4.5. Naturally
+dnl a user-selected $AR_FLAGS is left unchanged.
+dnl
+dnl For reference, $ARFLAGS is used by automake (1.8) for its ".a" archive
+dnl file rules. This doesn't get used by the piecewise linking, so we
+dnl leave it at the default "cru".
+dnl
+dnl FIXME: Libtool 1.5.2 has its own arrangements for "cq", but that version
+dnl is broken in other ways. When we can upgrade, remove the forcible
+dnl AR_FLAGS=cq.
+
+AC_DEFUN([GMP_PROG_AR],
+[dnl Want to establish $AR before libtool initialization.
+AC_BEFORE([$0],[AC_PROG_LIBTOOL])
+gmp_user_AR=$AR
+AC_CHECK_TOOL(AR, ar, ar)
+if test -z "$gmp_user_AR"; then
+ eval arflags=\"\$ar${abi1}_flags\"
+ test -n "$arflags" || eval arflags=\"\$ar${abi2}_flags\"
+ if test -n "$arflags"; then
+ AC_MSG_CHECKING([for extra ar flags])
+ AR="$AR $arflags"
+ ac_cv_prog_AR="$AR $arflags"
+ ac_cv_prog_ac_ct_AR="$AR $arflags"
+ AC_MSG_RESULT([$arflags])
+ fi
+fi
+if test -z "$AR_FLAGS"; then
+ AR_FLAGS=cq
+fi
+])
+
+
+dnl GMP_PROG_M4
+dnl -----------
+dnl Find a working m4, either in $PATH or likely locations, and setup $M4
+dnl and an AC_SUBST accordingly. If $M4 is already set then it's a user
+dnl choice and is accepted with no checks. GMP_PROG_M4 is like
+dnl AC_PATH_PROG or AC_CHECK_PROG, but tests each m4 found to see if it's
+dnl good enough.
+dnl
+dnl See mpn/asm-defs.m4 for details on the known bad m4s.
+
+AC_DEFUN([GMP_PROG_M4],
+[AC_ARG_VAR(M4,[m4 macro processor])
+AC_CACHE_CHECK([for suitable m4],
+ gmp_cv_prog_m4,
+[if test -n "$M4"; then
+ gmp_cv_prog_m4="$M4"
+else
+ cat >conftest.m4 <<\EOF
+dnl Must protect this against being expanded during autoconf m4!
+dnl Dont put "dnl"s in this as autoconf will flag an error for unexpanded
+dnl macros.
+[define(dollarhash,``$][#'')ifelse(dollarhash(x),1,`define(t1,Y)',
+``bad: $][# not supported (SunOS /usr/bin/m4)
+'')ifelse(eval(89),89,`define(t2,Y)',
+`bad: eval() doesnt support 8 or 9 in a constant (OpenBSD 2.6 m4)
+')ifelse(eval(9,9),10,`define(t3,Y)',
+`bad: eval() doesnt support radix in eval (FreeBSD 8.x,9.0,9.1,9.2 m4)
+')ifelse(t1`'t2`'t3,YYY,`good
+')]
+EOF
+dnl ' <- balance the quotes for emacs sh-mode
+ echo "trying m4" >&AC_FD_CC
+ gmp_tmp_val=`(m4 conftest.m4) 2>&AC_FD_CC`
+ echo "$gmp_tmp_val" >&AC_FD_CC
+ if test "$gmp_tmp_val" = good; then
+ gmp_cv_prog_m4="m4"
+ else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="$PATH:/usr/5bin"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ echo "trying $ac_dir/m4" >&AC_FD_CC
+ gmp_tmp_val=`($ac_dir/m4 conftest.m4) 2>&AC_FD_CC`
+ echo "$gmp_tmp_val" >&AC_FD_CC
+ if test "$gmp_tmp_val" = good; then
+ gmp_cv_prog_m4="$ac_dir/m4"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ if test -z "$gmp_cv_prog_m4"; then
+ AC_MSG_ERROR([No usable m4 in \$PATH or /usr/5bin (see config.log for reasons).])
+ fi
+ fi
+ rm -f conftest.m4
+fi])
+M4="$gmp_cv_prog_m4"
+AC_SUBST(M4)
+])
+
+
+dnl GMP_M4_M4WRAP_SPURIOUS
+dnl ----------------------
+dnl Check for spurious output from m4wrap(), as described in mpn/asm-defs.m4.
+dnl
+dnl The following systems have been seen with the problem.
+dnl
+dnl - Unicos alpha, but its assembler doesn't seem to mind.
+dnl - MacOS X Darwin, its assembler fails.
+dnl - NetBSD 1.4.1 m68k, and gas 1.92.3 there gives a warning and ignores
+dnl the bad last line since it doesn't have a newline.
+dnl - NetBSD 1.4.2 alpha, but its assembler doesn't seem to mind.
+dnl - HP-UX ia64.
+dnl
+dnl Enhancement: Maybe this could be in GMP_PROG_M4, and attempt to prefer
+dnl an m4 with a working m4wrap, if it can be found.
+
+AC_DEFUN([GMP_M4_M4WRAP_SPURIOUS],
+[AC_REQUIRE([GMP_PROG_M4])
+AC_CACHE_CHECK([if m4wrap produces spurious output],
+ gmp_cv_m4_m4wrap_spurious,
+[# hide the d-n-l from autoconf's error checking
+tmp_d_n_l=d""nl
+cat >conftest.m4 <<EOF
+[changequote({,})define(x,)m4wrap({x})$tmp_d_n_l]
+EOF
+echo test input is >&AC_FD_CC
+cat conftest.m4 >&AC_FD_CC
+tmp_chars=`$M4 conftest.m4 | wc -c`
+echo produces $tmp_chars chars output >&AC_FD_CC
+rm -f conftest.m4
+if test $tmp_chars = 0; then
+ gmp_cv_m4_m4wrap_spurious=no
+else
+ gmp_cv_m4_m4wrap_spurious=yes
+fi
+])
+GMP_DEFINE_RAW(["define(<M4WRAP_SPURIOUS>,<$gmp_cv_m4_m4wrap_spurious>)"])
+])
+
+
+dnl GMP_PROG_NM
+dnl -----------
+dnl GMP additions to libtool AC_PROG_NM.
+dnl
+dnl Note that if AC_PROG_NM can't find a working nm it still leaves
+dnl $NM set to "nm", so $NM can't be assumed to actually work.
+dnl
+dnl A user-selected $NM is always left unchanged. AC_PROG_NM is still run
+dnl to get the "checking" message printed though.
+dnl
+dnl Perhaps it'd be worthwhile checking that nm works, by running it on an
+dnl actual object file. For instance on sparcv9 solaris old versions of
+dnl GNU nm don't recognise 64-bit objects. Checking would give a better
+dnl error message than just a failure in later tests like GMP_ASM_W32 etc.
+dnl
+dnl On the other hand it's not really normal autoconf practice to take too
+dnl much trouble over detecting a broken set of tools. And libtool doesn't
+dnl do anything at all for say ranlib or strip. So for now we're inclined
+dnl to just demand that the user provides a coherent environment.
+
+AC_DEFUN([GMP_PROG_NM],
+[dnl Make sure we're the first to call AC_PROG_NM, so our extra flags are
+dnl used by everyone.
+AC_BEFORE([$0],[AC_PROG_NM])
+gmp_user_NM=$NM
+AC_PROG_NM
+
+# FIXME: When cross compiling (ie. $ac_tool_prefix not empty), libtool
+# defaults to plain "nm" if a "${ac_tool_prefix}nm" is not found. In this
+# case run it again to try the native "nm", firstly so that likely locations
+# are searched, secondly so that -B or -p are added if necessary for BSD
+# format. This is necessary for instance on OSF with "./configure
+# --build=alphaev5-dec-osf --host=alphaev6-dec-osf".
+#
+if test -z "$gmp_user_NM" && test -n "$ac_tool_prefix" && test "$NM" = nm; then
+ $as_unset lt_cv_path_NM
+ gmp_save_ac_tool_prefix=$ac_tool_prefix
+ ac_tool_prefix=
+ NM=
+ AC_PROG_NM
+ ac_tool_prefix=$gmp_save_ac_tool_prefix
+fi
+
+if test -z "$gmp_user_NM"; then
+ eval nmflags=\"\$nm${abi1}_flags\"
+ test -n "$nmflags" || eval nmflags=\"\$nm${abi2}_flags\"
+ if test -n "$nmflags"; then
+ AC_MSG_CHECKING([for extra nm flags])
+ NM="$NM $nmflags"
+ AC_MSG_RESULT([$nmflags])
+ fi
+fi
+])
+
+
+dnl GMP_PROG_CC_WORKS(cc+cflags,[ACTION-IF-WORKS][,ACTION-IF-NOT-WORKS])
+dnl --------------------------------------------------------------------
+dnl Check if cc+cflags can compile and link.
+dnl
+dnl This test is designed to be run repeatedly with different cc+cflags
+dnl selections, so the result is not cached.
+dnl
+dnl For a native build, meaning $cross_compiling == no, we require that the
+dnl generated program will run. This is the same as AC_PROG_CC does in
+dnl _AC_COMPILER_EXEEXT_WORKS, and checking here will ensure we don't pass
+dnl a CC/CFLAGS combination that it rejects.
+dnl
+dnl sparc-*-solaris2.7 can compile ABI=64 but won't run it if the kernel
+dnl was booted in 32-bit mode. The effect of requiring the compiler output
+dnl will run is that a plain native "./configure" falls back on ABI=32, but
+dnl ABI=64 is still available as a cross-compile.
+dnl
+dnl The various specific problems we try to detect are done in separate
+dnl compiles. Although this is probably a bit slower than one test
+dnl program, it makes it easy to indicate the problem in AC_MSG_RESULT,
+dnl hence giving the user a clue about why we rejected the compiler.
+
+AC_DEFUN([GMP_PROG_CC_WORKS],
+[AC_MSG_CHECKING([compiler $1])
+gmp_prog_cc_works=yes
+
+# first see a simple "main()" works, then go on to other checks
+GMP_PROG_CC_WORKS_PART([$1], [])
+
+GMP_PROG_CC_WORKS_PART([$1], [function pointer return],
+[/* The following provokes an internal error from gcc 2.95.2 -mpowerpc64
+ (without -maix64), hence detecting an unusable compiler */
+void *g() { return (void *) 0; }
+void *f() { return g(); }
+])
+
+GMP_PROG_CC_WORKS_PART([$1], [cmov instruction],
+[/* The following provokes an invalid instruction syntax from i386 gcc
+ -march=pentiumpro on Solaris 2.8. The native sun assembler
+ requires a non-standard syntax for cmov which gcc (as of 2.95.2 at
+ least) doesn't know. */
+int n;
+int cmov () { return (n >= 0 ? n : 0); }
+])
+
+GMP_PROG_CC_WORKS_PART([$1], [double -> ulong conversion],
+[/* The following provokes a linker invocation problem with gcc 3.0.3
+ on AIX 4.3 under "-maix64 -mpowerpc64 -mcpu=630". The -mcpu=630
+ option causes gcc to incorrectly select the 32-bit libgcc.a, not
+ the 64-bit one, and consequently it misses out on the __fixunsdfdi
+ helper (double -> uint64 conversion). */
+double d;
+unsigned long gcc303 () { return (unsigned long) d; }
+])
+
+GMP_PROG_CC_WORKS_PART([$1], [double negation],
+[/* The following provokes an error from hppa gcc 2.95 under -mpa-risc-2-0 if
+ the assembler doesn't know hppa 2.0 instructions. fneg is a 2.0
+ instruction, and a negation like this comes out using it. */
+double fneg_data;
+unsigned long fneg () { return -fneg_data; }
+])
+
+GMP_PROG_CC_WORKS_PART([$1], [double -> float conversion],
+[/* The following makes gcc 3.3 -march=pentium4 generate an SSE2 xmm insn
+ (cvtsd2ss) which will provoke an error if the assembler doesn't recognise
+ those instructions. Not sure how much of the gmp code will come out
+ wanting sse2, but it's easiest to reject an option we know is bad. */
+double ftod_data;
+float ftod () { return (float) ftod_data; }
+])
+
+GMP_PROG_CC_WORKS_PART([$1], [gnupro alpha ev6 char spilling],
+[/* The following provokes an internal compiler error from gcc version
+ "2.9-gnupro-99r1" under "-O2 -mcpu=ev6", apparently relating to char
+ values being spilled into floating point registers. The problem doesn't
+ show up all the time, but has occurred enough in GMP for us to reject
+ this compiler+flags. */
+#include <string.h> /* for memcpy */
+struct try_t
+{
+ char dst[2];
+ char size;
+ long d0, d1, d2, d3, d4, d5, d6;
+ char overlap;
+};
+struct try_t param[6];
+int
+param_init ()
+{
+ struct try_t *p;
+ memcpy (p, &param[ 2 ], sizeof (*p));
+ memcpy (p, &param[ 2 ], sizeof (*p));
+ p->size = 2;
+ memcpy (p, &param[ 1 ], sizeof (*p));
+ p->dst[0] = 1;
+ p->overlap = 2;
+ memcpy (p, &param[ 3 ], sizeof (*p));
+ p->dst[0] = 1;
+ p->overlap = 8;
+ memcpy (p, &param[ 4 ], sizeof (*p));
+ memcpy (p, &param[ 4 ], sizeof (*p));
+ p->overlap = 8;
+ memcpy (p, &param[ 5 ], sizeof (*p));
+ memcpy (p, &param[ 5 ], sizeof (*p));
+ memcpy (p, &param[ 5 ], sizeof (*p));
+ return 0;
+}
+])
+
+# __builtin_alloca is not available everywhere, check it exists before
+# seeing that it works
+GMP_PROG_CC_WORKS_PART_TEST([$1],[__builtin_alloca availability],
+[int k; int foo () { __builtin_alloca (k); }],
+ [GMP_PROG_CC_WORKS_PART([$1], [alloca array],
+[/* The following provokes an internal compiler error from Itanium HP-UX cc
+ under +O2 or higher. We use this sort of code in mpn/generic/mul_fft.c. */
+int k;
+int foo ()
+{
+ int i, **a;
+ a = __builtin_alloca (k);
+ for (i = 0; i <= k; i++)
+ a[i] = __builtin_alloca (1 << i);
+}
+])])
+
+GMP_PROG_CC_WORKS_PART([$1], [abs int -> double conversion],
+[/* The following provokes an internal error from the assembler on
+ power2-ibm-aix4.3.1.0. gcc -mrios2 compiles to nabs+fcirz, and this
+ results in "Internal error related to the source program domain".
+
+ For reference it seems to be the combination of nabs+fcirz which is bad,
+ not either alone. This sort of thing occurs in mpz/get_str.c with the
+ way double chars_per_bit_exactly is applied in MPN_SIZEINBASE. Perhaps
+ if that code changes to a scaled-integer style then we won't need this
+ test. */
+
+double fp[1];
+int x;
+int f ()
+{
+ int a;
+ a = (x >= 0 ? x : -x);
+ return a * fp[0];
+}
+])
+
+GMP_PROG_CC_WORKS_PART([$1], [long long reliability test 1],
+[/* The following provokes a segfault in the compiler on powerpc-apple-darwin.
+ Extracted from tests/mpn/t-iord_u.c. Causes Apple's gcc 3.3 build 1640 and
+ 1666 to segfault with e.g., -O2 -mpowerpc64. */
+
+#if defined (__GNUC__) && ! defined (__cplusplus)
+typedef unsigned long long t1;typedef t1*t2;
+static __inline__ t1 e(t2 rp,t2 up,int n,t1 v0)
+{t1 c,x,r;int i;if(v0){c=1;for(i=1;i<n;i++){x=up[i];r=x+1;rp[i]=r;}}return c;}
+f(){static const struct{t1 n;t1 src[9];t1 want[9];}d[]={{1,{0},{1}},};t1 got[9];int i;
+for(i=0;i<1;i++){if(e(got,got,9,d[i].n)==0)h();g(i,d[i].src,d[i].n,got,d[i].want,9);if(d[i].n)h();}}
+h(){}g(){}
+#else
+int dummy;
+#endif
+])
+
+GMP_PROG_CC_WORKS_PART([$1], [long long reliability test 2],
+[/* The following provokes an internal compiler error on powerpc-apple-darwin.
+ Extracted from mpz/cfdiv_q_2exp.c. Causes Apple's gcc 3.3 build 1640 and
+ 1666 to get an ICE with -O1 -mpowerpc64. */
+
+#if defined (__GNUC__) && ! defined (__cplusplus)
+f(int u){int i;long long x;x=u?~0:0;if(x)for(i=0;i<9;i++);x&=g();if(x)g();}
+g(){}
+#else
+int dummy;
+#endif
+])
+
+GMP_PROG_CC_WORKS_PART_MAIN([$1], [mpn_lshift_com optimization],
+[/* The following is mis-compiled by HP ia-64 cc version
+ cc: HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]
+ under "cc +O3", both in +DD32 and +DD64 modes. The mpn_lshift_com gets
+ inlined and its return value somehow botched to be 0 instead of 1. This
+ arises in the real mpn_lshift_com in mul_fft.c. A lower optimization
+ level, like +O2 seems ok. This code needs to be run to show the problem,
+ but that's fine, the offending cc is a native-only compiler so we don't
+ have to worry about cross compiling. */
+
+#if ! defined (__cplusplus)
+unsigned long
+lshift_com (rp, up, n, cnt)
+ unsigned long *rp;
+ unsigned long *up;
+ long n;
+ unsigned cnt;
+{
+ unsigned long retval, high_limb, low_limb;
+ unsigned tnc;
+ long i;
+ tnc = 8 * sizeof (unsigned long) - cnt;
+ low_limb = *up++;
+ retval = low_limb >> tnc;
+ high_limb = low_limb << cnt;
+ for (i = n - 1; i != 0; i--)
+ {
+ low_limb = *up++;
+ *rp++ = ~(high_limb | (low_limb >> tnc));
+ high_limb = low_limb << cnt;
+ }
+ return retval;
+}
+int
+main ()
+{
+ unsigned long cy, rp[2], up[2];
+ up[0] = ~ 0L;
+ up[1] = 0;
+ cy = lshift_com (rp, up, 2L, 1);
+ if (cy != 1L)
+ return 1;
+ return 0;
+}
+#else
+int
+main ()
+{
+ return 0;
+}
+#endif
+])
+
+GMP_PROG_CC_WORKS_PART_MAIN([$1], [mpn_lshift_com optimization 2],
+[/* The following is mis-compiled by Intel ia-64 icc version 1.8 under
+ "icc -O3", After several calls, the function writes partial garbage to
+ the result vector. Perhaps relates to the chk.a.nc insn. This code needs
+ to be run to show the problem, but that's fine, the offending cc is a
+ native-only compiler so we don't have to worry about cross compiling. */
+
+#if ! defined (__cplusplus)
+#include <stdlib.h>
+void
+lshift_com (rp, up, n, cnt)
+ unsigned long *rp;
+ unsigned long *up;
+ long n;
+ unsigned cnt;
+{
+ unsigned long high_limb, low_limb;
+ unsigned tnc;
+ long i;
+ up += n;
+ rp += n;
+ tnc = 8 * sizeof (unsigned long) - cnt;
+ low_limb = *--up;
+ high_limb = low_limb << cnt;
+ for (i = n - 1; i != 0; i--)
+ {
+ low_limb = *--up;
+ *--rp = ~(high_limb | (low_limb >> tnc));
+ high_limb = low_limb << cnt;
+ }
+ *--rp = ~high_limb;
+}
+int
+main ()
+{
+ unsigned long *r, *r2;
+ unsigned long a[88 + 1];
+ long i;
+ for (i = 0; i < 88 + 1; i++)
+ a[i] = ~0L;
+ r = malloc (10000 * sizeof (unsigned long));
+ r2 = r;
+ for (i = 0; i < 528; i += 22)
+ {
+ lshift_com (r2, a,
+ i / (8 * sizeof (unsigned long)) + 1,
+ i % (8 * sizeof (unsigned long)));
+ r2 += 88 + 1;
+ }
+ if (r[2048] != 0 || r[2049] != 0 || r[2050] != 0 || r[2051] != 0 ||
+ r[2052] != 0 || r[2053] != 0 || r[2054] != 0)
+ abort ();
+ return 0;
+}
+#else
+int
+main ()
+{
+ return 0;
+}
+#endif
+])
+
+
+# A certain _GLOBAL_OFFSET_TABLE_ problem in past versions of gas, tickled
+# by recent versions of gcc.
+#
+if test "$gmp_prog_cc_works" = yes; then
+ case $host in
+ X86_PATTERN)
+ # this problem only arises in PIC code, so don't need to test when
+ # --disable-shared. We don't necessarily have $enable_shared set to
+ # yes at this point, it will still be unset for the default (which is
+ # yes); hence the use of "!= no".
+ if test "$enable_shared" != no; then
+ GMP_PROG_CC_X86_GOT_EAX_EMITTED([$1],
+ [GMP_ASM_X86_GOT_EAX_OK([$1],,
+ [gmp_prog_cc_works="no, bad gas GOT with eax"])])
+ fi
+ ;;
+ esac
+fi
+
+AC_MSG_RESULT($gmp_prog_cc_works)
+case $gmp_prog_cc_works in
+ yes)
+ [$2]
+ ;;
+ *)
+ [$3]
+ ;;
+esac
+])
+
+dnl Called: GMP_PROG_CC_WORKS_PART(CC+CFLAGS,FAIL-MESSAGE [,CODE])
+dnl A dummy main() is appended to the CODE given.
+dnl
+AC_DEFUN([GMP_PROG_CC_WORKS_PART],
+[GMP_PROG_CC_WORKS_PART_MAIN([$1],[$2],
+[$3]
+[int main () { return 0; }])
+])
+
+dnl Called: GMP_PROG_CC_WORKS_PART_MAIN(CC+CFLAGS,FAIL-MESSAGE,CODE)
+dnl CODE must include a main().
+dnl
+AC_DEFUN([GMP_PROG_CC_WORKS_PART_MAIN],
+[GMP_PROG_CC_WORKS_PART_TEST([$1],[$2],[$3],
+ [],
+ gmp_prog_cc_works="no[]m4_if([$2],,,[[, ]])[$2]",
+ gmp_prog_cc_works="no[]m4_if([$2],,,[[, ]])[$2][[, program does not run]]")
+])
+
+dnl Called: GMP_PROG_CC_WORKS_PART_TEST(CC+CFLAGS,TITLE,[CODE],
+dnl [ACTION-GOOD],[ACTION-BAD][ACTION-NORUN])
+dnl
+AC_DEFUN([GMP_PROG_CC_WORKS_PART_TEST],
+[if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+[$3]
+EOF
+ echo "Test compile: [$2]" >&AC_FD_CC
+ gmp_compile="$1 conftest.c >&AC_FD_CC"
+ if AC_TRY_EVAL(gmp_compile); then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if AC_TRY_COMMAND([./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest]); then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+ $4
+ ;;
+ no)
+ $5
+ ;;
+ norun)
+ $6
+ ;;
+ esac
+fi
+])
+
+
+dnl GMP_PROG_CC_WORKS_LONGLONG(cc+cflags,[ACTION-YES][,ACTION-NO])
+dnl --------------------------------------------------------------
+dnl Check that cc+cflags accepts "long long".
+dnl
+dnl This test is designed to be run repeatedly with different cc+cflags
+dnl selections, so the result is not cached.
+
+AC_DEFUN([GMP_PROG_CC_WORKS_LONGLONG],
+[AC_MSG_CHECKING([compiler $1 has long long])
+cat >conftest.c <<EOF
+long long foo;
+long long bar () { return foo; }
+int main () { return 0; }
+EOF
+gmp_prog_cc_works=no
+gmp_compile="$1 -c conftest.c >&AC_FD_CC"
+if AC_TRY_EVAL(gmp_compile); then
+ gmp_prog_cc_works=yes
+else
+ echo "failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+AC_MSG_RESULT($gmp_prog_cc_works)
+if test $gmp_prog_cc_works = yes; then
+ ifelse([$2],,:,[$2])
+else
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_C_TEST_SIZEOF(cc/cflags,test,[ACTION-GOOD][,ACTION-BAD])
+dnl ------------------------------------------------------------
+dnl The given cc/cflags compiler is run to check the size of a type
+dnl specified by the "test" argument. "test" can either be a string, or a
+dnl variable like $foo. The value should be for instance "sizeof-long-4",
+dnl to test that sizeof(long)==4.
+dnl
+dnl This test is designed to be run for different compiler and/or flags
+dnl combinations, so the result is not cached.
+dnl
+dnl The idea for making an array that has a negative size if the desired
+dnl condition test is false comes from autoconf AC_CHECK_SIZEOF. The cast
+dnl to "long" in the array dimension also follows autoconf, apparently it's
+dnl a workaround for a HP compiler bug.
+
+AC_DEFUN([GMP_C_TEST_SIZEOF],
+[echo "configure: testlist $2" >&AC_FD_CC
+[gmp_sizeof_type=`echo "$2" | sed 's/sizeof-\([a-z]*\).*/\1/'`]
+[gmp_sizeof_want=`echo "$2" | sed 's/sizeof-[a-z]*-\([0-9]*\).*/\1/'`]
+AC_MSG_CHECKING([compiler $1 has sizeof($gmp_sizeof_type)==$gmp_sizeof_want])
+cat >conftest.c <<EOF
+[int
+main ()
+{
+ static int test_array [1 - 2 * (long) (sizeof ($gmp_sizeof_type) != $gmp_sizeof_want)];
+ test_array[0] = 0;
+ return 0;
+}]
+EOF
+gmp_c_testlist_sizeof=no
+gmp_compile="$1 -c conftest.c >&AC_FD_CC"
+if AC_TRY_EVAL(gmp_compile); then
+ gmp_c_testlist_sizeof=yes
+fi
+rm -f conftest*
+AC_MSG_RESULT($gmp_c_testlist_sizeof)
+if test $gmp_c_testlist_sizeof = yes; then
+ ifelse([$3],,:,[$3])
+else
+ ifelse([$4],,:,[$4])
+fi
+])
+
+
+dnl GMP_PROG_CC_IS_GNU(CC,[ACTIONS-IF-YES][,ACTIONS-IF-NO])
+dnl -------------------------------------------------------
+dnl Determine whether the given compiler is GNU C.
+dnl
+dnl This test is the same as autoconf _AC_LANG_COMPILER_GNU, but doesn't
+dnl cache the result. The same "ifndef" style test is used, to avoid
+dnl problems with syntax checking cpp's used on NeXT and Apple systems.
+
+AC_DEFUN([GMP_PROG_CC_IS_GNU],
+[cat >conftest.c <<EOF
+#if ! defined (__GNUC__) || defined (__INTEL_COMPILER)
+ choke me
+#endif
+EOF
+gmp_compile="$1 -c conftest.c >&AC_FD_CC"
+if AC_TRY_EVAL(gmp_compile); then
+ rm -f conftest*
+ AC_MSG_CHECKING([whether $1 is gcc])
+ AC_MSG_RESULT(yes)
+ ifelse([$2],,:,[$2])
+else
+ rm -f conftest*
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_PROG_CC_IS_XLC(CC,[ACTIONS-IF-YES][,ACTIONS-IF-NO])
+dnl -------------------------------------------------------
+dnl Determine whether the given compiler is IBM xlc (on AIX).
+dnl
+dnl There doesn't seem to be a preprocessor symbol to test for this, or if
+dnl there is one then it's well hidden in xlc 3.1 on AIX 4.3, so just grep
+dnl the man page printed when xlc is invoked with no arguments.
+
+AC_DEFUN([GMP_PROG_CC_IS_XLC],
+[gmp_command="$1 2>&1 | grep xlc >/dev/null"
+if AC_TRY_EVAL(gmp_command); then
+ AC_MSG_CHECKING([whether $1 is xlc])
+ AC_MSG_RESULT(yes)
+ ifelse([$2],,:,[$2])
+else
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_PROG_CC_X86_GOT_EAX_EMITTED(CC+CFLAGS, [ACTION-YES] [, ACTION-NO])
+dnl ----------------------------------------------------------------------
+dnl Determine whether CC+CFLAGS emits instructions using %eax with
+dnl _GLOBAL_OFFSET_TABLE_. This test is for use on x86 systems.
+dnl
+dnl Recent versions of gcc will use %eax for the GOT in leaf functions, for
+dnl instance gcc 3.3.3 with -O3. This avoids having to save and restore
+dnl %ebx which otherwise usually holds the GOT, and is what gcc used in the
+dnl past.
+dnl
+dnl %ecx and %edx are also candidates for this sort of optimization, and
+dnl are used under lesser optimization levels, like -O2 in 3.3.3. FIXME:
+dnl It's not quite clear what the conditions for using %eax are, we might
+dnl need more test code to provoke it.
+dnl
+dnl The motivation for this test is that past versions of gas have bugs
+dnl affecting this usage, see GMP_ASM_X86_GOT_EAX_OK.
+dnl
+dnl This test is not specific to gcc, other compilers might emit %eax GOT
+dnl insns like this, though we've not investigated that.
+dnl
+dnl This is for use by compiler probing in GMP_PROG_CC_WORKS, so we doesn't
+dnl cache the result.
+dnl
+dnl -fPIC is hard coded here, because this test is for use before libtool
+dnl has established the pic options. It's right for gcc, but perhaps not
+dnl other compilers.
+
+AC_DEFUN([GMP_PROG_CC_X86_GOT_EAX_EMITTED],
+[echo "Testing gcc GOT with eax emitted" >&AC_FD_CC
+cat >conftest.c <<\EOF
+[int foo;
+int bar () { return foo; }
+]EOF
+tmp_got_emitted=no
+gmp_compile="$1 -fPIC -S conftest.c >&AC_FD_CC 2>&1"
+if AC_TRY_EVAL(gmp_compile); then
+ if grep "addl.*_GLOBAL_OFFSET_TABLE_.*eax" conftest.s >/dev/null; then
+ tmp_got_emitted=yes
+ fi
+fi
+rm -f conftest.*
+echo "Result: $tmp_got_emitted" >&AC_FD_CC
+if test "$tmp_got_emitted" = yes; then
+ ifelse([$2],,:,[$2])
+else
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_HPC_HPPA_2_0(cc,[ACTION-IF-GOOD][,ACTION-IF-BAD])
+dnl ---------------------------------------------------------
+dnl Find out whether a HP compiler is good enough to generate hppa 2.0.
+dnl
+dnl This test might be repeated for different compilers, so the result is
+dnl not cached.
+
+AC_DEFUN([GMP_HPC_HPPA_2_0],
+[AC_MSG_CHECKING([whether HP compiler $1 is good for 64-bits])
+# Bad compiler output:
+# ccom: HP92453-01 G.10.32.05 HP C Compiler
+# Good compiler output:
+# ccom: HP92453-01 A.10.32.30 HP C Compiler
+# Let A.10.32.30 or higher be ok.
+echo >conftest.c
+gmp_tmp_vs=`$1 $2 -V -c -o conftest.$OBJEXT conftest.c 2>&1 | grep "^ccom:"`
+echo "Version string: $gmp_tmp_vs" >&AC_FD_CC
+rm conftest*
+gmp_tmp_v1=`echo $gmp_tmp_vs | sed 's/.* .\.\([[0-9]]*\).*/\1/'`
+gmp_tmp_v2=`echo $gmp_tmp_vs | sed 's/.* .\..*\.\(.*\)\..* HP C.*/\1/'`
+gmp_tmp_v3=`echo $gmp_tmp_vs | sed 's/.* .\..*\..*\.\(.*\) HP C.*/\1/'`
+echo "Version number: $gmp_tmp_v1.$gmp_tmp_v2.$gmp_tmp_v3" >&AC_FD_CC
+if test -z "$gmp_tmp_v1"; then
+ gmp_hpc_64bit=not-applicable
+else
+ GMP_COMPARE_GE($gmp_tmp_v1, 10, $gmp_tmp_v2, 32, $gmp_tmp_v3, 30)
+ gmp_hpc_64bit=$gmp_compare_ge
+fi
+AC_MSG_RESULT($gmp_hpc_64bit)
+if test $gmp_hpc_64bit = yes; then
+ ifelse([$2],,:,[$2])
+else
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_GCC_ARM_UMODSI(CC,[ACTIONS-IF-GOOD][,ACTIONS-IF-BAD])
+dnl ---------------------------------------------------------
+dnl gcc 2.95.3 and earlier on arm has a bug in the libgcc __umodsi routine
+dnl making "%" give wrong results for some operands, eg. "0x90000000 % 3".
+dnl We're hoping it'll be fixed in 2.95.4, and we know it'll be fixed in
+dnl gcc 3.
+dnl
+dnl There's only a couple of places gmp cares about this, one is the
+dnl size==1 case in mpn/generic/mode1o.c, and this shows up in
+dnl tests/mpz/t-jac.c as a wrong result from mpz_kronecker_ui.
+
+AC_DEFUN([GMP_GCC_ARM_UMODSI],
+[AC_MSG_CHECKING([whether ARM gcc unsigned division works])
+tmp_version=`$1 --version`
+echo "$tmp_version" >&AC_FD_CC
+case $tmp_version in
+ [2.95 | 2.95.[123]])
+ ifelse([$3],,:,[$3])
+ gmp_gcc_arm_umodsi_result=["no, gcc 2.95.[0123]"] ;;
+ *)
+ ifelse([$2],,:,[$2])
+ gmp_gcc_arm_umodsi_result=yes ;;
+esac
+AC_MSG_RESULT([$gmp_gcc_arm_umodsi_result])
+])
+
+
+dnl GMP_GCC_MIPS_O32(gcc,[actions-yes][,[actions-no]])
+dnl -------------------------------------------------
+dnl Test whether gcc supports o32.
+dnl
+dnl gcc 2.7.2.2 only does o32, and doesn't accept -mabi=32.
+dnl
+dnl gcc 2.95 accepts -mabi=32 but it only works on irix5, on irix6 it gives
+dnl "cc1: The -mabi=32 support does not work yet".
+
+AC_DEFUN([GMP_GCC_MIPS_O32],
+[AC_MSG_CHECKING([whether gcc supports o32])
+echo 'int x;' >conftest.c
+echo "$1 -mabi=32 -c conftest.c" >&AC_FD_CC
+if $1 -mabi=32 -c conftest.c >conftest.out 2>&1; then
+ result=yes
+else
+ cat conftest.out >&AC_FD_CC
+ if grep "cc1: Invalid option \`abi=32'" conftest.out >/dev/null; then
+ result=yes
+ else
+ result=no
+ fi
+fi
+rm -f conftest.*
+AC_MSG_RESULT($result)
+if test $result = yes; then
+ ifelse([$2],,:,[$2])
+else
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_GCC_NO_CPP_PRECOMP(CCBASE,CC,CFLAGS,[ACTIONS-YES][,ACTIONS-NO])
+dnl -------------------------------------------------------------------
+dnl Check whether -no-cpp-precomp should be used on this compiler, and
+dnl execute the corresponding ACTIONS-YES or ACTIONS-NO.
+dnl
+dnl -no-cpp-precomp is only meant for Apple's hacked version of gcc found
+dnl on powerpc*-*-darwin*, but we can give it a try on any gcc. Normal gcc
+dnl (as of 3.0 at least) only gives a warning, not an actual error, and we
+dnl watch for that and decide against the option in that case, to avoid
+dnl confusing the user.
+
+AC_DEFUN([GMP_GCC_NO_CPP_PRECOMP],
+[if test "$ccbase" = gcc; then
+ AC_MSG_CHECKING([compiler $2 $3 -no-cpp-precomp])
+ result=no
+ cat >conftest.c <<EOF
+int main () { return 0; }
+EOF
+ gmp_compile="$2 $3 -no-cpp-precomp conftest.c >conftest.out 2>&1"
+ if AC_TRY_EVAL(gmp_compile); then
+ if grep "unrecognized option.*-no-cpp-precomp" conftest.out >/dev/null; then : ;
+ else
+ result=yes
+ fi
+ fi
+ cat conftest.out >&AC_FD_CC
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ AC_MSG_RESULT($result)
+ if test "$result" = yes; then
+ ifelse([$4],,:,[$4])
+ else
+ ifelse([$5],,:,[$5])
+ fi
+fi
+])
+
+
+dnl GMP_GCC_PENTIUM4_SSE2(CC+CFLAGS,[ACTION-IF-YES][,ACTION-IF-NO])
+dnl ---------------------------------------------------------------
+dnl Determine whether gcc CC+CFLAGS is a good enough version for
+dnl -march=pentium4 with sse2.
+dnl
+dnl Gcc 3.2.1 was seen generating incorrect code for raw double -> int
+dnl conversions through a union. We believe the problem is in all 3.1 and
+dnl 3.2 versions, but that it's fixed in 3.3.
+
+AC_DEFUN([GMP_GCC_PENTIUM4_SSE2],
+[AC_MSG_CHECKING([whether gcc is good for sse2])
+case `$1 -dumpversion` in
+ [3.[012] | 3.[012].*]) result=no ;;
+ *) result=yes ;;
+esac
+AC_MSG_RESULT($result)
+if test "$result" = yes; then
+ ifelse([$2],,:,[$2])
+else
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_GCC_WA_MCPU(CC+CFLAGS, NEWFLAG [,ACTION-YES [,ACTION-NO]])
+dnl --------------------------------------------------------------
+dnl Check whether gcc (or gas rather) accepts a flag like "-Wa,-mev67".
+dnl
+dnl Gas doesn't give an error for an unknown cpu, it only prints a warning
+dnl like "Warning: Unknown CPU identifier `ev78'".
+dnl
+dnl This is intended for use on alpha, since only recent versions of gas
+dnl accept -mev67, but there's nothing here that's alpha specific.
+
+AC_DEFUN([GMP_GCC_WA_MCPU],
+[AC_MSG_CHECKING([assembler $1 $2])
+result=no
+cat >conftest.c <<EOF
+int main () {}
+EOF
+gmp_compile="$1 $2 -c conftest.c >conftest.out 2>&1"
+if AC_TRY_EVAL(gmp_compile); then
+ if grep "Unknown CPU identifier" conftest.out >/dev/null; then : ;
+ else
+ result=yes
+ fi
+fi
+cat conftest.out >&AC_FD_CC
+rm -f conftest*
+AC_MSG_RESULT($result)
+if test "$result" = yes; then
+ ifelse([$3],,:,[$3])
+else
+ ifelse([$4],,:,[$4])
+fi
+])
+
+
+dnl GMP_GCC_WA_OLDAS(CC+CFLAGS [,ACTION-YES [,ACTION-NO]])
+dnl ------------------------------------------------------
+dnl Check whether gcc should be run with "-Wa,-oldas".
+dnl
+dnl On systems alpha*-*-osf* (or maybe just osf5), apparently there's a
+dnl newish Compaq "as" which doesn't work with the gcc mips-tfile.
+dnl Compiling an empty file with "gcc -c foo.c" produces for instance
+dnl
+dnl mips-tfile, /tmp/ccaqUNnF.s:7 Segmentation fault
+dnl
+dnl The fix is to pass "-oldas" to that assembler, as noted by
+dnl
+dnl http://gcc.gnu.org/install/specific.html#alpha*-dec-osf*
+dnl
+dnl The test here tries to compile an empty file, and if that fails but
+dnl adding -Wa,-oldas makes it succeed, then that flag is considered
+dnl necessary.
+dnl
+dnl We look for the failing case specifically, since it may not be a good
+dnl idea to use -Wa,-oldas in other circumstances. For instance gas takes
+dnl "-oldas" to mean the "-o" option and will write a file called "ldas" as
+dnl its output. Normally gcc puts its own "-o" after any -Wa options, so
+dnl -oldas ends up being harmless, but clearly that's only through good
+dnl luck.
+dnl
+dnl This macro is designed for use while probing for a good compiler, and
+dnl so doesn't cache it's result.
+
+AC_DEFUN([GMP_GCC_WA_OLDAS],
+[AC_MSG_CHECKING([for $1 -Wa,-oldas])
+result=no
+cat >conftest.c <<EOF
+EOF
+echo "with empty conftest.c" >&AC_FD_CC
+gmp_compile="$1 -c conftest.c >&AC_FD_CC 2>&1"
+if AC_TRY_EVAL(gmp_compile); then : ;
+else
+ # empty fails
+ gmp_compile="$1 -Wa,-oldas -c conftest.c >&AC_FD_CC 2>&1"
+ if AC_TRY_EVAL(gmp_compile); then
+ # but with -Wa,-oldas it works
+ result=yes
+ fi
+fi
+rm -f conftest*
+AC_MSG_RESULT($result)
+if test "$result" = yes; then
+ ifelse([$2],,:,[$2])
+else
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_OS_X86_XMM(CC+CFLAGS,[ACTION-IF-YES][,ACTION-IF-NO])
+dnl --------------------------------------------------------
+dnl Determine whether the operating system supports XMM registers.
+dnl
+dnl If build==host then a test program is run, executing an SSE2
+dnl instruction using an XMM register. This will give a SIGILL if the
+dnl system hasn't set the OSFXSR bit in CR4 to say it knows it must use
+dnl fxsave/fxrestor in a context switch (to save xmm registers).
+dnl
+dnl If build!=host, we can fallback on:
+dnl
+dnl - FreeBSD version 4 is the first supporting xmm.
+dnl
+dnl - Linux kernel 2.4 might be the first stable series supporting xmm
+dnl (not sure). But there's no version number in the GNU/Linux
+dnl config tuple to test anyway.
+dnl
+dnl The default is to allow xmm. This might seem rash, but it's likely
+dnl most systems know xmm by now, so this will normally be what's wanted.
+dnl And cross compiling is a bit hairy anyway, so hopefully anyone doing it
+dnl will be smart enough to know what to do.
+dnl
+dnl In the test program, .text and .globl are hard coded because this macro
+dnl is wanted before GMP_ASM_TEXT and GMP_ASM_GLOBL are run. A .byte
+dnl sequence is used (for xorps %xmm0, %xmm0) to make us independent of
+dnl tests for whether the assembler supports sse2/xmm. Obviously we need
+dnl both assembler and OS support, but this means we don't force the order
+dnl in which we test.
+dnl
+dnl FIXME: Maybe we should use $CCAS to assemble, if it's set. (Would
+dnl still want $CC/$CFLAGS for the link.) But this test is used before
+dnl AC_PROG_CC sets $OBJEXT, so we'd need to check for various object file
+dnl suffixes ourselves.
+
+AC_DEFUN([GMP_OS_X86_XMM],
+[AC_CACHE_CHECK([whether the operating system supports XMM registers],
+ gmp_cv_os_x86_xmm,
+[if test "$build" = "$host"; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.s <<EOF
+ .text
+main:
+_main:
+ .globl main
+ .globl _main
+ .byte 0x0f, 0x57, 0xc0
+ xorl %eax, %eax
+ ret
+EOF
+ gmp_compile="$1 conftest.s -o conftest >&AC_FD_CC"
+ if AC_TRY_EVAL(gmp_compile); then
+ if AC_TRY_COMMAND([./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest]); then
+ gmp_cv_os_x86_xmm=yes
+ else
+ gmp_cv_os_x86_xmm=no
+ fi
+ else
+ AC_MSG_WARN([Oops, cannot compile test program])
+ fi
+ rm -f conftest*
+fi
+
+if test -z "$gmp_cv_os_x86_xmm"; then
+ case $host_os in
+ [freebsd[123] | freebsd[123].*])
+ gmp_cv_os_x86_xmm=no ;;
+ freebsd*)
+ gmp_cv_os_x86_xmm=yes ;;
+ *)
+ gmp_cv_os_x86_xmm=probably ;;
+ esac
+fi
+])
+
+if test "$gmp_cv_os_x86_xmm" = probably; then
+ AC_MSG_WARN([Not certain of OS support for xmm when cross compiling.])
+ AC_MSG_WARN([Will assume it's ok, expect a SIGILL if this is wrong.])
+fi
+
+case $gmp_cv_os_x86_xmm in
+no)
+ $3
+ ;;
+*)
+ $2
+ ;;
+esac
+])
+
+
+dnl GMP_CRAY_HOST_TYPES(C90/T90-IEEE, C90/T90-CFP, J90/SV1)
+dnl -------------------------------------------------------
+dnl Execute the actions in the arguments on the respective Cray vector
+dnl systems. For other hosts, do nothing.
+dnl
+dnl This macro should be used after the C compiler has been chosen, since
+dnl on c90 and t90 we ask the compiler whether we're in IEEE or CFP float
+dnl mode.
+dnl
+dnl This code is in a macro so that any AC_REQUIRE pre-requisites of
+dnl AC_EGREP_CPP will be expanded at the top-level, ie. for all hosts not
+dnl merely c90 and t90. In autoconf 2.57 for instance this means
+dnl AC_PROG_EGREP, which is needed by various other macros.
+
+AC_DEFUN([GMP_CRAY_OPTIONS],
+[case $host_cpu in
+ c90 | t90)
+ AC_EGREP_CPP(yes,
+[#ifdef _CRAYIEEE
+yes
+#endif],
+ [$1],
+ [$2])
+ ;;
+ j90 | sv1)
+ [$3]
+ ;;
+esac
+])
+
+
+dnl GMP_HPPA_LEVEL_20(cc/cflags [, ACTION-GOOD [,ACTION-BAD]])
+dnl ----------------------------------------------------------
+dnl Check that the given cc/cflags accepts HPPA 2.0n assembler code.
+dnl
+dnl Old versions of gas don't know 2.0 instructions. It rejects ".level
+dnl 2.0" for a start, so just test that.
+dnl
+dnl This test is designed to be run for various different compiler and
+dnl flags combinations, and hence doesn't cache its result.
+
+AC_DEFUN([GMP_HPPA_LEVEL_20],
+[AC_MSG_CHECKING([$1 assembler knows hppa 2.0])
+result=no
+cat >conftest.s <<EOF
+ .level 2.0
+EOF
+gmp_compile="$1 -c conftest.s >&AC_FD_CC 2>&1"
+if AC_TRY_EVAL(gmp_compile); then
+ result=yes
+else
+ echo "failed program was" >&AC_FD_CC
+ cat conftest.s >&AC_FD_CC
+fi
+rm -f conftest*
+AC_MSG_RESULT($result)
+if test "$result" = yes; then
+ ifelse([$2],,:,[$2])
+else
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_PROG_CXX_WORKS(cxx/cxxflags [, ACTION-YES [,ACTION-NO]])
+dnl ------------------------------------------------------------
+dnl Check whether cxx/cxxflags can compile and link.
+dnl
+dnl This test is designed to be run repeatedly with different cxx/cxxflags
+dnl selections, so the result is not cached.
+dnl
+dnl For a native build, we insist on being able to run the program, so as
+dnl to detect any problems with the standard C++ library. During
+dnl development various systems with broken or incomplete C++ installations
+dnl were seen.
+dnl
+dnl The various features and problems we try to detect are done in separate
+dnl compiles. Although this is probably a bit slower than one test
+dnl program, it makes it easy to indicate the problem in AC_MSG_RESULT,
+dnl hence giving the user a clue about why we rejected the compiler.
+
+AC_DEFUN([GMP_PROG_CXX_WORKS],
+[AC_MSG_CHECKING([C++ compiler $1])
+gmp_prog_cxx_works=yes
+
+# start with a plain "main()", then go on to further checks
+GMP_PROG_CXX_WORKS_PART([$1], [])
+
+GMP_PROG_CXX_WORKS_PART([$1], [namespace],
+[namespace foo { }
+using namespace foo;
+])
+
+# GMP requires the standard C++ iostream classes
+GMP_PROG_CXX_WORKS_PART([$1], [std iostream],
+[/* This test rejects g++ 2.7.2 which doesn't have <iostream>, only a
+ pre-standard iostream.h. */
+#include <iostream>
+
+/* This test rejects OSF 5.1 Compaq C++ in its default pre-standard iostream
+ mode, since that mode puts cout in the global namespace, not "std". */
+void someoutput (void) { std::cout << 123; }
+])
+
+AC_MSG_RESULT($gmp_prog_cxx_works)
+case $gmp_prog_cxx_works in
+ yes)
+ [$2]
+ ;;
+ *)
+ [$3]
+ ;;
+esac
+])
+
+dnl Called: GMP_PROG_CXX_WORKS_PART(CXX+CXXFLAGS, FAIL-MESSAGE [,CODE])
+dnl
+AC_DEFUN([GMP_PROG_CXX_WORKS_PART],
+[if test "$gmp_prog_cxx_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.cc <<EOF
+[$3]
+int main (void) { return 0; }
+EOF
+ echo "Test compile: [$2]" >&AC_FD_CC
+ gmp_cxxcompile="$1 conftest.cc >&AC_FD_CC"
+ if AC_TRY_EVAL(gmp_cxxcompile); then
+ if test "$cross_compiling" = no; then
+ if AC_TRY_COMMAND([./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest]); then :;
+ else
+ gmp_prog_cxx_works="no[]m4_if([$2],,,[, ])[$2], program does not run"
+ fi
+ fi
+ else
+ gmp_prog_cxx_works="no[]m4_if([$2],,,[, ])[$2]"
+ fi
+ case $gmp_prog_cxx_works in
+ no*)
+ echo "failed program was:" >&AC_FD_CC
+ cat conftest.cc >&AC_FD_CC
+ ;;
+ esac
+ rm -f conftest* a.out b.out a.exe a_out.exe
+fi
+])
+
+
+dnl GMP_INIT([M4-DEF-FILE])
+dnl -----------------------
+dnl Initializations for GMP config.m4 generation.
+dnl
+dnl FIXME: The generated config.m4 doesn't get recreated by config.status.
+dnl Maybe the relevant "echo"s should go through AC_CONFIG_COMMANDS.
+
+AC_DEFUN([GMP_INIT],
+[ifelse([$1], , gmp_configm4=config.m4, gmp_configm4="[$1]")
+gmp_tmpconfigm4=cnfm4.tmp
+gmp_tmpconfigm4i=cnfm4i.tmp
+gmp_tmpconfigm4p=cnfm4p.tmp
+rm -f $gmp_tmpconfigm4 $gmp_tmpconfigm4i $gmp_tmpconfigm4p
+
+# CONFIG_TOP_SRCDIR is a path from the mpn builddir to the top srcdir.
+# The pattern here tests for an absolute path the same way as
+# _AC_OUTPUT_FILES in autoconf acgeneral.m4.
+case $srcdir in
+[[\\/]]* | ?:[[\\/]]* ) tmp="$srcdir" ;;
+*) tmp="../$srcdir" ;;
+esac
+echo ["define(<CONFIG_TOP_SRCDIR>,<\`$tmp'>)"] >>$gmp_tmpconfigm4
+
+# All CPUs use asm-defs.m4
+echo ["include][(CONFIG_TOP_SRCDIR\`/mpn/asm-defs.m4')"] >>$gmp_tmpconfigm4i
+])
+
+
+dnl GMP_FINISH
+dnl ----------
+dnl Create config.m4 from its accumulated parts.
+dnl
+dnl __CONFIG_M4_INCLUDED__ is used so that a second or subsequent include
+dnl of config.m4 is harmless.
+dnl
+dnl A separate ifdef on the angle bracket quoted part ensures the quoting
+dnl style there is respected. The basic defines from gmp_tmpconfigm4 are
+dnl fully quoted but are still put under an ifdef in case any have been
+dnl redefined by one of the m4 include files.
+dnl
+dnl Doing a big ifdef within asm-defs.m4 and/or other macro files wouldn't
+dnl work, since it'd interpret parentheses and quotes in dnl comments, and
+dnl having a whole file as a macro argument would overflow the string space
+dnl on BSD m4.
+
+AC_DEFUN([GMP_FINISH],
+[AC_REQUIRE([GMP_INIT])
+echo "creating $gmp_configm4"
+echo ["d""nl $gmp_configm4. Generated automatically by configure."] > $gmp_configm4
+if test -f $gmp_tmpconfigm4; then
+ echo ["changequote(<,>)"] >> $gmp_configm4
+ echo ["ifdef(<__CONFIG_M4_INCLUDED__>,,<"] >> $gmp_configm4
+ cat $gmp_tmpconfigm4 >> $gmp_configm4
+ echo [">)"] >> $gmp_configm4
+ echo ["changequote(\`,')"] >> $gmp_configm4
+ rm $gmp_tmpconfigm4
+fi
+echo ["ifdef(\`__CONFIG_M4_INCLUDED__',,\`"] >> $gmp_configm4
+if test -f $gmp_tmpconfigm4i; then
+ cat $gmp_tmpconfigm4i >> $gmp_configm4
+ rm $gmp_tmpconfigm4i
+fi
+if test -f $gmp_tmpconfigm4p; then
+ cat $gmp_tmpconfigm4p >> $gmp_configm4
+ rm $gmp_tmpconfigm4p
+fi
+echo ["')"] >> $gmp_configm4
+echo ["define(\`__CONFIG_M4_INCLUDED__')"] >> $gmp_configm4
+])
+
+
+dnl GMP_INCLUDE_MPN(FILE)
+dnl ---------------------
+dnl Add an include_mpn(`FILE') to config.m4. FILE should be a path
+dnl relative to the mpn source directory, for example
+dnl
+dnl GMP_INCLUDE_MPN(`x86/x86-defs.m4')
+dnl
+
+AC_DEFUN([GMP_INCLUDE_MPN],
+[AC_REQUIRE([GMP_INIT])
+echo ["include_mpn(\`$1')"] >> $gmp_tmpconfigm4i
+])
+
+
+dnl GMP_DEFINE(MACRO, DEFINITION [, LOCATION])
+dnl ------------------------------------------
+dnl Define M4 macro MACRO as DEFINITION in temporary file.
+dnl
+dnl If LOCATION is `POST', the definition will appear after any include()
+dnl directives inserted by GMP_INCLUDE. Mind the quoting! No shell
+dnl variables will get expanded. Don't forget to invoke GMP_FINISH to
+dnl create file config.m4. config.m4 uses `<' and '>' as quote characters
+dnl for all defines.
+
+AC_DEFUN([GMP_DEFINE],
+[AC_REQUIRE([GMP_INIT])
+echo ['define(<$1>, <$2>)'] >>ifelse([$3], [POST],
+ $gmp_tmpconfigm4p, $gmp_tmpconfigm4)
+])
+
+
+dnl GMP_DEFINE_RAW(STRING [, LOCATION])
+dnl ------------------------------------
+dnl Put STRING into config.m4 file.
+dnl
+dnl If LOCATION is `POST', the definition will appear after any include()
+dnl directives inserted by GMP_INCLUDE. Don't forget to invoke GMP_FINISH
+dnl to create file config.m4.
+
+AC_DEFUN([GMP_DEFINE_RAW],
+[AC_REQUIRE([GMP_INIT])
+echo [$1] >> ifelse([$2], [POST], $gmp_tmpconfigm4p, $gmp_tmpconfigm4)
+])
+
+
+dnl GMP_TRY_ASSEMBLE(asm-code,[action-success][,action-fail])
+dnl ----------------------------------------------------------
+dnl Attempt to assemble the given code.
+dnl Do "action-success" if this succeeds, "action-fail" if not.
+dnl
+dnl conftest.o and conftest.out are available for inspection in
+dnl "action-success". If either action does a "break" out of a loop then
+dnl an explicit "rm -f conftest*" will be necessary.
+dnl
+dnl This is not unlike AC_TRY_COMPILE, but there's no default includes or
+dnl anything in "asm-code", everything wanted must be given explicitly.
+
+AC_DEFUN([GMP_TRY_ASSEMBLE],
+[cat >conftest.s <<EOF
+[$1]
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if AC_TRY_EVAL(gmp_assemble); then
+ cat conftest.out >&AC_FD_CC
+ ifelse([$2],,:,[$2])
+else
+ cat conftest.out >&AC_FD_CC
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.s >&AC_FD_CC
+ ifelse([$3],,:,[$3])
+fi
+rm -f conftest*
+])
+
+
+dnl Checks whether the stack can be marked nonexecutable by passing an option
+dnl to the C-compiler when acting on .s files. Appends that option to ASFLAGS.
+dnl This macro is adapted from one found in GLIBC-2.3.5.
+AC_DEFUN([CL_AS_NOEXECSTACK],[
+dnl AC_REQUIRE([AC_PROG_CC]) GMP uses something else
+AC_CACHE_CHECK([whether assembler supports --noexecstack option],
+cl_cv_as_noexecstack, [dnl
+ cat > conftest.c <<EOF
+void foo() {}
+EOF
+ if AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS
+ -S -o conftest.s conftest.c >/dev/null]) \
+ && grep .note.GNU-stack conftest.s >/dev/null \
+ && AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS -Wa,--noexecstack
+ -c -o conftest.o conftest.s >/dev/null])
+ then
+ cl_cv_as_noexecstack=yes
+ else
+ cl_cv_as_noexecstack=no
+ fi
+ rm -f conftest*])
+ if test "$cl_cv_as_noexecstack" = yes; then
+ ASMFLAGS="$ASMFLAGS -Wa,--noexecstack"
+ fi
+ AC_SUBST(ASMFLAGS)
+])
+
+
+dnl GMP_ASM_LABEL_SUFFIX
+dnl --------------------
+dnl : - is usual.
+dnl empty - hppa on HP-UX doesn't use a :, just the label name
+dnl
+dnl Note that it's necessary to test the empty case first, since HP "as"
+dnl will accept "somelabel:", and take it to mean a label with a name that
+dnl happens to end in a colon.
+
+AC_DEFUN([GMP_ASM_LABEL_SUFFIX],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([for assembler label suffix],
+ gmp_cv_asm_label_suffix,
+[gmp_cv_asm_label_suffix=unknown
+for i in "" ":"; do
+ echo "trying $i" >&AC_FD_CC
+ GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+somelabel$i],
+ [gmp_cv_asm_label_suffix=$i
+ rm -f conftest*
+ break],
+ [cat conftest.out >&AC_FD_CC])
+done
+if test "$gmp_cv_asm_label_suffix" = "unknown"; then
+ AC_MSG_ERROR([Cannot determine label suffix])
+fi
+])
+echo ["define(<LABEL_SUFFIX>, <$gmp_cv_asm_label_suffix>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_ASM_UNDERSCORE
+dnl ------------------
+dnl Determine whether global symbols need to be prefixed with an underscore.
+dnl The output from "nm" is grepped to see what a typical symbol looks like.
+dnl
+dnl This test used to grep the .o file directly, but that failed with greps
+dnl that don't like binary files (eg. SunOS 4).
+dnl
+dnl This test also used to construct an assembler file with and without an
+dnl underscore and try to link that to a C file, to see which worked.
+dnl Although that's what will happen in the real build we don't really want
+dnl to depend on creating asm files within configure for every possible CPU
+dnl (or at least we don't want to do that more than we have to).
+dnl
+dnl The fallback on no underscore is based on the assumption that the world
+dnl is moving towards non-underscore systems. There should actually be no
+dnl good reason for nm to fail though.
+
+AC_DEFUN([GMP_ASM_UNDERSCORE],
+[AC_REQUIRE([GMP_PROG_NM])
+AC_CACHE_CHECK([if globals are prefixed by underscore],
+ gmp_cv_asm_underscore,
+[gmp_cv_asm_underscore="unknown"
+cat >conftest.c <<EOF
+int gurkmacka;
+EOF
+gmp_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >&AC_FD_CC"
+if AC_TRY_EVAL(gmp_compile); then
+ $NM conftest.$OBJEXT >conftest.out
+ if grep _gurkmacka conftest.out >/dev/null; then
+ gmp_cv_asm_underscore=yes
+ elif grep gurkmacka conftest.out >/dev/null; then
+ gmp_cv_asm_underscore=no
+ else
+ echo "configure: $NM doesn't have gurkmacka:" >&AC_FD_CC
+ cat conftest.out >&AC_FD_CC
+ fi
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+fi
+rm -f conftest*
+])
+case $gmp_cv_asm_underscore in
+ yes)
+ GMP_DEFINE(GSYM_PREFIX, [_]) ;;
+ no)
+ GMP_DEFINE(GSYM_PREFIX, []) ;;
+ *)
+ AC_MSG_WARN([+----------------------------------------------------------])
+ AC_MSG_WARN([| Cannot determine global symbol prefix.])
+ AC_MSG_WARN([| $NM output doesn't contain a global data symbol.])
+ AC_MSG_WARN([| Will proceed with no underscore.])
+ AC_MSG_WARN([| If this is wrong then you'll get link errors referring])
+ AC_MSG_WARN([| to ___gmpn_add_n (note three underscores).])
+ AC_MSG_WARN([| In this case do a fresh build with an override,])
+ AC_MSG_WARN([| ./configure gmp_cv_asm_underscore=yes])
+ AC_MSG_WARN([+----------------------------------------------------------])
+ GMP_DEFINE(GSYM_PREFIX, [])
+ ;;
+esac
+])
+
+
+dnl GMP_ASM_ALIGN_LOG
+dnl -----------------
+dnl Is parameter to `.align' logarithmic?
+
+AC_DEFUN([GMP_ASM_ALIGN_LOG],
+[AC_REQUIRE([GMP_ASM_GLOBL])
+AC_REQUIRE([GMP_ASM_BYTE])
+AC_REQUIRE([GMP_ASM_DATA])
+AC_REQUIRE([GMP_ASM_LABEL_SUFFIX])
+AC_REQUIRE([GMP_PROG_NM])
+AC_CACHE_CHECK([if .align assembly directive is logarithmic],
+ gmp_cv_asm_align_log,
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_data
+ .align 4
+ $gmp_cv_asm_globl foo
+ $gmp_cv_asm_byte 1
+ .align 4
+foo$gmp_cv_asm_label_suffix
+ $gmp_cv_asm_byte 2],
+ [gmp_tmp_val=[`$NM conftest.$OBJEXT | grep foo | \
+ sed -e 's;[[][0-9][]]\(.*\);\1;' -e 's;[^1-9]*\([0-9]*\).*;\1;'`]
+ if test "$gmp_tmp_val" = "10" || test "$gmp_tmp_val" = "16"; then
+ gmp_cv_asm_align_log=yes
+ else
+ gmp_cv_asm_align_log=no
+ fi],
+ [AC_MSG_ERROR([cannot assemble alignment test])])])
+
+GMP_DEFINE_RAW(["define(<ALIGN_LOGARITHMIC>,<$gmp_cv_asm_align_log>)"])
+])
+
+
+dnl GMP_ASM_ALIGN_FILL_0x90
+dnl -----------------------
+dnl Determine whether a ",0x90" suffix works on a .align directive.
+dnl This is only meant for use on x86, 0x90 being a "nop".
+dnl
+dnl Old gas, eg. 1.92.3
+dnl Needs ",0x90" or else the fill is 0x00, which can't be executed
+dnl across.
+dnl
+dnl New gas, eg. 2.91
+dnl Generates multi-byte nop fills even when ",0x90" is given.
+dnl
+dnl Solaris 2.6 as
+dnl ",0x90" is not allowed, causes a fatal error.
+dnl
+dnl Solaris 2.8 as
+dnl ",0x90" does nothing, generates a warning that it's being ignored.
+dnl
+dnl SCO OpenServer 5 as
+dnl Second parameter is max bytes to fill, not a fill pattern.
+dnl ",0x90" is an error due to being bigger than the first parameter.
+dnl Multi-byte nop fills are generated in text segments.
+dnl
+dnl Note that both solaris "as"s only care about ",0x90" if they actually
+dnl have to use it to fill something, hence the .byte in the test. It's
+dnl the second .align which provokes the error or warning.
+dnl
+dnl The warning from solaris 2.8 is suppressed to stop anyone worrying that
+dnl something might be wrong.
+
+AC_DEFUN([GMP_ASM_ALIGN_FILL_0x90],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([if the .align directive accepts an 0x90 fill in .text],
+ gmp_cv_asm_align_fill_0x90,
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ .align 4, 0x90
+ .byte 0
+ .align 4, 0x90],
+[if grep "Warning: Fill parameter ignored for executable section" conftest.out >/dev/null; then
+ echo "Suppressing this warning by omitting 0x90" 1>&AC_FD_CC
+ gmp_cv_asm_align_fill_0x90=no
+else
+ gmp_cv_asm_align_fill_0x90=yes
+fi],
+[gmp_cv_asm_align_fill_0x90=no])])
+
+GMP_DEFINE_RAW(["define(<ALIGN_FILL_0x90>,<$gmp_cv_asm_align_fill_0x90>)"])
+])
+
+
+dnl GMP_ASM_BYTE
+dnl ------------
+dnl .byte - is usual.
+dnl data1 - required by ia64 (on hpux at least).
+dnl
+dnl This macro is just to support other configure tests, not any actual asm
+dnl code.
+
+AC_DEFUN([GMP_ASM_BYTE],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_REQUIRE([GMP_ASM_LABEL_SUFFIX])
+AC_CACHE_CHECK([for assembler byte directive],
+ gmp_cv_asm_byte,
+[for i in .byte data1; do
+ echo "trying $i" >&AC_FD_CC
+ GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_data
+ $i 0
+],
+ [gmp_cv_asm_byte=$i
+ rm -f conftest*
+ break],
+ [cat conftest.out >&AC_FD_CC])
+done
+if test -z "$gmp_cv_asm_byte"; then
+ AC_MSG_ERROR([Cannot determine how to emit a data byte])
+fi
+])
+])
+
+
+dnl GMP_ASM_TEXT
+dnl ------------
+dnl .text - is usual.
+dnl .code - is needed by the hppa on HP-UX (but ia64 HP-UX uses .text)
+dnl .csect .text[PR] - is for AIX.
+
+AC_DEFUN([GMP_ASM_TEXT],
+[AC_CACHE_CHECK([how to switch to text section],
+ gmp_cv_asm_text,
+[for i in ".text" ".code" [".csect .text[PR]"]; do
+ echo "trying $i" >&AC_FD_CC
+ GMP_TRY_ASSEMBLE([ $i],
+ [gmp_cv_asm_text=$i
+ rm -f conftest*
+ break])
+done
+if test -z "$gmp_cv_asm_text"; then
+ AC_MSG_ERROR([Cannot determine text section directive])
+fi
+])
+echo ["define(<TEXT>, <$gmp_cv_asm_text>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_ASM_DATA
+dnl ------------
+dnl Can we say `.data'?
+
+AC_DEFUN([GMP_ASM_DATA],
+[AC_CACHE_CHECK([how to switch to data section],
+ gmp_cv_asm_data,
+[case $host in
+ *-*-aix*) gmp_cv_asm_data=[".csect .data[RW]"] ;;
+ *) gmp_cv_asm_data=".data" ;;
+esac
+])
+echo ["define(<DATA>, <$gmp_cv_asm_data>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_ASM_RODATA
+dnl --------------
+dnl Find out how to switch to the read-only data section.
+dnl
+dnl The compiler output is grepped for the right directive. It's not
+dnl considered wise to just probe for ".section .rodata" or whatever works,
+dnl since arbitrary section names might be accepted, but not necessarily do
+dnl the right thing when they get to the linker.
+dnl
+dnl Only a few asm files use RODATA, so this code is perhaps a bit
+dnl excessive right now, but should find more uses in the future.
+dnl
+dnl FIXME: gcc on aix generates something like ".csect _foo.ro_c[RO],3"
+dnl where foo is the object file. Might need to check for that if we use
+dnl RODATA there.
+
+AC_DEFUN([GMP_ASM_RODATA],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_REQUIRE([GMP_ASM_DATA])
+AC_REQUIRE([GMP_ASM_LABEL_SUFFIX])
+AC_REQUIRE([GMP_ASM_UNDERSCORE])
+AC_CACHE_CHECK([how to switch to read-only data section],
+ gmp_cv_asm_rodata,
+[
+dnl Default to DATA on CPUs with split code/data caching, and TEXT
+dnl elsewhere. i386 means generic x86, so use DATA on it.
+case $host in
+X86_PATTERN | x86_64-*-*)
+ gmp_cv_asm_rodata="$gmp_cv_asm_data" ;;
+*)
+ gmp_cv_asm_rodata="$gmp_cv_asm_text" ;;
+esac
+
+cat >conftest.c <<EOF
+extern const int foo[[]]; /* Suppresses C++'s suppression of foo */
+const int foo[[]] = {1,2,3};
+EOF
+echo "Test program:" >&AC_FD_CC
+cat conftest.c >&AC_FD_CC
+gmp_compile="$CC $CFLAGS $CPPFLAGS -S conftest.c >&AC_FD_CC"
+if AC_TRY_EVAL(gmp_compile); then
+ echo "Compiler output:" >&AC_FD_CC
+ cat conftest.s >&AC_FD_CC
+ if test $gmp_cv_asm_underscore = yes; then
+ tmp_gsym_prefix=_
+ else
+ tmp_gsym_prefix=
+ fi
+ # must see our label
+ if grep "^${tmp_gsym_prefix}foo$gmp_cv_asm_label_suffix" conftest.s >/dev/null 2>&AC_FD_CC; then
+ # take the last directive before our label (hence skipping segments
+ # getting debugging info etc)
+ tmp_match=`sed -n ["/^${tmp_gsym_prefix}foo$gmp_cv_asm_label_suffix/q
+ /^[. ]*data/p
+ /^[. ]*rdata/p
+ /^[. ]*text/p
+ /^[. ]*section/p
+ /^[. ]*csect/p
+ /^[. ]*CSECT/p"] conftest.s | sed -n '$p'`
+ echo "Match: $tmp_match" >&AC_FD_CC
+ if test -n "$tmp_match"; then
+ gmp_cv_asm_rodata=$tmp_match
+ fi
+ else
+ echo "Couldn't find label: ^${tmp_gsym_prefix}foo$gmp_cv_asm_label_suffix" >&AC_FD_CC
+ fi
+fi
+rm -f conftest*
+])
+echo ["define(<RODATA>, <$gmp_cv_asm_rodata>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_ASM_GLOBL
+dnl -------------
+dnl The assembler directive to mark a label as a global symbol.
+dnl
+dnl ia64 - .global is standard, according to the Intel documentation.
+dnl
+dnl hppa - ".export foo,entry" is demanded by HP hppa "as". ".global" is a
+dnl kind of import.
+dnl
+dnl other - .globl is usual.
+dnl
+dnl "gas" tends to accept .globl everywhere, in addition to .export or
+dnl .global or whatever the system assembler demands.
+
+AC_DEFUN([GMP_ASM_GLOBL],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([for assembler global directive],
+ gmp_cv_asm_globl,
+[case $host in
+ hppa*-*-*) gmp_cv_asm_globl=.export ;;
+ IA64_PATTERN) gmp_cv_asm_globl=.global ;;
+ *) gmp_cv_asm_globl=.globl ;;
+esac
+])
+echo ["define(<GLOBL>, <$gmp_cv_asm_globl>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_ASM_GLOBL_ATTR
+dnl ------------------
+dnl Do we need something after `GLOBL symbol'?
+
+AC_DEFUN([GMP_ASM_GLOBL_ATTR],
+[AC_REQUIRE([GMP_ASM_GLOBL])
+AC_CACHE_CHECK([for assembler global directive attribute],
+ gmp_cv_asm_globl_attr,
+[case $gmp_cv_asm_globl in
+ .export) gmp_cv_asm_globl_attr=",entry" ;;
+ *) gmp_cv_asm_globl_attr="" ;;
+esac
+])
+echo ["define(<GLOBL_ATTR>, <$gmp_cv_asm_globl_attr>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_ASM_TYPE
+dnl ------------
+dnl Can we say ".type", and how?
+dnl
+dnl For i386 GNU/Linux ELF systems, and very likely other ELF systems,
+dnl .type and .size are important on functions in shared libraries. If
+dnl .type is omitted and the mainline program references that function then
+dnl the code will be copied down to the mainline at load time like a piece
+dnl of data. If .size is wrong or missing (it defaults to 4 bytes or some
+dnl such) then incorrect bytes will be copied and a segv is the most likely
+dnl result. In any case such copying is not what's wanted, a .type
+dnl directive will ensure a PLT entry is used.
+dnl
+dnl In GMP the assembler functions are normally only used from within the
+dnl library (since most programs are not interested in the low level
+dnl routines), and in those circumstances a missing .type isn't fatal,
+dnl letting the problem go unnoticed. tests/mpn/t-asmtype.c aims to check
+dnl for it.
+
+AC_DEFUN([GMP_ASM_TYPE],
+[AC_CACHE_CHECK([for assembler .type directive],
+ gmp_cv_asm_type,
+[gmp_cv_asm_type=
+for gmp_tmp_prefix in @ \# %; do
+ GMP_TRY_ASSEMBLE([ .type sym,${gmp_tmp_prefix}function],
+ [if grep "\.type pseudo-op used outside of \.def/\.endef ignored" conftest.out >/dev/null; then : ;
+ else
+ gmp_cv_asm_type=".type \$][1,${gmp_tmp_prefix}\$][2"
+ break
+ fi])
+done
+rm -f conftest*
+])
+echo ["define(<TYPE>, <$gmp_cv_asm_type>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_ASM_SIZE
+dnl ------------
+dnl Can we say `.size'?
+
+AC_DEFUN([GMP_ASM_SIZE],
+[AC_CACHE_CHECK([for assembler .size directive],
+ gmp_cv_asm_size,
+[gmp_cv_asm_size=
+GMP_TRY_ASSEMBLE([ .size sym,1],
+ [if grep "\.size pseudo-op used outside of \.def/\.endef ignored" conftest.out >/dev/null; then : ;
+ else
+ gmp_cv_asm_size=".size \$][1,\$][2"
+ fi])
+])
+echo ["define(<SIZE>, <$gmp_cv_asm_size>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_ASM_COFF_TYPE
+dnl -----------------
+dnl Determine whether the assembler supports COFF type information.
+dnl
+dnl Currently this is only needed for mingw (and cygwin perhaps) and so is
+dnl run only on the x86s, but it ought to work anywhere.
+dnl
+dnl On MINGW, recent versions of the linker have an automatic import scheme
+dnl for data in a DLL which is referenced by a mainline but without
+dnl __declspec (__dllimport__) on the prototype. It seems functions
+dnl without type information are treated as data, or something, and calls
+dnl to them from the mainline will crash. gcc puts type information on the
+dnl C functions it generates, we need to do the same for assembler
+dnl functions.
+dnl
+dnl This applies only to functions without __declspec(__dllimport__),
+dnl ie. without __GMP_DECLSPEC in the case of libgmp, so it also works just
+dnl to ensure all assembler functions used from outside libgmp have
+dnl __GMP_DECLSPEC on their prototypes. But this isn't an ideal situation,
+dnl since we don't want perfectly valid calls going wrong just because
+dnl there wasn't a prototype in scope.
+dnl
+dnl When an auto-import takes place, the following warning is given by the
+dnl linker. This shouldn't be seen for any functions.
+dnl
+dnl Info: resolving _foo by linking to __imp__foo (auto-import)
+dnl
+dnl
+dnl COFF type directives look like the following
+dnl
+dnl .def _foo
+dnl .scl 2
+dnl .type 32
+dnl .endef
+dnl
+dnl _foo is the symbol with GSYM_PREFIX (_). .scl is the storage class, 2
+dnl for external, 3 for static. .type is the object type, 32 for a
+dnl function.
+dnl
+dnl On an ELF system, this is (correctly) rejected due to .def, .endef and
+dnl .scl being invalid, and .type not having enough arguments.
+
+AC_DEFUN([GMP_ASM_COFF_TYPE],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_REQUIRE([GMP_ASM_GLOBL])
+AC_REQUIRE([GMP_ASM_GLOBL_ATTR])
+AC_REQUIRE([GMP_ASM_LABEL_SUFFIX])
+AC_REQUIRE([GMP_ASM_UNDERSCORE])
+AC_CACHE_CHECK([for assembler COFF type directives],
+ gmp_cv_asm_x86_coff_type,
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ $gmp_cv_asm_globl ${tmp_gsym_prefix}foo$gmp_cv_asm_globl_attr
+ .def ${tmp_gsym_prefix}foo
+ .scl 2
+ .type 32
+ .endef
+${tmp_gsym_prefix}foo$gmp_cv_asm_label_suffix
+],
+ [gmp_cv_asm_x86_coff_type=yes],
+ [gmp_cv_asm_x86_coff_type=no])
+])
+echo ["define(<HAVE_COFF_TYPE>, <$gmp_cv_asm_x86_coff_type>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_ASM_LSYM_PREFIX
+dnl -------------------
+dnl What is the prefix for a local label?
+dnl
+dnl The prefixes tested are,
+dnl
+dnl L - usual for underscore systems
+dnl .L - usual for non-underscore systems
+dnl $ - alpha (gas and OSF system assembler)
+dnl L$ - hppa (gas and HP-UX system assembler)
+dnl
+dnl The default is "L" if the tests fail for any reason. There's a good
+dnl chance this will be adequate, since on most systems labels are local
+dnl anyway unless given a ".globl", and an "L" will avoid clashes with
+dnl other identifers.
+dnl
+dnl For gas, ".L" is normally purely local to the assembler, it doesn't get
+dnl put into the object file at all. This style is preferred, to keep the
+dnl object files nice and clean.
+dnl
+dnl BSD format nm produces a line like
+dnl
+dnl 00000000 t Lgurkmacka
+dnl
+dnl The symbol code is normally "t" for text, but any lower case letter
+dnl indicates a local definition.
+dnl
+dnl Code "n" is for a debugging symbol, OSF "nm -B" gives that as an upper
+dnl case "N" for a local.
+dnl
+dnl HP-UX nm prints an error message (though seems to give a 0 exit) if
+dnl there's no symbols at all in an object file, hence the use of "dummy".
+
+AC_DEFUN([GMP_ASM_LSYM_PREFIX],
+[AC_REQUIRE([GMP_ASM_LABEL_SUFFIX])
+AC_REQUIRE([GMP_ASM_TEXT])
+AC_REQUIRE([GMP_PROG_NM])
+AC_CACHE_CHECK([for assembler local label prefix],
+ gmp_cv_asm_lsym_prefix,
+[gmp_tmp_pre_appears=yes
+for gmp_tmp_pre in L .L $L $ L$; do
+ echo "Trying $gmp_tmp_pre" >&AC_FD_CC
+ GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+dummy${gmp_cv_asm_label_suffix}
+${gmp_tmp_pre}gurkmacka${gmp_cv_asm_label_suffix}],
+ [if $NM conftest.$OBJEXT >conftest.nm 2>&AC_FD_CC; then : ; else
+ cat conftest.nm >&AC_FD_CC
+ AC_MSG_WARN(["$NM" failure])
+ break
+ fi
+ cat conftest.nm >&AC_FD_CC
+ if grep gurkmacka conftest.nm >/dev/null; then : ; else
+ # no mention of the symbol, this is good
+ echo "$gmp_tmp_pre label doesn't appear in object file at all (good)" >&AC_FD_CC
+ gmp_cv_asm_lsym_prefix="$gmp_tmp_pre"
+ gmp_tmp_pre_appears=no
+ break
+ fi
+ if grep [' [a-zN] .*gurkmacka'] conftest.nm >/dev/null; then
+ # symbol mentioned as a local, use this if nothing better
+ echo "$gmp_tmp_pre label is local but still in object file" >&AC_FD_CC
+ if test -z "$gmp_cv_asm_lsym_prefix"; then
+ gmp_cv_asm_lsym_prefix="$gmp_tmp_pre"
+ fi
+ else
+ echo "$gmp_tmp_pre label is something unknown" >&AC_FD_CC
+ fi
+ ])
+done
+rm -f conftest*
+if test -z "$gmp_cv_asm_lsym_prefix"; then
+ gmp_cv_asm_lsym_prefix=L
+ AC_MSG_WARN([cannot determine local label, using default $gmp_cv_asm_lsym_prefix])
+fi
+# for development purposes, note whether we got a purely temporary local label
+echo "Local label appears in object files: $gmp_tmp_pre_appears" >&AC_FD_CC
+])
+echo ["define(<LSYM_PREFIX>, <${gmp_cv_asm_lsym_prefix}>)"] >> $gmp_tmpconfigm4
+AC_DEFINE_UNQUOTED(LSYM_PREFIX, "$gmp_cv_asm_lsym_prefix",
+ [Assembler local label prefix])
+])
+
+
+dnl GMP_ASM_W32
+dnl -----------
+dnl How to define a 32-bit word.
+dnl
+dnl FIXME: This test is not right for ia64-*-hpux*. The directive should
+dnl be "data4", but the W32 macro is not currently used by the mpn/ia64 asm
+dnl files.
+
+AC_DEFUN([GMP_ASM_W32],
+[AC_REQUIRE([GMP_ASM_DATA])
+AC_REQUIRE([GMP_ASM_BYTE])
+AC_REQUIRE([GMP_ASM_GLOBL])
+AC_REQUIRE([GMP_ASM_LABEL_SUFFIX])
+AC_REQUIRE([GMP_PROG_NM])
+AC_CACHE_CHECK([how to define a 32-bit word],
+ gmp_cv_asm_w32,
+[case $host in
+ *-*-hpux*)
+ # FIXME: HPUX puts first symbol at 0x40000000, breaking our assumption
+ # that it's at 0x0. We'll have to declare another symbol before the
+ # .long/.word and look at the distance between the two symbols. The
+ # only problem is that the sed expression(s) barfs (on Solaris, for
+ # example) for the symbol with value 0. For now, HPUX uses .word.
+ gmp_cv_asm_w32=".word"
+ ;;
+ *-*-*)
+ gmp_tmp_val=
+ for gmp_tmp_op in .long .word data4; do
+ GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_data
+ $gmp_cv_asm_globl foo
+ $gmp_tmp_op 0
+foo$gmp_cv_asm_label_suffix
+ $gmp_cv_asm_byte 0],
+ [gmp_tmp_val=[`$NM conftest.$OBJEXT | grep foo | \
+ sed -e 's;[[][0-9][]]\(.*\);\1;' -e 's;[^1-9]*\([0-9]*\).*;\1;'`]
+ if test "$gmp_tmp_val" = 4; then
+ gmp_cv_asm_w32="$gmp_tmp_op"
+ break
+ fi])
+ done
+ rm -f conftest*
+ ;;
+esac
+if test -z "$gmp_cv_asm_w32"; then
+ AC_MSG_ERROR([cannot determine how to define a 32-bit word])
+fi
+])
+echo ["define(<W32>, <$gmp_cv_asm_w32>)"] >> $gmp_tmpconfigm4
+])
+
+
+dnl GMP_X86_ASM_GOT_UNDERSCORE
+dnl --------------------------
+dnl Determine whether i386 _GLOBAL_OFFSET_TABLE_ needs an additional
+dnl underscore prefix.
+dnl
+dnl SVR4 - the standard is _GLOBAL_OFFSET_TABLE_
+dnl GNU/Linux - follows SVR4
+dnl OpenBSD - an a.out underscore system, uses __GLOBAL_OFFSET_TABLE_
+dnl NetBSD - also an a.out underscore system, but _GLOBAL_OFFSET_TABLE_
+dnl
+dnl The test attempts to link a program using _GLOBAL_OFFSET_TABLE_ or
+dnl __GLOBAL_OFFSET_TABLE_ to see which works.
+dnl
+dnl $lt_prog_compiler_pic is included in the compile because old versions
+dnl of gas wouldn't accept PIC idioms without the right option (-K). This
+dnl is the same as what libtool and mpn/Makeasm.am will do.
+dnl
+dnl $lt_prog_compiler_pic is also included in the link because OpenBSD ld
+dnl won't accept an R_386_GOTPC relocation without the right options. This
+dnl is not what's done by the Makefiles when building executables, but
+dnl let's hope it's ok (it works fine with gcc).
+dnl
+dnl The fallback is no additional underscore, on the basis that this will
+dnl suit SVR4/ELF style systems, which should be much more common than
+dnl a.out systems with shared libraries.
+dnl
+dnl Note that it's not an error for the tests to fail, since for instance
+dnl cygwin, mingw and djgpp don't have a _GLOBAL_OFFSET_TABLE_ scheme at
+dnl all.
+dnl
+dnl Perhaps $CCAS could be asked to do the linking as well as the
+dnl assembling, but in the Makefiles it's only used for assembling, so lets
+dnl keep it that way.
+dnl
+dnl The test here is run even under --disable-shared, so that PIC objects
+dnl can be built and tested by the tune/many.pl development scheme. The
+dnl tests will be reasonably quick and won't give a fatal error, so this
+dnl arrangement is ok. AC_LIBTOOL_PROG_COMPILER_PIC does its
+dnl $lt_prog_compiler_pic setups even for --disable-shared too.
+
+AC_DEFUN([GMP_ASM_X86_GOT_UNDERSCORE],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_REQUIRE([GMP_ASM_GLOBL])
+AC_REQUIRE([GMP_ASM_GLOBL_ATTR])
+AC_REQUIRE([GMP_ASM_LABEL_SUFFIX])
+AC_REQUIRE([GMP_ASM_UNDERSCORE])
+AC_REQUIRE([AC_LIBTOOL_PROG_COMPILER_PIC])
+AC_CACHE_CHECK([if _GLOBAL_OFFSET_TABLE_ is prefixed by underscore],
+ gmp_cv_asm_x86_got_underscore,
+[gmp_cv_asm_x86_got_underscore="not applicable"
+if test $gmp_cv_asm_underscore = yes; then
+ tmp_gsym_prefix=_
+else
+ tmp_gsym_prefix=
+fi
+for tmp_underscore in "" "_"; do
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ $gmp_cv_asm_globl ${tmp_gsym_prefix}main$gmp_cv_asm_globl_attr
+${tmp_gsym_prefix}main$gmp_cv_asm_label_suffix
+ addl $ ${tmp_underscore}_GLOBAL_OFFSET_TABLE_, %ebx
+EOF
+ gmp_compile="$CCAS $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.s >&AC_FD_CC && $CC $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.$OBJEXT >&AC_FD_CC"
+ if AC_TRY_EVAL(gmp_compile); then
+ if test "$tmp_underscore" = "_"; then
+ gmp_cv_asm_x86_got_underscore=yes
+ else
+ gmp_cv_asm_x86_got_underscore=no
+ fi
+ break
+ fi
+done
+rm -f conftest* a.out b.out a.exe a_out.exe
+])
+if test "$gmp_cv_asm_x86_got_underscore" = "yes"; then
+ GMP_DEFINE(GOT_GSYM_PREFIX, [_])
+else
+ GMP_DEFINE(GOT_GSYM_PREFIX, [])
+fi
+])
+
+
+dnl GMP_ASM_X86_GOT_EAX_OK(CC+CFLAGS, [ACTION-YES] [, ACTION-NO])
+dnl -------------------------------------------------------------
+dnl Determine whether _GLOBAL_OFFSET_TABLE_ used with %eax is ok.
+dnl
+dnl An instruction
+dnl
+dnl addl $_GLOBAL_OFFSET_TABLE_, %eax
+dnl
+dnl is incorrectly assembled by gas 2.12 (or thereabouts) and earlier. It
+dnl puts an addend 2 into the R_386_GOTPC relocation, but it should be 1
+dnl for this %eax form being a 1 byte opcode (with other registers it's 2
+dnl opcode bytes). See note about this in mpn/x86/README too.
+dnl
+dnl We assemble this, surrounded by some unlikely byte sequences as
+dnl delimiters, and check for the bad output.
+dnl
+dnl This is for use by compiler probing in GMP_PROG_CC_WORKS, so the result
+dnl is not cached.
+dnl
+dnl This test is not specific to gas, but old gas is the only assembler we
+dnl know of with this problem. The Solaris has been seen coming out ok.
+dnl
+dnl ".text" is hard coded because this macro is wanted before GMP_ASM_TEXT.
+dnl This should be fine, ".text" is normal on x86 systems, and certainly
+dnl will be fine with the offending gas.
+dnl
+dnl If an error occurs when assembling, we consider the assembler ok, since
+dnl the bad output does not occur. This happens for instance on mingw,
+dnl where _GLOBAL_OFFSET_TABLE_ results in a bfd error, since there's no
+dnl GOT etc in PE object files.
+dnl
+dnl This test is used before the object file extension has been determined,
+dnl so we force output to conftest.o. Using -o with -c is not portable,
+dnl but we think all x86 compilers will accept -o with -c, certainly gcc
+dnl does.
+dnl
+dnl -fPIC is hard coded here, because this test is for use before libtool
+dnl has established the pic options. It's right for gcc, but perhaps not
+dnl other compilers.
+
+AC_DEFUN([GMP_ASM_X86_GOT_EAX_OK],
+[echo "Testing gas GOT with eax good" >&AC_FD_CC
+cat >conftest.awk <<\EOF
+[BEGIN {
+ want[0] = "001"
+ want[1] = "043"
+ want[2] = "105"
+ want[3] = "147"
+ want[4] = "211"
+ want[5] = "253"
+ want[6] = "315"
+ want[7] = "357"
+
+ want[8] = "005"
+ want[9] = "002"
+ want[10] = "000"
+ want[11] = "000"
+ want[12] = "000"
+
+ want[13] = "376"
+ want[14] = "334"
+ want[15] = "272"
+ want[16] = "230"
+ want[17] = "166"
+ want[18] = "124"
+ want[19] = "062"
+ want[20] = "020"
+
+ result = "yes"
+}
+{
+ for (f = 2; f <= NF; f++)
+ {
+ for (i = 0; i < 20; i++)
+ got[i] = got[i+1];
+ got[20] = $f;
+
+ found = 1
+ for (i = 0; i < 21; i++)
+ if (got[i] != want[i])
+ {
+ found = 0
+ break
+ }
+ if (found)
+ {
+ result = "no"
+ exit
+ }
+ }
+}
+END {
+ print result
+}
+]EOF
+cat >conftest.s <<\EOF
+[ .text
+ .byte 1, 35, 69, 103, 137, 171, 205, 239
+ addl $_GLOBAL_OFFSET_TABLE_, %eax
+ .byte 254, 220, 186, 152, 118, 84, 50, 16
+]EOF
+tmp_got_good=yes
+gmp_compile="$1 -fPIC -o conftest.o -c conftest.s >&AC_FD_CC 2>&1"
+if AC_TRY_EVAL(gmp_compile); then
+ tmp_got_good=`od -b conftest.o | $AWK -f conftest.awk`
+fi
+rm -f conftest.*
+echo "Result: $tmp_got_good" >&AC_FD_CC
+if test "$tmp_got_good" = no; then
+ ifelse([$3],,:,[$3])
+else
+ ifelse([$2],,:,[$2])
+fi
+])
+
+
+dnl GMP_ASM_X86_MMX([ACTION-IF-YES][,ACTION-IF-NO])
+dnl -----------------------------------------------
+dnl Determine whether the assembler supports MMX instructions.
+dnl
+dnl This macro is wanted before GMP_ASM_TEXT, so ".text" is hard coded
+dnl here. ".text" is believed to be correct on all x86 systems. Actually
+dnl ".text" probably isn't needed at all, at least for just checking
+dnl instruction syntax.
+dnl
+dnl "movq %mm0, %mm1" should assemble to "0f 6f c8", but Solaris 2.6 and
+dnl 2.7 wrongly assemble it to "0f 6f c1" (that being the reverse "movq
+dnl %mm1, %mm0"). It seems more trouble than it's worth to work around
+dnl this in the code, so just detect and reject.
+
+AC_DEFUN([GMP_ASM_X86_MMX],
+[AC_CACHE_CHECK([if the assembler knows about MMX instructions],
+ gmp_cv_asm_x86_mmx,
+[GMP_TRY_ASSEMBLE(
+[ .text
+ movq %mm0, %mm1],
+[gmp_cv_asm_x86_mmx=yes
+case $host in
+*-*-solaris*)
+ if (dis conftest.$OBJEXT >conftest.out) 2>/dev/null; then
+ if grep "0f 6f c1" conftest.out >/dev/null; then
+ gmp_cv_asm_x86_mmx=movq-bug
+ fi
+ else
+ AC_MSG_WARN(["dis" not available to check for "as" movq bug])
+ fi
+esac],
+[gmp_cv_asm_x86_mmx=no])])
+
+case $gmp_cv_asm_x86_mmx in
+movq-bug)
+ AC_MSG_WARN([+----------------------------------------------------------])
+ AC_MSG_WARN([| WARNING WARNING WARNING])
+ AC_MSG_WARN([| Host CPU has MMX code, but the assembler])
+ AC_MSG_WARN([| $CCAS $CFLAGS $CPPFLAGS])
+ AC_MSG_WARN([| has the Solaris 2.6 and 2.7 bug where register to register])
+ AC_MSG_WARN([| movq operands are reversed.])
+ AC_MSG_WARN([| Non-MMX replacements will be used.])
+ AC_MSG_WARN([| This will be an inferior build.])
+ AC_MSG_WARN([+----------------------------------------------------------])
+ ;;
+no)
+ AC_MSG_WARN([+----------------------------------------------------------])
+ AC_MSG_WARN([| WARNING WARNING WARNING])
+ AC_MSG_WARN([| Host CPU has MMX code, but it can't be assembled by])
+ AC_MSG_WARN([| $CCAS $CFLAGS $CPPFLAGS])
+ AC_MSG_WARN([| Non-MMX replacements will be used.])
+ AC_MSG_WARN([| This will be an inferior build.])
+ AC_MSG_WARN([+----------------------------------------------------------])
+ ;;
+esac
+if test "$gmp_cv_asm_x86_mmx" = yes; then
+ ifelse([$1],,:,[$1])
+else
+ ifelse([$2],,:,[$2])
+fi
+])
+
+
+dnl GMP_ASM_X86_SHLDL_CL
+dnl --------------------
+
+AC_DEFUN([GMP_ASM_X86_SHLDL_CL],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([if the assembler takes cl with shldl],
+ gmp_cv_asm_x86_shldl_cl,
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ shldl %cl, %eax, %ebx],
+ gmp_cv_asm_x86_shldl_cl=yes,
+ gmp_cv_asm_x86_shldl_cl=no)
+])
+if test "$gmp_cv_asm_x86_shldl_cl" = "yes"; then
+ GMP_DEFINE(WANT_SHLDL_CL,1)
+else
+ GMP_DEFINE(WANT_SHLDL_CL,0)
+fi
+])
+
+
+dnl GMP_ASM_X86_SSE2([ACTION-IF-YES][,ACTION-IF-NO])
+dnl ------------------------------------------------
+dnl Determine whether the assembler supports SSE2 instructions.
+dnl
+dnl This macro is wanted before GMP_ASM_TEXT, so ".text" is hard coded
+dnl here. ".text" is believed to be correct on all x86 systems, certainly
+dnl it's all GMP_ASM_TEXT gives currently. Actually ".text" probably isn't
+dnl needed at all, at least for just checking instruction syntax.
+
+AC_DEFUN([GMP_ASM_X86_SSE2],
+[AC_CACHE_CHECK([if the assembler knows about SSE2 instructions],
+ gmp_cv_asm_x86_sse2,
+[GMP_TRY_ASSEMBLE(
+[ .text
+ paddq %mm0, %mm1],
+ [gmp_cv_asm_x86_sse2=yes],
+ [gmp_cv_asm_x86_sse2=no])
+])
+case $gmp_cv_asm_x86_sse2 in
+yes)
+ ifelse([$1],,:,[$1])
+ ;;
+*)
+ AC_MSG_WARN([+----------------------------------------------------------])
+ AC_MSG_WARN([| WARNING WARNING WARNING])
+ AC_MSG_WARN([| Host CPU has SSE2 code, but it can't be assembled by])
+ AC_MSG_WARN([| $CCAS $CFLAGS $CPPFLAGS])
+ AC_MSG_WARN([| Non-SSE2 replacements will be used.])
+ AC_MSG_WARN([| This will be an inferior build.])
+ AC_MSG_WARN([+----------------------------------------------------------])
+ ifelse([$2],,:,[$2])
+ ;;
+esac
+])
+
+
+dnl GMP_ASM_X86_MULX([ACTION-IF-YES][,ACTION-IF-NO])
+dnl ------------------------------------------------
+dnl Determine whether the assembler supports the mulx instruction which debut
+dnl with Haswell.
+dnl
+dnl This macro is wanted before GMP_ASM_TEXT, so ".text" is hard coded
+dnl here. ".text" is believed to be correct on all x86 systems, certainly
+dnl it's all GMP_ASM_TEXT gives currently. Actually ".text" probably isn't
+dnl needed at all, at least for just checking instruction syntax.
+
+AC_DEFUN([GMP_ASM_X86_MULX],
+[AC_CACHE_CHECK([if the assembler knows about the mulx instruction],
+ gmp_cv_asm_x86_mulx,
+[GMP_TRY_ASSEMBLE(
+[ .text
+ mulx %r8, %r9, %r10],
+ [gmp_cv_asm_x86_mulx=yes],
+ [gmp_cv_asm_x86_mulx=no])
+])
+case $gmp_cv_asm_x86_mulx in
+yes)
+ ifelse([$1],,:,[$1])
+ ;;
+*)
+ AC_MSG_WARN([+----------------------------------------------------------])
+ AC_MSG_WARN([| WARNING WARNING WARNING])
+ AC_MSG_WARN([| Host CPU has the mulx instruction, but it can't be])
+ AC_MSG_WARN([| assembled by])
+ AC_MSG_WARN([| $CCAS $CFLAGS $CPPFLAGS])
+ AC_MSG_WARN([| Older x86 instructions will be used.])
+ AC_MSG_WARN([| This will be an inferior build.])
+ AC_MSG_WARN([+----------------------------------------------------------])
+ ifelse([$2],,:,[$2])
+ ;;
+esac
+])
+
+
+dnl GMP_ASM_X86_ADX([ACTION-IF-YES][,ACTION-IF-NO])
+dnl ------------------------------------------------
+dnl Determine whether the assembler supports the adcx and adox instructions
+dnl which debut with the Haswell shrink Broadwell.
+dnl
+dnl This macro is wanted before GMP_ASM_TEXT, so ".text" is hard coded
+dnl here. ".text" is believed to be correct on all x86 systems, certainly
+dnl it's all GMP_ASM_TEXT gives currently. Actually ".text" probably isn't
+dnl needed at all, at least for just checking instruction syntax.
+
+AC_DEFUN([GMP_ASM_X86_ADX],
+[AC_CACHE_CHECK([if the assembler knows about the adox instruction],
+ gmp_cv_asm_x86_adx,
+[GMP_TRY_ASSEMBLE(
+[ .text
+ adox %r8, %r9
+ adcx %r8, %r9],
+ [gmp_cv_asm_x86_adx=yes],
+ [gmp_cv_asm_x86_adx=no])
+])
+case $gmp_cv_asm_x86_adx in
+yes)
+ ifelse([$1],,:,[$1])
+ ;;
+*)
+ AC_MSG_WARN([+----------------------------------------------------------])
+ AC_MSG_WARN([| WARNING WARNING WARNING])
+ AC_MSG_WARN([| Host CPU has the adcx and adox instructions, but they])
+ AC_MSG_WARN([| can't be assembled by])
+ AC_MSG_WARN([| $CCAS $CFLAGS $CPPFLAGS])
+ AC_MSG_WARN([| Older x86 instructions will be used.])
+ AC_MSG_WARN([| This will be an inferior build.])
+ AC_MSG_WARN([+----------------------------------------------------------])
+ ifelse([$2],,:,[$2])
+ ;;
+esac
+])
+
+
+dnl GMP_ASM_X86_MCOUNT
+dnl ------------------
+dnl Find out how to call mcount for profiling on an x86 system.
+dnl
+dnl A dummy function is compiled and the ".s" output examined. The pattern
+dnl matching might be a bit fragile, but should work at least with gcc on
+dnl sensible systems. Certainly it's better than hard coding a table of
+dnl conventions.
+dnl
+dnl For non-PIC, any ".data" is taken to mean a counter might be passed.
+dnl It's assumed a movl will set it up, and the right register is taken
+dnl from that movl. Any movl involving %esp is ignored (a frame pointer
+dnl setup normally).
+dnl
+dnl For PIC, any ".data" is similarly interpreted, but a GOTOFF identifies
+dnl the line setting up the right register.
+dnl
+dnl In both cases a line with "mcount" identifies the call and that line is
+dnl used literally.
+dnl
+dnl On some systems (eg. FreeBSD 3.5) gcc emits ".data" but doesn't use it,
+dnl so it's not an error to have .data but then not find a register.
+dnl
+dnl Variations in mcount conventions on different x86 systems can be found
+dnl in gcc config/i386. mcount can have a "_" prefix or be .mcount or
+dnl _mcount_ptr, and for PIC it can be called through a GOT entry, or via
+dnl the PLT. If a pointer to a counter is required it's passed in %eax or
+dnl %edx.
+dnl
+dnl Flags to specify PIC are taken from $lt_prog_compiler_pic set by
+dnl AC_PROG_LIBTOOL.
+dnl
+dnl Enhancement: Cache the values determined here. But what's the right way
+dnl to get two variables (mcount_nonpic_reg and mcount_nonpic_call say) set
+dnl from one block of commands?
+
+AC_DEFUN([GMP_ASM_X86_MCOUNT],
+[AC_REQUIRE([AC_ENABLE_SHARED])
+AC_REQUIRE([AC_PROG_LIBTOOL])
+AC_MSG_CHECKING([how to call x86 mcount])
+cat >conftest.c <<EOF
+foo(){bar();}
+EOF
+
+if test "$enable_static" = yes; then
+ gmp_asmout_compile="$CC $CFLAGS $CPPFLAGS -S conftest.c 1>&AC_FD_CC"
+ if AC_TRY_EVAL(gmp_asmout_compile); then
+ if grep '\.data' conftest.s >/dev/null; then
+ mcount_nonpic_reg=`sed -n ['/esp/!s/.*movl.*,\(%[a-z]*\).*$/\1/p'] conftest.s`
+ else
+ mcount_nonpic_reg=
+ fi
+ mcount_nonpic_call=`grep 'call.*mcount' conftest.s`
+ if test -z "$mcount_nonpic_call"; then
+ AC_MSG_ERROR([Cannot find mcount call for non-PIC])
+ fi
+ else
+ AC_MSG_ERROR([Cannot compile test program for non-PIC])
+ fi
+fi
+
+if test "$enable_shared" = yes; then
+ gmp_asmout_compile="$CC $CFLAGS $CPPFLAGS $lt_prog_compiler_pic -S conftest.c 1>&AC_FD_CC"
+ if AC_TRY_EVAL(gmp_asmout_compile); then
+ if grep '\.data' conftest.s >/dev/null; then
+ case $lt_prog_compiler_pic in
+ *-DDLL_EXPORT*)
+ # Windows DLLs have non-PIC style mcount
+ mcount_pic_reg=`sed -n ['/esp/!s/.*movl.*,\(%[a-z]*\).*$/\1/p'] conftest.s`
+ ;;
+ *)
+ mcount_pic_reg=`sed -n ['s/.*GOTOFF.*,\(%[a-z]*\).*$/\1/p'] conftest.s`
+ ;;
+ esac
+ else
+ mcount_pic_reg=
+ fi
+ mcount_pic_call=`grep 'call.*mcount' conftest.s`
+ if test -z "$mcount_pic_call"; then
+ AC_MSG_ERROR([Cannot find mcount call for PIC])
+ fi
+ else
+ AC_MSG_ERROR([Cannot compile test program for PIC])
+ fi
+fi
+
+GMP_DEFINE_RAW(["define(<MCOUNT_NONPIC_REG>, <\`$mcount_nonpic_reg'>)"])
+GMP_DEFINE_RAW(["define(<MCOUNT_NONPIC_CALL>,<\`$mcount_nonpic_call'>)"])
+GMP_DEFINE_RAW(["define(<MCOUNT_PIC_REG>, <\`$mcount_pic_reg'>)"])
+GMP_DEFINE_RAW(["define(<MCOUNT_PIC_CALL>, <\`$mcount_pic_call'>)"])
+
+rm -f conftest.*
+AC_MSG_RESULT([determined])
+])
+
+
+dnl GMP_ASM_IA64_ALIGN_OK
+dnl ---------------------
+dnl Determine whether .align correctly pads with nop instructions in a text
+dnl segment.
+dnl
+dnl gas 2.14 and earlier byte swaps its padding bundle on big endian
+dnl systems, which is incorrect (endianness only changes data). What
+dnl should be "nop.m / nop.f / nop.i" comes out as "break" instructions.
+dnl
+dnl The test here detects the bad case, and assumes anything else is ok
+dnl (there are many sensible nop bundles, so it'd be impractical to try to
+dnl match everything good).
+
+AC_DEFUN([GMP_ASM_IA64_ALIGN_OK],
+[AC_CACHE_CHECK([whether assembler .align padding is good],
+ gmp_cv_asm_ia64_align_ok,
+[cat >conftest.awk <<\EOF
+[BEGIN {
+ want[0] = "011"
+ want[1] = "160"
+ want[2] = "074"
+ want[3] = "040"
+ want[4] = "000"
+ want[5] = "040"
+ want[6] = "020"
+ want[7] = "221"
+ want[8] = "114"
+ want[9] = "000"
+ want[10] = "100"
+ want[11] = "200"
+ want[12] = "122"
+ want[13] = "261"
+ want[14] = "000"
+ want[15] = "200"
+
+ want[16] = "000"
+ want[17] = "004"
+ want[18] = "000"
+ want[19] = "000"
+ want[20] = "000"
+ want[21] = "000"
+ want[22] = "002"
+ want[23] = "000"
+ want[24] = "000"
+ want[25] = "000"
+ want[26] = "000"
+ want[27] = "001"
+ want[28] = "000"
+ want[29] = "000"
+ want[30] = "000"
+ want[31] = "014"
+
+ want[32] = "011"
+ want[33] = "270"
+ want[34] = "140"
+ want[35] = "062"
+ want[36] = "000"
+ want[37] = "040"
+ want[38] = "240"
+ want[39] = "331"
+ want[40] = "160"
+ want[41] = "000"
+ want[42] = "100"
+ want[43] = "240"
+ want[44] = "343"
+ want[45] = "371"
+ want[46] = "000"
+ want[47] = "200"
+
+ result = "yes"
+}
+{
+ for (f = 2; f <= NF; f++)
+ {
+ for (i = 0; i < 47; i++)
+ got[i] = got[i+1];
+ got[47] = $f;
+
+ found = 1
+ for (i = 0; i < 48; i++)
+ if (got[i] != want[i])
+ {
+ found = 0
+ break
+ }
+ if (found)
+ {
+ result = "no"
+ exit
+ }
+ }
+}
+END {
+ print result
+}
+]EOF
+GMP_TRY_ASSEMBLE(
+[ .text
+ .align 32
+{ .mmi; add r14 = r15, r16
+ add r17 = r18, r19
+ add r20 = r21, r22 ;; }
+ .align 32
+{ .mmi; add r23 = r24, r25
+ add r26 = r27, r28
+ add r29 = r30, r31 ;; }
+],
+ [gmp_cv_asm_ia64_align_ok=`od -b conftest.$OBJEXT | $AWK -f conftest.awk`],
+ [AC_MSG_WARN([oops, cannot compile test program])
+ gmp_cv_asm_ia64_align_ok=yes])
+])
+GMP_DEFINE_RAW(["define(<IA64_ALIGN_OK>, <\`$gmp_cv_asm_ia64_align_ok'>)"])
+])
+
+
+
+
+dnl GMP_ASM_M68K_INSTRUCTION
+dnl ------------------------
+dnl Not sure if ".l" and "%" are independent settings, but it doesn't hurt
+dnl to try all four possibilities. Note that the % ones must be first, so
+dnl "d0" won't be interpreted as a label.
+dnl
+dnl gas 1.92.3 on NetBSD 1.4 needs to be tested with a two operand
+dnl instruction. It takes registers without "%", but a single operand
+dnl "clrl %d0" only gives a warning, not an error.
+
+AC_DEFUN([GMP_ASM_M68K_INSTRUCTION],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([assembler instruction and register style],
+ gmp_cv_asm_m68k_instruction,
+[for i in "addl %d0,%d1" "add.l %d0,%d1" "addl d0,d1" "add.l d0,d1"; do
+ GMP_TRY_ASSEMBLE(
+ [ $gmp_cv_asm_text
+ $i],
+ [gmp_cv_asm_m68k_instruction=$i
+ rm -f conftest*
+ break])
+done
+if test -z "$gmp_cv_asm_m68k_instruction"; then
+ AC_MSG_ERROR([cannot determine assembler instruction and register style])
+fi
+])
+case $gmp_cv_asm_m68k_instruction in
+"addl d0,d1") want_dot_size=no; want_register_percent=no ;;
+"addl %d0,%d1") want_dot_size=no; want_register_percent=yes ;;
+"add.l d0,d1") want_dot_size=yes; want_register_percent=no ;;
+"add.l %d0,%d1") want_dot_size=yes; want_register_percent=yes ;;
+*) AC_MSG_ERROR([oops, unrecognised instruction and register style]) ;;
+esac
+GMP_DEFINE_RAW(["define(<WANT_REGISTER_PERCENT>, <\`$want_register_percent'>)"])
+GMP_DEFINE_RAW(["define(<WANT_DOT_SIZE>, <\`$want_dot_size'>)"])
+])
+
+
+dnl GMP_ASM_M68K_ADDRESSING
+dnl -----------------------
+
+AC_DEFUN([GMP_ASM_M68K_ADDRESSING],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_REQUIRE([GMP_ASM_M68K_INSTRUCTION])
+AC_CACHE_CHECK([assembler addressing style],
+ gmp_cv_asm_m68k_addressing,
+[case $gmp_cv_asm_m68k_instruction in
+addl*) movel=movel ;;
+add.l*) movel=move.l ;;
+*) AC_MSG_ERROR([oops, unrecognised gmp_cv_asm_m68k_instruction]) ;;
+esac
+case $gmp_cv_asm_m68k_instruction in
+*"%d0,%d1") dreg=%d0; areg=%a0 ;;
+*"d0,d1") dreg=d0; areg=a0 ;;
+*) AC_MSG_ERROR([oops, unrecognised gmp_cv_asm_m68k_instruction]) ;;
+esac
+GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ $movel $dreg, $areg@-],
+ [gmp_cv_asm_m68k_addressing=mit],
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ $movel $dreg, -($areg)],
+ [gmp_cv_asm_m68k_addressing=motorola],
+[AC_MSG_ERROR([cannot determine assembler addressing style])])])
+])
+GMP_DEFINE_RAW(["define(<WANT_ADDRESSING>, <\`$gmp_cv_asm_m68k_addressing'>)"])
+])
+
+
+dnl GMP_ASM_M68K_BRANCHES
+dnl ---------------------
+dnl "bra" is the standard branch instruction. "jra" or "jbra" are
+dnl preferred where available, since on gas for instance they give a
+dnl displacement only as big as it needs to be, whereas "bra" is always
+dnl 16-bits. This applies to the conditional branches "bcc" etc too.
+dnl However "dbcc" etc on gas are already only as big as they need to be.
+
+AC_DEFUN([GMP_ASM_M68K_BRANCHES],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([assembler shortest branches],
+ gmp_cv_asm_m68k_branches,
+[for i in jra jbra bra; do
+ GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+foo$gmp_cv_asm_label_suffix
+ $i foo],
+ [gmp_cv_asm_m68k_branches=$i
+ rm -f conftest*
+ break])
+done
+if test -z "$gmp_cv_asm_m68k_branches"; then
+ AC_MSG_ERROR([cannot determine assembler branching style])
+fi
+])
+GMP_DEFINE_RAW(["define(<WANT_BRANCHES>, <\`$gmp_cv_asm_m68k_branches'>)"])
+])
+
+
+dnl GMP_ASM_POWERPC_PIC_ALWAYS
+dnl --------------------------
+dnl Determine whether PIC is the default compiler output.
+dnl
+dnl SVR4 style "foo@ha" addressing is interpreted as non-PIC, and anything
+dnl else is assumed to require PIC always (Darwin or AIX). SVR4 is the
+dnl only non-PIC addressing syntax the asm files have at the moment anyway.
+dnl
+dnl Libtool does this by taking "*-*-aix* | *-*-darwin* | *-*-rhapsody*" to
+dnl mean PIC always, but it seems more reliable to grep the compiler
+dnl output.
+dnl
+dnl The next paragraph is untrue for Tiger. Was it ever true? For tiger,
+dnl "cc -fast" makes non-PIC the default (and the binaries do run).
+dnl On Darwin "cc -static" is non-PIC with syntax "ha16(_foo)", but that's
+dnl apparently only for use in the kernel, which we're not attempting to
+dnl target at the moment, so don't look for that.
+
+AC_DEFUN([GMP_ASM_POWERPC_PIC_ALWAYS],
+[AC_REQUIRE([AC_PROG_CC])
+AC_CACHE_CHECK([whether compiler output is PIC by default],
+ gmp_cv_asm_powerpc_pic,
+[gmp_cv_asm_powerpc_pic=yes
+cat >conftest.c <<EOF
+int foo;
+int *bar() { return &foo; }
+EOF
+echo "Test program:" >&AC_FD_CC
+cat conftest.c >&AC_FD_CC
+gmp_compile="$CC $CFLAGS $CPPFLAGS -S conftest.c >&AC_FD_CC"
+if AC_TRY_EVAL(gmp_compile); then
+ echo "Compiler output:" >&AC_FD_CC
+ cat conftest.s >&AC_FD_CC
+ if grep 'foo@ha' conftest.s >/dev/null 2>&AC_FD_CC; then
+ gmp_cv_asm_powerpc_pic=no
+ fi
+ if grep 'ha16(_foo)' conftest.s >/dev/null 2>&AC_FD_CC; then
+ gmp_cv_asm_powerpc_pic=no
+ fi
+fi
+rm -f conftest*
+])
+GMP_DEFINE_RAW(["define(<PIC_ALWAYS>,<$gmp_cv_asm_powerpc_pic>)"])
+])
+
+
+dnl GMP_ASM_POWERPC_R_REGISTERS
+dnl ---------------------------
+dnl Determine whether the assembler takes powerpc registers with an "r" as
+dnl in "r6", or as plain "6". The latter is standard, but NeXT, Rhapsody,
+dnl and MacOS-X require the "r" forms.
+dnl
+dnl See also mpn/powerpc32/powerpc-defs.m4 which uses the result of this
+dnl test.
+
+AC_DEFUN([GMP_ASM_POWERPC_R_REGISTERS],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([if the assembler needs r on registers],
+ gmp_cv_asm_powerpc_r_registers,
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ mtctr 6],
+[gmp_cv_asm_powerpc_r_registers=no],
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ mtctr r6],
+[gmp_cv_asm_powerpc_r_registers=yes],
+[AC_MSG_ERROR([neither "mtctr 6" nor "mtctr r6" works])])])])
+
+GMP_DEFINE_RAW(["define(<WANT_R_REGISTERS>,<$gmp_cv_asm_powerpc_r_registers>)"])
+])
+
+
+dnl GMP_ASM_SPARC_REGISTER
+dnl ----------------------
+dnl Determine whether the assembler accepts the ".register" directive.
+dnl Old versions of solaris "as" don't.
+dnl
+dnl See also mpn/sparc32/sparc-defs.m4 which uses the result of this test.
+
+AC_DEFUN([GMP_ASM_SPARC_REGISTER],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([if the assembler accepts ".register"],
+ gmp_cv_asm_sparc_register,
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ .register %g2,#scratch
+],
+[gmp_cv_asm_sparc_register=yes],
+[gmp_cv_asm_sparc_register=no])])
+
+GMP_DEFINE_RAW(["define(<HAVE_REGISTER>,<$gmp_cv_asm_sparc_register>)"])
+])
+
+
+dnl GMP_ASM_SPARC_GOTDATA
+dnl ----------------------
+dnl Determine whether the assembler accepts gotdata relocations.
+dnl
+dnl See also mpn/sparc32/sparc-defs.m4 which uses the result of this test.
+
+AC_DEFUN([GMP_ASM_SPARC_GOTDATA],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([if the assembler accepts gotdata relocations],
+ gmp_cv_asm_sparc_gotdata,
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ .text
+ sethi %gdop_hix22(symbol), %g1
+ or %g1, %gdop_lox10(symbol), %g1
+],
+[gmp_cv_asm_sparc_gotdata=yes],
+[gmp_cv_asm_sparc_gotdata=no])])
+
+GMP_DEFINE_RAW(["define(<HAVE_GOTDATA>,<$gmp_cv_asm_sparc_gotdata>)"])
+])
+
+
+dnl GMP_ASM_SPARC_SHARED_THUNKS
+dnl ----------------------
+dnl Determine whether the assembler supports all of the features
+dnl necessary in order to emit shared PIC thunks on sparc.
+dnl
+dnl See also mpn/sparc32/sparc-defs.m4 which uses the result of this test.
+
+AC_DEFUN([GMP_ASM_SPARC_SHARED_THUNKS],
+[AC_REQUIRE([GMP_ASM_TEXT])
+AC_CACHE_CHECK([if the assembler can support shared PIC thunks],
+ gmp_cv_asm_sparc_shared_thunks,
+[GMP_TRY_ASSEMBLE(
+[ $gmp_cv_asm_text
+ .section .text.__sparc_get_pc_thunk.l7,"axG",@progbits,__sparc_get_pc_thunk.l7,comdat
+ .weak __sparc_get_pc_thunk.l7
+ .hidden __sparc_get_pc_thunk.l7
+ .type __sparc_get_pc_thunk.l7, #function
+__sparc_get_pc_thunk.l7:
+ jmp %o7+8
+ add %o7, %l7, %l7
+],
+[gmp_cv_asm_sparc_shared_thunks=yes],
+[gmp_cv_asm_sparc_shared_thunks=no])])
+
+GMP_DEFINE_RAW(["define(<HAVE_SHARED_THUNKS>,<$gmp_cv_asm_sparc_shared_thunks>)"])
+])
+
+
+dnl GMP_C_ATTRIBUTE_CONST
+dnl ---------------------
+
+AC_DEFUN([GMP_C_ATTRIBUTE_CONST],
+[AC_CACHE_CHECK([whether gcc __attribute__ ((const)) works],
+ gmp_cv_c_attribute_const,
+[AC_TRY_COMPILE([int foo (int x) __attribute__ ((const));], ,
+ gmp_cv_c_attribute_const=yes, gmp_cv_c_attribute_const=no)
+])
+if test $gmp_cv_c_attribute_const = yes; then
+ AC_DEFINE(HAVE_ATTRIBUTE_CONST, 1,
+ [Define to 1 if the compiler accepts gcc style __attribute__ ((const))])
+fi
+])
+
+
+dnl GMP_C_ATTRIBUTE_MALLOC
+dnl ----------------------
+dnl gcc 2.95.x accepts __attribute__ ((malloc)) but with a warning that
+dnl it's ignored. Pretend it doesn't exist in this case, to avoid that
+dnl warning.
+
+AC_DEFUN([GMP_C_ATTRIBUTE_MALLOC],
+[AC_CACHE_CHECK([whether gcc __attribute__ ((malloc)) works],
+ gmp_cv_c_attribute_malloc,
+[cat >conftest.c <<EOF
+void *foo (int x) __attribute__ ((malloc));
+EOF
+gmp_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >conftest.out 2>&1"
+if AC_TRY_EVAL(gmp_compile); then
+ if grep "attribute directive ignored" conftest.out >/dev/null; then
+ gmp_cv_c_attribute_malloc=no
+ else
+ gmp_cv_c_attribute_malloc=yes
+ fi
+else
+ gmp_cv_c_attribute_malloc=no
+fi
+cat conftest.out >&AC_FD_CC
+rm -f conftest*
+])
+if test $gmp_cv_c_attribute_malloc = yes; then
+ AC_DEFINE(HAVE_ATTRIBUTE_MALLOC, 1,
+ [Define to 1 if the compiler accepts gcc style __attribute__ ((malloc))])
+fi
+])
+
+
+dnl GMP_C_ATTRIBUTE_MODE
+dnl --------------------
+dnl Introduced in gcc 2.2, but perhaps not in all Apple derived versions.
+
+AC_DEFUN([GMP_C_ATTRIBUTE_MODE],
+[AC_CACHE_CHECK([whether gcc __attribute__ ((mode (XX))) works],
+ gmp_cv_c_attribute_mode,
+[AC_TRY_COMPILE([typedef int SItype __attribute__ ((mode (SI)));], ,
+ gmp_cv_c_attribute_mode=yes, gmp_cv_c_attribute_mode=no)
+])
+if test $gmp_cv_c_attribute_mode = yes; then
+ AC_DEFINE(HAVE_ATTRIBUTE_MODE, 1,
+ [Define to 1 if the compiler accepts gcc style __attribute__ ((mode (XX)))])
+fi
+])
+
+
+dnl GMP_C_ATTRIBUTE_NORETURN
+dnl ------------------------
+
+AC_DEFUN([GMP_C_ATTRIBUTE_NORETURN],
+[AC_CACHE_CHECK([whether gcc __attribute__ ((noreturn)) works],
+ gmp_cv_c_attribute_noreturn,
+[AC_TRY_COMPILE([void foo (int x) __attribute__ ((noreturn));], ,
+ gmp_cv_c_attribute_noreturn=yes, gmp_cv_c_attribute_noreturn=no)
+])
+if test $gmp_cv_c_attribute_noreturn = yes; then
+ AC_DEFINE(HAVE_ATTRIBUTE_NORETURN, 1,
+ [Define to 1 if the compiler accepts gcc style __attribute__ ((noreturn))])
+fi
+])
+
+
+dnl GMP_C_DOUBLE_FORMAT
+dnl -------------------
+dnl Determine the floating point format.
+dnl
+dnl The object file is grepped, in order to work when cross compiling. A
+dnl start and end sequence is included to avoid false matches, and allowance
+dnl is made for the desired data crossing an "od -b" line boundary. The test
+dnl number is a small integer so it should appear exactly, no rounding or
+dnl truncation etc.
+dnl
+dnl "od -b", incidentally, is supported even by Unix V7, and the awk script
+dnl used doesn't have functions or anything, so even an "old" awk should
+dnl suffice.
+dnl
+dnl The C code here declares the variable foo as extern; without that, some
+dnl C++ compilers will not put foo in the object file.
+
+AC_DEFUN([GMP_C_DOUBLE_FORMAT],
+[AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_PROG_AWK])
+AC_CACHE_CHECK([format of `double' floating point],
+ gmp_cv_c_double_format,
+[gmp_cv_c_double_format=unknown
+cat >conftest.c <<\EOF
+[struct foo {
+ char before[8];
+ double x;
+ char after[8];
+};
+extern struct foo foo;
+struct foo foo = {
+ { '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
+ -123456789.0,
+ { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' },
+};]
+EOF
+gmp_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >&AC_FD_CC 2>&1"
+if AC_TRY_EVAL(gmp_compile); then
+cat >conftest.awk <<\EOF
+[
+BEGIN {
+ found = 0
+}
+
+{
+ for (f = 2; f <= NF; f++)
+ {
+ for (i = 0; i < 23; i++)
+ got[i] = got[i+1];
+ got[23] = $f;
+
+ # match the special begin and end sequences
+ if (got[0] != "001") continue
+ if (got[1] != "043") continue
+ if (got[2] != "105") continue
+ if (got[3] != "147") continue
+ if (got[4] != "211") continue
+ if (got[5] != "253") continue
+ if (got[6] != "315") continue
+ if (got[7] != "357") continue
+ if (got[16] != "376") continue
+ if (got[17] != "334") continue
+ if (got[18] != "272") continue
+ if (got[19] != "230") continue
+ if (got[20] != "166") continue
+ if (got[21] != "124") continue
+ if (got[22] != "062") continue
+ if (got[23] != "020") continue
+
+ saw = " (" got[8] " " got[9] " " got[10] " " got[11] " " got[12] " " got[13] " " got[14] " " got[15] ")"
+
+ if (got[8] == "000" && \
+ got[9] == "000" && \
+ got[10] == "000" && \
+ got[11] == "124" && \
+ got[12] == "064" && \
+ got[13] == "157" && \
+ got[14] == "235" && \
+ got[15] == "301")
+ {
+ print "IEEE little endian"
+ found = 1
+ exit
+ }
+
+ # Little endian with the two 4-byte halves swapped, as used by ARM
+ # when the chip is in little endian mode.
+ #
+ if (got[8] == "064" && \
+ got[9] == "157" && \
+ got[10] == "235" && \
+ got[11] == "301" && \
+ got[12] == "000" && \
+ got[13] == "000" && \
+ got[14] == "000" && \
+ got[15] == "124")
+ {
+ print "IEEE little endian, swapped halves"
+ found = 1
+ exit
+ }
+
+ # gcc 2.95.4 on one GNU/Linux ARM system was seen generating 000 in
+ # the last byte, whereas 124 is correct. Not sure where the bug
+ # actually lies, but a running program didn't seem to get a full
+ # mantissa worth of working bits.
+ #
+ # We match this case explicitly so we can give a nice result message,
+ # but we deliberately exclude it from the normal IEEE double setups
+ # since it's too broken.
+ #
+ if (got[8] == "064" && \
+ got[9] == "157" && \
+ got[10] == "235" && \
+ got[11] == "301" && \
+ got[12] == "000" && \
+ got[13] == "000" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "bad ARM software floats"
+ found = 1
+ exit
+ }
+
+ if (got[8] == "301" && \
+ got[9] == "235" && \
+ got[10] == "157" && \
+ got[11] == "064" && \
+ got[12] == "124" && \
+ got[13] == "000" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "IEEE big endian"
+ found = 1
+ exit
+ }
+
+ if (got[8] == "353" && \
+ got[9] == "315" && \
+ got[10] == "242" && \
+ got[11] == "171" && \
+ got[12] == "000" && \
+ got[13] == "240" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "VAX D"
+ found = 1
+ exit
+ }
+
+ if (got[8] == "275" && \
+ got[9] == "301" && \
+ got[10] == "064" && \
+ got[11] == "157" && \
+ got[12] == "000" && \
+ got[13] == "124" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "VAX G"
+ found = 1
+ exit
+ }
+
+ if (got[8] == "300" && \
+ got[9] == "033" && \
+ got[10] == "353" && \
+ got[11] == "171" && \
+ got[12] == "242" && \
+ got[13] == "240" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "Cray CFP"
+ found = 1
+ exit
+ }
+ }
+}
+
+END {
+ if (! found)
+ print "unknown", saw
+}
+]
+EOF
+ gmp_cv_c_double_format=`od -b conftest.$OBJEXT | $AWK -f conftest.awk`
+ case $gmp_cv_c_double_format in
+ unknown*)
+ echo "cannot match anything, conftest.$OBJEXT contains" >&AC_FD_CC
+ od -b conftest.$OBJEXT >&AC_FD_CC
+ ;;
+ esac
+else
+ AC_MSG_WARN([oops, cannot compile test program])
+fi
+rm -f conftest*
+])
+
+AH_VERBATIM([HAVE_DOUBLE],
+[/* Define one of the following to 1 for the format of a `double'.
+ If your format is not among these choices, or you don't know what it is,
+ then leave all undefined.
+ IEEE_LITTLE_SWAPPED means little endian, but with the two 4-byte halves
+ swapped, as used by ARM CPUs in little endian mode. */
+#undef HAVE_DOUBLE_IEEE_BIG_ENDIAN
+#undef HAVE_DOUBLE_IEEE_LITTLE_ENDIAN
+#undef HAVE_DOUBLE_IEEE_LITTLE_SWAPPED
+#undef HAVE_DOUBLE_VAX_D
+#undef HAVE_DOUBLE_VAX_G
+#undef HAVE_DOUBLE_CRAY_CFP])
+
+case $gmp_cv_c_double_format in
+ "IEEE big endian")
+ AC_DEFINE(HAVE_DOUBLE_IEEE_BIG_ENDIAN, 1)
+ GMP_DEFINE_RAW("define_not_for_expansion(\`HAVE_DOUBLE_IEEE_BIG_ENDIAN')", POST)
+ ;;
+ "IEEE little endian")
+ AC_DEFINE(HAVE_DOUBLE_IEEE_LITTLE_ENDIAN, 1)
+ GMP_DEFINE_RAW("define_not_for_expansion(\`HAVE_DOUBLE_IEEE_LITTLE_ENDIAN')", POST)
+ ;;
+ "IEEE little endian, swapped halves")
+ AC_DEFINE(HAVE_DOUBLE_IEEE_LITTLE_SWAPPED, 1) ;;
+ "VAX D")
+ AC_DEFINE(HAVE_DOUBLE_VAX_D, 1) ;;
+ "VAX G")
+ AC_DEFINE(HAVE_DOUBLE_VAX_G, 1) ;;
+ "Cray CFP")
+ AC_DEFINE(HAVE_DOUBLE_CRAY_CFP, 1) ;;
+ "bad ARM software floats")
+ ;;
+ unknown*)
+ AC_MSG_WARN([Could not determine float format.])
+ AC_MSG_WARN([Conversions to and from "double" may be slow.])
+ ;;
+ *)
+ AC_MSG_WARN([oops, unrecognised float format: $gmp_cv_c_double_format])
+ ;;
+esac
+])
+
+
+dnl GMP_C_STDARG
+dnl ------------
+dnl Test whether to use <stdarg.h>.
+dnl
+dnl Notice the AC_DEFINE here is HAVE_STDARG to avoid clashing with
+dnl HAVE_STDARG_H which could arise from AC_CHECK_HEADERS.
+dnl
+dnl This test might be slight overkill, after all there's really only going
+dnl to be ANSI or K&R and the two can be differentiated by AC_PROG_CC_STDC
+dnl or very likely by the setups for _PROTO in gmp.h. On the other hand
+dnl this test is nice and direct, being what we're going to actually use.
+
+dnl AC_DEFUN([GMP_C_STDARG],
+dnl [AC_CACHE_CHECK([whether <stdarg.h> exists and works],
+dnl gmp_cv_c_stdarg,
+dnl [AC_TRY_COMPILE(
+dnl [#include <stdarg.h>
+dnl int foo (int x, ...)
+dnl {
+dnl va_list ap;
+dnl int y;
+dnl va_start (ap, x);
+dnl y = va_arg (ap, int);
+dnl va_end (ap);
+dnl return y;
+dnl }],,
+dnl gmp_cv_c_stdarg=yes, gmp_cv_c_stdarg=no)
+dnl ])
+dnl if test $gmp_cv_c_stdarg = yes; then
+dnl AC_DEFINE(HAVE_STDARG, 1, [Define to 1 if <stdarg.h> exists and works])
+dnl fi
+dnl ])
+
+
+dnl GMP_FUNC_ALLOCA
+dnl ---------------
+dnl Determine whether "alloca" is available. This is AC_FUNC_ALLOCA from
+dnl autoconf, but changed so it doesn't use alloca.c if alloca() isn't
+dnl available, and also to use gmp-impl.h for the conditionals detecting
+dnl compiler builtin alloca's.
+
+AC_DEFUN([GMP_FUNC_ALLOCA],
+[AC_REQUIRE([GMP_HEADER_ALLOCA])
+AC_CACHE_CHECK([for alloca (via gmp-impl.h)],
+ gmp_cv_func_alloca,
+[AC_TRY_LINK(
+GMP_INCLUDE_GMP_H
+[#include "$srcdir/gmp-impl.h"
+],
+ [char *p = (char *) alloca (1);],
+ gmp_cv_func_alloca=yes,
+ gmp_cv_func_alloca=no)])
+if test $gmp_cv_func_alloca = yes; then
+ AC_DEFINE(HAVE_ALLOCA, 1, [Define to 1 if alloca() works (via gmp-impl.h).])
+fi
+])
+
+AC_DEFUN([GMP_HEADER_ALLOCA],
+[# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+AC_CACHE_CHECK([for working alloca.h],
+ gmp_cv_header_alloca,
+[AC_TRY_LINK([#include <alloca.h>],
+ [char *p = (char *) alloca (2 * sizeof (int));],
+ gmp_cv_header_alloca=yes,
+ gmp_cv_header_alloca=no)])
+if test $gmp_cv_header_alloca = yes; then
+ AC_DEFINE(HAVE_ALLOCA_H, 1,
+ [Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).])
+fi
+])
+
+
+dnl GMP_OPTION_ALLOCA
+dnl -----------------
+dnl Decide what to do about --enable-alloca from the user.
+dnl This is a macro so it can require GMP_FUNC_ALLOCA.
+
+AC_DEFUN([GMP_OPTION_ALLOCA],
+[AC_REQUIRE([GMP_FUNC_ALLOCA])
+AC_CACHE_CHECK([how to allocate temporary memory],
+ gmp_cv_option_alloca,
+[case $enable_alloca in
+ yes)
+ gmp_cv_option_alloca=alloca
+ ;;
+ no)
+ gmp_cv_option_alloca=malloc-reentrant
+ ;;
+ reentrant | notreentrant)
+ case $gmp_cv_func_alloca in
+ yes) gmp_cv_option_alloca=alloca ;;
+ *) gmp_cv_option_alloca=malloc-$enable_alloca ;;
+ esac
+ ;;
+ *)
+ gmp_cv_option_alloca=$enable_alloca
+ ;;
+esac
+])
+
+AH_VERBATIM([WANT_TMP],
+[/* Define one of these to 1 for the desired temporary memory allocation
+ method, per --enable-alloca. */
+#undef WANT_TMP_ALLOCA
+#undef WANT_TMP_REENTRANT
+#undef WANT_TMP_NOTREENTRANT
+#undef WANT_TMP_DEBUG])
+
+case $gmp_cv_option_alloca in
+ alloca)
+ if test $gmp_cv_func_alloca = no; then
+ AC_MSG_ERROR([--enable-alloca=alloca specified, but alloca not available])
+ fi
+ AC_DEFINE(WANT_TMP_ALLOCA)
+ TAL_OBJECT=tal-reent$U.lo
+ ;;
+ malloc-reentrant)
+ AC_DEFINE(WANT_TMP_REENTRANT)
+ TAL_OBJECT=tal-reent$U.lo
+ ;;
+ malloc-notreentrant)
+ AC_DEFINE(WANT_TMP_NOTREENTRANT)
+ TAL_OBJECT=tal-notreent$U.lo
+ ;;
+ debug)
+ AC_DEFINE(WANT_TMP_DEBUG)
+ TAL_OBJECT=tal-debug$U.lo
+ ;;
+ *)
+ # checks at the start of configure.in should protect us
+ AC_MSG_ERROR([unrecognised --enable-alloca=$gmp_cv_option_alloca])
+ ;;
+esac
+AC_SUBST(TAL_OBJECT)
+])
+
+
+dnl GMP_FUNC_SSCANF_WRITABLE_INPUT
+dnl ------------------------------
+dnl Determine whether sscanf requires a writable input string.
+dnl
+dnl It might be nicer to run a program to determine this when doing a
+dnl native build, but the systems afflicted are few and far between these
+dnl days, so it seems good enough just to list them.
+
+AC_DEFUN([GMP_FUNC_SSCANF_WRITABLE_INPUT],
+[AC_CACHE_CHECK([whether sscanf needs writable input],
+ gmp_cv_func_sscanf_writable_input,
+[case $host in
+ *-*-hpux9 | *-*-hpux9.*)
+ gmp_cv_func_sscanf_writable_input=yes ;;
+ *) gmp_cv_func_sscanf_writable_input=no ;;
+esac
+])
+case $gmp_cv_func_sscanf_writable_input in
+ yes) AC_DEFINE(SSCANF_WRITABLE_INPUT, 1,
+ [Define to 1 if sscanf requires writable inputs]) ;;
+ no) ;;
+ *) AC_MSG_ERROR([unrecognised \$gmp_cv_func_sscanf_writable_input]) ;;
+esac
+])
+
+
+dnl GMP_FUNC_VSNPRINTF
+dnl ------------------
+dnl Check whether vsnprintf exists, and works properly.
+dnl
+dnl Systems without vsnprintf include mingw32, OSF 4.
+dnl
+dnl Sparc Solaris 2.7 in 64-bit mode doesn't always truncate, making
+dnl vsnprintf like vsprintf, and hence completely useless. On one system a
+dnl literal string is enough to provoke the problem, on another a "%n" was
+dnl needed. There seems to be something weird going on with the optimizer
+dnl or something, since on the first system adding a second check with
+dnl "%n", or even just an initialized local variable, makes it work. In
+dnl any case, without bothering to get to the bottom of this, the two
+dnl program runs in the code below end up successfully detecting the
+dnl problem.
+dnl
+dnl glibc 2.0.x returns either -1 or bufsize-1 for an overflow (both seen,
+dnl not sure which 2.0.x does which), but still puts the correct null
+dnl terminated result into the buffer.
+
+AC_DEFUN([GMP_FUNC_VSNPRINTF],
+[AC_CHECK_FUNC(vsnprintf,
+ [gmp_vsnprintf_exists=yes],
+ [gmp_vsnprintf_exists=no])
+if test "$gmp_vsnprintf_exists" = no; then
+ gmp_cv_func_vsnprintf=no
+else
+ AC_CACHE_CHECK([whether vsnprintf works],
+ gmp_cv_func_vsnprintf,
+ [gmp_cv_func_vsnprintf=yes
+ for i in 'return check ("hello world");' 'int n; return check ("%nhello world", &n);'; do
+ AC_TRY_RUN([
+#include <string.h> /* for strcmp */
+#include <stdio.h> /* for vsnprintf */
+
+#include <stdarg.h>
+
+int
+check (const char *fmt, ...)
+{
+ static char buf[128];
+ va_list ap;
+ int ret;
+
+ va_start (ap, fmt);
+
+ ret = vsnprintf (buf, 4, fmt, ap);
+
+ if (strcmp (buf, "hel") != 0)
+ return 1;
+
+ /* allowed return values */
+ if (ret != -1 && ret != 3 && ret != 11)
+ return 2;
+
+ return 0;
+}
+
+int
+main ()
+{
+$i
+}
+],
+ [:],
+ [gmp_cv_func_vsnprintf=no; break],
+ [gmp_cv_func_vsnprintf=probably; break])
+ done
+ ])
+ if test "$gmp_cv_func_vsnprintf" = probably; then
+ AC_MSG_WARN([cannot check for properly working vsnprintf when cross compiling, will assume it's ok])
+ fi
+ if test "$gmp_cv_func_vsnprintf" != no; then
+ AC_DEFINE(HAVE_VSNPRINTF,1,
+ [Define to 1 if you have the `vsnprintf' function and it works properly.])
+ fi
+fi
+])
+
+
+dnl GMP_H_EXTERN_INLINE
+dnl -------------------
+dnl If the compiler has an "inline" of some sort, check whether the
+dnl #ifdef's in gmp.h recognise it.
+
+AC_DEFUN([GMP_H_EXTERN_INLINE],
+[AC_REQUIRE([AC_C_INLINE])
+case $ac_cv_c_inline in
+no) ;;
+*)
+ AC_TRY_COMPILE(
+[#define __GMP_WITHIN_CONFIGURE_INLINE 1
+]GMP_INCLUDE_GMP_H[
+#ifndef __GMP_EXTERN_INLINE
+die die die
+#endif
+],,,
+ [case $ac_cv_c_inline in
+ yes) tmp_inline=inline ;;
+ *) tmp_inline=$ac_cv_c_inline ;;
+ esac
+ AC_MSG_WARN([gmp.h doesnt recognise compiler "$tmp_inline", inlines will be unavailable])])
+ ;;
+esac
+])
+
+
+dnl GMP_H_HAVE_FILE
+dnl ---------------
+dnl Check whether the #ifdef's in gmp.h recognise when stdio.h has been
+dnl included to get FILE.
+
+AC_DEFUN([GMP_H_HAVE_FILE],
+[AC_TRY_COMPILE(
+[#include <stdio.h>]
+GMP_INCLUDE_GMP_H
+[#if ! _GMP_H_HAVE_FILE
+die die die
+#endif
+],,,
+ [AC_MSG_WARN([gmp.h doesnt recognise <stdio.h>, FILE prototypes will be unavailable])])
+])
+
+
+dnl GMP_PROG_CC_FOR_BUILD
+dnl ---------------------
+dnl Establish CC_FOR_BUILD, a C compiler for the build system.
+dnl
+dnl If CC_FOR_BUILD is set then it's expected to work, likewise the old
+dnl style HOST_CC, otherwise some likely candidates are tried, the same as
+dnl configfsf.guess.
+
+AC_DEFUN([GMP_PROG_CC_FOR_BUILD],
+[AC_REQUIRE([AC_PROG_CC])
+if test -n "$CC_FOR_BUILD"; then
+ GMP_PROG_CC_FOR_BUILD_WORKS($CC_FOR_BUILD,,
+ [AC_MSG_ERROR([Specified CC_FOR_BUILD doesn't seem to work])])
+elif test -n "$HOST_CC"; then
+ GMP_PROG_CC_FOR_BUILD_WORKS($HOST_CC,
+ [CC_FOR_BUILD=$HOST_CC],
+ [AC_MSG_ERROR([Specified HOST_CC doesn't seem to work])])
+else
+ for i in "$CC" "$CC $CFLAGS $CPPFLAGS" cc gcc c89 c99; do
+ GMP_PROG_CC_FOR_BUILD_WORKS($i,
+ [CC_FOR_BUILD=$i
+ break])
+ done
+ if test -z "$CC_FOR_BUILD"; then
+ AC_MSG_ERROR([Cannot find a build system compiler])
+ fi
+fi
+
+AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler])
+AC_SUBST(CC_FOR_BUILD)
+])
+
+
+dnl GMP_PROG_CC_FOR_BUILD_WORKS(cc/cflags[,[action-if-good][,action-if-bad]])
+dnl -------------------------------------------------------------------------
+dnl See if the given cc/cflags works on the build system.
+dnl
+dnl It seems easiest to just use the default compiler output, rather than
+dnl figuring out the .exe or whatever at this stage.
+
+AC_DEFUN([GMP_PROG_CC_FOR_BUILD_WORKS],
+[AC_MSG_CHECKING([build system compiler $1])
+# remove anything that might look like compiler output to our "||" expression
+rm -f conftest* a.out b.out a.exe a_out.exe
+cat >conftest.c <<EOF
+int
+main ()
+{
+ exit(0);
+}
+EOF
+gmp_compile="$1 conftest.c"
+cc_for_build_works=no
+if AC_TRY_EVAL(gmp_compile); then
+ if (./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest) >&AC_FD_CC 2>&1; then
+ cc_for_build_works=yes
+ fi
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+AC_MSG_RESULT($cc_for_build_works)
+if test "$cc_for_build_works" = yes; then
+ ifelse([$2],,:,[$2])
+else
+ ifelse([$3],,:,[$3])
+fi
+])
+
+
+dnl GMP_PROG_CPP_FOR_BUILD
+dnl ---------------------
+dnl Establish CPP_FOR_BUILD, the build system C preprocessor.
+dnl The choices tried here are the same as AC_PROG_CPP, but with
+dnl CC_FOR_BUILD.
+
+AC_DEFUN([GMP_PROG_CPP_FOR_BUILD],
+[AC_REQUIRE([GMP_PROG_CC_FOR_BUILD])
+AC_MSG_CHECKING([for build system preprocessor])
+if test -z "$CPP_FOR_BUILD"; then
+ AC_CACHE_VAL(gmp_cv_prog_cpp_for_build,
+ [cat >conftest.c <<EOF
+#define FOO BAR
+EOF
+ for i in "$CC_FOR_BUILD -E" "$CC_FOR_BUILD -E -traditional-cpp" "/lib/cpp"; do
+ gmp_compile="$i conftest.c"
+ if AC_TRY_EVAL(gmp_compile) >&AC_FD_CC 2>&1; then
+ gmp_cv_prog_cpp_for_build=$i
+ break
+ fi
+ done
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ if test -z "$gmp_cv_prog_cpp_for_build"; then
+ AC_MSG_ERROR([Cannot find build system C preprocessor.])
+ fi
+ ])
+ CPP_FOR_BUILD=$gmp_cv_prog_cpp_for_build
+fi
+AC_MSG_RESULT([$CPP_FOR_BUILD])
+
+AC_ARG_VAR(CPP_FOR_BUILD,[build system C preprocessor])
+AC_SUBST(CPP_FOR_BUILD)
+])
+
+
+dnl GMP_PROG_EXEEXT_FOR_BUILD
+dnl -------------------------
+dnl Determine EXEEXT_FOR_BUILD, the build system executable suffix.
+dnl
+dnl The idea is to find what "-o conftest$foo" will make it possible to run
+dnl the program with ./conftest. On Unix-like systems this is of course
+dnl nothing, for DOS it's ".exe", or for a strange RISC OS foreign file
+dnl system cross compile it can be ",ff8" apparently. Not sure if the
+dnl latter actually applies to a build-system executable, maybe it doesn't,
+dnl but it won't hurt to try.
+
+AC_DEFUN([GMP_PROG_EXEEXT_FOR_BUILD],
+[AC_REQUIRE([GMP_PROG_CC_FOR_BUILD])
+AC_CACHE_CHECK([for build system executable suffix],
+ gmp_cv_prog_exeext_for_build,
+[cat >conftest.c <<EOF
+int
+main ()
+{
+ exit (0);
+}
+EOF
+for i in .exe ,ff8 ""; do
+ gmp_compile="$CC_FOR_BUILD conftest.c -o conftest$i"
+ if AC_TRY_EVAL(gmp_compile); then
+ if (./conftest) 2>&AC_FD_CC; then
+ gmp_cv_prog_exeext_for_build=$i
+ break
+ fi
+ fi
+done
+rm -f conftest*
+if test "${gmp_cv_prog_exeext_for_build+set}" != set; then
+ AC_MSG_ERROR([Cannot determine executable suffix])
+fi
+])
+AC_SUBST(EXEEXT_FOR_BUILD,$gmp_cv_prog_exeext_for_build)
+])
+
+
+dnl GMP_C_FOR_BUILD_ANSI
+dnl --------------------
+dnl Determine whether CC_FOR_BUILD is ANSI, and establish U_FOR_BUILD
+dnl accordingly.
+dnl
+dnl FIXME: Use AC_PROG_CC sets ac_cv_prog_cc_c89 which could be used instead
+
+AC_DEFUN([GMP_C_FOR_BUILD_ANSI],
+[AC_REQUIRE([GMP_PROG_CC_FOR_BUILD])
+AC_CACHE_CHECK([whether build system compiler is ANSI],
+ gmp_cv_c_for_build_ansi,
+[cat >conftest.c <<EOF
+int
+main (int argc, char **argv)
+{
+ exit(0);
+}
+EOF
+gmp_compile="$CC_FOR_BUILD conftest.c"
+if AC_TRY_EVAL(gmp_compile); then
+ gmp_cv_c_for_build_ansi=yes
+else
+ gmp_cv_c_for_build_ansi=no
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+])
+if test "$gmp_cv_c_for_build_ansi" = yes; then
+ U_FOR_BUILD=
+else
+ AC_SUBST(U_FOR_BUILD,_)
+fi
+])
+
+
+dnl GMP_CHECK_LIBM_FOR_BUILD
+dnl ------------------------
+dnl Establish LIBM_FOR_BUILD as -lm, if that seems to work.
+dnl
+dnl Libtool AC_CHECK_LIBM also uses -lmw on *-ncr-sysv4.3*, if it works.
+dnl Don't know what that does, lets assume it's not needed just for log().
+
+AC_DEFUN([GMP_CHECK_LIBM_FOR_BUILD],
+[AC_REQUIRE([GMP_PROG_CC_FOR_BUILD])
+AC_CACHE_CHECK([for build system compiler math library],
+ gmp_cv_check_libm_for_build,
+[cat >conftest.c <<EOF
+int
+main ()
+{
+ exit(0);
+}
+double d;
+double
+foo ()
+{
+ return log (d);
+}
+EOF
+gmp_compile="$CC_FOR_BUILD conftest.c -lm"
+if AC_TRY_EVAL(gmp_compile); then
+ gmp_cv_check_libm_for_build=-lm
+else
+ gmp_cv_check_libm_for_build=no
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+])
+case $gmp_cv_check_libm_for_build in
+ yes) AC_SUBST(LIBM_FOR_BUILD,-lm) ;;
+ no) LIBM_FOR_BUILD= ;;
+ *) LIBM_FOR_BUILD=$gmp_cv_check_libm_for_build ;;
+esac
+])
diff --git a/gmp/aclocal.m4 b/gmp/aclocal.m4
new file mode 100644
index 0000000000..11222f5a23
--- /dev/null
+++ b/gmp/aclocal.m4
@@ -0,0 +1,9302 @@
+# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+# Inc.
+# This file 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.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file 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.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ _LT_PROG_REPLACE_SHELLFNS
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ m4_if([$1], [CXX],
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case "$ECHO" in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[ --with-sysroot[=DIR] Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([${with_sysroot}])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS="$save_LDFLAGS"])
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report which library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case ${prev}${p} in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test "$pre_test_object_deps_done" = no; then
+ case ${prev} in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+ CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+ func_split_long_opt_name=${1%%=*}
+ func_split_long_opt_arg=${1#*=}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo])
+
+ _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))])
+
+ _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+ func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+ eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
+
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file 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.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
+
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file 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.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
+
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file 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.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
+
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file 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.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
+# Foundation, Inc.
+#
+# This file 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.
+
+# serial 1
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11.6], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.6])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 1
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
+# Inc.
+#
+# This file 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.
+
+# serial 1
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_PROG_LEX
+# -----------
+# Autoconf leaves LEX=: if lex or flex can't be found. Change that to a
+# "missing" invocation, for better error output.
+AC_DEFUN([AM_PROG_LEX],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AM_MISSING_HAS_RUN])dnl
+AC_REQUIRE([AC_PROG_LEX])dnl
+if test "$LEX" = :; then
+ LEX=${am_missing_run}flex
+fi])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
+# 2011 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
+# Inc.
+#
+# This file 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.
+
+# serial 1
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
+# Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 1
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 3
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/gmp/assert.c b/gmp/assert.c
new file mode 100644
index 0000000000..2e85e6bf63
--- /dev/null
+++ b/gmp/assert.c
@@ -0,0 +1,59 @@
+/* GMP assertion failure handler.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+__gmp_assert_header (const char *filename, int linenum)
+{
+ if (filename != NULL && filename[0] != '\0')
+ {
+ fprintf (stderr, "%s:", filename);
+ if (linenum != -1)
+ fprintf (stderr, "%d: ", linenum);
+ }
+}
+
+void
+__gmp_assert_fail (const char *filename, int linenum,
+ const char *expr)
+{
+ __gmp_assert_header (filename, linenum);
+ fprintf (stderr, "GNU MP assertion failed: %s\n", expr);
+ abort();
+}
diff --git a/gmp/bootstrap.c b/gmp/bootstrap.c
new file mode 100644
index 0000000000..bff960ed83
--- /dev/null
+++ b/gmp/bootstrap.c
@@ -0,0 +1,146 @@
+/* Functions needed for bootstrapping the gmp build, based on mini-gmp.
+
+Copyright 2001, 2002, 2004, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mini-gmp/mini-gmp.c"
+
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#define PTR(x) ((x)->_mp_d)
+#define SIZ(x) ((x)->_mp_size)
+
+#define xmalloc gmp_default_alloc
+
+int
+isprime (unsigned long int t)
+{
+ unsigned long int q, r, d;
+
+ if (t < 32)
+ return (0xa08a28acUL >> t) & 1;
+ if ((t & 1) == 0)
+ return 0;
+
+ if (t % 3 == 0)
+ return 0;
+ if (t % 5 == 0)
+ return 0;
+ if (t % 7 == 0)
+ return 0;
+
+ for (d = 11;;)
+ {
+ q = t / d;
+ r = t - q * d;
+ if (q < d)
+ return 1;
+ if (r == 0)
+ break;
+ d += 2;
+ q = t / d;
+ r = t - q * d;
+ if (q < d)
+ return 1;
+ if (r == 0)
+ break;
+ d += 4;
+ }
+ return 0;
+}
+
+int
+log2_ceil (int n)
+{
+ int e;
+ assert (n >= 1);
+ for (e = 0; ; e++)
+ if ((1 << e) >= n)
+ break;
+ return e;
+}
+
+/* Set inv to the inverse of d, in the style of invert_limb, ie. for
+ udiv_qrnnd_preinv. */
+void
+mpz_preinv_invert (mpz_t inv, mpz_t d, int numb_bits)
+{
+ mpz_t t;
+ int norm;
+ assert (SIZ(d) > 0);
+
+ norm = numb_bits - mpz_sizeinbase (d, 2);
+ assert (norm >= 0);
+ mpz_init_set_ui (t, 1L);
+ mpz_mul_2exp (t, t, 2*numb_bits - norm);
+ mpz_tdiv_q (inv, t, d);
+ mpz_set_ui (t, 1L);
+ mpz_mul_2exp (t, t, numb_bits);
+ mpz_sub (inv, inv, t);
+
+ mpz_clear (t);
+}
+
+/* Calculate r satisfying r*d == 1 mod 2^n. */
+void
+mpz_invert_2exp (mpz_t r, mpz_t a, unsigned long n)
+{
+ unsigned long i;
+ mpz_t inv, prod;
+
+ assert (mpz_odd_p (a));
+
+ mpz_init_set_ui (inv, 1L);
+ mpz_init (prod);
+
+ for (i = 1; i < n; i++)
+ {
+ mpz_mul (prod, inv, a);
+ if (mpz_tstbit (prod, i) != 0)
+ mpz_setbit (inv, i);
+ }
+
+ mpz_mul (prod, inv, a);
+ mpz_tdiv_r_2exp (prod, prod, n);
+ assert (mpz_cmp_ui (prod, 1L) == 0);
+
+ mpz_set (r, inv);
+
+ mpz_clear (inv);
+ mpz_clear (prod);
+}
+
+/* Calculate inv satisfying r*a == 1 mod 2^n. */
+void
+mpz_invert_ui_2exp (mpz_t r, unsigned long a, unsigned long n)
+{
+ mpz_t az;
+ mpz_init_set_ui (az, a);
+ mpz_invert_2exp (r, az, n);
+ mpz_clear (az);
+}
diff --git a/gmp/compat.c b/gmp/compat.c
new file mode 100644
index 0000000000..b896f8489f
--- /dev/null
+++ b/gmp/compat.c
@@ -0,0 +1,60 @@
+/* Old function entrypoints retained for binary compatibility.
+
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* mpn_divexact_by3 was a function in gmp 3.0.1, but as of gmp 3.1 it's a
+ macro calling mpn_divexact_by3c. */
+mp_limb_t
+__MPN (divexact_by3) (mp_ptr dst, mp_srcptr src, mp_size_t size)
+{
+ return mpn_divexact_by3 (dst, src, size);
+}
+
+
+/* mpn_divmod_1 was a function in gmp 3.0.1 and earlier, but marked obsolete
+ in both gmp 2 and 3. As of gmp 3.1 it's a macro calling mpn_divrem_1. */
+mp_limb_t
+__MPN (divmod_1) (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor)
+{
+ return mpn_divmod_1 (dst, src, size, divisor);
+}
+
+
+/* mpz_legendre was a separate function in gmp 3.1.1 and earlier, but as of
+ 4.0 it's a #define alias for mpz_jacobi. */
+int
+__gmpz_legendre (mpz_srcptr a, mpz_srcptr b)
+{
+ return mpz_jacobi (a, b);
+}
diff --git a/gmp/config.guess b/gmp/config.guess
new file mode 100755
index 0000000000..02b61f45aa
--- /dev/null
+++ b/gmp/config.guess
@@ -0,0 +1,1021 @@
+#! /bin/sh
+#
+# GMP config.guess wrapper.
+
+
+# Copyright 2000-2006, 2008, 2011-2014 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: config.guess
+#
+# Print the host system CPU-VENDOR-OS.
+#
+# configfsf.guess is run and its guess then sharpened up to take advantage
+# of the finer grained CPU types that GMP knows.
+
+
+# Expect to find configfsf.guess in the same directory as this config.guess
+configfsf_guess="`echo \"$0\" | sed 's/config.guess$/configfsf.guess/'`"
+if test "$configfsf_guess" = "$0"; then
+ echo "Cannot derive configfsf.guess from $0" 1>&2
+ exit 1
+fi
+if test -f "$configfsf_guess"; then
+ :
+else
+ echo "$configfsf_guess not found" 1>&2
+ exit 1
+fi
+
+# Setup a $SHELL with which to run configfsf.guess, using the same
+# $CONFIG_SHELL or /bin/sh as autoconf does when running config.guess
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identify ourselves on --version, --help or errors
+if test $# != 0; then
+ echo "(GNU MP wrapped config.guess)"
+ $SHELL $configfsf_guess "$@"
+ exit 1
+fi
+
+guess_full=`$SHELL $configfsf_guess`
+if test $? != 0; then
+ exit 1
+fi
+
+guess_cpu=`echo "$guess_full" | sed 's/-.*$//'`
+guess_rest=`echo "$guess_full" | sed 's/^[^-]*//'`
+exact_cpu=
+
+
+# -------------------------------------------------------------------------
+# The following should look at the current guess and probe the system to
+# establish a better guess in exact_cpu. Leave exact_cpu empty if probes
+# can't be done, or don't work.
+#
+# When a number of probes are done, test -z "$exact_cpu" can be used instead
+# of putting each probe under an "else" of the preceeding. That can stop
+# the code getting horribly nested and marching off the right side of the
+# screen.
+
+# Note that when a compile-and-link is done in one step we need to remove .o
+# files, since lame C compilers generate these even when not asked.
+#
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy $dummy.core ${dummy}0.s" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+
+case "$guess_full" in
+
+alpha-*-*)
+ eval $set_cc_for_build
+ # configfsf.guess detects exact alpha cpu types for OSF and GNU/Linux, but
+ # not for *BSD and other systems. We try to get an exact type for any
+ # plain "alpha" it leaves.
+ #
+ # configfsf.guess used to have a block of code not unlike this, but these
+ # days does its thing with Linux kernel /proc/cpuinfo or OSF psrinfo.
+ #
+ cat <<EOF >${dummy}0.s
+ .data
+Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+ .text
+ .globl main
+ .align 4
+ .ent main
+main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d91 # implver \$17
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,Lformat
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ $CC_FOR_BUILD ${dummy}0.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `$dummy` in
+ 0-0) exact_cpu=alpha ;;
+ 1-0) exact_cpu=alphaev5 ;;
+ 1-1) exact_cpu=alphaev56 ;;
+ 1-101) exact_cpu=alphapca56 ;;
+ 2-303) exact_cpu=alphaev6 ;;
+ 2-307) exact_cpu=alphaev67 ;;
+ 2-1307) exact_cpu=alphaev68 ;;
+ esac
+ fi
+ ;;
+
+arm*-*-*)
+ cpu_code=`sed -n 's/^CPU part.*\(0x.*\)$/\1/p' /proc/cpuinfo 2>/dev/null`
+ case "$cpu_code" in
+ 0xa10 | 0xa11 | 0xb11) # v4 strongarm/sa1100
+ exact_cpu="armsa1";;
+ 0x915 | 0x925 | \
+ 0x920 | 0x922 | 0x940) # v4
+ exact_cpu="arm9tdmi";;
+ 0x210 | 0x290 | 0x2d0 | \
+ 0x212 | 0x292 | 0x2d2 | \
+ 0x411) exact_cpu="armxscale";; # v5 pxa2xx
+ 0x926 | 0x946 | 0x966 | 0x968) # v5te/v5tej
+ exact_cpu="arm9te";;
+ 0xa20 | 0xa22 | 0xa26) # v5te
+ exact_cpu="arm10";;
+ 0xb02) exact_cpu="arm11mpcore";; # v6
+ 0xb36) exact_cpu="arm1136";; # v6
+ 0xb56) exact_cpu="arm1156";; # v6t2
+ 0xb76) exact_cpu="arm1176";; # v6
+ 0xc05) exact_cpu="armcortexa5";; # v7a
+ 0xc07) exact_cpu="armcortexa7";; # v7a
+ 0xc08) exact_cpu="armcortexa8";; # v7a
+ 0xc09) exact_cpu="armcortexa9";; # v7a
+ 0xc0f) exact_cpu="armcortexa15";; # v7a
+ 0xc14) exact_cpu="armcortexr4";; # v7r
+ 0xc15) exact_cpu="armcortexr5";; # v7r
+ 0xc23) exact_cpu="armcortexm3";; # v7m
+ esac
+ exact_cpu="${exact_cpu}`sed -n 's;^Features.*\(neon\).*;\1;p' /proc/cpuinfo 2>/dev/null`"
+ ;;
+
+ia64*-*-*)
+ eval $set_cc_for_build
+ # CPUID[3] bits 24 to 31 is the processor family. itanium2 is documented
+ # as 0x1f, plain itanium has been seen returning 0x07 on two systems, but
+ # haven't found any documentation on it as such.
+ #
+ # Defining both getcpuid and _getcpuid lets us ignore whether the system
+ # expects underscores or not.
+ #
+ # "unsigned long long" is always 64 bits, in fact on hpux in ilp32 mode
+ # (which is the default there), it's the only 64-bit type.
+ #
+ cat >${dummy}0.s <<EOF
+ .text
+ .global _getcpuid
+ .proc _getcpuid
+_getcpuid:
+ mov r8 = CPUID[r32] ;;
+ br.ret.sptk.many rp ;;
+ .endp _getcpuid
+ .global getcpuid
+ .proc getcpuid
+getcpuid:
+ mov r8 = CPUID[r32] ;;
+ br.ret.sptk.many rp ;;
+ .endp getcpuid
+EOF
+ cat >$dummy.c <<EOF
+#include <stdio.h>
+unsigned long long getcpuid ();
+int
+main ()
+{
+ if (getcpuid(0LL) == 0x49656E69756E6547LL && getcpuid(1LL) == 0x6C65746ELL)
+ {
+ /* "GenuineIntel" */
+ switch ((getcpuid(3LL) >> 24) & 0xFF) {
+ case 0x07: puts ("itanium"); break;
+ case 0x1F: puts ("itanium2"); break; /* McKinley, Madison */
+ case 0x20: puts ("itanium2"); break; /* Montecito */
+ }
+ }
+ return 0;
+}
+EOF
+ if $CC_FOR_BUILD ${dummy}0.s $dummy.c -o $dummy >/dev/null 2>&1; then
+ exact_cpu=`$dummy`
+ fi
+ ;;
+
+mips-*-irix[6789]*)
+ # IRIX 6 and up always has a 64-bit mips cpu
+ exact_cpu=mips64
+ ;;
+
+m68k-*-*)
+ eval $set_cc_for_build
+ # NetBSD (and presumably other *BSD) "sysctl hw.model" gives for example
+ # hw.model = Apple Macintosh Quadra 610 (68040)
+ exact_cpu=`(sysctl hw.model) 2>/dev/null | sed -n 's/^.*\(680[012346]0\).*$/m\1/p'`
+ if test -z "$exact_cpu"; then
+ # Linux kernel 2.2 gives for example "CPU: 68020" (tabs in between).
+ exact_cpu=`sed -n 's/^CPU:.*\(680[012346]0\).*$/m\1/p' /proc/cpuinfo 2>/dev/null`
+ fi
+ if test -z "$exact_cpu"; then
+ # Try: movel #0,%d0; rts
+ # This is to check the compiler and our asm code works etc, before
+ # assuming failures below indicate cpu characteristics.
+ # .byte is used to avoid problems with assembler syntax variations.
+ # For testing, provoke failures by adding "illegal" possibly as
+ # ".byte 0x4A, 0xFC"
+ cat >${dummy}0.s <<EOF
+ .text
+ .globl main
+ .globl _main
+main:
+_main:
+ .byte 0x70, 0x00
+ .byte 0x4e, 0x75
+EOF
+
+ if ($CC_FOR_BUILD ${dummy}0.s -o $dummy && $dummy) >/dev/null 2>&1; then
+
+ # $SHELL -c is used to execute $dummy below, since ($dummy)
+ # 2>/dev/null still prints the SIGILL message on some shells.
+ #
+ # Try: movel #0,%d0
+ # rtd #0
+ cat >${dummy}0.s <<EOF
+ .text
+ .globl main
+ .globl _main
+main:
+_main:
+ .byte 0x70, 0x00
+ .byte 0x4e, 0x74, 0x00, 0x00
+EOF
+ if $CC_FOR_BUILD ${dummy}0.s -o $dummy >/dev/null 2>&1; then
+ $SHELL -c $dummy >/dev/null 2>&1
+ if test $? != 0; then
+ exact_cpu=m68000 # because rtd didn't work
+ fi
+ fi
+ #
+
+ if test -z "$exact_cpu"; then
+ # Try: trapf
+ # movel #0,%d0
+ # rts
+ # Another possibility for identifying 68000 and 68010 is the
+ # different value stored by "movem a0,(a0)+"
+ cat >${dummy}0.s <<EOF
+ .text
+ .globl main
+ .globl _main
+main:
+_main:
+ .byte 0x51, 0xFC
+ .byte 0x70, 0x00
+ .byte 0x4e, 0x75
+EOF
+ if $CC_FOR_BUILD ${dummy}0.s -o $dummy >/dev/null 2>&1; then
+ $SHELL -c $dummy >/dev/null 2>&1
+ if test $? != 0; then
+ exact_cpu=m68010 # because trapf didn't work
+ fi
+ fi
+ fi
+
+ if test -z "$exact_cpu"; then
+ # Try: bfffo %d1{0:31},%d0
+ # movel #0,%d0
+ # rts
+ cat >${dummy}0.s <<EOF
+ .text
+ .globl main
+ .globl _main
+main:
+_main:
+ .byte 0xED, 0xC1, 0x00, 0x1F
+ .byte 0x70, 0x00
+ .byte 0x4e, 0x75
+EOF
+ if $CC_FOR_BUILD ${dummy}0.s -o $dummy >/dev/null 2>&1; then
+ $SHELL -c $dummy >/dev/null 2>&1
+ if test $? != 0; then
+ exact_cpu=m68360 # cpu32, because bfffo didn't work
+ fi
+ fi
+ fi
+
+ if test -z "$exact_cpu"; then
+ # FIXME: Now we know 68020 or up, but how to detect 030, 040 and 060?
+ exact_cpu=m68020
+ fi
+ fi
+ fi
+ if test -z "$exact_cpu"; then
+ case "$guess_full" in
+ *-*-next* | *-*-openstep*) # NeXTs are 68020 or better
+ exact_cpu=m68020 ;;
+ esac
+ fi
+ ;;
+
+
+rs6000-*-* | powerpc*-*-*)
+ # Enhancement: On MacOS the "machine" command prints for instance
+ # "ppc750". Interestingly on powerpc970-apple-darwin6.8.5 it prints
+ # "ppc970" where there's no actual #define for 970 from NXGetLocalArchInfo
+ # (as noted below). But the man page says the command is still "under
+ # development", so it doesn't seem wise to use it just yet, not while
+ # there's an alternative.
+ #
+ # Try to read the PVR. mfpvr is a protected instruction, NetBSD, MacOS
+ # and AIX don't allow it in user mode, but the Linux kernel does.
+ #
+ # Using explicit bytes for mfpvr avoids worrying about assembler syntax
+ # and underscores. "char"s are used instead of "int"s to avoid worrying
+ # whether sizeof(int)==4 or if it's the right endianness.
+ #
+ # Note this is no good on AIX, since a C function there is the address of
+ # a function descriptor, not actual code. But this doesn't matter since
+ # AIX doesn't allow mfpvr anyway.
+ #
+ eval $set_cc_for_build
+ cat >$dummy.c <<\EOF
+#include <stdio.h>
+struct {
+ int n; /* force 4-byte alignment */
+ char a[8];
+} getpvr = {
+ 0,
+ {
+ 0x7c, 0x7f, 0x42, 0xa6, /* mfpvr r3 */
+ 0x4e, 0x80, 0x00, 0x20, /* blr */
+ }
+};
+int
+main ()
+{
+ unsigned (*fun)();
+ unsigned pvr;
+
+ /* a separate "fun" variable is necessary for gcc 2.95.2 on MacOS,
+ it gets a compiler error on a combined cast and call */
+ fun = (unsigned (*)()) getpvr.a;
+ pvr = (*fun) ();
+
+ switch (pvr >> 16) {
+ case 0x0001: puts ("powerpc601"); break;
+ case 0x0003: puts ("powerpc603"); break;
+ case 0x0004: puts ("powerpc604"); break;
+ case 0x0006: puts ("powerpc603e"); break;
+ case 0x0007: puts ("powerpc603e"); break; /* 603ev */
+ case 0x0008: puts ("powerpc750"); break;
+ case 0x0009: puts ("powerpc604e"); break;
+ case 0x000a: puts ("powerpc604e"); break; /* 604ev5 */
+ case 0x000c: puts ("powerpc7400"); break;
+ case 0x0041: puts ("powerpc630"); break;
+ case 0x0050: puts ("powerpc860"); break;
+ case 0x8000: puts ("powerpc7450"); break;
+ case 0x8001: puts ("powerpc7455"); break;
+ case 0x8002: puts ("powerpc7457"); break;
+ case 0x8003: puts ("powerpc7447"); break; /* really 7447A */
+ case 0x800c: puts ("powerpc7410"); break;
+ }
+ return 0;
+}
+EOF
+ if ($CC_FOR_BUILD $dummy.c -o $dummy) >/dev/null 2>&1; then
+ # This style construct is needed on AIX 4.3 to suppress the SIGILL error
+ # from (*fun)(). Using $SHELL -c $dummy 2>/dev/null doesn't work.
+ { x=`$dummy`; } 2>/dev/null
+ if test -n "$x"; then
+ exact_cpu=$x
+ fi
+ fi
+
+ # Grep the linux kernel /proc/cpuinfo pseudo-file.
+ # Anything unrecognised is ignored, since of course we mustn't spit out
+ # a cpu type config.sub doesn't know.
+ if test -z "$exact_cpu" && test -f /proc/cpuinfo; then
+ x=`grep "^cpu[ ]" /proc/cpuinfo | head -n 1`
+ x=`echo $x | sed -n 's/^cpu[ ]*:[ ]*\([A-Za-z0-9]*\).*/\1/p'`
+ x=`echo $x | sed 's/PPC//'`
+ case $x in
+ 601) exact_cpu="power" ;;
+ 603ev) exact_cpu="powerpc603e" ;;
+ 604ev5) exact_cpu="powerpc604e" ;;
+ 970??) exact_cpu="powerpc970" ;;
+ 603 | 603e | 604 | 604e | 750 | 821 | 860)
+ exact_cpu="powerpc$x" ;;
+ POWER[4-9])
+ exact_cpu=`echo $x | sed "s;POWER;power;"` ;;
+ esac
+ fi
+
+ if test -z "$exact_cpu"; then
+ # On AIX, try looking at _system_configuration. This is present in
+ # version 4 at least.
+ cat >$dummy.c <<EOF
+#include <stdio.h>
+#include <sys/systemcfg.h>
+int
+main ()
+{
+ switch (_system_configuration.implementation) {
+ /* Old versions of AIX don't have all these constants,
+ use ifdef for safety. */
+#ifdef POWER_RS2
+ case POWER_RS2: puts ("power2"); break;
+#endif
+#ifdef POWER_601
+ case POWER_601: puts ("power"); break;
+#endif
+#ifdef POWER_603
+ case POWER_603: puts ("powerpc603"); break;
+#endif
+#ifdef POWER_604
+ case POWER_604: puts ("powerpc604"); break;
+#endif
+#ifdef POWER_620
+ case POWER_620: puts ("powerpc620"); break;
+#endif
+#ifdef POWER_630
+ case POWER_630: puts ("powerpc630"); break;
+#endif
+ /* Dunno what this is, leave it out for now.
+ case POWER_A35: puts ("powerpca35"); break;
+ */
+ /* This is waiting for a bit more info.
+ case POWER_RS64II: puts ("powerpcrs64ii"); break;
+ */
+#ifdef POWER_4
+ case POWER_4: puts ("power4"); break;
+#endif
+#ifdef POWER_5
+ case POWER_5: puts ("power5"); break;
+#endif
+#ifdef POWER_6
+ case POWER_6: puts ("power6"); break;
+#endif
+#ifdef POWER_7
+ case POWER_7: puts ("power7"); break;
+#endif
+ default:
+ if (_system_configuration.architecture == POWER_RS)
+ puts ("power");
+ else if (_system_configuration.width == 64)
+ puts ("powerpc64");
+ }
+ return 0;
+}
+EOF
+ if ($CC_FOR_BUILD $dummy.c -o $dummy) >/dev/null 2>&1; then
+ x=`$dummy`
+ if test -n "$x"; then
+ exact_cpu=$x
+ fi
+ fi
+ fi
+
+ if test -z "$exact_cpu"; then
+ # On MacOS X (or any Mach-O presumably), NXGetLocalArchInfo cpusubtype
+ # can tell us the exact cpu.
+ cat >$dummy.c <<EOF
+#include <stdio.h>
+#include <mach-o/arch.h>
+int
+main (void)
+{
+ const NXArchInfo *a = NXGetLocalArchInfo();
+ if (a->cputype == CPU_TYPE_POWERPC)
+ {
+ switch (a->cpusubtype) {
+ /* The following known to Darwin 1.3. */
+ case CPU_SUBTYPE_POWERPC_601: puts ("powerpc601"); break;
+ case CPU_SUBTYPE_POWERPC_602: puts ("powerpc602"); break;
+ case CPU_SUBTYPE_POWERPC_603: puts ("powerpc603"); break;
+ case CPU_SUBTYPE_POWERPC_603e: puts ("powerpc603e"); break;
+ case CPU_SUBTYPE_POWERPC_603ev: puts ("powerpc603e"); break;
+ case CPU_SUBTYPE_POWERPC_604: puts ("powerpc604"); break;
+ case CPU_SUBTYPE_POWERPC_604e: puts ("powerpc604e"); break;
+ case CPU_SUBTYPE_POWERPC_620: puts ("powerpc620"); break;
+ case CPU_SUBTYPE_POWERPC_750: puts ("powerpc750"); break;
+ case CPU_SUBTYPE_POWERPC_7400: puts ("powerpc7400"); break;
+ case CPU_SUBTYPE_POWERPC_7450: puts ("powerpc7450"); break;
+ /* Darwin 6.8.5 doesn't define the following */
+ case 0x8001: puts ("powerpc7455"); break;
+ case 0x8002: puts ("powerpc7457"); break;
+ case 0x8003: puts ("powerpc7447"); break;
+ case 100: puts ("powerpc970"); break;
+ }
+ }
+ return 0;
+}
+EOF
+ if ($CC_FOR_BUILD $dummy.c -o $dummy) >/dev/null 2>&1; then
+ x=`$dummy`
+ if test -n "$x"; then
+ exact_cpu=$x
+ fi
+ fi
+ fi
+ ;;
+
+sparc-*-* | sparc64-*-*)
+ # If we can recognise an actual v7 then $exact_cpu is set to "sparc" so as
+ # to short-circuit subsequent tests.
+
+ # Grep the linux kernel /proc/cpuinfo pseudo-file.
+ # A typical line is "cpu\t\t: TI UltraSparc II (BlackBird)"
+ # See arch/sparc/kernel/cpu.c and arch/sparc64/kernel/cpu.c.
+ #
+ if test -f /proc/cpuinfo; then
+ if grep 'cpu.*Cypress' /proc/cpuinfo >/dev/null; then
+ exact_cpu="sparc" # ie. v7
+ elif grep 'cpu.*Power-UP' /proc/cpuinfo >/dev/null; then
+ exact_cpu="sparc" # ie. v7
+ elif grep 'cpu.*HyperSparc' /proc/cpuinfo >/dev/null; then
+ exact_cpu="sparcv8"
+ elif grep 'cpu.*SuperSparc' /proc/cpuinfo >/dev/null; then
+ exact_cpu="supersparc"
+ elif grep 'cpu.*MicroSparc' /proc/cpuinfo >/dev/null; then
+ exact_cpu="microsparc"
+ elif grep 'cpu.*MB86904' /proc/cpuinfo >/dev/null; then
+ # actually MicroSPARC-II
+ exact_cpu=microsparc
+ elif grep 'cpu.*UltraSparc T4' /proc/cpuinfo >/dev/null; then
+ exact_cpu="ultrasparct4"
+ elif grep 'cpu.*UltraSparc T3' /proc/cpuinfo >/dev/null; then
+ exact_cpu="ultrasparct3"
+ elif grep 'cpu.*UltraSparc T2' /proc/cpuinfo >/dev/null; then
+ exact_cpu="ultrasparct2"
+ elif grep 'cpu.*UltraSparc T1' /proc/cpuinfo >/dev/null; then
+ exact_cpu="ultrasparct1"
+ elif grep 'cpu.*UltraSparc III' /proc/cpuinfo >/dev/null; then
+ exact_cpu="ultrasparc3"
+ elif grep 'cpu.*UltraSparc IIi' /proc/cpuinfo >/dev/null; then
+ exact_cpu="ultrasparc2i"
+ elif grep 'cpu.*UltraSparc II' /proc/cpuinfo >/dev/null; then
+ exact_cpu="ultrasparc2"
+ elif grep 'cpu.*UltraSparc' /proc/cpuinfo >/dev/null; then
+ exact_cpu="ultrasparc"
+ fi
+ fi
+
+ # Need to invoke this for setup of $dummy
+ eval $set_cc_for_build
+
+ # Grep the output from sysinfo on SunOS.
+ # sysinfo has been seen living in /bin or in /usr/kvm
+ # cpu0 is a "SuperSPARC Model 41 SPARCmodule" CPU
+ # cpu0 is a "75 MHz TI,TMS390Z55" CPU
+ #
+ if test -z "$exact_cpu"; then
+ for i in sysinfo /usr/kvm/sysinfo; do
+ if $SHELL -c $i 2>/dev/null >$dummy; then
+ if grep 'cpu0 is a "SuperSPARC' $dummy >/dev/null; then
+ exact_cpu=supersparc
+ break
+ elif grep 'cpu0 is a .*TMS390Z5.' $dummy >/dev/null; then
+ # TMS390Z50 and TMS390Z55
+ exact_cpu=supersparc
+ break
+ fi
+ fi
+ done
+ fi
+
+ # Grep the output from prtconf on Solaris.
+ # Use an explicit /usr/sbin, since that directory might not be in a normal
+ # user's path.
+ #
+ # SUNW,UltraSPARC (driver not attached)
+ # SUNW,UltraSPARC-II (driver not attached)
+ # SUNW,UltraSPARC-IIi (driver not attached)
+ # SUNW,UltraSPARC-III+ (driver not attached)
+ # Ross,RT625 (driver not attached)
+ # TI,TMS390Z50 (driver not attached)
+ #
+ # /usr/sbin/sysdef prints similar information, but includes all loadable
+ # cpu modules, not just the real cpu.
+ #
+ # We first try a plain prtconf, since that is known to work on older systems.
+ # But for newer T1 systems, that doesn't produce any useful output, we need
+ # "prtconf -vp" there.
+ #
+ for prtconfopt in "" "-vp"; do
+ if test -z "$exact_cpu"; then
+ if $SHELL -c "/usr/sbin/prtconf $prtconfopt" 2>/dev/null >$dummy; then
+ if grep 'SUNW,UltraSPARC-T3' $dummy >/dev/null; then
+ exact_cpu=ultrasparct3
+ elif grep 'SUNW,UltraSPARC-T2' $dummy >/dev/null; then
+ exact_cpu=ultrasparct2
+ elif grep 'SUNW,UltraSPARC-T1' $dummy >/dev/null; then
+ exact_cpu=ultrasparct1
+ elif grep 'SUNW,UltraSPARC-III' $dummy >/dev/null; then
+ exact_cpu=ultrasparc3
+ elif grep 'SUNW,UltraSPARC-IIi' $dummy >/dev/null; then
+ exact_cpu=ultrasparc2i
+ elif grep 'SUNW,UltraSPARC-II' $dummy >/dev/null; then
+ exact_cpu=ultrasparc2
+ elif grep 'SUNW,UltraSPARC' $dummy >/dev/null; then
+ exact_cpu=ultrasparc
+ elif grep 'Ross,RT62.' $dummy >/dev/null; then
+ # RT620, RT625, RT626 hypersparcs (v8).
+ exact_cpu=sparcv8
+ elif grep 'TI,TMS390Z5.' $dummy >/dev/null; then
+ # TMS390Z50 and TMS390Z55
+ exact_cpu=supersparc
+ elif grep 'TI,TMS390S10' $dummy >/dev/null; then
+ exact_cpu=microsparc
+ elif grep 'FMI,MB86904' $dummy >/dev/null; then
+ # actually MicroSPARC-II
+ exact_cpu=microsparc
+ fi
+ fi
+ fi
+ done
+
+ # Grep the output from sysctl hw.model on sparc or sparc64 *BSD.
+ # Use an explicit /sbin, since that directory might not be in a normal
+ # user's path. Example outputs,
+ #
+ # hw.model: Sun Microsystems UltraSparc-IIi
+ #
+ if test -z "$exact_cpu"; then
+ if $SHELL -c "/sbin/sysctl hw.model" 2>/dev/null >$dummy; then
+ if grep -i 'UltraSparc-T3' $dummy >/dev/null; then
+ exact_cpu=ultrasparct3
+ elif grep -i 'UltraSparc-T2' $dummy >/dev/null; then
+ exact_cpu=ultrasparct2
+ elif grep -i 'UltraSparc-T1' $dummy >/dev/null; then
+ exact_cpu=ultrasparct1
+ elif grep -i 'UltraSparc-III' $dummy >/dev/null; then
+ exact_cpu=ultrasparc3
+ elif grep -i 'UltraSparc-IIi' $dummy >/dev/null; then
+ exact_cpu=ultrasparc2i
+ elif grep -i 'UltraSparc-II' $dummy >/dev/null; then
+ exact_cpu=ultrasparc2
+ elif grep -i 'UltraSparc' $dummy >/dev/null; then
+ exact_cpu=ultrasparc
+ elif grep 'TMS390Z5.' $dummy >/dev/null; then
+ # TMS390Z50 and TMS390Z55
+ exact_cpu=supersparc
+ elif grep 'TMS390S10' $dummy >/dev/null; then
+ exact_cpu=microsparc
+ elif grep 'MB86904' $dummy >/dev/null; then
+ # actually MicroSPARC-II
+ exact_cpu=microsparc
+ elif grep 'MB86907' $dummy >/dev/null; then
+ exact_cpu=turbosparc
+ fi
+ fi
+ fi
+
+ # sun4m and sun4d are v8s of some sort, sun4u is a v9 of some sort
+ #
+ if test -z "$exact_cpu"; then
+ case `uname -m` in
+ sun4[md]) exact_cpu=sparcv8 ;;
+ sun4u) exact_cpu=sparcv9 ;;
+ esac
+ fi
+ ;;
+
+
+# Recognise x86 processors using a tricky cpuid with 4 arguments, repeating
+# arguments; for x86-64 we effectively pass the 1st in rdx and the 2nd in rcx.
+# This allows the same asm to work for both standard and Windoze calling
+# conventions.
+
+i?86-*-* | amd64-*-* | x86_64-*-*)
+ eval $set_cc_for_build
+
+ cat <<EOF >$dummy.c
+#include <string.h>
+#include <stdio.h>
+#define CPUID(a,b) cpuid(b,a,a,b)
+#if __cplusplus
+extern "C"
+#endif
+unsigned int cpuid (int, char *, char *, int);
+int
+main ()
+{
+ char vendor_string[13];
+ char dummy_string[12];
+ long fms;
+ int family, model, stepping;
+ const char *modelstr;
+ int cpu_64bit = 0;
+ int cpuid_64bit;
+
+ CPUID (vendor_string, 0);
+ vendor_string[12] = 0;
+
+ fms = CPUID (dummy_string, 1);
+
+ family = ((fms >> 8) & 0xf) + ((fms >> 20) & 0xff);
+ model = ((fms >> 4) & 0xf) + ((fms >> 12) & 0xf0);
+ stepping = fms & 0xf;
+
+ modelstr = "$guess_cpu";
+
+ /**************************************************/
+ /*** WARNING: keep this list in sync with fat.c ***/
+ /**************************************************/
+ if (strcmp (vendor_string, "GenuineIntel") == 0)
+ {
+ switch (family)
+ {
+ case 5:
+ if (model <= 2) modelstr = "pentium";
+ else if (model >= 4) modelstr = "pentiummmx";
+ break;
+ case 6:
+ if (model <= 1) modelstr = "pentiumpro";
+ else if (model <= 6) modelstr = "pentium2";
+ else if (model <= 8) modelstr = "pentium3";
+ else if (model <= 9) modelstr = "pentiumm";
+ else if (model <= 0x0c) modelstr = "pentium3";
+ else if (model <= 0x0e) modelstr = "pentiumm";
+ else if (model <= 0x19) cpu_64bit = 1, modelstr = "core2";
+ else if (model == 0x1a) cpu_64bit = 1, modelstr = "coreinhm"; /* NHM Gainestown */
+ else if (model == 0x1c) cpu_64bit = 1, modelstr = "atom"; /* Silverthorne */
+ else if (model == 0x1d) cpu_64bit = 1, modelstr = "core2"; /* PNR Dunnington */
+ else if (model == 0x1e) cpu_64bit = 1, modelstr = "coreinhm"; /* NHM Lynnfield/Jasper */
+ else if (model == 0x25) cpu_64bit = 1, modelstr = "coreiwsm"; /* WSM Clarkdale/Arrandale */
+ else if (model == 0x26) cpu_64bit = 1, modelstr = "atom"; /* Lincroft */
+ else if (model == 0x27) cpu_64bit = 1, modelstr = "atom"; /* Saltwell */
+ else if (model == 0x2a) cpu_64bit = 1, modelstr = "coreisbr"; /* SB */
+ else if (model == 0x2c) cpu_64bit = 1, modelstr = "coreiwsm"; /* WSM Gulftown */
+ else if (model == 0x2d) cpu_64bit = 1, modelstr = "coreisbr"; /* SBC-EP */
+ else if (model == 0x2e) cpu_64bit = 1, modelstr = "coreinhm"; /* NHM Beckton */
+ else if (model == 0x2f) cpu_64bit = 1, modelstr = "coreiwsm"; /* WSM Eagleton */
+ else if (model == 0x36) cpu_64bit = 1, modelstr = "atom"; /* Cedarview/Saltwell */
+ else if (model == 0x37) cpu_64bit = 1, modelstr = "coreinhm"; /* Atom Silvermont */
+ else if (model == 0x3a) cpu_64bit = 1, modelstr = "coreisbr"; /* IBR */
+ else if (model == 0x3c) cpu_64bit = 1, modelstr = "coreihwl"; /* Haswell client */
+ else if (model == 0x3d) cpu_64bit = 1, modelstr = "coreibwl"; /* Broadwell */
+ else if (model == 0x3e) cpu_64bit = 1, modelstr = "coreisbr"; /* Ivytown */
+ else if (model == 0x3f) cpu_64bit = 1, modelstr = "coreihwl"; /* Haswell server */
+ else if (model == 0x45) cpu_64bit = 1, modelstr = "coreihwl"; /* Haswell ULT */
+ else if (model == 0x46) cpu_64bit = 1, modelstr = "coreihwl"; /* Crystal Well */
+ else if (model == 0x4d) cpu_64bit = 1, modelstr = "coreinhm"; /* Silvermont/Avoton */
+ else if (model == 0x4f) cpu_64bit = 1, modelstr = "coreibwl"; /* Broadwell server */
+ else if (model == 0x56) cpu_64bit = 1, modelstr = "coreibwl"; /* Broadwell microserver */
+ else cpu_64bit = 1, modelstr = "corei"; /* default */
+
+ if (strcmp (modelstr, "coreihwl") == 0)
+ {
+ /* Some Haswells lack BMI2. Let them appear as Sandybridges for
+ now. */
+ CPUID (dummy_string, 7);
+ if ((dummy_string[0 + 8 / 8] & (1 << (8 % 8))) == 0)
+ modelstr = "coreisbr";
+ }
+
+ break;
+ case 15:
+ cpu_64bit = 1, modelstr = "pentium4";
+ break;
+ }
+ }
+ else if (strcmp (vendor_string, "AuthenticAMD") == 0)
+ {
+ switch (family)
+ {
+ case 5:
+ if (model <= 3) modelstr = "k5";
+ else if (model <= 7) modelstr = "k6";
+ else if (model == 8) modelstr = "k62";
+ else if (model == 9) modelstr = "k63";
+ else if (model == 10) modelstr = "geode";
+ else if (model == 13) modelstr = "k63";
+ break;
+ case 6:
+ modelstr = "athlon";
+ break;
+ case 15: /* K8, K9 */
+ cpu_64bit = 1, modelstr = "k8";
+ break;
+ case 16: /* K10 */
+ cpu_64bit = 1, modelstr = "k10";
+ break;
+ case 17: /* Hybrid k8/k10, claim k8 */
+ cpu_64bit = 1, modelstr = "k8";
+ break;
+ case 18: /* Llano, uses K10 core */
+ cpu_64bit = 1, modelstr = "k10";
+ break;
+ case 19: /* AMD Internal, assume future K10 */
+ cpu_64bit = 1, modelstr = "k10";
+ break;
+ case 20: /* Bobcat */
+ cpu_64bit = 1, modelstr = "bobcat";
+ break;
+ case 21: /* Bulldozer */
+ cpu_64bit = 1;
+ if (model <= 1)
+ modelstr = "bulldozer";
+ else if (model < 0x20) /* really 2, [0x10-0x20) */
+ modelstr = "piledriver";
+ else if (model < 0x40) /* really [0x30-0x40) */
+ modelstr = "steamroller";
+ else /* really [0x60-0x70) */
+ modelstr = "excavator";
+ break;
+ case 22: /* Jaguar, an improved bobcat */
+ cpu_64bit = 1, modelstr = "jaguar";
+ break;
+ }
+ }
+ else if (strcmp (vendor_string, "CyrixInstead") == 0)
+ {
+ /* Should recognize Cyrix' processors too. */
+ }
+ else if (strcmp (vendor_string, "CentaurHauls") == 0)
+ {
+ switch (family)
+ {
+ case 6:
+ if (model < 9) modelstr = "viac3";
+ else if (model < 15) modelstr = "viac32";
+ else cpu_64bit = 1, modelstr = "nano";
+ break;
+ }
+ }
+
+ CPUID (dummy_string, 0x80000001);
+ cpuid_64bit = (dummy_string[7] >> 5) & 1;
+
+ /* If our cpuid-based CPU identification thinks this is a 32-bit CPU but
+ cpuid claims AMD64 capabilities, then revert to the generic "x86_64".
+ This is of course wrong, but it can happen in some emulators, so this
+ workaround allows for successful 64-bit builds. */
+ if (cpuid_64bit && ! cpu_64bit)
+ modelstr = "x86_64";
+
+ printf ("%s", modelstr);
+ return 0;
+}
+EOF
+
+# The rcx/ecx zeroing here and in the variant below is needed for the BMI2
+# check.
+
+ cat <<EOF >${dummy}0.s
+ .globl cpuid
+ .globl _cpuid
+cpuid:
+_cpuid:
+ push %rbx
+ mov %rdx, %r8
+ mov %ecx, %eax
+ xor %ecx, %ecx
+ .byte 0x0f
+ .byte 0xa2
+ mov %ebx, (%r8)
+ mov %edx, 4(%r8)
+ mov %ecx, 8(%r8)
+ pop %rbx
+ ret
+EOF
+
+ if ($CC_FOR_BUILD ${dummy}0.s $dummy.c -o $dummy) >/dev/null 2>&1; then
+ # On 80386 and early 80486 cpuid is not available and will result in a
+ # SIGILL message, hence 2>/dev/null.
+ #
+ # On i386-unknown-freebsd4.9, "/bin/sh -c ./dummy" seems to send an
+ # "Illegal instruction (core dumped)" message to stdout, so we test $?
+ # to check if the program run was successful.
+ #
+ x=`$SHELL -c $dummy 2>/dev/null`
+ if test $? = 0 && test -n "$x"; then
+ exact_cpu=$x
+ fi
+ fi
+
+ cat <<EOF >${dummy}0.s
+ .globl cpuid
+ .globl _cpuid
+cpuid:
+_cpuid:
+ pushl %esi
+ pushl %ebx
+ movl 24(%esp),%eax
+ xor %ecx, %ecx
+ .byte 0x0f
+ .byte 0xa2
+ movl 20(%esp),%esi
+ movl %ebx,(%esi)
+ movl %edx,4(%esi)
+ movl %ecx,8(%esi)
+ popl %ebx
+ popl %esi
+ ret
+EOF
+
+ if test -z "$exact_cpu"; then
+ if ($CC_FOR_BUILD ${dummy}0.s $dummy.c -o $dummy) >/dev/null 2>&1; then
+ # On 80386 and early 80486 cpuid is not available and will result in a
+ # SIGILL message, hence 2>/dev/null.
+ #
+ # On i386-unknown-freebsd4.9, "/bin/sh -c ./dummy" seems to send an
+ # "Illegal instruction (core dumped)" message to stdout, so we test $?
+ # to check if the program run was successful.
+ #
+ x=`$SHELL -c $dummy 2>/dev/null`
+ if test $? = 0 && test -n "$x"; then
+ exact_cpu=$x
+ fi
+ fi
+ fi
+
+ # We need to remove some .o files here since lame C compilers
+ # generate these even when not asked.
+ ;;
+
+s390*-*-*)
+ model=`grep "^processor 0: version =" /proc/cpuinfo | sed -e 's/.*machine = //'`
+ case $model in
+ 2064 | 2066) zcpu="z900" ;;
+ 2084 | 2086) zcpu="z990" ;;
+ 2094 | 2096) zcpu="z9" ;;
+ 2097 | 2098) zcpu="z10" ;;
+ 2817 | 2818 | *) zcpu="z196" ;;
+ esac
+ case "$guess_full" in
+ s390x-*-*) exact_cpu=${zcpu} ;;
+ s390-*-*) exact_cpu=${zcpu}esa ;;
+ esac
+ ;;
+
+esac
+
+
+
+# -------------------------------------------------------------------------
+# Use an exact cpu, if possible
+
+if test -n "$exact_cpu"; then
+ echo "$exact_cpu$guess_rest"
+else
+ echo "$guess_full"
+fi
+exit 0
+
+
+
+# Local variables:
+# fill-column: 76
+# End:
diff --git a/gmp/config.in b/gmp/config.in
new file mode 100644
index 0000000000..e94acd7c03
--- /dev/null
+++ b/gmp/config.in
@@ -0,0 +1,640 @@
+/* config.in. Generated from configure.ac by autoheader. */
+
+/*
+
+Copyright 1996-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+*/
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* The gmp-mparam.h file (a string) the tune program should suggest updating.
+ */
+#undef GMP_MPARAM_H_SUGGEST
+
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
+/* Define to 1 if alloca() works (via gmp-impl.h). */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if the compiler accepts gcc style __attribute__ ((const)) */
+#undef HAVE_ATTRIBUTE_CONST
+
+/* Define to 1 if the compiler accepts gcc style __attribute__ ((malloc)) */
+#undef HAVE_ATTRIBUTE_MALLOC
+
+/* Define to 1 if the compiler accepts gcc style __attribute__ ((mode (XX)))
+ */
+#undef HAVE_ATTRIBUTE_MODE
+
+/* Define to 1 if the compiler accepts gcc style __attribute__ ((noreturn)) */
+#undef HAVE_ATTRIBUTE_NORETURN
+
+/* Define to 1 if you have the `attr_get' function. */
+#undef HAVE_ATTR_GET
+
+/* Define to 1 if tests/libtests has calling conventions checking for the CPU
+ */
+#undef HAVE_CALLING_CONVENTIONS
+
+/* Define to 1 if you have the `clock' function. */
+#undef HAVE_CLOCK
+
+/* Define to 1 if you have the `clock_gettime' function */
+#undef HAVE_CLOCK_GETTIME
+
+/* Define to 1 if you have the `cputime' function. */
+#undef HAVE_CPUTIME
+
+/* Define to 1 if you have the declaration of `fgetc', and to 0 if you don't.
+ */
+#undef HAVE_DECL_FGETC
+
+/* Define to 1 if you have the declaration of `fscanf', and to 0 if you don't.
+ */
+#undef HAVE_DECL_FSCANF
+
+/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't.
+ */
+#undef HAVE_DECL_OPTARG
+
+/* Define to 1 if you have the declaration of `sys_errlist', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SYS_ERRLIST
+
+/* Define to 1 if you have the declaration of `sys_nerr', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SYS_NERR
+
+/* Define to 1 if you have the declaration of `ungetc', and to 0 if you don't.
+ */
+#undef HAVE_DECL_UNGETC
+
+/* Define to 1 if you have the declaration of `vfprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_VFPRINTF
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define one of the following to 1 for the format of a `double'.
+ If your format is not among these choices, or you don't know what it is,
+ then leave all undefined.
+ IEEE_LITTLE_SWAPPED means little endian, but with the two 4-byte halves
+ swapped, as used by ARM CPUs in little endian mode. */
+#undef HAVE_DOUBLE_IEEE_BIG_ENDIAN
+#undef HAVE_DOUBLE_IEEE_LITTLE_ENDIAN
+#undef HAVE_DOUBLE_IEEE_LITTLE_SWAPPED
+#undef HAVE_DOUBLE_VAX_D
+#undef HAVE_DOUBLE_VAX_G
+#undef HAVE_DOUBLE_CRAY_CFP
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the <float.h> header file. */
+#undef HAVE_FLOAT_H
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `getsysinfo' function. */
+#undef HAVE_GETSYSINFO
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define one of these to 1 for the host CPU family.
+ If your CPU is not in any of these families, leave all undefined.
+ For an AMD64 chip, define "x86" in ABI=32, but not in ABI=64. */
+#undef HAVE_HOST_CPU_FAMILY_alpha
+#undef HAVE_HOST_CPU_FAMILY_m68k
+#undef HAVE_HOST_CPU_FAMILY_power
+#undef HAVE_HOST_CPU_FAMILY_powerpc
+#undef HAVE_HOST_CPU_FAMILY_x86
+#undef HAVE_HOST_CPU_FAMILY_x86_64
+
+/* Define one of the following to 1 for the host CPU, as per the output of
+ ./config.guess. If your CPU is not listed here, leave all undefined. */
+#undef HAVE_HOST_CPU_alphaev67
+#undef HAVE_HOST_CPU_alphaev68
+#undef HAVE_HOST_CPU_alphaev7
+#undef HAVE_HOST_CPU_m68020
+#undef HAVE_HOST_CPU_m68030
+#undef HAVE_HOST_CPU_m68040
+#undef HAVE_HOST_CPU_m68060
+#undef HAVE_HOST_CPU_m68360
+#undef HAVE_HOST_CPU_powerpc604
+#undef HAVE_HOST_CPU_powerpc604e
+#undef HAVE_HOST_CPU_powerpc750
+#undef HAVE_HOST_CPU_powerpc7400
+#undef HAVE_HOST_CPU_supersparc
+#undef HAVE_HOST_CPU_i386
+#undef HAVE_HOST_CPU_i586
+#undef HAVE_HOST_CPU_i686
+#undef HAVE_HOST_CPU_pentium
+#undef HAVE_HOST_CPU_pentiummmx
+#undef HAVE_HOST_CPU_pentiumpro
+#undef HAVE_HOST_CPU_pentium2
+#undef HAVE_HOST_CPU_pentium3
+#undef HAVE_HOST_CPU_s390_z900
+#undef HAVE_HOST_CPU_s390_z990
+#undef HAVE_HOST_CPU_s390_z9
+#undef HAVE_HOST_CPU_s390_z10
+#undef HAVE_HOST_CPU_s390_z196
+
+/* Define to 1 iff we have a s390 with 64-bit registers. */
+#undef HAVE_HOST_CPU_s390_zarch
+
+/* Define to 1 if the system has the type `intmax_t'. */
+#undef HAVE_INTMAX_T
+
+/* Define to 1 if the system has the type `intptr_t'. */
+#undef HAVE_INTPTR_T
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <invent.h> header file. */
+#undef HAVE_INVENT_H
+
+/* Define to 1 if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H
+
+/* Define one of these to 1 for the endianness of `mp_limb_t'.
+ If the endianness is not a simple big or little, or you don't know what
+ it is, then leave both undefined. */
+#undef HAVE_LIMB_BIG_ENDIAN
+#undef HAVE_LIMB_LITTLE_ENDIAN
+
+/* Define to 1 if you have the `localeconv' function. */
+#undef HAVE_LOCALECONV
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define to 1 if the system has the type `long double'. */
+#undef HAVE_LONG_DOUBLE
+
+/* Define to 1 if the system has the type `long long'. */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
+#undef HAVE_MACHINE_HAL_SYSINFO_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `mprotect' function. */
+#undef HAVE_MPROTECT
+
+/* Define to 1 each of the following for which a native (ie. CPU specific)
+ implementation of the corresponding routine exists. */
+#undef HAVE_NATIVE_mpn_add_n
+#undef HAVE_NATIVE_mpn_add_n_sub_n
+#undef HAVE_NATIVE_mpn_add_nc
+#undef HAVE_NATIVE_mpn_addaddmul_1msb0
+#undef HAVE_NATIVE_mpn_addlsh1_n
+#undef HAVE_NATIVE_mpn_addlsh2_n
+#undef HAVE_NATIVE_mpn_addlsh_n
+#undef HAVE_NATIVE_mpn_addlsh1_nc
+#undef HAVE_NATIVE_mpn_addlsh2_nc
+#undef HAVE_NATIVE_mpn_addlsh_nc
+#undef HAVE_NATIVE_mpn_addlsh1_n_ip1
+#undef HAVE_NATIVE_mpn_addlsh2_n_ip1
+#undef HAVE_NATIVE_mpn_addlsh_n_ip1
+#undef HAVE_NATIVE_mpn_addlsh1_nc_ip1
+#undef HAVE_NATIVE_mpn_addlsh2_nc_ip1
+#undef HAVE_NATIVE_mpn_addlsh_nc_ip1
+#undef HAVE_NATIVE_mpn_addlsh1_n_ip2
+#undef HAVE_NATIVE_mpn_addlsh2_n_ip2
+#undef HAVE_NATIVE_mpn_addlsh_n_ip2
+#undef HAVE_NATIVE_mpn_addlsh1_nc_ip2
+#undef HAVE_NATIVE_mpn_addlsh2_nc_ip2
+#undef HAVE_NATIVE_mpn_addlsh_nc_ip2
+#undef HAVE_NATIVE_mpn_addmul_1c
+#undef HAVE_NATIVE_mpn_addmul_2
+#undef HAVE_NATIVE_mpn_addmul_3
+#undef HAVE_NATIVE_mpn_addmul_4
+#undef HAVE_NATIVE_mpn_addmul_5
+#undef HAVE_NATIVE_mpn_addmul_6
+#undef HAVE_NATIVE_mpn_addmul_7
+#undef HAVE_NATIVE_mpn_addmul_8
+#undef HAVE_NATIVE_mpn_addmul_2s
+#undef HAVE_NATIVE_mpn_and_n
+#undef HAVE_NATIVE_mpn_andn_n
+#undef HAVE_NATIVE_mpn_bdiv_dbm1c
+#undef HAVE_NATIVE_mpn_bdiv_q_1
+#undef HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#undef HAVE_NATIVE_mpn_cnd_add_n
+#undef HAVE_NATIVE_mpn_cnd_sub_n
+#undef HAVE_NATIVE_mpn_com
+#undef HAVE_NATIVE_mpn_copyd
+#undef HAVE_NATIVE_mpn_copyi
+#undef HAVE_NATIVE_mpn_div_qr_1n_pi1
+#undef HAVE_NATIVE_mpn_div_qr_2
+#undef HAVE_NATIVE_mpn_divexact_1
+#undef HAVE_NATIVE_mpn_divexact_by3c
+#undef HAVE_NATIVE_mpn_divrem_1
+#undef HAVE_NATIVE_mpn_divrem_1c
+#undef HAVE_NATIVE_mpn_divrem_2
+#undef HAVE_NATIVE_mpn_gcd_1
+#undef HAVE_NATIVE_mpn_hamdist
+#undef HAVE_NATIVE_mpn_invert_limb
+#undef HAVE_NATIVE_mpn_ior_n
+#undef HAVE_NATIVE_mpn_iorn_n
+#undef HAVE_NATIVE_mpn_lshift
+#undef HAVE_NATIVE_mpn_lshiftc
+#undef HAVE_NATIVE_mpn_lshsub_n
+#undef HAVE_NATIVE_mpn_mod_1
+#undef HAVE_NATIVE_mpn_mod_1_1p
+#undef HAVE_NATIVE_mpn_mod_1c
+#undef HAVE_NATIVE_mpn_mod_1s_2p
+#undef HAVE_NATIVE_mpn_mod_1s_4p
+#undef HAVE_NATIVE_mpn_mod_34lsub1
+#undef HAVE_NATIVE_mpn_modexact_1_odd
+#undef HAVE_NATIVE_mpn_modexact_1c_odd
+#undef HAVE_NATIVE_mpn_mul_1
+#undef HAVE_NATIVE_mpn_mul_1c
+#undef HAVE_NATIVE_mpn_mul_2
+#undef HAVE_NATIVE_mpn_mul_3
+#undef HAVE_NATIVE_mpn_mul_4
+#undef HAVE_NATIVE_mpn_mul_5
+#undef HAVE_NATIVE_mpn_mul_6
+#undef HAVE_NATIVE_mpn_mul_basecase
+#undef HAVE_NATIVE_mpn_nand_n
+#undef HAVE_NATIVE_mpn_nior_n
+#undef HAVE_NATIVE_mpn_popcount
+#undef HAVE_NATIVE_mpn_preinv_divrem_1
+#undef HAVE_NATIVE_mpn_preinv_mod_1
+#undef HAVE_NATIVE_mpn_redc_1
+#undef HAVE_NATIVE_mpn_redc_2
+#undef HAVE_NATIVE_mpn_rsblsh1_n
+#undef HAVE_NATIVE_mpn_rsblsh2_n
+#undef HAVE_NATIVE_mpn_rsblsh_n
+#undef HAVE_NATIVE_mpn_rsblsh1_nc
+#undef HAVE_NATIVE_mpn_rsblsh2_nc
+#undef HAVE_NATIVE_mpn_rsblsh_nc
+#undef HAVE_NATIVE_mpn_rsh1add_n
+#undef HAVE_NATIVE_mpn_rsh1add_nc
+#undef HAVE_NATIVE_mpn_rsh1sub_n
+#undef HAVE_NATIVE_mpn_rsh1sub_nc
+#undef HAVE_NATIVE_mpn_rshift
+#undef HAVE_NATIVE_mpn_sqr_basecase
+#undef HAVE_NATIVE_mpn_sqr_diagonal
+#undef HAVE_NATIVE_mpn_sqr_diag_addlsh1
+#undef HAVE_NATIVE_mpn_sub_n
+#undef HAVE_NATIVE_mpn_sub_nc
+#undef HAVE_NATIVE_mpn_sublsh1_n
+#undef HAVE_NATIVE_mpn_sublsh2_n
+#undef HAVE_NATIVE_mpn_sublsh_n
+#undef HAVE_NATIVE_mpn_sublsh1_nc
+#undef HAVE_NATIVE_mpn_sublsh2_nc
+#undef HAVE_NATIVE_mpn_sublsh_nc
+#undef HAVE_NATIVE_mpn_sublsh1_n_ip1
+#undef HAVE_NATIVE_mpn_sublsh2_n_ip1
+#undef HAVE_NATIVE_mpn_sublsh_n_ip1
+#undef HAVE_NATIVE_mpn_sublsh1_nc_ip1
+#undef HAVE_NATIVE_mpn_sublsh2_nc_ip1
+#undef HAVE_NATIVE_mpn_sublsh_nc_ip1
+#undef HAVE_NATIVE_mpn_submul_1c
+#undef HAVE_NATIVE_mpn_tabselect
+#undef HAVE_NATIVE_mpn_udiv_qrnnd
+#undef HAVE_NATIVE_mpn_udiv_qrnnd_r
+#undef HAVE_NATIVE_mpn_umul_ppmm
+#undef HAVE_NATIVE_mpn_umul_ppmm_r
+#undef HAVE_NATIVE_mpn_xor_n
+#undef HAVE_NATIVE_mpn_xnor_n
+
+/* Define to 1 if you have the `nl_langinfo' function. */
+#undef HAVE_NL_LANGINFO
+
+/* Define to 1 if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define to 1 if you have the `obstack_vprintf' function. */
+#undef HAVE_OBSTACK_VPRINTF
+
+/* Define to 1 if you have the `popen' function. */
+#undef HAVE_POPEN
+
+/* Define to 1 if you have the `processor_info' function. */
+#undef HAVE_PROCESSOR_INFO
+
+/* Define to 1 if <sys/pstat.h> `struct pst_processor' exists and contains
+ `psp_iticksperclktick'. */
+#undef HAVE_PSP_ITICKSPERCLKTICK
+
+/* Define to 1 if you have the `pstat_getprocessor' function. */
+#undef HAVE_PSTAT_GETPROCESSOR
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#undef HAVE_PTRDIFF_T
+
+/* Define to 1 if the system has the type `quad_t'. */
+#undef HAVE_QUAD_T
+
+/* Define to 1 if you have the `raise' function. */
+#undef HAVE_RAISE
+
+/* Define to 1 if you have the `read_real_time' function. */
+#undef HAVE_READ_REAL_TIME
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the `sigaltstack' function. */
+#undef HAVE_SIGALTSTACK
+
+/* Define to 1 if you have the `sigstack' function. */
+#undef HAVE_SIGSTACK
+
+/* Tune directory speed_cyclecounter, undef=none, 1=32bits, 2=64bits) */
+#undef HAVE_SPEED_CYCLECOUNTER
+
+/* Define to 1 if you have the <sstream> header file. */
+#undef HAVE_SSTREAM
+
+/* Define to 1 if the system has the type `stack_t'. */
+#undef HAVE_STACK_T
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if the system has the type `std::locale'. */
+#undef HAVE_STD__LOCALE
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if cpp supports the ANSI # stringizing operator. */
+#undef HAVE_STRINGIZE
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strnlen' function. */
+#undef HAVE_STRNLEN
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if you have the `strtoul' function. */
+#undef HAVE_STRTOUL
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the `sysctl' function. */
+#undef HAVE_SYSCTL
+
+/* Define to 1 if you have the `sysctlbyname' function. */
+#undef HAVE_SYSCTLBYNAME
+
+/* Define to 1 if you have the `syssgi' function. */
+#undef HAVE_SYSSGI
+
+/* Define to 1 if you have the <sys/attributes.h> header file. */
+#undef HAVE_SYS_ATTRIBUTES_H
+
+/* Define to 1 if you have the <sys/iograph.h> header file. */
+#undef HAVE_SYS_IOGRAPH_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/processor.h> header file. */
+#undef HAVE_SYS_PROCESSOR_H
+
+/* Define to 1 if you have the <sys/pstat.h> header file. */
+#undef HAVE_SYS_PSTAT_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+#undef HAVE_SYS_SYSCTL_H
+
+/* Define to 1 if you have the <sys/sysinfo.h> header file. */
+#undef HAVE_SYS_SYSINFO_H
+
+/* Define to 1 if you have the <sys/syssgi.h> header file. */
+#undef HAVE_SYS_SYSSGI_H
+
+/* Define to 1 if you have the <sys/systemcfg.h> header file. */
+#undef HAVE_SYS_SYSTEMCFG_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the `times' function. */
+#undef HAVE_TIMES
+
+/* Define to 1 if the system has the type `uint_least32_t'. */
+#undef HAVE_UINT_LEAST32_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vsnprintf' function and it works properly. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 for Windos/64 */
+#undef HOST_DOS64
+
+/* Assembler local label prefix */
+#undef LSYM_PREFIX
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* The size of `mp_limb_t', as computed by sizeof. */
+#undef SIZEOF_MP_LIMB_T
+
+/* The size of `unsigned', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED
+
+/* The size of `unsigned long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* The size of `unsigned short', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_SHORT
+
+/* The size of `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
+/* Define to 1 if sscanf requires writable inputs */
+#undef SSCANF_WRITABLE_INPUT
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Maximum size the tune program can test for SQR_TOOM2_THRESHOLD */
+#undef TUNE_SQR_TOOM2_MAX
+
+/* Version number of package */
+#undef VERSION
+
+/* Defined to 1 as per --enable-assembly */
+#undef WANT_ASSEMBLY
+
+/* Define to 1 to enable ASSERT checking, per --enable-assert */
+#undef WANT_ASSERT
+
+/* Define to 1 to enable GMP_CPU_TYPE faking cpuid, per --enable-fake-cpuid */
+#undef WANT_FAKE_CPUID
+
+/* Define to 1 when building a fat binary. */
+#undef WANT_FAT_BINARY
+
+/* Define to 1 to enable FFTs for multiplication, per --enable-fft */
+#undef WANT_FFT
+
+/* Define to 1 to enable old mpn_mul_fft_full for multiplication, per
+ --enable-old-fft-full */
+#undef WANT_OLD_FFT_FULL
+
+/* Define to 1 if --enable-profiling=gprof */
+#undef WANT_PROFILING_GPROF
+
+/* Define to 1 if --enable-profiling=instrument */
+#undef WANT_PROFILING_INSTRUMENT
+
+/* Define to 1 if --enable-profiling=prof */
+#undef WANT_PROFILING_PROF
+
+/* Define one of these to 1 for the desired temporary memory allocation
+ method, per --enable-alloca. */
+#undef WANT_TMP_ALLOCA
+#undef WANT_TMP_REENTRANT
+#undef WANT_TMP_NOTREENTRANT
+#undef WANT_TMP_DEBUG
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to the equivalent of the C99 'restrict' keyword, or to
+ nothing if this is not supported. Do not define if restrict is
+ supported directly. */
+#undef restrict
+/* Work around a bug in Sun C++: it does not support _Restrict or
+ __restrict__, even though the corresponding Sun C compiler ends up with
+ "#define restrict _Restrict" or "#define restrict __restrict__" in the
+ previous line. Perhaps some future version of Sun C++ will work with
+ restrict; if so, hopefully it defines __RESTRICT like Sun C does. */
+#if defined __SUNPRO_CC && !defined __RESTRICT
+# define _Restrict
+# define __restrict__
+#endif
+
+/* Define to empty if the keyword `volatile' does not work. Warning: valid
+ code using `volatile' can become incorrect without. Disable with care. */
+#undef volatile
diff --git a/gmp/config.sub b/gmp/config.sub
new file mode 100755
index 0000000000..d734c43458
--- /dev/null
+++ b/gmp/config.sub
@@ -0,0 +1,165 @@
+#! /bin/sh
+#
+# GMP config.sub wrapper.
+
+
+# Copyright 2000-2003, 2006, 2009-2014 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: config.sub CPU-VENDOR-OS
+# config.sub ALIAS
+#
+# Validate and canonicalize the given configuration name, with special
+# handling for GMP extra CPU names.
+#
+# When the CPU isn't special the whole name is simply passed straight
+# through to configfsf.sub.
+#
+# When the CPU is a GMP extra, configfsf.sub is run on a similar CPU that it
+# will recognise. For example "athlon-pc-freebsd3.5" is validated using
+# "i386-pc-freebsd3.5".
+#
+# Any canonicalizations made by configfsf.sub are preserved. For example
+# given "athlon-linux", configfsf.sub is called with "i386-linux" and will
+# give back "i386-pc-linux-gnu". "athlon" is then reinstated, so we print
+# "athlon-pc-linux-gnu".
+
+
+# Expect to find configfsf.sub in the same directory as this config.sub
+configfsf_sub="`echo \"$0\" | sed 's/config.sub$/configfsf.sub/'`"
+if test "$configfsf_sub" = "$0"; then
+ echo "Cannot derive configfsf.sub from $0" 1>&2
+ exit 1
+fi
+if test -f "$configfsf_sub"; then
+ :
+else
+ echo "$configfsf_sub not found" 1>&2
+ exit 1
+fi
+
+# Always run configfsf.sub with $SHELL, like autoconf does for config.sub
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identify ourselves on --version, --help, etc
+case "$1" in
+"" | -*)
+ echo "(GNU MP wrapped config.sub)" 1>&2
+ $SHELL $configfsf_sub "$@"
+ exit
+ ;;
+esac
+
+given_full="$1"
+given_cpu=`echo "$given_full" | sed 's/-.*$//'`
+given_rest=`echo "$given_full" | sed 's/^[^-]*//'`
+
+
+# Aliases for GMP extras
+case "$given_cpu" in
+ # configfsf.sub turns p5 into i586, instead use our exact cpu type
+ p5 | p54) given_cpu=pentium ;;
+ p55) given_cpu=pentiummmx ;;
+
+ # configfsf.sub turns p6, pentiumii and pentiumiii into i686, instead use
+ # our exact cpu types
+ p6) given_cpu=pentiumpro ;;
+ pentiumii) given_cpu=pentium2 ;;
+ pentiumiii) given_cpu=pentium3 ;;
+esac
+given_full="$given_cpu$given_rest"
+
+
+# GMP extras and what to use for the config.sub test
+case "$given_cpu" in
+itanium | itanium2)
+ test_cpu=ia64 ;;
+pentium | pentiummmx | pentiumpro | pentium[234m] | k[567] | k6[23] | geode | athlon | viac3*)
+ test_cpu=i386 ;;
+athlon64 | atom | core2 | corei | coreinhm | coreiwsm | coreisbr | coreihwl | coreibwl | opteron | k[89] | k10 | bobcat | jaguar | bulldozer | piledriver | steamroller | excavator | nano)
+ test_cpu=x86_64 ;;
+power[2-9] | power2sc)
+ test_cpu=power ;;
+powerpc401 | powerpc403 | powerpc405 | \
+powerpc505 | \
+powerpc601 | powerpc602 | \
+powerpc603 | powerpc603e | \
+powerpc604 | powerpc604e | \
+powerpc620 | powerpc630 | powerpc970 | \
+powerpc740 | powerpc7400 | powerpc7450 | powerpc750 | \
+powerpc801 | powerpc821 | powerpc823 | powerpc860 | \
+powerpc64)
+ test_cpu=powerpc ;;
+sparcv8 | supersparc | microsparc | \
+ultrasparc | ultrasparc2 | ultrasparc2i | ultrasparc3 | ultrasparct[1234])
+ test_cpu=sparc ;;
+sh2)
+ test_cpu=sh ;;
+
+z900 | z990 | z9 | z10 | z196)
+ test_cpu=s390x;;
+z900esa | z990esa | z9esa | z10esa | z196esa)
+ test_cpu=s390;;
+
+armsa1 | armxscale | arm9tdmi | arm9te | \
+arm10* | arm11mpcore | armsa1 | arm1136 | arm1156 | arm1176 | \
+armcortexa5 | armcortexa7 | armcortexa8 | armcortexa9 | armcortexa15 | \
+armcortexr4 | armcortexr5 | armcortexm3)
+ test_cpu="arm";;
+
+*)
+ # Don't need or want to change the given name, just run configfsf.sub
+ $SHELL $configfsf_sub "$given_full"
+ if test $? = 0; then
+ exit 0
+ else
+ echo "(GNU MP wrapped config.sub, testing \"$given_full\")"
+ exit 1
+ fi
+esac
+
+
+test_full="$test_cpu$given_rest"
+canonical_full=`$SHELL $configfsf_sub "$test_full"`
+if test $? = 0; then
+ :
+else
+ echo "(GNU MP wrapped config.sub, testing \"$given_full\" as \"$test_full\")"
+ exit 1
+fi
+
+canonical_rest=`echo "$canonical_full" | sed 's/^[^-]*//'`
+echo "$given_cpu$canonical_rest"
+exit 0
+
+
+
+# Local variables:
+# fill-column: 76
+# End:
diff --git a/gmp/configfsf.guess b/gmp/configfsf.guess
new file mode 100755
index 0000000000..9afd676206
--- /dev/null
+++ b/gmp/configfsf.guess
@@ -0,0 +1,1568 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2013 Free Software Foundation, Inc.
+
+timestamp='2013-11-29'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2013 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ or1k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/gmp/configfsf.sub b/gmp/configfsf.sub
new file mode 100644
index 0000000000..61cb4bc22d
--- /dev/null
+++ b/gmp/configfsf.sub
@@ -0,0 +1,1793 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2013 Free Software Foundation, Inc.
+
+timestamp='2013-10-01'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2013 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 \
+ | or1k | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or1k-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/gmp/configure b/gmp/configure
new file mode 100755
index 0000000000..60c6bd55eb
--- /dev/null
+++ b/gmp/configure
@@ -0,0 +1,29770 @@
+#! /bin/sh
+# From configure.ac Revision.
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for GNU MP 6.0.0.
+#
+# Report bugs to <gmp-bugs@gmplib.org, see https://gmplib.org/manual/Reporting-Bugs.html>.
+#
+#
+#
+# Copyright 1996-2014 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+#
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: gmp-bugs@gmplib.org, see
+$0: https://gmplib.org/manual/Reporting-Bugs.html about
+$0: your system, including any error possibly output before
+$0: this message. Then install a modern shell, or manually
+$0: run the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='GNU MP'
+PACKAGE_TARNAME='gmp'
+PACKAGE_VERSION='6.0.0'
+PACKAGE_STRING='GNU MP 6.0.0'
+PACKAGE_BUGREPORT='gmp-bugs@gmplib.org, see https://gmplib.org/manual/Reporting-Bugs.html'
+PACKAGE_URL='http://www.gnu.org/software/gmp/'
+
+ac_unique_file="gmp-impl.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+LEXLIB
+LEX_OUTPUT_ROOT
+LEX
+YFLAGS
+YACC
+LIBREADLINE
+WITH_READLINE_01
+LIBCURSES
+HAVE_STACK_T_01
+HAVE_SYS_RESOURCE_H_01
+HAVE_SIGSTACK_01
+HAVE_SIGALTSTACK_01
+HAVE_SIGACTION_01
+HAVE_GETTIMEOFDAY_01
+HAVE_GETRUSAGE_01
+HAVE_CPUTIME_01
+HAVE_CLOCK_01
+TUNE_SQR_OBJ
+gmp_srclinks
+mpn_objs_in_libgmp
+mpn_objects
+GMP_LIMB_BITS
+M4
+TUNE_LIBS
+TAL_OBJECT
+LIBM
+ENABLE_STATIC_FALSE
+ENABLE_STATIC_TRUE
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+LN_S
+LD
+FGREP
+SED
+LIBTOOL
+LIBGMP_DLL
+OBJDUMP
+DLLTOOL
+AS
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+AR
+ASMFLAGS
+EGREP
+GREP
+CXXCPP
+WANT_CXX_FALSE
+WANT_CXX_TRUE
+ac_ct_CXX
+CXXFLAGS
+CXX
+CCAS
+LIBM_FOR_BUILD
+U_FOR_BUILD
+EXEEXT_FOR_BUILD
+CPP_FOR_BUILD
+CC_FOR_BUILD
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+DEFN_LONG_LONG_LIMB
+CALLING_CONVENTIONS_OBJS
+SPEED_CYCLECOUNTER_OBJ
+LIBGMPXX_LDFLAGS
+LIBGMP_LDFLAGS
+GMP_LDFLAGS
+HAVE_HOST_CPU_FAMILY_powerpc
+HAVE_HOST_CPU_FAMILY_power
+ABI
+GMP_NAIL_BITS
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+enable_assert
+enable_alloca
+enable_cxx
+enable_assembly
+enable_fft
+enable_old_fft_full
+enable_nails
+enable_profiling
+with_readline
+enable_fat
+enable_minithres
+enable_fake_cpuid
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+ABI
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CC_FOR_BUILD
+CPP_FOR_BUILD
+CXX
+CXXFLAGS
+CCC
+CXXCPP
+M4
+YACC
+YFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures GNU MP 6.0.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/gmp]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of GNU MP 6.0.0:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --enable-assert enable ASSERT checking [[default=no]]
+ --enable-alloca how to get temp memory [[default=reentrant]]
+ --enable-cxx enable C++ support [[default=no]]
+ --enable-assembly enable the use of assembly loops [[default=yes]]
+ --enable-fft enable FFTs for multiplication [[default=yes]]
+ --enable-old-fft-full enable old mpn_mul_fft_full for multiplication
+ [[default=no]]
+ --enable-nails use nails on limbs [[default=no]]
+ --enable-profiling build with profiler support [[default=no]]
+ --enable-fat build a fat binary on systems that support it
+ [[default=no]]
+ --enable-minithres choose minimal thresholds for testing [[default=no]]
+ --enable-fake-cpuid enable GMP_CPU_TYPE faking cpuid [[default=no]]
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-readline readline support in calc demo program
+ [[default=detect]]
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot=DIR Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).
+
+Some influential environment variables:
+ ABI desired ABI (for processors supporting more than one ABI)
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ CC_FOR_BUILD
+ build system C compiler
+ CPP_FOR_BUILD
+ build system C preprocessor
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ CXXCPP C++ preprocessor
+ M4 m4 macro processor
+ YACC The `Yet Another Compiler Compiler' implementation to use.
+ Defaults to the first program found out of: `bison -y', `byacc',
+ `yacc'.
+ YFLAGS The list of arguments that will be passed by default to $YACC.
+ This script will default YFLAGS to the empty string to avoid a
+ default value of `-d' given by some make applications.
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <gmp-bugs@gmplib.org, see https://gmplib.org/manual/Reporting-Bugs.html>.
+GNU MP home page: <http://www.gnu.org/software/gmp/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+GNU MP configure 6.0.0
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+
+
+
+Copyright 1996-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ssssssssssssssssssssssssssssssssss ##
+## Report this to gmp-bugs@gmplib.org ##
+## ssssssssssssssssssssssssssssssssss ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ as_decl_name=`echo $2|sed 's/ *(.*//'`
+ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+ (void) $as_decl_use;
+#else
+ (void) $as_decl_name;
+#endif
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_decl
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+
+# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_cxx_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ssssssssssssssssssssssssssssssssss ##
+## Report this to gmp-bugs@gmplib.org ##
+## ssssssssssssssssssssssssssssssssss ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_mongrel
+
+# ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES
+# ---------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_cxx_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_type
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by GNU MP $as_me 6.0.0, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+# If --target is not used then $target_alias is empty, but if say
+# "./configure athlon-pc-freebsd3.5" is used, then all three of
+# $build_alias, $host_alias and $target_alias are set to
+# "athlon-pc-freebsd3.5".
+#
+if test -n "$target_alias" && test "$target_alias" != "$host_alias"; then
+ as_fn_error $? "--target is not appropriate for GMP
+Use --build=CPU-VENDOR-OS if you need to specify your CPU and/or system
+explicitly. Use --host if cross-compiling (see \"Installing GMP\" in the
+manual for more on this)." "$LINENO" 5
+fi
+
+gmp_configm4="config.m4"
+gmp_tmpconfigm4=cnfm4.tmp
+gmp_tmpconfigm4i=cnfm4i.tmp
+gmp_tmpconfigm4p=cnfm4p.tmp
+rm -f $gmp_tmpconfigm4 $gmp_tmpconfigm4i $gmp_tmpconfigm4p
+
+# CONFIG_TOP_SRCDIR is a path from the mpn builddir to the top srcdir.
+# The pattern here tests for an absolute path the same way as
+# _AC_OUTPUT_FILES in autoconf acgeneral.m4.
+case $srcdir in
+[\\/]* | ?:[\\/]* ) tmp="$srcdir" ;;
+*) tmp="../$srcdir" ;;
+esac
+echo "define(<CONFIG_TOP_SRCDIR>,<\`$tmp'>)" >>$gmp_tmpconfigm4
+
+# All CPUs use asm-defs.m4
+echo "include(CONFIG_TOP_SRCDIR\`/mpn/asm-defs.m4')" >>$gmp_tmpconfigm4i
+
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+am__api_version='1.11'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='gmp'
+ VERSION='6.0.0'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+ac_config_headers="$ac_config_headers config.h:config.in"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+# Check whether --enable-assert was given.
+if test "${enable_assert+set}" = set; then :
+ enableval=$enable_assert; case $enableval in
+yes|no) ;;
+*) as_fn_error $? "bad value $enableval for --enable-assert, need yes or no" "$LINENO" 5 ;;
+esac
+else
+ enable_assert=no
+fi
+
+
+if test "$enable_assert" = "yes"; then
+
+$as_echo "#define WANT_ASSERT 1" >>confdefs.h
+
+ want_assert_01=1
+else
+ want_assert_01=0
+fi
+
+echo "define(<WANT_ASSERT>,$want_assert_01)" >> $gmp_tmpconfigm4
+
+
+
+# Check whether --enable-alloca was given.
+if test "${enable_alloca+set}" = set; then :
+ enableval=$enable_alloca; case $enableval in
+alloca|malloc-reentrant|malloc-notreentrant) ;;
+yes|no|reentrant|notreentrant) ;;
+debug) ;;
+*)
+ as_fn_error $? "bad value $enableval for --enable-alloca, need one of:
+yes no reentrant notreentrant alloca malloc-reentrant malloc-notreentrant debug" "$LINENO" 5 ;;
+esac
+else
+ enable_alloca=reentrant
+fi
+
+
+
+# IMPROVE ME: The default for C++ is disabled. The tests currently
+# performed below for a working C++ compiler are not particularly strong,
+# and in general can't be expected to get the right setup on their own. The
+# most significant problem is getting the ABI the same. Defaulting CXXFLAGS
+# to CFLAGS takes only a small step towards this. It's also probably worth
+# worrying whether the C and C++ runtimes from say gcc and a vendor C++ can
+# work together. Some rather broken C++ installations were encountered
+# during testing, and though such things clearly aren't GMP's problem, if
+# --enable-cxx=detect were to be the default then some careful checks of
+# which, if any, C++ compiler on the system is up to scratch would be
+# wanted.
+#
+# Check whether --enable-cxx was given.
+if test "${enable_cxx+set}" = set; then :
+ enableval=$enable_cxx; case $enableval in
+yes|no|detect) ;;
+*) as_fn_error $? "bad value $enableval for --enable-cxx, need yes/no/detect" "$LINENO" 5 ;;
+esac
+else
+ enable_cxx=no
+fi
+
+
+
+# Check whether --enable-assembly was given.
+if test "${enable_assembly+set}" = set; then :
+ enableval=$enable_assembly; case $enableval in
+yes|no) ;;
+*) as_fn_error $? "bad value $enableval for --enable-assembly, need yes or no" "$LINENO" 5 ;;
+esac
+else
+ enable_assembly=yes
+fi
+
+
+if test "$enable_assembly" = "yes"; then
+
+$as_echo "#define WANT_ASSEMBLY 1" >>confdefs.h
+
+fi
+
+
+# Check whether --enable-fft was given.
+if test "${enable_fft+set}" = set; then :
+ enableval=$enable_fft; case $enableval in
+yes|no) ;;
+*) as_fn_error $? "bad value $enableval for --enable-fft, need yes or no" "$LINENO" 5 ;;
+esac
+else
+ enable_fft=yes
+fi
+
+
+if test "$enable_fft" = "yes"; then
+
+$as_echo "#define WANT_FFT 1" >>confdefs.h
+
+fi
+
+
+# Check whether --enable-old-fft-full was given.
+if test "${enable_old_fft_full+set}" = set; then :
+ enableval=$enable_old_fft_full; case $enableval in
+yes|no) ;;
+*) as_fn_error $? "bad value $enableval for --enable-old-fft-full, need yes or no" "$LINENO" 5 ;;
+esac
+else
+ enable_old_fft_full=no
+fi
+
+
+if test "$enable_old_fft_full" = "yes"; then
+
+$as_echo "#define WANT_OLD_FFT_FULL 1" >>confdefs.h
+
+fi
+
+
+# Check whether --enable-nails was given.
+if test "${enable_nails+set}" = set; then :
+ enableval=$enable_nails; case $enableval in
+yes|no|[02468]|[0-9][02468]) ;;
+*[13579])
+ as_fn_error $? "bad value $enableval for --enable-nails, only even nail sizes supported" "$LINENO" 5 ;;
+*)
+ as_fn_error $? "bad value $enableval for --enable-nails, need yes/no/number" "$LINENO" 5 ;;
+esac
+else
+ enable_nails=no
+fi
+
+
+case $enable_nails in
+yes) GMP_NAIL_BITS=2 ;;
+no) GMP_NAIL_BITS=0 ;;
+*) GMP_NAIL_BITS=$enable_nails ;;
+esac
+
+
+
+# Check whether --enable-profiling was given.
+if test "${enable_profiling+set}" = set; then :
+ enableval=$enable_profiling; case $enableval in
+no|prof|gprof|instrument) ;;
+*) as_fn_error $? "bad value $enableval for --enable-profiling, need no/prof/gprof/instrument" "$LINENO" 5 ;;
+esac
+else
+ enable_profiling=no
+fi
+
+
+case $enable_profiling in
+ prof)
+
+$as_echo "#define WANT_PROFILING_PROF 1" >>confdefs.h
+
+ ;;
+ gprof)
+
+$as_echo "#define WANT_PROFILING_GPROF 1" >>confdefs.h
+
+ ;;
+ instrument)
+
+$as_echo "#define WANT_PROFILING_INSTRUMENT 1" >>confdefs.h
+
+ ;;
+esac
+
+
+echo "define(<WANT_PROFILING>,<\`$enable_profiling'>)" >> $gmp_tmpconfigm4
+
+
+# -fomit-frame-pointer is incompatible with -pg on some chips
+if test "$enable_profiling" = gprof; then
+ fomit_frame_pointer=
+else
+ fomit_frame_pointer="-fomit-frame-pointer"
+fi
+
+
+
+# Check whether --with-readline was given.
+if test "${with_readline+set}" = set; then :
+ withval=$with_readline; case $withval in
+yes|no|detect) ;;
+*) as_fn_error $? "bad value $withval for --with-readline, need yes/no/detect" "$LINENO" 5 ;;
+esac
+else
+ with_readline=detect
+fi
+
+
+
+# Check whether --enable-fat was given.
+if test "${enable_fat+set}" = set; then :
+ enableval=$enable_fat; case $enableval in
+yes|no) ;;
+*) as_fn_error $? "bad value $enableval for --enable-fat, need yes or no" "$LINENO" 5 ;;
+esac
+else
+ enable_fat=no
+fi
+
+
+
+# Check whether --enable-minithres was given.
+if test "${enable_minithres+set}" = set; then :
+ enableval=$enable_minithres; case $enableval in
+yes|no) ;;
+*) as_fn_error $? "bad value $enableval for --enable-minithres, need yes or no" "$LINENO" 5 ;;
+esac
+else
+ enable_minithres=no
+fi
+
+
+
+# Check whether --enable-fake-cpuid was given.
+if test "${enable_fake_cpuid+set}" = set; then :
+ enableval=$enable_fake_cpuid; case $enableval in
+yes|no) ;;
+*) as_fn_error $? "bad value $enableval for --enable-fake-cpuid, need yes or no" "$LINENO" 5 ;;
+esac
+else
+ enable_fake_cpuid=no
+fi
+
+
+if test "$enable_fake_cpuid" = "yes"; then
+
+$as_echo "#define WANT_FAKE_CPUID 1" >>confdefs.h
+
+fi
+
+
+if test $enable_fat = yes && test $enable_assembly = no ; then
+ as_fn_error $? "when doing a fat build, disabling assembly will not work" "$LINENO" 5
+fi
+
+if test $enable_fake_cpuid = yes && test $enable_fat = no ; then
+ as_fn_error $? "--enable-fake-cpuid requires --enable-fat" "$LINENO" 5
+fi
+
+
+tmp_host=`echo $host_cpu | sed 's/\./_/'`
+cat >>confdefs.h <<_ACEOF
+#define HAVE_HOST_CPU_$tmp_host 1
+_ACEOF
+
+
+echo "define_not_for_expansion(\`HAVE_HOST_CPU_$tmp_host')" >> $gmp_tmpconfigm4p
+
+
+
+
+
+
+# Table of compilers, options, and mpn paths. This code has various related
+# purposes
+#
+# - better default CC/CFLAGS selections than autoconf otherwise gives
+# - default CC/CFLAGS selections for extra CPU types specific to GMP
+# - a few tests for known bad compilers
+# - choice of ABIs on suitable systems
+# - selection of corresponding mpn search path
+#
+# After GMP specific searches and tests, the standard autoconf AC_PROG_CC is
+# called. User selections of CC etc are respected.
+#
+# Care is taken not to use macros like AC_TRY_COMPILE during the GMP
+# pre-testing, since they of course depend on AC_PROG_CC, and also some of
+# them cache their results, which is not wanted.
+#
+# The ABI selection mechanism is unique to GMP. All that reaches autoconf
+# is a different selection of CC/CFLAGS according to the best ABI the system
+# supports, and/or what the user selects. Naturally the mpn assembler code
+# selected is very dependent on the ABI.
+#
+# The closest the standard tools come to a notion of ABI is something like
+# "sparc64" which encodes a CPU and an ABI together. This doesn't seem to
+# scale well for GMP, where exact CPU types like "ultrasparc2" are wanted,
+# separate from the ABI used on them.
+#
+#
+# The variables set here are
+#
+# cclist the compiler choices
+# xx_cflags flags for compiler xx
+# xx_cflags_maybe flags for compiler xx, if they work
+# xx_cppflags cpp flags for compiler xx
+# xx_cflags_optlist list of sets of optional flags
+# xx_cflags_yyy set yyy of optional flags for compiler xx
+# xx_ldflags -Wc,-foo flags for libtool linking with compiler xx
+# ar_flags extra flags for $AR
+# nm_flags extra flags for $NM
+# limb limb size, can be "longlong"
+# path mpn search path
+# extra_functions extra mpn functions
+# fat_path fat binary mpn search path [if fat binary desired]
+# fat_functions fat functions
+# fat_thresholds fat thresholds
+#
+# Suppose xx_cflags_optlist="arch", then flags from $xx_cflags_arch are
+# tried, and the first flag that works will be used. An optlist like "arch
+# cpu optimize" can be used to get multiple independent sets of flags tried.
+# The first that works from each will be used. If no flag in a set works
+# then nothing from that set is added.
+#
+# For multiple ABIs, the scheme extends as follows.
+#
+# abilist set of ABI choices
+# cclist_aa compiler choices in ABI aa
+# xx_aa_cflags flags for xx in ABI aa
+# xx_aa_cflags_maybe flags for xx in ABI aa, if they work
+# xx_aa_cppflags cpp flags for xx in ABI aa
+# xx_aa_cflags_optlist list of sets of optional flags in ABI aa
+# xx_aa_cflags_yyy set yyy of optional flags for compiler xx in ABI aa
+# xx_aa_ldflags -Wc,-foo flags for libtool linking
+# ar_aa_flags extra flags for $AR in ABI aa
+# nm_aa_flags extra flags for $NM in ABI aa
+# limb_aa limb size in ABI aa, can be "longlong"
+# path_aa mpn search path in ABI aa
+# extra_functions_aa extra mpn functions in ABI aa
+#
+# As a convenience, the unadorned xx_cflags (etc) are used for the last ABI
+# in ablist, if an xx_aa_cflags for that ABI isn't given. For example if
+# abilist="64 32" then $cc_64_cflags will be used for the 64-bit ABI, but
+# for the 32-bit either $cc_32_cflags or $cc_cflags is used, whichever is
+# defined. This makes it easy to add some 64-bit compilers and flags to an
+# unadorned 32-bit set.
+#
+# limb=longlong (or limb_aa=longlong) applies to all compilers within that
+# ABI. It won't work to have some needing long long and some not, since a
+# single instantiated gmp.h will be used by both.
+#
+# SPEED_CYCLECOUNTER, cyclecounter_size and CALLING_CONVENTIONS_OBJS are
+# also set here, with an ABI suffix.
+#
+#
+#
+# A table-driven approach like this to mapping cpu type to good compiler
+# options is a bit of a maintenance burden, but there's not much uniformity
+# between options specifications on different compilers. Some sort of
+# separately updatable tool might be cute.
+#
+# The use of lots of variables like this, direct and indirect, tends to
+# obscure when and how various things are done, but unfortunately it's
+# pretty much the only way. If shell subroutines were portable then actual
+# code like "if this .. do that" could be written, but attempting the same
+# with full copies of GMP_PROG_CC_WORKS etc expanded at every point would
+# hugely bloat the output.
+
+
+
+
+# abilist needs to be non-empty, "standard" is just a generic name here
+abilist="standard"
+
+# FIXME: We'd like to prefer an ANSI compiler, perhaps by preferring
+# c89 over cc here. But note that on HP-UX c89 provides a castrated
+# environment, and would want to be excluded somehow. Maybe
+# AC_PROG_CC_STDC already does enough to stick cc into ANSI mode and
+# we don't need to worry.
+#
+cclist="gcc cc"
+
+gcc_cflags="-O2 -pedantic"
+gcc_64_cflags="-O2 -pedantic"
+cc_cflags="-O"
+cc_64_cflags="-O"
+
+SPEED_CYCLECOUNTER_OBJ=
+cyclecounter_size=2
+
+HAVE_HOST_CPU_FAMILY_power=0
+
+HAVE_HOST_CPU_FAMILY_powerpc=0
+
+
+case $host in
+
+ alpha*-*-*)
+ $as_echo "#define HAVE_HOST_CPU_FAMILY_alpha 1" >>confdefs.h
+
+ case $host_cpu in
+ alphaev5* | alphapca5*)
+ path="alpha/ev5 alpha" ;;
+ alphaev67 | alphaev68 | alphaev7*)
+ path="alpha/ev67 alpha/ev6 alpha" ;;
+ alphaev6)
+ path="alpha/ev6 alpha" ;;
+ *)
+ path="alpha" ;;
+ esac
+ if test "$enable_assembly" = "yes" ; then
+ extra_functions="cntlz"
+ fi
+ gcc_cflags_optlist="asm cpu oldas" # need asm ahead of cpu, see below
+ gcc_cflags_maybe="-mieee"
+ gcc_cflags_oldas="-Wa,-oldas" # see GMP_GCC_WA_OLDAS.
+
+ # gcc 2.7.2.3 doesn't know any -mcpu= for alpha, apparently.
+ # gcc 2.95 knows -mcpu= ev4, ev5, ev56, pca56, ev6.
+ # gcc 3.0 adds nothing.
+ # gcc 3.1 adds ev45, ev67 (but ev45 is the same as ev4).
+ # gcc 3.2 adds nothing.
+ #
+ # gcc version "2.9-gnupro-99r1" under "-O2 -mcpu=ev6" strikes internal
+ # compiler errors too easily and is rejected by GMP_PROG_CC_WORKS. Each
+ # -mcpu=ev6 below has a fallback to -mcpu=ev56 for this reason.
+ #
+ case $host_cpu in
+ alpha) gcc_cflags_cpu="-mcpu=ev4" ;;
+ alphaev5) gcc_cflags_cpu="-mcpu=ev5" ;;
+ alphaev56) gcc_cflags_cpu="-mcpu=ev56" ;;
+ alphapca56 | alphapca57)
+ gcc_cflags_cpu="-mcpu=pca56" ;;
+ alphaev6) gcc_cflags_cpu="-mcpu=ev6 -mcpu=ev56" ;;
+ alphaev67 | alphaev68 | alphaev7*)
+ gcc_cflags_cpu="-mcpu=ev67 -mcpu=ev6 -mcpu=ev56" ;;
+ esac
+
+ # gcc version "2.9-gnupro-99r1" on alphaev68-dec-osf5.1 has been seen
+ # accepting -mcpu=ev6, but not putting the assembler in the right mode
+ # for what it produces. We need to do this for it, and need to do it
+ # before testing the -mcpu options.
+ #
+ # On old versions of gcc, which don't know -mcpu=, we believe an
+ # explicit -Wa,-mev5 etc will be necessary to put the assembler in
+ # the right mode for our .asm files and longlong.h asm blocks.
+ #
+ # On newer versions of gcc, when -mcpu= is known, we must give a -Wa
+ # which is at least as high as the code gcc will generate. gcc
+ # establishes what it needs with a ".arch" directive, our command line
+ # option seems to override that.
+ #
+ # gas prior to 2.14 doesn't accept -mev67, but -mev6 seems enough for
+ # ctlz and cttz (in 2.10.0 at least).
+ #
+ # OSF `as' accepts ev68 but stupidly treats it as ev4. -arch only seems
+ # to affect insns like ldbu which are expanded as macros when necessary.
+ # Insns like ctlz which were never available as macros are always
+ # accepted and always generate their plain code.
+ #
+ case $host_cpu in
+ alpha) gcc_cflags_asm="-Wa,-arch,ev4 -Wa,-mev4" ;;
+ alphaev5) gcc_cflags_asm="-Wa,-arch,ev5 -Wa,-mev5" ;;
+ alphaev56) gcc_cflags_asm="-Wa,-arch,ev56 -Wa,-mev56" ;;
+ alphapca56 | alphapca57)
+ gcc_cflags_asm="-Wa,-arch,pca56 -Wa,-mpca56" ;;
+ alphaev6) gcc_cflags_asm="-Wa,-arch,ev6 -Wa,-mev6" ;;
+ alphaev67 | alphaev68 | alphaev7*)
+ gcc_cflags_asm="-Wa,-arch,ev67 -Wa,-mev67 -Wa,-arch,ev6 -Wa,-mev6" ;;
+ esac
+
+ # It might be better to ask "cc" whether it's Cray C or DEC C,
+ # instead of relying on the OS part of $host. But it's hard to
+ # imagine either of those compilers anywhere except their native
+ # systems.
+ #
+
+echo "include_mpn(\`alpha/alpha-defs.m4')" >> $gmp_tmpconfigm4i
+
+ case $host in
+ *-cray-unicos*)
+ cc_cflags="-O" # no -g, it silently disables all optimizations
+
+echo "include_mpn(\`alpha/unicos.m4')" >> $gmp_tmpconfigm4i
+
+ # Don't perform any assembly syntax tests on this beast.
+ gmp_asm_syntax_testing=no
+ ;;
+ *-*-osf*)
+
+echo "include_mpn(\`alpha/default.m4')" >> $gmp_tmpconfigm4i
+
+ cc_cflags=""
+ cc_cflags_optlist="opt cpu"
+
+ # not sure if -fast works on old versions, so make it optional
+ cc_cflags_opt="-fast -O2"
+
+ # DEC C V5.9-005 knows ev4, ev5, ev56, pca56, ev6.
+ # Compaq C V6.3-029 adds ev67.
+ #
+ case $host_cpu in
+ alpha) cc_cflags_cpu="-arch~ev4~-tune~ev4" ;;
+ alphaev5) cc_cflags_cpu="-arch~ev5~-tune~ev5" ;;
+ alphaev56) cc_cflags_cpu="-arch~ev56~-tune~ev56" ;;
+ alphapca56 | alphapca57)
+ cc_cflags_cpu="-arch~pca56~-tune~pca56" ;;
+ alphaev6) cc_cflags_cpu="-arch~ev6~-tune~ev6" ;;
+ alphaev67 | alphaev68 | alphaev7*)
+ cc_cflags_cpu="-arch~ev67~-tune~ev67 -arch~ev6~-tune~ev6" ;;
+ esac
+ ;;
+ *)
+
+echo "include_mpn(\`alpha/default.m4')" >> $gmp_tmpconfigm4i
+
+ ;;
+ esac
+
+ case $host in
+ *-*-unicos*)
+ # tune/alpha.asm assumes int==4bytes but unicos uses int==8bytes
+ ;;
+ *)
+ SPEED_CYCLECOUNTER_OBJ=alpha.lo
+ cyclecounter_size=1 ;;
+ esac
+ ;;
+
+
+ # Cray vector machines.
+ # This must come after alpha* so that we can recognize present and future
+ # vector processors with a wildcard.
+ *-cray-unicos*)
+ gmp_asm_syntax_testing=no
+ cclist="cc"
+ # We used to have -hscalar0 here as a workaround for miscompilation of
+ # mpz/import.c, but let's hope Cray fixes their bugs instead, since
+ # -hscalar0 causes disastrously poor code to be generated.
+ cc_cflags="-O3 -hnofastmd -htask0 -Wa,-B"
+ path="cray"
+ ;;
+
+
+ arm64*-*-* | aarch64*-*-*)
+ path="arm64"
+ ;;
+
+
+ arm*-*-*)
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ gcc_cflags_optlist="arch neon tune"
+ gcc_cflags_maybe="-marm"
+ gcc_testlist="gcc-arm-umodsi"
+
+echo "include_mpn(\`arm/arm-defs.m4')" >> $gmp_tmpconfigm4i
+
+ CALLING_CONVENTIONS_OBJS='arm32call.lo arm32check.lo'
+
+ # FIXME: We make mandatory compiler options optional here. We should
+ # either enforce them, or organise to strip paths as the corresponding
+ # options fail.
+ case $host_cpu in
+ armsa1 | arm9tdmi | armv4*)
+ path="arm"
+ gcc_cflags_arch="-march=armv4"
+ ;;
+ armxscale | arm9te | arm10 | armv5*)
+ path="arm/v5 arm"
+ gcc_cflags_arch="-march=armv5"
+ ;;
+ arm11mpcore | arm1136 | arm1176 | armv6*)
+ path="arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv6"
+ ;;
+ arm1156)
+ path="arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv6t2"
+ ;;
+ armcortexa5 | armv7a*)
+ path="arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv7-a"
+ ;;
+ armcortexa8)
+ path="arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_tune="-mtune=cortex-a8"
+ ;;
+ armcortexa8neon)
+ path="arm/v6t2 arm/v6 arm/v5 arm/neon arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_neon="-mfpu=neon"
+ gcc_cflags_tune="-mtune=cortex-a8"
+ ;;
+ armcortexa9)
+ path="arm/v7a/cora9 arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_tune="-mtune=cortex-a9"
+ ;;
+ armcortexa9neon)
+ path="arm/v7a/cora9 arm/v6t2 arm/v6 arm/v5 arm/neon arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_neon="-mfpu=neon"
+ gcc_cflags_tune="-mtune=cortex-a9"
+ ;;
+ armcortexa15)
+ path="arm/v7a/cora15 arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_tune="-mtune=cortex-a15 -mtune=cortex-a9"
+ ;;
+ armcortexa15neon)
+ path="arm/v7a/cora15/neon arm/v7a/cora15 arm/v6t2 arm/v6 arm/v5 arm/neon arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_neon="-mfpu=neon"
+ gcc_cflags_tune="-mtune=cortex-a15 -mtune=cortex-a9"
+ ;;
+ *)
+ path="arm"
+ ;;
+ esac
+ ;;
+
+
+ # Fujitsu
+ f30[01]-fujitsu-sysv*)
+ cclist="gcc vcc"
+ # FIXME: flags for vcc?
+ vcc_cflags="-g"
+ path="fujitsu"
+ ;;
+
+
+ hppa*-*-*)
+ # HP cc (the one sold separately) is K&R by default, but AM_C_PROTOTYPES
+ # will add "-Ae", or "-Aa -D_HPUX_SOURCE", to put it into ansi mode, if
+ # possible.
+ #
+ # gcc for hppa 2.0 can be built either for 2.0n (32-bit) or 2.0w
+ # (64-bit), but not both, so there's no option to choose the desired
+ # mode, we must instead detect which of the two it is. This is done by
+ # checking sizeof(long), either 4 or 8 bytes respectively. Do this in
+ # ABI=1.0 too, in case someone tries to build that with a 2.0w gcc.
+ #
+ gcc_cflags_optlist="arch"
+ gcc_testlist="sizeof-long-4"
+ SPEED_CYCLECOUNTER_OBJ=hppa.lo
+ cyclecounter_size=1
+
+ # FIXME: For hppa2.0*, path should be "pa32/hppa2_0 pa32/hppa1_1 pa32".
+ # (Can't remember why this isn't done already, have to check what .asm
+ # files are available in each and how they run on a typical 2.0 cpu.)
+ #
+ case $host_cpu in
+ hppa1.0*) path="pa32" ;;
+ hppa7000*) path="pa32/hppa1_1 pa32" ;;
+ hppa2.0* | hppa64)
+ path="pa32/hppa2_0 pa32/hppa1_1/pa7100 pa32/hppa1_1 pa32" ;;
+ *) # default to 7100
+ path="pa32/hppa1_1/pa7100 pa32/hppa1_1 pa32" ;;
+ esac
+
+ # gcc 2.7.2.3 knows -mpa-risc-1-0 and -mpa-risc-1-1
+ # gcc 2.95 adds -mpa-risc-2-0, plus synonyms -march=1.0, 1.1 and 2.0
+ #
+ # We don't use -mpa-risc-2-0 in ABI=1.0 because 64-bit registers may not
+ # be saved by the kernel on an old system. Actually gcc (as of 3.2)
+ # only adds a few float instructions with -mpa-risc-2-0, so it would
+ # probably be safe, but let's not take the chance. In any case, a
+ # configuration like --host=hppa2.0 ABI=1.0 is far from optimal.
+ #
+ case $host_cpu in
+ hppa1.0*) gcc_cflags_arch="-mpa-risc-1-0" ;;
+ *) # default to 7100
+ gcc_cflags_arch="-mpa-risc-1-1" ;;
+ esac
+
+ case $host_cpu in
+ hppa1.0*) cc_cflags="+O2" ;;
+ *) # default to 7100
+ cc_cflags="+DA1.1 +O2" ;;
+ esac
+
+ case $host in
+ hppa2.0*-*-* | hppa64-*-*)
+ cclist_20n="gcc cc"
+ abilist="2.0n 1.0"
+ path_20n="pa64"
+ limb_20n=longlong
+ any_20n_testlist="sizeof-long-4"
+ SPEED_CYCLECOUNTER_OBJ_20n=hppa2.lo
+ cyclecounter_size_20n=2
+
+ # -mpa-risc-2-0 is only an optional flag, in case an old gcc is
+ # used. Assembler support for 2.0 is essential though, for our asm
+ # files.
+ gcc_20n_cflags="$gcc_cflags"
+ gcc_20n_cflags_optlist="arch"
+ gcc_20n_cflags_arch="-mpa-risc-2-0 -mpa-risc-1-1"
+ gcc_20n_testlist="sizeof-long-4 hppa-level-2.0"
+
+ cc_20n_cflags="+DA2.0 +e +O2 -Wl,+vnocompatwarnings"
+ cc_20n_testlist="hpc-hppa-2-0"
+
+ # ABI=2.0w is available for hppa2.0w and hppa2.0, but not for
+ # hppa2.0n, on the assumption that that the latter indicates a
+ # desire for ABI=2.0n.
+ case $host in
+ hppa2.0n-*-*) ;;
+ *)
+ # HPUX 10 and earlier cannot run 2.0w. Not sure about other
+ # systems (GNU/Linux for instance), but lets assume they're ok.
+ case $host in
+ *-*-hpux[1-9] | *-*-hpux[1-9].* | *-*-hpux10 | *-*-hpux10.*) ;;
+ *-*-linux*) abilist="1.0" ;; # due to linux permanent kernel bug
+ *) abilist="2.0w $abilist" ;;
+ esac
+
+ cclist_20w="gcc cc"
+ gcc_20w_cflags="$gcc_cflags -mpa-risc-2-0"
+ cc_20w_cflags="+DD64 +O2"
+ cc_20w_testlist="hpc-hppa-2-0"
+ path_20w="pa64"
+ any_20w_testlist="sizeof-long-8"
+ SPEED_CYCLECOUNTER_OBJ_20w=hppa2w.lo
+ cyclecounter_size_20w=2
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+
+ ia64*-*-* | itanium-*-* | itanium2-*-*)
+ abilist="64"
+
+echo "include_mpn(\`ia64/ia64-defs.m4')" >> $gmp_tmpconfigm4i
+
+ SPEED_CYCLECOUNTER_OBJ=ia64.lo
+ any_32_testlist="sizeof-long-4"
+
+ case $host_cpu in
+ itanium) path="ia64/itanium ia64" ;;
+ itanium2) path="ia64/itanium2 ia64" ;;
+ *) path="ia64" ;;
+ esac
+
+ gcc_64_cflags_optlist="tune"
+ gcc_32_cflags_optlist=$gcc_64_cflags_optlist
+
+ # gcc pre-release 3.4 adds -mtune itanium and itanium2
+ case $host_cpu in
+ itanium) gcc_cflags_tune="-mtune=itanium" ;;
+ itanium2) gcc_cflags_tune="-mtune=itanium2" ;;
+ esac
+
+ case $host in
+ *-*-linux*)
+ cclist="gcc icc"
+ icc_cflags="-no-gcc"
+ icc_cflags_optlist="opt"
+ # Don't use -O3, it is for "large data sets" and also miscompiles GMP.
+ # But icc miscompiles GMP at any optimization level, at higher levels
+ # it miscompiles more files...
+ icc_cflags_opt="-O2 -O1"
+ ;;
+
+ *-*-hpux*)
+ # HP cc sometimes gets internal errors if the optimization level is
+ # too high. GMP_PROG_CC_WORKS detects this, the "_opt" fallbacks
+ # let us use whatever seems to work.
+ #
+ abilist="32 64"
+ any_64_testlist="sizeof-long-8"
+
+ cclist_32="gcc cc"
+ path_32="ia64"
+ cc_32_cflags=""
+ cc_32_cflags_optlist="opt"
+ cc_32_cflags_opt="+O3 +O2 +O1"
+ gcc_32_cflags="$gcc_cflags -milp32"
+ limb_32=longlong
+ SPEED_CYCLECOUNTER_OBJ_32=ia64.lo
+ cyclecounter_size_32=2
+
+ # Must have +DD64 in CPPFLAGS to get the right __LP64__ for headers,
+ # but also need it in CFLAGS for linking programs, since automake
+ # only uses CFLAGS when linking, not CPPFLAGS.
+ # FIXME: Maybe should use cc_64_ldflags for this, but that would
+ # need GMP_LDFLAGS used consistently by all the programs.
+ #
+ cc_64_cflags="+DD64"
+ cc_64_cppflags="+DD64"
+ cc_64_cflags_optlist="opt"
+ cc_64_cflags_opt="+O3 +O2 +O1"
+ gcc_64_cflags="$gcc_cflags -mlp64"
+ ;;
+ esac
+ ;;
+
+
+ # Motorola 68k
+ #
+ m68k-*-* | m68[0-9][0-9][0-9]-*-*)
+ $as_echo "#define HAVE_HOST_CPU_FAMILY_m68k 1" >>confdefs.h
+
+
+echo "include_mpn(\`m68k/m68k-defs.m4')" >> $gmp_tmpconfigm4i
+
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ gcc_cflags_optlist="arch"
+
+ # gcc 2.7.2 knows -m68000, -m68020, -m68030, -m68040.
+ # gcc 2.95 adds -mcpu32, -m68060.
+ # FIXME: Maybe "-m68020 -mnobitfield" would suit cpu32 on 2.7.2.
+ #
+ case $host_cpu in
+ m68020) gcc_cflags_arch="-m68020" ;;
+ m68030) gcc_cflags_arch="-m68030" ;;
+ m68040) gcc_cflags_arch="-m68040" ;;
+ m68060) gcc_cflags_arch="-m68060 -m68000" ;;
+ m68360) gcc_cflags_arch="-mcpu32 -m68000" ;;
+ *) gcc_cflags_arch="-m68000" ;;
+ esac
+
+ # FIXME: m68k/mc68020 looks like it's ok for cpu32, but this wants to be
+ # tested. Will need to introduce an m68k/cpu32 if m68k/mc68020 ever uses
+ # the bitfield instructions.
+ case $host_cpu in
+ m680[234]0 | m68360) path="m68k/mc68020 m68k" ;;
+ *) path="m68k" ;;
+ esac
+ ;;
+
+
+ # Motorola 88k
+ m88k*-*-*)
+ path="m88k"
+ ;;
+ m88110*-*-*)
+ gcc_cflags="$gcc_cflags -m88110"
+ path="m88k/mc88110 m88k"
+ ;;
+
+
+ # IRIX 5 and earlier can only run 32-bit o32.
+ #
+ # IRIX 6 and up always has a 64-bit mips CPU can run n32 or 64. n32 is
+ # preferred over 64, but only because that's been the default in past
+ # versions of GMP. The two are equally efficient.
+ #
+ # Linux kernel 2.2.13 arch/mips/kernel/irixelf.c has a comment about not
+ # supporting n32 or 64.
+ #
+ # For reference, libtool (eg. 1.5.6) recognises the n32 ABI and knows the
+ # right options to use when linking (both cc and gcc), so no need for
+ # anything special from us.
+ #
+ mips*-*-*)
+ abilist="o32"
+ gcc_cflags_optlist="abi"
+ gcc_cflags_abi="-mabi=32"
+ gcc_testlist="gcc-mips-o32"
+ path="mips32"
+ cc_cflags="-O2 -o32" # no -g, it disables all optimizations
+ # this suits both mips32 and mips64
+
+echo "include_mpn(\`mips32/mips-defs.m4')" >> $gmp_tmpconfigm4i
+
+
+ case $host in
+ mips64*-*-* | mips*-*-irix[6789]*)
+ abilist="n32 64 o32"
+
+ cclist_n32="gcc cc"
+ gcc_n32_cflags="$gcc_cflags -mabi=n32"
+ cc_n32_cflags="-O2 -n32" # no -g, it disables all optimizations
+ limb_n32=longlong
+ path_n32="mips64"
+
+ cclist_64="gcc cc"
+ gcc_64_cflags="$gcc_cflags -mabi=64"
+ gcc_64_ldflags="-Wc,-mabi=64"
+ cc_64_cflags="-O2 -64" # no -g, it disables all optimizations
+ cc_64_ldflags="-Wc,-64"
+ path_64="mips64"
+ ;;
+ esac
+ ;;
+
+
+ # Darwin (powerpc-apple-darwin1.3) has it's hacked gcc installed as cc.
+ # Our usual "gcc in disguise" detection means gcc_cflags etc here gets
+ # used.
+ #
+ # The darwin pre-compiling preprocessor is disabled with -no-cpp-precomp
+ # since it doesn't like "__attribute__ ((mode (SI)))" etc in gmp-impl.h,
+ # and so always ends up running the plain preprocessor anyway. This could
+ # be done in CPPFLAGS rather than CFLAGS, but there's not many places
+ # preprocessing is done separately, and this is only a speedup, the normal
+ # preprocessor gets run if there's any problems.
+ #
+ # We used to use -Wa,-mppc with gcc, but can't remember exactly why.
+ # Presumably it was for old versions of gcc where -mpowerpc doesn't put
+ # the assembler in the right mode. In any case -Wa,-mppc is not good, for
+ # instance -mcpu=604 makes recent gcc use -m604 to get access to the
+ # "fsel" instruction, but a -Wa,-mppc overrides that, making code that
+ # comes out with fsel fail.
+ #
+ # (Note also that the darwin assembler doesn't accept "-mppc", so any
+ # -Wa,-mppc was used only if it worked. The right flag on darwin would be
+ # "-arch ppc" or some such, but that's already the default.)
+ #
+ powerpc*-*-* | power[3-9]-*-*)
+ $as_echo "#define HAVE_HOST_CPU_FAMILY_powerpc 1" >>confdefs.h
+
+ HAVE_HOST_CPU_FAMILY_powerpc=1
+ abilist="32"
+ cclist="gcc cc"
+ cc_cflags="-O2"
+ gcc_32_cflags="$gcc_cflags -mpowerpc"
+ gcc_cflags_optlist="precomp subtype asm cpu"
+ gcc_cflags_precomp="-no-cpp-precomp"
+ gcc_cflags_subtype="-force_cpusubtype_ALL" # for vmx on darwin
+ gcc_cflags_asm=""
+ gcc_cflags_cpu=""
+ vmx_path=""
+
+ # grab this object, though it's not a true cycle counter routine
+ SPEED_CYCLECOUNTER_OBJ=powerpc.lo
+ cyclecounter_size=0
+
+ case $host_cpu in
+ powerpc740 | powerpc750)
+ path="powerpc32/750 powerpc32" ;;
+ powerpc7400 | powerpc7410)
+ path="powerpc32/vmx powerpc32/750 powerpc32" ;;
+ powerpc74[45]?)
+ path="powerpc32/vmx powerpc32" ;;
+ *)
+ path="powerpc32" ;;
+ esac
+
+ case $host_cpu in
+ powerpc401) gcc_cflags_cpu="-mcpu=401" ;;
+ powerpc403) gcc_cflags_cpu="-mcpu=403"
+ xlc_cflags_arch="-qarch=403 -qarch=ppc" ;;
+ powerpc405) gcc_cflags_cpu="-mcpu=405" ;;
+ powerpc505) gcc_cflags_cpu="-mcpu=505" ;;
+ powerpc601) gcc_cflags_cpu="-mcpu=601"
+ xlc_cflags_arch="-qarch=601 -qarch=ppc" ;;
+ powerpc602) gcc_cflags_cpu="-mcpu=602"
+ xlc_cflags_arch="-qarch=602 -qarch=ppc" ;;
+ powerpc603) gcc_cflags_cpu="-mcpu=603"
+ xlc_cflags_arch="-qarch=603 -qarch=ppc" ;;
+ powerpc603e) gcc_cflags_cpu="-mcpu=603e -mcpu=603"
+ xlc_cflags_arch="-qarch=603 -qarch=ppc" ;;
+ powerpc604) gcc_cflags_cpu="-mcpu=604"
+ xlc_cflags_arch="-qarch=604 -qarch=ppc" ;;
+ powerpc604e) gcc_cflags_cpu="-mcpu=604e -mcpu=604"
+ xlc_cflags_arch="-qarch=604 -qarch=ppc" ;;
+ powerpc620) gcc_cflags_cpu="-mcpu=620" ;;
+ powerpc630) gcc_cflags_cpu="-mcpu=630"
+ xlc_cflags_arch="-qarch=pwr3"
+ cpu_path="p3 p3-p7" ;;
+ powerpc740) gcc_cflags_cpu="-mcpu=740" ;;
+ powerpc7400 | powerpc7410)
+ gcc_cflags_asm="-Wa,-maltivec"
+ gcc_cflags_cpu="-mcpu=7400 -mcpu=750" ;;
+ powerpc74[45]?)
+ gcc_cflags_asm="-Wa,-maltivec"
+ gcc_cflags_cpu="-mcpu=7450" ;;
+ powerpc750) gcc_cflags_cpu="-mcpu=750" ;;
+ powerpc801) gcc_cflags_cpu="-mcpu=801" ;;
+ powerpc821) gcc_cflags_cpu="-mcpu=821" ;;
+ powerpc823) gcc_cflags_cpu="-mcpu=823" ;;
+ powerpc860) gcc_cflags_cpu="-mcpu=860" ;;
+ powerpc970) gcc_cflags_cpu="-mtune=970"
+ xlc_cflags_arch="-qarch=970 -qarch=pwr3"
+ vmx_path="powerpc64/vmx"
+ cpu_path="p4 p3-p7" ;;
+ power4) gcc_cflags_cpu="-mtune=power4"
+ xlc_cflags_arch="-qarch=pwr4"
+ cpu_path="p4 p3-p7" ;;
+ power5) gcc_cflags_cpu="-mtune=power5 -mtune=power4"
+ xlc_cflags_arch="-qarch=pwr5"
+ cpu_path="p5 p4 p3-p7" ;;
+ power6) gcc_cflags_cpu="-mtune=power6"
+ xlc_cflags_arch="-qarch=pwr6"
+ cpu_path="p6 p3-p7" ;;
+ power7) gcc_cflags_cpu="-mtune=power7 -mtune=power5"
+ xlc_cflags_arch="-qarch=pwr7 -qarch=pwr5"
+ cpu_path="p7 p5 p4 p3-p7" ;;
+ esac
+
+ case $host in
+ *-*-aix*)
+ cclist="gcc xlc cc"
+ gcc_32_cflags_maybe="-maix32"
+ xlc_cflags="-O2 -qmaxmem=20000"
+ xlc_cflags_optlist="arch"
+ xlc_32_cflags_maybe="-q32"
+ ar_32_flags="-X32"
+ nm_32_flags="-X32"
+ esac
+
+ case $host in
+ powerpc64-*-* | powerpc64le-*-* | powerpc620-*-* | powerpc630-*-* | powerpc970-*-* | power[3-9]-*-*)
+ case $host in
+ *-*-aix*)
+ # On AIX a true 64-bit ABI is available.
+ # Need -Wc to pass object type flags through to the linker.
+ abilist="mode64 $abilist"
+ cclist_mode64="gcc xlc"
+ gcc_mode64_cflags="$gcc_cflags -maix64 -mpowerpc64"
+ gcc_mode64_cflags_optlist="cpu"
+ gcc_mode64_ldflags="-Wc,-maix64"
+ xlc_mode64_cflags="-O2 -q64 -qmaxmem=20000"
+ xlc_mode64_cflags_optlist="arch"
+ xlc_mode64_ldflags="-Wc,-q64"
+ # Must indicate object type to ar and nm
+ ar_mode64_flags="-X64"
+ nm_mode64_flags="-X64"
+ path_mode64=""
+ p=""
+ for i in $cpu_path
+ do path_mode64="${path_mode64}powerpc64/mode64/$i "
+ path_mode64="${path_mode64}powerpc64/$i "
+ p="${p} powerpc32/$i "
+ done
+ path_mode64="${path_mode64}powerpc64/mode64 $vmx_path powerpc64"
+ path="$p $path"
+ # grab this object, though it's not a true cycle counter routine
+ SPEED_CYCLECOUNTER_OBJ_mode64=powerpc64.lo
+ cyclecounter_size_mode64=0
+ ;;
+ *-*-darwin*)
+ # On Darwin we can use 64-bit instructions with a longlong limb,
+ # but the chip still in 32-bit mode.
+ # In theory this can be used on any OS which knows how to save
+ # 64-bit registers in a context switch.
+ #
+ # Note that we must use -mpowerpc64 with gcc, since the
+ # longlong.h macros expect limb operands in a single 64-bit
+ # register, not two 32-bit registers as would be given for a
+ # long long without -mpowerpc64. In theory we could detect and
+ # accommodate both styles, but the proper 64-bit registers will
+ # be fastest and are what we really want to use.
+ #
+ # One would think -mpowerpc64 would set the assembler in the right
+ # mode to handle 64-bit instructions. But for that, also
+ # -force_cpusubtype_ALL is needed.
+ #
+ # Do not use -fast for Darwin, it actually adds options
+ # incompatible with a shared library.
+ #
+ abilist="mode64 mode32 $abilist"
+ gcc_32_cflags_maybe="-m32"
+ gcc_cflags_opt="-O3 -O2 -O1" # will this become used?
+ cclist_mode32="gcc"
+ gcc_mode32_cflags_maybe="-m32"
+ gcc_mode32_cflags="-mpowerpc64"
+ gcc_mode32_cflags_optlist="subtype cpu opt"
+ gcc_mode32_cflags_subtype="-force_cpusubtype_ALL"
+ gcc_mode32_cflags_opt="-O3 -O2 -O1"
+ limb_mode32=longlong
+ cclist_mode64="gcc"
+ gcc_mode64_cflags="-m64"
+ gcc_mode64_cflags_optlist="cpu opt"
+ gcc_mode64_cflags_opt="-O3 -O2 -O1"
+ path_mode64=""
+ path_mode32=""
+ p=""
+ for i in $cpu_path
+ do path_mode64="${path_mode64}powerpc64/mode64/$i "
+ path_mode64="${path_mode64}powerpc64/$i "
+ path_mode32="${path_mode32}powerpc64/mode32/$i "
+ path_mode32="${path_mode32}powerpc64/$i "
+ p="${p} powerpc32/$i "
+ done
+ path_mode64="${path_mode64}powerpc64/mode64 $vmx_path powerpc64"
+ path_mode32="${path_mode32}powerpc64/mode32 $vmx_path powerpc64"
+ path="$p $path"
+ SPEED_CYCLECOUNTER_OBJ_mode64=powerpc64.lo
+ cyclecounter_size_mode64=0
+ any_mode64_testlist="sizeof-long-8"
+ ;;
+ *-*-linux* | *-*-*bsd*)
+ # On GNU/Linux, assume the processor is in 64-bit mode. Some
+ # environments have a gcc that is always in 64-bit mode, while
+ # others require -m64, hence the use of cflags_maybe. The
+ # sizeof-long-8 test checks the mode is right (for the no option
+ # case).
+ #
+ # -mpowerpc64 is not used, since it should be the default in
+ # 64-bit mode. (We need its effect for the various longlong.h
+ # asm macros to be right of course.)
+ #
+ # gcc64 was an early port of gcc to 64-bit mode, but should be
+ # obsolete before too long. We prefer plain gcc when it knows
+ # 64-bits.
+ #
+ abilist="mode64 mode32 $abilist"
+ gcc_32_cflags_maybe="-m32"
+ cclist_mode32="gcc"
+ gcc_mode32_cflags_maybe="-m32"
+ gcc_mode32_cflags="-mpowerpc64"
+ gcc_mode32_cflags_optlist="cpu opt"
+ gcc_mode32_cflags_opt="-O3 -O2 -O1"
+ limb_mode32=longlong
+ cclist_mode64="gcc gcc64"
+ gcc_mode64_cflags_maybe="-m64"
+ gcc_mode64_cflags_optlist="cpu opt"
+ gcc_mode64_cflags_opt="-O3 -O2 -O1"
+ path_mode64=""
+ path_mode32=""
+ p=""
+ for i in $cpu_path
+ do path_mode64="${path_mode64}powerpc64/mode64/$i "
+ path_mode64="${path_mode64}powerpc64/$i "
+ path_mode32="${path_mode32}powerpc64/mode32/$i "
+ path_mode32="${path_mode32}powerpc64/$i "
+ p="${p} powerpc32/$i "
+ done
+ path_mode64="${path_mode64}powerpc64/mode64 $vmx_path powerpc64"
+ path_mode32="${path_mode32}powerpc64/mode32 $vmx_path powerpc64"
+ path="$p $path"
+ SPEED_CYCLECOUNTER_OBJ_mode64=powerpc64.lo
+ cyclecounter_size_mode64=0
+ any_mode64_testlist="sizeof-long-8"
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+
+ # POWER 32-bit
+ power-*-* | power[12]-*-* | power2sc-*-*)
+ $as_echo "#define HAVE_HOST_CPU_FAMILY_power 1" >>confdefs.h
+
+ HAVE_HOST_CPU_FAMILY_power=1
+ cclist="gcc"
+ extra_functions="udiv_w_sdiv"
+ path="power"
+
+ # gcc 2.7.2 knows rios1, rios2, rsc
+ #
+ # -mcpu=rios2 can tickle an AIX assembler bug (see GMP_PROG_CC_WORKS) so
+ # there needs to be a fallback to just -mpower.
+ #
+ gcc_cflags_optlist="cpu"
+ case $host in
+ power-*-*) gcc_cflags_cpu="-mcpu=power -mpower" ;;
+ power1-*-*) gcc_cflags_cpu="-mcpu=rios1 -mpower" ;;
+ power2-*-*) gcc_cflags_cpu="-mcpu=rios2 -mpower" ;;
+ power2sc-*-*) gcc_cflags_cpu="-mcpu=rsc -mpower" ;;
+ esac
+ case $host in
+ *-*-aix*)
+ cclist="gcc xlc"
+ xlc_cflags="-O2 -qarch=pwr -qmaxmem=20000"
+ ;;
+ esac
+ ;;
+
+
+ # IBM System/390 and z/Architecture
+ s390-*-* | z900esa-*-* | z990esa-*-* | z9esa-*-* | z10esa-*-* | z196esa-*-* | s390x-*-* | z900-*-* | z990-*-* | z9-*-* | z10-*-* | z196-*-*)
+ abilist="32"
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ gcc_cflags_optlist="arch"
+ path="s390_32"
+ extra_functions="udiv_w_sdiv"
+ gcc_32_cflags_maybe="-m31"
+
+ case $host_cpu in
+ s390)
+ ;;
+ z900 | z900esa)
+ cpu="z900"
+ gccarch="$cpu"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HOST_CPU_s390_$cpu 1
+_ACEOF
+
+ $as_echo "#define HAVE_HOST_CPU_s390_zarch 1" >>confdefs.h
+
+ extra_functions=""
+ ;;
+ z990 | z990esa)
+ cpu="z990"
+ gccarch="$cpu"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HOST_CPU_s390_$cpu 1
+_ACEOF
+
+ $as_echo "#define HAVE_HOST_CPU_s390_zarch 1" >>confdefs.h
+
+ extra_functions=""
+ ;;
+ z9 | z9esa)
+ cpu="z9"
+ gccarch="z9-109"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HOST_CPU_s390_$cpu 1
+_ACEOF
+
+ $as_echo "#define HAVE_HOST_CPU_s390_zarch 1" >>confdefs.h
+
+ extra_functions=""
+ ;;
+ z10 | z10esa)
+ cpu="z10"
+ gccarch="z10"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HOST_CPU_s390_$cpu 1
+_ACEOF
+
+ $as_echo "#define HAVE_HOST_CPU_s390_zarch 1" >>confdefs.h
+
+ extra_functions=""
+ ;;
+ z196 | z196esa)
+ cpu="z196"
+ gccarch="z196"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HOST_CPU_s390_$cpu 1
+_ACEOF
+
+ $as_echo "#define HAVE_HOST_CPU_s390_zarch 1" >>confdefs.h
+
+ extra_functions=""
+ ;;
+ esac
+
+ case $host in
+ s390x-*-* | z900-*-* | z990-*-* | z9-*-* | z10-*-* | z196-*-*)
+ abilist="64 32"
+ cclist_64="gcc"
+ gcc_64_cflags_optlist="arch"
+ gcc_64_cflags="$gcc_cflags -m64"
+ path_64="s390_64/$host_cpu s390_64"
+ extra_functions=""
+ ;;
+ esac
+ ;;
+
+
+ sh-*-*) path="sh" ;;
+ sh[2-4]-*-*) path="sh/sh2 sh" ;;
+
+
+ *sparc*-*-*)
+ # sizeof(long)==4 or 8 is tested, to ensure we get the right ABI. We've
+ # had various bug reports where users have set CFLAGS for their desired
+ # mode, but not set our ABI. For some reason it's sparc where this
+ # keeps coming up, presumably users there are accustomed to driving the
+ # compiler mode that way. The effect of our testlist setting is to
+ # reject ABI=64 in favour of ABI=32 if the user has forced the flags to
+ # 32-bit mode.
+ #
+ abilist="32"
+ cclist="gcc acc cc"
+ any_testlist="sizeof-long-4"
+
+echo "include_mpn(\`sparc32/sparc-defs.m4')" >> $gmp_tmpconfigm4i
+
+
+ case $host_cpu in
+ sparcv8 | microsparc | turbosparc)
+ path="sparc32/v8 sparc32" ;;
+ supersparc)
+ path="sparc32/v8/supersparc sparc32/v8 sparc32" ;;
+ sparc64 | sparcv9* | ultrasparc | ultrasparc[234]*)
+ path="sparc32/v9 sparc32/v8 sparc32" ;;
+ ultrasparct[12345])
+ path="sparc32/ultrasparct1 sparc32/v8 sparc32" ;;
+ *)
+ path="sparc32" ;;
+ esac
+
+ # gcc 2.7.2 doesn't know about v9 and doesn't pass -xarch=v8plus to the
+ # assembler. Add it explicitly since the solaris assembler won't accept
+ # our sparc32/v9 asm code without it. gas accepts -xarch=v8plus too, so
+ # it can be in the cflags unconditionally (though gas doesn't need it).
+ #
+ # gcc -m32 is needed to force 32-bit mode on a dual-ABI system, but past
+ # gcc doesn't know that flag, hence cflags_maybe. Note that -m32 cannot
+ # be done through the optlist since the plain cflags would be run first
+ # and we don't want to require the default mode (whatever it is) works.
+ #
+ # Note it's gcc_32_cflags_maybe and not gcc_cflags_maybe because the
+ # latter would be used in the 64-bit ABI on systems like "*bsd" where
+ # abilist="64" only.
+ #
+ gcc_32_cflags_maybe="-m32"
+ gcc_cflags_optlist="cpu asm"
+
+ # gcc 2.7.2 knows -mcypress, -msupersparc, -mv8, -msparclite.
+ # gcc 2.95 knows -mcpu= v7, hypersparc, sparclite86x, f930, f934,
+ # sparclet, tsc701, v9, ultrasparc. A warning is given that the
+ # plain -m forms will disappear.
+ # gcc 3.3 adds ultrasparc3.
+ #
+ case $host_cpu in
+ supersparc*)
+ gcc_cflags_cpu="-mcpu=supersparc -msupersparc"
+ gcc_cflags_asm="-Wa,-Av8 -Wa,-xarch=v8";;
+ sparcv8 | microsparc* | turbosparc | hypersparc*)
+ gcc_cflags_cpu="-mcpu=v8 -mv8"
+ gcc_cflags_asm="-Wa,-Av8 -Wa,-xarch=v8";;
+ sparc64 | sparcv9*)
+ gcc_cflags_cpu="-mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8 -Wa,-xarch=v8plus"
+ gcc_64_cflags_asm="-Wa,-Av9 -Wa,-xarch=v9";;
+ ultrasparc1 | ultrasparc2*)
+ gcc_cflags_cpu="-mcpu=ultrasparc -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusa -Wa,-xarch=v8plusa"
+ gcc_64_cflags_asm="-Wa,-Av9a -Wa,-xarch=v9a";;
+ ultrasparc[34])
+ gcc_cflags_cpu="-mcpu=ultrasparc3 -mcpu=ultrasparc -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusb -Wa,-xarch=v8plusb"
+ gcc_64_cflags_asm="-Wa,-Av9b -Wa,-xarch=v9b";;
+ ultrasparct[12])
+ gcc_cflags_cpu="-mcpu=niagara -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusc -Wa,-xarch=v8plusc"
+ gcc_64_cflags_asm="-Wa,-Av9c -Wa,-xarch=v9c";;
+ ultrasparct3)
+ gcc_cflags_cpu="-mcpu=niagara3 -mcpu=niagara -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusd -Wa,-xarch=v8plusd"
+ gcc_64_cflags_asm="-Wa,-Av9d -Wa,-xarch=v9d";;
+ ultrasparct4)
+ gcc_cflags_cpu="-mcpu=niagara4 -mcpu=niagara3 -mcpu=niagara -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusd -Wa,-xarch=v8plusd"
+ gcc_64_cflags_asm="-Wa,-Av9d -Wa,-xarch=v9d";;
+ *)
+ gcc_cflags_cpu="-mcpu=v7 -mcypress"
+ gcc_cflags_asm="";;
+ esac
+
+ # SunPRO cc and acc, and SunOS bundled cc
+ case $host in
+ *-*-solaris* | *-*-sunos*)
+ # Note no -g, it disables all optimizations.
+ cc_cflags=
+ cc_cflags_optlist="opt arch cpu"
+
+ # SunOS cc doesn't know -xO4, fallback to -O2.
+ cc_cflags_opt="-xO4 -O2"
+
+ # SunOS cc doesn't know -xarch, apparently always generating v7
+ # code, so make this optional
+ case $host_cpu in
+ sparcv8 | microsparc* | supersparc* | turbosparc | hypersparc*)
+ cc_cflags_arch="-xarch=v8";;
+ ultrasparct[345])
+ cc_cflags_arch="-xarch=v8plusd" ;;
+ sparc64 | sparcv9* | ultrasparc*)
+ cc_cflags_arch="-xarch=v8plus" ;;
+ *)
+ cc_cflags_arch="-xarch=v7" ;;
+ esac
+
+ # SunOS cc doesn't know -xchip and doesn't seem to have an equivalent.
+ # SunPRO cc 5 recognises -xchip=generic, old, super, super2, micro,
+ # micro2, hyper, hyper2, powerup, ultra, ultra2, ultra2i.
+ # SunPRO cc 6 adds -xchip=ultra2e, ultra3cu.
+ #
+ case $host_cpu in
+ supersparc*) cc_cflags_cpu="-xchip=super" ;;
+ microsparc*) cc_cflags_cpu="-xchip=micro" ;;
+ turbosparc) cc_cflags_cpu="-xchip=micro2" ;;
+ hypersparc*) cc_cflags_cpu="-xchip=hyper" ;;
+ ultrasparc) cc_cflags_cpu="-xchip=ultra" ;;
+ ultrasparc2) cc_cflags_cpu="-xchip=ultra2 -xchip=ultra" ;;
+ ultrasparc2i) cc_cflags_cpu="-xchip=ultra2i -xchip=ultra2 -xchip=ultra" ;;
+ ultrasparc3) cc_cflags_cpu="-xchip=ultra3 -xchip=ultra" ;;
+ ultrasparc4) cc_cflags_cpu="-xchip=ultra4 -xchip=ultra3 -xchip=ultra" ;;
+ ultrasparct1) cc_cflags_cpu="-xchip=ultraT1" ;;
+ ultrasparct2) cc_cflags_cpu="-xchip=ultraT2 -xchip=ultraT1" ;;
+ ultrasparct3) cc_cflags_cpu="-xchip=ultraT3 -xchip=ultraT2" ;;
+ ultrasparct4) cc_cflags_cpu="-xchip=T4" ;;
+ ultrasparct5) cc_cflags_cpu="-xchip=T5 -xchip=T4" ;;
+ *) cc_cflags_cpu="-xchip=generic" ;;
+ esac
+ esac
+
+ case $host_cpu in
+ sparc64 | sparcv9* | ultrasparc*)
+ case $host in
+ # Solaris 6 and earlier cannot run ABI=64 since it doesn't save
+ # registers properly, so ABI=32 is left as the only choice.
+ #
+ *-*-solaris2.[0-6] | *-*-solaris2.[0-6].*) ;;
+
+ # BSD sparc64 ports are 64-bit-only systems, so ABI=64 is the only
+ # choice. In fact they need no special compiler flags, gcc -m64
+ # is the default, but it doesn't hurt to add it. v9 CPUs always
+ # use the sparc64 port, since the plain 32-bit sparc ports don't
+ # run on a v9.
+ #
+ *-*-*bsd*) abilist="64" ;;
+
+ # For all other systems, we try both 64 and 32.
+ #
+ # GNU/Linux sparc64 has only recently gained a 64-bit user mode.
+ # In the past sparc64 meant a v9 cpu, but there were no 64-bit
+ # operations in user mode. We assume that if "gcc -m64" works
+ # then the system is suitable. Hopefully even if someone attempts
+ # to put a new gcc and/or glibc on an old system it won't run.
+ #
+ *) abilist="64 32" ;;
+ esac
+
+ case $host_cpu in
+ ultrasparc | ultrasparc2 | ultrasparc2i)
+ path_64="sparc64/ultrasparc1234 sparc64" ;;
+ ultrasparc[34])
+ path_64="sparc64/ultrasparc34 sparc64/ultrasparc1234 sparc64" ;;
+ ultrasparct[12])
+ path_64="sparc64/ultrasparct1 sparc64" ;;
+ ultrasparct[345])
+ path_64="sparc64/ultrasparct3 sparc64" ;;
+ *)
+ path_64="sparc64"
+ esac
+
+ cclist_64="gcc"
+ any_64_testlist="sizeof-long-8"
+
+ # gcc -mptr64 is probably implied by -m64, but we're not sure if
+ # this was always so. On Solaris in the past we always used both
+ # "-m64 -mptr64".
+ #
+ # gcc -Wa,-xarch=v9 is thought to be necessary in some cases on
+ # solaris, but it would seem likely that if gcc is going to generate
+ # 64-bit code it will have to add that option itself where needed.
+ # An extra copy of this option should be harmless though, but leave
+ # it until we're sure. (Might want -xarch=v9a or -xarch=v9b for the
+ # higher cpu types instead.)
+ #
+ gcc_64_cflags="$gcc_cflags -m64 -mptr64"
+ gcc_64_ldflags="-Wc,-m64"
+ gcc_64_cflags_optlist="cpu asm"
+
+ case $host in
+ *-*-solaris*)
+ # Sun cc.
+ #
+ # We used to have -fast and some fixup options here, but it
+ # recurrently caused problems with miscompilation. Of course,
+ # -fast is documented as miscompiling things for the sake of speed.
+ #
+ cclist_64="$cclist_64 cc"
+ cc_64_cflags_optlist="cpu"
+ case $host_cpu in
+ ultrasparct[345])
+ cc_64_cflags="$cc_64_cflags -xO3 -xarch=v9d" ;;
+ *)
+ cc_64_cflags="-xO3 -xarch=v9" ;;
+ esac
+ ;;
+ esac
+
+ # using the v9 %tick register
+ SPEED_CYCLECOUNTER_OBJ_32=sparcv9.lo
+ SPEED_CYCLECOUNTER_OBJ_64=sparcv9.lo
+ cyclecounter_size_32=2
+ cyclecounter_size_64=2
+ ;;
+ esac
+ ;;
+
+
+ # VAX
+ vax*-*-*elf*)
+ # Use elf conventions (i.e., '%' register prefix, no global prefix)
+ #
+
+echo "include_mpn(\`vax/elf.m4')" >> $gmp_tmpconfigm4i
+
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ path="vax"
+ extra_functions="udiv_w_sdiv"
+ ;;
+ vax*-*-*)
+ # Default to aout conventions (i.e., no register prefix, '_' global prefix)
+ #
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ path="vax"
+ extra_functions="udiv_w_sdiv"
+ ;;
+
+
+ # AMD and Intel x86 configurations, including AMD64
+ #
+ # Rumour has it gcc -O2 used to give worse register allocation than just
+ # -O, but lets assume that's no longer true.
+ #
+ # -m32 forces 32-bit mode on a bi-arch 32/64 amd64 build of gcc. -m64 is
+ # the default in such a build (we think), so -m32 is essential for ABI=32.
+ # This is, of course, done for any $host_cpu, not just x86_64, so we can
+ # get such a gcc into the right mode to cross-compile to say i486-*-*.
+ #
+ # -m32 is not available in gcc 2.95 and earlier, hence cflags_maybe to use
+ # it when it works. We check sizeof(long)==4 to ensure we get the right
+ # mode, in case -m32 has failed not because it's an old gcc, but because
+ # it's a dual 32/64-bit gcc without a 32-bit libc, or whatever.
+ #
+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-* | athlon64-*-* | k8-*-* | k10-*-* | bobcat-*-* | jaguar-*-* | bulldozer-*-* | piledriver-*-* | steamroller-*-* | excavator-*-* | pentium4-*-* | atom-*-* | core2-*-* | corei*-*-* | x86_64-*-* | nano-*-*)
+ abilist="32"
+ cclist="gcc icc cc"
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ gcc_32_cflags_maybe="-m32"
+ icc_cflags="-no-gcc"
+ icc_cflags_optlist="opt"
+ icc_cflags_opt="-O3 -O2 -O1"
+ any_32_testlist="sizeof-long-4"
+ CALLING_CONVENTIONS_OBJS='x86call.lo x86check$U.lo'
+
+ # Availability of rdtsc is checked at run-time.
+ SPEED_CYCLECOUNTER_OBJ=pentium.lo
+
+ # gcc 2.7.2 only knows i386 and i486, using -m386 or -m486. These
+ # represent -mcpu= since -m486 doesn't generate 486 specific insns.
+ # gcc 2.95 adds k6, pentium and pentiumpro, and takes -march= and -mcpu=.
+ # gcc 3.0 adds athlon.
+ # gcc 3.1 adds k6-2, k6-3, pentium-mmx, pentium2, pentium3, pentium4,
+ # athlon-tbird, athlon-4, athlon-xp, athlon-mp.
+ # gcc 3.2 adds winchip2.
+ # gcc 3.3 adds winchip-c6.
+ # gcc 3.3.1 from mandrake adds k8 and knows -mtune.
+ # gcc 3.4 adds c3, c3-2, k8, and deprecates -mcpu in favour of -mtune.
+ #
+ # In gcc 2.95.[0123], -march=pentiumpro provoked a stack slot bug in an
+ # old version of mpz/powm.c. Seems to be fine with the current code, so
+ # no need for any restrictions on that option.
+ #
+ # -march=pentiumpro can fail if the assembler doesn't know "cmov"
+ # (eg. solaris 2.8 native "as"), so always have -march=pentium after
+ # that as a fallback.
+ #
+ # -march=pentium4 and -march=k8 enable SSE2 instructions, which may or
+ # may not be supported by the assembler and/or the OS, and is bad in gcc
+ # prior to 3.3. The tests will reject these if no good, so fallbacks
+ # like "-march=pentium4 -mno-sse2" are given to try also without SSE2.
+ # Note the relevant -march types are listed in the optflags handling
+ # below, be sure to update there if adding new types emitting SSE2.
+ #
+ # -mtune is used at the start of each cpu option list to give something
+ # gcc 3.4 will use, thereby avoiding warnings from -mcpu. -mcpu forms
+ # are retained for use by prior gcc. For example pentium has
+ # "-mtune=pentium -mcpu=pentium ...", the -mtune is for 3.4 and the
+ # -mcpu for prior. If there's a brand new choice in 3.4 for a chip,
+ # like k8 for x86_64, then it can be the -mtune at the start, no need to
+ # duplicate anything.
+ #
+ gcc_cflags_optlist="cpu arch"
+ case $host_cpu in
+ i386*)
+ gcc_cflags_cpu="-mtune=i386 -mcpu=i386 -m386"
+ gcc_cflags_arch="-march=i386"
+ path="x86"
+ ;;
+ i486*)
+ gcc_cflags_cpu="-mtune=i486 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=i486"
+ path="x86/i486 x86"
+ ;;
+ i586 | pentium)
+ gcc_cflags_cpu="-mtune=pentium -mcpu=pentium -m486"
+ gcc_cflags_arch="-march=pentium"
+ path="x86/pentium x86"
+ ;;
+ pentiummmx)
+ gcc_cflags_cpu="-mtune=pentium-mmx -mcpu=pentium-mmx -mcpu=pentium -m486"
+ gcc_cflags_arch="-march=pentium-mmx -march=pentium"
+ path="x86/pentium/mmx x86/pentium x86/mmx x86"
+ ;;
+ i686 | pentiumpro)
+ gcc_cflags_cpu="-mtune=pentiumpro -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentiumpro -march=pentium"
+ path="x86/p6 x86"
+ ;;
+ pentium2)
+ gcc_cflags_cpu="-mtune=pentium2 -mcpu=pentium2 -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentium2 -march=pentiumpro -march=pentium"
+ path="x86/p6/mmx x86/p6 x86/mmx x86"
+ ;;
+ pentium3)
+ gcc_cflags_cpu="-mtune=pentium3 -mcpu=pentium3 -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentium3 -march=pentiumpro -march=pentium"
+ path="x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ ;;
+ pentiumm)
+ gcc_cflags_cpu="-mtune=pentium3 -mcpu=pentium3 -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentium3 -march=pentiumpro -march=pentium"
+ path="x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ ;;
+ k6)
+ gcc_cflags_cpu="-mtune=k6 -mcpu=k6 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k6"
+ path="x86/k6/mmx x86/k6 x86/mmx x86"
+ ;;
+ k62)
+ gcc_cflags_cpu="-mtune=k6-2 -mcpu=k6-2 -mcpu=k6 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k6-2 -march=k6"
+ path="x86/k6/k62mmx x86/k6/mmx x86/k6 x86/mmx x86"
+ ;;
+ k63)
+ gcc_cflags_cpu="-mtune=k6-3 -mcpu=k6-3 -mcpu=k6 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k6-3 -march=k6"
+ path="x86/k6/k62mmx x86/k6/mmx x86/k6 x86/mmx x86"
+ ;;
+ geode)
+ gcc_cflags_cpu="-mtune=k6-3 -mcpu=k6-3 -mcpu=k6 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k6-3 -march=k6"
+ path="x86/geode x86/k6/k62mmx x86/k6/mmx x86/k6 x86/mmx x86"
+ ;;
+ athlon)
+ # Athlon instruction costs are close to P6 (3 cycle load latency,
+ # 4-6 cycle mul, 40 cycle div, pairable adc, etc) so if gcc doesn't
+ # know athlon (eg. 2.95.2 doesn't) then fall back on pentiumpro.
+ gcc_cflags_cpu="-mtune=athlon -mcpu=athlon -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=athlon -march=pentiumpro -march=pentium"
+ path="x86/k7/mmx x86/k7 x86/mmx x86"
+ ;;
+ i786 | pentium4)
+ # pentiumpro is the primary fallback when gcc doesn't know pentium4.
+ # This gets us cmov to eliminate branches. Maybe "athlon" would be
+ # a possibility on gcc 3.0.
+ #
+ gcc_cflags_cpu="-mtune=pentium4 -mcpu=pentium4 -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentium4 -march=pentium4~-mno-sse2 -march=pentiumpro -march=pentium"
+ gcc_64_cflags_cpu="-mtune=nocona"
+ path="x86/pentium4/sse2 x86/pentium4/mmx x86/pentium4 x86/mmx x86"
+ path_64="x86_64/pentium4 x86_64"
+ ;;
+ viac32)
+ # Not sure of the best fallbacks here for -mcpu.
+ # c3-2 has sse and mmx, so pentium3 is good for -march.
+ gcc_cflags_cpu="-mtune=c3-2 -mcpu=c3-2 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=c3-2 -march=pentium3 -march=pentiumpro -march=pentium"
+ path="x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ ;;
+ viac3*)
+ # Not sure of the best fallbacks here.
+ gcc_cflags_cpu="-mtune=c3 -mcpu=c3 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=c3 -march=pentium-mmx -march=pentium"
+ path="x86/pentium/mmx x86/pentium x86/mmx x86"
+ ;;
+ athlon64 | k8 | x86_64)
+ gcc_cflags_cpu="-mtune=k8 -mcpu=athlon -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k8 -march=k8~-mno-sse2 -march=athlon -march=pentiumpro -march=pentium"
+ path="x86/k8 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/k8 x86_64"
+ ;;
+ k10)
+ gcc_cflags_cpu="-mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/k10 x86/k8 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ bobcat)
+ gcc_cflags_cpu="-mtune=btver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=btver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bobcat x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bobcat x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ jaguar)
+ gcc_cflags_cpu="-mtune=btver2 -mtune=btver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=btver2 -march=btver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/jaguar x86/bobcat x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/jaguar x86_64/bobcat x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ bulldozer | bd1)
+ gcc_cflags_cpu="-mtune=bdver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=bdver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bd1 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bd1 x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ piledriver | bd2)
+ gcc_cflags_cpu="-mtune=bdver2 -mtune=bdver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=bdver2 -march=bdver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bd2 x86/bd1 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bd2 x86_64/bd1 x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ steamroller | bd3)
+ gcc_cflags_cpu="-mtune=bdver3 -mtune=bdver2 -mtune=bdver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=bdver3 -march=bdver2 -march=bdver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bd3 x86/bd2 x86/bd1 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bd3 x86_64/bd2 x86_64/bd1 x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ excavator | bd4)
+ gcc_cflags_cpu="-mtune=bdver4 -mtune=bdver3 -mtune=bdver2 -mtune=bdver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=bdver4 -march=bdver3 -march=bdver2 -march=bdver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bd4 x86/bd3 x86/bd2 x86/bd1 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bd4 x86_64/bd3 x86_64/bd2 x86_64/bd1 x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ core2)
+ gcc_cflags_cpu="-mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/core2 x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/core2 x86_64"
+ ;;
+ corei | coreinhm | coreiwsm)
+ gcc_cflags_cpu="-mtune=corei7 -mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=corei7 -march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/coreinhm x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/coreinhm x86_64/core2 x86_64"
+ ;;
+ coreisbr)
+ gcc_cflags_cpu="-mtune=corei7 -mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=corei7 -march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/coreisbr x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/coreisbr x86_64/coreinhm x86_64/core2 x86_64"
+ ;;
+ coreihwl)
+ gcc_cflags_cpu="-mtune=corei7 -mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=corei7 -march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/coreisbr x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/coreihwl x86_64/coreisbr x86_64/coreinhm x86_64/core2 x86_64"
+ ;;
+ coreibwl)
+ gcc_cflags_cpu="-mtune=corei7 -mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=corei7 -march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/coreisbr x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/coreihwl x86_64/coreisbr x86_64/coreinhm x86_64/core2 x86_64"
+ # extra_functions_64="missing" # enable for bmi2/adx simulation
+ ;;
+ atom)
+ gcc_cflags_cpu="-mtune=atom -mtune=pentium3"
+ gcc_cflags_arch="-march=atom -march=pentium3"
+ path="x86/atom/sse2 x86/atom/mmx x86/atom x86/mmx x86"
+ path_64="x86_64/atom x86_64"
+ ;;
+ nano)
+ gcc_cflags_cpu="-mtune=nano"
+ gcc_cflags_arch="-march=nano"
+ path="x86/nano x86/mmx x86"
+ path_64="x86_64/nano x86_64"
+ ;;
+ *)
+ gcc_cflags_cpu="-mtune=i486 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=i486"
+ path="x86"
+ path_64="x86_64"
+ ;;
+ esac
+
+ case $host in
+ athlon64-*-* | k8-*-* | k10-*-* | bobcat-*-* | jaguar-*-* | bulldozer-*-* | piledriver-*-* | steamroller-*-* | excavator-*-* | pentium4-*-* | atom-*-* | core2-*-* | corei*-*-* | x86_64-*-* | nano-*-*)
+ cclist_64="gcc cc"
+ gcc_64_cflags="$gcc_cflags -m64"
+ gcc_64_cflags_optlist="cpu arch"
+ CALLING_CONVENTIONS_OBJS_64='amd64call.lo amd64check$U.lo'
+ SPEED_CYCLECOUNTER_OBJ_64=x86_64.lo
+ cyclecounter_size_64=2
+
+ cclist_x32="gcc cc"
+ gcc_x32_cflags="$gcc_cflags -mx32"
+ gcc_x32_cflags_optlist="$gcc_64_cflags_optlist"
+ CALLING_CONVENTIONS_OBJS_x32="$CALLING_CONVENTIONS_OBJS_64"
+ SPEED_CYCLECOUNTER_OBJ_x32="$SPEED_CYCLECOUNTER_OBJ_64"
+ cyclecounter_size_x32="$cyclecounter_size_64"
+ path_x32="$path_64"
+ limb_x32=longlong
+ any_x32_testlist="sizeof-long-4"
+
+ abilist="64 x32 32"
+ if test "$enable_assembly" = "yes" ; then
+ extra_functions_64="$extra_functions_64 invert_limb_table"
+ extra_functions_x32=$extra_functions_64
+ fi
+
+ case $host in
+ *-*-solaris*)
+ # Sun cc.
+ cc_64_cflags="-xO3 -m64"
+ ;;
+ *-*-mingw* | *-*-cygwin)
+ limb_64=longlong
+ CALLING_CONVENTIONS_OBJS_64=""
+
+$as_echo "#define HOST_DOS64 1" >>confdefs.h
+
+ GMP_NONSTD_ABI_64=DOS64
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+
+ # Special CPU "none" used to select generic C, now this is obsolete.
+ none-*-*)
+ enable_assembly=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: the \"none\" host is obsolete, use --disable-assembly" >&5
+$as_echo "$as_me: WARNING: the \"none\" host is obsolete, use --disable-assembly" >&2;}
+ ;;
+
+esac
+
+# mingw can be built by the cygwin gcc if -mno-cygwin is added. For
+# convenience add this automatically if it works. Actual mingw gcc accepts
+# -mno-cygwin too, but of course is the default. mingw only runs on the
+# x86s, but allow any CPU here so as to catch "none" too.
+#
+case $host in
+ *-*-mingw*)
+ gcc_cflags_optlist="$gcc_cflags_optlist nocygwin"
+ gcc_cflags_nocygwin="-mno-cygwin"
+ ;;
+esac
+
+
+CFLAGS_or_unset=${CFLAGS-'(unset)'}
+CPPFLAGS_or_unset=${CPPFLAGS-'(unset)'}
+
+cat >&5 <<EOF
+User:
+ABI=$ABI
+CC=$CC
+CFLAGS=$CFLAGS_or_unset
+CPPFLAGS=$CPPFLAGS_or_unset
+MPN_PATH=$MPN_PATH
+GMP:
+abilist=$abilist
+cclist=$cclist
+EOF
+
+
+test_CFLAGS=${CFLAGS+set}
+test_CPPFLAGS=${CPPFLAGS+set}
+
+for abi in $abilist; do
+ abi_last="$abi"
+done
+
+# If the user specifies an ABI then it must be in $abilist, after that
+# $abilist is restricted to just that choice.
+#
+if test -n "$ABI"; then
+ found=no
+ for abi in $abilist; do
+ if test $abi = "$ABI"; then found=yes; break; fi
+ done
+ if test $found = no; then
+ as_fn_error $? "ABI=$ABI is not among the following valid choices: $abilist" "$LINENO" 5
+ fi
+ abilist="$ABI"
+fi
+
+found_compiler=no
+
+for abi in $abilist; do
+
+ echo "checking ABI=$abi"
+
+ # Suppose abilist="64 32", then for abi=64, will have abi1="_64" and
+ # abi2="_64". For abi=32, will have abi1="_32" and abi2="". This is how
+ # $gcc_cflags becomes a fallback for $gcc_32_cflags (the last in the
+ # abilist), but there's no fallback for $gcc_64_cflags.
+ #
+ abi1=`echo _$abi | sed 's/[.]//g'`
+ if test $abi = $abi_last; then abi2=; else abi2="$abi1"; fi
+
+ # Compiler choices under this ABI
+ eval cclist_chosen=\"\$cclist$abi1\"
+ test -n "$cclist_chosen" || eval cclist_chosen=\"\$cclist$abi2\"
+
+ # If there's a user specified $CC then don't use a list for
+ # $cclist_chosen, just a single value for $ccbase.
+ #
+ if test -n "$CC"; then
+
+ # The first word of $CC, stripped of any directory. For instance
+ # CC="/usr/local/bin/gcc -pipe" will give "gcc".
+ #
+ for ccbase in $CC; do break; done
+ ccbase=`echo $ccbase | sed 's:.*/::'`
+
+ # If this $ccbase is in $cclist_chosen then it's a compiler we know and
+ # we can do flags defaulting with it. If not, then $cclist_chosen is
+ # set to "unrecognised" so no default flags are used.
+ #
+ # "unrecognised" is used to avoid bad effects with eval if $ccbase has
+ # non-symbol characters. For instance ccbase=my+cc would end up with
+ # something like cflags="$my+cc_cflags" which would give
+ # cflags="+cc_cflags" rather than the intended empty string for an
+ # unknown compiler.
+ #
+ found=unrecognised
+ for i in $cclist_chosen; do
+ if test "$ccbase" = $i; then
+ found=$ccbase
+ break
+ fi
+ done
+ cclist_chosen=$found
+ fi
+
+ for ccbase in $cclist_chosen; do
+
+ # When cross compiling, look for a compiler with the $host_alias as a
+ # prefix, the same way that AC_CHECK_TOOL does. But don't do this to a
+ # user-selected $CC.
+ #
+ # $cross_compiling will be yes/no/maybe at this point. Do the host
+ # prefixing for "maybe" as well as "yes".
+ #
+ if test "$cross_compiling" != no && test -z "$CC"; then
+ cross_compiling_prefix="${host_alias}-"
+ fi
+
+ for ccprefix in $cross_compiling_prefix ""; do
+
+ cc="$CC"
+ test -n "$cc" || cc="$ccprefix$ccbase"
+
+ # If the compiler is gcc but installed under another name, then change
+ # $ccbase so as to use the flags we know for gcc. This helps for
+ # instance when specifying CC=gcc272 on Debian GNU/Linux, or the
+ # native cc which is really gcc on NeXT or MacOS-X.
+ #
+ # FIXME: There's a slight misfeature here. If cc is actually gcc but
+ # gcc is not a known compiler under this $abi then we'll end up
+ # testing it with no flags and it'll work, but chances are it won't be
+ # in the right mode for the ABI we desire. Let's quietly hope this
+ # doesn't happen.
+ #
+ if test $ccbase != gcc; then
+ cat >conftest.c <<EOF
+#if ! defined (__GNUC__) || defined (__INTEL_COMPILER)
+ choke me
+#endif
+EOF
+gmp_compile="$cc -c conftest.c >&5"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ rm -f conftest*
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $cc is gcc" >&5
+$as_echo_n "checking whether $cc is gcc... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ccbase=gcc
+else
+ rm -f conftest*
+ :
+fi
+
+ fi
+
+ # Similarly if the compiler is IBM xlc but invoked as cc or whatever
+ # then change $ccbase and make the default xlc flags available.
+ if test $ccbase != xlc; then
+ gmp_command="$cc 2>&1 | grep xlc >/dev/null"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_command\""; } >&5
+ (eval $gmp_command) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $cc is xlc" >&5
+$as_echo_n "checking whether $cc is xlc... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ccbase=xlc
+else
+ :
+fi
+
+ fi
+
+ # acc was Sun's first unbundled compiler back in the SunOS days, or
+ # something like that, but today its man page says it's not meant to
+ # be used directly (instead via /usr/ucb/cc). The options are pretty
+ # much the same as the main SunPRO cc, so share those configs.
+ #
+ case $host in
+ *sparc*-*-solaris* | *sparc*-*-sunos*)
+ if test "$ccbase" = acc; then ccbase=cc; fi ;;
+ esac
+
+ for tmp_cflags_maybe in yes no; do
+ eval cflags=\"\$${ccbase}${abi1}_cflags\"
+ test -n "$cflags" || eval cflags=\"\$${ccbase}${abi2}_cflags\"
+
+ if test "$tmp_cflags_maybe" = yes; then
+ # don't try cflags_maybe when the user set CFLAGS
+ if test "$test_CFLAGS" = set; then continue; fi
+ eval cflags_maybe=\"\$${ccbase}${abi1}_cflags_maybe\"
+ test -n "$cflags_maybe" || eval cflags_maybe=\"\$${ccbase}${abi2}_cflags_maybe\"
+ # don't try cflags_maybe if there's nothing set
+ if test -z "$cflags_maybe"; then continue; fi
+ cflags="$cflags_maybe $cflags"
+ fi
+
+ # Any user CFLAGS, even an empty string, takes precedence
+ if test "$test_CFLAGS" = set; then cflags=$CFLAGS; fi
+
+ # Any user CPPFLAGS, even an empty string, takes precedence
+ eval cppflags=\"\$${ccbase}${abi1}_cppflags\"
+ test -n "$cppflags" || eval cppflags=\"\$${ccbase}${abi2}_cppflags\"
+ if test "$test_CPPFLAGS" = set; then cppflags=$CPPFLAGS; fi
+
+ # --enable-profiling adds -p/-pg even to user-specified CFLAGS.
+ # This is convenient, but it's perhaps a bit naughty to modify user
+ # CFLAGS.
+ case "$enable_profiling" in
+ prof) cflags="$cflags -p" ;;
+ gprof) cflags="$cflags -pg" ;;
+ instrument) cflags="$cflags -finstrument-functions" ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler $cc $cflags $cppflags" >&5
+$as_echo_n "checking compiler $cc $cflags $cppflags... " >&6; }
+gmp_prog_cc_works=yes
+
+# first see a simple "main()" works, then go on to other checks
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+
+int main () { return 0; }
+EOF
+ echo "Test compile: " >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal error from gcc 2.95.2 -mpowerpc64
+ (without -maix64), hence detecting an unusable compiler */
+void *g() { return (void *) 0; }
+void *f() { return g(); }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: function pointer return" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, function pointer return"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, function pointer return, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an invalid instruction syntax from i386 gcc
+ -march=pentiumpro on Solaris 2.8. The native sun assembler
+ requires a non-standard syntax for cmov which gcc (as of 2.95.2 at
+ least) doesn't know. */
+int n;
+int cmov () { return (n >= 0 ? n : 0); }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: cmov instruction" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, cmov instruction"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, cmov instruction, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes a linker invocation problem with gcc 3.0.3
+ on AIX 4.3 under "-maix64 -mpowerpc64 -mcpu=630". The -mcpu=630
+ option causes gcc to incorrectly select the 32-bit libgcc.a, not
+ the 64-bit one, and consequently it misses out on the __fixunsdfdi
+ helper (double -> uint64 conversion). */
+double d;
+unsigned long gcc303 () { return (unsigned long) d; }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: double -> ulong conversion" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, double -> ulong conversion"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, double -> ulong conversion, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an error from hppa gcc 2.95 under -mpa-risc-2-0 if
+ the assembler doesn't know hppa 2.0 instructions. fneg is a 2.0
+ instruction, and a negation like this comes out using it. */
+double fneg_data;
+unsigned long fneg () { return -fneg_data; }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: double negation" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, double negation"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, double negation, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following makes gcc 3.3 -march=pentium4 generate an SSE2 xmm insn
+ (cvtsd2ss) which will provoke an error if the assembler doesn't recognise
+ those instructions. Not sure how much of the gmp code will come out
+ wanting sse2, but it's easiest to reject an option we know is bad. */
+double ftod_data;
+float ftod () { return (float) ftod_data; }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: double -> float conversion" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, double -> float conversion"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, double -> float conversion, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal compiler error from gcc version
+ "2.9-gnupro-99r1" under "-O2 -mcpu=ev6", apparently relating to char
+ values being spilled into floating point registers. The problem doesn't
+ show up all the time, but has occurred enough in GMP for us to reject
+ this compiler+flags. */
+#include <string.h> /* for memcpy */
+struct try_t
+{
+ char dst[2];
+ char size;
+ long d0, d1, d2, d3, d4, d5, d6;
+ char overlap;
+};
+struct try_t param[6];
+int
+param_init ()
+{
+ struct try_t *p;
+ memcpy (p, &param[ 2 ], sizeof (*p));
+ memcpy (p, &param[ 2 ], sizeof (*p));
+ p->size = 2;
+ memcpy (p, &param[ 1 ], sizeof (*p));
+ p->dst[0] = 1;
+ p->overlap = 2;
+ memcpy (p, &param[ 3 ], sizeof (*p));
+ p->dst[0] = 1;
+ p->overlap = 8;
+ memcpy (p, &param[ 4 ], sizeof (*p));
+ memcpy (p, &param[ 4 ], sizeof (*p));
+ p->overlap = 8;
+ memcpy (p, &param[ 5 ], sizeof (*p));
+ memcpy (p, &param[ 5 ], sizeof (*p));
+ memcpy (p, &param[ 5 ], sizeof (*p));
+ return 0;
+}
+
+int main () { return 0; }
+EOF
+ echo "Test compile: gnupro alpha ev6 char spilling" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, gnupro alpha ev6 char spilling"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, gnupro alpha ev6 char spilling, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+# __builtin_alloca is not available everywhere, check it exists before
+# seeing that it works
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+int k; int foo () { __builtin_alloca (k); }
+EOF
+ echo "Test compile: __builtin_alloca availability" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+ if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal compiler error from Itanium HP-UX cc
+ under +O2 or higher. We use this sort of code in mpn/generic/mul_fft.c. */
+int k;
+int foo ()
+{
+ int i, **a;
+ a = __builtin_alloca (k);
+ for (i = 0; i <= k; i++)
+ a[i] = __builtin_alloca (1 << i);
+}
+
+int main () { return 0; }
+EOF
+ echo "Test compile: alloca array" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, alloca array"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, alloca array, program does not run"
+ ;;
+ esac
+fi
+
+
+
+ ;;
+ no)
+
+ ;;
+ norun)
+
+ ;;
+ esac
+fi
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal error from the assembler on
+ power2-ibm-aix4.3.1.0. gcc -mrios2 compiles to nabs+fcirz, and this
+ results in "Internal error related to the source program domain".
+
+ For reference it seems to be the combination of nabs+fcirz which is bad,
+ not either alone. This sort of thing occurs in mpz/get_str.c with the
+ way double chars_per_bit_exactly is applied in MPN_SIZEINBASE. Perhaps
+ if that code changes to a scaled-integer style then we won't need this
+ test. */
+
+double fp[1];
+int x;
+int f ()
+{
+ int a;
+ a = (x >= 0 ? x : -x);
+ return a * fp[0];
+}
+
+int main () { return 0; }
+EOF
+ echo "Test compile: abs int -> double conversion" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, abs int -> double conversion"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, abs int -> double conversion, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes a segfault in the compiler on powerpc-apple-darwin.
+ Extracted from tests/mpn/t-iord_u.c. Causes Apple's gcc 3.3 build 1640 and
+ 1666 to segfault with e.g., -O2 -mpowerpc64. */
+
+#if defined (__GNUC__) && ! defined (__cplusplus)
+typedef unsigned long long t1;typedef t1*t2;
+static __inline__ t1 e(t2 rp,t2 up,int n,t1 v0)
+{t1 c,x,r;int i;if(v0){c=1;for(i=1;i<n;i++){x=up[i];r=x+1;rp[i]=r;}}return c;}
+f(){static const struct{t1 n;t1 src[9];t1 want[9];}d[]={{1,{0},{1}},};t1 got[9];int i;
+for(i=0;i<1;i++){if(e(got,got,9,d[i].n)==0)h();g(i,d[i].src,d[i].n,got,d[i].want,9);if(d[i].n)h();}}
+h(){}g(){}
+#else
+int dummy;
+#endif
+
+int main () { return 0; }
+EOF
+ echo "Test compile: long long reliability test 1" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, long long reliability test 1"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, long long reliability test 1, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal compiler error on powerpc-apple-darwin.
+ Extracted from mpz/cfdiv_q_2exp.c. Causes Apple's gcc 3.3 build 1640 and
+ 1666 to get an ICE with -O1 -mpowerpc64. */
+
+#if defined (__GNUC__) && ! defined (__cplusplus)
+f(int u){int i;long long x;x=u?~0:0;if(x)for(i=0;i<9;i++);x&=g();if(x)g();}
+g(){}
+#else
+int dummy;
+#endif
+
+int main () { return 0; }
+EOF
+ echo "Test compile: long long reliability test 2" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, long long reliability test 2"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, long long reliability test 2, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following is mis-compiled by HP ia-64 cc version
+ cc: HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]
+ under "cc +O3", both in +DD32 and +DD64 modes. The mpn_lshift_com gets
+ inlined and its return value somehow botched to be 0 instead of 1. This
+ arises in the real mpn_lshift_com in mul_fft.c. A lower optimization
+ level, like +O2 seems ok. This code needs to be run to show the problem,
+ but that's fine, the offending cc is a native-only compiler so we don't
+ have to worry about cross compiling. */
+
+#if ! defined (__cplusplus)
+unsigned long
+lshift_com (rp, up, n, cnt)
+ unsigned long *rp;
+ unsigned long *up;
+ long n;
+ unsigned cnt;
+{
+ unsigned long retval, high_limb, low_limb;
+ unsigned tnc;
+ long i;
+ tnc = 8 * sizeof (unsigned long) - cnt;
+ low_limb = *up++;
+ retval = low_limb >> tnc;
+ high_limb = low_limb << cnt;
+ for (i = n - 1; i != 0; i--)
+ {
+ low_limb = *up++;
+ *rp++ = ~(high_limb | (low_limb >> tnc));
+ high_limb = low_limb << cnt;
+ }
+ return retval;
+}
+int
+main ()
+{
+ unsigned long cy, rp[2], up[2];
+ up[0] = ~ 0L;
+ up[1] = 0;
+ cy = lshift_com (rp, up, 2L, 1);
+ if (cy != 1L)
+ return 1;
+ return 0;
+}
+#else
+int
+main ()
+{
+ return 0;
+}
+#endif
+
+EOF
+ echo "Test compile: mpn_lshift_com optimization" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, mpn_lshift_com optimization"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, mpn_lshift_com optimization, program does not run"
+ ;;
+ esac
+fi
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following is mis-compiled by Intel ia-64 icc version 1.8 under
+ "icc -O3", After several calls, the function writes partial garbage to
+ the result vector. Perhaps relates to the chk.a.nc insn. This code needs
+ to be run to show the problem, but that's fine, the offending cc is a
+ native-only compiler so we don't have to worry about cross compiling. */
+
+#if ! defined (__cplusplus)
+#include <stdlib.h>
+void
+lshift_com (rp, up, n, cnt)
+ unsigned long *rp;
+ unsigned long *up;
+ long n;
+ unsigned cnt;
+{
+ unsigned long high_limb, low_limb;
+ unsigned tnc;
+ long i;
+ up += n;
+ rp += n;
+ tnc = 8 * sizeof (unsigned long) - cnt;
+ low_limb = *--up;
+ high_limb = low_limb << cnt;
+ for (i = n - 1; i != 0; i--)
+ {
+ low_limb = *--up;
+ *--rp = ~(high_limb | (low_limb >> tnc));
+ high_limb = low_limb << cnt;
+ }
+ *--rp = ~high_limb;
+}
+int
+main ()
+{
+ unsigned long *r, *r2;
+ unsigned long a[88 + 1];
+ long i;
+ for (i = 0; i < 88 + 1; i++)
+ a[i] = ~0L;
+ r = malloc (10000 * sizeof (unsigned long));
+ r2 = r;
+ for (i = 0; i < 528; i += 22)
+ {
+ lshift_com (r2, a,
+ i / (8 * sizeof (unsigned long)) + 1,
+ i % (8 * sizeof (unsigned long)));
+ r2 += 88 + 1;
+ }
+ if (r[2048] != 0 || r[2049] != 0 || r[2050] != 0 || r[2051] != 0 ||
+ r[2052] != 0 || r[2053] != 0 || r[2054] != 0)
+ abort ();
+ return 0;
+}
+#else
+int
+main ()
+{
+ return 0;
+}
+#endif
+
+EOF
+ echo "Test compile: mpn_lshift_com optimization 2" >&5
+ gmp_compile="$cc $cflags $cppflags conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, mpn_lshift_com optimization 2"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, mpn_lshift_com optimization 2, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+# A certain _GLOBAL_OFFSET_TABLE_ problem in past versions of gas, tickled
+# by recent versions of gcc.
+#
+if test "$gmp_prog_cc_works" = yes; then
+ case $host in
+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-*)
+ # this problem only arises in PIC code, so don't need to test when
+ # --disable-shared. We don't necessarily have $enable_shared set to
+ # yes at this point, it will still be unset for the default (which is
+ # yes); hence the use of "!= no".
+ if test "$enable_shared" != no; then
+ echo "Testing gcc GOT with eax emitted" >&5
+cat >conftest.c <<\EOF
+int foo;
+int bar () { return foo; }
+EOF
+tmp_got_emitted=no
+gmp_compile="$cc $cflags $cppflags -fPIC -S conftest.c >&5 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if grep "addl.*_GLOBAL_OFFSET_TABLE_.*eax" conftest.s >/dev/null; then
+ tmp_got_emitted=yes
+ fi
+fi
+rm -f conftest.*
+echo "Result: $tmp_got_emitted" >&5
+if test "$tmp_got_emitted" = yes; then
+ echo "Testing gas GOT with eax good" >&5
+cat >conftest.awk <<\EOF
+BEGIN {
+ want[0] = "001"
+ want[1] = "043"
+ want[2] = "105"
+ want[3] = "147"
+ want[4] = "211"
+ want[5] = "253"
+ want[6] = "315"
+ want[7] = "357"
+
+ want[8] = "005"
+ want[9] = "002"
+ want[10] = "000"
+ want[11] = "000"
+ want[12] = "000"
+
+ want[13] = "376"
+ want[14] = "334"
+ want[15] = "272"
+ want[16] = "230"
+ want[17] = "166"
+ want[18] = "124"
+ want[19] = "062"
+ want[20] = "020"
+
+ result = "yes"
+}
+{
+ for (f = 2; f <= NF; f++)
+ {
+ for (i = 0; i < 20; i++)
+ got[i] = got[i+1];
+ got[20] = $f;
+
+ found = 1
+ for (i = 0; i < 21; i++)
+ if (got[i] != want[i])
+ {
+ found = 0
+ break
+ }
+ if (found)
+ {
+ result = "no"
+ exit
+ }
+ }
+}
+END {
+ print result
+}
+EOF
+cat >conftest.s <<\EOF
+ .text
+ .byte 1, 35, 69, 103, 137, 171, 205, 239
+ addl $_GLOBAL_OFFSET_TABLE_, %eax
+ .byte 254, 220, 186, 152, 118, 84, 50, 16
+EOF
+tmp_got_good=yes
+gmp_compile="$cc $cflags $cppflags -fPIC -o conftest.o -c conftest.s >&5 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ tmp_got_good=`od -b conftest.o | $AWK -f conftest.awk`
+fi
+rm -f conftest.*
+echo "Result: $tmp_got_good" >&5
+if test "$tmp_got_good" = no; then
+ gmp_prog_cc_works="no, bad gas GOT with eax"
+else
+ :
+fi
+
+else
+ :
+fi
+
+ fi
+ ;;
+ esac
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_prog_cc_works" >&5
+$as_echo "$gmp_prog_cc_works" >&6; }
+case $gmp_prog_cc_works in
+ yes)
+
+ ;;
+ *)
+ continue
+ ;;
+esac
+
+
+ # If we're supposed to be using a "long long" for a limb, check that
+ # it works.
+ eval limb_chosen=\"\$limb$abi1\"
+ test -n "$limb_chosen" || eval limb_chosen=\"\$limb$abi2\"
+ if test "$limb_chosen" = longlong; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler $cc $cflags $cppflags has long long" >&5
+$as_echo_n "checking compiler $cc $cflags $cppflags has long long... " >&6; }
+cat >conftest.c <<EOF
+long long foo;
+long long bar () { return foo; }
+int main () { return 0; }
+EOF
+gmp_prog_cc_works=no
+gmp_compile="$cc $cflags $cppflags -c conftest.c >&5"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ gmp_prog_cc_works=yes
+else
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_prog_cc_works" >&5
+$as_echo "$gmp_prog_cc_works" >&6; }
+if test $gmp_prog_cc_works = yes; then
+ :
+else
+ continue
+fi
+
+ fi
+
+ # The tests to perform on this $cc, if any
+ eval testlist=\"\$${ccbase}${abi1}_testlist\"
+ test -n "$testlist" || eval testlist=\"\$${ccbase}${abi2}_testlist\"
+ test -n "$testlist" || eval testlist=\"\$any${abi1}_testlist\"
+ test -n "$testlist" || eval testlist=\"\$any${abi2}_testlist\"
+
+ testlist_pass=yes
+ for tst in $testlist; do
+ case $tst in
+ hpc-hppa-2-0) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether HP compiler $cc is good for 64-bits" >&5
+$as_echo_n "checking whether HP compiler $cc is good for 64-bits... " >&6; }
+# Bad compiler output:
+# ccom: HP92453-01 G.10.32.05 HP C Compiler
+# Good compiler output:
+# ccom: HP92453-01 A.10.32.30 HP C Compiler
+# Let A.10.32.30 or higher be ok.
+echo >conftest.c
+gmp_tmp_vs=`$cc -V -c -o conftest.$OBJEXT conftest.c 2>&1 | grep "^ccom:"`
+echo "Version string: $gmp_tmp_vs" >&5
+rm conftest*
+gmp_tmp_v1=`echo $gmp_tmp_vs | sed 's/.* .\.\([0-9]*\).*/\1/'`
+gmp_tmp_v2=`echo $gmp_tmp_vs | sed 's/.* .\..*\.\(.*\)\..* HP C.*/\1/'`
+gmp_tmp_v3=`echo $gmp_tmp_vs | sed 's/.* .\..*\..*\.\(.*\) HP C.*/\1/'`
+echo "Version number: $gmp_tmp_v1.$gmp_tmp_v2.$gmp_tmp_v3" >&5
+if test -z "$gmp_tmp_v1"; then
+ gmp_hpc_64bit=not-applicable
+else
+ gmp_compare_ge=no
+if test -n "$gmp_tmp_v1"; then
+ if test "$gmp_tmp_v1" -gt 10; then
+ gmp_compare_ge=yes
+ else
+ if test "$gmp_tmp_v1" -eq 10; then
+ if test -n "$gmp_tmp_v2"; then
+ if test "$gmp_tmp_v2" -gt 32; then
+ gmp_compare_ge=yes
+ else
+ if test "$gmp_tmp_v2" -eq 32; then
+ if test -n "$gmp_tmp_v3" && test "$gmp_tmp_v3" -ge 30; then
+ gmp_compare_ge=yes
+fi
+
+ fi
+ fi
+fi
+
+ fi
+ fi
+fi
+
+
+ gmp_hpc_64bit=$gmp_compare_ge
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_hpc_64bit" >&5
+$as_echo "$gmp_hpc_64bit" >&6; }
+if test $gmp_hpc_64bit = yes; then
+ :
+else
+ testlist_pass=no
+fi
+ ;;
+ gcc-arm-umodsi) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ARM gcc unsigned division works" >&5
+$as_echo_n "checking whether ARM gcc unsigned division works... " >&6; }
+tmp_version=`$cc --version`
+echo "$tmp_version" >&5
+case $tmp_version in
+ 2.95 | 2.95.[123])
+ testlist_pass=no
+ gmp_gcc_arm_umodsi_result="no, gcc 2.95.[0123]" ;;
+ *)
+ :
+ gmp_gcc_arm_umodsi_result=yes ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_gcc_arm_umodsi_result" >&5
+$as_echo "$gmp_gcc_arm_umodsi_result" >&6; }
+ ;;
+ gcc-mips-o32) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc supports o32" >&5
+$as_echo_n "checking whether gcc supports o32... " >&6; }
+echo 'int x;' >conftest.c
+echo "$cc -mabi=32 -c conftest.c" >&5
+if $cc -mabi=32 -c conftest.c >conftest.out 2>&1; then
+ result=yes
+else
+ cat conftest.out >&5
+ if grep "cc1: Invalid option \`abi=32'" conftest.out >/dev/null; then
+ result=yes
+ else
+ result=no
+ fi
+fi
+rm -f conftest.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5
+$as_echo "$result" >&6; }
+if test $result = yes; then
+ :
+else
+ testlist_pass=no
+fi
+ ;;
+ hppa-level-2.0) { $as_echo "$as_me:${as_lineno-$LINENO}: checking $cc $cflags assembler knows hppa 2.0" >&5
+$as_echo_n "checking $cc $cflags assembler knows hppa 2.0... " >&6; }
+result=no
+cat >conftest.s <<EOF
+ .level 2.0
+EOF
+gmp_compile="$cc $cflags -c conftest.s >&5 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ result=yes
+else
+ echo "failed program was" >&5
+ cat conftest.s >&5
+fi
+rm -f conftest*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5
+$as_echo "$result" >&6; }
+if test "$result" = yes; then
+ :
+else
+ testlist_pass=no
+fi
+ ;;
+ sizeof*) echo "configure: testlist $tst" >&5
+gmp_sizeof_type=`echo "$tst" | sed 's/sizeof-\([a-z]*\).*/\1/'`
+gmp_sizeof_want=`echo "$tst" | sed 's/sizeof-[a-z]*-\([0-9]*\).*/\1/'`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler $cc $cflags has sizeof($gmp_sizeof_type)==$gmp_sizeof_want" >&5
+$as_echo_n "checking compiler $cc $cflags has sizeof($gmp_sizeof_type)==$gmp_sizeof_want... " >&6; }
+cat >conftest.c <<EOF
+int
+main ()
+{
+ static int test_array [1 - 2 * (long) (sizeof ($gmp_sizeof_type) != $gmp_sizeof_want)];
+ test_array[0] = 0;
+ return 0;
+}
+EOF
+gmp_c_testlist_sizeof=no
+gmp_compile="$cc $cflags -c conftest.c >&5"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ gmp_c_testlist_sizeof=yes
+fi
+rm -f conftest*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_c_testlist_sizeof" >&5
+$as_echo "$gmp_c_testlist_sizeof" >&6; }
+if test $gmp_c_testlist_sizeof = yes; then
+ :
+else
+ testlist_pass=no
+fi
+ ;;
+ esac
+ if test $testlist_pass = no; then break; fi
+ done
+
+ if test $testlist_pass = yes; then
+ found_compiler=yes
+ break
+ fi
+ done
+
+ if test $found_compiler = yes; then break; fi
+ done
+
+ if test $found_compiler = yes; then break; fi
+ done
+
+ if test $found_compiler = yes; then break; fi
+done
+
+
+# If we recognised the CPU, as indicated by $path being set, then insist
+# that we have a working compiler, either from our $cclist choices or from
+# $CC. We can't let AC_PROG_CC look around for a compiler because it might
+# find one that we've rejected (for not supporting the modes our asm code
+# demands, etc).
+#
+# If we didn't recognise the CPU (and this includes host_cpu=none), then
+# fall through and let AC_PROG_CC look around for a compiler too. This is
+# mostly in the interests of following a standard autoconf setup, after all
+# we've already tested cc and gcc adequately (hopefully). As of autoconf
+# 2.50 the only thing AC_PROG_CC really adds is a check for "cl" (Microsoft
+# C on MS-DOS systems).
+#
+if test $found_compiler = no && test -n "$path"; then
+ as_fn_error $? "could not find a working compiler, see config.log for details" "$LINENO" 5
+fi
+
+case $host in
+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-* | athlon64-*-* | k8-*-* | k10-*-* | bobcat-*-* | jaguar-*-* | bulldozer-*-* | piledriver-*-* | steamroller-*-* | excavator-*-* | pentium4-*-* | atom-*-* | core2-*-* | corei*-*-* | x86_64-*-* | nano-*-*)
+ # If the user asked for a fat build, override the path and flags set above
+ if test $enable_fat = yes; then
+ gcc_cflags_cpu=""
+ gcc_cflags_arch=""
+
+ fat_functions="add_n addmul_1 bdiv_dbm1c com cnd_add_n cnd_sub_n
+ copyd copyi dive_1 divrem_1
+ gcd_1 lshift lshiftc mod_1 mod_1_1 mod_1_1_cps mod_1_2
+ mod_1_2_cps mod_1_4 mod_1_4_cps mod_34lsub1 mode1o mul_1
+ mul_basecase mullo_basecase pre_divrem_1 pre_mod_1 redc_1
+ redc_2 rshift sqr_basecase sub_n submul_1"
+
+ if test "$abi" = 32; then
+ extra_functions="$extra_functions fat fat_entry"
+ path="x86/fat x86"
+ fat_path="x86 x86/fat x86/i486
+ x86/k6 x86/k6/mmx x86/k6/k62mmx
+ x86/k7 x86/k7/mmx
+ x86/k8 x86/k10 x86/bobcat
+ x86/pentium x86/pentium/mmx
+ x86/p6 x86/p6/mmx x86/p6/p3mmx x86/p6/sse2
+ x86/pentium4 x86/pentium4/mmx x86/pentium4/sse2
+ x86/core2 x86/coreinhm x86/coreisbr
+ x86/atom x86/atom/mmx x86/atom/sse2 x86/nano"
+ fi
+
+ if test "$abi" = 64; then
+ gcc_64_cflags=""
+ extra_functions_64="$extra_functions_64 fat fat_entry"
+ path_64="x86_64/fat x86_64"
+ fat_path="x86_64 x86_64/fat
+ x86_64/k8 x86_64/k10 x86_64/bd1 x86_64/bobcat
+ x86_64/pentium4 x86_64/core2 x86_64/coreinhm x86_64/coreisbr
+ x86_64/coreihwl x86_64/atom x86_64/nano"
+ fat_functions="$fat_functions addmul_2 addlsh1_n addlsh2_n sublsh1_n"
+ fi
+
+ fat_thresholds="MUL_TOOM22_THRESHOLD MUL_TOOM33_THRESHOLD
+ SQR_TOOM2_THRESHOLD SQR_TOOM3_THRESHOLD
+ BMOD_1_TO_MOD_1_THRESHOLD"
+ fi
+ ;;
+esac
+
+
+if test $found_compiler = yes; then
+
+ # If we're creating CFLAGS, then look for optional additions. If the user
+ # set CFLAGS then leave it alone.
+ #
+ if test "$test_CFLAGS" != set; then
+ eval optlist=\"\$${ccbase}${abi1}_cflags_optlist\"
+ test -n "$optlist" || eval optlist=\"\$${ccbase}${abi2}_cflags_optlist\"
+
+ for opt in $optlist; do
+ eval optflags=\"\$${ccbase}${abi1}_cflags_${opt}\"
+ test -n "$optflags" || eval optflags=\"\$${ccbase}${abi2}_cflags_${opt}\"
+ test -n "$optflags" || eval optflags=\"\$${ccbase}_cflags_${opt}\"
+
+ for flag in $optflags; do
+
+ # ~ represents a space in an option spec
+ flag=`echo "$flag" | tr '~' ' '`
+
+ case $flag in
+ -march=pentium4 | -march=k8)
+ # For -march settings which enable SSE2 we exclude certain bad
+ # gcc versions and we need an OS knowing how to save xmm regs.
+ #
+ # This is only for ABI=32, any 64-bit gcc is good and any OS
+ # knowing x86_64 will know xmm.
+ #
+ # -march=k8 was only introduced in gcc 3.3, so we shouldn't need
+ # the GMP_GCC_PENTIUM4_SSE2 check (for gcc 3.2 and prior). But
+ # it doesn't hurt to run it anyway, sharing code with the
+ # pentium4 case.
+ #
+ if test "$abi" = 32; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc is good for sse2" >&5
+$as_echo_n "checking whether gcc is good for sse2... " >&6; }
+case `$cc $cflags $cppflags -dumpversion` in
+ 3.[012] | 3.[012].*) result=no ;;
+ *) result=yes ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5
+$as_echo "$result" >&6; }
+if test "$result" = yes; then
+ :
+else
+ continue
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the operating system supports XMM registers" >&5
+$as_echo_n "checking whether the operating system supports XMM registers... " >&6; }
+if ${gmp_cv_os_x86_xmm+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$build" = "$host"; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.s <<EOF
+ .text
+main:
+_main:
+ .globl main
+ .globl _main
+ .byte 0x0f, 0x57, 0xc0
+ xorl %eax, %eax
+ ret
+EOF
+ gmp_compile="$cc $cflags $cppflags conftest.s -o conftest >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ gmp_cv_os_x86_xmm=yes
+ else
+ gmp_cv_os_x86_xmm=no
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Oops, cannot compile test program" >&5
+$as_echo "$as_me: WARNING: Oops, cannot compile test program" >&2;}
+ fi
+ rm -f conftest*
+fi
+
+if test -z "$gmp_cv_os_x86_xmm"; then
+ case $host_os in
+ freebsd[123] | freebsd[123].*)
+ gmp_cv_os_x86_xmm=no ;;
+ freebsd*)
+ gmp_cv_os_x86_xmm=yes ;;
+ *)
+ gmp_cv_os_x86_xmm=probably ;;
+ esac
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_os_x86_xmm" >&5
+$as_echo "$gmp_cv_os_x86_xmm" >&6; }
+
+if test "$gmp_cv_os_x86_xmm" = probably; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Not certain of OS support for xmm when cross compiling." >&5
+$as_echo "$as_me: WARNING: Not certain of OS support for xmm when cross compiling." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Will assume it's ok, expect a SIGILL if this is wrong." >&5
+$as_echo "$as_me: WARNING: Will assume it's ok, expect a SIGILL if this is wrong." >&2;}
+fi
+
+case $gmp_cv_os_x86_xmm in
+no)
+ continue
+ ;;
+*)
+
+ ;;
+esac
+
+ fi
+ ;;
+ -no-cpp-precomp)
+ # special check, avoiding a warning
+ if test "$ccbase" = gcc; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler $cc $cflags -no-cpp-precomp" >&5
+$as_echo_n "checking compiler $cc $cflags -no-cpp-precomp... " >&6; }
+ result=no
+ cat >conftest.c <<EOF
+int main () { return 0; }
+EOF
+ gmp_compile="$cc $cflags -no-cpp-precomp conftest.c >conftest.out 2>&1"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if grep "unrecognized option.*-no-cpp-precomp" conftest.out >/dev/null; then : ;
+ else
+ result=yes
+ fi
+ fi
+ cat conftest.out >&5
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5
+$as_echo "$result" >&6; }
+ if test "$result" = yes; then
+ cflags="$cflags $flag"
+ break
+ else
+ continue
+ fi
+fi
+
+ ;;
+ -Wa,-m*)
+ case $host in
+ alpha*-*-*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler $cc $cflags $flag" >&5
+$as_echo_n "checking assembler $cc $cflags $flag... " >&6; }
+result=no
+cat >conftest.c <<EOF
+int main () {}
+EOF
+gmp_compile="$cc $cflags $flag -c conftest.c >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if grep "Unknown CPU identifier" conftest.out >/dev/null; then : ;
+ else
+ result=yes
+ fi
+fi
+cat conftest.out >&5
+rm -f conftest*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5
+$as_echo "$result" >&6; }
+if test "$result" = yes; then
+ :
+else
+ continue
+fi
+
+ ;;
+ esac
+ ;;
+ -Wa,-oldas)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $cc $cflags $cppflags -Wa,-oldas" >&5
+$as_echo_n "checking for $cc $cflags $cppflags -Wa,-oldas... " >&6; }
+result=no
+cat >conftest.c <<EOF
+EOF
+echo "with empty conftest.c" >&5
+gmp_compile="$cc $cflags $cppflags -c conftest.c >&5 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then : ;
+else
+ # empty fails
+ gmp_compile="$cc $cflags $cppflags -Wa,-oldas -c conftest.c >&5 2>&1"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # but with -Wa,-oldas it works
+ result=yes
+ fi
+fi
+rm -f conftest*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5
+$as_echo "$result" >&6; }
+if test "$result" = yes; then
+ cflags="$cflags $flag"
+ break
+else
+ continue
+fi
+
+ ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler $cc $cflags $cppflags $flag" >&5
+$as_echo_n "checking compiler $cc $cflags $cppflags $flag... " >&6; }
+gmp_prog_cc_works=yes
+
+# first see a simple "main()" works, then go on to other checks
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+
+int main () { return 0; }
+EOF
+ echo "Test compile: " >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal error from gcc 2.95.2 -mpowerpc64
+ (without -maix64), hence detecting an unusable compiler */
+void *g() { return (void *) 0; }
+void *f() { return g(); }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: function pointer return" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, function pointer return"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, function pointer return, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an invalid instruction syntax from i386 gcc
+ -march=pentiumpro on Solaris 2.8. The native sun assembler
+ requires a non-standard syntax for cmov which gcc (as of 2.95.2 at
+ least) doesn't know. */
+int n;
+int cmov () { return (n >= 0 ? n : 0); }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: cmov instruction" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, cmov instruction"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, cmov instruction, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes a linker invocation problem with gcc 3.0.3
+ on AIX 4.3 under "-maix64 -mpowerpc64 -mcpu=630". The -mcpu=630
+ option causes gcc to incorrectly select the 32-bit libgcc.a, not
+ the 64-bit one, and consequently it misses out on the __fixunsdfdi
+ helper (double -> uint64 conversion). */
+double d;
+unsigned long gcc303 () { return (unsigned long) d; }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: double -> ulong conversion" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, double -> ulong conversion"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, double -> ulong conversion, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an error from hppa gcc 2.95 under -mpa-risc-2-0 if
+ the assembler doesn't know hppa 2.0 instructions. fneg is a 2.0
+ instruction, and a negation like this comes out using it. */
+double fneg_data;
+unsigned long fneg () { return -fneg_data; }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: double negation" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, double negation"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, double negation, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following makes gcc 3.3 -march=pentium4 generate an SSE2 xmm insn
+ (cvtsd2ss) which will provoke an error if the assembler doesn't recognise
+ those instructions. Not sure how much of the gmp code will come out
+ wanting sse2, but it's easiest to reject an option we know is bad. */
+double ftod_data;
+float ftod () { return (float) ftod_data; }
+
+int main () { return 0; }
+EOF
+ echo "Test compile: double -> float conversion" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, double -> float conversion"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, double -> float conversion, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal compiler error from gcc version
+ "2.9-gnupro-99r1" under "-O2 -mcpu=ev6", apparently relating to char
+ values being spilled into floating point registers. The problem doesn't
+ show up all the time, but has occurred enough in GMP for us to reject
+ this compiler+flags. */
+#include <string.h> /* for memcpy */
+struct try_t
+{
+ char dst[2];
+ char size;
+ long d0, d1, d2, d3, d4, d5, d6;
+ char overlap;
+};
+struct try_t param[6];
+int
+param_init ()
+{
+ struct try_t *p;
+ memcpy (p, &param[ 2 ], sizeof (*p));
+ memcpy (p, &param[ 2 ], sizeof (*p));
+ p->size = 2;
+ memcpy (p, &param[ 1 ], sizeof (*p));
+ p->dst[0] = 1;
+ p->overlap = 2;
+ memcpy (p, &param[ 3 ], sizeof (*p));
+ p->dst[0] = 1;
+ p->overlap = 8;
+ memcpy (p, &param[ 4 ], sizeof (*p));
+ memcpy (p, &param[ 4 ], sizeof (*p));
+ p->overlap = 8;
+ memcpy (p, &param[ 5 ], sizeof (*p));
+ memcpy (p, &param[ 5 ], sizeof (*p));
+ memcpy (p, &param[ 5 ], sizeof (*p));
+ return 0;
+}
+
+int main () { return 0; }
+EOF
+ echo "Test compile: gnupro alpha ev6 char spilling" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, gnupro alpha ev6 char spilling"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, gnupro alpha ev6 char spilling, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+# __builtin_alloca is not available everywhere, check it exists before
+# seeing that it works
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+int k; int foo () { __builtin_alloca (k); }
+EOF
+ echo "Test compile: __builtin_alloca availability" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+ if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal compiler error from Itanium HP-UX cc
+ under +O2 or higher. We use this sort of code in mpn/generic/mul_fft.c. */
+int k;
+int foo ()
+{
+ int i, **a;
+ a = __builtin_alloca (k);
+ for (i = 0; i <= k; i++)
+ a[i] = __builtin_alloca (1 << i);
+}
+
+int main () { return 0; }
+EOF
+ echo "Test compile: alloca array" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, alloca array"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, alloca array, program does not run"
+ ;;
+ esac
+fi
+
+
+
+ ;;
+ no)
+
+ ;;
+ norun)
+
+ ;;
+ esac
+fi
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal error from the assembler on
+ power2-ibm-aix4.3.1.0. gcc -mrios2 compiles to nabs+fcirz, and this
+ results in "Internal error related to the source program domain".
+
+ For reference it seems to be the combination of nabs+fcirz which is bad,
+ not either alone. This sort of thing occurs in mpz/get_str.c with the
+ way double chars_per_bit_exactly is applied in MPN_SIZEINBASE. Perhaps
+ if that code changes to a scaled-integer style then we won't need this
+ test. */
+
+double fp[1];
+int x;
+int f ()
+{
+ int a;
+ a = (x >= 0 ? x : -x);
+ return a * fp[0];
+}
+
+int main () { return 0; }
+EOF
+ echo "Test compile: abs int -> double conversion" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, abs int -> double conversion"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, abs int -> double conversion, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes a segfault in the compiler on powerpc-apple-darwin.
+ Extracted from tests/mpn/t-iord_u.c. Causes Apple's gcc 3.3 build 1640 and
+ 1666 to segfault with e.g., -O2 -mpowerpc64. */
+
+#if defined (__GNUC__) && ! defined (__cplusplus)
+typedef unsigned long long t1;typedef t1*t2;
+static __inline__ t1 e(t2 rp,t2 up,int n,t1 v0)
+{t1 c,x,r;int i;if(v0){c=1;for(i=1;i<n;i++){x=up[i];r=x+1;rp[i]=r;}}return c;}
+f(){static const struct{t1 n;t1 src[9];t1 want[9];}d[]={{1,{0},{1}},};t1 got[9];int i;
+for(i=0;i<1;i++){if(e(got,got,9,d[i].n)==0)h();g(i,d[i].src,d[i].n,got,d[i].want,9);if(d[i].n)h();}}
+h(){}g(){}
+#else
+int dummy;
+#endif
+
+int main () { return 0; }
+EOF
+ echo "Test compile: long long reliability test 1" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, long long reliability test 1"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, long long reliability test 1, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following provokes an internal compiler error on powerpc-apple-darwin.
+ Extracted from mpz/cfdiv_q_2exp.c. Causes Apple's gcc 3.3 build 1640 and
+ 1666 to get an ICE with -O1 -mpowerpc64. */
+
+#if defined (__GNUC__) && ! defined (__cplusplus)
+f(int u){int i;long long x;x=u?~0:0;if(x)for(i=0;i<9;i++);x&=g();if(x)g();}
+g(){}
+#else
+int dummy;
+#endif
+
+int main () { return 0; }
+EOF
+ echo "Test compile: long long reliability test 2" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, long long reliability test 2"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, long long reliability test 2, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following is mis-compiled by HP ia-64 cc version
+ cc: HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]
+ under "cc +O3", both in +DD32 and +DD64 modes. The mpn_lshift_com gets
+ inlined and its return value somehow botched to be 0 instead of 1. This
+ arises in the real mpn_lshift_com in mul_fft.c. A lower optimization
+ level, like +O2 seems ok. This code needs to be run to show the problem,
+ but that's fine, the offending cc is a native-only compiler so we don't
+ have to worry about cross compiling. */
+
+#if ! defined (__cplusplus)
+unsigned long
+lshift_com (rp, up, n, cnt)
+ unsigned long *rp;
+ unsigned long *up;
+ long n;
+ unsigned cnt;
+{
+ unsigned long retval, high_limb, low_limb;
+ unsigned tnc;
+ long i;
+ tnc = 8 * sizeof (unsigned long) - cnt;
+ low_limb = *up++;
+ retval = low_limb >> tnc;
+ high_limb = low_limb << cnt;
+ for (i = n - 1; i != 0; i--)
+ {
+ low_limb = *up++;
+ *rp++ = ~(high_limb | (low_limb >> tnc));
+ high_limb = low_limb << cnt;
+ }
+ return retval;
+}
+int
+main ()
+{
+ unsigned long cy, rp[2], up[2];
+ up[0] = ~ 0L;
+ up[1] = 0;
+ cy = lshift_com (rp, up, 2L, 1);
+ if (cy != 1L)
+ return 1;
+ return 0;
+}
+#else
+int
+main ()
+{
+ return 0;
+}
+#endif
+
+EOF
+ echo "Test compile: mpn_lshift_com optimization" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, mpn_lshift_com optimization"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, mpn_lshift_com optimization, program does not run"
+ ;;
+ esac
+fi
+
+
+
+if test "$gmp_prog_cc_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.c <<EOF
+/* The following is mis-compiled by Intel ia-64 icc version 1.8 under
+ "icc -O3", After several calls, the function writes partial garbage to
+ the result vector. Perhaps relates to the chk.a.nc insn. This code needs
+ to be run to show the problem, but that's fine, the offending cc is a
+ native-only compiler so we don't have to worry about cross compiling. */
+
+#if ! defined (__cplusplus)
+#include <stdlib.h>
+void
+lshift_com (rp, up, n, cnt)
+ unsigned long *rp;
+ unsigned long *up;
+ long n;
+ unsigned cnt;
+{
+ unsigned long high_limb, low_limb;
+ unsigned tnc;
+ long i;
+ up += n;
+ rp += n;
+ tnc = 8 * sizeof (unsigned long) - cnt;
+ low_limb = *--up;
+ high_limb = low_limb << cnt;
+ for (i = n - 1; i != 0; i--)
+ {
+ low_limb = *--up;
+ *--rp = ~(high_limb | (low_limb >> tnc));
+ high_limb = low_limb << cnt;
+ }
+ *--rp = ~high_limb;
+}
+int
+main ()
+{
+ unsigned long *r, *r2;
+ unsigned long a[88 + 1];
+ long i;
+ for (i = 0; i < 88 + 1; i++)
+ a[i] = ~0L;
+ r = malloc (10000 * sizeof (unsigned long));
+ r2 = r;
+ for (i = 0; i < 528; i += 22)
+ {
+ lshift_com (r2, a,
+ i / (8 * sizeof (unsigned long)) + 1,
+ i % (8 * sizeof (unsigned long)));
+ r2 += 88 + 1;
+ }
+ if (r[2048] != 0 || r[2049] != 0 || r[2050] != 0 || r[2051] != 0 ||
+ r[2052] != 0 || r[2053] != 0 || r[2054] != 0)
+ abort ();
+ return 0;
+}
+#else
+int
+main ()
+{
+ return 0;
+}
+#endif
+
+EOF
+ echo "Test compile: mpn_lshift_com optimization 2" >&5
+ gmp_compile="$cc $cflags $cppflags $flag conftest.c >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cc_works_part=yes
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ cc_works_part=norun
+ fi
+ fi
+ else
+ cc_works_part=no
+ fi
+ if test "$cc_works_part" != yes; then
+ echo "failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ case $cc_works_part in
+ yes)
+
+ ;;
+ no)
+ gmp_prog_cc_works="no, mpn_lshift_com optimization 2"
+ ;;
+ norun)
+ gmp_prog_cc_works="no, mpn_lshift_com optimization 2, program does not run"
+ ;;
+ esac
+fi
+
+
+
+
+# A certain _GLOBAL_OFFSET_TABLE_ problem in past versions of gas, tickled
+# by recent versions of gcc.
+#
+if test "$gmp_prog_cc_works" = yes; then
+ case $host in
+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-*)
+ # this problem only arises in PIC code, so don't need to test when
+ # --disable-shared. We don't necessarily have $enable_shared set to
+ # yes at this point, it will still be unset for the default (which is
+ # yes); hence the use of "!= no".
+ if test "$enable_shared" != no; then
+ echo "Testing gcc GOT with eax emitted" >&5
+cat >conftest.c <<\EOF
+int foo;
+int bar () { return foo; }
+EOF
+tmp_got_emitted=no
+gmp_compile="$cc $cflags $cppflags $flag -fPIC -S conftest.c >&5 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if grep "addl.*_GLOBAL_OFFSET_TABLE_.*eax" conftest.s >/dev/null; then
+ tmp_got_emitted=yes
+ fi
+fi
+rm -f conftest.*
+echo "Result: $tmp_got_emitted" >&5
+if test "$tmp_got_emitted" = yes; then
+ echo "Testing gas GOT with eax good" >&5
+cat >conftest.awk <<\EOF
+BEGIN {
+ want[0] = "001"
+ want[1] = "043"
+ want[2] = "105"
+ want[3] = "147"
+ want[4] = "211"
+ want[5] = "253"
+ want[6] = "315"
+ want[7] = "357"
+
+ want[8] = "005"
+ want[9] = "002"
+ want[10] = "000"
+ want[11] = "000"
+ want[12] = "000"
+
+ want[13] = "376"
+ want[14] = "334"
+ want[15] = "272"
+ want[16] = "230"
+ want[17] = "166"
+ want[18] = "124"
+ want[19] = "062"
+ want[20] = "020"
+
+ result = "yes"
+}
+{
+ for (f = 2; f <= NF; f++)
+ {
+ for (i = 0; i < 20; i++)
+ got[i] = got[i+1];
+ got[20] = $f;
+
+ found = 1
+ for (i = 0; i < 21; i++)
+ if (got[i] != want[i])
+ {
+ found = 0
+ break
+ }
+ if (found)
+ {
+ result = "no"
+ exit
+ }
+ }
+}
+END {
+ print result
+}
+EOF
+cat >conftest.s <<\EOF
+ .text
+ .byte 1, 35, 69, 103, 137, 171, 205, 239
+ addl $_GLOBAL_OFFSET_TABLE_, %eax
+ .byte 254, 220, 186, 152, 118, 84, 50, 16
+EOF
+tmp_got_good=yes
+gmp_compile="$cc $cflags $cppflags $flag -fPIC -o conftest.o -c conftest.s >&5 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ tmp_got_good=`od -b conftest.o | $AWK -f conftest.awk`
+fi
+rm -f conftest.*
+echo "Result: $tmp_got_good" >&5
+if test "$tmp_got_good" = no; then
+ gmp_prog_cc_works="no, bad gas GOT with eax"
+else
+ :
+fi
+
+else
+ :
+fi
+
+ fi
+ ;;
+ esac
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_prog_cc_works" >&5
+$as_echo "$gmp_prog_cc_works" >&6; }
+case $gmp_prog_cc_works in
+ yes)
+ cflags="$cflags $flag"
+ break
+ ;;
+ *)
+
+ ;;
+esac
+
+ done
+ done
+ fi
+
+ ABI="$abi"
+ CC="$cc"
+ CFLAGS="$cflags"
+ CPPFLAGS="$cppflags"
+ eval GMP_NONSTD_ABI=\"\$GMP_NONSTD_ABI_$ABI\"
+
+ # Could easily have this in config.h too, if desired.
+ ABI_nodots=`echo $ABI | sed 's/\./_/'`
+
+echo "define_not_for_expansion(\`HAVE_ABI_$ABI_nodots')" >> $gmp_tmpconfigm4p
+
+
+
+ # GMP_LDFLAGS substitution, selected according to ABI.
+ # These are needed on libgmp.la and libmp.la, but currently not on
+ # convenience libraries like tune/libspeed.la or mpz/libmpz.la.
+ #
+ eval GMP_LDFLAGS=\"\$${ccbase}${abi1}_ldflags\"
+ test -n "$GMP_LDFLAGS" || eval GMP_LDFLAGS=\"\$${ccbase}${abi1}_ldflags\"
+
+
+
+
+ # extra_functions, selected according to ABI
+ eval tmp=\"\$extra_functions$abi1\"
+ test -n "$tmp" || eval tmp=\"\$extra_functions$abi2\"
+ extra_functions="$tmp"
+
+
+ # Cycle counter, selected according to ABI.
+ #
+ eval tmp=\"\$SPEED_CYCLECOUNTER_OBJ$abi1\"
+ test -n "$tmp" || eval tmp=\"\$SPEED_CYCLECOUNTER_OBJ$abi2\"
+ SPEED_CYCLECOUNTER_OBJ="$tmp"
+ eval tmp=\"\$cyclecounter_size$abi1\"
+ test -n "$tmp" || eval tmp=\"\$cyclecounter_size$abi2\"
+ cyclecounter_size="$tmp"
+
+ if test -n "$SPEED_CYCLECOUNTER_OBJ"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SPEED_CYCLECOUNTER $cyclecounter_size
+_ACEOF
+
+ fi
+
+
+
+ # Calling conventions checking, selected according to ABI.
+ #
+ eval tmp=\"\$CALLING_CONVENTIONS_OBJS$abi1\"
+ test -n "$tmp" || eval tmp=\"\$CALLING_CONVENTIONS_OBJS$abi2\"
+ if test "$enable_assembly" = "yes"; then
+ CALLING_CONVENTIONS_OBJS="$tmp"
+ else
+ CALLING_CONVENTIONS_OBJS=""
+ fi
+
+ if test -n "$CALLING_CONVENTIONS_OBJS"; then
+
+$as_echo "#define HAVE_CALLING_CONVENTIONS 1" >>confdefs.h
+
+ fi
+
+
+fi
+
+
+# If the user gave an MPN_PATH, use that verbatim, otherwise choose
+# according to the ABI and add "generic".
+#
+if test -n "$MPN_PATH"; then
+ path="$MPN_PATH"
+else
+ eval tmp=\"\$path$abi1\"
+ test -n "$tmp" || eval tmp=\"\$path$abi2\"
+ path="$tmp generic"
+fi
+
+
+# Long long limb setup for gmp.h.
+case $limb_chosen in
+longlong) DEFN_LONG_LONG_LIMB="#define _LONG_LONG_LIMB 1" ;;
+*) DEFN_LONG_LONG_LIMB="/* #undef _LONG_LONG_LIMB */" ;;
+esac
+
+
+
+# The C compiler and preprocessor, put into ANSI mode if possible.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ case $ac_cv_prog_cc_stdc in #(
+ no) :
+ ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #(
+ *) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str;
+ int number;
+ float fnumber;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+}
+
+int
+main ()
+{
+
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c99"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+else
+ ac_cv_prog_cc_stdc=no
+fi
+
+fi
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5
+$as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; }
+ if ${ac_cv_prog_cc_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+
+ case $ac_cv_prog_cc_stdc in #(
+ no) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;; #(
+ '') :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;; #(
+ *) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5
+$as_echo "$ac_cv_prog_cc_stdc" >&6; } ;;
+esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# The C compiler on the build system, and associated tests.
+
+if test -n "$CC_FOR_BUILD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system compiler $CC_FOR_BUILD" >&5
+$as_echo_n "checking build system compiler $CC_FOR_BUILD... " >&6; }
+# remove anything that might look like compiler output to our "||" expression
+rm -f conftest* a.out b.out a.exe a_out.exe
+cat >conftest.c <<EOF
+int
+main ()
+{
+ exit(0);
+}
+EOF
+gmp_compile="$CC_FOR_BUILD conftest.c"
+cc_for_build_works=no
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if (./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest) >&5 2>&1; then
+ cc_for_build_works=yes
+ fi
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cc_for_build_works" >&5
+$as_echo "$cc_for_build_works" >&6; }
+if test "$cc_for_build_works" = yes; then
+ :
+else
+ as_fn_error $? "Specified CC_FOR_BUILD doesn't seem to work" "$LINENO" 5
+fi
+
+elif test -n "$HOST_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system compiler $HOST_CC" >&5
+$as_echo_n "checking build system compiler $HOST_CC... " >&6; }
+# remove anything that might look like compiler output to our "||" expression
+rm -f conftest* a.out b.out a.exe a_out.exe
+cat >conftest.c <<EOF
+int
+main ()
+{
+ exit(0);
+}
+EOF
+gmp_compile="$HOST_CC conftest.c"
+cc_for_build_works=no
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if (./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest) >&5 2>&1; then
+ cc_for_build_works=yes
+ fi
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cc_for_build_works" >&5
+$as_echo "$cc_for_build_works" >&6; }
+if test "$cc_for_build_works" = yes; then
+ CC_FOR_BUILD=$HOST_CC
+else
+ as_fn_error $? "Specified HOST_CC doesn't seem to work" "$LINENO" 5
+fi
+
+else
+ for i in "$CC" "$CC $CFLAGS $CPPFLAGS" cc gcc c89 c99; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system compiler $i" >&5
+$as_echo_n "checking build system compiler $i... " >&6; }
+# remove anything that might look like compiler output to our "||" expression
+rm -f conftest* a.out b.out a.exe a_out.exe
+cat >conftest.c <<EOF
+int
+main ()
+{
+ exit(0);
+}
+EOF
+gmp_compile="$i conftest.c"
+cc_for_build_works=no
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if (./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest) >&5 2>&1; then
+ cc_for_build_works=yes
+ fi
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cc_for_build_works" >&5
+$as_echo "$cc_for_build_works" >&6; }
+if test "$cc_for_build_works" = yes; then
+ CC_FOR_BUILD=$i
+ break
+else
+ :
+fi
+
+ done
+ if test -z "$CC_FOR_BUILD"; then
+ as_fn_error $? "Cannot find a build system compiler" "$LINENO" 5
+ fi
+fi
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system preprocessor" >&5
+$as_echo_n "checking for build system preprocessor... " >&6; }
+if test -z "$CPP_FOR_BUILD"; then
+ if ${gmp_cv_prog_cpp_for_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.c <<EOF
+#define FOO BAR
+EOF
+ for i in "$CC_FOR_BUILD -E" "$CC_FOR_BUILD -E -traditional-cpp" "/lib/cpp"; do
+ gmp_compile="$i conftest.c"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } >&5 2>&1; then
+ gmp_cv_prog_cpp_for_build=$i
+ break
+ fi
+ done
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ if test -z "$gmp_cv_prog_cpp_for_build"; then
+ as_fn_error $? "Cannot find build system C preprocessor." "$LINENO" 5
+ fi
+
+fi
+
+ CPP_FOR_BUILD=$gmp_cv_prog_cpp_for_build
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP_FOR_BUILD" >&5
+$as_echo "$CPP_FOR_BUILD" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5
+$as_echo_n "checking for build system executable suffix... " >&6; }
+if ${gmp_cv_prog_exeext_for_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.c <<EOF
+int
+main ()
+{
+ exit (0);
+}
+EOF
+for i in .exe ,ff8 ""; do
+ gmp_compile="$CC_FOR_BUILD conftest.c -o conftest$i"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if (./conftest) 2>&5; then
+ gmp_cv_prog_exeext_for_build=$i
+ break
+ fi
+ fi
+done
+rm -f conftest*
+if test "${gmp_cv_prog_exeext_for_build+set}" != set; then
+ as_fn_error $? "Cannot determine executable suffix" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_prog_exeext_for_build" >&5
+$as_echo "$gmp_cv_prog_exeext_for_build" >&6; }
+EXEEXT_FOR_BUILD=$gmp_cv_prog_exeext_for_build
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build system compiler is ANSI" >&5
+$as_echo_n "checking whether build system compiler is ANSI... " >&6; }
+if ${gmp_cv_c_for_build_ansi+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.c <<EOF
+int
+main (int argc, char **argv)
+{
+ exit(0);
+}
+EOF
+gmp_compile="$CC_FOR_BUILD conftest.c"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ gmp_cv_c_for_build_ansi=yes
+else
+ gmp_cv_c_for_build_ansi=no
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_c_for_build_ansi" >&5
+$as_echo "$gmp_cv_c_for_build_ansi" >&6; }
+if test "$gmp_cv_c_for_build_ansi" = yes; then
+ U_FOR_BUILD=
+else
+ U_FOR_BUILD=_
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system compiler math library" >&5
+$as_echo_n "checking for build system compiler math library... " >&6; }
+if ${gmp_cv_check_libm_for_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.c <<EOF
+int
+main ()
+{
+ exit(0);
+}
+double d;
+double
+foo ()
+{
+ return log (d);
+}
+EOF
+gmp_compile="$CC_FOR_BUILD conftest.c -lm"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ gmp_cv_check_libm_for_build=-lm
+else
+ gmp_cv_check_libm_for_build=no
+fi
+rm -f conftest* a.out b.out a.exe a_out.exe
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_check_libm_for_build" >&5
+$as_echo "$gmp_cv_check_libm_for_build" >&6; }
+case $gmp_cv_check_libm_for_build in
+ yes) LIBM_FOR_BUILD=-lm
+ ;;
+ no) LIBM_FOR_BUILD= ;;
+ *) LIBM_FOR_BUILD=$gmp_cv_check_libm_for_build ;;
+esac
+
+
+
+# How to assemble, used with CFLAGS etc, see mpn/Makeasm.am.
+# Using the compiler is a lot easier than figuring out how to invoke the
+# assembler directly.
+#
+test -n "$CCAS" || CCAS="$CC -c"
+
+
+
+# The C++ compiler, if desired.
+want_cxx=no
+if test $enable_cxx != no; then
+ test_CXXFLAGS=${CXXFLAGS+set}
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ echo "CXXFLAGS chosen by autoconf: $CXXFLAGS" >&5
+ cxxflags_ac_prog_cxx=$CXXFLAGS
+ cxxflags_list=ac_prog_cxx
+
+ # If the user didn't specify $CXXFLAGS, then try $CFLAGS, with -g removed
+ # if AC_PROG_CXX thinks that doesn't work. $CFLAGS stands a good chance
+ # of working, eg. on a GNU system where CC=gcc and CXX=g++.
+ #
+ if test "$test_CXXFLAGS" != set; then
+ cxxflags_cflags=$CFLAGS
+ cxxflags_list="cflags $cxxflags_list"
+ if test "$ac_prog_cxx_g" = no; then
+ cxxflags_cflags=`echo "$cxxflags_cflags" | sed -e 's/ -g //' -e 's/^-g //' -e 's/ -g$//'`
+ fi
+ fi
+
+ # See if the C++ compiler works. If the user specified CXXFLAGS then all
+ # we're doing is checking whether AC_PROG_CXX succeeded, since it doesn't
+ # give a fatal error, just leaves CXX set to a default g++. If on the
+ # other hand the user didn't specify CXXFLAGS then we get to try here our
+ # $cxxflags_list alternatives.
+ #
+ # Automake includes $CPPFLAGS in a C++ compile, so we do the same here.
+ #
+ for cxxflags_choice in $cxxflags_list; do
+ eval CXXFLAGS=\"\$cxxflags_$cxxflags_choice\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking C++ compiler $CXX $CPPFLAGS $CXXFLAGS" >&5
+$as_echo_n "checking C++ compiler $CXX $CPPFLAGS $CXXFLAGS... " >&6; }
+gmp_prog_cxx_works=yes
+
+# start with a plain "main()", then go on to further checks
+if test "$gmp_prog_cxx_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.cc <<EOF
+
+int main (void) { return 0; }
+EOF
+ echo "Test compile: " >&5
+ gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS conftest.cc >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_cxxcompile\""; } >&5
+ (eval $gmp_cxxcompile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ gmp_prog_cxx_works="no, program does not run"
+ fi
+ fi
+ else
+ gmp_prog_cxx_works="no"
+ fi
+ case $gmp_prog_cxx_works in
+ no*)
+ echo "failed program was:" >&5
+ cat conftest.cc >&5
+ ;;
+ esac
+ rm -f conftest* a.out b.out a.exe a_out.exe
+fi
+
+
+if test "$gmp_prog_cxx_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.cc <<EOF
+namespace foo { }
+using namespace foo;
+
+int main (void) { return 0; }
+EOF
+ echo "Test compile: namespace" >&5
+ gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS conftest.cc >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_cxxcompile\""; } >&5
+ (eval $gmp_cxxcompile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ gmp_prog_cxx_works="no, namespace, program does not run"
+ fi
+ fi
+ else
+ gmp_prog_cxx_works="no, namespace"
+ fi
+ case $gmp_prog_cxx_works in
+ no*)
+ echo "failed program was:" >&5
+ cat conftest.cc >&5
+ ;;
+ esac
+ rm -f conftest* a.out b.out a.exe a_out.exe
+fi
+
+
+# GMP requires the standard C++ iostream classes
+if test "$gmp_prog_cxx_works" = yes; then
+ # remove anything that might look like compiler output to our "||" expression
+ rm -f conftest* a.out b.out a.exe a_out.exe
+ cat >conftest.cc <<EOF
+/* This test rejects g++ 2.7.2 which doesn't have <iostream>, only a
+ pre-standard iostream.h. */
+#include <iostream>
+
+/* This test rejects OSF 5.1 Compaq C++ in its default pre-standard iostream
+ mode, since that mode puts cout in the global namespace, not "std". */
+void someoutput (void) { std::cout << 123; }
+
+int main (void) { return 0; }
+EOF
+ echo "Test compile: std iostream" >&5
+ gmp_cxxcompile="$CXX $CPPFLAGS $CXXFLAGS conftest.cc >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_cxxcompile\""; } >&5
+ (eval $gmp_cxxcompile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$cross_compiling" = no; then
+ if { ac_try='./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :;
+ else
+ gmp_prog_cxx_works="no, std iostream, program does not run"
+ fi
+ fi
+ else
+ gmp_prog_cxx_works="no, std iostream"
+ fi
+ case $gmp_prog_cxx_works in
+ no*)
+ echo "failed program was:" >&5
+ cat conftest.cc >&5
+ ;;
+ esac
+ rm -f conftest* a.out b.out a.exe a_out.exe
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_prog_cxx_works" >&5
+$as_echo "$gmp_prog_cxx_works" >&6; }
+case $gmp_prog_cxx_works in
+ yes)
+ want_cxx=yes
+ break
+ ;;
+ *)
+
+ ;;
+esac
+
+ done
+
+ # If --enable-cxx=yes but a C++ compiler can't be found, then abort.
+ if test $want_cxx = no && test $enable_cxx = yes; then
+ as_fn_error $? "C++ compiler not available, see config.log for details" "$LINENO" 5
+ fi
+fi
+
+ if test $want_cxx = yes; then
+ WANT_CXX_TRUE=
+ WANT_CXX_FALSE='#'
+else
+ WANT_CXX_TRUE='#'
+ WANT_CXX_FALSE=
+fi
+
+
+# FIXME: We're not interested in CXXCPP for ourselves, but if we don't do it
+# here then AC_PROG_LIBTOOL will AC_REQUIRE it (via _LT_AC_TAGCONFIG) and
+# hence execute it unconditionally, and that will fail if there's no C++
+# compiler (and no generic /lib/cpp).
+#
+if test $want_cxx = yes; then
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+ if ${ac_cv_prog_CXXCPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+
+# Path setups for Cray, according to IEEE or CFP. These must come after
+# deciding the compiler.
+#
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+case $host_cpu in
+ c90 | t90)
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef _CRAYIEEE
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "yes" >/dev/null 2>&1; then :
+ add_path="cray/ieee"
+else
+ add_path="cray/cfp"; extra_functions="mulwwc90"
+fi
+rm -f conftest*
+
+ ;;
+ j90 | sv1)
+ add_path="cray/cfp"; extra_functions="mulwwj90"
+ ;;
+esac
+
+
+
+if test -z "$MPN_PATH"; then
+ path="$add_path $path"
+fi
+
+# For a nail build, also look in "nails" subdirectories.
+#
+if test $GMP_NAIL_BITS != 0 && test -z "$MPN_PATH"; then
+ new_path=
+ for i in $path; do
+ case $i in
+ generic) new_path="$new_path $i" ;;
+ *) new_path="$new_path $i/nails $i" ;;
+ esac
+ done
+ path=$new_path
+fi
+
+
+# Put all directories into CPUVEC_list so as to get a full set of
+# CPUVEC_SETUP_$tmp_suffix defines into config.h, even if some of them are
+# empty because mmx and/or sse2 had to be dropped.
+#
+for i in $fat_path; do
+ tmp_suffix=`echo $i | sed -e '/\//s:^[^/]*/::' -e 's:[\\/]:_:g'`
+ CPUVEC_list="$CPUVEC_list CPUVEC_SETUP_$tmp_suffix"
+done
+
+
+# If there's any sse2 or mmx in the path, check whether the assembler
+# supports it, and remove if not.
+#
+# We only need this in ABI=32, for ABI=64 on x86_64 we can assume a new
+# enough assembler.
+#
+case $host in
+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-* | athlon64-*-* | k8-*-* | k10-*-* | bobcat-*-* | jaguar-*-* | bulldozer-*-* | piledriver-*-* | steamroller-*-* | excavator-*-* | pentium4-*-* | atom-*-* | core2-*-* | corei*-*-* | x86_64-*-* | nano-*-*)
+ if test "$ABI" = 32; then
+ case "$path $fat_path" in
+ *mmx*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler knows about MMX instructions" >&5
+$as_echo_n "checking if the assembler knows about MMX instructions... " >&6; }
+if ${gmp_cv_asm_x86_mmx+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ .text
+ movq %mm0, %mm1
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_x86_mmx=yes
+case $host in
+*-*-solaris*)
+ if (dis conftest.$OBJEXT >conftest.out) 2>/dev/null; then
+ if grep "0f 6f c1" conftest.out >/dev/null; then
+ gmp_cv_asm_x86_mmx=movq-bug
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"dis\" not available to check for \"as\" movq bug" >&5
+$as_echo "$as_me: WARNING: \"dis\" not available to check for \"as\" movq bug" >&2;}
+ fi
+esac
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_x86_mmx=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_x86_mmx" >&5
+$as_echo "$gmp_cv_asm_x86_mmx" >&6; }
+
+case $gmp_cv_asm_x86_mmx in
+movq-bug)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | WARNING WARNING WARNING" >&5
+$as_echo "$as_me: WARNING: | WARNING WARNING WARNING" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Host CPU has MMX code, but the assembler" >&5
+$as_echo "$as_me: WARNING: | Host CPU has MMX code, but the assembler" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&5
+$as_echo "$as_me: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | has the Solaris 2.6 and 2.7 bug where register to register" >&5
+$as_echo "$as_me: WARNING: | has the Solaris 2.6 and 2.7 bug where register to register" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | movq operands are reversed." >&5
+$as_echo "$as_me: WARNING: | movq operands are reversed." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Non-MMX replacements will be used." >&5
+$as_echo "$as_me: WARNING: | Non-MMX replacements will be used." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | This will be an inferior build." >&5
+$as_echo "$as_me: WARNING: | This will be an inferior build." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ ;;
+no)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | WARNING WARNING WARNING" >&5
+$as_echo "$as_me: WARNING: | WARNING WARNING WARNING" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Host CPU has MMX code, but it can't be assembled by" >&5
+$as_echo "$as_me: WARNING: | Host CPU has MMX code, but it can't be assembled by" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&5
+$as_echo "$as_me: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Non-MMX replacements will be used." >&5
+$as_echo "$as_me: WARNING: | Non-MMX replacements will be used." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | This will be an inferior build." >&5
+$as_echo "$as_me: WARNING: | This will be an inferior build." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ ;;
+esac
+if test "$gmp_cv_asm_x86_mmx" = yes; then
+ :
+else
+ tmp_path=
+for i in $path; do
+ case $i in
+ */*mmx*) ;;
+ *) tmp_path="$tmp_path $i" ;;
+ esac
+done
+path="$tmp_path"
+
+tmp_path=
+for i in $fat_path; do
+ case $i in
+ */*mmx*) ;;
+ *) tmp_path="$tmp_path $i" ;;
+ esac
+done
+fat_path="$tmp_path"
+
+
+fi
+ ;;
+ esac
+ case "$path $fat_path" in
+ *sse2*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler knows about SSE2 instructions" >&5
+$as_echo_n "checking if the assembler knows about SSE2 instructions... " >&6; }
+if ${gmp_cv_asm_x86_sse2+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ .text
+ paddq %mm0, %mm1
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_x86_sse2=yes
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_x86_sse2=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_x86_sse2" >&5
+$as_echo "$gmp_cv_asm_x86_sse2" >&6; }
+case $gmp_cv_asm_x86_sse2 in
+yes)
+ :
+ ;;
+*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | WARNING WARNING WARNING" >&5
+$as_echo "$as_me: WARNING: | WARNING WARNING WARNING" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Host CPU has SSE2 code, but it can't be assembled by" >&5
+$as_echo "$as_me: WARNING: | Host CPU has SSE2 code, but it can't be assembled by" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&5
+$as_echo "$as_me: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Non-SSE2 replacements will be used." >&5
+$as_echo "$as_me: WARNING: | Non-SSE2 replacements will be used." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | This will be an inferior build." >&5
+$as_echo "$as_me: WARNING: | This will be an inferior build." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ tmp_path=
+for i in $path; do
+ case $i in
+ */sse2) ;;
+ *) tmp_path="$tmp_path $i" ;;
+ esac
+done
+path="$tmp_path"
+
+tmp_path=
+for i in $fat_path; do
+ case $i in
+ */sse2) ;;
+ *) tmp_path="$tmp_path $i" ;;
+ esac
+done
+fat_path="$tmp_path"
+
+
+ ;;
+esac
+ ;;
+ esac
+ fi
+ case "$path $fat_path" in
+ *mulx*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler knows about the mulx instruction" >&5
+$as_echo_n "checking if the assembler knows about the mulx instruction... " >&6; }
+if ${gmp_cv_asm_x86_mulx+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ .text
+ mulx %r8, %r9, %r10
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_x86_mulx=yes
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_x86_mulx=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_x86_mulx" >&5
+$as_echo "$gmp_cv_asm_x86_mulx" >&6; }
+case $gmp_cv_asm_x86_mulx in
+yes)
+ :
+ ;;
+*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | WARNING WARNING WARNING" >&5
+$as_echo "$as_me: WARNING: | WARNING WARNING WARNING" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Host CPU has the mulx instruction, but it can't be" >&5
+$as_echo "$as_me: WARNING: | Host CPU has the mulx instruction, but it can't be" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | assembled by" >&5
+$as_echo "$as_me: WARNING: | assembled by" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&5
+$as_echo "$as_me: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Older x86 instructions will be used." >&5
+$as_echo "$as_me: WARNING: | Older x86 instructions will be used." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | This will be an inferior build." >&5
+$as_echo "$as_me: WARNING: | This will be an inferior build." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ tmp_path=
+for i in $path; do
+ case $i in
+ */mulx) ;;
+ *) tmp_path="$tmp_path $i" ;;
+ esac
+done
+path="$tmp_path"
+
+tmp_path=
+for i in $fat_path; do
+ case $i in
+ */mulx) ;;
+ *) tmp_path="$tmp_path $i" ;;
+ esac
+done
+fat_path="$tmp_path"
+
+
+ ;;
+esac
+ ;;
+ esac
+ case "$path $fat_path" in
+ *adx*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler knows about the adox instruction" >&5
+$as_echo_n "checking if the assembler knows about the adox instruction... " >&6; }
+if ${gmp_cv_asm_x86_adx+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ .text
+ adox %r8, %r9
+ adcx %r8, %r9
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_x86_adx=yes
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_x86_adx=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_x86_adx" >&5
+$as_echo "$gmp_cv_asm_x86_adx" >&6; }
+case $gmp_cv_asm_x86_adx in
+yes)
+ :
+ ;;
+*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | WARNING WARNING WARNING" >&5
+$as_echo "$as_me: WARNING: | WARNING WARNING WARNING" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Host CPU has the adcx and adox instructions, but they" >&5
+$as_echo "$as_me: WARNING: | Host CPU has the adcx and adox instructions, but they" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | can't be assembled by" >&5
+$as_echo "$as_me: WARNING: | can't be assembled by" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&5
+$as_echo "$as_me: WARNING: | $CCAS $CFLAGS $CPPFLAGS" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Older x86 instructions will be used." >&5
+$as_echo "$as_me: WARNING: | Older x86 instructions will be used." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | This will be an inferior build." >&5
+$as_echo "$as_me: WARNING: | This will be an inferior build." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ tmp_path=
+for i in $path; do
+ case $i in
+ */adx) ;;
+ *) tmp_path="$tmp_path $i" ;;
+ esac
+done
+path="$tmp_path"
+
+tmp_path=
+for i in $fat_path; do
+ case $i in
+ */adx) ;;
+ *) tmp_path="$tmp_path $i" ;;
+ esac
+done
+fat_path="$tmp_path"
+
+
+ ;;
+esac
+ ;;
+ esac
+ ;;
+esac
+
+
+if test "$enable_assembly" = "no"; then
+ path="generic"
+ CFLAGS="$CFLAGS -DNO_ASM"
+# for abi in $abilist; do
+# eval unset "path_\$abi"
+# eval gcc_${abi}_cflags=\"\$gcc_${abi}_cflags -DNO_ASM\"
+# done
+fi
+
+
+cat >&5 <<EOF
+Decided:
+ABI=$ABI
+CC=$CC
+CFLAGS=$CFLAGS
+CPPFLAGS=$CPPFLAGS
+GMP_LDFLAGS=$GMP_LDFLAGS
+CXX=$CXX
+CXXFLAGS=$CXXFLAGS
+path=$path
+EOF
+echo "using ABI=\"$ABI\""
+echo " CC=\"$CC\""
+echo " CFLAGS=\"$CFLAGS\""
+echo " CPPFLAGS=\"$CPPFLAGS\""
+if test $want_cxx = yes; then
+ echo " CXX=\"$CXX\""
+ echo " CXXFLAGS=\"$CXXFLAGS\""
+fi
+echo " MPN_PATH=\"$path\""
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether assembler supports --noexecstack option" >&5
+$as_echo_n "checking whether assembler supports --noexecstack option... " >&6; }
+if ${cl_cv_as_noexecstack+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<EOF
+void foo() {}
+EOF
+ if { ac_try='${CC} $CFLAGS $CPPFLAGS
+ -S -o conftest.s conftest.c >/dev/null'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } \
+ && grep .note.GNU-stack conftest.s >/dev/null \
+ && { ac_try='${CC} $CFLAGS $CPPFLAGS -Wa,--noexecstack
+ -c -o conftest.o conftest.s >/dev/null'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ cl_cv_as_noexecstack=yes
+ else
+ cl_cv_as_noexecstack=no
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cl_cv_as_noexecstack" >&5
+$as_echo "$cl_cv_as_noexecstack" >&6; }
+ if test "$cl_cv_as_noexecstack" = yes; then
+ ASMFLAGS="$ASMFLAGS -Wa,--noexecstack"
+ fi
+
+
+
+
+gmp_user_AR=$AR
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="ar"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+if test -z "$gmp_user_AR"; then
+ eval arflags=\"\$ar${abi1}_flags\"
+ test -n "$arflags" || eval arflags=\"\$ar${abi2}_flags\"
+ if test -n "$arflags"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for extra ar flags" >&5
+$as_echo_n "checking for extra ar flags... " >&6; }
+ AR="$AR $arflags"
+ ac_cv_prog_AR="$AR $arflags"
+ ac_cv_prog_ac_ct_AR="$AR $arflags"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $arflags" >&5
+$as_echo "$arflags" >&6; }
+ fi
+fi
+if test -z "$AR_FLAGS"; then
+ AR_FLAGS=cq
+fi
+
+
+gmp_user_NM=$NM
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+
+# FIXME: When cross compiling (ie. $ac_tool_prefix not empty), libtool
+# defaults to plain "nm" if a "${ac_tool_prefix}nm" is not found. In this
+# case run it again to try the native "nm", firstly so that likely locations
+# are searched, secondly so that -B or -p are added if necessary for BSD
+# format. This is necessary for instance on OSF with "./configure
+# --build=alphaev5-dec-osf --host=alphaev6-dec-osf".
+#
+if test -z "$gmp_user_NM" && test -n "$ac_tool_prefix" && test "$NM" = nm; then
+ $as_unset lt_cv_path_NM
+ gmp_save_ac_tool_prefix=$ac_tool_prefix
+ ac_tool_prefix=
+ NM=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+ ac_tool_prefix=$gmp_save_ac_tool_prefix
+fi
+
+if test -z "$gmp_user_NM"; then
+ eval nmflags=\"\$nm${abi1}_flags\"
+ test -n "$nmflags" || eval nmflags=\"\$nm${abi2}_flags\"
+ if test -n "$nmflags"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for extra nm flags" >&5
+$as_echo_n "checking for extra nm flags... " >&6; }
+ NM="$NM $nmflags"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $nmflags" >&5
+$as_echo "$nmflags" >&6; }
+ fi
+fi
+
+
+case $host in
+ # FIXME: On AIX 3 and 4, $libname.a is included in libtool
+ # $library_names_spec, so libgmp.a becomes a symlink to libgmp.so, making
+ # it impossible to build shared and static libraries simultaneously.
+ # Disable shared libraries by default, but let the user override with
+ # --enable-shared --disable-static.
+ #
+ # FIXME: This $libname.a problem looks like it might apply to *-*-amigaos*
+ # and *-*-os2* too, but wait for someone to test this before worrying
+ # about it. If there is a problem then of course libtool is the right
+ # place to fix it.
+ #
+ *-*-aix[34]*)
+ if test -z "$enable_shared"; then enable_shared=no; fi ;;
+esac
+
+
+# Configs for Windows DLLs.
+
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+ ac_ct_AS=$AS
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AS"; then
+ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AS="as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AS" = x; then
+ AS="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AS=$ac_ct_AS
+ fi
+else
+ AS="$ac_cv_prog_AS"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+ ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+LIBGMP_DLL=0
+
+case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ # By default, build only static.
+ if test -z "$enable_shared"; then
+ enable_shared=no
+ fi
+ # Don't allow both static and DLL.
+ if test "$enable_shared" != no && test "$enable_static" != no; then
+ as_fn_error $? "cannot build both static and DLL, since gmp.h is different for each.
+Use \"--disable-static --enable-shared\" to build just a DLL." "$LINENO" 5
+ fi
+
+ # "-no-undefined" is required when building a DLL, see documentation on
+ # AC_LIBTOOL_WIN32_DLL.
+ #
+ # "-Wl,--export-all-symbols" is a bit of a hack, it gets all libgmp and
+ # libgmpxx functions and variables exported. This is what libtool did
+ # in the past, and it's convenient for us in the test programs.
+ #
+ # Maybe it'd be prudent to check for --export-all-symbols before using
+ # it, but it seems to have been in ld since at least 2000, and there's
+ # not really any alternative we want to take up at the moment.
+ #
+ # "-Wl,output-def" is used to get a .def file for use by MS lib to make
+ # a .lib import library, described in the manual. libgmp-3.dll.def
+ # corresponds to the libmp-3.dll.def generated by libtool (as a result
+ # of -export-symbols on that library).
+ #
+ # Incidentally, libtool does generate an import library libgmp.dll.a,
+ # but it's "ar" format and cannot be used by the MS linker. There
+ # doesn't seem to be any GNU tool for generating or converting to .lib.
+ #
+ # FIXME: The .def files produced by -Wl,output-def include isascii,
+ # iscsym, iscsymf and toascii, apparently because mingw ctype.h doesn't
+ # inline isascii (used in gmp). It gives an extern inline for
+ # __isascii, but for some reason not the plain isascii.
+ #
+ if test "$enable_shared" = yes; then
+ GMP_LDFLAGS="$GMP_LDFLAGS -no-undefined -Wl,--export-all-symbols"
+ LIBGMP_LDFLAGS="$LIBGMP_LDFLAGS -Wl,--output-def,.libs/libgmp-3.dll.def"
+ LIBGMPXX_LDFLAGS="$LIBGMP_LDFLAGS -Wl,--output-def,.libs/libgmpxx-3.dll.def"
+ LIBGMP_DLL=1
+ fi
+ ;;
+esac
+
+
+# Ensure that $CONFIG_SHELL is available for AC_LIBTOOL_SYS_MAX_CMD_LEN.
+# It's often set already by _LT_AC_PROG_ECHO_BACKSLASH or
+# _AS_LINENO_PREPARE, but not always.
+#
+# The symptom of CONFIG_SHELL unset is some "expr" errors during the test,
+# and an empty result. This only happens when invoked as "sh configure",
+# ie. no path, and can be seen for instance on ia64-*-hpux*.
+#
+# FIXME: Newer libtool should have it's own fix for this.
+#
+if test -z "$CONFIG_SHELL"; then
+ CONFIG_SHELL=$SHELL
+fi
+
+# Enable CXX in libtool only if we want it, and never enable GCJ, nor RC on
+# mingw and cygwin. Under --disable-cxx this avoids some error messages
+# from libtool arising from the fact we didn't actually run AC_PROG_CXX.
+# Notice that any user-supplied --with-tags setting takes precedence.
+#
+# FIXME: Is this the right way to get this effect? Very possibly not, but
+# the current _LT_AC_TAGCONFIG doesn't really suggest an alternative.
+#
+if test "${with_tags+set}" != set; then
+ if test $want_cxx = yes; then
+ with_tags=CXX
+ else
+ with_tags=
+ fi
+fi
+
+# The dead hand of AC_REQUIRE makes AC_PROG_LIBTOOL expand and execute
+# AC_PROG_F77, even when F77 is not in the selected with_tags. This is
+# probably harmless, but it's unsightly and bloats our configure, so pretend
+# AC_PROG_F77 has been expanded already.
+#
+# FIXME: Rumour has it libtool will one day provide a way for a configure.in
+# to say what it wants from among supported languages etc.
+#
+#AC_PROVIDE([AC_PROG_F77])
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case "$ECHO" in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+func_stripname_cnf ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+ if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+ if ${ac_cv_prog_CXXCPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+else
+ _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+ # save warnings/boilerplate of simple test code
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ compiler_CXX=$CC
+ for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+ else
+ lt_prog_compiler_no_builtin_flag_CXX=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec_CXX=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+ ld_shlibs_CXX=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds_CXX=''
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ file_list_spec_CXX='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct_CXX=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L_CXX=yes
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ hardcode_libdir_separator_CXX=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec_CXX='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ always_export_symbols_CXX=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag_CXX='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag_CXX="-z nodefs"
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag_CXX=' ${wl}-bernotok'
+ allow_undefined_flag_CXX=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec_CXX='$convenience'
+ fi
+ archive_cmds_need_lc_CXX=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag_CXX=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX=' '
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=yes
+ file_list_spec_CXX='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+ enable_shared_with_static_runtimes_CXX=yes
+ # Don't use ranlib
+ old_postinstall_cmds_CXX='chmod 644 $oldlib'
+ postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=no
+ enable_shared_with_static_runtimes_CXX=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc_CXX=no
+ hardcode_direct_CXX=no
+ hardcode_automatic_CXX=yes
+ hardcode_shlibpath_var_CXX=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec_CXX=''
+ fi
+ link_all_deplibs_CXX=yes
+ allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+
+ else
+ ld_shlibs_CXX=no
+ fi
+
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ ld_shlibs_CXX=no
+ ;;
+
+ freebsd-elf*)
+ archive_cmds_need_lc_CXX=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ ld_shlibs_CXX=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ haiku*)
+ archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs_CXX=yes
+ ;;
+
+ hpux9*)
+ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ hardcode_direct_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ ;;
+ *)
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ fi
+ fi
+ link_all_deplibs_CXX=yes
+ ;;
+ esac
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+ inherit_rpath_CXX=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ archive_cmds_need_lc_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+ prelink_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ old_archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ archive_expsym_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object_CXX=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ ld_shlibs_CXX=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ ld_shlibs_CXX=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ hardcode_direct_absolute_CXX=yes
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ allow_undefined_flag_CXX=' -expect_unresolved \*'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ ;;
+ esac
+
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ archive_cmds_need_lc_CXX=yes
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_shlibpath_var_CXX=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ link_all_deplibs_CXX=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag_CXX='${wl}-z,text'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag_CXX='${wl}-z,text'
+ allow_undefined_flag_CXX='${wl}-z,nodefs'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ export_dynamic_flag_spec_CXX='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+ '"$old_archive_cmds_CXX"
+ reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+ '"$reload_cmds_CXX"
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+ test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+ GCC_CXX="$GXX"
+ LD_CXX="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case ${prev}${p} in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test "$pre_test_object_deps_done" = no; then
+ case ${prev} in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$compiler_lib_search_path_CXX"; then
+ compiler_lib_search_path_CXX="${prev}${p}"
+ else
+ compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$postdeps_CXX"; then
+ postdeps_CXX="${prev}${p}"
+ else
+ postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$predep_objects_CXX"; then
+ predep_objects_CXX="$p"
+ else
+ predep_objects_CXX="$predep_objects_CXX $p"
+ fi
+ else
+ if test -z "$postdep_objects_CXX"; then
+ postdep_objects_CXX="$p"
+ else
+ postdep_objects_CXX="$postdep_objects_CXX $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ predep_objects_CXX=
+ postdep_objects_CXX=
+ postdeps_CXX=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ postdeps_CXX='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ postdeps_CXX='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic_CXX='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ lt_prog_compiler_pic_CXX=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static_CXX=
+ ;;
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic_CXX=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[4-9]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ else
+ lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ lt_prog_compiler_pic_CXX='+Z'
+ fi
+ ;;
+ aCC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fpic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-qpic'
+ lt_prog_compiler_static_CXX='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ lt_prog_compiler_pic_CXX='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ lt_prog_compiler_wl_CXX='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ lt_prog_compiler_pic_CXX='-pic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ lt_prog_compiler_can_build_shared_CXX=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic_CXX=
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works_CXX=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works_CXX=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+ case $lt_prog_compiler_pic_CXX in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+ esac
+else
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works_CXX=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+ :
+else
+ lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ case $host_os in
+ aix[4-9]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ export_symbols_cmds_CXX="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ ;;
+ esac
+ ;;
+ *)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc_CXX=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds_CXX in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl_CXX
+ pic_flag=$lt_prog_compiler_pic_CXX
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+ allow_undefined_flag_CXX=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc_CXX=no
+ else
+ lt_cv_archive_cmds_need_lc_CXX=yes
+ fi
+ allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+ archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+ test -n "$runpath_var_CXX" ||
+ test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct_CXX" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+ test "$hardcode_minus_L_CXX" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_CXX=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_CXX=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+ test "$inherit_rpath_CXX" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# Generate an error here if attempting to build both shared and static when
+# $libname.a is in $library_names_spec (as mentioned above), rather than
+# wait for ar or ld to fail.
+#
+if test "$enable_shared" = yes && test "$enable_static" = yes; then
+ case $library_names_spec in
+ *libname.a*)
+ as_fn_error $? "cannot create both shared and static libraries on this system, --disable one of the two" "$LINENO" 5
+ ;;
+ esac
+fi
+
+ if test "$enable_static" = yes; then
+ ENABLE_STATIC_TRUE=
+ ENABLE_STATIC_FALSE='#'
+else
+ ENABLE_STATIC_TRUE='#'
+ ENABLE_STATIC_FALSE=
+fi
+
+
+
+# Many of these library and header checks are for the benefit of
+# supplementary programs. libgmp doesn't use anything too weird.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_time=yes
+else
+ ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+
+# Reasons for testing:
+# float.h - not in SunOS bundled cc
+# invent.h - IRIX specific
+# langinfo.h - X/Open standard only, not in djgpp for instance
+# locale.h - old systems won't have this
+# nl_types.h - X/Open standard only, not in djgpp for instance
+# (usually langinfo.h gives nl_item etc, but not on netbsd 1.4.1)
+# sys/attributes.h - IRIX specific
+# sys/iograph.h - IRIX specific
+# sys/mman.h - not in Cray Unicos
+# sys/param.h - not in mingw
+# sys/processor.h - solaris specific, though also present in macos
+# sys/pstat.h - HPUX specific
+# sys/resource.h - not in mingw
+# sys/sysctl.h - not in mingw
+# sys/sysinfo.h - OSF specific
+# sys/syssgi.h - IRIX specific
+# sys/systemcfg.h - AIX specific
+# sys/time.h - autoconf suggests testing, don't know anywhere without it
+# sys/times.h - not in mingw
+# machine/hal_sysinfo.h - OSF specific
+#
+# inttypes.h, stdint.h, unistd.h and sys/types.h are already in the autoconf
+# default tests
+#
+for ac_header in fcntl.h float.h invent.h langinfo.h locale.h nl_types.h sys/attributes.h sys/iograph.h sys/mman.h sys/param.h sys/processor.h sys/pstat.h sys/sysinfo.h sys/syssgi.h sys/systemcfg.h sys/time.h sys/times.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# On SunOS, sys/resource.h needs sys/time.h (for struct timeval)
+for ac_header in sys/resource.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "sys/resource.h" "ac_cv_header_sys_resource_h" "#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+"
+if test "x$ac_cv_header_sys_resource_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_RESOURCE_H 1
+_ACEOF
+
+fi
+
+done
+
+
+# On NetBSD and OpenBSD, sys/sysctl.h needs sys/param.h for various constants
+for ac_header in sys/sysctl.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+"
+if test "x$ac_cv_header_sys_sysctl_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SYSCTL_H 1
+_ACEOF
+
+fi
+
+done
+
+
+# On OSF 4.0, <machine/hal_sysinfo.h> must have <sys/sysinfo.h> for ulong_t
+for ac_header in machine/hal_sysinfo.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "machine/hal_sysinfo.h" "ac_cv_header_machine_hal_sysinfo_h" "#if HAVE_SYS_SYSINFO_H
+# include <sys/sysinfo.h>
+#endif
+"
+if test "x$ac_cv_header_machine_hal_sysinfo_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MACHINE_HAL_SYSINFO_H 1
+_ACEOF
+
+fi
+
+done
+
+
+# Reasons for testing:
+# optarg - not declared in mingw
+# fgetc, fscanf, ungetc, vfprintf - not declared in SunOS 4
+# sys_errlist, sys_nerr - not declared in SunOS 4
+#
+# optarg should be in unistd.h and the rest in stdio.h, both of which are
+# in the autoconf default includes.
+#
+# sys_errlist and sys_nerr are supposed to be in <errno.h> on SunOS according
+# to the man page (but aren't), in glibc they're in stdio.h.
+#
+ac_fn_c_check_decl "$LINENO" "fgetc" "ac_cv_have_decl_fgetc" "$ac_includes_default"
+if test "x$ac_cv_have_decl_fgetc" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_FGETC $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "fscanf" "ac_cv_have_decl_fscanf" "$ac_includes_default"
+if test "x$ac_cv_have_decl_fscanf" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_FSCANF $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "optarg" "ac_cv_have_decl_optarg" "$ac_includes_default"
+if test "x$ac_cv_have_decl_optarg" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_OPTARG $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "ungetc" "ac_cv_have_decl_ungetc" "$ac_includes_default"
+if test "x$ac_cv_have_decl_ungetc" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_UNGETC $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "vfprintf" "ac_cv_have_decl_vfprintf" "$ac_includes_default"
+if test "x$ac_cv_have_decl_vfprintf" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VFPRINTF $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "sys_errlist" "ac_cv_have_decl_sys_errlist" "#include <stdio.h>
+#include <errno.h>
+"
+if test "x$ac_cv_have_decl_sys_errlist" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SYS_ERRLIST $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "sys_nerr" "ac_cv_have_decl_sys_nerr" "#include <stdio.h>
+#include <errno.h>
+"
+if test "x$ac_cv_have_decl_sys_nerr" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SYS_NERR $ac_have_decl
+_ACEOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
+$as_echo_n "checking return type of signal handlers... " >&6; }
+if ${ac_cv_type_signal+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+return *(signal (0, 0)) (0) == 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_type_signal=int
+else
+ ac_cv_type_signal=void
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
+$as_echo "$ac_cv_type_signal" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+# Reasons for testing:
+# intmax_t - C99
+# long double - not in the HP bundled K&R cc
+# long long - only in reasonably recent compilers
+# ptrdiff_t - seems to be everywhere, maybe don't need to check this
+# quad_t - BSD specific
+# uint_least32_t - C99
+#
+# the default includes are sufficient for all these types
+#
+ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_intmax_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INTMAX_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "long double" "ac_cv_type_long_double" "$ac_includes_default"
+if test "x$ac_cv_type_long_double" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONG_DOUBLE 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default"
+if test "x$ac_cv_type_long_long" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONG_LONG 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default"
+if test "x$ac_cv_type_ptrdiff_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PTRDIFF_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "quad_t" "ac_cv_type_quad_t" "$ac_includes_default"
+if test "x$ac_cv_type_quad_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_QUAD_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "uint_least32_t" "ac_cv_type_uint_least32_t" "$ac_includes_default"
+if test "x$ac_cv_type_uint_least32_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT_LEAST32_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_intptr_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INTPTR_T 1
+_ACEOF
+
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for preprocessor stringizing operator" >&5
+$as_echo_n "checking for preprocessor stringizing operator... " >&6; }
+if ${ac_cv_c_stringize+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define x(y) #y
+
+char *s = x(teststring);
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "#teststring" >/dev/null 2>&1; then :
+ ac_cv_c_stringize=no
+else
+ ac_cv_c_stringize=yes
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stringize" >&5
+$as_echo "$ac_cv_c_stringize" >&6; }
+if test $ac_cv_c_stringize = yes; then
+
+$as_echo "#define HAVE_STRINGIZE 1" >>confdefs.h
+
+fi
+
+
+# FIXME: Really want #ifndef __cplusplus around the #define volatile
+# replacement autoconf gives, since volatile is always available in C++.
+# But we don't use it in C++ currently.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5
+$as_echo_n "checking for working volatile... " >&6; }
+if ${ac_cv_c_volatile+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+volatile int x;
+int * volatile y = (int *) 0;
+return !x && !y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_volatile=yes
+else
+ ac_cv_c_volatile=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5
+$as_echo "$ac_cv_c_volatile" >&6; }
+if test $ac_cv_c_volatile = no; then
+
+$as_echo "#define volatile /**/" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
+$as_echo_n "checking for C/C++ restrict keyword... " >&6; }
+if ${ac_cv_c_restrict+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_restrict=no
+ # The order here caters to the fact that C++ does not require restrict.
+ for ac_kw in __restrict __restrict__ _Restrict restrict; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+typedef int * int_ptr;
+ int foo (int_ptr $ac_kw ip) {
+ return ip[0];
+ }
+int
+main ()
+{
+int s[1];
+ int * $ac_kw t = s;
+ t[0] = 0;
+ return foo(t)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_restrict=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_restrict" != no && break
+ done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5
+$as_echo "$ac_cv_c_restrict" >&6; }
+
+ case $ac_cv_c_restrict in
+ restrict) ;;
+ no) $as_echo "#define restrict /**/" >>confdefs.h
+ ;;
+ *) cat >>confdefs.h <<_ACEOF
+#define restrict $ac_cv_c_restrict
+_ACEOF
+ ;;
+ esac
+
+
+# GMP_C_STDARG
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc __attribute__ ((const)) works" >&5
+$as_echo_n "checking whether gcc __attribute__ ((const)) works... " >&6; }
+if ${gmp_cv_c_attribute_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (int x) __attribute__ ((const));
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gmp_cv_c_attribute_const=yes
+else
+ gmp_cv_c_attribute_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_c_attribute_const" >&5
+$as_echo "$gmp_cv_c_attribute_const" >&6; }
+if test $gmp_cv_c_attribute_const = yes; then
+
+$as_echo "#define HAVE_ATTRIBUTE_CONST 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc __attribute__ ((malloc)) works" >&5
+$as_echo_n "checking whether gcc __attribute__ ((malloc)) works... " >&6; }
+if ${gmp_cv_c_attribute_malloc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.c <<EOF
+void *foo (int x) __attribute__ ((malloc));
+EOF
+gmp_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if grep "attribute directive ignored" conftest.out >/dev/null; then
+ gmp_cv_c_attribute_malloc=no
+ else
+ gmp_cv_c_attribute_malloc=yes
+ fi
+else
+ gmp_cv_c_attribute_malloc=no
+fi
+cat conftest.out >&5
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_c_attribute_malloc" >&5
+$as_echo "$gmp_cv_c_attribute_malloc" >&6; }
+if test $gmp_cv_c_attribute_malloc = yes; then
+
+$as_echo "#define HAVE_ATTRIBUTE_MALLOC 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc __attribute__ ((mode (XX))) works" >&5
+$as_echo_n "checking whether gcc __attribute__ ((mode (XX))) works... " >&6; }
+if ${gmp_cv_c_attribute_mode+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+typedef int SItype __attribute__ ((mode (SI)));
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gmp_cv_c_attribute_mode=yes
+else
+ gmp_cv_c_attribute_mode=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_c_attribute_mode" >&5
+$as_echo "$gmp_cv_c_attribute_mode" >&6; }
+if test $gmp_cv_c_attribute_mode = yes; then
+
+$as_echo "#define HAVE_ATTRIBUTE_MODE 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc __attribute__ ((noreturn)) works" >&5
+$as_echo_n "checking whether gcc __attribute__ ((noreturn)) works... " >&6; }
+if ${gmp_cv_c_attribute_noreturn+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void foo (int x) __attribute__ ((noreturn));
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gmp_cv_c_attribute_noreturn=yes
+else
+ gmp_cv_c_attribute_noreturn=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_c_attribute_noreturn" >&5
+$as_echo "$gmp_cv_c_attribute_noreturn" >&6; }
+if test $gmp_cv_c_attribute_noreturn = yes; then
+
+$as_echo "#define HAVE_ATTRIBUTE_NORETURN 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+
+case $ac_cv_c_inline in
+no) ;;
+*)
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define __GMP_WITHIN_CONFIGURE_INLINE 1
+#define __GMP_WITHIN_CONFIGURE 1 /* ignore template stuff */
+#define GMP_NAIL_BITS $GMP_NAIL_BITS
+#define GMP_LIMB_BITS 123
+$DEFN_LONG_LONG_LIMB
+#include "$srcdir/gmp-h.in"
+
+#ifndef __GMP_EXTERN_INLINE
+die die die
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ case $ac_cv_c_inline in
+ yes) tmp_inline=inline ;;
+ *) tmp_inline=$ac_cv_c_inline ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gmp.h doesnt recognise compiler \"$tmp_inline\", inlines will be unavailable" >&5
+$as_echo "$as_me: WARNING: gmp.h doesnt recognise compiler \"$tmp_inline\", inlines will be unavailable" >&2;}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ;;
+esac
+
+
+# from libtool
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mwvalidcheckl in -lmw" >&5
+$as_echo_n "checking for _mwvalidcheckl in -lmw... " >&6; }
+if ${ac_cv_lib_mw__mwvalidcheckl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmw $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _mwvalidcheckl ();
+int
+main ()
+{
+return _mwvalidcheckl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_mw__mwvalidcheckl=yes
+else
+ ac_cv_lib_mw__mwvalidcheckl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mw__mwvalidcheckl" >&5
+$as_echo "$ac_cv_lib_mw__mwvalidcheckl" >&6; }
+if test "x$ac_cv_lib_mw__mwvalidcheckl" = xyes; then :
+ LIBM="-lmw"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
+$as_echo_n "checking for cos in -lm... " >&6; }
+if ${ac_cv_lib_m_cos+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cos ();
+int
+main ()
+{
+return cos ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_cos=yes
+else
+ ac_cv_lib_m_cos=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
+$as_echo "$ac_cv_lib_m_cos" >&6; }
+if test "x$ac_cv_lib_m_cos" = xyes; then :
+ LIBM="$LIBM -lm"
+fi
+
+ ;;
+*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
+$as_echo_n "checking for cos in -lm... " >&6; }
+if ${ac_cv_lib_m_cos+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cos ();
+int
+main ()
+{
+return cos ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_cos=yes
+else
+ ac_cv_lib_m_cos=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
+$as_echo "$ac_cv_lib_m_cos" >&6; }
+if test "x$ac_cv_lib_m_cos" = xyes; then :
+ LIBM="-lm"
+fi
+
+ ;;
+esac
+
+
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+$as_echo_n "checking for working alloca.h... " >&6; }
+if ${gmp_cv_header_alloca+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gmp_cv_header_alloca=yes
+else
+ gmp_cv_header_alloca=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_header_alloca" >&5
+$as_echo "$gmp_cv_header_alloca" >&6; }
+if test $gmp_cv_header_alloca = yes; then
+
+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca (via gmp-impl.h)" >&5
+$as_echo_n "checking for alloca (via gmp-impl.h)... " >&6; }
+if ${gmp_cv_func_alloca+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define __GMP_WITHIN_CONFIGURE 1 /* ignore template stuff */
+#define GMP_NAIL_BITS $GMP_NAIL_BITS
+#define GMP_LIMB_BITS 123
+$DEFN_LONG_LONG_LIMB
+#include "$srcdir/gmp-h.in"
+
+#include "$srcdir/gmp-impl.h"
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gmp_cv_func_alloca=yes
+else
+ gmp_cv_func_alloca=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_func_alloca" >&5
+$as_echo "$gmp_cv_func_alloca" >&6; }
+if test $gmp_cv_func_alloca = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to allocate temporary memory" >&5
+$as_echo_n "checking how to allocate temporary memory... " >&6; }
+if ${gmp_cv_option_alloca+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $enable_alloca in
+ yes)
+ gmp_cv_option_alloca=alloca
+ ;;
+ no)
+ gmp_cv_option_alloca=malloc-reentrant
+ ;;
+ reentrant | notreentrant)
+ case $gmp_cv_func_alloca in
+ yes) gmp_cv_option_alloca=alloca ;;
+ *) gmp_cv_option_alloca=malloc-$enable_alloca ;;
+ esac
+ ;;
+ *)
+ gmp_cv_option_alloca=$enable_alloca
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_option_alloca" >&5
+$as_echo "$gmp_cv_option_alloca" >&6; }
+
+
+
+case $gmp_cv_option_alloca in
+ alloca)
+ if test $gmp_cv_func_alloca = no; then
+ as_fn_error $? "--enable-alloca=alloca specified, but alloca not available" "$LINENO" 5
+ fi
+ $as_echo "#define WANT_TMP_ALLOCA 1" >>confdefs.h
+
+ TAL_OBJECT=tal-reent$U.lo
+ ;;
+ malloc-reentrant)
+ $as_echo "#define WANT_TMP_REENTRANT 1" >>confdefs.h
+
+ TAL_OBJECT=tal-reent$U.lo
+ ;;
+ malloc-notreentrant)
+ $as_echo "#define WANT_TMP_NOTREENTRANT 1" >>confdefs.h
+
+ TAL_OBJECT=tal-notreent$U.lo
+ ;;
+ debug)
+ $as_echo "#define WANT_TMP_DEBUG 1" >>confdefs.h
+
+ TAL_OBJECT=tal-debug$U.lo
+ ;;
+ *)
+ # checks at the start of configure.in should protect us
+ as_fn_error $? "unrecognised --enable-alloca=$gmp_cv_option_alloca" "$LINENO" 5
+ ;;
+esac
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+#define __GMP_WITHIN_CONFIGURE 1 /* ignore template stuff */
+#define GMP_NAIL_BITS $GMP_NAIL_BITS
+#define GMP_LIMB_BITS 123
+$DEFN_LONG_LONG_LIMB
+#include "$srcdir/gmp-h.in"
+
+#if ! _GMP_H_HAVE_FILE
+die die die
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: gmp.h doesnt recognise <stdio.h>, FILE prototypes will be unavailable" >&5
+$as_echo "$as_me: WARNING: gmp.h doesnt recognise <stdio.h>, FILE prototypes will be unavailable" >&2;}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define HAVE_LIMB_BIG_ENDIAN 1" >>confdefs.h
+
+
+echo "define_not_for_expansion(\`HAVE_LIMB_BIG_ENDIAN')" >> $gmp_tmpconfigm4p
+;; #(
+ no)
+ $as_echo "#define HAVE_LIMB_LITTLE_ENDIAN 1" >>confdefs.h
+
+
+echo "define_not_for_expansion(\`HAVE_LIMB_LITTLE_ENDIAN')" >> $gmp_tmpconfigm4p
+
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ : ;;
+ esac
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking format of \`double' floating point" >&5
+$as_echo_n "checking format of \`double' floating point... " >&6; }
+if ${gmp_cv_c_double_format+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gmp_cv_c_double_format=unknown
+cat >conftest.c <<\EOF
+struct foo {
+ char before[8];
+ double x;
+ char after[8];
+};
+extern struct foo foo;
+struct foo foo = {
+ { '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
+ -123456789.0,
+ { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' },
+};
+EOF
+gmp_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >&5 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+cat >conftest.awk <<\EOF
+
+BEGIN {
+ found = 0
+}
+
+{
+ for (f = 2; f <= NF; f++)
+ {
+ for (i = 0; i < 23; i++)
+ got[i] = got[i+1];
+ got[23] = $f;
+
+ # match the special begin and end sequences
+ if (got[0] != "001") continue
+ if (got[1] != "043") continue
+ if (got[2] != "105") continue
+ if (got[3] != "147") continue
+ if (got[4] != "211") continue
+ if (got[5] != "253") continue
+ if (got[6] != "315") continue
+ if (got[7] != "357") continue
+ if (got[16] != "376") continue
+ if (got[17] != "334") continue
+ if (got[18] != "272") continue
+ if (got[19] != "230") continue
+ if (got[20] != "166") continue
+ if (got[21] != "124") continue
+ if (got[22] != "062") continue
+ if (got[23] != "020") continue
+
+ saw = " (" got[8] " " got[9] " " got[10] " " got[11] " " got[12] " " got[13] " " got[14] " " got[15] ")"
+
+ if (got[8] == "000" && \
+ got[9] == "000" && \
+ got[10] == "000" && \
+ got[11] == "124" && \
+ got[12] == "064" && \
+ got[13] == "157" && \
+ got[14] == "235" && \
+ got[15] == "301")
+ {
+ print "IEEE little endian"
+ found = 1
+ exit
+ }
+
+ # Little endian with the two 4-byte halves swapped, as used by ARM
+ # when the chip is in little endian mode.
+ #
+ if (got[8] == "064" && \
+ got[9] == "157" && \
+ got[10] == "235" && \
+ got[11] == "301" && \
+ got[12] == "000" && \
+ got[13] == "000" && \
+ got[14] == "000" && \
+ got[15] == "124")
+ {
+ print "IEEE little endian, swapped halves"
+ found = 1
+ exit
+ }
+
+ # gcc 2.95.4 on one GNU/Linux ARM system was seen generating 000 in
+ # the last byte, whereas 124 is correct. Not sure where the bug
+ # actually lies, but a running program didn't seem to get a full
+ # mantissa worth of working bits.
+ #
+ # We match this case explicitly so we can give a nice result message,
+ # but we deliberately exclude it from the normal IEEE double setups
+ # since it's too broken.
+ #
+ if (got[8] == "064" && \
+ got[9] == "157" && \
+ got[10] == "235" && \
+ got[11] == "301" && \
+ got[12] == "000" && \
+ got[13] == "000" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "bad ARM software floats"
+ found = 1
+ exit
+ }
+
+ if (got[8] == "301" && \
+ got[9] == "235" && \
+ got[10] == "157" && \
+ got[11] == "064" && \
+ got[12] == "124" && \
+ got[13] == "000" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "IEEE big endian"
+ found = 1
+ exit
+ }
+
+ if (got[8] == "353" && \
+ got[9] == "315" && \
+ got[10] == "242" && \
+ got[11] == "171" && \
+ got[12] == "000" && \
+ got[13] == "240" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "VAX D"
+ found = 1
+ exit
+ }
+
+ if (got[8] == "275" && \
+ got[9] == "301" && \
+ got[10] == "064" && \
+ got[11] == "157" && \
+ got[12] == "000" && \
+ got[13] == "124" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "VAX G"
+ found = 1
+ exit
+ }
+
+ if (got[8] == "300" && \
+ got[9] == "033" && \
+ got[10] == "353" && \
+ got[11] == "171" && \
+ got[12] == "242" && \
+ got[13] == "240" && \
+ got[14] == "000" && \
+ got[15] == "000")
+ {
+ print "Cray CFP"
+ found = 1
+ exit
+ }
+ }
+}
+
+END {
+ if (! found)
+ print "unknown", saw
+}
+
+EOF
+ gmp_cv_c_double_format=`od -b conftest.$OBJEXT | $AWK -f conftest.awk`
+ case $gmp_cv_c_double_format in
+ unknown*)
+ echo "cannot match anything, conftest.$OBJEXT contains" >&5
+ od -b conftest.$OBJEXT >&5
+ ;;
+ esac
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: oops, cannot compile test program" >&5
+$as_echo "$as_me: WARNING: oops, cannot compile test program" >&2;}
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_c_double_format" >&5
+$as_echo "$gmp_cv_c_double_format" >&6; }
+
+
+
+case $gmp_cv_c_double_format in
+ "IEEE big endian")
+ $as_echo "#define HAVE_DOUBLE_IEEE_BIG_ENDIAN 1" >>confdefs.h
+
+
+echo "define_not_for_expansion(\`HAVE_DOUBLE_IEEE_BIG_ENDIAN')" >> $gmp_tmpconfigm4p
+
+ ;;
+ "IEEE little endian")
+ $as_echo "#define HAVE_DOUBLE_IEEE_LITTLE_ENDIAN 1" >>confdefs.h
+
+
+echo "define_not_for_expansion(\`HAVE_DOUBLE_IEEE_LITTLE_ENDIAN')" >> $gmp_tmpconfigm4p
+
+ ;;
+ "IEEE little endian, swapped halves")
+ $as_echo "#define HAVE_DOUBLE_IEEE_LITTLE_SWAPPED 1" >>confdefs.h
+ ;;
+ "VAX D")
+ $as_echo "#define HAVE_DOUBLE_VAX_D 1" >>confdefs.h
+ ;;
+ "VAX G")
+ $as_echo "#define HAVE_DOUBLE_VAX_G 1" >>confdefs.h
+ ;;
+ "Cray CFP")
+ $as_echo "#define HAVE_DOUBLE_CRAY_CFP 1" >>confdefs.h
+ ;;
+ "bad ARM software floats")
+ ;;
+ unknown*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not determine float format." >&5
+$as_echo "$as_me: WARNING: Could not determine float format." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Conversions to and from \"double\" may be slow." >&5
+$as_echo "$as_me: WARNING: Conversions to and from \"double\" may be slow." >&2;}
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: oops, unrecognised float format: $gmp_cv_c_double_format" >&5
+$as_echo "$as_me: WARNING: oops, unrecognised float format: $gmp_cv_c_double_format" >&2;}
+ ;;
+esac
+
+
+
+# Reasons for testing:
+# alarm - not in mingw
+# attr_get - IRIX specific
+# clock_gettime - not in glibc 2.2.4, only very recent systems
+# cputime - not in glibc
+# getsysinfo - OSF specific
+# getrusage - not in mingw
+# gettimeofday - not in mingw
+# mmap - not in mingw, djgpp
+# nl_langinfo - X/Open standard only, not in djgpp for instance
+# obstack_vprintf - glibc specific
+# processor_info - solaris specific
+# pstat_getprocessor - HPUX specific (10.x and up)
+# raise - an ANSI-ism, though probably almost universal by now
+# read_real_time - AIX specific
+# sigaction - not in mingw
+# sigaltstack - not in mingw, or old AIX (reputedly)
+# sigstack - not in mingw
+# strerror - not in SunOS
+# strnlen - glibc extension (some other systems too)
+# syssgi - IRIX specific
+# times - not in mingw
+#
+# AC_FUNC_STRNLEN is not used because we don't want the AC_LIBOBJ
+# replacement setups it gives. It detects a faulty strnlen on AIX, but
+# missing out on that test is ok since our only use of strnlen is in
+# __gmp_replacement_vsnprintf which is not required on AIX since it has a
+# vsnprintf.
+#
+for ac_func in alarm attr_get clock cputime getpagesize getrusage gettimeofday getsysinfo localeconv memset mmap mprotect nl_langinfo obstack_vprintf popen processor_info pstat_getprocessor raise read_real_time sigaction sigaltstack sigstack syssgi strchr strerror strnlen strtol strtoul sysconf sysctl sysctlbyname times
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# clock_gettime is in librt on *-*-osf5.1 and on glibc, so att -lrt to
+# TUNE_LIBS if needed. On linux (tested on x86_32, 2.6.26),
+# clock_getres reports ns accuracy, while in a quick test on osf
+# clock_getres said only 1 millisecond.
+
+old_LIBS="$LIBS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
+$as_echo_n "checking for library containing clock_gettime... " >&6; }
+if ${ac_cv_search_clock_gettime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' rt; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_clock_gettime=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_clock_gettime+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_clock_gettime+:} false; then :
+
+else
+ ac_cv_search_clock_gettime=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
+$as_echo "$ac_cv_search_clock_gettime" >&6; }
+ac_res=$ac_cv_search_clock_gettime
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+
+$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
+
+fi
+
+TUNE_LIBS="$LIBS"
+LIBS="$old_LIBS"
+
+
+
+ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf"
+if test "x$ac_cv_func_vsnprintf" = xyes; then :
+ gmp_vsnprintf_exists=yes
+else
+ gmp_vsnprintf_exists=no
+fi
+
+if test "$gmp_vsnprintf_exists" = no; then
+ gmp_cv_func_vsnprintf=no
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vsnprintf works" >&5
+$as_echo_n "checking whether vsnprintf works... " >&6; }
+if ${gmp_cv_func_vsnprintf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gmp_cv_func_vsnprintf=yes
+ for i in 'return check ("hello world");' 'int n; return check ("%nhello world", &n);'; do
+ if test "$cross_compiling" = yes; then :
+ gmp_cv_func_vsnprintf=probably; break
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <string.h> /* for strcmp */
+#include <stdio.h> /* for vsnprintf */
+
+#include <stdarg.h>
+
+int
+check (const char *fmt, ...)
+{
+ static char buf[128];
+ va_list ap;
+ int ret;
+
+ va_start (ap, fmt);
+
+ ret = vsnprintf (buf, 4, fmt, ap);
+
+ if (strcmp (buf, "hel") != 0)
+ return 1;
+
+ /* allowed return values */
+ if (ret != -1 && ret != 3 && ret != 11)
+ return 2;
+
+ return 0;
+}
+
+int
+main ()
+{
+$i
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ :
+else
+ gmp_cv_func_vsnprintf=no; break
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_func_vsnprintf" >&5
+$as_echo "$gmp_cv_func_vsnprintf" >&6; }
+ if test "$gmp_cv_func_vsnprintf" = probably; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot check for properly working vsnprintf when cross compiling, will assume it's ok" >&5
+$as_echo "$as_me: WARNING: cannot check for properly working vsnprintf when cross compiling, will assume it's ok" >&2;}
+ fi
+ if test "$gmp_cv_func_vsnprintf" != no; then
+
+$as_echo "#define HAVE_VSNPRINTF 1" >>confdefs.h
+
+ fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sscanf needs writable input" >&5
+$as_echo_n "checking whether sscanf needs writable input... " >&6; }
+if ${gmp_cv_func_sscanf_writable_input+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-hpux9 | *-*-hpux9.*)
+ gmp_cv_func_sscanf_writable_input=yes ;;
+ *) gmp_cv_func_sscanf_writable_input=no ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_func_sscanf_writable_input" >&5
+$as_echo "$gmp_cv_func_sscanf_writable_input" >&6; }
+case $gmp_cv_func_sscanf_writable_input in
+ yes)
+$as_echo "#define SSCANF_WRITABLE_INPUT 1" >>confdefs.h
+ ;;
+ no) ;;
+ *) as_fn_error $? "unrecognised \$gmp_cv_func_sscanf_writable_input" "$LINENO" 5 ;;
+esac
+
+
+# Reasons for checking:
+# pst_processor psp_iticksperclktick - not in hpux 9
+#
+ac_fn_c_check_member "$LINENO" "struct pst_processor" "psp_iticksperclktick" "ac_cv_member_struct_pst_processor_psp_iticksperclktick" "#include <sys/pstat.h>
+"
+if test "x$ac_cv_member_struct_pst_processor_psp_iticksperclktick" = xyes; then :
+
+$as_echo "#define HAVE_PSP_ITICKSPERCLKTICK 1" >>confdefs.h
+
+fi
+
+
+# C++ tests, when required
+#
+if test $enable_cxx = yes; then
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ # Reasons for testing:
+ # <sstream> - not in g++ 2.95.2
+ # std::locale - not in g++ 2.95.4
+ #
+
+for ac_header in sstream
+do :
+ ac_fn_cxx_check_header_mongrel "$LINENO" "sstream" "ac_cv_header_sstream" "$ac_includes_default"
+if test "x$ac_cv_header_sstream" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SSTREAM 1
+_ACEOF
+
+fi
+
+done
+
+ ac_fn_cxx_check_type "$LINENO" "std::locale" "ac_cv_type_std__locale" "#include <locale>
+"
+if test "x$ac_cv_type_std__locale" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STD__LOCALE 1
+_ACEOF
+
+
+fi
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+
+# Pick the correct source files in $path and link them to mpn/.
+# $gmp_mpn_functions lists all functions we need.
+#
+# The rule is to find a file with the function name and a .asm, .S,
+# .s, or .c extension. Certain multi-function files with special names
+# can provide some functions too. (mpn/Makefile.am passes
+# -DOPERATION_<func> to get them to generate the right code.)
+
+# Note: $gmp_mpn_functions must have mod_1 before pre_mod_1 so the former
+# can optionally provide the latter as an extra entrypoint. Likewise
+# divrem_1 and pre_divrem_1.
+
+gmp_mpn_functions_optional="umul udiv \
+ invert_limb sqr_diagonal sqr_diag_addlsh1 \
+ mul_2 mul_3 mul_4 mul_5 mul_6 \
+ addmul_2 addmul_3 addmul_4 addmul_5 addmul_6 addmul_7 addmul_8 \
+ addlsh1_n sublsh1_n rsblsh1_n rsh1add_n rsh1sub_n \
+ addlsh2_n sublsh2_n rsblsh2_n \
+ addlsh_n sublsh_n rsblsh_n \
+ add_n_sub_n addaddmul_1msb0"
+
+gmp_mpn_functions="$extra_functions \
+ add add_1 add_n sub sub_1 sub_n cnd_add_n cnd_sub_n neg com \
+ mul_1 addmul_1 submul_1 \
+ add_err1_n add_err2_n add_err3_n sub_err1_n sub_err2_n sub_err3_n \
+ lshift rshift dive_1 diveby3 divis divrem divrem_1 divrem_2 \
+ fib2_ui mod_1 mod_34lsub1 mode1o pre_divrem_1 pre_mod_1 dump \
+ mod_1_1 mod_1_2 mod_1_3 mod_1_4 lshiftc \
+ mul mul_fft mul_n sqr mul_basecase sqr_basecase nussbaumer_mul \
+ mulmid_basecase toom42_mulmid mulmid_n mulmid \
+ random random2 pow_1 \
+ rootrem sqrtrem sizeinbase get_str set_str \
+ scan0 scan1 popcount hamdist cmp \
+ perfsqr perfpow \
+ gcd_1 gcd gcdext_1 gcdext gcd_subdiv_step \
+ gcdext_lehmer \
+ div_q tdiv_qr jacbase jacobi_2 jacobi get_d \
+ matrix22_mul matrix22_mul1_inverse_vector \
+ hgcd_matrix hgcd2 hgcd_step hgcd_reduce hgcd hgcd_appr \
+ hgcd2_jacobi hgcd_jacobi \
+ mullo_n mullo_basecase \
+ toom22_mul toom32_mul toom42_mul toom52_mul toom62_mul \
+ toom33_mul toom43_mul toom53_mul toom54_mul toom63_mul \
+ toom44_mul \
+ toom6h_mul toom6_sqr toom8h_mul toom8_sqr \
+ toom_couple_handling \
+ toom2_sqr toom3_sqr toom4_sqr \
+ toom_eval_dgr3_pm1 toom_eval_dgr3_pm2 \
+ toom_eval_pm1 toom_eval_pm2 toom_eval_pm2exp toom_eval_pm2rexp \
+ toom_interpolate_5pts toom_interpolate_6pts toom_interpolate_7pts \
+ toom_interpolate_8pts toom_interpolate_12pts toom_interpolate_16pts \
+ invertappr invert binvert mulmod_bnm1 sqrmod_bnm1 \
+ div_qr_1 div_qr_1n_pi1 \
+ div_qr_2 div_qr_2n_pi1 div_qr_2u_pi1 \
+ sbpi1_div_q sbpi1_div_qr sbpi1_divappr_q \
+ dcpi1_div_q dcpi1_div_qr dcpi1_divappr_q \
+ mu_div_qr mu_divappr_q mu_div_q \
+ bdiv_q_1 \
+ sbpi1_bdiv_q sbpi1_bdiv_qr \
+ dcpi1_bdiv_q dcpi1_bdiv_qr \
+ mu_bdiv_q mu_bdiv_qr \
+ bdiv_q bdiv_qr broot brootinv bsqrt bsqrtinv \
+ divexact bdiv_dbm1c redc_1 redc_2 redc_n powm powlo sec_powm \
+ sec_mul sec_sqr sec_div_qr sec_div_r sec_pi1_div_qr sec_pi1_div_r \
+ sec_add_1 sec_sub_1 sec_invert \
+ trialdiv remove \
+ and_n andn_n nand_n ior_n iorn_n nior_n xor_n xnor_n \
+ copyi copyd zero sec_tabselect \
+ comb_tables \
+ $gmp_mpn_functions_optional"
+
+
+
+# the list of all object files used by mpn/Makefile.in and the
+# top-level Makefile.in, respectively
+mpn_objects=
+mpn_objs_in_libgmp=
+
+# links from the sources, to be removed by "make distclean"
+gmp_srclinks=
+
+
+# mpn_relative_top_srcdir is $top_srcdir, but for use from within the mpn
+# build directory. If $srcdir is relative then we use a relative path too,
+# so the two trees can be moved together.
+case $srcdir in
+ [\\/]* | ?:[\\/]*) # absolute, as per autoconf
+ mpn_relative_top_srcdir=$srcdir ;;
+ *) # relative
+ mpn_relative_top_srcdir=../$srcdir ;;
+esac
+
+
+
+
+
+
+# Fat binary setups.
+#
+# We proceed through each $fat_path directory, and look for $fat_function
+# routines there. Those found are incorporated in the build by generating a
+# little mpn/<foo>.asm or mpn/<foo>.c file in the build directory, with
+# suitable function renaming, and adding that to $mpn_objects (the same as a
+# normal mpn file).
+#
+# fat.h is generated with macros to let internal calls to each $fat_function
+# go directly through __gmpn_cpuvec, plus macros and declarations helping to
+# setup that structure, on a per-directory basis ready for
+# mpn/<cpu>/fat/fat.c.
+#
+# fat.h includes thresholds listed in $fat_thresholds, extracted from
+# gmp-mparam.h in each directory. An overall maximum for each threshold is
+# established, for use in making fixed size arrays of temporary space.
+# (Eg. MUL_TOOM33_THRESHOLD_LIMIT used by mpn/generic/mul.c.)
+#
+# It'd be possible to do some of this manually, but when there's more than a
+# few functions and a few directories it becomes very tedious, and very
+# prone to having some routine accidentally omitted. On that basis it seems
+# best to automate as much as possible, even if the code to do so is a bit
+# ugly.
+#
+
+if test -n "$fat_path"; then
+ # Usually the mpn build directory is created with mpn/Makefile
+ # instantiation, but we want to write to it sooner.
+ mkdir mpn 2>/dev/null
+
+ echo "/* fat.h - setups for fat binaries." >fat.h
+ echo " Generated by configure - DO NOT EDIT. */" >>fat.h
+
+
+$as_echo "#define WANT_FAT_BINARY 1" >>confdefs.h
+
+
+echo 'define(<WANT_FAT_BINARY>, <yes>)' >>$gmp_tmpconfigm4
+
+
+ # Don't want normal copies of fat functions
+ for tmp_fn in $fat_functions; do
+ remove_from_list_tmp=
+for remove_from_list_i in $gmp_mpn_functions; do
+ if test $remove_from_list_i = $tmp_fn; then :;
+ else
+ remove_from_list_tmp="$remove_from_list_tmp $remove_from_list_i"
+ fi
+done
+gmp_mpn_functions=$remove_from_list_tmp
+
+ remove_from_list_tmp=
+for remove_from_list_i in $gmp_mpn_functions_optional; do
+ if test $remove_from_list_i = $tmp_fn; then :;
+ else
+ remove_from_list_tmp="$remove_from_list_tmp $remove_from_list_i"
+ fi
+done
+gmp_mpn_functions_optional=$remove_from_list_tmp
+
+ done
+
+ for tmp_fn in $fat_functions; do
+ case $tmp_fn in
+ dive_1) tmp_fbase=divexact_1 ;;
+ diveby3) tmp_fbase=divexact_by3c ;;
+ pre_divrem_1) tmp_fbase=preinv_divrem_1 ;;
+ mode1o) tmp_fbase=modexact_1c_odd ;;
+ pre_mod_1) tmp_fbase=preinv_mod_1 ;;
+ mod_1_1) tmp_fbase=mod_1_1p ;;
+ mod_1_1_cps) tmp_fbase=mod_1_1p_cps ;;
+ mod_1_2) tmp_fbase=mod_1s_2p ;;
+ mod_1_2_cps) tmp_fbase=mod_1s_2p_cps ;;
+ mod_1_3) tmp_fbase=mod_1s_3p ;;
+ mod_1_3_cps) tmp_fbase=mod_1s_3p_cps ;;
+ mod_1_4) tmp_fbase=mod_1s_4p ;;
+ mod_1_4_cps) tmp_fbase=mod_1s_4p_cps ;;
+ *) tmp_fbase=$tmp_fn ;;
+esac
+
+ echo "
+#ifndef OPERATION_$tmp_fn
+#undef mpn_$tmp_fbase
+#define mpn_$tmp_fbase (*__gmpn_cpuvec.$tmp_fbase)
+#endif
+DECL_$tmp_fbase (__MPN(${tmp_fbase}_init));" >>fat.h
+ # encourage various macros to use fat functions
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NATIVE_mpn_$tmp_fbase 1
+_ACEOF
+
+ done
+
+ echo "" >>fat.h
+ echo "/* variable thresholds */" >>fat.h
+ for tmp_tn in $fat_thresholds; do
+ echo "#undef $tmp_tn" >>fat.h
+ echo "#define $tmp_tn CPUVEC_THRESHOLD (`echo $tmp_tn | tr [A-Z] [a-z]`)" >>fat.h
+ done
+
+ echo "
+/* Copy all fields into __gmpn_cpuvec.
+ memcpy is not used because it might operate byte-wise (depending on its
+ implementation), and we need the function pointer writes to be atomic.
+ "volatile" discourages the compiler from trying to optimize this. */
+#define CPUVEC_INSTALL(vec) \\
+ do { \\
+ volatile struct cpuvec_t *p = &__gmpn_cpuvec; \\" >>fat.h
+ for tmp_fn in $fat_functions; do
+ case $tmp_fn in
+ dive_1) tmp_fbase=divexact_1 ;;
+ diveby3) tmp_fbase=divexact_by3c ;;
+ pre_divrem_1) tmp_fbase=preinv_divrem_1 ;;
+ mode1o) tmp_fbase=modexact_1c_odd ;;
+ pre_mod_1) tmp_fbase=preinv_mod_1 ;;
+ mod_1_1) tmp_fbase=mod_1_1p ;;
+ mod_1_1_cps) tmp_fbase=mod_1_1p_cps ;;
+ mod_1_2) tmp_fbase=mod_1s_2p ;;
+ mod_1_2_cps) tmp_fbase=mod_1s_2p_cps ;;
+ mod_1_3) tmp_fbase=mod_1s_3p ;;
+ mod_1_3_cps) tmp_fbase=mod_1s_3p_cps ;;
+ mod_1_4) tmp_fbase=mod_1s_4p ;;
+ mod_1_4_cps) tmp_fbase=mod_1s_4p_cps ;;
+ *) tmp_fbase=$tmp_fn ;;
+esac
+
+ echo " p->$tmp_fbase = vec.$tmp_fbase; \\" >>fat.h
+ done
+ for tmp_tn in $fat_thresholds; do
+ tmp_field_name=`echo $tmp_tn | tr [A-Z] [a-z]`
+ echo " p->$tmp_field_name = vec.$tmp_field_name; \\" >>fat.h
+ done
+ echo " } while (0)" >>fat.h
+
+ echo "
+/* A helper to check all fields are filled. */
+#define ASSERT_CPUVEC(vec) \\
+ do { \\" >>fat.h
+ for tmp_fn in $fat_functions; do
+ case $tmp_fn in
+ dive_1) tmp_fbase=divexact_1 ;;
+ diveby3) tmp_fbase=divexact_by3c ;;
+ pre_divrem_1) tmp_fbase=preinv_divrem_1 ;;
+ mode1o) tmp_fbase=modexact_1c_odd ;;
+ pre_mod_1) tmp_fbase=preinv_mod_1 ;;
+ mod_1_1) tmp_fbase=mod_1_1p ;;
+ mod_1_1_cps) tmp_fbase=mod_1_1p_cps ;;
+ mod_1_2) tmp_fbase=mod_1s_2p ;;
+ mod_1_2_cps) tmp_fbase=mod_1s_2p_cps ;;
+ mod_1_3) tmp_fbase=mod_1s_3p ;;
+ mod_1_3_cps) tmp_fbase=mod_1s_3p_cps ;;
+ mod_1_4) tmp_fbase=mod_1s_4p ;;
+ mod_1_4_cps) tmp_fbase=mod_1s_4p_cps ;;
+ *) tmp_fbase=$tmp_fn ;;
+esac
+
+ echo " ASSERT (vec.$tmp_fbase != NULL); \\" >>fat.h
+ done
+ for tmp_tn in $fat_thresholds; do
+ tmp_field_name=`echo $tmp_tn | tr [A-Z] [a-z]`
+ echo " ASSERT (vec.$tmp_field_name != 0); \\" >>fat.h
+ done
+ echo " } while (0)" >>fat.h
+
+ echo "
+/* Call ITERATE(field) for each fat threshold field. */
+#define ITERATE_FAT_THRESHOLDS() \\
+ do { \\" >>fat.h
+ for tmp_tn in $fat_thresholds; do
+ tmp_field_name=`echo $tmp_tn | tr [A-Z] [a-z]`
+ echo " ITERATE ($tmp_tn, $tmp_field_name); \\" >>fat.h
+ done
+ echo " } while (0)" >>fat.h
+
+ for tmp_dir in $fat_path; do
+ CPUVEC_SETUP=
+ THRESH_ASM_SETUP=
+ echo "" >>fat.h
+ tmp_suffix=`echo $tmp_dir | sed -e '/\//s:^[^/]*/::' -e 's:[\\/]:_:g'`
+
+ # In order to keep names unique on a DOS 8.3 filesystem, use a prefix
+ # (rather than a suffix) for the generated file names, and abbreviate.
+ case $tmp_suffix in
+ pentium) tmp_prefix=p ;;
+ pentium_mmx) tmp_prefix=pm ;;
+ p6_mmx) tmp_prefix=p2 ;;
+ p6_p3mmx) tmp_prefix=p3 ;;
+ pentium4) tmp_prefix=p4 ;;
+ pentium4_mmx) tmp_prefix=p4m ;;
+ pentium4_sse2) tmp_prefix=p4s ;;
+ k6_mmx) tmp_prefix=k6m ;;
+ k6_k62mmx) tmp_prefix=k62 ;;
+ k7_mmx) tmp_prefix=k7m ;;
+ *) tmp_prefix=$tmp_suffix ;;
+ esac
+
+ # Extract desired thresholds from gmp-mparam.h file in this directory,
+ # if present.
+ tmp_mparam=$srcdir/mpn/$tmp_dir/gmp-mparam.h
+ if test -f $tmp_mparam; then
+ for tmp_tn in $fat_thresholds; do
+ tmp_thresh=`sed -n "s/^#define $tmp_tn[ ]*\\([0-9][0-9]*\\).*$/\\1/p" $tmp_mparam`
+ if test -n "$tmp_thresh"; then
+ THRESH_ASM_SETUP="${THRESH_ASM_SETUP}define($tmp_tn,$tmp_thresh)
+"
+ CPUVEC_SETUP="$CPUVEC_SETUP decided_cpuvec.`echo $tmp_tn | tr [A-Z] [a-z]` = $tmp_thresh; \\
+"
+ eval tmp_limit=\$${tmp_tn}_LIMIT
+ if test -z "$tmp_limit"; then
+ tmp_limit=0
+ fi
+ if test $tmp_thresh -gt $tmp_limit; then
+ eval ${tmp_tn}_LIMIT=$tmp_thresh
+ fi
+ fi
+ done
+ fi
+
+ for tmp_fn in $fat_functions; do
+ # functions that can be provided by multi-function files
+tmp_mulfunc=
+case $tmp_fn in
+ add_n|sub_n) tmp_mulfunc="aors_n" ;;
+ add_err1_n|sub_err1_n)
+ tmp_mulfunc="aors_err1_n" ;;
+ add_err2_n|sub_err2_n)
+ tmp_mulfunc="aors_err2_n" ;;
+ add_err3_n|sub_err3_n)
+ tmp_mulfunc="aors_err3_n" ;;
+ cnd_add_n|cnd_sub_n) tmp_mulfunc="cnd_aors_n" ;;
+ sec_add_1|sec_sub_1) tmp_mulfunc="sec_aors_1" ;;
+ addmul_1|submul_1) tmp_mulfunc="aorsmul_1" ;;
+ mul_2|addmul_2) tmp_mulfunc="aormul_2" ;;
+ mul_3|addmul_3) tmp_mulfunc="aormul_3" ;;
+ mul_4|addmul_4) tmp_mulfunc="aormul_4" ;;
+ popcount|hamdist) tmp_mulfunc="popham" ;;
+ and_n|andn_n|nand_n | ior_n|iorn_n|nior_n | xor_n|xnor_n)
+ tmp_mulfunc="logops_n" ;;
+ lshift|rshift) tmp_mulfunc="lorrshift";;
+ addlsh1_n)
+ tmp_mulfunc="aorslsh1_n aorrlsh1_n aorsorrlsh1_n";;
+ sublsh1_n)
+ tmp_mulfunc="aorslsh1_n sorrlsh1_n aorsorrlsh1_n";;
+ rsblsh1_n)
+ tmp_mulfunc="aorrlsh1_n sorrlsh1_n aorsorrlsh1_n";;
+ addlsh2_n)
+ tmp_mulfunc="aorslsh2_n aorrlsh2_n aorsorrlsh2_n";;
+ sublsh2_n)
+ tmp_mulfunc="aorslsh2_n sorrlsh2_n aorsorrlsh2_n";;
+ rsblsh2_n)
+ tmp_mulfunc="aorrlsh2_n sorrlsh2_n aorsorrlsh2_n";;
+ addlsh_n)
+ tmp_mulfunc="aorslsh_n aorrlsh_n aorsorrlsh_n";;
+ sublsh_n)
+ tmp_mulfunc="aorslsh_n sorrlsh_n aorsorrlsh_n";;
+ rsblsh_n)
+ tmp_mulfunc="aorrlsh_n sorrlsh_n aorsorrlsh_n";;
+ rsh1add_n|rsh1sub_n)
+ tmp_mulfunc="rsh1aors_n";;
+ sec_div_qr|sec_div_r)
+ tmp_mulfunc="sec_div";;
+ sec_pi1_div_qr|sec_pi1_div_r)
+ tmp_mulfunc="sec_pi1_div";;
+esac
+
+
+ for tmp_base in $tmp_fn $tmp_mulfunc; do
+ for tmp_ext in asm S s c; do
+ tmp_file=$srcdir/mpn/$tmp_dir/$tmp_base.$tmp_ext
+ if test -f $tmp_file; then
+
+ # If the host uses a non-standard ABI, check if tmp_file supports it
+ #
+ if test -n "$GMP_NONSTD_ABI" && test $tmp_ext != "c"; then
+ abi=`sed -n 's/^[ ]*ABI_SUPPORT(\(.*\))/\1/p' $tmp_file `
+ if echo "$abi" | grep -q "\\b${GMP_NONSTD_ABI}\\b"; then
+ true
+ else
+ continue
+ fi
+ fi
+
+ mpn_objects="$mpn_objects ${tmp_prefix}_$tmp_fn.lo"
+ mpn_objs_in_libgmp="$mpn_objs_in_libgmp mpn/${tmp_prefix}_$tmp_fn.lo"
+
+ case $tmp_fn in
+ dive_1) tmp_fbase=divexact_1 ;;
+ diveby3) tmp_fbase=divexact_by3c ;;
+ pre_divrem_1) tmp_fbase=preinv_divrem_1 ;;
+ mode1o) tmp_fbase=modexact_1c_odd ;;
+ pre_mod_1) tmp_fbase=preinv_mod_1 ;;
+ mod_1_1) tmp_fbase=mod_1_1p ;;
+ mod_1_1_cps) tmp_fbase=mod_1_1p_cps ;;
+ mod_1_2) tmp_fbase=mod_1s_2p ;;
+ mod_1_2_cps) tmp_fbase=mod_1s_2p_cps ;;
+ mod_1_3) tmp_fbase=mod_1s_3p ;;
+ mod_1_3_cps) tmp_fbase=mod_1s_3p_cps ;;
+ mod_1_4) tmp_fbase=mod_1s_4p ;;
+ mod_1_4_cps) tmp_fbase=mod_1s_4p_cps ;;
+ *) tmp_fbase=$tmp_fn ;;
+esac
+
+
+ # carry-in variant, eg. divrem_1c or modexact_1c_odd
+ case $tmp_fbase in
+ *_1*) tmp_fbasec=`echo $tmp_fbase | sed 's/_1/_1c/'` ;;
+ *) tmp_fbasec=${tmp_fbase}c ;;
+ esac
+
+ # Create a little file doing an include from srcdir. The
+ # OPERATION and renamings aren't all needed all the time, but
+ # they don't hurt if unused.
+ #
+ # FIXME: Should generate these via config.status commands.
+ # Would need them all in one AC_CONFIG_COMMANDS though, since
+ # that macro doesn't accept a set of separate commands generated
+ # by shell code.
+ #
+ case $tmp_ext in
+ asm)
+ # hide the d-n-l from autoconf's error checking
+ tmp_d_n_l=d""nl
+ echo "$tmp_d_n_l mpn_$tmp_fbase - from $tmp_dir directory for fat binary.
+$tmp_d_n_l Generated by configure - DO NOT EDIT.
+
+define(OPERATION_$tmp_fn)
+define(__gmpn_$tmp_fbase, __gmpn_${tmp_fbase}_$tmp_suffix)
+define(__gmpn_$tmp_fbasec,__gmpn_${tmp_fbasec}_${tmp_suffix})
+define(__gmpn_preinv_${tmp_fbase},__gmpn_preinv_${tmp_fbase}_${tmp_suffix})
+define(__gmpn_${tmp_fbase}_cps,__gmpn_${tmp_fbase}_cps_${tmp_suffix})
+
+$tmp_d_n_l For k6 and k7 gcd_1 calling their corresponding mpn_modexact_1_odd
+ifdef(\`__gmpn_modexact_1_odd',,
+\`define(__gmpn_modexact_1_odd,__gmpn_modexact_1_odd_${tmp_suffix})')
+
+$THRESH_ASM_SETUP
+include($mpn_relative_top_srcdir/mpn/$tmp_dir/$tmp_base.asm)
+" >mpn/${tmp_prefix}_$tmp_fn.asm
+ ;;
+ c)
+ echo "/* mpn_$tmp_fbase - from $tmp_dir directory for fat binary.
+ Generated by configure - DO NOT EDIT. */
+
+#define OPERATION_$tmp_fn 1
+#define __gmpn_$tmp_fbase __gmpn_${tmp_fbase}_$tmp_suffix
+#define __gmpn_$tmp_fbasec __gmpn_${tmp_fbasec}_${tmp_suffix}
+#define __gmpn_preinv_${tmp_fbase} __gmpn_preinv_${tmp_fbase}_${tmp_suffix}
+#define __gmpn_${tmp_fbase}_cps __gmpn_${tmp_fbase}_cps_${tmp_suffix}
+
+#include \"$mpn_relative_top_srcdir/mpn/$tmp_dir/$tmp_base.c\"
+" >mpn/${tmp_prefix}_$tmp_fn.c
+ ;;
+ esac
+
+ # Prototype, and append to CPUVEC_SETUP for this directory.
+ echo "DECL_$tmp_fbase (__gmpn_${tmp_fbase}_$tmp_suffix);" >>fat.h
+ CPUVEC_SETUP="$CPUVEC_SETUP decided_cpuvec.$tmp_fbase = __gmpn_${tmp_fbase}_${tmp_suffix}; \\
+"
+ # Ditto for any preinv variant (preinv_divrem_1, preinv_mod_1).
+ if grep "^PROLOGUE(mpn_preinv_$tmp_fn)" $tmp_file >/dev/null; then
+ echo "DECL_preinv_$tmp_fbase (__gmpn_preinv_${tmp_fbase}_$tmp_suffix);" >>fat.h
+ CPUVEC_SETUP="$CPUVEC_SETUP decided_cpuvec.preinv_$tmp_fbase = __gmpn_preinv_${tmp_fbase}_${tmp_suffix}; \\
+"
+ fi
+
+ # Ditto for any mod_1...cps variant
+ if grep "^PROLOGUE(mpn_${tmp_fbase}_cps)" $tmp_file >/dev/null; then
+ echo "DECL_${tmp_fbase}_cps (__gmpn_${tmp_fbase}_cps_$tmp_suffix);" >>fat.h
+ CPUVEC_SETUP="$CPUVEC_SETUP decided_cpuvec.${tmp_fbase}_cps = __gmpn_${tmp_fbase}_cps_${tmp_suffix}; \\
+"
+ fi
+ fi
+ done
+ done
+ done
+
+ # Emit CPUVEC_SETUP for this directory
+ echo "" >>fat.h
+ echo "#define CPUVEC_SETUP_$tmp_suffix \\" >>fat.h
+ echo " do { \\" >>fat.h
+ echo "$CPUVEC_SETUP } while (0)" >>fat.h
+ done
+
+ # Emit threshold limits
+ echo "" >>fat.h
+ for tmp_tn in $fat_thresholds; do
+ eval tmp_limit=\$${tmp_tn}_LIMIT
+ echo "#define ${tmp_tn}_LIMIT $tmp_limit" >>fat.h
+ done
+fi
+
+
+# Normal binary setups.
+#
+
+for tmp_ext in asm S s c; do
+ eval found_$tmp_ext=no
+done
+
+for tmp_fn in $gmp_mpn_functions; do
+ for tmp_ext in asm S s c; do
+ test "$no_create" = yes || rm -f mpn/$tmp_fn.$tmp_ext
+ done
+
+ # mpn_preinv_divrem_1 might have been provided by divrem_1.asm, likewise
+ # mpn_preinv_mod_1 by mod_1.asm.
+ case $tmp_fn in
+ pre_divrem_1)
+ if test "$HAVE_NATIVE_mpn_preinv_divrem_1" = yes; then continue; fi ;;
+ pre_mod_1)
+ if test "$HAVE_NATIVE_mpn_preinv_mod_1" = yes; then continue; fi ;;
+ esac
+
+ # functions that can be provided by multi-function files
+tmp_mulfunc=
+case $tmp_fn in
+ add_n|sub_n) tmp_mulfunc="aors_n" ;;
+ add_err1_n|sub_err1_n)
+ tmp_mulfunc="aors_err1_n" ;;
+ add_err2_n|sub_err2_n)
+ tmp_mulfunc="aors_err2_n" ;;
+ add_err3_n|sub_err3_n)
+ tmp_mulfunc="aors_err3_n" ;;
+ cnd_add_n|cnd_sub_n) tmp_mulfunc="cnd_aors_n" ;;
+ sec_add_1|sec_sub_1) tmp_mulfunc="sec_aors_1" ;;
+ addmul_1|submul_1) tmp_mulfunc="aorsmul_1" ;;
+ mul_2|addmul_2) tmp_mulfunc="aormul_2" ;;
+ mul_3|addmul_3) tmp_mulfunc="aormul_3" ;;
+ mul_4|addmul_4) tmp_mulfunc="aormul_4" ;;
+ popcount|hamdist) tmp_mulfunc="popham" ;;
+ and_n|andn_n|nand_n | ior_n|iorn_n|nior_n | xor_n|xnor_n)
+ tmp_mulfunc="logops_n" ;;
+ lshift|rshift) tmp_mulfunc="lorrshift";;
+ addlsh1_n)
+ tmp_mulfunc="aorslsh1_n aorrlsh1_n aorsorrlsh1_n";;
+ sublsh1_n)
+ tmp_mulfunc="aorslsh1_n sorrlsh1_n aorsorrlsh1_n";;
+ rsblsh1_n)
+ tmp_mulfunc="aorrlsh1_n sorrlsh1_n aorsorrlsh1_n";;
+ addlsh2_n)
+ tmp_mulfunc="aorslsh2_n aorrlsh2_n aorsorrlsh2_n";;
+ sublsh2_n)
+ tmp_mulfunc="aorslsh2_n sorrlsh2_n aorsorrlsh2_n";;
+ rsblsh2_n)
+ tmp_mulfunc="aorrlsh2_n sorrlsh2_n aorsorrlsh2_n";;
+ addlsh_n)
+ tmp_mulfunc="aorslsh_n aorrlsh_n aorsorrlsh_n";;
+ sublsh_n)
+ tmp_mulfunc="aorslsh_n sorrlsh_n aorsorrlsh_n";;
+ rsblsh_n)
+ tmp_mulfunc="aorrlsh_n sorrlsh_n aorsorrlsh_n";;
+ rsh1add_n|rsh1sub_n)
+ tmp_mulfunc="rsh1aors_n";;
+ sec_div_qr|sec_div_r)
+ tmp_mulfunc="sec_div";;
+ sec_pi1_div_qr|sec_pi1_div_r)
+ tmp_mulfunc="sec_pi1_div";;
+esac
+
+
+ found=no
+ for tmp_dir in $path; do
+ for tmp_base in $tmp_fn $tmp_mulfunc; do
+ for tmp_ext in asm S s c; do
+ tmp_file=$srcdir/mpn/$tmp_dir/$tmp_base.$tmp_ext
+ if test -f $tmp_file; then
+
+ # For a nails build, check if the file supports our nail bits.
+ # Generic code always supports all nails.
+ #
+ # FIXME: When a multi-function file is selected to provide one of
+ # the nails-neutral routines, like logops_n for and_n, the
+ # PROLOGUE grepping will create HAVE_NATIVE_mpn_<foo> defines for
+ # all functions in that file, even if they haven't all been
+ # nailified. Not sure what to do about this, it's only really a
+ # problem for logops_n, and it's not too terrible to insist those
+ # get nailified always.
+ #
+ if test $GMP_NAIL_BITS != 0 && test $tmp_dir != generic; then
+ case $tmp_fn in
+ and_n | ior_n | xor_n | andn_n | \
+ copyi | copyd | \
+ popcount | hamdist | \
+ udiv | udiv_w_sdiv | umul | \
+ cntlz | invert_limb)
+ # these operations are either unaffected by nails or defined
+ # to operate on full limbs
+ ;;
+ *)
+ nails=`sed -n 's/^[ ]*NAILS_SUPPORT(\(.*\))/\1/p' $tmp_file `
+ for n in $nails; do
+ case $n in
+ *-*)
+ n_start=`echo "$n" | sed -n 's/\(.*\)-.*/\1/p'`
+ n_end=`echo "$n" | sed -n 's/.*-\(.*\)/\1/p'`
+ ;;
+ *)
+ n_start=$n
+ n_end=$n
+ ;;
+ esac
+ if test $GMP_NAIL_BITS -ge $n_start && test $GMP_NAIL_BITS -le $n_end; then
+ found=yes
+ break
+ fi
+ done
+ if test $found != yes; then
+ continue
+ fi
+ ;;
+ esac
+ fi
+
+ # If the host uses a non-standard ABI, check if tmp_file supports it
+ #
+ if test -n "$GMP_NONSTD_ABI" && test $tmp_ext != "c"; then
+ abi=`sed -n 's/^[ ]*ABI_SUPPORT(\(.*\))/\1/p' $tmp_file `
+ if echo "$abi" | grep -q "\\b${GMP_NONSTD_ABI}\\b"; then
+ true
+ else
+ continue
+ fi
+ fi
+
+ found=yes
+ eval found_$tmp_ext=yes
+
+ if test $tmp_ext = c; then
+ tmp_u='$U'
+ else
+ tmp_u=
+ fi
+
+ mpn_objects="$mpn_objects $tmp_fn$tmp_u.lo"
+ mpn_objs_in_libgmp="$mpn_objs_in_libgmp mpn/$tmp_fn$tmp_u.lo"
+ ac_config_links="$ac_config_links mpn/$tmp_fn.$tmp_ext:mpn/$tmp_dir/$tmp_base.$tmp_ext"
+
+ gmp_srclinks="$gmp_srclinks mpn/$tmp_fn.$tmp_ext"
+
+ # Duplicate AC_DEFINEs are harmless, so it doesn't matter
+ # that multi-function files get grepped here repeatedly.
+ # The PROLOGUE pattern excludes the optional second parameter.
+ gmp_ep=`
+ sed -n 's/^[ ]*MULFUNC_PROLOGUE(\(.*\))/\1/p' $tmp_file ;
+ sed -n 's/^[ ]*PROLOGUE(\([^,]*\).*)/\1/p' $tmp_file
+ `
+ for gmp_tmp in $gmp_ep; do
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NATIVE_$gmp_tmp 1
+_ACEOF
+
+ eval HAVE_NATIVE_$gmp_tmp=yes
+ done
+
+ case $tmp_fn in
+ sqr_basecase) sqr_basecase_source=$tmp_file ;;
+ esac
+
+ break
+ fi
+ done
+ if test $found = yes; then break ; fi
+ done
+ if test $found = yes; then break ; fi
+ done
+
+ if test $found = no; then
+ for tmp_optional in $gmp_mpn_functions_optional; do
+ if test $tmp_optional = $tmp_fn; then
+ found=yes
+ fi
+ done
+ if test $found = no; then
+ as_fn_error $? "no version of $tmp_fn found in path: $path" "$LINENO" 5
+ fi
+ fi
+done
+
+# All cycle counters are .asm files currently
+if test -n "$SPEED_CYCLECOUNTER_OBJ"; then
+ found_asm=yes
+fi
+
+
+
+
+
+# Don't demand an m4 unless it's actually needed.
+if test $found_asm = yes; then
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suitable m4" >&5
+$as_echo_n "checking for suitable m4... " >&6; }
+if ${gmp_cv_prog_m4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$M4"; then
+ gmp_cv_prog_m4="$M4"
+else
+ cat >conftest.m4 <<\EOF
+define(dollarhash,``$#'')ifelse(dollarhash(x),1,`define(t1,Y)',
+``bad: $# not supported (SunOS /usr/bin/m4)
+'')ifelse(eval(89),89,`define(t2,Y)',
+`bad: eval() doesnt support 8 or 9 in a constant (OpenBSD 2.6 m4)
+')ifelse(eval(9,9),10,`define(t3,Y)',
+`bad: eval() doesnt support radix in eval (FreeBSD 8.x,9.0,9.1,9.2 m4)
+')ifelse(t1`'t2`'t3,YYY,`good
+')
+EOF
+ echo "trying m4" >&5
+ gmp_tmp_val=`(m4 conftest.m4) 2>&5`
+ echo "$gmp_tmp_val" >&5
+ if test "$gmp_tmp_val" = good; then
+ gmp_cv_prog_m4="m4"
+ else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH:/usr/5bin"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ echo "trying $ac_dir/m4" >&5
+ gmp_tmp_val=`($ac_dir/m4 conftest.m4) 2>&5`
+ echo "$gmp_tmp_val" >&5
+ if test "$gmp_tmp_val" = good; then
+ gmp_cv_prog_m4="$ac_dir/m4"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ if test -z "$gmp_cv_prog_m4"; then
+ as_fn_error $? "No usable m4 in \$PATH or /usr/5bin (see config.log for reasons)." "$LINENO" 5
+ fi
+ fi
+ rm -f conftest.m4
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_prog_m4" >&5
+$as_echo "$gmp_cv_prog_m4" >&6; }
+M4="$gmp_cv_prog_m4"
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if m4wrap produces spurious output" >&5
+$as_echo_n "checking if m4wrap produces spurious output... " >&6; }
+if ${gmp_cv_m4_m4wrap_spurious+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # hide the d-n-l from autoconf's error checking
+tmp_d_n_l=d""nl
+cat >conftest.m4 <<EOF
+changequote({,})define(x,)m4wrap({x})$tmp_d_n_l
+EOF
+echo test input is >&5
+cat conftest.m4 >&5
+tmp_chars=`$M4 conftest.m4 | wc -c`
+echo produces $tmp_chars chars output >&5
+rm -f conftest.m4
+if test $tmp_chars = 0; then
+ gmp_cv_m4_m4wrap_spurious=no
+else
+ gmp_cv_m4_m4wrap_spurious=yes
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_m4_m4wrap_spurious" >&5
+$as_echo "$gmp_cv_m4_m4wrap_spurious" >&6; }
+
+echo "define(<M4WRAP_SPURIOUS>,<$gmp_cv_m4_m4wrap_spurious>)" >> $gmp_tmpconfigm4
+
+
+# else
+# It's unclear why this m4-not-needed stuff was ever done.
+# if test -z "$M4" ; then
+# M4=m4-not-needed
+# fi
+fi
+
+# Only do the GMP_ASM checks if there's a .S or .asm wanting them.
+if test $found_asm = no && test $found_S = no; then
+ gmp_asm_syntax_testing=no
+fi
+
+if test "$gmp_asm_syntax_testing" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to switch to text section" >&5
+$as_echo_n "checking how to switch to text section... " >&6; }
+if ${gmp_cv_asm_text+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ for i in ".text" ".code" ".csect .text[PR]"; do
+ echo "trying $i" >&5
+ cat >conftest.s <<EOF
+ $i
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_text=$i
+ rm -f conftest*
+ break
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ :
+fi
+rm -f conftest*
+
+done
+if test -z "$gmp_cv_asm_text"; then
+ as_fn_error $? "Cannot determine text section directive" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_text" >&5
+$as_echo "$gmp_cv_asm_text" >&6; }
+echo "define(<TEXT>, <$gmp_cv_asm_text>)" >> $gmp_tmpconfigm4
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to switch to data section" >&5
+$as_echo_n "checking how to switch to data section... " >&6; }
+if ${gmp_cv_asm_data+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-aix*) gmp_cv_asm_data=".csect .data[RW]" ;;
+ *) gmp_cv_asm_data=".data" ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_data" >&5
+$as_echo "$gmp_cv_asm_data" >&6; }
+echo "define(<DATA>, <$gmp_cv_asm_data>)" >> $gmp_tmpconfigm4
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler label suffix" >&5
+$as_echo_n "checking for assembler label suffix... " >&6; }
+if ${gmp_cv_asm_label_suffix+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gmp_cv_asm_label_suffix=unknown
+for i in "" ":"; do
+ echo "trying $i" >&5
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+somelabel$i
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_label_suffix=$i
+ rm -f conftest*
+ break
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ cat conftest.out >&5
+fi
+rm -f conftest*
+
+done
+if test "$gmp_cv_asm_label_suffix" = "unknown"; then
+ as_fn_error $? "Cannot determine label suffix" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_label_suffix" >&5
+$as_echo "$gmp_cv_asm_label_suffix" >&6; }
+echo "define(<LABEL_SUFFIX>, <$gmp_cv_asm_label_suffix>)" >> $gmp_tmpconfigm4
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler global directive" >&5
+$as_echo_n "checking for assembler global directive... " >&6; }
+if ${gmp_cv_asm_globl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ hppa*-*-*) gmp_cv_asm_globl=.export ;;
+ ia64*-*-* | itanium-*-* | itanium2-*-*) gmp_cv_asm_globl=.global ;;
+ *) gmp_cv_asm_globl=.globl ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_globl" >&5
+$as_echo "$gmp_cv_asm_globl" >&6; }
+echo "define(<GLOBL>, <$gmp_cv_asm_globl>)" >> $gmp_tmpconfigm4
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler global directive attribute" >&5
+$as_echo_n "checking for assembler global directive attribute... " >&6; }
+if ${gmp_cv_asm_globl_attr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $gmp_cv_asm_globl in
+ .export) gmp_cv_asm_globl_attr=",entry" ;;
+ *) gmp_cv_asm_globl_attr="" ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_globl_attr" >&5
+$as_echo "$gmp_cv_asm_globl_attr" >&6; }
+echo "define(<GLOBL_ATTR>, <$gmp_cv_asm_globl_attr>)" >> $gmp_tmpconfigm4
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if globals are prefixed by underscore" >&5
+$as_echo_n "checking if globals are prefixed by underscore... " >&6; }
+if ${gmp_cv_asm_underscore+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gmp_cv_asm_underscore="unknown"
+cat >conftest.c <<EOF
+int gurkmacka;
+EOF
+gmp_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >&5"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ $NM conftest.$OBJEXT >conftest.out
+ if grep _gurkmacka conftest.out >/dev/null; then
+ gmp_cv_asm_underscore=yes
+ elif grep gurkmacka conftest.out >/dev/null; then
+ gmp_cv_asm_underscore=no
+ else
+ echo "configure: $NM doesn't have gurkmacka:" >&5
+ cat conftest.out >&5
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_underscore" >&5
+$as_echo "$gmp_cv_asm_underscore" >&6; }
+case $gmp_cv_asm_underscore in
+ yes)
+
+echo 'define(<GSYM_PREFIX>, <_>)' >>$gmp_tmpconfigm4
+ ;;
+ no)
+
+echo 'define(<GSYM_PREFIX>, <>)' >>$gmp_tmpconfigm4
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Cannot determine global symbol prefix." >&5
+$as_echo "$as_me: WARNING: | Cannot determine global symbol prefix." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | $NM output doesn't contain a global data symbol." >&5
+$as_echo "$as_me: WARNING: | $NM output doesn't contain a global data symbol." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | Will proceed with no underscore." >&5
+$as_echo "$as_me: WARNING: | Will proceed with no underscore." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | If this is wrong then you'll get link errors referring" >&5
+$as_echo "$as_me: WARNING: | If this is wrong then you'll get link errors referring" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | to ___gmpn_add_n (note three underscores)." >&5
+$as_echo "$as_me: WARNING: | to ___gmpn_add_n (note three underscores)." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | In this case do a fresh build with an override," >&5
+$as_echo "$as_me: WARNING: | In this case do a fresh build with an override," >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: | ./configure gmp_cv_asm_underscore=yes" >&5
+$as_echo "$as_me: WARNING: | ./configure gmp_cv_asm_underscore=yes" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING: +----------------------------------------------------------" >&2;}
+
+echo 'define(<GSYM_PREFIX>, <>)' >>$gmp_tmpconfigm4
+
+ ;;
+esac
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to switch to read-only data section" >&5
+$as_echo_n "checking how to switch to read-only data section... " >&6; }
+if ${gmp_cv_asm_rodata+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+case $host in
+i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-* | x86_64-*-*)
+ gmp_cv_asm_rodata="$gmp_cv_asm_data" ;;
+*)
+ gmp_cv_asm_rodata="$gmp_cv_asm_text" ;;
+esac
+
+cat >conftest.c <<EOF
+extern const int foo[]; /* Suppresses C++'s suppression of foo */
+const int foo[] = {1,2,3};
+EOF
+echo "Test program:" >&5
+cat conftest.c >&5
+gmp_compile="$CC $CFLAGS $CPPFLAGS -S conftest.c >&5"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ echo "Compiler output:" >&5
+ cat conftest.s >&5
+ if test $gmp_cv_asm_underscore = yes; then
+ tmp_gsym_prefix=_
+ else
+ tmp_gsym_prefix=
+ fi
+ # must see our label
+ if grep "^${tmp_gsym_prefix}foo$gmp_cv_asm_label_suffix" conftest.s >/dev/null 2>&5; then
+ # take the last directive before our label (hence skipping segments
+ # getting debugging info etc)
+ tmp_match=`sed -n "/^${tmp_gsym_prefix}foo$gmp_cv_asm_label_suffix/q
+ /^[. ]*data/p
+ /^[. ]*rdata/p
+ /^[. ]*text/p
+ /^[. ]*section/p
+ /^[. ]*csect/p
+ /^[. ]*CSECT/p" conftest.s | sed -n '$p'`
+ echo "Match: $tmp_match" >&5
+ if test -n "$tmp_match"; then
+ gmp_cv_asm_rodata=$tmp_match
+ fi
+ else
+ echo "Couldn't find label: ^${tmp_gsym_prefix}foo$gmp_cv_asm_label_suffix" >&5
+ fi
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_rodata" >&5
+$as_echo "$gmp_cv_asm_rodata" >&6; }
+echo "define(<RODATA>, <$gmp_cv_asm_rodata>)" >> $gmp_tmpconfigm4
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler .type directive" >&5
+$as_echo_n "checking for assembler .type directive... " >&6; }
+if ${gmp_cv_asm_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gmp_cv_asm_type=
+for gmp_tmp_prefix in @ \# %; do
+ cat >conftest.s <<EOF
+ .type sym,${gmp_tmp_prefix}function
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ if grep "\.type pseudo-op used outside of \.def/\.endef ignored" conftest.out >/dev/null; then : ;
+ else
+ gmp_cv_asm_type=".type \$1,${gmp_tmp_prefix}\$2"
+ break
+ fi
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ :
+fi
+rm -f conftest*
+
+done
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_type" >&5
+$as_echo "$gmp_cv_asm_type" >&6; }
+echo "define(<TYPE>, <$gmp_cv_asm_type>)" >> $gmp_tmpconfigm4
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler .size directive" >&5
+$as_echo_n "checking for assembler .size directive... " >&6; }
+if ${gmp_cv_asm_size+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gmp_cv_asm_size=
+cat >conftest.s <<EOF
+ .size sym,1
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ if grep "\.size pseudo-op used outside of \.def/\.endef ignored" conftest.out >/dev/null; then : ;
+ else
+ gmp_cv_asm_size=".size \$1,\$2"
+ fi
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ :
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_size" >&5
+$as_echo "$gmp_cv_asm_size" >&6; }
+echo "define(<SIZE>, <$gmp_cv_asm_size>)" >> $gmp_tmpconfigm4
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler local label prefix" >&5
+$as_echo_n "checking for assembler local label prefix... " >&6; }
+if ${gmp_cv_asm_lsym_prefix+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gmp_tmp_pre_appears=yes
+for gmp_tmp_pre in L .L $L $ L$; do
+ echo "Trying $gmp_tmp_pre" >&5
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+dummy${gmp_cv_asm_label_suffix}
+${gmp_tmp_pre}gurkmacka${gmp_cv_asm_label_suffix}
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ if $NM conftest.$OBJEXT >conftest.nm 2>&5; then : ; else
+ cat conftest.nm >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"$NM\" failure" >&5
+$as_echo "$as_me: WARNING: \"$NM\" failure" >&2;}
+ break
+ fi
+ cat conftest.nm >&5
+ if grep gurkmacka conftest.nm >/dev/null; then : ; else
+ # no mention of the symbol, this is good
+ echo "$gmp_tmp_pre label doesn't appear in object file at all (good)" >&5
+ gmp_cv_asm_lsym_prefix="$gmp_tmp_pre"
+ gmp_tmp_pre_appears=no
+ break
+ fi
+ if grep ' [a-zN] .*gurkmacka' conftest.nm >/dev/null; then
+ # symbol mentioned as a local, use this if nothing better
+ echo "$gmp_tmp_pre label is local but still in object file" >&5
+ if test -z "$gmp_cv_asm_lsym_prefix"; then
+ gmp_cv_asm_lsym_prefix="$gmp_tmp_pre"
+ fi
+ else
+ echo "$gmp_tmp_pre label is something unknown" >&5
+ fi
+
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ :
+fi
+rm -f conftest*
+
+done
+rm -f conftest*
+if test -z "$gmp_cv_asm_lsym_prefix"; then
+ gmp_cv_asm_lsym_prefix=L
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine local label, using default $gmp_cv_asm_lsym_prefix" >&5
+$as_echo "$as_me: WARNING: cannot determine local label, using default $gmp_cv_asm_lsym_prefix" >&2;}
+fi
+# for development purposes, note whether we got a purely temporary local label
+echo "Local label appears in object files: $gmp_tmp_pre_appears" >&5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_lsym_prefix" >&5
+$as_echo "$gmp_cv_asm_lsym_prefix" >&6; }
+echo "define(<LSYM_PREFIX>, <${gmp_cv_asm_lsym_prefix}>)" >> $gmp_tmpconfigm4
+
+cat >>confdefs.h <<_ACEOF
+#define LSYM_PREFIX "$gmp_cv_asm_lsym_prefix"
+_ACEOF
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler byte directive" >&5
+$as_echo_n "checking for assembler byte directive... " >&6; }
+if ${gmp_cv_asm_byte+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ for i in .byte data1; do
+ echo "trying $i" >&5
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_data
+ $i 0
+
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_byte=$i
+ rm -f conftest*
+ break
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ cat conftest.out >&5
+fi
+rm -f conftest*
+
+done
+if test -z "$gmp_cv_asm_byte"; then
+ as_fn_error $? "Cannot determine how to emit a data byte" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_byte" >&5
+$as_echo "$gmp_cv_asm_byte" >&6; }
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to define a 32-bit word" >&5
+$as_echo_n "checking how to define a 32-bit word... " >&6; }
+if ${gmp_cv_asm_w32+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-hpux*)
+ # FIXME: HPUX puts first symbol at 0x40000000, breaking our assumption
+ # that it's at 0x0. We'll have to declare another symbol before the
+ # .long/.word and look at the distance between the two symbols. The
+ # only problem is that the sed expression(s) barfs (on Solaris, for
+ # example) for the symbol with value 0. For now, HPUX uses .word.
+ gmp_cv_asm_w32=".word"
+ ;;
+ *-*-*)
+ gmp_tmp_val=
+ for gmp_tmp_op in .long .word data4; do
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_data
+ $gmp_cv_asm_globl foo
+ $gmp_tmp_op 0
+foo$gmp_cv_asm_label_suffix
+ $gmp_cv_asm_byte 0
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_tmp_val=`$NM conftest.$OBJEXT | grep foo | \
+ sed -e 's;[[][0-9][]]\(.*\);\1;' -e 's;[^1-9]*\([0-9]*\).*;\1;'`
+ if test "$gmp_tmp_val" = 4; then
+ gmp_cv_asm_w32="$gmp_tmp_op"
+ break
+ fi
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ :
+fi
+rm -f conftest*
+
+ done
+ rm -f conftest*
+ ;;
+esac
+if test -z "$gmp_cv_asm_w32"; then
+ as_fn_error $? "cannot determine how to define a 32-bit word" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_w32" >&5
+$as_echo "$gmp_cv_asm_w32" >&6; }
+echo "define(<W32>, <$gmp_cv_asm_w32>)" >> $gmp_tmpconfigm4
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if .align assembly directive is logarithmic" >&5
+$as_echo_n "checking if .align assembly directive is logarithmic... " >&6; }
+if ${gmp_cv_asm_align_log+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_data
+ .align 4
+ $gmp_cv_asm_globl foo
+ $gmp_cv_asm_byte 1
+ .align 4
+foo$gmp_cv_asm_label_suffix
+ $gmp_cv_asm_byte 2
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_tmp_val=`$NM conftest.$OBJEXT | grep foo | \
+ sed -e 's;[[][0-9][]]\(.*\);\1;' -e 's;[^1-9]*\([0-9]*\).*;\1;'`
+ if test "$gmp_tmp_val" = "10" || test "$gmp_tmp_val" = "16"; then
+ gmp_cv_asm_align_log=yes
+ else
+ gmp_cv_asm_align_log=no
+ fi
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ as_fn_error $? "cannot assemble alignment test" "$LINENO" 5
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_align_log" >&5
+$as_echo "$gmp_cv_asm_align_log" >&6; }
+
+
+echo "define(<ALIGN_LOGARITHMIC>,<$gmp_cv_asm_align_log>)" >> $gmp_tmpconfigm4
+
+
+
+ case $host in
+ hppa*-*-*)
+ # for both pa32 and pa64
+
+echo "include_mpn(\`pa32/pa-defs.m4')" >> $gmp_tmpconfigm4i
+
+ ;;
+ ia64*-*-* | itanium-*-* | itanium2-*-*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether assembler .align padding is good" >&5
+$as_echo_n "checking whether assembler .align padding is good... " >&6; }
+if ${gmp_cv_asm_ia64_align_ok+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.awk <<\EOF
+BEGIN {
+ want[0] = "011"
+ want[1] = "160"
+ want[2] = "074"
+ want[3] = "040"
+ want[4] = "000"
+ want[5] = "040"
+ want[6] = "020"
+ want[7] = "221"
+ want[8] = "114"
+ want[9] = "000"
+ want[10] = "100"
+ want[11] = "200"
+ want[12] = "122"
+ want[13] = "261"
+ want[14] = "000"
+ want[15] = "200"
+
+ want[16] = "000"
+ want[17] = "004"
+ want[18] = "000"
+ want[19] = "000"
+ want[20] = "000"
+ want[21] = "000"
+ want[22] = "002"
+ want[23] = "000"
+ want[24] = "000"
+ want[25] = "000"
+ want[26] = "000"
+ want[27] = "001"
+ want[28] = "000"
+ want[29] = "000"
+ want[30] = "000"
+ want[31] = "014"
+
+ want[32] = "011"
+ want[33] = "270"
+ want[34] = "140"
+ want[35] = "062"
+ want[36] = "000"
+ want[37] = "040"
+ want[38] = "240"
+ want[39] = "331"
+ want[40] = "160"
+ want[41] = "000"
+ want[42] = "100"
+ want[43] = "240"
+ want[44] = "343"
+ want[45] = "371"
+ want[46] = "000"
+ want[47] = "200"
+
+ result = "yes"
+}
+{
+ for (f = 2; f <= NF; f++)
+ {
+ for (i = 0; i < 47; i++)
+ got[i] = got[i+1];
+ got[47] = $f;
+
+ found = 1
+ for (i = 0; i < 48; i++)
+ if (got[i] != want[i])
+ {
+ found = 0
+ break
+ }
+ if (found)
+ {
+ result = "no"
+ exit
+ }
+ }
+}
+END {
+ print result
+}
+EOF
+cat >conftest.s <<EOF
+ .text
+ .align 32
+{ .mmi; add r14 = r15, r16
+ add r17 = r18, r19
+ add r20 = r21, r22 ;; }
+ .align 32
+{ .mmi; add r23 = r24, r25
+ add r26 = r27, r28
+ add r29 = r30, r31 ;; }
+
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_ia64_align_ok=`od -b conftest.$OBJEXT | $AWK -f conftest.awk`
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: oops, cannot compile test program" >&5
+$as_echo "$as_me: WARNING: oops, cannot compile test program" >&2;}
+ gmp_cv_asm_ia64_align_ok=yes
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_ia64_align_ok" >&5
+$as_echo "$gmp_cv_asm_ia64_align_ok" >&6; }
+
+echo "define(<IA64_ALIGN_OK>, <\`$gmp_cv_asm_ia64_align_ok'>)" >> $gmp_tmpconfigm4
+
+
+ ;;
+ m68k-*-* | m68[0-9][0-9][0-9]-*-*)
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler instruction and register style" >&5
+$as_echo_n "checking assembler instruction and register style... " >&6; }
+if ${gmp_cv_asm_m68k_instruction+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ for i in "addl %d0,%d1" "add.l %d0,%d1" "addl d0,d1" "add.l d0,d1"; do
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ $i
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_m68k_instruction=$i
+ rm -f conftest*
+ break
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ :
+fi
+rm -f conftest*
+
+done
+if test -z "$gmp_cv_asm_m68k_instruction"; then
+ as_fn_error $? "cannot determine assembler instruction and register style" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_m68k_instruction" >&5
+$as_echo "$gmp_cv_asm_m68k_instruction" >&6; }
+case $gmp_cv_asm_m68k_instruction in
+"addl d0,d1") want_dot_size=no; want_register_percent=no ;;
+"addl %d0,%d1") want_dot_size=no; want_register_percent=yes ;;
+"add.l d0,d1") want_dot_size=yes; want_register_percent=no ;;
+"add.l %d0,%d1") want_dot_size=yes; want_register_percent=yes ;;
+*) as_fn_error $? "oops, unrecognised instruction and register style" "$LINENO" 5 ;;
+esac
+
+echo "define(<WANT_REGISTER_PERCENT>, <\`$want_register_percent'>)" >> $gmp_tmpconfigm4
+
+
+echo "define(<WANT_DOT_SIZE>, <\`$want_dot_size'>)" >> $gmp_tmpconfigm4
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler addressing style" >&5
+$as_echo_n "checking assembler addressing style... " >&6; }
+if ${gmp_cv_asm_m68k_addressing+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $gmp_cv_asm_m68k_instruction in
+addl*) movel=movel ;;
+add.l*) movel=move.l ;;
+*) as_fn_error $? "oops, unrecognised gmp_cv_asm_m68k_instruction" "$LINENO" 5 ;;
+esac
+case $gmp_cv_asm_m68k_instruction in
+*"%d0,%d1") dreg=%d0; areg=%a0 ;;
+*"d0,d1") dreg=d0; areg=a0 ;;
+*) as_fn_error $? "oops, unrecognised gmp_cv_asm_m68k_instruction" "$LINENO" 5 ;;
+esac
+cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ $movel $dreg, $areg@-
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_m68k_addressing=mit
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ $movel $dreg, -($areg)
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_m68k_addressing=motorola
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ as_fn_error $? "cannot determine assembler addressing style" "$LINENO" 5
+fi
+rm -f conftest*
+
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_m68k_addressing" >&5
+$as_echo "$gmp_cv_asm_m68k_addressing" >&6; }
+
+echo "define(<WANT_ADDRESSING>, <\`$gmp_cv_asm_m68k_addressing'>)" >> $gmp_tmpconfigm4
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler shortest branches" >&5
+$as_echo_n "checking assembler shortest branches... " >&6; }
+if ${gmp_cv_asm_m68k_branches+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ for i in jra jbra bra; do
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+foo$gmp_cv_asm_label_suffix
+ $i foo
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_m68k_branches=$i
+ rm -f conftest*
+ break
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ :
+fi
+rm -f conftest*
+
+done
+if test -z "$gmp_cv_asm_m68k_branches"; then
+ as_fn_error $? "cannot determine assembler branching style" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_m68k_branches" >&5
+$as_echo "$gmp_cv_asm_m68k_branches" >&6; }
+
+echo "define(<WANT_BRANCHES>, <\`$gmp_cv_asm_m68k_branches'>)" >> $gmp_tmpconfigm4
+
+
+ ;;
+ powerpc*-*-* | power[3-9]-*-*)
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler output is PIC by default" >&5
+$as_echo_n "checking whether compiler output is PIC by default... " >&6; }
+if ${gmp_cv_asm_powerpc_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gmp_cv_asm_powerpc_pic=yes
+cat >conftest.c <<EOF
+int foo;
+int *bar() { return &foo; }
+EOF
+echo "Test program:" >&5
+cat conftest.c >&5
+gmp_compile="$CC $CFLAGS $CPPFLAGS -S conftest.c >&5"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ echo "Compiler output:" >&5
+ cat conftest.s >&5
+ if grep 'foo@ha' conftest.s >/dev/null 2>&5; then
+ gmp_cv_asm_powerpc_pic=no
+ fi
+ if grep 'ha16(_foo)' conftest.s >/dev/null 2>&5; then
+ gmp_cv_asm_powerpc_pic=no
+ fi
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_powerpc_pic" >&5
+$as_echo "$gmp_cv_asm_powerpc_pic" >&6; }
+
+echo "define(<PIC_ALWAYS>,<$gmp_cv_asm_powerpc_pic>)" >> $gmp_tmpconfigm4
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler needs r on registers" >&5
+$as_echo_n "checking if the assembler needs r on registers... " >&6; }
+if ${gmp_cv_asm_powerpc_r_registers+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ mtctr 6
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_powerpc_r_registers=no
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ mtctr r6
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_powerpc_r_registers=yes
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ as_fn_error $? "neither \"mtctr 6\" nor \"mtctr r6\" works" "$LINENO" 5
+fi
+rm -f conftest*
+
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_powerpc_r_registers" >&5
+$as_echo "$gmp_cv_asm_powerpc_r_registers" >&6; }
+
+
+echo "define(<WANT_R_REGISTERS>,<$gmp_cv_asm_powerpc_r_registers>)" >> $gmp_tmpconfigm4
+
+
+
+echo "include_mpn(\`powerpc32/powerpc-defs.m4')" >> $gmp_tmpconfigm4i
+
+
+ # Check for Linux ELFv2 ABI
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#if _CALL_ELF == 2
+yes
+#endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "yes" >/dev/null 2>&1; then :
+
+echo "define(<ELFv2_ABI>)" >> $gmp_tmpconfigm4
+
+fi
+rm -f conftest*
+
+
+ case $host in
+ *-*-aix*)
+ case $ABI in
+ mode64)
+echo "include_mpn(\`powerpc64/aix.m4')" >> $gmp_tmpconfigm4i
+ ;;
+ *)
+echo "include_mpn(\`powerpc32/aix.m4')" >> $gmp_tmpconfigm4i
+ ;;
+ esac
+ ;;
+ *-*-linux* | *-*-*bsd*)
+ case $ABI in
+ mode64)
+echo "include_mpn(\`powerpc64/elf.m4')" >> $gmp_tmpconfigm4i
+ ;;
+ mode32 | 32)
+echo "include_mpn(\`powerpc32/elf.m4')" >> $gmp_tmpconfigm4i
+ ;;
+ esac
+ ;;
+ *-*-darwin*)
+ case $ABI in
+ mode64)
+echo "include_mpn(\`powerpc64/darwin.m4')" >> $gmp_tmpconfigm4i
+ ;;
+ mode32 | 32)
+echo "include_mpn(\`powerpc32/darwin.m4')" >> $gmp_tmpconfigm4i
+ ;;
+ esac
+ ;;
+ *)
+ # Assume unrecognized operating system is the powerpc eABI
+
+echo "include_mpn(\`powerpc32/eabi.m4')" >> $gmp_tmpconfigm4i
+
+ ;;
+ esac
+ ;;
+ power*-*-aix*)
+
+echo "include_mpn(\`powerpc32/aix.m4')" >> $gmp_tmpconfigm4i
+
+ ;;
+ *sparc*-*-*)
+ case $ABI in
+ 64)
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler accepts \".register\"" >&5
+$as_echo_n "checking if the assembler accepts \".register\"... " >&6; }
+if ${gmp_cv_asm_sparc_register+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ .register %g2,#scratch
+
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_sparc_register=yes
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_sparc_register=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_sparc_register" >&5
+$as_echo "$gmp_cv_asm_sparc_register" >&6; }
+
+
+echo "define(<HAVE_REGISTER>,<$gmp_cv_asm_sparc_register>)" >> $gmp_tmpconfigm4
+
+
+ ;;
+ esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler accepts gotdata relocations" >&5
+$as_echo_n "checking if the assembler accepts gotdata relocations... " >&6; }
+if ${gmp_cv_asm_sparc_gotdata+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ .text
+ sethi %gdop_hix22(symbol), %g1
+ or %g1, %gdop_lox10(symbol), %g1
+
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_sparc_gotdata=yes
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_sparc_gotdata=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_sparc_gotdata" >&5
+$as_echo "$gmp_cv_asm_sparc_gotdata" >&6; }
+
+
+echo "define(<HAVE_GOTDATA>,<$gmp_cv_asm_sparc_gotdata>)" >> $gmp_tmpconfigm4
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler can support shared PIC thunks" >&5
+$as_echo_n "checking if the assembler can support shared PIC thunks... " >&6; }
+if ${gmp_cv_asm_sparc_shared_thunks+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ .section .text.__sparc_get_pc_thunk.l7,"axG",@progbits,__sparc_get_pc_thunk.l7,comdat
+ .weak __sparc_get_pc_thunk.l7
+ .hidden __sparc_get_pc_thunk.l7
+ .type __sparc_get_pc_thunk.l7, #function
+__sparc_get_pc_thunk.l7:
+ jmp %o7+8
+ add %o7, %l7, %l7
+
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_sparc_shared_thunks=yes
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_sparc_shared_thunks=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_sparc_shared_thunks" >&5
+$as_echo "$gmp_cv_asm_sparc_shared_thunks" >&6; }
+
+
+echo "define(<HAVE_SHARED_THUNKS>,<$gmp_cv_asm_sparc_shared_thunks>)" >> $gmp_tmpconfigm4
+
+
+ ;;
+ i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-* | athlon64-*-* | k8-*-* | k10-*-* | bobcat-*-* | jaguar-*-* | bulldozer-*-* | piledriver-*-* | steamroller-*-* | excavator-*-* | pentium4-*-* | atom-*-* | core2-*-* | corei*-*-* | x86_64-*-* | nano-*-*)
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the .align directive accepts an 0x90 fill in .text" >&5
+$as_echo_n "checking if the .align directive accepts an 0x90 fill in .text... " >&6; }
+if ${gmp_cv_asm_align_fill_0x90+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ .align 4, 0x90
+ .byte 0
+ .align 4, 0x90
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ if grep "Warning: Fill parameter ignored for executable section" conftest.out >/dev/null; then
+ echo "Suppressing this warning by omitting 0x90" 1>&5
+ gmp_cv_asm_align_fill_0x90=no
+else
+ gmp_cv_asm_align_fill_0x90=yes
+fi
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_align_fill_0x90=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_align_fill_0x90" >&5
+$as_echo "$gmp_cv_asm_align_fill_0x90" >&6; }
+
+
+echo "define(<ALIGN_FILL_0x90>,<$gmp_cv_asm_align_fill_0x90>)" >> $gmp_tmpconfigm4
+
+
+ case $ABI in
+ 32)
+
+echo "include_mpn(\`x86/x86-defs.m4')" >> $gmp_tmpconfigm4i
+
+ $as_echo "#define HAVE_HOST_CPU_FAMILY_x86 1" >>confdefs.h
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler COFF type directives" >&5
+$as_echo_n "checking for assembler COFF type directives... " >&6; }
+if ${gmp_cv_asm_x86_coff_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ $gmp_cv_asm_globl ${tmp_gsym_prefix}foo$gmp_cv_asm_globl_attr
+ .def ${tmp_gsym_prefix}foo
+ .scl 2
+ .type 32
+ .endef
+${tmp_gsym_prefix}foo$gmp_cv_asm_label_suffix
+
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_x86_coff_type=yes
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_x86_coff_type=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_x86_coff_type" >&5
+$as_echo "$gmp_cv_asm_x86_coff_type" >&6; }
+echo "define(<HAVE_COFF_TYPE>, <$gmp_cv_asm_x86_coff_type>)" >> $gmp_tmpconfigm4
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if _GLOBAL_OFFSET_TABLE_ is prefixed by underscore" >&5
+$as_echo_n "checking if _GLOBAL_OFFSET_TABLE_ is prefixed by underscore... " >&6; }
+if ${gmp_cv_asm_x86_got_underscore+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gmp_cv_asm_x86_got_underscore="not applicable"
+if test $gmp_cv_asm_underscore = yes; then
+ tmp_gsym_prefix=_
+else
+ tmp_gsym_prefix=
+fi
+for tmp_underscore in "" "_"; do
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ $gmp_cv_asm_globl ${tmp_gsym_prefix}main$gmp_cv_asm_globl_attr
+${tmp_gsym_prefix}main$gmp_cv_asm_label_suffix
+ addl $ ${tmp_underscore}_GLOBAL_OFFSET_TABLE_, %ebx
+EOF
+ gmp_compile="$CCAS $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.s >&5 && $CC $CFLAGS $CPPFLAGS $lt_prog_compiler_pic conftest.$OBJEXT >&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_compile\""; } >&5
+ (eval $gmp_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$tmp_underscore" = "_"; then
+ gmp_cv_asm_x86_got_underscore=yes
+ else
+ gmp_cv_asm_x86_got_underscore=no
+ fi
+ break
+ fi
+done
+rm -f conftest* a.out b.out a.exe a_out.exe
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_x86_got_underscore" >&5
+$as_echo "$gmp_cv_asm_x86_got_underscore" >&6; }
+if test "$gmp_cv_asm_x86_got_underscore" = "yes"; then
+
+echo 'define(<GOT_GSYM_PREFIX>, <_>)' >>$gmp_tmpconfigm4
+
+else
+
+echo 'define(<GOT_GSYM_PREFIX>, <>)' >>$gmp_tmpconfigm4
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler takes cl with shldl" >&5
+$as_echo_n "checking if the assembler takes cl with shldl... " >&6; }
+if ${gmp_cv_asm_x86_shldl_cl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.s <<EOF
+ $gmp_cv_asm_text
+ shldl %cl, %eax, %ebx
+EOF
+gmp_assemble="$CCAS $CFLAGS $CPPFLAGS conftest.s >conftest.out 2>&1"
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_assemble\""; } >&5
+ (eval $gmp_assemble) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat conftest.out >&5
+ gmp_cv_asm_x86_shldl_cl=yes
+else
+ cat conftest.out >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.s >&5
+ gmp_cv_asm_x86_shldl_cl=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_asm_x86_shldl_cl" >&5
+$as_echo "$gmp_cv_asm_x86_shldl_cl" >&6; }
+if test "$gmp_cv_asm_x86_shldl_cl" = "yes"; then
+
+echo 'define(<WANT_SHLDL_CL>, <1>)' >>$gmp_tmpconfigm4
+
+else
+
+echo 'define(<WANT_SHLDL_CL>, <0>)' >>$gmp_tmpconfigm4
+
+fi
+
+ case $enable_profiling in
+ prof | gprof) # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to call x86 mcount" >&5
+$as_echo_n "checking how to call x86 mcount... " >&6; }
+cat >conftest.c <<EOF
+foo(){bar();}
+EOF
+
+if test "$enable_static" = yes; then
+ gmp_asmout_compile="$CC $CFLAGS $CPPFLAGS -S conftest.c 1>&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_asmout_compile\""; } >&5
+ (eval $gmp_asmout_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if grep '\.data' conftest.s >/dev/null; then
+ mcount_nonpic_reg=`sed -n '/esp/!s/.*movl.*,\(%[a-z]*\).*$/\1/p' conftest.s`
+ else
+ mcount_nonpic_reg=
+ fi
+ mcount_nonpic_call=`grep 'call.*mcount' conftest.s`
+ if test -z "$mcount_nonpic_call"; then
+ as_fn_error $? "Cannot find mcount call for non-PIC" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Cannot compile test program for non-PIC" "$LINENO" 5
+ fi
+fi
+
+if test "$enable_shared" = yes; then
+ gmp_asmout_compile="$CC $CFLAGS $CPPFLAGS $lt_prog_compiler_pic -S conftest.c 1>&5"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$gmp_asmout_compile\""; } >&5
+ (eval $gmp_asmout_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if grep '\.data' conftest.s >/dev/null; then
+ case $lt_prog_compiler_pic in
+ *-DDLL_EXPORT*)
+ # Windows DLLs have non-PIC style mcount
+ mcount_pic_reg=`sed -n '/esp/!s/.*movl.*,\(%[a-z]*\).*$/\1/p' conftest.s`
+ ;;
+ *)
+ mcount_pic_reg=`sed -n 's/.*GOTOFF.*,\(%[a-z]*\).*$/\1/p' conftest.s`
+ ;;
+ esac
+ else
+ mcount_pic_reg=
+ fi
+ mcount_pic_call=`grep 'call.*mcount' conftest.s`
+ if test -z "$mcount_pic_call"; then
+ as_fn_error $? "Cannot find mcount call for PIC" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Cannot compile test program for PIC" "$LINENO" 5
+ fi
+fi
+
+
+echo "define(<MCOUNT_NONPIC_REG>, <\`$mcount_nonpic_reg'>)" >> $gmp_tmpconfigm4
+
+
+echo "define(<MCOUNT_NONPIC_CALL>,<\`$mcount_nonpic_call'>)" >> $gmp_tmpconfigm4
+
+
+echo "define(<MCOUNT_PIC_REG>, <\`$mcount_pic_reg'>)" >> $gmp_tmpconfigm4
+
+
+echo "define(<MCOUNT_PIC_CALL>, <\`$mcount_pic_call'>)" >> $gmp_tmpconfigm4
+
+
+rm -f conftest.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: determined" >&5
+$as_echo "determined" >&6; }
+ ;;
+ esac
+ case $host in
+ *-*-darwin*)
+
+echo "include_mpn(\`x86/darwin.m4')" >> $gmp_tmpconfigm4i
+ ;;
+ esac
+ ;;
+ 64|x32)
+
+echo "include_mpn(\`x86_64/x86_64-defs.m4')" >> $gmp_tmpconfigm4i
+
+ $as_echo "#define HAVE_HOST_CPU_FAMILY_x86_64 1" >>confdefs.h
+
+ case $host in
+ *-*-darwin*)
+
+echo "include_mpn(\`x86_64/darwin.m4')" >> $gmp_tmpconfigm4i
+ ;;
+ *-*-mingw* | *-*-cygwin)
+
+echo "include_mpn(\`x86_64/dos64.m4')" >> $gmp_tmpconfigm4i
+ ;;
+ *-openbsd*)
+
+echo "define(<OPENBSD>,1)" >> $gmp_tmpconfigm4
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+fi
+
+# For --enable-minithres, prepend "minithres" to path so that its special
+# gmp-mparam.h will be used.
+if test $enable_minithres = yes; then
+ path="minithres $path"
+fi
+
+# Create link for gmp-mparam.h.
+gmp_mparam_source=
+for gmp_mparam_dir in $path; do
+ test "$no_create" = yes || rm -f gmp-mparam.h
+ tmp_file=$srcdir/mpn/$gmp_mparam_dir/gmp-mparam.h
+ if test -f $tmp_file; then
+ ac_config_links="$ac_config_links gmp-mparam.h:mpn/$gmp_mparam_dir/gmp-mparam.h"
+
+ gmp_srclinks="$gmp_srclinks gmp-mparam.h"
+ gmp_mparam_source=$tmp_file
+ break
+ fi
+done
+if test -z "$gmp_mparam_source"; then
+ as_fn_error $? "no version of gmp-mparam.h found in path: $path" "$LINENO" 5
+fi
+
+# For a helpful message from tune/tuneup.c
+gmp_mparam_suggest=$gmp_mparam_source
+if test "$gmp_mparam_dir" = generic; then
+ for i in $path; do break; done
+ if test "$i" != generic; then
+ gmp_mparam_suggest="new file $srcdir/mpn/$i/gmp-mparam.h"
+ fi
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define GMP_MPARAM_H_SUGGEST "$gmp_mparam_source"
+_ACEOF
+
+
+
+# Copy relevant parameters from gmp-mparam.h to config.m4.
+# We only do this for parameters that are used by some assembly files.
+# Fat binaries do this on a per-file basis, so skip in that case.
+#
+if test -z "$fat_path"; then
+ for i in SQR_TOOM2_THRESHOLD BMOD_1_TO_MOD_1_THRESHOLD SHLD_SLOW SHRD_SLOW; do
+ value=`sed -n 's/^#define '$i'[ ]*\([0-9][0-9]*\).*$/\1/p' $gmp_mparam_source`
+ if test -n "$value"; then
+
+echo "define(<$i>,<$value>)" >> $gmp_tmpconfigm4
+
+ fi
+ done
+fi
+
+
+# Sizes of some types, needed at preprocessing time.
+#
+# FIXME: The assumption that GMP_LIMB_BITS is 8*sizeof(mp_limb_t) might
+# be slightly rash, but it's true everywhere we know of and ought to be true
+# of any sensible system. In a generic C build, grepping LONG_BIT out of
+# <limits.h> might be an alternative, for maximum portability.
+#
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
+$as_echo_n "checking size of void *... " >&6; }
+if ${ac_cv_sizeof_void_p+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_void_p" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (void *)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_void_p=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
+$as_echo "$ac_cv_sizeof_void_p" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5
+$as_echo_n "checking size of unsigned short... " >&6; }
+if ${ac_cv_sizeof_unsigned_short+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned short)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5
+$as_echo "$ac_cv_sizeof_unsigned_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned" >&5
+$as_echo_n "checking size of unsigned... " >&6; }
+if ${ac_cv_sizeof_unsigned+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned))" "ac_cv_sizeof_unsigned" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned" >&5
+$as_echo "$ac_cv_sizeof_unsigned" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED $ac_cv_sizeof_unsigned
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5
+$as_echo_n "checking size of unsigned long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of mp_limb_t" >&5
+$as_echo_n "checking size of mp_limb_t... " >&6; }
+if ${ac_cv_sizeof_mp_limb_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (mp_limb_t))" "ac_cv_sizeof_mp_limb_t" "#define __GMP_WITHIN_CONFIGURE 1 /* ignore template stuff */
+#define GMP_NAIL_BITS $GMP_NAIL_BITS
+#define GMP_LIMB_BITS 123
+$DEFN_LONG_LONG_LIMB
+#include \"$srcdir/gmp-h.in\"
+
+"; then :
+
+else
+ if test "$ac_cv_type_mp_limb_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (mp_limb_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_mp_limb_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_mp_limb_t" >&5
+$as_echo "$ac_cv_sizeof_mp_limb_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_MP_LIMB_T $ac_cv_sizeof_mp_limb_t
+_ACEOF
+
+
+if test "$ac_cv_sizeof_mp_limb_t" = 0; then
+ as_fn_error $? "Oops, mp_limb_t doesn't seem to work" "$LINENO" 5
+fi
+GMP_LIMB_BITS=`expr 8 \* $ac_cv_sizeof_mp_limb_t`
+
+
+echo "define(<SIZEOF_UNSIGNED>,<$ac_cv_sizeof_unsigned>)" >> $gmp_tmpconfigm4
+
+
+# Check compiler limb size matches gmp-mparam.h
+#
+# FIXME: Some of the cycle counter objects in the tune directory depend on
+# the size of ulong, it'd be possible to check that here, though a mismatch
+# probably wouldn't want to be fatal, none of the libgmp assembler code
+# depends on ulong.
+#
+mparam_bits=`sed -n 's/^#define GMP_LIMB_BITS[ ][ ]*\([0-9]*\).*$/\1/p' $gmp_mparam_source`
+if test -n "$mparam_bits" && test "$mparam_bits" -ne $GMP_LIMB_BITS; then
+ if test "$test_CFLAGS" = set; then
+ as_fn_error $? "Oops, mp_limb_t is $GMP_LIMB_BITS bits, but the assembler code
+in this configuration expects $mparam_bits bits.
+You appear to have set \$CFLAGS, perhaps you also need to tell GMP the
+intended ABI, see \"ABI and ISA\" in the manual." "$LINENO" 5
+ else
+ as_fn_error $? "Oops, mp_limb_t is $GMP_LIMB_BITS bits, but the assembler code
+in this configuration expects $mparam_bits bits." "$LINENO" 5
+ fi
+fi
+
+
+echo "define(<GMP_LIMB_BITS>,$GMP_LIMB_BITS)" >> $gmp_tmpconfigm4
+
+
+echo "define(<GMP_NAIL_BITS>,$GMP_NAIL_BITS)" >> $gmp_tmpconfigm4
+
+
+echo "define(<GMP_NUMB_BITS>,eval(GMP_LIMB_BITS-GMP_NAIL_BITS))" >> $gmp_tmpconfigm4
+
+
+
+
+
+
+
+
+# A recompiled sqr_basecase for use in the tune program, if necessary.
+TUNE_SQR_OBJ=
+test -d tune || mkdir tune
+case $sqr_basecase_source in
+ *.asm)
+ sqr_max=`sed -n 's/^def...(SQR_TOOM2_THRESHOLD_MAX, *\([0-9]*\))/\1/p' $sqr_basecase_source`
+ if test -n "$sqr_max"; then
+ TUNE_SQR_OBJ=sqr_asm.o
+
+cat >>confdefs.h <<_ACEOF
+#define TUNE_SQR_TOOM2_MAX $sqr_max
+_ACEOF
+
+ fi
+ cat >tune/sqr_basecase.c <<EOF
+/* not sure that an empty file can compile, so put in a dummy */
+int sqr_basecase_dummy;
+EOF
+ ;;
+ *.c)
+ TUNE_SQR_OBJ=
+ $as_echo "#define TUNE_SQR_TOOM2_MAX SQR_TOOM2_MAX_GENERIC" >>confdefs.h
+
+ cat >tune/sqr_basecase.c <<EOF
+#define TUNE_PROGRAM_BUILD 1
+#define TUNE_PROGRAM_BUILD_SQR 1
+#include "mpn/sqr_basecase.c"
+EOF
+ ;;
+esac
+
+
+
+# Configs for demos/pexpr.c.
+#
+ac_config_files="$ac_config_files demos/pexpr-config.h:demos/pexpr-config-h.in"
+
+case $ac_cv_func_clock in
+yes) HAVE_CLOCK_01=1
+ ;;
+no) HAVE_CLOCK_01=0 ;;
+esac
+
+case $ac_cv_func_cputime in
+yes) HAVE_CPUTIME_01=1
+ ;;
+no) HAVE_CPUTIME_01=0 ;;
+esac
+
+case $ac_cv_func_getrusage in
+yes) HAVE_GETRUSAGE_01=1
+ ;;
+no) HAVE_GETRUSAGE_01=0 ;;
+esac
+
+case $ac_cv_func_gettimeofday in
+yes) HAVE_GETTIMEOFDAY_01=1
+ ;;
+no) HAVE_GETTIMEOFDAY_01=0 ;;
+esac
+
+case $ac_cv_func_sigaction in
+yes) HAVE_SIGACTION_01=1
+ ;;
+no) HAVE_SIGACTION_01=0 ;;
+esac
+
+case $ac_cv_func_sigaltstack in
+yes) HAVE_SIGALTSTACK_01=1
+ ;;
+no) HAVE_SIGALTSTACK_01=0 ;;
+esac
+
+case $ac_cv_func_sigstack in
+yes) HAVE_SIGSTACK_01=1
+ ;;
+no) HAVE_SIGSTACK_01=0 ;;
+esac
+
+
+case $ac_cv_header_sys_resource_h in
+yes) HAVE_SYS_RESOURCE_H_01=1
+ ;;
+no) HAVE_SYS_RESOURCE_H_01=0 ;;
+esac
+
+
+ac_fn_c_check_type "$LINENO" "stack_t" "ac_cv_type_stack_t" "#include <signal.h>
+"
+if test "x$ac_cv_type_stack_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STACK_T 1
+_ACEOF
+
+HAVE_STACK_T_01=1
+else
+ HAVE_STACK_T_01=0
+fi
+
+
+
+# Configs for demos/calc directory
+#
+# AC_SUBST+AC_CONFIG_FILES is used for calc-config.h, rather than AC_DEFINE+
+# AC_CONFIG_HEADERS, since with the latter automake (1.8) will then put the
+# directory (ie. demos/calc) into $(DEFAULT_INCLUDES) for every Makefile.in,
+# which would look very strange.
+#
+# -lcurses is required by libreadline. On a typical SVR4 style system this
+# normally doesn't have to be given explicitly, since libreadline.so will
+# have a NEEDED record for it. But if someone for some reason is using only
+# a static libreadline.a then we must give -lcurses. Readline (as of
+# version 4.3) doesn't use libtool, so we can't rely on a .la to cover
+# necessary dependencies.
+#
+# On a couple of systems we've seen libreadline available, but the headers
+# not in the default include path, so check for readline/readline.h. We've
+# also seen readline/history.h missing, not sure if that's just a broken
+# install or a very old version, but check that too.
+#
+ac_config_files="$ac_config_files demos/calc/calc-config.h:demos/calc/calc-config-h.in"
+
+LIBCURSES=
+if test $with_readline != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tputs in -lncurses" >&5
+$as_echo_n "checking for tputs in -lncurses... " >&6; }
+if ${ac_cv_lib_ncurses_tputs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tputs ();
+int
+main ()
+{
+return tputs ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ncurses_tputs=yes
+else
+ ac_cv_lib_ncurses_tputs=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tputs" >&5
+$as_echo "$ac_cv_lib_ncurses_tputs" >&6; }
+if test "x$ac_cv_lib_ncurses_tputs" = xyes; then :
+ LIBCURSES=-lncurses
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tputs in -lcurses" >&5
+$as_echo_n "checking for tputs in -lcurses... " >&6; }
+if ${ac_cv_lib_curses_tputs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurses $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tputs ();
+int
+main ()
+{
+return tputs ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_curses_tputs=yes
+else
+ ac_cv_lib_curses_tputs=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_tputs" >&5
+$as_echo "$ac_cv_lib_curses_tputs" >&6; }
+if test "x$ac_cv_lib_curses_tputs" = xyes; then :
+ LIBCURSES=-lcurses
+fi
+
+fi
+
+fi
+
+use_readline=$with_readline
+if test $with_readline = detect; then
+ use_readline=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5
+$as_echo_n "checking for readline in -lreadline... " >&6; }
+if ${ac_cv_lib_readline_readline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $LIBCURSES $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char readline ();
+int
+main ()
+{
+return readline ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_readline_readline=yes
+else
+ ac_cv_lib_readline_readline=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5
+$as_echo "$ac_cv_lib_readline_readline" >&6; }
+if test "x$ac_cv_lib_readline_readline" = xyes; then :
+ ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default"
+if test "x$ac_cv_header_readline_readline_h" = xyes; then :
+ ac_fn_c_check_header_mongrel "$LINENO" "readline/history.h" "ac_cv_header_readline_history_h" "$ac_includes_default"
+if test "x$ac_cv_header_readline_history_h" = xyes; then :
+ use_readline=yes
+fi
+
+
+fi
+
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking readline detected" >&5
+$as_echo_n "checking readline detected... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_readline" >&5
+$as_echo "$use_readline" >&6; }
+fi
+if test $use_readline = yes; then
+ WITH_READLINE_01=1
+
+ LIBREADLINE=-lreadline
+
+else
+ WITH_READLINE_01=0
+fi
+for ac_prog in 'bison -y' byacc
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_YACC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_YACC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5
+$as_echo "$YACC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+for ac_prog in flex lex
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LEX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LEX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LEX=$ac_cv_prog_LEX
+if test -n "$LEX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5
+$as_echo "$LEX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=":"
+
+if test "x$LEX" != "x:"; then
+ cat >conftest.l <<_ACEOF
+%%
+a { ECHO; }
+b { REJECT; }
+c { yymore (); }
+d { yyless (1); }
+e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */
+ yyless ((input () != 0)); }
+f { unput (yytext[0]); }
+. { BEGIN INITIAL; }
+%%
+#ifdef YYTEXT_POINTER
+extern char *yytext;
+#endif
+int
+main (void)
+{
+ return ! yylex () + ! yywrap ();
+}
+_ACEOF
+{ { ac_try="$LEX conftest.l"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$LEX conftest.l") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5
+$as_echo_n "checking lex output file root... " >&6; }
+if ${ac_cv_prog_lex_root+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5
+$as_echo "$ac_cv_prog_lex_root" >&6; }
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+if test -z "${LEXLIB+set}"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5
+$as_echo_n "checking lex library... " >&6; }
+if ${ac_cv_lib_lex+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_save_LIBS=$LIBS
+ ac_cv_lib_lex='none needed'
+ for ac_lib in '' -lfl -ll; do
+ LIBS="$ac_lib $ac_save_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_lex=$ac_lib
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ test "$ac_cv_lib_lex" != 'none needed' && break
+ done
+ LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5
+$as_echo "$ac_cv_lib_lex" >&6; }
+ test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5
+$as_echo_n "checking whether yytext is a pointer... " >&6; }
+if ${ac_cv_prog_lex_yytext_pointer+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+ac_save_LIBS=$LIBS
+LIBS="$LEXLIB $ac_save_LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #define YYTEXT_POINTER 1
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_prog_lex_yytext_pointer=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5
+$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; }
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+
+$as_echo "#define YYTEXT_POINTER 1" >>confdefs.h
+
+fi
+rm -f conftest.l $LEX_OUTPUT_ROOT.c
+
+fi
+if test "$LEX" = :; then
+ LEX=${am_missing_run}flex
+fi
+
+# Configs for demos/expr directory
+#
+# Libtool already runs an AC_CHECK_TOOL for ranlib, but we give
+# AC_PROG_RANLIB anyway since automake is supposed to complain if it's not
+# called. (Automake 1.8.4 doesn't, at least not when the only library is in
+# an EXTRA_LIBRARIES.)
+#
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+
+# Create config.m4.
+
+echo "creating $gmp_configm4"
+echo "d""nl $gmp_configm4. Generated automatically by configure." > $gmp_configm4
+if test -f $gmp_tmpconfigm4; then
+ echo "changequote(<,>)" >> $gmp_configm4
+ echo "ifdef(<__CONFIG_M4_INCLUDED__>,,<" >> $gmp_configm4
+ cat $gmp_tmpconfigm4 >> $gmp_configm4
+ echo ">)" >> $gmp_configm4
+ echo "changequote(\`,')" >> $gmp_configm4
+ rm $gmp_tmpconfigm4
+fi
+echo "ifdef(\`__CONFIG_M4_INCLUDED__',,\`" >> $gmp_configm4
+if test -f $gmp_tmpconfigm4i; then
+ cat $gmp_tmpconfigm4i >> $gmp_configm4
+ rm $gmp_tmpconfigm4i
+fi
+if test -f $gmp_tmpconfigm4p; then
+ cat $gmp_tmpconfigm4p >> $gmp_configm4
+ rm $gmp_tmpconfigm4p
+fi
+echo "')" >> $gmp_configm4
+echo "define(\`__CONFIG_M4_INCLUDED__')" >> $gmp_configm4
+
+
+# Create Makefiles
+# FIXME: Upcoming version of autoconf/automake may not like broken lines.
+# Right now automake isn't accepting the new AC_CONFIG_FILES scheme.
+
+ac_config_files="$ac_config_files Makefile mpf/Makefile mpn/Makefile mpq/Makefile mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile tests/Makefile tests/devel/Makefile tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile tests/cxx/Makefile doc/Makefile tune/Makefile demos/Makefile demos/calc/Makefile demos/expr/Makefile gmp.h:gmp-h.in"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WANT_CXX_TRUE}" && test -z "${WANT_CXX_FALSE}"; then
+ as_fn_error $? "conditional \"WANT_CXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_STATIC_TRUE}" && test -z "${ENABLE_STATIC_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_STATIC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by GNU MP $as_me 6.0.0, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_links="$ac_config_links"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration links:
+$config_links
+
+Configuration commands:
+$config_commands
+
+Report bugs to <gmp-bugs@gmplib.org, see https://gmplib.org/manual/Reporting-Bugs.html>.
+GNU MP home page: <http://www.gnu.org/software/gmp/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+GNU MP config.status 6.0.0
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in NM \
+AS \
+DLLTOOL \
+OBJDUMP \
+SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "mpn/$tmp_fn.$tmp_ext") CONFIG_LINKS="$CONFIG_LINKS mpn/$tmp_fn.$tmp_ext:mpn/$tmp_dir/$tmp_base.$tmp_ext" ;;
+ "gmp-mparam.h") CONFIG_LINKS="$CONFIG_LINKS gmp-mparam.h:mpn/$gmp_mparam_dir/gmp-mparam.h" ;;
+ "demos/pexpr-config.h") CONFIG_FILES="$CONFIG_FILES demos/pexpr-config.h:demos/pexpr-config-h.in" ;;
+ "demos/calc/calc-config.h") CONFIG_FILES="$CONFIG_FILES demos/calc/calc-config.h:demos/calc/calc-config-h.in" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "mpf/Makefile") CONFIG_FILES="$CONFIG_FILES mpf/Makefile" ;;
+ "mpn/Makefile") CONFIG_FILES="$CONFIG_FILES mpn/Makefile" ;;
+ "mpq/Makefile") CONFIG_FILES="$CONFIG_FILES mpq/Makefile" ;;
+ "mpz/Makefile") CONFIG_FILES="$CONFIG_FILES mpz/Makefile" ;;
+ "printf/Makefile") CONFIG_FILES="$CONFIG_FILES printf/Makefile" ;;
+ "scanf/Makefile") CONFIG_FILES="$CONFIG_FILES scanf/Makefile" ;;
+ "rand/Makefile") CONFIG_FILES="$CONFIG_FILES rand/Makefile" ;;
+ "cxx/Makefile") CONFIG_FILES="$CONFIG_FILES cxx/Makefile" ;;
+ "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+ "tests/devel/Makefile") CONFIG_FILES="$CONFIG_FILES tests/devel/Makefile" ;;
+ "tests/mpf/Makefile") CONFIG_FILES="$CONFIG_FILES tests/mpf/Makefile" ;;
+ "tests/mpn/Makefile") CONFIG_FILES="$CONFIG_FILES tests/mpn/Makefile" ;;
+ "tests/mpq/Makefile") CONFIG_FILES="$CONFIG_FILES tests/mpq/Makefile" ;;
+ "tests/mpz/Makefile") CONFIG_FILES="$CONFIG_FILES tests/mpz/Makefile" ;;
+ "tests/rand/Makefile") CONFIG_FILES="$CONFIG_FILES tests/rand/Makefile" ;;
+ "tests/misc/Makefile") CONFIG_FILES="$CONFIG_FILES tests/misc/Makefile" ;;
+ "tests/cxx/Makefile") CONFIG_FILES="$CONFIG_FILES tests/cxx/Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "tune/Makefile") CONFIG_FILES="$CONFIG_FILES tune/Makefile" ;;
+ "demos/Makefile") CONFIG_FILES="$CONFIG_FILES demos/Makefile" ;;
+ "demos/calc/Makefile") CONFIG_FILES="$CONFIG_FILES demos/calc/Makefile" ;;
+ "demos/expr/Makefile") CONFIG_FILES="$CONFIG_FILES demos/expr/Makefile" ;;
+ "gmp.h") CONFIG_FILES="$CONFIG_FILES gmp.h:gmp-h.in" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+ :L)
+ #
+ # CONFIG_LINK
+ #
+
+ if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then
+ :
+ else
+ # Prefer the file from the source tree if names are identical.
+ if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then
+ ac_source=$srcdir/$ac_source
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5
+$as_echo "$as_me: linking $ac_source to $ac_file" >&6;}
+
+ if test ! -r "$ac_source"; then
+ as_fn_error $? "$ac_source: file not found" "$LINENO" 5
+ fi
+ rm -f "$ac_file"
+
+ # Try a relative symlink, then a hard link, then a copy.
+ case $ac_source in
+ [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;;
+ *) ac_rel_source=$ac_top_build_prefix$ac_source ;;
+ esac
+ ln -s "$ac_rel_source" "$ac_file" 2>/dev/null ||
+ ln "$ac_source" "$ac_file" 2>/dev/null ||
+ cp -p "$ac_source" "$ac_file" ||
+ as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5
+ fi
+ ;;
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Assembler program.
+AS=$lt_AS
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$lt_OBJDUMP
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ if test x"$xsi_shell" = xyes; then
+ sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\ # positional parameters, so assign one to ordinary parameter first.\
+\ func_stripname_result=${3}\
+\ func_stripname_result=${func_stripname_result#"${1}"}\
+\ func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\ func_split_long_opt_name=${1%%=*}\
+\ func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\ func_split_short_opt_arg=${1#??}\
+\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\ case ${1} in\
+\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\ *) func_lo2o_result=${1} ;;\
+\ esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+ func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+ func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+ func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+ eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\ func_quote_for_eval "${2}"\
+\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: summary of build options:
+
+ Version: ${PACKAGE_STRING}
+ Host type: ${host}
+ ABI: ${ABI}
+ Install prefix: ${prefix}
+ Compiler: ${CC}
+ Static libraries: ${enable_static}
+ Shared libraries: ${enable_shared}
+" >&5
+$as_echo "$as_me: summary of build options:
+
+ Version: ${PACKAGE_STRING}
+ Host type: ${host}
+ ABI: ${ABI}
+ Install prefix: ${prefix}
+ Compiler: ${CC}
+ Static libraries: ${enable_static}
+ Shared libraries: ${enable_shared}
+" >&6;}
+
+if test x$cross_compiling = xyes ; then
+ case "$host" in
+ *-*-mingw* | *-*-cygwin)
+ if test x$ABI = x64 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: If wine64 is installed, use make check TESTS_ENVIRONMENT=wine64." >&5
+$as_echo "$as_me: If wine64 is installed, use make check TESTS_ENVIRONMENT=wine64." >&6;}
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: If wine is installed, use make check TESTS_ENVIRONMENT=wine." >&5
+$as_echo "$as_me: If wine is installed, use make check TESTS_ENVIRONMENT=wine." >&6;}
+ fi
+ ;;
+ esac
+fi
diff --git a/gmp/configure.ac b/gmp/configure.ac
new file mode 100644
index 0000000000..64b2c50957
--- /dev/null
+++ b/gmp/configure.ac
@@ -0,0 +1,3816 @@
+dnl Process this file with autoconf to produce a configure script.
+
+
+define(GMP_COPYRIGHT,[[
+
+Copyright 1996-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+]])
+
+AC_COPYRIGHT(GMP_COPYRIGHT)
+AH_TOP(/*GMP_COPYRIGHT*/)
+
+AC_REVISION($Revision$)
+AC_PREREQ(2.59)
+AC_INIT(GNU MP, GMP_VERSION, [gmp-bugs@gmplib.org, see https://gmplib.org/manual/Reporting-Bugs.html], gmp)
+AC_CONFIG_SRCDIR(gmp-impl.h)
+m4_pattern_forbid([^[ \t]*GMP_])
+m4_pattern_allow(GMP_LDFLAGS)
+m4_pattern_allow(GMP_LIMB_BITS)
+m4_pattern_allow(GMP_MPARAM_H_SUGGEST)
+m4_pattern_allow(GMP_NAIL_BITS)
+m4_pattern_allow(GMP_NUMB_BITS)
+m4_pattern_allow(GMP_NONSTD_ABI)
+m4_pattern_allow(GMP_CPU_TYPE)
+
+# If --target is not used then $target_alias is empty, but if say
+# "./configure athlon-pc-freebsd3.5" is used, then all three of
+# $build_alias, $host_alias and $target_alias are set to
+# "athlon-pc-freebsd3.5".
+#
+if test -n "$target_alias" && test "$target_alias" != "$host_alias"; then
+ AC_MSG_ERROR([--target is not appropriate for GMP
+Use --build=CPU-VENDOR-OS if you need to specify your CPU and/or system
+explicitly. Use --host if cross-compiling (see "Installing GMP" in the
+manual for more on this).])
+fi
+
+GMP_INIT(config.m4)
+
+AC_CANONICAL_HOST
+
+dnl Automake "no-dependencies" is used because include file dependencies
+dnl are not useful to us. Pretty much everything depends just on gmp.h,
+dnl gmp-impl.h and longlong.h, and yet only rarely does everything need to
+dnl be rebuilt for changes to those files.
+dnl
+dnl "no-dependencies" also helps with the way we're setup to run
+dnl AC_PROG_CXX only conditionally. If dependencies are used then recent
+dnl automake (eg 1.7.2) appends an AM_CONDITIONAL to AC_PROG_CXX, and then
+dnl gets upset if it's not actually executed.
+dnl
+dnl Note that there's a copy of these options in the top-level Makefile.am,
+dnl so update there too if changing anything.
+dnl
+AM_INIT_AUTOMAKE([1.8 gnu no-dependencies])
+AC_CONFIG_HEADERS(config.h:config.in)
+AM_MAINTAINER_MODE
+
+
+AC_ARG_ENABLE(assert,
+AC_HELP_STRING([--enable-assert],[enable ASSERT checking [[default=no]]]),
+[case $enableval in
+yes|no) ;;
+*) AC_MSG_ERROR([bad value $enableval for --enable-assert, need yes or no]) ;;
+esac],
+[enable_assert=no])
+
+if test "$enable_assert" = "yes"; then
+ AC_DEFINE(WANT_ASSERT,1,
+ [Define to 1 to enable ASSERT checking, per --enable-assert])
+ want_assert_01=1
+else
+ want_assert_01=0
+fi
+GMP_DEFINE_RAW(["define(<WANT_ASSERT>,$want_assert_01)"])
+
+
+AC_ARG_ENABLE(alloca,
+AC_HELP_STRING([--enable-alloca],[how to get temp memory [[default=reentrant]]]),
+[case $enableval in
+alloca|malloc-reentrant|malloc-notreentrant) ;;
+yes|no|reentrant|notreentrant) ;;
+debug) ;;
+*)
+ AC_MSG_ERROR([bad value $enableval for --enable-alloca, need one of:
+yes no reentrant notreentrant alloca malloc-reentrant malloc-notreentrant debug]) ;;
+esac],
+[enable_alloca=reentrant])
+
+
+# IMPROVE ME: The default for C++ is disabled. The tests currently
+# performed below for a working C++ compiler are not particularly strong,
+# and in general can't be expected to get the right setup on their own. The
+# most significant problem is getting the ABI the same. Defaulting CXXFLAGS
+# to CFLAGS takes only a small step towards this. It's also probably worth
+# worrying whether the C and C++ runtimes from say gcc and a vendor C++ can
+# work together. Some rather broken C++ installations were encountered
+# during testing, and though such things clearly aren't GMP's problem, if
+# --enable-cxx=detect were to be the default then some careful checks of
+# which, if any, C++ compiler on the system is up to scratch would be
+# wanted.
+#
+AC_ARG_ENABLE(cxx,
+AC_HELP_STRING([--enable-cxx],[enable C++ support [[default=no]]]),
+[case $enableval in
+yes|no|detect) ;;
+*) AC_MSG_ERROR([bad value $enableval for --enable-cxx, need yes/no/detect]) ;;
+esac],
+[enable_cxx=no])
+
+
+AC_ARG_ENABLE(assembly,
+AC_HELP_STRING([--enable-assembly],[enable the use of assembly loops [[default=yes]]]),
+[case $enableval in
+yes|no) ;;
+*) AC_MSG_ERROR([bad value $enableval for --enable-assembly, need yes or no]) ;;
+esac],
+[enable_assembly=yes])
+
+if test "$enable_assembly" = "yes"; then
+ AC_DEFINE(WANT_ASSEMBLY,1,
+ [Defined to 1 as per --enable-assembly])
+fi
+
+
+AC_ARG_ENABLE(fft,
+AC_HELP_STRING([--enable-fft],[enable FFTs for multiplication [[default=yes]]]),
+[case $enableval in
+yes|no) ;;
+*) AC_MSG_ERROR([bad value $enableval for --enable-fft, need yes or no]) ;;
+esac],
+[enable_fft=yes])
+
+if test "$enable_fft" = "yes"; then
+ AC_DEFINE(WANT_FFT,1,
+ [Define to 1 to enable FFTs for multiplication, per --enable-fft])
+fi
+
+
+AC_ARG_ENABLE(old-fft-full,
+AC_HELP_STRING([--enable-old-fft-full],[enable old mpn_mul_fft_full for multiplication [[default=no]]]),
+[case $enableval in
+yes|no) ;;
+*) AC_MSG_ERROR([bad value $enableval for --enable-old-fft-full, need yes or no]) ;;
+esac],
+[enable_old_fft_full=no])
+
+if test "$enable_old_fft_full" = "yes"; then
+ AC_DEFINE(WANT_OLD_FFT_FULL,1,
+ [Define to 1 to enable old mpn_mul_fft_full for multiplication, per --enable-old-fft-full])
+fi
+
+
+AC_ARG_ENABLE(nails,
+AC_HELP_STRING([--enable-nails],[use nails on limbs [[default=no]]]),
+[case $enableval in
+[yes|no|[02468]|[0-9][02468]]) ;;
+[*[13579]])
+ AC_MSG_ERROR([bad value $enableval for --enable-nails, only even nail sizes supported]) ;;
+*)
+ AC_MSG_ERROR([bad value $enableval for --enable-nails, need yes/no/number]) ;;
+esac],
+[enable_nails=no])
+
+case $enable_nails in
+yes) GMP_NAIL_BITS=2 ;;
+no) GMP_NAIL_BITS=0 ;;
+*) GMP_NAIL_BITS=$enable_nails ;;
+esac
+AC_SUBST(GMP_NAIL_BITS)
+
+
+AC_ARG_ENABLE(profiling,
+AC_HELP_STRING([--enable-profiling],
+ [build with profiler support [[default=no]]]),
+[case $enableval in
+no|prof|gprof|instrument) ;;
+*) AC_MSG_ERROR([bad value $enableval for --enable-profiling, need no/prof/gprof/instrument]) ;;
+esac],
+[enable_profiling=no])
+
+case $enable_profiling in
+ prof)
+ AC_DEFINE(WANT_PROFILING_PROF, 1,
+ [Define to 1 if --enable-profiling=prof])
+ ;;
+ gprof)
+ AC_DEFINE(WANT_PROFILING_GPROF, 1,
+ [Define to 1 if --enable-profiling=gprof])
+ ;;
+ instrument)
+ AC_DEFINE(WANT_PROFILING_INSTRUMENT, 1,
+ [Define to 1 if --enable-profiling=instrument])
+ ;;
+esac
+
+GMP_DEFINE_RAW(["define(<WANT_PROFILING>,<\`$enable_profiling'>)"])
+
+# -fomit-frame-pointer is incompatible with -pg on some chips
+if test "$enable_profiling" = gprof; then
+ fomit_frame_pointer=
+else
+ fomit_frame_pointer="-fomit-frame-pointer"
+fi
+
+
+AC_ARG_WITH(readline,
+AC_HELP_STRING([--with-readline],
+ [readline support in calc demo program [[default=detect]]]),
+[case $withval in
+yes|no|detect) ;;
+*) AC_MSG_ERROR([bad value $withval for --with-readline, need yes/no/detect]) ;;
+esac],
+[with_readline=detect])
+
+
+AC_ARG_ENABLE(fat,
+AC_HELP_STRING([--enable-fat],
+ [build a fat binary on systems that support it [[default=no]]]),
+[case $enableval in
+yes|no) ;;
+*) AC_MSG_ERROR([bad value $enableval for --enable-fat, need yes or no]) ;;
+esac],
+[enable_fat=no])
+
+
+AC_ARG_ENABLE(minithres,
+AC_HELP_STRING([--enable-minithres],
+ [choose minimal thresholds for testing [[default=no]]]),
+[case $enableval in
+yes|no) ;;
+*) AC_MSG_ERROR([bad value $enableval for --enable-minithres, need yes or no]) ;;
+esac],
+[enable_minithres=no])
+
+
+AC_ARG_ENABLE(fake-cpuid,
+AC_HELP_STRING([--enable-fake-cpuid],[enable GMP_CPU_TYPE faking cpuid [[default=no]]]),
+[case $enableval in
+yes|no) ;;
+*) AC_MSG_ERROR([bad value $enableval for --enable-fake-cpuid, need yes or no]) ;;
+esac],
+[enable_fake_cpuid=no])
+
+if test "$enable_fake_cpuid" = "yes"; then
+ AC_DEFINE(WANT_FAKE_CPUID,1,
+ [Define to 1 to enable GMP_CPU_TYPE faking cpuid, per --enable-fake-cpuid])
+fi
+
+
+if test $enable_fat = yes && test $enable_assembly = no ; then
+ AC_MSG_ERROR([when doing a fat build, disabling assembly will not work])
+fi
+
+if test $enable_fake_cpuid = yes && test $enable_fat = no ; then
+ AC_MSG_ERROR([--enable-fake-cpuid requires --enable-fat])
+fi
+
+
+tmp_host=`echo $host_cpu | sed 's/\./_/'`
+AC_DEFINE_UNQUOTED(HAVE_HOST_CPU_$tmp_host)
+GMP_DEFINE_RAW("define_not_for_expansion(\`HAVE_HOST_CPU_$tmp_host')", POST)
+
+dnl The HAVE_HOST_CPU_ list here only needs to have entries for those which
+dnl are going to be tested, not everything that can possibly be selected.
+dnl
+dnl The HAVE_HOST_CPU_FAMILY_ list similarly, and note that the AC_DEFINEs
+dnl for these are under the cpu specific setups below.
+
+AH_VERBATIM([HAVE_HOST_CPU_1],
+[/* Define one of these to 1 for the host CPU family.
+ If your CPU is not in any of these families, leave all undefined.
+ For an AMD64 chip, define "x86" in ABI=32, but not in ABI=64. */
+#undef HAVE_HOST_CPU_FAMILY_alpha
+#undef HAVE_HOST_CPU_FAMILY_m68k
+#undef HAVE_HOST_CPU_FAMILY_power
+#undef HAVE_HOST_CPU_FAMILY_powerpc
+#undef HAVE_HOST_CPU_FAMILY_x86
+#undef HAVE_HOST_CPU_FAMILY_x86_64
+
+/* Define one of the following to 1 for the host CPU, as per the output of
+ ./config.guess. If your CPU is not listed here, leave all undefined. */
+#undef HAVE_HOST_CPU_alphaev67
+#undef HAVE_HOST_CPU_alphaev68
+#undef HAVE_HOST_CPU_alphaev7
+#undef HAVE_HOST_CPU_m68020
+#undef HAVE_HOST_CPU_m68030
+#undef HAVE_HOST_CPU_m68040
+#undef HAVE_HOST_CPU_m68060
+#undef HAVE_HOST_CPU_m68360
+#undef HAVE_HOST_CPU_powerpc604
+#undef HAVE_HOST_CPU_powerpc604e
+#undef HAVE_HOST_CPU_powerpc750
+#undef HAVE_HOST_CPU_powerpc7400
+#undef HAVE_HOST_CPU_supersparc
+#undef HAVE_HOST_CPU_i386
+#undef HAVE_HOST_CPU_i586
+#undef HAVE_HOST_CPU_i686
+#undef HAVE_HOST_CPU_pentium
+#undef HAVE_HOST_CPU_pentiummmx
+#undef HAVE_HOST_CPU_pentiumpro
+#undef HAVE_HOST_CPU_pentium2
+#undef HAVE_HOST_CPU_pentium3
+#undef HAVE_HOST_CPU_s390_z900
+#undef HAVE_HOST_CPU_s390_z990
+#undef HAVE_HOST_CPU_s390_z9
+#undef HAVE_HOST_CPU_s390_z10
+#undef HAVE_HOST_CPU_s390_z196
+
+/* Define to 1 iff we have a s390 with 64-bit registers. */
+#undef HAVE_HOST_CPU_s390_zarch])
+
+
+# Table of compilers, options, and mpn paths. This code has various related
+# purposes
+#
+# - better default CC/CFLAGS selections than autoconf otherwise gives
+# - default CC/CFLAGS selections for extra CPU types specific to GMP
+# - a few tests for known bad compilers
+# - choice of ABIs on suitable systems
+# - selection of corresponding mpn search path
+#
+# After GMP specific searches and tests, the standard autoconf AC_PROG_CC is
+# called. User selections of CC etc are respected.
+#
+# Care is taken not to use macros like AC_TRY_COMPILE during the GMP
+# pre-testing, since they of course depend on AC_PROG_CC, and also some of
+# them cache their results, which is not wanted.
+#
+# The ABI selection mechanism is unique to GMP. All that reaches autoconf
+# is a different selection of CC/CFLAGS according to the best ABI the system
+# supports, and/or what the user selects. Naturally the mpn assembler code
+# selected is very dependent on the ABI.
+#
+# The closest the standard tools come to a notion of ABI is something like
+# "sparc64" which encodes a CPU and an ABI together. This doesn't seem to
+# scale well for GMP, where exact CPU types like "ultrasparc2" are wanted,
+# separate from the ABI used on them.
+#
+#
+# The variables set here are
+#
+# cclist the compiler choices
+# xx_cflags flags for compiler xx
+# xx_cflags_maybe flags for compiler xx, if they work
+# xx_cppflags cpp flags for compiler xx
+# xx_cflags_optlist list of sets of optional flags
+# xx_cflags_yyy set yyy of optional flags for compiler xx
+# xx_ldflags -Wc,-foo flags for libtool linking with compiler xx
+# ar_flags extra flags for $AR
+# nm_flags extra flags for $NM
+# limb limb size, can be "longlong"
+# path mpn search path
+# extra_functions extra mpn functions
+# fat_path fat binary mpn search path [if fat binary desired]
+# fat_functions fat functions
+# fat_thresholds fat thresholds
+#
+# Suppose xx_cflags_optlist="arch", then flags from $xx_cflags_arch are
+# tried, and the first flag that works will be used. An optlist like "arch
+# cpu optimize" can be used to get multiple independent sets of flags tried.
+# The first that works from each will be used. If no flag in a set works
+# then nothing from that set is added.
+#
+# For multiple ABIs, the scheme extends as follows.
+#
+# abilist set of ABI choices
+# cclist_aa compiler choices in ABI aa
+# xx_aa_cflags flags for xx in ABI aa
+# xx_aa_cflags_maybe flags for xx in ABI aa, if they work
+# xx_aa_cppflags cpp flags for xx in ABI aa
+# xx_aa_cflags_optlist list of sets of optional flags in ABI aa
+# xx_aa_cflags_yyy set yyy of optional flags for compiler xx in ABI aa
+# xx_aa_ldflags -Wc,-foo flags for libtool linking
+# ar_aa_flags extra flags for $AR in ABI aa
+# nm_aa_flags extra flags for $NM in ABI aa
+# limb_aa limb size in ABI aa, can be "longlong"
+# path_aa mpn search path in ABI aa
+# extra_functions_aa extra mpn functions in ABI aa
+#
+# As a convenience, the unadorned xx_cflags (etc) are used for the last ABI
+# in ablist, if an xx_aa_cflags for that ABI isn't given. For example if
+# abilist="64 32" then $cc_64_cflags will be used for the 64-bit ABI, but
+# for the 32-bit either $cc_32_cflags or $cc_cflags is used, whichever is
+# defined. This makes it easy to add some 64-bit compilers and flags to an
+# unadorned 32-bit set.
+#
+# limb=longlong (or limb_aa=longlong) applies to all compilers within that
+# ABI. It won't work to have some needing long long and some not, since a
+# single instantiated gmp.h will be used by both.
+#
+# SPEED_CYCLECOUNTER, cyclecounter_size and CALLING_CONVENTIONS_OBJS are
+# also set here, with an ABI suffix.
+#
+#
+#
+# A table-driven approach like this to mapping cpu type to good compiler
+# options is a bit of a maintenance burden, but there's not much uniformity
+# between options specifications on different compilers. Some sort of
+# separately updatable tool might be cute.
+#
+# The use of lots of variables like this, direct and indirect, tends to
+# obscure when and how various things are done, but unfortunately it's
+# pretty much the only way. If shell subroutines were portable then actual
+# code like "if this .. do that" could be written, but attempting the same
+# with full copies of GMP_PROG_CC_WORKS etc expanded at every point would
+# hugely bloat the output.
+
+
+AC_ARG_VAR(ABI, [desired ABI (for processors supporting more than one ABI)])
+
+# abilist needs to be non-empty, "standard" is just a generic name here
+abilist="standard"
+
+# FIXME: We'd like to prefer an ANSI compiler, perhaps by preferring
+# c89 over cc here. But note that on HP-UX c89 provides a castrated
+# environment, and would want to be excluded somehow. Maybe
+# AC_PROG_CC_STDC already does enough to stick cc into ANSI mode and
+# we don't need to worry.
+#
+cclist="gcc cc"
+
+gcc_cflags="-O2 -pedantic"
+gcc_64_cflags="-O2 -pedantic"
+cc_cflags="-O"
+cc_64_cflags="-O"
+
+SPEED_CYCLECOUNTER_OBJ=
+cyclecounter_size=2
+
+AC_SUBST(HAVE_HOST_CPU_FAMILY_power, 0)
+AC_SUBST(HAVE_HOST_CPU_FAMILY_powerpc,0)
+
+case $host in
+
+ alpha*-*-*)
+ AC_DEFINE(HAVE_HOST_CPU_FAMILY_alpha)
+ case $host_cpu in
+ alphaev5* | alphapca5*)
+ path="alpha/ev5 alpha" ;;
+ alphaev67 | alphaev68 | alphaev7*)
+ path="alpha/ev67 alpha/ev6 alpha" ;;
+ alphaev6)
+ path="alpha/ev6 alpha" ;;
+ *)
+ path="alpha" ;;
+ esac
+ if test "$enable_assembly" = "yes" ; then
+ extra_functions="cntlz"
+ fi
+ gcc_cflags_optlist="asm cpu oldas" # need asm ahead of cpu, see below
+ gcc_cflags_maybe="-mieee"
+ gcc_cflags_oldas="-Wa,-oldas" # see GMP_GCC_WA_OLDAS.
+
+ # gcc 2.7.2.3 doesn't know any -mcpu= for alpha, apparently.
+ # gcc 2.95 knows -mcpu= ev4, ev5, ev56, pca56, ev6.
+ # gcc 3.0 adds nothing.
+ # gcc 3.1 adds ev45, ev67 (but ev45 is the same as ev4).
+ # gcc 3.2 adds nothing.
+ #
+ # gcc version "2.9-gnupro-99r1" under "-O2 -mcpu=ev6" strikes internal
+ # compiler errors too easily and is rejected by GMP_PROG_CC_WORKS. Each
+ # -mcpu=ev6 below has a fallback to -mcpu=ev56 for this reason.
+ #
+ case $host_cpu in
+ alpha) gcc_cflags_cpu="-mcpu=ev4" ;;
+ alphaev5) gcc_cflags_cpu="-mcpu=ev5" ;;
+ alphaev56) gcc_cflags_cpu="-mcpu=ev56" ;;
+ alphapca56 | alphapca57)
+ gcc_cflags_cpu="-mcpu=pca56" ;;
+ alphaev6) gcc_cflags_cpu="-mcpu=ev6 -mcpu=ev56" ;;
+ alphaev67 | alphaev68 | alphaev7*)
+ gcc_cflags_cpu="-mcpu=ev67 -mcpu=ev6 -mcpu=ev56" ;;
+ esac
+
+ # gcc version "2.9-gnupro-99r1" on alphaev68-dec-osf5.1 has been seen
+ # accepting -mcpu=ev6, but not putting the assembler in the right mode
+ # for what it produces. We need to do this for it, and need to do it
+ # before testing the -mcpu options.
+ #
+ # On old versions of gcc, which don't know -mcpu=, we believe an
+ # explicit -Wa,-mev5 etc will be necessary to put the assembler in
+ # the right mode for our .asm files and longlong.h asm blocks.
+ #
+ # On newer versions of gcc, when -mcpu= is known, we must give a -Wa
+ # which is at least as high as the code gcc will generate. gcc
+ # establishes what it needs with a ".arch" directive, our command line
+ # option seems to override that.
+ #
+ # gas prior to 2.14 doesn't accept -mev67, but -mev6 seems enough for
+ # ctlz and cttz (in 2.10.0 at least).
+ #
+ # OSF `as' accepts ev68 but stupidly treats it as ev4. -arch only seems
+ # to affect insns like ldbu which are expanded as macros when necessary.
+ # Insns like ctlz which were never available as macros are always
+ # accepted and always generate their plain code.
+ #
+ case $host_cpu in
+ alpha) gcc_cflags_asm="-Wa,-arch,ev4 -Wa,-mev4" ;;
+ alphaev5) gcc_cflags_asm="-Wa,-arch,ev5 -Wa,-mev5" ;;
+ alphaev56) gcc_cflags_asm="-Wa,-arch,ev56 -Wa,-mev56" ;;
+ alphapca56 | alphapca57)
+ gcc_cflags_asm="-Wa,-arch,pca56 -Wa,-mpca56" ;;
+ alphaev6) gcc_cflags_asm="-Wa,-arch,ev6 -Wa,-mev6" ;;
+ alphaev67 | alphaev68 | alphaev7*)
+ gcc_cflags_asm="-Wa,-arch,ev67 -Wa,-mev67 -Wa,-arch,ev6 -Wa,-mev6" ;;
+ esac
+
+ # It might be better to ask "cc" whether it's Cray C or DEC C,
+ # instead of relying on the OS part of $host. But it's hard to
+ # imagine either of those compilers anywhere except their native
+ # systems.
+ #
+ GMP_INCLUDE_MPN(alpha/alpha-defs.m4)
+ case $host in
+ *-cray-unicos*)
+ cc_cflags="-O" # no -g, it silently disables all optimizations
+ GMP_INCLUDE_MPN(alpha/unicos.m4)
+ # Don't perform any assembly syntax tests on this beast.
+ gmp_asm_syntax_testing=no
+ ;;
+ *-*-osf*)
+ GMP_INCLUDE_MPN(alpha/default.m4)
+ cc_cflags=""
+ cc_cflags_optlist="opt cpu"
+
+ # not sure if -fast works on old versions, so make it optional
+ cc_cflags_opt="-fast -O2"
+
+ # DEC C V5.9-005 knows ev4, ev5, ev56, pca56, ev6.
+ # Compaq C V6.3-029 adds ev67.
+ #
+ case $host_cpu in
+ alpha) cc_cflags_cpu="-arch~ev4~-tune~ev4" ;;
+ alphaev5) cc_cflags_cpu="-arch~ev5~-tune~ev5" ;;
+ alphaev56) cc_cflags_cpu="-arch~ev56~-tune~ev56" ;;
+ alphapca56 | alphapca57)
+ cc_cflags_cpu="-arch~pca56~-tune~pca56" ;;
+ alphaev6) cc_cflags_cpu="-arch~ev6~-tune~ev6" ;;
+ alphaev67 | alphaev68 | alphaev7*)
+ cc_cflags_cpu="-arch~ev67~-tune~ev67 -arch~ev6~-tune~ev6" ;;
+ esac
+ ;;
+ *)
+ GMP_INCLUDE_MPN(alpha/default.m4)
+ ;;
+ esac
+
+ case $host in
+ *-*-unicos*)
+ # tune/alpha.asm assumes int==4bytes but unicos uses int==8bytes
+ ;;
+ *)
+ SPEED_CYCLECOUNTER_OBJ=alpha.lo
+ cyclecounter_size=1 ;;
+ esac
+ ;;
+
+
+ # Cray vector machines.
+ # This must come after alpha* so that we can recognize present and future
+ # vector processors with a wildcard.
+ *-cray-unicos*)
+ gmp_asm_syntax_testing=no
+ cclist="cc"
+ # We used to have -hscalar0 here as a workaround for miscompilation of
+ # mpz/import.c, but let's hope Cray fixes their bugs instead, since
+ # -hscalar0 causes disastrously poor code to be generated.
+ cc_cflags="-O3 -hnofastmd -htask0 -Wa,-B"
+ path="cray"
+ ;;
+
+
+ arm64*-*-* | aarch64*-*-*)
+ path="arm64"
+ ;;
+
+
+ arm*-*-*)
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ gcc_cflags_optlist="arch neon tune"
+ gcc_cflags_maybe="-marm"
+ gcc_testlist="gcc-arm-umodsi"
+ GMP_INCLUDE_MPN(arm/arm-defs.m4)
+ CALLING_CONVENTIONS_OBJS='arm32call.lo arm32check.lo'
+
+ # FIXME: We make mandatory compiler options optional here. We should
+ # either enforce them, or organise to strip paths as the corresponding
+ # options fail.
+ case $host_cpu in
+ armsa1 | arm9tdmi | armv4*)
+ path="arm"
+ gcc_cflags_arch="-march=armv4"
+ ;;
+ armxscale | arm9te | arm10 | armv5*)
+ path="arm/v5 arm"
+ gcc_cflags_arch="-march=armv5"
+ ;;
+ arm11mpcore | arm1136 | arm1176 | armv6*)
+ path="arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv6"
+ ;;
+ arm1156)
+ path="arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv6t2"
+ ;;
+ armcortexa5 | armv7a*)
+ path="arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv7-a"
+ ;;
+ armcortexa8)
+ path="arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_tune="-mtune=cortex-a8"
+ ;;
+ armcortexa8neon)
+ path="arm/v6t2 arm/v6 arm/v5 arm/neon arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_neon="-mfpu=neon"
+ gcc_cflags_tune="-mtune=cortex-a8"
+ ;;
+ armcortexa9)
+ path="arm/v7a/cora9 arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_tune="-mtune=cortex-a9"
+ ;;
+ armcortexa9neon)
+ path="arm/v7a/cora9 arm/v6t2 arm/v6 arm/v5 arm/neon arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_neon="-mfpu=neon"
+ gcc_cflags_tune="-mtune=cortex-a9"
+ ;;
+ armcortexa15)
+ path="arm/v7a/cora15 arm/v6t2 arm/v6 arm/v5 arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_tune="-mtune=cortex-a15 -mtune=cortex-a9"
+ ;;
+ armcortexa15neon)
+ path="arm/v7a/cora15/neon arm/v7a/cora15 arm/v6t2 arm/v6 arm/v5 arm/neon arm"
+ gcc_cflags_arch="-march=armv7-a"
+ gcc_cflags_neon="-mfpu=neon"
+ gcc_cflags_tune="-mtune=cortex-a15 -mtune=cortex-a9"
+ ;;
+ *)
+ path="arm"
+ ;;
+ esac
+ ;;
+
+
+ # Fujitsu
+ [f30[01]-fujitsu-sysv*])
+ cclist="gcc vcc"
+ # FIXME: flags for vcc?
+ vcc_cflags="-g"
+ path="fujitsu"
+ ;;
+
+
+ hppa*-*-*)
+ # HP cc (the one sold separately) is K&R by default, but AM_C_PROTOTYPES
+ # will add "-Ae", or "-Aa -D_HPUX_SOURCE", to put it into ansi mode, if
+ # possible.
+ #
+ # gcc for hppa 2.0 can be built either for 2.0n (32-bit) or 2.0w
+ # (64-bit), but not both, so there's no option to choose the desired
+ # mode, we must instead detect which of the two it is. This is done by
+ # checking sizeof(long), either 4 or 8 bytes respectively. Do this in
+ # ABI=1.0 too, in case someone tries to build that with a 2.0w gcc.
+ #
+ gcc_cflags_optlist="arch"
+ gcc_testlist="sizeof-long-4"
+ SPEED_CYCLECOUNTER_OBJ=hppa.lo
+ cyclecounter_size=1
+
+ # FIXME: For hppa2.0*, path should be "pa32/hppa2_0 pa32/hppa1_1 pa32".
+ # (Can't remember why this isn't done already, have to check what .asm
+ # files are available in each and how they run on a typical 2.0 cpu.)
+ #
+ case $host_cpu in
+ hppa1.0*) path="pa32" ;;
+ hppa7000*) path="pa32/hppa1_1 pa32" ;;
+ hppa2.0* | hppa64)
+ path="pa32/hppa2_0 pa32/hppa1_1/pa7100 pa32/hppa1_1 pa32" ;;
+ *) # default to 7100
+ path="pa32/hppa1_1/pa7100 pa32/hppa1_1 pa32" ;;
+ esac
+
+ # gcc 2.7.2.3 knows -mpa-risc-1-0 and -mpa-risc-1-1
+ # gcc 2.95 adds -mpa-risc-2-0, plus synonyms -march=1.0, 1.1 and 2.0
+ #
+ # We don't use -mpa-risc-2-0 in ABI=1.0 because 64-bit registers may not
+ # be saved by the kernel on an old system. Actually gcc (as of 3.2)
+ # only adds a few float instructions with -mpa-risc-2-0, so it would
+ # probably be safe, but let's not take the chance. In any case, a
+ # configuration like --host=hppa2.0 ABI=1.0 is far from optimal.
+ #
+ case $host_cpu in
+ hppa1.0*) gcc_cflags_arch="-mpa-risc-1-0" ;;
+ *) # default to 7100
+ gcc_cflags_arch="-mpa-risc-1-1" ;;
+ esac
+
+ case $host_cpu in
+ hppa1.0*) cc_cflags="+O2" ;;
+ *) # default to 7100
+ cc_cflags="+DA1.1 +O2" ;;
+ esac
+
+ case $host in
+ hppa2.0*-*-* | hppa64-*-*)
+ cclist_20n="gcc cc"
+ abilist="2.0n 1.0"
+ path_20n="pa64"
+ limb_20n=longlong
+ any_20n_testlist="sizeof-long-4"
+ SPEED_CYCLECOUNTER_OBJ_20n=hppa2.lo
+ cyclecounter_size_20n=2
+
+ # -mpa-risc-2-0 is only an optional flag, in case an old gcc is
+ # used. Assembler support for 2.0 is essential though, for our asm
+ # files.
+ gcc_20n_cflags="$gcc_cflags"
+ gcc_20n_cflags_optlist="arch"
+ gcc_20n_cflags_arch="-mpa-risc-2-0 -mpa-risc-1-1"
+ gcc_20n_testlist="sizeof-long-4 hppa-level-2.0"
+
+ cc_20n_cflags="+DA2.0 +e +O2 -Wl,+vnocompatwarnings"
+ cc_20n_testlist="hpc-hppa-2-0"
+
+ # ABI=2.0w is available for hppa2.0w and hppa2.0, but not for
+ # hppa2.0n, on the assumption that that the latter indicates a
+ # desire for ABI=2.0n.
+ case $host in
+ hppa2.0n-*-*) ;;
+ *)
+ # HPUX 10 and earlier cannot run 2.0w. Not sure about other
+ # systems (GNU/Linux for instance), but lets assume they're ok.
+ case $host in
+ [*-*-hpux[1-9] | *-*-hpux[1-9].* | *-*-hpux10 | *-*-hpux10.*]) ;;
+ [*-*-linux*]) abilist="1.0" ;; # due to linux permanent kernel bug
+ *) abilist="2.0w $abilist" ;;
+ esac
+
+ cclist_20w="gcc cc"
+ gcc_20w_cflags="$gcc_cflags -mpa-risc-2-0"
+ cc_20w_cflags="+DD64 +O2"
+ cc_20w_testlist="hpc-hppa-2-0"
+ path_20w="pa64"
+ any_20w_testlist="sizeof-long-8"
+ SPEED_CYCLECOUNTER_OBJ_20w=hppa2w.lo
+ cyclecounter_size_20w=2
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+
+ IA64_PATTERN)
+ abilist="64"
+ GMP_INCLUDE_MPN(ia64/ia64-defs.m4)
+ SPEED_CYCLECOUNTER_OBJ=ia64.lo
+ any_32_testlist="sizeof-long-4"
+
+ case $host_cpu in
+ itanium) path="ia64/itanium ia64" ;;
+ itanium2) path="ia64/itanium2 ia64" ;;
+ *) path="ia64" ;;
+ esac
+
+ gcc_64_cflags_optlist="tune"
+ gcc_32_cflags_optlist=$gcc_64_cflags_optlist
+
+ # gcc pre-release 3.4 adds -mtune itanium and itanium2
+ case $host_cpu in
+ itanium) gcc_cflags_tune="-mtune=itanium" ;;
+ itanium2) gcc_cflags_tune="-mtune=itanium2" ;;
+ esac
+
+ case $host in
+ *-*-linux*)
+ cclist="gcc icc"
+ icc_cflags="-no-gcc"
+ icc_cflags_optlist="opt"
+ # Don't use -O3, it is for "large data sets" and also miscompiles GMP.
+ # But icc miscompiles GMP at any optimization level, at higher levels
+ # it miscompiles more files...
+ icc_cflags_opt="-O2 -O1"
+ ;;
+
+ *-*-hpux*)
+ # HP cc sometimes gets internal errors if the optimization level is
+ # too high. GMP_PROG_CC_WORKS detects this, the "_opt" fallbacks
+ # let us use whatever seems to work.
+ #
+ abilist="32 64"
+ any_64_testlist="sizeof-long-8"
+
+ cclist_32="gcc cc"
+ path_32="ia64"
+ cc_32_cflags=""
+ cc_32_cflags_optlist="opt"
+ cc_32_cflags_opt="+O3 +O2 +O1"
+ gcc_32_cflags="$gcc_cflags -milp32"
+ limb_32=longlong
+ SPEED_CYCLECOUNTER_OBJ_32=ia64.lo
+ cyclecounter_size_32=2
+
+ # Must have +DD64 in CPPFLAGS to get the right __LP64__ for headers,
+ # but also need it in CFLAGS for linking programs, since automake
+ # only uses CFLAGS when linking, not CPPFLAGS.
+ # FIXME: Maybe should use cc_64_ldflags for this, but that would
+ # need GMP_LDFLAGS used consistently by all the programs.
+ #
+ cc_64_cflags="+DD64"
+ cc_64_cppflags="+DD64"
+ cc_64_cflags_optlist="opt"
+ cc_64_cflags_opt="+O3 +O2 +O1"
+ gcc_64_cflags="$gcc_cflags -mlp64"
+ ;;
+ esac
+ ;;
+
+
+ # Motorola 68k
+ #
+ M68K_PATTERN)
+ AC_DEFINE(HAVE_HOST_CPU_FAMILY_m68k)
+ GMP_INCLUDE_MPN(m68k/m68k-defs.m4)
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ gcc_cflags_optlist="arch"
+
+ # gcc 2.7.2 knows -m68000, -m68020, -m68030, -m68040.
+ # gcc 2.95 adds -mcpu32, -m68060.
+ # FIXME: Maybe "-m68020 -mnobitfield" would suit cpu32 on 2.7.2.
+ #
+ case $host_cpu in
+ m68020) gcc_cflags_arch="-m68020" ;;
+ m68030) gcc_cflags_arch="-m68030" ;;
+ m68040) gcc_cflags_arch="-m68040" ;;
+ m68060) gcc_cflags_arch="-m68060 -m68000" ;;
+ m68360) gcc_cflags_arch="-mcpu32 -m68000" ;;
+ *) gcc_cflags_arch="-m68000" ;;
+ esac
+
+ # FIXME: m68k/mc68020 looks like it's ok for cpu32, but this wants to be
+ # tested. Will need to introduce an m68k/cpu32 if m68k/mc68020 ever uses
+ # the bitfield instructions.
+ case $host_cpu in
+ [m680[234]0 | m68360]) path="m68k/mc68020 m68k" ;;
+ *) path="m68k" ;;
+ esac
+ ;;
+
+
+ # Motorola 88k
+ m88k*-*-*)
+ path="m88k"
+ ;;
+ m88110*-*-*)
+ gcc_cflags="$gcc_cflags -m88110"
+ path="m88k/mc88110 m88k"
+ ;;
+
+
+ # IRIX 5 and earlier can only run 32-bit o32.
+ #
+ # IRIX 6 and up always has a 64-bit mips CPU can run n32 or 64. n32 is
+ # preferred over 64, but only because that's been the default in past
+ # versions of GMP. The two are equally efficient.
+ #
+ # Linux kernel 2.2.13 arch/mips/kernel/irixelf.c has a comment about not
+ # supporting n32 or 64.
+ #
+ # For reference, libtool (eg. 1.5.6) recognises the n32 ABI and knows the
+ # right options to use when linking (both cc and gcc), so no need for
+ # anything special from us.
+ #
+ mips*-*-*)
+ abilist="o32"
+ gcc_cflags_optlist="abi"
+ gcc_cflags_abi="-mabi=32"
+ gcc_testlist="gcc-mips-o32"
+ path="mips32"
+ cc_cflags="-O2 -o32" # no -g, it disables all optimizations
+ # this suits both mips32 and mips64
+ GMP_INCLUDE_MPN(mips32/mips-defs.m4)
+
+ case $host in
+ [mips64*-*-* | mips*-*-irix[6789]*])
+ abilist="n32 64 o32"
+
+ cclist_n32="gcc cc"
+ gcc_n32_cflags="$gcc_cflags -mabi=n32"
+ cc_n32_cflags="-O2 -n32" # no -g, it disables all optimizations
+ limb_n32=longlong
+ path_n32="mips64"
+
+ cclist_64="gcc cc"
+ gcc_64_cflags="$gcc_cflags -mabi=64"
+ gcc_64_ldflags="-Wc,-mabi=64"
+ cc_64_cflags="-O2 -64" # no -g, it disables all optimizations
+ cc_64_ldflags="-Wc,-64"
+ path_64="mips64"
+ ;;
+ esac
+ ;;
+
+
+ # Darwin (powerpc-apple-darwin1.3) has it's hacked gcc installed as cc.
+ # Our usual "gcc in disguise" detection means gcc_cflags etc here gets
+ # used.
+ #
+ # The darwin pre-compiling preprocessor is disabled with -no-cpp-precomp
+ # since it doesn't like "__attribute__ ((mode (SI)))" etc in gmp-impl.h,
+ # and so always ends up running the plain preprocessor anyway. This could
+ # be done in CPPFLAGS rather than CFLAGS, but there's not many places
+ # preprocessing is done separately, and this is only a speedup, the normal
+ # preprocessor gets run if there's any problems.
+ #
+ # We used to use -Wa,-mppc with gcc, but can't remember exactly why.
+ # Presumably it was for old versions of gcc where -mpowerpc doesn't put
+ # the assembler in the right mode. In any case -Wa,-mppc is not good, for
+ # instance -mcpu=604 makes recent gcc use -m604 to get access to the
+ # "fsel" instruction, but a -Wa,-mppc overrides that, making code that
+ # comes out with fsel fail.
+ #
+ # (Note also that the darwin assembler doesn't accept "-mppc", so any
+ # -Wa,-mppc was used only if it worked. The right flag on darwin would be
+ # "-arch ppc" or some such, but that's already the default.)
+ #
+ [powerpc*-*-* | power[3-9]-*-*])
+ AC_DEFINE(HAVE_HOST_CPU_FAMILY_powerpc)
+ HAVE_HOST_CPU_FAMILY_powerpc=1
+ abilist="32"
+ cclist="gcc cc"
+ cc_cflags="-O2"
+ gcc_32_cflags="$gcc_cflags -mpowerpc"
+ gcc_cflags_optlist="precomp subtype asm cpu"
+ gcc_cflags_precomp="-no-cpp-precomp"
+ gcc_cflags_subtype="-force_cpusubtype_ALL" # for vmx on darwin
+ gcc_cflags_asm=""
+ gcc_cflags_cpu=""
+ vmx_path=""
+
+ # grab this object, though it's not a true cycle counter routine
+ SPEED_CYCLECOUNTER_OBJ=powerpc.lo
+ cyclecounter_size=0
+
+ case $host_cpu in
+ powerpc740 | powerpc750)
+ path="powerpc32/750 powerpc32" ;;
+ powerpc7400 | powerpc7410)
+ path="powerpc32/vmx powerpc32/750 powerpc32" ;;
+ [powerpc74[45]?])
+ path="powerpc32/vmx powerpc32" ;;
+ *)
+ path="powerpc32" ;;
+ esac
+
+ case $host_cpu in
+ powerpc401) gcc_cflags_cpu="-mcpu=401" ;;
+ powerpc403) gcc_cflags_cpu="-mcpu=403"
+ xlc_cflags_arch="-qarch=403 -qarch=ppc" ;;
+ powerpc405) gcc_cflags_cpu="-mcpu=405" ;;
+ powerpc505) gcc_cflags_cpu="-mcpu=505" ;;
+ powerpc601) gcc_cflags_cpu="-mcpu=601"
+ xlc_cflags_arch="-qarch=601 -qarch=ppc" ;;
+ powerpc602) gcc_cflags_cpu="-mcpu=602"
+ xlc_cflags_arch="-qarch=602 -qarch=ppc" ;;
+ powerpc603) gcc_cflags_cpu="-mcpu=603"
+ xlc_cflags_arch="-qarch=603 -qarch=ppc" ;;
+ powerpc603e) gcc_cflags_cpu="-mcpu=603e -mcpu=603"
+ xlc_cflags_arch="-qarch=603 -qarch=ppc" ;;
+ powerpc604) gcc_cflags_cpu="-mcpu=604"
+ xlc_cflags_arch="-qarch=604 -qarch=ppc" ;;
+ powerpc604e) gcc_cflags_cpu="-mcpu=604e -mcpu=604"
+ xlc_cflags_arch="-qarch=604 -qarch=ppc" ;;
+ powerpc620) gcc_cflags_cpu="-mcpu=620" ;;
+ powerpc630) gcc_cflags_cpu="-mcpu=630"
+ xlc_cflags_arch="-qarch=pwr3"
+ cpu_path="p3 p3-p7" ;;
+ powerpc740) gcc_cflags_cpu="-mcpu=740" ;;
+ powerpc7400 | powerpc7410)
+ gcc_cflags_asm="-Wa,-maltivec"
+ gcc_cflags_cpu="-mcpu=7400 -mcpu=750" ;;
+ [powerpc74[45]?])
+ gcc_cflags_asm="-Wa,-maltivec"
+ gcc_cflags_cpu="-mcpu=7450" ;;
+ powerpc750) gcc_cflags_cpu="-mcpu=750" ;;
+ powerpc801) gcc_cflags_cpu="-mcpu=801" ;;
+ powerpc821) gcc_cflags_cpu="-mcpu=821" ;;
+ powerpc823) gcc_cflags_cpu="-mcpu=823" ;;
+ powerpc860) gcc_cflags_cpu="-mcpu=860" ;;
+ powerpc970) gcc_cflags_cpu="-mtune=970"
+ xlc_cflags_arch="-qarch=970 -qarch=pwr3"
+ vmx_path="powerpc64/vmx"
+ cpu_path="p4 p3-p7" ;;
+ power4) gcc_cflags_cpu="-mtune=power4"
+ xlc_cflags_arch="-qarch=pwr4"
+ cpu_path="p4 p3-p7" ;;
+ power5) gcc_cflags_cpu="-mtune=power5 -mtune=power4"
+ xlc_cflags_arch="-qarch=pwr5"
+ cpu_path="p5 p4 p3-p7" ;;
+ power6) gcc_cflags_cpu="-mtune=power6"
+ xlc_cflags_arch="-qarch=pwr6"
+ cpu_path="p6 p3-p7" ;;
+ power7) gcc_cflags_cpu="-mtune=power7 -mtune=power5"
+ xlc_cflags_arch="-qarch=pwr7 -qarch=pwr5"
+ cpu_path="p7 p5 p4 p3-p7" ;;
+ esac
+
+ case $host in
+ *-*-aix*)
+ cclist="gcc xlc cc"
+ gcc_32_cflags_maybe="-maix32"
+ xlc_cflags="-O2 -qmaxmem=20000"
+ xlc_cflags_optlist="arch"
+ xlc_32_cflags_maybe="-q32"
+ ar_32_flags="-X32"
+ nm_32_flags="-X32"
+ esac
+
+ case $host in
+ POWERPC64_PATTERN)
+ case $host in
+ *-*-aix*)
+ # On AIX a true 64-bit ABI is available.
+ # Need -Wc to pass object type flags through to the linker.
+ abilist="mode64 $abilist"
+ cclist_mode64="gcc xlc"
+ gcc_mode64_cflags="$gcc_cflags -maix64 -mpowerpc64"
+ gcc_mode64_cflags_optlist="cpu"
+ gcc_mode64_ldflags="-Wc,-maix64"
+ xlc_mode64_cflags="-O2 -q64 -qmaxmem=20000"
+ xlc_mode64_cflags_optlist="arch"
+ xlc_mode64_ldflags="-Wc,-q64"
+ # Must indicate object type to ar and nm
+ ar_mode64_flags="-X64"
+ nm_mode64_flags="-X64"
+ path_mode64=""
+ p=""
+ for i in $cpu_path
+ do path_mode64="${path_mode64}powerpc64/mode64/$i "
+ path_mode64="${path_mode64}powerpc64/$i "
+ p="${p} powerpc32/$i "
+ done
+ path_mode64="${path_mode64}powerpc64/mode64 $vmx_path powerpc64"
+ path="$p $path"
+ # grab this object, though it's not a true cycle counter routine
+ SPEED_CYCLECOUNTER_OBJ_mode64=powerpc64.lo
+ cyclecounter_size_mode64=0
+ ;;
+ *-*-darwin*)
+ # On Darwin we can use 64-bit instructions with a longlong limb,
+ # but the chip still in 32-bit mode.
+ # In theory this can be used on any OS which knows how to save
+ # 64-bit registers in a context switch.
+ #
+ # Note that we must use -mpowerpc64 with gcc, since the
+ # longlong.h macros expect limb operands in a single 64-bit
+ # register, not two 32-bit registers as would be given for a
+ # long long without -mpowerpc64. In theory we could detect and
+ # accommodate both styles, but the proper 64-bit registers will
+ # be fastest and are what we really want to use.
+ #
+ # One would think -mpowerpc64 would set the assembler in the right
+ # mode to handle 64-bit instructions. But for that, also
+ # -force_cpusubtype_ALL is needed.
+ #
+ # Do not use -fast for Darwin, it actually adds options
+ # incompatible with a shared library.
+ #
+ abilist="mode64 mode32 $abilist"
+ gcc_32_cflags_maybe="-m32"
+ gcc_cflags_opt="-O3 -O2 -O1" # will this become used?
+ cclist_mode32="gcc"
+ gcc_mode32_cflags_maybe="-m32"
+ gcc_mode32_cflags="-mpowerpc64"
+ gcc_mode32_cflags_optlist="subtype cpu opt"
+ gcc_mode32_cflags_subtype="-force_cpusubtype_ALL"
+ gcc_mode32_cflags_opt="-O3 -O2 -O1"
+ limb_mode32=longlong
+ cclist_mode64="gcc"
+ gcc_mode64_cflags="-m64"
+ gcc_mode64_cflags_optlist="cpu opt"
+ gcc_mode64_cflags_opt="-O3 -O2 -O1"
+ path_mode64=""
+ path_mode32=""
+ p=""
+ for i in $cpu_path
+ do path_mode64="${path_mode64}powerpc64/mode64/$i "
+ path_mode64="${path_mode64}powerpc64/$i "
+ path_mode32="${path_mode32}powerpc64/mode32/$i "
+ path_mode32="${path_mode32}powerpc64/$i "
+ p="${p} powerpc32/$i "
+ done
+ path_mode64="${path_mode64}powerpc64/mode64 $vmx_path powerpc64"
+ path_mode32="${path_mode32}powerpc64/mode32 $vmx_path powerpc64"
+ path="$p $path"
+ SPEED_CYCLECOUNTER_OBJ_mode64=powerpc64.lo
+ cyclecounter_size_mode64=0
+ any_mode64_testlist="sizeof-long-8"
+ ;;
+ *-*-linux* | *-*-*bsd*)
+ # On GNU/Linux, assume the processor is in 64-bit mode. Some
+ # environments have a gcc that is always in 64-bit mode, while
+ # others require -m64, hence the use of cflags_maybe. The
+ # sizeof-long-8 test checks the mode is right (for the no option
+ # case).
+ #
+ # -mpowerpc64 is not used, since it should be the default in
+ # 64-bit mode. (We need its effect for the various longlong.h
+ # asm macros to be right of course.)
+ #
+ # gcc64 was an early port of gcc to 64-bit mode, but should be
+ # obsolete before too long. We prefer plain gcc when it knows
+ # 64-bits.
+ #
+ abilist="mode64 mode32 $abilist"
+ gcc_32_cflags_maybe="-m32"
+ cclist_mode32="gcc"
+ gcc_mode32_cflags_maybe="-m32"
+ gcc_mode32_cflags="-mpowerpc64"
+ gcc_mode32_cflags_optlist="cpu opt"
+ gcc_mode32_cflags_opt="-O3 -O2 -O1"
+ limb_mode32=longlong
+ cclist_mode64="gcc gcc64"
+ gcc_mode64_cflags_maybe="-m64"
+ gcc_mode64_cflags_optlist="cpu opt"
+ gcc_mode64_cflags_opt="-O3 -O2 -O1"
+ path_mode64=""
+ path_mode32=""
+ p=""
+ for i in $cpu_path
+ do path_mode64="${path_mode64}powerpc64/mode64/$i "
+ path_mode64="${path_mode64}powerpc64/$i "
+ path_mode32="${path_mode32}powerpc64/mode32/$i "
+ path_mode32="${path_mode32}powerpc64/$i "
+ p="${p} powerpc32/$i "
+ done
+ path_mode64="${path_mode64}powerpc64/mode64 $vmx_path powerpc64"
+ path_mode32="${path_mode32}powerpc64/mode32 $vmx_path powerpc64"
+ path="$p $path"
+ SPEED_CYCLECOUNTER_OBJ_mode64=powerpc64.lo
+ cyclecounter_size_mode64=0
+ any_mode64_testlist="sizeof-long-8"
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+
+ # POWER 32-bit
+ [power-*-* | power[12]-*-* | power2sc-*-*])
+ AC_DEFINE(HAVE_HOST_CPU_FAMILY_power)
+ HAVE_HOST_CPU_FAMILY_power=1
+ cclist="gcc"
+ extra_functions="udiv_w_sdiv"
+ path="power"
+
+ # gcc 2.7.2 knows rios1, rios2, rsc
+ #
+ # -mcpu=rios2 can tickle an AIX assembler bug (see GMP_PROG_CC_WORKS) so
+ # there needs to be a fallback to just -mpower.
+ #
+ gcc_cflags_optlist="cpu"
+ case $host in
+ power-*-*) gcc_cflags_cpu="-mcpu=power -mpower" ;;
+ power1-*-*) gcc_cflags_cpu="-mcpu=rios1 -mpower" ;;
+ power2-*-*) gcc_cflags_cpu="-mcpu=rios2 -mpower" ;;
+ power2sc-*-*) gcc_cflags_cpu="-mcpu=rsc -mpower" ;;
+ esac
+ case $host in
+ *-*-aix*)
+ cclist="gcc xlc"
+ xlc_cflags="-O2 -qarch=pwr -qmaxmem=20000"
+ ;;
+ esac
+ ;;
+
+
+ # IBM System/390 and z/Architecture
+ S390_PATTERN | S390X_PATTERN)
+ abilist="32"
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ gcc_cflags_optlist="arch"
+ path="s390_32"
+ extra_functions="udiv_w_sdiv"
+ gcc_32_cflags_maybe="-m31"
+
+ case $host_cpu in
+ s390)
+ ;;
+ z900 | z900esa)
+ cpu="z900"
+ gccarch="$cpu"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ AC_DEFINE_UNQUOTED(HAVE_HOST_CPU_s390_$cpu)
+ AC_DEFINE(HAVE_HOST_CPU_s390_zarch)
+ extra_functions=""
+ ;;
+ z990 | z990esa)
+ cpu="z990"
+ gccarch="$cpu"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ AC_DEFINE_UNQUOTED(HAVE_HOST_CPU_s390_$cpu)
+ AC_DEFINE(HAVE_HOST_CPU_s390_zarch)
+ extra_functions=""
+ ;;
+ z9 | z9esa)
+ cpu="z9"
+ gccarch="z9-109"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ AC_DEFINE_UNQUOTED(HAVE_HOST_CPU_s390_$cpu)
+ AC_DEFINE(HAVE_HOST_CPU_s390_zarch)
+ extra_functions=""
+ ;;
+ z10 | z10esa)
+ cpu="z10"
+ gccarch="z10"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ AC_DEFINE_UNQUOTED(HAVE_HOST_CPU_s390_$cpu)
+ AC_DEFINE(HAVE_HOST_CPU_s390_zarch)
+ extra_functions=""
+ ;;
+ z196 | z196esa)
+ cpu="z196"
+ gccarch="z196"
+ path="s390_32/esame/$cpu s390_32/esame s390_32"
+ gcc_cflags_arch="-march=$gccarch"
+ AC_DEFINE_UNQUOTED(HAVE_HOST_CPU_s390_$cpu)
+ AC_DEFINE(HAVE_HOST_CPU_s390_zarch)
+ extra_functions=""
+ ;;
+ esac
+
+ case $host in
+ S390X_PATTERN)
+ abilist="64 32"
+ cclist_64="gcc"
+ gcc_64_cflags_optlist="arch"
+ gcc_64_cflags="$gcc_cflags -m64"
+ path_64="s390_64/$host_cpu s390_64"
+ extra_functions=""
+ ;;
+ esac
+ ;;
+
+
+ sh-*-*) path="sh" ;;
+ [sh[2-4]-*-*]) path="sh/sh2 sh" ;;
+
+
+ *sparc*-*-*)
+ # sizeof(long)==4 or 8 is tested, to ensure we get the right ABI. We've
+ # had various bug reports where users have set CFLAGS for their desired
+ # mode, but not set our ABI. For some reason it's sparc where this
+ # keeps coming up, presumably users there are accustomed to driving the
+ # compiler mode that way. The effect of our testlist setting is to
+ # reject ABI=64 in favour of ABI=32 if the user has forced the flags to
+ # 32-bit mode.
+ #
+ abilist="32"
+ cclist="gcc acc cc"
+ any_testlist="sizeof-long-4"
+ GMP_INCLUDE_MPN(sparc32/sparc-defs.m4)
+
+ case $host_cpu in
+ sparcv8 | microsparc | turbosparc)
+ path="sparc32/v8 sparc32" ;;
+ supersparc)
+ path="sparc32/v8/supersparc sparc32/v8 sparc32" ;;
+ [sparc64 | sparcv9* | ultrasparc | ultrasparc[234]*])
+ path="sparc32/v9 sparc32/v8 sparc32" ;;
+ [ultrasparct[12345]])
+ path="sparc32/ultrasparct1 sparc32/v8 sparc32" ;;
+ *)
+ path="sparc32" ;;
+ esac
+
+ # gcc 2.7.2 doesn't know about v9 and doesn't pass -xarch=v8plus to the
+ # assembler. Add it explicitly since the solaris assembler won't accept
+ # our sparc32/v9 asm code without it. gas accepts -xarch=v8plus too, so
+ # it can be in the cflags unconditionally (though gas doesn't need it).
+ #
+ # gcc -m32 is needed to force 32-bit mode on a dual-ABI system, but past
+ # gcc doesn't know that flag, hence cflags_maybe. Note that -m32 cannot
+ # be done through the optlist since the plain cflags would be run first
+ # and we don't want to require the default mode (whatever it is) works.
+ #
+ # Note it's gcc_32_cflags_maybe and not gcc_cflags_maybe because the
+ # latter would be used in the 64-bit ABI on systems like "*bsd" where
+ # abilist="64" only.
+ #
+ gcc_32_cflags_maybe="-m32"
+ gcc_cflags_optlist="cpu asm"
+
+ # gcc 2.7.2 knows -mcypress, -msupersparc, -mv8, -msparclite.
+ # gcc 2.95 knows -mcpu= v7, hypersparc, sparclite86x, f930, f934,
+ # sparclet, tsc701, v9, ultrasparc. A warning is given that the
+ # plain -m forms will disappear.
+ # gcc 3.3 adds ultrasparc3.
+ #
+ case $host_cpu in
+ supersparc*)
+ gcc_cflags_cpu="-mcpu=supersparc -msupersparc"
+ gcc_cflags_asm="-Wa,-Av8 -Wa,-xarch=v8";;
+ sparcv8 | microsparc* | turbosparc | hypersparc*)
+ gcc_cflags_cpu="-mcpu=v8 -mv8"
+ gcc_cflags_asm="-Wa,-Av8 -Wa,-xarch=v8";;
+ sparc64 | sparcv9*)
+ gcc_cflags_cpu="-mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8 -Wa,-xarch=v8plus"
+ gcc_64_cflags_asm="-Wa,-Av9 -Wa,-xarch=v9";;
+ ultrasparc1 | ultrasparc2*)
+ gcc_cflags_cpu="-mcpu=ultrasparc -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusa -Wa,-xarch=v8plusa"
+ gcc_64_cflags_asm="-Wa,-Av9a -Wa,-xarch=v9a";;
+ [ultrasparc[34]])
+ gcc_cflags_cpu="-mcpu=ultrasparc3 -mcpu=ultrasparc -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusb -Wa,-xarch=v8plusb"
+ gcc_64_cflags_asm="-Wa,-Av9b -Wa,-xarch=v9b";;
+ [ultrasparct[12]])
+ gcc_cflags_cpu="-mcpu=niagara -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusc -Wa,-xarch=v8plusc"
+ gcc_64_cflags_asm="-Wa,-Av9c -Wa,-xarch=v9c";;
+ ultrasparct3)
+ gcc_cflags_cpu="-mcpu=niagara3 -mcpu=niagara -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusd -Wa,-xarch=v8plusd"
+ gcc_64_cflags_asm="-Wa,-Av9d -Wa,-xarch=v9d";;
+ ultrasparct4)
+ gcc_cflags_cpu="-mcpu=niagara4 -mcpu=niagara3 -mcpu=niagara -mcpu=v9"
+ gcc_32_cflags_asm="-Wa,-Av8plusd -Wa,-xarch=v8plusd"
+ gcc_64_cflags_asm="-Wa,-Av9d -Wa,-xarch=v9d";;
+ *)
+ gcc_cflags_cpu="-mcpu=v7 -mcypress"
+ gcc_cflags_asm="";;
+ esac
+
+ # SunPRO cc and acc, and SunOS bundled cc
+ case $host in
+ *-*-solaris* | *-*-sunos*)
+ # Note no -g, it disables all optimizations.
+ cc_cflags=
+ cc_cflags_optlist="opt arch cpu"
+
+ # SunOS cc doesn't know -xO4, fallback to -O2.
+ cc_cflags_opt="-xO4 -O2"
+
+ # SunOS cc doesn't know -xarch, apparently always generating v7
+ # code, so make this optional
+ case $host_cpu in
+ sparcv8 | microsparc* | supersparc* | turbosparc | hypersparc*)
+ cc_cflags_arch="-xarch=v8";;
+ [ultrasparct[345]])
+ cc_cflags_arch="-xarch=v8plusd" ;;
+ sparc64 | sparcv9* | ultrasparc*)
+ cc_cflags_arch="-xarch=v8plus" ;;
+ *)
+ cc_cflags_arch="-xarch=v7" ;;
+ esac
+
+ # SunOS cc doesn't know -xchip and doesn't seem to have an equivalent.
+ # SunPRO cc 5 recognises -xchip=generic, old, super, super2, micro,
+ # micro2, hyper, hyper2, powerup, ultra, ultra2, ultra2i.
+ # SunPRO cc 6 adds -xchip=ultra2e, ultra3cu.
+ #
+ case $host_cpu in
+ supersparc*) cc_cflags_cpu="-xchip=super" ;;
+ microsparc*) cc_cflags_cpu="-xchip=micro" ;;
+ turbosparc) cc_cflags_cpu="-xchip=micro2" ;;
+ hypersparc*) cc_cflags_cpu="-xchip=hyper" ;;
+ ultrasparc) cc_cflags_cpu="-xchip=ultra" ;;
+ ultrasparc2) cc_cflags_cpu="-xchip=ultra2 -xchip=ultra" ;;
+ ultrasparc2i) cc_cflags_cpu="-xchip=ultra2i -xchip=ultra2 -xchip=ultra" ;;
+ ultrasparc3) cc_cflags_cpu="-xchip=ultra3 -xchip=ultra" ;;
+ ultrasparc4) cc_cflags_cpu="-xchip=ultra4 -xchip=ultra3 -xchip=ultra" ;;
+ ultrasparct1) cc_cflags_cpu="-xchip=ultraT1" ;;
+ ultrasparct2) cc_cflags_cpu="-xchip=ultraT2 -xchip=ultraT1" ;;
+ ultrasparct3) cc_cflags_cpu="-xchip=ultraT3 -xchip=ultraT2" ;;
+ ultrasparct4) cc_cflags_cpu="-xchip=T4" ;;
+ ultrasparct5) cc_cflags_cpu="-xchip=T5 -xchip=T4" ;;
+ *) cc_cflags_cpu="-xchip=generic" ;;
+ esac
+ esac
+
+ case $host_cpu in
+ sparc64 | sparcv9* | ultrasparc*)
+ case $host in
+ # Solaris 6 and earlier cannot run ABI=64 since it doesn't save
+ # registers properly, so ABI=32 is left as the only choice.
+ #
+ [*-*-solaris2.[0-6] | *-*-solaris2.[0-6].*]) ;;
+
+ # BSD sparc64 ports are 64-bit-only systems, so ABI=64 is the only
+ # choice. In fact they need no special compiler flags, gcc -m64
+ # is the default, but it doesn't hurt to add it. v9 CPUs always
+ # use the sparc64 port, since the plain 32-bit sparc ports don't
+ # run on a v9.
+ #
+ *-*-*bsd*) abilist="64" ;;
+
+ # For all other systems, we try both 64 and 32.
+ #
+ # GNU/Linux sparc64 has only recently gained a 64-bit user mode.
+ # In the past sparc64 meant a v9 cpu, but there were no 64-bit
+ # operations in user mode. We assume that if "gcc -m64" works
+ # then the system is suitable. Hopefully even if someone attempts
+ # to put a new gcc and/or glibc on an old system it won't run.
+ #
+ *) abilist="64 32" ;;
+ esac
+
+ case $host_cpu in
+ ultrasparc | ultrasparc2 | ultrasparc2i)
+ path_64="sparc64/ultrasparc1234 sparc64" ;;
+ [ultrasparc[34]])
+ path_64="sparc64/ultrasparc34 sparc64/ultrasparc1234 sparc64" ;;
+ [ultrasparct[12]])
+ path_64="sparc64/ultrasparct1 sparc64" ;;
+ [ultrasparct[345]])
+ path_64="sparc64/ultrasparct3 sparc64" ;;
+ *)
+ path_64="sparc64"
+ esac
+
+ cclist_64="gcc"
+ any_64_testlist="sizeof-long-8"
+
+ # gcc -mptr64 is probably implied by -m64, but we're not sure if
+ # this was always so. On Solaris in the past we always used both
+ # "-m64 -mptr64".
+ #
+ # gcc -Wa,-xarch=v9 is thought to be necessary in some cases on
+ # solaris, but it would seem likely that if gcc is going to generate
+ # 64-bit code it will have to add that option itself where needed.
+ # An extra copy of this option should be harmless though, but leave
+ # it until we're sure. (Might want -xarch=v9a or -xarch=v9b for the
+ # higher cpu types instead.)
+ #
+ gcc_64_cflags="$gcc_cflags -m64 -mptr64"
+ gcc_64_ldflags="-Wc,-m64"
+ gcc_64_cflags_optlist="cpu asm"
+
+ case $host in
+ *-*-solaris*)
+ # Sun cc.
+ #
+ # We used to have -fast and some fixup options here, but it
+ # recurrently caused problems with miscompilation. Of course,
+ # -fast is documented as miscompiling things for the sake of speed.
+ #
+ cclist_64="$cclist_64 cc"
+ cc_64_cflags_optlist="cpu"
+ case $host_cpu in
+ [ultrasparct[345]])
+ cc_64_cflags="$cc_64_cflags -xO3 -xarch=v9d" ;;
+ *)
+ cc_64_cflags="-xO3 -xarch=v9" ;;
+ esac
+ ;;
+ esac
+
+ # using the v9 %tick register
+ SPEED_CYCLECOUNTER_OBJ_32=sparcv9.lo
+ SPEED_CYCLECOUNTER_OBJ_64=sparcv9.lo
+ cyclecounter_size_32=2
+ cyclecounter_size_64=2
+ ;;
+ esac
+ ;;
+
+
+ # VAX
+ vax*-*-*elf*)
+ # Use elf conventions (i.e., '%' register prefix, no global prefix)
+ #
+ GMP_INCLUDE_MPN(vax/elf.m4)
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ path="vax"
+ extra_functions="udiv_w_sdiv"
+ ;;
+ vax*-*-*)
+ # Default to aout conventions (i.e., no register prefix, '_' global prefix)
+ #
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ path="vax"
+ extra_functions="udiv_w_sdiv"
+ ;;
+
+
+ # AMD and Intel x86 configurations, including AMD64
+ #
+ # Rumour has it gcc -O2 used to give worse register allocation than just
+ # -O, but lets assume that's no longer true.
+ #
+ # -m32 forces 32-bit mode on a bi-arch 32/64 amd64 build of gcc. -m64 is
+ # the default in such a build (we think), so -m32 is essential for ABI=32.
+ # This is, of course, done for any $host_cpu, not just x86_64, so we can
+ # get such a gcc into the right mode to cross-compile to say i486-*-*.
+ #
+ # -m32 is not available in gcc 2.95 and earlier, hence cflags_maybe to use
+ # it when it works. We check sizeof(long)==4 to ensure we get the right
+ # mode, in case -m32 has failed not because it's an old gcc, but because
+ # it's a dual 32/64-bit gcc without a 32-bit libc, or whatever.
+ #
+ X86_PATTERN | X86_64_PATTERN)
+ abilist="32"
+ cclist="gcc icc cc"
+ gcc_cflags="$gcc_cflags $fomit_frame_pointer"
+ gcc_32_cflags_maybe="-m32"
+ icc_cflags="-no-gcc"
+ icc_cflags_optlist="opt"
+ icc_cflags_opt="-O3 -O2 -O1"
+ any_32_testlist="sizeof-long-4"
+ CALLING_CONVENTIONS_OBJS='x86call.lo x86check$U.lo'
+
+ # Availability of rdtsc is checked at run-time.
+ SPEED_CYCLECOUNTER_OBJ=pentium.lo
+
+ # gcc 2.7.2 only knows i386 and i486, using -m386 or -m486. These
+ # represent -mcpu= since -m486 doesn't generate 486 specific insns.
+ # gcc 2.95 adds k6, pentium and pentiumpro, and takes -march= and -mcpu=.
+ # gcc 3.0 adds athlon.
+ # gcc 3.1 adds k6-2, k6-3, pentium-mmx, pentium2, pentium3, pentium4,
+ # athlon-tbird, athlon-4, athlon-xp, athlon-mp.
+ # gcc 3.2 adds winchip2.
+ # gcc 3.3 adds winchip-c6.
+ # gcc 3.3.1 from mandrake adds k8 and knows -mtune.
+ # gcc 3.4 adds c3, c3-2, k8, and deprecates -mcpu in favour of -mtune.
+ #
+ # In gcc 2.95.[0123], -march=pentiumpro provoked a stack slot bug in an
+ # old version of mpz/powm.c. Seems to be fine with the current code, so
+ # no need for any restrictions on that option.
+ #
+ # -march=pentiumpro can fail if the assembler doesn't know "cmov"
+ # (eg. solaris 2.8 native "as"), so always have -march=pentium after
+ # that as a fallback.
+ #
+ # -march=pentium4 and -march=k8 enable SSE2 instructions, which may or
+ # may not be supported by the assembler and/or the OS, and is bad in gcc
+ # prior to 3.3. The tests will reject these if no good, so fallbacks
+ # like "-march=pentium4 -mno-sse2" are given to try also without SSE2.
+ # Note the relevant -march types are listed in the optflags handling
+ # below, be sure to update there if adding new types emitting SSE2.
+ #
+ # -mtune is used at the start of each cpu option list to give something
+ # gcc 3.4 will use, thereby avoiding warnings from -mcpu. -mcpu forms
+ # are retained for use by prior gcc. For example pentium has
+ # "-mtune=pentium -mcpu=pentium ...", the -mtune is for 3.4 and the
+ # -mcpu for prior. If there's a brand new choice in 3.4 for a chip,
+ # like k8 for x86_64, then it can be the -mtune at the start, no need to
+ # duplicate anything.
+ #
+ gcc_cflags_optlist="cpu arch"
+ case $host_cpu in
+ i386*)
+ gcc_cflags_cpu="-mtune=i386 -mcpu=i386 -m386"
+ gcc_cflags_arch="-march=i386"
+ path="x86"
+ ;;
+ i486*)
+ gcc_cflags_cpu="-mtune=i486 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=i486"
+ path="x86/i486 x86"
+ ;;
+ i586 | pentium)
+ gcc_cflags_cpu="-mtune=pentium -mcpu=pentium -m486"
+ gcc_cflags_arch="-march=pentium"
+ path="x86/pentium x86"
+ ;;
+ pentiummmx)
+ gcc_cflags_cpu="-mtune=pentium-mmx -mcpu=pentium-mmx -mcpu=pentium -m486"
+ gcc_cflags_arch="-march=pentium-mmx -march=pentium"
+ path="x86/pentium/mmx x86/pentium x86/mmx x86"
+ ;;
+ i686 | pentiumpro)
+ gcc_cflags_cpu="-mtune=pentiumpro -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentiumpro -march=pentium"
+ path="x86/p6 x86"
+ ;;
+ pentium2)
+ gcc_cflags_cpu="-mtune=pentium2 -mcpu=pentium2 -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentium2 -march=pentiumpro -march=pentium"
+ path="x86/p6/mmx x86/p6 x86/mmx x86"
+ ;;
+ pentium3)
+ gcc_cflags_cpu="-mtune=pentium3 -mcpu=pentium3 -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentium3 -march=pentiumpro -march=pentium"
+ path="x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ ;;
+ pentiumm)
+ gcc_cflags_cpu="-mtune=pentium3 -mcpu=pentium3 -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentium3 -march=pentiumpro -march=pentium"
+ path="x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ ;;
+ k6)
+ gcc_cflags_cpu="-mtune=k6 -mcpu=k6 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k6"
+ path="x86/k6/mmx x86/k6 x86/mmx x86"
+ ;;
+ k62)
+ gcc_cflags_cpu="-mtune=k6-2 -mcpu=k6-2 -mcpu=k6 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k6-2 -march=k6"
+ path="x86/k6/k62mmx x86/k6/mmx x86/k6 x86/mmx x86"
+ ;;
+ k63)
+ gcc_cflags_cpu="-mtune=k6-3 -mcpu=k6-3 -mcpu=k6 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k6-3 -march=k6"
+ path="x86/k6/k62mmx x86/k6/mmx x86/k6 x86/mmx x86"
+ ;;
+ geode)
+ gcc_cflags_cpu="-mtune=k6-3 -mcpu=k6-3 -mcpu=k6 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k6-3 -march=k6"
+ path="x86/geode x86/k6/k62mmx x86/k6/mmx x86/k6 x86/mmx x86"
+ ;;
+ athlon)
+ # Athlon instruction costs are close to P6 (3 cycle load latency,
+ # 4-6 cycle mul, 40 cycle div, pairable adc, etc) so if gcc doesn't
+ # know athlon (eg. 2.95.2 doesn't) then fall back on pentiumpro.
+ gcc_cflags_cpu="-mtune=athlon -mcpu=athlon -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=athlon -march=pentiumpro -march=pentium"
+ path="x86/k7/mmx x86/k7 x86/mmx x86"
+ ;;
+ i786 | pentium4)
+ # pentiumpro is the primary fallback when gcc doesn't know pentium4.
+ # This gets us cmov to eliminate branches. Maybe "athlon" would be
+ # a possibility on gcc 3.0.
+ #
+ gcc_cflags_cpu="-mtune=pentium4 -mcpu=pentium4 -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=pentium4 -march=pentium4~-mno-sse2 -march=pentiumpro -march=pentium"
+ gcc_64_cflags_cpu="-mtune=nocona"
+ path="x86/pentium4/sse2 x86/pentium4/mmx x86/pentium4 x86/mmx x86"
+ path_64="x86_64/pentium4 x86_64"
+ ;;
+ viac32)
+ # Not sure of the best fallbacks here for -mcpu.
+ # c3-2 has sse and mmx, so pentium3 is good for -march.
+ gcc_cflags_cpu="-mtune=c3-2 -mcpu=c3-2 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=c3-2 -march=pentium3 -march=pentiumpro -march=pentium"
+ path="x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ ;;
+ viac3*)
+ # Not sure of the best fallbacks here.
+ gcc_cflags_cpu="-mtune=c3 -mcpu=c3 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=c3 -march=pentium-mmx -march=pentium"
+ path="x86/pentium/mmx x86/pentium x86/mmx x86"
+ ;;
+ athlon64 | k8 | x86_64)
+ gcc_cflags_cpu="-mtune=k8 -mcpu=athlon -mcpu=pentiumpro -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=k8 -march=k8~-mno-sse2 -march=athlon -march=pentiumpro -march=pentium"
+ path="x86/k8 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/k8 x86_64"
+ ;;
+ k10)
+ gcc_cflags_cpu="-mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/k10 x86/k8 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ bobcat)
+ gcc_cflags_cpu="-mtune=btver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=btver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bobcat x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bobcat x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ jaguar)
+ gcc_cflags_cpu="-mtune=btver2 -mtune=btver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=btver2 -march=btver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/jaguar x86/bobcat x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/jaguar x86_64/bobcat x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ bulldozer | bd1)
+ gcc_cflags_cpu="-mtune=bdver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=bdver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bd1 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bd1 x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ piledriver | bd2)
+ gcc_cflags_cpu="-mtune=bdver2 -mtune=bdver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=bdver2 -march=bdver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bd2 x86/bd1 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bd2 x86_64/bd1 x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ steamroller | bd3)
+ gcc_cflags_cpu="-mtune=bdver3 -mtune=bdver2 -mtune=bdver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=bdver3 -march=bdver2 -march=bdver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bd3 x86/bd2 x86/bd1 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bd3 x86_64/bd2 x86_64/bd1 x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ excavator | bd4)
+ gcc_cflags_cpu="-mtune=bdver4 -mtune=bdver3 -mtune=bdver2 -mtune=bdver1 -mtune=amdfam10 -mtune=k8"
+ gcc_cflags_arch="-march=bdver4 -march=bdver3 -march=bdver2 -march=bdver1 -march=amdfam10 -march=k8 -march=k8~-mno-sse2"
+ path="x86/bd4 x86/bd3 x86/bd2 x86/bd1 x86/k7/mmx x86/k7 x86/mmx x86"
+ path_64="x86_64/bd4 x86_64/bd3 x86_64/bd2 x86_64/bd1 x86_64/k10 x86_64/k8 x86_64"
+ ;;
+ core2)
+ gcc_cflags_cpu="-mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/core2 x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/core2 x86_64"
+ ;;
+ corei | coreinhm | coreiwsm)
+ gcc_cflags_cpu="-mtune=corei7 -mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=corei7 -march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/coreinhm x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/coreinhm x86_64/core2 x86_64"
+ ;;
+ coreisbr)
+ gcc_cflags_cpu="-mtune=corei7 -mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=corei7 -march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/coreisbr x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/coreisbr x86_64/coreinhm x86_64/core2 x86_64"
+ ;;
+ coreihwl)
+ gcc_cflags_cpu="-mtune=corei7 -mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=corei7 -march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/coreisbr x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/coreihwl x86_64/coreisbr x86_64/coreinhm x86_64/core2 x86_64"
+ ;;
+ coreibwl)
+ gcc_cflags_cpu="-mtune=corei7 -mtune=core2 -mtune=k8"
+ gcc_cflags_arch="-march=corei7 -march=core2 -march=core2~-mno-sse2 -march=k8 -march=k8~-mno-sse2"
+ path="x86/coreisbr x86/p6/sse2 x86/p6/p3mmx x86/p6/mmx x86/p6 x86/mmx x86"
+ path_64="x86_64/coreihwl x86_64/coreisbr x86_64/coreinhm x86_64/core2 x86_64"
+ # extra_functions_64="missing" # enable for bmi2/adx simulation
+ ;;
+ atom)
+ gcc_cflags_cpu="-mtune=atom -mtune=pentium3"
+ gcc_cflags_arch="-march=atom -march=pentium3"
+ path="x86/atom/sse2 x86/atom/mmx x86/atom x86/mmx x86"
+ path_64="x86_64/atom x86_64"
+ ;;
+ nano)
+ gcc_cflags_cpu="-mtune=nano"
+ gcc_cflags_arch="-march=nano"
+ path="x86/nano x86/mmx x86"
+ path_64="x86_64/nano x86_64"
+ ;;
+ *)
+ gcc_cflags_cpu="-mtune=i486 -mcpu=i486 -m486"
+ gcc_cflags_arch="-march=i486"
+ path="x86"
+ path_64="x86_64"
+ ;;
+ esac
+
+ case $host in
+ X86_64_PATTERN)
+ cclist_64="gcc cc"
+ gcc_64_cflags="$gcc_cflags -m64"
+ gcc_64_cflags_optlist="cpu arch"
+ CALLING_CONVENTIONS_OBJS_64='amd64call.lo amd64check$U.lo'
+ SPEED_CYCLECOUNTER_OBJ_64=x86_64.lo
+ cyclecounter_size_64=2
+
+ cclist_x32="gcc cc"
+ gcc_x32_cflags="$gcc_cflags -mx32"
+ gcc_x32_cflags_optlist="$gcc_64_cflags_optlist"
+ CALLING_CONVENTIONS_OBJS_x32="$CALLING_CONVENTIONS_OBJS_64"
+ SPEED_CYCLECOUNTER_OBJ_x32="$SPEED_CYCLECOUNTER_OBJ_64"
+ cyclecounter_size_x32="$cyclecounter_size_64"
+ path_x32="$path_64"
+ limb_x32=longlong
+ any_x32_testlist="sizeof-long-4"
+
+ abilist="64 x32 32"
+ if test "$enable_assembly" = "yes" ; then
+ extra_functions_64="$extra_functions_64 invert_limb_table"
+ extra_functions_x32=$extra_functions_64
+ fi
+
+ case $host in
+ *-*-solaris*)
+ # Sun cc.
+ cc_64_cflags="-xO3 -m64"
+ ;;
+ *-*-mingw* | *-*-cygwin)
+ limb_64=longlong
+ CALLING_CONVENTIONS_OBJS_64=""
+ AC_DEFINE(HOST_DOS64,1,[Define to 1 for Windos/64])
+ GMP_NONSTD_ABI_64=DOS64
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+
+ # Special CPU "none" used to select generic C, now this is obsolete.
+ none-*-*)
+ enable_assembly=no
+ AC_MSG_WARN([the \"none\" host is obsolete, use --disable-assembly])
+ ;;
+
+esac
+
+# mingw can be built by the cygwin gcc if -mno-cygwin is added. For
+# convenience add this automatically if it works. Actual mingw gcc accepts
+# -mno-cygwin too, but of course is the default. mingw only runs on the
+# x86s, but allow any CPU here so as to catch "none" too.
+#
+case $host in
+ *-*-mingw*)
+ gcc_cflags_optlist="$gcc_cflags_optlist nocygwin"
+ gcc_cflags_nocygwin="-mno-cygwin"
+ ;;
+esac
+
+
+CFLAGS_or_unset=${CFLAGS-'(unset)'}
+CPPFLAGS_or_unset=${CPPFLAGS-'(unset)'}
+
+cat >&AC_FD_CC <<EOF
+User:
+ABI=$ABI
+CC=$CC
+CFLAGS=$CFLAGS_or_unset
+CPPFLAGS=$CPPFLAGS_or_unset
+MPN_PATH=$MPN_PATH
+GMP:
+abilist=$abilist
+cclist=$cclist
+EOF
+
+
+test_CFLAGS=${CFLAGS+set}
+test_CPPFLAGS=${CPPFLAGS+set}
+
+for abi in $abilist; do
+ abi_last="$abi"
+done
+
+# If the user specifies an ABI then it must be in $abilist, after that
+# $abilist is restricted to just that choice.
+#
+if test -n "$ABI"; then
+ found=no
+ for abi in $abilist; do
+ if test $abi = "$ABI"; then found=yes; break; fi
+ done
+ if test $found = no; then
+ AC_MSG_ERROR([ABI=$ABI is not among the following valid choices: $abilist])
+ fi
+ abilist="$ABI"
+fi
+
+found_compiler=no
+
+for abi in $abilist; do
+
+ echo "checking ABI=$abi"
+
+ # Suppose abilist="64 32", then for abi=64, will have abi1="_64" and
+ # abi2="_64". For abi=32, will have abi1="_32" and abi2="". This is how
+ # $gcc_cflags becomes a fallback for $gcc_32_cflags (the last in the
+ # abilist), but there's no fallback for $gcc_64_cflags.
+ #
+ abi1=[`echo _$abi | sed 's/[.]//g'`]
+ if test $abi = $abi_last; then abi2=; else abi2="$abi1"; fi
+
+ # Compiler choices under this ABI
+ eval cclist_chosen=\"\$cclist$abi1\"
+ test -n "$cclist_chosen" || eval cclist_chosen=\"\$cclist$abi2\"
+
+ # If there's a user specified $CC then don't use a list for
+ # $cclist_chosen, just a single value for $ccbase.
+ #
+ if test -n "$CC"; then
+
+ # The first word of $CC, stripped of any directory. For instance
+ # CC="/usr/local/bin/gcc -pipe" will give "gcc".
+ #
+ for ccbase in $CC; do break; done
+ ccbase=`echo $ccbase | sed 's:.*/::'`
+
+ # If this $ccbase is in $cclist_chosen then it's a compiler we know and
+ # we can do flags defaulting with it. If not, then $cclist_chosen is
+ # set to "unrecognised" so no default flags are used.
+ #
+ # "unrecognised" is used to avoid bad effects with eval if $ccbase has
+ # non-symbol characters. For instance ccbase=my+cc would end up with
+ # something like cflags="$my+cc_cflags" which would give
+ # cflags="+cc_cflags" rather than the intended empty string for an
+ # unknown compiler.
+ #
+ found=unrecognised
+ for i in $cclist_chosen; do
+ if test "$ccbase" = $i; then
+ found=$ccbase
+ break
+ fi
+ done
+ cclist_chosen=$found
+ fi
+
+ for ccbase in $cclist_chosen; do
+
+ # When cross compiling, look for a compiler with the $host_alias as a
+ # prefix, the same way that AC_CHECK_TOOL does. But don't do this to a
+ # user-selected $CC.
+ #
+ # $cross_compiling will be yes/no/maybe at this point. Do the host
+ # prefixing for "maybe" as well as "yes".
+ #
+ if test "$cross_compiling" != no && test -z "$CC"; then
+ cross_compiling_prefix="${host_alias}-"
+ fi
+
+ for ccprefix in $cross_compiling_prefix ""; do
+
+ cc="$CC"
+ test -n "$cc" || cc="$ccprefix$ccbase"
+
+ # If the compiler is gcc but installed under another name, then change
+ # $ccbase so as to use the flags we know for gcc. This helps for
+ # instance when specifying CC=gcc272 on Debian GNU/Linux, or the
+ # native cc which is really gcc on NeXT or MacOS-X.
+ #
+ # FIXME: There's a slight misfeature here. If cc is actually gcc but
+ # gcc is not a known compiler under this $abi then we'll end up
+ # testing it with no flags and it'll work, but chances are it won't be
+ # in the right mode for the ABI we desire. Let's quietly hope this
+ # doesn't happen.
+ #
+ if test $ccbase != gcc; then
+ GMP_PROG_CC_IS_GNU($cc,ccbase=gcc)
+ fi
+
+ # Similarly if the compiler is IBM xlc but invoked as cc or whatever
+ # then change $ccbase and make the default xlc flags available.
+ if test $ccbase != xlc; then
+ GMP_PROG_CC_IS_XLC($cc,ccbase=xlc)
+ fi
+
+ # acc was Sun's first unbundled compiler back in the SunOS days, or
+ # something like that, but today its man page says it's not meant to
+ # be used directly (instead via /usr/ucb/cc). The options are pretty
+ # much the same as the main SunPRO cc, so share those configs.
+ #
+ case $host in
+ *sparc*-*-solaris* | *sparc*-*-sunos*)
+ if test "$ccbase" = acc; then ccbase=cc; fi ;;
+ esac
+
+ for tmp_cflags_maybe in yes no; do
+ eval cflags=\"\$${ccbase}${abi1}_cflags\"
+ test -n "$cflags" || eval cflags=\"\$${ccbase}${abi2}_cflags\"
+
+ if test "$tmp_cflags_maybe" = yes; then
+ # don't try cflags_maybe when the user set CFLAGS
+ if test "$test_CFLAGS" = set; then continue; fi
+ eval cflags_maybe=\"\$${ccbase}${abi1}_cflags_maybe\"
+ test -n "$cflags_maybe" || eval cflags_maybe=\"\$${ccbase}${abi2}_cflags_maybe\"
+ # don't try cflags_maybe if there's nothing set
+ if test -z "$cflags_maybe"; then continue; fi
+ cflags="$cflags_maybe $cflags"
+ fi
+
+ # Any user CFLAGS, even an empty string, takes precedence
+ if test "$test_CFLAGS" = set; then cflags=$CFLAGS; fi
+
+ # Any user CPPFLAGS, even an empty string, takes precedence
+ eval cppflags=\"\$${ccbase}${abi1}_cppflags\"
+ test -n "$cppflags" || eval cppflags=\"\$${ccbase}${abi2}_cppflags\"
+ if test "$test_CPPFLAGS" = set; then cppflags=$CPPFLAGS; fi
+
+ # --enable-profiling adds -p/-pg even to user-specified CFLAGS.
+ # This is convenient, but it's perhaps a bit naughty to modify user
+ # CFLAGS.
+ case "$enable_profiling" in
+ prof) cflags="$cflags -p" ;;
+ gprof) cflags="$cflags -pg" ;;
+ instrument) cflags="$cflags -finstrument-functions" ;;
+ esac
+
+ GMP_PROG_CC_WORKS($cc $cflags $cppflags,,continue)
+
+ # If we're supposed to be using a "long long" for a limb, check that
+ # it works.
+ eval limb_chosen=\"\$limb$abi1\"
+ test -n "$limb_chosen" || eval limb_chosen=\"\$limb$abi2\"
+ if test "$limb_chosen" = longlong; then
+ GMP_PROG_CC_WORKS_LONGLONG($cc $cflags $cppflags,,continue)
+ fi
+
+ # The tests to perform on this $cc, if any
+ eval testlist=\"\$${ccbase}${abi1}_testlist\"
+ test -n "$testlist" || eval testlist=\"\$${ccbase}${abi2}_testlist\"
+ test -n "$testlist" || eval testlist=\"\$any${abi1}_testlist\"
+ test -n "$testlist" || eval testlist=\"\$any${abi2}_testlist\"
+
+ testlist_pass=yes
+ for tst in $testlist; do
+ case $tst in
+ hpc-hppa-2-0) GMP_HPC_HPPA_2_0($cc,,testlist_pass=no) ;;
+ gcc-arm-umodsi) GMP_GCC_ARM_UMODSI($cc,,testlist_pass=no) ;;
+ gcc-mips-o32) GMP_GCC_MIPS_O32($cc,,testlist_pass=no) ;;
+ hppa-level-2.0) GMP_HPPA_LEVEL_20($cc $cflags,,testlist_pass=no) ;;
+ sizeof*) GMP_C_TEST_SIZEOF($cc $cflags,$tst,,testlist_pass=no) ;;
+ esac
+ if test $testlist_pass = no; then break; fi
+ done
+
+ if test $testlist_pass = yes; then
+ found_compiler=yes
+ break
+ fi
+ done
+
+ if test $found_compiler = yes; then break; fi
+ done
+
+ if test $found_compiler = yes; then break; fi
+ done
+
+ if test $found_compiler = yes; then break; fi
+done
+
+
+# If we recognised the CPU, as indicated by $path being set, then insist
+# that we have a working compiler, either from our $cclist choices or from
+# $CC. We can't let AC_PROG_CC look around for a compiler because it might
+# find one that we've rejected (for not supporting the modes our asm code
+# demands, etc).
+#
+# If we didn't recognise the CPU (and this includes host_cpu=none), then
+# fall through and let AC_PROG_CC look around for a compiler too. This is
+# mostly in the interests of following a standard autoconf setup, after all
+# we've already tested cc and gcc adequately (hopefully). As of autoconf
+# 2.50 the only thing AC_PROG_CC really adds is a check for "cl" (Microsoft
+# C on MS-DOS systems).
+#
+if test $found_compiler = no && test -n "$path"; then
+ AC_MSG_ERROR([could not find a working compiler, see config.log for details])
+fi
+
+case $host in
+ X86_PATTERN | X86_64_PATTERN)
+ # If the user asked for a fat build, override the path and flags set above
+ if test $enable_fat = yes; then
+ gcc_cflags_cpu=""
+ gcc_cflags_arch=""
+
+ fat_functions="add_n addmul_1 bdiv_dbm1c com cnd_add_n cnd_sub_n
+ copyd copyi dive_1 divrem_1
+ gcd_1 lshift lshiftc mod_1 mod_1_1 mod_1_1_cps mod_1_2
+ mod_1_2_cps mod_1_4 mod_1_4_cps mod_34lsub1 mode1o mul_1
+ mul_basecase mullo_basecase pre_divrem_1 pre_mod_1 redc_1
+ redc_2 rshift sqr_basecase sub_n submul_1"
+
+ if test "$abi" = 32; then
+ extra_functions="$extra_functions fat fat_entry"
+ path="x86/fat x86"
+ fat_path="x86 x86/fat x86/i486
+ x86/k6 x86/k6/mmx x86/k6/k62mmx
+ x86/k7 x86/k7/mmx
+ x86/k8 x86/k10 x86/bobcat
+ x86/pentium x86/pentium/mmx
+ x86/p6 x86/p6/mmx x86/p6/p3mmx x86/p6/sse2
+ x86/pentium4 x86/pentium4/mmx x86/pentium4/sse2
+ x86/core2 x86/coreinhm x86/coreisbr
+ x86/atom x86/atom/mmx x86/atom/sse2 x86/nano"
+ fi
+
+ if test "$abi" = 64; then
+ gcc_64_cflags=""
+ extra_functions_64="$extra_functions_64 fat fat_entry"
+ path_64="x86_64/fat x86_64"
+ fat_path="x86_64 x86_64/fat
+ x86_64/k8 x86_64/k10 x86_64/bd1 x86_64/bobcat
+ x86_64/pentium4 x86_64/core2 x86_64/coreinhm x86_64/coreisbr
+ x86_64/coreihwl x86_64/atom x86_64/nano"
+ fat_functions="$fat_functions addmul_2 addlsh1_n addlsh2_n sublsh1_n"
+ fi
+
+ fat_thresholds="MUL_TOOM22_THRESHOLD MUL_TOOM33_THRESHOLD
+ SQR_TOOM2_THRESHOLD SQR_TOOM3_THRESHOLD
+ BMOD_1_TO_MOD_1_THRESHOLD"
+ fi
+ ;;
+esac
+
+
+if test $found_compiler = yes; then
+
+ # If we're creating CFLAGS, then look for optional additions. If the user
+ # set CFLAGS then leave it alone.
+ #
+ if test "$test_CFLAGS" != set; then
+ eval optlist=\"\$${ccbase}${abi1}_cflags_optlist\"
+ test -n "$optlist" || eval optlist=\"\$${ccbase}${abi2}_cflags_optlist\"
+
+ for opt in $optlist; do
+ eval optflags=\"\$${ccbase}${abi1}_cflags_${opt}\"
+ test -n "$optflags" || eval optflags=\"\$${ccbase}${abi2}_cflags_${opt}\"
+ test -n "$optflags" || eval optflags=\"\$${ccbase}_cflags_${opt}\"
+
+ for flag in $optflags; do
+
+ # ~ represents a space in an option spec
+ flag=`echo "$flag" | tr '~' ' '`
+
+ case $flag in
+ -march=pentium4 | -march=k8)
+ # For -march settings which enable SSE2 we exclude certain bad
+ # gcc versions and we need an OS knowing how to save xmm regs.
+ #
+ # This is only for ABI=32, any 64-bit gcc is good and any OS
+ # knowing x86_64 will know xmm.
+ #
+ # -march=k8 was only introduced in gcc 3.3, so we shouldn't need
+ # the GMP_GCC_PENTIUM4_SSE2 check (for gcc 3.2 and prior). But
+ # it doesn't hurt to run it anyway, sharing code with the
+ # pentium4 case.
+ #
+ if test "$abi" = 32; then
+ GMP_GCC_PENTIUM4_SSE2($cc $cflags $cppflags,, continue)
+ GMP_OS_X86_XMM($cc $cflags $cppflags,, continue)
+ fi
+ ;;
+ -no-cpp-precomp)
+ # special check, avoiding a warning
+ GMP_GCC_NO_CPP_PRECOMP($ccbase,$cc,$cflags,
+ [cflags="$cflags $flag"
+ break],
+ [continue])
+ ;;
+ -Wa,-m*)
+ case $host in
+ alpha*-*-*)
+ GMP_GCC_WA_MCPU($cc $cflags, $flag, , [continue])
+ ;;
+ esac
+ ;;
+ -Wa,-oldas)
+ GMP_GCC_WA_OLDAS($cc $cflags $cppflags,
+ [cflags="$cflags $flag"
+ break],
+ [continue])
+ ;;
+ esac
+
+ GMP_PROG_CC_WORKS($cc $cflags $cppflags $flag,
+ [cflags="$cflags $flag"
+ break])
+ done
+ done
+ fi
+
+ ABI="$abi"
+ CC="$cc"
+ CFLAGS="$cflags"
+ CPPFLAGS="$cppflags"
+ eval GMP_NONSTD_ABI=\"\$GMP_NONSTD_ABI_$ABI\"
+
+ # Could easily have this in config.h too, if desired.
+ ABI_nodots=`echo $ABI | sed 's/\./_/'`
+ GMP_DEFINE_RAW("define_not_for_expansion(\`HAVE_ABI_$ABI_nodots')", POST)
+
+
+ # GMP_LDFLAGS substitution, selected according to ABI.
+ # These are needed on libgmp.la and libmp.la, but currently not on
+ # convenience libraries like tune/libspeed.la or mpz/libmpz.la.
+ #
+ eval GMP_LDFLAGS=\"\$${ccbase}${abi1}_ldflags\"
+ test -n "$GMP_LDFLAGS" || eval GMP_LDFLAGS=\"\$${ccbase}${abi1}_ldflags\"
+ AC_SUBST(GMP_LDFLAGS)
+ AC_SUBST(LIBGMP_LDFLAGS)
+ AC_SUBST(LIBGMPXX_LDFLAGS)
+
+ # extra_functions, selected according to ABI
+ eval tmp=\"\$extra_functions$abi1\"
+ test -n "$tmp" || eval tmp=\"\$extra_functions$abi2\"
+ extra_functions="$tmp"
+
+
+ # Cycle counter, selected according to ABI.
+ #
+ eval tmp=\"\$SPEED_CYCLECOUNTER_OBJ$abi1\"
+ test -n "$tmp" || eval tmp=\"\$SPEED_CYCLECOUNTER_OBJ$abi2\"
+ SPEED_CYCLECOUNTER_OBJ="$tmp"
+ eval tmp=\"\$cyclecounter_size$abi1\"
+ test -n "$tmp" || eval tmp=\"\$cyclecounter_size$abi2\"
+ cyclecounter_size="$tmp"
+
+ if test -n "$SPEED_CYCLECOUNTER_OBJ"; then
+ AC_DEFINE_UNQUOTED(HAVE_SPEED_CYCLECOUNTER, $cyclecounter_size,
+ [Tune directory speed_cyclecounter, undef=none, 1=32bits, 2=64bits)])
+ fi
+ AC_SUBST(SPEED_CYCLECOUNTER_OBJ)
+
+
+ # Calling conventions checking, selected according to ABI.
+ #
+ eval tmp=\"\$CALLING_CONVENTIONS_OBJS$abi1\"
+ test -n "$tmp" || eval tmp=\"\$CALLING_CONVENTIONS_OBJS$abi2\"
+ if test "$enable_assembly" = "yes"; then
+ CALLING_CONVENTIONS_OBJS="$tmp"
+ else
+ CALLING_CONVENTIONS_OBJS=""
+ fi
+
+ if test -n "$CALLING_CONVENTIONS_OBJS"; then
+ AC_DEFINE(HAVE_CALLING_CONVENTIONS,1,
+ [Define to 1 if tests/libtests has calling conventions checking for the CPU])
+ fi
+ AC_SUBST(CALLING_CONVENTIONS_OBJS)
+
+fi
+
+
+# If the user gave an MPN_PATH, use that verbatim, otherwise choose
+# according to the ABI and add "generic".
+#
+if test -n "$MPN_PATH"; then
+ path="$MPN_PATH"
+else
+ eval tmp=\"\$path$abi1\"
+ test -n "$tmp" || eval tmp=\"\$path$abi2\"
+ path="$tmp generic"
+fi
+
+
+# Long long limb setup for gmp.h.
+case $limb_chosen in
+longlong) DEFN_LONG_LONG_LIMB="#define _LONG_LONG_LIMB 1" ;;
+*) DEFN_LONG_LONG_LIMB="/* #undef _LONG_LONG_LIMB */" ;;
+esac
+AC_SUBST(DEFN_LONG_LONG_LIMB)
+
+
+# The C compiler and preprocessor, put into ANSI mode if possible.
+AC_PROG_CC
+AC_PROG_CC_STDC
+AC_PROG_CPP
+
+
+# The C compiler on the build system, and associated tests.
+GMP_PROG_CC_FOR_BUILD
+GMP_PROG_CPP_FOR_BUILD
+GMP_PROG_EXEEXT_FOR_BUILD
+GMP_C_FOR_BUILD_ANSI
+GMP_CHECK_LIBM_FOR_BUILD
+
+
+# How to assemble, used with CFLAGS etc, see mpn/Makeasm.am.
+# Using the compiler is a lot easier than figuring out how to invoke the
+# assembler directly.
+#
+test -n "$CCAS" || CCAS="$CC -c"
+AC_SUBST(CCAS)
+
+
+# The C++ compiler, if desired.
+want_cxx=no
+if test $enable_cxx != no; then
+ test_CXXFLAGS=${CXXFLAGS+set}
+ AC_PROG_CXX
+
+ echo "CXXFLAGS chosen by autoconf: $CXXFLAGS" >&AC_FD_CC
+ cxxflags_ac_prog_cxx=$CXXFLAGS
+ cxxflags_list=ac_prog_cxx
+
+ # If the user didn't specify $CXXFLAGS, then try $CFLAGS, with -g removed
+ # if AC_PROG_CXX thinks that doesn't work. $CFLAGS stands a good chance
+ # of working, eg. on a GNU system where CC=gcc and CXX=g++.
+ #
+ if test "$test_CXXFLAGS" != set; then
+ cxxflags_cflags=$CFLAGS
+ cxxflags_list="cflags $cxxflags_list"
+ if test "$ac_prog_cxx_g" = no; then
+ cxxflags_cflags=`echo "$cxxflags_cflags" | sed -e 's/ -g //' -e 's/^-g //' -e 's/ -g$//'`
+ fi
+ fi
+
+ # See if the C++ compiler works. If the user specified CXXFLAGS then all
+ # we're doing is checking whether AC_PROG_CXX succeeded, since it doesn't
+ # give a fatal error, just leaves CXX set to a default g++. If on the
+ # other hand the user didn't specify CXXFLAGS then we get to try here our
+ # $cxxflags_list alternatives.
+ #
+ # Automake includes $CPPFLAGS in a C++ compile, so we do the same here.
+ #
+ for cxxflags_choice in $cxxflags_list; do
+ eval CXXFLAGS=\"\$cxxflags_$cxxflags_choice\"
+ GMP_PROG_CXX_WORKS($CXX $CPPFLAGS $CXXFLAGS,
+ [want_cxx=yes
+ break])
+ done
+
+ # If --enable-cxx=yes but a C++ compiler can't be found, then abort.
+ if test $want_cxx = no && test $enable_cxx = yes; then
+ AC_MSG_ERROR([C++ compiler not available, see config.log for details])
+ fi
+fi
+
+AM_CONDITIONAL(WANT_CXX, test $want_cxx = yes)
+
+# FIXME: We're not interested in CXXCPP for ourselves, but if we don't do it
+# here then AC_PROG_LIBTOOL will AC_REQUIRE it (via _LT_AC_TAGCONFIG) and
+# hence execute it unconditionally, and that will fail if there's no C++
+# compiler (and no generic /lib/cpp).
+#
+if test $want_cxx = yes; then
+ AC_PROG_CXXCPP
+fi
+
+
+# Path setups for Cray, according to IEEE or CFP. These must come after
+# deciding the compiler.
+#
+GMP_CRAY_OPTIONS(
+ [add_path="cray/ieee"],
+ [add_path="cray/cfp"; extra_functions="mulwwc90"],
+ [add_path="cray/cfp"; extra_functions="mulwwj90"])
+
+
+if test -z "$MPN_PATH"; then
+ path="$add_path $path"
+fi
+
+# For a nail build, also look in "nails" subdirectories.
+#
+if test $GMP_NAIL_BITS != 0 && test -z "$MPN_PATH"; then
+ new_path=
+ for i in $path; do
+ case $i in
+ generic) new_path="$new_path $i" ;;
+ *) new_path="$new_path $i/nails $i" ;;
+ esac
+ done
+ path=$new_path
+fi
+
+
+# Put all directories into CPUVEC_list so as to get a full set of
+# CPUVEC_SETUP_$tmp_suffix defines into config.h, even if some of them are
+# empty because mmx and/or sse2 had to be dropped.
+#
+for i in $fat_path; do
+ GMP_FAT_SUFFIX(tmp_suffix, $i)
+ CPUVEC_list="$CPUVEC_list CPUVEC_SETUP_$tmp_suffix"
+done
+
+
+# If there's any sse2 or mmx in the path, check whether the assembler
+# supports it, and remove if not.
+#
+# We only need this in ABI=32, for ABI=64 on x86_64 we can assume a new
+# enough assembler.
+#
+case $host in
+ X86_PATTERN | X86_64_PATTERN)
+ if test "$ABI" = 32; then
+ case "$path $fat_path" in
+ *mmx*) GMP_ASM_X86_MMX( , [GMP_STRIP_PATH(*mmx*)]) ;;
+ esac
+ case "$path $fat_path" in
+ *sse2*) GMP_ASM_X86_SSE2( , [GMP_STRIP_PATH(sse2)]) ;;
+ esac
+ fi
+ case "$path $fat_path" in
+ *mulx*) GMP_ASM_X86_MULX( , [GMP_STRIP_PATH(mulx)]) ;;
+ esac
+ case "$path $fat_path" in
+ *adx*) GMP_ASM_X86_ADX( , [GMP_STRIP_PATH(adx)]) ;;
+ esac
+ ;;
+esac
+
+
+if test "$enable_assembly" = "no"; then
+ path="generic"
+ CFLAGS="$CFLAGS -DNO_ASM"
+# for abi in $abilist; do
+# eval unset "path_\$abi"
+# eval gcc_${abi}_cflags=\"\$gcc_${abi}_cflags -DNO_ASM\"
+# done
+fi
+
+
+cat >&AC_FD_CC <<EOF
+Decided:
+ABI=$ABI
+CC=$CC
+CFLAGS=$CFLAGS
+CPPFLAGS=$CPPFLAGS
+GMP_LDFLAGS=$GMP_LDFLAGS
+CXX=$CXX
+CXXFLAGS=$CXXFLAGS
+path=$path
+EOF
+echo "using ABI=\"$ABI\""
+echo " CC=\"$CC\""
+echo " CFLAGS=\"$CFLAGS\""
+echo " CPPFLAGS=\"$CPPFLAGS\""
+if test $want_cxx = yes; then
+ echo " CXX=\"$CXX\""
+ echo " CXXFLAGS=\"$CXXFLAGS\""
+fi
+echo " MPN_PATH=\"$path\""
+
+
+CL_AS_NOEXECSTACK
+
+GMP_PROG_AR
+GMP_PROG_NM
+
+case $host in
+ # FIXME: On AIX 3 and 4, $libname.a is included in libtool
+ # $library_names_spec, so libgmp.a becomes a symlink to libgmp.so, making
+ # it impossible to build shared and static libraries simultaneously.
+ # Disable shared libraries by default, but let the user override with
+ # --enable-shared --disable-static.
+ #
+ # FIXME: This $libname.a problem looks like it might apply to *-*-amigaos*
+ # and *-*-os2* too, but wait for someone to test this before worrying
+ # about it. If there is a problem then of course libtool is the right
+ # place to fix it.
+ #
+ [*-*-aix[34]*])
+ if test -z "$enable_shared"; then enable_shared=no; fi ;;
+esac
+
+
+# Configs for Windows DLLs.
+
+AC_LIBTOOL_WIN32_DLL
+
+AC_SUBST(LIBGMP_DLL,0)
+case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ # By default, build only static.
+ if test -z "$enable_shared"; then
+ enable_shared=no
+ fi
+ # Don't allow both static and DLL.
+ if test "$enable_shared" != no && test "$enable_static" != no; then
+ AC_MSG_ERROR([cannot build both static and DLL, since gmp.h is different for each.
+Use "--disable-static --enable-shared" to build just a DLL.])
+ fi
+
+ # "-no-undefined" is required when building a DLL, see documentation on
+ # AC_LIBTOOL_WIN32_DLL.
+ #
+ # "-Wl,--export-all-symbols" is a bit of a hack, it gets all libgmp and
+ # libgmpxx functions and variables exported. This is what libtool did
+ # in the past, and it's convenient for us in the test programs.
+ #
+ # Maybe it'd be prudent to check for --export-all-symbols before using
+ # it, but it seems to have been in ld since at least 2000, and there's
+ # not really any alternative we want to take up at the moment.
+ #
+ # "-Wl,output-def" is used to get a .def file for use by MS lib to make
+ # a .lib import library, described in the manual. libgmp-3.dll.def
+ # corresponds to the libmp-3.dll.def generated by libtool (as a result
+ # of -export-symbols on that library).
+ #
+ # Incidentally, libtool does generate an import library libgmp.dll.a,
+ # but it's "ar" format and cannot be used by the MS linker. There
+ # doesn't seem to be any GNU tool for generating or converting to .lib.
+ #
+ # FIXME: The .def files produced by -Wl,output-def include isascii,
+ # iscsym, iscsymf and toascii, apparently because mingw ctype.h doesn't
+ # inline isascii (used in gmp). It gives an extern inline for
+ # __isascii, but for some reason not the plain isascii.
+ #
+ if test "$enable_shared" = yes; then
+ GMP_LDFLAGS="$GMP_LDFLAGS -no-undefined -Wl,--export-all-symbols"
+ LIBGMP_LDFLAGS="$LIBGMP_LDFLAGS -Wl,--output-def,.libs/libgmp-3.dll.def"
+ LIBGMPXX_LDFLAGS="$LIBGMP_LDFLAGS -Wl,--output-def,.libs/libgmpxx-3.dll.def"
+ LIBGMP_DLL=1
+ fi
+ ;;
+esac
+
+
+# Ensure that $CONFIG_SHELL is available for AC_LIBTOOL_SYS_MAX_CMD_LEN.
+# It's often set already by _LT_AC_PROG_ECHO_BACKSLASH or
+# _AS_LINENO_PREPARE, but not always.
+#
+# The symptom of CONFIG_SHELL unset is some "expr" errors during the test,
+# and an empty result. This only happens when invoked as "sh configure",
+# ie. no path, and can be seen for instance on ia64-*-hpux*.
+#
+# FIXME: Newer libtool should have it's own fix for this.
+#
+if test -z "$CONFIG_SHELL"; then
+ CONFIG_SHELL=$SHELL
+fi
+
+# Enable CXX in libtool only if we want it, and never enable GCJ, nor RC on
+# mingw and cygwin. Under --disable-cxx this avoids some error messages
+# from libtool arising from the fact we didn't actually run AC_PROG_CXX.
+# Notice that any user-supplied --with-tags setting takes precedence.
+#
+# FIXME: Is this the right way to get this effect? Very possibly not, but
+# the current _LT_AC_TAGCONFIG doesn't really suggest an alternative.
+#
+if test "${with_tags+set}" != set; then
+ if test $want_cxx = yes; then
+ with_tags=CXX
+ else
+ with_tags=
+ fi
+fi
+
+# The dead hand of AC_REQUIRE makes AC_PROG_LIBTOOL expand and execute
+# AC_PROG_F77, even when F77 is not in the selected with_tags. This is
+# probably harmless, but it's unsightly and bloats our configure, so pretend
+# AC_PROG_F77 has been expanded already.
+#
+# FIXME: Rumour has it libtool will one day provide a way for a configure.in
+# to say what it wants from among supported languages etc.
+#
+#AC_PROVIDE([AC_PROG_F77])
+
+AC_PROG_LIBTOOL
+
+# Generate an error here if attempting to build both shared and static when
+# $libname.a is in $library_names_spec (as mentioned above), rather than
+# wait for ar or ld to fail.
+#
+if test "$enable_shared" = yes && test "$enable_static" = yes; then
+ case $library_names_spec in
+ *libname.a*)
+ AC_MSG_ERROR([cannot create both shared and static libraries on this system, --disable one of the two])
+ ;;
+ esac
+fi
+
+AM_CONDITIONAL(ENABLE_STATIC, test "$enable_static" = yes)
+
+
+# Many of these library and header checks are for the benefit of
+# supplementary programs. libgmp doesn't use anything too weird.
+
+AC_HEADER_STDC
+AC_HEADER_TIME
+
+# Reasons for testing:
+# float.h - not in SunOS bundled cc
+# invent.h - IRIX specific
+# langinfo.h - X/Open standard only, not in djgpp for instance
+# locale.h - old systems won't have this
+# nl_types.h - X/Open standard only, not in djgpp for instance
+# (usually langinfo.h gives nl_item etc, but not on netbsd 1.4.1)
+# sys/attributes.h - IRIX specific
+# sys/iograph.h - IRIX specific
+# sys/mman.h - not in Cray Unicos
+# sys/param.h - not in mingw
+# sys/processor.h - solaris specific, though also present in macos
+# sys/pstat.h - HPUX specific
+# sys/resource.h - not in mingw
+# sys/sysctl.h - not in mingw
+# sys/sysinfo.h - OSF specific
+# sys/syssgi.h - IRIX specific
+# sys/systemcfg.h - AIX specific
+# sys/time.h - autoconf suggests testing, don't know anywhere without it
+# sys/times.h - not in mingw
+# machine/hal_sysinfo.h - OSF specific
+#
+# inttypes.h, stdint.h, unistd.h and sys/types.h are already in the autoconf
+# default tests
+#
+AC_CHECK_HEADERS(fcntl.h float.h invent.h langinfo.h locale.h nl_types.h sys/attributes.h sys/iograph.h sys/mman.h sys/param.h sys/processor.h sys/pstat.h sys/sysinfo.h sys/syssgi.h sys/systemcfg.h sys/time.h sys/times.h)
+
+# On SunOS, sys/resource.h needs sys/time.h (for struct timeval)
+AC_CHECK_HEADERS(sys/resource.h,,,
+[#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif])
+
+# On NetBSD and OpenBSD, sys/sysctl.h needs sys/param.h for various constants
+AC_CHECK_HEADERS(sys/sysctl.h,,,
+[#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif])
+
+# On OSF 4.0, <machine/hal_sysinfo.h> must have <sys/sysinfo.h> for ulong_t
+AC_CHECK_HEADERS(machine/hal_sysinfo.h,,,
+[#if HAVE_SYS_SYSINFO_H
+# include <sys/sysinfo.h>
+#endif])
+
+# Reasons for testing:
+# optarg - not declared in mingw
+# fgetc, fscanf, ungetc, vfprintf - not declared in SunOS 4
+# sys_errlist, sys_nerr - not declared in SunOS 4
+#
+# optarg should be in unistd.h and the rest in stdio.h, both of which are
+# in the autoconf default includes.
+#
+# sys_errlist and sys_nerr are supposed to be in <errno.h> on SunOS according
+# to the man page (but aren't), in glibc they're in stdio.h.
+#
+AC_CHECK_DECLS([fgetc, fscanf, optarg, ungetc, vfprintf])
+AC_CHECK_DECLS([sys_errlist, sys_nerr], , ,
+[#include <stdio.h>
+#include <errno.h>])
+
+AC_TYPE_SIGNAL
+
+# Reasons for testing:
+# intmax_t - C99
+# long double - not in the HP bundled K&R cc
+# long long - only in reasonably recent compilers
+# ptrdiff_t - seems to be everywhere, maybe don't need to check this
+# quad_t - BSD specific
+# uint_least32_t - C99
+#
+# the default includes are sufficient for all these types
+#
+AC_CHECK_TYPES([intmax_t, long double, long long, ptrdiff_t, quad_t,
+ uint_least32_t, intptr_t])
+
+AC_C_STRINGIZE
+
+# FIXME: Really want #ifndef __cplusplus around the #define volatile
+# replacement autoconf gives, since volatile is always available in C++.
+# But we don't use it in C++ currently.
+AC_C_VOLATILE
+
+AC_C_RESTRICT
+
+# GMP_C_STDARG
+GMP_C_ATTRIBUTE_CONST
+GMP_C_ATTRIBUTE_MALLOC
+GMP_C_ATTRIBUTE_MODE
+GMP_C_ATTRIBUTE_NORETURN
+
+GMP_H_EXTERN_INLINE
+
+# from libtool
+AC_CHECK_LIBM
+AC_SUBST(LIBM)
+
+GMP_FUNC_ALLOCA
+GMP_OPTION_ALLOCA
+
+GMP_H_HAVE_FILE
+
+AC_C_BIGENDIAN(
+ [AC_DEFINE(HAVE_LIMB_BIG_ENDIAN, 1)
+ GMP_DEFINE_RAW("define_not_for_expansion(\`HAVE_LIMB_BIG_ENDIAN')", POST)],
+ [AC_DEFINE(HAVE_LIMB_LITTLE_ENDIAN, 1)
+ GMP_DEFINE_RAW("define_not_for_expansion(\`HAVE_LIMB_LITTLE_ENDIAN')", POST)
+ ], [:])
+AH_VERBATIM([HAVE_LIMB],
+[/* Define one of these to 1 for the endianness of `mp_limb_t'.
+ If the endianness is not a simple big or little, or you don't know what
+ it is, then leave both undefined. */
+#undef HAVE_LIMB_BIG_ENDIAN
+#undef HAVE_LIMB_LITTLE_ENDIAN])
+
+GMP_C_DOUBLE_FORMAT
+
+
+# Reasons for testing:
+# alarm - not in mingw
+# attr_get - IRIX specific
+# clock_gettime - not in glibc 2.2.4, only very recent systems
+# cputime - not in glibc
+# getsysinfo - OSF specific
+# getrusage - not in mingw
+# gettimeofday - not in mingw
+# mmap - not in mingw, djgpp
+# nl_langinfo - X/Open standard only, not in djgpp for instance
+# obstack_vprintf - glibc specific
+# processor_info - solaris specific
+# pstat_getprocessor - HPUX specific (10.x and up)
+# raise - an ANSI-ism, though probably almost universal by now
+# read_real_time - AIX specific
+# sigaction - not in mingw
+# sigaltstack - not in mingw, or old AIX (reputedly)
+# sigstack - not in mingw
+# strerror - not in SunOS
+# strnlen - glibc extension (some other systems too)
+# syssgi - IRIX specific
+# times - not in mingw
+#
+# AC_FUNC_STRNLEN is not used because we don't want the AC_LIBOBJ
+# replacement setups it gives. It detects a faulty strnlen on AIX, but
+# missing out on that test is ok since our only use of strnlen is in
+# __gmp_replacement_vsnprintf which is not required on AIX since it has a
+# vsnprintf.
+#
+AC_CHECK_FUNCS(alarm attr_get clock cputime getpagesize getrusage gettimeofday getsysinfo localeconv memset mmap mprotect nl_langinfo obstack_vprintf popen processor_info pstat_getprocessor raise read_real_time sigaction sigaltstack sigstack syssgi strchr strerror strnlen strtol strtoul sysconf sysctl sysctlbyname times)
+
+# clock_gettime is in librt on *-*-osf5.1 and on glibc, so att -lrt to
+# TUNE_LIBS if needed. On linux (tested on x86_32, 2.6.26),
+# clock_getres reports ns accuracy, while in a quick test on osf
+# clock_getres said only 1 millisecond.
+
+old_LIBS="$LIBS"
+AC_SEARCH_LIBS(clock_gettime, rt, [
+ AC_DEFINE([HAVE_CLOCK_GETTIME],1,[Define to 1 if you have the `clock_gettime' function])])
+TUNE_LIBS="$LIBS"
+LIBS="$old_LIBS"
+
+AC_SUBST(TUNE_LIBS)
+
+GMP_FUNC_VSNPRINTF
+GMP_FUNC_SSCANF_WRITABLE_INPUT
+
+# Reasons for checking:
+# pst_processor psp_iticksperclktick - not in hpux 9
+#
+AC_CHECK_MEMBER(struct pst_processor.psp_iticksperclktick,
+ [AC_DEFINE(HAVE_PSP_ITICKSPERCLKTICK, 1,
+[Define to 1 if <sys/pstat.h> `struct pst_processor' exists
+and contains `psp_iticksperclktick'.])],,
+ [#include <sys/pstat.h>])
+
+# C++ tests, when required
+#
+if test $enable_cxx = yes; then
+ AC_LANG_PUSH(C++)
+
+ # Reasons for testing:
+ # <sstream> - not in g++ 2.95.2
+ # std::locale - not in g++ 2.95.4
+ #
+ AC_CHECK_HEADERS([sstream])
+ AC_CHECK_TYPES([std::locale],,,[#include <locale>])
+
+ AC_LANG_POP(C++)
+fi
+
+
+# Pick the correct source files in $path and link them to mpn/.
+# $gmp_mpn_functions lists all functions we need.
+#
+# The rule is to find a file with the function name and a .asm, .S,
+# .s, or .c extension. Certain multi-function files with special names
+# can provide some functions too. (mpn/Makefile.am passes
+# -DOPERATION_<func> to get them to generate the right code.)
+
+# Note: $gmp_mpn_functions must have mod_1 before pre_mod_1 so the former
+# can optionally provide the latter as an extra entrypoint. Likewise
+# divrem_1 and pre_divrem_1.
+
+gmp_mpn_functions_optional="umul udiv \
+ invert_limb sqr_diagonal sqr_diag_addlsh1 \
+ mul_2 mul_3 mul_4 mul_5 mul_6 \
+ addmul_2 addmul_3 addmul_4 addmul_5 addmul_6 addmul_7 addmul_8 \
+ addlsh1_n sublsh1_n rsblsh1_n rsh1add_n rsh1sub_n \
+ addlsh2_n sublsh2_n rsblsh2_n \
+ addlsh_n sublsh_n rsblsh_n \
+ add_n_sub_n addaddmul_1msb0"
+
+gmp_mpn_functions="$extra_functions \
+ add add_1 add_n sub sub_1 sub_n cnd_add_n cnd_sub_n neg com \
+ mul_1 addmul_1 submul_1 \
+ add_err1_n add_err2_n add_err3_n sub_err1_n sub_err2_n sub_err3_n \
+ lshift rshift dive_1 diveby3 divis divrem divrem_1 divrem_2 \
+ fib2_ui mod_1 mod_34lsub1 mode1o pre_divrem_1 pre_mod_1 dump \
+ mod_1_1 mod_1_2 mod_1_3 mod_1_4 lshiftc \
+ mul mul_fft mul_n sqr mul_basecase sqr_basecase nussbaumer_mul \
+ mulmid_basecase toom42_mulmid mulmid_n mulmid \
+ random random2 pow_1 \
+ rootrem sqrtrem sizeinbase get_str set_str \
+ scan0 scan1 popcount hamdist cmp \
+ perfsqr perfpow \
+ gcd_1 gcd gcdext_1 gcdext gcd_subdiv_step \
+ gcdext_lehmer \
+ div_q tdiv_qr jacbase jacobi_2 jacobi get_d \
+ matrix22_mul matrix22_mul1_inverse_vector \
+ hgcd_matrix hgcd2 hgcd_step hgcd_reduce hgcd hgcd_appr \
+ hgcd2_jacobi hgcd_jacobi \
+ mullo_n mullo_basecase \
+ toom22_mul toom32_mul toom42_mul toom52_mul toom62_mul \
+ toom33_mul toom43_mul toom53_mul toom54_mul toom63_mul \
+ toom44_mul \
+ toom6h_mul toom6_sqr toom8h_mul toom8_sqr \
+ toom_couple_handling \
+ toom2_sqr toom3_sqr toom4_sqr \
+ toom_eval_dgr3_pm1 toom_eval_dgr3_pm2 \
+ toom_eval_pm1 toom_eval_pm2 toom_eval_pm2exp toom_eval_pm2rexp \
+ toom_interpolate_5pts toom_interpolate_6pts toom_interpolate_7pts \
+ toom_interpolate_8pts toom_interpolate_12pts toom_interpolate_16pts \
+ invertappr invert binvert mulmod_bnm1 sqrmod_bnm1 \
+ div_qr_1 div_qr_1n_pi1 \
+ div_qr_2 div_qr_2n_pi1 div_qr_2u_pi1 \
+ sbpi1_div_q sbpi1_div_qr sbpi1_divappr_q \
+ dcpi1_div_q dcpi1_div_qr dcpi1_divappr_q \
+ mu_div_qr mu_divappr_q mu_div_q \
+ bdiv_q_1 \
+ sbpi1_bdiv_q sbpi1_bdiv_qr \
+ dcpi1_bdiv_q dcpi1_bdiv_qr \
+ mu_bdiv_q mu_bdiv_qr \
+ bdiv_q bdiv_qr broot brootinv bsqrt bsqrtinv \
+ divexact bdiv_dbm1c redc_1 redc_2 redc_n powm powlo sec_powm \
+ sec_mul sec_sqr sec_div_qr sec_div_r sec_pi1_div_qr sec_pi1_div_r \
+ sec_add_1 sec_sub_1 sec_invert \
+ trialdiv remove \
+ and_n andn_n nand_n ior_n iorn_n nior_n xor_n xnor_n \
+ copyi copyd zero sec_tabselect \
+ comb_tables \
+ $gmp_mpn_functions_optional"
+
+define(GMP_MULFUNC_CHOICES,
+[# functions that can be provided by multi-function files
+tmp_mulfunc=
+case $tmp_fn in
+ add_n|sub_n) tmp_mulfunc="aors_n" ;;
+ add_err1_n|sub_err1_n)
+ tmp_mulfunc="aors_err1_n" ;;
+ add_err2_n|sub_err2_n)
+ tmp_mulfunc="aors_err2_n" ;;
+ add_err3_n|sub_err3_n)
+ tmp_mulfunc="aors_err3_n" ;;
+ cnd_add_n|cnd_sub_n) tmp_mulfunc="cnd_aors_n" ;;
+ sec_add_1|sec_sub_1) tmp_mulfunc="sec_aors_1" ;;
+ addmul_1|submul_1) tmp_mulfunc="aorsmul_1" ;;
+ mul_2|addmul_2) tmp_mulfunc="aormul_2" ;;
+ mul_3|addmul_3) tmp_mulfunc="aormul_3" ;;
+ mul_4|addmul_4) tmp_mulfunc="aormul_4" ;;
+ popcount|hamdist) tmp_mulfunc="popham" ;;
+ and_n|andn_n|nand_n | ior_n|iorn_n|nior_n | xor_n|xnor_n)
+ tmp_mulfunc="logops_n" ;;
+ lshift|rshift) tmp_mulfunc="lorrshift";;
+ addlsh1_n)
+ tmp_mulfunc="aorslsh1_n aorrlsh1_n aorsorrlsh1_n";;
+ sublsh1_n)
+ tmp_mulfunc="aorslsh1_n sorrlsh1_n aorsorrlsh1_n";;
+ rsblsh1_n)
+ tmp_mulfunc="aorrlsh1_n sorrlsh1_n aorsorrlsh1_n";;
+ addlsh2_n)
+ tmp_mulfunc="aorslsh2_n aorrlsh2_n aorsorrlsh2_n";;
+ sublsh2_n)
+ tmp_mulfunc="aorslsh2_n sorrlsh2_n aorsorrlsh2_n";;
+ rsblsh2_n)
+ tmp_mulfunc="aorrlsh2_n sorrlsh2_n aorsorrlsh2_n";;
+ addlsh_n)
+ tmp_mulfunc="aorslsh_n aorrlsh_n aorsorrlsh_n";;
+ sublsh_n)
+ tmp_mulfunc="aorslsh_n sorrlsh_n aorsorrlsh_n";;
+ rsblsh_n)
+ tmp_mulfunc="aorrlsh_n sorrlsh_n aorsorrlsh_n";;
+ rsh1add_n|rsh1sub_n)
+ tmp_mulfunc="rsh1aors_n";;
+ sec_div_qr|sec_div_r)
+ tmp_mulfunc="sec_div";;
+ sec_pi1_div_qr|sec_pi1_div_r)
+ tmp_mulfunc="sec_pi1_div";;
+esac
+])
+
+# the list of all object files used by mpn/Makefile.in and the
+# top-level Makefile.in, respectively
+mpn_objects=
+mpn_objs_in_libgmp=
+
+# links from the sources, to be removed by "make distclean"
+gmp_srclinks=
+
+
+# mpn_relative_top_srcdir is $top_srcdir, but for use from within the mpn
+# build directory. If $srcdir is relative then we use a relative path too,
+# so the two trees can be moved together.
+case $srcdir in
+ [[\\/]* | ?:[\\/]*]) # absolute, as per autoconf
+ mpn_relative_top_srcdir=$srcdir ;;
+ *) # relative
+ mpn_relative_top_srcdir=../$srcdir ;;
+esac
+
+
+define(MPN_SUFFIXES,[asm S s c])
+
+dnl Usage: GMP_FILE_TO_FUNCTION_BASE(func,file)
+dnl
+dnl Set $func to the function base name for $file, eg. dive_1 gives
+dnl divexact_1.
+dnl
+define(GMP_FILE_TO_FUNCTION,
+[case $$2 in
+ dive_1) $1=divexact_1 ;;
+ diveby3) $1=divexact_by3c ;;
+ pre_divrem_1) $1=preinv_divrem_1 ;;
+ mode1o) $1=modexact_1c_odd ;;
+ pre_mod_1) $1=preinv_mod_1 ;;
+ mod_1_1) $1=mod_1_1p ;;
+ mod_1_1_cps) $1=mod_1_1p_cps ;;
+ mod_1_2) $1=mod_1s_2p ;;
+ mod_1_2_cps) $1=mod_1s_2p_cps ;;
+ mod_1_3) $1=mod_1s_3p ;;
+ mod_1_3_cps) $1=mod_1s_3p_cps ;;
+ mod_1_4) $1=mod_1s_4p ;;
+ mod_1_4_cps) $1=mod_1s_4p_cps ;;
+ *) $1=$$2 ;;
+esac
+])
+
+# Fat binary setups.
+#
+# We proceed through each $fat_path directory, and look for $fat_function
+# routines there. Those found are incorporated in the build by generating a
+# little mpn/<foo>.asm or mpn/<foo>.c file in the build directory, with
+# suitable function renaming, and adding that to $mpn_objects (the same as a
+# normal mpn file).
+#
+# fat.h is generated with macros to let internal calls to each $fat_function
+# go directly through __gmpn_cpuvec, plus macros and declarations helping to
+# setup that structure, on a per-directory basis ready for
+# mpn/<cpu>/fat/fat.c.
+#
+# fat.h includes thresholds listed in $fat_thresholds, extracted from
+# gmp-mparam.h in each directory. An overall maximum for each threshold is
+# established, for use in making fixed size arrays of temporary space.
+# (Eg. MUL_TOOM33_THRESHOLD_LIMIT used by mpn/generic/mul.c.)
+#
+# It'd be possible to do some of this manually, but when there's more than a
+# few functions and a few directories it becomes very tedious, and very
+# prone to having some routine accidentally omitted. On that basis it seems
+# best to automate as much as possible, even if the code to do so is a bit
+# ugly.
+#
+
+if test -n "$fat_path"; then
+ # Usually the mpn build directory is created with mpn/Makefile
+ # instantiation, but we want to write to it sooner.
+ mkdir mpn 2>/dev/null
+
+ echo "/* fat.h - setups for fat binaries." >fat.h
+ echo " Generated by configure - DO NOT EDIT. */" >>fat.h
+
+ AC_DEFINE(WANT_FAT_BINARY, 1, [Define to 1 when building a fat binary.])
+ GMP_DEFINE(WANT_FAT_BINARY, yes)
+
+ # Don't want normal copies of fat functions
+ for tmp_fn in $fat_functions; do
+ GMP_REMOVE_FROM_LIST(gmp_mpn_functions, $tmp_fn)
+ GMP_REMOVE_FROM_LIST(gmp_mpn_functions_optional, $tmp_fn)
+ done
+
+ for tmp_fn in $fat_functions; do
+ GMP_FILE_TO_FUNCTION(tmp_fbase,tmp_fn)
+ echo "
+#ifndef OPERATION_$tmp_fn
+#undef mpn_$tmp_fbase
+#define mpn_$tmp_fbase (*__gmpn_cpuvec.$tmp_fbase)
+#endif
+DECL_$tmp_fbase (__MPN(${tmp_fbase}_init));" >>fat.h
+ # encourage various macros to use fat functions
+ AC_DEFINE_UNQUOTED(HAVE_NATIVE_mpn_$tmp_fbase)
+ done
+
+ echo "" >>fat.h
+ echo "/* variable thresholds */" >>fat.h
+ for tmp_tn in $fat_thresholds; do
+ echo "#undef $tmp_tn" >>fat.h
+ echo "#define $tmp_tn CPUVEC_THRESHOLD (`echo $tmp_tn | tr [A-Z] [a-z]`)" >>fat.h
+ done
+
+ echo "
+/* Copy all fields into __gmpn_cpuvec.
+ memcpy is not used because it might operate byte-wise (depending on its
+ implementation), and we need the function pointer writes to be atomic.
+ "volatile" discourages the compiler from trying to optimize this. */
+#define CPUVEC_INSTALL(vec) \\
+ do { \\
+ volatile struct cpuvec_t *p = &__gmpn_cpuvec; \\" >>fat.h
+ for tmp_fn in $fat_functions; do
+ GMP_FILE_TO_FUNCTION(tmp_fbase,tmp_fn)
+ echo " p->$tmp_fbase = vec.$tmp_fbase; \\" >>fat.h
+ done
+ for tmp_tn in $fat_thresholds; do
+ tmp_field_name=`echo $tmp_tn | tr [[A-Z]] [[a-z]]`
+ echo " p->$tmp_field_name = vec.$tmp_field_name; \\" >>fat.h
+ done
+ echo " } while (0)" >>fat.h
+
+ echo "
+/* A helper to check all fields are filled. */
+#define ASSERT_CPUVEC(vec) \\
+ do { \\" >>fat.h
+ for tmp_fn in $fat_functions; do
+ GMP_FILE_TO_FUNCTION(tmp_fbase,tmp_fn)
+ echo " ASSERT (vec.$tmp_fbase != NULL); \\" >>fat.h
+ done
+ for tmp_tn in $fat_thresholds; do
+ tmp_field_name=`echo $tmp_tn | tr [[A-Z]] [[a-z]]`
+ echo " ASSERT (vec.$tmp_field_name != 0); \\" >>fat.h
+ done
+ echo " } while (0)" >>fat.h
+
+ echo "
+/* Call ITERATE(field) for each fat threshold field. */
+#define ITERATE_FAT_THRESHOLDS() \\
+ do { \\" >>fat.h
+ for tmp_tn in $fat_thresholds; do
+ tmp_field_name=`echo $tmp_tn | tr [[A-Z]] [[a-z]]`
+ echo " ITERATE ($tmp_tn, $tmp_field_name); \\" >>fat.h
+ done
+ echo " } while (0)" >>fat.h
+
+ for tmp_dir in $fat_path; do
+ CPUVEC_SETUP=
+ THRESH_ASM_SETUP=
+ echo "" >>fat.h
+ GMP_FAT_SUFFIX(tmp_suffix, $tmp_dir)
+
+ # In order to keep names unique on a DOS 8.3 filesystem, use a prefix
+ # (rather than a suffix) for the generated file names, and abbreviate.
+ case $tmp_suffix in
+ pentium) tmp_prefix=p ;;
+ pentium_mmx) tmp_prefix=pm ;;
+ p6_mmx) tmp_prefix=p2 ;;
+ p6_p3mmx) tmp_prefix=p3 ;;
+ pentium4) tmp_prefix=p4 ;;
+ pentium4_mmx) tmp_prefix=p4m ;;
+ pentium4_sse2) tmp_prefix=p4s ;;
+ k6_mmx) tmp_prefix=k6m ;;
+ k6_k62mmx) tmp_prefix=k62 ;;
+ k7_mmx) tmp_prefix=k7m ;;
+ *) tmp_prefix=$tmp_suffix ;;
+ esac
+
+ # Extract desired thresholds from gmp-mparam.h file in this directory,
+ # if present.
+ tmp_mparam=$srcdir/mpn/$tmp_dir/gmp-mparam.h
+ if test -f $tmp_mparam; then
+ for tmp_tn in $fat_thresholds; do
+ tmp_thresh=`sed -n "s/^#define $tmp_tn[ ]*\\([0-9][0-9]*\\).*$/\\1/p" $tmp_mparam`
+ if test -n "$tmp_thresh"; then
+ THRESH_ASM_SETUP=["${THRESH_ASM_SETUP}define($tmp_tn,$tmp_thresh)
+"]
+ CPUVEC_SETUP="$CPUVEC_SETUP decided_cpuvec.`echo $tmp_tn | tr [[A-Z]] [[a-z]]` = $tmp_thresh; \\
+"
+ eval tmp_limit=\$${tmp_tn}_LIMIT
+ if test -z "$tmp_limit"; then
+ tmp_limit=0
+ fi
+ if test $tmp_thresh -gt $tmp_limit; then
+ eval ${tmp_tn}_LIMIT=$tmp_thresh
+ fi
+ fi
+ done
+ fi
+
+ for tmp_fn in $fat_functions; do
+ GMP_MULFUNC_CHOICES
+
+ for tmp_base in $tmp_fn $tmp_mulfunc; do
+ for tmp_ext in MPN_SUFFIXES; do
+ tmp_file=$srcdir/mpn/$tmp_dir/$tmp_base.$tmp_ext
+ if test -f $tmp_file; then
+
+ # If the host uses a non-standard ABI, check if tmp_file supports it
+ #
+ if test -n "$GMP_NONSTD_ABI" && test $tmp_ext != "c"; then
+ abi=[`sed -n 's/^[ ]*ABI_SUPPORT(\(.*\))/\1/p' $tmp_file `]
+ if echo "$abi" | grep -q "\\b${GMP_NONSTD_ABI}\\b"; then
+ true
+ else
+ continue
+ fi
+ fi
+
+ mpn_objects="$mpn_objects ${tmp_prefix}_$tmp_fn.lo"
+ mpn_objs_in_libgmp="$mpn_objs_in_libgmp mpn/${tmp_prefix}_$tmp_fn.lo"
+
+ GMP_FILE_TO_FUNCTION(tmp_fbase,tmp_fn)
+
+ # carry-in variant, eg. divrem_1c or modexact_1c_odd
+ case $tmp_fbase in
+ *_1*) tmp_fbasec=`echo $tmp_fbase | sed 's/_1/_1c/'` ;;
+ *) tmp_fbasec=${tmp_fbase}c ;;
+ esac
+
+ # Create a little file doing an include from srcdir. The
+ # OPERATION and renamings aren't all needed all the time, but
+ # they don't hurt if unused.
+ #
+ # FIXME: Should generate these via config.status commands.
+ # Would need them all in one AC_CONFIG_COMMANDS though, since
+ # that macro doesn't accept a set of separate commands generated
+ # by shell code.
+ #
+ case $tmp_ext in
+ asm)
+ # hide the d-n-l from autoconf's error checking
+ tmp_d_n_l=d""nl
+ echo ["$tmp_d_n_l mpn_$tmp_fbase - from $tmp_dir directory for fat binary.
+$tmp_d_n_l Generated by configure - DO NOT EDIT.
+
+define(OPERATION_$tmp_fn)
+define(__gmpn_$tmp_fbase, __gmpn_${tmp_fbase}_$tmp_suffix)
+define(__gmpn_$tmp_fbasec,__gmpn_${tmp_fbasec}_${tmp_suffix})
+define(__gmpn_preinv_${tmp_fbase},__gmpn_preinv_${tmp_fbase}_${tmp_suffix})
+define(__gmpn_${tmp_fbase}_cps,__gmpn_${tmp_fbase}_cps_${tmp_suffix})
+
+$tmp_d_n_l For k6 and k7 gcd_1 calling their corresponding mpn_modexact_1_odd
+ifdef(\`__gmpn_modexact_1_odd',,
+\`define(__gmpn_modexact_1_odd,__gmpn_modexact_1_odd_${tmp_suffix})')
+
+$THRESH_ASM_SETUP
+include][($mpn_relative_top_srcdir/mpn/$tmp_dir/$tmp_base.asm)
+"] >mpn/${tmp_prefix}_$tmp_fn.asm
+ ;;
+ c)
+ echo ["/* mpn_$tmp_fbase - from $tmp_dir directory for fat binary.
+ Generated by configure - DO NOT EDIT. */
+
+#define OPERATION_$tmp_fn 1
+#define __gmpn_$tmp_fbase __gmpn_${tmp_fbase}_$tmp_suffix
+#define __gmpn_$tmp_fbasec __gmpn_${tmp_fbasec}_${tmp_suffix}
+#define __gmpn_preinv_${tmp_fbase} __gmpn_preinv_${tmp_fbase}_${tmp_suffix}
+#define __gmpn_${tmp_fbase}_cps __gmpn_${tmp_fbase}_cps_${tmp_suffix}
+
+#include \"$mpn_relative_top_srcdir/mpn/$tmp_dir/$tmp_base.c\"
+"] >mpn/${tmp_prefix}_$tmp_fn.c
+ ;;
+ esac
+
+ # Prototype, and append to CPUVEC_SETUP for this directory.
+ echo "DECL_$tmp_fbase (__gmpn_${tmp_fbase}_$tmp_suffix);" >>fat.h
+ CPUVEC_SETUP="$CPUVEC_SETUP decided_cpuvec.$tmp_fbase = __gmpn_${tmp_fbase}_${tmp_suffix}; \\
+"
+ # Ditto for any preinv variant (preinv_divrem_1, preinv_mod_1).
+ if grep "^PROLOGUE(mpn_preinv_$tmp_fn)" $tmp_file >/dev/null; then
+ echo "DECL_preinv_$tmp_fbase (__gmpn_preinv_${tmp_fbase}_$tmp_suffix);" >>fat.h
+ CPUVEC_SETUP="$CPUVEC_SETUP decided_cpuvec.preinv_$tmp_fbase = __gmpn_preinv_${tmp_fbase}_${tmp_suffix}; \\
+"
+ fi
+
+ # Ditto for any mod_1...cps variant
+ if grep "^PROLOGUE(mpn_${tmp_fbase}_cps)" $tmp_file >/dev/null; then
+ echo "DECL_${tmp_fbase}_cps (__gmpn_${tmp_fbase}_cps_$tmp_suffix);" >>fat.h
+ CPUVEC_SETUP="$CPUVEC_SETUP decided_cpuvec.${tmp_fbase}_cps = __gmpn_${tmp_fbase}_cps_${tmp_suffix}; \\
+"
+ fi
+ fi
+ done
+ done
+ done
+
+ # Emit CPUVEC_SETUP for this directory
+ echo "" >>fat.h
+ echo "#define CPUVEC_SETUP_$tmp_suffix \\" >>fat.h
+ echo " do { \\" >>fat.h
+ echo "$CPUVEC_SETUP } while (0)" >>fat.h
+ done
+
+ # Emit threshold limits
+ echo "" >>fat.h
+ for tmp_tn in $fat_thresholds; do
+ eval tmp_limit=\$${tmp_tn}_LIMIT
+ echo "#define ${tmp_tn}_LIMIT $tmp_limit" >>fat.h
+ done
+fi
+
+
+# Normal binary setups.
+#
+
+for tmp_ext in MPN_SUFFIXES; do
+ eval found_$tmp_ext=no
+done
+
+for tmp_fn in $gmp_mpn_functions; do
+ for tmp_ext in MPN_SUFFIXES; do
+ test "$no_create" = yes || rm -f mpn/$tmp_fn.$tmp_ext
+ done
+
+ # mpn_preinv_divrem_1 might have been provided by divrem_1.asm, likewise
+ # mpn_preinv_mod_1 by mod_1.asm.
+ case $tmp_fn in
+ pre_divrem_1)
+ if test "$HAVE_NATIVE_mpn_preinv_divrem_1" = yes; then continue; fi ;;
+ pre_mod_1)
+ if test "$HAVE_NATIVE_mpn_preinv_mod_1" = yes; then continue; fi ;;
+ esac
+
+ GMP_MULFUNC_CHOICES
+
+ found=no
+ for tmp_dir in $path; do
+ for tmp_base in $tmp_fn $tmp_mulfunc; do
+ for tmp_ext in MPN_SUFFIXES; do
+ tmp_file=$srcdir/mpn/$tmp_dir/$tmp_base.$tmp_ext
+ if test -f $tmp_file; then
+
+ # For a nails build, check if the file supports our nail bits.
+ # Generic code always supports all nails.
+ #
+ # FIXME: When a multi-function file is selected to provide one of
+ # the nails-neutral routines, like logops_n for and_n, the
+ # PROLOGUE grepping will create HAVE_NATIVE_mpn_<foo> defines for
+ # all functions in that file, even if they haven't all been
+ # nailified. Not sure what to do about this, it's only really a
+ # problem for logops_n, and it's not too terrible to insist those
+ # get nailified always.
+ #
+ if test $GMP_NAIL_BITS != 0 && test $tmp_dir != generic; then
+ case $tmp_fn in
+ and_n | ior_n | xor_n | andn_n | \
+ copyi | copyd | \
+ popcount | hamdist | \
+ udiv | udiv_w_sdiv | umul | \
+ cntlz | invert_limb)
+ # these operations are either unaffected by nails or defined
+ # to operate on full limbs
+ ;;
+ *)
+ nails=[`sed -n 's/^[ ]*NAILS_SUPPORT(\(.*\))/\1/p' $tmp_file `]
+ for n in $nails; do
+ case $n in
+ *-*)
+ n_start=`echo "$n" | sed -n 's/\(.*\)-.*/\1/p'`
+ n_end=`echo "$n" | sed -n 's/.*-\(.*\)/\1/p'`
+ ;;
+ *)
+ n_start=$n
+ n_end=$n
+ ;;
+ esac
+ if test $GMP_NAIL_BITS -ge $n_start && test $GMP_NAIL_BITS -le $n_end; then
+ found=yes
+ break
+ fi
+ done
+ if test $found != yes; then
+ continue
+ fi
+ ;;
+ esac
+ fi
+
+ # If the host uses a non-standard ABI, check if tmp_file supports it
+ #
+ if test -n "$GMP_NONSTD_ABI" && test $tmp_ext != "c"; then
+ abi=[`sed -n 's/^[ ]*ABI_SUPPORT(\(.*\))/\1/p' $tmp_file `]
+ if echo "$abi" | grep -q "\\b${GMP_NONSTD_ABI}\\b"; then
+ true
+ else
+ continue
+ fi
+ fi
+
+ found=yes
+ eval found_$tmp_ext=yes
+
+ if test $tmp_ext = c; then
+ tmp_u='$U'
+ else
+ tmp_u=
+ fi
+
+ mpn_objects="$mpn_objects $tmp_fn$tmp_u.lo"
+ mpn_objs_in_libgmp="$mpn_objs_in_libgmp mpn/$tmp_fn$tmp_u.lo"
+ AC_CONFIG_LINKS(mpn/$tmp_fn.$tmp_ext:mpn/$tmp_dir/$tmp_base.$tmp_ext)
+ gmp_srclinks="$gmp_srclinks mpn/$tmp_fn.$tmp_ext"
+
+ # Duplicate AC_DEFINEs are harmless, so it doesn't matter
+ # that multi-function files get grepped here repeatedly.
+ # The PROLOGUE pattern excludes the optional second parameter.
+ gmp_ep=[`
+ sed -n 's/^[ ]*MULFUNC_PROLOGUE(\(.*\))/\1/p' $tmp_file ;
+ sed -n 's/^[ ]*PROLOGUE(\([^,]*\).*)/\1/p' $tmp_file
+ `]
+ for gmp_tmp in $gmp_ep; do
+ AC_DEFINE_UNQUOTED(HAVE_NATIVE_$gmp_tmp)
+ eval HAVE_NATIVE_$gmp_tmp=yes
+ done
+
+ case $tmp_fn in
+ sqr_basecase) sqr_basecase_source=$tmp_file ;;
+ esac
+
+ break
+ fi
+ done
+ if test $found = yes; then break ; fi
+ done
+ if test $found = yes; then break ; fi
+ done
+
+ if test $found = no; then
+ for tmp_optional in $gmp_mpn_functions_optional; do
+ if test $tmp_optional = $tmp_fn; then
+ found=yes
+ fi
+ done
+ if test $found = no; then
+ AC_MSG_ERROR([no version of $tmp_fn found in path: $path])
+ fi
+ fi
+done
+
+# All cycle counters are .asm files currently
+if test -n "$SPEED_CYCLECOUNTER_OBJ"; then
+ found_asm=yes
+fi
+
+dnl The following list only needs to have templates for those defines which
+dnl are going to be tested by the code, there's no need to have every
+dnl possible mpn routine.
+
+AH_VERBATIM([HAVE_NATIVE],
+[/* Define to 1 each of the following for which a native (ie. CPU specific)
+ implementation of the corresponding routine exists. */
+#undef HAVE_NATIVE_mpn_add_n
+#undef HAVE_NATIVE_mpn_add_n_sub_n
+#undef HAVE_NATIVE_mpn_add_nc
+#undef HAVE_NATIVE_mpn_addaddmul_1msb0
+#undef HAVE_NATIVE_mpn_addlsh1_n
+#undef HAVE_NATIVE_mpn_addlsh2_n
+#undef HAVE_NATIVE_mpn_addlsh_n
+#undef HAVE_NATIVE_mpn_addlsh1_nc
+#undef HAVE_NATIVE_mpn_addlsh2_nc
+#undef HAVE_NATIVE_mpn_addlsh_nc
+#undef HAVE_NATIVE_mpn_addlsh1_n_ip1
+#undef HAVE_NATIVE_mpn_addlsh2_n_ip1
+#undef HAVE_NATIVE_mpn_addlsh_n_ip1
+#undef HAVE_NATIVE_mpn_addlsh1_nc_ip1
+#undef HAVE_NATIVE_mpn_addlsh2_nc_ip1
+#undef HAVE_NATIVE_mpn_addlsh_nc_ip1
+#undef HAVE_NATIVE_mpn_addlsh1_n_ip2
+#undef HAVE_NATIVE_mpn_addlsh2_n_ip2
+#undef HAVE_NATIVE_mpn_addlsh_n_ip2
+#undef HAVE_NATIVE_mpn_addlsh1_nc_ip2
+#undef HAVE_NATIVE_mpn_addlsh2_nc_ip2
+#undef HAVE_NATIVE_mpn_addlsh_nc_ip2
+#undef HAVE_NATIVE_mpn_addmul_1c
+#undef HAVE_NATIVE_mpn_addmul_2
+#undef HAVE_NATIVE_mpn_addmul_3
+#undef HAVE_NATIVE_mpn_addmul_4
+#undef HAVE_NATIVE_mpn_addmul_5
+#undef HAVE_NATIVE_mpn_addmul_6
+#undef HAVE_NATIVE_mpn_addmul_7
+#undef HAVE_NATIVE_mpn_addmul_8
+#undef HAVE_NATIVE_mpn_addmul_2s
+#undef HAVE_NATIVE_mpn_and_n
+#undef HAVE_NATIVE_mpn_andn_n
+#undef HAVE_NATIVE_mpn_bdiv_dbm1c
+#undef HAVE_NATIVE_mpn_bdiv_q_1
+#undef HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#undef HAVE_NATIVE_mpn_cnd_add_n
+#undef HAVE_NATIVE_mpn_cnd_sub_n
+#undef HAVE_NATIVE_mpn_com
+#undef HAVE_NATIVE_mpn_copyd
+#undef HAVE_NATIVE_mpn_copyi
+#undef HAVE_NATIVE_mpn_div_qr_1n_pi1
+#undef HAVE_NATIVE_mpn_div_qr_2
+#undef HAVE_NATIVE_mpn_divexact_1
+#undef HAVE_NATIVE_mpn_divexact_by3c
+#undef HAVE_NATIVE_mpn_divrem_1
+#undef HAVE_NATIVE_mpn_divrem_1c
+#undef HAVE_NATIVE_mpn_divrem_2
+#undef HAVE_NATIVE_mpn_gcd_1
+#undef HAVE_NATIVE_mpn_hamdist
+#undef HAVE_NATIVE_mpn_invert_limb
+#undef HAVE_NATIVE_mpn_ior_n
+#undef HAVE_NATIVE_mpn_iorn_n
+#undef HAVE_NATIVE_mpn_lshift
+#undef HAVE_NATIVE_mpn_lshiftc
+#undef HAVE_NATIVE_mpn_lshsub_n
+#undef HAVE_NATIVE_mpn_mod_1
+#undef HAVE_NATIVE_mpn_mod_1_1p
+#undef HAVE_NATIVE_mpn_mod_1c
+#undef HAVE_NATIVE_mpn_mod_1s_2p
+#undef HAVE_NATIVE_mpn_mod_1s_4p
+#undef HAVE_NATIVE_mpn_mod_34lsub1
+#undef HAVE_NATIVE_mpn_modexact_1_odd
+#undef HAVE_NATIVE_mpn_modexact_1c_odd
+#undef HAVE_NATIVE_mpn_mul_1
+#undef HAVE_NATIVE_mpn_mul_1c
+#undef HAVE_NATIVE_mpn_mul_2
+#undef HAVE_NATIVE_mpn_mul_3
+#undef HAVE_NATIVE_mpn_mul_4
+#undef HAVE_NATIVE_mpn_mul_5
+#undef HAVE_NATIVE_mpn_mul_6
+#undef HAVE_NATIVE_mpn_mul_basecase
+#undef HAVE_NATIVE_mpn_nand_n
+#undef HAVE_NATIVE_mpn_nior_n
+#undef HAVE_NATIVE_mpn_popcount
+#undef HAVE_NATIVE_mpn_preinv_divrem_1
+#undef HAVE_NATIVE_mpn_preinv_mod_1
+#undef HAVE_NATIVE_mpn_redc_1
+#undef HAVE_NATIVE_mpn_redc_2
+#undef HAVE_NATIVE_mpn_rsblsh1_n
+#undef HAVE_NATIVE_mpn_rsblsh2_n
+#undef HAVE_NATIVE_mpn_rsblsh_n
+#undef HAVE_NATIVE_mpn_rsblsh1_nc
+#undef HAVE_NATIVE_mpn_rsblsh2_nc
+#undef HAVE_NATIVE_mpn_rsblsh_nc
+#undef HAVE_NATIVE_mpn_rsh1add_n
+#undef HAVE_NATIVE_mpn_rsh1add_nc
+#undef HAVE_NATIVE_mpn_rsh1sub_n
+#undef HAVE_NATIVE_mpn_rsh1sub_nc
+#undef HAVE_NATIVE_mpn_rshift
+#undef HAVE_NATIVE_mpn_sqr_basecase
+#undef HAVE_NATIVE_mpn_sqr_diagonal
+#undef HAVE_NATIVE_mpn_sqr_diag_addlsh1
+#undef HAVE_NATIVE_mpn_sub_n
+#undef HAVE_NATIVE_mpn_sub_nc
+#undef HAVE_NATIVE_mpn_sublsh1_n
+#undef HAVE_NATIVE_mpn_sublsh2_n
+#undef HAVE_NATIVE_mpn_sublsh_n
+#undef HAVE_NATIVE_mpn_sublsh1_nc
+#undef HAVE_NATIVE_mpn_sublsh2_nc
+#undef HAVE_NATIVE_mpn_sublsh_nc
+#undef HAVE_NATIVE_mpn_sublsh1_n_ip1
+#undef HAVE_NATIVE_mpn_sublsh2_n_ip1
+#undef HAVE_NATIVE_mpn_sublsh_n_ip1
+#undef HAVE_NATIVE_mpn_sublsh1_nc_ip1
+#undef HAVE_NATIVE_mpn_sublsh2_nc_ip1
+#undef HAVE_NATIVE_mpn_sublsh_nc_ip1
+#undef HAVE_NATIVE_mpn_submul_1c
+#undef HAVE_NATIVE_mpn_tabselect
+#undef HAVE_NATIVE_mpn_udiv_qrnnd
+#undef HAVE_NATIVE_mpn_udiv_qrnnd_r
+#undef HAVE_NATIVE_mpn_umul_ppmm
+#undef HAVE_NATIVE_mpn_umul_ppmm_r
+#undef HAVE_NATIVE_mpn_xor_n
+#undef HAVE_NATIVE_mpn_xnor_n])
+
+
+# Don't demand an m4 unless it's actually needed.
+if test $found_asm = yes; then
+ GMP_PROG_M4
+ GMP_M4_M4WRAP_SPURIOUS
+# else
+# It's unclear why this m4-not-needed stuff was ever done.
+# if test -z "$M4" ; then
+# M4=m4-not-needed
+# fi
+fi
+
+# Only do the GMP_ASM checks if there's a .S or .asm wanting them.
+if test $found_asm = no && test $found_S = no; then
+ gmp_asm_syntax_testing=no
+fi
+
+if test "$gmp_asm_syntax_testing" != no; then
+ GMP_ASM_TEXT
+ GMP_ASM_DATA
+ GMP_ASM_LABEL_SUFFIX
+ GMP_ASM_GLOBL
+ GMP_ASM_GLOBL_ATTR
+ GMP_ASM_UNDERSCORE
+ GMP_ASM_RODATA
+ GMP_ASM_TYPE
+ GMP_ASM_SIZE
+ GMP_ASM_LSYM_PREFIX
+ GMP_ASM_W32
+ GMP_ASM_ALIGN_LOG
+
+ case $host in
+ hppa*-*-*)
+ # for both pa32 and pa64
+ GMP_INCLUDE_MPN(pa32/pa-defs.m4)
+ ;;
+ IA64_PATTERN)
+ GMP_ASM_IA64_ALIGN_OK
+ ;;
+ M68K_PATTERN)
+ GMP_ASM_M68K_INSTRUCTION
+ GMP_ASM_M68K_ADDRESSING
+ GMP_ASM_M68K_BRANCHES
+ ;;
+ [powerpc*-*-* | power[3-9]-*-*])
+ GMP_ASM_POWERPC_PIC_ALWAYS
+ GMP_ASM_POWERPC_R_REGISTERS
+ GMP_INCLUDE_MPN(powerpc32/powerpc-defs.m4)
+
+ # Check for Linux ELFv2 ABI
+ AC_EGREP_CPP(yes,
+[#if _CALL_ELF == 2
+yes
+#endif],
+ [GMP_DEFINE_RAW(["define(<ELFv2_ABI>)"])])
+
+ case $host in
+ *-*-aix*)
+ case $ABI in
+ mode64) GMP_INCLUDE_MPN(powerpc64/aix.m4) ;;
+ *) GMP_INCLUDE_MPN(powerpc32/aix.m4) ;;
+ esac
+ ;;
+ *-*-linux* | *-*-*bsd*)
+ case $ABI in
+ mode64) GMP_INCLUDE_MPN(powerpc64/elf.m4) ;;
+ mode32 | 32) GMP_INCLUDE_MPN(powerpc32/elf.m4) ;;
+ esac
+ ;;
+ *-*-darwin*)
+ case $ABI in
+ mode64) GMP_INCLUDE_MPN(powerpc64/darwin.m4) ;;
+ mode32 | 32) GMP_INCLUDE_MPN(powerpc32/darwin.m4) ;;
+ esac
+ ;;
+ *)
+ # Assume unrecognized operating system is the powerpc eABI
+ GMP_INCLUDE_MPN(powerpc32/eabi.m4)
+ ;;
+ esac
+ ;;
+ power*-*-aix*)
+ GMP_INCLUDE_MPN(powerpc32/aix.m4)
+ ;;
+ *sparc*-*-*)
+ case $ABI in
+ 64)
+ GMP_ASM_SPARC_REGISTER
+ ;;
+ esac
+ GMP_ASM_SPARC_GOTDATA
+ GMP_ASM_SPARC_SHARED_THUNKS
+ ;;
+ X86_PATTERN | X86_64_PATTERN)
+ GMP_ASM_ALIGN_FILL_0x90
+ case $ABI in
+ 32)
+ GMP_INCLUDE_MPN(x86/x86-defs.m4)
+ AC_DEFINE(HAVE_HOST_CPU_FAMILY_x86)
+ GMP_ASM_COFF_TYPE
+ GMP_ASM_X86_GOT_UNDERSCORE
+ GMP_ASM_X86_SHLDL_CL
+ case $enable_profiling in
+ prof | gprof) GMP_ASM_X86_MCOUNT ;;
+ esac
+ case $host in
+ *-*-darwin*)
+ GMP_INCLUDE_MPN(x86/darwin.m4) ;;
+ esac
+ ;;
+ 64|x32)
+ GMP_INCLUDE_MPN(x86_64/x86_64-defs.m4)
+ AC_DEFINE(HAVE_HOST_CPU_FAMILY_x86_64)
+ case $host in
+ *-*-darwin*)
+ GMP_INCLUDE_MPN(x86_64/darwin.m4) ;;
+ *-*-mingw* | *-*-cygwin)
+ GMP_INCLUDE_MPN(x86_64/dos64.m4) ;;
+ *-openbsd*)
+ GMP_DEFINE_RAW(["define(<OPENBSD>,1)"]) ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+fi
+
+# For --enable-minithres, prepend "minithres" to path so that its special
+# gmp-mparam.h will be used.
+if test $enable_minithres = yes; then
+ path="minithres $path"
+fi
+
+# Create link for gmp-mparam.h.
+gmp_mparam_source=
+for gmp_mparam_dir in $path; do
+ test "$no_create" = yes || rm -f gmp-mparam.h
+ tmp_file=$srcdir/mpn/$gmp_mparam_dir/gmp-mparam.h
+ if test -f $tmp_file; then
+ AC_CONFIG_LINKS(gmp-mparam.h:mpn/$gmp_mparam_dir/gmp-mparam.h)
+ gmp_srclinks="$gmp_srclinks gmp-mparam.h"
+ gmp_mparam_source=$tmp_file
+ break
+ fi
+done
+if test -z "$gmp_mparam_source"; then
+ AC_MSG_ERROR([no version of gmp-mparam.h found in path: $path])
+fi
+
+# For a helpful message from tune/tuneup.c
+gmp_mparam_suggest=$gmp_mparam_source
+if test "$gmp_mparam_dir" = generic; then
+ for i in $path; do break; done
+ if test "$i" != generic; then
+ gmp_mparam_suggest="new file $srcdir/mpn/$i/gmp-mparam.h"
+ fi
+fi
+AC_DEFINE_UNQUOTED(GMP_MPARAM_H_SUGGEST, "$gmp_mparam_source",
+[The gmp-mparam.h file (a string) the tune program should suggest updating.])
+
+
+# Copy relevant parameters from gmp-mparam.h to config.m4.
+# We only do this for parameters that are used by some assembly files.
+# Fat binaries do this on a per-file basis, so skip in that case.
+#
+if test -z "$fat_path"; then
+ for i in SQR_TOOM2_THRESHOLD BMOD_1_TO_MOD_1_THRESHOLD SHLD_SLOW SHRD_SLOW; do
+ value=`sed -n 's/^#define '$i'[ ]*\([0-9][0-9]*\).*$/\1/p' $gmp_mparam_source`
+ if test -n "$value"; then
+ GMP_DEFINE_RAW(["define(<$i>,<$value>)"])
+ fi
+ done
+fi
+
+
+# Sizes of some types, needed at preprocessing time.
+#
+# FIXME: The assumption that GMP_LIMB_BITS is 8*sizeof(mp_limb_t) might
+# be slightly rash, but it's true everywhere we know of and ought to be true
+# of any sensible system. In a generic C build, grepping LONG_BIT out of
+# <limits.h> might be an alternative, for maximum portability.
+#
+AC_CHECK_SIZEOF(void *)
+AC_CHECK_SIZEOF(unsigned short)
+AC_CHECK_SIZEOF(unsigned)
+AC_CHECK_SIZEOF(unsigned long)
+AC_CHECK_SIZEOF(mp_limb_t, , GMP_INCLUDE_GMP_H)
+if test "$ac_cv_sizeof_mp_limb_t" = 0; then
+ AC_MSG_ERROR([Oops, mp_limb_t doesn't seem to work])
+fi
+AC_SUBST(GMP_LIMB_BITS, `expr 8 \* $ac_cv_sizeof_mp_limb_t`)
+GMP_DEFINE_RAW(["define(<SIZEOF_UNSIGNED>,<$ac_cv_sizeof_unsigned>)"])
+
+# Check compiler limb size matches gmp-mparam.h
+#
+# FIXME: Some of the cycle counter objects in the tune directory depend on
+# the size of ulong, it'd be possible to check that here, though a mismatch
+# probably wouldn't want to be fatal, none of the libgmp assembler code
+# depends on ulong.
+#
+mparam_bits=[`sed -n 's/^#define GMP_LIMB_BITS[ ][ ]*\([0-9]*\).*$/\1/p' $gmp_mparam_source`]
+if test -n "$mparam_bits" && test "$mparam_bits" -ne $GMP_LIMB_BITS; then
+ if test "$test_CFLAGS" = set; then
+ AC_MSG_ERROR([Oops, mp_limb_t is $GMP_LIMB_BITS bits, but the assembler code
+in this configuration expects $mparam_bits bits.
+You appear to have set \$CFLAGS, perhaps you also need to tell GMP the
+intended ABI, see "ABI and ISA" in the manual.])
+ else
+ AC_MSG_ERROR([Oops, mp_limb_t is $GMP_LIMB_BITS bits, but the assembler code
+in this configuration expects $mparam_bits bits.])
+ fi
+fi
+
+GMP_DEFINE_RAW(["define(<GMP_LIMB_BITS>,$GMP_LIMB_BITS)"])
+GMP_DEFINE_RAW(["define(<GMP_NAIL_BITS>,$GMP_NAIL_BITS)"])
+GMP_DEFINE_RAW(["define(<GMP_NUMB_BITS>,eval(GMP_LIMB_BITS-GMP_NAIL_BITS))"])
+
+
+AC_SUBST(mpn_objects)
+AC_SUBST(mpn_objs_in_libgmp)
+AC_SUBST(gmp_srclinks)
+
+
+# A recompiled sqr_basecase for use in the tune program, if necessary.
+TUNE_SQR_OBJ=
+test -d tune || mkdir tune
+case $sqr_basecase_source in
+ *.asm)
+ sqr_max=[`sed -n 's/^def...(SQR_TOOM2_THRESHOLD_MAX, *\([0-9]*\))/\1/p' $sqr_basecase_source`]
+ if test -n "$sqr_max"; then
+ TUNE_SQR_OBJ=sqr_asm.o
+ AC_DEFINE_UNQUOTED(TUNE_SQR_TOOM2_MAX,$sqr_max,
+ [Maximum size the tune program can test for SQR_TOOM2_THRESHOLD])
+ fi
+ cat >tune/sqr_basecase.c <<EOF
+/* not sure that an empty file can compile, so put in a dummy */
+int sqr_basecase_dummy;
+EOF
+ ;;
+ *.c)
+ TUNE_SQR_OBJ=
+ AC_DEFINE(TUNE_SQR_TOOM2_MAX,SQR_TOOM2_MAX_GENERIC)
+ cat >tune/sqr_basecase.c <<EOF
+#define TUNE_PROGRAM_BUILD 1
+#define TUNE_PROGRAM_BUILD_SQR 1
+#include "mpn/sqr_basecase.c"
+EOF
+ ;;
+esac
+AC_SUBST(TUNE_SQR_OBJ)
+
+
+# Configs for demos/pexpr.c.
+#
+AC_CONFIG_FILES(demos/pexpr-config.h:demos/pexpr-config-h.in)
+GMP_SUBST_CHECK_FUNCS(clock, cputime, getrusage, gettimeofday, sigaction, sigaltstack, sigstack)
+GMP_SUBST_CHECK_HEADERS(sys/resource.h)
+AC_CHECK_TYPES([stack_t], HAVE_STACK_T_01=1, HAVE_STACK_T_01=0,
+ [#include <signal.h>])
+AC_SUBST(HAVE_STACK_T_01)
+
+# Configs for demos/calc directory
+#
+# AC_SUBST+AC_CONFIG_FILES is used for calc-config.h, rather than AC_DEFINE+
+# AC_CONFIG_HEADERS, since with the latter automake (1.8) will then put the
+# directory (ie. demos/calc) into $(DEFAULT_INCLUDES) for every Makefile.in,
+# which would look very strange.
+#
+# -lcurses is required by libreadline. On a typical SVR4 style system this
+# normally doesn't have to be given explicitly, since libreadline.so will
+# have a NEEDED record for it. But if someone for some reason is using only
+# a static libreadline.a then we must give -lcurses. Readline (as of
+# version 4.3) doesn't use libtool, so we can't rely on a .la to cover
+# necessary dependencies.
+#
+# On a couple of systems we've seen libreadline available, but the headers
+# not in the default include path, so check for readline/readline.h. We've
+# also seen readline/history.h missing, not sure if that's just a broken
+# install or a very old version, but check that too.
+#
+AC_CONFIG_FILES(demos/calc/calc-config.h:demos/calc/calc-config-h.in)
+LIBCURSES=
+if test $with_readline != no; then
+ AC_CHECK_LIB(ncurses, tputs, [LIBCURSES=-lncurses],
+ [AC_CHECK_LIB(curses, tputs, [LIBCURSES=-lcurses])])
+fi
+AC_SUBST(LIBCURSES)
+use_readline=$with_readline
+if test $with_readline = detect; then
+ use_readline=no
+ AC_CHECK_LIB(readline, readline,
+ [AC_CHECK_HEADER(readline/readline.h,
+ [AC_CHECK_HEADER(readline/history.h, use_readline=yes)])],
+ , $LIBCURSES)
+ AC_MSG_CHECKING(readline detected)
+ AC_MSG_RESULT($use_readline)
+fi
+if test $use_readline = yes; then
+ AC_SUBST(WITH_READLINE_01, 1)
+ AC_SUBST(LIBREADLINE, -lreadline)
+else
+ WITH_READLINE_01=0
+fi
+AC_PROG_YACC
+AM_PROG_LEX
+
+# Configs for demos/expr directory
+#
+# Libtool already runs an AC_CHECK_TOOL for ranlib, but we give
+# AC_PROG_RANLIB anyway since automake is supposed to complain if it's not
+# called. (Automake 1.8.4 doesn't, at least not when the only library is in
+# an EXTRA_LIBRARIES.)
+#
+AC_PROG_RANLIB
+
+
+# Create config.m4.
+GMP_FINISH
+
+# Create Makefiles
+# FIXME: Upcoming version of autoconf/automake may not like broken lines.
+# Right now automake isn't accepting the new AC_CONFIG_FILES scheme.
+
+AC_OUTPUT(Makefile \
+ mpf/Makefile mpn/Makefile mpq/Makefile \
+ mpz/Makefile printf/Makefile scanf/Makefile rand/Makefile cxx/Makefile \
+ tests/Makefile tests/devel/Makefile \
+ tests/mpf/Makefile tests/mpn/Makefile tests/mpq/Makefile \
+ tests/mpz/Makefile tests/rand/Makefile tests/misc/Makefile \
+ tests/cxx/Makefile \
+ doc/Makefile tune/Makefile \
+ demos/Makefile demos/calc/Makefile demos/expr/Makefile \
+ gmp.h:gmp-h.in)
+
+AC_MSG_NOTICE([summary of build options:
+
+ Version: ${PACKAGE_STRING}
+ Host type: ${host}
+ ABI: ${ABI}
+ Install prefix: ${prefix}
+ Compiler: ${CC}
+ Static libraries: ${enable_static}
+ Shared libraries: ${enable_shared}
+])
+
+if test x$cross_compiling = xyes ; then
+ case "$host" in
+ *-*-mingw* | *-*-cygwin)
+ if test x$ABI = x64 ; then
+ AC_MSG_NOTICE([If wine64 is installed, use make check TESTS_ENVIRONMENT=wine64.])
+ else
+ AC_MSG_NOTICE([If wine is installed, use make check TESTS_ENVIRONMENT=wine.])
+ fi
+ ;;
+ esac
+fi
diff --git a/gmp/cxx/Makefile.am b/gmp/cxx/Makefile.am
new file mode 100644
index 0000000000..6af8ea3038
--- /dev/null
+++ b/gmp/cxx/Makefile.am
@@ -0,0 +1,40 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2001-2003, 2012 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -D__GMP_WITHIN_GMPXX -I$(top_srcdir)
+
+if WANT_CXX
+noinst_LTLIBRARIES = libcxx.la
+endif
+
+libcxx_la_SOURCES = \
+ isfuns.cc ismpf.cc ismpq.cc ismpz.cc ismpznw.cc limits.cc \
+ osdoprnti.cc osfuns.cc osmpf.cc osmpq.cc osmpz.cc
diff --git a/gmp/cxx/Makefile.in b/gmp/cxx/Makefile.in
new file mode 100644
index 0000000000..6066a76a7d
--- /dev/null
+++ b/gmp/cxx/Makefile.in
@@ -0,0 +1,556 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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-2003, 2012 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = cxx
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libcxx_la_LIBADD =
+am_libcxx_la_OBJECTS = isfuns.lo ismpf.lo ismpq.lo ismpz.lo ismpznw.lo \
+ limits.lo osdoprnti.lo osfuns.lo osmpf.lo osmpq.lo osmpz.lo
+libcxx_la_OBJECTS = $(am_libcxx_la_OBJECTS)
+@WANT_CXX_TRUE@am_libcxx_la_rpath =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp =
+am__depfiles_maybe =
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libcxx_la_SOURCES)
+DIST_SOURCES = $(libcxx_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -D__GMP_WITHIN_GMPXX -I$(top_srcdir)
+@WANT_CXX_TRUE@noinst_LTLIBRARIES = libcxx.la
+libcxx_la_SOURCES = \
+ isfuns.cc ismpf.cc ismpq.cc ismpz.cc ismpznw.cc limits.cc \
+ osdoprnti.cc osfuns.cc osmpf.cc osmpq.cc osmpz.cc
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .o .obj
+$(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 cxx/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps cxx/Makefile
+.PRECIOUS: 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-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libcxx.la: $(libcxx_la_OBJECTS) $(libcxx_la_DEPENDENCIES) $(EXTRA_libcxx_la_DEPENDENCIES)
+ $(CXXLINK) $(am_libcxx_la_rpath) $(libcxx_la_OBJECTS) $(libcxx_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.cc.o:
+ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+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:
+
+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-generic clean-libtool clean-noinstLTLIBRARIES \
+ 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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags 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 tags uninstall uninstall-am
+
+
+# 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/gmp/cxx/dummy.cc b/gmp/cxx/dummy.cc
new file mode 100644
index 0000000000..8b728caa2d
--- /dev/null
+++ b/gmp/cxx/dummy.cc
@@ -0,0 +1,33 @@
+/* Dummy file to make automake treat libgmpxx.la as C++.
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* some compilers reputedly dislike completely empty files */
+typedef int foo;
diff --git a/gmp/cxx/isfuns.cc b/gmp/cxx/isfuns.cc
new file mode 100644
index 0000000000..3d349bcfa5
--- /dev/null
+++ b/gmp/cxx/isfuns.cc
@@ -0,0 +1,116 @@
+/* Auxiliary functions for C++-style input of GMP types.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <cctype>
+#include <iostream>
+#include <string>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+int
+__gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase)
+{
+ int base;
+
+ zero = showbase = false;
+ switch (i.flags() & ios::basefield)
+ {
+ case ios::dec:
+ base = 10;
+ break;
+ case ios::hex:
+ base = 16;
+ break;
+ case ios::oct:
+ base = 8;
+ break;
+ default:
+ showbase = true; // look for initial "0" or "0x" or "0X"
+ if (c == '0')
+ {
+ if (! i.get(c))
+ c = 0; // reset or we might loop indefinitely
+
+ if (c == 'x' || c == 'X')
+ {
+ base = 16;
+ i.get(c);
+ }
+ else
+ {
+ base = 8;
+ zero = true; // if no other digit is read, the "0" counts
+ }
+ }
+ else
+ base = 10;
+ break;
+ }
+
+ return base;
+}
+
+void
+__gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base)
+{
+ switch (base)
+ {
+ case 10:
+ while (isdigit(c))
+ {
+ ok = true; // at least a valid digit was read
+ s += c;
+ if (! i.get(c))
+ break;
+ }
+ break;
+ case 8:
+ while (isdigit(c) && c != '8' && c != '9')
+ {
+ ok = true; // at least a valid digit was read
+ s += c;
+ if (! i.get(c))
+ break;
+ }
+ break;
+ case 16:
+ while (isxdigit(c))
+ {
+ ok = true; // at least a valid digit was read
+ s += c;
+ if (! i.get(c))
+ break;
+ }
+ break;
+ }
+}
diff --git a/gmp/cxx/ismpf.cc b/gmp/cxx/ismpf.cc
new file mode 100644
index 0000000000..71c2b44d5c
--- /dev/null
+++ b/gmp/cxx/ismpf.cc
@@ -0,0 +1,145 @@
+/* operator>> -- C++-style input of mpf_t.
+
+Copyright 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <cctype>
+#include <iostream>
+#include <string>
+#include <clocale> // for localeconv
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+// For g++ libstdc++ parsing see num_get<chartype,initer>::_M_extract_float
+// in include/bits/locale_facets.tcc.
+//
+// There are no plans to accept hex or octal floats, not unless the standard
+// C++ library does so. Although such formats might be of use, it's
+// considered more important to be compatible with what the normal
+// operator>> does on "double"s etc.
+
+istream &
+operator>> (istream &i, mpf_ptr f)
+{
+ int base;
+ char c = 0;
+ string s;
+ bool ok = false;
+
+ // C decimal point, as expected by mpf_set_str
+ const char *lconv_point = GMP_DECIMAL_POINT;
+
+ // C++ decimal point
+#if HAVE_STD__LOCALE
+ const locale& loc = i.getloc();
+ char point_char = use_facet< numpunct<char> >(loc).decimal_point();
+#else
+ const char *point = lconv_point;
+ char point_char = *point;
+#endif
+
+ i.get(c); // start reading
+
+ if (i.flags() & ios::skipws) // skip initial whitespace
+ {
+ // C++ isspace
+#if HAVE_STD__LOCALE
+ const ctype<char>& ct = use_facet< ctype<char> >(loc);
+#define cxx_isspace(c) (ct.is(ctype_base::space,(c)))
+#else
+#define cxx_isspace(c) isspace(c)
+#endif
+
+ while (cxx_isspace(c) && i.get(c))
+ ;
+ }
+
+ if (c == '-' || c == '+') // sign
+ {
+ if (c == '-')
+ s = "-";
+ i.get(c);
+ }
+
+ base = 10;
+ __gmp_istream_set_digits(s, i, c, ok, base); // read the number
+
+ // look for the C++ radix point, but put the C one in for mpf_set_str
+ if (c == point_char)
+ {
+#if HAVE_STD__LOCALE
+ i.get(c);
+#else // lconv point can be multi-char
+ for (;;)
+ {
+ i.get(c);
+ point++;
+ if (*point == '\0')
+ break;
+ if (c != *point)
+ goto fail;
+ }
+#endif
+ s += lconv_point;
+ __gmp_istream_set_digits(s, i, c, ok, base); // read the mantissa
+ }
+
+ if (ok && (c == 'e' || c == 'E')) // exponent
+ {
+ s += c;
+ i.get(c);
+ ok = false; // exponent is mandatory
+
+ if (c == '-' || c == '+') // sign
+ {
+ s += c;
+ i.get(c);
+ }
+
+ __gmp_istream_set_digits(s, i, c, ok, base); // read the exponent
+ }
+
+ if (i.good()) // last character read was non-numeric
+ i.putback(c);
+ else if (i.eof() && ok) // stopped just before eof
+ i.clear(ios::eofbit);
+
+ if (ok)
+ ASSERT_NOCARRY (mpf_set_str(f, s.c_str(), base)); // extract the number
+ else
+ {
+ fail:
+ i.setstate(ios::failbit); // read failed
+ }
+
+ return i;
+}
diff --git a/gmp/cxx/ismpq.cc b/gmp/cxx/ismpq.cc
new file mode 100644
index 0000000000..bc12e4a228
--- /dev/null
+++ b/gmp/cxx/ismpq.cc
@@ -0,0 +1,67 @@
+/* operator>> -- C++-style input of mpq_t.
+
+Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <cctype>
+#include <iostream>
+#include <string>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+istream &
+operator>> (istream &i, mpq_ptr q)
+{
+ if (! (i >> mpq_numref(q)))
+ return i;
+
+ char c = 0;
+ i.get(c); // start reading
+
+ if (c == '/')
+ {
+ // skip slash, read denominator
+ i.get(c);
+ return __gmpz_operator_in_nowhite (i, mpq_denref(q), c);
+ }
+ else
+ {
+ // no denominator, set 1
+ q->_mp_den._mp_size = 1;
+ q->_mp_den._mp_d[0] = 1;
+ if (i.good())
+ i.putback(c);
+ else if (i.eof())
+ i.clear(ios::eofbit);
+ }
+
+ return i;
+}
diff --git a/gmp/cxx/ismpz.cc b/gmp/cxx/ismpz.cc
new file mode 100644
index 0000000000..e4775bc300
--- /dev/null
+++ b/gmp/cxx/ismpz.cc
@@ -0,0 +1,63 @@
+/* operator>> -- C++-style input of mpz_t.
+
+Copyright 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <cctype>
+#include <iostream>
+#include <string>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+// For g++ libstdc++ parsing see num_get<chartype,initer>::_M_extract_int in
+// include/bits/locale_facets.tcc.
+
+istream &
+operator>> (istream &i, mpz_ptr z)
+{
+ char c = 0;
+ i.get(c); // start reading
+
+ if (i.flags() & ios::skipws) // skip initial whitespace
+ {
+#if HAVE_STD__LOCALE
+ const ctype<char>& ct = use_facet< ctype<char> >(i.getloc());
+#define cxx_isspace(c) (ct.is(ctype_base::space,(c)))
+#else
+#define cxx_isspace(c) isspace(c)
+#endif
+
+ while (cxx_isspace(c) && i.get(c))
+ ;
+ }
+
+ return __gmpz_operator_in_nowhite (i, z, c);
+}
diff --git a/gmp/cxx/ismpznw.cc b/gmp/cxx/ismpznw.cc
new file mode 100644
index 0000000000..549742c2ad
--- /dev/null
+++ b/gmp/cxx/ismpznw.cc
@@ -0,0 +1,73 @@
+/* __gmpz_operator_in_nowhite -- C++-style input of mpz_t, no whitespace skip.
+
+Copyright 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <cctype>
+#include <iostream>
+#include <string>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+// For g++ libstdc++ parsing see num_get<chartype,initer>::_M_extract_int in
+// include/bits/locale_facets.tcc.
+
+istream &
+__gmpz_operator_in_nowhite (istream &i, mpz_ptr z, char c)
+{
+ int base;
+ string s;
+ bool ok = false, zero, showbase;
+
+ if (c == '-' || c == '+') // sign
+ {
+ if (c == '-') // mpz_set_str doesn't accept '+'
+ s = "-";
+ i.get(c);
+ }
+
+ base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
+ __gmp_istream_set_digits(s, i, c, ok, base); // read the number
+
+ if (i.good()) // last character read was non-numeric
+ i.putback(c);
+ else if (i.eof() && (ok || zero)) // stopped just before eof
+ i.clear(ios::eofbit);
+
+ if (ok)
+ ASSERT_NOCARRY (mpz_set_str (z, s.c_str(), base)); // extract the number
+ else if (zero)
+ mpz_set_ui(z, 0);
+ else
+ i.setstate(ios::failbit); // read failed
+
+ return i;
+}
diff --git a/gmp/cxx/limits.cc b/gmp/cxx/limits.cc
new file mode 100644
index 0000000000..3004e16cce
--- /dev/null
+++ b/gmp/cxx/limits.cc
@@ -0,0 +1,62 @@
+/* instantiation of numeric_limits specializations.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmpxx.h"
+
+namespace std {
+#define GMPXX_INSTANTIATE_LIMITS(T) \
+ const bool numeric_limits<T>::is_specialized; \
+ const int numeric_limits<T>::digits; \
+ const int numeric_limits<T>::digits10; \
+ const int numeric_limits<T>::max_digits10; \
+ const bool numeric_limits<T>::is_signed; \
+ const bool numeric_limits<T>::is_integer; \
+ const bool numeric_limits<T>::is_exact; \
+ const int numeric_limits<T>::radix; \
+ const int numeric_limits<T>::min_exponent; \
+ const int numeric_limits<T>::min_exponent10; \
+ const int numeric_limits<T>::max_exponent; \
+ const int numeric_limits<T>::max_exponent10; \
+ const bool numeric_limits<T>::has_infinity; \
+ const bool numeric_limits<T>::has_quiet_NaN; \
+ const bool numeric_limits<T>::has_signaling_NaN; \
+ const float_denorm_style numeric_limits<T>::has_denorm; \
+ const bool numeric_limits<T>::has_denorm_loss; \
+ const bool numeric_limits<T>::is_iec559; \
+ const bool numeric_limits<T>::is_bounded; \
+ const bool numeric_limits<T>::is_modulo; \
+ const bool numeric_limits<T>::traps; \
+ const bool numeric_limits<T>::tinyness_before; \
+ const float_round_style numeric_limits<T>::round_style
+
+ GMPXX_INSTANTIATE_LIMITS(mpz_class);
+ GMPXX_INSTANTIATE_LIMITS(mpq_class);
+ GMPXX_INSTANTIATE_LIMITS(mpf_class);
+}
diff --git a/gmp/cxx/osdoprnti.cc b/gmp/cxx/osdoprnti.cc
new file mode 100644
index 0000000000..4903c87d7f
--- /dev/null
+++ b/gmp/cxx/osdoprnti.cc
@@ -0,0 +1,68 @@
+/* __gmp_doprnt_integer_ios -- integer formatted output to an ostream.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <iostream>
+#include <stdarg.h> /* for va_list and hence doprnt_funs_t */
+#include <string.h> /* for strlen */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+/* The gmp_asprintf support routines never give an error, so
+ __gmp_doprnt_integer shouldn't fail and it's return can just be checked
+ with an ASSERT. */
+
+ostream&
+__gmp_doprnt_integer_ostream (ostream &o, struct doprnt_params_t *p,
+ char *s)
+{
+ struct gmp_asprintf_t d;
+ char *result;
+ int ret;
+
+ /* don't show leading zeros the way printf does */
+ p->prec = -1;
+
+ GMP_ASPRINTF_T_INIT (d, &result);
+ ret = __gmp_doprnt_integer (&__gmp_asprintf_funs_noformat, &d, p, s);
+ ASSERT (ret != -1);
+ __gmp_asprintf_final (&d);
+ (*__gmp_free_func) (s, strlen(s)+1);
+
+ gmp_allocated_string t (result);
+ return o.write (t.str, t.len);
+}
diff --git a/gmp/cxx/osfuns.cc b/gmp/cxx/osfuns.cc
new file mode 100644
index 0000000000..8df833e15c
--- /dev/null
+++ b/gmp/cxx/osfuns.cc
@@ -0,0 +1,124 @@
+/* Support for operator<< routines.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <iostream>
+#include <stdarg.h> /* for va_list and hence doprnt_funs_t */
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+/* Don't need "format" for operator<< routines, just "memory" and "reps".
+ Omitting gmp_asprintf_format lets us avoid dragging vsnprintf into the
+ link. __gmp_asprintf_final will be called directly and doesn't need to
+ be in the struct. */
+
+const struct doprnt_funs_t __gmp_asprintf_funs_noformat = {
+ NULL,
+ (doprnt_memory_t) __gmp_asprintf_memory,
+ (doprnt_reps_t) __gmp_asprintf_reps,
+ NULL
+};
+
+
+void
+__gmp_doprnt_params_from_ios (struct doprnt_params_t *p, ios &o)
+{
+ if ((o.flags() & ios::basefield) == ios::hex)
+ {
+ p->expfmt = "@%c%02d";
+ p->base = (o.flags() & ios::uppercase ? -16 : 16);
+ }
+ else
+ {
+ p->expfmt = (o.flags() & ios::uppercase ? "E%c%02d" : "e%c%02d");
+ if ((o.flags() & ios::basefield) == ios::oct)
+ p->base = 8;
+ else
+ p->base = 10;
+ }
+
+ /* "general" if none or more than one bit set */
+ if ((o.flags() & ios::floatfield) == ios::fixed)
+ p->conv = DOPRNT_CONV_FIXED;
+ else if ((o.flags() & ios::floatfield) == ios::scientific)
+ p->conv = DOPRNT_CONV_SCIENTIFIC;
+ else
+ p->conv = DOPRNT_CONV_GENERAL;
+
+ p->exptimes4 = 0;
+
+ p->fill = o.fill();
+
+ /* "right" if more than one bit set */
+ if ((o.flags() & ios::adjustfield) == ios::left)
+ p->justify = DOPRNT_JUSTIFY_LEFT;
+ else if ((o.flags() & ios::adjustfield) == ios::internal)
+ p->justify = DOPRNT_JUSTIFY_INTERNAL;
+ else
+ p->justify = DOPRNT_JUSTIFY_RIGHT;
+
+ /* ios::fixed allows prec==0, others take 0 as the default 6.
+ Don't allow negatives (they do bad things to __gmp_doprnt_float_cxx). */
+ p->prec = MAX (0, o.precision());
+ if (p->prec == 0 && p->conv != DOPRNT_CONV_FIXED)
+ p->prec = 6;
+
+ /* for hex showbase is always, for octal only non-zero */
+ if (o.flags() & ios::showbase)
+ p->showbase = ((o.flags() & ios::basefield) == ios::hex
+ ? DOPRNT_SHOWBASE_YES : DOPRNT_SHOWBASE_NONZERO);
+ else
+ p->showbase = DOPRNT_SHOWBASE_NO;
+
+ p->showpoint = ((o.flags() & ios::showpoint) != 0);
+
+ /* in fixed and scientific always show trailing zeros, in general format
+ show them if showpoint is set (or so it seems) */
+ if ((o.flags() & ios::floatfield) == ios::fixed
+ || (o.flags() & ios::floatfield) == ios::scientific)
+ p->showtrailing = 1;
+ else
+ p->showtrailing = p->showpoint;
+
+ p->sign = (o.flags() & ios::showpos ? '+' : '\0');
+
+ p->width = o.width();
+
+ /* reset on each output */
+ o.width (0);
+}
diff --git a/gmp/cxx/osmpf.cc b/gmp/cxx/osmpf.cc
new file mode 100644
index 0000000000..c6a71d2520
--- /dev/null
+++ b/gmp/cxx/osmpf.cc
@@ -0,0 +1,71 @@
+/* operator<< -- mpf formatted output to an ostream.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <clocale>
+#include <iostream>
+#include <stdarg.h> /* for va_list and hence doprnt_funs_t */
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+/* The gmp_asprintf support routines never give an error, so
+ __gmp_doprnt_mpf shouldn't fail and it's return can just be checked with
+ an ASSERT. */
+
+ostream&
+operator<< (ostream &o, mpf_srcptr f)
+{
+ struct doprnt_params_t param;
+ struct gmp_asprintf_t d;
+ char *result;
+ int ret;
+
+ __gmp_doprnt_params_from_ios (&param, o);
+
+#if HAVE_STD__LOCALE
+ char point[2];
+ point[0] = use_facet< numpunct<char> >(o.getloc()).decimal_point();
+ point[1] = '\0';
+#else
+ const char *point = GMP_DECIMAL_POINT;
+#endif
+
+ GMP_ASPRINTF_T_INIT (d, &result);
+ ret = __gmp_doprnt_mpf (&__gmp_asprintf_funs_noformat, &d, &param, point, f);
+ ASSERT (ret != -1);
+ __gmp_asprintf_final (&d);
+
+ gmp_allocated_string t (result);
+ return o.write (t.str, t.len);
+}
diff --git a/gmp/cxx/osmpq.cc b/gmp/cxx/osmpq.cc
new file mode 100644
index 0000000000..f95f39a648
--- /dev/null
+++ b/gmp/cxx/osmpq.cc
@@ -0,0 +1,48 @@
+/* operator<< -- mpq formatted output to an ostream.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <iostream>
+#include <stdarg.h> /* for va_list and hence doprnt_funs_t */
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+ostream&
+operator<< (ostream &o, mpq_srcptr q)
+{
+ struct doprnt_params_t param;
+ __gmp_doprnt_params_from_ios (&param, o);
+ return __gmp_doprnt_integer_ostream (o, &param,
+ mpq_get_str (NULL, param.base, q));
+}
diff --git a/gmp/cxx/osmpz.cc b/gmp/cxx/osmpz.cc
new file mode 100644
index 0000000000..ac1aefff40
--- /dev/null
+++ b/gmp/cxx/osmpz.cc
@@ -0,0 +1,48 @@
+/* operator<< -- mpz formatted output to an ostream.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <iostream>
+#include <stdarg.h> /* for va_list and hence doprnt_funs_t */
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+using namespace std;
+
+
+ostream&
+operator<< (ostream &o, mpz_srcptr z)
+{
+ struct doprnt_params_t param;
+ __gmp_doprnt_params_from_ios (&param, o);
+ return __gmp_doprnt_integer_ostream (o, &param,
+ mpz_get_str (NULL, param.base, z));
+}
diff --git a/gmp/demos/Makefile.am b/gmp/demos/Makefile.am
new file mode 100644
index 0000000000..0a7c2a4732
--- /dev/null
+++ b/gmp/demos/Makefile.am
@@ -0,0 +1,50 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2000-2002, 2012 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+SUBDIRS = calc expr
+EXTRA_DIST = perl primes.h
+
+INCLUDES = -I$(top_srcdir)
+LDADD = $(top_builddir)/libgmp.la
+
+qcn_LDADD = $(LDADD) $(LIBM)
+primes_LDADD = $(LDADD) $(LIBM)
+
+# None of these programs are built by default, but "make <whatever>" will
+# build them once libgmp.la is built.
+#
+EXTRA_PROGRAMS = factorize isprime pexpr primes qcn
+
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+allprogs: $(EXTRA_PROGRAMS)
+ cd calc; $(MAKE) $(AM_MAKEFLAGS) allprogs
+ cd expr; $(MAKE) $(AM_MAKEFLAGS) allprogs
diff --git a/gmp/demos/Makefile.in b/gmp/demos/Makefile.in
new file mode 100644
index 0000000000..129c786f1c
--- /dev/null
+++ b/gmp/demos/Makefile.in
@@ -0,0 +1,731 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2000-2002, 2012 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+EXTRA_PROGRAMS = factorize$(EXEEXT) isprime$(EXEEXT) pexpr$(EXEEXT) \
+ primes$(EXEEXT) qcn$(EXEEXT)
+subdir = demos
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/pexpr-config-h.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = pexpr-config.h
+CONFIG_CLEAN_VPATH_FILES =
+factorize_SOURCES = factorize.c
+factorize_OBJECTS = factorize.$(OBJEXT)
+factorize_LDADD = $(LDADD)
+factorize_DEPENDENCIES = $(top_builddir)/libgmp.la
+isprime_SOURCES = isprime.c
+isprime_OBJECTS = isprime.$(OBJEXT)
+isprime_LDADD = $(LDADD)
+isprime_DEPENDENCIES = $(top_builddir)/libgmp.la
+pexpr_SOURCES = pexpr.c
+pexpr_OBJECTS = pexpr.$(OBJEXT)
+pexpr_LDADD = $(LDADD)
+pexpr_DEPENDENCIES = $(top_builddir)/libgmp.la
+primes_SOURCES = primes.c
+primes_OBJECTS = primes.$(OBJEXT)
+am__DEPENDENCIES_1 =
+primes_DEPENDENCIES = $(LDADD) $(am__DEPENDENCIES_1)
+qcn_SOURCES = qcn.c
+qcn_OBJECTS = qcn.$(OBJEXT)
+qcn_DEPENDENCIES = $(LDADD) $(am__DEPENDENCIES_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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = factorize.c isprime.c pexpr.c primes.c qcn.c
+DIST_SOURCES = factorize.c isprime.c pexpr.c primes.c qcn.c
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+SUBDIRS = calc expr
+EXTRA_DIST = perl primes.h
+INCLUDES = -I$(top_srcdir)
+LDADD = $(top_builddir)/libgmp.la
+qcn_LDADD = $(LDADD) $(LIBM)
+primes_LDADD = $(LDADD) $(LIBM)
+CLEANFILES = $(EXTRA_PROGRAMS)
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 demos/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps demos/Makefile
+.PRECIOUS: 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):
+pexpr-config.h: $(top_builddir)/config.status $(srcdir)/pexpr-config-h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+factorize$(EXEEXT): $(factorize_OBJECTS) $(factorize_DEPENDENCIES) $(EXTRA_factorize_DEPENDENCIES)
+ @rm -f factorize$(EXEEXT)
+ $(LINK) $(factorize_OBJECTS) $(factorize_LDADD) $(LIBS)
+isprime$(EXEEXT): $(isprime_OBJECTS) $(isprime_DEPENDENCIES) $(EXTRA_isprime_DEPENDENCIES)
+ @rm -f isprime$(EXEEXT)
+ $(LINK) $(isprime_OBJECTS) $(isprime_LDADD) $(LIBS)
+pexpr$(EXEEXT): $(pexpr_OBJECTS) $(pexpr_DEPENDENCIES) $(EXTRA_pexpr_DEPENDENCIES)
+ @rm -f pexpr$(EXEEXT)
+ $(LINK) $(pexpr_OBJECTS) $(pexpr_LDADD) $(LIBS)
+primes$(EXEEXT): $(primes_OBJECTS) $(primes_DEPENDENCIES) $(EXTRA_primes_DEPENDENCIES)
+ @rm -f primes$(EXEEXT)
+ $(LINK) $(primes_OBJECTS) $(primes_LDADD) $(LIBS)
+qcn$(EXEEXT): $(qcn_OBJECTS) $(qcn_DEPENDENCIES) $(EXTRA_qcn_DEPENDENCIES)
+ @rm -f qcn$(EXEEXT)
+ $(LINK) $(qcn_OBJECTS) $(qcn_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ ctags ctags-recursive 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 installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am
+
+
+allprogs: $(EXTRA_PROGRAMS)
+ cd calc; $(MAKE) $(AM_MAKEFLAGS) allprogs
+ cd expr; $(MAKE) $(AM_MAKEFLAGS) allprogs
+
+# 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/gmp/demos/calc/Makefile.am b/gmp/demos/calc/Makefile.am
new file mode 100644
index 0000000000..3a461ebc59
--- /dev/null
+++ b/gmp/demos/calc/Makefile.am
@@ -0,0 +1,47 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2000-2004 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -I$(top_srcdir)
+
+# $(LEXLIB) is not actually needed for flex (which means the distributed
+# calclex.c), but it's included here for the benefit of anyone rebuilding
+# with some other lex.
+#
+LDADD = $(top_builddir)/libgmp.la $(LIBREADLINE) $(LIBCURSES) $(LEXLIB)
+
+EXTRA_PROGRAMS = calc
+AM_YFLAGS = -d
+calc_SOURCES = calc.y calclex.l calcread.c calc-common.h
+BUILT_SOURCES = calc.h
+
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+allprogs: $(EXTRA_PROGRAMS)
diff --git a/gmp/demos/calc/Makefile.in b/gmp/demos/calc/Makefile.in
new file mode 100644
index 0000000000..6606f87bc8
--- /dev/null
+++ b/gmp/demos/calc/Makefile.in
@@ -0,0 +1,583 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2000-2004 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+EXTRA_PROGRAMS = calc$(EXEEXT)
+subdir = demos/calc
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/calc-config-h.in calc.c calc.h calclex.c
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = calc-config.h
+CONFIG_CLEAN_VPATH_FILES =
+am_calc_OBJECTS = calc.$(OBJEXT) calclex.$(OBJEXT) calcread.$(OBJEXT)
+calc_OBJECTS = $(am_calc_OBJECTS)
+calc_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+calc_DEPENDENCIES = $(top_builddir)/libgmp.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ ||
+LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS)
+LTLEXCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS)
+YLWRAP = $(top_srcdir)/ylwrap
+@MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ ||
+YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS)
+LTYACCCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS)
+SOURCES = $(calc_SOURCES)
+DIST_SOURCES = $(calc_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir)
+
+# $(LEXLIB) is not actually needed for flex (which means the distributed
+# calclex.c), but it's included here for the benefit of anyone rebuilding
+# with some other lex.
+#
+LDADD = $(top_builddir)/libgmp.la $(LIBREADLINE) $(LIBCURSES) $(LEXLIB)
+AM_YFLAGS = -d
+calc_SOURCES = calc.y calclex.l calcread.c calc-common.h
+BUILT_SOURCES = calc.h
+CLEANFILES = $(EXTRA_PROGRAMS)
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .l .lo .o .obj .y
+$(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 demos/calc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps demos/calc/Makefile
+.PRECIOUS: 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):
+calc-config.h: $(top_builddir)/config.status $(srcdir)/calc-config-h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+calc.h: calc.c
+ @if test ! -f $@; then rm -f calc.c; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) calc.c; else :; fi
+calc$(EXEEXT): $(calc_OBJECTS) $(calc_DEPENDENCIES) $(EXTRA_calc_DEPENDENCIES)
+ @rm -f calc$(EXEEXT)
+ $(LINK) $(calc_OBJECTS) $(calc_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+.l.c:
+ $(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE)
+
+.y.c:
+ $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile
+installdirs:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) 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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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."
+ -rm -f calc.c
+ -rm -f calc.h
+ -rm -f calclex.c
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: 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: all check install install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool ctags 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 \
+ tags uninstall uninstall-am
+
+
+allprogs: $(EXTRA_PROGRAMS)
+
+# 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/gmp/demos/calc/README b/gmp/demos/calc/README
new file mode 100644
index 0000000000..660394ecbc
--- /dev/null
+++ b/gmp/demos/calc/README
@@ -0,0 +1,65 @@
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/.
+
+
+
+
+ DEMONSTRATION CALCULATOR PROGRAM
+
+
+This is a simple program, meant only to show one way to use GMP with yacc
+and lex to make a calculator. Usage and comments on the implementation can
+be found in calc.y.
+
+Within a GMP build tree, the generated Makefile can be used to build the
+program,
+
+ make calc
+
+(or on a DOS system, "make calc.exe").
+
+Elsewhere, once GMP has been installed, the program can be compiled with for
+instance
+
+ gcc calc.c calclex.c -lgmp -o calc
+
+Or if GNU readline is used then
+
+ gcc calc.c calclex.c calcread.c -lgmp -lreadline -o calc
+
+(again, on a DOS system "-o calc.exe").
+
+Readline support can be enabled or disabled in calc-config.h. That file is
+created by the GMP ./configure based on the --with-readline option. The
+default is --with-readline=detect, which means to use readline if available.
+"yes" can be used to force it to be used, or "no" to not use it.
+
+The supplied calc.c was generated by GNU bison, but a standard yacc should
+work too.
+
+The supplied calclex.c was generated by GNU flex, but a standard lex should
+work too. The readline support may or may not work with a standard lex (see
+comments with input() in calcread.c). Note also that a standard lex will
+require its library "-ll" on the compile command line. "./configure" sets
+this up in the GMP build tree Makefile.
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/demos/calc/calc-common.h b/gmp/demos/calc/calc-common.h
new file mode 100644
index 0000000000..7a9187826f
--- /dev/null
+++ b/gmp/demos/calc/calc-common.h
@@ -0,0 +1,35 @@
+/* Prototypes etc for calc program.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+#include <stddef.h> /* for size_t */
+#ifndef NO_CALC_H
+#include "calc.h"
+#endif
+#include "calc-config.h"
+
+struct calc_keywords_t {
+ char *name;
+ int value;
+};
+
+extern int calc_option_readline;
+extern int calc_more_input;
+extern const struct calc_keywords_t calc_keywords[];
+
+int calc_input (char *buf, size_t max_size);
+void calc_init_readline (void);
diff --git a/gmp/demos/calc/calc-config-h.in b/gmp/demos/calc/calc-config-h.in
new file mode 100644
index 0000000000..42cdd440c2
--- /dev/null
+++ b/gmp/demos/calc/calc-config-h.in
@@ -0,0 +1,21 @@
+/* Templates for calc program configuration. -*- mode:c -*-
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* Define if GNU readline should be used. */
+#define WITH_READLINE @WITH_READLINE_01@
diff --git a/gmp/demos/calc/calc.c b/gmp/demos/calc/calc.c
new file mode 100644
index 0000000000..a306d1a563
--- /dev/null
+++ b/gmp/demos/calc/calc.c
@@ -0,0 +1,2254 @@
+/* A Bison parser, made by GNU Bison 2.7.12-4996. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.7.12-4996"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+
+
+/* Copy the first part of user declarations. */
+/* Line 371 of yacc.c */
+#line 1 "calc.y"
+
+/* A simple integer desk calculator using yacc and gmp.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* This is a simple program, meant only to show one way to use GMP for this
+ sort of thing. There's few features, and error checking is minimal.
+ Standard input is read, calc_help() below shows the inputs accepted.
+
+ Expressions are evaluated as they're read. If user defined functions
+ were wanted it'd be necessary to build a parse tree like pexpr.c does, or
+ a list of operations for a stack based evaluator. That would also make
+ it possible to detect and optimize evaluations "mod m" like pexpr.c does.
+
+ A stack is used for intermediate values in the expression evaluation,
+ separate from the yacc parser stack. This is simple, makes error
+ recovery easy, minimizes the junk around mpz calls in the rules, and
+ saves initializing or clearing "mpz_t"s during a calculation. A
+ disadvantage though is that variables must be copied to the stack to be
+ worked on. A more sophisticated calculator or language system might be
+ able to avoid that when executing a compiled or semi-compiled form.
+
+ Avoiding repeated initializing and clearing of "mpz_t"s is important. In
+ this program the time spent parsing is obviously much greater than any
+ possible saving from this, but a proper calculator or language should
+ take some trouble over it. Don't be surprised if an init/clear takes 3
+ or more times as long as a 10 limb addition, depending on the system (see
+ the mpz_init_realloc_clear example in tune/README). */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#define NO_CALC_H /* because it conflicts with normal calc.c stuff */
+#include "calc-common.h"
+
+
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+
+
+void
+calc_help (void)
+{
+ printf ("Examples:\n");
+ printf (" 2+3*4 expressions are evaluated\n");
+ printf (" x=5^6 variables a to z can be set and used\n");
+ printf ("Operators:\n");
+ printf (" + - * arithmetic\n");
+ printf (" / %% division and remainder (rounding towards negative infinity)\n");
+ printf (" ^ exponentiation\n");
+ printf (" ! factorial\n");
+ printf (" << >> left and right shifts\n");
+ printf (" <= >= > \\ comparisons, giving 1 if true, 0 if false\n");
+ printf (" == != < /\n");
+ printf (" && || logical and/or, giving 1 if true, 0 if false\n");
+ printf ("Functions:\n");
+ printf (" abs(n) absolute value\n");
+ printf (" bin(n,m) binomial coefficient\n");
+ printf (" fib(n) fibonacci number\n");
+ printf (" gcd(a,b,..) greatest common divisor\n");
+ printf (" kron(a,b) kronecker symbol\n");
+ printf (" lcm(a,b,..) least common multiple\n");
+ printf (" lucnum(n) lucas number\n");
+ printf (" nextprime(n) next prime after n\n");
+ printf (" powm(b,e,m) modulo powering, b^e%%m\n");
+ printf (" root(n,r) r-th root\n");
+ printf (" sqrt(n) square root\n");
+ printf ("Other:\n");
+ printf (" hex \\ set hex or decimal for input and output\n");
+ printf (" decimal / (\"0x\" can be used for hex too)\n");
+ printf (" quit exit program (EOF works too)\n");
+ printf (" ; statements are separated with a ; or newline\n");
+ printf (" \\ continue expressions with \\ before newline\n");
+ printf (" # xxx comments are # though to newline\n");
+ printf ("Hex numbers must be entered in upper case, to distinguish them from the\n");
+ printf ("variables a to f (like in bc).\n");
+}
+
+
+int ibase = 0;
+int obase = 10;
+
+
+/* The stack is a fixed size, which means there's a limit on the nesting
+ allowed in expressions. A more sophisticated program could let it grow
+ dynamically. */
+
+mpz_t stack[100];
+mpz_ptr sp = stack[0];
+
+#define CHECK_OVERFLOW() \
+ if (sp >= stack[numberof(stack)]) /* FIXME */ \
+ { \
+ fprintf (stderr, \
+ "Value stack overflow, too much nesting in expression\n"); \
+ YYERROR; \
+ }
+
+#define CHECK_EMPTY() \
+ if (sp != stack[0]) \
+ { \
+ fprintf (stderr, "Oops, expected the value stack to be empty\n"); \
+ sp = stack[0]; \
+ }
+
+
+mpz_t variable[26];
+
+#define CHECK_VARIABLE(var) \
+ if ((var) < 0 || (var) >= numberof (variable)) \
+ { \
+ fprintf (stderr, "Oops, bad variable somehow: %d\n", var); \
+ YYERROR; \
+ }
+
+
+#define CHECK_UI(name,z) \
+ if (! mpz_fits_ulong_p (z)) \
+ { \
+ fprintf (stderr, "%s too big\n", name); \
+ YYERROR; \
+ }
+
+
+/* Line 371 of yacc.c */
+#line 209 "calc.c"
+
+# ifndef YY_NULL
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULL nullptr
+# else
+# define YY_NULL 0
+# endif
+# endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* In a future release of Bison, this section will be replaced
+ by #include "y.tab.h". */
+#ifndef YY_YY_Y_TAB_H_INCLUDED
+# define YY_YY_Y_TAB_H_INCLUDED
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ EOS = 258,
+ BAD = 259,
+ HELP = 260,
+ HEX = 261,
+ DECIMAL = 262,
+ QUIT = 263,
+ ABS = 264,
+ BIN = 265,
+ FIB = 266,
+ GCD = 267,
+ KRON = 268,
+ LCM = 269,
+ LUCNUM = 270,
+ NEXTPRIME = 271,
+ POWM = 272,
+ ROOT = 273,
+ SQRT = 274,
+ NUMBER = 275,
+ VARIABLE = 276,
+ LOR = 277,
+ LAND = 278,
+ GE = 279,
+ LE = 280,
+ NE = 281,
+ EQ = 282,
+ RSHIFT = 283,
+ LSHIFT = 284,
+ UMINUS = 285
+ };
+#endif
+/* Tokens. */
+#define EOS 258
+#define BAD 259
+#define HELP 260
+#define HEX 261
+#define DECIMAL 262
+#define QUIT 263
+#define ABS 264
+#define BIN 265
+#define FIB 266
+#define GCD 267
+#define KRON 268
+#define LCM 269
+#define LUCNUM 270
+#define NEXTPRIME 271
+#define POWM 272
+#define ROOT 273
+#define SQRT 274
+#define NUMBER 275
+#define VARIABLE 276
+#define LOR 277
+#define LAND 278
+#define GE 279
+#define LE 280
+#define NE 281
+#define EQ 282
+#define RSHIFT 283
+#define LSHIFT 284
+#define UMINUS 285
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+/* Line 387 of yacc.c */
+#line 142 "calc.y"
+
+ char *str;
+ int var;
+
+
+/* Line 387 of yacc.c */
+#line 318 "calc.c"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+extern YYSTYPE yylval;
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY_YY_Y_TAB_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+
+/* Line 390 of yacc.c */
+#line 346 "calc.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if (! defined __GNUC__ || __GNUC__ < 2 \
+ || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
+# define __attribute__(Spec) /* empty */
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(N) (N)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 41
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 552
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 44
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 7
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 49
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 118
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 285
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 39, 2, 2, 2, 36, 2, 2,
+ 41, 42, 34, 32, 43, 33, 2, 35, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 24, 40, 25, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 38, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 26,
+ 27, 28, 29, 30, 31, 37
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint8 yyprhs[] =
+{
+ 0, 0, 3, 5, 8, 11, 15, 18, 19, 21,
+ 25, 27, 29, 31, 33, 37, 41, 45, 49, 53,
+ 57, 61, 65, 69, 72, 75, 79, 83, 87, 91,
+ 95, 99, 103, 107, 112, 119, 124, 129, 136, 141,
+ 146, 151, 160, 167, 172, 174, 176, 178, 182, 184
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int8 yyrhs[] =
+{
+ 45, 0, -1, 47, -1, 46, 47, -1, 47, 3,
+ -1, 46, 47, 3, -1, 1, 3, -1, -1, 48,
+ -1, 21, 40, 48, -1, 5, -1, 6, -1, 7,
+ -1, 8, -1, 41, 48, 42, -1, 48, 32, 48,
+ -1, 48, 33, 48, -1, 48, 34, 48, -1, 48,
+ 35, 48, -1, 48, 36, 48, -1, 48, 38, 48,
+ -1, 48, 31, 48, -1, 48, 30, 48, -1, 48,
+ 39, -1, 33, 48, -1, 48, 24, 48, -1, 48,
+ 27, 48, -1, 48, 29, 48, -1, 48, 28, 48,
+ -1, 48, 26, 48, -1, 48, 25, 48, -1, 48,
+ 23, 48, -1, 48, 22, 48, -1, 9, 41, 48,
+ 42, -1, 10, 41, 48, 43, 48, 42, -1, 11,
+ 41, 48, 42, -1, 12, 41, 49, 42, -1, 13,
+ 41, 48, 43, 48, 42, -1, 14, 41, 50, 42,
+ -1, 15, 41, 48, 42, -1, 16, 41, 48, 42,
+ -1, 17, 41, 48, 43, 48, 43, 48, 42, -1,
+ 18, 41, 48, 43, 48, 42, -1, 19, 41, 48,
+ 42, -1, 21, -1, 20, -1, 48, -1, 49, 43,
+ 48, -1, 48, -1, 50, 43, 48, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 167, 167, 168, 171, 172, 173, 175, 177, 182,
+ 188, 189, 190, 191, 197, 198, 199, 200, 201, 202,
+ 203, 205, 207, 209, 211, 213, 214, 215, 216, 217,
+ 218, 220, 221, 223, 224, 226, 228, 229, 231, 232,
+ 234, 235, 236, 238, 240, 246, 257, 258, 261, 262
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 0
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "EOS", "BAD", "HELP", "HEX", "DECIMAL",
+ "QUIT", "ABS", "BIN", "FIB", "GCD", "KRON", "LCM", "LUCNUM", "NEXTPRIME",
+ "POWM", "ROOT", "SQRT", "NUMBER", "VARIABLE", "LOR", "LAND", "'<'",
+ "'>'", "GE", "LE", "NE", "EQ", "RSHIFT", "LSHIFT", "'+'", "'-'", "'*'",
+ "'/'", "'%'", "UMINUS", "'^'", "'!'", "'='", "'('", "')'", "','",
+ "$accept", "top", "statements", "statement", "e", "gcdlist", "lcmlist", YY_NULL
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 60, 62, 279, 280, 281, 282,
+ 283, 284, 43, 45, 42, 47, 37, 285, 94, 33,
+ 61, 40, 41, 44
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 44, 45, 45, 46, 46, 46, 47, 47, 47,
+ 47, 47, 47, 47, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 49, 49, 50, 50
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 2, 2, 3, 2, 0, 1, 3,
+ 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 2, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 4, 6, 4, 4, 6, 4, 4,
+ 4, 8, 6, 4, 1, 1, 1, 3, 1, 3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 0, 0, 10, 11, 12, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 45, 44, 0,
+ 0, 0, 7, 2, 8, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 44, 24,
+ 0, 1, 3, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 23, 0, 0, 0, 46, 0, 0, 48, 0, 0,
+ 0, 0, 0, 0, 9, 14, 5, 32, 31, 25,
+ 30, 29, 26, 28, 27, 22, 21, 15, 16, 17,
+ 18, 19, 20, 33, 0, 35, 36, 0, 0, 38,
+ 0, 39, 40, 0, 0, 43, 0, 47, 0, 49,
+ 0, 0, 34, 37, 0, 42, 0, 41
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
+{
+ -1, 21, 22, 23, 24, 65, 68
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -39
+static const yytype_int16 yypact[] =
+{
+ 41, 3, -39, -39, -39, -39, 2, 4, 27, 32,
+ 35, 36, 39, 42, 45, 46, 47, -39, -18, 124,
+ 124, 89, 91, 87, 464, -39, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, -39, -36,
+ 254, -39, 88, -39, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ -39, 275, 144, 296, 464, -38, 166, 464, 29, 317,
+ 338, 188, 210, 359, 464, -39, -39, 481, 497, 513,
+ 513, 513, 513, 513, 513, 31, 31, -15, -15, -36,
+ -36, -36, -36, -39, 124, -39, -39, 124, 124, -39,
+ 124, -39, -39, 124, 124, -39, 380, 464, 401, 464,
+ 232, 422, -39, -39, 124, -39, 443, -39
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -39, -39, -39, 70, -19, -39, -39
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -8
+static const yytype_int8 yytable[] =
+{
+ 39, 40, 59, 60, 96, 97, 25, 61, 62, 63,
+ 64, 66, 67, 69, 70, 71, 72, 73, 74, 56,
+ 57, 58, 37, 59, 60, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, -7, 1, 26, -7, 27, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 54, 55, 56, 57, 58, 28, 59,
+ 60, 99, 100, 29, 19, 106, 30, 31, 107, 108,
+ 32, 109, 20, 33, 110, 111, 34, 35, 36, 41,
+ 43, 76, 42, 0, 0, 116, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 19, 0, 0, 0, 0, 0,
+ 0, 0, 20, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 38, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 19, 0, 0,
+ 0, 0, 0, 0, 0, 20, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 0, 59, 60, 0, 0, 0, 94, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 0, 59, 60, 0, 0, 0, 98,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 0, 59, 60, 0, 0,
+ 0, 103, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 0, 59, 60,
+ 0, 0, 0, 104, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 0,
+ 59, 60, 0, 0, 0, 114, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 0, 59, 60, 0, 0, 75, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 0, 59, 60, 0, 0, 93, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 0, 59, 60, 0, 0, 95, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 0, 59, 60, 0, 0, 101,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 0, 59, 60, 0, 0,
+ 102, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 0, 59, 60, 0,
+ 0, 105, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 0, 59, 60,
+ 0, 0, 112, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 0, 59,
+ 60, 0, 0, 113, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 0,
+ 59, 60, 0, 0, 115, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 0, 59, 60, 0, 0, 117, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 0, 59, 60, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 0, 59,
+ 60, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 0, 59, 60, -8, -8, -8,
+ -8, -8, -8, 52, 53, 54, 55, 56, 57, 58,
+ 0, 59, 60
+};
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-39)))
+
+#define yytable_value_is_error(Yytable_value) \
+ (!!((Yytable_value) == (-8)))
+
+static const yytype_int8 yycheck[] =
+{
+ 19, 20, 38, 39, 42, 43, 3, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 34,
+ 35, 36, 40, 38, 39, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 0, 1, 41, 3, 41, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 32, 33, 34, 35, 36, 41, 38,
+ 39, 42, 43, 41, 33, 94, 41, 41, 97, 98,
+ 41, 100, 41, 41, 103, 104, 41, 41, 41, 0,
+ 3, 3, 22, -1, -1, 114, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 33, -1, -1, -1, -1, -1,
+ -1, -1, 41, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 33, -1, -1,
+ -1, -1, -1, -1, -1, 41, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, -1, 38, 39, -1, -1, -1, 43, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, -1, 38, 39, -1, -1, -1, 43,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, -1, 38, 39, -1, -1,
+ -1, 43, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, -1, 38, 39,
+ -1, -1, -1, 43, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, -1,
+ 38, 39, -1, -1, -1, 43, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, -1, 38, 39, -1, -1, 42, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, -1, 38, 39, -1, -1, 42, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, -1, 38, 39, -1, -1, 42, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, -1, 38, 39, -1, -1, 42,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, -1, 38, 39, -1, -1,
+ 42, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, -1, 38, 39, -1,
+ -1, 42, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, -1, 38, 39,
+ -1, -1, 42, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, -1, 38,
+ 39, -1, -1, 42, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, -1,
+ 38, 39, -1, -1, 42, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ -1, 38, 39, -1, -1, 42, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, -1, 38, 39, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, -1, 38,
+ 39, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, -1, 38, 39, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ -1, 38, 39
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 1, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 33,
+ 41, 45, 46, 47, 48, 3, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 40, 21, 48,
+ 48, 0, 47, 3, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 38,
+ 39, 48, 48, 48, 48, 49, 48, 48, 50, 48,
+ 48, 48, 48, 48, 48, 42, 3, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 42, 43, 42, 42, 43, 43, 42,
+ 43, 42, 42, 43, 43, 42, 48, 48, 48, 48,
+ 48, 48, 42, 42, 43, 42, 48, 42
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. However,
+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated
+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+ discussed. */
+
+#define YYFAIL goto yyerrlab
+#if defined YYFAIL
+ /* This is here to suppress warnings from the GCC cpp's
+ -Wunused-macros. Normally we don't worry about that warning, but
+ some users do, and we want to make it easy for users to remove
+ YYFAIL uses, which will produce warnings from Bison 2.5. */
+#endif
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+ YYSTYPE *yyvsp;
+ int yyrule;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULL;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - Assume YYFAIL is not used. It's too flawed to consider. See
+ <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+ for details. YYERROR is fine as it does not invoke this
+ function.
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ YYUSE (yyvaluep);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YYUSE (yytype);
+}
+
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+
+ Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 6:
+/* Line 1787 of yacc.c */
+#line 173 "calc.y"
+ { sp = stack[0]; yyerrok; }
+ break;
+
+ case 8:
+/* Line 1787 of yacc.c */
+#line 177 "calc.y"
+ {
+ mpz_out_str (stdout, obase, sp); putchar ('\n');
+ sp--;
+ CHECK_EMPTY ();
+ }
+ break;
+
+ case 9:
+/* Line 1787 of yacc.c */
+#line 182 "calc.y"
+ {
+ CHECK_VARIABLE ((yyvsp[(1) - (3)].var));
+ mpz_swap (variable[(yyvsp[(1) - (3)].var)], sp);
+ sp--;
+ CHECK_EMPTY ();
+ }
+ break;
+
+ case 10:
+/* Line 1787 of yacc.c */
+#line 188 "calc.y"
+ { calc_help (); }
+ break;
+
+ case 11:
+/* Line 1787 of yacc.c */
+#line 189 "calc.y"
+ { ibase = 16; obase = -16; }
+ break;
+
+ case 12:
+/* Line 1787 of yacc.c */
+#line 190 "calc.y"
+ { ibase = 0; obase = 10; }
+ break;
+
+ case 13:
+/* Line 1787 of yacc.c */
+#line 191 "calc.y"
+ { exit (0); }
+ break;
+
+ case 15:
+/* Line 1787 of yacc.c */
+#line 198 "calc.y"
+ { sp--; mpz_add (sp, sp, sp+1); }
+ break;
+
+ case 16:
+/* Line 1787 of yacc.c */
+#line 199 "calc.y"
+ { sp--; mpz_sub (sp, sp, sp+1); }
+ break;
+
+ case 17:
+/* Line 1787 of yacc.c */
+#line 200 "calc.y"
+ { sp--; mpz_mul (sp, sp, sp+1); }
+ break;
+
+ case 18:
+/* Line 1787 of yacc.c */
+#line 201 "calc.y"
+ { sp--; mpz_fdiv_q (sp, sp, sp+1); }
+ break;
+
+ case 19:
+/* Line 1787 of yacc.c */
+#line 202 "calc.y"
+ { sp--; mpz_fdiv_r (sp, sp, sp+1); }
+ break;
+
+ case 20:
+/* Line 1787 of yacc.c */
+#line 203 "calc.y"
+ { CHECK_UI ("Exponent", sp);
+ sp--; mpz_pow_ui (sp, sp, mpz_get_ui (sp+1)); }
+ break;
+
+ case 21:
+/* Line 1787 of yacc.c */
+#line 205 "calc.y"
+ { CHECK_UI ("Shift count", sp);
+ sp--; mpz_mul_2exp (sp, sp, mpz_get_ui (sp+1)); }
+ break;
+
+ case 22:
+/* Line 1787 of yacc.c */
+#line 207 "calc.y"
+ { CHECK_UI ("Shift count", sp);
+ sp--; mpz_fdiv_q_2exp (sp, sp, mpz_get_ui (sp+1)); }
+ break;
+
+ case 23:
+/* Line 1787 of yacc.c */
+#line 209 "calc.y"
+ { CHECK_UI ("Factorial", sp);
+ mpz_fac_ui (sp, mpz_get_ui (sp)); }
+ break;
+
+ case 24:
+/* Line 1787 of yacc.c */
+#line 211 "calc.y"
+ { mpz_neg (sp, sp); }
+ break;
+
+ case 25:
+/* Line 1787 of yacc.c */
+#line 213 "calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) < 0); }
+ break;
+
+ case 26:
+/* Line 1787 of yacc.c */
+#line 214 "calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) <= 0); }
+ break;
+
+ case 27:
+/* Line 1787 of yacc.c */
+#line 215 "calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) == 0); }
+ break;
+
+ case 28:
+/* Line 1787 of yacc.c */
+#line 216 "calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) != 0); }
+ break;
+
+ case 29:
+/* Line 1787 of yacc.c */
+#line 217 "calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) >= 0); }
+ break;
+
+ case 30:
+/* Line 1787 of yacc.c */
+#line 218 "calc.y"
+ { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) > 0); }
+ break;
+
+ case 31:
+/* Line 1787 of yacc.c */
+#line 220 "calc.y"
+ { sp--; mpz_set_ui (sp, mpz_sgn (sp) && mpz_sgn (sp+1)); }
+ break;
+
+ case 32:
+/* Line 1787 of yacc.c */
+#line 221 "calc.y"
+ { sp--; mpz_set_ui (sp, mpz_sgn (sp) || mpz_sgn (sp+1)); }
+ break;
+
+ case 33:
+/* Line 1787 of yacc.c */
+#line 223 "calc.y"
+ { mpz_abs (sp, sp); }
+ break;
+
+ case 34:
+/* Line 1787 of yacc.c */
+#line 224 "calc.y"
+ { sp--; CHECK_UI ("Binomial base", sp+1);
+ mpz_bin_ui (sp, sp, mpz_get_ui (sp+1)); }
+ break;
+
+ case 35:
+/* Line 1787 of yacc.c */
+#line 226 "calc.y"
+ { CHECK_UI ("Fibonacci", sp);
+ mpz_fib_ui (sp, mpz_get_ui (sp)); }
+ break;
+
+ case 37:
+/* Line 1787 of yacc.c */
+#line 229 "calc.y"
+ { sp--; mpz_set_si (sp,
+ mpz_kronecker (sp, sp+1)); }
+ break;
+
+ case 39:
+/* Line 1787 of yacc.c */
+#line 232 "calc.y"
+ { CHECK_UI ("Lucas number", sp);
+ mpz_lucnum_ui (sp, mpz_get_ui (sp)); }
+ break;
+
+ case 40:
+/* Line 1787 of yacc.c */
+#line 234 "calc.y"
+ { mpz_nextprime (sp, sp); }
+ break;
+
+ case 41:
+/* Line 1787 of yacc.c */
+#line 235 "calc.y"
+ { sp -= 2; mpz_powm (sp, sp, sp+1, sp+2); }
+ break;
+
+ case 42:
+/* Line 1787 of yacc.c */
+#line 236 "calc.y"
+ { sp--; CHECK_UI ("Nth-root", sp+1);
+ mpz_root (sp, sp, mpz_get_ui (sp+1)); }
+ break;
+
+ case 43:
+/* Line 1787 of yacc.c */
+#line 238 "calc.y"
+ { mpz_sqrt (sp, sp); }
+ break;
+
+ case 44:
+/* Line 1787 of yacc.c */
+#line 240 "calc.y"
+ {
+ sp++;
+ CHECK_OVERFLOW ();
+ CHECK_VARIABLE ((yyvsp[(1) - (1)].var));
+ mpz_set (sp, variable[(yyvsp[(1) - (1)].var)]);
+ }
+ break;
+
+ case 45:
+/* Line 1787 of yacc.c */
+#line 246 "calc.y"
+ {
+ sp++;
+ CHECK_OVERFLOW ();
+ if (mpz_set_str (sp, (yyvsp[(1) - (1)].str), ibase) != 0)
+ {
+ fprintf (stderr, "Invalid number: %s\n", (yyvsp[(1) - (1)].str));
+ YYERROR;
+ }
+ }
+ break;
+
+ case 47:
+/* Line 1787 of yacc.c */
+#line 258 "calc.y"
+ { sp--; mpz_gcd (sp, sp, sp+1); }
+ break;
+
+ case 49:
+/* Line 1787 of yacc.c */
+#line 262 "calc.y"
+ { sp--; mpz_lcm (sp, sp, sp+1); }
+ break;
+
+
+/* Line 1787 of yacc.c */
+#line 1968 "calc.c"
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ }
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+/* Line 2050 of yacc.c */
+#line 264 "calc.y"
+
+
+yyerror (char *s)
+{
+ fprintf (stderr, "%s\n", s);
+}
+
+int calc_option_readline = -1;
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "--readline") == 0)
+ calc_option_readline = 1;
+ else if (strcmp (argv[i], "--noreadline") == 0)
+ calc_option_readline = 0;
+ else if (strcmp (argv[i], "--help") == 0)
+ {
+ printf ("Usage: calc [--option]...\n");
+ printf (" --readline use readline\n");
+ printf (" --noreadline don't use readline\n");
+ printf (" --help this message\n");
+ printf ("Readline is only available when compiled in,\n");
+ printf ("and in that case it's the default on a tty.\n");
+ exit (0);
+ }
+ else
+ {
+ fprintf (stderr, "Unrecognised option: %s\n", argv[i]);
+ exit (1);
+ }
+ }
+
+#if WITH_READLINE
+ calc_init_readline ();
+#else
+ if (calc_option_readline == 1)
+ {
+ fprintf (stderr, "Readline support not available\n");
+ exit (1);
+ }
+#endif
+
+ for (i = 0; i < numberof (variable); i++)
+ mpz_init (variable[i]);
+
+ for (i = 0; i < numberof (stack); i++)
+ mpz_init (stack[i]);
+
+ return yyparse ();
+}
diff --git a/gmp/demos/calc/calc.h b/gmp/demos/calc/calc.h
new file mode 100644
index 0000000000..78e0195d24
--- /dev/null
+++ b/gmp/demos/calc/calc.h
@@ -0,0 +1,145 @@
+/* A Bison parser, made by GNU Bison 2.7.12-4996. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+#ifndef YY_YY_CALC_H_INCLUDED
+# define YY_YY_CALC_H_INCLUDED
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ EOS = 258,
+ BAD = 259,
+ HELP = 260,
+ HEX = 261,
+ DECIMAL = 262,
+ QUIT = 263,
+ ABS = 264,
+ BIN = 265,
+ FIB = 266,
+ GCD = 267,
+ KRON = 268,
+ LCM = 269,
+ LUCNUM = 270,
+ NEXTPRIME = 271,
+ POWM = 272,
+ ROOT = 273,
+ SQRT = 274,
+ NUMBER = 275,
+ VARIABLE = 276,
+ LOR = 277,
+ LAND = 278,
+ GE = 279,
+ LE = 280,
+ NE = 281,
+ EQ = 282,
+ RSHIFT = 283,
+ LSHIFT = 284,
+ UMINUS = 285
+ };
+#endif
+/* Tokens. */
+#define EOS 258
+#define BAD 259
+#define HELP 260
+#define HEX 261
+#define DECIMAL 262
+#define QUIT 263
+#define ABS 264
+#define BIN 265
+#define FIB 266
+#define GCD 267
+#define KRON 268
+#define LCM 269
+#define LUCNUM 270
+#define NEXTPRIME 271
+#define POWM 272
+#define ROOT 273
+#define SQRT 274
+#define NUMBER 275
+#define VARIABLE 276
+#define LOR 277
+#define LAND 278
+#define GE 279
+#define LE 280
+#define NE 281
+#define EQ 282
+#define RSHIFT 283
+#define LSHIFT 284
+#define UMINUS 285
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+/* Line 2053 of yacc.c */
+#line 142 "calc.y"
+
+ char *str;
+ int var;
+
+
+/* Line 2053 of yacc.c */
+#line 123 "calc.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+extern YYSTYPE yylval;
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY_YY_CALC_H_INCLUDED */
diff --git a/gmp/demos/calc/calc.y b/gmp/demos/calc/calc.y
new file mode 100644
index 0000000000..0fa1206f79
--- /dev/null
+++ b/gmp/demos/calc/calc.y
@@ -0,0 +1,318 @@
+%{
+/* A simple integer desk calculator using yacc and gmp.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* This is a simple program, meant only to show one way to use GMP for this
+ sort of thing. There's few features, and error checking is minimal.
+ Standard input is read, calc_help() below shows the inputs accepted.
+
+ Expressions are evaluated as they're read. If user defined functions
+ were wanted it'd be necessary to build a parse tree like pexpr.c does, or
+ a list of operations for a stack based evaluator. That would also make
+ it possible to detect and optimize evaluations "mod m" like pexpr.c does.
+
+ A stack is used for intermediate values in the expression evaluation,
+ separate from the yacc parser stack. This is simple, makes error
+ recovery easy, minimizes the junk around mpz calls in the rules, and
+ saves initializing or clearing "mpz_t"s during a calculation. A
+ disadvantage though is that variables must be copied to the stack to be
+ worked on. A more sophisticated calculator or language system might be
+ able to avoid that when executing a compiled or semi-compiled form.
+
+ Avoiding repeated initializing and clearing of "mpz_t"s is important. In
+ this program the time spent parsing is obviously much greater than any
+ possible saving from this, but a proper calculator or language should
+ take some trouble over it. Don't be surprised if an init/clear takes 3
+ or more times as long as a 10 limb addition, depending on the system (see
+ the mpz_init_realloc_clear example in tune/README). */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#define NO_CALC_H /* because it conflicts with normal calc.c stuff */
+#include "calc-common.h"
+
+
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+
+
+void
+calc_help (void)
+{
+ printf ("Examples:\n");
+ printf (" 2+3*4 expressions are evaluated\n");
+ printf (" x=5^6 variables a to z can be set and used\n");
+ printf ("Operators:\n");
+ printf (" + - * arithmetic\n");
+ printf (" / %% division and remainder (rounding towards negative infinity)\n");
+ printf (" ^ exponentiation\n");
+ printf (" ! factorial\n");
+ printf (" << >> left and right shifts\n");
+ printf (" <= >= > \\ comparisons, giving 1 if true, 0 if false\n");
+ printf (" == != < /\n");
+ printf (" && || logical and/or, giving 1 if true, 0 if false\n");
+ printf ("Functions:\n");
+ printf (" abs(n) absolute value\n");
+ printf (" bin(n,m) binomial coefficient\n");
+ printf (" fib(n) fibonacci number\n");
+ printf (" gcd(a,b,..) greatest common divisor\n");
+ printf (" kron(a,b) kronecker symbol\n");
+ printf (" lcm(a,b,..) least common multiple\n");
+ printf (" lucnum(n) lucas number\n");
+ printf (" nextprime(n) next prime after n\n");
+ printf (" powm(b,e,m) modulo powering, b^e%%m\n");
+ printf (" root(n,r) r-th root\n");
+ printf (" sqrt(n) square root\n");
+ printf ("Other:\n");
+ printf (" hex \\ set hex or decimal for input and output\n");
+ printf (" decimal / (\"0x\" can be used for hex too)\n");
+ printf (" quit exit program (EOF works too)\n");
+ printf (" ; statements are separated with a ; or newline\n");
+ printf (" \\ continue expressions with \\ before newline\n");
+ printf (" # xxx comments are # though to newline\n");
+ printf ("Hex numbers must be entered in upper case, to distinguish them from the\n");
+ printf ("variables a to f (like in bc).\n");
+}
+
+
+int ibase = 0;
+int obase = 10;
+
+
+/* The stack is a fixed size, which means there's a limit on the nesting
+ allowed in expressions. A more sophisticated program could let it grow
+ dynamically. */
+
+mpz_t stack[100];
+mpz_ptr sp = stack[0];
+
+#define CHECK_OVERFLOW() \
+ if (sp >= stack[numberof(stack)]) /* FIXME */ \
+ { \
+ fprintf (stderr, \
+ "Value stack overflow, too much nesting in expression\n"); \
+ YYERROR; \
+ }
+
+#define CHECK_EMPTY() \
+ if (sp != stack[0]) \
+ { \
+ fprintf (stderr, "Oops, expected the value stack to be empty\n"); \
+ sp = stack[0]; \
+ }
+
+
+mpz_t variable[26];
+
+#define CHECK_VARIABLE(var) \
+ if ((var) < 0 || (var) >= numberof (variable)) \
+ { \
+ fprintf (stderr, "Oops, bad variable somehow: %d\n", var); \
+ YYERROR; \
+ }
+
+
+#define CHECK_UI(name,z) \
+ if (! mpz_fits_ulong_p (z)) \
+ { \
+ fprintf (stderr, "%s too big\n", name); \
+ YYERROR; \
+ }
+
+%}
+
+%union {
+ char *str;
+ int var;
+}
+
+%token EOS BAD
+%token HELP HEX DECIMAL QUIT
+%token ABS BIN FIB GCD KRON LCM LUCNUM NEXTPRIME POWM ROOT SQRT
+%token <str> NUMBER
+%token <var> VARIABLE
+
+/* operators, increasing precedence */
+%left LOR
+%left LAND
+%nonassoc '<' '>' EQ NE LE GE
+%left LSHIFT RSHIFT
+%left '+' '-'
+%left '*' '/' '%'
+%nonassoc UMINUS
+%right '^'
+%nonassoc '!'
+
+%%
+
+top:
+ statement
+ | statements statement;
+
+statements:
+ statement EOS
+ | statements statement EOS
+ | error EOS { sp = stack[0]; yyerrok; };
+
+statement:
+ /* empty */
+ | e {
+ mpz_out_str (stdout, obase, sp); putchar ('\n');
+ sp--;
+ CHECK_EMPTY ();
+ }
+ | VARIABLE '=' e {
+ CHECK_VARIABLE ($1);
+ mpz_swap (variable[$1], sp);
+ sp--;
+ CHECK_EMPTY ();
+ }
+ | HELP { calc_help (); }
+ | HEX { ibase = 16; obase = -16; }
+ | DECIMAL { ibase = 0; obase = 10; }
+ | QUIT { exit (0); };
+
+/* "e" leaves it's value on the top of the mpz stack. A rule like "e '+' e"
+ will have done a reduction for the first "e" first and the second "e"
+ second, so the code receives the values in that order on the stack. */
+e:
+ '(' e ')' /* value on stack */
+ | e '+' e { sp--; mpz_add (sp, sp, sp+1); }
+ | e '-' e { sp--; mpz_sub (sp, sp, sp+1); }
+ | e '*' e { sp--; mpz_mul (sp, sp, sp+1); }
+ | e '/' e { sp--; mpz_fdiv_q (sp, sp, sp+1); }
+ | e '%' e { sp--; mpz_fdiv_r (sp, sp, sp+1); }
+ | e '^' e { CHECK_UI ("Exponent", sp);
+ sp--; mpz_pow_ui (sp, sp, mpz_get_ui (sp+1)); }
+ | e LSHIFT e { CHECK_UI ("Shift count", sp);
+ sp--; mpz_mul_2exp (sp, sp, mpz_get_ui (sp+1)); }
+ | e RSHIFT e { CHECK_UI ("Shift count", sp);
+ sp--; mpz_fdiv_q_2exp (sp, sp, mpz_get_ui (sp+1)); }
+ | e '!' { CHECK_UI ("Factorial", sp);
+ mpz_fac_ui (sp, mpz_get_ui (sp)); }
+ | '-' e %prec UMINUS { mpz_neg (sp, sp); }
+
+ | e '<' e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) < 0); }
+ | e LE e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) <= 0); }
+ | e EQ e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) == 0); }
+ | e NE e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) != 0); }
+ | e GE e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) >= 0); }
+ | e '>' e { sp--; mpz_set_ui (sp, mpz_cmp (sp, sp+1) > 0); }
+
+ | e LAND e { sp--; mpz_set_ui (sp, mpz_sgn (sp) && mpz_sgn (sp+1)); }
+ | e LOR e { sp--; mpz_set_ui (sp, mpz_sgn (sp) || mpz_sgn (sp+1)); }
+
+ | ABS '(' e ')' { mpz_abs (sp, sp); }
+ | BIN '(' e ',' e ')' { sp--; CHECK_UI ("Binomial base", sp+1);
+ mpz_bin_ui (sp, sp, mpz_get_ui (sp+1)); }
+ | FIB '(' e ')' { CHECK_UI ("Fibonacci", sp);
+ mpz_fib_ui (sp, mpz_get_ui (sp)); }
+ | GCD '(' gcdlist ')' /* value on stack */
+ | KRON '(' e ',' e ')' { sp--; mpz_set_si (sp,
+ mpz_kronecker (sp, sp+1)); }
+ | LCM '(' lcmlist ')' /* value on stack */
+ | LUCNUM '(' e ')' { CHECK_UI ("Lucas number", sp);
+ mpz_lucnum_ui (sp, mpz_get_ui (sp)); }
+ | NEXTPRIME '(' e ')' { mpz_nextprime (sp, sp); }
+ | POWM '(' e ',' e ',' e ')' { sp -= 2; mpz_powm (sp, sp, sp+1, sp+2); }
+ | ROOT '(' e ',' e ')' { sp--; CHECK_UI ("Nth-root", sp+1);
+ mpz_root (sp, sp, mpz_get_ui (sp+1)); }
+ | SQRT '(' e ')' { mpz_sqrt (sp, sp); }
+
+ | VARIABLE {
+ sp++;
+ CHECK_OVERFLOW ();
+ CHECK_VARIABLE ($1);
+ mpz_set (sp, variable[$1]);
+ }
+ | NUMBER {
+ sp++;
+ CHECK_OVERFLOW ();
+ if (mpz_set_str (sp, $1, ibase) != 0)
+ {
+ fprintf (stderr, "Invalid number: %s\n", $1);
+ YYERROR;
+ }
+ };
+
+gcdlist:
+ e /* value on stack */
+ | gcdlist ',' e { sp--; mpz_gcd (sp, sp, sp+1); };
+
+lcmlist:
+ e /* value on stack */
+ | lcmlist ',' e { sp--; mpz_lcm (sp, sp, sp+1); };
+
+%%
+
+yyerror (char *s)
+{
+ fprintf (stderr, "%s\n", s);
+}
+
+int calc_option_readline = -1;
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "--readline") == 0)
+ calc_option_readline = 1;
+ else if (strcmp (argv[i], "--noreadline") == 0)
+ calc_option_readline = 0;
+ else if (strcmp (argv[i], "--help") == 0)
+ {
+ printf ("Usage: calc [--option]...\n");
+ printf (" --readline use readline\n");
+ printf (" --noreadline don't use readline\n");
+ printf (" --help this message\n");
+ printf ("Readline is only available when compiled in,\n");
+ printf ("and in that case it's the default on a tty.\n");
+ exit (0);
+ }
+ else
+ {
+ fprintf (stderr, "Unrecognised option: %s\n", argv[i]);
+ exit (1);
+ }
+ }
+
+#if WITH_READLINE
+ calc_init_readline ();
+#else
+ if (calc_option_readline == 1)
+ {
+ fprintf (stderr, "Readline support not available\n");
+ exit (1);
+ }
+#endif
+
+ for (i = 0; i < numberof (variable); i++)
+ mpz_init (variable[i]);
+
+ for (i = 0; i < numberof (stack); i++)
+ mpz_init (stack[i]);
+
+ return yyparse ();
+}
diff --git a/gmp/demos/calc/calclex.c b/gmp/demos/calc/calclex.c
new file mode 100644
index 0000000000..bf65cba425
--- /dev/null
+++ b/gmp/demos/calc/calclex.c
@@ -0,0 +1,1917 @@
+
+#line 3 "calclex.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 37
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ yy_size_t yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
+yy_size_t yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len );
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 19
+#define YY_END_OF_BUFFER 20
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[39] =
+ { 0,
+ 0, 0, 20, 18, 1, 2, 7, 6, 7, 18,
+ 16, 16, 2, 7, 7, 7, 16, 17, 18, 18,
+ 11, 6, 5, 6, 14, 16, 0, 12, 8, 10,
+ 9, 13, 16, 17, 3, 15, 4, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 1, 5, 1, 6, 7, 1, 6,
+ 6, 6, 6, 6, 6, 1, 6, 8, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 1, 10, 11,
+ 12, 13, 1, 1, 14, 14, 14, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 16, 15, 15,
+ 1, 17, 1, 6, 1, 1, 15, 15, 15, 15,
+
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 16,
+ 15, 15, 1, 18, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[19] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 1,
+ 1, 1, 1, 2, 3, 2, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[43] =
+ { 0,
+ 0, 0, 39, 49, 49, 49, 26, 16, 49, 30,
+ 20, 19, 49, 9, 22, 10, 9, 0, 29, 13,
+ 49, 23, 49, 24, 49, 0, 0, 49, 49, 49,
+ 49, 49, 13, 0, 49, 49, 49, 49, 41, 28,
+ 43, 45
+ } ;
+
+static yyconst flex_int16_t yy_def[43] =
+ { 0,
+ 38, 1, 38, 38, 38, 38, 38, 39, 38, 38,
+ 40, 40, 38, 38, 38, 38, 41, 42, 38, 38,
+ 38, 39, 38, 39, 38, 12, 12, 38, 38, 38,
+ 38, 38, 41, 42, 38, 38, 38, 0, 38, 38,
+ 38, 38
+ } ;
+
+static yyconst flex_int16_t yy_nxt[68] =
+ { 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 18, 19, 20, 23, 28,
+ 29, 31, 32, 34, 34, 23, 37, 34, 34, 26,
+ 36, 35, 24, 30, 38, 27, 25, 21, 38, 24,
+ 24, 22, 22, 22, 33, 33, 34, 34, 3, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38
+ } ;
+
+static yyconst flex_int16_t yy_chk[68] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 8, 14,
+ 14, 16, 16, 17, 17, 22, 24, 33, 33, 40,
+ 20, 19, 8, 15, 12, 11, 10, 7, 3, 22,
+ 24, 39, 39, 39, 41, 41, 42, 42, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "calclex.l"
+/* Lexical analyzer for calc program.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+#line 20 "calclex.l"
+#include <string.h>
+#include "calc-common.h"
+
+
+#if WITH_READLINE
+/* Let GNU flex use readline. See the calcread.c redefined input() for a
+ way that might work for a standard lex too. */
+#define YY_INPUT(buf,result,max_size) \
+ result = calc_input (buf, max_size);
+#endif
+
+
+/* Non-zero when reading the second or subsequent line of an expression,
+ used to give a different prompt when using readline. */
+int calc_more_input = 0;
+
+
+const struct calc_keywords_t calc_keywords[] = {
+ { "abs", ABS },
+ { "bin", BIN },
+ { "decimal", DECIMAL },
+ { "fib", FIB },
+ { "hex", HEX },
+ { "help", HELP },
+ { "gcd", GCD },
+ { "kron", KRON },
+ { "lcm", LCM },
+ { "lucnum", LUCNUM },
+ { "nextprime", NEXTPRIME },
+ { "powm", POWM },
+ { "quit", QUIT },
+ { "root", ROOT },
+ { "sqrt", SQRT },
+ { NULL }
+};
+#line 527 "calclex.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+yy_size_t yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 57 "calclex.l"
+
+
+#line 712 "calclex.c"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 39 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 49 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 59 "calclex.l"
+{ /* white space is skipped */ }
+ YY_BREAK
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+#line 61 "calclex.l"
+{ /* semicolon or newline separates statements */
+ calc_more_input = 0;
+ return EOS; }
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 64 "calclex.l"
+{ /* escaped newlines are skipped */ }
+ YY_BREAK
+case 4:
+/* rule 4 can match eol */
+YY_RULE_SETUP
+#line 67 "calclex.l"
+{
+ /* comment through to escaped newline is skipped */ }
+ YY_BREAK
+case 5:
+/* rule 5 can match eol */
+YY_RULE_SETUP
+#line 69 "calclex.l"
+{ /* comment through to newline is a separator */
+ calc_more_input = 0;
+ return EOS; }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 72 "calclex.l"
+{ /* comment through to EOF skipped */ }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 75 "calclex.l"
+{ return yytext[0]; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 76 "calclex.l"
+{ return LE; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 77 "calclex.l"
+{ return GE; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 78 "calclex.l"
+{ return EQ; }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 79 "calclex.l"
+{ return NE; }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 80 "calclex.l"
+{ return LSHIFT; }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 81 "calclex.l"
+{ return RSHIFT; }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 82 "calclex.l"
+{ return LAND; }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 83 "calclex.l"
+{ return LOR; }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 85 "calclex.l"
+{
+ yylval.str = yytext;
+ return NUMBER; }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 89 "calclex.l"
+{
+ int i;
+
+ for (i = 0; calc_keywords[i].name != NULL; i++)
+ if (strcmp (yytext, calc_keywords[i].name) == 0)
+ return calc_keywords[i].value;
+
+ if (yytext[0] >= 'a' && yytext[0] <= 'z' && yytext[1] == '\0')
+ {
+ yylval.var = yytext[0] - 'a';
+ return VARIABLE;
+ }
+
+ return BAD;
+}
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 105 "calclex.l"
+{ return BAD; }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 107 "calclex.l"
+ECHO;
+ YY_BREAK
+#line 915 "calclex.c"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ yy_size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ yy_size_t new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 39 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+ register char *yy_cp = (yy_c_buf_p);
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 39 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 38);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp )
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register yy_size_t number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+yy_size_t yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 107 "calclex.l"
+
+
+
+int
+yywrap ()
+{
+ return 1;
+}
+
diff --git a/gmp/demos/calc/calclex.l b/gmp/demos/calc/calclex.l
new file mode 100644
index 0000000000..44df848fad
--- /dev/null
+++ b/gmp/demos/calc/calclex.l
@@ -0,0 +1,113 @@
+/* Lexical analyzer for calc program.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+%{
+#include <string.h>
+#include "calc-common.h"
+
+
+#if WITH_READLINE
+/* Let GNU flex use readline. See the calcread.c redefined input() for a
+ way that might work for a standard lex too. */
+#define YY_INPUT(buf,result,max_size) \
+ result = calc_input (buf, max_size);
+#endif
+
+
+/* Non-zero when reading the second or subsequent line of an expression,
+ used to give a different prompt when using readline. */
+int calc_more_input = 0;
+
+
+const struct calc_keywords_t calc_keywords[] = {
+ { "abs", ABS },
+ { "bin", BIN },
+ { "decimal", DECIMAL },
+ { "fib", FIB },
+ { "hex", HEX },
+ { "help", HELP },
+ { "gcd", GCD },
+ { "kron", KRON },
+ { "lcm", LCM },
+ { "lucnum", LUCNUM },
+ { "nextprime", NEXTPRIME },
+ { "powm", POWM },
+ { "quit", QUIT },
+ { "root", ROOT },
+ { "sqrt", SQRT },
+ { NULL }
+};
+%}
+
+%%
+
+[ \t\f] { /* white space is skipped */ }
+
+[;\n] { /* semicolon or newline separates statements */
+ calc_more_input = 0;
+ return EOS; }
+\\\n { /* escaped newlines are skipped */ }
+
+
+#(([^\\\n]*)\\)+\n {
+ /* comment through to escaped newline is skipped */ }
+#[^\n]*\n { /* comment through to newline is a separator */
+ calc_more_input = 0;
+ return EOS; }
+#[^\n]* { /* comment through to EOF skipped */ }
+
+
+[-+*/%()<>^!=,] { return yytext[0]; }
+"<=" { return LE; }
+">=" { return GE; }
+"==" { return EQ; }
+"!=" { return NE; }
+"<<" { return LSHIFT; }
+">>" { return RSHIFT; }
+"&&" { return LAND; }
+"||" { return LOR; }
+
+(0[xX])?[0-9A-F]+ {
+ yylval.str = yytext;
+ return NUMBER; }
+
+[a-zA-Z][a-zA-Z0-9]* {
+ int i;
+
+ for (i = 0; calc_keywords[i].name != NULL; i++)
+ if (strcmp (yytext, calc_keywords[i].name) == 0)
+ return calc_keywords[i].value;
+
+ if (yytext[0] >= 'a' && yytext[0] <= 'z' && yytext[1] == '\0')
+ {
+ yylval.var = yytext[0] - 'a';
+ return VARIABLE;
+ }
+
+ return BAD;
+}
+
+. { return BAD; }
+
+%%
+
+int
+yywrap ()
+{
+ return 1;
+}
diff --git a/gmp/demos/calc/calcread.c b/gmp/demos/calc/calcread.c
new file mode 100644
index 0000000000..40433686c1
--- /dev/null
+++ b/gmp/demos/calc/calcread.c
@@ -0,0 +1,146 @@
+/* Readline support for calc program.
+
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+#include "calc-common.h"
+
+#if WITH_READLINE
+#include <stdio.h> /* for FILE for old versions of readline/readline.h */
+#include <stdlib.h> /* for free */
+#include <string.h> /* for strdup */
+#include <unistd.h> /* for isatty */
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include "gmp.h"
+
+
+/* change this to "#define TRACE(x) x" for a few diagnostics */
+#define TRACE(x)
+
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+
+char *
+calc_completion_entry (const char *text, int state)
+{
+ static int index, len;
+ char *name;
+
+ if (!state)
+ {
+ index = 0;
+ len = strlen (text);
+ }
+ TRACE (printf ("calc_completion_entry %s %d, index=%d len=%d\n",
+ text, state, index, len));
+ while ((name = calc_keywords[index].name) != NULL)
+ {
+ index++;
+ if (memcmp (name, text, len) == 0)
+ return (strdup (name));
+ }
+ return NULL;
+}
+
+void
+calc_init_readline (void)
+{
+ /* By default use readline when the input is a tty. It's a bit contrary
+ to the GNU interface conventions to make the behaviour depend on where
+ the input is coming from, but this is pretty convenient. */
+ if (calc_option_readline == -1)
+ {
+ calc_option_readline = isatty (fileno (stdin));
+ TRACE (printf ("calc_option_readline %d\n", calc_option_readline));
+ }
+
+ if (calc_option_readline)
+ {
+ printf ("GNU MP demo calculator program, gmp version %s\n", gmp_version);
+ printf ("Type \"help\" for help.\n");
+ rl_readline_name = "gmp-calc";
+ rl_completion_entry_function = calc_completion_entry;
+ }
+}
+
+
+/* This function is supposed to return YY_NULL to indicate EOF, but that
+ constant is only in calclex.c and we don't want to clutter calclex.l with
+ this readline stuff, so instead just hard code 0 for YY_NULL. That's
+ it's defined value on unix anyway. */
+
+int
+calc_input (char *buf, size_t max_size)
+{
+ if (calc_option_readline)
+ {
+ static char *line = NULL;
+ static size_t line_size = 0;
+ static size_t upto = 0;
+ size_t copy_size;
+
+ if (upto >= line_size)
+ {
+ if (line != NULL)
+ free (line);
+
+ line = readline (calc_more_input ? "more> " : "> ");
+ calc_more_input = 1;
+ if (line == NULL)
+ return 0;
+ TRACE (printf ("readline: %s\n", line));
+
+ if (line[0] != '\0')
+ add_history (line);
+
+ line_size = strlen (line);
+ line[line_size] = '\n';
+ line_size++;
+ upto = 0;
+ }
+
+ copy_size = MIN (line_size-upto, max_size);
+ memcpy (buf, line+upto, copy_size);
+ upto += copy_size;
+ return copy_size;
+ }
+ else
+ {
+ /* not readline */
+ return fread (buf, 1, max_size, stdin);
+ }
+}
+
+
+/* This redefined input() might let a traditional lex use the readline
+ support here. Apparently POSIX doesn't specify whether an override like
+ this will work, so maybe it'll work or maybe it won't. This function is
+ also not particularly efficient, but don't worry about that, since flex
+ is the preferred parser. */
+
+int
+input (void)
+{
+ char c;
+ if (calc_input (&c, 1) != 1)
+ return EOF;
+ else
+ return (int) c;
+}
+
+#endif /* WITH_READLINE */
diff --git a/gmp/demos/expr/Makefile.am b/gmp/demos/expr/Makefile.am
new file mode 100644
index 0000000000..369e751743
--- /dev/null
+++ b/gmp/demos/expr/Makefile.am
@@ -0,0 +1,54 @@
+## 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.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+
+# FIXME: This is a workaround for a bug in automake 1.8.4. When the only
+# library is in EXTRA_LIBRARIES, $(ARFLAGS) is used but no default setting
+# for that variable is established. We give an explicit ARFLAGS=cru the
+# same as generated for lib_LIBRARIES or noinst_LIBRARIES.
+#
+ARFLAGS = cru
+
+EXTRA_LIBRARIES = libexpr.a
+libexpr_a_SOURCES = expr.h expr-impl.h \
+ expr.c exprv.c exprz.c exprza.c exprq.c exprqa.c exprf.c exprfa.c
+
+EXTRA_PROGRAMS = run-expr t-expr
+LDADD = libexpr.a $(top_builddir)/libgmp.la
+t_expr_LDADD = $(top_builddir)/tests/libtests.la $(LDADD)
+
+CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LIBRARIES)
+
+allprogs: $(EXTRA_PROGRAMS)
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
diff --git a/gmp/demos/expr/Makefile.in b/gmp/demos/expr/Makefile.in
new file mode 100644
index 0000000000..adb9eba91a
--- /dev/null
+++ b/gmp/demos/expr/Makefile.in
@@ -0,0 +1,576 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+EXTRA_PROGRAMS = run-expr$(EXEEXT) t-expr$(EXEEXT)
+subdir = demos/expr
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+libexpr_a_AR = $(AR) $(ARFLAGS)
+libexpr_a_LIBADD =
+am_libexpr_a_OBJECTS = expr.$(OBJEXT) exprv.$(OBJEXT) exprz.$(OBJEXT) \
+ exprza.$(OBJEXT) exprq.$(OBJEXT) exprqa.$(OBJEXT) \
+ exprf.$(OBJEXT) exprfa.$(OBJEXT)
+libexpr_a_OBJECTS = $(am_libexpr_a_OBJECTS)
+run_expr_SOURCES = run-expr.c
+run_expr_OBJECTS = run-expr.$(OBJEXT)
+run_expr_LDADD = $(LDADD)
+run_expr_DEPENDENCIES = libexpr.a $(top_builddir)/libgmp.la
+t_expr_SOURCES = t-expr.c
+t_expr_OBJECTS = t-expr.$(OBJEXT)
+t_expr_DEPENDENCIES = $(top_builddir)/tests/libtests.la $(LDADD)
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libexpr_a_SOURCES) run-expr.c t-expr.c
+DIST_SOURCES = $(libexpr_a_SOURCES) run-expr.c t-expr.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+
+# FIXME: This is a workaround for a bug in automake 1.8.4. When the only
+# library is in EXTRA_LIBRARIES, $(ARFLAGS) is used but no default setting
+# for that variable is established. We give an explicit ARFLAGS=cru the
+# same as generated for lib_LIBRARIES or noinst_LIBRARIES.
+#
+ARFLAGS = cru
+EXTRA_LIBRARIES = libexpr.a
+libexpr_a_SOURCES = expr.h expr-impl.h \
+ expr.c exprv.c exprz.c exprza.c exprq.c exprqa.c exprf.c exprfa.c
+
+LDADD = libexpr.a $(top_builddir)/libgmp.la
+t_expr_LDADD = $(top_builddir)/tests/libtests.la $(LDADD)
+CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LIBRARIES)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 demos/expr/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps demos/expr/Makefile
+.PRECIOUS: 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):
+libexpr.a: $(libexpr_a_OBJECTS) $(libexpr_a_DEPENDENCIES) $(EXTRA_libexpr_a_DEPENDENCIES)
+ -rm -f libexpr.a
+ $(libexpr_a_AR) libexpr.a $(libexpr_a_OBJECTS) $(libexpr_a_LIBADD)
+ $(RANLIB) libexpr.a
+run-expr$(EXEEXT): $(run_expr_OBJECTS) $(run_expr_DEPENDENCIES) $(EXTRA_run_expr_DEPENDENCIES)
+ @rm -f run-expr$(EXEEXT)
+ $(LINK) $(run_expr_OBJECTS) $(run_expr_LDADD) $(LIBS)
+t-expr$(EXEEXT): $(t_expr_OBJECTS) $(t_expr_DEPENDENCIES) $(EXTRA_t_expr_DEPENDENCIES)
+ @rm -f t-expr$(EXEEXT)
+ $(LINK) $(t_expr_OBJECTS) $(t_expr_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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-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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool ctags 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 \
+ tags uninstall uninstall-am
+
+
+allprogs: $(EXTRA_PROGRAMS)
+
+$(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/gmp/demos/expr/README b/gmp/demos/expr/README
new file mode 100644
index 0000000000..a54fe42c08
--- /dev/null
+++ b/gmp/demos/expr/README
@@ -0,0 +1,501 @@
+Copyright 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+
+ GMP EXPRESSION EVALUATION
+ -------------------------
+
+
+
+THIS CODE IS PRELIMINARY AND MAY BE SUBJECT TO INCOMPATIBLE CHANGES IN
+FUTURE VERSIONS OF GMP.
+
+
+
+The files in this directory implement a simple scheme of string based
+expression parsing and evaluation, supporting mpz, mpq and mpf.
+
+This will be slower than direct GMP library calls, but may be convenient in
+various circumstances, such as while prototyping, or for letting a user
+enter values in symbolic form. "2**5723-7" for example is a lot easier to
+enter or maintain than the equivalent written out in decimal.
+
+
+
+BUILDING
+
+Nothing in this directory is a normal part of libgmp, and nothing is built
+or installed, but various Makefile rules are available to compile
+everything.
+
+All the functions are available through a little library (there's no shared
+library since upward binary compatibility is not guaranteed).
+
+ make libexpr.a
+
+In a program, prototypes are available using
+
+ #include "expr.h"
+
+run-expr.c is a sample program doing evaluations from the command line.
+
+ make run-expr
+ ./run-expr '1+2*3'
+
+t-expr.c is self-test program, it prints nothing if successful.
+
+ make t-expr
+ ./t-expr
+
+The expr*.c sources don't depend on gmp-impl.h and can be compiled with just
+a standard installed GMP. This isn't true of t-expr though, since it uses
+some of the internal tests/libtests.la.
+
+
+
+SIMPLE USAGE
+
+int mpz_expr (mpz_t res, int base, const char *e, ...);
+int mpq_expr (mpq_t res, int base, const char *e, ...);
+int mpf_expr (mpf_t res, int base, const char *e, ...);
+
+These functions evaluate simple arithmetic expressions. For example,
+
+ mpz_expr (result, 0, "123+456", NULL);
+
+Numbers are parsed by mpz_expr and mpq_expr the same as mpz_set_str with the
+given base. mpf_expr follows mpf_set_str, but supporting an "0x" prefix for
+hex when base==0.
+
+ mpz_expr (result, 0, "0xAAAA * 0x5555", NULL);
+
+White space, as indicated by <ctype.h> isspace(), is ignored except for the
+purpose of separating tokens.
+
+Variables can be included in expressions by putting them in the stdarg list
+after the string. "a", "b", "c" etc in the expression string designate
+those values. For example,
+
+ mpq_t foo, bar;
+ ...
+ mpq_expr (q, 10, "2/3 + 1/a + b/2", foo, bar, NULL);
+
+Here "a" will be the value from foo and "b" from bar. Up to 26 variables
+can be included this way. The NULL must be present to indicate the end of
+the list.
+
+Variables can also be written "$a", "$b" etc. This is necessary when using
+bases greater than 10 since plain "a", "b" etc will otherwise be interpreted
+as numbers. For example,
+
+ mpf_t quux;
+ mpf_expr (f, 16, "F00F@-6 * $a", quux, NULL);
+
+All the standard C operators are available, with the usual precedences, plus
+"**" for exponentiation at the highest precedence (and right associative).
+
+ Operators Precedence
+ ** 220
+ ~ ! - (unary) 210
+ * / % 200
+ + - 190
+ << >> 180
+ <= < >= > 170
+ == != 160
+ & 150
+ ^ 140
+ | 130
+ && 120
+ || 110
+ ? : 100/101
+
+Currently only mpz_expr has the bitwise ~ % & ^ and | operators. The
+precedence numbers are of interest in the advanced usage described below.
+
+Various functions are available too. For example,
+
+ mpz_expr (res, 10, "gcd(123,456,789) * abs(a)", var, NULL);
+
+The following is the full set of functions,
+
+ mpz_expr
+ abs bin clrbit cmp cmpabs congruent_p divisible_p even_p fib fac
+ gcd hamdist invert jacobi kronecker lcm lucnum max min nextprime
+ odd_p perfect_power_p perfect_square_p popcount powm
+ probab_prime_p root scan0 scan1 setbit sgn sqrt
+
+ mpq_expr
+ abs, cmp, den, max, min, num, sgn
+
+ mpf_expr
+ abs, ceil, cmp, eq, floor, integer_p, max, min, reldiff, sgn,
+ sqrt, trunc
+
+All these are the same as the GMP library functions, except that min and max
+don't exist in the library. Note also that min, max, gcd and lcm take any
+number of arguments, not just two.
+
+mpf_expr does all calculations to the precision of the destination variable.
+
+
+Expression parsing can succeed or fail. The return value indicates this,
+and will be one of the following
+
+ MPEXPR_RESULT_OK
+ MPEXPR_RESULT_BAD_VARIABLE
+ MPEXPR_RESULT_BAD_TABLE
+ MPEXPR_RESULT_PARSE_ERROR
+ MPEXPR_RESULT_NOT_UI
+
+BAD_VARIABLE is when a variable is referenced that hasn't been provided.
+For example if "c" is used when only two parameters have been passed.
+BAD_TABLE is applicable to the advanced usage described below.
+
+PARSE_ERROR is a general syntax error, returned for any mal-formed input
+string.
+
+NOT_UI is returned when an attempt is made to use an operand that's bigger
+than an "unsigned long" with a function that's restricted to that range.
+For example "fib" is mpz_fib_ui and only accepts an "unsigned long".
+
+
+
+
+ADVANCED USAGE
+
+int mpz_expr_a (const struct mpexpr_operator_t *table,
+ mpz_ptr res, int base, const char *e, size_t elen,
+ mpz_srcptr var[26])
+int mpq_expr_a (const struct mpexpr_operator_t *table,
+ mpq_ptr res, int base, const char *e, size_t elen,
+ mpq_srcptr var[26])
+int mpf_expr_a (const struct mpexpr_operator_t *table,
+ mpf_ptr res, int base, unsigned long prec,
+ const char *e, size_t elen,
+ mpf_srcptr var[26])
+
+These functions are an advanced interface to expression parsing.
+
+The string is taken as pointer and length. This makes it possible to parse
+an expression in the middle of somewhere without copying and null
+terminating it.
+
+Variables are an array of 26 pointers to the appropriate operands, or NULL
+for variables that are not available. Any combination of variables can be
+given, for example just "x" and "y" (var[23] and var[24]) could be set.
+
+Operators and functions are specified with a table. This makes it possible
+to provide additional operators or functions, or to completely change the
+syntax. The standard tables used by the simple functions above are
+available as
+
+ const struct mpexpr_operator_t * const mpz_expr_standard_table;
+ const struct mpexpr_operator_t * const mpq_expr_standard_table;
+ const struct mpexpr_operator_t * const mpf_expr_standard_table;
+
+struct mpexpr_operator_t is the following
+
+ struct mpexpr_operator_t {
+ const char *name;
+ mpexpr_fun_t fun;
+ int type;
+ int precedence;
+ };
+
+ typedef void (*mpexpr_fun_t) (void);
+
+As an example, the standard mpz_expr table entry for multiplication is as
+follows. See the source code for the full set of standard entries.
+
+ { "*", (mpexpr_fun_t) mpz_mul, MPEXPR_TYPE_BINARY, 200 },
+
+"name" is the string to parse, "fun" is the function to call for it, "type"
+indicates what parameters the function takes (among other things), and
+"precedence" sets its operator precedence.
+
+A NULL for "name" indicates the end of the table, so for example an mpf
+table with nothing but addition could be
+
+ struct mpexpr_operator_t table[] = {
+ { "+", (mpexpr_fun_t) mpf_add, MPEXPR_TYPE_BINARY, 190 },
+ { NULL }
+ };
+
+A special type MPEXPR_TYPE_NEW_TABLE makes it possible to chain from one
+table to another. For example the following would add a "mod" operator to
+the standard mpz table,
+
+ struct mpexpr_operator_t table[] = {
+ { "mod", (mpexpr_fun_t) mpz_fdiv_r, MPEXPR_TYPE_BINARY, 125 },
+ { (const char *) mpz_expr_standard_table, NULL, MPEXPR_TYPE_NEW_TABLE }
+ };
+
+Notice the low precedence on "mod", so that for instance "45+26 mod 7"
+parses as "(45+26)mod7".
+
+
+Functions are designated by a precedence of 0. They always occur as
+"foo(expr)" and so have no need for a precedence level. mpq_abs in the
+standard mpq table is
+
+ { "abs", (mpexpr_fun_t) mpq_abs, MPEXPR_TYPE_UNARY },
+
+Functions expecting no arguments as in "foo()" can be given with
+MPEXPR_TYPE_0ARY, or actual constants to be parsed as just "foo" are
+MPEXPR_TYPE_CONSTANT. For example if a "void mpf_const_pi(mpf_t f)"
+function existed (which it doesn't) it could be,
+
+ { "pi", (mpexpr_fun_t) mpf_const_pi, MPEXPR_TYPE_CONSTANT },
+
+
+Parsing of operator names is done by seeking the table entry with the
+longest matching name. So for instance operators "<" and "<=" exist, and
+when presented with "x <= y" the parser matches "<=" because it's longer.
+
+Parsing of function names, on the other hand, is done by requiring a whole
+alphanumeric word to match. For example presented with "fib2zz(5)" the
+parser will attempt to find a function called "fib2zz". A function "fib"
+wouldn't be used because it doesn't match the whole word.
+
+The flag MPEXPR_TYPE_WHOLEWORD can be ORed into an operator type to override
+the default parsing style. Similarly MPEXPR_TYPE_OPERATOR into a function.
+
+
+Binary operators are left associative by default, meaning they're evaluated
+from left to right, so for example "1+2+3" is treated as "(1+2)+3".
+MPEXPR_TYPE_RIGHTASSOC can be ORed into the operator type to work from right
+to left as in "1+(2+3)". This is generally what's wanted for
+exponentiation, and for example the standard mpz table has
+
+ { "**", (mpexpr_fun_t) mpz_pow_ui,
+ MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 }
+
+Unary operators are postfix by default. For example a factorial to be used
+as "123!" might be
+
+ { "!", (mpexpr_fun_t) mpz_fac_ui, MPEXPR_TYPE_UNARY_UI, 215 }
+
+MPEXPR_TYPE_PREFIX can be ORed into the type to get a prefix operator. For
+instance negation (unary minus) in the standard mpf table is
+
+ { "-", (mpexpr_fun_t) mpf_neg,
+ MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
+
+
+The same operator can exist as a prefix unary and a binary, or as a prefix
+and postfix unary, simply by putting two entries in the table. While
+parsing the context determines which style is sought. But note that the
+same operator can't be both a postfix unary and a binary, since the parser
+doesn't try to look ahead to decide which ought to be used.
+
+When there's two entries for an operator, both prefix or both postfix (or
+binary), then the first in the table will be used. This makes it possible
+to override an entry in a standard table, for example to change the function
+it calls, or perhaps its precedence level. The following would change mpz
+division from tdiv to cdiv,
+
+ struct mpexpr_operator_t table[] = {
+ { "/", (mpexpr_fun_t) mpz_cdiv_q, MPEXPR_TYPE_BINARY, 200 },
+ { "%", (mpexpr_fun_t) mpz_cdiv_r, MPEXPR_TYPE_BINARY, 200 },
+ { (char *) mpz_expr_standard_table, NULL, MPEXPR_TYPE_NEW_TABLE }
+ };
+
+
+The type field indicates what parameters the given function expects. The
+following styles of functions are supported. mpz_t is shown, but of course
+this is mpq_t for mpq_expr_a, mpf_t for mpf_expr_a, etc.
+
+ MPEXPR_TYPE_CONSTANT void func (mpz_t result);
+
+ MPEXPR_TYPE_0ARY void func (mpz_t result);
+ MPEXPR_TYPE_I_0ARY int func (void);
+
+ MPEXPR_TYPE_UNARY void func (mpz_t result, mpz_t op);
+ MPEXPR_TYPE_UNARY_UI void func (mpz_t result, unsigned long op);
+ MPEXPR_TYPE_I_UNARY int func (mpz_t op);
+ MPEXPR_TYPE_I_UNARY_UI int func (unsigned long op);
+
+ MPEXPR_TYPE_BINARY void func (mpz_t result, mpz_t op1, mpz_t op2);
+ MPEXPR_TYPE_BINARY_UI void func (mpz_t result,
+ mpz_t op1, unsigned long op2);
+ MPEXPR_TYPE_I_BINARY int func (mpz_t op1, mpz_t op2);
+ MPEXPR_TYPE_I_BINARY_UI int func (mpz_t op1, unsigned long op2);
+
+ MPEXPR_TYPE_TERNARY void func (mpz_t result,
+ mpz_t op1, mpz_t op2, mpz_t op3);
+ MPEXPR_TYPE_TERNARY_UI void func (mpz_t result, mpz_t op1, mpz_t op2,
+ unsigned long op3);
+ MPEXPR_TYPE_I_TERNARY int func (mpz_t op1, mpz_t op2, mpz_t op3);
+ MPEXPR_TYPE_I_TERNARY_UI int func (mpz_t op1, mpz_t op2,
+ unsigned long op3);
+
+Notice the pattern of "UI" for the last parameter as an unsigned long, or
+"I" for the result as an "int" return value.
+
+It's important that the declared type for an operator or function matches
+the function pointer given. Any mismatch will have unpredictable results.
+
+For binary functions, a further type attribute is MPEXPR_TYPE_PAIRWISE which
+indicates that any number of arguments should be accepted, and evaluated by
+applying the given binary function to them pairwise. This is used by gcd,
+lcm, min and max. For example the standard mpz gcd is
+
+ { "gcd", (mpexpr_fun_t) mpz_gcd,
+ MPEXPR_TYPE_BINARY | MPEXPR_TYPE_PAIRWISE },
+
+Some special types exist for comparison operators (or functions).
+MPEXPR_TYPE_CMP_LT through MPEXPR_TYPE_CMP_GE expect an MPEXPR_TYPE_I_BINARY
+function, returning positive, negative or zero like mpz_cmp and similar.
+For example the standard mpf "!=" operator is
+
+ { "!=", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_NE, 160 },
+
+But there's no obligation to use these types, for instance the standard mpq
+table just uses a plain MPEXPR_TYPE_I_BINARY and mpq_equal for "==".
+
+Further special types MPEXPR_TYPE_MIN and MPEXPR_TYPE_MAX exist to implement
+the min and max functions, and they take a function like mpf_cmp similarly.
+The standard mpf max function is
+
+ { "max", (mpexpr_fun_t) mpf_cmp,
+ MPEXPR_TYPE_MAX | MPEXPR_TYPE_PAIRWISE },
+
+These can be used as operators too, for instance the following would be the
+>? operator which is a feature of GNU C++,
+
+ { ">?", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_MAX, 175 },
+
+Other special types are used to define "(" ")" parentheses, "," function
+argument separator, "!" through "||" logical booleans, ternary "?" ":", and
+the "$" which introduces variables. See the sources for how they should be
+used.
+
+
+User definable operator tables will have various uses. For example,
+
+ - a subset of the C operators, to be rid of infrequently used things
+ - a more mathematical syntax like "." for multiply, "^" for powering,
+ and "!" for factorial
+ - a boolean evaluator with "^" for AND, "v" for OR
+ - variables introduced with "%" instead of "$"
+ - brackets as "[" and "]" instead of "(" and ")"
+
+The only fixed parts of the parsing are the treatment of numbers, whitespace
+and the two styles of operator/function name recognition.
+
+As a final example, the following would be a complete mpz table implementing
+some operators with a more mathematical syntax. Notice there's no need to
+preserve the standard precedence values, anything can be used so long as
+they're in the desired relation to each other. There's also no need to have
+entries in precedence order, but it's convenient to do so to show what comes
+where.
+
+ static const struct mpexpr_operator_t table[] = {
+ { "^", (mpexpr_fun_t) mpz_pow_ui,
+ MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 9 },
+
+ { "!", (mpexpr_fun_t) mpz_fac_ui, MPEXPR_TYPE_UNARY_UI, 8 },
+ { "-", (mpexpr_fun_t) mpz_neg,
+ MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 7 },
+
+ { "*", (mpexpr_fun_t) mpz_mul, MPEXPR_TYPE_BINARY, 6 },
+ { "/", (mpexpr_fun_t) mpz_fdiv_q, MPEXPR_TYPE_BINARY, 6 },
+
+ { "+", (mpexpr_fun_t) mpz_add, MPEXPR_TYPE_BINARY, 5 },
+ { "-", (mpexpr_fun_t) mpz_sub, MPEXPR_TYPE_BINARY, 5 },
+
+ { "mod", (mpexpr_fun_t) mpz_mod, MPEXPR_TYPE_BINARY, 6 },
+
+ { ")", NULL, MPEXPR_TYPE_CLOSEPAREN, 4 },
+ { "(", NULL, MPEXPR_TYPE_OPENPAREN, 3 },
+ { ",", NULL, MPEXPR_TYPE_ARGSEP, 2 },
+
+ { "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
+ { NULL }
+ };
+
+
+
+
+INTERNALS
+
+Operator precedence is implemented using a control and data stack, there's
+no C recursion. When an expression like 1+2*3 is read the "+" is held on
+the control stack and 1 on the data stack until "*" has been parsed and
+applied to 2 and 3. This happens any time a higher precedence operator
+follows a lower one, or when a right-associative operator like "**" is
+repeated.
+
+Parentheses are handled by making "(" a special prefix unary with a low
+precedence so a whole following expression is read. The special operator
+")" knows to discard the pending "(". Function arguments are handled
+similarly, with the function pretending to be a low precedence prefix unary
+operator, and with "," allowed within functions. The same special ")"
+operator recognises a pending function and will invoke it appropriately.
+
+The ternary "? :" operator is also handled using precedences. ":" is one
+level higher than "?", so when a valid a?b:c is parsed the ":" finds a "?"
+on the control stack. It's a parse error for ":" to find anything else.
+
+
+
+FUTURE
+
+The ternary "?:" operator evaluates the "false" side of its pair, which is
+wasteful, though it ought to be harmless. It'd be better if it could
+evaluate only the "true" side. Similarly for the logical booleans "&&" and
+"||" if they know their result already.
+
+Functions like MPEXPR_TYPE_BINARY could return a status indicating operand
+out of range or whatever, to get an error back through mpz_expr etc. That
+would want to be just an option, since plain mpz_add etc have no such
+return.
+
+Could have assignments like "a = b*c" modifying the input variables.
+Assignment could be an operator attribute, making it expect an lvalue.
+There would want to be a standard table without assignments available
+though, so user input could be safely parsed.
+
+The closing parenthesis table entry could specify the type of open paren it
+expects, so that "(" and ")" could match and "[" and "]" match but not a
+mixture of the two. Currently "[" and "]" can be added, but there's no
+error on writing a mixed expression like "2*(3+4]". Maybe also there could
+be a way to say that functions can only be written with one or the other
+style of parens.
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/demos/expr/expr-impl.h b/gmp/demos/expr/expr-impl.h
new file mode 100644
index 0000000000..9b6458fbd0
--- /dev/null
+++ b/gmp/demos/expr/expr-impl.h
@@ -0,0 +1,125 @@
+/* Implementation specifics for expression evaluation.
+
+Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+
+#include "expr.h"
+
+
+#define isasciidigit(c) (isascii (c) && isdigit (c))
+#define isasciicsym(c) (isascii (c) && (isalnum(c) || (c) == '_'))
+
+#define isasciidigit_in_base(c,base) \
+ (isascii (c) \
+ && ((isdigit (c) && (c)-'0' < (base)) \
+ || (isupper (c) && (c)-'A'+10 < (base)) \
+ || (islower (c) && (c)-'a'+10 < (base))))
+
+
+union mpX_t {
+ mpz_t z;
+ mpq_t q;
+ mpf_t f;
+};
+
+typedef union mpX_t *mpX_ptr;
+typedef const union mpX_t *mpX_srcptr;
+
+typedef void (*mpexpr_fun_one_t) (mpX_ptr);
+typedef unsigned long (*mpexpr_fun_ui_one_t) (mpX_ptr);
+
+typedef void (*mpexpr_fun_0ary_t) (mpX_ptr);
+typedef int (*mpexpr_fun_i_0ary_t) (void);
+
+typedef void (*mpexpr_fun_unary_t) (mpX_ptr, mpX_srcptr);
+typedef void (*mpexpr_fun_unary_ui_t) (mpX_ptr, unsigned long);
+typedef int (*mpexpr_fun_i_unary_t) (mpX_srcptr);
+typedef int (*mpexpr_fun_i_unary_ui_t) (unsigned long);
+
+typedef void (*mpexpr_fun_binary_t) (mpX_ptr, mpX_srcptr, mpX_srcptr);
+typedef void (*mpexpr_fun_binary_ui_t) (mpX_ptr, mpX_srcptr, unsigned long);
+typedef int (*mpexpr_fun_i_binary_t) (mpX_srcptr, mpX_srcptr);
+typedef int (*mpexpr_fun_i_binary_ui_t) (mpX_srcptr, unsigned long);
+
+typedef void (*mpexpr_fun_ternary_t) (mpX_ptr, mpX_srcptr, mpX_srcptr, mpX_srcptr);
+typedef void (*mpexpr_fun_ternary_ui_t) (mpX_ptr, mpX_srcptr, mpX_srcptr, unsigned long);
+typedef int (*mpexpr_fun_i_ternary_t) (mpX_srcptr, mpX_srcptr, mpX_srcptr);
+typedef int (*mpexpr_fun_i_ternary_ui_t) (mpX_srcptr, mpX_srcptr, unsigned long);
+
+typedef size_t (*mpexpr_fun_number_t) (mpX_ptr, const char *str, size_t len, int base);
+typedef void (*mpexpr_fun_swap_t) (mpX_ptr, mpX_ptr);
+typedef unsigned long (*mpexpr_fun_get_ui_t) (mpX_srcptr);
+typedef void (*mpexpr_fun_set_si_t) (mpX_srcptr, long);
+
+struct mpexpr_control_t {
+ const struct mpexpr_operator_t *op;
+ int argcount;
+};
+
+#define MPEXPR_VARIABLES 26
+
+struct mpexpr_parse_t {
+ const struct mpexpr_operator_t *table;
+
+ mpX_ptr res;
+ int base;
+ unsigned long prec;
+ const char *e;
+ size_t elen;
+ mpX_srcptr *var;
+ int error_code;
+
+ int token;
+ const struct mpexpr_operator_t *token_op;
+
+ union mpX_t *data_stack;
+ int data_top;
+ int data_alloc;
+ int data_inited;
+
+ struct mpexpr_control_t *control_stack;
+ int control_top;
+ int control_alloc;
+
+ mpexpr_fun_0ary_t mpX_clear;
+ mpexpr_fun_i_unary_t mpX_ulong_p;
+ mpexpr_fun_get_ui_t mpX_get_ui;
+ mpexpr_fun_unary_ui_t mpX_init;
+ mpexpr_fun_number_t mpX_number;
+ mpexpr_fun_unary_t mpX_set;
+ mpexpr_fun_unary_t mpX_set_or_swap;
+ mpexpr_fun_set_si_t mpX_set_si;
+ mpexpr_fun_swap_t mpX_swap;
+};
+
+
+int mpexpr_evaluate (struct mpexpr_parse_t *p);
+int mpexpr_va_to_var (void *var[], va_list ap);
+size_t mpexpr_mpz_number (mpz_ptr res, const char *e, size_t elen, int base);
diff --git a/gmp/demos/expr/expr.c b/gmp/demos/expr/expr.c
new file mode 100644
index 0000000000..42dd7966be
--- /dev/null
+++ b/gmp/demos/expr/expr.c
@@ -0,0 +1,834 @@
+/* mpexpr_evaluate -- shared code for simple expression evaluation
+
+Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "expr-impl.h"
+
+
+/* Change this to "#define TRACE(x) x" to get some traces. The trace
+ printfs junk up the code a bit, but it's very hard to tell what's going
+ on without them. Set MPX_TRACE to a suitable output function for the
+ mpz/mpq/mpf being run (if you have the wrong trace function it'll
+ probably segv). */
+
+#define TRACE(x)
+#define MPX_TRACE mpz_trace
+
+
+/* A few helper macros copied from gmp-impl.h */
+#define ALLOCATE_FUNC_TYPE(n,type) \
+ ((type *) (*allocate_func) ((n) * sizeof (type)))
+#define ALLOCATE_FUNC_LIMBS(n) ALLOCATE_FUNC_TYPE (n, mp_limb_t)
+#define REALLOCATE_FUNC_TYPE(p, old_size, new_size, type) \
+ ((type *) (*reallocate_func) \
+ (p, (old_size) * sizeof (type), (new_size) * sizeof (type)))
+#define REALLOCATE_FUNC_LIMBS(p, old_size, new_size) \
+ REALLOCATE_FUNC_TYPE(p, old_size, new_size, mp_limb_t)
+#define FREE_FUNC_TYPE(p,n,type) (*free_func) (p, (n) * sizeof (type))
+#define FREE_FUNC_LIMBS(p,n) FREE_FUNC_TYPE (p, n, mp_limb_t)
+#define ASSERT(x)
+
+
+
+/* All the error strings are just for diagnostic traces. Only the error
+ code is actually returned. */
+#define ERROR(str,code) \
+ { \
+ TRACE (printf ("%s\n", str)); \
+ p->error_code = (code); \
+ goto done; \
+ }
+
+
+#define REALLOC(ptr, alloc, incr, type) \
+ do { \
+ int new_alloc = (alloc) + (incr); \
+ ptr = REALLOCATE_FUNC_TYPE (ptr, alloc, new_alloc, type); \
+ (alloc) = new_alloc; \
+ } while (0)
+
+
+/* data stack top element */
+#define SP (p->data_stack + p->data_top)
+
+/* Make sure there's room for another data element above current top.
+ reallocate_func is fetched for when this macro is used in lookahead(). */
+#define DATA_SPACE() \
+ do { \
+ if (p->data_top + 1 >= p->data_alloc) \
+ { \
+ void *(*reallocate_func) (void *, size_t, size_t); \
+ mp_get_memory_functions (NULL, &reallocate_func, NULL); \
+ TRACE (printf ("grow stack from %d\n", p->data_alloc)); \
+ REALLOC (p->data_stack, p->data_alloc, 20, union mpX_t); \
+ } \
+ ASSERT (p->data_top + 1 <= p->data_inited); \
+ if (p->data_top + 1 == p->data_inited) \
+ { \
+ TRACE (printf ("initialize %d\n", p->data_top + 1)); \
+ (*p->mpX_init) (&p->data_stack[p->data_top + 1], p->prec); \
+ p->data_inited++; \
+ } \
+ } while (0)
+
+#define DATA_PUSH() \
+ do { \
+ p->data_top++; \
+ ASSERT (p->data_top < p->data_alloc); \
+ ASSERT (p->data_top < p->data_inited); \
+ } while (0)
+
+/* the last stack entry is never popped, so top>=0 will be true */
+#define DATA_POP(n) \
+ do { \
+ p->data_top -= (n); \
+ ASSERT (p->data_top >= 0); \
+ } while (0)
+
+
+/* lookahead() parses the next token. Return 1 if successful, with some
+ extra data. Return 0 if fail, with reason in p->error_code.
+
+ "prefix" is MPEXPR_TYPE_PREFIX if an operator with that attribute is
+ preferred, or 0 if an operator without is preferred. */
+
+#define TOKEN_EOF -1 /* no extra data */
+#define TOKEN_VALUE -2 /* pushed onto data stack */
+#define TOKEN_OPERATOR -3 /* stored in p->token_op */
+#define TOKEN_FUNCTION -4 /* stored in p->token_op */
+
+#define TOKEN_NAME(n) \
+ ((n) == TOKEN_EOF ? "TOKEN_EOF" \
+ : (n) == TOKEN_VALUE ? "TOKEN_VALUE" \
+ : (n) == TOKEN_OPERATOR ? "TOKEN_OPERATOR" \
+ : (n) == TOKEN_VALUE ? "TOKEN_FUNCTION" \
+ : "UNKNOWN TOKEN")
+
+/* Functions default to being parsed as whole words, operators to match just
+ at the start of the string. The type flags override this. */
+#define WHOLEWORD(op) \
+ (op->precedence == 0 \
+ ? (! (op->type & MPEXPR_TYPE_OPERATOR)) \
+ : (op->type & MPEXPR_TYPE_WHOLEWORD))
+
+#define isasciispace(c) (isascii (c) && isspace (c))
+
+static int
+lookahead (struct mpexpr_parse_t *p, int prefix)
+{
+ const struct mpexpr_operator_t *op, *op_found;
+ size_t oplen, oplen_found, wlen;
+ int i;
+
+ /* skip white space */
+ while (p->elen > 0 && isasciispace (*p->e))
+ p->e++, p->elen--;
+
+ if (p->elen == 0)
+ {
+ TRACE (printf ("lookahead EOF\n"));
+ p->token = TOKEN_EOF;
+ return 1;
+ }
+
+ DATA_SPACE ();
+
+ /* Get extent of whole word. */
+ for (wlen = 0; wlen < p->elen; wlen++)
+ if (! isasciicsym (p->e[wlen]))
+ break;
+
+ TRACE (printf ("lookahead at: \"%.*s\" length %u, word %u\n",
+ (int) p->elen, p->e, p->elen, wlen));
+
+ op_found = NULL;
+ oplen_found = 0;
+ for (op = p->table; op->name != NULL; op++)
+ {
+ if (op->type == MPEXPR_TYPE_NEW_TABLE)
+ {
+ printf ("new\n");
+ op = (struct mpexpr_operator_t *) op->name - 1;
+ continue;
+ }
+
+ oplen = strlen (op->name);
+ if (! ((WHOLEWORD (op) ? wlen == oplen : p->elen >= oplen)
+ && memcmp (p->e, op->name, oplen) == 0))
+ continue;
+
+ /* Shorter matches don't replace longer previous ones. */
+ if (op_found && oplen < oplen_found)
+ continue;
+
+ /* On a match of equal length to a previous one, the old match isn't
+ replaced if it has the preferred prefix, and if it doesn't then
+ it's not replaced if the new one also doesn't. */
+ if (op_found && oplen == oplen_found
+ && ((op_found->type & MPEXPR_TYPE_PREFIX) == prefix
+ || (op->type & MPEXPR_TYPE_PREFIX) != prefix))
+ continue;
+
+ /* This is now either the first match seen, or a longer than previous
+ match, or an equal to previous one but with a preferred prefix. */
+ op_found = op;
+ oplen_found = oplen;
+ }
+
+ if (op_found)
+ {
+ p->e += oplen_found, p->elen -= oplen_found;
+
+ if (op_found->type == MPEXPR_TYPE_VARIABLE)
+ {
+ if (p->elen == 0)
+ ERROR ("end of string expecting a variable",
+ MPEXPR_RESULT_PARSE_ERROR);
+ i = p->e[0] - 'a';
+ if (i < 0 || i >= MPEXPR_VARIABLES)
+ ERROR ("bad variable name", MPEXPR_RESULT_BAD_VARIABLE);
+ goto variable;
+ }
+
+ if (op_found->precedence == 0)
+ {
+ TRACE (printf ("lookahead function: %s\n", op_found->name));
+ p->token = TOKEN_FUNCTION;
+ p->token_op = op_found;
+ return 1;
+ }
+ else
+ {
+ TRACE (printf ("lookahead operator: %s\n", op_found->name));
+ p->token = TOKEN_OPERATOR;
+ p->token_op = op_found;
+ return 1;
+ }
+ }
+
+ oplen = (*p->mpX_number) (SP+1, p->e, p->elen, p->base);
+ if (oplen != 0)
+ {
+ p->e += oplen, p->elen -= oplen;
+ p->token = TOKEN_VALUE;
+ DATA_PUSH ();
+ TRACE (MPX_TRACE ("lookahead number", SP));
+ return 1;
+ }
+
+ /* Maybe an unprefixed one character variable */
+ i = p->e[0] - 'a';
+ if (wlen == 1 && i >= 0 && i < MPEXPR_VARIABLES)
+ {
+ variable:
+ p->e++, p->elen--;
+ if (p->var[i] == NULL)
+ ERROR ("NULL variable", MPEXPR_RESULT_BAD_VARIABLE);
+ TRACE (printf ("lookahead variable: var[%d] = ", i);
+ MPX_TRACE ("", p->var[i]));
+ p->token = TOKEN_VALUE;
+ DATA_PUSH ();
+ (*p->mpX_set) (SP, p->var[i]);
+ return 1;
+ }
+
+ ERROR ("no token matched", MPEXPR_RESULT_PARSE_ERROR);
+
+ done:
+ return 0;
+}
+
+
+/* control stack current top element */
+#define CP (p->control_stack + p->control_top)
+
+/* make sure there's room for another control element above current top */
+#define CONTROL_SPACE() \
+ do { \
+ if (p->control_top + 1 >= p->control_alloc) \
+ { \
+ TRACE (printf ("grow control stack from %d\n", p->control_alloc)); \
+ REALLOC (p->control_stack, p->control_alloc, 20, \
+ struct mpexpr_control_t); \
+ } \
+ } while (0)
+
+/* Push an operator on the control stack, claiming currently to have the
+ given number of args ready. Local variable "op" is used in case opptr is
+ a reference through CP. */
+#define CONTROL_PUSH(opptr,args) \
+ do { \
+ const struct mpexpr_operator_t *op = opptr; \
+ struct mpexpr_control_t *cp; \
+ CONTROL_SPACE (); \
+ p->control_top++; \
+ ASSERT (p->control_top < p->control_alloc); \
+ cp = CP; \
+ cp->op = op; \
+ cp->argcount = (args); \
+ TRACE_CONTROL("control stack push:"); \
+ } while (0)
+
+/* The special operator_done is never popped, so top>=0 will hold. */
+#define CONTROL_POP() \
+ do { \
+ p->control_top--; \
+ ASSERT (p->control_top >= 0); \
+ TRACE_CONTROL ("control stack pop:"); \
+ } while (0)
+
+#define TRACE_CONTROL(str) \
+ TRACE ({ \
+ int i; \
+ printf ("%s depth %d:", str, p->control_top); \
+ for (i = 0; i <= p->control_top; i++) \
+ printf (" \"%s\"(%d)", \
+ p->control_stack[i].op->name, \
+ p->control_stack[i].argcount); \
+ printf ("\n"); \
+ });
+
+
+#define LOOKAHEAD(prefix) \
+ do { \
+ if (! lookahead (p, prefix)) \
+ goto done; \
+ } while (0)
+
+#define CHECK_UI(n) \
+ do { \
+ if (! (*p->mpX_ulong_p) (n)) \
+ ERROR ("operand doesn't fit ulong", MPEXPR_RESULT_NOT_UI); \
+ } while (0)
+
+#define CHECK_ARGCOUNT(str,n) \
+ do { \
+ if (CP->argcount != (n)) \
+ { \
+ TRACE (printf ("wrong number of arguments for %s, got %d want %d", \
+ str, CP->argcount, n)); \
+ ERROR ("", MPEXPR_RESULT_PARSE_ERROR); \
+ } \
+ } while (0)
+
+
+/* There's two basic states here. In both p->token is the next token.
+
+ "another_expr" is when a whole expression should be parsed. This means a
+ literal or variable value possibly followed by an operator, or a function
+ or prefix operator followed by a further whole expression.
+
+ "another_operator" is when an expression has been parsed and its value is
+ on the top of the data stack (SP) and an optional further postfix or
+ infix operator should be parsed.
+
+ In "another_operator" precedences determine whether to push the operator
+ onto the control stack, or instead go to "apply_control" to reduce the
+ operator currently on top of the control stack.
+
+ When an operator has both a prefix and postfix/infix form, a LOOKAHEAD()
+ for "another_expr" will seek the prefix form, a LOOKAHEAD() for
+ "another_operator" will seek the postfix/infix form. The grammar is
+ simple enough that the next state is known before reading the next token.
+
+ Argument count checking guards against functions consuming the wrong
+ number of operands from the data stack. The same checks are applied to
+ operators, but will always pass since a UNARY or BINARY will only ever
+ parse with the correct operands. */
+
+int
+mpexpr_evaluate (struct mpexpr_parse_t *p)
+{
+ void *(*allocate_func) (size_t);
+ void *(*reallocate_func) (void *, size_t, size_t);
+ void (*free_func) (void *, size_t);
+
+ mp_get_memory_functions (&allocate_func, &reallocate_func, &free_func);
+
+ TRACE (printf ("mpexpr_evaluate() base %d \"%.*s\"\n",
+ p->base, (int) p->elen, p->e));
+
+ /* "done" is a special sentinel at the bottom of the control stack,
+ precedence -1 is lower than any normal operator. */
+ {
+ static const struct mpexpr_operator_t operator_done
+ = { "DONE", NULL, MPEXPR_TYPE_DONE, -1 };
+
+ p->control_alloc = 20;
+ p->control_stack = ALLOCATE_FUNC_TYPE (p->control_alloc,
+ struct mpexpr_control_t);
+ p->control_top = 0;
+ CP->op = &operator_done;
+ CP->argcount = 1;
+ }
+
+ p->data_inited = 0;
+ p->data_alloc = 20;
+ p->data_stack = ALLOCATE_FUNC_TYPE (p->data_alloc, union mpX_t);
+ p->data_top = -1;
+
+ p->error_code = MPEXPR_RESULT_OK;
+
+
+ another_expr_lookahead:
+ LOOKAHEAD (MPEXPR_TYPE_PREFIX);
+ TRACE (printf ("another expr\n"));
+
+ /*another_expr:*/
+ switch (p->token) {
+ case TOKEN_VALUE:
+ goto another_operator_lookahead;
+
+ case TOKEN_OPERATOR:
+ TRACE (printf ("operator %s\n", p->token_op->name));
+ if (! (p->token_op->type & MPEXPR_TYPE_PREFIX))
+ ERROR ("expected a prefix operator", MPEXPR_RESULT_PARSE_ERROR);
+
+ CONTROL_PUSH (p->token_op, 1);
+ goto another_expr_lookahead;
+
+ case TOKEN_FUNCTION:
+ CONTROL_PUSH (p->token_op, 1);
+
+ if (p->token_op->type & MPEXPR_TYPE_CONSTANT)
+ goto apply_control_lookahead;
+
+ LOOKAHEAD (MPEXPR_TYPE_PREFIX);
+ if (! (p->token == TOKEN_OPERATOR
+ && p->token_op->type == MPEXPR_TYPE_OPENPAREN))
+ ERROR ("expected open paren for function", MPEXPR_RESULT_PARSE_ERROR);
+
+ TRACE (printf ("open paren for function \"%s\"\n", CP->op->name));
+
+ if ((CP->op->type & MPEXPR_TYPE_MASK_ARGCOUNT) == MPEXPR_TYPE_NARY(0))
+ {
+ LOOKAHEAD (0);
+ if (! (p->token == TOKEN_OPERATOR
+ && p->token_op->type == MPEXPR_TYPE_CLOSEPAREN))
+ ERROR ("expected close paren for 0ary function",
+ MPEXPR_RESULT_PARSE_ERROR);
+ goto apply_control_lookahead;
+ }
+
+ goto another_expr_lookahead;
+ }
+ ERROR ("unrecognised start of expression", MPEXPR_RESULT_PARSE_ERROR);
+
+
+ another_operator_lookahead:
+ LOOKAHEAD (0);
+ another_operator:
+ TRACE (printf ("another operator maybe: %s\n", TOKEN_NAME(p->token)));
+
+ switch (p->token) {
+ case TOKEN_EOF:
+ goto apply_control;
+
+ case TOKEN_OPERATOR:
+ /* The next operator is compared to the one on top of the control stack.
+ If the next is lower precedence, or the same precedence and not
+ right-associative, then reduce using the control stack and look at
+ the next operator again later. */
+
+#define PRECEDENCE_TEST_REDUCE(tprec,cprec,ttype,ctype) \
+ ((tprec) < (cprec) \
+ || ((tprec) == (cprec) && ! ((ttype) & MPEXPR_TYPE_RIGHTASSOC)))
+
+ if (PRECEDENCE_TEST_REDUCE (p->token_op->precedence, CP->op->precedence,
+ p->token_op->type, CP->op->type))
+ {
+ TRACE (printf ("defer operator: %s (prec %d vs %d, type 0x%X)\n",
+ p->token_op->name,
+ p->token_op->precedence, CP->op->precedence,
+ p->token_op->type));
+ goto apply_control;
+ }
+
+ /* An argsep is a binary operator, but is never pushed on the control
+ stack, it just accumulates an extra argument for a function. */
+ if (p->token_op->type == MPEXPR_TYPE_ARGSEP)
+ {
+ if (CP->op->precedence != 0)
+ ERROR ("ARGSEP not in a function call", MPEXPR_RESULT_PARSE_ERROR);
+
+ TRACE (printf ("argsep for function \"%s\"(%d)\n",
+ CP->op->name, CP->argcount));
+
+#define IS_PAIRWISE(type) \
+ (((type) & (MPEXPR_TYPE_MASK_ARGCOUNT | MPEXPR_TYPE_PAIRWISE)) \
+ == (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_PAIRWISE))
+
+ if (IS_PAIRWISE (CP->op->type) && CP->argcount >= 2)
+ {
+ TRACE (printf (" will reduce pairwise now\n"));
+ CP->argcount--;
+ CONTROL_PUSH (CP->op, 2);
+ goto apply_control;
+ }
+
+ CP->argcount++;
+ goto another_expr_lookahead;
+ }
+
+ switch (p->token_op->type & MPEXPR_TYPE_MASK_ARGCOUNT) {
+ case MPEXPR_TYPE_NARY(1):
+ /* Postfix unary operators can always be applied immediately. The
+ easiest way to do this is just push it on the control stack and go
+ to the normal control stack reduction code. */
+
+ TRACE (printf ("postfix unary operator: %s\n", p->token_op->name));
+ if (p->token_op->type & MPEXPR_TYPE_PREFIX)
+ ERROR ("prefix unary operator used postfix",
+ MPEXPR_RESULT_PARSE_ERROR);
+ CONTROL_PUSH (p->token_op, 1);
+ goto apply_control_lookahead;
+
+ case MPEXPR_TYPE_NARY(2):
+ CONTROL_PUSH (p->token_op, 2);
+ goto another_expr_lookahead;
+
+ case MPEXPR_TYPE_NARY(3):
+ CONTROL_PUSH (p->token_op, 1);
+ goto another_expr_lookahead;
+ }
+
+ TRACE (printf ("unrecognised operator \"%s\" type: 0x%X",
+ CP->op->name, CP->op->type));
+ ERROR ("", MPEXPR_RESULT_PARSE_ERROR);
+ break;
+
+ default:
+ TRACE (printf ("expecting an operator, got token %d", p->token));
+ ERROR ("", MPEXPR_RESULT_PARSE_ERROR);
+ }
+
+
+ apply_control_lookahead:
+ LOOKAHEAD (0);
+ apply_control:
+ /* Apply the top element CP of the control stack. Data values are SP,
+ SP-1, etc. Result is left as stack top SP after popping consumed
+ values.
+
+ The use of sp as a duplicate of SP will help compilers that can't
+ otherwise recognise the various uses of SP as common subexpressions. */
+
+ TRACE (printf ("apply control: nested %d, \"%s\" 0x%X, %d args\n",
+ p->control_top, CP->op->name, CP->op->type, CP->argcount));
+
+ TRACE (printf ("apply 0x%X-ary\n",
+ CP->op->type & MPEXPR_TYPE_MASK_ARGCOUNT));
+ switch (CP->op->type & MPEXPR_TYPE_MASK_ARGCOUNT) {
+ case MPEXPR_TYPE_NARY(0):
+ {
+ mpX_ptr sp;
+ DATA_SPACE ();
+ DATA_PUSH ();
+ sp = SP;
+ switch (CP->op->type & MPEXPR_TYPE_MASK_ARGSTYLE) {
+ case 0:
+ (* (mpexpr_fun_0ary_t) CP->op->fun) (sp);
+ break;
+ case MPEXPR_TYPE_RESULT_INT:
+ (*p->mpX_set_si) (sp, (long) (* (mpexpr_fun_i_0ary_t) CP->op->fun) ());
+ break;
+ default:
+ ERROR ("unrecognised 0ary argument calling style",
+ MPEXPR_RESULT_BAD_TABLE);
+ }
+ }
+ break;
+
+ case MPEXPR_TYPE_NARY(1):
+ {
+ mpX_ptr sp = SP;
+ CHECK_ARGCOUNT ("unary", 1);
+ TRACE (MPX_TRACE ("before", sp));
+
+ switch (CP->op->type & MPEXPR_TYPE_MASK_SPECIAL) {
+ case 0:
+ /* not a special */
+ break;
+
+ case MPEXPR_TYPE_DONE & MPEXPR_TYPE_MASK_SPECIAL:
+ TRACE (printf ("special done\n"));
+ goto done;
+
+ case MPEXPR_TYPE_LOGICAL_NOT & MPEXPR_TYPE_MASK_SPECIAL:
+ TRACE (printf ("special logical not\n"));
+ (*p->mpX_set_si)
+ (sp, (long) ((* (mpexpr_fun_i_unary_t) CP->op->fun) (sp) == 0));
+ goto apply_control_done;
+
+ case MPEXPR_TYPE_CLOSEPAREN & MPEXPR_TYPE_MASK_SPECIAL:
+ CONTROL_POP ();
+ if (CP->op->type == MPEXPR_TYPE_OPENPAREN)
+ {
+ TRACE (printf ("close paren matching open paren\n"));
+ CONTROL_POP ();
+ goto another_operator;
+ }
+ if (CP->op->precedence == 0)
+ {
+ TRACE (printf ("close paren for function\n"));
+ goto apply_control;
+ }
+ ERROR ("unexpected close paren", MPEXPR_RESULT_PARSE_ERROR);
+
+ default:
+ TRACE (printf ("unrecognised special unary operator 0x%X",
+ CP->op->type & MPEXPR_TYPE_MASK_SPECIAL));
+ ERROR ("", MPEXPR_RESULT_BAD_TABLE);
+ }
+
+ switch (CP->op->type & MPEXPR_TYPE_MASK_ARGSTYLE) {
+ case 0:
+ (* (mpexpr_fun_unary_t) CP->op->fun) (sp, sp);
+ break;
+ case MPEXPR_TYPE_LAST_UI:
+ CHECK_UI (sp);
+ (* (mpexpr_fun_unary_ui_t) CP->op->fun)
+ (sp, (*p->mpX_get_ui) (sp));
+ break;
+ case MPEXPR_TYPE_RESULT_INT:
+ (*p->mpX_set_si)
+ (sp, (long) (* (mpexpr_fun_i_unary_t) CP->op->fun) (sp));
+ break;
+ case MPEXPR_TYPE_RESULT_INT | MPEXPR_TYPE_LAST_UI:
+ CHECK_UI (sp);
+ (*p->mpX_set_si)
+ (sp,
+ (long) (* (mpexpr_fun_i_unary_ui_t) CP->op->fun)
+ ((*p->mpX_get_ui) (sp)));
+ break;
+ default:
+ ERROR ("unrecognised unary argument calling style",
+ MPEXPR_RESULT_BAD_TABLE);
+ }
+ }
+ break;
+
+ case MPEXPR_TYPE_NARY(2):
+ {
+ mpX_ptr sp;
+
+ /* pairwise functions are allowed to have just one argument */
+ if ((CP->op->type & MPEXPR_TYPE_PAIRWISE)
+ && CP->op->precedence == 0
+ && CP->argcount == 1)
+ goto apply_control_done;
+
+ CHECK_ARGCOUNT ("binary", 2);
+ DATA_POP (1);
+ sp = SP;
+ TRACE (MPX_TRACE ("lhs", sp);
+ MPX_TRACE ("rhs", sp+1));
+
+ if (CP->op->type & MPEXPR_TYPE_MASK_CMP)
+ {
+ int type = CP->op->type;
+ int cmp = (* (mpexpr_fun_i_binary_t) CP->op->fun)
+ (sp, sp+1);
+ (*p->mpX_set_si)
+ (sp,
+ (long)
+ (( (cmp < 0) & ((type & MPEXPR_TYPE_MASK_CMP_LT) != 0))
+ | ((cmp == 0) & ((type & MPEXPR_TYPE_MASK_CMP_EQ) != 0))
+ | ((cmp > 0) & ((type & MPEXPR_TYPE_MASK_CMP_GT) != 0))));
+ goto apply_control_done;
+ }
+
+ switch (CP->op->type & MPEXPR_TYPE_MASK_SPECIAL) {
+ case 0:
+ /* not a special */
+ break;
+
+ case MPEXPR_TYPE_QUESTION & MPEXPR_TYPE_MASK_SPECIAL:
+ ERROR ("'?' without ':'", MPEXPR_RESULT_PARSE_ERROR);
+
+ case MPEXPR_TYPE_COLON & MPEXPR_TYPE_MASK_SPECIAL:
+ TRACE (printf ("special colon\n"));
+ CONTROL_POP ();
+ if (CP->op->type != MPEXPR_TYPE_QUESTION)
+ ERROR ("':' without '?'", MPEXPR_RESULT_PARSE_ERROR);
+
+ CP->argcount--;
+ DATA_POP (1);
+ sp--;
+ TRACE (MPX_TRACE ("query", sp);
+ MPX_TRACE ("true", sp+1);
+ MPX_TRACE ("false", sp+2));
+ (*p->mpX_set)
+ (sp, (* (mpexpr_fun_i_unary_t) CP->op->fun) (sp)
+ ? sp+1 : sp+2);
+ goto apply_control_done;
+
+ case MPEXPR_TYPE_LOGICAL_AND & MPEXPR_TYPE_MASK_SPECIAL:
+ TRACE (printf ("special logical and\n"));
+ (*p->mpX_set_si)
+ (sp,
+ (long)
+ ((* (mpexpr_fun_i_unary_t) CP->op->fun) (sp)
+ && (* (mpexpr_fun_i_unary_t) CP->op->fun) (sp+1)));
+ goto apply_control_done;
+
+ case MPEXPR_TYPE_LOGICAL_OR & MPEXPR_TYPE_MASK_SPECIAL:
+ TRACE (printf ("special logical and\n"));
+ (*p->mpX_set_si)
+ (sp,
+ (long)
+ ((* (mpexpr_fun_i_unary_t) CP->op->fun) (sp)
+ || (* (mpexpr_fun_i_unary_t) CP->op->fun) (sp+1)));
+ goto apply_control_done;
+
+ case MPEXPR_TYPE_MAX & MPEXPR_TYPE_MASK_SPECIAL:
+ TRACE (printf ("special max\n"));
+ if ((* (mpexpr_fun_i_binary_t) CP->op->fun) (sp, sp+1) < 0)
+ (*p->mpX_swap) (sp, sp+1);
+ goto apply_control_done;
+ case MPEXPR_TYPE_MIN & MPEXPR_TYPE_MASK_SPECIAL:
+ TRACE (printf ("special min\n"));
+ if ((* (mpexpr_fun_i_binary_t) CP->op->fun) (sp, sp+1) > 0)
+ (*p->mpX_swap) (sp, sp+1);
+ goto apply_control_done;
+
+ default:
+ ERROR ("unrecognised special binary operator",
+ MPEXPR_RESULT_BAD_TABLE);
+ }
+
+ switch (CP->op->type & MPEXPR_TYPE_MASK_ARGSTYLE) {
+ case 0:
+ (* (mpexpr_fun_binary_t) CP->op->fun) (sp, sp, sp+1);
+ break;
+ case MPEXPR_TYPE_LAST_UI:
+ CHECK_UI (sp+1);
+ (* (mpexpr_fun_binary_ui_t) CP->op->fun)
+ (sp, sp, (*p->mpX_get_ui) (sp+1));
+ break;
+ case MPEXPR_TYPE_RESULT_INT:
+ (*p->mpX_set_si)
+ (sp,
+ (long) (* (mpexpr_fun_i_binary_t) CP->op->fun) (sp, sp+1));
+ break;
+ case MPEXPR_TYPE_LAST_UI | MPEXPR_TYPE_RESULT_INT:
+ CHECK_UI (sp+1);
+ (*p->mpX_set_si)
+ (sp,
+ (long) (* (mpexpr_fun_i_binary_ui_t) CP->op->fun)
+ (sp, (*p->mpX_get_ui) (sp+1)));
+ break;
+ default:
+ ERROR ("unrecognised binary argument calling style",
+ MPEXPR_RESULT_BAD_TABLE);
+ }
+ }
+ break;
+
+ case MPEXPR_TYPE_NARY(3):
+ {
+ mpX_ptr sp;
+
+ CHECK_ARGCOUNT ("ternary", 3);
+ DATA_POP (2);
+ sp = SP;
+ TRACE (MPX_TRACE ("arg1", sp);
+ MPX_TRACE ("arg2", sp+1);
+ MPX_TRACE ("arg3", sp+1));
+
+ switch (CP->op->type & MPEXPR_TYPE_MASK_ARGSTYLE) {
+ case 0:
+ (* (mpexpr_fun_ternary_t) CP->op->fun) (sp, sp, sp+1, sp+2);
+ break;
+ case MPEXPR_TYPE_LAST_UI:
+ CHECK_UI (sp+2);
+ (* (mpexpr_fun_ternary_ui_t) CP->op->fun)
+ (sp, sp, sp+1, (*p->mpX_get_ui) (sp+2));
+ break;
+ case MPEXPR_TYPE_RESULT_INT:
+ (*p->mpX_set_si)
+ (sp,
+ (long) (* (mpexpr_fun_i_ternary_t) CP->op->fun)
+ (sp, sp+1, sp+2));
+ break;
+ case MPEXPR_TYPE_LAST_UI | MPEXPR_TYPE_RESULT_INT:
+ CHECK_UI (sp+2);
+ (*p->mpX_set_si)
+ (sp,
+ (long) (* (mpexpr_fun_i_ternary_ui_t) CP->op->fun)
+ (sp, sp+1, (*p->mpX_get_ui) (sp+2)));
+ break;
+ default:
+ ERROR ("unrecognised binary argument calling style",
+ MPEXPR_RESULT_BAD_TABLE);
+ }
+ }
+ break;
+
+ default:
+ TRACE (printf ("unrecognised operator type: 0x%X\n", CP->op->type));
+ ERROR ("", MPEXPR_RESULT_PARSE_ERROR);
+ }
+
+ apply_control_done:
+ TRACE (MPX_TRACE ("result", SP));
+ CONTROL_POP ();
+ goto another_operator;
+
+ done:
+ if (p->error_code == MPEXPR_RESULT_OK)
+ {
+ if (p->data_top != 0)
+ {
+ TRACE (printf ("data stack want top at 0, got %d\n", p->data_top));
+ p->error_code = MPEXPR_RESULT_PARSE_ERROR;
+ }
+ else
+ (*p->mpX_set_or_swap) (p->res, SP);
+ }
+
+ {
+ int i;
+ for (i = 0; i < p->data_inited; i++)
+ {
+ TRACE (printf ("clear %d\n", i));
+ (*p->mpX_clear) (p->data_stack+i);
+ }
+ }
+
+ FREE_FUNC_TYPE (p->data_stack, p->data_alloc, union mpX_t);
+ FREE_FUNC_TYPE (p->control_stack, p->control_alloc, struct mpexpr_control_t);
+
+ return p->error_code;
+}
diff --git a/gmp/demos/expr/expr.h b/gmp/demos/expr/expr.h
new file mode 100644
index 0000000000..d3b7c77cc3
--- /dev/null
+++ b/gmp/demos/expr/expr.h
@@ -0,0 +1,142 @@
+/* Header for expression evaluation.
+
+Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#ifndef __EXPR_H__
+#define __EXPR_H__
+
+#define MPEXPR_RESULT_OK 0
+#define MPEXPR_RESULT_BAD_VARIABLE 1
+#define MPEXPR_RESULT_BAD_TABLE 2
+#define MPEXPR_RESULT_PARSE_ERROR 3
+#define MPEXPR_RESULT_NOT_UI 4
+
+
+/* basic types */
+#define MPEXPR_TYPE_NARY(n) ((n) * 0x0100)
+#define MPEXPR_TYPE_MASK_ARGCOUNT MPEXPR_TYPE_NARY(0xF)
+#define MPEXPR_TYPE_0ARY MPEXPR_TYPE_NARY(0)
+#define MPEXPR_TYPE_UNARY MPEXPR_TYPE_NARY(1)
+#define MPEXPR_TYPE_BINARY MPEXPR_TYPE_NARY(2)
+#define MPEXPR_TYPE_TERNARY MPEXPR_TYPE_NARY(3)
+
+/* options for all */
+#define MPEXPR_TYPE_LAST_UI 0x0010
+#define MPEXPR_TYPE_RESULT_INT 0x0020
+#define MPEXPR_TYPE_MASK_ARGSTYLE 0x0030
+
+#define MPEXPR_TYPE_UNARY_UI (MPEXPR_TYPE_UNARY | MPEXPR_TYPE_LAST_UI)
+#define MPEXPR_TYPE_I_UNARY (MPEXPR_TYPE_UNARY | MPEXPR_TYPE_RESULT_INT)
+#define MPEXPR_TYPE_I_UNARY_UI (MPEXPR_TYPE_I_UNARY | MPEXPR_TYPE_LAST_UI)
+#define MPEXPR_TYPE_BINARY_UI (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_LAST_UI)
+#define MPEXPR_TYPE_I_BINARY (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_RESULT_INT)
+#define MPEXPR_TYPE_I_BINARY_UI (MPEXPR_TYPE_I_BINARY| MPEXPR_TYPE_LAST_UI)
+#define MPEXPR_TYPE_TERNARY_UI (MPEXPR_TYPE_TERNARY | MPEXPR_TYPE_LAST_UI)
+#define MPEXPR_TYPE_I_TERNARY (MPEXPR_TYPE_TERNARY | MPEXPR_TYPE_RESULT_INT)
+#define MPEXPR_TYPE_I_TERNARY_UI (MPEXPR_TYPE_I_TERNARY|MPEXPR_TYPE_LAST_UI)
+
+/* 0ary with options */
+#define MPEXPR_TYPE_CONSTANT (MPEXPR_TYPE_0ARY | 0x0040)
+
+/* unary options */
+#define MPEXPR_TYPE_PREFIX 0x0040
+
+/* binary options */
+#define MPEXPR_TYPE_RIGHTASSOC 0x0040
+#define MPEXPR_TYPE_PAIRWISE 0x0080
+
+#define MPEXPR_TYPE_MASK_SPECIAL 0x000F
+
+/* unary specials */
+#define MPEXPR_TYPE_NEW_TABLE (MPEXPR_TYPE_UNARY | 0x001)
+#define MPEXPR_TYPE_DONE (MPEXPR_TYPE_UNARY | 0x002)
+#define MPEXPR_TYPE_VARIABLE (MPEXPR_TYPE_UNARY | 0x003)
+#define MPEXPR_TYPE_LOGICAL_NOT (MPEXPR_TYPE_UNARY | 0x004)
+#define MPEXPR_TYPE_CLOSEPAREN (MPEXPR_TYPE_UNARY | 0x005)
+#define MPEXPR_TYPE_OPENPAREN (MPEXPR_TYPE_CLOSEPAREN | MPEXPR_TYPE_PREFIX)
+
+/* binary specials */
+#define MPEXPR_TYPE_LOGICAL_AND (MPEXPR_TYPE_BINARY | 0x001)
+#define MPEXPR_TYPE_LOGICAL_OR (MPEXPR_TYPE_BINARY | 0x002)
+#define MPEXPR_TYPE_ARGSEP (MPEXPR_TYPE_BINARY | 0x003)
+#define MPEXPR_TYPE_QUESTION (MPEXPR_TYPE_BINARY | 0x004)
+#define MPEXPR_TYPE_COLON (MPEXPR_TYPE_BINARY | 0x005)
+#define MPEXPR_TYPE_MAX (MPEXPR_TYPE_BINARY | 0x006)
+#define MPEXPR_TYPE_MIN (MPEXPR_TYPE_BINARY | 0x007)
+#define MPEXPR_TYPE_MASK_CMP 0x008
+#define MPEXPR_TYPE_MASK_CMP_LT 0x001
+#define MPEXPR_TYPE_MASK_CMP_EQ 0x002
+#define MPEXPR_TYPE_MASK_CMP_GT 0x004
+#define MPEXPR_TYPE_CMP_LT (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_MASK_CMP \
+ | MPEXPR_TYPE_MASK_CMP_LT)
+#define MPEXPR_TYPE_CMP_EQ (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_MASK_CMP \
+ | MPEXPR_TYPE_MASK_CMP_EQ)
+#define MPEXPR_TYPE_CMP_GT (MPEXPR_TYPE_BINARY | MPEXPR_TYPE_MASK_CMP \
+ | MPEXPR_TYPE_MASK_CMP_GT)
+#define MPEXPR_TYPE_CMP_LE (MPEXPR_TYPE_CMP_LT | MPEXPR_TYPE_MASK_CMP_EQ)
+#define MPEXPR_TYPE_CMP_NE (MPEXPR_TYPE_CMP_LT | MPEXPR_TYPE_MASK_CMP_GT)
+#define MPEXPR_TYPE_CMP_GE (MPEXPR_TYPE_CMP_GT | MPEXPR_TYPE_MASK_CMP_EQ)
+
+/* parse options */
+#define MPEXPR_TYPE_WHOLEWORD 0x1000
+#define MPEXPR_TYPE_OPERATOR 0x2000
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*mpexpr_fun_t) (void);
+
+struct mpexpr_operator_t {
+ const char *name;
+ mpexpr_fun_t fun;
+ int type;
+ int precedence;
+};
+
+
+int mpf_expr_a (const struct mpexpr_operator_t *, mpf_ptr, int,
+ unsigned long, const char *, size_t, mpf_srcptr [26]);
+int mpf_expr (mpf_ptr, int, const char *, ...);
+
+int mpq_expr_a (const struct mpexpr_operator_t *, mpq_ptr,
+ int, const char *, size_t, mpq_srcptr [26]);
+int mpq_expr (mpq_ptr, int, const char *, ...);
+
+int mpz_expr_a (const struct mpexpr_operator_t *, mpz_ptr, int,
+ const char *, size_t, mpz_srcptr [26]);
+int mpz_expr (mpz_ptr, int, const char *, ...);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/gmp/demos/expr/exprf.c b/gmp/demos/expr/exprf.c
new file mode 100644
index 0000000000..1f7e21f893
--- /dev/null
+++ b/gmp/demos/expr/exprf.c
@@ -0,0 +1,123 @@
+/* mpf expression evaluation
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <string.h>
+#include "gmp.h"
+#include "expr-impl.h"
+
+
+/* Change this to "#define TRACE(x) x" to get some traces. */
+#define TRACE(x)
+
+
+static int
+e_mpf_sgn (mpf_srcptr x)
+{
+ return mpf_sgn (x);
+}
+
+
+static const struct mpexpr_operator_t _mpf_expr_standard_table[] = {
+
+ { "**", (mpexpr_fun_t) mpf_pow_ui,
+ MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 },
+
+ { "!", (mpexpr_fun_t) e_mpf_sgn,
+ MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX, 210 },
+ { "-", (mpexpr_fun_t) mpf_neg,
+ MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
+
+ { "*", (mpexpr_fun_t) mpf_mul, MPEXPR_TYPE_BINARY, 200 },
+ { "/", (mpexpr_fun_t) mpf_div, MPEXPR_TYPE_BINARY, 200 },
+
+ { "+", (mpexpr_fun_t) mpf_add, MPEXPR_TYPE_BINARY, 190 },
+ { "-", (mpexpr_fun_t) mpf_sub, MPEXPR_TYPE_BINARY, 190 },
+
+ { "<<", (mpexpr_fun_t) mpf_mul_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
+ { ">>", (mpexpr_fun_t) mpf_div_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
+
+ { "<=", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_LE, 170 },
+ { "<", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_LT, 170 },
+ { ">=", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_GE, 170 },
+ { ">", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_GT, 170 },
+
+ { "==", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_EQ, 160 },
+ { "!=", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_CMP_NE, 160 },
+
+ { "&&", (mpexpr_fun_t) e_mpf_sgn, MPEXPR_TYPE_LOGICAL_AND, 120 },
+ { "||", (mpexpr_fun_t) e_mpf_sgn, MPEXPR_TYPE_LOGICAL_OR, 110 },
+
+ { ":", NULL, MPEXPR_TYPE_COLON, 101 },
+ { "?", (mpexpr_fun_t) e_mpf_sgn, MPEXPR_TYPE_QUESTION, 100 },
+
+ { ")", NULL, MPEXPR_TYPE_CLOSEPAREN, 4 },
+ { "(", NULL, MPEXPR_TYPE_OPENPAREN, 3 },
+ { ",", NULL, MPEXPR_TYPE_ARGSEP, 2 },
+ { "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
+
+ { "abs", (mpexpr_fun_t) mpf_abs, MPEXPR_TYPE_UNARY },
+ { "ceil", (mpexpr_fun_t) mpf_ceil, MPEXPR_TYPE_UNARY },
+ { "cmp", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_I_BINARY },
+ { "eq", (mpexpr_fun_t) mpf_eq, MPEXPR_TYPE_I_TERNARY_UI },
+ { "floor", (mpexpr_fun_t) mpf_floor, MPEXPR_TYPE_UNARY },
+ { "integer_p",(mpexpr_fun_t) mpf_integer_p, MPEXPR_TYPE_I_UNARY },
+ { "max", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_MAX | MPEXPR_TYPE_PAIRWISE },
+ { "min", (mpexpr_fun_t) mpf_cmp, MPEXPR_TYPE_MIN | MPEXPR_TYPE_PAIRWISE },
+ { "reldiff", (mpexpr_fun_t) mpf_reldiff, MPEXPR_TYPE_BINARY },
+ { "sgn", (mpexpr_fun_t) e_mpf_sgn, MPEXPR_TYPE_I_UNARY },
+ { "sqrt", (mpexpr_fun_t) mpf_sqrt, MPEXPR_TYPE_UNARY },
+ { "trunc", (mpexpr_fun_t) mpf_trunc, MPEXPR_TYPE_UNARY },
+
+ { NULL }
+};
+
+const struct mpexpr_operator_t * const mpf_expr_standard_table
+= _mpf_expr_standard_table;
+
+
+int
+mpf_expr (mpf_ptr res, int base, const char *e, ...)
+{
+ mpf_srcptr var[MPEXPR_VARIABLES];
+ va_list ap;
+ int ret;
+ va_start (ap, e);
+
+ TRACE (printf ("mpf_expr(): base %d, %s\n", base, e));
+ ret = mpexpr_va_to_var ((void **) var, ap);
+ va_end (ap);
+
+ if (ret != MPEXPR_RESULT_OK)
+ return ret;
+
+ return mpf_expr_a (mpf_expr_standard_table, res, base,
+ mpf_get_prec (res), e, strlen(e), var);
+}
diff --git a/gmp/demos/expr/exprfa.c b/gmp/demos/expr/exprfa.c
new file mode 100644
index 0000000000..1918cb55cd
--- /dev/null
+++ b/gmp/demos/expr/exprfa.c
@@ -0,0 +1,191 @@
+/* mpf expression evaluation
+
+Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* Future: Bitwise "&", "|" and "&" could be done, if desired. Not sure
+ those functions would be much value though. */
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "expr-impl.h"
+
+
+/* Change this to "#define TRACE(x) x" to get some traces. */
+#define TRACE(x)
+
+
+static size_t
+e_mpf_number (mpf_ptr res, const char *e, size_t elen, int base)
+{
+ char *edup;
+ size_t i, ret, extra=0;
+ int mant_base, exp_base;
+ void *(*allocate_func) (size_t);
+ void (*free_func) (void *, size_t);
+
+ TRACE (printf ("mpf_number base=%d \"%.*s\"\n", base, (int) elen, e));
+
+ /* mpf_set_str doesn't currently accept 0x for hex in base==0, so do it
+ here instead. FIXME: Would prefer to let mpf_set_str handle this. */
+ if (base == 0 && elen >= 2 && e[0] == '0' && (e[1] == 'x' || e[1] == 'X'))
+ {
+ base = 16;
+ extra = 2;
+ e += extra;
+ elen -= extra;
+ }
+
+ if (base == 0)
+ mant_base = 10;
+ else if (base < 0)
+ mant_base = -base;
+ else
+ mant_base = base;
+
+ /* exponent in decimal if base is negative */
+ if (base < 0)
+ exp_base = 10;
+ else if (base == 0)
+ exp_base = 10;
+ else
+ exp_base = base;
+
+#define IS_EXPONENT(c) \
+ (c == '@' || (base <= 10 && base >= -10 && (e[i] == 'e' || e[i] == 'E')))
+
+ i = 0;
+ for (;;)
+ {
+ if (i >= elen)
+ goto parsed;
+ if (e[i] == '.')
+ break;
+ if (IS_EXPONENT (e[i]))
+ goto exponent;
+ if (! isasciidigit_in_base (e[i], mant_base))
+ goto parsed;
+ i++;
+ }
+
+ /* fraction */
+ i++;
+ for (;;)
+ {
+ if (i >= elen)
+ goto parsed;
+ if (IS_EXPONENT (e[i]))
+ goto exponent;
+ if (! isasciidigit_in_base (e[i], mant_base))
+ goto parsed;
+ i++;
+ }
+
+ exponent:
+ i++;
+ if (i >= elen)
+ goto parsed;
+ if (e[i] == '-')
+ i++;
+ for (;;)
+ {
+ if (i >= elen)
+ goto parsed;
+ if (! isasciidigit_in_base (e[i], exp_base))
+ break;
+ i++;
+ }
+
+ parsed:
+ TRACE (printf (" parsed i=%u \"%.*s\"\n", i, (int) i, e));
+
+ mp_get_memory_functions (&allocate_func, NULL, &free_func);
+ edup = (*allocate_func) (i+1);
+ memcpy (edup, e, i);
+ edup[i] = '\0';
+
+ if (mpf_set_str (res, edup, base) == 0)
+ ret = i + extra;
+ else
+ ret = 0;
+
+ (*free_func) (edup, i+1);
+ return ret;
+}
+
+static int
+e_mpf_ulong_p (mpf_srcptr f)
+{
+ return mpf_integer_p (f) && mpf_fits_ulong_p (f);
+}
+
+/* Don't want to change the precision of w, can only do an actual swap when
+ w and x have the same precision. */
+static void
+e_mpf_set_or_swap (mpf_ptr w, mpf_ptr x)
+{
+ if (mpf_get_prec (w) == mpf_get_prec (x))
+ mpf_swap (w, x);
+ else
+ mpf_set (w, x);
+}
+
+
+int
+mpf_expr_a (const struct mpexpr_operator_t *table,
+ mpf_ptr res, int base, unsigned long prec,
+ const char *e, size_t elen,
+ mpf_srcptr var[26])
+{
+ struct mpexpr_parse_t p;
+
+ p.table = table;
+ p.res = (mpX_ptr) res;
+ p.base = base;
+ p.prec = prec;
+ p.e = e;
+ p.elen = elen;
+ p.var = (mpX_srcptr *) var;
+
+ p.mpX_clear = (mpexpr_fun_one_t) mpf_clear;
+ p.mpX_ulong_p = (mpexpr_fun_i_unary_t) e_mpf_ulong_p;
+ p.mpX_get_ui = (mpexpr_fun_get_ui_t) mpf_get_ui;
+ p.mpX_init = (mpexpr_fun_unary_ui_t) mpf_init2;
+ p.mpX_number = (mpexpr_fun_number_t) e_mpf_number;
+ p.mpX_set = (mpexpr_fun_unary_t) mpf_set;
+ p.mpX_set_or_swap = (mpexpr_fun_unary_t) e_mpf_set_or_swap;
+ p.mpX_set_si = (mpexpr_fun_set_si_t) mpf_set_si;
+ p.mpX_swap = (mpexpr_fun_swap_t) mpf_swap;
+
+ return mpexpr_evaluate (&p);
+}
diff --git a/gmp/demos/expr/exprq.c b/gmp/demos/expr/exprq.c
new file mode 100644
index 0000000000..96432006ef
--- /dev/null
+++ b/gmp/demos/expr/exprq.c
@@ -0,0 +1,155 @@
+/* mpq expression evaluation
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <string.h>
+#include "gmp.h"
+#include "expr-impl.h"
+
+
+/* Change this to "#define TRACE(x) x" to get some traces. */
+#define TRACE(x)
+
+
+static void
+e_mpq_pow_ui (mpq_ptr r, mpq_srcptr b, unsigned long e)
+{
+ mpz_pow_ui (mpq_numref(r), mpq_numref(b), e);
+ mpz_pow_ui (mpq_denref(r), mpq_denref(b), e);
+}
+
+/* Wrapped because mpq_sgn is a macro. */
+static int
+e_mpq_sgn (mpq_srcptr x)
+{
+ return mpq_sgn (x);
+}
+
+/* Wrapped because mpq_equal only guarantees a non-zero return, whereas we
+ want 1 or 0 for == and !=. */
+static int
+e_mpq_equal (mpq_srcptr x, mpq_srcptr y)
+{
+ return mpq_equal (x, y) != 0;
+}
+static int
+e_mpq_notequal (mpq_srcptr x, mpq_srcptr y)
+{
+ return ! mpq_equal (x, y);
+}
+
+static void
+e_mpq_num (mpq_ptr w, mpq_srcptr x)
+{
+ if (w != x)
+ mpz_set (mpq_numref(w), mpq_numref(x));
+ mpz_set_ui (mpq_denref(w), 1L);
+}
+static void
+e_mpq_den (mpq_ptr w, mpq_srcptr x)
+{
+ if (w == x)
+ mpz_swap (mpq_numref(w), mpq_denref(w));
+ else
+ mpz_set (mpq_numref(w), mpq_denref(x));
+ mpz_set_ui (mpq_denref(w), 1L);
+}
+
+
+static const struct mpexpr_operator_t _mpq_expr_standard_table[] = {
+
+ { "**", (mpexpr_fun_t) e_mpq_pow_ui,
+ MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 },
+
+ { "!", (mpexpr_fun_t) e_mpq_sgn,
+ MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX, 210 },
+ { "-", (mpexpr_fun_t) mpq_neg,
+ MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
+
+ { "*", (mpexpr_fun_t) mpq_mul, MPEXPR_TYPE_BINARY, 200 },
+ { "/", (mpexpr_fun_t) mpq_div, MPEXPR_TYPE_BINARY, 200 },
+
+ { "+", (mpexpr_fun_t) mpq_add, MPEXPR_TYPE_BINARY, 190 },
+ { "-", (mpexpr_fun_t) mpq_sub, MPEXPR_TYPE_BINARY, 190 },
+
+ { "<<", (mpexpr_fun_t) mpq_mul_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
+ { ">>", (mpexpr_fun_t) mpq_div_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
+
+ { "<=", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_LE, 170 },
+ { "<", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_LT, 170 },
+ { ">=", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_GE, 170 },
+ { ">", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_GT, 170 },
+
+ { "==", (mpexpr_fun_t) e_mpq_equal, MPEXPR_TYPE_I_BINARY, 160 },
+ { "!=", (mpexpr_fun_t) e_mpq_notequal, MPEXPR_TYPE_I_BINARY, 160 },
+
+ { "&&", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_LOGICAL_AND, 120 },
+ { "||", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_LOGICAL_OR, 110 },
+
+ { ":", NULL, MPEXPR_TYPE_COLON, 101 },
+ { "?", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_QUESTION, 100 },
+
+ { ")", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_CLOSEPAREN, 4 },
+ { "(", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_OPENPAREN, 3 },
+ { ",", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_ARGSEP, 2 },
+ { "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
+
+ { "abs", (mpexpr_fun_t) mpq_abs, MPEXPR_TYPE_UNARY },
+ { "cmp", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_I_BINARY },
+ { "den", (mpexpr_fun_t) e_mpq_den, MPEXPR_TYPE_UNARY },
+ { "max", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_MAX | MPEXPR_TYPE_PAIRWISE },
+ { "min", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_MIN | MPEXPR_TYPE_PAIRWISE },
+ { "num", (mpexpr_fun_t) e_mpq_num, MPEXPR_TYPE_UNARY },
+ { "sgn", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_I_UNARY },
+
+ { NULL }
+};
+
+const struct mpexpr_operator_t * const mpq_expr_standard_table
+= _mpq_expr_standard_table;
+
+
+int
+mpq_expr (mpq_ptr res, int base, const char *e, ...)
+{
+ mpq_srcptr var[MPEXPR_VARIABLES];
+ va_list ap;
+ int ret;
+ va_start (ap, e);
+
+ TRACE (printf ("mpq_expr(): base %d, %s\n", base, e));
+ ret = mpexpr_va_to_var ((void **) var, ap);
+ va_end (ap);
+
+ if (ret != MPEXPR_RESULT_OK)
+ return ret;
+
+ return mpq_expr_a (mpq_expr_standard_table, res, base, e, strlen(e), var);
+}
diff --git a/gmp/demos/expr/exprqa.c b/gmp/demos/expr/exprqa.c
new file mode 100644
index 0000000000..f3b6ecb495
--- /dev/null
+++ b/gmp/demos/expr/exprqa.c
@@ -0,0 +1,100 @@
+/* mpq expression evaluation
+
+Copyright 2000, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include <stdio.h>
+#include "gmp.h"
+#include "expr-impl.h"
+
+
+static int
+e_mpq_ulong_p (mpq_srcptr q)
+{
+ return mpz_fits_ulong_p (mpq_numref (q))
+ && mpz_cmp_ui (mpq_denref (q), 1L) == 0;
+}
+
+/* get value as a ui, on the assumption it fits */
+static int
+e_mpq_get_ui_fits (mpq_srcptr q)
+{
+ return mpz_get_ui (mpq_numref (q));
+}
+
+static void
+e_mpq_set_si1 (mpq_ptr q, long num)
+{
+ mpq_set_si (q, num, 1L);
+}
+
+/* The same as mpz, but putting the result in the numerator. Negatives and
+ fractions aren't parsed here because '-' and '/' are operators. */
+static size_t
+e_mpq_number (mpq_ptr res, const char *e, size_t elen, int base)
+{
+ mpz_set_ui (mpq_denref (res), 1L);
+ return mpexpr_mpz_number (mpq_numref (res), e, elen, base);
+}
+
+
+/* ignoring prec */
+static void
+e_mpq_init (mpq_ptr q, unsigned long prec)
+{
+ mpq_init (q);
+}
+
+int
+mpq_expr_a (const struct mpexpr_operator_t *table,
+ mpq_ptr res, int base,
+ const char *e, size_t elen,
+ mpq_srcptr var[26])
+{
+ struct mpexpr_parse_t p;
+
+ p.table = table;
+ p.res = (mpX_ptr) res;
+ p.base = base;
+ p.e = e;
+ p.elen = elen;
+ p.var = (mpX_srcptr *) var;
+
+ p.mpX_clear = (mpexpr_fun_one_t) mpq_clear;
+ p.mpX_ulong_p = (mpexpr_fun_i_unary_t) e_mpq_ulong_p;
+ p.mpX_get_ui = (mpexpr_fun_get_ui_t) e_mpq_get_ui_fits;
+ p.mpX_init = (mpexpr_fun_unary_ui_t) e_mpq_init;
+ p.mpX_number = (mpexpr_fun_number_t) e_mpq_number;
+ p.mpX_set = (mpexpr_fun_unary_t) mpq_set;
+ p.mpX_set_or_swap = (mpexpr_fun_unary_t) mpq_swap;
+ p.mpX_set_si = (mpexpr_fun_set_si_t) e_mpq_set_si1;
+ p.mpX_swap = (mpexpr_fun_swap_t) mpq_swap;
+
+ return mpexpr_evaluate (&p);
+}
diff --git a/gmp/demos/expr/exprv.c b/gmp/demos/expr/exprv.c
new file mode 100644
index 0000000000..c25741b023
--- /dev/null
+++ b/gmp/demos/expr/exprv.c
@@ -0,0 +1,57 @@
+/* mpz expression evaluation, simple part */
+
+/*
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "expr-impl.h"
+
+
+int
+mpexpr_va_to_var (void *var[], va_list ap)
+{
+ int i = 0;
+ void *v;
+
+ for (;;)
+ {
+ v = va_arg (ap, void *);
+ if (v == NULL)
+ break;
+ if (i >= MPEXPR_VARIABLES)
+ return MPEXPR_RESULT_BAD_VARIABLE;
+ var[i++] = v;
+ }
+
+ while (i < MPEXPR_VARIABLES)
+ var[i++] = NULL;
+
+ return MPEXPR_RESULT_OK;
+}
diff --git a/gmp/demos/expr/exprz.c b/gmp/demos/expr/exprz.c
new file mode 100644
index 0000000000..bac1a9992e
--- /dev/null
+++ b/gmp/demos/expr/exprz.c
@@ -0,0 +1,206 @@
+/* mpz expression evaluation, simple part
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include "gmp.h"
+#include "expr-impl.h"
+
+
+/* Change this to "#define TRACE(x) x" to get some traces. */
+#define TRACE(x)
+
+
+/* These are macros, so need function wrappers. */
+static int
+e_mpz_sgn (mpz_srcptr x)
+{
+ return mpz_sgn (x);
+}
+static int
+e_mpz_odd_p (mpz_srcptr x)
+{
+ return mpz_odd_p (x);
+}
+static int
+e_mpz_even_p (mpz_srcptr x)
+{
+ return mpz_even_p (x);
+}
+
+/* These wrapped because MPEXPR_TYPE_I_ functions are expected to return
+ "int" whereas these return "unsigned long". */
+static void
+e_mpz_hamdist (mpz_ptr w, mpz_srcptr x, mpz_srcptr y)
+{
+ mpz_set_ui (w, mpz_hamdist (x, y));
+}
+static void
+e_mpz_popcount (mpz_ptr w, mpz_srcptr x)
+{
+ mpz_set_ui (w, mpz_popcount (x));
+}
+static void
+e_mpz_scan0 (mpz_ptr w, mpz_srcptr x, unsigned long start)
+{
+ mpz_set_ui (w, mpz_scan0 (x, start));
+}
+static void
+e_mpz_scan1 (mpz_ptr w, mpz_srcptr x, unsigned long start)
+{
+ mpz_set_ui (w, mpz_scan1 (x, start));
+}
+
+/* These wrapped because they're in-place whereas MPEXPR_TYPE_BINARY_UI
+ expects a separate source and destination. Actually the parser will
+ normally pass w==x anyway. */
+static void
+e_mpz_setbit (mpz_ptr w, mpz_srcptr x, unsigned long n)
+{
+ if (w != x)
+ mpz_set (w, x);
+ mpz_setbit (w, n);
+}
+static void
+e_mpz_clrbit (mpz_ptr w, mpz_srcptr x, unsigned long n)
+{
+ if (w != x)
+ mpz_set (w, x);
+ mpz_clrbit (w, n);
+}
+
+static const struct mpexpr_operator_t _mpz_expr_standard_table[] = {
+
+ { "**", (mpexpr_fun_t) mpz_pow_ui,
+ MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 },
+
+ { "~", (mpexpr_fun_t) mpz_com,
+ MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
+ { "!", (mpexpr_fun_t) e_mpz_sgn,
+ MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX, 210 },
+ { "-", (mpexpr_fun_t) mpz_neg,
+ MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
+
+ { "*", (mpexpr_fun_t) mpz_mul, MPEXPR_TYPE_BINARY, 200 },
+ { "/", (mpexpr_fun_t) mpz_tdiv_q, MPEXPR_TYPE_BINARY, 200 },
+ { "%", (mpexpr_fun_t) mpz_tdiv_r, MPEXPR_TYPE_BINARY, 200 },
+
+ { "+", (mpexpr_fun_t) mpz_add, MPEXPR_TYPE_BINARY, 190 },
+ { "-", (mpexpr_fun_t) mpz_sub, MPEXPR_TYPE_BINARY, 190 },
+
+ { "<<", (mpexpr_fun_t) mpz_mul_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
+ { ">>", (mpexpr_fun_t) mpz_tdiv_q_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
+
+ { "<=", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_LE, 170 },
+ { "<", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_LT, 170 },
+ { ">=", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_GE, 170 },
+ { ">", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_GT, 170 },
+
+ { "==", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_EQ, 160 },
+ { "!=", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_CMP_NE, 160 },
+
+ { "&", (mpexpr_fun_t) mpz_and, MPEXPR_TYPE_BINARY, 150 },
+ { "^", (mpexpr_fun_t) mpz_xor, MPEXPR_TYPE_BINARY, 140 },
+ { "|", (mpexpr_fun_t) mpz_ior, MPEXPR_TYPE_BINARY, 130 },
+ { "&&", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_LOGICAL_AND, 120 },
+ { "||", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_LOGICAL_OR, 110 },
+
+ { ":", NULL, MPEXPR_TYPE_COLON, 101 },
+ { "?", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_QUESTION, 100 },
+
+ { ")", NULL, MPEXPR_TYPE_CLOSEPAREN, 4 },
+ { "(", NULL, MPEXPR_TYPE_OPENPAREN, 3 },
+ { ",", NULL, MPEXPR_TYPE_ARGSEP, 2 },
+ { "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
+
+ { "abs", (mpexpr_fun_t) mpz_abs, MPEXPR_TYPE_UNARY },
+ { "bin", (mpexpr_fun_t) mpz_bin_ui, MPEXPR_TYPE_BINARY_UI },
+ { "clrbit", (mpexpr_fun_t) e_mpz_clrbit, MPEXPR_TYPE_BINARY_UI },
+ { "cmp", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_I_BINARY },
+ { "cmpabs", (mpexpr_fun_t) mpz_cmpabs, MPEXPR_TYPE_I_BINARY },
+ { "congruent_p",(mpexpr_fun_t)mpz_congruent_p, MPEXPR_TYPE_I_TERNARY },
+ { "divisible_p",(mpexpr_fun_t)mpz_divisible_p, MPEXPR_TYPE_I_BINARY },
+ { "even_p", (mpexpr_fun_t) e_mpz_even_p, MPEXPR_TYPE_I_UNARY },
+ { "fib", (mpexpr_fun_t) mpz_fib_ui, MPEXPR_TYPE_UNARY_UI },
+ { "fac", (mpexpr_fun_t) mpz_fac_ui, MPEXPR_TYPE_UNARY_UI },
+ { "gcd", (mpexpr_fun_t) mpz_gcd, MPEXPR_TYPE_BINARY
+ | MPEXPR_TYPE_PAIRWISE },
+ { "hamdist", (mpexpr_fun_t) e_mpz_hamdist, MPEXPR_TYPE_BINARY },
+ { "invert", (mpexpr_fun_t) mpz_invert, MPEXPR_TYPE_BINARY },
+ { "jacobi", (mpexpr_fun_t) mpz_jacobi, MPEXPR_TYPE_I_BINARY },
+ { "kronecker", (mpexpr_fun_t) mpz_kronecker, MPEXPR_TYPE_I_BINARY },
+ { "lcm", (mpexpr_fun_t) mpz_lcm, MPEXPR_TYPE_BINARY
+ | MPEXPR_TYPE_PAIRWISE },
+ { "lucnum", (mpexpr_fun_t) mpz_lucnum_ui, MPEXPR_TYPE_UNARY_UI },
+ { "max", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_MAX
+ | MPEXPR_TYPE_PAIRWISE },
+ { "min", (mpexpr_fun_t) mpz_cmp, MPEXPR_TYPE_MIN
+ | MPEXPR_TYPE_PAIRWISE },
+ { "nextprime", (mpexpr_fun_t) mpz_nextprime, MPEXPR_TYPE_UNARY },
+ { "odd_p", (mpexpr_fun_t) e_mpz_odd_p, MPEXPR_TYPE_I_UNARY },
+ { "perfect_power_p", (mpexpr_fun_t)mpz_perfect_power_p, MPEXPR_TYPE_I_UNARY},
+ { "perfect_square_p",(mpexpr_fun_t)mpz_perfect_square_p,MPEXPR_TYPE_I_UNARY},
+ { "popcount", (mpexpr_fun_t) e_mpz_popcount, MPEXPR_TYPE_UNARY },
+ { "powm", (mpexpr_fun_t) mpz_powm, MPEXPR_TYPE_TERNARY },
+ { "probab_prime_p", (mpexpr_fun_t)mpz_probab_prime_p, MPEXPR_TYPE_I_UNARY},
+ { "root", (mpexpr_fun_t) mpz_root, MPEXPR_TYPE_BINARY_UI },
+ { "scan0", (mpexpr_fun_t) e_mpz_scan0, MPEXPR_TYPE_BINARY_UI },
+ { "scan1", (mpexpr_fun_t) e_mpz_scan1, MPEXPR_TYPE_BINARY_UI },
+ { "setbit", (mpexpr_fun_t) e_mpz_setbit, MPEXPR_TYPE_BINARY_UI },
+ { "tstbit", (mpexpr_fun_t) mpz_tstbit, MPEXPR_TYPE_I_BINARY_UI },
+ { "sgn", (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_I_UNARY },
+ { "sqrt", (mpexpr_fun_t) mpz_sqrt, MPEXPR_TYPE_UNARY },
+ { NULL }
+};
+
+/* The table is available globally only through a pointer, so the table size
+ can change without breaking binary compatibility. */
+const struct mpexpr_operator_t * const mpz_expr_standard_table
+= _mpz_expr_standard_table;
+
+
+int
+mpz_expr (mpz_ptr res, int base, const char *e, ...)
+{
+ mpz_srcptr var[MPEXPR_VARIABLES];
+ va_list ap;
+ int ret;
+ va_start (ap, e);
+
+ TRACE (printf ("mpz_expr(): base %d, %s\n", base, e));
+ ret = mpexpr_va_to_var ((void **) var, ap);
+ va_end (ap);
+
+ if (ret != MPEXPR_RESULT_OK)
+ return ret;
+
+ return mpz_expr_a (mpz_expr_standard_table, res, base, e, strlen(e), var);
+}
diff --git a/gmp/demos/expr/exprza.c b/gmp/demos/expr/exprza.c
new file mode 100644
index 0000000000..eda830d970
--- /dev/null
+++ b/gmp/demos/expr/exprza.c
@@ -0,0 +1,108 @@
+/* mpz expression evaluation
+
+Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include "gmp.h"
+#include "expr-impl.h"
+
+
+/* No need to parse '-' since that's handled as an operator.
+ This function also by mpq_expr_a, so it's not static. */
+size_t
+mpexpr_mpz_number (mpz_ptr res, const char *e, size_t elen, int base)
+{
+ char *edup;
+ size_t i, ret;
+ int base_effective = (base == 0 ? 10 : base);
+ void *(*allocate_func) (size_t);
+ void (*free_func) (void *, size_t);
+
+ i = 0;
+ if (e[i] == '0')
+ {
+ i++;
+ if (e[i] == 'x' || e[i] == 'b')
+ i++;
+ }
+
+ for ( ; i < elen; i++)
+ if (! isasciidigit_in_base (e[i], base_effective))
+ break;
+
+ mp_get_memory_functions (&allocate_func, NULL, &free_func);
+ edup = (*allocate_func) (i+1);
+ memcpy (edup, e, i);
+ edup[i] = '\0';
+
+ if (mpz_set_str (res, edup, base) == 0)
+ ret = i;
+ else
+ ret = 0;
+
+ (*free_func) (edup, i+1);
+ return ret;
+}
+
+/* ignoring prec */
+static void
+e_mpz_init (mpz_ptr z, unsigned long prec)
+{
+ mpz_init (z);
+}
+
+int
+mpz_expr_a (const struct mpexpr_operator_t *table,
+ mpz_ptr res, int base,
+ const char *e, size_t elen,
+ mpz_srcptr var[26])
+{
+ struct mpexpr_parse_t p;
+
+ p.table = table;
+ p.res = (mpX_ptr) res;
+ p.base = base;
+ p.e = e;
+ p.elen = elen;
+ p.var = (mpX_srcptr *) var;
+
+ p.mpX_clear = (mpexpr_fun_one_t) mpz_clear;
+ p.mpX_ulong_p = (mpexpr_fun_i_unary_t) mpz_fits_ulong_p;
+ p.mpX_get_ui = (mpexpr_fun_get_ui_t) mpz_get_ui;
+ p.mpX_init = (mpexpr_fun_unary_ui_t) e_mpz_init;
+ p.mpX_number = (mpexpr_fun_number_t) mpexpr_mpz_number;
+ p.mpX_set = (mpexpr_fun_unary_t) mpz_set;
+ p.mpX_set_or_swap = (mpexpr_fun_unary_t) mpz_swap;
+ p.mpX_set_si = (mpexpr_fun_set_si_t) mpz_set_si;
+ p.mpX_swap = (mpexpr_fun_swap_t) mpz_swap;
+
+ return mpexpr_evaluate (&p);
+}
diff --git a/gmp/demos/expr/run-expr.c b/gmp/demos/expr/run-expr.c
new file mode 100644
index 0000000000..706b910287
--- /dev/null
+++ b/gmp/demos/expr/run-expr.c
@@ -0,0 +1,242 @@
+/* Demo program to run expression evaluation.
+
+Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* Usage: ./run-expr [-z] [-q] [-f] [-p prec] [-b base] expression...
+
+ Evaluate each argument as a simple expression. By default this is in mpz
+ integers, but -q selects mpq or -f selects mpf. For mpf the float
+ precision can be set with -p. In all cases the input base can be set
+ with -b, or the default is "0" meaning decimal with "0x" allowed.
+
+ This is a pretty trivial program, it's just an easy way to experiment
+ with the evaluation functions. */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "expr.h"
+
+
+void
+run_expr (int type, int base, unsigned long prec, char *str)
+{
+ int outbase = (base == 0 ? 10 : base);
+ int ret;
+
+ switch (type) {
+ case 'z':
+ default:
+ {
+ mpz_t res, var_a, var_b;
+
+ mpz_init (res);
+ mpz_init_set_ui (var_a, 55L);
+ mpz_init_set_ui (var_b, 99L);
+
+ ret = mpz_expr (res, base, str, var_a, var_b, NULL);
+ printf ("\"%s\" base %d: ", str, base);
+ if (ret == MPEXPR_RESULT_OK)
+ {
+ printf ("result ");
+ mpz_out_str (stdout, outbase, res);
+ printf ("\n");
+ }
+ else
+ printf ("invalid (return code %d)\n", ret);
+
+ mpz_clear (res);
+ mpz_clear (var_a);
+ mpz_clear (var_b);
+ }
+ break;
+
+ case 'q':
+ {
+ mpq_t res, var_a, var_b;
+
+ mpq_init (res);
+ mpq_init (var_a);
+ mpq_init (var_b);
+
+ mpq_set_ui (var_a, 55L, 1);
+ mpq_set_ui (var_b, 99L, 1);
+
+ ret = mpq_expr (res, base, str, var_a, var_b, NULL);
+ printf ("\"%s\" base %d: ", str, base);
+ if (ret == MPEXPR_RESULT_OK)
+ {
+ printf ("result ");
+ mpq_out_str (stdout, outbase, res);
+ printf ("\n");
+ }
+ else
+ printf ("invalid (return code %d)\n", ret);
+
+ mpq_clear (res);
+ mpq_clear (var_a);
+ mpq_clear (var_b);
+ }
+ break;
+
+ case 'f':
+ {
+ mpf_t res, var_a, var_b;
+
+ mpf_init2 (res, prec);
+ mpf_init_set_ui (var_a, 55L);
+ mpf_init_set_ui (var_b, 99L);
+
+ ret = mpf_expr (res, base, str, var_a, var_b, NULL);
+ printf ("\"%s\" base %d: ", str, base);
+ if (ret == MPEXPR_RESULT_OK)
+ {
+ printf ("result ");
+ mpf_out_str (stdout, outbase, (size_t) 0, res);
+ printf ("\n");
+ }
+ else
+ printf ("invalid (return code %d)\n", ret);
+
+ mpf_clear (res);
+ mpf_clear (var_a);
+ mpf_clear (var_b);
+ }
+ break;
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int type = 'z';
+ int base = 0;
+ unsigned long prec = 64;
+ int seen_expr = 0;
+ int opt;
+ char *arg;
+
+ for (;;)
+ {
+ argv++;
+ arg = argv[0];
+ if (arg == NULL)
+ break;
+
+ if (arg[0] == '-')
+ {
+ for (;;)
+ {
+ arg++;
+ opt = arg[0];
+
+ switch (opt) {
+ case '\0':
+ goto end_opt;
+
+ case 'f':
+ case 'q':
+ case 'z':
+ type = opt;
+ break;
+
+ case 'b':
+ arg++;
+ if (arg[0] == '\0')
+ {
+ argv++;
+ arg = argv[0];
+ if (arg == NULL)
+ {
+ need_arg:
+ fprintf (stderr, "Need argument for -%c\n", opt);
+ exit (1);
+ }
+ }
+ base = atoi (arg);
+ goto end_opt;
+
+ case 'p':
+ arg++;
+ if (arg[0] == '\0')
+ {
+ argv++;
+ arg = argv[0];
+ if (arg == NULL)
+ goto need_arg;
+ }
+ prec = atoi (arg);
+ goto end_opt;
+
+ case '-':
+ arg++;
+ if (arg[0] != '\0')
+ {
+ /* no "--foo" options */
+ fprintf (stderr, "Unrecognised option --%s\n", arg);
+ exit (1);
+ }
+ /* stop option interpretation at "--" */
+ for (;;)
+ {
+ argv++;
+ arg = argv[0];
+ if (arg == NULL)
+ goto done;
+ run_expr (type, base, prec, arg);
+ seen_expr = 1;
+ }
+
+ default:
+ fprintf (stderr, "Unrecognised option -%c\n", opt);
+ exit (1);
+ }
+ }
+ end_opt:
+ ;
+ }
+ else
+ {
+ run_expr (type, base, prec, arg);
+ seen_expr = 1;
+ }
+ }
+
+ done:
+ if (! seen_expr)
+ {
+ printf ("Usage: %s [-z] [-q] [-f] [-p prec] [-b base] expression...\n", argv[0]);
+ exit (1);
+ }
+
+ return 0;
+}
diff --git a/gmp/demos/expr/t-expr.c b/gmp/demos/expr/t-expr.c
new file mode 100644
index 0000000000..2f808dd8cd
--- /dev/null
+++ b/gmp/demos/expr/t-expr.c
@@ -0,0 +1,510 @@
+/* Test expression evaluation (print nothing and exit 0 if successful).
+
+Copyright 2000-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "tests.h"
+#include "expr-impl.h"
+
+
+int option_trace = 0;
+
+
+struct data_t {
+ int base;
+ const char *expr;
+ const char *want;
+};
+
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+
+
+/* These data_xxx[] arrays are tables to be tested with one or more of the
+ mp?_t types. z=mpz_t, q=mpz_t, f=mpf_t. */
+
+struct data_t data_zqf[] = {
+
+ /* various deliberately wrong expressions */
+ { 0, "", NULL },
+ { 0, "1+", NULL },
+ { 0, "+2", NULL },
+ { 0, "1,2", NULL },
+ { 0, "foo(1,2)", NULL },
+ { 0, "1+foo", NULL },
+ { 10, "0fff", NULL },
+ { 0, "!", NULL },
+ { 0, "10!", NULL },
+ { 0, "-10!", NULL },
+ { 0, "gcd((4,6))", NULL },
+ { 0, "()", NULL },
+ { 0, "fac(2**1000)", NULL },
+ { 0, "$", NULL },
+ { 0, "$-", NULL },
+
+ /* some basics */
+ { 10, "123", "123" },
+ { 10, "-123", "-123" },
+ { 10, "1+2", "3" },
+ { 10, "1+2+3", "6" },
+ { 10, "1+2*3", "7" },
+ { 10, "3*2+1", "7" },
+ { 10, "$a", "55" },
+ { 10, "b", "99" },
+ { 16, "b", "11" },
+ { 10, "4**3 * 2 + 1", "129" },
+ { 10, "1<2", "1" },
+ { 10, "1>2", "0" },
+
+ { 10, "(123)", "123" },
+
+ { 10, "sgn(-123)", "-1" },
+ { 10, "5-7", "-2" },
+
+ { 0, "cmp(0,0)", "0" },
+ { 0, "cmp(1,0)", "1" },
+ { 0, "cmp(0,1)", "-1" },
+ { 0, "cmp(-1,0)", "-1" },
+ { 0, "cmp(0,-1)", "1" },
+
+ { 10, "0 ? 123 : 456", "456" },
+ { 10, "1 ? 4+5 : 6+7", "9" },
+
+ { 10, "(123)", "123" },
+ { 10, "(2+3)", "5" },
+ { 10, "(4+5)*(5+6)", "99" },
+
+ { 0, "1 << 16", "65536" },
+ { 0, "256 >> 4", "16" },
+ { 0, "-256 >> 4", "-16" },
+
+ { 0, "!1", "0" },
+ { 0, "!9", "0" },
+ { 0, "!0", "1" },
+
+ { 0, "2**2**2", "16" },
+ { 0, "-2**2**2", "-16" },
+
+ { 0, "0x100", "256" },
+ { 10, "0x100", NULL },
+ { 10, "0x 100", NULL },
+
+ { 0, " max ( 1, 2, 3, 4, 5, 6, 7, 8)", "8" },
+ { 0, " max ( 1, 9, 2, 3, 4, 5, 6, 7, 8)", "9" },
+ { 0, " min ( 1, 9, 2, 3, 4, 5, 6, 7, 8)", "1" },
+
+ { 10, "abs(123)", "123" },
+ { 10, "abs(-123)", "123" },
+ { 10, "abs(0)", "0" },
+
+ /* filling data stack */
+ { 0, "1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+1))))))))))))))", "16" },
+
+ /* filling control stack */
+ { 0, "----------------------------------------------------1", "1" },
+};
+
+
+const struct data_t data_z[] = {
+ { 0, "divisible_p(333,3)", "1" },
+ { 0, "congruent_p(7,1,3)", "1" },
+
+ { 0, "cmpabs(0,0)", "0" },
+ { 0, "cmpabs(1,0)", "1" },
+ { 0, "cmpabs(0,1)", "-1" },
+ { 0, "cmpabs(-1,0)", "1" },
+ { 0, "cmpabs(0,-1)", "-1" },
+
+ { 0, "odd_p(1)", "1" },
+ { 0, "odd_p(0)", "0" },
+ { 0, "odd_p(-1)", "1" },
+
+ { 0, "even_p(1)", "0" },
+ { 0, "even_p(0)", "1" },
+ { 0, "even_p(-1)", "0" },
+
+ { 0, "fac(0)", "1" },
+ { 0, "fac(1)", "1" },
+ { 0, "fac(2)", "2" },
+ { 0, "fac(3)", "6" },
+ { 0, "fac(10)", "3628800" },
+
+ { 10, "root(81,4)", "3" },
+
+ { 10, "gcd(4,6)", "2" },
+ { 10, "gcd(4,6,9)", "1" },
+
+ { 10, "powm(3,2,9)", "0" },
+ { 10, "powm(3,2,8)", "1" },
+
+ /* filling data stack */
+ { 0, "1 ? 1 : 1 || 1 && 1 | 1 ^ 1 & 1 == 1 >= 1 << 1 - 1 * 1 ** 1", "1" },
+
+ /* filling control stack */
+ { 0, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1", "1" },
+
+ { 0, "fib(10)", "55" },
+
+ { 0, "setbit(0,5)", "32" },
+ { 0, "clrbit(32,5)", "0" },
+ { 0, "tstbit(32,5)", "1" },
+ { 0, "tstbit(32,4)", "0" },
+ { 0, "scan0(7,0)", "3" },
+ { 0, "scan1(7,0)", "0" },
+};
+
+const struct data_t data_zq[] = {
+ /* expecting failure */
+ { 0, "1.2", NULL },
+};
+
+const struct data_t data_q[] = {
+ { 10, "(1/2 + 1/3 + 1/4 + 1/5 + 1/6)*20", "29" },
+ { 0, "num(5/9)", "5" },
+ { 0, "den(5/9)", "9" },
+};
+
+const struct data_t data_zf[] = {
+ { 10, "sqrt ( 49 )", "7" },
+ { 10, "sqrt ( 49 ) + 1", "8" },
+ { 10, "sqrt((49))", "7" },
+ { 10, "sqrt((((((((49))))))))", "7" },
+};
+
+const struct data_t data_f[] = {
+ { 0, "1@10", "10000000000" },
+ { 0, "1.5@10", "15000000000" },
+ { 0, "1000@-1", "100" },
+ { 0, "10.00@-1", "1" },
+
+ { 0, "1e10", "10000000000" },
+ { 0, "1.5e10", "15000000000" },
+ { 0, "1000e-1", "100" },
+ { 0, "10.00e-1", "1" },
+
+ { 16, "1@9", "68719476736" },
+
+ { 16, "1@10", "18446744073709551616" },
+ { -16, "1@10", "1099511627776" },
+
+ { 0, "ceil(0)", "0" },
+ { 0, "ceil(0.25)", "1" },
+ { 0, "ceil(0.5)", "1" },
+ { 0, "ceil(1.5)", "2" },
+ { 0, "ceil(-0.5)", "0" },
+ { 0, "ceil(-1.5)", "-1" },
+
+ /* only simple cases because mpf_eq currently only works on whole limbs */
+ { 0, "eq(0xFFFFFFFFFFFFFFFF1111111111111111,0xFFFFFFFFFFFFFFFF2222222222222222,64)", "1" },
+ { 0, "eq(0xFFFFFFFFFFFFFFFF1111111111111111,0xFFFFFFFFFFFFFFFF2222222222222222,128)", "0" },
+
+ { 0, "floor(0)", "0" },
+ { 0, "floor(0.25)", "0" },
+ { 0, "floor(0.5)", "0" },
+ { 0, "floor(1.5)", "1" },
+ { 0, "floor(-0.5)", "-1" },
+ { 0, "floor(-1.5)", "-2" },
+
+ { 0, "integer_p(1)", "1" },
+ { 0, "integer_p(0.5)", "0" },
+
+ { 0, "trunc(0)", "0" },
+ { 0, "trunc(0.25)", "0" },
+ { 0, "trunc(0.5)", "0" },
+ { 0, "trunc(1.5)", "1" },
+ { 0, "trunc(-0.5)", "0" },
+ { 0, "trunc(-1.5)", "-1" },
+};
+
+struct datalist_t {
+ const struct data_t *data;
+ int num;
+};
+
+#define DATALIST(data) { data, numberof (data) }
+
+struct datalist_t list_z[] = {
+ DATALIST (data_z),
+ DATALIST (data_zq),
+ DATALIST (data_zf),
+ DATALIST (data_zqf),
+};
+
+struct datalist_t list_q[] = {
+ DATALIST (data_q),
+ DATALIST (data_zq),
+ DATALIST (data_zqf),
+};
+
+struct datalist_t list_f[] = {
+ DATALIST (data_zf),
+ DATALIST (data_zqf),
+ DATALIST (data_f),
+};
+
+
+void
+check_z (void)
+{
+ const struct data_t *data;
+ mpz_t a, b, got, want;
+ int l, i, ret;
+
+ mpz_init (got);
+ mpz_init (want);
+ mpz_init_set_ui (a, 55);
+ mpz_init_set_ui (b, 99);
+
+ for (l = 0; l < numberof (list_z); l++)
+ {
+ data = list_z[l].data;
+
+ for (i = 0; i < list_z[l].num; i++)
+ {
+ if (option_trace)
+ printf ("mpz_expr \"%s\"\n", data[i].expr);
+
+ ret = mpz_expr (got, data[i].base, data[i].expr, a, b, NULL);
+
+ if (data[i].want == NULL)
+ {
+ /* expect to fail */
+ if (ret == MPEXPR_RESULT_OK)
+ {
+ printf ("mpz_expr wrong return value, got %d, expected failure\n", ret);
+ goto error;
+ }
+ }
+ else
+ {
+ if (mpz_set_str (want, data[i].want, 0) != 0)
+ {
+ printf ("Cannot parse wanted value string\n");
+ goto error;
+ }
+ if (ret != MPEXPR_RESULT_OK)
+ {
+ printf ("mpz_expr failed unexpectedly\n");
+ printf (" return value %d\n", ret);
+ goto error;
+ }
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_expr wrong result\n");
+ printf (" got "); mpz_out_str (stdout, 10, got);
+ printf ("\n");
+ printf (" want "); mpz_out_str (stdout, 10, want);
+ printf ("\n");
+ goto error;
+ }
+ }
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (got);
+ mpz_clear (want);
+ return;
+
+ error:
+ printf (" base %d\n", data[i].base);
+ printf (" expr \"%s\"\n", data[i].expr);
+ if (data[i].want != NULL)
+ printf (" want \"%s\"\n", data[i].want);
+ abort ();
+}
+
+void
+check_q (void)
+{
+ const struct data_t *data;
+ mpq_t a, b, got, want;
+ int l, i, ret;
+
+ mpq_init (got);
+ mpq_init (want);
+ mpq_init (a);
+ mpq_init (b);
+
+ mpq_set_ui (a, 55, 1);
+ mpq_set_ui (b, 99, 1);
+
+ for (l = 0; l < numberof (list_q); l++)
+ {
+ data = list_q[l].data;
+
+ for (i = 0; i < list_q[l].num; i++)
+ {
+ if (option_trace)
+ printf ("mpq_expr \"%s\"\n", data[i].expr);
+
+ ret = mpq_expr (got, data[i].base, data[i].expr, a, b, NULL);
+
+ if (data[i].want == NULL)
+ {
+ /* expect to fail */
+ if (ret == MPEXPR_RESULT_OK)
+ {
+ printf ("mpq_expr wrong return value, got %d, expected failure\n", ret);
+ goto error;
+ }
+ }
+ else
+ {
+ if (mpz_set_str (mpq_numref(want), data[i].want, 0) != 0)
+ {
+ printf ("Cannot parse wanted value string\n");
+ goto error;
+ }
+ mpz_set_ui (mpq_denref(want), 1);
+
+ if (ret != MPEXPR_RESULT_OK)
+ {
+ printf ("mpq_expr failed unexpectedly\n");
+ printf (" return value %d\n", ret);
+ goto error;
+ }
+ if (mpq_cmp (got, want) != 0)
+ {
+ printf ("mpq_expr wrong result\n");
+ printf (" got "); mpq_out_str (stdout, 10, got);
+ printf ("\n");
+ printf (" want "); mpq_out_str (stdout, 10, want);
+ printf ("\n");
+ goto error;
+ }
+ }
+ }
+ }
+ mpq_clear (a);
+ mpq_clear (b);
+ mpq_clear (got);
+ mpq_clear (want);
+ return;
+
+ error:
+ printf (" base %d\n", data[i].base);
+ printf (" expr \"%s\"\n", data[i].expr);
+ if (data[i].want != NULL)
+ printf (" want \"%s\"\n", data[i].want);
+ abort ();
+}
+
+void
+check_f (void)
+{
+ const struct data_t *data;
+ mpf_t a, b, got, want;
+ int l, i, ret;
+
+ mpf_set_default_prec (200L);
+
+ mpf_init (got);
+ mpf_init (want);
+ mpf_init_set_ui (a, 55);
+ mpf_init_set_ui (b, 99);
+
+ for (l = 0; l < numberof (list_f); l++)
+ {
+ data = list_f[l].data;
+
+ for (i = 0; i < list_f[l].num; i++)
+ {
+ if (option_trace)
+ printf ("mpf_expr \"%s\"\n", data[i].expr);
+
+ ret = mpf_expr (got, data[i].base, data[i].expr, a, b, NULL);
+
+ if (data[i].want == NULL)
+ {
+ /* expect to fail */
+ if (ret == MPEXPR_RESULT_OK)
+ {
+ printf ("mpf_expr wrong return value, got %d, expected failure\n", ret);
+ goto error;
+ }
+ }
+ else
+ {
+ if (mpf_set_str (want, data[i].want, 0) != 0)
+ {
+ printf ("Cannot parse wanted value string\n");
+ goto error;
+ }
+
+ if (ret != MPEXPR_RESULT_OK)
+ {
+ printf ("mpf_expr failed unexpectedly\n");
+ printf (" return value %d\n", ret);
+ goto error;
+ }
+ if (mpf_cmp (got, want) != 0)
+ {
+ printf ("mpf_expr wrong result\n");
+ printf (" got "); mpf_out_str (stdout, 10, 20, got);
+ printf ("\n");
+ printf (" want "); mpf_out_str (stdout, 10, 20, want);
+ printf ("\n");
+ goto error;
+ }
+ }
+ }
+ }
+ mpf_clear (a);
+ mpf_clear (b);
+ mpf_clear (got);
+ mpf_clear (want);
+ return;
+
+ error:
+ printf (" base %d\n", data[i].base);
+ printf (" expr \"%s\"\n", data[i].expr);
+ if (data[i].want != NULL)
+ printf (" want \"%s\"\n", data[i].want);
+ abort ();
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ if (argc >= 2)
+ option_trace = 1;
+
+ check_z ();
+ check_q ();
+ check_f ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/demos/factorize.c b/gmp/demos/factorize.c
new file mode 100644
index 0000000000..0d5f26d909
--- /dev/null
+++ b/gmp/demos/factorize.c
@@ -0,0 +1,446 @@
+/* Factoring with Pollard's rho method.
+
+Copyright 1995, 1997-2003, 2005, 2009, 2012 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "gmp.h"
+
+static unsigned char primes_diff[] = {
+#define P(a,b,c) a,
+#include "primes.h"
+#undef P
+};
+#define PRIMES_PTAB_ENTRIES (sizeof(primes_diff) / sizeof(primes_diff[0]))
+
+int flag_verbose = 0;
+
+/* Prove primality or run probabilistic tests. */
+int flag_prove_primality = 1;
+
+/* Number of Miller-Rabin tests to run when not proving primality. */
+#define MR_REPS 25
+
+struct factors
+{
+ mpz_t *p;
+ unsigned long *e;
+ long nfactors;
+};
+
+void factor (mpz_t, struct factors *);
+
+void
+factor_init (struct factors *factors)
+{
+ factors->p = malloc (1);
+ factors->e = malloc (1);
+ factors->nfactors = 0;
+}
+
+void
+factor_clear (struct factors *factors)
+{
+ int i;
+
+ for (i = 0; i < factors->nfactors; i++)
+ mpz_clear (factors->p[i]);
+
+ free (factors->p);
+ free (factors->e);
+}
+
+void
+factor_insert (struct factors *factors, mpz_t prime)
+{
+ long nfactors = factors->nfactors;
+ mpz_t *p = factors->p;
+ unsigned long *e = factors->e;
+ long i, j;
+
+ /* Locate position for insert new or increment e. */
+ for (i = nfactors - 1; i >= 0; i--)
+ {
+ if (mpz_cmp (p[i], prime) <= 0)
+ break;
+ }
+
+ if (i < 0 || mpz_cmp (p[i], prime) != 0)
+ {
+ p = realloc (p, (nfactors + 1) * sizeof p[0]);
+ e = realloc (e, (nfactors + 1) * sizeof e[0]);
+
+ mpz_init (p[nfactors]);
+ for (j = nfactors - 1; j > i; j--)
+ {
+ mpz_set (p[j + 1], p[j]);
+ e[j + 1] = e[j];
+ }
+ mpz_set (p[i + 1], prime);
+ e[i + 1] = 1;
+
+ factors->p = p;
+ factors->e = e;
+ factors->nfactors = nfactors + 1;
+ }
+ else
+ {
+ e[i] += 1;
+ }
+}
+
+void
+factor_insert_ui (struct factors *factors, unsigned long prime)
+{
+ mpz_t pz;
+
+ mpz_init_set_ui (pz, prime);
+ factor_insert (factors, pz);
+ mpz_clear (pz);
+}
+
+
+void
+factor_using_division (mpz_t t, struct factors *factors)
+{
+ mpz_t q;
+ unsigned long int p;
+ int i;
+
+ if (flag_verbose > 0)
+ {
+ printf ("[trial division] ");
+ }
+
+ mpz_init (q);
+
+ p = mpz_scan1 (t, 0);
+ mpz_div_2exp (t, t, p);
+ while (p)
+ {
+ factor_insert_ui (factors, 2);
+ --p;
+ }
+
+ p = 3;
+ for (i = 1; i <= PRIMES_PTAB_ENTRIES;)
+ {
+ if (! mpz_divisible_ui_p (t, p))
+ {
+ p += primes_diff[i++];
+ if (mpz_cmp_ui (t, p * p) < 0)
+ break;
+ }
+ else
+ {
+ mpz_tdiv_q_ui (t, t, p);
+ factor_insert_ui (factors, p);
+ }
+ }
+
+ mpz_clear (q);
+}
+
+static int
+mp_millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y,
+ mpz_srcptr q, unsigned long int k)
+{
+ unsigned long int i;
+
+ mpz_powm (y, x, q, n);
+
+ if (mpz_cmp_ui (y, 1) == 0 || mpz_cmp (y, nm1) == 0)
+ return 1;
+
+ for (i = 1; i < k; i++)
+ {
+ mpz_powm_ui (y, y, 2, n);
+ if (mpz_cmp (y, nm1) == 0)
+ return 1;
+ if (mpz_cmp_ui (y, 1) == 0)
+ return 0;
+ }
+ return 0;
+}
+
+int
+mp_prime_p (mpz_t n)
+{
+ int k, r, is_prime;
+ mpz_t q, a, nm1, tmp;
+ struct factors factors;
+
+ if (mpz_cmp_ui (n, 1) <= 0)
+ return 0;
+
+ /* We have already casted out small primes. */
+ if (mpz_cmp_ui (n, (long) FIRST_OMITTED_PRIME * FIRST_OMITTED_PRIME) < 0)
+ return 1;
+
+ mpz_inits (q, a, nm1, tmp, NULL);
+
+ /* Precomputation for Miller-Rabin. */
+ mpz_sub_ui (nm1, n, 1);
+
+ /* Find q and k, where q is odd and n = 1 + 2**k * q. */
+ k = mpz_scan1 (nm1, 0);
+ mpz_tdiv_q_2exp (q, nm1, k);
+
+ mpz_set_ui (a, 2);
+
+ /* Perform a Miller-Rabin test, finds most composites quickly. */
+ if (!mp_millerrabin (n, nm1, a, tmp, q, k))
+ {
+ is_prime = 0;
+ goto ret2;
+ }
+
+ if (flag_prove_primality)
+ {
+ /* Factor n-1 for Lucas. */
+ mpz_set (tmp, nm1);
+ factor (tmp, &factors);
+ }
+
+ /* Loop until Lucas proves our number prime, or Miller-Rabin proves our
+ number composite. */
+ for (r = 0; r < PRIMES_PTAB_ENTRIES; r++)
+ {
+ int i;
+
+ if (flag_prove_primality)
+ {
+ is_prime = 1;
+ for (i = 0; i < factors.nfactors && is_prime; i++)
+ {
+ mpz_divexact (tmp, nm1, factors.p[i]);
+ mpz_powm (tmp, a, tmp, n);
+ is_prime = mpz_cmp_ui (tmp, 1) != 0;
+ }
+ }
+ else
+ {
+ /* After enough Miller-Rabin runs, be content. */
+ is_prime = (r == MR_REPS - 1);
+ }
+
+ if (is_prime)
+ goto ret1;
+
+ mpz_add_ui (a, a, primes_diff[r]); /* Establish new base. */
+
+ if (!mp_millerrabin (n, nm1, a, tmp, q, k))
+ {
+ is_prime = 0;
+ goto ret1;
+ }
+ }
+
+ fprintf (stderr, "Lucas prime test failure. This should not happen\n");
+ abort ();
+
+ ret1:
+ if (flag_prove_primality)
+ factor_clear (&factors);
+ ret2:
+ mpz_clears (q, a, nm1, tmp, NULL);
+
+ return is_prime;
+}
+
+void
+factor_using_pollard_rho (mpz_t n, unsigned long a, struct factors *factors)
+{
+ mpz_t x, z, y, P;
+ mpz_t t, t2;
+ unsigned long long k, l, i;
+
+ if (flag_verbose > 0)
+ {
+ printf ("[pollard-rho (%lu)] ", a);
+ }
+
+ mpz_inits (t, t2, NULL);
+ mpz_init_set_si (y, 2);
+ mpz_init_set_si (x, 2);
+ mpz_init_set_si (z, 2);
+ mpz_init_set_ui (P, 1);
+ k = 1;
+ l = 1;
+
+ while (mpz_cmp_ui (n, 1) != 0)
+ {
+ for (;;)
+ {
+ do
+ {
+ mpz_mul (t, x, x);
+ mpz_mod (x, t, n);
+ mpz_add_ui (x, x, a);
+
+ mpz_sub (t, z, x);
+ mpz_mul (t2, P, t);
+ mpz_mod (P, t2, n);
+
+ if (k % 32 == 1)
+ {
+ mpz_gcd (t, P, n);
+ if (mpz_cmp_ui (t, 1) != 0)
+ goto factor_found;
+ mpz_set (y, x);
+ }
+ }
+ while (--k != 0);
+
+ mpz_set (z, x);
+ k = l;
+ l = 2 * l;
+ for (i = 0; i < k; i++)
+ {
+ mpz_mul (t, x, x);
+ mpz_mod (x, t, n);
+ mpz_add_ui (x, x, a);
+ }
+ mpz_set (y, x);
+ }
+
+ factor_found:
+ do
+ {
+ mpz_mul (t, y, y);
+ mpz_mod (y, t, n);
+ mpz_add_ui (y, y, a);
+
+ mpz_sub (t, z, y);
+ mpz_gcd (t, t, n);
+ }
+ while (mpz_cmp_ui (t, 1) == 0);
+
+ mpz_divexact (n, n, t); /* divide by t, before t is overwritten */
+
+ if (!mp_prime_p (t))
+ {
+ if (flag_verbose > 0)
+ {
+ printf ("[composite factor--restarting pollard-rho] ");
+ }
+ factor_using_pollard_rho (t, a + 1, factors);
+ }
+ else
+ {
+ factor_insert (factors, t);
+ }
+
+ if (mp_prime_p (n))
+ {
+ factor_insert (factors, n);
+ break;
+ }
+
+ mpz_mod (x, x, n);
+ mpz_mod (z, z, n);
+ mpz_mod (y, y, n);
+ }
+
+ mpz_clears (P, t2, t, z, x, y, NULL);
+}
+
+void
+factor (mpz_t t, struct factors *factors)
+{
+ factor_init (factors);
+
+ if (mpz_sgn (t) != 0)
+ {
+ factor_using_division (t, factors);
+
+ if (mpz_cmp_ui (t, 1) != 0)
+ {
+ if (flag_verbose > 0)
+ {
+ printf ("[is number prime?] ");
+ }
+ if (mp_prime_p (t))
+ factor_insert (factors, t);
+ else
+ factor_using_pollard_rho (t, 1, factors);
+ }
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpz_t t;
+ int i, j, k;
+ struct factors factors;
+
+ while (argc > 1)
+ {
+ if (!strcmp (argv[1], "-v"))
+ flag_verbose = 1;
+ else if (!strcmp (argv[1], "-w"))
+ flag_prove_primality = 0;
+ else
+ break;
+
+ argv++;
+ argc--;
+ }
+
+ mpz_init (t);
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; i++)
+ {
+ mpz_set_str (t, argv[i], 0);
+
+ gmp_printf ("%Zd:", t);
+ factor (t, &factors);
+
+ for (j = 0; j < factors.nfactors; j++)
+ for (k = 0; k < factors.e[j]; k++)
+ gmp_printf (" %Zd", factors.p[j]);
+
+ puts ("");
+ factor_clear (&factors);
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ mpz_inp_str (t, stdin, 0);
+ if (feof (stdin))
+ break;
+
+ gmp_printf ("%Zd:", t);
+ factor (t, &factors);
+
+ for (j = 0; j < factors.nfactors; j++)
+ for (k = 0; k < factors.e[j]; k++)
+ gmp_printf (" %Zd", factors.p[j]);
+
+ puts ("");
+ factor_clear (&factors);
+ }
+ }
+
+ exit (0);
+}
diff --git a/gmp/demos/isprime.c b/gmp/demos/isprime.c
new file mode 100644
index 0000000000..40ee70eb99
--- /dev/null
+++ b/gmp/demos/isprime.c
@@ -0,0 +1,68 @@
+/* Classify numbers as probable primes, primes or composites.
+ With -q return true if the following argument is a (probable) prime.
+
+Copyright 1999, 2000, 2002, 2005, 2012 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "gmp.h"
+
+char *progname;
+
+void
+print_usage_and_exit ()
+{
+ fprintf (stderr, "usage: %s -q nnn\n", progname);
+ fprintf (stderr, "usage: %s nnn ...\n", progname);
+ exit (-1);
+}
+
+int
+main (int argc, char **argv)
+{
+ mpz_t n;
+ int i;
+
+ progname = argv[0];
+
+ if (argc < 2)
+ print_usage_and_exit ();
+
+ mpz_init (n);
+
+ if (argc == 3 && strcmp (argv[1], "-q") == 0)
+ {
+ if (mpz_set_str (n, argv[2], 0) != 0)
+ print_usage_and_exit ();
+ exit (mpz_probab_prime_p (n, 25) == 0);
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ int class;
+ if (mpz_set_str (n, argv[i], 0) != 0)
+ print_usage_and_exit ();
+ class = mpz_probab_prime_p (n, 25);
+ mpz_out_str (stdout, 10, n);
+ if (class == 0)
+ puts (" is composite");
+ else if (class == 1)
+ puts (" is a probable prime");
+ else /* class == 2 */
+ puts (" is a prime");
+ }
+ exit (0);
+}
diff --git a/gmp/demos/perl/GMP.pm b/gmp/demos/perl/GMP.pm
new file mode 100644
index 0000000000..46bc707cfe
--- /dev/null
+++ b/gmp/demos/perl/GMP.pm
@@ -0,0 +1,671 @@
+# GMP perl module
+
+# Copyright 2001-2004 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+# [Note: The above copyright notice is repeated in the documentation section
+# below, in order to get it into man pages etc generated by the various pod
+# conversions. When changing, be sure to update below too.]
+
+
+# This code is designed to work with perl 5.005, so it and the sub-packages
+# aren't as modern as they could be.
+
+package GMP;
+
+require Symbol;
+require Exporter;
+require DynaLoader;
+@ISA = qw(Exporter DynaLoader);
+
+@EXPORT = qw();
+@EXPORT_OK = qw(version);
+%EXPORT_TAGS = ('all' => [qw(
+ get_d get_d_2exp get_si get_str integer_p
+ printf sgn sprintf)],
+ 'constants' => [()]);
+Exporter::export_ok_tags('all');
+
+$VERSION = '2.00';
+bootstrap GMP $VERSION;
+
+
+# The format string is cut up into "%" specifiers so GMP types can be
+# passed to GMP::sprintf_internal. Any "*"s are interpolated before
+# calling sprintf_internal, which saves worrying about variable
+# argument lists there.
+#
+# Because sprintf_internal is only called after the conversion and
+# operand have been checked there won't be any crashes from a bad
+# format string.
+#
+sub sprintf {
+ my $fmt = shift;
+ my $out = '';
+ my ($pre, $dummy, $pat, $rest);
+
+ while (($pre, $dummy, $pat, $rest) = ($fmt =~ /^((%%|[^%])*)(%[- +#.*hlLqv\d]*[bcdfeEgGinopsuxX])(.*)$/s)) {
+
+ $out .= $pre;
+
+ my $pat2 = $pat; # $pat with "*"s expanded
+ my @params = (); # arguments per "*"s
+ while ($pat2 =~ /[*]/) {
+ my $arg = shift;
+ $pat2 =~ s/[*]/$arg/;
+ push @params, $arg;
+ }
+
+ if (UNIVERSAL::isa($_[0],"GMP::Mpz")) {
+ if ($pat2 !~ /[dioxX]$/) {
+ die "GMP::sprintf: unsupported output format for mpz: $pat2\n";
+ }
+ $pat2 =~ s/(.)$/Z$1/;
+ $out .= sprintf_internal ($pat2, shift);
+
+ } elsif (UNIVERSAL::isa($_[0],"GMP::Mpq")) {
+ if ($pat2 !~ /[dioxX]$/) {
+ die "GMP::sprintf: unsupported output format for mpq: $pat2\n";
+ }
+ $pat2 =~ s/(.)$/Q$1/;
+ $out .= sprintf_internal ($pat2, shift);
+
+ } elsif (UNIVERSAL::isa($_[0],"GMP::Mpf")) {
+ if ($pat2 !~ /[eEfgG]$/) {
+ die "GMP::sprintf: unsupported output format for mpf: $pat2\n";
+ }
+ $pat2 =~ s/(.)$/F$1/;
+ $out .= sprintf_internal ($pat2, shift);
+
+ } elsif ($pat =~ /n$/) {
+ # do it this way so h, l or V type modifiers are respected, and use a
+ # dummy variable to avoid a warning about discarding the value
+ my $dummy = sprintf "%s$pat", $out, $_[0];
+ shift;
+
+ } else {
+ $out .= sprintf $pat, @params, shift;
+ }
+
+ $fmt = $rest;
+ }
+ $out .= $fmt;
+ return $out;
+}
+
+sub printf {
+ if (ref($_[0]) eq 'GLOB') {
+ my $h = Symbol::qualify_to_ref(shift, caller);
+ print $h GMP::sprintf(@_);
+ } else {
+ print STDOUT GMP::sprintf(@_);
+ }
+}
+
+1;
+__END__
+
+
+
+=head1 NAME
+
+GMP - Perl interface to the GNU Multiple Precision Arithmetic Library
+
+=head1 SYNOPSIS
+
+ use GMP;
+ use GMP::Mpz;
+ use GMP::Mpq;
+ use GMP::Mpf;
+ use GMP::Rand;
+
+=head1 DESCRIPTION
+
+This module provides access to GNU MP arbitrary precision integers,
+rationals and floating point.
+
+No functions are exported from these packages by default, but can be
+selected in the usual way, or the tag :all for everything.
+
+ use GMP::Mpz qw(gcd, lcm); # just these functions
+ use GMP::Mpq qw(:all); # everything in mpq
+
+=head2 GMP::Mpz
+
+This class provides arbitrary precision integers. A new mpz can be
+constructed with C<mpz>. The initial value can be an integer, float,
+string, mpz, mpq or mpf. Floats, mpq and mpf will be automatically
+truncated to an integer.
+
+ use GMP::Mpz qw(:all);
+ my $a = mpz(123);
+ my $b = mpz("0xFFFF");
+ my $c = mpz(1.5); # truncated
+
+The following overloaded operators are available, and corresponding
+assignment forms like C<+=>,
+
+=over 4
+
+=item
+
++ - * / % E<lt>E<lt> E<gt>E<gt> ** & | ^ ! E<lt> E<lt>= == != E<gt> E<gt>=
+E<lt>=E<gt> abs not sqrt
+
+=back
+
+C</> and C<%> round towards zero (as per the C<tdiv> functions in GMP).
+
+The following functions are available, behaving the same as the
+corresponding GMP mpz functions,
+
+=over 4
+
+=item
+
+bin, cdiv, cdiv_2exp, clrbit, combit, congruent_p, congruent_2exp_p,
+divexact, divisible_p, divisible_2exp_p, even_p, fac, fdiv, fdiv_2exp, fib,
+fib2, gcd, gcdext, hamdist, invert, jacobi, kronecker, lcm, lucnum, lucnum2,
+mod, mpz_export, mpz_import, nextprime, odd_p, perfect_power_p,
+perfect_square_p, popcount, powm, probab_prime_p, realloc, remove, root,
+roote, scan0, scan1, setbit, sizeinbase, sqrtrem, tdiv, tdiv_2exp, tstbit
+
+=back
+
+C<cdiv>, C<fdiv> and C<tdiv> and their C<2exp> variants return a
+quotient/remainder pair. C<fib2> returns a pair F[n] and F[n-1], similarly
+C<lucnum2>. C<gcd> and C<lcm> accept a variable number of arguments (one or
+more). C<gcdext> returns a triplet of gcd and two cofactors, for example
+
+ use GMP::Mpz qw(:all);
+ $a = 7257;
+ $b = 10701;
+ ($g, $x, $y) = gcdext ($a, $b);
+ print "gcd($a,$b) is $g, and $g == $a*$x + $b*$y\n";
+
+C<mpz_import> and C<mpz_export> are so named to avoid the C<import> keyword.
+Their parameters are as follows,
+
+ $z = mpz_import ($order, $size, $endian, $nails, $string);
+ $string = mpz_export ($order, $size, $endian, $nails, $z);
+
+The order, size, endian and nails parameters are as per the corresponding C
+functions. The string input for C<mpz_import> is interpreted as byte data
+and must be a multiple of $size bytes. C<mpz_export> conversely returns a
+string of byte data, which will be a multiple of $size bytes.
+
+C<invert> returns the inverse, or undef if it doesn't exist. C<remove>
+returns a remainder/multiplicity pair. C<root> returns the nth root, and
+C<roote> returns a root/bool pair, the bool indicating whether the root is
+exact. C<sqrtrem> and C<rootrem> return a root/remainder pair.
+
+C<clrbit>, C<combit> and C<setbit> expect a variable which they can modify,
+it doesn't make sense to pass a literal constant. Only the given variable
+is modified, if other variables are referencing the same mpz object then a
+new copy is made of it. If the variable isn't an mpz it will be coerced to
+one. For instance,
+
+ use GMP::Mpz qw(setbit);
+ setbit (123, 0); # wrong, don't pass a constant
+ $a = mpz(6);
+ $b = $a;
+ setbit ($a, 0); # $a becomes 7, $b stays at 6
+
+C<scan0> and C<scan1> return ~0 if no 0 or 1 bit respectively is found.
+
+=head2 GMP::Mpq
+
+This class provides rationals with arbitrary precision numerators and
+denominators. A new mpq can be constructed with C<mpq>. The initial value
+can be an integer, float, string, mpz, mpq or mpf, or a pair of integers or
+mpz's. No precision is lost when converting a float or mpf, the exact value
+is retained.
+
+ use GMP::Mpq qw(:all);
+ $a = mpq(); # zero
+ $b = mpq(0.5); # gives 1/2
+ $b = mpq(14); # integer 14
+ $b = mpq(3,4); # fraction 3/4
+ $b = mpq("7/12"); # fraction 7/12
+ $b = mpq("0xFF/0x100"); # fraction 255/256
+
+When a fraction is given, it should be in the canonical form specified in
+the GMP manual, which is denominator positive, no common factors, and zero
+always represented as 0/1. If not then C<canonicalize> can be called to put
+it in that form. For example,
+
+ use GMP::Mpq qw(:all);
+ $q = mpq(21,15); # eek! common factor 3
+ canonicalize($q); # get rid of it
+
+The following overloaded operators are available, and corresponding
+assignment forms like C<+=>,
+
+=over 4
+
+=item
+
++ - * / E<lt>E<lt> E<gt>E<gt> ** ! E<lt> E<lt>= == != E<gt> E<gt>=
+E<lt>=E<gt> abs not
+
+=back
+
+The following functions are available,
+
+=over 4
+
+=item
+
+den, inv, num
+
+=back
+
+C<inv> calculates 1/q, as per the corresponding GMP function. C<num> and
+C<den> return an mpz copy of the numerator or denominator respectively. In
+the future C<num> and C<den> might give lvalues so the original mpq can be
+modified through them, but this is not done currently.
+
+=head2 GMP::Mpf
+
+This class provides arbitrary precision floating point numbers. The
+mantissa is an arbitrary user-selected precision and the exponent is a fixed
+size (one machine word).
+
+A new mpf can be constructed with C<mpf>. The initial value can be an
+integer, float, string, mpz, mpq or mpf. The second argument specifies the
+desired precision in bits, or if omitted then the default precision is used.
+
+ use GMP::Mpf qw(:all);
+ $a = mpf(); # zero
+ $b = mpf(-7.5); # default precision
+ $c = mpf(1.5, 500); # 500 bits precision
+ $d = mpf("1.0000000000000001");
+
+The following overloaded operators are available, with the corresponding
+assignment forms like C<+=>,
+
+=over 4
+
+=item
+
++ - * / E<lt>E<lt> E<gt>E<gt> ** ! E<lt> E<lt>= == != E<gt> E<gt>=
+E<lt>=E<gt> abs not sqrt
+
+=back
+
+The following functions are available, behaving the same as the
+corresponding GMP mpf functions,
+
+=over 4
+
+=item
+
+ceil, floor, get_default_prec, get_prec, mpf_eq, set_default_prec, set_prec,
+trunc
+
+=back
+
+C<mpf_eq> is so named to avoid clashing with the perl C<eq> operator.
+
+C<set_prec> expects a variable which it can modify, it doesn't make sense to
+pass a literal constant. Only the given variable is modified, if other
+variables are referencing the same mpf object then a new copy is made of it.
+If the variable isn't an mpf it will be coerced to one.
+
+Results are the same precision as inputs, or if two mpf's are given to a
+binary operator then the precision of the first is used. For example,
+
+ use GMP::Mpf qw(mpf);
+ $a = mpf(2.0, 100);
+ $b = mpf(2.0, 500);
+ $c = $a + $b; # gives 100 bits precision
+
+Mpf to string conversion via "" or the usual string contexts uses C<$#> the
+same as normal float to string conversions, or defaults to C<%.g> if C<$#>
+is not defined. C<%.g> means all significant digits in the selected
+precision.
+
+=head2 GMP class
+
+The following functions are available in the GMP class,
+
+=over 4
+
+=item
+
+fits_slong_p, get_d, get_d_2exp, get_si, get_str, integer_p, printf, sgn,
+sprintf, version
+
+=back
+
+C<get_d_2exp> accepts any integer, string, float, mpz, mpq or mpf operands
+and returns a float and an integer exponent,
+
+ ($dbl, $exp) = get_d_2exp (mpf ("3.0"));
+ # dbl is 0.75, exp is 2
+
+C<get_str> takes an optional second argument which is the base, defaulting
+to decimal. A negative base means upper case, as per the C functions. For
+integer, integer string, mpz or mpq operands a string is returned.
+
+ use GMP qw(:all);
+ use GMP::Mpq qw(:all);
+ print get_str(mpq(-5,8)),"\n"; # -5/8
+ print get_str(255,16),"\n"; # ff
+
+For float, float strings or mpf operands, C<get_str> accepts an optional
+third parameter being how many digits to produce, defaulting to 0 which
+means all digits. (Only as many digits as can be accurately represented by
+the float precision are ever produced though.) A string/exponent pair is
+returned, as per the C mpf_get_str function. For example,
+
+ use GMP qw(:all);
+ use GMP::Mpf qw(:all);
+ ($s, $e) = get_str(111.111111111, 10, 4);
+ printf ".$se$e\n"; # .1111e3
+ ($s, $e) = get_str(1.625, 10);
+ print "0.$s*10^$e\n"; # 0.1625*10^1
+ ($s, $e) = get_str(mpf(2)**20, 16);
+ printf ".%s@%x\n", $s, $e; # .1@14
+
+C<printf> and C<sprintf> allow formatted output of GMP types. mpz and mpq
+values can be used with integer conversions (d, o, x, X) and mpf with float
+conversions (f, e, E, g, G). All the standard perl printf features are
+available too. For example,
+
+ use GMP::Mpz qw(mpz);
+ use GMP::Mpf qw(mpf);
+ GMP::printf ("%d %d %s", 123, mpz(2)**128, 'foo');
+ GMP::printf STDERR "%.40f", mpf(1.234);
+
+In perl 5.6.1 it doesn't seem to work to export C<printf>, the plain builtin
+C<printf> is reached unless calls are C<&printf()> style. Explicit use of
+C<GMP::printf> is suggested. C<sprintf> doesn't suffer this problem.
+
+ use GMP qw(sprintf);
+ use GMP::Mpq qw(mpq);
+ $s = sprintf "%x", mpq(15,16);
+
+C<version> is not exported by default or by tag :all, calling it as
+C<GMP::version()> is recommended. It returns the GMP library version
+string, which is not to be confused with the module version number.
+
+The other GMP module functions behave as per the corresponding GMP routines,
+and accept any integer, string, float, mpz, mpq or mpf. For example,
+
+ use GMP qw(:all);
+ use GMP::Mpz qw(mpz);
+ $z = mpz(123);
+ print sgn($z); # gives 1
+
+Because each of GMP::Mpz, GMP::Mpq and GMP::Mpf is a sub-class of GMP,
+C<-E<gt>> style calls work too.
+
+ use GMP qw(:all);
+ use GMP::Mpq qw(mpf);
+ $q = mpq(-5,7);
+ if ($q->integer_p()) # false
+ ...
+
+=head2 GMP::Rand
+
+This class provides objects holding an algorithm and state for random number
+generation. C<randstate> creates a new object, for example,
+
+ use GMP::Rand qw(randstate);
+ $r = randstate();
+ $r = randstate('lc_2exp_size', 64);
+ $r = randstate('lc_2exp', 43840821, 1, 32);
+ $r = randstate('mt');
+ $r = randstate($another_r);
+
+With no parameters this corresponds to the C function
+C<gmp_randinit_default>, and is a compromise between speed and randomness.
+'lc_2exp_size' corresponds to C<gmp_randinit_lc_2exp_size>, 'lc_2exp'
+corresponds to C<gmp_randinit_lc_2exp>, and 'mt' corresponds to
+C<gmp_randinit_mt>. Or when passed another randstate object, a copy of that
+object is made.
+
+'lc_2exp_size' can fail if the requested size is bigger than the internal
+table provides for, in which case undef is returned. The maximum size
+currently supported is 128. The other forms always succeed.
+
+A randstate can be seeded with an integer or mpz, using the C<seed> method.
+/dev/random might be a good source of randomness, or time() or
+Time::HiRes::time() might be adequate, depending on the application.
+
+ $r->seed(time()));
+
+Random numbers can be generated with the following functions,
+
+=over 4
+
+=item
+
+mpf_urandomb, mpz_rrandomb, mpz_urandomb, mpz_urandomm,
+gmp_urandomb_ui, gmp_urandomm_ui
+
+=back
+
+Each constructs a new mpz or mpf and with a distribution per the
+corresponding GMP function. For example,
+
+ use GMP::Rand (:all);
+ $r = randstate();
+ $a = mpz_urandomb($r,256); # uniform mpz, 256 bits
+ $b = mpz_urandomm($r,mpz(3)**100); # uniform mpz, 0 to 3**100-1
+ $c = mpz_rrandomb($r,1024); # special mpz, 1024 bits
+ $f = mpf_urandomb($r,128); # uniform mpf, 128 bits, 0<=$f<1
+ $f = gmp_urandomm_ui($r,56); # uniform int, 0 to 55
+
+=head2 Coercion
+
+Arguments to operators and functions are converted as necessary to the
+appropriate type. For instance C<**> requires an unsigned integer exponent,
+and an mpq argument will be converted, so long as it's an integer in the
+appropriate range.
+
+ use GMP::Mpz (mpz);
+ use GMP::Mpq (mpq);
+ $p = mpz(3) ** mpq(45); # allowed, 45 is an integer
+
+It's an error if a conversion to an integer or mpz would cause any
+truncation. For example,
+
+ use GMP::Mpz (mpz);
+ $p = mpz(3) + 1.25; # not allowed
+ $p = mpz(3) + mpz(1.25); # allowed, explicit truncation
+
+Comparisons, however, accept any combination of operands and are always done
+exactly. For example,
+
+ use GMP::Mpz (mpz);
+ print mpz(3) < 3.1; # true
+
+Variables used on the left of an assignment operator like C<+=> are subject
+to coercion too. An integer, float or string will change type when an mpz,
+mpq or mpf is applied to it. For example,
+
+ use GMP::Mpz (mpz);
+ $a = 1;
+ $a += mpz(1234); # $a becomes an mpz
+
+=head2 Overloading
+
+The rule for binary operators in the C<overload> mechanism is that if both
+operands are class objects then the method from the first is used. This
+determines the result type when mixing GMP classes. For example,
+
+ use GMP::Mpz (mpz);
+ use GMP::Mpq (mpq);
+ use GMP::Mpf (mpf);
+ $z = mpz(123);
+ $q = mpq(3,2);
+ $f = mpf(1.375)
+ print $q+$f; # gives an mpq
+ print $f+$z; # gives an mpf
+ print $z+$f; # not allowed, would lose precision
+
+=head2 Constants
+
+A special tag C<:constants> is recognised in the module exports list. It
+doesn't select any functions, but indicates that perl constants should be
+GMP objects. This can only be used on one of GMP::Mpz, GMP::Mpq or GMP::Mpf
+at any one time, since they apply different rules.
+
+GMP::Mpz will treat constants as mpz's if they're integers, or ordinary
+floats if not. For example,
+
+ use GMP::Mpz qw(:constants);
+ print 764861287634126387126378128,"\n"; # an mpz
+ print 1.25,"\n"; # a float
+
+GMP::Mpq is similar, treating integers as mpq's and leaving floats to the
+normal perl handling. Something like 3/4 is read as two integer mpq's and a
+division, but that's fine since it gives the intended fraction.
+
+ use GMP::Mpq qw(:constants);
+ print 3/4,"\n"; # an mpq
+ print 1.25,"\n"; # a float
+
+GMP::Mpf will treat all constants as mpf's using the default precision.
+BEGIN blocks can be used to set that precision while the code is parsed.
+For example,
+
+ use GMP::Mpf qw(:constants);
+ BEGIN { GMP::Mpf::set_default_prec(256); }
+ print 1/3;
+ BEGIN { GMP::Mpf::set_default_prec(64); }
+ print 5/7;
+
+A similar special tag :noconstants is recognised to turn off the constants
+feature. For example,
+
+ use GMP::Mpz qw(:constants);
+ print 438249738748174928193,"\n"; # an mpz
+ use GMP::Mpz qw(:noconstants);
+ print 438249738748174928193,"\n"; # now a float
+
+All three 'integer', 'binary' and 'float' constant methods are captured.
+'float' is captured even for GMP::Mpz and GMP::Mpq since perl by default
+treats integer strings as floats if they don't fit a plain integer.
+
+=head1 SEE ALSO
+
+GMP manual, L<perl>, L<overload>.
+
+=head1 BUGS
+
+In perl 5.005_03 on i386 FreeBSD, the overloaded constants sometimes provoke
+seg faults. Don't know if that's a perl bug or a GMP module bug, though it
+does seem to go bad before reaching anything in GMP.xs.
+
+There's no way to specify an arbitrary base when converting a string to an
+mpz (or mpq or mpf), only hex or octal with 0x or 0 (for mpz and mpq, but
+not for mpf).
+
+These modules are not reentrant or thread safe, due to the implementation of
+the XSUBs.
+
+Returning a new object from the various functions is convenient, but
+assignment versions could avoid creating new objects. Perhaps they could be
+named after the C language functions, eg. mpq_inv($q,$q);
+
+It'd be good if C<num> and C<den> gave lvalues so the underlying mpq could
+be manipulated.
+
+C<printf> could usefully accept %b for mpz, mpq and mpf, and perhaps %x for
+mpf too.
+
+C<get_str> returning different style values for integer versus float is a
+bit unfortunate. With mpz, mpq and mpf objects there's no doubt what it
+will do, but on a plain scalar its action depends on whether the scalar was
+promoted to a float at any stage, and then on the GMP module rules about
+using the integer or float part.
+
+=head1 INTERNALS
+
+In usual perl object style, an mpz is a reference to an object blessed into
+class C<GMP::Mpz>. The object holds a pointer to the C language C<mpz_t>
+structure. Similarly for mpq, mpf and randstate.
+
+A free list of mpz and mpq values is kept to avoid repeated initializing and
+clearing when objects are created and destroyed. This aims to help speed,
+but it's not clear whether it's really needed.
+
+mpf doesn't use a free list because the precision of new objects can be
+different each time.
+
+No interface to C<mpf_set_prec_raw> is provided. It wouldn't be very useful
+since there's no way to make an operation store its result in a particular
+object. The plain C<set_prec> is useful though, for truncating to a lower
+precision, or as a sort of directive that subsequent calculations involving
+that variable should use a higher precision.
+
+The overheads of perl dynamic typing (operator dispatch, operand type
+checking or coercion) will mean this interface is slower than using C
+directly.
+
+Some assertion checking is available as a compile-time option.
+
+=head1 COPYRIGHT
+
+Copyright 2001-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+=cut
+
+# Local variables:
+# perl-indent-level: 2
+# fill-column: 76
+# End:
diff --git a/gmp/demos/perl/GMP.xs b/gmp/demos/perl/GMP.xs
new file mode 100644
index 0000000000..9738259c2a
--- /dev/null
+++ b/gmp/demos/perl/GMP.xs
@@ -0,0 +1,3212 @@
+/* GMP module external subroutines.
+
+Copyright 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+/* Notes:
+
+ Routines are grouped with the alias feature and a table of function
+ pointers where possible, since each xsub routine ends up with quite a bit
+ of code size. Different combinations of arguments and return values have
+ to be separate though.
+
+ The "INTERFACE:" feature isn't available in perl 5.005 and so isn't used.
+ "ALIAS:" requires a table lookup with CvXSUBANY(cv).any_i32 (which is
+ "ix") whereas "INTERFACE:" would have CvXSUBANY(cv).any_dptr as the
+ function pointer immediately.
+
+ Mixed-type swapped-order assignments like "$a = 123; $a += mpz(456);"
+ invoke the plain overloaded "+", not "+=", which makes life easier.
+
+ mpz_assume etc types are used with the overloaded operators since such
+ operators are always called with a class object as the first argument, we
+ don't need an sv_derived_from() lookup to check. There's assert()s in
+ MPX_ASSUME() for this though.
+
+ The overload_constant routines reached via overload::constant get 4
+ arguments in perl 5.6, not the 3 as documented. This is apparently a
+ bug, using "..." lets us ignore the extra one.
+
+ There's only a few "si" functions in gmp, so usually SvIV values get
+ handled with an mpz_set_si into a temporary and then a full precision mpz
+ routine. This is reasonably efficient.
+
+ Argument types are checked, with a view to preserving all bits in the
+ operand. Perl is a bit looser in its arithmetic, allowing rounding or
+ truncation to an intended operand type (IV, UV or NV).
+
+ Bugs:
+
+ The memory leak detection attempted in GMP::END() doesn't work when mpz's
+ are created as constants because END() is called before they're
+ destroyed. What's the right place to hook such a check?
+
+ See the bugs section of GMP.pm too. */
+
+
+/* Comment this out to get assertion checking. */
+#define NDEBUG
+
+/* Change this to "#define TRACE(x) x" for some diagnostics. */
+#define TRACE(x)
+
+
+#include <assert.h>
+#include <float.h>
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "patchlevel.h"
+
+#include "gmp.h"
+
+
+/* Perl 5.005 doesn't have SvIsUV, only 5.6 and up.
+ Perl 5.8 has SvUOK, but not 5.6, so we don't use that. */
+#ifndef SvIsUV
+#define SvIsUV(sv) 0
+#endif
+#ifndef SvUVX
+#define SvUVX(sv) (croak("GMP: oops, shouldn't be using SvUVX"), 0)
+#endif
+
+
+/* Code which doesn't check anything itself, but exists to support other
+ assert()s. */
+#ifdef NDEBUG
+#define assert_support(x)
+#else
+#define assert_support(x) x
+#endif
+
+/* LONG_MAX + 1 and ULONG_MAX + 1, as a doubles */
+#define LONG_MAX_P1_AS_DOUBLE ((double) ((unsigned long) LONG_MAX + 1))
+#define ULONG_MAX_P1_AS_DOUBLE (2.0 * (double) ((unsigned long) ULONG_MAX/2 + 1))
+
+/* Check for perl version "major.minor".
+ Perl 5.004 doesn't have PERL_REVISION and PERL_VERSION, but that's ok,
+ we're only interested in tests above that. */
+#if defined (PERL_REVISION) && defined (PERL_VERSION)
+#define PERL_GE(major,minor) \
+ (PERL_REVISION > (major) \
+ || ((major) == PERL_REVISION && PERL_VERSION >= (minor)))
+#else
+#define PERL_GE(major,minor) (0)
+#endif
+#define PERL_LT(major,minor) (! PERL_GE(major,minor))
+
+/* sv_derived_from etc in 5.005 took "char *" rather than "const char *".
+ Avoid some compiler warnings by using const only where it works. */
+#if PERL_LT (5,6)
+#define classconst
+#else
+#define classconst const
+#endif
+
+/* In a MINGW or Cygwin DLL build of gmp, the various gmp functions are
+ given with dllimport directives, which prevents them being used as
+ initializers for constant data. We give function tables as
+ "static_functable const ...", which is normally "static const", but for
+ mingw expands to just "const" making the table an automatic with a
+ run-time initializer.
+
+ In gcc 3.3.1, the function tables initialized like this end up getting
+ all the __imp__foo values fetched, even though just one or two will be
+ used. This is wasteful, but probably not too bad. */
+
+#if defined (__MINGW32__) || defined (__CYGWIN__)
+#define static_functable
+#else
+#define static_functable static
+#endif
+
+#define GMP_MALLOC_ID 42
+
+static classconst char mpz_class[] = "GMP::Mpz";
+static classconst char mpq_class[] = "GMP::Mpq";
+static classconst char mpf_class[] = "GMP::Mpf";
+static classconst char rand_class[] = "GMP::Rand";
+
+static HV *mpz_class_hv;
+static HV *mpq_class_hv;
+static HV *mpf_class_hv;
+
+assert_support (static long mpz_count = 0;)
+assert_support (static long mpq_count = 0;)
+assert_support (static long mpf_count = 0;)
+assert_support (static long rand_count = 0;)
+
+#define TRACE_ACTIVE() \
+ assert_support \
+ (TRACE (printf (" active %ld mpz, %ld mpq, %ld mpf, %ld randstate\n", \
+ mpz_count, mpq_count, mpf_count, rand_count)))
+
+
+/* Each "struct mpz_elem" etc is an mpz_t with a link field tacked on the
+ end so they can be held on a linked list. */
+
+#define CREATE_MPX(type) \
+ \
+ /* must have mpz_t etc first, for sprintf below */ \
+ struct type##_elem { \
+ type##_t m; \
+ struct type##_elem *next; \
+ }; \
+ typedef struct type##_elem *type; \
+ typedef struct type##_elem *type##_assume; \
+ typedef type##_ptr type##_coerce; \
+ \
+ static type type##_freelist = NULL; \
+ \
+ static type \
+ new_##type (void) \
+ { \
+ type p; \
+ TRACE (printf ("new %s\n", type##_class)); \
+ if (type##_freelist != NULL) \
+ { \
+ p = type##_freelist; \
+ type##_freelist = type##_freelist->next; \
+ } \
+ else \
+ { \
+ New (GMP_MALLOC_ID, p, 1, struct type##_elem); \
+ type##_init (p->m); \
+ } \
+ TRACE (printf (" p=%p\n", p)); \
+ assert_support (type##_count++); \
+ TRACE_ACTIVE (); \
+ return p; \
+ } \
+
+CREATE_MPX (mpz)
+CREATE_MPX (mpq)
+
+typedef mpf_ptr mpf;
+typedef mpf_ptr mpf_assume;
+typedef mpf_ptr mpf_coerce_st0;
+typedef mpf_ptr mpf_coerce_def;
+
+
+static mpf
+new_mpf (unsigned long prec)
+{
+ mpf p;
+ New (GMP_MALLOC_ID, p, 1, __mpf_struct);
+ mpf_init2 (p, prec);
+ TRACE (printf (" mpf p=%p\n", p));
+ assert_support (mpf_count++);
+ TRACE_ACTIVE ();
+ return p;
+}
+
+
+/* tmp_mpf_t records an allocated precision with an mpf_t so changes of
+ precision can be done with just an mpf_set_prec_raw. */
+
+struct tmp_mpf_struct {
+ mpf_t m;
+ unsigned long allocated_prec;
+};
+typedef const struct tmp_mpf_struct *tmp_mpf_srcptr;
+typedef struct tmp_mpf_struct *tmp_mpf_ptr;
+typedef struct tmp_mpf_struct tmp_mpf_t[1];
+
+#define tmp_mpf_init(f) \
+ do { \
+ mpf_init (f->m); \
+ f->allocated_prec = mpf_get_prec (f->m); \
+ } while (0)
+
+static void
+tmp_mpf_grow (tmp_mpf_ptr f, unsigned long prec)
+{
+ mpf_set_prec_raw (f->m, f->allocated_prec);
+ mpf_set_prec (f->m, prec);
+ f->allocated_prec = mpf_get_prec (f->m);
+}
+
+#define tmp_mpf_shrink(f) tmp_mpf_grow (f, 1L)
+
+#define tmp_mpf_set_prec(f,prec) \
+ do { \
+ if (prec > f->allocated_prec) \
+ tmp_mpf_grow (f, prec); \
+ else \
+ mpf_set_prec_raw (f->m, prec); \
+ } while (0)
+
+
+static mpz_t tmp_mpz_0, tmp_mpz_1, tmp_mpz_2;
+static mpq_t tmp_mpq_0, tmp_mpq_1;
+static tmp_mpf_t tmp_mpf_0, tmp_mpf_1;
+
+/* for GMP::Mpz::export */
+#define tmp_mpz_4 tmp_mpz_2
+
+
+#define FREE_MPX_FREELIST(p,type) \
+ do { \
+ TRACE (printf ("free %s\n", type##_class)); \
+ p->next = type##_freelist; \
+ type##_freelist = p; \
+ assert_support (type##_count--); \
+ TRACE_ACTIVE (); \
+ assert (type##_count >= 0); \
+ } while (0)
+
+/* this version for comparison, if desired */
+#define FREE_MPX_NOFREELIST(p,type) \
+ do { \
+ TRACE (printf ("free %s\n", type##_class)); \
+ type##_clear (p->m); \
+ Safefree (p); \
+ assert_support (type##_count--); \
+ TRACE_ACTIVE (); \
+ assert (type##_count >= 0); \
+ } while (0)
+
+#define free_mpz(z) FREE_MPX_FREELIST (z, mpz)
+#define free_mpq(q) FREE_MPX_FREELIST (q, mpq)
+
+
+/* Return a new mortal SV holding the given mpx_ptr pointer.
+ class_hv should be one of mpz_class_hv etc. */
+#define MPX_NEWMORTAL(mpx_ptr, class_hv) \
+ sv_bless (sv_setref_pv (sv_newmortal(), NULL, mpx_ptr), class_hv)
+
+/* Aliases for use in typemaps */
+typedef char *malloced_string;
+typedef const char *const_string;
+typedef const char *const_string_assume;
+typedef char *string;
+typedef SV *order_noswap;
+typedef SV *dummy;
+typedef SV *SV_copy_0;
+typedef unsigned long ulong_coerce;
+typedef __gmp_randstate_struct *randstate;
+typedef UV gmp_UV;
+
+#define SvMPX(s,type) ((type) SvIV((SV*) SvRV(s)))
+#define SvMPZ(s) SvMPX(s,mpz)
+#define SvMPQ(s) SvMPX(s,mpq)
+#define SvMPF(s) SvMPX(s,mpf)
+#define SvRANDSTATE(s) SvMPX(s,randstate)
+
+#define MPX_ASSUME(x,sv,type) \
+ do { \
+ assert (sv_derived_from (sv, type##_class)); \
+ x = SvMPX(sv,type); \
+ } while (0)
+
+#define MPZ_ASSUME(z,sv) MPX_ASSUME(z,sv,mpz)
+#define MPQ_ASSUME(q,sv) MPX_ASSUME(q,sv,mpq)
+#define MPF_ASSUME(f,sv) MPX_ASSUME(f,sv,mpf)
+
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+#define SGN(x) ((x)<0 ? -1 : (x) != 0)
+#define ABS(x) ((x)>=0 ? (x) : -(x))
+#define double_integer_p(d) (floor (d) == (d))
+
+#define x_mpq_integer_p(q) \
+ (mpz_cmp_ui (mpq_denref(q), 1L) == 0)
+
+#define assert_table(ix) assert (ix >= 0 && ix < numberof (table))
+
+#define SV_PTR_SWAP(x,y) \
+ do { SV *__tmp = (x); (x) = (y); (y) = __tmp; } while (0)
+#define MPF_PTR_SWAP(x,y) \
+ do { mpf_ptr __tmp = (x); (x) = (y); (y) = __tmp; } while (0)
+
+
+static void
+class_or_croak (SV *sv, classconst char *cl)
+{
+ if (! sv_derived_from (sv, cl))
+ croak("not type %s", cl);
+}
+
+
+/* These are macros, wrap them in functions. */
+static int
+x_mpz_odd_p (mpz_srcptr z)
+{
+ return mpz_odd_p (z);
+}
+static int
+x_mpz_even_p (mpz_srcptr z)
+{
+ return mpz_even_p (z);
+}
+
+static void
+x_mpq_pow_ui (mpq_ptr r, mpq_srcptr b, unsigned long e)
+{
+ mpz_pow_ui (mpq_numref(r), mpq_numref(b), e);
+ mpz_pow_ui (mpq_denref(r), mpq_denref(b), e);
+}
+
+
+static void *
+my_gmp_alloc (size_t n)
+{
+ void *p;
+ TRACE (printf ("my_gmp_alloc %u\n", n));
+ New (GMP_MALLOC_ID, p, n, char);
+ TRACE (printf (" p=%p\n", p));
+ return p;
+}
+
+static void *
+my_gmp_realloc (void *p, size_t oldsize, size_t newsize)
+{
+ TRACE (printf ("my_gmp_realloc %p, %u to %u\n", p, oldsize, newsize));
+ Renew (p, newsize, char);
+ TRACE (printf (" p=%p\n", p));
+ return p;
+}
+
+static void
+my_gmp_free (void *p, size_t n)
+{
+ TRACE (printf ("my_gmp_free %p %u\n", p, n));
+ Safefree (p);
+}
+
+
+#define my_mpx_set_svstr(type) \
+ static void \
+ my_##type##_set_svstr (type##_ptr x, SV *sv) \
+ { \
+ const char *str; \
+ STRLEN len; \
+ TRACE (printf (" my_" #type "_set_svstr\n")); \
+ assert (SvPOK(sv) || SvPOKp(sv)); \
+ str = SvPV (sv, len); \
+ TRACE (printf (" str \"%s\"\n", str)); \
+ if (type##_set_str (x, str, 0) != 0) \
+ croak ("%s: invalid string: %s", type##_class, str); \
+ }
+
+my_mpx_set_svstr(mpz)
+my_mpx_set_svstr(mpq)
+my_mpx_set_svstr(mpf)
+
+
+/* very slack */
+static int
+x_mpq_cmp_si (mpq_srcptr x, long yn, unsigned long yd)
+{
+ mpq y;
+ int ret;
+ y = new_mpq ();
+ mpq_set_si (y->m, yn, yd);
+ ret = mpq_cmp (x, y->m);
+ free_mpq (y);
+ return ret;
+}
+
+static int
+x_mpq_fits_slong_p (mpq_srcptr q)
+{
+ return x_mpq_cmp_si (q, LONG_MIN, 1L) >= 0
+ && mpq_cmp_ui (q, LONG_MAX, 1L) <= 0;
+}
+
+static int
+x_mpz_cmp_q (mpz_ptr x, mpq_srcptr y)
+{
+ int ret;
+ mpz_set_ui (mpq_denref(tmp_mpq_0), 1L);
+ mpz_swap (mpq_numref(tmp_mpq_0), x);
+ ret = mpq_cmp (tmp_mpq_0, y);
+ mpz_swap (mpq_numref(tmp_mpq_0), x);
+ return ret;
+}
+
+static int
+x_mpz_cmp_f (mpz_srcptr x, mpf_srcptr y)
+{
+ tmp_mpf_set_prec (tmp_mpf_0, mpz_sizeinbase (x, 2));
+ mpf_set_z (tmp_mpf_0->m, x);
+ return mpf_cmp (tmp_mpf_0->m, y);
+}
+
+
+#define USE_UNKNOWN 0
+#define USE_IVX 1
+#define USE_UVX 2
+#define USE_NVX 3
+#define USE_PVX 4
+#define USE_MPZ 5
+#define USE_MPQ 6
+#define USE_MPF 7
+
+/* mg_get is called every time we get a value, even if the private flags are
+ still set from a previous such call. This is the same as as SvIV and
+ friends do.
+
+ When POK, we use the PV, even if there's an IV or NV available. This is
+ because it's hard to be sure there wasn't any rounding in establishing
+ the IV and/or NV. Cases of overflow, where the PV should definitely be
+ used, are easy enough to spot, but rounding is hard. So although IV or
+ NV would be more efficient, we must use the PV to be sure of getting all
+ the data. Applications should convert once to mpz, mpq or mpf when using
+ a value repeatedly.
+
+ Zany dual-type scalars like $! where the IV is an error code and the PV
+ is an error description string won't work with this preference for PV,
+ but that's too bad. Such scalars should be rare, and unlikely to be used
+ in bignum calculations.
+
+ When IOK and NOK are both set, we would prefer to use the IV since it can
+ be converted more efficiently, and because on a 64-bit system the NV may
+ have less bits than the IV. The following rules are applied,
+
+ - If the NV is not an integer, then we must use that NV, since clearly
+ the IV was merely established by rounding and is not the full value.
+
+ - In perl prior to 5.8, an NV too big for an IV leaves an overflow value
+ 0xFFFFFFFF. If the NV is too big to fit an IV then clearly it's the NV
+ which is the true value and must be used.
+
+ - In perl 5.8 and up, such an overflow doesn't set IOK, so that test is
+ unnecessary. However when coming from get-magic, IOKp _is_ set, and we
+ must check for overflow the same as in older perl.
+
+ FIXME:
+
+ We'd like to call mg_get just once, but unfortunately sv_derived_from()
+ will call it for each of our checks. We could do a string compare like
+ sv_isa ourselves, but that only tests the exact class, it doesn't
+ recognise subclassing. There doesn't seem to be a public interface to
+ the subclassing tests (in the internal isa_lookup() function). */
+
+int
+use_sv (SV *sv)
+{
+ double d;
+
+ if (SvGMAGICAL(sv))
+ {
+ mg_get(sv);
+
+ if (SvPOKp(sv))
+ return USE_PVX;
+
+ if (SvIOKp(sv))
+ {
+ if (SvIsUV(sv))
+ {
+ if (SvNOKp(sv))
+ goto u_or_n;
+ return USE_UVX;
+ }
+ else
+ {
+ if (SvNOKp(sv))
+ goto i_or_n;
+ return USE_IVX;
+ }
+ }
+
+ if (SvNOKp(sv))
+ return USE_NVX;
+
+ goto rok_or_unknown;
+ }
+
+ if (SvPOK(sv))
+ return USE_PVX;
+
+ if (SvIOK(sv))
+ {
+ if (SvIsUV(sv))
+ {
+ if (SvNOK(sv))
+ {
+ if (PERL_LT (5, 8))
+ {
+ u_or_n:
+ d = SvNVX(sv);
+ if (d >= ULONG_MAX_P1_AS_DOUBLE || d < 0.0)
+ return USE_NVX;
+ }
+ d = SvNVX(sv);
+ if (d != floor (d))
+ return USE_NVX;
+ }
+ return USE_UVX;
+ }
+ else
+ {
+ if (SvNOK(sv))
+ {
+ if (PERL_LT (5, 8))
+ {
+ i_or_n:
+ d = SvNVX(sv);
+ if (d >= LONG_MAX_P1_AS_DOUBLE || d < (double) LONG_MIN)
+ return USE_NVX;
+ }
+ d = SvNVX(sv);
+ if (d != floor (d))
+ return USE_NVX;
+ }
+ return USE_IVX;
+ }
+ }
+
+ if (SvNOK(sv))
+ return USE_NVX;
+
+ rok_or_unknown:
+ if (SvROK(sv))
+ {
+ if (sv_derived_from (sv, mpz_class))
+ return USE_MPZ;
+ if (sv_derived_from (sv, mpq_class))
+ return USE_MPQ;
+ if (sv_derived_from (sv, mpf_class))
+ return USE_MPF;
+ }
+
+ return USE_UNKNOWN;
+}
+
+
+/* Coerce sv to an mpz. Use tmp to hold the converted value if sv isn't
+ already an mpz (or an mpq of which the numerator can be used). Return
+ the chosen mpz (tmp or the contents of sv). */
+
+static mpz_ptr
+coerce_mpz_using (mpz_ptr tmp, SV *sv, int use)
+{
+ switch (use) {
+ case USE_IVX:
+ mpz_set_si (tmp, SvIVX(sv));
+ return tmp;
+
+ case USE_UVX:
+ mpz_set_ui (tmp, SvUVX(sv));
+ return tmp;
+
+ case USE_NVX:
+ {
+ double d;
+ d = SvNVX(sv);
+ if (! double_integer_p (d))
+ croak ("cannot coerce non-integer double to mpz");
+ mpz_set_d (tmp, d);
+ return tmp;
+ }
+
+ case USE_PVX:
+ my_mpz_set_svstr (tmp, sv);
+ return tmp;
+
+ case USE_MPZ:
+ return SvMPZ(sv)->m;
+
+ case USE_MPQ:
+ {
+ mpq q = SvMPQ(sv);
+ if (! x_mpq_integer_p (q->m))
+ croak ("cannot coerce non-integer mpq to mpz");
+ return mpq_numref(q->m);
+ }
+
+ case USE_MPF:
+ {
+ mpf f = SvMPF(sv);
+ if (! mpf_integer_p (f))
+ croak ("cannot coerce non-integer mpf to mpz");
+ mpz_set_f (tmp, f);
+ return tmp;
+ }
+
+ default:
+ croak ("cannot coerce to mpz");
+ }
+}
+static mpz_ptr
+coerce_mpz (mpz_ptr tmp, SV *sv)
+{
+ return coerce_mpz_using (tmp, sv, use_sv (sv));
+}
+
+
+/* Coerce sv to an mpq. If sv is an mpq then just return that, otherwise
+ use tmp to hold the converted value and return that. */
+
+static mpq_ptr
+coerce_mpq_using (mpq_ptr tmp, SV *sv, int use)
+{
+ TRACE (printf ("coerce_mpq_using %p %d\n", tmp, use));
+ switch (use) {
+ case USE_IVX:
+ mpq_set_si (tmp, SvIVX(sv), 1L);
+ return tmp;
+
+ case USE_UVX:
+ mpq_set_ui (tmp, SvUVX(sv), 1L);
+ return tmp;
+
+ case USE_NVX:
+ mpq_set_d (tmp, SvNVX(sv));
+ return tmp;
+
+ case USE_PVX:
+ my_mpq_set_svstr (tmp, sv);
+ return tmp;
+
+ case USE_MPZ:
+ mpq_set_z (tmp, SvMPZ(sv)->m);
+ return tmp;
+
+ case USE_MPQ:
+ return SvMPQ(sv)->m;
+
+ case USE_MPF:
+ mpq_set_f (tmp, SvMPF(sv));
+ return tmp;
+
+ default:
+ croak ("cannot coerce to mpq");
+ }
+}
+static mpq_ptr
+coerce_mpq (mpq_ptr tmp, SV *sv)
+{
+ return coerce_mpq_using (tmp, sv, use_sv (sv));
+}
+
+
+static void
+my_mpf_set_sv_using (mpf_ptr f, SV *sv, int use)
+{
+ switch (use) {
+ case USE_IVX:
+ mpf_set_si (f, SvIVX(sv));
+ break;
+
+ case USE_UVX:
+ mpf_set_ui (f, SvUVX(sv));
+ break;
+
+ case USE_NVX:
+ mpf_set_d (f, SvNVX(sv));
+ break;
+
+ case USE_PVX:
+ my_mpf_set_svstr (f, sv);
+ break;
+
+ case USE_MPZ:
+ mpf_set_z (f, SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ mpf_set_q (f, SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ mpf_set (f, SvMPF(sv));
+ break;
+
+ default:
+ croak ("cannot coerce to mpf");
+ }
+}
+
+/* Coerce sv to an mpf. If sv is an mpf then just return that, otherwise
+ use tmp to hold the converted value (with prec precision). */
+static mpf_ptr
+coerce_mpf_using (tmp_mpf_ptr tmp, SV *sv, unsigned long prec, int use)
+{
+ if (use == USE_MPF)
+ return SvMPF(sv);
+
+ tmp_mpf_set_prec (tmp, prec);
+ my_mpf_set_sv_using (tmp->m, sv, use);
+ return tmp->m;
+}
+static mpf_ptr
+coerce_mpf (tmp_mpf_ptr tmp, SV *sv, unsigned long prec)
+{
+ return coerce_mpf_using (tmp, sv, prec, use_sv (sv));
+}
+
+
+/* Coerce xv to an mpf and store the pointer in x, ditto for yv to x. If
+ one of xv or yv is an mpf then use it for the precision, otherwise use
+ the default precision. */
+unsigned long
+coerce_mpf_pair (mpf *xp, SV *xv, mpf *yp, SV *yv)
+{
+ int x_use = use_sv (xv);
+ int y_use = use_sv (yv);
+ unsigned long prec;
+ mpf x, y;
+
+ if (x_use == USE_MPF)
+ {
+ x = SvMPF(xv);
+ prec = mpf_get_prec (x);
+ y = coerce_mpf_using (tmp_mpf_0, yv, prec, y_use);
+ }
+ else
+ {
+ y = coerce_mpf_using (tmp_mpf_0, yv, mpf_get_default_prec(), y_use);
+ prec = mpf_get_prec (y);
+ x = coerce_mpf_using (tmp_mpf_1, xv, prec, x_use);
+ }
+ *xp = x;
+ *yp = y;
+ return prec;
+}
+
+
+/* Note that SvUV is not used, since it merely treats the signed IV as if it
+ was unsigned. We get an IV and check its sign. */
+static unsigned long
+coerce_ulong (SV *sv)
+{
+ long n;
+
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ n = SvIVX(sv);
+ negative_check:
+ if (n < 0)
+ goto range_error;
+ return n;
+
+ case USE_UVX:
+ return SvUVX(sv);
+
+ case USE_NVX:
+ {
+ double d;
+ d = SvNVX(sv);
+ if (! double_integer_p (d))
+ goto integer_error;
+ n = SvIV(sv);
+ }
+ goto negative_check;
+
+ case USE_PVX:
+ /* FIXME: Check the string is an integer. */
+ n = SvIV(sv);
+ goto negative_check;
+
+ case USE_MPZ:
+ {
+ mpz z = SvMPZ(sv);
+ if (! mpz_fits_ulong_p (z->m))
+ goto range_error;
+ return mpz_get_ui (z->m);
+ }
+
+ case USE_MPQ:
+ {
+ mpq q = SvMPQ(sv);
+ if (! x_mpq_integer_p (q->m))
+ goto integer_error;
+ if (! mpz_fits_ulong_p (mpq_numref (q->m)))
+ goto range_error;
+ return mpz_get_ui (mpq_numref (q->m));
+ }
+
+ case USE_MPF:
+ {
+ mpf f = SvMPF(sv);
+ if (! mpf_integer_p (f))
+ goto integer_error;
+ if (! mpf_fits_ulong_p (f))
+ goto range_error;
+ return mpf_get_ui (f);
+ }
+
+ default:
+ croak ("cannot coerce to ulong");
+ }
+
+ integer_error:
+ croak ("not an integer");
+
+ range_error:
+ croak ("out of range for ulong");
+}
+
+
+static long
+coerce_long (SV *sv)
+{
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ return SvIVX(sv);
+
+ case USE_UVX:
+ {
+ UV u = SvUVX(sv);
+ if (u > (UV) LONG_MAX)
+ goto range_error;
+ return u;
+ }
+
+ case USE_NVX:
+ {
+ double d = SvNVX(sv);
+ if (! double_integer_p (d))
+ goto integer_error;
+ return SvIV(sv);
+ }
+
+ case USE_PVX:
+ /* FIXME: Check the string is an integer. */
+ return SvIV(sv);
+
+ case USE_MPZ:
+ {
+ mpz z = SvMPZ(sv);
+ if (! mpz_fits_slong_p (z->m))
+ goto range_error;
+ return mpz_get_si (z->m);
+ }
+
+ case USE_MPQ:
+ {
+ mpq q = SvMPQ(sv);
+ if (! x_mpq_integer_p (q->m))
+ goto integer_error;
+ if (! mpz_fits_slong_p (mpq_numref (q->m)))
+ goto range_error;
+ return mpz_get_si (mpq_numref (q->m));
+ }
+
+ case USE_MPF:
+ {
+ mpf f = SvMPF(sv);
+ if (! mpf_integer_p (f))
+ goto integer_error;
+ if (! mpf_fits_slong_p (f))
+ goto range_error;
+ return mpf_get_si (f);
+ }
+
+ default:
+ croak ("cannot coerce to long");
+ }
+
+ integer_error:
+ croak ("not an integer");
+
+ range_error:
+ croak ("out of range for ulong");
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+MODULE = GMP PACKAGE = GMP
+
+BOOT:
+ TRACE (printf ("GMP boot\n"));
+ mp_set_memory_functions (my_gmp_alloc, my_gmp_realloc, my_gmp_free);
+ mpz_init (tmp_mpz_0);
+ mpz_init (tmp_mpz_1);
+ mpz_init (tmp_mpz_2);
+ mpq_init (tmp_mpq_0);
+ mpq_init (tmp_mpq_1);
+ tmp_mpf_init (tmp_mpf_0);
+ tmp_mpf_init (tmp_mpf_1);
+ mpz_class_hv = gv_stashpv (mpz_class, 1);
+ mpq_class_hv = gv_stashpv (mpq_class, 1);
+ mpf_class_hv = gv_stashpv (mpf_class, 1);
+
+
+void
+END()
+CODE:
+ TRACE (printf ("GMP end\n"));
+ TRACE_ACTIVE ();
+ /* These are not always true, see Bugs at the top of the file. */
+ /* assert (mpz_count == 0); */
+ /* assert (mpq_count == 0); */
+ /* assert (mpf_count == 0); */
+ /* assert (rand_count == 0); */
+
+
+const_string
+version()
+CODE:
+ RETVAL = gmp_version;
+OUTPUT:
+ RETVAL
+
+
+bool
+fits_slong_p (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ RETVAL = 1;
+ break;
+
+ case USE_UVX:
+ {
+ UV u = SvUVX(sv);
+ RETVAL = (u <= LONG_MAX);
+ }
+ break;
+
+ case USE_NVX:
+ {
+ double d = SvNVX(sv);
+ RETVAL = (d >= (double) LONG_MIN && d < LONG_MAX_P1_AS_DOUBLE);
+ }
+ break;
+
+ case USE_PVX:
+ {
+ STRLEN len;
+ const char *str = SvPV (sv, len);
+ if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
+ RETVAL = x_mpq_fits_slong_p (tmp_mpq_0);
+ else
+ {
+ /* enough precision for a long */
+ tmp_mpf_set_prec (tmp_mpf_0, 2*mp_bits_per_limb);
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) != 0)
+ croak ("GMP::fits_slong_p invalid string format");
+ RETVAL = mpf_fits_slong_p (tmp_mpf_0->m);
+ }
+ }
+ break;
+
+ case USE_MPZ:
+ RETVAL = mpz_fits_slong_p (SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ RETVAL = x_mpq_fits_slong_p (SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_fits_slong_p (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::fits_slong_p invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+double
+get_d (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ RETVAL = (double) SvIVX(sv);
+ break;
+
+ case USE_UVX:
+ RETVAL = (double) SvUVX(sv);
+ break;
+
+ case USE_NVX:
+ RETVAL = SvNVX(sv);
+ break;
+
+ case USE_PVX:
+ {
+ STRLEN len;
+ RETVAL = atof(SvPV(sv, len));
+ }
+ break;
+
+ case USE_MPZ:
+ RETVAL = mpz_get_d (SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ RETVAL = mpq_get_d (SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_get_d (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::get_d invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+get_d_2exp (sv)
+ SV *sv
+PREINIT:
+ double ret;
+ long exp;
+PPCODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ ret = (double) SvIVX(sv);
+ goto use_frexp;
+
+ case USE_UVX:
+ ret = (double) SvUVX(sv);
+ goto use_frexp;
+
+ case USE_NVX:
+ {
+ int i_exp;
+ ret = SvNVX(sv);
+ use_frexp:
+ ret = frexp (ret, &i_exp);
+ exp = i_exp;
+ }
+ break;
+
+ case USE_PVX:
+ /* put strings through mpf to give full exp range */
+ tmp_mpf_set_prec (tmp_mpf_0, DBL_MANT_DIG);
+ my_mpf_set_svstr (tmp_mpf_0->m, sv);
+ ret = mpf_get_d_2exp (&exp, tmp_mpf_0->m);
+ break;
+
+ case USE_MPZ:
+ ret = mpz_get_d_2exp (&exp, SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ tmp_mpf_set_prec (tmp_mpf_0, DBL_MANT_DIG);
+ mpf_set_q (tmp_mpf_0->m, SvMPQ(sv)->m);
+ ret = mpf_get_d_2exp (&exp, tmp_mpf_0->m);
+ break;
+
+ case USE_MPF:
+ ret = mpf_get_d_2exp (&exp, SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::get_d_2exp invalid argument");
+ }
+ PUSHs (sv_2mortal (newSVnv (ret)));
+ PUSHs (sv_2mortal (newSViv (exp)));
+
+
+long
+get_si (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ RETVAL = SvIVX(sv);
+ break;
+
+ case USE_UVX:
+ RETVAL = SvUVX(sv);
+ break;
+
+ case USE_NVX:
+ RETVAL = (long) SvNVX(sv);
+ break;
+
+ case USE_PVX:
+ RETVAL = SvIV(sv);
+ break;
+
+ case USE_MPZ:
+ RETVAL = mpz_get_si (SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ mpz_set_q (tmp_mpz_0, SvMPQ(sv)->m);
+ RETVAL = mpz_get_si (tmp_mpz_0);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_get_si (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::get_si invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+get_str (sv, ...)
+ SV *sv
+PREINIT:
+ char *str;
+ mp_exp_t exp;
+ mpz_ptr z;
+ mpq_ptr q;
+ mpf f;
+ int base;
+ int ndigits;
+PPCODE:
+ TRACE (printf ("GMP::get_str\n"));
+
+ if (items >= 2)
+ base = coerce_long (ST(1));
+ else
+ base = 10;
+ TRACE (printf (" base=%d\n", base));
+
+ if (items >= 3)
+ ndigits = coerce_long (ST(2));
+ else
+ ndigits = 10;
+ TRACE (printf (" ndigits=%d\n", ndigits));
+
+ EXTEND (SP, 2);
+
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ mpz_set_si (tmp_mpz_0, SvIVX(sv));
+ get_tmp_mpz_0:
+ z = tmp_mpz_0;
+ goto get_mpz;
+
+ case USE_UVX:
+ mpz_set_ui (tmp_mpz_0, SvUVX(sv));
+ goto get_tmp_mpz_0;
+
+ case USE_NVX:
+ /* only digits in the original double, not in the coerced form */
+ if (ndigits == 0)
+ ndigits = DBL_DIG;
+ mpf_set_d (tmp_mpf_0->m, SvNVX(sv));
+ f = tmp_mpf_0->m;
+ goto get_mpf;
+
+ case USE_PVX:
+ {
+ /* get_str on a string is not much more than a base conversion */
+ STRLEN len;
+ str = SvPV (sv, len);
+ if (mpz_set_str (tmp_mpz_0, str, 0) == 0)
+ {
+ z = tmp_mpz_0;
+ goto get_mpz;
+ }
+ else if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
+ {
+ q = tmp_mpq_0;
+ goto get_mpq;
+ }
+ else
+ {
+ /* FIXME: Would like perhaps a precision equivalent to the
+ number of significant digits of the string, in its given
+ base. */
+ tmp_mpf_set_prec (tmp_mpf_0, strlen(str));
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0)
+ {
+ f = tmp_mpf_0->m;
+ goto get_mpf;
+ }
+ else
+ croak ("GMP::get_str invalid string format");
+ }
+ }
+ break;
+
+ case USE_MPZ:
+ z = SvMPZ(sv)->m;
+ get_mpz:
+ str = mpz_get_str (NULL, base, z);
+ push_str:
+ PUSHs (sv_2mortal (newSVpv (str, 0)));
+ break;
+
+ case USE_MPQ:
+ q = SvMPQ(sv)->m;
+ get_mpq:
+ str = mpq_get_str (NULL, base, q);
+ goto push_str;
+
+ case USE_MPF:
+ f = SvMPF(sv);
+ get_mpf:
+ str = mpf_get_str (NULL, &exp, base, 0, f);
+ PUSHs (sv_2mortal (newSVpv (str, 0)));
+ PUSHs (sv_2mortal (newSViv (exp)));
+ break;
+
+ default:
+ croak ("GMP::get_str invalid argument");
+ }
+
+
+bool
+integer_p (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ case USE_UVX:
+ RETVAL = 1;
+ break;
+
+ case USE_NVX:
+ RETVAL = double_integer_p (SvNVX(sv));
+ break;
+
+ case USE_PVX:
+ {
+ /* FIXME: Maybe this should be done by parsing the string, not by an
+ actual conversion. */
+ STRLEN len;
+ const char *str = SvPV (sv, len);
+ if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
+ RETVAL = x_mpq_integer_p (tmp_mpq_0);
+ else
+ {
+ /* enough for all digits of the string */
+ tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64);
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0)
+ RETVAL = mpf_integer_p (tmp_mpf_0->m);
+ else
+ croak ("GMP::integer_p invalid string format");
+ }
+ }
+ break;
+
+ case USE_MPZ:
+ RETVAL = 1;
+ break;
+
+ case USE_MPQ:
+ RETVAL = x_mpq_integer_p (SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_integer_p (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::integer_p invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+int
+sgn (sv)
+ SV *sv
+CODE:
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ RETVAL = SGN (SvIVX(sv));
+ break;
+
+ case USE_UVX:
+ RETVAL = (SvUVX(sv) > 0);
+ break;
+
+ case USE_NVX:
+ RETVAL = SGN (SvNVX(sv));
+ break;
+
+ case USE_PVX:
+ {
+ /* FIXME: Maybe this should be done by parsing the string, not by an
+ actual conversion. */
+ STRLEN len;
+ const char *str = SvPV (sv, len);
+ if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
+ RETVAL = mpq_sgn (tmp_mpq_0);
+ else
+ {
+ /* enough for all digits of the string */
+ tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64);
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0)
+ RETVAL = mpf_sgn (tmp_mpf_0->m);
+ else
+ croak ("GMP::sgn invalid string format");
+ }
+ }
+ break;
+
+ case USE_MPZ:
+ RETVAL = mpz_sgn (SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ RETVAL = mpq_sgn (SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ RETVAL = mpf_sgn (SvMPF(sv));
+ break;
+
+ default:
+ croak ("GMP::sgn invalid argument");
+ }
+OUTPUT:
+ RETVAL
+
+
+# currently undocumented
+void
+shrink ()
+CODE:
+#define x_mpz_shrink(z) \
+ mpz_set_ui (z, 0L); _mpz_realloc (z, 1)
+#define x_mpq_shrink(q) \
+ x_mpz_shrink (mpq_numref(q)); x_mpz_shrink (mpq_denref(q))
+
+ x_mpz_shrink (tmp_mpz_0);
+ x_mpz_shrink (tmp_mpz_1);
+ x_mpz_shrink (tmp_mpz_2);
+ x_mpq_shrink (tmp_mpq_0);
+ x_mpq_shrink (tmp_mpq_1);
+ tmp_mpf_shrink (tmp_mpf_0);
+ tmp_mpf_shrink (tmp_mpf_1);
+
+
+
+malloced_string
+sprintf_internal (fmt, sv)
+ const_string fmt
+ SV *sv
+CODE:
+ assert (strlen (fmt) >= 3);
+ assert (SvROK(sv));
+ assert ((sv_derived_from (sv, mpz_class) && fmt[strlen(fmt)-2] == 'Z')
+ || (sv_derived_from (sv, mpq_class) && fmt[strlen(fmt)-2] == 'Q')
+ || (sv_derived_from (sv, mpf_class) && fmt[strlen(fmt)-2] == 'F'));
+ TRACE (printf ("GMP::sprintf_internal\n");
+ printf (" fmt |%s|\n", fmt);
+ printf (" sv |%p|\n", SvMPZ(sv)));
+
+ /* cheat a bit here, SvMPZ works for mpq and mpf too */
+ gmp_asprintf (&RETVAL, fmt, SvMPZ(sv));
+
+ TRACE (printf (" result |%s|\n", RETVAL));
+OUTPUT:
+ RETVAL
+
+
+
+#------------------------------------------------------------------------------
+
+MODULE = GMP PACKAGE = GMP::Mpz
+
+mpz
+mpz (...)
+ALIAS:
+ GMP::Mpz::new = 1
+PREINIT:
+ SV *sv;
+CODE:
+ TRACE (printf ("%s new, ix=%ld, items=%d\n", mpz_class, ix, (int) items));
+ RETVAL = new_mpz();
+
+ switch (items) {
+ case 0:
+ mpz_set_ui (RETVAL->m, 0L);
+ break;
+
+ case 1:
+ sv = ST(0);
+ TRACE (printf (" use %d\n", use_sv (sv)));
+ switch (use_sv (sv)) {
+ case USE_IVX:
+ mpz_set_si (RETVAL->m, SvIVX(sv));
+ break;
+
+ case USE_UVX:
+ mpz_set_ui (RETVAL->m, SvUVX(sv));
+ break;
+
+ case USE_NVX:
+ mpz_set_d (RETVAL->m, SvNVX(sv));
+ break;
+
+ case USE_PVX:
+ my_mpz_set_svstr (RETVAL->m, sv);
+ break;
+
+ case USE_MPZ:
+ mpz_set (RETVAL->m, SvMPZ(sv)->m);
+ break;
+
+ case USE_MPQ:
+ mpz_set_q (RETVAL->m, SvMPQ(sv)->m);
+ break;
+
+ case USE_MPF:
+ mpz_set_f (RETVAL->m, SvMPF(sv));
+ break;
+
+ default:
+ goto invalid;
+ }
+ break;
+
+ default:
+ invalid:
+ croak ("%s new: invalid arguments", mpz_class);
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+overload_constant (str, pv, d1, ...)
+ const_string_assume str
+ SV *pv
+ dummy d1
+PREINIT:
+ mpz z;
+PPCODE:
+ TRACE (printf ("%s constant: %s\n", mpz_class, str));
+ z = new_mpz();
+ if (mpz_set_str (z->m, str, 0) == 0)
+ {
+ PUSHs (MPX_NEWMORTAL (z, mpz_class_hv));
+ }
+ else
+ {
+ free_mpz (z);
+ PUSHs(pv);
+ }
+
+
+mpz
+overload_copy (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+CODE:
+ RETVAL = new_mpz();
+ mpz_set (RETVAL->m, z->m);
+OUTPUT:
+ RETVAL
+
+
+void
+DESTROY (z)
+ mpz_assume z
+CODE:
+ TRACE (printf ("%s DESTROY %p\n", mpz_class, z));
+ free_mpz (z);
+
+
+malloced_string
+overload_string (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+CODE:
+ TRACE (printf ("%s overload_string %p\n", mpz_class, z));
+ RETVAL = mpz_get_str (NULL, 10, z->m);
+OUTPUT:
+ RETVAL
+
+
+mpz
+overload_add (xv, yv, order)
+ SV *xv
+ SV *yv
+ SV *order
+ALIAS:
+ GMP::Mpz::overload_sub = 1
+ GMP::Mpz::overload_mul = 2
+ GMP::Mpz::overload_div = 3
+ GMP::Mpz::overload_rem = 4
+ GMP::Mpz::overload_and = 5
+ GMP::Mpz::overload_ior = 6
+ GMP::Mpz::overload_xor = 7
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_add }, /* 0 */
+ { mpz_sub }, /* 1 */
+ { mpz_mul }, /* 2 */
+ { mpz_tdiv_q }, /* 3 */
+ { mpz_tdiv_r }, /* 4 */
+ { mpz_and }, /* 5 */
+ { mpz_ior }, /* 6 */
+ { mpz_xor }, /* 7 */
+ };
+CODE:
+ assert_table (ix);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (xv, yv);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m,
+ coerce_mpz (tmp_mpz_0, xv),
+ coerce_mpz (tmp_mpz_1, yv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_addeq (x, y, o)
+ mpz_assume x
+ mpz_coerce y
+ order_noswap o
+ALIAS:
+ GMP::Mpz::overload_subeq = 1
+ GMP::Mpz::overload_muleq = 2
+ GMP::Mpz::overload_diveq = 3
+ GMP::Mpz::overload_remeq = 4
+ GMP::Mpz::overload_andeq = 5
+ GMP::Mpz::overload_ioreq = 6
+ GMP::Mpz::overload_xoreq = 7
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_add }, /* 0 */
+ { mpz_sub }, /* 1 */
+ { mpz_mul }, /* 2 */
+ { mpz_tdiv_q }, /* 3 */
+ { mpz_tdiv_r }, /* 4 */
+ { mpz_and }, /* 5 */
+ { mpz_ior }, /* 6 */
+ { mpz_xor }, /* 7 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (x->m, x->m, y);
+ XPUSHs (ST(0));
+
+
+mpz
+overload_lshift (zv, nv, order)
+ SV *zv
+ SV *nv
+ SV *order
+ALIAS:
+ GMP::Mpz::overload_rshift = 1
+ GMP::Mpz::overload_pow = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_mul_2exp }, /* 0 */
+ { mpz_div_2exp }, /* 1 */
+ { mpz_pow_ui }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (zv, nv);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, coerce_mpz (RETVAL->m, zv), coerce_ulong (nv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_lshifteq (z, n, o)
+ mpz_assume z
+ ulong_coerce n
+ order_noswap o
+ALIAS:
+ GMP::Mpz::overload_rshifteq = 1
+ GMP::Mpz::overload_poweq = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_mul_2exp }, /* 0 */
+ { mpz_div_2exp }, /* 1 */
+ { mpz_pow_ui }, /* 2 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (z->m, z->m, n);
+ XPUSHs(ST(0));
+
+
+mpz
+overload_abs (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpz::overload_neg = 1
+ GMP::Mpz::overload_com = 2
+ GMP::Mpz::overload_sqrt = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr w, mpz_srcptr x);
+ } table[] = {
+ { mpz_abs }, /* 0 */
+ { mpz_neg }, /* 1 */
+ { mpz_com }, /* 2 */
+ { mpz_sqrt }, /* 3 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, z->m);
+OUTPUT:
+ RETVAL
+
+
+void
+overload_inc (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpz::overload_dec = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr w, mpz_srcptr x, unsigned long y);
+ } table[] = {
+ { mpz_add_ui }, /* 0 */
+ { mpz_sub_ui }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ (*table[ix].op) (z->m, z->m, 1L);
+
+
+int
+overload_spaceship (xv, yv, order)
+ SV *xv
+ SV *yv
+ SV *order
+PREINIT:
+ mpz x;
+CODE:
+ TRACE (printf ("%s overload_spaceship\n", mpz_class));
+ MPZ_ASSUME (x, xv);
+ switch (use_sv (yv)) {
+ case USE_IVX:
+ RETVAL = mpz_cmp_si (x->m, SvIVX(yv));
+ break;
+ case USE_UVX:
+ RETVAL = mpz_cmp_ui (x->m, SvUVX(yv));
+ break;
+ case USE_PVX:
+ RETVAL = mpz_cmp (x->m, coerce_mpz (tmp_mpz_0, yv));
+ break;
+ case USE_NVX:
+ RETVAL = mpz_cmp_d (x->m, SvNVX(yv));
+ break;
+ case USE_MPZ:
+ RETVAL = mpz_cmp (x->m, SvMPZ(yv)->m);
+ break;
+ case USE_MPQ:
+ RETVAL = x_mpz_cmp_q (x->m, SvMPQ(yv)->m);
+ break;
+ case USE_MPF:
+ RETVAL = x_mpz_cmp_f (x->m, SvMPF(yv));
+ break;
+ default:
+ croak ("%s <=>: invalid operand", mpz_class);
+ }
+ RETVAL = SGN (RETVAL);
+ if (order == &PL_sv_yes)
+ RETVAL = -RETVAL;
+OUTPUT:
+ RETVAL
+
+
+bool
+overload_bool (z, d1, d2)
+ mpz_assume z
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpz::overload_not = 1
+CODE:
+ RETVAL = (mpz_sgn (z->m) != 0) ^ ix;
+OUTPUT:
+ RETVAL
+
+
+mpz
+bin (n, k)
+ mpz_coerce n
+ ulong_coerce k
+ALIAS:
+ GMP::Mpz::root = 1
+PREINIT:
+ /* mpz_root returns an int, hence the cast */
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_bin_ui }, /* 0 */
+ { (void (*)(mpz_ptr, mpz_srcptr, unsigned long)) mpz_root }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, n, k);
+OUTPUT:
+ RETVAL
+
+
+void
+cdiv (a, d)
+ mpz_coerce a
+ mpz_coerce d
+ALIAS:
+ GMP::Mpz::fdiv = 1
+ GMP::Mpz::tdiv = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_cdiv_qr }, /* 0 */
+ { mpz_fdiv_qr }, /* 1 */
+ { mpz_tdiv_qr }, /* 2 */
+ };
+ mpz q, r;
+PPCODE:
+ assert_table (ix);
+ q = new_mpz();
+ r = new_mpz();
+ (*table[ix].op) (q->m, r->m, a, d);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (q, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));
+
+
+void
+cdiv_2exp (a, d)
+ mpz_coerce a
+ ulong_coerce d
+ALIAS:
+ GMP::Mpz::fdiv_2exp = 1
+ GMP::Mpz::tdiv_2exp = 2
+PREINIT:
+ static_functable const struct {
+ void (*q) (mpz_ptr, mpz_srcptr, unsigned long);
+ void (*r) (mpz_ptr, mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_cdiv_q_2exp, mpz_cdiv_r_2exp }, /* 0 */
+ { mpz_fdiv_q_2exp, mpz_fdiv_r_2exp }, /* 1 */
+ { mpz_tdiv_q_2exp, mpz_tdiv_r_2exp }, /* 2 */
+ };
+ mpz q, r;
+PPCODE:
+ assert_table (ix);
+ q = new_mpz();
+ r = new_mpz();
+ (*table[ix].q) (q->m, a, d);
+ (*table[ix].r) (r->m, a, d);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (q, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));
+
+
+bool
+congruent_p (a, c, d)
+ mpz_coerce a
+ mpz_coerce c
+ mpz_coerce d
+PREINIT:
+CODE:
+ RETVAL = mpz_congruent_p (a, c, d);
+OUTPUT:
+ RETVAL
+
+
+bool
+congruent_2exp_p (a, c, d)
+ mpz_coerce a
+ mpz_coerce c
+ ulong_coerce d
+PREINIT:
+CODE:
+ RETVAL = mpz_congruent_2exp_p (a, c, d);
+OUTPUT:
+ RETVAL
+
+
+mpz
+divexact (a, d)
+ mpz_coerce a
+ mpz_coerce d
+ALIAS:
+ GMP::Mpz::mod = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_divexact }, /* 0 */
+ { mpz_mod }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, a, d);
+OUTPUT:
+ RETVAL
+
+
+bool
+divisible_p (a, d)
+ mpz_coerce a
+ mpz_coerce d
+CODE:
+ RETVAL = mpz_divisible_p (a, d);
+OUTPUT:
+ RETVAL
+
+
+bool
+divisible_2exp_p (a, d)
+ mpz_coerce a
+ ulong_coerce d
+CODE:
+ RETVAL = mpz_divisible_2exp_p (a, d);
+OUTPUT:
+ RETVAL
+
+
+bool
+even_p (z)
+ mpz_coerce z
+ALIAS:
+ GMP::Mpz::odd_p = 1
+ GMP::Mpz::perfect_square_p = 2
+ GMP::Mpz::perfect_power_p = 3
+PREINIT:
+ static_functable const struct {
+ int (*op) (mpz_srcptr z);
+ } table[] = {
+ { x_mpz_even_p }, /* 0 */
+ { x_mpz_odd_p }, /* 1 */
+ { mpz_perfect_square_p }, /* 2 */
+ { mpz_perfect_power_p }, /* 3 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = (*table[ix].op) (z);
+OUTPUT:
+ RETVAL
+
+
+mpz
+fac (n)
+ ulong_coerce n
+ALIAS:
+ GMP::Mpz::fib = 1
+ GMP::Mpz::lucnum = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr r, unsigned long n);
+ } table[] = {
+ { mpz_fac_ui }, /* 0 */
+ { mpz_fib_ui }, /* 1 */
+ { mpz_lucnum_ui }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].op) (RETVAL->m, n);
+OUTPUT:
+ RETVAL
+
+
+void
+fib2 (n)
+ ulong_coerce n
+ALIAS:
+ GMP::Mpz::lucnum2 = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr r, mpz_ptr r2, unsigned long n);
+ } table[] = {
+ { mpz_fib2_ui }, /* 0 */
+ { mpz_lucnum2_ui }, /* 1 */
+ };
+ mpz r, r2;
+PPCODE:
+ assert_table (ix);
+ r = new_mpz();
+ r2 = new_mpz();
+ (*table[ix].op) (r->m, r2->m, n);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (r2, mpz_class_hv));
+
+
+mpz
+gcd (x, ...)
+ mpz_coerce x
+ALIAS:
+ GMP::Mpz::lcm = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr w, mpz_srcptr x, mpz_srcptr y);
+ void (*op_ui) (mpz_ptr w, mpz_srcptr x, unsigned long y);
+ } table[] = {
+ /* cast to ignore ulong return from mpz_gcd_ui */
+ { mpz_gcd,
+ (void (*) (mpz_ptr, mpz_srcptr, unsigned long)) mpz_gcd_ui }, /* 0 */
+ { mpz_lcm, mpz_lcm_ui }, /* 1 */
+ };
+ int i;
+ SV *yv;
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ if (items == 1)
+ mpz_set (RETVAL->m, x);
+ else
+ {
+ for (i = 1; i < items; i++)
+ {
+ yv = ST(i);
+ if (SvIOK(yv))
+ (*table[ix].op_ui) (RETVAL->m, x, ABS(SvIVX(yv)));
+ else
+ (*table[ix].op) (RETVAL->m, x, coerce_mpz (tmp_mpz_1, yv));
+ x = RETVAL->m;
+ }
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+gcdext (a, b)
+ mpz_coerce a
+ mpz_coerce b
+PREINIT:
+ mpz g, x, y;
+ SV *sv;
+PPCODE:
+ g = new_mpz();
+ x = new_mpz();
+ y = new_mpz();
+ mpz_gcdext (g->m, x->m, y->m, a, b);
+ EXTEND (SP, 3);
+ PUSHs (MPX_NEWMORTAL (g, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (x, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (y, mpz_class_hv));
+
+
+unsigned long
+hamdist (x, y)
+ mpz_coerce x
+ mpz_coerce y
+CODE:
+ RETVAL = mpz_hamdist (x, y);
+OUTPUT:
+ RETVAL
+
+
+mpz
+invert (a, m)
+ mpz_coerce a
+ mpz_coerce m
+CODE:
+ RETVAL = new_mpz();
+ if (! mpz_invert (RETVAL->m, a, m))
+ {
+ free_mpz (RETVAL);
+ XSRETURN_UNDEF;
+ }
+OUTPUT:
+ RETVAL
+
+
+int
+jacobi (a, b)
+ mpz_coerce a
+ mpz_coerce b
+CODE:
+ RETVAL = mpz_jacobi (a, b);
+OUTPUT:
+ RETVAL
+
+
+int
+kronecker (a, b)
+ SV *a
+ SV *b
+CODE:
+ if (SvIOK(b))
+ RETVAL = mpz_kronecker_si (coerce_mpz(tmp_mpz_0,a), SvIVX(b));
+ else if (SvIOK(a))
+ RETVAL = mpz_si_kronecker (SvIVX(a), coerce_mpz(tmp_mpz_0,b));
+ else
+ RETVAL = mpz_kronecker (coerce_mpz(tmp_mpz_0,a),
+ coerce_mpz(tmp_mpz_1,b));
+OUTPUT:
+ RETVAL
+
+
+void
+mpz_export (order, size, endian, nails, z)
+ int order
+ size_t size
+ int endian
+ size_t nails
+ mpz_coerce z
+PREINIT:
+ size_t numb, count, bytes, actual_count;
+ char *data;
+ SV *sv;
+PPCODE:
+ numb = 8*size - nails;
+ count = (mpz_sizeinbase (z, 2) + numb-1) / numb;
+ bytes = count * size;
+ New (GMP_MALLOC_ID, data, bytes+1, char);
+ mpz_export (data, &actual_count, order, size, endian, nails, z);
+ assert (count == actual_count);
+ data[bytes] = '\0';
+ sv = sv_newmortal(); sv_usepvn_mg (sv, data, bytes); PUSHs(sv);
+
+
+mpz
+mpz_import (order, size, endian, nails, sv)
+ int order
+ size_t size
+ int endian
+ size_t nails
+ SV *sv
+PREINIT:
+ size_t count;
+ const char *data;
+ STRLEN len;
+CODE:
+ data = SvPV (sv, len);
+ if ((len % size) != 0)
+ croak ("%s mpz_import: string not a multiple of the given size",
+ mpz_class);
+ count = len / size;
+ RETVAL = new_mpz();
+ mpz_import (RETVAL->m, count, order, size, endian, nails, data);
+OUTPUT:
+ RETVAL
+
+
+mpz
+nextprime (z)
+ mpz_coerce z
+CODE:
+ RETVAL = new_mpz();
+ mpz_nextprime (RETVAL->m, z);
+OUTPUT:
+ RETVAL
+
+
+unsigned long
+popcount (x)
+ mpz_coerce x
+CODE:
+ RETVAL = mpz_popcount (x);
+OUTPUT:
+ RETVAL
+
+
+mpz
+powm (b, e, m)
+ mpz_coerce b
+ mpz_coerce e
+ mpz_coerce m
+CODE:
+ RETVAL = new_mpz();
+ mpz_powm (RETVAL->m, b, e, m);
+OUTPUT:
+ RETVAL
+
+
+bool
+probab_prime_p (z, n)
+ mpz_coerce z
+ ulong_coerce n
+CODE:
+ RETVAL = mpz_probab_prime_p (z, n);
+OUTPUT:
+ RETVAL
+
+
+# No attempt to coerce here, only an mpz makes sense.
+void
+realloc (z, limbs)
+ mpz z
+ int limbs
+CODE:
+ _mpz_realloc (z->m, limbs);
+
+
+void
+remove (z, f)
+ mpz_coerce z
+ mpz_coerce f
+PREINIT:
+ SV *sv;
+ mpz rem;
+ unsigned long mult;
+PPCODE:
+ rem = new_mpz();
+ mult = mpz_remove (rem->m, z, f);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (rem, mpz_class_hv));
+ PUSHs (sv_2mortal (newSViv (mult)));
+
+
+void
+roote (z, n)
+ mpz_coerce z
+ ulong_coerce n
+PREINIT:
+ SV *sv;
+ mpz root;
+ int exact;
+PPCODE:
+ root = new_mpz();
+ exact = mpz_root (root->m, z, n);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (root, mpz_class_hv));
+ sv = (exact ? &PL_sv_yes : &PL_sv_no); sv_2mortal(sv); PUSHs(sv);
+
+
+void
+rootrem (z, n)
+ mpz_coerce z
+ ulong_coerce n
+PREINIT:
+ SV *sv;
+ mpz root;
+ mpz rem;
+PPCODE:
+ root = new_mpz();
+ rem = new_mpz();
+ mpz_rootrem (root->m, rem->m, z, n);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (root, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (rem, mpz_class_hv));
+
+
+# In the past scan0 and scan1 were described as returning ULONG_MAX which
+# could be obtained in perl with ~0. That wasn't true on 64-bit systems
+# (eg. alpha) with perl 5.005, since in that version IV and UV were still
+# 32-bits.
+#
+# We changed in gmp 4.2 to just say ~0 for the not-found return. It's
+# likely most people have used ~0 rather than POSIX::ULONG_MAX(), so this
+# change should match existing usage. It only actually makes a difference
+# in old perl, since recent versions have gone to 64-bits for IV and UV, the
+# same as a ulong.
+#
+# In perl 5.005 we explicitly mask the mpz return down to 32-bits to get ~0.
+# UV_MAX is no good, it reflects the size of the UV type (64-bits), rather
+# than the size of the values one ought to be storing in an SV (32-bits).
+
+gmp_UV
+scan0 (z, start)
+ mpz_coerce z
+ ulong_coerce start
+ALIAS:
+ GMP::Mpz::scan1 = 1
+PREINIT:
+ static_functable const struct {
+ unsigned long (*op) (mpz_srcptr, unsigned long);
+ } table[] = {
+ { mpz_scan0 }, /* 0 */
+ { mpz_scan1 }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = (*table[ix].op) (z, start);
+ if (PERL_LT (5,6))
+ RETVAL &= 0xFFFFFFFF;
+OUTPUT:
+ RETVAL
+
+
+void
+setbit (sv, bit)
+ SV *sv
+ ulong_coerce bit
+ALIAS:
+ GMP::Mpz::clrbit = 1
+ GMP::Mpz::combit = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, unsigned long);
+ } table[] = {
+ { mpz_setbit }, /* 0 */
+ { mpz_clrbit }, /* 1 */
+ { mpz_combit }, /* 2 */
+ };
+ int use;
+ mpz z;
+CODE:
+ use = use_sv (sv);
+ if (use == USE_MPZ && SvREFCNT(SvRV(sv)) == 1 && ! SvSMAGICAL(sv))
+ {
+ /* our operand is a non-magical mpz with a reference count of 1, so
+ we can just modify it */
+ (*table[ix].op) (SvMPZ(sv)->m, bit);
+ }
+ else
+ {
+ /* otherwise we need to make a new mpz, from whatever we have, and
+ operate on that, possibly invoking magic when storing back */
+ SV *new_sv;
+ mpz z = new_mpz ();
+ mpz_ptr coerce_ptr = coerce_mpz_using (z->m, sv, use);
+ if (coerce_ptr != z->m)
+ mpz_set (z->m, coerce_ptr);
+ (*table[ix].op) (z->m, bit);
+ new_sv = sv_bless (sv_setref_pv (sv_newmortal(), NULL, z),
+ mpz_class_hv);
+ SvSetMagicSV (sv, new_sv);
+ }
+
+
+void
+sqrtrem (z)
+ mpz_coerce z
+PREINIT:
+ SV *sv;
+ mpz root;
+ mpz rem;
+PPCODE:
+ root = new_mpz();
+ rem = new_mpz();
+ mpz_sqrtrem (root->m, rem->m, z);
+ EXTEND (SP, 2);
+ PUSHs (MPX_NEWMORTAL (root, mpz_class_hv));
+ PUSHs (MPX_NEWMORTAL (rem, mpz_class_hv));
+
+
+size_t
+sizeinbase (z, base)
+ mpz_coerce z
+ int base
+CODE:
+ RETVAL = mpz_sizeinbase (z, base);
+OUTPUT:
+ RETVAL
+
+
+int
+tstbit (z, bit)
+ mpz_coerce z
+ ulong_coerce bit
+CODE:
+ RETVAL = mpz_tstbit (z, bit);
+OUTPUT:
+ RETVAL
+
+
+
+#------------------------------------------------------------------------------
+
+MODULE = GMP PACKAGE = GMP::Mpq
+
+
+mpq
+mpq (...)
+ALIAS:
+ GMP::Mpq::new = 1
+CODE:
+ TRACE (printf ("%s new, ix=%ld, items=%d\n", mpq_class, ix, (int) items));
+ RETVAL = new_mpq();
+ switch (items) {
+ case 0:
+ mpq_set_ui (RETVAL->m, 0L, 1L);
+ break;
+ case 1:
+ {
+ mpq_ptr rp = RETVAL->m;
+ mpq_ptr cp = coerce_mpq (rp, ST(0));
+ if (cp != rp)
+ mpq_set (rp, cp);
+ }
+ break;
+ case 2:
+ {
+ mpz_ptr rp, cp;
+ rp = mpq_numref (RETVAL->m);
+ cp = coerce_mpz (rp, ST(0));
+ if (cp != rp)
+ mpz_set (rp, cp);
+ rp = mpq_denref (RETVAL->m);
+ cp = coerce_mpz (rp, ST(1));
+ if (cp != rp)
+ mpz_set (rp, cp);
+ }
+ break;
+ default:
+ croak ("%s new: invalid arguments", mpq_class);
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+overload_constant (str, pv, d1, ...)
+ const_string_assume str
+ SV *pv
+ dummy d1
+PREINIT:
+ SV *sv;
+ mpq q;
+PPCODE:
+ TRACE (printf ("%s constant: %s\n", mpq_class, str));
+ q = new_mpq();
+ if (mpq_set_str (q->m, str, 0) == 0)
+ { sv = sv_bless (sv_setref_pv (sv_newmortal(), NULL, q), mpq_class_hv); }
+ else
+ { free_mpq (q); sv = pv; }
+ XPUSHs(sv);
+
+
+mpq
+overload_copy (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+CODE:
+ RETVAL = new_mpq();
+ mpq_set (RETVAL->m, q->m);
+OUTPUT:
+ RETVAL
+
+
+void
+DESTROY (q)
+ mpq_assume q
+CODE:
+ TRACE (printf ("%s DESTROY %p\n", mpq_class, q));
+ free_mpq (q);
+
+
+malloced_string
+overload_string (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+CODE:
+ TRACE (printf ("%s overload_string %p\n", mpq_class, q));
+ RETVAL = mpq_get_str (NULL, 10, q->m);
+OUTPUT:
+ RETVAL
+
+
+mpq
+overload_add (xv, yv, order)
+ SV *xv
+ SV *yv
+ SV *order
+ALIAS:
+ GMP::Mpq::overload_sub = 1
+ GMP::Mpq::overload_mul = 2
+ GMP::Mpq::overload_div = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr, mpq_srcptr, mpq_srcptr);
+ } table[] = {
+ { mpq_add }, /* 0 */
+ { mpq_sub }, /* 1 */
+ { mpq_mul }, /* 2 */
+ { mpq_div }, /* 3 */
+ };
+CODE:
+ TRACE (printf ("%s binary\n", mpf_class));
+ assert_table (ix);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (xv, yv);
+ RETVAL = new_mpq();
+ (*table[ix].op) (RETVAL->m,
+ coerce_mpq (tmp_mpq_0, xv),
+ coerce_mpq (tmp_mpq_1, yv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_addeq (x, y, o)
+ mpq_assume x
+ mpq_coerce y
+ order_noswap o
+ALIAS:
+ GMP::Mpq::overload_subeq = 1
+ GMP::Mpq::overload_muleq = 2
+ GMP::Mpq::overload_diveq = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr, mpq_srcptr, mpq_srcptr);
+ } table[] = {
+ { mpq_add }, /* 0 */
+ { mpq_sub }, /* 1 */
+ { mpq_mul }, /* 2 */
+ { mpq_div }, /* 3 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (x->m, x->m, y);
+ XPUSHs(ST(0));
+
+
+mpq
+overload_lshift (qv, nv, order)
+ SV *qv
+ SV *nv
+ SV *order
+ALIAS:
+ GMP::Mpq::overload_rshift = 1
+ GMP::Mpq::overload_pow = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr, mpq_srcptr, unsigned long);
+ } table[] = {
+ { mpq_mul_2exp }, /* 0 */
+ { mpq_div_2exp }, /* 1 */
+ { x_mpq_pow_ui }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (qv, nv);
+ RETVAL = new_mpq();
+ (*table[ix].op) (RETVAL->m, coerce_mpq (RETVAL->m, qv), coerce_ulong (nv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_lshifteq (q, n, o)
+ mpq_assume q
+ ulong_coerce n
+ order_noswap o
+ALIAS:
+ GMP::Mpq::overload_rshifteq = 1
+ GMP::Mpq::overload_poweq = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr, mpq_srcptr, unsigned long);
+ } table[] = {
+ { mpq_mul_2exp }, /* 0 */
+ { mpq_div_2exp }, /* 1 */
+ { x_mpq_pow_ui }, /* 2 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (q->m, q->m, n);
+ XPUSHs(ST(0));
+
+
+void
+overload_inc (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpq::overload_dec = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+ } table[] = {
+ { mpz_add }, /* 0 */
+ { mpz_sub }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ (*table[ix].op) (mpq_numref(q->m), mpq_numref(q->m), mpq_denref(q->m));
+
+
+mpq
+overload_abs (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpq::overload_neg = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpq_ptr w, mpq_srcptr x);
+ } table[] = {
+ { mpq_abs }, /* 0 */
+ { mpq_neg }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpq();
+ (*table[ix].op) (RETVAL->m, q->m);
+OUTPUT:
+ RETVAL
+
+
+int
+overload_spaceship (x, y, order)
+ mpq_assume x
+ mpq_coerce y
+ SV *order
+CODE:
+ RETVAL = mpq_cmp (x->m, y);
+ RETVAL = SGN (RETVAL);
+ if (order == &PL_sv_yes)
+ RETVAL = -RETVAL;
+OUTPUT:
+ RETVAL
+
+
+bool
+overload_bool (q, d1, d2)
+ mpq_assume q
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpq::overload_not = 1
+CODE:
+ RETVAL = (mpq_sgn (q->m) != 0) ^ ix;
+OUTPUT:
+ RETVAL
+
+
+bool
+overload_eq (x, yv, d)
+ mpq_assume x
+ SV *yv
+ dummy d
+ALIAS:
+ GMP::Mpq::overload_ne = 1
+PREINIT:
+ int use;
+CODE:
+ use = use_sv (yv);
+ switch (use) {
+ case USE_IVX:
+ case USE_UVX:
+ case USE_MPZ:
+ RETVAL = 0;
+ if (x_mpq_integer_p (x->m))
+ {
+ switch (use) {
+ case USE_IVX:
+ RETVAL = (mpz_cmp_si (mpq_numref(x->m), SvIVX(yv)) == 0);
+ break;
+ case USE_UVX:
+ RETVAL = (mpz_cmp_ui (mpq_numref(x->m), SvUVX(yv)) == 0);
+ break;
+ case USE_MPZ:
+ RETVAL = (mpz_cmp (mpq_numref(x->m), SvMPZ(yv)->m) == 0);
+ break;
+ }
+ }
+ break;
+
+ case USE_MPQ:
+ RETVAL = (mpq_equal (x->m, SvMPQ(yv)->m) != 0);
+ break;
+
+ default:
+ RETVAL = (mpq_equal (x->m, coerce_mpq_using (tmp_mpq_0, yv, use)) != 0);
+ break;
+ }
+ RETVAL ^= ix;
+OUTPUT:
+ RETVAL
+
+
+void
+canonicalize (q)
+ mpq q
+CODE:
+ mpq_canonicalize (q->m);
+
+
+mpq
+inv (q)
+ mpq_coerce q
+CODE:
+ RETVAL = new_mpq();
+ mpq_inv (RETVAL->m, q);
+OUTPUT:
+ RETVAL
+
+
+mpz
+num (q)
+ mpq q
+ALIAS:
+ GMP::Mpq::den = 1
+CODE:
+ RETVAL = new_mpz();
+ mpz_set (RETVAL->m, (ix == 0 ? mpq_numref(q->m) : mpq_denref(q->m)));
+OUTPUT:
+ RETVAL
+
+
+
+#------------------------------------------------------------------------------
+
+MODULE = GMP PACKAGE = GMP::Mpf
+
+
+mpf
+mpf (...)
+ALIAS:
+ GMP::Mpf::new = 1
+PREINIT:
+ unsigned long prec;
+CODE:
+ TRACE (printf ("%s new\n", mpf_class));
+ if (items > 2)
+ croak ("%s new: invalid arguments", mpf_class);
+ prec = (items == 2 ? coerce_ulong (ST(1)) : mpf_get_default_prec());
+ RETVAL = new_mpf (prec);
+ if (items >= 1)
+ {
+ SV *sv = ST(0);
+ my_mpf_set_sv_using (RETVAL, sv, use_sv(sv));
+ }
+OUTPUT:
+ RETVAL
+
+
+mpf
+overload_constant (sv, d1, d2, ...)
+ SV *sv
+ dummy d1
+ dummy d2
+CODE:
+ assert (SvPOK (sv));
+ TRACE (printf ("%s constant: %s\n", mpq_class, SvPVX(sv)));
+ RETVAL = new_mpf (mpf_get_default_prec());
+ my_mpf_set_svstr (RETVAL, sv);
+OUTPUT:
+ RETVAL
+
+
+mpf
+overload_copy (f, d1, d2)
+ mpf_assume f
+ dummy d1
+ dummy d2
+CODE:
+ TRACE (printf ("%s copy\n", mpf_class));
+ RETVAL = new_mpf (mpf_get_prec (f));
+ mpf_set (RETVAL, f);
+OUTPUT:
+ RETVAL
+
+
+void
+DESTROY (f)
+ mpf_assume f
+CODE:
+ TRACE (printf ("%s DESTROY %p\n", mpf_class, f));
+ mpf_clear (f);
+ Safefree (f);
+ assert_support (mpf_count--);
+ TRACE_ACTIVE ();
+
+
+mpf
+overload_add (x, y, order)
+ mpf_assume x
+ mpf_coerce_st0 y
+ SV *order
+ALIAS:
+ GMP::Mpf::overload_sub = 1
+ GMP::Mpf::overload_mul = 2
+ GMP::Mpf::overload_div = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr, mpf_srcptr, mpf_srcptr);
+ } table[] = {
+ { mpf_add }, /* 0 */
+ { mpf_sub }, /* 1 */
+ { mpf_mul }, /* 2 */
+ { mpf_div }, /* 3 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpf (mpf_get_prec (x));
+ if (order == &PL_sv_yes)
+ MPF_PTR_SWAP (x, y);
+ (*table[ix].op) (RETVAL, x, y);
+OUTPUT:
+ RETVAL
+
+
+void
+overload_addeq (x, y, o)
+ mpf_assume x
+ mpf_coerce_st0 y
+ order_noswap o
+ALIAS:
+ GMP::Mpf::overload_subeq = 1
+ GMP::Mpf::overload_muleq = 2
+ GMP::Mpf::overload_diveq = 3
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr, mpf_srcptr, mpf_srcptr);
+ } table[] = {
+ { mpf_add }, /* 0 */
+ { mpf_sub }, /* 1 */
+ { mpf_mul }, /* 2 */
+ { mpf_div }, /* 3 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (x, x, y);
+ XPUSHs(ST(0));
+
+
+mpf
+overload_lshift (fv, nv, order)
+ SV *fv
+ SV *nv
+ SV *order
+ALIAS:
+ GMP::Mpf::overload_rshift = 1
+ GMP::Mpf::overload_pow = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr, mpf_srcptr, unsigned long);
+ } table[] = {
+ { mpf_mul_2exp }, /* 0 */
+ { mpf_div_2exp }, /* 1 */
+ { mpf_pow_ui }, /* 2 */
+ };
+ mpf f;
+ unsigned long prec;
+CODE:
+ assert_table (ix);
+ MPF_ASSUME (f, fv);
+ prec = mpf_get_prec (f);
+ if (order == &PL_sv_yes)
+ SV_PTR_SWAP (fv, nv);
+ f = coerce_mpf (tmp_mpf_0, fv, prec);
+ RETVAL = new_mpf (prec);
+ (*table[ix].op) (RETVAL, f, coerce_ulong (nv));
+OUTPUT:
+ RETVAL
+
+
+void
+overload_lshifteq (f, n, o)
+ mpf_assume f
+ ulong_coerce n
+ order_noswap o
+ALIAS:
+ GMP::Mpf::overload_rshifteq = 1
+ GMP::Mpf::overload_poweq = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr, mpf_srcptr, unsigned long);
+ } table[] = {
+ { mpf_mul_2exp }, /* 0 */
+ { mpf_div_2exp }, /* 1 */
+ { mpf_pow_ui }, /* 2 */
+ };
+PPCODE:
+ assert_table (ix);
+ (*table[ix].op) (f, f, n);
+ XPUSHs(ST(0));
+
+
+mpf
+overload_abs (f, d1, d2)
+ mpf_assume f
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpf::overload_neg = 1
+ GMP::Mpf::overload_sqrt = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr w, mpf_srcptr x);
+ } table[] = {
+ { mpf_abs }, /* 0 */
+ { mpf_neg }, /* 1 */
+ { mpf_sqrt }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpf (mpf_get_prec (f));
+ (*table[ix].op) (RETVAL, f);
+OUTPUT:
+ RETVAL
+
+
+void
+overload_inc (f, d1, d2)
+ mpf_assume f
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpf::overload_dec = 1
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr w, mpf_srcptr x, unsigned long y);
+ } table[] = {
+ { mpf_add_ui }, /* 0 */
+ { mpf_sub_ui }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ (*table[ix].op) (f, f, 1L);
+
+
+int
+overload_spaceship (xv, yv, order)
+ SV *xv
+ SV *yv
+ SV *order
+PREINIT:
+ mpf x;
+CODE:
+ MPF_ASSUME (x, xv);
+ switch (use_sv (yv)) {
+ case USE_IVX:
+ RETVAL = mpf_cmp_si (x, SvIVX(yv));
+ break;
+ case USE_UVX:
+ RETVAL = mpf_cmp_ui (x, SvUVX(yv));
+ break;
+ case USE_NVX:
+ RETVAL = mpf_cmp_d (x, SvNVX(yv));
+ break;
+ case USE_PVX:
+ {
+ STRLEN len;
+ const char *str = SvPV (yv, len);
+ /* enough for all digits of the string */
+ tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64);
+ if (mpf_set_str (tmp_mpf_0->m, str, 10) != 0)
+ croak ("%s <=>: invalid string format", mpf_class);
+ RETVAL = mpf_cmp (x, tmp_mpf_0->m);
+ }
+ break;
+ case USE_MPZ:
+ RETVAL = - x_mpz_cmp_f (SvMPZ(yv)->m, x);
+ break;
+ case USE_MPF:
+ RETVAL = mpf_cmp (x, SvMPF(yv));
+ break;
+ default:
+ RETVAL = mpq_cmp (coerce_mpq (tmp_mpq_0, xv),
+ coerce_mpq (tmp_mpq_1, yv));
+ break;
+ }
+ RETVAL = SGN (RETVAL);
+ if (order == &PL_sv_yes)
+ RETVAL = -RETVAL;
+OUTPUT:
+ RETVAL
+
+
+bool
+overload_bool (f, d1, d2)
+ mpf_assume f
+ dummy d1
+ dummy d2
+ALIAS:
+ GMP::Mpf::overload_not = 1
+CODE:
+ RETVAL = (mpf_sgn (f) != 0) ^ ix;
+OUTPUT:
+ RETVAL
+
+
+mpf
+ceil (f)
+ mpf_coerce_def f
+ALIAS:
+ GMP::Mpf::floor = 1
+ GMP::Mpf::trunc = 2
+PREINIT:
+ static_functable const struct {
+ void (*op) (mpf_ptr w, mpf_srcptr x);
+ } table[] = {
+ { mpf_ceil }, /* 0 */
+ { mpf_floor }, /* 1 */
+ { mpf_trunc }, /* 2 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpf (mpf_get_prec (f));
+ (*table[ix].op) (RETVAL, f);
+OUTPUT:
+ RETVAL
+
+
+unsigned long
+get_default_prec ()
+CODE:
+ RETVAL = mpf_get_default_prec();
+OUTPUT:
+ RETVAL
+
+
+unsigned long
+get_prec (f)
+ mpf_coerce_def f
+CODE:
+ RETVAL = mpf_get_prec (f);
+OUTPUT:
+ RETVAL
+
+
+bool
+mpf_eq (xv, yv, bits)
+ SV *xv
+ SV *yv
+ ulong_coerce bits
+PREINIT:
+ mpf x, y;
+CODE:
+ TRACE (printf ("%s eq\n", mpf_class));
+ coerce_mpf_pair (&x,xv, &y,yv);
+ RETVAL = mpf_eq (x, y, bits);
+OUTPUT:
+ RETVAL
+
+
+mpf
+reldiff (xv, yv)
+ SV *xv
+ SV *yv
+PREINIT:
+ mpf x, y;
+ unsigned long prec;
+CODE:
+ TRACE (printf ("%s reldiff\n", mpf_class));
+ prec = coerce_mpf_pair (&x,xv, &y,yv);
+ RETVAL = new_mpf (prec);
+ mpf_reldiff (RETVAL, x, y);
+OUTPUT:
+ RETVAL
+
+
+void
+set_default_prec (prec)
+ ulong_coerce prec
+CODE:
+ TRACE (printf ("%s set_default_prec %lu\n", mpf_class, prec));
+ mpf_set_default_prec (prec);
+
+
+void
+set_prec (sv, prec)
+ SV *sv
+ ulong_coerce prec
+PREINIT:
+ mpf_ptr old_f, new_f;
+ int use;
+CODE:
+ TRACE (printf ("%s set_prec to %lu\n", mpf_class, prec));
+ use = use_sv (sv);
+ if (use == USE_MPF)
+ {
+ old_f = SvMPF(sv);
+ if (SvREFCNT(SvRV(sv)) == 1)
+ mpf_set_prec (old_f, prec);
+ else
+ {
+ TRACE (printf (" fork new mpf\n"));
+ new_f = new_mpf (prec);
+ mpf_set (new_f, old_f);
+ goto setref;
+ }
+ }
+ else
+ {
+ TRACE (printf (" coerce to mpf\n"));
+ new_f = new_mpf (prec);
+ my_mpf_set_sv_using (new_f, sv, use);
+ setref:
+ sv_bless (sv_setref_pv (sv, NULL, new_f), mpf_class_hv);
+ }
+
+
+
+#------------------------------------------------------------------------------
+
+MODULE = GMP PACKAGE = GMP::Rand
+
+randstate
+new (...)
+ALIAS:
+ GMP::Rand::randstate = 1
+CODE:
+ TRACE (printf ("%s new\n", rand_class));
+ New (GMP_MALLOC_ID, RETVAL, 1, __gmp_randstate_struct);
+ TRACE (printf (" RETVAL %p\n", RETVAL));
+ assert_support (rand_count++);
+ TRACE_ACTIVE ();
+
+ if (items == 0)
+ {
+ gmp_randinit_default (RETVAL);
+ }
+ else
+ {
+ if (SvROK (ST(0)) && sv_derived_from (ST(0), rand_class))
+ {
+ if (items != 1)
+ goto invalid;
+ gmp_randinit_set (RETVAL, SvRANDSTATE (ST(0)));
+ }
+ else
+ {
+ STRLEN len;
+ const char *method = SvPV (ST(0), len);
+ assert (len == strlen (method));
+ if (strcmp (method, "lc_2exp") == 0)
+ {
+ if (items != 4)
+ goto invalid;
+ gmp_randinit_lc_2exp (RETVAL,
+ coerce_mpz (tmp_mpz_0, ST(1)),
+ coerce_ulong (ST(2)),
+ coerce_ulong (ST(3)));
+ }
+ else if (strcmp (method, "lc_2exp_size") == 0)
+ {
+ if (items != 2)
+ goto invalid;
+ if (! gmp_randinit_lc_2exp_size (RETVAL, coerce_ulong (ST(1))))
+ {
+ Safefree (RETVAL);
+ XSRETURN_UNDEF;
+ }
+ }
+ else if (strcmp (method, "mt") == 0)
+ {
+ if (items != 1)
+ goto invalid;
+ gmp_randinit_mt (RETVAL);
+ }
+ else
+ {
+ invalid:
+ croak ("%s new: invalid arguments", rand_class);
+ }
+ }
+ }
+OUTPUT:
+ RETVAL
+
+
+void
+DESTROY (r)
+ randstate r
+CODE:
+ TRACE (printf ("%s DESTROY\n", rand_class));
+ gmp_randclear (r);
+ Safefree (r);
+ assert_support (rand_count--);
+ TRACE_ACTIVE ();
+
+
+void
+seed (r, z)
+ randstate r
+ mpz_coerce z
+CODE:
+ gmp_randseed (r, z);
+
+
+mpz
+mpz_urandomb (r, bits)
+ randstate r
+ ulong_coerce bits
+ALIAS:
+ GMP::Rand::mpz_rrandomb = 1
+PREINIT:
+ static_functable const struct {
+ void (*fun) (mpz_ptr, gmp_randstate_t r, unsigned long bits);
+ } table[] = {
+ { mpz_urandomb }, /* 0 */
+ { mpz_rrandomb }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = new_mpz();
+ (*table[ix].fun) (RETVAL->m, r, bits);
+OUTPUT:
+ RETVAL
+
+
+mpz
+mpz_urandomm (r, m)
+ randstate r
+ mpz_coerce m
+CODE:
+ RETVAL = new_mpz();
+ mpz_urandomm (RETVAL->m, r, m);
+OUTPUT:
+ RETVAL
+
+
+mpf
+mpf_urandomb (r, bits)
+ randstate r
+ ulong_coerce bits
+CODE:
+ RETVAL = new_mpf (bits);
+ mpf_urandomb (RETVAL, r, bits);
+OUTPUT:
+ RETVAL
+
+
+unsigned long
+gmp_urandomb_ui (r, bits)
+ randstate r
+ ulong_coerce bits
+ALIAS:
+ GMP::Rand::gmp_urandomm_ui = 1
+PREINIT:
+ static_functable const struct {
+ unsigned long (*fun) (gmp_randstate_t r, unsigned long bits);
+ } table[] = {
+ { gmp_urandomb_ui }, /* 0 */
+ { gmp_urandomm_ui }, /* 1 */
+ };
+CODE:
+ assert_table (ix);
+ RETVAL = (*table[ix].fun) (r, bits);
+OUTPUT:
+ RETVAL
diff --git a/gmp/demos/perl/GMP/Mpf.pm b/gmp/demos/perl/GMP/Mpf.pm
new file mode 100644
index 0000000000..4c0dec6cea
--- /dev/null
+++ b/gmp/demos/perl/GMP/Mpf.pm
@@ -0,0 +1,106 @@
+# GMP mpf module.
+
+# Copyright 2001, 2003 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+package GMP::Mpf;
+
+require GMP;
+require Exporter;
+@ISA = qw(GMP Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw();
+%EXPORT_TAGS = ('all' => [qw(
+ ceil floor get_default_prec get_prec mpf mpf_eq
+ reldiff set_default_prec set_prec trunc)],
+ 'constants' => [@EXPORT],
+ 'noconstants' => [@EXPORT]);
+Exporter::export_ok_tags('all');
+
+use overload
+ '+' => \&overload_add, '+=' => \&overload_addeq,
+ '-' => \&overload_sub, '-=' => \&overload_subeq,
+ '*' => \&overload_mul, '*=' => \&overload_muleq,
+ '/' => \&overload_div, '/=' => \&overload_diveq,
+ '**' => \&overload_pow, '**=' => \&overload_poweq,
+ '<<' => \&overload_lshift, '<<=' => \&overload_lshifteq,
+ '>>' => \&overload_rshift, '>>=' => \&overload_rshifteq,
+
+ 'bool' => \&overload_bool,
+ 'not' => \&overload_not,
+ '!' => \&overload_not,
+ '<=>' => \&overload_spaceship,
+ '++' => \&overload_inc,
+ '--' => \&overload_dec,
+ 'abs' => \&overload_abs,
+ 'neg' => \&overload_neg,
+ 'sqrt' => \&overload_sqrt,
+ '=' => \&overload_copy,
+ '""' => \&overload_string;
+
+sub import {
+ foreach (@_) {
+ if ($_ eq ':constants') {
+ overload::constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ } elsif ($_ eq ':noconstants') {
+ overload::remove_constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ }
+ }
+ goto &Exporter::import;
+}
+
+
+sub overload_string {
+ my $fmt;
+ BEGIN { $^W = 0; }
+ if (defined ($#)) {
+ $fmt = $#;
+ BEGIN { $^W = 1; }
+ # protect against calling sprintf_internal with a bad format
+ if ($fmt !~ /^((%%|[^%])*%[-+ .\d]*)([eEfgG](%%|[^%])*)$/) {
+ die "GMP::Mpf: invalid \$# format: $#\n";
+ }
+ $fmt = $1 . 'F' . $3;
+ } else {
+ $fmt = '%.Fg';
+ }
+ GMP::sprintf_internal ($fmt, $_[0]);
+}
+
+1;
+__END__
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/gmp/demos/perl/GMP/Mpq.pm b/gmp/demos/perl/GMP/Mpq.pm
new file mode 100644
index 0000000000..fe010849e0
--- /dev/null
+++ b/gmp/demos/perl/GMP/Mpq.pm
@@ -0,0 +1,89 @@
+# GMP mpq module.
+
+# Copyright 2001 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+package GMP::Mpq;
+
+require GMP;
+require Exporter;
+@ISA = qw(GMP Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw();
+%EXPORT_TAGS = ('all' => [qw(canonicalize den inv mpq num)],
+ 'constants' => [@EXPORT],
+ 'noconstants' => [@EXPORT] );
+Exporter::export_ok_tags('all');
+
+use overload
+ '+' => \&overload_add, '+=' => \&overload_addeq,
+ '-' => \&overload_sub, '-=' => \&overload_subeq,
+ '*' => \&overload_mul, '*=' => \&overload_muleq,
+ '/' => \&overload_div, '/=' => \&overload_diveq,
+ '**' => \&overload_pow, '**=' => \&overload_poweq,
+ '<<' => \&overload_lshift, '<<=' => \&overload_lshifteq,
+ '>>' => \&overload_rshift, '>>=' => \&overload_rshifteq,
+
+ 'bool' => \&overload_bool,
+ 'not' => \&overload_not,
+ '!' => \&overload_not,
+ '==' => \&overload_eq,
+ '!=' => \&overload_ne,
+ '<=>' => \&overload_spaceship,
+ '++' => \&overload_inc,
+ '--' => \&overload_dec,
+ 'abs' => \&overload_abs,
+ 'neg' => \&overload_neg,
+ '=' => \&overload_copy,
+ '""' => \&overload_string;
+
+my $constants = { };
+
+sub import {
+ foreach (@_) {
+ if ($_ eq ':constants') {
+ overload::constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ } elsif ($_ eq ':noconstants') {
+ overload::remove_constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ }
+ }
+ goto &Exporter::import;
+}
+
+1;
+__END__
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/gmp/demos/perl/GMP/Mpz.pm b/gmp/demos/perl/GMP/Mpz.pm
new file mode 100644
index 0000000000..27e6336775
--- /dev/null
+++ b/gmp/demos/perl/GMP/Mpz.pm
@@ -0,0 +1,101 @@
+# GMP mpz module.
+
+# Copyright 2001-2003 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+package GMP::Mpz;
+
+require GMP;
+require Exporter;
+@ISA = qw(GMP Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw();
+%EXPORT_TAGS = ('all' => [qw(
+ bin cdiv cdiv_2exp clrbit combit congruent_p
+ congruent_2exp_p divexact divisible_p
+ divisible_2exp_p even_p fac fdiv fdiv_2exp fib
+ fib2 gcd gcdext hamdist invert jacobi kronecker
+ lcm lucnum lucnum2 mod mpz mpz_export
+ mpz_import nextprime odd_p perfect_power_p
+ perfect_square_p popcount powm probab_prime_p
+ realloc remove root roote rootrem scan0 scan1
+ setbit sizeinbase sqrtrem tdiv tdiv_2exp
+ tstbit)],
+ 'constants' => [@EXPORT],
+ 'noconstants' => [@EXPORT]);
+Exporter::export_ok_tags('all');
+
+use overload
+ '+' => \&overload_add, '+=' => \&overload_addeq,
+ '-' => \&overload_sub, '-=' => \&overload_subeq,
+ '*' => \&overload_mul, '*=' => \&overload_muleq,
+ '/' => \&overload_div, '/=' => \&overload_diveq,
+ '%' => \&overload_rem, '%=' => \&overload_remeq,
+ '<<' => \&overload_lshift, '<<=' => \&overload_lshifteq,
+ '>>' => \&overload_rshift, '>>=' => \&overload_rshifteq,
+ '**' => \&overload_pow, '**=' => \&overload_poweq,
+ '&' => \&overload_and, '&=' => \&overload_andeq,
+ '|' => \&overload_ior, '|=' => \&overload_ioreq,
+ '^' => \&overload_xor, '^=' => \&overload_xoreq,
+
+ 'bool' => \&overload_bool,
+ 'not' => \&overload_not,
+ '!' => \&overload_not,
+ '~' => \&overload_com,
+ '<=>' => \&overload_spaceship,
+ '++' => \&overload_inc,
+ '--' => \&overload_dec,
+ '=' => \&overload_copy,
+ 'abs' => \&overload_abs,
+ 'neg' => \&overload_neg,
+ 'sqrt' => \&overload_sqrt,
+ '""' => \&overload_string;
+
+sub import {
+ foreach (@_) {
+ if ($_ eq ':constants') {
+ overload::constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ } elsif ($_ eq ':noconstants') {
+ overload::remove_constant ('integer' => \&overload_constant,
+ 'binary' => \&overload_constant,
+ 'float' => \&overload_constant);
+ }
+ }
+ goto &Exporter::import;
+}
+
+1;
+__END__
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/gmp/demos/perl/GMP/Rand.pm b/gmp/demos/perl/GMP/Rand.pm
new file mode 100644
index 0000000000..9f7d763dd5
--- /dev/null
+++ b/gmp/demos/perl/GMP/Rand.pm
@@ -0,0 +1,44 @@
+# GMP random numbers module.
+
+# Copyright 2001, 2003 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+package GMP::Rand;
+
+require GMP;
+require Exporter;
+@ISA = qw(GMP Exporter);
+@EXPORT = qw();
+%EXPORT_TAGS = ('all' => [qw(
+ randstate mpf_urandomb mpz_rrandomb
+ mpz_urandomb mpz_urandomm gmp_urandomb_ui
+ gmp_urandomm_ui)]);
+Exporter::export_ok_tags('all');
+1;
+__END__
diff --git a/gmp/demos/perl/INSTALL b/gmp/demos/perl/INSTALL
new file mode 100644
index 0000000000..f3d7c53b1c
--- /dev/null
+++ b/gmp/demos/perl/INSTALL
@@ -0,0 +1,88 @@
+Copyright 2001, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ GMP PERL MODULE INSTALLATION
+
+
+This module can be compiled within the GMP source directory or moved
+elsewhere and compiled. An installed GMP can be used, or a specified
+GMP build tree. Both static and shared GMP builds will work.
+
+The simplest case is when GMP has been installed to a standard system
+location
+
+ perl Makefile.PL
+ make
+
+If not yet installed then the top-level GMP build directory must be
+specified
+
+ perl Makefile.PL GMP_BUILDDIR=/my/gmp/build
+ make
+
+In any case, with the module built, the sample program provided can be
+run
+
+ perl -Iblib/arch sample.pl
+
+If you built a shared version of libgmp but haven't yet installed it,
+then it might be necessary to add a run-time path to it. For example
+
+ LD_LIBRARY_PATH=/my/gmp/build/.libs perl -Iblib/arch sample.pl
+
+Documentation is provided in pod format in GMP.pm, and will have been
+"man"-ified in the module build
+
+ man -l blib/man3/GMP.3pm
+or
+ man -M`pwd`/blib GMP
+
+A test script is provided, running a large number of more or less
+trivial checks
+
+ make test
+
+The module and its documentation can be installed in the usual way
+
+ make install
+
+This will be into /usr/local or wherever the perl Config module
+directs, but that can be controlled back at the Makefile.PL stage with
+the usual ExtUtils::MakeMaker options.
+
+Once installed, programs using the GMP module become simply
+
+ perl sample.pl
+
+And the documentation read directly too
+
+ man GMP
diff --git a/gmp/demos/perl/Makefile.PL b/gmp/demos/perl/Makefile.PL
new file mode 100644
index 0000000000..a676710c1c
--- /dev/null
+++ b/gmp/demos/perl/Makefile.PL
@@ -0,0 +1,82 @@
+# Makefile for GMP perl module.
+
+# Copyright 2001, 2003, 2004 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Bugs:
+#
+# When the generated Makefile re-runs "perl Makefile.PL" the GMP_BUILDDIR
+# parameter is lost.
+
+
+use ExtUtils::MakeMaker;
+
+
+# Find and remove our parameters
+@ARGV = map {
+ if (/^GMP_BUILDDIR=(.*)/) {
+ $GMP_BUILDDIR=$1; ();
+ } else {
+ $_;
+ }
+} (@ARGV);
+
+$INC = "";
+$LIBS = "-lgmp";
+$OBJECT = "GMP.o";
+
+if (defined $GMP_BUILDDIR) {
+ if (! -f "$GMP_BUILDDIR/libgmp.la") {
+ die "$GMP_BUILDDIR doesn't contain libgmp.la\n" .
+ "if it's really a gmp build directory then go there and run \"make libgmp.la\"\n";
+ }
+ $INC = "-I$GMP_BUILDDIR $INC";
+ $LIBS = "-L$GMP_BUILDDIR/.libs $LIBS";
+}
+
+WriteMakefile(
+ NAME => 'GMP',
+ VERSION => '2.00',
+ LIBS => [$LIBS],
+ OBJECT => $OBJECT,
+ INC => $INC,
+ clean => { FILES => 'test.tmp' },
+ PM => {
+ 'GMP.pm' => '$(INST_LIBDIR)/GMP.pm',
+ 'GMP/Mpz.pm' => '$(INST_LIBDIR)/GMP/Mpz.pm',
+ 'GMP/Mpq.pm' => '$(INST_LIBDIR)/GMP/Mpq.pm',
+ 'GMP/Mpf.pm' => '$(INST_LIBDIR)/GMP/Mpf.pm',
+ 'GMP/Rand.pm' => '$(INST_LIBDIR)/GMP/Rand.pm',
+ }
+ );
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/gmp/demos/perl/sample.pl b/gmp/demos/perl/sample.pl
new file mode 100644
index 0000000000..8a10ee1ebb
--- /dev/null
+++ b/gmp/demos/perl/sample.pl
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+# Some sample GMP module operations
+
+# Copyright 2001, 2004 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+use strict;
+
+
+use GMP;
+print "using GMP module $GMP::VERSION and GMP library ",GMP::version(),"\n";
+
+
+use GMP::Mpz qw(:all);
+print "the 200th fibonacci number is ", fib(200), "\n";
+print "next prime after 10**30 is (probably) ", nextprime(mpz(10)**30), "\n";
+
+
+use GMP::Mpq qw(:constants);
+print "the 7th harmonic number is ", 1+1/2+1/3+1/4+1/5+1/6+1/7, "\n";
+use GMP::Mpq qw(:noconstants);
+
+
+use GMP::Mpf qw(mpf);
+my $f = mpf(1,180);
+$f >>= 180;
+$f += 1;
+print "a sample mpf is $f\n";
diff --git a/gmp/demos/perl/test.pl b/gmp/demos/perl/test.pl
new file mode 100644
index 0000000000..2b54089165
--- /dev/null
+++ b/gmp/demos/perl/test.pl
@@ -0,0 +1,2179 @@
+#!/usr/bin/perl -w
+
+# GMP perl module tests
+
+# Copyright 2001-2003 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# These tests aim to exercise the many possible combinations of operands
+# etc, and to run all functions at least once, which if nothing else will
+# check everything intended is in the :all list.
+#
+# Use the following in .emacs to match test failure messages.
+#
+# ;; perl "Test" module error messages
+# (eval-after-load "compile"
+# '(add-to-list
+# 'compilation-error-regexp-alist
+# '("^.*Failed test [0-9]+ in \\([^ ]+\\) at line \\([0-9]+\\)" 1 2)))
+
+
+use strict;
+use Test;
+
+BEGIN {
+ plan tests => 123,
+ onfail => sub { print "there were failures\n" },
+}
+
+use GMP qw(:all);
+use GMP::Mpz qw(:all);
+use GMP::Mpq qw(:all);
+use GMP::Mpf qw(:all);
+use GMP::Rand qw(:all);
+
+use GMP::Mpz qw(:constants);
+use GMP::Mpz qw(:noconstants);
+use GMP::Mpq qw(:constants);
+use GMP::Mpq qw(:noconstants);
+use GMP::Mpf qw(:constants);
+use GMP::Mpf qw(:noconstants);
+
+package Mytie;
+use Exporter;
+use vars qw($val $fetched $stored);
+$val = 0;
+$fetched = 0;
+$stored = 0;
+sub TIESCALAR {
+ my ($class, $newval) = @_;
+ my $var = 'mytie dummy refed var';
+ $val = $newval;
+ $fetched = 0;
+ $stored = 0;
+ return bless \$var, $class;
+}
+sub FETCH {
+ my ($self) = @_;
+ $fetched++;
+ return $val;
+}
+sub STORE {
+ my ($self, $newval) = @_;
+ $val = $newval;
+ $stored++;
+}
+package main;
+
+# check Mytie does what it should
+{ tie my $t, 'Mytie', 123;
+ ok ($Mytie::val == 123);
+ $Mytie::val = 456;
+ ok ($t == 456);
+ $t = 789;
+ ok ($Mytie::val == 789);
+}
+
+
+# Usage: str(x)
+# Return x forced to a string, not a PVIV.
+#
+sub str {
+ my $s = "$_[0]" . "";
+ return $s;
+}
+
+my $ivnv_2p128 = 65536.0 * 65536.0 * 65536.0 * 65536.0
+ * 65536.0 * 65536.0 * 65536.0 * 65536.0;
+kill (0, $ivnv_2p128);
+my $str_2p128 = '340282366920938463463374607431768211456';
+
+my $uv_max = ~ 0;
+my $uv_max_str = ~ 0;
+$uv_max_str = "$uv_max_str";
+$uv_max_str = "" . "$uv_max_str";
+
+
+#------------------------------------------------------------------------------
+# GMP::version
+
+use GMP qw(version);
+print '$GMP::VERSION ',$GMP::VERSION,' GMP::version() ',version(),"\n";
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::new
+
+ok (mpz(0) == 0);
+ok (mpz('0') == 0);
+ok (mpz(substr('101',1,1)) == 0);
+ok (mpz(0.0) == 0);
+ok (mpz(mpz(0)) == 0);
+ok (mpz(mpq(0)) == 0);
+ok (mpz(mpf(0)) == 0);
+
+{ tie my $t, 'Mytie', 0;
+ ok (mpz($t) == 0);
+ ok ($Mytie::fetched > 0);
+}
+{ tie my $t, 'Mytie', '0';
+ ok (mpz($t) == 0);
+ ok ($Mytie::fetched > 0);
+}
+{ tie my $t, 'Mytie', substr('101',1,1); ok (mpz($t) == 0); }
+{ tie my $t, 'Mytie', 0.0; ok (mpz($t) == 0); }
+{ tie my $t, 'Mytie', mpz(0); ok (mpz($t) == 0); }
+{ tie my $t, 'Mytie', mpq(0); ok (mpz($t) == 0); }
+{ tie my $t, 'Mytie', mpf(0); ok (mpz($t) == 0); }
+
+ok (mpz(-123) == -123);
+ok (mpz('-123') == -123);
+ok (mpz(substr('1-1231',1,4)) == -123);
+ok (mpz(-123.0) == -123);
+ok (mpz(mpz(-123)) == -123);
+ok (mpz(mpq(-123)) == -123);
+ok (mpz(mpf(-123)) == -123);
+
+{ tie my $t, 'Mytie', -123; ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', '-123'; ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', substr('1-1231',1,4); ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', -123.0; ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', mpz(-123); ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', mpq(-123); ok (mpz($t) == -123); }
+{ tie my $t, 'Mytie', mpf(-123); ok (mpz($t) == -123); }
+
+ok (mpz($ivnv_2p128) == $str_2p128);
+{ tie my $t, 'Mytie', $ivnv_2p128; ok (mpz($t) == $str_2p128); }
+
+ok (mpz($uv_max) > 0);
+ok (mpz($uv_max) == mpz($uv_max_str));
+{ tie my $t, 'Mytie', $uv_max; ok (mpz($t) > 0); }
+{ tie my $t, 'Mytie', $uv_max; ok (mpz($t) == mpz($uv_max_str)); }
+
+{ my $s = '999999999999999999999999999999';
+ kill (0, $s);
+ ok (mpz($s) == '999999999999999999999999999999');
+ tie my $t, 'Mytie', $s;
+ ok (mpz($t) == '999999999999999999999999999999');
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_abs
+
+ok (abs(mpz(0)) == 0);
+ok (abs(mpz(123)) == 123);
+ok (abs(mpz(-123)) == 123);
+
+{ my $x = mpz(-123); $x = abs($x); ok ($x == 123); }
+{ my $x = mpz(0); $x = abs($x); ok ($x == 0); }
+{ my $x = mpz(123); $x = abs($x); ok ($x == 123); }
+
+{ tie my $t, 'Mytie', mpz(0); ok (abs($t) == 0); }
+{ tie my $t, 'Mytie', mpz(123); ok (abs($t) == 123); }
+{ tie my $t, 'Mytie', mpz(-123); ok (abs($t) == 123); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_add
+
+ok (mpz(0) + 1 == 1);
+ok (mpz(-1) + 1 == 0);
+ok (1 + mpz(0) == 1);
+ok (1 + mpz(-1) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_addeq
+
+{ my $a = mpz(7); $a += 1; ok ($a == 8); }
+{ my $a = mpz(7); my $b = $a; $a += 1; ok ($a == 8); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_and
+
+ok ((mpz(3) & 1) == 1);
+ok ((mpz(3) & 4) == 0);
+
+{ my $a = mpz(3); $a &= 1; ok ($a == 1); }
+{ my $a = mpz(3); $a &= 4; ok ($a == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_bool
+
+if (mpz(0)) { ok (0); } else { ok (1); }
+if (mpz(123)) { ok (1); } else { ok (0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_com
+
+ok (~ mpz(0) == -1);
+ok (~ mpz(1) == -2);
+ok (~ mpz(-2) == 1);
+ok (~ mpz(0xFF) == -0x100);
+ok (~ mpz(-0x100) == 0xFF);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_dec
+
+{ my $a = mpz(0); ok ($a-- == 0); ok ($a == -1); }
+{ my $a = mpz(0); ok (--$a == -1); }
+
+{ my $a = mpz(0); my $b = $a; $a--; ok ($a == -1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_div
+
+ok (mpz(6) / 2 == 3);
+ok (mpz(-6) / 2 == -3);
+ok (mpz(6) / -2 == -3);
+ok (mpz(-6) / -2 == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_diveq
+
+{ my $a = mpz(21); $a /= 3; ok ($a == 7); }
+{ my $a = mpz(21); my $b = $a; $a /= 3; ok ($a == 7); ok ($b == 21); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_eq
+
+{ my $a = mpz(0);
+ my $b = $a;
+ $a = mpz(1);
+ ok ($a == 1);
+ ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_inc
+
+{ my $a = mpz(0); ok ($a++ == 0); ok ($a == 1); }
+{ my $a = mpz(0); ok (++$a == 1); }
+
+{ my $a = mpz(0); my $b = $a; $a++; ok ($a == 1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_ior
+
+ok ((mpz(3) | 1) == 3);
+ok ((mpz(3) | 4) == 7);
+
+{ my $a = mpz(3); $a |= 1; ok ($a == 3); }
+{ my $a = mpz(3); $a |= 4; ok ($a == 7); }
+
+ok ((mpz("0xAA") | mpz("0x55")) == mpz("0xFF"));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_lshift
+
+{ my $a = mpz(7) << 1; ok ($a == 14); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_lshifteq
+
+{ my $a = mpz(7); $a <<= 1; ok ($a == 14); }
+{ my $a = mpz(7); my $b = $a; $a <<= 1; ok ($a == 14); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_mul
+
+ok (mpz(2) * 3 == 6);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_muleq
+
+{ my $a = mpz(7); $a *= 3; ok ($a == 21); }
+{ my $a = mpz(7); my $b = $a; $a *= 3; ok ($a == 21); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_neg
+
+ok (- mpz(0) == 0);
+ok (- mpz(123) == -123);
+ok (- mpz(-123) == 123);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_not
+
+if (not mpz(0)) { ok (1); } else { ok (0); }
+if (not mpz(123)) { ok (0); } else { ok (1); }
+
+ok ((! mpz(0)) == 1);
+ok ((! mpz(123)) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_pow
+
+ok (mpz(0) ** 1 == 0);
+ok (mpz(1) ** 1 == 1);
+ok (mpz(2) ** 0 == 1);
+ok (mpz(2) ** 1 == 2);
+ok (mpz(2) ** 2 == 4);
+ok (mpz(2) ** 3 == 8);
+ok (mpz(2) ** 4 == 16);
+
+ok (mpz(0) ** mpz(1) == 0);
+ok (mpz(1) ** mpz(1) == 1);
+ok (mpz(2) ** mpz(0) == 1);
+ok (mpz(2) ** mpz(1) == 2);
+ok (mpz(2) ** mpz(2) == 4);
+ok (mpz(2) ** mpz(3) == 8);
+ok (mpz(2) ** mpz(4) == 16);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_poweq
+
+{ my $a = mpz(3); $a **= 4; ok ($a == 81); }
+{ my $a = mpz(3); my $b = $a; $a **= 4; ok ($a == 81); ok ($b == 3); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_rem
+
+ok (mpz(-8) % 3 == -2);
+ok (mpz(-7) % 3 == -1);
+ok (mpz(-6) % 3 == 0);
+ok (mpz(6) % 3 == 0);
+ok (mpz(7) % 3 == 1);
+ok (mpz(8) % 3 == 2);
+
+{ my $a = mpz(24); $a %= 7; ok ($a == 3); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_rshift
+
+{ my $a = mpz(32) >> 1; ok ($a == 16); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_rshifteq
+
+{ my $a = mpz(32); $a >>= 1; ok ($a == 16); }
+{ my $a = mpz(32); my $b = $a; $a >>= 1; ok ($a == 16); ok ($b == 32); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_spaceship
+
+ok (mpz(0) < 1);
+ok (mpz(0) > -1);
+
+ok (mpz(0) != 1);
+ok (mpz(0) != -1);
+ok (mpz(1) != 0);
+ok (mpz(1) != -1);
+ok (mpz(-1) != 0);
+ok (mpz(-1) != 1);
+
+ok (mpz(0) < 1.0);
+ok (mpz(0) < '1');
+ok (mpz(0) < substr('-1',1,1));
+ok (mpz(0) < mpz(1));
+ok (mpz(0) < mpq(1));
+ok (mpz(0) < mpf(1));
+ok (mpz(0) < $uv_max);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_sqrt
+
+ok (sqrt(mpz(0)) == 0);
+ok (sqrt(mpz(1)) == 1);
+ok (sqrt(mpz(4)) == 2);
+ok (sqrt(mpz(81)) == 9);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_string
+
+{ my $x = mpz(0); ok("$x" eq "0"); }
+{ my $x = mpz(123); ok("$x" eq "123"); }
+{ my $x = mpz(-123); ok("$x" eq "-123"); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_sub
+
+ok (mpz(0) - 1 == -1);
+ok (mpz(1) - 1 == 0);
+ok (1 - mpz(0) == 1);
+ok (1 - mpz(1) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_subeq
+
+{ my $a = mpz(7); $a -= 1; ok ($a == 6); }
+{ my $a = mpz(7); my $b = $a; $a -= 1; ok ($a == 6); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::overload_xor
+
+ok ((mpz(3) ^ 1) == 2);
+ok ((mpz(3) ^ 4) == 7);
+
+{ my $a = mpz(3); $a ^= 1; ok ($a == 2); }
+{ my $a = mpz(3); $a ^= 4; ok ($a == 7); }
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::bin
+
+ok (bin(2,0) == 1);
+ok (bin(2,1) == 2);
+ok (bin(2,2) == 1);
+
+ok (bin(3,0) == 1);
+ok (bin(3,1) == 3);
+ok (bin(3,2) == 3);
+ok (bin(3,3) == 1);
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::cdiv
+
+{ my ($q, $r);
+ ($q, $r) = cdiv (16, 3);
+ ok ($q == 6);
+ ok ($r == -2);
+ ($q, $r) = cdiv (16, -3);
+ ok ($q == -5);
+ ok ($r == 1);
+ ($q, $r) = cdiv (-16, 3);
+ ok ($q == -5);
+ ok ($r == -1);
+ ($q, $r) = cdiv (-16, -3);
+ ok ($q == 6);
+ ok ($r == 2);
+}
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::cdiv_2exp
+
+{ my ($q, $r);
+ ($q, $r) = cdiv_2exp (23, 2);
+ ok ($q == 6);
+ ok ($r == -1);
+ ($q, $r) = cdiv_2exp (-23, 2);
+ ok ($q == -5);
+ ok ($r == -3);
+}
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::clrbit
+
+{ my $a = mpz(3); clrbit ($a, 1); ok ($a == 1);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+{ my $a = mpz(3); clrbit ($a, 2); ok ($a == 3);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+
+{ my $a = 3; clrbit ($a, 1); ok ($a == 1);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+{ my $a = 3; clrbit ($a, 2); ok ($a == 3);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+
+# mutate only given variable
+{ my $a = mpz(3);
+ my $b = $a;
+ clrbit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+}
+{ my $a = 3;
+ my $b = $a;
+ clrbit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+}
+
+{ tie my $a, 'Mytie', mpz(3);
+ clrbit ($a, 1);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 1); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+{ tie my $a, 'Mytie', 3;
+ clrbit ($a, 1);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 1); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+
+{ my $b = mpz(3);
+ tie my $a, 'Mytie', $b;
+ clrbit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+ ok (tied($a));
+}
+{ my $b = 3;
+ tie my $a, 'Mytie', $b;
+ clrbit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+ ok (tied($a));
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::combit
+
+{ my $a = mpz(3); combit ($a, 1); ok ($a == 1);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+{ my $a = mpz(3); combit ($a, 2); ok ($a == 7);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+
+{ my $a = 3; combit ($a, 1); ok ($a == 1);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+{ my $a = 3; combit ($a, 2); ok ($a == 7);
+ ok (UNIVERSAL::isa($a,"GMP::Mpz")); }
+
+# mutate only given variable
+{ my $a = mpz(3);
+ my $b = $a;
+ combit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+}
+{ my $a = 3;
+ my $b = $a;
+ combit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+}
+
+{ tie my $a, 'Mytie', mpz(3);
+ combit ($a, 2);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 7); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+{ tie my $a, 'Mytie', 3;
+ combit ($a, 2);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 7); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+
+{ my $b = mpz(3);
+ tie my $a, 'Mytie', $b;
+ combit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+ ok (tied($a));
+}
+{ my $b = 3;
+ tie my $a, 'Mytie', $b;
+ combit ($a, 0);
+ ok ($a == 2);
+ ok ($b == 3);
+ ok (tied($a));
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::congruent_p
+
+ok ( congruent_p (21, 0, 7));
+ok (! congruent_p (21, 1, 7));
+ok ( congruent_p (21, 5, 8));
+ok (! congruent_p (21, 6, 8));
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::congruent_2exp_p
+
+ok ( congruent_2exp_p (20, 0, 2));
+ok (! congruent_2exp_p (21, 0, 2));
+ok (! congruent_2exp_p (20, 1, 2));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::divexact
+
+ok (divexact(27,3) == 9);
+ok (divexact(27,-3) == -9);
+ok (divexact(-27,3) == -9);
+ok (divexact(-27,-3) == 9);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::divisible_p
+
+ok ( divisible_p (21, 7));
+ok (! divisible_p (21, 8));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::divisible_2exp_p
+
+ok ( divisible_2exp_p (20, 2));
+ok (! divisible_2exp_p (21, 2));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::even_p
+
+ok (! even_p(mpz(-3)));
+ok ( even_p(mpz(-2)));
+ok (! even_p(mpz(-1)));
+ok ( even_p(mpz(0)));
+ok (! even_p(mpz(1)));
+ok ( even_p(mpz(2)));
+ok (! even_p(mpz(3)));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::export
+
+{ my $s = mpz_export (1, 2, 1, 0, "0x61626364");
+ ok ($s eq 'abcd'); }
+{ my $s = mpz_export (-1, 2, 1, 0, "0x61626364");
+ ok ($s eq 'cdab'); }
+{ my $s = mpz_export (1, 2, -1, 0, "0x61626364");
+ ok ($s eq 'badc'); }
+{ my $s = mpz_export (-1, 2, -1, 0, "0x61626364");
+ ok ($s eq 'dcba'); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fac
+
+ok (fac(0) == 1);
+ok (fac(1) == 1);
+ok (fac(2) == 2);
+ok (fac(3) == 6);
+ok (fac(4) == 24);
+ok (fac(5) == 120);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fdiv
+
+{ my ($q, $r);
+ ($q, $r) = fdiv (16, 3);
+ ok ($q == 5);
+ ok ($r == 1);
+ ($q, $r) = fdiv (16, -3);
+ ok ($q == -6);
+ ok ($r == -2);
+ ($q, $r) = fdiv (-16, 3);
+ ok ($q == -6);
+ ok ($r == 2);
+ ($q, $r) = fdiv (-16, -3);
+ ok ($q == 5);
+ ok ($r == -1);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fdiv_2exp
+
+{ my ($q, $r);
+ ($q, $r) = fdiv_2exp (23, 2);
+ ok ($q == 5);
+ ok ($r == 3);
+ ($q, $r) = fdiv_2exp (-23, 2);
+ ok ($q == -6);
+ ok ($r == 1);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fib
+
+ok (fib(0) == 0);
+ok (fib(1) == 1);
+ok (fib(2) == 1);
+ok (fib(3) == 2);
+ok (fib(4) == 3);
+ok (fib(5) == 5);
+ok (fib(6) == 8);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::fib2
+
+{ my ($a, $b) = fib2(0); ok($a==0); ok($b==1); }
+{ my ($a, $b) = fib2(1); ok($a==1); ok($b==0); }
+{ my ($a, $b) = fib2(2); ok($a==1); ok($b==1); }
+{ my ($a, $b) = fib2(3); ok($a==2); ok($b==1); }
+{ my ($a, $b) = fib2(4); ok($a==3); ok($b==2); }
+{ my ($a, $b) = fib2(5); ok($a==5); ok($b==3); }
+{ my ($a, $b) = fib2(6); ok($a==8); ok($b==5); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::gcd
+
+ok (gcd (21) == 21);
+ok (gcd (21,15) == 3);
+ok (gcd (21,15,30,57) == 3);
+ok (gcd (21,-15) == 3);
+ok (gcd (-21,15) == 3);
+ok (gcd (-21,-15) == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::gcdext
+
+{
+ my ($g, $x, $y) = gcdext (3,5);
+ ok ($g == 1);
+ ok ($x == 2);
+ ok ($y == -1);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::hamdist
+
+ok (hamdist(5,7) == 1);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::import
+
+{ my $z = mpz_import (1, 2, 1, 0, 'abcd');
+ ok ($z == 0x61626364); }
+{ my $z = mpz_import (-1, 2, 1, 0, 'abcd');
+ ok ($z == 0x63646162); }
+{ my $z = mpz_import (1, 2, -1, 0, 'abcd');
+ ok ($z == 0x62616463); }
+{ my $z = mpz_import (-1, 2, -1, 0, 'abcd');
+ ok ($z == 0x64636261); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::invert
+
+ok (invert(1,123) == 1);
+ok (invert(6,7) == 6);
+ok (! defined invert(2,8));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::jacobi, GMP::Mpz::kronecker
+
+foreach my $i ([ 1, 19, 1 ],
+ [ 4, 19, 1 ],
+ [ 5, 19, 1 ],
+ [ 6, 19, 1 ],
+ [ 7, 19, 1 ],
+ [ 9, 19, 1 ],
+ [ 11, 19, 1 ],
+ [ 16, 19, 1 ],
+ [ 17, 19, 1 ],
+ [ 2, 19, -1 ],
+ [ 3, 19, -1 ],
+ [ 8, 19, -1 ],
+ [ 10, 19, -1 ],
+ [ 12, 19, -1 ],
+ [ 13, 19, -1 ],
+ [ 14, 19, -1 ],
+ [ 15, 19, -1 ],
+ [ 18, 19, -1 ]) {
+ foreach my $fun (\&jacobi, \&kronecker) {
+ ok (&$fun ($$i[0], $$i[1]) == $$i[2]);
+
+ ok (&$fun ($$i[0], str($$i[1])) == $$i[2]);
+ ok (&$fun (str($$i[0]), $$i[1]) == $$i[2]);
+ ok (&$fun (str($$i[0]), str($$i[1])) == $$i[2]);
+
+ ok (&$fun ($$i[0], mpz($$i[1])) == $$i[2]);
+ ok (&$fun (mpz($$i[0]), $$i[1]) == $$i[2]);
+ ok (&$fun (mpz($$i[0]), mpz($$i[1])) == $$i[2]);
+ }
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::lcm
+
+ok (lcm (2) == 2);
+ok (lcm (0) == 0);
+ok (lcm (0,0) == 0);
+ok (lcm (0,0,0) == 0);
+ok (lcm (0,0,0,0) == 0);
+ok (lcm (2,0) == 0);
+ok (lcm (-2,0) == 0);
+ok (lcm (2,3) == 6);
+ok (lcm (2,3,4) == 12);
+ok (lcm (2,-3) == 6);
+ok (lcm (-2,3) == 6);
+ok (lcm (-2,-3) == 6);
+ok (lcm (mpz(2)**512,1) == mpz(2)**512);
+ok (lcm (mpz(2)**512,-1) == mpz(2)**512);
+ok (lcm (-mpz(2)**512,1) == mpz(2)**512);
+ok (lcm (-mpz(2)**512,-1) == mpz(2)**512);
+ok (lcm (mpz(2)**512,mpz(2)**512) == mpz(2)**512);
+ok (lcm (mpz(2)**512,-mpz(2)**512) == mpz(2)**512);
+ok (lcm (-mpz(2)**512,mpz(2)**512) == mpz(2)**512);
+ok (lcm (-mpz(2)**512,-mpz(2)**512) == mpz(2)**512);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::lucnum
+
+ok (lucnum(0) == 2);
+ok (lucnum(1) == 1);
+ok (lucnum(2) == 3);
+ok (lucnum(3) == 4);
+ok (lucnum(4) == 7);
+ok (lucnum(5) == 11);
+ok (lucnum(6) == 18);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::lucnum2
+
+{ my ($a, $b) = lucnum2(0); ok($a==2); ok($b==-1); }
+{ my ($a, $b) = lucnum2(1); ok($a==1); ok($b==2); }
+{ my ($a, $b) = lucnum2(2); ok($a==3); ok($b==1); }
+{ my ($a, $b) = lucnum2(3); ok($a==4); ok($b==3); }
+{ my ($a, $b) = lucnum2(4); ok($a==7); ok($b==4); }
+{ my ($a, $b) = lucnum2(5); ok($a==11); ok($b==7); }
+{ my ($a, $b) = lucnum2(6); ok($a==18); ok($b==11); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::nextprime
+
+ok (nextprime(2) == 3);
+ok (nextprime(3) == 5);
+ok (nextprime(5) == 7);
+ok (nextprime(7) == 11);
+ok (nextprime(11) == 13);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::perfect_power_p
+
+# ok ( perfect_power_p(mpz(-27)));
+# ok (! perfect_power_p(mpz(-9)));
+# ok (! perfect_power_p(mpz(-1)));
+ok ( perfect_power_p(mpz(0)));
+ok ( perfect_power_p(mpz(1)));
+ok (! perfect_power_p(mpz(2)));
+ok (! perfect_power_p(mpz(3)));
+ok ( perfect_power_p(mpz(4)));
+ok ( perfect_power_p(mpz(9)));
+ok ( perfect_power_p(mpz(27)));
+ok ( perfect_power_p(mpz(81)));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::perfect_square_p
+
+ok (! perfect_square_p(mpz(-9)));
+ok (! perfect_square_p(mpz(-1)));
+ok ( perfect_square_p(mpz(0)));
+ok ( perfect_square_p(mpz(1)));
+ok (! perfect_square_p(mpz(2)));
+ok (! perfect_square_p(mpz(3)));
+ok ( perfect_square_p(mpz(4)));
+ok ( perfect_square_p(mpz(9)));
+ok (! perfect_square_p(mpz(27)));
+ok ( perfect_square_p(mpz(81)));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::popcount
+
+ok (popcount(7) == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::powm
+
+ok (powm (3,2,8) == 1);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::probab_prime_p
+
+ok ( probab_prime_p(89,1));
+ok (! probab_prime_p(81,1));
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::realloc
+
+{ my $z = mpz(123);
+ realloc ($z, 512); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::remove
+
+{
+ my ($rem, $mult);
+ ($rem, $mult) = remove(12,3);
+ ok ($rem == 4);
+ ok ($mult == 1);
+ ($rem, $mult) = remove(12,2);
+ ok ($rem == 3);
+ ok ($mult == 2);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::root
+
+ok (root(0,2) == 0);
+ok (root(8,3) == 2);
+ok (root(-8,3) == -2);
+ok (root(81,4) == 3);
+ok (root(243,5) == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::roote
+
+{ my ($r,$e);
+ ($r, $e) = roote(0,2);
+ ok ($r == 0);
+ ok ($e);
+ ($r, $e) = roote(81,4);
+ ok ($r == 3);
+ ok ($e);
+ ($r, $e) = roote(85,4);
+ ok ($r == 3);
+ ok (! $e);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::rootrem
+
+{ my ($root, $rem) = rootrem (mpz(0), 1);
+ ok ($root == 0); ok ($rem == 0); }
+{ my ($root, $rem) = rootrem (mpz(0), 2);
+ ok ($root == 0); ok ($rem == 0); }
+{ my ($root, $rem) = rootrem (mpz(64), 2);
+ ok ($root == 8); ok ($rem == 0); }
+{ my ($root, $rem) = rootrem (mpz(64), 3);
+ ok ($root == 4); ok ($rem == 0); }
+{ my ($root, $rem) = rootrem (mpz(65), 3);
+ ok ($root == 4); ok ($rem == 1); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::scan0
+
+ok (scan0 (0, 0) == 0);
+ok (scan0 (1, 0) == 1);
+ok (scan0 (3, 0) == 2);
+ok (scan0 (-1, 0) == ~0);
+ok (scan0 (-2, 1) == ~0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::scan1
+
+ok (scan1 (1, 0) == 0);
+ok (scan1 (2, 0) == 1);
+ok (scan1 (4, 0) == 2);
+ok (scan1 (0, 0) == ~0);
+ok (scan1 (3, 2) == ~0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::setbit
+
+{ my $a = mpz(3); setbit ($a, 1); ok ($a == 3); }
+{ my $a = mpz(3); setbit ($a, 2); ok ($a == 7); }
+
+{ my $a = 3; setbit ($a, 1); ok ($a == 3); }
+{ my $a = 3; setbit ($a, 2); ok ($a == 7); }
+
+# mutate only given variable
+{ my $a = mpz(0);
+ my $b = $a;
+ setbit ($a, 0);
+ ok ($a == 1);
+ ok ($b == 0);
+}
+{ my $a = 0;
+ my $b = $a;
+ setbit ($a, 0);
+ ok ($a == 1);
+ ok ($b == 0);
+}
+
+{ tie my $a, 'Mytie', mpz(3);
+ setbit ($a, 2);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 7); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+{ tie my $a, 'Mytie', 3;
+ setbit ($a, 2);
+ ok ($Mytie::fetched > 0); # used fetch
+ ok ($Mytie::stored > 0); # used store
+ ok ($a == 7); # expected result
+ ok (UNIVERSAL::isa($a,"GMP::Mpz"));
+ ok (tied($a)); # still tied
+}
+
+{ my $b = mpz(2);
+ tie my $a, 'Mytie', $b;
+ setbit ($a, 0);
+ ok ($a == 3);
+ ok ($b == 2);
+ ok (tied($a));
+}
+{ my $b = 2;
+ tie my $a, 'Mytie', $b;
+ setbit ($a, 0);
+ ok ($a == 3);
+ ok ($b == 2);
+ ok (tied($a));
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::sizeinbase
+
+ok (sizeinbase(1,10) == 1);
+ok (sizeinbase(100,10) == 3);
+ok (sizeinbase(9999,10) == 5);
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::sqrtrem
+
+{
+ my ($root, $rem) = sqrtrem(mpz(0));
+ ok ($root == 0);
+ ok ($rem == 0);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(1));
+ ok ($root == 1);
+ ok ($rem == 0);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(2));
+ ok ($root == 1);
+ ok ($rem == 1);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(9));
+ ok ($root == 3);
+ ok ($rem == 0);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(35));
+ ok ($root == 5);
+ ok ($rem == 10);
+}
+{
+ my ($root, $rem) = sqrtrem(mpz(0));
+ ok ($root == 0);
+ ok ($rem == 0);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::tdiv
+
+{ my ($q, $r);
+ ($q, $r) = tdiv (16, 3);
+ ok ($q == 5);
+ ok ($r == 1);
+ ($q, $r) = tdiv (16, -3);
+ ok ($q == -5);
+ ok ($r == 1);
+ ($q, $r) = tdiv (-16, 3);
+ ok ($q == -5);
+ ok ($r == -1);
+ ($q, $r) = tdiv (-16, -3);
+ ok ($q == 5);
+ ok ($r == -1);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::tdiv_2exp
+
+{ my ($q, $r);
+ ($q, $r) = tdiv_2exp (23, 2);
+ ok ($q == 5);
+ ok ($r == 3);
+ ($q, $r) = tdiv_2exp (-23, 2);
+ ok ($q == -5);
+ ok ($r == -3);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpz::tstbit
+
+ok (tstbit (6, 0) == 0);
+ok (tstbit (6, 1) == 1);
+ok (tstbit (6, 2) == 1);
+ok (tstbit (6, 3) == 0);
+
+
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpq
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::new
+
+ok (mpq(0) == 0);
+ok (mpq('0') == 0);
+ok (mpq(substr('101',1,1)) == 0);
+ok (mpq(0.0) == 0);
+ok (mpq(mpz(0)) == 0);
+ok (mpq(mpq(0)) == 0);
+ok (mpq(mpf(0)) == 0);
+
+{ tie my $t, 'Mytie', 0; ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', '0'; ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', substr('101',1,1); ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', 0.0; ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', mpz(0); ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', mpq(0); ok (mpq($t) == 0); }
+{ tie my $t, 'Mytie', mpf(0); ok (mpq($t) == 0); }
+
+ok (mpq(-123) == -123);
+ok (mpq('-123') == -123);
+ok (mpq(substr('1-1231',1,4)) == -123);
+ok (mpq(-123.0) == -123);
+ok (mpq(mpz(-123)) == -123);
+ok (mpq(mpq(-123)) == -123);
+ok (mpq(mpf(-123)) == -123);
+
+{ tie my $t, 'Mytie', -123; ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', '-123'; ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', substr('1-1231',1,4); ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', -123.0; ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', mpz(-123); ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', mpq(-123); ok (mpq($t) == -123); }
+{ tie my $t, 'Mytie', mpf(-123); ok (mpq($t) == -123); }
+
+ok (mpq($ivnv_2p128) == $str_2p128);
+{ tie my $t, 'Mytie', $ivnv_2p128; ok (mpq($t) == $str_2p128); }
+
+ok (mpq('3/2') == mpq(3,2));
+ok (mpq('3/1') == mpq(3,1));
+ok (mpq('-3/2') == mpq(-3,2));
+ok (mpq('-3/1') == mpq(-3,1));
+ok (mpq('0x3') == mpq(3,1));
+ok (mpq('0b111') == mpq(7,1));
+ok (mpq('0b0') == mpq(0,1));
+
+ok (mpq($uv_max) > 0);
+ok (mpq($uv_max) == mpq($uv_max_str));
+{ tie my $t, 'Mytie', $uv_max; ok (mpq($t) > 0); }
+{ tie my $t, 'Mytie', $uv_max; ok (mpq($t) == mpq($uv_max_str)); }
+
+{ my $x = 123.5;
+ kill (0, $x);
+ ok (mpq($x) == 123.5);
+ tie my $t, 'Mytie', $x;
+ ok (mpq($t) == 123.5);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_abs
+
+ok (abs(mpq(0)) == 0);
+ok (abs(mpq(123)) == 123);
+ok (abs(mpq(-123)) == 123);
+
+{ my $x = mpq(-123); $x = abs($x); ok ($x == 123); }
+{ my $x = mpq(0); $x = abs($x); ok ($x == 0); }
+{ my $x = mpq(123); $x = abs($x); ok ($x == 123); }
+
+{ tie my $t, 'Mytie', mpq(0); ok (abs($t) == 0); }
+{ tie my $t, 'Mytie', mpq(123); ok (abs($t) == 123); }
+{ tie my $t, 'Mytie', mpq(-123); ok (abs($t) == 123); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_add
+
+ok (mpq(0) + 1 == 1);
+ok (mpq(-1) + 1 == 0);
+ok (1 + mpq(0) == 1);
+ok (1 + mpq(-1) == 0);
+
+ok (mpq(1,2)+mpq(1,3) == mpq(5,6));
+ok (mpq(1,2)+mpq(-1,3) == mpq(1,6));
+ok (mpq(-1,2)+mpq(1,3) == mpq(-1,6));
+ok (mpq(-1,2)+mpq(-1,3) == mpq(-5,6));
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_addeq
+
+{ my $a = mpq(7); $a += 1; ok ($a == 8); }
+{ my $a = mpq(7); my $b = $a; $a += 1; ok ($a == 8); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_bool
+
+if (mpq(0)) { ok (0); } else { ok (1); }
+if (mpq(123)) { ok (1); } else { ok (0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_dec
+
+{ my $a = mpq(0); ok ($a-- == 0); ok ($a == -1); }
+{ my $a = mpq(0); ok (--$a == -1); }
+
+{ my $a = mpq(0); my $b = $a; $a--; ok ($a == -1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_div
+
+ok (mpq(6) / 2 == 3);
+ok (mpq(-6) / 2 == -3);
+ok (mpq(6) / -2 == -3);
+ok (mpq(-6) / -2 == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_diveq
+
+{ my $a = mpq(21); $a /= 3; ok ($a == 7); }
+{ my $a = mpq(21); my $b = $a; $a /= 3; ok ($a == 7); ok ($b == 21); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_eq
+
+{ my $a = mpq(0);
+ my $b = $a;
+ $a = mpq(1);
+ ok ($a == 1);
+ ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_inc
+
+{ my $a = mpq(0); ok ($a++ == 0); ok ($a == 1); }
+{ my $a = mpq(0); ok (++$a == 1); }
+
+{ my $a = mpq(0); my $b = $a; $a++; ok ($a == 1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_lshift
+
+{ my $a = mpq(7) << 1; ok ($a == 14); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_lshifteq
+
+{ my $a = mpq(7); $a <<= 1; ok ($a == 14); }
+{ my $a = mpq(7); my $b = $a; $a <<= 1; ok ($a == 14); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_mul
+
+ok (mpq(2) * 3 == 6);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_muleq
+
+{ my $a = mpq(7); $a *= 3; ok ($a == 21); }
+{ my $a = mpq(7); my $b = $a; $a *= 3; ok ($a == 21); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_neg
+
+ok (- mpq(0) == 0);
+ok (- mpq(123) == -123);
+ok (- mpq(-123) == 123);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_not
+
+if (not mpq(0)) { ok (1); } else { ok (0); }
+if (not mpq(123)) { ok (0); } else { ok (1); }
+
+ok ((! mpq(0)) == 1);
+ok ((! mpq(123)) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_pow
+
+ok (mpq(0) ** 1 == 0);
+ok (mpq(1) ** 1 == 1);
+ok (mpq(2) ** 0 == 1);
+ok (mpq(2) ** 1 == 2);
+ok (mpq(2) ** 2 == 4);
+ok (mpq(2) ** 3 == 8);
+ok (mpq(2) ** 4 == 16);
+
+ok (mpq(0) ** mpq(1) == 0);
+ok (mpq(1) ** mpq(1) == 1);
+ok (mpq(2) ** mpq(0) == 1);
+ok (mpq(2) ** mpq(1) == 2);
+ok (mpq(2) ** mpq(2) == 4);
+ok (mpq(2) ** mpq(3) == 8);
+ok (mpq(2) ** mpq(4) == 16);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_poweq
+
+{ my $a = mpq(3); $a **= 4; ok ($a == 81); }
+{ my $a = mpq(3); my $b = $a; $a **= 4; ok ($a == 81); ok ($b == 3); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_rshift
+
+{ my $a = mpq(32) >> 1; ok ($a == 16); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_rshifteq
+
+{ my $a = mpq(32); $a >>= 1; ok ($a == 16); }
+{ my $a = mpq(32); my $b = $a; $a >>= 1; ok ($a == 16); ok ($b == 32); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_spaceship
+
+ok (mpq(0) < 1);
+ok (mpq(0) > -1);
+
+ok (mpq(0) != 1);
+ok (mpq(0) != -1);
+ok (mpq(1) != 0);
+ok (mpq(1) != -1);
+ok (mpq(-1) != 0);
+ok (mpq(-1) != 1);
+
+ok (mpq(3,2) > 1);
+ok (mpq(3,2) < 2);
+
+ok (mpq(0) < 1.0);
+ok (mpq(0) < '1');
+ok (mpq(0) < substr('-1',1,1));
+ok (mpq(0) < mpz(1));
+ok (mpq(0) < mpq(1));
+ok (mpq(0) < mpf(1));
+ok (mpq(0) < $uv_max);
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_string
+
+{ my $x = mpq(0); ok("$x" eq "0"); }
+{ my $x = mpq(123); ok("$x" eq "123"); }
+{ my $x = mpq(-123); ok("$x" eq "-123"); }
+
+{ my $q = mpq(5,7); ok("$q" eq "5/7"); }
+{ my $q = mpq(-5,7); ok("$q" eq "-5/7"); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_sub
+
+ok (mpq(0) - 1 == -1);
+ok (mpq(1) - 1 == 0);
+ok (1 - mpq(0) == 1);
+ok (1 - mpq(1) == 0);
+
+ok (mpq(1,2)-mpq(1,3) == mpq(1,6));
+ok (mpq(1,2)-mpq(-1,3) == mpq(5,6));
+ok (mpq(-1,2)-mpq(1,3) == mpq(-5,6));
+ok (mpq(-1,2)-mpq(-1,3) == mpq(-1,6));
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::overload_subeq
+
+{ my $a = mpq(7); $a -= 1; ok ($a == 6); }
+{ my $a = mpq(7); my $b = $a; $a -= 1; ok ($a == 6); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::canonicalize
+
+{ my $q = mpq(21,15); canonicalize($q);
+ ok (num($q) == 7);
+ ok (den($q) == 5);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::den
+
+{ my $q = mpq(5,9); ok (den($q) == 9); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpq::num
+
+{ my $q = mpq(5,9); ok (num($q) == 5); }
+
+
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpf
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::new
+
+ok (mpf(0) == 0);
+ok (mpf('0') == 0);
+ok (mpf(substr('101',1,1)) == 0);
+ok (mpf(0.0) == 0);
+ok (mpf(mpz(0)) == 0);
+ok (mpf(mpq(0)) == 0);
+ok (mpf(mpf(0)) == 0);
+
+{ tie my $t, 'Mytie', 0; ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', '0'; ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', substr('101',1,1); ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', 0.0; ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', mpz(0); ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', mpq(0); ok (mpf($t) == 0); }
+{ tie my $t, 'Mytie', mpf(0); ok (mpf($t) == 0); }
+
+ok (mpf(-123) == -123);
+ok (mpf('-123') == -123);
+ok (mpf(substr('1-1231',1,4)) == -123);
+ok (mpf(-123.0) == -123);
+ok (mpf(mpz(-123)) == -123);
+ok (mpf(mpq(-123)) == -123);
+ok (mpf(mpf(-123)) == -123);
+
+{ tie my $t, 'Mytie', -123; ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', '-123'; ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', substr('1-1231',1,4); ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', -123.0; ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', mpz(-123); ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', mpq(-123); ok (mpf($t) == -123); }
+{ tie my $t, 'Mytie', mpf(-123); ok (mpf($t) == -123); }
+
+ok (mpf($ivnv_2p128) == $str_2p128);
+{ tie my $t, 'Mytie', $ivnv_2p128; ok (mpf($t) == $str_2p128); }
+
+ok (mpf(-1.5) == -1.5);
+ok (mpf(-1.0) == -1.0);
+ok (mpf(-0.5) == -0.5);
+ok (mpf(0) == 0);
+ok (mpf(0.5) == 0.5);
+ok (mpf(1.0) == 1.0);
+ok (mpf(1.5) == 1.5);
+
+ok (mpf("-1.5") == -1.5);
+ok (mpf("-1.0") == -1.0);
+ok (mpf("-0.5") == -0.5);
+ok (mpf("0") == 0);
+ok (mpf("0.5") == 0.5);
+ok (mpf("1.0") == 1.0);
+ok (mpf("1.5") == 1.5);
+
+ok (mpf($uv_max) > 0);
+ok (mpf($uv_max) == mpf($uv_max_str));
+{ tie my $t, 'Mytie', $uv_max; ok (mpf($t) > 0); }
+{ tie my $t, 'Mytie', $uv_max; ok (mpf($t) == mpf($uv_max_str)); }
+
+{ my $x = 123.5;
+ kill (0, $x);
+ ok (mpf($x) == 123.5);
+ tie my $t, 'Mytie', $x;
+ ok (mpf($t) == 123.5);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_abs
+
+ok (abs(mpf(0)) == 0);
+ok (abs(mpf(123)) == 123);
+ok (abs(mpf(-123)) == 123);
+
+{ my $x = mpf(-123); $x = abs($x); ok ($x == 123); }
+{ my $x = mpf(0); $x = abs($x); ok ($x == 0); }
+{ my $x = mpf(123); $x = abs($x); ok ($x == 123); }
+
+{ tie my $t, 'Mytie', mpf(0); ok (abs($t) == 0); }
+{ tie my $t, 'Mytie', mpf(123); ok (abs($t) == 123); }
+{ tie my $t, 'Mytie', mpf(-123); ok (abs($t) == 123); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_add
+
+ok (mpf(0) + 1 == 1);
+ok (mpf(-1) + 1 == 0);
+ok (1 + mpf(0) == 1);
+ok (1 + mpf(-1) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_addeq
+
+{ my $a = mpf(7); $a += 1; ok ($a == 8); }
+{ my $a = mpf(7); my $b = $a; $a += 1; ok ($a == 8); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_bool
+
+if (mpf(0)) { ok (0); } else { ok (1); }
+if (mpf(123)) { ok (1); } else { ok (0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_dec
+
+{ my $a = mpf(0); ok ($a-- == 0); ok ($a == -1); }
+{ my $a = mpf(0); ok (--$a == -1); }
+
+{ my $a = mpf(0); my $b = $a; $a--; ok ($a == -1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_div
+
+ok (mpf(6) / 2 == 3);
+ok (mpf(-6) / 2 == -3);
+ok (mpf(6) / -2 == -3);
+ok (mpf(-6) / -2 == 3);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_diveq
+
+{ my $a = mpf(21); $a /= 3; ok ($a == 7); }
+{ my $a = mpf(21); my $b = $a; $a /= 3; ok ($a == 7); ok ($b == 21); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_eq
+
+{ my $a = mpf(0);
+ my $b = $a;
+ $a = mpf(1);
+ ok ($a == 1);
+ ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_inc
+
+{ my $a = mpf(0); ok ($a++ == 0); ok ($a == 1); }
+{ my $a = mpf(0); ok (++$a == 1); }
+
+{ my $a = mpf(0); my $b = $a; $a++; ok ($a == 1); ok ($b == 0); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_lshift
+
+{ my $a = mpf(7) << 1; ok ($a == 14); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_lshifteq
+
+{ my $a = mpf(7); $a <<= 1; ok ($a == 14); }
+{ my $a = mpf(7); my $b = $a; $a <<= 1; ok ($a == 14); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_mul
+
+ok (mpf(2) * 3 == 6);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_muleq
+
+{ my $a = mpf(7); $a *= 3; ok ($a == 21); }
+{ my $a = mpf(7); my $b = $a; $a *= 3; ok ($a == 21); ok ($b == 7); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_neg
+
+ok (- mpf(0) == 0);
+ok (- mpf(123) == -123);
+ok (- mpf(-123) == 123);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_not
+
+if (not mpf(0)) { ok (1); } else { ok (0); }
+if (not mpf(123)) { ok (0); } else { ok (1); }
+
+ok ((! mpf(0)) == 1);
+ok ((! mpf(123)) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_pow
+
+ok (mpf(0) ** 1 == 0);
+ok (mpf(1) ** 1 == 1);
+ok (mpf(2) ** 0 == 1);
+ok (mpf(2) ** 1 == 2);
+ok (mpf(2) ** 2 == 4);
+ok (mpf(2) ** 3 == 8);
+ok (mpf(2) ** 4 == 16);
+
+ok (mpf(0) ** mpf(1) == 0);
+ok (mpf(1) ** mpf(1) == 1);
+ok (mpf(2) ** mpf(0) == 1);
+ok (mpf(2) ** mpf(1) == 2);
+ok (mpf(2) ** mpf(2) == 4);
+ok (mpf(2) ** mpf(3) == 8);
+ok (mpf(2) ** mpf(4) == 16);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_poweq
+
+{ my $a = mpf(3); $a **= 4; ok ($a == 81); }
+{ my $a = mpf(3); my $b = $a; $a **= 4; ok ($a == 81); ok ($b == 3); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_rshift
+
+{ my $a = mpf(32) >> 1; ok ($a == 16); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_rshifteq
+
+{ my $a = mpf(32); $a >>= 1; ok ($a == 16); }
+{ my $a = mpf(32); my $b = $a; $a >>= 1; ok ($a == 16); ok ($b == 32); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_sqrt
+
+ok (sqrt(mpf(0)) == 0);
+ok (sqrt(mpf(1)) == 1);
+ok (sqrt(mpf(4)) == 2);
+ok (sqrt(mpf(81)) == 9);
+
+ok (sqrt(mpf(0.25)) == 0.5);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_spaceship
+
+ok (mpf(0) < 1);
+ok (mpf(0) > -1);
+
+ok (mpf(0) != 1);
+ok (mpf(0) != -1);
+ok (mpf(1) != 0);
+ok (mpf(1) != -1);
+ok (mpf(-1) != 0);
+ok (mpf(-1) != 1);
+
+ok (mpf(0) < 1.0);
+ok (mpf(0) < '1');
+ok (mpf(0) < substr('-1',1,1));
+ok (mpf(0) < mpz(1));
+ok (mpf(0) < mpq(1));
+ok (mpf(0) < mpf(1));
+ok (mpf(0) < $uv_max);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_string
+
+{ my $x = mpf(0); ok ("$x" eq "0"); }
+{ my $x = mpf(123); ok ("$x" eq "123"); }
+{ my $x = mpf(-123); ok ("$x" eq "-123"); }
+
+{ my $f = mpf(0.25); ok ("$f" eq "0.25"); }
+{ my $f = mpf(-0.25); ok ("$f" eq "-0.25"); }
+{ my $f = mpf(1.25); ok ("$f" eq "1.25"); }
+{ my $f = mpf(-1.25); ok ("$f" eq "-1.25"); }
+{ my $f = mpf(1000000); ok ("$f" eq "1000000"); }
+{ my $f = mpf(-1000000); ok ("$f" eq "-1000000"); }
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_sub
+
+ok (mpf(0) - 1 == -1);
+ok (mpf(1) - 1 == 0);
+ok (1 - mpf(0) == 1);
+ok (1 - mpf(1) == 0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::overload_subeq
+
+{ my $a = mpf(7); $a -= 1; ok ($a == 6); }
+{ my $a = mpf(7); my $b = $a; $a -= 1; ok ($a == 6); ok ($b == 7); }
+
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::ceil
+
+ok (ceil (mpf(-7.5)) == -7.0);
+ok (ceil (mpf(7.5)) == 8.0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::floor
+
+ok (floor(mpf(-7.5)) == -8.0);
+ok (floor(mpf(7.5)) == 7.0);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::mpf_eq
+
+{ my $old_prec = get_default_prec();
+ set_default_prec(128);
+
+ ok ( mpf_eq (mpz("0x10000000000000001"), mpz("0x10000000000000002"), 1));
+ ok (! mpf_eq (mpz("0x11"), mpz("0x12"), 128));
+
+ set_default_prec($old_prec);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::get_default_prec
+
+get_default_prec();
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::get_prec
+
+{ my $x = mpf(1.0, 512);
+ ok (get_prec ($x) == 512);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::reldiff
+
+ok (reldiff (2,4) == 1);
+ok (reldiff (4,2) == 0.5);
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::set_default_prec
+
+{ my $old_prec = get_default_prec();
+
+ set_default_prec(512);
+ ok (get_default_prec () == 512);
+
+ set_default_prec($old_prec);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::set_prec
+
+{ my $x = mpf(1.0, 512);
+ my $y = $x;
+ set_prec ($x, 1024);
+ ok (get_prec ($x) == 1024);
+ ok (get_prec ($y) == 512);
+}
+
+#------------------------------------------------------------------------------
+# GMP::Mpf::trunc
+
+ok (trunc(mpf(-7.5)) == -7.0);
+ok (trunc(mpf(7.5)) == 7.0);
+
+
+
+#------------------------------------------------------------------------------
+# GMP::Rand
+
+#------------------------------------------------------------------------------
+# GMP::Rand::new
+
+{ my $r = randstate(); ok (defined $r); }
+{ my $r = randstate('lc_2exp', 1, 2, 3); ok (defined $r); }
+{ my $r = randstate('lc_2exp_size', 64); ok (defined $r); }
+{ my $r = randstate('lc_2exp_size', 999999999); ok (! defined $r); }
+{ my $r = randstate('mt'); ok (defined $r); }
+
+{ # copying a randstate results in same sequence
+ my $r1 = randstate('lc_2exp_size', 64);
+ $r1->seed(123);
+ my $r2 = randstate($r1);
+ for (1 .. 20) {
+ my $z1 = mpz_urandomb($r1, 20);
+ my $z2 = mpz_urandomb($r2, 20);
+ ok ($z1 == $z2);
+ }
+}
+
+#------------------------------------------------------------------------------
+# GMP::Rand::seed
+
+{ my $r = randstate();
+ $r->seed(123);
+ $r->seed(time());
+}
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpf_urandomb
+
+{ my $r = randstate();
+ my $f = mpf_urandomb($r,1024);
+ ok (UNIVERSAL::isa($f,"GMP::Mpf")); }
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_urandomb
+
+{ my $r = randstate();
+ my $z = mpz_urandomb($r, 1024);
+ ok (UNIVERSAL::isa($z,"GMP::Mpz")); }
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_rrandomb
+
+{ my $r = randstate();
+ my $z = mpz_rrandomb($r, 1024);
+ ok (UNIVERSAL::isa($z,"GMP::Mpz")); }
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_urandomm
+
+{ my $r = randstate();
+ my $z = mpz_urandomm($r, mpz(3)**100);
+ ok (UNIVERSAL::isa($z,"GMP::Mpz")); }
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_urandomb_ui
+
+{ my $r = randstate();
+ foreach (1 .. 20) {
+ my $u = gmp_urandomb_ui($r,8);
+ ok ($u >= 0);
+ ok ($u < 256);
+ }
+}
+
+#------------------------------------------------------------------------------
+# GMP::Rand::mpz_urandomm_ui
+
+{ my $r = randstate();
+ foreach (1 .. 20) {
+ my $u = gmp_urandomm_ui($r,8);
+ ok ($u >= 0);
+ ok ($u < 8);
+ }
+}
+
+
+
+
+#------------------------------------------------------------------------------
+# GMP module
+
+#------------------------------------------------------------------------------
+# GMP::fits_slong_p
+
+ok (GMP::fits_slong_p(0));
+
+# in perl 5.005 uv_max is only 32-bits on a 64-bit system, so won't exceed a
+# long
+# ok (! GMP::fits_slong_p($uv_max));
+
+ok (GMP::fits_slong_p(0.0));
+
+ok (GMP::fits_slong_p('0'));
+
+ok (GMP::fits_slong_p(substr('999999999999999999999999999999',1,1)));
+
+ok (! mpz("-9999999999999999999999999999999999999999999")->fits_slong_p());
+ok ( mpz(-123)->fits_slong_p());
+ok ( mpz(0)->fits_slong_p());
+ok ( mpz(123)->fits_slong_p());
+ok (! mpz("9999999999999999999999999999999999999999999")->fits_slong_p());
+
+ok (! mpq("-9999999999999999999999999999999999999999999")->fits_slong_p());
+ok ( mpq(-123)->fits_slong_p());
+ok ( mpq(0)->fits_slong_p());
+ok ( mpq(123)->fits_slong_p());
+ok (! mpq("9999999999999999999999999999999999999999999")->fits_slong_p());
+
+ok (! mpf("-9999999999999999999999999999999999999999999")->fits_slong_p());
+ok ( mpf(-123)->fits_slong_p());
+ok ( mpf(0)->fits_slong_p());
+ok ( mpf(123)->fits_slong_p());
+ok (! mpf("9999999999999999999999999999999999999999999")->fits_slong_p());
+
+#------------------------------------------------------------------------------
+# GMP::get_d
+
+ok (GMP::get_d(123) == 123.0);
+
+ok (GMP::get_d($uv_max) > 0);
+
+ok (GMP::get_d(123.0) == 123.0);
+
+ok (GMP::get_d('123') == 123.0);
+
+ok (GMP::get_d(mpz(123)) == 123.0);
+
+ok (GMP::get_d(mpq(123)) == 123.0);
+
+ok (GMP::get_d(mpf(123)) == 123.0);
+
+#------------------------------------------------------------------------------
+# GMP::get_d_2exp
+
+{ my ($dbl, $exp) = get_d_2exp (0);
+ ok ($dbl == 0); ok ($exp == 0); }
+{ my ($dbl, $exp) = get_d_2exp (1);
+ ok ($dbl == 0.5); ok ($exp == 1); }
+
+{ my ($dbl, $exp) = get_d_2exp ($uv_max);
+ ok ($dbl > 0.0); ok ($exp > 0); }
+
+{ my ($dbl, $exp) = get_d_2exp (0.5);
+ ok ($dbl == 0.5); ok ($exp == 0); }
+{ my ($dbl, $exp) = get_d_2exp (0.25);
+ ok ($dbl == 0.5); ok ($exp == -1); }
+
+{ my ($dbl, $exp) = get_d_2exp ("1.0");
+ ok ($dbl == 0.5); ok ($exp == 1); }
+
+{ my ($dbl, $exp) = get_d_2exp (mpz ("256"));
+ ok ($dbl == 0.5); ok ($exp == 9); }
+
+{ my ($dbl, $exp) = get_d_2exp (mpq ("1/16"));
+ ok ($dbl == 0.5); ok ($exp == -3); }
+
+{ my ($dbl, $exp) = get_d_2exp (mpf ("1.5"));
+ ok ($dbl == 0.75); ok ($exp == 1); }
+{ my ($dbl, $exp) = get_d_2exp (mpf ("3.0"));
+ ok ($dbl == 0.75); ok ($exp == 2); }
+
+#------------------------------------------------------------------------------
+# GMP::get_str
+
+ok (get_str(-123) eq '-123');
+ok (get_str('-123') eq '-123');
+ok (get_str(substr('x-123x',1,4)) eq '-123');
+ok (get_str(mpz(-123)) eq '-123');
+ok (get_str(mpq(-123)) eq '-123');
+
+ok (get_str(-123,10) eq '-123');
+ok (get_str('-123',10) eq '-123');
+ok (get_str(substr('x-123x',1,4),10) eq '-123');
+ok (get_str(mpz(-123),10) eq '-123');
+ok (get_str(mpq(-123),10) eq '-123');
+
+ok (get_str(-123,16) eq '-7b');
+ok (get_str('-123',16) eq '-7b');
+ok (get_str(substr('x-123x',1,4),16) eq '-7b');
+ok (get_str(mpz(-123),16) eq '-7b');
+ok (get_str(mpq(-123),16) eq '-7b');
+
+ok (get_str(-123,-16) eq '-7B');
+ok (get_str('-123',-16) eq '-7B');
+ok (get_str(substr('x-123x',1,4),-16) eq '-7B');
+ok (get_str(mpz(-123),-16) eq '-7B');
+ok (get_str(mpq(-123),-16) eq '-7B');
+
+# is a float in past versions of perl without UV type
+{ my ($str, $exp) = get_str($uv_max);
+ ok ($str eq $uv_max_str); }
+
+ok (get_str(mpq(5/8)) eq "5/8");
+ok (get_str(mpq(-5/8)) eq "-5/8");
+ok (get_str(mpq(255/256),16) eq "ff/100");
+ok (get_str(mpq(255/256),-16) eq "FF/100");
+ok (get_str(mpq(-255/256),16) eq "-ff/100");
+ok (get_str(mpq(-255/256),-16) eq "-FF/100");
+
+{ my ($s,$e) = get_str(1.5, 10); ok ($s eq '15'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(1.5), 10); ok ($s eq '15'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(-1.5, 10); ok ($s eq '-15'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(-1.5), 10); ok ($s eq '-15'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(1.5, 16); ok ($s eq '18'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(1.5), 16); ok ($s eq '18'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(-1.5, 16); ok ($s eq '-18'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(-1.5), 16); ok ($s eq '-18'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(65536.0, 16); ok ($s eq '1'); ok ($e == 5); }
+{ my ($s,$e) = get_str(mpf(65536.0), 16); ok ($s eq '1'); ok ($e == 5); }
+
+{ my ($s,$e) = get_str(1.625, 16); ok ($s eq '1a'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(1.625), 16); ok ($s eq '1a'); ok ($e == 1); }
+
+{ my ($s,$e) = get_str(1.625, -16); ok ($s eq '1A'); ok ($e == 1); }
+{ my ($s,$e) = get_str(mpf(1.625), -16); ok ($s eq '1A'); ok ($e == 1); }
+
+{ my ($s, $e) = get_str(255.0,16,0); ok ($s eq "ff"); ok ($e == 2); }
+{ my ($s, $e) = get_str(mpf(255.0),16,0); ok ($s eq "ff"); ok ($e == 2); }
+
+{ my ($s, $e) = get_str(255.0,-16,0); ok ($s eq "FF"); ok ($e == 2); }
+{ my ($s, $e) = get_str(mpf(255.0),-16,0); ok ($s eq "FF"); ok ($e == 2); }
+
+#------------------------------------------------------------------------------
+# GMP::get_si
+
+ok (GMP::get_si(123) == 123.0);
+
+# better not assume anything about the relatives sizes of long and UV
+ok (GMP::get_si($uv_max) != 0);
+
+ok (GMP::get_si(123.0) == 123.0);
+
+ok (GMP::get_si('123') == 123.0);
+
+ok (GMP::get_si(mpz(123)) == 123.0);
+
+ok (GMP::get_si(mpq(123)) == 123.0);
+
+ok (GMP::get_si(mpf(123)) == 123.0);
+
+#------------------------------------------------------------------------------
+# GMP::integer_p
+
+ok ( GMP::integer_p (0));
+ok ( GMP::integer_p (123));
+ok ( GMP::integer_p (-123));
+
+ok ( GMP::integer_p ($uv_max));
+
+ok ( GMP::integer_p (0.0));
+ok ( GMP::integer_p (123.0));
+ok ( GMP::integer_p (-123.0));
+ok (! GMP::integer_p (0.5));
+ok (! GMP::integer_p (123.5));
+ok (! GMP::integer_p (-123.5));
+
+ok ( GMP::integer_p ('0'));
+ok ( GMP::integer_p ('123'));
+ok ( GMP::integer_p ('-123'));
+ok (! GMP::integer_p ('0.5'));
+ok (! GMP::integer_p ('123.5'));
+ok (! GMP::integer_p ('-123.5'));
+ok (! GMP::integer_p ('5/8'));
+
+ok ( GMP::integer_p (mpz(1)));
+
+ok ( GMP::integer_p (mpq(1)));
+ok (! GMP::integer_p (mpq(1,2)));
+
+ok ( GMP::integer_p (mpf(1.0)));
+ok (! GMP::integer_p (mpf(1.5)));
+
+#------------------------------------------------------------------------------
+# GMP::odd_p
+
+ok (! odd_p(0));
+ok ( odd_p(1));
+ok (! odd_p(2));
+
+ok ( odd_p($uv_max));
+
+ok ( odd_p(mpz(-3)));
+ok (! odd_p(mpz(-2)));
+ok ( odd_p(mpz(-1)));
+ok (! odd_p(mpz(0)));
+ok ( odd_p(mpz(1)));
+ok (! odd_p(mpz(2)));
+ok ( odd_p(mpz(3)));
+
+#------------------------------------------------------------------------------
+# GMP::printf
+
+GMP::printf ("hello world\n");
+
+sub via_printf {
+ my $s;
+ open TEMP, ">test.tmp" or die;
+ GMP::printf TEMP @_;
+ close TEMP or die;
+ open TEMP, "<test.tmp" or die;
+ read (TEMP, $s, 1024);
+ close TEMP or die;
+ unlink 'test.tmp';
+ return $s;
+}
+
+ok (sprintf ("%d", mpz(123)) eq '123');
+ok (sprintf ("%d %d %d", 456, mpz(123), 789) eq '456 123 789');
+ok (sprintf ("%d", mpq(15,16)) eq '15/16');
+ok (sprintf ("%f", mpf(1.5)) eq '1.500000');
+ok (sprintf ("%.2f", mpf(1.5)) eq '1.50');
+
+ok (sprintf ("%*d", 6, 123) eq ' 123');
+ok (sprintf ("%*d", 6, mpz(123)) eq ' 123');
+ok (sprintf ("%*d", 6, mpq(15,16)) eq ' 15/16');
+
+ok (sprintf ("%x", 123) eq '7b');
+ok (sprintf ("%x", mpz(123)) eq '7b');
+ok (sprintf ("%X", 123) eq '7B');
+ok (sprintf ("%X", mpz(123)) eq '7B');
+ok (sprintf ("%#x", 123) eq '0x7b');
+ok (sprintf ("%#x", mpz(123)) eq '0x7b');
+ok (sprintf ("%#X", 123) eq '0X7B');
+ok (sprintf ("%#X", mpz(123)) eq '0X7B');
+
+ok (sprintf ("%x", mpq(15,16)) eq 'f/10');
+ok (sprintf ("%X", mpq(15,16)) eq 'F/10');
+ok (sprintf ("%#x", mpq(15,16)) eq '0xf/0x10');
+ok (sprintf ("%#X", mpq(15,16)) eq '0XF/0X10');
+
+ok (sprintf ("%*.*f", 10, 3, 1.25) eq ' 1.250');
+ok (sprintf ("%*.*f", 10, 3, mpf(1.5)) eq ' 1.500');
+
+ok (via_printf ("%d", mpz(123)) eq '123');
+ok (via_printf ("%d %d %d", 456, mpz(123), 789) eq '456 123 789');
+ok (via_printf ("%d", mpq(15,16)) eq '15/16');
+ok (via_printf ("%f", mpf(1.5)) eq '1.500000');
+ok (via_printf ("%.2f", mpf(1.5)) eq '1.50');
+
+ok (via_printf ("%*d", 6, 123) eq ' 123');
+ok (via_printf ("%*d", 6, mpz(123)) eq ' 123');
+ok (via_printf ("%*d", 6, mpq(15,16)) eq ' 15/16');
+
+ok (via_printf ("%x", 123) eq '7b');
+ok (via_printf ("%x", mpz(123)) eq '7b');
+ok (via_printf ("%X", 123) eq '7B');
+ok (via_printf ("%X", mpz(123)) eq '7B');
+ok (via_printf ("%#x", 123) eq '0x7b');
+ok (via_printf ("%#x", mpz(123)) eq '0x7b');
+ok (via_printf ("%#X", 123) eq '0X7B');
+ok (via_printf ("%#X", mpz(123)) eq '0X7B');
+
+ok (via_printf ("%x", mpq(15,16)) eq 'f/10');
+ok (via_printf ("%X", mpq(15,16)) eq 'F/10');
+ok (via_printf ("%#x", mpq(15,16)) eq '0xf/0x10');
+ok (via_printf ("%#X", mpq(15,16)) eq '0XF/0X10');
+
+ok (via_printf ("%*.*f", 10, 3, 1.25) eq ' 1.250');
+ok (via_printf ("%*.*f", 10, 3, mpf(1.5)) eq ' 1.500');
+
+#------------------------------------------------------------------------------
+# GMP::sgn
+
+ok (sgn(-123) == -1);
+ok (sgn(0) == 0);
+ok (sgn(123) == 1);
+
+ok (sgn($uv_max) == 1);
+
+ok (sgn(-123.0) == -1);
+ok (sgn(0.0) == 0);
+ok (sgn(123.0) == 1);
+
+ok (sgn('-123') == -1);
+ok (sgn('0') == 0);
+ok (sgn('123') == 1);
+ok (sgn('-123.0') == -1);
+ok (sgn('0.0') == 0);
+ok (sgn('123.0') == 1);
+
+ok (sgn(substr('x-123x',1,4)) == -1);
+ok (sgn(substr('x0x',1,1)) == 0);
+ok (sgn(substr('x123x',1,3)) == 1);
+
+ok (mpz(-123)->sgn() == -1);
+ok (mpz(0) ->sgn() == 0);
+ok (mpz(123) ->sgn() == 1);
+
+ok (mpq(-123)->sgn() == -1);
+ok (mpq(0) ->sgn() == 0);
+ok (mpq(123) ->sgn() == 1);
+
+ok (mpf(-123)->sgn() == -1);
+ok (mpf(0) ->sgn() == 0);
+ok (mpf(123) ->sgn() == 1);
+
+
+
+#------------------------------------------------------------------------------
+# overloaded constants
+
+if ($] > 5.00503) {
+ if (! do 'test2.pl') {
+ die "Cannot run test2.pl\n";
+ }
+}
+
+
+
+
+#------------------------------------------------------------------------------
+# $# stuff
+#
+# For some reason "local $#" doesn't leave $# back at its default undefined
+# state when exiting the block.
+
+{ local $# = 'hi %.0f there';
+ my $f = mpf(123);
+ ok ("$f" eq 'hi 123 there'); }
+
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/gmp/demos/perl/test2.pl b/gmp/demos/perl/test2.pl
new file mode 100644
index 0000000000..31a1d6bdd9
--- /dev/null
+++ b/gmp/demos/perl/test2.pl
@@ -0,0 +1,75 @@
+# GMP perl module tests (part 2)
+
+# Copyright 2001 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# The following uses of :constants seem to provoke segvs in perl 5.005_03,
+# so they're kept separate file to be run only on suitable perl versions.
+
+
+use GMP::Mpz qw(:constants);
+{
+ my $a = 123;
+ ok (UNIVERSAL::isa ($a, "GMP::Mpz"));
+}
+use GMP::Mpz qw(:noconstants);
+
+use GMP::Mpq qw(:constants);
+{
+ my $a = 123;
+ ok (UNIVERSAL::isa ($a, "GMP::Mpq"));
+}
+use GMP::Mpq qw(:noconstants);
+
+use GMP::Mpf qw(:constants);
+{
+ my $a = 123;
+ ok (UNIVERSAL::isa ($a, "GMP::Mpf"));
+}
+use GMP::Mpf qw(:noconstants);
+
+
+# compiled constants unchanged by clrbit etc when re-executed
+foreach (0, 1, 2) {
+ use GMP::Mpz qw(:constants);
+ my $a = 15;
+ my $b = 6;
+ use GMP::Mpz qw(:noconstants);
+ clrbit ($a, 0);
+ ok ($a == 14);
+ setbit ($b, 0);
+ ok ($b == 7);
+}
+
+1;
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/gmp/demos/perl/typemap b/gmp/demos/perl/typemap
new file mode 100644
index 0000000000..e863a9c516
--- /dev/null
+++ b/gmp/demos/perl/typemap
@@ -0,0 +1,108 @@
+# GMP module external subroutine type mappings.
+
+# Copyright 2001, 2003 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+TYPEMAP
+const_string T_PV
+const_string_assume CONST_STRING_ASSUME
+mpz MPZ
+mpq MPQ
+mpf MPF
+mpz_assume MPZ_ASSUME
+mpq_assume MPQ_ASSUME
+mpf_assume MPF_ASSUME
+mpz_coerce MPZ_COERCE
+mpq_coerce MPQ_COERCE
+mpf_coerce_st0 MPF_COERCE_ST0
+mpf_coerce_def MPF_COERCE_DEF
+randstate RANDSTATE
+ulong_coerce ULONG_COERCE
+malloced_string MALLOCED_STRING
+order_noswap ORDER_NOSWAP
+dummy DUMMY
+# perl 5.005 doesn't have UV in its standard typemap, so use this instead
+gmp_UV GMP_UV
+
+
+INPUT
+MPZ
+ class_or_croak ($arg, mpz_class); $var = SvMPZ($arg);
+MPQ
+ class_or_croak ($arg, mpq_class); $var = SvMPQ($arg);
+MPF
+ class_or_croak ($arg, mpf_class); $var = SvMPF($arg);
+MPZ_ASSUME
+ MPZ_ASSUME ($var, $arg)
+MPQ_ASSUME
+ MPQ_ASSUME ($var, $arg)
+MPF_ASSUME
+ MPF_ASSUME ($var, $arg)
+MPZ_COERCE
+ $var = coerce_mpz (tmp_mpz_${(my $stnum=$arg)=~s/[^0-9]//g;\$stnum}, $arg)
+MPQ_COERCE
+ $var = coerce_mpq (tmp_mpq_${(my $stnum=$arg)=~s/[^0-9]//g;\$stnum}, $arg)
+MPF_COERCE_ST0
+ /* precision follows ST(0) */
+ assert (sv_derived_from (ST(0), mpf_class));
+ $var = coerce_mpf (tmp_mpf_${(my $stnum=$arg)=~s/[^0-9]//g;\$stnum},
+ $arg, mpf_get_prec (SvMPF(ST(0))))
+MPF_COERCE_DEF
+ /* default precision used */
+ $var = coerce_mpf (tmp_mpf_${(my $stnum=$arg)=~s/[^0-9]//g;\$stnum},
+ $arg, mpf_get_default_prec())
+RANDSTATE
+ class_or_croak ($arg, rand_class); $var = SvRANDSTATE($arg);
+ULONG_COERCE
+ $var = coerce_ulong ($arg)
+ORDER_NOSWAP
+ assert ($arg != &PL_sv_yes);
+DUMMY
+ /* dummy $var */
+CONST_STRING_ASSUME
+ /* No need to check for SvPOKp and use SvPV, this mapping is
+ only used for overload_constant, which always gets literal
+ strings. */
+ assert (SvPOK ($arg));
+ $var = SvPVX ($arg);
+
+
+OUTPUT
+MPZ
+ sv_bless (sv_setref_pv ($arg, NULL, $var), mpz_class_hv);
+MPQ
+ sv_bless (sv_setref_pv ($arg, NULL, $var), mpq_class_hv);
+MPF
+ sv_bless (sv_setref_pv ($arg, NULL, $var), mpf_class_hv);
+RANDSTATE
+ sv_setref_pv ($arg, rand_class, $var);
+MALLOCED_STRING
+ sv_usepvn_mg ($arg, $var, strlen($var));
+GMP_UV
+ sv_setuv ($arg, (UV) ($var));
diff --git a/gmp/demos/pexpr-config-h.in b/gmp/demos/pexpr-config-h.in
new file mode 100644
index 0000000000..b3e7f5d46f
--- /dev/null
+++ b/gmp/demos/pexpr-config-h.in
@@ -0,0 +1,45 @@
+/* Templates for pexpr program configuration. -*- mode:c -*-
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* Define if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H @HAVE_SYS_RESOURCE_H_01@
+
+/* Define if you have the `clock' function. */
+#define HAVE_CLOCK @HAVE_CLOCK_01@
+
+/* Define if you have the `cputime' function. */
+#define HAVE_CPUTIME @HAVE_CPUTIME_01@
+
+/* Define if you have the `getrusage' function. */
+#define HAVE_GETRUSAGE @HAVE_GETRUSAGE_01@
+
+/* Define if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY @HAVE_GETTIMEOFDAY_01@
+
+/* Define if you have the `sigaction' function. */
+#define HAVE_SIGACTION @HAVE_SIGACTION_01@
+
+/* Define if you have the `sigaltstack' function. */
+#define HAVE_SIGALTSTACK @HAVE_SIGALTSTACK_01@
+
+/* Define if you have the `sigstack' function. */
+#define HAVE_SIGSTACK @HAVE_SIGSTACK_01@
+
+/* Define if the system has the type `stack_t'. */
+#define HAVE_STACK_T @HAVE_STACK_T_01@
diff --git a/gmp/demos/pexpr.c b/gmp/demos/pexpr.c
new file mode 100644
index 0000000000..ce28187811
--- /dev/null
+++ b/gmp/demos/pexpr.c
@@ -0,0 +1,1378 @@
+/* Program for computing integer expressions using the GNU Multiple Precision
+ Arithmetic Library.
+
+Copyright 1997, 1999-2002, 2005, 2008, 2012 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* This expressions evaluator works by building an expression tree (using a
+ recursive descent parser) which is then evaluated. The expression tree is
+ useful since we want to optimize certain expressions (like a^b % c).
+
+ Usage: pexpr [options] expr ...
+ (Assuming you called the executable `pexpr' of course.)
+
+ Command line options:
+
+ -b print output in binary
+ -o print output in octal
+ -d print output in decimal (the default)
+ -x print output in hexadecimal
+ -b<NUM> print output in base NUM
+ -t print timing information
+ -html output html
+ -wml output wml
+ -split split long lines each 80th digit
+*/
+
+/* Define LIMIT_RESOURCE_USAGE if you want to make sure the program doesn't
+ use up extensive resources (cpu, memory). Useful for the GMP demo on the
+ GMP web site, since we cannot load the server too much. */
+
+#include "pexpr-config.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <ctype.h>
+
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#include "gmp.h"
+
+/* SunOS 4 and HPUX 9 don't define a canonical SIGSTKSZ, use a default. */
+#ifndef SIGSTKSZ
+#define SIGSTKSZ 4096
+#endif
+
+
+#define TIME(t,func) \
+ do { int __t0, __tmp; \
+ __t0 = cputime (); \
+ {func;} \
+ __tmp = cputime () - __t0; \
+ (t) = __tmp; \
+ } while (0)
+
+/* GMP version 1.x compatibility. */
+#if ! (__GNU_MP_VERSION >= 2)
+typedef MP_INT __mpz_struct;
+typedef __mpz_struct mpz_t[1];
+typedef __mpz_struct *mpz_ptr;
+#define mpz_fdiv_q mpz_div
+#define mpz_fdiv_r mpz_mod
+#define mpz_tdiv_q_2exp mpz_div_2exp
+#define mpz_sgn(Z) ((Z)->size < 0 ? -1 : (Z)->size > 0)
+#endif
+
+/* GMP version 2.0 compatibility. */
+#if ! (__GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1)
+#define mpz_swap(a,b) \
+ do { __mpz_struct __t; __t = *a; *a = *b; *b = __t;} while (0)
+#endif
+
+jmp_buf errjmpbuf;
+
+enum op_t {NOP, LIT, NEG, NOT, PLUS, MINUS, MULT, DIV, MOD, REM, INVMOD, POW,
+ AND, IOR, XOR, SLL, SRA, POPCNT, HAMDIST, GCD, LCM, SQRT, ROOT, FAC,
+ LOG, LOG2, FERMAT, MERSENNE, FIBONACCI, RANDOM, NEXTPRIME, BINOM,
+ TIMING};
+
+/* Type for the expression tree. */
+struct expr
+{
+ enum op_t op;
+ union
+ {
+ struct {struct expr *lhs, *rhs;} ops;
+ mpz_t val;
+ } operands;
+};
+
+typedef struct expr *expr_t;
+
+void cleanup_and_exit (int);
+
+char *skipspace (char *);
+void makeexp (expr_t *, enum op_t, expr_t, expr_t);
+void free_expr (expr_t);
+char *expr (char *, expr_t *);
+char *term (char *, expr_t *);
+char *power (char *, expr_t *);
+char *factor (char *, expr_t *);
+int match (char *, char *);
+int matchp (char *, char *);
+int cputime (void);
+
+void mpz_eval_expr (mpz_ptr, expr_t);
+void mpz_eval_mod_expr (mpz_ptr, expr_t, mpz_ptr);
+
+char *error;
+int flag_print = 1;
+int print_timing = 0;
+int flag_html = 0;
+int flag_wml = 0;
+int flag_splitup_output = 0;
+char *newline = "";
+gmp_randstate_t rstate;
+
+
+
+/* cputime() returns user CPU time measured in milliseconds. */
+#if ! HAVE_CPUTIME
+#if HAVE_GETRUSAGE
+int
+cputime (void)
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#if HAVE_CLOCK
+int
+cputime (void)
+{
+ if (CLOCKS_PER_SEC < 100000)
+ return clock () * 1000 / CLOCKS_PER_SEC;
+ return clock () / (CLOCKS_PER_SEC / 1000);
+}
+#else
+int
+cputime (void)
+{
+ return 0;
+}
+#endif
+#endif
+#endif
+
+
+int
+stack_downwards_helper (char *xp)
+{
+ char y;
+ return &y < xp;
+}
+int
+stack_downwards_p (void)
+{
+ char x;
+ return stack_downwards_helper (&x);
+}
+
+
+void
+setup_error_handler (void)
+{
+#if HAVE_SIGACTION
+ struct sigaction act;
+ act.sa_handler = cleanup_and_exit;
+ sigemptyset (&(act.sa_mask));
+#define SIGNAL(sig) sigaction (sig, &act, NULL)
+#else
+ struct { int sa_flags; } act;
+#define SIGNAL(sig) signal (sig, cleanup_and_exit)
+#endif
+ act.sa_flags = 0;
+
+ /* Set up a stack for signal handling. A typical cause of error is stack
+ overflow, and in such situation a signal can not be delivered on the
+ overflown stack. */
+#if HAVE_SIGALTSTACK
+ {
+ /* AIX uses stack_t, MacOS uses struct sigaltstack, various other
+ systems have both. */
+#if HAVE_STACK_T
+ stack_t s;
+#else
+ struct sigaltstack s;
+#endif
+ s.ss_sp = malloc (SIGSTKSZ);
+ s.ss_size = SIGSTKSZ;
+ s.ss_flags = 0;
+ if (sigaltstack (&s, NULL) != 0)
+ perror("sigaltstack");
+ act.sa_flags = SA_ONSTACK;
+ }
+#else
+#if HAVE_SIGSTACK
+ {
+ struct sigstack s;
+ s.ss_sp = malloc (SIGSTKSZ);
+ if (stack_downwards_p ())
+ s.ss_sp += SIGSTKSZ;
+ s.ss_onstack = 0;
+ if (sigstack (&s, NULL) != 0)
+ perror("sigstack");
+ act.sa_flags = SA_ONSTACK;
+ }
+#else
+#endif
+#endif
+
+#ifdef LIMIT_RESOURCE_USAGE
+ {
+ struct rlimit limit;
+
+ limit.rlim_cur = limit.rlim_max = 0;
+ setrlimit (RLIMIT_CORE, &limit);
+
+ limit.rlim_cur = 3;
+ limit.rlim_max = 4;
+ setrlimit (RLIMIT_CPU, &limit);
+
+ limit.rlim_cur = limit.rlim_max = 16 * 1024 * 1024;
+ setrlimit (RLIMIT_DATA, &limit);
+
+ getrlimit (RLIMIT_STACK, &limit);
+ limit.rlim_cur = 4 * 1024 * 1024;
+ setrlimit (RLIMIT_STACK, &limit);
+
+ SIGNAL (SIGXCPU);
+ }
+#endif /* LIMIT_RESOURCE_USAGE */
+
+ SIGNAL (SIGILL);
+ SIGNAL (SIGSEGV);
+#ifdef SIGBUS /* not in mingw */
+ SIGNAL (SIGBUS);
+#endif
+ SIGNAL (SIGFPE);
+ SIGNAL (SIGABRT);
+}
+
+int
+main (int argc, char **argv)
+{
+ struct expr *e;
+ int i;
+ mpz_t r;
+ int errcode = 0;
+ char *str;
+ int base = 10;
+
+ setup_error_handler ();
+
+ gmp_randinit (rstate, GMP_RAND_ALG_LC, 128);
+
+ {
+#if HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ gmp_randseed_ui (rstate, tv.tv_sec + tv.tv_usec);
+#else
+ time_t t;
+ time (&t);
+ gmp_randseed_ui (rstate, t);
+#endif
+ }
+
+ mpz_init (r);
+
+ while (argc > 1 && argv[1][0] == '-')
+ {
+ char *arg = argv[1];
+
+ if (arg[1] >= '0' && arg[1] <= '9')
+ break;
+
+ if (arg[1] == 't')
+ print_timing = 1;
+ else if (arg[1] == 'b' && arg[2] >= '0' && arg[2] <= '9')
+ {
+ base = atoi (arg + 2);
+ if (base < 2 || base > 62)
+ {
+ fprintf (stderr, "error: invalid output base\n");
+ exit (-1);
+ }
+ }
+ else if (arg[1] == 'b' && arg[2] == 0)
+ base = 2;
+ else if (arg[1] == 'x' && arg[2] == 0)
+ base = 16;
+ else if (arg[1] == 'X' && arg[2] == 0)
+ base = -16;
+ else if (arg[1] == 'o' && arg[2] == 0)
+ base = 8;
+ else if (arg[1] == 'd' && arg[2] == 0)
+ base = 10;
+ else if (arg[1] == 'v' && arg[2] == 0)
+ {
+ printf ("pexpr linked to gmp %s\n", __gmp_version);
+ }
+ else if (strcmp (arg, "-html") == 0)
+ {
+ flag_html = 1;
+ newline = "<br>";
+ }
+ else if (strcmp (arg, "-wml") == 0)
+ {
+ flag_wml = 1;
+ newline = "<br/>";
+ }
+ else if (strcmp (arg, "-split") == 0)
+ {
+ flag_splitup_output = 1;
+ }
+ else if (strcmp (arg, "-noprint") == 0)
+ {
+ flag_print = 0;
+ }
+ else
+ {
+ fprintf (stderr, "error: unknown option `%s'\n", arg);
+ exit (-1);
+ }
+ argv++;
+ argc--;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ int s;
+ int jmpval;
+
+ /* Set up error handler for parsing expression. */
+ jmpval = setjmp (errjmpbuf);
+ if (jmpval != 0)
+ {
+ fprintf (stderr, "error: %s%s\n", error, newline);
+ fprintf (stderr, " %s%s\n", argv[i], newline);
+ if (! flag_html)
+ {
+ /* ??? Dunno how to align expression position with arrow in
+ HTML ??? */
+ fprintf (stderr, " ");
+ for (s = jmpval - (long) argv[i]; --s >= 0; )
+ putc (' ', stderr);
+ fprintf (stderr, "^\n");
+ }
+
+ errcode |= 1;
+ continue;
+ }
+
+ str = expr (argv[i], &e);
+
+ if (str[0] != 0)
+ {
+ fprintf (stderr,
+ "error: garbage where end of expression expected%s\n",
+ newline);
+ fprintf (stderr, " %s%s\n", argv[i], newline);
+ if (! flag_html)
+ {
+ /* ??? Dunno how to align expression position with arrow in
+ HTML ??? */
+ fprintf (stderr, " ");
+ for (s = str - argv[i]; --s; )
+ putc (' ', stderr);
+ fprintf (stderr, "^\n");
+ }
+
+ errcode |= 1;
+ free_expr (e);
+ continue;
+ }
+
+ /* Set up error handler for evaluating expression. */
+ if (setjmp (errjmpbuf))
+ {
+ fprintf (stderr, "error: %s%s\n", error, newline);
+ fprintf (stderr, " %s%s\n", argv[i], newline);
+ if (! flag_html)
+ {
+ /* ??? Dunno how to align expression position with arrow in
+ HTML ??? */
+ fprintf (stderr, " ");
+ for (s = str - argv[i]; --s >= 0; )
+ putc (' ', stderr);
+ fprintf (stderr, "^\n");
+ }
+
+ errcode |= 2;
+ continue;
+ }
+
+ if (print_timing)
+ {
+ int t;
+ TIME (t, mpz_eval_expr (r, e));
+ printf ("computation took %d ms%s\n", t, newline);
+ }
+ else
+ mpz_eval_expr (r, e);
+
+ if (flag_print)
+ {
+ size_t out_len;
+ char *tmp, *s;
+
+ out_len = mpz_sizeinbase (r, base >= 0 ? base : -base) + 2;
+#ifdef LIMIT_RESOURCE_USAGE
+ if (out_len > 100000)
+ {
+ printf ("result is about %ld digits, not printing it%s\n",
+ (long) out_len - 3, newline);
+ exit (-2);
+ }
+#endif
+ tmp = malloc (out_len);
+
+ if (print_timing)
+ {
+ int t;
+ printf ("output conversion ");
+ TIME (t, mpz_get_str (tmp, base, r));
+ printf ("took %d ms%s\n", t, newline);
+ }
+ else
+ mpz_get_str (tmp, base, r);
+
+ out_len = strlen (tmp);
+ if (flag_splitup_output)
+ {
+ for (s = tmp; out_len > 80; s += 80)
+ {
+ fwrite (s, 1, 80, stdout);
+ printf ("%s\n", newline);
+ out_len -= 80;
+ }
+
+ fwrite (s, 1, out_len, stdout);
+ }
+ else
+ {
+ fwrite (tmp, 1, out_len, stdout);
+ }
+
+ free (tmp);
+ printf ("%s\n", newline);
+ }
+ else
+ {
+ printf ("result is approximately %ld digits%s\n",
+ (long) mpz_sizeinbase (r, base >= 0 ? base : -base),
+ newline);
+ }
+
+ free_expr (e);
+ }
+
+ exit (errcode);
+}
+
+char *
+expr (char *str, expr_t *e)
+{
+ expr_t e2;
+
+ str = skipspace (str);
+ if (str[0] == '+')
+ {
+ str = term (str + 1, e);
+ }
+ else if (str[0] == '-')
+ {
+ str = term (str + 1, e);
+ makeexp (e, NEG, *e, NULL);
+ }
+ else if (str[0] == '~')
+ {
+ str = term (str + 1, e);
+ makeexp (e, NOT, *e, NULL);
+ }
+ else
+ {
+ str = term (str, e);
+ }
+
+ for (;;)
+ {
+ str = skipspace (str);
+ switch (str[0])
+ {
+ case 'p':
+ if (match ("plus", str))
+ {
+ str = term (str + 4, &e2);
+ makeexp (e, PLUS, *e, e2);
+ }
+ else
+ return str;
+ break;
+ case 'm':
+ if (match ("minus", str))
+ {
+ str = term (str + 5, &e2);
+ makeexp (e, MINUS, *e, e2);
+ }
+ else
+ return str;
+ break;
+ case '+':
+ str = term (str + 1, &e2);
+ makeexp (e, PLUS, *e, e2);
+ break;
+ case '-':
+ str = term (str + 1, &e2);
+ makeexp (e, MINUS, *e, e2);
+ break;
+ default:
+ return str;
+ }
+ }
+}
+
+char *
+term (char *str, expr_t *e)
+{
+ expr_t e2;
+
+ str = power (str, e);
+ for (;;)
+ {
+ str = skipspace (str);
+ switch (str[0])
+ {
+ case 'm':
+ if (match ("mul", str))
+ {
+ str = power (str + 3, &e2);
+ makeexp (e, MULT, *e, e2);
+ break;
+ }
+ if (match ("mod", str))
+ {
+ str = power (str + 3, &e2);
+ makeexp (e, MOD, *e, e2);
+ break;
+ }
+ return str;
+ case 'd':
+ if (match ("div", str))
+ {
+ str = power (str + 3, &e2);
+ makeexp (e, DIV, *e, e2);
+ break;
+ }
+ return str;
+ case 'r':
+ if (match ("rem", str))
+ {
+ str = power (str + 3, &e2);
+ makeexp (e, REM, *e, e2);
+ break;
+ }
+ return str;
+ case 'i':
+ if (match ("invmod", str))
+ {
+ str = power (str + 6, &e2);
+ makeexp (e, REM, *e, e2);
+ break;
+ }
+ return str;
+ case 't':
+ if (match ("times", str))
+ {
+ str = power (str + 5, &e2);
+ makeexp (e, MULT, *e, e2);
+ break;
+ }
+ if (match ("thru", str))
+ {
+ str = power (str + 4, &e2);
+ makeexp (e, DIV, *e, e2);
+ break;
+ }
+ if (match ("through", str))
+ {
+ str = power (str + 7, &e2);
+ makeexp (e, DIV, *e, e2);
+ break;
+ }
+ return str;
+ case '*':
+ str = power (str + 1, &e2);
+ makeexp (e, MULT, *e, e2);
+ break;
+ case '/':
+ str = power (str + 1, &e2);
+ makeexp (e, DIV, *e, e2);
+ break;
+ case '%':
+ str = power (str + 1, &e2);
+ makeexp (e, MOD, *e, e2);
+ break;
+ default:
+ return str;
+ }
+ }
+}
+
+char *
+power (char *str, expr_t *e)
+{
+ expr_t e2;
+
+ str = factor (str, e);
+ while (str[0] == '!')
+ {
+ str++;
+ makeexp (e, FAC, *e, NULL);
+ }
+ str = skipspace (str);
+ if (str[0] == '^')
+ {
+ str = power (str + 1, &e2);
+ makeexp (e, POW, *e, e2);
+ }
+ return str;
+}
+
+int
+match (char *s, char *str)
+{
+ char *ostr = str;
+ int i;
+
+ for (i = 0; s[i] != 0; i++)
+ {
+ if (str[i] != s[i])
+ return 0;
+ }
+ str = skipspace (str + i);
+ return str - ostr;
+}
+
+int
+matchp (char *s, char *str)
+{
+ char *ostr = str;
+ int i;
+
+ for (i = 0; s[i] != 0; i++)
+ {
+ if (str[i] != s[i])
+ return 0;
+ }
+ str = skipspace (str + i);
+ if (str[0] == '(')
+ return str - ostr + 1;
+ return 0;
+}
+
+struct functions
+{
+ char *spelling;
+ enum op_t op;
+ int arity; /* 1 or 2 means real arity; 0 means arbitrary. */
+};
+
+struct functions fns[] =
+{
+ {"sqrt", SQRT, 1},
+#if __GNU_MP_VERSION >= 2
+ {"root", ROOT, 2},
+ {"popc", POPCNT, 1},
+ {"hamdist", HAMDIST, 2},
+#endif
+ {"gcd", GCD, 0},
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ {"lcm", LCM, 0},
+#endif
+ {"and", AND, 0},
+ {"ior", IOR, 0},
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ {"xor", XOR, 0},
+#endif
+ {"plus", PLUS, 0},
+ {"pow", POW, 2},
+ {"minus", MINUS, 2},
+ {"mul", MULT, 0},
+ {"div", DIV, 2},
+ {"mod", MOD, 2},
+ {"rem", REM, 2},
+#if __GNU_MP_VERSION >= 2
+ {"invmod", INVMOD, 2},
+#endif
+ {"log", LOG, 2},
+ {"log2", LOG2, 1},
+ {"F", FERMAT, 1},
+ {"M", MERSENNE, 1},
+ {"fib", FIBONACCI, 1},
+ {"Fib", FIBONACCI, 1},
+ {"random", RANDOM, 1},
+ {"nextprime", NEXTPRIME, 1},
+ {"binom", BINOM, 2},
+ {"binomial", BINOM, 2},
+ {"fac", FAC, 1},
+ {"fact", FAC, 1},
+ {"factorial", FAC, 1},
+ {"time", TIMING, 1},
+ {"", NOP, 0}
+};
+
+char *
+factor (char *str, expr_t *e)
+{
+ expr_t e1, e2;
+
+ str = skipspace (str);
+
+ if (isalpha (str[0]))
+ {
+ int i;
+ int cnt;
+
+ for (i = 0; fns[i].op != NOP; i++)
+ {
+ if (fns[i].arity == 1)
+ {
+ cnt = matchp (fns[i].spelling, str);
+ if (cnt != 0)
+ {
+ str = expr (str + cnt, &e1);
+ str = skipspace (str);
+ if (str[0] != ')')
+ {
+ error = "expected `)'";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+ makeexp (e, fns[i].op, e1, NULL);
+ return str + 1;
+ }
+ }
+ }
+
+ for (i = 0; fns[i].op != NOP; i++)
+ {
+ if (fns[i].arity != 1)
+ {
+ cnt = matchp (fns[i].spelling, str);
+ if (cnt != 0)
+ {
+ str = expr (str + cnt, &e1);
+ str = skipspace (str);
+
+ if (str[0] != ',')
+ {
+ error = "expected `,' and another operand";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+
+ str = skipspace (str + 1);
+ str = expr (str, &e2);
+ str = skipspace (str);
+
+ if (fns[i].arity == 0)
+ {
+ while (str[0] == ',')
+ {
+ makeexp (&e1, fns[i].op, e1, e2);
+ str = skipspace (str + 1);
+ str = expr (str, &e2);
+ str = skipspace (str);
+ }
+ }
+
+ if (str[0] != ')')
+ {
+ error = "expected `)'";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+
+ makeexp (e, fns[i].op, e1, e2);
+ return str + 1;
+ }
+ }
+ }
+ }
+
+ if (str[0] == '(')
+ {
+ str = expr (str + 1, e);
+ str = skipspace (str);
+ if (str[0] != ')')
+ {
+ error = "expected `)'";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+ str++;
+ }
+ else if (str[0] >= '0' && str[0] <= '9')
+ {
+ expr_t res;
+ char *s, *sc;
+
+ res = malloc (sizeof (struct expr));
+ res -> op = LIT;
+ mpz_init (res->operands.val);
+
+ s = str;
+ while (isalnum (str[0]))
+ str++;
+ sc = malloc (str - s + 1);
+ memcpy (sc, s, str - s);
+ sc[str - s] = 0;
+
+ mpz_set_str (res->operands.val, sc, 0);
+ *e = res;
+ free (sc);
+ }
+ else
+ {
+ error = "operand expected";
+ longjmp (errjmpbuf, (int) (long) str);
+ }
+ return str;
+}
+
+char *
+skipspace (char *str)
+{
+ while (str[0] == ' ')
+ str++;
+ return str;
+}
+
+/* Make a new expression with operation OP and right hand side
+ RHS and left hand side lhs. Put the result in R. */
+void
+makeexp (expr_t *r, enum op_t op, expr_t lhs, expr_t rhs)
+{
+ expr_t res;
+ res = malloc (sizeof (struct expr));
+ res -> op = op;
+ res -> operands.ops.lhs = lhs;
+ res -> operands.ops.rhs = rhs;
+ *r = res;
+ return;
+}
+
+/* Free the memory used by expression E. */
+void
+free_expr (expr_t e)
+{
+ if (e->op != LIT)
+ {
+ free_expr (e->operands.ops.lhs);
+ if (e->operands.ops.rhs != NULL)
+ free_expr (e->operands.ops.rhs);
+ }
+ else
+ {
+ mpz_clear (e->operands.val);
+ }
+}
+
+/* Evaluate the expression E and put the result in R. */
+void
+mpz_eval_expr (mpz_ptr r, expr_t e)
+{
+ mpz_t lhs, rhs;
+
+ switch (e->op)
+ {
+ case LIT:
+ mpz_set (r, e->operands.val);
+ return;
+ case PLUS:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_add (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MINUS:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_sub (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MULT:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_mul (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case DIV:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_fdiv_q (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MOD:
+ mpz_init (rhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_abs (rhs, rhs);
+ mpz_eval_mod_expr (r, e->operands.ops.lhs, rhs);
+ mpz_clear (rhs);
+ return;
+ case REM:
+ /* Check if lhs operand is POW expression and optimize for that case. */
+ if (e->operands.ops.lhs->op == POW)
+ {
+ mpz_t powlhs, powrhs;
+ mpz_init (powlhs);
+ mpz_init (powrhs);
+ mpz_init (rhs);
+ mpz_eval_expr (powlhs, e->operands.ops.lhs->operands.ops.lhs);
+ mpz_eval_expr (powrhs, e->operands.ops.lhs->operands.ops.rhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_powm (r, powlhs, powrhs, rhs);
+ if (mpz_cmp_si (rhs, 0L) < 0)
+ mpz_neg (r, r);
+ mpz_clear (powlhs);
+ mpz_clear (powrhs);
+ mpz_clear (rhs);
+ return;
+ }
+
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_fdiv_r (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#if __GNU_MP_VERSION >= 2
+ case INVMOD:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_invert (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#endif
+ case POW:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_cmpabs_ui (lhs, 1) <= 0)
+ {
+ /* For 0^rhs and 1^rhs, we just need to verify that
+ rhs is well-defined. For (-1)^rhs we need to
+ determine (rhs mod 2). For simplicity, compute
+ (rhs mod 2) for all three cases. */
+ expr_t two, et;
+ two = malloc (sizeof (struct expr));
+ two -> op = LIT;
+ mpz_init_set_ui (two->operands.val, 2L);
+ makeexp (&et, MOD, e->operands.ops.rhs, two);
+ e->operands.ops.rhs = et;
+ }
+
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ if (mpz_cmp_si (rhs, 0L) == 0)
+ /* x^0 is 1 */
+ mpz_set_ui (r, 1L);
+ else if (mpz_cmp_si (lhs, 0L) == 0)
+ /* 0^y (where y != 0) is 0 */
+ mpz_set_ui (r, 0L);
+ else if (mpz_cmp_ui (lhs, 1L) == 0)
+ /* 1^y is 1 */
+ mpz_set_ui (r, 1L);
+ else if (mpz_cmp_si (lhs, -1L) == 0)
+ /* (-1)^y just depends on whether y is even or odd */
+ mpz_set_si (r, (mpz_get_ui (rhs) & 1) ? -1L : 1L);
+ else if (mpz_cmp_si (rhs, 0L) < 0)
+ /* x^(-n) is 0 */
+ mpz_set_ui (r, 0L);
+ else
+ {
+ unsigned long int cnt;
+ unsigned long int y;
+ /* error if exponent does not fit into an unsigned long int. */
+ if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
+ goto pow_err;
+
+ y = mpz_get_ui (rhs);
+ /* x^y == (x/(2^c))^y * 2^(c*y) */
+#if __GNU_MP_VERSION >= 2
+ cnt = mpz_scan1 (lhs, 0);
+#else
+ cnt = 0;
+#endif
+ if (cnt != 0)
+ {
+ if (y * cnt / cnt != y)
+ goto pow_err;
+ mpz_tdiv_q_2exp (lhs, lhs, cnt);
+ mpz_pow_ui (r, lhs, y);
+ mpz_mul_2exp (r, r, y * cnt);
+ }
+ else
+ mpz_pow_ui (r, lhs, y);
+ }
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ pow_err:
+ error = "result of `pow' operator too large";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ case GCD:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_gcd (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ case LCM:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_lcm (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#endif
+ case AND:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_and (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case IOR:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_ior (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ case XOR:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_xor (r, lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#endif
+ case NEG:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ mpz_neg (r, r);
+ return;
+ case NOT:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ mpz_com (r, r);
+ return;
+ case SQRT:
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_sgn (lhs) < 0)
+ {
+ error = "cannot take square root of negative numbers";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ mpz_sqrt (r, lhs);
+ return;
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ case ROOT:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ if (mpz_sgn (rhs) <= 0)
+ {
+ error = "cannot take non-positive root orders";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+ if (mpz_sgn (lhs) < 0 && (mpz_get_ui (rhs) & 1) == 0)
+ {
+ error = "cannot take even root orders of negative numbers";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+
+ {
+ unsigned long int nth = mpz_get_ui (rhs);
+ if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
+ {
+ /* If we are asked to take an awfully large root order, cheat and
+ ask for the largest order we can pass to mpz_root. This saves
+ some error prone special cases. */
+ nth = ~(unsigned long int) 0;
+ }
+ mpz_root (r, lhs, nth);
+ }
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+#endif
+ case FAC:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ if (mpz_size (r) > 1)
+ {
+ error = "result of `!' operator too large";
+ longjmp (errjmpbuf, 1);
+ }
+ mpz_fac_ui (r, mpz_get_ui (r));
+ return;
+#if __GNU_MP_VERSION >= 2
+ case POPCNT:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ { long int cnt;
+ cnt = mpz_popcount (r);
+ mpz_set_si (r, cnt);
+ }
+ return;
+ case HAMDIST:
+ { long int cnt;
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ cnt = mpz_hamdist (lhs, rhs);
+ mpz_clear (lhs); mpz_clear (rhs);
+ mpz_set_si (r, cnt);
+ }
+ return;
+#endif
+ case LOG2:
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ { unsigned long int cnt;
+ if (mpz_sgn (r) <= 0)
+ {
+ error = "logarithm of non-positive number";
+ longjmp (errjmpbuf, 1);
+ }
+ cnt = mpz_sizeinbase (r, 2);
+ mpz_set_ui (r, cnt - 1);
+ }
+ return;
+ case LOG:
+ { unsigned long int cnt;
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ if (mpz_sgn (lhs) <= 0)
+ {
+ error = "logarithm of non-positive number";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+ if (mpz_cmp_ui (rhs, 256) >= 0)
+ {
+ error = "logarithm base too large";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+ cnt = mpz_sizeinbase (lhs, mpz_get_ui (rhs));
+ mpz_set_ui (r, cnt - 1);
+ mpz_clear (lhs); mpz_clear (rhs);
+ }
+ return;
+ case FERMAT:
+ {
+ unsigned long int t;
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ t = (unsigned long int) 1 << mpz_get_ui (lhs);
+ if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0 || t == 0)
+ {
+ error = "too large Mersenne number index";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ mpz_set_ui (r, 1);
+ mpz_mul_2exp (r, r, t);
+ mpz_add_ui (r, r, 1);
+ mpz_clear (lhs);
+ }
+ return;
+ case MERSENNE:
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0)
+ {
+ error = "too large Mersenne number index";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ mpz_set_ui (r, 1);
+ mpz_mul_2exp (r, r, mpz_get_ui (lhs));
+ mpz_sub_ui (r, r, 1);
+ mpz_clear (lhs);
+ return;
+ case FIBONACCI:
+ { mpz_t t;
+ unsigned long int n, i;
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
+ {
+ error = "Fibonacci index out of range";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ n = mpz_get_ui (lhs);
+ mpz_clear (lhs);
+
+#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
+ mpz_fib_ui (r, n);
+#else
+ mpz_init_set_ui (t, 1);
+ mpz_set_ui (r, 1);
+
+ if (n <= 2)
+ mpz_set_ui (r, 1);
+ else
+ {
+ for (i = 3; i <= n; i++)
+ {
+ mpz_add (t, t, r);
+ mpz_swap (t, r);
+ }
+ }
+ mpz_clear (t);
+#endif
+ }
+ return;
+ case RANDOM:
+ {
+ unsigned long int n;
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
+ {
+ error = "random number size out of range";
+ mpz_clear (lhs);
+ longjmp (errjmpbuf, 1);
+ }
+ n = mpz_get_ui (lhs);
+ mpz_clear (lhs);
+ mpz_urandomb (r, rstate, n);
+ }
+ return;
+ case NEXTPRIME:
+ {
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ mpz_nextprime (r, r);
+ }
+ return;
+ case BINOM:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_expr (lhs, e->operands.ops.lhs);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ {
+ unsigned long int k;
+ if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
+ {
+ error = "k too large in (n over k) expression";
+ mpz_clear (lhs); mpz_clear (rhs);
+ longjmp (errjmpbuf, 1);
+ }
+ k = mpz_get_ui (rhs);
+ mpz_bin_ui (r, lhs, k);
+ }
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case TIMING:
+ {
+ int t0;
+ t0 = cputime ();
+ mpz_eval_expr (r, e->operands.ops.lhs);
+ printf ("time: %d\n", cputime () - t0);
+ }
+ return;
+ default:
+ abort ();
+ }
+}
+
+/* Evaluate the expression E modulo MOD and put the result in R. */
+void
+mpz_eval_mod_expr (mpz_ptr r, expr_t e, mpz_ptr mod)
+{
+ mpz_t lhs, rhs;
+
+ switch (e->op)
+ {
+ case POW:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
+ mpz_eval_expr (rhs, e->operands.ops.rhs);
+ mpz_powm (r, lhs, rhs, mod);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case PLUS:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
+ mpz_eval_mod_expr (rhs, e->operands.ops.rhs, mod);
+ mpz_add (r, lhs, rhs);
+ if (mpz_cmp_si (r, 0L) < 0)
+ mpz_add (r, r, mod);
+ else if (mpz_cmp (r, mod) >= 0)
+ mpz_sub (r, r, mod);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MINUS:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
+ mpz_eval_mod_expr (rhs, e->operands.ops.rhs, mod);
+ mpz_sub (r, lhs, rhs);
+ if (mpz_cmp_si (r, 0L) < 0)
+ mpz_add (r, r, mod);
+ else if (mpz_cmp (r, mod) >= 0)
+ mpz_sub (r, r, mod);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ case MULT:
+ mpz_init (lhs); mpz_init (rhs);
+ mpz_eval_mod_expr (lhs, e->operands.ops.lhs, mod);
+ mpz_eval_mod_expr (rhs, e->operands.ops.rhs, mod);
+ mpz_mul (r, lhs, rhs);
+ mpz_mod (r, r, mod);
+ mpz_clear (lhs); mpz_clear (rhs);
+ return;
+ default:
+ mpz_init (lhs);
+ mpz_eval_expr (lhs, e);
+ mpz_mod (r, lhs, mod);
+ mpz_clear (lhs);
+ return;
+ }
+}
+
+void
+cleanup_and_exit (int sig)
+{
+ switch (sig) {
+#ifdef LIMIT_RESOURCE_USAGE
+ case SIGXCPU:
+ printf ("expression took too long to evaluate%s\n", newline);
+ break;
+#endif
+ case SIGFPE:
+ printf ("divide by zero%s\n", newline);
+ break;
+ default:
+ printf ("expression required too much memory to evaluate%s\n", newline);
+ break;
+ }
+ exit (-2);
+}
diff --git a/gmp/demos/primes.c b/gmp/demos/primes.c
new file mode 100644
index 0000000000..3cb32e2e25
--- /dev/null
+++ b/gmp/demos/primes.c
@@ -0,0 +1,387 @@
+/* List and count primes.
+ Written by tege while on holiday in Rodupp, August 2001.
+ Between 10 and 500 times faster than previous program.
+
+Copyright 2001, 2002, 2006, 2012 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+
+/* IDEAS:
+ * Do not fill primes[] with real primes when the range [fr,to] is small,
+ when fr,to are relatively large. Fill primes[] with odd numbers instead.
+ [Probably a bad idea, since the primes[] array would become very large.]
+ * Separate small primes and large primes when sieving. Either the Montgomery
+ way (i.e., having a large array a multiple of L1 cache size), or just
+ separate loops for primes <= S and primes > S. The latter primes do not
+ require an inner loop, since they will touch the sieving array at most once.
+ * Pre-fill sieving array with an appropriately aligned ...00100100... pattern,
+ then omit 3 from primes array. (May require similar special handling of 3
+ as we now have for 2.)
+ * A large SIEVE_LIMIT currently implies very large memory usage, mainly due
+ to the sieving array in make_primelist, but also because of the primes[]
+ array. We might want to stage the program, using sieve_region/find_primes
+ to build primes[]. Make report() a function pointer, as part of achieving
+ this.
+ * Store primes[] as two arrays, one array with primes represented as delta
+ values using just 8 bits (if gaps are too big, store bogus primes!)
+ and one array with "rem" values. The latter needs 32-bit values.
+ * A new entry point, mpz_probab_prime_likely_p, would be useful.
+ * Improve command line syntax and versatility. "primes -f FROM -t TO",
+ allow either to be omitted for open interval. (But disallow
+ "primes -c -f FROM" since that would be infinity.) Allow printing a
+ limited *number* of primes using syntax like "primes -f FROM -n NUMBER".
+ * When looking for maxgaps, we should not perform any primality testing until
+ we find possible record gaps. Should speed up the searches tremendously.
+ */
+
+#include "gmp.h"
+
+struct primes
+{
+ unsigned int prime;
+ int rem;
+};
+
+struct primes *primes;
+unsigned long n_primes;
+
+void find_primes (unsigned char *, mpz_t, unsigned long, mpz_t);
+void sieve_region (unsigned char *, mpz_t, unsigned long);
+void make_primelist (unsigned long);
+
+int flag_print = 1;
+int flag_count = 0;
+int flag_maxgap = 0;
+unsigned long maxgap = 0;
+unsigned long total_primes = 0;
+
+void
+report (mpz_t prime)
+{
+ total_primes += 1;
+ if (flag_print)
+ {
+ mpz_out_str (stdout, 10, prime);
+ printf ("\n");
+ }
+ if (flag_maxgap)
+ {
+ static unsigned long prev_prime_low = 0;
+ unsigned long gap;
+ if (prev_prime_low != 0)
+ {
+ gap = mpz_get_ui (prime) - prev_prime_low;
+ if (maxgap < gap)
+ maxgap = gap;
+ }
+ prev_prime_low = mpz_get_ui (prime);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *progname = argv[0];
+ mpz_t fr, to;
+ mpz_t fr2, to2;
+ unsigned long sieve_lim;
+ unsigned long est_n_primes;
+ unsigned char *s;
+ mpz_t tmp;
+ mpz_t siev_sqr_lim;
+
+ while (argc != 1)
+ {
+ if (strcmp (argv[1], "-c") == 0)
+ {
+ flag_count = 1;
+ argv++;
+ argc--;
+ }
+ else if (strcmp (argv[1], "-p") == 0)
+ {
+ flag_print = 2;
+ argv++;
+ argc--;
+ }
+ else if (strcmp (argv[1], "-g") == 0)
+ {
+ flag_maxgap = 1;
+ argv++;
+ argc--;
+ }
+ else
+ break;
+ }
+
+ if (flag_count || flag_maxgap)
+ flag_print--; /* clear unless an explicit -p */
+
+ mpz_init (fr);
+ mpz_init (to);
+ mpz_init (fr2);
+ mpz_init (to2);
+
+ if (argc == 3)
+ {
+ mpz_set_str (fr, argv[1], 0);
+ if (argv[2][0] == '+')
+ {
+ mpz_set_str (to, argv[2] + 1, 0);
+ mpz_add (to, to, fr);
+ }
+ else
+ mpz_set_str (to, argv[2], 0);
+ }
+ else if (argc == 2)
+ {
+ mpz_set_ui (fr, 0);
+ mpz_set_str (to, argv[1], 0);
+ }
+ else
+ {
+ fprintf (stderr, "usage: %s [-c] [-p] [-g] [from [+]]to\n", progname);
+ exit (1);
+ }
+
+ mpz_set (fr2, fr);
+ if (mpz_cmp_ui (fr2, 3) < 0)
+ {
+ mpz_set_ui (fr2, 2);
+ report (fr2);
+ mpz_set_ui (fr2, 3);
+ }
+ mpz_setbit (fr2, 0); /* make odd */
+ mpz_sub_ui (to2, to, 1);
+ mpz_setbit (to2, 0); /* make odd */
+
+ mpz_init (tmp);
+ mpz_init (siev_sqr_lim);
+
+ mpz_sqrt (tmp, to2);
+#define SIEVE_LIMIT 10000000
+ if (mpz_cmp_ui (tmp, SIEVE_LIMIT) < 0)
+ {
+ sieve_lim = mpz_get_ui (tmp);
+ }
+ else
+ {
+ sieve_lim = SIEVE_LIMIT;
+ mpz_sub (tmp, to2, fr2);
+ if (mpz_cmp_ui (tmp, sieve_lim) < 0)
+ sieve_lim = mpz_get_ui (tmp); /* limit sieving for small ranges */
+ }
+ mpz_set_ui (siev_sqr_lim, sieve_lim + 1);
+ mpz_mul_ui (siev_sqr_lim, siev_sqr_lim, sieve_lim + 1);
+
+ est_n_primes = (size_t) (sieve_lim / log((double) sieve_lim) * 1.13) + 10;
+ primes = malloc (est_n_primes * sizeof primes[0]);
+ make_primelist (sieve_lim);
+ assert (est_n_primes >= n_primes);
+
+#if DEBUG
+ printf ("sieve_lim = %lu\n", sieve_lim);
+ printf ("n_primes = %lu (3..%u)\n",
+ n_primes, primes[n_primes - 1].prime);
+#endif
+
+#define S (1 << 15) /* FIXME: Figure out L1 cache size */
+ s = malloc (S/2);
+ while (mpz_cmp (fr2, to2) <= 0)
+ {
+ unsigned long rsize;
+ rsize = S;
+ mpz_add_ui (tmp, fr2, rsize);
+ if (mpz_cmp (tmp, to2) > 0)
+ {
+ mpz_sub (tmp, to2, fr2);
+ rsize = mpz_get_ui (tmp) + 2;
+ }
+#if DEBUG
+ printf ("Sieving region ["); mpz_out_str (stdout, 10, fr2);
+ printf (","); mpz_add_ui (tmp, fr2, rsize - 2);
+ mpz_out_str (stdout, 10, tmp); printf ("]\n");
+#endif
+ sieve_region (s, fr2, rsize);
+ find_primes (s, fr2, rsize / 2, siev_sqr_lim);
+
+ mpz_add_ui (fr2, fr2, S);
+ }
+ free (s);
+
+ if (flag_count)
+ printf ("Pi(interval) = %lu\n", total_primes);
+
+ if (flag_maxgap)
+ printf ("max gap: %lu\n", maxgap);
+
+ return 0;
+}
+
+/* Find primes in region [fr,fr+rsize). Requires that fr is odd and that
+ rsize is even. The sieving array s should be aligned for "long int" and
+ have rsize/2 entries, rounded up to the nearest multiple of "long int". */
+void
+sieve_region (unsigned char *s, mpz_t fr, unsigned long rsize)
+{
+ unsigned long ssize = rsize / 2;
+ unsigned long start, start2, prime;
+ unsigned long i;
+ mpz_t tmp;
+
+ mpz_init (tmp);
+
+#if 0
+ /* initialize sieving array */
+ for (ii = 0; ii < (ssize + sizeof (long) - 1) / sizeof (long); ii++)
+ ((long *) s) [ii] = ~0L;
+#else
+ {
+ long k;
+ long *se = (long *) (s + ((ssize + sizeof (long) - 1) & -sizeof (long)));
+ for (k = -((ssize + sizeof (long) - 1) / sizeof (long)); k < 0; k++)
+ se[k] = ~0L;
+ }
+#endif
+
+ for (i = 0; i < n_primes; i++)
+ {
+ prime = primes[i].prime;
+
+ if (primes[i].rem >= 0)
+ {
+ start2 = primes[i].rem;
+ }
+ else
+ {
+ mpz_set_ui (tmp, prime);
+ mpz_mul_ui (tmp, tmp, prime);
+ if (mpz_cmp (fr, tmp) <= 0)
+ {
+ mpz_sub (tmp, tmp, fr);
+ if (mpz_cmp_ui (tmp, 2 * ssize) > 0)
+ break; /* avoid overflow at next line, also speedup */
+ start = mpz_get_ui (tmp);
+ }
+ else
+ {
+ start = (prime - mpz_tdiv_ui (fr, prime)) % prime;
+ if (start % 2 != 0)
+ start += prime; /* adjust if even divisible */
+ }
+ start2 = start / 2;
+ }
+
+#if 0
+ for (ii = start2; ii < ssize; ii += prime)
+ s[ii] = 0;
+ primes[i].rem = ii - ssize;
+#else
+ {
+ long k;
+ unsigned char *se = s + ssize; /* point just beyond sieving range */
+ for (k = start2 - ssize; k < 0; k += prime)
+ se[k] = 0;
+ primes[i].rem = k;
+ }
+#endif
+ }
+ mpz_clear (tmp);
+}
+
+/* Find primes in region [fr,fr+rsize), using the previously sieved s[]. */
+void
+find_primes (unsigned char *s, mpz_t fr, unsigned long ssize,
+ mpz_t siev_sqr_lim)
+{
+ unsigned long j, ij;
+ mpz_t tmp;
+
+ mpz_init (tmp);
+ for (j = 0; j < (ssize + sizeof (long) - 1) / sizeof (long); j++)
+ {
+ if (((long *) s) [j] != 0)
+ {
+ for (ij = 0; ij < sizeof (long); ij++)
+ {
+ if (s[j * sizeof (long) + ij] != 0)
+ {
+ if (j * sizeof (long) + ij >= ssize)
+ goto out;
+ mpz_add_ui (tmp, fr, (j * sizeof (long) + ij) * 2);
+ if (mpz_cmp (tmp, siev_sqr_lim) < 0 ||
+ mpz_probab_prime_p (tmp, 10))
+ report (tmp);
+ }
+ }
+ }
+ }
+ out:
+ mpz_clear (tmp);
+}
+
+/* Generate a list of primes and store in the global array primes[]. */
+void
+make_primelist (unsigned long maxprime)
+{
+#if 1
+ unsigned char *s;
+ unsigned long ssize = maxprime / 2;
+ unsigned long i, ii, j;
+
+ s = malloc (ssize);
+ memset (s, ~0, ssize);
+ for (i = 3; ; i += 2)
+ {
+ unsigned long isqr = i * i;
+ if (isqr >= maxprime)
+ break;
+ if (s[i * i / 2 - 1] == 0)
+ continue; /* only sieve with primes */
+ for (ii = i * i / 2 - 1; ii < ssize; ii += i)
+ s[ii] = 0;
+ }
+ n_primes = 0;
+ for (j = 0; j < ssize; j++)
+ {
+ if (s[j] != 0)
+ {
+ primes[n_primes].prime = j * 2 + 3;
+ primes[n_primes].rem = -1;
+ n_primes++;
+ }
+ }
+ /* FIXME: This should not be needed if fencepost errors were fixed... */
+ if (primes[n_primes - 1].prime > maxprime)
+ n_primes--;
+ free (s);
+#else
+ unsigned long i;
+ n_primes = 0;
+ for (i = 3; i <= maxprime; i += 2)
+ {
+ if (i < 7 || (i % 3 != 0 && i % 5 != 0 && i % 7 != 0))
+ {
+ primes[n_primes].prime = i;
+ primes[n_primes].rem = -1;
+ n_primes++;
+ }
+ }
+#endif
+}
diff --git a/gmp/demos/primes.h b/gmp/demos/primes.h
new file mode 100644
index 0000000000..b85c7e1ff2
--- /dev/null
+++ b/gmp/demos/primes.h
@@ -0,0 +1,552 @@
+P( 1, 0xaaaaaaaaaaaaaaabUL, 0x5555555555555555UL) /* 3 */
+P( 2, 0xcccccccccccccccdUL, 0x3333333333333333UL) /* 5 */
+P( 2, 0x6db6db6db6db6db7UL, 0x2492492492492492UL) /* 7 */
+P( 4, 0x2e8ba2e8ba2e8ba3UL, 0x1745d1745d1745d1UL) /* 11 */
+P( 2, 0x4ec4ec4ec4ec4ec5UL, 0x13b13b13b13b13b1UL) /* 13 */
+P( 4, 0xf0f0f0f0f0f0f0f1UL, 0x0f0f0f0f0f0f0f0fUL) /* 17 */
+P( 2, 0x86bca1af286bca1bUL, 0x0d79435e50d79435UL) /* 19 */
+P( 4, 0xd37a6f4de9bd37a7UL, 0x0b21642c8590b216UL) /* 23 */
+P( 6, 0x34f72c234f72c235UL, 0x08d3dcb08d3dcb08UL) /* 29 */
+P( 2, 0xef7bdef7bdef7bdfUL, 0x0842108421084210UL) /* 31 */
+P( 6, 0x14c1bacf914c1badUL, 0x06eb3e45306eb3e4UL) /* 37 */
+P( 4, 0x8f9c18f9c18f9c19UL, 0x063e7063e7063e70UL) /* 41 */
+P( 2, 0x82fa0be82fa0be83UL, 0x05f417d05f417d05UL) /* 43 */
+P( 4, 0x51b3bea3677d46cfUL, 0x0572620ae4c415c9UL) /* 47 */
+P( 6, 0x21cfb2b78c13521dUL, 0x04d4873ecade304dUL) /* 53 */
+P( 6, 0xcbeea4e1a08ad8f3UL, 0x0456c797dd49c341UL) /* 59 */
+P( 2, 0x4fbcda3ac10c9715UL, 0x04325c53ef368eb0UL) /* 61 */
+P( 6, 0xf0b7672a07a44c6bUL, 0x03d226357e16ece5UL) /* 67 */
+P( 4, 0x193d4bb7e327a977UL, 0x039b0ad12073615aUL) /* 71 */
+P( 2, 0x7e3f1f8fc7e3f1f9UL, 0x0381c0e070381c0eUL) /* 73 */
+P( 6, 0x9b8b577e613716afUL, 0x033d91d2a2067b23UL) /* 79 */
+P( 4, 0xa3784a062b2e43dbUL, 0x03159721ed7e7534UL) /* 83 */
+P( 6, 0xf47e8fd1fa3f47e9UL, 0x02e05c0b81702e05UL) /* 89 */
+P( 8, 0xa3a0fd5c5f02a3a1UL, 0x02a3a0fd5c5f02a3UL) /* 97 */
+P( 4, 0x3a4c0a237c32b16dUL, 0x0288df0cac5b3f5dUL) /* 101 */
+P( 2, 0xdab7ec1dd3431b57UL, 0x027c45979c95204fUL) /* 103 */
+P( 4, 0x77a04c8f8d28ac43UL, 0x02647c69456217ecUL) /* 107 */
+P( 2, 0xa6c0964fda6c0965UL, 0x02593f69b02593f6UL) /* 109 */
+P( 4, 0x90fdbc090fdbc091UL, 0x0243f6f0243f6f02UL) /* 113 */
+P(14, 0x7efdfbf7efdfbf7fUL, 0x0204081020408102UL) /* 127 */
+P( 4, 0x03e88cb3c9484e2bUL, 0x01f44659e4a42715UL) /* 131 */
+P( 6, 0xe21a291c077975b9UL, 0x01de5d6e3f8868a4UL) /* 137 */
+P( 2, 0x3aef6ca970586723UL, 0x01d77b654b82c339UL) /* 139 */
+P(10, 0xdf5b0f768ce2cabdUL, 0x01b7d6c3dda338b2UL) /* 149 */
+P( 2, 0x6fe4dfc9bf937f27UL, 0x01b2036406c80d90UL) /* 151 */
+P( 6, 0x5b4fe5e92c0685b5UL, 0x01a16d3f97a4b01aUL) /* 157 */
+P( 6, 0x1f693a1c451ab30bUL, 0x01920fb49d0e228dUL) /* 163 */
+P( 4, 0x8d07aa27db35a717UL, 0x01886e5f0abb0499UL) /* 167 */
+P( 6, 0x882383b30d516325UL, 0x017ad2208e0ecc35UL) /* 173 */
+P( 6, 0xed6866f8d962ae7bUL, 0x016e1f76b4337c6cUL) /* 179 */
+P( 2, 0x3454dca410f8ed9dUL, 0x016a13cd15372904UL) /* 181 */
+P(10, 0x1d7ca632ee936f3fUL, 0x01571ed3c506b39aUL) /* 191 */
+P( 2, 0x70bf015390948f41UL, 0x015390948f40feacUL) /* 193 */
+P( 4, 0xc96bdb9d3d137e0dUL, 0x014cab88725af6e7UL) /* 197 */
+P( 2, 0x2697cc8aef46c0f7UL, 0x0149539e3b2d066eUL) /* 199 */
+P(12, 0xc0e8f2a76e68575bUL, 0x013698df3de07479UL) /* 211 */
+P(12, 0x687763dfdb43bb1fUL, 0x0125e22708092f11UL) /* 223 */
+P( 4, 0x1b10ea929ba144cbUL, 0x0120b470c67c0d88UL) /* 227 */
+P( 2, 0x1d10c4c0478bbcedUL, 0x011e2ef3b3fb8744UL) /* 229 */
+P( 4, 0x63fb9aeb1fdcd759UL, 0x0119453808ca29c0UL) /* 233 */
+P( 6, 0x64afaa4f437b2e0fUL, 0x0112358e75d30336UL) /* 239 */
+P( 2, 0xf010fef010fef011UL, 0x010fef010fef010fUL) /* 241 */
+P(10, 0x28cbfbeb9a020a33UL, 0x0105197f7d734041UL) /* 251 */
+P( 6, 0xff00ff00ff00ff01UL, 0x00ff00ff00ff00ffUL) /* 257 */
+P( 6, 0xd624fd1470e99cb7UL, 0x00f92fb2211855a8UL) /* 263 */
+P( 6, 0x8fb3ddbd6205b5c5UL, 0x00f3a0d52cba8723UL) /* 269 */
+P( 2, 0xd57da36ca27acdefUL, 0x00f1d48bcee0d399UL) /* 271 */
+P( 6, 0xee70c03b25e4463dUL, 0x00ec979118f3fc4dUL) /* 277 */
+P( 4, 0xc5b1a6b80749cb29UL, 0x00e939651fe2d8d3UL) /* 281 */
+P( 2, 0x47768073c9b97113UL, 0x00e79372e225fe30UL) /* 283 */
+P(10, 0x2591e94884ce32adUL, 0x00dfac1f74346c57UL) /* 293 */
+P(14, 0xf02806abc74be1fbUL, 0x00d578e97c3f5fe5UL) /* 307 */
+P( 4, 0x7ec3e8f3a7198487UL, 0x00d2ba083b445250UL) /* 311 */
+P( 2, 0x58550f8a39409d09UL, 0x00d161543e28e502UL) /* 313 */
+P( 4, 0xec9e48ae6f71de15UL, 0x00cebcf8bb5b4169UL) /* 317 */
+P(14, 0x2ff3a018bfce8063UL, 0x00c5fe740317f9d0UL) /* 331 */
+P( 6, 0x7f9ec3fcf61fe7b1UL, 0x00c2780613c0309eUL) /* 337 */
+P(10, 0x89f5abe570e046d3UL, 0x00bcdd535db1cc5bUL) /* 347 */
+P( 2, 0xda971b23f1545af5UL, 0x00bbc8408cd63069UL) /* 349 */
+P( 4, 0x79d5f00b9a7862a1UL, 0x00b9a7862a0ff465UL) /* 353 */
+P( 6, 0x4dba1df32a128a57UL, 0x00b68d31340e4307UL) /* 359 */
+P( 8, 0x87530217b7747d8fUL, 0x00b2927c29da5519UL) /* 367 */
+P( 6, 0x30baae53bb5e06ddUL, 0x00afb321a1496fdfUL) /* 373 */
+P( 6, 0xee70206c12e9b5b3UL, 0x00aceb0f891e6551UL) /* 379 */
+P( 4, 0xcdde9462ec9dbe7fUL, 0x00ab1cbdd3e2970fUL) /* 383 */
+P( 6, 0xafb64b05ec41cf4dUL, 0x00a87917088e262bUL) /* 389 */
+P( 8, 0x02944ff5aec02945UL, 0x00a513fd6bb00a51UL) /* 397 */
+P( 4, 0x2cb033128382df71UL, 0x00a36e71a2cb0331UL) /* 401 */
+P( 8, 0x1ccacc0c84b1c2a9UL, 0x00a03c1688732b30UL) /* 409 */
+P(10, 0x19a93db575eb3a0bUL, 0x009c69169b30446dUL) /* 419 */
+P( 2, 0xcebeef94fa86fe2dUL, 0x009baade8e4a2f6eUL) /* 421 */
+P(10, 0x6faa77fb3f8df54fUL, 0x00980e4156201301UL) /* 431 */
+P( 2, 0x68a58af00975a751UL, 0x00975a750ff68a58UL) /* 433 */
+P( 6, 0xd56e36d0c3efac07UL, 0x009548e4979e0829UL) /* 439 */
+P( 4, 0xd8b44c47a8299b73UL, 0x0093efd1c50e726bUL) /* 443 */
+P( 6, 0x02d9ccaf9ba70e41UL, 0x0091f5bcb8bb02d9UL) /* 449 */
+P( 8, 0x0985e1c023d9e879UL, 0x008f67a1e3fdc261UL) /* 457 */
+P( 4, 0x2a343316c494d305UL, 0x008e2917e0e702c6UL) /* 461 */
+P( 2, 0x70cb7916ab67652fUL, 0x008d8be33f95d715UL) /* 463 */
+P( 4, 0xd398f132fb10fe5bUL, 0x008c55841c815ed5UL) /* 467 */
+P(12, 0x6f2a38a6bf54fa1fUL, 0x0088d180cd3a4133UL) /* 479 */
+P( 8, 0x211df689b98f81d7UL, 0x00869222b1acf1ceUL) /* 487 */
+P( 4, 0x0e994983e90f1ec3UL, 0x0085797b917765abUL) /* 491 */
+P( 8, 0xad671e44bed87f3bUL, 0x008355ace3c897dbUL) /* 499 */
+P( 4, 0xf9623a0516e70fc7UL, 0x00824a4e60b3262bUL) /* 503 */
+P( 6, 0x4b7129be9dece355UL, 0x0080c121b28bd1baUL) /* 509 */
+P(12, 0x190f3b7473f62c39UL, 0x007dc9f3397d4c29UL) /* 521 */
+P( 2, 0x63dacc9aad46f9a3UL, 0x007d4ece8fe88139UL) /* 523 */
+P(18, 0xc1108fda24e8d035UL, 0x0079237d65bcce50UL) /* 541 */
+P( 6, 0xb77578472319bd8bUL, 0x0077cf53c5f7936cUL) /* 547 */
+P(10, 0x473d20a1c7ed9da5UL, 0x0075a8accfbdd11eUL) /* 557 */
+P( 6, 0xfbe85af0fea2c8fbUL, 0x007467ac557c228eUL) /* 563 */
+P( 6, 0x58a1f7e6ce0f4c09UL, 0x00732d70ed8db8e9UL) /* 569 */
+P( 2, 0x1a00e58c544986f3UL, 0x0072c62a24c3797fUL) /* 571 */
+P( 6, 0x7194a17f55a10dc1UL, 0x007194a17f55a10dUL) /* 577 */
+P(10, 0x7084944785e33763UL, 0x006fa549b41da7e7UL) /* 587 */
+P( 6, 0xba10679bd84886b1UL, 0x006e8419e6f61221UL) /* 593 */
+P( 6, 0xebe9c6bb31260967UL, 0x006d68b5356c207bUL) /* 599 */
+P( 2, 0x97a3fe4bd1ff25e9UL, 0x006d0b803685c01bUL) /* 601 */
+P( 6, 0x6c6388395b84d99fUL, 0x006bf790a8b2d207UL) /* 607 */
+P( 6, 0x8c51da6a1335df6dUL, 0x006ae907ef4b96c2UL) /* 613 */
+P( 4, 0x46f3234475d5add9UL, 0x006a37991a23aeadUL) /* 617 */
+P( 2, 0x905605ca3c619a43UL, 0x0069dfbdd4295b66UL) /* 619 */
+P(12, 0xcee8dff304767747UL, 0x0067dc4c45c8033eUL) /* 631 */
+P(10, 0xff99c27f00663d81UL, 0x00663d80ff99c27fUL) /* 641 */
+P( 2, 0xacca407f671ddc2bUL, 0x0065ec17e3559948UL) /* 643 */
+P( 4, 0xe71298bac1e12337UL, 0x00654ac835cfba5cUL) /* 647 */
+P( 6, 0xfa1e94309cd09045UL, 0x00645c854ae10772UL) /* 653 */
+P( 6, 0xbebccb8e91496b9bUL, 0x006372990e5f901fUL) /* 659 */
+P( 2, 0x312fa30cc7d7b8bdUL, 0x006325913c07beefUL) /* 661 */
+P(12, 0x6160ff9e9f006161UL, 0x006160ff9e9f0061UL) /* 673 */
+P( 4, 0x6b03673b5e28152dUL, 0x0060cdb520e5e88eUL) /* 677 */
+P( 6, 0xfe802ffa00bfe803UL, 0x005ff4017fd005ffUL) /* 683 */
+P( 8, 0xe66fe25c9e907c7bUL, 0x005ed79e31a4dccdUL) /* 691 */
+P(10, 0x3f8b236c76528895UL, 0x005d7d42d48ac5efUL) /* 701 */
+P( 8, 0xf6f923bf01ce2c0dUL, 0x005c6f35ccba5028UL) /* 709 */
+P(10, 0x6c3d3d98bed7c42fUL, 0x005b2618ec6ad0a5UL) /* 719 */
+P( 8, 0x30981efcd4b010e7UL, 0x005a2553748e42e7UL) /* 727 */
+P( 6, 0x6f691fc81ebbe575UL, 0x0059686cf744cd5bUL) /* 733 */
+P( 6, 0xb10480ddb47b52cbUL, 0x0058ae97bab79976UL) /* 739 */
+P( 4, 0x74cd59ed64f3f0d7UL, 0x0058345f1876865fUL) /* 743 */
+P( 8, 0x0105cb81316d6c0fUL, 0x005743d5bb24795aUL) /* 751 */
+P( 6, 0x9be64c6d91c1195dUL, 0x005692c4d1ab74abUL) /* 757 */
+P( 4, 0x71b3f945a27b1f49UL, 0x00561e46a4d5f337UL) /* 761 */
+P( 8, 0x77d80d50e508fd01UL, 0x005538ed06533997UL) /* 769 */
+P( 4, 0xa5eb778e133551cdUL, 0x0054c807f2c0bec2UL) /* 773 */
+P(14, 0x18657d3c2d8a3f1bUL, 0x005345efbc572d36UL) /* 787 */
+P(10, 0x2e40e220c34ad735UL, 0x00523a758f941345UL) /* 797 */
+P(12, 0xa76593c70a714919UL, 0x005102370f816c89UL) /* 809 */
+P( 2, 0x1eef452124eea383UL, 0x0050cf129fb94acfUL) /* 811 */
+P(10, 0x38206dc242ba771dUL, 0x004fd31941cafdd1UL) /* 821 */
+P( 2, 0x4cd4c35807772287UL, 0x004fa1704aa75945UL) /* 823 */
+P( 4, 0x83de917d5e69ddf3UL, 0x004f3ed6d45a63adUL) /* 827 */
+P( 2, 0x882ef0403b4a6c15UL, 0x004f0de57154ebedUL) /* 829 */
+P(10, 0xf8fb6c51c606b677UL, 0x004e1cae8815f811UL) /* 839 */
+P(14, 0xb4abaac446d3e1fdUL, 0x004cd47ba5f6ff19UL) /* 853 */
+P( 4, 0xa9f83bbe484a14e9UL, 0x004c78ae734df709UL) /* 857 */
+P( 2, 0x0bebbc0d1ce874d3UL, 0x004c4b19ed85cfb8UL) /* 859 */
+P( 4, 0xbd418eaf0473189fUL, 0x004bf093221d1218UL) /* 863 */
+P(14, 0x44e3af6f372b7e65UL, 0x004aba3c21dc633fUL) /* 877 */
+P( 4, 0xc87fdace4f9e5d91UL, 0x004a6360c344de00UL) /* 881 */
+P( 2, 0xec93479c446bd9bbUL, 0x004a383e9f74d68aUL) /* 883 */
+P( 4, 0xdac4d592e777c647UL, 0x0049e28fbabb9940UL) /* 887 */
+P(20, 0xa63ea8c8f61f0c23UL, 0x0048417b57c78cd7UL) /* 907 */
+P( 4, 0xe476062ea5cbbb6fUL, 0x0047f043713f3a2bUL) /* 911 */
+P( 8, 0xdf68761c69daac27UL, 0x00474ff2a10281cfUL) /* 919 */
+P(10, 0xb813d737637aa061UL, 0x00468b6f9a978f91UL) /* 929 */
+P( 8, 0xa3a77aac1fb15099UL, 0x0045f13f1caff2e2UL) /* 937 */
+P( 4, 0x17f0c3e0712c5825UL, 0x0045a5228cec23e9UL) /* 941 */
+P( 6, 0xfd912a70ff30637bUL, 0x0045342c556c66b9UL) /* 947 */
+P( 6, 0xfbb3b5dc01131289UL, 0x0044c4a23feeced7UL) /* 953 */
+P(14, 0x856d560a0f5acdf7UL, 0x0043c5c20d3c9fe6UL) /* 967 */
+P( 4, 0x96472f314d3f89e3UL, 0x00437e494b239798UL) /* 971 */
+P( 6, 0xa76f5c7ed2253531UL, 0x0043142d118e47cbUL) /* 977 */
+P( 6, 0x816eae7c7bf69fe7UL, 0x0042ab5c73a13458UL) /* 983 */
+P( 8, 0xb6a2bea4cfb1781fUL, 0x004221950db0f3dbUL) /* 991 */
+P( 6, 0xa3900c53318e81edUL, 0x0041bbb2f80a4553UL) /* 997 */
+P(12, 0x60aa7f5d9f148d11UL, 0x0040f391612c6680UL) /* 1009 */
+P( 4, 0x6be8c0102c7a505dUL, 0x0040b1e94173fefdUL) /* 1013 */
+P( 6, 0x8ff3f0ed28728f33UL, 0x004050647d9d0445UL) /* 1019 */
+P( 2, 0x680e0a87e5ec7155UL, 0x004030241b144f3bUL) /* 1021 */
+P(10, 0xbbf70fa49fe829b7UL, 0x003f90c2ab542cb1UL) /* 1031 */
+P( 2, 0xd69d1e7b6a50ca39UL, 0x003f71412d59f597UL) /* 1033 */
+P( 6, 0x1a1e0f46b6d26aefUL, 0x003f137701b98841UL) /* 1039 */
+P(10, 0x7429f9a7a8251829UL, 0x003e79886b60e278UL) /* 1049 */
+P( 2, 0xd9c2219d1b863613UL, 0x003e5b1916a7181dUL) /* 1051 */
+P(10, 0x91406c1820d077adUL, 0x003dc4a50968f524UL) /* 1061 */
+P( 2, 0x521f4ec02e3d2b97UL, 0x003da6e4c9550321UL) /* 1063 */
+P( 6, 0xbb8283b63dc8eba5UL, 0x003d4e4f06f1def3UL) /* 1069 */
+P(18, 0x431eda153229ebbfUL, 0x003c4a6bdd24f9a4UL) /* 1087 */
+P( 4, 0xaf0bf78d7e01686bUL, 0x003c11d54b525c73UL) /* 1091 */
+P( 2, 0xa9ced0742c086e8dUL, 0x003bf5b1c5721065UL) /* 1093 */
+P( 4, 0xc26458ad9f632df9UL, 0x003bbdb9862f23b4UL) /* 1097 */
+P( 6, 0xbbff1255dff892afUL, 0x003b6a8801db5440UL) /* 1103 */
+P( 6, 0xcbd49a333f04d8fdUL, 0x003b183cf0fed886UL) /* 1109 */
+P( 8, 0xec84ed6f9cfdeff5UL, 0x003aabe394bdc3f4UL) /* 1117 */
+P( 6, 0x97980cc40bda9d4bUL, 0x003a5ba3e76156daUL) /* 1123 */
+P( 6, 0x777f34d524f5cbd9UL, 0x003a0c3e953378dbUL) /* 1129 */
+P(22, 0x2797051d94cbbb7fUL, 0x0038f03561320b1eUL) /* 1151 */
+P( 2, 0xea769051b4f43b81UL, 0x0038d6ecaef5908aUL) /* 1153 */
+P(10, 0xce7910f3034d4323UL, 0x003859cf221e6069UL) /* 1163 */
+P( 8, 0x92791d1374f5b99bUL, 0x0037f7415dc9588aUL) /* 1171 */
+P(10, 0x89a5645cc68ea1b5UL, 0x00377df0d3902626UL) /* 1181 */
+P( 6, 0x5f8aacf796c0cf0bUL, 0x00373622136907faUL) /* 1187 */
+P( 6, 0xf2e90a15e33edf99UL, 0x0036ef0c3b39b92fUL) /* 1193 */
+P( 8, 0x8e99e5feb897c451UL, 0x0036915f47d55e6dUL) /* 1201 */
+P(12, 0xaca2eda38fb91695UL, 0x0036072cf3f866fdUL) /* 1213 */
+P( 4, 0x5d9b737be5ea8b41UL, 0x0035d9b737be5ea8UL) /* 1217 */
+P( 6, 0x4aefe1db93fd7cf7UL, 0x0035961559cc81c7UL) /* 1223 */
+P( 6, 0xa0994ef20b3f8805UL, 0x0035531c897a4592UL) /* 1229 */
+P( 2, 0x103890bda912822fUL, 0x00353ceebd3e98a4UL) /* 1231 */
+P( 6, 0xb441659d13a9147dUL, 0x0034fad381585e5eUL) /* 1237 */
+P(12, 0x1e2134440c4c3f21UL, 0x00347884d1103130UL) /* 1249 */
+P(10, 0x263a27727a6883c3UL, 0x00340dd3ac39bf56UL) /* 1259 */
+P(18, 0x78e221472ab33855UL, 0x003351fdfecc140cUL) /* 1277 */
+P( 2, 0x95eac88e82e6faffUL, 0x00333d72b089b524UL) /* 1279 */
+P( 4, 0xf66c258317be8dabUL, 0x0033148d44d6b261UL) /* 1283 */
+P( 6, 0x09ee202c7cb91939UL, 0x0032d7aef8412458UL) /* 1289 */
+P( 2, 0x8d2fca1042a09ea3UL, 0x0032c3850e79c0f1UL) /* 1291 */
+P( 6, 0x82779c856d8b8bf1UL, 0x00328766d59048a2UL) /* 1297 */
+P( 4, 0x3879361cba8a223dUL, 0x00325fa18cb11833UL) /* 1301 */
+P( 2, 0xf23f43639c3182a7UL, 0x00324bd659327e22UL) /* 1303 */
+P( 4, 0xa03868fc474bcd13UL, 0x0032246e784360f4UL) /* 1307 */
+P(12, 0x651e78b8c5311a97UL, 0x0031afa5f1a33a08UL) /* 1319 */
+P( 2, 0x8ffce639c00c6719UL, 0x00319c63ff398e70UL) /* 1321 */
+P( 6, 0xf7b460754b0b61cfUL, 0x003162f7519a86a7UL) /* 1327 */
+P(34, 0x7b03f3359b8e63b1UL, 0x0030271fc9d3fc3cUL) /* 1361 */
+P( 6, 0xa55c5326041eb667UL, 0x002ff104ae89750bUL) /* 1367 */
+P( 6, 0x647f88ab896a76f5UL, 0x002fbb62a236d133UL) /* 1373 */
+P( 8, 0x8fd971434a55a46dUL, 0x002f74997d2070b4UL) /* 1381 */
+P(18, 0x9fbf969958046447UL, 0x002ed84aa8b6fce3UL) /* 1399 */
+P(10, 0x9986feba69be3a81UL, 0x002e832df7a46dbdUL) /* 1409 */
+P(14, 0xa668b3e6d053796fUL, 0x002e0e0846857cabUL) /* 1423 */
+P( 4, 0x97694e6589f4e09bUL, 0x002decfbdfb55ee6UL) /* 1427 */
+P( 2, 0x37890c00b7721dbdUL, 0x002ddc876f3ff488UL) /* 1429 */
+P( 4, 0x5ac094a235f37ea9UL, 0x002dbbc1d4c482c4UL) /* 1433 */
+P( 6, 0x31cff775f2d5d65fUL, 0x002d8af0e0de0556UL) /* 1439 */
+P( 8, 0xddad8e6b36505217UL, 0x002d4a7b7d14b30aUL) /* 1447 */
+P( 4, 0x5a27df897062cd03UL, 0x002d2a85073bcf4eUL) /* 1451 */
+P( 2, 0xe2396fe0fdb5a625UL, 0x002d1a9ab13e8be4UL) /* 1453 */
+P( 6, 0xb352a4957e82317bUL, 0x002ceb1eb4b9fd8bUL) /* 1459 */
+P(12, 0xd8ab3f2c60c2ea3fUL, 0x002c8d503a79794cUL) /* 1471 */
+P(10, 0x6893f702f0452479UL, 0x002c404d708784edUL) /* 1481 */
+P( 2, 0x9686fdc182acf7e3UL, 0x002c31066315ec52UL) /* 1483 */
+P( 4, 0x6854037173dce12fUL, 0x002c1297d80f2664UL) /* 1487 */
+P( 2, 0x7f0ded1685c27331UL, 0x002c037044c55f6bUL) /* 1489 */
+P( 4, 0xeeda72e1fe490b7dUL, 0x002be5404cd13086UL) /* 1493 */
+P( 6, 0x9e7bfc959a8e6e53UL, 0x002bb845adaf0cceUL) /* 1499 */
+P(12, 0x49b314d6d4753dd7UL, 0x002b5f62c639f16dUL) /* 1511 */
+P(12, 0x2e8f8c5ac4aa1b3bUL, 0x002b07e6734f2b88UL) /* 1523 */
+P( 8, 0xb8ef723481163d33UL, 0x002ace569d8342b7UL) /* 1531 */
+P(12, 0x6a2ec96a594287b7UL, 0x002a791d5dbd4dcfUL) /* 1543 */
+P( 6, 0xdba41c6d13aab8c5UL, 0x002a4eff8113017cUL) /* 1549 */
+P( 4, 0xc2adbe648dc3aaf1UL, 0x002a3319e156df32UL) /* 1553 */
+P( 6, 0x87a2bade565f91a7UL, 0x002a0986286526eaUL) /* 1559 */
+P( 8, 0x4d6fe8798c01f5dfUL, 0x0029d29551d91e39UL) /* 1567 */
+P( 4, 0x3791310c8c23d98bUL, 0x0029b7529e109f0aUL) /* 1571 */
+P( 8, 0xf80e446b01228883UL, 0x00298137491ea465UL) /* 1579 */
+P( 4, 0x9aed1436fbf500cfUL, 0x0029665e1eb9f9daUL) /* 1583 */
+P(14, 0x7839b54cc8b24115UL, 0x002909752e019a5eUL) /* 1597 */
+P( 4, 0xc128c646ad0309c1UL, 0x0028ef35e2e5efb0UL) /* 1601 */
+P( 6, 0x14de631624a3c377UL, 0x0028c815aa4b8278UL) /* 1607 */
+P( 2, 0x3f7b9fe68b0ecbf9UL, 0x0028bb1b867199daUL) /* 1609 */
+P( 4, 0x284ffd75ec00a285UL, 0x0028a13ff5d7b002UL) /* 1613 */
+P( 6, 0x37803cb80dea2ddbUL, 0x00287ab3f173e755UL) /* 1619 */
+P( 2, 0x86b63f7c9ac4c6fdUL, 0x00286dead67713bdUL) /* 1621 */
+P( 6, 0x8b6851d1bd99b9d3UL, 0x002847bfcda6503eUL) /* 1627 */
+P(10, 0xb62fda77ca343b6dUL, 0x002808c1ea6b4777UL) /* 1637 */
+P(20, 0x1f0dc009e34383c9UL, 0x00278d0e0f23ff61UL) /* 1657 */
+P( 6, 0x496dc21ddd35b97fUL, 0x002768863c093c7fUL) /* 1663 */
+P( 4, 0xb0e96ce17090f82bUL, 0x0027505115a73ca8UL) /* 1667 */
+P( 2, 0xaadf05acdd7d024dUL, 0x00274441a61dc1b9UL) /* 1669 */
+P(24, 0xcb138196746eafb5UL, 0x0026b5c166113cf0UL) /* 1693 */
+P( 4, 0x347f523736755d61UL, 0x00269e65ad07b18eUL) /* 1697 */
+P( 2, 0xd14a48a051f7dd0bUL, 0x002692c25f877560UL) /* 1699 */
+P(10, 0x474d71b1ce914d25UL, 0x002658fa7523cd11UL) /* 1709 */
+P(12, 0x386063f5e28c1f89UL, 0x0026148710cf0f9eUL) /* 1721 */
+P( 2, 0x1db7325e32d04e73UL, 0x002609363b22524fUL) /* 1723 */
+P(10, 0xfef748d3893b880dUL, 0x0025d1065a1c1122UL) /* 1733 */
+P( 8, 0x2f3351506e935605UL, 0x0025a48a382b863fUL) /* 1741 */
+P( 6, 0x7a3637fa2376415bUL, 0x0025837190eccdbcUL) /* 1747 */
+P( 6, 0x4ac525d2baa21969UL, 0x00256292e95d510cUL) /* 1753 */
+P( 6, 0x3a11c16b42cd351fUL, 0x002541eda98d068cUL) /* 1759 */
+P(18, 0x6c7abde0049c2a11UL, 0x0024e15087fed8f5UL) /* 1777 */
+P( 6, 0x54dad0303e069ac7UL, 0x0024c18b20979e5dUL) /* 1783 */
+P( 4, 0xebf1ac9fdfe91433UL, 0x0024ac7b336de0c5UL) /* 1787 */
+P( 2, 0xfafdda8237cec655UL, 0x0024a1fc478c60bbUL) /* 1789 */
+P(12, 0xdce3ff6e71ffb739UL, 0x002463801231c009UL) /* 1801 */
+P(10, 0xbed5737d6286db1bUL, 0x0024300fd506ed33UL) /* 1811 */
+P(12, 0xe479e431fe08b4dfUL, 0x0023f314a494da81UL) /* 1823 */
+P( 8, 0x9dd9b0dd7742f897UL, 0x0023cadedd2fad3aUL) /* 1831 */
+P(16, 0x8f09d7402c5a5e87UL, 0x00237b7ed2664a03UL) /* 1847 */
+P(14, 0x9216d5c4d958738dUL, 0x0023372967dbaf1dUL) /* 1861 */
+P( 6, 0xb3139ba11d34ca63UL, 0x00231a308a371f20UL) /* 1867 */
+P( 4, 0x47d54f7ed644afafUL, 0x002306fa63e1e600UL) /* 1871 */
+P( 2, 0x92a81d85cf11a1b1UL, 0x0022fd6731575684UL) /* 1873 */
+P( 4, 0x754b26533253bdfdUL, 0x0022ea507805749cUL) /* 1877 */
+P( 2, 0xbbe0efc980bfd467UL, 0x0022e0cce8b3d720UL) /* 1879 */
+P(10, 0xc0d8d594f024dca1UL, 0x0022b1887857d161UL) /* 1889 */
+P(12, 0x8238d43bcaac1a65UL, 0x00227977fcc49cc0UL) /* 1901 */
+P( 6, 0x27779c1fae6175bbUL, 0x00225db37b5e5f4fUL) /* 1907 */
+P( 6, 0xa746ca9af708b2c9UL, 0x0022421b91322ed6UL) /* 1913 */
+P(18, 0x93f3cd9f389be823UL, 0x0021f05b35f52102UL) /* 1931 */
+P( 2, 0x5cb4a4c04c489345UL, 0x0021e75de5c70d60UL) /* 1933 */
+P(16, 0xbf6047743e85b6b5UL, 0x0021a01d6c19be96UL) /* 1949 */
+P( 2, 0x61c147831563545fUL, 0x0021974a6615c81aUL) /* 1951 */
+P(22, 0xedb47c0ae62dee9dUL, 0x00213767697cf36aUL) /* 1973 */
+P( 6, 0x0a3824386673a573UL, 0x00211d9f7fad35f1UL) /* 1979 */
+P( 8, 0xa4a77d19e575a0ebUL, 0x0020fb7d9dd36c18UL) /* 1987 */
+P( 6, 0xa2bee045e066c279UL, 0x0020e2123d661e0eUL) /* 1993 */
+P( 4, 0xc23618de8ab43d05UL, 0x0020d135b66ae990UL) /* 1997 */
+P( 2, 0x266b515216cb9f2fUL, 0x0020c8cded4d7a8eUL) /* 1999 */
+P( 4, 0xe279edd9e9c2e85bUL, 0x0020b80b3f43ddbfUL) /* 2003 */
+P( 8, 0xd0c591c221dc9c53UL, 0x002096b9180f46a6UL) /* 2011 */
+P( 6, 0x06da8ee9c9ee7c21UL, 0x00207de7e28de5daUL) /* 2017 */
+P(10, 0x9dfebcaf4c27e8c3UL, 0x002054dec8cf1fb3UL) /* 2027 */
+P( 2, 0x49aeff9f19dd6de5UL, 0x00204cb630b3aab5UL) /* 2029 */
+P(10, 0x86976a57a296e9c7UL, 0x00202428adc37bebUL) /* 2039 */
+P(14, 0xa3b9abf4872b84cdUL, 0x001fec0c7834def4UL) /* 2053 */
+P(10, 0x34fca6483895e6efUL, 0x001fc46fae98a1d0UL) /* 2063 */
+P( 6, 0x34b5a333988f873dUL, 0x001facda430ff619UL) /* 2069 */
+P(12, 0xd9dd4f19b5f17be1UL, 0x001f7e17dd8e15e5UL) /* 2081 */
+P( 2, 0xb935b507fd0ce78bUL, 0x001f765a3556a4eeUL) /* 2083 */
+P( 4, 0xb450f5540660e797UL, 0x001f66ea49d802f1UL) /* 2087 */
+P( 2, 0x63ff82831ffc1419UL, 0x001f5f3800faf9c0UL) /* 2089 */
+P(10, 0x8992f718c22a32fbUL, 0x001f38f4e6c0f1f9UL) /* 2099 */
+P(12, 0x5f3253ad0d37e7bfUL, 0x001f0b8546752578UL) /* 2111 */
+P( 2, 0x007c0ffe0fc007c1UL, 0x001f03ff83f001f0UL) /* 2113 */
+P(16, 0x4d8ebadc0c0640b1UL, 0x001ec853b0a3883cUL) /* 2129 */
+P( 2, 0xe2729af831037bdbUL, 0x001ec0ee573723ebUL) /* 2131 */
+P( 6, 0xb8f64bf30feebfe9UL, 0x001eaad38e6f6894UL) /* 2137 */
+P( 4, 0xda93124b544c0bf5UL, 0x001e9c28a765fe53UL) /* 2141 */
+P( 2, 0x9cf7ff0b593c539fUL, 0x001e94d8758c2003UL) /* 2143 */
+P(10, 0xd6bd8861fa0e07d9UL, 0x001e707ba8f65e68UL) /* 2153 */
+P( 8, 0x5cfe75c0bd8ab891UL, 0x001e53a2a68f574eUL) /* 2161 */
+P(18, 0x43e808757c2e862bUL, 0x001e1380a56b438dUL) /* 2179 */
+P(24, 0x90caa96d595c9d93UL, 0x001dbf9f513a3802UL) /* 2203 */
+P( 4, 0x8fd550625d07135fUL, 0x001db1d1d58bc600UL) /* 2207 */
+P( 6, 0x76b010a86e209f2dUL, 0x001d9d358f53de38UL) /* 2213 */
+P( 8, 0xecc0426447769b25UL, 0x001d81e6df6165c7UL) /* 2221 */
+P(16, 0xe381339caabe3295UL, 0x001d4bdf7fd40e30UL) /* 2237 */
+P( 2, 0xd1b190a2d0c7673fUL, 0x001d452c7a1c958dUL) /* 2239 */
+P( 4, 0xc3bce3cf26b0e7ebUL, 0x001d37cf9b902659UL) /* 2243 */
+P( 8, 0x5f87e76f56c61ce3UL, 0x001d1d3a5791e97bUL) /* 2251 */
+P(16, 0xc06c6857a124b353UL, 0x001ce89fe6b47416UL) /* 2267 */
+P( 2, 0x38c040fcba630f75UL, 0x001ce219f3235071UL) /* 2269 */
+P( 4, 0xd078bc4fbd533b21UL, 0x001cd516dcf92139UL) /* 2273 */
+P( 8, 0xde8e15c5dd354f59UL, 0x001cbb33bd1c2b8bUL) /* 2281 */
+P( 6, 0xca61d53d7414260fUL, 0x001ca7e7d2546688UL) /* 2287 */
+P( 6, 0xb56bf5ba8eae635dUL, 0x001c94b5c1b3dbd3UL) /* 2293 */
+P( 4, 0x44a72cb0fb6e3949UL, 0x001c87f7f9c241c1UL) /* 2297 */
+P(12, 0x879839a714f45bcdUL, 0x001c6202706c35a9UL) /* 2309 */
+P( 2, 0x02a8994fde5314b7UL, 0x001c5bb8a9437632UL) /* 2311 */
+P(22, 0xb971920cf2b90135UL, 0x001c174343b4111eUL) /* 2333 */
+P( 6, 0x8a8fd0b7df9a6e8bUL, 0x001c04d0d3e46b42UL) /* 2339 */
+P( 2, 0xb31f9a84c1c6eaadUL, 0x001bfeb00fbf4308UL) /* 2341 */
+P( 6, 0x92293b02823c6d83UL, 0x001bec5dce0b202dUL) /* 2347 */
+P( 4, 0xeee77ff20fe5ddcfUL, 0x001be03444620037UL) /* 2351 */
+P( 6, 0x0e1ea0f6c496c11dUL, 0x001bce09c66f6fc3UL) /* 2357 */
+P(14, 0xfdf2d3d6f88ccb6bUL, 0x001ba40228d02b30UL) /* 2371 */
+P( 6, 0xfa9d74a3457738f9UL, 0x001b9225b1cf8919UL) /* 2377 */
+P( 4, 0xefc3ca3db71a5785UL, 0x001b864a2ff3f53fUL) /* 2381 */
+P( 2, 0x8e2071718d0d6dafUL, 0x001b80604150e49bUL) /* 2383 */
+P( 6, 0xbc0fdbfeb6cfabfdUL, 0x001b6eb1aaeaacf3UL) /* 2389 */
+P( 4, 0x1eeab613e5e5aee9UL, 0x001b62f48da3c8ccUL) /* 2393 */
+P( 6, 0x2d2388e90e9e929fUL, 0x001b516babe96092UL) /* 2399 */
+P(12, 0x81dbafba588ddb43UL, 0x001b2e9cef1e0c87UL) /* 2411 */
+P( 6, 0x52eebc51c4799791UL, 0x001b1d56bedc849bUL) /* 2417 */
+P( 6, 0x1c6bc4693b45a047UL, 0x001b0c267546aec0UL) /* 2423 */
+P(14, 0x06eee0974498874dUL, 0x001ae45f62024fa0UL) /* 2437 */
+P( 4, 0xd85b7377a9953cb9UL, 0x001ad917631b5f54UL) /* 2441 */
+P( 6, 0x4b6df412d4caf56fUL, 0x001ac83d18cb608fUL) /* 2447 */
+P(12, 0x6b8afbbb4a053493UL, 0x001aa6c7ad8c063fUL) /* 2459 */
+P( 8, 0xcc5299c96ac7720bUL, 0x001a90a7b1228e2aUL) /* 2467 */
+P( 6, 0xadce84b5c710aa99UL, 0x001a8027c03ba059UL) /* 2473 */
+P( 4, 0x9d673f5aa3804225UL, 0x001a7533289deb89UL) /* 2477 */
+P(26, 0xe6541268efbce7f7UL, 0x001a2ed7ce16b49fUL) /* 2503 */
+P(18, 0xfcf41e76cf5be669UL, 0x0019fefc0a279a73UL) /* 2521 */
+P(10, 0x5c3eb5dc31c383cbUL, 0x0019e4b0cd873b5fUL) /* 2531 */
+P( 8, 0x301832d11d8ad6c3UL, 0x0019cfcdfd60e514UL) /* 2539 */
+P( 4, 0x2e9c0942f1ce450fUL, 0x0019c56932d66c85UL) /* 2543 */
+P( 6, 0x97f3f2be37a39a5dUL, 0x0019b5e1ab6fc7c2UL) /* 2549 */
+P( 2, 0xe8b7d8a9654187c7UL, 0x0019b0b8a62f2a73UL) /* 2551 */
+P( 6, 0xb5d024d7da5b1b55UL, 0x0019a149fc98942cUL) /* 2557 */
+P(22, 0xb8ba9d6e7ae3501bUL, 0x001969517ec25b85UL) /* 2579 */
+P(12, 0xf50865f71b90f1dfUL, 0x00194b3083360ba8UL) /* 2591 */
+P( 2, 0x739c1682847df9e1UL, 0x00194631f4bebdc1UL) /* 2593 */
+P(16, 0xc470a4d842b90ed1UL, 0x00191e84127268fdUL) /* 2609 */
+P( 8, 0x1fb1be11698cc409UL, 0x00190adbb543984fUL) /* 2617 */
+P( 4, 0xd8d5512a7cd35d15UL, 0x001901130bd18200UL) /* 2621 */
+P(12, 0xa5496821723e07f9UL, 0x0018e3e6b889ac94UL) /* 2633 */
+P(14, 0xbcc8c6d7abaa8167UL, 0x0018c233420e1ec1UL) /* 2647 */
+P(10, 0x52c396c95eb619a1UL, 0x0018aa5872d92bd6UL) /* 2657 */
+P( 2, 0x6eb7e380878ec74bUL, 0x0018a5989945ccf9UL) /* 2659 */
+P( 4, 0x3d5513b504537157UL, 0x00189c1e60b57f60UL) /* 2663 */
+P( 8, 0x314391f8862e948fUL, 0x0018893fbc8690b9UL) /* 2671 */
+P( 6, 0xdc0b17cfcd81f5ddUL, 0x00187b2bb3e1041cUL) /* 2677 */
+P( 6, 0x2f6bea3ec89044b3UL, 0x00186d27c9cdcfb8UL) /* 2683 */
+P( 4, 0xce13a05869f1b57fUL, 0x001863d8bf4f2c1cUL) /* 2687 */
+P( 2, 0x7593474e8ace3581UL, 0x00185f33e2ad7593UL) /* 2689 */
+P( 4, 0x07fc329295a05e4dUL, 0x001855ef75973e13UL) /* 2693 */
+P( 6, 0xb05377cba4908d23UL, 0x001848160153f134UL) /* 2699 */
+P( 8, 0xe7b2131a628aa39bUL, 0x001835b72e6f0656UL) /* 2707 */
+P( 4, 0x9031dbed7de01527UL, 0x00182c922d83eb39UL) /* 2711 */
+P( 2, 0x76844b1c670aa9a9UL, 0x0018280243c0365aUL) /* 2713 */
+P( 6, 0x6a03f4533b08915fUL, 0x00181a5cd5898e73UL) /* 2719 */
+P(10, 0x1dbca579db0a3999UL, 0x001803c0961773aaUL) /* 2729 */
+P( 2, 0x002ffe800bffa003UL, 0x0017ff4005ffd001UL) /* 2731 */
+P(10, 0x478ab1a3e936139dUL, 0x0017e8d670433edbUL) /* 2741 */
+P( 8, 0x66e722bc4c5cc095UL, 0x0017d7066cf4bb5dUL) /* 2749 */
+P( 4, 0x7a8f63c717278541UL, 0x0017ce285b806b1fUL) /* 2753 */
+P(14, 0xdf6eee24d292bc2fUL, 0x0017af52cdf27e02UL) /* 2767 */
+P(10, 0x9fc20d17237dd569UL, 0x0017997d47d01039UL) /* 2777 */
+P(12, 0xcdf9932356bda2edUL, 0x00177f7ec2c6d0baUL) /* 2789 */
+P( 2, 0x97b5e332e80f68d7UL, 0x00177b2f3cd00756UL) /* 2791 */
+P( 6, 0x46eee26fd875e2e5UL, 0x00176e4a22f692a0UL) /* 2797 */
+P( 4, 0x3548a8e65157a611UL, 0x001765b94271e11bUL) /* 2801 */
+P( 2, 0xc288d03be9b71e3bUL, 0x001761732b044ae4UL) /* 2803 */
+P(16, 0x8151186db38937abUL, 0x00173f7a5300a2bcUL) /* 2819 */
+P(14, 0x7800b910895a45f1UL, 0x001722112b48be1fUL) /* 2833 */
+P( 4, 0xaee0b024182eec3dUL, 0x001719b7a16eb843UL) /* 2837 */
+P( 6, 0x96323eda173b5713UL, 0x00170d3c99cc5052UL) /* 2843 */
+P( 8, 0x0ed0dbd03ae77c8bUL, 0x0016fcad7aed3bb6UL) /* 2851 */
+P( 6, 0xf73800b7828dc119UL, 0x0016f051b8231ffdUL) /* 2857 */
+P( 4, 0x1b61715ec22b7ca5UL, 0x0016e81beae20643UL) /* 2861 */
+P(18, 0xa8533a991ead64bfUL, 0x0016c3721584c1d8UL) /* 2879 */
+P( 8, 0x7f6c7290e46c2e77UL, 0x0016b34c2ba09663UL) /* 2887 */
+P(10, 0x6325e8d907b01db1UL, 0x00169f3ce292ddcdUL) /* 2897 */
+P( 6, 0x28909f70152a1067UL, 0x00169344b2220a0dUL) /* 2903 */
+P( 6, 0xea7077af0997a0f5UL, 0x001687592593c1b1UL) /* 2909 */
+P( 8, 0x7e605cad10c32e6dUL, 0x00167787f1418ec9UL) /* 2917 */
+P(10, 0x471b33570635b38fUL, 0x001663e190395ff2UL) /* 2927 */
+P(12, 0xab559fa997a61bb3UL, 0x00164c7a4b6eb5b3UL) /* 2939 */
+P(14, 0xad4bdae562bddab9UL, 0x0016316a061182fdUL) /* 2953 */
+P( 4, 0x055e1b2f2ed62f45UL, 0x001629ba914584e4UL) /* 2957 */
+P( 6, 0x03cd328b1a2dca9bUL, 0x00161e3d57de21b2UL) /* 2963 */
+P( 6, 0xd28f4e08733218a9UL, 0x001612cc01b977f0UL) /* 2969 */
+P( 2, 0xb6800b077f186293UL, 0x00160efe30c525ffUL) /* 2971 */
+P(28, 0x6fbd138c3fd9c207UL, 0x0015da45249ec5deUL) /* 2999 */
+P( 2, 0xb117ccd12ae88a89UL, 0x0015d68ab4acff92UL) /* 3001 */
+P(10, 0x2f1a1a044046bcebUL, 0x0015c3f989d1eb15UL) /* 3011 */
+P( 8, 0x548aba0b060541e3UL, 0x0015b535ad11b8f0UL) /* 3019 */
+P( 4, 0xcf4e808cea111b2fUL, 0x0015addb3f424ec1UL) /* 3023 */
+P(14, 0xdbec1b4fa855a475UL, 0x00159445cb91be6bUL) /* 3037 */
+P( 4, 0xe3f794eb600d7821UL, 0x00158d0199771e63UL) /* 3041 */
+P( 8, 0x34fae0d9a11f7c59UL, 0x00157e87d9b69e04UL) /* 3049 */
+P(12, 0xf006b0ccbbac085dUL, 0x001568f58bc01ac3UL) /* 3061 */
+P( 6, 0x3f45076dc3114733UL, 0x00155e3c993fda9bUL) /* 3067 */
+P(12, 0xeef49bfa58a1a1b7UL, 0x001548eacc5e1e6eUL) /* 3079 */
+P( 4, 0x12c4218bea691fa3UL, 0x001541d8f91ba6a7UL) /* 3083 */
+P( 6, 0xbc7504e3bd5e64f1UL, 0x00153747060cc340UL) /* 3089 */
+P(20, 0x4ee21c292bb92fadUL, 0x001514569f93f7c4UL) /* 3109 */
+P(10, 0x34338b7327a4bacfUL, 0x00150309705d3d79UL) /* 3119 */
+P( 2, 0x3fe5c0833d6fccd1UL, 0x0014ff97020cf5bfUL) /* 3121 */
+P(16, 0xb1e70743535203c1UL, 0x0014e42c114cf47eUL) /* 3137 */
+P(26, 0xefbb5dcdfb4e43d3UL, 0x0014b835bdcb6447UL) /* 3163 */
+P( 4, 0xca68467ca5394f9fUL, 0x0014b182b53a9ab7UL) /* 3167 */
+P( 2, 0x8c51c081408b97a1UL, 0x0014ae2ad094a3d3UL) /* 3169 */
+P(12, 0x3275a899dfa5dd65UL, 0x00149a320ea59f96UL) /* 3181 */
+P( 6, 0x9e674cb62e1b78bbUL, 0x001490441de1a2fbUL) /* 3187 */
+P( 4, 0xa37ff5bb2a998d47UL, 0x001489aacce57200UL) /* 3191 */
+P(12, 0x792a999db131a22bUL, 0x001475f82ad6ff99UL) /* 3203 */
+P( 6, 0x1b48841bc30d29b9UL, 0x00146c2cfe53204fUL) /* 3209 */
+P( 8, 0xf06721d2011d3471UL, 0x00145f2ca490d4a1UL) /* 3217 */
+P( 4, 0x93fd2386dff85ebdUL, 0x001458b2aae0ec87UL) /* 3221 */
+P( 8, 0x4ce72f54c07ed9b5UL, 0x00144bcb0a3a3150UL) /* 3229 */
+P(22, 0xd6d0fd3e71dd827bUL, 0x001428a1e65441d4UL) /* 3251 */
+P( 2, 0x856405fb1eed819dUL, 0x00142575a6c210d7UL) /* 3253 */
+P( 4, 0x8ea8aceb7c443989UL, 0x00141f2025ba5c46UL) /* 3257 */
+P( 2, 0x34a13026f62e5873UL, 0x00141bf6e35420fdUL) /* 3259 */
+P(12, 0x1eea0208ec0af4f7UL, 0x001409141d1d313aUL) /* 3271 */
+P(28, 0x63679853cea598cbUL, 0x0013dd8bc19c3513UL) /* 3299 */
+P( 2, 0xc30b3ebd61f2d0edUL, 0x0013da76f714dc8fUL) /* 3301 */
+P( 6, 0x7eb9037bc7f43bc3UL, 0x0013d13e50f8f49eUL) /* 3307 */
+P( 6, 0xa583e6f6ce016411UL, 0x0013c80e37ca3819UL) /* 3313 */
+P( 6, 0xf1938d895f1a74c7UL, 0x0013bee69fa99ccfUL) /* 3319 */
+P( 4, 0x80cf1491c1e81e33UL, 0x0013b8d0ede55835UL) /* 3323 */
+P( 6, 0x3c0f12886ba8f301UL, 0x0013afb7680bb054UL) /* 3329 */
+P( 2, 0x0e4b786e0dfcc5abUL, 0x0013acb0c3841c96UL) /* 3331 */
+P(12, 0x672684c93f2d41efUL, 0x00139a9c5f434fdeUL) /* 3343 */
+P( 4, 0xe00757badb35c51bUL, 0x0013949cf33a0d9dUL) /* 3347 */
+P(12, 0xd6d84afe66472edfUL, 0x001382b4a00c31b0UL) /* 3359 */
+P( 2, 0xfbbc0eedcbbfb6e1UL, 0x00137fbbc0eedcbbUL) /* 3361 */
+P(10, 0x250f43aa08a84983UL, 0x001370ecf047b069UL) /* 3371 */
+P( 2, 0x04400e927b1acaa5UL, 0x00136df9790e3155UL) /* 3373 */
+P(16, 0x56572be34b9d3215UL, 0x0013567dd8defd5bUL) /* 3389 */
+P( 2, 0x87964ef7781c62bfUL, 0x0013539261fdbc34UL) /* 3391 */
+P(16, 0x29ed84051c06e9afUL, 0x00133c564292d28aUL) /* 3407 */
+P( 6, 0xb00acd11ed3f87fdUL, 0x001333ae178d6388UL) /* 3413 */
+P(20, 0x06307881744152d9UL, 0x0013170ad00d1fd7UL) /* 3433 */
+P(16, 0x7a786459f5c1ccc9UL, 0x0013005f01db0947UL) /* 3449 */
+P( 8, 0x1308125d74563281UL, 0x0012f51d40342210UL) /* 3457 */
+P( 4, 0x395310a480b3e34dUL, 0x0012ef815e4ed950UL) /* 3461 */
+P( 2, 0x35985baa8b202837UL, 0x0012ecb4abccd827UL) /* 3463 */
+P( 4, 0x96304a6e052b3223UL, 0x0012e71dc1d3d820UL) /* 3467 */
+P( 2, 0xbd8265fc9af8fd45UL, 0x0012e45389a16495UL) /* 3469 */
+P(22, 0x1b6d0b383ec58e0bUL, 0x0012c5d9226476ccUL) /* 3491 */
+P( 8, 0xc21a7c3b68b28503UL, 0x0012badc391156fdUL) /* 3499 */
+P(12, 0x236fa180fbfd6007UL, 0x0012aa78e412f522UL) /* 3511 */
+P( 6, 0xc42accd440ed9595UL, 0x0012a251f5f47fd1UL) /* 3517 */
+P(10, 0x7acf7128236ba3f7UL, 0x001294cb85c53534UL) /* 3527 */
+P( 2, 0xf909367a987b9c79UL, 0x0012921963beb65eUL) /* 3529 */
+P( 4, 0xb64efb252bfba705UL, 0x00128cb777c69ca8UL) /* 3533 */
+P( 6, 0x980d4f5a7e4cd25bUL, 0x001284aa6cf07294UL) /* 3539 */
+P( 2, 0xe1ecc4ef27b0c37dUL, 0x001281fcf6ac7f87UL) /* 3541 */
+P( 6, 0x9111aebb81d72653UL, 0x001279f937367db9UL) /* 3547 */
+P(10, 0x8951f985cb2c67edUL, 0x00126cad0488be94UL) /* 3557 */
+P( 2, 0xc439d4fc54e0b5d7UL, 0x00126a06794646a2UL) /* 3559 */
+P(12, 0xe857bf31896d533bUL, 0x00125a2f2bcd3e95UL) /* 3571 */
+P(10, 0xb614bb4cb5023755UL, 0x00124d108389e6b1UL) /* 3581 */
+P( 2, 0x938a89e5473bf1ffUL, 0x00124a73083771acUL) /* 3583 */
+P(10, 0xeac481aca34de039UL, 0x00123d6acda0620aUL) /* 3593 */
+P(14, 0x14b961badf4809a7UL, 0x00122b4b2917eafdUL) /* 3607 */
+P( 6, 0x76784fecba352435UL, 0x00122391bfce1e2fUL) /* 3613 */
+P( 4, 0xefa689bb58aef5e1UL, 0x00121e6f1ea579f2UL) /* 3617 */
+P( 6, 0xb2b2c4db9c3a8197UL, 0x001216c09e471568UL) /* 3623 */
+P( 8, 0x2503bc992279f8cfUL, 0x00120c8cb9d93909UL) /* 3631 */
+P( 6, 0xd2ab9aec5ca1541dUL, 0x001204ed58e64ef9UL) /* 3637 */
+P( 6, 0x3e78ba1460f99af3UL, 0x0011fd546578f00cUL) /* 3643 */
+P(16, 0x0a01426572cfcb63UL, 0x0011e9310b8b4c9cUL) /* 3659 */
+P(12, 0xbea857968f3cbd67UL, 0x0011da3405db9911UL) /* 3671 */
+P( 2, 0x78db213eefe659e9UL, 0x0011d7b6f4eb055dUL) /* 3673 */
+P( 4, 0x963e8541a74d35f5UL, 0x0011d2bee748c145UL) /* 3677 */
+P(14, 0x9e22d152776f2e43UL, 0x0011c1706ddce7a7UL) /* 3691 */
+P( 6, 0x05d10d39d1e1f291UL, 0x0011ba0fed2a4f14UL) /* 3697 */
+P( 4, 0x374468dccaced1ddUL, 0x0011b528538ed64aUL) /* 3701 */
+P( 8, 0x8d145c7d110c5ad5UL, 0x0011ab61404242acUL) /* 3709 */
+P(10, 0x3251a39f5acb5737UL, 0x00119f378ce81d2fUL) /* 3719 */
+P( 8, 0xa66e50171443506fUL, 0x001195889ece79daUL) /* 3727 */
+P( 6, 0x124f69ad91dd4cbdUL, 0x00118e4c65387077UL) /* 3733 */
+P( 6, 0xec24f8f2a61a2793UL, 0x001187161d70e725UL) /* 3739 */
+P(22, 0xb472148e656b7a51UL, 0x00116cd6d1c85239UL) /* 3761 */
+P( 6, 0x0adf9570e1142f07UL, 0x001165bbe7ce86b1UL) /* 3767 */
+P( 2, 0x89bf33b065119789UL, 0x0011635ee344ce36UL) /* 3769 */
+P(10, 0x8f0149803cb291ebUL, 0x0011579767b6d679UL) /* 3779 */
+P(14, 0x8334b63afd190a31UL, 0x00114734711e2b54UL) /* 3793 */
+P( 4, 0x920908d50d6aba7dUL, 0x0011428b90147f05UL) /* 3797 */
+P( 6, 0x57d8b018c5a33d53UL, 0x00113b92f3021636UL) /* 3803 */
+P(18, 0xea1773092dc27ee5UL, 0x001126cabc886884UL) /* 3821 */
+P( 2, 0xcae5f38b7bf2e00fUL, 0x0011247eb1b85976UL) /* 3823 */
+P(10, 0x2bd02df34f695349UL, 0x0011190bb01efd65UL) /* 3833 */
+P(14, 0xddfecd5be62e2eb7UL, 0x0011091de0fd679cUL) /* 3847 */
+P( 4, 0xdbf849ebec96c4a3UL, 0x001104963c7e4e0bUL) /* 3851 */
+P( 2, 0xda31d4d0187357c5UL, 0x00110253516420b0UL) /* 3853 */
+P(10, 0xe34e21cc2d5418a7UL, 0x0010f70db7c41797UL) /* 3863 */
+P(14, 0x68ca5137a9e574adUL, 0x0010e75ee2bf9ecdUL) /* 3877 */
+P( 4, 0x3eaa0d0f804bfd19UL, 0x0010e2e91c6e0676UL) /* 3881 */
+P( 8, 0x554fb753cc20e9d1UL, 0x0010da049b9d428dUL) /* 3889 */
+P(18, 0x797afcca1300756bUL, 0x0010c6248fe3b1a2UL) /* 3907 */
+P( 4, 0x8b8d950b52eeea77UL, 0x0010c1c03ed690ebUL) /* 3911 */
+P( 6, 0xfb6cd166acabc185UL, 0x0010bb2e1379e3a2UL) /* 3917 */
+P( 2, 0x4eb6c5ed9437a7afUL, 0x0010b8fe7f61228eUL) /* 3919 */
+P( 4, 0xd1eddbd91b790cdbUL, 0x0010b4a10d60a4f7UL) /* 3923 */
+P( 6, 0x93d714ea4d8948e9UL, 0x0010ae192681ec0fUL) /* 3929 */
+P( 2, 0x3ca13ed8145188d3UL, 0x0010abecfbe5b0aeUL) /* 3931 */
+P(12, 0x829086016da89c57UL, 0x00109eefd568b96dUL) /* 3943 */
+P( 4, 0xd7da1f432124a543UL, 0x00109a9ff178b40cUL) /* 3947 */
+P(20, 0x7ead5581632fb07fUL, 0x00108531e22f9ff9UL) /* 3967 */
+P(22, 0x35443837f63ec3bdUL, 0x00106ddec1af4417UL) /* 3989 */
+
+#undef FIRST_OMITTED_PRIME
+#define FIRST_OMITTED_PRIME 4001
diff --git a/gmp/demos/qcn.c b/gmp/demos/qcn.c
new file mode 100644
index 0000000000..9d76446804
--- /dev/null
+++ b/gmp/demos/qcn.c
@@ -0,0 +1,172 @@
+/* Use mpz_kronecker_ui() to calculate an estimate for the quadratic
+ class number h(d), for a given negative fundamental discriminant, using
+ Dirichlet's analytic formula.
+
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3 of the License, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see https://www.gnu.org/licenses/. */
+
+
+/* Usage: qcn [-p limit] <discriminant>...
+
+ A fundamental discriminant means one of the form D or 4*D with D
+ square-free. Each argument is checked to see it's congruent to 0 or 1
+ mod 4 (as all discriminants must be), and that it's negative, but there's
+ no check on D being square-free.
+
+ This program is a bit of a toy, there are better methods for calculating
+ the class number and class group structure.
+
+ Reference:
+
+ Daniel Shanks, "Class Number, A Theory of Factorization, and Genera",
+ Proc. Symp. Pure Math., vol 20, 1970, pages 415-440.
+
+*/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+
+/* A simple but slow primality test. */
+int
+prime_p (unsigned long n)
+{
+ unsigned long i, limit;
+
+ if (n == 2)
+ return 1;
+ if (n < 2 || !(n&1))
+ return 0;
+
+ limit = (unsigned long) floor (sqrt ((double) n));
+ for (i = 3; i <= limit; i+=2)
+ if ((n % i) == 0)
+ return 0;
+
+ return 1;
+}
+
+
+/* The formula is as follows, with d < 0.
+
+ w * sqrt(-d) inf p
+ h(d) = ------------ * product --------
+ 2 * pi p=2 p - (d/p)
+
+
+ (d/p) is the Kronecker symbol and the product is over primes p. w is 6
+ when d=-3, 4 when d=-4, or 2 otherwise.
+
+ Calculating the product up to p=infinity would take a long time, so for
+ the estimate primes up to 132,000 are used. Shanks found this giving an
+ accuracy of about 1 part in 1000, in normal cases. */
+
+unsigned long p_limit = 132000;
+
+double
+qcn_estimate (mpz_t d)
+{
+ double h;
+ unsigned long p;
+
+ /* p=2 */
+ h = sqrt (-mpz_get_d (d)) / M_PI
+ * 2.0 / (2.0 - mpz_kronecker_ui (d, 2));
+
+ if (mpz_cmp_si (d, -3) == 0) h *= 3;
+ else if (mpz_cmp_si (d, -4) == 0) h *= 2;
+
+ for (p = 3; p <= p_limit; p += 2)
+ if (prime_p (p))
+ h *= (double) p / (double) (p - mpz_kronecker_ui (d, p));
+
+ return h;
+}
+
+
+void
+qcn_str (char *num)
+{
+ mpz_t z;
+
+ mpz_init_set_str (z, num, 0);
+
+ if (mpz_sgn (z) >= 0)
+ {
+ mpz_out_str (stdout, 0, z);
+ printf (" is not supported (negatives only)\n");
+ }
+ else if (mpz_fdiv_ui (z, 4) != 0 && mpz_fdiv_ui (z, 4) != 1)
+ {
+ mpz_out_str (stdout, 0, z);
+ printf (" is not a discriminant (must == 0 or 1 mod 4)\n");
+ }
+ else
+ {
+ printf ("h(");
+ mpz_out_str (stdout, 0, z);
+ printf (") approx %.1f\n", qcn_estimate (z));
+ }
+ mpz_clear (z);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ int saw_number = 0;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "-p") == 0)
+ {
+ i++;
+ if (i >= argc)
+ {
+ fprintf (stderr, "Missing argument to -p\n");
+ exit (1);
+ }
+ p_limit = atoi (argv[i]);
+ }
+ else
+ {
+ qcn_str (argv[i]);
+ saw_number = 1;
+ }
+ }
+
+ if (! saw_number)
+ {
+ /* some default output */
+ qcn_str ("-85702502803"); /* is 16259 */
+ qcn_str ("-328878692999"); /* is 1499699 */
+ qcn_str ("-928185925902146563"); /* is 52739552 */
+ qcn_str ("-84148631888752647283"); /* is 496652272 */
+ return 0;
+ }
+
+ return 0;
+}
diff --git a/gmp/doc/Makefile.am b/gmp/doc/Makefile.am
new file mode 100644
index 0000000000..083f25a630
--- /dev/null
+++ b/gmp/doc/Makefile.am
@@ -0,0 +1,36 @@
+## Process this file with automake to generate Makefile.in
+
+
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+EXTRA_DIST = configuration isa_abi_headache projects.html tasks.html
+
+info_TEXINFOS = gmp.texi
+gmp_TEXINFOS = fdl-1.3.texi
diff --git a/gmp/doc/Makefile.in b/gmp/doc/Makefile.in
new file mode 100644
index 0000000000..1acf6029ef
--- /dev/null
+++ b/gmp/doc/Makefile.in
@@ -0,0 +1,766 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2003 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = doc
+DIST_COMMON = $(gmp_TEXINFOS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/stamp-vti \
+ $(srcdir)/version.texi mdate-sh texinfo.tex
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+depcomp =
+am__depfiles_maybe =
+SOURCES =
+DIST_SOURCES =
+INFO_DEPS = $(srcdir)/gmp.info
+am__TEXINFO_TEX_DIR = $(srcdir)
+DVIS = gmp.dvi
+PDFS = gmp.pdf
+PSS = gmp.ps
+HTMLS = gmp.html
+TEXINFOS = gmp.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__installdirs = "$(DESTDIR)$(infodir)"
+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; }; \
+ }
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+EXTRA_DIST = configuration isa_abi_headache projects.html tasks.html
+info_TEXINFOS = gmp.texi
+gmp_TEXINFOS = fdl-1.3.texi
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .html .info .pdf .ps .texi
+$(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 doc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps doc/Makefile
+.PRECIOUS: 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):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+.texi.info:
+ restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ am__cwd=`pwd` && $(am__cd) $(srcdir) && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+ done; \
+ else :; fi && \
+ cd "$$am__cwd"; \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<; \
+ then \
+ rc=0; \
+ $(am__cd) $(srcdir); \
+ else \
+ rc=$$?; \
+ $(am__cd) $(srcdir) && \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) $<
+
+.texi.pdf:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) $<
+
+.texi.html:
+ rm -rf $(@:.html=.htp)
+ if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ else \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+ exit 1; \
+ fi
+$(srcdir)/gmp.info: gmp.texi $(srcdir)/version.texi $(gmp_TEXINFOS)
+gmp.dvi: gmp.texi $(srcdir)/version.texi $(gmp_TEXINFOS)
+gmp.pdf: gmp.texi $(srcdir)/version.texi $(gmp_TEXINFOS)
+gmp.html: gmp.texi $(srcdir)/version.texi $(gmp_TEXINFOS)
+$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti
+$(srcdir)/stamp-vti: gmp.texi $(top_srcdir)/configure
+ @(dir=.; test -f ./gmp.texi || dir=$(srcdir); \
+ set `$(SHELL) $(srcdir)/mdate-sh $$dir/gmp.texi`; \
+ echo "@set UPDATED $$1 $$2 $$3"; \
+ echo "@set UPDATED-MONTH $$2 $$3"; \
+ echo "@set EDITION $(VERSION)"; \
+ echo "@set VERSION $(VERSION)") > vti.tmp
+ @cmp -s vti.tmp $(srcdir)/version.texi \
+ || (echo "Updating $(srcdir)/version.texi"; \
+ cp vti.tmp $(srcdir)/version.texi)
+ -@rm -f vti.tmp
+ @cp $(srcdir)/version.texi $@
+
+mostlyclean-vti:
+ -rm -f vti.tmp
+
+maintainer-clean-vti:
+@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
+.dvi.ps:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) -o $@ $<
+
+uninstall-dvi-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
+ rm -f "$(DESTDIR)$(dvidir)/$$f"; \
+ done
+
+uninstall-html-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-info-am:
+ @$(PRE_UNINSTALL)
+ @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
+ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+uninstall-pdf-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
+
+uninstall-ps-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(psdir)/$$f"; \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+ if test -f $$file; then \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f "$(distdir)/$$relfile" || \
+ cp -p $$file "$(distdir)/$$relfile"; \
+ else :; fi; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf gmp.aux gmp.cp gmp.cps gmp.fn gmp.fns gmp.ky gmp.kys gmp.log gmp.pg \
+ gmp.pgs gmp.tmp gmp.toc gmp.tp gmp.vr gmp.vrs
+
+clean-aminfo:
+ -test -z "gmp.dvi gmp.pdf gmp.ps gmp.html" \
+ || rm -rf gmp.dvi gmp.pdf gmp.ps gmp.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+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
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-info
+check-am: all-am
+check: check-am
+all-am: Makefile $(INFO_DEPS)
+installdirs:
+ for dir in "$(DESTDIR)$(infodir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+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:
+
+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-aminfo clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am
+
+install-dvi: install-dvi-am
+
+install-dvi-am: $(DVIS)
+ @$(NORMAL_INSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
+ done
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am: $(HTMLS)
+ @$(NORMAL_INSTALL)
+ @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__strip_dir) \
+ d2=$$d$$p; \
+ if test -d "$$d2"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+ echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+ else \
+ list2="$$list2 $$d2"; \
+ fi; \
+ done; \
+ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
+ done; }
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \
+ fi; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ echo "$$ifile"; \
+ else : ; fi; \
+ done; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
+ @$(POST_INSTALL)
+ @if $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am: $(PDFS)
+ @$(NORMAL_INSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
+install-ps: install-ps-am
+
+install-ps-am: $(PSS)
+ @$(NORMAL_INSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+ maintainer-clean-generic maintainer-clean-vti
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-libtool mostlyclean-vti
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-aminfo clean-generic \
+ clean-libtool dist-info distclean distclean-generic \
+ distclean-libtool 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-aminfo \
+ maintainer-clean-generic maintainer-clean-vti mostlyclean \
+ mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool \
+ mostlyclean-vti pdf pdf-am ps ps-am uninstall uninstall-am \
+ uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+
+# 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/gmp/doc/configuration b/gmp/doc/configuration
new file mode 100644
index 0000000000..b6903866b2
--- /dev/null
+++ b/gmp/doc/configuration
@@ -0,0 +1,390 @@
+/* doc/configuration (in Emacs -*-outline-*- format). */
+
+Copyright 2000-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+* Adding a new file
+
+** Adding a top-level file
+
+ i) Add it to libgmp_la_SOURCES in Makefile.am.
+
+ ii) If libmp.la needs it (usually doesn't), then add it to
+ libmp_la_SOURCES too.
+
+** Adding a subdirectory file
+
+For instance for mpz,
+
+ i) Add file.c to libmpz_la_SOURCES in mpz/Makefile.am.
+
+ ii) Add mpz/file$U.lo to MPZ_OBJECTS in the top-level Makefile.am
+
+ iii) If for some reason libmp.la needs it (usually doesn't) then add
+ mpz/file$U.lo to libmp_la_DEPENDENCIES in the top-level
+ Makefile.am too.
+
+The same applies to mpf, mpq, scanf and printf.
+
+** Adding an mpn file
+
+The way we build libmpn (in the `mpn' subdirectory) is quite special.
+
+Currently only mpn/mp_bases.c is truly generic and included in every
+configuration. All other files are linked at build time into the mpn
+build directory from one of the CPU specific sub-directories, or from
+the mpn/generic directory.
+
+There are four types of mpn source files.
+
+ .asm Assembly code preprocessed with m4
+ .S Assembly code preprocessed with cpp
+ .s Assembly code not preprocessed at all
+ .c C code
+
+There are two types of .asm files.
+
+ i) ``Normal'' files containing one function, though possibly with
+ more than one entry point.
+
+ ii) Multi-function files that generate one of a set of functions
+ according to build options.
+
+To add a new implementation of an existing function,
+
+ i) Put it in the appropriate CPU-specific mpn subdirectory, it'll be
+ detected and used.
+
+ ii) Any entrypoints tested by HAVE_NATIVE_func in other code must
+ have PROLOGUE(func) for configure to grep. This is normal for
+ .asm or .S files, but for .c files a dummy comment like the
+ following will be needed.
+
+ /*
+ PROLOGUE(func)
+ */
+
+To add a new implementation using a multi-function file, in addition
+do the following,
+
+ i) Use a MULFUNC_PROLOGUE(func1 func2 ...) in the .asm, declaring
+ all the functions implemented, including carry-in variants.
+
+ If there's a separate PROLOGUE(func) for each possible function
+ (but this is usually not the case), then MULFUNC_PROLOGUE isn't
+ necessary.
+
+To add a new style of multi-function file, in addition do the
+following,
+
+ i) Add to the GMP_MULFUNC_CHOICES "case" statement in configure.in
+ which lists each multi-function filename and what function files
+ it can provide.
+
+To add a completely new mpn function file, do the following,
+
+ i) Ensure the filename is a valid C identifier, due to the
+ -DOPERATION_$* used to support multi-function files. This means
+ "-" can't be used (but "_" can).
+
+ ii) Add it to configure.in under one of the following
+
+ a) `gmp_mpn_functions' if it exists for every target. This
+ means there must be a C version in mpn/generic. (Eg. mul_1)
+
+ b) `gmp_mpn_functions_optional' if it's a standard function, but
+ doesn't need to exist for every target. Code wanting to use
+ this will test HAVE_NATIVE_func to see if it's available.
+ (Eg. copyi)
+
+ c) `extra_functions' for some targets, if it's a special
+ function that only ever needs to exist for certain targets.
+ Code wanting to use it can test either HAVE_NATIVE_func or
+ HAVE_HOST_CPU_foo, as desired.
+
+ iii) If HAVE_NATIVE_func is going to be used, then add a #undef to
+ the AH_VERBATIM([HAVE_NATIVE] block in configure.in.
+
+ iv) If the function can be provided by a multi-function file, then
+ add to the "case" statement in configure.in which lists each
+ multi-function filename and what function files it can provide.
+
+
+** Adding a test program
+
+ i) Tests to be run early in the testing can be added to the main
+ "tests" sub-directory.
+
+ ii) Tests for mpn, mpz, mpq and mpf can be added under the
+ corresponding tests subdirectory.
+
+ iii) Generic tests for late in the testing can be added to
+ "tests/misc". printf and scanf tests currently live there too.
+
+ iv) Random number function tests can be added to "tests/rand". That
+ directory has some development-time programs too.
+
+ v) C++ test programs can be added to "tests/cxx". A line like the
+ following must be added for each, since by default automake looks
+ for a .c file.
+
+ t_foo_SOURCES = t-foo.cc
+
+In all cases the name of the program should be added to check_PROGRAMS
+in the Makefile.am. TESTS is equal to check_PROGRAMS, so all those
+programs get run.
+
+"tests/devel" has a number of programs which are only for development
+purposes and are not for use in "make check". These should be listed
+in EXTRA_PROGRAMS to get Makefile rules created, but they're never
+built or run unless an explicit "make someprog" is used.
+
+
+* Adding a new CPU
+
+In general it's policy to use proper names for each CPU type
+supported. If two CPUs are quite similar and perhaps don't have any
+actual differences in GMP then they're still given separate names, for
+example alphaev67 and alphaev68.
+
+Canonical names:
+
+ i) Decide the canonical CPU names GMP will accept.
+
+ ii) Add these to the config.sub wrapper if configfsf.sub doesn't
+ already accept them.
+
+ iii) Document the names in gmp.texi.
+
+Aliases (optional):
+
+ i) Any aliases can be added to the config.sub wrapper, unless
+ configfsf.sub already does the right thing with them.
+
+ ii) Leave configure.in and everywhere else using only the canonical
+ names. Aliases shouldn't appear anywhere except config.sub.
+
+ iii) Document in gmp.texi, if desired. Usually this isn't a good
+ idea, better encourage users to know just the canonical
+ names.
+
+Configure:
+
+ i) Add patterns to configure.in for the new CPU names. Include the
+ following (see configure.in for the variables to set up),
+
+ a) ABI choices (if any).
+ b) Compiler choices.
+ c) mpn path for CPU specific code.
+ d) Good default CFLAGS for each likely compiler.
+ d) Any special tests necessary on the compiler or assembler
+ capabilities.
+
+ ii) M4 macros to be shared by asm files in a CPU family are by
+ convention in a foo-defs.m4 like mpn/x86/x86-defs.m4. They're
+ likely to use settings from config.m4 generated by configure.
+
+Fat binaries:
+
+ i) In configure.in, add CPU specific directory(s) to fat_path.
+
+ ii) In mpn/<cpu>/fat.c, identify the CPU at runtime and use suitable
+ CPUVEC_SETUP_subdir macros to select the function pointers for it.
+
+ iii) For the x86s, add to the "$tmp_prefix" setups in configure.in
+ which abbreviates subdirectory names to fit an 8.3 filesystem.
+ (No need to restrict to 8.3, just ensure uniqueness when
+ truncated.)
+
+
+* The configure system
+
+** Installing tools
+
+The current versions of automake, autoconf and libtool in use can be
+checked in the ChangeLog. Look for "Update to ...". Patches may have
+been applied, look for "Regenerate ...".
+
+The GMP build system is in places somewhat dependent on the internals
+of the build tools. Obviously that's avoided as much as possible, but
+where it can't it creates a problem when upgrading or attempting to
+use different tools versions.
+
+** Updating gmp
+
+The following files need to be updated when going to a new version of
+the build tools. Unfortunately the tools generally don't identify
+when an out-of-date version is present.
+
+aclocal.m4 is updated by running "aclocal". (Only needed for a new
+automake or libtool.)
+
+INSTALL.autoconf can be copied from INSTALL in autoconf.
+
+ltmain.sh comes from libtool. Remove it and run "libtoolize --copy",
+or just copy the file by hand.
+
+texinfo.tex can be updated from ftp.gnu.org. Check it still works
+with "make gmp.dvi", "make gmp.ps" and "make gmp.pdf".
+
+configfsf.guess and configfsf.sub can be updated from ftp.gnu.org (or
+from the "config" cvs module at subversions.gnu.org). The gmp
+config.guess and config.sub wrappers are supposed to make such an
+update fairly painless.
+
+depcomp from automake is not needed because configure.in specifies
+automake with "no-dependencies".
+
+** How it works
+
+During development:
+
+ Input files Tool Output files
+ ---------------------------------------------------------
+
+ aclocal
+ $prefix/share/aclocal*/*.m4 ----------------> aclocal.m4
+
+
+ configure.in \ autoconf
+ aclocal.m4 / -----------------------------> configure
+
+
+ */Makefile.am \ automake
+ configure.in | ----------------------------> Makefile.in
+ aclocal.m4 /
+
+ configure.in \ autoheader
+ aclocal.m4 / -----------------------------> config.in
+
+At build time:
+
+ Input files Tool Output files
+ --------------------------------------------
+
+ */Makefile.in \ configure / */Makefile
+ config.in | -------------> | config.h
+ gmp-h.in | | config.m4
+ mp-h.in / | gmp.h
+ | mp.h
+ \ fat.h (fat binary build only)
+
+When configured with --enable-maintainer-mode the Makefiles include
+rules to re-run the necessary tools if the input files are changed.
+This can end up running a lot more things than are really necessary.
+
+If a build tree is in too much of a mess for those rules to work
+properly then a bootstrap can be done from the source directory with
+
+ aclocal
+ autoconf
+ automake
+ autoheader
+
+The autom4te.cache directory is created by autoconf to save some work
+in subsequent automake or autoheader runs. It's recreated
+automatically if removed, it doesn't get distributed.
+
+** C++ configuration
+
+It's intended that the contents of libgmp.la won't vary according to
+whether --enable-cxx is selected. This means that if C++ shared
+libraries don't work properly then a shared+static with --disable-cxx
+can be done for the C parts, then a static-only with --enable-cxx to
+get libgmpxx.
+
+libgmpxx.la uses some internals from libgmp.la, in order to share code
+between C and C++. It's intended that libgmpxx can only be expected
+to work with libgmp from the same version of GMP. If some of the
+shared internals change their interface, then it's proposed to rename
+them, for instance __gmp_doprint2 or the like, so as to provoke link
+errors rather than mysterious failures from a mismatch.
+
+* Development setups
+
+** General
+
+--disable-shared will make builds go much faster, though of course
+shared or shared+static should be tested too.
+
+--prefix to a dummy directory followed by "make install" will show
+what's installed.
+
+"make check" acts on the libgmp just built, and will ignore any other
+/usr/lib/libgmp, or at least it should do. Libtool does various hairy
+things to ensure it hits the just-built library.
+
+** Long long limb testing
+
+On systems where gcc supports long long, but a limb is normally just a
+long, the following can be used to force long long for testing
+purposes. It will probably run quite slowly.
+
+ ./configure --host=none ABI=longlong
+
+** Function argument conversions
+
+When using gcc, configuring with something like
+
+ ./configure CFLAGS="-g -Wall -Wconversion -Wno-sign-compare"
+
+can show where function parameters are being converted due to having
+function prototypes available, which won't happen in a K&R compiler.
+Doing this in combination with the long long limb setups above is
+good.
+
+Conversions between int and long aren't warned about by gcc when
+they're the same size, which is unfortunate because casts should be
+used in such cases, for the benefit of K&R compilers with int!=long
+and where the difference matters in function calls.
+
+* Other Notes
+
+** Compatibility
+
+compat.c is the home of functions retained for binary compatibility,
+ but now done by other means (like a macro).
+
+struct __mpz_struct etc - this must be retained for C++ compatibility.
+ C++ applications defining functions taking mpz_t etc parameters
+ will get this in the mangled name because C++ "sees though" the
+ typedef mpz_t to the underlying struct.
+
+__gmpn - note that glibc defines some __mpn symbols, old versions of
+ some mpn routines, which it uses for floating point printfs.
+
+
+
+
+Local variables:
+mode: outline
+fill-column: 70
+End:
+/* eof doc/configuration */
diff --git a/gmp/doc/fdl-1.3.texi b/gmp/doc/fdl-1.3.texi
new file mode 100644
index 0000000000..05804eecbb
--- /dev/null
+++ b/gmp/doc/fdl-1.3.texi
@@ -0,0 +1,506 @@
+@c The GNU Free Documentation License.
+@center Version 1.3, 3 November 2008
+
+@c This file is intended to be included within another document,
+@c hence no sectioning command or @node.
+
+@display
+Copyright @copyright{} 2000-2002, 2007, 2008 Free Software Foundation, Inc.
+@uref{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+@sc{ascii} without markup, Texinfo input format, La@TeX{} input
+format, @acronym{SGML} or @acronym{XML} using a publicly available
+@acronym{DTD}, and standard-conforming simple @acronym{HTML},
+PostScript or @acronym{PDF} designed for human modification. Examples
+of transparent image formats include @acronym{PNG}, @acronym{XCF} and
+@acronym{JPG}. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, @acronym{SGML} or
+@acronym{XML} for which the @acronym{DTD} and/or processing tools are
+not generally available, and the machine-generated @acronym{HTML},
+PostScript or @acronym{PDF} produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+The ``publisher'' means any person or entity that distributes copies
+of the Document to the public.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense, or distribute it is void, and
+will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+@uref{https://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation. If the Document
+specifies that a proxy can decide which future versions of this
+License can be used, that proxy's public statement of acceptance of a
+version permanently authorizes you to choose that version for the
+Document.
+
+@item
+RELICENSING
+
+``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
+World Wide Web server that publishes copyrightable works and also
+provides prominent facilities for anybody to edit those works. A
+public wiki that anybody can edit is an example of such a server. A
+``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
+site means any set of copyrightable works thus published on the MMC
+site.
+
+``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
+license published by Creative Commons Corporation, a not-for-profit
+corporation with a principal place of business in San Francisco,
+California, as well as future copyleft versions of that license
+published by that same organization.
+
+``Incorporate'' means to publish or republish a Document, in whole or
+in part, as part of another Document.
+
+An MMC is ``eligible for relicensing'' if it is licensed under this
+License, and if all works that were first published under this License
+somewhere other than this MMC, and subsequently incorporated in whole
+or in part into the MMC, (1) had no cover texts or invariant sections,
+and (2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+@end enumerate
+
+@page
+@heading ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with@dots{}Texts.'' line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
+
diff --git a/gmp/doc/gmp.info b/gmp/doc/gmp.info
new file mode 100644
index 0000000000..b1acc78505
--- /dev/null
+++ b/gmp/doc/gmp.info
@@ -0,0 +1,181 @@
+This is ../../gmp/doc/gmp.info, produced by makeinfo version 4.13 from
+../../gmp/doc/gmp.texi.
+
+This manual describes how to install and use the GNU multiple precision
+arithmetic library, version 6.0.0.
+
+ Copyright 1991, 1993-2014 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation License, Version
+1.3 or any later version published by the Free Software Foundation;
+with no Invariant Sections, with the Front-Cover Texts being "A GNU
+Manual", and with the Back-Cover Texts being "You have freedom to copy
+and modify this GNU Manual, like GNU software". A copy of the license
+is included in *note GNU Free Documentation License::.
+
+INFO-DIR-SECTION GNU libraries
+START-INFO-DIR-ENTRY
+* gmp: (gmp). GNU Multiple Precision Arithmetic Library.
+END-INFO-DIR-ENTRY
+
+
+Indirect:
+gmp.info-1: 882
+gmp.info-2: 300831
+
+Tag Table:
+(Indirect)
+Node: Top882
+Node: Copying2953
+Node: Introduction to GMP5299
+Node: Installing GMP8014
+Node: Build Options8746
+Node: ABI and ISA24479
+Node: Notes for Package Builds34316
+Node: Notes for Particular Systems37403
+Node: Known Build Problems45153
+Node: Performance optimization48688
+Node: GMP Basics49817
+Node: Headers and Libraries50465
+Node: Nomenclature and Types51870
+Node: Function Classes53866
+Node: Variable Conventions55400
+Node: Parameter Conventions57009
+Node: Memory Management59065
+Node: Reentrancy60193
+Node: Useful Macros and Constants62061
+Node: Compatibility with older versions63052
+Node: Demonstration Programs63963
+Node: Efficiency65828
+Node: Debugging73452
+Node: Profiling80478
+Node: Autoconf84469
+Node: Emacs86250
+Node: Reporting Bugs86856
+Node: Integer Functions89483
+Node: Initializing Integers90259
+Node: Assigning Integers92635
+Node: Simultaneous Integer Init & Assign94246
+Node: Converting Integers95893
+Node: Integer Arithmetic98857
+Node: Integer Division100593
+Node: Integer Exponentiation107345
+Node: Integer Roots108839
+Node: Number Theoretic Functions110559
+Node: Integer Comparisons118034
+Node: Integer Logic and Bit Fiddling119472
+Node: I/O of Integers122117
+Node: Integer Random Numbers125108
+Node: Integer Import and Export127725
+Node: Miscellaneous Integer Functions131741
+Node: Integer Special Functions133655
+Node: Rational Number Functions137815
+Node: Initializing Rationals139008
+Node: Rational Conversions141487
+Node: Rational Arithmetic143237
+Node: Comparing Rationals144649
+Node: Applying Integer Functions146057
+Node: I/O of Rationals147576
+Node: Floating-point Functions149634
+Node: Initializing Floats152604
+Node: Assigning Floats156697
+Node: Simultaneous Float Init & Assign159288
+Node: Converting Floats160838
+Node: Float Arithmetic164128
+Node: Float Comparison166281
+Node: I/O of Floats167941
+Node: Miscellaneous Float Functions170630
+Node: Low-level Functions172632
+Node: Random Number Functions205756
+Node: Random State Initialization206824
+Node: Random State Seeding209689
+Node: Random State Miscellaneous211094
+Node: Formatted Output211736
+Node: Formatted Output Strings211981
+Node: Formatted Output Functions217360
+Node: C++ Formatted Output221435
+Node: Formatted Input224135
+Node: Formatted Input Strings224371
+Node: Formatted Input Functions229023
+Node: C++ Formatted Input231992
+Node: C++ Class Interface233895
+Node: C++ Interface General234846
+Node: C++ Interface Integers237916
+Node: C++ Interface Rationals241637
+Node: C++ Interface Floats245660
+Node: C++ Interface Random Numbers251676
+Node: C++ Interface Limitations254078
+Node: Custom Allocation257656
+Node: Language Bindings261875
+Node: Algorithms265469
+Node: Multiplication Algorithms266169
+Node: Basecase Multiplication267258
+Node: Karatsuba Multiplication269166
+Node: Toom 3-Way Multiplication272792
+Node: Toom 4-Way Multiplication279211
+Node: Higher degree Toom'n'half280590
+Node: FFT Multiplication281876
+Node: Other Multiplication287211
+Node: Unbalanced Multiplication289685
+Node: Division Algorithms290473
+Node: Single Limb Division290852
+Node: Basecase Division293742
+Node: Divide and Conquer Division294945
+Node: Block-Wise Barrett Division297014
+Node: Exact Division297666
+Node: Exact Remainder300831
+Node: Small Quotient Division303081
+Node: Greatest Common Divisor Algorithms304679
+Node: Binary GCD304976
+Node: Lehmer's Algorithm307825
+Node: Subquadratic GCD310044
+Node: Extended GCD312501
+Node: Jacobi Symbol313813
+Node: Powering Algorithms314828
+Node: Normal Powering Algorithm315091
+Node: Modular Powering Algorithm315619
+Node: Root Extraction Algorithms316401
+Node: Square Root Algorithm316716
+Node: Nth Root Algorithm318857
+Node: Perfect Square Algorithm319642
+Node: Perfect Power Algorithm321729
+Node: Radix Conversion Algorithms322350
+Node: Binary to Radix322726
+Node: Radix to Binary326656
+Node: Other Algorithms328744
+Node: Prime Testing Algorithm329096
+Node: Factorial Algorithm330280
+Node: Binomial Coefficients Algorithm332670
+Node: Fibonacci Numbers Algorithm333564
+Node: Lucas Numbers Algorithm336038
+Node: Random Number Algorithms336759
+Node: Assembly Coding338881
+Node: Assembly Code Organisation339841
+Node: Assembly Basics340808
+Node: Assembly Carry Propagation341958
+Node: Assembly Cache Handling343789
+Node: Assembly Functional Units345950
+Node: Assembly Floating Point347563
+Node: Assembly SIMD Instructions351341
+Node: Assembly Software Pipelining352323
+Node: Assembly Loop Unrolling353385
+Node: Assembly Writing Guide355600
+Node: Internals358365
+Node: Integer Internals358877
+Node: Rational Internals361133
+Node: Float Internals362371
+Node: Raw Output Internals369785
+Node: C++ Interface Internals370979
+Node: Contributors374300
+Node: References380372
+Node: GNU Free Documentation License386132
+Node: Concept Index411295
+Node: Function Index457482
+
+End Tag Table
+
+
+Local Variables:
+coding: iso-8859-1
+End:
diff --git a/gmp/doc/gmp.info-1 b/gmp/doc/gmp.info-1
new file mode 100644
index 0000000000..171d224635
--- /dev/null
+++ b/gmp/doc/gmp.info-1
@@ -0,0 +1,7073 @@
+This is ../../gmp/doc/gmp.info, produced by makeinfo version 4.13 from
+../../gmp/doc/gmp.texi.
+
+This manual describes how to install and use the GNU multiple precision
+arithmetic library, version 6.0.0.
+
+ Copyright 1991, 1993-2014 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation License, Version
+1.3 or any later version published by the Free Software Foundation;
+with no Invariant Sections, with the Front-Cover Texts being "A GNU
+Manual", and with the Back-Cover Texts being "You have freedom to copy
+and modify this GNU Manual, like GNU software". A copy of the license
+is included in *note GNU Free Documentation License::.
+
+INFO-DIR-SECTION GNU libraries
+START-INFO-DIR-ENTRY
+* gmp: (gmp). GNU Multiple Precision Arithmetic Library.
+END-INFO-DIR-ENTRY
+
+
+File: gmp.info, Node: Top, Next: Copying, Prev: (dir), Up: (dir)
+
+GNU MP
+******
+
+ This manual describes how to install and use the GNU multiple
+precision arithmetic library, version 6.0.0.
+
+ Copyright 1991, 1993-2014 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation License, Version
+1.3 or any later version published by the Free Software Foundation;
+with no Invariant Sections, with the Front-Cover Texts being "A GNU
+Manual", and with the Back-Cover Texts being "You have freedom to copy
+and modify this GNU Manual, like GNU software". A copy of the license
+is included in *note GNU Free Documentation License::.
+
+
+* Menu:
+
+* Copying:: GMP Copying Conditions (LGPL).
+* Introduction to GMP:: Brief introduction to GNU MP.
+* Installing GMP:: How to configure and compile the GMP library.
+* GMP Basics:: What every GMP user should know.
+* Reporting Bugs:: How to usefully report bugs.
+* Integer Functions:: Functions for arithmetic on signed integers.
+* Rational Number Functions:: Functions for arithmetic on rational numbers.
+* Floating-point Functions:: Functions for arithmetic on floats.
+* Low-level Functions:: Fast functions for natural numbers.
+* Random Number Functions:: Functions for generating random numbers.
+* Formatted Output:: `printf' style output.
+* Formatted Input:: `scanf' style input.
+* C++ Class Interface:: Class wrappers around GMP types.
+* Custom Allocation:: How to customize the internal allocation.
+* Language Bindings:: Using GMP from other languages.
+* Algorithms:: What happens behind the scenes.
+* Internals:: How values are represented behind the scenes.
+
+* Contributors:: Who brings you this library?
+* References:: Some useful papers and books to read.
+* GNU Free Documentation License::
+* Concept Index::
+* Function Index::
+
+
+File: gmp.info, Node: Copying, Next: Introduction to GMP, Prev: Top, Up: Top
+
+GNU MP Copying Conditions
+*************************
+
+This library is "free"; this means that everyone is free to use it and
+free to redistribute it on a free basis. The library is not in the
+public domain; it is copyrighted and there are restrictions on its
+distribution, but these restrictions are designed to permit everything
+that a good cooperating citizen would want to do. What is not allowed
+is to try to prevent others from further sharing any version of this
+library that they might get from you.
+
+ Specifically, we want to make sure that you have the right to give
+away copies of the library, that you receive source code or else can
+get it if you want it, that you can change this library or use pieces
+of it in new free programs, and that you know you can do these things.
+
+ To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights. For example, if you distribute
+copies of the GNU MP library, you must give the recipients all the
+rights that you have. You must make sure that they, too, receive or
+can get the source code. And you must tell them their rights.
+
+ Also, for our own protection, we must make certain that everyone
+finds out that there is no warranty for the GNU MP library. If it is
+modified by someone else and passed on, we want their recipients to
+know that what they have is not what we distributed, so that any
+problems introduced by others will not reflect on our reputation.
+
+ More precisely, the GNU MP library is dual licensed, under the
+conditions of the GNU Lesser General Public License version 3 (see
+`COPYING.LESSERv3'), or the GNU General Public License version 2 (see
+`COPYINGv2'). This is the recipient's choice, and the recipient also has
+the additional option of applying later versions of these licenses. (The
+reason for this dual licensing is to make it possible to use the
+library with programs which are licensed under GPL version 2, but which
+for historical or other reasons do not allow use under later versions
+of the GPL).
+
+ Programs which are not part of the library itself, such as
+demonstration programs and the GMP testsuite, are licensed under the
+terms of the GNU General Public License version 3 (see `COPYINGv3'), or
+any later version.
+
+
+File: gmp.info, Node: Introduction to GMP, Next: Installing GMP, Prev: Copying, Up: Top
+
+1 Introduction to GNU MP
+************************
+
+GNU MP is a portable library written in C for arbitrary precision
+arithmetic on integers, rational numbers, and floating-point numbers.
+It aims to provide the fastest possible arithmetic for all applications
+that need higher precision than is directly supported by the basic C
+types.
+
+ Many applications use just a few hundred bits of precision; but some
+applications may need thousands or even millions of bits. GMP is
+designed to give good performance for both, by choosing algorithms
+based on the sizes of the operands, and by carefully keeping the
+overhead at a minimum.
+
+ The speed of GMP is achieved by using fullwords as the basic
+arithmetic type, by using sophisticated algorithms, by including
+carefully optimized assembly code for the most common inner loops for
+many different CPUs, and by a general emphasis on speed (as opposed to
+simplicity or elegance).
+
+ There is assembly code for these CPUs: ARM Cortex-A9, Cortex-A15,
+and generic ARM, DEC Alpha 21064, 21164, and 21264, AMD K8 and K10
+(sold under many brands, e.g. Athlon64, Phenom, Opteron) Bulldozer, and
+Bobcat, Intel Pentium, Pentium Pro/II/III, Pentium 4, Core2, Nehalem,
+Sandy bridge, Haswell, generic x86, Intel IA-64, Motorola/IBM PowerPC
+32 and 64 such as POWER970, POWER5, POWER6, and POWER7, MIPS 32-bit and
+64-bit, SPARC 32-bit ad 64-bit with special support for all UltraSPARC
+models. There is also assembly code for many obsolete CPUs.
+
+For up-to-date information on GMP, please see the GMP web pages at
+
+ `https://gmplib.org/'
+
+The latest version of the library is available at
+
+ `https://ftp.gnu.org/gnu/gmp/'
+
+ Many sites around the world mirror `ftp.gnu.org', please use a mirror
+near you, see `https://www.gnu.org/order/ftp.html' for a full list.
+
+ There are three public mailing lists of interest. One for release
+announcements, one for general questions and discussions about usage of
+the GMP library and one for bug reports. For more information, see
+
+ `https://gmplib.org/mailman/listinfo/'.
+
+ The proper place for bug reports is <gmp-bugs@gmplib.org>. See
+*note Reporting Bugs:: for information about reporting bugs.
+
+
+1.1 How to use this Manual
+==========================
+
+Everyone should read *note GMP Basics::. If you need to install the
+library yourself, then read *note Installing GMP::. If you have a
+system with multiple ABIs, then read *note ABI and ISA::, for the
+compiler options that must be used on applications.
+
+ The rest of the manual can be used for later reference, although it
+is probably a good idea to glance through it.
+
+
+File: gmp.info, Node: Installing GMP, Next: GMP Basics, Prev: Introduction to GMP, Up: Top
+
+2 Installing GMP
+****************
+
+GMP has an autoconf/automake/libtool based configuration system. On a
+Unix-like system a basic build can be done with
+
+ ./configure
+ make
+
+Some self-tests can be run with
+
+ make check
+
+And you can install (under `/usr/local' by default) with
+
+ make install
+
+ If you experience problems, please report them to
+<gmp-bugs@gmplib.org>. See *note Reporting Bugs::, for information on
+what to include in useful bug reports.
+
+* Menu:
+
+* Build Options::
+* ABI and ISA::
+* Notes for Package Builds::
+* Notes for Particular Systems::
+* Known Build Problems::
+* Performance optimization::
+
+
+File: gmp.info, Node: Build Options, Next: ABI and ISA, Prev: Installing GMP, Up: Installing GMP
+
+2.1 Build Options
+=================
+
+All the usual autoconf configure options are available, run `./configure
+--help' for a summary. The file `INSTALL.autoconf' has some generic
+installation information too.
+
+Tools
+ `configure' requires various Unix-like tools. See *note Notes for
+ Particular Systems::, for some options on non-Unix systems.
+
+ It might be possible to build without the help of `configure',
+ certainly all the code is there, but unfortunately you'll be on
+ your own.
+
+Build Directory
+ To compile in a separate build directory, `cd' to that directory,
+ and prefix the configure command with the path to the GMP source
+ directory. For example
+
+ cd /my/build/dir
+ /my/sources/gmp-6.0.0/configure
+
+ Not all `make' programs have the necessary features (`VPATH') to
+ support this. In particular, SunOS and Slowaris `make' have bugs
+ that make them unable to build in a separate directory. Use GNU
+ `make' instead.
+
+`--prefix' and `--exec-prefix'
+ The `--prefix' option can be used in the normal way to direct GMP
+ to install under a particular tree. The default is `/usr/local'.
+
+ `--exec-prefix' can be used to direct architecture-dependent files
+ like `libgmp.a' to a different location. This can be used to share
+ architecture-independent parts like the documentation, but
+ separate the dependent parts. Note however that `gmp.h' and
+ `mp.h' are architecture-dependent since they encode certain
+ aspects of `libgmp', so it will be necessary to ensure both
+ `$prefix/include' and `$exec_prefix/include' are available to the
+ compiler.
+
+`--disable-shared', `--disable-static'
+ By default both shared and static libraries are built (where
+ possible), but one or other can be disabled. Shared libraries
+ result in smaller executables and permit code sharing between
+ separate running processes, but on some CPUs are slightly slower,
+ having a small cost on each function call.
+
+Native Compilation, `--build=CPU-VENDOR-OS'
+ For normal native compilation, the system can be specified with
+ `--build'. By default `./configure' uses the output from running
+ `./config.guess'. On some systems `./config.guess' can determine
+ the exact CPU type, on others it will be necessary to give it
+ explicitly. For example,
+
+ ./configure --build=ultrasparc-sun-solaris2.7
+
+ In all cases the `OS' part is important, since it controls how
+ libtool generates shared libraries. Running `./config.guess' is
+ the simplest way to see what it should be, if you don't know
+ already.
+
+Cross Compilation, `--host=CPU-VENDOR-OS'
+ When cross-compiling, the system used for compiling is given by
+ `--build' and the system where the library will run is given by
+ `--host'. For example when using a FreeBSD Athlon system to build
+ GNU/Linux m68k binaries,
+
+ ./configure --build=athlon-pc-freebsd3.5 --host=m68k-mac-linux-gnu
+
+ Compiler tools are sought first with the host system type as a
+ prefix. For example `m68k-mac-linux-gnu-ranlib' is tried, then
+ plain `ranlib'. This makes it possible for a set of
+ cross-compiling tools to co-exist with native tools. The prefix
+ is the argument to `--host', and this can be an alias, such as
+ `m68k-linux'. But note that tools don't have to be setup this
+ way, it's enough to just have a `PATH' with a suitable
+ cross-compiling `cc' etc.
+
+ Compiling for a different CPU in the same family as the build
+ system is a form of cross-compilation, though very possibly this
+ would merely be special options on a native compiler. In any case
+ `./configure' avoids depending on being able to run code on the
+ build system, which is important when creating binaries for a
+ newer CPU since they very possibly won't run on the build system.
+
+ In all cases the compiler must be able to produce an executable
+ (of whatever format) from a standard C `main'. Although only
+ object files will go to make up `libgmp', `./configure' uses
+ linking tests for various purposes, such as determining what
+ functions are available on the host system.
+
+ Currently a warning is given unless an explicit `--build' is used
+ when cross-compiling, because it may not be possible to correctly
+ guess the build system type if the `PATH' has only a
+ cross-compiling `cc'.
+
+ Note that the `--target' option is not appropriate for GMP. It's
+ for use when building compiler tools, with `--host' being where
+ they will run, and `--target' what they'll produce code for.
+ Ordinary programs or libraries like GMP are only interested in the
+ `--host' part, being where they'll run. (Some past versions of
+ GMP used `--target' incorrectly.)
+
+CPU types
+ In general, if you want a library that runs as fast as possible,
+ you should configure GMP for the exact CPU type your system uses.
+ However, this may mean the binaries won't run on older members of
+ the family, and might run slower on other members, older or newer.
+ The best idea is always to build GMP for the exact machine type
+ you intend to run it on.
+
+ The following CPUs have specific support. See `configure.ac' for
+ details of what code and compiler options they select.
+
+ * Alpha: alpha, alphaev5, alphaev56, alphapca56, alphapca57,
+ alphaev6, alphaev67, alphaev68 alphaev7
+
+ * Cray: c90, j90, t90, sv1
+
+ * HPPA: hppa1.0, hppa1.1, hppa2.0, hppa2.0n, hppa2.0w, hppa64
+
+ * IA-64: ia64, itanium, itanium2
+
+ * MIPS: mips, mips3, mips64
+
+ * Motorola: m68k, m68000, m68010, m68020, m68030, m68040,
+ m68060, m68302, m68360, m88k, m88110
+
+ * POWER: power, power1, power2, power2sc
+
+ * PowerPC: powerpc, powerpc64, powerpc401, powerpc403,
+ powerpc405, powerpc505, powerpc601, powerpc602, powerpc603,
+ powerpc603e, powerpc604, powerpc604e, powerpc620, powerpc630,
+ powerpc740, powerpc7400, powerpc7450, powerpc750, powerpc801,
+ powerpc821, powerpc823, powerpc860, powerpc970
+
+ * SPARC: sparc, sparcv8, microsparc, supersparc, sparcv9,
+ ultrasparc, ultrasparc2, ultrasparc2i, ultrasparc3, sparc64
+
+ * x86 family: i386, i486, i586, pentium, pentiummmx, pentiumpro,
+ pentium2, pentium3, pentium4, k6, k62, k63, athlon, amd64,
+ viac3, viac32
+
+ * Other: arm, sh, sh2, vax,
+
+ CPUs not listed will use generic C code.
+
+Generic C Build
+ If some of the assembly code causes problems, or if otherwise
+ desired, the generic C code can be selected with the configure
+ `--disable-assembly'.
+
+ Note that this will run quite slowly, but it should be portable
+ and should at least make it possible to get something running if
+ all else fails.
+
+Fat binary, `--enable-fat'
+ Using `--enable-fat' selects a "fat binary" build on x86, where
+ optimized low level subroutines are chosen at runtime according to
+ the CPU detected. This means more code, but gives good
+ performance on all x86 chips. (This option might become available
+ for more architectures in the future.)
+
+`ABI'
+ On some systems GMP supports multiple ABIs (application binary
+ interfaces), meaning data type sizes and calling conventions. By
+ default GMP chooses the best ABI available, but a particular ABI
+ can be selected. For example
+
+ ./configure --host=mips64-sgi-irix6 ABI=n32
+
+ See *note ABI and ISA::, for the available choices on relevant
+ CPUs, and what applications need to do.
+
+`CC', `CFLAGS'
+ By default the C compiler used is chosen from among some likely
+ candidates, with `gcc' normally preferred if it's present. The
+ usual `CC=whatever' can be passed to `./configure' to choose
+ something different.
+
+ For various systems, default compiler flags are set based on the
+ CPU and compiler. The usual `CFLAGS="-whatever"' can be passed to
+ `./configure' to use something different or to set good flags for
+ systems GMP doesn't otherwise know.
+
+ The `CC' and `CFLAGS' used are printed during `./configure', and
+ can be found in each generated `Makefile'. This is the easiest way
+ to check the defaults when considering changing or adding
+ something.
+
+ Note that when `CC' and `CFLAGS' are specified on a system
+ supporting multiple ABIs it's important to give an explicit
+ `ABI=whatever', since GMP can't determine the ABI just from the
+ flags and won't be able to select the correct assembly code.
+
+ If just `CC' is selected then normal default `CFLAGS' for that
+ compiler will be used (if GMP recognises it). For example
+ `CC=gcc' can be used to force the use of GCC, with default flags
+ (and default ABI).
+
+`CPPFLAGS'
+ Any flags like `-D' defines or `-I' includes required by the
+ preprocessor should be set in `CPPFLAGS' rather than `CFLAGS'.
+ Compiling is done with both `CPPFLAGS' and `CFLAGS', but
+ preprocessing uses just `CPPFLAGS'. This distinction is because
+ most preprocessors won't accept all the flags the compiler does.
+ Preprocessing is done separately in some configure tests.
+
+`CC_FOR_BUILD'
+ Some build-time programs are compiled and run to generate
+ host-specific data tables. `CC_FOR_BUILD' is the compiler used
+ for this. It doesn't need to be in any particular ABI or mode, it
+ merely needs to generate executables that can run. The default is
+ to try the selected `CC' and some likely candidates such as `cc'
+ and `gcc', looking for something that works.
+
+ No flags are used with `CC_FOR_BUILD' because a simple invocation
+ like `cc foo.c' should be enough. If some particular options are
+ required they can be included as for instance `CC_FOR_BUILD="cc
+ -whatever"'.
+
+C++ Support, `--enable-cxx'
+ C++ support in GMP can be enabled with `--enable-cxx', in which
+ case a C++ compiler will be required. As a convenience
+ `--enable-cxx=detect' can be used to enable C++ support only if a
+ compiler can be found. The C++ support consists of a library
+ `libgmpxx.la' and header file `gmpxx.h' (*note Headers and
+ Libraries::).
+
+ A separate `libgmpxx.la' has been adopted rather than having C++
+ objects within `libgmp.la' in order to ensure dynamic linked C
+ programs aren't bloated by a dependency on the C++ standard
+ library, and to avoid any chance that the C++ compiler could be
+ required when linking plain C programs.
+
+ `libgmpxx.la' will use certain internals from `libgmp.la' and can
+ only be expected to work with `libgmp.la' from the same GMP
+ version. Future changes to the relevant internals will be
+ accompanied by renaming, so a mismatch will cause unresolved
+ symbols rather than perhaps mysterious misbehaviour.
+
+ In general `libgmpxx.la' will be usable only with the C++ compiler
+ that built it, since name mangling and runtime support are usually
+ incompatible between different compilers.
+
+`CXX', `CXXFLAGS'
+ When C++ support is enabled, the C++ compiler and its flags can be
+ set with variables `CXX' and `CXXFLAGS' in the usual way. The
+ default for `CXX' is the first compiler that works from a list of
+ likely candidates, with `g++' normally preferred when available.
+ The default for `CXXFLAGS' is to try `CFLAGS', `CFLAGS' without
+ `-g', then for `g++' either `-g -O2' or `-O2', or for other
+ compilers `-g' or nothing. Trying `CFLAGS' this way is convenient
+ when using `gcc' and `g++' together, since the flags for `gcc' will
+ usually suit `g++'.
+
+ It's important that the C and C++ compilers match, meaning their
+ startup and runtime support routines are compatible and that they
+ generate code in the same ABI (if there's a choice of ABIs on the
+ system). `./configure' isn't currently able to check these things
+ very well itself, so for that reason `--disable-cxx' is the
+ default, to avoid a build failure due to a compiler mismatch.
+ Perhaps this will change in the future.
+
+ Incidentally, it's normally not good enough to set `CXX' to the
+ same as `CC'. Although `gcc' for instance recognises `foo.cc' as
+ C++ code, only `g++' will invoke the linker the right way when
+ building an executable or shared library from C++ object files.
+
+Temporary Memory, `--enable-alloca=<choice>'
+ GMP allocates temporary workspace using one of the following three
+ methods, which can be selected with for instance
+ `--enable-alloca=malloc-reentrant'.
+
+ * `alloca' - C library or compiler builtin.
+
+ * `malloc-reentrant' - the heap, in a re-entrant fashion.
+
+ * `malloc-notreentrant' - the heap, with global variables.
+
+ For convenience, the following choices are also available.
+ `--disable-alloca' is the same as `no'.
+
+ * `yes' - a synonym for `alloca'.
+
+ * `no' - a synonym for `malloc-reentrant'.
+
+ * `reentrant' - `alloca' if available, otherwise
+ `malloc-reentrant'. This is the default.
+
+ * `notreentrant' - `alloca' if available, otherwise
+ `malloc-notreentrant'.
+
+ `alloca' is reentrant and fast, and is recommended. It actually
+ allocates just small blocks on the stack; larger ones use
+ malloc-reentrant.
+
+ `malloc-reentrant' is, as the name suggests, reentrant and thread
+ safe, but `malloc-notreentrant' is faster and should be used if
+ reentrancy is not required.
+
+ The two malloc methods in fact use the memory allocation functions
+ selected by `mp_set_memory_functions', these being `malloc' and
+ friends by default. *Note Custom Allocation::.
+
+ An additional choice `--enable-alloca=debug' is available, to help
+ when debugging memory related problems (*note Debugging::).
+
+FFT Multiplication, `--disable-fft'
+ By default multiplications are done using Karatsuba, 3-way Toom,
+ higher degree Toom, and Fermat FFT. The FFT is only used on large
+ to very large operands and can be disabled to save code size if
+ desired.
+
+Assertion Checking, `--enable-assert'
+ This option enables some consistency checking within the library.
+ This can be of use while debugging, *note Debugging::.
+
+Execution Profiling, `--enable-profiling=prof/gprof/instrument'
+ Enable profiling support, in one of various styles, *note
+ Profiling::.
+
+`MPN_PATH'
+ Various assembly versions of each mpn subroutines are provided.
+ For a given CPU, a search is made though a path to choose a
+ version of each. For example `sparcv8' has
+
+ MPN_PATH="sparc32/v8 sparc32 generic"
+
+ which means look first for v8 code, then plain sparc32 (which is
+ v7), and finally fall back on generic C. Knowledgeable users with
+ special requirements can specify a different path. Normally this
+ is completely unnecessary.
+
+Documentation
+ The source for the document you're now reading is `doc/gmp.texi',
+ in Texinfo format, see *note Texinfo: (texinfo)Top.
+
+ Info format `doc/gmp.info' is included in the distribution. The
+ usual automake targets are available to make PostScript, DVI, PDF
+ and HTML (these will require various TeX and Texinfo tools).
+
+ DocBook and XML can be generated by the Texinfo `makeinfo' program
+ too, see *note Options for `makeinfo': (texinfo)makeinfo options.
+
+ Some supplementary notes can also be found in the `doc'
+ subdirectory.
+
+
+
+File: gmp.info, Node: ABI and ISA, Next: Notes for Package Builds, Prev: Build Options, Up: Installing GMP
+
+2.2 ABI and ISA
+===============
+
+ABI (Application Binary Interface) refers to the calling conventions
+between functions, meaning what registers are used and what sizes the
+various C data types are. ISA (Instruction Set Architecture) refers to
+the instructions and registers a CPU has available.
+
+ Some 64-bit ISA CPUs have both a 64-bit ABI and a 32-bit ABI
+defined, the latter for compatibility with older CPUs in the family.
+GMP supports some CPUs like this in both ABIs. In fact within GMP
+`ABI' means a combination of chip ABI, plus how GMP chooses to use it.
+For example in some 32-bit ABIs, GMP may support a limb as either a
+32-bit `long' or a 64-bit `long long'.
+
+ By default GMP chooses the best ABI available for a given system,
+and this generally gives significantly greater speed. But an ABI can
+be chosen explicitly to make GMP compatible with other libraries, or
+particular application requirements. For example,
+
+ ./configure ABI=32
+
+ In all cases it's vital that all object code used in a given program
+is compiled for the same ABI.
+
+ Usually a limb is implemented as a `long'. When a `long long' limb
+is used this is encoded in the generated `gmp.h'. This is convenient
+for applications, but it does mean that `gmp.h' will vary, and can't be
+just copied around. `gmp.h' remains compiler independent though, since
+all compilers for a particular ABI will be expected to use the same
+limb type.
+
+ Currently no attempt is made to follow whatever conventions a system
+has for installing library or header files built for a particular ABI.
+This will probably only matter when installing multiple builds of GMP,
+and it might be as simple as configuring with a special `libdir', or it
+might require more than that. Note that builds for different ABIs need
+to done separately, with a fresh `./configure' and `make' each.
+
+
+AMD64 (`x86_64')
+ On AMD64 systems supporting both 32-bit and 64-bit modes for
+ applications, the following ABI choices are available.
+
+ `ABI=64'
+ The 64-bit ABI uses 64-bit limbs and pointers and makes full
+ use of the chip architecture. This is the default.
+ Applications will usually not need special compiler flags,
+ but for reference the option is
+
+ gcc -m64
+
+ `ABI=32'
+ The 32-bit ABI is the usual i386 conventions. This will be
+ slower, and is not recommended except for inter-operating
+ with other code not yet 64-bit capable. Applications must be
+ compiled with
+
+ gcc -m32
+
+ (In GCC 2.95 and earlier there's no `-m32' option, it's the
+ only mode.)
+
+ `ABI=x32'
+ The x32 ABI uses 64-bit limbs but 32-bit pointers. Like the
+ 64-bit ABI, it makes full use of the chip's arithmetic
+ capabilities. This ABI is not supported by all operating
+ systems.
+
+ gcc -mx32
+
+
+
+HPPA 2.0 (`hppa2.0*', `hppa64')
+
+ `ABI=2.0w'
+ The 2.0w ABI uses 64-bit limbs and pointers and is available
+ on HP-UX 11 or up. Applications must be compiled with
+
+ gcc [built for 2.0w]
+ cc +DD64
+
+ `ABI=2.0n'
+ The 2.0n ABI means the 32-bit HPPA 1.0 ABI and all its normal
+ calling conventions, but with 64-bit instructions permitted
+ within functions. GMP uses a 64-bit `long long' for a limb.
+ This ABI is available on hppa64 GNU/Linux and on HP-UX 10 or
+ higher. Applications must be compiled with
+
+ gcc [built for 2.0n]
+ cc +DA2.0 +e
+
+ Note that current versions of GCC (eg. 3.2) don't generate
+ 64-bit instructions for `long long' operations and so may be
+ slower than for 2.0w. (The GMP assembly code is the same
+ though.)
+
+ `ABI=1.0'
+ HPPA 2.0 CPUs can run all HPPA 1.0 and 1.1 code in the 32-bit
+ HPPA 1.0 ABI. No special compiler options are needed for
+ applications.
+
+ All three ABIs are available for CPU types `hppa2.0w', `hppa2.0'
+ and `hppa64', but for CPU type `hppa2.0n' only 2.0n or 1.0 are
+ considered.
+
+ Note that GCC on HP-UX has no options to choose between 2.0n and
+ 2.0w modes, unlike HP `cc'. Instead it must be built for one or
+ the other ABI. GMP will detect how it was built, and skip to the
+ corresponding `ABI'.
+
+
+IA-64 under HP-UX (`ia64*-*-hpux*', `itanium*-*-hpux*')
+ HP-UX supports two ABIs for IA-64. GMP performance is the same in
+ both.
+
+ `ABI=32'
+ In the 32-bit ABI, pointers, `int's and `long's are 32 bits
+ and GMP uses a 64 bit `long long' for a limb. Applications
+ can be compiled without any special flags since this ABI is
+ the default in both HP C and GCC, but for reference the flags
+ are
+
+ gcc -milp32
+ cc +DD32
+
+ `ABI=64'
+ In the 64-bit ABI, `long's and pointers are 64 bits and GMP
+ uses a `long' for a limb. Applications must be compiled with
+
+ gcc -mlp64
+ cc +DD64
+
+ On other IA-64 systems, GNU/Linux for instance, `ABI=64' is the
+ only choice.
+
+
+MIPS under IRIX 6 (`mips*-*-irix[6789]')
+ IRIX 6 always has a 64-bit MIPS 3 or better CPU, and supports ABIs
+ o32, n32, and 64. n32 or 64 are recommended, and GMP performance
+ will be the same in each. The default is n32.
+
+ `ABI=o32'
+ The o32 ABI is 32-bit pointers and integers, and no 64-bit
+ operations. GMP will be slower than in n32 or 64, this
+ option only exists to support old compilers, eg. GCC 2.7.2.
+ Applications can be compiled with no special flags on an old
+ compiler, or on a newer compiler with
+
+ gcc -mabi=32
+ cc -32
+
+ `ABI=n32'
+ The n32 ABI is 32-bit pointers and integers, but with a
+ 64-bit limb using a `long long'. Applications must be
+ compiled with
+
+ gcc -mabi=n32
+ cc -n32
+
+ `ABI=64'
+ The 64-bit ABI is 64-bit pointers and integers. Applications
+ must be compiled with
+
+ gcc -mabi=64
+ cc -64
+
+ Note that MIPS GNU/Linux, as of kernel version 2.2, doesn't have
+ the necessary support for n32 or 64 and so only gets a 32-bit limb
+ and the MIPS 2 code.
+
+
+PowerPC 64 (`powerpc64', `powerpc620', `powerpc630', `powerpc970', `power4', `power5')
+
+ `ABI=mode64'
+ The AIX 64 ABI uses 64-bit limbs and pointers and is the
+ default on PowerPC 64 `*-*-aix*' systems. Applications must
+ be compiled with
+
+ gcc -maix64
+ xlc -q64
+
+ On 64-bit GNU/Linux, BSD, and Mac OS X/Darwin systems, the
+ applications must be compiled with
+
+ gcc -m64
+
+ `ABI=mode32'
+ The `mode32' ABI uses a 64-bit `long long' limb but with the
+ chip still in 32-bit mode and using 32-bit calling
+ conventions. This is the default for systems where the true
+ 64-bit ABI is unavailable. No special compiler options are
+ typically needed for applications. This ABI is not available
+ under AIX.
+
+ `ABI=32'
+ This is the basic 32-bit PowerPC ABI, with a 32-bit limb. No
+ special compiler options are needed for applications.
+
+ GMP's speed is greatest for the `mode64' ABI, the `mode32' ABI is
+ 2nd best. In `ABI=32' only the 32-bit ISA is used and this
+ doesn't make full use of a 64-bit chip.
+
+
+Sparc V9 (`sparc64', `sparcv9', `ultrasparc*')
+
+ `ABI=64'
+ The 64-bit V9 ABI is available on the various BSD sparc64
+ ports, recent versions of Sparc64 GNU/Linux, and Solaris 2.7
+ and up (when the kernel is in 64-bit mode). GCC 3.2 or
+ higher, or Sun `cc' is required. On GNU/Linux, depending on
+ the default `gcc' mode, applications must be compiled with
+
+ gcc -m64
+
+ On Solaris applications must be compiled with
+
+ gcc -m64 -mptr64 -Wa,-xarch=v9 -mcpu=v9
+ cc -xarch=v9
+
+ On the BSD sparc64 systems no special options are required,
+ since 64-bits is the only ABI available.
+
+ `ABI=32'
+ For the basic 32-bit ABI, GMP still uses as much of the V9
+ ISA as it can. In the Sun documentation this combination is
+ known as "v8plus". On GNU/Linux, depending on the default
+ `gcc' mode, applications may need to be compiled with
+
+ gcc -m32
+
+ On Solaris, no special compiler options are required for
+ applications, though using something like the following is
+ recommended. (`gcc' 2.8 and earlier only support `-mv8'
+ though.)
+
+ gcc -mv8plus
+ cc -xarch=v8plus
+
+ GMP speed is greatest in `ABI=64', so it's the default where
+ available. The speed is partly because there are extra registers
+ available and partly because 64-bits is considered the more
+ important case and has therefore had better code written for it.
+
+ Don't be confused by the names of the `-m' and `-x' compiler
+ options, they're called `arch' but effectively control both ABI
+ and ISA.
+
+ On Solaris 2.6 and earlier, only `ABI=32' is available since the
+ kernel doesn't save all registers.
+
+ On Solaris 2.7 with the kernel in 32-bit mode, a normal native
+ build will reject `ABI=64' because the resulting executables won't
+ run. `ABI=64' can still be built if desired by making it look
+ like a cross-compile, for example
+
+ ./configure --build=none --host=sparcv9-sun-solaris2.7 ABI=64
+
+
+File: gmp.info, Node: Notes for Package Builds, Next: Notes for Particular Systems, Prev: ABI and ISA, Up: Installing GMP
+
+2.3 Notes for Package Builds
+============================
+
+GMP should present no great difficulties for packaging in a binary
+distribution.
+
+ Libtool is used to build the library and `-version-info' is set
+appropriately, having started from `3:0:0' in GMP 3.0 (*note Library
+interface versions: (libtool)Versioning.).
+
+ The GMP 4 series will be upwardly binary compatible in each release
+and will be upwardly binary compatible with all of the GMP 3 series.
+Additional function interfaces may be added in each release, so on
+systems where libtool versioning is not fully checked by the loader an
+auxiliary mechanism may be needed to express that a dynamic linked
+application depends on a new enough GMP.
+
+ An auxiliary mechanism may also be needed to express that
+`libgmpxx.la' (from `--enable-cxx', *note Build Options::) requires
+`libgmp.la' from the same GMP version, since this is not done by the
+libtool versioning, nor otherwise. A mismatch will result in
+unresolved symbols from the linker, or perhaps the loader.
+
+ When building a package for a CPU family, care should be taken to use
+`--host' (or `--build') to choose the least common denominator among
+the CPUs which might use the package. For example this might mean plain
+`sparc' (meaning V7) for SPARCs.
+
+ For x86s, `--enable-fat' sets things up for a fat binary build,
+making a runtime selection of optimized low level routines. This is a
+good choice for packaging to run on a range of x86 chips.
+
+ Users who care about speed will want GMP built for their exact CPU
+type, to make best use of the available optimizations. Providing a way
+to suitably rebuild a package may be useful. This could be as simple
+as making it possible for a user to omit `--build' (and `--host') so
+`./config.guess' will detect the CPU. But a way to manually specify a
+`--build' will be wanted for systems where `./config.guess' is inexact.
+
+ On systems with multiple ABIs, a packaged build will need to decide
+which among the choices is to be provided, see *note ABI and ISA::. A
+given run of `./configure' etc will only build one ABI. If a second
+ABI is also required then a second run of `./configure' etc must be
+made, starting from a clean directory tree (`make distclean').
+
+ As noted under "ABI and ISA", currently no attempt is made to follow
+system conventions for install locations that vary with ABI, such as
+`/usr/lib/sparcv9' for `ABI=64' as opposed to `/usr/lib' for `ABI=32'.
+A package build can override `libdir' and other standard variables as
+necessary.
+
+ Note that `gmp.h' is a generated file, and will be architecture and
+ABI dependent. When attempting to install two ABIs simultaneously it
+will be important that an application compile gets the correct `gmp.h'
+for its desired ABI. If compiler include paths don't vary with ABI
+options then it might be necessary to create a `/usr/include/gmp.h'
+which tests preprocessor symbols and chooses the correct actual `gmp.h'.
+
+
+File: gmp.info, Node: Notes for Particular Systems, Next: Known Build Problems, Prev: Notes for Package Builds, Up: Installing GMP
+
+2.4 Notes for Particular Systems
+================================
+
+AIX 3 and 4
+ On systems `*-*-aix[34]*' shared libraries are disabled by
+ default, since some versions of the native `ar' fail on the
+ convenience libraries used. A shared build can be attempted with
+
+ ./configure --enable-shared --disable-static
+
+ Note that the `--disable-static' is necessary because in a shared
+ build libtool makes `libgmp.a' a symlink to `libgmp.so',
+ apparently for the benefit of old versions of `ld' which only
+ recognise `.a', but unfortunately this is done even if a fully
+ functional `ld' is available.
+
+ARM
+ On systems `arm*-*-*', versions of GCC up to and including 2.95.3
+ have a bug in unsigned division, giving wrong results for some
+ operands. GMP `./configure' will demand GCC 2.95.4 or later.
+
+Compaq C++
+ Compaq C++ on OSF 5.1 has two flavours of `iostream', a standard
+ one and an old pre-standard one (see `man iostream_intro'). GMP
+ can only use the standard one, which unfortunately is not the
+ default but must be selected by defining `__USE_STD_IOSTREAM'.
+ Configure with for instance
+
+ ./configure --enable-cxx CPPFLAGS=-D__USE_STD_IOSTREAM
+
+Floating Point Mode
+ On some systems, the hardware floating point has a control mode
+ which can set all operations to be done in a particular precision,
+ for instance single, double or extended on x86 systems (x87
+ floating point). The GMP functions involving a `double' cannot be
+ expected to operate to their full precision when the hardware is
+ in single precision mode. Of course this affects all code,
+ including application code, not just GMP.
+
+FreeBSD 7.x, 8.x, 9.0, 9.1, 9.2
+ `m4' in these releases of FreeBSD has an eval function which
+ ignores its 2nd and 3rd arguments, which makes it unsuitable for
+ `.asm' file processing. `./configure' will detect the problem and
+ either abort or choose another m4 in the `PATH'. The bug is fixed
+ in FreeBSD 9.3 and 10.0, so either upgrade or use GNU m4. Note
+ that the FreeBSD package system installs GNU m4 under the name
+ `gm4', which GMP cannot guess.
+
+FreeBSD 7.x, 8.x, 9.x
+ GMP releases starting with 6.0 do not support `ABI=32' on
+ FreeBSD/amd64 prior to release 10.0 of the system. The cause is a
+ broken `limits.h', which GMP no longer works around.
+
+MS-DOS and MS Windows
+ On an MS-DOS system DJGPP can be used to build GMP, and on an MS
+ Windows system Cygwin, DJGPP and MINGW can be used. All three are
+ excellent ports of GCC and the various GNU tools.
+
+ `http://www.cygwin.com/'
+ `http://www.delorie.com/djgpp/'
+ `http://www.mingw.org/'
+
+ Microsoft also publishes an Interix "Services for Unix" which can
+ be used to build GMP on Windows (with a normal `./configure'), but
+ it's not free software.
+
+MS Windows DLLs
+ On systems `*-*-cygwin*', `*-*-mingw*' and `*-*-pw32*' by default
+ GMP builds only a static library, but a DLL can be built instead
+ using
+
+ ./configure --disable-static --enable-shared
+
+ Static and DLL libraries can't both be built, since certain export
+ directives in `gmp.h' must be different.
+
+ A MINGW DLL build of GMP can be used with Microsoft C. Libtool
+ doesn't install a `.lib' format import library, but it can be
+ created with MS `lib' as follows, and copied to the install
+ directory. Similarly for `libmp' and `libgmpxx'.
+
+ cd .libs
+ lib /def:libgmp-3.dll.def /out:libgmp-3.lib
+
+ MINGW uses the C runtime library `msvcrt.dll' for I/O, so
+ applications wanting to use the GMP I/O routines must be compiled
+ with `cl /MD' to do the same. If one of the other C runtime
+ library choices provided by MS C is desired then the suggestion is
+ to use the GMP string functions and confine I/O to the application.
+
+Motorola 68k CPU Types
+ `m68k' is taken to mean 68000. `m68020' or higher will give a
+ performance boost on applicable CPUs. `m68360' can be used for
+ CPU32 series chips. `m68302' can be used for "Dragonball" series
+ chips, though this is merely a synonym for `m68000'.
+
+NetBSD 5.x
+ `m4' in these releases of NetBSD has an eval function which
+ ignores its 2nd and 3rd arguments, which makes it unsuitable for
+ `.asm' file processing. `./configure' will detect the problem and
+ either abort or choose another m4 in the `PATH'. The bug is fixed
+ in NetBSD 6, so either upgrade or use GNU m4. Note that the
+ NetBSD package system installs GNU m4 under the name `gm4', which
+ GMP cannot guess.
+
+OpenBSD 2.6
+ `m4' in this release of OpenBSD has a bug in `eval' that makes it
+ unsuitable for `.asm' file processing. `./configure' will detect
+ the problem and either abort or choose another m4 in the `PATH'.
+ The bug is fixed in OpenBSD 2.7, so either upgrade or use GNU m4.
+
+Power CPU Types
+ In GMP, CPU types `power*' and `powerpc*' will each use
+ instructions not available on the other, so it's important to
+ choose the right one for the CPU that will be used. Currently GMP
+ has no assembly code support for using just the common instruction
+ subset. To get executables that run on both, the current
+ suggestion is to use the generic C code (`--disable-assembly'),
+ possibly with appropriate compiler options (like `-mcpu=common' for
+ `gcc'). CPU `rs6000' (which is not a CPU but a family of
+ workstations) is accepted by `config.sub', but is currently
+ equivalent to `--disable-assembly'.
+
+Sparc CPU Types
+ `sparcv8' or `supersparc' on relevant systems will give a
+ significant performance increase over the V7 code selected by plain
+ `sparc'.
+
+Sparc App Regs
+ The GMP assembly code for both 32-bit and 64-bit Sparc clobbers the
+ "application registers" `g2', `g3' and `g4', the same way that the
+ GCC default `-mapp-regs' does (*note SPARC Options: (gcc)SPARC
+ Options.).
+
+ This makes that code unsuitable for use with the special V9
+ `-mcmodel=embmedany' (which uses `g4' as a data segment pointer),
+ and for applications wanting to use those registers for special
+ purposes. In these cases the only suggestion currently is to
+ build GMP with `--disable-assembly' to avoid the assembly code.
+
+SunOS 4
+ `/usr/bin/m4' lacks various features needed to process `.asm'
+ files, and instead `./configure' will automatically use
+ `/usr/5bin/m4', which we believe is always available (if not then
+ use GNU m4).
+
+x86 CPU Types
+ `i586', `pentium' or `pentiummmx' code is good for its intended P5
+ Pentium chips, but quite slow when run on Intel P6 class chips
+ (PPro, P-II, P-III). `i386' is a better choice when making
+ binaries that must run on both.
+
+x86 MMX and SSE2 Code
+ If the CPU selected has MMX code but the assembler doesn't support
+ it, a warning is given and non-MMX code is used instead. This
+ will be an inferior build, since the MMX code that's present is
+ there because it's faster than the corresponding plain integer
+ code. The same applies to SSE2.
+
+ Old versions of `gas' don't support MMX instructions, in particular
+ version 1.92.3 that comes with FreeBSD 2.2.8 or the more recent
+ OpenBSD 3.1 doesn't.
+
+ Solaris 2.6 and 2.7 `as' generate incorrect object code for
+ register to register `movq' instructions, and so can't be used for
+ MMX code. Install a recent `gas' if MMX code is wanted on these
+ systems.
+
+
+File: gmp.info, Node: Known Build Problems, Next: Performance optimization, Prev: Notes for Particular Systems, Up: Installing GMP
+
+2.5 Known Build Problems
+========================
+
+You might find more up-to-date information at `https://gmplib.org/'.
+
+Compiler link options
+ The version of libtool currently in use rather aggressively strips
+ compiler options when linking a shared library. This will
+ hopefully be relaxed in the future, but for now if this is a
+ problem the suggestion is to create a little script to hide them,
+ and for instance configure with
+
+ ./configure CC=gcc-with-my-options
+
+DJGPP (`*-*-msdosdjgpp*')
+ The DJGPP port of `bash' 2.03 is unable to run the `configure'
+ script, it exits silently, having died writing a preamble to
+ `config.log'. Use `bash' 2.04 or higher.
+
+ `make all' was found to run out of memory during the final
+ `libgmp.la' link on one system tested, despite having 64Mb
+ available. Running `make libgmp.la' directly helped, perhaps
+ recursing into the various subdirectories uses up memory.
+
+GNU binutils `strip' prior to 2.12
+ `strip' from GNU binutils 2.11 and earlier should not be used on
+ the static libraries `libgmp.a' and `libmp.a' since it will
+ discard all but the last of multiple archive members with the same
+ name, like the three versions of `init.o' in `libgmp.a'. Binutils
+ 2.12 or higher can be used successfully.
+
+ The shared libraries `libgmp.so' and `libmp.so' are not affected by
+ this and any version of `strip' can be used on them.
+
+`make' syntax error
+ On certain versions of SCO OpenServer 5 and IRIX 6.5 the native
+ `make' is unable to handle the long dependencies list for
+ `libgmp.la'. The symptom is a "syntax error" on the following
+ line of the top-level `Makefile'.
+
+ libgmp.la: $(libgmp_la_OBJECTS) $(libgmp_la_DEPENDENCIES)
+
+ Either use GNU Make, or as a workaround remove
+ `$(libgmp_la_DEPENDENCIES)' from that line (which will make the
+ initial build work, but if any recompiling is done `libgmp.la'
+ might not be rebuilt).
+
+MacOS X (`*-*-darwin*')
+ Libtool currently only knows how to create shared libraries on
+ MacOS X using the native `cc' (which is a modified GCC), not a
+ plain GCC. A static-only build should work though
+ (`--disable-shared').
+
+NeXT prior to 3.3
+ The system compiler on old versions of NeXT was a massacred and
+ old GCC, even if it called itself `cc'. This compiler cannot be
+ used to build GMP, you need to get a real GCC, and install that.
+ (NeXT may have fixed this in release 3.3 of their system.)
+
+POWER and PowerPC
+ Bugs in GCC 2.7.2 (and 2.6.3) mean it can't be used to compile GMP
+ on POWER or PowerPC. If you want to use GCC for these machines,
+ get GCC 2.7.2.1 (or later).
+
+Sequent Symmetry
+ Use the GNU assembler instead of the system assembler, since the
+ latter has serious bugs.
+
+Solaris 2.6
+ The system `sed' prints an error "Output line too long" when
+ libtool builds `libgmp.la'. This doesn't seem to cause any
+ obvious ill effects, but GNU `sed' is recommended, to avoid any
+ doubt.
+
+Sparc Solaris 2.7 with gcc 2.95.2 in `ABI=32'
+ A shared library build of GMP seems to fail in this combination,
+ it builds but then fails the tests, apparently due to some
+ incorrect data relocations within `gmp_randinit_lc_2exp_size'.
+ The exact cause is unknown, `--disable-shared' is recommended.
+
+
+File: gmp.info, Node: Performance optimization, Prev: Known Build Problems, Up: Installing GMP
+
+2.6 Performance optimization
+============================
+
+For optimal performance, build GMP for the exact CPU type of the target
+computer, see *note Build Options::.
+
+ Unlike what is the case for most other programs, the compiler
+typically doesn't matter much, since GMP uses assembly language for the
+most critical operation.
+
+ In particular for long-running GMP applications, and applications
+demanding extremely large numbers, building and running the `tuneup'
+program in the `tune' subdirectory, can be important. For example,
+
+ cd tune
+ make tuneup
+ ./tuneup
+
+ will generate better contents for the `gmp-mparam.h' parameter file.
+
+ To use the results, put the output in the file indicated in the
+`Parameters for ...' header. Then recompile from scratch.
+
+ The `tuneup' program takes one useful parameter, `-f NNN', which
+instructs the program how long to check FFT multiply parameters. If
+you're going to use GMP for extremely large numbers, you may want to
+run `tuneup' with a large NNN value.
+
+
+File: gmp.info, Node: GMP Basics, Next: Reporting Bugs, Prev: Installing GMP, Up: Top
+
+3 GMP Basics
+************
+
+*Using functions, macros, data types, etc. not documented in this
+manual is strongly discouraged. If you do so your application is
+guaranteed to be incompatible with future versions of GMP.*
+
+* Menu:
+
+* Headers and Libraries::
+* Nomenclature and Types::
+* Function Classes::
+* Variable Conventions::
+* Parameter Conventions::
+* Memory Management::
+* Reentrancy::
+* Useful Macros and Constants::
+* Compatibility with older versions::
+* Demonstration Programs::
+* Efficiency::
+* Debugging::
+* Profiling::
+* Autoconf::
+* Emacs::
+
+
+File: gmp.info, Node: Headers and Libraries, Next: Nomenclature and Types, Prev: GMP Basics, Up: GMP Basics
+
+3.1 Headers and Libraries
+=========================
+
+All declarations needed to use GMP are collected in the include file
+`gmp.h'. It is designed to work with both C and C++ compilers.
+
+ #include <gmp.h>
+
+ Note however that prototypes for GMP functions with `FILE *'
+parameters are only provided if `<stdio.h>' is included too.
+
+ #include <stdio.h>
+ #include <gmp.h>
+
+ Likewise `<stdarg.h>' is required for prototypes with `va_list'
+parameters, such as `gmp_vprintf'. And `<obstack.h>' for prototypes
+with `struct obstack' parameters, such as `gmp_obstack_printf', when
+available.
+
+ All programs using GMP must link against the `libgmp' library. On a
+typical Unix-like system this can be done with `-lgmp', for example
+
+ gcc myprogram.c -lgmp
+
+ GMP C++ functions are in a separate `libgmpxx' library. This is
+built and installed if C++ support has been enabled (*note Build
+Options::). For example,
+
+ g++ mycxxprog.cc -lgmpxx -lgmp
+
+ GMP is built using Libtool and an application can use that to link
+if desired, *note GNU Libtool: (libtool)Top.
+
+ If GMP has been installed to a non-standard location then it may be
+necessary to use `-I' and `-L' compiler options to point to the right
+directories, and some sort of run-time path for a shared library.
+
+
+File: gmp.info, Node: Nomenclature and Types, Next: Function Classes, Prev: Headers and Libraries, Up: GMP Basics
+
+3.2 Nomenclature and Types
+==========================
+
+In this manual, "integer" usually means a multiple precision integer, as
+defined by the GMP library. The C data type for such integers is
+`mpz_t'. Here are some examples of how to declare such integers:
+
+ mpz_t sum;
+
+ struct foo { mpz_t x, y; };
+
+ mpz_t vec[20];
+
+ "Rational number" means a multiple precision fraction. The C data
+type for these fractions is `mpq_t'. For example:
+
+ mpq_t quotient;
+
+ "Floating point number" or "Float" for short, is an arbitrary
+precision mantissa with a limited precision exponent. The C data type
+for such objects is `mpf_t'. For example:
+
+ mpf_t fp;
+
+ The floating point functions accept and return exponents in the C
+type `mp_exp_t'. Currently this is usually a `long', but on some
+systems it's an `int' for efficiency.
+
+ A "limb" means the part of a multi-precision number that fits in a
+single machine word. (We chose this word because a limb of the human
+body is analogous to a digit, only larger, and containing several
+digits.) Normally a limb is 32 or 64 bits. The C data type for a limb
+is `mp_limb_t'.
+
+ Counts of limbs of a multi-precision number represented in the C type
+`mp_size_t'. Currently this is normally a `long', but on some systems
+it's an `int' for efficiency, and on some systems it will be `long
+long' in the future.
+
+ Counts of bits of a multi-precision number are represented in the C
+type `mp_bitcnt_t'. Currently this is always an `unsigned long', but on
+some systems it will be an `unsigned long long' in the future.
+
+ "Random state" means an algorithm selection and current state data.
+The C data type for such objects is `gmp_randstate_t'. For example:
+
+ gmp_randstate_t rstate;
+
+ Also, in general `mp_bitcnt_t' is used for bit counts and ranges, and
+`size_t' is used for byte or character counts.
+
+
+File: gmp.info, Node: Function Classes, Next: Variable Conventions, Prev: Nomenclature and Types, Up: GMP Basics
+
+3.3 Function Classes
+====================
+
+There are six classes of functions in the GMP library:
+
+ 1. Functions for signed integer arithmetic, with names beginning with
+ `mpz_'. The associated type is `mpz_t'. There are about 150
+ functions in this class. (*note Integer Functions::)
+
+ 2. Functions for rational number arithmetic, with names beginning with
+ `mpq_'. The associated type is `mpq_t'. There are about 35
+ functions in this class, but the integer functions can be used for
+ arithmetic on the numerator and denominator separately. (*note
+ Rational Number Functions::)
+
+ 3. Functions for floating-point arithmetic, with names beginning with
+ `mpf_'. The associated type is `mpf_t'. There are about 70
+ functions is this class. (*note Floating-point Functions::)
+
+ 4. Fast low-level functions that operate on natural numbers. These
+ are used by the functions in the preceding groups, and you can
+ also call them directly from very time-critical user programs.
+ These functions' names begin with `mpn_'. The associated type is
+ array of `mp_limb_t'. There are about 60 (hard-to-use) functions
+ in this class. (*note Low-level Functions::)
+
+ 5. Miscellaneous functions. Functions for setting up custom
+ allocation and functions for generating random numbers. (*note
+ Custom Allocation::, and *note Random Number Functions::)
+
+
+File: gmp.info, Node: Variable Conventions, Next: Parameter Conventions, Prev: Function Classes, Up: GMP Basics
+
+3.4 Variable Conventions
+========================
+
+GMP functions generally have output arguments before input arguments.
+This notation is by analogy with the assignment operator. The BSD MP
+compatibility functions are exceptions, having the output arguments
+last.
+
+ GMP lets you use the same variable for both input and output in one
+call. For example, the main function for integer multiplication,
+`mpz_mul', can be used to square `x' and put the result back in `x' with
+
+ mpz_mul (x, x, x);
+
+ Before you can assign to a GMP variable, you need to initialize it
+by calling one of the special initialization functions. When you're
+done with a variable, you need to clear it out, using one of the
+functions for that purpose. Which function to use depends on the type
+of variable. See the chapters on integer functions, rational number
+functions, and floating-point functions for details.
+
+ A variable should only be initialized once, or at least cleared
+between each initialization. After a variable has been initialized, it
+may be assigned to any number of times.
+
+ For efficiency reasons, avoid excessive initializing and clearing.
+In general, initialize near the start of a function and clear near the
+end. For example,
+
+ void
+ foo (void)
+ {
+ mpz_t n;
+ int i;
+ mpz_init (n);
+ for (i = 1; i < 100; i++)
+ {
+ mpz_mul (n, ...);
+ mpz_fdiv_q (n, ...);
+ ...
+ }
+ mpz_clear (n);
+ }
+
+
+File: gmp.info, Node: Parameter Conventions, Next: Memory Management, Prev: Variable Conventions, Up: GMP Basics
+
+3.5 Parameter Conventions
+=========================
+
+When a GMP variable is used as a function parameter, it's effectively a
+call-by-reference, meaning if the function stores a value there it will
+change the original in the caller. Parameters which are input-only can
+be designated `const' to provoke a compiler error or warning on
+attempting to modify them.
+
+ When a function is going to return a GMP result, it should designate
+a parameter that it sets, like the library functions do. More than one
+value can be returned by having more than one output parameter, again
+like the library functions. A `return' of an `mpz_t' etc doesn't
+return the object, only a pointer, and this is almost certainly not
+what's wanted.
+
+ Here's an example accepting an `mpz_t' parameter, doing a
+calculation, and storing the result to the indicated parameter.
+
+ void
+ foo (mpz_t result, const mpz_t param, unsigned long n)
+ {
+ unsigned long i;
+ mpz_mul_ui (result, param, n);
+ for (i = 1; i < n; i++)
+ mpz_add_ui (result, result, i*7);
+ }
+
+ int
+ main (void)
+ {
+ mpz_t r, n;
+ mpz_init (r);
+ mpz_init_set_str (n, "123456", 0);
+ foo (r, n, 20L);
+ gmp_printf ("%Zd\n", r);
+ return 0;
+ }
+
+ `foo' works even if the mainline passes the same variable for
+`param' and `result', just like the library functions. But sometimes
+it's tricky to make that work, and an application might not want to
+bother supporting that sort of thing.
+
+ For interest, the GMP types `mpz_t' etc are implemented as
+one-element arrays of certain structures. This is why declaring a
+variable creates an object with the fields GMP needs, but then using it
+as a parameter passes a pointer to the object. Note that the actual
+fields in each `mpz_t' etc are for internal use only and should not be
+accessed directly by code that expects to be compatible with future GMP
+releases.
+
+
+File: gmp.info, Node: Memory Management, Next: Reentrancy, Prev: Parameter Conventions, Up: GMP Basics
+
+3.6 Memory Management
+=====================
+
+The GMP types like `mpz_t' are small, containing only a couple of sizes,
+and pointers to allocated data. Once a variable is initialized, GMP
+takes care of all space allocation. Additional space is allocated
+whenever a variable doesn't have enough.
+
+ `mpz_t' and `mpq_t' variables never reduce their allocated space.
+Normally this is the best policy, since it avoids frequent reallocation.
+Applications that need to return memory to the heap at some particular
+point can use `mpz_realloc2', or clear variables no longer needed.
+
+ `mpf_t' variables, in the current implementation, use a fixed amount
+of space, determined by the chosen precision and allocated at
+initialization, so their size doesn't change.
+
+ All memory is allocated using `malloc' and friends by default, but
+this can be changed, see *note Custom Allocation::. Temporary memory
+on the stack is also used (via `alloca'), but this can be changed at
+build-time if desired, see *note Build Options::.
+
+
+File: gmp.info, Node: Reentrancy, Next: Useful Macros and Constants, Prev: Memory Management, Up: GMP Basics
+
+3.7 Reentrancy
+==============
+
+GMP is reentrant and thread-safe, with some exceptions:
+
+ * If configured with `--enable-alloca=malloc-notreentrant' (or with
+ `--enable-alloca=notreentrant' when `alloca' is not available),
+ then naturally GMP is not reentrant.
+
+ * `mpf_set_default_prec' and `mpf_init' use a global variable for the
+ selected precision. `mpf_init2' can be used instead, and in the
+ C++ interface an explicit precision to the `mpf_class' constructor.
+
+ * `mpz_random' and the other old random number functions use a global
+ random state and are hence not reentrant. The newer random number
+ functions that accept a `gmp_randstate_t' parameter can be used
+ instead.
+
+ * `gmp_randinit' (obsolete) returns an error indication through a
+ global variable, which is not thread safe. Applications are
+ advised to use `gmp_randinit_default' or `gmp_randinit_lc_2exp'
+ instead.
+
+ * `mp_set_memory_functions' uses global variables to store the
+ selected memory allocation functions.
+
+ * If the memory allocation functions set by a call to
+ `mp_set_memory_functions' (or `malloc' and friends by default) are
+ not reentrant, then GMP will not be reentrant either.
+
+ * If the standard I/O functions such as `fwrite' are not reentrant
+ then the GMP I/O functions using them will not be reentrant either.
+
+ * It's safe for two threads to read from the same GMP variable
+ simultaneously, but it's not safe for one to read while another
+ might be writing, nor for two threads to write simultaneously.
+ It's not safe for two threads to generate a random number from the
+ same `gmp_randstate_t' simultaneously, since this involves an
+ update of that variable.
+
+
+File: gmp.info, Node: Useful Macros and Constants, Next: Compatibility with older versions, Prev: Reentrancy, Up: GMP Basics
+
+3.8 Useful Macros and Constants
+===============================
+
+ -- Global Constant: const int mp_bits_per_limb
+ The number of bits per limb.
+
+ -- Macro: __GNU_MP_VERSION
+ -- Macro: __GNU_MP_VERSION_MINOR
+ -- Macro: __GNU_MP_VERSION_PATCHLEVEL
+ The major and minor GMP version, and patch level, respectively, as
+ integers. For GMP i.j, these numbers will be i, j, and 0,
+ respectively. For GMP i.j.k, these numbers will be i, j, and k,
+ respectively.
+
+ -- Global Constant: const char * const gmp_version
+ The GMP version number, as a null-terminated string, in the form
+ "i.j.k". This release is "6.0.0". Note that the format "i.j" was
+ used, before version 4.3.0, when k was zero.
+
+ -- Macro: __GMP_CC
+ -- Macro: __GMP_CFLAGS
+ The compiler and compiler flags, respectively, used when compiling
+ GMP, as strings.
+
+
+File: gmp.info, Node: Compatibility with older versions, Next: Demonstration Programs, Prev: Useful Macros and Constants, Up: GMP Basics
+
+3.9 Compatibility with older versions
+=====================================
+
+This version of GMP is upwardly binary compatible with all 5.x, 4.x,
+and 3.x versions, and upwardly compatible at the source level with all
+2.x versions, with the following exceptions.
+
+ * `mpn_gcd' had its source arguments swapped as of GMP 3.0, for
+ consistency with other `mpn' functions.
+
+ * `mpf_get_prec' counted precision slightly differently in GMP 3.0
+ and 3.0.1, but in 3.1 reverted to the 2.x style.
+
+ * `mpn_bdivmod', documented as preliminary in GMP 4, has been
+ removed.
+
+ There are a number of compatibility issues between GMP 1 and GMP 2
+that of course also apply when porting applications from GMP 1 to GMP
+5. Please see the GMP 2 manual for details.
+
+
+File: gmp.info, Node: Demonstration Programs, Next: Efficiency, Prev: Compatibility with older versions, Up: GMP Basics
+
+3.10 Demonstration programs
+===========================
+
+The `demos' subdirectory has some sample programs using GMP. These
+aren't built or installed, but there's a `Makefile' with rules for them.
+For instance,
+
+ make pexpr
+ ./pexpr 68^975+10
+
+The following programs are provided
+
+ * `pexpr' is an expression evaluator, the program used on the GMP
+ web page.
+
+ * The `calc' subdirectory has a similar but simpler evaluator using
+ `lex' and `yacc'.
+
+ * The `expr' subdirectory is yet another expression evaluator, a
+ library designed for ease of use within a C program. See
+ `demos/expr/README' for more information.
+
+ * `factorize' is a Pollard-Rho factorization program.
+
+ * `isprime' is a command-line interface to the `mpz_probab_prime_p'
+ function.
+
+ * `primes' counts or lists primes in an interval, using a sieve.
+
+ * `qcn' is an example use of `mpz_kronecker_ui' to estimate quadratic
+ class numbers.
+
+ * The `perl' subdirectory is a comprehensive perl interface to GMP.
+ See `demos/perl/INSTALL' for more information. Documentation is
+ in POD format in `demos/perl/GMP.pm'.
+
+ As an aside, consideration has been given at various times to some
+sort of expression evaluation within the main GMP library. Going
+beyond something minimal quickly leads to matters like user-defined
+functions, looping, fixnums for control variables, etc, which are
+considered outside the scope of GMP (much closer to language
+interpreters or compilers, *Note Language Bindings::.) Something
+simple for program input convenience may yet be a possibility, a
+combination of the `expr' demo and the `pexpr' tree back-end perhaps.
+But for now the above evaluators are offered as illustrations.
+
+
+File: gmp.info, Node: Efficiency, Next: Debugging, Prev: Demonstration Programs, Up: GMP Basics
+
+3.11 Efficiency
+===============
+
+Small Operands
+ On small operands, the time for function call overheads and memory
+ allocation can be significant in comparison to actual calculation.
+ This is unavoidable in a general purpose variable precision
+ library, although GMP attempts to be as efficient as it can on
+ both large and small operands.
+
+Static Linking
+ On some CPUs, in particular the x86s, the static `libgmp.a' should
+ be used for maximum speed, since the PIC code in the shared
+ `libgmp.so' will have a small overhead on each function call and
+ global data address. For many programs this will be
+ insignificant, but for long calculations there's a gain to be had.
+
+Initializing and Clearing
+ Avoid excessive initializing and clearing of variables, since this
+ can be quite time consuming, especially in comparison to otherwise
+ fast operations like addition.
+
+ A language interpreter might want to keep a free list or stack of
+ initialized variables ready for use. It should be possible to
+ integrate something like that with a garbage collector too.
+
+Reallocations
+ An `mpz_t' or `mpq_t' variable used to hold successively increasing
+ values will have its memory repeatedly `realloc'ed, which could be
+ quite slow or could fragment memory, depending on the C library.
+ If an application can estimate the final size then `mpz_init2' or
+ `mpz_realloc2' can be called to allocate the necessary space from
+ the beginning (*note Initializing Integers::).
+
+ It doesn't matter if a size set with `mpz_init2' or `mpz_realloc2'
+ is too small, since all functions will do a further reallocation
+ if necessary. Badly overestimating memory required will waste
+ space though.
+
+`2exp' Functions
+ It's up to an application to call functions like `mpz_mul_2exp'
+ when appropriate. General purpose functions like `mpz_mul' make
+ no attempt to identify powers of two or other special forms,
+ because such inputs will usually be very rare and testing every
+ time would be wasteful.
+
+`ui' and `si' Functions
+ The `ui' functions and the small number of `si' functions exist for
+ convenience and should be used where applicable. But if for
+ example an `mpz_t' contains a value that fits in an `unsigned
+ long' there's no need extract it and call a `ui' function, just
+ use the regular `mpz' function.
+
+In-Place Operations
+ `mpz_abs', `mpq_abs', `mpf_abs', `mpz_neg', `mpq_neg' and
+ `mpf_neg' are fast when used for in-place operations like
+ `mpz_abs(x,x)', since in the current implementation only a single
+ field of `x' needs changing. On suitable compilers (GCC for
+ instance) this is inlined too.
+
+ `mpz_add_ui', `mpz_sub_ui', `mpf_add_ui' and `mpf_sub_ui' benefit
+ from an in-place operation like `mpz_add_ui(x,x,y)', since usually
+ only one or two limbs of `x' will need to be changed. The same
+ applies to the full precision `mpz_add' etc if `y' is small. If
+ `y' is big then cache locality may be helped, but that's all.
+
+ `mpz_mul' is currently the opposite, a separate destination is
+ slightly better. A call like `mpz_mul(x,x,y)' will, unless `y' is
+ only one limb, make a temporary copy of `x' before forming the
+ result. Normally that copying will only be a tiny fraction of the
+ time for the multiply, so this is not a particularly important
+ consideration.
+
+ `mpz_set', `mpq_set', `mpq_set_num', `mpf_set', etc, make no
+ attempt to recognise a copy of something to itself, so a call like
+ `mpz_set(x,x)' will be wasteful. Naturally that would never be
+ written deliberately, but if it might arise from two pointers to
+ the same object then a test to avoid it might be desirable.
+
+ if (x != y)
+ mpz_set (x, y);
+
+ Note that it's never worth introducing extra `mpz_set' calls just
+ to get in-place operations. If a result should go to a particular
+ variable then just direct it there and let GMP take care of data
+ movement.
+
+Divisibility Testing (Small Integers)
+ `mpz_divisible_ui_p' and `mpz_congruent_ui_p' are the best
+ functions for testing whether an `mpz_t' is divisible by an
+ individual small integer. They use an algorithm which is faster
+ than `mpz_tdiv_ui', but which gives no useful information about
+ the actual remainder, only whether it's zero (or a particular
+ value).
+
+ However when testing divisibility by several small integers, it's
+ best to take a remainder modulo their product, to save
+ multi-precision operations. For instance to test whether a number
+ is divisible by any of 23, 29 or 31 take a remainder modulo
+ 23*29*31 = 20677 and then test that.
+
+ The division functions like `mpz_tdiv_q_ui' which give a quotient
+ as well as a remainder are generally a little slower than the
+ remainder-only functions like `mpz_tdiv_ui'. If the quotient is
+ only rarely wanted then it's probably best to just take a
+ remainder and then go back and calculate the quotient if and when
+ it's wanted (`mpz_divexact_ui' can be used if the remainder is
+ zero).
+
+Rational Arithmetic
+ The `mpq' functions operate on `mpq_t' values with no common
+ factors in the numerator and denominator. Common factors are
+ checked-for and cast out as necessary. In general, cancelling
+ factors every time is the best approach since it minimizes the
+ sizes for subsequent operations.
+
+ However, applications that know something about the factorization
+ of the values they're working with might be able to avoid some of
+ the GCDs used for canonicalization, or swap them for divisions.
+ For example when multiplying by a prime it's enough to check for
+ factors of it in the denominator instead of doing a full GCD. Or
+ when forming a big product it might be known that very little
+ cancellation will be possible, and so canonicalization can be left
+ to the end.
+
+ The `mpq_numref' and `mpq_denref' macros give access to the
+ numerator and denominator to do things outside the scope of the
+ supplied `mpq' functions. *Note Applying Integer Functions::.
+
+ The canonical form for rationals allows mixed-type `mpq_t' and
+ integer additions or subtractions to be done directly with
+ multiples of the denominator. This will be somewhat faster than
+ `mpq_add'. For example,
+
+ /* mpq increment */
+ mpz_add (mpq_numref(q), mpq_numref(q), mpq_denref(q));
+
+ /* mpq += unsigned long */
+ mpz_addmul_ui (mpq_numref(q), mpq_denref(q), 123UL);
+
+ /* mpq -= mpz */
+ mpz_submul (mpq_numref(q), mpq_denref(q), z);
+
+Number Sequences
+ Functions like `mpz_fac_ui', `mpz_fib_ui' and `mpz_bin_uiui' are
+ designed for calculating isolated values. If a range of values is
+ wanted it's probably best to call to get a starting point and
+ iterate from there.
+
+Text Input/Output
+ Hexadecimal or octal are suggested for input or output in text
+ form. Power-of-2 bases like these can be converted much more
+ efficiently than other bases, like decimal. For big numbers
+ there's usually nothing of particular interest to be seen in the
+ digits, so the base doesn't matter much.
+
+ Maybe we can hope octal will one day become the normal base for
+ everyday use, as proposed by King Charles XII of Sweden and later
+ reformers.
+
+
+File: gmp.info, Node: Debugging, Next: Profiling, Prev: Efficiency, Up: GMP Basics
+
+3.12 Debugging
+==============
+
+Stack Overflow
+ Depending on the system, a segmentation violation or bus error
+ might be the only indication of stack overflow. See
+ `--enable-alloca' choices in *note Build Options::, for how to
+ address this.
+
+ In new enough versions of GCC, `-fstack-check' may be able to
+ ensure an overflow is recognised by the system before too much
+ damage is done, or `-fstack-limit-symbol' or
+ `-fstack-limit-register' may be able to add checking if the system
+ itself doesn't do any (*note Options for Code Generation:
+ (gcc)Code Gen Options.). These options must be added to the
+ `CFLAGS' used in the GMP build (*note Build Options::), adding
+ them just to an application will have no effect. Note also
+ they're a slowdown, adding overhead to each function call and each
+ stack allocation.
+
+Heap Problems
+ The most likely cause of application problems with GMP is heap
+ corruption. Failing to `init' GMP variables will have
+ unpredictable effects, and corruption arising elsewhere in a
+ program may well affect GMP. Initializing GMP variables more than
+ once or failing to clear them will cause memory leaks.
+
+ In all such cases a `malloc' debugger is recommended. On a GNU or
+ BSD system the standard C library `malloc' has some diagnostic
+ facilities, see *note Allocation Debugging: (libc)Allocation
+ Debugging, or `man 3 malloc'. Other possibilities, in no
+ particular order, include
+
+ `http://www.inf.ethz.ch/personal/biere/projects/ccmalloc/'
+ `http://dmalloc.com/'
+ `http://www.perens.com/FreeSoftware/' (electric fence)
+ `http://packages.debian.org/stable/devel/fda'
+ `http://www.gnupdate.org/components/leakbug/'
+ `http://people.redhat.com/~otaylor/memprof/'
+ `http://www.cbmamiga.demon.co.uk/mpatrol/'
+
+ The GMP default allocation routines in `memory.c' also have a
+ simple sentinel scheme which can be enabled with `#define DEBUG'
+ in that file. This is mainly designed for detecting buffer
+ overruns during GMP development, but might find other uses.
+
+Stack Backtraces
+ On some systems the compiler options GMP uses by default can
+ interfere with debugging. In particular on x86 and 68k systems
+ `-fomit-frame-pointer' is used and this generally inhibits stack
+ backtracing. Recompiling without such options may help while
+ debugging, though the usual caveats about it potentially moving a
+ memory problem or hiding a compiler bug will apply.
+
+GDB, the GNU Debugger
+ A sample `.gdbinit' is included in the distribution, showing how
+ to call some undocumented dump functions to print GMP variables
+ from within GDB. Note that these functions shouldn't be used in
+ final application code since they're undocumented and may be
+ subject to incompatible changes in future versions of GMP.
+
+Source File Paths
+ GMP has multiple source files with the same name, in different
+ directories. For example `mpz', `mpq' and `mpf' each have an
+ `init.c'. If the debugger can't already determine the right one
+ it may help to build with absolute paths on each C file. One way
+ to do that is to use a separate object directory with an absolute
+ path to the source directory.
+
+ cd /my/build/dir
+ /my/source/dir/gmp-6.0.0/configure
+
+ This works via `VPATH', and might require GNU `make'. Alternately
+ it might be possible to change the `.c.lo' rules appropriately.
+
+Assertion Checking
+ The build option `--enable-assert' is available to add some
+ consistency checks to the library (see *note Build Options::).
+ These are likely to be of limited value to most applications.
+ Assertion failures are just as likely to indicate memory
+ corruption as a library or compiler bug.
+
+ Applications using the low-level `mpn' functions, however, will
+ benefit from `--enable-assert' since it adds checks on the
+ parameters of most such functions, many of which have subtle
+ restrictions on their usage. Note however that only the generic C
+ code has checks, not the assembly code, so `--disable-assembly'
+ should be used for maximum checking.
+
+Temporary Memory Checking
+ The build option `--enable-alloca=debug' arranges that each block
+ of temporary memory in GMP is allocated with a separate call to
+ `malloc' (or the allocation function set with
+ `mp_set_memory_functions').
+
+ This can help a malloc debugger detect accesses outside the
+ intended bounds, or detect memory not released. In a normal
+ build, on the other hand, temporary memory is allocated in blocks
+ which GMP divides up for its own use, or may be allocated with a
+ compiler builtin `alloca' which will go nowhere near any malloc
+ debugger hooks.
+
+Maximum Debuggability
+ To summarize the above, a GMP build for maximum debuggability
+ would be
+
+ ./configure --disable-shared --enable-assert \
+ --enable-alloca=debug --disable-assembly CFLAGS=-g
+
+ For C++, add `--enable-cxx CXXFLAGS=-g'.
+
+Checker
+ The GCC checker (`https://savannah.nongnu.org/projects/checker/')
+ can be used with GMP. It contains a stub library which means GMP
+ applications compiled with checker can use a normal GMP build.
+
+ A build of GMP with checking within GMP itself can be made. This
+ will run very very slowly. On GNU/Linux for example,
+
+ ./configure --disable-assembly CC=checkergcc
+
+ `--disable-assembly' must be used, since the GMP assembly code
+ doesn't support the checking scheme. The GMP C++ features cannot
+ be used, since current versions of checker (0.9.9.1) don't yet
+ support the standard C++ library.
+
+Valgrind
+ Valgrind (`http://valgrind.org/') is a memory checker for x86,
+ ARM, MIPS, PowerPC, and S/390. It translates and emulates machine
+ instructions to do strong checks for uninitialized data (at the
+ level of individual bits), memory accesses through bad pointers,
+ and memory leaks.
+
+ Valgrind does not always support every possible instruction, in
+ particular ones recently added to an ISA. Valgrind might
+ therefore be incompatible with a recent GMP or even a less recent
+ GMP which is compiled using a recent GCC.
+
+ GMP's assembly code sometimes promotes a read of the limbs to some
+ larger size, for efficiency. GMP will do this even at the start
+ and end of a multilimb operand, using naturally aligned operations
+ on the larger type. This may lead to benign reads outside of
+ allocated areas, triggering complaints from Valgrind. Valgrind's
+ option `--partial-loads-ok=yes' should help.
+
+Other Problems
+ Any suspected bug in GMP itself should be isolated to make sure
+ it's not an application problem, see *note Reporting Bugs::.
+
+
+File: gmp.info, Node: Profiling, Next: Autoconf, Prev: Debugging, Up: GMP Basics
+
+3.13 Profiling
+==============
+
+Running a program under a profiler is a good way to find where it's
+spending most time and where improvements can be best sought. The
+profiling choices for a GMP build are as follows.
+
+`--disable-profiling'
+ The default is to add nothing special for profiling.
+
+ It should be possible to just compile the mainline of a program
+ with `-p' and use `prof' to get a profile consisting of
+ timer-based sampling of the program counter. Most of the GMP
+ assembly code has the necessary symbol information.
+
+ This approach has the advantage of minimizing interference with
+ normal program operation, but on most systems the resolution of
+ the sampling is quite low (10 milliseconds for instance),
+ requiring long runs to get accurate information.
+
+`--enable-profiling=prof'
+ Build with support for the system `prof', which means `-p' added
+ to the `CFLAGS'.
+
+ This provides call counting in addition to program counter
+ sampling, which allows the most frequently called routines to be
+ identified, and an average time spent in each routine to be
+ determined.
+
+ The x86 assembly code has support for this option, but on other
+ processors the assembly routines will be as if compiled without
+ `-p' and therefore won't appear in the call counts.
+
+ On some systems, such as GNU/Linux, `-p' in fact means `-pg' and in
+ this case `--enable-profiling=gprof' described below should be used
+ instead.
+
+`--enable-profiling=gprof'
+ Build with support for `gprof', which means `-pg' added to the
+ `CFLAGS'.
+
+ This provides call graph construction in addition to call counting
+ and program counter sampling, which makes it possible to count
+ calls coming from different locations. For example the number of
+ calls to `mpn_mul' from `mpz_mul' versus the number from
+ `mpf_mul'. The program counter sampling is still flat though, so
+ only a total time in `mpn_mul' would be accumulated, not a
+ separate amount for each call site.
+
+ The x86 assembly code has support for this option, but on other
+ processors the assembly routines will be as if compiled without
+ `-pg' and therefore not be included in the call counts.
+
+ On x86 and m68k systems `-pg' and `-fomit-frame-pointer' are
+ incompatible, so the latter is omitted from the default flags in
+ that case, which might result in poorer code generation.
+
+ Incidentally, it should be possible to use the `gprof' program
+ with a plain `--enable-profiling=prof' build. But in that case
+ only the `gprof -p' flat profile and call counts can be expected
+ to be valid, not the `gprof -q' call graph.
+
+`--enable-profiling=instrument'
+ Build with the GCC option `-finstrument-functions' added to the
+ `CFLAGS' (*note Options for Code Generation: (gcc)Code Gen
+ Options.).
+
+ This inserts special instrumenting calls at the start and end of
+ each function, allowing exact timing and full call graph
+ construction.
+
+ This instrumenting is not normally a standard system feature and
+ will require support from an external library, such as
+
+ `http://sourceforge.net/projects/fnccheck/'
+
+ This should be included in `LIBS' during the GMP configure so that
+ test programs will link. For example,
+
+ ./configure --enable-profiling=instrument LIBS=-lfc
+
+ On a GNU system the C library provides dummy instrumenting
+ functions, so programs compiled with this option will link. In
+ this case it's only necessary to ensure the correct library is
+ added when linking an application.
+
+ The x86 assembly code supports this option, but on other
+ processors the assembly routines will be as if compiled without
+ `-finstrument-functions' meaning time spent in them will
+ effectively be attributed to their caller.
+
+
+File: gmp.info, Node: Autoconf, Next: Emacs, Prev: Profiling, Up: GMP Basics
+
+3.14 Autoconf
+=============
+
+Autoconf based applications can easily check whether GMP is installed.
+The only thing to be noted is that GMP library symbols from version 3
+onwards have prefixes like `__gmpz'. The following therefore would be
+a simple test,
+
+ AC_CHECK_LIB(gmp, __gmpz_init)
+
+ This just uses the default `AC_CHECK_LIB' actions for found or not
+found, but an application that must have GMP would want to generate an
+error if not found. For example,
+
+ AC_CHECK_LIB(gmp, __gmpz_init, ,
+ [AC_MSG_ERROR([GNU MP not found, see https://gmplib.org/])])
+
+ If functions added in some particular version of GMP are required,
+then one of those can be used when checking. For example `mpz_mul_si'
+was added in GMP 3.1,
+
+ AC_CHECK_LIB(gmp, __gmpz_mul_si, ,
+ [AC_MSG_ERROR(
+ [GNU MP not found, or not 3.1 or up, see https://gmplib.org/])])
+
+ An alternative would be to test the version number in `gmp.h' using
+say `AC_EGREP_CPP'. That would make it possible to test the exact
+version, if some particular sub-minor release is known to be necessary.
+
+ In general it's recommended that applications should simply demand a
+new enough GMP rather than trying to provide supplements for features
+not available in past versions.
+
+ Occasionally an application will need or want to know the size of a
+type at configuration or preprocessing time, not just with `sizeof' in
+the code. This can be done in the normal way with `mp_limb_t' etc, but
+GMP 4.0 or up is best for this, since prior versions needed certain
+`-D' defines on systems using a `long long' limb. The following would
+suit Autoconf 2.50 or up,
+
+ AC_CHECK_SIZEOF(mp_limb_t, , [#include <gmp.h>])
+
+
+File: gmp.info, Node: Emacs, Prev: Autoconf, Up: GMP Basics
+
+3.15 Emacs
+==========
+
+<C-h C-i> (`info-lookup-symbol') is a good way to find documentation on
+C functions while editing (*note Info Documentation Lookup: (emacs)Info
+Lookup.).
+
+ The GMP manual can be included in such lookups by putting the
+following in your `.emacs',
+
+ (eval-after-load "info-look"
+ '(let ((mode-value (assoc 'c-mode (assoc 'symbol info-lookup-alist))))
+ (setcar (nthcdr 3 mode-value)
+ (cons '("(gmp)Function Index" nil "^ -.* " "\\>")
+ (nth 3 mode-value)))))
+
+
+File: gmp.info, Node: Reporting Bugs, Next: Integer Functions, Prev: GMP Basics, Up: Top
+
+4 Reporting Bugs
+****************
+
+If you think you have found a bug in the GMP library, please
+investigate it and report it. We have made this library available to
+you, and it is not too much to ask you to report the bugs you find.
+
+ Before you report a bug, check it's not already addressed in *note
+Known Build Problems::, or perhaps *note Notes for Particular
+Systems::. You may also want to check `https://gmplib.org/' for
+patches for this release.
+
+ Please include the following in any report,
+
+ * The GMP version number, and if pre-packaged or patched then say so.
+
+ * A test program that makes it possible for us to reproduce the bug.
+ Include instructions on how to run the program.
+
+ * A description of what is wrong. If the results are incorrect, in
+ what way. If you get a crash, say so.
+
+ * If you get a crash, include a stack backtrace from the debugger if
+ it's informative (`where' in `gdb', or `$C' in `adb').
+
+ * Please do not send core dumps, executables or `strace's.
+
+ * The `configure' options you used when building GMP, if any.
+
+ * The output from `configure', as printed to stdout, with any
+ options used.
+
+ * The name of the compiler and its version. For `gcc', get the
+ version with `gcc -v', otherwise perhaps `what `which cc`', or
+ similar.
+
+ * The output from running `uname -a'.
+
+ * The output from running `./config.guess', and from running
+ `./configfsf.guess' (might be the same).
+
+ * If the bug is related to `configure', then the compressed contents
+ of `config.log'.
+
+ * If the bug is related to an `asm' file not assembling, then the
+ contents of `config.m4' and the offending line or lines from the
+ temporary `mpn/tmp-<file>.s'.
+
+ Please make an effort to produce a self-contained report, with
+something definite that can be tested or debugged. Vague queries or
+piecemeal messages are difficult to act on and don't help the
+development effort.
+
+ It is not uncommon that an observed problem is actually due to a bug
+in the compiler; the GMP code tends to explore interesting corners in
+compilers.
+
+ If your bug report is good, we will do our best to help you get a
+corrected version of the library; if the bug report is poor, we won't
+do anything about it (except maybe ask you to send a better report).
+
+ Send your report to: <gmp-bugs@gmplib.org>.
+
+ If you think something in this manual is unclear, or downright
+incorrect, or if the language needs to be improved, please send a note
+to the same address.
+
+
+File: gmp.info, Node: Integer Functions, Next: Rational Number Functions, Prev: Reporting Bugs, Up: Top
+
+5 Integer Functions
+*******************
+
+This chapter describes the GMP functions for performing integer
+arithmetic. These functions start with the prefix `mpz_'.
+
+ GMP integers are stored in objects of type `mpz_t'.
+
+* Menu:
+
+* Initializing Integers::
+* Assigning Integers::
+* Simultaneous Integer Init & Assign::
+* Converting Integers::
+* Integer Arithmetic::
+* Integer Division::
+* Integer Exponentiation::
+* Integer Roots::
+* Number Theoretic Functions::
+* Integer Comparisons::
+* Integer Logic and Bit Fiddling::
+* I/O of Integers::
+* Integer Random Numbers::
+* Integer Import and Export::
+* Miscellaneous Integer Functions::
+* Integer Special Functions::
+
+
+File: gmp.info, Node: Initializing Integers, Next: Assigning Integers, Prev: Integer Functions, Up: Integer Functions
+
+5.1 Initialization Functions
+============================
+
+The functions for integer arithmetic assume that all integer objects are
+initialized. You do that by calling the function `mpz_init'. For
+example,
+
+ {
+ mpz_t integ;
+ mpz_init (integ);
+ ...
+ mpz_add (integ, ...);
+ ...
+ mpz_sub (integ, ...);
+
+ /* Unless the program is about to exit, do ... */
+ mpz_clear (integ);
+ }
+
+ As you can see, you can store new values any number of times, once an
+object is initialized.
+
+ -- Function: void mpz_init (mpz_t X)
+ Initialize X, and set its value to 0.
+
+ -- Function: void mpz_inits (mpz_t X, ...)
+ Initialize a NULL-terminated list of `mpz_t' variables, and set
+ their values to 0.
+
+ -- Function: void mpz_init2 (mpz_t X, mp_bitcnt_t N)
+ Initialize X, with space for N-bit numbers, and set its value to 0.
+ Calling this function instead of `mpz_init' or `mpz_inits' is never
+ necessary; reallocation is handled automatically by GMP when
+ needed.
+
+ While N defines the initial space, X will grow automatically in the
+ normal way, if necessary, for subsequent values stored.
+ `mpz_init2' makes it possible to avoid such reallocations if a
+ maximum size is known in advance.
+
+ In preparation for an operation, GMP often allocates one limb more
+ than ultimately needed. To make sure GMP will not perform
+ reallocation for X, you need to add the number of bits in
+ `mp_limb_t' to N.
+
+ -- Function: void mpz_clear (mpz_t X)
+ Free the space occupied by X. Call this function for all `mpz_t'
+ variables when you are done with them.
+
+ -- Function: void mpz_clears (mpz_t X, ...)
+ Free the space occupied by a NULL-terminated list of `mpz_t'
+ variables.
+
+ -- Function: void mpz_realloc2 (mpz_t X, mp_bitcnt_t N)
+ Change the space allocated for X to N bits. The value in X is
+ preserved if it fits, or is set to 0 if not.
+
+ Calling this function is never necessary; reallocation is handled
+ automatically by GMP when needed. But this function can be used
+ to increase the space for a variable in order to avoid repeated
+ automatic reallocations, or to decrease it to give memory back to
+ the heap.
+
+
+File: gmp.info, Node: Assigning Integers, Next: Simultaneous Integer Init & Assign, Prev: Initializing Integers, Up: Integer Functions
+
+5.2 Assignment Functions
+========================
+
+These functions assign new values to already initialized integers
+(*note Initializing Integers::).
+
+ -- Function: void mpz_set (mpz_t ROP, const mpz_t OP)
+ -- Function: void mpz_set_ui (mpz_t ROP, unsigned long int OP)
+ -- Function: void mpz_set_si (mpz_t ROP, signed long int OP)
+ -- Function: void mpz_set_d (mpz_t ROP, double OP)
+ -- Function: void mpz_set_q (mpz_t ROP, const mpq_t OP)
+ -- Function: void mpz_set_f (mpz_t ROP, const mpf_t OP)
+ Set the value of ROP from OP.
+
+ `mpz_set_d', `mpz_set_q' and `mpz_set_f' truncate OP to make it an
+ integer.
+
+ -- Function: int mpz_set_str (mpz_t ROP, const char *STR, int BASE)
+ Set the value of ROP from STR, a null-terminated C string in base
+ BASE. White space is allowed in the string, and is simply ignored.
+
+ The BASE may vary from 2 to 62, or if BASE is 0, then the leading
+ characters are used: `0x' and `0X' for hexadecimal, `0b' and `0B'
+ for binary, `0' for octal, or decimal otherwise.
+
+ For bases up to 36, case is ignored; upper-case and lower-case
+ letters have the same value. For bases 37 to 62, upper-case
+ letter represent the usual 10..35 while lower-case letter
+ represent 36..61.
+
+ This function returns 0 if the entire string is a valid number in
+ base BASE. Otherwise it returns -1.
+
+ -- Function: void mpz_swap (mpz_t ROP1, mpz_t ROP2)
+ Swap the values ROP1 and ROP2 efficiently.
+
+
+File: gmp.info, Node: Simultaneous Integer Init & Assign, Next: Converting Integers, Prev: Assigning Integers, Up: Integer Functions
+
+5.3 Combined Initialization and Assignment Functions
+====================================================
+
+For convenience, GMP provides a parallel series of initialize-and-set
+functions which initialize the output and then store the value there.
+These functions' names have the form `mpz_init_set...'
+
+ Here is an example of using one:
+
+ {
+ mpz_t pie;
+ mpz_init_set_str (pie, "3141592653589793238462643383279502884", 10);
+ ...
+ mpz_sub (pie, ...);
+ ...
+ mpz_clear (pie);
+ }
+
+Once the integer has been initialized by any of the `mpz_init_set...'
+functions, it can be used as the source or destination operand for the
+ordinary integer functions. Don't use an initialize-and-set function
+on a variable already initialized!
+
+ -- Function: void mpz_init_set (mpz_t ROP, const mpz_t OP)
+ -- Function: void mpz_init_set_ui (mpz_t ROP, unsigned long int OP)
+ -- Function: void mpz_init_set_si (mpz_t ROP, signed long int OP)
+ -- Function: void mpz_init_set_d (mpz_t ROP, double OP)
+ Initialize ROP with limb space and set the initial numeric value
+ from OP.
+
+ -- Function: int mpz_init_set_str (mpz_t ROP, const char *STR, int
+ BASE)
+ Initialize ROP and set its value like `mpz_set_str' (see its
+ documentation above for details).
+
+ If the string is a correct base BASE number, the function returns
+ 0; if an error occurs it returns -1. ROP is initialized even if
+ an error occurs. (I.e., you have to call `mpz_clear' for it.)
+
+
+File: gmp.info, Node: Converting Integers, Next: Integer Arithmetic, Prev: Simultaneous Integer Init & Assign, Up: Integer Functions
+
+5.4 Conversion Functions
+========================
+
+This section describes functions for converting GMP integers to
+standard C types. Functions for converting _to_ GMP integers are
+described in *note Assigning Integers:: and *note I/O of Integers::.
+
+ -- Function: unsigned long int mpz_get_ui (const mpz_t OP)
+ Return the value of OP as an `unsigned long'.
+
+ If OP is too big to fit an `unsigned long' then just the least
+ significant bits that do fit are returned. The sign of OP is
+ ignored, only the absolute value is used.
+
+ -- Function: signed long int mpz_get_si (const mpz_t OP)
+ If OP fits into a `signed long int' return the value of OP.
+ Otherwise return the least significant part of OP, with the same
+ sign as OP.
+
+ If OP is too big to fit in a `signed long int', the returned
+ result is probably not very useful. To find out if the value will
+ fit, use the function `mpz_fits_slong_p'.
+
+ -- Function: double mpz_get_d (const mpz_t OP)
+ Convert OP to a `double', truncating if necessary (i.e. rounding
+ towards zero).
+
+ If the exponent from the conversion is too big, the result is
+ system dependent. An infinity is returned where available. A
+ hardware overflow trap may or may not occur.
+
+ -- Function: double mpz_get_d_2exp (signed long int *EXP, const mpz_t
+ OP)
+ Convert OP to a `double', truncating if necessary (i.e. rounding
+ towards zero), and returning the exponent separately.
+
+ The return value is in the range 0.5<=abs(D)<1 and the exponent is
+ stored to `*EXP'. D * 2^EXP is the (truncated) OP value. If OP
+ is zero, the return is 0.0 and 0 is stored to `*EXP'.
+
+ This is similar to the standard C `frexp' function (*note
+ Normalization Functions: (libc)Normalization Functions.).
+
+ -- Function: char * mpz_get_str (char *STR, int BASE, const mpz_t OP)
+ Convert OP to a string of digits in base BASE. The base argument
+ may vary from 2 to 62 or from -2 to -36.
+
+ For BASE in the range 2..36, digits and lower-case letters are
+ used; for -2..-36, digits and upper-case letters are used; for
+ 37..62, digits, upper-case letters, and lower-case letters (in
+ that significance order) are used.
+
+ If STR is `NULL', the result string is allocated using the current
+ allocation function (*note Custom Allocation::). The block will be
+ `strlen(str)+1' bytes, that being exactly enough for the string and
+ null-terminator.
+
+ If STR is not `NULL', it should point to a block of storage large
+ enough for the result, that being `mpz_sizeinbase (OP, BASE) + 2'.
+ The two extra bytes are for a possible minus sign, and the
+ null-terminator.
+
+ A pointer to the result string is returned, being either the
+ allocated block, or the given STR.
+
+
+File: gmp.info, Node: Integer Arithmetic, Next: Integer Division, Prev: Converting Integers, Up: Integer Functions
+
+5.5 Arithmetic Functions
+========================
+
+ -- Function: void mpz_add (mpz_t ROP, const mpz_t OP1, const mpz_t OP2)
+ -- Function: void mpz_add_ui (mpz_t ROP, const mpz_t OP1, unsigned
+ long int OP2)
+ Set ROP to OP1 + OP2.
+
+ -- Function: void mpz_sub (mpz_t ROP, const mpz_t OP1, const mpz_t OP2)
+ -- Function: void mpz_sub_ui (mpz_t ROP, const mpz_t OP1, unsigned
+ long int OP2)
+ -- Function: void mpz_ui_sub (mpz_t ROP, unsigned long int OP1, const
+ mpz_t OP2)
+ Set ROP to OP1 - OP2.
+
+ -- Function: void mpz_mul (mpz_t ROP, const mpz_t OP1, const mpz_t OP2)
+ -- Function: void mpz_mul_si (mpz_t ROP, const mpz_t OP1, long int OP2)
+ -- Function: void mpz_mul_ui (mpz_t ROP, const mpz_t OP1, unsigned
+ long int OP2)
+ Set ROP to OP1 times OP2.
+
+ -- Function: void mpz_addmul (mpz_t ROP, const mpz_t OP1, const mpz_t
+ OP2)
+ -- Function: void mpz_addmul_ui (mpz_t ROP, const mpz_t OP1, unsigned
+ long int OP2)
+ Set ROP to ROP + OP1 times OP2.
+
+ -- Function: void mpz_submul (mpz_t ROP, const mpz_t OP1, const mpz_t
+ OP2)
+ -- Function: void mpz_submul_ui (mpz_t ROP, const mpz_t OP1, unsigned
+ long int OP2)
+ Set ROP to ROP - OP1 times OP2.
+
+ -- Function: void mpz_mul_2exp (mpz_t ROP, const mpz_t OP1,
+ mp_bitcnt_t OP2)
+ Set ROP to OP1 times 2 raised to OP2. This operation can also be
+ defined as a left shift by OP2 bits.
+
+ -- Function: void mpz_neg (mpz_t ROP, const mpz_t OP)
+ Set ROP to -OP.
+
+ -- Function: void mpz_abs (mpz_t ROP, const mpz_t OP)
+ Set ROP to the absolute value of OP.
+
+
+File: gmp.info, Node: Integer Division, Next: Integer Exponentiation, Prev: Integer Arithmetic, Up: Integer Functions
+
+5.6 Division Functions
+======================
+
+Division is undefined if the divisor is zero. Passing a zero divisor
+to the division or modulo functions (including the modular powering
+functions `mpz_powm' and `mpz_powm_ui'), will cause an intentional
+division by zero. This lets a program handle arithmetic exceptions in
+these functions the same way as for normal C `int' arithmetic.
+
+ -- Function: void mpz_cdiv_q (mpz_t Q, const mpz_t N, const mpz_t D)
+ -- Function: void mpz_cdiv_r (mpz_t R, const mpz_t N, const mpz_t D)
+ -- Function: void mpz_cdiv_qr (mpz_t Q, mpz_t R, const mpz_t N, const
+ mpz_t D)
+ -- Function: unsigned long int mpz_cdiv_q_ui (mpz_t Q, const mpz_t N,
+ unsigned long int D)
+ -- Function: unsigned long int mpz_cdiv_r_ui (mpz_t R, const mpz_t N,
+ unsigned long int D)
+ -- Function: unsigned long int mpz_cdiv_qr_ui (mpz_t Q, mpz_t R,
+ const mpz_t N, unsigned long int D)
+ -- Function: unsigned long int mpz_cdiv_ui (const mpz_t N,
+ unsigned long int D)
+ -- Function: void mpz_cdiv_q_2exp (mpz_t Q, const mpz_t N,
+ mp_bitcnt_t B)
+ -- Function: void mpz_cdiv_r_2exp (mpz_t R, const mpz_t N,
+ mp_bitcnt_t B)
+
+ -- Function: void mpz_fdiv_q (mpz_t Q, const mpz_t N, const mpz_t D)
+ -- Function: void mpz_fdiv_r (mpz_t R, const mpz_t N, const mpz_t D)
+ -- Function: void mpz_fdiv_qr (mpz_t Q, mpz_t R, const mpz_t N, const
+ mpz_t D)
+ -- Function: unsigned long int mpz_fdiv_q_ui (mpz_t Q, const mpz_t N,
+ unsigned long int D)
+ -- Function: unsigned long int mpz_fdiv_r_ui (mpz_t R, const mpz_t N,
+ unsigned long int D)
+ -- Function: unsigned long int mpz_fdiv_qr_ui (mpz_t Q, mpz_t R,
+ const mpz_t N, unsigned long int D)
+ -- Function: unsigned long int mpz_fdiv_ui (const mpz_t N,
+ unsigned long int D)
+ -- Function: void mpz_fdiv_q_2exp (mpz_t Q, const mpz_t N,
+ mp_bitcnt_t B)
+ -- Function: void mpz_fdiv_r_2exp (mpz_t R, const mpz_t N,
+ mp_bitcnt_t B)
+
+ -- Function: void mpz_tdiv_q (mpz_t Q, const mpz_t N, const mpz_t D)
+ -- Function: void mpz_tdiv_r (mpz_t R, const mpz_t N, const mpz_t D)
+ -- Function: void mpz_tdiv_qr (mpz_t Q, mpz_t R, const mpz_t N, const
+ mpz_t D)
+ -- Function: unsigned long int mpz_tdiv_q_ui (mpz_t Q, const mpz_t N,
+ unsigned long int D)
+ -- Function: unsigned long int mpz_tdiv_r_ui (mpz_t R, const mpz_t N,
+ unsigned long int D)
+ -- Function: unsigned long int mpz_tdiv_qr_ui (mpz_t Q, mpz_t R,
+ const mpz_t N, unsigned long int D)
+ -- Function: unsigned long int mpz_tdiv_ui (const mpz_t N,
+ unsigned long int D)
+ -- Function: void mpz_tdiv_q_2exp (mpz_t Q, const mpz_t N,
+ mp_bitcnt_t B)
+ -- Function: void mpz_tdiv_r_2exp (mpz_t R, const mpz_t N,
+ mp_bitcnt_t B)
+
+ Divide N by D, forming a quotient Q and/or remainder R. For the
+ `2exp' functions, D=2^B. The rounding is in three styles, each
+ suiting different applications.
+
+ * `cdiv' rounds Q up towards +infinity, and R will have the
+ opposite sign to D. The `c' stands for "ceil".
+
+ * `fdiv' rounds Q down towards -infinity, and R will have the
+ same sign as D. The `f' stands for "floor".
+
+ * `tdiv' rounds Q towards zero, and R will have the same sign
+ as N. The `t' stands for "truncate".
+
+ In all cases Q and R will satisfy N=Q*D+R, and R will satisfy
+ 0<=abs(R)<abs(D).
+
+ The `q' functions calculate only the quotient, the `r' functions
+ only the remainder, and the `qr' functions calculate both. Note
+ that for `qr' the same variable cannot be passed for both Q and R,
+ or results will be unpredictable.
+
+ For the `ui' variants the return value is the remainder, and in
+ fact returning the remainder is all the `div_ui' functions do. For
+ `tdiv' and `cdiv' the remainder can be negative, so for those the
+ return value is the absolute value of the remainder.
+
+ For the `2exp' variants the divisor is 2^B. These functions are
+ implemented as right shifts and bit masks, but of course they
+ round the same as the other functions.
+
+ For positive N both `mpz_fdiv_q_2exp' and `mpz_tdiv_q_2exp' are
+ simple bitwise right shifts. For negative N, `mpz_fdiv_q_2exp' is
+ effectively an arithmetic right shift treating N as twos complement
+ the same as the bitwise logical functions do, whereas
+ `mpz_tdiv_q_2exp' effectively treats N as sign and magnitude.
+
+ -- Function: void mpz_mod (mpz_t R, const mpz_t N, const mpz_t D)
+ -- Function: unsigned long int mpz_mod_ui (mpz_t R, const mpz_t N,
+ unsigned long int D)
+ Set R to N `mod' D. The sign of the divisor is ignored; the
+ result is always non-negative.
+
+ `mpz_mod_ui' is identical to `mpz_fdiv_r_ui' above, returning the
+ remainder as well as setting R. See `mpz_fdiv_ui' above if only
+ the return value is wanted.
+
+ -- Function: void mpz_divexact (mpz_t Q, const mpz_t N, const mpz_t D)
+ -- Function: void mpz_divexact_ui (mpz_t Q, const mpz_t N, unsigned
+ long D)
+ Set Q to N/D. These functions produce correct results only when
+ it is known in advance that D divides N.
+
+ These routines are much faster than the other division functions,
+ and are the best choice when exact division is known to occur, for
+ example reducing a rational to lowest terms.
+
+ -- Function: int mpz_divisible_p (const mpz_t N, const mpz_t D)
+ -- Function: int mpz_divisible_ui_p (const mpz_t N, unsigned long int
+ D)
+ -- Function: int mpz_divisible_2exp_p (const mpz_t N, mp_bitcnt_t B)
+ Return non-zero if N is exactly divisible by D, or in the case of
+ `mpz_divisible_2exp_p' by 2^B.
+
+ N is divisible by D if there exists an integer Q satisfying N =
+ Q*D. Unlike the other division functions, D=0 is accepted and
+ following the rule it can be seen that only 0 is considered
+ divisible by 0.
+
+ -- Function: int mpz_congruent_p (const mpz_t N, const mpz_t C, const
+ mpz_t D)
+ -- Function: int mpz_congruent_ui_p (const mpz_t N, unsigned long int
+ C, unsigned long int D)
+ -- Function: int mpz_congruent_2exp_p (const mpz_t N, const mpz_t C,
+ mp_bitcnt_t B)
+ Return non-zero if N is congruent to C modulo D, or in the case of
+ `mpz_congruent_2exp_p' modulo 2^B.
+
+ N is congruent to C mod D if there exists an integer Q satisfying
+ N = C + Q*D. Unlike the other division functions, D=0 is accepted
+ and following the rule it can be seen that N and C are considered
+ congruent mod 0 only when exactly equal.
+
+
+File: gmp.info, Node: Integer Exponentiation, Next: Integer Roots, Prev: Integer Division, Up: Integer Functions
+
+5.7 Exponentiation Functions
+============================
+
+ -- Function: void mpz_powm (mpz_t ROP, const mpz_t BASE, const mpz_t
+ EXP, const mpz_t MOD)
+ -- Function: void mpz_powm_ui (mpz_t ROP, const mpz_t BASE, unsigned
+ long int EXP, const mpz_t MOD)
+ Set ROP to (BASE raised to EXP) modulo MOD.
+
+ Negative EXP is supported if an inverse BASE^-1 mod MOD exists
+ (see `mpz_invert' in *note Number Theoretic Functions::). If an
+ inverse doesn't exist then a divide by zero is raised.
+
+ -- Function: void mpz_powm_sec (mpz_t ROP, const mpz_t BASE, const
+ mpz_t EXP, const mpz_t MOD)
+ Set ROP to (BASE raised to EXP) modulo MOD.
+
+ It is required that EXP > 0 and that MOD is odd.
+
+ This function is designed to take the same time and have the same
+ cache access patterns for any two same-size arguments, assuming
+ that function arguments are placed at the same position and that
+ the machine state is identical upon function entry. This function
+ is intended for cryptographic purposes, where resilience to
+ side-channel attacks is desired.
+
+ -- Function: void mpz_pow_ui (mpz_t ROP, const mpz_t BASE, unsigned
+ long int EXP)
+ -- Function: void mpz_ui_pow_ui (mpz_t ROP, unsigned long int BASE,
+ unsigned long int EXP)
+ Set ROP to BASE raised to EXP. The case 0^0 yields 1.
+
+
+File: gmp.info, Node: Integer Roots, Next: Number Theoretic Functions, Prev: Integer Exponentiation, Up: Integer Functions
+
+5.8 Root Extraction Functions
+=============================
+
+ -- Function: int mpz_root (mpz_t ROP, const mpz_t OP, unsigned long
+ int N)
+ Set ROP to the truncated integer part of the Nth root of OP.
+ Return non-zero if the computation was exact, i.e., if OP is ROP
+ to the Nth power.
+
+ -- Function: void mpz_rootrem (mpz_t ROOT, mpz_t REM, const mpz_t U,
+ unsigned long int N)
+ Set ROOT to the truncated integer part of the Nth root of U. Set
+ REM to the remainder, U-ROOT**N.
+
+ -- Function: void mpz_sqrt (mpz_t ROP, const mpz_t OP)
+ Set ROP to the truncated integer part of the square root of OP.
+
+ -- Function: void mpz_sqrtrem (mpz_t ROP1, mpz_t ROP2, const mpz_t OP)
+ Set ROP1 to the truncated integer part of the square root of OP,
+ like `mpz_sqrt'. Set ROP2 to the remainder OP-ROP1*ROP1, which
+ will be zero if OP is a perfect square.
+
+ If ROP1 and ROP2 are the same variable, the results are undefined.
+
+ -- Function: int mpz_perfect_power_p (const mpz_t OP)
+ Return non-zero if OP is a perfect power, i.e., if there exist
+ integers A and B, with B>1, such that OP equals A raised to the
+ power B.
+
+ Under this definition both 0 and 1 are considered to be perfect
+ powers. Negative values of OP are accepted, but of course can
+ only be odd perfect powers.
+
+ -- Function: int mpz_perfect_square_p (const mpz_t OP)
+ Return non-zero if OP is a perfect square, i.e., if the square
+ root of OP is an integer. Under this definition both 0 and 1 are
+ considered to be perfect squares.
+
+
+File: gmp.info, Node: Number Theoretic Functions, Next: Integer Comparisons, Prev: Integer Roots, Up: Integer Functions
+
+5.9 Number Theoretic Functions
+==============================
+
+ -- Function: int mpz_probab_prime_p (const mpz_t N, int REPS)
+ Determine whether N is prime. Return 2 if N is definitely prime,
+ return 1 if N is probably prime (without being certain), or return
+ 0 if N is definitely composite.
+
+ This function does some trial divisions, then some Miller-Rabin
+ probabilistic primality tests. The argument REPS controls how
+ many such tests are done; a higher value will reduce the chances
+ of a composite being returned as "probably prime". 25 is a
+ reasonable number; a composite number will then be identified as a
+ prime with a probability of less than 2^(-50).
+
+ Miller-Rabin and similar tests can be more properly called
+ compositeness tests. Numbers which fail are known to be composite
+ but those which pass might be prime or might be composite. Only a
+ few composites pass, hence those which pass are considered
+ probably prime.
+
+ -- Function: void mpz_nextprime (mpz_t ROP, const mpz_t OP)
+ Set ROP to the next prime greater than OP.
+
+ This function uses a probabilistic algorithm to identify primes.
+ For practical purposes it's adequate, the chance of a composite
+ passing will be extremely small.
+
+ -- Function: void mpz_gcd (mpz_t ROP, const mpz_t OP1, const mpz_t OP2)
+ Set ROP to the greatest common divisor of OP1 and OP2. The result
+ is always positive even if one or both input operands are negative.
+ Except if both inputs are zero; then this function defines
+ gcd(0,0) = 0.
+
+ -- Function: unsigned long int mpz_gcd_ui (mpz_t ROP, const mpz_t OP1,
+ unsigned long int OP2)
+ Compute the greatest common divisor of OP1 and OP2. If ROP is not
+ `NULL', store the result there.
+
+ If the result is small enough to fit in an `unsigned long int', it
+ is returned. If the result does not fit, 0 is returned, and the
+ result is equal to the argument OP1. Note that the result will
+ always fit if OP2 is non-zero.
+
+ -- Function: void mpz_gcdext (mpz_t G, mpz_t S, mpz_t T, const mpz_t
+ A, const mpz_t B)
+ Set G to the greatest common divisor of A and B, and in addition
+ set S and T to coefficients satisfying A*S + B*T = G. The value
+ in G is always positive, even if one or both of A and B are
+ negative (or zero if both inputs are zero). The values in S and T
+ are chosen such that normally, abs(S) < abs(B) / (2 G) and abs(T)
+ < abs(A) / (2 G), and these relations define S and T uniquely.
+ There are a few exceptional cases:
+
+ If abs(A) = abs(B), then S = 0, T = sgn(B).
+
+ Otherwise, S = sgn(A) if B = 0 or abs(B) = 2 G, and T = sgn(B) if
+ A = 0 or abs(A) = 2 G.
+
+ In all cases, S = 0 if and only if G = abs(B), i.e., if B divides
+ A or A = B = 0.
+
+ If T is `NULL' then that value is not computed.
+
+ -- Function: void mpz_lcm (mpz_t ROP, const mpz_t OP1, const mpz_t OP2)
+ -- Function: void mpz_lcm_ui (mpz_t ROP, const mpz_t OP1, unsigned
+ long OP2)
+ Set ROP to the least common multiple of OP1 and OP2. ROP is
+ always positive, irrespective of the signs of OP1 and OP2. ROP
+ will be zero if either OP1 or OP2 is zero.
+
+ -- Function: int mpz_invert (mpz_t ROP, const mpz_t OP1, const mpz_t
+ OP2)
+ Compute the inverse of OP1 modulo OP2 and put the result in ROP.
+ If the inverse exists, the return value is non-zero and ROP will
+ satisfy 0 < ROP < abs(OP2). If an inverse doesn't exist the
+ return value is zero and ROP is undefined. The behaviour of this
+ function is undefined when OP2 is zero.
+
+ -- Function: int mpz_jacobi (const mpz_t A, const mpz_t B)
+ Calculate the Jacobi symbol (A/B). This is defined only for B odd.
+
+ -- Function: int mpz_legendre (const mpz_t A, const mpz_t P)
+ Calculate the Legendre symbol (A/P). This is defined only for P
+ an odd positive prime, and for such P it's identical to the Jacobi
+ symbol.
+
+ -- Function: int mpz_kronecker (const mpz_t A, const mpz_t B)
+ -- Function: int mpz_kronecker_si (const mpz_t A, long B)
+ -- Function: int mpz_kronecker_ui (const mpz_t A, unsigned long B)
+ -- Function: int mpz_si_kronecker (long A, const mpz_t B)
+ -- Function: int mpz_ui_kronecker (unsigned long A, const mpz_t B)
+ Calculate the Jacobi symbol (A/B) with the Kronecker extension
+ (a/2)=(2/a) when a odd, or (a/2)=0 when a even.
+
+ When B is odd the Jacobi symbol and Kronecker symbol are
+ identical, so `mpz_kronecker_ui' etc can be used for mixed
+ precision Jacobi symbols too.
+
+ For more information see Henri Cohen section 1.4.2 (*note
+ References::), or any number theory textbook. See also the
+ example program `demos/qcn.c' which uses `mpz_kronecker_ui'.
+
+ -- Function: mp_bitcnt_t mpz_remove (mpz_t ROP, const mpz_t OP, const
+ mpz_t F)
+ Remove all occurrences of the factor F from OP and store the
+ result in ROP. The return value is how many such occurrences were
+ removed.
+
+ -- Function: void mpz_fac_ui (mpz_t ROP, unsigned long int N)
+ -- Function: void mpz_2fac_ui (mpz_t ROP, unsigned long int N)
+ -- Function: void mpz_mfac_uiui (mpz_t ROP, unsigned long int N,
+ unsigned long int M)
+ Set ROP to the factorial of N: `mpz_fac_ui' computes the plain
+ factorial N!, `mpz_2fac_ui' computes the double-factorial N!!, and
+ `mpz_mfac_uiui' the M-multi-factorial N!^(M).
+
+ -- Function: void mpz_primorial_ui (mpz_t ROP, unsigned long int N)
+ Set ROP to the primorial of N, i.e. the product of all positive
+ prime numbers <=N.
+
+ -- Function: void mpz_bin_ui (mpz_t ROP, const mpz_t N, unsigned long
+ int K)
+ -- Function: void mpz_bin_uiui (mpz_t ROP, unsigned long int N,
+ unsigned long int K)
+ Compute the binomial coefficient N over K and store the result in
+ ROP. Negative values of N are supported by `mpz_bin_ui', using
+ the identity bin(-n,k) = (-1)^k * bin(n+k-1,k), see Knuth volume 1
+ section 1.2.6 part G.
+
+ -- Function: void mpz_fib_ui (mpz_t FN, unsigned long int N)
+ -- Function: void mpz_fib2_ui (mpz_t FN, mpz_t FNSUB1, unsigned long
+ int N)
+ `mpz_fib_ui' sets FN to to F[n], the N'th Fibonacci number.
+ `mpz_fib2_ui' sets FN to F[n], and FNSUB1 to F[n-1].
+
+ These functions are designed for calculating isolated Fibonacci
+ numbers. When a sequence of values is wanted it's best to start
+ with `mpz_fib2_ui' and iterate the defining F[n+1]=F[n]+F[n-1] or
+ similar.
+
+ -- Function: void mpz_lucnum_ui (mpz_t LN, unsigned long int N)
+ -- Function: void mpz_lucnum2_ui (mpz_t LN, mpz_t LNSUB1, unsigned
+ long int N)
+ `mpz_lucnum_ui' sets LN to to L[n], the N'th Lucas number.
+ `mpz_lucnum2_ui' sets LN to L[n], and LNSUB1 to L[n-1].
+
+ These functions are designed for calculating isolated Lucas
+ numbers. When a sequence of values is wanted it's best to start
+ with `mpz_lucnum2_ui' and iterate the defining L[n+1]=L[n]+L[n-1]
+ or similar.
+
+ The Fibonacci numbers and Lucas numbers are related sequences, so
+ it's never necessary to call both `mpz_fib2_ui' and
+ `mpz_lucnum2_ui'. The formulas for going from Fibonacci to Lucas
+ can be found in *note Lucas Numbers Algorithm::, the reverse is
+ straightforward too.
+
+
+File: gmp.info, Node: Integer Comparisons, Next: Integer Logic and Bit Fiddling, Prev: Number Theoretic Functions, Up: Integer Functions
+
+5.10 Comparison Functions
+=========================
+
+ -- Function: int mpz_cmp (const mpz_t OP1, const mpz_t OP2)
+ -- Function: int mpz_cmp_d (const mpz_t OP1, double OP2)
+ -- Macro: int mpz_cmp_si (const mpz_t OP1, signed long int OP2)
+ -- Macro: int mpz_cmp_ui (const mpz_t OP1, unsigned long int OP2)
+ Compare OP1 and OP2. Return a positive value if OP1 > OP2, zero
+ if OP1 = OP2, or a negative value if OP1 < OP2.
+
+ `mpz_cmp_ui' and `mpz_cmp_si' are macros and will evaluate their
+ arguments more than once. `mpz_cmp_d' can be called with an
+ infinity, but results are undefined for a NaN.
+
+ -- Function: int mpz_cmpabs (const mpz_t OP1, const mpz_t OP2)
+ -- Function: int mpz_cmpabs_d (const mpz_t OP1, double OP2)
+ -- Function: int mpz_cmpabs_ui (const mpz_t OP1, unsigned long int OP2)
+ Compare the absolute values of OP1 and OP2. Return a positive
+ value if abs(OP1) > abs(OP2), zero if abs(OP1) = abs(OP2), or a
+ negative value if abs(OP1) < abs(OP2).
+
+ `mpz_cmpabs_d' can be called with an infinity, but results are
+ undefined for a NaN.
+
+ -- Macro: int mpz_sgn (const mpz_t OP)
+ Return +1 if OP > 0, 0 if OP = 0, and -1 if OP < 0.
+
+ This function is actually implemented as a macro. It evaluates
+ its argument multiple times.
+
+
+File: gmp.info, Node: Integer Logic and Bit Fiddling, Next: I/O of Integers, Prev: Integer Comparisons, Up: Integer Functions
+
+5.11 Logical and Bit Manipulation Functions
+===========================================
+
+These functions behave as if twos complement arithmetic were used
+(although sign-magnitude is the actual implementation). The least
+significant bit is number 0.
+
+ -- Function: void mpz_and (mpz_t ROP, const mpz_t OP1, const mpz_t OP2)
+ Set ROP to OP1 bitwise-and OP2.
+
+ -- Function: void mpz_ior (mpz_t ROP, const mpz_t OP1, const mpz_t OP2)
+ Set ROP to OP1 bitwise inclusive-or OP2.
+
+ -- Function: void mpz_xor (mpz_t ROP, const mpz_t OP1, const mpz_t OP2)
+ Set ROP to OP1 bitwise exclusive-or OP2.
+
+ -- Function: void mpz_com (mpz_t ROP, const mpz_t OP)
+ Set ROP to the one's complement of OP.
+
+ -- Function: mp_bitcnt_t mpz_popcount (const mpz_t OP)
+ If OP>=0, return the population count of OP, which is the number
+ of 1 bits in the binary representation. If OP<0, the number of 1s
+ is infinite, and the return value is the largest possible
+ `mp_bitcnt_t'.
+
+ -- Function: mp_bitcnt_t mpz_hamdist (const mpz_t OP1, const mpz_t OP2)
+ If OP1 and OP2 are both >=0 or both <0, return the hamming
+ distance between the two operands, which is the number of bit
+ positions where OP1 and OP2 have different bit values. If one
+ operand is >=0 and the other <0 then the number of bits different
+ is infinite, and the return value is the largest possible
+ `mp_bitcnt_t'.
+
+ -- Function: mp_bitcnt_t mpz_scan0 (const mpz_t OP, mp_bitcnt_t
+ STARTING_BIT)
+ -- Function: mp_bitcnt_t mpz_scan1 (const mpz_t OP, mp_bitcnt_t
+ STARTING_BIT)
+ Scan OP, starting from bit STARTING_BIT, towards more significant
+ bits, until the first 0 or 1 bit (respectively) is found. Return
+ the index of the found bit.
+
+ If the bit at STARTING_BIT is already what's sought, then
+ STARTING_BIT is returned.
+
+ If there's no bit found, then the largest possible `mp_bitcnt_t' is
+ returned. This will happen in `mpz_scan0' past the end of a
+ negative number, or `mpz_scan1' past the end of a nonnegative
+ number.
+
+ -- Function: void mpz_setbit (mpz_t ROP, mp_bitcnt_t BIT_INDEX)
+ Set bit BIT_INDEX in ROP.
+
+ -- Function: void mpz_clrbit (mpz_t ROP, mp_bitcnt_t BIT_INDEX)
+ Clear bit BIT_INDEX in ROP.
+
+ -- Function: void mpz_combit (mpz_t ROP, mp_bitcnt_t BIT_INDEX)
+ Complement bit BIT_INDEX in ROP.
+
+ -- Function: int mpz_tstbit (const mpz_t OP, mp_bitcnt_t BIT_INDEX)
+ Test bit BIT_INDEX in OP and return 0 or 1 accordingly.
+
+
+File: gmp.info, Node: I/O of Integers, Next: Integer Random Numbers, Prev: Integer Logic and Bit Fiddling, Up: Integer Functions
+
+5.12 Input and Output Functions
+===============================
+
+Functions that perform input from a stdio stream, and functions that
+output to a stdio stream, of `mpz' numbers. Passing a `NULL' pointer
+for a STREAM argument to any of these functions will make them read from
+`stdin' and write to `stdout', respectively.
+
+ When using any of these functions, it is a good idea to include
+`stdio.h' before `gmp.h', since that will allow `gmp.h' to define
+prototypes for these functions.
+
+ See also *note Formatted Output:: and *note Formatted Input::.
+
+ -- Function: size_t mpz_out_str (FILE *STREAM, int BASE, const mpz_t
+ OP)
+ Output OP on stdio stream STREAM, as a string of digits in base
+ BASE. The base argument may vary from 2 to 62 or from -2 to -36.
+
+ For BASE in the range 2..36, digits and lower-case letters are
+ used; for -2..-36, digits and upper-case letters are used; for
+ 37..62, digits, upper-case letters, and lower-case letters (in
+ that significance order) are used.
+
+ Return the number of bytes written, or if an error occurred,
+ return 0.
+
+ -- Function: size_t mpz_inp_str (mpz_t ROP, FILE *STREAM, int BASE)
+ Input a possibly white-space preceded string in base BASE from
+ stdio stream STREAM, and put the read integer in ROP.
+
+ The BASE may vary from 2 to 62, or if BASE is 0, then the leading
+ characters are used: `0x' and `0X' for hexadecimal, `0b' and `0B'
+ for binary, `0' for octal, or decimal otherwise.
+
+ For bases up to 36, case is ignored; upper-case and lower-case
+ letters have the same value. For bases 37 to 62, upper-case
+ letter represent the usual 10..35 while lower-case letter
+ represent 36..61.
+
+ Return the number of bytes read, or if an error occurred, return 0.
+
+ -- Function: size_t mpz_out_raw (FILE *STREAM, const mpz_t OP)
+ Output OP on stdio stream STREAM, in raw binary format. The
+ integer is written in a portable format, with 4 bytes of size
+ information, and that many bytes of limbs. Both the size and the
+ limbs are written in decreasing significance order (i.e., in
+ big-endian).
+
+ The output can be read with `mpz_inp_raw'.
+
+ Return the number of bytes written, or if an error occurred,
+ return 0.
+
+ The output of this can not be read by `mpz_inp_raw' from GMP 1,
+ because of changes necessary for compatibility between 32-bit and
+ 64-bit machines.
+
+ -- Function: size_t mpz_inp_raw (mpz_t ROP, FILE *STREAM)
+ Input from stdio stream STREAM in the format written by
+ `mpz_out_raw', and put the result in ROP. Return the number of
+ bytes read, or if an error occurred, return 0.
+
+ This routine can read the output from `mpz_out_raw' also from GMP
+ 1, in spite of changes necessary for compatibility between 32-bit
+ and 64-bit machines.
+
+
+File: gmp.info, Node: Integer Random Numbers, Next: Integer Import and Export, Prev: I/O of Integers, Up: Integer Functions
+
+5.13 Random Number Functions
+============================
+
+The random number functions of GMP come in two groups; older function
+that rely on a global state, and newer functions that accept a state
+parameter that is read and modified. Please see the *note Random
+Number Functions:: for more information on how to use and not to use
+random number functions.
+
+ -- Function: void mpz_urandomb (mpz_t ROP, gmp_randstate_t STATE,
+ mp_bitcnt_t N)
+ Generate a uniformly distributed random integer in the range 0 to
+ 2^N-1, inclusive.
+
+ The variable STATE must be initialized by calling one of the
+ `gmp_randinit' functions (*note Random State Initialization::)
+ before invoking this function.
+
+ -- Function: void mpz_urandomm (mpz_t ROP, gmp_randstate_t STATE,
+ const mpz_t N)
+ Generate a uniform random integer in the range 0 to N-1, inclusive.
+
+ The variable STATE must be initialized by calling one of the
+ `gmp_randinit' functions (*note Random State Initialization::)
+ before invoking this function.
+
+ -- Function: void mpz_rrandomb (mpz_t ROP, gmp_randstate_t STATE,
+ mp_bitcnt_t N)
+ Generate a random integer with long strings of zeros and ones in
+ the binary representation. Useful for testing functions and
+ algorithms, since this kind of random numbers have proven to be
+ more likely to trigger corner-case bugs. The random number will
+ be in the range 0 to 2^N-1, inclusive.
+
+ The variable STATE must be initialized by calling one of the
+ `gmp_randinit' functions (*note Random State Initialization::)
+ before invoking this function.
+
+ -- Function: void mpz_random (mpz_t ROP, mp_size_t MAX_SIZE)
+ Generate a random integer of at most MAX_SIZE limbs. The generated
+ random number doesn't satisfy any particular requirements of
+ randomness. Negative random numbers are generated when MAX_SIZE
+ is negative.
+
+ This function is obsolete. Use `mpz_urandomb' or `mpz_urandomm'
+ instead.
+
+ -- Function: void mpz_random2 (mpz_t ROP, mp_size_t MAX_SIZE)
+ Generate a random integer of at most MAX_SIZE limbs, with long
+ strings of zeros and ones in the binary representation. Useful
+ for testing functions and algorithms, since this kind of random
+ numbers have proven to be more likely to trigger corner-case bugs.
+ Negative random numbers are generated when MAX_SIZE is negative.
+
+ This function is obsolete. Use `mpz_rrandomb' instead.
+
+
+File: gmp.info, Node: Integer Import and Export, Next: Miscellaneous Integer Functions, Prev: Integer Random Numbers, Up: Integer Functions
+
+5.14 Integer Import and Export
+==============================
+
+`mpz_t' variables can be converted to and from arbitrary words of binary
+data with the following functions.
+
+ -- Function: void mpz_import (mpz_t ROP, size_t COUNT, int ORDER,
+ size_t SIZE, int ENDIAN, size_t NAILS, const void *OP)
+ Set ROP from an array of word data at OP.
+
+ The parameters specify the format of the data. COUNT many words
+ are read, each SIZE bytes. ORDER can be 1 for most significant
+ word first or -1 for least significant first. Within each word
+ ENDIAN can be 1 for most significant byte first, -1 for least
+ significant first, or 0 for the native endianness of the host CPU.
+ The most significant NAILS bits of each word are skipped, this can
+ be 0 to use the full words.
+
+ There is no sign taken from the data, ROP will simply be a positive
+ integer. An application can handle any sign itself, and apply it
+ for instance with `mpz_neg'.
+
+ There are no data alignment restrictions on OP, any address is
+ allowed.
+
+ Here's an example converting an array of `unsigned long' data, most
+ significant element first, and host byte order within each value.
+
+ unsigned long a[20];
+ /* Initialize Z and A */
+ mpz_import (z, 20, 1, sizeof(a[0]), 0, 0, a);
+
+ This example assumes the full `sizeof' bytes are used for data in
+ the given type, which is usually true, and certainly true for
+ `unsigned long' everywhere we know of. However on Cray vector
+ systems it may be noted that `short' and `int' are always stored
+ in 8 bytes (and with `sizeof' indicating that) but use only 32 or
+ 46 bits. The NAILS feature can account for this, by passing for
+ instance `8*sizeof(int)-INT_BIT'.
+
+ -- Function: void * mpz_export (void *ROP, size_t *COUNTP, int ORDER,
+ size_t SIZE, int ENDIAN, size_t NAILS, const mpz_t OP)
+ Fill ROP with word data from OP.
+
+ The parameters specify the format of the data produced. Each word
+ will be SIZE bytes and ORDER can be 1 for most significant word
+ first or -1 for least significant first. Within each word ENDIAN
+ can be 1 for most significant byte first, -1 for least significant
+ first, or 0 for the native endianness of the host CPU. The most
+ significant NAILS bits of each word are unused and set to zero,
+ this can be 0 to produce full words.
+
+ The number of words produced is written to `*COUNTP', or COUNTP
+ can be `NULL' to discard the count. ROP must have enough space
+ for the data, or if ROP is `NULL' then a result array of the
+ necessary size is allocated using the current GMP allocation
+ function (*note Custom Allocation::). In either case the return
+ value is the destination used, either ROP or the allocated block.
+
+ If OP is non-zero then the most significant word produced will be
+ non-zero. If OP is zero then the count returned will be zero and
+ nothing written to ROP. If ROP is `NULL' in this case, no block
+ is allocated, just `NULL' is returned.
+
+ The sign of OP is ignored, just the absolute value is exported. An
+ application can use `mpz_sgn' to get the sign and handle it as
+ desired. (*note Integer Comparisons::)
+
+ There are no data alignment restrictions on ROP, any address is
+ allowed.
+
+ When an application is allocating space itself the required size
+ can be determined with a calculation like the following. Since
+ `mpz_sizeinbase' always returns at least 1, `count' here will be
+ at least one, which avoids any portability problems with
+ `malloc(0)', though if `z' is zero no space at all is actually
+ needed (or written).
+
+ numb = 8*size - nail;
+ count = (mpz_sizeinbase (z, 2) + numb-1) / numb;
+ p = malloc (count * size);
+
+
+File: gmp.info, Node: Miscellaneous Integer Functions, Next: Integer Special Functions, Prev: Integer Import and Export, Up: Integer Functions
+
+5.15 Miscellaneous Functions
+============================
+
+ -- Function: int mpz_fits_ulong_p (const mpz_t OP)
+ -- Function: int mpz_fits_slong_p (const mpz_t OP)
+ -- Function: int mpz_fits_uint_p (const mpz_t OP)
+ -- Function: int mpz_fits_sint_p (const mpz_t OP)
+ -- Function: int mpz_fits_ushort_p (const mpz_t OP)
+ -- Function: int mpz_fits_sshort_p (const mpz_t OP)
+ Return non-zero iff the value of OP fits in an `unsigned long int',
+ `signed long int', `unsigned int', `signed int', `unsigned short
+ int', or `signed short int', respectively. Otherwise, return zero.
+
+ -- Macro: int mpz_odd_p (const mpz_t OP)
+ -- Macro: int mpz_even_p (const mpz_t OP)
+ Determine whether OP is odd or even, respectively. Return
+ non-zero if yes, zero if no. These macros evaluate their argument
+ more than once.
+
+ -- Function: size_t mpz_sizeinbase (const mpz_t OP, int BASE)
+ Return the size of OP measured in number of digits in the given
+ BASE. BASE can vary from 2 to 62. The sign of OP is ignored,
+ just the absolute value is used. The result will be either exact
+ or 1 too big. If BASE is a power of 2, the result is always
+ exact. If OP is zero the return value is always 1.
+
+ This function can be used to determine the space required when
+ converting OP to a string. The right amount of allocation is
+ normally two more than the value returned by `mpz_sizeinbase', one
+ extra for a minus sign and one for the null-terminator.
+
+ It will be noted that `mpz_sizeinbase(OP,2)' can be used to locate
+ the most significant 1 bit in OP, counting from 1. (Unlike the
+ bitwise functions which start from 0, *Note Logical and Bit
+ Manipulation Functions: Integer Logic and Bit Fiddling.)
+
+
+File: gmp.info, Node: Integer Special Functions, Prev: Miscellaneous Integer Functions, Up: Integer Functions
+
+5.16 Special Functions
+======================
+
+The functions in this section are for various special purposes. Most
+applications will not need them.
+
+ -- Function: void mpz_array_init (mpz_t INTEGER_ARRAY, mp_size_t
+ ARRAY_SIZE, mp_size_t FIXED_NUM_BITS)
+ *This is an obsolete function. Do not use it.*
+
+ -- Function: void * _mpz_realloc (mpz_t INTEGER, mp_size_t NEW_ALLOC)
+ Change the space for INTEGER to NEW_ALLOC limbs. The value in
+ INTEGER is preserved if it fits, or is set to 0 if not. The return
+ value is not useful to applications and should be ignored.
+
+ `mpz_realloc2' is the preferred way to accomplish allocation
+ changes like this. `mpz_realloc2' and `_mpz_realloc' are the same
+ except that `_mpz_realloc' takes its size in limbs.
+
+ -- Function: mp_limb_t mpz_getlimbn (const mpz_t OP, mp_size_t N)
+ Return limb number N from OP. The sign of OP is ignored, just the
+ absolute value is used. The least significant limb is number 0.
+
+ `mpz_size' can be used to find how many limbs make up OP.
+ `mpz_getlimbn' returns zero if N is outside the range 0 to
+ `mpz_size(OP)-1'.
+
+ -- Function: size_t mpz_size (const mpz_t OP)
+ Return the size of OP measured in number of limbs. If OP is zero,
+ the returned value will be zero.
+
+ -- Function: const mp_limb_t * mpz_limbs_read (const mpz_t X)
+ Return a pointer to the limb array representing the absolute value
+ of X. The size of the array is `mpz_size(X)'. Intended for read
+ access only.
+
+ -- Function: mp_limb_t * mpz_limbs_write (mpz_t X, mp_size_t N)
+ -- Function: mp_limb_t * mpz_limbs_modify (mpz_t X, mp_size_t N)
+ Return a pointer to the limb array, intended for write access. The
+ array is reallocated as needed, to make room for N limbs. Requires
+ N > 0. The `mpz_limbs_modify' function returns an array that holds
+ the old absolute value of X, while `mpz_limbs_write' may destroy
+ the old value and return an array with unspecified contents.
+
+ -- Function: void mpz_limbs_finish (mpz_t X, mp_size_t S)
+ Updates the internal size field of X. Used after writing to the
+ limb array pointer returned by `mpz_limbs_write' or
+ `mpz_limbs_modify' is completed. The array should contain abs(S)
+ valid limbs, representing the new absolute value for X, and the
+ sign of X is taken from the sign of S. This function never
+ reallocates X, so the limb pointer remains valid.
+
+ void foo (mpz_t x)
+ {
+ mp_size_t n, i;
+ mp_limb_t *xp;
+
+ n = mpz_size (x);
+ xp = mpz_limbs_modify(x, 2*n);
+ for (i = 0; i < n; i++)
+ xp[n+i] = xp[n-1-i];
+ mpz_limbs_finish (x, mpz_sgn (x) < 0 ? - 2*n : 2*n);
+ }
+
+ -- Function: mpz_srcptr mpz_roinit_n (mpz_t X, const mp_limb_t *XP,
+ mp_size_t XS)
+ Special initialization of X, using the given limb array and size.
+ X should be treated as read-only: it can be passed safely as input
+ to any mpz function, but not as an output. The array XP must point
+ to at least a readable limb, its size is abs(XS), and the sign of
+ X is the sign of XS. For convenience, the function returns X, but
+ cast to a const pointer type.
+
+ void foo (mpz_t x)
+ {
+ static const mp_limb_t y[3] = { 0x1, 0x2, 0x3 };
+ mpz_t tmp;
+ mpz_add (x, x, mpz_roinit_n (tmp, y, 3));
+ }
+
+ -- Macro: mpz_t MPZ_ROINIT_N (mp_limb_t *XP, mp_size_t XS)
+ This macro expands to an initializer which can be assigned to an
+ mpz_t variable. The limb array XP must point to at least a
+ readable limb, moreover, unlike the `mpz_roinit_n' function, the
+ array must be normalized: if XS is non-zero, then `XP[abs(XS)-1]'
+ must be non-zero. Intended primarily for constant values. Using it
+ for non-constant values requires a C compiler supporting C99.
+
+ void foo (mpz_t x)
+ {
+ static const mp_limb_t ya[3] = { 0x1, 0x2, 0x3 };
+ static const mpz_t y = MPZ_ROINIT_N ((mp_limb_t *) ya, 3);
+
+ mpz_add (x, x, y);
+ }
+
+
+File: gmp.info, Node: Rational Number Functions, Next: Floating-point Functions, Prev: Integer Functions, Up: Top
+
+6 Rational Number Functions
+***************************
+
+This chapter describes the GMP functions for performing arithmetic on
+rational numbers. These functions start with the prefix `mpq_'.
+
+ Rational numbers are stored in objects of type `mpq_t'.
+
+ All rational arithmetic functions assume operands have a canonical
+form, and canonicalize their result. The canonical from means that the
+denominator and the numerator have no common factors, and that the
+denominator is positive. Zero has the unique representation 0/1.
+
+ Pure assignment functions do not canonicalize the assigned variable.
+It is the responsibility of the user to canonicalize the assigned
+variable before any arithmetic operations are performed on that
+variable.
+
+ -- Function: void mpq_canonicalize (mpq_t OP)
+ Remove any factors that are common to the numerator and
+ denominator of OP, and make the denominator positive.
+
+* Menu:
+
+* Initializing Rationals::
+* Rational Conversions::
+* Rational Arithmetic::
+* Comparing Rationals::
+* Applying Integer Functions::
+* I/O of Rationals::
+
+
+File: gmp.info, Node: Initializing Rationals, Next: Rational Conversions, Prev: Rational Number Functions, Up: Rational Number Functions
+
+6.1 Initialization and Assignment Functions
+===========================================
+
+ -- Function: void mpq_init (mpq_t X)
+ Initialize X and set it to 0/1. Each variable should normally
+ only be initialized once, or at least cleared out (using the
+ function `mpq_clear') between each initialization.
+
+ -- Function: void mpq_inits (mpq_t X, ...)
+ Initialize a NULL-terminated list of `mpq_t' variables, and set
+ their values to 0/1.
+
+ -- Function: void mpq_clear (mpq_t X)
+ Free the space occupied by X. Make sure to call this function for
+ all `mpq_t' variables when you are done with them.
+
+ -- Function: void mpq_clears (mpq_t X, ...)
+ Free the space occupied by a NULL-terminated list of `mpq_t'
+ variables.
+
+ -- Function: void mpq_set (mpq_t ROP, const mpq_t OP)
+ -- Function: void mpq_set_z (mpq_t ROP, const mpz_t OP)
+ Assign ROP from OP.
+
+ -- Function: void mpq_set_ui (mpq_t ROP, unsigned long int OP1,
+ unsigned long int OP2)
+ -- Function: void mpq_set_si (mpq_t ROP, signed long int OP1, unsigned
+ long int OP2)
+ Set the value of ROP to OP1/OP2. Note that if OP1 and OP2 have
+ common factors, ROP has to be passed to `mpq_canonicalize' before
+ any operations are performed on ROP.
+
+ -- Function: int mpq_set_str (mpq_t ROP, const char *STR, int BASE)
+ Set ROP from a null-terminated string STR in the given BASE.
+
+ The string can be an integer like "41" or a fraction like
+ "41/152". The fraction must be in canonical form (*note Rational
+ Number Functions::), or if not then `mpq_canonicalize' must be
+ called.
+
+ The numerator and optional denominator are parsed the same as in
+ `mpz_set_str' (*note Assigning Integers::). White space is
+ allowed in the string, and is simply ignored. The BASE can vary
+ from 2 to 62, or if BASE is 0 then the leading characters are
+ used: `0x' or `0X' for hex, `0b' or `0B' for binary, `0' for
+ octal, or decimal otherwise. Note that this is done separately
+ for the numerator and denominator, so for instance `0xEF/100' is
+ 239/100, whereas `0xEF/0x100' is 239/256.
+
+ The return value is 0 if the entire string is a valid number, or
+ -1 if not.
+
+ -- Function: void mpq_swap (mpq_t ROP1, mpq_t ROP2)
+ Swap the values ROP1 and ROP2 efficiently.
+
+
+File: gmp.info, Node: Rational Conversions, Next: Rational Arithmetic, Prev: Initializing Rationals, Up: Rational Number Functions
+
+6.2 Conversion Functions
+========================
+
+ -- Function: double mpq_get_d (const mpq_t OP)
+ Convert OP to a `double', truncating if necessary (i.e. rounding
+ towards zero).
+
+ If the exponent from the conversion is too big or too small to fit
+ a `double' then the result is system dependent. For too big an
+ infinity is returned when available. For too small 0.0 is
+ normally returned. Hardware overflow, underflow and denorm traps
+ may or may not occur.
+
+ -- Function: void mpq_set_d (mpq_t ROP, double OP)
+ -- Function: void mpq_set_f (mpq_t ROP, const mpf_t OP)
+ Set ROP to the value of OP. There is no rounding, this conversion
+ is exact.
+
+ -- Function: char * mpq_get_str (char *STR, int BASE, const mpq_t OP)
+ Convert OP to a string of digits in base BASE. The base may vary
+ from 2 to 36. The string will be of the form `num/den', or if the
+ denominator is 1 then just `num'.
+
+ If STR is `NULL', the result string is allocated using the current
+ allocation function (*note Custom Allocation::). The block will be
+ `strlen(str)+1' bytes, that being exactly enough for the string and
+ null-terminator.
+
+ If STR is not `NULL', it should point to a block of storage large
+ enough for the result, that being
+
+ mpz_sizeinbase (mpq_numref(OP), BASE)
+ + mpz_sizeinbase (mpq_denref(OP), BASE) + 3
+
+ The three extra bytes are for a possible minus sign, possible
+ slash, and the null-terminator.
+
+ A pointer to the result string is returned, being either the
+ allocated block, or the given STR.
+
+
+File: gmp.info, Node: Rational Arithmetic, Next: Comparing Rationals, Prev: Rational Conversions, Up: Rational Number Functions
+
+6.3 Arithmetic Functions
+========================
+
+ -- Function: void mpq_add (mpq_t SUM, const mpq_t ADDEND1, const mpq_t
+ ADDEND2)
+ Set SUM to ADDEND1 + ADDEND2.
+
+ -- Function: void mpq_sub (mpq_t DIFFERENCE, const mpq_t MINUEND,
+ const mpq_t SUBTRAHEND)
+ Set DIFFERENCE to MINUEND - SUBTRAHEND.
+
+ -- Function: void mpq_mul (mpq_t PRODUCT, const mpq_t MULTIPLIER,
+ const mpq_t MULTIPLICAND)
+ Set PRODUCT to MULTIPLIER times MULTIPLICAND.
+
+ -- Function: void mpq_mul_2exp (mpq_t ROP, const mpq_t OP1,
+ mp_bitcnt_t OP2)
+ Set ROP to OP1 times 2 raised to OP2.
+
+ -- Function: void mpq_div (mpq_t QUOTIENT, const mpq_t DIVIDEND, const
+ mpq_t DIVISOR)
+ Set QUOTIENT to DIVIDEND/DIVISOR.
+
+ -- Function: void mpq_div_2exp (mpq_t ROP, const mpq_t OP1,
+ mp_bitcnt_t OP2)
+ Set ROP to OP1 divided by 2 raised to OP2.
+
+ -- Function: void mpq_neg (mpq_t NEGATED_OPERAND, const mpq_t OPERAND)
+ Set NEGATED_OPERAND to -OPERAND.
+
+ -- Function: void mpq_abs (mpq_t ROP, const mpq_t OP)
+ Set ROP to the absolute value of OP.
+
+ -- Function: void mpq_inv (mpq_t INVERTED_NUMBER, const mpq_t NUMBER)
+ Set INVERTED_NUMBER to 1/NUMBER. If the new denominator is zero,
+ this routine will divide by zero.
+
+
+File: gmp.info, Node: Comparing Rationals, Next: Applying Integer Functions, Prev: Rational Arithmetic, Up: Rational Number Functions
+
+6.4 Comparison Functions
+========================
+
+ -- Function: int mpq_cmp (const mpq_t OP1, const mpq_t OP2)
+ Compare OP1 and OP2. Return a positive value if OP1 > OP2, zero
+ if OP1 = OP2, and a negative value if OP1 < OP2.
+
+ To determine if two rationals are equal, `mpq_equal' is faster than
+ `mpq_cmp'.
+
+ -- Macro: int mpq_cmp_ui (const mpq_t OP1, unsigned long int NUM2,
+ unsigned long int DEN2)
+ -- Macro: int mpq_cmp_si (const mpq_t OP1, long int NUM2, unsigned
+ long int DEN2)
+ Compare OP1 and NUM2/DEN2. Return a positive value if OP1 >
+ NUM2/DEN2, zero if OP1 = NUM2/DEN2, and a negative value if OP1 <
+ NUM2/DEN2.
+
+ NUM2 and DEN2 are allowed to have common factors.
+
+ These functions are implemented as a macros and evaluate their
+ arguments multiple times.
+
+ -- Macro: int mpq_sgn (const mpq_t OP)
+ Return +1 if OP > 0, 0 if OP = 0, and -1 if OP < 0.
+
+ This function is actually implemented as a macro. It evaluates its
+ argument multiple times.
+
+ -- Function: int mpq_equal (const mpq_t OP1, const mpq_t OP2)
+ Return non-zero if OP1 and OP2 are equal, zero if they are
+ non-equal. Although `mpq_cmp' can be used for the same purpose,
+ this function is much faster.
+
+
+File: gmp.info, Node: Applying Integer Functions, Next: I/O of Rationals, Prev: Comparing Rationals, Up: Rational Number Functions
+
+6.5 Applying Integer Functions to Rationals
+===========================================
+
+The set of `mpq' functions is quite small. In particular, there are few
+functions for either input or output. The following functions give
+direct access to the numerator and denominator of an `mpq_t'.
+
+ Note that if an assignment to the numerator and/or denominator could
+take an `mpq_t' out of the canonical form described at the start of
+this chapter (*note Rational Number Functions::) then
+`mpq_canonicalize' must be called before any other `mpq' functions are
+applied to that `mpq_t'.
+
+ -- Macro: mpz_t mpq_numref (const mpq_t OP)
+ -- Macro: mpz_t mpq_denref (const mpq_t OP)
+ Return a reference to the numerator and denominator of OP,
+ respectively. The `mpz' functions can be used on the result of
+ these macros.
+
+ -- Function: void mpq_get_num (mpz_t NUMERATOR, const mpq_t RATIONAL)
+ -- Function: void mpq_get_den (mpz_t DENOMINATOR, const mpq_t RATIONAL)
+ -- Function: void mpq_set_num (mpq_t RATIONAL, const mpz_t NUMERATOR)
+ -- Function: void mpq_set_den (mpq_t RATIONAL, const mpz_t DENOMINATOR)
+ Get or set the numerator or denominator of a rational. These
+ functions are equivalent to calling `mpz_set' with an appropriate
+ `mpq_numref' or `mpq_denref'. Direct use of `mpq_numref' or
+ `mpq_denref' is recommended instead of these functions.
+
+
+File: gmp.info, Node: I/O of Rationals, Prev: Applying Integer Functions, Up: Rational Number Functions
+
+6.6 Input and Output Functions
+==============================
+
+Functions that perform input from a stdio stream, and functions that
+output to a stdio stream, of `mpq' numbers. Passing a `NULL' pointer
+for a STREAM argument to any of these functions will make them read from
+`stdin' and write to `stdout', respectively.
+
+ When using any of these functions, it is a good idea to include
+`stdio.h' before `gmp.h', since that will allow `gmp.h' to define
+prototypes for these functions.
+
+ See also *note Formatted Output:: and *note Formatted Input::.
+
+ -- Function: size_t mpq_out_str (FILE *STREAM, int BASE, const mpq_t
+ OP)
+ Output OP on stdio stream STREAM, as a string of digits in base
+ BASE. The base may vary from 2 to 36. Output is in the form
+ `num/den' or if the denominator is 1 then just `num'.
+
+ Return the number of bytes written, or if an error occurred,
+ return 0.
+
+ -- Function: size_t mpq_inp_str (mpq_t ROP, FILE *STREAM, int BASE)
+ Read a string of digits from STREAM and convert them to a rational
+ in ROP. Any initial white-space characters are read and
+ discarded. Return the number of characters read (including white
+ space), or 0 if a rational could not be read.
+
+ The input can be a fraction like `17/63' or just an integer like
+ `123'. Reading stops at the first character not in this form, and
+ white space is not permitted within the string. If the input
+ might not be in canonical form, then `mpq_canonicalize' must be
+ called (*note Rational Number Functions::).
+
+ The BASE can be between 2 and 36, or can be 0 in which case the
+ leading characters of the string determine the base, `0x' or `0X'
+ for hexadecimal, `0' for octal, or decimal otherwise. The leading
+ characters are examined separately for the numerator and
+ denominator of a fraction, so for instance `0x10/11' is 16/11,
+ whereas `0x10/0x11' is 16/17.
+
+
+File: gmp.info, Node: Floating-point Functions, Next: Low-level Functions, Prev: Rational Number Functions, Up: Top
+
+7 Floating-point Functions
+**************************
+
+GMP floating point numbers are stored in objects of type `mpf_t' and
+functions operating on them have an `mpf_' prefix.
+
+ The mantissa of each float has a user-selectable precision, limited
+only by available memory. Each variable has its own precision, and
+that can be increased or decreased at any time.
+
+ The exponent of each float is a fixed precision, one machine word on
+most systems. In the current implementation the exponent is a count of
+limbs, so for example on a 32-bit system this means a range of roughly
+2^-68719476768 to 2^68719476736, or on a 64-bit system this will be
+greater. Note however that `mpf_get_str' can only return an exponent
+which fits an `mp_exp_t' and currently `mpf_set_str' doesn't accept
+exponents bigger than a `long'.
+
+ Each variable keeps a size for the mantissa data actually in use.
+This means that if a float is exactly represented in only a few bits
+then only those bits will be used in a calculation, even if the
+selected precision is high.
+
+ All calculations are performed to the precision of the destination
+variable. Each function is defined to calculate with "infinite
+precision" followed by a truncation to the destination precision, but
+of course the work done is only what's needed to determine a result
+under that definition.
+
+ The precision selected by the user for a variable is a minimum
+value, GMP may increase it to facilitate efficient calculation.
+Currently this means rounding up to a whole limb, and then sometimes
+having a further partial limb, depending on the high limb of the
+mantissa.
+
+ The mantissa is stored in binary. One consequence of this is that
+decimal fractions like 0.1 cannot be represented exactly. The same is
+true of plain IEEE `double' floats. This makes both highly unsuitable
+for calculations involving money or other values that should be exact
+decimal fractions. (Suitably scaled integers, or perhaps rationals,
+are better choices.)
+
+ The `mpf' functions and variables have no special notion of infinity
+or not-a-number, and applications must take care not to overflow the
+exponent or results will be unpredictable. This might change in a
+future release.
+
+ Note that the `mpf' functions are _not_ intended as a smooth
+extension to IEEE P754 arithmetic. In particular results obtained on
+one computer often differ from the results on a computer with a
+different word size.
+
+ The GMP extension library MPFR (`http://mpfr.org') is an alternative
+to GMP's `mpf' functions. MPFR provides well-defined precision and
+accurate rounding, and thereby naturally extends IEEE P754.
+
+* Menu:
+
+* Initializing Floats::
+* Assigning Floats::
+* Simultaneous Float Init & Assign::
+* Converting Floats::
+* Float Arithmetic::
+* Float Comparison::
+* I/O of Floats::
+* Miscellaneous Float Functions::
+
+
+File: gmp.info, Node: Initializing Floats, Next: Assigning Floats, Prev: Floating-point Functions, Up: Floating-point Functions
+
+7.1 Initialization Functions
+============================
+
+ -- Function: void mpf_set_default_prec (mp_bitcnt_t PREC)
+ Set the default precision to be *at least* PREC bits. All
+ subsequent calls to `mpf_init' will use this precision, but
+ previously initialized variables are unaffected.
+
+ -- Function: mp_bitcnt_t mpf_get_default_prec (void)
+ Return the default precision actually used.
+
+ An `mpf_t' object must be initialized before storing the first value
+in it. The functions `mpf_init' and `mpf_init2' are used for that
+purpose.
+
+ -- Function: void mpf_init (mpf_t X)
+ Initialize X to 0. Normally, a variable should be initialized
+ once only or at least be cleared, using `mpf_clear', between
+ initializations. The precision of X is undefined unless a default
+ precision has already been established by a call to
+ `mpf_set_default_prec'.
+
+ -- Function: void mpf_init2 (mpf_t X, mp_bitcnt_t PREC)
+ Initialize X to 0 and set its precision to be *at least* PREC
+ bits. Normally, a variable should be initialized once only or at
+ least be cleared, using `mpf_clear', between initializations.
+
+ -- Function: void mpf_inits (mpf_t X, ...)
+ Initialize a NULL-terminated list of `mpf_t' variables, and set
+ their values to 0. The precision of the initialized variables is
+ undefined unless a default precision has already been established
+ by a call to `mpf_set_default_prec'.
+
+ -- Function: void mpf_clear (mpf_t X)
+ Free the space occupied by X. Make sure to call this function for
+ all `mpf_t' variables when you are done with them.
+
+ -- Function: void mpf_clears (mpf_t X, ...)
+ Free the space occupied by a NULL-terminated list of `mpf_t'
+ variables.
+
+ Here is an example on how to initialize floating-point variables:
+ {
+ mpf_t x, y;
+ mpf_init (x); /* use default precision */
+ mpf_init2 (y, 256); /* precision _at least_ 256 bits */
+ ...
+ /* Unless the program is about to exit, do ... */
+ mpf_clear (x);
+ mpf_clear (y);
+ }
+
+ The following three functions are useful for changing the precision
+during a calculation. A typical use would be for adjusting the
+precision gradually in iterative algorithms like Newton-Raphson, making
+the computation precision closely match the actual accurate part of the
+numbers.
+
+ -- Function: mp_bitcnt_t mpf_get_prec (const mpf_t OP)
+ Return the current precision of OP, in bits.
+
+ -- Function: void mpf_set_prec (mpf_t ROP, mp_bitcnt_t PREC)
+ Set the precision of ROP to be *at least* PREC bits. The value in
+ ROP will be truncated to the new precision.
+
+ This function requires a call to `realloc', and so should not be
+ used in a tight loop.
+
+ -- Function: void mpf_set_prec_raw (mpf_t ROP, mp_bitcnt_t PREC)
+ Set the precision of ROP to be *at least* PREC bits, without
+ changing the memory allocated.
+
+ PREC must be no more than the allocated precision for ROP, that
+ being the precision when ROP was initialized, or in the most recent
+ `mpf_set_prec'.
+
+ The value in ROP is unchanged, and in particular if it had a higher
+ precision than PREC it will retain that higher precision. New
+ values written to ROP will use the new PREC.
+
+ Before calling `mpf_clear' or the full `mpf_set_prec', another
+ `mpf_set_prec_raw' call must be made to restore ROP to its original
+ allocated precision. Failing to do so will have unpredictable
+ results.
+
+ `mpf_get_prec' can be used before `mpf_set_prec_raw' to get the
+ original allocated precision. After `mpf_set_prec_raw' it
+ reflects the PREC value set.
+
+ `mpf_set_prec_raw' is an efficient way to use an `mpf_t' variable
+ at different precisions during a calculation, perhaps to gradually
+ increase precision in an iteration, or just to use various
+ different precisions for different purposes during a calculation.
+
+
+File: gmp.info, Node: Assigning Floats, Next: Simultaneous Float Init & Assign, Prev: Initializing Floats, Up: Floating-point Functions
+
+7.2 Assignment Functions
+========================
+
+These functions assign new values to already initialized floats (*note
+Initializing Floats::).
+
+ -- Function: void mpf_set (mpf_t ROP, const mpf_t OP)
+ -- Function: void mpf_set_ui (mpf_t ROP, unsigned long int OP)
+ -- Function: void mpf_set_si (mpf_t ROP, signed long int OP)
+ -- Function: void mpf_set_d (mpf_t ROP, double OP)
+ -- Function: void mpf_set_z (mpf_t ROP, const mpz_t OP)
+ -- Function: void mpf_set_q (mpf_t ROP, const mpq_t OP)
+ Set the value of ROP from OP.
+
+ -- Function: int mpf_set_str (mpf_t ROP, const char *STR, int BASE)
+ Set the value of ROP from the string in STR. The string is of the
+ form `M@N' or, if the base is 10 or less, alternatively `MeN'.
+ `M' is the mantissa and `N' is the exponent. The mantissa is
+ always in the specified base. The exponent is either in the
+ specified base or, if BASE is negative, in decimal. The decimal
+ point expected is taken from the current locale, on systems
+ providing `localeconv'.
+
+ The argument BASE may be in the ranges 2 to 62, or -62 to -2.
+ Negative values are used to specify that the exponent is in
+ decimal.
+
+ For bases up to 36, case is ignored; upper-case and lower-case
+ letters have the same value; for bases 37 to 62, upper-case letter
+ represent the usual 10..35 while lower-case letter represent
+ 36..61.
+
+ Unlike the corresponding `mpz' function, the base will not be
+ determined from the leading characters of the string if BASE is 0.
+ This is so that numbers like `0.23' are not interpreted as octal.
+
+ White space is allowed in the string, and is simply ignored.
+ [This is not really true; white-space is ignored in the beginning
+ of the string and within the mantissa, but not in other places,
+ such as after a minus sign or in the exponent. We are considering
+ changing the definition of this function, making it fail when
+ there is any white-space in the input, since that makes a lot of
+ sense. Please tell us your opinion about this change. Do you
+ really want it to accept "3 14" as meaning 314 as it does now?]
+
+ This function returns 0 if the entire string is a valid number in
+ base BASE. Otherwise it returns -1.
+
+ -- Function: void mpf_swap (mpf_t ROP1, mpf_t ROP2)
+ Swap ROP1 and ROP2 efficiently. Both the values and the
+ precisions of the two variables are swapped.
+
+
+File: gmp.info, Node: Simultaneous Float Init & Assign, Next: Converting Floats, Prev: Assigning Floats, Up: Floating-point Functions
+
+7.3 Combined Initialization and Assignment Functions
+====================================================
+
+For convenience, GMP provides a parallel series of initialize-and-set
+functions which initialize the output and then store the value there.
+These functions' names have the form `mpf_init_set...'
+
+ Once the float has been initialized by any of the `mpf_init_set...'
+functions, it can be used as the source or destination operand for the
+ordinary float functions. Don't use an initialize-and-set function on
+a variable already initialized!
+
+ -- Function: void mpf_init_set (mpf_t ROP, const mpf_t OP)
+ -- Function: void mpf_init_set_ui (mpf_t ROP, unsigned long int OP)
+ -- Function: void mpf_init_set_si (mpf_t ROP, signed long int OP)
+ -- Function: void mpf_init_set_d (mpf_t ROP, double OP)
+ Initialize ROP and set its value from OP.
+
+ The precision of ROP will be taken from the active default
+ precision, as set by `mpf_set_default_prec'.
+
+ -- Function: int mpf_init_set_str (mpf_t ROP, const char *STR, int
+ BASE)
+ Initialize ROP and set its value from the string in STR. See
+ `mpf_set_str' above for details on the assignment operation.
+
+ Note that ROP is initialized even if an error occurs. (I.e., you
+ have to call `mpf_clear' for it.)
+
+ The precision of ROP will be taken from the active default
+ precision, as set by `mpf_set_default_prec'.
+
+
+File: gmp.info, Node: Converting Floats, Next: Float Arithmetic, Prev: Simultaneous Float Init & Assign, Up: Floating-point Functions
+
+7.4 Conversion Functions
+========================
+
+ -- Function: double mpf_get_d (const mpf_t OP)
+ Convert OP to a `double', truncating if necessary (i.e. rounding
+ towards zero).
+
+ If the exponent in OP is too big or too small to fit a `double'
+ then the result is system dependent. For too big an infinity is
+ returned when available. For too small 0.0 is normally returned.
+ Hardware overflow, underflow and denorm traps may or may not occur.
+
+ -- Function: double mpf_get_d_2exp (signed long int *EXP, const mpf_t
+ OP)
+ Convert OP to a `double', truncating if necessary (i.e. rounding
+ towards zero), and with an exponent returned separately.
+
+ The return value is in the range 0.5<=abs(D)<1 and the exponent is
+ stored to `*EXP'. D * 2^EXP is the (truncated) OP value. If OP
+ is zero, the return is 0.0 and 0 is stored to `*EXP'.
+
+ This is similar to the standard C `frexp' function (*note
+ Normalization Functions: (libc)Normalization Functions.).
+
+ -- Function: long mpf_get_si (const mpf_t OP)
+ -- Function: unsigned long mpf_get_ui (const mpf_t OP)
+ Convert OP to a `long' or `unsigned long', truncating any fraction
+ part. If OP is too big for the return type, the result is
+ undefined.
+
+ See also `mpf_fits_slong_p' and `mpf_fits_ulong_p' (*note
+ Miscellaneous Float Functions::).
+
+ -- Function: char * mpf_get_str (char *STR, mp_exp_t *EXPPTR, int
+ BASE, size_t N_DIGITS, const mpf_t OP)
+ Convert OP to a string of digits in base BASE. The base argument
+ may vary from 2 to 62 or from -2 to -36. Up to N_DIGITS digits
+ will be generated. Trailing zeros are not returned. No more
+ digits than can be accurately represented by OP are ever
+ generated. If N_DIGITS is 0 then that accurate maximum number of
+ digits are generated.
+
+ For BASE in the range 2..36, digits and lower-case letters are
+ used; for -2..-36, digits and upper-case letters are used; for
+ 37..62, digits, upper-case letters, and lower-case letters (in
+ that significance order) are used.
+
+ If STR is `NULL', the result string is allocated using the current
+ allocation function (*note Custom Allocation::). The block will be
+ `strlen(str)+1' bytes, that being exactly enough for the string and
+ null-terminator.
+
+ If STR is not `NULL', it should point to a block of N_DIGITS + 2
+ bytes, that being enough for the mantissa, a possible minus sign,
+ and a null-terminator. When N_DIGITS is 0 to get all significant
+ digits, an application won't be able to know the space required,
+ and STR should be `NULL' in that case.
+
+ The generated string is a fraction, with an implicit radix point
+ immediately to the left of the first digit. The applicable
+ exponent is written through the EXPPTR pointer. For example, the
+ number 3.1416 would be returned as string "31416" and exponent 1.
+
+ When OP is zero, an empty string is produced and the exponent
+ returned is 0.
+
+ A pointer to the result string is returned, being either the
+ allocated block or the given STR.
+
+
+File: gmp.info, Node: Float Arithmetic, Next: Float Comparison, Prev: Converting Floats, Up: Floating-point Functions
+
+7.5 Arithmetic Functions
+========================
+
+ -- Function: void mpf_add (mpf_t ROP, const mpf_t OP1, const mpf_t OP2)
+ -- Function: void mpf_add_ui (mpf_t ROP, const mpf_t OP1, unsigned
+ long int OP2)
+ Set ROP to OP1 + OP2.
+
+ -- Function: void mpf_sub (mpf_t ROP, const mpf_t OP1, const mpf_t OP2)
+ -- Function: void mpf_ui_sub (mpf_t ROP, unsigned long int OP1, const
+ mpf_t OP2)
+ -- Function: void mpf_sub_ui (mpf_t ROP, const mpf_t OP1, unsigned
+ long int OP2)
+ Set ROP to OP1 - OP2.
+
+ -- Function: void mpf_mul (mpf_t ROP, const mpf_t OP1, const mpf_t OP2)
+ -- Function: void mpf_mul_ui (mpf_t ROP, const mpf_t OP1, unsigned
+ long int OP2)
+ Set ROP to OP1 times OP2.
+
+ Division is undefined if the divisor is zero, and passing a zero
+divisor to the divide functions will make these functions intentionally
+divide by zero. This lets the user handle arithmetic exceptions in
+these functions in the same manner as other arithmetic exceptions.
+
+ -- Function: void mpf_div (mpf_t ROP, const mpf_t OP1, const mpf_t OP2)
+ -- Function: void mpf_ui_div (mpf_t ROP, unsigned long int OP1, const
+ mpf_t OP2)
+ -- Function: void mpf_div_ui (mpf_t ROP, const mpf_t OP1, unsigned
+ long int OP2)
+ Set ROP to OP1/OP2.
+
+ -- Function: void mpf_sqrt (mpf_t ROP, const mpf_t OP)
+ -- Function: void mpf_sqrt_ui (mpf_t ROP, unsigned long int OP)
+ Set ROP to the square root of OP.
+
+ -- Function: void mpf_pow_ui (mpf_t ROP, const mpf_t OP1, unsigned
+ long int OP2)
+ Set ROP to OP1 raised to the power OP2.
+
+ -- Function: void mpf_neg (mpf_t ROP, const mpf_t OP)
+ Set ROP to -OP.
+
+ -- Function: void mpf_abs (mpf_t ROP, const mpf_t OP)
+ Set ROP to the absolute value of OP.
+
+ -- Function: void mpf_mul_2exp (mpf_t ROP, const mpf_t OP1,
+ mp_bitcnt_t OP2)
+ Set ROP to OP1 times 2 raised to OP2.
+
+ -- Function: void mpf_div_2exp (mpf_t ROP, const mpf_t OP1,
+ mp_bitcnt_t OP2)
+ Set ROP to OP1 divided by 2 raised to OP2.
+
+
+File: gmp.info, Node: Float Comparison, Next: I/O of Floats, Prev: Float Arithmetic, Up: Floating-point Functions
+
+7.6 Comparison Functions
+========================
+
+ -- Function: int mpf_cmp (const mpf_t OP1, const mpf_t OP2)
+ -- Function: int mpf_cmp_d (const mpf_t OP1, double OP2)
+ -- Function: int mpf_cmp_ui (const mpf_t OP1, unsigned long int OP2)
+ -- Function: int mpf_cmp_si (const mpf_t OP1, signed long int OP2)
+ Compare OP1 and OP2. Return a positive value if OP1 > OP2, zero
+ if OP1 = OP2, and a negative value if OP1 < OP2.
+
+ `mpf_cmp_d' can be called with an infinity, but results are
+ undefined for a NaN.
+
+ -- Function: int mpf_eq (const mpf_t OP1, const mpf_t OP2, mp_bitcnt_t
+ op3)
+ Return non-zero if the first OP3 bits of OP1 and OP2 are equal,
+ zero otherwise. I.e., test if OP1 and OP2 are approximately equal.
+
+ Caution 1: All version of GMP up to version 4.2.4 compared just
+ whole limbs, meaning sometimes more than OP3 bits, sometimes fewer.
+
+ Caution 2: This function will consider XXX11...111 and XX100...000
+ different, even if ... is replaced by a semi-infinite number of
+ bits. Such numbers are really just one ulp off, and should be
+ considered equal.
+
+ -- Function: void mpf_reldiff (mpf_t ROP, const mpf_t OP1, const mpf_t
+ OP2)
+ Compute the relative difference between OP1 and OP2 and store the
+ result in ROP. This is abs(OP1-OP2)/OP1.
+
+ -- Macro: int mpf_sgn (const mpf_t OP)
+ Return +1 if OP > 0, 0 if OP = 0, and -1 if OP < 0.
+
+ This function is actually implemented as a macro. It evaluates
+ its argument multiple times.
+
+
+File: gmp.info, Node: I/O of Floats, Next: Miscellaneous Float Functions, Prev: Float Comparison, Up: Floating-point Functions
+
+7.7 Input and Output Functions
+==============================
+
+Functions that perform input from a stdio stream, and functions that
+output to a stdio stream, of `mpf' numbers. Passing a `NULL' pointer
+for a STREAM argument to any of these functions will make them read from
+`stdin' and write to `stdout', respectively.
+
+ When using any of these functions, it is a good idea to include
+`stdio.h' before `gmp.h', since that will allow `gmp.h' to define
+prototypes for these functions.
+
+ See also *note Formatted Output:: and *note Formatted Input::.
+
+ -- Function: size_t mpf_out_str (FILE *STREAM, int BASE, size_t
+ N_DIGITS, const mpf_t OP)
+ Print OP to STREAM, as a string of digits. Return the number of
+ bytes written, or if an error occurred, return 0.
+
+ The mantissa is prefixed with an `0.' and is in the given BASE,
+ which may vary from 2 to 62 or from -2 to -36. An exponent is
+ then printed, separated by an `e', or if the base is greater than
+ 10 then by an `@'. The exponent is always in decimal. The
+ decimal point follows the current locale, on systems providing
+ `localeconv'.
+
+ For BASE in the range 2..36, digits and lower-case letters are
+ used; for -2..-36, digits and upper-case letters are used; for
+ 37..62, digits, upper-case letters, and lower-case letters (in
+ that significance order) are used.
+
+ Up to N_DIGITS will be printed from the mantissa, except that no
+ more digits than are accurately representable by OP will be
+ printed. N_DIGITS can be 0 to select that accurate maximum.
+
+ -- Function: size_t mpf_inp_str (mpf_t ROP, FILE *STREAM, int BASE)
+ Read a string in base BASE from STREAM, and put the read float in
+ ROP. The string is of the form `M@N' or, if the base is 10 or
+ less, alternatively `MeN'. `M' is the mantissa and `N' is the
+ exponent. The mantissa is always in the specified base. The
+ exponent is either in the specified base or, if BASE is negative,
+ in decimal. The decimal point expected is taken from the current
+ locale, on systems providing `localeconv'.
+
+ The argument BASE may be in the ranges 2 to 36, or -36 to -2.
+ Negative values are used to specify that the exponent is in
+ decimal.
+
+ Unlike the corresponding `mpz' function, the base will not be
+ determined from the leading characters of the string if BASE is 0.
+ This is so that numbers like `0.23' are not interpreted as octal.
+
+ Return the number of bytes read, or if an error occurred, return 0.
+
+
+File: gmp.info, Node: Miscellaneous Float Functions, Prev: I/O of Floats, Up: Floating-point Functions
+
+7.8 Miscellaneous Functions
+===========================
+
+ -- Function: void mpf_ceil (mpf_t ROP, const mpf_t OP)
+ -- Function: void mpf_floor (mpf_t ROP, const mpf_t OP)
+ -- Function: void mpf_trunc (mpf_t ROP, const mpf_t OP)
+ Set ROP to OP rounded to an integer. `mpf_ceil' rounds to the
+ next higher integer, `mpf_floor' to the next lower, and `mpf_trunc'
+ to the integer towards zero.
+
+ -- Function: int mpf_integer_p (const mpf_t OP)
+ Return non-zero if OP is an integer.
+
+ -- Function: int mpf_fits_ulong_p (const mpf_t OP)
+ -- Function: int mpf_fits_slong_p (const mpf_t OP)
+ -- Function: int mpf_fits_uint_p (const mpf_t OP)
+ -- Function: int mpf_fits_sint_p (const mpf_t OP)
+ -- Function: int mpf_fits_ushort_p (const mpf_t OP)
+ -- Function: int mpf_fits_sshort_p (const mpf_t OP)
+ Return non-zero if OP would fit in the respective C data type, when
+ truncated to an integer.
+
+ -- Function: void mpf_urandomb (mpf_t ROP, gmp_randstate_t STATE,
+ mp_bitcnt_t NBITS)
+ Generate a uniformly distributed random float in ROP, such that 0
+ <= ROP < 1, with NBITS significant bits in the mantissa or less if
+ the precision of ROP is smaller.
+
+ The variable STATE must be initialized by calling one of the
+ `gmp_randinit' functions (*note Random State Initialization::)
+ before invoking this function.
+
+ -- Function: void mpf_random2 (mpf_t ROP, mp_size_t MAX_SIZE, mp_exp_t
+ EXP)
+ Generate a random float of at most MAX_SIZE limbs, with long
+ strings of zeros and ones in the binary representation. The
+ exponent of the number is in the interval -EXP to EXP (in limbs).
+ This function is useful for testing functions and algorithms,
+ since these kind of random numbers have proven to be more likely
+ to trigger corner-case bugs. Negative random numbers are
+ generated when MAX_SIZE is negative.
+
+
+File: gmp.info, Node: Low-level Functions, Next: Random Number Functions, Prev: Floating-point Functions, Up: Top
+
+8 Low-level Functions
+*********************
+
+This chapter describes low-level GMP functions, used to implement the
+high-level GMP functions, but also intended for time-critical user code.
+
+ These functions start with the prefix `mpn_'.
+
+ The `mpn' functions are designed to be as fast as possible, *not* to
+provide a coherent calling interface. The different functions have
+somewhat similar interfaces, but there are variations that make them
+hard to use. These functions do as little as possible apart from the
+real multiple precision computation, so that no time is spent on things
+that not all callers need.
+
+ A source operand is specified by a pointer to the least significant
+limb and a limb count. A destination operand is specified by just a
+pointer. It is the responsibility of the caller to ensure that the
+destination has enough space for storing the result.
+
+ With this way of specifying operands, it is possible to perform
+computations on subranges of an argument, and store the result into a
+subrange of a destination.
+
+ A common requirement for all functions is that each source area
+needs at least one limb. No size argument may be zero. Unless
+otherwise stated, in-place operations are allowed where source and
+destination are the same, but not where they only partly overlap.
+
+ The `mpn' functions are the base for the implementation of the
+`mpz_', `mpf_', and `mpq_' functions.
+
+ This example adds the number beginning at S1P and the number
+beginning at S2P and writes the sum at DESTP. All areas have N limbs.
+
+ cy = mpn_add_n (destp, s1p, s2p, n)
+
+ It should be noted that the `mpn' functions make no attempt to
+identify high or low zero limbs on their operands, or other special
+forms. On random data such cases will be unlikely and it'd be wasteful
+for every function to check every time. An application knowing
+something about its data can take steps to trim or perhaps split its
+calculations.
+
+
+In the notation used below, a source operand is identified by the
+pointer to the least significant limb, and the limb count in braces.
+For example, {S1P, S1N}.
+
+ -- Function: mp_limb_t mpn_add_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Add {S1P, N} and {S2P, N}, and write the N least significant limbs
+ of the result to RP. Return carry, either 0 or 1.
+
+ This is the lowest-level function for addition. It is the
+ preferred function for addition, since it is written in assembly
+ for most CPUs. For addition of a variable to itself (i.e., S1P
+ equals S2P) use `mpn_lshift' with a count of 1 for optimal speed.
+
+ -- Function: mp_limb_t mpn_add_1 (mp_limb_t *RP, const mp_limb_t *S1P,
+ mp_size_t N, mp_limb_t S2LIMB)
+ Add {S1P, N} and S2LIMB, and write the N least significant limbs
+ of the result to RP. Return carry, either 0 or 1.
+
+ -- Function: mp_limb_t mpn_add (mp_limb_t *RP, const mp_limb_t *S1P,
+ mp_size_t S1N, const mp_limb_t *S2P, mp_size_t S2N)
+ Add {S1P, S1N} and {S2P, S2N}, and write the S1N least significant
+ limbs of the result to RP. Return carry, either 0 or 1.
+
+ This function requires that S1N is greater than or equal to S2N.
+
+ -- Function: mp_limb_t mpn_sub_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Subtract {S2P, N} from {S1P, N}, and write the N least significant
+ limbs of the result to RP. Return borrow, either 0 or 1.
+
+ This is the lowest-level function for subtraction. It is the
+ preferred function for subtraction, since it is written in
+ assembly for most CPUs.
+
+ -- Function: mp_limb_t mpn_sub_1 (mp_limb_t *RP, const mp_limb_t *S1P,
+ mp_size_t N, mp_limb_t S2LIMB)
+ Subtract S2LIMB from {S1P, N}, and write the N least significant
+ limbs of the result to RP. Return borrow, either 0 or 1.
+
+ -- Function: mp_limb_t mpn_sub (mp_limb_t *RP, const mp_limb_t *S1P,
+ mp_size_t S1N, const mp_limb_t *S2P, mp_size_t S2N)
+ Subtract {S2P, S2N} from {S1P, S1N}, and write the S1N least
+ significant limbs of the result to RP. Return borrow, either 0 or
+ 1.
+
+ This function requires that S1N is greater than or equal to S2N.
+
+ -- Function: mp_limb_t mpn_neg (mp_limb_t *RP, const mp_limb_t *SP,
+ mp_size_t N)
+ Perform the negation of {SP, N}, and write the result to {RP, N}.
+ This is equivalent to calling `mpn_sub_n' with a N-limb zero
+ minuend and passing {SP, N} as subtrahend. Return borrow, either
+ 0 or 1.
+
+ -- Function: void mpn_mul_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Multiply {S1P, N} and {S2P, N}, and write the 2*N-limb result to
+ RP.
+
+ The destination has to have space for 2*N limbs, even if the
+ product's most significant limb is zero. No overlap is permitted
+ between the destination and either source.
+
+ If the two input operands are the same, use `mpn_sqr'.
+
+ -- Function: mp_limb_t mpn_mul (mp_limb_t *RP, const mp_limb_t *S1P,
+ mp_size_t S1N, const mp_limb_t *S2P, mp_size_t S2N)
+ Multiply {S1P, S1N} and {S2P, S2N}, and write the (S1N+S2N)-limb
+ result to RP. Return the most significant limb of the result.
+
+ The destination has to have space for S1N + S2N limbs, even if the
+ product's most significant limb is zero. No overlap is permitted
+ between the destination and either source.
+
+ This function requires that S1N is greater than or equal to S2N.
+
+ -- Function: void mpn_sqr (mp_limb_t *RP, const mp_limb_t *S1P,
+ mp_size_t N)
+ Compute the square of {S1P, N} and write the 2*N-limb result to RP.
+
+ The destination has to have space for 2N limbs, even if the
+ result's most significant limb is zero. No overlap is permitted
+ between the destination and the source.
+
+ -- Function: mp_limb_t mpn_mul_1 (mp_limb_t *RP, const mp_limb_t *S1P,
+ mp_size_t N, mp_limb_t S2LIMB)
+ Multiply {S1P, N} by S2LIMB, and write the N least significant
+ limbs of the product to RP. Return the most significant limb of
+ the product. {S1P, N} and {RP, N} are allowed to overlap provided
+ RP <= S1P.
+
+ This is a low-level function that is a building block for general
+ multiplication as well as other operations in GMP. It is written
+ in assembly for most CPUs.
+
+ Don't call this function if S2LIMB is a power of 2; use
+ `mpn_lshift' with a count equal to the logarithm of S2LIMB
+ instead, for optimal speed.
+
+ -- Function: mp_limb_t mpn_addmul_1 (mp_limb_t *RP, const mp_limb_t
+ *S1P, mp_size_t N, mp_limb_t S2LIMB)
+ Multiply {S1P, N} and S2LIMB, and add the N least significant
+ limbs of the product to {RP, N} and write the result to RP.
+ Return the most significant limb of the product, plus carry-out
+ from the addition.
+
+ This is a low-level function that is a building block for general
+ multiplication as well as other operations in GMP. It is written
+ in assembly for most CPUs.
+
+ -- Function: mp_limb_t mpn_submul_1 (mp_limb_t *RP, const mp_limb_t
+ *S1P, mp_size_t N, mp_limb_t S2LIMB)
+ Multiply {S1P, N} and S2LIMB, and subtract the N least significant
+ limbs of the product from {RP, N} and write the result to RP.
+ Return the most significant limb of the product, plus borrow-out
+ from the subtraction.
+
+ This is a low-level function that is a building block for general
+ multiplication and division as well as other operations in GMP.
+ It is written in assembly for most CPUs.
+
+ -- Function: void mpn_tdiv_qr (mp_limb_t *QP, mp_limb_t *RP, mp_size_t
+ QXN, const mp_limb_t *NP, mp_size_t NN, const mp_limb_t *DP,
+ mp_size_t DN)
+ Divide {NP, NN} by {DP, DN} and put the quotient at {QP, NN-DN+1}
+ and the remainder at {RP, DN}. The quotient is rounded towards 0.
+
+ No overlap is permitted between arguments, except that NP might
+ equal RP. The dividend size NN must be greater than or equal to
+ divisor size DN. The most significant limb of the divisor must be
+ non-zero. The QXN operand must be zero.
+
+ -- Function: mp_limb_t mpn_divrem (mp_limb_t *R1P, mp_size_t QXN,
+ mp_limb_t *RS2P, mp_size_t RS2N, const mp_limb_t *S3P,
+ mp_size_t S3N)
+ [This function is obsolete. Please call `mpn_tdiv_qr' instead for
+ best performance.]
+
+ Divide {RS2P, RS2N} by {S3P, S3N}, and write the quotient at R1P,
+ with the exception of the most significant limb, which is
+ returned. The remainder replaces the dividend at RS2P; it will be
+ S3N limbs long (i.e., as many limbs as the divisor).
+
+ In addition to an integer quotient, QXN fraction limbs are
+ developed, and stored after the integral limbs. For most usages,
+ QXN will be zero.
+
+ It is required that RS2N is greater than or equal to S3N. It is
+ required that the most significant bit of the divisor is set.
+
+ If the quotient is not needed, pass RS2P + S3N as R1P. Aside from
+ that special case, no overlap between arguments is permitted.
+
+ Return the most significant limb of the quotient, either 0 or 1.
+
+ The area at R1P needs to be RS2N - S3N + QXN limbs large.
+
+ -- Function: mp_limb_t mpn_divrem_1 (mp_limb_t *R1P, mp_size_t QXN,
+ mp_limb_t *S2P, mp_size_t S2N, mp_limb_t S3LIMB)
+ -- Macro: mp_limb_t mpn_divmod_1 (mp_limb_t *R1P, mp_limb_t *S2P,
+ mp_size_t S2N, mp_limb_t S3LIMB)
+ Divide {S2P, S2N} by S3LIMB, and write the quotient at R1P.
+ Return the remainder.
+
+ The integer quotient is written to {R1P+QXN, S2N} and in addition
+ QXN fraction limbs are developed and written to {R1P, QXN}.
+ Either or both S2N and QXN can be zero. For most usages, QXN will
+ be zero.
+
+ `mpn_divmod_1' exists for upward source compatibility and is
+ simply a macro calling `mpn_divrem_1' with a QXN of 0.
+
+ The areas at R1P and S2P have to be identical or completely
+ separate, not partially overlapping.
+
+ -- Function: mp_limb_t mpn_divmod (mp_limb_t *R1P, mp_limb_t *RS2P,
+ mp_size_t RS2N, const mp_limb_t *S3P, mp_size_t S3N)
+ [This function is obsolete. Please call `mpn_tdiv_qr' instead for
+ best performance.]
+
+ -- Macro: mp_limb_t mpn_divexact_by3 (mp_limb_t *RP, mp_limb_t *SP,
+ mp_size_t N)
+ -- Function: mp_limb_t mpn_divexact_by3c (mp_limb_t *RP, mp_limb_t
+ *SP, mp_size_t N, mp_limb_t CARRY)
+ Divide {SP, N} by 3, expecting it to divide exactly, and writing
+ the result to {RP, N}. If 3 divides exactly, the return value is
+ zero and the result is the quotient. If not, the return value is
+ non-zero and the result won't be anything useful.
+
+ `mpn_divexact_by3c' takes an initial carry parameter, which can be
+ the return value from a previous call, so a large calculation can
+ be done piece by piece from low to high. `mpn_divexact_by3' is
+ simply a macro calling `mpn_divexact_by3c' with a 0 carry
+ parameter.
+
+ These routines use a multiply-by-inverse and will be faster than
+ `mpn_divrem_1' on CPUs with fast multiplication but slow division.
+
+ The source a, result q, size n, initial carry i, and return value
+ c satisfy c*b^n + a-i = 3*q, where b=2^GMP_NUMB_BITS. The return
+ c is always 0, 1 or 2, and the initial carry i must also be 0, 1
+ or 2 (these are both borrows really). When c=0 clearly q=(a-i)/3.
+ When c!=0, the remainder (a-i) mod 3 is given by 3-c, because b ==
+ 1 mod 3 (when `mp_bits_per_limb' is even, which is always so
+ currently).
+
+ -- Function: mp_limb_t mpn_mod_1 (const mp_limb_t *S1P, mp_size_t S1N,
+ mp_limb_t S2LIMB)
+ Divide {S1P, S1N} by S2LIMB, and return the remainder. S1N can be
+ zero.
+
+ -- Function: mp_limb_t mpn_lshift (mp_limb_t *RP, const mp_limb_t *SP,
+ mp_size_t N, unsigned int COUNT)
+ Shift {SP, N} left by COUNT bits, and write the result to {RP, N}.
+ The bits shifted out at the left are returned in the least
+ significant COUNT bits of the return value (the rest of the return
+ value is zero).
+
+ COUNT must be in the range 1 to mp_bits_per_limb-1. The regions
+ {SP, N} and {RP, N} may overlap, provided RP >= SP.
+
+ This function is written in assembly for most CPUs.
+
+ -- Function: mp_limb_t mpn_rshift (mp_limb_t *RP, const mp_limb_t *SP,
+ mp_size_t N, unsigned int COUNT)
+ Shift {SP, N} right by COUNT bits, and write the result to {RP,
+ N}. The bits shifted out at the right are returned in the most
+ significant COUNT bits of the return value (the rest of the return
+ value is zero).
+
+ COUNT must be in the range 1 to mp_bits_per_limb-1. The regions
+ {SP, N} and {RP, N} may overlap, provided RP <= SP.
+
+ This function is written in assembly for most CPUs.
+
+ -- Function: int mpn_cmp (const mp_limb_t *S1P, const mp_limb_t *S2P,
+ mp_size_t N)
+ Compare {S1P, N} and {S2P, N} and return a positive value if S1 >
+ S2, 0 if they are equal, or a negative value if S1 < S2.
+
+ -- Function: mp_size_t mpn_gcd (mp_limb_t *RP, mp_limb_t *XP,
+ mp_size_t XN, mp_limb_t *YP, mp_size_t YN)
+ Set {RP, RETVAL} to the greatest common divisor of {XP, XN} and
+ {YP, YN}. The result can be up to YN limbs, the return value is
+ the actual number produced. Both source operands are destroyed.
+
+ It is required that XN >= YN > 0, and the most significant limb of
+ {YP, YN} must be non-zero. No overlap is permitted between {XP,
+ XN} and {YP, YN}.
+
+ -- Function: mp_limb_t mpn_gcd_1 (const mp_limb_t *XP, mp_size_t XN,
+ mp_limb_t YLIMB)
+ Return the greatest common divisor of {XP, XN} and YLIMB. Both
+ operands must be non-zero.
+
+ -- Function: mp_size_t mpn_gcdext (mp_limb_t *GP, mp_limb_t *SP,
+ mp_size_t *SN, mp_limb_t *UP, mp_size_t UN, mp_limb_t *VP,
+ mp_size_t VN)
+ Let U be defined by {UP, UN} and let V be defined by {VP, VN}.
+
+ Compute the greatest common divisor G of U and V. Compute a
+ cofactor S such that G = US + VT. The second cofactor T is not
+ computed but can easily be obtained from (G - U*S) / V (the
+ division will be exact). It is required that UN >= VN > 0, and
+ the most significant limb of {VP, VN} must be non-zero.
+
+ S satisfies S = 1 or abs(S) < V / (2 G). S = 0 if and only if V
+ divides U (i.e., G = V).
+
+ Store G at GP and let the return value define its limb count.
+ Store S at SP and let |*SN| define its limb count. S can be
+ negative; when this happens *SN will be negative. The area at GP
+ should have room for VN limbs and the area at SP should have room
+ for VN+1 limbs.
+
+ Both source operands are destroyed.
+
+ Compatibility notes: GMP 4.3.0 and 4.3.1 defined S less strictly.
+ Earlier as well as later GMP releases define S as described here.
+ GMP releases before GMP 4.3.0 required additional space for both
+ input and output areas. More precisely, the areas {UP, UN+1} and
+ {VP, VN+1} were destroyed (i.e. the operands plus an extra limb
+ past the end of each), and the areas pointed to by GP and SP
+ should each have room for UN+1 limbs.
+
+ -- Function: mp_size_t mpn_sqrtrem (mp_limb_t *R1P, mp_limb_t *R2P,
+ const mp_limb_t *SP, mp_size_t N)
+ Compute the square root of {SP, N} and put the result at {R1P,
+ ceil(N/2)} and the remainder at {R2P, RETVAL}. R2P needs space
+ for N limbs, but the return value indicates how many are produced.
+
+ The most significant limb of {SP, N} must be non-zero. The areas
+ {R1P, ceil(N/2)} and {SP, N} must be completely separate. The
+ areas {R2P, N} and {SP, N} must be either identical or completely
+ separate.
+
+ If the remainder is not wanted then R2P can be `NULL', and in this
+ case the return value is zero or non-zero according to whether the
+ remainder would have been zero or non-zero.
+
+ A return value of zero indicates a perfect square. See also
+ `mpn_perfect_square_p'.
+
+ -- Function: size_t mpn_sizeinbase (const mp_limb_t *XP, mp_size_t N,
+ int BASE)
+ Return the size of {XP,N} measured in number of digits in the
+ given BASE. BASE can vary from 2 to 62. Requires N > 0 and
+ XP[N-1] > 0. The result will be either exact or 1 too big. If
+ BASE is a power of 2, the result is always exact.
+
+ -- Function: mp_size_t mpn_get_str (unsigned char *STR, int BASE,
+ mp_limb_t *S1P, mp_size_t S1N)
+ Convert {S1P, S1N} to a raw unsigned char array at STR in base
+ BASE, and return the number of characters produced. There may be
+ leading zeros in the string. The string is not in ASCII; to
+ convert it to printable format, add the ASCII codes for `0' or
+ `A', depending on the base and range. BASE can vary from 2 to 256.
+
+ The most significant limb of the input {S1P, S1N} must be
+ non-zero. The input {S1P, S1N} is clobbered, except when BASE is
+ a power of 2, in which case it's unchanged.
+
+ The area at STR has to have space for the largest possible number
+ represented by a S1N long limb array, plus one extra character.
+
+ -- Function: mp_size_t mpn_set_str (mp_limb_t *RP, const unsigned char
+ *STR, size_t STRSIZE, int BASE)
+ Convert bytes {STR,STRSIZE} in the given BASE to limbs at RP.
+
+ STR[0] is the most significant input byte and STR[STRSIZE-1] is
+ the least significant input byte. Each byte should be a value in
+ the range 0 to BASE-1, not an ASCII character. BASE can vary from
+ 2 to 256.
+
+ The converted value is {RP,RN} where RN is the return value. If
+ the most significant input byte STR[0] is non-zero, then RP[RN-1]
+ will be non-zero, else RP[RN-1] and some number of subsequent
+ limbs may be zero.
+
+ The area at RP has to have space for the largest possible number
+ with STRSIZE digits in the chosen base, plus one extra limb.
+
+ The input must have at least one byte, and no overlap is permitted
+ between {STR,STRSIZE} and the result at RP.
+
+ -- Function: mp_bitcnt_t mpn_scan0 (const mp_limb_t *S1P, mp_bitcnt_t
+ BIT)
+ Scan S1P from bit position BIT for the next clear bit.
+
+ It is required that there be a clear bit within the area at S1P at
+ or beyond bit position BIT, so that the function has something to
+ return.
+
+ -- Function: mp_bitcnt_t mpn_scan1 (const mp_limb_t *S1P, mp_bitcnt_t
+ BIT)
+ Scan S1P from bit position BIT for the next set bit.
+
+ It is required that there be a set bit within the area at S1P at or
+ beyond bit position BIT, so that the function has something to
+ return.
+
+ -- Function: void mpn_random (mp_limb_t *R1P, mp_size_t R1N)
+ -- Function: void mpn_random2 (mp_limb_t *R1P, mp_size_t R1N)
+ Generate a random number of length R1N and store it at R1P. The
+ most significant limb is always non-zero. `mpn_random' generates
+ uniformly distributed limb data, `mpn_random2' generates long
+ strings of zeros and ones in the binary representation.
+
+ `mpn_random2' is intended for testing the correctness of the `mpn'
+ routines.
+
+ -- Function: mp_bitcnt_t mpn_popcount (const mp_limb_t *S1P, mp_size_t
+ N)
+ Count the number of set bits in {S1P, N}.
+
+ -- Function: mp_bitcnt_t mpn_hamdist (const mp_limb_t *S1P, const
+ mp_limb_t *S2P, mp_size_t N)
+ Compute the hamming distance between {S1P, N} and {S2P, N}, which
+ is the number of bit positions where the two operands have
+ different bit values.
+
+ -- Function: int mpn_perfect_square_p (const mp_limb_t *S1P, mp_size_t
+ N)
+ Return non-zero iff {S1P, N} is a perfect square. The most
+ significant limb of the input {S1P, N} must be non-zero.
+
+ -- Function: void mpn_and_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Perform the bitwise logical and of {S1P, N} and {S2P, N}, and
+ write the result to {RP, N}.
+
+ -- Function: void mpn_ior_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Perform the bitwise logical inclusive or of {S1P, N} and {S2P, N},
+ and write the result to {RP, N}.
+
+ -- Function: void mpn_xor_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Perform the bitwise logical exclusive or of {S1P, N} and {S2P, N},
+ and write the result to {RP, N}.
+
+ -- Function: void mpn_andn_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Perform the bitwise logical and of {S1P, N} and the bitwise
+ complement of {S2P, N}, and write the result to {RP, N}.
+
+ -- Function: void mpn_iorn_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Perform the bitwise logical inclusive or of {S1P, N} and the
+ bitwise complement of {S2P, N}, and write the result to {RP, N}.
+
+ -- Function: void mpn_nand_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Perform the bitwise logical and of {S1P, N} and {S2P, N}, and
+ write the bitwise complement of the result to {RP, N}.
+
+ -- Function: void mpn_nior_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Perform the bitwise logical inclusive or of {S1P, N} and {S2P, N},
+ and write the bitwise complement of the result to {RP, N}.
+
+ -- Function: void mpn_xnor_n (mp_limb_t *RP, const mp_limb_t *S1P,
+ const mp_limb_t *S2P, mp_size_t N)
+ Perform the bitwise logical exclusive or of {S1P, N} and {S2P, N},
+ and write the bitwise complement of the result to {RP, N}.
+
+ -- Function: void mpn_com (mp_limb_t *RP, const mp_limb_t *SP,
+ mp_size_t N)
+ Perform the bitwise complement of {SP, N}, and write the result to
+ {RP, N}.
+
+ -- Function: void mpn_copyi (mp_limb_t *RP, const mp_limb_t *S1P,
+ mp_size_t N)
+ Copy from {S1P, N} to {RP, N}, increasingly.
+
+ -- Function: void mpn_copyd (mp_limb_t *RP, const mp_limb_t *S1P,
+ mp_size_t N)
+ Copy from {S1P, N} to {RP, N}, decreasingly.
+
+ -- Function: void mpn_zero (mp_limb_t *RP, mp_size_t N)
+ Zero {RP, N}.
+
+
+8.1 Low-level functions for cryptography
+========================================
+
+The functions prefixed with `mpn_sec_' and `mpn_cnd_' are designed to
+perform the exact same low-level operations and have the same cache
+access patterns for any two same-size arguments, assuming that function
+arguments are placed at the same position and that the machine state is
+identical upon function entry. These functions are intended for
+cryptographic purposes, where resilience to side-channel attacks is
+desired.
+
+ These functions are less efficient than their "leaky" counterparts;
+their performance for operands of the sizes typically used for
+cryptographic applications is between 15% and 100% worse. For larger
+operands, these functions might be inadequate, since they rely on
+asymptotically elementary algorithms.
+
+ These functions do not make any explicit allocations. Those of
+these functions that need scratch space accept a scratch space operand.
+This convention allows callers to keep sensitive data in designated
+memory areas. Note however that compilers may choose to spill scalar
+values used within these functions to their stack frame and that such
+scalars may contain sensitive data.
+
+ In addition to these specially crafted functions, the following `mpn'
+functions are naturally side-channel resistant: `mpn_add_n',
+`mpn_sub_n', `mpn_lshift', `mpn_rshift', `mpn_zero', `mpn_copyi',
+`mpn_copyd', `mpn_com', and the logical function (`mpn_and_n', etc).
+
+ There are some exceptions from the side-channel resilience: (1) Some
+assembly implementations of `mpn_lshift' identify shift-by-one as a
+special case. This is a problem iff the shift count is a function of
+sensitive data. (2) Alpha ev6 and Pentium4 using 64-bit limbs have
+leaky `mpn_add_n' and `mpn_sub_n'. (3) Alpha ev6 has a leaky
+`mpn_mul_1' which also makes `mpn_sec_mul' on those systems unsafe.
+
+ -- Function: mp_limb_t mpn_cnd_add_n (mp_limb_t CND, mp_limb_t *RP,
+ const mp_limb_t *S1P, const mp_limb_t *S2P, mp_size_t N)
+ -- Function: mp_limb_t mpn_cnd_sub_n (mp_limb_t CND, mp_limb_t *RP,
+ const mp_limb_t *S1P, const mp_limb_t *S2P, mp_size_t N)
+ These functions do conditional addition and subtraction. If CND is
+ non-zero, they produce the same result as a regular `mpn_add_n' or
+ `mpn_sub_n', and if CND is zero, they copy {S1P,N} to the result
+ area and return zero. The functions are designed to have timing
+ and memory access patterns depending only on size and location of
+ the data areas, but independent of the condition CND. Like for
+ `mpn_add_n' and `mpn_sub_n', on most machines, the timing will
+ also be independent of the actual limb values.
+
+ -- Function: mp_limb_t mpn_sec_add_1 (mp_limb_t *RP, const mp_limb_t
+ *AP, mp_size_t N, mp_limb_t B, mp_limb_t *TP)
+ -- Function: mp_limb_t mpn_sec_sub_1 (mp_limb_t *RP, const mp_limb_t
+ *AP, mp_size_t N, mp_limb_t B, mp_limb_t *TP)
+ Set R to A + B or A - B, respectively, where R = {RP,N}, A =
+ {AP,N}, and B is a single limb. Returns carry.
+
+ These functions take O(N) time, unlike the leaky functions
+ `mpn_add_1' which are O(1) on average. They require scratch space
+ of `mpn_sec_add_1_itch(N)' and `mpn_sec_sub_1_itch(N)' limbs,
+ respectively, to be passed in the TP parameter. The scratch space
+ requirements are guaranteed to increase monotonously in the
+ operand size.
+
+ -- Function: void mpn_sec_mul (mp_limb_t *RP, const mp_limb_t *AP,
+ mp_size_t AN, const mp_limb_t *BP, mp_size_t BN, mp_limb_t
+ *TP)
+ -- Function: mp_size_t mpn_sec_mul_itch (mp_size_t AN, mp_size_t BN)
+ Set R to A * B, where A = {AP,AN}, B = {BP,BN}, and R = {RP,AN+BN}.
+
+ It is required that AN >= BN > 0.
+
+ No overlapping between R and the input operands is allowed. For A
+ = B, use `mpn_sec_sqr' for optimal performance.
+
+ This function requires scratch space of `mpn_sec_mul_itch(AN, BN)'
+ limbs to be passed in the TP parameter. The scratch space
+ requirements are guaranteed to increase monotonously in the
+ operand sizes.
+
+ -- Function: void mpn_sec_sqr (mp_limb_t *RP, const mp_limb_t *AP,
+ mp_size_t AN, mp_limb_t *TP)
+ -- Function: mp_size_t mpn_sec_sqr_itch (mp_size_t AN)
+ Set R to A^2, where A = {AP,AN}, and R = {RP,2AN}.
+
+ It is required that AN > 0.
+
+ No overlapping between R and the input operands is allowed.
+
+ This function requires scratch space of `mpn_sec_sqr_itch(AN)'
+ limbs to be passed in the TP parameter. The scratch space
+ requirements are guaranteed to increase monotonously in the
+ operand size.
+
+ -- Function: void mpn_sec_powm (mp_limb_t *RP, const mp_limb_t *BP,
+ mp_size_t BN, const mp_limb_t *EP, mp_bitcnt_t ENB, const
+ mp_limb_t *MP, mp_size_t N, mp_limb_t *TP)
+ -- Function: mp_size_t mpn_sec_powm_itch (mp_size_t BN, mp_bitcnt_t
+ ENB, size_t N)
+ Set R to (B raised to E) modulo M, where R = {RP,N}, M = {MP,N},
+ and E = {EP,ceil(ENB / `GMP_NUMB_BITS')}.
+
+ It is required that B > 0, that M > 0 is odd, and that E < 2^ENB.
+
+ No overlapping between R and the input operands is allowed.
+
+ This function requires scratch space of `mpn_sec_powm_itch(BN,
+ ENB, N)' limbs to be passed in the TP parameter. The scratch
+ space requirements are guaranteed to increase monotonously in the
+ operand sizes.
+
+ -- Function: void mpn_sec_tabselect (mp_limb_t *RP, const mp_limb_t
+ *TAB, mp_size_t N, mp_size_t NENTS, mp_size_t WHICH)
+ Select entry WHICH from table TAB, which has NENTS entries, each N
+ limbs. Store the selected entry at RP.
+
+ This function reads the entire table to avoid side-channel
+ information leaks.
+
+ -- Function: mp_limb_t mpn_sec_div_qr (mp_limb_t *QP, mp_limb_t *NP,
+ mp_size_t NN, const mp_limb_t *DP, mp_size_t DN, mp_limb_t
+ *TP)
+ -- Function: mp_size_t mpn_sec_div_qr_itch (mp_size_t NN, mp_size_t DN)
+ Set Q to the truncated quotient N / D and R to N modulo D, where N
+ = {NP,NN}, D = {DP,DN}, Q's most significant limb is the function
+ return value and the remaining limbs are {QP,NN-DN}, and R =
+ {NP,DN}.
+
+ It is required that NN >= DN >= 1, and that DP[DN-1] != 0. This
+ does not imply that N >= D since N might be zero-padded.
+
+ Note the overlapping between N and R. No other operand overlapping
+ is allowed. The entire space occupied by N is overwritten.
+
+ This function requires scratch space of `mpn_sec_div_qr_itch(NN,
+ DN)' limbs to be passed in the TP parameter.
+
+ -- Function: void mpn_sec_div_r (mp_limb_t *NP, mp_size_t NN, const
+ mp_limb_t *DP, mp_size_t DN, mp_limb_t *TP)
+ -- Function: mp_size_t mpn_sec_div_r_itch (mp_size_t NN, mp_size_t DN)
+ Set R to N modulo D, where N = {NP,NN}, D = {DP,DN}, and R =
+ {NP,DN}.
+
+ It is required that NN >= DN >= 1, and that DP[DN-1] != 0. This
+ does not imply that N >= D since N might be zero-padded.
+
+ Note the overlapping between N and R. No other operand overlapping
+ is allowed. The entire space occupied by N is overwritten.
+
+ This function requires scratch space of `mpn_sec_div_r_itch(NN,
+ DN)' limbs to be passed in the TP parameter.
+
+ -- Function: int mpn_sec_invert (mp_limb_t *RP, mp_limb_t *AP, const
+ mp_limb_t *MP, mp_size_t N, mp_bitcnt_t NBCNT, mp_limb_t *TP)
+ -- Function: mp_size_t mpn_sec_invert_itch (mp_size_t N)
+ Set R to the inverse of A modulo M, where R = {RP,N}, A = {AP,N},
+ and M = {MP,N}. *This function's interface is preliminary.*
+
+ If an inverse exists, return 1, otherwise return 0 and leave R
+ undefined. In either case, the input A is destroyed.
+
+ It is required that M is odd, and that NBCNT >= ceil(log(A+1)) +
+ ceil(log(M+1)). A safe choice is NBCNT = 2 * N * GMP_NUMB_BITS,
+ but a smaller value might improve performance if M or A are known
+ to have leading zero bits.
+
+ This function requires scratch space of `mpn_sec_invert_itch(N)'
+ limbs to be passed in the TP parameter.
+
+
+8.2 Nails
+=========
+
+*Everything in this section is highly experimental and may disappear or
+be subject to incompatible changes in a future version of GMP.*
+
+ Nails are an experimental feature whereby a few bits are left unused
+at the top of each `mp_limb_t'. This can significantly improve carry
+handling on some processors.
+
+ All the `mpn' functions accepting limb data will expect the nail
+bits to be zero on entry, and will return data with the nails similarly
+all zero. This applies both to limb vectors and to single limb
+arguments.
+
+ Nails can be enabled by configuring with `--enable-nails'. By
+default the number of bits will be chosen according to what suits the
+host processor, but a particular number can be selected with
+`--enable-nails=N'.
+
+ At the mpn level, a nail build is neither source nor binary
+compatible with a non-nail build, strictly speaking. But programs
+acting on limbs only through the mpn functions are likely to work
+equally well with either build, and judicious use of the definitions
+below should make any program compatible with either build, at the
+source level.
+
+ For the higher level routines, meaning `mpz' etc, a nail build
+should be fully source and binary compatible with a non-nail build.
+
+ -- Macro: GMP_NAIL_BITS
+ -- Macro: GMP_NUMB_BITS
+ -- Macro: GMP_LIMB_BITS
+ `GMP_NAIL_BITS' is the number of nail bits, or 0 when nails are
+ not in use. `GMP_NUMB_BITS' is the number of data bits in a limb.
+ `GMP_LIMB_BITS' is the total number of bits in an `mp_limb_t'. In
+ all cases
+
+ GMP_LIMB_BITS == GMP_NAIL_BITS + GMP_NUMB_BITS
+
+ -- Macro: GMP_NAIL_MASK
+ -- Macro: GMP_NUMB_MASK
+ Bit masks for the nail and number parts of a limb.
+ `GMP_NAIL_MASK' is 0 when nails are not in use.
+
+ `GMP_NAIL_MASK' is not often needed, since the nail part can be
+ obtained with `x >> GMP_NUMB_BITS', and that means one less large
+ constant, which can help various RISC chips.
+
+ -- Macro: GMP_NUMB_MAX
+ The maximum value that can be stored in the number part of a limb.
+ This is the same as `GMP_NUMB_MASK', but can be used for clarity
+ when doing comparisons rather than bit-wise operations.
+
+ The term "nails" comes from finger or toe nails, which are at the
+ends of a limb (arm or leg). "numb" is short for number, but is also
+how the developers felt after trying for a long time to come up with
+sensible names for these things.
+
+ In the future (the distant future most likely) a non-zero nail might
+be permitted, giving non-unique representations for numbers in a limb
+vector. This would help vector processors since carries would only
+ever need to propagate one or two limbs.
+
+
+File: gmp.info, Node: Random Number Functions, Next: Formatted Output, Prev: Low-level Functions, Up: Top
+
+9 Random Number Functions
+*************************
+
+Sequences of pseudo-random numbers in GMP are generated using a
+variable of type `gmp_randstate_t', which holds an algorithm selection
+and a current state. Such a variable must be initialized by a call to
+one of the `gmp_randinit' functions, and can be seeded with one of the
+`gmp_randseed' functions.
+
+ The functions actually generating random numbers are described in
+*note Integer Random Numbers::, and *note Miscellaneous Float
+Functions::.
+
+ The older style random number functions don't accept a
+`gmp_randstate_t' parameter but instead share a global variable of that
+type. They use a default algorithm and are currently not seeded
+(though perhaps that will change in the future). The new functions
+accepting a `gmp_randstate_t' are recommended for applications that
+care about randomness.
+
+* Menu:
+
+* Random State Initialization::
+* Random State Seeding::
+* Random State Miscellaneous::
+
+
+File: gmp.info, Node: Random State Initialization, Next: Random State Seeding, Prev: Random Number Functions, Up: Random Number Functions
+
+9.1 Random State Initialization
+===============================
+
+ -- Function: void gmp_randinit_default (gmp_randstate_t STATE)
+ Initialize STATE with a default algorithm. This will be a
+ compromise between speed and randomness, and is recommended for
+ applications with no special requirements. Currently this is
+ `gmp_randinit_mt'.
+
+ -- Function: void gmp_randinit_mt (gmp_randstate_t STATE)
+ Initialize STATE for a Mersenne Twister algorithm. This algorithm
+ is fast and has good randomness properties.
+
+ -- Function: void gmp_randinit_lc_2exp (gmp_randstate_t STATE, const
+ mpz_t A, unsigned long C, mp_bitcnt_t M2EXP)
+ Initialize STATE with a linear congruential algorithm X = (A*X +
+ C) mod 2^M2EXP.
+
+ The low bits of X in this algorithm are not very random. The least
+ significant bit will have a period no more than 2, and the second
+ bit no more than 4, etc. For this reason only the high half of
+ each X is actually used.
+
+ When a random number of more than M2EXP/2 bits is to be generated,
+ multiple iterations of the recurrence are used and the results
+ concatenated.
+
+ -- Function: int gmp_randinit_lc_2exp_size (gmp_randstate_t STATE,
+ mp_bitcnt_t SIZE)
+ Initialize STATE for a linear congruential algorithm as per
+ `gmp_randinit_lc_2exp'. A, C and M2EXP are selected from a table,
+ chosen so that SIZE bits (or more) of each X will be used, i.e.
+ M2EXP/2 >= SIZE.
+
+ If successful the return value is non-zero. If SIZE is bigger
+ than the table data provides then the return value is zero. The
+ maximum SIZE currently supported is 128.
+
+ -- Function: void gmp_randinit_set (gmp_randstate_t ROP,
+ gmp_randstate_t OP)
+ Initialize ROP with a copy of the algorithm and state from OP.
+
+ -- Function: void gmp_randinit (gmp_randstate_t STATE,
+ gmp_randalg_t ALG, ...)
+ *This function is obsolete.*
+
+ Initialize STATE with an algorithm selected by ALG. The only
+ choice is `GMP_RAND_ALG_LC', which is `gmp_randinit_lc_2exp_size'
+ described above. A third parameter of type `unsigned long' is
+ required, this is the SIZE for that function.
+ `GMP_RAND_ALG_DEFAULT' or 0 are the same as `GMP_RAND_ALG_LC'.
+
+ `gmp_randinit' sets bits in the global variable `gmp_errno' to
+ indicate an error. `GMP_ERROR_UNSUPPORTED_ARGUMENT' if ALG is
+ unsupported, or `GMP_ERROR_INVALID_ARGUMENT' if the SIZE parameter
+ is too big. It may be noted this error reporting is not thread
+ safe (a good reason to use `gmp_randinit_lc_2exp_size' instead).
+
+ -- Function: void gmp_randclear (gmp_randstate_t STATE)
+ Free all memory occupied by STATE.
+
+
+File: gmp.info, Node: Random State Seeding, Next: Random State Miscellaneous, Prev: Random State Initialization, Up: Random Number Functions
+
+9.2 Random State Seeding
+========================
+
+ -- Function: void gmp_randseed (gmp_randstate_t STATE, const mpz_t
+ SEED)
+ -- Function: void gmp_randseed_ui (gmp_randstate_t STATE,
+ unsigned long int SEED)
+ Set an initial seed value into STATE.
+
+ The size of a seed determines how many different sequences of
+ random numbers that it's possible to generate. The "quality" of
+ the seed is the randomness of a given seed compared to the
+ previous seed used, and this affects the randomness of separate
+ number sequences. The method for choosing a seed is critical if
+ the generated numbers are to be used for important applications,
+ such as generating cryptographic keys.
+
+ Traditionally the system time has been used to seed, but care
+ needs to be taken with this. If an application seeds often and
+ the resolution of the system clock is low, then the same sequence
+ of numbers might be repeated. Also, the system time is quite easy
+ to guess, so if unpredictability is required then it should
+ definitely not be the only source for the seed value. On some
+ systems there's a special device `/dev/random' which provides
+ random data better suited for use as a seed.
+
+
+File: gmp.info, Node: Random State Miscellaneous, Prev: Random State Seeding, Up: Random Number Functions
+
+9.3 Random State Miscellaneous
+==============================
+
+ -- Function: unsigned long gmp_urandomb_ui (gmp_randstate_t STATE,
+ unsigned long N)
+ Return a uniformly distributed random number of N bits, i.e. in the
+ range 0 to 2^N-1 inclusive. N must be less than or equal to the
+ number of bits in an `unsigned long'.
+
+ -- Function: unsigned long gmp_urandomm_ui (gmp_randstate_t STATE,
+ unsigned long N)
+ Return a uniformly distributed random number in the range 0 to
+ N-1, inclusive.
+
+
+File: gmp.info, Node: Formatted Output, Next: Formatted Input, Prev: Random Number Functions, Up: Top
+
+10 Formatted Output
+*******************
+
+* Menu:
+
+* Formatted Output Strings::
+* Formatted Output Functions::
+* C++ Formatted Output::
+
+
+File: gmp.info, Node: Formatted Output Strings, Next: Formatted Output Functions, Prev: Formatted Output, Up: Formatted Output
+
+10.1 Format Strings
+===================
+
+`gmp_printf' and friends accept format strings similar to the standard C
+`printf' (*note Formatted Output: (libc)Formatted Output.). A format
+specification is of the form
+
+ % [flags] [width] [.[precision]] [type] conv
+
+ GMP adds types `Z', `Q' and `F' for `mpz_t', `mpq_t' and `mpf_t'
+respectively, `M' for `mp_limb_t', and `N' for an `mp_limb_t' array.
+`Z', `Q', `M' and `N' behave like integers. `Q' will print a `/' and a
+denominator, if needed. `F' behaves like a float. For example,
+
+ mpz_t z;
+ gmp_printf ("%s is an mpz %Zd\n", "here", z);
+
+ mpq_t q;
+ gmp_printf ("a hex rational: %#40Qx\n", q);
+
+ mpf_t f;
+ int n;
+ gmp_printf ("fixed point mpf %.*Ff with %d digits\n", n, f, n);
+
+ mp_limb_t l;
+ gmp_printf ("limb %Mu\n", l);
+
+ const mp_limb_t *ptr;
+ mp_size_t size;
+ gmp_printf ("limb array %Nx\n", ptr, size);
+
+ For `N' the limbs are expected least significant first, as per the
+`mpn' functions (*note Low-level Functions::). A negative size can be
+given to print the value as a negative.
+
+ All the standard C `printf' types behave the same as the C library
+`printf', and can be freely intermixed with the GMP extensions. In the
+current implementation the standard parts of the format string are
+simply handed to `printf' and only the GMP extensions handled directly.
+
+ The flags accepted are as follows. GLIBC style ' is only for the
+standard C types (not the GMP types), and only if the C library
+supports it.
+
+ 0 pad with zeros (rather than spaces)
+ # show the base with `0x', `0X' or `0'
+ + always show a sign
+ (space) show a space or a `-' sign
+ ' group digits, GLIBC style (not GMP types)
+
+ The optional width and precision can be given as a number within the
+format string, or as a `*' to take an extra parameter of type `int', the
+same as the standard `printf'.
+
+ The standard types accepted are as follows. `h' and `l' are
+portable, the rest will depend on the compiler (or include files) for
+the type and the C library for the output.
+
+ h short
+ hh char
+ j intmax_t or uintmax_t
+ l long or wchar_t
+ ll long long
+ L long double
+ q quad_t or u_quad_t
+ t ptrdiff_t
+ z size_t
+
+The GMP types are
+
+ F mpf_t, float conversions
+ Q mpq_t, integer conversions
+ M mp_limb_t, integer conversions
+ N mp_limb_t array, integer conversions
+ Z mpz_t, integer conversions
+
+ The conversions accepted are as follows. `a' and `A' are always
+supported for `mpf_t' but depend on the C library for standard C float
+types. `m' and `p' depend on the C library.
+
+ a A hex floats, C99 style
+ c character
+ d decimal integer
+ e E scientific format float
+ f fixed point float
+ i same as d
+ g G fixed or scientific float
+ m `strerror' string, GLIBC style
+ n store characters written so far
+ o octal integer
+ p pointer
+ s string
+ u unsigned integer
+ x X hex integer
+
+ `o', `x' and `X' are unsigned for the standard C types, but for
+types `Z', `Q' and `N' they are signed. `u' is not meaningful for `Z',
+`Q' and `N'.
+
+ `M' is a proxy for the C library `l' or `L', according to the size
+of `mp_limb_t'. Unsigned conversions will be usual, but a signed
+conversion can be used and will interpret the value as a twos complement
+negative.
+
+ `n' can be used with any type, even the GMP types.
+
+ Other types or conversions that might be accepted by the C library
+`printf' cannot be used through `gmp_printf', this includes for
+instance extensions registered with GLIBC `register_printf_function'.
+Also currently there's no support for POSIX `$' style numbered arguments
+(perhaps this will be added in the future).
+
+ The precision field has its usual meaning for integer `Z' and float
+`F' types, but is currently undefined for `Q' and should not be used
+with that.
+
+ `mpf_t' conversions only ever generate as many digits as can be
+accurately represented by the operand, the same as `mpf_get_str' does.
+Zeros will be used if necessary to pad to the requested precision. This
+happens even for an `f' conversion of an `mpf_t' which is an integer,
+for instance 2^1024 in an `mpf_t' of 128 bits precision will only
+produce about 40 digits, then pad with zeros to the decimal point. An
+empty precision field like `%.Fe' or `%.Ff' can be used to specifically
+request just the significant digits. Without any dot and thus no
+precision field, a precision value of 6 will be used. Note that these
+rules mean that `%Ff', `%.Ff', and `%.0Ff' will all be different.
+
+ The decimal point character (or string) is taken from the current
+locale settings on systems which provide `localeconv' (*note Locales
+and Internationalization: (libc)Locales.). The C library will normally
+do the same for standard float output.
+
+ The format string is only interpreted as plain `char's, multibyte
+characters are not recognised. Perhaps this will change in the future.
+
+
+File: gmp.info, Node: Formatted Output Functions, Next: C++ Formatted Output, Prev: Formatted Output Strings, Up: Formatted Output
+
+10.2 Functions
+==============
+
+Each of the following functions is similar to the corresponding C
+library function. The basic `printf' forms take a variable argument
+list. The `vprintf' forms take an argument pointer, see *note Variadic
+Functions: (libc)Variadic Functions, or `man 3 va_start'.
+
+ It should be emphasised that if a format string is invalid, or the
+arguments don't match what the format specifies, then the behaviour of
+any of these functions will be unpredictable. GCC format string
+checking is not available, since it doesn't recognise the GMP
+extensions.
+
+ The file based functions `gmp_printf' and `gmp_fprintf' will return
+-1 to indicate a write error. Output is not "atomic", so partial
+output may be produced if a write error occurs. All the functions can
+return -1 if the C library `printf' variant in use returns -1, but this
+shouldn't normally occur.
+
+ -- Function: int gmp_printf (const char *FMT, ...)
+ -- Function: int gmp_vprintf (const char *FMT, va_list AP)
+ Print to the standard output `stdout'. Return the number of
+ characters written, or -1 if an error occurred.
+
+ -- Function: int gmp_fprintf (FILE *FP, const char *FMT, ...)
+ -- Function: int gmp_vfprintf (FILE *FP, const char *FMT, va_list AP)
+ Print to the stream FP. Return the number of characters written,
+ or -1 if an error occurred.
+
+ -- Function: int gmp_sprintf (char *BUF, const char *FMT, ...)
+ -- Function: int gmp_vsprintf (char *BUF, const char *FMT, va_list AP)
+ Form a null-terminated string in BUF. Return the number of
+ characters written, excluding the terminating null.
+
+ No overlap is permitted between the space at BUF and the string
+ FMT.
+
+ These functions are not recommended, since there's no protection
+ against exceeding the space available at BUF.
+
+ -- Function: int gmp_snprintf (char *BUF, size_t SIZE, const char
+ *FMT, ...)
+ -- Function: int gmp_vsnprintf (char *BUF, size_t SIZE, const char
+ *FMT, va_list AP)
+ Form a null-terminated string in BUF. No more than SIZE bytes
+ will be written. To get the full output, SIZE must be enough for
+ the string and null-terminator.
+
+ The return value is the total number of characters which ought to
+ have been produced, excluding the terminating null. If RETVAL >=
+ SIZE then the actual output has been truncated to the first SIZE-1
+ characters, and a null appended.
+
+ No overlap is permitted between the region {BUF,SIZE} and the FMT
+ string.
+
+ Notice the return value is in ISO C99 `snprintf' style. This is
+ so even if the C library `vsnprintf' is the older GLIBC 2.0.x
+ style.
+
+ -- Function: int gmp_asprintf (char **PP, const char *FMT, ...)
+ -- Function: int gmp_vasprintf (char **PP, const char *FMT, va_list AP)
+ Form a null-terminated string in a block of memory obtained from
+ the current memory allocation function (*note Custom
+ Allocation::). The block will be the size of the string and
+ null-terminator. The address of the block in stored to *PP. The
+ return value is the number of characters produced, excluding the
+ null-terminator.
+
+ Unlike the C library `asprintf', `gmp_asprintf' doesn't return -1
+ if there's no more memory available, it lets the current allocation
+ function handle that.
+
+ -- Function: int gmp_obstack_printf (struct obstack *OB, const char
+ *FMT, ...)
+ -- Function: int gmp_obstack_vprintf (struct obstack *OB, const char
+ *FMT, va_list AP)
+ Append to the current object in OB. The return value is the
+ number of characters written. A null-terminator is not written.
+
+ FMT cannot be within the current object in OB, since that object
+ might move as it grows.
+
+ These functions are available only when the C library provides the
+ obstack feature, which probably means only on GNU systems, see
+ *note Obstacks: (libc)Obstacks.
+
+
+File: gmp.info, Node: C++ Formatted Output, Prev: Formatted Output Functions, Up: Formatted Output
+
+10.3 C++ Formatted Output
+=========================
+
+The following functions are provided in `libgmpxx' (*note Headers and
+Libraries::), which is built if C++ support is enabled (*note Build
+Options::). Prototypes are available from `<gmp.h>'.
+
+ -- Function: ostream& operator<< (ostream& STREAM, const mpz_t OP)
+ Print OP to STREAM, using its `ios' formatting settings.
+ `ios::width' is reset to 0 after output, the same as the standard
+ `ostream operator<<' routines do.
+
+ In hex or octal, OP is printed as a signed number, the same as for
+ decimal. This is unlike the standard `operator<<' routines on
+ `int' etc, which instead give twos complement.
+
+ -- Function: ostream& operator<< (ostream& STREAM, const mpq_t OP)
+ Print OP to STREAM, using its `ios' formatting settings.
+ `ios::width' is reset to 0 after output, the same as the standard
+ `ostream operator<<' routines do.
+
+ Output will be a fraction like `5/9', or if the denominator is 1
+ then just a plain integer like `123'.
+
+ In hex or octal, OP is printed as a signed value, the same as for
+ decimal. If `ios::showbase' is set then a base indicator is shown
+ on both the numerator and denominator (if the denominator is
+ required).
+
+ -- Function: ostream& operator<< (ostream& STREAM, const mpf_t OP)
+ Print OP to STREAM, using its `ios' formatting settings.
+ `ios::width' is reset to 0 after output, the same as the standard
+ `ostream operator<<' routines do.
+
+ The decimal point follows the standard library float `operator<<',
+ which on recent systems means the `std::locale' imbued on STREAM.
+
+ Hex and octal are supported, unlike the standard `operator<<' on
+ `double'. The mantissa will be in hex or octal, the exponent will
+ be in decimal. For hex the exponent delimiter is an `@'. This is
+ as per `mpf_out_str'.
+
+ `ios::showbase' is supported, and will put a base on the mantissa,
+ for example hex `0x1.8' or `0x0.8', or octal `01.4' or `00.4'.
+ This last form is slightly strange, but at least differentiates
+ itself from decimal.
+
+ These operators mean that GMP types can be printed in the usual C++
+way, for example,
+
+ mpz_t z;
+ int n;
+ ...
+ cout << "iteration " << n << " value " << z << "\n";
+
+ But note that `ostream' output (and `istream' input, *note C++
+Formatted Input::) is the only overloading available for the GMP types
+and that for instance using `+' with an `mpz_t' will have unpredictable
+results. For classes with overloading, see *note C++ Class Interface::.
+
+
+File: gmp.info, Node: Formatted Input, Next: C++ Class Interface, Prev: Formatted Output, Up: Top
+
+11 Formatted Input
+******************
+
+* Menu:
+
+* Formatted Input Strings::
+* Formatted Input Functions::
+* C++ Formatted Input::
+
+
+File: gmp.info, Node: Formatted Input Strings, Next: Formatted Input Functions, Prev: Formatted Input, Up: Formatted Input
+
+11.1 Formatted Input Strings
+============================
+
+`gmp_scanf' and friends accept format strings similar to the standard C
+`scanf' (*note Formatted Input: (libc)Formatted Input.). A format
+specification is of the form
+
+ % [flags] [width] [type] conv
+
+ GMP adds types `Z', `Q' and `F' for `mpz_t', `mpq_t' and `mpf_t'
+respectively. `Z' and `Q' behave like integers. `Q' will read a `/'
+and a denominator, if present. `F' behaves like a float.
+
+ GMP variables don't require an `&' when passed to `gmp_scanf', since
+they're already "call-by-reference". For example,
+
+ /* to read say "a(5) = 1234" */
+ int n;
+ mpz_t z;
+ gmp_scanf ("a(%d) = %Zd\n", &n, z);
+
+ mpq_t q1, q2;
+ gmp_sscanf ("0377 + 0x10/0x11", "%Qi + %Qi", q1, q2);
+
+ /* to read say "topleft (1.55,-2.66)" */
+ mpf_t x, y;
+ char buf[32];
+ gmp_scanf ("%31s (%Ff,%Ff)", buf, x, y);
+
+ All the standard C `scanf' types behave the same as in the C library
+`scanf', and can be freely intermixed with the GMP extensions. In the
+current implementation the standard parts of the format string are
+simply handed to `scanf' and only the GMP extensions handled directly.
+
+ The flags accepted are as follows. `a' and `'' will depend on
+support from the C library, and `'' cannot be used with GMP types.
+
+ * read but don't store
+ a allocate a buffer (string conversions)
+ ' grouped digits, GLIBC style (not GMP
+ types)
+
+ The standard types accepted are as follows. `h' and `l' are
+portable, the rest will depend on the compiler (or include files) for
+the type and the C library for the input.
+
+ h short
+ hh char
+ j intmax_t or uintmax_t
+ l long int, double or wchar_t
+ ll long long
+ L long double
+ q quad_t or u_quad_t
+ t ptrdiff_t
+ z size_t
+
+The GMP types are
+
+ F mpf_t, float conversions
+ Q mpq_t, integer conversions
+ Z mpz_t, integer conversions
+
+ The conversions accepted are as follows. `p' and `[' will depend on
+support from the C library, the rest are standard.
+
+ c character or characters
+ d decimal integer
+ e E f g G float
+ i integer with base indicator
+ n characters read so far
+ o octal integer
+ p pointer
+ s string of non-whitespace characters
+ u decimal integer
+ x X hex integer
+ [ string of characters in a set
+
+ `e', `E', `f', `g' and `G' are identical, they all read either fixed
+point or scientific format, and either upper or lower case `e' for the
+exponent in scientific format.
+
+ C99 style hex float format (`printf %a', *note Formatted Output
+Strings::) is always accepted for `mpf_t', but for the standard float
+types it will depend on the C library.
+
+ `x' and `X' are identical, both accept both upper and lower case
+hexadecimal.
+
+ `o', `u', `x' and `X' all read positive or negative values. For the
+standard C types these are described as "unsigned" conversions, but
+that merely affects certain overflow handling, negatives are still
+allowed (per `strtoul', *note Parsing of Integers: (libc)Parsing of
+Integers.). For GMP types there are no overflows, so `d' and `u' are
+identical.
+
+ `Q' type reads the numerator and (optional) denominator as given.
+If the value might not be in canonical form then `mpq_canonicalize'
+must be called before using it in any calculations (*note Rational
+Number Functions::).
+
+ `Qi' will read a base specification separately for the numerator and
+denominator. For example `0x10/11' would be 16/11, whereas `0x10/0x11'
+would be 16/17.
+
+ `n' can be used with any of the types above, even the GMP types.
+`*' to suppress assignment is allowed, though in that case it would do
+nothing at all.
+
+ Other conversions or types that might be accepted by the C library
+`scanf' cannot be used through `gmp_scanf'.
+
+ Whitespace is read and discarded before a field, except for `c' and
+`[' conversions.
+
+ For float conversions, the decimal point character (or string)
+expected is taken from the current locale settings on systems which
+provide `localeconv' (*note Locales and Internationalization:
+(libc)Locales.). The C library will normally do the same for standard
+float input.
+
+ The format string is only interpreted as plain `char's, multibyte
+characters are not recognised. Perhaps this will change in the future.
+
+
+File: gmp.info, Node: Formatted Input Functions, Next: C++ Formatted Input, Prev: Formatted Input Strings, Up: Formatted Input
+
+11.2 Formatted Input Functions
+==============================
+
+Each of the following functions is similar to the corresponding C
+library function. The plain `scanf' forms take a variable argument
+list. The `vscanf' forms take an argument pointer, see *note Variadic
+Functions: (libc)Variadic Functions, or `man 3 va_start'.
+
+ It should be emphasised that if a format string is invalid, or the
+arguments don't match what the format specifies, then the behaviour of
+any of these functions will be unpredictable. GCC format string
+checking is not available, since it doesn't recognise the GMP
+extensions.
+
+ No overlap is permitted between the FMT string and any of the results
+produced.
+
+ -- Function: int gmp_scanf (const char *FMT, ...)
+ -- Function: int gmp_vscanf (const char *FMT, va_list AP)
+ Read from the standard input `stdin'.
+
+ -- Function: int gmp_fscanf (FILE *FP, const char *FMT, ...)
+ -- Function: int gmp_vfscanf (FILE *FP, const char *FMT, va_list AP)
+ Read from the stream FP.
+
+ -- Function: int gmp_sscanf (const char *S, const char *FMT, ...)
+ -- Function: int gmp_vsscanf (const char *S, const char *FMT, va_list
+ AP)
+ Read from a null-terminated string S.
+
+ The return value from each of these functions is the same as the
+standard C99 `scanf', namely the number of fields successfully parsed
+and stored. `%n' fields and fields read but suppressed by `*' don't
+count towards the return value.
+
+ If end of input (or a file error) is reached before a character for
+a field or a literal, and if no previous non-suppressed fields have
+matched, then the return value is `EOF' instead of 0. A whitespace
+character in the format string is only an optional match and doesn't
+induce an `EOF' in this fashion. Leading whitespace read and discarded
+for a field don't count as characters for that field.
+
+ For the GMP types, input parsing follows C99 rules, namely one
+character of lookahead is used and characters are read while they
+continue to meet the format requirements. If this doesn't provide a
+complete number then the function terminates, with that field not
+stored nor counted towards the return value. For instance with `mpf_t'
+an input `1.23e-XYZ' would be read up to the `X' and that character
+pushed back since it's not a digit. The string `1.23e-' would then be
+considered invalid since an `e' must be followed by at least one digit.
+
+ For the standard C types, in the current implementation GMP calls
+the C library `scanf' functions, which might have looser rules about
+what constitutes a valid input.
+
+ Note that `gmp_sscanf' is the same as `gmp_fscanf' and only does one
+character of lookahead when parsing. Although clearly it could look at
+its entire input, it is deliberately made identical to `gmp_fscanf',
+the same way C99 `sscanf' is the same as `fscanf'.
+
+
+File: gmp.info, Node: C++ Formatted Input, Prev: Formatted Input Functions, Up: Formatted Input
+
+11.3 C++ Formatted Input
+========================
+
+The following functions are provided in `libgmpxx' (*note Headers and
+Libraries::), which is built only if C++ support is enabled (*note
+Build Options::). Prototypes are available from `<gmp.h>'.
+
+ -- Function: istream& operator>> (istream& STREAM, mpz_t ROP)
+ Read ROP from STREAM, using its `ios' formatting settings.
+
+ -- Function: istream& operator>> (istream& STREAM, mpq_t ROP)
+ An integer like `123' will be read, or a fraction like `5/9'. No
+ whitespace is allowed around the `/'. If the fraction is not in
+ canonical form then `mpq_canonicalize' must be called (*note
+ Rational Number Functions::) before operating on it.
+
+ As per integer input, an `0' or `0x' base indicator is read when
+ none of `ios::dec', `ios::oct' or `ios::hex' are set. This is
+ done separately for numerator and denominator, so that for instance
+ `0x10/11' is 16/11 and `0x10/0x11' is 16/17.
+
+ -- Function: istream& operator>> (istream& STREAM, mpf_t ROP)
+ Read ROP from STREAM, using its `ios' formatting settings.
+
+ Hex or octal floats are not supported, but might be in the future,
+ or perhaps it's best to accept only what the standard float
+ `operator>>' does.
+
+ Note that digit grouping specified by the `istream' locale is
+currently not accepted. Perhaps this will change in the future.
+
+
+ These operators mean that GMP types can be read in the usual C++
+way, for example,
+
+ mpz_t z;
+ ...
+ cin >> z;
+
+ But note that `istream' input (and `ostream' output, *note C++
+Formatted Output::) is the only overloading available for the GMP types
+and that for instance using `+' with an `mpz_t' will have unpredictable
+results. For classes with overloading, see *note C++ Class Interface::.
+
+
+File: gmp.info, Node: C++ Class Interface, Next: Custom Allocation, Prev: Formatted Input, Up: Top
+
+12 C++ Class Interface
+**********************
+
+This chapter describes the C++ class based interface to GMP.
+
+ All GMP C language types and functions can be used in C++ programs,
+since `gmp.h' has `extern "C"' qualifiers, but the class interface
+offers overloaded functions and operators which may be more convenient.
+
+ Due to the implementation of this interface, a reasonably recent C++
+compiler is required, one supporting namespaces, partial specialization
+of templates and member templates.
+
+ *Everything described in this chapter is to be considered preliminary
+and might be subject to incompatible changes if some unforeseen
+difficulty reveals itself.*
+
+* Menu:
+
+* C++ Interface General::
+* C++ Interface Integers::
+* C++ Interface Rationals::
+* C++ Interface Floats::
+* C++ Interface Random Numbers::
+* C++ Interface Limitations::
+
+
+File: gmp.info, Node: C++ Interface General, Next: C++ Interface Integers, Prev: C++ Class Interface, Up: C++ Class Interface
+
+12.1 C++ Interface General
+==========================
+
+All the C++ classes and functions are available with
+
+ #include <gmpxx.h>
+
+ Programs should be linked with the `libgmpxx' and `libgmp'
+libraries. For example,
+
+ g++ mycxxprog.cc -lgmpxx -lgmp
+
+The classes defined are
+
+ -- Class: mpz_class
+ -- Class: mpq_class
+ -- Class: mpf_class
+
+ The standard operators and various standard functions are overloaded
+to allow arithmetic with these classes. For example,
+
+ int
+ main (void)
+ {
+ mpz_class a, b, c;
+
+ a = 1234;
+ b = "-5678";
+ c = a+b;
+ cout << "sum is " << c << "\n";
+ cout << "absolute value is " << abs(c) << "\n";
+
+ return 0;
+ }
+
+ An important feature of the implementation is that an expression like
+`a=b+c' results in a single call to the corresponding `mpz_add',
+without using a temporary for the `b+c' part. Expressions which by
+their nature imply intermediate values, like `a=b*c+d*e', still use
+temporaries though.
+
+ The classes can be freely intermixed in expressions, as can the
+classes and the standard types `long', `unsigned long' and `double'.
+Smaller types like `int' or `float' can also be intermixed, since C++
+will promote them.
+
+ Note that `bool' is not accepted directly, but must be explicitly
+cast to an `int' first. This is because C++ will automatically convert
+any pointer to a `bool', so if GMP accepted `bool' it would make all
+sorts of invalid class and pointer combinations compile but almost
+certainly not do anything sensible.
+
+ Conversions back from the classes to standard C++ types aren't done
+automatically, instead member functions like `get_si' are provided (see
+the following sections for details).
+
+ Also there are no automatic conversions from the classes to the
+corresponding GMP C types, instead a reference to the underlying C
+object can be obtained with the following functions,
+
+ -- Function: mpz_t mpz_class::get_mpz_t ()
+ -- Function: mpq_t mpq_class::get_mpq_t ()
+ -- Function: mpf_t mpf_class::get_mpf_t ()
+
+ These can be used to call a C function which doesn't have a C++ class
+interface. For example to set `a' to the GCD of `b' and `c',
+
+ mpz_class a, b, c;
+ ...
+ mpz_gcd (a.get_mpz_t(), b.get_mpz_t(), c.get_mpz_t());
+
+ In the other direction, a class can be initialized from the
+corresponding GMP C type, or assigned to if an explicit constructor is
+used. In both cases this makes a copy of the value, it doesn't create
+any sort of association. For example,
+
+ mpz_t z;
+ // ... init and calculate z ...
+ mpz_class x(z);
+ mpz_class y;
+ y = mpz_class (z);
+
+ There are no namespace setups in `gmpxx.h', all types and functions
+are simply put into the global namespace. This is what `gmp.h' has
+done in the past, and continues to do for compatibility. The extras
+provided by `gmpxx.h' follow GMP naming conventions and are unlikely to
+clash with anything.
+
+
+File: gmp.info, Node: C++ Interface Integers, Next: C++ Interface Rationals, Prev: C++ Interface General, Up: C++ Class Interface
+
+12.2 C++ Interface Integers
+===========================
+
+ -- Function: mpz_class::mpz_class (type N)
+ Construct an `mpz_class'. All the standard C++ types may be used,
+ except `long long' and `long double', and all the GMP C++ classes
+ can be used, although conversions from `mpq_class' and `mpf_class'
+ are `explicit'. Any necessary conversion follows the
+ corresponding C function, for example `double' follows `mpz_set_d'
+ (*note Assigning Integers::).
+
+ -- Function: explicit mpz_class::mpz_class (const mpz_t Z)
+ Construct an `mpz_class' from an `mpz_t'. The value in Z is
+ copied into the new `mpz_class', there won't be any permanent
+ association between it and Z.
+
+ -- Function: explicit mpz_class::mpz_class (const char *S, int BASE =
+ 0)
+ -- Function: explicit mpz_class::mpz_class (const string& S, int BASE
+ = 0)
+ Construct an `mpz_class' converted from a string using
+ `mpz_set_str' (*note Assigning Integers::).
+
+ If the string is not a valid integer, an `std::invalid_argument'
+ exception is thrown. The same applies to `operator='.
+
+ -- Function: mpz_class operator"" _mpz (const char *STR)
+ With C++11 compilers, integers can be constructed with the syntax
+ `123_mpz' which is equivalent to `mpz_class("123")'.
+
+ -- Function: mpz_class operator/ (mpz_class A, mpz_class D)
+ -- Function: mpz_class operator% (mpz_class A, mpz_class D)
+ Divisions involving `mpz_class' round towards zero, as per the
+ `mpz_tdiv_q' and `mpz_tdiv_r' functions (*note Integer Division::).
+ This is the same as the C99 `/' and `%' operators.
+
+ The `mpz_fdiv...' or `mpz_cdiv...' functions can always be called
+ directly if desired. For example,
+
+ mpz_class q, a, d;
+ ...
+ mpz_fdiv_q (q.get_mpz_t(), a.get_mpz_t(), d.get_mpz_t());
+
+ -- Function: mpz_class abs (mpz_class OP)
+ -- Function: int cmp (mpz_class OP1, type OP2)
+ -- Function: int cmp (type OP1, mpz_class OP2)
+ -- Function: bool mpz_class::fits_sint_p (void)
+ -- Function: bool mpz_class::fits_slong_p (void)
+ -- Function: bool mpz_class::fits_sshort_p (void)
+ -- Function: bool mpz_class::fits_uint_p (void)
+ -- Function: bool mpz_class::fits_ulong_p (void)
+ -- Function: bool mpz_class::fits_ushort_p (void)
+ -- Function: double mpz_class::get_d (void)
+ -- Function: long mpz_class::get_si (void)
+ -- Function: string mpz_class::get_str (int BASE = 10)
+ -- Function: unsigned long mpz_class::get_ui (void)
+ -- Function: int mpz_class::set_str (const char *STR, int BASE)
+ -- Function: int mpz_class::set_str (const string& STR, int BASE)
+ -- Function: int sgn (mpz_class OP)
+ -- Function: mpz_class sqrt (mpz_class OP)
+ -- Function: void mpz_class::swap (mpz_class& OP)
+ -- Function: void swap (mpz_class& OP1, mpz_class& OP2)
+ These functions provide a C++ class interface to the corresponding
+ GMP C routines.
+
+ `cmp' can be used with any of the classes or the standard C++
+ types, except `long long' and `long double'.
+
+
+ Overloaded operators for combinations of `mpz_class' and `double'
+are provided for completeness, but it should be noted that if the given
+`double' is not an integer then the way any rounding is done is
+currently unspecified. The rounding might take place at the start, in
+the middle, or at the end of the operation, and it might change in the
+future.
+
+ Conversions between `mpz_class' and `double', however, are defined
+to follow the corresponding C functions `mpz_get_d' and `mpz_set_d'.
+And comparisons are always made exactly, as per `mpz_cmp_d'.
+
+
+File: gmp.info, Node: C++ Interface Rationals, Next: C++ Interface Floats, Prev: C++ Interface Integers, Up: C++ Class Interface
+
+12.3 C++ Interface Rationals
+============================
+
+In all the following constructors, if a fraction is given then it
+should be in canonical form, or if not then `mpq_class::canonicalize'
+called.
+
+ -- Function: mpq_class::mpq_class (type OP)
+ -- Function: mpq_class::mpq_class (integer NUM, integer DEN)
+ Construct an `mpq_class'. The initial value can be a single value
+ of any type (conversion from `mpf_class' is `explicit'), or a pair
+ of integers (`mpz_class' or standard C++ integer types)
+ representing a fraction, except that `long long' and `long double'
+ are not supported. For example,
+
+ mpq_class q (99);
+ mpq_class q (1.75);
+ mpq_class q (1, 3);
+
+ -- Function: explicit mpq_class::mpq_class (const mpq_t Q)
+ Construct an `mpq_class' from an `mpq_t'. The value in Q is
+ copied into the new `mpq_class', there won't be any permanent
+ association between it and Q.
+
+ -- Function: explicit mpq_class::mpq_class (const char *S, int BASE =
+ 0)
+ -- Function: explicit mpq_class::mpq_class (const string& S, int BASE
+ = 0)
+ Construct an `mpq_class' converted from a string using
+ `mpq_set_str' (*note Initializing Rationals::).
+
+ If the string is not a valid rational, an `std::invalid_argument'
+ exception is thrown. The same applies to `operator='.
+
+ -- Function: mpq_class operator"" _mpq (const char *STR)
+ With C++11 compilers, integral rationals can be constructed with
+ the syntax `123_mpq' which is equivalent to `mpq_class(123_mpz)'.
+ Other rationals can be built as `-1_mpq/2' or `0xb_mpq/123456_mpz'.
+
+ -- Function: void mpq_class::canonicalize ()
+ Put an `mpq_class' into canonical form, as per *note Rational
+ Number Functions::. All arithmetic operators require their
+ operands in canonical form, and will return results in canonical
+ form.
+
+ -- Function: mpq_class abs (mpq_class OP)
+ -- Function: int cmp (mpq_class OP1, type OP2)
+ -- Function: int cmp (type OP1, mpq_class OP2)
+ -- Function: double mpq_class::get_d (void)
+ -- Function: string mpq_class::get_str (int BASE = 10)
+ -- Function: int mpq_class::set_str (const char *STR, int BASE)
+ -- Function: int mpq_class::set_str (const string& STR, int BASE)
+ -- Function: int sgn (mpq_class OP)
+ -- Function: void mpq_class::swap (mpq_class& OP)
+ -- Function: void swap (mpq_class& OP1, mpq_class& OP2)
+ These functions provide a C++ class interface to the corresponding
+ GMP C routines.
+
+ `cmp' can be used with any of the classes or the standard C++
+ types, except `long long' and `long double'.
+
+ -- Function: mpz_class& mpq_class::get_num ()
+ -- Function: mpz_class& mpq_class::get_den ()
+ Get a reference to an `mpz_class' which is the numerator or
+ denominator of an `mpq_class'. This can be used both for read and
+ write access. If the object returned is modified, it modifies the
+ original `mpq_class'.
+
+ If direct manipulation might produce a non-canonical value, then
+ `mpq_class::canonicalize' must be called before further operations.
+
+ -- Function: mpz_t mpq_class::get_num_mpz_t ()
+ -- Function: mpz_t mpq_class::get_den_mpz_t ()
+ Get a reference to the underlying `mpz_t' numerator or denominator
+ of an `mpq_class'. This can be passed to C functions expecting an
+ `mpz_t'. Any modifications made to the `mpz_t' will modify the
+ original `mpq_class'.
+
+ If direct manipulation might produce a non-canonical value, then
+ `mpq_class::canonicalize' must be called before further operations.
+
+ -- Function: istream& operator>> (istream& STREAM, mpq_class& ROP);
+ Read ROP from STREAM, using its `ios' formatting settings, the
+ same as `mpq_t operator>>' (*note C++ Formatted Input::).
+
+ If the ROP read might not be in canonical form then
+ `mpq_class::canonicalize' must be called.
+
+
+File: gmp.info, Node: C++ Interface Floats, Next: C++ Interface Random Numbers, Prev: C++ Interface Rationals, Up: C++ Class Interface
+
+12.4 C++ Interface Floats
+=========================
+
+When an expression requires the use of temporary intermediate
+`mpf_class' values, like `f=g*h+x*y', those temporaries will have the
+same precision as the destination `f'. Explicit constructors can be
+used if this doesn't suit.
+
+ -- Function: mpf_class::mpf_class (type OP)
+ -- Function: mpf_class::mpf_class (type OP, mp_bitcnt_t PREC)
+ Construct an `mpf_class'. Any standard C++ type can be used,
+ except `long long' and `long double', and any of the GMP C++
+ classes can be used.
+
+ If PREC is given, the initial precision is that value, in bits. If
+ PREC is not given, then the initial precision is determined by the
+ type of OP given. An `mpz_class', `mpq_class', or C++ builtin
+ type will give the default `mpf' precision (*note Initializing
+ Floats::). An `mpf_class' or expression will give the precision
+ of that value. The precision of a binary expression is the higher
+ of the two operands.
+
+ mpf_class f(1.5); // default precision
+ mpf_class f(1.5, 500); // 500 bits (at least)
+ mpf_class f(x); // precision of x
+ mpf_class f(abs(x)); // precision of x
+ mpf_class f(-g, 1000); // 1000 bits (at least)
+ mpf_class f(x+y); // greater of precisions of x and y
+
+ -- Function: explicit mpf_class::mpf_class (const mpf_t F)
+ -- Function: mpf_class::mpf_class (const mpf_t F, mp_bitcnt_t PREC)
+ Construct an `mpf_class' from an `mpf_t'. The value in F is
+ copied into the new `mpf_class', there won't be any permanent
+ association between it and F.
+
+ If PREC is given, the initial precision is that value, in bits. If
+ PREC is not given, then the initial precision is that of F.
+
+ -- Function: explicit mpf_class::mpf_class (const char *S)
+ -- Function: mpf_class::mpf_class (const char *S, mp_bitcnt_t PREC,
+ int BASE = 0)
+ -- Function: explicit mpf_class::mpf_class (const string& S)
+ -- Function: mpf_class::mpf_class (const string& S, mp_bitcnt_t PREC,
+ int BASE = 0)
+ Construct an `mpf_class' converted from a string using
+ `mpf_set_str' (*note Assigning Floats::). If PREC is given, the
+ initial precision is that value, in bits. If not, the default
+ `mpf' precision (*note Initializing Floats::) is used.
+
+ If the string is not a valid float, an `std::invalid_argument'
+ exception is thrown. The same applies to `operator='.
+
+ -- Function: mpf_class operator"" _mpf (const char *STR)
+ With C++11 compilers, floats can be constructed with the syntax
+ `1.23e-1_mpf' which is equivalent to `mpf_class("1.23e-1")'.
+
+ -- Function: mpf_class& mpf_class::operator= (type OP)
+ Convert and store the given OP value to an `mpf_class' object. The
+ same types are accepted as for the constructors above.
+
+ Note that `operator=' only stores a new value, it doesn't copy or
+ change the precision of the destination, instead the value is
+ truncated if necessary. This is the same as `mpf_set' etc. Note
+ in particular this means for `mpf_class' a copy constructor is not
+ the same as a default constructor plus assignment.
+
+ mpf_class x (y); // x created with precision of y
+
+ mpf_class x; // x created with default precision
+ x = y; // value truncated to that precision
+
+ Applications using templated code may need to be careful about the
+ assumptions the code makes in this area, when working with
+ `mpf_class' values of various different or non-default precisions.
+ For instance implementations of the standard `complex' template
+ have been seen in both styles above, though of course `complex' is
+ normally only actually specified for use with the builtin float
+ types.
+
+ -- Function: mpf_class abs (mpf_class OP)
+ -- Function: mpf_class ceil (mpf_class OP)
+ -- Function: int cmp (mpf_class OP1, type OP2)
+ -- Function: int cmp (type OP1, mpf_class OP2)
+ -- Function: bool mpf_class::fits_sint_p (void)
+ -- Function: bool mpf_class::fits_slong_p (void)
+ -- Function: bool mpf_class::fits_sshort_p (void)
+ -- Function: bool mpf_class::fits_uint_p (void)
+ -- Function: bool mpf_class::fits_ulong_p (void)
+ -- Function: bool mpf_class::fits_ushort_p (void)
+ -- Function: mpf_class floor (mpf_class OP)
+ -- Function: mpf_class hypot (mpf_class OP1, mpf_class OP2)
+ -- Function: double mpf_class::get_d (void)
+ -- Function: long mpf_class::get_si (void)
+ -- Function: string mpf_class::get_str (mp_exp_t& EXP, int BASE = 10,
+ size_t DIGITS = 0)
+ -- Function: unsigned long mpf_class::get_ui (void)
+ -- Function: int mpf_class::set_str (const char *STR, int BASE)
+ -- Function: int mpf_class::set_str (const string& STR, int BASE)
+ -- Function: int sgn (mpf_class OP)
+ -- Function: mpf_class sqrt (mpf_class OP)
+ -- Function: void mpf_class::swap (mpf_class& OP)
+ -- Function: void swap (mpf_class& OP1, mpf_class& OP2)
+ -- Function: mpf_class trunc (mpf_class OP)
+ These functions provide a C++ class interface to the corresponding
+ GMP C routines.
+
+ `cmp' can be used with any of the classes or the standard C++
+ types, except `long long' and `long double'.
+
+ The accuracy provided by `hypot' is not currently guaranteed.
+
+ -- Function: mp_bitcnt_t mpf_class::get_prec ()
+ -- Function: void mpf_class::set_prec (mp_bitcnt_t PREC)
+ -- Function: void mpf_class::set_prec_raw (mp_bitcnt_t PREC)
+ Get or set the current precision of an `mpf_class'.
+
+ The restrictions described for `mpf_set_prec_raw' (*note
+ Initializing Floats::) apply to `mpf_class::set_prec_raw'. Note
+ in particular that the `mpf_class' must be restored to it's
+ allocated precision before being destroyed. This must be done by
+ application code, there's no automatic mechanism for it.
+
+
+File: gmp.info, Node: C++ Interface Random Numbers, Next: C++ Interface Limitations, Prev: C++ Interface Floats, Up: C++ Class Interface
+
+12.5 C++ Interface Random Numbers
+=================================
+
+ -- Class: gmp_randclass
+ The C++ class interface to the GMP random number functions uses
+ `gmp_randclass' to hold an algorithm selection and current state,
+ as per `gmp_randstate_t'.
+
+ -- Function: gmp_randclass::gmp_randclass (void (*RANDINIT)
+ (gmp_randstate_t, ...), ...)
+ Construct a `gmp_randclass', using a call to the given RANDINIT
+ function (*note Random State Initialization::). The arguments
+ expected are the same as RANDINIT, but with `mpz_class' instead of
+ `mpz_t'. For example,
+
+ gmp_randclass r1 (gmp_randinit_default);
+ gmp_randclass r2 (gmp_randinit_lc_2exp_size, 32);
+ gmp_randclass r3 (gmp_randinit_lc_2exp, a, c, m2exp);
+ gmp_randclass r4 (gmp_randinit_mt);
+
+ `gmp_randinit_lc_2exp_size' will fail if the size requested is too
+ big, an `std::length_error' exception is thrown in that case.
+
+ -- Function: gmp_randclass::gmp_randclass (gmp_randalg_t ALG, ...)
+ Construct a `gmp_randclass' using the same parameters as
+ `gmp_randinit' (*note Random State Initialization::). This
+ function is obsolete and the above RANDINIT style should be
+ preferred.
+
+ -- Function: void gmp_randclass::seed (unsigned long int S)
+ -- Function: void gmp_randclass::seed (mpz_class S)
+ Seed a random number generator. See *note Random Number
+ Functions::, for how to choose a good seed.
+
+ -- Function: mpz_class gmp_randclass::get_z_bits (mp_bitcnt_t BITS)
+ -- Function: mpz_class gmp_randclass::get_z_bits (mpz_class BITS)
+ Generate a random integer with a specified number of bits.
+
+ -- Function: mpz_class gmp_randclass::get_z_range (mpz_class N)
+ Generate a random integer in the range 0 to N-1 inclusive.
+
+ -- Function: mpf_class gmp_randclass::get_f ()
+ -- Function: mpf_class gmp_randclass::get_f (mp_bitcnt_t PREC)
+ Generate a random float F in the range 0 <= F < 1. F will be to
+ PREC bits precision, or if PREC is not given then to the precision
+ of the destination. For example,
+
+ gmp_randclass r;
+ ...
+ mpf_class f (0, 512); // 512 bits precision
+ f = r.get_f(); // random number, 512 bits
+
+
+File: gmp.info, Node: C++ Interface Limitations, Prev: C++ Interface Random Numbers, Up: C++ Class Interface
+
+12.6 C++ Interface Limitations
+==============================
+
+`mpq_class' and Templated Reading
+ A generic piece of template code probably won't know that
+ `mpq_class' requires a `canonicalize' call if inputs read with
+ `operator>>' might be non-canonical. This can lead to incorrect
+ results.
+
+ `operator>>' behaves as it does for reasons of efficiency. A
+ canonicalize can be quite time consuming on large operands, and is
+ best avoided if it's not necessary.
+
+ But this potential difficulty reduces the usefulness of
+ `mpq_class'. Perhaps a mechanism to tell `operator>>' what to do
+ will be adopted in the future, maybe a preprocessor define, a
+ global flag, or an `ios' flag pressed into service. Or maybe, at
+ the risk of inconsistency, the `mpq_class' `operator>>' could
+ canonicalize and leave `mpq_t' `operator>>' not doing so, for use
+ on those occasions when that's acceptable. Send feedback or
+ alternate ideas to <gmp-bugs@gmplib.org>.
+
+Subclassing
+ Subclassing the GMP C++ classes works, but is not currently
+ recommended.
+
+ Expressions involving subclasses resolve correctly (or seem to),
+ but in normal C++ fashion the subclass doesn't inherit
+ constructors and assignments. There's many of those in the GMP
+ classes, and a good way to reestablish them in a subclass is not
+ yet provided.
+
+Templated Expressions
+ A subtle difficulty exists when using expressions together with
+ application-defined template functions. Consider the following,
+ with `T' intended to be some numeric type,
+
+ template <class T>
+ T fun (const T &, const T &);
+
+ When used with, say, plain `mpz_class' variables, it works fine:
+ `T' is resolved as `mpz_class'.
+
+ mpz_class f(1), g(2);
+ fun (f, g); // Good
+
+ But when one of the arguments is an expression, it doesn't work.
+
+ mpz_class f(1), g(2), h(3);
+ fun (f, g+h); // Bad
+
+ This is because `g+h' ends up being a certain expression template
+ type internal to `gmpxx.h', which the C++ template resolution
+ rules are unable to automatically convert to `mpz_class'. The
+ workaround is simply to add an explicit cast.
+
+ mpz_class f(1), g(2), h(3);
+ fun (f, mpz_class(g+h)); // Good
+
+ Similarly, within `fun' it may be necessary to cast an expression
+ to type `T' when calling a templated `fun2'.
+
+ template <class T>
+ void fun (T f, T g)
+ {
+ fun2 (f, f+g); // Bad
+ }
+
+ template <class T>
+ void fun (T f, T g)
+ {
+ fun2 (f, T(f+g)); // Good
+ }
+
+C++11
+ C++11 provides several new ways in which types can be inferred:
+ `auto', `decltype', etc. While they can be very convenient, they
+ don't mix well with expression templates. In this example, the
+ addition is performed twice, as if we had defined `sum' as a macro.
+
+ mpz_class z = 33;
+ auto sum = z + z;
+ mpz_class prod = sum * sum;
+
+ This other example may crash, though some compilers might make it
+ look like it is working, because the expression `z+z' goes out of
+ scope before it is evaluated.
+
+ mpz_class z = 33;
+ auto sum = z + z + z;
+ mpz_class prod = sum * 2;
+
+ It is thus strongly recommended to avoid `auto' anywhere a GMP C++
+ expression may appear.
+
+
+File: gmp.info, Node: Custom Allocation, Next: Language Bindings, Prev: C++ Class Interface, Up: Top
+
+13 Custom Allocation
+********************
+
+By default GMP uses `malloc', `realloc' and `free' for memory
+allocation, and if they fail GMP prints a message to the standard error
+output and terminates the program.
+
+ Alternate functions can be specified, to allocate memory in a
+different way or to have a different error action on running out of
+memory.
+
+ -- Function: void mp_set_memory_functions (
+ void *(*ALLOC_FUNC_PTR) (size_t),
+ void *(*REALLOC_FUNC_PTR) (void *, size_t, size_t),
+ void (*FREE_FUNC_PTR) (void *, size_t))
+ Replace the current allocation functions from the arguments. If
+ an argument is `NULL', the corresponding default function is used.
+
+ These functions will be used for all memory allocation done by
+ GMP, apart from temporary space from `alloca' if that function is
+ available and GMP is configured to use it (*note Build Options::).
+
+ *Be sure to call `mp_set_memory_functions' only when there are no
+ active GMP objects allocated using the previous memory functions!
+ Usually that means calling it before any other GMP function.*
+
+ The functions supplied should fit the following declarations:
+
+ -- Function: void * allocate_function (size_t ALLOC_SIZE)
+ Return a pointer to newly allocated space with at least ALLOC_SIZE
+ bytes.
+
+ -- Function: void * reallocate_function (void *PTR, size_t OLD_SIZE,
+ size_t NEW_SIZE)
+ Resize a previously allocated block PTR of OLD_SIZE bytes to be
+ NEW_SIZE bytes.
+
+ The block may be moved if necessary or if desired, and in that
+ case the smaller of OLD_SIZE and NEW_SIZE bytes must be copied to
+ the new location. The return value is a pointer to the resized
+ block, that being the new location if moved or just PTR if not.
+
+ PTR is never `NULL', it's always a previously allocated block.
+ NEW_SIZE may be bigger or smaller than OLD_SIZE.
+
+ -- Function: void free_function (void *PTR, size_t SIZE)
+ De-allocate the space pointed to by PTR.
+
+ PTR is never `NULL', it's always a previously allocated block of
+ SIZE bytes.
+
+ A "byte" here means the unit used by the `sizeof' operator.
+
+ The REALLOCATE_FUNCTION parameter OLD_SIZE and the FREE_FUNCTION
+parameter SIZE are passed for convenience, but of course they can be
+ignored if not needed by an implementation. The default functions
+using `malloc' and friends for instance don't use them.
+
+ No error return is allowed from any of these functions, if they
+return then they must have performed the specified operation. In
+particular note that ALLOCATE_FUNCTION or REALLOCATE_FUNCTION mustn't
+return `NULL'.
+
+ Getting a different fatal error action is a good use for custom
+allocation functions, for example giving a graphical dialog rather than
+the default print to `stderr'. How much is possible when genuinely out
+of memory is another question though.
+
+ There's currently no defined way for the allocation functions to
+recover from an error such as out of memory, they must terminate
+program execution. A `longjmp' or throwing a C++ exception will have
+undefined results. This may change in the future.
+
+ GMP may use allocated blocks to hold pointers to other allocated
+blocks. This will limit the assumptions a conservative garbage
+collection scheme can make.
+
+ Since the default GMP allocation uses `malloc' and friends, those
+functions will be linked in even if the first thing a program does is an
+`mp_set_memory_functions'. It's necessary to change the GMP sources if
+this is a problem.
+
+
+ -- Function: void mp_get_memory_functions (
+ void *(**ALLOC_FUNC_PTR) (size_t),
+ void *(**REALLOC_FUNC_PTR) (void *, size_t, size_t),
+ void (**FREE_FUNC_PTR) (void *, size_t))
+ Get the current allocation functions, storing function pointers to
+ the locations given by the arguments. If an argument is `NULL',
+ that function pointer is not stored.
+
+ For example, to get just the current free function,
+
+ void (*freefunc) (void *, size_t);
+
+ mp_get_memory_functions (NULL, NULL, &freefunc);
+
+
+File: gmp.info, Node: Language Bindings, Next: Algorithms, Prev: Custom Allocation, Up: Top
+
+14 Language Bindings
+********************
+
+The following packages and projects offer access to GMP from languages
+other than C, though perhaps with varying levels of functionality and
+efficiency.
+
+
+C++
+ * GMP C++ class interface, *note C++ Class Interface::
+ Straightforward interface, expression templates to eliminate
+ temporaries.
+
+ * ALP `https://www-sop.inria.fr/saga/logiciels/ALP/'
+ Linear algebra and polynomials using templates.
+
+ * Arithmos `http://cant.ua.ac.be/old/arithmos/'
+ Rationals with infinities and square roots.
+
+ * CLN `http://www.ginac.de/CLN/'
+ High level classes for arithmetic.
+
+ * Linbox `http://www.linalg.org/'
+ Sparse vectors and matrices.
+
+ * NTL `http://www.shoup.net/ntl/'
+ A C++ number theory library.
+
+Eiffel
+ * Eiffelroom `http://www.eiffelroom.org/node/442'
+
+Haskell
+ * Glasgow Haskell Compiler `https://www.haskell.org/ghc/'
+
+Java
+ * Kaffe `https://github.com/kaffe/kaffe'
+
+Lisp
+ * GNU Common Lisp `https://www.gnu.org/software/gcl/gcl.html'
+
+ * Librep `http://librep.sourceforge.net/'
+
+ * XEmacs (21.5.18 beta and up) `http://www.xemacs.org'
+ Optional big integers, rationals and floats using GMP.
+
+M4
+ * GNU m4 betas `http://www.seindal.dk/rene/gnu/'
+ Optionally provides an arbitrary precision `mpeval'.
+
+ML
+ * MLton compiler `http://mlton.org/'
+
+Objective Caml
+ * MLGMP `http://opam.ocamlpro.com/pkg/mlgmp.20120224.html'
+
+ * Numerix `http://pauillac.inria.fr/~quercia/'
+ Optionally using GMP.
+
+Oz
+ * Mozart `http://mozart.github.io/'
+
+Pascal
+ * GNU Pascal Compiler `http://www.gnu-pascal.de/'
+ GMP unit.
+
+ * Numerix `http://pauillac.inria.fr/~quercia/'
+ For Free Pascal, optionally using GMP.
+
+Perl
+ * GMP module, see `demos/perl' in the GMP sources (*note
+ Demonstration Programs::).
+
+ * Math::GMP `http://www.cpan.org/'
+ Compatible with Math::BigInt, but not as many functions as
+ the GMP module above.
+
+ * Math::BigInt::GMP `http://www.cpan.org/'
+ Plug Math::GMP into normal Math::BigInt operations.
+
+Pike
+ * mpz module in the standard distribution,
+ `http://pike.ida.liu.se/'
+
+Prolog
+ * SWI Prolog `http://www.swi-prolog.org/'
+ Arbitrary precision floats.
+
+Python
+ * GMPY `https://code.google.com/p/gmpy/'
+
+Ruby
+ * http://rubygems.org/gems/gmp
+
+Scheme
+ * GNU Guile `https://www.gnu.org/software/guile/guile.html'
+
+ * RScheme `http://www.rscheme.org/'
+
+ * STklos `http://www.stklos.net/'
+
+Smalltalk
+ * GNU Smalltalk
+ `http://www.smalltalk.org/versions/GNUSmalltalk.html'
+
+Other
+ * Axiom `https://savannah.nongnu.org/projects/axiom'
+ Computer algebra using GCL.
+
+ * DrGenius `http://drgenius.seul.org/'
+ Geometry system and mathematical programming language.
+
+ * GiNaC `http://www.ginac.de/'
+ C++ computer algebra using CLN.
+
+ * GOO `https://www.eecs.berkeley.edu/~jrb/goo/'
+ Dynamic object oriented language.
+
+ * Maxima `https://www.ma.utexas.edu/users/wfs/maxima.html'
+ Macsyma computer algebra using GCL.
+
+ * Regina `http://regina.sourceforge.net/'
+ Topological calculator.
+
+ * Yacas `http://yacas.sourceforge.net'
+ Yet another computer algebra system.
+
+
+
+File: gmp.info, Node: Algorithms, Next: Internals, Prev: Language Bindings, Up: Top
+
+15 Algorithms
+*************
+
+This chapter is an introduction to some of the algorithms used for
+various GMP operations. The code is likely to be hard to understand
+without knowing something about the algorithms.
+
+ Some GMP internals are mentioned, but applications that expect to be
+compatible with future GMP releases should take care to use only the
+documented functions.
+
+* Menu:
+
+* Multiplication Algorithms::
+* Division Algorithms::
+* Greatest Common Divisor Algorithms::
+* Powering Algorithms::
+* Root Extraction Algorithms::
+* Radix Conversion Algorithms::
+* Other Algorithms::
+* Assembly Coding::
+
+
+File: gmp.info, Node: Multiplication Algorithms, Next: Division Algorithms, Prev: Algorithms, Up: Algorithms
+
+15.1 Multiplication
+===================
+
+NxN limb multiplications and squares are done using one of seven
+algorithms, as the size N increases.
+
+ Algorithm Threshold
+ Basecase (none)
+ Karatsuba `MUL_TOOM22_THRESHOLD'
+ Toom-3 `MUL_TOOM33_THRESHOLD'
+ Toom-4 `MUL_TOOM44_THRESHOLD'
+ Toom-6.5 `MUL_TOOM6H_THRESHOLD'
+ Toom-8.5 `MUL_TOOM8H_THRESHOLD'
+ FFT `MUL_FFT_THRESHOLD'
+
+ Similarly for squaring, with the `SQR' thresholds.
+
+ NxM multiplications of operands with different sizes above
+`MUL_TOOM22_THRESHOLD' are currently done by special Toom-inspired
+algorithms or directly with FFT, depending on operand size (*note
+Unbalanced Multiplication::).
+
+* Menu:
+
+* Basecase Multiplication::
+* Karatsuba Multiplication::
+* Toom 3-Way Multiplication::
+* Toom 4-Way Multiplication::
+* Higher degree Toom'n'half::
+* FFT Multiplication::
+* Other Multiplication::
+* Unbalanced Multiplication::
+
+
+File: gmp.info, Node: Basecase Multiplication, Next: Karatsuba Multiplication, Prev: Multiplication Algorithms, Up: Multiplication Algorithms
+
+15.1.1 Basecase Multiplication
+------------------------------
+
+Basecase NxM multiplication is a straightforward rectangular set of
+cross-products, the same as long multiplication done by hand and for
+that reason sometimes known as the schoolbook or grammar school method.
+This is an O(N*M) algorithm. See Knuth section 4.3.1 algorithm M
+(*note References::), and the `mpn/generic/mul_basecase.c' code.
+
+ Assembly implementations of `mpn_mul_basecase' are essentially the
+same as the generic C code, but have all the usual assembly tricks and
+obscurities introduced for speed.
+
+ A square can be done in roughly half the time of a multiply, by
+using the fact that the cross products above and below the diagonal are
+the same. A triangle of products below the diagonal is formed, doubled
+(left shift by one bit), and then the products on the diagonal added.
+This can be seen in `mpn/generic/sqr_basecase.c'. Again the assembly
+implementations take essentially the same approach.
+
+ u0 u1 u2 u3 u4
+ +---+---+---+---+---+
+ u0 | d | | | | |
+ +---+---+---+---+---+
+ u1 | | d | | | |
+ +---+---+---+---+---+
+ u2 | | | d | | |
+ +---+---+---+---+---+
+ u3 | | | | d | |
+ +---+---+---+---+---+
+ u4 | | | | | d |
+ +---+---+---+---+---+
+
+ In practice squaring isn't a full 2x faster than multiplying, it's
+usually around 1.5x. Less than 1.5x probably indicates
+`mpn_sqr_basecase' wants improving on that CPU.
+
+ On some CPUs `mpn_mul_basecase' can be faster than the generic C
+`mpn_sqr_basecase' on some small sizes. `SQR_BASECASE_THRESHOLD' is
+the size at which to use `mpn_sqr_basecase', this will be zero if that
+routine should be used always.
+
+
+File: gmp.info, Node: Karatsuba Multiplication, Next: Toom 3-Way Multiplication, Prev: Basecase Multiplication, Up: Multiplication Algorithms
+
+15.1.2 Karatsuba Multiplication
+-------------------------------
+
+The Karatsuba multiplication algorithm is described in Knuth section
+4.3.3 part A, and various other textbooks. A brief description is
+given here.
+
+ The inputs x and y are treated as each split into two parts of equal
+length (or the most significant part one limb shorter if N is odd).
+
+ high low
+ +----------+----------+
+ | x1 | x0 |
+ +----------+----------+
+
+ +----------+----------+
+ | y1 | y0 |
+ +----------+----------+
+
+ Let b be the power of 2 where the split occurs, i.e. if x0 is k
+limbs (y0 the same) then b=2^(k*mp_bits_per_limb). With that x=x1*b+x0
+and y=y1*b+y0, and the following holds,
+
+ x*y = (b^2+b)*x1*y1 - b*(x1-x0)*(y1-y0) + (b+1)*x0*y0
+
+ This formula means doing only three multiplies of (N/2)x(N/2) limbs,
+whereas a basecase multiply of NxN limbs is equivalent to four
+multiplies of (N/2)x(N/2). The factors (b^2+b) etc represent the
+positions where the three products must be added.
+
+ high low
+ +--------+--------+ +--------+--------+
+ | x1*y1 | | x0*y0 |
+ +--------+--------+ +--------+--------+
+ +--------+--------+
+ add | x1*y1 |
+ +--------+--------+
+ +--------+--------+
+ add | x0*y0 |
+ +--------+--------+
+ +--------+--------+
+ sub | (x1-x0)*(y1-y0) |
+ +--------+--------+
+
+ The term (x1-x0)*(y1-y0) is best calculated as an absolute value,
+and the sign used to choose to add or subtract. Notice the sum
+high(x0*y0)+low(x1*y1) occurs twice, so it's possible to do 5*k limb
+additions, rather than 6*k, but in GMP extra function call overheads
+outweigh the saving.
+
+ Squaring is similar to multiplying, but with x=y the formula reduces
+to an equivalent with three squares,
+
+ x^2 = (b^2+b)*x1^2 - b*(x1-x0)^2 + (b+1)*x0^2
+
+ The final result is accumulated from those three squares the same
+way as for the three multiplies above. The middle term (x1-x0)^2 is now
+always positive.
+
+ A similar formula for both multiplying and squaring can be
+constructed with a middle term (x1+x0)*(y1+y0). But those sums can
+exceed k limbs, leading to more carry handling and additions than the
+form above.
+
+ Karatsuba multiplication is asymptotically an O(N^1.585) algorithm,
+the exponent being log(3)/log(2), representing 3 multiplies each 1/2
+the size of the inputs. This is a big improvement over the basecase
+multiply at O(N^2) and the advantage soon overcomes the extra additions
+Karatsuba performs. `MUL_TOOM22_THRESHOLD' can be as little as 10
+limbs. The `SQR' threshold is usually about twice the `MUL'.
+
+ The basecase algorithm will take a time of the form M(N) = a*N^2 +
+b*N + c and the Karatsuba algorithm K(N) = 3*M(N/2) + d*N + e, which
+expands to K(N) = 3/4*a*N^2 + 3/2*b*N + 3*c + d*N + e. The factor 3/4
+for a means per-crossproduct speedups in the basecase code will
+increase the threshold since they benefit M(N) more than K(N). And
+conversely the 3/2 for b means linear style speedups of b will increase
+the threshold since they benefit K(N) more than M(N). The latter can
+be seen for instance when adding an optimized `mpn_sqr_diagonal' to
+`mpn_sqr_basecase'. Of course all speedups reduce total time, and in
+that sense the algorithm thresholds are merely of academic interest.
+
+
+File: gmp.info, Node: Toom 3-Way Multiplication, Next: Toom 4-Way Multiplication, Prev: Karatsuba Multiplication, Up: Multiplication Algorithms
+
+15.1.3 Toom 3-Way Multiplication
+--------------------------------
+
+The Karatsuba formula is the simplest case of a general approach to
+splitting inputs that leads to both Toom and FFT algorithms. A
+description of Toom can be found in Knuth section 4.3.3, with an
+example 3-way calculation after Theorem A. The 3-way form used in GMP
+is described here.
+
+ The operands are each considered split into 3 pieces of equal length
+(or the most significant part 1 or 2 limbs shorter than the other two).
+
+ high low
+ +----------+----------+----------+
+ | x2 | x1 | x0 |
+ +----------+----------+----------+
+
+ +----------+----------+----------+
+ | y2 | y1 | y0 |
+ +----------+----------+----------+
+
+These parts are treated as the coefficients of two polynomials
+
+ X(t) = x2*t^2 + x1*t + x0
+ Y(t) = y2*t^2 + y1*t + y0
+
+ Let b equal the power of 2 which is the size of the x0, x1, y0 and
+y1 pieces, i.e. if they're k limbs each then b=2^(k*mp_bits_per_limb).
+With this x=X(b) and y=Y(b).
+
+ Let a polynomial W(t)=X(t)*Y(t) and suppose its coefficients are
+
+ W(t) = w4*t^4 + w3*t^3 + w2*t^2 + w1*t + w0
+
+ The w[i] are going to be determined, and when they are they'll give
+the final result using w=W(b), since x*y=X(b)*Y(b)=W(b). The
+coefficients will be roughly b^2 each, and the final W(b) will be an
+addition like,
+
+ high low
+ +-------+-------+
+ | w4 |
+ +-------+-------+
+ +--------+-------+
+ | w3 |
+ +--------+-------+
+ +--------+-------+
+ | w2 |
+ +--------+-------+
+ +--------+-------+
+ | w1 |
+ +--------+-------+
+ +-------+-------+
+ | w0 |
+ +-------+-------+
+
+ The w[i] coefficients could be formed by a simple set of cross
+products, like w4=x2*y2, w3=x2*y1+x1*y2, w2=x2*y0+x1*y1+x0*y2 etc, but
+this would need all nine x[i]*y[j] for i,j=0,1,2, and would be
+equivalent merely to a basecase multiply. Instead the following
+approach is used.
+
+ X(t) and Y(t) are evaluated and multiplied at 5 points, giving
+values of W(t) at those points. In GMP the following points are used,
+
+ Point Value
+ t=0 x0 * y0, which gives w0 immediately
+ t=1 (x2+x1+x0) * (y2+y1+y0)
+ t=-1 (x2-x1+x0) * (y2-y1+y0)
+ t=2 (4*x2+2*x1+x0) * (4*y2+2*y1+y0)
+ t=inf x2 * y2, which gives w4 immediately
+
+ At t=-1 the values can be negative and that's handled using the
+absolute values and tracking the sign separately. At t=inf the value
+is actually X(t)*Y(t)/t^4 in the limit as t approaches infinity, but
+it's much easier to think of as simply x2*y2 giving w4 immediately
+(much like x0*y0 at t=0 gives w0 immediately).
+
+ Each of the points substituted into W(t)=w4*t^4+...+w0 gives a
+linear combination of the w[i] coefficients, and the value of those
+combinations has just been calculated.
+
+ W(0) = w0
+ W(1) = w4 + w3 + w2 + w1 + w0
+ W(-1) = w4 - w3 + w2 - w1 + w0
+ W(2) = 16*w4 + 8*w3 + 4*w2 + 2*w1 + w0
+ W(inf) = w4
+
+ This is a set of five equations in five unknowns, and some
+elementary linear algebra quickly isolates each w[i]. This involves
+adding or subtracting one W(t) value from another, and a couple of
+divisions by powers of 2 and one division by 3, the latter using the
+special `mpn_divexact_by3' (*note Exact Division::).
+
+ The conversion of W(t) values to the coefficients is interpolation.
+A polynomial of degree 4 like W(t) is uniquely determined by values
+known at 5 different points. The points are arbitrary and can be
+chosen to make the linear equations come out with a convenient set of
+steps for quickly isolating the w[i].
+
+ Squaring follows the same procedure as multiplication, but there's
+only one X(t) and it's evaluated at the 5 points, and those values
+squared to give values of W(t). The interpolation is then identical,
+and in fact the same `toom_interpolate_5pts' subroutine is used for
+both squaring and multiplying.
+
+ Toom-3 is asymptotically O(N^1.465), the exponent being
+log(5)/log(3), representing 5 recursive multiplies of 1/3 the original
+size each. This is an improvement over Karatsuba at O(N^1.585), though
+Toom does more work in the evaluation and interpolation and so it only
+realizes its advantage above a certain size.
+
+ Near the crossover between Toom-3 and Karatsuba there's generally a
+range of sizes where the difference between the two is small.
+`MUL_TOOM33_THRESHOLD' is a somewhat arbitrary point in that range and
+successive runs of the tune program can give different values due to
+small variations in measuring. A graph of time versus size for the two
+shows the effect, see `tune/README'.
+
+ At the fairly small sizes where the Toom-3 thresholds occur it's
+worth remembering that the asymptotic behaviour for Karatsuba and
+Toom-3 can't be expected to make accurate predictions, due of course to
+the big influence of all sorts of overheads, and the fact that only a
+few recursions of each are being performed. Even at large sizes
+there's a good chance machine dependent effects like cache architecture
+will mean actual performance deviates from what might be predicted.
+
+ The formula given for the Karatsuba algorithm (*note Karatsuba
+Multiplication::) has an equivalent for Toom-3 involving only five
+multiplies, but this would be complicated and unenlightening.
+
+ An alternate view of Toom-3 can be found in Zuras (*note
+References::), using a vector to represent the x and y splits and a
+matrix multiplication for the evaluation and interpolation stages. The
+matrix inverses are not meant to be actually used, and they have
+elements with values much greater than in fact arise in the
+interpolation steps. The diagram shown for the 3-way is attractive,
+but again doesn't have to be implemented that way and for example with
+a bit of rearrangement just one division by 6 can be done.
+
+
+File: gmp.info, Node: Toom 4-Way Multiplication, Next: Higher degree Toom'n'half, Prev: Toom 3-Way Multiplication, Up: Multiplication Algorithms
+
+15.1.4 Toom 4-Way Multiplication
+--------------------------------
+
+Karatsuba and Toom-3 split the operands into 2 and 3 coefficients,
+respectively. Toom-4 analogously splits the operands into 4
+coefficients. Using the notation from the section on Toom-3
+multiplication, we form two polynomials:
+
+ X(t) = x3*t^3 + x2*t^2 + x1*t + x0
+ Y(t) = y3*t^3 + y2*t^2 + y1*t + y0
+
+ X(t) and Y(t) are evaluated and multiplied at 7 points, giving
+values of W(t) at those points. In GMP the following points are used,
+
+ Point Value
+ t=0 x0 * y0, which gives w0 immediately
+ t=1/2 (x3+2*x2+4*x1+8*x0) * (y3+2*y2+4*y1+8*y0)
+ t=-1/2 (-x3+2*x2-4*x1+8*x0) * (-y3+2*y2-4*y1+8*y0)
+ t=1 (x3+x2+x1+x0) * (y3+y2+y1+y0)
+ t=-1 (-x3+x2-x1+x0) * (-y3+y2-y1+y0)
+ t=2 (8*x3+4*x2+2*x1+x0) * (8*y3+4*y2+2*y1+y0)
+ t=inf x3 * y3, which gives w6 immediately
+
+ The number of additions and subtractions for Toom-4 is much larger
+than for Toom-3. But several subexpressions occur multiple times, for
+example x2+x0, occurs for both t=1 and t=-1.
+
+ Toom-4 is asymptotically O(N^1.404), the exponent being
+log(7)/log(4), representing 7 recursive multiplies of 1/4 the original
+size each.
+
+
+File: gmp.info, Node: Higher degree Toom'n'half, Next: FFT Multiplication, Prev: Toom 4-Way Multiplication, Up: Multiplication Algorithms
+
+15.1.5 Higher degree Toom'n'half
+--------------------------------
+
+The Toom algorithms described above (*note Toom 3-Way Multiplication::,
+*note Toom 4-Way Multiplication::) generalizes to split into an
+arbitrary number of pieces. In general a split of two equally long
+operands into r pieces leads to evaluations and pointwise
+multiplications done at 2*r-1 points. To fully exploit symmetries it
+would be better to have a multiple of 4 points, that's why for higher
+degree Toom'n'half is used.
+
+ Toom'n'half means that the existence of one more piece is considered
+for a single operand. It can be virtual, i.e. zero, or real, when the
+two operand are not exactly balanced. By choosing an even r, Toom-r+1/2
+requires 2r points, a multiple of four.
+
+ The four-plets of points include 0, inf, +1, -1 and +-2^i, +-2^-i .
+Each of them giving shortcuts for the evaluation phase and for some
+steps in the interpolation phase. Further tricks are used to reduce the
+memory footprint of the whole multiplication algorithm to a memory
+buffer equanl in size to the result of the product.
+
+ Current GMP uses both Toom-6'n'half and Toom-8'n'half.
+
+
+File: gmp.info, Node: FFT Multiplication, Next: Other Multiplication, Prev: Higher degree Toom'n'half, Up: Multiplication Algorithms
+
+15.1.6 FFT Multiplication
+-------------------------
+
+At large to very large sizes a Fermat style FFT multiplication is used,
+following Schönhage and Strassen (*note References::). Descriptions of
+FFTs in various forms can be found in many textbooks, for instance
+Knuth section 4.3.3 part C or Lipson chapter IX. A brief description
+of the form used in GMP is given here.
+
+ The multiplication done is x*y mod 2^N+1, for a given N. A full
+product x*y is obtained by choosing N>=bits(x)+bits(y) and padding x
+and y with high zero limbs. The modular product is the native form for
+the algorithm, so padding to get a full product is unavoidable.
+
+ The algorithm follows a split, evaluate, pointwise multiply,
+interpolate and combine similar to that described above for Karatsuba
+and Toom-3. A k parameter controls the split, with an FFT-k splitting
+into 2^k pieces of M=N/2^k bits each. N must be a multiple of
+(2^k)*mp_bits_per_limb so the split falls on limb boundaries, avoiding
+bit shifts in the split and combine stages.
+
+ The evaluations, pointwise multiplications, and interpolation, are
+all done modulo 2^N'+1 where N' is 2M+k+3 rounded up to a multiple of
+2^k and of `mp_bits_per_limb'. The results of interpolation will be
+the following negacyclic convolution of the input pieces, and the
+choice of N' ensures these sums aren't truncated.
+
+ ---
+ \ b
+ w[n] = / (-1) * x[i] * y[j]
+ ---
+ i+j==b*2^k+n
+ b=0,1
+
+ The points used for the evaluation are g^i for i=0 to 2^k-1 where
+g=2^(2N'/2^k). g is a 2^k'th root of unity mod 2^N'+1, which produces
+necessary cancellations at the interpolation stage, and it's also a
+power of 2 so the fast Fourier transforms used for the evaluation and
+interpolation do only shifts, adds and negations.
+
+ The pointwise multiplications are done modulo 2^N'+1 and either
+recurse into a further FFT or use a plain multiplication (Toom-3,
+Karatsuba or basecase), whichever is optimal at the size N'. The
+interpolation is an inverse fast Fourier transform. The resulting set
+of sums of x[i]*y[j] are added at appropriate offsets to give the final
+result.
+
+ Squaring is the same, but x is the only input so it's one transform
+at the evaluate stage and the pointwise multiplies are squares. The
+interpolation is the same.
+
+ For a mod 2^N+1 product, an FFT-k is an O(N^(k/(k-1))) algorithm,
+the exponent representing 2^k recursed modular multiplies each
+1/2^(k-1) the size of the original. Each successive k is an asymptotic
+improvement, but overheads mean each is only faster at bigger and
+bigger sizes. In the code, `MUL_FFT_TABLE' and `SQR_FFT_TABLE' are the
+thresholds where each k is used. Each new k effectively swaps some
+multiplying for some shifts, adds and overheads.
+
+ A mod 2^N+1 product can be formed with a normal NxN->2N bit multiply
+plus a subtraction, so an FFT and Toom-3 etc can be compared directly.
+A k=4 FFT at O(N^1.333) can be expected to be the first faster than
+Toom-3 at O(N^1.465). In practice this is what's found, with
+`MUL_FFT_MODF_THRESHOLD' and `SQR_FFT_MODF_THRESHOLD' being between 300
+and 1000 limbs, depending on the CPU. So far it's been found that only
+very large FFTs recurse into pointwise multiplies above these sizes.
+
+ When an FFT is to give a full product, the change of N to 2N doesn't
+alter the theoretical complexity for a given k, but for the purposes of
+considering where an FFT might be first used it can be assumed that the
+FFT is recursing into a normal multiply and that on that basis it's
+doing 2^k recursed multiplies each 1/2^(k-2) the size of the inputs,
+making it O(N^(k/(k-2))). This would mean k=7 at O(N^1.4) would be the
+first FFT faster than Toom-3. In practice `MUL_FFT_THRESHOLD' and
+`SQR_FFT_THRESHOLD' have been found to be in the k=8 range, somewhere
+between 3000 and 10000 limbs.
+
+ The way N is split into 2^k pieces and then 2M+k+3 is rounded up to
+a multiple of 2^k and `mp_bits_per_limb' means that when
+2^k>=mp_bits_per_limb the effective N is a multiple of 2^(2k-1) bits.
+The +k+3 means some values of N just under such a multiple will be
+rounded to the next. The complexity calculations above assume that a
+favourable size is used, meaning one which isn't padded through
+rounding, and it's also assumed that the extra +k+3 bits are negligible
+at typical FFT sizes.
+
+ The practical effect of the 2^(2k-1) constraint is to introduce a
+step-effect into measured speeds. For example k=8 will round N up to a
+multiple of 32768 bits, so for a 32-bit limb there'll be 512 limb
+groups of sizes for which `mpn_mul_n' runs at the same speed. Or for
+k=9 groups of 2048 limbs, k=10 groups of 8192 limbs, etc. In practice
+it's been found each k is used at quite small multiples of its size
+constraint and so the step effect is quite noticeable in a time versus
+size graph.
+
+ The threshold determinations currently measure at the mid-points of
+size steps, but this is sub-optimal since at the start of a new step it
+can happen that it's better to go back to the previous k for a while.
+Something more sophisticated for `MUL_FFT_TABLE' and `SQR_FFT_TABLE'
+will be needed.
+
+
+File: gmp.info, Node: Other Multiplication, Next: Unbalanced Multiplication, Prev: FFT Multiplication, Up: Multiplication Algorithms
+
+15.1.7 Other Multiplication
+---------------------------
+
+The Toom algorithms described above (*note Toom 3-Way Multiplication::,
+*note Toom 4-Way Multiplication::) generalizes to split into an
+arbitrary number of pieces, as per Knuth section 4.3.3 algorithm C.
+This is not currently used. The notes here are merely for interest.
+
+ In general a split into r+1 pieces is made, and evaluations and
+pointwise multiplications done at 2*r+1 points. A 4-way split does 7
+pointwise multiplies, 5-way does 9, etc. Asymptotically an (r+1)-way
+algorithm is O(N^(log(2*r+1)/log(r+1))). Only the pointwise
+multiplications count towards big-O complexity, but the time spent in
+the evaluate and interpolate stages grows with r and has a significant
+practical impact, with the asymptotic advantage of each r realized only
+at bigger and bigger sizes. The overheads grow as O(N*r), whereas in
+an r=2^k FFT they grow only as O(N*log(r)).
+
+ Knuth algorithm C evaluates at points 0,1,2,...,2*r, but exercise 4
+uses -r,...,0,...,r and the latter saves some small multiplies in the
+evaluate stage (or rather trades them for additions), and has a further
+saving of nearly half the interpolate steps. The idea is to separate
+odd and even final coefficients and then perform algorithm C steps C7
+and C8 on them separately. The divisors at step C7 become j^2 and the
+multipliers at C8 become 2*t*j-j^2.
+
+ Splitting odd and even parts through positive and negative points
+can be thought of as using -1 as a square root of unity. If a 4th root
+of unity was available then a further split and speedup would be
+possible, but no such root exists for plain integers. Going to complex
+integers with i=sqrt(-1) doesn't help, essentially because in Cartesian
+form it takes three real multiplies to do a complex multiply. The
+existence of 2^k'th roots of unity in a suitable ring or field lets the
+fast Fourier transform keep splitting and get to O(N*log(r)).
+
+ Floating point FFTs use complex numbers approximating Nth roots of
+unity. Some processors have special support for such FFTs. But these
+are not used in GMP since it's very difficult to guarantee an exact
+result (to some number of bits). An occasional difference of 1 in the
+last bit might not matter to a typical signal processing algorithm, but
+is of course of vital importance to GMP.
+
+
+File: gmp.info, Node: Unbalanced Multiplication, Prev: Other Multiplication, Up: Multiplication Algorithms
+
+15.1.8 Unbalanced Multiplication
+--------------------------------
+
+Multiplication of operands with different sizes, both below
+`MUL_TOOM22_THRESHOLD' are done with plain schoolbook multiplication
+(*note Basecase Multiplication::).
+
+ For really large operands, we invoke FFT directly.
+
+ For operands between these sizes, we use Toom inspired algorithms
+suggested by Alberto Zanoni and Marco Bodrato. The idea is to split
+the operands into polynomials of different degree. GMP currently
+splits the smaller operand onto 2 coefficients, i.e., a polynomial of
+degree 1, but the larger operand can be split into 2, 3, or 4
+coefficients, i.e., a polynomial of degree 1 to 3.
+
+
+File: gmp.info, Node: Division Algorithms, Next: Greatest Common Divisor Algorithms, Prev: Multiplication Algorithms, Up: Algorithms
+
+15.2 Division Algorithms
+========================
+
+* Menu:
+
+* Single Limb Division::
+* Basecase Division::
+* Divide and Conquer Division::
+* Block-Wise Barrett Division::
+* Exact Division::
+* Exact Remainder::
+* Small Quotient Division::
+
+
+File: gmp.info, Node: Single Limb Division, Next: Basecase Division, Prev: Division Algorithms, Up: Division Algorithms
+
+15.2.1 Single Limb Division
+---------------------------
+
+Nx1 division is implemented using repeated 2x1 divisions from high to
+low, either with a hardware divide instruction or a multiplication by
+inverse, whichever is best on a given CPU.
+
+ The multiply by inverse follows "Improved division by invariant
+integers" by Möller and Granlund (*note References::) and is
+implemented as `udiv_qrnnd_preinv' in `gmp-impl.h'. The idea is to
+have a fixed-point approximation to 1/d (see `invert_limb') and then
+multiply by the high limb (plus one bit) of the dividend to get a
+quotient q. With d normalized (high bit set), q is no more than 1 too
+small. Subtracting q*d from the dividend gives a remainder, and
+reveals whether q or q-1 is correct.
+
+ The result is a division done with two multiplications and four or
+five arithmetic operations. On CPUs with low latency multipliers this
+can be much faster than a hardware divide, though the cost of
+calculating the inverse at the start may mean it's only better on
+inputs bigger than say 4 or 5 limbs.
+
+ When a divisor must be normalized, either for the generic C
+`__udiv_qrnnd_c' or the multiply by inverse, the division performed is
+actually a*2^k by d*2^k where a is the dividend and k is the power
+necessary to have the high bit of d*2^k set. The bit shifts for the
+dividend are usually accomplished "on the fly" meaning by extracting
+the appropriate bits at each step. Done this way the quotient limbs
+come out aligned ready to store. When only the remainder is wanted, an
+alternative is to take the dividend limbs unshifted and calculate r = a
+mod d*2^k followed by an extra final step r*2^k mod d*2^k. This can
+help on CPUs with poor bit shifts or few registers.
+
+ The multiply by inverse can be done two limbs at a time. The
+calculation is basically the same, but the inverse is two limbs and the
+divisor treated as if padded with a low zero limb. This means more
+work, since the inverse will need a 2x2 multiply, but the four 1x1s to
+do that are independent and can therefore be done partly or wholly in
+parallel. Likewise for a 2x1 calculating q*d. The net effect is to
+process two limbs with roughly the same two multiplies worth of latency
+that one limb at a time gives. This extends to 3 or 4 limbs at a time,
+though the extra work to apply the inverse will almost certainly soon
+reach the limits of multiplier throughput.
+
+ A similar approach in reverse can be taken to process just half a
+limb at a time if the divisor is only a half limb. In this case the
+1x1 multiply for the inverse effectively becomes two (1/2)x1 for each
+limb, which can be a saving on CPUs with a fast half limb multiply, or
+in fact if the only multiply is a half limb, and especially if it's not
+pipelined.
+
+
+File: gmp.info, Node: Basecase Division, Next: Divide and Conquer Division, Prev: Single Limb Division, Up: Division Algorithms
+
+15.2.2 Basecase Division
+------------------------
+
+Basecase NxM division is like long division done by hand, but in base
+2^mp_bits_per_limb. See Knuth section 4.3.1 algorithm D, and
+`mpn/generic/sb_divrem_mn.c'.
+
+ Briefly stated, while the dividend remains larger than the divisor,
+a high quotient limb is formed and the Nx1 product q*d subtracted at
+the top end of the dividend. With a normalized divisor (most
+significant bit set), each quotient limb can be formed with a 2x1
+division and a 1x1 multiplication plus some subtractions. The 2x1
+division is by the high limb of the divisor and is done either with a
+hardware divide or a multiply by inverse (the same as in *note Single
+Limb Division::) whichever is faster. Such a quotient is sometimes one
+too big, requiring an addback of the divisor, but that happens rarely.
+
+ With Q=N-M being the number of quotient limbs, this is an O(Q*M)
+algorithm and will run at a speed similar to a basecase QxM
+multiplication, differing in fact only in the extra multiply and divide
+for each of the Q quotient limbs.
+
+
+File: gmp.info, Node: Divide and Conquer Division, Next: Block-Wise Barrett Division, Prev: Basecase Division, Up: Division Algorithms
+
+15.2.3 Divide and Conquer Division
+----------------------------------
+
+For divisors larger than `DC_DIV_QR_THRESHOLD', division is done by
+dividing. Or to be precise by a recursive divide and conquer algorithm
+based on work by Moenck and Borodin, Jebelean, and Burnikel and Ziegler
+(*note References::).
+
+ The algorithm consists essentially of recognising that a 2NxN
+division can be done with the basecase division algorithm (*note
+Basecase Division::), but using N/2 limbs as a base, not just a single
+limb. This way the multiplications that arise are (N/2)x(N/2) and can
+take advantage of Karatsuba and higher multiplication algorithms (*note
+Multiplication Algorithms::). The two "digits" of the quotient are
+formed by recursive Nx(N/2) divisions.
+
+ If the (N/2)x(N/2) multiplies are done with a basecase multiplication
+then the work is about the same as a basecase division, but with more
+function call overheads and with some subtractions separated from the
+multiplies. These overheads mean that it's only when N/2 is above
+`MUL_TOOM22_THRESHOLD' that divide and conquer is of use.
+
+ `DC_DIV_QR_THRESHOLD' is based on the divisor size N, so it will be
+somewhere above twice `MUL_TOOM22_THRESHOLD', but how much above
+depends on the CPU. An optimized `mpn_mul_basecase' can lower
+`DC_DIV_QR_THRESHOLD' a little by offering a ready-made advantage over
+repeated `mpn_submul_1' calls.
+
+ Divide and conquer is asymptotically O(M(N)*log(N)) where M(N) is
+the time for an NxN multiplication done with FFTs. The actual time is
+a sum over multiplications of the recursed sizes, as can be seen near
+the end of section 2.2 of Burnikel and Ziegler. For example, within
+the Toom-3 range, divide and conquer is 2.63*M(N). With higher
+algorithms the M(N) term improves and the multiplier tends to log(N).
+In practice, at moderate to large sizes, a 2NxN division is about 2 to
+4 times slower than an NxN multiplication.
+
+
+File: gmp.info, Node: Block-Wise Barrett Division, Next: Exact Division, Prev: Divide and Conquer Division, Up: Division Algorithms
+
+15.2.4 Block-Wise Barrett Division
+----------------------------------
+
+For the largest divisions, a block-wise Barrett division algorithm is
+used. Here, the divisor is inverted to a precision determined by the
+relative size of the dividend and divisor. Blocks of quotient limbs
+are then generated by multiplying blocks from the dividend by the
+inverse.
+
+ Our block-wise algorithm computes a smaller inverse than in the
+plain Barrett algorithm. For a 2n/n division, the inverse will be just
+ceil(n/2) limbs.
+
+
+File: gmp.info, Node: Exact Division, Next: Exact Remainder, Prev: Block-Wise Barrett Division, Up: Division Algorithms
+
+15.2.5 Exact Division
+---------------------
+
+A so-called exact division is when the dividend is known to be an exact
+multiple of the divisor. Jebelean's exact division algorithm uses this
+knowledge to make some significant optimizations (*note References::).
+
+ The idea can be illustrated in decimal for example with 368154
+divided by 543. Because the low digit of the dividend is 4, the low
+digit of the quotient must be 8. This is arrived at from 4*7 mod 10,
+using the fact 7 is the modular inverse of 3 (the low digit of the
+divisor), since 3*7 == 1 mod 10. So 8*543=4344 can be subtracted from
+the dividend leaving 363810. Notice the low digit has become zero.
+
+ The procedure is repeated at the second digit, with the next
+quotient digit 7 (7 == 1*7 mod 10), subtracting 7*543=3801, leaving
+325800. And finally at the third digit with quotient digit 6 (8*7 mod
+10), subtracting 6*543=3258 leaving 0. So the quotient is 678.
+
+ Notice however that the multiplies and subtractions don't need to
+extend past the low three digits of the dividend, since that's enough
+to determine the three quotient digits. For the last quotient digit no
+subtraction is needed at all. On a 2NxN division like this one, only
+about half the work of a normal basecase division is necessary.
+
+ For an NxM exact division producing Q=N-M quotient limbs, the saving
+over a normal basecase division is in two parts. Firstly, each of the
+Q quotient limbs needs only one multiply, not a 2x1 divide and
+multiply. Secondly, the crossproducts are reduced when Q>M to
+Q*M-M*(M+1)/2, or when Q<=M to Q*(Q-1)/2. Notice the savings are
+complementary. If Q is big then many divisions are saved, or if Q is
+small then the crossproducts reduce to a small number.
+
+ The modular inverse used is calculated efficiently by `binvert_limb'
+in `gmp-impl.h'. This does four multiplies for a 32-bit limb, or six
+for a 64-bit limb. `tune/modlinv.c' has some alternate implementations
+that might suit processors better at bit twiddling than multiplying.
+
+ The sub-quadratic exact division described by Jebelean in "Exact
+Division with Karatsuba Complexity" is not currently implemented. It
+uses a rearrangement similar to the divide and conquer for normal
+division (*note Divide and Conquer Division::), but operating from low
+to high. A further possibility not currently implemented is
+"Bidirectional Exact Integer Division" by Krandick and Jebelean which
+forms quotient limbs from both the high and low ends of the dividend,
+and can halve once more the number of crossproducts needed in a 2NxN
+division.
+
+ A special case exact division by 3 exists in `mpn_divexact_by3',
+supporting Toom-3 multiplication and `mpq' canonicalizations. It forms
+quotient digits with a multiply by the modular inverse of 3 (which is
+`0xAA..AAB') and uses two comparisons to determine a borrow for the next
+limb. The multiplications don't need to be on the dependent chain, as
+long as the effect of the borrows is applied, which can help chips with
+pipelined multipliers.
+
+
+
+Local Variables:
+coding: iso-8859-1
+End:
diff --git a/gmp/doc/gmp.info-2 b/gmp/doc/gmp.info-2
new file mode 100644
index 0000000000..9dd7c34407
--- /dev/null
+++ b/gmp/doc/gmp.info-2
@@ -0,0 +1,3865 @@
+This is ../../gmp/doc/gmp.info, produced by makeinfo version 4.13 from
+../../gmp/doc/gmp.texi.
+
+This manual describes how to install and use the GNU multiple precision
+arithmetic library, version 6.0.0.
+
+ Copyright 1991, 1993-2014 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation License, Version
+1.3 or any later version published by the Free Software Foundation;
+with no Invariant Sections, with the Front-Cover Texts being "A GNU
+Manual", and with the Back-Cover Texts being "You have freedom to copy
+and modify this GNU Manual, like GNU software". A copy of the license
+is included in *note GNU Free Documentation License::.
+
+INFO-DIR-SECTION GNU libraries
+START-INFO-DIR-ENTRY
+* gmp: (gmp). GNU Multiple Precision Arithmetic Library.
+END-INFO-DIR-ENTRY
+
+
+File: gmp.info, Node: Exact Remainder, Next: Small Quotient Division, Prev: Exact Division, Up: Division Algorithms
+
+15.2.6 Exact Remainder
+----------------------
+
+If the exact division algorithm is done with a full subtraction at each
+stage and the dividend isn't a multiple of the divisor, then low zero
+limbs are produced but with a remainder in the high limbs. For
+dividend a, divisor d, quotient q, and b = 2^mp_bits_per_limb, this
+remainder r is of the form
+
+ a = q*d + r*b^n
+
+ n represents the number of zero limbs produced by the subtractions,
+that being the number of limbs produced for q. r will be in the range
+0<=r<d and can be viewed as a remainder, but one shifted up by a factor
+of b^n.
+
+ Carrying out full subtractions at each stage means the same number
+of cross products must be done as a normal division, but there's still
+some single limb divisions saved. When d is a single limb some
+simplifications arise, providing good speedups on a number of
+processors.
+
+ The functions `mpn_divexact_by3', `mpn_modexact_1_odd' and the
+internal `mpn_redc_X' functions differ subtly in how they return r,
+leading to some negations in the above formula, but all are essentially
+the same.
+
+ Clearly r is zero when a is a multiple of d, and this leads to
+divisibility or congruence tests which are potentially more efficient
+than a normal division.
+
+ The factor of b^n on r can be ignored in a GCD when d is odd, hence
+the use of `mpn_modexact_1_odd' by `mpn_gcd_1' and `mpz_kronecker_ui'
+etc (*note Greatest Common Divisor Algorithms::).
+
+ Montgomery's REDC method for modular multiplications uses operands
+of the form of x*b^-n and y*b^-n and on calculating (x*b^-n)*(y*b^-n)
+uses the factor of b^n in the exact remainder to reach a product in the
+same form (x*y)*b^-n (*note Modular Powering Algorithm::).
+
+ Notice that r generally gives no useful information about the
+ordinary remainder a mod d since b^n mod d could be anything. If
+however b^n == 1 mod d, then r is the negative of the ordinary
+remainder. This occurs whenever d is a factor of b^n-1, as for example
+with 3 in `mpn_divexact_by3'. For a 32 or 64 bit limb other such
+factors include 5, 17 and 257, but no particular use has been found for
+this.
+
+
+File: gmp.info, Node: Small Quotient Division, Prev: Exact Remainder, Up: Division Algorithms
+
+15.2.7 Small Quotient Division
+------------------------------
+
+An NxM division where the number of quotient limbs Q=N-M is small can
+be optimized somewhat.
+
+ An ordinary basecase division normalizes the divisor by shifting it
+to make the high bit set, shifting the dividend accordingly, and
+shifting the remainder back down at the end of the calculation. This
+is wasteful if only a few quotient limbs are to be formed. Instead a
+division of just the top 2*Q limbs of the dividend by the top Q limbs
+of the divisor can be used to form a trial quotient. This requires
+only those limbs normalized, not the whole of the divisor and dividend.
+
+ A multiply and subtract then applies the trial quotient to the M-Q
+unused limbs of the divisor and N-Q dividend limbs (which includes Q
+limbs remaining from the trial quotient division). The starting trial
+quotient can be 1 or 2 too big, but all cases of 2 too big and most
+cases of 1 too big are detected by first comparing the most significant
+limbs that will arise from the subtraction. An addback is done if the
+quotient still turns out to be 1 too big.
+
+ This whole procedure is essentially the same as one step of the
+basecase algorithm done in a Q limb base, though with the trial
+quotient test done only with the high limbs, not an entire Q limb
+"digit" product. The correctness of this weaker test can be
+established by following the argument of Knuth section 4.3.1 exercise
+20 but with the v2*q>b*r+u2 condition appropriately relaxed.
+
+
+File: gmp.info, Node: Greatest Common Divisor Algorithms, Next: Powering Algorithms, Prev: Division Algorithms, Up: Algorithms
+
+15.3 Greatest Common Divisor
+============================
+
+* Menu:
+
+* Binary GCD::
+* Lehmer's Algorithm::
+* Subquadratic GCD::
+* Extended GCD::
+* Jacobi Symbol::
+
+
+File: gmp.info, Node: Binary GCD, Next: Lehmer's Algorithm, Prev: Greatest Common Divisor Algorithms, Up: Greatest Common Divisor Algorithms
+
+15.3.1 Binary GCD
+-----------------
+
+At small sizes GMP uses an O(N^2) binary style GCD. This is described
+in many textbooks, for example Knuth section 4.5.2 algorithm B. It
+simply consists of successively reducing odd operands a and b using
+
+ a,b = abs(a-b),min(a,b)
+ strip factors of 2 from a
+
+ The Euclidean GCD algorithm, as per Knuth algorithms E and A,
+repeatedly computes the quotient q = floor(a/b) and replaces a,b by v,
+u - q v. The binary algorithm has so far been found to be faster than
+the Euclidean algorithm everywhere. One reason the binary method does
+well is that the implied quotient at each step is usually small, so
+often only one or two subtractions are needed to get the same effect as
+a division. Quotients 1, 2 and 3 for example occur 67.7% of the time,
+see Knuth section 4.5.3 Theorem E.
+
+ When the implied quotient is large, meaning b is much smaller than
+a, then a division is worthwhile. This is the basis for the initial a
+mod b reductions in `mpn_gcd' and `mpn_gcd_1' (the latter for both Nx1
+and 1x1 cases). But after that initial reduction, big quotients occur
+too rarely to make it worth checking for them.
+
+
+ The final 1x1 GCD in `mpn_gcd_1' is done in the generic C code as
+described above. For two N-bit operands, the algorithm takes about
+0.68 iterations per bit. For optimum performance some attention needs
+to be paid to the way the factors of 2 are stripped from a.
+
+ Firstly it may be noted that in twos complement the number of low
+zero bits on a-b is the same as b-a, so counting or testing can begin on
+a-b without waiting for abs(a-b) to be determined.
+
+ A loop stripping low zero bits tends not to branch predict well,
+since the condition is data dependent. But on average there's only a
+few low zeros, so an option is to strip one or two bits arithmetically
+then loop for more (as done for AMD K6). Or use a lookup table to get
+a count for several bits then loop for more (as done for AMD K7). An
+alternative approach is to keep just one of a or b odd and iterate
+
+ a,b = abs(a-b), min(a,b)
+ a = a/2 if even
+ b = b/2 if even
+
+ This requires about 1.25 iterations per bit, but stripping of a
+single bit at each step avoids any branching. Repeating the bit strip
+reduces to about 0.9 iterations per bit, which may be a worthwhile
+tradeoff.
+
+ Generally with the above approaches a speed of perhaps 6 cycles per
+bit can be achieved, which is still not terribly fast with for instance
+a 64-bit GCD taking nearly 400 cycles. It's this sort of time which
+means it's not usually advantageous to combine a set of divisibility
+tests into a GCD.
+
+ Currently, the binary algorithm is used for GCD only when N < 3.
+
+
+File: gmp.info, Node: Lehmer's Algorithm, Next: Subquadratic GCD, Prev: Binary GCD, Up: Greatest Common Divisor Algorithms
+
+15.3.2 Lehmer's algorithm
+-------------------------
+
+Lehmer's improvement of the Euclidean algorithms is based on the
+observation that the initial part of the quotient sequence depends only
+on the most significant parts of the inputs. The variant of Lehmer's
+algorithm used in GMP splits off the most significant two limbs, as
+suggested, e.g., in "A Double-Digit Lehmer-Euclid Algorithm" by
+Jebelean (*note References::). The quotients of two double-limb inputs
+are collected as a 2 by 2 matrix with single-limb elements. This is
+done by the function `mpn_hgcd2'. The resulting matrix is applied to
+the inputs using `mpn_mul_1' and `mpn_submul_1'. Each iteration usually
+reduces the inputs by almost one limb. In the rare case of a large
+quotient, no progress can be made by examining just the most
+significant two limbs, and the quotient is computed using plain
+division.
+
+ The resulting algorithm is asymptotically O(N^2), just as the
+Euclidean algorithm and the binary algorithm. The quadratic part of the
+work are the calls to `mpn_mul_1' and `mpn_submul_1'. For small sizes,
+the linear work is also significant. There are roughly N calls to the
+`mpn_hgcd2' function. This function uses a couple of important
+optimizations:
+
+ * It uses the same relaxed notion of correctness as `mpn_hgcd' (see
+ next section). This means that when called with the most
+ significant two limbs of two large numbers, the returned matrix
+ does not always correspond exactly to the initial quotient
+ sequence for the two large numbers; the final quotient may
+ sometimes be one off.
+
+ * It takes advantage of the fact the quotients are usually small.
+ The division operator is not used, since the corresponding
+ assembler instruction is very slow on most architectures. (This
+ code could probably be improved further, it uses many branches
+ that are unfriendly to prediction).
+
+ * It switches from double-limb calculations to single-limb
+ calculations half-way through, when the input numbers have been
+ reduced in size from two limbs to one and a half.
+
+
+
+File: gmp.info, Node: Subquadratic GCD, Next: Extended GCD, Prev: Lehmer's Algorithm, Up: Greatest Common Divisor Algorithms
+
+15.3.3 Subquadratic GCD
+-----------------------
+
+For inputs larger than `GCD_DC_THRESHOLD', GCD is computed via the HGCD
+(Half GCD) function, as a generalization to Lehmer's algorithm.
+
+ Let the inputs a,b be of size N limbs each. Put S = floor(N/2) + 1.
+Then HGCD(a,b) returns a transformation matrix T with non-negative
+elements, and reduced numbers (c;d) = T^-1 (a;b). The reduced numbers
+c,d must be larger than S limbs, while their difference abs(c-d) must
+fit in S limbs. The matrix elements will also be of size roughly N/2.
+
+ The HGCD base case uses Lehmer's algorithm, but with the above stop
+condition that returns reduced numbers and the corresponding
+transformation matrix half-way through. For inputs larger than
+`HGCD_THRESHOLD', HGCD is computed recursively, using the divide and
+conquer algorithm in "On Schönhage's algorithm and subquadratic integer
+GCD computation" by Möller (*note References::). The recursive
+algorithm consists of these main steps.
+
+ * Call HGCD recursively, on the most significant N/2 limbs. Apply the
+ resulting matrix T_1 to the full numbers, reducing them to a size
+ just above 3N/2.
+
+ * Perform a small number of division or subtraction steps to reduce
+ the numbers to size below 3N/2. This is essential mainly for the
+ unlikely case of large quotients.
+
+ * Call HGCD recursively, on the most significant N/2 limbs of the
+ reduced numbers. Apply the resulting matrix T_2 to the full
+ numbers, reducing them to a size just above N/2.
+
+ * Compute T = T_1 T_2.
+
+ * Perform a small number of division and subtraction steps to
+ satisfy the requirements, and return.
+
+ GCD is then implemented as a loop around HGCD, similarly to Lehmer's
+algorithm. Where Lehmer repeatedly chops off the top two limbs, calls
+`mpn_hgcd2', and applies the resulting matrix to the full numbers, the
+subquadratic GCD chops off the most significant third of the limbs (the
+proportion is a tuning parameter, and 1/3 seems to be more efficient
+than, e.g, 1/2), calls `mpn_hgcd', and applies the resulting matrix.
+Once the input numbers are reduced to size below `GCD_DC_THRESHOLD',
+Lehmer's algorithm is used for the rest of the work.
+
+ The asymptotic running time of both HGCD and GCD is O(M(N)*log(N)),
+where M(N) is the time for multiplying two N-limb numbers.
+
+
+File: gmp.info, Node: Extended GCD, Next: Jacobi Symbol, Prev: Subquadratic GCD, Up: Greatest Common Divisor Algorithms
+
+15.3.4 Extended GCD
+-------------------
+
+The extended GCD function, or GCDEXT, calculates gcd(a,b) and also
+cofactors x and y satisfying a*x+b*y=gcd(a,b). All the algorithms used
+for plain GCD are extended to handle this case. The binary algorithm is
+used only for single-limb GCDEXT. Lehmer's algorithm is used for sizes
+up to `GCDEXT_DC_THRESHOLD'. Above this threshold, GCDEXT is
+implemented as a loop around HGCD, but with more book-keeping to keep
+track of the cofactors. This gives the same asymptotic running time as
+for GCD and HGCD, O(M(N)*log(N))
+
+ One difference to plain GCD is that while the inputs a and b are
+reduced as the algorithm proceeds, the cofactors x and y grow in size.
+This makes the tuning of the chopping-point more difficult. The current
+code chops off the most significant half of the inputs for the call to
+HGCD in the first iteration, and the most significant two thirds for
+the remaining calls. This strategy could surely be improved. Also the
+stop condition for the loop, where Lehmer's algorithm is invoked once
+the inputs are reduced below `GCDEXT_DC_THRESHOLD', could maybe be
+improved by taking into account the current size of the cofactors.
+
+
+File: gmp.info, Node: Jacobi Symbol, Prev: Extended GCD, Up: Greatest Common Divisor Algorithms
+
+15.3.5 Jacobi Symbol
+--------------------
+
+[This section is obsolete. The current Jacobi code actually uses a very
+efficient algorithm.]
+
+ `mpz_jacobi' and `mpz_kronecker' are currently implemented with a
+simple binary algorithm similar to that described for the GCDs (*note
+Binary GCD::). They're not very fast when both inputs are large.
+Lehmer's multi-step improvement or a binary based multi-step algorithm
+is likely to be better.
+
+ When one operand fits a single limb, and that includes
+`mpz_kronecker_ui' and friends, an initial reduction is done with
+either `mpn_mod_1' or `mpn_modexact_1_odd', followed by the binary
+algorithm on a single limb. The binary algorithm is well suited to a
+single limb, and the whole calculation in this case is quite efficient.
+
+ In all the routines sign changes for the result are accumulated
+using some bit twiddling, avoiding table lookups or conditional jumps.
+
+
+File: gmp.info, Node: Powering Algorithms, Next: Root Extraction Algorithms, Prev: Greatest Common Divisor Algorithms, Up: Algorithms
+
+15.4 Powering Algorithms
+========================
+
+* Menu:
+
+* Normal Powering Algorithm::
+* Modular Powering Algorithm::
+
+
+File: gmp.info, Node: Normal Powering Algorithm, Next: Modular Powering Algorithm, Prev: Powering Algorithms, Up: Powering Algorithms
+
+15.4.1 Normal Powering
+----------------------
+
+Normal `mpz' or `mpf' powering uses a simple binary algorithm,
+successively squaring and then multiplying by the base when a 1 bit is
+seen in the exponent, as per Knuth section 4.6.3. The "left to right"
+variant described there is used rather than algorithm A, since it's
+just as easy and can be done with somewhat less temporary memory.
+
+
+File: gmp.info, Node: Modular Powering Algorithm, Prev: Normal Powering Algorithm, Up: Powering Algorithms
+
+15.4.2 Modular Powering
+-----------------------
+
+Modular powering is implemented using a 2^k-ary sliding window
+algorithm, as per "Handbook of Applied Cryptography" algorithm 14.85
+(*note References::). k is chosen according to the size of the
+exponent. Larger exponents use larger values of k, the choice being
+made to minimize the average number of multiplications that must
+supplement the squaring.
+
+ The modular multiplies and squarings use either a simple division or
+the REDC method by Montgomery (*note References::). REDC is a little
+faster, essentially saving N single limb divisions in a fashion similar
+to an exact remainder (*note Exact Remainder::).
+
+
+File: gmp.info, Node: Root Extraction Algorithms, Next: Radix Conversion Algorithms, Prev: Powering Algorithms, Up: Algorithms
+
+15.5 Root Extraction Algorithms
+===============================
+
+* Menu:
+
+* Square Root Algorithm::
+* Nth Root Algorithm::
+* Perfect Square Algorithm::
+* Perfect Power Algorithm::
+
+
+File: gmp.info, Node: Square Root Algorithm, Next: Nth Root Algorithm, Prev: Root Extraction Algorithms, Up: Root Extraction Algorithms
+
+15.5.1 Square Root
+------------------
+
+Square roots are taken using the "Karatsuba Square Root" algorithm by
+Paul Zimmermann (*note References::).
+
+ An input n is split into four parts of k bits each, so with b=2^k we
+have n = a3*b^3 + a2*b^2 + a1*b + a0. Part a3 must be "normalized" so
+that either the high or second highest bit is set. In GMP, k is kept
+on a limb boundary and the input is left shifted (by an even number of
+bits) to normalize.
+
+ The square root of the high two parts is taken, by recursive
+application of the algorithm (bottoming out in a one-limb Newton's
+method),
+
+ s1,r1 = sqrtrem (a3*b + a2)
+
+ This is an approximation to the desired root and is extended by a
+division to give s,r,
+
+ q,u = divrem (r1*b + a1, 2*s1)
+ s = s1*b + q
+ r = u*b + a0 - q^2
+
+ The normalization requirement on a3 means at this point s is either
+correct or 1 too big. r is negative in the latter case, so
+
+ if r < 0 then
+ r = r + 2*s - 1
+ s = s - 1
+
+ The algorithm is expressed in a divide and conquer form, but as
+noted in the paper it can also be viewed as a discrete variant of
+Newton's method, or as a variation on the schoolboy method (no longer
+taught) for square roots two digits at a time.
+
+ If the remainder r is not required then usually only a few high limbs
+of r and u need to be calculated to determine whether an adjustment to
+s is required. This optimization is not currently implemented.
+
+ In the Karatsuba multiplication range this algorithm is
+O(1.5*M(N/2)), where M(n) is the time to multiply two numbers of n
+limbs. In the FFT multiplication range this grows to a bound of
+O(6*M(N/2)). In practice a factor of about 1.5 to 1.8 is found in the
+Karatsuba and Toom-3 ranges, growing to 2 or 3 in the FFT range.
+
+ The algorithm does all its calculations in integers and the resulting
+`mpn_sqrtrem' is used for both `mpz_sqrt' and `mpf_sqrt'. The extended
+precision given by `mpf_sqrt_ui' is obtained by padding with zero limbs.
+
+
+File: gmp.info, Node: Nth Root Algorithm, Next: Perfect Square Algorithm, Prev: Square Root Algorithm, Up: Root Extraction Algorithms
+
+15.5.2 Nth Root
+---------------
+
+Integer Nth roots are taken using Newton's method with the following
+iteration, where A is the input and n is the root to be taken.
+
+ 1 A
+ a[i+1] = - * ( --------- + (n-1)*a[i] )
+ n a[i]^(n-1)
+
+ The initial approximation a[1] is generated bitwise by successively
+powering a trial root with or without new 1 bits, aiming to be just
+above the true root. The iteration converges quadratically when
+started from a good approximation. When n is large more initial bits
+are needed to get good convergence. The current implementation is not
+particularly well optimized.
+
+
+File: gmp.info, Node: Perfect Square Algorithm, Next: Perfect Power Algorithm, Prev: Nth Root Algorithm, Up: Root Extraction Algorithms
+
+15.5.3 Perfect Square
+---------------------
+
+A significant fraction of non-squares can be quickly identified by
+checking whether the input is a quadratic residue modulo small integers.
+
+ `mpz_perfect_square_p' first tests the input mod 256, which means
+just examining the low byte. Only 44 different values occur for
+squares mod 256, so 82.8% of inputs can be immediately identified as
+non-squares.
+
+ On a 32-bit system similar tests are done mod 9, 5, 7, 13 and 17,
+for a total 99.25% of inputs identified as non-squares. On a 64-bit
+system 97 is tested too, for a total 99.62%.
+
+ These moduli are chosen because they're factors of 2^24-1 (or 2^48-1
+for 64-bits), and such a remainder can be quickly taken just using
+additions (see `mpn_mod_34lsub1').
+
+ When nails are in use moduli are instead selected by the `gen-psqr.c'
+program and applied with an `mpn_mod_1'. The same 2^24-1 or 2^48-1
+could be done with nails using some extra bit shifts, but this is not
+currently implemented.
+
+ In any case each modulus is applied to the `mpn_mod_34lsub1' or
+`mpn_mod_1' remainder and a table lookup identifies non-squares. By
+using a "modexact" style calculation, and suitably permuted tables,
+just one multiply each is required, see the code for details. Moduli
+are also combined to save operations, so long as the lookup tables
+don't become too big. `gen-psqr.c' does all the pre-calculations.
+
+ A square root must still be taken for any value that passes these
+tests, to verify it's really a square and not one of the small fraction
+of non-squares that get through (i.e. a pseudo-square to all the tested
+bases).
+
+ Clearly more residue tests could be done, `mpz_perfect_square_p' only
+uses a compact and efficient set. Big inputs would probably benefit
+from more residue testing, small inputs might be better off with less.
+The assumed distribution of squares versus non-squares in the input
+would affect such considerations.
+
+
+File: gmp.info, Node: Perfect Power Algorithm, Prev: Perfect Square Algorithm, Up: Root Extraction Algorithms
+
+15.5.4 Perfect Power
+--------------------
+
+Detecting perfect powers is required by some factorization algorithms.
+Currently `mpz_perfect_power_p' is implemented using repeated Nth root
+extractions, though naturally only prime roots need to be considered.
+(*Note Nth Root Algorithm::.)
+
+ If a prime divisor p with multiplicity e can be found, then only
+roots which are divisors of e need to be considered, much reducing the
+work necessary. To this end divisibility by a set of small primes is
+checked.
+
+
+File: gmp.info, Node: Radix Conversion Algorithms, Next: Other Algorithms, Prev: Root Extraction Algorithms, Up: Algorithms
+
+15.6 Radix Conversion
+=====================
+
+Radix conversions are less important than other algorithms. A program
+dominated by conversions should probably use a different data
+representation.
+
+* Menu:
+
+* Binary to Radix::
+* Radix to Binary::
+
+
+File: gmp.info, Node: Binary to Radix, Next: Radix to Binary, Prev: Radix Conversion Algorithms, Up: Radix Conversion Algorithms
+
+15.6.1 Binary to Radix
+----------------------
+
+Conversions from binary to a power-of-2 radix use a simple and fast
+O(N) bit extraction algorithm.
+
+ Conversions from binary to other radices use one of two algorithms.
+Sizes below `GET_STR_PRECOMPUTE_THRESHOLD' use a basic O(N^2) method.
+Repeated divisions by b^n are made, where b is the radix and n is the
+biggest power that fits in a limb. But instead of simply using the
+remainder r from such divisions, an extra divide step is done to give a
+fractional limb representing r/b^n. The digits of r can then be
+extracted using multiplications by b rather than divisions. Special
+case code is provided for decimal, allowing multiplications by 10 to
+optimize to shifts and adds.
+
+ Above `GET_STR_PRECOMPUTE_THRESHOLD' a sub-quadratic algorithm is
+used. For an input t, powers b^(n*2^i) of the radix are calculated,
+until a power between t and sqrt(t) is reached. t is then divided by
+that largest power, giving a quotient which is the digits above that
+power, and a remainder which is those below. These two parts are in
+turn divided by the second highest power, and so on recursively. When
+a piece has been divided down to less than `GET_STR_DC_THRESHOLD'
+limbs, the basecase algorithm described above is used.
+
+ The advantage of this algorithm is that big divisions can make use
+of the sub-quadratic divide and conquer division (*note Divide and
+Conquer Division::), and big divisions tend to have less overheads than
+lots of separate single limb divisions anyway. But in any case the
+cost of calculating the powers b^(n*2^i) must first be overcome.
+
+ `GET_STR_PRECOMPUTE_THRESHOLD' and `GET_STR_DC_THRESHOLD' represent
+the same basic thing, the point where it becomes worth doing a big
+division to cut the input in half. `GET_STR_PRECOMPUTE_THRESHOLD'
+includes the cost of calculating the radix power required, whereas
+`GET_STR_DC_THRESHOLD' assumes that's already available, which is the
+case when recursing.
+
+ Since the base case produces digits from least to most significant
+but they want to be stored from most to least, it's necessary to
+calculate in advance how many digits there will be, or at least be sure
+not to underestimate that. For GMP the number of input bits is
+multiplied by `chars_per_bit_exactly' from `mp_bases', rounding up.
+The result is either correct or one too big.
+
+ Examining some of the high bits of the input could increase the
+chance of getting the exact number of digits, but an exact result every
+time would not be practical, since in general the difference between
+numbers 100... and 99... is only in the last few bits and the work to
+identify 99... might well be almost as much as a full conversion.
+
+ `mpf_get_str' doesn't currently use the algorithm described here, it
+multiplies or divides by a power of b to move the radix point to the
+just above the highest non-zero digit (or at worst one above that
+location), then multiplies by b^n to bring out digits. This is O(N^2)
+and is certainly not optimal.
+
+ The r/b^n scheme described above for using multiplications to bring
+out digits might be useful for more than a single limb. Some brief
+experiments with it on the base case when recursing didn't give a
+noticeable improvement, but perhaps that was only due to the
+implementation. Something similar would work for the sub-quadratic
+divisions too, though there would be the cost of calculating a bigger
+radix power.
+
+ Another possible improvement for the sub-quadratic part would be to
+arrange for radix powers that balanced the sizes of quotient and
+remainder produced, i.e. the highest power would be an b^(n*k)
+approximately equal to sqrt(t), not restricted to a 2^i factor. That
+ought to smooth out a graph of times against sizes, but may or may not
+be a net speedup.
+
+
+File: gmp.info, Node: Radix to Binary, Prev: Binary to Radix, Up: Radix Conversion Algorithms
+
+15.6.2 Radix to Binary
+----------------------
+
+*This section needs to be rewritten, it currently describes the
+algorithms used before GMP 4.3.*
+
+ Conversions from a power-of-2 radix into binary use a simple and fast
+O(N) bitwise concatenation algorithm.
+
+ Conversions from other radices use one of two algorithms. Sizes
+below `SET_STR_PRECOMPUTE_THRESHOLD' use a basic O(N^2) method. Groups
+of n digits are converted to limbs, where n is the biggest power of the
+base b which will fit in a limb, then those groups are accumulated into
+the result by multiplying by b^n and adding. This saves
+multi-precision operations, as per Knuth section 4.4 part E (*note
+References::). Some special case code is provided for decimal, giving
+the compiler a chance to optimize multiplications by 10.
+
+ Above `SET_STR_PRECOMPUTE_THRESHOLD' a sub-quadratic algorithm is
+used. First groups of n digits are converted into limbs. Then adjacent
+limbs are combined into limb pairs with x*b^n+y, where x and y are the
+limbs. Adjacent limb pairs are combined into quads similarly with
+x*b^(2n)+y. This continues until a single block remains, that being
+the result.
+
+ The advantage of this method is that the multiplications for each x
+are big blocks, allowing Karatsuba and higher algorithms to be used.
+But the cost of calculating the powers b^(n*2^i) must be overcome.
+`SET_STR_PRECOMPUTE_THRESHOLD' usually ends up quite big, around 5000
+digits, and on some processors much bigger still.
+
+ `SET_STR_PRECOMPUTE_THRESHOLD' is based on the input digits (and
+tuned for decimal), though it might be better based on a limb count, so
+as to be independent of the base. But that sort of count isn't used by
+the base case and so would need some sort of initial calculation or
+estimate.
+
+ The main reason `SET_STR_PRECOMPUTE_THRESHOLD' is so much bigger
+than the corresponding `GET_STR_PRECOMPUTE_THRESHOLD' is that
+`mpn_mul_1' is much faster than `mpn_divrem_1' (often by a factor of 5,
+or more).
+
+
+File: gmp.info, Node: Other Algorithms, Next: Assembly Coding, Prev: Radix Conversion Algorithms, Up: Algorithms
+
+15.7 Other Algorithms
+=====================
+
+* Menu:
+
+* Prime Testing Algorithm::
+* Factorial Algorithm::
+* Binomial Coefficients Algorithm::
+* Fibonacci Numbers Algorithm::
+* Lucas Numbers Algorithm::
+* Random Number Algorithms::
+
+
+File: gmp.info, Node: Prime Testing Algorithm, Next: Factorial Algorithm, Prev: Other Algorithms, Up: Other Algorithms
+
+15.7.1 Prime Testing
+--------------------
+
+The primality testing in `mpz_probab_prime_p' (*note Number Theoretic
+Functions::) first does some trial division by small factors and then
+uses the Miller-Rabin probabilistic primality testing algorithm, as
+described in Knuth section 4.5.4 algorithm P (*note References::).
+
+ For an odd input n, and with n = q*2^k+1 where q is odd, this
+algorithm selects a random base x and tests whether x^q mod n is 1 or
+-1, or an x^(q*2^j) mod n is 1, for 1<=j<=k. If so then n is probably
+prime, if not then n is definitely composite.
+
+ Any prime n will pass the test, but some composites do too. Such
+composites are known as strong pseudoprimes to base x. No n is a
+strong pseudoprime to more than 1/4 of all bases (see Knuth exercise
+22), hence with x chosen at random there's no more than a 1/4 chance a
+"probable prime" will in fact be composite.
+
+ In fact strong pseudoprimes are quite rare, making the test much more
+powerful than this analysis would suggest, but 1/4 is all that's proven
+for an arbitrary n.
+
+
+File: gmp.info, Node: Factorial Algorithm, Next: Binomial Coefficients Algorithm, Prev: Prime Testing Algorithm, Up: Other Algorithms
+
+15.7.2 Factorial
+----------------
+
+Factorials are calculated by a combination of two algorithms. An idea is
+shared among them: to compute the odd part of the factorial; a final
+step takes account of the power of 2 term, by shifting.
+
+ For small n, the odd factor of n! is computed with the simple
+observation that it is equal to the product of all positive odd numbers
+smaller than n times the odd factor of [n/2]!, where [x] is the integer
+part of x, and so on recursively. The procedure can be best illustrated
+with an example,
+
+ 23! = (23.21.19.17.15.13.11.9.7.5.3)(11.9.7.5.3)(5.3)2^19
+
+ Current code collects all the factors in a single list, with a loop
+and no recursion, and compute the product, with no special care for
+repeated chunks.
+
+ When n is larger, computation pass trough prime sieving. An helper
+function is used, as suggested by Peter Luschny:
+
+ n
+ -----
+ n! | | L(p,n)
+ msf(n) = -------------- = | | p
+ [n/2]!^2.2^k p=3
+
+ Where p ranges on odd prime numbers. The exponent k is chosen to
+obtain an odd integer number: k is the number of 1 bits in the binary
+representation of [n/2]. The function L(p,n) can be defined as zero
+when p is composite, and, for any prime p, it is computed with:
+
+ ---
+ \ n
+ L(p,n) = / [---] mod 2 <= log (n) .
+ --- p^i p
+ i>0
+
+ With this helper function, we are able to compute the odd part of n!
+using the recursion implied by n!=[n/2]!^2*msf(n)*2^k. The recursion
+stops using the small-n algorithm on some [n/2^i].
+
+ Both the above algorithms use binary splitting to compute the
+product of many small factors. At first as many products as possible
+are accumulated in a single register, generating a list of factors that
+fit in a machine word. This list is then split into halves, and the
+product is computed recursively.
+
+ Such splitting is more efficient than repeated Nx1 multiplies since
+it forms big multiplies, allowing Karatsuba and higher algorithms to be
+used. And even below the Karatsuba threshold a big block of work can
+be more efficient for the basecase algorithm.
+
+
+File: gmp.info, Node: Binomial Coefficients Algorithm, Next: Fibonacci Numbers Algorithm, Prev: Factorial Algorithm, Up: Other Algorithms
+
+15.7.3 Binomial Coefficients
+----------------------------
+
+Binomial coefficients C(n,k) are calculated by first arranging k <= n/2
+using C(n,k) = C(n,n-k) if necessary, and then evaluating the following
+product simply from i=2 to i=k.
+
+ k (n-k+i)
+ C(n,k) = (n-k+1) * prod -------
+ i=2 i
+
+ It's easy to show that each denominator i will divide the product so
+far, so the exact division algorithm is used (*note Exact Division::).
+
+ The numerators n-k+i and denominators i are first accumulated into
+as many fit a limb, to save multi-precision operations, though for
+`mpz_bin_ui' this applies only to the divisors, since n is an `mpz_t'
+and n-k+i in general won't fit in a limb at all.
+
+
+File: gmp.info, Node: Fibonacci Numbers Algorithm, Next: Lucas Numbers Algorithm, Prev: Binomial Coefficients Algorithm, Up: Other Algorithms
+
+15.7.4 Fibonacci Numbers
+------------------------
+
+The Fibonacci functions `mpz_fib_ui' and `mpz_fib2_ui' are designed for
+calculating isolated F[n] or F[n],F[n-1] values efficiently.
+
+ For small n, a table of single limb values in `__gmp_fib_table' is
+used. On a 32-bit limb this goes up to F[47], or on a 64-bit limb up
+to F[93]. For convenience the table starts at F[-1].
+
+ Beyond the table, values are generated with a binary powering
+algorithm, calculating a pair F[n] and F[n-1] working from high to low
+across the bits of n. The formulas used are
+
+ F[2k+1] = 4*F[k]^2 - F[k-1]^2 + 2*(-1)^k
+ F[2k-1] = F[k]^2 + F[k-1]^2
+
+ F[2k] = F[2k+1] - F[2k-1]
+
+ At each step, k is the high b bits of n. If the next bit of n is 0
+then F[2k],F[2k-1] is used, or if it's a 1 then F[2k+1],F[2k] is used,
+and the process repeated until all bits of n are incorporated. Notice
+these formulas require just two squares per bit of n.
+
+ It'd be possible to handle the first few n above the single limb
+table with simple additions, using the defining Fibonacci recurrence
+F[k+1]=F[k]+F[k-1], but this is not done since it usually turns out to
+be faster for only about 10 or 20 values of n, and including a block of
+code for just those doesn't seem worthwhile. If they really mattered
+it'd be better to extend the data table.
+
+ Using a table avoids lots of calculations on small numbers, and
+makes small n go fast. A bigger table would make more small n go fast,
+it's just a question of balancing size against desired speed. For GMP
+the code is kept compact, with the emphasis primarily on a good
+powering algorithm.
+
+ `mpz_fib2_ui' returns both F[n] and F[n-1], but `mpz_fib_ui' is only
+interested in F[n]. In this case the last step of the algorithm can
+become one multiply instead of two squares. One of the following two
+formulas is used, according as n is odd or even.
+
+ F[2k] = F[k]*(F[k]+2F[k-1])
+
+ F[2k+1] = (2F[k]+F[k-1])*(2F[k]-F[k-1]) + 2*(-1)^k
+
+ F[2k+1] here is the same as above, just rearranged to be a multiply.
+For interest, the 2*(-1)^k term both here and above can be applied just
+to the low limb of the calculation, without a carry or borrow into
+further limbs, which saves some code size. See comments with
+`mpz_fib_ui' and the internal `mpn_fib2_ui' for how this is done.
+
+
+File: gmp.info, Node: Lucas Numbers Algorithm, Next: Random Number Algorithms, Prev: Fibonacci Numbers Algorithm, Up: Other Algorithms
+
+15.7.5 Lucas Numbers
+--------------------
+
+`mpz_lucnum2_ui' derives a pair of Lucas numbers from a pair of
+Fibonacci numbers with the following simple formulas.
+
+ L[k] = F[k] + 2*F[k-1]
+ L[k-1] = 2*F[k] - F[k-1]
+
+ `mpz_lucnum_ui' is only interested in L[n], and some work can be
+saved. Trailing zero bits on n can be handled with a single square
+each.
+
+ L[2k] = L[k]^2 - 2*(-1)^k
+
+ And the lowest 1 bit can be handled with one multiply of a pair of
+Fibonacci numbers, similar to what `mpz_fib_ui' does.
+
+ L[2k+1] = 5*F[k-1]*(2*F[k]+F[k-1]) - 4*(-1)^k
+
+
+File: gmp.info, Node: Random Number Algorithms, Prev: Lucas Numbers Algorithm, Up: Other Algorithms
+
+15.7.6 Random Numbers
+---------------------
+
+For the `urandomb' functions, random numbers are generated simply by
+concatenating bits produced by the generator. As long as the generator
+has good randomness properties this will produce well-distributed N bit
+numbers.
+
+ For the `urandomm' functions, random numbers in a range 0<=R<N are
+generated by taking values R of ceil(log2(N)) bits each until one
+satisfies R<N. This will normally require only one or two attempts,
+but the attempts are limited in case the generator is somehow
+degenerate and produces only 1 bits or similar.
+
+ The Mersenne Twister generator is by Matsumoto and Nishimura (*note
+References::). It has a non-repeating period of 2^19937-1, which is a
+Mersenne prime, hence the name of the generator. The state is 624
+words of 32-bits each, which is iterated with one XOR and shift for each
+32-bit word generated, making the algorithm very fast. Randomness
+properties are also very good and this is the default algorithm used by
+GMP.
+
+ Linear congruential generators are described in many text books, for
+instance Knuth volume 2 (*note References::). With a modulus M and
+parameters A and C, an integer state S is iterated by the formula S <-
+A*S+C mod M. At each step the new state is a linear function of the
+previous, mod M, hence the name of the generator.
+
+ In GMP only moduli of the form 2^N are supported, and the current
+implementation is not as well optimized as it could be. Overheads are
+significant when N is small, and when N is large clearly the multiply
+at each step will become slow. This is not a big concern, since the
+Mersenne Twister generator is better in every respect and is therefore
+recommended for all normal applications.
+
+ For both generators the current state can be deduced by observing
+enough output and applying some linear algebra (over GF(2) in the case
+of the Mersenne Twister). This generally means raw output is
+unsuitable for cryptographic applications without further hashing or
+the like.
+
+
+File: gmp.info, Node: Assembly Coding, Prev: Other Algorithms, Up: Algorithms
+
+15.8 Assembly Coding
+====================
+
+The assembly subroutines in GMP are the most significant source of
+speed at small to moderate sizes. At larger sizes algorithm selection
+becomes more important, but of course speedups in low level routines
+will still speed up everything proportionally.
+
+ Carry handling and widening multiplies that are important for GMP
+can't be easily expressed in C. GCC `asm' blocks help a lot and are
+provided in `longlong.h', but hand coding low level routines invariably
+offers a speedup over generic C by a factor of anything from 2 to 10.
+
+* Menu:
+
+* Assembly Code Organisation::
+* Assembly Basics::
+* Assembly Carry Propagation::
+* Assembly Cache Handling::
+* Assembly Functional Units::
+* Assembly Floating Point::
+* Assembly SIMD Instructions::
+* Assembly Software Pipelining::
+* Assembly Loop Unrolling::
+* Assembly Writing Guide::
+
+
+File: gmp.info, Node: Assembly Code Organisation, Next: Assembly Basics, Prev: Assembly Coding, Up: Assembly Coding
+
+15.8.1 Code Organisation
+------------------------
+
+The various `mpn' subdirectories contain machine-dependent code, written
+in C or assembly. The `mpn/generic' subdirectory contains default code,
+used when there's no machine-specific version of a particular file.
+
+ Each `mpn' subdirectory is for an ISA family. Generally 32-bit and
+64-bit variants in a family cannot share code and have separate
+directories. Within a family further subdirectories may exist for CPU
+variants.
+
+ In each directory a `nails' subdirectory may exist, holding code with
+nails support for that CPU variant. A `NAILS_SUPPORT' directive in each
+file indicates the nails values the code handles. Nails code only
+exists where it's faster, or promises to be faster, than plain code.
+There's no effort put into nails if they're not going to enhance a
+given CPU.
+
+
+File: gmp.info, Node: Assembly Basics, Next: Assembly Carry Propagation, Prev: Assembly Code Organisation, Up: Assembly Coding
+
+15.8.2 Assembly Basics
+----------------------
+
+`mpn_addmul_1' and `mpn_submul_1' are the most important routines for
+overall GMP performance. All multiplications and divisions come down to
+repeated calls to these. `mpn_add_n', `mpn_sub_n', `mpn_lshift' and
+`mpn_rshift' are next most important.
+
+ On some CPUs assembly versions of the internal functions
+`mpn_mul_basecase' and `mpn_sqr_basecase' give significant speedups,
+mainly through avoiding function call overheads. They can also
+potentially make better use of a wide superscalar processor, as can
+bigger primitives like `mpn_addmul_2' or `mpn_addmul_4'.
+
+ The restrictions on overlaps between sources and destinations (*note
+Low-level Functions::) are designed to facilitate a variety of
+implementations. For example, knowing `mpn_add_n' won't have partly
+overlapping sources and destination means reading can be done far ahead
+of writing on superscalar processors, and loops can be vectorized on a
+vector processor, depending on the carry handling.
+
+
+File: gmp.info, Node: Assembly Carry Propagation, Next: Assembly Cache Handling, Prev: Assembly Basics, Up: Assembly Coding
+
+15.8.3 Carry Propagation
+------------------------
+
+The problem that presents most challenges in GMP is propagating carries
+from one limb to the next. In functions like `mpn_addmul_1' and
+`mpn_add_n', carries are the only dependencies between limb operations.
+
+ On processors with carry flags, a straightforward CISC style `adc' is
+generally best. AMD K6 `mpn_addmul_1' however is an example of an
+unusual set of circumstances where a branch works out better.
+
+ On RISC processors generally an add and compare for overflow is
+used. This sort of thing can be seen in `mpn/generic/aors_n.c'. Some
+carry propagation schemes require 4 instructions, meaning at least 4
+cycles per limb, but other schemes may use just 1 or 2. On wide
+superscalar processors performance may be completely determined by the
+number of dependent instructions between carry-in and carry-out for
+each limb.
+
+ On vector processors good use can be made of the fact that a carry
+bit only very rarely propagates more than one limb. When adding a
+single bit to a limb, there's only a carry out if that limb was
+`0xFF...FF' which on random data will be only 1 in 2^mp_bits_per_limb.
+`mpn/cray/add_n.c' is an example of this, it adds all limbs in
+parallel, adds one set of carry bits in parallel and then only rarely
+needs to fall through to a loop propagating further carries.
+
+ On the x86s, GCC (as of version 2.95.2) doesn't generate
+particularly good code for the RISC style idioms that are necessary to
+handle carry bits in C. Often conditional jumps are generated where
+`adc' or `sbb' forms would be better. And so unfortunately almost any
+loop involving carry bits needs to be coded in assembly for best
+results.
+
+
+File: gmp.info, Node: Assembly Cache Handling, Next: Assembly Functional Units, Prev: Assembly Carry Propagation, Up: Assembly Coding
+
+15.8.4 Cache Handling
+---------------------
+
+GMP aims to perform well both on operands that fit entirely in L1 cache
+and those which don't.
+
+ Basic routines like `mpn_add_n' or `mpn_lshift' are often used on
+large operands, so L2 and main memory performance is important for them.
+`mpn_mul_1' and `mpn_addmul_1' are mostly used for multiply and square
+basecases, so L1 performance matters most for them, unless assembly
+versions of `mpn_mul_basecase' and `mpn_sqr_basecase' exist, in which
+case the remaining uses are mostly for larger operands.
+
+ For L2 or main memory operands, memory access times will almost
+certainly be more than the calculation time. The aim therefore is to
+maximize memory throughput, by starting a load of the next cache line
+while processing the contents of the previous one. Clearly this is
+only possible if the chip has a lock-up free cache or some sort of
+prefetch instruction. Most current chips have both these features.
+
+ Prefetching sources combines well with loop unrolling, since a
+prefetch can be initiated once per unrolled loop (or more than once if
+the loop covers more than one cache line).
+
+ On CPUs without write-allocate caches, prefetching destinations will
+ensure individual stores don't go further down the cache hierarchy,
+limiting bandwidth. Of course for calculations which are slow anyway,
+like `mpn_divrem_1', write-throughs might be fine.
+
+ The distance ahead to prefetch will be determined by memory latency
+versus throughput. The aim of course is to have data arriving
+continuously, at peak throughput. Some CPUs have limits on the number
+of fetches or prefetches in progress.
+
+ If a special prefetch instruction doesn't exist then a plain load
+can be used, but in that case care must be taken not to attempt to read
+past the end of an operand, since that might produce a segmentation
+violation.
+
+ Some CPUs or systems have hardware that detects sequential memory
+accesses and initiates suitable cache movements automatically, making
+life easy.
+
+
+File: gmp.info, Node: Assembly Functional Units, Next: Assembly Floating Point, Prev: Assembly Cache Handling, Up: Assembly Coding
+
+15.8.5 Functional Units
+-----------------------
+
+When choosing an approach for an assembly loop, consideration is given
+to what operations can execute simultaneously and what throughput can
+thereby be achieved. In some cases an algorithm can be tweaked to
+accommodate available resources.
+
+ Loop control will generally require a counter and pointer updates,
+costing as much as 5 instructions, plus any delays a branch introduces.
+CPU addressing modes might reduce pointer updates, perhaps by allowing
+just one updating pointer and others expressed as offsets from it, or
+on CISC chips with all addressing done with the loop counter as a
+scaled index.
+
+ The final loop control cost can be amortised by processing several
+limbs in each iteration (*note Assembly Loop Unrolling::). This at
+least ensures loop control isn't a big fraction the work done.
+
+ Memory throughput is always a limit. If perhaps only one load or
+one store can be done per cycle then 3 cycles/limb will the top speed
+for "binary" operations like `mpn_add_n', and any code achieving that
+is optimal.
+
+ Integer resources can be freed up by having the loop counter in a
+float register, or by pressing the float units into use for some
+multiplying, perhaps doing every second limb on the float side (*note
+Assembly Floating Point::).
+
+ Float resources can be freed up by doing carry propagation on the
+integer side, or even by doing integer to float conversions in integers
+using bit twiddling.
+
+
+File: gmp.info, Node: Assembly Floating Point, Next: Assembly SIMD Instructions, Prev: Assembly Functional Units, Up: Assembly Coding
+
+15.8.6 Floating Point
+---------------------
+
+Floating point arithmetic is used in GMP for multiplications on CPUs
+with poor integer multipliers. It's mostly useful for `mpn_mul_1',
+`mpn_addmul_1' and `mpn_submul_1' on 64-bit machines, and
+`mpn_mul_basecase' on both 32-bit and 64-bit machines.
+
+ With IEEE 53-bit double precision floats, integer multiplications
+producing up to 53 bits will give exact results. Breaking a 64x64
+multiplication into eight 16x32->48 bit pieces is convenient. With
+some care though six 21x32->53 bit products can be used, if one of the
+lower two 21-bit pieces also uses the sign bit.
+
+ For the `mpn_mul_1' family of functions on a 64-bit machine, the
+invariant single limb is split at the start, into 3 or 4 pieces.
+Inside the loop, the bignum operand is split into 32-bit pieces. Fast
+conversion of these unsigned 32-bit pieces to floating point is highly
+machine-dependent. In some cases, reading the data into the integer
+unit, zero-extending to 64-bits, then transferring to the floating
+point unit back via memory is the only option.
+
+ Converting partial products back to 64-bit limbs is usually best
+done as a signed conversion. Since all values are smaller than 2^53,
+signed and unsigned are the same, but most processors lack unsigned
+conversions.
+
+
+
+ Here is a diagram showing 16x32 bit products for an `mpn_mul_1' or
+`mpn_addmul_1' with a 64-bit limb. The single limb operand V is split
+into four 16-bit parts. The multi-limb operand U is split in the loop
+into two 32-bit parts.
+
+ +---+---+---+---+
+ |v48|v32|v16|v00| V operand
+ +---+---+---+---+
+
+ +-------+---+---+
+ x | u32 | u00 | U operand (one limb)
+ +---------------+
+
+ ---------------------------------
+
+ +-----------+
+ | u00 x v00 | p00 48-bit products
+ +-----------+
+ +-----------+
+ | u00 x v16 | p16
+ +-----------+
+ +-----------+
+ | u00 x v32 | p32
+ +-----------+
+ +-----------+
+ | u00 x v48 | p48
+ +-----------+
+ +-----------+
+ | u32 x v00 | r32
+ +-----------+
+ +-----------+
+ | u32 x v16 | r48
+ +-----------+
+ +-----------+
+ | u32 x v32 | r64
+ +-----------+
+ +-----------+
+ | u32 x v48 | r80
+ +-----------+
+
+ p32 and r32 can be summed using floating-point addition, and
+likewise p48 and r48. p00 and p16 can be summed with r64 and r80 from
+the previous iteration.
+
+ For each loop then, four 49-bit quantities are transferred to the
+integer unit, aligned as follows,
+
+ |-----64bits----|-----64bits----|
+ +------------+
+ | p00 + r64' | i00
+ +------------+
+ +------------+
+ | p16 + r80' | i16
+ +------------+
+ +------------+
+ | p32 + r32 | i32
+ +------------+
+ +------------+
+ | p48 + r48 | i48
+ +------------+
+
+ The challenge then is to sum these efficiently and add in a carry
+limb, generating a low 64-bit result limb and a high 33-bit carry limb
+(i48 extends 33 bits into the high half).
+
+
+File: gmp.info, Node: Assembly SIMD Instructions, Next: Assembly Software Pipelining, Prev: Assembly Floating Point, Up: Assembly Coding
+
+15.8.7 SIMD Instructions
+------------------------
+
+The single-instruction multiple-data support in current microprocessors
+is aimed at signal processing algorithms where each data point can be
+treated more or less independently. There's generally not much support
+for propagating the sort of carries that arise in GMP.
+
+ SIMD multiplications of say four 16x16 bit multiplies only do as much
+work as one 32x32 from GMP's point of view, and need some shifts and
+adds besides. But of course if say the SIMD form is fully pipelined
+and uses less instruction decoding then it may still be worthwhile.
+
+ On the x86 chips, MMX has so far found a use in `mpn_rshift' and
+`mpn_lshift', and is used in a special case for 16-bit multipliers in
+the P55 `mpn_mul_1'. SSE2 is used for Pentium 4 `mpn_mul_1',
+`mpn_addmul_1', and `mpn_submul_1'.
+
+
+File: gmp.info, Node: Assembly Software Pipelining, Next: Assembly Loop Unrolling, Prev: Assembly SIMD Instructions, Up: Assembly Coding
+
+15.8.8 Software Pipelining
+--------------------------
+
+Software pipelining consists of scheduling instructions around the
+branch point in a loop. For example a loop might issue a load not for
+use in the present iteration but the next, thereby allowing extra
+cycles for the data to arrive from memory.
+
+ Naturally this is wanted only when doing things like loads or
+multiplies that take several cycles to complete, and only where a CPU
+has multiple functional units so that other work can be done in the
+meantime.
+
+ A pipeline with several stages will have a data value in progress at
+each stage and each loop iteration moves them along one stage. This is
+like juggling.
+
+ If the latency of some instruction is greater than the loop time
+then it will be necessary to unroll, so one register has a result ready
+to use while another (or multiple others) are still in progress.
+(*note Assembly Loop Unrolling::).
+
+
+File: gmp.info, Node: Assembly Loop Unrolling, Next: Assembly Writing Guide, Prev: Assembly Software Pipelining, Up: Assembly Coding
+
+15.8.9 Loop Unrolling
+---------------------
+
+Loop unrolling consists of replicating code so that several limbs are
+processed in each loop. At a minimum this reduces loop overheads by a
+corresponding factor, but it can also allow better register usage, for
+example alternately using one register combination and then another.
+Judicious use of `m4' macros can help avoid lots of duplication in the
+source code.
+
+ Any amount of unrolling can be handled with a loop counter that's
+decremented by N each time, stopping when the remaining count is less
+than the further N the loop will process. Or by subtracting N at the
+start, the termination condition becomes when the counter C is less
+than 0 (and the count of remaining limbs is C+N).
+
+ Alternately for a power of 2 unroll the loop count and remainder can
+be established with a shift and mask. This is convenient if also
+making a computed jump into the middle of a large loop.
+
+ The limbs not a multiple of the unrolling can be handled in various
+ways, for example
+
+ * A simple loop at the end (or the start) to process the excess.
+ Care will be wanted that it isn't too much slower than the
+ unrolled part.
+
+ * A set of binary tests, for example after an 8-limb unrolling, test
+ for 4 more limbs to process, then a further 2 more or not, and
+ finally 1 more or not. This will probably take more code space
+ than a simple loop.
+
+ * A `switch' statement, providing separate code for each possible
+ excess, for example an 8-limb unrolling would have separate code
+ for 0 remaining, 1 remaining, etc, up to 7 remaining. This might
+ take a lot of code, but may be the best way to optimize all cases
+ in combination with a deep pipelined loop.
+
+ * A computed jump into the middle of the loop, thus making the first
+ iteration handle the excess. This should make times smoothly
+ increase with size, which is attractive, but setups for the jump
+ and adjustments for pointers can be tricky and could become quite
+ difficult in combination with deep pipelining.
+
+
+File: gmp.info, Node: Assembly Writing Guide, Prev: Assembly Loop Unrolling, Up: Assembly Coding
+
+15.8.10 Writing Guide
+---------------------
+
+This is a guide to writing software pipelined loops for processing limb
+vectors in assembly.
+
+ First determine the algorithm and which instructions are needed.
+Code it without unrolling or scheduling, to make sure it works. On a
+3-operand CPU try to write each new value to a new register, this will
+greatly simplify later steps.
+
+ Then note for each instruction the functional unit and/or issue port
+requirements. If an instruction can use either of two units, like U0
+or U1 then make a category "U0/U1". Count the total using each unit
+(or combined unit), and count all instructions.
+
+ Figure out from those counts the best possible loop time. The goal
+will be to find a perfect schedule where instruction latencies are
+completely hidden. The total instruction count might be the limiting
+factor, or perhaps a particular functional unit. It might be possible
+to tweak the instructions to help the limiting factor.
+
+ Suppose the loop time is N, then make N issue buckets, with the
+final loop branch at the end of the last. Now fill the buckets with
+dummy instructions using the functional units desired. Run this to
+make sure the intended speed is reached.
+
+ Now replace the dummy instructions with the real instructions from
+the slow but correct loop you started with. The first will typically
+be a load instruction. Then the instruction using that value is placed
+in a bucket an appropriate distance down. Run the loop again, to check
+it still runs at target speed.
+
+ Keep placing instructions, frequently measuring the loop. After a
+few you will need to wrap around from the last bucket back to the top
+of the loop. If you used the new-register for new-value strategy above
+then there will be no register conflicts. If not then take care not to
+clobber something already in use. Changing registers at this time is
+very error prone.
+
+ The loop will overlap two or more of the original loop iterations,
+and the computation of one vector element result will be started in one
+iteration of the new loop, and completed one or several iterations
+later.
+
+ The final step is to create feed-in and wind-down code for the loop.
+A good way to do this is to make a copy (or copies) of the loop at the
+start and delete those instructions which don't have valid antecedents,
+and at the end replicate and delete those whose results are unwanted
+(including any further loads).
+
+ The loop will have a minimum number of limbs loaded and processed,
+so the feed-in code must test if the request size is smaller and skip
+either to a suitable part of the wind-down or to special code for small
+sizes.
+
+
+File: gmp.info, Node: Internals, Next: Contributors, Prev: Algorithms, Up: Top
+
+16 Internals
+************
+
+*This chapter is provided only for informational purposes and the
+various internals described here may change in future GMP releases.
+Applications expecting to be compatible with future releases should use
+only the documented interfaces described in previous chapters.*
+
+* Menu:
+
+* Integer Internals::
+* Rational Internals::
+* Float Internals::
+* Raw Output Internals::
+* C++ Interface Internals::
+
+
+File: gmp.info, Node: Integer Internals, Next: Rational Internals, Prev: Internals, Up: Internals
+
+16.1 Integer Internals
+======================
+
+`mpz_t' variables represent integers using sign and magnitude, in space
+dynamically allocated and reallocated. The fields are as follows.
+
+`_mp_size'
+ The number of limbs, or the negative of that when representing a
+ negative integer. Zero is represented by `_mp_size' set to zero,
+ in which case the `_mp_d' data is unused.
+
+`_mp_d'
+ A pointer to an array of limbs which is the magnitude. These are
+ stored "little endian" as per the `mpn' functions, so `_mp_d[0]'
+ is the least significant limb and `_mp_d[ABS(_mp_size)-1]' is the
+ most significant. Whenever `_mp_size' is non-zero, the most
+ significant limb is non-zero.
+
+ Currently there's always at least one limb allocated, so for
+ instance `mpz_set_ui' never needs to reallocate, and `mpz_get_ui'
+ can fetch `_mp_d[0]' unconditionally (though its value is then
+ only wanted if `_mp_size' is non-zero).
+
+`_mp_alloc'
+ `_mp_alloc' is the number of limbs currently allocated at `_mp_d',
+ and naturally `_mp_alloc >= ABS(_mp_size)'. When an `mpz' routine
+ is about to (or might be about to) increase `_mp_size', it checks
+ `_mp_alloc' to see whether there's enough space, and reallocates
+ if not. `MPZ_REALLOC' is generally used for this.
+
+ The various bitwise logical functions like `mpz_and' behave as if
+negative values were twos complement. But sign and magnitude is always
+used internally, and necessary adjustments are made during the
+calculations. Sometimes this isn't pretty, but sign and magnitude are
+best for other routines.
+
+ Some internal temporary variables are setup with `MPZ_TMP_INIT' and
+these have `_mp_d' space obtained from `TMP_ALLOC' rather than the
+memory allocation functions. Care is taken to ensure that these are
+big enough that no reallocation is necessary (since it would have
+unpredictable consequences).
+
+ `_mp_size' and `_mp_alloc' are `int', although `mp_size_t' is
+usually a `long'. This is done to make the fields just 32 bits on some
+64 bits systems, thereby saving a few bytes of data space but still
+providing plenty of range.
+
+
+File: gmp.info, Node: Rational Internals, Next: Float Internals, Prev: Integer Internals, Up: Internals
+
+16.2 Rational Internals
+=======================
+
+`mpq_t' variables represent rationals using an `mpz_t' numerator and
+denominator (*note Integer Internals::).
+
+ The canonical form adopted is denominator positive (and non-zero),
+no common factors between numerator and denominator, and zero uniquely
+represented as 0/1.
+
+ It's believed that casting out common factors at each stage of a
+calculation is best in general. A GCD is an O(N^2) operation so it's
+better to do a few small ones immediately than to delay and have to do
+a big one later. Knowing the numerator and denominator have no common
+factors can be used for example in `mpq_mul' to make only two cross
+GCDs necessary, not four.
+
+ This general approach to common factors is badly sub-optimal in the
+presence of simple factorizations or little prospect for cancellation,
+but GMP has no way to know when this will occur. As per *note
+Efficiency::, that's left to applications. The `mpq_t' framework might
+still suit, with `mpq_numref' and `mpq_denref' for direct access to the
+numerator and denominator, or of course `mpz_t' variables can be used
+directly.
+
+
+File: gmp.info, Node: Float Internals, Next: Raw Output Internals, Prev: Rational Internals, Up: Internals
+
+16.3 Float Internals
+====================
+
+Efficient calculation is the primary aim of GMP floats and the use of
+whole limbs and simple rounding facilitates this.
+
+ `mpf_t' floats have a variable precision mantissa and a single
+machine word signed exponent. The mantissa is represented using sign
+and magnitude.
+
+ most least
+ significant significant
+ limb limb
+
+ _mp_d
+ |---- _mp_exp ---> |
+ _____ _____ _____ _____ _____
+ |_____|_____|_____|_____|_____|
+ . <------------ radix point
+
+ <-------- _mp_size --------->
+
+The fields are as follows.
+
+`_mp_size'
+ The number of limbs currently in use, or the negative of that when
+ representing a negative value. Zero is represented by `_mp_size'
+ and `_mp_exp' both set to zero, and in that case the `_mp_d' data
+ is unused. (In the future `_mp_exp' might be undefined when
+ representing zero.)
+
+`_mp_prec'
+ The precision of the mantissa, in limbs. In any calculation the
+ aim is to produce `_mp_prec' limbs of result (the most significant
+ being non-zero).
+
+`_mp_d'
+ A pointer to the array of limbs which is the absolute value of the
+ mantissa. These are stored "little endian" as per the `mpn'
+ functions, so `_mp_d[0]' is the least significant limb and
+ `_mp_d[ABS(_mp_size)-1]' the most significant.
+
+ The most significant limb is always non-zero, but there are no
+ other restrictions on its value, in particular the highest 1 bit
+ can be anywhere within the limb.
+
+ `_mp_prec+1' limbs are allocated to `_mp_d', the extra limb being
+ for convenience (see below). There are no reallocations during a
+ calculation, only in a change of precision with `mpf_set_prec'.
+
+`_mp_exp'
+ The exponent, in limbs, determining the location of the implied
+ radix point. Zero means the radix point is just above the most
+ significant limb. Positive values mean a radix point offset
+ towards the lower limbs and hence a value >= 1, as for example in
+ the diagram above. Negative exponents mean a radix point further
+ above the highest limb.
+
+ Naturally the exponent can be any value, it doesn't have to fall
+ within the limbs as the diagram shows, it can be a long way above
+ or a long way below. Limbs other than those included in the
+ `{_mp_d,_mp_size}' data are treated as zero.
+
+ The `_mp_size' and `_mp_prec' fields are `int', although the
+`mp_size_t' type is usually a `long'. The `_mp_exp' field is usually
+`long'. This is done to make some fields just 32 bits on some 64 bits
+systems, thereby saving a few bytes of data space but still providing
+plenty of precision and a very large range.
+
+
+The following various points should be noted.
+
+Low Zeros
+ The least significant limbs `_mp_d[0]' etc can be zero, though
+ such low zeros can always be ignored. Routines likely to produce
+ low zeros check and avoid them to save time in subsequent
+ calculations, but for most routines they're quite unlikely and
+ aren't checked.
+
+Mantissa Size Range
+ The `_mp_size' count of limbs in use can be less than `_mp_prec' if
+ the value can be represented in less. This means low precision
+ values or small integers stored in a high precision `mpf_t' can
+ still be operated on efficiently.
+
+ `_mp_size' can also be greater than `_mp_prec'. Firstly a value is
+ allowed to use all of the `_mp_prec+1' limbs available at `_mp_d',
+ and secondly when `mpf_set_prec_raw' lowers `_mp_prec' it leaves
+ `_mp_size' unchanged and so the size can be arbitrarily bigger than
+ `_mp_prec'.
+
+Rounding
+ All rounding is done on limb boundaries. Calculating `_mp_prec'
+ limbs with the high non-zero will ensure the application requested
+ minimum precision is obtained.
+
+ The use of simple "trunc" rounding towards zero is efficient,
+ since there's no need to examine extra limbs and increment or
+ decrement.
+
+Bit Shifts
+ Since the exponent is in limbs, there are no bit shifts in basic
+ operations like `mpf_add' and `mpf_mul'. When differing exponents
+ are encountered all that's needed is to adjust pointers to line up
+ the relevant limbs.
+
+ Of course `mpf_mul_2exp' and `mpf_div_2exp' will require bit
+ shifts, but the choice is between an exponent in limbs which
+ requires shifts there, or one in bits which requires them almost
+ everywhere else.
+
+Use of `_mp_prec+1' Limbs
+ The extra limb on `_mp_d' (`_mp_prec+1' rather than just
+ `_mp_prec') helps when an `mpf' routine might get a carry from its
+ operation. `mpf_add' for instance will do an `mpn_add' of
+ `_mp_prec' limbs. If there's no carry then that's the result, but
+ if there is a carry then it's stored in the extra limb of space and
+ `_mp_size' becomes `_mp_prec+1'.
+
+ Whenever `_mp_prec+1' limbs are held in a variable, the low limb
+ is not needed for the intended precision, only the `_mp_prec' high
+ limbs. But zeroing it out or moving the rest down is unnecessary.
+ Subsequent routines reading the value will simply take the high
+ limbs they need, and this will be `_mp_prec' if their target has
+ that same precision. This is no more than a pointer adjustment,
+ and must be checked anyway since the destination precision can be
+ different from the sources.
+
+ Copy functions like `mpf_set' will retain a full `_mp_prec+1' limbs
+ if available. This ensures that a variable which has `_mp_size'
+ equal to `_mp_prec+1' will get its full exact value copied.
+ Strictly speaking this is unnecessary since only `_mp_prec' limbs
+ are needed for the application's requested precision, but it's
+ considered that an `mpf_set' from one variable into another of the
+ same precision ought to produce an exact copy.
+
+Application Precisions
+ `__GMPF_BITS_TO_PREC' converts an application requested precision
+ to an `_mp_prec'. The value in bits is rounded up to a whole limb
+ then an extra limb is added since the most significant limb of
+ `_mp_d' is only non-zero and therefore might contain only one bit.
+
+ `__GMPF_PREC_TO_BITS' does the reverse conversion, and removes the
+ extra limb from `_mp_prec' before converting to bits. The net
+ effect of reading back with `mpf_get_prec' is simply the precision
+ rounded up to a multiple of `mp_bits_per_limb'.
+
+ Note that the extra limb added here for the high only being
+ non-zero is in addition to the extra limb allocated to `_mp_d'.
+ For example with a 32-bit limb, an application request for 250
+ bits will be rounded up to 8 limbs, then an extra added for the
+ high being only non-zero, giving an `_mp_prec' of 9. `_mp_d' then
+ gets 10 limbs allocated. Reading back with `mpf_get_prec' will
+ take `_mp_prec' subtract 1 limb and multiply by 32, giving 256
+ bits.
+
+ Strictly speaking, the fact the high limb has at least one bit
+ means that a float with, say, 3 limbs of 32-bits each will be
+ holding at least 65 bits, but for the purposes of `mpf_t' it's
+ considered simply to be 64 bits, a nice multiple of the limb size.
+
+
+File: gmp.info, Node: Raw Output Internals, Next: C++ Interface Internals, Prev: Float Internals, Up: Internals
+
+16.4 Raw Output Internals
+=========================
+
+`mpz_out_raw' uses the following format.
+
+ +------+------------------------+
+ | size | data bytes |
+ +------+------------------------+
+
+ The size is 4 bytes written most significant byte first, being the
+number of subsequent data bytes, or the twos complement negative of
+that when a negative integer is represented. The data bytes are the
+absolute value of the integer, written most significant byte first.
+
+ The most significant data byte is always non-zero, so the output is
+the same on all systems, irrespective of limb size.
+
+ In GMP 1, leading zero bytes were written to pad the data bytes to a
+multiple of the limb size. `mpz_inp_raw' will still accept this, for
+compatibility.
+
+ The use of "big endian" for both the size and data fields is
+deliberate, it makes the data easy to read in a hex dump of a file.
+Unfortunately it also means that the limb data must be reversed when
+reading or writing, so neither a big endian nor little endian system
+can just read and write `_mp_d'.
+
+
+File: gmp.info, Node: C++ Interface Internals, Prev: Raw Output Internals, Up: Internals
+
+16.5 C++ Interface Internals
+============================
+
+A system of expression templates is used to ensure something like
+`a=b+c' turns into a simple call to `mpz_add' etc. For `mpf_class' the
+scheme also ensures the precision of the final destination is used for
+any temporaries within a statement like `f=w*x+y*z'. These are
+important features which a naive implementation cannot provide.
+
+ A simplified description of the scheme follows. The true scheme is
+complicated by the fact that expressions have different return types.
+For detailed information, refer to the source code.
+
+ To perform an operation, say, addition, we first define a "function
+object" evaluating it,
+
+ struct __gmp_binary_plus
+ {
+ static void eval(mpf_t f, const mpf_t g, const mpf_t h)
+ {
+ mpf_add(f, g, h);
+ }
+ };
+
+And an "additive expression" object,
+
+ __gmp_expr<__gmp_binary_expr<mpf_class, mpf_class, __gmp_binary_plus> >
+ operator+(const mpf_class &f, const mpf_class &g)
+ {
+ return __gmp_expr
+ <__gmp_binary_expr<mpf_class, mpf_class, __gmp_binary_plus> >(f, g);
+ }
+
+ The seemingly redundant `__gmp_expr<__gmp_binary_expr<...>>' is used
+to encapsulate any possible kind of expression into a single template
+type. In fact even `mpf_class' etc are `typedef' specializations of
+`__gmp_expr'.
+
+ Next we define assignment of `__gmp_expr' to `mpf_class'.
+
+ template <class T>
+ mpf_class & mpf_class::operator=(const __gmp_expr<T> &expr)
+ {
+ expr.eval(this->get_mpf_t(), this->precision());
+ return *this;
+ }
+
+ template <class Op>
+ void __gmp_expr<__gmp_binary_expr<mpf_class, mpf_class, Op> >::eval
+ (mpf_t f, mp_bitcnt_t precision)
+ {
+ Op::eval(f, expr.val1.get_mpf_t(), expr.val2.get_mpf_t());
+ }
+
+ where `expr.val1' and `expr.val2' are references to the expression's
+operands (here `expr' is the `__gmp_binary_expr' stored within the
+`__gmp_expr').
+
+ This way, the expression is actually evaluated only at the time of
+assignment, when the required precision (that of `f') is known.
+Furthermore the target `mpf_t' is now available, thus we can call
+`mpf_add' directly with `f' as the output argument.
+
+ Compound expressions are handled by defining operators taking
+subexpressions as their arguments, like this:
+
+ template <class T, class U>
+ __gmp_expr
+ <__gmp_binary_expr<__gmp_expr<T>, __gmp_expr<U>, __gmp_binary_plus> >
+ operator+(const __gmp_expr<T> &expr1, const __gmp_expr<U> &expr2)
+ {
+ return __gmp_expr
+ <__gmp_binary_expr<__gmp_expr<T>, __gmp_expr<U>, __gmp_binary_plus> >
+ (expr1, expr2);
+ }
+
+ And the corresponding specializations of `__gmp_expr::eval':
+
+ template <class T, class U, class Op>
+ void __gmp_expr
+ <__gmp_binary_expr<__gmp_expr<T>, __gmp_expr<U>, Op> >::eval
+ (mpf_t f, mp_bitcnt_t precision)
+ {
+ // declare two temporaries
+ mpf_class temp1(expr.val1, precision), temp2(expr.val2, precision);
+ Op::eval(f, temp1.get_mpf_t(), temp2.get_mpf_t());
+ }
+
+ The expression is thus recursively evaluated to any level of
+complexity and all subexpressions are evaluated to the precision of `f'.
+
+
+File: gmp.info, Node: Contributors, Next: References, Prev: Internals, Up: Top
+
+Appendix A Contributors
+***********************
+
+Torbjörn Granlund wrote the original GMP library and is still the main
+developer. Code not explicitly attributed to others, was contributed by
+Torbjörn. Several other individuals and organizations have contributed
+GMP. Here is a list in chronological order on first contribution:
+
+ Gunnar Sjödin and Hans Riesel helped with mathematical problems in
+early versions of the library.
+
+ Richard Stallman helped with the interface design and revised the
+first version of this manual.
+
+ Brian Beuning and Doug Lea helped with testing of early versions of
+the library and made creative suggestions.
+
+ John Amanatides of York University in Canada contributed the function
+`mpz_probab_prime_p'.
+
+ Paul Zimmermann wrote the REDC-based mpz_powm code, the
+Schönhage-Strassen FFT multiply code, and the Karatsuba square root
+code. He also improved the Toom3 code for GMP 4.2. Paul sparked the
+development of GMP 2, with his comparisons between bignum packages.
+The ECMNET project Paul is organizing was a driving force behind many
+of the optimizations in GMP 3. Paul also wrote the new GMP 4.3 nth
+root code (with Torbjörn).
+
+ Ken Weber (Kent State University, Universidade Federal do Rio Grande
+do Sul) contributed now defunct versions of `mpz_gcd', `mpz_divexact',
+`mpn_gcd', and `mpn_bdivmod', partially supported by CNPq (Brazil)
+grant 301314194-2.
+
+ Per Bothner of Cygnus Support helped to set up GMP to use Cygnus'
+configure. He has also made valuable suggestions and tested numerous
+intermediary releases.
+
+ Joachim Hollman was involved in the design of the `mpf' interface,
+and in the `mpz' design revisions for version 2.
+
+ Bennet Yee contributed the initial versions of `mpz_jacobi' and
+`mpz_legendre'.
+
+ Andreas Schwab contributed the files `mpn/m68k/lshift.S' and
+`mpn/m68k/rshift.S' (now in `.asm' form).
+
+ Robert Harley of Inria, France and David Seal of ARM, England,
+suggested clever improvements for population count. Robert also wrote
+highly optimized Karatsuba and 3-way Toom multiplication functions for
+GMP 3, and contributed the ARM assembly code.
+
+ Torsten Ekedahl of the Mathematical department of Stockholm
+University provided significant inspiration during several phases of
+the GMP development. His mathematical expertise helped improve several
+algorithms.
+
+ Linus Nordberg wrote the new configure system based on autoconf and
+implemented the new random functions.
+
+ Kevin Ryde worked on a large number of things: optimized x86 code,
+m4 asm macros, parameter tuning, speed measuring, the configure system,
+function inlining, divisibility tests, bit scanning, Jacobi symbols,
+Fibonacci and Lucas number functions, printf and scanf functions, perl
+interface, demo expression parser, the algorithms chapter in the
+manual, `gmpasm-mode.el', and various miscellaneous improvements
+elsewhere.
+
+ Kent Boortz made the Mac OS 9 port.
+
+ Steve Root helped write the optimized alpha 21264 assembly code.
+
+ Gerardo Ballabio wrote the `gmpxx.h' C++ class interface and the C++
+`istream' input routines.
+
+ Jason Moxham rewrote `mpz_fac_ui'.
+
+ Pedro Gimeno implemented the Mersenne Twister and made other random
+number improvements.
+
+ Niels Möller wrote the sub-quadratic GCD, extended GCD and jacobi
+code, the quadratic Hensel division code, and (with Torbjörn) the new
+divide and conquer division code for GMP 4.3. Niels also helped
+implement the new Toom multiply code for GMP 4.3 and implemented helper
+functions to simplify Toom evaluations for GMP 5.0. He wrote the
+original version of mpn_mulmod_bnm1, and he is the main author of the
+mini-gmp package used for gmp bootstrapping.
+
+ Alberto Zanoni and Marco Bodrato suggested the unbalanced multiply
+strategy, and found the optimal strategies for evaluation and
+interpolation in Toom multiplication.
+
+ Marco Bodrato helped implement the new Toom multiply code for GMP
+4.3 and implemented most of the new Toom multiply and squaring code for
+5.0. He is the main author of the current mpn_mulmod_bnm1 and
+mpn_mullo_n. Marco also wrote the functions mpn_invert and
+mpn_invertappr. He is the author of the current combinatorial
+functions: binomial, factorial, multifactorial, primorial.
+
+ David Harvey suggested the internal function `mpn_bdiv_dbm1',
+implementing division relevant to Toom multiplication. He also worked
+on fast assembly sequences, in particular on a fast AMD64
+`mpn_mul_basecase'. He wrote the internal middle product functions
+`mpn_mulmid_basecase', `mpn_toom42_mulmid', `mpn_mulmid_n' and related
+helper routines.
+
+ Martin Boij wrote `mpn_perfect_power_p'.
+
+ Marc Glisse improved `gmpxx.h': use fewer temporaries (faster),
+specializations of `numeric_limits' and `common_type', C++11 features
+(move constructors, explicit bool conversion, UDL), make the conversion
+from `mpq_class' to `mpz_class' explicit, optimize operations where one
+argument is a small compile-time constant, replace some heap
+allocations by stack allocations. He also fixed the eofbit handling of
+C++ streams, and removed one division from `mpq/aors.c'.
+
+ David S Miller wrote assembly code for SPARC T3 and T4.
+
+ Mark Sofroniou cleaned up the types of mul_fft.c, letting it work
+for huge operands.
+
+ Ulrich Weigand ported GMP to the powerpc64le ABI.
+
+ (This list is chronological, not ordered after significance. If you
+have contributed to GMP but are not listed above, please tell
+<gmp-devel@gmplib.org> about the omission!)
+
+ The development of floating point functions of GNU MP 2, were
+supported in part by the ESPRIT-BRA (Basic Research Activities) 6846
+project POSSO (POlynomial System SOlving).
+
+ The development of GMP 2, 3, and 4.0 was supported in part by the
+IDA Center for Computing Sciences.
+
+ The development of GMP 4.3, 5.0, and 5.1 was supported in part by
+the Swedish Foundation for Strategic Research.
+
+ Thanks go to Hans Thorsen for donating an SGI system for the GMP
+test system environment.
+
+
+File: gmp.info, Node: References, Next: GNU Free Documentation License, Prev: Contributors, Up: Top
+
+Appendix B References
+*********************
+
+B.1 Books
+=========
+
+ * Jonathan M. Borwein and Peter B. Borwein, "Pi and the AGM: A Study
+ in Analytic Number Theory and Computational Complexity", Wiley,
+ 1998.
+
+ * Richard Crandall and Carl Pomerance, "Prime Numbers: A
+ Computational Perspective", 2nd edition, Springer-Verlag, 2005.
+ `http://www.math.dartmouth.edu/~carlp/'
+
+ * Henri Cohen, "A Course in Computational Algebraic Number Theory",
+ Graduate Texts in Mathematics number 138, Springer-Verlag, 1993.
+ `http://www.math.u-bordeaux.fr/~cohen/'
+
+ * Donald E. Knuth, "The Art of Computer Programming", volume 2,
+ "Seminumerical Algorithms", 3rd edition, Addison-Wesley, 1998.
+ `http://www-cs-faculty.stanford.edu/~knuth/taocp.html'
+
+ * John D. Lipson, "Elements of Algebra and Algebraic Computing", The
+ Benjamin Cummings Publishing Company Inc, 1981.
+
+ * Alfred J. Menezes, Paul C. van Oorschot and Scott A. Vanstone,
+ "Handbook of Applied Cryptography",
+ `http://www.cacr.math.uwaterloo.ca/hac/'
+
+ * Richard M. Stallman and the GCC Developer Community, "Using the
+ GNU Compiler Collection", Free Software Foundation, 2008,
+ available online `https://gcc.gnu.org/onlinedocs/', and in the GCC
+ package `https://ftp.gnu.org/gnu/gcc/'
+
+B.2 Papers
+==========
+
+ * Yves Bertot, Nicolas Magaud and Paul Zimmermann, "A Proof of GMP
+ Square Root", Journal of Automated Reasoning, volume 29, 2002, pp.
+ 225-252. Also available online as INRIA Research Report 4475,
+ June 2002, `http://hal.inria.fr/docs/00/07/21/13/PDF/RR-4475.pdf'
+
+ * Christoph Burnikel and Joachim Ziegler, "Fast Recursive Division",
+ Max-Planck-Institut fuer Informatik Research Report MPI-I-98-1-022,
+ `http://data.mpi-sb.mpg.de/internet/reports.nsf/NumberView/1998-1-022'
+
+ * Torbjörn Granlund and Peter L. Montgomery, "Division by Invariant
+ Integers using Multiplication", in Proceedings of the SIGPLAN
+ PLDI'94 Conference, June 1994. Also available
+ `https://gmplib.org/~tege/divcnst-pldi94.pdf'.
+
+ * Niels Möller and Torbjörn Granlund, "Improved division by invariant
+ integers", IEEE Transactions on Computers, 11 June 2010.
+ `https://gmplib.org/~tege/division-paper.pdf'
+
+ * Torbjörn Granlund and Niels Möller, "Division of integers large and
+ small", to appear.
+
+ * Tudor Jebelean, "An algorithm for exact division", Journal of
+ Symbolic Computation, volume 15, 1993, pp. 169-180. Research
+ report version available
+ `ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1992/92-35.ps.gz'
+
+ * Tudor Jebelean, "Exact Division with Karatsuba Complexity -
+ Extended Abstract", RISC-Linz technical report 96-31,
+ `ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1996/96-31.ps.gz'
+
+ * Tudor Jebelean, "Practical Integer Division with Karatsuba
+ Complexity", ISSAC 97, pp. 339-341. Technical report available
+ `ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1996/96-29.ps.gz'
+
+ * Tudor Jebelean, "A Generalization of the Binary GCD Algorithm",
+ ISSAC 93, pp. 111-116. Technical report version available
+ `ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1993/93-01.ps.gz'
+
+ * Tudor Jebelean, "A Double-Digit Lehmer-Euclid Algorithm for
+ Finding the GCD of Long Integers", Journal of Symbolic
+ Computation, volume 19, 1995, pp. 145-157. Technical report
+ version also available
+ `ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1992/92-69.ps.gz'
+
+ * Werner Krandick and Tudor Jebelean, "Bidirectional Exact Integer
+ Division", Journal of Symbolic Computation, volume 21, 1996, pp.
+ 441-455. Early technical report version also available
+ `ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1994/94-50.ps.gz'
+
+ * Makoto Matsumoto and Takuji Nishimura, "Mersenne Twister: A
+ 623-dimensionally equidistributed uniform pseudorandom number
+ generator", ACM Transactions on Modelling and Computer Simulation,
+ volume 8, January 1998, pp. 3-30. Available online
+ `http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/mt.ps.gz'
+ (or .pdf)
+
+ * R. Moenck and A. Borodin, "Fast Modular Transforms via Division",
+ Proceedings of the 13th Annual IEEE Symposium on Switching and
+ Automata Theory, October 1972, pp. 90-96. Reprinted as "Fast
+ Modular Transforms", Journal of Computer and System Sciences,
+ volume 8, number 3, June 1974, pp. 366-386.
+
+ * Niels Möller, "On Schönhage's algorithm and subquadratic integer
+ GCD computation", in Mathematics of Computation, volume 77,
+ January 2008, pp. 589-607.
+
+ * Peter L. Montgomery, "Modular Multiplication Without Trial
+ Division", in Mathematics of Computation, volume 44, number 170,
+ April 1985.
+
+ * Arnold Schönhage and Volker Strassen, "Schnelle Multiplikation
+ grosser Zahlen", Computing 7, 1971, pp. 281-292.
+
+ * Kenneth Weber, "The accelerated integer GCD algorithm", ACM
+ Transactions on Mathematical Software, volume 21, number 1, March
+ 1995, pp. 111-122.
+
+ * Paul Zimmermann, "Karatsuba Square Root", INRIA Research Report
+ 3805, November 1999,
+ `http://hal.inria.fr/inria-00072854/PDF/RR-3805.pdf'
+
+ * Paul Zimmermann, "A Proof of GMP Fast Division and Square Root
+ Implementations",
+ `http://www.loria.fr/~zimmerma/papers/proof-div-sqrt.ps.gz'
+
+ * Dan Zuras, "On Squaring and Multiplying Large Integers", ARITH-11:
+ IEEE Symposium on Computer Arithmetic, 1993, pp. 260 to 271.
+ Reprinted as "More on Multiplying and Squaring Large Integers",
+ IEEE Transactions on Computers, volume 43, number 8, August 1994,
+ pp. 899-908.
+
+
+File: gmp.info, Node: GNU Free Documentation License, Next: Concept Index, Prev: References, Up: Top
+
+Appendix C GNU Free Documentation License
+*****************************************
+
+ Version 1.3, 3 November 2008
+
+ Copyright (C) 2000-2002, 2007, 2008 Free Software Foundation, Inc.
+ `http://fsf.org/'
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML or
+ XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ The "publisher" means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of
+ previous versions (which should, if there were any, be listed
+ in the History section of the Document). You may use the
+ same title as a previous version if the original publisher of
+ that version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on
+ the Title Page. If there is no section Entitled "History" in
+ the Document, create one stating the title, year, authors,
+ and publisher of the Document as given on its Title Page,
+ then add an item describing the Modified Version as stated in
+ the previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a
+ work that was published at least four years before the
+ Document itself, or if the original publisher of the version
+ it refers to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the
+ section all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section
+ titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly
+ and finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from
+ you under this License. If your rights have been terminated and
+ not permanently reinstated, receipt of a copy of some or all of
+ the same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ `https://www.gnu.org/copyleft/'.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation. If the Document specifies that a proxy
+ can decide which future versions of this License can be used, that
+ proxy's public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ "Incorporate" means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is "eligible for relicensing" if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+
+File: gmp.info, Node: Concept Index, Next: Function Index, Prev: GNU Free Documentation License, Up: Top
+
+Concept Index
+*************
+
+
+* Menu:
+
+* #include: Headers and Libraries.
+ (line 6)
+* --build: Build Options. (line 52)
+* --disable-fft: Build Options. (line 313)
+* --disable-shared: Build Options. (line 45)
+* --disable-static: Build Options. (line 45)
+* --enable-alloca: Build Options. (line 274)
+* --enable-assert: Build Options. (line 319)
+* --enable-cxx: Build Options. (line 226)
+* --enable-fat: Build Options. (line 161)
+* --enable-profiling <1>: Build Options. (line 323)
+* --enable-profiling: Profiling. (line 6)
+* --exec-prefix: Build Options. (line 32)
+* --host: Build Options. (line 66)
+* --prefix: Build Options. (line 32)
+* -finstrument-functions: Profiling. (line 66)
+* 2exp functions: Efficiency. (line 43)
+* 68000: Notes for Particular Systems.
+ (line 94)
+* 80x86: Notes for Particular Systems.
+ (line 150)
+* ABI <1>: Build Options. (line 168)
+* ABI: ABI and ISA. (line 6)
+* About this manual: Introduction to GMP. (line 57)
+* AC_CHECK_LIB: Autoconf. (line 11)
+* AIX <1>: Notes for Particular Systems.
+ (line 7)
+* AIX: ABI and ISA. (line 178)
+* Algorithms: Algorithms. (line 6)
+* alloca: Build Options. (line 274)
+* Allocation of memory: Custom Allocation. (line 6)
+* AMD64: ABI and ISA. (line 44)
+* Anonymous FTP of latest version: Introduction to GMP. (line 37)
+* Application Binary Interface: ABI and ISA. (line 6)
+* Arithmetic functions <1>: Rational Arithmetic. (line 6)
+* Arithmetic functions <2>: Float Arithmetic. (line 6)
+* Arithmetic functions: Integer Arithmetic. (line 6)
+* ARM: Notes for Particular Systems.
+ (line 20)
+* Assembly cache handling: Assembly Cache Handling.
+ (line 6)
+* Assembly carry propagation: Assembly Carry Propagation.
+ (line 6)
+* Assembly code organisation: Assembly Code Organisation.
+ (line 6)
+* Assembly coding: Assembly Coding. (line 6)
+* Assembly floating Point: Assembly Floating Point.
+ (line 6)
+* Assembly loop unrolling: Assembly Loop Unrolling.
+ (line 6)
+* Assembly SIMD: Assembly SIMD Instructions.
+ (line 6)
+* Assembly software pipelining: Assembly Software Pipelining.
+ (line 6)
+* Assembly writing guide: Assembly Writing Guide.
+ (line 6)
+* Assertion checking <1>: Debugging. (line 79)
+* Assertion checking: Build Options. (line 319)
+* Assignment functions <1>: Assigning Integers. (line 6)
+* Assignment functions <2>: Initializing Rationals.
+ (line 6)
+* Assignment functions <3>: Simultaneous Float Init & Assign.
+ (line 6)
+* Assignment functions <4>: Simultaneous Integer Init & Assign.
+ (line 6)
+* Assignment functions: Assigning Floats. (line 6)
+* Autoconf: Autoconf. (line 6)
+* Basics: GMP Basics. (line 6)
+* Binomial coefficient algorithm: Binomial Coefficients Algorithm.
+ (line 6)
+* Binomial coefficient functions: Number Theoretic Functions.
+ (line 128)
+* Binutils strip: Known Build Problems.
+ (line 28)
+* Bit manipulation functions: Integer Logic and Bit Fiddling.
+ (line 6)
+* Bit scanning functions: Integer Logic and Bit Fiddling.
+ (line 40)
+* Bit shift left: Integer Arithmetic. (line 38)
+* Bit shift right: Integer Division. (line 62)
+* Bits per limb: Useful Macros and Constants.
+ (line 7)
+* Bug reporting: Reporting Bugs. (line 6)
+* Build directory: Build Options. (line 19)
+* Build notes for binary packaging: Notes for Package Builds.
+ (line 6)
+* Build notes for particular systems: Notes for Particular Systems.
+ (line 6)
+* Build options: Build Options. (line 6)
+* Build problems known: Known Build Problems.
+ (line 6)
+* Build system: Build Options. (line 52)
+* Building GMP: Installing GMP. (line 6)
+* Bus error: Debugging. (line 7)
+* C compiler: Build Options. (line 179)
+* C++ compiler: Build Options. (line 250)
+* C++ interface: C++ Class Interface. (line 6)
+* C++ interface internals: C++ Interface Internals.
+ (line 6)
+* C++ istream input: C++ Formatted Input. (line 6)
+* C++ ostream output: C++ Formatted Output.
+ (line 6)
+* C++ support: Build Options. (line 226)
+* CC: Build Options. (line 179)
+* CC_FOR_BUILD: Build Options. (line 213)
+* CFLAGS: Build Options. (line 179)
+* Checker: Debugging. (line 115)
+* checkergcc: Debugging. (line 122)
+* Code organisation: Assembly Code Organisation.
+ (line 6)
+* Compaq C++: Notes for Particular Systems.
+ (line 25)
+* Comparison functions <1>: Integer Comparisons. (line 6)
+* Comparison functions <2>: Float Comparison. (line 6)
+* Comparison functions: Comparing Rationals. (line 6)
+* Compatibility with older versions: Compatibility with older versions.
+ (line 6)
+* Conditions for copying GNU MP: Copying. (line 6)
+* Configuring GMP: Installing GMP. (line 6)
+* Congruence algorithm: Exact Remainder. (line 30)
+* Congruence functions: Integer Division. (line 137)
+* Constants: Useful Macros and Constants.
+ (line 6)
+* Contributors: Contributors. (line 6)
+* Conventions for parameters: Parameter Conventions.
+ (line 6)
+* Conventions for variables: Variable Conventions.
+ (line 6)
+* Conversion functions <1>: Converting Integers. (line 6)
+* Conversion functions <2>: Converting Floats. (line 6)
+* Conversion functions: Rational Conversions.
+ (line 6)
+* Copying conditions: Copying. (line 6)
+* CPPFLAGS: Build Options. (line 205)
+* CPU types <1>: Introduction to GMP. (line 24)
+* CPU types: Build Options. (line 108)
+* Cross compiling: Build Options. (line 66)
+* Cryptography functions, low-level: Low-level Functions. (line 495)
+* Custom allocation: Custom Allocation. (line 6)
+* CXX: Build Options. (line 250)
+* CXXFLAGS: Build Options. (line 250)
+* Cygwin: Notes for Particular Systems.
+ (line 57)
+* Darwin: Known Build Problems.
+ (line 51)
+* Debugging: Debugging. (line 6)
+* Demonstration programs: Demonstration Programs.
+ (line 6)
+* Digits in an integer: Miscellaneous Integer Functions.
+ (line 23)
+* Divisibility algorithm: Exact Remainder. (line 30)
+* Divisibility functions: Integer Division. (line 137)
+* Divisibility testing: Efficiency. (line 91)
+* Division algorithms: Division Algorithms. (line 6)
+* Division functions <1>: Rational Arithmetic. (line 24)
+* Division functions <2>: Integer Division. (line 6)
+* Division functions: Float Arithmetic. (line 33)
+* DJGPP <1>: Notes for Particular Systems.
+ (line 57)
+* DJGPP: Known Build Problems.
+ (line 18)
+* DLLs: Notes for Particular Systems.
+ (line 70)
+* DocBook: Build Options. (line 346)
+* Documentation formats: Build Options. (line 339)
+* Documentation license: GNU Free Documentation License.
+ (line 6)
+* DVI: Build Options. (line 342)
+* Efficiency: Efficiency. (line 6)
+* Emacs: Emacs. (line 6)
+* Exact division functions: Integer Division. (line 112)
+* Exact remainder: Exact Remainder. (line 6)
+* Example programs: Demonstration Programs.
+ (line 6)
+* Exec prefix: Build Options. (line 32)
+* Execution profiling <1>: Build Options. (line 323)
+* Execution profiling: Profiling. (line 6)
+* Exponentiation functions <1>: Float Arithmetic. (line 41)
+* Exponentiation functions: Integer Exponentiation.
+ (line 6)
+* Export: Integer Import and Export.
+ (line 45)
+* Expression parsing demo: Demonstration Programs.
+ (line 15)
+* Extended GCD: Number Theoretic Functions.
+ (line 49)
+* Factor removal functions: Number Theoretic Functions.
+ (line 108)
+* Factorial algorithm: Factorial Algorithm. (line 6)
+* Factorial functions: Number Theoretic Functions.
+ (line 116)
+* Factorization demo: Demonstration Programs.
+ (line 25)
+* Fast Fourier Transform: FFT Multiplication. (line 6)
+* Fat binary: Build Options. (line 161)
+* FFT multiplication <1>: FFT Multiplication. (line 6)
+* FFT multiplication: Build Options. (line 313)
+* Fibonacci number algorithm: Fibonacci Numbers Algorithm.
+ (line 6)
+* Fibonacci sequence functions: Number Theoretic Functions.
+ (line 136)
+* Float arithmetic functions: Float Arithmetic. (line 6)
+* Float assignment functions <1>: Simultaneous Float Init & Assign.
+ (line 6)
+* Float assignment functions: Assigning Floats. (line 6)
+* Float comparison functions: Float Comparison. (line 6)
+* Float conversion functions: Converting Floats. (line 6)
+* Float functions: Floating-point Functions.
+ (line 6)
+* Float initialization functions <1>: Simultaneous Float Init & Assign.
+ (line 6)
+* Float initialization functions: Initializing Floats. (line 6)
+* Float input and output functions: I/O of Floats. (line 6)
+* Float internals: Float Internals. (line 6)
+* Float miscellaneous functions: Miscellaneous Float Functions.
+ (line 6)
+* Float random number functions: Miscellaneous Float Functions.
+ (line 27)
+* Float rounding functions: Miscellaneous Float Functions.
+ (line 9)
+* Float sign tests: Float Comparison. (line 35)
+* Floating point mode: Notes for Particular Systems.
+ (line 34)
+* Floating-point functions: Floating-point Functions.
+ (line 6)
+* Floating-point number: Nomenclature and Types.
+ (line 21)
+* fnccheck: Profiling. (line 77)
+* Formatted input: Formatted Input. (line 6)
+* Formatted output: Formatted Output. (line 6)
+* Free Documentation License: GNU Free Documentation License.
+ (line 6)
+* FreeBSD: Notes for Particular Systems.
+ (line 43)
+* frexp <1>: Converting Integers. (line 43)
+* frexp: Converting Floats. (line 24)
+* FTP of latest version: Introduction to GMP. (line 37)
+* Function classes: Function Classes. (line 6)
+* FunctionCheck: Profiling. (line 77)
+* GCC Checker: Debugging. (line 115)
+* GCD algorithms: Greatest Common Divisor Algorithms.
+ (line 6)
+* GCD extended: Number Theoretic Functions.
+ (line 49)
+* GCD functions: Number Theoretic Functions.
+ (line 32)
+* GDB: Debugging. (line 58)
+* Generic C: Build Options. (line 152)
+* GMP Perl module: Demonstration Programs.
+ (line 35)
+* GMP version number: Useful Macros and Constants.
+ (line 12)
+* gmp.h: Headers and Libraries.
+ (line 6)
+* gmpxx.h: C++ Interface General.
+ (line 8)
+* GNU Debugger: Debugging. (line 58)
+* GNU Free Documentation License: GNU Free Documentation License.
+ (line 6)
+* GNU strip: Known Build Problems.
+ (line 28)
+* gprof: Profiling. (line 41)
+* Greatest common divisor algorithms: Greatest Common Divisor Algorithms.
+ (line 6)
+* Greatest common divisor functions: Number Theoretic Functions.
+ (line 32)
+* Hardware floating point mode: Notes for Particular Systems.
+ (line 34)
+* Headers: Headers and Libraries.
+ (line 6)
+* Heap problems: Debugging. (line 24)
+* Home page: Introduction to GMP. (line 33)
+* Host system: Build Options. (line 66)
+* HP-UX: ABI and ISA. (line 77)
+* HPPA: ABI and ISA. (line 77)
+* I/O functions <1>: I/O of Integers. (line 6)
+* I/O functions <2>: I/O of Floats. (line 6)
+* I/O functions: I/O of Rationals. (line 6)
+* i386: Notes for Particular Systems.
+ (line 150)
+* IA-64: ABI and ISA. (line 116)
+* Import: Integer Import and Export.
+ (line 11)
+* In-place operations: Efficiency. (line 57)
+* Include files: Headers and Libraries.
+ (line 6)
+* info-lookup-symbol: Emacs. (line 6)
+* Initialization functions <1>: Initializing Floats. (line 6)
+* Initialization functions <2>: Random State Initialization.
+ (line 6)
+* Initialization functions <3>: Simultaneous Float Init & Assign.
+ (line 6)
+* Initialization functions <4>: Simultaneous Integer Init & Assign.
+ (line 6)
+* Initialization functions <5>: Initializing Rationals.
+ (line 6)
+* Initialization functions: Initializing Integers.
+ (line 6)
+* Initializing and clearing: Efficiency. (line 21)
+* Input functions <1>: Formatted Input Functions.
+ (line 6)
+* Input functions <2>: I/O of Rationals. (line 6)
+* Input functions <3>: I/O of Floats. (line 6)
+* Input functions: I/O of Integers. (line 6)
+* Install prefix: Build Options. (line 32)
+* Installing GMP: Installing GMP. (line 6)
+* Instruction Set Architecture: ABI and ISA. (line 6)
+* instrument-functions: Profiling. (line 66)
+* Integer: Nomenclature and Types.
+ (line 6)
+* Integer arithmetic functions: Integer Arithmetic. (line 6)
+* Integer assignment functions <1>: Assigning Integers. (line 6)
+* Integer assignment functions: Simultaneous Integer Init & Assign.
+ (line 6)
+* Integer bit manipulation functions: Integer Logic and Bit Fiddling.
+ (line 6)
+* Integer comparison functions: Integer Comparisons. (line 6)
+* Integer conversion functions: Converting Integers. (line 6)
+* Integer division functions: Integer Division. (line 6)
+* Integer exponentiation functions: Integer Exponentiation.
+ (line 6)
+* Integer export: Integer Import and Export.
+ (line 45)
+* Integer functions: Integer Functions. (line 6)
+* Integer import: Integer Import and Export.
+ (line 11)
+* Integer initialization functions <1>: Initializing Integers.
+ (line 6)
+* Integer initialization functions: Simultaneous Integer Init & Assign.
+ (line 6)
+* Integer input and output functions: I/O of Integers. (line 6)
+* Integer internals: Integer Internals. (line 6)
+* Integer logical functions: Integer Logic and Bit Fiddling.
+ (line 6)
+* Integer miscellaneous functions: Miscellaneous Integer Functions.
+ (line 6)
+* Integer random number functions: Integer Random Numbers.
+ (line 6)
+* Integer root functions: Integer Roots. (line 6)
+* Integer sign tests: Integer Comparisons. (line 28)
+* Integer special functions: Integer Special Functions.
+ (line 6)
+* Interix: Notes for Particular Systems.
+ (line 65)
+* Internals: Internals. (line 6)
+* Introduction: Introduction to GMP. (line 6)
+* Inverse modulo functions: Number Theoretic Functions.
+ (line 76)
+* IRIX <1>: ABI and ISA. (line 141)
+* IRIX: Known Build Problems.
+ (line 38)
+* ISA: ABI and ISA. (line 6)
+* istream input: C++ Formatted Input. (line 6)
+* Jacobi symbol algorithm: Jacobi Symbol. (line 6)
+* Jacobi symbol functions: Number Theoretic Functions.
+ (line 83)
+* Karatsuba multiplication: Karatsuba Multiplication.
+ (line 6)
+* Karatsuba square root algorithm: Square Root Algorithm.
+ (line 6)
+* Kronecker symbol functions: Number Theoretic Functions.
+ (line 95)
+* Language bindings: Language Bindings. (line 6)
+* Latest version of GMP: Introduction to GMP. (line 37)
+* LCM functions: Number Theoretic Functions.
+ (line 70)
+* Least common multiple functions: Number Theoretic Functions.
+ (line 70)
+* Legendre symbol functions: Number Theoretic Functions.
+ (line 86)
+* libgmp: Headers and Libraries.
+ (line 22)
+* libgmpxx: Headers and Libraries.
+ (line 27)
+* Libraries: Headers and Libraries.
+ (line 22)
+* Libtool: Headers and Libraries.
+ (line 33)
+* Libtool versioning: Notes for Package Builds.
+ (line 9)
+* License conditions: Copying. (line 6)
+* Limb: Nomenclature and Types.
+ (line 31)
+* Limb size: Useful Macros and Constants.
+ (line 7)
+* Linear congruential algorithm: Random Number Algorithms.
+ (line 25)
+* Linear congruential random numbers: Random State Initialization.
+ (line 32)
+* Linking: Headers and Libraries.
+ (line 22)
+* Logical functions: Integer Logic and Bit Fiddling.
+ (line 6)
+* Low-level functions: Low-level Functions. (line 6)
+* Low-level functions for cryptography: Low-level Functions. (line 495)
+* Lucas number algorithm: Lucas Numbers Algorithm.
+ (line 6)
+* Lucas number functions: Number Theoretic Functions.
+ (line 147)
+* MacOS X: Known Build Problems.
+ (line 51)
+* Mailing lists: Introduction to GMP. (line 44)
+* Malloc debugger: Debugging. (line 30)
+* Malloc problems: Debugging. (line 24)
+* Memory allocation: Custom Allocation. (line 6)
+* Memory management: Memory Management. (line 6)
+* Mersenne twister algorithm: Random Number Algorithms.
+ (line 17)
+* Mersenne twister random numbers: Random State Initialization.
+ (line 13)
+* MINGW: Notes for Particular Systems.
+ (line 57)
+* MIPS: ABI and ISA. (line 141)
+* Miscellaneous float functions: Miscellaneous Float Functions.
+ (line 6)
+* Miscellaneous integer functions: Miscellaneous Integer Functions.
+ (line 6)
+* MMX: Notes for Particular Systems.
+ (line 156)
+* Modular inverse functions: Number Theoretic Functions.
+ (line 76)
+* Most significant bit: Miscellaneous Integer Functions.
+ (line 34)
+* MPN_PATH: Build Options. (line 327)
+* MS Windows: Notes for Particular Systems.
+ (line 57)
+* MS-DOS: Notes for Particular Systems.
+ (line 57)
+* Multi-threading: Reentrancy. (line 6)
+* Multiplication algorithms: Multiplication Algorithms.
+ (line 6)
+* Nails: Low-level Functions. (line 664)
+* Native compilation: Build Options. (line 52)
+* NetBSD: Notes for Particular Systems.
+ (line 100)
+* NeXT: Known Build Problems.
+ (line 57)
+* Next prime function: Number Theoretic Functions.
+ (line 25)
+* Nomenclature: Nomenclature and Types.
+ (line 6)
+* Non-Unix systems: Build Options. (line 11)
+* Nth root algorithm: Nth Root Algorithm. (line 6)
+* Number sequences: Efficiency. (line 147)
+* Number theoretic functions: Number Theoretic Functions.
+ (line 6)
+* Numerator and denominator: Applying Integer Functions.
+ (line 6)
+* obstack output: Formatted Output Functions.
+ (line 81)
+* OpenBSD: Notes for Particular Systems.
+ (line 109)
+* Optimizing performance: Performance optimization.
+ (line 6)
+* ostream output: C++ Formatted Output.
+ (line 6)
+* Other languages: Language Bindings. (line 6)
+* Output functions <1>: Formatted Output Functions.
+ (line 6)
+* Output functions <2>: I/O of Rationals. (line 6)
+* Output functions <3>: I/O of Integers. (line 6)
+* Output functions: I/O of Floats. (line 6)
+* Packaged builds: Notes for Package Builds.
+ (line 6)
+* Parameter conventions: Parameter Conventions.
+ (line 6)
+* Parsing expressions demo: Demonstration Programs.
+ (line 21)
+* Particular systems: Notes for Particular Systems.
+ (line 6)
+* Past GMP versions: Compatibility with older versions.
+ (line 6)
+* PDF: Build Options. (line 342)
+* Perfect power algorithm: Perfect Power Algorithm.
+ (line 6)
+* Perfect power functions: Integer Roots. (line 28)
+* Perfect square algorithm: Perfect Square Algorithm.
+ (line 6)
+* Perfect square functions: Integer Roots. (line 37)
+* perl: Demonstration Programs.
+ (line 35)
+* Perl module: Demonstration Programs.
+ (line 35)
+* Postscript: Build Options. (line 342)
+* Power/PowerPC <1>: Known Build Problems.
+ (line 63)
+* Power/PowerPC: Notes for Particular Systems.
+ (line 115)
+* Powering algorithms: Powering Algorithms. (line 6)
+* Powering functions <1>: Float Arithmetic. (line 41)
+* Powering functions: Integer Exponentiation.
+ (line 6)
+* PowerPC: ABI and ISA. (line 176)
+* Precision of floats: Floating-point Functions.
+ (line 6)
+* Precision of hardware floating point: Notes for Particular Systems.
+ (line 34)
+* Prefix: Build Options. (line 32)
+* Prime testing algorithms: Prime Testing Algorithm.
+ (line 6)
+* Prime testing functions: Number Theoretic Functions.
+ (line 7)
+* Primorial functions: Number Theoretic Functions.
+ (line 121)
+* printf formatted output: Formatted Output. (line 6)
+* Probable prime testing functions: Number Theoretic Functions.
+ (line 7)
+* prof: Profiling. (line 24)
+* Profiling: Profiling. (line 6)
+* Radix conversion algorithms: Radix Conversion Algorithms.
+ (line 6)
+* Random number algorithms: Random Number Algorithms.
+ (line 6)
+* Random number functions <1>: Integer Random Numbers.
+ (line 6)
+* Random number functions <2>: Random Number Functions.
+ (line 6)
+* Random number functions: Miscellaneous Float Functions.
+ (line 27)
+* Random number seeding: Random State Seeding.
+ (line 6)
+* Random number state: Random State Initialization.
+ (line 6)
+* Random state: Nomenclature and Types.
+ (line 46)
+* Rational arithmetic: Efficiency. (line 113)
+* Rational arithmetic functions: Rational Arithmetic. (line 6)
+* Rational assignment functions: Initializing Rationals.
+ (line 6)
+* Rational comparison functions: Comparing Rationals. (line 6)
+* Rational conversion functions: Rational Conversions.
+ (line 6)
+* Rational initialization functions: Initializing Rationals.
+ (line 6)
+* Rational input and output functions: I/O of Rationals. (line 6)
+* Rational internals: Rational Internals. (line 6)
+* Rational number: Nomenclature and Types.
+ (line 16)
+* Rational number functions: Rational Number Functions.
+ (line 6)
+* Rational numerator and denominator: Applying Integer Functions.
+ (line 6)
+* Rational sign tests: Comparing Rationals. (line 27)
+* Raw output internals: Raw Output Internals.
+ (line 6)
+* Reallocations: Efficiency. (line 30)
+* Reentrancy: Reentrancy. (line 6)
+* References: References. (line 6)
+* Remove factor functions: Number Theoretic Functions.
+ (line 108)
+* Reporting bugs: Reporting Bugs. (line 6)
+* Root extraction algorithm: Nth Root Algorithm. (line 6)
+* Root extraction algorithms: Root Extraction Algorithms.
+ (line 6)
+* Root extraction functions <1>: Float Arithmetic. (line 37)
+* Root extraction functions: Integer Roots. (line 6)
+* Root testing functions: Integer Roots. (line 28)
+* Rounding functions: Miscellaneous Float Functions.
+ (line 9)
+* Sample programs: Demonstration Programs.
+ (line 6)
+* Scan bit functions: Integer Logic and Bit Fiddling.
+ (line 40)
+* scanf formatted input: Formatted Input. (line 6)
+* SCO: Known Build Problems.
+ (line 38)
+* Seeding random numbers: Random State Seeding.
+ (line 6)
+* Segmentation violation: Debugging. (line 7)
+* Sequent Symmetry: Known Build Problems.
+ (line 68)
+* Services for Unix: Notes for Particular Systems.
+ (line 65)
+* Shared library versioning: Notes for Package Builds.
+ (line 9)
+* Sign tests <1>: Comparing Rationals. (line 27)
+* Sign tests <2>: Float Comparison. (line 35)
+* Sign tests: Integer Comparisons. (line 28)
+* Size in digits: Miscellaneous Integer Functions.
+ (line 23)
+* Small operands: Efficiency. (line 7)
+* Solaris <1>: ABI and ISA. (line 208)
+* Solaris: Known Build Problems.
+ (line 72)
+* Sparc: Notes for Particular Systems.
+ (line 127)
+* Sparc V9: ABI and ISA. (line 208)
+* Special integer functions: Integer Special Functions.
+ (line 6)
+* Square root algorithm: Square Root Algorithm.
+ (line 6)
+* SSE2: Notes for Particular Systems.
+ (line 156)
+* Stack backtrace: Debugging. (line 50)
+* Stack overflow <1>: Debugging. (line 7)
+* Stack overflow: Build Options. (line 274)
+* Static linking: Efficiency. (line 14)
+* stdarg.h: Headers and Libraries.
+ (line 17)
+* stdio.h: Headers and Libraries.
+ (line 11)
+* Stripped libraries: Known Build Problems.
+ (line 28)
+* Sun: ABI and ISA. (line 208)
+* SunOS: Notes for Particular Systems.
+ (line 144)
+* Systems: Notes for Particular Systems.
+ (line 6)
+* Temporary memory: Build Options. (line 274)
+* Texinfo: Build Options. (line 339)
+* Text input/output: Efficiency. (line 153)
+* Thread safety: Reentrancy. (line 6)
+* Toom multiplication <1>: Higher degree Toom'n'half.
+ (line 6)
+* Toom multiplication <2>: Other Multiplication.
+ (line 6)
+* Toom multiplication <3>: Toom 4-Way Multiplication.
+ (line 6)
+* Toom multiplication: Toom 3-Way Multiplication.
+ (line 6)
+* Types: Nomenclature and Types.
+ (line 6)
+* ui and si functions: Efficiency. (line 50)
+* Unbalanced multiplication: Unbalanced Multiplication.
+ (line 6)
+* Upward compatibility: Compatibility with older versions.
+ (line 6)
+* Useful macros and constants: Useful Macros and Constants.
+ (line 6)
+* User-defined precision: Floating-point Functions.
+ (line 6)
+* Valgrind: Debugging. (line 130)
+* Variable conventions: Variable Conventions.
+ (line 6)
+* Version number: Useful Macros and Constants.
+ (line 12)
+* Web page: Introduction to GMP. (line 33)
+* Windows: Notes for Particular Systems.
+ (line 70)
+* x86: Notes for Particular Systems.
+ (line 150)
+* x87: Notes for Particular Systems.
+ (line 34)
+* XML: Build Options. (line 346)
+
+
+File: gmp.info, Node: Function Index, Prev: Concept Index, Up: Top
+
+Function and Type Index
+***********************
+
+
+* Menu:
+
+* __GMP_CC: Useful Macros and Constants.
+ (line 23)
+* __GMP_CFLAGS: Useful Macros and Constants.
+ (line 24)
+* __GNU_MP_VERSION: Useful Macros and Constants.
+ (line 10)
+* __GNU_MP_VERSION_MINOR: Useful Macros and Constants.
+ (line 11)
+* __GNU_MP_VERSION_PATCHLEVEL: Useful Macros and Constants.
+ (line 12)
+* _mpz_realloc: Integer Special Functions.
+ (line 14)
+* abs <1>: C++ Interface Rationals.
+ (line 49)
+* abs <2>: C++ Interface Floats.
+ (line 83)
+* abs: C++ Interface Integers.
+ (line 47)
+* ceil: C++ Interface Floats.
+ (line 84)
+* cmp <1>: C++ Interface Floats.
+ (line 86)
+* cmp <2>: C++ Interface Rationals.
+ (line 51)
+* cmp <3>: C++ Interface Floats.
+ (line 85)
+* cmp <4>: C++ Interface Rationals.
+ (line 50)
+* cmp: C++ Interface Integers.
+ (line 49)
+* floor: C++ Interface Floats.
+ (line 93)
+* gmp_asprintf: Formatted Output Functions.
+ (line 65)
+* gmp_errno: Random State Initialization.
+ (line 55)
+* GMP_ERROR_INVALID_ARGUMENT: Random State Initialization.
+ (line 55)
+* GMP_ERROR_UNSUPPORTED_ARGUMENT: Random State Initialization.
+ (line 55)
+* gmp_fprintf: Formatted Output Functions.
+ (line 29)
+* gmp_fscanf: Formatted Input Functions.
+ (line 25)
+* GMP_LIMB_BITS: Low-level Functions. (line 694)
+* GMP_NAIL_BITS: Low-level Functions. (line 692)
+* GMP_NAIL_MASK: Low-level Functions. (line 702)
+* GMP_NUMB_BITS: Low-level Functions. (line 693)
+* GMP_NUMB_MASK: Low-level Functions. (line 703)
+* GMP_NUMB_MAX: Low-level Functions. (line 711)
+* gmp_obstack_printf: Formatted Output Functions.
+ (line 79)
+* gmp_obstack_vprintf: Formatted Output Functions.
+ (line 81)
+* gmp_printf: Formatted Output Functions.
+ (line 24)
+* GMP_RAND_ALG_DEFAULT: Random State Initialization.
+ (line 49)
+* GMP_RAND_ALG_LC: Random State Initialization.
+ (line 49)
+* gmp_randclass: C++ Interface Random Numbers.
+ (line 7)
+* gmp_randclass::get_f: C++ Interface Random Numbers.
+ (line 45)
+* gmp_randclass::get_z_bits: C++ Interface Random Numbers.
+ (line 38)
+* gmp_randclass::get_z_range: C++ Interface Random Numbers.
+ (line 42)
+* gmp_randclass::gmp_randclass: C++ Interface Random Numbers.
+ (line 27)
+* gmp_randclass::seed: C++ Interface Random Numbers.
+ (line 33)
+* gmp_randclear: Random State Initialization.
+ (line 62)
+* gmp_randinit: Random State Initialization.
+ (line 47)
+* gmp_randinit_default: Random State Initialization.
+ (line 7)
+* gmp_randinit_lc_2exp: Random State Initialization.
+ (line 18)
+* gmp_randinit_lc_2exp_size: Random State Initialization.
+ (line 32)
+* gmp_randinit_mt: Random State Initialization.
+ (line 13)
+* gmp_randinit_set: Random State Initialization.
+ (line 43)
+* gmp_randseed: Random State Seeding.
+ (line 8)
+* gmp_randseed_ui: Random State Seeding.
+ (line 10)
+* gmp_randstate_t: Nomenclature and Types.
+ (line 46)
+* gmp_scanf: Formatted Input Functions.
+ (line 21)
+* gmp_snprintf: Formatted Output Functions.
+ (line 46)
+* gmp_sprintf: Formatted Output Functions.
+ (line 34)
+* gmp_sscanf: Formatted Input Functions.
+ (line 29)
+* gmp_urandomb_ui: Random State Miscellaneous.
+ (line 8)
+* gmp_urandomm_ui: Random State Miscellaneous.
+ (line 14)
+* gmp_vasprintf: Formatted Output Functions.
+ (line 66)
+* gmp_version: Useful Macros and Constants.
+ (line 18)
+* gmp_vfprintf: Formatted Output Functions.
+ (line 30)
+* gmp_vfscanf: Formatted Input Functions.
+ (line 26)
+* gmp_vprintf: Formatted Output Functions.
+ (line 25)
+* gmp_vscanf: Formatted Input Functions.
+ (line 22)
+* gmp_vsnprintf: Formatted Output Functions.
+ (line 48)
+* gmp_vsprintf: Formatted Output Functions.
+ (line 35)
+* gmp_vsscanf: Formatted Input Functions.
+ (line 31)
+* hypot: C++ Interface Floats.
+ (line 94)
+* mp_bitcnt_t: Nomenclature and Types.
+ (line 42)
+* mp_bits_per_limb: Useful Macros and Constants.
+ (line 7)
+* mp_exp_t: Nomenclature and Types.
+ (line 27)
+* mp_get_memory_functions: Custom Allocation. (line 90)
+* mp_limb_t: Nomenclature and Types.
+ (line 31)
+* mp_set_memory_functions: Custom Allocation. (line 18)
+* mp_size_t: Nomenclature and Types.
+ (line 37)
+* mpf_abs: Float Arithmetic. (line 47)
+* mpf_add: Float Arithmetic. (line 7)
+* mpf_add_ui: Float Arithmetic. (line 9)
+* mpf_ceil: Miscellaneous Float Functions.
+ (line 7)
+* mpf_class: C++ Interface General.
+ (line 20)
+* mpf_class::fits_sint_p: C++ Interface Floats.
+ (line 87)
+* mpf_class::fits_slong_p: C++ Interface Floats.
+ (line 88)
+* mpf_class::fits_sshort_p: C++ Interface Floats.
+ (line 89)
+* mpf_class::fits_uint_p: C++ Interface Floats.
+ (line 90)
+* mpf_class::fits_ulong_p: C++ Interface Floats.
+ (line 91)
+* mpf_class::fits_ushort_p: C++ Interface Floats.
+ (line 92)
+* mpf_class::get_d: C++ Interface Floats.
+ (line 95)
+* mpf_class::get_mpf_t: C++ Interface General.
+ (line 66)
+* mpf_class::get_prec: C++ Interface Floats.
+ (line 115)
+* mpf_class::get_si: C++ Interface Floats.
+ (line 96)
+* mpf_class::get_str: C++ Interface Floats.
+ (line 98)
+* mpf_class::get_ui: C++ Interface Floats.
+ (line 99)
+* mpf_class::mpf_class: C++ Interface Floats.
+ (line 12)
+* mpf_class::operator=: C++ Interface Floats.
+ (line 60)
+* mpf_class::set_prec: C++ Interface Floats.
+ (line 116)
+* mpf_class::set_prec_raw: C++ Interface Floats.
+ (line 117)
+* mpf_class::set_str: C++ Interface Floats.
+ (line 100)
+* mpf_class::swap: C++ Interface Floats.
+ (line 104)
+* mpf_clear: Initializing Floats. (line 37)
+* mpf_clears: Initializing Floats. (line 41)
+* mpf_cmp: Float Comparison. (line 7)
+* mpf_cmp_d: Float Comparison. (line 8)
+* mpf_cmp_si: Float Comparison. (line 10)
+* mpf_cmp_ui: Float Comparison. (line 9)
+* mpf_div: Float Arithmetic. (line 29)
+* mpf_div_2exp: Float Arithmetic. (line 55)
+* mpf_div_ui: Float Arithmetic. (line 33)
+* mpf_eq: Float Comparison. (line 18)
+* mpf_fits_sint_p: Miscellaneous Float Functions.
+ (line 20)
+* mpf_fits_slong_p: Miscellaneous Float Functions.
+ (line 18)
+* mpf_fits_sshort_p: Miscellaneous Float Functions.
+ (line 22)
+* mpf_fits_uint_p: Miscellaneous Float Functions.
+ (line 19)
+* mpf_fits_ulong_p: Miscellaneous Float Functions.
+ (line 17)
+* mpf_fits_ushort_p: Miscellaneous Float Functions.
+ (line 21)
+* mpf_floor: Miscellaneous Float Functions.
+ (line 8)
+* mpf_get_d: Converting Floats. (line 7)
+* mpf_get_d_2exp: Converting Floats. (line 17)
+* mpf_get_default_prec: Initializing Floats. (line 12)
+* mpf_get_prec: Initializing Floats. (line 62)
+* mpf_get_si: Converting Floats. (line 28)
+* mpf_get_str: Converting Floats. (line 38)
+* mpf_get_ui: Converting Floats. (line 29)
+* mpf_init: Initializing Floats. (line 19)
+* mpf_init2: Initializing Floats. (line 26)
+* mpf_init_set: Simultaneous Float Init & Assign.
+ (line 16)
+* mpf_init_set_d: Simultaneous Float Init & Assign.
+ (line 19)
+* mpf_init_set_si: Simultaneous Float Init & Assign.
+ (line 18)
+* mpf_init_set_str: Simultaneous Float Init & Assign.
+ (line 26)
+* mpf_init_set_ui: Simultaneous Float Init & Assign.
+ (line 17)
+* mpf_inits: Initializing Floats. (line 31)
+* mpf_inp_str: I/O of Floats. (line 39)
+* mpf_integer_p: Miscellaneous Float Functions.
+ (line 14)
+* mpf_mul: Float Arithmetic. (line 19)
+* mpf_mul_2exp: Float Arithmetic. (line 51)
+* mpf_mul_ui: Float Arithmetic. (line 21)
+* mpf_neg: Float Arithmetic. (line 44)
+* mpf_out_str: I/O of Floats. (line 19)
+* mpf_pow_ui: Float Arithmetic. (line 41)
+* mpf_random2: Miscellaneous Float Functions.
+ (line 37)
+* mpf_reldiff: Float Comparison. (line 31)
+* mpf_set: Assigning Floats. (line 10)
+* mpf_set_d: Assigning Floats. (line 13)
+* mpf_set_default_prec: Initializing Floats. (line 7)
+* mpf_set_prec: Initializing Floats. (line 65)
+* mpf_set_prec_raw: Initializing Floats. (line 72)
+* mpf_set_q: Assigning Floats. (line 15)
+* mpf_set_si: Assigning Floats. (line 12)
+* mpf_set_str: Assigning Floats. (line 18)
+* mpf_set_ui: Assigning Floats. (line 11)
+* mpf_set_z: Assigning Floats. (line 14)
+* mpf_sgn: Float Comparison. (line 35)
+* mpf_sqrt: Float Arithmetic. (line 36)
+* mpf_sqrt_ui: Float Arithmetic. (line 37)
+* mpf_sub: Float Arithmetic. (line 12)
+* mpf_sub_ui: Float Arithmetic. (line 16)
+* mpf_swap: Assigning Floats. (line 52)
+* mpf_t: Nomenclature and Types.
+ (line 21)
+* mpf_trunc: Miscellaneous Float Functions.
+ (line 9)
+* mpf_ui_div: Float Arithmetic. (line 31)
+* mpf_ui_sub: Float Arithmetic. (line 14)
+* mpf_urandomb: Miscellaneous Float Functions.
+ (line 27)
+* mpn_add: Low-level Functions. (line 69)
+* mpn_add_1: Low-level Functions. (line 64)
+* mpn_add_n: Low-level Functions. (line 54)
+* mpn_addmul_1: Low-level Functions. (line 150)
+* mpn_and_n: Low-level Functions. (line 437)
+* mpn_andn_n: Low-level Functions. (line 452)
+* mpn_cmp: Low-level Functions. (line 286)
+* mpn_cnd_add_n: Low-level Functions. (line 530)
+* mpn_cnd_sub_n: Low-level Functions. (line 532)
+* mpn_com: Low-level Functions. (line 477)
+* mpn_copyd: Low-level Functions. (line 486)
+* mpn_copyi: Low-level Functions. (line 482)
+* mpn_divexact_by3: Low-level Functions. (line 231)
+* mpn_divexact_by3c: Low-level Functions. (line 233)
+* mpn_divmod: Low-level Functions. (line 226)
+* mpn_divmod_1: Low-level Functions. (line 210)
+* mpn_divrem: Low-level Functions. (line 184)
+* mpn_divrem_1: Low-level Functions. (line 208)
+* mpn_gcd: Low-level Functions. (line 291)
+* mpn_gcd_1: Low-level Functions. (line 301)
+* mpn_gcdext: Low-level Functions. (line 307)
+* mpn_get_str: Low-level Functions. (line 361)
+* mpn_hamdist: Low-level Functions. (line 426)
+* mpn_ior_n: Low-level Functions. (line 442)
+* mpn_iorn_n: Low-level Functions. (line 457)
+* mpn_lshift: Low-level Functions. (line 262)
+* mpn_mod_1: Low-level Functions. (line 257)
+* mpn_mul: Low-level Functions. (line 116)
+* mpn_mul_1: Low-level Functions. (line 135)
+* mpn_mul_n: Low-level Functions. (line 105)
+* mpn_nand_n: Low-level Functions. (line 462)
+* mpn_neg: Low-level Functions. (line 98)
+* mpn_nior_n: Low-level Functions. (line 467)
+* mpn_perfect_square_p: Low-level Functions. (line 432)
+* mpn_popcount: Low-level Functions. (line 422)
+* mpn_random: Low-level Functions. (line 411)
+* mpn_random2: Low-level Functions. (line 412)
+* mpn_rshift: Low-level Functions. (line 274)
+* mpn_scan0: Low-level Functions. (line 396)
+* mpn_scan1: Low-level Functions. (line 404)
+* mpn_sec_add_1: Low-level Functions. (line 543)
+* mpn_sec_div_qr: Low-level Functions. (line 613)
+* mpn_sec_div_qr_itch: Low-level Functions. (line 614)
+* mpn_sec_div_r: Low-level Functions. (line 630)
+* mpn_sec_div_r_itch: Low-level Functions. (line 631)
+* mpn_sec_invert: Low-level Functions. (line 645)
+* mpn_sec_invert_itch: Low-level Functions. (line 646)
+* mpn_sec_mul: Low-level Functions. (line 558)
+* mpn_sec_mul_itch: Low-level Functions. (line 559)
+* mpn_sec_powm: Low-level Functions. (line 588)
+* mpn_sec_powm_itch: Low-level Functions. (line 590)
+* mpn_sec_sqr: Low-level Functions. (line 573)
+* mpn_sec_sqr_itch: Low-level Functions. (line 574)
+* mpn_sec_sub_1: Low-level Functions. (line 545)
+* mpn_sec_tabselect: Low-level Functions. (line 604)
+* mpn_set_str: Low-level Functions. (line 376)
+* mpn_sizeinbase: Low-level Functions. (line 354)
+* mpn_sqr: Low-level Functions. (line 127)
+* mpn_sqrtrem: Low-level Functions. (line 336)
+* mpn_sub: Low-level Functions. (line 90)
+* mpn_sub_1: Low-level Functions. (line 85)
+* mpn_sub_n: Low-level Functions. (line 76)
+* mpn_submul_1: Low-level Functions. (line 161)
+* mpn_tdiv_qr: Low-level Functions. (line 173)
+* mpn_xnor_n: Low-level Functions. (line 472)
+* mpn_xor_n: Low-level Functions. (line 447)
+* mpn_zero: Low-level Functions. (line 489)
+* mpq_abs: Rational Arithmetic. (line 34)
+* mpq_add: Rational Arithmetic. (line 8)
+* mpq_canonicalize: Rational Number Functions.
+ (line 22)
+* mpq_class: C++ Interface General.
+ (line 19)
+* mpq_class::canonicalize: C++ Interface Rationals.
+ (line 43)
+* mpq_class::get_d: C++ Interface Rationals.
+ (line 52)
+* mpq_class::get_den: C++ Interface Rationals.
+ (line 66)
+* mpq_class::get_den_mpz_t: C++ Interface Rationals.
+ (line 76)
+* mpq_class::get_mpq_t: C++ Interface General.
+ (line 65)
+* mpq_class::get_num: C++ Interface Rationals.
+ (line 65)
+* mpq_class::get_num_mpz_t: C++ Interface Rationals.
+ (line 75)
+* mpq_class::get_str: C++ Interface Rationals.
+ (line 53)
+* mpq_class::mpq_class: C++ Interface Rationals.
+ (line 12)
+* mpq_class::set_str: C++ Interface Rationals.
+ (line 55)
+* mpq_class::swap: C++ Interface Rationals.
+ (line 57)
+* mpq_clear: Initializing Rationals.
+ (line 16)
+* mpq_clears: Initializing Rationals.
+ (line 20)
+* mpq_cmp: Comparing Rationals. (line 7)
+* mpq_cmp_si: Comparing Rationals. (line 17)
+* mpq_cmp_ui: Comparing Rationals. (line 15)
+* mpq_denref: Applying Integer Functions.
+ (line 18)
+* mpq_div: Rational Arithmetic. (line 24)
+* mpq_div_2exp: Rational Arithmetic. (line 28)
+* mpq_equal: Comparing Rationals. (line 33)
+* mpq_get_d: Rational Conversions.
+ (line 7)
+* mpq_get_den: Applying Integer Functions.
+ (line 24)
+* mpq_get_num: Applying Integer Functions.
+ (line 23)
+* mpq_get_str: Rational Conversions.
+ (line 22)
+* mpq_init: Initializing Rationals.
+ (line 7)
+* mpq_inits: Initializing Rationals.
+ (line 12)
+* mpq_inp_str: I/O of Rationals. (line 27)
+* mpq_inv: Rational Arithmetic. (line 37)
+* mpq_mul: Rational Arithmetic. (line 16)
+* mpq_mul_2exp: Rational Arithmetic. (line 20)
+* mpq_neg: Rational Arithmetic. (line 31)
+* mpq_numref: Applying Integer Functions.
+ (line 17)
+* mpq_out_str: I/O of Rationals. (line 19)
+* mpq_set: Initializing Rationals.
+ (line 24)
+* mpq_set_d: Rational Conversions.
+ (line 17)
+* mpq_set_den: Applying Integer Functions.
+ (line 26)
+* mpq_set_f: Rational Conversions.
+ (line 18)
+* mpq_set_num: Applying Integer Functions.
+ (line 25)
+* mpq_set_si: Initializing Rationals.
+ (line 31)
+* mpq_set_str: Initializing Rationals.
+ (line 36)
+* mpq_set_ui: Initializing Rationals.
+ (line 29)
+* mpq_set_z: Initializing Rationals.
+ (line 25)
+* mpq_sgn: Comparing Rationals. (line 27)
+* mpq_sub: Rational Arithmetic. (line 12)
+* mpq_swap: Initializing Rationals.
+ (line 56)
+* mpq_t: Nomenclature and Types.
+ (line 16)
+* mpz_2fac_ui: Number Theoretic Functions.
+ (line 114)
+* mpz_abs: Integer Arithmetic. (line 45)
+* mpz_add: Integer Arithmetic. (line 7)
+* mpz_add_ui: Integer Arithmetic. (line 9)
+* mpz_addmul: Integer Arithmetic. (line 26)
+* mpz_addmul_ui: Integer Arithmetic. (line 28)
+* mpz_and: Integer Logic and Bit Fiddling.
+ (line 11)
+* mpz_array_init: Integer Special Functions.
+ (line 11)
+* mpz_bin_ui: Number Theoretic Functions.
+ (line 126)
+* mpz_bin_uiui: Number Theoretic Functions.
+ (line 128)
+* mpz_cdiv_q: Integer Division. (line 13)
+* mpz_cdiv_q_2exp: Integer Division. (line 26)
+* mpz_cdiv_q_ui: Integer Division. (line 18)
+* mpz_cdiv_qr: Integer Division. (line 16)
+* mpz_cdiv_qr_ui: Integer Division. (line 22)
+* mpz_cdiv_r: Integer Division. (line 14)
+* mpz_cdiv_r_2exp: Integer Division. (line 28)
+* mpz_cdiv_r_ui: Integer Division. (line 20)
+* mpz_cdiv_ui: Integer Division. (line 24)
+* mpz_class: C++ Interface General.
+ (line 18)
+* mpz_class::fits_sint_p: C++ Interface Integers.
+ (line 50)
+* mpz_class::fits_slong_p: C++ Interface Integers.
+ (line 51)
+* mpz_class::fits_sshort_p: C++ Interface Integers.
+ (line 52)
+* mpz_class::fits_uint_p: C++ Interface Integers.
+ (line 53)
+* mpz_class::fits_ulong_p: C++ Interface Integers.
+ (line 54)
+* mpz_class::fits_ushort_p: C++ Interface Integers.
+ (line 55)
+* mpz_class::get_d: C++ Interface Integers.
+ (line 56)
+* mpz_class::get_mpz_t: C++ Interface General.
+ (line 64)
+* mpz_class::get_si: C++ Interface Integers.
+ (line 57)
+* mpz_class::get_str: C++ Interface Integers.
+ (line 58)
+* mpz_class::get_ui: C++ Interface Integers.
+ (line 59)
+* mpz_class::mpz_class: C++ Interface Integers.
+ (line 21)
+* mpz_class::set_str: C++ Interface Integers.
+ (line 60)
+* mpz_class::swap: C++ Interface Integers.
+ (line 64)
+* mpz_clear: Initializing Integers.
+ (line 49)
+* mpz_clears: Initializing Integers.
+ (line 53)
+* mpz_clrbit: Integer Logic and Bit Fiddling.
+ (line 56)
+* mpz_cmp: Integer Comparisons. (line 7)
+* mpz_cmp_d: Integer Comparisons. (line 8)
+* mpz_cmp_si: Integer Comparisons. (line 9)
+* mpz_cmp_ui: Integer Comparisons. (line 10)
+* mpz_cmpabs: Integer Comparisons. (line 18)
+* mpz_cmpabs_d: Integer Comparisons. (line 19)
+* mpz_cmpabs_ui: Integer Comparisons. (line 20)
+* mpz_com: Integer Logic and Bit Fiddling.
+ (line 20)
+* mpz_combit: Integer Logic and Bit Fiddling.
+ (line 59)
+* mpz_congruent_2exp_p: Integer Division. (line 137)
+* mpz_congruent_p: Integer Division. (line 133)
+* mpz_congruent_ui_p: Integer Division. (line 135)
+* mpz_divexact: Integer Division. (line 110)
+* mpz_divexact_ui: Integer Division. (line 112)
+* mpz_divisible_2exp_p: Integer Division. (line 123)
+* mpz_divisible_p: Integer Division. (line 120)
+* mpz_divisible_ui_p: Integer Division. (line 122)
+* mpz_even_p: Miscellaneous Integer Functions.
+ (line 18)
+* mpz_export: Integer Import and Export.
+ (line 45)
+* mpz_fac_ui: Number Theoretic Functions.
+ (line 113)
+* mpz_fdiv_q: Integer Division. (line 30)
+* mpz_fdiv_q_2exp: Integer Division. (line 43)
+* mpz_fdiv_q_ui: Integer Division. (line 35)
+* mpz_fdiv_qr: Integer Division. (line 33)
+* mpz_fdiv_qr_ui: Integer Division. (line 39)
+* mpz_fdiv_r: Integer Division. (line 31)
+* mpz_fdiv_r_2exp: Integer Division. (line 45)
+* mpz_fdiv_r_ui: Integer Division. (line 37)
+* mpz_fdiv_ui: Integer Division. (line 41)
+* mpz_fib2_ui: Number Theoretic Functions.
+ (line 136)
+* mpz_fib_ui: Number Theoretic Functions.
+ (line 134)
+* mpz_fits_sint_p: Miscellaneous Integer Functions.
+ (line 10)
+* mpz_fits_slong_p: Miscellaneous Integer Functions.
+ (line 8)
+* mpz_fits_sshort_p: Miscellaneous Integer Functions.
+ (line 12)
+* mpz_fits_uint_p: Miscellaneous Integer Functions.
+ (line 9)
+* mpz_fits_ulong_p: Miscellaneous Integer Functions.
+ (line 7)
+* mpz_fits_ushort_p: Miscellaneous Integer Functions.
+ (line 11)
+* mpz_gcd: Number Theoretic Functions.
+ (line 32)
+* mpz_gcd_ui: Number Theoretic Functions.
+ (line 39)
+* mpz_gcdext: Number Theoretic Functions.
+ (line 49)
+* mpz_get_d: Converting Integers. (line 27)
+* mpz_get_d_2exp: Converting Integers. (line 36)
+* mpz_get_si: Converting Integers. (line 18)
+* mpz_get_str: Converting Integers. (line 47)
+* mpz_get_ui: Converting Integers. (line 11)
+* mpz_getlimbn: Integer Special Functions.
+ (line 23)
+* mpz_hamdist: Integer Logic and Bit Fiddling.
+ (line 29)
+* mpz_import: Integer Import and Export.
+ (line 11)
+* mpz_init: Initializing Integers.
+ (line 26)
+* mpz_init2: Initializing Integers.
+ (line 33)
+* mpz_init_set: Simultaneous Integer Init & Assign.
+ (line 27)
+* mpz_init_set_d: Simultaneous Integer Init & Assign.
+ (line 30)
+* mpz_init_set_si: Simultaneous Integer Init & Assign.
+ (line 29)
+* mpz_init_set_str: Simultaneous Integer Init & Assign.
+ (line 35)
+* mpz_init_set_ui: Simultaneous Integer Init & Assign.
+ (line 28)
+* mpz_inits: Initializing Integers.
+ (line 29)
+* mpz_inp_raw: I/O of Integers. (line 62)
+* mpz_inp_str: I/O of Integers. (line 31)
+* mpz_invert: Number Theoretic Functions.
+ (line 76)
+* mpz_ior: Integer Logic and Bit Fiddling.
+ (line 14)
+* mpz_jacobi: Number Theoretic Functions.
+ (line 83)
+* mpz_kronecker: Number Theoretic Functions.
+ (line 91)
+* mpz_kronecker_si: Number Theoretic Functions.
+ (line 92)
+* mpz_kronecker_ui: Number Theoretic Functions.
+ (line 93)
+* mpz_lcm: Number Theoretic Functions.
+ (line 68)
+* mpz_lcm_ui: Number Theoretic Functions.
+ (line 70)
+* mpz_legendre: Number Theoretic Functions.
+ (line 86)
+* mpz_limbs_finish: Integer Special Functions.
+ (line 48)
+* mpz_limbs_modify: Integer Special Functions.
+ (line 41)
+* mpz_limbs_read: Integer Special Functions.
+ (line 35)
+* mpz_limbs_write: Integer Special Functions.
+ (line 40)
+* mpz_lucnum2_ui: Number Theoretic Functions.
+ (line 147)
+* mpz_lucnum_ui: Number Theoretic Functions.
+ (line 145)
+* mpz_mfac_uiui: Number Theoretic Functions.
+ (line 116)
+* mpz_mod: Integer Division. (line 100)
+* mpz_mod_ui: Integer Division. (line 102)
+* mpz_mul: Integer Arithmetic. (line 19)
+* mpz_mul_2exp: Integer Arithmetic. (line 38)
+* mpz_mul_si: Integer Arithmetic. (line 20)
+* mpz_mul_ui: Integer Arithmetic. (line 22)
+* mpz_neg: Integer Arithmetic. (line 42)
+* mpz_nextprime: Number Theoretic Functions.
+ (line 25)
+* mpz_odd_p: Miscellaneous Integer Functions.
+ (line 17)
+* mpz_out_raw: I/O of Integers. (line 46)
+* mpz_out_str: I/O of Integers. (line 19)
+* mpz_perfect_power_p: Integer Roots. (line 28)
+* mpz_perfect_square_p: Integer Roots. (line 37)
+* mpz_popcount: Integer Logic and Bit Fiddling.
+ (line 23)
+* mpz_pow_ui: Integer Exponentiation.
+ (line 31)
+* mpz_powm: Integer Exponentiation.
+ (line 8)
+* mpz_powm_sec: Integer Exponentiation.
+ (line 18)
+* mpz_powm_ui: Integer Exponentiation.
+ (line 10)
+* mpz_primorial_ui: Number Theoretic Functions.
+ (line 121)
+* mpz_probab_prime_p: Number Theoretic Functions.
+ (line 7)
+* mpz_random: Integer Random Numbers.
+ (line 42)
+* mpz_random2: Integer Random Numbers.
+ (line 51)
+* mpz_realloc2: Initializing Integers.
+ (line 57)
+* mpz_remove: Number Theoretic Functions.
+ (line 108)
+* mpz_roinit_n: Integer Special Functions.
+ (line 69)
+* MPZ_ROINIT_N: Integer Special Functions.
+ (line 84)
+* mpz_root: Integer Roots. (line 8)
+* mpz_rootrem: Integer Roots. (line 14)
+* mpz_rrandomb: Integer Random Numbers.
+ (line 31)
+* mpz_scan0: Integer Logic and Bit Fiddling.
+ (line 38)
+* mpz_scan1: Integer Logic and Bit Fiddling.
+ (line 40)
+* mpz_set: Assigning Integers. (line 10)
+* mpz_set_d: Assigning Integers. (line 13)
+* mpz_set_f: Assigning Integers. (line 15)
+* mpz_set_q: Assigning Integers. (line 14)
+* mpz_set_si: Assigning Integers. (line 12)
+* mpz_set_str: Assigning Integers. (line 21)
+* mpz_set_ui: Assigning Integers. (line 11)
+* mpz_setbit: Integer Logic and Bit Fiddling.
+ (line 53)
+* mpz_sgn: Integer Comparisons. (line 28)
+* mpz_si_kronecker: Number Theoretic Functions.
+ (line 94)
+* mpz_size: Integer Special Functions.
+ (line 31)
+* mpz_sizeinbase: Miscellaneous Integer Functions.
+ (line 23)
+* mpz_sqrt: Integer Roots. (line 18)
+* mpz_sqrtrem: Integer Roots. (line 21)
+* mpz_sub: Integer Arithmetic. (line 12)
+* mpz_sub_ui: Integer Arithmetic. (line 14)
+* mpz_submul: Integer Arithmetic. (line 32)
+* mpz_submul_ui: Integer Arithmetic. (line 34)
+* mpz_swap: Assigning Integers. (line 37)
+* mpz_t: Nomenclature and Types.
+ (line 6)
+* mpz_tdiv_q: Integer Division. (line 47)
+* mpz_tdiv_q_2exp: Integer Division. (line 60)
+* mpz_tdiv_q_ui: Integer Division. (line 52)
+* mpz_tdiv_qr: Integer Division. (line 50)
+* mpz_tdiv_qr_ui: Integer Division. (line 56)
+* mpz_tdiv_r: Integer Division. (line 48)
+* mpz_tdiv_r_2exp: Integer Division. (line 62)
+* mpz_tdiv_r_ui: Integer Division. (line 54)
+* mpz_tdiv_ui: Integer Division. (line 58)
+* mpz_tstbit: Integer Logic and Bit Fiddling.
+ (line 62)
+* mpz_ui_kronecker: Number Theoretic Functions.
+ (line 95)
+* mpz_ui_pow_ui: Integer Exponentiation.
+ (line 33)
+* mpz_ui_sub: Integer Arithmetic. (line 16)
+* mpz_urandomb: Integer Random Numbers.
+ (line 14)
+* mpz_urandomm: Integer Random Numbers.
+ (line 23)
+* mpz_xor: Integer Logic and Bit Fiddling.
+ (line 17)
+* operator"" <1>: C++ Interface Floats.
+ (line 56)
+* operator"" <2>: C++ Interface Integers.
+ (line 30)
+* operator"": C++ Interface Rationals.
+ (line 38)
+* operator%: C++ Interface Integers.
+ (line 35)
+* operator/: C++ Interface Integers.
+ (line 34)
+* operator<<: C++ Formatted Output.
+ (line 20)
+* operator>> <1>: C++ Formatted Input. (line 14)
+* operator>>: C++ Interface Rationals.
+ (line 85)
+* sgn <1>: C++ Interface Floats.
+ (line 102)
+* sgn <2>: C++ Interface Integers.
+ (line 62)
+* sgn: C++ Interface Rationals.
+ (line 56)
+* sqrt <1>: C++ Interface Integers.
+ (line 63)
+* sqrt: C++ Interface Floats.
+ (line 103)
+* swap <1>: C++ Interface Floats.
+ (line 105)
+* swap <2>: C++ Interface Integers.
+ (line 65)
+* swap: C++ Interface Rationals.
+ (line 58)
+* trunc: C++ Interface Floats.
+ (line 106)
+
+
+
+
+Local Variables:
+coding: iso-8859-1
+End:
diff --git a/gmp/doc/gmp.texi b/gmp/doc/gmp.texi
new file mode 100644
index 0000000000..86d033101a
--- /dev/null
+++ b/gmp/doc/gmp.texi
@@ -0,0 +1,10887 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename gmp.info
+@documentencoding ISO-8859-1
+@include version.texi
+@settitle GNU MP @value{VERSION}
+@synindex tp fn
+@iftex
+@afourpaper
+@end iftex
+@comment %**end of header
+
+@copying
+This manual describes how to install and use the GNU multiple precision
+arithmetic library, version @value{VERSION}.
+
+Copyright 1991, 1993-2014 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document under
+the terms of the GNU Free Documentation License, Version 1.3 or any later
+version published by the Free Software Foundation; with no Invariant Sections,
+with the Front-Cover Texts being ``A GNU Manual'', and with the Back-Cover
+Texts being ``You have freedom to copy and modify this GNU Manual, like GNU
+software''. A copy of the license is included in
+@ref{GNU Free Documentation License}.
+@end copying
+@c Note the @ref above must be on one line, a line break in an @ref within
+@c @copying will bomb in recent texinfo.tex (eg. 2004-04-07.08 which comes
+@c with texinfo 4.7), with messages about missing @endcsname.
+
+
+@c Texinfo version 4.2 or up will be needed to process this file.
+@c
+@c The version number and edition number are taken from version.texi provided
+@c by automake (note that it's regenerated only if you configure with
+@c --enable-maintainer-mode).
+@c
+@c Notes discussing the present version number of GMP in relation to previous
+@c ones (for instance in the "Compatibility" section) must be updated at
+@c manually though.
+@c
+@c @cindex entries have been made for function categories and programming
+@c topics. The "mpn" section is not included in this, because a beginner
+@c looking for "GCD" or something is only going to be confused by pointers to
+@c low level routines.
+@c
+@c @cindex entries are present for processors and systems when there's
+@c particular notes concerning them, but not just for everything GMP
+@c supports.
+@c
+@c Index entries for files use @code rather than @file, @samp or @option,
+@c since the latter come out with quotes in TeX, which are nice in the text
+@c but don't look so good in index columns.
+@c
+@c Tex:
+@c
+@c A suitable texinfo.tex is supplied, a newer one should work equally well.
+@c
+@c HTML:
+@c
+@c Nothing special is done for links to external manuals, they just come out
+@c in the usual makeinfo style, eg. "../libc/Locales.html". If you have
+@c local copies of such manuals then this is a good thing, if not then you
+@c may want to search-and-replace to some online source.
+@c
+
+@dircategory GNU libraries
+@direntry
+* gmp: (gmp). GNU Multiple Precision Arithmetic Library.
+@end direntry
+
+@c html <meta name="description" content="...">
+@documentdescription
+How to install and use the GNU multiple precision arithmetic library, version @value{VERSION}.
+@end documentdescription
+
+@c smallbook
+@finalout
+@setchapternewpage on
+
+@ifnottex
+@node Top, Copying, (dir), (dir)
+@top GNU MP
+@end ifnottex
+
+@iftex
+@titlepage
+@title GNU MP
+@subtitle The GNU Multiple Precision Arithmetic Library
+@subtitle Edition @value{EDITION}
+@subtitle @value{UPDATED}
+
+@author by Torbj@"orn Granlund and the GMP development team
+@c @email{tg@@gmplib.org}
+
+@c Include the Distribution inside the titlepage so
+@c that headings are turned off.
+
+@tex
+\global\parindent=0pt
+\global\parskip=8pt
+\global\baselineskip=13pt
+@end tex
+
+@page
+@vskip 0pt plus 1filll
+@end iftex
+
+@insertcopying
+@ifnottex
+@sp 1
+@end ifnottex
+
+@iftex
+@end titlepage
+@headings double
+@end iftex
+
+@c Don't bother with contents for html, the menus seem adequate.
+@ifnothtml
+@contents
+@end ifnothtml
+
+@menu
+* Copying:: GMP Copying Conditions (LGPL).
+* Introduction to GMP:: Brief introduction to GNU MP.
+* Installing GMP:: How to configure and compile the GMP library.
+* GMP Basics:: What every GMP user should know.
+* Reporting Bugs:: How to usefully report bugs.
+* Integer Functions:: Functions for arithmetic on signed integers.
+* Rational Number Functions:: Functions for arithmetic on rational numbers.
+* Floating-point Functions:: Functions for arithmetic on floats.
+* Low-level Functions:: Fast functions for natural numbers.
+* Random Number Functions:: Functions for generating random numbers.
+* Formatted Output:: @code{printf} style output.
+* Formatted Input:: @code{scanf} style input.
+* C++ Class Interface:: Class wrappers around GMP types.
+* Custom Allocation:: How to customize the internal allocation.
+* Language Bindings:: Using GMP from other languages.
+* Algorithms:: What happens behind the scenes.
+* Internals:: How values are represented behind the scenes.
+
+* Contributors:: Who brings you this library?
+* References:: Some useful papers and books to read.
+* GNU Free Documentation License::
+* Concept Index::
+* Function Index::
+@end menu
+
+
+@c @m{T,N} is $T$ in tex or @math{N} otherwise. This is an easy way to give
+@c different forms for math in tex and info. Commas in N or T don't work,
+@c but @C{} can be used instead. \, works in info but not in tex.
+@iftex
+@macro m {T,N}
+@tex$\T\$@end tex
+@end macro
+@end iftex
+@ifnottex
+@macro m {T,N}
+@math{\N\}
+@end macro
+@end ifnottex
+
+@macro C {}
+,
+@end macro
+
+@c @ms{V,N} is $V_N$ in tex or just vn otherwise. This suits simple
+@c subscripts like @ms{x,0}.
+@iftex
+@macro ms {V,N}
+@tex$\V\_{\N\}$@end tex
+@end macro
+@end iftex
+@ifnottex
+@macro ms {V,N}
+\V\\N\
+@end macro
+@end ifnottex
+
+@c @nicode{S} is plain S in info, or @code{S} elsewhere. This can be used
+@c when the quotes that @code{} gives in info aren't wanted, but the
+@c fontification in tex or html is wanted. Doesn't work as @nicode{'\\0'}
+@c though (gives two backslashes in tex).
+@ifinfo
+@macro nicode {S}
+\S\
+@end macro
+@end ifinfo
+@ifnotinfo
+@macro nicode {S}
+@code{\S\}
+@end macro
+@end ifnotinfo
+
+@c @nisamp{S} is plain S in info, or @samp{S} elsewhere. This can be used
+@c when the quotes that @samp{} gives in info aren't wanted, but the
+@c fontification in tex or html is wanted.
+@ifinfo
+@macro nisamp {S}
+\S\
+@end macro
+@end ifinfo
+@ifnotinfo
+@macro nisamp {S}
+@samp{\S\}
+@end macro
+@end ifnotinfo
+
+@c Usage: @GMPtimes{}
+@c Give either \times or the word "times".
+@tex
+\gdef\GMPtimes{\times}
+@end tex
+@ifnottex
+@macro GMPtimes
+times
+@end macro
+@end ifnottex
+
+@c Usage: @GMPmultiply{}
+@c Give * in info, or nothing in tex.
+@tex
+\gdef\GMPmultiply{}
+@end tex
+@ifnottex
+@macro GMPmultiply
+*
+@end macro
+@end ifnottex
+
+@c Usage: @GMPabs{x}
+@c Give either |x| in tex, or abs(x) in info or html.
+@tex
+\gdef\GMPabs#1{|#1|}
+@end tex
+@ifnottex
+@macro GMPabs {X}
+@abs{}(\X\)
+@end macro
+@end ifnottex
+
+@c Usage: @GMPfloor{x}
+@c Give either \lfloor x\rfloor in tex, or floor(x) in info or html.
+@tex
+\gdef\GMPfloor#1{\lfloor #1\rfloor}
+@end tex
+@ifnottex
+@macro GMPfloor {X}
+floor(\X\)
+@end macro
+@end ifnottex
+
+@c Usage: @GMPceil{x}
+@c Give either \lceil x\rceil in tex, or ceil(x) in info or html.
+@tex
+\gdef\GMPceil#1{\lceil #1 \rceil}
+@end tex
+@ifnottex
+@macro GMPceil {X}
+ceil(\X\)
+@end macro
+@end ifnottex
+
+@c Math operators already available in tex, made available in info too.
+@c For example @bmod{} can be used in both tex and info.
+@ifnottex
+@macro bmod
+mod
+@end macro
+@macro gcd
+gcd
+@end macro
+@macro ge
+>=
+@end macro
+@macro le
+<=
+@end macro
+@macro log
+log
+@end macro
+@macro min
+min
+@end macro
+@macro leftarrow
+<-
+@end macro
+@macro rightarrow
+->
+@end macro
+@end ifnottex
+
+@c New math operators.
+@c @abs{} can be used in both tex and info, or just \abs in tex.
+@tex
+\gdef\abs{\mathop{\rm abs}}
+@end tex
+@ifnottex
+@macro abs
+abs
+@end macro
+@end ifnottex
+
+@c @cross{} is a \times symbol in tex, or an "x" in info. In tex it works
+@c inside or outside $ $.
+@tex
+\gdef\cross{\ifmmode\times\else$\times$\fi}
+@end tex
+@ifnottex
+@macro cross
+x
+@end macro
+@end ifnottex
+
+@c @times{} made available as a "*" in info and html (already works in tex).
+@ifnottex
+@macro times
+*
+@end macro
+@end ifnottex
+
+@c Usage: @W{text}
+@c Like @w{} but working in math mode too.
+@tex
+\gdef\W#1{\ifmmode{#1}\else\w{#1}\fi}
+@end tex
+@ifnottex
+@macro W {S}
+@w{\S\}
+@end macro
+@end ifnottex
+
+@c Usage: \GMPdisplay{text}
+@c Put the given text in an @display style indent, but without turning off
+@c paragraph reflow etc.
+@tex
+\gdef\GMPdisplay#1{%
+\noindent
+\advance\leftskip by \lispnarrowing
+#1\par}
+@end tex
+
+@c Usage: \GMPhat
+@c A new \hat that will work in math mode, unlike the texinfo redefined
+@c version.
+@tex
+\gdef\GMPhat{\mathaccent"705E}
+@end tex
+
+@c Usage: \GMPraise{text}
+@c For use in a $ $ math expression as an alternative to "^". This is good
+@c for @code{} in an exponent, since there seems to be no superscript font
+@c for that.
+@tex
+\gdef\GMPraise#1{\mskip0.5\thinmuskip\hbox{\raise0.8ex\hbox{#1}}}
+@end tex
+
+@c Usage: @texlinebreak{}
+@c A line break as per @*, but only in tex.
+@iftex
+@macro texlinebreak
+@*
+@end macro
+@end iftex
+@ifnottex
+@macro texlinebreak
+@end macro
+@end ifnottex
+
+@c Usage: @maybepagebreak
+@c Allow tex to insert a page break, if it feels the urge.
+@c Normally blocks of @deftypefun/funx are kept together, which can lead to
+@c some poor page break positioning if it's a big block, like the sets of
+@c division functions etc.
+@tex
+\gdef\maybepagebreak{\penalty0}
+@end tex
+@ifnottex
+@macro maybepagebreak
+@end macro
+@end ifnottex
+
+@c Usage: @GMPreftop{info,title}
+@c Usage: @GMPpxreftop{info,title}
+@c
+@c Like @ref{} and @pxref{}, but designed for a reference to the top of a
+@c document, not a particular section. The TeX output for plain @ref insists
+@c on printing a particular section, GMPreftop gives just the title.
+@c
+@c The texinfo manual recommends putting a likely section name in references
+@c like this, eg. "Introduction", but it seems better to just give the title.
+@c
+@iftex
+@macro GMPreftop{info,title}
+@i{\title\}
+@end macro
+@macro GMPpxreftop{info,title}
+see @i{\title\}
+@end macro
+@end iftex
+@c
+@ifnottex
+@macro GMPreftop{info,title}
+@ref{Top,\title\,\title\,\info\,\title\}
+@end macro
+@macro GMPpxreftop{info,title}
+@pxref{Top,\title\,\title\,\info\,\title\}
+@end macro
+@end ifnottex
+
+
+@node Copying, Introduction to GMP, Top, Top
+@comment node-name, next, previous, up
+@unnumbered GNU MP Copying Conditions
+@cindex Copying conditions
+@cindex Conditions for copying GNU MP
+@cindex License conditions
+
+This library is @dfn{free}; this means that everyone is free to use it and
+free to redistribute it on a free basis. The library is not in the public
+domain; it is copyrighted and there are restrictions on its distribution, but
+these restrictions are designed to permit everything that a good cooperating
+citizen would want to do. What is not allowed is to try to prevent others
+from further sharing any version of this library that they might get from
+you.@refill
+
+Specifically, we want to make sure that you have the right to give away copies
+of the library, that you receive source code or else can get it if you want
+it, that you can change this library or use pieces of it in new free programs,
+and that you know you can do these things.@refill
+
+To make sure that everyone has such rights, we have to forbid you to deprive
+anyone else of these rights. For example, if you distribute copies of the GNU
+MP library, you must give the recipients all the rights that you have. You
+must make sure that they, too, receive or can get the source code. And you
+must tell them their rights.@refill
+
+Also, for our own protection, we must make certain that everyone finds out
+that there is no warranty for the GNU MP library. If it is modified by
+someone else and passed on, we want their recipients to know that what they
+have is not what we distributed, so that any problems introduced by others
+will not reflect on our reputation.@refill
+
+More precisely, the GNU MP library is dual licensed, under the conditions of
+the GNU Lesser General Public License version 3 (see
+@file{COPYING.LESSERv3}), or the GNU General Public License version 2 (see
+@file{COPYINGv2}). This is the recipient's choice, and the recipient also has
+the additional option of applying later versions of these licenses. (The
+reason for this dual licensing is to make it possible to use the library with
+programs which are licensed under GPL version 2, but which for historical or
+other reasons do not allow use under later versions of the GPL).
+
+Programs which are not part of the library itself, such as demonstration
+programs and the GMP testsuite, are licensed under the terms of the GNU
+General Public License version 3 (see @file{COPYINGv3}), or any later
+version.
+
+
+@node Introduction to GMP, Installing GMP, Copying, Top
+@comment node-name, next, previous, up
+@chapter Introduction to GNU MP
+@cindex Introduction
+
+GNU MP is a portable library written in C for arbitrary precision arithmetic
+on integers, rational numbers, and floating-point numbers. It aims to provide
+the fastest possible arithmetic for all applications that need higher
+precision than is directly supported by the basic C types.
+
+Many applications use just a few hundred bits of precision; but some
+applications may need thousands or even millions of bits. GMP is designed to
+give good performance for both, by choosing algorithms based on the sizes of
+the operands, and by carefully keeping the overhead at a minimum.
+
+The speed of GMP is achieved by using fullwords as the basic arithmetic type,
+by using sophisticated algorithms, by including carefully optimized assembly
+code for the most common inner loops for many different CPUs, and by a general
+emphasis on speed (as opposed to simplicity or elegance).
+
+There is assembly code for these CPUs:
+@cindex CPU types
+ARM Cortex-A9, Cortex-A15, and generic ARM,
+DEC Alpha 21064, 21164, and 21264,
+AMD K8 and K10 (sold under many brands, e.g. Athlon64, Phenom, Opteron)
+Bulldozer, and Bobcat,
+Intel Pentium, Pentium Pro/II/III, Pentium 4, Core2, Nehalem, Sandy bridge, Haswell, generic x86,
+Intel IA-64,
+Motorola/IBM PowerPC 32 and 64 such as POWER970, POWER5, POWER6, and POWER7,
+MIPS 32-bit and 64-bit,
+SPARC 32-bit ad 64-bit with special support for all UltraSPARC models.
+There is also assembly code for many obsolete CPUs.
+
+
+@cindex Home page
+@cindex Web page
+@noindent
+For up-to-date information on GMP, please see the GMP web pages at
+
+@display
+@uref{https://gmplib.org/}
+@end display
+
+@cindex Latest version of GMP
+@cindex Anonymous FTP of latest version
+@cindex FTP of latest version
+@noindent
+The latest version of the library is available at
+
+@display
+@uref{https://ftp.gnu.org/gnu/gmp/}
+@end display
+
+Many sites around the world mirror @samp{ftp.gnu.org}, please use a mirror
+near you, see @uref{https://www.gnu.org/order/ftp.html} for a full list.
+
+@cindex Mailing lists
+There are three public mailing lists of interest. One for release
+announcements, one for general questions and discussions about usage of the GMP
+library and one for bug reports. For more information, see
+
+@display
+@uref{https://gmplib.org/mailman/listinfo/}.
+@end display
+
+The proper place for bug reports is @email{gmp-bugs@@gmplib.org}. See
+@ref{Reporting Bugs} for information about reporting bugs.
+
+@sp 1
+@section How to use this Manual
+@cindex About this manual
+
+Everyone should read @ref{GMP Basics}. If you need to install the library
+yourself, then read @ref{Installing GMP}. If you have a system with multiple
+ABIs, then read @ref{ABI and ISA}, for the compiler options that must be used
+on applications.
+
+The rest of the manual can be used for later reference, although it is
+probably a good idea to glance through it.
+
+
+@node Installing GMP, GMP Basics, Introduction to GMP, Top
+@comment node-name, next, previous, up
+@chapter Installing GMP
+@cindex Installing GMP
+@cindex Configuring GMP
+@cindex Building GMP
+
+GMP has an autoconf/automake/libtool based configuration system. On a
+Unix-like system a basic build can be done with
+
+@example
+./configure
+make
+@end example
+
+@noindent
+Some self-tests can be run with
+
+@example
+make check
+@end example
+
+@noindent
+And you can install (under @file{/usr/local} by default) with
+
+@example
+make install
+@end example
+
+If you experience problems, please report them to @email{gmp-bugs@@gmplib.org}.
+See @ref{Reporting Bugs}, for information on what to include in useful bug
+reports.
+
+@menu
+* Build Options::
+* ABI and ISA::
+* Notes for Package Builds::
+* Notes for Particular Systems::
+* Known Build Problems::
+* Performance optimization::
+@end menu
+
+
+@node Build Options, ABI and ISA, Installing GMP, Installing GMP
+@section Build Options
+@cindex Build options
+
+All the usual autoconf configure options are available, run @samp{./configure
+--help} for a summary. The file @file{INSTALL.autoconf} has some generic
+installation information too.
+
+@table @asis
+@item Tools
+@cindex Non-Unix systems
+@samp{configure} requires various Unix-like tools. See @ref{Notes for
+Particular Systems}, for some options on non-Unix systems.
+
+It might be possible to build without the help of @samp{configure}, certainly
+all the code is there, but unfortunately you'll be on your own.
+
+@item Build Directory
+@cindex Build directory
+To compile in a separate build directory, @command{cd} to that directory, and
+prefix the configure command with the path to the GMP source directory. For
+example
+
+@example
+cd /my/build/dir
+/my/sources/gmp-@value{VERSION}/configure
+@end example
+
+Not all @samp{make} programs have the necessary features (@code{VPATH}) to
+support this. In particular, SunOS and Slowaris @command{make} have bugs that
+make them unable to build in a separate directory. Use GNU @command{make}
+instead.
+
+@item @option{--prefix} and @option{--exec-prefix}
+@cindex Prefix
+@cindex Exec prefix
+@cindex Install prefix
+@cindex @code{--prefix}
+@cindex @code{--exec-prefix}
+The @option{--prefix} option can be used in the normal way to direct GMP to
+install under a particular tree. The default is @samp{/usr/local}.
+
+@option{--exec-prefix} can be used to direct architecture-dependent files like
+@file{libgmp.a} to a different location. This can be used to share
+architecture-independent parts like the documentation, but separate the
+dependent parts. Note however that @file{gmp.h} and @file{mp.h} are
+architecture-dependent since they encode certain aspects of @file{libgmp}, so
+it will be necessary to ensure both @file{$prefix/include} and
+@file{$exec_prefix/include} are available to the compiler.
+
+@item @option{--disable-shared}, @option{--disable-static}
+@cindex @code{--disable-shared}
+@cindex @code{--disable-static}
+By default both shared and static libraries are built (where possible), but
+one or other can be disabled. Shared libraries result in smaller executables
+and permit code sharing between separate running processes, but on some CPUs
+are slightly slower, having a small cost on each function call.
+
+@item Native Compilation, @option{--build=CPU-VENDOR-OS}
+@cindex Native compilation
+@cindex Build system
+@cindex @code{--build}
+For normal native compilation, the system can be specified with
+@samp{--build}. By default @samp{./configure} uses the output from running
+@samp{./config.guess}. On some systems @samp{./config.guess} can determine
+the exact CPU type, on others it will be necessary to give it explicitly. For
+example,
+
+@example
+./configure --build=ultrasparc-sun-solaris2.7
+@end example
+
+In all cases the @samp{OS} part is important, since it controls how libtool
+generates shared libraries. Running @samp{./config.guess} is the simplest way
+to see what it should be, if you don't know already.
+
+@item Cross Compilation, @option{--host=CPU-VENDOR-OS}
+@cindex Cross compiling
+@cindex Host system
+@cindex @code{--host}
+When cross-compiling, the system used for compiling is given by @samp{--build}
+and the system where the library will run is given by @samp{--host}. For
+example when using a FreeBSD Athlon system to build GNU/Linux m68k binaries,
+
+@example
+./configure --build=athlon-pc-freebsd3.5 --host=m68k-mac-linux-gnu
+@end example
+
+Compiler tools are sought first with the host system type as a prefix. For
+example @command{m68k-mac-linux-gnu-ranlib} is tried, then plain
+@command{ranlib}. This makes it possible for a set of cross-compiling tools
+to co-exist with native tools. The prefix is the argument to @samp{--host},
+and this can be an alias, such as @samp{m68k-linux}. But note that tools
+don't have to be setup this way, it's enough to just have a @env{PATH} with a
+suitable cross-compiling @command{cc} etc.
+
+Compiling for a different CPU in the same family as the build system is a form
+of cross-compilation, though very possibly this would merely be special
+options on a native compiler. In any case @samp{./configure} avoids depending
+on being able to run code on the build system, which is important when
+creating binaries for a newer CPU since they very possibly won't run on the
+build system.
+
+In all cases the compiler must be able to produce an executable (of whatever
+format) from a standard C @code{main}. Although only object files will go to
+make up @file{libgmp}, @samp{./configure} uses linking tests for various
+purposes, such as determining what functions are available on the host system.
+
+Currently a warning is given unless an explicit @samp{--build} is used when
+cross-compiling, because it may not be possible to correctly guess the build
+system type if the @env{PATH} has only a cross-compiling @command{cc}.
+
+Note that the @samp{--target} option is not appropriate for GMP@. It's for use
+when building compiler tools, with @samp{--host} being where they will run,
+and @samp{--target} what they'll produce code for. Ordinary programs or
+libraries like GMP are only interested in the @samp{--host} part, being where
+they'll run. (Some past versions of GMP used @samp{--target} incorrectly.)
+
+@item CPU types
+@cindex CPU types
+In general, if you want a library that runs as fast as possible, you should
+configure GMP for the exact CPU type your system uses. However, this may mean
+the binaries won't run on older members of the family, and might run slower on
+other members, older or newer. The best idea is always to build GMP for the
+exact machine type you intend to run it on.
+
+The following CPUs have specific support. See @file{configure.ac} for details
+of what code and compiler options they select.
+
+@itemize @bullet
+
+@c Keep this formatting, it's easy to read and it can be grepped to
+@c automatically test that CPUs listed get through ./config.sub
+
+@item
+Alpha:
+@nisamp{alpha},
+@nisamp{alphaev5},
+@nisamp{alphaev56},
+@nisamp{alphapca56},
+@nisamp{alphapca57},
+@nisamp{alphaev6},
+@nisamp{alphaev67},
+@nisamp{alphaev68}
+@nisamp{alphaev7}
+
+@item
+Cray:
+@nisamp{c90},
+@nisamp{j90},
+@nisamp{t90},
+@nisamp{sv1}
+
+@item
+HPPA:
+@nisamp{hppa1.0},
+@nisamp{hppa1.1},
+@nisamp{hppa2.0},
+@nisamp{hppa2.0n},
+@nisamp{hppa2.0w},
+@nisamp{hppa64}
+
+@item
+IA-64:
+@nisamp{ia64},
+@nisamp{itanium},
+@nisamp{itanium2}
+
+@item
+MIPS:
+@nisamp{mips},
+@nisamp{mips3},
+@nisamp{mips64}
+
+@item
+Motorola:
+@nisamp{m68k},
+@nisamp{m68000},
+@nisamp{m68010},
+@nisamp{m68020},
+@nisamp{m68030},
+@nisamp{m68040},
+@nisamp{m68060},
+@nisamp{m68302},
+@nisamp{m68360},
+@nisamp{m88k},
+@nisamp{m88110}
+
+@item
+POWER:
+@nisamp{power},
+@nisamp{power1},
+@nisamp{power2},
+@nisamp{power2sc}
+
+@item
+PowerPC:
+@nisamp{powerpc},
+@nisamp{powerpc64},
+@nisamp{powerpc401},
+@nisamp{powerpc403},
+@nisamp{powerpc405},
+@nisamp{powerpc505},
+@nisamp{powerpc601},
+@nisamp{powerpc602},
+@nisamp{powerpc603},
+@nisamp{powerpc603e},
+@nisamp{powerpc604},
+@nisamp{powerpc604e},
+@nisamp{powerpc620},
+@nisamp{powerpc630},
+@nisamp{powerpc740},
+@nisamp{powerpc7400},
+@nisamp{powerpc7450},
+@nisamp{powerpc750},
+@nisamp{powerpc801},
+@nisamp{powerpc821},
+@nisamp{powerpc823},
+@nisamp{powerpc860},
+@nisamp{powerpc970}
+
+@item
+SPARC:
+@nisamp{sparc},
+@nisamp{sparcv8},
+@nisamp{microsparc},
+@nisamp{supersparc},
+@nisamp{sparcv9},
+@nisamp{ultrasparc},
+@nisamp{ultrasparc2},
+@nisamp{ultrasparc2i},
+@nisamp{ultrasparc3},
+@nisamp{sparc64}
+
+@item
+x86 family:
+@nisamp{i386},
+@nisamp{i486},
+@nisamp{i586},
+@nisamp{pentium},
+@nisamp{pentiummmx},
+@nisamp{pentiumpro},
+@nisamp{pentium2},
+@nisamp{pentium3},
+@nisamp{pentium4},
+@nisamp{k6},
+@nisamp{k62},
+@nisamp{k63},
+@nisamp{athlon},
+@nisamp{amd64},
+@nisamp{viac3},
+@nisamp{viac32}
+
+@item
+Other:
+@nisamp{arm},
+@nisamp{sh},
+@nisamp{sh2},
+@nisamp{vax},
+@end itemize
+
+CPUs not listed will use generic C code.
+
+@item Generic C Build
+@cindex Generic C
+If some of the assembly code causes problems, or if otherwise desired, the
+generic C code can be selected with the configure @option{--disable-assembly}.
+
+Note that this will run quite slowly, but it should be portable and should at
+least make it possible to get something running if all else fails.
+
+@item Fat binary, @option{--enable-fat}
+@cindex Fat binary
+@cindex @code{--enable-fat}
+Using @option{--enable-fat} selects a ``fat binary'' build on x86, where
+optimized low level subroutines are chosen at runtime according to the CPU
+detected. This means more code, but gives good performance on all x86 chips.
+(This option might become available for more architectures in the future.)
+
+@item @option{ABI}
+@cindex ABI
+On some systems GMP supports multiple ABIs (application binary interfaces),
+meaning data type sizes and calling conventions. By default GMP chooses the
+best ABI available, but a particular ABI can be selected. For example
+
+@example
+./configure --host=mips64-sgi-irix6 ABI=n32
+@end example
+
+See @ref{ABI and ISA}, for the available choices on relevant CPUs, and what
+applications need to do.
+
+@item @option{CC}, @option{CFLAGS}
+@cindex C compiler
+@cindex @code{CC}
+@cindex @code{CFLAGS}
+By default the C compiler used is chosen from among some likely candidates,
+with @command{gcc} normally preferred if it's present. The usual
+@samp{CC=whatever} can be passed to @samp{./configure} to choose something
+different.
+
+For various systems, default compiler flags are set based on the CPU and
+compiler. The usual @samp{CFLAGS="-whatever"} can be passed to
+@samp{./configure} to use something different or to set good flags for systems
+GMP doesn't otherwise know.
+
+The @samp{CC} and @samp{CFLAGS} used are printed during @samp{./configure},
+and can be found in each generated @file{Makefile}. This is the easiest way
+to check the defaults when considering changing or adding something.
+
+Note that when @samp{CC} and @samp{CFLAGS} are specified on a system
+supporting multiple ABIs it's important to give an explicit
+@samp{ABI=whatever}, since GMP can't determine the ABI just from the flags and
+won't be able to select the correct assembly code.
+
+If just @samp{CC} is selected then normal default @samp{CFLAGS} for that
+compiler will be used (if GMP recognises it). For example @samp{CC=gcc} can
+be used to force the use of GCC, with default flags (and default ABI).
+
+@item @option{CPPFLAGS}
+@cindex @code{CPPFLAGS}
+Any flags like @samp{-D} defines or @samp{-I} includes required by the
+preprocessor should be set in @samp{CPPFLAGS} rather than @samp{CFLAGS}.
+Compiling is done with both @samp{CPPFLAGS} and @samp{CFLAGS}, but
+preprocessing uses just @samp{CPPFLAGS}. This distinction is because most
+preprocessors won't accept all the flags the compiler does. Preprocessing is
+done separately in some configure tests.
+
+@item @option{CC_FOR_BUILD}
+@cindex @code{CC_FOR_BUILD}
+Some build-time programs are compiled and run to generate host-specific data
+tables. @samp{CC_FOR_BUILD} is the compiler used for this. It doesn't need
+to be in any particular ABI or mode, it merely needs to generate executables
+that can run. The default is to try the selected @samp{CC} and some likely
+candidates such as @samp{cc} and @samp{gcc}, looking for something that works.
+
+No flags are used with @samp{CC_FOR_BUILD} because a simple invocation like
+@samp{cc foo.c} should be enough. If some particular options are required
+they can be included as for instance @samp{CC_FOR_BUILD="cc -whatever"}.
+
+@item C++ Support, @option{--enable-cxx}
+@cindex C++ support
+@cindex @code{--enable-cxx}
+C++ support in GMP can be enabled with @samp{--enable-cxx}, in which case a
+C++ compiler will be required. As a convenience @samp{--enable-cxx=detect}
+can be used to enable C++ support only if a compiler can be found. The C++
+support consists of a library @file{libgmpxx.la} and header file
+@file{gmpxx.h} (@pxref{Headers and Libraries}).
+
+A separate @file{libgmpxx.la} has been adopted rather than having C++ objects
+within @file{libgmp.la} in order to ensure dynamic linked C programs aren't
+bloated by a dependency on the C++ standard library, and to avoid any chance
+that the C++ compiler could be required when linking plain C programs.
+
+@file{libgmpxx.la} will use certain internals from @file{libgmp.la} and can
+only be expected to work with @file{libgmp.la} from the same GMP version.
+Future changes to the relevant internals will be accompanied by renaming, so a
+mismatch will cause unresolved symbols rather than perhaps mysterious
+misbehaviour.
+
+In general @file{libgmpxx.la} will be usable only with the C++ compiler that
+built it, since name mangling and runtime support are usually incompatible
+between different compilers.
+
+@item @option{CXX}, @option{CXXFLAGS}
+@cindex C++ compiler
+@cindex @code{CXX}
+@cindex @code{CXXFLAGS}
+When C++ support is enabled, the C++ compiler and its flags can be set with
+variables @samp{CXX} and @samp{CXXFLAGS} in the usual way. The default for
+@samp{CXX} is the first compiler that works from a list of likely candidates,
+with @command{g++} normally preferred when available. The default for
+@samp{CXXFLAGS} is to try @samp{CFLAGS}, @samp{CFLAGS} without @samp{-g}, then
+for @command{g++} either @samp{-g -O2} or @samp{-O2}, or for other compilers
+@samp{-g} or nothing. Trying @samp{CFLAGS} this way is convenient when using
+@samp{gcc} and @samp{g++} together, since the flags for @samp{gcc} will
+usually suit @samp{g++}.
+
+It's important that the C and C++ compilers match, meaning their startup and
+runtime support routines are compatible and that they generate code in the
+same ABI (if there's a choice of ABIs on the system). @samp{./configure}
+isn't currently able to check these things very well itself, so for that
+reason @samp{--disable-cxx} is the default, to avoid a build failure due to a
+compiler mismatch. Perhaps this will change in the future.
+
+Incidentally, it's normally not good enough to set @samp{CXX} to the same as
+@samp{CC}. Although @command{gcc} for instance recognises @file{foo.cc} as
+C++ code, only @command{g++} will invoke the linker the right way when
+building an executable or shared library from C++ object files.
+
+@item Temporary Memory, @option{--enable-alloca=<choice>}
+@cindex Temporary memory
+@cindex Stack overflow
+@cindex @code{alloca}
+@cindex @code{--enable-alloca}
+GMP allocates temporary workspace using one of the following three methods,
+which can be selected with for instance
+@samp{--enable-alloca=malloc-reentrant}.
+
+@itemize @bullet
+@item
+@samp{alloca} - C library or compiler builtin.
+@item
+@samp{malloc-reentrant} - the heap, in a re-entrant fashion.
+@item
+@samp{malloc-notreentrant} - the heap, with global variables.
+@end itemize
+
+For convenience, the following choices are also available.
+@samp{--disable-alloca} is the same as @samp{no}.
+
+@itemize @bullet
+@item
+@samp{yes} - a synonym for @samp{alloca}.
+@item
+@samp{no} - a synonym for @samp{malloc-reentrant}.
+@item
+@samp{reentrant} - @code{alloca} if available, otherwise
+@samp{malloc-reentrant}. This is the default.
+@item
+@samp{notreentrant} - @code{alloca} if available, otherwise
+@samp{malloc-notreentrant}.
+@end itemize
+
+@code{alloca} is reentrant and fast, and is recommended. It actually allocates
+just small blocks on the stack; larger ones use malloc-reentrant.
+
+@samp{malloc-reentrant} is, as the name suggests, reentrant and thread safe,
+but @samp{malloc-notreentrant} is faster and should be used if reentrancy is
+not required.
+
+The two malloc methods in fact use the memory allocation functions selected by
+@code{mp_set_memory_functions}, these being @code{malloc} and friends by
+default. @xref{Custom Allocation}.
+
+An additional choice @samp{--enable-alloca=debug} is available, to help when
+debugging memory related problems (@pxref{Debugging}).
+
+@item FFT Multiplication, @option{--disable-fft}
+@cindex FFT multiplication
+@cindex @code{--disable-fft}
+By default multiplications are done using Karatsuba, 3-way Toom, higher degree
+Toom, and Fermat FFT@. The FFT is only used on large to very large operands
+and can be disabled to save code size if desired.
+
+@item Assertion Checking, @option{--enable-assert}
+@cindex Assertion checking
+@cindex @code{--enable-assert}
+This option enables some consistency checking within the library. This can be
+of use while debugging, @pxref{Debugging}.
+
+@item Execution Profiling, @option{--enable-profiling=prof/gprof/instrument}
+@cindex Execution profiling
+@cindex @code{--enable-profiling}
+Enable profiling support, in one of various styles, @pxref{Profiling}.
+
+@item @option{MPN_PATH}
+@cindex @code{MPN_PATH}
+Various assembly versions of each mpn subroutines are provided. For a given
+CPU, a search is made though a path to choose a version of each. For example
+@samp{sparcv8} has
+
+@example
+MPN_PATH="sparc32/v8 sparc32 generic"
+@end example
+
+which means look first for v8 code, then plain sparc32 (which is v7), and
+finally fall back on generic C@. Knowledgeable users with special requirements
+can specify a different path. Normally this is completely unnecessary.
+
+@item Documentation
+@cindex Documentation formats
+@cindex Texinfo
+The source for the document you're now reading is @file{doc/gmp.texi}, in
+Texinfo format, see @GMPreftop{texinfo, Texinfo}.
+
+@cindex Postscript
+@cindex DVI
+@cindex PDF
+Info format @samp{doc/gmp.info} is included in the distribution. The usual
+automake targets are available to make PostScript, DVI, PDF and HTML (these
+will require various @TeX{} and Texinfo tools).
+
+@cindex DocBook
+@cindex XML
+DocBook and XML can be generated by the Texinfo @command{makeinfo} program
+too, see @ref{makeinfo options,, Options for @command{makeinfo}, texinfo,
+Texinfo}.
+
+Some supplementary notes can also be found in the @file{doc} subdirectory.
+
+@end table
+
+
+@need 2000
+@node ABI and ISA, Notes for Package Builds, Build Options, Installing GMP
+@section ABI and ISA
+@cindex ABI
+@cindex Application Binary Interface
+@cindex ISA
+@cindex Instruction Set Architecture
+
+ABI (Application Binary Interface) refers to the calling conventions between
+functions, meaning what registers are used and what sizes the various C data
+types are. ISA (Instruction Set Architecture) refers to the instructions and
+registers a CPU has available.
+
+Some 64-bit ISA CPUs have both a 64-bit ABI and a 32-bit ABI defined, the
+latter for compatibility with older CPUs in the family. GMP supports some
+CPUs like this in both ABIs. In fact within GMP @samp{ABI} means a
+combination of chip ABI, plus how GMP chooses to use it. For example in some
+32-bit ABIs, GMP may support a limb as either a 32-bit @code{long} or a 64-bit
+@code{long long}.
+
+By default GMP chooses the best ABI available for a given system, and this
+generally gives significantly greater speed. But an ABI can be chosen
+explicitly to make GMP compatible with other libraries, or particular
+application requirements. For example,
+
+@example
+./configure ABI=32
+@end example
+
+In all cases it's vital that all object code used in a given program is
+compiled for the same ABI.
+
+Usually a limb is implemented as a @code{long}. When a @code{long long} limb
+is used this is encoded in the generated @file{gmp.h}. This is convenient for
+applications, but it does mean that @file{gmp.h} will vary, and can't be just
+copied around. @file{gmp.h} remains compiler independent though, since all
+compilers for a particular ABI will be expected to use the same limb type.
+
+Currently no attempt is made to follow whatever conventions a system has for
+installing library or header files built for a particular ABI@. This will
+probably only matter when installing multiple builds of GMP, and it might be
+as simple as configuring with a special @samp{libdir}, or it might require
+more than that. Note that builds for different ABIs need to done separately,
+with a fresh @command{./configure} and @command{make} each.
+
+@sp 1
+@table @asis
+@need 1000
+@item AMD64 (@samp{x86_64})
+@cindex AMD64
+On AMD64 systems supporting both 32-bit and 64-bit modes for applications, the
+following ABI choices are available.
+
+@table @asis
+@item @samp{ABI=64}
+The 64-bit ABI uses 64-bit limbs and pointers and makes full use of the chip
+architecture. This is the default. Applications will usually not need
+special compiler flags, but for reference the option is
+
+@example
+gcc -m64
+@end example
+
+@item @samp{ABI=32}
+The 32-bit ABI is the usual i386 conventions. This will be slower, and is not
+recommended except for inter-operating with other code not yet 64-bit capable.
+Applications must be compiled with
+
+@example
+gcc -m32
+@end example
+
+(In GCC 2.95 and earlier there's no @samp{-m32} option, it's the only mode.)
+
+@item @samp{ABI=x32}
+The x32 ABI uses 64-bit limbs but 32-bit pointers. Like the 64-bit ABI, it
+makes full use of the chip's arithmetic capabilities. This ABI is not
+supported by all operating systems.
+
+@example
+gcc -mx32
+@end example
+
+@end table
+
+@sp 1
+@need 1000
+@item HPPA 2.0 (@samp{hppa2.0*}, @samp{hppa64})
+@cindex HPPA
+@cindex HP-UX
+@table @asis
+@item @samp{ABI=2.0w}
+The 2.0w ABI uses 64-bit limbs and pointers and is available on HP-UX 11 or
+up. Applications must be compiled with
+
+@example
+gcc [built for 2.0w]
+cc +DD64
+@end example
+
+@item @samp{ABI=2.0n}
+The 2.0n ABI means the 32-bit HPPA 1.0 ABI and all its normal calling
+conventions, but with 64-bit instructions permitted within functions. GMP
+uses a 64-bit @code{long long} for a limb. This ABI is available on hppa64
+GNU/Linux and on HP-UX 10 or higher. Applications must be compiled with
+
+@example
+gcc [built for 2.0n]
+cc +DA2.0 +e
+@end example
+
+Note that current versions of GCC (eg.@: 3.2) don't generate 64-bit
+instructions for @code{long long} operations and so may be slower than for
+2.0w. (The GMP assembly code is the same though.)
+
+@item @samp{ABI=1.0}
+HPPA 2.0 CPUs can run all HPPA 1.0 and 1.1 code in the 32-bit HPPA 1.0 ABI@.
+No special compiler options are needed for applications.
+@end table
+
+All three ABIs are available for CPU types @samp{hppa2.0w}, @samp{hppa2.0} and
+@samp{hppa64}, but for CPU type @samp{hppa2.0n} only 2.0n or 1.0 are
+considered.
+
+Note that GCC on HP-UX has no options to choose between 2.0n and 2.0w modes,
+unlike HP @command{cc}. Instead it must be built for one or the other ABI@.
+GMP will detect how it was built, and skip to the corresponding @samp{ABI}.
+
+@sp 1
+@need 1500
+@item IA-64 under HP-UX (@samp{ia64*-*-hpux*}, @samp{itanium*-*-hpux*})
+@cindex IA-64
+@cindex HP-UX
+HP-UX supports two ABIs for IA-64. GMP performance is the same in both.
+
+@table @asis
+@item @samp{ABI=32}
+In the 32-bit ABI, pointers, @code{int}s and @code{long}s are 32 bits and GMP
+uses a 64 bit @code{long long} for a limb. Applications can be compiled
+without any special flags since this ABI is the default in both HP C and GCC,
+but for reference the flags are
+
+@example
+gcc -milp32
+cc +DD32
+@end example
+
+@item @samp{ABI=64}
+In the 64-bit ABI, @code{long}s and pointers are 64 bits and GMP uses a
+@code{long} for a limb. Applications must be compiled with
+
+@example
+gcc -mlp64
+cc +DD64
+@end example
+@end table
+
+On other IA-64 systems, GNU/Linux for instance, @samp{ABI=64} is the only
+choice.
+
+@sp 1
+@need 1000
+@item MIPS under IRIX 6 (@samp{mips*-*-irix[6789]})
+@cindex MIPS
+@cindex IRIX
+IRIX 6 always has a 64-bit MIPS 3 or better CPU, and supports ABIs o32, n32,
+and 64. n32 or 64 are recommended, and GMP performance will be the same in
+each. The default is n32.
+
+@table @asis
+@item @samp{ABI=o32}
+The o32 ABI is 32-bit pointers and integers, and no 64-bit operations. GMP
+will be slower than in n32 or 64, this option only exists to support old
+compilers, eg.@: GCC 2.7.2. Applications can be compiled with no special
+flags on an old compiler, or on a newer compiler with
+
+@example
+gcc -mabi=32
+cc -32
+@end example
+
+@item @samp{ABI=n32}
+The n32 ABI is 32-bit pointers and integers, but with a 64-bit limb using a
+@code{long long}. Applications must be compiled with
+
+@example
+gcc -mabi=n32
+cc -n32
+@end example
+
+@item @samp{ABI=64}
+The 64-bit ABI is 64-bit pointers and integers. Applications must be compiled
+with
+
+@example
+gcc -mabi=64
+cc -64
+@end example
+@end table
+
+Note that MIPS GNU/Linux, as of kernel version 2.2, doesn't have the necessary
+support for n32 or 64 and so only gets a 32-bit limb and the MIPS 2 code.
+
+@sp 1
+@need 1000
+@item PowerPC 64 (@samp{powerpc64}, @samp{powerpc620}, @samp{powerpc630}, @samp{powerpc970}, @samp{power4}, @samp{power5})
+@cindex PowerPC
+@table @asis
+@item @samp{ABI=mode64}
+@cindex AIX
+The AIX 64 ABI uses 64-bit limbs and pointers and is the default on PowerPC 64
+@samp{*-*-aix*} systems. Applications must be compiled with
+
+@example
+gcc -maix64
+xlc -q64
+@end example
+
+On 64-bit GNU/Linux, BSD, and Mac OS X/Darwin systems, the applications must
+be compiled with
+
+@example
+gcc -m64
+@end example
+
+@item @samp{ABI=mode32}
+The @samp{mode32} ABI uses a 64-bit @code{long long} limb but with the chip
+still in 32-bit mode and using 32-bit calling conventions. This is the default
+for systems where the true 64-bit ABI is unavailable. No special compiler
+options are typically needed for applications. This ABI is not available under
+AIX.
+
+@item @samp{ABI=32}
+This is the basic 32-bit PowerPC ABI, with a 32-bit limb. No special compiler
+options are needed for applications.
+@end table
+
+GMP's speed is greatest for the @samp{mode64} ABI, the @samp{mode32} ABI is 2nd
+best. In @samp{ABI=32} only the 32-bit ISA is used and this doesn't make full
+use of a 64-bit chip.
+
+@sp 1
+@need 1000
+@item Sparc V9 (@samp{sparc64}, @samp{sparcv9}, @samp{ultrasparc*})
+@cindex Sparc V9
+@cindex Solaris
+@cindex Sun
+@table @asis
+@item @samp{ABI=64}
+The 64-bit V9 ABI is available on the various BSD sparc64 ports, recent
+versions of Sparc64 GNU/Linux, and Solaris 2.7 and up (when the kernel is in
+64-bit mode). GCC 3.2 or higher, or Sun @command{cc} is required. On
+GNU/Linux, depending on the default @command{gcc} mode, applications must be
+compiled with
+
+@example
+gcc -m64
+@end example
+
+On Solaris applications must be compiled with
+
+@example
+gcc -m64 -mptr64 -Wa,-xarch=v9 -mcpu=v9
+cc -xarch=v9
+@end example
+
+On the BSD sparc64 systems no special options are required, since 64-bits is
+the only ABI available.
+
+@item @samp{ABI=32}
+For the basic 32-bit ABI, GMP still uses as much of the V9 ISA as it can. In
+the Sun documentation this combination is known as ``v8plus''. On GNU/Linux,
+depending on the default @command{gcc} mode, applications may need to be
+compiled with
+
+@example
+gcc -m32
+@end example
+
+On Solaris, no special compiler options are required for applications, though
+using something like the following is recommended. (@command{gcc} 2.8 and
+earlier only support @samp{-mv8} though.)
+
+@example
+gcc -mv8plus
+cc -xarch=v8plus
+@end example
+@end table
+
+GMP speed is greatest in @samp{ABI=64}, so it's the default where available.
+The speed is partly because there are extra registers available and partly
+because 64-bits is considered the more important case and has therefore had
+better code written for it.
+
+Don't be confused by the names of the @samp{-m} and @samp{-x} compiler
+options, they're called @samp{arch} but effectively control both ABI and ISA@.
+
+On Solaris 2.6 and earlier, only @samp{ABI=32} is available since the kernel
+doesn't save all registers.
+
+On Solaris 2.7 with the kernel in 32-bit mode, a normal native build will
+reject @samp{ABI=64} because the resulting executables won't run.
+@samp{ABI=64} can still be built if desired by making it look like a
+cross-compile, for example
+
+@example
+./configure --build=none --host=sparcv9-sun-solaris2.7 ABI=64
+@end example
+@end table
+
+
+@need 2000
+@node Notes for Package Builds, Notes for Particular Systems, ABI and ISA, Installing GMP
+@section Notes for Package Builds
+@cindex Build notes for binary packaging
+@cindex Packaged builds
+
+GMP should present no great difficulties for packaging in a binary
+distribution.
+
+@cindex Libtool versioning
+@cindex Shared library versioning
+Libtool is used to build the library and @samp{-version-info} is set
+appropriately, having started from @samp{3:0:0} in GMP 3.0 (@pxref{Versioning,
+Library interface versions, Library interface versions, libtool, GNU
+Libtool}).
+
+The GMP 4 series will be upwardly binary compatible in each release and will
+be upwardly binary compatible with all of the GMP 3 series. Additional
+function interfaces may be added in each release, so on systems where libtool
+versioning is not fully checked by the loader an auxiliary mechanism may be
+needed to express that a dynamic linked application depends on a new enough
+GMP.
+
+An auxiliary mechanism may also be needed to express that @file{libgmpxx.la}
+(from @option{--enable-cxx}, @pxref{Build Options}) requires @file{libgmp.la}
+from the same GMP version, since this is not done by the libtool versioning,
+nor otherwise. A mismatch will result in unresolved symbols from the linker,
+or perhaps the loader.
+
+When building a package for a CPU family, care should be taken to use
+@samp{--host} (or @samp{--build}) to choose the least common denominator among
+the CPUs which might use the package. For example this might mean plain
+@samp{sparc} (meaning V7) for SPARCs.
+
+For x86s, @option{--enable-fat} sets things up for a fat binary build, making a
+runtime selection of optimized low level routines. This is a good choice for
+packaging to run on a range of x86 chips.
+
+Users who care about speed will want GMP built for their exact CPU type, to
+make best use of the available optimizations. Providing a way to suitably
+rebuild a package may be useful. This could be as simple as making it
+possible for a user to omit @samp{--build} (and @samp{--host}) so
+@samp{./config.guess} will detect the CPU@. But a way to manually specify a
+@samp{--build} will be wanted for systems where @samp{./config.guess} is
+inexact.
+
+On systems with multiple ABIs, a packaged build will need to decide which
+among the choices is to be provided, see @ref{ABI and ISA}. A given run of
+@samp{./configure} etc will only build one ABI@. If a second ABI is also
+required then a second run of @samp{./configure} etc must be made, starting
+from a clean directory tree (@samp{make distclean}).
+
+As noted under ``ABI and ISA'', currently no attempt is made to follow system
+conventions for install locations that vary with ABI, such as
+@file{/usr/lib/sparcv9} for @samp{ABI=64} as opposed to @file{/usr/lib} for
+@samp{ABI=32}. A package build can override @samp{libdir} and other standard
+variables as necessary.
+
+Note that @file{gmp.h} is a generated file, and will be architecture and ABI
+dependent. When attempting to install two ABIs simultaneously it will be
+important that an application compile gets the correct @file{gmp.h} for its
+desired ABI@. If compiler include paths don't vary with ABI options then it
+might be necessary to create a @file{/usr/include/gmp.h} which tests
+preprocessor symbols and chooses the correct actual @file{gmp.h}.
+
+
+@need 2000
+@node Notes for Particular Systems, Known Build Problems, Notes for Package Builds, Installing GMP
+@section Notes for Particular Systems
+@cindex Build notes for particular systems
+@cindex Particular systems
+@cindex Systems
+@table @asis
+
+@c This section is more or less meant for notes about performance or about
+@c build problems that have been worked around but might leave a user
+@c scratching their head. Fun with different ABIs on a system belongs in the
+@c above section.
+
+@item AIX 3 and 4
+@cindex AIX
+On systems @samp{*-*-aix[34]*} shared libraries are disabled by default, since
+some versions of the native @command{ar} fail on the convenience libraries
+used. A shared build can be attempted with
+
+@example
+./configure --enable-shared --disable-static
+@end example
+
+Note that the @samp{--disable-static} is necessary because in a shared build
+libtool makes @file{libgmp.a} a symlink to @file{libgmp.so}, apparently for
+the benefit of old versions of @command{ld} which only recognise @file{.a},
+but unfortunately this is done even if a fully functional @command{ld} is
+available.
+
+@item ARM
+@cindex ARM
+On systems @samp{arm*-*-*}, versions of GCC up to and including 2.95.3 have a
+bug in unsigned division, giving wrong results for some operands. GMP
+@samp{./configure} will demand GCC 2.95.4 or later.
+
+@item Compaq C++
+@cindex Compaq C++
+Compaq C++ on OSF 5.1 has two flavours of @code{iostream}, a standard one and
+an old pre-standard one (see @samp{man iostream_intro}). GMP can only use the
+standard one, which unfortunately is not the default but must be selected by
+defining @code{__USE_STD_IOSTREAM}. Configure with for instance
+
+@example
+./configure --enable-cxx CPPFLAGS=-D__USE_STD_IOSTREAM
+@end example
+
+@item Floating Point Mode
+@cindex Floating point mode
+@cindex Hardware floating point mode
+@cindex Precision of hardware floating point
+@cindex x87
+On some systems, the hardware floating point has a control mode which can set
+all operations to be done in a particular precision, for instance single,
+double or extended on x86 systems (x87 floating point). The GMP functions
+involving a @code{double} cannot be expected to operate to their full
+precision when the hardware is in single precision mode. Of course this
+affects all code, including application code, not just GMP.
+
+@item FreeBSD 7.x, 8.x, 9.0, 9.1, 9.2
+@cindex FreeBSD
+@command{m4} in these releases of FreeBSD has an eval function which ignores
+its 2nd and 3rd arguments, which makes it unsuitable for @file{.asm} file
+processing. @samp{./configure} will detect the problem and either abort or
+choose another m4 in the @env{PATH}. The bug is fixed in FreeBSD 9.3 and 10.0,
+so either upgrade or use GNU m4. Note that the FreeBSD package system installs
+GNU m4 under the name @samp{gm4}, which GMP cannot guess.
+
+@item FreeBSD 7.x, 8.x, 9.x
+@cindex FreeBSD
+GMP releases starting with 6.0 do not support @samp{ABI=32} on FreeBSD/amd64
+prior to release 10.0 of the system. The cause is a broken @code{limits.h},
+which GMP no longer works around.
+
+@item MS-DOS and MS Windows
+@cindex MS-DOS
+@cindex MS Windows
+@cindex Windows
+@cindex Cygwin
+@cindex DJGPP
+@cindex MINGW
+On an MS-DOS system DJGPP can be used to build GMP, and on an MS Windows
+system Cygwin, DJGPP and MINGW can be used. All three are excellent ports of
+GCC and the various GNU tools.
+
+@display
+@uref{http://www.cygwin.com/}
+@uref{http://www.delorie.com/djgpp/}
+@uref{http://www.mingw.org/}
+@end display
+
+@cindex Interix
+@cindex Services for Unix
+Microsoft also publishes an Interix ``Services for Unix'' which can be used to
+build GMP on Windows (with a normal @samp{./configure}), but it's not free
+software.
+
+@item MS Windows DLLs
+@cindex DLLs
+@cindex MS Windows
+@cindex Windows
+On systems @samp{*-*-cygwin*}, @samp{*-*-mingw*} and @samp{*-*-pw32*} by
+default GMP builds only a static library, but a DLL can be built instead using
+
+@example
+./configure --disable-static --enable-shared
+@end example
+
+Static and DLL libraries can't both be built, since certain export directives
+in @file{gmp.h} must be different.
+
+A MINGW DLL build of GMP can be used with Microsoft C@. Libtool doesn't
+install a @file{.lib} format import library, but it can be created with MS
+@command{lib} as follows, and copied to the install directory. Similarly for
+@file{libmp} and @file{libgmpxx}.
+
+@example
+cd .libs
+lib /def:libgmp-3.dll.def /out:libgmp-3.lib
+@end example
+
+MINGW uses the C runtime library @samp{msvcrt.dll} for I/O, so applications
+wanting to use the GMP I/O routines must be compiled with @samp{cl /MD} to do
+the same. If one of the other C runtime library choices provided by MS C is
+desired then the suggestion is to use the GMP string functions and confine I/O
+to the application.
+
+@item Motorola 68k CPU Types
+@cindex 68000
+@samp{m68k} is taken to mean 68000. @samp{m68020} or higher will give a
+performance boost on applicable CPUs. @samp{m68360} can be used for CPU32
+series chips. @samp{m68302} can be used for ``Dragonball'' series chips,
+though this is merely a synonym for @samp{m68000}.
+
+@item NetBSD 5.x
+@cindex NetBSD
+@command{m4} in these releases of NetBSD has an eval function which ignores its
+2nd and 3rd arguments, which makes it unsuitable for @file{.asm} file
+processing. @samp{./configure} will detect the problem and either abort or
+choose another m4 in the @env{PATH}. The bug is fixed in NetBSD 6, so either
+upgrade or use GNU m4. Note that the NetBSD package system installs GNU m4
+under the name @samp{gm4}, which GMP cannot guess.
+
+@item OpenBSD 2.6
+@cindex OpenBSD
+@command{m4} in this release of OpenBSD has a bug in @code{eval} that makes it
+unsuitable for @file{.asm} file processing. @samp{./configure} will detect
+the problem and either abort or choose another m4 in the @env{PATH}. The bug
+is fixed in OpenBSD 2.7, so either upgrade or use GNU m4.
+
+@item Power CPU Types
+@cindex Power/PowerPC
+In GMP, CPU types @samp{power*} and @samp{powerpc*} will each use instructions
+not available on the other, so it's important to choose the right one for the
+CPU that will be used. Currently GMP has no assembly code support for using
+just the common instruction subset. To get executables that run on both, the
+current suggestion is to use the generic C code (@option{--disable-assembly}),
+possibly with appropriate compiler options (like @samp{-mcpu=common} for
+@command{gcc}). CPU @samp{rs6000} (which is not a CPU but a family of
+workstations) is accepted by @file{config.sub}, but is currently equivalent to
+@option{--disable-assembly}.
+
+@item Sparc CPU Types
+@cindex Sparc
+@samp{sparcv8} or @samp{supersparc} on relevant systems will give a
+significant performance increase over the V7 code selected by plain
+@samp{sparc}.
+
+@item Sparc App Regs
+@cindex Sparc
+The GMP assembly code for both 32-bit and 64-bit Sparc clobbers the
+``application registers'' @code{g2}, @code{g3} and @code{g4}, the same way
+that the GCC default @samp{-mapp-regs} does (@pxref{SPARC Options,, SPARC
+Options, gcc, Using the GNU Compiler Collection (GCC)}).
+
+This makes that code unsuitable for use with the special V9
+@samp{-mcmodel=embmedany} (which uses @code{g4} as a data segment pointer), and
+for applications wanting to use those registers for special purposes. In these
+cases the only suggestion currently is to build GMP with
+@option{--disable-assembly} to avoid the assembly code.
+
+@item SunOS 4
+@cindex SunOS
+@command{/usr/bin/m4} lacks various features needed to process @file{.asm}
+files, and instead @samp{./configure} will automatically use
+@command{/usr/5bin/m4}, which we believe is always available (if not then use
+GNU m4).
+
+@item x86 CPU Types
+@cindex x86
+@cindex 80x86
+@cindex i386
+@samp{i586}, @samp{pentium} or @samp{pentiummmx} code is good for its intended
+P5 Pentium chips, but quite slow when run on Intel P6 class chips (PPro, P-II,
+P-III)@. @samp{i386} is a better choice when making binaries that must run on
+both.
+
+@item x86 MMX and SSE2 Code
+@cindex MMX
+@cindex SSE2
+If the CPU selected has MMX code but the assembler doesn't support it, a
+warning is given and non-MMX code is used instead. This will be an inferior
+build, since the MMX code that's present is there because it's faster than the
+corresponding plain integer code. The same applies to SSE2.
+
+Old versions of @samp{gas} don't support MMX instructions, in particular
+version 1.92.3 that comes with FreeBSD 2.2.8 or the more recent OpenBSD 3.1
+doesn't.
+
+Solaris 2.6 and 2.7 @command{as} generate incorrect object code for register
+to register @code{movq} instructions, and so can't be used for MMX code.
+Install a recent @command{gas} if MMX code is wanted on these systems.
+@end table
+
+
+@need 2000
+@node Known Build Problems, Performance optimization, Notes for Particular Systems, Installing GMP
+@section Known Build Problems
+@cindex Build problems known
+
+@c This section is more or less meant for known build problems that are not
+@c otherwise worked around and require some sort of manual intervention.
+
+You might find more up-to-date information at @uref{https://gmplib.org/}.
+
+@table @asis
+@item Compiler link options
+The version of libtool currently in use rather aggressively strips compiler
+options when linking a shared library. This will hopefully be relaxed in the
+future, but for now if this is a problem the suggestion is to create a little
+script to hide them, and for instance configure with
+
+@example
+./configure CC=gcc-with-my-options
+@end example
+
+@item DJGPP (@samp{*-*-msdosdjgpp*})
+@cindex DJGPP
+The DJGPP port of @command{bash} 2.03 is unable to run the @samp{configure}
+script, it exits silently, having died writing a preamble to
+@file{config.log}. Use @command{bash} 2.04 or higher.
+
+@samp{make all} was found to run out of memory during the final
+@file{libgmp.la} link on one system tested, despite having 64Mb available.
+Running @samp{make libgmp.la} directly helped, perhaps recursing into the
+various subdirectories uses up memory.
+
+@item GNU binutils @command{strip} prior to 2.12
+@cindex Stripped libraries
+@cindex Binutils @command{strip}
+@cindex GNU @command{strip}
+@command{strip} from GNU binutils 2.11 and earlier should not be used on the
+static libraries @file{libgmp.a} and @file{libmp.a} since it will discard all
+but the last of multiple archive members with the same name, like the three
+versions of @file{init.o} in @file{libgmp.a}. Binutils 2.12 or higher can be
+used successfully.
+
+The shared libraries @file{libgmp.so} and @file{libmp.so} are not affected by
+this and any version of @command{strip} can be used on them.
+
+@item @command{make} syntax error
+@cindex SCO
+@cindex IRIX
+On certain versions of SCO OpenServer 5 and IRIX 6.5 the native @command{make}
+is unable to handle the long dependencies list for @file{libgmp.la}. The
+symptom is a ``syntax error'' on the following line of the top-level
+@file{Makefile}.
+
+@example
+libgmp.la: $(libgmp_la_OBJECTS) $(libgmp_la_DEPENDENCIES)
+@end example
+
+Either use GNU Make, or as a workaround remove
+@code{$(libgmp_la_DEPENDENCIES)} from that line (which will make the initial
+build work, but if any recompiling is done @file{libgmp.la} might not be
+rebuilt).
+
+@item MacOS X (@samp{*-*-darwin*})
+@cindex MacOS X
+@cindex Darwin
+Libtool currently only knows how to create shared libraries on MacOS X using
+the native @command{cc} (which is a modified GCC), not a plain GCC@. A
+static-only build should work though (@samp{--disable-shared}).
+
+@item NeXT prior to 3.3
+@cindex NeXT
+The system compiler on old versions of NeXT was a massacred and old GCC, even
+if it called itself @file{cc}. This compiler cannot be used to build GMP, you
+need to get a real GCC, and install that. (NeXT may have fixed this in
+release 3.3 of their system.)
+
+@item POWER and PowerPC
+@cindex Power/PowerPC
+Bugs in GCC 2.7.2 (and 2.6.3) mean it can't be used to compile GMP on POWER or
+PowerPC@. If you want to use GCC for these machines, get GCC 2.7.2.1 (or
+later).
+
+@item Sequent Symmetry
+@cindex Sequent Symmetry
+Use the GNU assembler instead of the system assembler, since the latter has
+serious bugs.
+
+@item Solaris 2.6
+@cindex Solaris
+The system @command{sed} prints an error ``Output line too long'' when libtool
+builds @file{libgmp.la}. This doesn't seem to cause any obvious ill effects,
+but GNU @command{sed} is recommended, to avoid any doubt.
+
+@item Sparc Solaris 2.7 with gcc 2.95.2 in @samp{ABI=32}
+@cindex Solaris
+A shared library build of GMP seems to fail in this combination, it builds but
+then fails the tests, apparently due to some incorrect data relocations within
+@code{gmp_randinit_lc_2exp_size}. The exact cause is unknown,
+@samp{--disable-shared} is recommended.
+@end table
+
+
+@need 2000
+@node Performance optimization, , Known Build Problems, Installing GMP
+@section Performance optimization
+@cindex Optimizing performance
+
+@c At some point, this should perhaps move to a separate chapter on optimizing
+@c performance.
+
+For optimal performance, build GMP for the exact CPU type of the target
+computer, see @ref{Build Options}.
+
+Unlike what is the case for most other programs, the compiler typically
+doesn't matter much, since GMP uses assembly language for the most critical
+operation.
+
+In particular for long-running GMP applications, and applications demanding
+extremely large numbers, building and running the @code{tuneup} program in the
+@file{tune} subdirectory, can be important. For example,
+
+@example
+cd tune
+make tuneup
+./tuneup
+@end example
+
+will generate better contents for the @file{gmp-mparam.h} parameter file.
+
+To use the results, put the output in the file indicated in the
+@samp{Parameters for ...} header. Then recompile from scratch.
+
+The @code{tuneup} program takes one useful parameter, @samp{-f NNN}, which
+instructs the program how long to check FFT multiply parameters. If you're
+going to use GMP for extremely large numbers, you may want to run @code{tuneup}
+with a large NNN value.
+
+
+@node GMP Basics, Reporting Bugs, Installing GMP, Top
+@comment node-name, next, previous, up
+@chapter GMP Basics
+@cindex Basics
+
+@strong{Using functions, macros, data types, etc.@: not documented in this
+manual is strongly discouraged. If you do so your application is guaranteed
+to be incompatible with future versions of GMP.}
+
+@menu
+* Headers and Libraries::
+* Nomenclature and Types::
+* Function Classes::
+* Variable Conventions::
+* Parameter Conventions::
+* Memory Management::
+* Reentrancy::
+* Useful Macros and Constants::
+* Compatibility with older versions::
+* Demonstration Programs::
+* Efficiency::
+* Debugging::
+* Profiling::
+* Autoconf::
+* Emacs::
+@end menu
+
+@node Headers and Libraries, Nomenclature and Types, GMP Basics, GMP Basics
+@section Headers and Libraries
+@cindex Headers
+
+@cindex @file{gmp.h}
+@cindex Include files
+@cindex @code{#include}
+All declarations needed to use GMP are collected in the include file
+@file{gmp.h}. It is designed to work with both C and C++ compilers.
+
+@example
+#include <gmp.h>
+@end example
+
+@cindex @code{stdio.h}
+Note however that prototypes for GMP functions with @code{FILE *} parameters
+are only provided if @code{<stdio.h>} is included too.
+
+@example
+#include <stdio.h>
+#include <gmp.h>
+@end example
+
+@cindex @code{stdarg.h}
+Likewise @code{<stdarg.h>} is required for prototypes with @code{va_list}
+parameters, such as @code{gmp_vprintf}. And @code{<obstack.h>} for prototypes
+with @code{struct obstack} parameters, such as @code{gmp_obstack_printf}, when
+available.
+
+@cindex Libraries
+@cindex Linking
+@cindex @code{libgmp}
+All programs using GMP must link against the @file{libgmp} library. On a
+typical Unix-like system this can be done with @samp{-lgmp}, for example
+
+@example
+gcc myprogram.c -lgmp
+@end example
+
+@cindex @code{libgmpxx}
+GMP C++ functions are in a separate @file{libgmpxx} library. This is built
+and installed if C++ support has been enabled (@pxref{Build Options}). For
+example,
+
+@example
+g++ mycxxprog.cc -lgmpxx -lgmp
+@end example
+
+@cindex Libtool
+GMP is built using Libtool and an application can use that to link if desired,
+@GMPpxreftop{libtool, GNU Libtool}.
+
+If GMP has been installed to a non-standard location then it may be necessary
+to use @samp{-I} and @samp{-L} compiler options to point to the right
+directories, and some sort of run-time path for a shared library.
+
+
+@node Nomenclature and Types, Function Classes, Headers and Libraries, GMP Basics
+@section Nomenclature and Types
+@cindex Nomenclature
+@cindex Types
+
+@cindex Integer
+@tindex @code{mpz_t}
+In this manual, @dfn{integer} usually means a multiple precision integer, as
+defined by the GMP library. The C data type for such integers is @code{mpz_t}.
+Here are some examples of how to declare such integers:
+
+@example
+mpz_t sum;
+
+struct foo @{ mpz_t x, y; @};
+
+mpz_t vec[20];
+@end example
+
+@cindex Rational number
+@tindex @code{mpq_t}
+@dfn{Rational number} means a multiple precision fraction. The C data type
+for these fractions is @code{mpq_t}. For example:
+
+@example
+mpq_t quotient;
+@end example
+
+@cindex Floating-point number
+@tindex @code{mpf_t}
+@dfn{Floating point number} or @dfn{Float} for short, is an arbitrary precision
+mantissa with a limited precision exponent. The C data type for such objects
+is @code{mpf_t}. For example:
+
+@example
+mpf_t fp;
+@end example
+
+@tindex @code{mp_exp_t}
+The floating point functions accept and return exponents in the C type
+@code{mp_exp_t}. Currently this is usually a @code{long}, but on some systems
+it's an @code{int} for efficiency.
+
+@cindex Limb
+@tindex @code{mp_limb_t}
+A @dfn{limb} means the part of a multi-precision number that fits in a single
+machine word. (We chose this word because a limb of the human body is
+analogous to a digit, only larger, and containing several digits.) Normally a
+limb is 32 or 64 bits. The C data type for a limb is @code{mp_limb_t}.
+
+@tindex @code{mp_size_t}
+Counts of limbs of a multi-precision number represented in the C type
+@code{mp_size_t}. Currently this is normally a @code{long}, but on some
+systems it's an @code{int} for efficiency, and on some systems it will be
+@code{long long} in the future.
+
+@tindex @code{mp_bitcnt_t}
+Counts of bits of a multi-precision number are represented in the C type
+@code{mp_bitcnt_t}. Currently this is always an @code{unsigned long}, but on
+some systems it will be an @code{unsigned long long} in the future.
+
+@cindex Random state
+@tindex @code{gmp_randstate_t}
+@dfn{Random state} means an algorithm selection and current state data. The C
+data type for such objects is @code{gmp_randstate_t}. For example:
+
+@example
+gmp_randstate_t rstate;
+@end example
+
+Also, in general @code{mp_bitcnt_t} is used for bit counts and ranges, and
+@code{size_t} is used for byte or character counts.
+
+
+@node Function Classes, Variable Conventions, Nomenclature and Types, GMP Basics
+@section Function Classes
+@cindex Function classes
+
+There are six classes of functions in the GMP library:
+
+@enumerate
+@item
+Functions for signed integer arithmetic, with names beginning with
+@code{mpz_}. The associated type is @code{mpz_t}. There are about 150
+functions in this class. (@pxref{Integer Functions})
+
+@item
+Functions for rational number arithmetic, with names beginning with
+@code{mpq_}. The associated type is @code{mpq_t}. There are about 35
+functions in this class, but the integer functions can be used for arithmetic
+on the numerator and denominator separately. (@pxref{Rational Number
+Functions})
+
+@item
+Functions for floating-point arithmetic, with names beginning with
+@code{mpf_}. The associated type is @code{mpf_t}. There are about 70
+functions is this class. (@pxref{Floating-point Functions})
+
+@item
+Fast low-level functions that operate on natural numbers. These are used by
+the functions in the preceding groups, and you can also call them directly
+from very time-critical user programs. These functions' names begin with
+@code{mpn_}. The associated type is array of @code{mp_limb_t}. There are
+about 60 (hard-to-use) functions in this class. (@pxref{Low-level Functions})
+
+@item
+Miscellaneous functions. Functions for setting up custom allocation and
+functions for generating random numbers. (@pxref{Custom Allocation}, and
+@pxref{Random Number Functions})
+@end enumerate
+
+
+@node Variable Conventions, Parameter Conventions, Function Classes, GMP Basics
+@section Variable Conventions
+@cindex Variable conventions
+@cindex Conventions for variables
+
+GMP functions generally have output arguments before input arguments. This
+notation is by analogy with the assignment operator. The BSD MP compatibility
+functions are exceptions, having the output arguments last.
+
+GMP lets you use the same variable for both input and output in one call. For
+example, the main function for integer multiplication, @code{mpz_mul}, can be
+used to square @code{x} and put the result back in @code{x} with
+
+@example
+mpz_mul (x, x, x);
+@end example
+
+Before you can assign to a GMP variable, you need to initialize it by calling
+one of the special initialization functions. When you're done with a
+variable, you need to clear it out, using one of the functions for that
+purpose. Which function to use depends on the type of variable. See the
+chapters on integer functions, rational number functions, and floating-point
+functions for details.
+
+A variable should only be initialized once, or at least cleared between each
+initialization. After a variable has been initialized, it may be assigned to
+any number of times.
+
+For efficiency reasons, avoid excessive initializing and clearing. In
+general, initialize near the start of a function and clear near the end. For
+example,
+
+@example
+void
+foo (void)
+@{
+ mpz_t n;
+ int i;
+ mpz_init (n);
+ for (i = 1; i < 100; i++)
+ @{
+ mpz_mul (n, @dots{});
+ mpz_fdiv_q (n, @dots{});
+ @dots{}
+ @}
+ mpz_clear (n);
+@}
+@end example
+
+
+@node Parameter Conventions, Memory Management, Variable Conventions, GMP Basics
+@section Parameter Conventions
+@cindex Parameter conventions
+@cindex Conventions for parameters
+
+When a GMP variable is used as a function parameter, it's effectively a
+call-by-reference, meaning if the function stores a value there it will change
+the original in the caller. Parameters which are input-only can be designated
+@code{const} to provoke a compiler error or warning on attempting to modify
+them.
+
+When a function is going to return a GMP result, it should designate a
+parameter that it sets, like the library functions do. More than one value
+can be returned by having more than one output parameter, again like the
+library functions. A @code{return} of an @code{mpz_t} etc doesn't return the
+object, only a pointer, and this is almost certainly not what's wanted.
+
+Here's an example accepting an @code{mpz_t} parameter, doing a calculation,
+and storing the result to the indicated parameter.
+
+@example
+void
+foo (mpz_t result, const mpz_t param, unsigned long n)
+@{
+ unsigned long i;
+ mpz_mul_ui (result, param, n);
+ for (i = 1; i < n; i++)
+ mpz_add_ui (result, result, i*7);
+@}
+
+int
+main (void)
+@{
+ mpz_t r, n;
+ mpz_init (r);
+ mpz_init_set_str (n, "123456", 0);
+ foo (r, n, 20L);
+ gmp_printf ("%Zd\n", r);
+ return 0;
+@}
+@end example
+
+@code{foo} works even if the mainline passes the same variable for
+@code{param} and @code{result}, just like the library functions. But
+sometimes it's tricky to make that work, and an application might not want to
+bother supporting that sort of thing.
+
+For interest, the GMP types @code{mpz_t} etc are implemented as one-element
+arrays of certain structures. This is why declaring a variable creates an
+object with the fields GMP needs, but then using it as a parameter passes a
+pointer to the object. Note that the actual fields in each @code{mpz_t} etc
+are for internal use only and should not be accessed directly by code that
+expects to be compatible with future GMP releases.
+
+
+@need 1000
+@node Memory Management, Reentrancy, Parameter Conventions, GMP Basics
+@section Memory Management
+@cindex Memory management
+
+The GMP types like @code{mpz_t} are small, containing only a couple of sizes,
+and pointers to allocated data. Once a variable is initialized, GMP takes
+care of all space allocation. Additional space is allocated whenever a
+variable doesn't have enough.
+
+@code{mpz_t} and @code{mpq_t} variables never reduce their allocated space.
+Normally this is the best policy, since it avoids frequent reallocation.
+Applications that need to return memory to the heap at some particular point
+can use @code{mpz_realloc2}, or clear variables no longer needed.
+
+@code{mpf_t} variables, in the current implementation, use a fixed amount of
+space, determined by the chosen precision and allocated at initialization, so
+their size doesn't change.
+
+All memory is allocated using @code{malloc} and friends by default, but this
+can be changed, see @ref{Custom Allocation}. Temporary memory on the stack is
+also used (via @code{alloca}), but this can be changed at build-time if
+desired, see @ref{Build Options}.
+
+
+@node Reentrancy, Useful Macros and Constants, Memory Management, GMP Basics
+@section Reentrancy
+@cindex Reentrancy
+@cindex Thread safety
+@cindex Multi-threading
+
+@noindent
+GMP is reentrant and thread-safe, with some exceptions:
+
+@itemize @bullet
+@item
+If configured with @option{--enable-alloca=malloc-notreentrant} (or with
+@option{--enable-alloca=notreentrant} when @code{alloca} is not available),
+then naturally GMP is not reentrant.
+
+@item
+@code{mpf_set_default_prec} and @code{mpf_init} use a global variable for the
+selected precision. @code{mpf_init2} can be used instead, and in the C++
+interface an explicit precision to the @code{mpf_class} constructor.
+
+@item
+@code{mpz_random} and the other old random number functions use a global
+random state and are hence not reentrant. The newer random number functions
+that accept a @code{gmp_randstate_t} parameter can be used instead.
+
+@item
+@code{gmp_randinit} (obsolete) returns an error indication through a global
+variable, which is not thread safe. Applications are advised to use
+@code{gmp_randinit_default} or @code{gmp_randinit_lc_2exp} instead.
+
+@item
+@code{mp_set_memory_functions} uses global variables to store the selected
+memory allocation functions.
+
+@item
+If the memory allocation functions set by a call to
+@code{mp_set_memory_functions} (or @code{malloc} and friends by default) are
+not reentrant, then GMP will not be reentrant either.
+
+@item
+If the standard I/O functions such as @code{fwrite} are not reentrant then the
+GMP I/O functions using them will not be reentrant either.
+
+@item
+It's safe for two threads to read from the same GMP variable simultaneously,
+but it's not safe for one to read while another might be writing, nor for
+two threads to write simultaneously. It's not safe for two threads to
+generate a random number from the same @code{gmp_randstate_t} simultaneously,
+since this involves an update of that variable.
+@end itemize
+
+
+@need 2000
+@node Useful Macros and Constants, Compatibility with older versions, Reentrancy, GMP Basics
+@section Useful Macros and Constants
+@cindex Useful macros and constants
+@cindex Constants
+
+@deftypevr {Global Constant} {const int} mp_bits_per_limb
+@findex mp_bits_per_limb
+@cindex Bits per limb
+@cindex Limb size
+The number of bits per limb.
+@end deftypevr
+
+@defmac __GNU_MP_VERSION
+@defmacx __GNU_MP_VERSION_MINOR
+@defmacx __GNU_MP_VERSION_PATCHLEVEL
+@cindex Version number
+@cindex GMP version number
+The major and minor GMP version, and patch level, respectively, as integers.
+For GMP i.j, these numbers will be i, j, and 0, respectively.
+For GMP i.j.k, these numbers will be i, j, and k, respectively.
+@end defmac
+
+@deftypevr {Global Constant} {const char * const} gmp_version
+@findex gmp_version
+The GMP version number, as a null-terminated string, in the form ``i.j.k''.
+This release is @nicode{"@value{VERSION}"}. Note that the format ``i.j'' was
+used, before version 4.3.0, when k was zero.
+@end deftypevr
+
+@defmac __GMP_CC
+@defmacx __GMP_CFLAGS
+The compiler and compiler flags, respectively, used when compiling GMP, as
+strings.
+@end defmac
+
+
+@node Compatibility with older versions, Demonstration Programs, Useful Macros and Constants, GMP Basics
+@section Compatibility with older versions
+@cindex Compatibility with older versions
+@cindex Past GMP versions
+@cindex Upward compatibility
+
+This version of GMP is upwardly binary compatible with all 5.x, 4.x, and 3.x
+versions, and upwardly compatible at the source level with all 2.x versions,
+with the following exceptions.
+
+@itemize @bullet
+@item
+@code{mpn_gcd} had its source arguments swapped as of GMP 3.0, for consistency
+with other @code{mpn} functions.
+
+@item
+@code{mpf_get_prec} counted precision slightly differently in GMP 3.0 and
+3.0.1, but in 3.1 reverted to the 2.x style.
+
+@item
+@code{mpn_bdivmod}, documented as preliminary in GMP 4, has been removed.
+@end itemize
+
+There are a number of compatibility issues between GMP 1 and GMP 2 that of
+course also apply when porting applications from GMP 1 to GMP 5. Please
+see the GMP 2 manual for details.
+
+@c @item Integer division functions round the result differently. The obsolete
+@c functions (@code{mpz_div}, @code{mpz_divmod}, @code{mpz_mdiv},
+@c @code{mpz_mdivmod}, etc) now all use floor rounding (i.e., they round the
+@c quotient towards
+@c @ifinfo
+@c @minus{}infinity).
+@c @end ifinfo
+@c @iftex
+@c @tex
+@c $-\infty$).
+@c @end tex
+@c @end iftex
+@c There are a lot of functions for integer division, giving the user better
+@c control over the rounding.
+
+@c @item The function @code{mpz_mod} now compute the true @strong{mod} function.
+
+@c @item The functions @code{mpz_powm} and @code{mpz_powm_ui} now use
+@c @strong{mod} for reduction.
+
+@c @item The assignment functions for rational numbers do no longer canonicalize
+@c their results. In the case a non-canonical result could arise from an
+@c assignment, the user need to insert an explicit call to
+@c @code{mpq_canonicalize}. This change was made for efficiency.
+
+@c @item Output generated by @code{mpz_out_raw} in this release cannot be read
+@c by @code{mpz_inp_raw} in previous releases. This change was made for making
+@c the file format truly portable between machines with different word sizes.
+
+@c @item Several @code{mpn} functions have changed. But they were intentionally
+@c undocumented in previous releases.
+
+@c @item The functions @code{mpz_cmp_ui}, @code{mpz_cmp_si}, and @code{mpq_cmp_ui}
+@c are now implemented as macros, and thereby sometimes evaluate their
+@c arguments multiple times.
+
+@c @item The functions @code{mpz_pow_ui} and @code{mpz_ui_pow_ui} now yield 1
+@c for 0^0. (In version 1, they yielded 0.)
+
+@c In version 1 of the library, @code{mpq_set_den} handled negative
+@c denominators by copying the sign to the numerator. That is no longer done.
+
+@c Pure assignment functions do not canonicalize the assigned variable. It is
+@c the responsibility of the user to canonicalize the assigned variable before
+@c any arithmetic operations are performed on that variable.
+@c Note that this is an incompatible change from version 1 of the library.
+
+@c @end enumerate
+
+
+@need 1000
+@node Demonstration Programs, Efficiency, Compatibility with older versions, GMP Basics
+@section Demonstration programs
+@cindex Demonstration programs
+@cindex Example programs
+@cindex Sample programs
+The @file{demos} subdirectory has some sample programs using GMP@. These
+aren't built or installed, but there's a @file{Makefile} with rules for them.
+For instance,
+
+@example
+make pexpr
+./pexpr 68^975+10
+@end example
+
+@noindent
+The following programs are provided
+
+@itemize @bullet
+@item
+@cindex Expression parsing demo
+@cindex Parsing expressions demo
+@samp{pexpr} is an expression evaluator, the program used on the GMP web page.
+@item
+@cindex Expression parsing demo
+@cindex Parsing expressions demo
+The @samp{calc} subdirectory has a similar but simpler evaluator using
+@command{lex} and @command{yacc}.
+@item
+@cindex Expression parsing demo
+@cindex Parsing expressions demo
+The @samp{expr} subdirectory is yet another expression evaluator, a library
+designed for ease of use within a C program. See @file{demos/expr/README} for
+more information.
+@item
+@cindex Factorization demo
+@samp{factorize} is a Pollard-Rho factorization program.
+@item
+@samp{isprime} is a command-line interface to the @code{mpz_probab_prime_p}
+function.
+@item
+@samp{primes} counts or lists primes in an interval, using a sieve.
+@item
+@samp{qcn} is an example use of @code{mpz_kronecker_ui} to estimate quadratic
+class numbers.
+@item
+@cindex @code{perl}
+@cindex GMP Perl module
+@cindex Perl module
+The @samp{perl} subdirectory is a comprehensive perl interface to GMP@. See
+@file{demos/perl/INSTALL} for more information. Documentation is in POD
+format in @file{demos/perl/GMP.pm}.
+@end itemize
+
+As an aside, consideration has been given at various times to some sort of
+expression evaluation within the main GMP library. Going beyond something
+minimal quickly leads to matters like user-defined functions, looping, fixnums
+for control variables, etc, which are considered outside the scope of GMP
+(much closer to language interpreters or compilers, @xref{Language Bindings}.)
+Something simple for program input convenience may yet be a possibility, a
+combination of the @file{expr} demo and the @file{pexpr} tree back-end
+perhaps. But for now the above evaluators are offered as illustrations.
+
+
+@need 1000
+@node Efficiency, Debugging, Demonstration Programs, GMP Basics
+@section Efficiency
+@cindex Efficiency
+
+@table @asis
+@item Small Operands
+@cindex Small operands
+On small operands, the time for function call overheads and memory allocation
+can be significant in comparison to actual calculation. This is unavoidable
+in a general purpose variable precision library, although GMP attempts to be
+as efficient as it can on both large and small operands.
+
+@item Static Linking
+@cindex Static linking
+On some CPUs, in particular the x86s, the static @file{libgmp.a} should be
+used for maximum speed, since the PIC code in the shared @file{libgmp.so} will
+have a small overhead on each function call and global data address. For many
+programs this will be insignificant, but for long calculations there's a gain
+to be had.
+
+@item Initializing and Clearing
+@cindex Initializing and clearing
+Avoid excessive initializing and clearing of variables, since this can be
+quite time consuming, especially in comparison to otherwise fast operations
+like addition.
+
+A language interpreter might want to keep a free list or stack of
+initialized variables ready for use. It should be possible to integrate
+something like that with a garbage collector too.
+
+@item Reallocations
+@cindex Reallocations
+An @code{mpz_t} or @code{mpq_t} variable used to hold successively increasing
+values will have its memory repeatedly @code{realloc}ed, which could be quite
+slow or could fragment memory, depending on the C library. If an application
+can estimate the final size then @code{mpz_init2} or @code{mpz_realloc2} can
+be called to allocate the necessary space from the beginning
+(@pxref{Initializing Integers}).
+
+It doesn't matter if a size set with @code{mpz_init2} or @code{mpz_realloc2}
+is too small, since all functions will do a further reallocation if necessary.
+Badly overestimating memory required will waste space though.
+
+@item @code{2exp} Functions
+@cindex @code{2exp} functions
+It's up to an application to call functions like @code{mpz_mul_2exp} when
+appropriate. General purpose functions like @code{mpz_mul} make no attempt to
+identify powers of two or other special forms, because such inputs will
+usually be very rare and testing every time would be wasteful.
+
+@item @code{ui} and @code{si} Functions
+@cindex @code{ui} and @code{si} functions
+The @code{ui} functions and the small number of @code{si} functions exist for
+convenience and should be used where applicable. But if for example an
+@code{mpz_t} contains a value that fits in an @code{unsigned long} there's no
+need extract it and call a @code{ui} function, just use the regular @code{mpz}
+function.
+
+@item In-Place Operations
+@cindex In-place operations
+@code{mpz_abs}, @code{mpq_abs}, @code{mpf_abs}, @code{mpz_neg}, @code{mpq_neg}
+and @code{mpf_neg} are fast when used for in-place operations like
+@code{mpz_abs(x,x)}, since in the current implementation only a single field
+of @code{x} needs changing. On suitable compilers (GCC for instance) this is
+inlined too.
+
+@code{mpz_add_ui}, @code{mpz_sub_ui}, @code{mpf_add_ui} and @code{mpf_sub_ui}
+benefit from an in-place operation like @code{mpz_add_ui(x,x,y)}, since
+usually only one or two limbs of @code{x} will need to be changed. The same
+applies to the full precision @code{mpz_add} etc if @code{y} is small. If
+@code{y} is big then cache locality may be helped, but that's all.
+
+@code{mpz_mul} is currently the opposite, a separate destination is slightly
+better. A call like @code{mpz_mul(x,x,y)} will, unless @code{y} is only one
+limb, make a temporary copy of @code{x} before forming the result. Normally
+that copying will only be a tiny fraction of the time for the multiply, so
+this is not a particularly important consideration.
+
+@code{mpz_set}, @code{mpq_set}, @code{mpq_set_num}, @code{mpf_set}, etc, make
+no attempt to recognise a copy of something to itself, so a call like
+@code{mpz_set(x,x)} will be wasteful. Naturally that would never be written
+deliberately, but if it might arise from two pointers to the same object then
+a test to avoid it might be desirable.
+
+@example
+if (x != y)
+ mpz_set (x, y);
+@end example
+
+Note that it's never worth introducing extra @code{mpz_set} calls just to get
+in-place operations. If a result should go to a particular variable then just
+direct it there and let GMP take care of data movement.
+
+@item Divisibility Testing (Small Integers)
+@cindex Divisibility testing
+@code{mpz_divisible_ui_p} and @code{mpz_congruent_ui_p} are the best functions
+for testing whether an @code{mpz_t} is divisible by an individual small
+integer. They use an algorithm which is faster than @code{mpz_tdiv_ui}, but
+which gives no useful information about the actual remainder, only whether
+it's zero (or a particular value).
+
+However when testing divisibility by several small integers, it's best to take
+a remainder modulo their product, to save multi-precision operations. For
+instance to test whether a number is divisible by any of 23, 29 or 31 take a
+remainder modulo @math{23@times{}29@times{}31 = 20677} and then test that.
+
+The division functions like @code{mpz_tdiv_q_ui} which give a quotient as well
+as a remainder are generally a little slower than the remainder-only functions
+like @code{mpz_tdiv_ui}. If the quotient is only rarely wanted then it's
+probably best to just take a remainder and then go back and calculate the
+quotient if and when it's wanted (@code{mpz_divexact_ui} can be used if the
+remainder is zero).
+
+@item Rational Arithmetic
+@cindex Rational arithmetic
+The @code{mpq} functions operate on @code{mpq_t} values with no common factors
+in the numerator and denominator. Common factors are checked-for and cast out
+as necessary. In general, cancelling factors every time is the best approach
+since it minimizes the sizes for subsequent operations.
+
+However, applications that know something about the factorization of the
+values they're working with might be able to avoid some of the GCDs used for
+canonicalization, or swap them for divisions. For example when multiplying by
+a prime it's enough to check for factors of it in the denominator instead of
+doing a full GCD@. Or when forming a big product it might be known that very
+little cancellation will be possible, and so canonicalization can be left to
+the end.
+
+The @code{mpq_numref} and @code{mpq_denref} macros give access to the
+numerator and denominator to do things outside the scope of the supplied
+@code{mpq} functions. @xref{Applying Integer Functions}.
+
+The canonical form for rationals allows mixed-type @code{mpq_t} and integer
+additions or subtractions to be done directly with multiples of the
+denominator. This will be somewhat faster than @code{mpq_add}. For example,
+
+@example
+/* mpq increment */
+mpz_add (mpq_numref(q), mpq_numref(q), mpq_denref(q));
+
+/* mpq += unsigned long */
+mpz_addmul_ui (mpq_numref(q), mpq_denref(q), 123UL);
+
+/* mpq -= mpz */
+mpz_submul (mpq_numref(q), mpq_denref(q), z);
+@end example
+
+@item Number Sequences
+@cindex Number sequences
+Functions like @code{mpz_fac_ui}, @code{mpz_fib_ui} and @code{mpz_bin_uiui}
+are designed for calculating isolated values. If a range of values is wanted
+it's probably best to call to get a starting point and iterate from there.
+
+@item Text Input/Output
+@cindex Text input/output
+Hexadecimal or octal are suggested for input or output in text form.
+Power-of-2 bases like these can be converted much more efficiently than other
+bases, like decimal. For big numbers there's usually nothing of particular
+interest to be seen in the digits, so the base doesn't matter much.
+
+Maybe we can hope octal will one day become the normal base for everyday use,
+as proposed by King Charles XII of Sweden and later reformers.
+@c Reference: Knuth volume 2 section 4.1, page 184 of second edition. :-)
+@end table
+
+
+@node Debugging, Profiling, Efficiency, GMP Basics
+@section Debugging
+@cindex Debugging
+
+@table @asis
+@item Stack Overflow
+@cindex Stack overflow
+@cindex Segmentation violation
+@cindex Bus error
+Depending on the system, a segmentation violation or bus error might be the
+only indication of stack overflow. See @samp{--enable-alloca} choices in
+@ref{Build Options}, for how to address this.
+
+In new enough versions of GCC, @samp{-fstack-check} may be able to ensure an
+overflow is recognised by the system before too much damage is done, or
+@samp{-fstack-limit-symbol} or @samp{-fstack-limit-register} may be able to
+add checking if the system itself doesn't do any (@pxref{Code Gen Options,,
+Options for Code Generation, gcc, Using the GNU Compiler Collection (GCC)}).
+These options must be added to the @samp{CFLAGS} used in the GMP build
+(@pxref{Build Options}), adding them just to an application will have no
+effect. Note also they're a slowdown, adding overhead to each function call
+and each stack allocation.
+
+@item Heap Problems
+@cindex Heap problems
+@cindex Malloc problems
+The most likely cause of application problems with GMP is heap corruption.
+Failing to @code{init} GMP variables will have unpredictable effects, and
+corruption arising elsewhere in a program may well affect GMP@. Initializing
+GMP variables more than once or failing to clear them will cause memory leaks.
+
+@cindex Malloc debugger
+In all such cases a @code{malloc} debugger is recommended. On a GNU or BSD
+system the standard C library @code{malloc} has some diagnostic facilities,
+see @ref{Allocation Debugging,, Allocation Debugging, libc, The GNU C Library
+Reference Manual}, or @samp{man 3 malloc}. Other possibilities, in no
+particular order, include
+
+@display
+@uref{http://www.inf.ethz.ch/personal/biere/projects/ccmalloc/}
+@uref{http://dmalloc.com/}
+@uref{http://www.perens.com/FreeSoftware/} @ (electric fence)
+@uref{http://packages.debian.org/stable/devel/fda}
+@uref{http://www.gnupdate.org/components/leakbug/}
+@uref{http://people.redhat.com/~otaylor/memprof/}
+@uref{http://www.cbmamiga.demon.co.uk/mpatrol/}
+@end display
+
+The GMP default allocation routines in @file{memory.c} also have a simple
+sentinel scheme which can be enabled with @code{#define DEBUG} in that file.
+This is mainly designed for detecting buffer overruns during GMP development,
+but might find other uses.
+
+@item Stack Backtraces
+@cindex Stack backtrace
+On some systems the compiler options GMP uses by default can interfere with
+debugging. In particular on x86 and 68k systems @samp{-fomit-frame-pointer}
+is used and this generally inhibits stack backtracing. Recompiling without
+such options may help while debugging, though the usual caveats about it
+potentially moving a memory problem or hiding a compiler bug will apply.
+
+@item GDB, the GNU Debugger
+@cindex GDB
+@cindex GNU Debugger
+A sample @file{.gdbinit} is included in the distribution, showing how to call
+some undocumented dump functions to print GMP variables from within GDB@. Note
+that these functions shouldn't be used in final application code since they're
+undocumented and may be subject to incompatible changes in future versions of
+GMP.
+
+@item Source File Paths
+GMP has multiple source files with the same name, in different directories.
+For example @file{mpz}, @file{mpq} and @file{mpf} each have an
+@file{init.c}. If the debugger can't already determine the right one it may
+help to build with absolute paths on each C file. One way to do that is to
+use a separate object directory with an absolute path to the source directory.
+
+@example
+cd /my/build/dir
+/my/source/dir/gmp-@value{VERSION}/configure
+@end example
+
+This works via @code{VPATH}, and might require GNU @command{make}.
+Alternately it might be possible to change the @code{.c.lo} rules
+appropriately.
+
+@item Assertion Checking
+@cindex Assertion checking
+The build option @option{--enable-assert} is available to add some consistency
+checks to the library (see @ref{Build Options}). These are likely to be of
+limited value to most applications. Assertion failures are just as likely to
+indicate memory corruption as a library or compiler bug.
+
+Applications using the low-level @code{mpn} functions, however, will benefit
+from @option{--enable-assert} since it adds checks on the parameters of most
+such functions, many of which have subtle restrictions on their usage. Note
+however that only the generic C code has checks, not the assembly code, so
+@option{--disable-assembly} should be used for maximum checking.
+
+@item Temporary Memory Checking
+The build option @option{--enable-alloca=debug} arranges that each block of
+temporary memory in GMP is allocated with a separate call to @code{malloc} (or
+the allocation function set with @code{mp_set_memory_functions}).
+
+This can help a malloc debugger detect accesses outside the intended bounds,
+or detect memory not released. In a normal build, on the other hand,
+temporary memory is allocated in blocks which GMP divides up for its own use,
+or may be allocated with a compiler builtin @code{alloca} which will go
+nowhere near any malloc debugger hooks.
+
+@item Maximum Debuggability
+To summarize the above, a GMP build for maximum debuggability would be
+
+@example
+./configure --disable-shared --enable-assert \
+ --enable-alloca=debug --disable-assembly CFLAGS=-g
+@end example
+
+For C++, add @samp{--enable-cxx CXXFLAGS=-g}.
+
+@item Checker
+@cindex Checker
+@cindex GCC Checker
+The GCC checker (@uref{https://savannah.nongnu.org/projects/checker/}) can be
+used with GMP@. It contains a stub library which means GMP applications
+compiled with checker can use a normal GMP build.
+
+A build of GMP with checking within GMP itself can be made. This will run
+very very slowly. On GNU/Linux for example,
+
+@cindex @command{checkergcc}
+@example
+./configure --disable-assembly CC=checkergcc
+@end example
+
+@option{--disable-assembly} must be used, since the GMP assembly code doesn't
+support the checking scheme. The GMP C++ features cannot be used, since
+current versions of checker (0.9.9.1) don't yet support the standard C++
+library.
+
+@item Valgrind
+@cindex Valgrind
+Valgrind (@uref{http://valgrind.org/}) is a memory checker for x86, ARM, MIPS,
+PowerPC, and S/390. It translates and emulates machine instructions to do
+strong checks for uninitialized data (at the level of individual bits), memory
+accesses through bad pointers, and memory leaks.
+
+Valgrind does not always support every possible instruction, in particular
+ones recently added to an ISA. Valgrind might therefore be incompatible with
+a recent GMP or even a less recent GMP which is compiled using a recent GCC.
+
+GMP's assembly code sometimes promotes a read of the limbs to some larger size,
+for efficiency. GMP will do this even at the start and end of a multilimb
+operand, using naturally aligned operations on the larger type. This may lead
+to benign reads outside of allocated areas, triggering complaints from
+Valgrind. Valgrind's option @samp{--partial-loads-ok=yes} should help.
+
+@item Other Problems
+Any suspected bug in GMP itself should be isolated to make sure it's not an
+application problem, see @ref{Reporting Bugs}.
+@end table
+
+
+@node Profiling, Autoconf, Debugging, GMP Basics
+@section Profiling
+@cindex Profiling
+@cindex Execution profiling
+@cindex @code{--enable-profiling}
+
+Running a program under a profiler is a good way to find where it's spending
+most time and where improvements can be best sought. The profiling choices
+for a GMP build are as follows.
+
+@table @asis
+@item @samp{--disable-profiling}
+The default is to add nothing special for profiling.
+
+It should be possible to just compile the mainline of a program with @code{-p}
+and use @command{prof} to get a profile consisting of timer-based sampling of
+the program counter. Most of the GMP assembly code has the necessary symbol
+information.
+
+This approach has the advantage of minimizing interference with normal program
+operation, but on most systems the resolution of the sampling is quite low (10
+milliseconds for instance), requiring long runs to get accurate information.
+
+@item @samp{--enable-profiling=prof}
+@cindex @code{prof}
+Build with support for the system @command{prof}, which means @samp{-p} added
+to the @samp{CFLAGS}.
+
+This provides call counting in addition to program counter sampling, which
+allows the most frequently called routines to be identified, and an average
+time spent in each routine to be determined.
+
+The x86 assembly code has support for this option, but on other processors
+the assembly routines will be as if compiled without @samp{-p} and therefore
+won't appear in the call counts.
+
+On some systems, such as GNU/Linux, @samp{-p} in fact means @samp{-pg} and in
+this case @samp{--enable-profiling=gprof} described below should be used
+instead.
+
+@item @samp{--enable-profiling=gprof}
+@cindex @code{gprof}
+Build with support for @command{gprof}, which means @samp{-pg} added to the
+@samp{CFLAGS}.
+
+This provides call graph construction in addition to call counting and program
+counter sampling, which makes it possible to count calls coming from different
+locations. For example the number of calls to @code{mpn_mul} from
+@code{mpz_mul} versus the number from @code{mpf_mul}. The program counter
+sampling is still flat though, so only a total time in @code{mpn_mul} would be
+accumulated, not a separate amount for each call site.
+
+The x86 assembly code has support for this option, but on other processors
+the assembly routines will be as if compiled without @samp{-pg} and therefore
+not be included in the call counts.
+
+On x86 and m68k systems @samp{-pg} and @samp{-fomit-frame-pointer} are
+incompatible, so the latter is omitted from the default flags in that case,
+which might result in poorer code generation.
+
+Incidentally, it should be possible to use the @command{gprof} program with a
+plain @samp{--enable-profiling=prof} build. But in that case only the
+@samp{gprof -p} flat profile and call counts can be expected to be valid, not
+the @samp{gprof -q} call graph.
+
+@item @samp{--enable-profiling=instrument}
+@cindex @code{-finstrument-functions}
+@cindex @code{instrument-functions}
+Build with the GCC option @samp{-finstrument-functions} added to the
+@samp{CFLAGS} (@pxref{Code Gen Options,, Options for Code Generation, gcc,
+Using the GNU Compiler Collection (GCC)}).
+
+This inserts special instrumenting calls at the start and end of each
+function, allowing exact timing and full call graph construction.
+
+This instrumenting is not normally a standard system feature and will require
+support from an external library, such as
+
+@cindex FunctionCheck
+@cindex fnccheck
+@display
+@uref{http://sourceforge.net/projects/fnccheck/}
+@end display
+
+This should be included in @samp{LIBS} during the GMP configure so that test
+programs will link. For example,
+
+@example
+./configure --enable-profiling=instrument LIBS=-lfc
+@end example
+
+On a GNU system the C library provides dummy instrumenting functions, so
+programs compiled with this option will link. In this case it's only
+necessary to ensure the correct library is added when linking an application.
+
+The x86 assembly code supports this option, but on other processors the
+assembly routines will be as if compiled without
+@samp{-finstrument-functions} meaning time spent in them will effectively be
+attributed to their caller.
+@end table
+
+
+@node Autoconf, Emacs, Profiling, GMP Basics
+@section Autoconf
+@cindex Autoconf
+
+Autoconf based applications can easily check whether GMP is installed. The
+only thing to be noted is that GMP library symbols from version 3 onwards have
+prefixes like @code{__gmpz}. The following therefore would be a simple test,
+
+@cindex @code{AC_CHECK_LIB}
+@example
+AC_CHECK_LIB(gmp, __gmpz_init)
+@end example
+
+This just uses the default @code{AC_CHECK_LIB} actions for found or not found,
+but an application that must have GMP would want to generate an error if not
+found. For example,
+
+@example
+AC_CHECK_LIB(gmp, __gmpz_init, ,
+ [AC_MSG_ERROR([GNU MP not found, see https://gmplib.org/])])
+@end example
+
+If functions added in some particular version of GMP are required, then one of
+those can be used when checking. For example @code{mpz_mul_si} was added in
+GMP 3.1,
+
+@example
+AC_CHECK_LIB(gmp, __gmpz_mul_si, ,
+ [AC_MSG_ERROR(
+ [GNU MP not found, or not 3.1 or up, see https://gmplib.org/])])
+@end example
+
+An alternative would be to test the version number in @file{gmp.h} using say
+@code{AC_EGREP_CPP}. That would make it possible to test the exact version,
+if some particular sub-minor release is known to be necessary.
+
+In general it's recommended that applications should simply demand a new
+enough GMP rather than trying to provide supplements for features not
+available in past versions.
+
+Occasionally an application will need or want to know the size of a type at
+configuration or preprocessing time, not just with @code{sizeof} in the code.
+This can be done in the normal way with @code{mp_limb_t} etc, but GMP 4.0 or
+up is best for this, since prior versions needed certain @samp{-D} defines on
+systems using a @code{long long} limb. The following would suit Autoconf 2.50
+or up,
+
+@example
+AC_CHECK_SIZEOF(mp_limb_t, , [#include <gmp.h>])
+@end example
+
+
+@node Emacs, , Autoconf, GMP Basics
+@section Emacs
+@cindex Emacs
+@cindex @code{info-lookup-symbol}
+
+@key{C-h C-i} (@code{info-lookup-symbol}) is a good way to find documentation
+on C functions while editing (@pxref{Info Lookup, , Info Documentation Lookup,
+emacs, The Emacs Editor}).
+
+The GMP manual can be included in such lookups by putting the following in
+your @file{.emacs},
+
+@c This isn't pretty, but there doesn't seem to be a better way (in emacs
+@c 21.2 at least). info-lookup->mode-value could be used for the "assoc"s,
+@c but that function isn't documented, whereas info-lookup-alist is.
+@c
+@example
+(eval-after-load "info-look"
+ '(let ((mode-value (assoc 'c-mode (assoc 'symbol info-lookup-alist))))
+ (setcar (nthcdr 3 mode-value)
+ (cons '("(gmp)Function Index" nil "^ -.* " "\\>")
+ (nth 3 mode-value)))))
+@end example
+
+
+@node Reporting Bugs, Integer Functions, GMP Basics, Top
+@comment node-name, next, previous, up
+@chapter Reporting Bugs
+@cindex Reporting bugs
+@cindex Bug reporting
+
+If you think you have found a bug in the GMP library, please investigate it
+and report it. We have made this library available to you, and it is not too
+much to ask you to report the bugs you find.
+
+Before you report a bug, check it's not already addressed in @ref{Known Build
+Problems}, or perhaps @ref{Notes for Particular Systems}. You may also want
+to check @uref{https://gmplib.org/} for patches for this release.
+
+Please include the following in any report,
+
+@itemize @bullet
+@item
+The GMP version number, and if pre-packaged or patched then say so.
+
+@item
+A test program that makes it possible for us to reproduce the bug. Include
+instructions on how to run the program.
+
+@item
+A description of what is wrong. If the results are incorrect, in what way.
+If you get a crash, say so.
+
+@item
+If you get a crash, include a stack backtrace from the debugger if it's
+informative (@samp{where} in @command{gdb}, or @samp{$C} in @command{adb}).
+
+@item
+Please do not send core dumps, executables or @command{strace}s.
+
+@item
+The @samp{configure} options you used when building GMP, if any.
+
+@item
+The output from @samp{configure}, as printed to stdout, with any options used.
+
+@item
+The name of the compiler and its version. For @command{gcc}, get the version
+with @samp{gcc -v}, otherwise perhaps @samp{what `which cc`}, or similar.
+
+@item
+The output from running @samp{uname -a}.
+
+@item
+The output from running @samp{./config.guess}, and from running
+@samp{./configfsf.guess} (might be the same).
+
+@item
+If the bug is related to @samp{configure}, then the compressed contents of
+@file{config.log}.
+
+@item
+If the bug is related to an @file{asm} file not assembling, then the contents
+of @file{config.m4} and the offending line or lines from the temporary
+@file{mpn/tmp-<file>.s}.
+@end itemize
+
+Please make an effort to produce a self-contained report, with something
+definite that can be tested or debugged. Vague queries or piecemeal messages
+are difficult to act on and don't help the development effort.
+
+It is not uncommon that an observed problem is actually due to a bug in the
+compiler; the GMP code tends to explore interesting corners in compilers.
+
+If your bug report is good, we will do our best to help you get a corrected
+version of the library; if the bug report is poor, we won't do anything about
+it (except maybe ask you to send a better report).
+
+Send your report to: @email{gmp-bugs@@gmplib.org}.
+
+If you think something in this manual is unclear, or downright incorrect, or if
+the language needs to be improved, please send a note to the same address.
+
+
+@node Integer Functions, Rational Number Functions, Reporting Bugs, Top
+@comment node-name, next, previous, up
+@chapter Integer Functions
+@cindex Integer functions
+
+This chapter describes the GMP functions for performing integer arithmetic.
+These functions start with the prefix @code{mpz_}.
+
+GMP integers are stored in objects of type @code{mpz_t}.
+
+@menu
+* Initializing Integers::
+* Assigning Integers::
+* Simultaneous Integer Init & Assign::
+* Converting Integers::
+* Integer Arithmetic::
+* Integer Division::
+* Integer Exponentiation::
+* Integer Roots::
+* Number Theoretic Functions::
+* Integer Comparisons::
+* Integer Logic and Bit Fiddling::
+* I/O of Integers::
+* Integer Random Numbers::
+* Integer Import and Export::
+* Miscellaneous Integer Functions::
+* Integer Special Functions::
+@end menu
+
+@node Initializing Integers, Assigning Integers, Integer Functions, Integer Functions
+@comment node-name, next, previous, up
+@section Initialization Functions
+@cindex Integer initialization functions
+@cindex Initialization functions
+
+The functions for integer arithmetic assume that all integer objects are
+initialized. You do that by calling the function @code{mpz_init}. For
+example,
+
+@example
+@{
+ mpz_t integ;
+ mpz_init (integ);
+ @dots{}
+ mpz_add (integ, @dots{});
+ @dots{}
+ mpz_sub (integ, @dots{});
+
+ /* Unless the program is about to exit, do ... */
+ mpz_clear (integ);
+@}
+@end example
+
+As you can see, you can store new values any number of times, once an
+object is initialized.
+
+@deftypefun void mpz_init (mpz_t @var{x})
+Initialize @var{x}, and set its value to 0.
+@end deftypefun
+
+@deftypefun void mpz_inits (mpz_t @var{x}, ...)
+Initialize a NULL-terminated list of @code{mpz_t} variables, and set their
+values to 0.
+@end deftypefun
+
+@deftypefun void mpz_init2 (mpz_t @var{x}, mp_bitcnt_t @var{n})
+Initialize @var{x}, with space for @var{n}-bit numbers, and set its value to 0.
+Calling this function instead of @code{mpz_init} or @code{mpz_inits} is never
+necessary; reallocation is handled automatically by GMP when needed.
+
+While @var{n} defines the initial space, @var{x} will grow automatically in the
+normal way, if necessary, for subsequent values stored. @code{mpz_init2} makes
+it possible to avoid such reallocations if a maximum size is known in advance.
+
+In preparation for an operation, GMP often allocates one limb more than
+ultimately needed. To make sure GMP will not perform reallocation for
+@var{x}, you need to add the number of bits in @code{mp_limb_t} to @var{n}.
+@end deftypefun
+
+@deftypefun void mpz_clear (mpz_t @var{x})
+Free the space occupied by @var{x}. Call this function for all @code{mpz_t}
+variables when you are done with them.
+@end deftypefun
+
+@deftypefun void mpz_clears (mpz_t @var{x}, ...)
+Free the space occupied by a NULL-terminated list of @code{mpz_t} variables.
+@end deftypefun
+
+@deftypefun void mpz_realloc2 (mpz_t @var{x}, mp_bitcnt_t @var{n})
+Change the space allocated for @var{x} to @var{n} bits. The value in @var{x}
+is preserved if it fits, or is set to 0 if not.
+
+Calling this function is never necessary; reallocation is handled automatically
+by GMP when needed. But this function can be used to increase the space for a
+variable in order to avoid repeated automatic reallocations, or to decrease it
+to give memory back to the heap.
+@end deftypefun
+
+
+@node Assigning Integers, Simultaneous Integer Init & Assign, Initializing Integers, Integer Functions
+@comment node-name, next, previous, up
+@section Assignment Functions
+@cindex Integer assignment functions
+@cindex Assignment functions
+
+These functions assign new values to already initialized integers
+(@pxref{Initializing Integers}).
+
+@deftypefun void mpz_set (mpz_t @var{rop}, const mpz_t @var{op})
+@deftypefunx void mpz_set_ui (mpz_t @var{rop}, unsigned long int @var{op})
+@deftypefunx void mpz_set_si (mpz_t @var{rop}, signed long int @var{op})
+@deftypefunx void mpz_set_d (mpz_t @var{rop}, double @var{op})
+@deftypefunx void mpz_set_q (mpz_t @var{rop}, const mpq_t @var{op})
+@deftypefunx void mpz_set_f (mpz_t @var{rop}, const mpf_t @var{op})
+Set the value of @var{rop} from @var{op}.
+
+@code{mpz_set_d}, @code{mpz_set_q} and @code{mpz_set_f} truncate @var{op} to
+make it an integer.
+@end deftypefun
+
+@deftypefun int mpz_set_str (mpz_t @var{rop}, const char *@var{str}, int @var{base})
+Set the value of @var{rop} from @var{str}, a null-terminated C string in base
+@var{base}. White space is allowed in the string, and is simply ignored.
+
+The @var{base} may vary from 2 to 62, or if @var{base} is 0, then the leading
+characters are used: @code{0x} and @code{0X} for hexadecimal, @code{0b} and
+@code{0B} for binary, @code{0} for octal, or decimal otherwise.
+
+For bases up to 36, case is ignored; upper-case and lower-case letters have
+the same value. For bases 37 to 62, upper-case letter represent the usual
+10..35 while lower-case letter represent 36..61.
+
+This function returns 0 if the entire string is a valid number in base
+@var{base}. Otherwise it returns @minus{}1.
+@c
+@c It turns out that it is not entirely true that this function ignores
+@c white-space. It does ignore it between digits, but not after a minus sign
+@c or within or after ``0x''. Some thought was given to disallowing all
+@c whitespace, but that would be an incompatible change, whitespace has been
+@c documented as ignored ever since GMP 1.
+@c
+@end deftypefun
+
+@deftypefun void mpz_swap (mpz_t @var{rop1}, mpz_t @var{rop2})
+Swap the values @var{rop1} and @var{rop2} efficiently.
+@end deftypefun
+
+
+@node Simultaneous Integer Init & Assign, Converting Integers, Assigning Integers, Integer Functions
+@comment node-name, next, previous, up
+@section Combined Initialization and Assignment Functions
+@cindex Integer assignment functions
+@cindex Assignment functions
+@cindex Integer initialization functions
+@cindex Initialization functions
+
+For convenience, GMP provides a parallel series of initialize-and-set functions
+which initialize the output and then store the value there. These functions'
+names have the form @code{mpz_init_set@dots{}}
+
+Here is an example of using one:
+
+@example
+@{
+ mpz_t pie;
+ mpz_init_set_str (pie, "3141592653589793238462643383279502884", 10);
+ @dots{}
+ mpz_sub (pie, @dots{});
+ @dots{}
+ mpz_clear (pie);
+@}
+@end example
+
+@noindent
+Once the integer has been initialized by any of the @code{mpz_init_set@dots{}}
+functions, it can be used as the source or destination operand for the ordinary
+integer functions. Don't use an initialize-and-set function on a variable
+already initialized!
+
+@deftypefun void mpz_init_set (mpz_t @var{rop}, const mpz_t @var{op})
+@deftypefunx void mpz_init_set_ui (mpz_t @var{rop}, unsigned long int @var{op})
+@deftypefunx void mpz_init_set_si (mpz_t @var{rop}, signed long int @var{op})
+@deftypefunx void mpz_init_set_d (mpz_t @var{rop}, double @var{op})
+Initialize @var{rop} with limb space and set the initial numeric value from
+@var{op}.
+@end deftypefun
+
+@deftypefun int mpz_init_set_str (mpz_t @var{rop}, const char *@var{str}, int @var{base})
+Initialize @var{rop} and set its value like @code{mpz_set_str} (see its
+documentation above for details).
+
+If the string is a correct base @var{base} number, the function returns 0;
+if an error occurs it returns @minus{}1. @var{rop} is initialized even if
+an error occurs. (I.e., you have to call @code{mpz_clear} for it.)
+@end deftypefun
+
+
+@node Converting Integers, Integer Arithmetic, Simultaneous Integer Init & Assign, Integer Functions
+@comment node-name, next, previous, up
+@section Conversion Functions
+@cindex Integer conversion functions
+@cindex Conversion functions
+
+This section describes functions for converting GMP integers to standard C
+types. Functions for converting @emph{to} GMP integers are described in
+@ref{Assigning Integers} and @ref{I/O of Integers}.
+
+@deftypefun {unsigned long int} mpz_get_ui (const mpz_t @var{op})
+Return the value of @var{op} as an @code{unsigned long}.
+
+If @var{op} is too big to fit an @code{unsigned long} then just the least
+significant bits that do fit are returned. The sign of @var{op} is ignored,
+only the absolute value is used.
+@end deftypefun
+
+@deftypefun {signed long int} mpz_get_si (const mpz_t @var{op})
+If @var{op} fits into a @code{signed long int} return the value of @var{op}.
+Otherwise return the least significant part of @var{op}, with the same sign
+as @var{op}.
+
+If @var{op} is too big to fit in a @code{signed long int}, the returned
+result is probably not very useful. To find out if the value will fit, use
+the function @code{mpz_fits_slong_p}.
+@end deftypefun
+
+@deftypefun double mpz_get_d (const mpz_t @var{op})
+Convert @var{op} to a @code{double}, truncating if necessary (i.e.@: rounding
+towards zero).
+
+If the exponent from the conversion is too big, the result is system
+dependent. An infinity is returned where available. A hardware overflow trap
+may or may not occur.
+@end deftypefun
+
+@deftypefun double mpz_get_d_2exp (signed long int *@var{exp}, const mpz_t @var{op})
+Convert @var{op} to a @code{double}, truncating if necessary (i.e.@: rounding
+towards zero), and returning the exponent separately.
+
+The return value is in the range @math{0.5@le{}@GMPabs{@var{d}}<1} and the
+exponent is stored to @code{*@var{exp}}. @m{@var{d} * 2^{exp}, @var{d} *
+2^@var{exp}} is the (truncated) @var{op} value. If @var{op} is zero, the
+return is @math{0.0} and 0 is stored to @code{*@var{exp}}.
+
+@cindex @code{frexp}
+This is similar to the standard C @code{frexp} function (@pxref{Normalization
+Functions,,, libc, The GNU C Library Reference Manual}).
+@end deftypefun
+
+@deftypefun {char *} mpz_get_str (char *@var{str}, int @var{base}, const mpz_t @var{op})
+Convert @var{op} to a string of digits in base @var{base}. The base argument
+may vary from 2 to 62 or from @minus{}2 to @minus{}36.
+
+For @var{base} in the range 2..36, digits and lower-case letters are used; for
+@minus{}2..@minus{}36, digits and upper-case letters are used; for 37..62,
+digits, upper-case letters, and lower-case letters (in that significance order)
+are used.
+
+If @var{str} is @code{NULL}, the result string is allocated using the current
+allocation function (@pxref{Custom Allocation}). The block will be
+@code{strlen(str)+1} bytes, that being exactly enough for the string and
+null-terminator.
+
+If @var{str} is not @code{NULL}, it should point to a block of storage large
+enough for the result, that being @code{mpz_sizeinbase (@var{op}, @var{base})
++ 2}. The two extra bytes are for a possible minus sign, and the
+null-terminator.
+
+A pointer to the result string is returned, being either the allocated block,
+or the given @var{str}.
+@end deftypefun
+
+
+@need 2000
+@node Integer Arithmetic, Integer Division, Converting Integers, Integer Functions
+@comment node-name, next, previous, up
+@section Arithmetic Functions
+@cindex Integer arithmetic functions
+@cindex Arithmetic functions
+
+@deftypefun void mpz_add (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+@deftypefunx void mpz_add_ui (mpz_t @var{rop}, const mpz_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @math{@var{op1} + @var{op2}}.
+@end deftypefun
+
+@deftypefun void mpz_sub (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+@deftypefunx void mpz_sub_ui (mpz_t @var{rop}, const mpz_t @var{op1}, unsigned long int @var{op2})
+@deftypefunx void mpz_ui_sub (mpz_t @var{rop}, unsigned long int @var{op1}, const mpz_t @var{op2})
+Set @var{rop} to @var{op1} @minus{} @var{op2}.
+@end deftypefun
+
+@deftypefun void mpz_mul (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+@deftypefunx void mpz_mul_si (mpz_t @var{rop}, const mpz_t @var{op1}, long int @var{op2})
+@deftypefunx void mpz_mul_ui (mpz_t @var{rop}, const mpz_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @math{@var{op1} @GMPtimes{} @var{op2}}.
+@end deftypefun
+
+@deftypefun void mpz_addmul (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+@deftypefunx void mpz_addmul_ui (mpz_t @var{rop}, const mpz_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @math{@var{rop} + @var{op1} @GMPtimes{} @var{op2}}.
+@end deftypefun
+
+@deftypefun void mpz_submul (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+@deftypefunx void mpz_submul_ui (mpz_t @var{rop}, const mpz_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @math{@var{rop} - @var{op1} @GMPtimes{} @var{op2}}.
+@end deftypefun
+
+@deftypefun void mpz_mul_2exp (mpz_t @var{rop}, const mpz_t @var{op1}, mp_bitcnt_t @var{op2})
+@cindex Bit shift left
+Set @var{rop} to @m{@var{op1} \times 2^{op2}, @var{op1} times 2 raised to
+@var{op2}}. This operation can also be defined as a left shift by @var{op2}
+bits.
+@end deftypefun
+
+@deftypefun void mpz_neg (mpz_t @var{rop}, const mpz_t @var{op})
+Set @var{rop} to @minus{}@var{op}.
+@end deftypefun
+
+@deftypefun void mpz_abs (mpz_t @var{rop}, const mpz_t @var{op})
+Set @var{rop} to the absolute value of @var{op}.
+@end deftypefun
+
+
+@need 2000
+@node Integer Division, Integer Exponentiation, Integer Arithmetic, Integer Functions
+@section Division Functions
+@cindex Integer division functions
+@cindex Division functions
+
+Division is undefined if the divisor is zero. Passing a zero divisor to the
+division or modulo functions (including the modular powering functions
+@code{mpz_powm} and @code{mpz_powm_ui}), will cause an intentional division by
+zero. This lets a program handle arithmetic exceptions in these functions the
+same way as for normal C @code{int} arithmetic.
+
+@c Separate deftypefun groups for cdiv, fdiv and tdiv produce a blank line
+@c between each, and seem to let tex do a better job of page breaks than an
+@c @sp 1 in the middle of one big set.
+
+@deftypefun void mpz_cdiv_q (mpz_t @var{q}, const mpz_t @var{n}, const mpz_t @var{d})
+@deftypefunx void mpz_cdiv_r (mpz_t @var{r}, const mpz_t @var{n}, const mpz_t @var{d})
+@deftypefunx void mpz_cdiv_qr (mpz_t @var{q}, mpz_t @var{r}, const mpz_t @var{n}, const mpz_t @var{d})
+@maybepagebreak
+@deftypefunx {unsigned long int} mpz_cdiv_q_ui (mpz_t @var{q}, const mpz_t @var{n}, @w{unsigned long int @var{d}})
+@deftypefunx {unsigned long int} mpz_cdiv_r_ui (mpz_t @var{r}, const mpz_t @var{n}, @w{unsigned long int @var{d}})
+@deftypefunx {unsigned long int} mpz_cdiv_qr_ui (mpz_t @var{q}, mpz_t @var{r}, @w{const mpz_t @var{n}}, @w{unsigned long int @var{d}})
+@deftypefunx {unsigned long int} mpz_cdiv_ui (const mpz_t @var{n}, @w{unsigned long int @var{d}})
+@maybepagebreak
+@deftypefunx void mpz_cdiv_q_2exp (mpz_t @var{q}, const mpz_t @var{n}, @w{mp_bitcnt_t @var{b}})
+@deftypefunx void mpz_cdiv_r_2exp (mpz_t @var{r}, const mpz_t @var{n}, @w{mp_bitcnt_t @var{b}})
+@end deftypefun
+
+@deftypefun void mpz_fdiv_q (mpz_t @var{q}, const mpz_t @var{n}, const mpz_t @var{d})
+@deftypefunx void mpz_fdiv_r (mpz_t @var{r}, const mpz_t @var{n}, const mpz_t @var{d})
+@deftypefunx void mpz_fdiv_qr (mpz_t @var{q}, mpz_t @var{r}, const mpz_t @var{n}, const mpz_t @var{d})
+@maybepagebreak
+@deftypefunx {unsigned long int} mpz_fdiv_q_ui (mpz_t @var{q}, const mpz_t @var{n}, @w{unsigned long int @var{d}})
+@deftypefunx {unsigned long int} mpz_fdiv_r_ui (mpz_t @var{r}, const mpz_t @var{n}, @w{unsigned long int @var{d}})
+@deftypefunx {unsigned long int} mpz_fdiv_qr_ui (mpz_t @var{q}, mpz_t @var{r}, @w{const mpz_t @var{n}}, @w{unsigned long int @var{d}})
+@deftypefunx {unsigned long int} mpz_fdiv_ui (const mpz_t @var{n}, @w{unsigned long int @var{d}})
+@maybepagebreak
+@deftypefunx void mpz_fdiv_q_2exp (mpz_t @var{q}, const mpz_t @var{n}, @w{mp_bitcnt_t @var{b}})
+@deftypefunx void mpz_fdiv_r_2exp (mpz_t @var{r}, const mpz_t @var{n}, @w{mp_bitcnt_t @var{b}})
+@end deftypefun
+
+@deftypefun void mpz_tdiv_q (mpz_t @var{q}, const mpz_t @var{n}, const mpz_t @var{d})
+@deftypefunx void mpz_tdiv_r (mpz_t @var{r}, const mpz_t @var{n}, const mpz_t @var{d})
+@deftypefunx void mpz_tdiv_qr (mpz_t @var{q}, mpz_t @var{r}, const mpz_t @var{n}, const mpz_t @var{d})
+@maybepagebreak
+@deftypefunx {unsigned long int} mpz_tdiv_q_ui (mpz_t @var{q}, const mpz_t @var{n}, @w{unsigned long int @var{d}})
+@deftypefunx {unsigned long int} mpz_tdiv_r_ui (mpz_t @var{r}, const mpz_t @var{n}, @w{unsigned long int @var{d}})
+@deftypefunx {unsigned long int} mpz_tdiv_qr_ui (mpz_t @var{q}, mpz_t @var{r}, @w{const mpz_t @var{n}}, @w{unsigned long int @var{d}})
+@deftypefunx {unsigned long int} mpz_tdiv_ui (const mpz_t @var{n}, @w{unsigned long int @var{d}})
+@maybepagebreak
+@deftypefunx void mpz_tdiv_q_2exp (mpz_t @var{q}, const mpz_t @var{n}, @w{mp_bitcnt_t @var{b}})
+@deftypefunx void mpz_tdiv_r_2exp (mpz_t @var{r}, const mpz_t @var{n}, @w{mp_bitcnt_t @var{b}})
+@cindex Bit shift right
+
+@sp 1
+Divide @var{n} by @var{d}, forming a quotient @var{q} and/or remainder
+@var{r}. For the @code{2exp} functions, @m{@var{d}=2^b, @var{d}=2^@var{b}}.
+The rounding is in three styles, each suiting different applications.
+
+@itemize @bullet
+@item
+@code{cdiv} rounds @var{q} up towards @m{+\infty, +infinity}, and @var{r} will
+have the opposite sign to @var{d}. The @code{c} stands for ``ceil''.
+
+@item
+@code{fdiv} rounds @var{q} down towards @m{-\infty, @minus{}infinity}, and
+@var{r} will have the same sign as @var{d}. The @code{f} stands for
+``floor''.
+
+@item
+@code{tdiv} rounds @var{q} towards zero, and @var{r} will have the same sign
+as @var{n}. The @code{t} stands for ``truncate''.
+@end itemize
+
+In all cases @var{q} and @var{r} will satisfy
+@m{@var{n}=@var{q}@var{d}+@var{r}, @var{n}=@var{q}*@var{d}+@var{r}}, and
+@var{r} will satisfy @math{0@le{}@GMPabs{@var{r}}<@GMPabs{@var{d}}}.
+
+The @code{q} functions calculate only the quotient, the @code{r} functions
+only the remainder, and the @code{qr} functions calculate both. Note that for
+@code{qr} the same variable cannot be passed for both @var{q} and @var{r}, or
+results will be unpredictable.
+
+For the @code{ui} variants the return value is the remainder, and in fact
+returning the remainder is all the @code{div_ui} functions do. For
+@code{tdiv} and @code{cdiv} the remainder can be negative, so for those the
+return value is the absolute value of the remainder.
+
+For the @code{2exp} variants the divisor is @m{2^b,2^@var{b}}. These
+functions are implemented as right shifts and bit masks, but of course they
+round the same as the other functions.
+
+For positive @var{n} both @code{mpz_fdiv_q_2exp} and @code{mpz_tdiv_q_2exp}
+are simple bitwise right shifts. For negative @var{n}, @code{mpz_fdiv_q_2exp}
+is effectively an arithmetic right shift treating @var{n} as twos complement
+the same as the bitwise logical functions do, whereas @code{mpz_tdiv_q_2exp}
+effectively treats @var{n} as sign and magnitude.
+@end deftypefun
+
+@deftypefun void mpz_mod (mpz_t @var{r}, const mpz_t @var{n}, const mpz_t @var{d})
+@deftypefunx {unsigned long int} mpz_mod_ui (mpz_t @var{r}, const mpz_t @var{n}, @w{unsigned long int @var{d}})
+Set @var{r} to @var{n} @code{mod} @var{d}. The sign of the divisor is
+ignored; the result is always non-negative.
+
+@code{mpz_mod_ui} is identical to @code{mpz_fdiv_r_ui} above, returning the
+remainder as well as setting @var{r}. See @code{mpz_fdiv_ui} above if only
+the return value is wanted.
+@end deftypefun
+
+@deftypefun void mpz_divexact (mpz_t @var{q}, const mpz_t @var{n}, const mpz_t @var{d})
+@deftypefunx void mpz_divexact_ui (mpz_t @var{q}, const mpz_t @var{n}, unsigned long @var{d})
+@cindex Exact division functions
+Set @var{q} to @var{n}/@var{d}. These functions produce correct results only
+when it is known in advance that @var{d} divides @var{n}.
+
+These routines are much faster than the other division functions, and are the
+best choice when exact division is known to occur, for example reducing a
+rational to lowest terms.
+@end deftypefun
+
+@deftypefun int mpz_divisible_p (const mpz_t @var{n}, const mpz_t @var{d})
+@deftypefunx int mpz_divisible_ui_p (const mpz_t @var{n}, unsigned long int @var{d})
+@deftypefunx int mpz_divisible_2exp_p (const mpz_t @var{n}, mp_bitcnt_t @var{b})
+@cindex Divisibility functions
+Return non-zero if @var{n} is exactly divisible by @var{d}, or in the case of
+@code{mpz_divisible_2exp_p} by @m{2^b,2^@var{b}}.
+
+@var{n} is divisible by @var{d} if there exists an integer @var{q} satisfying
+@math{@var{n} = @var{q}@GMPmultiply{}@var{d}}. Unlike the other division
+functions, @math{@var{d}=0} is accepted and following the rule it can be seen
+that only 0 is considered divisible by 0.
+@end deftypefun
+
+@deftypefun int mpz_congruent_p (const mpz_t @var{n}, const mpz_t @var{c}, const mpz_t @var{d})
+@deftypefunx int mpz_congruent_ui_p (const mpz_t @var{n}, unsigned long int @var{c}, unsigned long int @var{d})
+@deftypefunx int mpz_congruent_2exp_p (const mpz_t @var{n}, const mpz_t @var{c}, mp_bitcnt_t @var{b})
+@cindex Divisibility functions
+@cindex Congruence functions
+Return non-zero if @var{n} is congruent to @var{c} modulo @var{d}, or in the
+case of @code{mpz_congruent_2exp_p} modulo @m{2^b,2^@var{b}}.
+
+@var{n} is congruent to @var{c} mod @var{d} if there exists an integer @var{q}
+satisfying @math{@var{n} = @var{c} + @var{q}@GMPmultiply{}@var{d}}. Unlike
+the other division functions, @math{@var{d}=0} is accepted and following the
+rule it can be seen that @var{n} and @var{c} are considered congruent mod 0
+only when exactly equal.
+@end deftypefun
+
+
+@need 2000
+@node Integer Exponentiation, Integer Roots, Integer Division, Integer Functions
+@section Exponentiation Functions
+@cindex Integer exponentiation functions
+@cindex Exponentiation functions
+@cindex Powering functions
+
+@deftypefun void mpz_powm (mpz_t @var{rop}, const mpz_t @var{base}, const mpz_t @var{exp}, const mpz_t @var{mod})
+@deftypefunx void mpz_powm_ui (mpz_t @var{rop}, const mpz_t @var{base}, unsigned long int @var{exp}, const mpz_t @var{mod})
+Set @var{rop} to @m{base^{exp} \bmod mod, (@var{base} raised to @var{exp})
+modulo @var{mod}}.
+
+Negative @var{exp} is supported if an inverse @math{@var{base}^@W{-1} @bmod
+@var{mod}} exists (see @code{mpz_invert} in @ref{Number Theoretic Functions}).
+If an inverse doesn't exist then a divide by zero is raised.
+@end deftypefun
+
+@deftypefun void mpz_powm_sec (mpz_t @var{rop}, const mpz_t @var{base}, const mpz_t @var{exp}, const mpz_t @var{mod})
+Set @var{rop} to @m{base^{exp} \bmod @var{mod}, (@var{base} raised to @var{exp})
+modulo @var{mod}}.
+
+It is required that @math{@var{exp} > 0} and that @var{mod} is odd.
+
+This function is designed to take the same time and have the same cache access
+patterns for any two same-size arguments, assuming that function arguments are
+placed at the same position and that the machine state is identical upon
+function entry. This function is intended for cryptographic purposes, where
+resilience to side-channel attacks is desired.
+@end deftypefun
+
+@deftypefun void mpz_pow_ui (mpz_t @var{rop}, const mpz_t @var{base}, unsigned long int @var{exp})
+@deftypefunx void mpz_ui_pow_ui (mpz_t @var{rop}, unsigned long int @var{base}, unsigned long int @var{exp})
+Set @var{rop} to @m{base^{exp}, @var{base} raised to @var{exp}}. The case
+@math{0^0} yields 1.
+@end deftypefun
+
+
+@need 2000
+@node Integer Roots, Number Theoretic Functions, Integer Exponentiation, Integer Functions
+@section Root Extraction Functions
+@cindex Integer root functions
+@cindex Root extraction functions
+
+@deftypefun int mpz_root (mpz_t @var{rop}, const mpz_t @var{op}, unsigned long int @var{n})
+Set @var{rop} to @m{\lfloor\root n \of {op}\rfloor@C{},} the truncated integer
+part of the @var{n}th root of @var{op}. Return non-zero if the computation
+was exact, i.e., if @var{op} is @var{rop} to the @var{n}th power.
+@end deftypefun
+
+@deftypefun void mpz_rootrem (mpz_t @var{root}, mpz_t @var{rem}, const mpz_t @var{u}, unsigned long int @var{n})
+Set @var{root} to @m{\lfloor\root n \of {u}\rfloor@C{},} the truncated
+integer part of the @var{n}th root of @var{u}. Set @var{rem} to the
+remainder, @m{(@var{u} - @var{root}^n),
+@var{u}@minus{}@var{root}**@var{n}}.
+@end deftypefun
+
+@deftypefun void mpz_sqrt (mpz_t @var{rop}, const mpz_t @var{op})
+Set @var{rop} to @m{\lfloor\sqrt{@var{op}}\rfloor@C{},} the truncated
+integer part of the square root of @var{op}.
+@end deftypefun
+
+@deftypefun void mpz_sqrtrem (mpz_t @var{rop1}, mpz_t @var{rop2}, const mpz_t @var{op})
+Set @var{rop1} to @m{\lfloor\sqrt{@var{op}}\rfloor, the truncated integer part
+of the square root of @var{op}}, like @code{mpz_sqrt}. Set @var{rop2} to the
+remainder @m{(@var{op} - @var{rop1}^2),
+@var{op}@minus{}@var{rop1}*@var{rop1}}, which will be zero if @var{op} is a
+perfect square.
+
+If @var{rop1} and @var{rop2} are the same variable, the results are
+undefined.
+@end deftypefun
+
+@deftypefun int mpz_perfect_power_p (const mpz_t @var{op})
+@cindex Perfect power functions
+@cindex Root testing functions
+Return non-zero if @var{op} is a perfect power, i.e., if there exist integers
+@m{a,@var{a}} and @m{b,@var{b}}, with @m{b>1, @var{b}>1}, such that
+@m{@var{op}=a^b, @var{op} equals @var{a} raised to the power @var{b}}.
+
+Under this definition both 0 and 1 are considered to be perfect powers.
+Negative values of @var{op} are accepted, but of course can only be odd
+perfect powers.
+@end deftypefun
+
+@deftypefun int mpz_perfect_square_p (const mpz_t @var{op})
+@cindex Perfect square functions
+@cindex Root testing functions
+Return non-zero if @var{op} is a perfect square, i.e., if the square root of
+@var{op} is an integer. Under this definition both 0 and 1 are considered to
+be perfect squares.
+@end deftypefun
+
+
+@need 2000
+@node Number Theoretic Functions, Integer Comparisons, Integer Roots, Integer Functions
+@section Number Theoretic Functions
+@cindex Number theoretic functions
+
+@deftypefun int mpz_probab_prime_p (const mpz_t @var{n}, int @var{reps})
+@cindex Prime testing functions
+@cindex Probable prime testing functions
+Determine whether @var{n} is prime. Return 2 if @var{n} is definitely prime,
+return 1 if @var{n} is probably prime (without being certain), or return 0 if
+@var{n} is definitely composite.
+
+This function does some trial divisions, then some Miller-Rabin probabilistic
+primality tests. The argument @var{reps} controls how many such tests are
+done; a higher value will reduce the chances of a composite being returned as
+``probably prime''. 25 is a reasonable number; a composite number will then be
+identified as a prime with a probability of less than @m{2^{-50},2^(-50)}.
+
+Miller-Rabin and similar tests can be more properly called compositeness
+tests. Numbers which fail are known to be composite but those which pass
+might be prime or might be composite. Only a few composites pass, hence those
+which pass are considered probably prime.
+@end deftypefun
+
+@deftypefun void mpz_nextprime (mpz_t @var{rop}, const mpz_t @var{op})
+@cindex Next prime function
+Set @var{rop} to the next prime greater than @var{op}.
+
+This function uses a probabilistic algorithm to identify primes. For
+practical purposes it's adequate, the chance of a composite passing will be
+extremely small.
+@end deftypefun
+
+@c mpz_prime_p not implemented as of gmp 3.0.
+
+@c @deftypefun int mpz_prime_p (const mpz_t @var{n})
+@c Return non-zero if @var{n} is prime and zero if @var{n} is a non-prime.
+@c This function is far slower than @code{mpz_probab_prime_p}, but then it
+@c never returns non-zero for composite numbers.
+
+@c (For practical purposes, using @code{mpz_probab_prime_p} is adequate.
+@c The likelihood of a programming error or hardware malfunction is orders
+@c of magnitudes greater than the likelihood for a composite to pass as a
+@c prime, if the @var{reps} argument is in the suggested range.)
+@c @end deftypefun
+
+@deftypefun void mpz_gcd (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+@cindex Greatest common divisor functions
+@cindex GCD functions
+Set @var{rop} to the greatest common divisor of @var{op1} and @var{op2}. The
+result is always positive even if one or both input operands are negative.
+Except if both inputs are zero; then this function defines @math{gcd(0,0) = 0}.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpz_gcd_ui (mpz_t @var{rop}, const mpz_t @var{op1}, unsigned long int @var{op2})
+Compute the greatest common divisor of @var{op1} and @var{op2}. If
+@var{rop} is not @code{NULL}, store the result there.
+
+If the result is small enough to fit in an @code{unsigned long int}, it is
+returned. If the result does not fit, 0 is returned, and the result is equal
+to the argument @var{op1}. Note that the result will always fit if @var{op2}
+is non-zero.
+@end deftypefun
+
+@deftypefun void mpz_gcdext (mpz_t @var{g}, mpz_t @var{s}, mpz_t @var{t}, const mpz_t @var{a}, const mpz_t @var{b})
+@cindex Extended GCD
+@cindex GCD extended
+Set @var{g} to the greatest common divisor of @var{a} and @var{b}, and in
+addition set @var{s} and @var{t} to coefficients satisfying
+@math{@var{a}@GMPmultiply{}@var{s} + @var{b}@GMPmultiply{}@var{t} = @var{g}}.
+The value in @var{g} is always positive, even if one or both of @var{a} and
+@var{b} are negative (or zero if both inputs are zero). The values in @var{s}
+and @var{t} are chosen such that normally, @math{@GMPabs{@var{s}} <
+@GMPabs{@var{b}} / (2 @var{g})} and @math{@GMPabs{@var{t}} < @GMPabs{@var{a}}
+/ (2 @var{g})}, and these relations define @var{s} and @var{t} uniquely. There
+are a few exceptional cases:
+
+If @math{@GMPabs{@var{a}} = @GMPabs{@var{b}}}, then @math{@var{s} = 0},
+@math{@var{t} = sgn(@var{b})}.
+
+Otherwise, @math{@var{s} = sgn(@var{a})} if @math{@var{b} = 0} or
+@math{@GMPabs{@var{b}} = 2 @var{g}}, and @math{@var{t} = sgn(@var{b})} if
+@math{@var{a} = 0} or @math{@GMPabs{@var{a}} = 2 @var{g}}.
+
+In all cases, @math{@var{s} = 0} if and only if @math{@var{g} =
+@GMPabs{@var{b}}}, i.e., if @var{b} divides @var{a} or @math{@var{a} = @var{b}
+= 0}.
+
+If @var{t} is @code{NULL} then that value is not computed.
+@end deftypefun
+
+@deftypefun void mpz_lcm (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+@deftypefunx void mpz_lcm_ui (mpz_t @var{rop}, const mpz_t @var{op1}, unsigned long @var{op2})
+@cindex Least common multiple functions
+@cindex LCM functions
+Set @var{rop} to the least common multiple of @var{op1} and @var{op2}.
+@var{rop} is always positive, irrespective of the signs of @var{op1} and
+@var{op2}. @var{rop} will be zero if either @var{op1} or @var{op2} is zero.
+@end deftypefun
+
+@deftypefun int mpz_invert (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+@cindex Modular inverse functions
+@cindex Inverse modulo functions
+Compute the inverse of @var{op1} modulo @var{op2} and put the result in
+@var{rop}. If the inverse exists, the return value is non-zero and @var{rop}
+will satisfy @math{0 < @var{rop} < @GMPabs{@var{op2}}}. If an inverse doesn't
+exist the return value is zero and @var{rop} is undefined. The behaviour of
+this function is undefined when @var{op2} is zero.
+@end deftypefun
+
+@deftypefun int mpz_jacobi (const mpz_t @var{a}, const mpz_t @var{b})
+@cindex Jacobi symbol functions
+Calculate the Jacobi symbol @m{\left(a \over b\right),
+(@var{a}/@var{b})}. This is defined only for @var{b} odd.
+@end deftypefun
+
+@deftypefun int mpz_legendre (const mpz_t @var{a}, const mpz_t @var{p})
+@cindex Legendre symbol functions
+Calculate the Legendre symbol @m{\left(a \over p\right),
+(@var{a}/@var{p})}. This is defined only for @var{p} an odd positive
+prime, and for such @var{p} it's identical to the Jacobi symbol.
+@end deftypefun
+
+@deftypefun int mpz_kronecker (const mpz_t @var{a}, const mpz_t @var{b})
+@deftypefunx int mpz_kronecker_si (const mpz_t @var{a}, long @var{b})
+@deftypefunx int mpz_kronecker_ui (const mpz_t @var{a}, unsigned long @var{b})
+@deftypefunx int mpz_si_kronecker (long @var{a}, const mpz_t @var{b})
+@deftypefunx int mpz_ui_kronecker (unsigned long @var{a}, const mpz_t @var{b})
+@cindex Kronecker symbol functions
+Calculate the Jacobi symbol @m{\left(a \over b\right),
+(@var{a}/@var{b})} with the Kronecker extension @m{\left(a \over
+2\right) = \left(2 \over a\right), (a/2)=(2/a)} when @math{a} odd, or
+@m{\left(a \over 2\right) = 0, (a/2)=0} when @math{a} even.
+
+When @var{b} is odd the Jacobi symbol and Kronecker symbol are
+identical, so @code{mpz_kronecker_ui} etc can be used for mixed
+precision Jacobi symbols too.
+
+For more information see Henri Cohen section 1.4.2 (@pxref{References}),
+or any number theory textbook. See also the example program
+@file{demos/qcn.c} which uses @code{mpz_kronecker_ui}.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpz_remove (mpz_t @var{rop}, const mpz_t @var{op}, const mpz_t @var{f})
+@cindex Remove factor functions
+@cindex Factor removal functions
+Remove all occurrences of the factor @var{f} from @var{op} and store the
+result in @var{rop}. The return value is how many such occurrences were
+removed.
+@end deftypefun
+
+@deftypefun void mpz_fac_ui (mpz_t @var{rop}, unsigned long int @var{n})
+@deftypefunx void mpz_2fac_ui (mpz_t @var{rop}, unsigned long int @var{n})
+@deftypefunx void mpz_mfac_uiui (mpz_t @var{rop}, unsigned long int @var{n}, unsigned long int @var{m})
+@cindex Factorial functions
+Set @var{rop} to the factorial of @var{n}: @code{mpz_fac_ui} computes the plain factorial @var{n}!,
+@code{mpz_2fac_ui} computes the double-factorial @var{n}!!, and @code{mpz_mfac_uiui} the
+@var{m}-multi-factorial @m{n!^{(m)}, @var{n}!^(@var{m})}.
+@end deftypefun
+
+@deftypefun void mpz_primorial_ui (mpz_t @var{rop}, unsigned long int @var{n})
+@cindex Primorial functions
+Set @var{rop} to the primorial of @var{n}, i.e. the product of all positive
+prime numbers @math{@le{}@var{n}}.
+@end deftypefun
+
+@deftypefun void mpz_bin_ui (mpz_t @var{rop}, const mpz_t @var{n}, unsigned long int @var{k})
+@deftypefunx void mpz_bin_uiui (mpz_t @var{rop}, unsigned long int @var{n}, @w{unsigned long int @var{k}})
+@cindex Binomial coefficient functions
+Compute the binomial coefficient @m{\left({n}\atop{k}\right), @var{n} over
+@var{k}} and store the result in @var{rop}. Negative values of @var{n} are
+supported by @code{mpz_bin_ui}, using the identity
+@m{\left({-n}\atop{k}\right) = (-1)^k \left({n+k-1}\atop{k}\right),
+bin(-n@C{}k) = (-1)^k * bin(n+k-1@C{}k)}, see Knuth volume 1 section 1.2.6
+part G.
+@end deftypefun
+
+@deftypefun void mpz_fib_ui (mpz_t @var{fn}, unsigned long int @var{n})
+@deftypefunx void mpz_fib2_ui (mpz_t @var{fn}, mpz_t @var{fnsub1}, unsigned long int @var{n})
+@cindex Fibonacci sequence functions
+@code{mpz_fib_ui} sets @var{fn} to to @m{F_n,F[n]}, the @var{n}'th Fibonacci
+number. @code{mpz_fib2_ui} sets @var{fn} to @m{F_n,F[n]}, and @var{fnsub1} to
+@m{F_{n-1},F[n-1]}.
+
+These functions are designed for calculating isolated Fibonacci numbers. When
+a sequence of values is wanted it's best to start with @code{mpz_fib2_ui} and
+iterate the defining @m{F_{n+1} = F_n + F_{n-1}, F[n+1]=F[n]+F[n-1]} or
+similar.
+@end deftypefun
+
+@deftypefun void mpz_lucnum_ui (mpz_t @var{ln}, unsigned long int @var{n})
+@deftypefunx void mpz_lucnum2_ui (mpz_t @var{ln}, mpz_t @var{lnsub1}, unsigned long int @var{n})
+@cindex Lucas number functions
+@code{mpz_lucnum_ui} sets @var{ln} to to @m{L_n,L[n]}, the @var{n}'th Lucas
+number. @code{mpz_lucnum2_ui} sets @var{ln} to @m{L_n,L[n]}, and @var{lnsub1}
+to @m{L_{n-1},L[n-1]}.
+
+These functions are designed for calculating isolated Lucas numbers. When a
+sequence of values is wanted it's best to start with @code{mpz_lucnum2_ui} and
+iterate the defining @m{L_{n+1} = L_n + L_{n-1}, L[n+1]=L[n]+L[n-1]} or
+similar.
+
+The Fibonacci numbers and Lucas numbers are related sequences, so it's never
+necessary to call both @code{mpz_fib2_ui} and @code{mpz_lucnum2_ui}. The
+formulas for going from Fibonacci to Lucas can be found in @ref{Lucas Numbers
+Algorithm}, the reverse is straightforward too.
+@end deftypefun
+
+
+@node Integer Comparisons, Integer Logic and Bit Fiddling, Number Theoretic Functions, Integer Functions
+@comment node-name, next, previous, up
+@section Comparison Functions
+@cindex Integer comparison functions
+@cindex Comparison functions
+
+@deftypefn Function int mpz_cmp (const mpz_t @var{op1}, const mpz_t @var{op2})
+@deftypefnx Function int mpz_cmp_d (const mpz_t @var{op1}, double @var{op2})
+@deftypefnx Macro int mpz_cmp_si (const mpz_t @var{op1}, signed long int @var{op2})
+@deftypefnx Macro int mpz_cmp_ui (const mpz_t @var{op1}, unsigned long int @var{op2})
+Compare @var{op1} and @var{op2}. Return a positive value if @math{@var{op1} >
+@var{op2}}, zero if @math{@var{op1} = @var{op2}}, or a negative value if
+@math{@var{op1} < @var{op2}}.
+
+@code{mpz_cmp_ui} and @code{mpz_cmp_si} are macros and will evaluate their
+arguments more than once. @code{mpz_cmp_d} can be called with an infinity,
+but results are undefined for a NaN.
+@end deftypefn
+
+@deftypefn Function int mpz_cmpabs (const mpz_t @var{op1}, const mpz_t @var{op2})
+@deftypefnx Function int mpz_cmpabs_d (const mpz_t @var{op1}, double @var{op2})
+@deftypefnx Function int mpz_cmpabs_ui (const mpz_t @var{op1}, unsigned long int @var{op2})
+Compare the absolute values of @var{op1} and @var{op2}. Return a positive
+value if @math{@GMPabs{@var{op1}} > @GMPabs{@var{op2}}}, zero if
+@math{@GMPabs{@var{op1}} = @GMPabs{@var{op2}}}, or a negative value if
+@math{@GMPabs{@var{op1}} < @GMPabs{@var{op2}}}.
+
+@code{mpz_cmpabs_d} can be called with an infinity, but results are undefined
+for a NaN.
+@end deftypefn
+
+@deftypefn Macro int mpz_sgn (const mpz_t @var{op})
+@cindex Sign tests
+@cindex Integer sign tests
+Return @math{+1} if @math{@var{op} > 0}, 0 if @math{@var{op} = 0}, and
+@math{-1} if @math{@var{op} < 0}.
+
+This function is actually implemented as a macro. It evaluates its argument
+multiple times.
+@end deftypefn
+
+
+@node Integer Logic and Bit Fiddling, I/O of Integers, Integer Comparisons, Integer Functions
+@comment node-name, next, previous, up
+@section Logical and Bit Manipulation Functions
+@cindex Logical functions
+@cindex Bit manipulation functions
+@cindex Integer logical functions
+@cindex Integer bit manipulation functions
+
+These functions behave as if twos complement arithmetic were used (although
+sign-magnitude is the actual implementation). The least significant bit is
+number 0.
+
+@deftypefun void mpz_and (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+Set @var{rop} to @var{op1} bitwise-and @var{op2}.
+@end deftypefun
+
+@deftypefun void mpz_ior (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+Set @var{rop} to @var{op1} bitwise inclusive-or @var{op2}.
+@end deftypefun
+
+@deftypefun void mpz_xor (mpz_t @var{rop}, const mpz_t @var{op1}, const mpz_t @var{op2})
+Set @var{rop} to @var{op1} bitwise exclusive-or @var{op2}.
+@end deftypefun
+
+@deftypefun void mpz_com (mpz_t @var{rop}, const mpz_t @var{op})
+Set @var{rop} to the one's complement of @var{op}.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpz_popcount (const mpz_t @var{op})
+If @math{@var{op}@ge{}0}, return the population count of @var{op}, which is the
+number of 1 bits in the binary representation. If @math{@var{op}<0}, the
+number of 1s is infinite, and the return value is the largest possible
+@code{mp_bitcnt_t}.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpz_hamdist (const mpz_t @var{op1}, const mpz_t @var{op2})
+If @var{op1} and @var{op2} are both @math{@ge{}0} or both @math{<0}, return the
+hamming distance between the two operands, which is the number of bit positions
+where @var{op1} and @var{op2} have different bit values. If one operand is
+@math{@ge{}0} and the other @math{<0} then the number of bits different is
+infinite, and the return value is the largest possible @code{mp_bitcnt_t}.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpz_scan0 (const mpz_t @var{op}, mp_bitcnt_t @var{starting_bit})
+@deftypefunx {mp_bitcnt_t} mpz_scan1 (const mpz_t @var{op}, mp_bitcnt_t @var{starting_bit})
+@cindex Bit scanning functions
+@cindex Scan bit functions
+Scan @var{op}, starting from bit @var{starting_bit}, towards more significant
+bits, until the first 0 or 1 bit (respectively) is found. Return the index of
+the found bit.
+
+If the bit at @var{starting_bit} is already what's sought, then
+@var{starting_bit} is returned.
+
+If there's no bit found, then the largest possible @code{mp_bitcnt_t} is
+returned. This will happen in @code{mpz_scan0} past the end of a negative
+number, or @code{mpz_scan1} past the end of a nonnegative number.
+@end deftypefun
+
+@deftypefun void mpz_setbit (mpz_t @var{rop}, mp_bitcnt_t @var{bit_index})
+Set bit @var{bit_index} in @var{rop}.
+@end deftypefun
+
+@deftypefun void mpz_clrbit (mpz_t @var{rop}, mp_bitcnt_t @var{bit_index})
+Clear bit @var{bit_index} in @var{rop}.
+@end deftypefun
+
+@deftypefun void mpz_combit (mpz_t @var{rop}, mp_bitcnt_t @var{bit_index})
+Complement bit @var{bit_index} in @var{rop}.
+@end deftypefun
+
+@deftypefun int mpz_tstbit (const mpz_t @var{op}, mp_bitcnt_t @var{bit_index})
+Test bit @var{bit_index} in @var{op} and return 0 or 1 accordingly.
+@end deftypefun
+
+@node I/O of Integers, Integer Random Numbers, Integer Logic and Bit Fiddling, Integer Functions
+@comment node-name, next, previous, up
+@section Input and Output Functions
+@cindex Integer input and output functions
+@cindex Input functions
+@cindex Output functions
+@cindex I/O functions
+
+Functions that perform input from a stdio stream, and functions that output to
+a stdio stream, of @code{mpz} numbers. Passing a @code{NULL} pointer for a
+@var{stream} argument to any of these functions will make them read from
+@code{stdin} and write to @code{stdout}, respectively.
+
+When using any of these functions, it is a good idea to include @file{stdio.h}
+before @file{gmp.h}, since that will allow @file{gmp.h} to define prototypes
+for these functions.
+
+See also @ref{Formatted Output} and @ref{Formatted Input}.
+
+@deftypefun size_t mpz_out_str (FILE *@var{stream}, int @var{base}, const mpz_t @var{op})
+Output @var{op} on stdio stream @var{stream}, as a string of digits in base
+@var{base}. The base argument may vary from 2 to 62 or from @minus{}2 to
+@minus{}36.
+
+For @var{base} in the range 2..36, digits and lower-case letters are used; for
+@minus{}2..@minus{}36, digits and upper-case letters are used; for 37..62,
+digits, upper-case letters, and lower-case letters (in that significance order)
+are used.
+
+Return the number of bytes written, or if an error occurred, return 0.
+@end deftypefun
+
+@deftypefun size_t mpz_inp_str (mpz_t @var{rop}, FILE *@var{stream}, int @var{base})
+Input a possibly white-space preceded string in base @var{base} from stdio
+stream @var{stream}, and put the read integer in @var{rop}.
+
+The @var{base} may vary from 2 to 62, or if @var{base} is 0, then the leading
+characters are used: @code{0x} and @code{0X} for hexadecimal, @code{0b} and
+@code{0B} for binary, @code{0} for octal, or decimal otherwise.
+
+For bases up to 36, case is ignored; upper-case and lower-case letters have
+the same value. For bases 37 to 62, upper-case letter represent the usual
+10..35 while lower-case letter represent 36..61.
+
+Return the number of bytes read, or if an error occurred, return 0.
+@end deftypefun
+
+@deftypefun size_t mpz_out_raw (FILE *@var{stream}, const mpz_t @var{op})
+Output @var{op} on stdio stream @var{stream}, in raw binary format. The
+integer is written in a portable format, with 4 bytes of size information, and
+that many bytes of limbs. Both the size and the limbs are written in
+decreasing significance order (i.e., in big-endian).
+
+The output can be read with @code{mpz_inp_raw}.
+
+Return the number of bytes written, or if an error occurred, return 0.
+
+The output of this can not be read by @code{mpz_inp_raw} from GMP 1, because
+of changes necessary for compatibility between 32-bit and 64-bit machines.
+@end deftypefun
+
+@deftypefun size_t mpz_inp_raw (mpz_t @var{rop}, FILE *@var{stream})
+Input from stdio stream @var{stream} in the format written by
+@code{mpz_out_raw}, and put the result in @var{rop}. Return the number of
+bytes read, or if an error occurred, return 0.
+
+This routine can read the output from @code{mpz_out_raw} also from GMP 1, in
+spite of changes necessary for compatibility between 32-bit and 64-bit
+machines.
+@end deftypefun
+
+
+@need 2000
+@node Integer Random Numbers, Integer Import and Export, I/O of Integers, Integer Functions
+@comment node-name, next, previous, up
+@section Random Number Functions
+@cindex Integer random number functions
+@cindex Random number functions
+
+The random number functions of GMP come in two groups; older function
+that rely on a global state, and newer functions that accept a state
+parameter that is read and modified. Please see the @ref{Random Number
+Functions} for more information on how to use and not to use random
+number functions.
+
+@deftypefun void mpz_urandomb (mpz_t @var{rop}, gmp_randstate_t @var{state}, mp_bitcnt_t @var{n})
+Generate a uniformly distributed random integer in the range 0 to @m{2^n-1,
+2^@var{n}@minus{}1}, inclusive.
+
+The variable @var{state} must be initialized by calling one of the
+@code{gmp_randinit} functions (@ref{Random State Initialization}) before
+invoking this function.
+@end deftypefun
+
+@deftypefun void mpz_urandomm (mpz_t @var{rop}, gmp_randstate_t @var{state}, const mpz_t @var{n})
+Generate a uniform random integer in the range 0 to @math{@var{n}-1},
+inclusive.
+
+The variable @var{state} must be initialized by calling one of the
+@code{gmp_randinit} functions (@ref{Random State Initialization})
+before invoking this function.
+@end deftypefun
+
+@deftypefun void mpz_rrandomb (mpz_t @var{rop}, gmp_randstate_t @var{state}, mp_bitcnt_t @var{n})
+Generate a random integer with long strings of zeros and ones in the
+binary representation. Useful for testing functions and algorithms,
+since this kind of random numbers have proven to be more likely to
+trigger corner-case bugs. The random number will be in the range
+0 to @m{2^n-1, 2^@var{n}@minus{}1}, inclusive.
+
+The variable @var{state} must be initialized by calling one of the
+@code{gmp_randinit} functions (@ref{Random State Initialization})
+before invoking this function.
+@end deftypefun
+
+@deftypefun void mpz_random (mpz_t @var{rop}, mp_size_t @var{max_size})
+Generate a random integer of at most @var{max_size} limbs. The generated
+random number doesn't satisfy any particular requirements of randomness.
+Negative random numbers are generated when @var{max_size} is negative.
+
+This function is obsolete. Use @code{mpz_urandomb} or
+@code{mpz_urandomm} instead.
+@end deftypefun
+
+@deftypefun void mpz_random2 (mpz_t @var{rop}, mp_size_t @var{max_size})
+Generate a random integer of at most @var{max_size} limbs, with long strings
+of zeros and ones in the binary representation. Useful for testing functions
+and algorithms, since this kind of random numbers have proven to be more
+likely to trigger corner-case bugs. Negative random numbers are generated
+when @var{max_size} is negative.
+
+This function is obsolete. Use @code{mpz_rrandomb} instead.
+@end deftypefun
+
+
+@node Integer Import and Export, Miscellaneous Integer Functions, Integer Random Numbers, Integer Functions
+@section Integer Import and Export
+
+@code{mpz_t} variables can be converted to and from arbitrary words of binary
+data with the following functions.
+
+@deftypefun void mpz_import (mpz_t @var{rop}, size_t @var{count}, int @var{order}, size_t @var{size}, int @var{endian}, size_t @var{nails}, const void *@var{op})
+@cindex Integer import
+@cindex Import
+Set @var{rop} from an array of word data at @var{op}.
+
+The parameters specify the format of the data. @var{count} many words are
+read, each @var{size} bytes. @var{order} can be 1 for most significant word
+first or -1 for least significant first. Within each word @var{endian} can be
+1 for most significant byte first, -1 for least significant first, or 0 for
+the native endianness of the host CPU@. The most significant @var{nails} bits
+of each word are skipped, this can be 0 to use the full words.
+
+There is no sign taken from the data, @var{rop} will simply be a positive
+integer. An application can handle any sign itself, and apply it for instance
+with @code{mpz_neg}.
+
+There are no data alignment restrictions on @var{op}, any address is allowed.
+
+Here's an example converting an array of @code{unsigned long} data, most
+significant element first, and host byte order within each value.
+
+@example
+unsigned long a[20];
+/* Initialize @var{z} and @var{a} */
+mpz_import (z, 20, 1, sizeof(a[0]), 0, 0, a);
+@end example
+
+This example assumes the full @code{sizeof} bytes are used for data in the
+given type, which is usually true, and certainly true for @code{unsigned long}
+everywhere we know of. However on Cray vector systems it may be noted that
+@code{short} and @code{int} are always stored in 8 bytes (and with
+@code{sizeof} indicating that) but use only 32 or 46 bits. The @var{nails}
+feature can account for this, by passing for instance
+@code{8*sizeof(int)-INT_BIT}.
+@end deftypefun
+
+@deftypefun {void *} mpz_export (void *@var{rop}, size_t *@var{countp}, int @var{order}, size_t @var{size}, int @var{endian}, size_t @var{nails}, const mpz_t @var{op})
+@cindex Integer export
+@cindex Export
+Fill @var{rop} with word data from @var{op}.
+
+The parameters specify the format of the data produced. Each word will be
+@var{size} bytes and @var{order} can be 1 for most significant word first or
+-1 for least significant first. Within each word @var{endian} can be 1 for
+most significant byte first, -1 for least significant first, or 0 for the
+native endianness of the host CPU@. The most significant @var{nails} bits of
+each word are unused and set to zero, this can be 0 to produce full words.
+
+The number of words produced is written to @code{*@var{countp}}, or
+@var{countp} can be @code{NULL} to discard the count. @var{rop} must have
+enough space for the data, or if @var{rop} is @code{NULL} then a result array
+of the necessary size is allocated using the current GMP allocation function
+(@pxref{Custom Allocation}). In either case the return value is the
+destination used, either @var{rop} or the allocated block.
+
+If @var{op} is non-zero then the most significant word produced will be
+non-zero. If @var{op} is zero then the count returned will be zero and
+nothing written to @var{rop}. If @var{rop} is @code{NULL} in this case, no
+block is allocated, just @code{NULL} is returned.
+
+The sign of @var{op} is ignored, just the absolute value is exported. An
+application can use @code{mpz_sgn} to get the sign and handle it as desired.
+(@pxref{Integer Comparisons})
+
+There are no data alignment restrictions on @var{rop}, any address is allowed.
+
+When an application is allocating space itself the required size can be
+determined with a calculation like the following. Since @code{mpz_sizeinbase}
+always returns at least 1, @code{count} here will be at least one, which
+avoids any portability problems with @code{malloc(0)}, though if @code{z} is
+zero no space at all is actually needed (or written).
+
+@example
+numb = 8*size - nail;
+count = (mpz_sizeinbase (z, 2) + numb-1) / numb;
+p = malloc (count * size);
+@end example
+@end deftypefun
+
+
+@need 2000
+@node Miscellaneous Integer Functions, Integer Special Functions, Integer Import and Export, Integer Functions
+@comment node-name, next, previous, up
+@section Miscellaneous Functions
+@cindex Miscellaneous integer functions
+@cindex Integer miscellaneous functions
+
+@deftypefun int mpz_fits_ulong_p (const mpz_t @var{op})
+@deftypefunx int mpz_fits_slong_p (const mpz_t @var{op})
+@deftypefunx int mpz_fits_uint_p (const mpz_t @var{op})
+@deftypefunx int mpz_fits_sint_p (const mpz_t @var{op})
+@deftypefunx int mpz_fits_ushort_p (const mpz_t @var{op})
+@deftypefunx int mpz_fits_sshort_p (const mpz_t @var{op})
+Return non-zero iff the value of @var{op} fits in an @code{unsigned long int},
+@code{signed long int}, @code{unsigned int}, @code{signed int}, @code{unsigned
+short int}, or @code{signed short int}, respectively. Otherwise, return zero.
+@end deftypefun
+
+@deftypefn Macro int mpz_odd_p (const mpz_t @var{op})
+@deftypefnx Macro int mpz_even_p (const mpz_t @var{op})
+Determine whether @var{op} is odd or even, respectively. Return non-zero if
+yes, zero if no. These macros evaluate their argument more than once.
+@end deftypefn
+
+@deftypefun size_t mpz_sizeinbase (const mpz_t @var{op}, int @var{base})
+@cindex Size in digits
+@cindex Digits in an integer
+Return the size of @var{op} measured in number of digits in the given
+@var{base}. @var{base} can vary from 2 to 62. The sign of @var{op} is
+ignored, just the absolute value is used. The result will be either exact or
+1 too big. If @var{base} is a power of 2, the result is always exact. If
+@var{op} is zero the return value is always 1.
+
+This function can be used to determine the space required when converting
+@var{op} to a string. The right amount of allocation is normally two more
+than the value returned by @code{mpz_sizeinbase}, one extra for a minus sign
+and one for the null-terminator.
+
+@cindex Most significant bit
+It will be noted that @code{mpz_sizeinbase(@var{op},2)} can be used to locate
+the most significant 1 bit in @var{op}, counting from 1. (Unlike the bitwise
+functions which start from 0, @xref{Integer Logic and Bit Fiddling,, Logical
+and Bit Manipulation Functions}.)
+@end deftypefun
+
+
+@node Integer Special Functions, , Miscellaneous Integer Functions, Integer Functions
+@section Special Functions
+@cindex Special integer functions
+@cindex Integer special functions
+
+The functions in this section are for various special purposes. Most
+applications will not need them.
+
+@deftypefun void mpz_array_init (mpz_t @var{integer_array}, mp_size_t @var{array_size}, @w{mp_size_t @var{fixed_num_bits}})
+@strong{This is an obsolete function. Do not use it.}
+@end deftypefun
+
+@deftypefun {void *} _mpz_realloc (mpz_t @var{integer}, mp_size_t @var{new_alloc})
+Change the space for @var{integer} to @var{new_alloc} limbs. The value in
+@var{integer} is preserved if it fits, or is set to 0 if not. The return
+value is not useful to applications and should be ignored.
+
+@code{mpz_realloc2} is the preferred way to accomplish allocation changes like
+this. @code{mpz_realloc2} and @code{_mpz_realloc} are the same except that
+@code{_mpz_realloc} takes its size in limbs.
+@end deftypefun
+
+@deftypefun mp_limb_t mpz_getlimbn (const mpz_t @var{op}, mp_size_t @var{n})
+Return limb number @var{n} from @var{op}. The sign of @var{op} is ignored,
+just the absolute value is used. The least significant limb is number 0.
+
+@code{mpz_size} can be used to find how many limbs make up @var{op}.
+@code{mpz_getlimbn} returns zero if @var{n} is outside the range 0 to
+@code{mpz_size(@var{op})-1}.
+@end deftypefun
+
+@deftypefun size_t mpz_size (const mpz_t @var{op})
+Return the size of @var{op} measured in number of limbs. If @var{op} is zero,
+the returned value will be zero.
+@c (@xref{Nomenclature}, for an explanation of the concept @dfn{limb}.)
+@end deftypefun
+
+@deftypefun {const mp_limb_t *} mpz_limbs_read (const mpz_t @var{x})
+Return a pointer to the limb array representing the absolute value of @var{x}.
+The size of the array is @code{mpz_size(@var{x})}. Intended for read access
+only.
+@end deftypefun
+
+@deftypefun {mp_limb_t *} mpz_limbs_write (mpz_t @var{x}, mp_size_t @var{n})
+@deftypefunx {mp_limb_t *} mpz_limbs_modify (mpz_t @var{x}, mp_size_t @var{n})
+Return a pointer to the limb array, intended for write access. The array is
+reallocated as needed, to make room for @var{n} limbs. Requires @math{@var{n}
+> 0}. The @code{mpz_limbs_modify} function returns an array that holds the old
+absolute value of @var{x}, while @code{mpz_limbs_write} may destroy the old
+value and return an array with unspecified contents.
+@end deftypefun
+
+@deftypefun void mpz_limbs_finish (mpz_t @var{x}, mp_size_t @var{s})
+Updates the internal size field of @var{x}. Used after writing to the limb
+array pointer returned by @code{mpz_limbs_write} or @code{mpz_limbs_modify} is
+completed. The array should contain @math{@GMPabs{@var{s}}} valid limbs,
+representing the new absolute value for @var{x}, and the sign of @var{x} is
+taken from the sign of @var{s}. This function never reallocates @var{x}, so
+the limb pointer remains valid.
+@end deftypefun
+
+@c FIXME: Some more useful and less silly example?
+@example
+void foo (mpz_t x)
+@{
+ mp_size_t n, i;
+ mp_limb_t *xp;
+
+ n = mpz_size (x);
+ xp = mpz_limbs_modify(x, 2*n);
+ for (i = 0; i < n; i++)
+ xp[n+i] = xp[n-1-i];
+ mpz_limbs_finish (x, mpz_sgn (x) < 0 ? - 2*n : 2*n);
+@}
+@end example
+
+@deftypefun mpz_srcptr mpz_roinit_n (mpz_t @var{x}, const mp_limb_t *@var{xp}, mp_size_t @var{xs})
+Special initialization of @var{x}, using the given limb array and size.
+@var{x} should be treated as read-only: it can be passed safely as input to
+any mpz function, but not as an output. The array @var{xp} must point to at
+least a readable limb, its size is
+@math{@GMPabs{@var{xs}}}, and the sign of @var{x} is the sign of @var{xs}. For
+convenience, the function returns @var{x}, but cast to a const pointer type.
+@end deftypefun
+
+@example
+void foo (mpz_t x)
+@{
+ static const mp_limb_t y[3] = @{ 0x1, 0x2, 0x3 @};
+ mpz_t tmp;
+ mpz_add (x, x, mpz_roinit_n (tmp, y, 3));
+@}
+@end example
+
+@deftypefn Macro mpz_t MPZ_ROINIT_N (mp_limb_t *@var{xp}, mp_size_t @var{xs})
+This macro expands to an initializer which can be assigned to an mpz_t
+variable. The limb array @var{xp} must point to at least a readable limb,
+moreover, unlike the @code{mpz_roinit_n} function, the array must be
+normalized: if @var{xs} is non-zero, then
+@code{@var{xp}[@math{@GMPabs{@var{xs}}-1}]} must be non-zero. Intended
+primarily for constant values. Using it for non-constant values requires a C
+compiler supporting C99.
+@end deftypefn
+
+@example
+void foo (mpz_t x)
+@{
+ static const mp_limb_t ya[3] = @{ 0x1, 0x2, 0x3 @};
+ static const mpz_t y = MPZ_ROINIT_N ((mp_limb_t *) ya, 3);
+
+ mpz_add (x, x, y);
+@}
+@end example
+
+
+@node Rational Number Functions, Floating-point Functions, Integer Functions, Top
+@comment node-name, next, previous, up
+@chapter Rational Number Functions
+@cindex Rational number functions
+
+This chapter describes the GMP functions for performing arithmetic on rational
+numbers. These functions start with the prefix @code{mpq_}.
+
+Rational numbers are stored in objects of type @code{mpq_t}.
+
+All rational arithmetic functions assume operands have a canonical form, and
+canonicalize their result. The canonical from means that the denominator and
+the numerator have no common factors, and that the denominator is positive.
+Zero has the unique representation 0/1.
+
+Pure assignment functions do not canonicalize the assigned variable. It is
+the responsibility of the user to canonicalize the assigned variable before
+any arithmetic operations are performed on that variable.
+
+@deftypefun void mpq_canonicalize (mpq_t @var{op})
+Remove any factors that are common to the numerator and denominator of
+@var{op}, and make the denominator positive.
+@end deftypefun
+
+@menu
+* Initializing Rationals::
+* Rational Conversions::
+* Rational Arithmetic::
+* Comparing Rationals::
+* Applying Integer Functions::
+* I/O of Rationals::
+@end menu
+
+@node Initializing Rationals, Rational Conversions, Rational Number Functions, Rational Number Functions
+@comment node-name, next, previous, up
+@section Initialization and Assignment Functions
+@cindex Rational assignment functions
+@cindex Assignment functions
+@cindex Rational initialization functions
+@cindex Initialization functions
+
+@deftypefun void mpq_init (mpq_t @var{x})
+Initialize @var{x} and set it to 0/1. Each variable should normally only be
+initialized once, or at least cleared out (using the function @code{mpq_clear})
+between each initialization.
+@end deftypefun
+
+@deftypefun void mpq_inits (mpq_t @var{x}, ...)
+Initialize a NULL-terminated list of @code{mpq_t} variables, and set their
+values to 0/1.
+@end deftypefun
+
+@deftypefun void mpq_clear (mpq_t @var{x})
+Free the space occupied by @var{x}. Make sure to call this function for all
+@code{mpq_t} variables when you are done with them.
+@end deftypefun
+
+@deftypefun void mpq_clears (mpq_t @var{x}, ...)
+Free the space occupied by a NULL-terminated list of @code{mpq_t} variables.
+@end deftypefun
+
+@deftypefun void mpq_set (mpq_t @var{rop}, const mpq_t @var{op})
+@deftypefunx void mpq_set_z (mpq_t @var{rop}, const mpz_t @var{op})
+Assign @var{rop} from @var{op}.
+@end deftypefun
+
+@deftypefun void mpq_set_ui (mpq_t @var{rop}, unsigned long int @var{op1}, unsigned long int @var{op2})
+@deftypefunx void mpq_set_si (mpq_t @var{rop}, signed long int @var{op1}, unsigned long int @var{op2})
+Set the value of @var{rop} to @var{op1}/@var{op2}. Note that if @var{op1} and
+@var{op2} have common factors, @var{rop} has to be passed to
+@code{mpq_canonicalize} before any operations are performed on @var{rop}.
+@end deftypefun
+
+@deftypefun int mpq_set_str (mpq_t @var{rop}, const char *@var{str}, int @var{base})
+Set @var{rop} from a null-terminated string @var{str} in the given @var{base}.
+
+The string can be an integer like ``41'' or a fraction like ``41/152''. The
+fraction must be in canonical form (@pxref{Rational Number Functions}), or if
+not then @code{mpq_canonicalize} must be called.
+
+The numerator and optional denominator are parsed the same as in
+@code{mpz_set_str} (@pxref{Assigning Integers}). White space is allowed in
+the string, and is simply ignored. The @var{base} can vary from 2 to 62, or
+if @var{base} is 0 then the leading characters are used: @code{0x} or @code{0X} for hex,
+@code{0b} or @code{0B} for binary,
+@code{0} for octal, or decimal otherwise. Note that this is done separately
+for the numerator and denominator, so for instance @code{0xEF/100} is 239/100,
+whereas @code{0xEF/0x100} is 239/256.
+
+The return value is 0 if the entire string is a valid number, or @minus{}1 if
+not.
+@end deftypefun
+
+@deftypefun void mpq_swap (mpq_t @var{rop1}, mpq_t @var{rop2})
+Swap the values @var{rop1} and @var{rop2} efficiently.
+@end deftypefun
+
+
+@need 2000
+@node Rational Conversions, Rational Arithmetic, Initializing Rationals, Rational Number Functions
+@comment node-name, next, previous, up
+@section Conversion Functions
+@cindex Rational conversion functions
+@cindex Conversion functions
+
+@deftypefun double mpq_get_d (const mpq_t @var{op})
+Convert @var{op} to a @code{double}, truncating if necessary (i.e.@: rounding
+towards zero).
+
+If the exponent from the conversion is too big or too small to fit a
+@code{double} then the result is system dependent. For too big an infinity is
+returned when available. For too small @math{0.0} is normally returned.
+Hardware overflow, underflow and denorm traps may or may not occur.
+@end deftypefun
+
+@deftypefun void mpq_set_d (mpq_t @var{rop}, double @var{op})
+@deftypefunx void mpq_set_f (mpq_t @var{rop}, const mpf_t @var{op})
+Set @var{rop} to the value of @var{op}. There is no rounding, this conversion
+is exact.
+@end deftypefun
+
+@deftypefun {char *} mpq_get_str (char *@var{str}, int @var{base}, const mpq_t @var{op})
+Convert @var{op} to a string of digits in base @var{base}. The base may vary
+from 2 to 36. The string will be of the form @samp{num/den}, or if the
+denominator is 1 then just @samp{num}.
+
+If @var{str} is @code{NULL}, the result string is allocated using the current
+allocation function (@pxref{Custom Allocation}). The block will be
+@code{strlen(str)+1} bytes, that being exactly enough for the string and
+null-terminator.
+
+If @var{str} is not @code{NULL}, it should point to a block of storage large
+enough for the result, that being
+
+@example
+mpz_sizeinbase (mpq_numref(@var{op}), @var{base})
++ mpz_sizeinbase (mpq_denref(@var{op}), @var{base}) + 3
+@end example
+
+The three extra bytes are for a possible minus sign, possible slash, and the
+null-terminator.
+
+A pointer to the result string is returned, being either the allocated block,
+or the given @var{str}.
+@end deftypefun
+
+
+@node Rational Arithmetic, Comparing Rationals, Rational Conversions, Rational Number Functions
+@comment node-name, next, previous, up
+@section Arithmetic Functions
+@cindex Rational arithmetic functions
+@cindex Arithmetic functions
+
+@deftypefun void mpq_add (mpq_t @var{sum}, const mpq_t @var{addend1}, const mpq_t @var{addend2})
+Set @var{sum} to @var{addend1} + @var{addend2}.
+@end deftypefun
+
+@deftypefun void mpq_sub (mpq_t @var{difference}, const mpq_t @var{minuend}, const mpq_t @var{subtrahend})
+Set @var{difference} to @var{minuend} @minus{} @var{subtrahend}.
+@end deftypefun
+
+@deftypefun void mpq_mul (mpq_t @var{product}, const mpq_t @var{multiplier}, const mpq_t @var{multiplicand})
+Set @var{product} to @math{@var{multiplier} @GMPtimes{} @var{multiplicand}}.
+@end deftypefun
+
+@deftypefun void mpq_mul_2exp (mpq_t @var{rop}, const mpq_t @var{op1}, mp_bitcnt_t @var{op2})
+Set @var{rop} to @m{@var{op1} \times 2^{op2}, @var{op1} times 2 raised to
+@var{op2}}.
+@end deftypefun
+
+@deftypefun void mpq_div (mpq_t @var{quotient}, const mpq_t @var{dividend}, const mpq_t @var{divisor})
+@cindex Division functions
+Set @var{quotient} to @var{dividend}/@var{divisor}.
+@end deftypefun
+
+@deftypefun void mpq_div_2exp (mpq_t @var{rop}, const mpq_t @var{op1}, mp_bitcnt_t @var{op2})
+Set @var{rop} to @m{@var{op1}/2^{op2}, @var{op1} divided by 2 raised to
+@var{op2}}.
+@end deftypefun
+
+@deftypefun void mpq_neg (mpq_t @var{negated_operand}, const mpq_t @var{operand})
+Set @var{negated_operand} to @minus{}@var{operand}.
+@end deftypefun
+
+@deftypefun void mpq_abs (mpq_t @var{rop}, const mpq_t @var{op})
+Set @var{rop} to the absolute value of @var{op}.
+@end deftypefun
+
+@deftypefun void mpq_inv (mpq_t @var{inverted_number}, const mpq_t @var{number})
+Set @var{inverted_number} to 1/@var{number}. If the new denominator is
+zero, this routine will divide by zero.
+@end deftypefun
+
+@node Comparing Rationals, Applying Integer Functions, Rational Arithmetic, Rational Number Functions
+@comment node-name, next, previous, up
+@section Comparison Functions
+@cindex Rational comparison functions
+@cindex Comparison functions
+
+@deftypefun int mpq_cmp (const mpq_t @var{op1}, const mpq_t @var{op2})
+Compare @var{op1} and @var{op2}. Return a positive value if @math{@var{op1} >
+@var{op2}}, zero if @math{@var{op1} = @var{op2}}, and a negative value if
+@math{@var{op1} < @var{op2}}.
+
+To determine if two rationals are equal, @code{mpq_equal} is faster than
+@code{mpq_cmp}.
+@end deftypefun
+
+@deftypefn Macro int mpq_cmp_ui (const mpq_t @var{op1}, unsigned long int @var{num2}, unsigned long int @var{den2})
+@deftypefnx Macro int mpq_cmp_si (const mpq_t @var{op1}, long int @var{num2}, unsigned long int @var{den2})
+Compare @var{op1} and @var{num2}/@var{den2}. Return a positive value if
+@math{@var{op1} > @var{num2}/@var{den2}}, zero if @math{@var{op1} =
+@var{num2}/@var{den2}}, and a negative value if @math{@var{op1} <
+@var{num2}/@var{den2}}.
+
+@var{num2} and @var{den2} are allowed to have common factors.
+
+These functions are implemented as a macros and evaluate their arguments
+multiple times.
+@end deftypefn
+
+@deftypefn Macro int mpq_sgn (const mpq_t @var{op})
+@cindex Sign tests
+@cindex Rational sign tests
+Return @math{+1} if @math{@var{op} > 0}, 0 if @math{@var{op} = 0}, and
+@math{-1} if @math{@var{op} < 0}.
+
+This function is actually implemented as a macro. It evaluates its
+argument multiple times.
+@end deftypefn
+
+@deftypefun int mpq_equal (const mpq_t @var{op1}, const mpq_t @var{op2})
+Return non-zero if @var{op1} and @var{op2} are equal, zero if they are
+non-equal. Although @code{mpq_cmp} can be used for the same purpose, this
+function is much faster.
+@end deftypefun
+
+@node Applying Integer Functions, I/O of Rationals, Comparing Rationals, Rational Number Functions
+@comment node-name, next, previous, up
+@section Applying Integer Functions to Rationals
+@cindex Rational numerator and denominator
+@cindex Numerator and denominator
+
+The set of @code{mpq} functions is quite small. In particular, there are few
+functions for either input or output. The following functions give direct
+access to the numerator and denominator of an @code{mpq_t}.
+
+Note that if an assignment to the numerator and/or denominator could take an
+@code{mpq_t} out of the canonical form described at the start of this chapter
+(@pxref{Rational Number Functions}) then @code{mpq_canonicalize} must be
+called before any other @code{mpq} functions are applied to that @code{mpq_t}.
+
+@deftypefn Macro mpz_t mpq_numref (const mpq_t @var{op})
+@deftypefnx Macro mpz_t mpq_denref (const mpq_t @var{op})
+Return a reference to the numerator and denominator of @var{op}, respectively.
+The @code{mpz} functions can be used on the result of these macros.
+@end deftypefn
+
+@deftypefun void mpq_get_num (mpz_t @var{numerator}, const mpq_t @var{rational})
+@deftypefunx void mpq_get_den (mpz_t @var{denominator}, const mpq_t @var{rational})
+@deftypefunx void mpq_set_num (mpq_t @var{rational}, const mpz_t @var{numerator})
+@deftypefunx void mpq_set_den (mpq_t @var{rational}, const mpz_t @var{denominator})
+Get or set the numerator or denominator of a rational. These functions are
+equivalent to calling @code{mpz_set} with an appropriate @code{mpq_numref} or
+@code{mpq_denref}. Direct use of @code{mpq_numref} or @code{mpq_denref} is
+recommended instead of these functions.
+@end deftypefun
+
+
+@need 2000
+@node I/O of Rationals, , Applying Integer Functions, Rational Number Functions
+@comment node-name, next, previous, up
+@section Input and Output Functions
+@cindex Rational input and output functions
+@cindex Input functions
+@cindex Output functions
+@cindex I/O functions
+
+Functions that perform input from a stdio stream, and functions that output to
+a stdio stream, of @code{mpq} numbers. Passing a @code{NULL} pointer for a
+@var{stream} argument to any of these functions will make them read from
+@code{stdin} and write to @code{stdout}, respectively.
+
+When using any of these functions, it is a good idea to include @file{stdio.h}
+before @file{gmp.h}, since that will allow @file{gmp.h} to define prototypes
+for these functions.
+
+See also @ref{Formatted Output} and @ref{Formatted Input}.
+
+@deftypefun size_t mpq_out_str (FILE *@var{stream}, int @var{base}, const mpq_t @var{op})
+Output @var{op} on stdio stream @var{stream}, as a string of digits in base
+@var{base}. The base may vary from 2 to 36. Output is in the form
+@samp{num/den} or if the denominator is 1 then just @samp{num}.
+
+Return the number of bytes written, or if an error occurred, return 0.
+@end deftypefun
+
+@deftypefun size_t mpq_inp_str (mpq_t @var{rop}, FILE *@var{stream}, int @var{base})
+Read a string of digits from @var{stream} and convert them to a rational in
+@var{rop}. Any initial white-space characters are read and discarded. Return
+the number of characters read (including white space), or 0 if a rational
+could not be read.
+
+The input can be a fraction like @samp{17/63} or just an integer like
+@samp{123}. Reading stops at the first character not in this form, and white
+space is not permitted within the string. If the input might not be in
+canonical form, then @code{mpq_canonicalize} must be called (@pxref{Rational
+Number Functions}).
+
+The @var{base} can be between 2 and 36, or can be 0 in which case the leading
+characters of the string determine the base, @samp{0x} or @samp{0X} for
+hexadecimal, @samp{0} for octal, or decimal otherwise. The leading characters
+are examined separately for the numerator and denominator of a fraction, so
+for instance @samp{0x10/11} is @math{16/11}, whereas @samp{0x10/0x11} is
+@math{16/17}.
+@end deftypefun
+
+
+@node Floating-point Functions, Low-level Functions, Rational Number Functions, Top
+@comment node-name, next, previous, up
+@chapter Floating-point Functions
+@cindex Floating-point functions
+@cindex Float functions
+@cindex User-defined precision
+@cindex Precision of floats
+
+GMP floating point numbers are stored in objects of type @code{mpf_t} and
+functions operating on them have an @code{mpf_} prefix.
+
+The mantissa of each float has a user-selectable precision, limited only by
+available memory. Each variable has its own precision, and that can be
+increased or decreased at any time.
+
+The exponent of each float is a fixed precision, one machine word on most
+systems. In the current implementation the exponent is a count of limbs, so
+for example on a 32-bit system this means a range of roughly
+@math{2^@W{-68719476768}} to @math{2^@W{68719476736}}, or on a 64-bit system
+this will be greater. Note however that @code{mpf_get_str} can only return an
+exponent which fits an @code{mp_exp_t} and currently @code{mpf_set_str}
+doesn't accept exponents bigger than a @code{long}.
+
+Each variable keeps a size for the mantissa data actually in use. This means
+that if a float is exactly represented in only a few bits then only those bits
+will be used in a calculation, even if the selected precision is high.
+
+All calculations are performed to the precision of the destination variable.
+Each function is defined to calculate with ``infinite precision'' followed by
+a truncation to the destination precision, but of course the work done is only
+what's needed to determine a result under that definition.
+
+The precision selected by the user for a variable is a minimum value, GMP may
+increase it to facilitate efficient calculation. Currently this means
+rounding up to a whole limb, and then sometimes having a further partial limb,
+depending on the high limb of the mantissa.
+
+The mantissa is stored in binary. One consequence of this is that decimal
+fractions like @math{0.1} cannot be represented exactly. The same is true of
+plain IEEE @code{double} floats. This makes both highly unsuitable for
+calculations involving money or other values that should be exact decimal
+fractions. (Suitably scaled integers, or perhaps rationals, are better
+choices.)
+
+The @code{mpf} functions and variables have no special notion of infinity or
+not-a-number, and applications must take care not to overflow the exponent or
+results will be unpredictable. This might change in a future release.
+
+Note that the @code{mpf} functions are @emph{not} intended as a smooth
+extension to IEEE P754 arithmetic. In particular results obtained on one
+computer often differ from the results on a computer with a different word
+size.
+
+The GMP extension library MPFR (@url{http://mpfr.org}) is an alternative to
+GMP's @code{mpf} functions. MPFR provides well-defined precision and accurate
+rounding, and thereby naturally extends IEEE P754.
+
+@menu
+* Initializing Floats::
+* Assigning Floats::
+* Simultaneous Float Init & Assign::
+* Converting Floats::
+* Float Arithmetic::
+* Float Comparison::
+* I/O of Floats::
+* Miscellaneous Float Functions::
+@end menu
+
+@node Initializing Floats, Assigning Floats, Floating-point Functions, Floating-point Functions
+@comment node-name, next, previous, up
+@section Initialization Functions
+@cindex Float initialization functions
+@cindex Initialization functions
+
+@deftypefun void mpf_set_default_prec (mp_bitcnt_t @var{prec})
+Set the default precision to be @strong{at least} @var{prec} bits. All
+subsequent calls to @code{mpf_init} will use this precision, but previously
+initialized variables are unaffected.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpf_get_default_prec (void)
+Return the default precision actually used.
+@end deftypefun
+
+An @code{mpf_t} object must be initialized before storing the first value in
+it. The functions @code{mpf_init} and @code{mpf_init2} are used for that
+purpose.
+
+@deftypefun void mpf_init (mpf_t @var{x})
+Initialize @var{x} to 0. Normally, a variable should be initialized once only
+or at least be cleared, using @code{mpf_clear}, between initializations. The
+precision of @var{x} is undefined unless a default precision has already been
+established by a call to @code{mpf_set_default_prec}.
+@end deftypefun
+
+@deftypefun void mpf_init2 (mpf_t @var{x}, mp_bitcnt_t @var{prec})
+Initialize @var{x} to 0 and set its precision to be @strong{at least}
+@var{prec} bits. Normally, a variable should be initialized once only or at
+least be cleared, using @code{mpf_clear}, between initializations.
+@end deftypefun
+
+@deftypefun void mpf_inits (mpf_t @var{x}, ...)
+Initialize a NULL-terminated list of @code{mpf_t} variables, and set their
+values to 0. The precision of the initialized variables is undefined unless a
+default precision has already been established by a call to
+@code{mpf_set_default_prec}.
+@end deftypefun
+
+@deftypefun void mpf_clear (mpf_t @var{x})
+Free the space occupied by @var{x}. Make sure to call this function for all
+@code{mpf_t} variables when you are done with them.
+@end deftypefun
+
+@deftypefun void mpf_clears (mpf_t @var{x}, ...)
+Free the space occupied by a NULL-terminated list of @code{mpf_t} variables.
+@end deftypefun
+
+@need 2000
+Here is an example on how to initialize floating-point variables:
+@example
+@{
+ mpf_t x, y;
+ mpf_init (x); /* use default precision */
+ mpf_init2 (y, 256); /* precision @emph{at least} 256 bits */
+ @dots{}
+ /* Unless the program is about to exit, do ... */
+ mpf_clear (x);
+ mpf_clear (y);
+@}
+@end example
+
+The following three functions are useful for changing the precision during a
+calculation. A typical use would be for adjusting the precision gradually in
+iterative algorithms like Newton-Raphson, making the computation precision
+closely match the actual accurate part of the numbers.
+
+@deftypefun {mp_bitcnt_t} mpf_get_prec (const mpf_t @var{op})
+Return the current precision of @var{op}, in bits.
+@end deftypefun
+
+@deftypefun void mpf_set_prec (mpf_t @var{rop}, mp_bitcnt_t @var{prec})
+Set the precision of @var{rop} to be @strong{at least} @var{prec} bits. The
+value in @var{rop} will be truncated to the new precision.
+
+This function requires a call to @code{realloc}, and so should not be used in
+a tight loop.
+@end deftypefun
+
+@deftypefun void mpf_set_prec_raw (mpf_t @var{rop}, mp_bitcnt_t @var{prec})
+Set the precision of @var{rop} to be @strong{at least} @var{prec} bits,
+without changing the memory allocated.
+
+@var{prec} must be no more than the allocated precision for @var{rop}, that
+being the precision when @var{rop} was initialized, or in the most recent
+@code{mpf_set_prec}.
+
+The value in @var{rop} is unchanged, and in particular if it had a higher
+precision than @var{prec} it will retain that higher precision. New values
+written to @var{rop} will use the new @var{prec}.
+
+Before calling @code{mpf_clear} or the full @code{mpf_set_prec}, another
+@code{mpf_set_prec_raw} call must be made to restore @var{rop} to its original
+allocated precision. Failing to do so will have unpredictable results.
+
+@code{mpf_get_prec} can be used before @code{mpf_set_prec_raw} to get the
+original allocated precision. After @code{mpf_set_prec_raw} it reflects the
+@var{prec} value set.
+
+@code{mpf_set_prec_raw} is an efficient way to use an @code{mpf_t} variable at
+different precisions during a calculation, perhaps to gradually increase
+precision in an iteration, or just to use various different precisions for
+different purposes during a calculation.
+@end deftypefun
+
+
+@need 2000
+@node Assigning Floats, Simultaneous Float Init & Assign, Initializing Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@section Assignment Functions
+@cindex Float assignment functions
+@cindex Assignment functions
+
+These functions assign new values to already initialized floats
+(@pxref{Initializing Floats}).
+
+@deftypefun void mpf_set (mpf_t @var{rop}, const mpf_t @var{op})
+@deftypefunx void mpf_set_ui (mpf_t @var{rop}, unsigned long int @var{op})
+@deftypefunx void mpf_set_si (mpf_t @var{rop}, signed long int @var{op})
+@deftypefunx void mpf_set_d (mpf_t @var{rop}, double @var{op})
+@deftypefunx void mpf_set_z (mpf_t @var{rop}, const mpz_t @var{op})
+@deftypefunx void mpf_set_q (mpf_t @var{rop}, const mpq_t @var{op})
+Set the value of @var{rop} from @var{op}.
+@end deftypefun
+
+@deftypefun int mpf_set_str (mpf_t @var{rop}, const char *@var{str}, int @var{base})
+Set the value of @var{rop} from the string in @var{str}. The string is of the
+form @samp{M@@N} or, if the base is 10 or less, alternatively @samp{MeN}.
+@samp{M} is the mantissa and @samp{N} is the exponent. The mantissa is always
+in the specified base. The exponent is either in the specified base or, if
+@var{base} is negative, in decimal. The decimal point expected is taken from
+the current locale, on systems providing @code{localeconv}.
+
+The argument @var{base} may be in the ranges 2 to 62, or @minus{}62 to
+@minus{}2. Negative values are used to specify that the exponent is in
+decimal.
+
+For bases up to 36, case is ignored; upper-case and lower-case letters have
+the same value; for bases 37 to 62, upper-case letter represent the usual
+10..35 while lower-case letter represent 36..61.
+
+Unlike the corresponding @code{mpz} function, the base will not be determined
+from the leading characters of the string if @var{base} is 0. This is so that
+numbers like @samp{0.23} are not interpreted as octal.
+
+White space is allowed in the string, and is simply ignored. [This is not
+really true; white-space is ignored in the beginning of the string and within
+the mantissa, but not in other places, such as after a minus sign or in the
+exponent. We are considering changing the definition of this function, making
+it fail when there is any white-space in the input, since that makes a lot of
+sense. Please tell us your opinion about this change. Do you really want it
+to accept @nicode{"3 14"} as meaning 314 as it does now?]
+
+This function returns 0 if the entire string is a valid number in base
+@var{base}. Otherwise it returns @minus{}1.
+@end deftypefun
+
+@deftypefun void mpf_swap (mpf_t @var{rop1}, mpf_t @var{rop2})
+Swap @var{rop1} and @var{rop2} efficiently. Both the values and the
+precisions of the two variables are swapped.
+@end deftypefun
+
+
+@node Simultaneous Float Init & Assign, Converting Floats, Assigning Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@section Combined Initialization and Assignment Functions
+@cindex Float assignment functions
+@cindex Assignment functions
+@cindex Float initialization functions
+@cindex Initialization functions
+
+For convenience, GMP provides a parallel series of initialize-and-set functions
+which initialize the output and then store the value there. These functions'
+names have the form @code{mpf_init_set@dots{}}
+
+Once the float has been initialized by any of the @code{mpf_init_set@dots{}}
+functions, it can be used as the source or destination operand for the ordinary
+float functions. Don't use an initialize-and-set function on a variable
+already initialized!
+
+@deftypefun void mpf_init_set (mpf_t @var{rop}, const mpf_t @var{op})
+@deftypefunx void mpf_init_set_ui (mpf_t @var{rop}, unsigned long int @var{op})
+@deftypefunx void mpf_init_set_si (mpf_t @var{rop}, signed long int @var{op})
+@deftypefunx void mpf_init_set_d (mpf_t @var{rop}, double @var{op})
+Initialize @var{rop} and set its value from @var{op}.
+
+The precision of @var{rop} will be taken from the active default precision, as
+set by @code{mpf_set_default_prec}.
+@end deftypefun
+
+@deftypefun int mpf_init_set_str (mpf_t @var{rop}, const char *@var{str}, int @var{base})
+Initialize @var{rop} and set its value from the string in @var{str}. See
+@code{mpf_set_str} above for details on the assignment operation.
+
+Note that @var{rop} is initialized even if an error occurs. (I.e., you have to
+call @code{mpf_clear} for it.)
+
+The precision of @var{rop} will be taken from the active default precision, as
+set by @code{mpf_set_default_prec}.
+@end deftypefun
+
+
+@node Converting Floats, Float Arithmetic, Simultaneous Float Init & Assign, Floating-point Functions
+@comment node-name, next, previous, up
+@section Conversion Functions
+@cindex Float conversion functions
+@cindex Conversion functions
+
+@deftypefun double mpf_get_d (const mpf_t @var{op})
+Convert @var{op} to a @code{double}, truncating if necessary (i.e.@: rounding
+towards zero).
+
+If the exponent in @var{op} is too big or too small to fit a @code{double}
+then the result is system dependent. For too big an infinity is returned when
+available. For too small @math{0.0} is normally returned. Hardware overflow,
+underflow and denorm traps may or may not occur.
+@end deftypefun
+
+@deftypefun double mpf_get_d_2exp (signed long int *@var{exp}, const mpf_t @var{op})
+Convert @var{op} to a @code{double}, truncating if necessary (i.e.@: rounding
+towards zero), and with an exponent returned separately.
+
+The return value is in the range @math{0.5@le{}@GMPabs{@var{d}}<1} and the
+exponent is stored to @code{*@var{exp}}. @m{@var{d} \times 2^{exp},
+@var{d} * 2^@var{exp}} is the (truncated) @var{op} value. If @var{op} is zero,
+the return is @math{0.0} and 0 is stored to @code{*@var{exp}}.
+
+@cindex @code{frexp}
+This is similar to the standard C @code{frexp} function (@pxref{Normalization
+Functions,,, libc, The GNU C Library Reference Manual}).
+@end deftypefun
+
+@deftypefun long mpf_get_si (const mpf_t @var{op})
+@deftypefunx {unsigned long} mpf_get_ui (const mpf_t @var{op})
+Convert @var{op} to a @code{long} or @code{unsigned long}, truncating any
+fraction part. If @var{op} is too big for the return type, the result is
+undefined.
+
+See also @code{mpf_fits_slong_p} and @code{mpf_fits_ulong_p}
+(@pxref{Miscellaneous Float Functions}).
+@end deftypefun
+
+@deftypefun {char *} mpf_get_str (char *@var{str}, mp_exp_t *@var{expptr}, int @var{base}, size_t @var{n_digits}, const mpf_t @var{op})
+Convert @var{op} to a string of digits in base @var{base}. The base argument
+may vary from 2 to 62 or from @minus{}2 to @minus{}36. Up to @var{n_digits}
+digits will be generated. Trailing zeros are not returned. No more digits
+than can be accurately represented by @var{op} are ever generated. If
+@var{n_digits} is 0 then that accurate maximum number of digits are generated.
+
+For @var{base} in the range 2..36, digits and lower-case letters are used; for
+@minus{}2..@minus{}36, digits and upper-case letters are used; for 37..62,
+digits, upper-case letters, and lower-case letters (in that significance order)
+are used.
+
+If @var{str} is @code{NULL}, the result string is allocated using the current
+allocation function (@pxref{Custom Allocation}). The block will be
+@code{strlen(str)+1} bytes, that being exactly enough for the string and
+null-terminator.
+
+If @var{str} is not @code{NULL}, it should point to a block of
+@math{@var{n_digits} + 2} bytes, that being enough for the mantissa, a
+possible minus sign, and a null-terminator. When @var{n_digits} is 0 to get
+all significant digits, an application won't be able to know the space
+required, and @var{str} should be @code{NULL} in that case.
+
+The generated string is a fraction, with an implicit radix point immediately
+to the left of the first digit. The applicable exponent is written through
+the @var{expptr} pointer. For example, the number 3.1416 would be returned as
+string @nicode{"31416"} and exponent 1.
+
+When @var{op} is zero, an empty string is produced and the exponent returned
+is 0.
+
+A pointer to the result string is returned, being either the allocated block
+or the given @var{str}.
+@end deftypefun
+
+
+@node Float Arithmetic, Float Comparison, Converting Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@section Arithmetic Functions
+@cindex Float arithmetic functions
+@cindex Arithmetic functions
+
+@deftypefun void mpf_add (mpf_t @var{rop}, const mpf_t @var{op1}, const mpf_t @var{op2})
+@deftypefunx void mpf_add_ui (mpf_t @var{rop}, const mpf_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @math{@var{op1} + @var{op2}}.
+@end deftypefun
+
+@deftypefun void mpf_sub (mpf_t @var{rop}, const mpf_t @var{op1}, const mpf_t @var{op2})
+@deftypefunx void mpf_ui_sub (mpf_t @var{rop}, unsigned long int @var{op1}, const mpf_t @var{op2})
+@deftypefunx void mpf_sub_ui (mpf_t @var{rop}, const mpf_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @var{op1} @minus{} @var{op2}.
+@end deftypefun
+
+@deftypefun void mpf_mul (mpf_t @var{rop}, const mpf_t @var{op1}, const mpf_t @var{op2})
+@deftypefunx void mpf_mul_ui (mpf_t @var{rop}, const mpf_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @math{@var{op1} @GMPtimes{} @var{op2}}.
+@end deftypefun
+
+Division is undefined if the divisor is zero, and passing a zero divisor to the
+divide functions will make these functions intentionally divide by zero. This
+lets the user handle arithmetic exceptions in these functions in the same
+manner as other arithmetic exceptions.
+
+@deftypefun void mpf_div (mpf_t @var{rop}, const mpf_t @var{op1}, const mpf_t @var{op2})
+@deftypefunx void mpf_ui_div (mpf_t @var{rop}, unsigned long int @var{op1}, const mpf_t @var{op2})
+@deftypefunx void mpf_div_ui (mpf_t @var{rop}, const mpf_t @var{op1}, unsigned long int @var{op2})
+@cindex Division functions
+Set @var{rop} to @var{op1}/@var{op2}.
+@end deftypefun
+
+@deftypefun void mpf_sqrt (mpf_t @var{rop}, const mpf_t @var{op})
+@deftypefunx void mpf_sqrt_ui (mpf_t @var{rop}, unsigned long int @var{op})
+@cindex Root extraction functions
+Set @var{rop} to @m{\sqrt{@var{op}}, the square root of @var{op}}.
+@end deftypefun
+
+@deftypefun void mpf_pow_ui (mpf_t @var{rop}, const mpf_t @var{op1}, unsigned long int @var{op2})
+@cindex Exponentiation functions
+@cindex Powering functions
+Set @var{rop} to @m{@var{op1}^{op2}, @var{op1} raised to the power @var{op2}}.
+@end deftypefun
+
+@deftypefun void mpf_neg (mpf_t @var{rop}, const mpf_t @var{op})
+Set @var{rop} to @minus{}@var{op}.
+@end deftypefun
+
+@deftypefun void mpf_abs (mpf_t @var{rop}, const mpf_t @var{op})
+Set @var{rop} to the absolute value of @var{op}.
+@end deftypefun
+
+@deftypefun void mpf_mul_2exp (mpf_t @var{rop}, const mpf_t @var{op1}, mp_bitcnt_t @var{op2})
+Set @var{rop} to @m{@var{op1} \times 2^{op2}, @var{op1} times 2 raised to
+@var{op2}}.
+@end deftypefun
+
+@deftypefun void mpf_div_2exp (mpf_t @var{rop}, const mpf_t @var{op1}, mp_bitcnt_t @var{op2})
+Set @var{rop} to @m{@var{op1}/2^{op2}, @var{op1} divided by 2 raised to
+@var{op2}}.
+@end deftypefun
+
+@node Float Comparison, I/O of Floats, Float Arithmetic, Floating-point Functions
+@comment node-name, next, previous, up
+@section Comparison Functions
+@cindex Float comparison functions
+@cindex Comparison functions
+
+@deftypefun int mpf_cmp (const mpf_t @var{op1}, const mpf_t @var{op2})
+@deftypefunx int mpf_cmp_d (const mpf_t @var{op1}, double @var{op2})
+@deftypefunx int mpf_cmp_ui (const mpf_t @var{op1}, unsigned long int @var{op2})
+@deftypefunx int mpf_cmp_si (const mpf_t @var{op1}, signed long int @var{op2})
+Compare @var{op1} and @var{op2}. Return a positive value if @math{@var{op1} >
+@var{op2}}, zero if @math{@var{op1} = @var{op2}}, and a negative value if
+@math{@var{op1} < @var{op2}}.
+
+@code{mpf_cmp_d} can be called with an infinity, but results are undefined for
+a NaN.
+@end deftypefun
+
+@deftypefun int mpf_eq (const mpf_t @var{op1}, const mpf_t @var{op2}, mp_bitcnt_t op3)
+Return non-zero if the first @var{op3} bits of @var{op1} and @var{op2} are
+equal, zero otherwise. I.e., test if @var{op1} and @var{op2} are approximately
+equal.
+
+Caution 1: All version of GMP up to version 4.2.4 compared just whole limbs,
+meaning sometimes more than @var{op3} bits, sometimes fewer.
+
+Caution 2: This function will consider XXX11...111 and XX100...000 different,
+even if ... is replaced by a semi-infinite number of bits. Such numbers are
+really just one ulp off, and should be considered equal.
+@end deftypefun
+
+@deftypefun void mpf_reldiff (mpf_t @var{rop}, const mpf_t @var{op1}, const mpf_t @var{op2})
+Compute the relative difference between @var{op1} and @var{op2} and store the
+result in @var{rop}. This is @math{@GMPabs{@var{op1}-@var{op2}}/@var{op1}}.
+@end deftypefun
+
+@deftypefn Macro int mpf_sgn (const mpf_t @var{op})
+@cindex Sign tests
+@cindex Float sign tests
+Return @math{+1} if @math{@var{op} > 0}, 0 if @math{@var{op} = 0}, and
+@math{-1} if @math{@var{op} < 0}.
+
+This function is actually implemented as a macro. It evaluates its argument
+multiple times.
+@end deftypefn
+
+@node I/O of Floats, Miscellaneous Float Functions, Float Comparison, Floating-point Functions
+@comment node-name, next, previous, up
+@section Input and Output Functions
+@cindex Float input and output functions
+@cindex Input functions
+@cindex Output functions
+@cindex I/O functions
+
+Functions that perform input from a stdio stream, and functions that output to
+a stdio stream, of @code{mpf} numbers. Passing a @code{NULL} pointer for a
+@var{stream} argument to any of these functions will make them read from
+@code{stdin} and write to @code{stdout}, respectively.
+
+When using any of these functions, it is a good idea to include @file{stdio.h}
+before @file{gmp.h}, since that will allow @file{gmp.h} to define prototypes
+for these functions.
+
+See also @ref{Formatted Output} and @ref{Formatted Input}.
+
+@deftypefun size_t mpf_out_str (FILE *@var{stream}, int @var{base}, size_t @var{n_digits}, const mpf_t @var{op})
+Print @var{op} to @var{stream}, as a string of digits. Return the number of
+bytes written, or if an error occurred, return 0.
+
+The mantissa is prefixed with an @samp{0.} and is in the given @var{base},
+which may vary from 2 to 62 or from @minus{}2 to @minus{}36. An exponent is
+then printed, separated by an @samp{e}, or if the base is greater than 10 then
+by an @samp{@@}. The exponent is always in decimal. The decimal point follows
+the current locale, on systems providing @code{localeconv}.
+
+For @var{base} in the range 2..36, digits and lower-case letters are used; for
+@minus{}2..@minus{}36, digits and upper-case letters are used; for 37..62,
+digits, upper-case letters, and lower-case letters (in that significance order)
+are used.
+
+Up to @var{n_digits} will be printed from the mantissa, except that no more
+digits than are accurately representable by @var{op} will be printed.
+@var{n_digits} can be 0 to select that accurate maximum.
+@end deftypefun
+
+@deftypefun size_t mpf_inp_str (mpf_t @var{rop}, FILE *@var{stream}, int @var{base})
+Read a string in base @var{base} from @var{stream}, and put the read float in
+@var{rop}. The string is of the form @samp{M@@N} or, if the base is 10 or
+less, alternatively @samp{MeN}. @samp{M} is the mantissa and @samp{N} is the
+exponent. The mantissa is always in the specified base. The exponent is
+either in the specified base or, if @var{base} is negative, in decimal. The
+decimal point expected is taken from the current locale, on systems providing
+@code{localeconv}.
+
+The argument @var{base} may be in the ranges 2 to 36, or @minus{}36 to
+@minus{}2. Negative values are used to specify that the exponent is in
+decimal.
+
+Unlike the corresponding @code{mpz} function, the base will not be determined
+from the leading characters of the string if @var{base} is 0. This is so that
+numbers like @samp{0.23} are not interpreted as octal.
+
+Return the number of bytes read, or if an error occurred, return 0.
+@end deftypefun
+
+@c @deftypefun void mpf_out_raw (FILE *@var{stream}, const mpf_t @var{float})
+@c Output @var{float} on stdio stream @var{stream}, in raw binary
+@c format. The float is written in a portable format, with 4 bytes of
+@c size information, and that many bytes of limbs. Both the size and the
+@c limbs are written in decreasing significance order.
+@c @end deftypefun
+
+@c @deftypefun void mpf_inp_raw (mpf_t @var{float}, FILE *@var{stream})
+@c Input from stdio stream @var{stream} in the format written by
+@c @code{mpf_out_raw}, and put the result in @var{float}.
+@c @end deftypefun
+
+
+@node Miscellaneous Float Functions, , I/O of Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@section Miscellaneous Functions
+@cindex Miscellaneous float functions
+@cindex Float miscellaneous functions
+
+@deftypefun void mpf_ceil (mpf_t @var{rop}, const mpf_t @var{op})
+@deftypefunx void mpf_floor (mpf_t @var{rop}, const mpf_t @var{op})
+@deftypefunx void mpf_trunc (mpf_t @var{rop}, const mpf_t @var{op})
+@cindex Rounding functions
+@cindex Float rounding functions
+Set @var{rop} to @var{op} rounded to an integer. @code{mpf_ceil} rounds to the
+next higher integer, @code{mpf_floor} to the next lower, and @code{mpf_trunc}
+to the integer towards zero.
+@end deftypefun
+
+@deftypefun int mpf_integer_p (const mpf_t @var{op})
+Return non-zero if @var{op} is an integer.
+@end deftypefun
+
+@deftypefun int mpf_fits_ulong_p (const mpf_t @var{op})
+@deftypefunx int mpf_fits_slong_p (const mpf_t @var{op})
+@deftypefunx int mpf_fits_uint_p (const mpf_t @var{op})
+@deftypefunx int mpf_fits_sint_p (const mpf_t @var{op})
+@deftypefunx int mpf_fits_ushort_p (const mpf_t @var{op})
+@deftypefunx int mpf_fits_sshort_p (const mpf_t @var{op})
+Return non-zero if @var{op} would fit in the respective C data type, when
+truncated to an integer.
+@end deftypefun
+
+@deftypefun void mpf_urandomb (mpf_t @var{rop}, gmp_randstate_t @var{state}, mp_bitcnt_t @var{nbits})
+@cindex Random number functions
+@cindex Float random number functions
+Generate a uniformly distributed random float in @var{rop}, such that @math{0
+@le{} @var{rop} < 1}, with @var{nbits} significant bits in the mantissa or
+less if the precision of @var{rop} is smaller.
+
+The variable @var{state} must be initialized by calling one of the
+@code{gmp_randinit} functions (@ref{Random State Initialization}) before
+invoking this function.
+@end deftypefun
+
+@deftypefun void mpf_random2 (mpf_t @var{rop}, mp_size_t @var{max_size}, mp_exp_t @var{exp})
+Generate a random float of at most @var{max_size} limbs, with long strings of
+zeros and ones in the binary representation. The exponent of the number is in
+the interval @minus{}@var{exp} to @var{exp} (in limbs). This function is
+useful for testing functions and algorithms, since these kind of random
+numbers have proven to be more likely to trigger corner-case bugs. Negative
+random numbers are generated when @var{max_size} is negative.
+@end deftypefun
+
+@c @deftypefun size_t mpf_size (const mpf_t @var{op})
+@c Return the size of @var{op} measured in number of limbs. If @var{op} is
+@c zero, the returned value will be zero. (@xref{Nomenclature}, for an
+@c explanation of the concept @dfn{limb}.)
+@c
+@c @strong{This function is obsolete. It will disappear from future GMP
+@c releases.}
+@c @end deftypefun
+
+
+@node Low-level Functions, Random Number Functions, Floating-point Functions, Top
+@comment node-name, next, previous, up
+@chapter Low-level Functions
+@cindex Low-level functions
+
+This chapter describes low-level GMP functions, used to implement the
+high-level GMP functions, but also intended for time-critical user code.
+
+These functions start with the prefix @code{mpn_}.
+
+@c 1. Some of these function clobber input operands.
+@c
+
+The @code{mpn} functions are designed to be as fast as possible, @strong{not}
+to provide a coherent calling interface. The different functions have somewhat
+similar interfaces, but there are variations that make them hard to use. These
+functions do as little as possible apart from the real multiple precision
+computation, so that no time is spent on things that not all callers need.
+
+A source operand is specified by a pointer to the least significant limb and a
+limb count. A destination operand is specified by just a pointer. It is the
+responsibility of the caller to ensure that the destination has enough space
+for storing the result.
+
+With this way of specifying operands, it is possible to perform computations on
+subranges of an argument, and store the result into a subrange of a
+destination.
+
+A common requirement for all functions is that each source area needs at least
+one limb. No size argument may be zero. Unless otherwise stated, in-place
+operations are allowed where source and destination are the same, but not where
+they only partly overlap.
+
+The @code{mpn} functions are the base for the implementation of the
+@code{mpz_}, @code{mpf_}, and @code{mpq_} functions.
+
+This example adds the number beginning at @var{s1p} and the number beginning at
+@var{s2p} and writes the sum at @var{destp}. All areas have @var{n} limbs.
+
+@example
+cy = mpn_add_n (destp, s1p, s2p, n)
+@end example
+
+It should be noted that the @code{mpn} functions make no attempt to identify
+high or low zero limbs on their operands, or other special forms. On random
+data such cases will be unlikely and it'd be wasteful for every function to
+check every time. An application knowing something about its data can take
+steps to trim or perhaps split its calculations.
+@c
+@c For reference, within gmp mpz_t operands never have high zero limbs, and
+@c we rate low zero limbs as unlikely too (or something an application should
+@c handle). This is a prime motivation for not stripping zero limbs in say
+@c mpn_mul_n etc.
+@c
+@c Other applications doing variable-length calculations will quite likely do
+@c something similar to mpz. And even if not then it's highly likely zero
+@c limb stripping can be done at just a few judicious points, which will be
+@c more efficient than having lots of mpn functions checking every time.
+
+@sp 1
+@noindent
+In the notation used below, a source operand is identified by the pointer to
+the least significant limb, and the limb count in braces. For example,
+@{@var{s1p}, @var{s1n}@}.
+
+@deftypefun mp_limb_t mpn_add_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Add @{@var{s1p}, @var{n}@} and @{@var{s2p}, @var{n}@}, and write the @var{n}
+least significant limbs of the result to @var{rp}. Return carry, either 0 or
+1.
+
+This is the lowest-level function for addition. It is the preferred function
+for addition, since it is written in assembly for most CPUs. For addition of
+a variable to itself (i.e., @var{s1p} equals @var{s2p}) use @code{mpn_lshift}
+with a count of 1 for optimal speed.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_add_1 (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{n}, mp_limb_t @var{s2limb})
+Add @{@var{s1p}, @var{n}@} and @var{s2limb}, and write the @var{n} least
+significant limbs of the result to @var{rp}. Return carry, either 0 or 1.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_add (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{s1n}, const mp_limb_t *@var{s2p}, mp_size_t @var{s2n})
+Add @{@var{s1p}, @var{s1n}@} and @{@var{s2p}, @var{s2n}@}, and write the
+@var{s1n} least significant limbs of the result to @var{rp}. Return carry,
+either 0 or 1.
+
+This function requires that @var{s1n} is greater than or equal to @var{s2n}.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_sub_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Subtract @{@var{s2p}, @var{n}@} from @{@var{s1p}, @var{n}@}, and write the
+@var{n} least significant limbs of the result to @var{rp}. Return borrow,
+either 0 or 1.
+
+This is the lowest-level function for subtraction. It is the preferred
+function for subtraction, since it is written in assembly for most CPUs.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_sub_1 (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{n}, mp_limb_t @var{s2limb})
+Subtract @var{s2limb} from @{@var{s1p}, @var{n}@}, and write the @var{n} least
+significant limbs of the result to @var{rp}. Return borrow, either 0 or 1.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_sub (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{s1n}, const mp_limb_t *@var{s2p}, mp_size_t @var{s2n})
+Subtract @{@var{s2p}, @var{s2n}@} from @{@var{s1p}, @var{s1n}@}, and write the
+@var{s1n} least significant limbs of the result to @var{rp}. Return borrow,
+either 0 or 1.
+
+This function requires that @var{s1n} is greater than or equal to
+@var{s2n}.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_neg (mp_limb_t *@var{rp}, const mp_limb_t *@var{sp}, mp_size_t @var{n})
+Perform the negation of @{@var{sp}, @var{n}@}, and write the result to
+@{@var{rp}, @var{n}@}. This is equivalent to calling @code{mpn_sub_n} with a
+@var{n}-limb zero minuend and passing @{@var{sp}, @var{n}@} as subtrahend.
+Return borrow, either 0 or 1.
+@end deftypefun
+
+@deftypefun void mpn_mul_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Multiply @{@var{s1p}, @var{n}@} and @{@var{s2p}, @var{n}@}, and write the
+2*@var{n}-limb result to @var{rp}.
+
+The destination has to have space for 2*@var{n} limbs, even if the product's
+most significant limb is zero. No overlap is permitted between the
+destination and either source.
+
+If the two input operands are the same, use @code{mpn_sqr}.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_mul (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{s1n}, const mp_limb_t *@var{s2p}, mp_size_t @var{s2n})
+Multiply @{@var{s1p}, @var{s1n}@} and @{@var{s2p}, @var{s2n}@}, and write the
+(@var{s1n}+@var{s2n})-limb result to @var{rp}. Return the most significant
+limb of the result.
+
+The destination has to have space for @var{s1n} + @var{s2n} limbs, even if the
+product's most significant limb is zero. No overlap is permitted between the
+destination and either source.
+
+This function requires that @var{s1n} is greater than or equal to @var{s2n}.
+@end deftypefun
+
+@deftypefun void mpn_sqr (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{n})
+Compute the square of @{@var{s1p}, @var{n}@} and write the 2*@var{n}-limb
+result to @var{rp}.
+
+The destination has to have space for 2@var{n} limbs, even if the result's
+most significant limb is zero. No overlap is permitted between the
+destination and the source.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_mul_1 (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{n}, mp_limb_t @var{s2limb})
+Multiply @{@var{s1p}, @var{n}@} by @var{s2limb}, and write the @var{n} least
+significant limbs of the product to @var{rp}. Return the most significant
+limb of the product. @{@var{s1p}, @var{n}@} and @{@var{rp}, @var{n}@} are
+allowed to overlap provided @math{@var{rp} @le{} @var{s1p}}.
+
+This is a low-level function that is a building block for general
+multiplication as well as other operations in GMP@. It is written in assembly
+for most CPUs.
+
+Don't call this function if @var{s2limb} is a power of 2; use @code{mpn_lshift}
+with a count equal to the logarithm of @var{s2limb} instead, for optimal speed.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_addmul_1 (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{n}, mp_limb_t @var{s2limb})
+Multiply @{@var{s1p}, @var{n}@} and @var{s2limb}, and add the @var{n} least
+significant limbs of the product to @{@var{rp}, @var{n}@} and write the result
+to @var{rp}. Return the most significant limb of the product, plus carry-out
+from the addition.
+
+This is a low-level function that is a building block for general
+multiplication as well as other operations in GMP@. It is written in assembly
+for most CPUs.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_submul_1 (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{n}, mp_limb_t @var{s2limb})
+Multiply @{@var{s1p}, @var{n}@} and @var{s2limb}, and subtract the @var{n}
+least significant limbs of the product from @{@var{rp}, @var{n}@} and write the
+result to @var{rp}. Return the most significant limb of the product, plus
+borrow-out from the subtraction.
+
+This is a low-level function that is a building block for general
+multiplication and division as well as other operations in GMP@. It is written
+in assembly for most CPUs.
+@end deftypefun
+
+@deftypefun void mpn_tdiv_qr (mp_limb_t *@var{qp}, mp_limb_t *@var{rp}, mp_size_t @var{qxn}, const mp_limb_t *@var{np}, mp_size_t @var{nn}, const mp_limb_t *@var{dp}, mp_size_t @var{dn})
+Divide @{@var{np}, @var{nn}@} by @{@var{dp}, @var{dn}@} and put the quotient
+at @{@var{qp}, @var{nn}@minus{}@var{dn}+1@} and the remainder at @{@var{rp},
+@var{dn}@}. The quotient is rounded towards 0.
+
+No overlap is permitted between arguments, except that @var{np} might equal
+@var{rp}. The dividend size @var{nn} must be greater than or equal to divisor
+size @var{dn}. The most significant limb of the divisor must be non-zero. The
+@var{qxn} operand must be zero.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_divrem (mp_limb_t *@var{r1p}, mp_size_t @var{qxn}, mp_limb_t *@var{rs2p}, mp_size_t @var{rs2n}, const mp_limb_t *@var{s3p}, mp_size_t @var{s3n})
+[This function is obsolete. Please call @code{mpn_tdiv_qr} instead for best
+performance.]
+
+Divide @{@var{rs2p}, @var{rs2n}@} by @{@var{s3p}, @var{s3n}@}, and write the
+quotient at @var{r1p}, with the exception of the most significant limb, which
+is returned. The remainder replaces the dividend at @var{rs2p}; it will be
+@var{s3n} limbs long (i.e., as many limbs as the divisor).
+
+In addition to an integer quotient, @var{qxn} fraction limbs are developed, and
+stored after the integral limbs. For most usages, @var{qxn} will be zero.
+
+It is required that @var{rs2n} is greater than or equal to @var{s3n}. It is
+required that the most significant bit of the divisor is set.
+
+If the quotient is not needed, pass @var{rs2p} + @var{s3n} as @var{r1p}. Aside
+from that special case, no overlap between arguments is permitted.
+
+Return the most significant limb of the quotient, either 0 or 1.
+
+The area at @var{r1p} needs to be @var{rs2n} @minus{} @var{s3n} + @var{qxn}
+limbs large.
+@end deftypefun
+
+@deftypefn Function mp_limb_t mpn_divrem_1 (mp_limb_t *@var{r1p}, mp_size_t @var{qxn}, @w{mp_limb_t *@var{s2p}}, mp_size_t @var{s2n}, mp_limb_t @var{s3limb})
+@deftypefnx Macro mp_limb_t mpn_divmod_1 (mp_limb_t *@var{r1p}, mp_limb_t *@var{s2p}, @w{mp_size_t @var{s2n}}, @w{mp_limb_t @var{s3limb}})
+Divide @{@var{s2p}, @var{s2n}@} by @var{s3limb}, and write the quotient at
+@var{r1p}. Return the remainder.
+
+The integer quotient is written to @{@var{r1p}+@var{qxn}, @var{s2n}@} and in
+addition @var{qxn} fraction limbs are developed and written to @{@var{r1p},
+@var{qxn}@}. Either or both @var{s2n} and @var{qxn} can be zero. For most
+usages, @var{qxn} will be zero.
+
+@code{mpn_divmod_1} exists for upward source compatibility and is simply a
+macro calling @code{mpn_divrem_1} with a @var{qxn} of 0.
+
+The areas at @var{r1p} and @var{s2p} have to be identical or completely
+separate, not partially overlapping.
+@end deftypefn
+
+@deftypefun mp_limb_t mpn_divmod (mp_limb_t *@var{r1p}, mp_limb_t *@var{rs2p}, mp_size_t @var{rs2n}, const mp_limb_t *@var{s3p}, mp_size_t @var{s3n})
+[This function is obsolete. Please call @code{mpn_tdiv_qr} instead for best
+performance.]
+@end deftypefun
+
+@deftypefn Macro mp_limb_t mpn_divexact_by3 (mp_limb_t *@var{rp}, mp_limb_t *@var{sp}, @w{mp_size_t @var{n}})
+@deftypefnx Function mp_limb_t mpn_divexact_by3c (mp_limb_t *@var{rp}, mp_limb_t *@var{sp}, @w{mp_size_t @var{n}}, mp_limb_t @var{carry})
+Divide @{@var{sp}, @var{n}@} by 3, expecting it to divide exactly, and writing
+the result to @{@var{rp}, @var{n}@}. If 3 divides exactly, the return value is
+zero and the result is the quotient. If not, the return value is non-zero and
+the result won't be anything useful.
+
+@code{mpn_divexact_by3c} takes an initial carry parameter, which can be the
+return value from a previous call, so a large calculation can be done piece by
+piece from low to high. @code{mpn_divexact_by3} is simply a macro calling
+@code{mpn_divexact_by3c} with a 0 carry parameter.
+
+These routines use a multiply-by-inverse and will be faster than
+@code{mpn_divrem_1} on CPUs with fast multiplication but slow division.
+
+The source @math{a}, result @math{q}, size @math{n}, initial carry @math{i},
+and return value @math{c} satisfy @m{cb^n+a-i=3q, c*b^n + a-i = 3*q}, where
+@m{b=2\GMPraise{@code{GMP\_NUMB\_BITS}}, b=2^GMP_NUMB_BITS}. The
+return @math{c} is always 0, 1 or 2, and the initial carry @math{i} must also
+be 0, 1 or 2 (these are both borrows really). When @math{c=0} clearly
+@math{q=(a-i)/3}. When @m{c \neq 0, c!=0}, the remainder @math{(a-i) @bmod{}
+3} is given by @math{3-c}, because @math{b @equiv{} 1 @bmod{} 3} (when
+@code{mp_bits_per_limb} is even, which is always so currently).
+@end deftypefn
+
+@deftypefun mp_limb_t mpn_mod_1 (const mp_limb_t *@var{s1p}, mp_size_t @var{s1n}, mp_limb_t @var{s2limb})
+Divide @{@var{s1p}, @var{s1n}@} by @var{s2limb}, and return the remainder.
+@var{s1n} can be zero.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_lshift (mp_limb_t *@var{rp}, const mp_limb_t *@var{sp}, mp_size_t @var{n}, unsigned int @var{count})
+Shift @{@var{sp}, @var{n}@} left by @var{count} bits, and write the result to
+@{@var{rp}, @var{n}@}. The bits shifted out at the left are returned in the
+least significant @var{count} bits of the return value (the rest of the return
+value is zero).
+
+@var{count} must be in the range 1 to @nicode{mp_bits_per_limb}@minus{}1. The
+regions @{@var{sp}, @var{n}@} and @{@var{rp}, @var{n}@} may overlap, provided
+@math{@var{rp} @ge{} @var{sp}}.
+
+This function is written in assembly for most CPUs.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_rshift (mp_limb_t *@var{rp}, const mp_limb_t *@var{sp}, mp_size_t @var{n}, unsigned int @var{count})
+Shift @{@var{sp}, @var{n}@} right by @var{count} bits, and write the result to
+@{@var{rp}, @var{n}@}. The bits shifted out at the right are returned in the
+most significant @var{count} bits of the return value (the rest of the return
+value is zero).
+
+@var{count} must be in the range 1 to @nicode{mp_bits_per_limb}@minus{}1. The
+regions @{@var{sp}, @var{n}@} and @{@var{rp}, @var{n}@} may overlap, provided
+@math{@var{rp} @le{} @var{sp}}.
+
+This function is written in assembly for most CPUs.
+@end deftypefun
+
+@deftypefun int mpn_cmp (const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Compare @{@var{s1p}, @var{n}@} and @{@var{s2p}, @var{n}@} and return a
+positive value if @math{@var{s1} > @var{s2}}, 0 if they are equal, or a
+negative value if @math{@var{s1} < @var{s2}}.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_gcd (mp_limb_t *@var{rp}, mp_limb_t *@var{xp}, mp_size_t @var{xn}, mp_limb_t *@var{yp}, mp_size_t @var{yn})
+Set @{@var{rp}, @var{retval}@} to the greatest common divisor of @{@var{xp},
+@var{xn}@} and @{@var{yp}, @var{yn}@}. The result can be up to @var{yn} limbs,
+the return value is the actual number produced. Both source operands are
+destroyed.
+
+It is required that @math{@var{xn} @ge @var{yn} > 0}, and the most significant
+limb of @{@var{yp}, @var{yn}@} must be non-zero. No overlap is permitted
+between @{@var{xp}, @var{xn}@} and @{@var{yp}, @var{yn}@}.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_gcd_1 (const mp_limb_t *@var{xp}, mp_size_t @var{xn}, mp_limb_t @var{ylimb})
+Return the greatest common divisor of @{@var{xp}, @var{xn}@} and @var{ylimb}.
+Both operands must be non-zero.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_gcdext (mp_limb_t *@var{gp}, mp_limb_t *@var{sp}, mp_size_t *@var{sn}, mp_limb_t *@var{up}, mp_size_t @var{un}, mp_limb_t *@var{vp}, mp_size_t @var{vn})
+Let @m{U,@var{U}} be defined by @{@var{up}, @var{un}@} and let @m{V,@var{V}} be
+defined by @{@var{vp}, @var{vn}@}.
+
+Compute the greatest common divisor @math{G} of @math{U} and @math{V}. Compute
+a cofactor @math{S} such that @math{G = US + VT}. The second cofactor @var{T}
+is not computed but can easily be obtained from @m{(G - US) / V, (@var{G} -
+@var{U}*@var{S}) / @var{V}} (the division will be exact). It is required that
+@math{@var{un} @ge @var{vn} > 0}, and the most significant
+limb of @{@var{vp}, @var{vn}@} must be non-zero.
+
+@math{S} satisfies @math{S = 1} or @math{@GMPabs{S} < V / (2 G)}. @math{S =
+0} if and only if @math{V} divides @math{U} (i.e., @math{G = V}).
+
+Store @math{G} at @var{gp} and let the return value define its limb count.
+Store @math{S} at @var{sp} and let |*@var{sn}| define its limb count. @math{S}
+can be negative; when this happens *@var{sn} will be negative. The area at
+@var{gp} should have room for @var{vn} limbs and the area at @var{sp} should
+have room for @math{@var{vn}+1} limbs.
+
+Both source operands are destroyed.
+
+Compatibility notes: GMP 4.3.0 and 4.3.1 defined @math{S} less strictly.
+Earlier as well as later GMP releases define @math{S} as described here.
+GMP releases before GMP 4.3.0 required additional space for both input and output
+areas. More precisely, the areas @{@var{up}, @math{@var{un}+1}@} and
+@{@var{vp}, @math{@var{vn}+1}@} were destroyed (i.e.@: the operands plus an
+extra limb past the end of each), and the areas pointed to by @var{gp} and
+@var{sp} should each have room for @math{@var{un}+1} limbs.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_sqrtrem (mp_limb_t *@var{r1p}, mp_limb_t *@var{r2p}, const mp_limb_t *@var{sp}, mp_size_t @var{n})
+Compute the square root of @{@var{sp}, @var{n}@} and put the result at
+@{@var{r1p}, @math{@GMPceil{@var{n}/2}}@} and the remainder at @{@var{r2p},
+@var{retval}@}. @var{r2p} needs space for @var{n} limbs, but the return value
+indicates how many are produced.
+
+The most significant limb of @{@var{sp}, @var{n}@} must be non-zero. The
+areas @{@var{r1p}, @math{@GMPceil{@var{n}/2}}@} and @{@var{sp}, @var{n}@} must
+be completely separate. The areas @{@var{r2p}, @var{n}@} and @{@var{sp},
+@var{n}@} must be either identical or completely separate.
+
+If the remainder is not wanted then @var{r2p} can be @code{NULL}, and in this
+case the return value is zero or non-zero according to whether the remainder
+would have been zero or non-zero.
+
+A return value of zero indicates a perfect square. See also
+@code{mpn_perfect_square_p}.
+@end deftypefun
+
+@deftypefun size_t mpn_sizeinbase (const mp_limb_t *@var{xp}, mp_size_t @var{n}, int @var{base})
+Return the size of @{@var{xp},@var{n}@} measured in number of digits in the
+given @var{base}. @var{base} can vary from 2 to 62. Requires @math{@var{n} > 0}
+and @math{@var{xp}[@var{n}-1] > 0}. The result will be either exact or
+1 too big. If @var{base} is a power of 2, the result is always exact.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_get_str (unsigned char *@var{str}, int @var{base}, mp_limb_t *@var{s1p}, mp_size_t @var{s1n})
+Convert @{@var{s1p}, @var{s1n}@} to a raw unsigned char array at @var{str} in
+base @var{base}, and return the number of characters produced. There may be
+leading zeros in the string. The string is not in ASCII; to convert it to
+printable format, add the ASCII codes for @samp{0} or @samp{A}, depending on
+the base and range. @var{base} can vary from 2 to 256.
+
+The most significant limb of the input @{@var{s1p}, @var{s1n}@} must be
+non-zero. The input @{@var{s1p}, @var{s1n}@} is clobbered, except when
+@var{base} is a power of 2, in which case it's unchanged.
+
+The area at @var{str} has to have space for the largest possible number
+represented by a @var{s1n} long limb array, plus one extra character.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_set_str (mp_limb_t *@var{rp}, const unsigned char *@var{str}, size_t @var{strsize}, int @var{base})
+Convert bytes @{@var{str},@var{strsize}@} in the given @var{base} to limbs at
+@var{rp}.
+
+@math{@var{str}[0]} is the most significant input byte and
+@math{@var{str}[@var{strsize}-1]} is the least significant input byte. Each
+byte should be a value in the range 0 to @math{@var{base}-1}, not an ASCII
+character. @var{base} can vary from 2 to 256.
+
+The converted value is @{@var{rp},@var{rn}@} where @var{rn} is the return
+value. If the most significant input byte @math{@var{str}[0]} is non-zero,
+then @math{@var{rp}[@var{rn}-1]} will be non-zero, else
+@math{@var{rp}[@var{rn}-1]} and some number of subsequent limbs may be zero.
+
+The area at @var{rp} has to have space for the largest possible number with
+@var{strsize} digits in the chosen base, plus one extra limb.
+
+The input must have at least one byte, and no overlap is permitted between
+@{@var{str},@var{strsize}@} and the result at @var{rp}.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpn_scan0 (const mp_limb_t *@var{s1p}, mp_bitcnt_t @var{bit})
+Scan @var{s1p} from bit position @var{bit} for the next clear bit.
+
+It is required that there be a clear bit within the area at @var{s1p} at or
+beyond bit position @var{bit}, so that the function has something to return.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpn_scan1 (const mp_limb_t *@var{s1p}, mp_bitcnt_t @var{bit})
+Scan @var{s1p} from bit position @var{bit} for the next set bit.
+
+It is required that there be a set bit within the area at @var{s1p} at or
+beyond bit position @var{bit}, so that the function has something to return.
+@end deftypefun
+
+@deftypefun void mpn_random (mp_limb_t *@var{r1p}, mp_size_t @var{r1n})
+@deftypefunx void mpn_random2 (mp_limb_t *@var{r1p}, mp_size_t @var{r1n})
+Generate a random number of length @var{r1n} and store it at @var{r1p}. The
+most significant limb is always non-zero. @code{mpn_random} generates
+uniformly distributed limb data, @code{mpn_random2} generates long strings of
+zeros and ones in the binary representation.
+
+@code{mpn_random2} is intended for testing the correctness of the @code{mpn}
+routines.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpn_popcount (const mp_limb_t *@var{s1p}, mp_size_t @var{n})
+Count the number of set bits in @{@var{s1p}, @var{n}@}.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpn_hamdist (const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Compute the hamming distance between @{@var{s1p}, @var{n}@} and @{@var{s2p},
+@var{n}@}, which is the number of bit positions where the two operands have
+different bit values.
+@end deftypefun
+
+@deftypefun int mpn_perfect_square_p (const mp_limb_t *@var{s1p}, mp_size_t @var{n})
+Return non-zero iff @{@var{s1p}, @var{n}@} is a perfect square.
+The most significant limb of the input @{@var{s1p}, @var{n}@} must be
+non-zero.
+@end deftypefun
+
+@deftypefun void mpn_and_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Perform the bitwise logical and of @{@var{s1p}, @var{n}@} and @{@var{s2p},
+@var{n}@}, and write the result to @{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@deftypefun void mpn_ior_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Perform the bitwise logical inclusive or of @{@var{s1p}, @var{n}@} and
+@{@var{s2p}, @var{n}@}, and write the result to @{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@deftypefun void mpn_xor_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Perform the bitwise logical exclusive or of @{@var{s1p}, @var{n}@} and
+@{@var{s2p}, @var{n}@}, and write the result to @{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@deftypefun void mpn_andn_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Perform the bitwise logical and of @{@var{s1p}, @var{n}@} and the bitwise
+complement of @{@var{s2p}, @var{n}@}, and write the result to @{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@deftypefun void mpn_iorn_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Perform the bitwise logical inclusive or of @{@var{s1p}, @var{n}@} and the bitwise
+complement of @{@var{s2p}, @var{n}@}, and write the result to @{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@deftypefun void mpn_nand_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Perform the bitwise logical and of @{@var{s1p}, @var{n}@} and @{@var{s2p},
+@var{n}@}, and write the bitwise complement of the result to @{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@deftypefun void mpn_nior_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Perform the bitwise logical inclusive or of @{@var{s1p}, @var{n}@} and
+@{@var{s2p}, @var{n}@}, and write the bitwise complement of the result to
+@{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@deftypefun void mpn_xnor_n (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+Perform the bitwise logical exclusive or of @{@var{s1p}, @var{n}@} and
+@{@var{s2p}, @var{n}@}, and write the bitwise complement of the result to
+@{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@deftypefun void mpn_com (mp_limb_t *@var{rp}, const mp_limb_t *@var{sp}, mp_size_t @var{n})
+Perform the bitwise complement of @{@var{sp}, @var{n}@}, and write the result
+to @{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@deftypefun void mpn_copyi (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{n})
+Copy from @{@var{s1p}, @var{n}@} to @{@var{rp}, @var{n}@}, increasingly.
+@end deftypefun
+
+@deftypefun void mpn_copyd (mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, mp_size_t @var{n})
+Copy from @{@var{s1p}, @var{n}@} to @{@var{rp}, @var{n}@}, decreasingly.
+@end deftypefun
+
+@deftypefun void mpn_zero (mp_limb_t *@var{rp}, mp_size_t @var{n})
+Zero @{@var{rp}, @var{n}@}.
+@end deftypefun
+
+@sp 1
+@section Low-level functions for cryptography
+@cindex Low-level functions for cryptography
+@cindex Cryptography functions, low-level
+
+The functions prefixed with @code{mpn_sec_} and @code{mpn_cnd_} are designed to
+perform the exact same low-level operations and have the same cache access
+patterns for any two same-size arguments, assuming that function arguments are
+placed at the same position and that the machine state is identical upon
+function entry. These functions are intended for cryptographic purposes, where
+resilience to side-channel attacks is desired.
+
+These functions are less efficient than their ``leaky'' counterparts; their
+performance for operands of the sizes typically used for cryptographic
+applications is between 15% and 100% worse. For larger operands, these
+functions might be inadequate, since they rely on asymptotically elementary
+algorithms.
+
+These functions do not make any explicit allocations. Those of these functions
+that need scratch space accept a scratch space operand. This convention allows
+callers to keep sensitive data in designated memory areas. Note however that
+compilers may choose to spill scalar values used within these functions to
+their stack frame and that such scalars may contain sensitive data.
+
+In addition to these specially crafted functions, the following @code{mpn}
+functions are naturally side-channel resistant: @code{mpn_add_n},
+@code{mpn_sub_n}, @code{mpn_lshift}, @code{mpn_rshift}, @code{mpn_zero},
+@code{mpn_copyi}, @code{mpn_copyd}, @code{mpn_com}, and the logical function
+(@code{mpn_and_n}, etc).
+
+There are some exceptions from the side-channel resilience: (1) Some assembly
+implementations of @code{mpn_lshift} identify shift-by-one as a special case.
+This is a problem iff the shift count is a function of sensitive data. (2)
+Alpha ev6 and Pentium4 using 64-bit limbs have leaky @code{mpn_add_n} and
+@code{mpn_sub_n}. (3) Alpha ev6 has a leaky @code{mpn_mul_1} which also makes
+@code{mpn_sec_mul} on those systems unsafe.
+
+@deftypefun mp_limb_t mpn_cnd_add_n (mp_limb_t @var{cnd}, mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+@deftypefunx mp_limb_t mpn_cnd_sub_n (mp_limb_t @var{cnd}, mp_limb_t *@var{rp}, const mp_limb_t *@var{s1p}, const mp_limb_t *@var{s2p}, mp_size_t @var{n})
+These functions do conditional addition and subtraction. If @var{cnd} is
+non-zero, they produce the same result as a regular @code{mpn_add_n} or
+@code{mpn_sub_n}, and if @var{cnd} is zero, they copy @{@var{s1p},@var{n}@} to
+the result area and return zero. The functions are designed to have timing and
+memory access patterns depending only on size and location of the data areas,
+but independent of the condition @var{cnd}. Like for @code{mpn_add_n} and
+@code{mpn_sub_n}, on most machines, the timing will also be independent of the
+actual limb values.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_sec_add_1 (mp_limb_t *@var{rp}, const mp_limb_t *@var{ap}, mp_size_t @var{n}, mp_limb_t @var{b}, mp_limb_t *@var{tp})
+@deftypefunx mp_limb_t mpn_sec_sub_1 (mp_limb_t *@var{rp}, const mp_limb_t *@var{ap}, mp_size_t @var{n}, mp_limb_t @var{b}, mp_limb_t *@var{tp})
+Set @var{R} to @var{A} + @var{b} or @var{A} - @var{b}, respectively, where
+@var{R} = @{@var{rp},@var{n}@}, @var{A} = @{@var{ap},@var{n}@}, and @var{b} is
+a single limb. Returns carry.
+
+These functions take @math{O(N)} time, unlike the leaky functions
+@code{mpn_add_1} which are @math{O(1)} on average. They require scratch space
+of @code{mpn_sec_add_1_itch(@var{n})} and @code{mpn_sec_sub_1_itch(@var{n})}
+limbs, respectively, to be passed in the @var{tp} parameter. The scratch space
+requirements are guaranteed to increase monotonously in the operand size.
+@end deftypefun
+
+@deftypefun void mpn_sec_mul (mp_limb_t *@var{rp}, const mp_limb_t *@var{ap}, mp_size_t @var{an}, const mp_limb_t *@var{bp}, mp_size_t @var{bn}, mp_limb_t *@var{tp})
+@deftypefunx mp_size_t mpn_sec_mul_itch (mp_size_t @var{an}, mp_size_t @var{bn})
+Set @var{R} to @math{A @times{} B}, where @var{A} = @{@var{ap},@var{an}@},
+@var{B} = @{@var{bp},@var{bn}@}, and @var{R} =
+@{@var{rp},@math{@var{an}+@var{bn}}@}.
+
+It is required that @math{@var{an} @ge @var{bn} > 0}.
+
+No overlapping between @var{R} and the input operands is allowed. For
+@math{@var{A} = @var{B}}, use @code{mpn_sec_sqr} for optimal performance.
+
+This function requires scratch space of @code{mpn_sec_mul_itch(@var{an},
+@var{bn})} limbs to be passed in the @var{tp} parameter. The scratch space
+requirements are guaranteed to increase monotonously in the operand sizes.
+@end deftypefun
+
+
+@deftypefun void mpn_sec_sqr (mp_limb_t *@var{rp}, const mp_limb_t *@var{ap}, mp_size_t @var{an}, mp_limb_t *@var{tp})
+@deftypefunx mp_size_t mpn_sec_sqr_itch (mp_size_t @var{an})
+Set @var{R} to @math{A^2}, where @var{A} = @{@var{ap},@var{an}@}, and @var{R} =
+@{@var{rp},@math{2@var{an}}@}.
+
+It is required that @math{@var{an} > 0}.
+
+No overlapping between @var{R} and the input operands is allowed.
+
+This function requires scratch space of @code{mpn_sec_sqr_itch(@var{an})} limbs
+to be passed in the @var{tp} parameter. The scratch space requirements are
+guaranteed to increase monotonously in the operand size.
+@end deftypefun
+
+
+@deftypefun void mpn_sec_powm (mp_limb_t *@var{rp}, const mp_limb_t *@var{bp}, mp_size_t @var{bn}, const mp_limb_t *@var{ep}, mp_bitcnt_t @var{enb}, const mp_limb_t *@var{mp}, mp_size_t @var{n}, mp_limb_t *@var{tp})
+@deftypefunx mp_size_t mpn_sec_powm_itch (mp_size_t @var{bn}, mp_bitcnt_t @var{enb}, size_t @var{n})
+Set @var{R} to @m{B^E \bmod @var{M}, (@var{B} raised to @var{E}) modulo
+@var{M}}, where @var{R} = @{@var{rp},@var{n}@}, @var{M} = @{@var{mp},@var{n}@},
+and @var{E} = @{@var{ep},@math{@GMPceil{@var{enb} /
+@code{GMP\_NUMB\_BITS}}}@}.
+
+It is required that @math{@var{B} > 0}, that @math{@var{M} > 0} is odd, and
+that @m{@var{E} < 2@GMPraise{@var{enb}}, @var{E} < 2^@var{enb}}.
+
+No overlapping between @var{R} and the input operands is allowed.
+
+This function requires scratch space of @code{mpn_sec_powm_itch(@var{bn},
+@var{enb}, @var{n})} limbs to be passed in the @var{tp} parameter. The scratch
+space requirements are guaranteed to increase monotonously in the operand
+sizes.
+@end deftypefun
+
+@deftypefun void mpn_sec_tabselect (mp_limb_t *@var{rp}, const mp_limb_t *@var{tab}, mp_size_t @var{n}, mp_size_t @var{nents}, mp_size_t @var{which})
+Select entry @var{which} from table @var{tab}, which has @var{nents} entries, each @var{n}
+limbs. Store the selected entry at @var{rp}.
+
+This function reads the entire table to avoid side-channel information leaks.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_sec_div_qr (mp_limb_t *@var{qp}, mp_limb_t *@var{np}, mp_size_t @var{nn}, const mp_limb_t *@var{dp}, mp_size_t @var{dn}, mp_limb_t *@var{tp})
+@deftypefunx mp_size_t mpn_sec_div_qr_itch (mp_size_t @var{nn}, mp_size_t @var{dn})
+
+Set @var{Q} to @m{\lfloor @var{N} / @var{D}\rfloor, the truncated quotient
+@var{N} / @var{D}} and @var{R} to @m{@var{N} \bmod @var{D}, @var{N} modulo
+@var{D}}, where @var{N} = @{@var{np},@var{nn}@}, @var{D} =
+@{@var{dp},@var{dn}@}, @var{Q}'s most significant limb is the function return
+value and the remaining limbs are @{@var{qp},@var{nn-dn}@}, and @var{R} =
+@{@var{np},@var{dn}@}.
+
+It is required that @math{@var{nn} @ge @var{dn} @ge 1}, and that
+@m{@var{dp}[@var{dn}-1] @neq 0, @var{dp}[@var{dn}-1] != 0}. This does not
+imply that @math{@var{N} @ge @var{D}} since @var{N} might be zero-padded.
+
+Note the overlapping between @var{N} and @var{R}. No other operand overlapping
+is allowed. The entire space occupied by @var{N} is overwritten.
+
+This function requires scratch space of @code{mpn_sec_div_qr_itch(@var{nn},
+@var{dn})} limbs to be passed in the @var{tp} parameter.
+@end deftypefun
+
+@deftypefun void mpn_sec_div_r (mp_limb_t *@var{np}, mp_size_t @var{nn}, const mp_limb_t *@var{dp}, mp_size_t @var{dn}, mp_limb_t *@var{tp})
+@deftypefunx mp_size_t mpn_sec_div_r_itch (mp_size_t @var{nn}, mp_size_t @var{dn})
+
+Set @var{R} to @m{@var{N} \bmod @var{D}, @var{N} modulo @var{D}}, where @var{N}
+= @{@var{np},@var{nn}@}, @var{D} = @{@var{dp},@var{dn}@}, and @var{R} =
+@{@var{np},@var{dn}@}.
+
+It is required that @math{@var{nn} @ge @var{dn} @ge 1}, and that
+@m{@var{dp}[@var{dn}-1] @neq 0, @var{dp}[@var{dn}-1] != 0}. This does not
+imply that @math{@var{N} @ge @var{D}} since @var{N} might be zero-padded.
+
+Note the overlapping between @var{N} and @var{R}. No other operand overlapping
+is allowed. The entire space occupied by @var{N} is overwritten.
+
+This function requires scratch space of @code{mpn_sec_div_r_itch(@var{nn},
+@var{dn})} limbs to be passed in the @var{tp} parameter.
+@end deftypefun
+
+@deftypefun int mpn_sec_invert (mp_limb_t *@var{rp}, mp_limb_t *@var{ap}, const mp_limb_t *@var{mp}, mp_size_t @var{n}, mp_bitcnt_t @var{nbcnt}, mp_limb_t *@var{tp})
+@deftypefunx mp_size_t mpn_sec_invert_itch (mp_size_t @var{n})
+Set @var{R} to @m{@var{A}^{-1} \bmod @var{M}, the inverse of @var{A} modulo
+@var{M}}, where @var{R} = @{@var{rp},@var{n}@}, @var{A} = @{@var{ap},@var{n}@},
+and @var{M} = @{@var{mp},@var{n}@}. @strong{This function's interface is
+preliminary.}
+
+If an inverse exists, return 1, otherwise return 0 and leave @var{R}
+undefined. In either case, the input @var{A} is destroyed.
+
+It is required that @var{M} is odd, and that @math{@var{nbcnt} @ge
+@GMPceil{\log(@var{A}+1)} + @GMPceil{\log(@var{M}+1)}}. A safe choice is
+@m{@var{nbcnt} = 2@var{n} @times{} @code{GMP\_NUMB\_BITS}, @var{nbcnt} = 2
+@times{} @var{n} @times{} GMP_NUMB_BITS}, but a smaller value might improve
+performance if @var{M} or @var{A} are known to have leading zero bits.
+
+This function requires scratch space of @code{mpn_sec_invert_itch(@var{n})}
+limbs to be passed in the @var{tp} parameter.
+@end deftypefun
+
+
+@sp 1
+@section Nails
+@cindex Nails
+
+@strong{Everything in this section is highly experimental and may disappear or
+be subject to incompatible changes in a future version of GMP.}
+
+Nails are an experimental feature whereby a few bits are left unused at the
+top of each @code{mp_limb_t}. This can significantly improve carry handling
+on some processors.
+
+All the @code{mpn} functions accepting limb data will expect the nail bits to
+be zero on entry, and will return data with the nails similarly all zero.
+This applies both to limb vectors and to single limb arguments.
+
+Nails can be enabled by configuring with @samp{--enable-nails}. By default
+the number of bits will be chosen according to what suits the host processor,
+but a particular number can be selected with @samp{--enable-nails=N}.
+
+At the mpn level, a nail build is neither source nor binary compatible with a
+non-nail build, strictly speaking. But programs acting on limbs only through
+the mpn functions are likely to work equally well with either build, and
+judicious use of the definitions below should make any program compatible with
+either build, at the source level.
+
+For the higher level routines, meaning @code{mpz} etc, a nail build should be
+fully source and binary compatible with a non-nail build.
+
+@defmac GMP_NAIL_BITS
+@defmacx GMP_NUMB_BITS
+@defmacx GMP_LIMB_BITS
+@code{GMP_NAIL_BITS} is the number of nail bits, or 0 when nails are not in
+use. @code{GMP_NUMB_BITS} is the number of data bits in a limb.
+@code{GMP_LIMB_BITS} is the total number of bits in an @code{mp_limb_t}. In
+all cases
+
+@example
+GMP_LIMB_BITS == GMP_NAIL_BITS + GMP_NUMB_BITS
+@end example
+@end defmac
+
+@defmac GMP_NAIL_MASK
+@defmacx GMP_NUMB_MASK
+Bit masks for the nail and number parts of a limb. @code{GMP_NAIL_MASK} is 0
+when nails are not in use.
+
+@code{GMP_NAIL_MASK} is not often needed, since the nail part can be obtained
+with @code{x >> GMP_NUMB_BITS}, and that means one less large constant, which
+can help various RISC chips.
+@end defmac
+
+@defmac GMP_NUMB_MAX
+The maximum value that can be stored in the number part of a limb. This is
+the same as @code{GMP_NUMB_MASK}, but can be used for clarity when doing
+comparisons rather than bit-wise operations.
+@end defmac
+
+The term ``nails'' comes from finger or toe nails, which are at the ends of a
+limb (arm or leg). ``numb'' is short for number, but is also how the
+developers felt after trying for a long time to come up with sensible names
+for these things.
+
+In the future (the distant future most likely) a non-zero nail might be
+permitted, giving non-unique representations for numbers in a limb vector.
+This would help vector processors since carries would only ever need to
+propagate one or two limbs.
+
+
+@node Random Number Functions, Formatted Output, Low-level Functions, Top
+@chapter Random Number Functions
+@cindex Random number functions
+
+Sequences of pseudo-random numbers in GMP are generated using a variable of
+type @code{gmp_randstate_t}, which holds an algorithm selection and a current
+state. Such a variable must be initialized by a call to one of the
+@code{gmp_randinit} functions, and can be seeded with one of the
+@code{gmp_randseed} functions.
+
+The functions actually generating random numbers are described in @ref{Integer
+Random Numbers}, and @ref{Miscellaneous Float Functions}.
+
+The older style random number functions don't accept a @code{gmp_randstate_t}
+parameter but instead share a global variable of that type. They use a
+default algorithm and are currently not seeded (though perhaps that will
+change in the future). The new functions accepting a @code{gmp_randstate_t}
+are recommended for applications that care about randomness.
+
+@menu
+* Random State Initialization::
+* Random State Seeding::
+* Random State Miscellaneous::
+@end menu
+
+@node Random State Initialization, Random State Seeding, Random Number Functions, Random Number Functions
+@section Random State Initialization
+@cindex Random number state
+@cindex Initialization functions
+
+@deftypefun void gmp_randinit_default (gmp_randstate_t @var{state})
+Initialize @var{state} with a default algorithm. This will be a compromise
+between speed and randomness, and is recommended for applications with no
+special requirements. Currently this is @code{gmp_randinit_mt}.
+@end deftypefun
+
+@deftypefun void gmp_randinit_mt (gmp_randstate_t @var{state})
+@cindex Mersenne twister random numbers
+Initialize @var{state} for a Mersenne Twister algorithm. This algorithm is
+fast and has good randomness properties.
+@end deftypefun
+
+@deftypefun void gmp_randinit_lc_2exp (gmp_randstate_t @var{state}, const mpz_t @var{a}, @w{unsigned long @var{c}}, @w{mp_bitcnt_t @var{m2exp}})
+@cindex Linear congruential random numbers
+Initialize @var{state} with a linear congruential algorithm @m{X = (@var{a}X +
+@var{c}) @bmod 2^{m2exp}, X = (@var{a}*X + @var{c}) mod 2^@var{m2exp}}.
+
+The low bits of @math{X} in this algorithm are not very random. The least
+significant bit will have a period no more than 2, and the second bit no more
+than 4, etc. For this reason only the high half of each @math{X} is actually
+used.
+
+When a random number of more than @math{@var{m2exp}/2} bits is to be
+generated, multiple iterations of the recurrence are used and the results
+concatenated.
+@end deftypefun
+
+@deftypefun int gmp_randinit_lc_2exp_size (gmp_randstate_t @var{state}, mp_bitcnt_t @var{size})
+@cindex Linear congruential random numbers
+Initialize @var{state} for a linear congruential algorithm as per
+@code{gmp_randinit_lc_2exp}. @var{a}, @var{c} and @var{m2exp} are selected
+from a table, chosen so that @var{size} bits (or more) of each @math{X} will
+be used, i.e.@: @math{@var{m2exp}/2 @ge{} @var{size}}.
+
+If successful the return value is non-zero. If @var{size} is bigger than the
+table data provides then the return value is zero. The maximum @var{size}
+currently supported is 128.
+@end deftypefun
+
+@deftypefun void gmp_randinit_set (gmp_randstate_t @var{rop}, gmp_randstate_t @var{op})
+Initialize @var{rop} with a copy of the algorithm and state from @var{op}.
+@end deftypefun
+
+@c Although gmp_randinit, gmp_errno and related constants are obsolete, we
+@c still put @findex entries for them, since they're still documented and
+@c someone might be looking them up when perusing old application code.
+
+@deftypefun void gmp_randinit (gmp_randstate_t @var{state}, @w{gmp_randalg_t @var{alg}}, @dots{})
+@strong{This function is obsolete.}
+
+@findex GMP_RAND_ALG_LC
+@findex GMP_RAND_ALG_DEFAULT
+Initialize @var{state} with an algorithm selected by @var{alg}. The only
+choice is @code{GMP_RAND_ALG_LC}, which is @code{gmp_randinit_lc_2exp_size}
+described above. A third parameter of type @code{unsigned long} is required,
+this is the @var{size} for that function. @code{GMP_RAND_ALG_DEFAULT} or 0
+are the same as @code{GMP_RAND_ALG_LC}.
+
+@c For reference, this is the only place gmp_errno has been documented, and
+@c due to being non thread safe we won't be adding to it's uses.
+@findex gmp_errno
+@findex GMP_ERROR_UNSUPPORTED_ARGUMENT
+@findex GMP_ERROR_INVALID_ARGUMENT
+@code{gmp_randinit} sets bits in the global variable @code{gmp_errno} to
+indicate an error. @code{GMP_ERROR_UNSUPPORTED_ARGUMENT} if @var{alg} is
+unsupported, or @code{GMP_ERROR_INVALID_ARGUMENT} if the @var{size} parameter
+is too big. It may be noted this error reporting is not thread safe (a good
+reason to use @code{gmp_randinit_lc_2exp_size} instead).
+@end deftypefun
+
+@deftypefun void gmp_randclear (gmp_randstate_t @var{state})
+Free all memory occupied by @var{state}.
+@end deftypefun
+
+
+@node Random State Seeding, Random State Miscellaneous, Random State Initialization, Random Number Functions
+@section Random State Seeding
+@cindex Random number seeding
+@cindex Seeding random numbers
+
+@deftypefun void gmp_randseed (gmp_randstate_t @var{state}, const mpz_t @var{seed})
+@deftypefunx void gmp_randseed_ui (gmp_randstate_t @var{state}, @w{unsigned long int @var{seed}})
+Set an initial seed value into @var{state}.
+
+The size of a seed determines how many different sequences of random numbers
+that it's possible to generate. The ``quality'' of the seed is the randomness
+of a given seed compared to the previous seed used, and this affects the
+randomness of separate number sequences. The method for choosing a seed is
+critical if the generated numbers are to be used for important applications,
+such as generating cryptographic keys.
+
+Traditionally the system time has been used to seed, but care needs to be
+taken with this. If an application seeds often and the resolution of the
+system clock is low, then the same sequence of numbers might be repeated.
+Also, the system time is quite easy to guess, so if unpredictability is
+required then it should definitely not be the only source for the seed value.
+On some systems there's a special device @file{/dev/random} which provides
+random data better suited for use as a seed.
+@end deftypefun
+
+
+@node Random State Miscellaneous, , Random State Seeding, Random Number Functions
+@section Random State Miscellaneous
+
+@deftypefun {unsigned long} gmp_urandomb_ui (gmp_randstate_t @var{state}, unsigned long @var{n})
+Return a uniformly distributed random number of @var{n} bits, i.e.@: in the
+range 0 to @m{2^n-1,2^@var{n}-1} inclusive. @var{n} must be less than or
+equal to the number of bits in an @code{unsigned long}.
+@end deftypefun
+
+@deftypefun {unsigned long} gmp_urandomm_ui (gmp_randstate_t @var{state}, unsigned long @var{n})
+Return a uniformly distributed random number in the range 0 to
+@math{@var{n}-1}, inclusive.
+@end deftypefun
+
+
+@node Formatted Output, Formatted Input, Random Number Functions, Top
+@chapter Formatted Output
+@cindex Formatted output
+@cindex @code{printf} formatted output
+
+@menu
+* Formatted Output Strings::
+* Formatted Output Functions::
+* C++ Formatted Output::
+@end menu
+
+@node Formatted Output Strings, Formatted Output Functions, Formatted Output, Formatted Output
+@section Format Strings
+
+@code{gmp_printf} and friends accept format strings similar to the standard C
+@code{printf} (@pxref{Formatted Output,, Formatted Output, libc, The GNU C
+Library Reference Manual}). A format specification is of the form
+
+@example
+% [flags] [width] [.[precision]] [type] conv
+@end example
+
+GMP adds types @samp{Z}, @samp{Q} and @samp{F} for @code{mpz_t}, @code{mpq_t}
+and @code{mpf_t} respectively, @samp{M} for @code{mp_limb_t}, and @samp{N} for
+an @code{mp_limb_t} array. @samp{Z}, @samp{Q}, @samp{M} and @samp{N} behave
+like integers. @samp{Q} will print a @samp{/} and a denominator, if needed.
+@samp{F} behaves like a float. For example,
+
+@example
+mpz_t z;
+gmp_printf ("%s is an mpz %Zd\n", "here", z);
+
+mpq_t q;
+gmp_printf ("a hex rational: %#40Qx\n", q);
+
+mpf_t f;
+int n;
+gmp_printf ("fixed point mpf %.*Ff with %d digits\n", n, f, n);
+
+mp_limb_t l;
+gmp_printf ("limb %Mu\n", l);
+
+const mp_limb_t *ptr;
+mp_size_t size;
+gmp_printf ("limb array %Nx\n", ptr, size);
+@end example
+
+For @samp{N} the limbs are expected least significant first, as per the
+@code{mpn} functions (@pxref{Low-level Functions}). A negative size can be
+given to print the value as a negative.
+
+All the standard C @code{printf} types behave the same as the C library
+@code{printf}, and can be freely intermixed with the GMP extensions. In the
+current implementation the standard parts of the format string are simply
+handed to @code{printf} and only the GMP extensions handled directly.
+
+The flags accepted are as follows. GLIBC style @nisamp{'} is only for the
+standard C types (not the GMP types), and only if the C library supports it.
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @nicode{0} @tab pad with zeros (rather than spaces)
+@item @nicode{#} @tab show the base with @samp{0x}, @samp{0X} or @samp{0}
+@item @nicode{+} @tab always show a sign
+@item (space) @tab show a space or a @samp{-} sign
+@item @nicode{'} @tab group digits, GLIBC style (not GMP types)
+@end multitable
+@end quotation
+
+The optional width and precision can be given as a number within the format
+string, or as a @samp{*} to take an extra parameter of type @code{int}, the
+same as the standard @code{printf}.
+
+The standard types accepted are as follows. @samp{h} and @samp{l} are
+portable, the rest will depend on the compiler (or include files) for the type
+and the C library for the output.
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @nicode{h} @tab @nicode{short}
+@item @nicode{hh} @tab @nicode{char}
+@item @nicode{j} @tab @nicode{intmax_t} or @nicode{uintmax_t}
+@item @nicode{l} @tab @nicode{long} or @nicode{wchar_t}
+@item @nicode{ll} @tab @nicode{long long}
+@item @nicode{L} @tab @nicode{long double}
+@item @nicode{q} @tab @nicode{quad_t} or @nicode{u_quad_t}
+@item @nicode{t} @tab @nicode{ptrdiff_t}
+@item @nicode{z} @tab @nicode{size_t}
+@end multitable
+@end quotation
+
+@noindent
+The GMP types are
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @nicode{F} @tab @nicode{mpf_t}, float conversions
+@item @nicode{Q} @tab @nicode{mpq_t}, integer conversions
+@item @nicode{M} @tab @nicode{mp_limb_t}, integer conversions
+@item @nicode{N} @tab @nicode{mp_limb_t} array, integer conversions
+@item @nicode{Z} @tab @nicode{mpz_t}, integer conversions
+@end multitable
+@end quotation
+
+The conversions accepted are as follows. @samp{a} and @samp{A} are always
+supported for @code{mpf_t} but depend on the C library for standard C float
+types. @samp{m} and @samp{p} depend on the C library.
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @nicode{a} @nicode{A} @tab hex floats, C99 style
+@item @nicode{c} @tab character
+@item @nicode{d} @tab decimal integer
+@item @nicode{e} @nicode{E} @tab scientific format float
+@item @nicode{f} @tab fixed point float
+@item @nicode{i} @tab same as @nicode{d}
+@item @nicode{g} @nicode{G} @tab fixed or scientific float
+@item @nicode{m} @tab @code{strerror} string, GLIBC style
+@item @nicode{n} @tab store characters written so far
+@item @nicode{o} @tab octal integer
+@item @nicode{p} @tab pointer
+@item @nicode{s} @tab string
+@item @nicode{u} @tab unsigned integer
+@item @nicode{x} @nicode{X} @tab hex integer
+@end multitable
+@end quotation
+
+@samp{o}, @samp{x} and @samp{X} are unsigned for the standard C types, but for
+types @samp{Z}, @samp{Q} and @samp{N} they are signed. @samp{u} is not
+meaningful for @samp{Z}, @samp{Q} and @samp{N}.
+
+@samp{M} is a proxy for the C library @samp{l} or @samp{L}, according to the
+size of @code{mp_limb_t}. Unsigned conversions will be usual, but a signed
+conversion can be used and will interpret the value as a twos complement
+negative.
+
+@samp{n} can be used with any type, even the GMP types.
+
+Other types or conversions that might be accepted by the C library
+@code{printf} cannot be used through @code{gmp_printf}, this includes for
+instance extensions registered with GLIBC @code{register_printf_function}.
+Also currently there's no support for POSIX @samp{$} style numbered arguments
+(perhaps this will be added in the future).
+
+The precision field has its usual meaning for integer @samp{Z} and float
+@samp{F} types, but is currently undefined for @samp{Q} and should not be used
+with that.
+
+@code{mpf_t} conversions only ever generate as many digits as can be
+accurately represented by the operand, the same as @code{mpf_get_str} does.
+Zeros will be used if necessary to pad to the requested precision. This
+happens even for an @samp{f} conversion of an @code{mpf_t} which is an
+integer, for instance @math{2^@W{1024}} in an @code{mpf_t} of 128 bits
+precision will only produce about 40 digits, then pad with zeros to the
+decimal point. An empty precision field like @samp{%.Fe} or @samp{%.Ff} can
+be used to specifically request just the significant digits. Without any dot
+and thus no precision field, a precision value of 6 will be used. Note that
+these rules mean that @samp{%Ff}, @samp{%.Ff}, and @samp{%.0Ff} will all be
+different.
+
+The decimal point character (or string) is taken from the current locale
+settings on systems which provide @code{localeconv} (@pxref{Locales,, Locales
+and Internationalization, libc, The GNU C Library Reference Manual}). The C
+library will normally do the same for standard float output.
+
+The format string is only interpreted as plain @code{char}s, multibyte
+characters are not recognised. Perhaps this will change in the future.
+
+
+@node Formatted Output Functions, C++ Formatted Output, Formatted Output Strings, Formatted Output
+@section Functions
+@cindex Output functions
+
+Each of the following functions is similar to the corresponding C library
+function. The basic @code{printf} forms take a variable argument list. The
+@code{vprintf} forms take an argument pointer, see @ref{Variadic Functions,,
+Variadic Functions, libc, The GNU C Library Reference Manual}, or @samp{man 3
+va_start}.
+
+It should be emphasised that if a format string is invalid, or the arguments
+don't match what the format specifies, then the behaviour of any of these
+functions will be unpredictable. GCC format string checking is not available,
+since it doesn't recognise the GMP extensions.
+
+The file based functions @code{gmp_printf} and @code{gmp_fprintf} will return
+@math{-1} to indicate a write error. Output is not ``atomic'', so partial
+output may be produced if a write error occurs. All the functions can return
+@math{-1} if the C library @code{printf} variant in use returns @math{-1}, but
+this shouldn't normally occur.
+
+@deftypefun int gmp_printf (const char *@var{fmt}, @dots{})
+@deftypefunx int gmp_vprintf (const char *@var{fmt}, va_list @var{ap})
+Print to the standard output @code{stdout}. Return the number of characters
+written, or @math{-1} if an error occurred.
+@end deftypefun
+
+@deftypefun int gmp_fprintf (FILE *@var{fp}, const char *@var{fmt}, @dots{})
+@deftypefunx int gmp_vfprintf (FILE *@var{fp}, const char *@var{fmt}, va_list @var{ap})
+Print to the stream @var{fp}. Return the number of characters written, or
+@math{-1} if an error occurred.
+@end deftypefun
+
+@deftypefun int gmp_sprintf (char *@var{buf}, const char *@var{fmt}, @dots{})
+@deftypefunx int gmp_vsprintf (char *@var{buf}, const char *@var{fmt}, va_list @var{ap})
+Form a null-terminated string in @var{buf}. Return the number of characters
+written, excluding the terminating null.
+
+No overlap is permitted between the space at @var{buf} and the string
+@var{fmt}.
+
+These functions are not recommended, since there's no protection against
+exceeding the space available at @var{buf}.
+@end deftypefun
+
+@deftypefun int gmp_snprintf (char *@var{buf}, size_t @var{size}, const char *@var{fmt}, @dots{})
+@deftypefunx int gmp_vsnprintf (char *@var{buf}, size_t @var{size}, const char *@var{fmt}, va_list @var{ap})
+Form a null-terminated string in @var{buf}. No more than @var{size} bytes
+will be written. To get the full output, @var{size} must be enough for the
+string and null-terminator.
+
+The return value is the total number of characters which ought to have been
+produced, excluding the terminating null. If @math{@var{retval} @ge{}
+@var{size}} then the actual output has been truncated to the first
+@math{@var{size}-1} characters, and a null appended.
+
+No overlap is permitted between the region @{@var{buf},@var{size}@} and the
+@var{fmt} string.
+
+Notice the return value is in ISO C99 @code{snprintf} style. This is so even
+if the C library @code{vsnprintf} is the older GLIBC 2.0.x style.
+@end deftypefun
+
+@deftypefun int gmp_asprintf (char **@var{pp}, const char *@var{fmt}, @dots{})
+@deftypefunx int gmp_vasprintf (char **@var{pp}, const char *@var{fmt}, va_list @var{ap})
+Form a null-terminated string in a block of memory obtained from the current
+memory allocation function (@pxref{Custom Allocation}). The block will be the
+size of the string and null-terminator. The address of the block in stored to
+*@var{pp}. The return value is the number of characters produced, excluding
+the null-terminator.
+
+Unlike the C library @code{asprintf}, @code{gmp_asprintf} doesn't return
+@math{-1} if there's no more memory available, it lets the current allocation
+function handle that.
+@end deftypefun
+
+@deftypefun int gmp_obstack_printf (struct obstack *@var{ob}, const char *@var{fmt}, @dots{})
+@deftypefunx int gmp_obstack_vprintf (struct obstack *@var{ob}, const char *@var{fmt}, va_list @var{ap})
+@cindex @code{obstack} output
+Append to the current object in @var{ob}. The return value is the number of
+characters written. A null-terminator is not written.
+
+@var{fmt} cannot be within the current object in @var{ob}, since that object
+might move as it grows.
+
+These functions are available only when the C library provides the obstack
+feature, which probably means only on GNU systems, see @ref{Obstacks,,
+Obstacks, libc, The GNU C Library Reference Manual}.
+@end deftypefun
+
+
+@node C++ Formatted Output, , Formatted Output Functions, Formatted Output
+@section C++ Formatted Output
+@cindex C++ @code{ostream} output
+@cindex @code{ostream} output
+
+The following functions are provided in @file{libgmpxx} (@pxref{Headers and
+Libraries}), which is built if C++ support is enabled (@pxref{Build Options}).
+Prototypes are available from @code{<gmp.h>}.
+
+@deftypefun ostream& operator<< (ostream& @var{stream}, const mpz_t @var{op})
+Print @var{op} to @var{stream}, using its @code{ios} formatting settings.
+@code{ios::width} is reset to 0 after output, the same as the standard
+@code{ostream operator<<} routines do.
+
+In hex or octal, @var{op} is printed as a signed number, the same as for
+decimal. This is unlike the standard @code{operator<<} routines on @code{int}
+etc, which instead give twos complement.
+@end deftypefun
+
+@deftypefun ostream& operator<< (ostream& @var{stream}, const mpq_t @var{op})
+Print @var{op} to @var{stream}, using its @code{ios} formatting settings.
+@code{ios::width} is reset to 0 after output, the same as the standard
+@code{ostream operator<<} routines do.
+
+Output will be a fraction like @samp{5/9}, or if the denominator is 1 then
+just a plain integer like @samp{123}.
+
+In hex or octal, @var{op} is printed as a signed value, the same as for
+decimal. If @code{ios::showbase} is set then a base indicator is shown on
+both the numerator and denominator (if the denominator is required).
+@end deftypefun
+
+@deftypefun ostream& operator<< (ostream& @var{stream}, const mpf_t @var{op})
+Print @var{op} to @var{stream}, using its @code{ios} formatting settings.
+@code{ios::width} is reset to 0 after output, the same as the standard
+@code{ostream operator<<} routines do.
+
+The decimal point follows the standard library float @code{operator<<}, which
+on recent systems means the @code{std::locale} imbued on @var{stream}.
+
+Hex and octal are supported, unlike the standard @code{operator<<} on
+@code{double}. The mantissa will be in hex or octal, the exponent will be in
+decimal. For hex the exponent delimiter is an @samp{@@}. This is as per
+@code{mpf_out_str}.
+
+@code{ios::showbase} is supported, and will put a base on the mantissa, for
+example hex @samp{0x1.8} or @samp{0x0.8}, or octal @samp{01.4} or @samp{00.4}.
+This last form is slightly strange, but at least differentiates itself from
+decimal.
+@end deftypefun
+
+These operators mean that GMP types can be printed in the usual C++ way, for
+example,
+
+@example
+mpz_t z;
+int n;
+...
+cout << "iteration " << n << " value " << z << "\n";
+@end example
+
+But note that @code{ostream} output (and @code{istream} input, @pxref{C++
+Formatted Input}) is the only overloading available for the GMP types and that
+for instance using @code{+} with an @code{mpz_t} will have unpredictable
+results. For classes with overloading, see @ref{C++ Class Interface}.
+
+
+@node Formatted Input, C++ Class Interface, Formatted Output, Top
+@chapter Formatted Input
+@cindex Formatted input
+@cindex @code{scanf} formatted input
+
+@menu
+* Formatted Input Strings::
+* Formatted Input Functions::
+* C++ Formatted Input::
+@end menu
+
+
+@node Formatted Input Strings, Formatted Input Functions, Formatted Input, Formatted Input
+@section Formatted Input Strings
+
+@code{gmp_scanf} and friends accept format strings similar to the standard C
+@code{scanf} (@pxref{Formatted Input,, Formatted Input, libc, The GNU C
+Library Reference Manual}). A format specification is of the form
+
+@example
+% [flags] [width] [type] conv
+@end example
+
+GMP adds types @samp{Z}, @samp{Q} and @samp{F} for @code{mpz_t}, @code{mpq_t}
+and @code{mpf_t} respectively. @samp{Z} and @samp{Q} behave like integers.
+@samp{Q} will read a @samp{/} and a denominator, if present. @samp{F} behaves
+like a float.
+
+GMP variables don't require an @code{&} when passed to @code{gmp_scanf}, since
+they're already ``call-by-reference''. For example,
+
+@example
+/* to read say "a(5) = 1234" */
+int n;
+mpz_t z;
+gmp_scanf ("a(%d) = %Zd\n", &n, z);
+
+mpq_t q1, q2;
+gmp_sscanf ("0377 + 0x10/0x11", "%Qi + %Qi", q1, q2);
+
+/* to read say "topleft (1.55,-2.66)" */
+mpf_t x, y;
+char buf[32];
+gmp_scanf ("%31s (%Ff,%Ff)", buf, x, y);
+@end example
+
+All the standard C @code{scanf} types behave the same as in the C library
+@code{scanf}, and can be freely intermixed with the GMP extensions. In the
+current implementation the standard parts of the format string are simply
+handed to @code{scanf} and only the GMP extensions handled directly.
+
+The flags accepted are as follows. @samp{a} and @samp{'} will depend on
+support from the C library, and @samp{'} cannot be used with GMP types.
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @nicode{*} @tab read but don't store
+@item @nicode{a} @tab allocate a buffer (string conversions)
+@item @nicode{'} @tab grouped digits, GLIBC style (not GMP types)
+@end multitable
+@end quotation
+
+The standard types accepted are as follows. @samp{h} and @samp{l} are
+portable, the rest will depend on the compiler (or include files) for the type
+and the C library for the input.
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @nicode{h} @tab @nicode{short}
+@item @nicode{hh} @tab @nicode{char}
+@item @nicode{j} @tab @nicode{intmax_t} or @nicode{uintmax_t}
+@item @nicode{l} @tab @nicode{long int}, @nicode{double} or @nicode{wchar_t}
+@item @nicode{ll} @tab @nicode{long long}
+@item @nicode{L} @tab @nicode{long double}
+@item @nicode{q} @tab @nicode{quad_t} or @nicode{u_quad_t}
+@item @nicode{t} @tab @nicode{ptrdiff_t}
+@item @nicode{z} @tab @nicode{size_t}
+@end multitable
+@end quotation
+
+@noindent
+The GMP types are
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @nicode{F} @tab @nicode{mpf_t}, float conversions
+@item @nicode{Q} @tab @nicode{mpq_t}, integer conversions
+@item @nicode{Z} @tab @nicode{mpz_t}, integer conversions
+@end multitable
+@end quotation
+
+The conversions accepted are as follows. @samp{p} and @samp{[} will depend on
+support from the C library, the rest are standard.
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @nicode{c} @tab character or characters
+@item @nicode{d} @tab decimal integer
+@item @nicode{e} @nicode{E} @nicode{f} @nicode{g} @nicode{G}
+ @tab float
+@item @nicode{i} @tab integer with base indicator
+@item @nicode{n} @tab characters read so far
+@item @nicode{o} @tab octal integer
+@item @nicode{p} @tab pointer
+@item @nicode{s} @tab string of non-whitespace characters
+@item @nicode{u} @tab decimal integer
+@item @nicode{x} @nicode{X} @tab hex integer
+@item @nicode{[} @tab string of characters in a set
+@end multitable
+@end quotation
+
+@samp{e}, @samp{E}, @samp{f}, @samp{g} and @samp{G} are identical, they all
+read either fixed point or scientific format, and either upper or lower case
+@samp{e} for the exponent in scientific format.
+
+C99 style hex float format (@code{printf %a}, @pxref{Formatted Output
+Strings}) is always accepted for @code{mpf_t}, but for the standard float
+types it will depend on the C library.
+
+@samp{x} and @samp{X} are identical, both accept both upper and lower case
+hexadecimal.
+
+@samp{o}, @samp{u}, @samp{x} and @samp{X} all read positive or negative
+values. For the standard C types these are described as ``unsigned''
+conversions, but that merely affects certain overflow handling, negatives are
+still allowed (per @code{strtoul}, @pxref{Parsing of Integers,, Parsing of
+Integers, libc, The GNU C Library Reference Manual}). For GMP types there are
+no overflows, so @samp{d} and @samp{u} are identical.
+
+@samp{Q} type reads the numerator and (optional) denominator as given. If the
+value might not be in canonical form then @code{mpq_canonicalize} must be
+called before using it in any calculations (@pxref{Rational Number
+Functions}).
+
+@samp{Qi} will read a base specification separately for the numerator and
+denominator. For example @samp{0x10/11} would be 16/11, whereas
+@samp{0x10/0x11} would be 16/17.
+
+@samp{n} can be used with any of the types above, even the GMP types.
+@samp{*} to suppress assignment is allowed, though in that case it would do
+nothing at all.
+
+Other conversions or types that might be accepted by the C library
+@code{scanf} cannot be used through @code{gmp_scanf}.
+
+Whitespace is read and discarded before a field, except for @samp{c} and
+@samp{[} conversions.
+
+For float conversions, the decimal point character (or string) expected is
+taken from the current locale settings on systems which provide
+@code{localeconv} (@pxref{Locales,, Locales and Internationalization, libc,
+The GNU C Library Reference Manual}). The C library will normally do the same
+for standard float input.
+
+The format string is only interpreted as plain @code{char}s, multibyte
+characters are not recognised. Perhaps this will change in the future.
+
+
+@node Formatted Input Functions, C++ Formatted Input, Formatted Input Strings, Formatted Input
+@section Formatted Input Functions
+@cindex Input functions
+
+Each of the following functions is similar to the corresponding C library
+function. The plain @code{scanf} forms take a variable argument list. The
+@code{vscanf} forms take an argument pointer, see @ref{Variadic Functions,,
+Variadic Functions, libc, The GNU C Library Reference Manual}, or @samp{man 3
+va_start}.
+
+It should be emphasised that if a format string is invalid, or the arguments
+don't match what the format specifies, then the behaviour of any of these
+functions will be unpredictable. GCC format string checking is not available,
+since it doesn't recognise the GMP extensions.
+
+No overlap is permitted between the @var{fmt} string and any of the results
+produced.
+
+@deftypefun int gmp_scanf (const char *@var{fmt}, @dots{})
+@deftypefunx int gmp_vscanf (const char *@var{fmt}, va_list @var{ap})
+Read from the standard input @code{stdin}.
+@end deftypefun
+
+@deftypefun int gmp_fscanf (FILE *@var{fp}, const char *@var{fmt}, @dots{})
+@deftypefunx int gmp_vfscanf (FILE *@var{fp}, const char *@var{fmt}, va_list @var{ap})
+Read from the stream @var{fp}.
+@end deftypefun
+
+@deftypefun int gmp_sscanf (const char *@var{s}, const char *@var{fmt}, @dots{})
+@deftypefunx int gmp_vsscanf (const char *@var{s}, const char *@var{fmt}, va_list @var{ap})
+Read from a null-terminated string @var{s}.
+@end deftypefun
+
+The return value from each of these functions is the same as the standard C99
+@code{scanf}, namely the number of fields successfully parsed and stored.
+@samp{%n} fields and fields read but suppressed by @samp{*} don't count
+towards the return value.
+
+If end of input (or a file error) is reached before a character for a field or
+a literal, and if no previous non-suppressed fields have matched, then the
+return value is @code{EOF} instead of 0. A whitespace character in the format
+string is only an optional match and doesn't induce an @code{EOF} in this
+fashion. Leading whitespace read and discarded for a field don't count as
+characters for that field.
+
+For the GMP types, input parsing follows C99 rules, namely one character of
+lookahead is used and characters are read while they continue to meet the
+format requirements. If this doesn't provide a complete number then the
+function terminates, with that field not stored nor counted towards the return
+value. For instance with @code{mpf_t} an input @samp{1.23e-XYZ} would be read
+up to the @samp{X} and that character pushed back since it's not a digit. The
+string @samp{1.23e-} would then be considered invalid since an @samp{e} must
+be followed by at least one digit.
+
+For the standard C types, in the current implementation GMP calls the C
+library @code{scanf} functions, which might have looser rules about what
+constitutes a valid input.
+
+Note that @code{gmp_sscanf} is the same as @code{gmp_fscanf} and only does one
+character of lookahead when parsing. Although clearly it could look at its
+entire input, it is deliberately made identical to @code{gmp_fscanf}, the same
+way C99 @code{sscanf} is the same as @code{fscanf}.
+
+
+@node C++ Formatted Input, , Formatted Input Functions, Formatted Input
+@section C++ Formatted Input
+@cindex C++ @code{istream} input
+@cindex @code{istream} input
+
+The following functions are provided in @file{libgmpxx} (@pxref{Headers and
+Libraries}), which is built only if C++ support is enabled (@pxref{Build
+Options}). Prototypes are available from @code{<gmp.h>}.
+
+@deftypefun istream& operator>> (istream& @var{stream}, mpz_t @var{rop})
+Read @var{rop} from @var{stream}, using its @code{ios} formatting settings.
+@end deftypefun
+
+@deftypefun istream& operator>> (istream& @var{stream}, mpq_t @var{rop})
+An integer like @samp{123} will be read, or a fraction like @samp{5/9}. No
+whitespace is allowed around the @samp{/}. If the fraction is not in
+canonical form then @code{mpq_canonicalize} must be called (@pxref{Rational
+Number Functions}) before operating on it.
+
+As per integer input, an @samp{0} or @samp{0x} base indicator is read when
+none of @code{ios::dec}, @code{ios::oct} or @code{ios::hex} are set. This is
+done separately for numerator and denominator, so that for instance
+@samp{0x10/11} is @math{16/11} and @samp{0x10/0x11} is @math{16/17}.
+@end deftypefun
+
+@deftypefun istream& operator>> (istream& @var{stream}, mpf_t @var{rop})
+Read @var{rop} from @var{stream}, using its @code{ios} formatting settings.
+
+Hex or octal floats are not supported, but might be in the future, or perhaps
+it's best to accept only what the standard float @code{operator>>} does.
+@end deftypefun
+
+Note that digit grouping specified by the @code{istream} locale is currently
+not accepted. Perhaps this will change in the future.
+
+@sp 1
+These operators mean that GMP types can be read in the usual C++ way, for
+example,
+
+@example
+mpz_t z;
+...
+cin >> z;
+@end example
+
+But note that @code{istream} input (and @code{ostream} output, @pxref{C++
+Formatted Output}) is the only overloading available for the GMP types and
+that for instance using @code{+} with an @code{mpz_t} will have unpredictable
+results. For classes with overloading, see @ref{C++ Class Interface}.
+
+
+
+@node C++ Class Interface, Custom Allocation, Formatted Input, Top
+@chapter C++ Class Interface
+@cindex C++ interface
+
+This chapter describes the C++ class based interface to GMP.
+
+All GMP C language types and functions can be used in C++ programs, since
+@file{gmp.h} has @code{extern "C"} qualifiers, but the class interface offers
+overloaded functions and operators which may be more convenient.
+
+Due to the implementation of this interface, a reasonably recent C++ compiler
+is required, one supporting namespaces, partial specialization of templates
+and member templates.
+
+@strong{Everything described in this chapter is to be considered preliminary
+and might be subject to incompatible changes if some unforeseen difficulty
+reveals itself.}
+
+@menu
+* C++ Interface General::
+* C++ Interface Integers::
+* C++ Interface Rationals::
+* C++ Interface Floats::
+* C++ Interface Random Numbers::
+* C++ Interface Limitations::
+@end menu
+
+
+@node C++ Interface General, C++ Interface Integers, C++ Class Interface, C++ Class Interface
+@section C++ Interface General
+
+@noindent
+All the C++ classes and functions are available with
+
+@cindex @code{gmpxx.h}
+@example
+#include <gmpxx.h>
+@end example
+
+Programs should be linked with the @file{libgmpxx} and @file{libgmp}
+libraries. For example,
+
+@example
+g++ mycxxprog.cc -lgmpxx -lgmp
+@end example
+
+@noindent
+The classes defined are
+
+@deftp Class mpz_class
+@deftpx Class mpq_class
+@deftpx Class mpf_class
+@end deftp
+
+The standard operators and various standard functions are overloaded to allow
+arithmetic with these classes. For example,
+
+@example
+int
+main (void)
+@{
+ mpz_class a, b, c;
+
+ a = 1234;
+ b = "-5678";
+ c = a+b;
+ cout << "sum is " << c << "\n";
+ cout << "absolute value is " << abs(c) << "\n";
+
+ return 0;
+@}
+@end example
+
+An important feature of the implementation is that an expression like
+@code{a=b+c} results in a single call to the corresponding @code{mpz_add},
+without using a temporary for the @code{b+c} part. Expressions which by their
+nature imply intermediate values, like @code{a=b*c+d*e}, still use temporaries
+though.
+
+The classes can be freely intermixed in expressions, as can the classes and
+the standard types @code{long}, @code{unsigned long} and @code{double}.
+Smaller types like @code{int} or @code{float} can also be intermixed, since
+C++ will promote them.
+
+Note that @code{bool} is not accepted directly, but must be explicitly cast to
+an @code{int} first. This is because C++ will automatically convert any
+pointer to a @code{bool}, so if GMP accepted @code{bool} it would make all
+sorts of invalid class and pointer combinations compile but almost certainly
+not do anything sensible.
+
+Conversions back from the classes to standard C++ types aren't done
+automatically, instead member functions like @code{get_si} are provided (see
+the following sections for details).
+
+Also there are no automatic conversions from the classes to the corresponding
+GMP C types, instead a reference to the underlying C object can be obtained
+with the following functions,
+
+@deftypefun mpz_t mpz_class::get_mpz_t ()
+@deftypefunx mpq_t mpq_class::get_mpq_t ()
+@deftypefunx mpf_t mpf_class::get_mpf_t ()
+@end deftypefun
+
+These can be used to call a C function which doesn't have a C++ class
+interface. For example to set @code{a} to the GCD of @code{b} and @code{c},
+
+@example
+mpz_class a, b, c;
+...
+mpz_gcd (a.get_mpz_t(), b.get_mpz_t(), c.get_mpz_t());
+@end example
+
+In the other direction, a class can be initialized from the corresponding GMP
+C type, or assigned to if an explicit constructor is used. In both cases this
+makes a copy of the value, it doesn't create any sort of association. For
+example,
+
+@example
+mpz_t z;
+// ... init and calculate z ...
+mpz_class x(z);
+mpz_class y;
+y = mpz_class (z);
+@end example
+
+There are no namespace setups in @file{gmpxx.h}, all types and functions are
+simply put into the global namespace. This is what @file{gmp.h} has done in
+the past, and continues to do for compatibility. The extras provided by
+@file{gmpxx.h} follow GMP naming conventions and are unlikely to clash with
+anything.
+
+
+@node C++ Interface Integers, C++ Interface Rationals, C++ Interface General, C++ Class Interface
+@section C++ Interface Integers
+
+@deftypefun {} mpz_class::mpz_class (type @var{n})
+Construct an @code{mpz_class}. All the standard C++ types may be used, except
+@code{long long} and @code{long double}, and all the GMP C++ classes can be
+used, although conversions from @code{mpq_class} and @code{mpf_class} are
+@code{explicit}. Any necessary conversion follows the corresponding C
+function, for example @code{double} follows @code{mpz_set_d}
+(@pxref{Assigning Integers}).
+@end deftypefun
+
+@deftypefun explicit mpz_class::mpz_class (const mpz_t @var{z})
+Construct an @code{mpz_class} from an @code{mpz_t}. The value in @var{z} is
+copied into the new @code{mpz_class}, there won't be any permanent association
+between it and @var{z}.
+@end deftypefun
+
+@deftypefun explicit mpz_class::mpz_class (const char *@var{s}, int @var{base} = 0)
+@deftypefunx explicit mpz_class::mpz_class (const string& @var{s}, int @var{base} = 0)
+Construct an @code{mpz_class} converted from a string using @code{mpz_set_str}
+(@pxref{Assigning Integers}).
+
+If the string is not a valid integer, an @code{std::invalid_argument}
+exception is thrown. The same applies to @code{operator=}.
+@end deftypefun
+
+@deftypefun mpz_class operator"" _mpz (const char *@var{str})
+With C++11 compilers, integers can be constructed with the syntax
+@code{123_mpz} which is equivalent to @code{mpz_class("123")}.
+@end deftypefun
+
+@deftypefun mpz_class operator/ (mpz_class @var{a}, mpz_class @var{d})
+@deftypefunx mpz_class operator% (mpz_class @var{a}, mpz_class @var{d})
+Divisions involving @code{mpz_class} round towards zero, as per the
+@code{mpz_tdiv_q} and @code{mpz_tdiv_r} functions (@pxref{Integer Division}).
+This is the same as the C99 @code{/} and @code{%} operators.
+
+The @code{mpz_fdiv@dots{}} or @code{mpz_cdiv@dots{}} functions can always be called
+directly if desired. For example,
+
+@example
+mpz_class q, a, d;
+...
+mpz_fdiv_q (q.get_mpz_t(), a.get_mpz_t(), d.get_mpz_t());
+@end example
+@end deftypefun
+
+@deftypefun mpz_class abs (mpz_class @var{op})
+@deftypefunx int cmp (mpz_class @var{op1}, type @var{op2})
+@deftypefunx int cmp (type @var{op1}, mpz_class @var{op2})
+@maybepagebreak
+@deftypefunx bool mpz_class::fits_sint_p (void)
+@deftypefunx bool mpz_class::fits_slong_p (void)
+@deftypefunx bool mpz_class::fits_sshort_p (void)
+@maybepagebreak
+@deftypefunx bool mpz_class::fits_uint_p (void)
+@deftypefunx bool mpz_class::fits_ulong_p (void)
+@deftypefunx bool mpz_class::fits_ushort_p (void)
+@maybepagebreak
+@deftypefunx double mpz_class::get_d (void)
+@deftypefunx long mpz_class::get_si (void)
+@deftypefunx string mpz_class::get_str (int @var{base} = 10)
+@deftypefunx {unsigned long} mpz_class::get_ui (void)
+@maybepagebreak
+@deftypefunx int mpz_class::set_str (const char *@var{str}, int @var{base})
+@deftypefunx int mpz_class::set_str (const string& @var{str}, int @var{base})
+@deftypefunx int sgn (mpz_class @var{op})
+@deftypefunx mpz_class sqrt (mpz_class @var{op})
+@maybepagebreak
+@deftypefunx void mpz_class::swap (mpz_class& @var{op})
+@deftypefunx void swap (mpz_class& @var{op1}, mpz_class& @var{op2})
+These functions provide a C++ class interface to the corresponding GMP C
+routines.
+
+@code{cmp} can be used with any of the classes or the standard C++ types,
+except @code{long long} and @code{long double}.
+@end deftypefun
+
+@sp 1
+Overloaded operators for combinations of @code{mpz_class} and @code{double}
+are provided for completeness, but it should be noted that if the given
+@code{double} is not an integer then the way any rounding is done is currently
+unspecified. The rounding might take place at the start, in the middle, or at
+the end of the operation, and it might change in the future.
+
+Conversions between @code{mpz_class} and @code{double}, however, are defined
+to follow the corresponding C functions @code{mpz_get_d} and @code{mpz_set_d}.
+And comparisons are always made exactly, as per @code{mpz_cmp_d}.
+
+
+@node C++ Interface Rationals, C++ Interface Floats, C++ Interface Integers, C++ Class Interface
+@section C++ Interface Rationals
+
+In all the following constructors, if a fraction is given then it should be in
+canonical form, or if not then @code{mpq_class::canonicalize} called.
+
+@deftypefun {} mpq_class::mpq_class (type @var{op})
+@deftypefunx {} mpq_class::mpq_class (integer @var{num}, integer @var{den})
+Construct an @code{mpq_class}. The initial value can be a single value of any
+type (conversion from @code{mpf_class} is @code{explicit}), or a pair of
+integers (@code{mpz_class} or standard C++ integer types) representing a
+fraction, except that @code{long long} and @code{long double} are not
+supported. For example,
+
+@example
+mpq_class q (99);
+mpq_class q (1.75);
+mpq_class q (1, 3);
+@end example
+@end deftypefun
+
+@deftypefun explicit mpq_class::mpq_class (const mpq_t @var{q})
+Construct an @code{mpq_class} from an @code{mpq_t}. The value in @var{q} is
+copied into the new @code{mpq_class}, there won't be any permanent association
+between it and @var{q}.
+@end deftypefun
+
+@deftypefun explicit mpq_class::mpq_class (const char *@var{s}, int @var{base} = 0)
+@deftypefunx explicit mpq_class::mpq_class (const string& @var{s}, int @var{base} = 0)
+Construct an @code{mpq_class} converted from a string using @code{mpq_set_str}
+(@pxref{Initializing Rationals}).
+
+If the string is not a valid rational, an @code{std::invalid_argument}
+exception is thrown. The same applies to @code{operator=}.
+@end deftypefun
+
+@deftypefun mpq_class operator"" _mpq (const char *@var{str})
+With C++11 compilers, integral rationals can be constructed with the syntax
+@code{123_mpq} which is equivalent to @code{mpq_class(123_mpz)}. Other
+rationals can be built as @code{-1_mpq/2} or @code{0xb_mpq/123456_mpz}.
+@end deftypefun
+
+@deftypefun void mpq_class::canonicalize ()
+Put an @code{mpq_class} into canonical form, as per @ref{Rational Number
+Functions}. All arithmetic operators require their operands in canonical
+form, and will return results in canonical form.
+@end deftypefun
+
+@deftypefun mpq_class abs (mpq_class @var{op})
+@deftypefunx int cmp (mpq_class @var{op1}, type @var{op2})
+@deftypefunx int cmp (type @var{op1}, mpq_class @var{op2})
+@maybepagebreak
+@deftypefunx double mpq_class::get_d (void)
+@deftypefunx string mpq_class::get_str (int @var{base} = 10)
+@maybepagebreak
+@deftypefunx int mpq_class::set_str (const char *@var{str}, int @var{base})
+@deftypefunx int mpq_class::set_str (const string& @var{str}, int @var{base})
+@deftypefunx int sgn (mpq_class @var{op})
+@maybepagebreak
+@deftypefunx void mpq_class::swap (mpq_class& @var{op})
+@deftypefunx void swap (mpq_class& @var{op1}, mpq_class& @var{op2})
+These functions provide a C++ class interface to the corresponding GMP C
+routines.
+
+@code{cmp} can be used with any of the classes or the standard C++ types,
+except @code{long long} and @code{long double}.
+@end deftypefun
+
+@deftypefun {mpz_class&} mpq_class::get_num ()
+@deftypefunx {mpz_class&} mpq_class::get_den ()
+Get a reference to an @code{mpz_class} which is the numerator or denominator
+of an @code{mpq_class}. This can be used both for read and write access. If
+the object returned is modified, it modifies the original @code{mpq_class}.
+
+If direct manipulation might produce a non-canonical value, then
+@code{mpq_class::canonicalize} must be called before further operations.
+@end deftypefun
+
+@deftypefun mpz_t mpq_class::get_num_mpz_t ()
+@deftypefunx mpz_t mpq_class::get_den_mpz_t ()
+Get a reference to the underlying @code{mpz_t} numerator or denominator of an
+@code{mpq_class}. This can be passed to C functions expecting an
+@code{mpz_t}. Any modifications made to the @code{mpz_t} will modify the
+original @code{mpq_class}.
+
+If direct manipulation might produce a non-canonical value, then
+@code{mpq_class::canonicalize} must be called before further operations.
+@end deftypefun
+
+@deftypefun istream& operator>> (istream& @var{stream}, mpq_class& @var{rop});
+Read @var{rop} from @var{stream}, using its @code{ios} formatting settings,
+the same as @code{mpq_t operator>>} (@pxref{C++ Formatted Input}).
+
+If the @var{rop} read might not be in canonical form then
+@code{mpq_class::canonicalize} must be called.
+@end deftypefun
+
+
+@node C++ Interface Floats, C++ Interface Random Numbers, C++ Interface Rationals, C++ Class Interface
+@section C++ Interface Floats
+
+When an expression requires the use of temporary intermediate @code{mpf_class}
+values, like @code{f=g*h+x*y}, those temporaries will have the same precision
+as the destination @code{f}. Explicit constructors can be used if this
+doesn't suit.
+
+@deftypefun {} mpf_class::mpf_class (type @var{op})
+@deftypefunx {} mpf_class::mpf_class (type @var{op}, mp_bitcnt_t @var{prec})
+Construct an @code{mpf_class}. Any standard C++ type can be used, except
+@code{long long} and @code{long double}, and any of the GMP C++ classes can be
+used.
+
+If @var{prec} is given, the initial precision is that value, in bits. If
+@var{prec} is not given, then the initial precision is determined by the type
+of @var{op} given. An @code{mpz_class}, @code{mpq_class}, or C++
+builtin type will give the default @code{mpf} precision (@pxref{Initializing
+Floats}). An @code{mpf_class} or expression will give the precision of that
+value. The precision of a binary expression is the higher of the two
+operands.
+
+@example
+mpf_class f(1.5); // default precision
+mpf_class f(1.5, 500); // 500 bits (at least)
+mpf_class f(x); // precision of x
+mpf_class f(abs(x)); // precision of x
+mpf_class f(-g, 1000); // 1000 bits (at least)
+mpf_class f(x+y); // greater of precisions of x and y
+@end example
+@end deftypefun
+
+@deftypefun explicit mpf_class::mpf_class (const mpf_t @var{f})
+@deftypefunx {} mpf_class::mpf_class (const mpf_t @var{f}, mp_bitcnt_t @var{prec})
+Construct an @code{mpf_class} from an @code{mpf_t}. The value in @var{f} is
+copied into the new @code{mpf_class}, there won't be any permanent association
+between it and @var{f}.
+
+If @var{prec} is given, the initial precision is that value, in bits. If
+@var{prec} is not given, then the initial precision is that of @var{f}.
+@end deftypefun
+
+@deftypefun explicit mpf_class::mpf_class (const char *@var{s})
+@deftypefunx {} mpf_class::mpf_class (const char *@var{s}, mp_bitcnt_t @var{prec}, int @var{base} = 0)
+@deftypefunx explicit mpf_class::mpf_class (const string& @var{s})
+@deftypefunx {} mpf_class::mpf_class (const string& @var{s}, mp_bitcnt_t @var{prec}, int @var{base} = 0)
+Construct an @code{mpf_class} converted from a string using @code{mpf_set_str}
+(@pxref{Assigning Floats}). If @var{prec} is given, the initial precision is
+that value, in bits. If not, the default @code{mpf} precision
+(@pxref{Initializing Floats}) is used.
+
+If the string is not a valid float, an @code{std::invalid_argument} exception
+is thrown. The same applies to @code{operator=}.
+@end deftypefun
+
+@deftypefun mpf_class operator"" _mpf (const char *@var{str})
+With C++11 compilers, floats can be constructed with the syntax
+@code{1.23e-1_mpf} which is equivalent to @code{mpf_class("1.23e-1")}.
+@end deftypefun
+
+@deftypefun {mpf_class&} mpf_class::operator= (type @var{op})
+Convert and store the given @var{op} value to an @code{mpf_class} object. The
+same types are accepted as for the constructors above.
+
+Note that @code{operator=} only stores a new value, it doesn't copy or change
+the precision of the destination, instead the value is truncated if necessary.
+This is the same as @code{mpf_set} etc. Note in particular this means for
+@code{mpf_class} a copy constructor is not the same as a default constructor
+plus assignment.
+
+@example
+mpf_class x (y); // x created with precision of y
+
+mpf_class x; // x created with default precision
+x = y; // value truncated to that precision
+@end example
+
+Applications using templated code may need to be careful about the assumptions
+the code makes in this area, when working with @code{mpf_class} values of
+various different or non-default precisions. For instance implementations of
+the standard @code{complex} template have been seen in both styles above,
+though of course @code{complex} is normally only actually specified for use
+with the builtin float types.
+@end deftypefun
+
+@deftypefun mpf_class abs (mpf_class @var{op})
+@deftypefunx mpf_class ceil (mpf_class @var{op})
+@deftypefunx int cmp (mpf_class @var{op1}, type @var{op2})
+@deftypefunx int cmp (type @var{op1}, mpf_class @var{op2})
+@maybepagebreak
+@deftypefunx bool mpf_class::fits_sint_p (void)
+@deftypefunx bool mpf_class::fits_slong_p (void)
+@deftypefunx bool mpf_class::fits_sshort_p (void)
+@maybepagebreak
+@deftypefunx bool mpf_class::fits_uint_p (void)
+@deftypefunx bool mpf_class::fits_ulong_p (void)
+@deftypefunx bool mpf_class::fits_ushort_p (void)
+@maybepagebreak
+@deftypefunx mpf_class floor (mpf_class @var{op})
+@deftypefunx mpf_class hypot (mpf_class @var{op1}, mpf_class @var{op2})
+@maybepagebreak
+@deftypefunx double mpf_class::get_d (void)
+@deftypefunx long mpf_class::get_si (void)
+@deftypefunx string mpf_class::get_str (mp_exp_t& @var{exp}, int @var{base} = 10, size_t @var{digits} = 0)
+@deftypefunx {unsigned long} mpf_class::get_ui (void)
+@maybepagebreak
+@deftypefunx int mpf_class::set_str (const char *@var{str}, int @var{base})
+@deftypefunx int mpf_class::set_str (const string& @var{str}, int @var{base})
+@deftypefunx int sgn (mpf_class @var{op})
+@deftypefunx mpf_class sqrt (mpf_class @var{op})
+@maybepagebreak
+@deftypefunx void mpf_class::swap (mpf_class& @var{op})
+@deftypefunx void swap (mpf_class& @var{op1}, mpf_class& @var{op2})
+@deftypefunx mpf_class trunc (mpf_class @var{op})
+These functions provide a C++ class interface to the corresponding GMP C
+routines.
+
+@code{cmp} can be used with any of the classes or the standard C++ types,
+except @code{long long} and @code{long double}.
+
+The accuracy provided by @code{hypot} is not currently guaranteed.
+@end deftypefun
+
+@deftypefun {mp_bitcnt_t} mpf_class::get_prec ()
+@deftypefunx void mpf_class::set_prec (mp_bitcnt_t @var{prec})
+@deftypefunx void mpf_class::set_prec_raw (mp_bitcnt_t @var{prec})
+Get or set the current precision of an @code{mpf_class}.
+
+The restrictions described for @code{mpf_set_prec_raw} (@pxref{Initializing
+Floats}) apply to @code{mpf_class::set_prec_raw}. Note in particular that the
+@code{mpf_class} must be restored to it's allocated precision before being
+destroyed. This must be done by application code, there's no automatic
+mechanism for it.
+@end deftypefun
+
+
+@node C++ Interface Random Numbers, C++ Interface Limitations, C++ Interface Floats, C++ Class Interface
+@section C++ Interface Random Numbers
+
+@deftp Class gmp_randclass
+The C++ class interface to the GMP random number functions uses
+@code{gmp_randclass} to hold an algorithm selection and current state, as per
+@code{gmp_randstate_t}.
+@end deftp
+
+@deftypefun {} gmp_randclass::gmp_randclass (void (*@var{randinit}) (gmp_randstate_t, @dots{}), @dots{})
+Construct a @code{gmp_randclass}, using a call to the given @var{randinit}
+function (@pxref{Random State Initialization}). The arguments expected are
+the same as @var{randinit}, but with @code{mpz_class} instead of @code{mpz_t}.
+For example,
+
+@example
+gmp_randclass r1 (gmp_randinit_default);
+gmp_randclass r2 (gmp_randinit_lc_2exp_size, 32);
+gmp_randclass r3 (gmp_randinit_lc_2exp, a, c, m2exp);
+gmp_randclass r4 (gmp_randinit_mt);
+@end example
+
+@code{gmp_randinit_lc_2exp_size} will fail if the size requested is too big,
+an @code{std::length_error} exception is thrown in that case.
+@end deftypefun
+
+@deftypefun {} gmp_randclass::gmp_randclass (gmp_randalg_t @var{alg}, @dots{})
+Construct a @code{gmp_randclass} using the same parameters as
+@code{gmp_randinit} (@pxref{Random State Initialization}). This function is
+obsolete and the above @var{randinit} style should be preferred.
+@end deftypefun
+
+@deftypefun void gmp_randclass::seed (unsigned long int @var{s})
+@deftypefunx void gmp_randclass::seed (mpz_class @var{s})
+Seed a random number generator. See @pxref{Random Number Functions}, for how
+to choose a good seed.
+@end deftypefun
+
+@deftypefun mpz_class gmp_randclass::get_z_bits (mp_bitcnt_t @var{bits})
+@deftypefunx mpz_class gmp_randclass::get_z_bits (mpz_class @var{bits})
+Generate a random integer with a specified number of bits.
+@end deftypefun
+
+@deftypefun mpz_class gmp_randclass::get_z_range (mpz_class @var{n})
+Generate a random integer in the range 0 to @math{@var{n}-1} inclusive.
+@end deftypefun
+
+@deftypefun mpf_class gmp_randclass::get_f ()
+@deftypefunx mpf_class gmp_randclass::get_f (mp_bitcnt_t @var{prec})
+Generate a random float @var{f} in the range @math{0 <= @var{f} < 1}. @var{f}
+will be to @var{prec} bits precision, or if @var{prec} is not given then to
+the precision of the destination. For example,
+
+@example
+gmp_randclass r;
+...
+mpf_class f (0, 512); // 512 bits precision
+f = r.get_f(); // random number, 512 bits
+@end example
+@end deftypefun
+
+
+
+@node C++ Interface Limitations, , C++ Interface Random Numbers, C++ Class Interface
+@section C++ Interface Limitations
+
+@table @asis
+@item @code{mpq_class} and Templated Reading
+A generic piece of template code probably won't know that @code{mpq_class}
+requires a @code{canonicalize} call if inputs read with @code{operator>>}
+might be non-canonical. This can lead to incorrect results.
+
+@code{operator>>} behaves as it does for reasons of efficiency. A
+canonicalize can be quite time consuming on large operands, and is best
+avoided if it's not necessary.
+
+But this potential difficulty reduces the usefulness of @code{mpq_class}.
+Perhaps a mechanism to tell @code{operator>>} what to do will be adopted in
+the future, maybe a preprocessor define, a global flag, or an @code{ios} flag
+pressed into service. Or maybe, at the risk of inconsistency, the
+@code{mpq_class} @code{operator>>} could canonicalize and leave @code{mpq_t}
+@code{operator>>} not doing so, for use on those occasions when that's
+acceptable. Send feedback or alternate ideas to @email{gmp-bugs@@gmplib.org}.
+
+@item Subclassing
+Subclassing the GMP C++ classes works, but is not currently recommended.
+
+Expressions involving subclasses resolve correctly (or seem to), but in normal
+C++ fashion the subclass doesn't inherit constructors and assignments.
+There's many of those in the GMP classes, and a good way to reestablish them
+in a subclass is not yet provided.
+
+@item Templated Expressions
+A subtle difficulty exists when using expressions together with
+application-defined template functions. Consider the following, with @code{T}
+intended to be some numeric type,
+
+@example
+template <class T>
+T fun (const T &, const T &);
+@end example
+
+@noindent
+When used with, say, plain @code{mpz_class} variables, it works fine: @code{T}
+is resolved as @code{mpz_class}.
+
+@example
+mpz_class f(1), g(2);
+fun (f, g); // Good
+@end example
+
+@noindent
+But when one of the arguments is an expression, it doesn't work.
+
+@example
+mpz_class f(1), g(2), h(3);
+fun (f, g+h); // Bad
+@end example
+
+This is because @code{g+h} ends up being a certain expression template type
+internal to @code{gmpxx.h}, which the C++ template resolution rules are unable
+to automatically convert to @code{mpz_class}. The workaround is simply to add
+an explicit cast.
+
+@example
+mpz_class f(1), g(2), h(3);
+fun (f, mpz_class(g+h)); // Good
+@end example
+
+Similarly, within @code{fun} it may be necessary to cast an expression to type
+@code{T} when calling a templated @code{fun2}.
+
+@example
+template <class T>
+void fun (T f, T g)
+@{
+ fun2 (f, f+g); // Bad
+@}
+
+template <class T>
+void fun (T f, T g)
+@{
+ fun2 (f, T(f+g)); // Good
+@}
+@end example
+
+@item C++11
+C++11 provides several new ways in which types can be inferred: @code{auto},
+@code{decltype}, etc. While they can be very convenient, they don't mix well
+with expression templates. In this example, the addition is performed twice,
+as if we had defined @code{sum} as a macro.
+
+@example
+mpz_class z = 33;
+auto sum = z + z;
+mpz_class prod = sum * sum;
+@end example
+
+This other example may crash, though some compilers might make it look like
+it is working, because the expression @code{z+z} goes out of scope before it
+is evaluated.
+
+@example
+mpz_class z = 33;
+auto sum = z + z + z;
+mpz_class prod = sum * 2;
+@end example
+
+It is thus strongly recommended to avoid @code{auto} anywhere a GMP C++
+expression may appear.
+@end table
+
+
+@node Custom Allocation, Language Bindings, C++ Class Interface, Top
+@comment node-name, next, previous, up
+@chapter Custom Allocation
+@cindex Custom allocation
+@cindex Memory allocation
+@cindex Allocation of memory
+
+By default GMP uses @code{malloc}, @code{realloc} and @code{free} for memory
+allocation, and if they fail GMP prints a message to the standard error output
+and terminates the program.
+
+Alternate functions can be specified, to allocate memory in a different way or
+to have a different error action on running out of memory.
+
+@deftypefun void mp_set_memory_functions (@* void *(*@var{alloc_func_ptr}) (size_t), @* void *(*@var{realloc_func_ptr}) (void *, size_t, size_t), @* void (*@var{free_func_ptr}) (void *, size_t))
+Replace the current allocation functions from the arguments. If an argument
+is @code{NULL}, the corresponding default function is used.
+
+These functions will be used for all memory allocation done by GMP, apart from
+temporary space from @code{alloca} if that function is available and GMP is
+configured to use it (@pxref{Build Options}).
+
+@strong{Be sure to call @code{mp_set_memory_functions} only when there are no
+active GMP objects allocated using the previous memory functions! Usually
+that means calling it before any other GMP function.}
+@end deftypefun
+
+The functions supplied should fit the following declarations:
+
+@deftypevr Function {void *} allocate_function (size_t @var{alloc_size})
+Return a pointer to newly allocated space with at least @var{alloc_size}
+bytes.
+@end deftypevr
+
+@deftypevr Function {void *} reallocate_function (void *@var{ptr}, size_t @var{old_size}, size_t @var{new_size})
+Resize a previously allocated block @var{ptr} of @var{old_size} bytes to be
+@var{new_size} bytes.
+
+The block may be moved if necessary or if desired, and in that case the
+smaller of @var{old_size} and @var{new_size} bytes must be copied to the new
+location. The return value is a pointer to the resized block, that being the
+new location if moved or just @var{ptr} if not.
+
+@var{ptr} is never @code{NULL}, it's always a previously allocated block.
+@var{new_size} may be bigger or smaller than @var{old_size}.
+@end deftypevr
+
+@deftypevr Function void free_function (void *@var{ptr}, size_t @var{size})
+De-allocate the space pointed to by @var{ptr}.
+
+@var{ptr} is never @code{NULL}, it's always a previously allocated block of
+@var{size} bytes.
+@end deftypevr
+
+A @dfn{byte} here means the unit used by the @code{sizeof} operator.
+
+The @var{reallocate_function} parameter @var{old_size} and the
+@var{free_function} parameter @var{size} are passed for convenience, but of
+course they can be ignored if not needed by an implementation. The default
+functions using @code{malloc} and friends for instance don't use them.
+
+No error return is allowed from any of these functions, if they return then
+they must have performed the specified operation. In particular note that
+@var{allocate_function} or @var{reallocate_function} mustn't return
+@code{NULL}.
+
+Getting a different fatal error action is a good use for custom allocation
+functions, for example giving a graphical dialog rather than the default print
+to @code{stderr}. How much is possible when genuinely out of memory is
+another question though.
+
+There's currently no defined way for the allocation functions to recover from
+an error such as out of memory, they must terminate program execution. A
+@code{longjmp} or throwing a C++ exception will have undefined results. This
+may change in the future.
+
+GMP may use allocated blocks to hold pointers to other allocated blocks. This
+will limit the assumptions a conservative garbage collection scheme can make.
+
+Since the default GMP allocation uses @code{malloc} and friends, those
+functions will be linked in even if the first thing a program does is an
+@code{mp_set_memory_functions}. It's necessary to change the GMP sources if
+this is a problem.
+
+@sp 1
+@deftypefun void mp_get_memory_functions (@* void *(**@var{alloc_func_ptr}) (size_t), @* void *(**@var{realloc_func_ptr}) (void *, size_t, size_t), @* void (**@var{free_func_ptr}) (void *, size_t))
+Get the current allocation functions, storing function pointers to the
+locations given by the arguments. If an argument is @code{NULL}, that
+function pointer is not stored.
+
+@need 1000
+For example, to get just the current free function,
+
+@example
+void (*freefunc) (void *, size_t);
+
+mp_get_memory_functions (NULL, NULL, &freefunc);
+@end example
+@end deftypefun
+
+@node Language Bindings, Algorithms, Custom Allocation, Top
+@chapter Language Bindings
+@cindex Language bindings
+@cindex Other languages
+
+The following packages and projects offer access to GMP from languages other
+than C, though perhaps with varying levels of functionality and efficiency.
+
+@c @spaceuref{U} is the same as @uref{U}, but with a couple of extra spaces
+@c in tex, just to separate the URL from the preceding text a bit.
+@iftex
+@macro spaceuref {U}
+@ @ @uref{\U\}
+@end macro
+@end iftex
+@ifnottex
+@macro spaceuref {U}
+@uref{\U\}
+@end macro
+@end ifnottex
+
+@sp 1
+@table @asis
+@item C++
+@itemize @bullet
+@item
+GMP C++ class interface, @pxref{C++ Class Interface} @* Straightforward
+interface, expression templates to eliminate temporaries.
+@item
+ALP @spaceuref{https://www-sop.inria.fr/saga/logiciels/ALP/} @* Linear algebra and
+polynomials using templates.
+@item
+Arithmos @spaceuref{http://cant.ua.ac.be/old/arithmos/} @* Rationals
+with infinities and square roots.
+@item
+CLN @spaceuref{http://www.ginac.de/CLN/} @* High level classes for arithmetic.
+@item
+Linbox @spaceuref{http://www.linalg.org/} @* Sparse vectors and matrices.
+@item
+NTL @spaceuref{http://www.shoup.net/ntl/} @* A C++ number theory library.
+@end itemize
+
+@c @item D
+@c @itemize @bullet
+@c @item
+@c gmp-d @spaceuref{http://home.comcast.net/~benhinkle/gmp-d/}
+@c @end itemize
+
+@item Eiffel
+@itemize @bullet
+@item
+Eiffelroom @spaceuref{http://www.eiffelroom.org/node/442}
+@end itemize
+
+@c @item Fortran
+@c @itemize @bullet
+@c @item
+@c Omni F77 @spaceuref{http://phase.hpcc.jp/Omni/home.html} @* Arbitrary
+@c precision floats.
+@c @end itemize
+
+@item Haskell
+@itemize @bullet
+@item
+Glasgow Haskell Compiler @spaceuref{https://www.haskell.org/ghc/}
+@end itemize
+
+@item Java
+@itemize @bullet
+@item
+Kaffe @spaceuref{https://github.com/kaffe/kaffe}
+@end itemize
+
+@item Lisp
+@itemize @bullet
+@item
+GNU Common Lisp @spaceuref{https://www.gnu.org/software/gcl/gcl.html}
+@item
+Librep @spaceuref{http://librep.sourceforge.net/}
+@item
+@c FIXME: When there's a stable release with gmp support, just refer to it
+@c rather than bothering to talk about betas.
+XEmacs (21.5.18 beta and up) @spaceuref{http://www.xemacs.org} @* Optional
+big integers, rationals and floats using GMP.
+@end itemize
+
+@item M4
+@itemize @bullet
+@item
+@c FIXME: When there's a stable release with gmp support, just refer to it
+@c rather than bothering to talk about betas.
+GNU m4 betas @spaceuref{http://www.seindal.dk/rene/gnu/} @* Optionally provides
+an arbitrary precision @code{mpeval}.
+@end itemize
+
+@item ML
+@itemize @bullet
+@item
+MLton compiler @spaceuref{http://mlton.org/}
+@end itemize
+
+@item Objective Caml
+@itemize @bullet
+@item
+MLGMP @spaceuref{http://opam.ocamlpro.com/pkg/mlgmp.20120224.html}
+@item
+Numerix @spaceuref{http://pauillac.inria.fr/~quercia/} @* Optionally using
+GMP.
+@end itemize
+
+@item Oz
+@itemize @bullet
+@item
+Mozart @spaceuref{http://mozart.github.io/}
+@end itemize
+
+@item Pascal
+@itemize @bullet
+@item
+GNU Pascal Compiler @spaceuref{http://www.gnu-pascal.de/} @* GMP unit.
+@item
+Numerix @spaceuref{http://pauillac.inria.fr/~quercia/} @* For Free Pascal,
+optionally using GMP.
+@end itemize
+
+@item Perl
+@itemize @bullet
+@item
+GMP module, see @file{demos/perl} in the GMP sources (@pxref{Demonstration
+Programs}).
+@item
+Math::GMP @spaceuref{http://www.cpan.org/} @* Compatible with Math::BigInt, but
+not as many functions as the GMP module above.
+@item
+Math::BigInt::GMP @spaceuref{http://www.cpan.org/} @* Plug Math::GMP into
+normal Math::BigInt operations.
+@end itemize
+
+@need 1000
+@item Pike
+@itemize @bullet
+@item
+mpz module in the standard distribution, @uref{http://pike.ida.liu.se/}
+@end itemize
+
+@need 500
+@item Prolog
+@itemize @bullet
+@item
+SWI Prolog @spaceuref{http://www.swi-prolog.org/} @*
+Arbitrary precision floats.
+@end itemize
+
+@item Python
+@itemize @bullet
+@item
+GMPY @uref{https://code.google.com/p/gmpy/}
+@end itemize
+
+@item Ruby
+@itemize @bullet
+@item
+http://rubygems.org/gems/gmp
+@end itemize
+
+@item Scheme
+@itemize @bullet
+@item
+GNU Guile @spaceuref{https://www.gnu.org/software/guile/guile.html}
+@item
+RScheme @spaceuref{http://www.rscheme.org/}
+@item
+STklos @spaceuref{http://www.stklos.net/}
+@c
+@c For reference, MzScheme uses some of gmp, but (as of version 205) it only
+@c has copies of some of the generic C code, and we don't consider that a
+@c language binding to gmp.
+@c
+@end itemize
+
+@item Smalltalk
+@itemize @bullet
+@item
+GNU Smalltalk @spaceuref{http://www.smalltalk.org/versions/GNUSmalltalk.html}
+@end itemize
+
+@item Other
+@itemize @bullet
+@item
+Axiom @uref{https://savannah.nongnu.org/projects/axiom} @* Computer algebra
+using GCL.
+@item
+DrGenius @spaceuref{http://drgenius.seul.org/} @* Geometry system and
+mathematical programming language.
+@item
+GiNaC @spaceuref{http://www.ginac.de/} @* C++ computer algebra using CLN.
+@item
+GOO @spaceuref{https://www.eecs.berkeley.edu/~jrb/goo/} @* Dynamic object oriented
+language.
+@item
+Maxima @uref{https://www.ma.utexas.edu/users/wfs/maxima.html} @* Macsyma
+computer algebra using GCL.
+@c @item
+@c Q @spaceuref{http://q-lang.sourceforge.net/} @* Equational programming system.
+@item
+Regina @spaceuref{http://regina.sourceforge.net/} @* Topological calculator.
+@item
+Yacas @spaceuref{http://yacas.sourceforge.net} @* Yet another computer algebra system.
+@end itemize
+
+@end table
+
+
+@node Algorithms, Internals, Language Bindings, Top
+@chapter Algorithms
+@cindex Algorithms
+
+This chapter is an introduction to some of the algorithms used for various GMP
+operations. The code is likely to be hard to understand without knowing
+something about the algorithms.
+
+Some GMP internals are mentioned, but applications that expect to be
+compatible with future GMP releases should take care to use only the
+documented functions.
+
+@menu
+* Multiplication Algorithms::
+* Division Algorithms::
+* Greatest Common Divisor Algorithms::
+* Powering Algorithms::
+* Root Extraction Algorithms::
+* Radix Conversion Algorithms::
+* Other Algorithms::
+* Assembly Coding::
+@end menu
+
+
+@node Multiplication Algorithms, Division Algorithms, Algorithms, Algorithms
+@section Multiplication
+@cindex Multiplication algorithms
+
+N@cross{}N limb multiplications and squares are done using one of seven
+algorithms, as the size N increases.
+
+@quotation
+@multitable {KaratsubaMMM} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item Algorithm @tab Threshold
+@item Basecase @tab (none)
+@item Karatsuba @tab @code{MUL_TOOM22_THRESHOLD}
+@item Toom-3 @tab @code{MUL_TOOM33_THRESHOLD}
+@item Toom-4 @tab @code{MUL_TOOM44_THRESHOLD}
+@item Toom-6.5 @tab @code{MUL_TOOM6H_THRESHOLD}
+@item Toom-8.5 @tab @code{MUL_TOOM8H_THRESHOLD}
+@item FFT @tab @code{MUL_FFT_THRESHOLD}
+@end multitable
+@end quotation
+
+Similarly for squaring, with the @code{SQR} thresholds.
+
+N@cross{}M multiplications of operands with different sizes above
+@code{MUL_TOOM22_THRESHOLD} are currently done by special Toom-inspired
+algorithms or directly with FFT, depending on operand size (@pxref{Unbalanced
+Multiplication}).
+
+@menu
+* Basecase Multiplication::
+* Karatsuba Multiplication::
+* Toom 3-Way Multiplication::
+* Toom 4-Way Multiplication::
+* Higher degree Toom'n'half::
+* FFT Multiplication::
+* Other Multiplication::
+* Unbalanced Multiplication::
+@end menu
+
+
+@node Basecase Multiplication, Karatsuba Multiplication, Multiplication Algorithms, Multiplication Algorithms
+@subsection Basecase Multiplication
+
+Basecase N@cross{}M multiplication is a straightforward rectangular set of
+cross-products, the same as long multiplication done by hand and for that
+reason sometimes known as the schoolbook or grammar school method. This is an
+@m{O(NM),O(N*M)} algorithm. See Knuth section 4.3.1 algorithm M
+(@pxref{References}), and the @file{mpn/generic/mul_basecase.c} code.
+
+Assembly implementations of @code{mpn_mul_basecase} are essentially the same
+as the generic C code, but have all the usual assembly tricks and
+obscurities introduced for speed.
+
+A square can be done in roughly half the time of a multiply, by using the fact
+that the cross products above and below the diagonal are the same. A triangle
+of products below the diagonal is formed, doubled (left shift by one bit), and
+then the products on the diagonal added. This can be seen in
+@file{mpn/generic/sqr_basecase.c}. Again the assembly implementations take
+essentially the same approach.
+
+@tex
+\def\GMPline#1#2#3#4#5#6{%
+ \hbox {%
+ \vrule height 2.5ex depth 1ex
+ \hbox to 2em {\hfil{#2}\hfil}%
+ \vrule \hbox to 2em {\hfil{#3}\hfil}%
+ \vrule \hbox to 2em {\hfil{#4}\hfil}%
+ \vrule \hbox to 2em {\hfil{#5}\hfil}%
+ \vrule \hbox to 2em {\hfil{#6}\hfil}%
+ \vrule}}
+\GMPdisplay{
+ \hbox{%
+ \vbox{%
+ \hbox to 1.5em {\vrule height 2.5ex depth 1ex width 0pt}%
+ \hbox {\vrule height 2.5ex depth 1ex width 0pt u0\hfil}%
+ \hbox {\vrule height 2.5ex depth 1ex width 0pt u1\hfil}%
+ \hbox {\vrule height 2.5ex depth 1ex width 0pt u2\hfil}%
+ \hbox {\vrule height 2.5ex depth 1ex width 0pt u3\hfil}%
+ \hbox {\vrule height 2.5ex depth 1ex width 0pt u4\hfil}%
+ \vfill}%
+ \vbox{%
+ \hbox{%
+ \hbox to 2em {\hfil u0\hfil}%
+ \hbox to 2em {\hfil u1\hfil}%
+ \hbox to 2em {\hfil u2\hfil}%
+ \hbox to 2em {\hfil u3\hfil}%
+ \hbox to 2em {\hfil u4\hfil}}%
+ \vskip 0.7ex
+ \hrule
+ \GMPline{u0}{d}{}{}{}{}%
+ \hrule
+ \GMPline{u1}{}{d}{}{}{}%
+ \hrule
+ \GMPline{u2}{}{}{d}{}{}%
+ \hrule
+ \GMPline{u3}{}{}{}{d}{}%
+ \hrule
+ \GMPline{u4}{}{}{}{}{d}%
+ \hrule}}}
+@end tex
+@ifnottex
+@example
+@group
+ u0 u1 u2 u3 u4
+ +---+---+---+---+---+
+u0 | d | | | | |
+ +---+---+---+---+---+
+u1 | | d | | | |
+ +---+---+---+---+---+
+u2 | | | d | | |
+ +---+---+---+---+---+
+u3 | | | | d | |
+ +---+---+---+---+---+
+u4 | | | | | d |
+ +---+---+---+---+---+
+@end group
+@end example
+@end ifnottex
+
+In practice squaring isn't a full 2@cross{} faster than multiplying, it's
+usually around 1.5@cross{}. Less than 1.5@cross{} probably indicates
+@code{mpn_sqr_basecase} wants improving on that CPU.
+
+On some CPUs @code{mpn_mul_basecase} can be faster than the generic C
+@code{mpn_sqr_basecase} on some small sizes. @code{SQR_BASECASE_THRESHOLD} is
+the size at which to use @code{mpn_sqr_basecase}, this will be zero if that
+routine should be used always.
+
+
+@node Karatsuba Multiplication, Toom 3-Way Multiplication, Basecase Multiplication, Multiplication Algorithms
+@subsection Karatsuba Multiplication
+@cindex Karatsuba multiplication
+
+The Karatsuba multiplication algorithm is described in Knuth section 4.3.3
+part A, and various other textbooks. A brief description is given here.
+
+The inputs @math{x} and @math{y} are treated as each split into two parts of
+equal length (or the most significant part one limb shorter if N is odd).
+
+@tex
+% GMPboxwidth used for all the multiplication pictures
+\global\newdimen\GMPboxwidth \global\GMPboxwidth=5em
+% GMPboxdepth and GMPboxheight are also used for the float pictures
+\global\newdimen\GMPboxdepth \global\GMPboxdepth=1ex
+\global\newdimen\GMPboxheight \global\GMPboxheight=2ex
+\gdef\GMPvrule{\vrule height \GMPboxheight depth \GMPboxdepth}
+\def\GMPbox#1#2{%
+ \vbox {%
+ \hrule
+ \hbox to 2\GMPboxwidth{%
+ \GMPvrule \hfil $#1$\hfil \vrule \hfil $#2$\hfil \vrule}%
+ \hrule}}
+\GMPdisplay{%
+\vbox{%
+ \hbox to 2\GMPboxwidth {high \hfil low}
+ \vskip 0.7ex
+ \GMPbox{x_1}{x_0}
+ \vskip 0.5ex
+ \GMPbox{y_1}{y_0}
+}}
+@end tex
+@ifnottex
+@example
+@group
+ high low
++----------+----------+
+| x1 | x0 |
++----------+----------+
+
++----------+----------+
+| y1 | y0 |
++----------+----------+
+@end group
+@end example
+@end ifnottex
+
+Let @math{b} be the power of 2 where the split occurs, i.e.@: if @ms{x,0} is
+@math{k} limbs (@ms{y,0} the same) then
+@m{b=2\GMPraise{$k*$@code{mp\_bits\_per\_limb}}, b=2^(k*mp_bits_per_limb)}.
+With that @m{x=x_1b+x_0,x=x1*b+x0} and @m{y=y_1b+y_0,y=y1*b+y0}, and the
+following holds,
+
+@display
+@m{xy = (b^2+b)x_1y_1 - b(x_1-x_0)(y_1-y_0) + (b+1)x_0y_0,
+ x*y = (b^2+b)*x1*y1 - b*(x1-x0)*(y1-y0) + (b+1)*x0*y0}
+@end display
+
+This formula means doing only three multiplies of (N/2)@cross{}(N/2) limbs,
+whereas a basecase multiply of N@cross{}N limbs is equivalent to four
+multiplies of (N/2)@cross{}(N/2). The factors @math{(b^2+b)} etc represent
+the positions where the three products must be added.
+
+@tex
+\def\GMPboxA#1#2{%
+ \vbox{%
+ \hrule
+ \hbox{%
+ \GMPvrule
+ \hbox to 2\GMPboxwidth {\hfil\hbox{$#1$}\hfil}%
+ \vrule
+ \hbox to 2\GMPboxwidth {\hfil\hbox{$#2$}\hfil}%
+ \vrule}
+ \hrule}}
+\def\GMPboxB#1#2{%
+ \hbox{%
+ \raise \GMPboxdepth \hbox to \GMPboxwidth {\hfil #1\hskip 0.5em}%
+ \vbox{%
+ \hrule
+ \hbox{%
+ \GMPvrule
+ \hbox to 2\GMPboxwidth {\hfil\hbox{$#2$}\hfil}%
+ \vrule}%
+ \hrule}}}
+\GMPdisplay{%
+\vbox{%
+ \hbox to 4\GMPboxwidth {high \hfil low}
+ \vskip 0.7ex
+ \GMPboxA{x_1y_1}{x_0y_0}
+ \vskip 0.5ex
+ \GMPboxB{$+$}{x_1y_1}
+ \vskip 0.5ex
+ \GMPboxB{$+$}{x_0y_0}
+ \vskip 0.5ex
+ \GMPboxB{$-$}{(x_1-x_0)(y_1-y_0)}
+}}
+@end tex
+@ifnottex
+@example
+@group
+ high low
++--------+--------+ +--------+--------+
+| x1*y1 | | x0*y0 |
++--------+--------+ +--------+--------+
+ +--------+--------+
+ add | x1*y1 |
+ +--------+--------+
+ +--------+--------+
+ add | x0*y0 |
+ +--------+--------+
+ +--------+--------+
+ sub | (x1-x0)*(y1-y0) |
+ +--------+--------+
+@end group
+@end example
+@end ifnottex
+
+The term @m{(x_1-x_0)(y_1-y_0),(x1-x0)*(y1-y0)} is best calculated as an
+absolute value, and the sign used to choose to add or subtract. Notice the
+sum @m{\mathop{\rm high}(x_0y_0)+\mathop{\rm low}(x_1y_1),
+high(x0*y0)+low(x1*y1)} occurs twice, so it's possible to do @m{5k,5*k} limb
+additions, rather than @m{6k,6*k}, but in GMP extra function call overheads
+outweigh the saving.
+
+Squaring is similar to multiplying, but with @math{x=y} the formula reduces to
+an equivalent with three squares,
+
+@display
+@m{x^2 = (b^2+b)x_1^2 - b(x_1-x_0)^2 + (b+1)x_0^2,
+ x^2 = (b^2+b)*x1^2 - b*(x1-x0)^2 + (b+1)*x0^2}
+@end display
+
+The final result is accumulated from those three squares the same way as for
+the three multiplies above. The middle term @m{(x_1-x_0)^2,(x1-x0)^2} is now
+always positive.
+
+A similar formula for both multiplying and squaring can be constructed with a
+middle term @m{(x_1+x_0)(y_1+y_0),(x1+x0)*(y1+y0)}. But those sums can exceed
+@math{k} limbs, leading to more carry handling and additions than the form
+above.
+
+Karatsuba multiplication is asymptotically an @math{O(N^@W{1.585})} algorithm,
+the exponent being @m{\log3/\log2,log(3)/log(2)}, representing 3 multiplies
+each @math{1/2} the size of the inputs. This is a big improvement over the
+basecase multiply at @math{O(N^2)} and the advantage soon overcomes the extra
+additions Karatsuba performs. @code{MUL_TOOM22_THRESHOLD} can be as little
+as 10 limbs. The @code{SQR} threshold is usually about twice the @code{MUL}.
+
+The basecase algorithm will take a time of the form @m{M(N) = aN^2 + bN + c,
+M(N) = a*N^2 + b*N + c} and the Karatsuba algorithm @m{K(N) = 3M(N/2) + dN +
+e, K(N) = 3*M(N/2) + d*N + e}, which expands to @m{K(N) = {3\over4} aN^2 +
+{3\over2} bN + 3c + dN + e, K(N) = 3/4*a*N^2 + 3/2*b*N + 3*c + d*N + e}. The
+factor @m{3\over4, 3/4} for @math{a} means per-crossproduct speedups in the
+basecase code will increase the threshold since they benefit @math{M(N)} more
+than @math{K(N)}. And conversely the @m{3\over2, 3/2} for @math{b} means
+linear style speedups of @math{b} will increase the threshold since they
+benefit @math{K(N)} more than @math{M(N)}. The latter can be seen for
+instance when adding an optimized @code{mpn_sqr_diagonal} to
+@code{mpn_sqr_basecase}. Of course all speedups reduce total time, and in
+that sense the algorithm thresholds are merely of academic interest.
+
+
+@node Toom 3-Way Multiplication, Toom 4-Way Multiplication, Karatsuba Multiplication, Multiplication Algorithms
+@subsection Toom 3-Way Multiplication
+@cindex Toom multiplication
+
+The Karatsuba formula is the simplest case of a general approach to splitting
+inputs that leads to both Toom and FFT algorithms. A description of
+Toom can be found in Knuth section 4.3.3, with an example 3-way
+calculation after Theorem A@. The 3-way form used in GMP is described here.
+
+The operands are each considered split into 3 pieces of equal length (or the
+most significant part 1 or 2 limbs shorter than the other two).
+
+@tex
+\def\GMPbox#1#2#3{%
+ \vbox{%
+ \hrule \vfil
+ \hbox to 3\GMPboxwidth {%
+ \GMPvrule
+ \hfil$#1$\hfil
+ \vrule
+ \hfil$#2$\hfil
+ \vrule
+ \hfil$#3$\hfil
+ \vrule}%
+ \vfil \hrule
+}}
+\GMPdisplay{%
+\vbox{%
+ \hbox to 3\GMPboxwidth {high \hfil low}
+ \vskip 0.7ex
+ \GMPbox{x_2}{x_1}{x_0}
+ \vskip 0.5ex
+ \GMPbox{y_2}{y_1}{y_0}
+ \vskip 0.5ex
+}}
+@end tex
+@ifnottex
+@example
+@group
+ high low
++----------+----------+----------+
+| x2 | x1 | x0 |
++----------+----------+----------+
+
++----------+----------+----------+
+| y2 | y1 | y0 |
++----------+----------+----------+
+@end group
+@end example
+@end ifnottex
+
+@noindent
+These parts are treated as the coefficients of two polynomials
+
+@display
+@group
+@m{X(t) = x_2t^2 + x_1t + x_0,
+ X(t) = x2*t^2 + x1*t + x0}
+@m{Y(t) = y_2t^2 + y_1t + y_0,
+ Y(t) = y2*t^2 + y1*t + y0}
+@end group
+@end display
+
+Let @math{b} equal the power of 2 which is the size of the @ms{x,0}, @ms{x,1},
+@ms{y,0} and @ms{y,1} pieces, i.e.@: if they're @math{k} limbs each then
+@m{b=2\GMPraise{$k*$@code{mp\_bits\_per\_limb}}, b=2^(k*mp_bits_per_limb)}.
+With this @math{x=X(b)} and @math{y=Y(b)}.
+
+Let a polynomial @m{W(t)=X(t)Y(t),W(t)=X(t)*Y(t)} and suppose its coefficients
+are
+
+@display
+@m{W(t) = w_4t^4 + w_3t^3 + w_2t^2 + w_1t + w_0,
+ W(t) = w4*t^4 + w3*t^3 + w2*t^2 + w1*t + w0}
+@end display
+
+The @m{w_i,w[i]} are going to be determined, and when they are they'll give
+the final result using @math{w=W(b)}, since
+@m{xy=X(b)Y(b),x*y=X(b)*Y(b)=W(b)}. The coefficients will be roughly
+@math{b^2} each, and the final @math{W(b)} will be an addition like,
+
+@tex
+\def\GMPbox#1#2{%
+ \moveright #1\GMPboxwidth
+ \vbox{%
+ \hrule
+ \hbox{%
+ \GMPvrule
+ \hbox to 2\GMPboxwidth {\hfil$#2$\hfil}%
+ \vrule}%
+ \hrule
+}}
+\GMPdisplay{%
+\vbox{%
+ \hbox to 6\GMPboxwidth {high \hfil low}%
+ \vskip 0.7ex
+ \GMPbox{0}{w_4}
+ \vskip 0.5ex
+ \GMPbox{1}{w_3}
+ \vskip 0.5ex
+ \GMPbox{2}{w_2}
+ \vskip 0.5ex
+ \GMPbox{3}{w_1}
+ \vskip 0.5ex
+ \GMPbox{4}{w_0}
+}}
+@end tex
+@ifnottex
+@example
+@group
+ high low
++-------+-------+
+| w4 |
++-------+-------+
+ +--------+-------+
+ | w3 |
+ +--------+-------+
+ +--------+-------+
+ | w2 |
+ +--------+-------+
+ +--------+-------+
+ | w1 |
+ +--------+-------+
+ +-------+-------+
+ | w0 |
+ +-------+-------+
+@end group
+@end example
+@end ifnottex
+
+The @m{w_i,w[i]} coefficients could be formed by a simple set of cross
+products, like @m{w_4=x_2y_2,w4=x2*y2}, @m{w_3=x_2y_1+x_1y_2,w3=x2*y1+x1*y2},
+@m{w_2=x_2y_0+x_1y_1+x_0y_2,w2=x2*y0+x1*y1+x0*y2} etc, but this would need all
+nine @m{x_iy_j,x[i]*y[j]} for @math{i,j=0,1,2}, and would be equivalent merely
+to a basecase multiply. Instead the following approach is used.
+
+@math{X(t)} and @math{Y(t)} are evaluated and multiplied at 5 points, giving
+values of @math{W(t)} at those points. In GMP the following points are used,
+
+@quotation
+@multitable {@m{t=\infty,t=inf}M} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item Point @tab Value
+@item @math{t=0} @tab @m{x_0y_0,x0 * y0}, which gives @ms{w,0} immediately
+@item @math{t=1} @tab @m{(x_2+x_1+x_0)(y_2+y_1+y_0),(x2+x1+x0) * (y2+y1+y0)}
+@item @math{t=-1} @tab @m{(x_2-x_1+x_0)(y_2-y_1+y_0),(x2-x1+x0) * (y2-y1+y0)}
+@item @math{t=2} @tab @m{(4x_2+2x_1+x_0)(4y_2+2y_1+y_0),(4*x2+2*x1+x0) * (4*y2+2*y1+y0)}
+@item @m{t=\infty,t=inf} @tab @m{x_2y_2,x2 * y2}, which gives @ms{w,4} immediately
+@end multitable
+@end quotation
+
+At @math{t=-1} the values can be negative and that's handled using the
+absolute values and tracking the sign separately. At @m{t=\infty,t=inf} the
+value is actually @m{\lim_{t\to\infty} {X(t)Y(t)\over t^4}, X(t)*Y(t)/t^4 in
+the limit as t approaches infinity}, but it's much easier to think of as
+simply @m{x_2y_2,x2*y2} giving @ms{w,4} immediately (much like
+@m{x_0y_0,x0*y0} at @math{t=0} gives @ms{w,0} immediately).
+
+Each of the points substituted into
+@m{W(t)=w_4t^4+\cdots+w_0,W(t)=w4*t^4+@dots{}+w0} gives a linear combination
+of the @m{w_i,w[i]} coefficients, and the value of those combinations has just
+been calculated.
+
+@tex
+\GMPdisplay{%
+$\matrix{%
+W(0) & = & & & & & & & & & w_0 \cr
+W(1) & = & w_4 & + & w_3 & + & w_2 & + & w_1 & + & w_0 \cr
+W(-1) & = & w_4 & - & w_3 & + & w_2 & - & w_1 & + & w_0 \cr
+W(2) & = & 16w_4 & + & 8w_3 & + & 4w_2 & + & 2w_1 & + & w_0 \cr
+W(\infty) & = & w_4 \cr
+}$}
+@end tex
+@ifnottex
+@example
+@group
+W(0) = w0
+W(1) = w4 + w3 + w2 + w1 + w0
+W(-1) = w4 - w3 + w2 - w1 + w0
+W(2) = 16*w4 + 8*w3 + 4*w2 + 2*w1 + w0
+W(inf) = w4
+@end group
+@end example
+@end ifnottex
+
+This is a set of five equations in five unknowns, and some elementary linear
+algebra quickly isolates each @m{w_i,w[i]}. This involves adding or
+subtracting one @math{W(t)} value from another, and a couple of divisions by
+powers of 2 and one division by 3, the latter using the special
+@code{mpn_divexact_by3} (@pxref{Exact Division}).
+
+The conversion of @math{W(t)} values to the coefficients is interpolation. A
+polynomial of degree 4 like @math{W(t)} is uniquely determined by values known
+at 5 different points. The points are arbitrary and can be chosen to make the
+linear equations come out with a convenient set of steps for quickly isolating
+the @m{w_i,w[i]}.
+
+Squaring follows the same procedure as multiplication, but there's only one
+@math{X(t)} and it's evaluated at the 5 points, and those values squared to
+give values of @math{W(t)}. The interpolation is then identical, and in fact
+the same @code{toom_interpolate_5pts} subroutine is used for both squaring and
+multiplying.
+
+Toom-3 is asymptotically @math{O(N^@W{1.465})}, the exponent being
+@m{\log5/\log3,log(5)/log(3)}, representing 5 recursive multiplies of 1/3 the
+original size each. This is an improvement over Karatsuba at
+@math{O(N^@W{1.585})}, though Toom does more work in the evaluation and
+interpolation and so it only realizes its advantage above a certain size.
+
+Near the crossover between Toom-3 and Karatsuba there's generally a range of
+sizes where the difference between the two is small.
+@code{MUL_TOOM33_THRESHOLD} is a somewhat arbitrary point in that range and
+successive runs of the tune program can give different values due to small
+variations in measuring. A graph of time versus size for the two shows the
+effect, see @file{tune/README}.
+
+At the fairly small sizes where the Toom-3 thresholds occur it's worth
+remembering that the asymptotic behaviour for Karatsuba and Toom-3 can't be
+expected to make accurate predictions, due of course to the big influence of
+all sorts of overheads, and the fact that only a few recursions of each are
+being performed. Even at large sizes there's a good chance machine dependent
+effects like cache architecture will mean actual performance deviates from
+what might be predicted.
+
+The formula given for the Karatsuba algorithm (@pxref{Karatsuba
+Multiplication}) has an equivalent for Toom-3 involving only five multiplies,
+but this would be complicated and unenlightening.
+
+An alternate view of Toom-3 can be found in Zuras (@pxref{References}), using
+a vector to represent the @math{x} and @math{y} splits and a matrix
+multiplication for the evaluation and interpolation stages. The matrix
+inverses are not meant to be actually used, and they have elements with values
+much greater than in fact arise in the interpolation steps. The diagram shown
+for the 3-way is attractive, but again doesn't have to be implemented that way
+and for example with a bit of rearrangement just one division by 6 can be
+done.
+
+
+@node Toom 4-Way Multiplication, Higher degree Toom'n'half, Toom 3-Way Multiplication, Multiplication Algorithms
+@subsection Toom 4-Way Multiplication
+@cindex Toom multiplication
+
+Karatsuba and Toom-3 split the operands into 2 and 3 coefficients,
+respectively. Toom-4 analogously splits the operands into 4 coefficients.
+Using the notation from the section on Toom-3 multiplication, we form two
+polynomials:
+
+@display
+@group
+@m{X(t) = x_3t^3 + x_2t^2 + x_1t + x_0,
+ X(t) = x3*t^3 + x2*t^2 + x1*t + x0}
+@m{Y(t) = y_3t^3 + y_2t^2 + y_1t + y_0,
+ Y(t) = y3*t^3 + y2*t^2 + y1*t + y0}
+@end group
+@end display
+
+@math{X(t)} and @math{Y(t)} are evaluated and multiplied at 7 points, giving
+values of @math{W(t)} at those points. In GMP the following points are used,
+
+@quotation
+@multitable {@m{t=-1/2,t=inf}M} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item Point @tab Value
+@item @math{t=0} @tab @m{x_0y_0,x0 * y0}, which gives @ms{w,0} immediately
+@item @math{t=1/2} @tab @m{(x_3+2x_2+4x_1+8x_0)(y_3+2y_2+4y_1+8y_0),(x3+2*x2+4*x1+8*x0) * (y3+2*y2+4*y1+8*y0)}
+@item @math{t=-1/2} @tab @m{(-x_3+2x_2-4x_1+8x_0)(-y_3+2y_2-4y_1+8y_0),(-x3+2*x2-4*x1+8*x0) * (-y3+2*y2-4*y1+8*y0)}
+@item @math{t=1} @tab @m{(x_3+x_2+x_1+x_0)(y_3+y_2+y_1+y_0),(x3+x2+x1+x0) * (y3+y2+y1+y0)}
+@item @math{t=-1} @tab @m{(-x_3+x_2-x_1+x_0)(-y_3+y_2-y_1+y_0),(-x3+x2-x1+x0) * (-y3+y2-y1+y0)}
+@item @math{t=2} @tab @m{(8x_3+4x_2+2x_1+x_0)(8y_3+4y_2+2y_1+y_0),(8*x3+4*x2+2*x1+x0) * (8*y3+4*y2+2*y1+y0)}
+@item @m{t=\infty,t=inf} @tab @m{x_3y_3,x3 * y3}, which gives @ms{w,6} immediately
+@end multitable
+@end quotation
+
+The number of additions and subtractions for Toom-4 is much larger than for Toom-3.
+But several subexpressions occur multiple times, for example @m{x_2+x_0,x2+x0}, occurs
+for both @math{t=1} and @math{t=-1}.
+
+Toom-4 is asymptotically @math{O(N^@W{1.404})}, the exponent being
+@m{\log7/\log4,log(7)/log(4)}, representing 7 recursive multiplies of 1/4 the
+original size each.
+
+
+@node Higher degree Toom'n'half, FFT Multiplication, Toom 4-Way Multiplication, Multiplication Algorithms
+@subsection Higher degree Toom'n'half
+@cindex Toom multiplication
+
+The Toom algorithms described above (@pxref{Toom 3-Way Multiplication},
+@pxref{Toom 4-Way Multiplication}) generalizes to split into an arbitrary
+number of pieces. In general a split of two equally long operands into
+@math{r} pieces leads to evaluations and pointwise multiplications done at
+@m{2r-1,2*r-1} points. To fully exploit symmetries it would be better to have
+a multiple of 4 points, that's why for higher degree Toom'n'half is used.
+
+Toom'n'half means that the existence of one more piece is considered for a
+single operand. It can be virtual, i.e. zero, or real, when the two operand
+are not exactly balanced. By choosing an even @math{r},
+Toom-@m{r{1\over2},r+1/2} requires @math{2r} points, a multiple of four.
+
+The four-plets of points include 0, @m{\infty,inf}, +1, -1 and
+@m{\pm2^i,+-2^i}, @m{\pm2^{-i},+-2^-i} . Each of them giving shortcuts for the
+evaluation phase and for some steps in the interpolation phase. Further tricks
+are used to reduce the memory footprint of the whole multiplication algorithm
+to a memory buffer equanl in size to the result of the product.
+
+Current GMP uses both Toom-6'n'half and Toom-8'n'half.
+
+
+@node FFT Multiplication, Other Multiplication, Higher degree Toom'n'half, Multiplication Algorithms
+@subsection FFT Multiplication
+@cindex FFT multiplication
+@cindex Fast Fourier Transform
+
+At large to very large sizes a Fermat style FFT multiplication is used,
+following Sch@"onhage and Strassen (@pxref{References}). Descriptions of FFTs
+in various forms can be found in many textbooks, for instance Knuth section
+4.3.3 part C or Lipson chapter IX@. A brief description of the form used in
+GMP is given here.
+
+The multiplication done is @m{xy \bmod 2^N+1, x*y mod 2^N+1}, for a given
+@math{N}. A full product @m{xy,x*y} is obtained by choosing @m{N \ge
+\mathop{\rm bits}(x)+\mathop{\rm bits}(y), N>=bits(x)+bits(y)} and padding
+@math{x} and @math{y} with high zero limbs. The modular product is the native
+form for the algorithm, so padding to get a full product is unavoidable.
+
+The algorithm follows a split, evaluate, pointwise multiply, interpolate and
+combine similar to that described above for Karatsuba and Toom-3. A @math{k}
+parameter controls the split, with an FFT-@math{k} splitting into @math{2^k}
+pieces of @math{M=N/2^k} bits each. @math{N} must be a multiple of
+@m{2^k\times@code{mp\_bits\_per\_limb}, (2^k)*@nicode{mp_bits_per_limb}} so
+the split falls on limb boundaries, avoiding bit shifts in the split and
+combine stages.
+
+The evaluations, pointwise multiplications, and interpolation, are all done
+modulo @m{2^{N'}+1, 2^N'+1} where @math{N'} is @math{2M+k+3} rounded up to a
+multiple of @math{2^k} and of @code{mp_bits_per_limb}. The results of
+interpolation will be the following negacyclic convolution of the input
+pieces, and the choice of @math{N'} ensures these sums aren't truncated.
+@tex
+$$ w_n = \sum_{{i+j = b2^k+n}\atop{b=0,1}} (-1)^b x_i y_j $$
+@end tex
+@ifnottex
+
+@example
+ ---
+ \ b
+w[n] = / (-1) * x[i] * y[j]
+ ---
+ i+j==b*2^k+n
+ b=0,1
+@end example
+
+@end ifnottex
+The points used for the evaluation are @math{g^i} for @math{i=0} to
+@math{2^k-1} where @m{g=2^{2N'/2^k}, g=2^(2N'/2^k)}. @math{g} is a
+@m{2^k,2^k'}th root of unity mod @m{2^{N'}+1,2^N'+1}, which produces necessary
+cancellations at the interpolation stage, and it's also a power of 2 so the
+fast Fourier transforms used for the evaluation and interpolation do only
+shifts, adds and negations.
+
+The pointwise multiplications are done modulo @m{2^{N'}+1, 2^N'+1} and either
+recurse into a further FFT or use a plain multiplication (Toom-3, Karatsuba or
+basecase), whichever is optimal at the size @math{N'}. The interpolation is
+an inverse fast Fourier transform. The resulting set of sums of @m{x_iy_j,
+x[i]*y[j]} are added at appropriate offsets to give the final result.
+
+Squaring is the same, but @math{x} is the only input so it's one transform at
+the evaluate stage and the pointwise multiplies are squares. The
+interpolation is the same.
+
+For a mod @math{2^N+1} product, an FFT-@math{k} is an @m{O(N^{k/(k-1)}),
+O(N^(k/(k-1)))} algorithm, the exponent representing @math{2^k} recursed
+modular multiplies each @m{1/2^{k-1},1/2^(k-1)} the size of the original.
+Each successive @math{k} is an asymptotic improvement, but overheads mean each
+is only faster at bigger and bigger sizes. In the code, @code{MUL_FFT_TABLE}
+and @code{SQR_FFT_TABLE} are the thresholds where each @math{k} is used. Each
+new @math{k} effectively swaps some multiplying for some shifts, adds and
+overheads.
+
+A mod @math{2^N+1} product can be formed with a normal
+@math{N@cross{}N@rightarrow{}2N} bit multiply plus a subtraction, so an FFT
+and Toom-3 etc can be compared directly. A @math{k=4} FFT at
+@math{O(N^@W{1.333})} can be expected to be the first faster than Toom-3 at
+@math{O(N^@W{1.465})}. In practice this is what's found, with
+@code{MUL_FFT_MODF_THRESHOLD} and @code{SQR_FFT_MODF_THRESHOLD} being between
+300 and 1000 limbs, depending on the CPU@. So far it's been found that only
+very large FFTs recurse into pointwise multiplies above these sizes.
+
+When an FFT is to give a full product, the change of @math{N} to @math{2N}
+doesn't alter the theoretical complexity for a given @math{k}, but for the
+purposes of considering where an FFT might be first used it can be assumed
+that the FFT is recursing into a normal multiply and that on that basis it's
+doing @math{2^k} recursed multiplies each @m{1/2^{k-2},1/2^(k-2)} the size of
+the inputs, making it @m{O(N^{k/(k-2)}), O(N^(k/(k-2)))}. This would mean
+@math{k=7} at @math{O(N^@W{1.4})} would be the first FFT faster than Toom-3.
+In practice @code{MUL_FFT_THRESHOLD} and @code{SQR_FFT_THRESHOLD} have been
+found to be in the @math{k=8} range, somewhere between 3000 and 10000 limbs.
+
+The way @math{N} is split into @math{2^k} pieces and then @math{2M+k+3} is
+rounded up to a multiple of @math{2^k} and @code{mp_bits_per_limb} means that
+when @math{2^k@ge{}@nicode{mp\_bits\_per\_limb}} the effective @math{N} is a
+multiple of @m{2^{2k-1},2^(2k-1)} bits. The @math{+k+3} means some values of
+@math{N} just under such a multiple will be rounded to the next. The
+complexity calculations above assume that a favourable size is used, meaning
+one which isn't padded through rounding, and it's also assumed that the extra
+@math{+k+3} bits are negligible at typical FFT sizes.
+
+The practical effect of the @m{2^{2k-1},2^(2k-1)} constraint is to introduce a
+step-effect into measured speeds. For example @math{k=8} will round @math{N}
+up to a multiple of 32768 bits, so for a 32-bit limb there'll be 512 limb
+groups of sizes for which @code{mpn_mul_n} runs at the same speed. Or for
+@math{k=9} groups of 2048 limbs, @math{k=10} groups of 8192 limbs, etc. In
+practice it's been found each @math{k} is used at quite small multiples of its
+size constraint and so the step effect is quite noticeable in a time versus
+size graph.
+
+The threshold determinations currently measure at the mid-points of size
+steps, but this is sub-optimal since at the start of a new step it can happen
+that it's better to go back to the previous @math{k} for a while. Something
+more sophisticated for @code{MUL_FFT_TABLE} and @code{SQR_FFT_TABLE} will be
+needed.
+
+
+@node Other Multiplication, Unbalanced Multiplication, FFT Multiplication, Multiplication Algorithms
+@subsection Other Multiplication
+@cindex Toom multiplication
+
+The Toom algorithms described above (@pxref{Toom 3-Way Multiplication},
+@pxref{Toom 4-Way Multiplication}) generalizes to split into an arbitrary
+number of pieces, as per Knuth section 4.3.3 algorithm C@. This is not
+currently used. The notes here are merely for interest.
+
+In general a split into @math{r+1} pieces is made, and evaluations and
+pointwise multiplications done at @m{2r+1,2*r+1} points. A 4-way split does 7
+pointwise multiplies, 5-way does 9, etc. Asymptotically an @math{(r+1)}-way
+algorithm is @m{O(N^{log(2r+1)/log(r+1)}), O(N^(log(2*r+1)/log(r+1)))}. Only
+the pointwise multiplications count towards big-@math{O} complexity, but the
+time spent in the evaluate and interpolate stages grows with @math{r} and has
+a significant practical impact, with the asymptotic advantage of each @math{r}
+realized only at bigger and bigger sizes. The overheads grow as
+@m{O(Nr),O(N*r)}, whereas in an @math{r=2^k} FFT they grow only as @m{O(N \log
+r), O(N*log(r))}.
+
+Knuth algorithm C evaluates at points 0,1,2,@dots{},@m{2r,2*r}, but exercise 4
+uses @math{-r},@dots{},0,@dots{},@math{r} and the latter saves some small
+multiplies in the evaluate stage (or rather trades them for additions), and
+has a further saving of nearly half the interpolate steps. The idea is to
+separate odd and even final coefficients and then perform algorithm C steps C7
+and C8 on them separately. The divisors at step C7 become @math{j^2} and the
+multipliers at C8 become @m{2tj-j^2,2*t*j-j^2}.
+
+Splitting odd and even parts through positive and negative points can be
+thought of as using @math{-1} as a square root of unity. If a 4th root of
+unity was available then a further split and speedup would be possible, but no
+such root exists for plain integers. Going to complex integers with
+@m{i=\sqrt{-1}, i=sqrt(-1)} doesn't help, essentially because in Cartesian
+form it takes three real multiplies to do a complex multiply. The existence
+of @m{2^k,2^k'}th roots of unity in a suitable ring or field lets the fast
+Fourier transform keep splitting and get to @m{O(N \log r), O(N*log(r))}.
+
+Floating point FFTs use complex numbers approximating Nth roots of unity.
+Some processors have special support for such FFTs. But these are not used in
+GMP since it's very difficult to guarantee an exact result (to some number of
+bits). An occasional difference of 1 in the last bit might not matter to a
+typical signal processing algorithm, but is of course of vital importance to
+GMP.
+
+
+@node Unbalanced Multiplication, , Other Multiplication, Multiplication Algorithms
+@subsection Unbalanced Multiplication
+@cindex Unbalanced multiplication
+
+Multiplication of operands with different sizes, both below
+@code{MUL_TOOM22_THRESHOLD} are done with plain schoolbook multiplication
+(@pxref{Basecase Multiplication}).
+
+For really large operands, we invoke FFT directly.
+
+For operands between these sizes, we use Toom inspired algorithms suggested by
+Alberto Zanoni and Marco Bodrato. The idea is to split the operands into
+polynomials of different degree. GMP currently splits the smaller operand
+onto 2 coefficients, i.e., a polynomial of degree 1, but the larger operand
+can be split into 2, 3, or 4 coefficients, i.e., a polynomial of degree 1 to
+3.
+
+@c FIXME: This is mighty ugly, but a cleaner @need triggers texinfo bugs that
+@c screws up layout here and there in the rest of the manual.
+@c @tex
+@c \goodbreak
+@c @end tex
+@node Division Algorithms, Greatest Common Divisor Algorithms, Multiplication Algorithms, Algorithms
+@section Division Algorithms
+@cindex Division algorithms
+
+@menu
+* Single Limb Division::
+* Basecase Division::
+* Divide and Conquer Division::
+* Block-Wise Barrett Division::
+* Exact Division::
+* Exact Remainder::
+* Small Quotient Division::
+@end menu
+
+
+@node Single Limb Division, Basecase Division, Division Algorithms, Division Algorithms
+@subsection Single Limb Division
+
+N@cross{}1 division is implemented using repeated 2@cross{}1 divisions from
+high to low, either with a hardware divide instruction or a multiplication by
+inverse, whichever is best on a given CPU.
+
+The multiply by inverse follows ``Improved division by invariant integers'' by
+M@"oller and Granlund (@pxref{References}) and is implemented as
+@code{udiv_qrnnd_preinv} in @file{gmp-impl.h}. The idea is to have a
+fixed-point approximation to @math{1/d} (see @code{invert_limb}) and then
+multiply by the high limb (plus one bit) of the dividend to get a quotient
+@math{q}. With @math{d} normalized (high bit set), @math{q} is no more than 1
+too small. Subtracting @m{qd,q*d} from the dividend gives a remainder, and
+reveals whether @math{q} or @math{q-1} is correct.
+
+The result is a division done with two multiplications and four or five
+arithmetic operations. On CPUs with low latency multipliers this can be much
+faster than a hardware divide, though the cost of calculating the inverse at
+the start may mean it's only better on inputs bigger than say 4 or 5 limbs.
+
+When a divisor must be normalized, either for the generic C
+@code{__udiv_qrnnd_c} or the multiply by inverse, the division performed is
+actually @m{a2^k,a*2^k} by @m{d2^k,d*2^k} where @math{a} is the dividend and
+@math{k} is the power necessary to have the high bit of @m{d2^k,d*2^k} set.
+The bit shifts for the dividend are usually accomplished ``on the fly''
+meaning by extracting the appropriate bits at each step. Done this way the
+quotient limbs come out aligned ready to store. When only the remainder is
+wanted, an alternative is to take the dividend limbs unshifted and calculate
+@m{r = a \bmod d2^k, r = a mod d*2^k} followed by an extra final step @m{r2^k
+\bmod d2^k, r*2^k mod d*2^k}. This can help on CPUs with poor bit shifts or
+few registers.
+
+The multiply by inverse can be done two limbs at a time. The calculation is
+basically the same, but the inverse is two limbs and the divisor treated as if
+padded with a low zero limb. This means more work, since the inverse will
+need a 2@cross{}2 multiply, but the four 1@cross{}1s to do that are
+independent and can therefore be done partly or wholly in parallel. Likewise
+for a 2@cross{}1 calculating @m{qd,q*d}. The net effect is to process two
+limbs with roughly the same two multiplies worth of latency that one limb at a
+time gives. This extends to 3 or 4 limbs at a time, though the extra work to
+apply the inverse will almost certainly soon reach the limits of multiplier
+throughput.
+
+A similar approach in reverse can be taken to process just half a limb at a
+time if the divisor is only a half limb. In this case the 1@cross{}1 multiply
+for the inverse effectively becomes two @m{{1\over2}\times1, (1/2)x1} for each
+limb, which can be a saving on CPUs with a fast half limb multiply, or in fact
+if the only multiply is a half limb, and especially if it's not pipelined.
+
+
+@node Basecase Division, Divide and Conquer Division, Single Limb Division, Division Algorithms
+@subsection Basecase Division
+
+Basecase N@cross{}M division is like long division done by hand, but in base
+@m{2\GMPraise{@code{mp\_bits\_per\_limb}}, 2^mp_bits_per_limb}. See Knuth
+section 4.3.1 algorithm D, and @file{mpn/generic/sb_divrem_mn.c}.
+
+Briefly stated, while the dividend remains larger than the divisor, a high
+quotient limb is formed and the N@cross{}1 product @m{qd,q*d} subtracted at
+the top end of the dividend. With a normalized divisor (most significant bit
+set), each quotient limb can be formed with a 2@cross{}1 division and a
+1@cross{}1 multiplication plus some subtractions. The 2@cross{}1 division is
+by the high limb of the divisor and is done either with a hardware divide or a
+multiply by inverse (the same as in @ref{Single Limb Division}) whichever is
+faster. Such a quotient is sometimes one too big, requiring an addback of the
+divisor, but that happens rarely.
+
+With Q=N@minus{}M being the number of quotient limbs, this is an
+@m{O(QM),O(Q*M)} algorithm and will run at a speed similar to a basecase
+Q@cross{}M multiplication, differing in fact only in the extra multiply and
+divide for each of the Q quotient limbs.
+
+
+@node Divide and Conquer Division, Block-Wise Barrett Division, Basecase Division, Division Algorithms
+@subsection Divide and Conquer Division
+
+For divisors larger than @code{DC_DIV_QR_THRESHOLD}, division is done by dividing.
+Or to be precise by a recursive divide and conquer algorithm based on work by
+Moenck and Borodin, Jebelean, and Burnikel and Ziegler (@pxref{References}).
+
+The algorithm consists essentially of recognising that a 2N@cross{}N division
+can be done with the basecase division algorithm (@pxref{Basecase Division}),
+but using N/2 limbs as a base, not just a single limb. This way the
+multiplications that arise are (N/2)@cross{}(N/2) and can take advantage of
+Karatsuba and higher multiplication algorithms (@pxref{Multiplication
+Algorithms}). The two ``digits'' of the quotient are formed by recursive
+N@cross{}(N/2) divisions.
+
+If the (N/2)@cross{}(N/2) multiplies are done with a basecase multiplication
+then the work is about the same as a basecase division, but with more function
+call overheads and with some subtractions separated from the multiplies.
+These overheads mean that it's only when N/2 is above
+@code{MUL_TOOM22_THRESHOLD} that divide and conquer is of use.
+
+@code{DC_DIV_QR_THRESHOLD} is based on the divisor size N, so it will be somewhere
+above twice @code{MUL_TOOM22_THRESHOLD}, but how much above depends on the
+CPU@. An optimized @code{mpn_mul_basecase} can lower @code{DC_DIV_QR_THRESHOLD} a
+little by offering a ready-made advantage over repeated @code{mpn_submul_1}
+calls.
+
+Divide and conquer is asymptotically @m{O(M(N)\log N),O(M(N)*log(N))} where
+@math{M(N)} is the time for an N@cross{}N multiplication done with FFTs. The
+actual time is a sum over multiplications of the recursed sizes, as can be
+seen near the end of section 2.2 of Burnikel and Ziegler. For example, within
+the Toom-3 range, divide and conquer is @m{2.63M(N), 2.63*M(N)}. With higher
+algorithms the @math{M(N)} term improves and the multiplier tends to @m{\log
+N, log(N)}. In practice, at moderate to large sizes, a 2N@cross{}N division
+is about 2 to 4 times slower than an N@cross{}N multiplication.
+
+
+@node Block-Wise Barrett Division, Exact Division, Divide and Conquer Division, Division Algorithms
+@subsection Block-Wise Barrett Division
+
+For the largest divisions, a block-wise Barrett division algorithm is used.
+Here, the divisor is inverted to a precision determined by the relative size of
+the dividend and divisor. Blocks of quotient limbs are then generated by
+multiplying blocks from the dividend by the inverse.
+
+Our block-wise algorithm computes a smaller inverse than in the plain Barrett
+algorithm. For a @math{2n/n} division, the inverse will be just @m{\lceil n/2
+\rceil, ceil(n/2)} limbs.
+
+
+@node Exact Division, Exact Remainder, Block-Wise Barrett Division, Division Algorithms
+@subsection Exact Division
+
+
+A so-called exact division is when the dividend is known to be an exact
+multiple of the divisor. Jebelean's exact division algorithm uses this
+knowledge to make some significant optimizations (@pxref{References}).
+
+The idea can be illustrated in decimal for example with 368154 divided by
+543. Because the low digit of the dividend is 4, the low digit of the
+quotient must be 8. This is arrived at from @m{4 \mathord{\times} 7 \bmod 10,
+4*7 mod 10}, using the fact 7 is the modular inverse of 3 (the low digit of
+the divisor), since @m{3 \mathord{\times} 7 \mathop{\equiv} 1 \bmod 10, 3*7
+@equiv{} 1 mod 10}. So @m{8\mathord{\times}543 = 4344,8*543=4344} can be
+subtracted from the dividend leaving 363810. Notice the low digit has become
+zero.
+
+The procedure is repeated at the second digit, with the next quotient digit 7
+(@m{1 \mathord{\times} 7 \bmod 10, 7 @equiv{} 1*7 mod 10}), subtracting
+@m{7\mathord{\times}543 = 3801,7*543=3801}, leaving 325800. And finally at
+the third digit with quotient digit 6 (@m{8 \mathord{\times} 7 \bmod 10, 8*7
+mod 10}), subtracting @m{6\mathord{\times}543 = 3258,6*543=3258} leaving 0.
+So the quotient is 678.
+
+Notice however that the multiplies and subtractions don't need to extend past
+the low three digits of the dividend, since that's enough to determine the
+three quotient digits. For the last quotient digit no subtraction is needed
+at all. On a 2N@cross{}N division like this one, only about half the work of
+a normal basecase division is necessary.
+
+For an N@cross{}M exact division producing Q=N@minus{}M quotient limbs, the
+saving over a normal basecase division is in two parts. Firstly, each of the
+Q quotient limbs needs only one multiply, not a 2@cross{}1 divide and
+multiply. Secondly, the crossproducts are reduced when @math{Q>M} to
+@m{QM-M(M+1)/2,Q*M-M*(M+1)/2}, or when @math{Q@le{}M} to @m{Q(Q-1)/2,
+Q*(Q-1)/2}. Notice the savings are complementary. If Q is big then many
+divisions are saved, or if Q is small then the crossproducts reduce to a small
+number.
+
+The modular inverse used is calculated efficiently by @code{binvert_limb} in
+@file{gmp-impl.h}. This does four multiplies for a 32-bit limb, or six for a
+64-bit limb. @file{tune/modlinv.c} has some alternate implementations that
+might suit processors better at bit twiddling than multiplying.
+
+The sub-quadratic exact division described by Jebelean in ``Exact Division
+with Karatsuba Complexity'' is not currently implemented. It uses a
+rearrangement similar to the divide and conquer for normal division
+(@pxref{Divide and Conquer Division}), but operating from low to high. A
+further possibility not currently implemented is ``Bidirectional Exact Integer
+Division'' by Krandick and Jebelean which forms quotient limbs from both the
+high and low ends of the dividend, and can halve once more the number of
+crossproducts needed in a 2N@cross{}N division.
+
+A special case exact division by 3 exists in @code{mpn_divexact_by3},
+supporting Toom-3 multiplication and @code{mpq} canonicalizations. It forms
+quotient digits with a multiply by the modular inverse of 3 (which is
+@code{0xAA..AAB}) and uses two comparisons to determine a borrow for the next
+limb. The multiplications don't need to be on the dependent chain, as long as
+the effect of the borrows is applied, which can help chips with pipelined
+multipliers.
+
+
+@node Exact Remainder, Small Quotient Division, Exact Division, Division Algorithms
+@subsection Exact Remainder
+@cindex Exact remainder
+
+If the exact division algorithm is done with a full subtraction at each stage
+and the dividend isn't a multiple of the divisor, then low zero limbs are
+produced but with a remainder in the high limbs. For dividend @math{a},
+divisor @math{d}, quotient @math{q}, and @m{b = 2
+\GMPraise{@code{mp\_bits\_per\_limb}}, b = 2^mp_bits_per_limb}, this remainder
+@math{r} is of the form
+@tex
+$$ a = qd + r b^n $$
+@end tex
+@ifnottex
+
+@example
+a = q*d + r*b^n
+@end example
+
+@end ifnottex
+@math{n} represents the number of zero limbs produced by the subtractions,
+that being the number of limbs produced for @math{q}. @math{r} will be in the
+range @math{0@le{}r<d} and can be viewed as a remainder, but one shifted up by
+a factor of @math{b^n}.
+
+Carrying out full subtractions at each stage means the same number of cross
+products must be done as a normal division, but there's still some single limb
+divisions saved. When @math{d} is a single limb some simplifications arise,
+providing good speedups on a number of processors.
+
+The functions @code{mpn_divexact_by3}, @code{mpn_modexact_1_odd} and the
+internal @code{mpn_redc_X} functions differ subtly in how they return @math{r},
+leading to some negations in the above formula, but all are essentially the
+same.
+
+@cindex Divisibility algorithm
+@cindex Congruence algorithm
+Clearly @math{r} is zero when @math{a} is a multiple of @math{d}, and this
+leads to divisibility or congruence tests which are potentially more efficient
+than a normal division.
+
+The factor of @math{b^n} on @math{r} can be ignored in a GCD when @math{d} is
+odd, hence the use of @code{mpn_modexact_1_odd} by @code{mpn_gcd_1} and
+@code{mpz_kronecker_ui} etc (@pxref{Greatest Common Divisor Algorithms}).
+
+Montgomery's REDC method for modular multiplications uses operands of the form
+of @m{xb^{-n}, x*b^-n} and @m{yb^{-n}, y*b^-n} and on calculating @m{(xb^{-n})
+(yb^{-n}), (x*b^-n)*(y*b^-n)} uses the factor of @math{b^n} in the exact
+remainder to reach a product in the same form @m{(xy)b^{-n}, (x*y)*b^-n}
+(@pxref{Modular Powering Algorithm}).
+
+Notice that @math{r} generally gives no useful information about the ordinary
+remainder @math{a @bmod d} since @math{b^n @bmod d} could be anything. If
+however @math{b^n @equiv{} 1 @bmod d}, then @math{r} is the negative of the
+ordinary remainder. This occurs whenever @math{d} is a factor of
+@math{b^n-1}, as for example with 3 in @code{mpn_divexact_by3}. For a 32 or
+64 bit limb other such factors include 5, 17 and 257, but no particular use
+has been found for this.
+
+
+@node Small Quotient Division, , Exact Remainder, Division Algorithms
+@subsection Small Quotient Division
+
+An N@cross{}M division where the number of quotient limbs Q=N@minus{}M is
+small can be optimized somewhat.
+
+An ordinary basecase division normalizes the divisor by shifting it to make
+the high bit set, shifting the dividend accordingly, and shifting the
+remainder back down at the end of the calculation. This is wasteful if only a
+few quotient limbs are to be formed. Instead a division of just the top
+@m{\rm2Q,2*Q} limbs of the dividend by the top Q limbs of the divisor can be
+used to form a trial quotient. This requires only those limbs normalized, not
+the whole of the divisor and dividend.
+
+A multiply and subtract then applies the trial quotient to the M@minus{}Q
+unused limbs of the divisor and N@minus{}Q dividend limbs (which includes Q
+limbs remaining from the trial quotient division). The starting trial
+quotient can be 1 or 2 too big, but all cases of 2 too big and most cases of 1
+too big are detected by first comparing the most significant limbs that will
+arise from the subtraction. An addback is done if the quotient still turns
+out to be 1 too big.
+
+This whole procedure is essentially the same as one step of the basecase
+algorithm done in a Q limb base, though with the trial quotient test done only
+with the high limbs, not an entire Q limb ``digit'' product. The correctness
+of this weaker test can be established by following the argument of Knuth
+section 4.3.1 exercise 20 but with the @m{v_2 \GMPhat q > b \GMPhat r
++ u_2, v2*q>b*r+u2} condition appropriately relaxed.
+
+
+@need 1000
+@node Greatest Common Divisor Algorithms, Powering Algorithms, Division Algorithms, Algorithms
+@section Greatest Common Divisor
+@cindex Greatest common divisor algorithms
+@cindex GCD algorithms
+
+@menu
+* Binary GCD::
+* Lehmer's Algorithm::
+* Subquadratic GCD::
+* Extended GCD::
+* Jacobi Symbol::
+@end menu
+
+
+@node Binary GCD, Lehmer's Algorithm, Greatest Common Divisor Algorithms, Greatest Common Divisor Algorithms
+@subsection Binary GCD
+
+At small sizes GMP uses an @math{O(N^2)} binary style GCD@. This is described
+in many textbooks, for example Knuth section 4.5.2 algorithm B@. It simply
+consists of successively reducing odd operands @math{a} and @math{b} using
+
+@quotation
+@math{a,b = @abs{}(a-b),@min{}(a,b)} @*
+strip factors of 2 from @math{a}
+@end quotation
+
+The Euclidean GCD algorithm, as per Knuth algorithms E and A, repeatedly
+computes the quotient @m{q = \lfloor a/b \rfloor, q = floor(a/b)} and replaces
+@math{a,b} by @math{v, u - q v}. The binary algorithm has so far been found to
+be faster than the Euclidean algorithm everywhere. One reason the binary
+method does well is that the implied quotient at each step is usually small,
+so often only one or two subtractions are needed to get the same effect as a
+division. Quotients 1, 2 and 3 for example occur 67.7% of the time, see Knuth
+section 4.5.3 Theorem E.
+
+When the implied quotient is large, meaning @math{b} is much smaller than
+@math{a}, then a division is worthwhile. This is the basis for the initial
+@math{a @bmod b} reductions in @code{mpn_gcd} and @code{mpn_gcd_1} (the latter
+for both N@cross{}1 and 1@cross{}1 cases). But after that initial reduction,
+big quotients occur too rarely to make it worth checking for them.
+
+@sp 1
+The final @math{1@cross{}1} GCD in @code{mpn_gcd_1} is done in the generic C
+code as described above. For two N-bit operands, the algorithm takes about
+0.68 iterations per bit. For optimum performance some attention needs to be
+paid to the way the factors of 2 are stripped from @math{a}.
+
+Firstly it may be noted that in twos complement the number of low zero bits on
+@math{a-b} is the same as @math{b-a}, so counting or testing can begin on
+@math{a-b} without waiting for @math{@abs{}(a-b)} to be determined.
+
+A loop stripping low zero bits tends not to branch predict well, since the
+condition is data dependent. But on average there's only a few low zeros, so
+an option is to strip one or two bits arithmetically then loop for more (as
+done for AMD K6). Or use a lookup table to get a count for several bits then
+loop for more (as done for AMD K7). An alternative approach is to keep just
+one of @math{a} or @math{b} odd and iterate
+
+@quotation
+@math{a,b = @abs{}(a-b), @min{}(a,b)} @*
+@math{a = a/2} if even @*
+@math{b = b/2} if even
+@end quotation
+
+This requires about 1.25 iterations per bit, but stripping of a single bit at
+each step avoids any branching. Repeating the bit strip reduces to about 0.9
+iterations per bit, which may be a worthwhile tradeoff.
+
+Generally with the above approaches a speed of perhaps 6 cycles per bit can be
+achieved, which is still not terribly fast with for instance a 64-bit GCD
+taking nearly 400 cycles. It's this sort of time which means it's not usually
+advantageous to combine a set of divisibility tests into a GCD.
+
+Currently, the binary algorithm is used for GCD only when @math{N < 3}.
+
+@node Lehmer's Algorithm, Subquadratic GCD, Binary GCD, Greatest Common Divisor Algorithms
+@comment node-name, next, previous, up
+@subsection Lehmer's algorithm
+
+Lehmer's improvement of the Euclidean algorithms is based on the observation
+that the initial part of the quotient sequence depends only on the most
+significant parts of the inputs. The variant of Lehmer's algorithm used in GMP
+splits off the most significant two limbs, as suggested, e.g., in ``A
+Double-Digit Lehmer-Euclid Algorithm'' by Jebelean (@pxref{References}). The
+quotients of two double-limb inputs are collected as a 2 by 2 matrix with
+single-limb elements. This is done by the function @code{mpn_hgcd2}. The
+resulting matrix is applied to the inputs using @code{mpn_mul_1} and
+@code{mpn_submul_1}. Each iteration usually reduces the inputs by almost one
+limb. In the rare case of a large quotient, no progress can be made by
+examining just the most significant two limbs, and the quotient is computed
+using plain division.
+
+The resulting algorithm is asymptotically @math{O(N^2)}, just as the Euclidean
+algorithm and the binary algorithm. The quadratic part of the work are
+the calls to @code{mpn_mul_1} and @code{mpn_submul_1}. For small sizes, the
+linear work is also significant. There are roughly @math{N} calls to the
+@code{mpn_hgcd2} function. This function uses a couple of important
+optimizations:
+
+@itemize
+@item
+It uses the same relaxed notion of correctness as @code{mpn_hgcd} (see next
+section). This means that when called with the most significant two limbs of
+two large numbers, the returned matrix does not always correspond exactly to
+the initial quotient sequence for the two large numbers; the final quotient
+may sometimes be one off.
+
+@item
+It takes advantage of the fact the quotients are usually small. The division
+operator is not used, since the corresponding assembler instruction is very
+slow on most architectures. (This code could probably be improved further, it
+uses many branches that are unfriendly to prediction).
+
+@item
+It switches from double-limb calculations to single-limb calculations half-way
+through, when the input numbers have been reduced in size from two limbs to
+one and a half.
+
+@end itemize
+
+@node Subquadratic GCD, Extended GCD, Lehmer's Algorithm, Greatest Common Divisor Algorithms
+@subsection Subquadratic GCD
+
+For inputs larger than @code{GCD_DC_THRESHOLD}, GCD is computed via the HGCD
+(Half GCD) function, as a generalization to Lehmer's algorithm.
+
+Let the inputs @math{a,b} be of size @math{N} limbs each. Put @m{S=\lfloor N/2
+\rfloor + 1, S = floor(N/2) + 1}. Then HGCD(a,b) returns a transformation
+matrix @math{T} with non-negative elements, and reduced numbers @math{(c;d) =
+T^{-1} (a;b)}. The reduced numbers @math{c,d} must be larger than @math{S}
+limbs, while their difference @math{abs(c-d)} must fit in @math{S} limbs. The
+matrix elements will also be of size roughly @math{N/2}.
+
+The HGCD base case uses Lehmer's algorithm, but with the above stop condition
+that returns reduced numbers and the corresponding transformation matrix
+half-way through. For inputs larger than @code{HGCD_THRESHOLD}, HGCD is
+computed recursively, using the divide and conquer algorithm in ``On
+Sch@"onhage's algorithm and subquadratic integer GCD computation'' by M@"oller
+(@pxref{References}). The recursive algorithm consists of these main
+steps.
+
+@itemize
+
+@item
+Call HGCD recursively, on the most significant @math{N/2} limbs. Apply the
+resulting matrix @math{T_1} to the full numbers, reducing them to a size just
+above @math{3N/2}.
+
+@item
+Perform a small number of division or subtraction steps to reduce the numbers
+to size below @math{3N/2}. This is essential mainly for the unlikely case of
+large quotients.
+
+@item
+Call HGCD recursively, on the most significant @math{N/2} limbs of the reduced
+numbers. Apply the resulting matrix @math{T_2} to the full numbers, reducing
+them to a size just above @math{N/2}.
+
+@item
+Compute @math{T = T_1 T_2}.
+
+@item
+Perform a small number of division and subtraction steps to satisfy the
+requirements, and return.
+@end itemize
+
+GCD is then implemented as a loop around HGCD, similarly to Lehmer's
+algorithm. Where Lehmer repeatedly chops off the top two limbs, calls
+@code{mpn_hgcd2}, and applies the resulting matrix to the full numbers, the
+subquadratic GCD chops off the most significant third of the limbs (the
+proportion is a tuning parameter, and @math{1/3} seems to be more efficient
+than, e.g, @math{1/2}), calls @code{mpn_hgcd}, and applies the resulting
+matrix. Once the input numbers are reduced to size below
+@code{GCD_DC_THRESHOLD}, Lehmer's algorithm is used for the rest of the work.
+
+The asymptotic running time of both HGCD and GCD is @m{O(M(N)\log N),O(M(N)*log(N))},
+where @math{M(N)} is the time for multiplying two @math{N}-limb numbers.
+
+@comment node-name, next, previous, up
+
+@node Extended GCD, Jacobi Symbol, Subquadratic GCD, Greatest Common Divisor Algorithms
+@subsection Extended GCD
+
+The extended GCD function, or GCDEXT, calculates @math{@gcd{}(a,b)} and also
+cofactors @math{x} and @math{y} satisfying @m{ax+by=\gcd(a@C{}b),
+a*x+b*y=gcd(a@C{}b)}. All the algorithms used for plain GCD are extended to
+handle this case. The binary algorithm is used only for single-limb GCDEXT.
+Lehmer's algorithm is used for sizes up to @code{GCDEXT_DC_THRESHOLD}. Above
+this threshold, GCDEXT is implemented as a loop around HGCD, but with more
+book-keeping to keep track of the cofactors. This gives the same asymptotic
+running time as for GCD and HGCD, @m{O(M(N)\log N),O(M(N)*log(N))}
+
+One difference to plain GCD is that while the inputs @math{a} and @math{b} are
+reduced as the algorithm proceeds, the cofactors @math{x} and @math{y} grow in
+size. This makes the tuning of the chopping-point more difficult. The current
+code chops off the most significant half of the inputs for the call to HGCD in
+the first iteration, and the most significant two thirds for the remaining
+calls. This strategy could surely be improved. Also the stop condition for the
+loop, where Lehmer's algorithm is invoked once the inputs are reduced below
+@code{GCDEXT_DC_THRESHOLD}, could maybe be improved by taking into account the
+current size of the cofactors.
+
+@node Jacobi Symbol, , Extended GCD, Greatest Common Divisor Algorithms
+@subsection Jacobi Symbol
+@cindex Jacobi symbol algorithm
+
+[This section is obsolete. The current Jacobi code actually uses a very
+efficient algorithm.]
+
+@code{mpz_jacobi} and @code{mpz_kronecker} are currently implemented with a
+simple binary algorithm similar to that described for the GCDs (@pxref{Binary
+GCD}). They're not very fast when both inputs are large. Lehmer's multi-step
+improvement or a binary based multi-step algorithm is likely to be better.
+
+When one operand fits a single limb, and that includes @code{mpz_kronecker_ui}
+and friends, an initial reduction is done with either @code{mpn_mod_1} or
+@code{mpn_modexact_1_odd}, followed by the binary algorithm on a single limb.
+The binary algorithm is well suited to a single limb, and the whole
+calculation in this case is quite efficient.
+
+In all the routines sign changes for the result are accumulated using some bit
+twiddling, avoiding table lookups or conditional jumps.
+
+
+@need 1000
+@node Powering Algorithms, Root Extraction Algorithms, Greatest Common Divisor Algorithms, Algorithms
+@section Powering Algorithms
+@cindex Powering algorithms
+
+@menu
+* Normal Powering Algorithm::
+* Modular Powering Algorithm::
+@end menu
+
+
+@node Normal Powering Algorithm, Modular Powering Algorithm, Powering Algorithms, Powering Algorithms
+@subsection Normal Powering
+
+Normal @code{mpz} or @code{mpf} powering uses a simple binary algorithm,
+successively squaring and then multiplying by the base when a 1 bit is seen in
+the exponent, as per Knuth section 4.6.3. The ``left to right''
+variant described there is used rather than algorithm A, since it's just as
+easy and can be done with somewhat less temporary memory.
+
+
+@node Modular Powering Algorithm, , Normal Powering Algorithm, Powering Algorithms
+@subsection Modular Powering
+
+Modular powering is implemented using a @math{2^k}-ary sliding window
+algorithm, as per ``Handbook of Applied Cryptography'' algorithm 14.85
+(@pxref{References}). @math{k} is chosen according to the size of the
+exponent. Larger exponents use larger values of @math{k}, the choice being
+made to minimize the average number of multiplications that must supplement
+the squaring.
+
+The modular multiplies and squarings use either a simple division or the REDC
+method by Montgomery (@pxref{References}). REDC is a little faster,
+essentially saving N single limb divisions in a fashion similar to an exact
+remainder (@pxref{Exact Remainder}).
+
+
+@node Root Extraction Algorithms, Radix Conversion Algorithms, Powering Algorithms, Algorithms
+@section Root Extraction Algorithms
+@cindex Root extraction algorithms
+
+@menu
+* Square Root Algorithm::
+* Nth Root Algorithm::
+* Perfect Square Algorithm::
+* Perfect Power Algorithm::
+@end menu
+
+
+@node Square Root Algorithm, Nth Root Algorithm, Root Extraction Algorithms, Root Extraction Algorithms
+@subsection Square Root
+@cindex Square root algorithm
+@cindex Karatsuba square root algorithm
+
+Square roots are taken using the ``Karatsuba Square Root'' algorithm by Paul
+Zimmermann (@pxref{References}).
+
+An input @math{n} is split into four parts of @math{k} bits each, so with
+@math{b=2^k} we have @m{n = a_3b^3 + a_2b^2 + a_1b + a_0, n = a3*b^3 + a2*b^2
++ a1*b + a0}. Part @ms{a,3} must be ``normalized'' so that either the high or
+second highest bit is set. In GMP, @math{k} is kept on a limb boundary and
+the input is left shifted (by an even number of bits) to normalize.
+
+The square root of the high two parts is taken, by recursive application of
+the algorithm (bottoming out in a one-limb Newton's method),
+@tex
+$$ s',r' = \mathop{\rm sqrtrem} \> (a_3b + a_2) $$
+@end tex
+@ifnottex
+
+@example
+s1,r1 = sqrtrem (a3*b + a2)
+@end example
+
+@end ifnottex
+This is an approximation to the desired root and is extended by a division to
+give @math{s},@math{r},
+@tex
+$$\eqalign{
+q,u &= \mathop{\rm divrem} \> (r'b + a_1, 2s') \cr
+s &= s'b + q \cr
+r &= ub + a_0 - q^2
+}$$
+@end tex
+@ifnottex
+
+@example
+q,u = divrem (r1*b + a1, 2*s1)
+s = s1*b + q
+r = u*b + a0 - q^2
+@end example
+
+@end ifnottex
+The normalization requirement on @ms{a,3} means at this point @math{s} is
+either correct or 1 too big. @math{r} is negative in the latter case, so
+@tex
+$$\eqalign{
+\mathop{\rm if} \; r &< 0 \; \mathop{\rm then} \cr
+r &\leftarrow r + 2s - 1 \cr
+s &\leftarrow s - 1
+}$$
+@end tex
+@ifnottex
+
+@example
+if r < 0 then
+ r = r + 2*s - 1
+ s = s - 1
+@end example
+
+@end ifnottex
+The algorithm is expressed in a divide and conquer form, but as noted in the
+paper it can also be viewed as a discrete variant of Newton's method, or as a
+variation on the schoolboy method (no longer taught) for square roots two
+digits at a time.
+
+If the remainder @math{r} is not required then usually only a few high limbs
+of @math{r} and @math{u} need to be calculated to determine whether an
+adjustment to @math{s} is required. This optimization is not currently
+implemented.
+
+In the Karatsuba multiplication range this algorithm is @m{O({3\over2}
+M(N/2)),O(1.5*M(N/2))}, where @math{M(n)} is the time to multiply two numbers
+of @math{n} limbs. In the FFT multiplication range this grows to a bound of
+@m{O(6 M(N/2)),O(6*M(N/2))}. In practice a factor of about 1.5 to 1.8 is
+found in the Karatsuba and Toom-3 ranges, growing to 2 or 3 in the FFT range.
+
+The algorithm does all its calculations in integers and the resulting
+@code{mpn_sqrtrem} is used for both @code{mpz_sqrt} and @code{mpf_sqrt}.
+The extended precision given by @code{mpf_sqrt_ui} is obtained by
+padding with zero limbs.
+
+
+@node Nth Root Algorithm, Perfect Square Algorithm, Square Root Algorithm, Root Extraction Algorithms
+@subsection Nth Root
+@cindex Root extraction algorithm
+@cindex Nth root algorithm
+
+Integer Nth roots are taken using Newton's method with the following
+iteration, where @math{A} is the input and @math{n} is the root to be taken.
+@tex
+$$a_{i+1} = {1\over n} \left({A \over a_i^{n-1}} + (n-1)a_i \right)$$
+@end tex
+@ifnottex
+
+@example
+ 1 A
+a[i+1] = - * ( --------- + (n-1)*a[i] )
+ n a[i]^(n-1)
+@end example
+
+@end ifnottex
+The initial approximation @m{a_1,a[1]} is generated bitwise by successively
+powering a trial root with or without new 1 bits, aiming to be just above the
+true root. The iteration converges quadratically when started from a good
+approximation. When @math{n} is large more initial bits are needed to get
+good convergence. The current implementation is not particularly well
+optimized.
+
+
+@node Perfect Square Algorithm, Perfect Power Algorithm, Nth Root Algorithm, Root Extraction Algorithms
+@subsection Perfect Square
+@cindex Perfect square algorithm
+
+A significant fraction of non-squares can be quickly identified by checking
+whether the input is a quadratic residue modulo small integers.
+
+@code{mpz_perfect_square_p} first tests the input mod 256, which means just
+examining the low byte. Only 44 different values occur for squares mod 256,
+so 82.8% of inputs can be immediately identified as non-squares.
+
+On a 32-bit system similar tests are done mod 9, 5, 7, 13 and 17, for a total
+99.25% of inputs identified as non-squares. On a 64-bit system 97 is tested
+too, for a total 99.62%.
+
+These moduli are chosen because they're factors of @math{2^@W{24}-1} (or
+@math{2^@W{48}-1} for 64-bits), and such a remainder can be quickly taken just
+using additions (see @code{mpn_mod_34lsub1}).
+
+When nails are in use moduli are instead selected by the @file{gen-psqr.c}
+program and applied with an @code{mpn_mod_1}. The same @math{2^@W{24}-1} or
+@math{2^@W{48}-1} could be done with nails using some extra bit shifts, but
+this is not currently implemented.
+
+In any case each modulus is applied to the @code{mpn_mod_34lsub1} or
+@code{mpn_mod_1} remainder and a table lookup identifies non-squares. By
+using a ``modexact'' style calculation, and suitably permuted tables, just one
+multiply each is required, see the code for details. Moduli are also combined
+to save operations, so long as the lookup tables don't become too big.
+@file{gen-psqr.c} does all the pre-calculations.
+
+A square root must still be taken for any value that passes these tests, to
+verify it's really a square and not one of the small fraction of non-squares
+that get through (i.e.@: a pseudo-square to all the tested bases).
+
+Clearly more residue tests could be done, @code{mpz_perfect_square_p} only
+uses a compact and efficient set. Big inputs would probably benefit from more
+residue testing, small inputs might be better off with less. The assumed
+distribution of squares versus non-squares in the input would affect such
+considerations.
+
+
+@node Perfect Power Algorithm, , Perfect Square Algorithm, Root Extraction Algorithms
+@subsection Perfect Power
+@cindex Perfect power algorithm
+
+Detecting perfect powers is required by some factorization algorithms.
+Currently @code{mpz_perfect_power_p} is implemented using repeated Nth root
+extractions, though naturally only prime roots need to be considered.
+(@xref{Nth Root Algorithm}.)
+
+If a prime divisor @math{p} with multiplicity @math{e} can be found, then only
+roots which are divisors of @math{e} need to be considered, much reducing the
+work necessary. To this end divisibility by a set of small primes is checked.
+
+
+@node Radix Conversion Algorithms, Other Algorithms, Root Extraction Algorithms, Algorithms
+@section Radix Conversion
+@cindex Radix conversion algorithms
+
+Radix conversions are less important than other algorithms. A program
+dominated by conversions should probably use a different data representation.
+
+@menu
+* Binary to Radix::
+* Radix to Binary::
+@end menu
+
+
+@node Binary to Radix, Radix to Binary, Radix Conversion Algorithms, Radix Conversion Algorithms
+@subsection Binary to Radix
+
+Conversions from binary to a power-of-2 radix use a simple and fast
+@math{O(N)} bit extraction algorithm.
+
+Conversions from binary to other radices use one of two algorithms. Sizes
+below @code{GET_STR_PRECOMPUTE_THRESHOLD} use a basic @math{O(N^2)} method.
+Repeated divisions by @math{b^n} are made, where @math{b} is the radix and
+@math{n} is the biggest power that fits in a limb. But instead of simply
+using the remainder @math{r} from such divisions, an extra divide step is done
+to give a fractional limb representing @math{r/b^n}. The digits of @math{r}
+can then be extracted using multiplications by @math{b} rather than divisions.
+Special case code is provided for decimal, allowing multiplications by 10 to
+optimize to shifts and adds.
+
+Above @code{GET_STR_PRECOMPUTE_THRESHOLD} a sub-quadratic algorithm is used.
+For an input @math{t}, powers @m{b^{n2^i},b^(n*2^i)} of the radix are
+calculated, until a power between @math{t} and @m{\sqrt{t},sqrt(t)} is
+reached. @math{t} is then divided by that largest power, giving a quotient
+which is the digits above that power, and a remainder which is those below.
+These two parts are in turn divided by the second highest power, and so on
+recursively. When a piece has been divided down to less than
+@code{GET_STR_DC_THRESHOLD} limbs, the basecase algorithm described above is
+used.
+
+The advantage of this algorithm is that big divisions can make use of the
+sub-quadratic divide and conquer division (@pxref{Divide and Conquer
+Division}), and big divisions tend to have less overheads than lots of
+separate single limb divisions anyway. But in any case the cost of
+calculating the powers @m{b^{n2^i},b^(n*2^i)} must first be overcome.
+
+@code{GET_STR_PRECOMPUTE_THRESHOLD} and @code{GET_STR_DC_THRESHOLD} represent
+the same basic thing, the point where it becomes worth doing a big division to
+cut the input in half. @code{GET_STR_PRECOMPUTE_THRESHOLD} includes the cost
+of calculating the radix power required, whereas @code{GET_STR_DC_THRESHOLD}
+assumes that's already available, which is the case when recursing.
+
+Since the base case produces digits from least to most significant but they
+want to be stored from most to least, it's necessary to calculate in advance
+how many digits there will be, or at least be sure not to underestimate that.
+For GMP the number of input bits is multiplied by @code{chars_per_bit_exactly}
+from @code{mp_bases}, rounding up. The result is either correct or one too
+big.
+
+Examining some of the high bits of the input could increase the chance of
+getting the exact number of digits, but an exact result every time would not
+be practical, since in general the difference between numbers 100@dots{} and
+99@dots{} is only in the last few bits and the work to identify 99@dots{}
+might well be almost as much as a full conversion.
+
+@code{mpf_get_str} doesn't currently use the algorithm described here, it
+multiplies or divides by a power of @math{b} to move the radix point to the
+just above the highest non-zero digit (or at worst one above that location),
+then multiplies by @math{b^n} to bring out digits. This is @math{O(N^2)} and
+is certainly not optimal.
+
+The @math{r/b^n} scheme described above for using multiplications to bring out
+digits might be useful for more than a single limb. Some brief experiments
+with it on the base case when recursing didn't give a noticeable improvement,
+but perhaps that was only due to the implementation. Something similar would
+work for the sub-quadratic divisions too, though there would be the cost of
+calculating a bigger radix power.
+
+Another possible improvement for the sub-quadratic part would be to arrange
+for radix powers that balanced the sizes of quotient and remainder produced,
+i.e.@: the highest power would be an @m{b^{nk},b^(n*k)} approximately equal to
+@m{\sqrt{t},sqrt(t)}, not restricted to a @math{2^i} factor. That ought to
+smooth out a graph of times against sizes, but may or may not be a net
+speedup.
+
+
+@node Radix to Binary, , Binary to Radix, Radix Conversion Algorithms
+@subsection Radix to Binary
+
+@strong{This section needs to be rewritten, it currently describes the
+algorithms used before GMP 4.3.}
+
+Conversions from a power-of-2 radix into binary use a simple and fast
+@math{O(N)} bitwise concatenation algorithm.
+
+Conversions from other radices use one of two algorithms. Sizes below
+@code{SET_STR_PRECOMPUTE_THRESHOLD} use a basic @math{O(N^2)} method. Groups
+of @math{n} digits are converted to limbs, where @math{n} is the biggest
+power of the base @math{b} which will fit in a limb, then those groups are
+accumulated into the result by multiplying by @math{b^n} and adding. This
+saves multi-precision operations, as per Knuth section 4.4 part E
+(@pxref{References}). Some special case code is provided for decimal, giving
+the compiler a chance to optimize multiplications by 10.
+
+Above @code{SET_STR_PRECOMPUTE_THRESHOLD} a sub-quadratic algorithm is used.
+First groups of @math{n} digits are converted into limbs. Then adjacent
+limbs are combined into limb pairs with @m{xb^n+y,x*b^n+y}, where @math{x}
+and @math{y} are the limbs. Adjacent limb pairs are combined into quads
+similarly with @m{xb^{2n}+y,x*b^(2n)+y}. This continues until a single block
+remains, that being the result.
+
+The advantage of this method is that the multiplications for each @math{x} are
+big blocks, allowing Karatsuba and higher algorithms to be used. But the cost
+of calculating the powers @m{b^{n2^i},b^(n*2^i)} must be overcome.
+@code{SET_STR_PRECOMPUTE_THRESHOLD} usually ends up quite big, around 5000 digits, and on
+some processors much bigger still.
+
+@code{SET_STR_PRECOMPUTE_THRESHOLD} is based on the input digits (and tuned
+for decimal), though it might be better based on a limb count, so as to be
+independent of the base. But that sort of count isn't used by the base case
+and so would need some sort of initial calculation or estimate.
+
+The main reason @code{SET_STR_PRECOMPUTE_THRESHOLD} is so much bigger than the
+corresponding @code{GET_STR_PRECOMPUTE_THRESHOLD} is that @code{mpn_mul_1} is
+much faster than @code{mpn_divrem_1} (often by a factor of 5, or more).
+
+
+@need 1000
+@node Other Algorithms, Assembly Coding, Radix Conversion Algorithms, Algorithms
+@section Other Algorithms
+
+@menu
+* Prime Testing Algorithm::
+* Factorial Algorithm::
+* Binomial Coefficients Algorithm::
+* Fibonacci Numbers Algorithm::
+* Lucas Numbers Algorithm::
+* Random Number Algorithms::
+@end menu
+
+
+@node Prime Testing Algorithm, Factorial Algorithm, Other Algorithms, Other Algorithms
+@subsection Prime Testing
+@cindex Prime testing algorithms
+
+The primality testing in @code{mpz_probab_prime_p} (@pxref{Number Theoretic
+Functions}) first does some trial division by small factors and then uses the
+Miller-Rabin probabilistic primality testing algorithm, as described in Knuth
+section 4.5.4 algorithm P (@pxref{References}).
+
+For an odd input @math{n}, and with @math{n = q@GMPmultiply{}2^k+1} where
+@math{q} is odd, this algorithm selects a random base @math{x} and tests
+whether @math{x^q @bmod{} n} is 1 or @math{-1}, or an @m{x^{q2^j} \bmod n,
+x^(q*2^j) mod n} is @math{1}, for @math{1@le{}j@le{}k}. If so then @math{n}
+is probably prime, if not then @math{n} is definitely composite.
+
+Any prime @math{n} will pass the test, but some composites do too. Such
+composites are known as strong pseudoprimes to base @math{x}. No @math{n} is
+a strong pseudoprime to more than @math{1/4} of all bases (see Knuth exercise
+22), hence with @math{x} chosen at random there's no more than a @math{1/4}
+chance a ``probable prime'' will in fact be composite.
+
+In fact strong pseudoprimes are quite rare, making the test much more
+powerful than this analysis would suggest, but @math{1/4} is all that's proven
+for an arbitrary @math{n}.
+
+
+@node Factorial Algorithm, Binomial Coefficients Algorithm, Prime Testing Algorithm, Other Algorithms
+@subsection Factorial
+@cindex Factorial algorithm
+
+Factorials are calculated by a combination of two algorithms. An idea is
+shared among them: to compute the odd part of the factorial; a final step
+takes account of the power of @math{2} term, by shifting.
+
+For small @math{n}, the odd factor of @math{n!} is computed with the simple
+observation that it is equal to the product of all positive odd numbers
+smaller than @math{n} times the odd factor of @m{\lfloor n/2\rfloor!, [n/2]!},
+where @m{\lfloor x\rfloor, [x]} is the integer part of @math{x}, and so on
+recursively. The procedure can be best illustrated with an example,
+
+@quotation
+@math{23! = (23.21.19.17.15.13.11.9.7.5.3)(11.9.7.5.3)(5.3)2^{19}}
+@end quotation
+
+Current code collects all the factors in a single list, with a loop and no
+recursion, and compute the product, with no special care for repeated chunks.
+
+When @math{n} is larger, computation pass trough prime sieving. An helper
+function is used, as suggested by Peter Luschny:
+@tex
+$$\mathop{\rm msf}(n) = {n!\over\lfloor n/2\rfloor!^2\cdot2^k} = \prod_{p=3}^{n}
+p^{\mathop{\rm L}(p,n)} $$
+@end tex
+@ifnottex
+
+@example
+ n
+ -----
+ n! | | L(p,n)
+msf(n) = -------------- = | | p
+ [n/2]!^2.2^k p=3
+@end example
+@end ifnottex
+
+Where @math{p} ranges on odd prime numbers. The exponent @math{k} is chosen to
+obtain an odd integer number: @math{k} is the number of 1 bits in the binary
+representation of @m{\lfloor n/2\rfloor, [n/2]}. The function L@math{(p,n)}
+can be defined as zero when @math{p} is composite, and, for any prime
+@math{p}, it is computed with:
+@tex
+$$\mathop{\rm L}(p,n) = \sum_{i>0}\left\lfloor{n\over p^i}\right\rfloor\bmod2
+\leq\log_p(n)$$
+@end tex
+@ifnottex
+
+@example
+ ---
+ \ n
+L(p,n) = / [---] mod 2 <= log (n) .
+ --- p^i p
+ i>0
+@end example
+@end ifnottex
+
+With this helper function, we are able to compute the odd part of @math{n!}
+using the recursion implied by @m{n!=\lfloor n/2\rfloor!^2\cdot\mathop{\rm
+msf}(n)\cdot2^k , n!=[n/2]!^2*msf(n)*2^k}. The recursion stops using the
+small-@math{n} algorithm on some @m{\lfloor n/2^i\rfloor, [n/2^i]}.
+
+Both the above algorithms use binary splitting to compute the product of many
+small factors. At first as many products as possible are accumulated in a
+single register, generating a list of factors that fit in a machine word. This
+list is then split into halves, and the product is computed recursively.
+
+Such splitting is more efficient than repeated N@cross{}1 multiplies since it
+forms big multiplies, allowing Karatsuba and higher algorithms to be used.
+And even below the Karatsuba threshold a big block of work can be more
+efficient for the basecase algorithm.
+
+
+@node Binomial Coefficients Algorithm, Fibonacci Numbers Algorithm, Factorial Algorithm, Other Algorithms
+@subsection Binomial Coefficients
+@cindex Binomial coefficient algorithm
+
+Binomial coefficients @m{\left({n}\atop{k}\right), C(n@C{}k)} are calculated
+by first arranging @math{k @le{} n/2} using @m{\left({n}\atop{k}\right) =
+\left({n}\atop{n-k}\right), C(n@C{}k) = C(n@C{}n-k)} if necessary, and then
+evaluating the following product simply from @math{i=2} to @math{i=k}.
+@tex
+$$ \left({n}\atop{k}\right) = (n-k+1) \prod_{i=2}^{k} {{n-k+i} \over i} $$
+@end tex
+@ifnottex
+
+@example
+ k (n-k+i)
+C(n,k) = (n-k+1) * prod -------
+ i=2 i
+@end example
+
+@end ifnottex
+It's easy to show that each denominator @math{i} will divide the product so
+far, so the exact division algorithm is used (@pxref{Exact Division}).
+
+The numerators @math{n-k+i} and denominators @math{i} are first accumulated
+into as many fit a limb, to save multi-precision operations, though for
+@code{mpz_bin_ui} this applies only to the divisors, since @math{n} is an
+@code{mpz_t} and @math{n-k+i} in general won't fit in a limb at all.
+
+
+@node Fibonacci Numbers Algorithm, Lucas Numbers Algorithm, Binomial Coefficients Algorithm, Other Algorithms
+@subsection Fibonacci Numbers
+@cindex Fibonacci number algorithm
+
+The Fibonacci functions @code{mpz_fib_ui} and @code{mpz_fib2_ui} are designed
+for calculating isolated @m{F_n,F[n]} or @m{F_n,F[n]},@m{F_{n-1},F[n-1]}
+values efficiently.
+
+For small @math{n}, a table of single limb values in @code{__gmp_fib_table} is
+used. On a 32-bit limb this goes up to @m{F_{47},F[47]}, or on a 64-bit limb
+up to @m{F_{93},F[93]}. For convenience the table starts at @m{F_{-1},F[-1]}.
+
+Beyond the table, values are generated with a binary powering algorithm,
+calculating a pair @m{F_n,F[n]} and @m{F_{n-1},F[n-1]} working from high to
+low across the bits of @math{n}. The formulas used are
+@tex
+$$\eqalign{
+ F_{2k+1} &= 4F_k^2 - F_{k-1}^2 + 2(-1)^k \cr
+ F_{2k-1} &= F_k^2 + F_{k-1}^2 \cr
+ F_{2k} &= F_{2k+1} - F_{2k-1}
+}$$
+@end tex
+@ifnottex
+
+@example
+F[2k+1] = 4*F[k]^2 - F[k-1]^2 + 2*(-1)^k
+F[2k-1] = F[k]^2 + F[k-1]^2
+
+F[2k] = F[2k+1] - F[2k-1]
+@end example
+
+@end ifnottex
+At each step, @math{k} is the high @math{b} bits of @math{n}. If the next bit
+of @math{n} is 0 then @m{F_{2k},F[2k]},@m{F_{2k-1},F[2k-1]} is used, or if
+it's a 1 then @m{F_{2k+1},F[2k+1]},@m{F_{2k},F[2k]} is used, and the process
+repeated until all bits of @math{n} are incorporated. Notice these formulas
+require just two squares per bit of @math{n}.
+
+It'd be possible to handle the first few @math{n} above the single limb table
+with simple additions, using the defining Fibonacci recurrence @m{F_{k+1} =
+F_k + F_{k-1}, F[k+1]=F[k]+F[k-1]}, but this is not done since it usually
+turns out to be faster for only about 10 or 20 values of @math{n}, and
+including a block of code for just those doesn't seem worthwhile. If they
+really mattered it'd be better to extend the data table.
+
+Using a table avoids lots of calculations on small numbers, and makes small
+@math{n} go fast. A bigger table would make more small @math{n} go fast, it's
+just a question of balancing size against desired speed. For GMP the code is
+kept compact, with the emphasis primarily on a good powering algorithm.
+
+@code{mpz_fib2_ui} returns both @m{F_n,F[n]} and @m{F_{n-1},F[n-1]}, but
+@code{mpz_fib_ui} is only interested in @m{F_n,F[n]}. In this case the last
+step of the algorithm can become one multiply instead of two squares. One of
+the following two formulas is used, according as @math{n} is odd or even.
+@tex
+$$\eqalign{
+ F_{2k} &= F_k (F_k + 2F_{k-1}) \cr
+ F_{2k+1} &= (2F_k + F_{k-1}) (2F_k - F_{k-1}) + 2(-1)^k
+}$$
+@end tex
+@ifnottex
+
+@example
+F[2k] = F[k]*(F[k]+2F[k-1])
+
+F[2k+1] = (2F[k]+F[k-1])*(2F[k]-F[k-1]) + 2*(-1)^k
+@end example
+
+@end ifnottex
+@m{F_{2k+1},F[2k+1]} here is the same as above, just rearranged to be a
+multiply. For interest, the @m{2(-1)^k, 2*(-1)^k} term both here and above
+can be applied just to the low limb of the calculation, without a carry or
+borrow into further limbs, which saves some code size. See comments with
+@code{mpz_fib_ui} and the internal @code{mpn_fib2_ui} for how this is done.
+
+
+@node Lucas Numbers Algorithm, Random Number Algorithms, Fibonacci Numbers Algorithm, Other Algorithms
+@subsection Lucas Numbers
+@cindex Lucas number algorithm
+
+@code{mpz_lucnum2_ui} derives a pair of Lucas numbers from a pair of Fibonacci
+numbers with the following simple formulas.
+@tex
+$$\eqalign{
+ L_k &= F_k + 2F_{k-1} \cr
+ L_{k-1} &= 2F_k - F_{k-1}
+}$$
+@end tex
+@ifnottex
+
+@example
+L[k] = F[k] + 2*F[k-1]
+L[k-1] = 2*F[k] - F[k-1]
+@end example
+
+@end ifnottex
+@code{mpz_lucnum_ui} is only interested in @m{L_n,L[n]}, and some work can be
+saved. Trailing zero bits on @math{n} can be handled with a single square
+each.
+@tex
+$$ L_{2k} = L_k^2 - 2(-1)^k $$
+@end tex
+@ifnottex
+
+@example
+L[2k] = L[k]^2 - 2*(-1)^k
+@end example
+
+@end ifnottex
+And the lowest 1 bit can be handled with one multiply of a pair of Fibonacci
+numbers, similar to what @code{mpz_fib_ui} does.
+@tex
+$$ L_{2k+1} = 5F_{k-1} (2F_k + F_{k-1}) - 4(-1)^k $$
+@end tex
+@ifnottex
+
+@example
+L[2k+1] = 5*F[k-1]*(2*F[k]+F[k-1]) - 4*(-1)^k
+@end example
+
+@end ifnottex
+
+
+@node Random Number Algorithms, , Lucas Numbers Algorithm, Other Algorithms
+@subsection Random Numbers
+@cindex Random number algorithms
+
+For the @code{urandomb} functions, random numbers are generated simply by
+concatenating bits produced by the generator. As long as the generator has
+good randomness properties this will produce well-distributed @math{N} bit
+numbers.
+
+For the @code{urandomm} functions, random numbers in a range @math{0@le{}R<N}
+are generated by taking values @math{R} of @m{\lceil \log_2 N \rceil,
+ceil(log2(N))} bits each until one satisfies @math{R<N}. This will normally
+require only one or two attempts, but the attempts are limited in case the
+generator is somehow degenerate and produces only 1 bits or similar.
+
+@cindex Mersenne twister algorithm
+The Mersenne Twister generator is by Matsumoto and Nishimura
+(@pxref{References}). It has a non-repeating period of @math{2^@W{19937}-1},
+which is a Mersenne prime, hence the name of the generator. The state is 624
+words of 32-bits each, which is iterated with one XOR and shift for each
+32-bit word generated, making the algorithm very fast. Randomness properties
+are also very good and this is the default algorithm used by GMP.
+
+@cindex Linear congruential algorithm
+Linear congruential generators are described in many text books, for instance
+Knuth volume 2 (@pxref{References}). With a modulus @math{M} and parameters
+@math{A} and @math{C}, an integer state @math{S} is iterated by the formula
+@math{S @leftarrow{} A@GMPmultiply{}S+C @bmod{} M}. At each step the new
+state is a linear function of the previous, mod @math{M}, hence the name of
+the generator.
+
+In GMP only moduli of the form @math{2^N} are supported, and the current
+implementation is not as well optimized as it could be. Overheads are
+significant when @math{N} is small, and when @math{N} is large clearly the
+multiply at each step will become slow. This is not a big concern, since the
+Mersenne Twister generator is better in every respect and is therefore
+recommended for all normal applications.
+
+For both generators the current state can be deduced by observing enough
+output and applying some linear algebra (over GF(2) in the case of the
+Mersenne Twister). This generally means raw output is unsuitable for
+cryptographic applications without further hashing or the like.
+
+
+@node Assembly Coding, , Other Algorithms, Algorithms
+@section Assembly Coding
+@cindex Assembly coding
+
+The assembly subroutines in GMP are the most significant source of speed at
+small to moderate sizes. At larger sizes algorithm selection becomes more
+important, but of course speedups in low level routines will still speed up
+everything proportionally.
+
+Carry handling and widening multiplies that are important for GMP can't be
+easily expressed in C@. GCC @code{asm} blocks help a lot and are provided in
+@file{longlong.h}, but hand coding low level routines invariably offers a
+speedup over generic C by a factor of anything from 2 to 10.
+
+@menu
+* Assembly Code Organisation::
+* Assembly Basics::
+* Assembly Carry Propagation::
+* Assembly Cache Handling::
+* Assembly Functional Units::
+* Assembly Floating Point::
+* Assembly SIMD Instructions::
+* Assembly Software Pipelining::
+* Assembly Loop Unrolling::
+* Assembly Writing Guide::
+@end menu
+
+
+@node Assembly Code Organisation, Assembly Basics, Assembly Coding, Assembly Coding
+@subsection Code Organisation
+@cindex Assembly code organisation
+@cindex Code organisation
+
+The various @file{mpn} subdirectories contain machine-dependent code, written
+in C or assembly. The @file{mpn/generic} subdirectory contains default code,
+used when there's no machine-specific version of a particular file.
+
+Each @file{mpn} subdirectory is for an ISA family. Generally 32-bit and
+64-bit variants in a family cannot share code and have separate directories.
+Within a family further subdirectories may exist for CPU variants.
+
+In each directory a @file{nails} subdirectory may exist, holding code with
+nails support for that CPU variant. A @code{NAILS_SUPPORT} directive in each
+file indicates the nails values the code handles. Nails code only exists
+where it's faster, or promises to be faster, than plain code. There's no
+effort put into nails if they're not going to enhance a given CPU.
+
+
+@node Assembly Basics, Assembly Carry Propagation, Assembly Code Organisation, Assembly Coding
+@subsection Assembly Basics
+
+@code{mpn_addmul_1} and @code{mpn_submul_1} are the most important routines
+for overall GMP performance. All multiplications and divisions come down to
+repeated calls to these. @code{mpn_add_n}, @code{mpn_sub_n},
+@code{mpn_lshift} and @code{mpn_rshift} are next most important.
+
+On some CPUs assembly versions of the internal functions
+@code{mpn_mul_basecase} and @code{mpn_sqr_basecase} give significant speedups,
+mainly through avoiding function call overheads. They can also potentially
+make better use of a wide superscalar processor, as can bigger primitives like
+@code{mpn_addmul_2} or @code{mpn_addmul_4}.
+
+The restrictions on overlaps between sources and destinations
+(@pxref{Low-level Functions}) are designed to facilitate a variety of
+implementations. For example, knowing @code{mpn_add_n} won't have partly
+overlapping sources and destination means reading can be done far ahead of
+writing on superscalar processors, and loops can be vectorized on a vector
+processor, depending on the carry handling.
+
+
+@node Assembly Carry Propagation, Assembly Cache Handling, Assembly Basics, Assembly Coding
+@subsection Carry Propagation
+@cindex Assembly carry propagation
+
+The problem that presents most challenges in GMP is propagating carries from
+one limb to the next. In functions like @code{mpn_addmul_1} and
+@code{mpn_add_n}, carries are the only dependencies between limb operations.
+
+On processors with carry flags, a straightforward CISC style @code{adc} is
+generally best. AMD K6 @code{mpn_addmul_1} however is an example of an
+unusual set of circumstances where a branch works out better.
+
+On RISC processors generally an add and compare for overflow is used. This
+sort of thing can be seen in @file{mpn/generic/aors_n.c}. Some carry
+propagation schemes require 4 instructions, meaning at least 4 cycles per
+limb, but other schemes may use just 1 or 2. On wide superscalar processors
+performance may be completely determined by the number of dependent
+instructions between carry-in and carry-out for each limb.
+
+On vector processors good use can be made of the fact that a carry bit only
+very rarely propagates more than one limb. When adding a single bit to a
+limb, there's only a carry out if that limb was @code{0xFF@dots{}FF} which on
+random data will be only 1 in @m{2\GMPraise{@code{mp\_bits\_per\_limb}},
+2^mp_bits_per_limb}. @file{mpn/cray/add_n.c} is an example of this, it adds
+all limbs in parallel, adds one set of carry bits in parallel and then only
+rarely needs to fall through to a loop propagating further carries.
+
+On the x86s, GCC (as of version 2.95.2) doesn't generate particularly good code
+for the RISC style idioms that are necessary to handle carry bits in
+C@. Often conditional jumps are generated where @code{adc} or @code{sbb} forms
+would be better. And so unfortunately almost any loop involving carry bits
+needs to be coded in assembly for best results.
+
+
+@node Assembly Cache Handling, Assembly Functional Units, Assembly Carry Propagation, Assembly Coding
+@subsection Cache Handling
+@cindex Assembly cache handling
+
+GMP aims to perform well both on operands that fit entirely in L1 cache and
+those which don't.
+
+Basic routines like @code{mpn_add_n} or @code{mpn_lshift} are often used on
+large operands, so L2 and main memory performance is important for them.
+@code{mpn_mul_1} and @code{mpn_addmul_1} are mostly used for multiply and
+square basecases, so L1 performance matters most for them, unless assembly
+versions of @code{mpn_mul_basecase} and @code{mpn_sqr_basecase} exist, in
+which case the remaining uses are mostly for larger operands.
+
+For L2 or main memory operands, memory access times will almost certainly be
+more than the calculation time. The aim therefore is to maximize memory
+throughput, by starting a load of the next cache line while processing the
+contents of the previous one. Clearly this is only possible if the chip has a
+lock-up free cache or some sort of prefetch instruction. Most current chips
+have both these features.
+
+Prefetching sources combines well with loop unrolling, since a prefetch can be
+initiated once per unrolled loop (or more than once if the loop covers more
+than one cache line).
+
+On CPUs without write-allocate caches, prefetching destinations will ensure
+individual stores don't go further down the cache hierarchy, limiting
+bandwidth. Of course for calculations which are slow anyway, like
+@code{mpn_divrem_1}, write-throughs might be fine.
+
+The distance ahead to prefetch will be determined by memory latency versus
+throughput. The aim of course is to have data arriving continuously, at peak
+throughput. Some CPUs have limits on the number of fetches or prefetches in
+progress.
+
+If a special prefetch instruction doesn't exist then a plain load can be used,
+but in that case care must be taken not to attempt to read past the end of an
+operand, since that might produce a segmentation violation.
+
+Some CPUs or systems have hardware that detects sequential memory accesses and
+initiates suitable cache movements automatically, making life easy.
+
+
+@node Assembly Functional Units, Assembly Floating Point, Assembly Cache Handling, Assembly Coding
+@subsection Functional Units
+
+When choosing an approach for an assembly loop, consideration is given to
+what operations can execute simultaneously and what throughput can thereby be
+achieved. In some cases an algorithm can be tweaked to accommodate available
+resources.
+
+Loop control will generally require a counter and pointer updates, costing as
+much as 5 instructions, plus any delays a branch introduces. CPU addressing
+modes might reduce pointer updates, perhaps by allowing just one updating
+pointer and others expressed as offsets from it, or on CISC chips with all
+addressing done with the loop counter as a scaled index.
+
+The final loop control cost can be amortised by processing several limbs in
+each iteration (@pxref{Assembly Loop Unrolling}). This at least ensures loop
+control isn't a big fraction the work done.
+
+Memory throughput is always a limit. If perhaps only one load or one store
+can be done per cycle then 3 cycles/limb will the top speed for ``binary''
+operations like @code{mpn_add_n}, and any code achieving that is optimal.
+
+Integer resources can be freed up by having the loop counter in a float
+register, or by pressing the float units into use for some multiplying,
+perhaps doing every second limb on the float side (@pxref{Assembly Floating
+Point}).
+
+Float resources can be freed up by doing carry propagation on the integer
+side, or even by doing integer to float conversions in integers using bit
+twiddling.
+
+
+@node Assembly Floating Point, Assembly SIMD Instructions, Assembly Functional Units, Assembly Coding
+@subsection Floating Point
+@cindex Assembly floating Point
+
+Floating point arithmetic is used in GMP for multiplications on CPUs with poor
+integer multipliers. It's mostly useful for @code{mpn_mul_1},
+@code{mpn_addmul_1} and @code{mpn_submul_1} on 64-bit machines, and
+@code{mpn_mul_basecase} on both 32-bit and 64-bit machines.
+
+With IEEE 53-bit double precision floats, integer multiplications producing up
+to 53 bits will give exact results. Breaking a 64@cross{}64 multiplication
+into eight 16@cross{}@math{32@rightarrow{}48} bit pieces is convenient. With
+some care though six 21@cross{}@math{32@rightarrow{}53} bit products can be
+used, if one of the lower two 21-bit pieces also uses the sign bit.
+
+For the @code{mpn_mul_1} family of functions on a 64-bit machine, the
+invariant single limb is split at the start, into 3 or 4 pieces. Inside the
+loop, the bignum operand is split into 32-bit pieces. Fast conversion of
+these unsigned 32-bit pieces to floating point is highly machine-dependent.
+In some cases, reading the data into the integer unit, zero-extending to
+64-bits, then transferring to the floating point unit back via memory is the
+only option.
+
+Converting partial products back to 64-bit limbs is usually best done as a
+signed conversion. Since all values are smaller than @m{2^{53},2^53}, signed
+and unsigned are the same, but most processors lack unsigned conversions.
+
+@sp 2
+
+Here is a diagram showing 16@cross{}32 bit products for an @code{mpn_mul_1} or
+@code{mpn_addmul_1} with a 64-bit limb. The single limb operand V is split
+into four 16-bit parts. The multi-limb operand U is split in the loop into
+two 32-bit parts.
+
+@tex
+\global\newdimen\GMPbits \global\GMPbits=0.18em
+\def\GMPbox#1#2#3{%
+ \hbox{%
+ \hbox to 128\GMPbits{\hfil
+ \vbox{%
+ \hrule
+ \hbox to 48\GMPbits {\GMPvrule \hfil$#2$\hfil \vrule}%
+ \hrule}%
+ \hskip #1\GMPbits}%
+ \raise \GMPboxdepth \hbox{\hskip 2em #3}}}
+%
+\GMPdisplay{%
+ \vbox{%
+ \hbox{%
+ \hbox to 128\GMPbits {\hfil
+ \vbox{%
+ \hrule
+ \hbox to 64\GMPbits{%
+ \GMPvrule \hfil$v48$\hfil
+ \vrule \hfil$v32$\hfil
+ \vrule \hfil$v16$\hfil
+ \vrule \hfil$v00$\hfil
+ \vrule}
+ \hrule}}%
+ \raise \GMPboxdepth \hbox{\hskip 2em V Operand}}
+ \vskip 0.5ex
+ \hbox{%
+ \hbox to 128\GMPbits {\hfil
+ \raise \GMPboxdepth \hbox{$\times$\hskip 1.5em}%
+ \vbox{%
+ \hrule
+ \hbox to 64\GMPbits {%
+ \GMPvrule \hfil$u32$\hfil
+ \vrule \hfil$u00$\hfil
+ \vrule}%
+ \hrule}}%
+ \raise \GMPboxdepth \hbox{\hskip 2em U Operand (one limb)}}%
+ \vskip 0.5ex
+ \hbox{\vbox to 2ex{\hrule width 128\GMPbits}}%
+ \GMPbox{0}{u00 \times v00}{$p00$\hskip 1.5em 48-bit products}%
+ \vskip 0.5ex
+ \GMPbox{16}{u00 \times v16}{$p16$}
+ \vskip 0.5ex
+ \GMPbox{32}{u00 \times v32}{$p32$}
+ \vskip 0.5ex
+ \GMPbox{48}{u00 \times v48}{$p48$}
+ \vskip 0.5ex
+ \GMPbox{32}{u32 \times v00}{$r32$}
+ \vskip 0.5ex
+ \GMPbox{48}{u32 \times v16}{$r48$}
+ \vskip 0.5ex
+ \GMPbox{64}{u32 \times v32}{$r64$}
+ \vskip 0.5ex
+ \GMPbox{80}{u32 \times v48}{$r80$}
+}}
+@end tex
+@ifnottex
+@example
+@group
+ +---+---+---+---+
+ |v48|v32|v16|v00| V operand
+ +---+---+---+---+
+
+ +-------+---+---+
+ x | u32 | u00 | U operand (one limb)
+ +---------------+
+
+---------------------------------
+
+ +-----------+
+ | u00 x v00 | p00 48-bit products
+ +-----------+
+ +-----------+
+ | u00 x v16 | p16
+ +-----------+
+ +-----------+
+ | u00 x v32 | p32
+ +-----------+
+ +-----------+
+ | u00 x v48 | p48
+ +-----------+
+ +-----------+
+ | u32 x v00 | r32
+ +-----------+
+ +-----------+
+ | u32 x v16 | r48
+ +-----------+
+ +-----------+
+ | u32 x v32 | r64
+ +-----------+
++-----------+
+| u32 x v48 | r80
++-----------+
+@end group
+@end example
+@end ifnottex
+
+@math{p32} and @math{r32} can be summed using floating-point addition, and
+likewise @math{p48} and @math{r48}. @math{p00} and @math{p16} can be summed
+with @math{r64} and @math{r80} from the previous iteration.
+
+For each loop then, four 49-bit quantities are transferred to the integer unit,
+aligned as follows,
+
+@tex
+% GMPbox here should be 49 bits wide, but use 51 to better show p16+r80'
+% crossing into the upper 64 bits.
+\def\GMPbox#1#2#3{%
+ \hbox{%
+ \hbox to 128\GMPbits {%
+ \hfil
+ \vbox{%
+ \hrule
+ \hbox to 51\GMPbits {\GMPvrule \hfil$#2$\hfil \vrule}%
+ \hrule}%
+ \hskip #1\GMPbits}%
+ \raise \GMPboxdepth \hbox{\hskip 1.5em $#3$\hfil}%
+}}
+\newbox\b \setbox\b\hbox{64 bits}%
+\newdimen\bw \bw=\wd\b \advance\bw by 2em
+\newdimen\x \x=128\GMPbits
+\advance\x by -2\bw
+\divide\x by4
+\GMPdisplay{%
+ \vbox{%
+ \hbox to 128\GMPbits {%
+ \GMPvrule
+ \raise 0.5ex \vbox{\hrule \hbox to \x {}}%
+ \hfil 64 bits\hfil
+ \raise 0.5ex \vbox{\hrule \hbox to \x {}}%
+ \vrule
+ \raise 0.5ex \vbox{\hrule \hbox to \x {}}%
+ \hfil 64 bits\hfil
+ \raise 0.5ex \vbox{\hrule \hbox to \x {}}%
+ \vrule}%
+ \vskip 0.7ex
+ \GMPbox{0}{p00+r64'}{i00}
+ \vskip 0.5ex
+ \GMPbox{16}{p16+r80'}{i16}
+ \vskip 0.5ex
+ \GMPbox{32}{p32+r32}{i32}
+ \vskip 0.5ex
+ \GMPbox{48}{p48+r48}{i48}
+}}
+@end tex
+@ifnottex
+@example
+@group
+|-----64bits----|-----64bits----|
+ +------------+
+ | p00 + r64' | i00
+ +------------+
+ +------------+
+ | p16 + r80' | i16
+ +------------+
+ +------------+
+ | p32 + r32 | i32
+ +------------+
+ +------------+
+ | p48 + r48 | i48
+ +------------+
+@end group
+@end example
+@end ifnottex
+
+The challenge then is to sum these efficiently and add in a carry limb,
+generating a low 64-bit result limb and a high 33-bit carry limb (@math{i48}
+extends 33 bits into the high half).
+
+
+@node Assembly SIMD Instructions, Assembly Software Pipelining, Assembly Floating Point, Assembly Coding
+@subsection SIMD Instructions
+@cindex Assembly SIMD
+
+The single-instruction multiple-data support in current microprocessors is
+aimed at signal processing algorithms where each data point can be treated
+more or less independently. There's generally not much support for
+propagating the sort of carries that arise in GMP.
+
+SIMD multiplications of say four 16@cross{}16 bit multiplies only do as much
+work as one 32@cross{}32 from GMP's point of view, and need some shifts and
+adds besides. But of course if say the SIMD form is fully pipelined and uses
+less instruction decoding then it may still be worthwhile.
+
+On the x86 chips, MMX has so far found a use in @code{mpn_rshift} and
+@code{mpn_lshift}, and is used in a special case for 16-bit multipliers in the
+P55 @code{mpn_mul_1}. SSE2 is used for Pentium 4 @code{mpn_mul_1},
+@code{mpn_addmul_1}, and @code{mpn_submul_1}.
+
+
+@node Assembly Software Pipelining, Assembly Loop Unrolling, Assembly SIMD Instructions, Assembly Coding
+@subsection Software Pipelining
+@cindex Assembly software pipelining
+
+Software pipelining consists of scheduling instructions around the branch
+point in a loop. For example a loop might issue a load not for use in the
+present iteration but the next, thereby allowing extra cycles for the data to
+arrive from memory.
+
+Naturally this is wanted only when doing things like loads or multiplies that
+take several cycles to complete, and only where a CPU has multiple functional
+units so that other work can be done in the meantime.
+
+A pipeline with several stages will have a data value in progress at each
+stage and each loop iteration moves them along one stage. This is like
+juggling.
+
+If the latency of some instruction is greater than the loop time then it will
+be necessary to unroll, so one register has a result ready to use while
+another (or multiple others) are still in progress. (@pxref{Assembly Loop
+Unrolling}).
+
+
+@node Assembly Loop Unrolling, Assembly Writing Guide, Assembly Software Pipelining, Assembly Coding
+@subsection Loop Unrolling
+@cindex Assembly loop unrolling
+
+Loop unrolling consists of replicating code so that several limbs are
+processed in each loop. At a minimum this reduces loop overheads by a
+corresponding factor, but it can also allow better register usage, for example
+alternately using one register combination and then another. Judicious use of
+@command{m4} macros can help avoid lots of duplication in the source code.
+
+Any amount of unrolling can be handled with a loop counter that's decremented
+by @math{N} each time, stopping when the remaining count is less than the
+further @math{N} the loop will process. Or by subtracting @math{N} at the
+start, the termination condition becomes when the counter @math{C} is less
+than 0 (and the count of remaining limbs is @math{C+N}).
+
+Alternately for a power of 2 unroll the loop count and remainder can be
+established with a shift and mask. This is convenient if also making a
+computed jump into the middle of a large loop.
+
+The limbs not a multiple of the unrolling can be handled in various ways, for
+example
+
+@itemize @bullet
+@item
+A simple loop at the end (or the start) to process the excess. Care will be
+wanted that it isn't too much slower than the unrolled part.
+
+@item
+A set of binary tests, for example after an 8-limb unrolling, test for 4 more
+limbs to process, then a further 2 more or not, and finally 1 more or not.
+This will probably take more code space than a simple loop.
+
+@item
+A @code{switch} statement, providing separate code for each possible excess,
+for example an 8-limb unrolling would have separate code for 0 remaining, 1
+remaining, etc, up to 7 remaining. This might take a lot of code, but may be
+the best way to optimize all cases in combination with a deep pipelined loop.
+
+@item
+A computed jump into the middle of the loop, thus making the first iteration
+handle the excess. This should make times smoothly increase with size, which
+is attractive, but setups for the jump and adjustments for pointers can be
+tricky and could become quite difficult in combination with deep pipelining.
+@end itemize
+
+
+@node Assembly Writing Guide, , Assembly Loop Unrolling, Assembly Coding
+@subsection Writing Guide
+@cindex Assembly writing guide
+
+This is a guide to writing software pipelined loops for processing limb
+vectors in assembly.
+
+First determine the algorithm and which instructions are needed. Code it
+without unrolling or scheduling, to make sure it works. On a 3-operand CPU
+try to write each new value to a new register, this will greatly simplify later
+steps.
+
+Then note for each instruction the functional unit and/or issue port
+requirements. If an instruction can use either of two units, like U0 or U1
+then make a category ``U0/U1''. Count the total using each unit (or combined
+unit), and count all instructions.
+
+Figure out from those counts the best possible loop time. The goal will be to
+find a perfect schedule where instruction latencies are completely hidden.
+The total instruction count might be the limiting factor, or perhaps a
+particular functional unit. It might be possible to tweak the instructions to
+help the limiting factor.
+
+Suppose the loop time is @math{N}, then make @math{N} issue buckets, with the
+final loop branch at the end of the last. Now fill the buckets with dummy
+instructions using the functional units desired. Run this to make sure the
+intended speed is reached.
+
+Now replace the dummy instructions with the real instructions from the slow
+but correct loop you started with. The first will typically be a load
+instruction. Then the instruction using that value is placed in a bucket an
+appropriate distance down. Run the loop again, to check it still runs at
+target speed.
+
+Keep placing instructions, frequently measuring the loop. After a few you
+will need to wrap around from the last bucket back to the top of the loop. If
+you used the new-register for new-value strategy above then there will be no
+register conflicts. If not then take care not to clobber something already in
+use. Changing registers at this time is very error prone.
+
+The loop will overlap two or more of the original loop iterations, and the
+computation of one vector element result will be started in one iteration of
+the new loop, and completed one or several iterations later.
+
+The final step is to create feed-in and wind-down code for the loop. A good
+way to do this is to make a copy (or copies) of the loop at the start and
+delete those instructions which don't have valid antecedents, and at the end
+replicate and delete those whose results are unwanted (including any further
+loads).
+
+The loop will have a minimum number of limbs loaded and processed, so the
+feed-in code must test if the request size is smaller and skip either to a
+suitable part of the wind-down or to special code for small sizes.
+
+
+@node Internals, Contributors, Algorithms, Top
+@chapter Internals
+@cindex Internals
+
+@strong{This chapter is provided only for informational purposes and the
+various internals described here may change in future GMP releases.
+Applications expecting to be compatible with future releases should use only
+the documented interfaces described in previous chapters.}
+
+@menu
+* Integer Internals::
+* Rational Internals::
+* Float Internals::
+* Raw Output Internals::
+* C++ Interface Internals::
+@end menu
+
+@node Integer Internals, Rational Internals, Internals, Internals
+@section Integer Internals
+@cindex Integer internals
+
+@code{mpz_t} variables represent integers using sign and magnitude, in space
+dynamically allocated and reallocated. The fields are as follows.
+
+@table @asis
+@item @code{_mp_size}
+The number of limbs, or the negative of that when representing a negative
+integer. Zero is represented by @code{_mp_size} set to zero, in which case
+the @code{_mp_d} data is unused.
+
+@item @code{_mp_d}
+A pointer to an array of limbs which is the magnitude. These are stored
+``little endian'' as per the @code{mpn} functions, so @code{_mp_d[0]} is the
+least significant limb and @code{_mp_d[ABS(_mp_size)-1]} is the most
+significant. Whenever @code{_mp_size} is non-zero, the most significant limb
+is non-zero.
+
+Currently there's always at least one limb allocated, so for instance
+@code{mpz_set_ui} never needs to reallocate, and @code{mpz_get_ui} can fetch
+@code{_mp_d[0]} unconditionally (though its value is then only wanted if
+@code{_mp_size} is non-zero).
+
+@item @code{_mp_alloc}
+@code{_mp_alloc} is the number of limbs currently allocated at @code{_mp_d},
+and naturally @code{_mp_alloc >= ABS(_mp_size)}. When an @code{mpz} routine
+is about to (or might be about to) increase @code{_mp_size}, it checks
+@code{_mp_alloc} to see whether there's enough space, and reallocates if not.
+@code{MPZ_REALLOC} is generally used for this.
+@end table
+
+The various bitwise logical functions like @code{mpz_and} behave as if
+negative values were twos complement. But sign and magnitude is always used
+internally, and necessary adjustments are made during the calculations.
+Sometimes this isn't pretty, but sign and magnitude are best for other
+routines.
+
+Some internal temporary variables are setup with @code{MPZ_TMP_INIT} and these
+have @code{_mp_d} space obtained from @code{TMP_ALLOC} rather than the memory
+allocation functions. Care is taken to ensure that these are big enough that
+no reallocation is necessary (since it would have unpredictable consequences).
+
+@code{_mp_size} and @code{_mp_alloc} are @code{int}, although @code{mp_size_t}
+is usually a @code{long}. This is done to make the fields just 32 bits on
+some 64 bits systems, thereby saving a few bytes of data space but still
+providing plenty of range.
+
+
+@node Rational Internals, Float Internals, Integer Internals, Internals
+@section Rational Internals
+@cindex Rational internals
+
+@code{mpq_t} variables represent rationals using an @code{mpz_t} numerator and
+denominator (@pxref{Integer Internals}).
+
+The canonical form adopted is denominator positive (and non-zero), no common
+factors between numerator and denominator, and zero uniquely represented as
+0/1.
+
+It's believed that casting out common factors at each stage of a calculation
+is best in general. A GCD is an @math{O(N^2)} operation so it's better to do
+a few small ones immediately than to delay and have to do a big one later.
+Knowing the numerator and denominator have no common factors can be used for
+example in @code{mpq_mul} to make only two cross GCDs necessary, not four.
+
+This general approach to common factors is badly sub-optimal in the presence
+of simple factorizations or little prospect for cancellation, but GMP has no
+way to know when this will occur. As per @ref{Efficiency}, that's left to
+applications. The @code{mpq_t} framework might still suit, with
+@code{mpq_numref} and @code{mpq_denref} for direct access to the numerator and
+denominator, or of course @code{mpz_t} variables can be used directly.
+
+
+@node Float Internals, Raw Output Internals, Rational Internals, Internals
+@section Float Internals
+@cindex Float internals
+
+Efficient calculation is the primary aim of GMP floats and the use of whole
+limbs and simple rounding facilitates this.
+
+@code{mpf_t} floats have a variable precision mantissa and a single machine
+word signed exponent. The mantissa is represented using sign and magnitude.
+
+@c FIXME: The arrow heads don't join to the lines exactly.
+@tex
+\global\newdimen\GMPboxwidth \GMPboxwidth=5em
+\global\newdimen\GMPboxheight \GMPboxheight=3ex
+\def\centreline{\hbox{\raise 0.8ex \vbox{\hrule \hbox{\hfil}}}}
+\GMPdisplay{%
+\vbox{%
+ \hbox to 5\GMPboxwidth {most significant limb \hfil least significant limb}
+ \vskip 0.7ex
+ \def\GMPcentreline#1{\hbox{\raise 0.5 ex \vbox{\hrule \hbox to #1 {}}}}
+ \hbox {
+ \hbox to 3\GMPboxwidth {%
+ \setbox 0 = \hbox{@code{\_mp\_exp}}%
+ \dimen0=3\GMPboxwidth
+ \advance\dimen0 by -\wd0
+ \divide\dimen0 by 2
+ \advance\dimen0 by -1em
+ \setbox1 = \hbox{$\rightarrow$}%
+ \dimen1=\dimen0
+ \advance\dimen1 by -\wd1
+ \GMPcentreline{\dimen0}%
+ \hfil
+ \box0%
+ \hfil
+ \GMPcentreline{\dimen1{}}%
+ \box1}
+ \hbox to 2\GMPboxwidth {\hfil @code{\_mp\_d}}}
+ \vskip 0.5ex
+ \vbox {%
+ \hrule
+ \hbox{%
+ \vrule height 2ex depth 1ex
+ \hbox to \GMPboxwidth {}%
+ \vrule
+ \hbox to \GMPboxwidth {}%
+ \vrule
+ \hbox to \GMPboxwidth {}%
+ \vrule
+ \hbox to \GMPboxwidth {}%
+ \vrule
+ \hbox to \GMPboxwidth {}%
+ \vrule}
+ \hrule
+ }
+ \hbox {%
+ \hbox to 0.8 pt {}
+ \hbox to 3\GMPboxwidth {%
+ \hfil $\cdot$} \hbox {$\leftarrow$ radix point\hfil}}
+ \hbox to 5\GMPboxwidth{%
+ \setbox 0 = \hbox{@code{\_mp\_size}}%
+ \dimen0 = 5\GMPboxwidth
+ \advance\dimen0 by -\wd0
+ \divide\dimen0 by 2
+ \advance\dimen0 by -1em
+ \dimen1 = \dimen0
+ \setbox1 = \hbox{$\leftarrow$}%
+ \setbox2 = \hbox{$\rightarrow$}%
+ \advance\dimen0 by -\wd1
+ \advance\dimen1 by -\wd2
+ \hbox to 0.3 em {}%
+ \box1
+ \GMPcentreline{\dimen0}%
+ \hfil
+ \box0
+ \hfil
+ \GMPcentreline{\dimen1}%
+ \box2}
+}}
+@end tex
+@ifnottex
+@example
+ most least
+significant significant
+ limb limb
+
+ _mp_d
+ |---- _mp_exp ---> |
+ _____ _____ _____ _____ _____
+ |_____|_____|_____|_____|_____|
+ . <------------ radix point
+
+ <-------- _mp_size --------->
+@sp 1
+@end example
+@end ifnottex
+
+@noindent
+The fields are as follows.
+
+@table @asis
+@item @code{_mp_size}
+The number of limbs currently in use, or the negative of that when
+representing a negative value. Zero is represented by @code{_mp_size} and
+@code{_mp_exp} both set to zero, and in that case the @code{_mp_d} data is
+unused. (In the future @code{_mp_exp} might be undefined when representing
+zero.)
+
+@item @code{_mp_prec}
+The precision of the mantissa, in limbs. In any calculation the aim is to
+produce @code{_mp_prec} limbs of result (the most significant being non-zero).
+
+@item @code{_mp_d}
+A pointer to the array of limbs which is the absolute value of the mantissa.
+These are stored ``little endian'' as per the @code{mpn} functions, so
+@code{_mp_d[0]} is the least significant limb and
+@code{_mp_d[ABS(_mp_size)-1]} the most significant.
+
+The most significant limb is always non-zero, but there are no other
+restrictions on its value, in particular the highest 1 bit can be anywhere
+within the limb.
+
+@code{_mp_prec+1} limbs are allocated to @code{_mp_d}, the extra limb being
+for convenience (see below). There are no reallocations during a calculation,
+only in a change of precision with @code{mpf_set_prec}.
+
+@item @code{_mp_exp}
+The exponent, in limbs, determining the location of the implied radix point.
+Zero means the radix point is just above the most significant limb. Positive
+values mean a radix point offset towards the lower limbs and hence a value
+@math{@ge{} 1}, as for example in the diagram above. Negative exponents mean
+a radix point further above the highest limb.
+
+Naturally the exponent can be any value, it doesn't have to fall within the
+limbs as the diagram shows, it can be a long way above or a long way below.
+Limbs other than those included in the @code{@{_mp_d,_mp_size@}} data
+are treated as zero.
+@end table
+
+The @code{_mp_size} and @code{_mp_prec} fields are @code{int}, although the
+@code{mp_size_t} type is usually a @code{long}. The @code{_mp_exp} field is
+usually @code{long}. This is done to make some fields just 32 bits on some 64
+bits systems, thereby saving a few bytes of data space but still providing
+plenty of precision and a very large range.
+
+
+@sp 1
+@noindent
+The following various points should be noted.
+
+@table @asis
+@item Low Zeros
+The least significant limbs @code{_mp_d[0]} etc can be zero, though such low
+zeros can always be ignored. Routines likely to produce low zeros check and
+avoid them to save time in subsequent calculations, but for most routines
+they're quite unlikely and aren't checked.
+
+@item Mantissa Size Range
+The @code{_mp_size} count of limbs in use can be less than @code{_mp_prec} if
+the value can be represented in less. This means low precision values or
+small integers stored in a high precision @code{mpf_t} can still be operated
+on efficiently.
+
+@code{_mp_size} can also be greater than @code{_mp_prec}. Firstly a value is
+allowed to use all of the @code{_mp_prec+1} limbs available at @code{_mp_d},
+and secondly when @code{mpf_set_prec_raw} lowers @code{_mp_prec} it leaves
+@code{_mp_size} unchanged and so the size can be arbitrarily bigger than
+@code{_mp_prec}.
+
+@item Rounding
+All rounding is done on limb boundaries. Calculating @code{_mp_prec} limbs
+with the high non-zero will ensure the application requested minimum precision
+is obtained.
+
+The use of simple ``trunc'' rounding towards zero is efficient, since there's
+no need to examine extra limbs and increment or decrement.
+
+@item Bit Shifts
+Since the exponent is in limbs, there are no bit shifts in basic operations
+like @code{mpf_add} and @code{mpf_mul}. When differing exponents are
+encountered all that's needed is to adjust pointers to line up the relevant
+limbs.
+
+Of course @code{mpf_mul_2exp} and @code{mpf_div_2exp} will require bit shifts,
+but the choice is between an exponent in limbs which requires shifts there, or
+one in bits which requires them almost everywhere else.
+
+@item Use of @code{_mp_prec+1} Limbs
+The extra limb on @code{_mp_d} (@code{_mp_prec+1} rather than just
+@code{_mp_prec}) helps when an @code{mpf} routine might get a carry from its
+operation. @code{mpf_add} for instance will do an @code{mpn_add} of
+@code{_mp_prec} limbs. If there's no carry then that's the result, but if
+there is a carry then it's stored in the extra limb of space and
+@code{_mp_size} becomes @code{_mp_prec+1}.
+
+Whenever @code{_mp_prec+1} limbs are held in a variable, the low limb is not
+needed for the intended precision, only the @code{_mp_prec} high limbs. But
+zeroing it out or moving the rest down is unnecessary. Subsequent routines
+reading the value will simply take the high limbs they need, and this will be
+@code{_mp_prec} if their target has that same precision. This is no more than
+a pointer adjustment, and must be checked anyway since the destination
+precision can be different from the sources.
+
+Copy functions like @code{mpf_set} will retain a full @code{_mp_prec+1} limbs
+if available. This ensures that a variable which has @code{_mp_size} equal to
+@code{_mp_prec+1} will get its full exact value copied. Strictly speaking
+this is unnecessary since only @code{_mp_prec} limbs are needed for the
+application's requested precision, but it's considered that an @code{mpf_set}
+from one variable into another of the same precision ought to produce an exact
+copy.
+
+@item Application Precisions
+@code{__GMPF_BITS_TO_PREC} converts an application requested precision to an
+@code{_mp_prec}. The value in bits is rounded up to a whole limb then an
+extra limb is added since the most significant limb of @code{_mp_d} is only
+non-zero and therefore might contain only one bit.
+
+@code{__GMPF_PREC_TO_BITS} does the reverse conversion, and removes the extra
+limb from @code{_mp_prec} before converting to bits. The net effect of
+reading back with @code{mpf_get_prec} is simply the precision rounded up to a
+multiple of @code{mp_bits_per_limb}.
+
+Note that the extra limb added here for the high only being non-zero is in
+addition to the extra limb allocated to @code{_mp_d}. For example with a
+32-bit limb, an application request for 250 bits will be rounded up to 8
+limbs, then an extra added for the high being only non-zero, giving an
+@code{_mp_prec} of 9. @code{_mp_d} then gets 10 limbs allocated. Reading
+back with @code{mpf_get_prec} will take @code{_mp_prec} subtract 1 limb and
+multiply by 32, giving 256 bits.
+
+Strictly speaking, the fact the high limb has at least one bit means that a
+float with, say, 3 limbs of 32-bits each will be holding at least 65 bits, but
+for the purposes of @code{mpf_t} it's considered simply to be 64 bits, a nice
+multiple of the limb size.
+@end table
+
+
+@node Raw Output Internals, C++ Interface Internals, Float Internals, Internals
+@section Raw Output Internals
+@cindex Raw output internals
+
+@noindent
+@code{mpz_out_raw} uses the following format.
+
+@tex
+\global\newdimen\GMPboxwidth \GMPboxwidth=5em
+\global\newdimen\GMPboxheight \GMPboxheight=3ex
+\def\centreline{\hbox{\raise 0.8ex \vbox{\hrule \hbox{\hfil}}}}
+\GMPdisplay{%
+\vbox{%
+ \def\GMPcentreline#1{\hbox{\raise 0.5 ex \vbox{\hrule \hbox to #1 {}}}}
+ \vbox {%
+ \hrule
+ \hbox{%
+ \vrule height 2.5ex depth 1.5ex
+ \hbox to \GMPboxwidth {\hfil size\hfil}%
+ \vrule
+ \hbox to 3\GMPboxwidth {\hfil data bytes\hfil}%
+ \vrule}
+ \hrule}
+}}
+@end tex
+@ifnottex
+@example
++------+------------------------+
+| size | data bytes |
++------+------------------------+
+@end example
+@end ifnottex
+
+The size is 4 bytes written most significant byte first, being the number of
+subsequent data bytes, or the twos complement negative of that when a negative
+integer is represented. The data bytes are the absolute value of the integer,
+written most significant byte first.
+
+The most significant data byte is always non-zero, so the output is the same
+on all systems, irrespective of limb size.
+
+In GMP 1, leading zero bytes were written to pad the data bytes to a multiple
+of the limb size. @code{mpz_inp_raw} will still accept this, for
+compatibility.
+
+The use of ``big endian'' for both the size and data fields is deliberate, it
+makes the data easy to read in a hex dump of a file. Unfortunately it also
+means that the limb data must be reversed when reading or writing, so neither
+a big endian nor little endian system can just read and write @code{_mp_d}.
+
+
+@node C++ Interface Internals, , Raw Output Internals, Internals
+@section C++ Interface Internals
+@cindex C++ interface internals
+
+A system of expression templates is used to ensure something like @code{a=b+c}
+turns into a simple call to @code{mpz_add} etc. For @code{mpf_class}
+the scheme also ensures the precision of the final
+destination is used for any temporaries within a statement like
+@code{f=w*x+y*z}. These are important features which a naive implementation
+cannot provide.
+
+A simplified description of the scheme follows. The true scheme is
+complicated by the fact that expressions have different return types. For
+detailed information, refer to the source code.
+
+To perform an operation, say, addition, we first define a ``function object''
+evaluating it,
+
+@example
+struct __gmp_binary_plus
+@{
+ static void eval(mpf_t f, const mpf_t g, const mpf_t h)
+ @{
+ mpf_add(f, g, h);
+ @}
+@};
+@end example
+
+@noindent
+And an ``additive expression'' object,
+
+@example
+__gmp_expr<__gmp_binary_expr<mpf_class, mpf_class, __gmp_binary_plus> >
+operator+(const mpf_class &f, const mpf_class &g)
+@{
+ return __gmp_expr
+ <__gmp_binary_expr<mpf_class, mpf_class, __gmp_binary_plus> >(f, g);
+@}
+@end example
+
+The seemingly redundant @code{__gmp_expr<__gmp_binary_expr<@dots{}>>} is used to
+encapsulate any possible kind of expression into a single template type. In
+fact even @code{mpf_class} etc are @code{typedef} specializations of
+@code{__gmp_expr}.
+
+Next we define assignment of @code{__gmp_expr} to @code{mpf_class}.
+
+@example
+template <class T>
+mpf_class & mpf_class::operator=(const __gmp_expr<T> &expr)
+@{
+ expr.eval(this->get_mpf_t(), this->precision());
+ return *this;
+@}
+
+template <class Op>
+void __gmp_expr<__gmp_binary_expr<mpf_class, mpf_class, Op> >::eval
+(mpf_t f, mp_bitcnt_t precision)
+@{
+ Op::eval(f, expr.val1.get_mpf_t(), expr.val2.get_mpf_t());
+@}
+@end example
+
+where @code{expr.val1} and @code{expr.val2} are references to the expression's
+operands (here @code{expr} is the @code{__gmp_binary_expr} stored within the
+@code{__gmp_expr}).
+
+This way, the expression is actually evaluated only at the time of assignment,
+when the required precision (that of @code{f}) is known. Furthermore the
+target @code{mpf_t} is now available, thus we can call @code{mpf_add} directly
+with @code{f} as the output argument.
+
+Compound expressions are handled by defining operators taking subexpressions
+as their arguments, like this:
+
+@example
+template <class T, class U>
+__gmp_expr
+<__gmp_binary_expr<__gmp_expr<T>, __gmp_expr<U>, __gmp_binary_plus> >
+operator+(const __gmp_expr<T> &expr1, const __gmp_expr<U> &expr2)
+@{
+ return __gmp_expr
+ <__gmp_binary_expr<__gmp_expr<T>, __gmp_expr<U>, __gmp_binary_plus> >
+ (expr1, expr2);
+@}
+@end example
+
+And the corresponding specializations of @code{__gmp_expr::eval}:
+
+@example
+template <class T, class U, class Op>
+void __gmp_expr
+<__gmp_binary_expr<__gmp_expr<T>, __gmp_expr<U>, Op> >::eval
+(mpf_t f, mp_bitcnt_t precision)
+@{
+ // declare two temporaries
+ mpf_class temp1(expr.val1, precision), temp2(expr.val2, precision);
+ Op::eval(f, temp1.get_mpf_t(), temp2.get_mpf_t());
+@}
+@end example
+
+The expression is thus recursively evaluated to any level of complexity and
+all subexpressions are evaluated to the precision of @code{f}.
+
+
+@node Contributors, References, Internals, Top
+@comment node-name, next, previous, up
+@appendix Contributors
+@cindex Contributors
+
+Torbj@"orn Granlund wrote the original GMP library and is still the main
+developer. Code not explicitly attributed to others, was contributed by
+Torbj@"orn. Several other individuals and organizations have contributed
+GMP. Here is a list in chronological order on first contribution:
+
+Gunnar Sj@"odin and Hans Riesel helped with mathematical problems in early
+versions of the library.
+
+Richard Stallman helped with the interface design and revised the first
+version of this manual.
+
+Brian Beuning and Doug Lea helped with testing of early versions of the
+library and made creative suggestions.
+
+John Amanatides of York University in Canada contributed the function
+@code{mpz_probab_prime_p}.
+
+Paul Zimmermann wrote the REDC-based mpz_powm code, the Sch@"onhage-Strassen
+FFT multiply code, and the Karatsuba square root code. He also improved the
+Toom3 code for GMP 4.2. Paul sparked the development of GMP 2, with his
+comparisons between bignum packages. The ECMNET project Paul is organizing
+was a driving force behind many of the optimizations in GMP 3. Paul also
+wrote the new GMP 4.3 nth root code (with Torbj@"orn).
+
+Ken Weber (Kent State University, Universidade Federal do Rio Grande do Sul)
+contributed now defunct versions of @code{mpz_gcd}, @code{mpz_divexact},
+@code{mpn_gcd}, and @code{mpn_bdivmod}, partially supported by CNPq (Brazil)
+grant 301314194-2.
+
+Per Bothner of Cygnus Support helped to set up GMP to use Cygnus' configure.
+He has also made valuable suggestions and tested numerous intermediary
+releases.
+
+Joachim Hollman was involved in the design of the @code{mpf} interface, and in
+the @code{mpz} design revisions for version 2.
+
+Bennet Yee contributed the initial versions of @code{mpz_jacobi} and
+@code{mpz_legendre}.
+
+Andreas Schwab contributed the files @file{mpn/m68k/lshift.S} and
+@file{mpn/m68k/rshift.S} (now in @file{.asm} form).
+
+Robert Harley of Inria, France and David Seal of ARM, England, suggested clever
+improvements for population count. Robert also wrote highly optimized
+Karatsuba and 3-way Toom multiplication functions for GMP 3, and contributed
+the ARM assembly code.
+
+Torsten Ekedahl of the Mathematical department of Stockholm University provided
+significant inspiration during several phases of the GMP development. His
+mathematical expertise helped improve several algorithms.
+
+Linus Nordberg wrote the new configure system based on autoconf and
+implemented the new random functions.
+
+Kevin Ryde worked on a large number of things: optimized x86 code, m4 asm
+macros, parameter tuning, speed measuring, the configure system, function
+inlining, divisibility tests, bit scanning, Jacobi symbols, Fibonacci and Lucas
+number functions, printf and scanf functions, perl interface, demo expression
+parser, the algorithms chapter in the manual, @file{gmpasm-mode.el}, and
+various miscellaneous improvements elsewhere.
+
+Kent Boortz made the Mac OS 9 port.
+
+Steve Root helped write the optimized alpha 21264 assembly code.
+
+Gerardo Ballabio wrote the @file{gmpxx.h} C++ class interface and the C++
+@code{istream} input routines.
+
+Jason Moxham rewrote @code{mpz_fac_ui}.
+
+Pedro Gimeno implemented the Mersenne Twister and made other random number
+improvements.
+
+Niels M@"oller wrote the sub-quadratic GCD, extended GCD and jacobi code, the
+quadratic Hensel division code, and (with Torbj@"orn) the new divide and
+conquer division code for GMP 4.3. Niels also helped implement the new Toom
+multiply code for GMP 4.3 and implemented helper functions to simplify Toom
+evaluations for GMP 5.0. He wrote the original version of mpn_mulmod_bnm1, and
+he is the main author of the mini-gmp package used for gmp bootstrapping.
+
+Alberto Zanoni and Marco Bodrato suggested the unbalanced multiply strategy,
+and found the optimal strategies for evaluation and interpolation in Toom
+multiplication.
+
+Marco Bodrato helped implement the new Toom multiply code for GMP 4.3 and
+implemented most of the new Toom multiply and squaring code for 5.0.
+He is the main author of the current mpn_mulmod_bnm1 and mpn_mullo_n. Marco
+also wrote the functions mpn_invert and mpn_invertappr. He is the author of
+the current combinatorial functions: binomial, factorial, multifactorial,
+primorial.
+
+David Harvey suggested the internal function @code{mpn_bdiv_dbm1}, implementing
+division relevant to Toom multiplication. He also worked on fast assembly
+sequences, in particular on a fast AMD64 @code{mpn_mul_basecase}. He wrote
+the internal middle product functions @code{mpn_mulmid_basecase},
+@code{mpn_toom42_mulmid}, @code{mpn_mulmid_n} and related helper routines.
+
+Martin Boij wrote @code{mpn_perfect_power_p}.
+
+Marc Glisse improved @file{gmpxx.h}: use fewer temporaries (faster),
+specializations of @code{numeric_limits} and @code{common_type}, C++11
+features (move constructors, explicit bool conversion, UDL), make the
+conversion from @code{mpq_class} to @code{mpz_class} explicit, optimize
+operations where one argument is a small compile-time constant, replace
+some heap allocations by stack allocations. He also fixed the eofbit
+handling of C++ streams, and removed one division from @file{mpq/aors.c}.
+
+David S Miller wrote assembly code for SPARC T3 and T4.
+
+Mark Sofroniou cleaned up the types of mul_fft.c, letting it work for huge
+operands.
+
+Ulrich Weigand ported GMP to the powerpc64le ABI.
+
+(This list is chronological, not ordered after significance. If you have
+contributed to GMP but are not listed above, please tell
+@email{gmp-devel@@gmplib.org} about the omission!)
+
+The development of floating point functions of GNU MP 2, were supported in part
+by the ESPRIT-BRA (Basic Research Activities) 6846 project POSSO (POlynomial
+System SOlving).
+
+The development of GMP 2, 3, and 4.0 was supported in part by the IDA Center
+for Computing Sciences.
+
+The development of GMP 4.3, 5.0, and 5.1 was supported in part by the Swedish
+Foundation for Strategic Research.
+
+Thanks go to Hans Thorsen for donating an SGI system for the GMP test system
+environment.
+
+@node References, GNU Free Documentation License, Contributors, Top
+@comment node-name, next, previous, up
+@appendix References
+@cindex References
+
+@c FIXME: In tex, the @uref's are unhyphenated, which is good for clarity,
+@c but being long words they upset paragraph formatting (the preceding line
+@c can get badly stretched). Would like an conditional @* style line break
+@c if the uref is too long to fit on the last line of the paragraph, but it's
+@c not clear how to do that. For now explicit @texlinebreak{}s are used on
+@c paragraphs that come out bad.
+
+@section Books
+
+@itemize @bullet
+@item
+Jonathan M. Borwein and Peter B. Borwein, ``Pi and the AGM: A Study in
+Analytic Number Theory and Computational Complexity'', Wiley, 1998.
+
+@item
+Richard Crandall and Carl Pomerance, ``Prime Numbers: A Computational
+Perspective'', 2nd edition, Springer-Verlag, 2005.
+@texlinebreak{} @uref{http://www.math.dartmouth.edu/~carlp/}
+
+@item
+Henri Cohen, ``A Course in Computational Algebraic Number Theory'', Graduate
+Texts in Mathematics number 138, Springer-Verlag, 1993.
+@texlinebreak{} @uref{http://www.math.u-bordeaux.fr/~cohen/}
+
+@item
+Donald E. Knuth, ``The Art of Computer Programming'', volume 2,
+``Seminumerical Algorithms'', 3rd edition, Addison-Wesley, 1998.
+@texlinebreak{} @uref{http://www-cs-faculty.stanford.edu/~knuth/taocp.html}
+
+@item
+John D. Lipson, ``Elements of Algebra and Algebraic Computing'',
+The Benjamin Cummings Publishing Company Inc, 1981.
+
+@item
+Alfred J. Menezes, Paul C. van Oorschot and Scott A. Vanstone, ``Handbook of
+Applied Cryptography'', @uref{http://www.cacr.math.uwaterloo.ca/hac/}
+
+@item
+Richard M. Stallman and the GCC Developer Community, ``Using the GNU Compiler
+Collection'', Free Software Foundation, 2008, available online
+@uref{https://gcc.gnu.org/onlinedocs/}, and in the GCC package
+@uref{https://ftp.gnu.org/gnu/gcc/}
+@end itemize
+
+@section Papers
+
+@itemize @bullet
+@item
+Yves Bertot, Nicolas Magaud and Paul Zimmermann, ``A Proof of GMP Square
+Root'', Journal of Automated Reasoning, volume 29, 2002, pp.@: 225-252. Also
+available online as INRIA Research Report 4475, June 2002,
+@uref{http://hal.inria.fr/docs/00/07/21/13/PDF/RR-4475.pdf}
+
+@item
+Christoph Burnikel and Joachim Ziegler, ``Fast Recursive Division'',
+Max-Planck-Institut fuer Informatik Research Report MPI-I-98-1-022,
+@texlinebreak{} @uref{http://data.mpi-sb.mpg.de/internet/reports.nsf/NumberView/1998-1-022}
+
+@item
+Torbj@"orn Granlund and Peter L. Montgomery, ``Division by Invariant Integers
+using Multiplication'', in Proceedings of the SIGPLAN PLDI'94 Conference, June
+1994. Also available @uref{https://gmplib.org/~tege/divcnst-pldi94.pdf}.
+
+@item
+Niels M@"oller and Torbj@"orn Granlund, ``Improved division by invariant
+integers'', IEEE Transactions on Computers, 11 June 2010.
+@uref{https://gmplib.org/~tege/division-paper.pdf}
+
+@item
+Torbj@"orn Granlund and Niels M@"oller, ``Division of integers large and
+small'', to appear.
+
+@item
+Tudor Jebelean,
+``An algorithm for exact division'',
+Journal of Symbolic Computation,
+volume 15, 1993, pp.@: 169-180.
+Research report version available @texlinebreak{}
+@uref{ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1992/92-35.ps.gz}
+
+@item
+Tudor Jebelean, ``Exact Division with Karatsuba Complexity - Extended
+Abstract'', RISC-Linz technical report 96-31, @texlinebreak{}
+@uref{ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1996/96-31.ps.gz}
+
+@item
+Tudor Jebelean, ``Practical Integer Division with Karatsuba Complexity'',
+ISSAC 97, pp.@: 339-341. Technical report available @texlinebreak{}
+@uref{ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1996/96-29.ps.gz}
+
+@item
+Tudor Jebelean, ``A Generalization of the Binary GCD Algorithm'', ISSAC 93,
+pp.@: 111-116. Technical report version available @texlinebreak{}
+@uref{ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1993/93-01.ps.gz}
+
+@item
+Tudor Jebelean, ``A Double-Digit Lehmer-Euclid Algorithm for Finding the GCD
+of Long Integers'', Journal of Symbolic Computation, volume 19, 1995,
+pp.@: 145-157. Technical report version also available @texlinebreak{}
+@uref{ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1992/92-69.ps.gz}
+
+@item
+Werner Krandick and Tudor Jebelean, ``Bidirectional Exact Integer Division'',
+Journal of Symbolic Computation, volume 21, 1996, pp.@: 441-455. Early
+technical report version also available
+@uref{ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1994/94-50.ps.gz}
+
+@item
+Makoto Matsumoto and Takuji Nishimura, ``Mersenne Twister: A 623-dimensionally
+equidistributed uniform pseudorandom number generator'', ACM Transactions on
+Modelling and Computer Simulation, volume 8, January 1998, pp.@: 3-30.
+Available online @texlinebreak{}
+@uref{http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/mt.ps.gz} (or .pdf)
+
+@item
+R. Moenck and A. Borodin, ``Fast Modular Transforms via Division'',
+Proceedings of the 13th Annual IEEE Symposium on Switching and Automata
+Theory, October 1972, pp.@: 90-96. Reprinted as ``Fast Modular Transforms'',
+Journal of Computer and System Sciences, volume 8, number 3, June 1974,
+pp.@: 366-386.
+
+@item
+Niels M@"oller, ``On Sch@"onhage's algorithm and subquadratic integer GCD
+ computation'', in Mathematics of Computation, volume 77, January 2008, pp.@:
+ 589-607.
+
+@item
+Peter L. Montgomery, ``Modular Multiplication Without Trial Division'', in
+Mathematics of Computation, volume 44, number 170, April 1985.
+
+@item
+Arnold Sch@"onhage and Volker Strassen, ``Schnelle Multiplikation grosser
+Zahlen'', Computing 7, 1971, pp.@: 281-292.
+
+@item
+Kenneth Weber, ``The accelerated integer GCD algorithm'',
+ACM Transactions on Mathematical Software,
+volume 21, number 1, March 1995, pp.@: 111-122.
+
+@item
+Paul Zimmermann, ``Karatsuba Square Root'', INRIA Research Report 3805,
+November 1999, @uref{http://hal.inria.fr/inria-00072854/PDF/RR-3805.pdf}
+
+@item
+Paul Zimmermann, ``A Proof of GMP Fast Division and Square Root
+Implementations'', @texlinebreak{}
+@uref{http://www.loria.fr/~zimmerma/papers/proof-div-sqrt.ps.gz}
+
+@item
+Dan Zuras, ``On Squaring and Multiplying Large Integers'', ARITH-11: IEEE
+Symposium on Computer Arithmetic, 1993, pp.@: 260 to 271. Reprinted as ``More
+on Multiplying and Squaring Large Integers'', IEEE Transactions on Computers,
+volume 43, number 8, August 1994, pp.@: 899-908.
+@end itemize
+
+
+@node GNU Free Documentation License, Concept Index, References, Top
+@appendix GNU Free Documentation License
+@cindex GNU Free Documentation License
+@cindex Free Documentation License
+@cindex Documentation license
+@include fdl-1.3.texi
+
+
+@node Concept Index, Function Index, GNU Free Documentation License, Top
+@comment node-name, next, previous, up
+@unnumbered Concept Index
+@printindex cp
+
+@node Function Index, , Concept Index, Top
+@comment node-name, next, previous, up
+@unnumbered Function and Type Index
+@printindex fn
+
+@bye
+
+@c Local variables:
+@c fill-column: 78
+@c compile-command: "make gmp.info"
+@c End:
diff --git a/gmp/doc/isa_abi_headache b/gmp/doc/isa_abi_headache
new file mode 100644
index 0000000000..7e1430d3d3
--- /dev/null
+++ b/gmp/doc/isa_abi_headache
@@ -0,0 +1,128 @@
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+Terms Used In This Document:
+ ISA = Instruction Set Architecture. The instructions the current
+ processor provides.
+ ABI = Application Binary Interface. Specifies calling convention,
+ type sizes, etc.
+ AR64 = Arithmetic operations are 64-bit using 64-bit instructions
+ (E.g., addition, subtraction, load, store, of 64-bit integer types
+ are done with single instructions, not 32 bits at a time.)
+ Environment = The operating system and compiler.
+
+GMP is a very complex package to build since its speed is very
+sensitive to the ISA and ABI. For example, if the ISA provides 64-bit
+instructions, it is crucial that GMP is configured to use them.
+
+Most environments that run on a 64-bit ISA provide more than one ABI.
+Typically one of the supported ABI's is a backward compatible 32-bit
+ABI, and one ABI provides 64-bit addressing and `long' (sometimes
+known as LP64). But a few environments (IRIX, HP-UX) provide
+intermediate ABI's using 32-bit addressing but allow efficient 64-bit
+operations through a `long long' type. For the latter to be useful to
+GMP, the ABI must allow operations using the native 64-bit
+instructions provided by the ISA, and allow passing of 64-bit
+quantities atomically.
+
+The ABI is typically chosen by means of command line options to the
+compiler tools (gcc, cc, c89, nm, ar, ld, as). Different environments
+use different defaults, but as of this writing (May 2000) the
+dominating default is to the plain 32-bit ABI in its most arcane form.
+
+The GMP 3.0.x approach was to compile using the ABI that gives the
+best performance. That places the burden on users to pass special
+options to the compiler when they compile their GMP applications.
+That approach has its advantages and disadvantages. The main
+advantage is that users don't unknowingly get bad GMP performance.
+The main disadvantage is that users' compiles (actually links) will
+fail unless they pass special compiler options.
+
+** SPARC
+
+System vendors often confuse ABI, ISA, and implementation. The worst
+case is Solaris, were the unbundled compiler confuses ISA and ABI, and
+the options have very confusing names.
+
+ option interpretation
+ ====== ==============
+cc -xarch=v8plus ISA=sparcv9, ABI=V8plus (PTR=32, see below)
+gcc -mv8plus ISA=sparcv9, ABI=V8plus (see below)
+cc -xarch=v9 ISA=sparcv9, ABI=V9 (implying AR=64, PTR=64)
+
+It's hard to believe, but the option v8plus really means ISA=V9!
+
+Solaris releases prior to version 7 running on a V9 CPU fails to
+save/restore the upper 32 bits of the `i' and `l' registers. The
+`v8plus' option generates code that use as many V9 features as
+possible under such circumstances.
+
+** MIPS
+
+The IRIX 6 compilers gets things right. They have a clear
+understanding of the differences between ABI and ISA. The option
+names are descriptive.
+
+ option interpretation
+ ====== ==============
+cc -n32 ABI=n32 (implying AR=64, PTR=32)
+gcc -mabi=n32 ABI=n32 (implying AR=64, PTR=32)
+cc -64 ABI=64 (implying AR=64, PTR=64)
+gcc -mabi=64 ABI=64 (implying AR=64, PTR=64)
+cc -mips3 ISA=mips3
+gcc -mips3 ISA=mips3
+cc -mips4 ISA=mips4
+gcc -mips4 ISA=mips4
+
+** HP-PA
+
+HP-UX is somewhat weird, but not as broken as Solaris.
+
+ option interpretation
+ ====== ==============
+cc +DA2.0 ABI=32bit (implying AR=64, PTR=32)
+cc +DD64 ABI=64bit (implying AR=64, PTR=64)
+
+Code performing 64-bit arithmetic in the HP-UX 32-bit is not
+compatible with the 64-bit ABI; the former has a calling convention
+that passes/returns 64-bit integer quantities as two 32-bit chunks.
+
+** PowerPC
+
+While the PowerPC ABI's are capable of supporting 64-bit
+registers/operations, the compilers under AIX are similar to Solaris'
+cc in that they don't currently provide any 32-bit addressing with
+64-bit arithmetic.
+
+ option interpretation
+ ====== ==============
+cc -q64 ABI=64bit (implying AR=64, PTR=64)
+gcc -maix64 -mpowerpc64 ABI=64bit (implying AR=64, PTR=64)
diff --git a/gmp/doc/mdate-sh b/gmp/doc/mdate-sh
new file mode 100755
index 0000000000..60dc485a37
--- /dev/null
+++ b/gmp/doc/mdate-sh
@@ -0,0 +1,225 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+
+scriptversion=2010-08-21.06; # UTC
+
+# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005, 2007, 2009, 2010
+# Free Software Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+fi
+
+case $1 in
+ '')
+ echo "$0: No file. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: mdate-sh [--help] [--version] FILE
+
+Pretty-print the modification day of FILE, in the format:
+1 January 1970
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "mdate-sh $scriptversion"
+ exit $?
+ ;;
+esac
+
+error ()
+{
+ echo "$0: $1" >&2
+ exit 1
+}
+
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# GNU ls changes its time format in response to the TIME_STYLE
+# variable. Since we cannot assume `unset' works, revert this
+# variable to its documented default.
+if test "${TIME_STYLE+set}" = set; then
+ TIME_STYLE=posix-long-iso
+ export TIME_STYLE
+fi
+
+save_arg1=$1
+
+# Find out how to get the extended ls output of a file or directory.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+ ls_command='ls -L -l -d'
+else
+ ls_command='ls -l -d'
+fi
+# Avoid user/group names that might have spaces, when possible.
+if ls -n /dev/null 1>/dev/null 2>&1; then
+ ls_command="$ls_command -n"
+fi
+
+# A `ls -l' line looks as follows on OS/2.
+# drwxrwx--- 0 Aug 11 2001 foo
+# This differs from Unix, which adds ownership information.
+# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
+#
+# To find the date, we split the line on spaces and iterate on words
+# until we find a month. This cannot work with files whose owner is a
+# user named `Jan', or `Feb', etc. However, it's unlikely that `/'
+# will be owned by a user whose name is a month. So we first look at
+# the extended ls output of the root directory to decide how many
+# words should be skipped to get the date.
+
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+set x`$ls_command /`
+
+# Find which argument is the month.
+month=
+command=
+until test $month
+do
+ test $# -gt 0 || error "failed parsing \`$ls_command /' output"
+ shift
+ # Add another shift to the command.
+ command="$command shift;"
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+done
+
+test -n "$month" || error "failed parsing \`$ls_command /' output"
+
+# Get the extended ls output of the file or directory.
+set dummy x`eval "$ls_command \"\\\$save_arg1\""`
+
+# Remove all preceding arguments
+eval $command
+
+# Because of the dummy argument above, month is in $2.
+#
+# On a POSIX system, we should have
+#
+# $# = 5
+# $1 = file size
+# $2 = month
+# $3 = day
+# $4 = year or time
+# $5 = filename
+#
+# On Darwin 7.7.0 and 7.6.0, we have
+#
+# $# = 4
+# $1 = day
+# $2 = month
+# $3 = year or time
+# $4 = filename
+
+# Get the month.
+case $2 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+esac
+
+case $3 in
+ ???*) day=$1;;
+ *) day=$3; shift;;
+esac
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+ *:*) set `date`; eval year=\$$#
+ case $2 in
+ Jan) nummonthtod=1;;
+ Feb) nummonthtod=2;;
+ Mar) nummonthtod=3;;
+ Apr) nummonthtod=4;;
+ May) nummonthtod=5;;
+ Jun) nummonthtod=6;;
+ Jul) nummonthtod=7;;
+ Aug) nummonthtod=8;;
+ Sep) nummonthtod=9;;
+ Oct) nummonthtod=10;;
+ Nov) nummonthtod=11;;
+ Dec) nummonthtod=12;;
+ esac
+ # For the first six month of the year the time notation can also
+ # be used for files modified in the last year.
+ if (expr $nummonth \> $nummonthtod) > /dev/null;
+ then
+ year=`expr $year - 1`
+ fi;;
+ *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/gmp/doc/projects.html b/gmp/doc/projects.html
new file mode 100644
index 0000000000..4a105142b0
--- /dev/null
+++ b/gmp/doc/projects.html
@@ -0,0 +1,476 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title>GMP Development Projects</title>
+ <link rel="shortcut icon" href="favicon.ico">
+ <link rel="stylesheet" href="gmp.css">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+
+<center>
+ <h1>
+ GMP Development Projects
+ </h1>
+</center>
+
+<font size=-1>
+<pre>
+Copyright 2000-2006, 2008-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+</pre>
+</font>
+
+<hr>
+<!-- NB. timestamp updated automatically by emacs -->
+ This file current as of 29 Jan 2014. An up-to-date version is available at
+ <a href="https://gmplib.org/projects.html">https://gmplib.org/projects.html</a>.
+ Please send comments about this page to gmp-devel<font>@</font>gmplib.org.
+
+<p> This file lists projects suitable for volunteers. Please see the
+ <a href="tasks.html">tasks file</a> for smaller tasks.
+
+<p> If you want to work on any of the projects below, please let
+ gmp-devel<font>@</font>gmplib.org know. If you want to help with a project
+ that already somebody else is working on, you will get in touch through
+ gmp-devel<font>@</font>gmplib.org. (There are no email addresses of
+ volunteers below, due to spamming problems.)
+
+<ul>
+<li> <strong>Faster multiplication</strong>
+
+ <ol>
+
+ <li> Work on the algorithm selection code for unbalanced multiplication.
+
+ <li> Implement an FFT variant computing the coefficients mod m different
+ limb size primes of the form l*2^k+1. i.e., compute m separate FFTs.
+ The wanted coefficients will at the end be found by lifting with CRT
+ (Chinese Remainder Theorem). If we let m = 3, i.e., use 3 primes, we
+ can split the operands into coefficients at limb boundaries, and if
+ our machine uses b-bit limbs, we can multiply numbers with close to
+ 2^b limbs without coefficient overflow. For smaller multiplication,
+ we might perhaps let m = 1, and instead of splitting our operands at
+ limb boundaries, split them in much smaller pieces. We might also use
+ 4 or more primes, and split operands into bigger than b-bit chunks.
+ By using more primes, the gain in shorter transform length, but lose
+ in having to do more FFTs, but that is a slight total save. We then
+ lose in more expensive CRT. <br><br>
+
+ <p> [We now have two implementations of this algorithm, one by Tommy
+ Färnqvist and one by Niels Möller.]
+
+ <li> Work on short products. Our mullo and mulmid are probably K, but we
+ lack mulhi.
+
+ </ol>
+
+ <p> Another possibility would be an optimized cube. In the basecase that
+ should definitely be able to save cross-products in a similar fashion to
+ squaring, but some investigation might be needed for how best to adapt
+ the higher-order algorithms. Not sure whether cubing or further small
+ powers have any particularly important uses though.
+
+
+<li> <strong>Assembly routines</strong>
+
+ <p> Write new and improve existing assembly routines. The tests/devel
+ programs and the tune/speed.c and tune/many.pl programs are useful for
+ testing and timing the routines you write. See the README files in those
+ directories for more information.
+
+ <p> Please make sure your new routines are fast for these three situations:
+ <ol>
+ <li> Small operands of less than, say, 10 limbs.
+ <li> Medium size operands, that fit into the cache.
+ <li> Huge operands that does not fit into the cache.
+ </ol>
+
+ <p> The most important routines are mpn_addmul_1, mpn_mul_basecase and
+ mpn_sqr_basecase. The latter two don't exist for all machines, while
+ mpn_addmul_1 exists for almost all machines.
+
+ <p> Standard techniques for these routines are unrolling, software
+ pipelining, and specialization for common operand values. For machines
+ with poor integer multiplication, it is sometimes possible to remedy the
+ situation using floating-point operations or SIMD operations such as MMX
+ (x86) (x86), SSE (x86), VMX (PowerPC), VIS (Sparc).
+
+ <p> Using floating-point operations is interesting but somewhat tricky.
+ Since IEEE double has 53 bit of mantissa, one has to split the operands
+ in small pieces, so that no intermediates are greater than 2^53. For
+ 32-bit computers, splitting one operand into 16-bit pieces works. For
+ 64-bit machines, one operand can be split into 21-bit pieces and the
+ other into 32-bit pieces. (A 64-bit operand can be split into just three
+ 21-bit pieces if one allows the split operands to be negative!)
+
+
+<li> <strong>Faster sqrt</strong>
+
+ <p> The current code uses divisions, which are reasonably fast, but it'd be
+ possible to use only multiplications by computing 1/sqrt(A) using this
+ iteration:
+ <pre>
+ 2
+ x = x (3 &minus; A x )/2
+ i+1 i i </pre>
+ The square root can then be computed like this:
+ <pre>
+ sqrt(A) = A x
+ n </pre>
+ <p> That final multiply might be the full size of the input (though it might
+ only need the high half of that), so there may or may not be any speedup
+ overall.
+
+ <p> We should probably allow a special exponent-like parameter, to speed
+ computations of a precise square root of a small number in mpf and mpfr.
+
+
+<li> <strong>Nth root</strong>
+
+ <p> Improve mpn_rootrem. The current code is not too bad, but its time
+ complexity is a function of the input, while it is possible to make
+ the <i>average</i> complexity a function of the output.
+
+
+<li> <strong>Fat binaries</strong>
+
+ <p> Add more functions to the set of fat functions.
+
+ <p> The speed of multiplication is today highly dependent on combination
+ functions like <code>addlsh1_n</code>. A fat binary will never use any such
+ functions, since they are classified as optional. Ideally, we should use
+ them, but making the current compile-time selections of optional functions
+ become run-time selections for fat binaries.
+
+ <p> If we make fat binaries work really well, we should move away frm tehe
+ current configure scheme (at least by default) and instead include all code
+ always.
+
+
+<li> <strong>Exceptions</strong>
+
+ <p> Some sort of scheme for exceptions handling would be desirable.
+ Presently the only thing documented is that divide by zero in GMP
+ functions provokes a deliberate machine divide by zero (on those systems
+ where such a thing exists at least). The global <code>gmp_errno</code>
+ is not actually documented, except for the old <code>gmp_randinit</code>
+ function. Being currently just a plain global means it's not
+ thread-safe.
+
+ <p> The basic choices for exceptions are returning an error code or having a
+ handler function to be called. The disadvantage of error returns is they
+ have to be checked, leading to tedious and rarely executed code, and
+ strictly speaking such a scheme wouldn't be source or binary compatible.
+ The disadvantage of a handler function is that a <code>longjmp</code> or
+ similar recovery from it may be difficult. A combination would be
+ possible, for instance by allowing the handler to return an error code.
+
+ <p> Divide-by-zero, sqrt-of-negative, and similar operand range errors can
+ normally be detected at the start of functions, so exception handling
+ would have a clean state. What's worth considering though is that the
+ GMP function detecting the exception may have been called via some third
+ party library or self contained application module, and hence have
+ various bits of state to be cleaned up above it. It'd be highly
+ desirable for an exceptions scheme to allow for such cleanups.
+
+ <p> The C++ destructor mechanism could help with cleanups both internally and
+ externally, but being a plain C library we don't want to depend on that.
+
+ <p> A C++ <code>throw</code> might be a good optional extra exceptions
+ mechanism, perhaps under a build option. For
+ GCC <code>-fexceptions</code> will add the necessary frame information to
+ plain C code, or GMP could be compiled as C++.
+
+ <p> Out-of-memory exceptions are expected to be handled by the
+ <code>mp_set_memory_functions</code> routines, rather than being a
+ prospective part of divide-by-zero etc. Some similar considerations
+ apply but what differs is that out-of-memory can arise deep within GMP
+ internals. Even fundamental routines like <code>mpn_add_n</code> and
+ <code>mpn_addmul_1</code> can use temporary memory (for instance on Cray
+ vector systems). Allowing for an error code return would require an
+ awful lot of checking internally. Perhaps it'd still be worthwhile, but
+ it'd be a lot of changes and the extra code would probably be rather
+ rarely executed in normal usages.
+
+ <p> A <code>longjmp</code> recovery for out-of-memory will currently, in
+ general, lead to memory leaks and may leave GMP variables operated on in
+ inconsistent states. Maybe it'd be possible to record recovery
+ information for use by the relevant allocate or reallocate function, but
+ that too would be a lot of changes.
+
+ <p> One scheme for out-of-memory would be to note that all GMP allocations go
+ through the <code>mp_set_memory_functions</code> routines. So if the
+ application has an intended <code>setjmp</code> recovery point it can
+ record memory activity by GMP and abandon space allocated and variables
+ initialized after that point. This might be as simple as directing the
+ allocation functions to a separate pool, but in general would have the
+ disadvantage of needing application-level bookkeeping on top of the
+ normal system <code>malloc</code>. An advantage however is that it needs
+ nothing from GMP itself and on that basis doesn't burden applications not
+ needing recovery. Note that there's probably some details to be worked
+ out here about reallocs of existing variables, and perhaps about copying
+ or swapping between "permanent" and "temporary" variables.
+
+ <p> Applications desiring a fine-grained error control, for instance a
+ language interpreter, would very possibly not be well served by a scheme
+ requiring <code>longjmp</code>. Wrapping every GMP function call with a
+ <code>setjmp</code> would be very inconvenient.
+
+ <p> Another option would be to let <code>mpz_t</code> etc hold a sort of NaN,
+ a special value indicating an out-of-memory or other failure. This would
+ be similar to NaNs in mpfr. Unfortunately such a scheme could only be
+ used by programs prepared to handle such special values, since for
+ instance a program waiting for some condition to be satisfied could
+ become an infinite loop if it wasn't also watching for NaNs. The work to
+ implement this would be significant too, lots of checking of inputs and
+ intermediate results. And if <code>mpn</code> routines were to
+ participate in this (which they would have to internally) a lot of new
+ return values would need to be added, since of course there's no
+ <code>mpz_t</code> etc structure for them to indicate failure in.
+
+ <p> Stack overflow is another possible exception, but perhaps not one that
+ can be easily detected in general. On i386 GNU/Linux for instance GCC
+ normally doesn't generate stack probes for an <code>alloca</code>, but
+ merely adjusts <code>%esp</code>. A big enough <code>alloca</code> can
+ miss the stack redzone and hit arbitrary data. GMP stack usage is
+ normally a function of operand size, which might be enough for some
+ applications to know they'll be safe. Otherwise a fixed maximum usage
+ can probably be obtained by building with
+ <code>--enable-alloca=malloc-reentrant</code> (or
+ <code>notreentrant</code>). Arranging the default to be
+ <code>alloca</code> only on blocks up to a certain size and
+ <code>malloc</code> thereafter might be a better approach and would have
+ the advantage of not having calculations limited by available stack.
+
+ <p> Actually recovering from stack overflow is of course another problem. It
+ might be possible to catch a <code>SIGSEGV</code> in the stack redzone
+ and do something in a <code>sigaltstack</code>, on systems which have
+ that, but recovery might otherwise not be possible. This is worth
+ bearing in mind because there's no point worrying about tight and careful
+ out-of-memory recovery if an out-of-stack is fatal.
+
+ <p> Operand overflow is another exception to be addressed. It's easy for
+ instance to ask <code>mpz_pow_ui</code> for a result bigger than an
+ <code>mpz_t</code> can possibly represent. Currently overflows in limb
+ or byte count calculations will go undetected. Often they'll still end
+ up asking the memory functions for blocks bigger than available memory,
+ but that's by no means certain and results are unpredictable in general.
+ It'd be desirable to tighten up such size calculations. Probably only
+ selected routines would need checks, if it's assumed say that no input
+ will be more than half of all memory and hence size additions like say
+ <code>mpz_mul</code> won't overflow.
+
+
+<li> <strong>Performance Tool</strong>
+
+ <p> It'd be nice to have some sort of tool for getting an overview of
+ performance. Clearly a great many things could be done, but some primary
+ uses would be,
+
+ <ol>
+ <li> Checking speed variations between compilers.
+ <li> Checking relative performance between systems or CPUs.
+ </ol>
+
+ <p> A combination of measuring some fundamental routines and some
+ representative application routines might satisfy these.
+
+ <p> The tune/time.c routines would be the easiest way to get good accurate
+ measurements on lots of different systems. The high level
+ <code>speed_measure</code> may or may not suit, but the basic
+ <code>speed_starttime</code> and <code>speed_endtime</code> would cover
+ lots of portability and accuracy questions.
+
+
+<li> <strong>Using <code>restrict</code></strong>
+
+ <p> There might be some value in judicious use of C99 style
+ <code>restrict</code> on various pointers, but this would need some
+ careful thought about what it implies for the various operand overlaps
+ permitted in GMP.
+
+ <p> Rumour has it some pre-C99 compilers had <code>restrict</code>, but
+ expressing tighter (or perhaps looser) requirements. Might be worth
+ investigating that before using <code>restrict</code> unconditionally.
+
+ <p> Loops are presumably where the greatest benefit would be had, by allowing
+ the compiler to advance reads ahead of writes, perhaps as part of loop
+ unrolling. However critical loops are generally coded in assembler, so
+ there might not be very much to gain. And on Cray systems the explicit
+ use of <code>_Pragma</code> gives an equivalent effect.
+
+ <p> One thing to note is that Microsoft C headers (on ia64 at least) contain
+ <code>__declspec(restrict)</code>, so a <code>#define</code> of
+ <code>restrict</code> should be avoided. It might be wisest to setup a
+ <code>gmp_restrict</code>.
+
+
+<li> <strong>Prime Testing</strong>
+
+ <p> GMP is not really a number theory library and probably shouldn't have
+ large amounts of code dedicated to sophisticated prime testing
+ algorithms, but basic things well-implemented would suit. Tests offering
+ certainty are probably all too big or too slow (or both!) to justify
+ inclusion in the main library. Demo programs showing some possibilities
+ would be good though.
+
+ <p> The present "repetitions" argument to <code>mpz_probab_prime_p</code> is
+ rather specific to the Miller-Rabin tests of the current implementation.
+ Better would be some sort of parameter asking perhaps for a maximum
+ chance 1/2^x of a probable prime in fact being composite. If
+ applications follow the advice that the present reps gives 1/4^reps
+ chance then perhaps such a change is unnecessary, but an explicitly
+ described 1/2^x would allow for changes in the implementation or even for
+ new proofs about the theory.
+
+ <p> <code>mpz_probab_prime_p</code> always initializes a new
+ <code>gmp_randstate_t</code> for randomized tests, which unfortunately
+ means it's not really very random and in particular always runs the same
+ tests for a given input. Perhaps a new interface could accept an rstate
+ to use, so successive tests could increase confidence in the result.
+
+ <p> <code>mpn_mod_34lsub1</code> is an obvious and easy improvement to the
+ trial divisions. And since the various prime factors are constants, the
+ remainder can be tested with something like
+<pre>
+#define MP_LIMB_DIVISIBLE_7_P(n) \
+ ((n) * MODLIMB_INVERSE_7 &lt;= MP_LIMB_T_MAX/7)
+</pre>
+ Which would help compilers that don't know how to optimize divisions by
+ constants, and is even an improvement on current gcc 3.2 code. This
+ technique works for any modulus, see Granlund and Montgomery "Division by
+ Invariant Integers" section 9.
+
+ <p> The trial divisions are done with primes generated and grouped at
+ runtime. This could instead be a table of data, with pre-calculated
+ inverses too. Storing deltas, ie. amounts to add, rather than actual
+ primes would save space. <code>udiv_qrnnd_preinv</code> style inverses
+ can be made to exist by adding dummy factors of 2 if necessary. Some
+ thought needs to be given as to how big such a table should be, based on
+ how much dividing would be profitable for what sort of size inputs. The
+ data could be shared by the perfect power testing.
+
+ <p> Jason Moxham points out that if a sqrt(-1) mod N exists then any factor
+ of N must be == 1 mod 4, saving half the work in trial dividing. (If
+ x^2==-1 mod N then for a prime factor p we have x^2==-1 mod p and so the
+ jacobi symbol (-1/p)=1. But also (-1/p)=(-1)^((p-1)/2), hence must have
+ p==1 mod 4.) But knowing whether sqrt(-1) mod N exists is not too easy.
+ A strong pseudoprime test can reveal one, so perhaps such a test could be
+ inserted part way though the dividing.
+
+ <p> Jon Grantham "Frobenius Pseudoprimes" (www.pseudoprime.com) describes a
+ quadratic pseudoprime test taking about 3x longer than a plain test, but
+ with only a 1/7710 chance of error (whereas 3 plain Miller-Rabin tests
+ would offer only (1/4)^3 == 1/64). Such a test needs completely random
+ parameters to satisfy the theory, though single-limb values would run
+ faster. It's probably best to do at least one plain Miller-Rabin before
+ any quadratic tests, since that can identify composites in less total
+ time.
+
+ <p> Some thought needs to be given to the structure of which tests (trial
+ division, Miller-Rabin, quadratic) and how many are done, based on what
+ sort of inputs we expect, with a view to minimizing average time.
+
+ <p> It might be a good idea to break out subroutines for the various tests,
+ so that an application can combine them in ways it prefers, if sensible
+ defaults in <code>mpz_probab_prime_p</code> don't suit. In particular
+ this would let applications skip tests it knew would be unprofitable,
+ like trial dividing when an input is already known to have no small
+ factors.
+
+ <p> For small inputs, combinations of theory and explicit search make it
+ relatively easy to offer certainty. For instance numbers up to 2^32
+ could be handled with a strong pseudoprime test and table lookup. But
+ it's rather doubtful whether a smallnum prime test belongs in a bignum
+ library. Perhaps if it had other internal uses.
+
+ <p> An <code>mpz_nthprime</code> might be cute, but is almost certainly
+ impractical for anything but small n.
+
+
+<li> <strong>Intra-Library Calls</strong>
+
+ <p> On various systems, calls within libgmp still go through the PLT, TOC or
+ other mechanism, which makes the code bigger and slower than it needs to
+ be.
+
+ <p> The theory would be to have all GMP intra-library calls resolved directly
+ to the routines in the library. An application wouldn't be able to
+ replace a routine, the way it can normally, but there seems no good
+ reason to do that, in normal circumstances.
+
+ <p> The <code>visibility</code> attribute in recent gcc is good for this,
+ because it lets gcc omit unnecessary GOT pointer setups or whatever if it
+ finds all calls are local and there's no global data references.
+ Documented entrypoints would be <code>protected</code>, and purely
+ internal things not wanted by test programs or anything can be
+ <code>internal</code>.
+
+ <p> Unfortunately, on i386 it seems <code>protected</code> ends up causing
+ text segment relocations within libgmp.so, meaning the library code can't
+ be shared between processes, defeating the purpose of a shared library.
+ Perhaps this is just a gremlin in binutils (debian packaged
+ 2.13.90.0.16-1).
+
+ <p> The linker can be told directly (with a link script, or options) to do
+ the same sort of thing. This doesn't change the code emitted by gcc of
+ course, but it does mean calls are resolved directly to their targets,
+ avoiding a PLT entry.
+
+ <p> Keeping symbols private to libgmp.so is probably a good thing in general
+ too, to stop anyone even attempting to access them. But some
+ undocumented things will need or want to be kept visible, for use by
+ mpfr, or the test and tune programs. Libtool has a standard option for
+ selecting public symbols (used now for libmp).
+
+
+<li> <strong>Math functions for the mpf layer</strong>
+
+ <p> Implement the functions of math.h for the GMP mpf layer! Check the book
+ "Pi and the AGM" by Borwein and Borwein for ideas how to do this. These
+ functions are desirable: acos, acosh, asin, asinh, atan, atanh, atan2,
+ cos, cosh, exp, log, log10, pow, sin, sinh, tan, tanh.
+
+ <p> Note that the <a href="http://mpfr.org">mpfr</a> functions already
+ provide these functions, and that we usually recommend new programs to use
+ mpfr instead of mpf.
+</ul>
+<hr>
+
+</body>
+</html>
+
+<!--
+Local variables:
+eval: (add-hook 'write-file-hooks 'time-stamp)
+time-stamp-start: "This file current as of "
+time-stamp-format: "%:d %3b %:y"
+time-stamp-end: "\\."
+time-stamp-line-limit: 50
+End:
+-->
diff --git a/gmp/doc/stamp-vti b/gmp/doc/stamp-vti
new file mode 100644
index 0000000000..08f09e7e86
--- /dev/null
+++ b/gmp/doc/stamp-vti
@@ -0,0 +1,4 @@
+@set UPDATED 25 March 2014
+@set UPDATED-MONTH March 2014
+@set EDITION 6.0.0
+@set VERSION 6.0.0
diff --git a/gmp/doc/tasks.html b/gmp/doc/tasks.html
new file mode 100644
index 0000000000..9a25bef1a3
--- /dev/null
+++ b/gmp/doc/tasks.html
@@ -0,0 +1,896 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title>GMP Itemized Development Tasks</title>
+ <link rel="shortcut icon" href="favicon.ico">
+ <link rel="stylesheet" href="gmp.css">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+
+<center>
+ <h1>
+ GMP Itemized Development Tasks
+ </h1>
+</center>
+
+<font size=-1>
+<pre>
+Copyright 2000-2004, 2006, 2008, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+</pre>
+</font>
+
+<hr>
+<!-- NB. timestamp updated automatically by emacs -->
+ This file current as of 29 Jan 2014. An up-to-date version is available at
+ <a href="https://gmplib.org/tasks.html">https://gmplib.org/tasks.html</a>.
+ Please send comments about this page to gmp-devel<font>@</font>gmplib.org.
+
+<p> These are itemized GMP development tasks. Not all the tasks
+ listed here are suitable for volunteers, but many of them are.
+ Please see the <a href="projects.html">projects file</a> for more
+ sizeable projects.
+
+<p> CAUTION: This file needs updating. Many of the tasks here have
+either already been taken care of, or have become irrelevant.
+
+<h4>Correctness and Completeness</h4>
+<ul>
+<li> <code>_LONG_LONG_LIMB</code> in gmp.h is not namespace clean. Reported
+ by Patrick Pelissier.
+ <br>
+ We sort of mentioned <code>_LONG_LONG_LIMB</code> in past releases, so
+ need to be careful about changing it. It used to be a define
+ applications had to set for long long limb systems, but that in
+ particular is no longer relevant now that it's established automatically.
+<li> The various reuse.c tests need to force reallocation by calling
+ <code>_mpz_realloc</code> with a small (1 limb) size.
+<li> One reuse case is missing from mpX/tests/reuse.c:
+ <code>mpz_XXX(a,a,a)</code>.
+<li> Make the string reading functions allow the `0x' prefix when the base is
+ explicitly 16. They currently only allow that prefix when the base is
+ unspecified (zero).
+<li> <code>mpf_eq</code> is not always correct, when one operand is
+ 1000000000... and the other operand is 0111111111..., i.e., extremely
+ close. There is a special case in <code>mpf_sub</code> for this
+ situation; put similar code in <code>mpf_eq</code>. [In progress.]
+<li> <code>mpf_eq</code> doesn't implement what gmp.texi specifies. It should
+ not use just whole limbs, but partial limbs. [In progress.]
+<li> <code>mpf_set_str</code> doesn't validate it's exponent, for instance
+ garbage 123.456eX789X is accepted (and an exponent 0 used), and overflow
+ of a <code>long</code> is not detected.
+<li> <code>mpf_add</code> doesn't check for a carry from truncated portions of
+ the inputs, and in that respect doesn't implement the "infinite precision
+ followed by truncate" specified in the manual.
+<li> Windows DLLs: tests/mpz/reuse.c and tests/mpf/reuse.c initialize global
+ variables with pointers to <code>mpz_add</code> etc, which doesn't work
+ when those routines are coming from a DLL (because they're effectively
+ function pointer global variables themselves). Need to rearrange perhaps
+ to a set of calls to a test function rather than iterating over an array.
+<li> <code>mpz_pow_ui</code>: Detect when the result would be more memory than
+ a <code>size_t</code> can represent and raise some suitable exception,
+ probably an alloc call asking for <code>SIZE_T_MAX</code>, and if that
+ somehow succeeds then an <code>abort</code>. Various size overflows of
+ this kind are not handled gracefully, probably resulting in segvs.
+ <br>
+ In <code>mpz_n_pow_ui</code>, detect when the count of low zero bits
+ exceeds an <code>unsigned long</code>. There's a (small) chance of this
+ happening but still having enough memory to represent the value.
+ Reported by Winfried Dreckmann in for instance <code>mpz_ui_pow_ui (x,
+ 4UL, 1431655766UL)</code>.
+<li> <code>mpf</code>: Detect exponent overflow and raise some exception.
+ It'd be nice to allow the full <code>mp_exp_t</code> range since that's
+ how it's been in the past, but maybe dropping one bit would make it
+ easier to test if e1+e2 goes out of bounds.
+</ul>
+
+
+
+<h4>Machine Independent Optimization</h4>
+<ul>
+<li> <code>mpf_cmp</code>: For better cache locality, don't test for low zero
+ limbs until the high limbs fail to give an ordering. Reduce code size by
+ turning the three <code>mpn_cmp</code>'s into a single loop stopping when
+ the end of one operand is reached (and then looking for a non-zero in the
+ rest of the other).
+<li> <code>mpf_mul_2exp</code>, <code>mpf_div_2exp</code>: The use of
+ <code>mpn_lshift</code> for any size&lt;=prec means repeated
+ <code>mul_2exp</code> and <code>div_2exp</code> calls accumulate low zero
+ limbs until size==prec+1 is reached. Those zeros will slow down
+ subsequent operations, especially if the value is otherwise only small.
+ If low bits of the low limb are zero, use <code>mpn_rshift</code> so as
+ to not increase the size.
+<li> <code>mpn_dc_sqrtrem</code>, <code>mpn_sqrtrem2</code>: Don't use
+ <code>mpn_add_1</code> and <code>mpn_sub_1</code> for 1 limb operations,
+ instead <code>ADDC_LIMB</code> and <code>SUBC_LIMB</code>.
+<li> <code>mpn_sqrtrem2</code>: Use plain variables for <code>sp[0]</code> and
+ <code>rp[0]</code> calculations, so the compiler needn't worry about
+ aliasing between <code>sp</code> and <code>rp</code>.
+<li> <code>mpn_sqrtrem</code>: Some work can be saved in the last step when
+ the remainder is not required, as noted in Paul's paper.
+<li> <code>mpq_add</code>, <code>mpq_sub</code>: The gcd fits a single limb
+ with high probability and in this case <code>binvert_limb</code> could
+ be used to calculate the inverse just once for the two exact divisions
+ "op1.den / gcd" and "op2.den / gcd", rather than letting
+ <code>mpn_bdiv_q_1</code> do it each time. This would require calling
+ <code>mpn_pi1_bdiv_q_1</code>.
+<li> <code>mpn_gcdext</code>: Don't test <code>count_leading_zeros</code> for
+ zero, instead check the high bit of the operand and avoid invoking
+ <code>count_leading_zeros</code>. This is an optimization on all
+ machines, and significant on machines with slow
+ <code>count_leading_zeros</code>, though it's possible an already
+ normalized operand might not be encountered very often.
+<li> Rewrite <code>umul_ppmm</code> to use floating-point for generating the
+ most significant limb (if <code>GMP_LIMB_BITS</code> &lt= 52 bits).
+ (Peter Montgomery has some ideas on this subject.)
+<li> Improve the default <code>umul_ppmm</code> code in longlong.h: Add partial
+ products with fewer operations.
+<li> Consider inlining <code>mpz_set_ui</code>. This would be both small and
+ fast, especially for compile-time constants, but would make application
+ binaries depend on having 1 limb allocated to an <code>mpz_t</code>,
+ preventing the "lazy" allocation scheme below.
+<li> Consider inlining <code>mpz_[cft]div_ui</code> and maybe
+ <code>mpz_[cft]div_r_ui</code>. A <code>__gmp_divide_by_zero</code>
+ would be needed for the divide by zero test, unless that could be left to
+ <code>mpn_mod_1</code> (not sure currently whether all the risc chips
+ provoke the right exception there if using mul-by-inverse).
+<li> Consider inlining: <code>mpz_fits_s*_p</code>. The setups for
+ <code>LONG_MAX</code> etc would need to go into gmp.h, and on Cray it
+ might, unfortunately, be necessary to forcibly include &lt;limits.h&gt;
+ since there's no apparent way to get <code>SHRT_MAX</code> with an
+ expression (since <code>short</code> and <code>unsigned short</code> can
+ be different sizes).
+<li> <code>mpz_powm</code> and <code>mpz_powm_ui</code> aren't very fast on one
+ or two limb moduli, due to a lot of function call overheads. These could
+ perhaps be handled as special cases.
+<li> Make sure <code>mpz_powm_ui</code> is never slower than the corresponding
+ computation using <code>mpz_powm</code>.
+<li> <code>mpz_powm</code> REDC should do multiplications by <code>g[]</code>
+ using the division method when they're small, since the REDC form of a
+ small multiplier is normally a full size product. Probably would need a
+ new tuned parameter to say what size multiplier is "small", as a function
+ of the size of the modulus.
+<li> <code>mpn_gcd</code> might be able to be sped up on small to moderate
+ sizes by improving <code>find_a</code>, possibly just by providing an
+ alternate implementation for CPUs with slowish
+ <code>count_leading_zeros</code>.
+<li> <code>mpf_set_str</code> produces low zero limbs when a string has a
+ fraction but is exactly representable, eg. 0.5 in decimal. These could be
+ stripped to save work in later operations.
+<li> <code>mpz_and</code>, <code>mpz_ior</code> and <code>mpz_xor</code> should
+ use <code>mpn_and_n</code> etc for the benefit of the small number of
+ targets with native versions of those routines. Need to be careful not to
+ pass size==0. Is some code sharing possible between the <code>mpz</code>
+ routines?
+<li> <code>mpf_add</code>: Don't do a copy to avoid overlapping operands
+ unless it's really necessary (currently only sizes are tested, not
+ whether r really is u or v).
+<li> <code>mpf_add</code>: Under the check for v having no effect on the
+ result, perhaps test for r==u and do nothing in that case, rather than
+ currently it looks like an <code>MPN_COPY_INCR</code> will be done to
+ reduce prec+1 limbs to prec.
+<li> <code>mpf_div_ui</code>: Instead of padding with low zeros, call
+ <code>mpn_divrem_1</code> asking for fractional quotient limbs.
+<li> <code>mpf_div_ui</code>: Eliminate <code>TMP_ALLOC</code>. When r!=u
+ there's no overlap and the division can be called on those operands.
+ When r==u and is prec+1 limbs, then it's an in-place division. If r==u
+ and not prec+1 limbs, then move the available limbs up to prec+1 and do
+ an in-place there.
+<li> <code>mpf_div_ui</code>: Whether the high quotient limb is zero can be
+ determined by testing the dividend for high&lt;divisor. When non-zero, the
+ division can be done on prec dividend limbs instead of prec+1. The result
+ size is also known before the division, so that can be a tail call (once
+ the <code>TMP_ALLOC</code> is eliminated).
+<li> <code>mpn_divrem_2</code> could usefully accept unnormalized divisors and
+ shift the dividend on-the-fly, since this should cost nothing on
+ superscalar processors and avoid the need for temporary copying in
+ <code>mpn_tdiv_qr</code>.
+<li> <code>mpf_sqrt</code>: If r!=u, and if u doesn't need to be padded with
+ zeros, then there's no need for the tp temporary.
+<li> <code>mpq_cmp_ui</code> could form the <code>num1*den2</code> and
+ <code>num2*den1</code> products limb-by-limb from high to low and look at
+ each step for values differing by more than the possible carry bit from
+ the uncalculated portion.
+<li> <code>mpq_cmp</code> could do the same high-to-low progressive multiply
+ and compare. The benefits of karatsuba and higher multiplication
+ algorithms are lost, but if it's assumed only a few high limbs will be
+ needed to determine an order then that's fine.
+<li> <code>mpn_add_1</code>, <code>mpn_sub_1</code>, <code>mpn_add</code>,
+ <code>mpn_sub</code>: Internally use <code>__GMPN_ADD_1</code> etc
+ instead of the functions, so they get inlined on all compilers, not just
+ gcc and others with <code>inline</code> recognised in gmp.h.
+ <code>__GMPN_ADD_1</code> etc are meant mostly to support application
+ inline <code>mpn_add_1</code> etc and if they don't come out good for
+ internal uses then special forms can be introduced, for instance many
+ internal uses are in-place. Sometimes a block of code is executed based
+ on the carry-out, rather than using it arithmetically, and those places
+ might want to do their own loops entirely.
+<li> <code>__gmp_extract_double</code> on 64-bit systems could use just one
+ bitfield for the mantissa extraction, not two, when endianness permits.
+ Might depend on the compiler allowing <code>long long</code> bit fields
+ when that's the only actual 64-bit type.
+<li> tal-notreent.c could keep a block of memory permanently allocated.
+ Currently the last nested <code>TMP_FREE</code> releases all memory, so
+ there's an allocate and free every time a top-level function using
+ <code>TMP</code> is called. Would need
+ <code>mp_set_memory_functions</code> to tell tal-notreent.c to release
+ any cached memory when changing allocation functions though.
+<li> <code>__gmp_tmp_alloc</code> from tal-notreent.c could be partially
+ inlined. If the current chunk has enough room then a couple of pointers
+ can be updated. Only if more space is required then a call to some sort
+ of <code>__gmp_tmp_increase</code> would be needed. The requirement that
+ <code>TMP_ALLOC</code> is an expression might make the implementation a
+ bit ugly and/or a bit sub-optimal.
+<pre>
+#define TMP_ALLOC(n)
+ ((ROUND_UP(n) &gt; current-&gt;end - current-&gt;point ?
+ __gmp_tmp_increase (ROUND_UP (n)) : 0),
+ current-&gt;point += ROUND_UP (n),
+ current-&gt;point - ROUND_UP (n))
+</pre>
+<li> <code>__mp_bases</code> has a lot of data for bases which are pretty much
+ never used. Perhaps the table should just go up to base 16, and have
+ code to generate data above that, if and when required. Naturally this
+ assumes the code would be smaller than the data saved.
+<li> <code>__mp_bases</code> field <code>big_base_inverted</code> is only used
+ if <code>USE_PREINV_DIVREM_1</code> is true, and could be omitted
+ otherwise, to save space.
+<li> <code>mpz_get_str</code>, <code>mtox</code>: For power-of-2 bases, which
+ are of course fast, it seems a little silly to make a second pass over
+ the <code>mpn_get_str</code> output to convert to ASCII. Perhaps combine
+ that with the bit extractions.
+<li> <code>mpz_gcdext</code>: If the caller requests only the S cofactor (of
+ A), and A&lt;B, then the code ends up generating the cofactor T (of B) and
+ deriving S from that. Perhaps it'd be possible to arrange to get S in
+ the first place by calling <code>mpn_gcdext</code> with A+B,B. This
+ might only be an advantage if A and B are about the same size.
+<li> <code>mpz_n_pow_ui</code> does a good job with small bases and stripping
+ powers of 2, but it's perhaps a bit too complicated for what it gains.
+ The simpler <code>mpn_pow_1</code> is a little faster on small exponents.
+ (Note some of the ugliness in <code>mpz_n_pow_ui</code> is due to
+ supporting <code>mpn_mul_2</code>.)
+ <br>
+ Perhaps the stripping of 2s in <code>mpz_n_pow_ui</code> should be
+ confined to single limb operands for simplicity and since that's where
+ the greatest gain would be.
+ <br>
+ Ideally <code>mpn_pow_1</code> and <code>mpz_n_pow_ui</code> would be
+ merged. The reason <code>mpz_n_pow_ui</code> writes to an
+ <code>mpz_t</code> is that its callers leave it to make a good estimate
+ of the result size. Callers of <code>mpn_pow_1</code> already know the
+ size by separate means (<code>mp_bases</code>).
+<li> <code>mpz_invert</code> should call <code>mpn_gcdext</code> directly.
+</ul>
+
+
+<h4>Machine Dependent Optimization</h4>
+<ul>
+<li> <code>invert_limb</code> on various processors might benefit from the
+ little Newton iteration done for alpha and ia64.
+<li> Alpha 21264: <code>mpn_addlsh1_n</code> could be implemented with
+ <code>mpn_addmul_1</code>, since that code at 3.5 is a touch faster than
+ a separate <code>lshift</code> and <code>add_n</code> at
+ 1.75+2.125=3.875. Or very likely some specific <code>addlsh1_n</code>
+ code could beat both.
+<li> Alpha 21264: Improve feed-in code for <code>mpn_mul_1</code>,
+ <code>mpn_addmul_1</code>, and <code>mpn_submul_1</code>.
+<li> Alpha 21164: Rewrite <code>mpn_mul_1</code>, <code>mpn_addmul_1</code>,
+ and <code>mpn_submul_1</code> for the 21164. This should use both integer
+ multiplies and floating-point multiplies. For the floating-point
+ operations, the single-limb multiplier should be split into three 21-bit
+ chunks, or perhaps even better in four 16-bit chunks. Probably possible
+ to reach 9 cycles/limb.
+<li> Alpha: GCC 3.4 will introduce <code>__builtin_ctzl</code>,
+ <code>__builtin_clzl</code> and <code>__builtin_popcountl</code> using
+ the corresponding CIX <code>ct</code> instructions, and
+ <code>__builtin_alpha_cmpbge</code>. These should give GCC more
+ information about scheduling etc than the <code>asm</code> blocks
+ currently used in longlong.h and gmp-impl.h.
+<li> Alpha Unicos: Apparently there's no <code>alloca</code> on this system,
+ making <code>configure</code> choose the slower
+ <code>malloc-reentrant</code> allocation method. Is there a better way?
+ Maybe variable-length arrays per notes below.
+<li> Alpha Unicos 21164, 21264: <code>.align</code> is not used since it pads
+ with garbage. Does the code get the intended slotting required for the
+ claimed speeds? <code>.align</code> at the start of a function would
+ presumably be safe no matter how it pads.
+<li> ARM V5: <code>count_leading_zeros</code> can use the <code>clz</code>
+ instruction. For GCC 3.4 and up, do this via <code>__builtin_clzl</code>
+ since then gcc knows it's "predicable".
+<li> Itanium: GCC 3.4 introduces <code>__builtin_popcount</code> which can be
+ used instead of an <code>asm</code> block. The builtin should give gcc
+ more opportunities for scheduling, bundling and predication.
+ <code>__builtin_ctz</code> similarly (it just uses popcount as per
+ current longlong.h).
+<li> UltraSPARC/64: Optimize <code>mpn_mul_1</code>, <code>mpn_addmul_1</code>,
+ for s2 &lt; 2^32 (or perhaps for any zero 16-bit s2 chunk). Not sure how
+ much this can improve the speed, though, since the symmetry that we rely
+ on is lost. Perhaps we can just gain cycles when s2 &lt; 2^16, or more
+ accurately, when two 16-bit s2 chunks which are 16 bits apart are zero.
+<li> UltraSPARC/64: Write native <code>mpn_submul_1</code>, analogous to
+ <code>mpn_addmul_1</code>.
+<li> UltraSPARC/64: Write <code>umul_ppmm</code>. Using four
+ "<code>mulx</code>"s either with an asm block or via the generic C code is
+ about 90 cycles. Try using fp operations, and also try using karatsuba
+ for just three "<code>mulx</code>"s.
+<li> UltraSPARC/32: Rewrite <code>mpn_lshift</code>, <code>mpn_rshift</code>.
+ Will give 2 cycles/limb. Trivial modifications of mpn/sparc64 should do.
+<li> UltraSPARC/32: Write special mpn_Xmul_1 loops for s2 &lt; 2^16.
+<li> UltraSPARC/32: Use <code>mulx</code> for <code>umul_ppmm</code> if
+ possible (see commented out code in longlong.h). This is unlikely to
+ save more than a couple of cycles, so perhaps isn't worth bothering with.
+<li> UltraSPARC/32: On Solaris gcc doesn't give us <code>__sparc_v9__</code>
+ or anything to indicate V9 support when -mcpu=v9 is selected. See
+ gcc/config/sol2-sld-64.h. Will need to pass something through from
+ ./configure to select the right code in longlong.h. (Currently nothing
+ is lost because <code>mulx</code> for multiplying is commented out.)
+<li> UltraSPARC/32: <code>mpn_divexact_1</code> and
+ <code>mpn_modexact_1c_odd</code> can use a 64-bit inverse and take
+ 64-bits at a time from the dividend, as per the 32-bit divisor case in
+ mpn/sparc64/mode1o.c. This must be done in assembler, since the full
+ 64-bit registers (<code>%gN</code>) are not available from C.
+<li> UltraSPARC/32: <code>mpn_divexact_by3c</code> can work 64-bits at a time
+ using <code>mulx</code>, in assembler. This would be the same as for
+ sparc64.
+<li> UltraSPARC: <code>binvert_limb</code> might save a few cycles from
+ masking down to just the useful bits at each point in the calculation,
+ since <code>mulx</code> speed depends on the highest bit set. Either
+ explicit masks or small types like <code>short</code> and
+ <code>int</code> ought to work.
+<li> Sparc64 HAL R1 <code>popc</code>: This chip reputedly implements
+ <code>popc</code> properly (see gcc sparc.md). Would need to recognise
+ it as <code>sparchalr1</code> or something in configure / config.sub /
+ config.guess. <code>popc_limb</code> in gmp-impl.h could use this (per
+ commented out code). <code>count_trailing_zeros</code> could use it too.
+<li> PA64: Improve <code>mpn_addmul_1</code>, <code>mpn_submul_1</code>, and
+ <code>mpn_mul_1</code>. The current code runs at 11 cycles/limb. It
+ should be possible to saturate the cache, which will happen at 8
+ cycles/limb (7.5 for mpn_mul_1). Write special loops for s2 &lt; 2^32;
+ it should be possible to make them run at about 5 cycles/limb.
+<li> PPC601: See which of the power or powerpc32 code runs better. Currently
+ the powerpc32 is used, but only because it's the default for
+ <code>powerpc*</code>.
+<li> PPC630: Rewrite <code>mpn_addmul_1</code>, <code>mpn_submul_1</code>, and
+ <code>mpn_mul_1</code>. Use both integer and floating-point operations,
+ possibly two floating-point and one integer limb per loop. Split operands
+ into four 16-bit chunks for fast fp operations. Should easily reach 9
+ cycles/limb (using one int + one fp), but perhaps even 7 cycles/limb
+ (using one int + two fp).
+<li> PPC630: <code>mpn_rshift</code> could do the same sort of unrolled loop
+ as <code>mpn_lshift</code>. Some judicious use of m4 might let the two
+ share source code, or with a register to control the loop direction
+ perhaps even share object code.
+<li> Implement <code>mpn_mul_basecase</code> and <code>mpn_sqr_basecase</code>
+ for important machines. Helping the generic sqr_basecase.c with an
+ <code>mpn_sqr_diagonal</code> might be enough for some of the RISCs.
+<li> POWER2/POWER2SC: Schedule <code>mpn_lshift</code>/<code>mpn_rshift</code>.
+ Will bring time from 1.75 to 1.25 cycles/limb.
+<li> X86: Optimize non-MMX <code>mpn_lshift</code> for shifts by 1. (See
+ Pentium code.)
+<li> X86: Good authority has it that in the past an inline <code>rep
+ movs</code> would upset GCC register allocation for the whole function.
+ Is this still true in GCC 3? It uses <code>rep movs</code> itself for
+ <code>__builtin_memcpy</code>. Examine the code for some simple and
+ complex functions to find out. Inlining <code>rep movs</code> would be
+ desirable, it'd be both smaller and faster.
+<li> Pentium P54: <code>mpn_lshift</code> and <code>mpn_rshift</code> can come
+ down from 6.0 c/l to 5.5 or 5.375 by paying attention to pairing after
+ <code>shrdl</code> and <code>shldl</code>, see mpn/x86/pentium/README.
+<li> Pentium P55 MMX: <code>mpn_lshift</code> and <code>mpn_rshift</code>
+ might benefit from some destination prefetching.
+<li> PentiumPro: <code>mpn_divrem_1</code> might be able to use a
+ mul-by-inverse, hoping for maybe 30 c/l.
+<li> K7: <code>mpn_lshift</code> and <code>mpn_rshift</code> might be able to
+ do something branch-free for unaligned startups, and shaving one insn
+ from the loop with alternative indexing might save a cycle.
+<li> PPC32: Try using fewer registers in the current <code>mpn_lshift</code>.
+ The pipeline is now extremely deep, perhaps unnecessarily deep.
+<li> Fujitsu VPP: Vectorize main functions, perhaps in assembly language.
+<li> Fujitsu VPP: Write <code>mpn_mul_basecase</code> and
+ <code>mpn_sqr_basecase</code>. This should use a "vertical multiplication
+ method", to avoid carry propagation. splitting one of the operands in
+ 11-bit chunks.
+<li> Pentium: <code>mpn_lshift</code> by 31 should use the special rshift
+ by 1 code, and vice versa <code>mpn_rshift</code> by 31 should use the
+ special lshift by 1. This would be best as a jump across to the other
+ routine, could let both live in lshift.asm and omit rshift.asm on finding
+ <code>mpn_rshift</code> already provided.
+<li> Cray T3E: Experiment with optimization options. In particular,
+ -hpipeline3 seems promising. We should at least up -O to -O2 or -O3.
+<li> Cray: <code>mpn_com</code> and <code>mpn_and_n</code> etc very probably
+ wants a pragma like <code>MPN_COPY_INCR</code>.
+<li> Cray vector systems: <code>mpn_lshift</code>, <code>mpn_rshift</code>,
+ <code>mpn_popcount</code> and <code>mpn_hamdist</code> are nice and small
+ and could be inlined to avoid function calls.
+<li> Cray: Variable length arrays seem to be faster than the tal-notreent.c
+ scheme. Not sure why, maybe they merely give the compiler more
+ information about aliasing (or the lack thereof). Would like to modify
+ <code>TMP_ALLOC</code> to use them, or introduce a new scheme. Memory
+ blocks wanted unconditionally are easy enough, those wanted only
+ sometimes are a problem. Perhaps a special size calculation to ask for a
+ dummy length 1 when unwanted, or perhaps an inlined subroutine
+ duplicating code under each conditional. Don't really want to turn
+ everything into a dog's dinner just because Cray don't offer an
+ <code>alloca</code>.
+<li> Cray: <code>mpn_get_str</code> on power-of-2 bases ought to vectorize.
+ Does it? <code>bits_per_digit</code> and the inner loop over bits in a
+ limb might prevent it. Perhaps special cases for binary, octal and hex
+ would be worthwhile (very possibly for all processors too).
+<li> S390: <code>BSWAP_LIMB_FETCH</code> looks like it could be done with
+ <code>lrvg</code>, as per glibc sysdeps/s390/s390-64/bits/byteswap.h.
+ This is only for 64-bit mode or something is it, since 32-bit mode has
+ other code? Also, is it worth using for <code>BSWAP_LIMB</code> too, or
+ would that mean a store and re-fetch? Presumably that's what comes out
+ in glibc.
+<li> Improve <code>count_leading_zeros</code> for 64-bit machines:
+ <pre>
+ if ((x &gt&gt 32) == 0) { x &lt&lt= 32; cnt += 32; }
+ if ((x &gt&gt 48) == 0) { x &lt&lt= 16; cnt += 16; }
+ ... </pre>
+<li> IRIX 6 MIPSpro compiler has an <code>__inline</code> which could perhaps
+ be used in <code>__GMP_EXTERN_INLINE</code>. What would be the right way
+ to identify suitable versions of that compiler?
+<li> IRIX <code>cc</code> is rumoured to have an <code>_int_mult_upper</code>
+ (in <code>&lt;intrinsics.h&gt;</code> like Cray), but it didn't seem to
+ exist on some IRIX 6.5 systems tried. If it does actually exist
+ somewhere it would very likely be an improvement over a function call to
+ umul.asm.
+<li> <code>mpn_get_str</code> final divisions by the base with
+ <code>udiv_qrnd_unnorm</code> could use some sort of multiply-by-inverse
+ on suitable machines. This ends up happening for decimal by presenting
+ the compiler with a run-time constant, but the same for other bases would
+ be good. Perhaps use could be made of the fact base&lt;256.
+<li> <code>mpn_umul_ppmm</code>, <code>mpn_udiv_qrnnd</code>: Return a
+ structure like <code>div_t</code> to avoid going through memory, in
+ particular helping RISCs that don't do store-to-load forwarding. Clearly
+ this is only possible if the ABI returns a structure of two
+ <code>mp_limb_t</code>s in registers.
+ <br>
+ On PowerPC, structures are returned in memory on AIX and Darwin. In SVR4
+ they're returned in registers, except that draft SVR4 had said memory, so
+ it'd be prudent to check which is done. We can jam the compiler into the
+ right mode if we know how, since all this is purely internal to libgmp.
+ (gcc has an option, though of course gcc doesn't matter since we use
+ inline asm there.)
+</ul>
+
+<h4>New Functionality</h4>
+<ul>
+<li> Maybe add <code>mpz_crr</code> (Chinese Remainder Reconstruction).
+<li> Let `0b' and `0B' mean binary input everywhere.
+<li> <code>mpz_init</code> and <code>mpq_init</code> could do lazy allocation.
+ Set <code>ALLOC(var)</code> to 0 to indicate nothing allocated, and let
+ <code>_mpz_realloc</code> do the initial alloc. Set
+ <code>z-&gt;_mp_d</code> to a dummy that <code>mpz_get_ui</code> and
+ similar can unconditionally fetch from. Niels Möller has had a go at
+ this.
+ <br>
+ The advantages of the lazy scheme would be:
+ <ul>
+ <li> Initial allocate would be the size required for the first value
+ stored, rather than getting 1 limb in <code>mpz_init</code> and then
+ more or less immediately reallocating.
+ <li> <code>mpz_init</code> would only store magic values in the
+ <code>mpz_t</code> fields, and could be inlined.
+ <li> A fixed initializer could even be used by applications, like
+ <code>mpz_t z = MPZ_INITIALIZER;</code>, which might be convenient
+ for globals.
+ </ul>
+ The advantages of the current scheme are:
+ <ul>
+ <li> <code>mpz_set_ui</code> and other similar routines needn't check the
+ size allocated and can just store unconditionally.
+ <li> <code>mpz_set_ui</code> and perhaps others like
+ <code>mpz_tdiv_r_ui</code> and a prospective
+ <code>mpz_set_ull</code> could be inlined.
+ </ul>
+<li> Add <code>mpf_out_raw</code> and <code>mpf_inp_raw</code>. Make sure
+ format is portable between 32-bit and 64-bit machines, and between
+ little-endian and big-endian machines. A format which MPFR can use too
+ would be good.
+<li> <code>mpn_and_n</code> ... <code>mpn_copyd</code>: Perhaps make the mpn
+ logops and copys available in gmp.h, either as library functions or
+ inlines, with the availability of library functions instantiated in the
+ generated gmp.h at build time.
+<li> <code>mpz_set_str</code> etc variants taking string lengths rather than
+ null-terminators.
+<li> <code>mpz_andn</code>, <code>mpz_iorn</code>, <code>mpz_nand</code>,
+ <code>mpz_nior</code>, <code>mpz_xnor</code> might be useful additions,
+ if they could share code with the current such functions (which should be
+ possible).
+<li> <code>mpz_and_ui</code> etc might be of use sometimes. Suggested by
+ Niels Möller.
+<li> <code>mpf_set_str</code> and <code>mpf_inp_str</code> could usefully
+ accept 0x, 0b etc when base==0. Perhaps the exponent could default to
+ decimal in this case, with a further 0x, 0b etc allowed there.
+ Eg. 0xFFAA@0x5A. A leading "0" for octal would match the integers, but
+ probably something like "0.123" ought not mean octal.
+<li> <code>GMP_LONG_LONG_LIMB</code> or some such could become a documented
+ feature of gmp.h, so applications could know whether to
+ <code>printf</code> a limb using <code>%lu</code> or <code>%Lu</code>.
+<li> <code>GMP_PRIdMP_LIMB</code> and similar defines following C99
+ &lt;inttypes.h&gt; might be of use to applications printing limbs. But
+ if <code>GMP_LONG_LONG_LIMB</code> or whatever is added then perhaps this
+ can easily enough be left to applications.
+<li> <code>gmp_printf</code> could accept <code>%b</code> for binary output.
+ It'd be nice if it worked for plain <code>int</code> etc too, not just
+ <code>mpz_t</code> etc.
+<li> <code>gmp_printf</code> in fact could usefully accept an arbitrary base,
+ for both integer and float conversions. A base either in the format
+ string or as a parameter with <code>*</code> should be allowed. Maybe
+ <code>&amp;13b</code> (b for base) or something like that.
+<li> <code>gmp_printf</code> could perhaps accept <code>mpq_t</code> for float
+ conversions, eg. <code>"%.4Qf"</code>. This would be merely for
+ convenience, but still might be useful. Rounding would be the same as
+ for an <code>mpf_t</code> (ie. currently round-to-nearest, but not
+ actually documented). Alternately, perhaps a separate
+ <code>mpq_get_str_point</code> or some such might be more use. Suggested
+ by Pedro Gimeno.
+<li> <code>mpz_rscan0</code> or <code>mpz_revscan0</code> or some such
+ searching towards the low end of an integer might match
+ <code>mpz_scan0</code> nicely. Likewise for <code>scan1</code>.
+ Suggested by Roberto Bagnara.
+<li> <code>mpz_bit_subset</code> or some such to test whether one integer is a
+ bitwise subset of another might be of use. Some sort of return value
+ indicating whether it's a proper or non-proper subset would be good and
+ wouldn't cost anything in the implementation. Suggested by Roberto
+ Bagnara.
+<li> <code>mpf_get_ld</code>, <code>mpf_set_ld</code>: Conversions between
+ <code>mpf_t</code> and <code>long double</code>, suggested by Dan
+ Christensen. Other <code>long double</code> routines might be desirable
+ too, but <code>mpf</code> would be a start.
+ <br>
+ <code>long double</code> is an ANSI-ism, so everything involving it would
+ need to be suppressed on a K&amp;R compiler.
+ <br>
+ There'd be some work to be done by <code>configure</code> to recognise
+ the format in use, MPFR has a start on this. Often <code>long
+ double</code> is the same as <code>double</code>, which is easy but
+ pretty pointless. A single float format detector macro could look at
+ <code>double</code> then <code>long double</code>
+ <br>
+ Sometimes there's a compiler option for the size of a <code>long
+ double</code>, eg. xlc on AIX can use either 64-bit or 128-bit. It's
+ probably simplest to regard this as a compiler compatibility issue, and
+ leave it to users or sysadmins to ensure application and library code is
+ built the same.
+<li> <code>mpz_sqrt_if_perfect_square</code>: When
+ <code>mpz_perfect_square_p</code> does its tests it calculates a square
+ root and then discards it. For some applications it might be useful to
+ return that root. Suggested by Jason Moxham.
+<li> <code>mpz_get_ull</code>, <code>mpz_set_ull</code>,
+ <code>mpz_get_sll</code>, <code>mpz_get_sll</code>: Conversions for
+ <code>long long</code>. These would aid interoperability, though a
+ mixture of GMP and <code>long long</code> would probably not be too
+ common. Since <code>long long</code> is not always available (it's in
+ C99 and GCC though), disadvantages of using <code>long long</code> in
+ libgmp.a would be
+ <ul>
+ <li> Library contents vary according to the build compiler.
+ <li> gmp.h would need an ugly <code>#ifdef</code> block to decide if the
+ application compiler could take the <code>long long</code>
+ prototypes.
+ <li> Some sort of <code>LIBGMP_HAS_LONGLONG</code> might be wanted to
+ indicate whether the functions are available. (Applications using
+ autoconf could probe the library too.)
+ </ul>
+ It'd be possible to defer the need for <code>long long</code> to
+ application compile time, by having something like
+ <code>mpz_set_2ui</code> called with two halves of a <code>long
+ long</code>. Disadvantages of this would be,
+ <ul>
+ <li> Bigger code in the application, though perhaps not if a <code>long
+ long</code> is normally passed as two halves anyway.
+ <li> <code>mpz_get_ull</code> would be a rather big inline, or would have
+ to be two function calls.
+ <li> <code>mpz_get_sll</code> would be a worse inline, and would put the
+ treatment of <code>-0x10..00</code> into applications (see
+ <code>mpz_get_si</code> correctness above).
+ <li> Although having libgmp.a independent of the build compiler is nice,
+ it sort of sacrifices the capabilities of a good compiler to
+ uniformity with inferior ones.
+ </ul>
+ Plain use of <code>long long</code> is probably the lesser evil, if only
+ because it makes best use of gcc. In fact perhaps it would suffice to
+ guarantee <code>long long</code> conversions only when using GCC for both
+ application and library. That would cover free software, and we can
+ worry about selected vendor compilers later.
+ <br>
+ In C++ the situation is probably clearer, we demand fairly recent C++ so
+ <code>long long</code> should be available always. We'd probably prefer
+ to have the C and C++ the same in respect of <code>long long</code>
+ support, but it would be possible to have it unconditionally in gmpxx.h,
+ by some means or another.
+<li> <code>mpz_strtoz</code> parsing the same as <code>strtol</code>.
+ Suggested by Alexander Kruppa.
+</ul>
+
+
+<h4>Configuration</h4>
+
+<ul>
+<li> Alpha ev7, ev79: Add code to config.guess to detect these. Believe ev7
+ will be "3-1307" in the current switch, but need to verify that. (On
+ OSF, current configfsf.guess identifies ev7 using psrinfo, we need to do
+ it ourselves for other systems.)
+<li> Alpha OSF: Libtool (version 1.5) doesn't seem to recognise this system is
+ "pic always" and ends up running gcc twice with the same options. This
+ is wasteful, but harmless. Perhaps a newer libtool will be better.
+<li> ARM: <code>umul_ppmm</code> in longlong.h always uses <code>umull</code>,
+ but is that available only for M series chips or some such? Perhaps it
+ should be configured in some way.
+<li> HPPA: config.guess should recognize 7000, 7100, 7200, and 8x00.
+<li> HPPA: gcc 3.2 introduces a <code>-mschedule=7200</code> etc parameter,
+ which could be driven by an exact hppa cpu type.
+<li> Mips: config.guess should say mipsr3000, mipsr4000, mipsr10000, etc.
+ "hinv -c processor" gives lots of information on Irix. Standard
+ config.guess appends "el" to indicate endianness, but
+ <code>AC_C_BIGENDIAN</code> seems the best way to handle that for GMP.
+<li> PowerPC: The function descriptor nonsense for AIX is currently driven by
+ <code>*-*-aix*</code>. It might be more reliable to do some sort of
+ feature test, examining the compiler output perhaps. It might also be
+ nice to merge the aix.m4 files into powerpc-defs.m4.
+<li> config.m4 is generated only by the configure script, it won't be
+ regenerated by config.status. Creating it as an <code>AC_OUTPUT</code>
+ would work, but it might upset "make" to have things like <code>L$</code>
+ get into the Makefiles through <code>AC_SUBST</code>.
+ <code>AC_CONFIG_COMMANDS</code> would be the alternative. With some
+ careful m4 quoting the <code>changequote</code> calls might not be
+ needed, which might free up the order in which things had to be output.
+<li> Automake: Latest automake has a <code>CCAS</code>, <code>CCASFLAGS</code>
+ scheme. Though we probably wouldn't be using its assembler support we
+ could try to use those variables in compatible ways.
+<li> <code>GMP_LDFLAGS</code> could probably be done with plain
+ <code>LDFLAGS</code> already used by automake for all linking. But with
+ a bit of luck the next libtool will pass pretty much all
+ <code>CFLAGS</code> through to the compiler when linking, making
+ <code>GMP_LDFLAGS</code> unnecessary.
+<li> mpn/Makeasm.am uses <code>-c</code> and <code>-o</code> together in the
+ .S and .asm rules, but apparently that isn't completely portable (there's
+ an autoconf <code>AC_PROG_CC_C_O</code> test for it). So far we've not
+ had problems, but perhaps the rules could be rewritten to use "foo.s" as
+ the temporary, or to do a suitable "mv" of the result. The only danger
+ from using foo.s would be if a compile failed and the temporary foo.s
+ then looked like the primary source. Hopefully if the
+ <code>SUFFIXES</code> are ordered to have .S and .asm ahead of .s that
+ wouldn't happen. Might need to check.
+</ul>
+
+
+<h4>Random Numbers</h4>
+<ul>
+<li> <code>_gmp_rand</code> is not particularly fast on the linear
+ congruential algorithm and could stand various improvements.
+ <ul>
+ <li> Make a second seed area within <code>gmp_randstate_t</code> (or
+ <code>_mp_algdata</code> rather) to save some copying.
+ <li> Make a special case for a single limb <code>2exp</code> modulus, to
+ avoid <code>mpn_mul</code> calls. Perhaps the same for two limbs.
+ <li> Inline the <code>lc</code> code, to avoid a function call and
+ <code>TMP_ALLOC</code> for every chunk.
+ <li> Perhaps the <code>2exp</code> and general LC cases should be split,
+ for clarity (if the general case is retained).
+ </ul>
+<li> <code>gmp_randstate_t</code> used for parameters perhaps should become
+ <code>gmp_randstate_ptr</code> the same as other types.
+<li> Some of the empirical randomness tests could be included in a "make
+ check". They ought to work everywhere, for a given seed at least.
+</ul>
+
+
+<h4>C++</h4>
+<ul>
+<li> <code>mpz_class(string)</code>, etc: Use the C++ global locale to
+ identify whitespace.
+ <br>
+ <code>mpf_class(string)</code>: Use the C++ global locale decimal point,
+ rather than the C one.
+ <br>
+ Consider making these variant <code>mpz_set_str</code> etc forms
+ available for <code>mpz_t</code> too, not just <code>mpz_class</code>
+ etc.
+<li> <code>mpq_class operator+=</code>: Don't emit an unnecessary
+ <code>mpq_set(q,q)</code> before <code>mpz_addmul</code> etc.
+<li> Put various bits of gmpxx.h into libgmpxx, to avoid excessive inlining.
+ Candidates for this would be,
+ <ul>
+ <li> <code>mpz_class(const char *)</code>, etc: since they're normally
+ not fast anyway, and we can hide the exception <code>throw</code>.
+ <li> <code>mpz_class(string)</code>, etc: to hide the <code>cstr</code>
+ needed to get to the C conversion function.
+ <li> <code>mpz_class string, char*</code> etc constructors: likewise to
+ hide the throws and conversions.
+ <li> <code>mpz_class::get_str</code>, etc: to hide the <code>char*</code>
+ to <code>string</code> conversion and free. Perhaps
+ <code>mpz_get_str</code> can write directly into a
+ <code>string</code>, to avoid copying.
+ <br>
+ Consider making such <code>string</code> returning variants
+ available for use with plain <code>mpz_t</code> etc too.
+ </ul>
+</ul>
+
+<h4>Miscellaneous</h4>
+<ul>
+<li> <code>mpz_gcdext</code> and <code>mpn_gcdext</code> ought to document
+ what range of values the generated cofactors can take, and preferably
+ ensure the definition uniquely specifies the cofactors for given inputs.
+ A basic extended Euclidean algorithm or multi-step variant leads to
+ |x|&lt;|b| and |y|&lt;|a| or something like that, but there's probably
+ two solutions under just those restrictions.
+<li> demos/factorize.c: use <code>mpz_divisible_ui_p</code> rather than
+ <code>mpz_tdiv_qr_ui</code>. (Of course dividing multiple primes at a
+ time would be better still.)
+<li> The various test programs use quite a bit of the main
+ <code>libgmp</code>. This establishes good cross-checks, but it might be
+ better to use simple reference routines where possible. Where it's not
+ possible some attention could be paid to the order of the tests, so a
+ <code>libgmp</code> routine is only used for tests once it seems to be
+ good.
+<li> <code>MUL_FFT_THRESHOLD</code> etc: the FFT thresholds should allow a
+ return to a previous k at certain sizes. This arises basically due to
+ the step effect caused by size multiples effectively used for each k.
+ Looking at a graph makes it fairly clear.
+<li> <code>__gmp_doprnt_mpf</code> does a rather unattractive round-to-nearest
+ on the string returned by <code>mpf_get_str</code>. Perhaps some variant
+ of <code>mpf_get_str</code> could be made which would better suit.
+</ul>
+
+
+<h4>Aids to Development</h4>
+<ul>
+<li> Add <code>ASSERT</code>s at the start of each user-visible mpz/mpq/mpf
+ function to check the validity of each <code>mp?_t</code> parameter, in
+ particular to check they've been <code>mp?_init</code>ed. This might
+ catch elementary mistakes in user programs. Care would need to be taken
+ over <code>MPZ_TMP_INIT</code>ed variables used internally. If nothing
+ else then consistency checks like size&lt;=alloc, ptr not
+ <code>NULL</code> and ptr+size not wrapping around the address space,
+ would be possible. A more sophisticated scheme could track
+ <code>_mp_d</code> pointers and ensure only a valid one is used. Such a
+ scheme probably wouldn't be reentrant, not without some help from the
+ system.
+<li> tune/time.c could try to determine at runtime whether
+ <code>getrusage</code> and <code>gettimeofday</code> are reliable.
+ Currently we pretend in configure that the dodgy m68k netbsd 1.4.1
+ <code>getrusage</code> doesn't exist. If a test might take a long time
+ to run then perhaps cache the result in a file somewhere.
+<li> tune/time.c could choose the default precision based on the
+ <code>speed_unittime</code> determined, independent of the method in use.
+<li> Cray vector systems: CPU frequency could be determined from
+ <code>sysconf(_SC_CLK_TCK)</code>, since it seems to be clock cycle
+ based. Is this true for all Cray systems? Would like some documentation
+ or something to confirm.
+</ul>
+
+
+<h4>Documentation</h4>
+<ul>
+<li> <code>mpz_inp_str</code> (etc) doesn't say when it stops reading digits.
+<li> <code>mpn_get_str</code> isn't terribly clear about how many digits it
+ produces. It'd probably be possible to say at most one leading zero,
+ which is what both it and <code>mpz_get_str</code> currently do. But
+ want to be careful not to bind ourselves to something that might not suit
+ another implementation.
+<li> <code>va_arg</code> doesn't do the right thing with <code>mpz_t</code>
+ etc directly, but instead needs a pointer type like <code>MP_INT*</code>.
+ It'd be good to show how to do this, but we'd either need to document
+ <code>mpz_ptr</code> and friends, or perhaps fallback on something
+ slightly nasty with <code>void*</code>.
+</ul>
+
+
+<h4>Bright Ideas</h4>
+
+<p> The following may or may not be feasible, and aren't likely to get done in the
+near future, but are at least worth thinking about.
+
+<ul>
+<li> Reorganize longlong.h so that we can inline the operations even for the
+ system compiler. When there is no such compiler feature, make calls to
+ stub functions. Write such stub functions for as many machines as
+ possible.
+<li> longlong.h could declare when it's using, or would like to use,
+ <code>mpn_umul_ppmm</code>, and the corresponding umul.asm file could be
+ included in libgmp only in that case, the same as is effectively done for
+ <code>__clz_tab</code>. Likewise udiv.asm and perhaps cntlz.asm. This
+ would only be a very small space saving, so perhaps not worth the
+ complexity.
+<li> longlong.h could be built at configure time by concatenating or
+ #including fragments from each directory in the mpn path. This would
+ select CPU specific macros the same way as CPU specific assembler code.
+ Code used would no longer depend on cpp predefines, and the current
+ nested conditionals could be flattened out.
+<li> <code>mpz_get_si</code> returns 0x80000000 for -0x100000000, whereas it's
+ sort of supposed to return the low 31 (or 63) bits. But this is
+ undocumented, and perhaps not too important.
+<li> <code>mpz_init_set*</code> and <code>mpz_realloc</code> could allocate
+ say an extra 16 limbs over what's needed, so as to reduce the chance of
+ having to do a reallocate if the <code>mpz_t</code> grows a bit more.
+ This could only be an option, since it'd badly bloat memory usage in
+ applications using many small values.
+<li> <code>mpq</code> functions could perhaps check for numerator or
+ denominator equal to 1, on the assumption that integers or
+ denominator-only values might be expected to occur reasonably often.
+<li> <code>count_trailing_zeros</code> is used on more or less uniformly
+ distributed numbers in a couple of places. For some CPUs
+ <code>count_trailing_zeros</code> is slow and it's probably worth handling
+ the frequently occurring 0 to 2 trailing zeros cases specially.
+<li> <code>mpf_t</code> might like to let the exponent be undefined when
+ size==0, instead of requiring it 0 as now. It should be possible to do
+ size==0 tests before paying attention to the exponent. The advantage is
+ not needing to set exp in the various places a zero result can arise,
+ which avoids some tedium but is otherwise perhaps not too important.
+ Currently <code>mpz_set_f</code> and <code>mpf_cmp_ui</code> depend on
+ exp==0, maybe elsewhere too.
+<li> <code>__gmp_allocate_func</code>: Could use GCC <code>__attribute__
+ ((malloc))</code> on this, though don't know if it'd do much. GCC 3.0
+ allows that attribute on functions, but not function pointers (see info
+ node "Attribute Syntax"), so would need a new autoconf test. This can
+ wait until there's a GCC that supports it.
+<li> <code>mpz_add_ui</code> contains two <code>__GMPN_COPY</code>s, one from
+ <code>mpn_add_1</code> and one from <code>mpn_sub_1</code>. If those two
+ routines were opened up a bit maybe that code could be shared. When a
+ copy needs to be done there's no carry to append for the add, and if the
+ copy is non-empty no high zero for the sub.
+</ul>
+
+
+<h4>Old and Obsolete Stuff</h4>
+
+<p> The following tasks apply to chips or systems that are old and/or obsolete.
+It's unlikely anything will be done about them unless anyone is actively using
+them.
+
+<ul>
+<li> Sparc32: The integer based udiv_nfp.asm used to be selected by
+ <code>configure --nfp</code> but that option is gone now that autoconf is
+ used. The file could go somewhere suitable in the mpn search if any
+ chips might benefit from it, though it's possible we don't currently
+ differentiate enough exact cpu types to do this properly.
+<li> VAX D and G format <code>double</code> floats are straightforward and
+ could perhaps be handled directly in <code>__gmp_extract_double</code>
+ and maybe in <code>mpn_get_d</code>, rather than falling back on the
+ generic code. (Both formats are detected by <code>configure</code>.)
+</ul>
+
+
+<hr>
+
+</body>
+</html>
+
+<!--
+Local variables:
+eval: (add-hook 'write-file-hooks 'time-stamp)
+time-stamp-start: "This file current as of "
+time-stamp-format: "%:d %3b %:y"
+time-stamp-end: "\\."
+time-stamp-line-limit: 50
+End:
+-->
diff --git a/gmp/doc/texinfo.tex b/gmp/doc/texinfo.tex
new file mode 100644
index 0000000000..85f184cc4c
--- /dev/null
+++ b/gmp/doc/texinfo.tex
@@ -0,0 +1,10079 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2013-02-01.11}
+%
+% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+%
+% This texinfo.tex file is free software: you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation, either version 3 of the
+% License, or (at your option) any later version.
+%
+% This texinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction. This Exception is an additional permission under section 7
+% of the GNU General Public License, version 3 ("GPLv3").
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or
+% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page)
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org. Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem. Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution. For a simple
+% manual foo.texi, however, you can get away with this:
+% tex foo.texi
+% texindex foo.??
+% tex foo.texi
+% tex foo.texi
+% dvips foo.dvi -o # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent. You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexraggedright=\raggedright
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+\let\ptextop=\top
+{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Pre-3.0.
+\else
+ \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putworderror\undefined \gdef\putworderror{error}\fi
+\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\ampChar = `\&
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar = `\-
+\chardef\dotChar = `\.
+\chardef\exclamChar= `\!
+\chardef\hashChar = `\#
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar = `\;
+\chardef\slashChar = `\/
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+ ap-pen-dix bit-map bit-maps
+ data-base data-bases eshell fall-ing half-way long-est man-u-script
+ man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+ par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+ spell-ing spell-ings
+ stand-alone strong-est time-stamp time-stamps which-ever white-space
+ wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt }
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal. We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+ \tracingstats2
+ \tracingpages1
+ \tracinglostchars2 % 2 gives us more in etex
+ \tracingparagraphs1
+ \tracingoutput1
+ \tracingmacros2
+ \tracingrestores1
+ \showboxbreadth\maxdimen \showboxdepth\maxdimen
+ \ifx\eTeXversion\thisisundefined\else % etex gives us more logging
+ \tracingscantokens1
+ \tracingifs1
+ \tracinggroups1
+ \tracingnesting2
+ \tracingassigns1
+ \fi
+ \tracingcommands3 % 3 gives us more in etex
+ \errorcontextlines16
+}%
+
+% @errormsg{MSG}. Do the index-like expansions on MSG, but if things
+% aren't perfect, it's not the end of the world, being an error message,
+% after all.
+%
+\def\errormsg{\begingroup \indexnofonts \doerrormsg}
+\def\doerrormsg#1{\errmessage{#1}}
+
+% add check for \lastpenalty to plain's definitions. If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+ \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+ \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+ \removelastskip\penalty-200\bigskip\fi\fi}
+
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Output a mark which sets \thischapter, \thissection and \thiscolor.
+% We dump everything together because we only have one kind of mark.
+% This works because we only use \botmark / \topmark, not \firstmark.
+%
+% A mark contains a subexpression of the \ifcase ... \fi construct.
+% \get*marks macros below extract the needed part using \ifcase.
+%
+% Another complication is to let the user choose whether \thischapter
+% (\thissection) refers to the chapter (section) in effect at the top
+% of a page, or that at the bottom of a page. The solution is
+% described on page 260 of The TeXbook. It involves outputting two
+% marks for the sectioning macros, one before the section break, and
+% one after. I won't pretend I can describe this better than DEK...
+\def\domark{%
+ \toks0=\expandafter{\lastchapterdefs}%
+ \toks2=\expandafter{\lastsectiondefs}%
+ \toks4=\expandafter{\prevchapterdefs}%
+ \toks6=\expandafter{\prevsectiondefs}%
+ \toks8=\expandafter{\lastcolordefs}%
+ \mark{%
+ \the\toks0 \the\toks2
+ \noexpand\or \the\toks4 \the\toks6
+ \noexpand\else \the\toks8
+ }%
+}
+% \topmark doesn't work for the very first chapter (after the title
+% page or the contents), so we use \firstmark there -- this gets us
+% the mark with the chapter defs, unless the user sneaks in, e.g.,
+% @setcolor (or @url, or @link, etc.) between @contents and the very
+% first @chapter.
+\def\gettopheadingmarks{%
+ \ifcase0\topmark\fi
+ \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
+}
+\def\getbottomheadingmarks{\ifcase1\botmark\fi}
+\def\getcolormarks{\ifcase2\topmark\fi}
+
+% Avoid "undefined control sequence" errors.
+\def\lastchapterdefs{}
+\def\lastsectiondefs{}
+\def\prevchapterdefs{}
+\def\prevsectiondefs{}
+\def\lastcolordefs{}
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+ %
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
+ \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ % We don't want .vr (or whatever) entries like this:
+ % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+ % "\acronym" won't work when it's read back in;
+ % it needs to be
+ % {\code {{\tt \backslashcurfont }acronym}
+ \shipout\vbox{%
+ % Do this early so pdf references go to the beginning of the page.
+ \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+ %
+ \ifcropmarks \vbox to \outervsize\bgroup
+ \hsize = \outerhsize
+ \vskip-\topandbottommargin
+ \vtop to0pt{%
+ \line{\ewtop\hfil\ewtop}%
+ \nointerlineskip
+ \line{%
+ \vbox{\moveleft\cornerthick\nstop}%
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}%
+ }%
+ \vss}%
+ \vskip\topandbottommargin
+ \line\bgroup
+ \hfil % center the page within the outer (page) hsize.
+ \ifodd\pageno\hskip\bindingoffset\fi
+ \vbox\bgroup
+ \fi
+ %
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \ifdim\ht\footlinebox > 0pt
+ % Only leave this space if the footline is nonempty.
+ % (We lessened \vsize for it in \oddfootingyyy.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 24pt
+ \unvbox\footlinebox
+ \fi
+ %
+ \ifcropmarks
+ \egroup % end of \vbox\bgroup
+ \hfil\egroup % end of (centering) \line\bgroup
+ \vskip\topandbottommargin plus1fill minus1fill
+ \boxmaxdepth = \cornerthick
+ \vbox to0pt{\vss
+ \line{%
+ \vbox{\moveleft\cornerthick\nsbot}%
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}%
+ }%
+ \nointerlineskip
+ \line{\ewbot\hfil\ewbot}%
+ }%
+ \egroup % \vbox from first cropmarks clause
+ \fi
+ }% end of \shipout\vbox
+ }% end of group with \indexdummies
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+ \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1\relax \unvbox#1\relax
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+ \def\argtorun{#2}%
+ \begingroup
+ \obeylines
+ \spaceisspace
+ #1%
+ \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ \argremovecomment #1\comment\ArgTerm%
+ }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+% @end itemize @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+ \def\temp{#3}%
+ \ifx\temp\empty
+ % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+ \let\temp\finishparsearg
+ \else
+ \let\temp\argcheckspaces
+ \fi
+ % Put the space token in:
+ \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \argtorun.
+% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\foo{...}
+% is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick. --kasal, 16nov03
+
+\def\parseargdef#1{%
+ \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+ \def#2{\parsearg#1}%
+ \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+ \obeyspaces
+ \gdef\obeyedspace{ }
+
+ % Make each space character in the input produce a normal interword
+ % space in the output. Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ \gdef\sepspaces{\obeyspaces\let =\tie}
+
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\leavevmode \penalty \@M \ ).
+ \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex. It's used like this:
+%
+% \envdef\foo{...}
+% \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo. \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches. The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as environments; they don't open a group. (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At run-time, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+ \def\temp{#1}%
+ \ifx\thisenv\temp
+ \else
+ \badenverr
+ \fi
+}
+
+% Environment mismatch, #1 expected:
+\def\badenverr{%
+ \errhelp = \EMsimple
+ \errmessage{This command can appear only \inenvironment\temp,
+ not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+ \ifx#1\empty
+ outside of any environment%
+ \else
+ in environment \expandafter\string#1%
+ \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+ \if 1\csname iscond.#1\endcsname
+ \else
+ % The general wording of \badenverr may not be ideal.
+ \expandafter\checkenv\csname#1\endcsname
+ \csname E#1\endcsname
+ \endgroup
+ \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\unskip\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+ \def\temp{#1}%
+ \ifx\temp\onword \plainfrenchspacing
+ \else\ifx\temp\offword \plainnonfrenchspacing
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @frenchspacing option `\temp', must be on|off}%
+ \fi\fi
+}
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large. This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material. In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom. The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+ \ifnum\catcode`\^^M=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ \startsavinginserts
+ %
+ \setbox\groupbox = \vtop\bgroup
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it. Thus, space below is not quite equal to space
+% above. But it's pretty close.
+\def\Egroup{%
+ % To get correct interline space between the last line of the group
+ % and the first line afterwards, we have to propagate \prevdepth.
+ \endgraf % Not \par, as it may have been set to \lisppar.
+ \global\dimen1 = \prevdepth
+ \egroup % End the \vtop.
+ % \dimen0 is the vertical size of the group's box.
+ \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
+ % \dimen2 is how much space is left on the page (more or less).
+ \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
+ % if the group doesn't fit on the current page, and it's a big big
+ % group, force a page break.
+ \ifdim \dimen0 > \dimen2
+ \ifdim \pagetotal < \vfilllimit\pageheight
+ \page
+ \fi
+ \fi
+ \box\groupbox
+ \prevdepth = \dimen1
+ \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+\parseargdef\need{%
+ % Ensure vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % If the @need value is less than one line space, it's useless.
+ \dimen0 = #1\mil
+ \dimen2 = \ht\strutbox
+ \advance\dimen2 by \dp\strutbox
+ \ifdim\dimen0 > \dimen2
+ %
+ % Do a \strut just to make the height of this box be normal, so the
+ % normal leading is inserted relative to the preceding line.
+ % And a page break here is fine.
+ \vtop to #1\mil{\strut\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+ \fi
+}
+
+% @br forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph. For more general purposes, use the \margin insertion
+% class. WHICH is `l' or `r'. Not documented, written for gawk manual.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+ \nobreak
+ \kern-\strutdepth
+ \vtop to \strutdepth{%
+ \baselineskip=\strutdepth
+ \vss
+ % if you have multiple lines of stuff to put here, you'll need to
+ % make the vbox yourself of the appropriate size.
+ \ifx#1l%
+ \llap{\ignorespaces #2\hskip\inmarginspacing}%
+ \else
+ \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+ \fi
+ \null
+ }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \def\lefttext{#1}% have both texts
+ \def\righttext{#2}%
+ \else
+ \def\lefttext{#1}% have only one text
+ \def\righttext{#1}%
+ \fi
+ %
+ \ifodd\pageno
+ \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+ \else
+ \def\temp{\inleftmargin\lefttext}%
+ \fi
+ \temp
+}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change). This command
+% is not documented, not supported, and doesn't work.
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% @include FILE -- \input text of FILE.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+ \pushthisfilestack
+ \def\thisfile{#1}%
+ {%
+ \makevalueexpandable % we want to expand any @value in FILE.
+ \turnoffactive % and allow special characters in the expansion
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @include of #1^^J}%
+ \edef\temp{\noexpand\input #1 }%
+ %
+ % This trickery is to read FILE outside of a group, in case it makes
+ % definitions, etc.
+ \expandafter
+ }\temp
+ \popthisfilestack
+}
+\def\filenamecatcodes{%
+ \catcode`\\=\other
+ \catcode`~=\other
+ \catcode`^=\other
+ \catcode`_=\other
+ \catcode`|=\other
+ \catcode`<=\other
+ \catcode`>=\other
+ \catcode`+=\other
+ \catcode`-=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
+}
+
+\def\pushthisfilestack{%
+ \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+ \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+ \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+ the stack of filenames is empty.}}
+%
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+ \ifhmode
+ \let\centersub\centerH
+ \else
+ \let\centersub\centerV
+ \fi
+ \centersub{\hfil \ignorespaces#1\unskip \hfil}%
+ \let\centersub\relax % don't let the definition persist, just in case
+}
+\def\centerH#1{{%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+}}
+%
+\newcount\centerpenalty
+\def\centerV#1{%
+ % The idea here is the same as in \startdefun, \cartouche, etc.: if
+ % @center is the first thing after a section heading, we need to wipe
+ % out the negative parskip inserted by \sectionheading, but still
+ % prevent a page break here.
+ \centerpenalty = \lastpenalty
+ \ifnum\centerpenalty>10000 \vskip\parskip \fi
+ \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi
+ \line{\kern\leftskip #1\kern\rightskip}%
+}
+
+% @sp n outputs n lines of vertical space
+%
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+%
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+%
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \defaultparindent = 0pt
+ \else
+ \defaultparindent = #1em
+ \fi
+ \fi
+ \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \lispnarrowing = 0pt
+ \else
+ \lispnarrowing = #1em
+ \fi
+ \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading. If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\noneword
+ \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+ \else\ifx\temp\insertword
+ \let\suppressfirstparagraphindent = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @firstparagraphindent option `\temp'}%
+ \fi\fi
+}
+
+% Here is how we actually suppress indentation. Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+ \gdef\indent{%
+ \restorefirstparagraphindent
+ \indent
+ }%
+ \gdef\noindent{%
+ \restorefirstparagraphindent
+ \noindent
+ }%
+ \global\everypar = {%
+ \kern -\parindent
+ \restorefirstparagraphindent
+ }%
+}
+
+\gdef\restorefirstparagraphindent{%
+ \global \let \indent = \ptexindent
+ \global \let \noindent = \ptexnoindent
+ \global \everypar = {}%
+}
+
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \iflinks
+ \tryauxfile
+ % Open the new aux file. TeX will close it automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ \openin 1 texinfo.cnf
+ \ifeof 1 \else \input texinfo.cnf \fi
+ \closein 1
+ %
+ \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set). So we test for \relax and 0 as well as being undefined.
+\ifx\pdfoutput\thisisundefined
+\else
+ \ifx\pdfoutput\relax
+ \else
+ \ifcase\pdfoutput
+ \else
+ \pdftrue
+ \fi
+ \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places. Thus, we have to
+% double any backslashes. Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e. Not good.
+%
+% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
+% related messages. The final outcome is that it is up to the TeX user
+% to double the backslashes and otherwise make the string valid, so
+% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to
+% do this reliably, so we use it.
+
+% #1 is a control sequence in which to do the replacements,
+% which we \xdef.
+\def\txiescapepdf#1{%
+ \ifx\pdfescapestring\thisisundefined
+ % No primitive available; should we give a warning or log?
+ % Many times it won't matter.
+ \else
+ % The expandable \pdfescapestring primitive escapes parentheses,
+ % backslashes, and other special chars.
+ \xdef#1{\pdfescapestring{#1}}%
+ \fi
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found. (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
+\ifpdf
+ %
+ % Color manipulation macros based on pdfcolor.tex,
+ % except using rgb instead of cmyk; the latter is said to render as a
+ % very dark gray on-screen and a very dark halftone in print, instead
+ % of actual black.
+ \def\rgbDarkRed{0.50 0.09 0.12}
+ \def\rgbBlack{0 0 0}
+ %
+ % k sets the color for filling (usual text, etc.);
+ % K sets the color for stroking (thin rules, e.g., normal _'s).
+ \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}}
+ %
+ % Set color, and create a mark which defines \thiscolor accordingly,
+ % so that \makeheadline knows which color to restore.
+ \def\setcolor#1{%
+ \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
+ \domark
+ \pdfsetcolor{#1}%
+ }
+ %
+ \def\maincolor{\rgbBlack}
+ \pdfsetcolor{\maincolor}
+ \edef\thiscolor{\maincolor}
+ \def\lastcolordefs{}
+ %
+ \def\makefootline{%
+ \baselineskip24pt
+ \line{\pdfsetcolor{\maincolor}\the\footline}%
+ }
+ %
+ \def\makeheadline{%
+ \vbox to 0pt{%
+ \vskip-22.5pt
+ \line{%
+ \vbox to8.5pt{}%
+ % Extract \thiscolor definition from the marks.
+ \getcolormarks
+ % Typeset the headline with \maincolor, then restore the color.
+ \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
+ }%
+ \vss
+ }%
+ \nointerlineskip
+ }
+ %
+ %
+ \pdfcatalog{/PageMode /UseOutlines}
+ %
+ % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+ \def\dopdfimage#1#2#3{%
+ \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ %
+ % pdftex (and the PDF format) support .pdf, .png, .jpg (among
+ % others). Let's try in that order, PDF first since if
+ % someone has a scalable image, presumably better to use that than a
+ % bitmap.
+ \let\pdfimgext=\empty
+ \begingroup
+ \openin 1 #1.pdf \ifeof 1
+ \openin 1 #1.PDF \ifeof 1
+ \openin 1 #1.png \ifeof 1
+ \openin 1 #1.jpg \ifeof 1
+ \openin 1 #1.jpeg \ifeof 1
+ \openin 1 #1.JPG \ifeof 1
+ \errhelp = \nopdfimagehelp
+ \errmessage{Could not find image file #1 for pdf}%
+ \else \gdef\pdfimgext{JPG}%
+ \fi
+ \else \gdef\pdfimgext{jpeg}%
+ \fi
+ \else \gdef\pdfimgext{jpg}%
+ \fi
+ \else \gdef\pdfimgext{png}%
+ \fi
+ \else \gdef\pdfimgext{PDF}%
+ \fi
+ \else \gdef\pdfimgext{pdf}%
+ \fi
+ \closein 1
+ \endgroup
+ %
+ % without \immediate, ancient pdftex seg faults when the same image is
+ % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
+ \ifnum\pdftexversion < 14
+ \immediate\pdfimage
+ \else
+ \immediate\pdfximage
+ \fi
+ \ifdim \wd0 >0pt width \pdfimagewidth \fi
+ \ifdim \wd2 >0pt height \pdfimageheight \fi
+ \ifnum\pdftexversion<13
+ #1.\pdfimgext
+ \else
+ {#1.\pdfimgext}%
+ \fi
+ \ifnum\pdftexversion < 14 \else
+ \pdfrefximage \pdflastximage
+ \fi}
+ %
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code, and characters
+ % such as \, aren't expanded when present in a section title.
+ \indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ \def\pdfdestname{#1}%
+ \txiescapepdf\pdfdestname
+ \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+ }}
+ %
+ % used to mark target names; must be expandable.
+ \def\pdfmkpgn#1{#1}
+ %
+ % by default, use a color that is dark enough to print on paper as
+ % nearly black, but still distinguishable for online viewing.
+ \def\urlcolor{\rgbDarkRed}
+ \def\linkcolor{\rgbDarkRed}
+ \def\endlink{\setcolor{\maincolor}\pdfendlink}
+ %
+ % Adding outlines to PDF; macros for calculating structure of outlines
+ % come from Petr Olsak
+ \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi}
+ \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+ \advance\tempnum by 1
+ \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+ %
+ % #1 is the section text, which is what will be displayed in the
+ % outline by the pdf viewer. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node text,
+ % which might be empty if this toc entry had no corresponding node.
+ % #4 is the page number
+ %
+ \def\dopdfoutline#1#2#3#4{%
+ % Generate a link to the node text if that exists; else, use the
+ % page number. We could generate a destination for the section
+ % text in the case where a section has no node, but it doesn't
+ % seem worth the trouble, since most documents are normally structured.
+ \edef\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty
+ \def\pdfoutlinedest{#4}%
+ \else
+ \txiescapepdf\pdfoutlinedest
+ \fi
+ %
+ % Also escape PDF chars in the display string.
+ \edef\pdfoutlinetext{#1}%
+ \txiescapepdf\pdfoutlinetext
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \begingroup
+ % Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\partentry##1##2##3##4{}% ignore parts in the outlines
+ \def\numchapentry##1##2##3##4{%
+ \def\thischapnum{##2}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsecentry##1##2##3##4{%
+ \advancenumber{chap\thischapnum}%
+ \def\thissecnum{##2}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsubsecentry##1##2##3##4{%
+ \advancenumber{sec\thissecnum}%
+ \def\thissubsecnum{##2}%
+ }%
+ \def\numsubsubsecentry##1##2##3##4{%
+ \advancenumber{subsec\thissubsecnum}%
+ }%
+ \def\thischapnum{0}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ %
+ % use \def rather than \let here because we redefine \chapentry et
+ % al. a second time, below.
+ \def\appentry{\numchapentry}%
+ \def\appsecentry{\numsecentry}%
+ \def\appsubsecentry{\numsubsecentry}%
+ \def\appsubsubsecentry{\numsubsubsecentry}%
+ \def\unnchapentry{\numchapentry}%
+ \def\unnsecentry{\numsecentry}%
+ \def\unnsubsecentry{\numsubsecentry}%
+ \def\unnsubsubsecentry{\numsubsubsecentry}%
+ \readdatafile{toc}%
+ %
+ % Read toc second time, this time actually producing the outlines.
+ % The `-' means take the \expnumber as the absolute number of
+ % subentries, which we calculated on our first read of the .toc above.
+ %
+ % We use the node names as the destinations.
+ \def\numchapentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+ \def\numsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+ \def\numsubsubsecentry##1##2##3##4{% count is always zero
+ \dopdfoutline{##1}{}{##3}{##4}}%
+ %
+ % PDF outlines are displayed using system fonts, instead of
+ % document fonts. Therefore we cannot use special characters,
+ % since the encoding is unknown. For example, the eogonek from
+ % Latin 2 (0xea) gets translated to a | character. Info from
+ % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+ %
+ % TODO this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Too
+ % much work for too little return. Just use the ASCII equivalents
+ % we use for the index sort strings.
+ %
+ \indexnofonts
+ \setupdatafile
+ % We can have normal brace characters in the PDF outlines, unlike
+ % Texinfo index files. So set that up.
+ \def\{{\lbracecharliteral}%
+ \def\}{\rbracecharliteral}%
+ \catcode`\\=\active \otherbackslash
+ \input \tocreadfilename
+ \endgroup
+ }
+ {\catcode`[=1 \catcode`]=2
+ \catcode`{=\other \catcode`}=\other
+ \gdef\lbracecharliteral[{]%
+ \gdef\rbracecharliteral[}]%
+ ]
+ %
+ \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+ \ifx\PP\D\let\nextsp\relax
+ \else\let\nextsp\skipspaces
+ \addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
+ \fi
+ \nextsp}
+ \def\getfilename#1{%
+ \filenamelength=0
+ % If we don't expand the argument now, \skipspaces will get
+ % snagged on things like "@value{foo}".
+ \edef\temp{#1}%
+ \expandafter\skipspaces\temp|\relax
+ }
+ \ifnum\pdftexversion < 14
+ \let \startlink \pdfannotlink
+ \else
+ \let \startlink \pdfstartlink
+ \fi
+ % make a live url in pdf output.
+ \def\pdfurl#1{%
+ \begingroup
+ % it seems we really need yet another set of dummies; have not
+ % tried to figure out what each command should do in the context
+ % of @url. for now, just make @/ a no-op, that's the only one
+ % people have actually reported a problem with.
+ %
+ \normalturnoffactive
+ \def\@{@}%
+ \let\/=\empty
+ \makevalueexpandable
+ % do we want to go so far as to use \indexnofonts instead of just
+ % special-casing \var here?
+ \def\var##1{##1}%
+ %
+ \leavevmode\setcolor{\urlcolor}%
+ \startlink attr{/Border [0 0 0]}%
+ user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+ \endgroup}
+ \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+ \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+ \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+ \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+ \def\maketoks{%
+ \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+ \ifx\first0\adn0
+ \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+ \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+ \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+ \else
+ \ifnum0=\countA\else\makelink\fi
+ \ifx\first.\let\next=\done\else
+ \let\next=\maketoks
+ \addtokens{\toksB}{\the\toksD}
+ \ifx\first,\addtokens{\toksB}{\space}\fi
+ \fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next}
+ \def\makelink{\addtokens{\toksB}%
+ {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+ \def\pdflink#1{%
+ \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+ \setcolor{\linkcolor}#1\endlink}
+ \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+ % non-pdf mode
+ \let\pdfmkdest = \gobble
+ \let\pdfurl = \gobble
+ \let\endlink = \relax
+ \let\setcolor = \gobble
+ \let\pdfsetcolor = \gobble
+ \let\pdfmakeoutlines = \relax
+\fi % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+ \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+ \csname ten#1\endcsname % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Unfortunately, we have to override this for titles and the like, since
+% in those cases "rm" is bold. Sigh.
+\def\rmisbold{\rm\def\curfontstyle{bf}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+% can get a sort of poor man's double spacing by redefining this.
+\def\baselinefactor{1}
+%
+\newdimen\textleading
+\def\setleading#1{%
+ \dimen0 = #1\relax
+ \normalbaselineskip = \baselinefactor\dimen0
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+% PDF CMaps. See also LaTeX's t1.cmap.
+%
+% do nothing with this by default.
+\expandafter\let\csname cmapOT1\endcsname\gobble
+\expandafter\let\csname cmapOT1IT\endcsname\gobble
+\expandafter\let\csname cmapOT1TT\endcsname\gobble
+
+% if we are producing pdf, and we have \pdffontattr, then define cmaps.
+% (\pdffontattr was introduced many years ago, but people still run
+% older pdftex's; it's easy to conditionalize, so we do.)
+\ifpdf \ifx\pdffontattr\thisisundefined \else
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1IT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1TT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+\fi\fi
+
+
+% Set the font macro #1 to the font named \fontprefix#2.
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit).
+% Example:
+% #1 = \textrm
+% #2 = \rmshape
+% #3 = 10
+% #4 = \mainmagstep
+% #5 = OT1
+%
+\def\setfont#1#2#3#4#5{%
+ \font#1=\fontprefix#2#3 scaled #4
+ \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+%
+% (end of cmaps)
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\thisisundefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx} % where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Definitions for a main text size of 11pt. (The default in Texinfo.)
+%
+\def\definetextfontsizexi{%
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1095}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+\def\chapecsize{1728}
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+\def\sececsize{1440}
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+\def\ssececsize{1200}
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+\def\reducedecsize{1000}
+
+\textleading = 13.2pt % line spacing for 11pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 11pt text font size definitions, \definetextfontsizexi
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit. This is for the GNU
+% Press printing of the Emacs 22 manual. Maybe other manuals in the
+% future. Used with @smallbook, which sets the leading to 12pt.
+%
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1000}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+\def\chapecsize{1440}
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+\def\sececsize{1200}
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+\def\ssececsize{1000}
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+\def\reducedecsize{0900}
+
+\divide\parskip by 2 % reduce space between paragraphs
+\textleading = 12pt % line spacing for 10pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 10pt text font size definitions, \definetextfontsizex
+
+
+% We provide the user-level command
+% @fonttextsize 10
+% (or 11) to redefine the text font size. pt is assumed.
+%
+\def\xiword{11}
+\def\xword{10}
+\def\xwordpt{10pt}
+%
+\parseargdef\fonttextsize{%
+ \def\textsizearg{#1}%
+ %\wlog{doing @fonttextsize \textsizearg}%
+ %
+ % Set \globaldefs so that documents can use this inside @tex, since
+ % makeinfo 4.8 does not support it, but we need it nonetheless.
+ %
+ \begingroup \globaldefs=1
+ \ifx\textsizearg\xword \definetextfontsizex
+ \else \ifx\textsizearg\xiword \definetextfontsizexi
+ \else
+ \errhelp=\EMsimple
+ \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+ \fi\fi
+ \endgroup
+}
+
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+ \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+ \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this because \STYLE needs to also set the
+% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower). These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \let\tenttsl=\textttsl
+ \def\curfontsize{text}%
+ \def\lsize{reduced}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+ \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+ \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+ \let\tenttsl=\titlettsl
+ \def\curfontsize{title}%
+ \def\lsize{chap}\def\lllsize{subsec}%
+ \resetmathfonts \setleading{27pt}}
+\def\titlefont#1{{\titlefonts\rmisbold #1}}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \let\tenttsl=\chapttsl
+ \def\curfontsize{chap}%
+ \def\lsize{sec}\def\lllsize{text}%
+ \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \let\tenttsl=\secttsl
+ \def\curfontsize{sec}%
+ \def\lsize{subsec}\def\lllsize{reduced}%
+ \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \let\tenttsl=\ssecttsl
+ \def\curfontsize{ssec}%
+ \def\lsize{text}\def\lllsize{small}%
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+ \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+ \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+ \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+ \let\tenttsl=\reducedttsl
+ \def\curfontsize{reduced}%
+ \def\lsize{small}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+ \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+ \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+ \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+ \let\tenttsl=\smallttsl
+ \def\curfontsize{small}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+ \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+ \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+ \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+ \let\tenttsl=\smallerttsl
+ \def\curfontsize{smaller}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{9.5pt}}
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+% Define these just so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+% 8.5x11=86 smallbook=72 a4=90 a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+% 8.5x11=90+ smallbook=80 a4=90+ a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt. So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+% 8.5x11=71 smallbook=60 a4=75 a5=58
+% --karl, 24jan03.
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+
+\message{markup,}
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will
+% define and register \INITMACRO to be called on markup style changes.
+% \INITMACRO can check \currentmarkupstyle for the innermost
+% style and the set of \ifmarkupSTYLE switches for all styles
+% currently in effect.
+\newif\ifmarkupvar
+\newif\ifmarkupsamp
+\newif\ifmarkupkey
+%\newif\ifmarkupfile % @file == @samp.
+%\newif\ifmarkupoption % @option == @samp.
+\newif\ifmarkupcode
+\newif\ifmarkupkbd
+%\newif\ifmarkupenv % @env == @code.
+%\newif\ifmarkupcommand % @command == @code.
+\newif\ifmarkuptex % @tex (and part of @math, for now).
+\newif\ifmarkupexample
+\newif\ifmarkupverb
+\newif\ifmarkupverbatim
+
+\let\currentmarkupstyle\empty
+
+\def\setupmarkupstyle#1{%
+ \csname markup#1true\endcsname
+ \def\currentmarkupstyle{#1}%
+ \markupstylesetup
+}
+
+\let\markupstylesetup\empty
+
+\def\defmarkupstylesetup#1{%
+ \expandafter\def\expandafter\markupstylesetup
+ \expandafter{\markupstylesetup #1}%
+ \def#1%
+}
+
+% Markup style setup for left and right quotes.
+\defmarkupstylesetup\markupsetuplq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuplq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuplqdefault \else \temp \fi
+}
+
+\defmarkupstylesetup\markupsetuprq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuprq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuprqdefault \else \temp \fi
+}
+
+{
+\catcode`\'=\active
+\catcode`\`=\active
+
+\gdef\markupsetuplqdefault{\let`\lq}
+\gdef\markupsetuprqdefault{\let'\rq}
+
+\gdef\markupsetcodequoteleft{\let`\codequoteleft}
+\gdef\markupsetcodequoteright{\let'\codequoteright}
+}
+
+\let\markupsetuplqcode \markupsetcodequoteleft
+\let\markupsetuprqcode \markupsetcodequoteright
+%
+\let\markupsetuplqexample \markupsetcodequoteleft
+\let\markupsetuprqexample \markupsetcodequoteright
+%
+\let\markupsetuplqkbd \markupsetcodequoteleft
+\let\markupsetuprqkbd \markupsetcodequoteright
+%
+\let\markupsetuplqsamp \markupsetcodequoteleft
+\let\markupsetuprqsamp \markupsetcodequoteright
+%
+\let\markupsetuplqverb \markupsetcodequoteleft
+\let\markupsetuprqverb \markupsetcodequoteright
+%
+\let\markupsetuplqverbatim \markupsetcodequoteleft
+\let\markupsetuprqverbatim \markupsetcodequoteright
+
+% Allow an option to not use regular directed right quote/apostrophe
+% (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
+% The undirected quote is ugly, so don't make it the default, but it
+% works for pasting with more pdf viewers (at least evince), the
+% lilypond developers report. xpdf does work with the regular 0x27.
+%
+\def\codequoteright{%
+ \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+ \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ '%
+ \else \char'15 \fi
+ \else \char'15 \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+ \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
+ \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ % [Knuth] pp. 380,381,391
+ % \relax disables Spanish ligatures ?` and !` of \tt font.
+ \relax`%
+ \else \char'22 \fi
+ \else \char'22 \fi
+}
+
+% Commands to set the quote options.
+%
+\parseargdef\codequoteundirected{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}%
+ \fi\fi
+}
+%
+\parseargdef\codequotebacktick{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}%
+ \fi\fi
+}
+
+% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font.
+\def\noligaturesquoteleft{\relax\lq}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Font commands.
+
+% #1 is the font command (\sl or \it), #2 is the text to slant.
+% If we are in a monospaced environment, however, 1) always use \ttsl,
+% and 2) do not add an italic correction.
+\def\dosmartslant#1#2{%
+ \ifusingtt
+ {{\ttsl #2}\let\next=\relax}%
+ {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}%
+ \next
+}
+\def\smartslanted{\dosmartslant\sl}
+\def\smartitalic{\dosmartslant\it}
+
+% Output an italic correction unless \next (presumed to be the following
+% character) is such as not to need one.
+\def\smartitaliccorrection{%
+ \ifx\next,%
+ \else\ifx\next-%
+ \else\ifx\next.%
+ \else\ptexslash
+ \fi\fi\fi
+ \aftersmartic
+}
+
+% Unconditional use \ttsl, and no ic. @var is set to this for defuns.
+\def\ttslanted#1{{\ttsl #1}}
+
+% @cite is like \smartslanted except unconditionally use \sl. We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection}
+
+\def\aftersmartic{}
+\def\var#1{%
+ \let\saveaftersmartic = \aftersmartic
+ \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}%
+ \smartslanted{#1}%
+}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @b, explicit bold. Also @strong.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+ \def\plainfrenchspacing{%
+ \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+ \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ \def\endofsentencespacefactor{1000}% for @. and friends
+ }
+ \def\plainnonfrenchspacing{%
+ \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+ \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+ \def\endofsentencespacefactor{3000}% for @. and friends
+ }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+% @t, explicit typewriter.
+\def\t#1{%
+ {\tt \rawbackslash \plainfrenchspacing #1}%
+ \null
+}
+
+% @samp.
+\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
+
+% @indicateurl is \samp, that is, with quotes.
+\let\indicateurl=\samp
+
+% @code (and similar) prints in typewriter, but with spaces the same
+% size as normal in the surrounding text, without hyphenation, etc.
+% This is a subroutine for that.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \plainfrenchspacing
+ #1%
+ }%
+ \null % reset spacefactor to 1000
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+%
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+% -- rms.
+{
+ \catcode`\-=\active \catcode`\_=\active
+ \catcode`\'=\active \catcode`\`=\active
+ \global\let'=\rq \global\let`=\lq % default definitions
+ %
+ \global\def\code{\begingroup
+ \setupmarkupstyle{code}%
+ % The following should really be moved into \setupmarkupstyle handlers.
+ \catcode\dashChar=\active \catcode\underChar=\active
+ \ifallowcodebreaks
+ \let-\codedash
+ \let_\codeunder
+ \else
+ \let-\normaldash
+ \let_\realunder
+ \fi
+ \codex
+ }
+}
+
+\def\codex #1{\tclose{#1}\endgroup}
+
+\def\normaldash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+ % this is all so @math{@code{var_name}+1} can work. In math mode, _
+ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+ % will therefore expand the active definition of _, which is us
+ % (inside @code that is), therefore an endless loop.
+ \ifusingtt{\ifmmode
+ \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+ \else\normalunderscore \fi
+ \discretionary{}{}{}}%
+ {\_}%
+}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__. This is bad.
+% @allowcodebreaks provides a document-level way to turn breaking at -
+% and _ on and off.
+%
+\newif\ifallowcodebreaks \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\keywordtrue
+ \allowcodebreakstrue
+ \else\ifx\txiarg\keywordfalse
+ \allowcodebreaksfalse
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}%
+ \fi\fi
+}
+
+% For @command, @env, @file, @option quotes seem unnecessary,
+% so use \code rather than \samp.
+\let\command=\code
+\let\env=\code
+\let\file=\code
+\let\option=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself. First (mandatory) arg is the url.
+% (This \urefnobreak definition isn't used now, leaving it for a while
+% for comparison.)
+\def\urefnobreak#1{\dourefnobreak #1,,,\finish}
+\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \code{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% This \urefbreak definition is the active one.
+\def\urefbreak{\begingroup \urefcatcodes \dourefbreak}
+\let\uref=\urefbreak
+\def\dourefbreak#1{\urefbreakfinish #1,,,\finish}
+\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \urefcode{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% Allow line breaks around only a few characters (only).
+\def\urefcatcodes{%
+ \catcode\ampChar=\active \catcode\dotChar=\active
+ \catcode\hashChar=\active \catcode\questChar=\active
+ \catcode\slashChar=\active
+}
+{
+ \urefcatcodes
+ %
+ \global\def\urefcode{\begingroup
+ \setupmarkupstyle{code}%
+ \urefcatcodes
+ \let&\urefcodeamp
+ \let.\urefcodedot
+ \let#\urefcodehash
+ \let?\urefcodequest
+ \let/\urefcodeslash
+ \codex
+ }
+ %
+ % By default, they are just regular characters.
+ \global\def&{\normalamp}
+ \global\def.{\normaldot}
+ \global\def#{\normalhash}
+ \global\def?{\normalquest}
+ \global\def/{\normalslash}
+}
+
+% we put a little stretch before and after the breakable chars, to help
+% line breaking of long url's. The unequal skips make look better in
+% cmtt at least, especially for dots.
+\def\urefprestretch{\urefprebreak \hskip0pt plus.13em }
+\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em }
+%
+\def\urefcodeamp{\urefprestretch \&\urefpoststretch}
+\def\urefcodedot{\urefprestretch .\urefpoststretch}
+\def\urefcodehash{\urefprestretch \#\urefpoststretch}
+\def\urefcodequest{\urefprestretch ?\urefpoststretch}
+\def\urefcodeslash{\futurelet\next\urefcodeslashfinish}
+{
+ \catcode`\/=\active
+ \global\def\urefcodeslashfinish{%
+ \urefprestretch \slashChar
+ % Allow line break only after the final / in a sequence of
+ % slashes, to avoid line break between the slashes in http://.
+ \ifx\next/\else \urefpoststretch \fi
+ }
+}
+
+% One more complication: by default we'll break after the special
+% characters, but some people like to break before the special chars, so
+% allow that. Also allow no breaking at all, for manual control.
+%
+\parseargdef\urefbreakstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\wordnone
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordbefore
+ \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordafter
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak}
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @urefbreakstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\wordafter{after}
+\def\wordbefore{before}
+\def\wordnone{none}
+
+\urefbreakstyle after
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+ \def\email#1{\doemail#1,,\finish}
+ \def\doemail#1,#2,#3\finish{\begingroup
+ \unsepspaces
+ \pdfurl{mailto:#1}%
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+ \endlink
+ \endgroup}
+\else
+ \let\email=\uref
+\fi
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct'.
+\kbdinputstyle distinct
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}}
+
+\def\xkey{\key}
+\def\kbdsub#1#2#3\par{%
+ \def\one{#1}\def\three{#3}\def\threex{??}%
+ \ifx\one\xkey\ifx\threex\three \key{#2}%
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+}
+
+% definition of @key that produces a lozenge. Doesn't adjust to text size.
+%\setfont\keyrm\rmshape{8}{1000}{OT1}
+%\font\keysy=cmsy9
+%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+% \vbox{\hrule\kern-0.4pt
+% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+% \kern-0.4pt\hrule}%
+% \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+
+% definition of @key with no lozenge. If the current font is already
+% monospace, don't change it; that way, we respect @kbdinputstyle. But
+% if it isn't monospace, then use \tt.
+%
+\def\key#1{{\setupmarkupstyle{key}%
+ \nohyphenation
+ \ifmonospace\else\tt\fi
+ #1}\null}
+
+% @clicksequence{File @click{} Open ...}
+\def\clicksequence#1{\begingroup #1\endgroup}
+
+% @clickstyle @arrow (by default)
+\parseargdef\clickstyle{\def\click{#1}}
+\def\click{\arrow}
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+%
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+ {\selectfonts\lsize #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+ \null % reset \spacefactor=1000
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+%
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+ {\plainfrenchspacing #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+ \null % reset \spacefactor=1000
+}
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode`\_ = \active
+ \gdef\mathunderscore{%
+ \catcode`\_=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a math (or tt) \.
+% FYI, plain.tex uses \\ as a temporary control sequence (for no
+% particular reason), but this is not advertised and we don't care.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ % make the texinfo accent commands work in math mode
+ \let\"=\ddot
+ \let\'=\acute
+ \let\==\bar
+ \let\^=\hat
+ \let\`=\grave
+ \let\u=\breve
+ \let\v=\check
+ \let\~=\tilde
+ \let\dotaccent=\dot
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \catcode`' = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ \let' = \ptexquoteright
+ }
+}
+
+% ctrl is no longer a Texinfo command, but leave this definition for fun.
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
+% Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
+% except specified as a normal braced arg, so no newlines to worry about.
+%
+\def\outfmtnametex{tex}
+%
+\long\def\inlinefmt#1{\doinlinefmt #1,\finish}
+\long\def\doinlinefmt#1,#2,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi
+}
+% For raw, must switch into @tex before parsing the argument, to avoid
+% setting catcodes prematurely. Doing it this way means that, for
+% example, @inlineraw{html, foo{bar} gets a parse error instead of being
+% ignored. But this isn't important because if people want a literal
+% *right* brace they would have to use a command anyway, so they may as
+% well use a command to get a left brace too. We could re-use the
+% delimiter character idea from \verb, but it seems like overkill.
+%
+\long\def\inlineraw{\tex \doinlineraw}
+\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish}
+\def\doinlinerawtwo#1,#2,\finish{%
+ \def\inlinerawname{#1}%
+ \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi
+ \endgroup % close group opened by \tex.
+}
+
+
+\message{glyphs,}
+% and logos.
+
+% @@ prints an @, as does @atchar{}.
+\def\@{\char64 }
+\let\atchar=\@
+
+% @{ @} @lbracechar{} @rbracechar{} all generate brace characters.
+% Unless we're in typewriter, use \ecfont because the CM text fonts do
+% not have braces, and we don't want to switch into math.
+\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}}
+\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}}
+\let\{=\mylbrace \let\lbracechar=\{
+\let\}=\myrbrace \let\rbracechar=\}
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux/toc files.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \ptexc
+\let\dotaccent = \ptexdot
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \ptext
+\let\ubaraccent = \ptexb
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi
+ \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{%
+ \ifx\textnominalsize\xwordpt
+ % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX.
+ % Revert to plain's \scriptsize, which is 7pt.
+ \count255=\the\fam $\fam\count255 \scriptstyle A$%
+ \else
+ % For 11pt, we can use our lllsize.
+ \selectfonts\lllsize A%
+ \fi
+ }%
+ \vss
+ }}%
+ \kern-.15em
+ \TeX
+}
+
+% Some math mode symbols.
+\def\bullet{$\ptexbullet$}
+\def\geq{\ifmmode \ge\else $\ge$\fi}
+\def\leq{\ifmmode \le\else $\le$\fi}
+\def\minus{\ifmmode -\else $-$\fi}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em. So do
+% whichever is larger.
+%
+\def\dots{%
+ \leavevmode
+ \setbox0=\hbox{...}% get width of three periods
+ \ifdim\wd0 > 1.5em
+ \dimen0 = \wd0
+ \else
+ \dimen0 = 1.5em
+ \fi
+ \hbox to \dimen0{%
+ \hskip 0pt plus.25fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=\endofsentencespacefactor
+}
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, they should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}}
+\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that. The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math. Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+ % We set the font at each command, rather than predefining it in
+ % \textfonts and the other font-switching commands, so that
+ % installations which never need the symbol don't have to have the
+ % font installed.
+ %
+ % There is only one designed size (nominal 10pt), so we always scale
+ % that to the current nominal size.
+ %
+ % By the way, simply using "at 1em" works for cmr10 and the like, but
+ % does not work for cmbx10 and other extended/shrunken fonts.
+ %
+ \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+ %
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+ \else
+ % regular:
+ \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+ \fi
+ \thiseurofont
+}
+
+% Glyphs from the EC fonts. We don't use \let for the aliases, because
+% sometimes we redefine the original macro, and the alias should reflect
+% the redefinition.
+%
+% Use LaTeX names for the Icelandic letters.
+\def\DH{{\ecfont \char"D0}} % Eth
+\def\dh{{\ecfont \char"F0}} % eth
+\def\TH{{\ecfont \char"DE}} % Thorn
+\def\th{{\ecfont \char"FE}} % thorn
+%
+\def\guillemetleft{{\ecfont \char"13}}
+\def\guillemotleft{\guillemetleft}
+\def\guillemetright{{\ecfont \char"14}}
+\def\guillemotright{\guillemetright}
+\def\guilsinglleft{{\ecfont \char"0E}}
+\def\guilsinglright{{\ecfont \char"0F}}
+\def\quotedblbase{{\ecfont \char"12}}
+\def\quotesinglbase{{\ecfont \char"0D}}
+%
+% This positioning is not perfect (see the ogonek LaTeX package), but
+% we have the precomposed glyphs for the most common cases. We put the
+% tests to use those glyphs in the single \ogonek macro so we have fewer
+% dummy definitions to worry about for index entries, etc.
+%
+% ogonek is also used with other letters in Lithuanian (IOU), but using
+% the precomposed glyphs for those is not so easy since they aren't in
+% the same EC font.
+\def\ogonek#1{{%
+ \def\temp{#1}%
+ \ifx\temp\macrocharA\Aogonek
+ \else\ifx\temp\macrochara\aogonek
+ \else\ifx\temp\macrocharE\Eogonek
+ \else\ifx\temp\macrochare\eogonek
+ \else
+ \ecfont \setbox0=\hbox{#1}%
+ \ifdim\ht0=1ex\accent"0C #1%
+ \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}%
+ \fi
+ \fi\fi\fi\fi
+ }%
+}
+\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A}
+\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a}
+\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E}
+\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e}
+%
+% Use the ec* fonts (cm-super in outline format) for non-CM glyphs.
+\def\ecfont{%
+ % We can't distinguish serif/sans and italic/slanted, but this
+ % is used for crude hacks anyway (like adding French and German
+ % quotes to documents typeset with CM, where we lose kerning), so
+ % hopefully nobody will notice/care.
+ \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+ \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+ \ifmonospace
+ % typewriter:
+ \font\thisecfont = ectt\ecsize \space at \nominalsize
+ \else
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \else
+ % regular:
+ \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \fi
+ \fi
+ \thisecfont
+}
+
+% @registeredsymbol - R in a circle. The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+ \hfil\crcr\Orb}}%
+ }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% Laurent Siebenmann reports \Orb undefined with:
+% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
+% so we'll define it if necessary.
+%
+\ifx\Orb\thisisundefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+% Quotes.
+\chardef\quotedblleft="5C
+\chardef\quotedblright=`\"
+\chardef\quoteleft=`\`
+\chardef\quoteright=`\'
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{%
+ \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+ % Open one extra group, as we want to close it in the middle of \Etitlepage.
+ \begingroup
+ \parindent=0pt \textfonts
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \let\page = \oldpage
+ \page
+ \null
+ }%
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ %
+ % Need this before the \...aftertitlepage checks so that if they are
+ % in effect the toc pages will come out with page numbers.
+ \HEADINGSon
+ %
+ % If they want short, they certainly want long too.
+ \ifsetshortcontentsaftertitlepage
+ \shortcontents
+ \contents
+ \global\let\shortcontents = \relax
+ \global\let\contents = \relax
+ \fi
+ %
+ \ifsetcontentsaftertitlepage
+ \contents
+ \global\let\contents = \relax
+ \global\let\shortcontents = \relax
+ \fi
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+% Settings used for typesetting titles: no hyphenation, no indentation,
+% don't worry much about spacing, ragged right. This should be used
+% inside a \vbox, and fonts need to be set appropriately first. Because
+% it is always used for titles, nothing else, we call \rmisbold. \par
+% should be specified before the end of the \vbox, since a vbox is a group.
+%
+\def\raggedtitlesettings{%
+ \rmisbold
+ \hyphenpenalty=10000
+ \parindent=0pt
+ \tolerance=5000
+ \ptexraggedright
+}
+
+% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\parseargdef\title{%
+ \checkenv\titlepage
+ \vbox{\titlefonts \raggedtitlesettings #1\par}%
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+ \checkenv\titlepage
+ {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+ \def\temp{\quotation}%
+ \ifx\thisenv\temp
+ \def\quotationauthor{#1}% printed in \Equotation.
+ \else
+ \checkenv\titlepage
+ \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+ {\secfonts\rmisbold \leftline{#1}}%
+ \fi
+}
+
+
+% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline % headline on even pages
+\newtoks\oddheadline % headline on odd pages
+\newtoks\evenfootline % footline on even pages
+\newtoks\oddfootline % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+ \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+ %
+ % Leave some space for the footline. Hopefully ok to assume
+ % @evenfooting will not be used by itself.
+ \global\advance\pageheight by -12pt
+ \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+% @evenheadingmarks top \thischapter <- chapter at the top of a page
+% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page
+%
+% The same set of arguments for:
+%
+% @oddheadingmarks
+% @evenfootingmarks
+% @oddfootingmarks
+% @everyheadingmarks
+% @everyfootingmarks
+
+\def\evenheadingmarks{\headingmarks{even}{heading}}
+\def\oddheadingmarks{\headingmarks{odd}{heading}}
+\def\evenfootingmarks{\headingmarks{even}{footing}}
+\def\oddfootingmarks{\headingmarks{odd}{footing}}
+\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
+ \headingmarks{odd}{heading}{#1} }
+\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
+ \headingmarks{odd}{footing}{#1} }
+% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
+\def\headingmarks#1#2#3 {%
+ \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
+ \global\expandafter\let\csname get#1#2marks\endcsname \temp
+}
+
+\everyheadingmarks bottom
+\everyfootingmarks bottom
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\headingsoff{% non-global headings elimination
+ \evenheadline={\hfil}\evenfootline={\hfil}%
+ \oddheadline={\hfil}\oddfootline={\hfil}%
+}
+
+\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting
+\HEADINGSoff % it's the default
+
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\thisisundefined
+\def\today{%
+ \number\day\space
+ \ifcase\month
+ \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+ \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+ \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+ \fi
+ \space\number\year}
+\fi
+
+% @settitle line... specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemindicate{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil\relax
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. However, if
+ % what follows is an environment such as @example, there will be no
+ % \parskip glue; then the negative vskip we just inserted would
+ % cause the example and the item to crash together. So we use this
+ % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+ % \parskip glue after all. Section titles are handled this way also.
+ %
+ \penalty 10001
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line.
+ \noindent
+ % Do this with kerns and \unhbox so that if there is a footnote in
+ % the item text, it can migrate to the main vertical list and
+ % eventually be printed.
+ \nobreak\kern-\tableindent
+ \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+ \unhbox0
+ \nobreak\kern\dimen0
+ \endgroup
+ \itemxneedsnegativevskiptrue
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+ \let\itemindex\gobble
+ \tablecheck{table}%
+}
+\envdef\ftable{%
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablecheck{ftable}%
+}
+\envdef\vtable{%
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+ \ifnum \the\catcode`\^^M=\active
+ \endgroup
+ \errmessage{This command won't work in this context; perhaps the problem is
+ that we are \inenvironment\thisenv}%
+ \def\next{\doignore{#1}}%
+ \else
+ \let\next\tablex
+ \fi
+ \next
+}
+\def\tablex#1{%
+ \def\itemindicate{#1}%
+ \parsearg\tabley
+}
+\def\tabley#1{%
+ {%
+ \makevalueexpandable
+ \edef\temp{\noexpand\tablez #1\space\space\space}%
+ \expandafter
+ }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+ \aboveenvbreak
+ \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+ \ifnum 0#2>0 \tableindent=#2\mil \fi
+ \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+ \itemmax=\tableindent
+ \advance \itemmax by -\itemmargin
+ \advance \leftskip by \tableindent
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi
+ \let\item = \internalBitem
+ \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+ \aboveenvbreak
+ \itemmax=\itemindent
+ \advance\itemmax by -\itemmargin
+ \advance\leftskip by \itemindent
+ \exdentamount=\itemindent
+ \parindent=0pt
+ \parskip=\smallskipamount
+ \ifdim\parskip=0pt \parskip=2pt \fi
+ %
+ % Try typesetting the item mark that if the document erroneously says
+ % something like @itemize @samp (intending @table), there's an error
+ % right away at the @itemize. It's not the best error message in the
+ % world, but it's better than leaving it to the @item. This means if
+ % the user wants an empty mark, they have to say @w{} not just @w.
+ \def\itemcontents{#1}%
+ \setbox0 = \hbox{\itemcontents}%
+ %
+ % @itemize with no arg is equivalent to @itemize @bullet.
+ \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ %
+ \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+ \advance\itemno by 1 % for enumerations
+ {\let\par=\endgraf \smallbreak}% reasonable place to break
+ {%
+ % If the document has an @itemize directly after a section title, a
+ % \nobreak will be last on the list, and \sectionheading will have
+ % done a \vskip-\parskip. In that case, we don't want to zero
+ % parskip, or the item text will crash with the heading. On the
+ % other hand, when there is normal text preceding the item (as there
+ % usually is), we do want to zero parskip, or there would be too much
+ % space. In that case, we won't have a \nobreak before. At least
+ % that's the theory.
+ \ifnum\lastpenalty<10000 \parskip=0in \fi
+ \noindent
+ \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ %
+ \vadjust{\penalty 1200}}% not good to break after first line of item.
+ \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @columnfractions .25 .3 .45
+% @item ...
+%
+% Numbers following @columnfractions are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1. We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+ \global\advance\colcount by 1
+ \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+ \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+ \def\firstarg{#1}%
+ \ifx\firstarg\xendsetuptable
+ \let\go = \relax
+ \else
+ \ifx\firstarg\xcolumnfractions
+ \global\setpercenttrue
+ \else
+ \ifsetpercent
+ \let\go\pickupwholefraction
+ \else
+ \global\advance\colcount by 1
+ \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+ % separator; typically that is always in the input, anyway.
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi
+ \fi
+ \ifx\go\pickupwholefraction
+ % Put the argument back for the \pickupwholefraction call, so
+ % we'll always have a period there to be parsed.
+ \def\go{\pickupwholefraction#1}%
+ \else
+ \let\go = \setuptable
+ \fi%
+ \fi
+ \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry. \everycr resets \everytab so we don't have to
+% undo it ourselves.
+\def\headitemfont{\b}% for people to use in the template row; not changeable
+\def\headitem{%
+ \checkenv\multitable
+ \crcr
+ \global\everytab={\bf}% can't use \headitemfont since the parsing differs
+ \the\everytab % for the first item
+}%
+%
+% A \tab used to include \hskip1sp. But then the space in a template
+% line is not enough. That is bad. So let's go back to just `&' until
+% we again encounter the problem the 1sp was intended to solve.
+% --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab % insert after every tab.
+%
+\envdef\multitable{%
+ \vskip\parskip
+ \startsavinginserts
+ %
+ % @item within a multitable starts a normal row.
+ % We use \def instead of \let so that if one of the multitable entries
+ % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+ % \endtemplate) expanding \doitemize.
+ \def\item{\crcr}%
+ %
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ %
+ \everycr = {%
+ \noalign{%
+ \global\everytab={}%
+ \global\colcount=0 % Reset the column counter.
+ % Check for saved footnotes, etc.
+ \checkinserts
+ % Keeps underfull box messages off when table breaks over pages.
+ %\filbreak
+ % Maybe so, but it also creates really weird page breaks when the
+ % table breaks over pages. Wouldn't \vfil be better? Wait until the
+ % problem manifests itself, so it can be fixed for real --karl.
+ }%
+ }%
+ %
+ \parsearg\domultitable
+}
+\def\domultitable#1{%
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+ \halign\bgroup &%
+ \global\advance\colcount by 1
+ \multistrut
+ \vtop{%
+ % Use the current \colcount to find the correct column width:
+ \hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively
+ % marking characters.
+ \noindent\ignorespaces##\unskip\multistrut
+ }\cr
+}
+\def\Emultitable{%
+ \crcr
+ \egroup % end the \halign
+ \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+ \def\multistrut{\strut}% just use the standard line spacing
+ %
+ % Compute \multitablelinespace (if not defined by user) for use in
+ % \multitableparskip calculation. We used define \multistrut based on
+ % this, but (ironically) that caused the spacing to be off.
+ % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+% Test to see if parskip is larger than space between lines of
+% table. If not, do nothing.
+% If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed. They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested. But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+ \expandafter\let\csname #1\endcsname = \relax
+ \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+ % Scan in ``verbatim'' mode:
+ \obeylines
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \spaceisspace
+ %
+ % Count number of #1's that we've seen.
+ \doignorecount = 0
+ %
+ % Swallow text until we reach the matching `@end #1'.
+ \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+ \obeylines %
+ %
+ \gdef\dodoignore#1{%
+ % #1 contains the command name as a string, e.g., `ifinfo'.
+ %
+ % Define a command to find the next `@end #1'.
+ \long\def\doignoretext##1^^M@end #1{%
+ \doignoretextyyy##1^^M@#1\_STOP_}%
+ %
+ % And this command to find another #1 command, at the beginning of a
+ % line. (Otherwise, we would consider a line `@c @ifset', for
+ % example, to count as an @ifset for nesting.)
+ \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+ %
+ % And now expand that command.
+ \doignoretext ^^M%
+ }%
+}
+
+\def\doignoreyyy#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty % Nothing found.
+ \let\next\doignoretextzzz
+ \else % Found a nested condition, ...
+ \advance\doignorecount by 1
+ \let\next\doignoretextyyy % ..., look for another.
+ % If we're here, #1 ends with ^^M\ifinfo (for example).
+ \fi
+ \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+ \ifnum\doignorecount = 0 % We have just found the outermost @end.
+ \let\next\enddoignore
+ \else % Still inside a nested condition.
+ \advance\doignorecount by -1
+ \let\next\doignoretext % Look for the next @end.
+ \fi
+ \next
+}
+
+% Finish off ignored text.
+{ \obeylines%
+ % Ignore anything after the last `@end #1'; this matters in verbatim
+ % environments, where otherwise the newline after an ignored conditional
+ % would result in a blank line in the output.
+ \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ {%
+ \makevalueexpandable
+ \def\temp{#2}%
+ \edef\next{\gdef\makecsname{SET#1}}%
+ \ifx\temp\empty
+ \next{}%
+ \else
+ \setzzz#2\endsetzzz
+ \fi
+ }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+ {%
+ \makevalueexpandable
+ \global\expandafter\let\csname SET#1\endcsname=\relax
+ }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+ \catcode`\- = \active \catcode`\_ = \active
+ %
+ \gdef\makevalueexpandable{%
+ \let\value = \expandablevalue
+ % We don't want these characters active, ...
+ \catcode`\-=\other \catcode`\_=\other
+ % ..., but we might end up with active ones in the argument if
+ % we're called from @code, as @code{@value{foo-bar_}}, though.
+ % So \let them to their normal equivalents.
+ \let-\normaldash \let_\normalunderscore
+ }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file. This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {[No value for ``#1'']}%
+ \message{Variable `#1', used in @value, is not set.}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+ {%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname SET#2\endcsname\relax
+ #1% If not set, redefine \next.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end executes the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written
+% without the @) is in fact defined. We can only feasibly check at the
+% TeX level, so something like `mathcode' is going to considered
+% defined even though it is not a Texinfo command.
+%
+\makecond{ifcommanddefined}
+\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}}
+%
+\def\doifcmddefined#1#2{{%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname #2\endcsname\relax
+ #1% If not defined, \let\next as above.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifcmddefinedfail{\doignore{ifcommanddefined}}
+
+% @ifcommandnotdefined CMD ... handled similar to @ifclear above.
+\makecond{ifcommandnotdefined}
+\def\ifcommandnotdefined{%
+ \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}}
+\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}}
+
+% Set the `txicommandconditionals' variable, so documents have a way to
+% test if the @ifcommand...defined conditionals are available.
+\set txicommandconditionals
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{% % Define @#1index
+ \noexpand\doindex{#1}}
+}
+
+% @defindex foo == \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{%
+ \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+ % Only do \closeout if we haven't already done it, else we'll end up
+ % closing the target index.
+ \expandafter \ifx\csname donesynindex#2\endcsname \relax
+ % The \closeout helps reduce unnecessary open files; the limit on the
+ % Acorn RISC OS is a mere 16 files.
+ \expandafter\closeout\csname#2indfile\endcsname
+ \expandafter\let\csname donesynindex#2\endcsname = 1
+ \fi
+ % redefine \fooindfile:
+ \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+ \expandafter\let\csname#2indfile\endcsname=\temp
+ % redefine \fooindex:
+ \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+ \escapechar = `\\ % use backslash in output files.
+ \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+ \def\ {\realbackslash\space }%
+ %
+ % Need these unexpandable (because we define \tt as a dummy)
+ % definitions when @{ or @} appear in index entry text. Also, more
+ % complicated, when \tex is in effect and \{ is a \delimiter again.
+ % We can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters. Perhaps we
+ % should define @lbrace and @rbrace commands a la @comma.
+ \def\{{{\tt\char123}}%
+ \def\}{{\tt\char125}}%
+ %
+ % I don't entirely understand this, but when an index entry is
+ % generated from a macro call, the \endinput which \scanmacro inserts
+ % causes processing to be prematurely terminated. This is,
+ % apparently, because \indexsorttmp is fully expanded, and \endinput
+ % is an expandable command. The redefinition below makes \endinput
+ % disappear altogether for that purpose -- although logging shows that
+ % processing continues to some further point. On the other hand, it
+ % seems \endinput does not hurt in the printed index arg, since that
+ % is still getting written without apparent harm.
+ %
+ % Sample source (mac-idx3.tex, reported by Graham Percival to
+ % help-texinfo, 22may06):
+ % @macro funindex {WORD}
+ % @findex xyz
+ % @end macro
+ % ...
+ % @funindex commtest
+ %
+ % The above is not enough to reproduce the bug, but it gives the flavor.
+ %
+ % Sample whatsit resulting:
+ % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+ %
+ % So:
+ \let\endinput = \empty
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% For the aux and toc files, @ is the escape character. So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files). When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+ \def\@{@@}%
+ \def\ {@ }%
+ \let\{ = \lbraceatcmd
+ \let\} = \rbraceatcmd
+ %
+ % Do the redefinitions.
+ \commondummies
+ \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+ %
+ % \definedummyword defines \#1 as \string\#1\space, thus effectively
+ % preventing its expansion. This is used only for control words,
+ % not control letters, because the \space would be incorrect for
+ % control characters, but is needed to separate the control word
+ % from whatever follows.
+ %
+ % For control letters, we have \definedummyletter, which omits the
+ % space.
+ %
+ % These can be used both for control words that take an argument and
+ % those that do not. If it is followed by {arg} in the input, then
+ % that will dutifully get written to the index (or wherever).
+ %
+ \def\definedummyword ##1{\def##1{\string##1\space}}%
+ \def\definedummyletter##1{\def##1{\string##1}}%
+ \let\definedummyaccent\definedummyletter
+ %
+ \commondummiesnofonts
+ %
+ \definedummyletter\_%
+ \definedummyletter\-%
+ %
+ % Non-English letters.
+ \definedummyword\AA
+ \definedummyword\AE
+ \definedummyword\DH
+ \definedummyword\L
+ \definedummyword\O
+ \definedummyword\OE
+ \definedummyword\TH
+ \definedummyword\aa
+ \definedummyword\ae
+ \definedummyword\dh
+ \definedummyword\exclamdown
+ \definedummyword\l
+ \definedummyword\o
+ \definedummyword\oe
+ \definedummyword\ordf
+ \definedummyword\ordm
+ \definedummyword\questiondown
+ \definedummyword\ss
+ \definedummyword\th
+ %
+ % Although these internal commands shouldn't show up, sometimes they do.
+ \definedummyword\bf
+ \definedummyword\gtr
+ \definedummyword\hat
+ \definedummyword\less
+ \definedummyword\sf
+ \definedummyword\sl
+ \definedummyword\tclose
+ \definedummyword\tt
+ %
+ \definedummyword\LaTeX
+ \definedummyword\TeX
+ %
+ % Assorted special characters.
+ \definedummyword\arrow
+ \definedummyword\bullet
+ \definedummyword\comma
+ \definedummyword\copyright
+ \definedummyword\registeredsymbol
+ \definedummyword\dots
+ \definedummyword\enddots
+ \definedummyword\entrybreak
+ \definedummyword\equiv
+ \definedummyword\error
+ \definedummyword\euro
+ \definedummyword\expansion
+ \definedummyword\geq
+ \definedummyword\guillemetleft
+ \definedummyword\guillemetright
+ \definedummyword\guilsinglleft
+ \definedummyword\guilsinglright
+ \definedummyword\lbracechar
+ \definedummyword\leq
+ \definedummyword\minus
+ \definedummyword\ogonek
+ \definedummyword\pounds
+ \definedummyword\point
+ \definedummyword\print
+ \definedummyword\quotedblbase
+ \definedummyword\quotedblleft
+ \definedummyword\quotedblright
+ \definedummyword\quoteleft
+ \definedummyword\quoteright
+ \definedummyword\quotesinglbase
+ \definedummyword\rbracechar
+ \definedummyword\result
+ \definedummyword\textdegree
+ %
+ % We want to disable all macros so that they are not expanded by \write.
+ \macrolist
+ %
+ \normalturnoffactive
+ %
+ % Handle some cases of @value -- where it does not contain any
+ % (non-fully-expandable) commands.
+ \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter\!%
+ \definedummyaccent\"%
+ \definedummyaccent\'%
+ \definedummyletter\*%
+ \definedummyaccent\,%
+ \definedummyletter\.%
+ \definedummyletter\/%
+ \definedummyletter\:%
+ \definedummyaccent\=%
+ \definedummyletter\?%
+ \definedummyaccent\^%
+ \definedummyaccent\`%
+ \definedummyaccent\~%
+ \definedummyword\u
+ \definedummyword\v
+ \definedummyword\H
+ \definedummyword\dotaccent
+ \definedummyword\ogonek
+ \definedummyword\ringaccent
+ \definedummyword\tieaccent
+ \definedummyword\ubaraccent
+ \definedummyword\udotaccent
+ \definedummyword\dotless
+ %
+ % Texinfo font commands.
+ \definedummyword\b
+ \definedummyword\i
+ \definedummyword\r
+ \definedummyword\sansserif
+ \definedummyword\sc
+ \definedummyword\slanted
+ \definedummyword\t
+ %
+ % Commands that take arguments.
+ \definedummyword\abbr
+ \definedummyword\acronym
+ \definedummyword\anchor
+ \definedummyword\cite
+ \definedummyword\code
+ \definedummyword\command
+ \definedummyword\dfn
+ \definedummyword\dmn
+ \definedummyword\email
+ \definedummyword\emph
+ \definedummyword\env
+ \definedummyword\file
+ \definedummyword\image
+ \definedummyword\indicateurl
+ \definedummyword\inforef
+ \definedummyword\kbd
+ \definedummyword\key
+ \definedummyword\math
+ \definedummyword\option
+ \definedummyword\pxref
+ \definedummyword\ref
+ \definedummyword\samp
+ \definedummyword\strong
+ \definedummyword\tie
+ \definedummyword\uref
+ \definedummyword\url
+ \definedummyword\var
+ \definedummyword\verb
+ \definedummyword\w
+ \definedummyword\xref
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names. It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+ % Accent commands should become @asis.
+ \def\definedummyaccent##1{\let##1\asis}%
+ % We can just ignore other control letters.
+ \def\definedummyletter##1{\let##1\empty}%
+ % All control words become @asis by default; overrides below.
+ \let\definedummyword\definedummyaccent
+ %
+ \commondummiesnofonts
+ %
+ % Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the active chars like <, >, |, etc.
+ % Likewise with the other plain tex font commands.
+ %\let\tt=\asis
+ %
+ \def\ { }%
+ \def\@{@}%
+ \def\_{\normalunderscore}%
+ \def\-{}% @- shouldn't affect sorting
+ %
+ % Unfortunately, texindex is not prepared to handle braces in the
+ % content at all. So for index sorting, we map @{ and @} to strings
+ % starting with |, since that ASCII character is between ASCII { and }.
+ \def\{{|a}%
+ \def\lbracechar{|a}%
+ %
+ \def\}{|b}%
+ \def\rbracechar{|b}%
+ %
+ % Non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\DH{DZZ}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\TH{ZZZ}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\dh{dzz}%
+ \def\exclamdown{!}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ \def\o{o}%
+ \def\questiondown{?}%
+ \def\ss{ss}%
+ \def\th{zzz}%
+ %
+ \def\LaTeX{LaTeX}%
+ \def\TeX{TeX}%
+ %
+ % Assorted special characters.
+ % (The following {} will end up in the sort string, but that's ok.)
+ \def\arrow{->}%
+ \def\bullet{bullet}%
+ \def\comma{,}%
+ \def\copyright{copyright}%
+ \def\dots{...}%
+ \def\enddots{...}%
+ \def\equiv{==}%
+ \def\error{error}%
+ \def\euro{euro}%
+ \def\expansion{==>}%
+ \def\geq{>=}%
+ \def\guillemetleft{<<}%
+ \def\guillemetright{>>}%
+ \def\guilsinglleft{<}%
+ \def\guilsinglright{>}%
+ \def\leq{<=}%
+ \def\minus{-}%
+ \def\point{.}%
+ \def\pounds{pounds}%
+ \def\print{-|}%
+ \def\quotedblbase{"}%
+ \def\quotedblleft{"}%
+ \def\quotedblright{"}%
+ \def\quoteleft{`}%
+ \def\quoteright{'}%
+ \def\quotesinglbase{,}%
+ \def\registeredsymbol{R}%
+ \def\result{=>}%
+ \def\textdegree{o}%
+ %
+ \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax
+ \else \indexlquoteignore \fi
+ %
+ % We need to get rid of all macros, leaving only the arguments (if present).
+ % Of course this is not nearly correct, but it is the best we can do for now.
+ % makeinfo does not expand macros in the argument to @deffn, which ends up
+ % writing an index entry, and texindex isn't prepared for an index sort entry
+ % that starts with \.
+ %
+ % Since macro invocations are followed by braces, we can just redefine them
+ % to take a single TeX argument. The case of a macro invocation that
+ % goes to end-of-line is not handled.
+ %
+ \macrolist
+}
+
+% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us
+% ignore left quotes in the sort term.
+{\catcode`\`=\active
+ \gdef\indexlquoteignore{\let`=\empty}}
+
+\let\indexbackslash=0 %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+ \iflinks
+ {%
+ % Store the main index entry text (including the third arg).
+ \toks0 = {#2}%
+ % If third arg is present, precede it with a space.
+ \def\thirdarg{#3}%
+ \ifx\thirdarg\empty \else
+ \toks0 = \expandafter{\the\toks0 \space #3}%
+ \fi
+ %
+ \edef\writeto{\csname#1indfile\endcsname}%
+ %
+ \safewhatsit\dosubindwrite
+ }%
+ \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+ \fi
+ %
+ % Remember, we are within a group.
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % Process the index entry with all font commands turned off, to
+ % get the string to sort by.
+ {\indexnofonts
+ \edef\temp{\the\toks0}% need full expansion
+ \xdef\indexsorttmp{\temp}%
+ }%
+ %
+ % Set up the complete index entry, with both the sort key and
+ % the original text, including any font commands. We write
+ % three arguments to \entry to the .?? file (four in the
+ % subentry case), texindex reduces to two when writing the .??s
+ % sorted result.
+ \edef\temp{%
+ \write\writeto{%
+ \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+ }%
+ \temp
+}
+
+% Take care of unwanted page breaks/skips around a whatsit:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again. Otherwise, the whatsit generated by the
+% \write or \pdfdest will make \lastskip zero. The result is that
+% sequences like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode. We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip. \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip. The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
+% ..., ready, GO:
+%
+\def\safewhatsit#1{\ifhmode
+ #1%
+ \else
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \whatsitskip = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \whatsitpenalty = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\whatsitskip glue we're inserting is preceded by a
+ % non-discardable item, therefore it is not a potential
+ % breakpoint, therefore no \nobreak needed.
+ \ifx\lastskipmacro\zeroskipmacro
+ \else
+ \vskip-\whatsitskip
+ \fi
+ %
+ #1%
+ %
+ \ifx\lastskipmacro\zeroskipmacro
+ % If \lastskip was zero, perhaps the last item was a penalty, and
+ % perhaps it was >=10000, e.g., a \nobreak. In that case, we want
+ % to re-insert the same penalty (values >10000 are used for various
+ % signals); since we just inserted a non-discardable item, any
+ % following glue (such as a \parskip) would be a breakpoint. For example:
+ % @deffn deffn-whatever
+ % @vindex index-whatever
+ % Description.
+ % would allow a break between the index-whatever whatsit
+ % and the "Description." paragraph.
+ \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
+ \else
+ % On the other hand, if we had a nonzero \lastskip,
+ % this make-up glue would be preceded by a non-discardable item
+ % (the whatsit from the \write), so we must insert a \nobreak.
+ \nobreak\vskip\whatsitskip
+ \fi
+\fi}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \smallfonts \rm
+ \tolerance = 9500
+ \plainfrenchspacing
+ \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+ %
+ % See if the index file exists and is nonempty.
+ % Change catcode of @ here so that if the index file contains
+ % \initial {@}
+ % as its first line, TeX doesn't complain about mismatched braces
+ % (because it thinks @} is a control sequence).
+ \catcode`\@ = 11
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ \putwordIndexNonexistent
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ \putwordIndexIsEmpty
+ \else
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \def\indexbackslash{\backslashcurfont}%
+ \catcode`\\ = 0
+ \escapechar = `\\
+ \begindoublecolumns
+ \input \jobname.#1s
+ \enddoublecolumns
+ \fi
+ \fi
+ \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+ % Some minor font changes for the special characters.
+ \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+ %
+ % Remove any glue we may have, we'll be inserting our own.
+ \removelastskip
+ %
+ % We like breaks before the index initials, so insert a bonus.
+ \nobreak
+ \vskip 0pt plus 3\baselineskip
+ \penalty 0
+ \vskip 0pt plus -3\baselineskip
+ %
+ % Typeset the initial. Making this add up to a whole number of
+ % baselineskips increases the chance of the dots lining up from column
+ % to column. It still won't often be perfect, because of the stretch
+ % we need before each entry, but it's better.
+ %
+ % No shrink because it confuses \balancecolumns.
+ \vskip 1.67\baselineskip plus .5\baselineskip
+ \leftline{\secbf #1}%
+ % Do our best not to break after the initial.
+ \nobreak
+ \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin. It is used for index
+% and table of contents entries. The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+% \def\entry#1#2{...
+% But this freezes the catcodes in the argument, and can cause problems to
+% @code, which sets - active. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+% The right solution is to prevent \entry from swallowing the whole text.
+% --kasal, 21nov03
+\def\entry{%
+ \begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent = 2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % A bit of stretch before each entry for the benefit of balancing
+ % columns.
+ \vskip 0pt plus1pt
+ %
+ % When reading the text of entry, convert explicit line breaks
+ % from @* into spaces. The user might give these in long section
+ % titles, for instance.
+ \def\*{\unskip\space\ignorespaces}%
+ \def\entrybreak{\hfil\break}%
+ %
+ % Swallow the left brace of the text (first parameter):
+ \afterassignment\doentry
+ \let\temp =
+}
+\def\entrybreak{\unskip\space\ignorespaces}%
+\def\doentry{%
+ \bgroup % Instead of the swallowed brace.
+ \noindent
+ \aftergroup\finishentry
+ % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+ % #1 is the page number.
+ %
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \setbox\boxA = \hbox{#1}%
+ \ifdim\wd\boxA = 0pt
+ \ %
+ \else
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ifpdf
+ \pdfgettoks#1.%
+ \ \the\toksA
+ \else
+ \ #1%
+ \fi
+ \fi
+ \par
+ \endgroup
+}
+
+% Like plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+ \parfillskip=0in
+ \parskip=0in
+ \hangindent=1in
+ \hangafter=1
+ \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+ \ifpdf
+ \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+ \else
+ #2
+ \fi
+ \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+ % Grab any single-column material above us.
+ \output = {%
+ %
+ % Here is a possibility not foreseen in manmac: if we accumulate a
+ % whole lot of material, we might end up calling this \output
+ % routine twice in a row (see the doublecol-lose test, which is
+ % essentially a couple of indexes with @setchapternewpage off). In
+ % that case we just ship out what is in \partialpage with the normal
+ % output routine. Generally, \partialpage will be empty when this
+ % runs and this will be a no-op. See the indexspread.tex test case.
+ \ifvoid\partialpage \else
+ \onepageout{\pagecontents\partialpage}%
+ \fi
+ %
+ \global\setbox\partialpage = \vbox{%
+ % Unvbox the main output page.
+ \unvbox\PAGE
+ \kern-\topskip \kern\baselineskip
+ }%
+ }%
+ \eject % run that output routine to set \partialpage
+ %
+ % Use the double-column output routine for subsequent pages.
+ \output = {\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it in one place.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +-<1pt)
+ % as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@ = \vsize
+ \divide\dimen@ by 2
+ \advance\dimen@ by -\ht\partialpage
+ %
+ % box0 will be the left-hand column, box2 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255
+ \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+ \unvbox\partialpage
+ %
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize
+ \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+ % The following penalty ensures that the page builder is exercised
+ % _before_ we change the output routine. This is necessary in the
+ % following situation:
+ %
+ % The last section of the index consists only of a single entry.
+ % Before this section, \pagetotal is less than \pagegoal, so no
+ % break occurs before the last section starts. However, the last
+ % section, consisting of \initial and the single \entry, does not
+ % fit on the page and has to be broken off. Without the following
+ % penalty the page builder will not be exercised until \eject
+ % below, and by that time we'll already have changed the output
+ % routine to the \balancecolumns version, so the next-to-last
+ % double-column page will be processed with \balancecolumns, which
+ % is wrong: The two columns will go to the main vertical list, with
+ % the broken-off section in the recent contributions. As soon as
+ % the output routine finishes, TeX starts reconsidering the page
+ % break. The two columns and the broken-off section both fit on the
+ % page, because the two columns now take up only half of the page
+ % goal. When TeX sees \eject from below which follows the final
+ % section, it invokes the new output routine that we've set after
+ % \balancecolumns below; \onepageout will try to fit the two columns
+ % and the final section into the vbox of \pageheight (see
+ % \pagebody), causing an overfull box.
+ %
+ % Note that glue won't work here, because glue does not exercise the
+ % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+ \penalty0
+ %
+ \output = {%
+ % Split the last of the double-column material. Leave it on the
+ % current page, no automatic page break.
+ \balancecolumns
+ %
+ % If we end up splitting too much material for the current page,
+ % though, there will be another page break right after this \output
+ % invocation ends. Having called \balancecolumns once, we do not
+ % want to call it again. Therefore, reset \output to its normal
+ % definition right away. (We hope \balancecolumns will never be
+ % called on to balance too much material, but if it is, this makes
+ % the output somewhat more palatable.)
+ \global\output = {\onepageout{\pagecontents\PAGE}}%
+ }%
+ \eject
+ \endgroup % started in \begindoublecolumns
+ %
+ % \pagegoal was set to the doubled \vsize above, since we restarted
+ % the current page. We're now back to normal single-column
+ % typesetting, so reset \pagegoal to the normal \vsize (after the
+ % \endgroup where \vsize got restored).
+ \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+ \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2 % target to split to
+ %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {%
+ \vbadness = 10000
+ \loop
+ \global\setbox3 = \copy0
+ \global\setbox1 = \vsplit3 to \dimen@
+ \ifdim\ht3>\dimen@
+ \global\advance\dimen@ by 1pt
+ \repeat
+ }%
+ %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ %
+ \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% Let's start with @part.
+\outer\parseargdef\part{\partzzz{#1}}
+\def\partzzz#1{%
+ \chapoddpage
+ \null
+ \vskip.3\vsize % move it down on the page a bit
+ \begingroup
+ \noindent \titlefonts\rmisbold #1\par % the text
+ \let\lastnode=\empty % no node to associate with
+ \writetocentry{part}{#1}{}% but put it in the toc
+ \headingsoff % no headline or footline on the part page
+ \chapoddpage
+ \endgroup
+}
+
+% \unnumberedno is an oxymoron. But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number". We avoid collisions with chapter
+% numbers by starting them at 10000. (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno \secno=0
+\newcount\subsecno \subsecno=0
+\newcount\subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+ \ifnum\appendixno=`A A%
+ \else\ifnum\appendixno=`B B%
+ \else\ifnum\appendixno=`C C%
+ \else\ifnum\appendixno=`D D%
+ \else\ifnum\appendixno=`E E%
+ \else\ifnum\appendixno=`F F%
+ \else\ifnum\appendixno=`G G%
+ \else\ifnum\appendixno=`H H%
+ \else\ifnum\appendixno=`I I%
+ \else\ifnum\appendixno=`J J%
+ \else\ifnum\appendixno=`K K%
+ \else\ifnum\appendixno=`L L%
+ \else\ifnum\appendixno=`M M%
+ \else\ifnum\appendixno=`N N%
+ \else\ifnum\appendixno=`O O%
+ \else\ifnum\appendixno=`P P%
+ \else\ifnum\appendixno=`Q Q%
+ \else\ifnum\appendixno=`R R%
+ \else\ifnum\appendixno=`S S%
+ \else\ifnum\appendixno=`T T%
+ \else\ifnum\appendixno=`U U%
+ \else\ifnum\appendixno=`V V%
+ \else\ifnum\appendixno=`W W%
+ \else\ifnum\appendixno=`X X%
+ \else\ifnum\appendixno=`Y Y%
+ \else\ifnum\appendixno=`Z Z%
+ % The \the is necessary, despite appearances, because \appendixletter is
+ % expanded while writing the .toc file. \char\appendixno is not
+ % expandable, thus it is written literally, thus all appendixes come out
+ % with the same letter (or @) in the toc without it.
+ \else\char\the\appendixno
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines these (using marks) as the number+name, number
+% and name of the chapter. Page headings and footings can use
+% these. @section does likewise.
+\def\thischapter{}
+\def\thischapternum{}
+\def\thischaptername{}
+\def\thissection{}
+\def\thissectionnum{}
+\def\thissectionname{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achieve this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unnlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+ % Compute the abs. sec. level:
+ \absseclevel=#2
+ \advance\absseclevel by \secbase
+ % Make sure \absseclevel doesn't fall outside the range:
+ \ifnum \absseclevel < 0
+ \absseclevel = 0
+ \else
+ \ifnum \absseclevel > 3
+ \absseclevel = 3
+ \fi
+ \fi
+ % The heading type:
+ \def\headtype{#1}%
+ \if \headtype U%
+ \ifnum \absseclevel < \unnlevel
+ \chardef\unnlevel = \absseclevel
+ \fi
+ \else
+ % Check for appendix sections:
+ \ifnum \absseclevel = 0
+ \edef\chapheadtype{\headtype}%
+ \else
+ \if \headtype A\if \chapheadtype N%
+ \errmessage{@appendix... within a non-appendix chapter}%
+ \fi\fi
+ \fi
+ % Check for numbered within unnumbered:
+ \ifnum \absseclevel > \unnlevel
+ \def\headtype{U}%
+ \else
+ \chardef\unnlevel = 3
+ \fi
+ \fi
+ % Now print the heading:
+ \if \headtype U%
+ \ifcase\absseclevel
+ \unnumberedzzz{#3}%
+ \or \unnumberedseczzz{#3}%
+ \or \unnumberedsubseczzz{#3}%
+ \or \unnumberedsubsubseczzz{#3}%
+ \fi
+ \else
+ \if \headtype A%
+ \ifcase\absseclevel
+ \appendixzzz{#3}%
+ \or \appendixsectionzzz{#3}%
+ \or \appendixsubseczzz{#3}%
+ \or \appendixsubsubseczzz{#3}%
+ \fi
+ \else
+ \ifcase\absseclevel
+ \chapterzzz{#3}%
+ \or \seczzz{#3}%
+ \or \numberedsubseczzz{#3}%
+ \or \numberedsubsubseczzz{#3}%
+ \fi
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered. Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v. By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+ % section resetting is \global in case the chapter is in a group, such
+ % as an @include file.
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\chapno by 1
+ %
+ % Used for \float.
+ \gdef\chaplevelprefix{\the\chapno.}%
+ \resetallfloatnos
+ %
+ % \putwordChapter can contain complex things in translations.
+ \toks0=\expandafter{\putwordChapter}%
+ \message{\the\toks0 \space \the\chapno}%
+ %
+ % Write the actual heading.
+ \chapmacro{#1}{Ynumbered}{\the\chapno}%
+ %
+ % So @section and the like are numbered underneath this chapter.
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz
+%
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \gdef\chaplevelprefix{\appendixletter.}%
+ \resetallfloatnos
+ %
+ % \putwordAppendix can contain complex things in translations.
+ \toks0=\expandafter{\putwordAppendix}%
+ \message{\the\toks0 \space \appendixletter}%
+ %
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ %
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+}
+
+% normally unnmhead0 calls unnumberedzzz:
+\outer\parseargdef\unnumbered{\unnmhead0{#1}}
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % Since an unnumbered has no number, no prefix for figures.
+ \global\let\chaplevelprefix = \empty
+ \resetallfloatnos
+ %
+ % This used to be simply \message{#1}, but TeX fully expands the
+ % argument to \message. Therefore, if #1 contained @-commands, TeX
+ % expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+ % expanded @cite (which turns out to cause errors because \cite is meant
+ % to be executed, not expanded).
+ %
+ % Anyway, we don't want the fully-expanded definition of @cite to appear
+ % as a result of the \message, we just want `@cite' itself. We use
+ % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+ % simply yielding the contents of <toks register>. (We also do this for
+ % the toc entries.)
+ \toks0 = {#1}%
+ \message{(\the\toks0)}%
+ %
+ \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+ %
+ \global\let\section = \unnumberedsec
+ \global\let\subsection = \unnumberedsubsec
+ \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+ % Well, we could do the following in a group, but that would break
+ % an assumption that \chapmacro is called at the outermost level.
+ % Thus we are safer this way: --kasal, 24feb04
+ \let\centerparametersmaybe = \centerparameters
+ \unnmhead0{#1}%
+ \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+%
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+% normally calls appendixsectionzzz:
+\outer\parseargdef\appendixsection{\apphead1{#1}}
+\def\appendixsectionzzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+% normally calls unnumberedseczzz:
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}}
+\def\unnumberedseczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+%
+% normally calls numberedsubseczzz:
+\outer\parseargdef\numberedsubsec{\numhead2{#1}}
+\def\numberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+% normally calls appendixsubseczzz:
+\outer\parseargdef\appendixsubsec{\apphead2{#1}}
+\def\appendixsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+% normally calls unnumberedsubseczzz:
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}}
+\def\unnumberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+%
+% normally numberedsubsubseczzz:
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}}
+\def\numberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynumbered}%
+ {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% normally appendixsubsubseczzz:
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}}
+\def\appendixsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% normally unnumberedsubsubseczzz:
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}}
+\def\unnumberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+\def\majorheading{%
+ {\advance\chapheadingskip by 10pt \chapbreak }%
+ \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip \nobreak
+ \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+% Parameter controlling skip before chapter headings (if needed)
+\newskip\chapheadingskip
+
+% Define plain chapter starts, and page on/off switching for it.
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+% Because \domark is called before \chapoddpage, the filler page will
+% get the headings for the next chapter, which is wrong. But we don't
+% care -- we just disable all headings on the filler page.
+\def\chapoddpage{%
+ \chappager
+ \ifodd\pageno \else
+ \begingroup
+ \headingsoff
+ \null
+ \chappager
+ \endgroup
+ \fi
+}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+ % Insert the first mark before the heading break (see notes for \domark).
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
+ \gdef\thissection{}}%
+ %
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{\thischaptername}}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{}}%
+ \else\ifx\temptype\Yappendixkeyword
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\appendixletter}%
+ % \noexpand\putwordAppendix avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordAppendix{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \else
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\the\chapno}%
+ % \noexpand\putwordChapter avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordChapter{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \fi\fi\fi
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert the chapter heading break.
+ \pchapsepmacro
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ {%
+ \chapfonts \rmisbold
+ %
+ % Have to define \lastsection before calling \donoderef, because the
+ % xref code eventually uses it. On the other hand, it has to be called
+ % after \pchapsepmacro, or the headline will change too soon.
+ \gdef\lastsection{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \fi\fi\fi
+ %
+ % Write the toc entry for this chapter. Must come before the
+ % \donoderef, because we include the current node name in the toc
+ % entry, and \donoderef resets it to empty.
+ \writetocentry{\toctype}{#1}{#3}%
+ %
+ % For pdftex, we have to write out the node definition (aka, make
+ % the pdfdest) after any page break, but before the actual text has
+ % been typeset. If the destination for the pdf outline is after the
+ % text, then jumping from the outline may wind up with the text not
+ % being visible, for instance under high magnification.
+ \donoderef{#2}%
+ %
+ % Typeset the actual heading.
+ \nobreak % Avoid page breaks at the interline glue.
+ \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
+ }%
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff. We'll see. --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}%
+ \nobreak\bigskip \nobreak
+}
+\def\CHAPFopen{%
+ \global\let\chapmacro=\chfopen
+ \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles. These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\seckeyword{sec}
+%
+\def\sectionheading#1#2#3#4{%
+ {%
+ \checkenv{}% should not be in an environment.
+ %
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rmisbold
+ %
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ % Insert first mark before the heading break (see notes for \domark).
+ \let\prevsectiondefs=\lastsectiondefs
+ \ifx\temptype\Ynothingkeyword
+ \ifx\sectionlevel\seckeyword
+ \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
+ \gdef\thissection{\thissectionname}}%
+ \fi
+ \else\ifx\temptype\Yomitfromtockeyword
+ % Don't redefine \thissection.
+ \else\ifx\temptype\Yappendixkeyword
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \else
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \fi\fi\fi
+ %
+ % Go into vertical mode. Usually we'll already be there, but we
+ % don't want the following whatsit to end up in a preceding paragraph
+ % if the document didn't happen to have a blank line.
+ \par
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ % Only insert the space after the number if we have a section number.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\lastsection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \lastsection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\lastsection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\lastsection{#1}%
+ \fi\fi\fi
+ %
+ % Write the toc entry (before \donoderef). See comments in \chapmacro.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chapmacro.
+ \donoderef{#3}%
+ %
+ % Interline glue will be inserted when the vbox is completed.
+ % That glue will be a valid breakpoint for the page, since it'll be
+ % preceded by a whatsit (usually from the \donoderef, or from the
+ % \writetocentry if there was no node). We don't want to allow that
+ % break, since then the whatsits could end up on page n while the
+ % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000.
+ \nobreak
+ %
+ % Output the actual section heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
+ \hangindent=\wd0 % zero if no section number
+ \unhbox0 #1}%
+ }%
+ % Add extra space after the heading -- half of whatever came above it.
+ % Don't allow stretch, though.
+ \kern .5 \csname #2headingskip\endcsname
+ %
+ % Do not let the kern be a potential breakpoint, as it would be if it
+ % was followed by glue.
+ \nobreak
+ %
+ % We'll almost certainly start a paragraph next, so don't let that
+ % glue accumulate. (Not a breakpoint because it's preceded by a
+ % discardable item.) However, when a paragraph is not started next
+ % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out
+ % or the negative glue will cause weirdly wrong output, typically
+ % obscuring the section heading with something else.
+ \vskip-\parskip
+ %
+ % This is so the last item on the main vertical list is a known
+ % \penalty > 10000, so \startdefun, etc., can recognize the situation
+ % and do the needful.
+ \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this. The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything. This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+ \edef\writetoctype{#1}%
+ \ifx\writetoctype\omitkeyword \else
+ \iftocfileopened\else
+ \immediate\openout\tocfile = \jobname.toc
+ \global\tocfileopenedtrue
+ \fi
+ %
+ \iflinks
+ {\atdummies
+ \edef\temp{%
+ \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+ \temp
+ }%
+ \fi
+ \fi
+ %
+ % Tell \shipout to create a pdf destination on each page, if we're
+ % writing pdf. These are used in the table of contents. We can't
+ % just write one on every page because the title pages are numbered
+ % 1 and 2 (the page numbers aren't printed), and so are the first
+ % two pages of the document. Thus, we'd have two destinations named
+ % `1', and two named `2'.
+ \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care. This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+%
+\def\activecatcodes{%
+ \catcode`\"=\active
+ \catcode`\$=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
+ \catcode`\\=\active
+ \catcode`\^=\active
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+ \setupdatafile
+ \activecatcodes
+ \input \tocreadfilename
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout\tocfile
+ %
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+ %
+ % Roman numerals for page numbers.
+ \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+% redefined for the two-volume lispref. We always output on
+% \jobname.toc even if this is redefined.
+%
+\def\tocreadfilename{\jobname.toc}
+
+% Normal (long) toc.
+%
+\def\contents{%
+ \startcontents{\putwordTOC}%
+ \openin 1 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \ifeof 1 \else
+ \pdfmakeoutlines
+ \fi
+ \closein 1
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+ \startcontents{\putwordShortTOC}%
+ %
+ \let\partentry = \shortpartentry
+ \let\numchapentry = \shortchapentry
+ \let\appentry = \shortchapentry
+ \let\unnchapentry = \shortunnchapentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf
+ \let\sl=\shortcontsl \let\tt=\shortconttt
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\numsecentry##1##2##3##4{}
+ \let\appsecentry = \numsecentry
+ \let\unnsecentry = \numsecentry
+ \let\numsubsecentry = \numsecentry
+ \let\appsubsecentry = \numsecentry
+ \let\unnsubsecentry = \numsecentry
+ \let\numsubsubsecentry = \numsecentry
+ \let\appsubsubsecentry = \numsecentry
+ \let\unnsubsubsecentry = \numsecentry
+ \openin 1 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \closein 1
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+ % This space should be enough, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % But use \hss just in case.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ %
+ % We'd like to right-justify chapter numbers, but that looks strange
+ % with appendix letters. And right-justifying numbers and
+ % left-justifying letters looks strange when there is less than 10
+ % chapters. Have to read the whole toc once to know how many chapters
+ % there are before deciding ...
+ \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Parts, in the main contents. Replace the part number, which doesn't
+% exist, with an empty box. Let's hope all the numbers have the same width.
+% Also ignore the page number, which is conventionally not printed.
+\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}}
+\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}}
+%
+% Parts, in the short toc.
+\def\shortpartentry#1#2#3#4{%
+ \penalty-300
+ \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip
+ \shortchapentry{{\bf #1}}{\numeralbox}{}{}%
+}
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+ % We use M since it's probably the widest letter.
+ \setbox0 = \hbox{\putwordAppendix{} M}%
+ \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @tex ... @end tex escapes into raw TeX temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain @ character.
+
+\envdef\tex{%
+ \setupmarkupstyle{tex}%
+ \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+ \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+ \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+ \catcode `\%=14
+ \catcode `\+=\other
+ \catcode `\"=\other
+ \catcode `\|=\other
+ \catcode `\<=\other
+ \catcode `\>=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
+ \escapechar=`\\
+ %
+ % ' is active in math mode (mathcode"8000). So reset it, and all our
+ % other math active characters (just in case), to plain's definitions.
+ \mathactive
+ %
+ \let\b=\ptexb
+ \let\bullet=\ptexbullet
+ \let\c=\ptexc
+ \let\,=\ptexcomma
+ \let\.=\ptexdot
+ \let\dots=\ptexdots
+ \let\equiv=\ptexequiv
+ \let\!=\ptexexclam
+ \let\i=\ptexi
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \let\{=\ptexlbrace
+ \let\+=\tabalign
+ \let\}=\ptexrbrace
+ \let\/=\ptexslash
+ \let\*=\ptexstar
+ \let\t=\ptext
+ \expandafter \let\csname top\endcsname=\ptextop % outer
+ \let\frenchspacing=\plainfrenchspacing
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+ % =10000 instead of <10000 because of a special case in \itemzzz and
+ % \sectionheading, q.v.
+ \ifnum \lastpenalty=10000 \else
+ \advance\envskipamount by \parskip
+ \endgraf
+ \ifdim\lastskip<\envskipamount
+ \removelastskip
+ % it's not a good place to break if the last penalty was \nobreak
+ % or better ...
+ \ifnum\lastpenalty<10000 \penalty-50 \fi
+ \vskip\envskipamount
+ \fi
+ \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+ \ifhmode\par\fi % can't be in the midst of a paragraph.
+ \startsavinginserts
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt % we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ % side, and for 6pt waste from
+ % each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing = t%
+ %
+ % If this cartouche directly follows a sectioning command, we need the
+ % \parskip glue (backspaced over by default) or the cartouche can
+ % collide with the section heading.
+ \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi
+ %
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \kern3pt
+ \hsize=\cartinner
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+ \comment % For explanation, see the end of def\group.
+}
+\def\Ecartouche{%
+ \ifhmode\par\fi
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+ \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\newdimen\nonfillparindent
+\def\nonfillstart{%
+ \aboveenvbreak
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ % Turn off paragraph indentation but redefine \indent to emulate
+ % the normal \indent.
+ \nonfillparindent=\parindent
+ \parindent = 0pt
+ \let\indent\nonfillindent
+ %
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \let\exdent=\nofillexdent
+}
+
+\begingroup
+\obeyspaces
+% We want to swallow spaces (but not other tokens) after the fake
+% @indent in our nonfill-environments, where spaces are normally
+% active and set to @tie, resulting in them not being ignored after
+% @indent.
+\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}%
+\gdef\nonfillindentcheck{%
+\ifx\temp %
+\expandafter\nonfillindentgobble%
+\else%
+\leavevmode\nonfillindentbox%
+\fi%
+}%
+\endgroup
+\def\nonfillindentgobble#1{\nonfillindent}
+\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+% @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+ \ifx\SETdispenvsize\smallword
+ % end paragraph for sake of leading, in case document has no blank
+ % line. This is redundant with what happens in \aboveenvbreak, but
+ % we need to do it before changing the fonts, and it's inconvenient
+ % to change the fonts afterward.
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+\def\setsmalldispenv{%
+ \ifx\SETdispenvsize\nosmallword
+ \else
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it in one command. #1 is the env name, #2 the definition.
+\def\makedispenvdef#1#2{%
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}%
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}%
+ \expandafter\let\csname E#1\endcsname \afterenvbreak
+ \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two environment synonyms (#1 and #2) for an environment.
+\def\maketwodispenvdef#1#2#3{%
+ \makedispenvdef{#1}{#3}%
+ \makedispenvdef{#2}{#3}%
+}
+%
+% @lisp: indented, narrowed, typewriter font;
+% @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvdef{lisp}{example}{%
+ \nonfillstart
+ \tt\setupmarkupstyle{example}%
+ \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+ \gobble % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenvdef{display}{%
+ \nonfillstart
+ \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenvdef{format}{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \advance\leftskip by 0pt plus 1fill\relax
+ \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @raggedright does more-or-less normal line breaking but no right
+% justification. From plain.tex.
+\envdef\raggedright{%
+ \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax
+}
+\let\Eraggedright\par
+
+\envdef\raggedleft{%
+ \parindent=0pt \leftskip0pt plus2em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedleft\par
+
+\envdef\raggedcenter{%
+ \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedcenter\par
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins. We keep \parskip nonzero in general, since
+% we're doing normal filling. So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\makedispenvdef{quotation}{\quotationstart}
+%
+\def\quotationstart{%
+ \indentedblockstart % same as \indentedblock, but increase right margin too.
+ \ifx\nonarrowing\relax
+ \advance\rightskip by \lispnarrowing
+ \fi
+ \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+ \par
+ \ifx\quotationauthor\thisisundefined\else
+ % indent a bit.
+ \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+ \fi
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallquotation{\Equotation}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty \else
+ {\bf #1: }%
+ \fi
+}
+
+% @indentedblock is like @quotation, but indents only on the left and
+% has no optional argument.
+%
+\makedispenvdef{indentedblock}{\indentedblockstart}
+%
+\def\indentedblockstart{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+}
+
+% Keep a nonzero parskip for the environment, since we're doing normal filling.
+%
+\def\Eindentedblock{%
+ \par
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallindentedblock{\Eindentedblock}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too. Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+ \do\ \do\\\do\{\do\}\do\$\do\&%
+ \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+ \do\<\do\>\do\|\do\@\do+\do\"%
+ % Don't do the quotes -- if we do, @set txicodequoteundirected and
+ % @set txicodequotebacktick will not have effect on @verb and
+ % @verbatim, and ?` and !` ligatures won't get disabled.
+ %\do\`\do\'%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+ \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+ \tt % easiest (and conventionally used) font for verbatim
+ \def\par{\leavevmode\endgraf}%
+ \setupmarkupstyle{verb}%
+ \tabeightspaces
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion.
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+% We typeset each line of the verbatim in an \hbox, so we can handle
+% tabs. The \global is in case the verbatim line starts with an accent,
+% or some other command that starts with a begin-group. Otherwise, the
+% entire \verbbox would disappear at the corresponding end-group, before
+% it is typeset. Meanwhile, we can't have nested verbatim commands
+% (can we?), so the \global won't be overwriting itself.
+\newbox\verbbox
+\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup}
+%
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabexpand{%
+ \catcode`\^^I=\active
+ \def^^I{\leavevmode\egroup
+ \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab
+ \divide\dimen\verbbox by\tabw
+ \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw
+ \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw
+ \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox
+ }%
+ }
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \tt % easiest (and conventionally used) font for verbatim
+ % The \leavevmode here is for blank lines. Otherwise, we would
+ % never \starttabox and the \egroup would end verbatim mode.
+ \def\par{\leavevmode\egroup\box\verbbox\endgraf}%
+ \tabexpand
+ \setupmarkupstyle{verbatim}%
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count.
+ % Must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+ \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters. Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+% \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+ \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+ \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+% \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+ \catcode`\ =\active
+ \obeylines %
+ % ignore everything up to the first ^^M, that's the newline at the end
+ % of the @verbatim input line itself. Otherwise we get an extra blank
+ % line in the output.
+ \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+ % We really want {...\end verbatim} in the body of the macro, but
+ % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+ \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+ {%
+ \makevalueexpandable
+ \setupverbatim
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}%
+ \input #1
+ \afterenvbreak
+ }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+ \begingroup
+ \parindent = 0pt % paragraph indentation looks wrong on title page
+ \scanexp\copyingtext
+ \endgroup
+}
+
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
+
+% Start the processing of @deffn:
+\def\startdefun{%
+ \ifnum\lastpenalty<10000
+ \medbreak
+ \defunpenalty=10003 % Will keep this @deffn together with the
+ % following @def command, see below.
+ \else
+ % If there are two @def commands in a row, we'll have a \nobreak,
+ % which is there to keep the function description together with its
+ % header. But if there's nothing but headers, we need to allow a
+ % break somewhere. Check specifically for penalty 10002, inserted
+ % by \printdefunline, instead of 10000, since the sectioning
+ % commands also insert a nobreak penalty, and we don't want to allow
+ % a break between a section heading and a defun.
+ %
+ % As a further refinement, we avoid "club" headers by signalling
+ % with penalty of 10003 after the very first @deffn in the
+ % sequence (see above), and penalty of 10002 after any following
+ % @def command.
+ \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
+ %
+ % Similarly, after a section heading, do not allow a break.
+ % But do insert the glue.
+ \medskip % preceded by discardable penalty, so not a breakpoint
+ \fi
+ %
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+ % First, check whether we are in the right environment:
+ \checkenv#1%
+ %
+ % As above, allow line break if we have multiple x headers in a row.
+ % It's not a great place, though.
+ \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
+ %
+ % And now, it's time to reuse the body of the original defun:
+ \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+ \begingroup
+ % call \deffnheader:
+ #1#2 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil\relax
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty\defunpenalty % signal to \startdefun and \dodefunx
+ % Some of the @defun-type tags do not enable magic parentheses,
+ % rendering the following check redundant. But we don't optimize.
+ \checkparencounts
+ \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remaining is to define \deffnheader.
+%
+\def\makedefun#1{%
+ \expandafter\let\csname E#1\endcsname = \Edefun
+ \edef\temp{\noexpand\domakedefun
+ \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+ \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+ \envdef#1{%
+ \startdefun
+ \doingtypefnfalse % distinguish typed functions from all else
+ \parseargusing\activeparens{\printdefunline#3}%
+ }%
+ \def#2{\dodefunx#1}%
+ \def#3%
+}
+
+\newif\ifdoingtypefn % doing typed function?
+\newif\ifrettypeownline % typeset return type on its own line?
+
+% @deftypefnnewline on|off says whether the return type of typed functions
+% are printed on their own line. This affects @deftypefn, @deftypefun,
+% @deftypeop, and @deftypemethod.
+%
+\parseargdef\deftypefnnewline{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @txideftypefnnl value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+ % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{fn}{\code{#4}}{#1}%
+ \doingtypefntrue
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{vr}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+% Types:
+
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+ \par
+ % Get the values of \leftskip and \rightskip as they were outside the @def...
+ \advance\leftskip by -\defbodyindent
+ %
+ % Determine if we are typesetting the return type of a typed function
+ % on a line by itself.
+ \rettypeownlinefalse
+ \ifdoingtypefn % doing a typed function specifically?
+ % then check user option for putting return type on its own line:
+ \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else
+ \rettypeownlinetrue
+ \fi
+ \fi
+ %
+ % How we'll format the category name. Putting it in brackets helps
+ % distinguish it from the body text that may end up on the next line
+ % just below it.
+ \def\temp{#1}%
+ \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+ %
+ % Figure out line sizes for the paragraph shape. We'll always have at
+ % least two.
+ \tempnum = 2
+ %
+ % The first line needs space for \box0; but if \rightskip is nonzero,
+ % we need only space for the part of \box0 which exceeds it:
+ \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ %
+ % If doing a return type on its own line, we'll have another line.
+ \ifrettypeownline
+ \advance\tempnum by 1
+ \def\maybeshapeline{0in \hsize}%
+ \else
+ \def\maybeshapeline{}%
+ \fi
+ %
+ % The continuations:
+ \dimen2=\hsize \advance\dimen2 by -\defargsindent
+ %
+ % The final paragraph shape:
+ \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2
+ %
+ % Put the category name at the right margin.
+ \noindent
+ \hbox to 0pt{%
+ \hfil\box0 \kern-\hsize
+ % \hsize has to be shortened this way:
+ \kern\leftskip
+ % Intentionally do not respect \rightskip, since we need the space.
+ }%
+ %
+ % Allow all lines to be underfull without complaint:
+ \tolerance=10000 \hbadness=10000
+ \exdentamount=\defbodyindent
+ {%
+ % defun fonts. We use typewriter by default (used to be bold) because:
+ % . we're printing identifiers, they should be in tt in principle.
+ % . in languages with many accents, such as Czech or French, it's
+ % common to leave accents off identifiers. The result looks ok in
+ % tt, but exceedingly strange in rm.
+ % . we don't want -- and --- to be treated as ligatures.
+ % . this still does not fix the ?` and !` ligatures, but so far no
+ % one has made identifiers using them :).
+ \df \tt
+ \def\temp{#2}% text of the return type
+ \ifx\temp\empty\else
+ \tclose{\temp}% typeset the return type
+ \ifrettypeownline
+ % put return type on its own line; prohibit line break following:
+ \hfil\vadjust{\nobreak}\break
+ \else
+ \space % type on same line, so just followed by a space
+ \fi
+ \fi % no return type
+ #3% output function name
+ }%
+ {\rm\enskip}% hskip 0.5 em of \tenrm
+ %
+ \boldbrax
+ % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name. This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable. Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+ % use sl by default (not ttsl),
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ %
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. We used to recommend @var for that, so
+ % leave the code in, but it's strange for @var to lead to typewriter.
+ % Nowadays we recommend @code, since the difference between a ttsl hyphen
+ % and a tt hyphen is pretty tiny. @code also disables ?` !`.
+ \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
+ #1%
+ \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
+
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
+}
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
+}
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
+}
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+% these should not use \errmessage; the glibc manual, at least, actually
+% has such constructs (when documenting function pointers).
+\def\badparencount{%
+ \message{Warning: unbalanced parentheses in @def...}%
+ \global\parencount=0
+}
+\def\badbrackcount{%
+ \message{Warning: unbalanced square brackets in @def...}%
+ \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\thisisundefined
+ \newwrite\macscribble
+ \def\scantokens#1{%
+ \toks0={#1}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \input \jobname.tmp
+ }
+\fi
+
+\def\scanmacro#1{\begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ %
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ %
+ % ... and for \example:
+ \spaceisspace
+ %
+ % The \empty here causes a following catcode 5 newline to be eaten as
+ % part of reading whitespace after a control sequence. It does not
+ % eat a catcode 13 newline. There's no good way to handle the two
+ % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX
+ % would then have different behavior). See the Macro Details node in
+ % the manual for the workaround we recommend for macros and
+ % line-oriented commands.
+ %
+ \scantokens{#1\empty}%
+\endgroup}
+
+\def\scanexp#1{%
+ \edef\temp{\noexpand\scanmacro{#1}}%
+ \temp
+}
+
+\newcount\paramno % Count of parameters
+\newtoks\macname % Macro name
+\newif\ifrecursive % Is it recursive?
+
+% List of all defined macros in the form
+% \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+ \toks0 = \expandafter{\macrolist\definedummyword#1}%
+ \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+% \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+%
+\def\cslet#1#2{%
+ \expandafter\let
+ \csname#1\expandafter\endcsname
+ \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \
+% to recognize macro arguments; this is the job of \mbodybackslash.
+%
+% Non-ASCII encodings make 8-bit characters active, so un-activate
+% them to avoid their expansion. Must do this non-globally, to
+% confine the change to the current group.
+%
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+%
+\def\scanctxt{% used as subroutine
+ \catcode`\"=\other
+ \catcode`\+=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\~=\other
+ \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
+}
+
+\def\scanargctxt{% used for copying and captions, not macros.
+ \scanctxt
+ \catcode`\\=\other
+ \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{% used for @macro definitions
+ \scanctxt
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\^^M=\other
+ \usembodybackslash
+}
+
+\def\macroargctxt{% used when scanning invocations
+ \scanctxt
+ \catcode`\\=0
+}
+% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes"
+% for the single characters \ { }. Thus, we end up with the "commands"
+% that would be written @\ @{ @} in a Texinfo document.
+%
+% We already have @{ and @}. For @\, we define it here, and only for
+% this purpose, to produce a typewriter backslash (so, the @\ that we
+% define for @math can't be used with @macro calls):
+%
+\def\\{\normalbackslash}%
+%
+% We would like to do this for \, too, since that is what makeinfo does.
+% But it is not possible, because Texinfo already has a command @, for a
+% cedilla accent. Documents must use @comma{} instead.
+%
+% \anythingelse will almost certainly be an error of some kind.
+
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+%
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\margbackslash#1{\char`\#1 }
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+ \getargs{#1}% now \macname is the macname and \argl the arglist
+ \ifx\argl\empty % no arguments
+ \paramno=0\relax
+ \else
+ \expandafter\parsemargdef \argl;%
+ \if\paramno>256\relax
+ \ifx\eTeXversion\thisisundefined
+ \errhelp = \EMsimple
+ \errmessage{You need eTeX to compile a file with macros with more than 256 arguments}
+ \fi
+ \fi
+ \fi
+ \if1\csname ismacro.\the\macname\endcsname
+ \message{Warning: redefining \the\macname}%
+ \else
+ \expandafter\ifx\csname \the\macname\endcsname \relax
+ \else \errmessage{Macro name \the\macname\space already defined}\fi
+ \global\cslet{macsave.\the\macname}{\the\macname}%
+ \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+ \addtomacrolist{\the\macname}%
+ \fi
+ \begingroup \macrobodyctxt
+ \ifrecursive \expandafter\parsermacbody
+ \else \expandafter\parsemacbody
+ \fi}
+
+\parseargdef\unmacro{%
+ \if1\csname ismacro.#1\endcsname
+ \global\cslet{#1}{macsave.#1}%
+ \global\expandafter\let \csname ismacro.#1\endcsname=0%
+ % Remove the macro name from \macrolist:
+ \begingroup
+ \expandafter\let\csname#1\endcsname \relax
+ \let\definedummyword\unmacrodo
+ \xdef\macrolist{\macrolist}%
+ \endgroup
+ \else
+ \errmessage{Macro #1 not defined}%
+ \fi
+}
+
+% Called by \do from \dounmacro on each macro. The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+ \ifx #1\relax
+ % remove this
+ \else
+ \noexpand\definedummyword \noexpand#1%
+ \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname#1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% For macro processing make @ a letter so that we can make Texinfo private macro names.
+\edef\texiatcatcode{\the\catcode`\@}
+\catcode `@=11\relax
+
+% Parse the optional {params} list. Set up \paramno and \paramlist
+% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH
+% in the params list to some hook where the argument si to be expanded. If
+% there are less than 10 arguments that hook is to be replaced by ##N where N
+% is the position in that list, that is to say the macro arguments are to be
+% defined `a la TeX in the macro body.
+%
+% That gets used by \mbodybackslash (above).
+%
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX: let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+%
+% If there are 10 or more arguments, a different technique is used, where the
+% hook remains in the body, and when macro is to be expanded the body is
+% processed again to replace the arguments.
+%
+% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the
+% argument N value and then \edef the body (nothing else will expand because of
+% the catcode regime underwhich the body was input).
+%
+% If you compile with TeX (not eTeX), and you have macros with 10 or more
+% arguments, you need that no macro has more than 256 arguments, otherwise an
+% error is produced.
+\def\parsemargdef#1;{%
+ \paramno=0\def\paramlist{}%
+ \let\hash\relax
+ \let\xeatspaces\relax
+ \parsemargdefxxx#1,;,%
+ % In case that there are 10 or more arguments we parse again the arguments
+ % list to set new definitions for the \macarg.BLAH macros corresponding to
+ % each BLAH argument. It was anyhow needed to parse already once this list
+ % in order to count the arguments, and as macros with at most 9 arguments
+ % are by far more frequent than macro with 10 or more arguments, defining
+ % twice the \macarg.BLAH macros does not cost too much processing power.
+ \ifnum\paramno<10\relax\else
+ \paramno0\relax
+ \parsemmanyargdef@@#1,;,% 10 or more arguments
+ \fi
+}
+\def\parsemargdefxxx#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\parsemargdefxxx
+ \advance\paramno by 1
+ \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+ {\xeatspaces{\hash\the\paramno}}%
+ \edef\paramlist{\paramlist\hash\the\paramno,}%
+ \fi\next}
+
+\def\parsemmanyargdef@@#1,{%
+ \if#1;\let\next=\relax
+ \else
+ \let\next=\parsemmanyargdef@@
+ \edef\tempb{\eatspaces{#1}}%
+ \expandafter\def\expandafter\tempa
+ \expandafter{\csname macarg.\tempb\endcsname}%
+ % Note that we need some extra \noexpand\noexpand, this is because we
+ % don't want \the to be expanded in the \parsermacbody as it uses an
+ % \xdef .
+ \expandafter\edef\tempa
+ {\noexpand\noexpand\noexpand\the\toks\the\paramno}%
+ \advance\paramno by 1\relax
+ \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+%
+
+\catcode `\@\texiatcatcode
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\catcode `\@=11\relax
+
+\let\endargs@\relax
+\let\nil@\relax
+\def\nilm@{\nil@}%
+\long\def\nillm@{\nil@}%
+
+% This macro is expanded during the Texinfo macro expansion, not during its
+% definition. It gets all the arguments values and assigns them to macros
+% macarg.ARGNAME
+%
+% #1 is the macro name
+% #2 is the list of argument names
+% #3 is the list of argument values
+\def\getargvals@#1#2#3{%
+ \def\macargdeflist@{}%
+ \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion.
+ \def\paramlist{#2,\nil@}%
+ \def\macroname{#1}%
+ \begingroup
+ \macroargctxt
+ \def\argvaluelist{#3,\nil@}%
+ \def\@tempa{#3}%
+ \ifx\@tempa\empty
+ \setemptyargvalues@
+ \else
+ \getargvals@@
+ \fi
+}
+
+%
+\def\getargvals@@{%
+ \ifx\paramlist\nilm@
+ % Some sanity check needed here that \argvaluelist is also empty.
+ \ifx\argvaluelist\nillm@
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Too many arguments in macro `\macroname'!}%
+ \fi
+ \let\next\macargexpandinbody@
+ \else
+ \ifx\argvaluelist\nillm@
+ % No more arguments values passed to macro. Set remaining named-arg
+ % macros to empty.
+ \let\next\setemptyargvalues@
+ \else
+ % pop current arg name into \@tempb
+ \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\paramlist}%
+ % pop current argument value into \@tempc
+ \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\argvaluelist}%
+ % Here \@tempb is the current arg name and \@tempc is the current arg value.
+ % First place the new argument macro definition into \@tempd
+ \expandafter\macname\expandafter{\@tempc}%
+ \expandafter\let\csname macarg.\@tempb\endcsname\relax
+ \expandafter\def\expandafter\@tempe\expandafter{%
+ \csname macarg.\@tempb\endcsname}%
+ \edef\@tempd{\long\def\@tempe{\the\macname}}%
+ \push@\@tempd\macargdeflist@
+ \let\next\getargvals@@
+ \fi
+ \fi
+ \next
+}
+
+\def\push@#1#2{%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter#2%
+ \expandafter\expandafter\expandafter{%
+ \expandafter#1#2}%
+}
+
+% Replace arguments by their values in the macro body, and place the result
+% in macro \@tempa
+\def\macvalstoargs@{%
+ % To do this we use the property that token registers that are \the'ed
+ % within an \edef expand only once. So we are going to place all argument
+ % values into respective token registers.
+ %
+ % First we save the token context, and initialize argument numbering.
+ \begingroup
+ \paramno0\relax
+ % Then, for each argument number #N, we place the corresponding argument
+ % value into a new token list register \toks#N
+ \expandafter\putargsintokens@\saveparamlist@,;,%
+ % Then, we expand the body so that argument are replaced by their
+ % values. The trick for values not to be expanded themselves is that they
+ % are within tokens and that tokens expand only once in an \edef .
+ \edef\@tempc{\csname mac.\macroname .body\endcsname}%
+ % Now we restore the token stack pointer to free the token list registers
+ % which we have used, but we make sure that expanded body is saved after
+ % group.
+ \expandafter
+ \endgroup
+ \expandafter\def\expandafter\@tempa\expandafter{\@tempc}%
+ }
+
+\def\macargexpandinbody@{%
+ %% Define the named-macro outside of this group and then close this group.
+ \expandafter
+ \endgroup
+ \macargdeflist@
+ % First the replace in body the macro arguments by their values, the result
+ % is in \@tempa .
+ \macvalstoargs@
+ % Then we point at the \norecurse or \gobble (for recursive) macro value
+ % with \@tempb .
+ \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname
+ % Depending on whether it is recursive or not, we need some tailing
+ % \egroup .
+ \ifx\@tempb\gobble
+ \let\@tempc\relax
+ \else
+ \let\@tempc\egroup
+ \fi
+ % And now we do the real job:
+ \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}%
+ \@tempd
+}
+
+\def\putargsintokens@#1,{%
+ \if#1;\let\next\relax
+ \else
+ \let\next\putargsintokens@
+ % First we allocate the new token list register, and give it a temporary
+ % alias \@tempb .
+ \toksdef\@tempb\the\paramno
+ % Then we place the argument value into that token list register.
+ \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname
+ \expandafter\@tempb\expandafter{\@tempa}%
+ \advance\paramno by 1\relax
+ \fi
+ \next
+}
+
+% Save the token stack pointer into macro #1
+\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}}
+% Restore the token stack pointer from number in macro #1
+\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax}
+% newtoks that can be used non \outer .
+\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi}
+
+% Tailing missing arguments are set to empty
+\def\setemptyargvalues@{%
+ \ifx\paramlist\nilm@
+ \let\next\macargexpandinbody@
+ \else
+ \expandafter\setemptyargvaluesparser@\paramlist\endargs@
+ \let\next\setemptyargvalues@
+ \fi
+ \next
+}
+
+\def\setemptyargvaluesparser@#1,#2\endargs@{%
+ \expandafter\def\expandafter\@tempa\expandafter{%
+ \expandafter\def\csname macarg.#1\endcsname{}}%
+ \push@\@tempa\macargdeflist@
+ \def\paramlist{#2}%
+}
+
+% #1 is the element target macro
+% #2 is the list macro
+% #3,#4\endargs@ is the list value
+\def\pop@#1#2#3,#4\endargs@{%
+ \def#1{#3}%
+ \def#2{#4}%
+}
+\long\def\longpop@#1#2#3,#4\endargs@{%
+ \long\def#1{#3}%
+ \long\def#2{#4}%
+}
+
+% This defines a Texinfo @macro. There are eight cases: recursive and
+% nonrecursive macros of zero, one, up to nine, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+%
+\def\defmacro{%
+ \let\hash=##% convert placeholders to macro parameter chars
+ \ifrecursive
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\scanmacro{\temp}}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup\noexpand\scanmacro{\temp}}%
+ \else
+ \ifnum\paramno<10\relax % at most 9
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \else % 10 or more
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble
+ \fi
+ \fi
+ \else
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % at most 9
+ \ifnum\paramno<10\relax
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % 10 or more:
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse
+ \fi
+ \fi
+ \fi}
+
+\catcode `\@\texiatcatcode\relax
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {. If so it reads up to the closing }, if not, it reads the whole
+% line. Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg).
+%
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+ \ifx\nchar\bgroup\else
+ \expandafter\parsearg
+ \fi \macnamexxx}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign. Make them active and then expand them all to nothing.
+%
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+ {%
+ \expandafter\let\obeyedspace=\empty
+ \addtomacrolist{#1}%
+ \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+ }%
+ \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{%
+ \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references. The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross, , , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node. #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+ \ifx\lastnode\empty\else
+ \setref{\lastnode}{#1}%
+ \global\let\lastnode=\empty
+ \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \lastsection,
+% or the anchor name.
+% 2) NAME-snt - section number and type, passed as the SNT arg, or
+% empty for anchors.
+% 3) NAME-pg - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat. In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+ \pdfmkdest{#1}%
+ \iflinks
+ {%
+ \atdummies % preserve commands, but don't expand them
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\lastsection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout
+ }%
+ \fi
+}
+
+% @xrefautosectiontitle on|off says whether @section(ing) names are used
+% automatically in xrefs, if the third arg is not explicitly specified.
+% This was provided as a "secret" @set xref-automatic-section-title
+% variable, now it's official.
+%
+\parseargdef\xrefautomaticsectiontitle{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @xrefautomaticsectiontitle value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+%
+% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual. All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+%
+\newbox\toprefbox
+\newbox\printedrefnamebox
+\newbox\infofilenamebox
+\newbox\printedmanualbox
+%
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \unsepspaces
+ %
+ % Get args without leading/trailing spaces.
+ \def\printedrefname{\ignorespaces #3}%
+ \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
+ %
+ \def\infofilename{\ignorespaces #4}%
+ \setbox\infofilenamebox = \hbox{\infofilename\unskip}%
+ %
+ \def\printedmanual{\ignorespaces #5}%
+ \setbox\printedmanualbox = \hbox{\printedmanual\unskip}%
+ %
+ % If the printed reference name (arg #3) was not explicitly given in
+ % the @xref, figure out what we want to use.
+ \ifdim \wd\printedrefnamebox = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax
+ % Not auto section-title: use node name inside the square brackets.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ % Auto section-title: use chapter/section title inside
+ % the square brackets if we have it.
+ \ifdim \wd\printedmanualbox > 0pt
+ % It is in another manual, so we don't have it; use node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We (should) know the real title if we have the xref values.
+ \def\printedrefname{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % Make link in pdf output.
+ \ifpdf
+ {\indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ % This expands tokens, so do it after making catcode changes, so _
+ % etc. don't get their TeX definitions. This ignores all spaces in
+ % #4, including (wrongly) those in the middle of the filename.
+ \getfilename{#4}%
+ %
+ % This (wrongly) does not take account of leading or trailing
+ % spaces in #1, which should be ignored.
+ \edef\pdfxrefdest{#1}%
+ \ifx\pdfxrefdest\empty
+ \def\pdfxrefdest{Top}% no empty targets
+ \else
+ \txiescapepdf\pdfxrefdest % escape PDF special chars
+ \fi
+ %
+ \leavevmode
+ \startlink attr{/Border [0 0 0]}%
+ \ifnum\filenamelength>0
+ goto file{\the\filename.pdf} name{\pdfxrefdest}%
+ \else
+ goto name{\pdfmkpgn{\pdfxrefdest}}%
+ \fi
+ }%
+ \setcolor{\linkcolor}%
+ \fi
+ %
+ % Float references are printed completely differently: "Figure 1.2"
+ % instead of "[somenode], p.3". We distinguish them by the
+ % LABEL-title being set to a magic string.
+ {%
+ % Have to otherify everything special to allow the \csname to
+ % include an _ in the xref name, etc.
+ \indexnofonts
+ \turnoffactive
+ \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+ \csname XR#1-title\endcsname
+ }%
+ \iffloat\Xthisreftitle
+ % If the user specified the print name (third arg) to the ref,
+ % print it instead of our usual "Figure 1.2".
+ \ifdim\wd\printedrefnamebox = 0pt
+ \refx{#1-snt}{}%
+ \else
+ \printedrefname
+ \fi
+ %
+ % If the user also gave the printed manual name (fifth arg), append
+ % "in MANUALNAME".
+ \ifdim \wd\printedmanualbox > 0pt
+ \space \putwordin{} \cite{\printedmanual}%
+ \fi
+ \else
+ % node/anchor (non-float) references.
+ %
+ % If we use \unhbox to print the node names, TeX does not insert
+ % empty discretionaries after hyphens, which means that it will not
+ % find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens,
+ % this is a loss. Therefore, we give the text of the node name
+ % again, so it is as if TeX is seeing it for the first time.
+ %
+ \ifdim \wd\printedmanualbox > 0pt
+ % Cross-manual reference with a printed manual name.
+ %
+ \crossmanualxref{\cite{\printedmanual\unskip}}%
+ %
+ \else\ifdim \wd\infofilenamebox > 0pt
+ % Cross-manual reference with only an info filename (arg 4), no
+ % printed manual name (arg 5). This is essentially the same as
+ % the case above; we output the filename, since we have nothing else.
+ %
+ \crossmanualxref{\code{\infofilename\unskip}}%
+ %
+ \else
+ % Reference within this manual.
+ %
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive
+ % Only output a following space if the -snt ref is nonempty; for
+ % @unnumbered and @anchor, it won't be.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+ }%
+ % output the `[mynode]' via the macro below so it can be overridden.
+ \xrefprintnodename\printedrefname
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi\fi
+ \fi
+ \endlink
+\endgroup}
+
+% Output a cross-manual xref to #1. Used just above (twice).
+%
+% Only include the text "Section ``foo'' in" if the foo is neither
+% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply
+% "see The Foo Manual", the idea being to refer to the whole manual.
+%
+% But, this being TeX, we can't easily compare our node name against the
+% string "Top" while ignoring the possible spaces before and after in
+% the input. By adding the arbitrary 7sp below, we make it much less
+% likely that a real node name would have the same width as "Top" (e.g.,
+% in a monospaced font). Hopefully it will never happen in practice.
+%
+% For the same basic reason, we retypeset the "Top" at every
+% reference, since the current font is indeterminate.
+%
+\def\crossmanualxref#1{%
+ \setbox\toprefbox = \hbox{Top\kern7sp}%
+ \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
+ \ifdim \wd2 > 7sp % nonempty?
+ \ifdim \wd2 = \wd\toprefbox \else % same as Top?
+ \putwordSection{} ``\printedrefname'' \putwordin{}\space
+ \fi
+ \fi
+ #1%
+}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output. It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents. Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+ \ifnum\secno=0
+ \putwordChapter@tie \the\chapno
+ \else \ifnum\subsecno=0
+ \putwordSection@tie \the\chapno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+\def\Yappendix{%
+ \ifnum\secno=0
+ \putwordAppendix@tie @char\the\appendixno{}%
+ \else \ifnum\subsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie
+ @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+ {%
+ \indexnofonts
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\thisrefX
+ \csname XR#1\endcsname
+ }%
+ \ifx\thisrefX\relax
+ % If not defined, say something at least.
+ \angleleft un\-de\-fined\angleright
+ \iflinks
+ \ifhavexrefs
+ {\toks0 = {#1}% avoid expansion of possibly-complex value
+ \message{\linenumber Undefined cross reference `\the\toks0'.}}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \thisrefX
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file. Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions). But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+ {% The node name might contain 8-bit characters, which in our current
+ % implementation are changed to commands like @'e. Don't let these
+ % mess up the control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safexrefname{#1}%
+ }%
+ %
+ \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
+ %
+ % Was that xref control sequence that we just defined for a float?
+ \expandafter\iffloat\csname XR\safexrefname\endcsname
+ % it was a float, and we have the (safe) float type in \iffloattype.
+ \expandafter\let\expandafter\floatlist
+ \csname floatlist\iffloattype\endcsname
+ %
+ % Is this the first time we've seen this float type?
+ \expandafter\ifx\floatlist\relax
+ \toks0 = {\do}% yes, so just \do
+ \else
+ % had it before, so preserve previous elements in list.
+ \toks0 = \expandafter{\floatlist\do}%
+ \fi
+ %
+ % Remember this xref in the control sequence \floatlistFLOATTYPE,
+ % for later use in \listoffloats.
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+ {\safexrefname}}%
+ \fi
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+%
+\def\tryauxfile{%
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \readdatafile{aux}%
+ \global\havexrefstrue
+ \fi
+ \closein 1
+}
+
+\def\setupdatafile{%
+ \catcode`\^^@=\other
+ \catcode`\^^A=\other
+ \catcode`\^^B=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\^^K=\other
+ \catcode`\^^L=\other
+ \catcode`\^^N=\other
+ \catcode`\^^P=\other
+ \catcode`\^^Q=\other
+ \catcode`\^^R=\other
+ \catcode`\^^S=\other
+ \catcode`\^^T=\other
+ \catcode`\^^U=\other
+ \catcode`\^^V=\other
+ \catcode`\^^W=\other
+ \catcode`\^^X=\other
+ \catcode`\^^Z=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\^=\other
+ %
+ % Special characters. Should be turned off anyway, but...
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ \catcode`\%=\other
+ \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+ %
+ % This is to support \ in node names and titles, since the \
+ % characters end up in a \csname. It's easier than
+ % leaving it active and making its active definition an actual \
+ % character. What I don't understand is why it works in the *value*
+ % of the xrdef. Seems like it should be a catcode12 \, and that
+ % should not typeset properly. But it works, so I'm moving on for
+ % now. --karl, 15jan04.
+ \catcode`\\=\other
+ %
+ % Make the characters 128-255 be printing characters.
+ {%
+ \count1=128
+ \def\loop{%
+ \catcode\count1=\other
+ \advance\count1 by 1
+ \ifnum \count1<256 \loop \fi
+ }%
+ }%
+ %
+ % @ is our escape character in .aux files, and we need braces.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+ \setupdatafile
+ \input\jobname.#1
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for Info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
+%
+\gdef\dofootnote{%
+ \insert\footins\bgroup
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \hsize=\pagewidth
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ \smallfonts \rm
+ %
+ % Because we use hanging indentation in footnotes, a @noindent appears
+ % to exdent this text, so make it be a no-op. makeinfo does not use
+ % hanging indentation so @noindent can still be needed within footnote
+ % text after an @example or the like (not that this is good style).
+ \let\noindent = \relax
+ %
+ % Hang the footnote text off the number. Use \everypar in case the
+ % footnote extends for more than one paragraph.
+ \everypar = {\hang}%
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ %
+ % Invoke rest of plain TeX footnote routine.
+ \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished. Otherwise, the insertion
+% would be lost.
+% Similarly, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes. --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+ \ifx \insert\ptexinsert
+ \let\insert\saveinsert
+ \else
+ \let\checkinserts\relax
+ \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+ \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+ \afterassignment\next
+ % swallow the left brace
+ \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+ \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+ {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+ \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-)
+ \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+ \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+ \next
+}
+\def\newsaveinsX #1{%
+ \csname newbox\endcsname #1%
+ \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+ \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image. We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front. If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+ % Do not bother showing banner with epsf.tex v2.7k (available in
+ % doc/epsf.tex and on ctan).
+ \def\epsfannounce{\toks0 = }%
+ \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+ work. It is also included in the Texinfo distribution, or you can get
+ it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+ \ifx\epsfbox\thisisundefined
+ \ifwarnednoepsf \else
+ \errhelp = \noepsfhelp
+ \errmessage{epsf.tex not found, images will be ignored}%
+ \global\warnednoepsftrue
+ \fi
+ \else
+ \imagexxx #1,,,,,\finish
+ \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+ \catcode`\^^M = 5 % in case we're inside an example
+ \normalturnoffactive % allow _ et al. in names
+ % If the image is by itself, center it.
+ \ifvmode
+ \imagevmodetrue
+ \else \ifx\centersub\centerV
+ % for @center @image, we need a vbox so we can have our vertical space
+ \imagevmodetrue
+ \vbox\bgroup % vbox has better behavior than vtop herev
+ \fi\fi
+ %
+ \ifimagevmode
+ \nobreak\medskip
+ % Usually we'll have text after the image which will insert
+ % \parskip glue, so insert it here too to equalize the space
+ % above and below.
+ \nobreak\vskip\parskip
+ \nobreak
+ \fi
+ %
+ % Leave vertical mode so that indentation from an enclosing
+ % environment such as @quotation is respected.
+ % However, if we're at the top level, we don't want the
+ % normal paragraph indentation.
+ % On the other hand, if we are in the case of @center @image, we don't
+ % want to start a paragraph, which will create a hsize-width box and
+ % eradicate the centering.
+ \ifx\centersub\centerV\else \noindent \fi
+ %
+ % Output the image.
+ \ifpdf
+ \dopdfimage{#1}{#2}{#3}%
+ \else
+ % \epsfbox itself resets \epsf?size at each figure.
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+ \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+ \epsfbox{#1.eps}%
+ \fi
+ %
+ \ifimagevmode
+ \medskip % space after a standalone image
+ \fi
+ \ifx\centersub\centerV \egroup \fi
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc. We don't actually implement floating yet, we always include the
+% float "here". But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc. Can't contain commas. If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label. Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored. It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+ \let\thiscaption=\empty
+ \let\thisshortcaption=\empty
+ %
+ % don't lose footnotes inside @float.
+ %
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
+ %
+ \startsavinginserts
+ %
+ % We can't be used inside a paragraph.
+ \par
+ %
+ \vtop\bgroup
+ \def\floattype{#1}%
+ \def\floatlabel{#2}%
+ \def\floatloc{#3}% we do nothing with this yet.
+ %
+ \ifx\floattype\empty
+ \let\safefloattype=\empty
+ \else
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ \fi
+ %
+ % If label is given but no type, we handle that as the empty type.
+ \ifx\floatlabel\empty \else
+ % We want each FLOATTYPE to be numbered separately (Figure 1,
+ % Table 1, Figure 2, ...). (And if no label, no number.)
+ %
+ \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+ \global\advance\floatno by 1
+ %
+ {%
+ % This magic value for \lastsection is output by \setref as the
+ % XREFLABEL-title value. \xrefX uses it to distinguish float
+ % labels (which have a completely different output format) from
+ % node and anchor labels. And \xrdef uses it to construct the
+ % lists of floats.
+ %
+ \edef\lastsection{\floatmagic=\safefloattype}%
+ \setref{\floatlabel}{Yfloat}%
+ }%
+ \fi
+ %
+ % start with \parskip glue, I guess.
+ \vskip\parskip
+ %
+ % Don't suppress indentation if a float happens to start a section.
+ \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption: Foo 1.1
+% @float Foo & @caption{Cap}: Foo: Cap
+% @float Foo & no caption: Foo
+% @float ,lbl & Caption{Cap}: 1.1: Cap
+% @float ,lbl & no caption: 1.1
+% @float & @caption{Cap}: Cap
+% @float & no caption:
+%
+\def\Efloat{%
+ \let\floatident = \empty
+ %
+ % In all cases, if we have a float type, it comes first.
+ \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+ %
+ % If we have an xref label, the number comes next.
+ \ifx\floatlabel\empty \else
+ \ifx\floattype\empty \else % if also had float type, need tie first.
+ \appendtomacro\floatident{\tie}%
+ \fi
+ % the number.
+ \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+ \fi
+ %
+ % Start the printed caption with what we've constructed in
+ % \floatident, but keep it separate; we need \floatident again.
+ \let\captionline = \floatident
+ %
+ \ifx\thiscaption\empty \else
+ \ifx\floatident\empty \else
+ \appendtomacro\captionline{: }% had ident, so need a colon between
+ \fi
+ %
+ % caption text.
+ \appendtomacro\captionline{\scanexp\thiscaption}%
+ \fi
+ %
+ % If we have anything to print, print it, with space before.
+ % Eventually this needs to become an \insert.
+ \ifx\captionline\empty \else
+ \vskip.5\parskip
+ \captionline
+ %
+ % Space below caption.
+ \vskip\parskip
+ \fi
+ %
+ % If have an xref label, write the list of floats info. Do this
+ % after the caption, to avoid chance of it being a breakpoint.
+ \ifx\floatlabel\empty \else
+ % Write the text that goes in the lof to the aux file as
+ % \floatlabel-lof. Besides \floatident, we include the short
+ % caption if specified, else the full caption if specified, else nothing.
+ {%
+ \atdummies
+ %
+ % since we read the caption text in the macro world, where ^^M
+ % is turned into a normal character, we have to scan it back, so
+ % we don't write the literal three characters "^^M" into the aux file.
+ \scanexp{%
+ \xdef\noexpand\gtemp{%
+ \ifx\thisshortcaption\empty
+ \thiscaption
+ \else
+ \thisshortcaption
+ \fi
+ }%
+ }%
+ \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+ \ifx\gtemp\empty \else : \gtemp \fi}}%
+ }%
+ \fi
+ \egroup % end of \vtop
+ %
+ % place the captured inserts
+ %
+ % BEWARE: when the floats start floating, we have to issue warning
+ % whenever an insert appears inside a float which could possibly
+ % float. --kasal, 26may04
+ %
+ \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use. Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+ \ifx#1\relax
+ % Haven't seen this figure type before.
+ \csname newcount\endcsname #1%
+ %
+ % Remember to reset this floatno at the next chap.
+ \expandafter\gdef\expandafter\resetallfloatnos
+ \expandafter{\resetallfloatnos #1=0 }%
+ \fi
+ \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value. We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref. That is, the magic
+% \lastsection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string. If so, #2 will be the
+% (safe) float type for this float. We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+ \def\temp{#1}%
+ \def\iffloattype{#2}%
+ \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+ \def\floattype{#1}% floattype
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ %
+ % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+ \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+ \ifhavexrefs
+ % if the user said @listoffloats foo but never @float foo.
+ \message{\linenumber No `\safefloattype' floats to list.}%
+ \fi
+ \else
+ \begingroup
+ \leftskip=\tocindent % indent these entries like a toc
+ \let\do=\listoffloatsdo
+ \csname floatlist\safefloattype\endcsname
+ \endgroup
+ \fi
+}
+
+% This is called on each entry in a list of floats. We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file. We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+ % Can't fully expand XR#1-lof because it can contain anything. Just
+ % pass the control sequence. On the other hand, XR#1-pg is just the
+ % page number, and we want to fully expand that so we can get a link
+ % in pdf output.
+ \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+ %
+ % use the same \entry macro we use to generate the TOC and index.
+ \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+ \writeentry
+}}
+
+
+\message{localization,}
+
+% For single-language documents, @documentlanguage is usually given very
+% early, just after @documentencoding. Single argument is the language
+% (de) or locale (de_DE) abbreviation.
+%
+{
+ \catcode`\_ = \active
+ \globaldefs=1
+\parseargdef\documentlanguage{\begingroup
+ \let_=\normalunderscore % normal _ character for filenames
+ \tex % read txi-??.tex file in plain TeX.
+ % Read the file by the name they passed if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \documentlanguagetrywithoutunderscore{#1_\finish}%
+ \else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
+ \input txi-#1.tex
+ \fi
+ \closein 1
+ \endgroup % end raw TeX
+\endgroup}
+%
+% If they passed de_DE, and txi-de_DE.tex doesn't exist,
+% try txi-de.tex.
+%
+\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{%
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
+ \input txi-#1.tex
+ \fi
+ \closein 1
+}
+}% end of special _ catcode
+%
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty. Maybe you need to install it? Putting it in the current
+directory should work if nowhere else does.}
+
+% This macro is called from txi-??.tex files; the first argument is the
+% \language name to set (without the "\lang@" prefix), the second and
+% third args are \{left,right}hyphenmin.
+%
+% The language names to pass are determined when the format is built.
+% See the etex.log file created at that time, e.g.,
+% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log.
+%
+% With TeX Live 2008, etex now includes hyphenation patterns for all
+% available languages. This means we can support hyphenation in
+% Texinfo, at least to some extent. (This still doesn't solve the
+% accented characters problem.)
+%
+\catcode`@=11
+\def\txisetlanguage#1#2#3{%
+ % do not set the language if the name is undefined in the current TeX.
+ \expandafter\ifx\csname lang@#1\endcsname \relax
+ \message{no patterns for #1}%
+ \else
+ \global\language = \csname lang@#1\endcsname
+ \fi
+ % but there is no harm in adjusting the hyphenmin values regardless.
+ \global\lefthyphenmin = #2\relax
+ \global\righthyphenmin = #3\relax
+}
+
+% Helpers for encodings.
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \global\catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+\def\setnonasciicharscatcodenonglobal#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+ % Encoding being declared for the document.
+ \def\declaredencoding{\csname #1.enc\endcsname}%
+ %
+ % Supported encodings: names converted to tokens in order to be able
+ % to compare them with \ifx.
+ \def\ascii{\csname US-ASCII.enc\endcsname}%
+ \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+ \def\latone{\csname ISO-8859-1.enc\endcsname}%
+ \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+ \def\utfeight{\csname UTF-8.enc\endcsname}%
+ %
+ \ifx \declaredencoding \ascii
+ \asciichardefs
+ %
+ \else \ifx \declaredencoding \lattwo
+ \setnonasciicharscatcode\active
+ \lattwochardefs
+ %
+ \else \ifx \declaredencoding \latone
+ \setnonasciicharscatcode\active
+ \latonechardefs
+ %
+ \else \ifx \declaredencoding \latnine
+ \setnonasciicharscatcode\active
+ \latninechardefs
+ %
+ \else \ifx \declaredencoding \utfeight
+ \setnonasciicharscatcode\active
+ \utfeightchardefs
+ %
+ \else
+ \message{Unknown document encoding #1, ignoring.}%
+ %
+ \fi % utfeight
+ \fi % latnine
+ \fi % latone
+ \fi % lattwo
+ \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\exclamdown}
+ \gdef^^a2{\missingcharmsg{CENT SIGN}}
+ \gdef^^a3{{\pounds}}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\missingcharmsg{YEN SIGN}}
+ \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\copyright}
+ \gdef^^aa{\ordf}
+ \gdef^^ab{\guillemetleft}
+ \gdef^^ac{$\lnot$}
+ \gdef^^ad{\-}
+ \gdef^^ae{\registeredsymbol}
+ \gdef^^af{\={}}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{$\pm$}
+ \gdef^^b2{$^2$}
+ \gdef^^b3{$^3$}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{$\mu$}
+ \gdef^^b6{\P}
+ %
+ \gdef^^b7{$^.$}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{$^1$}
+ \gdef^^ba{\ordm}
+ %
+ \gdef^^bb{\guillemetright}
+ \gdef^^bc{$1\over4$}
+ \gdef^^bd{$1\over2$}
+ \gdef^^be{$3\over4$}
+ \gdef^^bf{\questiondown}
+ %
+ \gdef^^c0{\`A}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\~A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\ringaccent A}
+ \gdef^^c6{\AE}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\`E}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\^E}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\`I}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\"I}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\~N}
+ \gdef^^d2{\`O}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\~O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\O}
+ \gdef^^d9{\`U}
+ \gdef^^da{\'U}
+ \gdef^^db{\^U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\TH}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\`a}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\~a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\ringaccent a}
+ \gdef^^e6{\ae}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\`e}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\^e}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\`{\dotless i}}
+ \gdef^^ed{\'{\dotless i}}
+ \gdef^^ee{\^{\dotless i}}
+ \gdef^^ef{\"{\dotless i}}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\~n}
+ \gdef^^f2{\`o}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\~o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\o}
+ \gdef^^f9{\`u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\^u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\th}
+ \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+ % Encoding is almost identical to Latin1.
+ \latonechardefs
+ %
+ \gdef^^a4{\euro}
+ \gdef^^a6{\v S}
+ \gdef^^a8{\v s}
+ \gdef^^b4{\v Z}
+ \gdef^^b8{\v z}
+ \gdef^^bc{\OE}
+ \gdef^^bd{\oe}
+ \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\ogonek{A}}
+ \gdef^^a2{\u{}}
+ \gdef^^a3{\L}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\v L}
+ \gdef^^a6{\'S}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\v S}
+ \gdef^^aa{\cedilla S}
+ \gdef^^ab{\v T}
+ \gdef^^ac{\'Z}
+ \gdef^^ad{\-}
+ \gdef^^ae{\v Z}
+ \gdef^^af{\dotaccent Z}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{\ogonek{a}}
+ \gdef^^b2{\ogonek{ }}
+ \gdef^^b3{\l}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{\v l}
+ \gdef^^b6{\'s}
+ \gdef^^b7{\v{}}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{\v s}
+ \gdef^^ba{\cedilla s}
+ \gdef^^bb{\v t}
+ \gdef^^bc{\'z}
+ \gdef^^bd{\H{}}
+ \gdef^^be{\v z}
+ \gdef^^bf{\dotaccent z}
+ %
+ \gdef^^c0{\'R}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\u A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\'L}
+ \gdef^^c6{\'C}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\v C}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\ogonek{E}}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\v E}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\v D}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\'N}
+ \gdef^^d2{\v N}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\H O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\v R}
+ \gdef^^d9{\ringaccent U}
+ \gdef^^da{\'U}
+ \gdef^^db{\H U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\cedilla T}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\'r}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\u a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\'l}
+ \gdef^^e6{\'c}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\v c}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\ogonek{e}}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\v e}
+ \gdef^^ed{\'{\dotless{i}}}
+ \gdef^^ee{\^{\dotless{i}}}
+ \gdef^^ef{\v d}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\'n}
+ \gdef^^f2{\v n}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\H o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\v r}
+ \gdef^^f9{\ringaccent u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\H u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\cedilla t}
+ \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions. It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+ \ifx #1\relax
+ \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+ \else
+ \expandafter #1%
+ \fi
+}
+
+\begingroup
+ \catcode`\~13
+ \catcode`\"12
+
+ \def\UTFviiiLoop{%
+ \global\catcode\countUTFx\active
+ \uccode`\~\countUTFx
+ \uppercase\expandafter{\UTFviiiTmp}%
+ \advance\countUTFx by 1
+ \ifnum\countUTFx < \countUTFy
+ \expandafter\UTFviiiLoop
+ \fi}
+
+ \countUTFx = "C2
+ \countUTFy = "E0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "E0
+ \countUTFy = "F0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "F0
+ \countUTFy = "F4
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+ \UTFviiiLoop
+\endgroup
+
+\begingroup
+ \catcode`\"=12
+ \catcode`\<=12
+ \catcode`\.=12
+ \catcode`\,=12
+ \catcode`\;=12
+ \catcode`\!=12
+ \catcode`\~=13
+
+ \gdef\DeclareUnicodeCharacter#1#2{%
+ \countUTFz = "#1\relax
+ %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+ \begingroup
+ \parseXMLCharref
+ \def\UTFviiiTwoOctets##1##2{%
+ \csname u8:##1\string ##2\endcsname}%
+ \def\UTFviiiThreeOctets##1##2##3{%
+ \csname u8:##1\string ##2\string ##3\endcsname}%
+ \def\UTFviiiFourOctets##1##2##3##4{%
+ \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+ \expandafter\expandafter\expandafter\expandafter
+ \expandafter\expandafter\expandafter
+ \gdef\UTFviiiTmp{#2}%
+ \endgroup}
+
+ \gdef\parseXMLCharref{%
+ \ifnum\countUTFz < "A0\relax
+ \errhelp = \EMsimple
+ \errmessage{Cannot define Unicode char value < 00A0}%
+ \else\ifnum\countUTFz < "800\relax
+ \parseUTFviiiA,%
+ \parseUTFviiiB C\UTFviiiTwoOctets.,%
+ \else\ifnum\countUTFz < "10000\relax
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+ \else
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiA!%
+ \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+ \fi\fi\fi
+ }
+
+ \gdef\parseUTFviiiA#1{%
+ \countUTFx = \countUTFz
+ \divide\countUTFz by 64
+ \countUTFy = \countUTFz
+ \multiply\countUTFz by 64
+ \advance\countUTFx by -\countUTFz
+ \advance\countUTFx by 128
+ \uccode `#1\countUTFx
+ \countUTFz = \countUTFy}
+
+ \gdef\parseUTFviiiB#1#2#3#4{%
+ \advance\countUTFz by "#10\relax
+ \uccode `#3\countUTFz
+ \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+ \DeclareUnicodeCharacter{00A0}{\tie}
+ \DeclareUnicodeCharacter{00A1}{\exclamdown}
+ \DeclareUnicodeCharacter{00A3}{\pounds}
+ \DeclareUnicodeCharacter{00A8}{\"{ }}
+ \DeclareUnicodeCharacter{00A9}{\copyright}
+ \DeclareUnicodeCharacter{00AA}{\ordf}
+ \DeclareUnicodeCharacter{00AB}{\guillemetleft}
+ \DeclareUnicodeCharacter{00AD}{\-}
+ \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+ \DeclareUnicodeCharacter{00AF}{\={ }}
+
+ \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+ \DeclareUnicodeCharacter{00B4}{\'{ }}
+ \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+ \DeclareUnicodeCharacter{00BA}{\ordm}
+ \DeclareUnicodeCharacter{00BB}{\guillemetright}
+ \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+ \DeclareUnicodeCharacter{00C0}{\`A}
+ \DeclareUnicodeCharacter{00C1}{\'A}
+ \DeclareUnicodeCharacter{00C2}{\^A}
+ \DeclareUnicodeCharacter{00C3}{\~A}
+ \DeclareUnicodeCharacter{00C4}{\"A}
+ \DeclareUnicodeCharacter{00C5}{\AA}
+ \DeclareUnicodeCharacter{00C6}{\AE}
+ \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+ \DeclareUnicodeCharacter{00C8}{\`E}
+ \DeclareUnicodeCharacter{00C9}{\'E}
+ \DeclareUnicodeCharacter{00CA}{\^E}
+ \DeclareUnicodeCharacter{00CB}{\"E}
+ \DeclareUnicodeCharacter{00CC}{\`I}
+ \DeclareUnicodeCharacter{00CD}{\'I}
+ \DeclareUnicodeCharacter{00CE}{\^I}
+ \DeclareUnicodeCharacter{00CF}{\"I}
+
+ \DeclareUnicodeCharacter{00D0}{\DH}
+ \DeclareUnicodeCharacter{00D1}{\~N}
+ \DeclareUnicodeCharacter{00D2}{\`O}
+ \DeclareUnicodeCharacter{00D3}{\'O}
+ \DeclareUnicodeCharacter{00D4}{\^O}
+ \DeclareUnicodeCharacter{00D5}{\~O}
+ \DeclareUnicodeCharacter{00D6}{\"O}
+ \DeclareUnicodeCharacter{00D8}{\O}
+ \DeclareUnicodeCharacter{00D9}{\`U}
+ \DeclareUnicodeCharacter{00DA}{\'U}
+ \DeclareUnicodeCharacter{00DB}{\^U}
+ \DeclareUnicodeCharacter{00DC}{\"U}
+ \DeclareUnicodeCharacter{00DD}{\'Y}
+ \DeclareUnicodeCharacter{00DE}{\TH}
+ \DeclareUnicodeCharacter{00DF}{\ss}
+
+ \DeclareUnicodeCharacter{00E0}{\`a}
+ \DeclareUnicodeCharacter{00E1}{\'a}
+ \DeclareUnicodeCharacter{00E2}{\^a}
+ \DeclareUnicodeCharacter{00E3}{\~a}
+ \DeclareUnicodeCharacter{00E4}{\"a}
+ \DeclareUnicodeCharacter{00E5}{\aa}
+ \DeclareUnicodeCharacter{00E6}{\ae}
+ \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+ \DeclareUnicodeCharacter{00E8}{\`e}
+ \DeclareUnicodeCharacter{00E9}{\'e}
+ \DeclareUnicodeCharacter{00EA}{\^e}
+ \DeclareUnicodeCharacter{00EB}{\"e}
+ \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+ \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{00F0}{\dh}
+ \DeclareUnicodeCharacter{00F1}{\~n}
+ \DeclareUnicodeCharacter{00F2}{\`o}
+ \DeclareUnicodeCharacter{00F3}{\'o}
+ \DeclareUnicodeCharacter{00F4}{\^o}
+ \DeclareUnicodeCharacter{00F5}{\~o}
+ \DeclareUnicodeCharacter{00F6}{\"o}
+ \DeclareUnicodeCharacter{00F8}{\o}
+ \DeclareUnicodeCharacter{00F9}{\`u}
+ \DeclareUnicodeCharacter{00FA}{\'u}
+ \DeclareUnicodeCharacter{00FB}{\^u}
+ \DeclareUnicodeCharacter{00FC}{\"u}
+ \DeclareUnicodeCharacter{00FD}{\'y}
+ \DeclareUnicodeCharacter{00FE}{\th}
+ \DeclareUnicodeCharacter{00FF}{\"y}
+
+ \DeclareUnicodeCharacter{0100}{\=A}
+ \DeclareUnicodeCharacter{0101}{\=a}
+ \DeclareUnicodeCharacter{0102}{\u{A}}
+ \DeclareUnicodeCharacter{0103}{\u{a}}
+ \DeclareUnicodeCharacter{0104}{\ogonek{A}}
+ \DeclareUnicodeCharacter{0105}{\ogonek{a}}
+ \DeclareUnicodeCharacter{0106}{\'C}
+ \DeclareUnicodeCharacter{0107}{\'c}
+ \DeclareUnicodeCharacter{0108}{\^C}
+ \DeclareUnicodeCharacter{0109}{\^c}
+ \DeclareUnicodeCharacter{0118}{\ogonek{E}}
+ \DeclareUnicodeCharacter{0119}{\ogonek{e}}
+ \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+ \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+ \DeclareUnicodeCharacter{010C}{\v{C}}
+ \DeclareUnicodeCharacter{010D}{\v{c}}
+ \DeclareUnicodeCharacter{010E}{\v{D}}
+
+ \DeclareUnicodeCharacter{0112}{\=E}
+ \DeclareUnicodeCharacter{0113}{\=e}
+ \DeclareUnicodeCharacter{0114}{\u{E}}
+ \DeclareUnicodeCharacter{0115}{\u{e}}
+ \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+ \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+ \DeclareUnicodeCharacter{011A}{\v{E}}
+ \DeclareUnicodeCharacter{011B}{\v{e}}
+ \DeclareUnicodeCharacter{011C}{\^G}
+ \DeclareUnicodeCharacter{011D}{\^g}
+ \DeclareUnicodeCharacter{011E}{\u{G}}
+ \DeclareUnicodeCharacter{011F}{\u{g}}
+
+ \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+ \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+ \DeclareUnicodeCharacter{0124}{\^H}
+ \DeclareUnicodeCharacter{0125}{\^h}
+ \DeclareUnicodeCharacter{0128}{\~I}
+ \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+ \DeclareUnicodeCharacter{012A}{\=I}
+ \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+ \DeclareUnicodeCharacter{012C}{\u{I}}
+ \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+ \DeclareUnicodeCharacter{0131}{\dotless{i}}
+ \DeclareUnicodeCharacter{0132}{IJ}
+ \DeclareUnicodeCharacter{0133}{ij}
+ \DeclareUnicodeCharacter{0134}{\^J}
+ \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+ \DeclareUnicodeCharacter{0139}{\'L}
+ \DeclareUnicodeCharacter{013A}{\'l}
+
+ \DeclareUnicodeCharacter{0141}{\L}
+ \DeclareUnicodeCharacter{0142}{\l}
+ \DeclareUnicodeCharacter{0143}{\'N}
+ \DeclareUnicodeCharacter{0144}{\'n}
+ \DeclareUnicodeCharacter{0147}{\v{N}}
+ \DeclareUnicodeCharacter{0148}{\v{n}}
+ \DeclareUnicodeCharacter{014C}{\=O}
+ \DeclareUnicodeCharacter{014D}{\=o}
+ \DeclareUnicodeCharacter{014E}{\u{O}}
+ \DeclareUnicodeCharacter{014F}{\u{o}}
+
+ \DeclareUnicodeCharacter{0150}{\H{O}}
+ \DeclareUnicodeCharacter{0151}{\H{o}}
+ \DeclareUnicodeCharacter{0152}{\OE}
+ \DeclareUnicodeCharacter{0153}{\oe}
+ \DeclareUnicodeCharacter{0154}{\'R}
+ \DeclareUnicodeCharacter{0155}{\'r}
+ \DeclareUnicodeCharacter{0158}{\v{R}}
+ \DeclareUnicodeCharacter{0159}{\v{r}}
+ \DeclareUnicodeCharacter{015A}{\'S}
+ \DeclareUnicodeCharacter{015B}{\'s}
+ \DeclareUnicodeCharacter{015C}{\^S}
+ \DeclareUnicodeCharacter{015D}{\^s}
+ \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+ \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+ \DeclareUnicodeCharacter{0160}{\v{S}}
+ \DeclareUnicodeCharacter{0161}{\v{s}}
+ \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+ \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+ \DeclareUnicodeCharacter{0164}{\v{T}}
+
+ \DeclareUnicodeCharacter{0168}{\~U}
+ \DeclareUnicodeCharacter{0169}{\~u}
+ \DeclareUnicodeCharacter{016A}{\=U}
+ \DeclareUnicodeCharacter{016B}{\=u}
+ \DeclareUnicodeCharacter{016C}{\u{U}}
+ \DeclareUnicodeCharacter{016D}{\u{u}}
+ \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+ \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+ \DeclareUnicodeCharacter{0170}{\H{U}}
+ \DeclareUnicodeCharacter{0171}{\H{u}}
+ \DeclareUnicodeCharacter{0174}{\^W}
+ \DeclareUnicodeCharacter{0175}{\^w}
+ \DeclareUnicodeCharacter{0176}{\^Y}
+ \DeclareUnicodeCharacter{0177}{\^y}
+ \DeclareUnicodeCharacter{0178}{\"Y}
+ \DeclareUnicodeCharacter{0179}{\'Z}
+ \DeclareUnicodeCharacter{017A}{\'z}
+ \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+ \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+ \DeclareUnicodeCharacter{017D}{\v{Z}}
+ \DeclareUnicodeCharacter{017E}{\v{z}}
+
+ \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+ \DeclareUnicodeCharacter{01C5}{D\v{z}}
+ \DeclareUnicodeCharacter{01C6}{d\v{z}}
+ \DeclareUnicodeCharacter{01C7}{LJ}
+ \DeclareUnicodeCharacter{01C8}{Lj}
+ \DeclareUnicodeCharacter{01C9}{lj}
+ \DeclareUnicodeCharacter{01CA}{NJ}
+ \DeclareUnicodeCharacter{01CB}{Nj}
+ \DeclareUnicodeCharacter{01CC}{nj}
+ \DeclareUnicodeCharacter{01CD}{\v{A}}
+ \DeclareUnicodeCharacter{01CE}{\v{a}}
+ \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+ \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+ \DeclareUnicodeCharacter{01D1}{\v{O}}
+ \DeclareUnicodeCharacter{01D2}{\v{o}}
+ \DeclareUnicodeCharacter{01D3}{\v{U}}
+ \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+ \DeclareUnicodeCharacter{01E2}{\={\AE}}
+ \DeclareUnicodeCharacter{01E3}{\={\ae}}
+ \DeclareUnicodeCharacter{01E6}{\v{G}}
+ \DeclareUnicodeCharacter{01E7}{\v{g}}
+ \DeclareUnicodeCharacter{01E8}{\v{K}}
+ \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+ \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+ \DeclareUnicodeCharacter{01F1}{DZ}
+ \DeclareUnicodeCharacter{01F2}{Dz}
+ \DeclareUnicodeCharacter{01F3}{dz}
+ \DeclareUnicodeCharacter{01F4}{\'G}
+ \DeclareUnicodeCharacter{01F5}{\'g}
+ \DeclareUnicodeCharacter{01F8}{\`N}
+ \DeclareUnicodeCharacter{01F9}{\`n}
+ \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+ \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+ \DeclareUnicodeCharacter{01FE}{\'{\O}}
+ \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+ \DeclareUnicodeCharacter{021E}{\v{H}}
+ \DeclareUnicodeCharacter{021F}{\v{h}}
+
+ \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+ \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+ \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+ \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+ \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+ \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+ \DeclareUnicodeCharacter{0232}{\=Y}
+ \DeclareUnicodeCharacter{0233}{\=y}
+ \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+ \DeclareUnicodeCharacter{02DB}{\ogonek{ }}
+
+ \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+ \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+ \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+ \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+ \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+ \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+ \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+ \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+ \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+ \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+ \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+ \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+ \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+ \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+ \DeclareUnicodeCharacter{1E20}{\=G}
+ \DeclareUnicodeCharacter{1E21}{\=g}
+ \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+ \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+ \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+ \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+ \DeclareUnicodeCharacter{1E26}{\"H}
+ \DeclareUnicodeCharacter{1E27}{\"h}
+
+ \DeclareUnicodeCharacter{1E30}{\'K}
+ \DeclareUnicodeCharacter{1E31}{\'k}
+ \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+ \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+ \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+ \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+ \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+ \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+ \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+ \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+ \DeclareUnicodeCharacter{1E3E}{\'M}
+ \DeclareUnicodeCharacter{1E3F}{\'m}
+
+ \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+ \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+ \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+ \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+ \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+ \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+ \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+ \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+ \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+ \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+ \DeclareUnicodeCharacter{1E54}{\'P}
+ \DeclareUnicodeCharacter{1E55}{\'p}
+ \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+ \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+ \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+ \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+ \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+ \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+ \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+ \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+ \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+ \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+ \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+ \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+ \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+ \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+ \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+ \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+ \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+ \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+ \DeclareUnicodeCharacter{1E7C}{\~V}
+ \DeclareUnicodeCharacter{1E7D}{\~v}
+ \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+ \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+ \DeclareUnicodeCharacter{1E80}{\`W}
+ \DeclareUnicodeCharacter{1E81}{\`w}
+ \DeclareUnicodeCharacter{1E82}{\'W}
+ \DeclareUnicodeCharacter{1E83}{\'w}
+ \DeclareUnicodeCharacter{1E84}{\"W}
+ \DeclareUnicodeCharacter{1E85}{\"w}
+ \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+ \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+ \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+ \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+ \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+ \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+ \DeclareUnicodeCharacter{1E8C}{\"X}
+ \DeclareUnicodeCharacter{1E8D}{\"x}
+ \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+ \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+ \DeclareUnicodeCharacter{1E90}{\^Z}
+ \DeclareUnicodeCharacter{1E91}{\^z}
+ \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+ \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+ \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+ \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+ \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+ \DeclareUnicodeCharacter{1E97}{\"t}
+ \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+ \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+ \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+ \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+ \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+ \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+ \DeclareUnicodeCharacter{1EBC}{\~E}
+ \DeclareUnicodeCharacter{1EBD}{\~e}
+
+ \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+ \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+ \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+ \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+ \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+ \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+ \DeclareUnicodeCharacter{1EF2}{\`Y}
+ \DeclareUnicodeCharacter{1EF3}{\`y}
+ \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+ \DeclareUnicodeCharacter{1EF8}{\~Y}
+ \DeclareUnicodeCharacter{1EF9}{\~y}
+
+ \DeclareUnicodeCharacter{2013}{--}
+ \DeclareUnicodeCharacter{2014}{---}
+ \DeclareUnicodeCharacter{2018}{\quoteleft}
+ \DeclareUnicodeCharacter{2019}{\quoteright}
+ \DeclareUnicodeCharacter{201A}{\quotesinglbase}
+ \DeclareUnicodeCharacter{201C}{\quotedblleft}
+ \DeclareUnicodeCharacter{201D}{\quotedblright}
+ \DeclareUnicodeCharacter{201E}{\quotedblbase}
+ \DeclareUnicodeCharacter{2022}{\bullet}
+ \DeclareUnicodeCharacter{2026}{\dots}
+ \DeclareUnicodeCharacter{2039}{\guilsinglleft}
+ \DeclareUnicodeCharacter{203A}{\guilsinglright}
+ \DeclareUnicodeCharacter{20AC}{\euro}
+
+ \DeclareUnicodeCharacter{2192}{\expansion}
+ \DeclareUnicodeCharacter{21D2}{\result}
+
+ \DeclareUnicodeCharacter{2212}{\minus}
+ \DeclareUnicodeCharacter{2217}{\point}
+ \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+ \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be very finicky about underfull hboxes, either.
+\hbadness = 6666
+
+% Following George Bush, get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+ \ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+ \else
+ \emergencystretch = .15\hsize
+ \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading. The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+ \voffset = #3\relax
+ \topskip = #6\relax
+ \splittopskip = \topskip
+ %
+ \vsize = #1\relax
+ \advance\vsize by \topskip
+ \outervsize = \vsize
+ \advance\outervsize by 2\topandbottommargin
+ \pageheight = \vsize
+ %
+ \hsize = #2\relax
+ \outerhsize = \hsize
+ \advance\outerhsize by 0.5in
+ \pagewidth = \hsize
+ %
+ \normaloffset = #4\relax
+ \bindingoffset = #5\relax
+ %
+ \ifpdf
+ \pdfpageheight #7\relax
+ \pdfpagewidth #8\relax
+ % if we don't reset these, they will remain at "1 true in" of
+ % whatever layout pdftex was dumped with.
+ \pdfhorigin = 1 true in
+ \pdfvorigin = 1 true in
+ \fi
+ %
+ \setleading{\textleading}
+ %
+ \parindent = \defaultparindent
+ \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % If page is nothing but text, make it come out even.
+ \internalpagesizes{607.2pt}{6in}% that's 46 lines
+ {\voffset}{.25in}%
+ {\bindingoffset}{36pt}%
+ {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+ \parskip = 2pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.5in}{5in}%
+ {-.2in}{0in}%
+ {\bindingoffset}{16pt}%
+ {9.25in}{7in}%
+ %
+ \lispnarrowing = 0.3in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+ \parskip = 1.5pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.4in}{4.8in}%
+ {-.2in}{-.4in}%
+ {0pt}{14pt}%
+ {9in}{6in}%
+ %
+ \lispnarrowing = 0.25in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % Double-side printing via postscript on Laserjet 4050
+ % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+ % To change the settings for a different printer or situation, adjust
+ % \normaloffset until the front-side and back-side texts align. Then
+ % do the same for \bindingoffset. You can set these for testing in
+ % your texinfo source file like this:
+ % @tex
+ % \global\normaloffset = -6mm
+ % \global\bindingoffset = 10mm
+ % @end tex
+ \internalpagesizes{673.2pt}{160mm}% that's 51 lines
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{44pt}%
+ {297mm}{210mm}%
+ %
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+ \parskip = 2pt plus 1pt minus 0.1pt
+ \textleading = 12.5pt
+ %
+ \internalpagesizes{160mm}{120mm}%
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{8pt}%
+ {210mm}{148mm}%
+ %
+ \lispnarrowing = 0.2in
+ \tolerance = 800
+ \hfuzz = 1.2pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 2mm
+ \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{237mm}{150mm}%
+ {\voffset}{4.6mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ %
+ % Must explicitly reset to 0 because we call \afourpaper.
+ \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{241mm}{165mm}%
+ {\voffset}{-2.95mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+ \globaldefs = 1
+ %
+ \parskip = 3pt plus 2pt minus 1pt
+ \setleading{\textleading}%
+ %
+ \dimen0 = #1\relax
+ \advance\dimen0 by \voffset
+ %
+ \dimen2 = \hsize
+ \advance\dimen2 by \normaloffset
+ %
+ \internalpagesizes{#1}{\hsize}%
+ {\voffset}{\normaloffset}%
+ {\bindingoffset}{44pt}%
+ {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+\def^^L{\par} % remove \outer, so ^L can appear in an @comment
+
+% DEL is a comment character, in case @c does not suffice.
+\catcode`\^^? = 14
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other \def\normaldoublequote{"}
+\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix
+\catcode`\+=\other \def\normalplus{+}
+\catcode`\<=\other \def\normalless{<}
+\catcode`\>=\other \def\normalgreater{>}
+\catcode`\^=\other \def\normalcaret{^}
+\catcode`\_=\other \def\normalunderscore{_}
+\catcode`\|=\other \def\normalverticalbar{|}
+\catcode`\~=\other \def\normaltilde{~}
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font. Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts. But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+ \normalturnoffactive
+ \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active % @ for escape char from now on.
+
+% The story here is that in math mode, the \char of \backslashcurfont
+% ends up printing the roman \ from the math symbol font (because \char
+% in math mode uses the \mathcode, and plain.tex sets
+% \mathcode`\\="026E). It seems better for @backslashchar{} to always
+% print a typewriter backslash, hence we use an explicit \mathchar,
+% which is the decimal equivalent of "715c (class 7, e.g., use \fam;
+% ignored family value; char position "5C). We can't use " for the
+% usual hex value because it has already been made active.
+@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}}
+@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents.
+
+% On startup, @fixbackslash assigns:
+% @let \ = @normalbackslash
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other. We switch back and forth between these.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'. Also revert - to its normal character, in
+% case the active - from code has slipped in.
+%
+{@catcode`- = @active
+ @gdef@normalturnoffactive{%
+ @let-=@normaldash
+ @let"=@normaldoublequote
+ @let$=@normaldollar %$ font-lock fix
+ @let+=@normalplus
+ @let<=@normalless
+ @let>=@normalgreater
+ @let\=@normalbackslash
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let~=@normaltilde
+ @markupsetuplqdefault
+ @markupsetuprqdefault
+ @unsepspaces
+ }
+}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\' in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+ @ifx\@eatinput @let\ = @normalbackslash @fi
+ @catcode`+=@active
+ @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These (along with & and #) are made active for url-breaking, so need
+% active definitions as the normal characters.
+@def@normaldot{.}
+@def@normalquest{?}
+@def@normalslash{/}
+
+% These look ok in all fonts, so just make them not special.
+% @hashchar{} gets its own user-level command, because of #line.
+@catcode`@& = @other @def@normalamp{&}
+@catcode`@# = @other @def@normalhash{#}
+@catcode`@% = @other @def@normalpercent{%}
+
+@let @hashchar = @normalhash
+
+@c Finally, make ` and ' active, so that txicodequoteundirected and
+@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we
+@c don't make ` and ' active, @code will not get them as active chars.
+@c Do this last of all since we use ` in the previous @catcode assignments.
+@catcode`@'=@active
+@catcode`@`=@active
+@markupsetuplqdefault
+@markupsetuprqdefault
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/gmp/doc/version.texi b/gmp/doc/version.texi
new file mode 100644
index 0000000000..08f09e7e86
--- /dev/null
+++ b/gmp/doc/version.texi
@@ -0,0 +1,4 @@
+@set UPDATED 25 March 2014
+@set UPDATED-MONTH March 2014
+@set EDITION 6.0.0
+@set VERSION 6.0.0
diff --git a/gmp/errno.c b/gmp/errno.c
new file mode 100644
index 0000000000..d3c02ef4b8
--- /dev/null
+++ b/gmp/errno.c
@@ -0,0 +1,70 @@
+/* gmp_errno, __gmp_exception -- exception handling and reporting.
+
+ THE FUNCTIONS IN THIS FILE, APART FROM gmp_errno, ARE FOR INTERNAL USE
+ ONLY. THEY'RE ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR
+ DISAPPEAR COMPLETELY IN FUTURE GNU MP RELEASES.
+
+Copyright 2000, 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int gmp_errno = 0;
+
+
+/* The deliberate divide by zero triggers an exception on most systems. On
+ those where it doesn't, for example power and powerpc, use abort instead.
+
+ Enhancement: Perhaps raise(SIGFPE) (or the same with kill()) would be
+ better than abort. Perhaps it'd be possible to get the BSD style
+ FPE_INTDIV_TRAP parameter in there too. */
+
+void
+__gmp_exception (int error_bit)
+{
+ gmp_errno |= error_bit;
+ __gmp_junk = 10 / __gmp_0;
+ abort ();
+}
+
+
+/* These functions minimize the amount of code required in functions raising
+ exceptions. Since they're "noreturn" and don't take any parameters, a
+ test and call might even come out as a simple conditional jump. */
+void
+__gmp_sqrt_of_negative (void)
+{
+ __gmp_exception (GMP_ERROR_SQRT_OF_NEGATIVE);
+}
+void
+__gmp_divide_by_zero (void)
+{
+ __gmp_exception (GMP_ERROR_DIVISION_BY_ZERO);
+}
diff --git a/gmp/extract-dbl.c b/gmp/extract-dbl.c
new file mode 100644
index 0000000000..a6e7bf9468
--- /dev/null
+++ b/gmp/extract-dbl.c
@@ -0,0 +1,311 @@
+/* __gmp_extract_double -- convert from double to array of mp_limb_t.
+
+Copyright 1996, 1999-2002, 2006, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifdef XDEBUG
+#undef _GMP_IEEE_FLOATS
+#endif
+
+#ifndef _GMP_IEEE_FLOATS
+#define _GMP_IEEE_FLOATS 0
+#endif
+
+/* Extract a non-negative double in d. */
+
+int
+__gmp_extract_double (mp_ptr rp, double d)
+{
+ long exp;
+ unsigned sc;
+#ifdef _LONG_LONG_LIMB
+#define BITS_PER_PART 64 /* somewhat bogus */
+ unsigned long long int manl;
+#else
+#define BITS_PER_PART GMP_LIMB_BITS
+ unsigned long int manh, manl;
+#endif
+
+ /* BUGS
+
+ 1. Should handle Inf and NaN in IEEE specific code.
+ 2. Handle Inf and NaN also in default code, to avoid hangs.
+ 3. Generalize to handle all GMP_LIMB_BITS >= 32.
+ 4. This lits is incomplete and misspelled.
+ */
+
+ ASSERT (d >= 0.0);
+
+ if (d == 0.0)
+ {
+ MPN_ZERO (rp, LIMBS_PER_DOUBLE);
+ return 0;
+ }
+
+#if _GMP_IEEE_FLOATS
+ {
+#if defined (__alpha) && __GNUC__ == 2 && __GNUC_MINOR__ == 8
+ /* Work around alpha-specific bug in GCC 2.8.x. */
+ volatile
+#endif
+ union ieee_double_extract x;
+ x.d = d;
+ exp = x.s.exp;
+#if BITS_PER_PART == 64 /* generalize this to BITS_PER_PART > BITS_IN_MANTISSA */
+ manl = (((mp_limb_t) 1 << 63)
+ | ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11));
+ if (exp == 0)
+ {
+ /* Denormalized number. Don't try to be clever about this,
+ since it is not an important case to make fast. */
+ exp = 1;
+ do
+ {
+ manl = manl << 1;
+ exp--;
+ }
+ while ((manl & GMP_LIMB_HIGHBIT) == 0);
+ }
+#endif
+#if BITS_PER_PART == 32
+ manh = ((mp_limb_t) 1 << 31) | (x.s.manh << 11) | (x.s.manl >> 21);
+ manl = x.s.manl << 11;
+ if (exp == 0)
+ {
+ /* Denormalized number. Don't try to be clever about this,
+ since it is not an important case to make fast. */
+ exp = 1;
+ do
+ {
+ manh = (manh << 1) | (manl >> 31);
+ manl = manl << 1;
+ exp--;
+ }
+ while ((manh & GMP_LIMB_HIGHBIT) == 0);
+ }
+#endif
+#if BITS_PER_PART != 32 && BITS_PER_PART != 64
+ You need to generalize the code above to handle this.
+#endif
+ exp -= 1022; /* Remove IEEE bias. */
+ }
+#else
+ {
+ /* Unknown (or known to be non-IEEE) double format. */
+ exp = 0;
+ if (d >= 1.0)
+ {
+ ASSERT_ALWAYS (d * 0.5 != d);
+
+ while (d >= 32768.0)
+ {
+ d *= (1.0 / 65536.0);
+ exp += 16;
+ }
+ while (d >= 1.0)
+ {
+ d *= 0.5;
+ exp += 1;
+ }
+ }
+ else if (d < 0.5)
+ {
+ while (d < (1.0 / 65536.0))
+ {
+ d *= 65536.0;
+ exp -= 16;
+ }
+ while (d < 0.5)
+ {
+ d *= 2.0;
+ exp -= 1;
+ }
+ }
+
+ d *= (4.0 * ((unsigned long int) 1 << (BITS_PER_PART - 2)));
+#if BITS_PER_PART == 64
+ manl = d;
+#endif
+#if BITS_PER_PART == 32
+ manh = d;
+ manl = (d - manh) * (4.0 * ((unsigned long int) 1 << (BITS_PER_PART - 2)));
+#endif
+ }
+#endif /* IEEE */
+
+ sc = (unsigned) (exp + 64 * GMP_NUMB_BITS) % GMP_NUMB_BITS;
+
+ /* We add something here to get rounding right. */
+ exp = (exp + 64 * GMP_NUMB_BITS) / GMP_NUMB_BITS - 64 * GMP_NUMB_BITS / GMP_NUMB_BITS + 1;
+
+#if BITS_PER_PART == 64 && LIMBS_PER_DOUBLE == 2
+#if GMP_NAIL_BITS == 0
+ if (sc != 0)
+ {
+ rp[1] = manl >> (GMP_LIMB_BITS - sc);
+ rp[0] = manl << sc;
+ }
+ else
+ {
+ rp[1] = manl;
+ rp[0] = 0;
+ exp--;
+ }
+#else
+ if (sc > GMP_NAIL_BITS)
+ {
+ rp[1] = manl >> (GMP_LIMB_BITS - sc);
+ rp[0] = (manl << (sc - GMP_NAIL_BITS)) & GMP_NUMB_MASK;
+ }
+ else
+ {
+ if (sc == 0)
+ {
+ rp[1] = manl >> GMP_NAIL_BITS;
+ rp[0] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS) & GMP_NUMB_MASK;
+ exp--;
+ }
+ else
+ {
+ rp[1] = manl >> (GMP_LIMB_BITS - sc);
+ rp[0] = (manl >> (GMP_NAIL_BITS - sc)) & GMP_NUMB_MASK;
+ }
+ }
+#endif
+#endif
+
+#if BITS_PER_PART == 64 && LIMBS_PER_DOUBLE == 3
+ if (sc > GMP_NAIL_BITS)
+ {
+ rp[2] = manl >> (GMP_LIMB_BITS - sc);
+ rp[1] = (manl << sc - GMP_NAIL_BITS) & GMP_NUMB_MASK;
+ if (sc >= 2 * GMP_NAIL_BITS)
+ rp[0] = 0;
+ else
+ rp[0] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS + sc) & GMP_NUMB_MASK;
+ }
+ else
+ {
+ if (sc == 0)
+ {
+ rp[2] = manl >> GMP_NAIL_BITS;
+ rp[1] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS) & GMP_NUMB_MASK;
+ rp[0] = 0;
+ exp--;
+ }
+ else
+ {
+ rp[2] = manl >> (GMP_LIMB_BITS - sc);
+ rp[1] = (manl >> GMP_NAIL_BITS - sc) & GMP_NUMB_MASK;
+ rp[0] = (manl << GMP_NUMB_BITS - GMP_NAIL_BITS + sc) & GMP_NUMB_MASK;
+ }
+ }
+#endif
+
+#if BITS_PER_PART == 32 && LIMBS_PER_DOUBLE == 3
+#if GMP_NAIL_BITS == 0
+ if (sc != 0)
+ {
+ rp[2] = manh >> (GMP_LIMB_BITS - sc);
+ rp[1] = (manh << sc) | (manl >> (GMP_LIMB_BITS - sc));
+ rp[0] = manl << sc;
+ }
+ else
+ {
+ rp[2] = manh;
+ rp[1] = manl;
+ rp[0] = 0;
+ exp--;
+ }
+#else
+ if (sc > GMP_NAIL_BITS)
+ {
+ rp[2] = (manh >> (GMP_LIMB_BITS - sc));
+ rp[1] = ((manh << (sc - GMP_NAIL_BITS)) |
+ (manl >> (GMP_LIMB_BITS - sc + GMP_NAIL_BITS))) & GMP_NUMB_MASK;
+ if (sc >= 2 * GMP_NAIL_BITS)
+ rp[0] = (manl << sc - 2 * GMP_NAIL_BITS) & GMP_NUMB_MASK;
+ else
+ rp[0] = manl >> (2 * GMP_NAIL_BITS - sc) & GMP_NUMB_MASK;
+ }
+ else
+ {
+ if (sc == 0)
+ {
+ rp[2] = manh >> GMP_NAIL_BITS;
+ rp[1] = ((manh << GMP_NUMB_BITS - GMP_NAIL_BITS) | (manl >> 2 * GMP_NAIL_BITS)) & GMP_NUMB_MASK;
+ rp[0] = (manl << GMP_NUMB_BITS - 2 * GMP_NAIL_BITS) & GMP_NUMB_MASK;
+ exp--;
+ }
+ else
+ {
+ rp[2] = (manh >> (GMP_LIMB_BITS - sc));
+ rp[1] = (manh >> (GMP_NAIL_BITS - sc)) & GMP_NUMB_MASK;
+ rp[0] = ((manh << (GMP_NUMB_BITS - GMP_NAIL_BITS + sc))
+ | (manl >> (GMP_LIMB_BITS - (GMP_NUMB_BITS - GMP_NAIL_BITS + sc)))) & GMP_NUMB_MASK;
+ }
+ }
+#endif
+#endif
+
+#if BITS_PER_PART == 32 && LIMBS_PER_DOUBLE > 3
+ if (sc == 0)
+ {
+ int i;
+
+ for (i = LIMBS_PER_DOUBLE - 1; i >= 0; i--)
+ {
+ rp[i] = manh >> (BITS_PER_ULONG - GMP_NUMB_BITS);
+ manh = ((manh << GMP_NUMB_BITS)
+ | (manl >> (BITS_PER_ULONG - GMP_NUMB_BITS)));
+ manl = manl << GMP_NUMB_BITS;
+ }
+ exp--;
+ }
+ else
+ {
+ int i;
+
+ rp[LIMBS_PER_DOUBLE - 1] = (manh >> (GMP_LIMB_BITS - sc));
+ manh = (manh << sc) | (manl >> (GMP_LIMB_BITS - sc));
+ manl = (manl << sc);
+ for (i = LIMBS_PER_DOUBLE - 2; i >= 0; i--)
+ {
+ rp[i] = manh >> (BITS_PER_ULONG - GMP_NUMB_BITS);
+ manh = ((manh << GMP_NUMB_BITS)
+ | (manl >> (BITS_PER_ULONG - GMP_NUMB_BITS)));
+ manl = manl << GMP_NUMB_BITS;
+ }
+ }
+#endif
+
+ return exp;
+}
diff --git a/gmp/gen-bases.c b/gmp/gen-bases.c
new file mode 100644
index 0000000000..4d4b0db8ac
--- /dev/null
+++ b/gmp/gen-bases.c
@@ -0,0 +1,251 @@
+/* Generate mp_bases data.
+
+Copyright 1991, 1993, 1994, 1996, 2000, 2002, 2004, 2011, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "bootstrap.c"
+
+
+int chars_per_limb;
+mpz_t big_base;
+int normalization_steps;
+mpz_t big_base_inverted;
+
+mpz_t t;
+
+#define POW2_P(n) (((n) & ((n) - 1)) == 0)
+
+unsigned int
+ulog2 (unsigned int x)
+{
+ unsigned int i;
+ for (i = 0; x != 0; i++)
+ x >>= 1;
+ return i;
+}
+
+void
+generate (int limb_bits, int nail_bits, int base)
+{
+ int numb_bits = limb_bits - nail_bits;
+
+ mpz_set_ui (t, 1L);
+ mpz_mul_2exp (t, t, numb_bits);
+ mpz_set_ui (big_base, 1L);
+ chars_per_limb = 0;
+ for (;;)
+ {
+ mpz_mul_ui (big_base, big_base, (long) base);
+ if (mpz_cmp (big_base, t) > 0)
+ break;
+ chars_per_limb++;
+ }
+
+ mpz_ui_pow_ui (big_base, (long) base, (long) chars_per_limb);
+
+ normalization_steps = limb_bits - mpz_sizeinbase (big_base, 2);
+
+ mpz_set_ui (t, 1L);
+ mpz_mul_2exp (t, t, 2*limb_bits - normalization_steps);
+ mpz_tdiv_q (big_base_inverted, t, big_base);
+ mpz_set_ui (t, 1L);
+ mpz_mul_2exp (t, t, limb_bits);
+ mpz_sub (big_base_inverted, big_base_inverted, t);
+}
+
+void
+header (int limb_bits, int nail_bits)
+{
+ int numb_bits = limb_bits - nail_bits;
+
+ generate (limb_bits, nail_bits, 10);
+
+ printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
+ printf ("\n");
+ printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
+ printf ("Error, error, this data is for %d bits\n", numb_bits);
+ printf ("#endif\n");
+ printf ("\n");
+ printf ("/* mp_bases[10] data, as literal values */\n");
+ printf ("#define MP_BASES_CHARS_PER_LIMB_10 %d\n", chars_per_limb);
+ printf ("#define MP_BASES_BIG_BASE_10 CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, big_base);
+ printf (")\n");
+ printf ("#define MP_BASES_BIG_BASE_INVERTED_10 CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, big_base_inverted);
+ printf (")\n");
+ printf ("#define MP_BASES_NORMALIZATION_STEPS_10 %d\n", normalization_steps);
+}
+
+
+#define EXTRA 16
+
+/* Compute log(2)/log(b) as a fixnum. */
+void
+mp_2logb (mpz_t r, int bi, int prec)
+{
+ mpz_t t, t2, two, b;
+ int i;
+
+ mpz_init_set_ui (t, 1);
+ mpz_mul_2exp (t, t, prec+EXTRA);
+
+ mpz_init (t2);
+
+ mpz_init_set_ui (two, 2);
+ mpz_mul_2exp (two, two, prec+EXTRA);
+
+ mpz_set_ui (r, 0);
+
+ mpz_init_set_ui (b, bi);
+ mpz_mul_2exp (b, b, prec+EXTRA);
+
+ for (i = prec-1; i >= 0; i--)
+ {
+ mpz_mul_2exp (b, b, prec+EXTRA);
+ mpz_sqrt (b, b);
+
+ mpz_mul (t2, t, b);
+ mpz_tdiv_q_2exp (t2, t2, prec+EXTRA);
+
+ if (mpz_cmp (t2, two) < 0) /* not too large? */
+ {
+ mpz_setbit (r, i); /* set next less significant bit */
+ mpz_set (t, t2); /* new value acceptable */
+ }
+ }
+
+ mpz_clear (t);
+ mpz_clear (t2);
+ mpz_clear (two);
+ mpz_clear (b);
+}
+
+void
+table (int limb_bits, int nail_bits)
+{
+ int numb_bits = limb_bits - nail_bits;
+ int base;
+ mpz_t r, t, logb2, log2b;
+
+ mpz_init (r);
+ mpz_init (t);
+ mpz_init (logb2);
+ mpz_init (log2b);
+
+ printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
+ printf ("\n");
+ printf ("#include \"gmp.h\"\n");
+ printf ("#include \"gmp-impl.h\"\n");
+ printf ("\n");
+ printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
+ printf ("Error, error, this data is for %d bits\n", numb_bits);
+ printf ("#endif\n");
+ printf ("\n");
+ puts ("const struct bases mp_bases[257] =\n{");
+ puts (" /* 0 */ { 0, 0, 0, 0, 0 },");
+ puts (" /* 1 */ { 0, 0, 0, 0, 0 },");
+ for (base = 2; base <= 256; base++)
+ {
+ generate (limb_bits, nail_bits, base);
+ mp_2logb (r, base, limb_bits + 8);
+ mpz_tdiv_q_2exp (logb2, r, 8);
+ mpz_set_ui (t, 1);
+ mpz_mul_2exp (t, t, 2*limb_bits + 5);
+ mpz_sub_ui (t, t, 1);
+ mpz_add_ui (r, r, 1);
+ mpz_tdiv_q (log2b, t, r);
+
+ printf (" /* %3u */ { ", base);
+ if (POW2_P (base))
+ {
+ mpz_set_ui (big_base, ulog2 (base) - 1);
+ mpz_set_ui (big_base_inverted, 0);
+ }
+
+ printf ("%u,", chars_per_limb);
+ printf (" CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, logb2);
+ printf ("), CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, log2b);
+ printf ("), CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, big_base);
+ printf ("), CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, big_base_inverted);
+ printf (") },\n");
+ }
+
+ puts ("};");
+
+ mpz_clear (r);
+ mpz_clear (t);
+ mpz_clear (logb2);
+ mpz_clear (log2b);
+
+}
+
+int
+main (int argc, char **argv)
+{
+ int limb_bits, nail_bits;
+
+ mpz_init (big_base);
+ mpz_init (big_base_inverted);
+ mpz_init (t);
+
+ if (argc != 4)
+ {
+ fprintf (stderr, "Usage: gen-bases <header|table> <limbbits> <nailbits>\n");
+ exit (1);
+ }
+
+ limb_bits = atoi (argv[2]);
+ nail_bits = atoi (argv[3]);
+
+ if (limb_bits <= 0
+ || nail_bits < 0
+ || nail_bits >= limb_bits)
+ {
+ fprintf (stderr, "Invalid limb/nail bits: %d %d\n",
+ limb_bits, nail_bits);
+ exit (1);
+ }
+
+ if (strcmp (argv[1], "header") == 0)
+ header (limb_bits, nail_bits);
+ else if (strcmp (argv[1], "table") == 0)
+ table (limb_bits, nail_bits);
+ else
+ {
+ fprintf (stderr, "Invalid header/table choice: %s\n", argv[1]);
+ exit (1);
+ }
+
+ return 0;
+}
diff --git a/gmp/gen-fac.c b/gmp/gen-fac.c
new file mode 100644
index 0000000000..b1756a6117
--- /dev/null
+++ b/gmp/gen-fac.c
@@ -0,0 +1,285 @@
+/* Generate data for combinatorics: fac_ui, bin_uiui, ...
+
+Copyright 2002, 2011-2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "bootstrap.c"
+
+int
+mpz_remove_twos (mpz_t x)
+{
+ mp_bitcnt_t r = mpz_scan1(x, 0);
+ mpz_tdiv_q_2exp (x, x, r);
+ return r;
+}
+
+/* returns 0 on success */
+int
+gen_consts (int numb, int nail, int limb)
+{
+ mpz_t x, mask, y, last;
+ unsigned long a, b;
+ unsigned long ofl, ofe;
+
+ printf ("/* This file is automatically generated by gen-fac.c */\n\n");
+ printf ("#if GMP_NUMB_BITS != %d\n", numb);
+ printf ("Error , error this data is for %d GMP_NUMB_BITS only\n", numb);
+ printf ("#endif\n");
+#if 0
+ printf ("#if GMP_LIMB_BITS != %d\n", limb);
+ printf ("Error , error this data is for %d GMP_LIMB_BITS only\n", limb);
+ printf ("#endif\n");
+#endif
+
+ printf
+ ("/* This table is 0!,1!,2!,3!,...,n! where n! has <= GMP_NUMB_BITS bits */\n");
+ printf
+ ("#define ONE_LIMB_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1");
+ mpz_init_set_ui (x, 1);
+ mpz_init (last);
+ for (b = 2;; b++)
+ {
+ mpz_mul_ui (x, x, b); /* so b!=a */
+ if (mpz_sizeinbase (x, 2) > numb)
+ break;
+ printf ("),CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, x);
+ }
+ printf (")\n");
+
+ printf
+ ("\n/* This table is 0!,1!,2!/2,3!/2,...,n!/2^sn where n!/2^sn is an */\n");
+ printf
+ ("/* odd integer for each n, and n!/2^sn has <= GMP_NUMB_BITS bits */\n");
+ printf
+ ("#define ONE_LIMB_ODD_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1),CNST_LIMB(0x1");
+ mpz_set_ui (x, 1);
+ for (b = 3;; b++)
+ {
+ for (a = b; (a & 1) == 0; a >>= 1);
+ mpz_swap (last, x);
+ mpz_mul_ui (x, last, a);
+ if (mpz_sizeinbase (x, 2) > numb)
+ break;
+ printf ("),CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, x);
+ }
+ printf (")\n");
+ printf
+ ("#define ODD_FACTORIAL_TABLE_MAX CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, last);
+ printf (")\n");
+
+ ofl = b - 1;
+ printf
+ ("#define ODD_FACTORIAL_TABLE_LIMIT (%lu)\n", ofl);
+ mpz_init2 (mask, numb);
+ mpz_setbit (mask, numb);
+ mpz_sub_ui (mask, mask, 1);
+ printf
+ ("\n/* Previous table, continued, values modulo 2^GMP_NUMB_BITS */\n");
+ printf
+ ("#define ONE_LIMB_ODD_FACTORIAL_EXTTABLE CNST_LIMB(0x");
+ mpz_and (x, x, mask);
+ mpz_out_str (stdout, 16, x);
+ mpz_init (y);
+ mpz_bin_uiui (y, b, b/2);
+ b++;
+ for (;; b++)
+ {
+ for (a = b; (a & 1) == 0; a >>= 1);
+ if (a == b) {
+ mpz_divexact_ui (y, y, a/2+1);
+ mpz_mul_ui (y, y, a);
+ } else
+ mpz_mul_2exp (y, y, 1);
+ if (mpz_sizeinbase (y, 2) > numb)
+ break;
+ mpz_mul_ui (x, x, a);
+ mpz_and (x, x, mask);
+ printf ("),CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, x);
+ }
+ printf (")\n");
+ ofe = b - 1;
+ printf
+ ("#define ODD_FACTORIAL_EXTTABLE_LIMIT (%lu)\n", ofe);
+
+ printf
+ ("\n/* This table is 1!!,3!!,...,(2n+1)!! where (2n+1)!! has <= GMP_NUMB_BITS bits */\n");
+ printf
+ ("#define ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE CNST_LIMB(0x1");
+ mpz_set_ui (x, 1);
+ for (b = 3;; b+=2)
+ {
+ mpz_swap (last, x);
+ mpz_mul_ui (x, last, b);
+ if (mpz_sizeinbase (x, 2) > numb)
+ break;
+ printf ("),CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, x);
+ }
+ printf (")\n");
+ printf
+ ("#define ODD_DOUBLEFACTORIAL_TABLE_MAX CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, last);
+ printf (")\n");
+
+ printf
+ ("#define ODD_DOUBLEFACTORIAL_TABLE_LIMIT (%lu)\n", b - 2);
+
+ printf
+ ("\n/* This table x_1, x_2,... contains values s.t. x_n^n has <= GMP_NUMB_BITS bits */\n");
+ printf
+ ("#define NTH_ROOT_NUMB_MASK_TABLE (GMP_NUMB_MASK");
+ for (b = 2;b <= 8; b++)
+ {
+ mpz_root (x, mask, b);
+ printf ("),CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, x);
+ }
+ printf (")\n");
+
+ mpz_add_ui (mask, mask, 1);
+ printf
+ ("\n/* This table contains inverses of odd factorials, modulo 2^GMP_NUMB_BITS */\n");
+ printf
+ ("\n/* It begins with (2!/2)^-1=1 */\n");
+ printf
+ ("#define ONE_LIMB_ODD_FACTORIAL_INVERSES_TABLE CNST_LIMB(0x1");
+ mpz_set_ui (x, 1);
+ for (b = 3;b <= ofe - 2; b++)
+ {
+ for (a = b; (a & 1) == 0; a >>= 1);
+ mpz_mul_ui (x, x, a);
+ mpz_invert (y, x, mask);
+ printf ("),CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, y);
+ }
+ printf (")\n");
+
+ ofe = (ofe / 16 + 1) * 16;
+
+ printf
+ ("\n/* This table contains 2n-popc(2n) for small n */\n");
+ printf
+ ("\n/* It begins with 2-1=1 (n=1) */\n");
+ printf
+ ("#define TABLE_2N_MINUS_POPC_2N 1");
+ for (b = 4; b <= ofe; b += 2)
+ {
+ mpz_set_ui (x, b);
+ printf (",%lu",b - mpz_popcount (x));
+ }
+ printf ("\n");
+ printf
+ ("#define TABLE_LIMIT_2N_MINUS_POPC_2N %lu\n", ofe + 1);
+
+
+ ofl = (ofl + 1) / 2;
+ printf
+ ("#define ODD_CENTRAL_BINOMIAL_OFFSET (%lu)\n", ofl);
+ printf
+ ("\n/* This table contains binomial(2k,k)/2^t */\n");
+ printf
+ ("\n/* It begins with ODD_CENTRAL_BINOMIAL_TABLE_MIN */\n");
+ printf
+ ("#define ONE_LIMB_ODD_CENTRAL_BINOMIAL_TABLE ");
+ for (b = ofl;; b++)
+ {
+ mpz_bin_uiui (x, 2 * b, b);
+ mpz_remove_twos (x);
+ if (mpz_sizeinbase (x, 2) > numb)
+ break;
+ if (b != ofl)
+ printf ("),");
+ printf("CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, x);
+ }
+ printf (")\n");
+
+ ofe = b - 1;
+ printf
+ ("#define ODD_CENTRAL_BINOMIAL_TABLE_LIMIT (%lu)\n", ofe);
+
+ printf
+ ("\n/* This table contains the inverses of elements in the previous table. */\n");
+ printf
+ ("#define ONE_LIMB_ODD_CENTRAL_BINOMIAL_INVERSE_TABLE CNST_LIMB(0x");
+ for (b = ofl; b <= ofe; b++)
+ {
+ mpz_bin_uiui (x, 2 * b, b);
+ mpz_remove_twos (x);
+ mpz_invert (x, x, mask);
+ mpz_out_str (stdout, 16, x);
+ if (b != ofe)
+ printf ("),CNST_LIMB(0x");
+ }
+ printf (")\n");
+
+ printf
+ ("\n/* This table contains the values t in the formula binomial(2k,k)/2^t */\n");
+ printf
+ ("#define CENTRAL_BINOMIAL_2FAC_TABLE ");
+ for (b = ofl; b <= ofe; b++)
+ {
+ mpz_bin_uiui (x, 2 * b, b);
+ printf ("%d", mpz_remove_twos (x));
+ if (b != ofe)
+ printf (",");
+ }
+ printf ("\n");
+
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int nail_bits, limb_bits, numb_bits;
+
+ if (argc != 3)
+ {
+ fprintf (stderr, "Usage: gen-fac_ui limbbits nailbits\n");
+ exit (1);
+ }
+ limb_bits = atoi (argv[1]);
+ nail_bits = atoi (argv[2]);
+ numb_bits = limb_bits - nail_bits;
+ if (limb_bits < 2 || nail_bits < 0 || numb_bits < 1)
+ {
+ fprintf (stderr, "Invalid limb/nail bits %d,%d\n", limb_bits,
+ nail_bits);
+ exit (1);
+ }
+ gen_consts (numb_bits, nail_bits, limb_bits);
+ return 0;
+}
diff --git a/gmp/gen-fib.c b/gmp/gen-fib.c
new file mode 100644
index 0000000000..d5f2601915
--- /dev/null
+++ b/gmp/gen-fib.c
@@ -0,0 +1,156 @@
+/* Generate Fibonacci table data.
+
+Copyright 2001, 2002, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "bootstrap.c"
+
+mpz_t *f;
+int fnum, fib_limit, luc_limit;
+
+void
+generate (int numb_bits)
+{
+ mpz_t limit, l;
+ int falloc, i;
+
+ mpz_init_set_ui (limit, 1L);
+ mpz_mul_2exp (limit, limit, numb_bits);
+
+ /* fib(2n) > 2^n, so use 2n as a limit for the table size */
+ falloc = 2 * numb_bits;
+ f = xmalloc (falloc * sizeof (*f));
+
+ mpz_init_set_ui (f[0], 1L); /* F[-1] */
+ mpz_init_set_ui (f[1], 0L); /* F[0] */
+
+ mpz_init (l);
+
+ for (i = 2; ; i++)
+ {
+ assert (i < falloc);
+
+ /* F[i] = F[i-1] + F[i-2] */
+ mpz_init (f[i]);
+ mpz_add (f[i], f[i-1], f[i-2]);
+ if (mpz_cmp (f[i], limit) >= 0)
+ break;
+
+ fnum = i+1;
+ fib_limit = i-1;
+
+ /* L[i] = F[i]+2*F[i-1] */
+ mpz_add (l, f[i], f[i-1]);
+ mpz_add (l, l, f[i-1]);
+
+ if (mpz_cmp (l, limit) < 0)
+ luc_limit = i-1;
+ }
+
+ mpz_clear (limit);
+}
+
+
+void
+header (int numb_bits)
+{
+ printf ("/* This file generated by gen-fib.c - DO NOT EDIT. */\n");
+ printf ("\n");
+ printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
+ printf ("Error, error, this data is for %d bits\n", numb_bits);
+ printf ("#endif\n");
+ printf ("\n");
+ printf ("#define FIB_TABLE_LIMIT %d\n", fib_limit);
+ printf ("#define FIB_TABLE_LUCNUM_LIMIT %d\n", luc_limit);
+}
+
+void
+table (int numb_bits)
+{
+ int i;
+
+ printf ("/* This file generated by gen-fib.c - DO NOT EDIT. */\n");
+ printf ("\n");
+ printf ("#include \"gmp.h\"\n");
+ printf ("#include \"gmp-impl.h\"\n");
+ printf ("\n");
+ printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
+ printf ("Error, error, this data is for %d bits\n", numb_bits);
+ printf ("#endif\n");
+ printf ("\n");
+ printf ("const mp_limb_t\n");
+ printf ("__gmp_fib_table[FIB_TABLE_LIMIT+2] = {\n");
+
+ for (i = 0; i < fnum; i++)
+ {
+ printf (" CNST_LIMB (0x");
+ mpz_out_str (stdout, 16, f[i]);
+ printf ("), /* %d */\n", i-1);
+ }
+ printf ("};\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+ int limb_bits, nail_bits, numb_bits;
+
+ if (argc != 4)
+ {
+ fprintf (stderr, "Usage: gen-bases <header|table> <limbbits> <nailbits>\n");
+ exit (1);
+ }
+
+ limb_bits = atoi (argv[2]);
+ nail_bits = atoi (argv[3]);
+
+ if (limb_bits <= 0
+ || nail_bits < 0
+ || nail_bits >= limb_bits)
+ {
+ fprintf (stderr, "Invalid limb/nail bits: %d %d\n",
+ limb_bits, nail_bits);
+ exit (1);
+ }
+ numb_bits = limb_bits - nail_bits;
+
+ generate (numb_bits);
+
+ if (strcmp (argv[1], "header") == 0)
+ header (numb_bits);
+ else if (strcmp (argv[1], "table") == 0)
+ table (numb_bits);
+ else
+ {
+ fprintf (stderr, "Invalid header/table choice: %s\n", argv[1]);
+ exit (1);
+ }
+
+ return 0;
+}
diff --git a/gmp/gen-jacobitab.c b/gmp/gen-jacobitab.c
new file mode 100644
index 0000000000..537994b3b2
--- /dev/null
+++ b/gmp/gen-jacobitab.c
@@ -0,0 +1,128 @@
+/* gen-jacobi.c
+
+ Contributed to the GNU project by Niels Möller.
+
+Copyright 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* Generate the lookup table needed for fast left-to-right computation
+ of the Jacobi symbol. */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static const struct
+{
+ unsigned char a;
+ unsigned char b;
+} decode_table[13] = {
+ /* 0 */ { 0, 1 },
+ /* 1 */ { 0, 3 },
+ /* 2 */ { 1, 1 },
+ /* 3 */ { 1, 3 },
+ /* 4 */ { 2, 1 },
+ /* 5 */ { 2, 3 },
+ /* 6 */ { 3, 1 },
+ /* 7 */ { 3, 3 }, /* d = 1 */
+ /* 8 */ { 1, 0 },
+ /* 9 */ { 1, 2 },
+ /* 10 */ { 3, 0 },
+ /* 11 */ { 3, 2 },
+ /* 12 */ { 3, 3 }, /* d = 0 */
+
+};
+#define JACOBI_A(bits) (decode_table[(bits)>>1].a)
+#define JACOBI_B(bits) (decode_table[(bits)>>1].b)
+
+#define JACOBI_E(bits) ((bits) & 1)
+#define JACOBI_D(bits) (((bits)>>1) == 7) /* Gives 0 for don't care states. */
+
+static unsigned
+encode (unsigned a, unsigned b, unsigned d)
+{
+ unsigned i;
+
+ assert (d < 2);
+ assert (a < 4);
+ assert (b < 4);
+ assert ( (a | b ) & 1);
+
+ if (a == 3 && b == 3)
+ return d ? 7 : 12;
+
+ for (i = 0; i < 12; i++)
+ if (decode_table[i].a == a
+ && decode_table[i].b == b)
+ return i;
+
+ abort ();
+}
+
+int
+main (int argc, char **argv)
+{
+ unsigned bits;
+
+ for (bits = 0; bits < 208; bits++)
+ {
+ unsigned e, a, b, d_old, d, q;
+
+ if (bits && !(bits & 0xf))
+ printf("\n");
+
+ q = bits & 3;
+ d = (bits >> 2) & 1;
+
+ e = JACOBI_E (bits >> 3);
+ a = JACOBI_A (bits >> 3);
+ b = JACOBI_B (bits >> 3);
+ d_old = JACOBI_D (bits >> 3);
+
+ if (d != d_old && a == 3 && b == 3)
+ e ^= 1;
+
+ if (d == 1)
+ {
+ if (b == 2)
+ e ^= (q & (a >> 1)) ^ (q >> 1);
+ a = (a - q * b) & 3;
+ }
+ else
+ {
+ if (a == 2)
+ e ^= (q & (b >> 1)) ^ (q >> 1);
+ b = (b - q * a) & 3;
+ }
+
+ printf("%2d,", (encode (a, b, d) << 1) | e);
+ }
+ printf("\n");
+
+ return 0;
+}
diff --git a/gmp/gen-psqr.c b/gmp/gen-psqr.c
new file mode 100644
index 0000000000..31977cda1c
--- /dev/null
+++ b/gmp/gen-psqr.c
@@ -0,0 +1,586 @@
+/* Generate perfect square testing data.
+
+Copyright 2002-2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "bootstrap.c"
+
+
+/* The aim of this program is to choose either mpn_mod_34lsub1 or mpn_mod_1
+ (plus a PERFSQR_PP modulus), and generate tables indicating quadratic
+ residues and non-residues modulo small factors of that modulus.
+
+ For the usual 32 or 64 bit cases mpn_mod_34lsub1 gets used. That
+ function exists specifically because 2^24-1 and 2^48-1 have nice sets of
+ prime factors. For other limb sizes it's considered, but if it doesn't
+ have good factors then mpn_mod_1 will be used instead.
+
+ When mpn_mod_1 is used, the modulus PERFSQR_PP is created from a
+ selection of small primes, chosen to fill PERFSQR_MOD_BITS of a limb,
+ with that bit count chosen so (2*GMP_LIMB_BITS)*2^PERFSQR_MOD_BITS <=
+ GMP_LIMB_MAX, allowing PERFSQR_MOD_IDX in mpn/generic/perfsqr.c to do its
+ calculation within a single limb.
+
+ In either case primes can be combined to make divisors. The table data
+ then effectively indicates remainders which are quadratic residues mod
+ all the primes. This sort of combining reduces the number of steps
+ needed after mpn_mod_34lsub1 or mpn_mod_1, saving code size and time.
+ Nothing is gained or lost in terms of detections, the same total fraction
+ of non-residues will be identified.
+
+ Nothing particularly sophisticated is attempted for combining factors to
+ make divisors. This is probably a kind of knapsack problem so it'd be
+ too hard to attempt anything completely general. For the usual 32 and 64
+ bit limbs we get a good enough result just pairing the biggest and
+ smallest which fit together, repeatedly.
+
+ Another aim is to get powerful combinations, ie. divisors which identify
+ biggest fraction of non-residues, and have those run first. Again for
+ the usual 32 and 64 bits it seems good enough just to pair for big
+ divisors then sort according to the resulting fraction of non-residues
+ identified.
+
+ Also in this program, a table sq_res_0x100 of residues modulo 256 is
+ generated. This simply fills bits into limbs of the appropriate
+ build-time GMP_LIMB_BITS each.
+
+*/
+
+
+/* Normally we aren't using const in gen*.c programs, so as not to have to
+ bother figuring out if it works, but using it with f_cmp_divisor and
+ f_cmp_fraction avoids warnings from the qsort calls. */
+
+/* Same tests as gmp.h. */
+#if defined (__STDC__) \
+ || defined (__cplusplus) \
+ || defined (_AIX) \
+ || defined (__DECC) \
+ || (defined (__mips) && defined (_SYSTYPE_SVR4)) \
+ || defined (_MSC_VER) \
+ || defined (_WIN32)
+#define HAVE_CONST 1
+#endif
+
+#if ! HAVE_CONST
+#define const
+#endif
+
+
+mpz_t *sq_res_0x100; /* table of limbs */
+int nsq_res_0x100; /* elements in sq_res_0x100 array */
+int sq_res_0x100_num; /* squares in sq_res_0x100 */
+double sq_res_0x100_fraction; /* sq_res_0x100_num / 256 */
+
+int mod34_bits; /* 3*GMP_NUMB_BITS/4 */
+int mod_bits; /* bits from PERFSQR_MOD_34 or MOD_PP */
+int max_divisor; /* all divisors <= max_divisor */
+int max_divisor_bits; /* ceil(log2(max_divisor)) */
+double total_fraction; /* of squares */
+mpz_t pp; /* product of primes, or 0 if mod_34lsub1 used */
+mpz_t pp_norm; /* pp shifted so NUMB high bit set */
+mpz_t pp_inverted; /* invert_limb style inverse */
+mpz_t mod_mask; /* 2^mod_bits-1 */
+char mod34_excuse[128]; /* why mod_34lsub1 not used (if it's not) */
+
+/* raw list of divisors of 2^mod34_bits-1 or pp, just to show in a comment */
+struct rawfactor_t {
+ int divisor;
+ int multiplicity;
+};
+struct rawfactor_t *rawfactor;
+int nrawfactor;
+
+/* factors of 2^mod34_bits-1 or pp and associated data, after combining etc */
+struct factor_t {
+ int divisor;
+ mpz_t inverse; /* 1/divisor mod 2^mod_bits */
+ mpz_t mask; /* indicating squares mod divisor */
+ double fraction; /* squares/total */
+};
+struct factor_t *factor;
+int nfactor; /* entries in use in factor array */
+int factor_alloc; /* entries allocated to factor array */
+
+
+int
+f_cmp_divisor (const void *parg, const void *qarg)
+{
+ const struct factor_t *p, *q;
+ p = parg;
+ q = qarg;
+ if (p->divisor > q->divisor)
+ return 1;
+ else if (p->divisor < q->divisor)
+ return -1;
+ else
+ return 0;
+}
+
+int
+f_cmp_fraction (const void *parg, const void *qarg)
+{
+ const struct factor_t *p, *q;
+ p = parg;
+ q = qarg;
+ if (p->fraction > q->fraction)
+ return 1;
+ else if (p->fraction < q->fraction)
+ return -1;
+ else
+ return 0;
+}
+
+/* Remove array[idx] by copying the remainder down, and adjust narray
+ accordingly. */
+#define COLLAPSE_ELEMENT(array, idx, narray) \
+ do { \
+ memmove (&(array)[idx], \
+ &(array)[idx+1], \
+ ((narray)-((idx)+1)) * sizeof (array[0])); \
+ (narray)--; \
+ } while (0)
+
+
+/* return n*2^p mod m */
+int
+mul_2exp_mod (int n, int p, int m)
+{
+ int i;
+ for (i = 0; i < p; i++)
+ n = (2 * n) % m;
+ return n;
+}
+
+/* return -n mod m */
+int
+neg_mod (int n, int m)
+{
+ assert (n >= 0 && n < m);
+ return (n == 0 ? 0 : m-n);
+}
+
+/* Set "mask" to a value such that "mask & (1<<idx)" is non-zero if
+ "-(idx<<mod_bits)" can be a square modulo m. */
+void
+square_mask (mpz_t mask, int m)
+{
+ int p, i, r, idx;
+
+ p = mul_2exp_mod (1, mod_bits, m);
+ p = neg_mod (p, m);
+
+ mpz_set_ui (mask, 0L);
+ for (i = 0; i < m; i++)
+ {
+ r = (i * i) % m;
+ idx = (r * p) % m;
+ mpz_setbit (mask, (unsigned long) idx);
+ }
+}
+
+void
+generate_sq_res_0x100 (int limb_bits)
+{
+ int i, res;
+
+ nsq_res_0x100 = (0x100 + limb_bits - 1) / limb_bits;
+ sq_res_0x100 = xmalloc (nsq_res_0x100 * sizeof (*sq_res_0x100));
+
+ for (i = 0; i < nsq_res_0x100; i++)
+ mpz_init_set_ui (sq_res_0x100[i], 0L);
+
+ for (i = 0; i < 0x100; i++)
+ {
+ res = (i * i) % 0x100;
+ mpz_setbit (sq_res_0x100[res / limb_bits],
+ (unsigned long) (res % limb_bits));
+ }
+
+ sq_res_0x100_num = 0;
+ for (i = 0; i < nsq_res_0x100; i++)
+ sq_res_0x100_num += mpz_popcount (sq_res_0x100[i]);
+ sq_res_0x100_fraction = (double) sq_res_0x100_num / 256.0;
+}
+
+void
+generate_mod (int limb_bits, int nail_bits)
+{
+ int numb_bits = limb_bits - nail_bits;
+ int i, divisor;
+
+ mpz_init_set_ui (pp, 0L);
+ mpz_init_set_ui (pp_norm, 0L);
+ mpz_init_set_ui (pp_inverted, 0L);
+
+ /* no more than limb_bits many factors in a one limb modulus (and of
+ course in reality nothing like that many) */
+ factor_alloc = limb_bits;
+ factor = xmalloc (factor_alloc * sizeof (*factor));
+ rawfactor = xmalloc (factor_alloc * sizeof (*rawfactor));
+
+ if (numb_bits % 4 != 0)
+ {
+ strcpy (mod34_excuse, "GMP_NUMB_BITS % 4 != 0");
+ goto use_pp;
+ }
+
+ max_divisor = 2*limb_bits;
+ max_divisor_bits = log2_ceil (max_divisor);
+
+ if (numb_bits / 4 < max_divisor_bits)
+ {
+ /* Wind back to one limb worth of max_divisor, if that will let us use
+ mpn_mod_34lsub1. */
+ max_divisor = limb_bits;
+ max_divisor_bits = log2_ceil (max_divisor);
+
+ if (numb_bits / 4 < max_divisor_bits)
+ {
+ strcpy (mod34_excuse, "GMP_NUMB_BITS / 4 too small");
+ goto use_pp;
+ }
+ }
+
+ {
+ /* Can use mpn_mod_34lsub1, find small factors of 2^mod34_bits-1. */
+ mpz_t m, q, r;
+ int multiplicity;
+
+ mod34_bits = (numb_bits / 4) * 3;
+
+ /* mpn_mod_34lsub1 returns a full limb value, PERFSQR_MOD_34 folds it at
+ the mod34_bits mark, adding the two halves for a remainder of at most
+ mod34_bits+1 many bits */
+ mod_bits = mod34_bits + 1;
+
+ mpz_init_set_ui (m, 1L);
+ mpz_mul_2exp (m, m, mod34_bits);
+ mpz_sub_ui (m, m, 1L);
+
+ mpz_init (q);
+ mpz_init (r);
+
+ for (i = 3; i <= max_divisor; i++)
+ {
+ if (! isprime (i))
+ continue;
+
+ mpz_tdiv_qr_ui (q, r, m, (unsigned long) i);
+ if (mpz_sgn (r) != 0)
+ continue;
+
+ /* if a repeated prime is found it's used as an i^n in one factor */
+ divisor = 1;
+ multiplicity = 0;
+ do
+ {
+ if (divisor > max_divisor / i)
+ break;
+ multiplicity++;
+ mpz_set (m, q);
+ mpz_tdiv_qr_ui (q, r, m, (unsigned long) i);
+ }
+ while (mpz_sgn (r) == 0);
+
+ assert (nrawfactor < factor_alloc);
+ rawfactor[nrawfactor].divisor = i;
+ rawfactor[nrawfactor].multiplicity = multiplicity;
+ nrawfactor++;
+ }
+
+ mpz_clear (m);
+ mpz_clear (q);
+ mpz_clear (r);
+ }
+
+ if (nrawfactor <= 2)
+ {
+ mpz_t new_pp;
+
+ sprintf (mod34_excuse, "only %d small factor%s",
+ nrawfactor, nrawfactor == 1 ? "" : "s");
+
+ use_pp:
+ /* reset to two limbs of max_divisor, in case the mpn_mod_34lsub1 code
+ tried with just one */
+ max_divisor = 2*limb_bits;
+ max_divisor_bits = log2_ceil (max_divisor);
+
+ mpz_init (new_pp);
+ nrawfactor = 0;
+ mod_bits = MIN (numb_bits, limb_bits - max_divisor_bits);
+
+ /* one copy of each small prime */
+ mpz_set_ui (pp, 1L);
+ for (i = 3; i <= max_divisor; i++)
+ {
+ if (! isprime (i))
+ continue;
+
+ mpz_mul_ui (new_pp, pp, (unsigned long) i);
+ if (mpz_sizeinbase (new_pp, 2) > mod_bits)
+ break;
+ mpz_set (pp, new_pp);
+
+ assert (nrawfactor < factor_alloc);
+ rawfactor[nrawfactor].divisor = i;
+ rawfactor[nrawfactor].multiplicity = 1;
+ nrawfactor++;
+ }
+
+ /* Plus an extra copy of one or more of the primes selected, if that
+ still fits in max_divisor and the total in mod_bits. Usually only
+ 3 or 5 will be candidates */
+ for (i = nrawfactor-1; i >= 0; i--)
+ {
+ if (rawfactor[i].divisor > max_divisor / rawfactor[i].divisor)
+ continue;
+ mpz_mul_ui (new_pp, pp, (unsigned long) rawfactor[i].divisor);
+ if (mpz_sizeinbase (new_pp, 2) > mod_bits)
+ continue;
+ mpz_set (pp, new_pp);
+
+ rawfactor[i].multiplicity++;
+ }
+
+ mod_bits = mpz_sizeinbase (pp, 2);
+
+ mpz_set (pp_norm, pp);
+ while (mpz_sizeinbase (pp_norm, 2) < numb_bits)
+ mpz_add (pp_norm, pp_norm, pp_norm);
+
+ mpz_preinv_invert (pp_inverted, pp_norm, numb_bits);
+
+ mpz_clear (new_pp);
+ }
+
+ /* start the factor array */
+ for (i = 0; i < nrawfactor; i++)
+ {
+ int j;
+ assert (nfactor < factor_alloc);
+ factor[nfactor].divisor = 1;
+ for (j = 0; j < rawfactor[i].multiplicity; j++)
+ factor[nfactor].divisor *= rawfactor[i].divisor;
+ nfactor++;
+ }
+
+ combine:
+ /* Combine entries in the factor array. Combine the smallest entry with
+ the biggest one that will fit with it (ie. under max_divisor), then
+ repeat that with the new smallest entry. */
+ qsort (factor, nfactor, sizeof (factor[0]), f_cmp_divisor);
+ for (i = nfactor-1; i >= 1; i--)
+ {
+ if (factor[i].divisor <= max_divisor / factor[0].divisor)
+ {
+ factor[0].divisor *= factor[i].divisor;
+ COLLAPSE_ELEMENT (factor, i, nfactor);
+ goto combine;
+ }
+ }
+
+ total_fraction = 1.0;
+ for (i = 0; i < nfactor; i++)
+ {
+ mpz_init (factor[i].inverse);
+ mpz_invert_ui_2exp (factor[i].inverse,
+ (unsigned long) factor[i].divisor,
+ (unsigned long) mod_bits);
+
+ mpz_init (factor[i].mask);
+ square_mask (factor[i].mask, factor[i].divisor);
+
+ /* fraction of possible squares */
+ factor[i].fraction = (double) mpz_popcount (factor[i].mask)
+ / factor[i].divisor;
+
+ /* total fraction of possible squares */
+ total_fraction *= factor[i].fraction;
+ }
+
+ /* best tests first (ie. smallest fraction) */
+ qsort (factor, nfactor, sizeof (factor[0]), f_cmp_fraction);
+}
+
+void
+print (int limb_bits, int nail_bits)
+{
+ int i;
+ mpz_t mhi, mlo;
+
+ printf ("/* This file generated by gen-psqr.c - DO NOT EDIT. */\n");
+ printf ("\n");
+
+ printf ("#if GMP_LIMB_BITS != %d || GMP_NAIL_BITS != %d\n",
+ limb_bits, nail_bits);
+ printf ("Error, error, this data is for %d bit limb and %d bit nail\n",
+ limb_bits, nail_bits);
+ printf ("#endif\n");
+ printf ("\n");
+
+ printf ("/* Non-zero bit indicates a quadratic residue mod 0x100.\n");
+ printf (" This test identifies %.2f%% as non-squares (%d/256). */\n",
+ (1.0 - sq_res_0x100_fraction) * 100.0,
+ 0x100 - sq_res_0x100_num);
+ printf ("static const mp_limb_t\n");
+ printf ("sq_res_0x100[%d] = {\n", nsq_res_0x100);
+ for (i = 0; i < nsq_res_0x100; i++)
+ {
+ printf (" CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, sq_res_0x100[i]);
+ printf ("),\n");
+ }
+ printf ("};\n");
+ printf ("\n");
+
+ if (mpz_sgn (pp) != 0)
+ {
+ printf ("/* mpn_mod_34lsub1 not used due to %s */\n", mod34_excuse);
+ printf ("/* PERFSQR_PP = ");
+ }
+ else
+ printf ("/* 2^%d-1 = ", mod34_bits);
+ for (i = 0; i < nrawfactor; i++)
+ {
+ if (i != 0)
+ printf (" * ");
+ printf ("%d", rawfactor[i].divisor);
+ if (rawfactor[i].multiplicity != 1)
+ printf ("^%d", rawfactor[i].multiplicity);
+ }
+ printf (" %s*/\n", mpz_sgn (pp) == 0 ? "... " : "");
+
+ printf ("#define PERFSQR_MOD_BITS %d\n", mod_bits);
+ if (mpz_sgn (pp) != 0)
+ {
+ printf ("#define PERFSQR_PP CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, pp);
+ printf (")\n");
+ printf ("#define PERFSQR_PP_NORM CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, pp_norm);
+ printf (")\n");
+ printf ("#define PERFSQR_PP_INVERTED CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, pp_inverted);
+ printf (")\n");
+ }
+ printf ("\n");
+
+ mpz_init (mhi);
+ mpz_init (mlo);
+
+ printf ("/* This test identifies %.2f%% as non-squares. */\n",
+ (1.0 - total_fraction) * 100.0);
+ printf ("#define PERFSQR_MOD_TEST(up, usize) \\\n");
+ printf (" do { \\\n");
+ printf (" mp_limb_t r; \\\n");
+ if (mpz_sgn (pp) != 0)
+ printf (" PERFSQR_MOD_PP (r, up, usize); \\\n");
+ else
+ printf (" PERFSQR_MOD_34 (r, up, usize); \\\n");
+
+ for (i = 0; i < nfactor; i++)
+ {
+ printf (" \\\n");
+ printf (" /* %5.2f%% */ \\\n",
+ (1.0 - factor[i].fraction) * 100.0);
+
+ printf (" PERFSQR_MOD_%d (r, CNST_LIMB(%2d), CNST_LIMB(0x",
+ factor[i].divisor <= limb_bits ? 1 : 2,
+ factor[i].divisor);
+ mpz_out_str (stdout, 16, factor[i].inverse);
+ printf ("), \\\n");
+ printf (" CNST_LIMB(0x");
+
+ if ( factor[i].divisor <= limb_bits)
+ {
+ mpz_out_str (stdout, 16, factor[i].mask);
+ }
+ else
+ {
+ mpz_tdiv_r_2exp (mlo, factor[i].mask, (unsigned long) limb_bits);
+ mpz_tdiv_q_2exp (mhi, factor[i].mask, (unsigned long) limb_bits);
+ mpz_out_str (stdout, 16, mhi);
+ printf ("), CNST_LIMB(0x");
+ mpz_out_str (stdout, 16, mlo);
+ }
+ printf (")); \\\n");
+ }
+
+ printf (" } while (0)\n");
+ printf ("\n");
+
+ printf ("/* Grand total sq_res_0x100 and PERFSQR_MOD_TEST, %.2f%% non-squares. */\n",
+ (1.0 - (total_fraction * 44.0/256.0)) * 100.0);
+ printf ("\n");
+
+ printf ("/* helper for tests/mpz/t-perfsqr.c */\n");
+ printf ("#define PERFSQR_DIVISORS { 256,");
+ for (i = 0; i < nfactor; i++)
+ printf (" %d,", factor[i].divisor);
+ printf (" }\n");
+
+
+ mpz_clear (mhi);
+ mpz_clear (mlo);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int limb_bits, nail_bits;
+
+ if (argc != 3)
+ {
+ fprintf (stderr, "Usage: gen-psqr <limbbits> <nailbits>\n");
+ exit (1);
+ }
+
+ limb_bits = atoi (argv[1]);
+ nail_bits = atoi (argv[2]);
+
+ if (limb_bits <= 0
+ || nail_bits < 0
+ || nail_bits >= limb_bits)
+ {
+ fprintf (stderr, "Invalid limb/nail bits: %d %d\n",
+ limb_bits, nail_bits);
+ exit (1);
+ }
+
+ generate_sq_res_0x100 (limb_bits);
+ generate_mod (limb_bits, nail_bits);
+
+ print (limb_bits, nail_bits);
+
+ return 0;
+}
diff --git a/gmp/gen-trialdivtab.c b/gmp/gen-trialdivtab.c
new file mode 100644
index 0000000000..7587666003
--- /dev/null
+++ b/gmp/gen-trialdivtab.c
@@ -0,0 +1,300 @@
+/* gen-trialdivtab.c
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+Copyright 2009, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/*
+ Generate tables for fast, division-free trial division for GMP.
+
+ There is one main table, ptab. It contains primes, multiplied together, and
+ several types of pre-computed inverses. It refers to tables of the type
+ dtab, via the last two indices. That table contains the individual primes in
+ the range, except that the primes are not actually included in the table (see
+ the P macro; it sneakingly excludes the primes themselves). Instead, the
+ dtab tables contains tuples for each prime (modular-inverse, limit) used for
+ divisibility checks.
+
+ This interface is not intended for division of very many primes, since then
+ other algorithms apply.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "bootstrap.c"
+
+int sumspills (mpz_t, mpz_t *, int);
+void mpn_mod_1s_4p_cps (mpz_t [7], mpz_t);
+
+int limb_bits;
+
+mpz_t B;
+
+int
+main (int argc, char *argv[])
+{
+ unsigned long t, p;
+ mpz_t ppp, acc, inv, gmp_numb_max, tmp, Bhalf;
+ mpz_t pre[7];
+ int i;
+ int start_p, end_p, interval_start, interval_end, omitted_p;
+ char *endtok;
+ int stop;
+ int np, start_idx;
+
+ if (argc < 2)
+ {
+ fprintf (stderr, "usage: %s bits endprime\n", argv[0]);
+ exit (1);
+ }
+
+ limb_bits = atoi (argv[1]);
+
+ end_p = 1290; /* default end prime */
+ if (argc == 3)
+ end_p = atoi (argv[2]);
+
+ printf ("#if GMP_LIMB_BITS != %d\n", limb_bits);
+ printf ("#error This table is for GMP_LIMB_BITS = %d\n", limb_bits);
+ printf ("#endif\n\n");
+
+ printf ("#if GMP_NAIL_BITS != 0\n");
+ printf ("#error This table does not support nails\n");
+ printf ("#endif\n\n");
+
+ for (i = 0; i < 7; i++)
+ mpz_init (pre[i]);
+
+ mpz_init_set_ui (gmp_numb_max, 1);
+ mpz_mul_2exp (gmp_numb_max, gmp_numb_max, limb_bits);
+ mpz_sub_ui (gmp_numb_max, gmp_numb_max, 1);
+
+ mpz_init (tmp);
+ mpz_init (inv);
+
+ mpz_init_set_ui (B, 1); mpz_mul_2exp (B, B, limb_bits);
+ mpz_init_set_ui (Bhalf, 1); mpz_mul_2exp (Bhalf, Bhalf, limb_bits - 1);
+
+ start_p = 3;
+
+ mpz_init_set_ui (ppp, 1);
+ mpz_init (acc);
+ interval_start = start_p;
+ omitted_p = 3;
+ interval_end = 0;
+
+/* printf ("static struct gmp_primes_dtab gmp_primes_dtab[] = {\n"); */
+
+ printf ("#ifdef WANT_dtab\n");
+
+ for (t = start_p; t <= end_p; t += 2)
+ {
+ if (! isprime (t))
+ continue;
+
+ mpz_mul_ui (acc, ppp, t);
+ stop = mpz_cmp (acc, Bhalf) >= 0;
+ if (!stop)
+ {
+ mpn_mod_1s_4p_cps (pre, acc);
+ stop = sumspills (acc, pre + 2, 5);
+ }
+
+ if (stop)
+ {
+ for (p = interval_start; p <= interval_end; p += 2)
+ {
+ if (! isprime (p))
+ continue;
+
+ printf (" P(%d,", (int) p);
+ mpz_invert_ui_2exp (inv, p, limb_bits);
+ printf ("CNST_LIMB(0x"); mpz_out_str (stdout, 16, inv); printf ("),");
+
+ mpz_tdiv_q_ui (tmp, gmp_numb_max, p);
+ printf ("CNST_LIMB(0x"); mpz_out_str (stdout, 16, tmp);
+ printf (")),\n");
+ }
+ mpz_set_ui (ppp, t);
+ interval_start = t;
+ omitted_p = t;
+ }
+ else
+ {
+ mpz_set (ppp, acc);
+ }
+ interval_end = t;
+ }
+ printf ("#define SMALLEST_OMITTED_PRIME %d\n", (int) omitted_p);
+ printf ("#endif\n");
+
+ printf ("#ifdef WANT_ptab\n");
+
+/* printf ("static struct gmp_primes_ptab gmp_primes_ptab[] = {\n"); */
+
+ endtok = "";
+
+ mpz_set_ui (ppp, 1);
+ interval_start = start_p;
+ interval_end = 0;
+ np = 0;
+ start_idx = 0;
+ for (t = start_p; t <= end_p; t += 2)
+ {
+ if (! isprime (t))
+ continue;
+
+ mpz_mul_ui (acc, ppp, t);
+
+ stop = mpz_cmp (acc, Bhalf) >= 0;
+ if (!stop)
+ {
+ mpn_mod_1s_4p_cps (pre, acc);
+ stop = sumspills (acc, pre + 2, 5);
+ }
+
+ if (stop)
+ {
+ mpn_mod_1s_4p_cps (pre, ppp);
+ printf ("%s", endtok);
+ printf (" {CNST_LIMB(0x"); mpz_out_str (stdout, 16, ppp);
+ printf ("),{CNST_LIMB(0x"); mpz_out_str (stdout, 16, pre[0]);
+ printf ("),%d", (int) PTR(pre[1])[0]);
+ for (i = 0; i < 5; i++)
+ {
+ printf (",");
+ printf ("CNST_LIMB(0x"); mpz_out_str (stdout, 16, pre[2 + i]);
+ printf (")");
+ }
+ printf ("},");
+ printf ("%d,", start_idx);
+ printf ("%d}", np - start_idx);
+
+ endtok = ",\n";
+ mpz_set_ui (ppp, t);
+ interval_start = t;
+ start_idx = np;
+ }
+ else
+ {
+ mpz_set (ppp, acc);
+ }
+ interval_end = t;
+ np++;
+ }
+
+ printf ("\n");
+ printf ("#endif\n");
+
+ return 0;
+}
+
+unsigned long
+mpz_log2 (mpz_t x)
+{
+ return mpz_sgn (x) ? mpz_sizeinbase (x, 2) : 0;
+}
+
+void
+mpn_mod_1s_4p_cps (mpz_t cps[7], mpz_t bparm)
+{
+ mpz_t b, bi;
+ mpz_t B1modb, B2modb, B3modb, B4modb, B5modb;
+ mpz_t t;
+ int cnt;
+
+ mpz_init_set (b, bparm);
+
+ cnt = limb_bits - mpz_log2 (b);
+
+ mpz_init (bi);
+ mpz_init (t);
+ mpz_init (B1modb);
+ mpz_init (B2modb);
+ mpz_init (B3modb);
+ mpz_init (B4modb);
+ mpz_init (B5modb);
+
+ mpz_set_ui (t, 1);
+ mpz_mul_2exp (t, t, limb_bits - cnt);
+ mpz_sub (t, t, b);
+ mpz_mul_2exp (t, t, limb_bits);
+ mpz_tdiv_q (bi, t, b); /* bi = B^2/b, except msb */
+
+ mpz_set_ui (t, 1);
+ mpz_mul_2exp (t, t, limb_bits); /* t = B */
+ mpz_tdiv_r (B1modb, t, b);
+
+ mpz_mul_2exp (t, B1modb, limb_bits);
+ mpz_tdiv_r (B2modb, t, b);
+
+ mpz_mul_2exp (t, B2modb, limb_bits);
+ mpz_tdiv_r (B3modb, t, b);
+
+ mpz_mul_2exp (t, B3modb, limb_bits);
+ mpz_tdiv_r (B4modb, t, b);
+
+ mpz_mul_2exp (t, B4modb, limb_bits);
+ mpz_tdiv_r (B5modb, t, b);
+
+ mpz_set (cps[0], bi);
+ mpz_set_ui (cps[1], cnt);
+ mpz_tdiv_q_2exp (cps[2], B1modb, 0);
+ mpz_tdiv_q_2exp (cps[3], B2modb, 0);
+ mpz_tdiv_q_2exp (cps[4], B3modb, 0);
+ mpz_tdiv_q_2exp (cps[5], B4modb, 0);
+ mpz_tdiv_q_2exp (cps[6], B5modb, 0);
+
+ mpz_clear (b);
+ mpz_clear (bi);
+ mpz_clear (t);
+ mpz_clear (B1modb);
+ mpz_clear (B2modb);
+ mpz_clear (B3modb);
+ mpz_clear (B4modb);
+ mpz_clear (B5modb);
+}
+
+int
+sumspills (mpz_t ppp, mpz_t *a, int n)
+{
+ mpz_t s;
+ int i, ret;
+
+ mpz_init_set (s, a[0]);
+
+ for (i = 1; i < n; i++)
+ {
+ mpz_add (s, s, a[i]);
+ }
+ ret = mpz_cmp (s, B) >= 0;
+ mpz_clear (s);
+
+ return ret;
+}
diff --git a/gmp/gmp-h.in b/gmp/gmp-h.in
new file mode 100644
index 0000000000..32f63d9a08
--- /dev/null
+++ b/gmp/gmp-h.in
@@ -0,0 +1,2301 @@
+/* Definitions for GNU multiple precision functions. -*- mode: c -*-
+
+Copyright 1991, 1993-1997, 1999-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#ifndef __GMP_H__
+
+#if defined (__cplusplus)
+#include <iosfwd> /* for std::istream, std::ostream, std::string */
+#include <cstdio>
+#endif
+
+
+/* Instantiated by configure. */
+#if ! defined (__GMP_WITHIN_CONFIGURE)
+#define __GMP_HAVE_HOST_CPU_FAMILY_power @HAVE_HOST_CPU_FAMILY_power@
+#define __GMP_HAVE_HOST_CPU_FAMILY_powerpc @HAVE_HOST_CPU_FAMILY_powerpc@
+#define GMP_LIMB_BITS @GMP_LIMB_BITS@
+#define GMP_NAIL_BITS @GMP_NAIL_BITS@
+#endif
+#define GMP_NUMB_BITS (GMP_LIMB_BITS - GMP_NAIL_BITS)
+#define GMP_NUMB_MASK ((~ __GMP_CAST (mp_limb_t, 0)) >> GMP_NAIL_BITS)
+#define GMP_NUMB_MAX GMP_NUMB_MASK
+#define GMP_NAIL_MASK (~ GMP_NUMB_MASK)
+
+
+/* The following (everything under ifndef __GNU_MP__) must be identical in
+ gmp.h and mp.h to allow both to be included in an application or during
+ the library build. */
+#ifndef __GNU_MP__
+#define __GNU_MP__ 5
+
+#include <stddef.h> /* for size_t */
+
+/* Instantiated by configure. */
+#if ! defined (__GMP_WITHIN_CONFIGURE)
+@DEFN_LONG_LONG_LIMB@
+#define __GMP_LIBGMP_DLL @LIBGMP_DLL@
+#endif
+
+
+/* __GMP_DECLSPEC supports Windows DLL versions of libgmp, and is empty in
+ all other circumstances.
+
+ When compiling objects for libgmp, __GMP_DECLSPEC is an export directive,
+ or when compiling for an application it's an import directive. The two
+ cases are differentiated by __GMP_WITHIN_GMP defined by the GMP Makefiles
+ (and not defined from an application).
+
+ __GMP_DECLSPEC_XX is similarly used for libgmpxx. __GMP_WITHIN_GMPXX
+ indicates when building libgmpxx, and in that case libgmpxx functions are
+ exports, but libgmp functions which might get called are imports.
+
+ Libtool DLL_EXPORT define is not used.
+
+ There's no attempt to support GMP built both static and DLL. Doing so
+ would mean applications would have to tell us which of the two is going
+ to be used when linking, and that seems very tedious and error prone if
+ using GMP by hand, and equally tedious from a package since autoconf and
+ automake don't give much help.
+
+ __GMP_DECLSPEC is required on all documented global functions and
+ variables, the various internals in gmp-impl.h etc can be left unadorned.
+ But internals used by the test programs or speed measuring programs
+ should have __GMP_DECLSPEC, and certainly constants or variables must
+ have it or the wrong address will be resolved.
+
+ In gcc __declspec can go at either the start or end of a prototype.
+
+ In Microsoft C __declspec must go at the start, or after the type like
+ void __declspec(...) *foo()". There's no __dllexport or anything to
+ guard against someone foolish #defining dllexport. _export used to be
+ available, but no longer.
+
+ In Borland C _export still exists, but needs to go after the type, like
+ "void _export foo();". Would have to change the __GMP_DECLSPEC syntax to
+ make use of that. Probably more trouble than it's worth. */
+
+#if defined (__GNUC__)
+#define __GMP_DECLSPEC_EXPORT __declspec(__dllexport__)
+#define __GMP_DECLSPEC_IMPORT __declspec(__dllimport__)
+#endif
+#if defined (_MSC_VER) || defined (__BORLANDC__)
+#define __GMP_DECLSPEC_EXPORT __declspec(dllexport)
+#define __GMP_DECLSPEC_IMPORT __declspec(dllimport)
+#endif
+#ifdef __WATCOMC__
+#define __GMP_DECLSPEC_EXPORT __export
+#define __GMP_DECLSPEC_IMPORT __import
+#endif
+#ifdef __IBMC__
+#define __GMP_DECLSPEC_EXPORT _Export
+#define __GMP_DECLSPEC_IMPORT _Import
+#endif
+
+#if __GMP_LIBGMP_DLL
+#ifdef __GMP_WITHIN_GMP
+/* compiling to go into a DLL libgmp */
+#define __GMP_DECLSPEC __GMP_DECLSPEC_EXPORT
+#else
+/* compiling to go into an application which will link to a DLL libgmp */
+#define __GMP_DECLSPEC __GMP_DECLSPEC_IMPORT
+#endif
+#else
+/* all other cases */
+#define __GMP_DECLSPEC
+#endif
+
+
+#ifdef __GMP_SHORT_LIMB
+typedef unsigned int mp_limb_t;
+typedef int mp_limb_signed_t;
+#else
+#ifdef _LONG_LONG_LIMB
+typedef unsigned long long int mp_limb_t;
+typedef long long int mp_limb_signed_t;
+#else
+typedef unsigned long int mp_limb_t;
+typedef long int mp_limb_signed_t;
+#endif
+#endif
+typedef unsigned long int mp_bitcnt_t;
+
+/* For reference, note that the name __mpz_struct gets into C++ mangled
+ function names, which means although the "__" suggests an internal, we
+ must leave this name for binary compatibility. */
+typedef struct
+{
+ int _mp_alloc; /* Number of *limbs* allocated and pointed
+ to by the _mp_d field. */
+ int _mp_size; /* abs(_mp_size) is the number of limbs the
+ last field points to. If _mp_size is
+ negative this is a negative number. */
+ mp_limb_t *_mp_d; /* Pointer to the limbs. */
+} __mpz_struct;
+
+#endif /* __GNU_MP__ */
+
+
+typedef __mpz_struct MP_INT; /* gmp 1 source compatibility */
+typedef __mpz_struct mpz_t[1];
+
+typedef mp_limb_t * mp_ptr;
+typedef const mp_limb_t * mp_srcptr;
+#if defined (_CRAY) && ! defined (_CRAYMPP)
+/* plain `int' is much faster (48 bits) */
+#define __GMP_MP_SIZE_T_INT 1
+typedef int mp_size_t;
+typedef int mp_exp_t;
+#else
+#define __GMP_MP_SIZE_T_INT 0
+typedef long int mp_size_t;
+typedef long int mp_exp_t;
+#endif
+
+typedef struct
+{
+ __mpz_struct _mp_num;
+ __mpz_struct _mp_den;
+} __mpq_struct;
+
+typedef __mpq_struct MP_RAT; /* gmp 1 source compatibility */
+typedef __mpq_struct mpq_t[1];
+
+typedef struct
+{
+ int _mp_prec; /* Max precision, in number of `mp_limb_t's.
+ Set by mpf_init and modified by
+ mpf_set_prec. The area pointed to by the
+ _mp_d field contains `prec' + 1 limbs. */
+ int _mp_size; /* abs(_mp_size) is the number of limbs the
+ last field points to. If _mp_size is
+ negative this is a negative number. */
+ mp_exp_t _mp_exp; /* Exponent, in the base of `mp_limb_t'. */
+ mp_limb_t *_mp_d; /* Pointer to the limbs. */
+} __mpf_struct;
+
+/* typedef __mpf_struct MP_FLOAT; */
+typedef __mpf_struct mpf_t[1];
+
+/* Available random number generation algorithms. */
+typedef enum
+{
+ GMP_RAND_ALG_DEFAULT = 0,
+ GMP_RAND_ALG_LC = GMP_RAND_ALG_DEFAULT /* Linear congruential. */
+} gmp_randalg_t;
+
+/* Random state struct. */
+typedef struct
+{
+ mpz_t _mp_seed; /* _mp_d member points to state of the generator. */
+ gmp_randalg_t _mp_alg; /* Currently unused. */
+ union {
+ void *_mp_lc; /* Pointer to function pointers structure. */
+ } _mp_algdata;
+} __gmp_randstate_struct;
+typedef __gmp_randstate_struct gmp_randstate_t[1];
+
+/* Types for function declarations in gmp files. */
+/* ??? Should not pollute user name space with these ??? */
+typedef const __mpz_struct *mpz_srcptr;
+typedef __mpz_struct *mpz_ptr;
+typedef const __mpf_struct *mpf_srcptr;
+typedef __mpf_struct *mpf_ptr;
+typedef const __mpq_struct *mpq_srcptr;
+typedef __mpq_struct *mpq_ptr;
+
+
+/* This is not wanted in mp.h, so put it outside the __GNU_MP__ common
+ section. */
+#if __GMP_LIBGMP_DLL
+#ifdef __GMP_WITHIN_GMPXX
+/* compiling to go into a DLL libgmpxx */
+#define __GMP_DECLSPEC_XX __GMP_DECLSPEC_EXPORT
+#else
+/* compiling to go into a application which will link to a DLL libgmpxx */
+#define __GMP_DECLSPEC_XX __GMP_DECLSPEC_IMPORT
+#endif
+#else
+/* all other cases */
+#define __GMP_DECLSPEC_XX
+#endif
+
+
+#ifndef __MPN
+#define __MPN(x) __gmpn_##x
+#endif
+
+/* For reference, "defined(EOF)" cannot be used here. In g++ 2.95.4,
+ <iostream> defines EOF but not FILE. */
+#if defined (FILE) \
+ || defined (H_STDIO) \
+ || defined (_H_STDIO) /* AIX */ \
+ || defined (_STDIO_H) /* glibc, Sun, SCO */ \
+ || defined (_STDIO_H_) /* BSD, OSF */ \
+ || defined (__STDIO_H) /* Borland */ \
+ || defined (__STDIO_H__) /* IRIX */ \
+ || defined (_STDIO_INCLUDED) /* HPUX */ \
+ || defined (__dj_include_stdio_h_) /* DJGPP */ \
+ || defined (_FILE_DEFINED) /* Microsoft */ \
+ || defined (__STDIO__) /* Apple MPW MrC */ \
+ || defined (_MSL_STDIO_H) /* Metrowerks */ \
+ || defined (_STDIO_H_INCLUDED) /* QNX4 */ \
+ || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \
+ || defined (__STDIO_LOADED) /* VMS */
+#define _GMP_H_HAVE_FILE 1
+#endif
+
+/* In ISO C, if a prototype involving "struct obstack *" is given without
+ that structure defined, then the struct is scoped down to just the
+ prototype, causing a conflict if it's subsequently defined for real. So
+ only give prototypes if we've got obstack.h. */
+#if defined (_OBSTACK_H) /* glibc <obstack.h> */
+#define _GMP_H_HAVE_OBSTACK 1
+#endif
+
+/* The prototypes for gmp_vprintf etc are provided only if va_list is defined,
+ via an application having included <stdarg.h>. Usually va_list is a typedef
+ so can't be tested directly, but C99 specifies that va_start is a macro.
+
+ <stdio.h> will define some sort of va_list for vprintf and vfprintf, but
+ let's not bother trying to use that since it's not standard and since
+ application uses for gmp_vprintf etc will almost certainly require the
+ whole <stdarg.h> anyway. */
+
+#ifdef va_start
+#define _GMP_H_HAVE_VA_LIST 1
+#endif
+
+/* Test for gcc >= maj.min, as per __GNUC_PREREQ in glibc */
+#if defined (__GNUC__) && defined (__GNUC_MINOR__)
+#define __GMP_GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define __GMP_GNUC_PREREQ(maj, min) 0
+#endif
+
+/* "pure" is in gcc 2.96 and up, see "(gcc)Function Attributes". Basically
+ it means a function does nothing but examine its arguments and memory
+ (global or via arguments) to generate a return value, but changes nothing
+ and has no side-effects. __GMP_NO_ATTRIBUTE_CONST_PURE lets
+ tune/common.c etc turn this off when trying to write timing loops. */
+#if __GMP_GNUC_PREREQ (2,96) && ! defined (__GMP_NO_ATTRIBUTE_CONST_PURE)
+#define __GMP_ATTRIBUTE_PURE __attribute__ ((__pure__))
+#else
+#define __GMP_ATTRIBUTE_PURE
+#endif
+
+
+/* __GMP_CAST allows us to use static_cast in C++, so our macros are clean
+ to "g++ -Wold-style-cast".
+
+ Casts in "extern inline" code within an extern "C" block don't induce
+ these warnings, so __GMP_CAST only needs to be used on documented
+ macros. */
+
+#ifdef __cplusplus
+#define __GMP_CAST(type, expr) (static_cast<type> (expr))
+#else
+#define __GMP_CAST(type, expr) ((type) (expr))
+#endif
+
+
+/* An empty "throw ()" means the function doesn't throw any C++ exceptions,
+ this can save some stack frame info in applications.
+
+ Currently it's given only on functions which never divide-by-zero etc,
+ don't allocate memory, and are expected to never need to allocate memory.
+ This leaves open the possibility of a C++ throw from a future GMP
+ exceptions scheme.
+
+ mpz_set_ui etc are omitted to leave open the lazy allocation scheme
+ described in doc/tasks.html. mpz_get_d etc are omitted to leave open
+ exceptions for float overflows.
+
+ Note that __GMP_NOTHROW must be given on any inlines the same as on their
+ prototypes (for g++ at least, where they're used together). Note also
+ that g++ 3.0 demands that __GMP_NOTHROW is before other attributes like
+ __GMP_ATTRIBUTE_PURE. */
+
+#if defined (__cplusplus)
+#define __GMP_NOTHROW throw ()
+#else
+#define __GMP_NOTHROW
+#endif
+
+
+/* PORTME: What other compilers have a useful "extern inline"? "static
+ inline" would be an acceptable substitute if the compiler (or linker)
+ discards unused statics. */
+
+ /* gcc has __inline__ in all modes, including strict ansi. Give a prototype
+ for an inline too, so as to correctly specify "dllimport" on windows, in
+ case the function is called rather than inlined.
+ GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+ inline semantics, unless -fgnu89-inline is used. */
+#ifdef __GNUC__
+#if (defined __GNUC_STDC_INLINE__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 2) \
+ || (defined __GNUC_GNU_INLINE__ && defined __cplusplus)
+#define __GMP_EXTERN_INLINE extern __inline__ __attribute__ ((__gnu_inline__))
+#else
+#define __GMP_EXTERN_INLINE extern __inline__
+#endif
+#define __GMP_INLINE_PROTOTYPES 1
+#endif
+
+/* DEC C (eg. version 5.9) supports "static __inline foo()", even in -std1
+ strict ANSI mode. Inlining is done even when not optimizing (ie. -O0
+ mode, which is the default), but an unnecessary local copy of foo is
+ emitted unless -O is used. "extern __inline" is accepted, but the
+ "extern" appears to be ignored, ie. it becomes a plain global function
+ but which is inlined within its file. Don't know if all old versions of
+ DEC C supported __inline, but as a start let's do the right thing for
+ current versions. */
+#ifdef __DECC
+#define __GMP_EXTERN_INLINE static __inline
+#endif
+
+/* SCO OpenUNIX 8 cc supports "static inline foo()" but not in -Xc strict
+ ANSI mode (__STDC__ is 1 in that mode). Inlining only actually takes
+ place under -O. Without -O "foo" seems to be emitted whether it's used
+ or not, which is wasteful. "extern inline foo()" isn't useful, the
+ "extern" is apparently ignored, so foo is inlined if possible but also
+ emitted as a global, which causes multiple definition errors when
+ building a shared libgmp. */
+#ifdef __SCO_VERSION__
+#if __SCO_VERSION__ > 400000000 && __STDC__ != 1 \
+ && ! defined (__GMP_EXTERN_INLINE)
+#define __GMP_EXTERN_INLINE static inline
+#endif
+#endif
+
+/* Microsoft's C compiler accepts __inline */
+#ifdef _MSC_VER
+#define __GMP_EXTERN_INLINE __inline
+#endif
+
+/* Recent enough Sun C compilers want "inline" */
+#if defined (__SUNPRO_C) && __SUNPRO_C >= 0x560 \
+ && ! defined (__GMP_EXTERN_INLINE)
+#define __GMP_EXTERN_INLINE inline
+#endif
+
+/* Somewhat older Sun C compilers want "static inline" */
+#if defined (__SUNPRO_C) && __SUNPRO_C >= 0x540 \
+ && ! defined (__GMP_EXTERN_INLINE)
+#define __GMP_EXTERN_INLINE static inline
+#endif
+
+
+/* C++ always has "inline" and since it's a normal feature the linker should
+ discard duplicate non-inlined copies, or if it doesn't then that's a
+ problem for everyone, not just GMP. */
+#if defined (__cplusplus) && ! defined (__GMP_EXTERN_INLINE)
+#define __GMP_EXTERN_INLINE inline
+#endif
+
+/* Don't do any inlining within a configure run, since if the compiler ends
+ up emitting copies of the code into the object file it can end up
+ demanding the various support routines (like mpn_popcount) for linking,
+ making the "alloca" test and perhaps others fail. And on hppa ia64 a
+ pre-release gcc 3.2 was seen not respecting the "extern" in "extern
+ __inline__", triggering this problem too. */
+#if defined (__GMP_WITHIN_CONFIGURE) && ! __GMP_WITHIN_CONFIGURE_INLINE
+#undef __GMP_EXTERN_INLINE
+#endif
+
+/* By default, don't give a prototype when there's going to be an inline
+ version. Note in particular that Cray C++ objects to the combination of
+ prototype and inline. */
+#ifdef __GMP_EXTERN_INLINE
+#ifndef __GMP_INLINE_PROTOTYPES
+#define __GMP_INLINE_PROTOTYPES 0
+#endif
+#else
+#define __GMP_INLINE_PROTOTYPES 1
+#endif
+
+
+#define __GMP_ABS(x) ((x) >= 0 ? (x) : -(x))
+#define __GMP_MAX(h,i) ((h) > (i) ? (h) : (i))
+
+/* __GMP_USHRT_MAX is not "~ (unsigned short) 0" because short is promoted
+ to int by "~". It still needs to have the promoted type. */
+#define __GMP_UINT_MAX (~ (unsigned) 0)
+#define __GMP_ULONG_MAX (~ (unsigned long) 0)
+#define __GMP_USHRT_MAX (0 + (unsigned short) ~0)
+
+
+/* __builtin_expect is in gcc 3.0, and not in 2.95. */
+#if __GMP_GNUC_PREREQ (3,0)
+#define __GMP_LIKELY(cond) __builtin_expect ((cond) != 0, 1)
+#define __GMP_UNLIKELY(cond) __builtin_expect ((cond) != 0, 0)
+#else
+#define __GMP_LIKELY(cond) (cond)
+#define __GMP_UNLIKELY(cond) (cond)
+#endif
+
+#ifdef _CRAY
+#define __GMP_CRAY_Pragma(str) _Pragma (str)
+#else
+#define __GMP_CRAY_Pragma(str)
+#endif
+
+
+/* Allow direct user access to numerator and denominator of a mpq_t object. */
+#define mpq_numref(Q) (&((Q)->_mp_num))
+#define mpq_denref(Q) (&((Q)->_mp_den))
+
+
+#if defined (__cplusplus)
+extern "C" {
+using std::FILE;
+#endif
+
+#define mp_set_memory_functions __gmp_set_memory_functions
+__GMP_DECLSPEC void mp_set_memory_functions (void *(*) (size_t),
+ void *(*) (void *, size_t, size_t),
+ void (*) (void *, size_t)) __GMP_NOTHROW;
+
+#define mp_get_memory_functions __gmp_get_memory_functions
+__GMP_DECLSPEC void mp_get_memory_functions (void *(**) (size_t),
+ void *(**) (void *, size_t, size_t),
+ void (**) (void *, size_t)) __GMP_NOTHROW;
+
+#define mp_bits_per_limb __gmp_bits_per_limb
+__GMP_DECLSPEC extern const int mp_bits_per_limb;
+
+#define gmp_errno __gmp_errno
+__GMP_DECLSPEC extern int gmp_errno;
+
+#define gmp_version __gmp_version
+__GMP_DECLSPEC extern const char * const gmp_version;
+
+
+/**************** Random number routines. ****************/
+
+/* obsolete */
+#define gmp_randinit __gmp_randinit
+__GMP_DECLSPEC void gmp_randinit (gmp_randstate_t, gmp_randalg_t, ...);
+
+#define gmp_randinit_default __gmp_randinit_default
+__GMP_DECLSPEC void gmp_randinit_default (gmp_randstate_t);
+
+#define gmp_randinit_lc_2exp __gmp_randinit_lc_2exp
+__GMP_DECLSPEC void gmp_randinit_lc_2exp (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t);
+
+#define gmp_randinit_lc_2exp_size __gmp_randinit_lc_2exp_size
+__GMP_DECLSPEC int gmp_randinit_lc_2exp_size (gmp_randstate_t, mp_bitcnt_t);
+
+#define gmp_randinit_mt __gmp_randinit_mt
+__GMP_DECLSPEC void gmp_randinit_mt (gmp_randstate_t);
+
+#define gmp_randinit_set __gmp_randinit_set
+__GMP_DECLSPEC void gmp_randinit_set (gmp_randstate_t, const __gmp_randstate_struct *);
+
+#define gmp_randseed __gmp_randseed
+__GMP_DECLSPEC void gmp_randseed (gmp_randstate_t, mpz_srcptr);
+
+#define gmp_randseed_ui __gmp_randseed_ui
+__GMP_DECLSPEC void gmp_randseed_ui (gmp_randstate_t, unsigned long int);
+
+#define gmp_randclear __gmp_randclear
+__GMP_DECLSPEC void gmp_randclear (gmp_randstate_t);
+
+#define gmp_urandomb_ui __gmp_urandomb_ui
+__GMP_DECLSPEC unsigned long gmp_urandomb_ui (gmp_randstate_t, unsigned long);
+
+#define gmp_urandomm_ui __gmp_urandomm_ui
+__GMP_DECLSPEC unsigned long gmp_urandomm_ui (gmp_randstate_t, unsigned long);
+
+
+/**************** Formatted output routines. ****************/
+
+#define gmp_asprintf __gmp_asprintf
+__GMP_DECLSPEC int gmp_asprintf (char **, const char *, ...);
+
+#define gmp_fprintf __gmp_fprintf
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC int gmp_fprintf (FILE *, const char *, ...);
+#endif
+
+#define gmp_obstack_printf __gmp_obstack_printf
+#if defined (_GMP_H_HAVE_OBSTACK)
+__GMP_DECLSPEC int gmp_obstack_printf (struct obstack *, const char *, ...);
+#endif
+
+#define gmp_obstack_vprintf __gmp_obstack_vprintf
+#if defined (_GMP_H_HAVE_OBSTACK) && defined (_GMP_H_HAVE_VA_LIST)
+__GMP_DECLSPEC int gmp_obstack_vprintf (struct obstack *, const char *, va_list);
+#endif
+
+#define gmp_printf __gmp_printf
+__GMP_DECLSPEC int gmp_printf (const char *, ...);
+
+#define gmp_snprintf __gmp_snprintf
+__GMP_DECLSPEC int gmp_snprintf (char *, size_t, const char *, ...);
+
+#define gmp_sprintf __gmp_sprintf
+__GMP_DECLSPEC int gmp_sprintf (char *, const char *, ...);
+
+#define gmp_vasprintf __gmp_vasprintf
+#if defined (_GMP_H_HAVE_VA_LIST)
+__GMP_DECLSPEC int gmp_vasprintf (char **, const char *, va_list);
+#endif
+
+#define gmp_vfprintf __gmp_vfprintf
+#if defined (_GMP_H_HAVE_FILE) && defined (_GMP_H_HAVE_VA_LIST)
+__GMP_DECLSPEC int gmp_vfprintf (FILE *, const char *, va_list);
+#endif
+
+#define gmp_vprintf __gmp_vprintf
+#if defined (_GMP_H_HAVE_VA_LIST)
+__GMP_DECLSPEC int gmp_vprintf (const char *, va_list);
+#endif
+
+#define gmp_vsnprintf __gmp_vsnprintf
+#if defined (_GMP_H_HAVE_VA_LIST)
+__GMP_DECLSPEC int gmp_vsnprintf (char *, size_t, const char *, va_list);
+#endif
+
+#define gmp_vsprintf __gmp_vsprintf
+#if defined (_GMP_H_HAVE_VA_LIST)
+__GMP_DECLSPEC int gmp_vsprintf (char *, const char *, va_list);
+#endif
+
+
+/**************** Formatted input routines. ****************/
+
+#define gmp_fscanf __gmp_fscanf
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC int gmp_fscanf (FILE *, const char *, ...);
+#endif
+
+#define gmp_scanf __gmp_scanf
+__GMP_DECLSPEC int gmp_scanf (const char *, ...);
+
+#define gmp_sscanf __gmp_sscanf
+__GMP_DECLSPEC int gmp_sscanf (const char *, const char *, ...);
+
+#define gmp_vfscanf __gmp_vfscanf
+#if defined (_GMP_H_HAVE_FILE) && defined (_GMP_H_HAVE_VA_LIST)
+__GMP_DECLSPEC int gmp_vfscanf (FILE *, const char *, va_list);
+#endif
+
+#define gmp_vscanf __gmp_vscanf
+#if defined (_GMP_H_HAVE_VA_LIST)
+__GMP_DECLSPEC int gmp_vscanf (const char *, va_list);
+#endif
+
+#define gmp_vsscanf __gmp_vsscanf
+#if defined (_GMP_H_HAVE_VA_LIST)
+__GMP_DECLSPEC int gmp_vsscanf (const char *, const char *, va_list);
+#endif
+
+
+/**************** Integer (i.e. Z) routines. ****************/
+
+#define _mpz_realloc __gmpz_realloc
+#define mpz_realloc __gmpz_realloc
+__GMP_DECLSPEC void *_mpz_realloc (mpz_ptr, mp_size_t);
+
+#define mpz_abs __gmpz_abs
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_abs)
+__GMP_DECLSPEC void mpz_abs (mpz_ptr, mpz_srcptr);
+#endif
+
+#define mpz_add __gmpz_add
+__GMP_DECLSPEC void mpz_add (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_add_ui __gmpz_add_ui
+__GMP_DECLSPEC void mpz_add_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_addmul __gmpz_addmul
+__GMP_DECLSPEC void mpz_addmul (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_addmul_ui __gmpz_addmul_ui
+__GMP_DECLSPEC void mpz_addmul_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_and __gmpz_and
+__GMP_DECLSPEC void mpz_and (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_array_init __gmpz_array_init
+__GMP_DECLSPEC void mpz_array_init (mpz_ptr, mp_size_t, mp_size_t);
+
+#define mpz_bin_ui __gmpz_bin_ui
+__GMP_DECLSPEC void mpz_bin_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_bin_uiui __gmpz_bin_uiui
+__GMP_DECLSPEC void mpz_bin_uiui (mpz_ptr, unsigned long int, unsigned long int);
+
+#define mpz_cdiv_q __gmpz_cdiv_q
+__GMP_DECLSPEC void mpz_cdiv_q (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_cdiv_q_2exp __gmpz_cdiv_q_2exp
+__GMP_DECLSPEC void mpz_cdiv_q_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
+
+#define mpz_cdiv_q_ui __gmpz_cdiv_q_ui
+__GMP_DECLSPEC unsigned long int mpz_cdiv_q_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_cdiv_qr __gmpz_cdiv_qr
+__GMP_DECLSPEC void mpz_cdiv_qr (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_cdiv_qr_ui __gmpz_cdiv_qr_ui
+__GMP_DECLSPEC unsigned long int mpz_cdiv_qr_ui (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_cdiv_r __gmpz_cdiv_r
+__GMP_DECLSPEC void mpz_cdiv_r (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_cdiv_r_2exp __gmpz_cdiv_r_2exp
+__GMP_DECLSPEC void mpz_cdiv_r_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
+
+#define mpz_cdiv_r_ui __gmpz_cdiv_r_ui
+__GMP_DECLSPEC unsigned long int mpz_cdiv_r_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_cdiv_ui __gmpz_cdiv_ui
+__GMP_DECLSPEC unsigned long int mpz_cdiv_ui (mpz_srcptr, unsigned long int) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_clear __gmpz_clear
+__GMP_DECLSPEC void mpz_clear (mpz_ptr);
+
+#define mpz_clears __gmpz_clears
+__GMP_DECLSPEC void mpz_clears (mpz_ptr, ...);
+
+#define mpz_clrbit __gmpz_clrbit
+__GMP_DECLSPEC void mpz_clrbit (mpz_ptr, mp_bitcnt_t);
+
+#define mpz_cmp __gmpz_cmp
+__GMP_DECLSPEC int mpz_cmp (mpz_srcptr, mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_cmp_d __gmpz_cmp_d
+__GMP_DECLSPEC int mpz_cmp_d (mpz_srcptr, double) __GMP_ATTRIBUTE_PURE;
+
+#define _mpz_cmp_si __gmpz_cmp_si
+__GMP_DECLSPEC int _mpz_cmp_si (mpz_srcptr, signed long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define _mpz_cmp_ui __gmpz_cmp_ui
+__GMP_DECLSPEC int _mpz_cmp_ui (mpz_srcptr, unsigned long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_cmpabs __gmpz_cmpabs
+__GMP_DECLSPEC int mpz_cmpabs (mpz_srcptr, mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_cmpabs_d __gmpz_cmpabs_d
+__GMP_DECLSPEC int mpz_cmpabs_d (mpz_srcptr, double) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_cmpabs_ui __gmpz_cmpabs_ui
+__GMP_DECLSPEC int mpz_cmpabs_ui (mpz_srcptr, unsigned long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_com __gmpz_com
+__GMP_DECLSPEC void mpz_com (mpz_ptr, mpz_srcptr);
+
+#define mpz_combit __gmpz_combit
+__GMP_DECLSPEC void mpz_combit (mpz_ptr, mp_bitcnt_t);
+
+#define mpz_congruent_p __gmpz_congruent_p
+__GMP_DECLSPEC int mpz_congruent_p (mpz_srcptr, mpz_srcptr, mpz_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_congruent_2exp_p __gmpz_congruent_2exp_p
+__GMP_DECLSPEC int mpz_congruent_2exp_p (mpz_srcptr, mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_congruent_ui_p __gmpz_congruent_ui_p
+__GMP_DECLSPEC int mpz_congruent_ui_p (mpz_srcptr, unsigned long, unsigned long) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_divexact __gmpz_divexact
+__GMP_DECLSPEC void mpz_divexact (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_divexact_ui __gmpz_divexact_ui
+__GMP_DECLSPEC void mpz_divexact_ui (mpz_ptr, mpz_srcptr, unsigned long);
+
+#define mpz_divisible_p __gmpz_divisible_p
+__GMP_DECLSPEC int mpz_divisible_p (mpz_srcptr, mpz_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_divisible_ui_p __gmpz_divisible_ui_p
+__GMP_DECLSPEC int mpz_divisible_ui_p (mpz_srcptr, unsigned long) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_divisible_2exp_p __gmpz_divisible_2exp_p
+__GMP_DECLSPEC int mpz_divisible_2exp_p (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_dump __gmpz_dump
+__GMP_DECLSPEC void mpz_dump (mpz_srcptr);
+
+#define mpz_export __gmpz_export
+__GMP_DECLSPEC void *mpz_export (void *, size_t *, int, size_t, int, size_t, mpz_srcptr);
+
+#define mpz_fac_ui __gmpz_fac_ui
+__GMP_DECLSPEC void mpz_fac_ui (mpz_ptr, unsigned long int);
+
+#define mpz_2fac_ui __gmpz_2fac_ui
+__GMP_DECLSPEC void mpz_2fac_ui (mpz_ptr, unsigned long int);
+
+#define mpz_mfac_uiui __gmpz_mfac_uiui
+__GMP_DECLSPEC void mpz_mfac_uiui (mpz_ptr, unsigned long int, unsigned long int);
+
+#define mpz_primorial_ui __gmpz_primorial_ui
+__GMP_DECLSPEC void mpz_primorial_ui (mpz_ptr, unsigned long int);
+
+#define mpz_fdiv_q __gmpz_fdiv_q
+__GMP_DECLSPEC void mpz_fdiv_q (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_fdiv_q_2exp __gmpz_fdiv_q_2exp
+__GMP_DECLSPEC void mpz_fdiv_q_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
+
+#define mpz_fdiv_q_ui __gmpz_fdiv_q_ui
+__GMP_DECLSPEC unsigned long int mpz_fdiv_q_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_fdiv_qr __gmpz_fdiv_qr
+__GMP_DECLSPEC void mpz_fdiv_qr (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_fdiv_qr_ui __gmpz_fdiv_qr_ui
+__GMP_DECLSPEC unsigned long int mpz_fdiv_qr_ui (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_fdiv_r __gmpz_fdiv_r
+__GMP_DECLSPEC void mpz_fdiv_r (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_fdiv_r_2exp __gmpz_fdiv_r_2exp
+__GMP_DECLSPEC void mpz_fdiv_r_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
+
+#define mpz_fdiv_r_ui __gmpz_fdiv_r_ui
+__GMP_DECLSPEC unsigned long int mpz_fdiv_r_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_fdiv_ui __gmpz_fdiv_ui
+__GMP_DECLSPEC unsigned long int mpz_fdiv_ui (mpz_srcptr, unsigned long int) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_fib_ui __gmpz_fib_ui
+__GMP_DECLSPEC void mpz_fib_ui (mpz_ptr, unsigned long int);
+
+#define mpz_fib2_ui __gmpz_fib2_ui
+__GMP_DECLSPEC void mpz_fib2_ui (mpz_ptr, mpz_ptr, unsigned long int);
+
+#define mpz_fits_sint_p __gmpz_fits_sint_p
+__GMP_DECLSPEC int mpz_fits_sint_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_fits_slong_p __gmpz_fits_slong_p
+__GMP_DECLSPEC int mpz_fits_slong_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_fits_sshort_p __gmpz_fits_sshort_p
+__GMP_DECLSPEC int mpz_fits_sshort_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_fits_uint_p __gmpz_fits_uint_p
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_fits_uint_p)
+__GMP_DECLSPEC int mpz_fits_uint_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpz_fits_ulong_p __gmpz_fits_ulong_p
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_fits_ulong_p)
+__GMP_DECLSPEC int mpz_fits_ulong_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpz_fits_ushort_p __gmpz_fits_ushort_p
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_fits_ushort_p)
+__GMP_DECLSPEC int mpz_fits_ushort_p (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpz_gcd __gmpz_gcd
+__GMP_DECLSPEC void mpz_gcd (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_gcd_ui __gmpz_gcd_ui
+__GMP_DECLSPEC unsigned long int mpz_gcd_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_gcdext __gmpz_gcdext
+__GMP_DECLSPEC void mpz_gcdext (mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_get_d __gmpz_get_d
+__GMP_DECLSPEC double mpz_get_d (mpz_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_get_d_2exp __gmpz_get_d_2exp
+__GMP_DECLSPEC double mpz_get_d_2exp (signed long int *, mpz_srcptr);
+
+#define mpz_get_si __gmpz_get_si
+__GMP_DECLSPEC /* signed */ long int mpz_get_si (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_get_str __gmpz_get_str
+__GMP_DECLSPEC char *mpz_get_str (char *, int, mpz_srcptr);
+
+#define mpz_get_ui __gmpz_get_ui
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_get_ui)
+__GMP_DECLSPEC unsigned long int mpz_get_ui (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpz_getlimbn __gmpz_getlimbn
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_getlimbn)
+__GMP_DECLSPEC mp_limb_t mpz_getlimbn (mpz_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpz_hamdist __gmpz_hamdist
+__GMP_DECLSPEC mp_bitcnt_t mpz_hamdist (mpz_srcptr, mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_import __gmpz_import
+__GMP_DECLSPEC void mpz_import (mpz_ptr, size_t, int, size_t, int, size_t, const void *);
+
+#define mpz_init __gmpz_init
+__GMP_DECLSPEC void mpz_init (mpz_ptr);
+
+#define mpz_init2 __gmpz_init2
+__GMP_DECLSPEC void mpz_init2 (mpz_ptr, mp_bitcnt_t);
+
+#define mpz_inits __gmpz_inits
+__GMP_DECLSPEC void mpz_inits (mpz_ptr, ...);
+
+#define mpz_init_set __gmpz_init_set
+__GMP_DECLSPEC void mpz_init_set (mpz_ptr, mpz_srcptr);
+
+#define mpz_init_set_d __gmpz_init_set_d
+__GMP_DECLSPEC void mpz_init_set_d (mpz_ptr, double);
+
+#define mpz_init_set_si __gmpz_init_set_si
+__GMP_DECLSPEC void mpz_init_set_si (mpz_ptr, signed long int);
+
+#define mpz_init_set_str __gmpz_init_set_str
+__GMP_DECLSPEC int mpz_init_set_str (mpz_ptr, const char *, int);
+
+#define mpz_init_set_ui __gmpz_init_set_ui
+__GMP_DECLSPEC void mpz_init_set_ui (mpz_ptr, unsigned long int);
+
+#define mpz_inp_raw __gmpz_inp_raw
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpz_inp_raw (mpz_ptr, FILE *);
+#endif
+
+#define mpz_inp_str __gmpz_inp_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpz_inp_str (mpz_ptr, FILE *, int);
+#endif
+
+#define mpz_invert __gmpz_invert
+__GMP_DECLSPEC int mpz_invert (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_ior __gmpz_ior
+__GMP_DECLSPEC void mpz_ior (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_jacobi __gmpz_jacobi
+__GMP_DECLSPEC int mpz_jacobi (mpz_srcptr, mpz_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_kronecker mpz_jacobi /* alias */
+
+#define mpz_kronecker_si __gmpz_kronecker_si
+__GMP_DECLSPEC int mpz_kronecker_si (mpz_srcptr, long) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_kronecker_ui __gmpz_kronecker_ui
+__GMP_DECLSPEC int mpz_kronecker_ui (mpz_srcptr, unsigned long) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_si_kronecker __gmpz_si_kronecker
+__GMP_DECLSPEC int mpz_si_kronecker (long, mpz_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_ui_kronecker __gmpz_ui_kronecker
+__GMP_DECLSPEC int mpz_ui_kronecker (unsigned long, mpz_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_lcm __gmpz_lcm
+__GMP_DECLSPEC void mpz_lcm (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_lcm_ui __gmpz_lcm_ui
+__GMP_DECLSPEC void mpz_lcm_ui (mpz_ptr, mpz_srcptr, unsigned long);
+
+#define mpz_legendre mpz_jacobi /* alias */
+
+#define mpz_lucnum_ui __gmpz_lucnum_ui
+__GMP_DECLSPEC void mpz_lucnum_ui (mpz_ptr, unsigned long int);
+
+#define mpz_lucnum2_ui __gmpz_lucnum2_ui
+__GMP_DECLSPEC void mpz_lucnum2_ui (mpz_ptr, mpz_ptr, unsigned long int);
+
+#define mpz_millerrabin __gmpz_millerrabin
+__GMP_DECLSPEC int mpz_millerrabin (mpz_srcptr, int) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_mod __gmpz_mod
+__GMP_DECLSPEC void mpz_mod (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_mod_ui mpz_fdiv_r_ui /* same as fdiv_r because divisor unsigned */
+
+#define mpz_mul __gmpz_mul
+__GMP_DECLSPEC void mpz_mul (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_mul_2exp __gmpz_mul_2exp
+__GMP_DECLSPEC void mpz_mul_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
+
+#define mpz_mul_si __gmpz_mul_si
+__GMP_DECLSPEC void mpz_mul_si (mpz_ptr, mpz_srcptr, long int);
+
+#define mpz_mul_ui __gmpz_mul_ui
+__GMP_DECLSPEC void mpz_mul_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_neg __gmpz_neg
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_neg)
+__GMP_DECLSPEC void mpz_neg (mpz_ptr, mpz_srcptr);
+#endif
+
+#define mpz_nextprime __gmpz_nextprime
+__GMP_DECLSPEC void mpz_nextprime (mpz_ptr, mpz_srcptr);
+
+#define mpz_out_raw __gmpz_out_raw
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpz_out_raw (FILE *, mpz_srcptr);
+#endif
+
+#define mpz_out_str __gmpz_out_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpz_out_str (FILE *, int, mpz_srcptr);
+#endif
+
+#define mpz_perfect_power_p __gmpz_perfect_power_p
+__GMP_DECLSPEC int mpz_perfect_power_p (mpz_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_perfect_square_p __gmpz_perfect_square_p
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_perfect_square_p)
+__GMP_DECLSPEC int mpz_perfect_square_p (mpz_srcptr) __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpz_popcount __gmpz_popcount
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_popcount)
+__GMP_DECLSPEC mp_bitcnt_t mpz_popcount (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpz_pow_ui __gmpz_pow_ui
+__GMP_DECLSPEC void mpz_pow_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_powm __gmpz_powm
+__GMP_DECLSPEC void mpz_powm (mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_powm_sec __gmpz_powm_sec
+__GMP_DECLSPEC void mpz_powm_sec (mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_powm_ui __gmpz_powm_ui
+__GMP_DECLSPEC void mpz_powm_ui (mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr);
+
+#define mpz_probab_prime_p __gmpz_probab_prime_p
+__GMP_DECLSPEC int mpz_probab_prime_p (mpz_srcptr, int) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_random __gmpz_random
+__GMP_DECLSPEC void mpz_random (mpz_ptr, mp_size_t);
+
+#define mpz_random2 __gmpz_random2
+__GMP_DECLSPEC void mpz_random2 (mpz_ptr, mp_size_t);
+
+#define mpz_realloc2 __gmpz_realloc2
+__GMP_DECLSPEC void mpz_realloc2 (mpz_ptr, mp_bitcnt_t);
+
+#define mpz_remove __gmpz_remove
+__GMP_DECLSPEC mp_bitcnt_t mpz_remove (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_root __gmpz_root
+__GMP_DECLSPEC int mpz_root (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_rootrem __gmpz_rootrem
+__GMP_DECLSPEC void mpz_rootrem (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_rrandomb __gmpz_rrandomb
+__GMP_DECLSPEC void mpz_rrandomb (mpz_ptr, gmp_randstate_t, mp_bitcnt_t);
+
+#define mpz_scan0 __gmpz_scan0
+__GMP_DECLSPEC mp_bitcnt_t mpz_scan0 (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_scan1 __gmpz_scan1
+__GMP_DECLSPEC mp_bitcnt_t mpz_scan1 (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_set __gmpz_set
+__GMP_DECLSPEC void mpz_set (mpz_ptr, mpz_srcptr);
+
+#define mpz_set_d __gmpz_set_d
+__GMP_DECLSPEC void mpz_set_d (mpz_ptr, double);
+
+#define mpz_set_f __gmpz_set_f
+__GMP_DECLSPEC void mpz_set_f (mpz_ptr, mpf_srcptr);
+
+#define mpz_set_q __gmpz_set_q
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_set_q)
+__GMP_DECLSPEC void mpz_set_q (mpz_ptr, mpq_srcptr);
+#endif
+
+#define mpz_set_si __gmpz_set_si
+__GMP_DECLSPEC void mpz_set_si (mpz_ptr, signed long int);
+
+#define mpz_set_str __gmpz_set_str
+__GMP_DECLSPEC int mpz_set_str (mpz_ptr, const char *, int);
+
+#define mpz_set_ui __gmpz_set_ui
+__GMP_DECLSPEC void mpz_set_ui (mpz_ptr, unsigned long int);
+
+#define mpz_setbit __gmpz_setbit
+__GMP_DECLSPEC void mpz_setbit (mpz_ptr, mp_bitcnt_t);
+
+#define mpz_size __gmpz_size
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpz_size)
+__GMP_DECLSPEC size_t mpz_size (mpz_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpz_sizeinbase __gmpz_sizeinbase
+__GMP_DECLSPEC size_t mpz_sizeinbase (mpz_srcptr, int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_sqrt __gmpz_sqrt
+__GMP_DECLSPEC void mpz_sqrt (mpz_ptr, mpz_srcptr);
+
+#define mpz_sqrtrem __gmpz_sqrtrem
+__GMP_DECLSPEC void mpz_sqrtrem (mpz_ptr, mpz_ptr, mpz_srcptr);
+
+#define mpz_sub __gmpz_sub
+__GMP_DECLSPEC void mpz_sub (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_sub_ui __gmpz_sub_ui
+__GMP_DECLSPEC void mpz_sub_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_ui_sub __gmpz_ui_sub
+__GMP_DECLSPEC void mpz_ui_sub (mpz_ptr, unsigned long int, mpz_srcptr);
+
+#define mpz_submul __gmpz_submul
+__GMP_DECLSPEC void mpz_submul (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_submul_ui __gmpz_submul_ui
+__GMP_DECLSPEC void mpz_submul_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_swap __gmpz_swap
+__GMP_DECLSPEC void mpz_swap (mpz_ptr, mpz_ptr) __GMP_NOTHROW;
+
+#define mpz_tdiv_ui __gmpz_tdiv_ui
+__GMP_DECLSPEC unsigned long int mpz_tdiv_ui (mpz_srcptr, unsigned long int) __GMP_ATTRIBUTE_PURE;
+
+#define mpz_tdiv_q __gmpz_tdiv_q
+__GMP_DECLSPEC void mpz_tdiv_q (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_tdiv_q_2exp __gmpz_tdiv_q_2exp
+__GMP_DECLSPEC void mpz_tdiv_q_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
+
+#define mpz_tdiv_q_ui __gmpz_tdiv_q_ui
+__GMP_DECLSPEC unsigned long int mpz_tdiv_q_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_tdiv_qr __gmpz_tdiv_qr
+__GMP_DECLSPEC void mpz_tdiv_qr (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_tdiv_qr_ui __gmpz_tdiv_qr_ui
+__GMP_DECLSPEC unsigned long int mpz_tdiv_qr_ui (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_tdiv_r __gmpz_tdiv_r
+__GMP_DECLSPEC void mpz_tdiv_r (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_tdiv_r_2exp __gmpz_tdiv_r_2exp
+__GMP_DECLSPEC void mpz_tdiv_r_2exp (mpz_ptr, mpz_srcptr, mp_bitcnt_t);
+
+#define mpz_tdiv_r_ui __gmpz_tdiv_r_ui
+__GMP_DECLSPEC unsigned long int mpz_tdiv_r_ui (mpz_ptr, mpz_srcptr, unsigned long int);
+
+#define mpz_tstbit __gmpz_tstbit
+__GMP_DECLSPEC int mpz_tstbit (mpz_srcptr, mp_bitcnt_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpz_ui_pow_ui __gmpz_ui_pow_ui
+__GMP_DECLSPEC void mpz_ui_pow_ui (mpz_ptr, unsigned long int, unsigned long int);
+
+#define mpz_urandomb __gmpz_urandomb
+__GMP_DECLSPEC void mpz_urandomb (mpz_ptr, gmp_randstate_t, mp_bitcnt_t);
+
+#define mpz_urandomm __gmpz_urandomm
+__GMP_DECLSPEC void mpz_urandomm (mpz_ptr, gmp_randstate_t, mpz_srcptr);
+
+#define mpz_xor __gmpz_xor
+#define mpz_eor __gmpz_xor
+__GMP_DECLSPEC void mpz_xor (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_limbs_read __gmpz_limbs_read
+__GMP_DECLSPEC mp_srcptr mpz_limbs_read (mpz_srcptr);
+
+#define mpz_limbs_write __gmpz_limbs_write
+__GMP_DECLSPEC mp_ptr mpz_limbs_write (mpz_ptr, mp_size_t);
+
+#define mpz_limbs_modify __gmpz_limbs_modify
+__GMP_DECLSPEC mp_ptr mpz_limbs_modify (mpz_ptr, mp_size_t);
+
+#define mpz_limbs_finish __gmpz_limbs_finish
+__GMP_DECLSPEC void mpz_limbs_finish (mpz_ptr, mp_size_t);
+
+#define mpz_roinit_n __gmpz_roinit_n
+__GMP_DECLSPEC mpz_srcptr mpz_roinit_n (mpz_ptr, mp_srcptr, mp_size_t);
+
+#define MPZ_ROINIT_N(xp, xs) {{0, (xs),(xp) }}
+
+/**************** Rational (i.e. Q) routines. ****************/
+
+#define mpq_abs __gmpq_abs
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpq_abs)
+__GMP_DECLSPEC void mpq_abs (mpq_ptr, mpq_srcptr);
+#endif
+
+#define mpq_add __gmpq_add
+__GMP_DECLSPEC void mpq_add (mpq_ptr, mpq_srcptr, mpq_srcptr);
+
+#define mpq_canonicalize __gmpq_canonicalize
+__GMP_DECLSPEC void mpq_canonicalize (mpq_ptr);
+
+#define mpq_clear __gmpq_clear
+__GMP_DECLSPEC void mpq_clear (mpq_ptr);
+
+#define mpq_clears __gmpq_clears
+__GMP_DECLSPEC void mpq_clears (mpq_ptr, ...);
+
+#define mpq_cmp __gmpq_cmp
+__GMP_DECLSPEC int mpq_cmp (mpq_srcptr, mpq_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define _mpq_cmp_si __gmpq_cmp_si
+__GMP_DECLSPEC int _mpq_cmp_si (mpq_srcptr, long, unsigned long) __GMP_ATTRIBUTE_PURE;
+
+#define _mpq_cmp_ui __gmpq_cmp_ui
+__GMP_DECLSPEC int _mpq_cmp_ui (mpq_srcptr, unsigned long int, unsigned long int) __GMP_ATTRIBUTE_PURE;
+
+#define mpq_div __gmpq_div
+__GMP_DECLSPEC void mpq_div (mpq_ptr, mpq_srcptr, mpq_srcptr);
+
+#define mpq_div_2exp __gmpq_div_2exp
+__GMP_DECLSPEC void mpq_div_2exp (mpq_ptr, mpq_srcptr, mp_bitcnt_t);
+
+#define mpq_equal __gmpq_equal
+__GMP_DECLSPEC int mpq_equal (mpq_srcptr, mpq_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpq_get_num __gmpq_get_num
+__GMP_DECLSPEC void mpq_get_num (mpz_ptr, mpq_srcptr);
+
+#define mpq_get_den __gmpq_get_den
+__GMP_DECLSPEC void mpq_get_den (mpz_ptr, mpq_srcptr);
+
+#define mpq_get_d __gmpq_get_d
+__GMP_DECLSPEC double mpq_get_d (mpq_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define mpq_get_str __gmpq_get_str
+__GMP_DECLSPEC char *mpq_get_str (char *, int, mpq_srcptr);
+
+#define mpq_init __gmpq_init
+__GMP_DECLSPEC void mpq_init (mpq_ptr);
+
+#define mpq_inits __gmpq_inits
+__GMP_DECLSPEC void mpq_inits (mpq_ptr, ...);
+
+#define mpq_inp_str __gmpq_inp_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpq_inp_str (mpq_ptr, FILE *, int);
+#endif
+
+#define mpq_inv __gmpq_inv
+__GMP_DECLSPEC void mpq_inv (mpq_ptr, mpq_srcptr);
+
+#define mpq_mul __gmpq_mul
+__GMP_DECLSPEC void mpq_mul (mpq_ptr, mpq_srcptr, mpq_srcptr);
+
+#define mpq_mul_2exp __gmpq_mul_2exp
+__GMP_DECLSPEC void mpq_mul_2exp (mpq_ptr, mpq_srcptr, mp_bitcnt_t);
+
+#define mpq_neg __gmpq_neg
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpq_neg)
+__GMP_DECLSPEC void mpq_neg (mpq_ptr, mpq_srcptr);
+#endif
+
+#define mpq_out_str __gmpq_out_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpq_out_str (FILE *, int, mpq_srcptr);
+#endif
+
+#define mpq_set __gmpq_set
+__GMP_DECLSPEC void mpq_set (mpq_ptr, mpq_srcptr);
+
+#define mpq_set_d __gmpq_set_d
+__GMP_DECLSPEC void mpq_set_d (mpq_ptr, double);
+
+#define mpq_set_den __gmpq_set_den
+__GMP_DECLSPEC void mpq_set_den (mpq_ptr, mpz_srcptr);
+
+#define mpq_set_f __gmpq_set_f
+__GMP_DECLSPEC void mpq_set_f (mpq_ptr, mpf_srcptr);
+
+#define mpq_set_num __gmpq_set_num
+__GMP_DECLSPEC void mpq_set_num (mpq_ptr, mpz_srcptr);
+
+#define mpq_set_si __gmpq_set_si
+__GMP_DECLSPEC void mpq_set_si (mpq_ptr, signed long int, unsigned long int);
+
+#define mpq_set_str __gmpq_set_str
+__GMP_DECLSPEC int mpq_set_str (mpq_ptr, const char *, int);
+
+#define mpq_set_ui __gmpq_set_ui
+__GMP_DECLSPEC void mpq_set_ui (mpq_ptr, unsigned long int, unsigned long int);
+
+#define mpq_set_z __gmpq_set_z
+__GMP_DECLSPEC void mpq_set_z (mpq_ptr, mpz_srcptr);
+
+#define mpq_sub __gmpq_sub
+__GMP_DECLSPEC void mpq_sub (mpq_ptr, mpq_srcptr, mpq_srcptr);
+
+#define mpq_swap __gmpq_swap
+__GMP_DECLSPEC void mpq_swap (mpq_ptr, mpq_ptr) __GMP_NOTHROW;
+
+
+/**************** Float (i.e. F) routines. ****************/
+
+#define mpf_abs __gmpf_abs
+__GMP_DECLSPEC void mpf_abs (mpf_ptr, mpf_srcptr);
+
+#define mpf_add __gmpf_add
+__GMP_DECLSPEC void mpf_add (mpf_ptr, mpf_srcptr, mpf_srcptr);
+
+#define mpf_add_ui __gmpf_add_ui
+__GMP_DECLSPEC void mpf_add_ui (mpf_ptr, mpf_srcptr, unsigned long int);
+#define mpf_ceil __gmpf_ceil
+__GMP_DECLSPEC void mpf_ceil (mpf_ptr, mpf_srcptr);
+
+#define mpf_clear __gmpf_clear
+__GMP_DECLSPEC void mpf_clear (mpf_ptr);
+
+#define mpf_clears __gmpf_clears
+__GMP_DECLSPEC void mpf_clears (mpf_ptr, ...);
+
+#define mpf_cmp __gmpf_cmp
+__GMP_DECLSPEC int mpf_cmp (mpf_srcptr, mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_cmp_d __gmpf_cmp_d
+__GMP_DECLSPEC int mpf_cmp_d (mpf_srcptr, double) __GMP_ATTRIBUTE_PURE;
+
+#define mpf_cmp_si __gmpf_cmp_si
+__GMP_DECLSPEC int mpf_cmp_si (mpf_srcptr, signed long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_cmp_ui __gmpf_cmp_ui
+__GMP_DECLSPEC int mpf_cmp_ui (mpf_srcptr, unsigned long int) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_div __gmpf_div
+__GMP_DECLSPEC void mpf_div (mpf_ptr, mpf_srcptr, mpf_srcptr);
+
+#define mpf_div_2exp __gmpf_div_2exp
+__GMP_DECLSPEC void mpf_div_2exp (mpf_ptr, mpf_srcptr, mp_bitcnt_t);
+
+#define mpf_div_ui __gmpf_div_ui
+__GMP_DECLSPEC void mpf_div_ui (mpf_ptr, mpf_srcptr, unsigned long int);
+
+#define mpf_dump __gmpf_dump
+__GMP_DECLSPEC void mpf_dump (mpf_srcptr);
+
+#define mpf_eq __gmpf_eq
+__GMP_DECLSPEC int mpf_eq (mpf_srcptr, mpf_srcptr, mp_bitcnt_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpf_fits_sint_p __gmpf_fits_sint_p
+__GMP_DECLSPEC int mpf_fits_sint_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_fits_slong_p __gmpf_fits_slong_p
+__GMP_DECLSPEC int mpf_fits_slong_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_fits_sshort_p __gmpf_fits_sshort_p
+__GMP_DECLSPEC int mpf_fits_sshort_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_fits_uint_p __gmpf_fits_uint_p
+__GMP_DECLSPEC int mpf_fits_uint_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_fits_ulong_p __gmpf_fits_ulong_p
+__GMP_DECLSPEC int mpf_fits_ulong_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_fits_ushort_p __gmpf_fits_ushort_p
+__GMP_DECLSPEC int mpf_fits_ushort_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_floor __gmpf_floor
+__GMP_DECLSPEC void mpf_floor (mpf_ptr, mpf_srcptr);
+
+#define mpf_get_d __gmpf_get_d
+__GMP_DECLSPEC double mpf_get_d (mpf_srcptr) __GMP_ATTRIBUTE_PURE;
+
+#define mpf_get_d_2exp __gmpf_get_d_2exp
+__GMP_DECLSPEC double mpf_get_d_2exp (signed long int *, mpf_srcptr);
+
+#define mpf_get_default_prec __gmpf_get_default_prec
+__GMP_DECLSPEC mp_bitcnt_t mpf_get_default_prec (void) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_get_prec __gmpf_get_prec
+__GMP_DECLSPEC mp_bitcnt_t mpf_get_prec (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_get_si __gmpf_get_si
+__GMP_DECLSPEC long mpf_get_si (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_get_str __gmpf_get_str
+__GMP_DECLSPEC char *mpf_get_str (char *, mp_exp_t *, int, size_t, mpf_srcptr);
+
+#define mpf_get_ui __gmpf_get_ui
+__GMP_DECLSPEC unsigned long mpf_get_ui (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_init __gmpf_init
+__GMP_DECLSPEC void mpf_init (mpf_ptr);
+
+#define mpf_init2 __gmpf_init2
+__GMP_DECLSPEC void mpf_init2 (mpf_ptr, mp_bitcnt_t);
+
+#define mpf_inits __gmpf_inits
+__GMP_DECLSPEC void mpf_inits (mpf_ptr, ...);
+
+#define mpf_init_set __gmpf_init_set
+__GMP_DECLSPEC void mpf_init_set (mpf_ptr, mpf_srcptr);
+
+#define mpf_init_set_d __gmpf_init_set_d
+__GMP_DECLSPEC void mpf_init_set_d (mpf_ptr, double);
+
+#define mpf_init_set_si __gmpf_init_set_si
+__GMP_DECLSPEC void mpf_init_set_si (mpf_ptr, signed long int);
+
+#define mpf_init_set_str __gmpf_init_set_str
+__GMP_DECLSPEC int mpf_init_set_str (mpf_ptr, const char *, int);
+
+#define mpf_init_set_ui __gmpf_init_set_ui
+__GMP_DECLSPEC void mpf_init_set_ui (mpf_ptr, unsigned long int);
+
+#define mpf_inp_str __gmpf_inp_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpf_inp_str (mpf_ptr, FILE *, int);
+#endif
+
+#define mpf_integer_p __gmpf_integer_p
+__GMP_DECLSPEC int mpf_integer_p (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_mul __gmpf_mul
+__GMP_DECLSPEC void mpf_mul (mpf_ptr, mpf_srcptr, mpf_srcptr);
+
+#define mpf_mul_2exp __gmpf_mul_2exp
+__GMP_DECLSPEC void mpf_mul_2exp (mpf_ptr, mpf_srcptr, mp_bitcnt_t);
+
+#define mpf_mul_ui __gmpf_mul_ui
+__GMP_DECLSPEC void mpf_mul_ui (mpf_ptr, mpf_srcptr, unsigned long int);
+
+#define mpf_neg __gmpf_neg
+__GMP_DECLSPEC void mpf_neg (mpf_ptr, mpf_srcptr);
+
+#define mpf_out_str __gmpf_out_str
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpf_out_str (FILE *, int, size_t, mpf_srcptr);
+#endif
+
+#define mpf_pow_ui __gmpf_pow_ui
+__GMP_DECLSPEC void mpf_pow_ui (mpf_ptr, mpf_srcptr, unsigned long int);
+
+#define mpf_random2 __gmpf_random2
+__GMP_DECLSPEC void mpf_random2 (mpf_ptr, mp_size_t, mp_exp_t);
+
+#define mpf_reldiff __gmpf_reldiff
+__GMP_DECLSPEC void mpf_reldiff (mpf_ptr, mpf_srcptr, mpf_srcptr);
+
+#define mpf_set __gmpf_set
+__GMP_DECLSPEC void mpf_set (mpf_ptr, mpf_srcptr);
+
+#define mpf_set_d __gmpf_set_d
+__GMP_DECLSPEC void mpf_set_d (mpf_ptr, double);
+
+#define mpf_set_default_prec __gmpf_set_default_prec
+__GMP_DECLSPEC void mpf_set_default_prec (mp_bitcnt_t) __GMP_NOTHROW;
+
+#define mpf_set_prec __gmpf_set_prec
+__GMP_DECLSPEC void mpf_set_prec (mpf_ptr, mp_bitcnt_t);
+
+#define mpf_set_prec_raw __gmpf_set_prec_raw
+__GMP_DECLSPEC void mpf_set_prec_raw (mpf_ptr, mp_bitcnt_t) __GMP_NOTHROW;
+
+#define mpf_set_q __gmpf_set_q
+__GMP_DECLSPEC void mpf_set_q (mpf_ptr, mpq_srcptr);
+
+#define mpf_set_si __gmpf_set_si
+__GMP_DECLSPEC void mpf_set_si (mpf_ptr, signed long int);
+
+#define mpf_set_str __gmpf_set_str
+__GMP_DECLSPEC int mpf_set_str (mpf_ptr, const char *, int);
+
+#define mpf_set_ui __gmpf_set_ui
+__GMP_DECLSPEC void mpf_set_ui (mpf_ptr, unsigned long int);
+
+#define mpf_set_z __gmpf_set_z
+__GMP_DECLSPEC void mpf_set_z (mpf_ptr, mpz_srcptr);
+
+#define mpf_size __gmpf_size
+__GMP_DECLSPEC size_t mpf_size (mpf_srcptr) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpf_sqrt __gmpf_sqrt
+__GMP_DECLSPEC void mpf_sqrt (mpf_ptr, mpf_srcptr);
+
+#define mpf_sqrt_ui __gmpf_sqrt_ui
+__GMP_DECLSPEC void mpf_sqrt_ui (mpf_ptr, unsigned long int);
+
+#define mpf_sub __gmpf_sub
+__GMP_DECLSPEC void mpf_sub (mpf_ptr, mpf_srcptr, mpf_srcptr);
+
+#define mpf_sub_ui __gmpf_sub_ui
+__GMP_DECLSPEC void mpf_sub_ui (mpf_ptr, mpf_srcptr, unsigned long int);
+
+#define mpf_swap __gmpf_swap
+__GMP_DECLSPEC void mpf_swap (mpf_ptr, mpf_ptr) __GMP_NOTHROW;
+
+#define mpf_trunc __gmpf_trunc
+__GMP_DECLSPEC void mpf_trunc (mpf_ptr, mpf_srcptr);
+
+#define mpf_ui_div __gmpf_ui_div
+__GMP_DECLSPEC void mpf_ui_div (mpf_ptr, unsigned long int, mpf_srcptr);
+
+#define mpf_ui_sub __gmpf_ui_sub
+__GMP_DECLSPEC void mpf_ui_sub (mpf_ptr, unsigned long int, mpf_srcptr);
+
+#define mpf_urandomb __gmpf_urandomb
+__GMP_DECLSPEC void mpf_urandomb (mpf_t, gmp_randstate_t, mp_bitcnt_t);
+
+
+/************ Low level positive-integer (i.e. N) routines. ************/
+
+/* This is ugly, but we need to make user calls reach the prefixed function. */
+
+#define mpn_add __MPN(add)
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_add)
+__GMP_DECLSPEC mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+#endif
+
+#define mpn_add_1 __MPN(add_1)
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_add_1)
+__GMP_DECLSPEC mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t) __GMP_NOTHROW;
+#endif
+
+#define mpn_add_n __MPN(add_n)
+__GMP_DECLSPEC mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+#define mpn_addmul_1 __MPN(addmul_1)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_cmp __MPN(cmp)
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_cmp)
+__GMP_DECLSPEC int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpn_divexact_by3(dst,src,size) \
+ mpn_divexact_by3c (dst, src, size, __GMP_CAST (mp_limb_t, 0))
+
+#define mpn_divexact_by3c __MPN(divexact_by3c)
+__GMP_DECLSPEC mp_limb_t mpn_divexact_by3c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_divmod_1(qp,np,nsize,dlimb) \
+ mpn_divrem_1 (qp, __GMP_CAST (mp_size_t, 0), np, nsize, dlimb)
+
+#define mpn_divrem __MPN(divrem)
+__GMP_DECLSPEC mp_limb_t mpn_divrem (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr, mp_size_t);
+
+#define mpn_divrem_1 __MPN(divrem_1)
+__GMP_DECLSPEC mp_limb_t mpn_divrem_1 (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_divrem_2 __MPN(divrem_2)
+__GMP_DECLSPEC mp_limb_t mpn_divrem_2 (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr);
+
+#define mpn_div_qr_1 __MPN(div_qr_1)
+__GMP_DECLSPEC mp_limb_t mpn_div_qr_1 (mp_ptr, mp_limb_t *, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_div_qr_2 __MPN(div_qr_2)
+__GMP_DECLSPEC mp_limb_t mpn_div_qr_2 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_gcd __MPN(gcd)
+__GMP_DECLSPEC mp_size_t mpn_gcd (mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
+
+#define mpn_gcd_1 __MPN(gcd_1)
+__GMP_DECLSPEC mp_limb_t mpn_gcd_1 (mp_srcptr, mp_size_t, mp_limb_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_gcdext_1 __MPN(gcdext_1)
+__GMP_DECLSPEC mp_limb_t mpn_gcdext_1 (mp_limb_signed_t *, mp_limb_signed_t *, mp_limb_t, mp_limb_t);
+
+#define mpn_gcdext __MPN(gcdext)
+__GMP_DECLSPEC mp_size_t mpn_gcdext (mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
+
+#define mpn_get_str __MPN(get_str)
+__GMP_DECLSPEC size_t mpn_get_str (unsigned char *, int, mp_ptr, mp_size_t);
+
+#define mpn_hamdist __MPN(hamdist)
+__GMP_DECLSPEC mp_bitcnt_t mpn_hamdist (mp_srcptr, mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpn_lshift __MPN(lshift)
+__GMP_DECLSPEC mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
+
+#define mpn_mod_1 __MPN(mod_1)
+__GMP_DECLSPEC mp_limb_t mpn_mod_1 (mp_srcptr, mp_size_t, mp_limb_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_mul __MPN(mul)
+__GMP_DECLSPEC mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+#define mpn_mul_1 __MPN(mul_1)
+__GMP_DECLSPEC mp_limb_t mpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_mul_n __MPN(mul_n)
+__GMP_DECLSPEC void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+#define mpn_sqr __MPN(sqr)
+__GMP_DECLSPEC void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t);
+
+#define mpn_neg __MPN(neg)
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_neg)
+__GMP_DECLSPEC mp_limb_t mpn_neg (mp_ptr, mp_srcptr, mp_size_t);
+#endif
+
+#define mpn_com __MPN(com)
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_com)
+__GMP_DECLSPEC void mpn_com (mp_ptr, mp_srcptr, mp_size_t);
+#endif
+
+#define mpn_perfect_square_p __MPN(perfect_square_p)
+__GMP_DECLSPEC int mpn_perfect_square_p (mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_perfect_power_p __MPN(perfect_power_p)
+__GMP_DECLSPEC int mpn_perfect_power_p (mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_popcount __MPN(popcount)
+__GMP_DECLSPEC mp_bitcnt_t mpn_popcount (mp_srcptr, mp_size_t) __GMP_NOTHROW __GMP_ATTRIBUTE_PURE;
+
+#define mpn_pow_1 __MPN(pow_1)
+__GMP_DECLSPEC mp_size_t mpn_pow_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
+
+/* undocumented now, but retained here for upward compatibility */
+#define mpn_preinv_mod_1 __MPN(preinv_mod_1)
+__GMP_DECLSPEC mp_limb_t mpn_preinv_mod_1 (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_random __MPN(random)
+__GMP_DECLSPEC void mpn_random (mp_ptr, mp_size_t);
+
+#define mpn_random2 __MPN(random2)
+__GMP_DECLSPEC void mpn_random2 (mp_ptr, mp_size_t);
+
+#define mpn_rshift __MPN(rshift)
+__GMP_DECLSPEC mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
+
+#define mpn_scan0 __MPN(scan0)
+__GMP_DECLSPEC mp_bitcnt_t mpn_scan0 (mp_srcptr, mp_bitcnt_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_scan1 __MPN(scan1)
+__GMP_DECLSPEC mp_bitcnt_t mpn_scan1 (mp_srcptr, mp_bitcnt_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_set_str __MPN(set_str)
+__GMP_DECLSPEC mp_size_t mpn_set_str (mp_ptr, const unsigned char *, size_t, int);
+
+#define mpn_sizeinbase __MPN(sizeinbase)
+__GMP_DECLSPEC size_t mpn_sizeinbase (mp_srcptr, mp_size_t, int);
+
+#define mpn_sqrtrem __MPN(sqrtrem)
+__GMP_DECLSPEC mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t);
+
+#define mpn_sub __MPN(sub)
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_sub)
+__GMP_DECLSPEC mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+#endif
+
+#define mpn_sub_1 __MPN(sub_1)
+#if __GMP_INLINE_PROTOTYPES || defined (__GMP_FORCE_mpn_sub_1)
+__GMP_DECLSPEC mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t) __GMP_NOTHROW;
+#endif
+
+#define mpn_sub_n __MPN(sub_n)
+__GMP_DECLSPEC mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+#define mpn_submul_1 __MPN(submul_1)
+__GMP_DECLSPEC mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_tdiv_qr __MPN(tdiv_qr)
+__GMP_DECLSPEC void mpn_tdiv_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+#define mpn_and_n __MPN(and_n)
+__GMP_DECLSPEC void mpn_and_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_andn_n __MPN(andn_n)
+__GMP_DECLSPEC void mpn_andn_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_nand_n __MPN(nand_n)
+__GMP_DECLSPEC void mpn_nand_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_ior_n __MPN(ior_n)
+__GMP_DECLSPEC void mpn_ior_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_iorn_n __MPN(iorn_n)
+__GMP_DECLSPEC void mpn_iorn_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_nior_n __MPN(nior_n)
+__GMP_DECLSPEC void mpn_nior_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_xor_n __MPN(xor_n)
+__GMP_DECLSPEC void mpn_xor_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_xnor_n __MPN(xnor_n)
+__GMP_DECLSPEC void mpn_xnor_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+#define mpn_copyi __MPN(copyi)
+__GMP_DECLSPEC void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t);
+#define mpn_copyd __MPN(copyd)
+__GMP_DECLSPEC void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t);
+#define mpn_zero __MPN(zero)
+__GMP_DECLSPEC void mpn_zero (mp_ptr, mp_size_t);
+
+#define mpn_cnd_add_n __MPN(cnd_add_n)
+__GMP_DECLSPEC mp_limb_t mpn_cnd_add_n (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_cnd_sub_n __MPN(cnd_sub_n)
+__GMP_DECLSPEC mp_limb_t mpn_cnd_sub_n (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+#define mpn_sec_add_1 __MPN(sec_add_1)
+__GMP_DECLSPEC mp_limb_t mpn_sec_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
+#define mpn_sec_add_1_itch __MPN(sec_add_1_itch)
+__GMP_DECLSPEC mp_size_t mpn_sec_add_1_itch (mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_sec_sub_1 __MPN(sec_sub_1)
+__GMP_DECLSPEC mp_limb_t mpn_sec_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
+#define mpn_sec_sub_1_itch __MPN(sec_sub_1_itch)
+__GMP_DECLSPEC mp_size_t mpn_sec_sub_1_itch (mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_sec_mul __MPN(sec_mul)
+__GMP_DECLSPEC void mpn_sec_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_sec_mul_itch __MPN(sec_mul_itch)
+__GMP_DECLSPEC mp_size_t mpn_sec_mul_itch (mp_size_t, mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_sec_sqr __MPN(sec_sqr)
+__GMP_DECLSPEC void mpn_sec_sqr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_sec_sqr_itch __MPN(sec_sqr_itch)
+__GMP_DECLSPEC mp_size_t mpn_sec_sqr_itch (mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_sec_powm __MPN(sec_powm)
+__GMP_DECLSPEC void mpn_sec_powm (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_bitcnt_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_sec_powm_itch __MPN(sec_powm_itch)
+__GMP_DECLSPEC mp_size_t mpn_sec_powm_itch (mp_size_t, mp_bitcnt_t, mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_sec_tabselect __MPN(sec_tabselect)
+__GMP_DECLSPEC void mpn_sec_tabselect (volatile mp_limb_t *, volatile const mp_limb_t *, mp_size_t, mp_size_t, mp_size_t);
+
+#define mpn_sec_div_qr __MPN(sec_div_qr)
+__GMP_DECLSPEC mp_limb_t mpn_sec_div_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_sec_div_qr_itch __MPN(sec_div_qr_itch)
+__GMP_DECLSPEC mp_size_t mpn_sec_div_qr_itch (mp_size_t, mp_size_t) __GMP_ATTRIBUTE_PURE;
+#define mpn_sec_div_r __MPN(sec_div_r)
+__GMP_DECLSPEC void mpn_sec_div_r (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_sec_div_r_itch __MPN(sec_div_r_itch)
+__GMP_DECLSPEC mp_size_t mpn_sec_div_r_itch (mp_size_t, mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_sec_invert __MPN(sec_invert)
+__GMP_DECLSPEC int mpn_sec_invert (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_bitcnt_t, mp_ptr);
+#define mpn_sec_invert_itch __MPN(sec_invert_itch)
+__GMP_DECLSPEC mp_size_t mpn_sec_invert_itch (mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+
+/**************** mpz inlines ****************/
+
+/* The following are provided as inlines where possible, but always exist as
+ library functions too, for binary compatibility.
+
+ Within gmp itself this inlining generally isn't relied on, since it
+ doesn't get done for all compilers, whereas if something is worth
+ inlining then it's worth arranging always.
+
+ There are two styles of inlining here. When the same bit of code is
+ wanted for the inline as for the library version, then __GMP_FORCE_foo
+ arranges for that code to be emitted and the __GMP_EXTERN_INLINE
+ directive suppressed, eg. mpz_fits_uint_p. When a different bit of code
+ is wanted for the inline than for the library version, then
+ __GMP_FORCE_foo arranges the inline to be suppressed, eg. mpz_abs. */
+
+#if defined (__GMP_EXTERN_INLINE) && ! defined (__GMP_FORCE_mpz_abs)
+__GMP_EXTERN_INLINE void
+mpz_abs (mpz_ptr __gmp_w, mpz_srcptr __gmp_u)
+{
+ if (__gmp_w != __gmp_u)
+ mpz_set (__gmp_w, __gmp_u);
+ __gmp_w->_mp_size = __GMP_ABS (__gmp_w->_mp_size);
+}
+#endif
+
+#if GMP_NAIL_BITS == 0
+#define __GMPZ_FITS_UTYPE_P(z,maxval) \
+ mp_size_t __gmp_n = z->_mp_size; \
+ mp_ptr __gmp_p = z->_mp_d; \
+ return (__gmp_n == 0 || (__gmp_n == 1 && __gmp_p[0] <= maxval));
+#else
+#define __GMPZ_FITS_UTYPE_P(z,maxval) \
+ mp_size_t __gmp_n = z->_mp_size; \
+ mp_ptr __gmp_p = z->_mp_d; \
+ return (__gmp_n == 0 || (__gmp_n == 1 && __gmp_p[0] <= maxval) \
+ || (__gmp_n == 2 && __gmp_p[1] <= ((mp_limb_t) maxval >> GMP_NUMB_BITS)));
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_fits_uint_p)
+#if ! defined (__GMP_FORCE_mpz_fits_uint_p)
+__GMP_EXTERN_INLINE
+#endif
+int
+mpz_fits_uint_p (mpz_srcptr __gmp_z) __GMP_NOTHROW
+{
+ __GMPZ_FITS_UTYPE_P (__gmp_z, __GMP_UINT_MAX);
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_fits_ulong_p)
+#if ! defined (__GMP_FORCE_mpz_fits_ulong_p)
+__GMP_EXTERN_INLINE
+#endif
+int
+mpz_fits_ulong_p (mpz_srcptr __gmp_z) __GMP_NOTHROW
+{
+ __GMPZ_FITS_UTYPE_P (__gmp_z, __GMP_ULONG_MAX);
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_fits_ushort_p)
+#if ! defined (__GMP_FORCE_mpz_fits_ushort_p)
+__GMP_EXTERN_INLINE
+#endif
+int
+mpz_fits_ushort_p (mpz_srcptr __gmp_z) __GMP_NOTHROW
+{
+ __GMPZ_FITS_UTYPE_P (__gmp_z, __GMP_USHRT_MAX);
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_get_ui)
+#if ! defined (__GMP_FORCE_mpz_get_ui)
+__GMP_EXTERN_INLINE
+#endif
+unsigned long
+mpz_get_ui (mpz_srcptr __gmp_z) __GMP_NOTHROW
+{
+ mp_ptr __gmp_p = __gmp_z->_mp_d;
+ mp_size_t __gmp_n = __gmp_z->_mp_size;
+ mp_limb_t __gmp_l = __gmp_p[0];
+ /* This is a "#if" rather than a plain "if" so as to avoid gcc warnings
+ about "<< GMP_NUMB_BITS" exceeding the type size, and to avoid Borland
+ C++ 6.0 warnings about condition always true for something like
+ "__GMP_ULONG_MAX < GMP_NUMB_MASK". */
+#if GMP_NAIL_BITS == 0 || defined (_LONG_LONG_LIMB)
+ /* limb==long and no nails, or limb==longlong, one limb is enough */
+ return (__gmp_n != 0 ? __gmp_l : 0);
+#else
+ /* limb==long and nails, need two limbs when available */
+ __gmp_n = __GMP_ABS (__gmp_n);
+ if (__gmp_n <= 1)
+ return (__gmp_n != 0 ? __gmp_l : 0);
+ else
+ return __gmp_l + (__gmp_p[1] << GMP_NUMB_BITS);
+#endif
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_getlimbn)
+#if ! defined (__GMP_FORCE_mpz_getlimbn)
+__GMP_EXTERN_INLINE
+#endif
+mp_limb_t
+mpz_getlimbn (mpz_srcptr __gmp_z, mp_size_t __gmp_n) __GMP_NOTHROW
+{
+ mp_limb_t __gmp_result = 0;
+ if (__GMP_LIKELY (__gmp_n >= 0 && __gmp_n < __GMP_ABS (__gmp_z->_mp_size)))
+ __gmp_result = __gmp_z->_mp_d[__gmp_n];
+ return __gmp_result;
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) && ! defined (__GMP_FORCE_mpz_neg)
+__GMP_EXTERN_INLINE void
+mpz_neg (mpz_ptr __gmp_w, mpz_srcptr __gmp_u)
+{
+ if (__gmp_w != __gmp_u)
+ mpz_set (__gmp_w, __gmp_u);
+ __gmp_w->_mp_size = - __gmp_w->_mp_size;
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_perfect_square_p)
+#if ! defined (__GMP_FORCE_mpz_perfect_square_p)
+__GMP_EXTERN_INLINE
+#endif
+int
+mpz_perfect_square_p (mpz_srcptr __gmp_a)
+{
+ mp_size_t __gmp_asize;
+ int __gmp_result;
+
+ __gmp_asize = __gmp_a->_mp_size;
+ __gmp_result = (__gmp_asize >= 0); /* zero is a square, negatives are not */
+ if (__GMP_LIKELY (__gmp_asize > 0))
+ __gmp_result = mpn_perfect_square_p (__gmp_a->_mp_d, __gmp_asize);
+ return __gmp_result;
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_popcount)
+#if ! defined (__GMP_FORCE_mpz_popcount)
+__GMP_EXTERN_INLINE
+#endif
+mp_bitcnt_t
+mpz_popcount (mpz_srcptr __gmp_u) __GMP_NOTHROW
+{
+ mp_size_t __gmp_usize;
+ mp_bitcnt_t __gmp_result;
+
+ __gmp_usize = __gmp_u->_mp_size;
+ __gmp_result = (__gmp_usize < 0 ? __GMP_ULONG_MAX : 0);
+ if (__GMP_LIKELY (__gmp_usize > 0))
+ __gmp_result = mpn_popcount (__gmp_u->_mp_d, __gmp_usize);
+ return __gmp_result;
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_set_q)
+#if ! defined (__GMP_FORCE_mpz_set_q)
+__GMP_EXTERN_INLINE
+#endif
+void
+mpz_set_q (mpz_ptr __gmp_w, mpq_srcptr __gmp_u)
+{
+ mpz_tdiv_q (__gmp_w, mpq_numref (__gmp_u), mpq_denref (__gmp_u));
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpz_size)
+#if ! defined (__GMP_FORCE_mpz_size)
+__GMP_EXTERN_INLINE
+#endif
+size_t
+mpz_size (mpz_srcptr __gmp_z) __GMP_NOTHROW
+{
+ return __GMP_ABS (__gmp_z->_mp_size);
+}
+#endif
+
+
+/**************** mpq inlines ****************/
+
+#if defined (__GMP_EXTERN_INLINE) && ! defined (__GMP_FORCE_mpq_abs)
+__GMP_EXTERN_INLINE void
+mpq_abs (mpq_ptr __gmp_w, mpq_srcptr __gmp_u)
+{
+ if (__gmp_w != __gmp_u)
+ mpq_set (__gmp_w, __gmp_u);
+ __gmp_w->_mp_num._mp_size = __GMP_ABS (__gmp_w->_mp_num._mp_size);
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) && ! defined (__GMP_FORCE_mpq_neg)
+__GMP_EXTERN_INLINE void
+mpq_neg (mpq_ptr __gmp_w, mpq_srcptr __gmp_u)
+{
+ if (__gmp_w != __gmp_u)
+ mpq_set (__gmp_w, __gmp_u);
+ __gmp_w->_mp_num._mp_size = - __gmp_w->_mp_num._mp_size;
+}
+#endif
+
+
+/**************** mpn inlines ****************/
+
+/* The comments with __GMPN_ADD_1 below apply here too.
+
+ The test for FUNCTION returning 0 should predict well. If it's assumed
+ {yp,ysize} will usually have a random number of bits then the high limb
+ won't be full and a carry out will occur a good deal less than 50% of the
+ time.
+
+ ysize==0 isn't a documented feature, but is used internally in a few
+ places.
+
+ Producing cout last stops it using up a register during the main part of
+ the calculation, though gcc (as of 3.0) on an "if (mpn_add (...))"
+ doesn't seem able to move the true and false legs of the conditional up
+ to the two places cout is generated. */
+
+#define __GMPN_AORS(cout, wp, xp, xsize, yp, ysize, FUNCTION, TEST) \
+ do { \
+ mp_size_t __gmp_i; \
+ mp_limb_t __gmp_x; \
+ \
+ /* ASSERT ((ysize) >= 0); */ \
+ /* ASSERT ((xsize) >= (ysize)); */ \
+ /* ASSERT (MPN_SAME_OR_SEPARATE2_P (wp, xsize, xp, xsize)); */ \
+ /* ASSERT (MPN_SAME_OR_SEPARATE2_P (wp, xsize, yp, ysize)); */ \
+ \
+ __gmp_i = (ysize); \
+ if (__gmp_i != 0) \
+ { \
+ if (FUNCTION (wp, xp, yp, __gmp_i)) \
+ { \
+ do \
+ { \
+ if (__gmp_i >= (xsize)) \
+ { \
+ (cout) = 1; \
+ goto __gmp_done; \
+ } \
+ __gmp_x = (xp)[__gmp_i]; \
+ } \
+ while (TEST); \
+ } \
+ } \
+ if ((wp) != (xp)) \
+ __GMPN_COPY_REST (wp, xp, xsize, __gmp_i); \
+ (cout) = 0; \
+ __gmp_done: \
+ ; \
+ } while (0)
+
+#define __GMPN_ADD(cout, wp, xp, xsize, yp, ysize) \
+ __GMPN_AORS (cout, wp, xp, xsize, yp, ysize, mpn_add_n, \
+ (((wp)[__gmp_i++] = (__gmp_x + 1) & GMP_NUMB_MASK) == 0))
+#define __GMPN_SUB(cout, wp, xp, xsize, yp, ysize) \
+ __GMPN_AORS (cout, wp, xp, xsize, yp, ysize, mpn_sub_n, \
+ (((wp)[__gmp_i++] = (__gmp_x - 1) & GMP_NUMB_MASK), __gmp_x == 0))
+
+
+/* The use of __gmp_i indexing is designed to ensure a compile time src==dst
+ remains nice and clear to the compiler, so that __GMPN_COPY_REST can
+ disappear, and the load/add/store gets a chance to become a
+ read-modify-write on CISC CPUs.
+
+ Alternatives:
+
+ Using a pair of pointers instead of indexing would be possible, but gcc
+ isn't able to recognise compile-time src==dst in that case, even when the
+ pointers are incremented more or less together. Other compilers would
+ very likely have similar difficulty.
+
+ gcc could use "if (__builtin_constant_p(src==dst) && src==dst)" or
+ similar to detect a compile-time src==dst. This works nicely on gcc
+ 2.95.x, it's not good on gcc 3.0 where __builtin_constant_p(p==p) seems
+ to be always false, for a pointer p. But the current code form seems
+ good enough for src==dst anyway.
+
+ gcc on x86 as usual doesn't give particularly good flags handling for the
+ carry/borrow detection. It's tempting to want some multi instruction asm
+ blocks to help it, and this was tried, but in truth there's only a few
+ instructions to save and any gain is all too easily lost by register
+ juggling setting up for the asm. */
+
+#if GMP_NAIL_BITS == 0
+#define __GMPN_AORS_1(cout, dst, src, n, v, OP, CB) \
+ do { \
+ mp_size_t __gmp_i; \
+ mp_limb_t __gmp_x, __gmp_r; \
+ \
+ /* ASSERT ((n) >= 1); */ \
+ /* ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, n)); */ \
+ \
+ __gmp_x = (src)[0]; \
+ __gmp_r = __gmp_x OP (v); \
+ (dst)[0] = __gmp_r; \
+ if (CB (__gmp_r, __gmp_x, (v))) \
+ { \
+ (cout) = 1; \
+ for (__gmp_i = 1; __gmp_i < (n);) \
+ { \
+ __gmp_x = (src)[__gmp_i]; \
+ __gmp_r = __gmp_x OP 1; \
+ (dst)[__gmp_i] = __gmp_r; \
+ ++__gmp_i; \
+ if (!CB (__gmp_r, __gmp_x, 1)) \
+ { \
+ if ((src) != (dst)) \
+ __GMPN_COPY_REST (dst, src, n, __gmp_i); \
+ (cout) = 0; \
+ break; \
+ } \
+ } \
+ } \
+ else \
+ { \
+ if ((src) != (dst)) \
+ __GMPN_COPY_REST (dst, src, n, 1); \
+ (cout) = 0; \
+ } \
+ } while (0)
+#endif
+
+#if GMP_NAIL_BITS >= 1
+#define __GMPN_AORS_1(cout, dst, src, n, v, OP, CB) \
+ do { \
+ mp_size_t __gmp_i; \
+ mp_limb_t __gmp_x, __gmp_r; \
+ \
+ /* ASSERT ((n) >= 1); */ \
+ /* ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, n)); */ \
+ \
+ __gmp_x = (src)[0]; \
+ __gmp_r = __gmp_x OP (v); \
+ (dst)[0] = __gmp_r & GMP_NUMB_MASK; \
+ if (__gmp_r >> GMP_NUMB_BITS != 0) \
+ { \
+ (cout) = 1; \
+ for (__gmp_i = 1; __gmp_i < (n);) \
+ { \
+ __gmp_x = (src)[__gmp_i]; \
+ __gmp_r = __gmp_x OP 1; \
+ (dst)[__gmp_i] = __gmp_r & GMP_NUMB_MASK; \
+ ++__gmp_i; \
+ if (__gmp_r >> GMP_NUMB_BITS == 0) \
+ { \
+ if ((src) != (dst)) \
+ __GMPN_COPY_REST (dst, src, n, __gmp_i); \
+ (cout) = 0; \
+ break; \
+ } \
+ } \
+ } \
+ else \
+ { \
+ if ((src) != (dst)) \
+ __GMPN_COPY_REST (dst, src, n, 1); \
+ (cout) = 0; \
+ } \
+ } while (0)
+#endif
+
+#define __GMPN_ADDCB(r,x,y) ((r) < (y))
+#define __GMPN_SUBCB(r,x,y) ((x) < (y))
+
+#define __GMPN_ADD_1(cout, dst, src, n, v) \
+ __GMPN_AORS_1(cout, dst, src, n, v, +, __GMPN_ADDCB)
+#define __GMPN_SUB_1(cout, dst, src, n, v) \
+ __GMPN_AORS_1(cout, dst, src, n, v, -, __GMPN_SUBCB)
+
+
+/* Compare {xp,size} and {yp,size}, setting "result" to positive, zero or
+ negative. size==0 is allowed. On random data usually only one limb will
+ need to be examined to get a result, so it's worth having it inline. */
+#define __GMPN_CMP(result, xp, yp, size) \
+ do { \
+ mp_size_t __gmp_i; \
+ mp_limb_t __gmp_x, __gmp_y; \
+ \
+ /* ASSERT ((size) >= 0); */ \
+ \
+ (result) = 0; \
+ __gmp_i = (size); \
+ while (--__gmp_i >= 0) \
+ { \
+ __gmp_x = (xp)[__gmp_i]; \
+ __gmp_y = (yp)[__gmp_i]; \
+ if (__gmp_x != __gmp_y) \
+ { \
+ /* Cannot use __gmp_x - __gmp_y, may overflow an "int" */ \
+ (result) = (__gmp_x > __gmp_y ? 1 : -1); \
+ break; \
+ } \
+ } \
+ } while (0)
+
+
+#if defined (__GMPN_COPY) && ! defined (__GMPN_COPY_REST)
+#define __GMPN_COPY_REST(dst, src, size, start) \
+ do { \
+ /* ASSERT ((start) >= 0); */ \
+ /* ASSERT ((start) <= (size)); */ \
+ __GMPN_COPY ((dst)+(start), (src)+(start), (size)-(start)); \
+ } while (0)
+#endif
+
+/* Copy {src,size} to {dst,size}, starting at "start". This is designed to
+ keep the indexing dst[j] and src[j] nice and simple for __GMPN_ADD_1,
+ __GMPN_ADD, etc. */
+#if ! defined (__GMPN_COPY_REST)
+#define __GMPN_COPY_REST(dst, src, size, start) \
+ do { \
+ mp_size_t __gmp_j; \
+ /* ASSERT ((size) >= 0); */ \
+ /* ASSERT ((start) >= 0); */ \
+ /* ASSERT ((start) <= (size)); */ \
+ /* ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, size)); */ \
+ __GMP_CRAY_Pragma ("_CRI ivdep"); \
+ for (__gmp_j = (start); __gmp_j < (size); __gmp_j++) \
+ (dst)[__gmp_j] = (src)[__gmp_j]; \
+ } while (0)
+#endif
+
+/* Enhancement: Use some of the smarter code from gmp-impl.h. Maybe use
+ mpn_copyi if there's a native version, and if we don't mind demanding
+ binary compatibility for it (on targets which use it). */
+
+#if ! defined (__GMPN_COPY)
+#define __GMPN_COPY(dst, src, size) __GMPN_COPY_REST (dst, src, size, 0)
+#endif
+
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_add)
+#if ! defined (__GMP_FORCE_mpn_add)
+__GMP_EXTERN_INLINE
+#endif
+mp_limb_t
+mpn_add (mp_ptr __gmp_wp, mp_srcptr __gmp_xp, mp_size_t __gmp_xsize, mp_srcptr __gmp_yp, mp_size_t __gmp_ysize)
+{
+ mp_limb_t __gmp_c;
+ __GMPN_ADD (__gmp_c, __gmp_wp, __gmp_xp, __gmp_xsize, __gmp_yp, __gmp_ysize);
+ return __gmp_c;
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_add_1)
+#if ! defined (__GMP_FORCE_mpn_add_1)
+__GMP_EXTERN_INLINE
+#endif
+mp_limb_t
+mpn_add_1 (mp_ptr __gmp_dst, mp_srcptr __gmp_src, mp_size_t __gmp_size, mp_limb_t __gmp_n) __GMP_NOTHROW
+{
+ mp_limb_t __gmp_c;
+ __GMPN_ADD_1 (__gmp_c, __gmp_dst, __gmp_src, __gmp_size, __gmp_n);
+ return __gmp_c;
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_cmp)
+#if ! defined (__GMP_FORCE_mpn_cmp)
+__GMP_EXTERN_INLINE
+#endif
+int
+mpn_cmp (mp_srcptr __gmp_xp, mp_srcptr __gmp_yp, mp_size_t __gmp_size) __GMP_NOTHROW
+{
+ int __gmp_result;
+ __GMPN_CMP (__gmp_result, __gmp_xp, __gmp_yp, __gmp_size);
+ return __gmp_result;
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_sub)
+#if ! defined (__GMP_FORCE_mpn_sub)
+__GMP_EXTERN_INLINE
+#endif
+mp_limb_t
+mpn_sub (mp_ptr __gmp_wp, mp_srcptr __gmp_xp, mp_size_t __gmp_xsize, mp_srcptr __gmp_yp, mp_size_t __gmp_ysize)
+{
+ mp_limb_t __gmp_c;
+ __GMPN_SUB (__gmp_c, __gmp_wp, __gmp_xp, __gmp_xsize, __gmp_yp, __gmp_ysize);
+ return __gmp_c;
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_sub_1)
+#if ! defined (__GMP_FORCE_mpn_sub_1)
+__GMP_EXTERN_INLINE
+#endif
+mp_limb_t
+mpn_sub_1 (mp_ptr __gmp_dst, mp_srcptr __gmp_src, mp_size_t __gmp_size, mp_limb_t __gmp_n) __GMP_NOTHROW
+{
+ mp_limb_t __gmp_c;
+ __GMPN_SUB_1 (__gmp_c, __gmp_dst, __gmp_src, __gmp_size, __gmp_n);
+ return __gmp_c;
+}
+#endif
+
+#if defined (__GMP_EXTERN_INLINE) || defined (__GMP_FORCE_mpn_neg)
+#if ! defined (__GMP_FORCE_mpn_neg)
+__GMP_EXTERN_INLINE
+#endif
+mp_limb_t
+mpn_neg (mp_ptr __gmp_rp, mp_srcptr __gmp_up, mp_size_t __gmp_n)
+{
+ mp_limb_t __gmp_ul, __gmp_cy;
+ __gmp_cy = 0;
+ do {
+ __gmp_ul = *__gmp_up++;
+ *__gmp_rp++ = -__gmp_ul - __gmp_cy;
+ __gmp_cy |= __gmp_ul != 0;
+ } while (--__gmp_n != 0);
+ return __gmp_cy;
+}
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+
+/* Allow faster testing for negative, zero, and positive. */
+#define mpz_sgn(Z) ((Z)->_mp_size < 0 ? -1 : (Z)->_mp_size > 0)
+#define mpf_sgn(F) ((F)->_mp_size < 0 ? -1 : (F)->_mp_size > 0)
+#define mpq_sgn(Q) ((Q)->_mp_num._mp_size < 0 ? -1 : (Q)->_mp_num._mp_size > 0)
+
+/* When using GCC, optimize certain common comparisons. */
+#if defined (__GNUC__) && __GNUC__ >= 2
+#define mpz_cmp_ui(Z,UI) \
+ (__builtin_constant_p (UI) && (UI) == 0 \
+ ? mpz_sgn (Z) : _mpz_cmp_ui (Z,UI))
+#define mpz_cmp_si(Z,SI) \
+ (__builtin_constant_p ((SI) >= 0) && (SI) >= 0 \
+ ? mpz_cmp_ui (Z, __GMP_CAST (unsigned long, SI)) \
+ : _mpz_cmp_si (Z,SI))
+#define mpq_cmp_ui(Q,NUI,DUI) \
+ (__builtin_constant_p (NUI) && (NUI) == 0 ? mpq_sgn (Q) \
+ : __builtin_constant_p ((NUI) == (DUI)) && (NUI) == (DUI) \
+ ? mpz_cmp (mpq_numref (Q), mpq_denref (Q)) \
+ : _mpq_cmp_ui (Q,NUI,DUI))
+#define mpq_cmp_si(q,n,d) \
+ (__builtin_constant_p ((n) >= 0) && (n) >= 0 \
+ ? mpq_cmp_ui (q, __GMP_CAST (unsigned long, n), d) \
+ : _mpq_cmp_si (q, n, d))
+#else
+#define mpz_cmp_ui(Z,UI) _mpz_cmp_ui (Z,UI)
+#define mpz_cmp_si(Z,UI) _mpz_cmp_si (Z,UI)
+#define mpq_cmp_ui(Q,NUI,DUI) _mpq_cmp_ui (Q,NUI,DUI)
+#define mpq_cmp_si(q,n,d) _mpq_cmp_si(q,n,d)
+#endif
+
+
+/* Using "&" rather than "&&" means these can come out branch-free. Every
+ mpz_t has at least one limb allocated, so fetching the low limb is always
+ allowed. */
+#define mpz_odd_p(z) (((z)->_mp_size != 0) & __GMP_CAST (int, (z)->_mp_d[0]))
+#define mpz_even_p(z) (! mpz_odd_p (z))
+
+
+/**************** C++ routines ****************/
+
+#ifdef __cplusplus
+__GMP_DECLSPEC_XX std::ostream& operator<< (std::ostream &, mpz_srcptr);
+__GMP_DECLSPEC_XX std::ostream& operator<< (std::ostream &, mpq_srcptr);
+__GMP_DECLSPEC_XX std::ostream& operator<< (std::ostream &, mpf_srcptr);
+__GMP_DECLSPEC_XX std::istream& operator>> (std::istream &, mpz_ptr);
+__GMP_DECLSPEC_XX std::istream& operator>> (std::istream &, mpq_ptr);
+__GMP_DECLSPEC_XX std::istream& operator>> (std::istream &, mpf_ptr);
+#endif
+
+
+/* Source-level compatibility with GMP 2 and earlier. */
+#define mpn_divmod(qp,np,nsize,dp,dsize) \
+ mpn_divrem (qp, __GMP_CAST (mp_size_t, 0), np, nsize, dp, dsize)
+
+/* Source-level compatibility with GMP 1. */
+#define mpz_mdiv mpz_fdiv_q
+#define mpz_mdivmod mpz_fdiv_qr
+#define mpz_mmod mpz_fdiv_r
+#define mpz_mdiv_ui mpz_fdiv_q_ui
+#define mpz_mdivmod_ui(q,r,n,d) \
+ (((r) == 0) ? mpz_fdiv_q_ui (q,n,d) : mpz_fdiv_qr_ui (q,r,n,d))
+#define mpz_mmod_ui(r,n,d) \
+ (((r) == 0) ? mpz_fdiv_ui (n,d) : mpz_fdiv_r_ui (r,n,d))
+
+/* Useful synonyms, but not quite compatible with GMP 1. */
+#define mpz_div mpz_fdiv_q
+#define mpz_divmod mpz_fdiv_qr
+#define mpz_div_ui mpz_fdiv_q_ui
+#define mpz_divmod_ui mpz_fdiv_qr_ui
+#define mpz_div_2exp mpz_fdiv_q_2exp
+#define mpz_mod_2exp mpz_fdiv_r_2exp
+
+enum
+{
+ GMP_ERROR_NONE = 0,
+ GMP_ERROR_UNSUPPORTED_ARGUMENT = 1,
+ GMP_ERROR_DIVISION_BY_ZERO = 2,
+ GMP_ERROR_SQRT_OF_NEGATIVE = 4,
+ GMP_ERROR_INVALID_ARGUMENT = 8
+};
+
+/* Define CC and CFLAGS which were used to build this version of GMP */
+#define __GMP_CC "@CC@"
+#define __GMP_CFLAGS "@CFLAGS@"
+
+/* Major version number is the value of __GNU_MP__ too, above and in mp.h. */
+#define __GNU_MP_VERSION 6
+#define __GNU_MP_VERSION_MINOR 0
+#define __GNU_MP_VERSION_PATCHLEVEL 0
+#define __GNU_MP_RELEASE (__GNU_MP_VERSION * 10000 + __GNU_MP_VERSION_MINOR * 100 + __GNU_MP_VERSION_PATCHLEVEL)
+
+#define __GMP_H__
+#endif /* __GMP_H__ */
diff --git a/gmp/gmp-impl.h b/gmp/gmp-impl.h
new file mode 100644
index 0000000000..dc4e084a72
--- /dev/null
+++ b/gmp/gmp-impl.h
@@ -0,0 +1,5203 @@
+/* Include file for internal GNU MP types and definitions.
+
+ THE CONTENTS OF THIS FILE ARE FOR INTERNAL USE AND ARE ALMOST CERTAIN TO
+ BE SUBJECT TO INCOMPATIBLE CHANGES IN FUTURE GNU MP RELEASES.
+
+Copyright 1991, 1993-1997, 1999-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* __GMP_DECLSPEC must be given on any global data that will be accessed
+ from outside libgmp, meaning from the test or development programs, or
+ from libgmpxx. Failing to do this will result in an incorrect address
+ being used for the accesses. On functions __GMP_DECLSPEC makes calls
+ from outside libgmp more efficient, but they'll still work fine without
+ it. */
+
+
+#ifndef __GMP_IMPL_H__
+#define __GMP_IMPL_H__
+
+#if defined _CRAY
+#include <intrinsics.h> /* for _popcnt */
+#endif
+
+/* For INT_MAX, etc. We used to avoid it because of a bug (on solaris,
+ gcc 2.95 under -mcpu=ultrasparc in ABI=32 ends up getting wrong
+ values (the ABI=64 values)), but it should be safe now.
+
+ On Cray vector systems, however, we need the system limits.h since sizes
+ of signed and unsigned types can differ there, depending on compiler
+ options (eg. -hnofastmd), making our SHRT_MAX etc expressions fail. For
+ reference, int can be 46 or 64 bits, whereas uint is always 64 bits; and
+ short can be 24, 32, 46 or 64 bits, and different for ushort. */
+
+#include <limits.h>
+
+/* For fat.h and other fat binary stuff.
+ No need for __GMP_ATTRIBUTE_PURE or __GMP_NOTHROW, since functions
+ declared this way are only used to set function pointers in __gmpn_cpuvec,
+ they're not called directly. */
+#define DECL_add_n(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)
+#define DECL_addlsh1_n(name) \
+ DECL_add_n (name)
+#define DECL_addlsh2_n(name) \
+ DECL_add_n (name)
+#define DECL_addmul_1(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)
+#define DECL_addmul_2(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr)
+#define DECL_bdiv_dbm1c(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t)
+#define DECL_cnd_add_n(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)
+#define DECL_cnd_sub_n(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)
+#define DECL_com(name) \
+ __GMP_DECLSPEC void name (mp_ptr, mp_srcptr, mp_size_t)
+#define DECL_copyd(name) \
+ __GMP_DECLSPEC void name (mp_ptr, mp_srcptr, mp_size_t)
+#define DECL_copyi(name) \
+ DECL_copyd (name)
+#define DECL_divexact_1(name) \
+ __GMP_DECLSPEC void name (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)
+#define DECL_divexact_by3c(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)
+#define DECL_divrem_1(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t)
+#define DECL_gcd_1(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_srcptr, mp_size_t, mp_limb_t)
+#define DECL_lshift(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_srcptr, mp_size_t, unsigned)
+#define DECL_lshiftc(name) \
+ DECL_lshift (name)
+#define DECL_mod_1(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_srcptr, mp_size_t, mp_limb_t)
+#define DECL_mod_1_1p(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_srcptr, mp_size_t, mp_limb_t, const mp_limb_t [])
+#define DECL_mod_1_1p_cps(name) \
+ __GMP_DECLSPEC void name (mp_limb_t cps[], mp_limb_t b)
+#define DECL_mod_1s_2p(name) \
+ DECL_mod_1_1p (name)
+#define DECL_mod_1s_2p_cps(name) \
+ DECL_mod_1_1p_cps (name)
+#define DECL_mod_1s_4p(name) \
+ DECL_mod_1_1p (name)
+#define DECL_mod_1s_4p_cps(name) \
+ DECL_mod_1_1p_cps (name)
+#define DECL_mod_34lsub1(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_srcptr, mp_size_t)
+#define DECL_modexact_1c_odd(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t)
+#define DECL_mul_1(name) \
+ DECL_addmul_1 (name)
+#define DECL_mul_basecase(name) \
+ __GMP_DECLSPEC void name (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t)
+#define DECL_mullo_basecase(name) \
+ __GMP_DECLSPEC void name (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)
+#define DECL_preinv_divrem_1(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, int)
+#define DECL_preinv_mod_1(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t)
+#define DECL_redc_1(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)
+#define DECL_redc_2(name) \
+ __GMP_DECLSPEC mp_limb_t name (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr)
+#define DECL_rshift(name) \
+ DECL_lshift (name)
+#define DECL_sqr_basecase(name) \
+ __GMP_DECLSPEC void name (mp_ptr, mp_srcptr, mp_size_t)
+#define DECL_sub_n(name) \
+ DECL_add_n (name)
+#define DECL_sublsh1_n(name) \
+ DECL_add_n (name)
+#define DECL_submul_1(name) \
+ DECL_addmul_1 (name)
+
+#if ! defined (__GMP_WITHIN_CONFIGURE)
+#include "config.h"
+#include "gmp-mparam.h"
+#include "fib_table.h"
+#include "fac_table.h"
+#include "mp_bases.h"
+#if WANT_FAT_BINARY
+#include "fat.h"
+#endif
+#endif
+
+#if HAVE_INTTYPES_H /* for uint_least32_t */
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+
+#ifdef __cplusplus
+#include <cstring> /* for strlen */
+#include <string> /* for std::string */
+#endif
+
+
+#ifndef WANT_TMP_DEBUG /* for TMP_ALLOC_LIMBS_2 and others */
+#define WANT_TMP_DEBUG 0
+#endif
+
+/* The following tries to get a good version of alloca. The tests are
+ adapted from autoconf AC_FUNC_ALLOCA, with a couple of additions.
+ Whether this succeeds is tested by GMP_FUNC_ALLOCA and HAVE_ALLOCA will
+ be setup appropriately.
+
+ ifndef alloca - a cpp define might already exist.
+ glibc <stdlib.h> includes <alloca.h> which uses GCC __builtin_alloca.
+ HP cc +Olibcalls adds a #define of alloca to __builtin_alloca.
+
+ GCC __builtin_alloca - preferred whenever available.
+
+ _AIX pragma - IBM compilers need a #pragma in "each module that needs to
+ use alloca". Pragma indented to protect pre-ANSI cpp's. _IBMR2 was
+ used in past versions of GMP, retained still in case it matters.
+
+ The autoconf manual says this pragma needs to be at the start of a C
+ file, apart from comments and preprocessor directives. Is that true?
+ xlc on aix 4.xxx doesn't seem to mind it being after prototypes etc
+ from gmp.h.
+*/
+
+#ifndef alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# else
+# ifdef __DECC
+# define alloca(x) __ALLOCA(x)
+# else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# if defined (_AIX) || defined (_IBMR2)
+ #pragma alloca
+# else
+ char *alloca ();
+# endif
+# endif
+# endif
+# endif
+# endif
+#endif
+
+
+/* if not provided by gmp-mparam.h */
+#ifndef GMP_LIMB_BYTES
+#define GMP_LIMB_BYTES SIZEOF_MP_LIMB_T
+#endif
+#ifndef GMP_LIMB_BITS
+#define GMP_LIMB_BITS (8 * SIZEOF_MP_LIMB_T)
+#endif
+
+#define BITS_PER_ULONG (8 * SIZEOF_UNSIGNED_LONG)
+
+
+/* gmp_uint_least32_t is an unsigned integer type with at least 32 bits. */
+#if HAVE_UINT_LEAST32_T
+typedef uint_least32_t gmp_uint_least32_t;
+#else
+#if SIZEOF_UNSIGNED_SHORT >= 4
+typedef unsigned short gmp_uint_least32_t;
+#else
+#if SIZEOF_UNSIGNED >= 4
+typedef unsigned gmp_uint_least32_t;
+#else
+typedef unsigned long gmp_uint_least32_t;
+#endif
+#endif
+#endif
+
+
+/* gmp_intptr_t, for pointer to integer casts */
+#if HAVE_INTPTR_T
+typedef intptr_t gmp_intptr_t;
+#else /* fallback */
+typedef size_t gmp_intptr_t;
+#endif
+
+
+/* pre-inverse types for truncating division and modulo */
+typedef struct {mp_limb_t inv32;} gmp_pi1_t;
+typedef struct {mp_limb_t inv21, inv32, inv53;} gmp_pi2_t;
+
+
+/* "const" basically means a function does nothing but examine its arguments
+ and give a return value, it doesn't read or write any memory (neither
+ global nor pointed to by arguments), and has no other side-effects. This
+ is more restrictive than "pure". See info node "(gcc)Function
+ Attributes". __GMP_NO_ATTRIBUTE_CONST_PURE lets tune/common.c etc turn
+ this off when trying to write timing loops. */
+#if HAVE_ATTRIBUTE_CONST && ! defined (__GMP_NO_ATTRIBUTE_CONST_PURE)
+#define ATTRIBUTE_CONST __attribute__ ((const))
+#else
+#define ATTRIBUTE_CONST
+#endif
+
+#if HAVE_ATTRIBUTE_NORETURN
+#define ATTRIBUTE_NORETURN __attribute__ ((noreturn))
+#else
+#define ATTRIBUTE_NORETURN
+#endif
+
+/* "malloc" means a function behaves like malloc in that the pointer it
+ returns doesn't alias anything. */
+#if HAVE_ATTRIBUTE_MALLOC
+#define ATTRIBUTE_MALLOC __attribute__ ((malloc))
+#else
+#define ATTRIBUTE_MALLOC
+#endif
+
+
+#if ! HAVE_STRCHR
+#define strchr(s,c) index(s,c)
+#endif
+
+#if ! HAVE_MEMSET
+#define memset(p, c, n) \
+ do { \
+ ASSERT ((n) >= 0); \
+ char *__memset__p = (p); \
+ int __i; \
+ for (__i = 0; __i < (n); __i++) \
+ __memset__p[__i] = (c); \
+ } while (0)
+#endif
+
+/* va_copy is standard in C99, and gcc provides __va_copy when in strict C89
+ mode. Falling back to a memcpy will give maximum portability, since it
+ works no matter whether va_list is a pointer, struct or array. */
+#if ! defined (va_copy) && defined (__va_copy)
+#define va_copy(dst,src) __va_copy(dst,src)
+#endif
+#if ! defined (va_copy)
+#define va_copy(dst,src) \
+ do { memcpy (&(dst), &(src), sizeof (va_list)); } while (0)
+#endif
+
+
+/* HAVE_HOST_CPU_alpha_CIX is 1 on an alpha with the CIX instructions
+ (ie. ctlz, ctpop, cttz). */
+#if HAVE_HOST_CPU_alphaev67 || HAVE_HOST_CPU_alphaev68 \
+ || HAVE_HOST_CPU_alphaev7
+#define HAVE_HOST_CPU_alpha_CIX 1
+#endif
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* Usage: TMP_DECL;
+ TMP_MARK;
+ ptr = TMP_ALLOC (bytes);
+ TMP_FREE;
+
+ Small allocations should use TMP_SALLOC, big allocations should use
+ TMP_BALLOC. Allocations that might be small or big should use TMP_ALLOC.
+
+ Functions that use just TMP_SALLOC should use TMP_SDECL, TMP_SMARK, and
+ TMP_SFREE.
+
+ TMP_DECL just declares a variable, but might be empty and so must be last
+ in a list of variables. TMP_MARK must be done before any TMP_ALLOC.
+ TMP_ALLOC(0) is not allowed. TMP_FREE doesn't need to be done if a
+ TMP_MARK was made, but then no TMP_ALLOCs. */
+
+/* The alignment in bytes, used for TMP_ALLOCed blocks, when alloca or
+ __gmp_allocate_func doesn't already determine it. Currently TMP_ALLOC
+ isn't used for "double"s, so that's not in the union. */
+union tmp_align_t {
+ mp_limb_t l;
+ char *p;
+};
+#define __TMP_ALIGN sizeof (union tmp_align_t)
+
+/* Return "a" rounded upwards to a multiple of "m", if it isn't already.
+ "a" must be an unsigned type.
+ This is designed for use with a compile-time constant "m".
+ The POW2 case is expected to be usual, and gcc 3.0 and up recognises
+ "(-(8*n))%8" or the like is always zero, which means the rounding up in
+ the WANT_TMP_NOTREENTRANT version of TMP_ALLOC below will be a noop. */
+#define ROUND_UP_MULTIPLE(a,m) \
+ (POW2_P(m) ? (a) + (-(a))%(m) \
+ : (a)+(m)-1 - (((a)+(m)-1) % (m)))
+
+#if defined (WANT_TMP_ALLOCA) || defined (WANT_TMP_REENTRANT)
+struct tmp_reentrant_t {
+ struct tmp_reentrant_t *next;
+ size_t size; /* bytes, including header */
+};
+__GMP_DECLSPEC void *__gmp_tmp_reentrant_alloc (struct tmp_reentrant_t **, size_t) ATTRIBUTE_MALLOC;
+__GMP_DECLSPEC void __gmp_tmp_reentrant_free (struct tmp_reentrant_t *);
+#endif
+
+#if WANT_TMP_ALLOCA
+#define TMP_SDECL
+#define TMP_DECL struct tmp_reentrant_t *__tmp_marker
+#define TMP_SMARK
+#define TMP_MARK __tmp_marker = 0
+#define TMP_SALLOC(n) alloca(n)
+#define TMP_BALLOC(n) __gmp_tmp_reentrant_alloc (&__tmp_marker, n)
+#define TMP_ALLOC(n) \
+ (LIKELY ((n) < 65536) ? TMP_SALLOC(n) : TMP_BALLOC(n))
+#define TMP_SFREE
+#define TMP_FREE \
+ do { \
+ if (UNLIKELY (__tmp_marker != 0)) \
+ __gmp_tmp_reentrant_free (__tmp_marker); \
+ } while (0)
+#endif
+
+#if WANT_TMP_REENTRANT
+#define TMP_SDECL TMP_DECL
+#define TMP_DECL struct tmp_reentrant_t *__tmp_marker
+#define TMP_SMARK TMP_MARK
+#define TMP_MARK __tmp_marker = 0
+#define TMP_SALLOC(n) TMP_ALLOC(n)
+#define TMP_BALLOC(n) TMP_ALLOC(n)
+#define TMP_ALLOC(n) __gmp_tmp_reentrant_alloc (&__tmp_marker, n)
+#define TMP_SFREE TMP_FREE
+#define TMP_FREE __gmp_tmp_reentrant_free (__tmp_marker)
+#endif
+
+#if WANT_TMP_NOTREENTRANT
+struct tmp_marker
+{
+ struct tmp_stack *which_chunk;
+ void *alloc_point;
+};
+__GMP_DECLSPEC void *__gmp_tmp_alloc (unsigned long) ATTRIBUTE_MALLOC;
+__GMP_DECLSPEC void __gmp_tmp_mark (struct tmp_marker *);
+__GMP_DECLSPEC void __gmp_tmp_free (struct tmp_marker *);
+#define TMP_SDECL TMP_DECL
+#define TMP_DECL struct tmp_marker __tmp_marker
+#define TMP_SMARK TMP_MARK
+#define TMP_MARK __gmp_tmp_mark (&__tmp_marker)
+#define TMP_SALLOC(n) TMP_ALLOC(n)
+#define TMP_BALLOC(n) TMP_ALLOC(n)
+#define TMP_ALLOC(n) \
+ __gmp_tmp_alloc (ROUND_UP_MULTIPLE ((unsigned long) (n), __TMP_ALIGN))
+#define TMP_SFREE TMP_FREE
+#define TMP_FREE __gmp_tmp_free (&__tmp_marker)
+#endif
+
+#if WANT_TMP_DEBUG
+/* See tal-debug.c for some comments. */
+struct tmp_debug_t {
+ struct tmp_debug_entry_t *list;
+ const char *file;
+ int line;
+};
+struct tmp_debug_entry_t {
+ struct tmp_debug_entry_t *next;
+ char *block;
+ size_t size;
+};
+__GMP_DECLSPEC void __gmp_tmp_debug_mark (const char *, int, struct tmp_debug_t **,
+ struct tmp_debug_t *,
+ const char *, const char *);
+__GMP_DECLSPEC void *__gmp_tmp_debug_alloc (const char *, int, int,
+ struct tmp_debug_t **, const char *,
+ size_t) ATTRIBUTE_MALLOC;
+__GMP_DECLSPEC void __gmp_tmp_debug_free (const char *, int, int,
+ struct tmp_debug_t **,
+ const char *, const char *);
+#define TMP_SDECL TMP_DECL_NAME(__tmp_xmarker, "__tmp_marker")
+#define TMP_DECL TMP_DECL_NAME(__tmp_xmarker, "__tmp_marker")
+#define TMP_SMARK TMP_MARK_NAME(__tmp_xmarker, "__tmp_marker")
+#define TMP_MARK TMP_MARK_NAME(__tmp_xmarker, "__tmp_marker")
+#define TMP_SFREE TMP_FREE_NAME(__tmp_xmarker, "__tmp_marker")
+#define TMP_FREE TMP_FREE_NAME(__tmp_xmarker, "__tmp_marker")
+/* The marker variable is designed to provoke an uninitialized variable
+ warning from the compiler if TMP_FREE is used without a TMP_MARK.
+ __tmp_marker_inscope does the same for TMP_ALLOC. Runtime tests pick
+ these things up too. */
+#define TMP_DECL_NAME(marker, marker_name) \
+ int marker; \
+ int __tmp_marker_inscope; \
+ const char *__tmp_marker_name = marker_name; \
+ struct tmp_debug_t __tmp_marker_struct; \
+ /* don't demand NULL, just cast a zero */ \
+ struct tmp_debug_t *__tmp_marker = (struct tmp_debug_t *) 0
+#define TMP_MARK_NAME(marker, marker_name) \
+ do { \
+ marker = 1; \
+ __tmp_marker_inscope = 1; \
+ __gmp_tmp_debug_mark (ASSERT_FILE, ASSERT_LINE, \
+ &__tmp_marker, &__tmp_marker_struct, \
+ __tmp_marker_name, marker_name); \
+ } while (0)
+#define TMP_SALLOC(n) TMP_ALLOC(n)
+#define TMP_BALLOC(n) TMP_ALLOC(n)
+#define TMP_ALLOC(size) \
+ __gmp_tmp_debug_alloc (ASSERT_FILE, ASSERT_LINE, \
+ __tmp_marker_inscope, \
+ &__tmp_marker, __tmp_marker_name, size)
+#define TMP_FREE_NAME(marker, marker_name) \
+ do { \
+ __gmp_tmp_debug_free (ASSERT_FILE, ASSERT_LINE, \
+ marker, &__tmp_marker, \
+ __tmp_marker_name, marker_name); \
+ } while (0)
+#endif /* WANT_TMP_DEBUG */
+
+
+/* Allocating various types. */
+#define TMP_ALLOC_TYPE(n,type) ((type *) TMP_ALLOC ((n) * sizeof (type)))
+#define TMP_SALLOC_TYPE(n,type) ((type *) TMP_SALLOC ((n) * sizeof (type)))
+#define TMP_BALLOC_TYPE(n,type) ((type *) TMP_BALLOC ((n) * sizeof (type)))
+#define TMP_ALLOC_LIMBS(n) TMP_ALLOC_TYPE(n,mp_limb_t)
+#define TMP_SALLOC_LIMBS(n) TMP_SALLOC_TYPE(n,mp_limb_t)
+#define TMP_BALLOC_LIMBS(n) TMP_BALLOC_TYPE(n,mp_limb_t)
+#define TMP_ALLOC_MP_PTRS(n) TMP_ALLOC_TYPE(n,mp_ptr)
+#define TMP_SALLOC_MP_PTRS(n) TMP_SALLOC_TYPE(n,mp_ptr)
+#define TMP_BALLOC_MP_PTRS(n) TMP_BALLOC_TYPE(n,mp_ptr)
+
+/* It's more efficient to allocate one block than two. This is certainly
+ true of the malloc methods, but it can even be true of alloca if that
+ involves copying a chunk of stack (various RISCs), or a call to a stack
+ bounds check (mingw). In any case, when debugging keep separate blocks
+ so a redzoning malloc debugger can protect each individually. */
+#define TMP_ALLOC_LIMBS_2(xp,xsize, yp,ysize) \
+ do { \
+ if (WANT_TMP_DEBUG) \
+ { \
+ (xp) = TMP_ALLOC_LIMBS (xsize); \
+ (yp) = TMP_ALLOC_LIMBS (ysize); \
+ } \
+ else \
+ { \
+ (xp) = TMP_ALLOC_LIMBS ((xsize) + (ysize)); \
+ (yp) = (xp) + (xsize); \
+ } \
+ } while (0)
+
+
+/* From gmp.h, nicer names for internal use. */
+#define CRAY_Pragma(str) __GMP_CRAY_Pragma(str)
+#define MPN_CMP(result, xp, yp, size) __GMPN_CMP(result, xp, yp, size)
+#define LIKELY(cond) __GMP_LIKELY(cond)
+#define UNLIKELY(cond) __GMP_UNLIKELY(cond)
+
+#define ABS(x) ((x) >= 0 ? (x) : -(x))
+#define NEG_CAST(T,x) (- (__GMP_CAST (T, (x) + 1) - 1))
+#define ABS_CAST(T,x) ((x) >= 0 ? __GMP_CAST (T, x) : NEG_CAST (T,x))
+#undef MIN
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#undef MAX
+#define MAX(h,i) ((h) > (i) ? (h) : (i))
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+
+/* Field access macros. */
+#define SIZ(x) ((x)->_mp_size)
+#define ABSIZ(x) ABS (SIZ (x))
+#define PTR(x) ((x)->_mp_d)
+#define EXP(x) ((x)->_mp_exp)
+#define PREC(x) ((x)->_mp_prec)
+#define ALLOC(x) ((x)->_mp_alloc)
+#define NUM(x) mpq_numref(x)
+#define DEN(x) mpq_denref(x)
+
+/* n-1 inverts any low zeros and the lowest one bit. If n&(n-1) leaves zero
+ then that lowest one bit must have been the only bit set. n==0 will
+ return true though, so avoid that. */
+#define POW2_P(n) (((n) & ((n) - 1)) == 0)
+
+/* This is intended for constant THRESHOLDs only, where the compiler
+ can completely fold the result. */
+#define LOG2C(n) \
+ (((n) >= 0x1) + ((n) >= 0x2) + ((n) >= 0x4) + ((n) >= 0x8) + \
+ ((n) >= 0x10) + ((n) >= 0x20) + ((n) >= 0x40) + ((n) >= 0x80) + \
+ ((n) >= 0x100) + ((n) >= 0x200) + ((n) >= 0x400) + ((n) >= 0x800) + \
+ ((n) >= 0x1000) + ((n) >= 0x2000) + ((n) >= 0x4000) + ((n) >= 0x8000))
+
+/* The "short" defines are a bit different because shorts are promoted to
+ ints by ~ or >> etc.
+
+ #ifndef's are used since on some systems (HP?) header files other than
+ limits.h setup these defines. We could forcibly #undef in that case, but
+ there seems no need to worry about that.
+
+ Now that we include <limits.h> we should be able to remove all this. */
+
+#ifndef ULONG_MAX
+#define ULONG_MAX __GMP_ULONG_MAX
+#endif
+#ifndef UINT_MAX
+#define UINT_MAX __GMP_UINT_MAX
+#endif
+#ifndef USHRT_MAX
+#define USHRT_MAX __GMP_USHRT_MAX
+#endif
+#define MP_LIMB_T_MAX (~ (mp_limb_t) 0)
+
+/* Must cast ULONG_MAX etc to unsigned long etc, since they might not be
+ unsigned on a K&R compiler. In particular the HP-UX 10 bundled K&R cc
+ treats the plain decimal values in <limits.h> as signed. */
+#define ULONG_HIGHBIT (ULONG_MAX ^ ((unsigned long) ULONG_MAX >> 1))
+#define UINT_HIGHBIT (UINT_MAX ^ ((unsigned) UINT_MAX >> 1))
+#define USHRT_HIGHBIT (USHRT_MAX ^ ((unsigned short) USHRT_MAX >> 1))
+#define GMP_LIMB_HIGHBIT (MP_LIMB_T_MAX ^ (MP_LIMB_T_MAX >> 1))
+
+#ifndef LONG_MIN
+#define LONG_MIN ((long) ULONG_HIGHBIT)
+#endif
+#ifndef LONG_MAX
+#define LONG_MAX (-(LONG_MIN+1))
+#endif
+
+#ifndef INT_MIN
+#define INT_MIN ((int) UINT_HIGHBIT)
+#endif
+#ifndef INT_MAX
+#define INT_MAX (-(INT_MIN+1))
+#endif
+
+#ifndef SHRT_MIN
+#define SHRT_MIN ((int) (short) USHRT_HIGHBIT)
+#endif
+#ifndef SHRT_MAX
+#define SHRT_MAX (-(SHRT_MIN+1))
+#endif
+
+#if __GMP_MP_SIZE_T_INT
+#define MP_SIZE_T_MAX INT_MAX
+#define MP_SIZE_T_MIN INT_MIN
+#else
+#define MP_SIZE_T_MAX LONG_MAX
+#define MP_SIZE_T_MIN LONG_MIN
+#endif
+
+/* mp_exp_t is the same as mp_size_t */
+#define MP_EXP_T_MAX MP_SIZE_T_MAX
+#define MP_EXP_T_MIN MP_SIZE_T_MIN
+
+#define LONG_HIGHBIT LONG_MIN
+#define INT_HIGHBIT INT_MIN
+#define SHRT_HIGHBIT SHRT_MIN
+
+
+#define GMP_NUMB_HIGHBIT (CNST_LIMB(1) << (GMP_NUMB_BITS-1))
+
+#if GMP_NAIL_BITS == 0
+#define GMP_NAIL_LOWBIT CNST_LIMB(0)
+#else
+#define GMP_NAIL_LOWBIT (CNST_LIMB(1) << GMP_NUMB_BITS)
+#endif
+
+#if GMP_NAIL_BITS != 0
+/* Set various *_THRESHOLD values to be used for nails. Thus we avoid using
+ code that has not yet been qualified. */
+
+#undef DC_DIV_QR_THRESHOLD
+#define DC_DIV_QR_THRESHOLD 50
+
+#undef DIVREM_1_NORM_THRESHOLD
+#undef DIVREM_1_UNNORM_THRESHOLD
+#undef MOD_1_NORM_THRESHOLD
+#undef MOD_1_UNNORM_THRESHOLD
+#undef USE_PREINV_DIVREM_1
+#undef DIVREM_2_THRESHOLD
+#undef DIVEXACT_1_THRESHOLD
+#define DIVREM_1_NORM_THRESHOLD MP_SIZE_T_MAX /* no preinv */
+#define DIVREM_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* no preinv */
+#define MOD_1_NORM_THRESHOLD MP_SIZE_T_MAX /* no preinv */
+#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* no preinv */
+#define USE_PREINV_DIVREM_1 0 /* no preinv */
+#define DIVREM_2_THRESHOLD MP_SIZE_T_MAX /* no preinv */
+
+/* mpn/generic/mul_fft.c is not nails-capable. */
+#undef MUL_FFT_THRESHOLD
+#undef SQR_FFT_THRESHOLD
+#define MUL_FFT_THRESHOLD MP_SIZE_T_MAX
+#define SQR_FFT_THRESHOLD MP_SIZE_T_MAX
+#endif
+
+/* Swap macros. */
+
+#define MP_LIMB_T_SWAP(x, y) \
+ do { \
+ mp_limb_t __mp_limb_t_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mp_limb_t_swap__tmp; \
+ } while (0)
+#define MP_SIZE_T_SWAP(x, y) \
+ do { \
+ mp_size_t __mp_size_t_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mp_size_t_swap__tmp; \
+ } while (0)
+
+#define MP_PTR_SWAP(x, y) \
+ do { \
+ mp_ptr __mp_ptr_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mp_ptr_swap__tmp; \
+ } while (0)
+#define MP_SRCPTR_SWAP(x, y) \
+ do { \
+ mp_srcptr __mp_srcptr_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mp_srcptr_swap__tmp; \
+ } while (0)
+
+#define MPN_PTR_SWAP(xp,xs, yp,ys) \
+ do { \
+ MP_PTR_SWAP (xp, yp); \
+ MP_SIZE_T_SWAP (xs, ys); \
+ } while(0)
+#define MPN_SRCPTR_SWAP(xp,xs, yp,ys) \
+ do { \
+ MP_SRCPTR_SWAP (xp, yp); \
+ MP_SIZE_T_SWAP (xs, ys); \
+ } while(0)
+
+#define MPZ_PTR_SWAP(x, y) \
+ do { \
+ mpz_ptr __mpz_ptr_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mpz_ptr_swap__tmp; \
+ } while (0)
+#define MPZ_SRCPTR_SWAP(x, y) \
+ do { \
+ mpz_srcptr __mpz_srcptr_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mpz_srcptr_swap__tmp; \
+ } while (0)
+
+
+/* Enhancement: __gmp_allocate_func could have "__attribute__ ((malloc))",
+ but current gcc (3.0) doesn't seem to support that. */
+__GMP_DECLSPEC extern void * (*__gmp_allocate_func) (size_t);
+__GMP_DECLSPEC extern void * (*__gmp_reallocate_func) (void *, size_t, size_t);
+__GMP_DECLSPEC extern void (*__gmp_free_func) (void *, size_t);
+
+__GMP_DECLSPEC void *__gmp_default_allocate (size_t);
+__GMP_DECLSPEC void *__gmp_default_reallocate (void *, size_t, size_t);
+__GMP_DECLSPEC void __gmp_default_free (void *, size_t);
+
+#define __GMP_ALLOCATE_FUNC_TYPE(n,type) \
+ ((type *) (*__gmp_allocate_func) ((n) * sizeof (type)))
+#define __GMP_ALLOCATE_FUNC_LIMBS(n) __GMP_ALLOCATE_FUNC_TYPE (n, mp_limb_t)
+
+#define __GMP_REALLOCATE_FUNC_TYPE(p, old_size, new_size, type) \
+ ((type *) (*__gmp_reallocate_func) \
+ (p, (old_size) * sizeof (type), (new_size) * sizeof (type)))
+#define __GMP_REALLOCATE_FUNC_LIMBS(p, old_size, new_size) \
+ __GMP_REALLOCATE_FUNC_TYPE(p, old_size, new_size, mp_limb_t)
+
+#define __GMP_FREE_FUNC_TYPE(p,n,type) (*__gmp_free_func) (p, (n) * sizeof (type))
+#define __GMP_FREE_FUNC_LIMBS(p,n) __GMP_FREE_FUNC_TYPE (p, n, mp_limb_t)
+
+#define __GMP_REALLOCATE_FUNC_MAYBE(ptr, oldsize, newsize) \
+ do { \
+ if ((oldsize) != (newsize)) \
+ (ptr) = (*__gmp_reallocate_func) (ptr, oldsize, newsize); \
+ } while (0)
+
+#define __GMP_REALLOCATE_FUNC_MAYBE_TYPE(ptr, oldsize, newsize, type) \
+ do { \
+ if ((oldsize) != (newsize)) \
+ (ptr) = (type *) (*__gmp_reallocate_func) \
+ (ptr, (oldsize) * sizeof (type), (newsize) * sizeof (type)); \
+ } while (0)
+
+
+/* Dummy for non-gcc, code involving it will go dead. */
+#if ! defined (__GNUC__) || __GNUC__ < 2
+#define __builtin_constant_p(x) 0
+#endif
+
+
+/* In gcc 2.96 and up on i386, tail calls are optimized to jumps if the
+ stack usage is compatible. __attribute__ ((regparm (N))) helps by
+ putting leading parameters in registers, avoiding extra stack.
+
+ regparm cannot be used with calls going through the PLT, because the
+ binding code there may clobber the registers (%eax, %edx, %ecx) used for
+ the regparm parameters. Calls to local (ie. static) functions could
+ still use this, if we cared to differentiate locals and globals.
+
+ On athlon-unknown-freebsd4.9 with gcc 3.3.3, regparm cannot be used with
+ -p or -pg profiling, since that version of gcc doesn't realize the
+ .mcount calls will clobber the parameter registers. Other systems are
+ ok, like debian with glibc 2.3.2 (mcount doesn't clobber), but we don't
+ bother to try to detect this. regparm is only an optimization so we just
+ disable it when profiling (profiling being a slowdown anyway). */
+
+#if HAVE_HOST_CPU_FAMILY_x86 && __GMP_GNUC_PREREQ (2,96) && ! defined (PIC) \
+ && ! WANT_PROFILING_PROF && ! WANT_PROFILING_GPROF
+#define USE_LEADING_REGPARM 1
+#else
+#define USE_LEADING_REGPARM 0
+#endif
+
+/* Macros for altering parameter order according to regparm usage. */
+#if USE_LEADING_REGPARM
+#define REGPARM_2_1(a,b,x) x,a,b
+#define REGPARM_3_1(a,b,c,x) x,a,b,c
+#define REGPARM_ATTR(n) __attribute__ ((regparm (n)))
+#else
+#define REGPARM_2_1(a,b,x) a,b,x
+#define REGPARM_3_1(a,b,c,x) a,b,c,x
+#define REGPARM_ATTR(n)
+#endif
+
+
+/* ASM_L gives a local label for a gcc asm block, for use when temporary
+ local labels like "1:" might not be available, which is the case for
+ instance on the x86s (the SCO assembler doesn't support them).
+
+ The label generated is made unique by including "%=" which is a unique
+ number for each insn. This ensures the same name can be used in multiple
+ asm blocks, perhaps via a macro. Since jumps between asm blocks are not
+ allowed there's no need for a label to be usable outside a single
+ block. */
+
+#define ASM_L(name) LSYM_PREFIX "asm_%=_" #name
+
+
+#if defined (__GNUC__) && HAVE_HOST_CPU_FAMILY_x86
+#if 0
+/* FIXME: Check that these actually improve things.
+ FIXME: Need a cld after each std.
+ FIXME: Can't have inputs in clobbered registers, must describe them as
+ dummy outputs, and add volatile. */
+#define MPN_COPY_INCR(DST, SRC, N) \
+ __asm__ ("cld\n\trep\n\tmovsl" : : \
+ "D" (DST), "S" (SRC), "c" (N) : \
+ "cx", "di", "si", "memory")
+#define MPN_COPY_DECR(DST, SRC, N) \
+ __asm__ ("std\n\trep\n\tmovsl" : : \
+ "D" ((DST) + (N) - 1), "S" ((SRC) + (N) - 1), "c" (N) : \
+ "cx", "di", "si", "memory")
+#endif
+#endif
+
+
+__GMP_DECLSPEC void __gmpz_aorsmul_1 (REGPARM_3_1 (mpz_ptr, mpz_srcptr, mp_limb_t, mp_size_t)) REGPARM_ATTR(1);
+#define mpz_aorsmul_1(w,u,v,sub) __gmpz_aorsmul_1 (REGPARM_3_1 (w, u, v, sub))
+
+#define mpz_n_pow_ui __gmpz_n_pow_ui
+__GMP_DECLSPEC void mpz_n_pow_ui (mpz_ptr, mp_srcptr, mp_size_t, unsigned long);
+
+
+#define mpn_addmul_1c __MPN(addmul_1c)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_1c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+
+#ifndef mpn_addmul_2 /* if not done with cpuvec in a fat binary */
+#define mpn_addmul_2 __MPN(addmul_2)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_2 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+#endif
+
+#define mpn_addmul_3 __MPN(addmul_3)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_3 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_addmul_4 __MPN(addmul_4)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_4 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_addmul_5 __MPN(addmul_5)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_5 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_addmul_6 __MPN(addmul_6)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_6 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_addmul_7 __MPN(addmul_7)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_7 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_addmul_8 __MPN(addmul_8)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_8 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+/* Alternative entry point in mpn_addmul_2 for the benefit of mpn_sqr_basecase. */
+#define mpn_addmul_2s __MPN(addmul_2s)
+__GMP_DECLSPEC mp_limb_t mpn_addmul_2s (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+/* mpn_addlsh1_n(c,a,b,n), when it exists, sets {c,n} to {a,n}+2*{b,n}, and
+ returns the carry out (0, 1 or 2). Use _ip1 when a=c. */
+#ifndef mpn_addlsh1_n /* if not done with cpuvec in a fat binary */
+#define mpn_addlsh1_n __MPN(addlsh1_n)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#endif
+#define mpn_addlsh1_nc __MPN(addlsh1_nc)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh1_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+#if HAVE_NATIVE_mpn_addlsh1_n && ! HAVE_NATIVE_mpn_addlsh1_n_ip1
+#define mpn_addlsh1_n_ip1(dst,src,n) mpn_addlsh1_n(dst,dst,src,n)
+#define HAVE_NATIVE_mpn_addlsh1_n_ip1 1
+#else
+#define mpn_addlsh1_n_ip1 __MPN(addlsh1_n_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh1_n_ip1 (mp_ptr, mp_srcptr, mp_size_t);
+#endif
+#if HAVE_NATIVE_mpn_addlsh1_nc && ! HAVE_NATIVE_mpn_addlsh1_nc_ip1
+#define mpn_addlsh1_nc_ip1(dst,src,n,c) mpn_addlsh1_nc(dst,dst,src,n,c)
+#define HAVE_NATIVE_mpn_addlsh1_nc_ip1 1
+#else
+#define mpn_addlsh1_nc_ip1 __MPN(addlsh1_nc_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh1_nc_ip1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+#endif
+
+#ifndef mpn_addlsh2_n /* if not done with cpuvec in a fat binary */
+/* mpn_addlsh2_n(c,a,b,n), when it exists, sets {c,n} to {a,n}+4*{b,n}, and
+ returns the carry out (0, ..., 4). Use _ip1 when a=c. */
+#define mpn_addlsh2_n __MPN(addlsh2_n)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#endif
+#define mpn_addlsh2_nc __MPN(addlsh2_nc)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh2_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+#if HAVE_NATIVE_mpn_addlsh2_n && ! HAVE_NATIVE_mpn_addlsh2_n_ip1
+#define mpn_addlsh2_n_ip1(dst,src,n) mpn_addlsh2_n(dst,dst,src,n)
+#define HAVE_NATIVE_mpn_addlsh2_n_ip1 1
+#else
+#define mpn_addlsh2_n_ip1 __MPN(addlsh2_n_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh2_n_ip1 (mp_ptr, mp_srcptr, mp_size_t);
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_nc && ! HAVE_NATIVE_mpn_addlsh2_nc_ip1
+#define mpn_addlsh2_nc_ip1(dst,src,n,c) mpn_addlsh2_nc(dst,dst,src,n,c)
+#define HAVE_NATIVE_mpn_addlsh2_nc_ip1 1
+#else
+#define mpn_addlsh2_nc_ip1 __MPN(addlsh2_nc_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh2_nc_ip1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+#endif
+
+/* mpn_addlsh_n(c,a,b,n,k), when it exists, sets {c,n} to {a,n}+2^k*{b,n}, and
+ returns the carry out (0, ..., 2^k). Use _ip1 when a=c. */
+#define mpn_addlsh_n __MPN(addlsh_n)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned int);
+#define mpn_addlsh_nc __MPN(addlsh_nc)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned int, mp_limb_t);
+#if HAVE_NATIVE_mpn_addlsh_n && ! HAVE_NATIVE_mpn_addlsh_n_ip1
+#define mpn_addlsh_n_ip1(dst,src,n,s) mpn_addlsh_n(dst,dst,src,n,s)
+#define HAVE_NATIVE_mpn_addlsh_n_ip1 1
+#else
+#define mpn_addlsh_n_ip1 __MPN(addlsh_n_ip1)
+ __GMP_DECLSPEC mp_limb_t mpn_addlsh_n_ip1 (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
+#endif
+#if HAVE_NATIVE_mpn_addlsh_nc && ! HAVE_NATIVE_mpn_addlsh_nc_ip1
+#define mpn_addlsh_nc_ip1(dst,src,n,s,c) mpn_addlsh_nc(dst,dst,src,n,s,c)
+#define HAVE_NATIVE_mpn_addlsh_nc_ip1 1
+#else
+#define mpn_addlsh_nc_ip1 __MPN(addlsh_nc_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_addlsh_nc_ip1 (mp_ptr, mp_srcptr, mp_size_t, unsigned int, mp_limb_t);
+#endif
+
+#ifndef mpn_sublsh1_n /* if not done with cpuvec in a fat binary */
+/* mpn_sublsh1_n(c,a,b,n), when it exists, sets {c,n} to {a,n}-2*{b,n}, and
+ returns the borrow out (0, 1 or 2). Use _ip1 when a=c. */
+#define mpn_sublsh1_n __MPN(sublsh1_n)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#endif
+#define mpn_sublsh1_nc __MPN(sublsh1_nc)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh1_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+#if HAVE_NATIVE_mpn_sublsh1_n && ! HAVE_NATIVE_mpn_sublsh1_n_ip1
+#define mpn_sublsh1_n_ip1(dst,src,n) mpn_sublsh1_n(dst,dst,src,n)
+#define HAVE_NATIVE_mpn_sublsh1_n_ip1 1
+#else
+#define mpn_sublsh1_n_ip1 __MPN(sublsh1_n_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh1_n_ip1 (mp_ptr, mp_srcptr, mp_size_t);
+#endif
+#if HAVE_NATIVE_mpn_sublsh1_nc && ! HAVE_NATIVE_mpn_sublsh1_nc_ip1
+#define mpn_sublsh1_nc_ip1(dst,src,n,c) mpn_sublsh1_nc(dst,dst,src,n,c)
+#define HAVE_NATIVE_mpn_sublsh1_nc_ip1 1
+#else
+#define mpn_sublsh1_nc_ip1 __MPN(sublsh1_nc_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh1_nc_ip1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+#endif
+
+/* mpn_rsblsh1_n(c,a,b,n), when it exists, sets {c,n} to 2*{b,n}-{a,n}, and
+ returns the carry out (-1, 0, 1). */
+#define mpn_rsblsh1_n __MPN(rsblsh1_n)
+__GMP_DECLSPEC mp_limb_signed_t mpn_rsblsh1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_rsblsh1_nc __MPN(rsblsh1_nc)
+__GMP_DECLSPEC mp_limb_signed_t mpn_rsblsh1_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+/* mpn_sublsh2_n(c,a,b,n), when it exists, sets {c,n} to {a,n}-4*{b,n}, and
+ returns the borrow out (0, ..., 4). Use _ip1 when a=c. */
+#define mpn_sublsh2_n __MPN(sublsh2_n)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_sublsh2_nc __MPN(sublsh2_nc)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh2_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+#if HAVE_NATIVE_mpn_sublsh2_n && ! HAVE_NATIVE_mpn_sublsh2_n_ip1
+#define mpn_sublsh2_n_ip1(dst,src,n) mpn_sublsh2_n(dst,dst,src,n)
+#define HAVE_NATIVE_mpn_sublsh2_n_ip1 1
+#else
+#define mpn_sublsh2_n_ip1 __MPN(sublsh2_n_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh2_n_ip1 (mp_ptr, mp_srcptr, mp_size_t);
+#endif
+#if HAVE_NATIVE_mpn_sublsh2_nc && ! HAVE_NATIVE_mpn_sublsh2_nc_ip1
+#define mpn_sublsh2_nc_ip1(dst,src,n,c) mpn_sublsh2_nc(dst,dst,src,n,c)
+#define HAVE_NATIVE_mpn_sublsh2_nc_ip1 1
+#else
+#define mpn_sublsh2_nc_ip1 __MPN(sublsh2_nc_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh2_nc_ip1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+#endif
+
+/* mpn_sublsh_n(c,a,b,n,k), when it exists, sets {c,n} to {a,n}-2^k*{b,n}, and
+ returns the carry out (0, ..., 2^k). Use _ip1 when a=c. */
+#define mpn_sublsh_n __MPN(sublsh_n)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned int);
+#if HAVE_NATIVE_mpn_sublsh_n && ! HAVE_NATIVE_mpn_sublsh_n_ip1
+#define mpn_sublsh_n_ip1(dst,src,n,s) mpn_sublsh_n(dst,dst,src,n,s)
+#define HAVE_NATIVE_mpn_sublsh_n_ip1 1
+#else
+#define mpn_sublsh_n_ip1 __MPN(sublsh_n_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh_n_ip1 (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
+#endif
+#if HAVE_NATIVE_mpn_sublsh_nc && ! HAVE_NATIVE_mpn_sublsh_nc_ip1
+#define mpn_sublsh_nc_ip1(dst,src,n,s,c) mpn_sublsh_nc(dst,dst,src,n,s,c)
+#define HAVE_NATIVE_mpn_sublsh_nc_ip1 1
+#else
+#define mpn_sublsh_nc_ip1 __MPN(sublsh_nc_ip1)
+__GMP_DECLSPEC mp_limb_t mpn_sublsh_nc_ip1 (mp_ptr, mp_srcptr, mp_size_t, unsigned int, mp_limb_t);
+#endif
+
+/* mpn_rsblsh2_n(c,a,b,n), when it exists, sets {c,n} to 4*{b,n}-{a,n}, and
+ returns the carry out (-1, ..., 3). */
+#define mpn_rsblsh2_n __MPN(rsblsh2_n)
+__GMP_DECLSPEC mp_limb_signed_t mpn_rsblsh2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_rsblsh2_nc __MPN(rsblsh2_nc)
+__GMP_DECLSPEC mp_limb_signed_t mpn_rsblsh2_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+/* mpn_rsblsh_n(c,a,b,n,k), when it exists, sets {c,n} to 2^k*{b,n}-{a,n}, and
+ returns the carry out (-1, 0, ..., 2^k-1). */
+#define mpn_rsblsh_n __MPN(rsblsh_n)
+__GMP_DECLSPEC mp_limb_signed_t mpn_rsblsh_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned int);
+#define mpn_rsblsh_nc __MPN(rsblsh_nc)
+__GMP_DECLSPEC mp_limb_signed_t mpn_rsblsh_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned int, mp_limb_t);
+
+/* mpn_rsh1add_n(c,a,b,n), when it exists, sets {c,n} to ({a,n} + {b,n}) >> 1,
+ and returns the bit rshifted out (0 or 1). */
+#define mpn_rsh1add_n __MPN(rsh1add_n)
+__GMP_DECLSPEC mp_limb_t mpn_rsh1add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_rsh1add_nc __MPN(rsh1add_nc)
+__GMP_DECLSPEC mp_limb_t mpn_rsh1add_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+/* mpn_rsh1sub_n(c,a,b,n), when it exists, sets {c,n} to ({a,n} - {b,n}) >> 1,
+ and returns the bit rshifted out (0 or 1). If there's a borrow from the
+ subtract, it's stored as a 1 in the high bit of c[n-1], like a twos
+ complement negative. */
+#define mpn_rsh1sub_n __MPN(rsh1sub_n)
+__GMP_DECLSPEC mp_limb_t mpn_rsh1sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#define mpn_rsh1sub_nc __MPN(rsh1sub_nc)
+__GMP_DECLSPEC mp_limb_t mpn_rsh1sub_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#ifndef mpn_lshiftc /* if not done with cpuvec in a fat binary */
+#define mpn_lshiftc __MPN(lshiftc)
+__GMP_DECLSPEC mp_limb_t mpn_lshiftc (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
+#endif
+
+#define mpn_add_err1_n __MPN(add_err1_n)
+__GMP_DECLSPEC mp_limb_t mpn_add_err1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_add_err2_n __MPN(add_err2_n)
+__GMP_DECLSPEC mp_limb_t mpn_add_err2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_add_err3_n __MPN(add_err3_n)
+__GMP_DECLSPEC mp_limb_t mpn_add_err3_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_sub_err1_n __MPN(sub_err1_n)
+__GMP_DECLSPEC mp_limb_t mpn_sub_err1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_sub_err2_n __MPN(sub_err2_n)
+__GMP_DECLSPEC mp_limb_t mpn_sub_err2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_sub_err3_n __MPN(sub_err3_n)
+__GMP_DECLSPEC mp_limb_t mpn_sub_err3_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_add_n_sub_n __MPN(add_n_sub_n)
+__GMP_DECLSPEC mp_limb_t mpn_add_n_sub_n (mp_ptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+#define mpn_add_n_sub_nc __MPN(add_n_sub_nc)
+__GMP_DECLSPEC mp_limb_t mpn_add_n_sub_nc (mp_ptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_addaddmul_1msb0 __MPN(addaddmul_1msb0)
+__GMP_DECLSPEC mp_limb_t mpn_addaddmul_1msb0 (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+
+#define mpn_divrem_1c __MPN(divrem_1c)
+__GMP_DECLSPEC mp_limb_t mpn_divrem_1c (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+
+#define mpn_dump __MPN(dump)
+__GMP_DECLSPEC void mpn_dump (mp_srcptr, mp_size_t);
+
+#define mpn_fib2_ui __MPN(fib2_ui)
+__GMP_DECLSPEC mp_size_t mpn_fib2_ui (mp_ptr, mp_ptr, unsigned long);
+
+/* Remap names of internal mpn functions. */
+#define __clz_tab __MPN(clz_tab)
+#define mpn_udiv_w_sdiv __MPN(udiv_w_sdiv)
+
+#define mpn_jacobi_base __MPN(jacobi_base)
+__GMP_DECLSPEC int mpn_jacobi_base (mp_limb_t, mp_limb_t, int) ATTRIBUTE_CONST;
+
+#define mpn_jacobi_2 __MPN(jacobi_2)
+__GMP_DECLSPEC int mpn_jacobi_2 (mp_srcptr, mp_srcptr, unsigned);
+
+#define mpn_jacobi_n __MPN(jacobi_n)
+__GMP_DECLSPEC int mpn_jacobi_n (mp_ptr, mp_ptr, mp_size_t, unsigned);
+
+#define mpn_mod_1c __MPN(mod_1c)
+__GMP_DECLSPEC mp_limb_t mpn_mod_1c (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_mul_1c __MPN(mul_1c)
+__GMP_DECLSPEC mp_limb_t mpn_mul_1c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+
+#define mpn_mul_2 __MPN(mul_2)
+__GMP_DECLSPEC mp_limb_t mpn_mul_2 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_mul_3 __MPN(mul_3)
+__GMP_DECLSPEC mp_limb_t mpn_mul_3 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_mul_4 __MPN(mul_4)
+__GMP_DECLSPEC mp_limb_t mpn_mul_4 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_mul_5 __MPN(mul_5)
+__GMP_DECLSPEC mp_limb_t mpn_mul_5 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#define mpn_mul_6 __MPN(mul_6)
+__GMP_DECLSPEC mp_limb_t mpn_mul_6 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+#ifndef mpn_mul_basecase /* if not done with cpuvec in a fat binary */
+#define mpn_mul_basecase __MPN(mul_basecase)
+__GMP_DECLSPEC void mpn_mul_basecase (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+#endif
+
+#define mpn_mullo_n __MPN(mullo_n)
+__GMP_DECLSPEC void mpn_mullo_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+#ifndef mpn_mullo_basecase /* if not done with cpuvec in a fat binary */
+#define mpn_mullo_basecase __MPN(mullo_basecase)
+__GMP_DECLSPEC void mpn_mullo_basecase (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+#endif
+
+#ifndef mpn_sqr_basecase /* if not done with cpuvec in a fat binary */
+#define mpn_sqr_basecase __MPN(sqr_basecase)
+__GMP_DECLSPEC void mpn_sqr_basecase (mp_ptr, mp_srcptr, mp_size_t);
+#endif
+
+#define mpn_mulmid_basecase __MPN(mulmid_basecase)
+__GMP_DECLSPEC void mpn_mulmid_basecase (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+#define mpn_mulmid_n __MPN(mulmid_n)
+__GMP_DECLSPEC void mpn_mulmid_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+#define mpn_mulmid __MPN(mulmid)
+__GMP_DECLSPEC void mpn_mulmid (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+#define mpn_submul_1c __MPN(submul_1c)
+__GMP_DECLSPEC mp_limb_t mpn_submul_1c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+
+#ifndef mpn_redc_1 /* if not done with cpuvec in a fat binary */
+#define mpn_redc_1 __MPN(redc_1)
+__GMP_DECLSPEC mp_limb_t mpn_redc_1 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+#endif
+
+#ifndef mpn_redc_2 /* if not done with cpuvec in a fat binary */
+#define mpn_redc_2 __MPN(redc_2)
+__GMP_DECLSPEC mp_limb_t mpn_redc_2 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+#endif
+
+#define mpn_redc_n __MPN(redc_n)
+__GMP_DECLSPEC void mpn_redc_n (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+
+#ifndef mpn_mod_1_1p_cps /* if not done with cpuvec in a fat binary */
+#define mpn_mod_1_1p_cps __MPN(mod_1_1p_cps)
+__GMP_DECLSPEC void mpn_mod_1_1p_cps (mp_limb_t [4], mp_limb_t);
+#endif
+#ifndef mpn_mod_1_1p /* if not done with cpuvec in a fat binary */
+#define mpn_mod_1_1p __MPN(mod_1_1p)
+__GMP_DECLSPEC mp_limb_t mpn_mod_1_1p (mp_srcptr, mp_size_t, mp_limb_t, const mp_limb_t [4]) __GMP_ATTRIBUTE_PURE;
+#endif
+
+#ifndef mpn_mod_1s_2p_cps /* if not done with cpuvec in a fat binary */
+#define mpn_mod_1s_2p_cps __MPN(mod_1s_2p_cps)
+__GMP_DECLSPEC void mpn_mod_1s_2p_cps (mp_limb_t [5], mp_limb_t);
+#endif
+#ifndef mpn_mod_1s_2p /* if not done with cpuvec in a fat binary */
+#define mpn_mod_1s_2p __MPN(mod_1s_2p)
+__GMP_DECLSPEC mp_limb_t mpn_mod_1s_2p (mp_srcptr, mp_size_t, mp_limb_t, const mp_limb_t [5]) __GMP_ATTRIBUTE_PURE;
+#endif
+
+#ifndef mpn_mod_1s_3p_cps /* if not done with cpuvec in a fat binary */
+#define mpn_mod_1s_3p_cps __MPN(mod_1s_3p_cps)
+__GMP_DECLSPEC void mpn_mod_1s_3p_cps (mp_limb_t [6], mp_limb_t);
+#endif
+#ifndef mpn_mod_1s_3p /* if not done with cpuvec in a fat binary */
+#define mpn_mod_1s_3p __MPN(mod_1s_3p)
+__GMP_DECLSPEC mp_limb_t mpn_mod_1s_3p (mp_srcptr, mp_size_t, mp_limb_t, const mp_limb_t [6]) __GMP_ATTRIBUTE_PURE;
+#endif
+
+#ifndef mpn_mod_1s_4p_cps /* if not done with cpuvec in a fat binary */
+#define mpn_mod_1s_4p_cps __MPN(mod_1s_4p_cps)
+__GMP_DECLSPEC void mpn_mod_1s_4p_cps (mp_limb_t [7], mp_limb_t);
+#endif
+#ifndef mpn_mod_1s_4p /* if not done with cpuvec in a fat binary */
+#define mpn_mod_1s_4p __MPN(mod_1s_4p)
+__GMP_DECLSPEC mp_limb_t mpn_mod_1s_4p (mp_srcptr, mp_size_t, mp_limb_t, const mp_limb_t [7]) __GMP_ATTRIBUTE_PURE;
+#endif
+
+#define mpn_bc_mulmod_bnm1 __MPN(bc_mulmod_bnm1)
+__GMP_DECLSPEC void mpn_bc_mulmod_bnm1 (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_mulmod_bnm1 __MPN(mulmod_bnm1)
+__GMP_DECLSPEC void mpn_mulmod_bnm1 (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_mulmod_bnm1_next_size __MPN(mulmod_bnm1_next_size)
+__GMP_DECLSPEC mp_size_t mpn_mulmod_bnm1_next_size (mp_size_t) ATTRIBUTE_CONST;
+static inline mp_size_t
+mpn_mulmod_bnm1_itch (mp_size_t rn, mp_size_t an, mp_size_t bn) {
+ mp_size_t n, itch;
+ n = rn >> 1;
+ itch = rn + 4 +
+ (an > n ? (bn > n ? rn : n) : 0);
+ return itch;
+}
+
+#define mpn_sqrmod_bnm1 __MPN(sqrmod_bnm1)
+__GMP_DECLSPEC void mpn_sqrmod_bnm1 (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_sqrmod_bnm1_next_size __MPN(sqrmod_bnm1_next_size)
+__GMP_DECLSPEC mp_size_t mpn_sqrmod_bnm1_next_size (mp_size_t) ATTRIBUTE_CONST;
+static inline mp_size_t
+mpn_sqrmod_bnm1_itch (mp_size_t rn, mp_size_t an) {
+ mp_size_t n, itch;
+ n = rn >> 1;
+ itch = rn + 3 +
+ (an > n ? an : 0);
+ return itch;
+}
+
+typedef __gmp_randstate_struct *gmp_randstate_ptr;
+typedef const __gmp_randstate_struct *gmp_randstate_srcptr;
+
+/* Pseudo-random number generator function pointers structure. */
+typedef struct {
+ void (*randseed_fn) (gmp_randstate_t, mpz_srcptr);
+ void (*randget_fn) (gmp_randstate_t, mp_ptr, unsigned long int);
+ void (*randclear_fn) (gmp_randstate_t);
+ void (*randiset_fn) (gmp_randstate_ptr, gmp_randstate_srcptr);
+} gmp_randfnptr_t;
+
+/* Macro to obtain a void pointer to the function pointers structure. */
+#define RNG_FNPTR(rstate) ((rstate)->_mp_algdata._mp_lc)
+
+/* Macro to obtain a pointer to the generator's state.
+ When used as a lvalue the rvalue needs to be cast to mp_ptr. */
+#define RNG_STATE(rstate) ((rstate)->_mp_seed->_mp_d)
+
+/* Write a given number of random bits to rp. */
+#define _gmp_rand(rp, state, bits) \
+ do { \
+ gmp_randstate_ptr __rstate = (state); \
+ (*((gmp_randfnptr_t *) RNG_FNPTR (__rstate))->randget_fn) \
+ (__rstate, rp, bits); \
+ } while (0)
+
+__GMP_DECLSPEC void __gmp_randinit_mt_noseed (gmp_randstate_t);
+
+
+/* __gmp_rands is the global state for the old-style random functions, and
+ is also used in the test programs (hence the __GMP_DECLSPEC).
+
+ There's no seeding here, so mpz_random etc will generate the same
+ sequence every time. This is not unlike the C library random functions
+ if you don't seed them, so perhaps it's acceptable. Digging up a seed
+ from /dev/random or the like would work on many systems, but might
+ encourage a false confidence, since it'd be pretty much impossible to do
+ something that would work reliably everywhere. In any case the new style
+ functions are recommended to applications which care about randomness, so
+ the old functions aren't too important. */
+
+__GMP_DECLSPEC extern char __gmp_rands_initialized;
+__GMP_DECLSPEC extern gmp_randstate_t __gmp_rands;
+
+#define RANDS \
+ ((__gmp_rands_initialized ? 0 \
+ : (__gmp_rands_initialized = 1, \
+ __gmp_randinit_mt_noseed (__gmp_rands), 0)), \
+ __gmp_rands)
+
+/* this is used by the test programs, to free memory */
+#define RANDS_CLEAR() \
+ do { \
+ if (__gmp_rands_initialized) \
+ { \
+ __gmp_rands_initialized = 0; \
+ gmp_randclear (__gmp_rands); \
+ } \
+ } while (0)
+
+
+/* For a threshold between algorithms A and B, size>=thresh is where B
+ should be used. Special value MP_SIZE_T_MAX means only ever use A, or
+ value 0 means only ever use B. The tests for these special values will
+ be compile-time constants, so the compiler should be able to eliminate
+ the code for the unwanted algorithm. */
+
+#if ! defined (__GNUC__) || __GNUC__ < 2
+#define ABOVE_THRESHOLD(size,thresh) \
+ ((thresh) == 0 \
+ || ((thresh) != MP_SIZE_T_MAX \
+ && (size) >= (thresh)))
+#else
+#define ABOVE_THRESHOLD(size,thresh) \
+ ((__builtin_constant_p (thresh) && (thresh) == 0) \
+ || (!(__builtin_constant_p (thresh) && (thresh) == MP_SIZE_T_MAX) \
+ && (size) >= (thresh)))
+#endif
+#define BELOW_THRESHOLD(size,thresh) (! ABOVE_THRESHOLD (size, thresh))
+
+#define MPN_TOOM22_MUL_MINSIZE 4
+#define MPN_TOOM2_SQR_MINSIZE 4
+
+#define MPN_TOOM33_MUL_MINSIZE 17
+#define MPN_TOOM3_SQR_MINSIZE 17
+
+#define MPN_TOOM44_MUL_MINSIZE 30
+#define MPN_TOOM4_SQR_MINSIZE 30
+
+#define MPN_TOOM6H_MUL_MINSIZE 46
+#define MPN_TOOM6_SQR_MINSIZE 46
+
+#define MPN_TOOM8H_MUL_MINSIZE 86
+#define MPN_TOOM8_SQR_MINSIZE 86
+
+#define MPN_TOOM32_MUL_MINSIZE 10
+#define MPN_TOOM42_MUL_MINSIZE 10
+#define MPN_TOOM43_MUL_MINSIZE 25
+#define MPN_TOOM53_MUL_MINSIZE 17
+#define MPN_TOOM54_MUL_MINSIZE 31
+#define MPN_TOOM63_MUL_MINSIZE 49
+
+#define MPN_TOOM42_MULMID_MINSIZE 4
+
+#define mpn_sqr_diagonal __MPN(sqr_diagonal)
+__GMP_DECLSPEC void mpn_sqr_diagonal (mp_ptr, mp_srcptr, mp_size_t);
+
+#define mpn_sqr_diag_addlsh1 __MPN(sqr_diag_addlsh1)
+__GMP_DECLSPEC void mpn_sqr_diag_addlsh1 (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+#define mpn_toom_interpolate_5pts __MPN(toom_interpolate_5pts)
+__GMP_DECLSPEC void mpn_toom_interpolate_5pts (mp_ptr, mp_ptr, mp_ptr, mp_size_t, mp_size_t, int, mp_limb_t);
+
+enum toom6_flags {toom6_all_pos = 0, toom6_vm1_neg = 1, toom6_vm2_neg = 2};
+#define mpn_toom_interpolate_6pts __MPN(toom_interpolate_6pts)
+__GMP_DECLSPEC void mpn_toom_interpolate_6pts (mp_ptr, mp_size_t, enum toom6_flags, mp_ptr, mp_ptr, mp_ptr, mp_size_t);
+
+enum toom7_flags { toom7_w1_neg = 1, toom7_w3_neg = 2 };
+#define mpn_toom_interpolate_7pts __MPN(toom_interpolate_7pts)
+__GMP_DECLSPEC void mpn_toom_interpolate_7pts (mp_ptr, mp_size_t, enum toom7_flags, mp_ptr, mp_ptr, mp_ptr, mp_ptr, mp_size_t, mp_ptr);
+
+#define mpn_toom_interpolate_8pts __MPN(toom_interpolate_8pts)
+__GMP_DECLSPEC void mpn_toom_interpolate_8pts (mp_ptr, mp_size_t, mp_ptr, mp_ptr, mp_size_t, mp_ptr);
+
+#define mpn_toom_interpolate_12pts __MPN(toom_interpolate_12pts)
+__GMP_DECLSPEC void mpn_toom_interpolate_12pts (mp_ptr, mp_ptr, mp_ptr, mp_ptr, mp_size_t, mp_size_t, int, mp_ptr);
+
+#define mpn_toom_interpolate_16pts __MPN(toom_interpolate_16pts)
+__GMP_DECLSPEC void mpn_toom_interpolate_16pts (mp_ptr, mp_ptr, mp_ptr, mp_ptr, mp_ptr, mp_size_t, mp_size_t, int, mp_ptr);
+
+#define mpn_toom_couple_handling __MPN(toom_couple_handling)
+__GMP_DECLSPEC void mpn_toom_couple_handling (mp_ptr, mp_size_t, mp_ptr, int, mp_size_t, int, int);
+
+#define mpn_toom_eval_dgr3_pm1 __MPN(toom_eval_dgr3_pm1)
+__GMP_DECLSPEC int mpn_toom_eval_dgr3_pm1 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_size_t, mp_ptr);
+
+#define mpn_toom_eval_dgr3_pm2 __MPN(toom_eval_dgr3_pm2)
+__GMP_DECLSPEC int mpn_toom_eval_dgr3_pm2 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_size_t, mp_ptr);
+
+#define mpn_toom_eval_pm1 __MPN(toom_eval_pm1)
+__GMP_DECLSPEC int mpn_toom_eval_pm1 (mp_ptr, mp_ptr, unsigned, mp_srcptr, mp_size_t, mp_size_t, mp_ptr);
+
+#define mpn_toom_eval_pm2 __MPN(toom_eval_pm2)
+__GMP_DECLSPEC int mpn_toom_eval_pm2 (mp_ptr, mp_ptr, unsigned, mp_srcptr, mp_size_t, mp_size_t, mp_ptr);
+
+#define mpn_toom_eval_pm2exp __MPN(toom_eval_pm2exp)
+__GMP_DECLSPEC int mpn_toom_eval_pm2exp (mp_ptr, mp_ptr, unsigned, mp_srcptr, mp_size_t, mp_size_t, unsigned, mp_ptr);
+
+#define mpn_toom_eval_pm2rexp __MPN(toom_eval_pm2rexp)
+__GMP_DECLSPEC int mpn_toom_eval_pm2rexp (mp_ptr, mp_ptr, unsigned, mp_srcptr, mp_size_t, mp_size_t, unsigned, mp_ptr);
+
+#define mpn_toom22_mul __MPN(toom22_mul)
+__GMP_DECLSPEC void mpn_toom22_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom32_mul __MPN(toom32_mul)
+__GMP_DECLSPEC void mpn_toom32_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom42_mul __MPN(toom42_mul)
+__GMP_DECLSPEC void mpn_toom42_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom52_mul __MPN(toom52_mul)
+__GMP_DECLSPEC void mpn_toom52_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom62_mul __MPN(toom62_mul)
+__GMP_DECLSPEC void mpn_toom62_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom2_sqr __MPN(toom2_sqr)
+__GMP_DECLSPEC void mpn_toom2_sqr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom33_mul __MPN(toom33_mul)
+__GMP_DECLSPEC void mpn_toom33_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom43_mul __MPN(toom43_mul)
+__GMP_DECLSPEC void mpn_toom43_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom53_mul __MPN(toom53_mul)
+__GMP_DECLSPEC void mpn_toom53_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom54_mul __MPN(toom54_mul)
+__GMP_DECLSPEC void mpn_toom54_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom63_mul __MPN(toom63_mul)
+__GMP_DECLSPEC void mpn_toom63_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom3_sqr __MPN(toom3_sqr)
+__GMP_DECLSPEC void mpn_toom3_sqr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom44_mul __MPN(toom44_mul)
+__GMP_DECLSPEC void mpn_toom44_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom4_sqr __MPN(toom4_sqr)
+__GMP_DECLSPEC void mpn_toom4_sqr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom6h_mul __MPN(toom6h_mul)
+__GMP_DECLSPEC void mpn_toom6h_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom6_sqr __MPN(toom6_sqr)
+__GMP_DECLSPEC void mpn_toom6_sqr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom8h_mul __MPN(toom8h_mul)
+__GMP_DECLSPEC void mpn_toom8h_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom8_sqr __MPN(toom8_sqr)
+__GMP_DECLSPEC void mpn_toom8_sqr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_toom42_mulmid __MPN(toom42_mulmid)
+__GMP_DECLSPEC void mpn_toom42_mulmid (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_fft_best_k __MPN(fft_best_k)
+__GMP_DECLSPEC int mpn_fft_best_k (mp_size_t, int) ATTRIBUTE_CONST;
+
+#define mpn_mul_fft __MPN(mul_fft)
+__GMP_DECLSPEC mp_limb_t mpn_mul_fft (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, int);
+
+#define mpn_mul_fft_full __MPN(mul_fft_full)
+__GMP_DECLSPEC void mpn_mul_fft_full (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+#define mpn_nussbaumer_mul __MPN(nussbaumer_mul)
+__GMP_DECLSPEC void mpn_nussbaumer_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+#define mpn_fft_next_size __MPN(fft_next_size)
+__GMP_DECLSPEC mp_size_t mpn_fft_next_size (mp_size_t, int) ATTRIBUTE_CONST;
+
+#define mpn_div_qr_1n_pi1 __MPN(div_qr_1n_pi1)
+ __GMP_DECLSPEC mp_limb_t mpn_div_qr_1n_pi1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, mp_limb_t);
+
+#define mpn_div_qr_2n_pi1 __MPN(div_qr_2n_pi1)
+ __GMP_DECLSPEC mp_limb_t mpn_div_qr_2n_pi1 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, mp_limb_t);
+
+#define mpn_div_qr_2u_pi1 __MPN(div_qr_2u_pi1)
+ __GMP_DECLSPEC mp_limb_t mpn_div_qr_2u_pi1 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, int, mp_limb_t);
+
+#define mpn_sbpi1_div_qr __MPN(sbpi1_div_qr)
+__GMP_DECLSPEC mp_limb_t mpn_sbpi1_div_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_sbpi1_div_q __MPN(sbpi1_div_q)
+__GMP_DECLSPEC mp_limb_t mpn_sbpi1_div_q (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_sbpi1_divappr_q __MPN(sbpi1_divappr_q)
+__GMP_DECLSPEC mp_limb_t mpn_sbpi1_divappr_q (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_dcpi1_div_qr __MPN(dcpi1_div_qr)
+__GMP_DECLSPEC mp_limb_t mpn_dcpi1_div_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, gmp_pi1_t *);
+#define mpn_dcpi1_div_qr_n __MPN(dcpi1_div_qr_n)
+__GMP_DECLSPEC mp_limb_t mpn_dcpi1_div_qr_n (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, gmp_pi1_t *, mp_ptr);
+
+#define mpn_dcpi1_div_q __MPN(dcpi1_div_q)
+__GMP_DECLSPEC mp_limb_t mpn_dcpi1_div_q (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, gmp_pi1_t *);
+
+#define mpn_dcpi1_divappr_q __MPN(dcpi1_divappr_q)
+__GMP_DECLSPEC mp_limb_t mpn_dcpi1_divappr_q (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, gmp_pi1_t *);
+#define mpn_dcpi1_divappr_q_n __MPN(dcpi1_divappr_q_n)
+__GMP_DECLSPEC mp_limb_t mpn_dcpi1_divappr_q_n (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, gmp_pi1_t *, mp_ptr);
+
+#define mpn_mu_div_qr __MPN(mu_div_qr)
+__GMP_DECLSPEC mp_limb_t mpn_mu_div_qr (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_mu_div_qr_itch __MPN(mu_div_qr_itch)
+__GMP_DECLSPEC mp_size_t mpn_mu_div_qr_itch (mp_size_t, mp_size_t, int) ATTRIBUTE_CONST;
+#define mpn_mu_div_qr_choose_in __MPN(mu_div_qr_choose_in)
+__GMP_DECLSPEC mp_size_t mpn_mu_div_qr_choose_in (mp_size_t, mp_size_t, int);
+
+#define mpn_preinv_mu_div_qr __MPN(preinv_mu_div_qr)
+__GMP_DECLSPEC mp_limb_t mpn_preinv_mu_div_qr (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_preinv_mu_div_qr_itch __MPN(preinv_mu_div_qr_itch)
+__GMP_DECLSPEC mp_size_t mpn_preinv_mu_div_qr_itch (mp_size_t, mp_size_t, mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_mu_divappr_q __MPN(mu_divappr_q)
+__GMP_DECLSPEC mp_limb_t mpn_mu_divappr_q (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_mu_divappr_q_itch __MPN(mu_divappr_q_itch)
+__GMP_DECLSPEC mp_size_t mpn_mu_divappr_q_itch (mp_size_t, mp_size_t, int) ATTRIBUTE_CONST;
+#define mpn_mu_divappr_q_choose_in __MPN(mu_divappr_q_choose_in)
+__GMP_DECLSPEC mp_size_t mpn_mu_divappr_q_choose_in (mp_size_t, mp_size_t, int);
+
+#define mpn_preinv_mu_divappr_q __MPN(preinv_mu_divappr_q)
+__GMP_DECLSPEC mp_limb_t mpn_preinv_mu_divappr_q (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_mu_div_q __MPN(mu_div_q)
+__GMP_DECLSPEC mp_limb_t mpn_mu_div_q (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_mu_div_q_itch __MPN(mu_div_q_itch)
+__GMP_DECLSPEC mp_size_t mpn_mu_div_q_itch (mp_size_t, mp_size_t, int) ATTRIBUTE_CONST;
+
+#define mpn_div_q __MPN(div_q)
+__GMP_DECLSPEC void mpn_div_q (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+#define mpn_invert __MPN(invert)
+__GMP_DECLSPEC void mpn_invert (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_invert_itch(n) mpn_invertappr_itch(n)
+
+#define mpn_ni_invertappr __MPN(ni_invertappr)
+__GMP_DECLSPEC mp_limb_t mpn_ni_invertappr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_invertappr __MPN(invertappr)
+__GMP_DECLSPEC mp_limb_t mpn_invertappr (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_invertappr_itch(n) (3 * (n) + 2)
+
+#define mpn_binvert __MPN(binvert)
+__GMP_DECLSPEC void mpn_binvert (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_binvert_itch __MPN(binvert_itch)
+__GMP_DECLSPEC mp_size_t mpn_binvert_itch (mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_bdiv_q_1 __MPN(bdiv_q_1)
+__GMP_DECLSPEC mp_limb_t mpn_bdiv_q_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_pi1_bdiv_q_1 __MPN(pi1_bdiv_q_1)
+__GMP_DECLSPEC mp_limb_t mpn_pi1_bdiv_q_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, int);
+
+#define mpn_sbpi1_bdiv_qr __MPN(sbpi1_bdiv_qr)
+__GMP_DECLSPEC mp_limb_t mpn_sbpi1_bdiv_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_sbpi1_bdiv_q __MPN(sbpi1_bdiv_q)
+__GMP_DECLSPEC void mpn_sbpi1_bdiv_q (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_dcpi1_bdiv_qr __MPN(dcpi1_bdiv_qr)
+__GMP_DECLSPEC mp_limb_t mpn_dcpi1_bdiv_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+#define mpn_dcpi1_bdiv_qr_n_itch __MPN(dcpi1_bdiv_qr_n_itch)
+__GMP_DECLSPEC mp_size_t mpn_dcpi1_bdiv_qr_n_itch (mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_dcpi1_bdiv_qr_n __MPN(dcpi1_bdiv_qr_n)
+__GMP_DECLSPEC mp_limb_t mpn_dcpi1_bdiv_qr_n (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
+#define mpn_dcpi1_bdiv_q __MPN(dcpi1_bdiv_q)
+__GMP_DECLSPEC void mpn_dcpi1_bdiv_q (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_dcpi1_bdiv_q_n __MPN(dcpi1_bdiv_q_n)
+__GMP_DECLSPEC void mpn_dcpi1_bdiv_q_n (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
+#define mpn_dcpi1_bdiv_q_n_itch __MPN(dcpi1_bdiv_q_n_itch)
+__GMP_DECLSPEC mp_size_t mpn_dcpi1_bdiv_q_n_itch (mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_mu_bdiv_qr __MPN(mu_bdiv_qr)
+__GMP_DECLSPEC mp_limb_t mpn_mu_bdiv_qr (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_mu_bdiv_qr_itch __MPN(mu_bdiv_qr_itch)
+__GMP_DECLSPEC mp_size_t mpn_mu_bdiv_qr_itch (mp_size_t, mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_mu_bdiv_q __MPN(mu_bdiv_q)
+__GMP_DECLSPEC void mpn_mu_bdiv_q (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_mu_bdiv_q_itch __MPN(mu_bdiv_q_itch)
+__GMP_DECLSPEC mp_size_t mpn_mu_bdiv_q_itch (mp_size_t, mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_bdiv_qr __MPN(bdiv_qr)
+__GMP_DECLSPEC mp_limb_t mpn_bdiv_qr (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_bdiv_qr_itch __MPN(bdiv_qr_itch)
+__GMP_DECLSPEC mp_size_t mpn_bdiv_qr_itch (mp_size_t, mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_bdiv_q __MPN(bdiv_q)
+__GMP_DECLSPEC void mpn_bdiv_q (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_bdiv_q_itch __MPN(bdiv_q_itch)
+__GMP_DECLSPEC mp_size_t mpn_bdiv_q_itch (mp_size_t, mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_divexact __MPN(divexact)
+__GMP_DECLSPEC void mpn_divexact (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+#define mpn_divexact_itch __MPN(divexact_itch)
+__GMP_DECLSPEC mp_size_t mpn_divexact_itch (mp_size_t, mp_size_t) ATTRIBUTE_CONST;
+
+#ifndef mpn_bdiv_dbm1c /* if not done with cpuvec in a fat binary */
+#define mpn_bdiv_dbm1c __MPN(bdiv_dbm1c)
+__GMP_DECLSPEC mp_limb_t mpn_bdiv_dbm1c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+#endif
+
+#define mpn_bdiv_dbm1(dst, src, size, divisor) \
+ mpn_bdiv_dbm1c (dst, src, size, divisor, __GMP_CAST (mp_limb_t, 0))
+
+#define mpn_powm __MPN(powm)
+__GMP_DECLSPEC void mpn_powm (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_powlo __MPN(powlo)
+__GMP_DECLSPEC void mpn_powlo (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_size_t, mp_ptr);
+
+#define mpn_sec_pi1_div_qr __MPN(sec_pi1_div_qr)
+__GMP_DECLSPEC mp_limb_t mpn_sec_pi1_div_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
+#define mpn_sec_pi1_div_r __MPN(sec_pi1_div_r)
+__GMP_DECLSPEC void mpn_sec_pi1_div_r (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
+
+
+/* Override mpn_addlsh1_n, mpn_addlsh2_n, mpn_sublsh1_n, etc with mpn_addlsh_n,
+ etc when !HAVE_NATIVE the former but HAVE_NATIVE_ the latter. We then lie
+ and say these macros represent native functions, but leave a trace by using
+ the value 2 rather than 1. */
+
+#if HAVE_NATIVE_mpn_addlsh_n && ! HAVE_NATIVE_mpn_addlsh1_n
+#undef mpn_addlsh1_n
+#define mpn_addlsh1_n(a,b,c,d) mpn_addlsh_n(a,b,c,d,1)
+#define HAVE_NATIVE_mpn_addlsh1_n 2
+#endif
+
+#if HAVE_NATIVE_mpn_addlsh_n && ! HAVE_NATIVE_mpn_addlsh2_n
+#undef mpn_addlsh2_n
+#define mpn_addlsh2_n(a,b,c,d) mpn_addlsh_n(a,b,c,d,2)
+#define HAVE_NATIVE_mpn_addlsh2_n 2
+#endif
+
+#if HAVE_NATIVE_mpn_sublsh_n && ! HAVE_NATIVE_mpn_sublsh1_n
+#undef mpn_sublsh1_n
+#define mpn_sublsh1_n(a,b,c,d) mpn_sublsh_n(a,b,c,d,1)
+#define HAVE_NATIVE_mpn_sublsh1_n 2
+#endif
+
+#if HAVE_NATIVE_mpn_sublsh_n && ! HAVE_NATIVE_mpn_sublsh2_n
+#undef mpn_sublsh2_n
+#define mpn_sublsh2_n(a,b,c,d) mpn_sublsh_n(a,b,c,d,2)
+#define HAVE_NATIVE_mpn_sublsh2_n 2
+#endif
+
+#if HAVE_NATIVE_mpn_rsblsh_n && ! HAVE_NATIVE_mpn_rsblsh1_n
+#undef mpn_rsblsh1_n
+#define mpn_rsblsh1_n(a,b,c,d) mpn_rsblsh_n(a,b,c,d,1)
+#define HAVE_NATIVE_mpn_rsblsh1_n 2
+#endif
+
+#if HAVE_NATIVE_mpn_rsblsh_n && ! HAVE_NATIVE_mpn_rsblsh2_n
+#undef mpn_rsblsh2_n
+#define mpn_rsblsh2_n(a,b,c,d) mpn_rsblsh_n(a,b,c,d,2)
+#define HAVE_NATIVE_mpn_rsblsh2_n 2
+#endif
+
+
+#ifndef DIVEXACT_BY3_METHOD
+#if GMP_NUMB_BITS % 2 == 0 && ! defined (HAVE_NATIVE_mpn_divexact_by3c)
+#define DIVEXACT_BY3_METHOD 0 /* default to using mpn_bdiv_dbm1c */
+#else
+#define DIVEXACT_BY3_METHOD 1
+#endif
+#endif
+
+#if DIVEXACT_BY3_METHOD == 0
+#undef mpn_divexact_by3
+#define mpn_divexact_by3(dst,src,size) \
+ (3 & mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 3)))
+/* override mpn_divexact_by3c defined in gmp.h */
+/*
+#undef mpn_divexact_by3c
+#define mpn_divexact_by3c(dst,src,size,cy) \
+ (3 & mpn_bdiv_dbm1c (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 3, GMP_NUMB_MASK / 3 * cy)))
+*/
+#endif
+
+#if GMP_NUMB_BITS % 4 == 0
+#define mpn_divexact_by5(dst,src,size) \
+ (7 & 3 * mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 5)))
+#endif
+
+#if GMP_NUMB_BITS % 3 == 0
+#define mpn_divexact_by7(dst,src,size) \
+ (7 & 1 * mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 7)))
+#endif
+
+#if GMP_NUMB_BITS % 6 == 0
+#define mpn_divexact_by9(dst,src,size) \
+ (15 & 7 * mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 9)))
+#endif
+
+#if GMP_NUMB_BITS % 10 == 0
+#define mpn_divexact_by11(dst,src,size) \
+ (15 & 5 * mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 11)))
+#endif
+
+#if GMP_NUMB_BITS % 12 == 0
+#define mpn_divexact_by13(dst,src,size) \
+ (15 & 3 * mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 13)))
+#endif
+
+#if GMP_NUMB_BITS % 4 == 0
+#define mpn_divexact_by15(dst,src,size) \
+ (15 & 1 * mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 15)))
+#endif
+
+#define mpz_divexact_gcd __gmpz_divexact_gcd
+__GMP_DECLSPEC void mpz_divexact_gcd (mpz_ptr, mpz_srcptr, mpz_srcptr);
+
+#define mpz_prodlimbs __gmpz_prodlimbs
+__GMP_DECLSPEC mp_size_t mpz_prodlimbs (mpz_ptr, mp_ptr, mp_size_t);
+
+#define mpz_oddfac_1 __gmpz_oddfac_1
+__GMP_DECLSPEC void mpz_oddfac_1 (mpz_ptr, mp_limb_t, unsigned);
+
+#define mpz_inp_str_nowhite __gmpz_inp_str_nowhite
+#ifdef _GMP_H_HAVE_FILE
+__GMP_DECLSPEC size_t mpz_inp_str_nowhite (mpz_ptr, FILE *, int, int, size_t);
+#endif
+
+#define mpn_divisible_p __MPN(divisible_p)
+__GMP_DECLSPEC int mpn_divisible_p (mp_srcptr, mp_size_t, mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+#define mpn_rootrem __MPN(rootrem)
+__GMP_DECLSPEC mp_size_t mpn_rootrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_broot __MPN(broot)
+__GMP_DECLSPEC void mpn_broot (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_broot_invm1 __MPN(broot_invm1)
+__GMP_DECLSPEC void mpn_broot_invm1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+#define mpn_brootinv __MPN(brootinv)
+__GMP_DECLSPEC void mpn_brootinv (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_ptr);
+
+#define mpn_bsqrt __MPN(bsqrt)
+__GMP_DECLSPEC void mpn_bsqrt (mp_ptr, mp_srcptr, mp_bitcnt_t, mp_ptr);
+
+#define mpn_bsqrtinv __MPN(bsqrtinv)
+__GMP_DECLSPEC int mpn_bsqrtinv (mp_ptr, mp_srcptr, mp_bitcnt_t, mp_ptr);
+
+#if defined (_CRAY)
+#define MPN_COPY_INCR(dst, src, n) \
+ do { \
+ int __i; /* Faster on some Crays with plain int */ \
+ _Pragma ("_CRI ivdep"); \
+ for (__i = 0; __i < (n); __i++) \
+ (dst)[__i] = (src)[__i]; \
+ } while (0)
+#endif
+
+/* used by test programs, hence __GMP_DECLSPEC */
+#ifndef mpn_copyi /* if not done with cpuvec in a fat binary */
+#define mpn_copyi __MPN(copyi)
+__GMP_DECLSPEC void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t);
+#endif
+
+#if ! defined (MPN_COPY_INCR) && HAVE_NATIVE_mpn_copyi
+#define MPN_COPY_INCR(dst, src, size) \
+ do { \
+ ASSERT ((size) >= 0); \
+ ASSERT (MPN_SAME_OR_INCR_P (dst, src, size)); \
+ mpn_copyi (dst, src, size); \
+ } while (0)
+#endif
+
+/* Copy N limbs from SRC to DST incrementing, N==0 allowed. */
+#if ! defined (MPN_COPY_INCR)
+#define MPN_COPY_INCR(dst, src, n) \
+ do { \
+ ASSERT ((n) >= 0); \
+ ASSERT (MPN_SAME_OR_INCR_P (dst, src, n)); \
+ if ((n) != 0) \
+ { \
+ mp_size_t __n = (n) - 1; \
+ mp_ptr __dst = (dst); \
+ mp_srcptr __src = (src); \
+ mp_limb_t __x; \
+ __x = *__src++; \
+ if (__n != 0) \
+ { \
+ do \
+ { \
+ *__dst++ = __x; \
+ __x = *__src++; \
+ } \
+ while (--__n); \
+ } \
+ *__dst++ = __x; \
+ } \
+ } while (0)
+#endif
+
+
+#if defined (_CRAY)
+#define MPN_COPY_DECR(dst, src, n) \
+ do { \
+ int __i; /* Faster on some Crays with plain int */ \
+ _Pragma ("_CRI ivdep"); \
+ for (__i = (n) - 1; __i >= 0; __i--) \
+ (dst)[__i] = (src)[__i]; \
+ } while (0)
+#endif
+
+/* used by test programs, hence __GMP_DECLSPEC */
+#ifndef mpn_copyd /* if not done with cpuvec in a fat binary */
+#define mpn_copyd __MPN(copyd)
+__GMP_DECLSPEC void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t);
+#endif
+
+#if ! defined (MPN_COPY_DECR) && HAVE_NATIVE_mpn_copyd
+#define MPN_COPY_DECR(dst, src, size) \
+ do { \
+ ASSERT ((size) >= 0); \
+ ASSERT (MPN_SAME_OR_DECR_P (dst, src, size)); \
+ mpn_copyd (dst, src, size); \
+ } while (0)
+#endif
+
+/* Copy N limbs from SRC to DST decrementing, N==0 allowed. */
+#if ! defined (MPN_COPY_DECR)
+#define MPN_COPY_DECR(dst, src, n) \
+ do { \
+ ASSERT ((n) >= 0); \
+ ASSERT (MPN_SAME_OR_DECR_P (dst, src, n)); \
+ if ((n) != 0) \
+ { \
+ mp_size_t __n = (n) - 1; \
+ mp_ptr __dst = (dst) + __n; \
+ mp_srcptr __src = (src) + __n; \
+ mp_limb_t __x; \
+ __x = *__src--; \
+ if (__n != 0) \
+ { \
+ do \
+ { \
+ *__dst-- = __x; \
+ __x = *__src--; \
+ } \
+ while (--__n); \
+ } \
+ *__dst-- = __x; \
+ } \
+ } while (0)
+#endif
+
+
+#ifndef MPN_COPY
+#define MPN_COPY(d,s,n) \
+ do { \
+ ASSERT (MPN_SAME_OR_SEPARATE_P (d, s, n)); \
+ MPN_COPY_INCR (d, s, n); \
+ } while (0)
+#endif
+
+
+/* Set {dst,size} to the limbs of {src,size} in reverse order. */
+#define MPN_REVERSE(dst, src, size) \
+ do { \
+ mp_ptr __dst = (dst); \
+ mp_size_t __size = (size); \
+ mp_srcptr __src = (src) + __size - 1; \
+ mp_size_t __i; \
+ ASSERT ((size) >= 0); \
+ ASSERT (! MPN_OVERLAP_P (dst, size, src, size)); \
+ CRAY_Pragma ("_CRI ivdep"); \
+ for (__i = 0; __i < __size; __i++) \
+ { \
+ *__dst = *__src; \
+ __dst++; \
+ __src--; \
+ } \
+ } while (0)
+
+
+/* Zero n limbs at dst.
+
+ For power and powerpc we want an inline stu/bdnz loop for zeroing. On
+ ppc630 for instance this is optimal since it can sustain only 1 store per
+ cycle.
+
+ gcc 2.95.x (for powerpc64 -maix64, or powerpc32) doesn't recognise the
+ "for" loop in the generic code below can become stu/bdnz. The do/while
+ here helps it get to that. The same caveat about plain -mpowerpc64 mode
+ applies here as to __GMPN_COPY_INCR in gmp.h.
+
+ xlc 3.1 already generates stu/bdnz from the generic C, and does so from
+ this loop too.
+
+ Enhancement: GLIBC does some trickery with dcbz to zero whole cache lines
+ at a time. MPN_ZERO isn't all that important in GMP, so it might be more
+ trouble than it's worth to do the same, though perhaps a call to memset
+ would be good when on a GNU system. */
+
+#if HAVE_HOST_CPU_FAMILY_power || HAVE_HOST_CPU_FAMILY_powerpc
+#define MPN_ZERO(dst, n) \
+ do { \
+ ASSERT ((n) >= 0); \
+ if ((n) != 0) \
+ { \
+ mp_ptr __dst = (dst) - 1; \
+ mp_size_t __n = (n); \
+ do \
+ *++__dst = 0; \
+ while (--__n); \
+ } \
+ } while (0)
+#endif
+
+#ifndef MPN_ZERO
+#define MPN_ZERO(dst, n) \
+ do { \
+ ASSERT ((n) >= 0); \
+ if ((n) != 0) \
+ { \
+ mp_ptr __dst = (dst); \
+ mp_size_t __n = (n); \
+ do \
+ *__dst++ = 0; \
+ while (--__n); \
+ } \
+ } while (0)
+#endif
+
+
+/* On the x86s repe/scasl doesn't seem useful, since it takes many cycles to
+ start up and would need to strip a lot of zeros before it'd be faster
+ than a simple cmpl loop. Here are some times in cycles for
+ std/repe/scasl/cld and cld/repe/scasl (the latter would be for stripping
+ low zeros).
+
+ std cld
+ P5 18 16
+ P6 46 38
+ K6 36 13
+ K7 21 20
+*/
+#ifndef MPN_NORMALIZE
+#define MPN_NORMALIZE(DST, NLIMBS) \
+ do { \
+ while ((NLIMBS) > 0) \
+ { \
+ if ((DST)[(NLIMBS) - 1] != 0) \
+ break; \
+ (NLIMBS)--; \
+ } \
+ } while (0)
+#endif
+#ifndef MPN_NORMALIZE_NOT_ZERO
+#define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS) \
+ do { \
+ while (1) \
+ { \
+ ASSERT ((NLIMBS) >= 1); \
+ if ((DST)[(NLIMBS) - 1] != 0) \
+ break; \
+ (NLIMBS)--; \
+ } \
+ } while (0)
+#endif
+
+/* Strip least significant zero limbs from {ptr,size} by incrementing ptr
+ and decrementing size. low should be ptr[0], and will be the new ptr[0]
+ on returning. The number in {ptr,size} must be non-zero, ie. size!=0 and
+ somewhere a non-zero limb. */
+#define MPN_STRIP_LOW_ZEROS_NOT_ZERO(ptr, size, low) \
+ do { \
+ ASSERT ((size) >= 1); \
+ ASSERT ((low) == (ptr)[0]); \
+ \
+ while ((low) == 0) \
+ { \
+ (size)--; \
+ ASSERT ((size) >= 1); \
+ (ptr)++; \
+ (low) = *(ptr); \
+ } \
+ } while (0)
+
+/* Initialize X of type mpz_t with space for NLIMBS limbs. X should be a
+ temporary variable; it will be automatically cleared out at function
+ return. We use __x here to make it possible to accept both mpz_ptr and
+ mpz_t arguments. */
+#define MPZ_TMP_INIT(X, NLIMBS) \
+ do { \
+ mpz_ptr __x = (X); \
+ ASSERT ((NLIMBS) >= 1); \
+ __x->_mp_alloc = (NLIMBS); \
+ __x->_mp_d = TMP_ALLOC_LIMBS (NLIMBS); \
+ } while (0)
+
+#if WANT_ASSERT
+static inline void *
+_mpz_newalloc (mpz_ptr z, mp_size_t n)
+{
+ void * res = _mpz_realloc(z,n);
+ /* If we are checking the code, force a random change to limbs. */
+ ((mp_ptr) res)[0] = ~ ((mp_ptr) res)[ALLOC (z) - 1];
+ return res;
+}
+#else
+#define _mpz_newalloc _mpz_realloc
+#endif
+/* Realloc for an mpz_t WHAT if it has less than NEEDED limbs. */
+#define MPZ_REALLOC(z,n) (UNLIKELY ((n) > ALLOC(z)) \
+ ? (mp_ptr) _mpz_realloc(z,n) \
+ : PTR(z))
+#define MPZ_NEWALLOC(z,n) (UNLIKELY ((n) > ALLOC(z)) \
+ ? (mp_ptr) _mpz_newalloc(z,n) \
+ : PTR(z))
+
+#define MPZ_EQUAL_1_P(z) (SIZ(z)==1 && PTR(z)[0] == 1)
+
+
+/* MPN_FIB2_SIZE(n) is the size in limbs required by mpn_fib2_ui for fp and
+ f1p.
+
+ From Knuth vol 1 section 1.2.8, F[n] = phi^n/sqrt(5) rounded to the
+ nearest integer, where phi=(1+sqrt(5))/2 is the golden ratio. So the
+ number of bits required is n*log_2((1+sqrt(5))/2) = n*0.6942419.
+
+ The multiplier used is 23/32=0.71875 for efficient calculation on CPUs
+ without good floating point. There's +2 for rounding up, and a further
+ +2 since at the last step x limbs are doubled into a 2x+1 limb region
+ whereas the actual F[2k] value might be only 2x-1 limbs.
+
+ Note that a division is done first, since on a 32-bit system it's at
+ least conceivable to go right up to n==ULONG_MAX. (F[2^32-1] would be
+ about 380Mbytes, plus temporary workspace of about 1.2Gbytes here and
+ whatever a multiply of two 190Mbyte numbers takes.)
+
+ Enhancement: When GMP_NUMB_BITS is not a power of 2 the division could be
+ worked into the multiplier. */
+
+#define MPN_FIB2_SIZE(n) \
+ ((mp_size_t) ((n) / 32 * 23 / GMP_NUMB_BITS) + 4)
+
+
+/* FIB_TABLE(n) returns the Fibonacci number F[n]. Must have n in the range
+ -1 <= n <= FIB_TABLE_LIMIT (that constant in fib_table.h).
+
+ FIB_TABLE_LUCNUM_LIMIT (in fib_table.h) is the largest n for which L[n] =
+ F[n] + 2*F[n-1] fits in a limb. */
+
+__GMP_DECLSPEC extern const mp_limb_t __gmp_fib_table[];
+#define FIB_TABLE(n) (__gmp_fib_table[(n)+1])
+
+extern const mp_limb_t __gmp_oddfac_table[];
+extern const mp_limb_t __gmp_odd2fac_table[];
+extern const unsigned char __gmp_fac2cnt_table[];
+extern const mp_limb_t __gmp_limbroots_table[];
+
+/* n^log <= GMP_NUMB_MAX, a limb can store log factors less than n */
+static inline unsigned
+log_n_max (mp_limb_t n)
+{
+ unsigned log;
+ for (log = 8; n > __gmp_limbroots_table[log - 1]; log--);
+ return log;
+}
+
+#define SIEVESIZE 512 /* FIXME: Allow gmp_init_primesieve to choose */
+typedef struct
+{
+ unsigned long d; /* current index in s[] */
+ unsigned long s0; /* number corresponding to s[0] */
+ unsigned long sqrt_s0; /* misnomer for sqrt(s[SIEVESIZE-1]) */
+ unsigned char s[SIEVESIZE + 1]; /* sieve table */
+} gmp_primesieve_t;
+
+#define gmp_init_primesieve __gmp_init_primesieve
+__GMP_DECLSPEC void gmp_init_primesieve (gmp_primesieve_t *);
+
+#define gmp_nextprime __gmp_nextprime
+__GMP_DECLSPEC unsigned long int gmp_nextprime (gmp_primesieve_t *);
+
+#define gmp_primesieve __gmp_primesieve
+__GMP_DECLSPEC mp_limb_t gmp_primesieve (mp_ptr, mp_limb_t);
+
+
+#ifndef MUL_TOOM22_THRESHOLD
+#define MUL_TOOM22_THRESHOLD 30
+#endif
+
+#ifndef MUL_TOOM33_THRESHOLD
+#define MUL_TOOM33_THRESHOLD 100
+#endif
+
+#ifndef MUL_TOOM44_THRESHOLD
+#define MUL_TOOM44_THRESHOLD 300
+#endif
+
+#ifndef MUL_TOOM6H_THRESHOLD
+#define MUL_TOOM6H_THRESHOLD 350
+#endif
+
+#ifndef SQR_TOOM6_THRESHOLD
+#define SQR_TOOM6_THRESHOLD MUL_TOOM6H_THRESHOLD
+#endif
+
+#ifndef MUL_TOOM8H_THRESHOLD
+#define MUL_TOOM8H_THRESHOLD 450
+#endif
+
+#ifndef SQR_TOOM8_THRESHOLD
+#define SQR_TOOM8_THRESHOLD MUL_TOOM8H_THRESHOLD
+#endif
+
+#ifndef MUL_TOOM32_TO_TOOM43_THRESHOLD
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 100
+#endif
+
+#ifndef MUL_TOOM32_TO_TOOM53_THRESHOLD
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 110
+#endif
+
+#ifndef MUL_TOOM42_TO_TOOM53_THRESHOLD
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 100
+#endif
+
+#ifndef MUL_TOOM42_TO_TOOM63_THRESHOLD
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 110
+#endif
+
+#ifndef MUL_TOOM43_TO_TOOM54_THRESHOLD
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 150
+#endif
+
+/* MUL_TOOM22_THRESHOLD_LIMIT is the maximum for MUL_TOOM22_THRESHOLD. In a
+ normal build MUL_TOOM22_THRESHOLD is a constant and we use that. In a fat
+ binary or tune program build MUL_TOOM22_THRESHOLD is a variable and a
+ separate hard limit will have been defined. Similarly for TOOM3. */
+#ifndef MUL_TOOM22_THRESHOLD_LIMIT
+#define MUL_TOOM22_THRESHOLD_LIMIT MUL_TOOM22_THRESHOLD
+#endif
+#ifndef MUL_TOOM33_THRESHOLD_LIMIT
+#define MUL_TOOM33_THRESHOLD_LIMIT MUL_TOOM33_THRESHOLD
+#endif
+#ifndef MULLO_BASECASE_THRESHOLD_LIMIT
+#define MULLO_BASECASE_THRESHOLD_LIMIT MULLO_BASECASE_THRESHOLD
+#endif
+
+/* SQR_BASECASE_THRESHOLD is where mpn_sqr_basecase should take over from
+ mpn_mul_basecase. Default is to use mpn_sqr_basecase from 0. (Note that we
+ certainly always want it if there's a native assembler mpn_sqr_basecase.)
+
+ If it turns out that mpn_toom2_sqr becomes faster than mpn_mul_basecase
+ before mpn_sqr_basecase does, then SQR_BASECASE_THRESHOLD is the toom2
+ threshold and SQR_TOOM2_THRESHOLD is 0. This oddity arises more or less
+ because SQR_TOOM2_THRESHOLD represents the size up to which mpn_sqr_basecase
+ should be used, and that may be never. */
+
+#ifndef SQR_BASECASE_THRESHOLD
+#define SQR_BASECASE_THRESHOLD 0
+#endif
+
+#ifndef SQR_TOOM2_THRESHOLD
+#define SQR_TOOM2_THRESHOLD 50
+#endif
+
+#ifndef SQR_TOOM3_THRESHOLD
+#define SQR_TOOM3_THRESHOLD 120
+#endif
+
+#ifndef SQR_TOOM4_THRESHOLD
+#define SQR_TOOM4_THRESHOLD 400
+#endif
+
+/* See comments above about MUL_TOOM33_THRESHOLD_LIMIT. */
+#ifndef SQR_TOOM3_THRESHOLD_LIMIT
+#define SQR_TOOM3_THRESHOLD_LIMIT SQR_TOOM3_THRESHOLD
+#endif
+
+#ifndef MULMID_TOOM42_THRESHOLD
+#define MULMID_TOOM42_THRESHOLD MUL_TOOM22_THRESHOLD
+#endif
+
+#ifndef DC_DIV_QR_THRESHOLD
+#define DC_DIV_QR_THRESHOLD 50
+#endif
+
+#ifndef DC_DIVAPPR_Q_THRESHOLD
+#define DC_DIVAPPR_Q_THRESHOLD 200
+#endif
+
+#ifndef DC_BDIV_QR_THRESHOLD
+#define DC_BDIV_QR_THRESHOLD 50
+#endif
+
+#ifndef DC_BDIV_Q_THRESHOLD
+#define DC_BDIV_Q_THRESHOLD 180
+#endif
+
+#ifndef DIVEXACT_JEB_THRESHOLD
+#define DIVEXACT_JEB_THRESHOLD 25
+#endif
+
+#ifndef INV_MULMOD_BNM1_THRESHOLD
+#define INV_MULMOD_BNM1_THRESHOLD (5*MULMOD_BNM1_THRESHOLD)
+#endif
+
+#ifndef INV_APPR_THRESHOLD
+#define INV_APPR_THRESHOLD INV_NEWTON_THRESHOLD
+#endif
+
+#ifndef INV_NEWTON_THRESHOLD
+#define INV_NEWTON_THRESHOLD 200
+#endif
+
+#ifndef BINV_NEWTON_THRESHOLD
+#define BINV_NEWTON_THRESHOLD 300
+#endif
+
+#ifndef MU_DIVAPPR_Q_THRESHOLD
+#define MU_DIVAPPR_Q_THRESHOLD 2000
+#endif
+
+#ifndef MU_DIV_QR_THRESHOLD
+#define MU_DIV_QR_THRESHOLD 2000
+#endif
+
+#ifndef MUPI_DIV_QR_THRESHOLD
+#define MUPI_DIV_QR_THRESHOLD 200
+#endif
+
+#ifndef MU_BDIV_Q_THRESHOLD
+#define MU_BDIV_Q_THRESHOLD 2000
+#endif
+
+#ifndef MU_BDIV_QR_THRESHOLD
+#define MU_BDIV_QR_THRESHOLD 2000
+#endif
+
+#ifndef MULMOD_BNM1_THRESHOLD
+#define MULMOD_BNM1_THRESHOLD 16
+#endif
+
+#ifndef SQRMOD_BNM1_THRESHOLD
+#define SQRMOD_BNM1_THRESHOLD 16
+#endif
+
+#ifndef MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD
+#define MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD (INV_MULMOD_BNM1_THRESHOLD/2)
+#endif
+
+#if HAVE_NATIVE_mpn_addmul_2 || HAVE_NATIVE_mpn_redc_2
+
+#ifndef REDC_1_TO_REDC_2_THRESHOLD
+#define REDC_1_TO_REDC_2_THRESHOLD 15
+#endif
+#ifndef REDC_2_TO_REDC_N_THRESHOLD
+#define REDC_2_TO_REDC_N_THRESHOLD 100
+#endif
+
+#else
+
+#ifndef REDC_1_TO_REDC_N_THRESHOLD
+#define REDC_1_TO_REDC_N_THRESHOLD 100
+#endif
+
+#endif /* HAVE_NATIVE_mpn_addmul_2 || HAVE_NATIVE_mpn_redc_2 */
+
+
+/* First k to use for an FFT modF multiply. A modF FFT is an order
+ log(2^k)/log(2^(k-1)) algorithm, so k=3 is merely 1.5 like karatsuba,
+ whereas k=4 is 1.33 which is faster than toom3 at 1.485. */
+#define FFT_FIRST_K 4
+
+/* Threshold at which FFT should be used to do a modF NxN -> N multiply. */
+#ifndef MUL_FFT_MODF_THRESHOLD
+#define MUL_FFT_MODF_THRESHOLD (MUL_TOOM33_THRESHOLD * 3)
+#endif
+#ifndef SQR_FFT_MODF_THRESHOLD
+#define SQR_FFT_MODF_THRESHOLD (SQR_TOOM3_THRESHOLD * 3)
+#endif
+
+/* Threshold at which FFT should be used to do an NxN -> 2N multiply. This
+ will be a size where FFT is using k=7 or k=8, since an FFT-k used for an
+ NxN->2N multiply and not recursing into itself is an order
+ log(2^k)/log(2^(k-2)) algorithm, so it'll be at least k=7 at 1.39 which
+ is the first better than toom3. */
+#ifndef MUL_FFT_THRESHOLD
+#define MUL_FFT_THRESHOLD (MUL_FFT_MODF_THRESHOLD * 10)
+#endif
+#ifndef SQR_FFT_THRESHOLD
+#define SQR_FFT_THRESHOLD (SQR_FFT_MODF_THRESHOLD * 10)
+#endif
+
+/* Table of thresholds for successive modF FFT "k"s. The first entry is
+ where FFT_FIRST_K+1 should be used, the second FFT_FIRST_K+2,
+ etc. See mpn_fft_best_k(). */
+#ifndef MUL_FFT_TABLE
+#define MUL_FFT_TABLE \
+ { MUL_TOOM33_THRESHOLD * 4, /* k=5 */ \
+ MUL_TOOM33_THRESHOLD * 8, /* k=6 */ \
+ MUL_TOOM33_THRESHOLD * 16, /* k=7 */ \
+ MUL_TOOM33_THRESHOLD * 32, /* k=8 */ \
+ MUL_TOOM33_THRESHOLD * 96, /* k=9 */ \
+ MUL_TOOM33_THRESHOLD * 288, /* k=10 */ \
+ 0 }
+#endif
+#ifndef SQR_FFT_TABLE
+#define SQR_FFT_TABLE \
+ { SQR_TOOM3_THRESHOLD * 4, /* k=5 */ \
+ SQR_TOOM3_THRESHOLD * 8, /* k=6 */ \
+ SQR_TOOM3_THRESHOLD * 16, /* k=7 */ \
+ SQR_TOOM3_THRESHOLD * 32, /* k=8 */ \
+ SQR_TOOM3_THRESHOLD * 96, /* k=9 */ \
+ SQR_TOOM3_THRESHOLD * 288, /* k=10 */ \
+ 0 }
+#endif
+
+struct fft_table_nk
+{
+ unsigned int n:27;
+ unsigned int k:5;
+};
+
+#ifndef FFT_TABLE_ATTRS
+#define FFT_TABLE_ATTRS static const
+#endif
+
+#define MPN_FFT_TABLE_SIZE 16
+
+
+#ifndef DC_DIV_QR_THRESHOLD
+#define DC_DIV_QR_THRESHOLD (3 * MUL_TOOM22_THRESHOLD)
+#endif
+
+#ifndef GET_STR_DC_THRESHOLD
+#define GET_STR_DC_THRESHOLD 18
+#endif
+
+#ifndef GET_STR_PRECOMPUTE_THRESHOLD
+#define GET_STR_PRECOMPUTE_THRESHOLD 35
+#endif
+
+#ifndef SET_STR_DC_THRESHOLD
+#define SET_STR_DC_THRESHOLD 750
+#endif
+
+#ifndef SET_STR_PRECOMPUTE_THRESHOLD
+#define SET_STR_PRECOMPUTE_THRESHOLD 2000
+#endif
+
+#ifndef FAC_ODD_THRESHOLD
+#define FAC_ODD_THRESHOLD 35
+#endif
+
+#ifndef FAC_DSC_THRESHOLD
+#define FAC_DSC_THRESHOLD 400
+#endif
+
+/* Return non-zero if xp,xsize and yp,ysize overlap.
+ If xp+xsize<=yp there's no overlap, or if yp+ysize<=xp there's no
+ overlap. If both these are false, there's an overlap. */
+#define MPN_OVERLAP_P(xp, xsize, yp, ysize) \
+ ((xp) + (xsize) > (yp) && (yp) + (ysize) > (xp))
+#define MEM_OVERLAP_P(xp, xsize, yp, ysize) \
+ ( (char *) (xp) + (xsize) > (char *) (yp) \
+ && (char *) (yp) + (ysize) > (char *) (xp))
+
+/* Return non-zero if xp,xsize and yp,ysize are either identical or not
+ overlapping. Return zero if they're partially overlapping. */
+#define MPN_SAME_OR_SEPARATE_P(xp, yp, size) \
+ MPN_SAME_OR_SEPARATE2_P(xp, size, yp, size)
+#define MPN_SAME_OR_SEPARATE2_P(xp, xsize, yp, ysize) \
+ ((xp) == (yp) || ! MPN_OVERLAP_P (xp, xsize, yp, ysize))
+
+/* Return non-zero if dst,dsize and src,ssize are either identical or
+ overlapping in a way suitable for an incrementing/decrementing algorithm.
+ Return zero if they're partially overlapping in an unsuitable fashion. */
+#define MPN_SAME_OR_INCR2_P(dst, dsize, src, ssize) \
+ ((dst) <= (src) || ! MPN_OVERLAP_P (dst, dsize, src, ssize))
+#define MPN_SAME_OR_INCR_P(dst, src, size) \
+ MPN_SAME_OR_INCR2_P(dst, size, src, size)
+#define MPN_SAME_OR_DECR2_P(dst, dsize, src, ssize) \
+ ((dst) >= (src) || ! MPN_OVERLAP_P (dst, dsize, src, ssize))
+#define MPN_SAME_OR_DECR_P(dst, src, size) \
+ MPN_SAME_OR_DECR2_P(dst, size, src, size)
+
+
+/* ASSERT() is a private assertion checking scheme, similar to <assert.h>.
+ ASSERT() does the check only if WANT_ASSERT is selected, ASSERT_ALWAYS()
+ does it always. Generally assertions are meant for development, but
+ might help when looking for a problem later too.
+
+ Note that strings shouldn't be used within the ASSERT expression,
+ eg. ASSERT(strcmp(s,"notgood")!=0), since the quotes upset the "expr"
+ used in the !HAVE_STRINGIZE case (ie. K&R). */
+
+#ifdef __LINE__
+#define ASSERT_LINE __LINE__
+#else
+#define ASSERT_LINE -1
+#endif
+
+#ifdef __FILE__
+#define ASSERT_FILE __FILE__
+#else
+#define ASSERT_FILE ""
+#endif
+
+__GMP_DECLSPEC void __gmp_assert_header (const char *, int);
+__GMP_DECLSPEC void __gmp_assert_fail (const char *, int, const char *) ATTRIBUTE_NORETURN;
+
+#if HAVE_STRINGIZE
+#define ASSERT_FAIL(expr) __gmp_assert_fail (ASSERT_FILE, ASSERT_LINE, #expr)
+#else
+#define ASSERT_FAIL(expr) __gmp_assert_fail (ASSERT_FILE, ASSERT_LINE, "expr")
+#endif
+
+#define ASSERT_ALWAYS(expr) \
+ do { \
+ if (UNLIKELY (!(expr))) \
+ ASSERT_FAIL (expr); \
+ } while (0)
+
+#if WANT_ASSERT
+#define ASSERT(expr) ASSERT_ALWAYS (expr)
+#else
+#define ASSERT(expr) do {} while (0)
+#endif
+
+
+/* ASSERT_CARRY checks the expression is non-zero, and ASSERT_NOCARRY checks
+ that it's zero. In both cases if assertion checking is disabled the
+ expression is still evaluated. These macros are meant for use with
+ routines like mpn_add_n() where the return value represents a carry or
+ whatever that should or shouldn't occur in some context. For example,
+ ASSERT_NOCARRY (mpn_add_n (rp, s1p, s2p, size)); */
+#if WANT_ASSERT
+#define ASSERT_CARRY(expr) ASSERT_ALWAYS ((expr) != 0)
+#define ASSERT_NOCARRY(expr) ASSERT_ALWAYS ((expr) == 0)
+#else
+#define ASSERT_CARRY(expr) (expr)
+#define ASSERT_NOCARRY(expr) (expr)
+#endif
+
+
+/* ASSERT_CODE includes code when assertion checking is wanted. This is the
+ same as writing "#if WANT_ASSERT", but more compact. */
+#if WANT_ASSERT
+#define ASSERT_CODE(expr) expr
+#else
+#define ASSERT_CODE(expr)
+#endif
+
+
+/* Test that an mpq_t is in fully canonical form. This can be used as
+ protection on routines like mpq_equal which give wrong results on
+ non-canonical inputs. */
+#if WANT_ASSERT
+#define ASSERT_MPQ_CANONICAL(q) \
+ do { \
+ ASSERT (q->_mp_den._mp_size > 0); \
+ if (q->_mp_num._mp_size == 0) \
+ { \
+ /* zero should be 0/1 */ \
+ ASSERT (mpz_cmp_ui (mpq_denref(q), 1L) == 0); \
+ } \
+ else \
+ { \
+ /* no common factors */ \
+ mpz_t __g; \
+ mpz_init (__g); \
+ mpz_gcd (__g, mpq_numref(q), mpq_denref(q)); \
+ ASSERT (mpz_cmp_ui (__g, 1) == 0); \
+ mpz_clear (__g); \
+ } \
+ } while (0)
+#else
+#define ASSERT_MPQ_CANONICAL(q) do {} while (0)
+#endif
+
+/* Check that the nail parts are zero. */
+#define ASSERT_ALWAYS_LIMB(limb) \
+ do { \
+ mp_limb_t __nail = (limb) & GMP_NAIL_MASK; \
+ ASSERT_ALWAYS (__nail == 0); \
+ } while (0)
+#define ASSERT_ALWAYS_MPN(ptr, size) \
+ do { \
+ /* let whole loop go dead when no nails */ \
+ if (GMP_NAIL_BITS != 0) \
+ { \
+ mp_size_t __i; \
+ for (__i = 0; __i < (size); __i++) \
+ ASSERT_ALWAYS_LIMB ((ptr)[__i]); \
+ } \
+ } while (0)
+#if WANT_ASSERT
+#define ASSERT_LIMB(limb) ASSERT_ALWAYS_LIMB (limb)
+#define ASSERT_MPN(ptr, size) ASSERT_ALWAYS_MPN (ptr, size)
+#else
+#define ASSERT_LIMB(limb) do {} while (0)
+#define ASSERT_MPN(ptr, size) do {} while (0)
+#endif
+
+
+/* Assert that an mpn region {ptr,size} is zero, or non-zero.
+ size==0 is allowed, and in that case {ptr,size} considered to be zero. */
+#if WANT_ASSERT
+#define ASSERT_MPN_ZERO_P(ptr,size) \
+ do { \
+ mp_size_t __i; \
+ ASSERT ((size) >= 0); \
+ for (__i = 0; __i < (size); __i++) \
+ ASSERT ((ptr)[__i] == 0); \
+ } while (0)
+#define ASSERT_MPN_NONZERO_P(ptr,size) \
+ do { \
+ mp_size_t __i; \
+ int __nonzero = 0; \
+ ASSERT ((size) >= 0); \
+ for (__i = 0; __i < (size); __i++) \
+ if ((ptr)[__i] != 0) \
+ { \
+ __nonzero = 1; \
+ break; \
+ } \
+ ASSERT (__nonzero); \
+ } while (0)
+#else
+#define ASSERT_MPN_ZERO_P(ptr,size) do {} while (0)
+#define ASSERT_MPN_NONZERO_P(ptr,size) do {} while (0)
+#endif
+
+
+#if ! HAVE_NATIVE_mpn_com
+#undef mpn_com
+#define mpn_com(d,s,n) \
+ do { \
+ mp_ptr __d = (d); \
+ mp_srcptr __s = (s); \
+ mp_size_t __n = (n); \
+ ASSERT (__n >= 1); \
+ ASSERT (MPN_SAME_OR_SEPARATE_P (__d, __s, __n)); \
+ do \
+ *__d++ = (~ *__s++) & GMP_NUMB_MASK; \
+ while (--__n); \
+ } while (0)
+#endif
+
+#define MPN_LOGOPS_N_INLINE(rp, up, vp, n, operation) \
+ do { \
+ mp_srcptr __up = (up); \
+ mp_srcptr __vp = (vp); \
+ mp_ptr __rp = (rp); \
+ mp_size_t __n = (n); \
+ mp_limb_t __a, __b; \
+ ASSERT (__n > 0); \
+ ASSERT (MPN_SAME_OR_SEPARATE_P (__rp, __up, __n)); \
+ ASSERT (MPN_SAME_OR_SEPARATE_P (__rp, __vp, __n)); \
+ __up += __n; \
+ __vp += __n; \
+ __rp += __n; \
+ __n = -__n; \
+ do { \
+ __a = __up[__n]; \
+ __b = __vp[__n]; \
+ __rp[__n] = operation; \
+ } while (++__n); \
+ } while (0)
+
+
+#if ! HAVE_NATIVE_mpn_and_n
+#undef mpn_and_n
+#define mpn_and_n(rp, up, vp, n) \
+ MPN_LOGOPS_N_INLINE (rp, up, vp, n, __a & __b)
+#endif
+
+#if ! HAVE_NATIVE_mpn_andn_n
+#undef mpn_andn_n
+#define mpn_andn_n(rp, up, vp, n) \
+ MPN_LOGOPS_N_INLINE (rp, up, vp, n, __a & ~__b)
+#endif
+
+#if ! HAVE_NATIVE_mpn_nand_n
+#undef mpn_nand_n
+#define mpn_nand_n(rp, up, vp, n) \
+ MPN_LOGOPS_N_INLINE (rp, up, vp, n, ~(__a & __b) & GMP_NUMB_MASK)
+#endif
+
+#if ! HAVE_NATIVE_mpn_ior_n
+#undef mpn_ior_n
+#define mpn_ior_n(rp, up, vp, n) \
+ MPN_LOGOPS_N_INLINE (rp, up, vp, n, __a | __b)
+#endif
+
+#if ! HAVE_NATIVE_mpn_iorn_n
+#undef mpn_iorn_n
+#define mpn_iorn_n(rp, up, vp, n) \
+ MPN_LOGOPS_N_INLINE (rp, up, vp, n, (__a | ~__b) & GMP_NUMB_MASK)
+#endif
+
+#if ! HAVE_NATIVE_mpn_nior_n
+#undef mpn_nior_n
+#define mpn_nior_n(rp, up, vp, n) \
+ MPN_LOGOPS_N_INLINE (rp, up, vp, n, ~(__a | __b) & GMP_NUMB_MASK)
+#endif
+
+#if ! HAVE_NATIVE_mpn_xor_n
+#undef mpn_xor_n
+#define mpn_xor_n(rp, up, vp, n) \
+ MPN_LOGOPS_N_INLINE (rp, up, vp, n, __a ^ __b)
+#endif
+
+#if ! HAVE_NATIVE_mpn_xnor_n
+#undef mpn_xnor_n
+#define mpn_xnor_n(rp, up, vp, n) \
+ MPN_LOGOPS_N_INLINE (rp, up, vp, n, ~(__a ^ __b) & GMP_NUMB_MASK)
+#endif
+
+#define mpn_trialdiv __MPN(trialdiv)
+__GMP_DECLSPEC mp_limb_t mpn_trialdiv (mp_srcptr, mp_size_t, mp_size_t, int *);
+
+#define mpn_remove __MPN(remove)
+__GMP_DECLSPEC mp_bitcnt_t mpn_remove (mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_bitcnt_t);
+
+
+/* ADDC_LIMB sets w=x+y and cout to 0 or 1 for a carry from that addition. */
+#if GMP_NAIL_BITS == 0
+#define ADDC_LIMB(cout, w, x, y) \
+ do { \
+ mp_limb_t __x = (x); \
+ mp_limb_t __y = (y); \
+ mp_limb_t __w = __x + __y; \
+ (w) = __w; \
+ (cout) = __w < __x; \
+ } while (0)
+#else
+#define ADDC_LIMB(cout, w, x, y) \
+ do { \
+ mp_limb_t __w; \
+ ASSERT_LIMB (x); \
+ ASSERT_LIMB (y); \
+ __w = (x) + (y); \
+ (w) = __w & GMP_NUMB_MASK; \
+ (cout) = __w >> GMP_NUMB_BITS; \
+ } while (0)
+#endif
+
+/* SUBC_LIMB sets w=x-y and cout to 0 or 1 for a borrow from that
+ subtract. */
+#if GMP_NAIL_BITS == 0
+#define SUBC_LIMB(cout, w, x, y) \
+ do { \
+ mp_limb_t __x = (x); \
+ mp_limb_t __y = (y); \
+ mp_limb_t __w = __x - __y; \
+ (w) = __w; \
+ (cout) = __w > __x; \
+ } while (0)
+#else
+#define SUBC_LIMB(cout, w, x, y) \
+ do { \
+ mp_limb_t __w = (x) - (y); \
+ (w) = __w & GMP_NUMB_MASK; \
+ (cout) = __w >> (GMP_LIMB_BITS-1); \
+ } while (0)
+#endif
+
+
+/* MPN_INCR_U does {ptr,size} += n, MPN_DECR_U does {ptr,size} -= n, both
+ expecting no carry (or borrow) from that.
+
+ The size parameter is only for the benefit of assertion checking. In a
+ normal build it's unused and the carry/borrow is just propagated as far
+ as it needs to go.
+
+ On random data, usually only one or two limbs of {ptr,size} get updated,
+ so there's no need for any sophisticated looping, just something compact
+ and sensible.
+
+ FIXME: Switch all code from mpn_{incr,decr}_u to MPN_{INCR,DECR}_U,
+ declaring their operand sizes, then remove the former. This is purely
+ for the benefit of assertion checking. */
+
+#if defined (__GNUC__) && GMP_NAIL_BITS == 0 && ! defined (NO_ASM) \
+ && (defined(HAVE_HOST_CPU_FAMILY_x86) || defined(HAVE_HOST_CPU_FAMILY_x86_64)) \
+ && ! WANT_ASSERT
+/* Better flags handling than the generic C gives on i386, saving a few
+ bytes of code and maybe a cycle or two. */
+
+#define MPN_IORD_U(ptr, incr, aors) \
+ do { \
+ mp_ptr __ptr_dummy; \
+ if (__builtin_constant_p (incr) && (incr) == 0) \
+ { \
+ } \
+ else if (__builtin_constant_p (incr) && (incr) == 1) \
+ { \
+ __asm__ __volatile__ \
+ ("\n" ASM_L(top) ":\n" \
+ "\t" aors "\t$1, (%0)\n" \
+ "\tlea\t%c2(%0), %0\n" \
+ "\tjc\t" ASM_L(top) \
+ : "=r" (__ptr_dummy) \
+ : "0" (ptr), "n" (sizeof(mp_limb_t)) \
+ : "memory"); \
+ } \
+ else \
+ { \
+ __asm__ __volatile__ \
+ ( aors "\t%2, (%0)\n" \
+ "\tjnc\t" ASM_L(done) "\n" \
+ ASM_L(top) ":\n" \
+ "\t" aors "\t$1, %c3(%0)\n" \
+ "\tlea\t%c3(%0), %0\n" \
+ "\tjc\t" ASM_L(top) "\n" \
+ ASM_L(done) ":\n" \
+ : "=r" (__ptr_dummy) \
+ : "0" (ptr), \
+ "ri" ((mp_limb_t) (incr)), "n" (sizeof(mp_limb_t)) \
+ : "memory"); \
+ } \
+ } while (0)
+
+#if GMP_LIMB_BITS == 32
+#define MPN_INCR_U(ptr, size, incr) MPN_IORD_U (ptr, incr, "addl")
+#define MPN_DECR_U(ptr, size, incr) MPN_IORD_U (ptr, incr, "subl")
+#endif
+#if GMP_LIMB_BITS == 64
+#define MPN_INCR_U(ptr, size, incr) MPN_IORD_U (ptr, incr, "addq")
+#define MPN_DECR_U(ptr, size, incr) MPN_IORD_U (ptr, incr, "subq")
+#endif
+#define mpn_incr_u(ptr, incr) MPN_INCR_U (ptr, 0, incr)
+#define mpn_decr_u(ptr, incr) MPN_DECR_U (ptr, 0, incr)
+#endif
+
+#if GMP_NAIL_BITS == 0
+#ifndef mpn_incr_u
+#define mpn_incr_u(p,incr) \
+ do { \
+ mp_limb_t __x; \
+ mp_ptr __p = (p); \
+ if (__builtin_constant_p (incr) && (incr) == 1) \
+ { \
+ while (++(*(__p++)) == 0) \
+ ; \
+ } \
+ else \
+ { \
+ __x = *__p + (incr); \
+ *__p = __x; \
+ if (__x < (incr)) \
+ while (++(*(++__p)) == 0) \
+ ; \
+ } \
+ } while (0)
+#endif
+#ifndef mpn_decr_u
+#define mpn_decr_u(p,incr) \
+ do { \
+ mp_limb_t __x; \
+ mp_ptr __p = (p); \
+ if (__builtin_constant_p (incr) && (incr) == 1) \
+ { \
+ while ((*(__p++))-- == 0) \
+ ; \
+ } \
+ else \
+ { \
+ __x = *__p; \
+ *__p = __x - (incr); \
+ if (__x < (incr)) \
+ while ((*(++__p))-- == 0) \
+ ; \
+ } \
+ } while (0)
+#endif
+#endif
+
+#if GMP_NAIL_BITS >= 1
+#ifndef mpn_incr_u
+#define mpn_incr_u(p,incr) \
+ do { \
+ mp_limb_t __x; \
+ mp_ptr __p = (p); \
+ if (__builtin_constant_p (incr) && (incr) == 1) \
+ { \
+ do \
+ { \
+ __x = (*__p + 1) & GMP_NUMB_MASK; \
+ *__p++ = __x; \
+ } \
+ while (__x == 0); \
+ } \
+ else \
+ { \
+ __x = (*__p + (incr)); \
+ *__p++ = __x & GMP_NUMB_MASK; \
+ if (__x >> GMP_NUMB_BITS != 0) \
+ { \
+ do \
+ { \
+ __x = (*__p + 1) & GMP_NUMB_MASK; \
+ *__p++ = __x; \
+ } \
+ while (__x == 0); \
+ } \
+ } \
+ } while (0)
+#endif
+#ifndef mpn_decr_u
+#define mpn_decr_u(p,incr) \
+ do { \
+ mp_limb_t __x; \
+ mp_ptr __p = (p); \
+ if (__builtin_constant_p (incr) && (incr) == 1) \
+ { \
+ do \
+ { \
+ __x = *__p; \
+ *__p++ = (__x - 1) & GMP_NUMB_MASK; \
+ } \
+ while (__x == 0); \
+ } \
+ else \
+ { \
+ __x = *__p - (incr); \
+ *__p++ = __x & GMP_NUMB_MASK; \
+ if (__x >> GMP_NUMB_BITS != 0) \
+ { \
+ do \
+ { \
+ __x = *__p; \
+ *__p++ = (__x - 1) & GMP_NUMB_MASK; \
+ } \
+ while (__x == 0); \
+ } \
+ } \
+ } while (0)
+#endif
+#endif
+
+#ifndef MPN_INCR_U
+#if WANT_ASSERT
+#define MPN_INCR_U(ptr, size, n) \
+ do { \
+ ASSERT ((size) >= 1); \
+ ASSERT_NOCARRY (mpn_add_1 (ptr, ptr, size, n)); \
+ } while (0)
+#else
+#define MPN_INCR_U(ptr, size, n) mpn_incr_u (ptr, n)
+#endif
+#endif
+
+#ifndef MPN_DECR_U
+#if WANT_ASSERT
+#define MPN_DECR_U(ptr, size, n) \
+ do { \
+ ASSERT ((size) >= 1); \
+ ASSERT_NOCARRY (mpn_sub_1 (ptr, ptr, size, n)); \
+ } while (0)
+#else
+#define MPN_DECR_U(ptr, size, n) mpn_decr_u (ptr, n)
+#endif
+#endif
+
+
+/* Structure for conversion between internal binary format and strings. */
+struct bases
+{
+ /* Number of digits in the conversion base that always fits in an mp_limb_t.
+ For example, for base 10 on a machine where a mp_limb_t has 32 bits this
+ is 9, since 10**9 is the largest number that fits into a mp_limb_t. */
+ int chars_per_limb;
+
+ /* log(2)/log(conversion_base) */
+ mp_limb_t logb2;
+
+ /* log(conversion_base)/log(2) */
+ mp_limb_t log2b;
+
+ /* base**chars_per_limb, i.e. the biggest number that fits a word, built by
+ factors of base. Exception: For 2, 4, 8, etc, big_base is log2(base),
+ i.e. the number of bits used to represent each digit in the base. */
+ mp_limb_t big_base;
+
+ /* A GMP_LIMB_BITS bit approximation to 1/big_base, represented as a
+ fixed-point number. Instead of dividing by big_base an application can
+ choose to multiply by big_base_inverted. */
+ mp_limb_t big_base_inverted;
+};
+
+#define mp_bases __MPN(bases)
+__GMP_DECLSPEC extern const struct bases mp_bases[257];
+
+
+/* Compute the number of digits in base for nbits bits, making sure the result
+ is never too small. The two variants of the macro implement the same
+ function; the GT2 variant below works just for bases > 2. */
+#define DIGITS_IN_BASE_FROM_BITS(res, nbits, b) \
+ do { \
+ mp_limb_t _ph, _dummy; \
+ size_t _nbits = (nbits); \
+ umul_ppmm (_ph, _dummy, mp_bases[b].logb2, _nbits); \
+ _ph += (_dummy + _nbits < _dummy); \
+ res = _ph + 1; \
+ } while (0)
+#define DIGITS_IN_BASEGT2_FROM_BITS(res, nbits, b) \
+ do { \
+ mp_limb_t _ph, _dummy; \
+ size_t _nbits = (nbits); \
+ umul_ppmm (_ph, _dummy, mp_bases[b].logb2 + 1, _nbits); \
+ res = _ph + 1; \
+ } while (0)
+
+/* For power of 2 bases this is exact. For other bases the result is either
+ exact or one too big.
+
+ To be exact always it'd be necessary to examine all the limbs of the
+ operand, since numbers like 100..000 and 99...999 generally differ only
+ in the lowest limb. It'd be possible to examine just a couple of high
+ limbs to increase the probability of being exact, but that doesn't seem
+ worth bothering with. */
+
+#define MPN_SIZEINBASE(result, ptr, size, base) \
+ do { \
+ int __lb_base, __cnt; \
+ size_t __totbits; \
+ \
+ ASSERT ((size) >= 0); \
+ ASSERT ((base) >= 2); \
+ ASSERT ((base) < numberof (mp_bases)); \
+ \
+ /* Special case for X == 0. */ \
+ if ((size) == 0) \
+ (result) = 1; \
+ else \
+ { \
+ /* Calculate the total number of significant bits of X. */ \
+ count_leading_zeros (__cnt, (ptr)[(size)-1]); \
+ __totbits = (size_t) (size) * GMP_NUMB_BITS - (__cnt - GMP_NAIL_BITS);\
+ \
+ if (POW2_P (base)) \
+ { \
+ __lb_base = mp_bases[base].big_base; \
+ (result) = (__totbits + __lb_base - 1) / __lb_base; \
+ } \
+ else \
+ { \
+ DIGITS_IN_BASEGT2_FROM_BITS (result, __totbits, base); \
+ } \
+ } \
+ } while (0)
+
+#define MPN_SIZEINBASE_2EXP(result, ptr, size, base2exp) \
+ do { \
+ int __cnt; \
+ mp_bitcnt_t __totbits; \
+ ASSERT ((size) > 0); \
+ ASSERT ((ptr)[(size)-1] != 0); \
+ count_leading_zeros (__cnt, (ptr)[(size)-1]); \
+ __totbits = (mp_bitcnt_t) (size) * GMP_NUMB_BITS - (__cnt - GMP_NAIL_BITS); \
+ (result) = (__totbits + (base2exp)-1) / (base2exp); \
+ } while (0)
+
+
+/* bit count to limb count, rounding up */
+#define BITS_TO_LIMBS(n) (((n) + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS)
+
+/* MPN_SET_UI sets an mpn (ptr, cnt) to given ui. MPZ_FAKE_UI creates fake
+ mpz_t from ui. The zp argument must have room for LIMBS_PER_ULONG limbs
+ in both cases (LIMBS_PER_ULONG is also defined here.) */
+#if BITS_PER_ULONG <= GMP_NUMB_BITS /* need one limb per ulong */
+
+#define LIMBS_PER_ULONG 1
+#define MPN_SET_UI(zp, zn, u) \
+ (zp)[0] = (u); \
+ (zn) = ((zp)[0] != 0);
+#define MPZ_FAKE_UI(z, zp, u) \
+ (zp)[0] = (u); \
+ PTR (z) = (zp); \
+ SIZ (z) = ((zp)[0] != 0); \
+ ASSERT_CODE (ALLOC (z) = 1);
+
+#else /* need two limbs per ulong */
+
+#define LIMBS_PER_ULONG 2
+#define MPN_SET_UI(zp, zn, u) \
+ (zp)[0] = (u) & GMP_NUMB_MASK; \
+ (zp)[1] = (u) >> GMP_NUMB_BITS; \
+ (zn) = ((zp)[1] != 0 ? 2 : (zp)[0] != 0 ? 1 : 0);
+#define MPZ_FAKE_UI(z, zp, u) \
+ (zp)[0] = (u) & GMP_NUMB_MASK; \
+ (zp)[1] = (u) >> GMP_NUMB_BITS; \
+ SIZ (z) = ((zp)[1] != 0 ? 2 : (zp)[0] != 0 ? 1 : 0); \
+ PTR (z) = (zp); \
+ ASSERT_CODE (ALLOC (z) = 2);
+
+#endif
+
+
+#if HAVE_HOST_CPU_FAMILY_x86
+#define TARGET_REGISTER_STARVED 1
+#else
+#define TARGET_REGISTER_STARVED 0
+#endif
+
+
+/* LIMB_HIGHBIT_TO_MASK(n) examines the high bit of a limb value and turns 1
+ or 0 there into a limb 0xFF..FF or 0 respectively.
+
+ On most CPUs this is just an arithmetic right shift by GMP_LIMB_BITS-1,
+ but C99 doesn't guarantee signed right shifts are arithmetic, so we have
+ a little compile-time test and a fallback to a "? :" form. The latter is
+ necessary for instance on Cray vector systems.
+
+ Recent versions of gcc (eg. 3.3) will in fact optimize a "? :" like this
+ to an arithmetic right shift anyway, but it's good to get the desired
+ shift on past versions too (in particular since an important use of
+ LIMB_HIGHBIT_TO_MASK is in udiv_qrnnd_preinv). */
+
+#define LIMB_HIGHBIT_TO_MASK(n) \
+ (((mp_limb_signed_t) -1 >> 1) < 0 \
+ ? (mp_limb_signed_t) (n) >> (GMP_LIMB_BITS - 1) \
+ : (n) & GMP_LIMB_HIGHBIT ? MP_LIMB_T_MAX : CNST_LIMB(0))
+
+
+/* Use a library function for invert_limb, if available. */
+#define mpn_invert_limb __MPN(invert_limb)
+__GMP_DECLSPEC mp_limb_t mpn_invert_limb (mp_limb_t) ATTRIBUTE_CONST;
+#if ! defined (invert_limb) && HAVE_NATIVE_mpn_invert_limb
+#define invert_limb(invxl,xl) \
+ do { \
+ (invxl) = mpn_invert_limb (xl); \
+ } while (0)
+#endif
+
+#ifndef invert_limb
+#define invert_limb(invxl,xl) \
+ do { \
+ mp_limb_t _dummy; \
+ ASSERT ((xl) != 0); \
+ udiv_qrnnd (invxl, _dummy, ~(xl), ~CNST_LIMB(0), xl); \
+ } while (0)
+#endif
+
+#define invert_pi1(dinv, d1, d0) \
+ do { \
+ mp_limb_t _v, _p, _t1, _t0, _mask; \
+ invert_limb (_v, d1); \
+ _p = (d1) * _v; \
+ _p += (d0); \
+ if (_p < (d0)) \
+ { \
+ _v--; \
+ _mask = -(mp_limb_t) (_p >= (d1)); \
+ _p -= (d1); \
+ _v += _mask; \
+ _p -= _mask & (d1); \
+ } \
+ umul_ppmm (_t1, _t0, d0, _v); \
+ _p += _t1; \
+ if (_p < _t1) \
+ { \
+ _v--; \
+ if (UNLIKELY (_p >= (d1))) \
+ { \
+ if (_p > (d1) || _t0 >= (d0)) \
+ _v--; \
+ } \
+ } \
+ (dinv).inv32 = _v; \
+ } while (0)
+
+
+/* udiv_qrnnd_preinv -- Based on work by Niels Möller and Torbjörn Granlund.
+ We write things strangely below, to help gcc. A more straightforward
+ version:
+ _r = (nl) - _qh * (d);
+ _t = _r + (d);
+ if (_r >= _ql)
+ {
+ _qh--;
+ _r = _t;
+ }
+ For one operation shorter critical path, one may want to use this form:
+ _p = _qh * (d)
+ _s = (nl) + (d);
+ _r = (nl) - _p;
+ _t = _s - _p;
+ if (_r >= _ql)
+ {
+ _qh--;
+ _r = _t;
+ }
+*/
+#define udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
+ do { \
+ mp_limb_t _qh, _ql, _r, _mask; \
+ umul_ppmm (_qh, _ql, (nh), (di)); \
+ if (__builtin_constant_p (nl) && (nl) == 0) \
+ { \
+ _qh += (nh) + 1; \
+ _r = - _qh * (d); \
+ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \
+ _qh += _mask; \
+ _r += _mask & (d); \
+ } \
+ else \
+ { \
+ add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \
+ _r = (nl) - _qh * (d); \
+ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \
+ _qh += _mask; \
+ _r += _mask & (d); \
+ if (UNLIKELY (_r >= (d))) \
+ { \
+ _r -= (d); \
+ _qh++; \
+ } \
+ } \
+ (r) = _r; \
+ (q) = _qh; \
+ } while (0)
+
+/* Dividing (NH, NL) by D, returning the remainder only. Unlike
+ udiv_qrnnd_preinv, works also for the case NH == D, where the
+ quotient doesn't quite fit in a single limb. */
+#define udiv_rnnd_preinv(r, nh, nl, d, di) \
+ do { \
+ mp_limb_t _qh, _ql, _r, _mask; \
+ umul_ppmm (_qh, _ql, (nh), (di)); \
+ if (__builtin_constant_p (nl) && (nl) == 0) \
+ { \
+ _r = ~(_qh + (nh)) * (d); \
+ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \
+ _r += _mask & (d); \
+ } \
+ else \
+ { \
+ add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \
+ _r = (nl) - _qh * (d); \
+ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \
+ _r += _mask & (d); \
+ if (UNLIKELY (_r >= (d))) \
+ _r -= (d); \
+ } \
+ (r) = _r; \
+ } while (0)
+
+/* Compute quotient the quotient and remainder for n / d. Requires d
+ >= B^2 / 2 and n < d B. di is the inverse
+
+ floor ((B^3 - 1) / (d0 + d1 B)) - B.
+
+ NOTE: Output variables are updated multiple times. Only some inputs
+ and outputs may overlap.
+*/
+#define udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \
+ do { \
+ mp_limb_t _q0, _t1, _t0, _mask; \
+ umul_ppmm ((q), _q0, (n2), (dinv)); \
+ add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \
+ \
+ /* Compute the two most significant limbs of n - q'd */ \
+ (r1) = (n1) - (d1) * (q); \
+ sub_ddmmss ((r1), (r0), (r1), (n0), (d1), (d0)); \
+ umul_ppmm (_t1, _t0, (d0), (q)); \
+ sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \
+ (q)++; \
+ \
+ /* Conditionally adjust q and the remainders */ \
+ _mask = - (mp_limb_t) ((r1) >= _q0); \
+ (q) += _mask; \
+ add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \
+ if (UNLIKELY ((r1) >= (d1))) \
+ { \
+ if ((r1) > (d1) || (r0) >= (d0)) \
+ { \
+ (q)++; \
+ sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \
+ } \
+ } \
+ } while (0)
+
+#ifndef mpn_preinv_divrem_1 /* if not done with cpuvec in a fat binary */
+#define mpn_preinv_divrem_1 __MPN(preinv_divrem_1)
+__GMP_DECLSPEC mp_limb_t mpn_preinv_divrem_1 (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, int);
+#endif
+
+
+/* USE_PREINV_DIVREM_1 is whether to use mpn_preinv_divrem_1, as opposed to the
+ plain mpn_divrem_1. The default is yes, since the few CISC chips where
+ preinv is not good have defines saying so. */
+#ifndef USE_PREINV_DIVREM_1
+#define USE_PREINV_DIVREM_1 1
+#endif
+
+#if USE_PREINV_DIVREM_1
+#define MPN_DIVREM_OR_PREINV_DIVREM_1(qp,xsize,ap,size,d,dinv,shift) \
+ mpn_preinv_divrem_1 (qp, xsize, ap, size, d, dinv, shift)
+#else
+#define MPN_DIVREM_OR_PREINV_DIVREM_1(qp,xsize,ap,size,d,dinv,shift) \
+ mpn_divrem_1 (qp, xsize, ap, size, d)
+#endif
+
+#ifndef PREINV_MOD_1_TO_MOD_1_THRESHOLD
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 10
+#endif
+
+/* This selection may seem backwards. The reason mpn_mod_1 typically takes
+ over for larger sizes is that it uses the mod_1_1 function. */
+#define MPN_MOD_OR_PREINV_MOD_1(src,size,divisor,inverse) \
+ (BELOW_THRESHOLD (size, PREINV_MOD_1_TO_MOD_1_THRESHOLD) \
+ ? mpn_preinv_mod_1 (src, size, divisor, inverse) \
+ : mpn_mod_1 (src, size, divisor))
+
+
+#ifndef mpn_mod_34lsub1 /* if not done with cpuvec in a fat binary */
+#define mpn_mod_34lsub1 __MPN(mod_34lsub1)
+__GMP_DECLSPEC mp_limb_t mpn_mod_34lsub1 (mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE;
+#endif
+
+
+/* DIVEXACT_1_THRESHOLD is at what size to use mpn_divexact_1, as opposed to
+ plain mpn_divrem_1. Likewise BMOD_1_TO_MOD_1_THRESHOLD for
+ mpn_modexact_1_odd against plain mpn_mod_1. On most CPUs divexact and
+ modexact are faster at all sizes, so the defaults are 0. Those CPUs
+ where this is not right have a tuned threshold. */
+#ifndef DIVEXACT_1_THRESHOLD
+#define DIVEXACT_1_THRESHOLD 0
+#endif
+#ifndef BMOD_1_TO_MOD_1_THRESHOLD
+#define BMOD_1_TO_MOD_1_THRESHOLD 10
+#endif
+
+#ifndef mpn_divexact_1 /* if not done with cpuvec in a fat binary */
+#define mpn_divexact_1 __MPN(divexact_1)
+__GMP_DECLSPEC void mpn_divexact_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+#endif
+
+#define MPN_DIVREM_OR_DIVEXACT_1(rp, up, n, d) \
+ do { \
+ if (BELOW_THRESHOLD (n, DIVEXACT_1_THRESHOLD)) \
+ ASSERT_NOCARRY (mpn_divrem_1 (rp, (mp_size_t) 0, up, n, d)); \
+ else \
+ { \
+ ASSERT (mpn_mod_1 (up, n, d) == 0); \
+ mpn_divexact_1 (rp, up, n, d); \
+ } \
+ } while (0)
+
+#ifndef mpn_modexact_1c_odd /* if not done with cpuvec in a fat binary */
+#define mpn_modexact_1c_odd __MPN(modexact_1c_odd)
+__GMP_DECLSPEC mp_limb_t mpn_modexact_1c_odd (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t) __GMP_ATTRIBUTE_PURE;
+#endif
+
+#if HAVE_NATIVE_mpn_modexact_1_odd
+#define mpn_modexact_1_odd __MPN(modexact_1_odd)
+__GMP_DECLSPEC mp_limb_t mpn_modexact_1_odd (mp_srcptr, mp_size_t, mp_limb_t) __GMP_ATTRIBUTE_PURE;
+#else
+#define mpn_modexact_1_odd(src,size,divisor) \
+ mpn_modexact_1c_odd (src, size, divisor, CNST_LIMB(0))
+#endif
+
+#define MPN_MOD_OR_MODEXACT_1_ODD(src,size,divisor) \
+ (BELOW_THRESHOLD (size, BMOD_1_TO_MOD_1_THRESHOLD) \
+ ? mpn_modexact_1_odd (src, size, divisor) \
+ : mpn_mod_1 (src, size, divisor))
+
+/* binvert_limb() sets inv to the multiplicative inverse of n modulo
+ 2^GMP_NUMB_BITS, ie. satisfying inv*n == 1 mod 2^GMP_NUMB_BITS.
+ n must be odd (otherwise such an inverse doesn't exist).
+
+ This is not to be confused with invert_limb(), which is completely
+ different.
+
+ The table lookup gives an inverse with the low 8 bits valid, and each
+ multiply step doubles the number of bits. See Jebelean "An algorithm for
+ exact division" end of section 4 (reference in gmp.texi).
+
+ Possible enhancement: Could use UHWtype until the last step, if half-size
+ multiplies are faster (might help under _LONG_LONG_LIMB).
+
+ Alternative: As noted in Granlund and Montgomery "Division by Invariant
+ Integers using Multiplication" (reference in gmp.texi), n itself gives a
+ 3-bit inverse immediately, and could be used instead of a table lookup.
+ A 4-bit inverse can be obtained effectively from xoring bits 1 and 2 into
+ bit 3, for instance with (((n + 2) & 4) << 1) ^ n. */
+
+#define binvert_limb_table __gmp_binvert_limb_table
+__GMP_DECLSPEC extern const unsigned char binvert_limb_table[128];
+
+#define binvert_limb(inv,n) \
+ do { \
+ mp_limb_t __n = (n); \
+ mp_limb_t __inv; \
+ ASSERT ((__n & 1) == 1); \
+ \
+ __inv = binvert_limb_table[(__n/2) & 0x7F]; /* 8 */ \
+ if (GMP_NUMB_BITS > 8) __inv = 2 * __inv - __inv * __inv * __n; \
+ if (GMP_NUMB_BITS > 16) __inv = 2 * __inv - __inv * __inv * __n; \
+ if (GMP_NUMB_BITS > 32) __inv = 2 * __inv - __inv * __inv * __n; \
+ \
+ if (GMP_NUMB_BITS > 64) \
+ { \
+ int __invbits = 64; \
+ do { \
+ __inv = 2 * __inv - __inv * __inv * __n; \
+ __invbits *= 2; \
+ } while (__invbits < GMP_NUMB_BITS); \
+ } \
+ \
+ ASSERT ((__inv * __n & GMP_NUMB_MASK) == 1); \
+ (inv) = __inv & GMP_NUMB_MASK; \
+ } while (0)
+#define modlimb_invert binvert_limb /* backward compatibility */
+
+/* Multiplicative inverse of 3, modulo 2^GMP_NUMB_BITS.
+ Eg. 0xAAAAAAAB for 32 bits, 0xAAAAAAAAAAAAAAAB for 64 bits.
+ GMP_NUMB_MAX/3*2+1 is right when GMP_NUMB_BITS is even, but when it's odd
+ we need to start from GMP_NUMB_MAX>>1. */
+#define MODLIMB_INVERSE_3 (((GMP_NUMB_MAX >> (GMP_NUMB_BITS % 2)) / 3) * 2 + 1)
+
+/* ceil(GMP_NUMB_MAX/3) and ceil(2*GMP_NUMB_MAX/3).
+ These expressions work because GMP_NUMB_MAX%3 != 0 for all GMP_NUMB_BITS. */
+#define GMP_NUMB_CEIL_MAX_DIV3 (GMP_NUMB_MAX / 3 + 1)
+#define GMP_NUMB_CEIL_2MAX_DIV3 ((GMP_NUMB_MAX>>1) / 3 + 1 + GMP_NUMB_HIGHBIT)
+
+
+/* Set r to -a mod d. a>=d is allowed. Can give r>d. All should be limbs.
+
+ It's not clear whether this is the best way to do this calculation.
+ Anything congruent to -a would be fine for the one limb congruence
+ tests. */
+
+#define NEG_MOD(r, a, d) \
+ do { \
+ ASSERT ((d) != 0); \
+ ASSERT_LIMB (a); \
+ ASSERT_LIMB (d); \
+ \
+ if ((a) <= (d)) \
+ { \
+ /* small a is reasonably likely */ \
+ (r) = (d) - (a); \
+ } \
+ else \
+ { \
+ unsigned __twos; \
+ mp_limb_t __dnorm; \
+ count_leading_zeros (__twos, d); \
+ __twos -= GMP_NAIL_BITS; \
+ __dnorm = (d) << __twos; \
+ (r) = ((a) <= __dnorm ? __dnorm : 2*__dnorm) - (a); \
+ } \
+ \
+ ASSERT_LIMB (r); \
+ } while (0)
+
+/* A bit mask of all the least significant zero bits of n, or -1 if n==0. */
+#define LOW_ZEROS_MASK(n) (((n) & -(n)) - 1)
+
+
+/* ULONG_PARITY sets "p" to 1 if there's an odd number of 1 bits in "n", or
+ to 0 if there's an even number. "n" should be an unsigned long and "p"
+ an int. */
+
+#if defined (__GNUC__) && ! defined (NO_ASM) && HAVE_HOST_CPU_alpha_CIX
+#define ULONG_PARITY(p, n) \
+ do { \
+ int __p; \
+ __asm__ ("ctpop %1, %0" : "=r" (__p) : "r" (n)); \
+ (p) = __p & 1; \
+ } while (0)
+#endif
+
+/* Cray intrinsic _popcnt. */
+#ifdef _CRAY
+#define ULONG_PARITY(p, n) \
+ do { \
+ (p) = _popcnt (n) & 1; \
+ } while (0)
+#endif
+
+#if defined (__GNUC__) && ! defined (__INTEL_COMPILER) \
+ && ! defined (NO_ASM) && defined (__ia64)
+/* unsigned long is either 32 or 64 bits depending on the ABI, zero extend
+ to a 64 bit unsigned long long for popcnt */
+#define ULONG_PARITY(p, n) \
+ do { \
+ unsigned long long __n = (unsigned long) (n); \
+ int __p; \
+ __asm__ ("popcnt %0 = %1" : "=r" (__p) : "r" (__n)); \
+ (p) = __p & 1; \
+ } while (0)
+#endif
+
+#if defined (__GNUC__) && ! defined (__INTEL_COMPILER) \
+ && ! defined (NO_ASM) && HAVE_HOST_CPU_FAMILY_x86
+#if __GMP_GNUC_PREREQ (3,1)
+#define __GMP_qm "=Qm"
+#define __GMP_q "=Q"
+#else
+#define __GMP_qm "=qm"
+#define __GMP_q "=q"
+#endif
+#define ULONG_PARITY(p, n) \
+ do { \
+ char __p; \
+ unsigned long __n = (n); \
+ __n ^= (__n >> 16); \
+ __asm__ ("xorb %h1, %b1\n\t" \
+ "setpo %0" \
+ : __GMP_qm (__p), __GMP_q (__n) \
+ : "1" (__n)); \
+ (p) = __p; \
+ } while (0)
+#endif
+
+#if ! defined (ULONG_PARITY)
+#define ULONG_PARITY(p, n) \
+ do { \
+ unsigned long __n = (n); \
+ int __p = 0; \
+ do \
+ { \
+ __p ^= 0x96696996L >> (__n & 0x1F); \
+ __n >>= 5; \
+ } \
+ while (__n != 0); \
+ \
+ (p) = __p & 1; \
+ } while (0)
+#endif
+
+
+/* 3 cycles on 604 or 750 since shifts and rlwimi's can pair. gcc (as of
+ version 3.1 at least) doesn't seem to know how to generate rlwimi for
+ anything other than bit-fields, so use "asm". */
+#if defined (__GNUC__) && ! defined (NO_ASM) \
+ && HAVE_HOST_CPU_FAMILY_powerpc && GMP_LIMB_BITS == 32
+#define BSWAP_LIMB(dst, src) \
+ do { \
+ mp_limb_t __bswapl_src = (src); \
+ mp_limb_t __tmp1 = __bswapl_src >> 24; /* low byte */ \
+ mp_limb_t __tmp2 = __bswapl_src << 24; /* high byte */ \
+ __asm__ ("rlwimi %0, %2, 24, 16, 23" /* 2nd low */ \
+ : "=r" (__tmp1) : "0" (__tmp1), "r" (__bswapl_src)); \
+ __asm__ ("rlwimi %0, %2, 8, 8, 15" /* 3nd high */ \
+ : "=r" (__tmp2) : "0" (__tmp2), "r" (__bswapl_src)); \
+ (dst) = __tmp1 | __tmp2; /* whole */ \
+ } while (0)
+#endif
+
+/* bswap is available on i486 and up and is fast. A combination rorw $8 /
+ roll $16 / rorw $8 is used in glibc for plain i386 (and in the linux
+ kernel with xchgb instead of rorw), but this is not done here, because
+ i386 means generic x86 and mixing word and dword operations will cause
+ partial register stalls on P6 chips. */
+#if defined (__GNUC__) && ! defined (NO_ASM) \
+ && HAVE_HOST_CPU_FAMILY_x86 && ! HAVE_HOST_CPU_i386 \
+ && GMP_LIMB_BITS == 32
+#define BSWAP_LIMB(dst, src) \
+ do { \
+ __asm__ ("bswap %0" : "=r" (dst) : "0" (src)); \
+ } while (0)
+#endif
+
+#if defined (__GNUC__) && ! defined (NO_ASM) \
+ && defined (__amd64__) && GMP_LIMB_BITS == 64
+#define BSWAP_LIMB(dst, src) \
+ do { \
+ __asm__ ("bswap %q0" : "=r" (dst) : "0" (src)); \
+ } while (0)
+#endif
+
+#if defined (__GNUC__) && ! defined (__INTEL_COMPILER) \
+ && ! defined (NO_ASM) && defined (__ia64) && GMP_LIMB_BITS == 64
+#define BSWAP_LIMB(dst, src) \
+ do { \
+ __asm__ ("mux1 %0 = %1, @rev" : "=r" (dst) : "r" (src)); \
+ } while (0)
+#endif
+
+/* As per glibc. */
+#if defined (__GNUC__) && ! defined (NO_ASM) \
+ && HAVE_HOST_CPU_FAMILY_m68k && GMP_LIMB_BITS == 32
+#define BSWAP_LIMB(dst, src) \
+ do { \
+ mp_limb_t __bswapl_src = (src); \
+ __asm__ ("ror%.w %#8, %0\n\t" \
+ "swap %0\n\t" \
+ "ror%.w %#8, %0" \
+ : "=d" (dst) \
+ : "0" (__bswapl_src)); \
+ } while (0)
+#endif
+
+#if ! defined (BSWAP_LIMB)
+#if GMP_LIMB_BITS == 8
+#define BSWAP_LIMB(dst, src) \
+ do { (dst) = (src); } while (0)
+#endif
+#if GMP_LIMB_BITS == 16
+#define BSWAP_LIMB(dst, src) \
+ do { \
+ (dst) = ((src) << 8) + ((src) >> 8); \
+ } while (0)
+#endif
+#if GMP_LIMB_BITS == 32
+#define BSWAP_LIMB(dst, src) \
+ do { \
+ (dst) = \
+ ((src) << 24) \
+ + (((src) & 0xFF00) << 8) \
+ + (((src) >> 8) & 0xFF00) \
+ + ((src) >> 24); \
+ } while (0)
+#endif
+#if GMP_LIMB_BITS == 64
+#define BSWAP_LIMB(dst, src) \
+ do { \
+ (dst) = \
+ ((src) << 56) \
+ + (((src) & 0xFF00) << 40) \
+ + (((src) & 0xFF0000) << 24) \
+ + (((src) & 0xFF000000) << 8) \
+ + (((src) >> 8) & 0xFF000000) \
+ + (((src) >> 24) & 0xFF0000) \
+ + (((src) >> 40) & 0xFF00) \
+ + ((src) >> 56); \
+ } while (0)
+#endif
+#endif
+
+#if ! defined (BSWAP_LIMB)
+#define BSWAP_LIMB(dst, src) \
+ do { \
+ mp_limb_t __bswapl_src = (src); \
+ mp_limb_t __dstl = 0; \
+ int __i; \
+ for (__i = 0; __i < GMP_LIMB_BYTES; __i++) \
+ { \
+ __dstl = (__dstl << 8) | (__bswapl_src & 0xFF); \
+ __bswapl_src >>= 8; \
+ } \
+ (dst) = __dstl; \
+ } while (0)
+#endif
+
+
+/* Apparently lwbrx might be slow on some PowerPC chips, so restrict it to
+ those we know are fast. */
+#if defined (__GNUC__) && ! defined (NO_ASM) \
+ && GMP_LIMB_BITS == 32 && HAVE_LIMB_BIG_ENDIAN \
+ && (HAVE_HOST_CPU_powerpc604 \
+ || HAVE_HOST_CPU_powerpc604e \
+ || HAVE_HOST_CPU_powerpc750 \
+ || HAVE_HOST_CPU_powerpc7400)
+#define BSWAP_LIMB_FETCH(limb, src) \
+ do { \
+ mp_srcptr __blf_src = (src); \
+ mp_limb_t __limb; \
+ __asm__ ("lwbrx %0, 0, %1" \
+ : "=r" (__limb) \
+ : "r" (__blf_src), \
+ "m" (*__blf_src)); \
+ (limb) = __limb; \
+ } while (0)
+#endif
+
+#if ! defined (BSWAP_LIMB_FETCH)
+#define BSWAP_LIMB_FETCH(limb, src) BSWAP_LIMB (limb, *(src))
+#endif
+
+
+/* On the same basis that lwbrx might be slow, restrict stwbrx to those we
+ know are fast. FIXME: Is this necessary? */
+#if defined (__GNUC__) && ! defined (NO_ASM) \
+ && GMP_LIMB_BITS == 32 && HAVE_LIMB_BIG_ENDIAN \
+ && (HAVE_HOST_CPU_powerpc604 \
+ || HAVE_HOST_CPU_powerpc604e \
+ || HAVE_HOST_CPU_powerpc750 \
+ || HAVE_HOST_CPU_powerpc7400)
+#define BSWAP_LIMB_STORE(dst, limb) \
+ do { \
+ mp_ptr __dst = (dst); \
+ mp_limb_t __limb = (limb); \
+ __asm__ ("stwbrx %1, 0, %2" \
+ : "=m" (*__dst) \
+ : "r" (__limb), \
+ "r" (__dst)); \
+ } while (0)
+#endif
+
+#if ! defined (BSWAP_LIMB_STORE)
+#define BSWAP_LIMB_STORE(dst, limb) BSWAP_LIMB (*(dst), limb)
+#endif
+
+
+/* Byte swap limbs from {src,size} and store at {dst,size}. */
+#define MPN_BSWAP(dst, src, size) \
+ do { \
+ mp_ptr __dst = (dst); \
+ mp_srcptr __src = (src); \
+ mp_size_t __size = (size); \
+ mp_size_t __i; \
+ ASSERT ((size) >= 0); \
+ ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, size)); \
+ CRAY_Pragma ("_CRI ivdep"); \
+ for (__i = 0; __i < __size; __i++) \
+ { \
+ BSWAP_LIMB_FETCH (*__dst, __src); \
+ __dst++; \
+ __src++; \
+ } \
+ } while (0)
+
+/* Byte swap limbs from {dst,size} and store in reverse order at {src,size}. */
+#define MPN_BSWAP_REVERSE(dst, src, size) \
+ do { \
+ mp_ptr __dst = (dst); \
+ mp_size_t __size = (size); \
+ mp_srcptr __src = (src) + __size - 1; \
+ mp_size_t __i; \
+ ASSERT ((size) >= 0); \
+ ASSERT (! MPN_OVERLAP_P (dst, size, src, size)); \
+ CRAY_Pragma ("_CRI ivdep"); \
+ for (__i = 0; __i < __size; __i++) \
+ { \
+ BSWAP_LIMB_FETCH (*__dst, __src); \
+ __dst++; \
+ __src--; \
+ } \
+ } while (0)
+
+
+/* No processor claiming to be SPARC v9 compliant seems to
+ implement the POPC instruction. Disable pattern for now. */
+#if 0
+#if defined __GNUC__ && defined __sparc_v9__ && GMP_LIMB_BITS == 64
+#define popc_limb(result, input) \
+ do { \
+ DItype __res; \
+ __asm__ ("popc %1,%0" : "=r" (result) : "rI" (input)); \
+ } while (0)
+#endif
+#endif
+
+#if defined (__GNUC__) && ! defined (NO_ASM) && HAVE_HOST_CPU_alpha_CIX
+#define popc_limb(result, input) \
+ do { \
+ __asm__ ("ctpop %1, %0" : "=r" (result) : "r" (input)); \
+ } while (0)
+#endif
+
+/* Cray intrinsic. */
+#ifdef _CRAY
+#define popc_limb(result, input) \
+ do { \
+ (result) = _popcnt (input); \
+ } while (0)
+#endif
+
+#if defined (__GNUC__) && ! defined (__INTEL_COMPILER) \
+ && ! defined (NO_ASM) && defined (__ia64) && GMP_LIMB_BITS == 64
+#define popc_limb(result, input) \
+ do { \
+ __asm__ ("popcnt %0 = %1" : "=r" (result) : "r" (input)); \
+ } while (0)
+#endif
+
+/* Cool population count of an mp_limb_t.
+ You have to figure out how this works, We won't tell you!
+
+ The constants could also be expressed as:
+ 0x55... = [2^N / 3] = [(2^N-1)/3]
+ 0x33... = [2^N / 5] = [(2^N-1)/5]
+ 0x0f... = [2^N / 17] = [(2^N-1)/17]
+ (N is GMP_LIMB_BITS, [] denotes truncation.) */
+
+#if ! defined (popc_limb) && GMP_LIMB_BITS == 8
+#define popc_limb(result, input) \
+ do { \
+ mp_limb_t __x = (input); \
+ __x -= (__x >> 1) & MP_LIMB_T_MAX/3; \
+ __x = ((__x >> 2) & MP_LIMB_T_MAX/5) + (__x & MP_LIMB_T_MAX/5); \
+ __x = ((__x >> 4) + __x); \
+ (result) = __x & 0x0f; \
+ } while (0)
+#endif
+
+#if ! defined (popc_limb) && GMP_LIMB_BITS == 16
+#define popc_limb(result, input) \
+ do { \
+ mp_limb_t __x = (input); \
+ __x -= (__x >> 1) & MP_LIMB_T_MAX/3; \
+ __x = ((__x >> 2) & MP_LIMB_T_MAX/5) + (__x & MP_LIMB_T_MAX/5); \
+ __x = ((__x >> 4) + __x) & MP_LIMB_T_MAX/17; \
+ __x = ((__x >> 8) + __x); \
+ (result) = __x & 0xff; \
+ } while (0)
+#endif
+
+#if ! defined (popc_limb) && GMP_LIMB_BITS == 32
+#define popc_limb(result, input) \
+ do { \
+ mp_limb_t __x = (input); \
+ __x -= (__x >> 1) & MP_LIMB_T_MAX/3; \
+ __x = ((__x >> 2) & MP_LIMB_T_MAX/5) + (__x & MP_LIMB_T_MAX/5); \
+ __x = ((__x >> 4) + __x) & MP_LIMB_T_MAX/17; \
+ __x = ((__x >> 8) + __x); \
+ __x = ((__x >> 16) + __x); \
+ (result) = __x & 0xff; \
+ } while (0)
+#endif
+
+#if ! defined (popc_limb) && GMP_LIMB_BITS == 64
+#define popc_limb(result, input) \
+ do { \
+ mp_limb_t __x = (input); \
+ __x -= (__x >> 1) & MP_LIMB_T_MAX/3; \
+ __x = ((__x >> 2) & MP_LIMB_T_MAX/5) + (__x & MP_LIMB_T_MAX/5); \
+ __x = ((__x >> 4) + __x) & MP_LIMB_T_MAX/17; \
+ __x = ((__x >> 8) + __x); \
+ __x = ((__x >> 16) + __x); \
+ __x = ((__x >> 32) + __x); \
+ (result) = __x & 0xff; \
+ } while (0)
+#endif
+
+
+/* Define stuff for longlong.h. */
+#if HAVE_ATTRIBUTE_MODE
+typedef unsigned int UQItype __attribute__ ((mode (QI)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+#else
+typedef unsigned char UQItype;
+typedef long SItype;
+typedef unsigned long USItype;
+#if HAVE_LONG_LONG
+typedef long long int DItype;
+typedef unsigned long long int UDItype;
+#else /* Assume `long' gives us a wide enough type. Needed for hppa2.0w. */
+typedef long int DItype;
+typedef unsigned long int UDItype;
+#endif
+#endif
+
+typedef mp_limb_t UWtype;
+typedef unsigned int UHWtype;
+#define W_TYPE_SIZE GMP_LIMB_BITS
+
+/* Define ieee_double_extract and _GMP_IEEE_FLOATS.
+
+ Bit field packing is "implementation defined" according to C99, which
+ leaves us at the compiler's mercy here. For some systems packing is
+ defined in the ABI (eg. x86). In any case so far it seems universal that
+ little endian systems pack from low to high, and big endian from high to
+ low within the given type.
+
+ Within the fields we rely on the integer endianness being the same as the
+ float endianness, this is true everywhere we know of and it'd be a fairly
+ strange system that did anything else. */
+
+#if HAVE_DOUBLE_IEEE_LITTLE_SWAPPED
+#define _GMP_IEEE_FLOATS 1
+union ieee_double_extract
+{
+ struct
+ {
+ gmp_uint_least32_t manh:20;
+ gmp_uint_least32_t exp:11;
+ gmp_uint_least32_t sig:1;
+ gmp_uint_least32_t manl:32;
+ } s;
+ double d;
+};
+#endif
+
+#if HAVE_DOUBLE_IEEE_LITTLE_ENDIAN
+#define _GMP_IEEE_FLOATS 1
+union ieee_double_extract
+{
+ struct
+ {
+ gmp_uint_least32_t manl:32;
+ gmp_uint_least32_t manh:20;
+ gmp_uint_least32_t exp:11;
+ gmp_uint_least32_t sig:1;
+ } s;
+ double d;
+};
+#endif
+
+#if HAVE_DOUBLE_IEEE_BIG_ENDIAN
+#define _GMP_IEEE_FLOATS 1
+union ieee_double_extract
+{
+ struct
+ {
+ gmp_uint_least32_t sig:1;
+ gmp_uint_least32_t exp:11;
+ gmp_uint_least32_t manh:20;
+ gmp_uint_least32_t manl:32;
+ } s;
+ double d;
+};
+#endif
+
+#if HAVE_DOUBLE_VAX_D
+union double_extract
+{
+ struct
+ {
+ gmp_uint_least32_t man3:7; /* highest 7 bits */
+ gmp_uint_least32_t exp:8; /* excess-128 exponent */
+ gmp_uint_least32_t sig:1;
+ gmp_uint_least32_t man2:16;
+ gmp_uint_least32_t man1:16;
+ gmp_uint_least32_t man0:16; /* lowest 16 bits */
+ } s;
+ double d;
+};
+#endif
+
+/* Use (4.0 * ...) instead of (2.0 * ...) to work around buggy compilers
+ that don't convert ulong->double correctly (eg. SunOS 4 native cc). */
+#define MP_BASE_AS_DOUBLE (4.0 * ((mp_limb_t) 1 << (GMP_NUMB_BITS - 2)))
+/* Maximum number of limbs it will take to store any `double'.
+ We assume doubles have 53 mantissa bits. */
+#define LIMBS_PER_DOUBLE ((53 + GMP_NUMB_BITS - 2) / GMP_NUMB_BITS + 1)
+
+__GMP_DECLSPEC int __gmp_extract_double (mp_ptr, double);
+
+#define mpn_get_d __gmpn_get_d
+__GMP_DECLSPEC double mpn_get_d (mp_srcptr, mp_size_t, mp_size_t, long) __GMP_ATTRIBUTE_PURE;
+
+
+/* DOUBLE_NAN_INF_ACTION executes code a_nan if x is a NaN, or executes
+ a_inf if x is an infinity. Both are considered unlikely values, for
+ branch prediction. */
+
+#if _GMP_IEEE_FLOATS
+#define DOUBLE_NAN_INF_ACTION(x, a_nan, a_inf) \
+ do { \
+ union ieee_double_extract u; \
+ u.d = (x); \
+ if (UNLIKELY (u.s.exp == 0x7FF)) \
+ { \
+ if (u.s.manl == 0 && u.s.manh == 0) \
+ { a_inf; } \
+ else \
+ { a_nan; } \
+ } \
+ } while (0)
+#endif
+
+#if HAVE_DOUBLE_VAX_D || HAVE_DOUBLE_VAX_G || HAVE_DOUBLE_CRAY_CFP
+/* no nans or infs in these formats */
+#define DOUBLE_NAN_INF_ACTION(x, a_nan, a_inf) \
+ do { } while (0)
+#endif
+
+#ifndef DOUBLE_NAN_INF_ACTION
+/* Unknown format, try something generic.
+ NaN should be "unordered", so x!=x.
+ Inf should be bigger than DBL_MAX. */
+#define DOUBLE_NAN_INF_ACTION(x, a_nan, a_inf) \
+ do { \
+ { \
+ if (UNLIKELY ((x) != (x))) \
+ { a_nan; } \
+ else if (UNLIKELY ((x) > DBL_MAX || (x) < -DBL_MAX)) \
+ { a_inf; } \
+ } \
+ } while (0)
+#endif
+
+/* On m68k, x86 and amd64, gcc (and maybe other compilers) can hold doubles
+ in the coprocessor, which means a bigger exponent range than normal, and
+ depending on the rounding mode, a bigger mantissa than normal. (See
+ "Disappointments" in the gcc manual.) FORCE_DOUBLE stores and fetches
+ "d" through memory to force any rounding and overflows to occur.
+
+ On amd64, and on x86s with SSE2, gcc (depending on options) uses the xmm
+ registers, where there's no such extra precision and no need for the
+ FORCE_DOUBLE. We don't bother to detect this since the present uses for
+ FORCE_DOUBLE are only in test programs and default generic C code.
+
+ Not quite sure that an "automatic volatile" will use memory, but it does
+ in gcc. An asm("":"=m"(d):"0"(d)) can't be used to trick gcc, since
+ apparently matching operands like "0" are only allowed on a register
+ output. gcc 3.4 warns about this, though in fact it and past versions
+ seem to put the operand through memory as hoped. */
+
+#if (HAVE_HOST_CPU_FAMILY_m68k || HAVE_HOST_CPU_FAMILY_x86 \
+ || defined (__amd64__))
+#define FORCE_DOUBLE(d) \
+ do { volatile double __gmp_force = (d); (d) = __gmp_force; } while (0)
+#else
+#define FORCE_DOUBLE(d) do { } while (0)
+#endif
+
+
+__GMP_DECLSPEC extern const unsigned char __gmp_digit_value_tab[];
+
+__GMP_DECLSPEC extern int __gmp_junk;
+__GMP_DECLSPEC extern const int __gmp_0;
+__GMP_DECLSPEC void __gmp_exception (int) ATTRIBUTE_NORETURN;
+__GMP_DECLSPEC void __gmp_divide_by_zero (void) ATTRIBUTE_NORETURN;
+__GMP_DECLSPEC void __gmp_sqrt_of_negative (void) ATTRIBUTE_NORETURN;
+__GMP_DECLSPEC void __gmp_invalid_operation (void) ATTRIBUTE_NORETURN;
+#define GMP_ERROR(code) __gmp_exception (code)
+#define DIVIDE_BY_ZERO __gmp_divide_by_zero ()
+#define SQRT_OF_NEGATIVE __gmp_sqrt_of_negative ()
+
+#if defined _LONG_LONG_LIMB
+#define CNST_LIMB(C) ((mp_limb_t) C##LL)
+#else /* not _LONG_LONG_LIMB */
+#define CNST_LIMB(C) ((mp_limb_t) C##L)
+#endif /* _LONG_LONG_LIMB */
+
+/* Stuff used by mpn/generic/perfsqr.c and mpz/prime_p.c */
+#if GMP_NUMB_BITS == 2
+#define PP 0x3 /* 3 */
+#define PP_FIRST_OMITTED 5
+#endif
+#if GMP_NUMB_BITS == 4
+#define PP 0xF /* 3 x 5 */
+#define PP_FIRST_OMITTED 7
+#endif
+#if GMP_NUMB_BITS == 8
+#define PP 0x69 /* 3 x 5 x 7 */
+#define PP_FIRST_OMITTED 11
+#endif
+#if GMP_NUMB_BITS == 16
+#define PP 0x3AA7 /* 3 x 5 x 7 x 11 x 13 */
+#define PP_FIRST_OMITTED 17
+#endif
+#if GMP_NUMB_BITS == 32
+#define PP 0xC0CFD797L /* 3 x 5 x 7 x 11 x ... x 29 */
+#define PP_INVERTED 0x53E5645CL
+#define PP_FIRST_OMITTED 31
+#endif
+#if GMP_NUMB_BITS == 64
+#define PP CNST_LIMB(0xE221F97C30E94E1D) /* 3 x 5 x 7 x 11 x ... x 53 */
+#define PP_INVERTED CNST_LIMB(0x21CFE6CFC938B36B)
+#define PP_FIRST_OMITTED 59
+#endif
+#ifndef PP_FIRST_OMITTED
+#define PP_FIRST_OMITTED 3
+#endif
+
+/* BIT1 means a result value in bit 1 (second least significant bit), with a
+ zero bit representing +1 and a one bit representing -1. Bits other than
+ bit 1 are garbage. These are meant to be kept in "int"s, and casts are
+ used to ensure the expressions are "int"s even if a and/or b might be
+ other types.
+
+ JACOBI_TWOS_U_BIT1 and JACOBI_RECIP_UU_BIT1 are used in mpn_jacobi_base
+ and their speed is important. Expressions are used rather than
+ conditionals to accumulate sign changes, which effectively means XORs
+ instead of conditional JUMPs. */
+
+/* (a/0), with a signed; is 1 if a=+/-1, 0 otherwise */
+#define JACOBI_S0(a) (((a) == 1) | ((a) == -1))
+
+/* (a/0), with a unsigned; is 1 if a=+/-1, 0 otherwise */
+#define JACOBI_U0(a) ((a) == 1)
+
+/* FIXME: JACOBI_LS0 and JACOBI_0LS are the same, so delete one and
+ come up with a better name. */
+
+/* (a/0), with a given by low and size;
+ is 1 if a=+/-1, 0 otherwise */
+#define JACOBI_LS0(alow,asize) \
+ (((asize) == 1 || (asize) == -1) && (alow) == 1)
+
+/* (a/0), with a an mpz_t;
+ fetch of low limb always valid, even if size is zero */
+#define JACOBI_Z0(a) JACOBI_LS0 (PTR(a)[0], SIZ(a))
+
+/* (0/b), with b unsigned; is 1 if b=1, 0 otherwise */
+#define JACOBI_0U(b) ((b) == 1)
+
+/* (0/b), with b unsigned; is 1 if b=+/-1, 0 otherwise */
+#define JACOBI_0S(b) ((b) == 1 || (b) == -1)
+
+/* (0/b), with b given by low and size; is 1 if b=+/-1, 0 otherwise */
+#define JACOBI_0LS(blow,bsize) \
+ (((bsize) == 1 || (bsize) == -1) && (blow) == 1)
+
+/* Convert a bit1 to +1 or -1. */
+#define JACOBI_BIT1_TO_PN(result_bit1) \
+ (1 - ((int) (result_bit1) & 2))
+
+/* (2/b), with b unsigned and odd;
+ is (-1)^((b^2-1)/8) which is 1 if b==1,7mod8 or -1 if b==3,5mod8 and
+ hence obtained from (b>>1)^b */
+#define JACOBI_TWO_U_BIT1(b) \
+ ((int) (((b) >> 1) ^ (b)))
+
+/* (2/b)^twos, with b unsigned and odd */
+#define JACOBI_TWOS_U_BIT1(twos, b) \
+ ((int) ((twos) << 1) & JACOBI_TWO_U_BIT1 (b))
+
+/* (2/b)^twos, with b unsigned and odd */
+#define JACOBI_TWOS_U(twos, b) \
+ (JACOBI_BIT1_TO_PN (JACOBI_TWOS_U_BIT1 (twos, b)))
+
+/* (-1/b), with b odd (signed or unsigned);
+ is (-1)^((b-1)/2) */
+#define JACOBI_N1B_BIT1(b) \
+ ((int) (b))
+
+/* (a/b) effect due to sign of a: signed/unsigned, b odd;
+ is (-1/b) if a<0, or +1 if a>=0 */
+#define JACOBI_ASGN_SU_BIT1(a, b) \
+ ((((a) < 0) << 1) & JACOBI_N1B_BIT1(b))
+
+/* (a/b) effect due to sign of b: signed/signed;
+ is -1 if a and b both negative, +1 otherwise */
+#define JACOBI_BSGN_SS_BIT1(a, b) \
+ ((((a)<0) & ((b)<0)) << 1)
+
+/* (a/b) effect due to sign of b: signed/mpz;
+ is -1 if a and b both negative, +1 otherwise */
+#define JACOBI_BSGN_SZ_BIT1(a, b) \
+ JACOBI_BSGN_SS_BIT1 (a, SIZ(b))
+
+/* (a/b) effect due to sign of b: mpz/signed;
+ is -1 if a and b both negative, +1 otherwise */
+#define JACOBI_BSGN_ZS_BIT1(a, b) \
+ JACOBI_BSGN_SZ_BIT1 (b, a)
+
+/* (a/b) reciprocity to switch to (b/a), a,b both unsigned and odd;
+ is (-1)^((a-1)*(b-1)/4), which means +1 if either a,b==1mod4, or -1 if
+ both a,b==3mod4, achieved in bit 1 by a&b. No ASSERT()s about a,b odd
+ because this is used in a couple of places with only bit 1 of a or b
+ valid. */
+#define JACOBI_RECIP_UU_BIT1(a, b) \
+ ((int) ((a) & (b)))
+
+/* Strip low zero limbs from {b_ptr,b_size} by incrementing b_ptr and
+ decrementing b_size. b_low should be b_ptr[0] on entry, and will be
+ updated for the new b_ptr. result_bit1 is updated according to the
+ factors of 2 stripped, as per (a/2). */
+#define JACOBI_STRIP_LOW_ZEROS(result_bit1, a, b_ptr, b_size, b_low) \
+ do { \
+ ASSERT ((b_size) >= 1); \
+ ASSERT ((b_low) == (b_ptr)[0]); \
+ \
+ while (UNLIKELY ((b_low) == 0)) \
+ { \
+ (b_size)--; \
+ ASSERT ((b_size) >= 1); \
+ (b_ptr)++; \
+ (b_low) = *(b_ptr); \
+ \
+ ASSERT (((a) & 1) != 0); \
+ if ((GMP_NUMB_BITS % 2) == 1) \
+ (result_bit1) ^= JACOBI_TWO_U_BIT1(a); \
+ } \
+ } while (0)
+
+/* Set a_rem to {a_ptr,a_size} reduced modulo b, either using mod_1 or
+ modexact_1_odd, but in either case leaving a_rem<b. b must be odd and
+ unsigned. modexact_1_odd effectively calculates -a mod b, and
+ result_bit1 is adjusted for the factor of -1.
+
+ The way mpn_modexact_1_odd sometimes bases its remainder on a_size and
+ sometimes on a_size-1 means if GMP_NUMB_BITS is odd we can't know what
+ factor to introduce into result_bit1, so for that case use mpn_mod_1
+ unconditionally.
+
+ FIXME: mpn_modexact_1_odd is more efficient, so some way to get it used
+ for odd GMP_NUMB_BITS would be good. Perhaps it could mung its result,
+ or not skip a divide step, or something. */
+
+#define JACOBI_MOD_OR_MODEXACT_1_ODD(result_bit1, a_rem, a_ptr, a_size, b) \
+ do { \
+ mp_srcptr __a_ptr = (a_ptr); \
+ mp_size_t __a_size = (a_size); \
+ mp_limb_t __b = (b); \
+ \
+ ASSERT (__a_size >= 1); \
+ ASSERT (__b & 1); \
+ \
+ if ((GMP_NUMB_BITS % 2) != 0 \
+ || ABOVE_THRESHOLD (__a_size, BMOD_1_TO_MOD_1_THRESHOLD)) \
+ { \
+ (a_rem) = mpn_mod_1 (__a_ptr, __a_size, __b); \
+ } \
+ else \
+ { \
+ (result_bit1) ^= JACOBI_N1B_BIT1 (__b); \
+ (a_rem) = mpn_modexact_1_odd (__a_ptr, __a_size, __b); \
+ } \
+ } while (0)
+
+/* State for the Jacobi computation using Lehmer. */
+#define jacobi_table __gmp_jacobi_table
+__GMP_DECLSPEC extern const unsigned char jacobi_table[208];
+
+/* Bit layout for the initial state. b must be odd.
+
+ 3 2 1 0
+ +--+--+--+--+
+ |a1|a0|b1| s|
+ +--+--+--+--+
+
+ */
+static inline unsigned
+mpn_jacobi_init (unsigned a, unsigned b, unsigned s)
+{
+ ASSERT (b & 1);
+ ASSERT (s <= 1);
+ return ((a & 3) << 2) + (b & 2) + s;
+}
+
+static inline int
+mpn_jacobi_finish (unsigned bits)
+{
+ /* (a, b) = (1,0) or (0,1) */
+ ASSERT ( (bits & 14) == 0);
+
+ return 1-2*(bits & 1);
+}
+
+static inline unsigned
+mpn_jacobi_update (unsigned bits, unsigned denominator, unsigned q)
+{
+ /* FIXME: Could halve table size by not including the e bit in the
+ * index, and instead xor when updating. Then the lookup would be
+ * like
+ *
+ * bits ^= table[((bits & 30) << 2) + (denominator << 2) + q];
+ */
+
+ ASSERT (bits < 26);
+ ASSERT (denominator < 2);
+ ASSERT (q < 4);
+
+ /* For almost all calls, denominator is constant and quite often q
+ is constant too. So use addition rather than or, so the compiler
+ can put the constant part can into the offset of an indexed
+ addressing instruction.
+
+ With constant denominator, the below table lookup is compiled to
+
+ C Constant q = 1, constant denominator = 1
+ movzbl table+5(%eax,8), %eax
+
+ or
+
+ C q in %edx, constant denominator = 1
+ movzbl table+4(%edx,%eax,8), %eax
+
+ One could maintain the state preshifted 3 bits, to save a shift
+ here, but at least on x86, that's no real saving.
+ */
+ return bits = jacobi_table[(bits << 3) + (denominator << 2) + q];
+}
+
+/* Matrix multiplication */
+#define mpn_matrix22_mul __MPN(matrix22_mul)
+__GMP_DECLSPEC void mpn_matrix22_mul (mp_ptr, mp_ptr, mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_srcptr, mp_srcptr, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_matrix22_mul_strassen __MPN(matrix22_mul_strassen)
+__GMP_DECLSPEC void mpn_matrix22_mul_strassen (mp_ptr, mp_ptr, mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_srcptr, mp_srcptr, mp_srcptr, mp_size_t, mp_ptr);
+#define mpn_matrix22_mul_itch __MPN(matrix22_mul_itch)
+__GMP_DECLSPEC mp_size_t mpn_matrix22_mul_itch (mp_size_t, mp_size_t) ATTRIBUTE_CONST;
+
+#ifndef MATRIX22_STRASSEN_THRESHOLD
+#define MATRIX22_STRASSEN_THRESHOLD 30
+#endif
+
+/* HGCD definitions */
+
+/* Extract one numb, shifting count bits left
+ ________ ________
+ |___xh___||___xl___|
+ |____r____|
+ >count <
+
+ The count includes any nail bits, so it should work fine if count
+ is computed using count_leading_zeros. If GMP_NAIL_BITS > 0, all of
+ xh, xl and r include nail bits. Must have 0 < count < GMP_LIMB_BITS.
+
+ FIXME: Omit masking with GMP_NUMB_MASK, and let callers do that for
+ those calls where the count high bits of xh may be non-zero.
+*/
+
+#define MPN_EXTRACT_NUMB(count, xh, xl) \
+ ((((xh) << ((count) - GMP_NAIL_BITS)) & GMP_NUMB_MASK) | \
+ ((xl) >> (GMP_LIMB_BITS - (count))))
+
+
+/* The matrix non-negative M = (u, u'; v,v') keeps track of the
+ reduction (a;b) = M (alpha; beta) where alpha, beta are smaller
+ than a, b. The determinant must always be one, so that M has an
+ inverse (v', -u'; -v, u). Elements always fit in GMP_NUMB_BITS - 1
+ bits. */
+struct hgcd_matrix1
+{
+ mp_limb_t u[2][2];
+};
+
+#define mpn_hgcd2 __MPN (hgcd2)
+__GMP_DECLSPEC int mpn_hgcd2 (mp_limb_t, mp_limb_t, mp_limb_t, mp_limb_t, struct hgcd_matrix1 *);
+
+#define mpn_hgcd_mul_matrix1_vector __MPN (hgcd_mul_matrix1_vector)
+__GMP_DECLSPEC mp_size_t mpn_hgcd_mul_matrix1_vector (const struct hgcd_matrix1 *, mp_ptr, mp_srcptr, mp_ptr, mp_size_t);
+
+#define mpn_matrix22_mul1_inverse_vector __MPN (matrix22_mul1_inverse_vector)
+__GMP_DECLSPEC mp_size_t mpn_matrix22_mul1_inverse_vector (const struct hgcd_matrix1 *, mp_ptr, mp_srcptr, mp_ptr, mp_size_t);
+
+#define mpn_hgcd2_jacobi __MPN (hgcd2_jacobi)
+__GMP_DECLSPEC int mpn_hgcd2_jacobi (mp_limb_t, mp_limb_t, mp_limb_t, mp_limb_t, struct hgcd_matrix1 *, unsigned *);
+
+struct hgcd_matrix
+{
+ mp_size_t alloc; /* for sanity checking only */
+ mp_size_t n;
+ mp_ptr p[2][2];
+};
+
+#define MPN_HGCD_MATRIX_INIT_ITCH(n) (4 * ((n+1)/2 + 1))
+
+#define mpn_hgcd_matrix_init __MPN (hgcd_matrix_init)
+__GMP_DECLSPEC void mpn_hgcd_matrix_init (struct hgcd_matrix *, mp_size_t, mp_ptr);
+
+#define mpn_hgcd_matrix_update_q __MPN (hgcd_matrix_update_q)
+__GMP_DECLSPEC void mpn_hgcd_matrix_update_q (struct hgcd_matrix *, mp_srcptr, mp_size_t, unsigned, mp_ptr);
+
+#define mpn_hgcd_matrix_mul_1 __MPN (hgcd_matrix_mul_1)
+__GMP_DECLSPEC void mpn_hgcd_matrix_mul_1 (struct hgcd_matrix *, const struct hgcd_matrix1 *, mp_ptr);
+
+#define mpn_hgcd_matrix_mul __MPN (hgcd_matrix_mul)
+__GMP_DECLSPEC void mpn_hgcd_matrix_mul (struct hgcd_matrix *, const struct hgcd_matrix *, mp_ptr);
+
+#define mpn_hgcd_matrix_adjust __MPN (hgcd_matrix_adjust)
+__GMP_DECLSPEC mp_size_t mpn_hgcd_matrix_adjust (const struct hgcd_matrix *, mp_size_t, mp_ptr, mp_ptr, mp_size_t, mp_ptr);
+
+#define mpn_hgcd_step __MPN(hgcd_step)
+__GMP_DECLSPEC mp_size_t mpn_hgcd_step (mp_size_t, mp_ptr, mp_ptr, mp_size_t, struct hgcd_matrix *, mp_ptr);
+
+#define mpn_hgcd_reduce __MPN(hgcd_reduce)
+__GMP_DECLSPEC mp_size_t mpn_hgcd_reduce (struct hgcd_matrix *, mp_ptr, mp_ptr, mp_size_t, mp_size_t, mp_ptr);
+
+#define mpn_hgcd_reduce_itch __MPN(hgcd_reduce_itch)
+__GMP_DECLSPEC mp_size_t mpn_hgcd_reduce_itch (mp_size_t, mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_hgcd_itch __MPN (hgcd_itch)
+__GMP_DECLSPEC mp_size_t mpn_hgcd_itch (mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_hgcd __MPN (hgcd)
+__GMP_DECLSPEC mp_size_t mpn_hgcd (mp_ptr, mp_ptr, mp_size_t, struct hgcd_matrix *, mp_ptr);
+
+#define mpn_hgcd_appr_itch __MPN (hgcd_appr_itch)
+__GMP_DECLSPEC mp_size_t mpn_hgcd_appr_itch (mp_size_t) ATTRIBUTE_CONST;
+
+#define mpn_hgcd_appr __MPN (hgcd_appr)
+__GMP_DECLSPEC int mpn_hgcd_appr (mp_ptr, mp_ptr, mp_size_t, struct hgcd_matrix *, mp_ptr);
+
+#define mpn_hgcd_jacobi __MPN (hgcd_jacobi)
+__GMP_DECLSPEC mp_size_t mpn_hgcd_jacobi (mp_ptr, mp_ptr, mp_size_t, struct hgcd_matrix *, unsigned *, mp_ptr);
+
+typedef void gcd_subdiv_step_hook(void *, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, int);
+
+/* Needs storage for the quotient */
+#define MPN_GCD_SUBDIV_STEP_ITCH(n) (n)
+
+#define mpn_gcd_subdiv_step __MPN(gcd_subdiv_step)
+__GMP_DECLSPEC mp_size_t mpn_gcd_subdiv_step (mp_ptr, mp_ptr, mp_size_t, mp_size_t, gcd_subdiv_step_hook *, void *, mp_ptr);
+
+struct gcdext_ctx
+{
+ /* Result parameters. */
+ mp_ptr gp;
+ mp_size_t gn;
+ mp_ptr up;
+ mp_size_t *usize;
+
+ /* Cofactors updated in each step. */
+ mp_size_t un;
+ mp_ptr u0, u1, tp;
+};
+
+#define mpn_gcdext_hook __MPN (gcdext_hook)
+gcd_subdiv_step_hook mpn_gcdext_hook;
+
+#define MPN_GCDEXT_LEHMER_N_ITCH(n) (4*(n) + 3)
+
+#define mpn_gcdext_lehmer_n __MPN(gcdext_lehmer_n)
+__GMP_DECLSPEC mp_size_t mpn_gcdext_lehmer_n (mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_ptr, mp_size_t, mp_ptr);
+
+/* 4*(an + 1) + 4*(bn + 1) + an */
+#define MPN_GCDEXT_LEHMER_ITCH(an, bn) (5*(an) + 4*(bn) + 8)
+
+#ifndef HGCD_THRESHOLD
+#define HGCD_THRESHOLD 400
+#endif
+
+#ifndef HGCD_APPR_THRESHOLD
+#define HGCD_APPR_THRESHOLD 400
+#endif
+
+#ifndef HGCD_REDUCE_THRESHOLD
+#define HGCD_REDUCE_THRESHOLD 1000
+#endif
+
+#ifndef GCD_DC_THRESHOLD
+#define GCD_DC_THRESHOLD 1000
+#endif
+
+#ifndef GCDEXT_DC_THRESHOLD
+#define GCDEXT_DC_THRESHOLD 600
+#endif
+
+/* Definitions for mpn_set_str and mpn_get_str */
+struct powers
+{
+ mp_ptr p; /* actual power value */
+ mp_size_t n; /* # of limbs at p */
+ mp_size_t shift; /* weight of lowest limb, in limb base B */
+ size_t digits_in_base; /* number of corresponding digits */
+ int base;
+};
+typedef struct powers powers_t;
+#define mpn_dc_set_str_powtab_alloc(n) ((n) + GMP_LIMB_BITS)
+#define mpn_dc_set_str_itch(n) ((n) + GMP_LIMB_BITS)
+#define mpn_dc_get_str_powtab_alloc(n) ((n) + 2 * GMP_LIMB_BITS)
+#define mpn_dc_get_str_itch(n) ((n) + GMP_LIMB_BITS)
+
+#define mpn_dc_set_str __MPN(dc_set_str)
+__GMP_DECLSPEC mp_size_t mpn_dc_set_str (mp_ptr, const unsigned char *, size_t, const powers_t *, mp_ptr);
+#define mpn_bc_set_str __MPN(bc_set_str)
+__GMP_DECLSPEC mp_size_t mpn_bc_set_str (mp_ptr, const unsigned char *, size_t, int);
+#define mpn_set_str_compute_powtab __MPN(set_str_compute_powtab)
+__GMP_DECLSPEC void mpn_set_str_compute_powtab (powers_t *, mp_ptr, mp_size_t, int);
+
+
+/* __GMPF_BITS_TO_PREC applies a minimum 53 bits, rounds upwards to a whole
+ limb and adds an extra limb. __GMPF_PREC_TO_BITS drops that extra limb,
+ hence giving back the user's size in bits rounded up. Notice that
+ converting prec->bits->prec gives an unchanged value. */
+#define __GMPF_BITS_TO_PREC(n) \
+ ((mp_size_t) ((__GMP_MAX (53, n) + 2 * GMP_NUMB_BITS - 1) / GMP_NUMB_BITS))
+#define __GMPF_PREC_TO_BITS(n) \
+ ((mp_bitcnt_t) (n) * GMP_NUMB_BITS - GMP_NUMB_BITS)
+
+__GMP_DECLSPEC extern mp_size_t __gmp_default_fp_limb_precision;
+
+/* Compute the number of base-b digits corresponding to nlimbs limbs, rounding
+ down. */
+#define DIGITS_IN_BASE_PER_LIMB(res, nlimbs, b) \
+ do { \
+ mp_limb_t _ph, _pl; \
+ umul_ppmm (_ph, _pl, \
+ mp_bases[b].logb2, GMP_NUMB_BITS * (mp_limb_t) (nlimbs));\
+ res = _ph; \
+ } while (0)
+
+/* Compute the number of limbs corresponding to ndigits base-b digits, rounding
+ up. */
+#define LIMBS_PER_DIGIT_IN_BASE(res, ndigits, b) \
+ do { \
+ mp_limb_t _ph, _dummy; \
+ umul_ppmm (_ph, _dummy, mp_bases[b].log2b, (mp_limb_t) (ndigits)); \
+ res = 8 * _ph / GMP_NUMB_BITS + 2; \
+ } while (0)
+
+
+/* Set n to the number of significant digits an mpf of the given _mp_prec
+ field, in the given base. This is a rounded up value, designed to ensure
+ there's enough digits to reproduce all the guaranteed part of the value.
+
+ There are prec many limbs, but the high might be only "1" so forget it
+ and just count prec-1 limbs into chars. +1 rounds that upwards, and a
+ further +1 is because the limbs usually won't fall on digit boundaries.
+
+ FIXME: If base is a power of 2 and the bits per digit divides
+ GMP_LIMB_BITS then the +2 is unnecessary. This happens always for
+ base==2, and in base==16 with the current 32 or 64 bit limb sizes. */
+
+#define MPF_SIGNIFICANT_DIGITS(n, base, prec) \
+ do { \
+ size_t rawn; \
+ ASSERT (base >= 2 && base < numberof (mp_bases)); \
+ DIGITS_IN_BASE_PER_LIMB (rawn, (prec) - 1, base); \
+ n = rawn + 2; \
+ } while (0)
+
+
+/* Decimal point string, from the current C locale. Needs <langinfo.h> for
+ nl_langinfo and constants, preferably with _GNU_SOURCE defined to get
+ DECIMAL_POINT from glibc, and needs <locale.h> for localeconv, each under
+ their respective #if HAVE_FOO_H.
+
+ GLIBC recommends nl_langinfo because getting only one facet can be
+ faster, apparently. */
+
+/* DECIMAL_POINT seems to need _GNU_SOURCE defined to get it from glibc. */
+#if HAVE_NL_LANGINFO && defined (DECIMAL_POINT)
+#define GMP_DECIMAL_POINT (nl_langinfo (DECIMAL_POINT))
+#endif
+/* RADIXCHAR is deprecated, still in unix98 or some such. */
+#if HAVE_NL_LANGINFO && defined (RADIXCHAR) && ! defined (GMP_DECIMAL_POINT)
+#define GMP_DECIMAL_POINT (nl_langinfo (RADIXCHAR))
+#endif
+/* localeconv is slower since it returns all locale stuff */
+#if HAVE_LOCALECONV && ! defined (GMP_DECIMAL_POINT)
+#define GMP_DECIMAL_POINT (localeconv()->decimal_point)
+#endif
+#if ! defined (GMP_DECIMAL_POINT)
+#define GMP_DECIMAL_POINT (".")
+#endif
+
+
+#define DOPRNT_CONV_FIXED 1
+#define DOPRNT_CONV_SCIENTIFIC 2
+#define DOPRNT_CONV_GENERAL 3
+
+#define DOPRNT_JUSTIFY_NONE 0
+#define DOPRNT_JUSTIFY_LEFT 1
+#define DOPRNT_JUSTIFY_RIGHT 2
+#define DOPRNT_JUSTIFY_INTERNAL 3
+
+#define DOPRNT_SHOWBASE_YES 1
+#define DOPRNT_SHOWBASE_NO 2
+#define DOPRNT_SHOWBASE_NONZERO 3
+
+struct doprnt_params_t {
+ int base; /* negative for upper case */
+ int conv; /* choices above */
+ const char *expfmt; /* exponent format */
+ int exptimes4; /* exponent multiply by 4 */
+ char fill; /* character */
+ int justify; /* choices above */
+ int prec; /* prec field, or -1 for all digits */
+ int showbase; /* choices above */
+ int showpoint; /* if radix point always shown */
+ int showtrailing; /* if trailing zeros wanted */
+ char sign; /* '+', ' ', or '\0' */
+ int width; /* width field */
+};
+
+#if _GMP_H_HAVE_VA_LIST
+
+typedef int (*doprnt_format_t) (void *, const char *, va_list);
+typedef int (*doprnt_memory_t) (void *, const char *, size_t);
+typedef int (*doprnt_reps_t) (void *, int, int);
+typedef int (*doprnt_final_t) (void *);
+
+struct doprnt_funs_t {
+ doprnt_format_t format;
+ doprnt_memory_t memory;
+ doprnt_reps_t reps;
+ doprnt_final_t final; /* NULL if not required */
+};
+
+extern const struct doprnt_funs_t __gmp_fprintf_funs;
+extern const struct doprnt_funs_t __gmp_sprintf_funs;
+extern const struct doprnt_funs_t __gmp_snprintf_funs;
+extern const struct doprnt_funs_t __gmp_obstack_printf_funs;
+extern const struct doprnt_funs_t __gmp_ostream_funs;
+
+/* "buf" is a __gmp_allocate_func block of "alloc" many bytes. The first
+ "size" of these have been written. "alloc > size" is maintained, so
+ there's room to store a '\0' at the end. "result" is where the
+ application wants the final block pointer. */
+struct gmp_asprintf_t {
+ char **result;
+ char *buf;
+ size_t size;
+ size_t alloc;
+};
+
+#define GMP_ASPRINTF_T_INIT(d, output) \
+ do { \
+ (d).result = (output); \
+ (d).alloc = 256; \
+ (d).buf = (char *) (*__gmp_allocate_func) ((d).alloc); \
+ (d).size = 0; \
+ } while (0)
+
+/* If a realloc is necessary, use twice the size actually required, so as to
+ avoid repeated small reallocs. */
+#define GMP_ASPRINTF_T_NEED(d, n) \
+ do { \
+ size_t alloc, newsize, newalloc; \
+ ASSERT ((d)->alloc >= (d)->size + 1); \
+ \
+ alloc = (d)->alloc; \
+ newsize = (d)->size + (n); \
+ if (alloc <= newsize) \
+ { \
+ newalloc = 2*newsize; \
+ (d)->alloc = newalloc; \
+ (d)->buf = __GMP_REALLOCATE_FUNC_TYPE ((d)->buf, \
+ alloc, newalloc, char); \
+ } \
+ } while (0)
+
+__GMP_DECLSPEC int __gmp_asprintf_memory (struct gmp_asprintf_t *, const char *, size_t);
+__GMP_DECLSPEC int __gmp_asprintf_reps (struct gmp_asprintf_t *, int, int);
+__GMP_DECLSPEC int __gmp_asprintf_final (struct gmp_asprintf_t *);
+
+/* buf is where to write the next output, and size is how much space is left
+ there. If the application passed size==0 then that's what we'll have
+ here, and nothing at all should be written. */
+struct gmp_snprintf_t {
+ char *buf;
+ size_t size;
+};
+
+/* Add the bytes printed by the call to the total retval, or bail out on an
+ error. */
+#define DOPRNT_ACCUMULATE(call) \
+ do { \
+ int __ret; \
+ __ret = call; \
+ if (__ret == -1) \
+ goto error; \
+ retval += __ret; \
+ } while (0)
+#define DOPRNT_ACCUMULATE_FUN(fun, params) \
+ do { \
+ ASSERT ((fun) != NULL); \
+ DOPRNT_ACCUMULATE ((*(fun)) params); \
+ } while (0)
+
+#define DOPRNT_FORMAT(fmt, ap) \
+ DOPRNT_ACCUMULATE_FUN (funs->format, (data, fmt, ap))
+#define DOPRNT_MEMORY(ptr, len) \
+ DOPRNT_ACCUMULATE_FUN (funs->memory, (data, ptr, len))
+#define DOPRNT_REPS(c, n) \
+ DOPRNT_ACCUMULATE_FUN (funs->reps, (data, c, n))
+
+#define DOPRNT_STRING(str) DOPRNT_MEMORY (str, strlen (str))
+
+#define DOPRNT_REPS_MAYBE(c, n) \
+ do { \
+ if ((n) != 0) \
+ DOPRNT_REPS (c, n); \
+ } while (0)
+#define DOPRNT_MEMORY_MAYBE(ptr, len) \
+ do { \
+ if ((len) != 0) \
+ DOPRNT_MEMORY (ptr, len); \
+ } while (0)
+
+__GMP_DECLSPEC int __gmp_doprnt (const struct doprnt_funs_t *, void *, const char *, va_list);
+__GMP_DECLSPEC int __gmp_doprnt_integer (const struct doprnt_funs_t *, void *, const struct doprnt_params_t *, const char *);
+
+#define __gmp_doprnt_mpf __gmp_doprnt_mpf2
+__GMP_DECLSPEC int __gmp_doprnt_mpf (const struct doprnt_funs_t *, void *, const struct doprnt_params_t *, const char *, mpf_srcptr);
+
+__GMP_DECLSPEC int __gmp_replacement_vsnprintf (char *, size_t, const char *, va_list);
+#endif /* _GMP_H_HAVE_VA_LIST */
+
+
+typedef int (*gmp_doscan_scan_t) (void *, const char *, ...);
+typedef void *(*gmp_doscan_step_t) (void *, int);
+typedef int (*gmp_doscan_get_t) (void *);
+typedef int (*gmp_doscan_unget_t) (int, void *);
+
+struct gmp_doscan_funs_t {
+ gmp_doscan_scan_t scan;
+ gmp_doscan_step_t step;
+ gmp_doscan_get_t get;
+ gmp_doscan_unget_t unget;
+};
+extern const struct gmp_doscan_funs_t __gmp_fscanf_funs;
+extern const struct gmp_doscan_funs_t __gmp_sscanf_funs;
+
+#if _GMP_H_HAVE_VA_LIST
+__GMP_DECLSPEC int __gmp_doscan (const struct gmp_doscan_funs_t *, void *, const char *, va_list);
+#endif
+
+
+/* For testing and debugging. */
+#define MPZ_CHECK_FORMAT(z) \
+ do { \
+ ASSERT_ALWAYS (SIZ(z) == 0 || PTR(z)[ABSIZ(z) - 1] != 0); \
+ ASSERT_ALWAYS (ALLOC(z) >= ABSIZ(z)); \
+ ASSERT_ALWAYS_MPN (PTR(z), ABSIZ(z)); \
+ } while (0)
+
+#define MPQ_CHECK_FORMAT(q) \
+ do { \
+ MPZ_CHECK_FORMAT (mpq_numref (q)); \
+ MPZ_CHECK_FORMAT (mpq_denref (q)); \
+ ASSERT_ALWAYS (SIZ(mpq_denref(q)) >= 1); \
+ \
+ if (SIZ(mpq_numref(q)) == 0) \
+ { \
+ /* should have zero as 0/1 */ \
+ ASSERT_ALWAYS (SIZ(mpq_denref(q)) == 1 \
+ && PTR(mpq_denref(q))[0] == 1); \
+ } \
+ else \
+ { \
+ /* should have no common factors */ \
+ mpz_t g; \
+ mpz_init (g); \
+ mpz_gcd (g, mpq_numref(q), mpq_denref(q)); \
+ ASSERT_ALWAYS (mpz_cmp_ui (g, 1) == 0); \
+ mpz_clear (g); \
+ } \
+ } while (0)
+
+#define MPF_CHECK_FORMAT(f) \
+ do { \
+ ASSERT_ALWAYS (PREC(f) >= __GMPF_BITS_TO_PREC(53)); \
+ ASSERT_ALWAYS (ABSIZ(f) <= PREC(f)+1); \
+ if (SIZ(f) == 0) \
+ ASSERT_ALWAYS (EXP(f) == 0); \
+ if (SIZ(f) != 0) \
+ ASSERT_ALWAYS (PTR(f)[ABSIZ(f) - 1] != 0); \
+ } while (0)
+
+
+/* Enhancement: The "mod" and "gcd_1" functions below could have
+ __GMP_ATTRIBUTE_PURE, but currently (gcc 3.3) that's not supported on
+ function pointers, only actual functions. It probably doesn't make much
+ difference to the gmp code, since hopefully we arrange calls so there's
+ no great need for the compiler to move things around. */
+
+#if WANT_FAT_BINARY && (HAVE_HOST_CPU_FAMILY_x86 || HAVE_HOST_CPU_FAMILY_x86_64)
+/* NOTE: The function pointers in this struct are also in CPUVEC_FUNCS_LIST
+ in mpn/x86/x86-defs.m4 and mpn/x86_64/x86_64-defs.m4. Be sure to update
+ those when changing here. */
+struct cpuvec_t {
+ DECL_add_n ((*add_n));
+ DECL_addlsh1_n ((*addlsh1_n));
+ DECL_addlsh2_n ((*addlsh2_n));
+ DECL_addmul_1 ((*addmul_1));
+ DECL_addmul_2 ((*addmul_2));
+ DECL_bdiv_dbm1c ((*bdiv_dbm1c));
+ DECL_cnd_add_n ((*cnd_add_n));
+ DECL_cnd_sub_n ((*cnd_sub_n));
+ DECL_com ((*com));
+ DECL_copyd ((*copyd));
+ DECL_copyi ((*copyi));
+ DECL_divexact_1 ((*divexact_1));
+ DECL_divrem_1 ((*divrem_1));
+ DECL_gcd_1 ((*gcd_1));
+ DECL_lshift ((*lshift));
+ DECL_lshiftc ((*lshiftc));
+ DECL_mod_1 ((*mod_1));
+ DECL_mod_1_1p ((*mod_1_1p));
+ DECL_mod_1_1p_cps ((*mod_1_1p_cps));
+ DECL_mod_1s_2p ((*mod_1s_2p));
+ DECL_mod_1s_2p_cps ((*mod_1s_2p_cps));
+ DECL_mod_1s_4p ((*mod_1s_4p));
+ DECL_mod_1s_4p_cps ((*mod_1s_4p_cps));
+ DECL_mod_34lsub1 ((*mod_34lsub1));
+ DECL_modexact_1c_odd ((*modexact_1c_odd));
+ DECL_mul_1 ((*mul_1));
+ DECL_mul_basecase ((*mul_basecase));
+ DECL_mullo_basecase ((*mullo_basecase));
+ DECL_preinv_divrem_1 ((*preinv_divrem_1));
+ DECL_preinv_mod_1 ((*preinv_mod_1));
+ DECL_redc_1 ((*redc_1));
+ DECL_redc_2 ((*redc_2));
+ DECL_rshift ((*rshift));
+ DECL_sqr_basecase ((*sqr_basecase));
+ DECL_sub_n ((*sub_n));
+ DECL_sublsh1_n ((*sublsh1_n));
+ DECL_submul_1 ((*submul_1));
+ mp_size_t mul_toom22_threshold;
+ mp_size_t mul_toom33_threshold;
+ mp_size_t sqr_toom2_threshold;
+ mp_size_t sqr_toom3_threshold;
+ mp_size_t bmod_1_to_mod_1_threshold;
+};
+__GMP_DECLSPEC extern struct cpuvec_t __gmpn_cpuvec;
+__GMP_DECLSPEC extern int __gmpn_cpuvec_initialized;
+#endif /* x86 fat binary */
+
+__GMP_DECLSPEC void __gmpn_cpuvec_init (void);
+
+/* Get a threshold "field" from __gmpn_cpuvec, running __gmpn_cpuvec_init()
+ if that hasn't yet been done (to establish the right values). */
+#define CPUVEC_THRESHOLD(field) \
+ ((LIKELY (__gmpn_cpuvec_initialized) ? 0 : (__gmpn_cpuvec_init (), 0)), \
+ __gmpn_cpuvec.field)
+
+
+#if HAVE_NATIVE_mpn_add_nc
+#define mpn_add_nc __MPN(add_nc)
+__GMP_DECLSPEC mp_limb_t mpn_add_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+#else
+static inline
+mp_limb_t
+mpn_add_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n, mp_limb_t ci)
+{
+ mp_limb_t co;
+ co = mpn_add_n (rp, up, vp, n);
+ co += mpn_add_1 (rp, rp, n, ci);
+ return co;
+}
+#endif
+
+#if HAVE_NATIVE_mpn_sub_nc
+#define mpn_sub_nc __MPN(sub_nc)
+__GMP_DECLSPEC mp_limb_t mpn_sub_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+#else
+static inline mp_limb_t
+mpn_sub_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n, mp_limb_t ci)
+{
+ mp_limb_t co;
+ co = mpn_sub_n (rp, up, vp, n);
+ co += mpn_sub_1 (rp, rp, n, ci);
+ return co;
+}
+#endif
+
+static inline int
+mpn_zero_p (mp_srcptr ap, mp_size_t n)
+{
+ while (--n >= 0)
+ {
+ if (ap[n] != 0)
+ return 0;
+ }
+ return 1;
+}
+
+#if TUNE_PROGRAM_BUILD
+/* Some extras wanted when recompiling some .c files for use by the tune
+ program. Not part of a normal build.
+
+ It's necessary to keep these thresholds as #defines (just to an
+ identically named variable), since various defaults are established based
+ on #ifdef in the .c files. For some this is not so (the defaults are
+ instead established above), but all are done this way for consistency. */
+
+#undef MUL_TOOM22_THRESHOLD
+#define MUL_TOOM22_THRESHOLD mul_toom22_threshold
+extern mp_size_t mul_toom22_threshold;
+
+#undef MUL_TOOM33_THRESHOLD
+#define MUL_TOOM33_THRESHOLD mul_toom33_threshold
+extern mp_size_t mul_toom33_threshold;
+
+#undef MUL_TOOM44_THRESHOLD
+#define MUL_TOOM44_THRESHOLD mul_toom44_threshold
+extern mp_size_t mul_toom44_threshold;
+
+#undef MUL_TOOM6H_THRESHOLD
+#define MUL_TOOM6H_THRESHOLD mul_toom6h_threshold
+extern mp_size_t mul_toom6h_threshold;
+
+#undef MUL_TOOM8H_THRESHOLD
+#define MUL_TOOM8H_THRESHOLD mul_toom8h_threshold
+extern mp_size_t mul_toom8h_threshold;
+
+#undef MUL_TOOM32_TO_TOOM43_THRESHOLD
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD mul_toom32_to_toom43_threshold
+extern mp_size_t mul_toom32_to_toom43_threshold;
+
+#undef MUL_TOOM32_TO_TOOM53_THRESHOLD
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD mul_toom32_to_toom53_threshold
+extern mp_size_t mul_toom32_to_toom53_threshold;
+
+#undef MUL_TOOM42_TO_TOOM53_THRESHOLD
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD mul_toom42_to_toom53_threshold
+extern mp_size_t mul_toom42_to_toom53_threshold;
+
+#undef MUL_TOOM42_TO_TOOM63_THRESHOLD
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD mul_toom42_to_toom63_threshold
+extern mp_size_t mul_toom42_to_toom63_threshold;
+
+#undef MUL_TOOM43_TO_TOOM54_THRESHOLD
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD mul_toom43_to_toom54_threshold;
+extern mp_size_t mul_toom43_to_toom54_threshold;
+
+#undef MUL_FFT_THRESHOLD
+#define MUL_FFT_THRESHOLD mul_fft_threshold
+extern mp_size_t mul_fft_threshold;
+
+#undef MUL_FFT_MODF_THRESHOLD
+#define MUL_FFT_MODF_THRESHOLD mul_fft_modf_threshold
+extern mp_size_t mul_fft_modf_threshold;
+
+#undef MUL_FFT_TABLE
+#define MUL_FFT_TABLE { 0 }
+
+#undef MUL_FFT_TABLE3
+#define MUL_FFT_TABLE3 { {0,0} }
+
+/* A native mpn_sqr_basecase is not tuned and SQR_BASECASE_THRESHOLD should
+ remain as zero (always use it). */
+#if ! HAVE_NATIVE_mpn_sqr_basecase
+#undef SQR_BASECASE_THRESHOLD
+#define SQR_BASECASE_THRESHOLD sqr_basecase_threshold
+extern mp_size_t sqr_basecase_threshold;
+#endif
+
+#if TUNE_PROGRAM_BUILD_SQR
+#undef SQR_TOOM2_THRESHOLD
+#define SQR_TOOM2_THRESHOLD SQR_TOOM2_MAX_GENERIC
+#else
+#undef SQR_TOOM2_THRESHOLD
+#define SQR_TOOM2_THRESHOLD sqr_toom2_threshold
+extern mp_size_t sqr_toom2_threshold;
+#endif
+
+#undef SQR_TOOM3_THRESHOLD
+#define SQR_TOOM3_THRESHOLD sqr_toom3_threshold
+extern mp_size_t sqr_toom3_threshold;
+
+#undef SQR_TOOM4_THRESHOLD
+#define SQR_TOOM4_THRESHOLD sqr_toom4_threshold
+extern mp_size_t sqr_toom4_threshold;
+
+#undef SQR_TOOM6_THRESHOLD
+#define SQR_TOOM6_THRESHOLD sqr_toom6_threshold
+extern mp_size_t sqr_toom6_threshold;
+
+#undef SQR_TOOM8_THRESHOLD
+#define SQR_TOOM8_THRESHOLD sqr_toom8_threshold
+extern mp_size_t sqr_toom8_threshold;
+
+#undef SQR_FFT_THRESHOLD
+#define SQR_FFT_THRESHOLD sqr_fft_threshold
+extern mp_size_t sqr_fft_threshold;
+
+#undef SQR_FFT_MODF_THRESHOLD
+#define SQR_FFT_MODF_THRESHOLD sqr_fft_modf_threshold
+extern mp_size_t sqr_fft_modf_threshold;
+
+#undef SQR_FFT_TABLE
+#define SQR_FFT_TABLE { 0 }
+
+#undef SQR_FFT_TABLE3
+#define SQR_FFT_TABLE3 { {0,0} }
+
+#undef MULLO_BASECASE_THRESHOLD
+#define MULLO_BASECASE_THRESHOLD mullo_basecase_threshold
+extern mp_size_t mullo_basecase_threshold;
+
+#undef MULLO_DC_THRESHOLD
+#define MULLO_DC_THRESHOLD mullo_dc_threshold
+extern mp_size_t mullo_dc_threshold;
+
+#undef MULLO_MUL_N_THRESHOLD
+#define MULLO_MUL_N_THRESHOLD mullo_mul_n_threshold
+extern mp_size_t mullo_mul_n_threshold;
+
+#undef MULMID_TOOM42_THRESHOLD
+#define MULMID_TOOM42_THRESHOLD mulmid_toom42_threshold
+extern mp_size_t mulmid_toom42_threshold;
+
+#undef DIV_QR_2_PI2_THRESHOLD
+#define DIV_QR_2_PI2_THRESHOLD div_qr_2_pi2_threshold
+extern mp_size_t div_qr_2_pi2_threshold;
+
+#undef DC_DIV_QR_THRESHOLD
+#define DC_DIV_QR_THRESHOLD dc_div_qr_threshold
+extern mp_size_t dc_div_qr_threshold;
+
+#undef DC_DIVAPPR_Q_THRESHOLD
+#define DC_DIVAPPR_Q_THRESHOLD dc_divappr_q_threshold
+extern mp_size_t dc_divappr_q_threshold;
+
+#undef DC_BDIV_Q_THRESHOLD
+#define DC_BDIV_Q_THRESHOLD dc_bdiv_q_threshold
+extern mp_size_t dc_bdiv_q_threshold;
+
+#undef DC_BDIV_QR_THRESHOLD
+#define DC_BDIV_QR_THRESHOLD dc_bdiv_qr_threshold
+extern mp_size_t dc_bdiv_qr_threshold;
+
+#undef MU_DIV_QR_THRESHOLD
+#define MU_DIV_QR_THRESHOLD mu_div_qr_threshold
+extern mp_size_t mu_div_qr_threshold;
+
+#undef MU_DIVAPPR_Q_THRESHOLD
+#define MU_DIVAPPR_Q_THRESHOLD mu_divappr_q_threshold
+extern mp_size_t mu_divappr_q_threshold;
+
+#undef MUPI_DIV_QR_THRESHOLD
+#define MUPI_DIV_QR_THRESHOLD mupi_div_qr_threshold
+extern mp_size_t mupi_div_qr_threshold;
+
+#undef MU_BDIV_QR_THRESHOLD
+#define MU_BDIV_QR_THRESHOLD mu_bdiv_qr_threshold
+extern mp_size_t mu_bdiv_qr_threshold;
+
+#undef MU_BDIV_Q_THRESHOLD
+#define MU_BDIV_Q_THRESHOLD mu_bdiv_q_threshold
+extern mp_size_t mu_bdiv_q_threshold;
+
+#undef INV_MULMOD_BNM1_THRESHOLD
+#define INV_MULMOD_BNM1_THRESHOLD inv_mulmod_bnm1_threshold
+extern mp_size_t inv_mulmod_bnm1_threshold;
+
+#undef INV_NEWTON_THRESHOLD
+#define INV_NEWTON_THRESHOLD inv_newton_threshold
+extern mp_size_t inv_newton_threshold;
+
+#undef INV_APPR_THRESHOLD
+#define INV_APPR_THRESHOLD inv_appr_threshold
+extern mp_size_t inv_appr_threshold;
+
+#undef BINV_NEWTON_THRESHOLD
+#define BINV_NEWTON_THRESHOLD binv_newton_threshold
+extern mp_size_t binv_newton_threshold;
+
+#undef REDC_1_TO_REDC_2_THRESHOLD
+#define REDC_1_TO_REDC_2_THRESHOLD redc_1_to_redc_2_threshold
+extern mp_size_t redc_1_to_redc_2_threshold;
+
+#undef REDC_2_TO_REDC_N_THRESHOLD
+#define REDC_2_TO_REDC_N_THRESHOLD redc_2_to_redc_n_threshold
+extern mp_size_t redc_2_to_redc_n_threshold;
+
+#undef REDC_1_TO_REDC_N_THRESHOLD
+#define REDC_1_TO_REDC_N_THRESHOLD redc_1_to_redc_n_threshold
+extern mp_size_t redc_1_to_redc_n_threshold;
+
+#undef MATRIX22_STRASSEN_THRESHOLD
+#define MATRIX22_STRASSEN_THRESHOLD matrix22_strassen_threshold
+extern mp_size_t matrix22_strassen_threshold;
+
+#undef HGCD_THRESHOLD
+#define HGCD_THRESHOLD hgcd_threshold
+extern mp_size_t hgcd_threshold;
+
+#undef HGCD_APPR_THRESHOLD
+#define HGCD_APPR_THRESHOLD hgcd_appr_threshold
+extern mp_size_t hgcd_appr_threshold;
+
+#undef HGCD_REDUCE_THRESHOLD
+#define HGCD_REDUCE_THRESHOLD hgcd_reduce_threshold
+extern mp_size_t hgcd_reduce_threshold;
+
+#undef GCD_DC_THRESHOLD
+#define GCD_DC_THRESHOLD gcd_dc_threshold
+extern mp_size_t gcd_dc_threshold;
+
+#undef GCDEXT_DC_THRESHOLD
+#define GCDEXT_DC_THRESHOLD gcdext_dc_threshold
+extern mp_size_t gcdext_dc_threshold;
+
+#undef DIV_QR_1N_PI1_METHOD
+#define DIV_QR_1N_PI1_METHOD div_qr_1n_pi1_method
+extern int div_qr_1n_pi1_method;
+
+#undef DIV_QR_1_NORM_THRESHOLD
+#define DIV_QR_1_NORM_THRESHOLD div_qr_1_norm_threshold
+extern mp_size_t div_qr_1_norm_threshold;
+
+#undef DIV_QR_1_UNNORM_THRESHOLD
+#define DIV_QR_1_UNNORM_THRESHOLD div_qr_1_unnorm_threshold
+extern mp_size_t div_qr_1_unnorm_threshold;
+
+#undef DIVREM_1_NORM_THRESHOLD
+#define DIVREM_1_NORM_THRESHOLD divrem_1_norm_threshold
+extern mp_size_t divrem_1_norm_threshold;
+
+#undef DIVREM_1_UNNORM_THRESHOLD
+#define DIVREM_1_UNNORM_THRESHOLD divrem_1_unnorm_threshold
+extern mp_size_t divrem_1_unnorm_threshold;
+
+#undef MOD_1_NORM_THRESHOLD
+#define MOD_1_NORM_THRESHOLD mod_1_norm_threshold
+extern mp_size_t mod_1_norm_threshold;
+
+#undef MOD_1_UNNORM_THRESHOLD
+#define MOD_1_UNNORM_THRESHOLD mod_1_unnorm_threshold
+extern mp_size_t mod_1_unnorm_threshold;
+
+#undef MOD_1_1P_METHOD
+#define MOD_1_1P_METHOD mod_1_1p_method
+extern int mod_1_1p_method;
+
+#undef MOD_1N_TO_MOD_1_1_THRESHOLD
+#define MOD_1N_TO_MOD_1_1_THRESHOLD mod_1n_to_mod_1_1_threshold
+extern mp_size_t mod_1n_to_mod_1_1_threshold;
+
+#undef MOD_1U_TO_MOD_1_1_THRESHOLD
+#define MOD_1U_TO_MOD_1_1_THRESHOLD mod_1u_to_mod_1_1_threshold
+extern mp_size_t mod_1u_to_mod_1_1_threshold;
+
+#undef MOD_1_1_TO_MOD_1_2_THRESHOLD
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD mod_1_1_to_mod_1_2_threshold
+extern mp_size_t mod_1_1_to_mod_1_2_threshold;
+
+#undef MOD_1_2_TO_MOD_1_4_THRESHOLD
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD mod_1_2_to_mod_1_4_threshold
+extern mp_size_t mod_1_2_to_mod_1_4_threshold;
+
+#undef PREINV_MOD_1_TO_MOD_1_THRESHOLD
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD preinv_mod_1_to_mod_1_threshold
+extern mp_size_t preinv_mod_1_to_mod_1_threshold;
+
+#if ! UDIV_PREINV_ALWAYS
+#undef DIVREM_2_THRESHOLD
+#define DIVREM_2_THRESHOLD divrem_2_threshold
+extern mp_size_t divrem_2_threshold;
+#endif
+
+#undef MULMOD_BNM1_THRESHOLD
+#define MULMOD_BNM1_THRESHOLD mulmod_bnm1_threshold
+extern mp_size_t mulmod_bnm1_threshold;
+
+#undef SQRMOD_BNM1_THRESHOLD
+#define SQRMOD_BNM1_THRESHOLD sqrmod_bnm1_threshold
+extern mp_size_t sqrmod_bnm1_threshold;
+
+#undef GET_STR_DC_THRESHOLD
+#define GET_STR_DC_THRESHOLD get_str_dc_threshold
+extern mp_size_t get_str_dc_threshold;
+
+#undef GET_STR_PRECOMPUTE_THRESHOLD
+#define GET_STR_PRECOMPUTE_THRESHOLD get_str_precompute_threshold
+extern mp_size_t get_str_precompute_threshold;
+
+#undef SET_STR_DC_THRESHOLD
+#define SET_STR_DC_THRESHOLD set_str_dc_threshold
+extern mp_size_t set_str_dc_threshold;
+
+#undef SET_STR_PRECOMPUTE_THRESHOLD
+#define SET_STR_PRECOMPUTE_THRESHOLD set_str_precompute_threshold
+extern mp_size_t set_str_precompute_threshold;
+
+#undef FAC_ODD_THRESHOLD
+#define FAC_ODD_THRESHOLD fac_odd_threshold
+extern mp_size_t fac_odd_threshold;
+
+#undef FAC_DSC_THRESHOLD
+#define FAC_DSC_THRESHOLD fac_dsc_threshold
+extern mp_size_t fac_dsc_threshold;
+
+#undef FFT_TABLE_ATTRS
+#define FFT_TABLE_ATTRS
+extern mp_size_t mpn_fft_table[2][MPN_FFT_TABLE_SIZE];
+#define FFT_TABLE3_SIZE 2000 /* generous space for tuning */
+extern struct fft_table_nk mpn_fft_table3[2][FFT_TABLE3_SIZE];
+
+/* Sizes the tune program tests up to, used in a couple of recompilations. */
+#undef MUL_TOOM22_THRESHOLD_LIMIT
+#undef MUL_TOOM33_THRESHOLD_LIMIT
+#undef MULLO_BASECASE_THRESHOLD_LIMIT
+#undef SQR_TOOM3_THRESHOLD_LIMIT
+#define SQR_TOOM2_MAX_GENERIC 200
+#define MUL_TOOM22_THRESHOLD_LIMIT 700
+#define MUL_TOOM33_THRESHOLD_LIMIT 700
+#define SQR_TOOM3_THRESHOLD_LIMIT 400
+#define MUL_TOOM44_THRESHOLD_LIMIT 1000
+#define SQR_TOOM4_THRESHOLD_LIMIT 1000
+#define MUL_TOOM6H_THRESHOLD_LIMIT 1100
+#define SQR_TOOM6_THRESHOLD_LIMIT 1100
+#define MUL_TOOM8H_THRESHOLD_LIMIT 1200
+#define SQR_TOOM8_THRESHOLD_LIMIT 1200
+#define MULLO_BASECASE_THRESHOLD_LIMIT 200
+#define GET_STR_THRESHOLD_LIMIT 150
+#define FAC_DSC_THRESHOLD_LIMIT 2048
+
+#endif /* TUNE_PROGRAM_BUILD */
+
+#if defined (__cplusplus)
+}
+#endif
+
+/* FIXME: Make these itch functions less conservative. Also consider making
+ them dependent on just 'an', and compute the allocation directly from 'an'
+ instead of via n. */
+
+/* toom22/toom2: Scratch need is 2*(an + k), k is the recursion depth.
+ k is ths smallest k such that
+ ceil(an/2^k) < MUL_TOOM22_THRESHOLD.
+ which implies that
+ k = bitsize of floor ((an-1)/(MUL_TOOM22_THRESHOLD-1))
+ = 1 + floor (log_2 (floor ((an-1)/(MUL_TOOM22_THRESHOLD-1))))
+*/
+#define mpn_toom22_mul_itch(an, bn) \
+ (2 * ((an) + GMP_NUMB_BITS))
+#define mpn_toom2_sqr_itch(an) \
+ (2 * ((an) + GMP_NUMB_BITS))
+
+/* toom33/toom3: Scratch need is 5an/2 + 10k, k is the recursion depth.
+ We use 3an + C, so that we can use a smaller constant.
+ */
+#define mpn_toom33_mul_itch(an, bn) \
+ (3 * (an) + GMP_NUMB_BITS)
+#define mpn_toom3_sqr_itch(an) \
+ (3 * (an) + GMP_NUMB_BITS)
+
+/* toom33/toom3: Scratch need is 8an/3 + 13k, k is the recursion depth.
+ We use 3an + C, so that we can use a smaller constant.
+ */
+#define mpn_toom44_mul_itch(an, bn) \
+ (3 * (an) + GMP_NUMB_BITS)
+#define mpn_toom4_sqr_itch(an) \
+ (3 * (an) + GMP_NUMB_BITS)
+
+#define mpn_toom6_sqr_itch(n) \
+ (((n) - SQR_TOOM6_THRESHOLD)*2 + \
+ MAX(SQR_TOOM6_THRESHOLD*2 + GMP_NUMB_BITS*6, \
+ mpn_toom4_sqr_itch(SQR_TOOM6_THRESHOLD)))
+
+#define MUL_TOOM6H_MIN \
+ ((MUL_TOOM6H_THRESHOLD > MUL_TOOM44_THRESHOLD) ? \
+ MUL_TOOM6H_THRESHOLD : MUL_TOOM44_THRESHOLD)
+#define mpn_toom6_mul_n_itch(n) \
+ (((n) - MUL_TOOM6H_MIN)*2 + \
+ MAX(MUL_TOOM6H_MIN*2 + GMP_NUMB_BITS*6, \
+ mpn_toom44_mul_itch(MUL_TOOM6H_MIN,MUL_TOOM6H_MIN)))
+
+static inline mp_size_t
+mpn_toom6h_mul_itch (mp_size_t an, mp_size_t bn) {
+ mp_size_t estimatedN;
+ estimatedN = (an + bn) / (size_t) 10 + 1;
+ return mpn_toom6_mul_n_itch (estimatedN * 6);
+}
+
+#define mpn_toom8_sqr_itch(n) \
+ ((((n)*15)>>3) - ((SQR_TOOM8_THRESHOLD*15)>>3) + \
+ MAX(((SQR_TOOM8_THRESHOLD*15)>>3) + GMP_NUMB_BITS*6, \
+ mpn_toom6_sqr_itch(SQR_TOOM8_THRESHOLD)))
+
+#define MUL_TOOM8H_MIN \
+ ((MUL_TOOM8H_THRESHOLD > MUL_TOOM6H_MIN) ? \
+ MUL_TOOM8H_THRESHOLD : MUL_TOOM6H_MIN)
+#define mpn_toom8_mul_n_itch(n) \
+ ((((n)*15)>>3) - ((MUL_TOOM8H_MIN*15)>>3) + \
+ MAX(((MUL_TOOM8H_MIN*15)>>3) + GMP_NUMB_BITS*6, \
+ mpn_toom6_mul_n_itch(MUL_TOOM8H_MIN)))
+
+static inline mp_size_t
+mpn_toom8h_mul_itch (mp_size_t an, mp_size_t bn) {
+ mp_size_t estimatedN;
+ estimatedN = (an + bn) / (size_t) 14 + 1;
+ return mpn_toom8_mul_n_itch (estimatedN * 8);
+}
+
+static inline mp_size_t
+mpn_toom32_mul_itch (mp_size_t an, mp_size_t bn)
+{
+ mp_size_t n = 1 + (2 * an >= 3 * bn ? (an - 1) / (size_t) 3 : (bn - 1) >> 1);
+ mp_size_t itch = 2 * n + 1;
+
+ return itch;
+}
+
+static inline mp_size_t
+mpn_toom42_mul_itch (mp_size_t an, mp_size_t bn)
+{
+ mp_size_t n = an >= 2 * bn ? (an + 3) >> 2 : (bn + 1) >> 1;
+ return 6 * n + 3;
+}
+
+static inline mp_size_t
+mpn_toom43_mul_itch (mp_size_t an, mp_size_t bn)
+{
+ mp_size_t n = 1 + (3 * an >= 4 * bn ? (an - 1) >> 2 : (bn - 1) / (size_t) 3);
+
+ return 6*n + 4;
+}
+
+static inline mp_size_t
+mpn_toom52_mul_itch (mp_size_t an, mp_size_t bn)
+{
+ mp_size_t n = 1 + (2 * an >= 5 * bn ? (an - 1) / (size_t) 5 : (bn - 1) >> 1);
+ return 6*n + 4;
+}
+
+static inline mp_size_t
+mpn_toom53_mul_itch (mp_size_t an, mp_size_t bn)
+{
+ mp_size_t n = 1 + (3 * an >= 5 * bn ? (an - 1) / (size_t) 5 : (bn - 1) / (size_t) 3);
+ return 10 * n + 10;
+}
+
+static inline mp_size_t
+mpn_toom62_mul_itch (mp_size_t an, mp_size_t bn)
+{
+ mp_size_t n = 1 + (an >= 3 * bn ? (an - 1) / (size_t) 6 : (bn - 1) >> 1);
+ return 10 * n + 10;
+}
+
+static inline mp_size_t
+mpn_toom63_mul_itch (mp_size_t an, mp_size_t bn)
+{
+ mp_size_t n = 1 + (an >= 2 * bn ? (an - 1) / (size_t) 6 : (bn - 1) / (size_t) 3);
+ return 9 * n + 3;
+}
+
+static inline mp_size_t
+mpn_toom54_mul_itch (mp_size_t an, mp_size_t bn)
+{
+ mp_size_t n = 1 + (4 * an >= 5 * bn ? (an - 1) / (size_t) 5 : (bn - 1) / (size_t) 4);
+ return 9 * n + 3;
+}
+
+/* let S(n) = space required for input size n,
+ then S(n) = 3 floor(n/2) + 1 + S(floor(n/2)). */
+#define mpn_toom42_mulmid_itch(n) \
+ (3 * (n) + GMP_NUMB_BITS)
+
+#if 0
+#define mpn_fft_mul mpn_mul_fft_full
+#else
+#define mpn_fft_mul mpn_nussbaumer_mul
+#endif
+
+#ifdef __cplusplus
+
+/* A little helper for a null-terminated __gmp_allocate_func string.
+ The destructor ensures it's freed even if an exception is thrown.
+ The len field is needed by the destructor, and can be used by anyone else
+ to avoid a second strlen pass over the data.
+
+ Since our input is a C string, using strlen is correct. Perhaps it'd be
+ more C++-ish style to use std::char_traits<char>::length, but char_traits
+ isn't available in gcc 2.95.4. */
+
+class gmp_allocated_string {
+ public:
+ char *str;
+ size_t len;
+ gmp_allocated_string(char *arg)
+ {
+ str = arg;
+ len = std::strlen (str);
+ }
+ ~gmp_allocated_string()
+ {
+ (*__gmp_free_func) (str, len+1);
+ }
+};
+
+std::istream &__gmpz_operator_in_nowhite (std::istream &, mpz_ptr, char);
+int __gmp_istream_set_base (std::istream &, char &, bool &, bool &);
+void __gmp_istream_set_digits (std::string &, std::istream &, char &, bool &, int);
+void __gmp_doprnt_params_from_ios (struct doprnt_params_t *, std::ios &);
+std::ostream& __gmp_doprnt_integer_ostream (std::ostream &, struct doprnt_params_t *, char *);
+extern const struct doprnt_funs_t __gmp_asprintf_funs_noformat;
+
+#endif /* __cplusplus */
+
+#endif /* __GMP_IMPL_H__ */
diff --git a/gmp/gmpxx.h b/gmp/gmpxx.h
new file mode 100644
index 0000000000..6dd9129c5a
--- /dev/null
+++ b/gmp/gmpxx.h
@@ -0,0 +1,3336 @@
+/* gmpxx.h -- C++ class wrapper for GMP types. -*- C++ -*-
+
+Copyright 2001-2003, 2006, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#ifndef __GMP_PLUSPLUS__
+#define __GMP_PLUSPLUS__
+
+#include <iosfwd>
+
+#include <cstring> /* for strlen */
+#include <limits> /* numeric_limits */
+#include <utility>
+#include <algorithm> /* swap */
+#include <string>
+#include <stdexcept>
+#include <cfloat>
+#include <gmp.h>
+
+// wrapper for gcc's __builtin_constant_p
+// __builtin_constant_p has been in gcc since forever,
+// but g++-3.4 miscompiles it.
+#if __GMP_GNUC_PREREQ(4, 2)
+#define __GMPXX_CONSTANT(X) __builtin_constant_p(X)
+#else
+#define __GMPXX_CONSTANT(X) false
+#endif
+#define __GMPXX_CONSTANT_TRUE(X) (__GMPXX_CONSTANT(X) && (X))
+
+// Use C++11 features
+#ifndef __GMPXX_USE_CXX11
+#if __cplusplus >= 201103L
+#define __GMPXX_USE_CXX11 1
+#else
+#define __GMPXX_USE_CXX11 0
+#endif
+#endif
+
+#if __GMPXX_USE_CXX11
+#define __GMPXX_NOEXCEPT noexcept
+#include <type_traits> // for common_type
+#else
+#define __GMPXX_NOEXCEPT
+#endif
+
+// Max allocations for plain types when converted to GMP types
+#if GMP_NAIL_BITS != 0 && ! defined _LONG_LONG_LIMB
+#define __GMPZ_ULI_LIMBS 2
+#else
+#define __GMPZ_ULI_LIMBS 1
+#endif
+
+#define __GMPXX_BITS_TO_LIMBS(n) (((n) + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS)
+#define __GMPZ_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MAX_EXP)+1
+#define __GMPQ_NUM_DBL_LIMBS __GMPZ_DBL_LIMBS
+#define __GMPQ_DEN_DBL_LIMBS __GMPXX_BITS_TO_LIMBS(DBL_MANT_DIG+1-DBL_MIN_EXP)+1
+// The final +1s are a security margin. The current implementation of
+// mpq_set_d seems to need it for the denominator.
+
+inline void __mpz_set_ui_safe(mpz_ptr p, unsigned long l)
+{
+ p->_mp_size = (l != 0);
+ p->_mp_d[0] = l & GMP_NUMB_MASK;
+#if __GMPZ_ULI_LIMBS > 1
+ l >>= GMP_NUMB_BITS;
+ p->_mp_d[1] = l;
+ p->_mp_size += (l != 0);
+#endif
+}
+
+inline void __mpz_set_si_safe(mpz_ptr p, long l)
+{
+ if(l < 0)
+ {
+ __mpz_set_ui_safe(p, -static_cast<unsigned long>(l));
+ mpz_neg(p, p);
+ }
+ else
+ __mpz_set_ui_safe(p, l);
+ // Note: we know the high bit of l is 0 so we could do slightly better
+}
+
+// Fake temporary variables
+#define __GMPXX_TMPZ_UI \
+ mpz_t temp; \
+ mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
+ temp->_mp_d = limbs; \
+ __mpz_set_ui_safe (temp, l)
+#define __GMPXX_TMPZ_SI \
+ mpz_t temp; \
+ mp_limb_t limbs[__GMPZ_ULI_LIMBS]; \
+ temp->_mp_d = limbs; \
+ __mpz_set_si_safe (temp, l)
+#define __GMPXX_TMPZ_D \
+ mpz_t temp; \
+ mp_limb_t limbs[__GMPZ_DBL_LIMBS]; \
+ temp->_mp_d = limbs; \
+ temp->_mp_alloc = __GMPZ_DBL_LIMBS; \
+ mpz_set_d (temp, d)
+
+#define __GMPXX_TMPQ_UI \
+ mpq_t temp; \
+ mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
+ mpq_numref(temp)->_mp_d = limbs; \
+ __mpz_set_ui_safe (mpq_numref(temp), l); \
+ mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
+ mpq_denref(temp)->_mp_size = 1; \
+ mpq_denref(temp)->_mp_d[0] = 1
+#define __GMPXX_TMPQ_SI \
+ mpq_t temp; \
+ mp_limb_t limbs[__GMPZ_ULI_LIMBS+1]; \
+ mpq_numref(temp)->_mp_d = limbs; \
+ __mpz_set_si_safe (mpq_numref(temp), l); \
+ mpq_denref(temp)->_mp_d = limbs + __GMPZ_ULI_LIMBS; \
+ mpq_denref(temp)->_mp_size = 1; \
+ mpq_denref(temp)->_mp_d[0] = 1
+#define __GMPXX_TMPQ_D \
+ mpq_t temp; \
+ mp_limb_t limbs[__GMPQ_NUM_DBL_LIMBS + __GMPQ_DEN_DBL_LIMBS]; \
+ mpq_numref(temp)->_mp_d = limbs; \
+ mpq_numref(temp)->_mp_alloc = __GMPQ_NUM_DBL_LIMBS; \
+ mpq_denref(temp)->_mp_d = limbs + __GMPQ_NUM_DBL_LIMBS; \
+ mpq_denref(temp)->_mp_alloc = __GMPQ_DEN_DBL_LIMBS; \
+ mpq_set_d (temp, d)
+
+inline unsigned long __gmpxx_abs_ui (signed long l)
+{
+ return l >= 0 ? static_cast<unsigned long>(l)
+ : -static_cast<unsigned long>(l);
+}
+
+/**************** Function objects ****************/
+/* Any evaluation of a __gmp_expr ends up calling one of these functions
+ all intermediate functions being inline, the evaluation should optimize
+ to a direct call to the relevant function, thus yielding no overhead
+ over the C interface. */
+
+struct __gmp_unary_plus
+{
+ static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); }
+ static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); }
+ static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); }
+};
+
+struct __gmp_unary_minus
+{
+ static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); }
+ static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); }
+ static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); }
+};
+
+struct __gmp_unary_com
+{
+ static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); }
+};
+
+struct __gmp_binary_plus
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
+ { mpz_add(z, w, v); }
+
+ static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
+ {
+ // Ideally, those checks should happen earlier so that the tree
+ // generated for a+0+b would just be sum(a,b).
+ if (__GMPXX_CONSTANT(l) && l == 0)
+ {
+ if (z != w) mpz_set(z, w);
+ }
+ else
+ mpz_add_ui(z, w, l);
+ }
+ static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
+ {
+ if (l >= 0)
+ eval(z, w, static_cast<unsigned long>(l));
+ else
+ mpz_sub_ui(z, w, -static_cast<unsigned long>(l));
+ }
+ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, double d)
+ { __GMPXX_TMPZ_D; mpz_add (z, w, temp); }
+ static void eval(mpz_ptr z, double d, mpz_srcptr w)
+ { eval(z, w, d); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
+ { mpq_add(q, r, s); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
+ {
+ if (__GMPXX_CONSTANT(l) && l == 0)
+ {
+ if (q != r) mpq_set(q, r);
+ }
+ else
+ {
+ if (q == r)
+ mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l);
+ else
+ {
+ mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
+ mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
+ mpz_set(mpq_denref(q), mpq_denref(r));
+ }
+ }
+ }
+ static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
+ { eval(q, r, l); }
+ static inline void eval(mpq_ptr q, mpq_srcptr r, signed long int l);
+ // defined after __gmp_binary_minus
+ static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
+ { eval(q, r, l); }
+ static void eval(mpq_ptr q, mpq_srcptr r, double d)
+ { __GMPXX_TMPQ_D; mpq_add (q, r, temp); }
+ static void eval(mpq_ptr q, double d, mpq_srcptr r)
+ { eval(q, r, d); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
+ {
+ if (q == r)
+ mpz_addmul(mpq_numref(q), mpq_denref(q), z);
+ else
+ {
+ mpz_mul(mpq_numref(q), mpq_denref(r), z);
+ mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(r));
+ mpz_set(mpq_denref(q), mpq_denref(r));
+ }
+ }
+ static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
+ { eval(q, r, z); }
+
+ static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
+ { mpf_add(f, g, h); }
+
+ static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
+ { mpf_add_ui(f, g, l); }
+ static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
+ { mpf_add_ui(f, g, l); }
+ static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
+ {
+ if (l >= 0)
+ mpf_add_ui(f, g, l);
+ else
+ mpf_sub_ui(f, g, -static_cast<unsigned long>(l));
+ }
+ static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
+ { eval(f, g, l); }
+ static void eval(mpf_ptr f, mpf_srcptr g, double d)
+ {
+ mpf_t temp;
+ mpf_init2(temp, 8*sizeof(double));
+ mpf_set_d(temp, d);
+ mpf_add(f, g, temp);
+ mpf_clear(temp);
+ }
+ static void eval(mpf_ptr f, double d, mpf_srcptr g)
+ { eval(f, g, d); }
+};
+
+struct __gmp_binary_minus
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
+ { mpz_sub(z, w, v); }
+
+ static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
+ {
+ if (__GMPXX_CONSTANT(l) && l == 0)
+ {
+ if (z != w) mpz_set(z, w);
+ }
+ else
+ mpz_sub_ui(z, w, l);
+ }
+ static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
+ {
+ if (__GMPXX_CONSTANT(l) && l == 0)
+ {
+ mpz_neg(z, w);
+ }
+ else
+ mpz_ui_sub(z, l, w);
+ }
+ static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
+ {
+ if (l >= 0)
+ eval(z, w, static_cast<unsigned long>(l));
+ else
+ mpz_add_ui(z, w, -static_cast<unsigned long>(l));
+ }
+ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
+ {
+ if (l >= 0)
+ eval(z, static_cast<unsigned long>(l), w);
+ else
+ {
+ mpz_add_ui(z, w, -static_cast<unsigned long>(l));
+ mpz_neg(z, z);
+ }
+ }
+ static void eval(mpz_ptr z, mpz_srcptr w, double d)
+ { __GMPXX_TMPZ_D; mpz_sub (z, w, temp); }
+ static void eval(mpz_ptr z, double d, mpz_srcptr w)
+ { __GMPXX_TMPZ_D; mpz_sub (z, temp, w); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
+ { mpq_sub(q, r, s); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
+ {
+ if (__GMPXX_CONSTANT(l) && l == 0)
+ {
+ if (q != r) mpq_set(q, r);
+ }
+ else
+ {
+ if (q == r)
+ mpz_submul_ui(mpq_numref(q), mpq_denref(q), l);
+ else
+ {
+ mpz_mul_ui(mpq_numref(q), mpq_denref(r), l);
+ mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
+ mpz_set(mpq_denref(q), mpq_denref(r));
+ }
+ }
+ }
+ static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
+ { eval(q, r, l); mpq_neg(q, q); }
+ static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
+ {
+ if (l >= 0)
+ eval(q, r, static_cast<unsigned long>(l));
+ else
+ __gmp_binary_plus::eval(q, r, -static_cast<unsigned long>(l));
+ }
+ static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
+ { eval(q, r, l); mpq_neg(q, q); }
+ static void eval(mpq_ptr q, mpq_srcptr r, double d)
+ { __GMPXX_TMPQ_D; mpq_sub (q, r, temp); }
+ static void eval(mpq_ptr q, double d, mpq_srcptr r)
+ { __GMPXX_TMPQ_D; mpq_sub (q, temp, r); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z)
+ {
+ if (q == r)
+ mpz_submul(mpq_numref(q), mpq_denref(q), z);
+ else
+ {
+ mpz_mul(mpq_numref(q), mpq_denref(r), z);
+ mpz_sub(mpq_numref(q), mpq_numref(r), mpq_numref(q));
+ mpz_set(mpq_denref(q), mpq_denref(r));
+ }
+ }
+ static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r)
+ { eval(q, r, z); mpq_neg(q, q); }
+
+ static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
+ { mpf_sub(f, g, h); }
+
+ static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
+ { mpf_sub_ui(f, g, l); }
+ static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
+ { mpf_ui_sub(f, l, g); }
+ static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
+ {
+ if (l >= 0)
+ mpf_sub_ui(f, g, l);
+ else
+ mpf_add_ui(f, g, -static_cast<unsigned long>(l));
+ }
+ static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
+ {
+ if (l >= 0)
+ mpf_sub_ui(f, g, l);
+ else
+ mpf_add_ui(f, g, -static_cast<unsigned long>(l));
+ mpf_neg(f, f);
+ }
+ static void eval(mpf_ptr f, mpf_srcptr g, double d)
+ {
+ mpf_t temp;
+ mpf_init2(temp, 8*sizeof(double));
+ mpf_set_d(temp, d);
+ mpf_sub(f, g, temp);
+ mpf_clear(temp);
+ }
+ static void eval(mpf_ptr f, double d, mpf_srcptr g)
+ {
+ mpf_t temp;
+ mpf_init2(temp, 8*sizeof(double));
+ mpf_set_d(temp, d);
+ mpf_sub(f, temp, g);
+ mpf_clear(temp);
+ }
+};
+
+// defined here so it can reference __gmp_binary_minus
+inline void
+__gmp_binary_plus::eval(mpq_ptr q, mpq_srcptr r, signed long int l)
+{
+ if (l >= 0)
+ eval(q, r, static_cast<unsigned long>(l));
+ else
+ __gmp_binary_minus::eval(q, r, -static_cast<unsigned long>(l));
+}
+
+struct __gmp_binary_lshift
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
+ {
+ if (__GMPXX_CONSTANT(l) && (l == 0))
+ {
+ if (z != w) mpz_set(z, w);
+ }
+ else
+ mpz_mul_2exp(z, w, l);
+ }
+ static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
+ {
+ if (__GMPXX_CONSTANT(l) && (l == 0))
+ {
+ if (q != r) mpq_set(q, r);
+ }
+ else
+ mpq_mul_2exp(q, r, l);
+ }
+ static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
+ { mpf_mul_2exp(f, g, l); }
+};
+
+struct __gmp_binary_rshift
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mp_bitcnt_t l)
+ {
+ if (__GMPXX_CONSTANT(l) && (l == 0))
+ {
+ if (z != w) mpz_set(z, w);
+ }
+ else
+ mpz_fdiv_q_2exp(z, w, l);
+ }
+ static void eval(mpq_ptr q, mpq_srcptr r, mp_bitcnt_t l)
+ {
+ if (__GMPXX_CONSTANT(l) && (l == 0))
+ {
+ if (q != r) mpq_set(q, r);
+ }
+ else
+ mpq_div_2exp(q, r, l);
+ }
+ static void eval(mpf_ptr f, mpf_srcptr g, mp_bitcnt_t l)
+ { mpf_div_2exp(f, g, l); }
+};
+
+struct __gmp_binary_multiplies
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
+ { mpz_mul(z, w, v); }
+
+ static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
+ {
+// gcc-3.3 doesn't have __builtin_ctzl. Don't bother optimizing for old gcc.
+#if __GMP_GNUC_PREREQ(3, 4)
+ if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
+ {
+ if (l == 0)
+ {
+ z->_mp_size = 0;
+ }
+ else
+ {
+ __gmp_binary_lshift::eval(z, w, __builtin_ctzl(l));
+ }
+ }
+ else
+#endif
+ mpz_mul_ui(z, w, l);
+ }
+ static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l >= 0))
+ eval(z, w, static_cast<unsigned long>(l));
+ else if (__GMPXX_CONSTANT_TRUE(l <= 0))
+ {
+ eval(z, w, -static_cast<unsigned long>(l));
+ mpz_neg(z, z);
+ }
+ else
+ mpz_mul_si (z, w, l);
+ }
+ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, double d)
+ { __GMPXX_TMPZ_D; mpz_mul (z, w, temp); }
+ static void eval(mpz_ptr z, double d, mpz_srcptr w)
+ { eval(z, w, d); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
+ { mpq_mul(q, r, s); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
+ {
+#if __GMP_GNUC_PREREQ(3, 4)
+ if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0)
+ {
+ if (l == 0)
+ {
+ mpq_set_ui(q, 0, 1);
+ }
+ else
+ {
+ __gmp_binary_lshift::eval(q, r, __builtin_ctzl(l));
+ }
+ }
+ else
+#endif
+ {
+ __GMPXX_TMPQ_UI;
+ mpq_mul (q, r, temp);
+ }
+ }
+ static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
+ { eval(q, r, l); }
+ static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l >= 0))
+ eval(q, r, static_cast<unsigned long>(l));
+ else if (__GMPXX_CONSTANT_TRUE(l <= 0))
+ {
+ eval(q, r, -static_cast<unsigned long>(l));
+ mpq_neg(q, q);
+ }
+ else
+ {
+ __GMPXX_TMPQ_SI;
+ mpq_mul (q, r, temp);
+ }
+ }
+ static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
+ { eval(q, r, l); }
+ static void eval(mpq_ptr q, mpq_srcptr r, double d)
+ { __GMPXX_TMPQ_D; mpq_mul (q, r, temp); }
+ static void eval(mpq_ptr q, double d, mpq_srcptr r)
+ { eval(q, r, d); }
+
+ static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
+ { mpf_mul(f, g, h); }
+
+ static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
+ { mpf_mul_ui(f, g, l); }
+ static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
+ { mpf_mul_ui(f, g, l); }
+ static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
+ {
+ if (l >= 0)
+ mpf_mul_ui(f, g, l);
+ else
+ {
+ mpf_mul_ui(f, g, -static_cast<unsigned long>(l));
+ mpf_neg(f, f);
+ }
+ }
+ static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
+ { eval(f, g, l); }
+ static void eval(mpf_ptr f, mpf_srcptr g, double d)
+ {
+ mpf_t temp;
+ mpf_init2(temp, 8*sizeof(double));
+ mpf_set_d(temp, d);
+ mpf_mul(f, g, temp);
+ mpf_clear(temp);
+ }
+ static void eval(mpf_ptr f, double d, mpf_srcptr g)
+ { eval(f, g, d); }
+};
+
+struct __gmp_binary_divides
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
+ { mpz_tdiv_q(z, w, v); }
+
+ static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
+ {
+#if __GMP_GNUC_PREREQ(3, 4)
+ // Don't optimize division by 0...
+ if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
+ {
+ if (l == 1)
+ {
+ if (z != w) mpz_set(z, w);
+ }
+ else
+ mpz_tdiv_q_2exp(z, w, __builtin_ctzl(l));
+ // warning: do not use rshift (fdiv)
+ }
+ else
+#endif
+ mpz_tdiv_q_ui(z, w, l);
+ }
+ static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
+ {
+ if (mpz_sgn(w) >= 0)
+ {
+ if (mpz_fits_ulong_p(w))
+ mpz_set_ui(z, l / mpz_get_ui(w));
+ else
+ mpz_set_ui(z, 0);
+ }
+ else
+ {
+ mpz_neg(z, w);
+ if (mpz_fits_ulong_p(z))
+ {
+ mpz_set_ui(z, l / mpz_get_ui(z));
+ mpz_neg(z, z);
+ }
+ else
+ mpz_set_ui(z, 0);
+ }
+ }
+ static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
+ {
+ if (l >= 0)
+ eval(z, w, static_cast<unsigned long>(l));
+ else
+ {
+ eval(z, w, -static_cast<unsigned long>(l));
+ mpz_neg(z, z);
+ }
+ }
+ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
+ {
+ if (mpz_fits_slong_p(w))
+ mpz_set_si(z, l / mpz_get_si(w));
+ else
+ {
+ /* if w is bigger than a long then the quotient must be zero, unless
+ l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */
+ mpz_set_si (z, (mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? -1 : 0));
+ }
+ }
+ static void eval(mpz_ptr z, mpz_srcptr w, double d)
+ { __GMPXX_TMPZ_D; mpz_tdiv_q (z, w, temp); }
+ static void eval(mpz_ptr z, double d, mpz_srcptr w)
+ { __GMPXX_TMPZ_D; mpz_tdiv_q (z, temp, w); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s)
+ { mpq_div(q, r, s); }
+
+ static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l)
+ {
+#if __GMP_GNUC_PREREQ(3, 4)
+ if (__GMPXX_CONSTANT(l) && (l & (l-1)) == 0 && l != 0)
+ __gmp_binary_rshift::eval(q, r, __builtin_ctzl(l));
+ else
+#endif
+ {
+ __GMPXX_TMPQ_UI;
+ mpq_div (q, r, temp);
+ }
+ }
+ static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r)
+ { __GMPXX_TMPQ_UI; mpq_div (q, temp, r); }
+ static void eval(mpq_ptr q, mpq_srcptr r, signed long int l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l >= 0))
+ eval(q, r, static_cast<unsigned long>(l));
+ else if (__GMPXX_CONSTANT_TRUE(l <= 0))
+ {
+ eval(q, r, -static_cast<unsigned long>(l));
+ mpq_neg(q, q);
+ }
+ else
+ {
+ __GMPXX_TMPQ_SI;
+ mpq_div (q, r, temp);
+ }
+ }
+ static void eval(mpq_ptr q, signed long int l, mpq_srcptr r)
+ { __GMPXX_TMPQ_SI; mpq_div (q, temp, r); }
+ static void eval(mpq_ptr q, mpq_srcptr r, double d)
+ { __GMPXX_TMPQ_D; mpq_div (q, r, temp); }
+ static void eval(mpq_ptr q, double d, mpq_srcptr r)
+ { __GMPXX_TMPQ_D; mpq_div (q, temp, r); }
+
+ static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
+ { mpf_div(f, g, h); }
+
+ static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
+ { mpf_div_ui(f, g, l); }
+ static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
+ { mpf_ui_div(f, l, g); }
+ static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
+ {
+ if (l >= 0)
+ mpf_div_ui(f, g, l);
+ else
+ {
+ mpf_div_ui(f, g, -static_cast<unsigned long>(l));
+ mpf_neg(f, f);
+ }
+ }
+ static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
+ {
+ if (l >= 0)
+ mpf_ui_div(f, l, g);
+ else
+ {
+ mpf_ui_div(f, -static_cast<unsigned long>(l), g);
+ mpf_neg(f, f);
+ }
+ }
+ static void eval(mpf_ptr f, mpf_srcptr g, double d)
+ {
+ mpf_t temp;
+ mpf_init2(temp, 8*sizeof(double));
+ mpf_set_d(temp, d);
+ mpf_div(f, g, temp);
+ mpf_clear(temp);
+ }
+ static void eval(mpf_ptr f, double d, mpf_srcptr g)
+ {
+ mpf_t temp;
+ mpf_init2(temp, 8*sizeof(double));
+ mpf_set_d(temp, d);
+ mpf_div(f, temp, g);
+ mpf_clear(temp);
+ }
+};
+
+struct __gmp_binary_modulus
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
+ { mpz_tdiv_r(z, w, v); }
+
+ static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
+ { mpz_tdiv_r_ui(z, w, l); }
+ static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
+ {
+ if (mpz_sgn(w) >= 0)
+ {
+ if (mpz_fits_ulong_p(w))
+ mpz_set_ui(z, l % mpz_get_ui(w));
+ else
+ mpz_set_ui(z, l);
+ }
+ else
+ {
+ mpz_neg(z, w);
+ if (mpz_fits_ulong_p(z))
+ mpz_set_ui(z, l % mpz_get_ui(z));
+ else
+ mpz_set_ui(z, l);
+ }
+ }
+ static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
+ {
+ mpz_tdiv_r_ui (z, w, __gmpxx_abs_ui(l));
+ }
+ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
+ {
+ if (mpz_fits_slong_p(w))
+ mpz_set_si(z, l % mpz_get_si(w));
+ else
+ {
+ /* if w is bigger than a long then the remainder is l unchanged,
+ unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */
+ mpz_set_si (z, mpz_cmpabs_ui (w, __gmpxx_abs_ui(l)) == 0 ? 0 : l);
+ }
+ }
+ static void eval(mpz_ptr z, mpz_srcptr w, double d)
+ { __GMPXX_TMPZ_D; mpz_tdiv_r (z, w, temp); }
+ static void eval(mpz_ptr z, double d, mpz_srcptr w)
+ { __GMPXX_TMPZ_D; mpz_tdiv_r (z, temp, w); }
+};
+
+struct __gmp_binary_and
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
+ { mpz_and(z, w, v); }
+
+ static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
+ { __GMPXX_TMPZ_UI; mpz_and (z, w, temp); }
+ static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
+ { __GMPXX_TMPZ_SI; mpz_and (z, w, temp); }
+ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, double d)
+ { __GMPXX_TMPZ_D; mpz_and (z, w, temp); }
+ static void eval(mpz_ptr z, double d, mpz_srcptr w)
+ { eval(z, w, d); }
+};
+
+struct __gmp_binary_ior
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
+ { mpz_ior(z, w, v); }
+ static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
+ { __GMPXX_TMPZ_UI; mpz_ior (z, w, temp); }
+ static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
+ { __GMPXX_TMPZ_SI; mpz_ior (z, w, temp); }
+ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, double d)
+ { __GMPXX_TMPZ_D; mpz_ior (z, w, temp); }
+ static void eval(mpz_ptr z, double d, mpz_srcptr w)
+ { eval(z, w, d); }
+};
+
+struct __gmp_binary_xor
+{
+ static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v)
+ { mpz_xor(z, w, v); }
+ static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l)
+ { __GMPXX_TMPZ_UI; mpz_xor (z, w, temp); }
+ static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, signed long int l)
+ { __GMPXX_TMPZ_SI; mpz_xor (z, w, temp); }
+ static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
+ { eval(z, w, l); }
+ static void eval(mpz_ptr z, mpz_srcptr w, double d)
+ { __GMPXX_TMPZ_D; mpz_xor (z, w, temp); }
+ static void eval(mpz_ptr z, double d, mpz_srcptr w)
+ { eval(z, w, d); }
+};
+
+struct __gmp_binary_equal
+{
+ static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; }
+
+ static bool eval(mpz_srcptr z, unsigned long int l)
+ { return mpz_cmp_ui(z, l) == 0; }
+ static bool eval(unsigned long int l, mpz_srcptr z)
+ { return eval(z, l); }
+ static bool eval(mpz_srcptr z, signed long int l)
+ { return mpz_cmp_si(z, l) == 0; }
+ static bool eval(signed long int l, mpz_srcptr z)
+ { return eval(z, l); }
+ static bool eval(mpz_srcptr z, double d)
+ { return mpz_cmp_d(z, d) == 0; }
+ static bool eval(double d, mpz_srcptr z)
+ { return eval(z, d); }
+
+ static bool eval(mpq_srcptr q, mpq_srcptr r)
+ { return mpq_equal(q, r) != 0; }
+
+ static bool eval(mpq_srcptr q, unsigned long int l)
+ { return mpq_cmp_ui(q, l, 1) == 0; }
+ static bool eval(unsigned long int l, mpq_srcptr q)
+ { return eval(q, l); }
+ static bool eval(mpq_srcptr q, signed long int l)
+ { return mpq_cmp_si(q, l, 1) == 0; }
+ static bool eval(signed long int l, mpq_srcptr q)
+ { return eval(q, l); }
+ static bool eval(mpq_srcptr q, double d)
+ { __GMPXX_TMPQ_D; return mpq_equal (q, temp) != 0; }
+ static bool eval(double d, mpq_srcptr q)
+ { return eval(q, d); }
+
+ static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; }
+
+ static bool eval(mpf_srcptr f, unsigned long int l)
+ { return mpf_cmp_ui(f, l) == 0; }
+ static bool eval(unsigned long int l, mpf_srcptr f)
+ { return eval(f, l); }
+ static bool eval(mpf_srcptr f, signed long int l)
+ { return mpf_cmp_si(f, l) == 0; }
+ static bool eval(signed long int l, mpf_srcptr f)
+ { return eval(f, l); }
+ static bool eval(mpf_srcptr f, double d)
+ { return mpf_cmp_d(f, d) == 0; }
+ static bool eval(double d, mpf_srcptr f)
+ { return eval(f, d); }
+};
+
+struct __gmp_binary_less
+{
+ static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; }
+
+ static bool eval(mpz_srcptr z, unsigned long int l)
+ { return mpz_cmp_ui(z, l) < 0; }
+ static bool eval(unsigned long int l, mpz_srcptr z)
+ { return mpz_cmp_ui(z, l) > 0; }
+ static bool eval(mpz_srcptr z, signed long int l)
+ { return mpz_cmp_si(z, l) < 0; }
+ static bool eval(signed long int l, mpz_srcptr z)
+ { return mpz_cmp_si(z, l) > 0; }
+ static bool eval(mpz_srcptr z, double d)
+ { return mpz_cmp_d(z, d) < 0; }
+ static bool eval(double d, mpz_srcptr z)
+ { return mpz_cmp_d(z, d) > 0; }
+
+ static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; }
+
+ static bool eval(mpq_srcptr q, unsigned long int l)
+ { return mpq_cmp_ui(q, l, 1) < 0; }
+ static bool eval(unsigned long int l, mpq_srcptr q)
+ { return mpq_cmp_ui(q, l, 1) > 0; }
+ static bool eval(mpq_srcptr q, signed long int l)
+ { return mpq_cmp_si(q, l, 1) < 0; }
+ static bool eval(signed long int l, mpq_srcptr q)
+ { return mpq_cmp_si(q, l, 1) > 0; }
+ static bool eval(mpq_srcptr q, double d)
+ { __GMPXX_TMPQ_D; return mpq_cmp (q, temp) < 0; }
+ static bool eval(double d, mpq_srcptr q)
+ { __GMPXX_TMPQ_D; return mpq_cmp (temp, q) < 0; }
+
+ static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; }
+
+ static bool eval(mpf_srcptr f, unsigned long int l)
+ { return mpf_cmp_ui(f, l) < 0; }
+ static bool eval(unsigned long int l, mpf_srcptr f)
+ { return mpf_cmp_ui(f, l) > 0; }
+ static bool eval(mpf_srcptr f, signed long int l)
+ { return mpf_cmp_si(f, l) < 0; }
+ static bool eval(signed long int l, mpf_srcptr f)
+ { return mpf_cmp_si(f, l) > 0; }
+ static bool eval(mpf_srcptr f, double d)
+ { return mpf_cmp_d(f, d) < 0; }
+ static bool eval(double d, mpf_srcptr f)
+ { return mpf_cmp_d(f, d) > 0; }
+};
+
+struct __gmp_binary_greater
+{
+ template <class T, class U>
+ static inline bool eval(T t, U u) { return __gmp_binary_less::eval(u, t); }
+};
+
+struct __gmp_unary_increment
+{
+ static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); }
+ static void eval(mpq_ptr q)
+ { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
+ static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); }
+};
+
+struct __gmp_unary_decrement
+{
+ static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); }
+ static void eval(mpq_ptr q)
+ { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); }
+ static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); }
+};
+
+struct __gmp_abs_function
+{
+ static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); }
+ static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); }
+ static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); }
+};
+
+struct __gmp_trunc_function
+{
+ static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); }
+};
+
+struct __gmp_floor_function
+{
+ static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); }
+};
+
+struct __gmp_ceil_function
+{
+ static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); }
+};
+
+struct __gmp_sqrt_function
+{
+ static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); }
+ static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); }
+};
+
+struct __gmp_hypot_function
+{
+ static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h)
+ {
+ mpf_t temp;
+ mpf_init2(temp, mpf_get_prec(f));
+ mpf_mul(temp, g, g);
+ mpf_mul(f, h, h);
+ mpf_add(f, f, temp);
+ mpf_sqrt(f, f);
+ mpf_clear(temp);
+ }
+
+ static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l)
+ {
+ mpf_t temp;
+ mpf_init2(temp, mpf_get_prec(f));
+ mpf_mul(temp, g, g);
+ mpf_set_ui(f, l);
+ mpf_mul_ui(f, f, l);
+ mpf_add(f, f, temp);
+ mpf_clear(temp);
+ mpf_sqrt(f, f);
+ }
+ static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g)
+ { eval(f, g, l); }
+ static void eval(mpf_ptr f, mpf_srcptr g, signed long int l)
+ { eval(f, g, __gmpxx_abs_ui(l)); }
+ static void eval(mpf_ptr f, signed long int l, mpf_srcptr g)
+ { eval(f, g, l); }
+ static void eval(mpf_ptr f, mpf_srcptr g, double d)
+ {
+ mpf_t temp;
+ mpf_init2(temp, mpf_get_prec(f));
+ mpf_mul(temp, g, g);
+ mpf_set_d(f, d);
+ mpf_mul(f, f, f);
+ mpf_add(f, f, temp);
+ mpf_sqrt(f, f);
+ mpf_clear(temp);
+ }
+ static void eval(mpf_ptr f, double d, mpf_srcptr g)
+ { eval(f, g, d); }
+};
+
+struct __gmp_sgn_function
+{
+ static int eval(mpz_srcptr z) { return mpz_sgn(z); }
+ static int eval(mpq_srcptr q) { return mpq_sgn(q); }
+ static int eval(mpf_srcptr f) { return mpf_sgn(f); }
+};
+
+struct __gmp_cmp_function
+{
+ static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); }
+
+ static int eval(mpz_srcptr z, unsigned long int l)
+ { return mpz_cmp_ui(z, l); }
+ static int eval(unsigned long int l, mpz_srcptr z)
+ { return -mpz_cmp_ui(z, l); }
+ static int eval(mpz_srcptr z, signed long int l)
+ { return mpz_cmp_si(z, l); }
+ static int eval(signed long int l, mpz_srcptr z)
+ { return -mpz_cmp_si(z, l); }
+ static int eval(mpz_srcptr z, double d)
+ { return mpz_cmp_d(z, d); }
+ static int eval(double d, mpz_srcptr z)
+ { return -mpz_cmp_d(z, d); }
+
+ static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); }
+
+ static int eval(mpq_srcptr q, unsigned long int l)
+ { return mpq_cmp_ui(q, l, 1); }
+ static int eval(unsigned long int l, mpq_srcptr q)
+ { return -mpq_cmp_ui(q, l, 1); }
+ static int eval(mpq_srcptr q, signed long int l)
+ { return mpq_cmp_si(q, l, 1); }
+ static int eval(signed long int l, mpq_srcptr q)
+ { return -mpq_cmp_si(q, l, 1); }
+ static int eval(mpq_srcptr q, double d)
+ { __GMPXX_TMPQ_D; return mpq_cmp (q, temp); }
+ static int eval(double d, mpq_srcptr q)
+ { __GMPXX_TMPQ_D; return mpq_cmp (temp, q); }
+
+ static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); }
+
+ static int eval(mpf_srcptr f, unsigned long int l)
+ { return mpf_cmp_ui(f, l); }
+ static int eval(unsigned long int l, mpf_srcptr f)
+ { return -mpf_cmp_ui(f, l); }
+ static int eval(mpf_srcptr f, signed long int l)
+ { return mpf_cmp_si(f, l); }
+ static int eval(signed long int l, mpf_srcptr f)
+ { return -mpf_cmp_si(f, l); }
+ static int eval(mpf_srcptr f, double d)
+ { return mpf_cmp_d(f, d); }
+ static int eval(double d, mpf_srcptr f)
+ { return -mpf_cmp_d(f, d); }
+};
+
+struct __gmp_rand_function
+{
+ static void eval(mpz_ptr z, gmp_randstate_t s, mp_bitcnt_t l)
+ { mpz_urandomb(z, s, l); }
+ static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w)
+ { mpz_urandomm(z, s, w); }
+ static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec)
+ { mpf_urandomb(f, s, prec); }
+};
+
+
+/**************** Auxiliary classes ****************/
+
+/* this is much the same as gmp_allocated_string in gmp-impl.h
+ since gmp-impl.h is not publicly available, I redefine it here
+ I use a different name to avoid possible clashes */
+
+extern "C" {
+ typedef void (*__gmp_freefunc_t) (void *, size_t);
+}
+struct __gmp_alloc_cstring
+{
+ char *str;
+ __gmp_alloc_cstring(char *s) { str = s; }
+ ~__gmp_alloc_cstring()
+ {
+ __gmp_freefunc_t freefunc;
+ mp_get_memory_functions (NULL, NULL, &freefunc);
+ (*freefunc) (str, std::strlen(str)+1);
+ }
+};
+
+
+// general expression template class
+template <class T, class U>
+class __gmp_expr;
+
+
+// templates for resolving expression types
+template <class T>
+struct __gmp_resolve_ref
+{
+ typedef T ref_type;
+};
+
+template <class T, class U>
+struct __gmp_resolve_ref<__gmp_expr<T, U> >
+{
+ typedef const __gmp_expr<T, U> & ref_type;
+};
+
+
+template <class T, class U = T>
+struct __gmp_resolve_expr;
+
+template <>
+struct __gmp_resolve_expr<mpz_t>
+{
+ typedef mpz_t value_type;
+ typedef mpz_ptr ptr_type;
+ typedef mpz_srcptr srcptr_type;
+};
+
+template <>
+struct __gmp_resolve_expr<mpq_t>
+{
+ typedef mpq_t value_type;
+ typedef mpq_ptr ptr_type;
+ typedef mpq_srcptr srcptr_type;
+};
+
+template <>
+struct __gmp_resolve_expr<mpf_t>
+{
+ typedef mpf_t value_type;
+ typedef mpf_ptr ptr_type;
+ typedef mpf_srcptr srcptr_type;
+};
+
+template <>
+struct __gmp_resolve_expr<mpz_t, mpq_t>
+{
+ typedef mpq_t value_type;
+};
+
+template <>
+struct __gmp_resolve_expr<mpq_t, mpz_t>
+{
+ typedef mpq_t value_type;
+};
+
+template <>
+struct __gmp_resolve_expr<mpz_t, mpf_t>
+{
+ typedef mpf_t value_type;
+};
+
+template <>
+struct __gmp_resolve_expr<mpf_t, mpz_t>
+{
+ typedef mpf_t value_type;
+};
+
+template <>
+struct __gmp_resolve_expr<mpq_t, mpf_t>
+{
+ typedef mpf_t value_type;
+};
+
+template <>
+struct __gmp_resolve_expr<mpf_t, mpq_t>
+{
+ typedef mpf_t value_type;
+};
+
+#if __GMPXX_USE_CXX11
+namespace std {
+ template <class T, class U, class V, class W>
+ struct common_type <__gmp_expr<T, U>, __gmp_expr<V, W> >
+ {
+ private:
+ typedef typename __gmp_resolve_expr<T, V>::value_type X;
+ public:
+ typedef __gmp_expr<X, X> type;
+ };
+
+ template <class T, class U>
+ struct common_type <__gmp_expr<T, U>, __gmp_expr<T, U> >
+ {
+ typedef __gmp_expr<T, U> type;
+ };
+
+#define __GMPXX_DECLARE_COMMON_TYPE(typ) \
+ template <class T, class U> \
+ struct common_type <__gmp_expr<T, U>, typ > \
+ { \
+ typedef __gmp_expr<T, T> type; \
+ }; \
+ \
+ template <class T, class U> \
+ struct common_type <typ, __gmp_expr<T, U> > \
+ { \
+ typedef __gmp_expr<T, T> type; \
+ }
+
+ __GMPXX_DECLARE_COMMON_TYPE(signed char);
+ __GMPXX_DECLARE_COMMON_TYPE(unsigned char);
+ __GMPXX_DECLARE_COMMON_TYPE(signed int);
+ __GMPXX_DECLARE_COMMON_TYPE(unsigned int);
+ __GMPXX_DECLARE_COMMON_TYPE(signed short int);
+ __GMPXX_DECLARE_COMMON_TYPE(unsigned short int);
+ __GMPXX_DECLARE_COMMON_TYPE(signed long int);
+ __GMPXX_DECLARE_COMMON_TYPE(unsigned long int);
+ __GMPXX_DECLARE_COMMON_TYPE(float);
+ __GMPXX_DECLARE_COMMON_TYPE(double);
+#undef __GMPXX_DECLARE_COMMON_TYPE
+}
+#endif
+
+// classes for evaluating unary and binary expressions
+template <class T, class Op>
+struct __gmp_unary_expr
+{
+ const T &val;
+
+ __gmp_unary_expr(const T &v) : val(v) { }
+private:
+ __gmp_unary_expr();
+};
+
+template <class T, class U, class Op>
+struct __gmp_binary_expr
+{
+ typename __gmp_resolve_ref<T>::ref_type val1;
+ typename __gmp_resolve_ref<U>::ref_type val2;
+
+ __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { }
+private:
+ __gmp_binary_expr();
+};
+
+
+
+/**************** Macros for in-class declarations ****************/
+/* This is just repetitive code that is easier to maintain if it's written
+ only once */
+
+#define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
+ template <class T, class U> \
+ __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &);
+
+#define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \
+ __gmp_expr & fun(signed char); \
+ __gmp_expr & fun(unsigned char); \
+ __gmp_expr & fun(signed int); \
+ __gmp_expr & fun(unsigned int); \
+ __gmp_expr & fun(signed short int); \
+ __gmp_expr & fun(unsigned short int); \
+ __gmp_expr & fun(signed long int); \
+ __gmp_expr & fun(unsigned long int); \
+ __gmp_expr & fun(float); \
+ __gmp_expr & fun(double); \
+ /* __gmp_expr & fun(long double); */
+
+#define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \
+__GMPP_DECLARE_COMPOUND_OPERATOR(fun) \
+__GMPN_DECLARE_COMPOUND_OPERATOR(fun)
+
+#define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \
+ __gmp_expr & fun(mp_bitcnt_t);
+
+#define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \
+ inline __gmp_expr & fun(); \
+ inline __gmp_expr fun(int);
+
+#define __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS \
+ __gmp_expr(signed char c) { init_si(c); } \
+ __gmp_expr(unsigned char c) { init_ui(c); } \
+ __gmp_expr(signed int i) { init_si(i); } \
+ __gmp_expr(unsigned int i) { init_ui(i); } \
+ __gmp_expr(signed short int s) { init_si(s); } \
+ __gmp_expr(unsigned short int s) { init_ui(s); } \
+ __gmp_expr(signed long int l) { init_si(l); } \
+ __gmp_expr(unsigned long int l) { init_ui(l); } \
+ __gmp_expr(float f) { init_d(f); } \
+ __gmp_expr(double d) { init_d(d); }
+
+#define __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS \
+ __gmp_expr & operator=(signed char c) { assign_si(c); return *this; } \
+ __gmp_expr & operator=(unsigned char c) { assign_ui(c); return *this; } \
+ __gmp_expr & operator=(signed int i) { assign_si(i); return *this; } \
+ __gmp_expr & operator=(unsigned int i) { assign_ui(i); return *this; } \
+ __gmp_expr & operator=(signed short int s) { assign_si(s); return *this; } \
+ __gmp_expr & operator=(unsigned short int s) { assign_ui(s); return *this; } \
+ __gmp_expr & operator=(signed long int l) { assign_si(l); return *this; } \
+ __gmp_expr & operator=(unsigned long int l) { assign_ui(l); return *this; } \
+ __gmp_expr & operator=(float f) { assign_d(f); return *this; } \
+ __gmp_expr & operator=(double d) { assign_d(d); return *this; }
+
+/**************** mpz_class -- wrapper for mpz_t ****************/
+
+template <>
+class __gmp_expr<mpz_t, mpz_t>
+{
+private:
+ typedef mpz_t value_type;
+ value_type mp;
+
+ // Helper functions used for all arithmetic types
+ void assign_ui(unsigned long l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l == 0))
+ mp->_mp_size = 0;
+ else
+ mpz_set_ui(mp, l);
+ }
+ void assign_si(signed long l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l >= 0))
+ assign_ui(l);
+ else if (__GMPXX_CONSTANT_TRUE(l <= 0))
+ {
+ assign_ui(-static_cast<unsigned long>(l));
+ mpz_neg(mp, mp);
+ }
+ else
+ mpz_set_si(mp, l);
+ }
+ void assign_d (double d)
+ {
+ mpz_set_d (mp, d);
+ }
+
+ void init_ui(unsigned long l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l == 0))
+ mpz_init(mp);
+ else
+ mpz_init_set_ui(mp, l);
+ }
+ void init_si(signed long l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l >= 0))
+ init_ui(l);
+ else if (__GMPXX_CONSTANT_TRUE(l <= 0))
+ {
+ init_ui(-static_cast<unsigned long>(l));
+ mpz_neg(mp, mp);
+ }
+ else
+ mpz_init_set_si(mp, l);
+ }
+ void init_d (double d)
+ {
+ mpz_init_set_d (mp, d);
+ }
+
+public:
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
+
+ // constructors and destructor
+ __gmp_expr() { mpz_init(mp); }
+
+ __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); }
+#if __GMPXX_USE_CXX11
+ __gmp_expr(__gmp_expr &&z)
+ { *mp = *z.mp; mpz_init(z.mp); }
+#endif
+ template <class T>
+ __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
+ { mpz_init(mp); __gmp_set_expr(mp, expr); }
+ template <class T, class U>
+ explicit __gmp_expr(const __gmp_expr<T, U> &expr)
+ { mpz_init(mp); __gmp_set_expr(mp, expr); }
+
+ __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
+
+ explicit __gmp_expr(const char *s, int base = 0)
+ {
+ if (mpz_init_set_str (mp, s, base) != 0)
+ {
+ mpz_clear (mp);
+ throw std::invalid_argument ("mpz_set_str");
+ }
+ }
+ explicit __gmp_expr(const std::string &s, int base = 0)
+ {
+ if (mpz_init_set_str(mp, s.c_str(), base) != 0)
+ {
+ mpz_clear (mp);
+ throw std::invalid_argument ("mpz_set_str");
+ }
+ }
+
+ explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); }
+
+ ~__gmp_expr() { mpz_clear(mp); }
+
+ void swap(__gmp_expr& z) __GMPXX_NOEXCEPT { std::swap(*mp, *z.mp); }
+
+ // assignment operators
+ __gmp_expr & operator=(const __gmp_expr &z)
+ { mpz_set(mp, z.mp); return *this; }
+#if __GMPXX_USE_CXX11
+ __gmp_expr & operator=(__gmp_expr &&z) noexcept
+ { swap(z); return *this; }
+#endif
+ template <class T, class U>
+ __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
+ { __gmp_set_expr(mp, expr); return *this; }
+
+ __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
+
+ __gmp_expr & operator=(const char *s)
+ {
+ if (mpz_set_str (mp, s, 0) != 0)
+ throw std::invalid_argument ("mpz_set_str");
+ return *this;
+ }
+ __gmp_expr & operator=(const std::string &s)
+ {
+ if (mpz_set_str(mp, s.c_str(), 0) != 0)
+ throw std::invalid_argument ("mpz_set_str");
+ return *this;
+ }
+
+ // string input/output functions
+ int set_str(const char *s, int base)
+ { return mpz_set_str(mp, s, base); }
+ int set_str(const std::string &s, int base)
+ { return mpz_set_str(mp, s.c_str(), base); }
+ std::string get_str(int base = 10) const
+ {
+ __gmp_alloc_cstring temp(mpz_get_str(0, base, mp));
+ return std::string(temp.str);
+ }
+
+ // conversion functions
+ mpz_srcptr __get_mp() const { return mp; }
+ mpz_ptr __get_mp() { return mp; }
+ mpz_srcptr get_mpz_t() const { return mp; }
+ mpz_ptr get_mpz_t() { return mp; }
+
+ signed long int get_si() const { return mpz_get_si(mp); }
+ unsigned long int get_ui() const { return mpz_get_ui(mp); }
+ double get_d() const { return mpz_get_d(mp); }
+
+ // bool fits_schar_p() const { return mpz_fits_schar_p(mp); }
+ // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); }
+ bool fits_sint_p() const { return mpz_fits_sint_p(mp); }
+ bool fits_uint_p() const { return mpz_fits_uint_p(mp); }
+ bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); }
+ bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); }
+ bool fits_slong_p() const { return mpz_fits_slong_p(mp); }
+ bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); }
+ // bool fits_float_p() const { return mpz_fits_float_p(mp); }
+ // bool fits_double_p() const { return mpz_fits_double_p(mp); }
+ // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); }
+
+#if __GMPXX_USE_CXX11
+ explicit operator bool() const { return mp->_mp_size != 0; }
+#endif
+
+ // member operators
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator%=)
+
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator&=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator|=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator^=)
+
+ __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
+ __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
+
+ __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
+ __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
+};
+
+typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
+
+
+/**************** mpq_class -- wrapper for mpq_t ****************/
+
+template <>
+class __gmp_expr<mpq_t, mpq_t>
+{
+private:
+ typedef mpq_t value_type;
+ value_type mp;
+
+ // Helper functions used for all arithmetic types
+ void assign_ui(unsigned long l) { mpq_set_ui(mp, l, 1); }
+ void assign_si(signed long l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l >= 0))
+ assign_ui(l);
+ else
+ mpq_set_si(mp, l, 1);
+ }
+ void assign_d (double d) { mpq_set_d (mp, d); }
+
+ void init_ui(unsigned long l) { mpq_init(mp); get_num() = l; }
+ void init_si(signed long l) { mpq_init(mp); get_num() = l; }
+ void init_d (double d) { mpq_init(mp); assign_d (d); }
+
+public:
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
+ void canonicalize() { mpq_canonicalize(mp); }
+
+ // constructors and destructor
+ __gmp_expr() { mpq_init(mp); }
+
+ __gmp_expr(const __gmp_expr &q)
+ {
+ mpz_init_set(mpq_numref(mp), mpq_numref(q.mp));
+ mpz_init_set(mpq_denref(mp), mpq_denref(q.mp));
+ }
+#if __GMPXX_USE_CXX11
+ __gmp_expr(__gmp_expr &&q)
+ { *mp = *q.mp; mpq_init(q.mp); }
+#endif
+ template <class T>
+ __gmp_expr(const __gmp_expr<mpz_t, T> &expr)
+ { mpq_init(mp); __gmp_set_expr(mp, expr); }
+ template <class T>
+ __gmp_expr(const __gmp_expr<mpq_t, T> &expr)
+ { mpq_init(mp); __gmp_set_expr(mp, expr); }
+ template <class T, class U>
+ explicit __gmp_expr(const __gmp_expr<T, U> &expr)
+ { mpq_init(mp); __gmp_set_expr(mp, expr); }
+
+ __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
+
+ explicit __gmp_expr(const char *s, int base = 0)
+ {
+ mpq_init (mp);
+ // If s is the literal 0, we meant to call another constructor.
+ // If s just happens to evaluate to 0, we would crash, so whatever.
+ if (s == 0)
+ {
+ // Don't turn mpq_class(0,0) into 0
+ mpz_set_si(mpq_denref(mp), base);
+ }
+ else if (mpq_set_str(mp, s, base) != 0)
+ {
+ mpq_clear (mp);
+ throw std::invalid_argument ("mpq_set_str");
+ }
+ }
+ explicit __gmp_expr(const std::string &s, int base = 0)
+ {
+ mpq_init(mp);
+ if (mpq_set_str (mp, s.c_str(), base) != 0)
+ {
+ mpq_clear (mp);
+ throw std::invalid_argument ("mpq_set_str");
+ }
+ }
+ explicit __gmp_expr(mpq_srcptr q)
+ {
+ mpz_init_set(mpq_numref(mp), mpq_numref(q));
+ mpz_init_set(mpq_denref(mp), mpq_denref(q));
+ }
+
+ __gmp_expr(const mpz_class &num, const mpz_class &den)
+ {
+ mpz_init_set(mpq_numref(mp), num.get_mpz_t());
+ mpz_init_set(mpq_denref(mp), den.get_mpz_t());
+ }
+
+ ~__gmp_expr() { mpq_clear(mp); }
+
+ void swap(__gmp_expr& q) __GMPXX_NOEXCEPT { std::swap(*mp, *q.mp); }
+
+ // assignment operators
+ __gmp_expr & operator=(const __gmp_expr &q)
+ { mpq_set(mp, q.mp); return *this; }
+#if __GMPXX_USE_CXX11
+ __gmp_expr & operator=(__gmp_expr &&q) noexcept
+ { swap(q); return *this; }
+ __gmp_expr & operator=(mpz_class &&z) noexcept
+ { get_num() = std::move(z); get_den() = 1u; return *this; }
+#endif
+ template <class T, class U>
+ __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
+ { __gmp_set_expr(mp, expr); return *this; }
+
+ __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
+
+ __gmp_expr & operator=(const char *s)
+ {
+ if (mpq_set_str (mp, s, 0) != 0)
+ throw std::invalid_argument ("mpq_set_str");
+ return *this;
+ }
+ __gmp_expr & operator=(const std::string &s)
+ {
+ if (mpq_set_str(mp, s.c_str(), 0) != 0)
+ throw std::invalid_argument ("mpq_set_str");
+ return *this;
+ }
+
+ // string input/output functions
+ int set_str(const char *s, int base)
+ { return mpq_set_str(mp, s, base); }
+ int set_str(const std::string &s, int base)
+ { return mpq_set_str(mp, s.c_str(), base); }
+ std::string get_str(int base = 10) const
+ {
+ __gmp_alloc_cstring temp(mpq_get_str(0, base, mp));
+ return std::string(temp.str);
+ }
+
+ // conversion functions
+
+ // casting a reference to an mpz_t to mpz_class & is a dirty hack,
+ // but works because the internal representation of mpz_class is
+ // exactly an mpz_t
+ const mpz_class & get_num() const
+ { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); }
+ mpz_class & get_num()
+ { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); }
+ const mpz_class & get_den() const
+ { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); }
+ mpz_class & get_den()
+ { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); }
+
+ mpq_srcptr __get_mp() const { return mp; }
+ mpq_ptr __get_mp() { return mp; }
+ mpq_srcptr get_mpq_t() const { return mp; }
+ mpq_ptr get_mpq_t() { return mp; }
+
+ mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); }
+ mpz_ptr get_num_mpz_t() { return mpq_numref(mp); }
+ mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); }
+ mpz_ptr get_den_mpz_t() { return mpq_denref(mp); }
+
+ double get_d() const { return mpq_get_d(mp); }
+
+#if __GMPXX_USE_CXX11
+ explicit operator bool() const { return mpq_numref(mp)->_mp_size != 0; }
+#endif
+
+ // compound assignments
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
+
+ __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
+ __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
+
+ __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
+ __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
+};
+
+typedef __gmp_expr<mpq_t, mpq_t> mpq_class;
+
+
+/**************** mpf_class -- wrapper for mpf_t ****************/
+
+template <>
+class __gmp_expr<mpf_t, mpf_t>
+{
+private:
+ typedef mpf_t value_type;
+ value_type mp;
+
+ // Helper functions used for all arithmetic types
+ void assign_ui(unsigned long l) { mpf_set_ui(mp, l); }
+ void assign_si(signed long l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l >= 0))
+ assign_ui(l);
+ else
+ mpf_set_si(mp, l);
+ }
+ void assign_d (double d) { mpf_set_d (mp, d); }
+
+ void init_ui(unsigned long l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l == 0))
+ mpf_init(mp);
+ else
+ mpf_init_set_ui(mp, l);
+ }
+ void init_si(signed long l)
+ {
+ if (__GMPXX_CONSTANT_TRUE(l >= 0))
+ init_ui(l);
+ else
+ mpf_init_set_si(mp, l);
+ }
+ void init_d (double d) { mpf_init_set_d (mp, d); }
+
+public:
+ mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); }
+
+ void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); }
+ void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); }
+
+ // constructors and destructor
+ __gmp_expr() { mpf_init(mp); }
+
+ __gmp_expr(const __gmp_expr &f)
+ { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); }
+#if __GMPXX_USE_CXX11
+ __gmp_expr(__gmp_expr &&f)
+ { *mp = *f.mp; mpf_init2(f.mp, get_prec()); }
+#endif
+ __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set(mp, f.mp); }
+ template <class T, class U>
+ __gmp_expr(const __gmp_expr<T, U> &expr)
+ { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
+ template <class T, class U>
+ __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); }
+
+ __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
+
+ __gmp_expr(signed char c, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_si(mp, c); }
+ __gmp_expr(unsigned char c, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_ui(mp, c); }
+
+ __gmp_expr(signed int i, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_si(mp, i); }
+ __gmp_expr(unsigned int i, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_ui(mp, i); }
+
+ __gmp_expr(signed short int s, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_si(mp, s); }
+ __gmp_expr(unsigned short int s, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_ui(mp, s); }
+
+ __gmp_expr(signed long int l, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_si(mp, l); }
+ __gmp_expr(unsigned long int l, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_ui(mp, l); }
+
+ __gmp_expr(float f, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_d(mp, f); }
+ __gmp_expr(double d, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set_d(mp, d); }
+ // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); }
+ // __gmp_expr(long double ld, mp_bitcnt_t prec)
+ // { mpf_init2(mp, prec); mpf_set_d(mp, ld); }
+
+ explicit __gmp_expr(const char *s)
+ {
+ if (mpf_init_set_str (mp, s, 0) != 0)
+ {
+ mpf_clear (mp);
+ throw std::invalid_argument ("mpf_set_str");
+ }
+ }
+ __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0)
+ {
+ mpf_init2(mp, prec);
+ if (mpf_set_str(mp, s, base) != 0)
+ {
+ mpf_clear (mp);
+ throw std::invalid_argument ("mpf_set_str");
+ }
+ }
+ explicit __gmp_expr(const std::string &s)
+ {
+ if (mpf_init_set_str(mp, s.c_str(), 0) != 0)
+ {
+ mpf_clear (mp);
+ throw std::invalid_argument ("mpf_set_str");
+ }
+ }
+ __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0)
+ {
+ mpf_init2(mp, prec);
+ if (mpf_set_str(mp, s.c_str(), base) != 0)
+ {
+ mpf_clear (mp);
+ throw std::invalid_argument ("mpf_set_str");
+ }
+ }
+
+ explicit __gmp_expr(mpf_srcptr f)
+ { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); }
+ __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec)
+ { mpf_init2(mp, prec); mpf_set(mp, f); }
+
+ ~__gmp_expr() { mpf_clear(mp); }
+
+ void swap(__gmp_expr& f) __GMPXX_NOEXCEPT { std::swap(*mp, *f.mp); }
+
+ // assignment operators
+ __gmp_expr & operator=(const __gmp_expr &f)
+ { mpf_set(mp, f.mp); return *this; }
+#if __GMPXX_USE_CXX11
+ __gmp_expr & operator=(__gmp_expr &&f) noexcept
+ { swap(f); return *this; }
+#endif
+ template <class T, class U>
+ __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr)
+ { __gmp_set_expr(mp, expr); return *this; }
+
+ __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
+
+ __gmp_expr & operator=(const char *s)
+ {
+ if (mpf_set_str (mp, s, 0) != 0)
+ throw std::invalid_argument ("mpf_set_str");
+ return *this;
+ }
+ __gmp_expr & operator=(const std::string &s)
+ {
+ if (mpf_set_str(mp, s.c_str(), 0) != 0)
+ throw std::invalid_argument ("mpf_set_str");
+ return *this;
+ }
+
+ // string input/output functions
+ int set_str(const char *s, int base)
+ { return mpf_set_str(mp, s, base); }
+ int set_str(const std::string &s, int base)
+ { return mpf_set_str(mp, s.c_str(), base); }
+ std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const
+ {
+ __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp));
+ return std::string(temp.str);
+ }
+
+ // conversion functions
+ mpf_srcptr __get_mp() const { return mp; }
+ mpf_ptr __get_mp() { return mp; }
+ mpf_srcptr get_mpf_t() const { return mp; }
+ mpf_ptr get_mpf_t() { return mp; }
+
+ signed long int get_si() const { return mpf_get_si(mp); }
+ unsigned long int get_ui() const { return mpf_get_ui(mp); }
+ double get_d() const { return mpf_get_d(mp); }
+
+ // bool fits_schar_p() const { return mpf_fits_schar_p(mp); }
+ // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); }
+ bool fits_sint_p() const { return mpf_fits_sint_p(mp); }
+ bool fits_uint_p() const { return mpf_fits_uint_p(mp); }
+ bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); }
+ bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); }
+ bool fits_slong_p() const { return mpf_fits_slong_p(mp); }
+ bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); }
+ // bool fits_float_p() const { return mpf_fits_float_p(mp); }
+ // bool fits_double_p() const { return mpf_fits_double_p(mp); }
+ // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); }
+
+#if __GMPXX_USE_CXX11
+ explicit operator bool() const { return mp->_mp_size != 0; }
+#endif
+
+ // compound assignments
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator+=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator-=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator*=)
+ __GMP_DECLARE_COMPOUND_OPERATOR(operator/=)
+
+ __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
+ __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
+
+ __GMP_DECLARE_INCREMENT_OPERATOR(operator++)
+ __GMP_DECLARE_INCREMENT_OPERATOR(operator--)
+};
+
+typedef __gmp_expr<mpf_t, mpf_t> mpf_class;
+
+
+
+/**************** User-defined literals ****************/
+
+#if __GMPXX_USE_CXX11
+inline mpz_class operator"" _mpz(const char* s)
+{
+ return mpz_class(s);
+}
+
+inline mpq_class operator"" _mpq(const char* s)
+{
+ mpq_class q;
+ q.get_num() = s;
+ return q;
+}
+
+inline mpf_class operator"" _mpf(const char* s)
+{
+ return mpf_class(s);
+}
+#endif
+
+/**************** I/O operators ****************/
+
+// these should (and will) be provided separately
+
+template <class T, class U>
+inline std::ostream & operator<<
+(std::ostream &o, const __gmp_expr<T, U> &expr)
+{
+ __gmp_expr<T, T> const& temp(expr);
+ return o << temp.__get_mp();
+}
+
+template <class T>
+inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr)
+{
+ return i >> expr.__get_mp();
+}
+
+/*
+// you might want to uncomment this
+inline std::istream & operator>>(std::istream &i, mpq_class &q)
+{
+ i >> q.get_mpq_t();
+ q.canonicalize();
+ return i;
+}
+*/
+
+
+/**************** Functions for type conversion ****************/
+
+inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w)
+{
+ mpz_set(z, w.get_mpz_t());
+}
+
+template <class T>
+inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr)
+{
+ expr.eval(z);
+}
+
+template <class T>
+inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr)
+{
+ mpq_class const& temp(expr);
+ mpz_set_q(z, temp.get_mpq_t());
+}
+
+template <class T>
+inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr)
+{
+ mpf_class const& temp(expr);
+ mpz_set_f(z, temp.get_mpf_t());
+}
+
+inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z)
+{
+ mpq_set_z(q, z.get_mpz_t());
+}
+
+template <class T>
+inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr)
+{
+ __gmp_set_expr(mpq_numref(q), expr);
+ mpz_set_ui(mpq_denref(q), 1);
+}
+
+inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r)
+{
+ mpq_set(q, r.get_mpq_t());
+}
+
+template <class T>
+inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr)
+{
+ expr.eval(q);
+}
+
+template <class T>
+inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr)
+{
+ mpf_class const& temp(expr);
+ mpq_set_f(q, temp.get_mpf_t());
+}
+
+template <class T>
+inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr)
+{
+ mpz_class const& temp(expr);
+ mpf_set_z(f, temp.get_mpz_t());
+}
+
+template <class T>
+inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr)
+{
+ mpq_class const& temp(expr);
+ mpf_set_q(f, temp.get_mpq_t());
+}
+
+inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g)
+{
+ mpf_set(f, g.get_mpf_t());
+}
+
+template <class T>
+inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr)
+{
+ expr.eval(f);
+}
+
+
+/* Temporary objects */
+
+template <class T>
+class __gmp_temp
+{
+ __gmp_expr<T, T> val;
+ public:
+ template<class U, class V>
+ __gmp_temp(U const& u, V) : val (u) {}
+ typename __gmp_resolve_expr<T>::srcptr_type
+ __get_mp() const { return val.__get_mp(); }
+};
+
+template <>
+class __gmp_temp <mpf_t>
+{
+ mpf_class val;
+ public:
+ template<class U>
+ __gmp_temp(U const& u, mpf_ptr res) : val (u, mpf_get_prec(res)) {}
+ mpf_srcptr __get_mp() const { return val.__get_mp(); }
+};
+
+/**************** Specializations of __gmp_expr ****************/
+/* The eval() method of __gmp_expr<T, U> evaluates the corresponding
+ expression and assigns the result to its argument, which is either an
+ mpz_t, mpq_t, or mpf_t as specified by the T argument.
+ Compound expressions are evaluated recursively (temporaries are created
+ to hold intermediate values), while for simple expressions the eval()
+ method of the appropriate function object (available as the Op argument
+ of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is
+ called. */
+
+
+/**************** Unary expressions ****************/
+/* cases:
+ - simple: argument is mp*_class, that is, __gmp_expr<T, T>
+ - compound: argument is __gmp_expr<T, U> (with U not equal to T) */
+
+
+// simple expressions
+
+template <class T, class Op>
+class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
+{
+private:
+ typedef __gmp_expr<T, T> val_type;
+
+ __gmp_unary_expr<val_type, Op> expr;
+public:
+ explicit __gmp_expr(const val_type &val) : expr(val) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ { Op::eval(p, expr.val.__get_mp()); }
+ const val_type & get_val() const { return expr.val; }
+ mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
+};
+
+
+// compound expressions
+
+template <class T, class U, class Op>
+class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
+{
+private:
+ typedef __gmp_expr<T, U> val_type;
+
+ __gmp_unary_expr<val_type, Op> expr;
+public:
+ explicit __gmp_expr(const val_type &val) : expr(val) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ { expr.val.eval(p); Op::eval(p, p); }
+ const val_type & get_val() const { return expr.val; }
+ mp_bitcnt_t get_prec() const { return expr.val.get_prec(); }
+};
+
+
+/**************** Binary expressions ****************/
+/* simple:
+ - arguments are both mp*_class
+ - one argument is mp*_class, one is a built-in type
+ compound:
+ - one is mp*_class, one is __gmp_expr<T, U>
+ - one is __gmp_expr<T, U>, one is built-in
+ - both arguments are __gmp_expr<...> */
+
+
+// simple expressions
+
+template <class T, class Op>
+class __gmp_expr
+<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
+{
+private:
+ typedef __gmp_expr<T, T> val1_type;
+ typedef __gmp_expr<T, T> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const
+ {
+ mp_bitcnt_t prec1 = expr.val1.get_prec(),
+ prec2 = expr.val2.get_prec();
+ return (prec1 > prec2) ? prec1 : prec2;
+ }
+};
+
+
+// simple expressions, T is a built-in numerical type
+
+template <class T, class U, class Op>
+class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
+{
+private:
+ typedef __gmp_expr<T, T> val1_type;
+ typedef U val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ { Op::eval(p, expr.val1.__get_mp(), expr.val2); }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
+};
+
+template <class T, class U, class Op>
+class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
+{
+private:
+ typedef U val1_type;
+ typedef __gmp_expr<T, T> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ { Op::eval(p, expr.val1, expr.val2.__get_mp()); }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
+};
+
+
+// compound expressions, one argument is a subexpression
+
+template <class T, class U, class V, class Op>
+class __gmp_expr
+<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
+{
+private:
+ typedef __gmp_expr<T, T> val1_type;
+ typedef __gmp_expr<U, V> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ {
+ if(p != expr.val1.__get_mp())
+ {
+ __gmp_set_expr(p, expr.val2);
+ Op::eval(p, expr.val1.__get_mp(), p);
+ }
+ else
+ {
+ __gmp_temp<T> temp(expr.val2, p);
+ Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
+ }
+ }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const
+ {
+ mp_bitcnt_t prec1 = expr.val1.get_prec(),
+ prec2 = expr.val2.get_prec();
+ return (prec1 > prec2) ? prec1 : prec2;
+ }
+};
+
+template <class T, class U, class V, class Op>
+class __gmp_expr
+<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
+{
+private:
+ typedef __gmp_expr<U, V> val1_type;
+ typedef __gmp_expr<T, T> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ {
+ if(p != expr.val2.__get_mp())
+ {
+ __gmp_set_expr(p, expr.val1);
+ Op::eval(p, p, expr.val2.__get_mp());
+ }
+ else
+ {
+ __gmp_temp<T> temp(expr.val1, p);
+ Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
+ }
+ }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const
+ {
+ mp_bitcnt_t prec1 = expr.val1.get_prec(),
+ prec2 = expr.val2.get_prec();
+ return (prec1 > prec2) ? prec1 : prec2;
+ }
+};
+
+template <class T, class U, class Op>
+class __gmp_expr
+<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
+{
+private:
+ typedef __gmp_expr<T, T> val1_type;
+ typedef __gmp_expr<T, U> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ {
+ if(p != expr.val1.__get_mp())
+ {
+ __gmp_set_expr(p, expr.val2);
+ Op::eval(p, expr.val1.__get_mp(), p);
+ }
+ else
+ {
+ __gmp_temp<T> temp(expr.val2, p);
+ Op::eval(p, expr.val1.__get_mp(), temp.__get_mp());
+ }
+ }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const
+ {
+ mp_bitcnt_t prec1 = expr.val1.get_prec(),
+ prec2 = expr.val2.get_prec();
+ return (prec1 > prec2) ? prec1 : prec2;
+ }
+};
+
+template <class T, class U, class Op>
+class __gmp_expr
+<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
+{
+private:
+ typedef __gmp_expr<T, U> val1_type;
+ typedef __gmp_expr<T, T> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ {
+ if(p != expr.val2.__get_mp())
+ {
+ __gmp_set_expr(p, expr.val1);
+ Op::eval(p, p, expr.val2.__get_mp());
+ }
+ else
+ {
+ __gmp_temp<T> temp(expr.val1, p);
+ Op::eval(p, temp.__get_mp(), expr.val2.__get_mp());
+ }
+ }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const
+ {
+ mp_bitcnt_t prec1 = expr.val1.get_prec(),
+ prec2 = expr.val2.get_prec();
+ return (prec1 > prec2) ? prec1 : prec2;
+ }
+};
+
+
+// one argument is a subexpression, one is a built-in
+
+template <class T, class U, class V, class Op>
+class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
+{
+private:
+ typedef __gmp_expr<T, U> val1_type;
+ typedef V val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ {
+ expr.val1.eval(p);
+ Op::eval(p, p, expr.val2);
+ }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const { return expr.val1.get_prec(); }
+};
+
+template <class T, class U, class V, class Op>
+class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
+{
+private:
+ typedef U val1_type;
+ typedef __gmp_expr<T, V> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ {
+ expr.val2.eval(p);
+ Op::eval(p, expr.val1, p);
+ }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const { return expr.val2.get_prec(); }
+};
+
+
+// both arguments are subexpressions
+
+template <class T, class U, class V, class W, class Op>
+class __gmp_expr
+<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
+{
+private:
+ typedef __gmp_expr<T, U> val1_type;
+ typedef __gmp_expr<V, W> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ {
+ __gmp_temp<T> temp2(expr.val2, p);
+ expr.val1.eval(p);
+ Op::eval(p, p, temp2.__get_mp());
+ }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const
+ {
+ mp_bitcnt_t prec1 = expr.val1.get_prec(),
+ prec2 = expr.val2.get_prec();
+ return (prec1 > prec2) ? prec1 : prec2;
+ }
+};
+
+template <class T, class U, class V, class W, class Op>
+class __gmp_expr
+<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
+{
+private:
+ typedef __gmp_expr<U, V> val1_type;
+ typedef __gmp_expr<T, W> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ {
+ __gmp_temp<T> temp1(expr.val1, p);
+ expr.val2.eval(p);
+ Op::eval(p, temp1.__get_mp(), p);
+ }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const
+ {
+ mp_bitcnt_t prec1 = expr.val1.get_prec(),
+ prec2 = expr.val2.get_prec();
+ return (prec1 > prec2) ? prec1 : prec2;
+ }
+};
+
+template <class T, class U, class V, class Op>
+class __gmp_expr
+<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
+{
+private:
+ typedef __gmp_expr<T, U> val1_type;
+ typedef __gmp_expr<T, V> val2_type;
+
+ __gmp_binary_expr<val1_type, val2_type, Op> expr;
+public:
+ __gmp_expr(const val1_type &val1, const val2_type &val2)
+ : expr(val1, val2) { }
+ void eval(typename __gmp_resolve_expr<T>::ptr_type p) const
+ {
+ __gmp_temp<T> temp2(expr.val2, p);
+ expr.val1.eval(p);
+ Op::eval(p, p, temp2.__get_mp());
+ }
+ const val1_type & get_val1() const { return expr.val1; }
+ const val2_type & get_val2() const { return expr.val2; }
+ mp_bitcnt_t get_prec() const
+ {
+ mp_bitcnt_t prec1 = expr.val1.get_prec(),
+ prec2 = expr.val2.get_prec();
+ return (prec1 > prec2) ? prec1 : prec2;
+ }
+};
+
+
+/**************** Special cases ****************/
+
+/* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments
+ can be done directly without first converting the mpz to mpq.
+ Appropriate specializations of __gmp_expr are required. */
+
+
+#define __GMPZQ_DEFINE_EXPR(eval_fun) \
+ \
+template <> \
+class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \
+{ \
+private: \
+ typedef mpz_class val1_type; \
+ typedef mpq_class val2_type; \
+ \
+ __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
+public: \
+ __gmp_expr(const val1_type &val1, const val2_type &val2) \
+ : expr(val1, val2) { } \
+ void eval(mpq_ptr q) const \
+ { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \
+ const val1_type & get_val1() const { return expr.val1; } \
+ const val2_type & get_val2() const { return expr.val2; } \
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
+}; \
+ \
+template <> \
+class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \
+{ \
+private: \
+ typedef mpq_class val1_type; \
+ typedef mpz_class val2_type; \
+ \
+ __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
+public: \
+ __gmp_expr(const val1_type &val1, const val2_type &val2) \
+ : expr(val1, val2) { } \
+ void eval(mpq_ptr q) const \
+ { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \
+ const val1_type & get_val1() const { return expr.val1; } \
+ const val2_type & get_val2() const { return expr.val2; } \
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
+}; \
+ \
+template <class T> \
+class __gmp_expr \
+<mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \
+{ \
+private: \
+ typedef mpz_class val1_type; \
+ typedef __gmp_expr<mpq_t, T> val2_type; \
+ \
+ __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
+public: \
+ __gmp_expr(const val1_type &val1, const val2_type &val2) \
+ : expr(val1, val2) { } \
+ void eval(mpq_ptr q) const \
+ { \
+ mpq_class temp(expr.val2); \
+ eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \
+ } \
+ const val1_type & get_val1() const { return expr.val1; } \
+ const val2_type & get_val2() const { return expr.val2; } \
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
+}; \
+ \
+template <class T> \
+class __gmp_expr \
+<mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \
+{ \
+private: \
+ typedef mpq_class val1_type; \
+ typedef __gmp_expr<mpz_t, T> val2_type; \
+ \
+ __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
+public: \
+ __gmp_expr(const val1_type &val1, const val2_type &val2) \
+ : expr(val1, val2) { } \
+ void eval(mpq_ptr q) const \
+ { \
+ mpz_class temp(expr.val2); \
+ eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \
+ } \
+ const val1_type & get_val1() const { return expr.val1; } \
+ const val2_type & get_val2() const { return expr.val2; } \
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
+}; \
+ \
+template <class T> \
+class __gmp_expr \
+<mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \
+{ \
+private: \
+ typedef __gmp_expr<mpz_t, T> val1_type; \
+ typedef mpq_class val2_type; \
+ \
+ __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
+public: \
+ __gmp_expr(const val1_type &val1, const val2_type &val2) \
+ : expr(val1, val2) { } \
+ void eval(mpq_ptr q) const \
+ { \
+ mpz_class temp(expr.val1); \
+ eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \
+ } \
+ const val1_type & get_val1() const { return expr.val1; } \
+ const val2_type & get_val2() const { return expr.val2; } \
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
+}; \
+ \
+template <class T> \
+class __gmp_expr \
+<mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \
+{ \
+private: \
+ typedef __gmp_expr<mpq_t, T> val1_type; \
+ typedef mpz_class val2_type; \
+ \
+ __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
+public: \
+ __gmp_expr(const val1_type &val1, const val2_type &val2) \
+ : expr(val1, val2) { } \
+ void eval(mpq_ptr q) const \
+ { \
+ mpq_class temp(expr.val1); \
+ eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \
+ } \
+ const val1_type & get_val1() const { return expr.val1; } \
+ const val2_type & get_val2() const { return expr.val2; } \
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
+}; \
+ \
+template <class T, class U> \
+class __gmp_expr<mpq_t, __gmp_binary_expr \
+<__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \
+{ \
+private: \
+ typedef __gmp_expr<mpz_t, T> val1_type; \
+ typedef __gmp_expr<mpq_t, U> val2_type; \
+ \
+ __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
+public: \
+ __gmp_expr(const val1_type &val1, const val2_type &val2) \
+ : expr(val1, val2) { } \
+ void eval(mpq_ptr q) const \
+ { \
+ mpz_class temp1(expr.val1); \
+ expr.val2.eval(q); \
+ eval_fun::eval(q, temp1.get_mpz_t(), q); \
+ } \
+ const val1_type & get_val1() const { return expr.val1; } \
+ const val2_type & get_val2() const { return expr.val2; } \
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
+}; \
+ \
+template <class T, class U> \
+class __gmp_expr<mpq_t, __gmp_binary_expr \
+<__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \
+{ \
+private: \
+ typedef __gmp_expr<mpq_t, T> val1_type; \
+ typedef __gmp_expr<mpz_t, U> val2_type; \
+ \
+ __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \
+public: \
+ __gmp_expr(const val1_type &val1, const val2_type &val2) \
+ : expr(val1, val2) { } \
+ void eval(mpq_ptr q) const \
+ { \
+ mpz_class temp2(expr.val2); \
+ expr.val1.eval(q); \
+ eval_fun::eval(q, q, temp2.get_mpz_t()); \
+ } \
+ const val1_type & get_val1() const { return expr.val1; } \
+ const val2_type & get_val2() const { return expr.val2; } \
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } \
+};
+
+
+__GMPZQ_DEFINE_EXPR(__gmp_binary_plus)
+__GMPZQ_DEFINE_EXPR(__gmp_binary_minus)
+
+
+
+/**************** Macros for defining functions ****************/
+/* Results of operators and functions are instances of __gmp_expr<T, U>.
+ T determines the numerical type of the expression: it can be either
+ mpz_t, mpq_t, or mpf_t. When the arguments of a binary
+ expression have different numerical types, __gmp_resolve_expr is used
+ to determine the "larger" type.
+ U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>,
+ where V and W are the arguments' types -- they can in turn be
+ expressions, thus allowing to build compound expressions to any
+ degree of complexity.
+ Op is a function object that must have an eval() method accepting
+ appropriate arguments.
+ Actual evaluation of a __gmp_expr<T, U> object is done when it gets
+ assigned to an mp*_class ("lazy" evaluation): this is done by calling
+ its eval() method. */
+
+
+// non-member unary operators and functions
+
+#define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \
+ \
+template <class T, class U> \
+inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \
+fun(const __gmp_expr<T, U> &expr) \
+{ \
+ return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \
+}
+
+#define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \
+ \
+template <class T, class U> \
+inline type fun(const __gmp_expr<T, U> &expr) \
+{ \
+ __gmp_expr<T, T> const& temp(expr); \
+ return eval_fun::eval(temp.__get_mp()); \
+}
+
+
+// non-member binary operators and functions
+
+#define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
+ \
+template <class T, class U, class V, class W> \
+inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
+__gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
+fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \
+{ \
+ return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \
+ __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \
+ (expr1, expr2); \
+}
+
+#define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \
+ \
+template <class T, class U> \
+inline __gmp_expr \
+<T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \
+fun(const __gmp_expr<T, U> &expr, type t) \
+{ \
+ return __gmp_expr \
+ <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \
+} \
+ \
+template <class T, class U> \
+inline __gmp_expr \
+<T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \
+fun(type t, const __gmp_expr<T, U> &expr) \
+{ \
+ return __gmp_expr \
+ <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \
+}
+
+#define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
+__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int)
+
+#define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
+__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int)
+
+#define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
+__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double)
+
+#define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \
+__GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double)
+
+#define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
+__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \
+__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \
+__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \
+__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \
+__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \
+__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \
+__GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \
+__GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \
+__GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \
+__GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \
+/* __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) */
+
+#define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
+__GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \
+__GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun)
+
+
+#define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \
+ \
+template <class T, class U> \
+inline __gmp_expr \
+<T, __gmp_binary_expr<__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> > \
+fun(const __gmp_expr<T, U> &expr, mp_bitcnt_t l) \
+{ \
+ return __gmp_expr<T, __gmp_binary_expr \
+ <__gmp_expr<T, U>, mp_bitcnt_t, eval_fun> >(expr, l); \
+}
+
+
+#define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
+ \
+template <class T, class U, class V, class W> \
+inline type fun(const __gmp_expr<T, U> &expr1, \
+ const __gmp_expr<V, W> &expr2) \
+{ \
+ typedef typename __gmp_resolve_expr<T, V>::value_type eval_type; \
+ __gmp_expr<eval_type, eval_type> const& temp1(expr1); \
+ __gmp_expr<eval_type, eval_type> const& temp2(expr2); \
+ return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \
+}
+
+#define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
+ type2, bigtype) \
+ \
+template <class T, class U> \
+inline type fun(const __gmp_expr<T, U> &expr, type2 t) \
+{ \
+ __gmp_expr<T, T> const& temp(expr); \
+ return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \
+} \
+ \
+template <class T, class U> \
+inline type fun(type2 t, const __gmp_expr<T, U> &expr) \
+{ \
+ __gmp_expr<T, T> const& temp(expr); \
+ return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \
+}
+
+#define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
+__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
+ type2, signed long int)
+
+#define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
+__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \
+ type2, unsigned long int)
+
+#define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
+__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double)
+
+#define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \
+__GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double)
+
+#define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
+__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \
+__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \
+__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \
+__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \
+__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \
+__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \
+__GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \
+__GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \
+__GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \
+__GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \
+/* __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) */
+
+#define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
+__GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \
+__GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun)
+
+
+// member operators
+
+#define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
+ \
+template <class T, class U> \
+inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \
+{ \
+ __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
+ <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \
+ return *this; \
+}
+
+#define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
+ type2, bigtype) \
+ \
+inline type##_class & type##_class::fun(type2 t) \
+{ \
+ __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
+ <type##_class, bigtype, eval_fun> >(*this, t)); \
+ return *this; \
+}
+
+#define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
+__GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
+ type2, signed long int)
+
+#define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
+__GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \
+ type2, unsigned long int)
+
+#define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
+__GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double)
+
+#define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \
+__GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double)
+
+#define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
+__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \
+__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \
+__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \
+__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \
+__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \
+__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \
+__GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \
+__GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \
+__GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \
+__GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \
+/* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */
+
+#define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
+__GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \
+__GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun)
+
+#define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
+__GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun)
+
+#define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
+__GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun)
+
+#define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
+__GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun)
+
+
+
+#define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \
+ \
+inline type##_class & type##_class::fun(mp_bitcnt_t l) \
+{ \
+ __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \
+ <type##_class, mp_bitcnt_t, eval_fun> >(*this, l)); \
+ return *this; \
+}
+
+#define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
+__GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun)
+
+#define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
+__GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun)
+
+#define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
+__GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun)
+
+
+
+#define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \
+ \
+inline type##_class & type##_class::fun() \
+{ \
+ eval_fun::eval(mp); \
+ return *this; \
+} \
+ \
+inline type##_class type##_class::fun(int) \
+{ \
+ type##_class temp(*this); \
+ eval_fun::eval(mp); \
+ return temp; \
+}
+
+#define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
+__GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun)
+
+#define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
+__GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun)
+
+#define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
+__GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun)
+
+
+
+/**************** Arithmetic operators and functions ****************/
+
+// non-member operators and functions
+
+__GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus)
+__GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus)
+__GMP_DEFINE_UNARY_FUNCTION(operator~, __gmp_unary_com)
+
+__GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus)
+__GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus)
+__GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies)
+__GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides)
+__GMP_DEFINE_BINARY_FUNCTION(operator%, __gmp_binary_modulus)
+__GMP_DEFINE_BINARY_FUNCTION(operator&, __gmp_binary_and)
+__GMP_DEFINE_BINARY_FUNCTION(operator|, __gmp_binary_ior)
+__GMP_DEFINE_BINARY_FUNCTION(operator^, __gmp_binary_xor)
+
+__GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift)
+__GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift)
+
+__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal)
+__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, ! __gmp_binary_equal)
+__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less)
+__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, ! __gmp_binary_greater)
+__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater)
+__GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, ! __gmp_binary_less)
+
+__GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function)
+__GMP_DEFINE_UNARY_FUNCTION(trunc, __gmp_trunc_function)
+__GMP_DEFINE_UNARY_FUNCTION(floor, __gmp_floor_function)
+__GMP_DEFINE_UNARY_FUNCTION(ceil, __gmp_ceil_function)
+__GMP_DEFINE_UNARY_FUNCTION(sqrt, __gmp_sqrt_function)
+__GMP_DEFINE_BINARY_FUNCTION(hypot, __gmp_hypot_function)
+
+__GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function)
+__GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function)
+
+template <class T>
+void swap(__gmp_expr<T, T>& x, __gmp_expr<T, T>& y) __GMPXX_NOEXCEPT
+{ x.swap(y); }
+
+// member operators for mpz_class
+
+__GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
+__GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
+__GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
+__GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
+__GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus)
+
+__GMPZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and)
+__GMPZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior)
+__GMPZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor)
+
+__GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
+__GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
+
+__GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
+__GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
+
+// member operators for mpq_class
+
+__GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
+__GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
+__GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
+__GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
+
+__GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
+__GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
+
+__GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
+__GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
+
+// member operators for mpf_class
+
+__GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
+__GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
+__GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
+__GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
+
+__GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
+__GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
+
+__GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
+__GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
+
+
+
+/**************** Class wrapper for gmp_randstate_t ****************/
+
+class __gmp_urandomb_value { };
+class __gmp_urandomm_value { };
+
+template <>
+class __gmp_expr<mpz_t, __gmp_urandomb_value>
+{
+private:
+ __gmp_randstate_struct *state;
+ mp_bitcnt_t bits;
+public:
+ __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
+ void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); }
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
+};
+
+template <>
+class __gmp_expr<mpz_t, __gmp_urandomm_value>
+{
+private:
+ __gmp_randstate_struct *state;
+ mpz_class range;
+public:
+ __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { }
+ void eval(mpz_ptr z) const
+ { __gmp_rand_function::eval(z, state, range.get_mpz_t()); }
+ mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); }
+};
+
+template <>
+class __gmp_expr<mpf_t, __gmp_urandomb_value>
+{
+private:
+ __gmp_randstate_struct *state;
+ mp_bitcnt_t bits;
+public:
+ __gmp_expr(gmp_randstate_t s, mp_bitcnt_t l) : state(s), bits(l) { }
+ void eval(mpf_ptr f) const
+ {
+ __gmp_rand_function::eval(f, state,
+ (bits>0) ? bits : mpf_get_prec(f));
+ }
+ mp_bitcnt_t get_prec() const
+ {
+ if (bits == 0)
+ return mpf_get_default_prec();
+ else
+ return bits;
+ }
+};
+
+extern "C" {
+ typedef void __gmp_randinit_default_t (gmp_randstate_t);
+ typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t);
+ typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t);
+}
+
+class gmp_randclass
+{
+private:
+ gmp_randstate_t state;
+
+ // copy construction and assignment not allowed
+ gmp_randclass(const gmp_randclass &);
+ void operator=(const gmp_randclass &);
+public:
+ // constructors and destructor
+ gmp_randclass(gmp_randalg_t alg, unsigned long int size)
+ {
+ switch (alg)
+ {
+ case GMP_RAND_ALG_LC: // no other cases for now
+ default:
+ gmp_randinit(state, alg, size);
+ break;
+ }
+ }
+
+ // gmp_randinit_default
+ gmp_randclass(__gmp_randinit_default_t* f) { f(state); }
+
+ // gmp_randinit_lc_2exp
+ gmp_randclass(__gmp_randinit_lc_2exp_t* f,
+ mpz_class z, unsigned long int l1, mp_bitcnt_t l2)
+ { f(state, z.get_mpz_t(), l1, l2); }
+
+ // gmp_randinit_lc_2exp_size
+ gmp_randclass(__gmp_randinit_lc_2exp_size_t* f,
+ mp_bitcnt_t size)
+ {
+ if (f (state, size) == 0)
+ throw std::length_error ("gmp_randinit_lc_2exp_size");
+ }
+
+ ~gmp_randclass() { gmp_randclear(state); }
+
+ // initialize
+ void seed(); // choose a random seed some way (?)
+ void seed(unsigned long int s) { gmp_randseed_ui(state, s); }
+ void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); }
+
+ // get random number
+ __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(mp_bitcnt_t l)
+ { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); }
+ __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z)
+ { return get_z_bits(z.get_ui()); }
+ // FIXME: z.get_bitcnt_t() ?
+
+ __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z)
+ { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); }
+
+ __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(mp_bitcnt_t prec = 0)
+ { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); }
+};
+
+
+/**************** Specialize std::numeric_limits ****************/
+
+namespace std {
+ template <> class numeric_limits<mpz_class>
+ {
+ public:
+ static const bool is_specialized = true;
+ static mpz_class min() { return mpz_class(); }
+ static mpz_class max() { return mpz_class(); }
+ static mpz_class lowest() { return mpz_class(); }
+ static const int digits = 0;
+ static const int digits10 = 0;
+ static const int max_digits10 = 0;
+ static const bool is_signed = true;
+ static const bool is_integer = true;
+ static const bool is_exact = true;
+ static const int radix = 2;
+ static mpz_class epsilon() { return mpz_class(); }
+ static mpz_class round_error() { return mpz_class(); }
+ static const int min_exponent = 0;
+ static const int min_exponent10 = 0;
+ static const int max_exponent = 0;
+ static const int max_exponent10 = 0;
+ static const bool has_infinity = false;
+ static const bool has_quiet_NaN = false;
+ static const bool has_signaling_NaN = false;
+ static const float_denorm_style has_denorm = denorm_absent;
+ static const bool has_denorm_loss = false;
+ static mpz_class infinity() { return mpz_class(); }
+ static mpz_class quiet_NaN() { return mpz_class(); }
+ static mpz_class signaling_NaN() { return mpz_class(); }
+ static mpz_class denorm_min() { return mpz_class(); }
+ static const bool is_iec559 = false;
+ static const bool is_bounded = false;
+ static const bool is_modulo = false;
+ static const bool traps = false;
+ static const bool tinyness_before = false;
+ static const float_round_style round_style = round_toward_zero;
+ };
+
+ template <> class numeric_limits<mpq_class>
+ {
+ public:
+ static const bool is_specialized = true;
+ static mpq_class min() { return mpq_class(); }
+ static mpq_class max() { return mpq_class(); }
+ static mpq_class lowest() { return mpq_class(); }
+ static const int digits = 0;
+ static const int digits10 = 0;
+ static const int max_digits10 = 0;
+ static const bool is_signed = true;
+ static const bool is_integer = false;
+ static const bool is_exact = true;
+ static const int radix = 2;
+ static mpq_class epsilon() { return mpq_class(); }
+ static mpq_class round_error() { return mpq_class(); }
+ static const int min_exponent = 0;
+ static const int min_exponent10 = 0;
+ static const int max_exponent = 0;
+ static const int max_exponent10 = 0;
+ static const bool has_infinity = false;
+ static const bool has_quiet_NaN = false;
+ static const bool has_signaling_NaN = false;
+ static const float_denorm_style has_denorm = denorm_absent;
+ static const bool has_denorm_loss = false;
+ static mpq_class infinity() { return mpq_class(); }
+ static mpq_class quiet_NaN() { return mpq_class(); }
+ static mpq_class signaling_NaN() { return mpq_class(); }
+ static mpq_class denorm_min() { return mpq_class(); }
+ static const bool is_iec559 = false;
+ static const bool is_bounded = false;
+ static const bool is_modulo = false;
+ static const bool traps = false;
+ static const bool tinyness_before = false;
+ static const float_round_style round_style = round_toward_zero;
+ };
+
+ template <> class numeric_limits<mpf_class>
+ {
+ public:
+ static const bool is_specialized = true;
+ static mpf_class min() { return mpf_class(); }
+ static mpf_class max() { return mpf_class(); }
+ static mpf_class lowest() { return mpf_class(); }
+ static const int digits = 0;
+ static const int digits10 = 0;
+ static const int max_digits10 = 0;
+ static const bool is_signed = true;
+ static const bool is_integer = false;
+ static const bool is_exact = false;
+ static const int radix = 2;
+ static mpf_class epsilon() { return mpf_class(); }
+ static mpf_class round_error() { return mpf_class(); }
+ static const int min_exponent = 0;
+ static const int min_exponent10 = 0;
+ static const int max_exponent = 0;
+ static const int max_exponent10 = 0;
+ static const bool has_infinity = false;
+ static const bool has_quiet_NaN = false;
+ static const bool has_signaling_NaN = false;
+ static const float_denorm_style has_denorm = denorm_absent;
+ static const bool has_denorm_loss = false;
+ static mpf_class infinity() { return mpf_class(); }
+ static mpf_class quiet_NaN() { return mpf_class(); }
+ static mpf_class signaling_NaN() { return mpf_class(); }
+ static mpf_class denorm_min() { return mpf_class(); }
+ static const bool is_iec559 = false;
+ static const bool is_bounded = false;
+ static const bool is_modulo = false;
+ static const bool traps = false;
+ static const bool tinyness_before = false;
+ static const float_round_style round_style = round_indeterminate;
+ };
+}
+
+
+/**************** #undef all private macros ****************/
+
+#undef __GMPP_DECLARE_COMPOUND_OPERATOR
+#undef __GMPN_DECLARE_COMPOUND_OPERATOR
+#undef __GMP_DECLARE_COMPOUND_OPERATOR
+#undef __GMP_DECLARE_COMPOUND_OPERATOR_UI
+#undef __GMP_DECLARE_INCREMENT_OPERATOR
+#undef __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
+#undef __GMPXX_DEFINE_ARITHMETIC_ASSIGNMENTS
+
+#undef __GMPZQ_DEFINE_EXPR
+
+#undef __GMP_DEFINE_UNARY_FUNCTION
+#undef __GMP_DEFINE_UNARY_TYPE_FUNCTION
+
+#undef __GMPP_DEFINE_BINARY_FUNCTION
+#undef __GMPNN_DEFINE_BINARY_FUNCTION
+#undef __GMPNS_DEFINE_BINARY_FUNCTION
+#undef __GMPNU_DEFINE_BINARY_FUNCTION
+#undef __GMPND_DEFINE_BINARY_FUNCTION
+#undef __GMPNLD_DEFINE_BINARY_FUNCTION
+#undef __GMPN_DEFINE_BINARY_FUNCTION
+#undef __GMP_DEFINE_BINARY_FUNCTION
+
+#undef __GMP_DEFINE_BINARY_FUNCTION_UI
+
+#undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION
+#undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION
+#undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION
+#undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION
+#undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION
+#undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION
+#undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION
+#undef __GMP_DEFINE_BINARY_TYPE_FUNCTION
+
+#undef __GMPZ_DEFINE_COMPOUND_OPERATOR
+
+#undef __GMPP_DEFINE_COMPOUND_OPERATOR
+#undef __GMPNN_DEFINE_COMPOUND_OPERATOR
+#undef __GMPNS_DEFINE_COMPOUND_OPERATOR
+#undef __GMPNU_DEFINE_COMPOUND_OPERATOR
+#undef __GMPND_DEFINE_COMPOUND_OPERATOR
+#undef __GMPNLD_DEFINE_COMPOUND_OPERATOR
+#undef __GMPN_DEFINE_COMPOUND_OPERATOR
+#undef __GMP_DEFINE_COMPOUND_OPERATOR
+
+#undef __GMPQ_DEFINE_COMPOUND_OPERATOR
+#undef __GMPF_DEFINE_COMPOUND_OPERATOR
+
+#undef __GMP_DEFINE_COMPOUND_OPERATOR_UI
+#undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI
+#undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI
+#undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI
+
+#undef __GMP_DEFINE_INCREMENT_OPERATOR
+#undef __GMPZ_DEFINE_INCREMENT_OPERATOR
+#undef __GMPQ_DEFINE_INCREMENT_OPERATOR
+#undef __GMPF_DEFINE_INCREMENT_OPERATOR
+
+#undef __GMPXX_CONSTANT_TRUE
+#undef __GMPXX_CONSTANT
+
+#endif /* __GMP_PLUSPLUS__ */
diff --git a/gmp/install-sh b/gmp/install-sh
new file mode 100755
index 0000000000..a9244eb078
--- /dev/null
+++ b/gmp/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-01-19.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for `test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/gmp/invalid.c b/gmp/invalid.c
new file mode 100644
index 0000000000..81d6720c0d
--- /dev/null
+++ b/gmp/invalid.c
@@ -0,0 +1,83 @@
+/* __gmp_invalid_operation -- invalid floating point operation.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#include <signal.h>
+#include <stdlib.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for getpid */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Incidentally, kill is not available on mingw, but that's ok, it has raise
+ and we'll be using that. */
+#if ! HAVE_RAISE
+#define raise(sig) kill (getpid(), sig)
+#endif
+
+
+/* __gmp_invalid_operation is for an invalid floating point operation, like
+ mpz_set_d on a NaN or Inf. It's done as a subroutine to minimize code in
+ places raising an exception.
+
+ feraiseexcept(FE_INVALID) is not used here, since unfortunately on most
+ systems it would require libm.
+
+ Alternatives:
+
+ It might be possible to check whether a hardware "invalid operation" trap
+ is enabled or not before raising a signal. This would require all
+ callers to be prepared to continue with some bogus result. Bogus returns
+ are bad, but presumably an application disabling the trap is prepared for
+ that.
+
+ On some systems (eg. BSD) the signal handler can find out the reason for
+ a SIGFPE (overflow, invalid, div-by-zero, etc). Perhaps we could get
+ that into our raise too.
+
+ i386 GLIBC implements feraiseexcept(FE_INVALID) with an asm fdiv 0/0.
+ That would both respect the exceptions mask and give a reason code in a
+ BSD signal. */
+
+void
+__gmp_invalid_operation (void)
+{
+ raise (SIGFPE);
+ abort ();
+}
diff --git a/gmp/longlong.h b/gmp/longlong.h
new file mode 100644
index 0000000000..f144dee9e7
--- /dev/null
+++ b/gmp/longlong.h
@@ -0,0 +1,2183 @@
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
+
+Copyright 1991-1994, 1996, 1997, 1999-2005, 2007-2009, 2011-2013 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* You have to define the following before including this file:
+
+ UWtype -- An unsigned type, default type for operations (typically a "word")
+ UHWtype -- An unsigned type, at least half the size of UWtype
+ UDWtype -- An unsigned type, at least twice as large a UWtype
+ W_TYPE_SIZE -- size in bits of UWtype
+
+ SItype, USItype -- Signed and unsigned 32 bit types
+ DItype, UDItype -- Signed and unsigned 64 bit types
+
+ On a 32 bit machine UWtype should typically be USItype;
+ on a 64 bit machine, UWtype should typically be UDItype.
+
+ Optionally, define:
+
+ LONGLONG_STANDALONE -- Avoid code that needs machine-dependent support files
+ NO_ASM -- Disable inline asm
+
+
+ CAUTION! Using this version of longlong.h outside of GMP is not safe. You
+ need to include gmp.h and gmp-impl.h, or certain things might not work as
+ expected.
+*/
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+/* This is used to make sure no undesirable sharing between different libraries
+ that use this file takes place. */
+#ifndef __MPN
+#define __MPN(x) __##x
+#endif
+
+/* Define auxiliary asm macros.
+
+ 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
+ UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype
+ word product in HIGH_PROD and LOW_PROD.
+
+ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
+ UDWtype product. This is just a variant of umul_ppmm.
+
+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator) divides a UDWtype, composed by the UWtype integers
+ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
+ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
+ than DENOMINATOR for correct operation. If, in addition, the most
+ significant bit of DENOMINATOR must be 1, then the pre-processor symbol
+ UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator). Like udiv_qrnnd but the numbers are signed. The quotient
+ is rounded towards 0.
+
+ 5) count_leading_zeros(count, x) counts the number of zero-bits from the
+ msb to the first non-zero bit in the UWtype X. This is the number of
+ steps X needs to be shifted left to set the msb. Undefined for X == 0,
+ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
+
+ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
+ from the least significant end.
+
+ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+ high_addend_2, low_addend_2) adds two UWtype integers, composed by
+ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
+ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
+ (i.e. carry out) is not stored anywhere, and is lost.
+
+ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
+ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
+ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
+ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
+ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ and is lost.
+
+ If any of these macros are left undefined for a particular CPU,
+ C macros are used.
+
+
+ Notes:
+
+ For add_ssaaaa the two high and two low addends can both commute, but
+ unfortunately gcc only supports one "%" commutative in each asm block.
+ This has always been so but is only documented in recent versions
+ (eg. pre-release 3.3). Having two or more "%"s can cause an internal
+ compiler error in certain rare circumstances.
+
+ Apparently it was only the last "%" that was ever actually respected, so
+ the code has been updated to leave just that. Clearly there's a free
+ choice whether high or low should get it, if there's a reason to favour
+ one over the other. Also obviously when the constraints on the two
+ operands are identical there's no benefit to the reloader in any "%" at
+ all.
+
+ */
+
+/* The CPUs come in alphabetical order below.
+
+ Please add support for more CPUs here, or improve the current support
+ for the CPUs below! */
+
+
+/* count_leading_zeros_gcc_clz is count_leading_zeros implemented with gcc
+ 3.4 __builtin_clzl or __builtin_clzll, according to our limb size.
+ Similarly count_trailing_zeros_gcc_ctz using __builtin_ctzl or
+ __builtin_ctzll.
+
+ These builtins are only used when we check what code comes out, on some
+ chips they're merely libgcc calls, where we will instead want an inline
+ in that case (either asm or generic C).
+
+ These builtins are better than an asm block of the same insn, since an
+ asm block doesn't give gcc any information about scheduling or resource
+ usage. We keep an asm block for use on prior versions of gcc though.
+
+ For reference, __builtin_ffs existed in gcc prior to __builtin_clz, but
+ it's not used (for count_leading_zeros) because it generally gives extra
+ code to ensure the result is 0 when the input is 0, which we don't need
+ or want. */
+
+#ifdef _LONG_LONG_LIMB
+#define count_leading_zeros_gcc_clz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_clzll (x); \
+ } while (0)
+#else
+#define count_leading_zeros_gcc_clz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_clzl (x); \
+ } while (0)
+#endif
+
+#ifdef _LONG_LONG_LIMB
+#define count_trailing_zeros_gcc_ctz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_ctzll (x); \
+ } while (0)
+#else
+#define count_trailing_zeros_gcc_ctz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_ctzl (x); \
+ } while (0)
+#endif
+
+
+/* FIXME: The macros using external routines like __MPN(count_leading_zeros)
+ don't need to be under !NO_ASM */
+#if ! defined (NO_ASM)
+
+#if defined (__alpha) && W_TYPE_SIZE == 64
+/* Most alpha-based machines, except Cray systems. */
+#if defined (__GNUC__)
+#if __GMP_GNUC_PREREQ (3,3)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ (ph) = __builtin_alpha_umulh (__m0, __m1); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#else
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("umulh %r1,%2,%0" \
+ : "=r" (ph) \
+ : "%rJ" (m0), "rI" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#endif
+#define UMUL_TIME 18
+#else /* ! __GNUC__ */
+#include <machine/builtins.h>
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ (ph) = __UMULH (m0, m1); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#endif
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __di; \
+ __di = __MPN(invert_limb) (d); \
+ udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \
+ } while (0)
+#define UDIV_PREINV_ALWAYS 1
+#define UDIV_NEEDS_NORMALIZATION 1
+#define UDIV_TIME 220
+#endif /* LONGLONG_STANDALONE */
+
+/* clz_tab is required in all configurations, since mpn/alpha/cntlz.asm
+ always goes into libgmp.so, even when not actually used. */
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+
+#if defined (__GNUC__) && HAVE_HOST_CPU_alpha_CIX
+#define count_leading_zeros(COUNT,X) \
+ __asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X))
+#define count_trailing_zeros(COUNT,X) \
+ __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X))
+#endif /* clz/ctz using cix */
+
+#if ! defined (count_leading_zeros) \
+ && defined (__GNUC__) && ! defined (LONGLONG_STANDALONE)
+/* ALPHA_CMPBGE_0 gives "cmpbge $31,src,dst", ie. test src bytes == 0.
+ "$31" is written explicitly in the asm, since an "r" constraint won't
+ select reg 31. There seems no need to worry about "r31" syntax for cray,
+ since gcc itself (pre-release 3.4) emits just $31 in various places. */
+#define ALPHA_CMPBGE_0(dst, src) \
+ do { asm ("cmpbge $31, %1, %0" : "=r" (dst) : "r" (src)); } while (0)
+/* Zero bytes are turned into bits with cmpbge, a __clz_tab lookup counts
+ them, locating the highest non-zero byte. A second __clz_tab lookup
+ counts the leading zero bits in that byte, giving the result. */
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype __clz__b, __clz__c, __clz__x = (x); \
+ ALPHA_CMPBGE_0 (__clz__b, __clz__x); /* zero bytes */ \
+ __clz__b = __clz_tab [(__clz__b >> 1) ^ 0x7F]; /* 8 to 1 byte */ \
+ __clz__b = __clz__b * 8 - 7; /* 57 to 1 shift */ \
+ __clz__x >>= __clz__b; \
+ __clz__c = __clz_tab [__clz__x]; /* 8 to 1 bit */ \
+ __clz__b = 65 - __clz__b; \
+ (count) = __clz__b - __clz__c; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#endif /* clz using cmpbge */
+
+#if ! defined (count_leading_zeros) && ! defined (LONGLONG_STANDALONE)
+#if HAVE_ATTRIBUTE_CONST
+long __MPN(count_leading_zeros) (UDItype) __attribute__ ((const));
+#else
+long __MPN(count_leading_zeros) (UDItype);
+#endif
+#define count_leading_zeros(count, x) \
+ ((count) = __MPN(count_leading_zeros) (x))
+#endif /* clz using mpn */
+#endif /* __alpha */
+
+#if defined (__AVR) && W_TYPE_SIZE == 8
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ unsigned short __p = (unsigned short) (m0) * (m1); \
+ (ph) = __p >> 8; \
+ (pl) = __p; \
+ } while (0)
+#endif /* AVR */
+
+#if defined (_CRAY) && W_TYPE_SIZE == 64
+#include <intrinsics.h>
+#define UDIV_PREINV_ALWAYS 1
+#define UDIV_NEEDS_NORMALIZATION 1
+#define UDIV_TIME 220
+long __MPN(count_leading_zeros) (UDItype);
+#define count_leading_zeros(count, x) \
+ ((count) = _leadz ((UWtype) (x)))
+#if defined (_CRAYIEEE) /* I.e., Cray T90/ieee, T3D, and T3E */
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ (ph) = _int_mult_upper (m0, m1); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __di; \
+ __di = __MPN(invert_limb) (d); \
+ udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \
+ } while (0)
+#endif /* LONGLONG_STANDALONE */
+#endif /* _CRAYIEEE */
+#endif /* _CRAY */
+
+#if defined (__ia64) && W_TYPE_SIZE == 64
+/* This form encourages gcc (pre-release 3.4 at least) to emit predicated
+ "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency. The generic
+ code using "al<bl" arithmetically comes out making an actual 0 or 1 in a
+ register, which takes an extra cycle. */
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ if ((al) < (bl)) \
+ (sh) = (ah) - (bh) - 1; \
+ else \
+ (sh) = (ah) - (bh); \
+ (sl) = __x; \
+ } while (0)
+#if defined (__GNUC__) && ! defined (__INTEL_COMPILER)
+/* Do both product parts in assembly, since that gives better code with
+ all gcc versions. Some callers will just use the upper part, and in
+ that situation we waste an instruction, but not any cycles. */
+#define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0" \
+ : "=&f" (ph), "=f" (pl) \
+ : "f" (m0), "f" (m1))
+#define UMUL_TIME 14
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype _x = (x), _y, _a, _c; \
+ __asm__ ("mux1 %0 = %1, @rev" : "=r" (_y) : "r" (_x)); \
+ __asm__ ("czx1.l %0 = %1" : "=r" (_a) : "r" (-_y | _y)); \
+ _c = (_a - 1) << 3; \
+ _x >>= _c; \
+ if (_x >= 1 << 4) \
+ _x >>= 4, _c += 4; \
+ if (_x >= 1 << 2) \
+ _x >>= 2, _c += 2; \
+ _c += _x >> 1; \
+ (count) = W_TYPE_SIZE - 1 - _c; \
+ } while (0)
+/* similar to what gcc does for __builtin_ffs, but 0 based rather than 1
+ based, and we don't need a special case for x==0 here */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ __asm__ ("popcnt %0 = %1" \
+ : "=r" (count) \
+ : "r" ((__ctz_x-1) & ~__ctz_x)); \
+ } while (0)
+#endif
+#if defined (__INTEL_COMPILER)
+#include <ia64intrin.h>
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UWtype _m0 = (m0), _m1 = (m1); \
+ ph = _m64_xmahu (_m0, _m1, 0); \
+ pl = _m0 * _m1; \
+ } while (0)
+#endif
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __di; \
+ __di = __MPN(invert_limb) (d); \
+ udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \
+ } while (0)
+#define UDIV_PREINV_ALWAYS 1
+#define UDIV_NEEDS_NORMALIZATION 1
+#endif
+#define UDIV_TIME 220
+#endif
+
+
+#if defined (__GNUC__)
+
+/* We sometimes need to clobber "cc" with gcc2, but that would not be
+ understood by gcc1. Use cpp to avoid major code duplication. */
+#if __GNUC__ < 2
+#define __CLOBBER_CC
+#define __AND_CLOBBER_CC
+#else /* __GNUC__ >= 2 */
+#define __CLOBBER_CC : "cc"
+#define __AND_CLOBBER_CC , "cc"
+#endif /* __GNUC__ < 2 */
+
+#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %1,%4,%5\n\taddc %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %1,%4,%5\n\tsubc %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "r" (al), "rI" (bl))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("multiplu %0,%1,%2" \
+ : "=r" (xl) \
+ : "r" (__m0), "r" (__m1)); \
+ __asm__ ("multmu %0,%1,%2" \
+ : "=r" (xh) \
+ : "r" (__m0), "r" (__m1)); \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("dividu %0,%3,%4" \
+ : "=r" (q), "=q" (r) \
+ : "1" (n1), "r" (n0), "r" (d))
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz %0,%1" \
+ : "=r" (count) \
+ : "r" (x))
+#define COUNT_LEADING_ZEROS_0 32
+#endif /* __a29k__ */
+
+#if defined (__arc__)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add.f\t%1, %4, %5\n\tadc\t%0, %2, %3" \
+ : "=r" (sh), \
+ "=&r" (sl) \
+ : "r" ((USItype) (ah)), \
+ "rIJ" ((USItype) (bh)), \
+ "%r" ((USItype) (al)), \
+ "rIJ" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub.f\t%1, %4, %5\n\tsbc\t%0, %2, %3" \
+ : "=r" (sh), \
+ "=&r" (sl) \
+ : "r" ((USItype) (ah)), \
+ "rIJ" ((USItype) (bh)), \
+ "r" ((USItype) (al)), \
+ "rIJ" ((USItype) (bl)))
+#endif
+
+#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (al)) \
+ { \
+ if (__builtin_constant_p (ah)) \
+ __asm__ ("rsbs\t%1, %5, %4\n\trsc\t%0, %3, %2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rI" (ah), "r" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \
+ else \
+ __asm__ ("rsbs\t%1, %5, %4\n\tsbc\t%0, %2, %3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \
+ } \
+ else if (__builtin_constant_p (ah)) \
+ { \
+ if (__builtin_constant_p (bl)) \
+ __asm__ ("subs\t%1, %4, %5\n\trsc\t%0, %3, %2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rI" (ah), "r" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \
+ else \
+ __asm__ ("rsbs\t%1, %5, %4\n\trsc\t%0, %3, %2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rI" (ah), "r" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \
+ } \
+ else if (__builtin_constant_p (bl)) \
+ { \
+ if (__builtin_constant_p (bh)) \
+ __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \
+ else \
+ __asm__ ("subs\t%1, %4, %5\n\trsc\t%0, %3, %2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rI" (ah), "r" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \
+ } \
+ else /* only bh might be a constant */ \
+ __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC);\
+ } while (0)
+#if 1 || defined (__arm_m__) /* `M' series has widening multiply support */
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("umull %0,%1,%2,%3" : "=&r" (xl), "=&r" (xh) : "r" (a), "r" (b))
+#define UMUL_TIME 5
+#define smul_ppmm(xh, xl, a, b) \
+ __asm__ ("smull %0,%1,%2,%3" : "=&r" (xl), "=&r" (xh) : "r" (a), "r" (b))
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __di; \
+ __di = __MPN(invert_limb) (d); \
+ udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \
+ } while (0)
+#define UDIV_PREINV_ALWAYS 1
+#define UDIV_NEEDS_NORMALIZATION 1
+#define UDIV_TIME 70
+#endif /* LONGLONG_STANDALONE */
+#else
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+" mov %|r0, %2, lsr #16\n" \
+" mov %|r2, %3, lsr #16\n" \
+" bic %|r1, %2, %|r0, lsl #16\n" \
+" bic %|r2, %3, %|r2, lsl #16\n" \
+" mul %1, %|r1, %|r2\n" \
+" mul %|r2, %|r0, %|r2\n" \
+" mul %|r1, %0, %|r1\n" \
+" mul %0, %|r0, %0\n" \
+" adds %|r1, %|r2, %|r1\n" \
+" addcs %0, %0, #65536\n" \
+" adds %1, %1, %|r1, lsl #16\n" \
+" adc %0, %0, %|r1, lsr #16" \
+ : "=&r" (xh), "=r" (xl) \
+ : "r" (a), "r" (b) \
+ : "r0", "r1", "r2")
+#define UMUL_TIME 20
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __r; \
+ (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
+#define UDIV_TIME 200
+#endif /* LONGLONG_STANDALONE */
+#endif
+/* This is a bizarre test, but GCC doesn't define any useful common symbol. */
+#if defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__) || \
+ defined (__ARM_ARCH_5E__) || defined (__ARM_ARCH_5TE__)|| \
+ defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__) || \
+ defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6Z__) || \
+ defined (__ARM_ARCH_6ZK__)|| defined (__ARM_ARCH_6T2__)|| \
+ defined (__ARM_ARCH_6M__) || defined (__ARM_ARCH_7__) || \
+ defined (__ARM_ARCH_7A__) || defined (__ARM_ARCH_7R__) || \
+ defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz\t%0, %1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 32
+#endif
+#endif /* __arm__ */
+
+#if defined (__aarch64__) && W_TYPE_SIZE == 64
+/* FIXME: Extend the immediate range for the low word by using both
+ ADDS and SUBS, since they set carry in the same way. */
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rZ" (ah), "rZ" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
+ : "=r,r" (sh), "=&r,&r" (sl) \
+ : "rZ,rZ" (ah), "rZ,rZ" (bh), "r,Z" (al), "rI,r" (bl) __CLOBBER_CC)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("umulh\t%0, %1, %2" : "=r" (ph) : "r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz\t%0, %1" : "=r" (count) : "r" (x))
+#define count_trailing_zeros(count, x) \
+ __asm__ ("rbit\t%0, %1\n\tclz\t%0, %0" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 64
+#endif /* __aarch64__ */
+
+#if defined (__clipper__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__x.__ll) \
+ : "%0" ((USItype)(u)), "r" ((USItype)(v))); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#define smul_ppmm(w1, w0, u, v) \
+ ({union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __x; \
+ __asm__ ("mulwx %2,%0" \
+ : "=r" (__x.__ll) \
+ : "%0" ((SItype)(u)), "r" ((SItype)(v))); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__w) : "%0" ((USItype)(u)), "r" ((USItype)(v))); \
+ __w; })
+#endif /* __clipper__ */
+
+/* Fujitsu vector computers. */
+#if defined (__uxp__) && W_TYPE_SIZE == 32
+#define umul_ppmm(ph, pl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mult.lu %1,%2,%0" : "=r" (__x.__ll) : "%r" (u), "rK" (v));\
+ (ph) = __x.__i.__h; \
+ (pl) = __x.__i.__l; \
+ } while (0)
+#define smul_ppmm(ph, pl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mult.l %1,%2,%0" : "=r" (__x.__ll) : "%r" (u), "rK" (v)); \
+ (ph) = __x.__i.__h; \
+ (pl) = __x.__i.__l; \
+ } while (0)
+#endif
+
+#if defined (__gmicro__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add.w %5,%1\n\taddx %3,%0" \
+ : "=g" (sh), "=&g" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub.w %5,%1\n\tsubx %3,%0" \
+ : "=g" (sh), "=&g" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("mulx %3,%0,%1" \
+ : "=g" (ph), "=r" (pl) \
+ : "%0" ((USItype)(m0)), "g" ((USItype)(m1)))
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("divx %4,%0,%1" \
+ : "=g" (q), "=r" (r) \
+ : "1" ((USItype)(nh)), "0" ((USItype)(nl)), "g" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bsch/1 %1,%0" \
+ : "=g" (count) : "g" ((USItype)(x)), "0" ((USItype)0))
+#endif
+
+#if defined (__hppa) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%I5 %5,%r4,%1\n\taddc %r2,%r3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rM" (ah), "rM" (bh), "%rM" (al), "rI" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%I4 %4,%r5,%1\n\tsubb %r2,%r3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rM" (ah), "rM" (bh), "rI" (al), "rM" (bl))
+#if defined (_PA_RISC1_1)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("xmpyu %1,%2,%0" : "=*f" (__x.__ll) : "*f" (u), "*f" (v)); \
+ (wh) = __x.__i.__h; \
+ (wl) = __x.__i.__l; \
+ } while (0)
+#define UMUL_TIME 8
+#define UDIV_TIME 60
+#else
+#define UMUL_TIME 40
+#define UDIV_TIME 80
+#endif
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __tmp; \
+ __asm__ ( \
+ "ldi 1,%0\n" \
+" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \
+" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \
+" ldo 16(%0),%0 ; Yes. Perform add.\n" \
+" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \
+" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \
+" ldo 8(%0),%0 ; Yes. Perform add.\n" \
+" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \
+" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \
+" ldo 4(%0),%0 ; Yes. Perform add.\n" \
+" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \
+" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \
+" ldo 2(%0),%0 ; Yes. Perform add.\n" \
+" extru %1,30,1,%1 ; Extract bit 1.\n" \
+" sub %0,%1,%0 ; Subtract it.\n" \
+ : "=r" (count), "=r" (__tmp) : "1" (x)); \
+ } while (0)
+#endif /* hppa */
+
+/* These macros are for ABI=2.0w. In ABI=2.0n they can't be used, since GCC
+ (3.2) puts longlong into two adjacent 32-bit registers. Presumably this
+ is just a case of no direct support for 2.0n but treating it like 1.0. */
+#if defined (__hppa) && W_TYPE_SIZE == 64 && ! defined (_LONG_LONG_LIMB)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%I5 %5,%r4,%1\n\tadd,dc %r2,%r3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rM" (ah), "rM" (bh), "%rM" (al), "rI" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%I4 %4,%r5,%1\n\tsub,db %r2,%r3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rM" (ah), "rM" (bh), "rI" (al), "rM" (bl))
+#endif /* hppa */
+
+#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32
+#if defined (__zarch__) || defined (HAVE_HOST_CPU_s390_zarch)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+/* if (__builtin_constant_p (bl)) \
+ __asm__ ("alfi\t%1,%o5\n\talcr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" (ah), "r" (bh), "%1" (al), "n" (bl) __CLOBBER_CC);\
+ else \
+*/ __asm__ ("alr\t%1,%5\n\talcr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" (ah), "r" (bh), "%1" (al), "r" (bl)__CLOBBER_CC); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+/* if (__builtin_constant_p (bl)) \
+ __asm__ ("slfi\t%1,%o5\n\tslbr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" (ah), "r" (bh), "1" (al), "n" (bl) __CLOBBER_CC); \
+ else \
+*/ __asm__ ("slr\t%1,%5\n\tslbr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" (ah), "r" (bh), "1" (al), "r" (bl) __CLOBBER_CC); \
+ } while (0)
+#if __GMP_GNUC_PREREQ (4,5)
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __x.__ll = (UDItype) (m0) * (UDItype) (m1); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+#else
+#if 0
+/* FIXME: this fails if gcc knows about the 64-bit registers. Use only
+ with a new enough processor pretending we have 32-bit registers. */
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mlr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "%0" (m0), "r" (m1)); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+#else
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ /* When we have 64-bit regs and gcc is aware of that, we cannot simply use
+ DImode for the product, since that would be allocated to a single 64-bit
+ register, whereas mlr uses the low 32-bits of an even-odd register pair.
+ */ \
+ register USItype __r0 __asm__ ("0"); \
+ register USItype __r1 __asm__ ("1") = (m0); \
+ __asm__ ("mlr\t%0,%3" \
+ : "=r" (__r0), "=r" (__r1) \
+ : "r" (__r1), "r" (m1)); \
+ (xh) = __r0; (xl) = __r1; \
+ } while (0)
+#endif /* if 0 */
+#endif
+#if 0
+/* FIXME: this fails if gcc knows about the 64-bit registers. Use only
+ with a new enough processor pretending we have 32-bit registers. */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __x.__i.__h = n1; __x.__i.__l = n0; \
+ __asm__ ("dlr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "0" (__x.__ll), "r" (d)); \
+ (q) = __x.__i.__l; (r) = __x.__i.__h; \
+ } while (0)
+#else
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ register USItype __r0 __asm__ ("0") = (n1); \
+ register USItype __r1 __asm__ ("1") = (n0); \
+ __asm__ ("dlr\t%0,%4" \
+ : "=r" (__r0), "=r" (__r1) \
+ : "r" (__r0), "r" (__r1), "r" (d)); \
+ (q) = __r1; (r) = __r0; \
+ } while (0)
+#endif /* if 0 */
+#else /* if __zarch__ */
+/* FIXME: this fails if gcc knows about the 64-bit registers. */
+#define smul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "%0" (m0), "r" (m1)); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+/* FIXME: this fails if gcc knows about the 64-bit registers. */
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __x.__i.__h = n1; __x.__i.__l = n0; \
+ __asm__ ("dr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "0" (__x.__ll), "r" (d)); \
+ (q) = __x.__i.__l; (r) = __x.__i.__h; \
+ } while (0)
+#endif /* if __zarch__ */
+#endif
+
+#if defined (__s390x__) && W_TYPE_SIZE == 64
+/* We need to cast operands with register constraints, otherwise their types
+ will be assumed to be SImode by gcc. For these machines, such operations
+ will insert a value into the low 32 bits, and leave the high 32 bits with
+ garbage. */
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ __asm__ ("algr\t%1,%5\n\talcgr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "%1" ((UDItype)(al)), "r" ((UDItype)(bl)) __CLOBBER_CC); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ __asm__ ("slgr\t%1,%5\n\tslbgr\t%0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), "r" ((UDItype)(bl)) __CLOBBER_CC); \
+ } while (0)
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {unsigned int __attribute__ ((mode(TI))) __ll; \
+ struct {UDItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mlgr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "%0" ((UDItype)(m0)), "r" ((UDItype)(m1))); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {unsigned int __attribute__ ((mode(TI))) __ll; \
+ struct {UDItype __h, __l;} __i; \
+ } __x; \
+ __x.__i.__h = n1; __x.__i.__l = n0; \
+ __asm__ ("dlgr\t%0,%2" \
+ : "=r" (__x.__ll) \
+ : "0" (__x.__ll), "r" ((UDItype)(d))); \
+ (q) = __x.__i.__l; (r) = __x.__i.__h; \
+ } while (0)
+#if 0 /* FIXME: Enable for z10 (?) */
+#define count_leading_zeros(cnt, x) \
+ do { \
+ union {unsigned int __attribute__ ((mode(TI))) __ll; \
+ struct {UDItype __h, __l;} __i; \
+ } __clr_cnt; \
+ __asm__ ("flogr\t%0,%1" \
+ : "=r" (__clr_cnt.__ll) \
+ : "r" (x) __CLOBBER_CC); \
+ (cnt) = __clr_cnt.__i.__h; \
+ } while (0)
+#endif
+#endif
+
+#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl %5,%k1\n\tadcl %3,%k0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl %5,%k1\n\tsbbl %3,%k0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mull %3" \
+ : "=a" (w0), "=d" (w1) \
+ : "%0" ((USItype)(u)), "rm" ((USItype)(v)))
+#define udiv_qrnnd(q, r, n1, n0, dx) /* d renamed to dx avoiding "=d" */\
+ __asm__ ("divl %4" /* stringification in K&R C */ \
+ : "=a" (q), "=d" (r) \
+ : "0" ((USItype)(n0)), "1" ((USItype)(n1)), "rm" ((USItype)(dx)))
+
+#if HAVE_HOST_CPU_i586 || HAVE_HOST_CPU_pentium || HAVE_HOST_CPU_pentiummmx
+/* Pentium bsrl takes between 10 and 72 cycles depending where the most
+ significant 1 bit is, hence the use of the following alternatives. bsfl
+ is slow too, between 18 and 42 depending where the least significant 1
+ bit is, so let the generic count_trailing_zeros below make use of the
+ count_leading_zeros here too. */
+
+#if HAVE_HOST_CPU_pentiummmx && ! defined (LONGLONG_STANDALONE)
+/* The following should be a fixed 14 or 15 cycles, but possibly plus an L1
+ cache miss reading from __clz_tab. For P55 it's favoured over the float
+ below so as to avoid mixing MMX and x87, since the penalty for switching
+ between the two is about 100 cycles.
+
+ The asm block sets __shift to -3 if the high 24 bits are clear, -2 for
+ 16, -1 for 8, or 0 otherwise. This could be written equivalently as
+ follows, but as of gcc 2.95.2 it results in conditional jumps.
+
+ __shift = -(__n < 0x1000000);
+ __shift -= (__n < 0x10000);
+ __shift -= (__n < 0x100);
+
+ The middle two sbbl and cmpl's pair, and with luck something gcc
+ generates might pair with the first cmpl and the last sbbl. The "32+1"
+ constant could be folded into __clz_tab[], but it doesn't seem worth
+ making a different table just for that. */
+
+#define count_leading_zeros(c,n) \
+ do { \
+ USItype __n = (n); \
+ USItype __shift; \
+ __asm__ ("cmpl $0x1000000, %1\n" \
+ "sbbl %0, %0\n" \
+ "cmpl $0x10000, %1\n" \
+ "sbbl $0, %0\n" \
+ "cmpl $0x100, %1\n" \
+ "sbbl $0, %0\n" \
+ : "=&r" (__shift) : "r" (__n)); \
+ __shift = __shift*8 + 24 + 1; \
+ (c) = 32 + 1 - __shift - __clz_tab[__n >> __shift]; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#define COUNT_LEADING_ZEROS_0 31 /* n==0 indistinguishable from n==1 */
+
+#else /* ! pentiummmx || LONGLONG_STANDALONE */
+/* The following should be a fixed 14 cycles or so. Some scheduling
+ opportunities should be available between the float load/store too. This
+ sort of code is used in gcc 3 for __builtin_ffs (with "n&-n") and is
+ apparently suggested by the Intel optimizing manual (don't know exactly
+ where). gcc 2.95 or up will be best for this, so the "double" is
+ correctly aligned on the stack. */
+#define count_leading_zeros(c,n) \
+ do { \
+ union { \
+ double d; \
+ unsigned a[2]; \
+ } __u; \
+ ASSERT ((n) != 0); \
+ __u.d = (UWtype) (n); \
+ (c) = 0x3FF + 31 - (__u.a[1] >> 20); \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 (0x3FF + 31)
+#endif /* pentiummx */
+
+#else /* ! pentium */
+
+#if __GMP_GNUC_PREREQ (3,4) /* using bsrl */
+#define count_leading_zeros(count,x) count_leading_zeros_gcc_clz(count,x)
+#endif /* gcc clz */
+
+/* On P6, gcc prior to 3.0 generates a partial register stall for
+ __cbtmp^31, due to using "xorb $31" instead of "xorl $31", the former
+ being 1 code byte smaller. "31-__cbtmp" is a workaround, probably at the
+ cost of one extra instruction. Do this for "i386" too, since that means
+ generic x86. */
+#if ! defined (count_leading_zeros) && __GNUC__ < 3 \
+ && (HAVE_HOST_CPU_i386 \
+ || HAVE_HOST_CPU_i686 \
+ || HAVE_HOST_CPU_pentiumpro \
+ || HAVE_HOST_CPU_pentium2 \
+ || HAVE_HOST_CPU_pentium3)
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsrl %1,%0" : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ (count) = 31 - __cbtmp; \
+ } while (0)
+#endif /* gcc<3 asm bsrl */
+
+#ifndef count_leading_zeros
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsrl %1,%0" : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#endif /* asm bsrl */
+
+#if __GMP_GNUC_PREREQ (3,4) /* using bsfl */
+#define count_trailing_zeros(count,x) count_trailing_zeros_gcc_ctz(count,x)
+#endif /* gcc ctz */
+
+#ifndef count_trailing_zeros
+#define count_trailing_zeros(count, x) \
+ do { \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsfl %1,%k0" : "=r" (count) : "rm" ((USItype)(x))); \
+ } while (0)
+#endif /* asm bsfl */
+
+#endif /* ! pentium */
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 10
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME 40
+#endif
+#endif /* 80x86 */
+
+#if defined (__amd64__) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addq %5,%q1\n\tadcq %3,%q0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((UDItype)(ah)), "rme" ((UDItype)(bh)), \
+ "%1" ((UDItype)(al)), "rme" ((UDItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subq %5,%q1\n\tsbbq %3,%q0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((UDItype)(ah)), "rme" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), "rme" ((UDItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulq %3" \
+ : "=a" (w0), "=d" (w1) \
+ : "%0" ((UDItype)(u)), "rm" ((UDItype)(v)))
+#define udiv_qrnnd(q, r, n1, n0, dx) /* d renamed to dx avoiding "=d" */\
+ __asm__ ("divq %4" /* stringification in K&R C */ \
+ : "=a" (q), "=d" (r) \
+ : "0" ((UDItype)(n0)), "1" ((UDItype)(n1)), "rm" ((UDItype)(dx)))
+/* bsrq destination must be a 64-bit register, hence UDItype for __cbtmp. */
+#define count_leading_zeros(count, x) \
+ do { \
+ UDItype __cbtmp; \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsrq %1,%0" : "=r" (__cbtmp) : "rm" ((UDItype)(x))); \
+ (count) = __cbtmp ^ 63; \
+ } while (0)
+/* bsfq destination must be a 64-bit register, "%q0" forces this in case
+ count is only an int. */
+#define count_trailing_zeros(count, x) \
+ do { \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsfq %1,%q0" : "=r" (count) : "rm" ((UDItype)(x))); \
+ } while (0)
+#endif /* __amd64__ */
+
+#if defined (__i860__) && W_TYPE_SIZE == 32
+#define rshift_rhlc(r,h,l,c) \
+ __asm__ ("shr %3,r0,r0\;shrd %1,%2,%0" \
+ "=r" (r) : "r" (h), "r" (l), "rn" (c))
+#endif /* i860 */
+
+#if defined (__i960__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 1,0\;addc %5,%4,%1\;addc %3,%2,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "dI" (ah), "dI" (bh), "%dI" (al), "dI" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 0,0\;subc %5,%4,%1\;subc %3,%2,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "dI" (ah), "dI" (bh), "dI" (al), "dI" (bl))
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__x.__ll) : "%dI" (u), "dI" (v)); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("emul %2,%1,%0" : "=d" (__w) : "%dI" (u), "dI" (v)); \
+ __w; })
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (nh); __nn.__i.__l = (nl); \
+ __asm__ ("ediv %d,%n,%0" \
+ : "=d" (__rq.__ll) : "dI" (__nn.__ll), "dI" (d)); \
+ (r) = __rq.__i.__l; (q) = __rq.__i.__h; \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("scanbit %1,%0" : "=r" (__cbtmp) : "r" (x)); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
+#if defined (__i960mx) /* what is the proper symbol to test??? */
+#define rshift_rhlc(r,h,l,c) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (h); __nn.__i.__l = (l); \
+ __asm__ ("shre %2,%1,%0" : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
+ }
+#endif /* i960mx */
+#endif /* i960 */
+
+#if (defined (__mc68000__) || defined (__mc68020__) || defined(mc68020) \
+ || defined (__m68k__) || defined (__mc5200__) || defined (__mc5206e__) \
+ || defined (__mc5307__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \
+ : "=d" (sh), "=&d" (sl) \
+ : "0" ((USItype)(ah)), "d" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \
+ : "=d" (sh), "=&d" (sl) \
+ : "0" ((USItype)(ah)), "d" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */
+#if defined (__mc68020__) || defined(mc68020) \
+ || defined (__mc68030__) || defined (mc68030) \
+ || defined (__mc68040__) || defined (mc68040) \
+ || defined (__mcpu32__) || defined (mcpu32) \
+ || defined (__NeXT__)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulu%.l %3,%1:%0" \
+ : "=d" (w0), "=d" (w1) \
+ : "%0" ((USItype)(u)), "dmi" ((USItype)(v)))
+#define UMUL_TIME 45
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divu%.l %4,%1:%0" \
+ : "=d" (q), "=d" (r) \
+ : "0" ((USItype)(n0)), "1" ((USItype)(n1)), "dmi" ((USItype)(d)))
+#define UDIV_TIME 90
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divs%.l %4,%1:%0" \
+ : "=d" (q), "=d" (r) \
+ : "0" ((USItype)(n0)), "1" ((USItype)(n1)), "dmi" ((USItype)(d)))
+#else /* for other 68k family members use 16x16->32 multiplication */
+#define umul_ppmm(xh, xl, a, b) \
+ do { USItype __umul_tmp1, __umul_tmp2; \
+ __asm__ ("| Inlined umul_ppmm\n" \
+" move%.l %5,%3\n" \
+" move%.l %2,%0\n" \
+" move%.w %3,%1\n" \
+" swap %3\n" \
+" swap %0\n" \
+" mulu%.w %2,%1\n" \
+" mulu%.w %3,%0\n" \
+" mulu%.w %2,%3\n" \
+" swap %2\n" \
+" mulu%.w %5,%2\n" \
+" add%.l %3,%2\n" \
+" jcc 1f\n" \
+" add%.l %#0x10000,%0\n" \
+"1: move%.l %2,%3\n" \
+" clr%.w %2\n" \
+" swap %2\n" \
+" swap %3\n" \
+" clr%.w %3\n" \
+" add%.l %3,%1\n" \
+" addx%.l %2,%0\n" \
+" | End inlined umul_ppmm" \
+ : "=&d" (xh), "=&d" (xl), \
+ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
+ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
+ } while (0)
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+#endif /* not mc68020 */
+/* The '020, '030, '040 and '060 have bitfield insns.
+ GCC 3.4 defines __mc68020__ when in CPU32 mode, check for __mcpu32__ to
+ exclude bfffo on that chip (bitfield insns not available). */
+#if (defined (__mc68020__) || defined (mc68020) \
+ || defined (__mc68030__) || defined (mc68030) \
+ || defined (__mc68040__) || defined (mc68040) \
+ || defined (__mc68060__) || defined (mc68060) \
+ || defined (__NeXT__)) \
+ && ! defined (__mcpu32__)
+#define count_leading_zeros(count, x) \
+ __asm__ ("bfffo %1{%b2:%b2},%0" \
+ : "=d" (count) \
+ : "od" ((USItype) (x)), "n" (0))
+#define COUNT_LEADING_ZEROS_0 32
+#endif
+#endif /* mc68000 */
+
+#if defined (__m88000__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rJ" (bh), "%rJ" (al), "rJ" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rJ" (bh), "rJ" (al), "rJ" (bl))
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("ff1 %0,%1" : "=r" (__cbtmp) : "r" (x)); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 63 /* sic */
+#if defined (__m88110__)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \
+ (wh) = __x.__i.__h; \
+ (wl) = __x.__i.__l; \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x, __q; \
+ __x.__i.__h = (n1); __x.__i.__l = (n0); \
+ __asm__ ("divu.d %0,%1,%2" \
+ : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \
+ (r) = (n0) - __q.__l * (d); (q) = __q.__l; })
+#define UMUL_TIME 5
+#define UDIV_TIME 25
+#else
+#define UMUL_TIME 17
+#define UDIV_TIME 150
+#endif /* __m88110__ */
+#endif /* __m88000__ */
+
+#if defined (__mips) && W_TYPE_SIZE == 32
+#if __GMP_GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UDItype __ll = (UDItype)(u) * (v); \
+ w1 = __ll >> 32; \
+ w0 = __ll; \
+ } while (0)
+#endif
+#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v))
+#endif
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3\n\tmflo %0\n\tmfhi %1" \
+ : "=d" (w0), "=d" (w1) : "d" (u), "d" (v))
+#endif
+#define UMUL_TIME 10
+#define UDIV_TIME 100
+#endif /* __mips */
+
+#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
+#if __GMP_GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
+ __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \
+ w1 = __ll >> 64; \
+ w0 = __ll; \
+ } while (0)
+#endif
+#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v))
+#endif
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3\n\tmflo %0\n\tmfhi %1" \
+ : "=d" (w0), "=d" (w1) : "d" (u), "d" (v))
+#endif
+#define UMUL_TIME 20
+#define UDIV_TIME 140
+#endif /* __mips */
+
+#if defined (__mmix__) && W_TYPE_SIZE == 64
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("MULU %0,%2,%3" : "=r" (w0), "=z" (w1) : "r" (u), "r" (v))
+#endif
+
+#if defined (__ns32000__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__x.__ll) \
+ : "%0" ((USItype)(u)), "g" ((USItype)(v))); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__w) \
+ : "%0" ((USItype)(u)), "g" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ __x.__i.__h = (n1); __x.__i.__l = (n0); \
+ __asm__ ("deid %2,%0" \
+ : "=g" (__x.__ll) \
+ : "0" (__x.__ll), "g" ((USItype)(d))); \
+ (r) = __x.__i.__l; (q) = __x.__i.__h; })
+#define count_trailing_zeros(count,x) \
+ do { \
+ __asm__ ("ffsd %2,%0" \
+ : "=r" (count) \
+ : "0" ((USItype) 0), "r" ((USItype) (x))); \
+ } while (0)
+#endif /* __ns32000__ */
+
+/* In the past we had a block of various #defines tested
+ _ARCH_PPC - AIX
+ _ARCH_PWR - AIX
+ __powerpc__ - gcc
+ __POWERPC__ - BEOS
+ __ppc__ - Darwin
+ PPC - old gcc, GNU/Linux, SysV
+ The plain PPC test was not good for vxWorks, since PPC is defined on all
+ CPUs there (eg. m68k too), as a constant one is expected to compare
+ CPU_FAMILY against.
+
+ At any rate, this was pretty unattractive and a bit fragile. The use of
+ HAVE_HOST_CPU_FAMILY is designed to cut through it all and be sure of
+ getting the desired effect.
+
+ ENHANCE-ME: We should test _IBMR2 here when we add assembly support for
+ the system vendor compilers. (Is that vendor compilers with inline asm,
+ or what?) */
+
+#if (HAVE_HOST_CPU_FAMILY_power || HAVE_HOST_CPU_FAMILY_powerpc) \
+ && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \
+ __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl)); \
+ else \
+ __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else \
+ __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("cntlzw %0,%1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 32
+#if HAVE_HOST_CPU_FAMILY_powerpc
+#if __GMP_GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UDItype __ll = (UDItype)(u) * (v); \
+ w1 = __ll >> 32; \
+ w0 = __ll; \
+ } while (0)
+#endif
+#if !defined (umul_ppmm)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#endif
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ SItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14
+#define UDIV_TIME 120
+#else
+#define UMUL_TIME 8
+#define smul_ppmm(xh, xl, m0, m1) \
+ __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1))
+#define SMUL_TIME 4
+#define sdiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d))
+#define UDIV_TIME 100
+#endif
+#endif /* 32-bit POWER architecture variants. */
+
+/* We should test _IBMR2 here when we add assembly support for the system
+ vendor compilers. */
+#if HAVE_HOST_CPU_FAMILY_powerpc && W_TYPE_SIZE == 64
+#if !defined (_LONG_LONG_LIMB)
+/* _LONG_LONG_LIMB is ABI=mode32 where adde operates on 32-bit values. So
+ use adde etc only when not _LONG_LONG_LIMB. */
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl)); \
+ else \
+ __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
+ } while (0)
+/* We use "*rI" for the constant operand here, since with just "I", gcc barfs.
+ This might seem strange, but gcc folds away the dead code late. */
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bl) && bl > -0x8000 && bl <= 0x8000) { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("addic %1,%3,%4\n\tsubfze %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "*rI" (-bl)); \
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("addic %1,%3,%4\n\tsubfme %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "*rI" (-bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("addic %1,%3,%4\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "*rI" (-bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("addic %1,%3,%4\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "*rI" (-bl)); \
+ else \
+ __asm__ ("addic %1,%4,%5\n\tsubfe %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "rI" (al), "*rI" (-bl)); \
+ } else { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl)); \
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl)); \
+ else \
+ __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
+ } \
+ } while (0)
+#endif /* ! _LONG_LONG_LIMB */
+#define count_leading_zeros(count, x) \
+ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 64
+#if 0 && __GMP_GNUC_PREREQ (4,4) /* Disable, this results in libcalls! */
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
+ __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \
+ w1 = __ll >> 64; \
+ w0 = __ll; \
+ } while (0)
+#endif
+#if !defined (umul_ppmm)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#endif
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ DItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14 /* ??? */
+#define UDIV_TIME 120 /* ??? */
+#endif /* 64-bit PowerPC. */
+
+#if defined (__pyr__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addw %5,%1\n\taddwc %3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subw %5,%1\n\tsubwb %3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("movw %1,%R0\n\tuemul %2,%0" \
+ : "=&r" (__x.__ll) \
+ : "g" ((USItype) (u)), "g" ((USItype)(v))); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#endif /* __pyr__ */
+
+#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("a %1,%5\n\tae %0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "r" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "r" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("s %1,%5\n\tse %0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "r" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "r" ((USItype)(bl)))
+#define smul_ppmm(ph, pl, m0, m1) \
+ __asm__ ( \
+ "s r2,r2\n" \
+" mts r10,%2\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" cas %0,r2,r0\n" \
+" mfs r10,%1" \
+ : "=r" (ph), "=r" (pl) \
+ : "%r" ((USItype)(m0)), "r" ((USItype)(m1)) \
+ : "r2")
+#define UMUL_TIME 20
+#define UDIV_TIME 200
+#define count_leading_zeros(count, x) \
+ do { \
+ if ((x) >= 0x10000) \
+ __asm__ ("clz %0,%1" \
+ : "=r" (count) : "r" ((USItype)(x) >> 16)); \
+ else \
+ { \
+ __asm__ ("clz %0,%1" \
+ : "=r" (count) : "r" ((USItype)(x))); \
+ (count) += 16; \
+ } \
+ } while (0)
+#endif /* RT/ROMP */
+
+#if (defined (__SH2__) || defined (__SH3__) || defined (__SH4__)) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \
+ : "=r" (w1), "=r" (w0) : "r" (u), "r" (v) : "macl", "mach")
+#define UMUL_TIME 5
+#endif
+
+#if defined (__sparc__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh),"%rJ" (al), "rI" (bl) \
+ __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "rJ" (al), "rI" (bl) \
+ __CLOBBER_CC)
+/* FIXME: When gcc -mcpu=v9 is used on solaris, gcc/config/sol2-sld-64.h
+ doesn't define anything to indicate that to us, it only sets __sparcv8. */
+#if defined (__sparc_v9__) || defined (__sparcv9)
+/* Perhaps we should use floating-point operations here? */
+#if 0
+/* Triggers a bug making mpz/tests/t-gcd.c fail.
+ Perhaps we simply need explicitly zero-extend the inputs? */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulx %2,%3,%%g1; srl %%g1,0,%1; srlx %%g1,32,%0" : \
+ "=r" (w1), "=r" (w0) : "r" (u), "r" (v) : "g1")
+#else
+/* Use v8 umul until above bug is fixed. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" : "=r" (w1), "=r" (w0) : "r" (u), "r" (v))
+#endif
+/* Use a plain v8 divide for v9. */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ USItype __q; \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" (__q) : "r" (n1), "r" (n0), "r" (d)); \
+ (r) = (n0) - __q * (d); \
+ (q) = __q; \
+ } while (0)
+#else
+#if defined (__sparc_v8__) /* gcc normal */ \
+ || defined (__sparcv8) /* gcc solaris */ \
+ || HAVE_HOST_CPU_supersparc
+/* Don't match immediate range because, 1) it is not often useful,
+ 2) the 'I' flag thinks of the range as a 13 bit signed interval,
+ while we want to match a 13 bit interval, sign extended to 32 bits,
+ but INTERPRETED AS UNSIGNED. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" : "=r" (w1), "=r" (w0) : "r" (u), "r" (v))
+#define UMUL_TIME 5
+
+#if HAVE_HOST_CPU_supersparc
+#define UDIV_TIME 60 /* SuperSPARC timing */
+#else
+/* Don't use this on SuperSPARC because its udiv only handles 53 bit
+ dividends and will trap to the kernel for the rest. */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ USItype __q; \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" (__q) : "r" (n1), "r" (n0), "r" (d)); \
+ (r) = (n0) - __q * (d); \
+ (q) = __q; \
+ } while (0)
+#define UDIV_TIME 25
+#endif /* HAVE_HOST_CPU_supersparc */
+
+#else /* ! __sparc_v8__ */
+#if defined (__sparclite__)
+/* This has hardware multiply but not divide. It also has two additional
+ instructions scan (ffs from high bit) and divscc. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" : "=r" (w1), "=r" (w0) : "r" (u), "r" (v))
+#define UMUL_TIME 5
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("! Inlined udiv_qrnnd\n" \
+" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \
+" tst %%g0\n" \
+" divscc %3,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%0\n" \
+" rd %%y,%1\n" \
+" bl,a 1f\n" \
+" add %1,%4,%1\n" \
+"1: ! End of inline udiv_qrnnd" \
+ : "=r" (q), "=r" (r) : "r" (n1), "r" (n0), "rI" (d) \
+ : "%g1" __AND_CLOBBER_CC)
+#define UDIV_TIME 37
+#define count_leading_zeros(count, x) \
+ __asm__ ("scan %1,1,%0" : "=r" (count) : "r" (x))
+/* Early sparclites return 63 for an argument of 0, but they warn that future
+ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
+ undefined. */
+#endif /* __sparclite__ */
+#endif /* __sparc_v8__ */
+#endif /* __sparc_v9__ */
+/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
+#ifndef umul_ppmm
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("! Inlined umul_ppmm\n" \
+" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n" \
+" sra %3,31,%%g2 ! Don't move this insn\n" \
+" and %2,%%g2,%%g2 ! Don't move this insn\n" \
+" andcc %%g0,0,%%g1 ! Don't move this insn\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,0,%%g1\n" \
+" add %%g1,%%g2,%0\n" \
+" rd %%y,%1" \
+ : "=r" (w1), "=r" (w0) : "%rI" (u), "r" (v) \
+ : "%g1", "%g2" __AND_CLOBBER_CC)
+#define UMUL_TIME 39 /* 39 instructions */
+#endif
+#ifndef udiv_qrnnd
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __r; \
+ (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
+#ifndef UDIV_TIME
+#define UDIV_TIME 140
+#endif
+#endif /* LONGLONG_STANDALONE */
+#endif /* udiv_qrnnd */
+#endif /* __sparc__ */
+
+#if defined (__sparc__) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ( \
+ "addcc %r4,%5,%1\n" \
+ " addccc %r6,%7,%%g0\n" \
+ " addc %r2,%3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl), \
+ "%rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ( \
+ "subcc %r4,%5,%1\n" \
+ " subccc %r6,%7,%%g0\n" \
+ " subc %r2,%3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "rJ" (al), "rI" (bl), \
+ "rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ __CLOBBER_CC)
+#if __VIS__ >= 0x300
+#undef add_ssaaaa
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ( \
+ "addcc %r4, %5, %1\n" \
+ " addxc %r2, %r3, %0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rJ" (bh), "%rJ" (al), "rI" (bl) __CLOBBER_CC)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ (pl) = __m0 * __m1; \
+ __asm__ ("umulxhi\t%2, %1, %0" \
+ : "=r" (ph) \
+ : "%r" (__m0), "r" (__m1)); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("lzd\t%1,%0" : "=r" (count) : "r" (x))
+#endif
+#endif
+
+#if (defined (__vax) || defined (__vax__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \
+ : "=g" (sh), "=&g" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \
+ : "=g" (sh), "=&g" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define smul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("emul %1,%2,$0,%0" \
+ : "=g" (__x.__ll) : "g" (__m0), "g" (__m1)); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __x; \
+ __x.__i.__h = n1; __x.__i.__l = n0; \
+ __asm__ ("ediv %3,%2,%0,%1" \
+ : "=g" (q), "=g" (r) : "g" (__x.__ll), "g" (d)); \
+ } while (0)
+#if 0
+/* FIXME: This instruction appears to be unimplemented on some systems (vax
+ 8800 maybe). */
+#define count_trailing_zeros(count,x) \
+ do { \
+ __asm__ ("ffs 0, 31, %1, %0" \
+ : "=g" (count) \
+ : "g" ((USItype) (x))); \
+ } while (0)
+#endif
+#endif /* vax */
+
+#if defined (__z8000__) && W_TYPE_SIZE == 16
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((unsigned int)(ah)), "r" ((unsigned int)(bh)), \
+ "%1" ((unsigned int)(al)), "rQR" ((unsigned int)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((unsigned int)(ah)), "r" ((unsigned int)(bh)), \
+ "1" ((unsigned int)(al)), "rQR" ((unsigned int)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {long int __ll; \
+ struct {unsigned int __h, __l;} __i; \
+ } __x; \
+ unsigned int __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mult %S0,%H3" \
+ : "=r" (__x.__i.__h), "=r" (__x.__i.__l) \
+ : "%1" (m0), "rQR" (m1)); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ (xh) += ((((signed int) __m0 >> 15) & __m1) \
+ + (((signed int) __m1 >> 15) & __m0)); \
+ } while (0)
+#endif /* __z8000__ */
+
+#endif /* __GNUC__ */
+
+#endif /* NO_ASM */
+
+
+/* FIXME: "sidi" here is highly doubtful, should sometimes be "diti". */
+#if !defined (umul_ppmm) && defined (__umulsidi3)
+#define umul_ppmm(ph, pl, m0, m1) \
+ { \
+ UDWtype __ll = __umulsidi3 (m0, m1); \
+ ph = (UWtype) (__ll >> W_TYPE_SIZE); \
+ pl = (UWtype) __ll; \
+ }
+#endif
+
+#if !defined (__umulsidi3)
+#define __umulsidi3(u, v) \
+ ({UWtype __hi, __lo; \
+ umul_ppmm (__hi, __lo, u, v); \
+ ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
+#endif
+
+
+/* Use mpn_umul_ppmm or mpn_udiv_qrnnd functions, if they exist. The "_r"
+ forms have "reversed" arguments, meaning the pointer is last, which
+ sometimes allows better parameter passing, in particular on 64-bit
+ hppa. */
+
+#define mpn_umul_ppmm __MPN(umul_ppmm)
+extern UWtype mpn_umul_ppmm (UWtype *, UWtype, UWtype);
+
+#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm \
+ && ! defined (LONGLONG_STANDALONE)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ UWtype __umul_ppmm__p0; \
+ (wh) = mpn_umul_ppmm (&__umul_ppmm__p0, (UWtype) (u), (UWtype) (v));\
+ (wl) = __umul_ppmm__p0; \
+ } while (0)
+#endif
+
+#define mpn_umul_ppmm_r __MPN(umul_ppmm_r)
+extern UWtype mpn_umul_ppmm_r (UWtype, UWtype, UWtype *);
+
+#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm_r \
+ && ! defined (LONGLONG_STANDALONE)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ UWtype __umul_p0; \
+ (wh) = mpn_umul_ppmm_r ((UWtype) (u), (UWtype) (v), &__umul_p0); \
+ (wl) = __umul_p0; \
+ } while (0)
+#endif
+
+#define mpn_udiv_qrnnd __MPN(udiv_qrnnd)
+extern UWtype mpn_udiv_qrnnd (UWtype *, UWtype, UWtype, UWtype);
+
+#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd \
+ && ! defined (LONGLONG_STANDALONE)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ UWtype __udiv_qrnnd_r; \
+ (q) = mpn_udiv_qrnnd (&__udiv_qrnnd_r, \
+ (UWtype) (n1), (UWtype) (n0), (UWtype) d); \
+ (r) = __udiv_qrnnd_r; \
+ } while (0)
+#endif
+
+#define mpn_udiv_qrnnd_r __MPN(udiv_qrnnd_r)
+extern UWtype mpn_udiv_qrnnd_r (UWtype, UWtype, UWtype, UWtype *);
+
+#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd_r \
+ && ! defined (LONGLONG_STANDALONE)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ UWtype __udiv_qrnnd_r; \
+ (q) = mpn_udiv_qrnnd_r ((UWtype) (n1), (UWtype) (n0), (UWtype) d, \
+ &__udiv_qrnnd_r); \
+ (r) = __udiv_qrnnd_r; \
+ } while (0)
+#endif
+
+
+/* If this machine has no inline assembler, use C macros. */
+
+#if !defined (add_ssaaaa)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) + (bl); \
+ (sh) = (ah) + (bh) + (__x < (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (sub_ddmmss)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - ((al) < (bl)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of
+ smul_ppmm. */
+#if !defined (umul_ppmm) && defined (smul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __w1; \
+ UWtype __xm0 = (u), __xm1 = (v); \
+ smul_ppmm (__w1, w0, __xm0, __xm1); \
+ (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \
+ + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \
+ } while (0)
+#endif
+
+/* If we still don't have umul_ppmm, define it using plain C.
+
+ For reference, when this code is used for squaring (ie. u and v identical
+ expressions), gcc recognises __x1 and __x2 are the same and generates 3
+ multiplies, not 4. The subsequent additions could be optimized a bit,
+ but the only place GMP currently uses such a square is mpn_sqr_basecase,
+ and chips obliged to use this generic C umul will have plenty of worse
+ performance problems than a couple of extra instructions on the diagonal
+ of sqr_basecase. */
+
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __x0, __x1, __x2, __x3; \
+ UHWtype __ul, __vl, __uh, __vh; \
+ UWtype __u = (u), __v = (v); \
+ \
+ __ul = __ll_lowpart (__u); \
+ __uh = __ll_highpart (__u); \
+ __vl = __ll_lowpart (__v); \
+ __vh = __ll_highpart (__v); \
+ \
+ __x0 = (UWtype) __ul * __vl; \
+ __x1 = (UWtype) __ul * __vh; \
+ __x2 = (UWtype) __uh * __vl; \
+ __x3 = (UWtype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = (__x1 << W_TYPE_SIZE/2) + __ll_lowpart (__x0); \
+ } while (0)
+#endif
+
+/* If we don't have smul_ppmm, define it using umul_ppmm (which surely will
+ exist in one form or another. */
+#if !defined (smul_ppmm)
+#define smul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __w1; \
+ UWtype __xm0 = (u), __xm1 = (v); \
+ umul_ppmm (__w1, w0, __xm0, __xm1); \
+ (w1) = __w1 - (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \
+ - (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \
+ } while (0)
+#endif
+
+/* Define this unconditionally, so it can be used for debugging. */
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
+ \
+ ASSERT ((d) != 0); \
+ ASSERT ((n1) < (d)); \
+ \
+ __d1 = __ll_highpart (d); \
+ __d0 = __ll_lowpart (d); \
+ \
+ __q1 = (n1) / __d1; \
+ __r1 = (n1) - __q1 * __d1; \
+ __m = __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
+ if (__r1 < __m) \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __q0 = __r1 / __d1; \
+ __r0 = __r1 - __q0 * __d1; \
+ __m = __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
+ if (__r0 < __m) \
+ { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
+ __udiv_w_sdiv (defined in libgcc or elsewhere). */
+#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ UWtype __r; \
+ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
+ (r) = __r; \
+ } while (0)
+__GMP_DECLSPEC UWtype __MPN(udiv_w_sdiv) (UWtype *, UWtype, UWtype, UWtype);
+#endif
+
+/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
+#if !defined (udiv_qrnnd)
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+#endif
+
+#if !defined (count_leading_zeros)
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype __xr = (x); \
+ UWtype __a; \
+ \
+ if (W_TYPE_SIZE == 32) \
+ { \
+ __a = __xr < ((UWtype) 1 << 2*__BITS4) \
+ ? (__xr < ((UWtype) 1 << __BITS4) ? 1 : __BITS4 + 1) \
+ : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 + 1 \
+ : 3*__BITS4 + 1); \
+ } \
+ else \
+ { \
+ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
+ if (((__xr >> __a) & 0xff) != 0) \
+ break; \
+ ++__a; \
+ } \
+ \
+ (count) = W_TYPE_SIZE + 1 - __a - __clz_tab[__xr >> __a]; \
+ } while (0)
+/* This version gives a well-defined value for zero. */
+#define COUNT_LEADING_ZEROS_0 (W_TYPE_SIZE - 1)
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#define COUNT_LEADING_ZEROS_SLOW
+#endif
+
+/* clz_tab needed by mpn/x86/pentium/mod_1.asm in a fat binary */
+#if HAVE_HOST_CPU_FAMILY_x86 && WANT_FAT_BINARY
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#endif
+
+#ifdef COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+extern const unsigned char __GMP_DECLSPEC __clz_tab[129];
+#endif
+
+#if !defined (count_trailing_zeros)
+#if !defined (COUNT_LEADING_ZEROS_SLOW)
+/* Define count_trailing_zeros using an asm count_leading_zeros. */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ UWtype __ctz_c; \
+ ASSERT (__ctz_x != 0); \
+ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
+ (count) = W_TYPE_SIZE - 1 - __ctz_c; \
+ } while (0)
+#else
+/* Define count_trailing_zeros in plain C, assuming small counts are common.
+ We use clz_tab without ado, since the C count_leading_zeros above will have
+ pulled it in. */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ int __ctz_c; \
+ \
+ if (LIKELY ((__ctz_x & 0xff) != 0)) \
+ (count) = __clz_tab[__ctz_x & -__ctz_x] - 2; \
+ else \
+ { \
+ for (__ctz_c = 8 - 2; __ctz_c < W_TYPE_SIZE - 2; __ctz_c += 8) \
+ { \
+ __ctz_x >>= 8; \
+ if (LIKELY ((__ctz_x & 0xff) != 0)) \
+ break; \
+ } \
+ \
+ (count) = __ctz_c + __clz_tab[__ctz_x & -__ctz_x]; \
+ } \
+ } while (0)
+#endif
+#endif
+
+#ifndef UDIV_NEEDS_NORMALIZATION
+#define UDIV_NEEDS_NORMALIZATION 0
+#endif
+
+/* Whether udiv_qrnnd is actually implemented with udiv_qrnnd_preinv, and
+ that hence the latter should always be used. */
+#ifndef UDIV_PREINV_ALWAYS
+#define UDIV_PREINV_ALWAYS 0
+#endif
+
+/* Give defaults for UMUL_TIME and UDIV_TIME. */
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
diff --git a/gmp/ltmain.sh b/gmp/ltmain.sh
new file mode 100644
index 0000000000..63ae69dc6f
--- /dev/null
+++ b/gmp/ltmain.sh
@@ -0,0 +1,9655 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --no-quiet, --no-silent
+# print informational messages (default)
+# --no-warn don't display warning messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print more informational messages than default
+# --no-verbose don't print the extra informational messages
+# --version print version information
+# -h, --help, --help-all print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE. When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.4.2
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.2
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+ s@/\./@/@g
+ t dotsl
+ s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+# value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test "$func_normal_abspath_tpath" = / ; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result" ; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+# value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=${func_dirname_result}
+ if test "x$func_relative_path_tlibdir" = x ; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test "x$func_stripname_result" != x ; then
+ func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+ fi
+
+ # Normalisation. If bindir is libdir, return empty string,
+ # else relative path ending with a slash; either way, target
+ # file name can be directly appended.
+ if test ! -z "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result/"
+ func_relative_path_result=$func_stripname_result
+ fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "$1" | $SED \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $opt_debug
+
+ $SED -n '/(C)/!b go
+ :more
+ /\./!{
+ N
+ s/\n# / /
+ b more
+ }
+ :go
+ /^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/^# *.*--help/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ echo
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ :print
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+ p
+ d
+ }
+ /^# .* home page:/b print
+ /^# General help using/b print
+ ' < "$progpath"
+ ret=$?
+ if test -z "$1"; then
+ exit $ret
+ fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $opt_debug
+
+ func_error "missing argument for $1."
+ exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+ my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+ my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+ func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+ func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+ my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+ my_sed_long_arg='1s/^--[^=]*=//'
+
+ func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+ func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+ func_quote_for_eval "${2}"
+ eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly. This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+ # this just eases exit handling
+ while test $# -gt 0; do
+ opt="$1"
+ shift
+ case $opt in
+ --debug|-x) opt_debug='set -x'
+ func_echo "enabling shell trace mode"
+ $opt_debug
+ ;;
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+ --config)
+ opt_config=:
+func_config
+ ;;
+ --dlopen|-dlopen)
+ optarg="$1"
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+ shift
+ ;;
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=:
+ ;;
+ --features)
+ opt_features=:
+func_features
+ ;;
+ --finish)
+ opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ --help)
+ opt_help=:
+ ;;
+ --help-all)
+ opt_help_all=:
+opt_help=': help-all'
+ ;;
+ --mode)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_mode="$optarg"
+case $optarg in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+esac
+ shift
+ ;;
+ --no-silent|--no-quiet)
+ opt_silent=false
+func_append preserve_args " $opt"
+ ;;
+ --no-warning|--no-warn)
+ opt_warning=false
+func_append preserve_args " $opt"
+ ;;
+ --no-verbose)
+ opt_verbose=false
+func_append preserve_args " $opt"
+ ;;
+ --silent|--quiet)
+ opt_silent=:
+func_append preserve_args " $opt"
+ opt_verbose=false
+ ;;
+ --verbose|-v)
+ opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+ ;;
+ --tag)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+ --version) func_version ;;
+
+ # Separate optargs to long options:
+ --*=*)
+ func_split_long_opt "$opt"
+ set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-n*|-v*)
+ func_split_short_opt "$opt"
+ set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+ *) set dummy "$opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # Validate options:
+
+ # save first non-option argument
+ if test "$#" -gt 0; then
+ nonopt="$opt"
+ shift
+ fi
+
+ # preserve --debug
+ test "$opt_debug" = : || func_append preserve_args " --debug"
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$opt_mode' for more information."
+ }
+
+
+ # Bail if the options were screwed
+ $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case "$lt_sysroot:$1" in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result="=$func_stripname_result"
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $opt_debug
+ func_convert_core_file_wine_to_w32_result="$1"
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $opt_debug
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=""
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $opt_debug
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $opt_debug
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $opt_debug
+ if test -z "$2" && test -n "$1" ; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " \`$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result="$1"
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $opt_debug
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " \`$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result="$3"
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $opt_debug
+ case $4 in
+ $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $opt_debug
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $opt_debug
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $opt_debug
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd="func_convert_path_${func_stripname_result}"
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $opt_debug
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_append_quoted lastarg "$arg"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test "$opt_help" = :; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | sed -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ sed '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "\`$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument \`$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test "x$prev" = x-m && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=""
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname" ; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename="$func_basename_result"
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename" ; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $opt_debug
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $opt_debug
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $opt_debug
+ if func_cygming_gnu_implib_p "$1" ; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1" ; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=""
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ if test "$lock_old_archive_extraction" = yes; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test "$lock_old_archive_extraction" = yes; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+# define _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (strcmp (argv[i], debug_opt) == 0)
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $opt_debug
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir="$arg"
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps ; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test "$prefer_static_libs" = yes ||
+ test "$prefer_static_libs,$installed" = "built,no"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$lt_sysroot$libdir"
+ absdir="$lt_sysroot$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ case "$host" in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ echo
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$opt_mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$absdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$opt_mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ func_append libobjs " $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$opt_mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test "$want_nocaseglob" = yes; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Remove ${wl} instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd1 in $cmds; do
+ IFS="$save_ifs"
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test "$try_normal_branch" = yes \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=${output_objdir}/${output_la}.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " ${wl}-bind_at_load"
+ func_append finalize_command " ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ func_append oldobjs " $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ func_resolve_sysroot "$deplib"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test "x$bindir" != x ;
+ then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=yes ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ odir="$objdir"
+ else
+ odir="$dir/$objdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$opt_mode" = uninstall && odir="$dir"
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test "$opt_mode" = clean; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case "$opt_mode" in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$opt_mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ func_append rmfiles " $odir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/gmp/memory.c b/gmp/memory.c
new file mode 100644
index 0000000000..4475f37de3
--- /dev/null
+++ b/gmp/memory.c
@@ -0,0 +1,146 @@
+/* Memory allocation routines.
+
+Copyright 1991, 1993, 1994, 2000-2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <stdlib.h> /* for malloc, realloc, free */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void * (*__gmp_allocate_func) (size_t) = __gmp_default_allocate;
+void * (*__gmp_reallocate_func) (void *, size_t, size_t) = __gmp_default_reallocate;
+void (*__gmp_free_func) (void *, size_t) = __gmp_default_free;
+
+
+/* Default allocation functions. In case of failure to allocate/reallocate
+ an error message is written to stderr and the program aborts. */
+
+void *
+__gmp_default_allocate (size_t size)
+{
+ void *ret;
+#ifdef DEBUG
+ size_t req_size = size;
+ size += 2 * GMP_LIMB_BYTES;
+#endif
+ ret = malloc (size);
+ if (ret == 0)
+ {
+ fprintf (stderr, "GNU MP: Cannot allocate memory (size=%lu)\n", (long) size);
+ abort ();
+ }
+
+#ifdef DEBUG
+ {
+ mp_ptr p = ret;
+ p++;
+ p[-1] = (0xdeadbeef << 31) + 0xdeafdeed;
+ if (req_size % GMP_LIMB_BYTES == 0)
+ p[req_size / GMP_LIMB_BYTES] = ~((0xdeadbeef << 31) + 0xdeafdeed);
+ ret = p;
+ }
+#endif
+ return ret;
+}
+
+void *
+__gmp_default_reallocate (void *oldptr, size_t old_size, size_t new_size)
+{
+ void *ret;
+
+#ifdef DEBUG
+ size_t req_size = new_size;
+
+ if (old_size != 0)
+ {
+ mp_ptr p = oldptr;
+ if (p[-1] != (0xdeadbeef << 31) + 0xdeafdeed)
+ {
+ fprintf (stderr, "gmp: (realloc) data clobbered before allocation block\n");
+ abort ();
+ }
+ if (old_size % GMP_LIMB_BYTES == 0)
+ if (p[old_size / GMP_LIMB_BYTES] != ~((0xdeadbeef << 31) + 0xdeafdeed))
+ {
+ fprintf (stderr, "gmp: (realloc) data clobbered after allocation block\n");
+ abort ();
+ }
+ oldptr = p - 1;
+ }
+
+ new_size += 2 * GMP_LIMB_BYTES;
+#endif
+
+ ret = realloc (oldptr, new_size);
+ if (ret == 0)
+ {
+ fprintf (stderr, "GNU MP: Cannot reallocate memory (old_size=%lu new_size=%lu)\n", (long) old_size, (long) new_size);
+ abort ();
+ }
+
+#ifdef DEBUG
+ {
+ mp_ptr p = ret;
+ p++;
+ p[-1] = (0xdeadbeef << 31) + 0xdeafdeed;
+ if (req_size % GMP_LIMB_BYTES == 0)
+ p[req_size / GMP_LIMB_BYTES] = ~((0xdeadbeef << 31) + 0xdeafdeed);
+ ret = p;
+ }
+#endif
+ return ret;
+}
+
+void
+__gmp_default_free (void *blk_ptr, size_t blk_size)
+{
+#ifdef DEBUG
+ {
+ mp_ptr p = blk_ptr;
+ if (blk_size != 0)
+ {
+ if (p[-1] != (0xdeadbeef << 31) + 0xdeafdeed)
+ {
+ fprintf (stderr, "gmp: (free) data clobbered before allocation block\n");
+ abort ();
+ }
+ if (blk_size % GMP_LIMB_BYTES == 0)
+ if (p[blk_size / GMP_LIMB_BYTES] != ~((0xdeadbeef << 31) + 0xdeafdeed))
+ {
+ fprintf (stderr, "gmp: (free) data clobbered after allocation block\n");
+ abort ();
+ }
+ }
+ blk_ptr = p - 1;
+ }
+#endif
+ free (blk_ptr);
+}
diff --git a/gmp/mini-gmp/README b/gmp/mini-gmp/README
new file mode 100644
index 0000000000..f291489ea3
--- /dev/null
+++ b/gmp/mini-gmp/README
@@ -0,0 +1,77 @@
+Copyright 2011-2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+This is "mini-gmp", a small implementation of a subset of GMP's mpn
+and mpz interfaces.
+
+It is intended for applications which need arithmetic on numbers
+larger than a machine word, but which don't need to handle very large
+numbers very efficiently. Those applications can include a copy of
+mini-gmp to get a GMP-compatible interface with small footprint. One
+can also arrange for optional linking with the real GMP library, using
+mini-gmp as a fallback when for some reason GMP is not available, or
+not desired as a dependency.
+
+The supported GMP subset is declared in mini-gmp.h. The implemented
+functions are fully compatible with the corresponding GMP functions,
+as specified in the GMP manual, with a few exceptions:
+
+ mpz_set_str, mpz_init_set_str, mpz_get_str, mpz_out_str and
+ mpz_sizeinbase support only |base| <= 36;
+ mpz_export and mpz_import support only NAILS = 0.
+
+ The REALLOC_FUNC and FREE_FUNC registered with
+ mp_set_memory_functions does not get the correct size of the
+ allocated block in the corresponding argument. mini-gmp always
+ passes zero for these rarely used arguments.
+
+The implementation is a single file, mini-gmp.c.
+
+The performance target for mini-gmp is to be at most 10 times slower
+than the real GMP library, for numbers of size up to a few hundred
+bits. No asymptotically fast algorithms are included in mini-gmp, so
+it will be many orders of magnitude slower than GMP for very large
+numbers.
+
+You should never "install" mini-gmp. Applications can either just
+#include mini-gmp.c (but then, beware that it defines several macros
+and functions outside of the advertised interface). Or compile
+mini-gmp.c as a separate compilation unit, and use the declarations in
+mini-gmp.h.
+
+The tests subdirectory contains a testsuite. To use it, you need GMP
+and GNU make. Just run make check in the tests directory. If the
+hard-coded compiler settings are not right, you have to either edit the
+Makefile or pass overriding values on the make command line (e.g.,
+make CC=cc check). Testing is not (yet) as thorough as for the real
+GMP.
+
+The current version was put together by Niels Möller
+<nisse@lysator.liu.se>, with a fair amount of copy-and-paste from the
+GMP sources.
diff --git a/gmp/mini-gmp/mini-gmp.c b/gmp/mini-gmp/mini-gmp.c
new file mode 100644
index 0000000000..b9186951cb
--- /dev/null
+++ b/gmp/mini-gmp/mini-gmp.c
@@ -0,0 +1,4386 @@
+/* mini-gmp, a minimalistic implementation of a GNU GMP subset.
+
+ Contributed to the GNU project by Niels Möller
+
+Copyright 1991-1997, 1999-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* NOTE: All functions in this file which are not declared in
+ mini-gmp.h are internal, and are not intended to be compatible
+ neither with GMP nor with future versions of mini-gmp. */
+
+/* Much of the material copied from GMP files, including: gmp-impl.h,
+ longlong.h, mpn/generic/add_n.c, mpn/generic/addmul_1.c,
+ mpn/generic/lshift.c, mpn/generic/mul_1.c,
+ mpn/generic/mul_basecase.c, mpn/generic/rshift.c,
+ mpn/generic/sbpi1_div_qr.c, mpn/generic/sub_n.c,
+ mpn/generic/submul_1.c. */
+
+#include <assert.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mini-gmp.h"
+
+
+/* Macros */
+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
+
+#define GMP_LIMB_MAX (~ (mp_limb_t) 0)
+#define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1))
+
+#define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2))
+#define GMP_LLIMB_MASK (GMP_HLIMB_BIT - 1)
+
+#define GMP_ULONG_BITS (sizeof(unsigned long) * CHAR_BIT)
+#define GMP_ULONG_HIGHBIT ((unsigned long) 1 << (GMP_ULONG_BITS - 1))
+
+#define GMP_ABS(x) ((x) >= 0 ? (x) : -(x))
+#define GMP_NEG_CAST(T,x) (-((T)((x) + 1) - 1))
+
+#define GMP_MIN(a, b) ((a) < (b) ? (a) : (b))
+#define GMP_MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define gmp_assert_nocarry(x) do { \
+ mp_limb_t __cy = x; \
+ assert (__cy == 0); \
+ } while (0)
+
+#define gmp_clz(count, x) do { \
+ mp_limb_t __clz_x = (x); \
+ unsigned __clz_c; \
+ for (__clz_c = 0; \
+ (__clz_x & ((mp_limb_t) 0xff << (GMP_LIMB_BITS - 8))) == 0; \
+ __clz_c += 8) \
+ __clz_x <<= 8; \
+ for (; (__clz_x & GMP_LIMB_HIGHBIT) == 0; __clz_c++) \
+ __clz_x <<= 1; \
+ (count) = __clz_c; \
+ } while (0)
+
+#define gmp_ctz(count, x) do { \
+ mp_limb_t __ctz_x = (x); \
+ unsigned __ctz_c = 0; \
+ gmp_clz (__ctz_c, __ctz_x & - __ctz_x); \
+ (count) = GMP_LIMB_BITS - 1 - __ctz_c; \
+ } while (0)
+
+#define gmp_add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ mp_limb_t __x; \
+ __x = (al) + (bl); \
+ (sh) = (ah) + (bh) + (__x < (al)); \
+ (sl) = __x; \
+ } while (0)
+
+#define gmp_sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ mp_limb_t __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - ((al) < (bl)); \
+ (sl) = __x; \
+ } while (0)
+
+#define gmp_umul_ppmm(w1, w0, u, v) \
+ do { \
+ mp_limb_t __x0, __x1, __x2, __x3; \
+ unsigned __ul, __vl, __uh, __vh; \
+ mp_limb_t __u = (u), __v = (v); \
+ \
+ __ul = __u & GMP_LLIMB_MASK; \
+ __uh = __u >> (GMP_LIMB_BITS / 2); \
+ __vl = __v & GMP_LLIMB_MASK; \
+ __vh = __v >> (GMP_LIMB_BITS / 2); \
+ \
+ __x0 = (mp_limb_t) __ul * __vl; \
+ __x1 = (mp_limb_t) __ul * __vh; \
+ __x2 = (mp_limb_t) __uh * __vl; \
+ __x3 = (mp_limb_t) __uh * __vh; \
+ \
+ __x1 += __x0 >> (GMP_LIMB_BITS / 2);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += GMP_HLIMB_BIT; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \
+ (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \
+ } while (0)
+
+#define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
+ do { \
+ mp_limb_t _qh, _ql, _r, _mask; \
+ gmp_umul_ppmm (_qh, _ql, (nh), (di)); \
+ gmp_add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \
+ _r = (nl) - _qh * (d); \
+ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \
+ _qh += _mask; \
+ _r += _mask & (d); \
+ if (_r >= (d)) \
+ { \
+ _r -= (d); \
+ _qh++; \
+ } \
+ \
+ (r) = _r; \
+ (q) = _qh; \
+ } while (0)
+
+#define gmp_udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \
+ do { \
+ mp_limb_t _q0, _t1, _t0, _mask; \
+ gmp_umul_ppmm ((q), _q0, (n2), (dinv)); \
+ gmp_add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \
+ \
+ /* Compute the two most significant limbs of n - q'd */ \
+ (r1) = (n1) - (d1) * (q); \
+ gmp_sub_ddmmss ((r1), (r0), (r1), (n0), (d1), (d0)); \
+ gmp_umul_ppmm (_t1, _t0, (d0), (q)); \
+ gmp_sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \
+ (q)++; \
+ \
+ /* Conditionally adjust q and the remainders */ \
+ _mask = - (mp_limb_t) ((r1) >= _q0); \
+ (q) += _mask; \
+ gmp_add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \
+ if ((r1) >= (d1)) \
+ { \
+ if ((r1) > (d1) || (r0) >= (d0)) \
+ { \
+ (q)++; \
+ gmp_sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \
+ } \
+ } \
+ } while (0)
+
+/* Swap macros. */
+#define MP_LIMB_T_SWAP(x, y) \
+ do { \
+ mp_limb_t __mp_limb_t_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mp_limb_t_swap__tmp; \
+ } while (0)
+#define MP_SIZE_T_SWAP(x, y) \
+ do { \
+ mp_size_t __mp_size_t_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mp_size_t_swap__tmp; \
+ } while (0)
+#define MP_BITCNT_T_SWAP(x,y) \
+ do { \
+ mp_bitcnt_t __mp_bitcnt_t_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mp_bitcnt_t_swap__tmp; \
+ } while (0)
+#define MP_PTR_SWAP(x, y) \
+ do { \
+ mp_ptr __mp_ptr_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mp_ptr_swap__tmp; \
+ } while (0)
+#define MP_SRCPTR_SWAP(x, y) \
+ do { \
+ mp_srcptr __mp_srcptr_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mp_srcptr_swap__tmp; \
+ } while (0)
+
+#define MPN_PTR_SWAP(xp,xs, yp,ys) \
+ do { \
+ MP_PTR_SWAP (xp, yp); \
+ MP_SIZE_T_SWAP (xs, ys); \
+ } while(0)
+#define MPN_SRCPTR_SWAP(xp,xs, yp,ys) \
+ do { \
+ MP_SRCPTR_SWAP (xp, yp); \
+ MP_SIZE_T_SWAP (xs, ys); \
+ } while(0)
+
+#define MPZ_PTR_SWAP(x, y) \
+ do { \
+ mpz_ptr __mpz_ptr_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mpz_ptr_swap__tmp; \
+ } while (0)
+#define MPZ_SRCPTR_SWAP(x, y) \
+ do { \
+ mpz_srcptr __mpz_srcptr_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mpz_srcptr_swap__tmp; \
+ } while (0)
+
+const int mp_bits_per_limb = GMP_LIMB_BITS;
+
+
+/* Memory allocation and other helper functions. */
+static void
+gmp_die (const char *msg)
+{
+ fprintf (stderr, "%s\n", msg);
+ abort();
+}
+
+static void *
+gmp_default_alloc (size_t size)
+{
+ void *p;
+
+ assert (size > 0);
+
+ p = malloc (size);
+ if (!p)
+ gmp_die("gmp_default_alloc: Virtual memory exhausted.");
+
+ return p;
+}
+
+static void *
+gmp_default_realloc (void *old, size_t old_size, size_t new_size)
+{
+ mp_ptr p;
+
+ p = realloc (old, new_size);
+
+ if (!p)
+ gmp_die("gmp_default_realoc: Virtual memory exhausted.");
+
+ return p;
+}
+
+static void
+gmp_default_free (void *p, size_t size)
+{
+ free (p);
+}
+
+static void * (*gmp_allocate_func) (size_t) = gmp_default_alloc;
+static void * (*gmp_reallocate_func) (void *, size_t, size_t) = gmp_default_realloc;
+static void (*gmp_free_func) (void *, size_t) = gmp_default_free;
+
+void
+mp_get_memory_functions (void *(**alloc_func) (size_t),
+ void *(**realloc_func) (void *, size_t, size_t),
+ void (**free_func) (void *, size_t))
+{
+ if (alloc_func)
+ *alloc_func = gmp_allocate_func;
+
+ if (realloc_func)
+ *realloc_func = gmp_reallocate_func;
+
+ if (free_func)
+ *free_func = gmp_free_func;
+}
+
+void
+mp_set_memory_functions (void *(*alloc_func) (size_t),
+ void *(*realloc_func) (void *, size_t, size_t),
+ void (*free_func) (void *, size_t))
+{
+ if (!alloc_func)
+ alloc_func = gmp_default_alloc;
+ if (!realloc_func)
+ realloc_func = gmp_default_realloc;
+ if (!free_func)
+ free_func = gmp_default_free;
+
+ gmp_allocate_func = alloc_func;
+ gmp_reallocate_func = realloc_func;
+ gmp_free_func = free_func;
+}
+
+#define gmp_xalloc(size) ((*gmp_allocate_func)((size)))
+#define gmp_free(p) ((*gmp_free_func) ((p), 0))
+
+static mp_ptr
+gmp_xalloc_limbs (mp_size_t size)
+{
+ return gmp_xalloc (size * sizeof (mp_limb_t));
+}
+
+static mp_ptr
+gmp_xrealloc_limbs (mp_ptr old, mp_size_t size)
+{
+ assert (size > 0);
+ return (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t));
+}
+
+
+/* MPN interface */
+
+void
+mpn_copyi (mp_ptr d, mp_srcptr s, mp_size_t n)
+{
+ mp_size_t i;
+ for (i = 0; i < n; i++)
+ d[i] = s[i];
+}
+
+void
+mpn_copyd (mp_ptr d, mp_srcptr s, mp_size_t n)
+{
+ while (n-- > 0)
+ d[n] = s[n];
+}
+
+int
+mpn_cmp (mp_srcptr ap, mp_srcptr bp, mp_size_t n)
+{
+ while (--n >= 0)
+ {
+ if (ap[n] != bp[n])
+ return ap[n] > bp[n] ? 1 : -1;
+ }
+ return 0;
+}
+
+static int
+mpn_cmp4 (mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
+{
+ if (an != bn)
+ return an < bn ? -1 : 1;
+ else
+ return mpn_cmp (ap, bp, an);
+}
+
+static mp_size_t
+mpn_normalized_size (mp_srcptr xp, mp_size_t n)
+{
+ for (; n > 0 && xp[n-1] == 0; n--)
+ ;
+ return n;
+}
+
+#define mpn_zero_p(xp, n) (mpn_normalized_size ((xp), (n)) == 0)
+
+void
+mpn_zero (mp_ptr rp, mp_size_t n)
+{
+ mp_size_t i;
+
+ for (i = 0; i < n; i++)
+ rp[i] = 0;
+}
+
+mp_limb_t
+mpn_add_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
+{
+ mp_size_t i;
+
+ assert (n > 0);
+ i = 0;
+ do
+ {
+ mp_limb_t r = ap[i] + b;
+ /* Carry out */
+ b = (r < b);
+ rp[i] = r;
+ }
+ while (++i < n);
+
+ return b;
+}
+
+mp_limb_t
+mpn_add_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
+{
+ mp_size_t i;
+ mp_limb_t cy;
+
+ for (i = 0, cy = 0; i < n; i++)
+ {
+ mp_limb_t a, b, r;
+ a = ap[i]; b = bp[i];
+ r = a + cy;
+ cy = (r < cy);
+ r += b;
+ cy += (r < b);
+ rp[i] = r;
+ }
+ return cy;
+}
+
+mp_limb_t
+mpn_add (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
+{
+ mp_limb_t cy;
+
+ assert (an >= bn);
+
+ cy = mpn_add_n (rp, ap, bp, bn);
+ if (an > bn)
+ cy = mpn_add_1 (rp + bn, ap + bn, an - bn, cy);
+ return cy;
+}
+
+mp_limb_t
+mpn_sub_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
+{
+ mp_size_t i;
+
+ assert (n > 0);
+
+ i = 0;
+ do
+ {
+ mp_limb_t a = ap[i];
+ /* Carry out */
+ mp_limb_t cy = a < b;;
+ rp[i] = a - b;
+ b = cy;
+ }
+ while (++i < n);
+
+ return b;
+}
+
+mp_limb_t
+mpn_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
+{
+ mp_size_t i;
+ mp_limb_t cy;
+
+ for (i = 0, cy = 0; i < n; i++)
+ {
+ mp_limb_t a, b;
+ a = ap[i]; b = bp[i];
+ b += cy;
+ cy = (b < cy);
+ cy += (a < b);
+ rp[i] = a - b;
+ }
+ return cy;
+}
+
+mp_limb_t
+mpn_sub (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
+{
+ mp_limb_t cy;
+
+ assert (an >= bn);
+
+ cy = mpn_sub_n (rp, ap, bp, bn);
+ if (an > bn)
+ cy = mpn_sub_1 (rp + bn, ap + bn, an - bn, cy);
+ return cy;
+}
+
+mp_limb_t
+mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t ul, cl, hpl, lpl;
+
+ assert (n >= 1);
+
+ cl = 0;
+ do
+ {
+ ul = *up++;
+ gmp_umul_ppmm (hpl, lpl, ul, vl);
+
+ lpl += cl;
+ cl = (lpl < cl) + hpl;
+
+ *rp++ = lpl;
+ }
+ while (--n != 0);
+
+ return cl;
+}
+
+mp_limb_t
+mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t ul, cl, hpl, lpl, rl;
+
+ assert (n >= 1);
+
+ cl = 0;
+ do
+ {
+ ul = *up++;
+ gmp_umul_ppmm (hpl, lpl, ul, vl);
+
+ lpl += cl;
+ cl = (lpl < cl) + hpl;
+
+ rl = *rp;
+ lpl = rl + lpl;
+ cl += lpl < rl;
+ *rp++ = lpl;
+ }
+ while (--n != 0);
+
+ return cl;
+}
+
+mp_limb_t
+mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t ul, cl, hpl, lpl, rl;
+
+ assert (n >= 1);
+
+ cl = 0;
+ do
+ {
+ ul = *up++;
+ gmp_umul_ppmm (hpl, lpl, ul, vl);
+
+ lpl += cl;
+ cl = (lpl < cl) + hpl;
+
+ rl = *rp;
+ lpl = rl - lpl;
+ cl += lpl > rl;
+ *rp++ = lpl;
+ }
+ while (--n != 0);
+
+ return cl;
+}
+
+mp_limb_t
+mpn_mul (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn)
+{
+ assert (un >= vn);
+ assert (vn >= 1);
+
+ /* We first multiply by the low order limb. This result can be
+ stored, not added, to rp. We also avoid a loop for zeroing this
+ way. */
+
+ rp[un] = mpn_mul_1 (rp, up, un, vp[0]);
+ rp += 1, vp += 1, vn -= 1;
+
+ /* Now accumulate the product of up[] and the next higher limb from
+ vp[]. */
+
+ while (vn >= 1)
+ {
+ rp[un] = mpn_addmul_1 (rp, up, un, vp[0]);
+ rp += 1, vp += 1, vn -= 1;
+ }
+ return rp[un - 1];
+}
+
+void
+mpn_mul_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
+{
+ mpn_mul (rp, ap, n, bp, n);
+}
+
+void
+mpn_sqr (mp_ptr rp, mp_srcptr ap, mp_size_t n)
+{
+ mpn_mul (rp, ap, n, ap, n);
+}
+
+mp_limb_t
+mpn_lshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt)
+{
+ mp_limb_t high_limb, low_limb;
+ unsigned int tnc;
+ mp_size_t i;
+ mp_limb_t retval;
+
+ assert (n >= 1);
+ assert (cnt >= 1);
+ assert (cnt < GMP_LIMB_BITS);
+
+ up += n;
+ rp += n;
+
+ tnc = GMP_LIMB_BITS - cnt;
+ low_limb = *--up;
+ retval = low_limb >> tnc;
+ high_limb = (low_limb << cnt);
+
+ for (i = n; --i != 0;)
+ {
+ low_limb = *--up;
+ *--rp = high_limb | (low_limb >> tnc);
+ high_limb = (low_limb << cnt);
+ }
+ *--rp = high_limb;
+
+ return retval;
+}
+
+mp_limb_t
+mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt)
+{
+ mp_limb_t high_limb, low_limb;
+ unsigned int tnc;
+ mp_size_t i;
+ mp_limb_t retval;
+
+ assert (n >= 1);
+ assert (cnt >= 1);
+ assert (cnt < GMP_LIMB_BITS);
+
+ tnc = GMP_LIMB_BITS - cnt;
+ high_limb = *up++;
+ retval = (high_limb << tnc);
+ low_limb = high_limb >> cnt;
+
+ for (i = n; --i != 0;)
+ {
+ high_limb = *up++;
+ *rp++ = low_limb | (high_limb << tnc);
+ low_limb = high_limb >> cnt;
+ }
+ *rp = low_limb;
+
+ return retval;
+}
+
+static mp_bitcnt_t
+mpn_common_scan (mp_limb_t limb, mp_size_t i, mp_srcptr up, mp_size_t un,
+ mp_limb_t ux)
+{
+ unsigned cnt;
+
+ assert (ux == 0 || ux == GMP_LIMB_MAX);
+ assert (0 <= i && i <= un );
+
+ while (limb == 0)
+ {
+ i++;
+ if (i == un)
+ return (ux == 0 ? ~(mp_bitcnt_t) 0 : un * GMP_LIMB_BITS);
+ limb = ux ^ up[i];
+ }
+ gmp_ctz (cnt, limb);
+ return (mp_bitcnt_t) i * GMP_LIMB_BITS + cnt;
+}
+
+mp_bitcnt_t
+mpn_scan1 (mp_srcptr ptr, mp_bitcnt_t bit)
+{
+ mp_size_t i;
+ i = bit / GMP_LIMB_BITS;
+
+ return mpn_common_scan ( ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)),
+ i, ptr, i, 0);
+}
+
+mp_bitcnt_t
+mpn_scan0 (mp_srcptr ptr, mp_bitcnt_t bit)
+{
+ mp_size_t i;
+ i = bit / GMP_LIMB_BITS;
+
+ return mpn_common_scan (~ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)),
+ i, ptr, i, GMP_LIMB_MAX);
+}
+
+
+/* MPN division interface. */
+mp_limb_t
+mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
+{
+ mp_limb_t r, p, m;
+ unsigned ul, uh;
+ unsigned ql, qh;
+
+ /* First, do a 2/1 inverse. */
+ /* The inverse m is defined as floor( (B^2 - 1 - u1)/u1 ), so that 0 <
+ * B^2 - (B + m) u1 <= u1 */
+ assert (u1 >= GMP_LIMB_HIGHBIT);
+
+ ul = u1 & GMP_LLIMB_MASK;
+ uh = u1 >> (GMP_LIMB_BITS / 2);
+
+ qh = ~u1 / uh;
+ r = ((~u1 - (mp_limb_t) qh * uh) << (GMP_LIMB_BITS / 2)) | GMP_LLIMB_MASK;
+
+ p = (mp_limb_t) qh * ul;
+ /* Adjustment steps taken from udiv_qrnnd_c */
+ if (r < p)
+ {
+ qh--;
+ r += u1;
+ if (r >= u1) /* i.e. we didn't get carry when adding to r */
+ if (r < p)
+ {
+ qh--;
+ r += u1;
+ }
+ }
+ r -= p;
+
+ /* Do a 3/2 division (with half limb size) */
+ p = (r >> (GMP_LIMB_BITS / 2)) * qh + r;
+ ql = (p >> (GMP_LIMB_BITS / 2)) + 1;
+
+ /* By the 3/2 method, we don't need the high half limb. */
+ r = (r << (GMP_LIMB_BITS / 2)) + GMP_LLIMB_MASK - ql * u1;
+
+ if (r >= (p << (GMP_LIMB_BITS / 2)))
+ {
+ ql--;
+ r += u1;
+ }
+ m = ((mp_limb_t) qh << (GMP_LIMB_BITS / 2)) + ql;
+ if (r >= u1)
+ {
+ m++;
+ r -= u1;
+ }
+
+ if (u0 > 0)
+ {
+ mp_limb_t th, tl;
+ r = ~r;
+ r += u0;
+ if (r < u0)
+ {
+ m--;
+ if (r >= u1)
+ {
+ m--;
+ r -= u1;
+ }
+ r -= u1;
+ }
+ gmp_umul_ppmm (th, tl, u0, m);
+ r += th;
+ if (r < th)
+ {
+ m--;
+ m -= ((r > u1) | ((r == u1) & (tl > u0)));
+ }
+ }
+
+ return m;
+}
+
+struct gmp_div_inverse
+{
+ /* Normalization shift count. */
+ unsigned shift;
+ /* Normalized divisor (d0 unused for mpn_div_qr_1) */
+ mp_limb_t d1, d0;
+ /* Inverse, for 2/1 or 3/2. */
+ mp_limb_t di;
+};
+
+static void
+mpn_div_qr_1_invert (struct gmp_div_inverse *inv, mp_limb_t d)
+{
+ unsigned shift;
+
+ assert (d > 0);
+ gmp_clz (shift, d);
+ inv->shift = shift;
+ inv->d1 = d << shift;
+ inv->di = mpn_invert_limb (inv->d1);
+}
+
+static void
+mpn_div_qr_2_invert (struct gmp_div_inverse *inv,
+ mp_limb_t d1, mp_limb_t d0)
+{
+ unsigned shift;
+
+ assert (d1 > 0);
+ gmp_clz (shift, d1);
+ inv->shift = shift;
+ if (shift > 0)
+ {
+ d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift));
+ d0 <<= shift;
+ }
+ inv->d1 = d1;
+ inv->d0 = d0;
+ inv->di = mpn_invert_3by2 (d1, d0);
+}
+
+static void
+mpn_div_qr_invert (struct gmp_div_inverse *inv,
+ mp_srcptr dp, mp_size_t dn)
+{
+ assert (dn > 0);
+
+ if (dn == 1)
+ mpn_div_qr_1_invert (inv, dp[0]);
+ else if (dn == 2)
+ mpn_div_qr_2_invert (inv, dp[1], dp[0]);
+ else
+ {
+ unsigned shift;
+ mp_limb_t d1, d0;
+
+ d1 = dp[dn-1];
+ d0 = dp[dn-2];
+ assert (d1 > 0);
+ gmp_clz (shift, d1);
+ inv->shift = shift;
+ if (shift > 0)
+ {
+ d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift));
+ d0 = (d0 << shift) | (dp[dn-3] >> (GMP_LIMB_BITS - shift));
+ }
+ inv->d1 = d1;
+ inv->d0 = d0;
+ inv->di = mpn_invert_3by2 (d1, d0);
+ }
+}
+
+/* Not matching current public gmp interface, rather corresponding to
+ the sbpi1_div_* functions. */
+static mp_limb_t
+mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn,
+ const struct gmp_div_inverse *inv)
+{
+ mp_limb_t d, di;
+ mp_limb_t r;
+ mp_ptr tp = NULL;
+
+ if (inv->shift > 0)
+ {
+ tp = gmp_xalloc_limbs (nn);
+ r = mpn_lshift (tp, np, nn, inv->shift);
+ np = tp;
+ }
+ else
+ r = 0;
+
+ d = inv->d1;
+ di = inv->di;
+ while (nn-- > 0)
+ {
+ mp_limb_t q;
+
+ gmp_udiv_qrnnd_preinv (q, r, r, np[nn], d, di);
+ if (qp)
+ qp[nn] = q;
+ }
+ if (inv->shift > 0)
+ gmp_free (tp);
+
+ return r >> inv->shift;
+}
+
+static mp_limb_t
+mpn_div_qr_1 (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t d)
+{
+ assert (d > 0);
+
+ /* Special case for powers of two. */
+ if ((d & (d-1)) == 0)
+ {
+ mp_limb_t r = np[0] & (d-1);
+ if (qp)
+ {
+ if (d <= 1)
+ mpn_copyi (qp, np, nn);
+ else
+ {
+ unsigned shift;
+ gmp_ctz (shift, d);
+ mpn_rshift (qp, np, nn, shift);
+ }
+ }
+ return r;
+ }
+ else
+ {
+ struct gmp_div_inverse inv;
+ mpn_div_qr_1_invert (&inv, d);
+ return mpn_div_qr_1_preinv (qp, np, nn, &inv);
+ }
+}
+
+static void
+mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn,
+ const struct gmp_div_inverse *inv)
+{
+ unsigned shift;
+ mp_size_t i;
+ mp_limb_t d1, d0, di, r1, r0;
+ mp_ptr tp;
+
+ assert (nn >= 2);
+ shift = inv->shift;
+ d1 = inv->d1;
+ d0 = inv->d0;
+ di = inv->di;
+
+ if (shift > 0)
+ {
+ tp = gmp_xalloc_limbs (nn);
+ r1 = mpn_lshift (tp, np, nn, shift);
+ np = tp;
+ }
+ else
+ r1 = 0;
+
+ r0 = np[nn - 1];
+
+ i = nn - 2;
+ do
+ {
+ mp_limb_t n0, q;
+ n0 = np[i];
+ gmp_udiv_qr_3by2 (q, r1, r0, r1, r0, n0, d1, d0, di);
+
+ if (qp)
+ qp[i] = q;
+ }
+ while (--i >= 0);
+
+ if (shift > 0)
+ {
+ assert ((r0 << (GMP_LIMB_BITS - shift)) == 0);
+ r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift));
+ r1 >>= shift;
+
+ gmp_free (tp);
+ }
+
+ rp[1] = r1;
+ rp[0] = r0;
+}
+
+#if 0
+static void
+mpn_div_qr_2 (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn,
+ mp_limb_t d1, mp_limb_t d0)
+{
+ struct gmp_div_inverse inv;
+ assert (nn >= 2);
+
+ mpn_div_qr_2_invert (&inv, d1, d0);
+ mpn_div_qr_2_preinv (qp, rp, np, nn, &inv);
+}
+#endif
+
+static void
+mpn_div_qr_pi1 (mp_ptr qp,
+ mp_ptr np, mp_size_t nn, mp_limb_t n1,
+ mp_srcptr dp, mp_size_t dn,
+ mp_limb_t dinv)
+{
+ mp_size_t i;
+
+ mp_limb_t d1, d0;
+ mp_limb_t cy, cy1;
+ mp_limb_t q;
+
+ assert (dn > 2);
+ assert (nn >= dn);
+
+ d1 = dp[dn - 1];
+ d0 = dp[dn - 2];
+
+ assert ((d1 & GMP_LIMB_HIGHBIT) != 0);
+ /* Iteration variable is the index of the q limb.
+ *
+ * We divide <n1, np[dn-1+i], np[dn-2+i], np[dn-3+i],..., np[i]>
+ * by <d1, d0, dp[dn-3], ..., dp[0] >
+ */
+
+ i = nn - dn;
+ do
+ {
+ mp_limb_t n0 = np[dn-1+i];
+
+ if (n1 == d1 && n0 == d0)
+ {
+ q = GMP_LIMB_MAX;
+ mpn_submul_1 (np+i, dp, dn, q);
+ n1 = np[dn-1+i]; /* update n1, last loop's value will now be invalid */
+ }
+ else
+ {
+ gmp_udiv_qr_3by2 (q, n1, n0, n1, n0, np[dn-2+i], d1, d0, dinv);
+
+ cy = mpn_submul_1 (np + i, dp, dn-2, q);
+
+ cy1 = n0 < cy;
+ n0 = n0 - cy;
+ cy = n1 < cy1;
+ n1 = n1 - cy1;
+ np[dn-2+i] = n0;
+
+ if (cy != 0)
+ {
+ n1 += d1 + mpn_add_n (np + i, np + i, dp, dn - 1);
+ q--;
+ }
+ }
+
+ if (qp)
+ qp[i] = q;
+ }
+ while (--i >= 0);
+
+ np[dn - 1] = n1;
+}
+
+static void
+mpn_div_qr_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ const struct gmp_div_inverse *inv)
+{
+ assert (dn > 0);
+ assert (nn >= dn);
+
+ if (dn == 1)
+ np[0] = mpn_div_qr_1_preinv (qp, np, nn, inv);
+ else if (dn == 2)
+ mpn_div_qr_2_preinv (qp, np, np, nn, inv);
+ else
+ {
+ mp_limb_t nh;
+ unsigned shift;
+
+ assert (inv->d1 == dp[dn-1]);
+ assert (inv->d0 == dp[dn-2]);
+ assert ((inv->d1 & GMP_LIMB_HIGHBIT) != 0);
+
+ shift = inv->shift;
+ if (shift > 0)
+ nh = mpn_lshift (np, np, nn, shift);
+ else
+ nh = 0;
+
+ mpn_div_qr_pi1 (qp, np, nn, nh, dp, dn, inv->di);
+
+ if (shift > 0)
+ gmp_assert_nocarry (mpn_rshift (np, np, dn, shift));
+ }
+}
+
+static void
+mpn_div_qr (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn)
+{
+ struct gmp_div_inverse inv;
+ mp_ptr tp = NULL;
+
+ assert (dn > 0);
+ assert (nn >= dn);
+
+ mpn_div_qr_invert (&inv, dp, dn);
+ if (dn > 2 && inv.shift > 0)
+ {
+ tp = gmp_xalloc_limbs (dn);
+ gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift));
+ dp = tp;
+ }
+ mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv);
+ if (tp)
+ gmp_free (tp);
+}
+
+
+/* MPN base conversion. */
+static unsigned
+mpn_base_power_of_two_p (unsigned b)
+{
+ switch (b)
+ {
+ case 2: return 1;
+ case 4: return 2;
+ case 8: return 3;
+ case 16: return 4;
+ case 32: return 5;
+ case 64: return 6;
+ case 128: return 7;
+ case 256: return 8;
+ default: return 0;
+ }
+}
+
+struct mpn_base_info
+{
+ /* bb is the largest power of the base which fits in one limb, and
+ exp is the corresponding exponent. */
+ unsigned exp;
+ mp_limb_t bb;
+};
+
+static void
+mpn_get_base_info (struct mpn_base_info *info, mp_limb_t b)
+{
+ mp_limb_t m;
+ mp_limb_t p;
+ unsigned exp;
+
+ m = GMP_LIMB_MAX / b;
+ for (exp = 1, p = b; p <= m; exp++)
+ p *= b;
+
+ info->exp = exp;
+ info->bb = p;
+}
+
+static mp_bitcnt_t
+mpn_limb_size_in_base_2 (mp_limb_t u)
+{
+ unsigned shift;
+
+ assert (u > 0);
+ gmp_clz (shift, u);
+ return GMP_LIMB_BITS - shift;
+}
+
+static size_t
+mpn_get_str_bits (unsigned char *sp, unsigned bits, mp_srcptr up, mp_size_t un)
+{
+ unsigned char mask;
+ size_t sn, j;
+ mp_size_t i;
+ int shift;
+
+ sn = ((un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1])
+ + bits - 1) / bits;
+
+ mask = (1U << bits) - 1;
+
+ for (i = 0, j = sn, shift = 0; j-- > 0;)
+ {
+ unsigned char digit = up[i] >> shift;
+
+ shift += bits;
+
+ if (shift >= GMP_LIMB_BITS && ++i < un)
+ {
+ shift -= GMP_LIMB_BITS;
+ digit |= up[i] << (bits - shift);
+ }
+ sp[j] = digit & mask;
+ }
+ return sn;
+}
+
+/* We generate digits from the least significant end, and reverse at
+ the end. */
+static size_t
+mpn_limb_get_str (unsigned char *sp, mp_limb_t w,
+ const struct gmp_div_inverse *binv)
+{
+ mp_size_t i;
+ for (i = 0; w > 0; i++)
+ {
+ mp_limb_t h, l, r;
+
+ h = w >> (GMP_LIMB_BITS - binv->shift);
+ l = w << binv->shift;
+
+ gmp_udiv_qrnnd_preinv (w, r, h, l, binv->d1, binv->di);
+ assert ( (r << (GMP_LIMB_BITS - binv->shift)) == 0);
+ r >>= binv->shift;
+
+ sp[i] = r;
+ }
+ return i;
+}
+
+static size_t
+mpn_get_str_other (unsigned char *sp,
+ int base, const struct mpn_base_info *info,
+ mp_ptr up, mp_size_t un)
+{
+ struct gmp_div_inverse binv;
+ size_t sn;
+ size_t i;
+
+ mpn_div_qr_1_invert (&binv, base);
+
+ sn = 0;
+
+ if (un > 1)
+ {
+ struct gmp_div_inverse bbinv;
+ mpn_div_qr_1_invert (&bbinv, info->bb);
+
+ do
+ {
+ mp_limb_t w;
+ size_t done;
+ w = mpn_div_qr_1_preinv (up, up, un, &bbinv);
+ un -= (up[un-1] == 0);
+ done = mpn_limb_get_str (sp + sn, w, &binv);
+
+ for (sn += done; done < info->exp; done++)
+ sp[sn++] = 0;
+ }
+ while (un > 1);
+ }
+ sn += mpn_limb_get_str (sp + sn, up[0], &binv);
+
+ /* Reverse order */
+ for (i = 0; 2*i + 1 < sn; i++)
+ {
+ unsigned char t = sp[i];
+ sp[i] = sp[sn - i - 1];
+ sp[sn - i - 1] = t;
+ }
+
+ return sn;
+}
+
+size_t
+mpn_get_str (unsigned char *sp, int base, mp_ptr up, mp_size_t un)
+{
+ unsigned bits;
+
+ assert (un > 0);
+ assert (up[un-1] > 0);
+
+ bits = mpn_base_power_of_two_p (base);
+ if (bits)
+ return mpn_get_str_bits (sp, bits, up, un);
+ else
+ {
+ struct mpn_base_info info;
+
+ mpn_get_base_info (&info, base);
+ return mpn_get_str_other (sp, base, &info, up, un);
+ }
+}
+
+static mp_size_t
+mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, size_t sn,
+ unsigned bits)
+{
+ mp_size_t rn;
+ size_t j;
+ unsigned shift;
+
+ for (j = sn, rn = 0, shift = 0; j-- > 0; )
+ {
+ if (shift == 0)
+ {
+ rp[rn++] = sp[j];
+ shift += bits;
+ }
+ else
+ {
+ rp[rn-1] |= (mp_limb_t) sp[j] << shift;
+ shift += bits;
+ if (shift >= GMP_LIMB_BITS)
+ {
+ shift -= GMP_LIMB_BITS;
+ if (shift > 0)
+ rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift);
+ }
+ }
+ }
+ rn = mpn_normalized_size (rp, rn);
+ return rn;
+}
+
+static mp_size_t
+mpn_set_str_other (mp_ptr rp, const unsigned char *sp, size_t sn,
+ mp_limb_t b, const struct mpn_base_info *info)
+{
+ mp_size_t rn;
+ mp_limb_t w;
+ unsigned k;
+ size_t j;
+
+ k = 1 + (sn - 1) % info->exp;
+
+ j = 0;
+ w = sp[j++];
+ for (; --k > 0; )
+ w = w * b + sp[j++];
+
+ rp[0] = w;
+
+ for (rn = (w > 0); j < sn;)
+ {
+ mp_limb_t cy;
+
+ w = sp[j++];
+ for (k = 1; k < info->exp; k++)
+ w = w * b + sp[j++];
+
+ cy = mpn_mul_1 (rp, rp, rn, info->bb);
+ cy += mpn_add_1 (rp, rp, rn, w);
+ if (cy > 0)
+ rp[rn++] = cy;
+ }
+ assert (j == sn);
+
+ return rn;
+}
+
+mp_size_t
+mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base)
+{
+ unsigned bits;
+
+ if (sn == 0)
+ return 0;
+
+ bits = mpn_base_power_of_two_p (base);
+ if (bits)
+ return mpn_set_str_bits (rp, sp, sn, bits);
+ else
+ {
+ struct mpn_base_info info;
+
+ mpn_get_base_info (&info, base);
+ return mpn_set_str_other (rp, sp, sn, base, &info);
+ }
+}
+
+
+/* MPZ interface */
+void
+mpz_init (mpz_t r)
+{
+ r->_mp_alloc = 1;
+ r->_mp_size = 0;
+ r->_mp_d = gmp_xalloc_limbs (1);
+}
+
+/* The utility of this function is a bit limited, since many functions
+ assigns the result variable using mpz_swap. */
+void
+mpz_init2 (mpz_t r, mp_bitcnt_t bits)
+{
+ mp_size_t rn;
+
+ bits -= (bits != 0); /* Round down, except if 0 */
+ rn = 1 + bits / GMP_LIMB_BITS;
+
+ r->_mp_alloc = rn;
+ r->_mp_size = 0;
+ r->_mp_d = gmp_xalloc_limbs (rn);
+}
+
+void
+mpz_clear (mpz_t r)
+{
+ gmp_free (r->_mp_d);
+}
+
+static void *
+mpz_realloc (mpz_t r, mp_size_t size)
+{
+ size = GMP_MAX (size, 1);
+
+ r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size);
+ r->_mp_alloc = size;
+
+ if (GMP_ABS (r->_mp_size) > size)
+ r->_mp_size = 0;
+
+ return r->_mp_d;
+}
+
+/* Realloc for an mpz_t WHAT if it has less than NEEDED limbs. */
+#define MPZ_REALLOC(z,n) ((n) > (z)->_mp_alloc \
+ ? mpz_realloc(z,n) \
+ : (z)->_mp_d)
+
+/* MPZ assignment and basic conversions. */
+void
+mpz_set_si (mpz_t r, signed long int x)
+{
+ if (x >= 0)
+ mpz_set_ui (r, x);
+ else /* (x < 0) */
+ {
+ r->_mp_size = -1;
+ r->_mp_d[0] = GMP_NEG_CAST (unsigned long int, x);
+ }
+}
+
+void
+mpz_set_ui (mpz_t r, unsigned long int x)
+{
+ if (x > 0)
+ {
+ r->_mp_size = 1;
+ r->_mp_d[0] = x;
+ }
+ else
+ r->_mp_size = 0;
+}
+
+void
+mpz_set (mpz_t r, const mpz_t x)
+{
+ /* Allow the NOP r == x */
+ if (r != x)
+ {
+ mp_size_t n;
+ mp_ptr rp;
+
+ n = GMP_ABS (x->_mp_size);
+ rp = MPZ_REALLOC (r, n);
+
+ mpn_copyi (rp, x->_mp_d, n);
+ r->_mp_size = x->_mp_size;
+ }
+}
+
+void
+mpz_init_set_si (mpz_t r, signed long int x)
+{
+ mpz_init (r);
+ mpz_set_si (r, x);
+}
+
+void
+mpz_init_set_ui (mpz_t r, unsigned long int x)
+{
+ mpz_init (r);
+ mpz_set_ui (r, x);
+}
+
+void
+mpz_init_set (mpz_t r, const mpz_t x)
+{
+ mpz_init (r);
+ mpz_set (r, x);
+}
+
+int
+mpz_fits_slong_p (const mpz_t u)
+{
+ mp_size_t us = u->_mp_size;
+
+ if (us == 0)
+ return 1;
+ else if (us == 1)
+ return u->_mp_d[0] < GMP_LIMB_HIGHBIT;
+ else if (us == -1)
+ return u->_mp_d[0] <= GMP_LIMB_HIGHBIT;
+ else
+ return 0;
+}
+
+int
+mpz_fits_ulong_p (const mpz_t u)
+{
+ mp_size_t us = u->_mp_size;
+
+ return (us == (us > 0));
+}
+
+long int
+mpz_get_si (const mpz_t u)
+{
+ mp_size_t us = u->_mp_size;
+
+ if (us > 0)
+ return (long) (u->_mp_d[0] & ~GMP_LIMB_HIGHBIT);
+ else if (us < 0)
+ return (long) (- u->_mp_d[0] | GMP_LIMB_HIGHBIT);
+ else
+ return 0;
+}
+
+unsigned long int
+mpz_get_ui (const mpz_t u)
+{
+ return u->_mp_size == 0 ? 0 : u->_mp_d[0];
+}
+
+size_t
+mpz_size (const mpz_t u)
+{
+ return GMP_ABS (u->_mp_size);
+}
+
+mp_limb_t
+mpz_getlimbn (const mpz_t u, mp_size_t n)
+{
+ if (n >= 0 && n < GMP_ABS (u->_mp_size))
+ return u->_mp_d[n];
+ else
+ return 0;
+}
+
+void
+mpz_realloc2 (mpz_t x, mp_bitcnt_t n)
+{
+ mpz_realloc (x, 1 + (n - (n != 0)) / GMP_LIMB_BITS);
+}
+
+mp_srcptr
+mpz_limbs_read (mpz_srcptr x)
+{
+ return x->_mp_d;;
+}
+
+mp_ptr
+mpz_limbs_modify (mpz_t x, mp_size_t n)
+{
+ assert (n > 0);
+ return MPZ_REALLOC (x, n);
+}
+
+mp_ptr
+mpz_limbs_write (mpz_t x, mp_size_t n)
+{
+ return mpz_limbs_modify (x, n);
+}
+
+void
+mpz_limbs_finish (mpz_t x, mp_size_t xs)
+{
+ mp_size_t xn;
+ xn = mpn_normalized_size (x->_mp_d, GMP_ABS (xs));
+ x->_mp_size = xs < 0 ? -xn : xn;
+}
+
+mpz_srcptr
+mpz_roinit_n (mpz_t x, mp_srcptr xp, mp_size_t xs)
+{
+ x->_mp_alloc = 0;
+ x->_mp_d = (mp_ptr) xp;
+ mpz_limbs_finish (x, xs);
+ return x;
+}
+
+
+/* Conversions and comparison to double. */
+void
+mpz_set_d (mpz_t r, double x)
+{
+ int sign;
+ mp_ptr rp;
+ mp_size_t rn, i;
+ double B;
+ double Bi;
+ mp_limb_t f;
+
+ /* x != x is true when x is a NaN, and x == x * 0.5 is true when x is
+ zero or infinity. */
+ if (x != x || x == x * 0.5)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+
+ sign = x < 0.0 ;
+ if (sign)
+ x = - x;
+
+ if (x < 1.0)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+ B = 2.0 * (double) GMP_LIMB_HIGHBIT;
+ Bi = 1.0 / B;
+ for (rn = 1; x >= B; rn++)
+ x *= Bi;
+
+ rp = MPZ_REALLOC (r, rn);
+
+ f = (mp_limb_t) x;
+ x -= f;
+ assert (x < 1.0);
+ i = rn-1;
+ rp[i] = f;
+ while (--i >= 0)
+ {
+ x = B * x;
+ f = (mp_limb_t) x;
+ x -= f;
+ assert (x < 1.0);
+ rp[i] = f;
+ }
+
+ r->_mp_size = sign ? - rn : rn;
+}
+
+void
+mpz_init_set_d (mpz_t r, double x)
+{
+ mpz_init (r);
+ mpz_set_d (r, x);
+}
+
+double
+mpz_get_d (const mpz_t u)
+{
+ mp_size_t un;
+ double x;
+ double B = 2.0 * (double) GMP_LIMB_HIGHBIT;
+
+ un = GMP_ABS (u->_mp_size);
+
+ if (un == 0)
+ return 0.0;
+
+ x = u->_mp_d[--un];
+ while (un > 0)
+ x = B*x + u->_mp_d[--un];
+
+ if (u->_mp_size < 0)
+ x = -x;
+
+ return x;
+}
+
+int
+mpz_cmpabs_d (const mpz_t x, double d)
+{
+ mp_size_t xn;
+ double B, Bi;
+ mp_size_t i;
+
+ xn = x->_mp_size;
+ d = GMP_ABS (d);
+
+ if (xn != 0)
+ {
+ xn = GMP_ABS (xn);
+
+ B = 2.0 * (double) GMP_LIMB_HIGHBIT;
+ Bi = 1.0 / B;
+
+ /* Scale d so it can be compared with the top limb. */
+ for (i = 1; i < xn; i++)
+ d *= Bi;
+
+ if (d >= B)
+ return -1;
+
+ /* Compare floor(d) to top limb, subtract and cancel when equal. */
+ for (i = xn; i-- > 0;)
+ {
+ mp_limb_t f, xl;
+
+ f = (mp_limb_t) d;
+ xl = x->_mp_d[i];
+ if (xl > f)
+ return 1;
+ else if (xl < f)
+ return -1;
+ d = B * (d - f);
+ }
+ }
+ return - (d > 0.0);
+}
+
+int
+mpz_cmp_d (const mpz_t x, double d)
+{
+ if (x->_mp_size < 0)
+ {
+ if (d >= 0.0)
+ return -1;
+ else
+ return -mpz_cmpabs_d (x, d);
+ }
+ else
+ {
+ if (d < 0.0)
+ return 1;
+ else
+ return mpz_cmpabs_d (x, d);
+ }
+}
+
+
+/* MPZ comparisons and the like. */
+int
+mpz_sgn (const mpz_t u)
+{
+ mp_size_t usize = u->_mp_size;
+
+ return (usize > 0) - (usize < 0);
+}
+
+int
+mpz_cmp_si (const mpz_t u, long v)
+{
+ mp_size_t usize = u->_mp_size;
+
+ if (usize < -1)
+ return -1;
+ else if (v >= 0)
+ return mpz_cmp_ui (u, v);
+ else if (usize >= 0)
+ return 1;
+ else /* usize == -1 */
+ {
+ mp_limb_t ul = u->_mp_d[0];
+ if ((mp_limb_t)GMP_NEG_CAST (unsigned long int, v) < ul)
+ return -1;
+ else
+ return (mp_limb_t)GMP_NEG_CAST (unsigned long int, v) > ul;
+ }
+}
+
+int
+mpz_cmp_ui (const mpz_t u, unsigned long v)
+{
+ mp_size_t usize = u->_mp_size;
+
+ if (usize > 1)
+ return 1;
+ else if (usize < 0)
+ return -1;
+ else
+ {
+ mp_limb_t ul = (usize > 0) ? u->_mp_d[0] : 0;
+ return (ul > v) - (ul < v);
+ }
+}
+
+int
+mpz_cmp (const mpz_t a, const mpz_t b)
+{
+ mp_size_t asize = a->_mp_size;
+ mp_size_t bsize = b->_mp_size;
+
+ if (asize != bsize)
+ return (asize < bsize) ? -1 : 1;
+ else if (asize >= 0)
+ return mpn_cmp (a->_mp_d, b->_mp_d, asize);
+ else
+ return mpn_cmp (b->_mp_d, a->_mp_d, -asize);
+}
+
+int
+mpz_cmpabs_ui (const mpz_t u, unsigned long v)
+{
+ mp_size_t un = GMP_ABS (u->_mp_size);
+ mp_limb_t ul;
+
+ if (un > 1)
+ return 1;
+
+ ul = (un == 1) ? u->_mp_d[0] : 0;
+
+ return (ul > v) - (ul < v);
+}
+
+int
+mpz_cmpabs (const mpz_t u, const mpz_t v)
+{
+ return mpn_cmp4 (u->_mp_d, GMP_ABS (u->_mp_size),
+ v->_mp_d, GMP_ABS (v->_mp_size));
+}
+
+void
+mpz_abs (mpz_t r, const mpz_t u)
+{
+ if (r != u)
+ mpz_set (r, u);
+
+ r->_mp_size = GMP_ABS (r->_mp_size);
+}
+
+void
+mpz_neg (mpz_t r, const mpz_t u)
+{
+ if (r != u)
+ mpz_set (r, u);
+
+ r->_mp_size = -r->_mp_size;
+}
+
+void
+mpz_swap (mpz_t u, mpz_t v)
+{
+ MP_SIZE_T_SWAP (u->_mp_size, v->_mp_size);
+ MP_SIZE_T_SWAP (u->_mp_alloc, v->_mp_alloc);
+ MP_PTR_SWAP (u->_mp_d, v->_mp_d);
+}
+
+
+/* MPZ addition and subtraction */
+
+/* Adds to the absolute value. Returns new size, but doesn't store it. */
+static mp_size_t
+mpz_abs_add_ui (mpz_t r, const mpz_t a, unsigned long b)
+{
+ mp_size_t an;
+ mp_ptr rp;
+ mp_limb_t cy;
+
+ an = GMP_ABS (a->_mp_size);
+ if (an == 0)
+ {
+ r->_mp_d[0] = b;
+ return b > 0;
+ }
+
+ rp = MPZ_REALLOC (r, an + 1);
+
+ cy = mpn_add_1 (rp, a->_mp_d, an, b);
+ rp[an] = cy;
+ an += cy;
+
+ return an;
+}
+
+/* Subtract from the absolute value. Returns new size, (or -1 on underflow),
+ but doesn't store it. */
+static mp_size_t
+mpz_abs_sub_ui (mpz_t r, const mpz_t a, unsigned long b)
+{
+ mp_size_t an = GMP_ABS (a->_mp_size);
+ mp_ptr rp = MPZ_REALLOC (r, an);
+
+ if (an == 0)
+ {
+ rp[0] = b;
+ return -(b > 0);
+ }
+ else if (an == 1 && a->_mp_d[0] < b)
+ {
+ rp[0] = b - a->_mp_d[0];
+ return -1;
+ }
+ else
+ {
+ gmp_assert_nocarry (mpn_sub_1 (rp, a->_mp_d, an, b));
+ return mpn_normalized_size (rp, an);
+ }
+}
+
+void
+mpz_add_ui (mpz_t r, const mpz_t a, unsigned long b)
+{
+ if (a->_mp_size >= 0)
+ r->_mp_size = mpz_abs_add_ui (r, a, b);
+ else
+ r->_mp_size = -mpz_abs_sub_ui (r, a, b);
+}
+
+void
+mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b)
+{
+ if (a->_mp_size < 0)
+ r->_mp_size = -mpz_abs_add_ui (r, a, b);
+ else
+ r->_mp_size = mpz_abs_sub_ui (r, a, b);
+}
+
+void
+mpz_ui_sub (mpz_t r, unsigned long a, const mpz_t b)
+{
+ if (b->_mp_size < 0)
+ r->_mp_size = mpz_abs_add_ui (r, b, a);
+ else
+ r->_mp_size = -mpz_abs_sub_ui (r, b, a);
+}
+
+static mp_size_t
+mpz_abs_add (mpz_t r, const mpz_t a, const mpz_t b)
+{
+ mp_size_t an = GMP_ABS (a->_mp_size);
+ mp_size_t bn = GMP_ABS (b->_mp_size);
+ mp_ptr rp;
+ mp_limb_t cy;
+
+ if (an < bn)
+ {
+ MPZ_SRCPTR_SWAP (a, b);
+ MP_SIZE_T_SWAP (an, bn);
+ }
+
+ rp = MPZ_REALLOC (r, an + 1);
+ cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn);
+
+ rp[an] = cy;
+
+ return an + cy;
+}
+
+static mp_size_t
+mpz_abs_sub (mpz_t r, const mpz_t a, const mpz_t b)
+{
+ mp_size_t an = GMP_ABS (a->_mp_size);
+ mp_size_t bn = GMP_ABS (b->_mp_size);
+ int cmp;
+ mp_ptr rp;
+
+ cmp = mpn_cmp4 (a->_mp_d, an, b->_mp_d, bn);
+ if (cmp > 0)
+ {
+ rp = MPZ_REALLOC (r, an);
+ gmp_assert_nocarry (mpn_sub (rp, a->_mp_d, an, b->_mp_d, bn));
+ return mpn_normalized_size (rp, an);
+ }
+ else if (cmp < 0)
+ {
+ rp = MPZ_REALLOC (r, bn);
+ gmp_assert_nocarry (mpn_sub (rp, b->_mp_d, bn, a->_mp_d, an));
+ return -mpn_normalized_size (rp, bn);
+ }
+ else
+ return 0;
+}
+
+void
+mpz_add (mpz_t r, const mpz_t a, const mpz_t b)
+{
+ mp_size_t rn;
+
+ if ( (a->_mp_size ^ b->_mp_size) >= 0)
+ rn = mpz_abs_add (r, a, b);
+ else
+ rn = mpz_abs_sub (r, a, b);
+
+ r->_mp_size = a->_mp_size >= 0 ? rn : - rn;
+}
+
+void
+mpz_sub (mpz_t r, const mpz_t a, const mpz_t b)
+{
+ mp_size_t rn;
+
+ if ( (a->_mp_size ^ b->_mp_size) >= 0)
+ rn = mpz_abs_sub (r, a, b);
+ else
+ rn = mpz_abs_add (r, a, b);
+
+ r->_mp_size = a->_mp_size >= 0 ? rn : - rn;
+}
+
+
+/* MPZ multiplication */
+void
+mpz_mul_si (mpz_t r, const mpz_t u, long int v)
+{
+ if (v < 0)
+ {
+ mpz_mul_ui (r, u, GMP_NEG_CAST (unsigned long int, v));
+ mpz_neg (r, r);
+ }
+ else
+ mpz_mul_ui (r, u, (unsigned long int) v);
+}
+
+void
+mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v)
+{
+ mp_size_t un, us;
+ mp_ptr tp;
+ mp_limb_t cy;
+
+ us = u->_mp_size;
+
+ if (us == 0 || v == 0)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+
+ un = GMP_ABS (us);
+
+ tp = MPZ_REALLOC (r, un + 1);
+ cy = mpn_mul_1 (tp, u->_mp_d, un, v);
+ tp[un] = cy;
+
+ un += (cy > 0);
+ r->_mp_size = (us < 0) ? - un : un;
+}
+
+void
+mpz_mul (mpz_t r, const mpz_t u, const mpz_t v)
+{
+ int sign;
+ mp_size_t un, vn, rn;
+ mpz_t t;
+ mp_ptr tp;
+
+ un = u->_mp_size;
+ vn = v->_mp_size;
+
+ if (un == 0 || vn == 0)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+
+ sign = (un ^ vn) < 0;
+
+ un = GMP_ABS (un);
+ vn = GMP_ABS (vn);
+
+ mpz_init2 (t, (un + vn) * GMP_LIMB_BITS);
+
+ tp = t->_mp_d;
+ if (un >= vn)
+ mpn_mul (tp, u->_mp_d, un, v->_mp_d, vn);
+ else
+ mpn_mul (tp, v->_mp_d, vn, u->_mp_d, un);
+
+ rn = un + vn;
+ rn -= tp[rn-1] == 0;
+
+ t->_mp_size = sign ? - rn : rn;
+ mpz_swap (r, t);
+ mpz_clear (t);
+}
+
+void
+mpz_mul_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bits)
+{
+ mp_size_t un, rn;
+ mp_size_t limbs;
+ unsigned shift;
+ mp_ptr rp;
+
+ un = GMP_ABS (u->_mp_size);
+ if (un == 0)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+
+ limbs = bits / GMP_LIMB_BITS;
+ shift = bits % GMP_LIMB_BITS;
+
+ rn = un + limbs + (shift > 0);
+ rp = MPZ_REALLOC (r, rn);
+ if (shift > 0)
+ {
+ mp_limb_t cy = mpn_lshift (rp + limbs, u->_mp_d, un, shift);
+ rp[rn-1] = cy;
+ rn -= (cy == 0);
+ }
+ else
+ mpn_copyd (rp + limbs, u->_mp_d, un);
+
+ while (limbs > 0)
+ rp[--limbs] = 0;
+
+ r->_mp_size = (u->_mp_size < 0) ? - rn : rn;
+}
+
+void
+mpz_addmul_ui (mpz_t r, const mpz_t u, unsigned long int v)
+{
+ mpz_t t;
+ mpz_init (t);
+ mpz_mul_ui (t, u, v);
+ mpz_add (r, r, t);
+ mpz_clear (t);
+}
+
+void
+mpz_submul_ui (mpz_t r, const mpz_t u, unsigned long int v)
+{
+ mpz_t t;
+ mpz_init (t);
+ mpz_mul_ui (t, u, v);
+ mpz_sub (r, r, t);
+ mpz_clear (t);
+}
+
+void
+mpz_addmul (mpz_t r, const mpz_t u, const mpz_t v)
+{
+ mpz_t t;
+ mpz_init (t);
+ mpz_mul (t, u, v);
+ mpz_add (r, r, t);
+ mpz_clear (t);
+}
+
+void
+mpz_submul (mpz_t r, const mpz_t u, const mpz_t v)
+{
+ mpz_t t;
+ mpz_init (t);
+ mpz_mul (t, u, v);
+ mpz_sub (r, r, t);
+ mpz_clear (t);
+}
+
+
+/* MPZ division */
+enum mpz_div_round_mode { GMP_DIV_FLOOR, GMP_DIV_CEIL, GMP_DIV_TRUNC };
+
+/* Allows q or r to be zero. Returns 1 iff remainder is non-zero. */
+static int
+mpz_div_qr (mpz_t q, mpz_t r,
+ const mpz_t n, const mpz_t d, enum mpz_div_round_mode mode)
+{
+ mp_size_t ns, ds, nn, dn, qs;
+ ns = n->_mp_size;
+ ds = d->_mp_size;
+
+ if (ds == 0)
+ gmp_die("mpz_div_qr: Divide by zero.");
+
+ if (ns == 0)
+ {
+ if (q)
+ q->_mp_size = 0;
+ if (r)
+ r->_mp_size = 0;
+ return 0;
+ }
+
+ nn = GMP_ABS (ns);
+ dn = GMP_ABS (ds);
+
+ qs = ds ^ ns;
+
+ if (nn < dn)
+ {
+ if (mode == GMP_DIV_CEIL && qs >= 0)
+ {
+ /* q = 1, r = n - d */
+ if (r)
+ mpz_sub (r, n, d);
+ if (q)
+ mpz_set_ui (q, 1);
+ }
+ else if (mode == GMP_DIV_FLOOR && qs < 0)
+ {
+ /* q = -1, r = n + d */
+ if (r)
+ mpz_add (r, n, d);
+ if (q)
+ mpz_set_si (q, -1);
+ }
+ else
+ {
+ /* q = 0, r = d */
+ if (r)
+ mpz_set (r, n);
+ if (q)
+ q->_mp_size = 0;
+ }
+ return 1;
+ }
+ else
+ {
+ mp_ptr np, qp;
+ mp_size_t qn, rn;
+ mpz_t tq, tr;
+
+ mpz_init_set (tr, n);
+ np = tr->_mp_d;
+
+ qn = nn - dn + 1;
+
+ if (q)
+ {
+ mpz_init2 (tq, qn * GMP_LIMB_BITS);
+ qp = tq->_mp_d;
+ }
+ else
+ qp = NULL;
+
+ mpn_div_qr (qp, np, nn, d->_mp_d, dn);
+
+ if (qp)
+ {
+ qn -= (qp[qn-1] == 0);
+
+ tq->_mp_size = qs < 0 ? -qn : qn;
+ }
+ rn = mpn_normalized_size (np, dn);
+ tr->_mp_size = ns < 0 ? - rn : rn;
+
+ if (mode == GMP_DIV_FLOOR && qs < 0 && rn != 0)
+ {
+ if (q)
+ mpz_sub_ui (tq, tq, 1);
+ if (r)
+ mpz_add (tr, tr, d);
+ }
+ else if (mode == GMP_DIV_CEIL && qs >= 0 && rn != 0)
+ {
+ if (q)
+ mpz_add_ui (tq, tq, 1);
+ if (r)
+ mpz_sub (tr, tr, d);
+ }
+
+ if (q)
+ {
+ mpz_swap (tq, q);
+ mpz_clear (tq);
+ }
+ if (r)
+ mpz_swap (tr, r);
+
+ mpz_clear (tr);
+
+ return rn != 0;
+ }
+}
+
+void
+mpz_cdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (q, r, n, d, GMP_DIV_CEIL);
+}
+
+void
+mpz_fdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (q, r, n, d, GMP_DIV_FLOOR);
+}
+
+void
+mpz_tdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (q, r, n, d, GMP_DIV_TRUNC);
+}
+
+void
+mpz_cdiv_q (mpz_t q, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (q, NULL, n, d, GMP_DIV_CEIL);
+}
+
+void
+mpz_fdiv_q (mpz_t q, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (q, NULL, n, d, GMP_DIV_FLOOR);
+}
+
+void
+mpz_tdiv_q (mpz_t q, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC);
+}
+
+void
+mpz_cdiv_r (mpz_t r, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (NULL, r, n, d, GMP_DIV_CEIL);
+}
+
+void
+mpz_fdiv_r (mpz_t r, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (NULL, r, n, d, GMP_DIV_FLOOR);
+}
+
+void
+mpz_tdiv_r (mpz_t r, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (NULL, r, n, d, GMP_DIV_TRUNC);
+}
+
+void
+mpz_mod (mpz_t r, const mpz_t n, const mpz_t d)
+{
+ mpz_div_qr (NULL, r, n, d, d->_mp_size >= 0 ? GMP_DIV_FLOOR : GMP_DIV_CEIL);
+}
+
+static void
+mpz_div_q_2exp (mpz_t q, const mpz_t u, mp_bitcnt_t bit_index,
+ enum mpz_div_round_mode mode)
+{
+ mp_size_t un, qn;
+ mp_size_t limb_cnt;
+ mp_ptr qp;
+ int adjust;
+
+ un = u->_mp_size;
+ if (un == 0)
+ {
+ q->_mp_size = 0;
+ return;
+ }
+ limb_cnt = bit_index / GMP_LIMB_BITS;
+ qn = GMP_ABS (un) - limb_cnt;
+ bit_index %= GMP_LIMB_BITS;
+
+ if (mode == ((un > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* un != 0 here. */
+ /* Note: Below, the final indexing at limb_cnt is valid because at
+ that point we have qn > 0. */
+ adjust = (qn <= 0
+ || !mpn_zero_p (u->_mp_d, limb_cnt)
+ || (u->_mp_d[limb_cnt]
+ & (((mp_limb_t) 1 << bit_index) - 1)));
+ else
+ adjust = 0;
+
+ if (qn <= 0)
+ qn = 0;
+
+ else
+ {
+ qp = MPZ_REALLOC (q, qn);
+
+ if (bit_index != 0)
+ {
+ mpn_rshift (qp, u->_mp_d + limb_cnt, qn, bit_index);
+ qn -= qp[qn - 1] == 0;
+ }
+ else
+ {
+ mpn_copyi (qp, u->_mp_d + limb_cnt, qn);
+ }
+ }
+
+ q->_mp_size = qn;
+
+ if (adjust)
+ mpz_add_ui (q, q, 1);
+ if (un < 0)
+ mpz_neg (q, q);
+}
+
+static void
+mpz_div_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bit_index,
+ enum mpz_div_round_mode mode)
+{
+ mp_size_t us, un, rn;
+ mp_ptr rp;
+ mp_limb_t mask;
+
+ us = u->_mp_size;
+ if (us == 0 || bit_index == 0)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+ rn = (bit_index + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
+ assert (rn > 0);
+
+ rp = MPZ_REALLOC (r, rn);
+ un = GMP_ABS (us);
+
+ mask = GMP_LIMB_MAX >> (rn * GMP_LIMB_BITS - bit_index);
+
+ if (rn > un)
+ {
+ /* Quotient (with truncation) is zero, and remainder is
+ non-zero */
+ if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */
+ {
+ /* Have to negate and sign extend. */
+ mp_size_t i;
+ mp_limb_t cy;
+
+ for (cy = 1, i = 0; i < un; i++)
+ {
+ mp_limb_t s = ~u->_mp_d[i] + cy;
+ cy = s < cy;
+ rp[i] = s;
+ }
+ assert (cy == 0);
+ for (; i < rn - 1; i++)
+ rp[i] = GMP_LIMB_MAX;
+
+ rp[rn-1] = mask;
+ us = -us;
+ }
+ else
+ {
+ /* Just copy */
+ if (r != u)
+ mpn_copyi (rp, u->_mp_d, un);
+
+ rn = un;
+ }
+ }
+ else
+ {
+ if (r != u)
+ mpn_copyi (rp, u->_mp_d, rn - 1);
+
+ rp[rn-1] = u->_mp_d[rn-1] & mask;
+
+ if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */
+ {
+ /* If r != 0, compute 2^{bit_count} - r. */
+ mp_size_t i;
+
+ for (i = 0; i < rn && rp[i] == 0; i++)
+ ;
+ if (i < rn)
+ {
+ /* r > 0, need to flip sign. */
+ rp[i] = ~rp[i] + 1;
+ while (++i < rn)
+ rp[i] = ~rp[i];
+
+ rp[rn-1] &= mask;
+
+ /* us is not used for anything else, so we can modify it
+ here to indicate flipped sign. */
+ us = -us;
+ }
+ }
+ }
+ rn = mpn_normalized_size (rp, rn);
+ r->_mp_size = us < 0 ? -rn : rn;
+}
+
+void
+mpz_cdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
+{
+ mpz_div_q_2exp (r, u, cnt, GMP_DIV_CEIL);
+}
+
+void
+mpz_fdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
+{
+ mpz_div_q_2exp (r, u, cnt, GMP_DIV_FLOOR);
+}
+
+void
+mpz_tdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
+{
+ mpz_div_q_2exp (r, u, cnt, GMP_DIV_TRUNC);
+}
+
+void
+mpz_cdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
+{
+ mpz_div_r_2exp (r, u, cnt, GMP_DIV_CEIL);
+}
+
+void
+mpz_fdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
+{
+ mpz_div_r_2exp (r, u, cnt, GMP_DIV_FLOOR);
+}
+
+void
+mpz_tdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
+{
+ mpz_div_r_2exp (r, u, cnt, GMP_DIV_TRUNC);
+}
+
+void
+mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d)
+{
+ gmp_assert_nocarry (mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC));
+}
+
+int
+mpz_divisible_p (const mpz_t n, const mpz_t d)
+{
+ return mpz_div_qr (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0;
+}
+
+int
+mpz_congruent_p (const mpz_t a, const mpz_t b, const mpz_t m)
+{
+ mpz_t t;
+ int res;
+
+ /* a == b (mod 0) iff a == b */
+ if (mpz_sgn (m) == 0)
+ return (mpz_cmp (a, b) == 0);
+
+ mpz_init (t);
+ mpz_sub (t, a, b);
+ res = mpz_divisible_p (t, m);
+ mpz_clear (t);
+
+ return res;
+}
+
+static unsigned long
+mpz_div_qr_ui (mpz_t q, mpz_t r,
+ const mpz_t n, unsigned long d, enum mpz_div_round_mode mode)
+{
+ mp_size_t ns, qn;
+ mp_ptr qp;
+ mp_limb_t rl;
+ mp_size_t rs;
+
+ ns = n->_mp_size;
+ if (ns == 0)
+ {
+ if (q)
+ q->_mp_size = 0;
+ if (r)
+ r->_mp_size = 0;
+ return 0;
+ }
+
+ qn = GMP_ABS (ns);
+ if (q)
+ qp = MPZ_REALLOC (q, qn);
+ else
+ qp = NULL;
+
+ rl = mpn_div_qr_1 (qp, n->_mp_d, qn, d);
+ assert (rl < d);
+
+ rs = rl > 0;
+ rs = (ns < 0) ? -rs : rs;
+
+ if (rl > 0 && ( (mode == GMP_DIV_FLOOR && ns < 0)
+ || (mode == GMP_DIV_CEIL && ns >= 0)))
+ {
+ if (q)
+ gmp_assert_nocarry (mpn_add_1 (qp, qp, qn, 1));
+ rl = d - rl;
+ rs = -rs;
+ }
+
+ if (r)
+ {
+ r->_mp_d[0] = rl;
+ r->_mp_size = rs;
+ }
+ if (q)
+ {
+ qn -= (qp[qn-1] == 0);
+ assert (qn == 0 || qp[qn-1] > 0);
+
+ q->_mp_size = (ns < 0) ? - qn : qn;
+ }
+
+ return rl;
+}
+
+unsigned long
+mpz_cdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (q, r, n, d, GMP_DIV_CEIL);
+}
+
+unsigned long
+mpz_fdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (q, r, n, d, GMP_DIV_FLOOR);
+}
+
+unsigned long
+mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (q, r, n, d, GMP_DIV_TRUNC);
+}
+
+unsigned long
+mpz_cdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_CEIL);
+}
+
+unsigned long
+mpz_fdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_FLOOR);
+}
+
+unsigned long
+mpz_tdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC);
+}
+
+unsigned long
+mpz_cdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_CEIL);
+}
+unsigned long
+mpz_fdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR);
+}
+unsigned long
+mpz_tdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_TRUNC);
+}
+
+unsigned long
+mpz_cdiv_ui (const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_CEIL);
+}
+
+unsigned long
+mpz_fdiv_ui (const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_FLOOR);
+}
+
+unsigned long
+mpz_tdiv_ui (const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC);
+}
+
+unsigned long
+mpz_mod_ui (mpz_t r, const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR);
+}
+
+void
+mpz_divexact_ui (mpz_t q, const mpz_t n, unsigned long d)
+{
+ gmp_assert_nocarry (mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC));
+}
+
+int
+mpz_divisible_ui_p (const mpz_t n, unsigned long d)
+{
+ return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0;
+}
+
+
+/* GCD */
+static mp_limb_t
+mpn_gcd_11 (mp_limb_t u, mp_limb_t v)
+{
+ unsigned shift;
+
+ assert ( (u | v) > 0);
+
+ if (u == 0)
+ return v;
+ else if (v == 0)
+ return u;
+
+ gmp_ctz (shift, u | v);
+
+ u >>= shift;
+ v >>= shift;
+
+ if ( (u & 1) == 0)
+ MP_LIMB_T_SWAP (u, v);
+
+ while ( (v & 1) == 0)
+ v >>= 1;
+
+ while (u != v)
+ {
+ if (u > v)
+ {
+ u -= v;
+ do
+ u >>= 1;
+ while ( (u & 1) == 0);
+ }
+ else
+ {
+ v -= u;
+ do
+ v >>= 1;
+ while ( (v & 1) == 0);
+ }
+ }
+ return u << shift;
+}
+
+unsigned long
+mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v)
+{
+ mp_size_t un;
+
+ if (v == 0)
+ {
+ if (g)
+ mpz_abs (g, u);
+ }
+ else
+ {
+ un = GMP_ABS (u->_mp_size);
+ if (un != 0)
+ v = mpn_gcd_11 (mpn_div_qr_1 (NULL, u->_mp_d, un, v), v);
+
+ if (g)
+ mpz_set_ui (g, v);
+ }
+
+ return v;
+}
+
+static mp_bitcnt_t
+mpz_make_odd (mpz_t r)
+{
+ mp_bitcnt_t shift;
+
+ assert (r->_mp_size > 0);
+ /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */
+ shift = mpn_common_scan (r->_mp_d[0], 0, r->_mp_d, 0, 0);
+ mpz_tdiv_q_2exp (r, r, shift);
+
+ return shift;
+}
+
+void
+mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v)
+{
+ mpz_t tu, tv;
+ mp_bitcnt_t uz, vz, gz;
+
+ if (u->_mp_size == 0)
+ {
+ mpz_abs (g, v);
+ return;
+ }
+ if (v->_mp_size == 0)
+ {
+ mpz_abs (g, u);
+ return;
+ }
+
+ mpz_init (tu);
+ mpz_init (tv);
+
+ mpz_abs (tu, u);
+ uz = mpz_make_odd (tu);
+ mpz_abs (tv, v);
+ vz = mpz_make_odd (tv);
+ gz = GMP_MIN (uz, vz);
+
+ if (tu->_mp_size < tv->_mp_size)
+ mpz_swap (tu, tv);
+
+ mpz_tdiv_r (tu, tu, tv);
+ if (tu->_mp_size == 0)
+ {
+ mpz_swap (g, tv);
+ }
+ else
+ for (;;)
+ {
+ int c;
+
+ mpz_make_odd (tu);
+ c = mpz_cmp (tu, tv);
+ if (c == 0)
+ {
+ mpz_swap (g, tu);
+ break;
+ }
+ if (c < 0)
+ mpz_swap (tu, tv);
+
+ if (tv->_mp_size == 1)
+ {
+ mp_limb_t vl = tv->_mp_d[0];
+ mp_limb_t ul = mpz_tdiv_ui (tu, vl);
+ mpz_set_ui (g, mpn_gcd_11 (ul, vl));
+ break;
+ }
+ mpz_sub (tu, tu, tv);
+ }
+ mpz_clear (tu);
+ mpz_clear (tv);
+ mpz_mul_2exp (g, g, gz);
+}
+
+void
+mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
+{
+ mpz_t tu, tv, s0, s1, t0, t1;
+ mp_bitcnt_t uz, vz, gz;
+ mp_bitcnt_t power;
+
+ if (u->_mp_size == 0)
+ {
+ /* g = 0 u + sgn(v) v */
+ signed long sign = mpz_sgn (v);
+ mpz_abs (g, v);
+ if (s)
+ mpz_set_ui (s, 0);
+ if (t)
+ mpz_set_si (t, sign);
+ return;
+ }
+
+ if (v->_mp_size == 0)
+ {
+ /* g = sgn(u) u + 0 v */
+ signed long sign = mpz_sgn (u);
+ mpz_abs (g, u);
+ if (s)
+ mpz_set_si (s, sign);
+ if (t)
+ mpz_set_ui (t, 0);
+ return;
+ }
+
+ mpz_init (tu);
+ mpz_init (tv);
+ mpz_init (s0);
+ mpz_init (s1);
+ mpz_init (t0);
+ mpz_init (t1);
+
+ mpz_abs (tu, u);
+ uz = mpz_make_odd (tu);
+ mpz_abs (tv, v);
+ vz = mpz_make_odd (tv);
+ gz = GMP_MIN (uz, vz);
+
+ uz -= gz;
+ vz -= gz;
+
+ /* Cofactors corresponding to odd gcd. gz handled later. */
+ if (tu->_mp_size < tv->_mp_size)
+ {
+ mpz_swap (tu, tv);
+ MPZ_SRCPTR_SWAP (u, v);
+ MPZ_PTR_SWAP (s, t);
+ MP_BITCNT_T_SWAP (uz, vz);
+ }
+
+ /* Maintain
+ *
+ * u = t0 tu + t1 tv
+ * v = s0 tu + s1 tv
+ *
+ * where u and v denote the inputs with common factors of two
+ * eliminated, and det (s0, t0; s1, t1) = 2^p. Then
+ *
+ * 2^p tu = s1 u - t1 v
+ * 2^p tv = -s0 u + t0 v
+ */
+
+ /* After initial division, tu = q tv + tu', we have
+ *
+ * u = 2^uz (tu' + q tv)
+ * v = 2^vz tv
+ *
+ * or
+ *
+ * t0 = 2^uz, t1 = 2^uz q
+ * s0 = 0, s1 = 2^vz
+ */
+
+ mpz_setbit (t0, uz);
+ mpz_tdiv_qr (t1, tu, tu, tv);
+ mpz_mul_2exp (t1, t1, uz);
+
+ mpz_setbit (s1, vz);
+ power = uz + vz;
+
+ if (tu->_mp_size > 0)
+ {
+ mp_bitcnt_t shift;
+ shift = mpz_make_odd (tu);
+ mpz_mul_2exp (t0, t0, shift);
+ mpz_mul_2exp (s0, s0, shift);
+ power += shift;
+
+ for (;;)
+ {
+ int c;
+ c = mpz_cmp (tu, tv);
+ if (c == 0)
+ break;
+
+ if (c < 0)
+ {
+ /* tv = tv' + tu
+ *
+ * u = t0 tu + t1 (tv' + tu) = (t0 + t1) tu + t1 tv'
+ * v = s0 tu + s1 (tv' + tu) = (s0 + s1) tu + s1 tv' */
+
+ mpz_sub (tv, tv, tu);
+ mpz_add (t0, t0, t1);
+ mpz_add (s0, s0, s1);
+
+ shift = mpz_make_odd (tv);
+ mpz_mul_2exp (t1, t1, shift);
+ mpz_mul_2exp (s1, s1, shift);
+ }
+ else
+ {
+ mpz_sub (tu, tu, tv);
+ mpz_add (t1, t0, t1);
+ mpz_add (s1, s0, s1);
+
+ shift = mpz_make_odd (tu);
+ mpz_mul_2exp (t0, t0, shift);
+ mpz_mul_2exp (s0, s0, shift);
+ }
+ power += shift;
+ }
+ }
+
+ /* Now tv = odd part of gcd, and -s0 and t0 are corresponding
+ cofactors. */
+
+ mpz_mul_2exp (tv, tv, gz);
+ mpz_neg (s0, s0);
+
+ /* 2^p g = s0 u + t0 v. Eliminate one factor of two at a time. To
+ adjust cofactors, we need u / g and v / g */
+
+ mpz_divexact (s1, v, tv);
+ mpz_abs (s1, s1);
+ mpz_divexact (t1, u, tv);
+ mpz_abs (t1, t1);
+
+ while (power-- > 0)
+ {
+ /* s0 u + t0 v = (s0 - v/g) u - (t0 + u/g) v */
+ if (mpz_odd_p (s0) || mpz_odd_p (t0))
+ {
+ mpz_sub (s0, s0, s1);
+ mpz_add (t0, t0, t1);
+ }
+ mpz_divexact_ui (s0, s0, 2);
+ mpz_divexact_ui (t0, t0, 2);
+ }
+
+ /* Arrange so that |s| < |u| / 2g */
+ mpz_add (s1, s0, s1);
+ if (mpz_cmpabs (s0, s1) > 0)
+ {
+ mpz_swap (s0, s1);
+ mpz_sub (t0, t0, t1);
+ }
+ if (u->_mp_size < 0)
+ mpz_neg (s0, s0);
+ if (v->_mp_size < 0)
+ mpz_neg (t0, t0);
+
+ mpz_swap (g, tv);
+ if (s)
+ mpz_swap (s, s0);
+ if (t)
+ mpz_swap (t, t0);
+
+ mpz_clear (tu);
+ mpz_clear (tv);
+ mpz_clear (s0);
+ mpz_clear (s1);
+ mpz_clear (t0);
+ mpz_clear (t1);
+}
+
+void
+mpz_lcm (mpz_t r, const mpz_t u, const mpz_t v)
+{
+ mpz_t g;
+
+ if (u->_mp_size == 0 || v->_mp_size == 0)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+
+ mpz_init (g);
+
+ mpz_gcd (g, u, v);
+ mpz_divexact (g, u, g);
+ mpz_mul (r, g, v);
+
+ mpz_clear (g);
+ mpz_abs (r, r);
+}
+
+void
+mpz_lcm_ui (mpz_t r, const mpz_t u, unsigned long v)
+{
+ if (v == 0 || u->_mp_size == 0)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+
+ v /= mpz_gcd_ui (NULL, u, v);
+ mpz_mul_ui (r, u, v);
+
+ mpz_abs (r, r);
+}
+
+int
+mpz_invert (mpz_t r, const mpz_t u, const mpz_t m)
+{
+ mpz_t g, tr;
+ int invertible;
+
+ if (u->_mp_size == 0 || mpz_cmpabs_ui (m, 1) <= 0)
+ return 0;
+
+ mpz_init (g);
+ mpz_init (tr);
+
+ mpz_gcdext (g, tr, NULL, u, m);
+ invertible = (mpz_cmp_ui (g, 1) == 0);
+
+ if (invertible)
+ {
+ if (tr->_mp_size < 0)
+ {
+ if (m->_mp_size >= 0)
+ mpz_add (tr, tr, m);
+ else
+ mpz_sub (tr, tr, m);
+ }
+ mpz_swap (r, tr);
+ }
+
+ mpz_clear (g);
+ mpz_clear (tr);
+ return invertible;
+}
+
+
+/* Higher level operations (sqrt, pow and root) */
+
+void
+mpz_pow_ui (mpz_t r, const mpz_t b, unsigned long e)
+{
+ unsigned long bit;
+ mpz_t tr;
+ mpz_init_set_ui (tr, 1);
+
+ bit = GMP_ULONG_HIGHBIT;
+ do
+ {
+ mpz_mul (tr, tr, tr);
+ if (e & bit)
+ mpz_mul (tr, tr, b);
+ bit >>= 1;
+ }
+ while (bit > 0);
+
+ mpz_swap (r, tr);
+ mpz_clear (tr);
+}
+
+void
+mpz_ui_pow_ui (mpz_t r, unsigned long blimb, unsigned long e)
+{
+ mpz_t b;
+ mpz_init_set_ui (b, blimb);
+ mpz_pow_ui (r, b, e);
+ mpz_clear (b);
+}
+
+void
+mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m)
+{
+ mpz_t tr;
+ mpz_t base;
+ mp_size_t en, mn;
+ mp_srcptr mp;
+ struct gmp_div_inverse minv;
+ unsigned shift;
+ mp_ptr tp = NULL;
+
+ en = GMP_ABS (e->_mp_size);
+ mn = GMP_ABS (m->_mp_size);
+ if (mn == 0)
+ gmp_die ("mpz_powm: Zero modulo.");
+
+ if (en == 0)
+ {
+ mpz_set_ui (r, 1);
+ return;
+ }
+
+ mp = m->_mp_d;
+ mpn_div_qr_invert (&minv, mp, mn);
+ shift = minv.shift;
+
+ if (shift > 0)
+ {
+ /* To avoid shifts, we do all our reductions, except the final
+ one, using a *normalized* m. */
+ minv.shift = 0;
+
+ tp = gmp_xalloc_limbs (mn);
+ gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift));
+ mp = tp;
+ }
+
+ mpz_init (base);
+
+ if (e->_mp_size < 0)
+ {
+ if (!mpz_invert (base, b, m))
+ gmp_die ("mpz_powm: Negative exponent and non-invertible base.");
+ }
+ else
+ {
+ mp_size_t bn;
+ mpz_abs (base, b);
+
+ bn = base->_mp_size;
+ if (bn >= mn)
+ {
+ mpn_div_qr_preinv (NULL, base->_mp_d, base->_mp_size, mp, mn, &minv);
+ bn = mn;
+ }
+
+ /* We have reduced the absolute value. Now take care of the
+ sign. Note that we get zero represented non-canonically as
+ m. */
+ if (b->_mp_size < 0)
+ {
+ mp_ptr bp = MPZ_REALLOC (base, mn);
+ gmp_assert_nocarry (mpn_sub (bp, mp, mn, bp, bn));
+ bn = mn;
+ }
+ base->_mp_size = mpn_normalized_size (base->_mp_d, bn);
+ }
+ mpz_init_set_ui (tr, 1);
+
+ while (en-- > 0)
+ {
+ mp_limb_t w = e->_mp_d[en];
+ mp_limb_t bit;
+
+ bit = GMP_LIMB_HIGHBIT;
+ do
+ {
+ mpz_mul (tr, tr, tr);
+ if (w & bit)
+ mpz_mul (tr, tr, base);
+ if (tr->_mp_size > mn)
+ {
+ mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv);
+ tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
+ }
+ bit >>= 1;
+ }
+ while (bit > 0);
+ }
+
+ /* Final reduction */
+ if (tr->_mp_size >= mn)
+ {
+ minv.shift = shift;
+ mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv);
+ tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
+ }
+ if (tp)
+ gmp_free (tp);
+
+ mpz_swap (r, tr);
+ mpz_clear (tr);
+ mpz_clear (base);
+}
+
+void
+mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m)
+{
+ mpz_t e;
+ mpz_init_set_ui (e, elimb);
+ mpz_powm (r, b, e, m);
+ mpz_clear (e);
+}
+
+/* x=trunc(y^(1/z)), r=y-x^z */
+void
+mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
+{
+ int sgn;
+ mpz_t t, u;
+
+ sgn = y->_mp_size < 0;
+ if ((~z & sgn) != 0)
+ gmp_die ("mpz_rootrem: Negative argument, with even root.");
+ if (z == 0)
+ gmp_die ("mpz_rootrem: Zeroth root.");
+
+ if (mpz_cmpabs_ui (y, 1) <= 0) {
+ if (x)
+ mpz_set (x, y);
+ if (r)
+ r->_mp_size = 0;
+ return;
+ }
+
+ mpz_init (u);
+ {
+ mp_bitcnt_t tb;
+ tb = mpz_sizeinbase (y, 2) / z + 1;
+ mpz_init2 (t, tb);
+ mpz_setbit (t, tb);
+ }
+
+ if (z == 2) /* simplify sqrt loop: z-1 == 1 */
+ do {
+ mpz_swap (u, t); /* u = x */
+ mpz_tdiv_q (t, y, u); /* t = y/x */
+ mpz_add (t, t, u); /* t = y/x + x */
+ mpz_tdiv_q_2exp (t, t, 1); /* x'= (y/x + x)/2 */
+ } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */
+ else /* z != 2 */ {
+ mpz_t v;
+
+ mpz_init (v);
+ if (sgn)
+ mpz_neg (t, t);
+
+ do {
+ mpz_swap (u, t); /* u = x */
+ mpz_pow_ui (t, u, z - 1); /* t = x^(z-1) */
+ mpz_tdiv_q (t, y, t); /* t = y/x^(z-1) */
+ mpz_mul_ui (v, u, z - 1); /* v = x*(z-1) */
+ mpz_add (t, t, v); /* t = y/x^(z-1) + x*(z-1) */
+ mpz_tdiv_q_ui (t, t, z); /* x'=(y/x^(z-1) + x*(z-1))/z */
+ } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */
+
+ mpz_clear (v);
+ }
+
+ if (r) {
+ mpz_pow_ui (t, u, z);
+ mpz_sub (r, y, t);
+ }
+ if (x)
+ mpz_swap (x, u);
+ mpz_clear (u);
+ mpz_clear (t);
+}
+
+int
+mpz_root (mpz_t x, const mpz_t y, unsigned long z)
+{
+ int res;
+ mpz_t r;
+
+ mpz_init (r);
+ mpz_rootrem (x, r, y, z);
+ res = r->_mp_size == 0;
+ mpz_clear (r);
+
+ return res;
+}
+
+/* Compute s = floor(sqrt(u)) and r = u - s^2. Allows r == NULL */
+void
+mpz_sqrtrem (mpz_t s, mpz_t r, const mpz_t u)
+{
+ mpz_rootrem (s, r, u, 2);
+}
+
+void
+mpz_sqrt (mpz_t s, const mpz_t u)
+{
+ mpz_rootrem (s, NULL, u, 2);
+}
+
+int
+mpz_perfect_square_p (const mpz_t u)
+{
+ if (u->_mp_size <= 0)
+ return (u->_mp_size == 0);
+ else
+ return mpz_root (NULL, u, 2);
+}
+
+int
+mpn_perfect_square_p (mp_srcptr p, mp_size_t n)
+{
+ mpz_t t;
+
+ assert (n > 0);
+ assert (p [n-1] != 0);
+ return mpz_root (NULL, mpz_roinit_n (t, p, n), 2);
+}
+
+mp_size_t
+mpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr p, mp_size_t n)
+{
+ mpz_t s, r, u;
+ mp_size_t res;
+
+ assert (n > 0);
+ assert (p [n-1] != 0);
+
+ mpz_init (r);
+ mpz_init (s);
+ mpz_rootrem (s, r, mpz_roinit_n (u, p, n), 2);
+
+ assert (s->_mp_size == (n+1)/2);
+ mpn_copyd (sp, s->_mp_d, s->_mp_size);
+ mpz_clear (s);
+ res = r->_mp_size;
+ if (rp)
+ mpn_copyd (rp, r->_mp_d, res);
+ mpz_clear (r);
+ return res;
+}
+
+/* Combinatorics */
+
+void
+mpz_fac_ui (mpz_t x, unsigned long n)
+{
+ mpz_set_ui (x, n + (n == 0));
+ for (;n > 2;)
+ mpz_mul_ui (x, x, --n);
+}
+
+void
+mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k)
+{
+ mpz_t t;
+
+ mpz_set_ui (r, k <= n);
+
+ if (k > (n >> 1))
+ k = (k <= n) ? n - k : 0;
+
+ mpz_init (t);
+ mpz_fac_ui (t, k);
+
+ for (; k > 0; k--)
+ mpz_mul_ui (r, r, n--);
+
+ mpz_divexact (r, r, t);
+ mpz_clear (t);
+}
+
+
+/* Primality testing */
+static int
+gmp_millerrabin (const mpz_t n, const mpz_t nm1, mpz_t y,
+ const mpz_t q, mp_bitcnt_t k)
+{
+ assert (k > 0);
+
+ /* Caller must initialize y to the base. */
+ mpz_powm (y, y, q, n);
+
+ if (mpz_cmp_ui (y, 1) == 0 || mpz_cmp (y, nm1) == 0)
+ return 1;
+
+ while (--k > 0)
+ {
+ mpz_powm_ui (y, y, 2, n);
+ if (mpz_cmp (y, nm1) == 0)
+ return 1;
+ /* y == 1 means that the previous y was a non-trivial square root
+ of 1 (mod n). y == 0 means that n is a power of the base.
+ In either case, n is not prime. */
+ if (mpz_cmp_ui (y, 1) <= 0)
+ return 0;
+ }
+ return 0;
+}
+
+/* This product is 0xc0cfd797, and fits in 32 bits. */
+#define GMP_PRIME_PRODUCT \
+ (3UL*5UL*7UL*11UL*13UL*17UL*19UL*23UL*29UL)
+
+/* Bit (p+1)/2 is set, for each odd prime <= 61 */
+#define GMP_PRIME_MASK 0xc96996dcUL
+
+int
+mpz_probab_prime_p (const mpz_t n, int reps)
+{
+ mpz_t nm1;
+ mpz_t q;
+ mpz_t y;
+ mp_bitcnt_t k;
+ int is_prime;
+ int j;
+
+ /* Note that we use the absolute value of n only, for compatibility
+ with the real GMP. */
+ if (mpz_even_p (n))
+ return (mpz_cmpabs_ui (n, 2) == 0) ? 2 : 0;
+
+ /* Above test excludes n == 0 */
+ assert (n->_mp_size != 0);
+
+ if (mpz_cmpabs_ui (n, 64) < 0)
+ return (GMP_PRIME_MASK >> (n->_mp_d[0] >> 1)) & 2;
+
+ if (mpz_gcd_ui (NULL, n, GMP_PRIME_PRODUCT) != 1)
+ return 0;
+
+ /* All prime factors are >= 31. */
+ if (mpz_cmpabs_ui (n, 31*31) < 0)
+ return 2;
+
+ /* Use Miller-Rabin, with a deterministic sequence of bases, a[j] =
+ j^2 + j + 41 using Euler's polynomial. We potentially stop early,
+ if a[j] >= n - 1. Since n >= 31*31, this can happen only if reps >
+ 30 (a[30] == 971 > 31*31 == 961). */
+
+ mpz_init (nm1);
+ mpz_init (q);
+ mpz_init (y);
+
+ /* Find q and k, where q is odd and n = 1 + 2**k * q. */
+ nm1->_mp_size = mpz_abs_sub_ui (nm1, n, 1);
+ k = mpz_scan1 (nm1, 0);
+ mpz_tdiv_q_2exp (q, nm1, k);
+
+ for (j = 0, is_prime = 1; is_prime & (j < reps); j++)
+ {
+ mpz_set_ui (y, (unsigned long) j*j+j+41);
+ if (mpz_cmp (y, nm1) >= 0)
+ {
+ /* Don't try any further bases. This "early" break does not affect
+ the result for any reasonable reps value (<=5000 was tested) */
+ assert (j >= 30);
+ break;
+ }
+ is_prime = gmp_millerrabin (n, nm1, y, q, k);
+ }
+ mpz_clear (nm1);
+ mpz_clear (q);
+ mpz_clear (y);
+
+ return is_prime;
+}
+
+
+/* Logical operations and bit manipulation. */
+
+/* Numbers are treated as if represented in two's complement (and
+ infinitely sign extended). For a negative values we get the two's
+ complement from -x = ~x + 1, where ~ is bitwise complement.
+ Negation transforms
+
+ xxxx10...0
+
+ into
+
+ yyyy10...0
+
+ where yyyy is the bitwise complement of xxxx. So least significant
+ bits, up to and including the first one bit, are unchanged, and
+ the more significant bits are all complemented.
+
+ To change a bit from zero to one in a negative number, subtract the
+ corresponding power of two from the absolute value. This can never
+ underflow. To change a bit from one to zero, add the corresponding
+ power of two, and this might overflow. E.g., if x = -001111, the
+ two's complement is 110001. Clearing the least significant bit, we
+ get two's complement 110000, and -010000. */
+
+int
+mpz_tstbit (const mpz_t d, mp_bitcnt_t bit_index)
+{
+ mp_size_t limb_index;
+ unsigned shift;
+ mp_size_t ds;
+ mp_size_t dn;
+ mp_limb_t w;
+ int bit;
+
+ ds = d->_mp_size;
+ dn = GMP_ABS (ds);
+ limb_index = bit_index / GMP_LIMB_BITS;
+ if (limb_index >= dn)
+ return ds < 0;
+
+ shift = bit_index % GMP_LIMB_BITS;
+ w = d->_mp_d[limb_index];
+ bit = (w >> shift) & 1;
+
+ if (ds < 0)
+ {
+ /* d < 0. Check if any of the bits below is set: If so, our bit
+ must be complemented. */
+ if (shift > 0 && (w << (GMP_LIMB_BITS - shift)) > 0)
+ return bit ^ 1;
+ while (limb_index-- > 0)
+ if (d->_mp_d[limb_index] > 0)
+ return bit ^ 1;
+ }
+ return bit;
+}
+
+static void
+mpz_abs_add_bit (mpz_t d, mp_bitcnt_t bit_index)
+{
+ mp_size_t dn, limb_index;
+ mp_limb_t bit;
+ mp_ptr dp;
+
+ dn = GMP_ABS (d->_mp_size);
+
+ limb_index = bit_index / GMP_LIMB_BITS;
+ bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS);
+
+ if (limb_index >= dn)
+ {
+ mp_size_t i;
+ /* The bit should be set outside of the end of the number.
+ We have to increase the size of the number. */
+ dp = MPZ_REALLOC (d, limb_index + 1);
+
+ dp[limb_index] = bit;
+ for (i = dn; i < limb_index; i++)
+ dp[i] = 0;
+ dn = limb_index + 1;
+ }
+ else
+ {
+ mp_limb_t cy;
+
+ dp = d->_mp_d;
+
+ cy = mpn_add_1 (dp + limb_index, dp + limb_index, dn - limb_index, bit);
+ if (cy > 0)
+ {
+ dp = MPZ_REALLOC (d, dn + 1);
+ dp[dn++] = cy;
+ }
+ }
+
+ d->_mp_size = (d->_mp_size < 0) ? - dn : dn;
+}
+
+static void
+mpz_abs_sub_bit (mpz_t d, mp_bitcnt_t bit_index)
+{
+ mp_size_t dn, limb_index;
+ mp_ptr dp;
+ mp_limb_t bit;
+
+ dn = GMP_ABS (d->_mp_size);
+ dp = d->_mp_d;
+
+ limb_index = bit_index / GMP_LIMB_BITS;
+ bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS);
+
+ assert (limb_index < dn);
+
+ gmp_assert_nocarry (mpn_sub_1 (dp + limb_index, dp + limb_index,
+ dn - limb_index, bit));
+ dn -= (dp[dn-1] == 0);
+ d->_mp_size = (d->_mp_size < 0) ? - dn : dn;
+}
+
+void
+mpz_setbit (mpz_t d, mp_bitcnt_t bit_index)
+{
+ if (!mpz_tstbit (d, bit_index))
+ {
+ if (d->_mp_size >= 0)
+ mpz_abs_add_bit (d, bit_index);
+ else
+ mpz_abs_sub_bit (d, bit_index);
+ }
+}
+
+void
+mpz_clrbit (mpz_t d, mp_bitcnt_t bit_index)
+{
+ if (mpz_tstbit (d, bit_index))
+ {
+ if (d->_mp_size >= 0)
+ mpz_abs_sub_bit (d, bit_index);
+ else
+ mpz_abs_add_bit (d, bit_index);
+ }
+}
+
+void
+mpz_combit (mpz_t d, mp_bitcnt_t bit_index)
+{
+ if (mpz_tstbit (d, bit_index) ^ (d->_mp_size < 0))
+ mpz_abs_sub_bit (d, bit_index);
+ else
+ mpz_abs_add_bit (d, bit_index);
+}
+
+void
+mpz_com (mpz_t r, const mpz_t u)
+{
+ mpz_neg (r, u);
+ mpz_sub_ui (r, r, 1);
+}
+
+void
+mpz_and (mpz_t r, const mpz_t u, const mpz_t v)
+{
+ mp_size_t un, vn, rn, i;
+ mp_ptr up, vp, rp;
+
+ mp_limb_t ux, vx, rx;
+ mp_limb_t uc, vc, rc;
+ mp_limb_t ul, vl, rl;
+
+ un = GMP_ABS (u->_mp_size);
+ vn = GMP_ABS (v->_mp_size);
+ if (un < vn)
+ {
+ MPZ_SRCPTR_SWAP (u, v);
+ MP_SIZE_T_SWAP (un, vn);
+ }
+ if (vn == 0)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+
+ uc = u->_mp_size < 0;
+ vc = v->_mp_size < 0;
+ rc = uc & vc;
+
+ ux = -uc;
+ vx = -vc;
+ rx = -rc;
+
+ /* If the smaller input is positive, higher limbs don't matter. */
+ rn = vx ? un : vn;
+
+ rp = MPZ_REALLOC (r, rn + rc);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ i = 0;
+ do
+ {
+ ul = (up[i] ^ ux) + uc;
+ uc = ul < uc;
+
+ vl = (vp[i] ^ vx) + vc;
+ vc = vl < vc;
+
+ rl = ( (ul & vl) ^ rx) + rc;
+ rc = rl < rc;
+ rp[i] = rl;
+ }
+ while (++i < vn);
+ assert (vc == 0);
+
+ for (; i < rn; i++)
+ {
+ ul = (up[i] ^ ux) + uc;
+ uc = ul < uc;
+
+ rl = ( (ul & vx) ^ rx) + rc;
+ rc = rl < rc;
+ rp[i] = rl;
+ }
+ if (rc)
+ rp[rn++] = rc;
+ else
+ rn = mpn_normalized_size (rp, rn);
+
+ r->_mp_size = rx ? -rn : rn;
+}
+
+void
+mpz_ior (mpz_t r, const mpz_t u, const mpz_t v)
+{
+ mp_size_t un, vn, rn, i;
+ mp_ptr up, vp, rp;
+
+ mp_limb_t ux, vx, rx;
+ mp_limb_t uc, vc, rc;
+ mp_limb_t ul, vl, rl;
+
+ un = GMP_ABS (u->_mp_size);
+ vn = GMP_ABS (v->_mp_size);
+ if (un < vn)
+ {
+ MPZ_SRCPTR_SWAP (u, v);
+ MP_SIZE_T_SWAP (un, vn);
+ }
+ if (vn == 0)
+ {
+ mpz_set (r, u);
+ return;
+ }
+
+ uc = u->_mp_size < 0;
+ vc = v->_mp_size < 0;
+ rc = uc | vc;
+
+ ux = -uc;
+ vx = -vc;
+ rx = -rc;
+
+ /* If the smaller input is negative, by sign extension higher limbs
+ don't matter. */
+ rn = vx ? vn : un;
+
+ rp = MPZ_REALLOC (r, rn + rc);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ i = 0;
+ do
+ {
+ ul = (up[i] ^ ux) + uc;
+ uc = ul < uc;
+
+ vl = (vp[i] ^ vx) + vc;
+ vc = vl < vc;
+
+ rl = ( (ul | vl) ^ rx) + rc;
+ rc = rl < rc;
+ rp[i] = rl;
+ }
+ while (++i < vn);
+ assert (vc == 0);
+
+ for (; i < rn; i++)
+ {
+ ul = (up[i] ^ ux) + uc;
+ uc = ul < uc;
+
+ rl = ( (ul | vx) ^ rx) + rc;
+ rc = rl < rc;
+ rp[i] = rl;
+ }
+ if (rc)
+ rp[rn++] = rc;
+ else
+ rn = mpn_normalized_size (rp, rn);
+
+ r->_mp_size = rx ? -rn : rn;
+}
+
+void
+mpz_xor (mpz_t r, const mpz_t u, const mpz_t v)
+{
+ mp_size_t un, vn, i;
+ mp_ptr up, vp, rp;
+
+ mp_limb_t ux, vx, rx;
+ mp_limb_t uc, vc, rc;
+ mp_limb_t ul, vl, rl;
+
+ un = GMP_ABS (u->_mp_size);
+ vn = GMP_ABS (v->_mp_size);
+ if (un < vn)
+ {
+ MPZ_SRCPTR_SWAP (u, v);
+ MP_SIZE_T_SWAP (un, vn);
+ }
+ if (vn == 0)
+ {
+ mpz_set (r, u);
+ return;
+ }
+
+ uc = u->_mp_size < 0;
+ vc = v->_mp_size < 0;
+ rc = uc ^ vc;
+
+ ux = -uc;
+ vx = -vc;
+ rx = -rc;
+
+ rp = MPZ_REALLOC (r, un + rc);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ i = 0;
+ do
+ {
+ ul = (up[i] ^ ux) + uc;
+ uc = ul < uc;
+
+ vl = (vp[i] ^ vx) + vc;
+ vc = vl < vc;
+
+ rl = (ul ^ vl ^ rx) + rc;
+ rc = rl < rc;
+ rp[i] = rl;
+ }
+ while (++i < vn);
+ assert (vc == 0);
+
+ for (; i < un; i++)
+ {
+ ul = (up[i] ^ ux) + uc;
+ uc = ul < uc;
+
+ rl = (ul ^ ux) + rc;
+ rc = rl < rc;
+ rp[i] = rl;
+ }
+ if (rc)
+ rp[un++] = rc;
+ else
+ un = mpn_normalized_size (rp, un);
+
+ r->_mp_size = rx ? -un : un;
+}
+
+static unsigned
+gmp_popcount_limb (mp_limb_t x)
+{
+ unsigned c;
+
+ /* Do 16 bits at a time, to avoid limb-sized constants. */
+ for (c = 0; x > 0; x >>= 16)
+ {
+ unsigned w = ((x >> 1) & 0x5555) + (x & 0x5555);
+ w = ((w >> 2) & 0x3333) + (w & 0x3333);
+ w = ((w >> 4) & 0x0f0f) + (w & 0x0f0f);
+ w = (w >> 8) + (w & 0x00ff);
+ c += w;
+ }
+ return c;
+}
+
+mp_bitcnt_t
+mpn_popcount (mp_srcptr p, mp_size_t n)
+{
+ mp_size_t i;
+ mp_bitcnt_t c;
+
+ for (c = 0, i = 0; i < n; i++)
+ c += gmp_popcount_limb (p[i]);
+
+ return c;
+}
+
+mp_bitcnt_t
+mpz_popcount (const mpz_t u)
+{
+ mp_size_t un;
+
+ un = u->_mp_size;
+
+ if (un < 0)
+ return ~(mp_bitcnt_t) 0;
+
+ return mpn_popcount (u->_mp_d, un);
+}
+
+mp_bitcnt_t
+mpz_hamdist (const mpz_t u, const mpz_t v)
+{
+ mp_size_t un, vn, i;
+ mp_limb_t uc, vc, ul, vl, comp;
+ mp_srcptr up, vp;
+ mp_bitcnt_t c;
+
+ un = u->_mp_size;
+ vn = v->_mp_size;
+
+ if ( (un ^ vn) < 0)
+ return ~(mp_bitcnt_t) 0;
+
+ comp = - (uc = vc = (un < 0));
+ if (uc)
+ {
+ assert (vn < 0);
+ un = -un;
+ vn = -vn;
+ }
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ if (un < vn)
+ MPN_SRCPTR_SWAP (up, un, vp, vn);
+
+ for (i = 0, c = 0; i < vn; i++)
+ {
+ ul = (up[i] ^ comp) + uc;
+ uc = ul < uc;
+
+ vl = (vp[i] ^ comp) + vc;
+ vc = vl < vc;
+
+ c += gmp_popcount_limb (ul ^ vl);
+ }
+ assert (vc == 0);
+
+ for (; i < un; i++)
+ {
+ ul = (up[i] ^ comp) + uc;
+ uc = ul < uc;
+
+ c += gmp_popcount_limb (ul ^ comp);
+ }
+
+ return c;
+}
+
+mp_bitcnt_t
+mpz_scan1 (const mpz_t u, mp_bitcnt_t starting_bit)
+{
+ mp_ptr up;
+ mp_size_t us, un, i;
+ mp_limb_t limb, ux;
+
+ us = u->_mp_size;
+ un = GMP_ABS (us);
+ i = starting_bit / GMP_LIMB_BITS;
+
+ /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit
+ for u<0. Notice this test picks up any u==0 too. */
+ if (i >= un)
+ return (us >= 0 ? ~(mp_bitcnt_t) 0 : starting_bit);
+
+ up = u->_mp_d;
+ ux = 0;
+ limb = up[i];
+
+ if (starting_bit != 0)
+ {
+ if (us < 0)
+ {
+ ux = mpn_zero_p (up, i);
+ limb = ~ limb + ux;
+ ux = - (mp_limb_t) (limb >= ux);
+ }
+
+ /* Mask to 0 all bits before starting_bit, thus ignoring them. */
+ limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS));
+ }
+
+ return mpn_common_scan (limb, i, up, un, ux);
+}
+
+mp_bitcnt_t
+mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit)
+{
+ mp_ptr up;
+ mp_size_t us, un, i;
+ mp_limb_t limb, ux;
+
+ us = u->_mp_size;
+ ux = - (mp_limb_t) (us >= 0);
+ un = GMP_ABS (us);
+ i = starting_bit / GMP_LIMB_BITS;
+
+ /* When past end, there's an immediate 0 bit for u>=0, or no 0 bits for
+ u<0. Notice this test picks up all cases of u==0 too. */
+ if (i >= un)
+ return (ux ? starting_bit : ~(mp_bitcnt_t) 0);
+
+ up = u->_mp_d;
+ limb = up[i] ^ ux;
+
+ if (ux == 0)
+ limb -= mpn_zero_p (up, i); /* limb = ~(~limb + zero_p) */
+
+ /* Mask all bits before starting_bit, thus ignoring them. */
+ limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS));
+
+ return mpn_common_scan (limb, i, up, un, ux);
+}
+
+
+/* MPZ base conversion. */
+
+size_t
+mpz_sizeinbase (const mpz_t u, int base)
+{
+ mp_size_t un;
+ mp_srcptr up;
+ mp_ptr tp;
+ mp_bitcnt_t bits;
+ struct gmp_div_inverse bi;
+ size_t ndigits;
+
+ assert (base >= 2);
+ assert (base <= 36);
+
+ un = GMP_ABS (u->_mp_size);
+ if (un == 0)
+ return 1;
+
+ up = u->_mp_d;
+
+ bits = (un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]);
+ switch (base)
+ {
+ case 2:
+ return bits;
+ case 4:
+ return (bits + 1) / 2;
+ case 8:
+ return (bits + 2) / 3;
+ case 16:
+ return (bits + 3) / 4;
+ case 32:
+ return (bits + 4) / 5;
+ /* FIXME: Do something more clever for the common case of base
+ 10. */
+ }
+
+ tp = gmp_xalloc_limbs (un);
+ mpn_copyi (tp, up, un);
+ mpn_div_qr_1_invert (&bi, base);
+
+ ndigits = 0;
+ do
+ {
+ ndigits++;
+ mpn_div_qr_1_preinv (tp, tp, un, &bi);
+ un -= (tp[un-1] == 0);
+ }
+ while (un > 0);
+
+ gmp_free (tp);
+ return ndigits;
+}
+
+char *
+mpz_get_str (char *sp, int base, const mpz_t u)
+{
+ unsigned bits;
+ const char *digits;
+ mp_size_t un;
+ size_t i, sn;
+
+ if (base >= 0)
+ {
+ digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+ }
+ else
+ {
+ base = -base;
+ digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ }
+ if (base <= 1)
+ base = 10;
+ if (base > 36)
+ return NULL;
+
+ sn = 1 + mpz_sizeinbase (u, base);
+ if (!sp)
+ sp = gmp_xalloc (1 + sn);
+
+ un = GMP_ABS (u->_mp_size);
+
+ if (un == 0)
+ {
+ sp[0] = '0';
+ sp[1] = '\0';
+ return sp;
+ }
+
+ i = 0;
+
+ if (u->_mp_size < 0)
+ sp[i++] = '-';
+
+ bits = mpn_base_power_of_two_p (base);
+
+ if (bits)
+ /* Not modified in this case. */
+ sn = i + mpn_get_str_bits ((unsigned char *) sp + i, bits, u->_mp_d, un);
+ else
+ {
+ struct mpn_base_info info;
+ mp_ptr tp;
+
+ mpn_get_base_info (&info, base);
+ tp = gmp_xalloc_limbs (un);
+ mpn_copyi (tp, u->_mp_d, un);
+
+ sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un);
+ gmp_free (tp);
+ }
+
+ for (; i < sn; i++)
+ sp[i] = digits[(unsigned char) sp[i]];
+
+ sp[sn] = '\0';
+ return sp;
+}
+
+int
+mpz_set_str (mpz_t r, const char *sp, int base)
+{
+ unsigned bits;
+ mp_size_t rn, alloc;
+ mp_ptr rp;
+ size_t sn;
+ int sign;
+ unsigned char *dp;
+
+ assert (base == 0 || (base >= 2 && base <= 36));
+
+ while (isspace( (unsigned char) *sp))
+ sp++;
+
+ sign = (*sp == '-');
+ sp += sign;
+
+ if (base == 0)
+ {
+ if (*sp == '0')
+ {
+ sp++;
+ if (*sp == 'x' || *sp == 'X')
+ {
+ base = 16;
+ sp++;
+ }
+ else if (*sp == 'b' || *sp == 'B')
+ {
+ base = 2;
+ sp++;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ sn = strlen (sp);
+ dp = gmp_xalloc (sn + (sn == 0));
+
+ for (sn = 0; *sp; sp++)
+ {
+ unsigned digit;
+
+ if (isspace ((unsigned char) *sp))
+ continue;
+ if (*sp >= '0' && *sp <= '9')
+ digit = *sp - '0';
+ else if (*sp >= 'a' && *sp <= 'z')
+ digit = *sp - 'a' + 10;
+ else if (*sp >= 'A' && *sp <= 'Z')
+ digit = *sp - 'A' + 10;
+ else
+ digit = base; /* fail */
+
+ if (digit >= base)
+ {
+ gmp_free (dp);
+ r->_mp_size = 0;
+ return -1;
+ }
+
+ dp[sn++] = digit;
+ }
+
+ bits = mpn_base_power_of_two_p (base);
+
+ if (bits > 0)
+ {
+ alloc = (sn * bits + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
+ rp = MPZ_REALLOC (r, alloc);
+ rn = mpn_set_str_bits (rp, dp, sn, bits);
+ }
+ else
+ {
+ struct mpn_base_info info;
+ mpn_get_base_info (&info, base);
+ alloc = (sn + info.exp - 1) / info.exp;
+ rp = MPZ_REALLOC (r, alloc);
+ rn = mpn_set_str_other (rp, dp, sn, base, &info);
+ }
+ assert (rn <= alloc);
+ gmp_free (dp);
+
+ r->_mp_size = sign ? - rn : rn;
+
+ return 0;
+}
+
+int
+mpz_init_set_str (mpz_t r, const char *sp, int base)
+{
+ mpz_init (r);
+ return mpz_set_str (r, sp, base);
+}
+
+size_t
+mpz_out_str (FILE *stream, int base, const mpz_t x)
+{
+ char *str;
+ size_t len;
+
+ str = mpz_get_str (NULL, base, x);
+ len = strlen (str);
+ len = fwrite (str, 1, len, stream);
+ gmp_free (str);
+ return len;
+}
+
+
+static int
+gmp_detect_endian (void)
+{
+ static const int i = 2;
+ const unsigned char *p = (const unsigned char *) &i;
+ return 1 - *p;
+}
+
+/* Import and export. Does not support nails. */
+void
+mpz_import (mpz_t r, size_t count, int order, size_t size, int endian,
+ size_t nails, const void *src)
+{
+ const unsigned char *p;
+ ptrdiff_t word_step;
+ mp_ptr rp;
+ mp_size_t rn;
+
+ /* The current (partial) limb. */
+ mp_limb_t limb;
+ /* The number of bytes already copied to this limb (starting from
+ the low end). */
+ size_t bytes;
+ /* The index where the limb should be stored, when completed. */
+ mp_size_t i;
+
+ if (nails != 0)
+ gmp_die ("mpz_import: Nails not supported.");
+
+ assert (order == 1 || order == -1);
+ assert (endian >= -1 && endian <= 1);
+
+ if (endian == 0)
+ endian = gmp_detect_endian ();
+
+ p = (unsigned char *) src;
+
+ word_step = (order != endian) ? 2 * size : 0;
+
+ /* Process bytes from the least significant end, so point p at the
+ least significant word. */
+ if (order == 1)
+ {
+ p += size * (count - 1);
+ word_step = - word_step;
+ }
+
+ /* And at least significant byte of that word. */
+ if (endian == 1)
+ p += (size - 1);
+
+ rn = (size * count + sizeof(mp_limb_t) - 1) / sizeof(mp_limb_t);
+ rp = MPZ_REALLOC (r, rn);
+
+ for (limb = 0, bytes = 0, i = 0; count > 0; count--, p += word_step)
+ {
+ size_t j;
+ for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
+ {
+ limb |= (mp_limb_t) *p << (bytes++ * CHAR_BIT);
+ if (bytes == sizeof(mp_limb_t))
+ {
+ rp[i++] = limb;
+ bytes = 0;
+ limb = 0;
+ }
+ }
+ }
+ assert (i + (bytes > 0) == rn);
+ if (limb != 0)
+ rp[i++] = limb;
+ else
+ i = mpn_normalized_size (rp, i);
+
+ r->_mp_size = i;
+}
+
+void *
+mpz_export (void *r, size_t *countp, int order, size_t size, int endian,
+ size_t nails, const mpz_t u)
+{
+ size_t count;
+ mp_size_t un;
+
+ if (nails != 0)
+ gmp_die ("mpz_import: Nails not supported.");
+
+ assert (order == 1 || order == -1);
+ assert (endian >= -1 && endian <= 1);
+ assert (size > 0 || u->_mp_size == 0);
+
+ un = u->_mp_size;
+ count = 0;
+ if (un != 0)
+ {
+ size_t k;
+ unsigned char *p;
+ ptrdiff_t word_step;
+ /* The current (partial) limb. */
+ mp_limb_t limb;
+ /* The number of bytes left to to in this limb. */
+ size_t bytes;
+ /* The index where the limb was read. */
+ mp_size_t i;
+
+ un = GMP_ABS (un);
+
+ /* Count bytes in top limb. */
+ limb = u->_mp_d[un-1];
+ assert (limb != 0);
+
+ k = 0;
+ do {
+ k++; limb >>= CHAR_BIT;
+ } while (limb != 0);
+
+ count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size;
+
+ if (!r)
+ r = gmp_xalloc (count * size);
+
+ if (endian == 0)
+ endian = gmp_detect_endian ();
+
+ p = (unsigned char *) r;
+
+ word_step = (order != endian) ? 2 * size : 0;
+
+ /* Process bytes from the least significant end, so point p at the
+ least significant word. */
+ if (order == 1)
+ {
+ p += size * (count - 1);
+ word_step = - word_step;
+ }
+
+ /* And at least significant byte of that word. */
+ if (endian == 1)
+ p += (size - 1);
+
+ for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step)
+ {
+ size_t j;
+ for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
+ {
+ if (bytes == 0)
+ {
+ if (i < un)
+ limb = u->_mp_d[i++];
+ bytes = sizeof (mp_limb_t);
+ }
+ *p = limb;
+ limb >>= CHAR_BIT;
+ bytes--;
+ }
+ }
+ assert (i == un);
+ assert (k == count);
+ }
+
+ if (countp)
+ *countp = count;
+
+ return r;
+}
diff --git a/gmp/mini-gmp/mini-gmp.h b/gmp/mini-gmp/mini-gmp.h
new file mode 100644
index 0000000000..c043ca7e66
--- /dev/null
+++ b/gmp/mini-gmp/mini-gmp.h
@@ -0,0 +1,294 @@
+/* mini-gmp, a minimalistic implementation of a GNU GMP subset.
+
+Copyright 2011-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* About mini-gmp: This is a minimal implementation of a subset of the
+ GMP interface. It is intended for inclusion into applications which
+ have modest bignums needs, as a fallback when the real GMP library
+ is not installed.
+
+ This file defines the public interface. */
+
+#ifndef __MINI_GMP_H__
+#define __MINI_GMP_H__
+
+/* For size_t */
+#include <stddef.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+void mp_set_memory_functions (void *(*) (size_t),
+ void *(*) (void *, size_t, size_t),
+ void (*) (void *, size_t));
+
+void mp_get_memory_functions (void *(**) (size_t),
+ void *(**) (void *, size_t, size_t),
+ void (**) (void *, size_t));
+
+typedef unsigned long mp_limb_t;
+typedef long mp_size_t;
+typedef unsigned long mp_bitcnt_t;
+
+typedef mp_limb_t *mp_ptr;
+typedef const mp_limb_t *mp_srcptr;
+
+typedef struct
+{
+ int _mp_alloc; /* Number of *limbs* allocated and pointed
+ to by the _mp_d field. */
+ int _mp_size; /* abs(_mp_size) is the number of limbs the
+ last field points to. If _mp_size is
+ negative this is a negative number. */
+ mp_limb_t *_mp_d; /* Pointer to the limbs. */
+} __mpz_struct;
+
+typedef __mpz_struct mpz_t[1];
+
+typedef __mpz_struct *mpz_ptr;
+typedef const __mpz_struct *mpz_srcptr;
+
+extern const int mp_bits_per_limb;
+
+void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t);
+void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t);
+void mpn_zero (mp_ptr, mp_size_t);
+
+int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t);
+
+mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+mp_limb_t mpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t mpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t);
+int mpn_perfect_square_p (mp_srcptr, mp_size_t);
+mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t);
+
+mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
+mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
+
+mp_bitcnt_t mpn_scan0 (mp_srcptr, mp_bitcnt_t);
+mp_bitcnt_t mpn_scan1 (mp_srcptr, mp_bitcnt_t);
+
+mp_bitcnt_t mpn_popcount (mp_srcptr, mp_size_t);
+
+mp_limb_t mpn_invert_3by2 (mp_limb_t, mp_limb_t);
+#define mpn_invert_limb(x) mpn_invert_3by2 ((x), 0)
+
+size_t mpn_get_str (unsigned char *, int, mp_ptr, mp_size_t);
+mp_size_t mpn_set_str (mp_ptr, const unsigned char *, size_t, int);
+
+void mpz_init (mpz_t);
+void mpz_init2 (mpz_t, mp_bitcnt_t);
+void mpz_clear (mpz_t);
+
+#define mpz_odd_p(z) (((z)->_mp_size != 0) & (int) (z)->_mp_d[0])
+#define mpz_even_p(z) (! mpz_odd_p (z))
+
+int mpz_sgn (const mpz_t);
+int mpz_cmp_si (const mpz_t, long);
+int mpz_cmp_ui (const mpz_t, unsigned long);
+int mpz_cmp (const mpz_t, const mpz_t);
+int mpz_cmpabs_ui (const mpz_t, unsigned long);
+int mpz_cmpabs (const mpz_t, const mpz_t);
+int mpz_cmp_d (const mpz_t, double);
+int mpz_cmpabs_d (const mpz_t, double);
+
+void mpz_abs (mpz_t, const mpz_t);
+void mpz_neg (mpz_t, const mpz_t);
+void mpz_swap (mpz_t, mpz_t);
+
+void mpz_add_ui (mpz_t, const mpz_t, unsigned long);
+void mpz_add (mpz_t, const mpz_t, const mpz_t);
+void mpz_sub_ui (mpz_t, const mpz_t, unsigned long);
+void mpz_ui_sub (mpz_t, unsigned long, const mpz_t);
+void mpz_sub (mpz_t, const mpz_t, const mpz_t);
+
+void mpz_mul_si (mpz_t, const mpz_t, long int);
+void mpz_mul_ui (mpz_t, const mpz_t, unsigned long int);
+void mpz_mul (mpz_t, const mpz_t, const mpz_t);
+void mpz_mul_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
+void mpz_addmul_ui (mpz_t, const mpz_t, unsigned long int);
+void mpz_addmul (mpz_t, const mpz_t, const mpz_t);
+void mpz_submul_ui (mpz_t, const mpz_t, unsigned long int);
+void mpz_submul (mpz_t, const mpz_t, const mpz_t);
+
+void mpz_cdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t);
+void mpz_fdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t);
+void mpz_tdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t);
+void mpz_cdiv_q (mpz_t, const mpz_t, const mpz_t);
+void mpz_fdiv_q (mpz_t, const mpz_t, const mpz_t);
+void mpz_tdiv_q (mpz_t, const mpz_t, const mpz_t);
+void mpz_cdiv_r (mpz_t, const mpz_t, const mpz_t);
+void mpz_fdiv_r (mpz_t, const mpz_t, const mpz_t);
+void mpz_tdiv_r (mpz_t, const mpz_t, const mpz_t);
+
+void mpz_cdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
+void mpz_fdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
+void mpz_tdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
+void mpz_cdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
+void mpz_fdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
+void mpz_tdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
+
+void mpz_mod (mpz_t, const mpz_t, const mpz_t);
+
+void mpz_divexact (mpz_t, const mpz_t, const mpz_t);
+
+int mpz_divisible_p (const mpz_t, const mpz_t);
+int mpz_congruent_p (const mpz_t, const mpz_t, const mpz_t);
+
+unsigned long mpz_cdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_fdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_tdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_cdiv_q_ui (mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_fdiv_q_ui (mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_tdiv_q_ui (mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_cdiv_r_ui (mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_fdiv_r_ui (mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_tdiv_r_ui (mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_cdiv_ui (const mpz_t, unsigned long);
+unsigned long mpz_fdiv_ui (const mpz_t, unsigned long);
+unsigned long mpz_tdiv_ui (const mpz_t, unsigned long);
+
+unsigned long mpz_mod_ui (mpz_t, const mpz_t, unsigned long);
+
+void mpz_divexact_ui (mpz_t, const mpz_t, unsigned long);
+
+int mpz_divisible_ui_p (const mpz_t, unsigned long);
+
+unsigned long mpz_gcd_ui (mpz_t, const mpz_t, unsigned long);
+void mpz_gcd (mpz_t, const mpz_t, const mpz_t);
+void mpz_gcdext (mpz_t, mpz_t, mpz_t, const mpz_t, const mpz_t);
+void mpz_lcm_ui (mpz_t, const mpz_t, unsigned long);
+void mpz_lcm (mpz_t, const mpz_t, const mpz_t);
+int mpz_invert (mpz_t, const mpz_t, const mpz_t);
+
+void mpz_sqrtrem (mpz_t, mpz_t, const mpz_t);
+void mpz_sqrt (mpz_t, const mpz_t);
+int mpz_perfect_square_p (const mpz_t);
+
+void mpz_pow_ui (mpz_t, const mpz_t, unsigned long);
+void mpz_ui_pow_ui (mpz_t, unsigned long, unsigned long);
+void mpz_powm (mpz_t, const mpz_t, const mpz_t, const mpz_t);
+void mpz_powm_ui (mpz_t, const mpz_t, unsigned long, const mpz_t);
+
+void mpz_rootrem (mpz_t, mpz_t, const mpz_t, unsigned long);
+int mpz_root (mpz_t, const mpz_t, unsigned long);
+
+void mpz_fac_ui (mpz_t, unsigned long);
+void mpz_bin_uiui (mpz_t, unsigned long, unsigned long);
+
+int mpz_probab_prime_p (const mpz_t, int);
+
+int mpz_tstbit (const mpz_t, mp_bitcnt_t);
+void mpz_setbit (mpz_t, mp_bitcnt_t);
+void mpz_clrbit (mpz_t, mp_bitcnt_t);
+void mpz_combit (mpz_t, mp_bitcnt_t);
+
+void mpz_com (mpz_t, const mpz_t);
+void mpz_and (mpz_t, const mpz_t, const mpz_t);
+void mpz_ior (mpz_t, const mpz_t, const mpz_t);
+void mpz_xor (mpz_t, const mpz_t, const mpz_t);
+
+mp_bitcnt_t mpz_popcount (const mpz_t);
+mp_bitcnt_t mpz_hamdist (const mpz_t, const mpz_t);
+mp_bitcnt_t mpz_scan0 (const mpz_t, mp_bitcnt_t);
+mp_bitcnt_t mpz_scan1 (const mpz_t, mp_bitcnt_t);
+
+int mpz_fits_slong_p (const mpz_t);
+int mpz_fits_ulong_p (const mpz_t);
+long int mpz_get_si (const mpz_t);
+unsigned long int mpz_get_ui (const mpz_t);
+double mpz_get_d (const mpz_t);
+size_t mpz_size (const mpz_t);
+mp_limb_t mpz_getlimbn (const mpz_t, mp_size_t);
+
+void mpz_realloc2 (mpz_t, mp_bitcnt_t);
+mp_srcptr mpz_limbs_read (mpz_srcptr);
+mp_ptr mpz_limbs_modify (mpz_t, mp_size_t);
+mp_ptr mpz_limbs_write (mpz_t, mp_size_t);
+void mpz_limbs_finish (mpz_t, mp_size_t);
+mpz_srcptr mpz_roinit_n (mpz_t, mp_srcptr, mp_size_t);
+
+#define MPZ_ROINIT_N(xp, xs) {{0, (xs),(xp) }}
+
+void mpz_set_si (mpz_t, signed long int);
+void mpz_set_ui (mpz_t, unsigned long int);
+void mpz_set (mpz_t, const mpz_t);
+void mpz_set_d (mpz_t, double);
+
+void mpz_init_set_si (mpz_t, signed long int);
+void mpz_init_set_ui (mpz_t, unsigned long int);
+void mpz_init_set (mpz_t, const mpz_t);
+void mpz_init_set_d (mpz_t, double);
+
+size_t mpz_sizeinbase (const mpz_t, int);
+char *mpz_get_str (char *, int, const mpz_t);
+int mpz_set_str (mpz_t, const char *, int);
+int mpz_init_set_str (mpz_t, const char *, int);
+
+/* This long list taken from gmp.h. */
+/* For reference, "defined(EOF)" cannot be used here. In g++ 2.95.4,
+ <iostream> defines EOF but not FILE. */
+#if defined (FILE) \
+ || defined (H_STDIO) \
+ || defined (_H_STDIO) /* AIX */ \
+ || defined (_STDIO_H) /* glibc, Sun, SCO */ \
+ || defined (_STDIO_H_) /* BSD, OSF */ \
+ || defined (__STDIO_H) /* Borland */ \
+ || defined (__STDIO_H__) /* IRIX */ \
+ || defined (_STDIO_INCLUDED) /* HPUX */ \
+ || defined (__dj_include_stdio_h_) /* DJGPP */ \
+ || defined (_FILE_DEFINED) /* Microsoft */ \
+ || defined (__STDIO__) /* Apple MPW MrC */ \
+ || defined (_MSL_STDIO_H) /* Metrowerks */ \
+ || defined (_STDIO_H_INCLUDED) /* QNX4 */ \
+ || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \
+ || defined (__STDIO_LOADED) /* VMS */
+size_t mpz_out_str (FILE *, int, const mpz_t);
+#endif
+
+void mpz_import (mpz_t, size_t, int, size_t, int, size_t, const void *);
+void *mpz_export (void *, size_t *, int, size_t, int, size_t, const mpz_t);
+
+#if defined (__cplusplus)
+}
+#endif
+#endif /* __MINI_GMP_H__ */
diff --git a/gmp/mini-gmp/tests/Makefile b/gmp/mini-gmp/tests/Makefile
new file mode 100644
index 0000000000..fe052a02f7
--- /dev/null
+++ b/gmp/mini-gmp/tests/Makefile
@@ -0,0 +1,60 @@
+# Note: Requires GNU make
+
+# Copyright 2011, 2012, 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/.
+
+srcdir=.
+MINI_GMP_DIR=..
+
+CC = gcc
+EXTRA_CFLAGS = -O -Wall -g
+CFLAGS = $(EXTRA_CFLAGS) -I$(MINI_GMP_DIR)
+LDFLAGS =
+
+LIBS = -lgmp -lm -lmcheck
+
+CHECK_PROGRAMS = t-add t-sub t-mul t-invert t-div t-div_2exp \
+ t-double t-cmp_d t-gcd t-lcm t-import t-comb t-signed \
+ t-sqrt t-root t-powm t-logops t-bitops t-scan t-str \
+ t-reuse t-aorsmul t-limbs t-cong t-pprime_p
+
+MISC_OBJS = hex-random.o mini-random.o testutils.o
+
+all:
+
+clean:
+ rm -f *.o $(CHECK_PROGRAMS)
+
+%: %.c
+.c:
+
+# Keep object files
+.PRECIOUS: %.o
+
+%.o: %.c $(MINI_GMP_DIR)/mini-gmp.h hex-random.h mini-random.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+testutils.o: $(MINI_GMP_DIR)/mini-gmp.c
+
+%: %.o $(MISC_OBJS)
+ $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+
+# Missing tests include:
+# mpz_cmp_d, mpz_popcount, mpz_hamdist, mpz_ui_pow_ui
+
+check: $(CHECK_PROGRAMS)
+ $(srcdir)/run-tests $(CHECK_PROGRAMS)
diff --git a/gmp/mini-gmp/tests/hex-random.c b/gmp/mini-gmp/tests/hex-random.c
new file mode 100644
index 0000000000..eb8d3f84ec
--- /dev/null
+++ b/gmp/mini-gmp/tests/hex-random.c
@@ -0,0 +1,434 @@
+/*
+
+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 <stdio.h>
+#include <stdlib.h>
+
+#include <time.h>
+#include <unistd.h>
+
+#include "gmp.h"
+
+#include "hex-random.h"
+
+static gmp_randstate_t state;
+
+void
+hex_random_init (void)
+{
+ unsigned long seed;
+ char *env_seed;
+
+ env_seed = getenv("GMP_CHECK_RANDOMIZE");
+ if (env_seed && env_seed[0])
+ {
+ seed = strtoul (env_seed, NULL, 0);
+ if (seed)
+ printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed);
+ else
+ {
+ seed = time(NULL) + getpid();
+ printf ("Seed GMP_CHECK_RANDOMIZE=%lu (include this in bug reports)\n", seed);
+ }
+ }
+ else
+ seed = 4711;
+
+ gmp_randinit_default (state);
+ gmp_randseed_ui (state, seed);
+}
+
+char *
+hex_urandomb (unsigned long bits)
+{
+ char *res;
+ mpz_t x;
+
+ mpz_init (x);
+ mpz_urandomb (x, state, bits);
+ gmp_asprintf (&res, "%Zx", x);
+ mpz_clear (x);
+ return res;
+}
+
+char *
+hex_rrandomb (unsigned long bits)
+{
+ char *res;
+ mpz_t x;
+
+ mpz_init (x);
+ mpz_rrandomb (x, state, bits);
+ gmp_asprintf (&res, "%Zx", x);
+ mpz_clear (x);
+ return res;
+}
+
+char *
+hex_rrandomb_export (void *dst, size_t *countp,
+ int order, size_t size, int endian, unsigned long bits)
+{
+ char *res;
+ mpz_t x;
+ mpz_init (x);
+ mpz_rrandomb (x, state, bits);
+ gmp_asprintf (&res, "%Zx", x);
+ mpz_export (dst, countp, order, size, endian, 0, x);
+ mpz_clear (x);
+ return res;
+}
+
+void hex_random_op2 (enum hex_random_op op, unsigned long maxbits,
+ char **ap, char **rp)
+{
+ mpz_t a, r;
+ unsigned long abits;
+ unsigned signs;
+
+ mpz_init (a);
+ mpz_init (r);
+
+ abits = gmp_urandomb_ui (state, 32) % maxbits;
+
+ mpz_rrandomb (a, state, abits);
+
+ signs = gmp_urandomb_ui (state, 1);
+ if (signs & 1)
+ mpz_neg (a, a);
+
+ switch (op)
+ {
+ default:
+ abort ();
+ case OP_SQR:
+ mpz_mul (r, a, a);
+ break;
+ }
+
+ gmp_asprintf (ap, "%Zx", a);
+ gmp_asprintf (rp, "%Zx", r);
+
+ mpz_clear (a);
+ mpz_clear (r);
+}
+
+void
+hex_random_op3 (enum hex_random_op op, unsigned long maxbits,
+ char **ap, char **bp, char **rp)
+{
+ mpz_t a, b, r;
+ unsigned long abits, bbits;
+ unsigned signs;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (r);
+
+ abits = gmp_urandomb_ui (state, 32) % maxbits;
+ bbits = gmp_urandomb_ui (state, 32) % maxbits;
+
+ mpz_rrandomb (a, state, abits);
+ mpz_rrandomb (b, state, bbits);
+
+ signs = gmp_urandomb_ui (state, 3);
+ if (signs & 1)
+ mpz_neg (a, a);
+ if (signs & 2)
+ mpz_neg (b, b);
+
+ switch (op)
+ {
+ default:
+ abort ();
+ case OP_ADD:
+ mpz_add (r, a, b);
+ break;
+ case OP_SUB:
+ mpz_sub (r, a, b);
+ break;
+ case OP_MUL:
+ mpz_mul (r, a, b);
+ break;
+ case OP_GCD:
+ if (signs & 4)
+ {
+ /* Produce a large gcd */
+ unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits;
+ mpz_rrandomb (r, state, gbits);
+ mpz_mul (a, a, r);
+ mpz_mul (b, b, r);
+ }
+ mpz_gcd (r, a, b);
+ break;
+ case OP_LCM:
+ if (signs & 4)
+ {
+ /* Produce a large gcd */
+ unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits;
+ mpz_rrandomb (r, state, gbits);
+ mpz_mul (a, a, r);
+ mpz_mul (b, b, r);
+ }
+ mpz_lcm (r, a, b);
+ break;
+ case OP_AND:
+ mpz_and (r, a, b);
+ break;
+ case OP_IOR:
+ mpz_ior (r, a, b);
+ break;
+ case OP_XOR:
+ mpz_xor (r, a, b);
+ break;
+ }
+
+ gmp_asprintf (ap, "%Zx", a);
+ gmp_asprintf (bp, "%Zx", b);
+ gmp_asprintf (rp, "%Zx", r);
+
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (r);
+}
+
+void
+hex_random_op4 (enum hex_random_op op, unsigned long maxbits,
+ char **ap, char **bp, char **cp, char **dp)
+{
+ mpz_t a, b, c, d;
+ unsigned long abits, bbits;
+ unsigned signs;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (c);
+ mpz_init (d);
+
+ if (op == OP_POWM)
+ {
+ unsigned long cbits;
+ abits = gmp_urandomb_ui (state, 32) % maxbits;
+ bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits;
+ cbits = 2 + gmp_urandomb_ui (state, 32) % maxbits;
+
+ mpz_rrandomb (a, state, abits);
+ mpz_rrandomb (b, state, bbits);
+ mpz_rrandomb (c, state, cbits);
+
+ signs = gmp_urandomb_ui (state, 3);
+ if (signs & 1)
+ mpz_neg (a, a);
+ if (signs & 2)
+ {
+ mpz_t g;
+
+ /* If we negate the exponent, must make sure that gcd(a, c) = 1 */
+ if (mpz_sgn (a) == 0)
+ mpz_set_ui (a, 1);
+ else
+ {
+ mpz_init (g);
+
+ for (;;)
+ {
+ mpz_gcd (g, a, c);
+ if (mpz_cmp_ui (g, 1) == 0)
+ break;
+ mpz_divexact (a, a, g);
+ }
+ mpz_clear (g);
+ }
+ mpz_neg (b, b);
+ }
+ if (signs & 4)
+ mpz_neg (c, c);
+
+ mpz_powm (d, a, b, c);
+ }
+ else
+ {
+ unsigned long qbits;
+ bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits;
+ qbits = gmp_urandomb_ui (state, 32) % maxbits;
+ abits = bbits + qbits;
+ if (abits > 30)
+ abits -= 30;
+ else
+ abits = 0;
+
+ mpz_rrandomb (a, state, abits);
+ mpz_rrandomb (b, state, bbits);
+
+ signs = gmp_urandomb_ui (state, 2);
+ if (signs & 1)
+ mpz_neg (a, a);
+ if (signs & 2)
+ mpz_neg (b, b);
+
+ switch (op)
+ {
+ default:
+ abort ();
+ case OP_CDIV:
+ mpz_cdiv_qr (c, d, a, b);
+ break;
+ case OP_FDIV:
+ mpz_fdiv_qr (c, d, a, b);
+ break;
+ case OP_TDIV:
+ mpz_tdiv_qr (c, d, a, b);
+ break;
+ }
+ }
+ gmp_asprintf (ap, "%Zx", a);
+ gmp_asprintf (bp, "%Zx", b);
+ gmp_asprintf (cp, "%Zx", c);
+ gmp_asprintf (dp, "%Zx", d);
+
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (c);
+ mpz_clear (d);
+}
+
+void
+hex_random_bit_op (enum hex_random_op op, unsigned long maxbits,
+ char **ap, unsigned long *b, char **rp)
+{
+ mpz_t a, r;
+ unsigned long abits, bbits;
+ unsigned signs;
+
+ mpz_init (a);
+ mpz_init (r);
+
+ abits = gmp_urandomb_ui (state, 32) % maxbits;
+ bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100);
+
+ mpz_rrandomb (a, state, abits);
+
+ signs = gmp_urandomb_ui (state, 1);
+ if (signs & 1)
+ mpz_neg (a, a);
+
+ switch (op)
+ {
+ default:
+ abort ();
+
+ case OP_SETBIT:
+ mpz_set (r, a);
+ mpz_setbit (r, bbits);
+ break;
+ case OP_CLRBIT:
+ mpz_set (r, a);
+ mpz_clrbit (r, bbits);
+ break;
+ case OP_COMBIT:
+ mpz_set (r, a);
+ mpz_combit (r, bbits);
+ break;
+ case OP_CDIV_Q_2:
+ mpz_cdiv_q_2exp (r, a, bbits);
+ break;
+ case OP_CDIV_R_2:
+ mpz_cdiv_r_2exp (r, a, bbits);
+ break;
+ case OP_FDIV_Q_2:
+ mpz_fdiv_q_2exp (r, a, bbits);
+ break;
+ case OP_FDIV_R_2:
+ mpz_fdiv_r_2exp (r, a, bbits);
+ break;
+ case OP_TDIV_Q_2:
+ mpz_tdiv_q_2exp (r, a, bbits);
+ break;
+ case OP_TDIV_R_2:
+ mpz_tdiv_r_2exp (r, a, bbits);
+ break;
+ }
+
+ gmp_asprintf (ap, "%Zx", a);
+ *b = bbits;
+ gmp_asprintf (rp, "%Zx", r);
+
+ mpz_clear (a);
+ mpz_clear (r);
+}
+
+void
+hex_random_scan_op (enum hex_random_op op, unsigned long maxbits,
+ char **ap, unsigned long *b, unsigned long *r)
+{
+ mpz_t a;
+ unsigned long abits, bbits;
+ unsigned signs;
+
+ mpz_init (a);
+
+ abits = gmp_urandomb_ui (state, 32) % maxbits;
+ bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100);
+
+ mpz_rrandomb (a, state, abits);
+
+ signs = gmp_urandomb_ui (state, 1);
+ if (signs & 1)
+ mpz_neg (a, a);
+
+ switch (op)
+ {
+ default:
+ abort ();
+
+ case OP_SCAN0:
+ *r = mpz_scan0 (a, bbits);
+ break;
+ case OP_SCAN1:
+ *r = mpz_scan1 (a, bbits);
+ break;
+ }
+ gmp_asprintf (ap, "%Zx", a);
+ *b = bbits;
+
+ mpz_clear (a);
+}
+
+void
+hex_random_str_op (unsigned long maxbits,
+ int base, char **ap, char **rp)
+{
+ mpz_t a;
+ unsigned long abits;
+ unsigned signs;
+
+ mpz_init (a);
+
+ abits = gmp_urandomb_ui (state, 32) % maxbits;
+
+ mpz_rrandomb (a, state, abits);
+
+ signs = gmp_urandomb_ui (state, 2);
+ if (signs & 1)
+ mpz_neg (a, a);
+
+ *ap = mpz_get_str (NULL, 16, a);
+ *rp = mpz_get_str (NULL, base, a);
+
+ mpz_clear (a);
+}
diff --git a/gmp/mini-gmp/tests/hex-random.h b/gmp/mini-gmp/tests/hex-random.h
new file mode 100644
index 0000000000..7a3913a0bc
--- /dev/null
+++ b/gmp/mini-gmp/tests/hex-random.h
@@ -0,0 +1,50 @@
+/*
+
+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/. */
+
+enum hex_random_op
+ {
+ OP_ADD, OP_SUB, OP_MUL, OP_SQR,
+ OP_CDIV, OP_FDIV, OP_TDIV,
+ OP_CDIV_Q_2, OP_CDIV_R_2,
+ OP_FDIV_Q_2, OP_FDIV_R_2,
+ OP_TDIV_Q_2, OP_TDIV_R_2,
+ OP_GCD, OP_LCM, OP_POWM, OP_AND, OP_IOR, OP_XOR,
+ OP_SETBIT, OP_CLRBIT, OP_COMBIT,
+ OP_SCAN0, OP_SCAN1,
+ };
+
+void hex_random_init (void);
+char *hex_urandomb (unsigned long bits);
+char *hex_rrandomb (unsigned long bits);
+char *hex_rrandomb_export (void *dst, size_t *countp,
+ int order, size_t size, int endian,
+ unsigned long bits);
+
+void hex_random_op2 (enum hex_random_op op, unsigned long maxbits,
+ char **ap, char **rp);
+void hex_random_op3 (enum hex_random_op op, unsigned long maxbits,
+ char **ap, char **bp, char **rp);
+void hex_random_op4 (enum hex_random_op op, unsigned long maxbits,
+ char **ap, char **bp, char **rp, char **qp);
+void hex_random_bit_op (enum hex_random_op op, unsigned long maxbits,
+ char **ap, unsigned long *b, char **rp);
+void hex_random_scan_op (enum hex_random_op op, unsigned long maxbits,
+ char **ap, unsigned long *b, unsigned long *r);
+void hex_random_str_op (unsigned long maxbits,
+ int base, char **ap, char **rp);
diff --git a/gmp/mini-gmp/tests/mini-random.c b/gmp/mini-gmp/tests/mini-random.c
new file mode 100644
index 0000000000..300d386b2c
--- /dev/null
+++ b/gmp/mini-gmp/tests/mini-random.c
@@ -0,0 +1,142 @@
+/*
+
+Copyright 2011, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "mini-random.h"
+
+static void
+set_str (mpz_t r, const char *s)
+{
+ if (mpz_set_str (r, s, 16) != 0)
+ {
+ fprintf (stderr, "mpz_set_str failed on input %s\n", s);
+ abort ();
+ }
+}
+
+void
+mini_urandomb (mpz_t r, unsigned long bits)
+{
+ char *s;
+ s = hex_urandomb (bits);
+ set_str (r, s);
+ free (s);
+}
+
+void
+mini_rrandomb (mpz_t r, unsigned long bits)
+{
+ char *s;
+ s = hex_rrandomb (bits);
+ set_str (r, s);
+ free (s);
+}
+
+void
+mini_rrandomb_export (mpz_t r, void *dst, size_t *countp,
+ int order, size_t size, int endian, unsigned long bits)
+{
+ char *s;
+ s = hex_rrandomb_export (dst, countp, order, size, endian, bits);
+ set_str (r, s);
+ free (s);
+}
+
+void
+mini_random_op2 (enum hex_random_op op, unsigned long maxbits,
+ mpz_t a, mpz_t r)
+{
+ char *ap;
+ char *rp;
+
+ hex_random_op2 (op, maxbits, &ap, &rp);
+ set_str (a, ap);
+ set_str (r, rp);
+
+ free (ap);
+ free (rp);
+}
+
+void
+mini_random_op3 (enum hex_random_op op, unsigned long maxbits,
+ mpz_t a, mpz_t b, mpz_t r)
+{
+ char *ap;
+ char *bp;
+ char *rp;
+
+ hex_random_op3 (op, maxbits, &ap, &bp, &rp);
+ set_str (a, ap);
+ set_str (b, bp);
+ set_str (r, rp);
+
+ free (ap);
+ free (bp);
+ free (rp);
+}
+
+void
+mini_random_op4 (enum hex_random_op op, unsigned long maxbits,
+ mpz_t a, mpz_t b, mpz_t c, mpz_t d)
+{
+ char *ap;
+ char *bp;
+ char *cp;
+ char *dp;
+
+ hex_random_op4 (op, maxbits, &ap, &bp, &cp, &dp);
+ set_str (a, ap);
+ set_str (b, bp);
+ set_str (c, cp);
+ set_str (d, dp);
+
+ free (ap);
+ free (bp);
+ free (cp);
+ free (dp);
+}
+
+void
+mini_random_bit_op (enum hex_random_op op, unsigned long maxbits,
+ mpz_t a, mp_bitcnt_t *b, mpz_t r)
+{
+ char *ap;
+ char *rp;
+
+ hex_random_bit_op (op, maxbits, &ap, b, &rp);
+ set_str (a, ap);
+ set_str (r, rp);
+
+ free (ap);
+ free (rp);
+}
+
+void
+mini_random_scan_op (enum hex_random_op op, unsigned long maxbits,
+ mpz_t a, mp_bitcnt_t *b, mp_bitcnt_t *r)
+{
+ char *ap;
+
+ hex_random_scan_op (op, maxbits, &ap, b, r);
+ set_str (a, ap);
+
+ free (ap);
+}
diff --git a/gmp/mini-gmp/tests/mini-random.h b/gmp/mini-gmp/tests/mini-random.h
new file mode 100644
index 0000000000..f36c56fc82
--- /dev/null
+++ b/gmp/mini-gmp/tests/mini-random.h
@@ -0,0 +1,33 @@
+/*
+
+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 "mini-gmp.h"
+#include "hex-random.h"
+
+void mini_urandomb (mpz_t, unsigned long);
+void mini_rrandomb (mpz_t, unsigned long);
+void mini_rrandomb_export (mpz_t r, void *dst, size_t *countp,
+ int order, size_t size, int endian,
+ unsigned long bits);
+
+void mini_random_op2 (enum hex_random_op, unsigned long, mpz_t, mpz_t);
+void mini_random_op3 (enum hex_random_op, unsigned long, mpz_t, mpz_t, mpz_t);
+void mini_random_op4 (enum hex_random_op, unsigned long, mpz_t, mpz_t, mpz_t, mpz_t);
+void mini_random_scan_op (enum hex_random_op, unsigned long, mpz_t, mp_bitcnt_t *, mp_bitcnt_t *);
+void mini_random_bit_op (enum hex_random_op, unsigned long, mpz_t, mp_bitcnt_t *, mpz_t);
diff --git a/gmp/mini-gmp/tests/run-tests b/gmp/mini-gmp/tests/run-tests
new file mode 100755
index 0000000000..5fc2952d76
--- /dev/null
+++ b/gmp/mini-gmp/tests/run-tests
@@ -0,0 +1,123 @@
+#! /bin/sh
+
+# Copyright (C) 2000-2002, 2004, 2005, 2011, 2012 Niels Möller
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+failed=0
+all=0
+
+debug='no'
+testflags=''
+
+if [ -z "$srcdir" ] ; then
+ srcdir=`pwd`
+fi
+
+export srcdir
+
+# When used in make rules, we sometimes get the filenames VPATH
+# expanded, but usually not.
+find_program () {
+ case "$1" in
+ */*)
+ echo "$1"
+ ;;
+ *)
+ if [ -x "$1" ] ; then
+ echo "./$1"
+ else
+ echo "$srcdir/$1"
+ fi
+ ;;
+ esac
+}
+
+env_program () {
+ if [ -x "$1" ] ; then
+ if "$1"; then : ; else
+ echo FAIL: $1
+ exit 1
+ fi
+ fi
+}
+
+test_program () {
+ testname=`basename "$1" .exe`
+ testname=`basename "$testname" -test`
+ if [ -z "$EMULATOR" ] || head -1 "$1" | grep '^#!' > /dev/null; then
+ "$1" $testflags
+ else
+ $EMULATOR "$1" $testflags
+ fi
+ case "$?" in
+ 0)
+ echo PASS: $testname
+ all=`expr $all + 1`
+ ;;
+ 77)
+ echo SKIP: $testname
+ ;;
+ *)
+ echo FAIL: $testname
+ failed=`expr $failed + 1`
+ all=`expr $all + 1`
+ ;;
+ esac
+}
+
+env_program `find_program setup-env`
+
+while test $# != 0
+do
+ case "$1" in
+ --debug)
+ debug=yes
+ ;;
+ -v)
+ testflags='-v'
+ ;;
+ -*)
+ echo >&2 'Unknown option `'"$1'"
+ exit 1
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+if [ $# -eq 0 ] ; then
+ for f in *-test; do test_program "./$f"; done
+else
+ for f in "$@" ; do test_program `find_program "$f"`; done
+fi
+
+if [ $failed -eq 0 ] ; then
+ banner="All $all tests passed"
+else
+ banner="$failed of $all tests failed"
+fi
+dashes=`echo "$banner" | sed s/./=/g`
+echo "$dashes"
+echo "$banner"
+echo "$dashes"
+
+if [ "x$debug" = xno ] ; then
+ env_program `find_program teardown-env`
+fi
+
+[ "$failed" -eq 0 ]
diff --git a/gmp/mini-gmp/tests/t-add.c b/gmp/mini-gmp/tests/t-add.c
new file mode 100644
index 0000000000..0a093efd90
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-add.c
@@ -0,0 +1,57 @@
+/*
+
+Copyright 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 <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, res, ref;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (res);
+ mpz_init (ref);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op3 (OP_ADD, MAXBITS, a, b, ref);
+ mpz_add (res, a, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_add failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (res);
+ mpz_clear (ref);
+}
diff --git a/gmp/mini-gmp/tests/t-aorsmul.c b/gmp/mini-gmp/tests/t-aorsmul.c
new file mode 100644
index 0000000000..eb275a8088
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-aorsmul.c
@@ -0,0 +1,77 @@
+/*
+
+Copyright 2012, 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
+#define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, res, ref;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init_set_ui (res, 5);
+ mpz_init (ref);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op3 (OP_MUL, MAXBITS, a, b, ref);
+ if (i & 1) {
+ mpz_add (ref, ref, res);
+ if (mpz_fits_ulong_p (b))
+ mpz_addmul_ui (res, a, mpz_get_ui (b));
+ else
+ mpz_addmul (res, a, b);
+ } else {
+ mpz_sub (ref, res, ref);
+ if (mpz_fits_ulong_p (b))
+ mpz_submul_ui (res, a, mpz_get_ui (b));
+ else
+ mpz_submul (res, a, b);
+ }
+ if (mpz_cmp (res, ref))
+ {
+ if (i & 1)
+ fprintf (stderr, "mpz_addmul failed:\n");
+ else
+ fprintf (stderr, "mpz_submul failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (res);
+ mpz_clear (ref);
+}
diff --git a/gmp/mini-gmp/tests/t-bitops.c b/gmp/mini-gmp/tests/t-bitops.c
new file mode 100644
index 0000000000..7e1688e662
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-bitops.c
@@ -0,0 +1,103 @@
+/*
+
+Copyright 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, res, ref;
+ mp_bitcnt_t b;
+
+ mpz_init (a);
+ mpz_init (res);
+ mpz_init (ref);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_bit_op (OP_SETBIT, MAXBITS, a, &b, ref);
+ mpz_set (res, a);
+ mpz_setbit (res, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_setbit failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "b: %lu\n", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ if (!mpz_tstbit (res, b))
+ {
+ fprintf (stderr, "mpz_tstbit failed (after mpz_setbit):\n");
+ dump ("res", a);
+ fprintf (stderr, "b: %lu\n", b);
+ abort ();
+ }
+ mini_random_bit_op (OP_CLRBIT, MAXBITS, a, &b, ref);
+ mpz_set (res, a);
+ mpz_clrbit (res, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_clrbit failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "b: %lu\n", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ if (mpz_tstbit (res, b))
+ {
+ fprintf (stderr, "mpz_tstbit failed (after mpz_clrbit):\n");
+ dump ("res", a);
+ fprintf (stderr, "b: %lu\n", b);
+ abort ();
+ }
+ mini_random_bit_op (OP_COMBIT, MAXBITS, a, &b, ref);
+ mpz_set (res, a);
+ mpz_combit (res, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_combit failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "b: %lu\n", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ if (mpz_tstbit (res, b) == mpz_tstbit (a, b))
+ {
+ fprintf (stderr, "mpz_tstbit failed (after mpz_combit):\n");
+ dump ("res", a);
+ fprintf (stderr, "b: %lu\n", b);
+ abort ();
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (res);
+ mpz_clear (ref);
+}
diff --git a/gmp/mini-gmp/tests/t-cmp_d.c b/gmp/mini-gmp/tests/t-cmp_d.c
new file mode 100644
index 0000000000..4eab278527
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-cmp_d.c
@@ -0,0 +1,283 @@
+/* Test mpz_cmp_d and mpz_cmpabs_d.
+
+Copyright 2001-2003, 2005, 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 <math.h>
+
+#include "testutils.h"
+
+/* FIXME: Not sure if the tests here are exhaustive. Ought to try to get
+ each possible exit from mpz_cmp_d (and mpz_cmpabs_d) exercised. */
+
+
+#define SGN(n) ((n) > 0 ? 1 : (n) < 0 ? -1 : 0)
+
+
+void
+check_one (const char *name, mpz_srcptr x, double y, int cmp, int cmpabs)
+{
+ int got;
+
+ got = mpz_cmp_d (x, y);
+ if (SGN(got) != cmp)
+ {
+ int i;
+ printf ("mpz_cmp_d wrong (from %s)\n", name);
+ printf (" got %d\n", got);
+ printf (" want %d\n", cmp);
+ fail:
+ printf (" x=");
+ mpz_out_str (stdout, 10, x);
+ printf ("\n y %g\n", y);
+ printf (" x=0x");
+ mpz_out_str (stdout, -16, x);
+ printf ("\n y %g\n", y);
+ printf (" y");
+ for (i = 0; i < sizeof(y); i++)
+ printf (" %02X", (unsigned) ((unsigned char *) &y)[i]);
+ printf ("\n");
+ abort ();
+ }
+
+ got = mpz_cmpabs_d (x, y);
+ if (SGN(got) != cmpabs)
+ {
+ printf ("mpz_cmpabs_d wrong\n");
+ printf (" got %d\n", got);
+ printf (" want %d\n", cmpabs);
+ goto fail;
+ }
+}
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *x;
+ double y;
+ int cmp, cmpabs;
+
+ } data[] = {
+
+ { "0", 0.0, 0, 0 },
+
+ { "1", 0.0, 1, 1 },
+ { "-1", 0.0, -1, 1 },
+
+ { "1", 0.5, 1, 1 },
+ { "-1", -0.5, -1, 1 },
+
+ { "0", 1.0, -1, -1 },
+ { "0", -1.0, 1, -1 },
+
+ { "0x1000000000000000000000000000000000000000000000000", 1.0, 1, 1 },
+ { "-0x1000000000000000000000000000000000000000000000000", 1.0, -1, 1 },
+
+ { "0", 1e100, -1, -1 },
+ { "0", -1e100, 1, -1 },
+
+ { "2", 1.5, 1, 1 },
+ { "2", -1.5, 1, 1 },
+ { "-2", 1.5, -1, 1 },
+ { "-2", -1.5, -1, 1 },
+ };
+
+ mpz_t x;
+ int i;
+
+ mpz_init (x);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (x, data[i].x, 0);
+ check_one ("check_data", x, data[i].y, data[i].cmp, data[i].cmpabs);
+ }
+
+ mpz_clear (x);
+}
+
+
+/* Equality of integers with up to 53 bits */
+void
+check_onebits (void)
+{
+ mpz_t x, x2;
+ double y;
+ int i;
+
+ mpz_init_set_ui (x, 0L);
+ mpz_init (x2);
+
+ for (i = 0; i < 512; i++)
+ {
+ mpz_mul_2exp (x, x, 1);
+ mpz_add_ui (x, x, 1L);
+
+ y = mpz_get_d (x);
+ mpz_set_d (x2, y);
+
+ /* stop if any truncation is occurring */
+ if (mpz_cmp (x, x2) != 0)
+ break;
+
+ check_one ("check_onebits", x, y, 0, 0);
+ check_one ("check_onebits", x, -y, 1, 0);
+ mpz_neg (x, x);
+ check_one ("check_onebits", x, y, -1, 0);
+ check_one ("check_onebits", x, -y, 0, 0);
+ mpz_neg (x, x);
+ }
+
+ mpz_clear (x);
+ mpz_clear (x2);
+}
+
+
+/* With the mpz differing by 1, in a limb position possibly below the double */
+void
+check_low_z_one (void)
+{
+ mpz_t x;
+ double y;
+ unsigned long i;
+
+ mpz_init (x);
+
+ /* FIXME: It'd be better to base this on the float format. */
+#if defined (__vax) || defined (__vax__)
+#define LIM 127 /* vax fp numbers have limited range */
+#else
+#define LIM 512
+#endif
+
+ for (i = 1; i < LIM; i++)
+ {
+ mpz_set_ui (x, 1L);
+ mpz_mul_2exp (x, x, i);
+ y = mpz_get_d (x);
+
+ check_one ("check_low_z_one", x, y, 0, 0);
+ check_one ("check_low_z_one", x, -y, 1, 0);
+ mpz_neg (x, x);
+ check_one ("check_low_z_one", x, y, -1, 0);
+ check_one ("check_low_z_one", x, -y, 0, 0);
+ mpz_neg (x, x);
+
+ mpz_sub_ui (x, x, 1);
+
+ check_one ("check_low_z_one", x, y, -1, -1);
+ check_one ("check_low_z_one", x, -y, 1, -1);
+ mpz_neg (x, x);
+ check_one ("check_low_z_one", x, y, -1, -1);
+ check_one ("check_low_z_one", x, -y, 1, -1);
+ mpz_neg (x, x);
+
+ mpz_add_ui (x, x, 2);
+
+ check_one ("check_low_z_one", x, y, 1, 1);
+ check_one ("check_low_z_one", x, -y, 1, 1);
+ mpz_neg (x, x);
+ check_one ("check_low_z_one", x, y, -1, 1);
+ check_one ("check_low_z_one", x, -y, -1, 1);
+ mpz_neg (x, x);
+ }
+
+ mpz_clear (x);
+}
+
+/* Comparing 1 and 1+2^-n. "y" is volatile to make gcc store and fetch it,
+ which forces it to a 64-bit double, whereas on x86 it would otherwise
+ remain on the float stack as an 80-bit long double. */
+void
+check_one_2exp (void)
+{
+ double e;
+ mpz_t x;
+ volatile double y;
+ int i;
+
+ mpz_init (x);
+
+ e = 1.0;
+ for (i = 0; i < 128; i++)
+ {
+ e /= 2.0;
+ y = 1.0 + e;
+ if (y == 1.0)
+ break;
+
+ mpz_set_ui (x, 1L);
+ check_one ("check_one_2exp", x, y, -1, -1);
+ check_one ("check_one_2exp", x, -y, 1, -1);
+
+ mpz_set_si (x, -1L);
+ check_one ("check_one_2exp", x, y, -1, -1);
+ check_one ("check_one_2exp", x, -y, 1, -1);
+ }
+
+ mpz_clear (x);
+}
+
+void
+check_infinity (void)
+{
+ mpz_t x;
+ double y = HUGE_VAL;
+ if (y != 2*y)
+ return;
+
+ mpz_init (x);
+
+ /* 0 cmp inf */
+ mpz_set_ui (x, 0L);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ /* 123 cmp inf */
+ mpz_set_ui (x, 123L);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ /* -123 cmp inf */
+ mpz_set_si (x, -123L);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ /* 2^5000 cmp inf */
+ mpz_set_ui (x, 1L);
+ mpz_mul_2exp (x, x, 5000L);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ /* -2^5000 cmp inf */
+ mpz_neg (x, x);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ mpz_clear (x);
+}
+
+void
+testmain (int argc, char *argv[])
+{
+ check_data ();
+ check_onebits ();
+ check_low_z_one ();
+ check_one_2exp ();
+ check_infinity ();
+}
diff --git a/gmp/mini-gmp/tests/t-comb.c b/gmp/mini-gmp/tests/t-comb.c
new file mode 100644
index 0000000000..31ee5a6ad6
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-comb.c
@@ -0,0 +1,164 @@
+/* Exercise mpz_fac_ui and mpz_bin_uiui.
+
+Copyright 2000-2002, 2012, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "testutils.h"
+
+/* Usage: t-fac_ui [x|num]
+
+ With no arguments testing goes up to the initial value of "limit" below.
+ With a number argument tests are carried that far, or with a literal "x"
+ tests are continued without limit (this being meant only for development
+ purposes). */
+
+void
+try_mpz_bin_uiui (mpz_srcptr want, unsigned long n, unsigned long k)
+{
+ mpz_t got;
+
+ mpz_init (got);
+ mpz_bin_uiui (got, n, k);
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_bin_uiui wrong\n");
+ printf (" n=%lu\n", n);
+ printf (" k=%lu\n", k);
+ printf (" got="); mpz_out_str (stdout, 10, got); printf ("\n");
+ printf (" want="); mpz_out_str (stdout, 10, want); printf ("\n");
+ abort();
+ }
+ mpz_clear (got);
+}
+
+/* Test all bin(n,k) cases, with 0 <= k <= n + 1 <= count. */
+void
+bin_smallexaustive (unsigned int count)
+{
+ mpz_t want;
+ unsigned long n, k;
+
+ mpz_init (want);
+
+ for (n = 0; n < count; n++)
+ {
+ mpz_set_ui (want, 1);
+ for (k = 0; k <= n; k++)
+ {
+ try_mpz_bin_uiui (want, n, k);
+ mpz_mul_ui (want, want, n - k);
+ mpz_fdiv_q_ui (want, want, k + 1);
+ }
+ try_mpz_bin_uiui (want, n, k);
+ }
+
+ mpz_clear (want);
+}
+
+/* Test all fac(n) cases, with 0 <= n <= limit. */
+void
+fac_smallexaustive (unsigned int limit)
+{
+ mpz_t f, r;
+ unsigned long n;
+ mpz_init_set_si (f, 1); /* 0! = 1 */
+ mpz_init (r);
+
+ for (n = 0; n < limit; n++)
+ {
+ mpz_fac_ui (r, n);
+
+ if (mpz_cmp (f, r) != 0)
+ {
+ printf ("mpz_fac_ui(%lu) wrong\n", n);
+ printf (" got "); mpz_out_str (stdout, 10, r); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, f); printf("\n");
+ abort ();
+ }
+
+ mpz_mul_ui (f, f, n+1); /* (n+1)! = n! * (n+1) */
+ }
+
+ mpz_clear (f);
+ mpz_clear (r);
+}
+
+void checkWilson (mpz_t f, unsigned long n)
+{
+ unsigned long m;
+
+ mpz_fac_ui (f, n - 1);
+ m = mpz_fdiv_ui (f, n);
+ if ( m != n - 1)
+ {
+ printf ("mpz_fac_ui(%lu) wrong\n", n - 1);
+ printf (" Wilson's theorem not verified: got %lu, expected %lu.\n",m ,n - 1);
+ abort ();
+ }
+}
+
+void
+checkprimes (unsigned long p1, unsigned long p2, unsigned long p3)
+{
+ mpz_t b, f;
+
+ if (p1 - 1 != p2 - 1 + p3 - 1)
+ {
+ printf ("checkprimes(%lu, %lu, %lu) wrong\n", p1, p2, p3);
+ printf (" %lu - 1 != %lu - 1 + %lu - 1 \n", p1, p2, p3);
+ abort ();
+ }
+
+ mpz_init (b);
+ mpz_init (f);
+
+ checkWilson (b, p1); /* b = (p1-1)! */
+ checkWilson (f, p2); /* f = (p2-1)! */
+ mpz_divexact (b, b, f);
+ checkWilson (f, p3); /* f = (p3-1)! */
+ mpz_divexact (b, b, f); /* b = (p1-1)!/((p2-1)!(p3-1)!) */
+ mpz_bin_uiui (f, p1 - 1, p2 - 1);
+ if (mpz_cmp (f, b) != 0)
+ {
+ printf ("checkprimes(%lu, %lu, %lu) wrong\n", p1, p2, p3);
+ printf (" got "); mpz_out_str (stdout, 10, b); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, f); printf("\n");
+ abort ();
+ }
+
+ mpz_clear (b);
+ mpz_clear (f);
+
+}
+
+void
+testmain (int argc, char *argv[])
+{
+ unsigned long limit = 128;
+
+ if (argc > 1 && argv[1][0] == 'x')
+ limit = ~ limit;
+ else if (argc > 1)
+ limit = atoi (argv[1]);
+
+ checkprimes(1009, 733, 277);
+ fac_smallexaustive (limit);
+ bin_smallexaustive (limit);
+}
diff --git a/gmp/mini-gmp/tests/t-cong.c b/gmp/mini-gmp/tests/t-cong.c
new file mode 100644
index 0000000000..8ddfe9bf46
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-cong.c
@@ -0,0 +1,212 @@
+/* test mpz_congruent_p
+
+Copyright 2001, 2002, 2012, 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 "testutils.h"
+
+#define MPZ_SRCPTR_SWAP(x, y) \
+ do { \
+ mpz_srcptr __mpz_srcptr_swap__tmp = (x); \
+ (x) = (y); \
+ (y) = __mpz_srcptr_swap__tmp; \
+ } while (0)
+
+void
+check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want)
+{
+ int got;
+ int swap;
+
+ for (swap = 0; swap <= 1; swap++)
+ {
+ got = (mpz_congruent_p (a, c, d) != 0);
+ if (want != got)
+ {
+ printf ("mpz_congruent_p wrong\n");
+ printf (" expected %d got %d\n", want, got);
+ dump (" a", a);
+ dump (" c", c);
+ dump (" d", d);
+ abort ();
+ }
+
+#if 0
+ if (mpz_fits_ulong_p (c) && mpz_fits_ulong_p (d))
+ {
+ unsigned long uc = mpz_get_ui (c);
+ unsigned long ud = mpz_get_ui (d);
+ got = (mpz_congruent_ui_p (a, uc, ud) != 0);
+ if (want != got)
+ {
+ printf ("mpz_congruent_ui_p wrong\n");
+ printf (" expected %d got %d\n", want, got);
+ dump (" a", a);
+ printf (" c=%lu\n", uc);
+ printf (" d=%lu\n", ud);
+ abort ();
+ }
+ }
+#endif
+ MPZ_SRCPTR_SWAP (a, c);
+ }
+}
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *a;
+ const char *c;
+ const char *d;
+ int want;
+
+ } data[] = {
+
+ /* strict equality mod 0 */
+ { "0", "0", "0", 1 },
+ { "11", "11", "0", 1 },
+ { "3", "11", "0", 0 },
+
+ /* anything congruent mod 1 */
+ { "0", "0", "1", 1 },
+ { "1", "0", "1", 1 },
+ { "0", "1", "1", 1 },
+ { "123", "456", "1", 1 },
+ { "0x123456789123456789", "0x987654321987654321", "1", 1 },
+
+ /* csize==1, dsize==2 changing to 1 after stripping 2s */
+ { "0x3333333333333333", "0x33333333",
+ "0x180000000", 1 },
+ { "0x33333333333333333333333333333333", "0x3333333333333333",
+ "0x18000000000000000", 1 },
+
+ /* another dsize==2 becoming 1, with opposite signs this time */
+ { "0x444444441",
+ "-0x22222221F",
+ "0x333333330", 1 },
+ { "0x44444444444444441",
+ "-0x2222222222222221F",
+ "0x33333333333333330", 1 },
+ };
+
+ mpz_t a, c, d;
+ int i;
+
+ mpz_init (a);
+ mpz_init (c);
+ mpz_init (d);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (a, data[i].a, 0);
+ mpz_set_str_or_abort (c, data[i].c, 0);
+ mpz_set_str_or_abort (d, data[i].d, 0);
+ check_one (a, c, d, data[i].want);
+ }
+
+ mpz_clear (a);
+ mpz_clear (c);
+ mpz_clear (d);
+}
+
+
+void
+check_random (int argc, char *argv[])
+{
+ mpz_t a, c, d, ra, rc;
+ int i;
+ int want;
+ int reps = 10000;
+ mpz_t bs;
+ unsigned long size_range, size;
+
+ if (argc >= 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (bs);
+
+ mpz_init (a);
+ mpz_init (c);
+ mpz_init (d);
+ mpz_init (ra);
+ mpz_init (rc);
+
+ for (i = 0; i < reps; i++)
+ {
+ mini_urandomb (bs, 32);
+ size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
+
+ mini_urandomb (bs, size_range);
+ size = mpz_get_ui (bs);
+ mini_rrandomb (a, size);
+
+ mini_urandomb (bs, 32);
+ size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
+
+ mini_urandomb (bs, size_range);
+ size = mpz_get_ui (bs);
+ mini_rrandomb (c, size);
+
+ do
+ {
+ mini_urandomb (bs, 32);
+ size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
+
+ mini_urandomb (bs, size_range);
+ size = mpz_get_ui (bs);
+ mini_rrandomb (d, size);
+ }
+ while (mpz_sgn(d) == 0);
+
+ mini_urandomb (bs, 3);
+ if (mpz_tstbit (bs, 0))
+ mpz_neg (a, a);
+ if (mpz_tstbit (bs, 1))
+ mpz_neg (c, c);
+ if (mpz_tstbit (bs, 2))
+ mpz_neg (d, d);
+
+ mpz_fdiv_r (ra, a, d);
+ mpz_fdiv_r (rc, c, d);
+
+ want = (mpz_cmp (ra, rc) == 0);
+ check_one (a, c, d, want);
+
+ mpz_sub (ra, ra, rc);
+ mpz_sub (a, a, ra);
+ check_one (a, c, d, 1);
+
+ }
+
+ mpz_clear (bs);
+
+ mpz_clear (a);
+ mpz_clear (c);
+ mpz_clear (d);
+ mpz_clear (ra);
+ mpz_clear (rc);
+}
+
+
+void
+testmain (int argc, char *argv[])
+{
+ check_data ();
+ check_random (argc, argv);
+}
diff --git a/gmp/mini-gmp/tests/t-div.c b/gmp/mini-gmp/tests/t-div.c
new file mode 100644
index 0000000000..a114a0f180
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-div.c
@@ -0,0 +1,254 @@
+/*
+
+Copyright 2012, 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 <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+typedef void div_qr_func (mpz_t, mpz_t, const mpz_t, const mpz_t);
+typedef unsigned long div_qr_ui_func (mpz_t, mpz_t, const mpz_t, unsigned long);
+typedef void div_func (mpz_t, const mpz_t, const mpz_t);
+typedef unsigned long div_x_ui_func (mpz_t, const mpz_t, unsigned long);
+typedef unsigned long div_ui_func (const mpz_t, unsigned long);
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, q, r, rq, rr;
+ int div_p;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (r);
+ mpz_init (q);
+ mpz_init (rr);
+ mpz_init (rq);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ unsigned j;
+ for (j = 0; j < 3; j++)
+ {
+ static const enum hex_random_op ops[3] = { OP_CDIV, OP_FDIV, OP_TDIV };
+ static const char name[3] = { 'c', 'f', 't'};
+ static div_qr_func * const div_qr [3] =
+ {
+ mpz_cdiv_qr, mpz_fdiv_qr, mpz_tdiv_qr
+ };
+ static div_qr_ui_func *div_qr_ui[3] =
+ {
+ mpz_cdiv_qr_ui, mpz_fdiv_qr_ui, mpz_tdiv_qr_ui
+ };
+ static div_func * const div_q [3] =
+ {
+ mpz_cdiv_q, mpz_fdiv_q, mpz_tdiv_q
+ };
+ static div_x_ui_func *div_q_ui[3] =
+ {
+ mpz_cdiv_q_ui, mpz_fdiv_q_ui, mpz_tdiv_q_ui
+ };
+ static div_func * const div_r [3] =
+ {
+ mpz_cdiv_r, mpz_fdiv_r, mpz_tdiv_r
+ };
+ static div_x_ui_func *div_r_ui[3] =
+ {
+ mpz_cdiv_r_ui, mpz_fdiv_r_ui, mpz_tdiv_r_ui
+ };
+ static div_ui_func *div_ui[3] =
+ {
+ mpz_cdiv_ui, mpz_fdiv_ui, mpz_tdiv_ui
+ };
+
+ mini_random_op4 (ops[j], MAXBITS, a, b, rq, rr);
+ div_qr[j] (q, r, a, b);
+ if (mpz_cmp (r, rr) || mpz_cmp (q, rq))
+ {
+ fprintf (stderr, "mpz_%cdiv_qr failed:\n", name[j]);
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r ", r);
+ dump ("rref", rr);
+ dump ("q ", q);
+ dump ("qref", rq);
+ abort ();
+ }
+ mpz_set_si (q, -5);
+ div_q[j] (q, a, b);
+ if (mpz_cmp (q, rq))
+ {
+ fprintf (stderr, "mpz_%cdiv_q failed:\n", name[j]);
+ dump ("a", a);
+ dump ("b", b);
+ dump ("q ", q);
+ dump ("qref", rq);
+ abort ();
+ }
+ mpz_set_ui (r, ~5);
+ div_r[j] (r, a, b);
+ if (mpz_cmp (r, rr))
+ {
+ fprintf (stderr, "mpz_%cdiv_r failed:\n", name[j]);
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r ", r);
+ dump ("rref", rr);
+ abort ();
+ }
+
+ if (j == 0) /* do this once, not for all roundings */
+ {
+ div_p = mpz_divisible_p (a, b);
+ if ((mpz_sgn (r) == 0) ^ (div_p != 0))
+ {
+ fprintf (stderr, "mpz_divisible_p failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r ", r);
+ abort ();
+ }
+ }
+
+ if (j == 0 && mpz_sgn (b) < 0) /* ceil, negative divisor */
+ {
+ mpz_mod (r, a, b);
+ if (mpz_cmp (r, rr))
+ {
+ fprintf (stderr, "mpz_mod failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r ", r);
+ dump ("rref", rr);
+ abort ();
+ }
+ }
+
+ if (j == 1 && mpz_sgn (b) > 0) /* floor, positive divisor */
+ {
+ mpz_mod (r, a, b);
+ if (mpz_cmp (r, rr))
+ {
+ fprintf (stderr, "mpz_mod failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r ", r);
+ dump ("rref", rr);
+ abort ();
+ }
+ }
+
+ if (mpz_fits_ulong_p (b))
+ {
+ mp_limb_t rl;
+
+ rl = div_qr_ui[j] (q, r, a, mpz_get_ui (b));
+ if (rl != mpz_get_ui (rr)
+ || mpz_cmp (r, rr) || mpz_cmp (q, rq))
+ {
+ fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
+ dump ("a", a);
+ dump ("b", b);
+ fprintf(stderr, "rl = %lx\n", rl);
+ dump ("r ", r);
+ dump ("rref", rr);
+ dump ("q ", q);
+ dump ("qref", rq);
+ abort ();
+ }
+
+ mpz_set_si (q, 3);
+ rl = div_q_ui[j] (q, a, mpz_get_ui (b));
+ if (rl != mpz_get_ui (rr) || mpz_cmp (q, rq))
+ {
+ fprintf (stderr, "mpz_%cdiv_q_ui failed:\n", name[j]);
+ dump ("a", a);
+ dump ("b", b);
+ fprintf(stderr, "rl = %lx\n", rl);
+ dump ("rref", rr);
+ dump ("q ", q);
+ dump ("qref", rq);
+ abort ();
+ }
+
+ mpz_set_ui (r, 7);
+ rl = div_r_ui[j] (r, a, mpz_get_ui (b));
+ if (rl != mpz_get_ui (rr) || mpz_cmp (r, rr))
+ {
+ fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
+ dump ("a", a);
+ dump ("b", b);
+ fprintf(stderr, "rl = %lx\n", rl);
+ dump ("r ", r);
+ dump ("rref", rr);
+ abort ();
+ }
+
+ rl = div_ui[j] (a, mpz_get_ui (b));
+ if (rl != mpz_get_ui (rr))
+ {
+ fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]);
+ dump ("a", a);
+ dump ("b", b);
+ fprintf(stderr, "rl = %lx\n", rl);
+ dump ("rref", rr);
+ abort ();
+ }
+
+ if (j == 0) /* do this once, not for all roundings */
+ {
+ div_p = mpz_divisible_ui_p (a, mpz_get_ui (b));
+ if ((mpz_sgn (r) == 0) ^ (div_p != 0))
+ {
+ fprintf (stderr, "mpz_divisible_ui_p failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r ", r);
+ abort ();
+ }
+ }
+
+ if (j == 1) /* floor */
+ {
+ mpz_mod_ui (r, a, mpz_get_ui (b));
+ if (mpz_cmp (r, rr))
+ {
+ fprintf (stderr, "mpz_mod failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r ", r);
+ dump ("rref", rr);
+ abort ();
+ }
+ }
+ }
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (r);
+ mpz_clear (q);
+ mpz_clear (rr);
+ mpz_clear (rq);
+}
diff --git a/gmp/mini-gmp/tests/t-div_2exp.c b/gmp/mini-gmp/tests/t-div_2exp.c
new file mode 100644
index 0000000000..53d3f2b84d
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-div_2exp.c
@@ -0,0 +1,82 @@
+/*
+
+Copyright 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 <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+typedef void div_func (mpz_t, const mpz_t, mp_bitcnt_t);
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, res, ref;
+ mp_bitcnt_t b;
+
+ mpz_init (a);
+ mpz_init (res);
+ mpz_init (ref);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ unsigned j;
+ for (j = 0; j < 6; j++)
+ {
+ static const enum hex_random_op ops[6] =
+ {
+ OP_CDIV_Q_2, OP_CDIV_R_2,
+ OP_FDIV_Q_2, OP_FDIV_R_2,
+ OP_TDIV_Q_2, OP_TDIV_R_2
+ };
+ static const char *name[6] =
+ {
+ "cdiv_q", "cdiv_r",
+ "fdiv_q", "fdiv_r",
+ "tdiv_q", "tdiv_r"
+ };
+ static div_func * const div [6] =
+ {
+ mpz_cdiv_q_2exp, mpz_cdiv_r_2exp,
+ mpz_fdiv_q_2exp, mpz_fdiv_r_2exp,
+ mpz_tdiv_q_2exp, mpz_tdiv_r_2exp
+ };
+
+ mini_random_bit_op (ops[j], MAXBITS, a, &b, ref);
+ div[j] (res, a, b);
+ if (mpz_cmp (ref, res))
+ {
+ fprintf (stderr, "mpz_%s_2exp failed:\n", name[j]);
+ dump ("a", a);
+ fprintf (stderr, "b: %lu\n", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (res);
+ mpz_clear (ref);
+}
diff --git a/gmp/mini-gmp/tests/t-double.c b/gmp/mini-gmp/tests/t-double.c
new file mode 100644
index 0000000000..9e8101ecfd
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-double.c
@@ -0,0 +1,138 @@
+/*
+
+Copyright 2012, 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 <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "testutils.h"
+
+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
+
+#define COUNT 10000
+
+static const struct
+{
+ double d;
+ const char *s;
+} values[] = {
+ { 0.0, "0" },
+ { 0.3, "0" },
+ { -0.3, "0" },
+ { M_PI, "3" },
+ { M_PI*1e15, "b29430a256d21" },
+ { -M_PI*1e15, "-b29430a256d21" },
+ /* 17 * 2^{200} =
+ 27317946752402834684213355569799764242877450894307478200123392 */
+ {0.2731794675240283468421335556979976424288e62,
+ "1100000000000000000000000000000000000000000000000000" },
+ { 0.0, NULL }
+};
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t x;
+
+ for (i = 0; values[i].s; i++)
+ {
+ char *s;
+ mpz_init_set_d (x, values[i].d);
+ s = mpz_get_str (NULL, 16, x);
+ if (strcmp (s, values[i].s) != 0)
+ {
+ fprintf (stderr, "mpz_set_d failed:\n"
+ "d = %.20g\n"
+ "s = %s\n"
+ "r = %s\n",
+ values[i].d, s, values[i].s);
+ abort ();
+ }
+ testfree (s);
+ mpz_clear (x);
+ }
+
+ mpz_init (x);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ /* Use volatile, to avoid extended precision in floating point
+ registers, e.g., on m68k and 80387. */
+ volatile double d, f;
+ unsigned long m;
+ int e;
+
+ mini_rrandomb (x, GMP_LIMB_BITS);
+ m = mpz_get_ui (x);
+ mini_urandomb (x, 8);
+ e = mpz_get_ui (x) - 100;
+
+ d = ldexp ((double) m, e);
+ mpz_set_d (x, d);
+ f = mpz_get_d (x);
+ if (f != floor (d))
+ {
+ fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n");
+ goto dumperror;
+ }
+ if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) >= 0))
+ {
+ fprintf (stderr, "mpz_cmp_d (x, d) failed:\n");
+ goto dumperror;
+ }
+ f = d + 1.0;
+ if (f > d && ! (mpz_cmp_d (x, f) < 0))
+ {
+ fprintf (stderr, "mpz_cmp_d (x, f) failed:\n");
+ goto dumperror;
+ }
+
+ d = - d;
+
+ mpz_set_d (x, d);
+ f = mpz_get_d (x);
+ if (f != ceil (d))
+ {
+ fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n");
+ dumperror:
+ dump ("x", x);
+ fprintf (stderr, "m = %lx, e = %i\n", m, e);
+ fprintf (stderr, "d = %.15g\n", d);
+ fprintf (stderr, "f = %.15g\n", f);
+ fprintf (stderr, "f - d = %.5g\n", f - d);
+ abort ();
+ }
+ if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) <= 0))
+ {
+ fprintf (stderr, "mpz_cmp_d (x, d) failed:\n");
+ goto dumperror;
+ }
+ f = d - 1.0;
+ if (f < d && ! (mpz_cmp_d (x, f) > 0))
+ {
+ fprintf (stderr, "mpz_cmp_d (x, f) failed:\n");
+ goto dumperror;
+ }
+ }
+
+ mpz_clear (x);
+}
diff --git a/gmp/mini-gmp/tests/t-gcd.c b/gmp/mini-gmp/tests/t-gcd.c
new file mode 100644
index 0000000000..1278000296
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-gcd.c
@@ -0,0 +1,176 @@
+/*
+
+Copyright 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+/* Called when g is supposed to be gcd(a,b), and g = s a + t b. */
+static int
+gcdext_valid_p (const mpz_t a, const mpz_t b,
+ const mpz_t g, const mpz_t s, const mpz_t t)
+{
+ mpz_t ta, tb, r;
+
+ /* It's not clear that gcd(0,0) is well defined, but we allow it and
+ require that gcd(0,0) = 0. */
+ if (mpz_sgn (g) < 0)
+ return 0;
+
+ if (mpz_sgn (a) == 0)
+ {
+ /* Must have g == abs (b). Any value for s is in some sense "correct",
+ but it makes sense to require that s == 0. */
+ return mpz_cmpabs (g, b) == 0 && mpz_sgn (s) == 0;
+ }
+ else if (mpz_sgn (b) == 0)
+ {
+ /* Must have g == abs (a), s == sign (a) */
+ return mpz_cmpabs (g, a) == 0 && mpz_cmp_si (s, mpz_sgn (a)) == 0;
+ }
+
+ if (mpz_sgn (g) <= 0)
+ return 0;
+
+ mpz_init (ta);
+ mpz_init (tb);
+ mpz_init (r);
+
+ mpz_mul (ta, s, a);
+ mpz_mul (tb, t, b);
+ mpz_add (ta, ta, tb);
+
+ if (mpz_cmp (ta, g) != 0)
+ {
+ fail:
+ mpz_clear (ta);
+ mpz_clear (tb);
+ mpz_clear (r);
+ return 0;
+ }
+ mpz_tdiv_qr (ta, r, a, g);
+ if (mpz_sgn (r) != 0)
+ goto fail;
+
+ mpz_tdiv_qr (tb, r, b, g);
+ if (mpz_sgn (r) != 0)
+ goto fail;
+
+ /* Require that 2 |s| < |b/g|, or |s| == 1. */
+ if (mpz_cmpabs_ui (s, 1) > 0)
+ {
+ mpz_mul_2exp (r, s, 1);
+ if (mpz_cmpabs (r, tb) > 0)
+ goto fail;
+ }
+
+ /* Require that 2 |t| < |a/g| or |t| == 1*/
+ if (mpz_cmpabs_ui (t, 1) > 0)
+ {
+ mpz_mul_2exp (r, t, 1);
+ if (mpz_cmpabs (r, ta) > 0)
+ return 0;
+ }
+
+ mpz_clear (ta);
+ mpz_clear (tb);
+ mpz_clear (r);
+
+ return 1;
+}
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, g, s, t;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (g);
+ mpz_init (s);
+ mpz_init (t);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op3 (OP_GCD, MAXBITS, a, b, s);
+ mpz_gcd (g, a, b);
+ if (mpz_cmp (g, s))
+ {
+ fprintf (stderr, "mpz_gcd failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", g);
+ dump ("ref", s);
+ abort ();
+ }
+ }
+
+ for (i = 0; i < COUNT; i++)
+ {
+ unsigned flags;
+ mini_urandomb (a, 32);
+ flags = mpz_get_ui (a);
+ mini_rrandomb (a, MAXBITS);
+ mini_rrandomb (b, MAXBITS);
+
+ if (flags % 37 == 0)
+ mpz_mul (a, a, b);
+ if (flags % 37 == 1)
+ mpz_mul (b, a, b);
+
+ if (flags & 1)
+ mpz_neg (a, a);
+ if (flags & 2)
+ mpz_neg (b, b);
+
+ mpz_gcdext (g, s, t, a, b);
+ if (!gcdext_valid_p (a, b, g, s, t))
+ {
+ fprintf (stderr, "mpz_gcdext failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("g", g);
+ dump ("s", s);
+ dump ("t", t);
+ abort ();
+ }
+
+ mpz_gcd (s, a, b);
+ if (mpz_cmp (g, s))
+ {
+ fprintf (stderr, "mpz_gcd failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", g);
+ dump ("ref", s);
+ abort ();
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (g);
+ mpz_clear (s);
+ mpz_clear (t);
+}
diff --git a/gmp/mini-gmp/tests/t-import.c b/gmp/mini-gmp/tests/t-import.c
new file mode 100644
index 0000000000..66c9d5e8d5
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-import.c
@@ -0,0 +1,99 @@
+/*
+
+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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "testutils.h"
+
+#define MAX_WORDS 20
+#define MAX_WORD_SIZE 10
+
+static void
+dump_bytes (const char *label, const unsigned char *s, size_t n)
+{
+ size_t i;
+ fprintf (stderr, "%s:", label);
+ for (i = 0; i < n; i++)
+ {
+ if (i && (i % 16) == 0)
+ fprintf (stderr, "\n");
+ fprintf (stderr, " %02x", s[i]);
+ }
+ fprintf (stderr, "\n");
+}
+
+/* Tests both mpz_import and mpz_export. */
+void
+testmain (int argc, char **argv)
+{
+ unsigned char input[MAX_WORDS * MAX_WORD_SIZE];
+ unsigned char output[MAX_WORDS * MAX_WORD_SIZE + 2];
+ size_t count, in_count, out_count, size;
+ int endian, order;
+
+ mpz_t a, res;
+
+ mpz_init (a);
+ mpz_init (res);
+
+ for (size = 0; size <= MAX_WORD_SIZE; size++)
+ for (count = 0; count <= MAX_WORDS; count++)
+ for (endian = -1; endian <= 1; endian++)
+ for (order = -1; order <= 1; order += 2)
+ {
+ mini_rrandomb_export (a, input, &in_count,
+ order, size, endian, size*count * 8);
+ mpz_import (res, in_count, order, size, endian, 0, input);
+ if (mpz_cmp (a, res))
+ {
+ fprintf (stderr, "mpz_import failed:\n"
+ "in_count %lu, out_count %lu, endian = %d, order = %d\n",
+ (unsigned long) in_count, (unsigned long) out_count, endian, order);
+ dump ("a", a);
+ dump ("res", res);
+ abort ();
+ }
+ output[0] = 17;
+ output[1+in_count*size] = 17;
+
+ mpz_export (output+1, &out_count, order, size, endian, 0, a);
+ if (out_count != in_count
+ || memcmp (output+1, input, in_count * size)
+ || output[0] != 17
+ || output[1+in_count*size] != 17)
+ {
+ fprintf (stderr, "mpz_export failed:\n"
+ "in_count %lu, out_count %lu, endian = %d, order = %d\n",
+ (unsigned long) in_count, (unsigned long) out_count, endian, order);
+ dump_bytes ("input", input, in_count * size);
+ dump_bytes ("output", output+1, out_count * size);
+ if (output[0] != 17)
+ fprintf (stderr, "Overwrite at -1, value %02x\n", output[0]);
+ if (output[1+in_count*size] != 17)
+ fprintf (stderr, "Overwrite at %lu, value %02x\n",
+ (unsigned long) (in_count*size), output[1+in_count*size]);
+
+ abort ();
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (res);
+}
diff --git a/gmp/mini-gmp/tests/t-invert.c b/gmp/mini-gmp/tests/t-invert.c
new file mode 100644
index 0000000000..496e8d4f53
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-invert.c
@@ -0,0 +1,98 @@
+/*
+
+Copyright 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
+
+#define COUNT 10000
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t u, m, p, t;
+
+ mpz_init (u);
+ mpz_init (m);
+ mpz_init (p);
+ mpz_init (t);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_urandomb (u, GMP_LIMB_BITS);
+ mpz_setbit (u, GMP_LIMB_BITS -1);
+
+ mpz_set_ui (m, mpn_invert_limb (u->_mp_d[0]));
+ mpz_setbit (m, GMP_LIMB_BITS);
+
+ mpz_mul (p, m, u);
+
+ mpz_set_ui (t, 0);
+ mpz_setbit (t, 2* GMP_LIMB_BITS);
+ mpz_sub (t, t, p);
+
+ /* Should have 0 < B^2 - m u <= u */
+ if (mpz_sgn (t) <= 0 || mpz_cmp (t, u) > 0)
+ {
+ fprintf (stderr, "mpn_invert_limb failed:\n");
+ dump ("u", u);
+ dump ("m", m);
+ dump ("p", p);
+ dump ("t", t);
+ abort ();
+ }
+ }
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_urandomb (u, 2*GMP_LIMB_BITS);
+ mpz_setbit (u, 2*GMP_LIMB_BITS -1);
+
+ mpz_set_ui (m, mpn_invert_3by2 (u->_mp_d[1], u[0]._mp_d[0]));
+
+ mpz_setbit (m, GMP_LIMB_BITS);
+
+ mpz_mul (p, m, u);
+
+ mpz_set_ui (t, 0);
+ mpz_setbit (t, 3 * GMP_LIMB_BITS);
+ mpz_sub (t, t, p);
+
+ /* Should have 0 < B^3 - m u <= u */
+ if (mpz_sgn (t) <= 0 || mpz_cmp (t, u) > 0)
+ {
+ fprintf (stderr, "mpn_invert_3by2 failed:\n");
+ dump ("u", u);
+ dump ("m", m);
+ dump ("p", p);
+ dump ("t", t);
+ abort ();
+ }
+ }
+
+ mpz_clear (u);
+ mpz_clear (m);
+ mpz_clear (p);
+ mpz_clear (t);
+}
diff --git a/gmp/mini-gmp/tests/t-lcm.c b/gmp/mini-gmp/tests/t-lcm.c
new file mode 100644
index 0000000000..f21a39a66a
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-lcm.c
@@ -0,0 +1,73 @@
+/*
+
+Copyright 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, g, s;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (g);
+ mpz_init (s);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op3 (OP_LCM, MAXBITS, a, b, s);
+ mpz_lcm (g, a, b);
+ if (mpz_cmp (g, s))
+ {
+ fprintf (stderr, "mpz_lcm failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", g);
+ dump ("ref", s);
+ abort ();
+ }
+ if (mpz_fits_ulong_p (b))
+ {
+ mpz_set_si (g, 0);
+ mpz_lcm_ui (g, a, mpz_get_ui (b));
+ if (mpz_cmp (g, s))
+ {
+ fprintf (stderr, "mpz_lcm_ui failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", g);
+ dump ("ref", s);
+ abort ();
+ }
+ }
+ }
+
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (g);
+ mpz_clear (s);
+}
diff --git a/gmp/mini-gmp/tests/t-limbs.c b/gmp/mini-gmp/tests/t-limbs.c
new file mode 100644
index 0000000000..fa65782db2
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-limbs.c
@@ -0,0 +1,106 @@
+/*
+
+Copyright 2012, 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 100
+
+void
+my_mpz_mul (mpz_t r, mpz_srcptr a, mpz_srcptr b)
+{
+ mp_limb_t *tp;
+ mp_size_t tn, an, bn;
+
+ an = mpz_size (a);
+ bn = mpz_size (b);
+ tn = an + bn;
+
+ tp = mpz_limbs_write (r, tn);
+ if (mpz_sgn (a) * mpz_sgn(b) == 0)
+ mpn_zero (tp, tn);
+ else if (an > bn)
+ mpn_mul (tp, mpz_limbs_read (a), an, mpz_limbs_read (b), bn);
+ else
+ mpn_mul (tp, mpz_limbs_read (b), bn, mpz_limbs_read (a), an);
+
+ if (mpz_sgn (a) != mpz_sgn(b))
+ tn = - tn;
+
+ mpz_limbs_finish (r, tn);
+}
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, t, res, ref;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (res);
+ mpz_init (ref);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op3 (OP_MUL, MAXBITS, a, b, ref);
+ my_mpz_mul (res, a, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "my_mpz_mul failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ /* The following test exploits a side-effect of my_mpz_mul: res
+ points to a buffer with at least an+bn limbs, and the limbs
+ above the result are zeroed. */
+ if (mpz_size (b) > 0 && mpz_getlimbn (res, mpz_size(a)) != mpz_limbs_read (res) [mpz_size(a)])
+ {
+ fprintf (stderr, "getlimbn - limbs_read differ.\n");
+ abort ();
+ }
+ if ((i % 4 == 0) && mpz_size (res) > 1)
+ {
+ mpz_realloc2 (res, 1);
+ if (mpz_cmp_ui (res, 0))
+ {
+ fprintf (stderr, "mpz_realloc2 did not clear res.\n");
+ abort ();
+ }
+ mpz_limbs_finish (ref, 0);
+ if (mpz_cmp_d (ref, 0))
+ {
+ fprintf (stderr, "mpz_limbs_finish did not clear res.\n");
+ abort ();
+ }
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (res);
+ mpz_clear (ref);
+}
diff --git a/gmp/mini-gmp/tests/t-logops.c b/gmp/mini-gmp/tests/t-logops.c
new file mode 100644
index 0000000000..7e2d68187a
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-logops.c
@@ -0,0 +1,112 @@
+/*
+
+Copyright 2012, 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+void
+testlogops (int count)
+{
+ unsigned i;
+ mpz_t a, b, res, ref;
+ mp_bitcnt_t c;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (res);
+ mpz_init (ref);
+
+ for (i = 0; i < count; i++)
+ {
+ mini_random_op3 (OP_AND, MAXBITS, a, b, ref);
+ mpz_and (res, a, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_and failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+
+ mini_random_op3 (OP_IOR, MAXBITS, a, b, ref);
+ mpz_ior (res, a, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_ior failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+
+ mini_random_op3 (OP_XOR, MAXBITS, a, b, ref);
+ mpz_xor (res, a, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_xor failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+
+ if (i % 8) {
+ c = 0;
+ mpz_mul_2exp (res, res, i % 8);
+ } else if (mpz_sgn (res) >= 0) {
+ c = mpz_odd_p (res) != 0;
+ mpz_tdiv_q_2exp (res, res, 1);
+ } else {
+ c = (~ (mp_bitcnt_t) 0) - 3;
+ mpz_set_ui (res, 11 << ((i >> 3)%4)); /* set 3 bits */
+ }
+
+ if (mpz_popcount (res) + c != mpz_hamdist (a, b))
+ {
+ fprintf (stderr, "mpz_popcount(r) + %lu and mpz_hamdist(a,b) differ:\n", c);
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res);
+ fprintf (stderr, "mpz_popcount(r) = %lu:\n", mpz_popcount (res));
+ fprintf (stderr, "mpz_hamdist(a,b) = %lu:\n", mpz_hamdist (a, b));
+ abort ();
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (res);
+ mpz_clear (ref);
+}
+
+void
+testmain (int argc, char **argv)
+{
+ testhalves (COUNT*2/3, testlogops);
+ testlogops (COUNT/3);
+}
diff --git a/gmp/mini-gmp/tests/t-mul.c b/gmp/mini-gmp/tests/t-mul.c
new file mode 100644
index 0000000000..57ec4ed36c
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-mul.c
@@ -0,0 +1,113 @@
+/*
+
+Copyright 2012, 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
+#define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, res, res_ui, ref, tz;
+ mp_limb_t t[2*MAXLIMBS];
+ mp_size_t an;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (res);
+ mpz_init (res_ui);
+ mpz_init (ref);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op3 (OP_MUL, MAXBITS, a, b, ref);
+ mpz_mul (res, a, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_mul failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ if (mpz_size (a) == mpz_size (b))
+ {
+ memset (t, 0x55, sizeof(t));
+ an = mpz_size (a);
+ if (an > 0)
+ {
+ mpn_mul_n (t, a->_mp_d, b->_mp_d, an);
+
+ mpz_roinit_n (tz, t, 2*an);
+ if (mpz_cmpabs (tz, ref))
+ {
+ fprintf (stderr, "mpn_mul_n failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("ref", ref);
+ abort ();
+ }
+ }
+ }
+ if (mpz_fits_slong_p (b)) {
+ mpz_mul_si (res_ui, a, mpz_get_si (b));
+ if (mpz_cmp (res_ui, ref))
+ {
+ fprintf (stderr, "mpz_mul_si failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res_ui);
+ dump ("ref", ref);
+ abort ();
+ }
+ }
+ mini_random_op2 (OP_SQR, MAXBITS, a, ref);
+ an = mpz_size (a);
+ if (an > 0)
+ {
+ memset (t, 0x33, sizeof(t));
+ mpn_sqr (t, mpz_limbs_read (a), an);
+
+ mpz_roinit_n (tz, t, 2*an);
+ if (mpz_cmp (tz, ref))
+ {
+ fprintf (stderr, "mpn (squaring) failed:\n");
+ dump ("a", a);
+ dump ("ref", ref);
+ abort ();
+ }
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (res);
+ mpz_clear (res_ui);
+ mpz_clear (ref);
+}
diff --git a/gmp/mini-gmp/tests/t-powm.c b/gmp/mini-gmp/tests/t-powm.c
new file mode 100644
index 0000000000..d6c108d47a
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-powm.c
@@ -0,0 +1,61 @@
+/*
+
+Copyright 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 1000
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t b, e, m, res, ref;
+
+ mpz_init (b);
+ mpz_init (e);
+ mpz_init (m);
+ mpz_init (res);
+ mpz_init (ref);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op4 (OP_POWM, MAXBITS, b, e, m, ref);
+ mpz_powm (res, b, e, m);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_powm failed:\n");
+ dump ("b", b);
+ dump ("e", e);
+ dump ("m", m);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ }
+ mpz_clear (b);
+ mpz_clear (e);
+ mpz_clear (m);
+ mpz_clear (res);
+ mpz_clear (ref);
+}
diff --git a/gmp/mini-gmp/tests/t-pprime_p.c b/gmp/mini-gmp/tests/t-pprime_p.c
new file mode 100644
index 0000000000..a7ffcdb758
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-pprime_p.c
@@ -0,0 +1,182 @@
+/* test mpz_probab_prime_p
+
+Copyright 2001, 2002, 2004, 2011, 2012, 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 "testutils.h"
+
+static int
+isprime (unsigned long int t)
+{
+ unsigned long int q, r, d;
+
+ if (t < 32)
+ return (0xa08a28acUL >> t) & 1;
+ if ((t & 1) == 0)
+ return 0;
+
+ if (t % 3 == 0)
+ return 0;
+ if (t % 5 == 0)
+ return 0;
+ if (t % 7 == 0)
+ return 0;
+
+ for (d = 11;;)
+ {
+ q = t / d;
+ r = t - q * d;
+ if (q < d)
+ return 1;
+ if (r == 0)
+ break;
+ d += 2;
+ q = t / d;
+ r = t - q * d;
+ if (q < d)
+ return 1;
+ if (r == 0)
+ break;
+ d += 4;
+ }
+ return 0;
+}
+
+static void
+check_one (mpz_srcptr n, int want)
+{
+ int got;
+
+ got = mpz_probab_prime_p (n, 25);
+
+ /* "definitely prime" is fine if we only wanted "probably prime" */
+ if (got == 2 && want == 1)
+ want = 2;
+
+ if (got != want)
+ {
+ printf ("mpz_probab_prime_p\n");
+ dump (" n ", n);
+ printf (" got =%d", got);
+ printf (" want=%d\n", want);
+ abort ();
+ }
+}
+
+static void
+check_pn (mpz_ptr n, int want)
+{
+ check_one (n, want);
+ mpz_neg (n, n);
+ check_one (n, want);
+}
+
+static void
+check_small (void)
+{
+ mpz_t n;
+ long i;
+
+ mpz_init (n);
+
+ for (i = 0; i < 1700; i++)
+ {
+ mpz_set_si (n, i);
+ check_pn (n, isprime (i));
+ }
+
+ mpz_clear (n);
+}
+
+void
+check_composites (void)
+{
+ int i;
+ int reps = 1000;
+ mpz_t a, b, n, bs;
+ unsigned long size_range, size;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (n);
+ mpz_init (bs);
+
+ for (i = 0; i < reps; i++)
+ {
+ mini_urandomb (bs, 32);
+ size_range = mpz_get_ui (bs) % 12 + 1; /* 0..4096 bit operands */
+
+ mini_urandomb (bs, size_range);
+ size = mpz_get_ui (bs);
+ mini_rrandomb (a, size);
+
+ mini_urandomb (bs, 32);
+ size_range = mpz_get_ui (bs) % 12 + 1; /* 0..4096 bit operands */
+ mini_rrandomb (b, size);
+
+ /* Exclude trivial factors */
+ if (mpz_cmp_ui (a, 1) == 0)
+ mpz_set_ui (a, 2);
+ if (mpz_cmp_ui (b, 1) == 0)
+ mpz_set_ui (b, 2);
+
+ mpz_mul (n, a, b);
+
+ check_pn (n, 0);
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (n);
+ mpz_clear (bs);
+}
+
+static void
+check_primes (void)
+{
+ static const char * const primes[] = {
+ "2", "17", "65537",
+ /* diffie-hellman-group1-sha1, also "Well known group 2" in RFC
+ 2412, 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 } */
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
+ "FFFFFFFFFFFFFFFF",
+ NULL
+ };
+
+ mpz_t n;
+ int i;
+
+ mpz_init (n);
+
+ for (i = 0; primes[i]; i++)
+ {
+ mpz_set_str_or_abort (n, primes[i], 0);
+ check_one (n, 1);
+ }
+ mpz_clear (n);
+}
+
+void
+testmain (int argc, char *argv[])
+{
+ check_small ();
+ check_composites ();
+ check_primes ();
+}
diff --git a/gmp/mini-gmp/tests/t-reuse.c b/gmp/mini-gmp/tests/t-reuse.c
new file mode 100644
index 0000000000..018f8fd632
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-reuse.c
@@ -0,0 +1,663 @@
+/* Test that routines allow reusing a source variable as destination.
+
+Copyright 1996, 1999-2002, 2009, 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "testutils.h"
+
+#define COUNT 100
+
+void dump3 (const char *, mpz_t, mpz_t, mpz_t);
+void mpz_check_format (const mpz_t);
+
+typedef void (*dss_func) (mpz_t, const mpz_t, const mpz_t);
+typedef void (*dsi_func) (mpz_t, const mpz_t, unsigned long int);
+typedef unsigned long int (*dsi_div_func) (mpz_t, const mpz_t, unsigned long int);
+typedef unsigned long int (*ddsi_div_func) (mpz_t, mpz_t, const mpz_t, unsigned long int);
+typedef void (*ddss_div_func) (mpz_t, mpz_t, const mpz_t, const mpz_t);
+typedef void (*ds_func) (mpz_t, const mpz_t);
+
+
+void
+mpz_xinvert (mpz_t r, const mpz_t a, const mpz_t b)
+{
+ int res;
+ res = mpz_invert (r, a, b);
+ if (res == 0)
+ mpz_set_ui (r, 0);
+}
+
+dss_func dss_funcs[] =
+{
+ mpz_add, mpz_sub, mpz_mul,
+ mpz_cdiv_q, mpz_cdiv_r, mpz_fdiv_q, mpz_fdiv_r, mpz_tdiv_q, mpz_tdiv_r,
+ mpz_xinvert,
+ mpz_gcd, mpz_lcm, mpz_and, mpz_ior, mpz_xor
+};
+const char *dss_func_names[] =
+{
+ "mpz_add", "mpz_sub", "mpz_mul",
+ "mpz_cdiv_q", "mpz_cdiv_r", "mpz_fdiv_q", "mpz_fdiv_r", "mpz_tdiv_q", "mpz_tdiv_r",
+ "mpz_xinvert",
+ "mpz_gcd", "mpz_lcm", "mpz_and", "mpz_ior", "mpz_xor"
+};
+char dss_func_division[] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
+
+dsi_func dsi_funcs[] =
+{
+ /* Don't change order here without changing the code in main(). */
+ mpz_add_ui, mpz_mul_ui, mpz_sub_ui,
+ mpz_fdiv_q_2exp, mpz_fdiv_r_2exp,
+ mpz_cdiv_q_2exp, mpz_cdiv_r_2exp,
+ mpz_tdiv_q_2exp, mpz_tdiv_r_2exp,
+ mpz_mul_2exp,
+ mpz_pow_ui
+};
+const char *dsi_func_names[] =
+{
+ "mpz_add_ui", "mpz_mul_ui", "mpz_sub_ui",
+ "mpz_fdiv_q_2exp", "mpz_fdiv_r_2exp",
+ "mpz_cdiv_q_2exp", "mpz_cdiv_r_2exp",
+ "mpz_tdiv_q_2exp", "mpz_tdiv_r_2exp",
+ "mpz_mul_2exp",
+ "mpz_pow_ui"
+};
+
+dsi_div_func dsi_div_funcs[] =
+{
+ mpz_cdiv_q_ui, mpz_cdiv_r_ui,
+ mpz_fdiv_q_ui, mpz_fdiv_r_ui,
+ mpz_tdiv_q_ui, mpz_tdiv_r_ui
+};
+const char *dsi_div_func_names[] =
+{
+ "mpz_cdiv_q_ui", "mpz_cdiv_r_ui",
+ "mpz_fdiv_q_ui", "mpz_fdiv_r_ui",
+ "mpz_tdiv_q_ui", "mpz_tdiv_r_ui"
+};
+
+ddsi_div_func ddsi_div_funcs[] =
+{
+ mpz_cdiv_qr_ui,
+ mpz_fdiv_qr_ui,
+ mpz_tdiv_qr_ui
+};
+const char *ddsi_div_func_names[] =
+{
+ "mpz_cdiv_qr_ui",
+ "mpz_fdiv_qr_ui",
+ "mpz_tdiv_qr_ui"
+};
+
+ddss_div_func ddss_div_funcs[] =
+{
+ mpz_cdiv_qr,
+ mpz_fdiv_qr,
+ mpz_tdiv_qr
+};
+const char *ddss_div_func_names[] =
+{
+ "mpz_cdiv_qr",
+ "mpz_fdiv_qr",
+ "mpz_tdiv_qr"
+};
+
+ds_func ds_funcs[] =
+{
+ mpz_abs, mpz_com, mpz_neg, mpz_sqrt
+};
+const char *ds_func_names[] =
+{
+ "mpz_abs", "mpz_com", "mpz_neg", "mpz_sqrt"
+};
+
+
+#define FAIL(class,indx,op1,op2,op3) \
+ do { \
+ class##_funcs[indx] = 0; \
+ dump3 (class##_func_names[indx], op1, op2, op3); \
+ failures++; \
+ } while (0)
+#define FAIL2(fname,op1,op2,op3) \
+ do { \
+ dump3 (#fname, op1, op2, op3); \
+ failures++; \
+ } while (0)
+
+void
+testmain (int argc, char **argv)
+{
+ int i;
+ int pass, reps = COUNT;
+ mpz_t in1, in2, in3;
+ unsigned long int in2i;
+ mp_size_t size;
+ mpz_t res1, res2, res3;
+ mpz_t ref1, ref2, ref3;
+ mpz_t t;
+ unsigned long int r1, r2;
+ long failures = 0;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+
+ mpz_init (bs);
+
+ mpz_init (in1);
+ mpz_init (in2);
+ mpz_init (in3);
+ mpz_init (ref1);
+ mpz_init (ref2);
+ mpz_init (ref3);
+ mpz_init (res1);
+ mpz_init (res2);
+ mpz_init (res3);
+ mpz_init (t);
+
+ for (pass = 1; pass <= reps; pass++)
+ {
+ mini_urandomb (bs, 32);
+ size_range = mpz_get_ui (bs) % 12 + 2;
+
+ mini_urandomb (bs, size_range);
+ size = mpz_get_ui (bs);
+ mini_rrandomb (in1, size);
+
+ mini_urandomb (bs, size_range);
+ size = mpz_get_ui (bs);
+ mini_rrandomb (in2, size);
+
+ mini_urandomb (bs, size_range);
+ size = mpz_get_ui (bs);
+ mini_rrandomb (in3, size);
+
+ mini_urandomb (bs, 3);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (in1, in1);
+ if ((bsi & 2) != 0)
+ mpz_neg (in2, in2);
+ if ((bsi & 4) != 0)
+ mpz_neg (in3, in3);
+
+ for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
+ {
+ if (dss_funcs[i] == 0)
+ continue;
+ if (dss_func_division[i] && mpz_sgn (in2) == 0)
+ continue;
+
+ (dss_funcs[i]) (ref1, in1, in2);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ (dss_funcs[i]) (res1, res1, in2);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL (dss, i, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ (dss_funcs[i]) (res1, in1, res1);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL (dss, i, in1, in2, NULL);
+ }
+
+ for (i = 0; i < sizeof (ddss_div_funcs) / sizeof (ddss_div_func); i++)
+ {
+ if (ddss_div_funcs[i] == 0)
+ continue;
+ if (mpz_sgn (in2) == 0)
+ continue;
+
+ (ddss_div_funcs[i]) (ref1, ref2, in1, in2);
+ mpz_check_format (ref1);
+ mpz_check_format (ref2);
+
+ mpz_set (res1, in1);
+ (ddss_div_funcs[i]) (res1, res2, res1, in2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL (ddss_div, i, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ (ddss_div_funcs[i]) (res1, res2, res2, in2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL (ddss_div, i, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ (ddss_div_funcs[i]) (res1, res2, in1, res1);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL (ddss_div, i, in1, in2, NULL);
+
+ mpz_set (res2, in2);
+ (ddss_div_funcs[i]) (res1, res2, in1, res2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL (ddss_div, i, in1, in2, NULL);
+ }
+
+ for (i = 0; i < sizeof (ds_funcs) / sizeof (ds_func); i++)
+ {
+ if (ds_funcs[i] == 0)
+ continue;
+ if (strcmp (ds_func_names[i], "mpz_sqrt") == 0
+ && mpz_sgn (in1) < 0)
+ continue;
+
+ (ds_funcs[i]) (ref1, in1);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ (ds_funcs[i]) (res1, res1);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL (ds, i, in1, in2, NULL);
+ }
+
+ in2i = mpz_get_ui (in2);
+
+ for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++)
+ {
+ if (dsi_funcs[i] == 0)
+ continue;
+ if (strcmp (dsi_func_names[i], "mpz_fdiv_q_2exp") == 0)
+ /* Limit exponent to something reasonable for the division
+ functions. Without this, we'd normally shift things off
+ the end and just generate the trivial values 1, 0, -1. */
+ in2i %= 0x1000;
+ if (strcmp (dsi_func_names[i], "mpz_mul_2exp") == 0)
+ /* Limit exponent more for mpz_mul_2exp to save time. */
+ in2i %= 0x100;
+ if (strcmp (dsi_func_names[i], "mpz_pow_ui") == 0)
+ /* Limit exponent yet more for mpz_pow_ui to save time. */
+ in2i %= 0x10;
+
+ (dsi_funcs[i]) (ref1, in1, in2i);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ (dsi_funcs[i]) (res1, res1, in2i);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL (dsi, i, in1, in2, NULL);
+ }
+
+ if (in2i != 0) /* Don't divide by 0. */
+ {
+ for (i = 0; i < sizeof (dsi_div_funcs) / sizeof (dsi_div_funcs); i++)
+ {
+ r1 = (dsi_div_funcs[i]) (ref1, in1, in2i);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ r2 = (dsi_div_funcs[i]) (res1, res1, in2i);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0 || r1 != r2)
+ FAIL (dsi_div, i, in1, in2, NULL);
+ }
+
+ for (i = 0; i < sizeof (ddsi_div_funcs) / sizeof (ddsi_div_funcs); i++)
+ {
+ r1 = (ddsi_div_funcs[i]) (ref1, ref2, in1, in2i);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ r2 = (ddsi_div_funcs[i]) (res1, res2, res1, in2i);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
+ FAIL (ddsi_div, i, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ (ddsi_div_funcs[i]) (res1, res2, res2, in2i);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
+ FAIL (ddsi_div, i, in1, in2, NULL);
+ }
+ }
+
+ if (mpz_sgn (in1) >= 0)
+ {
+ mpz_sqrtrem (ref1, ref2, in1);
+ mpz_check_format (ref1);
+ mpz_check_format (ref2);
+
+ mpz_set (res1, in1);
+ mpz_sqrtrem (res1, res2, res1);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
+
+ mpz_set (res2, in1);
+ mpz_sqrtrem (res1, res2, res2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
+ }
+
+ if (mpz_sgn (in1) >= 0)
+ {
+ mpz_root (ref1, in1, in2i % 0x1000 + 1);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ mpz_root (res1, res1, in2i % 0x1000 + 1);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_root, in1, in2, NULL);
+ }
+
+ if (mpz_sgn (in1) >= 0)
+ {
+ mpz_rootrem (ref1, ref2, in1, in2i % 0x1000 + 1);
+ mpz_check_format (ref1);
+ mpz_check_format (ref2);
+
+ mpz_set (res1, in1);
+ mpz_rootrem (res1, res2, res1, in2i % 0x1000 + 1);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL2 (mpz_rootrem, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ mpz_rootrem (res1, res2, res2, in2i % 0x1000 + 1);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL2 (mpz_rootrem, in1, in2, NULL);
+ }
+
+ if (pass < reps / 2) /* run fewer tests since gcdext lots of time */
+ {
+ mpz_gcdext (ref1, ref2, ref3, in1, in2);
+ mpz_check_format (ref1);
+ mpz_check_format (ref2);
+ mpz_check_format (ref3);
+
+ mpz_set (res1, in1);
+ mpz_gcdext (res1, res2, res3, res1, in2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ mpz_check_format (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ mpz_gcdext (res1, res2, res3, res2, in2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ mpz_check_format (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res3, in1);
+ mpz_gcdext (res1, res2, res3, res3, in2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ mpz_check_format (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ mpz_gcdext (res1, res2, res3, in1, res1);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ mpz_check_format (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res2, in2);
+ mpz_gcdext (res1, res2, res3, in1, res2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ mpz_check_format (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res3, in2);
+ mpz_gcdext (res1, res2, res3, in1, res3);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ mpz_check_format (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res1, in1);
+ mpz_gcdext (res1, res2, NULL, res1, in2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ mpz_gcdext (res1, res2, NULL, res2, in2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ mpz_gcdext (res1, res2, NULL, in1, res1);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res2, in2);
+ mpz_gcdext (res1, res2, NULL, in1, res2);
+ mpz_check_format (res1);
+ mpz_check_format (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+ }
+
+ /* Don't run mpz_powm for huge exponents or when undefined. */
+ if (mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0
+ && (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3)))
+ {
+ mpz_powm (ref1, in1, in2, in3);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ mpz_powm (res1, res1, in2, in3);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm, in1, in2, in3);
+
+ mpz_set (res1, in2);
+ mpz_powm (res1, in1, res1, in3);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm, in1, in2, in3);
+
+ mpz_set (res1, in3);
+ mpz_powm (res1, in1, in2, res1);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm, in1, in2, in3);
+ }
+
+ /* Don't run mpz_powm_ui when undefined. */
+ if (mpz_sgn (in3) != 0)
+ {
+ mpz_powm_ui (ref1, in1, in2i, in3);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ mpz_powm_ui (res1, res1, in2i, in3);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm_ui, in1, in2, in3);
+
+ mpz_set (res1, in3);
+ mpz_powm_ui (res1, in1, in2i, res1);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm_ui, in1, in2, in3);
+ }
+
+ {
+ r1 = mpz_gcd_ui (ref1, in1, in2i);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ r2 = mpz_gcd_ui (res1, res1, in2i);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_gcd_ui, in1, in2, NULL);
+ }
+#if 0
+ if (mpz_cmp_ui (in2, 1L) > 0 && mpz_sgn (in1) != 0)
+ {
+ /* Test mpz_remove */
+ mpz_remove (ref1, in1, in2);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, in1);
+ mpz_remove (res1, res1, in2);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_remove, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ mpz_remove (res1, in1, res1);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_remove, in1, in2, NULL);
+ }
+#endif
+ if (mpz_sgn (in2) != 0)
+ {
+ /* Test mpz_divexact */
+ mpz_mul (t, in1, in2);
+ mpz_divexact (ref1, t, in2);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, t);
+ mpz_divexact (res1, res1, in2);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_divexact, t, in2, NULL);
+
+ mpz_set (res1, in2);
+ mpz_divexact (res1, t, res1);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_divexact, t, in2, NULL);
+ }
+
+#if 0
+ if (mpz_sgn (in2) > 0)
+ {
+ /* Test mpz_divexact_gcd, same as mpz_divexact */
+ mpz_mul (t, in1, in2);
+ mpz_divexact_gcd (ref1, t, in2);
+ mpz_check_format (ref1);
+
+ mpz_set (res1, t);
+ mpz_divexact_gcd (res1, res1, in2);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_divexact_gcd, t, in2, NULL);
+
+ mpz_set (res1, in2);
+ mpz_divexact_gcd (res1, t, res1);
+ mpz_check_format (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_divexact_gcd, t, in2, NULL);
+ }
+#endif
+ }
+
+ if (failures != 0)
+ {
+ fprintf (stderr, "mpz/reuse: %ld error%s\n", failures, "s" + (failures == 1));
+ exit (1);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (in1);
+ mpz_clear (in2);
+ mpz_clear (in3);
+ mpz_clear (ref1);
+ mpz_clear (ref2);
+ mpz_clear (ref3);
+ mpz_clear (res1);
+ mpz_clear (res2);
+ mpz_clear (res3);
+ mpz_clear (t);
+}
+
+void
+dump3 (const char *name, mpz_t in1, mpz_t in2, mpz_t in3)
+{
+ printf ("failure in %s (", name);
+ mpz_out_str (stdout, -16, in1);
+ if (in2 != NULL)
+ {
+ printf (" ");
+ mpz_out_str (stdout, -16, in2);
+ }
+ if (in3 != NULL)
+ {
+ printf (" ");
+ mpz_out_str (stdout, -16, in3);
+ }
+ printf (")\n");
+}
+
+void
+mpz_check_format (const mpz_t x)
+{
+ mp_size_t n = x ->_mp_size;
+ if (n < 0)
+ n = - n;
+
+ if (n > x->_mp_alloc)
+ {
+ fprintf (stderr, "mpz_t size exceeds allocation!\n");
+ abort ();
+ }
+
+ if (n > 0 && x->_mp_d[n-1] == 0)
+ {
+ fprintf (stderr, "Unnormalized mpz_t!\n");
+ abort ();
+ }
+}
diff --git a/gmp/mini-gmp/tests/t-root.c b/gmp/mini-gmp/tests/t-root.c
new file mode 100644
index 0000000000..1f46c435c0
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-root.c
@@ -0,0 +1,95 @@
+/*
+
+Copyright 2012, 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+/* Called when s is supposed to be floor(root(u,z)), and r = u - s^z */
+static int
+rootrem_valid_p (const mpz_t u, const mpz_t s, const mpz_t r, unsigned long z)
+{
+ mpz_t t;
+
+ mpz_init (t);
+ if (mpz_fits_ulong_p (s))
+ mpz_ui_pow_ui (t, mpz_get_ui (s), z);
+ else
+ mpz_pow_ui (t, s, z);
+ mpz_sub (t, u, t);
+ if ((mpz_sgn (t) != mpz_sgn(u) && mpz_sgn (t) != 0) || mpz_cmp (t, r) != 0)
+ {
+ mpz_clear (t);
+ return 0;
+ }
+ if (mpz_sgn (s) > 0)
+ mpz_add_ui (t, s, 1);
+ else
+ mpz_sub_ui (t, s, 1);
+ mpz_pow_ui (t, t, z);
+ if (mpz_cmpabs (t, u) <= 0)
+ {
+ mpz_clear (t);
+ return 0;
+ }
+
+ mpz_clear (t);
+ return 1;
+}
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ unsigned long e;
+ mpz_t u, s, r, bs;
+
+ mpz_init (u);
+ mpz_init (s);
+ mpz_init (r);
+ mpz_init (bs);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_rrandomb (u, MAXBITS);
+ mini_rrandomb (bs, 12);
+ e = mpz_getlimbn (bs, 0) % mpz_sizeinbase (u, 2) + 1;
+ if ((e & 1) && (mpz_getlimbn (bs, 0) & (1L<<10)))
+ mpz_neg (u, u);
+ mpz_rootrem (s, r, u, e);
+
+ if (!rootrem_valid_p (u, s, r, e))
+ {
+ fprintf (stderr, "mpz_rootrem(%lu-th) failed:\n", e);
+ dump ("u", u);
+ dump ("root", s);
+ dump ("rem", r);
+ abort ();
+ }
+ }
+ mpz_clear (bs);
+ mpz_clear (u);
+ mpz_clear (s);
+ mpz_clear (r);
+}
diff --git a/gmp/mini-gmp/tests/t-scan.c b/gmp/mini-gmp/tests/t-scan.c
new file mode 100644
index 0000000000..39b1f35cf4
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-scan.c
@@ -0,0 +1,90 @@
+/*
+
+Copyright 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a;
+ mp_bitcnt_t b, res, ref;
+
+ mpz_init (a);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_scan_op (OP_SCAN0, MAXBITS, a, &b, &ref);
+ res = mpz_scan0 (a, b);
+ if (res != ref)
+ {
+ fprintf (stderr, "mpz_scan0 failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "b: %lu\n", b);
+ fprintf (stderr, "r: %lu\n", res);
+ fprintf (stderr, "ref: %lu\n", ref);
+ abort ();
+ }
+ if (mpz_sgn (a) > 0 && ref < mpz_sizeinbase (a, 2))
+ {
+ res = mpn_scan0 (a->_mp_d, b);
+ if (res != ref)
+ {
+ fprintf (stderr, "mpn_scan0 failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "b: %lu\n", b);
+ fprintf (stderr, "r: %lu\n", res);
+ fprintf (stderr, "ref: %lu\n", ref);
+ abort ();
+ }
+ }
+ mini_random_scan_op (OP_SCAN1, MAXBITS, a, &b, &ref);
+ res = mpz_scan1 (a, b);
+ if (res != ref)
+ {
+ fprintf (stderr, "mpz_scan1 failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "b: %lu\n", b);
+ fprintf (stderr, "r: %lu\n", res);
+ fprintf (stderr, "ref: %lu\n", ref);
+ abort ();
+ }
+ if (mpz_sgn (a) > 0 && ref != ~ (mp_bitcnt_t) 0)
+ {
+ res = mpn_scan1 (a->_mp_d, b);
+ if (res != ref)
+ {
+ fprintf (stderr, "mpn_scan1 failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "b: %lu\n", b);
+ fprintf (stderr, "r: %lu\n", res);
+ fprintf (stderr, "ref: %lu\n", ref);
+ abort ();
+ }
+ }
+ }
+ mpz_clear (a);
+}
diff --git a/gmp/mini-gmp/tests/t-signed.c b/gmp/mini-gmp/tests/t-signed.c
new file mode 100644
index 0000000000..e2502d6e9f
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-signed.c
@@ -0,0 +1,142 @@
+/* Exercise some mpz_..._si functions.
+
+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 <stdio.h>
+#include <stdlib.h>
+
+#include "testutils.h"
+
+int
+check_si (mpz_t sz, mpz_t oz, long si, long oi, int c)
+{
+ mpz_t t;
+ int fail;
+
+ if (mpz_cmp_si (sz, oi) != c)
+ {
+ printf ("mpz_cmp_si (sz, %ld) != %i.\n", oi, c);
+ printf (" sz="); mpz_out_str (stdout, 10, sz); printf ("\n");
+ abort ();
+ }
+
+ if ((si < oi ? -1 : si > oi) != c)
+ return 1;
+
+ mpz_init_set_si (t, si);
+
+ if ((fail = mpz_cmp_si (sz, si)) != 0)
+ printf ("mpz_cmp_si (sz, %ld) != 0.\n", si);
+ if (mpz_cmp_si (oz, si) != -c)
+ printf ("mpz_cmp_si (oz, %ld) != %i.\n", si, -c), fail = 1;
+ if (! mpz_fits_slong_p (sz))
+ printf ("mpz_fits_slong_p (sz) != 1.\n"), fail = 1;
+ if (mpz_get_si (sz) != si)
+ printf ("mpz_get_si (sz) != %ld.\n", si), fail = 1;
+ if (mpz_cmp (t, sz) != 0)
+ {
+ printf ("mpz_init_set_si (%ld) failed.\n", si);
+ printf (" got="); mpz_out_str (stdout, 10, t); printf ("\n");
+ fail = 1;
+ }
+
+ mpz_clear (t);
+
+ if (fail)
+ {
+ printf (" sz="); mpz_out_str (stdout, 10, sz); printf ("\n");
+ printf (" oz="); mpz_out_str (stdout, 10, oz); printf ("\n");
+ printf (" si=%ld\n", si);
+ abort ();
+ }
+
+ return 0;
+}
+
+void
+try_op_si (int c)
+{
+ long si, oi;
+ mpz_t sz, oz;
+
+ si = c;
+ mpz_init_set_si (sz, si);
+
+ oi = si;
+ mpz_init_set (oz, sz);
+
+ do {
+ si *= 2; /* c * 2^k */
+ mpz_mul_2exp (sz, sz, 1);
+
+ if (check_si (sz, oz, si, oi, c))
+ {
+ mpz_set (oz, sz);
+ break;
+ }
+
+ oi = si + c; /* c * (2^k + 1) */
+ if (c == -1)
+ mpz_sub_ui (oz, sz, 1);
+ else
+ mpz_add_ui (oz, sz, 1);
+
+ if (check_si (oz, sz, oi, si, c))
+ break;
+
+ oi = (si - c) * 2 + c; /* c * (2^K - 1) */
+ mpz_mul_si (oz, sz, 2*c);
+ if (c == -1)
+ mpz_ui_sub (oz, 1, oz); /* oz = sz * 2 + 1 */
+ else
+ mpz_sub_ui (oz, oz, 1); /* oz = sz * 2 - 1 */
+ } while (check_si (oz, sz, oi, si, c) == 0);
+
+ mpz_clear (sz);
+
+ if (mpz_fits_slong_p (oz))
+ {
+ printf ("Should not fit a signed long any more.\n");
+ printf (" oz="); mpz_out_str (stdout, 10, oz); printf ("\n");
+ abort ();
+ }
+
+ if (mpz_cmp_si (oz, -c) != c)
+ {
+ printf ("mpz_cmp_si (oz, %i) != %i.\n", c, c);
+ printf (" oz="); mpz_out_str (stdout, 10, oz); printf ("\n");
+ abort ();
+ }
+
+ mpz_mul_2exp (oz, oz, 1);
+ if (mpz_cmp_si (oz, -c) != c)
+ {
+ printf ("mpz_cmp_si (oz, %i) != %i.\n", c, c);
+ printf (" oz="); mpz_out_str (stdout, 10, oz); printf ("\n");
+ abort ();
+ }
+
+ mpz_clear (oz);
+}
+
+void
+testmain (int argc, char *argv[])
+{
+ try_op_si (-1);
+ try_op_si (1);
+}
diff --git a/gmp/mini-gmp/tests/t-sqrt.c b/gmp/mini-gmp/tests/t-sqrt.c
new file mode 100644
index 0000000000..f4ce7cbb4d
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-sqrt.c
@@ -0,0 +1,181 @@
+/*
+
+Copyright 2012, 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 9000
+
+/* Called when s is supposed to be floor(sqrt(u)), and r = u - s^2 */
+static int
+sqrtrem_valid_p (const mpz_t u, const mpz_t s, const mpz_t r)
+{
+ mpz_t t;
+
+ mpz_init (t);
+ mpz_mul (t, s, s);
+ mpz_sub (t, u, t);
+ if (mpz_sgn (t) < 0 || mpz_cmp (t, r) != 0)
+ {
+ mpz_clear (t);
+ return 0;
+ }
+ mpz_add_ui (t, s, 1);
+ mpz_mul (t, t, t);
+ if (mpz_cmp (t, u) <= 0)
+ {
+ mpz_clear (t);
+ return 0;
+ }
+
+ mpz_clear (t);
+ return 1;
+}
+
+void
+mpz_mpn_sqrtrem (mpz_t s, mpz_t r, const mpz_t u)
+{
+ mp_limb_t *sp, *rp;
+ mp_size_t un, sn, ret;
+
+ un = mpz_size (u);
+
+ mpz_xor (s, s, u);
+ sn = (un + 1) / 2;
+ sp = mpz_limbs_write (s, sn + 1);
+ sp [sn] = 11;
+
+ if (un & 1)
+ rp = NULL; /* Exploits the fact that r already is correct. */
+ else {
+ mpz_add (r, u, s);
+ rp = mpz_limbs_write (r, un + 1);
+ rp [un] = 19;
+ }
+
+ ret = mpn_sqrtrem (sp, rp, mpz_limbs_read (u), un);
+
+ if (sp [sn] != 11)
+ {
+ fprintf (stderr, "mpn_sqrtrem buffer overrun on sp.\n");
+ abort ();
+ }
+ if (un & 1) {
+ if ((ret != 0) != (mpz_size (r) != 0)) {
+ fprintf (stderr, "mpn_sqrtrem wrong return value with NULL.\n");
+ abort ();
+ }
+ } else {
+ mpz_limbs_finish (r, ret);
+ if (ret != mpz_size (r)) {
+ fprintf (stderr, "mpn_sqrtrem wrong return value.\n");
+ abort ();
+ }
+ if (rp [un] != 19)
+ {
+ fprintf (stderr, "mpn_sqrtrem buffer overrun on rp.\n");
+ abort ();
+ }
+ }
+
+ mpz_limbs_finish (s, (un + 1) / 2);
+}
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t u, s, r;
+
+ mpz_init (s);
+ mpz_init (r);
+
+ mpz_init_set_si (u, -1);
+ if (mpz_perfect_square_p (u))
+ {
+ fprintf (stderr, "mpz_perfect_square_p failed on -1.\n");
+ abort ();
+ }
+
+ if (!mpz_perfect_square_p (s))
+ {
+ fprintf (stderr, "mpz_perfect_square_p failed on 0.\n");
+ abort ();
+ }
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_rrandomb (u, MAXBITS - (i & 0xFF));
+ mpz_sqrtrem (s, r, u);
+
+ if (!sqrtrem_valid_p (u, s, r))
+ {
+ fprintf (stderr, "mpz_sqrtrem failed:\n");
+ dump ("u", u);
+ dump ("sqrt", s);
+ dump ("rem", r);
+ abort ();
+ }
+
+ mpz_mpn_sqrtrem (s, r, u);
+
+ if (!sqrtrem_valid_p (u, s, r))
+ {
+ fprintf (stderr, "mpn_sqrtrem failed:\n");
+ dump ("u", u);
+ dump ("sqrt", s);
+ dump ("rem", r);
+ abort ();
+ }
+
+ if (mpz_sgn (r) == 0) {
+ mpz_neg (u, u);
+ mpz_sub_ui (u, u, 1);
+ }
+
+ if ((mpz_sgn (u) <= 0 || (i & 1)) ?
+ mpz_perfect_square_p (u) :
+ mpn_perfect_square_p (mpz_limbs_read (u), mpz_size (u)))
+ {
+ fprintf (stderr, "mp%s_perfect_square_p failed on non square:\n",
+ (mpz_sgn (u) <= 0 || (i & 1)) ? "z" : "n");
+ dump ("u", u);
+ abort ();
+ }
+
+ mpz_mul (u, s, s);
+ if (!((mpz_sgn (u) <= 0 || (i & 1)) ?
+ mpz_perfect_square_p (u) :
+ mpn_perfect_square_p (mpz_limbs_read (u), mpz_size (u))))
+ {
+ fprintf (stderr, "mp%s_perfect_square_p failed on square:\n",
+ (mpz_sgn (u) <= 0 || (i & 1)) ? "z" : "n");
+ dump ("u", u);
+ abort ();
+ }
+
+ }
+ mpz_clear (u);
+ mpz_clear (s);
+ mpz_clear (r);
+}
diff --git a/gmp/mini-gmp/tests/t-str.c b/gmp/mini-gmp/tests/t-str.c
new file mode 100644
index 0000000000..2c384bd1d2
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-str.c
@@ -0,0 +1,307 @@
+/*
+
+Copyright 2012, 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 <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 2000
+
+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
+#define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
+
+static void
+test_small (void)
+{
+ struct {
+ const char *input;
+ const char *decimal;
+ } data[] = {
+ { "183407", "183407" },
+ { " 763959", "763959" },
+ { "9 81999", "981999" },
+ { "10\t7398", "107398" },
+ { "-9585 44", "-00958544" },
+ { "-0", "0000" },
+ { " -000 ", "0" },
+ { "0704436", "231710" },
+ { " 02503517", "689999" },
+ { "0 1312143", "365667" },
+ { "-03 274062", "-882738" },
+ { "012\t242", "005282" },
+ { "0b11010111110010001111", "883855" },
+ { " 0b11001010010100001", "103585" },
+ { "-0b101010110011101111", "-175343" },
+ { "0b 1111111011011100110", "521958" },
+ { "0b1 1111110111001000011", "1044035" },
+ { " 0x53dfc", "343548" },
+ { "0xfA019", "1024025" },
+ { "0x 642d1", "410321" },
+ { "0x5 8067", "360551" },
+ { "-0xd6Be6", "-879590" },
+ { "\t0B1110000100000000011", "460803" },
+ { "0B\t1111110010010100101", "517285" },
+ { "0B1\t010111101101110100", "359284" },
+ { "-0B101\t1001101111111001", "-367609" },
+ { "0B10001001010111110000", "562672" },
+ { "0Xe4B7e", "936830" },
+ { "0X1E4bf", "124095" },
+ { "-0Xfdb90", "-1039248" },
+ { "0X7fc47", "523335" },
+ { "0X8167c", "530044" },
+ /* Some invalid inputs */
+ { "0ab", NULL },
+ { "10x0", NULL },
+ { "0xxab", NULL },
+ { "ab", NULL },
+ { "0%#", NULL },
+ { "$foo", NULL },
+ { NULL, NULL }
+ };
+ unsigned i;
+ mpz_t a, b;
+ mpz_init (b);
+
+ for (i = 0; data[i].input; i++)
+ {
+ int res = mpz_init_set_str (a, data[i].input, 0);
+ if (data[i].decimal)
+ {
+ if (res != 0)
+ {
+ fprintf (stderr, "mpz_set_str returned -1, input: %s\n",
+ data[i].input);
+ abort ();
+ }
+ if (mpz_set_str (b, data[i].decimal, 10) != 0)
+ {
+ fprintf (stderr, "mpz_set_str returned -1, decimal input: %s\n",
+ data[i].input);
+ abort ();
+ }
+ if (mpz_cmp (a, b) != 0)
+ {
+ fprintf (stderr, "mpz_set_str failed for input: %s\n",
+ data[i].input);
+
+ dump ("got", a);
+ dump ("ref", b);
+ abort ();
+ }
+ }
+ else if (res != -1)
+ {
+ fprintf (stderr, "mpz_set_str returned %d, invalid input: %s\n",
+ res, data[i].input);
+ abort ();
+ }
+ mpz_clear (a);
+ }
+
+ mpz_clear (b);
+}
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ char *ap;
+ char *bp;
+ char *rp;
+ size_t bn, rn, arn;
+
+ mpz_t a, b;
+
+ FILE *tmp;
+
+ test_small ();
+
+ mpz_init (a);
+ mpz_init (b);
+
+ tmp = tmpfile ();
+ if (!tmp)
+ fprintf (stderr,
+ "Failed to create temporary file. Skipping mpz_out_str tests.\n");
+
+ for (i = 0; i < COUNT; i++)
+ {
+ int base;
+ for (base = 0; base <= 36; base += 1 + (base == 0))
+ {
+ hex_random_str_op (MAXBITS, i&1 ? base: -base, &ap, &rp);
+ if (mpz_set_str (a, ap, 16) != 0)
+ {
+ fprintf (stderr, "mpz_set_str failed on input %s\n", ap);
+ abort ();
+ }
+
+ rn = strlen (rp);
+ arn = rn - (rp[0] == '-');
+
+ bn = mpz_sizeinbase (a, base ? base : 10);
+ if (bn < arn || bn > (arn + 1))
+ {
+ fprintf (stderr, "mpz_sizeinbase failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "r = %s\n", rp);
+ fprintf (stderr, " base %d, correct size %u, got %u\n",
+ base, (unsigned) arn, (unsigned)bn);
+ abort ();
+ }
+ bp = mpz_get_str (NULL, i&1 ? base: -base, a);
+ if (strcmp (bp, rp))
+ {
+ fprintf (stderr, "mpz_get_str failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "b = %s\n", bp);
+ fprintf (stderr, " base = %d\n", base);
+ fprintf (stderr, "r = %s\n", rp);
+ abort ();
+ }
+
+ /* Just a few tests with file i/o. */
+ if (tmp && i < 20)
+ {
+ size_t tn;
+ rewind (tmp);
+ tn = mpz_out_str (tmp, i&1 ? base: -base, a);
+ if (tn != rn)
+ {
+ fprintf (stderr, "mpz_out_str, bad return value:\n");
+ dump ("a", a);
+ fprintf (stderr, "r = %s\n", rp);
+ fprintf (stderr, " base %d, correct size %u, got %u\n",
+ base, (unsigned) rn, (unsigned)tn);
+ abort ();
+ }
+ rewind (tmp);
+ memset (bp, 0, rn);
+ tn = fread (bp, 1, rn, tmp);
+ if (tn != rn)
+ {
+ fprintf (stderr,
+ "fread failed, expected %lu bytes, got only %lu.\n",
+ (unsigned long) rn, (unsigned long) tn);
+ abort ();
+ }
+
+ if (memcmp (bp, rp, rn) != 0)
+ {
+ fprintf (stderr, "mpz_out_str failed:\n");
+ dump ("a", a);
+ fprintf (stderr, "b = %s\n", bp);
+ fprintf (stderr, " base = %d\n", base);
+ fprintf (stderr, "r = %s\n", rp);
+ abort ();
+ }
+ }
+
+ mpz_set_str (b, rp, base);
+
+ if (mpz_cmp (a, b))
+ {
+ fprintf (stderr, "mpz_set_str failed:\n");
+ fprintf (stderr, "r = %s\n", rp);
+ fprintf (stderr, " base = %d\n", base);
+ fprintf (stderr, "r = %s\n", ap);
+ fprintf (stderr, " base = 16\n");
+ dump ("b", b);
+ dump ("r", a);
+ abort ();
+ }
+
+ /* Test mpn interface */
+ if (base && mpz_sgn (a))
+ {
+ size_t i;
+ const char *absr;
+ mp_limb_t t[MAXLIMBS];
+ mp_size_t tn = mpz_size (a);
+
+ assert (tn <= MAXLIMBS);
+ mpn_copyi (t, a->_mp_d, tn);
+
+ bn = mpn_get_str (bp, base, t, tn);
+ if (bn != arn)
+ {
+ fprintf (stderr, "mpn_get_str failed:\n");
+ fprintf (stderr, "returned length: %lu (bad)\n", (unsigned long) bn);
+ fprintf (stderr, "expected: %lu\n", (unsigned long) arn);
+ fprintf (stderr, " base = %d\n", base);
+ fprintf (stderr, "r = %s\n", ap);
+ fprintf (stderr, " base = 16\n");
+ dump ("b", b);
+ dump ("r", a);
+ abort ();
+ }
+ absr = rp + (rp[0] == '-');
+
+ for (i = 0; i < bn; i++)
+ {
+ unsigned char digit = absr[i];
+ unsigned value;
+ if (digit >= '0' && digit <= '9')
+ value = digit - '0';
+ else if (digit >= 'a' && digit <= 'z')
+ value = digit - 'a' + 10;
+ else if (digit >= 'A' && digit <= 'Z')
+ value = digit - 'A' + 10;
+ else
+ {
+ fprintf (stderr, "Internal error in test.\n");
+ abort();
+ }
+ if (bp[i] != value)
+ {
+ fprintf (stderr, "mpn_get_str failed:\n");
+ fprintf (stderr, "digit %lu: %d (bad)\n", (unsigned long) i, bp[i]);
+ fprintf (stderr, "expected: %d\n", value);
+ fprintf (stderr, " base = %d\n", base);
+ fprintf (stderr, "r = %s\n", ap);
+ fprintf (stderr, " base = 16\n");
+ dump ("b", b);
+ dump ("r", a);
+ abort ();
+ }
+ }
+ tn = mpn_set_str (t, bp, bn, base);
+ if (tn != mpz_size (a) || mpn_cmp (t, a->_mp_d, tn))
+ {
+ fprintf (stderr, "mpn_set_str failed:\n");
+ fprintf (stderr, "r = %s\n", rp);
+ fprintf (stderr, " base = %d\n", base);
+ fprintf (stderr, "r = %s\n", ap);
+ fprintf (stderr, " base = 16\n");
+ dump ("r", a);
+ abort ();
+ }
+ }
+ free (ap);
+ testfree (bp);
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+}
diff --git a/gmp/mini-gmp/tests/t-sub.c b/gmp/mini-gmp/tests/t-sub.c
new file mode 100644
index 0000000000..e230fda1fb
--- /dev/null
+++ b/gmp/mini-gmp/tests/t-sub.c
@@ -0,0 +1,71 @@
+/*
+
+Copyright 2012, 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 <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+
+#define MAXBITS 400
+#define COUNT 10000
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, res, res_ui, ref;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (res);
+ mpz_init (res_ui);
+ mpz_init (ref);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op3 (OP_SUB, MAXBITS, a, b, ref);
+ mpz_sub (res, a, b);
+ if (mpz_cmp (res, ref))
+ {
+ fprintf (stderr, "mpz_sub failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res);
+ dump ("ref", ref);
+ abort ();
+ }
+ if (mpz_fits_ulong_p (a)) {
+ mpz_ui_sub (res_ui, mpz_get_ui (a), b);
+ if (mpz_cmp (res_ui, ref))
+ {
+ fprintf (stderr, "mpz_ui_sub failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", res_ui);
+ dump ("ref", ref);
+ abort ();
+ }
+ }
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (res);
+ mpz_clear (res_ui);
+ mpz_clear (ref);
+}
diff --git a/gmp/mini-gmp/tests/testutils.c b/gmp/mini-gmp/tests/testutils.c
new file mode 100644
index 0000000000..c3840b36bc
--- /dev/null
+++ b/gmp/mini-gmp/tests/testutils.c
@@ -0,0 +1,173 @@
+/*
+
+Copyright 2013, 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 "testutils.h"
+
+/* Include it here, so we we could tweak, e.g., how MPZ_REALLOC
+ works. */
+#include "../mini-gmp.c"
+
+static size_t total_alloc = 0;
+
+/* Custom memory allocation to track memory usage, and add a small red
+ zone.
+
+ About alignment: In general, getting a block from malloc, and
+ incrementing it by sizeof(size_t), like we do here, might give a
+ pointer which is not properly aligned for all types. But the
+ largest type we allocate space for is unsigned long (mp_limb_t),
+ which shouldn't have stricter alignment requirements than
+ size_t. */
+
+static char block_end[8] =
+ { 0x7c, 0x37, 0xd6, 0x12, 0xa8, 0x6c, 0x01, 0xd1 };
+
+static void *
+block_init (size_t *block, size_t size)
+{
+ char *p;
+ *block++ = size;
+
+ p = (char *) block;
+ memcpy (p + size, block_end, sizeof(block_end));
+
+ total_alloc += size;
+ return p;
+}
+
+/* Check small redzone, return pointer to malloced block. */
+static size_t *
+block_check (char *p)
+{
+ size_t *block = (size_t *) p - 1;
+ size_t size = block[0];
+
+ if (memcmp (p + size, block_end, sizeof(block_end)) != 0)
+ {
+ fprintf (stderr, "red zone overwritten.\n");
+ abort ();
+ }
+ total_alloc -= size;
+ return block;
+}
+
+static void *
+tu_alloc (size_t size)
+{
+ size_t *block = malloc (sizeof(size_t) + size + sizeof(block_end));
+ if (!block)
+ {
+ fprintf (stderr, "Virtual memory exhausted.\n");
+ abort ();
+ }
+
+ return block_init (block, size);
+}
+
+static void *
+tu_realloc (void *p, size_t old_size, size_t new_size)
+{
+ size_t *block = block_check (p);
+ block = realloc (block, sizeof(size_t) + new_size + sizeof(block_end));
+ if (!block)
+ {
+ fprintf (stderr, "Virtual memory exhausted.\n");
+ abort ();
+ }
+
+ return block_init (block, new_size);
+}
+
+static void
+tu_free (void *p, size_t old_size)
+{
+ free (block_check (p));
+}
+
+/* Free memory allocated via mini-gmp allocation function. */
+void
+testfree (void *p)
+{
+ void (*freefunc) (void *, size_t);
+ mp_get_memory_functions (NULL, NULL, &freefunc);
+
+ freefunc (p, 0);
+}
+
+int
+main (int argc, char **argv)
+{
+ hex_random_init ();
+
+ mp_set_memory_functions (tu_alloc, tu_realloc, tu_free);
+
+ /* Currently, t-comb seems to be the only program accepting any
+ arguments. It might make sense to parse common arguments here. */
+ testmain (argc, argv);
+
+ if (total_alloc != 0)
+ {
+ fprintf (stderr, "Memory leaked: %lu bytes.\n",
+ (unsigned long) total_alloc);
+ abort ();
+ }
+ return 0;
+}
+
+void
+testhalves (int count, void (*tested_fun) (int))
+{
+ void (*freefunc) (void *, size_t);
+ void *(*reallocfunc) (void *, size_t, size_t);
+ void *(*allocfunc) (size_t);
+ size_t initial_alloc;
+
+ mp_get_memory_functions (&allocfunc, &reallocfunc, &freefunc);
+ initial_alloc = total_alloc;
+ (*tested_fun) (count / 2);
+ if (initial_alloc != total_alloc)
+ {
+ fprintf (stderr, "First half, memory leaked: %lu bytes.\n",
+ (unsigned long) total_alloc - initial_alloc);
+ abort ();
+ }
+ mp_set_memory_functions (NULL, NULL, NULL);
+ (*tested_fun) (count / 2);
+ mp_set_memory_functions (allocfunc, reallocfunc, freefunc);
+}
+
+void
+dump (const char *label, const mpz_t x)
+{
+ char *buf = mpz_get_str (NULL, 16, x);
+ fprintf (stderr, "%s: %s\n", label, buf);
+ testfree (buf);
+}
+
+void
+mpz_set_str_or_abort (mpz_ptr z, const char *str, int base)
+{
+ if (mpz_set_str (z, str, base) != 0)
+ {
+ fprintf (stderr, "ERROR: mpz_set_str failed\n");
+ fprintf (stderr, " str = \"%s\"\n", str);
+ fprintf (stderr, " base = %d\n", base);
+ abort();
+ }
+}
diff --git a/gmp/mini-gmp/tests/testutils.h b/gmp/mini-gmp/tests/testutils.h
new file mode 100644
index 0000000000..bc56c06a75
--- /dev/null
+++ b/gmp/mini-gmp/tests/testutils.h
@@ -0,0 +1,37 @@
+/*
+
+Copyright 2013, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "mini-random.h"
+
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+
+void testmain (int argc, char **argv);
+
+void testhalves (int count, void (*tested_fun) (int));
+
+void testfree (void *p);
+
+void
+dump (const char *label, const mpz_t x);
+
+void
+mpz_set_str_or_abort (mpz_ptr z, const char *str, int base);
diff --git a/gmp/missing b/gmp/missing
new file mode 100755
index 0000000000..86a8fc31e3
--- /dev/null
+++ b/gmp/missing
@@ -0,0 +1,331 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2012-01-06.13; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ autom4te touch the output file, or create a stub one
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program). This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+ lex*|yacc*)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case $f in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te*)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison*|yacc*)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if test $# -ne 1; then
+ eval LASTARG=\${$#}
+ case $LASTARG in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f y.tab.h; then
+ echo >y.tab.h
+ fi
+ if test ! -f y.tab.c; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex*|flex*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if test $# -ne 1; then
+ eval LASTARG=\${$#}
+ case $LASTARG in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f lex.yy.c; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit $?
+ fi
+ ;;
+
+ makeinfo*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '
+ /^@setfilename/{
+ s/.* \([^ ]*\) *$/\1/
+ p
+ q
+ }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ # If the file does not exist, the user really needs makeinfo;
+ # let's fail without touching anything.
+ test -f $file || exit 1
+ touch $file
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/gmp/mp_bpl.c b/gmp/mp_bpl.c
new file mode 100644
index 0000000000..6328057965
--- /dev/null
+++ b/gmp/mp_bpl.c
@@ -0,0 +1,35 @@
+/*
+Copyright 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+const int mp_bits_per_limb = GMP_LIMB_BITS;
+const int __gmp_0 = 0;
+int __gmp_junk;
diff --git a/gmp/mp_clz_tab.c b/gmp/mp_clz_tab.c
new file mode 100644
index 0000000000..7c9227e8b3
--- /dev/null
+++ b/gmp/mp_clz_tab.c
@@ -0,0 +1,49 @@
+/* __clz_tab -- support for longlong.h
+
+ THE CONTENTS OF THIS FILE ARE FOR INTERNAL USE AND MAY CHANGE
+ INCOMPATIBLY OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifdef COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+const
+unsigned char __clz_tab[129] =
+{
+ 1,2,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 9
+};
+#endif
diff --git a/gmp/mp_dv_tab.c b/gmp/mp_dv_tab.c
new file mode 100644
index 0000000000..c6d74eb3f2
--- /dev/null
+++ b/gmp/mp_dv_tab.c
@@ -0,0 +1,78 @@
+/* __gmp_digit_value_tab -- support for mp*_set_str
+
+ THE CONTENTS OF THIS FILE ARE FOR INTERNAL USE AND MAY CHANGE
+ INCOMPATIBLY OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2003, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Table to be indexed by character, to get its numerical value. Assumes ASCII
+ character set.
+
+ First part of table supports common usages, where 'A' and 'a' have the same
+ value; this supports bases 2..36
+
+ At offset 208, values for bases 37..62 start. Here, 'A' has the value 10
+ (in decimal) and 'a' has the value 36. */
+
+#define X 0xff
+const unsigned char __gmp_digit_value_tab[] =
+{
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, X, X, X, X, X, X,
+ X,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+ 25,26,27,28,29,30,31,32,33,34,35,X, X, X, X, X,
+ X,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+ 25,26,27,28,29,30,31,32,33,34,35,X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, X, X, X, X, X, X,
+ X,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+ 25,26,27,28,29,30,31,32,33,34,35,X, X, X, X, X,
+ X,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,
+ 51,52,53,54,55,56,57,58,59,60,61,X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X
+};
diff --git a/gmp/mp_get_fns.c b/gmp/mp_get_fns.c
new file mode 100644
index 0000000000..c77980fbeb
--- /dev/null
+++ b/gmp/mp_get_fns.c
@@ -0,0 +1,48 @@
+/* mp_get_memory_functions -- Get the allocate, reallocate, and free functions.
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mp_get_memory_functions (void *(**alloc_func) (size_t),
+ void *(**realloc_func) (void *, size_t, size_t),
+ void (**free_func) (void *, size_t)) __GMP_NOTHROW
+{
+ if (alloc_func != NULL)
+ *alloc_func = __gmp_allocate_func;
+
+ if (realloc_func != NULL)
+ *realloc_func = __gmp_reallocate_func;
+
+ if (free_func != NULL)
+ *free_func = __gmp_free_func;
+}
diff --git a/gmp/mp_minv_tab.c b/gmp/mp_minv_tab.c
new file mode 100644
index 0000000000..522bd0184b
--- /dev/null
+++ b/gmp/mp_minv_tab.c
@@ -0,0 +1,59 @@
+/* A table of data supporting binvert_limb().
+
+ THE CONTENTS OF THIS FILE ARE FOR INTERNAL USE AND MAY CHANGE
+ INCOMPATIBLY OR DISAPPEAR IN A FUTURE GNU MP RELEASE. */
+
+/*
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* binvert_limb_table[i] is the multiplicative inverse of 2*i+1 mod 256,
+ ie. (binvert_limb_table[i] * (2*i+1)) % 256 == 1 */
+
+const unsigned char binvert_limb_table[128] = {
+ 0x01, 0xAB, 0xCD, 0xB7, 0x39, 0xA3, 0xC5, 0xEF,
+ 0xF1, 0x1B, 0x3D, 0xA7, 0x29, 0x13, 0x35, 0xDF,
+ 0xE1, 0x8B, 0xAD, 0x97, 0x19, 0x83, 0xA5, 0xCF,
+ 0xD1, 0xFB, 0x1D, 0x87, 0x09, 0xF3, 0x15, 0xBF,
+ 0xC1, 0x6B, 0x8D, 0x77, 0xF9, 0x63, 0x85, 0xAF,
+ 0xB1, 0xDB, 0xFD, 0x67, 0xE9, 0xD3, 0xF5, 0x9F,
+ 0xA1, 0x4B, 0x6D, 0x57, 0xD9, 0x43, 0x65, 0x8F,
+ 0x91, 0xBB, 0xDD, 0x47, 0xC9, 0xB3, 0xD5, 0x7F,
+ 0x81, 0x2B, 0x4D, 0x37, 0xB9, 0x23, 0x45, 0x6F,
+ 0x71, 0x9B, 0xBD, 0x27, 0xA9, 0x93, 0xB5, 0x5F,
+ 0x61, 0x0B, 0x2D, 0x17, 0x99, 0x03, 0x25, 0x4F,
+ 0x51, 0x7B, 0x9D, 0x07, 0x89, 0x73, 0x95, 0x3F,
+ 0x41, 0xEB, 0x0D, 0xF7, 0x79, 0xE3, 0x05, 0x2F,
+ 0x31, 0x5B, 0x7D, 0xE7, 0x69, 0x53, 0x75, 0x1F,
+ 0x21, 0xCB, 0xED, 0xD7, 0x59, 0xC3, 0xE5, 0x0F,
+ 0x11, 0x3B, 0x5D, 0xC7, 0x49, 0x33, 0x55, 0xFF
+};
diff --git a/gmp/mp_set_fns.c b/gmp/mp_set_fns.c
new file mode 100644
index 0000000000..7be60066b9
--- /dev/null
+++ b/gmp/mp_set_fns.c
@@ -0,0 +1,50 @@
+/* mp_set_memory_functions -- Set the allocate, reallocate, and free functions
+ for use by the mp package.
+
+Copyright 1991, 1993, 1994, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mp_set_memory_functions (void *(*alloc_func) (size_t),
+ void *(*realloc_func) (void *, size_t, size_t),
+ void (*free_func) (void *, size_t)) __GMP_NOTHROW
+{
+ if (alloc_func == 0)
+ alloc_func = __gmp_default_allocate;
+ if (realloc_func == 0)
+ realloc_func = __gmp_default_reallocate;
+ if (free_func == 0)
+ free_func = __gmp_default_free;
+
+ __gmp_allocate_func = alloc_func;
+ __gmp_reallocate_func = realloc_func;
+ __gmp_free_func = free_func;
+}
diff --git a/gmp/mpf/Makefile.am b/gmp/mpf/Makefile.am
new file mode 100644
index 0000000000..30b0ea8f5f
--- /dev/null
+++ b/gmp/mpf/Makefile.am
@@ -0,0 +1,47 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 1996, 1998-2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+
+noinst_LTLIBRARIES = libmpf.la
+libmpf_la_SOURCES = \
+ init.c init2.c inits.c set.c set_ui.c set_si.c set_str.c set_d.c set_z.c \
+ set_q.c iset.c iset_ui.c iset_si.c iset_str.c iset_d.c clear.c clears.c \
+ get_str.c dump.c size.c eq.c reldiff.c sqrt.c random2.c inp_str.c out_str.c \
+ add.c add_ui.c sub.c sub_ui.c ui_sub.c mul.c mul_ui.c div.c div_ui.c \
+ cmp.c cmp_d.c cmp_si.c cmp_ui.c mul_2exp.c div_2exp.c abs.c neg.c get_d.c \
+ get_d_2exp.c set_dfl_prec.c set_prc.c set_prc_raw.c get_dfl_prec.c get_prc.c \
+ ui_div.c sqrt_ui.c \
+ pow_ui.c urandomb.c swap.c get_si.c get_ui.c int_p.c \
+ ceilfloor.c trunc.c \
+ fits_sint.c fits_slong.c fits_sshort.c \
+ fits_uint.c fits_ulong.c fits_ushort.c \
+ fits_s.h fits_u.h
diff --git a/gmp/mpf/Makefile.in b/gmp/mpf/Makefile.in
new file mode 100644
index 0000000000..2f5238be58
--- /dev/null
+++ b/gmp/mpf/Makefile.in
@@ -0,0 +1,575 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 1996, 1998-2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = mpf
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libmpf_la_LIBADD =
+am_libmpf_la_OBJECTS = init.lo init2.lo inits.lo set.lo set_ui.lo \
+ set_si.lo set_str.lo set_d.lo set_z.lo set_q.lo iset.lo \
+ iset_ui.lo iset_si.lo iset_str.lo iset_d.lo clear.lo clears.lo \
+ get_str.lo dump.lo size.lo eq.lo reldiff.lo sqrt.lo random2.lo \
+ inp_str.lo out_str.lo add.lo add_ui.lo sub.lo sub_ui.lo \
+ ui_sub.lo mul.lo mul_ui.lo div.lo div_ui.lo cmp.lo cmp_d.lo \
+ cmp_si.lo cmp_ui.lo mul_2exp.lo div_2exp.lo abs.lo neg.lo \
+ get_d.lo get_d_2exp.lo set_dfl_prec.lo set_prc.lo \
+ set_prc_raw.lo get_dfl_prec.lo get_prc.lo ui_div.lo sqrt_ui.lo \
+ pow_ui.lo urandomb.lo swap.lo get_si.lo get_ui.lo int_p.lo \
+ ceilfloor.lo trunc.lo fits_sint.lo fits_slong.lo \
+ fits_sshort.lo fits_uint.lo fits_ulong.lo fits_ushort.lo
+libmpf_la_OBJECTS = $(am_libmpf_la_OBJECTS)
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libmpf_la_SOURCES)
+DIST_SOURCES = $(libmpf_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+noinst_LTLIBRARIES = libmpf.la
+libmpf_la_SOURCES = \
+ init.c init2.c inits.c set.c set_ui.c set_si.c set_str.c set_d.c set_z.c \
+ set_q.c iset.c iset_ui.c iset_si.c iset_str.c iset_d.c clear.c clears.c \
+ get_str.c dump.c size.c eq.c reldiff.c sqrt.c random2.c inp_str.c out_str.c \
+ add.c add_ui.c sub.c sub_ui.c ui_sub.c mul.c mul_ui.c div.c div_ui.c \
+ cmp.c cmp_d.c cmp_si.c cmp_ui.c mul_2exp.c div_2exp.c abs.c neg.c get_d.c \
+ get_d_2exp.c set_dfl_prec.c set_prc.c set_prc_raw.c get_dfl_prec.c get_prc.c \
+ ui_div.c sqrt_ui.c \
+ pow_ui.c urandomb.c swap.c get_si.c get_ui.c int_p.c \
+ ceilfloor.c trunc.c \
+ fits_sint.c fits_slong.c fits_sshort.c \
+ fits_uint.c fits_ulong.c fits_ushort.c \
+ fits_s.h fits_u.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 mpf/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps mpf/Makefile
+.PRECIOUS: 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-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libmpf.la: $(libmpf_la_OBJECTS) $(libmpf_la_DEPENDENCIES) $(EXTRA_libmpf_la_DEPENDENCIES)
+ $(LINK) $(libmpf_la_OBJECTS) $(libmpf_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+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:
+
+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-generic clean-libtool clean-noinstLTLIBRARIES \
+ 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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags 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 tags uninstall uninstall-am
+
+
+# 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/gmp/mpf/abs.c b/gmp/mpf/abs.c
new file mode 100644
index 0000000000..a2bde2a4f8
--- /dev/null
+++ b/gmp/mpf/abs.c
@@ -0,0 +1,59 @@
+/* mpf_abs -- Compute the absolute value of a float.
+
+Copyright 1993-1995, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_abs (mpf_ptr r, mpf_srcptr u)
+{
+ mp_size_t size;
+
+ size = ABS (u->_mp_size);
+ if (r != u)
+ {
+ mp_size_t prec;
+ mp_ptr rp, up;
+
+ prec = r->_mp_prec + 1; /* lie not to lose precision in assignment */
+ rp = r->_mp_d;
+ up = u->_mp_d;
+
+ if (size > prec)
+ {
+ up += size - prec;
+ size = prec;
+ }
+
+ MPN_COPY (rp, up, size);
+ r->_mp_exp = u->_mp_exp;
+ }
+ r->_mp_size = size;
+}
diff --git a/gmp/mpf/add.c b/gmp/mpf/add.c
new file mode 100644
index 0000000000..d2a5c097c5
--- /dev/null
+++ b/gmp/mpf/add.c
@@ -0,0 +1,184 @@
+/* mpf_add -- Add two floats.
+
+Copyright 1993, 1994, 1996, 2000, 2001, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_add (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
+{
+ mp_srcptr up, vp;
+ mp_ptr rp, tp;
+ mp_size_t usize, vsize, rsize;
+ mp_size_t prec;
+ mp_exp_t uexp;
+ mp_size_t ediff;
+ mp_limb_t cy;
+ int negate;
+ TMP_DECL;
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+
+ /* Handle special cases that don't work in generic code below. */
+ if (usize == 0)
+ {
+ set_r_v_maybe:
+ if (r != v)
+ mpf_set (r, v);
+ return;
+ }
+ if (vsize == 0)
+ {
+ v = u;
+ goto set_r_v_maybe;
+ }
+
+ /* If signs of U and V are different, perform subtraction. */
+ if ((usize ^ vsize) < 0)
+ {
+ __mpf_struct v_negated;
+ v_negated._mp_size = -vsize;
+ v_negated._mp_exp = v->_mp_exp;
+ v_negated._mp_d = v->_mp_d;
+ mpf_sub (r, u, &v_negated);
+ return;
+ }
+
+ TMP_MARK;
+
+ /* Signs are now known to be the same. */
+ negate = usize < 0;
+
+ /* Make U be the operand with the largest exponent. */
+ if (u->_mp_exp < v->_mp_exp)
+ {
+ mpf_srcptr t;
+ t = u; u = v; v = t;
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+ }
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ rp = r->_mp_d;
+ prec = r->_mp_prec;
+ uexp = u->_mp_exp;
+ ediff = u->_mp_exp - v->_mp_exp;
+
+ /* If U extends beyond PREC, ignore the part that does. */
+ if (usize > prec)
+ {
+ up += usize - prec;
+ usize = prec;
+ }
+
+ /* If V extends beyond PREC, ignore the part that does.
+ Note that this may make vsize negative. */
+ if (vsize + ediff > prec)
+ {
+ vp += vsize + ediff - prec;
+ vsize = prec - ediff;
+ }
+
+#if 0
+ /* Locate the least significant non-zero limb in (the needed parts
+ of) U and V, to simplify the code below. */
+ while (up[0] == 0)
+ up++, usize--;
+ while (vp[0] == 0)
+ vp++, vsize--;
+#endif
+
+ /* Allocate temp space for the result. Allocate
+ just vsize + ediff later??? */
+ tp = TMP_ALLOC_LIMBS (prec);
+
+ if (ediff >= prec)
+ {
+ /* V completely cancelled. */
+ if (rp != up)
+ MPN_COPY_INCR (rp, up, usize);
+ rsize = usize;
+ }
+ else
+ {
+ /* uuuu | uuuu | uuuu | uuuu | uuuu */
+ /* vvvvvvv | vv | vvvvv | v | vv */
+
+ if (usize > ediff)
+ {
+ /* U and V partially overlaps. */
+ if (vsize + ediff <= usize)
+ {
+ /* uuuu */
+ /* v */
+ mp_size_t size;
+ size = usize - ediff - vsize;
+ MPN_COPY (tp, up, size);
+ cy = mpn_add (tp + size, up + size, usize - size, vp, vsize);
+ rsize = usize;
+ }
+ else
+ {
+ /* uuuu */
+ /* vvvvv */
+ mp_size_t size;
+ size = vsize + ediff - usize;
+ MPN_COPY (tp, vp, size);
+ cy = mpn_add (tp + size, up, usize, vp + size, usize - ediff);
+ rsize = vsize + ediff;
+ }
+ }
+ else
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size;
+ size = vsize + ediff - usize;
+ MPN_COPY (tp, vp, vsize);
+ MPN_ZERO (tp + vsize, ediff - usize);
+ MPN_COPY (tp + size, up, usize);
+ cy = 0;
+ rsize = size + usize;
+ }
+
+ MPN_COPY (rp, tp, rsize);
+ rp[rsize] = cy;
+ rsize += cy;
+ uexp += cy;
+ }
+
+ r->_mp_size = negate ? -rsize : rsize;
+ r->_mp_exp = uexp;
+ TMP_FREE;
+}
diff --git a/gmp/mpf/add_ui.c b/gmp/mpf/add_ui.c
new file mode 100644
index 0000000000..b1e57d04c1
--- /dev/null
+++ b/gmp/mpf/add_ui.c
@@ -0,0 +1,153 @@
+/* mpf_add_ui -- Add a float and an unsigned integer.
+
+Copyright 1993, 1994, 1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_add_ui (mpf_ptr sum, mpf_srcptr u, unsigned long int v)
+{
+ mp_srcptr up = u->_mp_d;
+ mp_ptr sump = sum->_mp_d;
+ mp_size_t usize, sumsize;
+ mp_size_t prec = sum->_mp_prec;
+ mp_exp_t uexp = u->_mp_exp;
+
+ usize = u->_mp_size;
+ if (usize <= 0)
+ {
+ if (usize == 0)
+ {
+ mpf_set_ui (sum, v);
+ return;
+ }
+ else
+ {
+ __mpf_struct u_negated;
+ u_negated._mp_size = -usize;
+ u_negated._mp_exp = u->_mp_exp;
+ u_negated._mp_d = u->_mp_d;
+ mpf_sub_ui (sum, &u_negated, v);
+ sum->_mp_size = -(sum->_mp_size);
+ return;
+ }
+ }
+
+ if (v == 0)
+ {
+ sum_is_u:
+ if (u != sum)
+ {
+ sumsize = MIN (usize, prec + 1);
+ MPN_COPY (sum->_mp_d, up + usize - sumsize, sumsize);
+ sum->_mp_size = sumsize;
+ sum->_mp_exp = u->_mp_exp;
+ }
+ return;
+ }
+
+ if (uexp > 0)
+ {
+ /* U >= 1. */
+ if (uexp > prec)
+ {
+ /* U >> V, V is not part of final result. */
+ goto sum_is_u;
+ }
+ else
+ {
+ /* U's "limb point" is somewhere between the first limb
+ and the PREC:th limb.
+ Both U and V are part of the final result. */
+ if (uexp > usize)
+ {
+ /* uuuuuu0000. */
+ /* + v. */
+ /* We begin with moving U to the top of SUM, to handle
+ samevar(U,SUM). */
+ MPN_COPY_DECR (sump + uexp - usize, up, usize);
+ sump[0] = v;
+ MPN_ZERO (sump + 1, uexp - usize - 1);
+#if 0 /* What is this??? */
+ if (sum == u)
+ MPN_COPY (sum->_mp_d, sump, uexp);
+#endif
+ sum->_mp_size = uexp;
+ sum->_mp_exp = uexp;
+ }
+ else
+ {
+ /* uuuuuu.uuuu */
+ /* + v. */
+ mp_limb_t cy_limb;
+ if (usize > prec)
+ {
+ /* Ignore excess limbs in U. */
+ up += usize - prec;
+ usize -= usize - prec; /* Eq. usize = prec */
+ }
+ if (sump != up)
+ MPN_COPY_INCR (sump, up, usize - uexp);
+ cy_limb = mpn_add_1 (sump + usize - uexp, up + usize - uexp,
+ uexp, (mp_limb_t) v);
+ sump[usize] = cy_limb;
+ sum->_mp_size = usize + cy_limb;
+ sum->_mp_exp = uexp + cy_limb;
+ }
+ }
+ }
+ else
+ {
+ /* U < 1, so V > U for sure. */
+ /* v. */
+ /* .0000uuuu */
+ if ((-uexp) >= prec)
+ {
+ sump[0] = v;
+ sum->_mp_size = 1;
+ sum->_mp_exp = 1;
+ }
+ else
+ {
+ if (usize + (-uexp) + 1 > prec)
+ {
+ /* Ignore excess limbs in U. */
+ up += usize + (-uexp) + 1 - prec;
+ usize -= usize + (-uexp) + 1 - prec;
+ }
+ if (sump != up)
+ MPN_COPY_INCR (sump, up, usize);
+ MPN_ZERO (sump + usize, -uexp);
+ sump[usize + (-uexp)] = v;
+ sum->_mp_size = usize + (-uexp) + 1;
+ sum->_mp_exp = 1;
+ }
+ }
+}
diff --git a/gmp/mpf/ceilfloor.c b/gmp/mpf/ceilfloor.c
new file mode 100644
index 0000000000..302e2b8ae5
--- /dev/null
+++ b/gmp/mpf/ceilfloor.c
@@ -0,0 +1,126 @@
+/* mpf_ceil, mpf_floor -- round an mpf to an integer.
+
+Copyright 2001, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* dir==1 for ceil, dir==-1 for floor
+
+ Notice the use of prec+1 ensures mpf_ceil and mpf_floor are equivalent to
+ mpf_set if u is already an integer. */
+
+static void __gmpf_ceil_or_floor (REGPARM_2_1 (mpf_ptr, mpf_srcptr, int)) REGPARM_ATTR (1);
+#define mpf_ceil_or_floor(r,u,dir) __gmpf_ceil_or_floor (REGPARM_2_1 (r, u, dir))
+
+REGPARM_ATTR (1) static void
+mpf_ceil_or_floor (mpf_ptr r, mpf_srcptr u, int dir)
+{
+ mp_ptr rp, up, p;
+ mp_size_t size, asize, prec;
+ mp_exp_t exp;
+
+ size = SIZ(u);
+ if (size == 0)
+ {
+ zero:
+ SIZ(r) = 0;
+ EXP(r) = 0;
+ return;
+ }
+
+ rp = PTR(r);
+ exp = EXP(u);
+ if (exp <= 0)
+ {
+ /* u is only a fraction */
+ if ((size ^ dir) < 0)
+ goto zero;
+ rp[0] = 1;
+ EXP(r) = 1;
+ SIZ(r) = dir;
+ return;
+ }
+ EXP(r) = exp;
+
+ up = PTR(u);
+ asize = ABS (size);
+ up += asize;
+
+ /* skip fraction part of u */
+ asize = MIN (asize, exp);
+
+ /* don't lose precision in the copy */
+ prec = PREC (r) + 1;
+
+ /* skip excess over target precision */
+ asize = MIN (asize, prec);
+
+ up -= asize;
+
+ if ((size ^ dir) >= 0)
+ {
+ /* rounding direction matches sign, must increment if ignored part is
+ non-zero */
+ for (p = PTR(u); p != up; p++)
+ {
+ if (*p != 0)
+ {
+ if (mpn_add_1 (rp, up, asize, CNST_LIMB(1)))
+ {
+ /* was all 0xFF..FFs, which have become zeros, giving just
+ a carry */
+ rp[0] = 1;
+ asize = 1;
+ EXP(r)++;
+ }
+ SIZ(r) = (size >= 0 ? asize : -asize);
+ return;
+ }
+ }
+ }
+
+ SIZ(r) = (size >= 0 ? asize : -asize);
+ if (rp != up)
+ MPN_COPY_INCR (rp, up, asize);
+}
+
+
+void
+mpf_ceil (mpf_ptr r, mpf_srcptr u)
+{
+ mpf_ceil_or_floor (r, u, 1);
+}
+
+void
+mpf_floor (mpf_ptr r, mpf_srcptr u)
+{
+ mpf_ceil_or_floor (r, u, -1);
+}
diff --git a/gmp/mpf/clear.c b/gmp/mpf/clear.c
new file mode 100644
index 0000000000..2df0de579b
--- /dev/null
+++ b/gmp/mpf/clear.c
@@ -0,0 +1,39 @@
+/* mpf_clear -- de-allocate the space occupied by the dynamic digit space of
+ an integer.
+
+Copyright 1993-1995, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_clear (mpf_ptr m)
+{
+ (*__gmp_free_func) (m->_mp_d, (size_t) (m->_mp_prec + 1) * GMP_LIMB_BYTES);
+}
diff --git a/gmp/mpf/clears.c b/gmp/mpf/clears.c
new file mode 100644
index 0000000000..addbe8faf3
--- /dev/null
+++ b/gmp/mpf/clears.c
@@ -0,0 +1,49 @@
+/* mpf_clears() -- Clear multiple mpf_t variables.
+
+Copyright 2009, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_clears (mpf_ptr x, ...)
+{
+ va_list ap;
+
+ va_start (ap, x);
+
+ while (x != NULL)
+ {
+ (*__gmp_free_func) (x->_mp_d, (size_t) (x->_mp_prec + 1) * GMP_LIMB_BYTES);
+ x = va_arg (ap, mpf_ptr);
+ }
+ va_end (ap);
+}
diff --git a/gmp/mpf/cmp.c b/gmp/mpf/cmp.c
new file mode 100644
index 0000000000..ab22c3f89c
--- /dev/null
+++ b/gmp/mpf/cmp.c
@@ -0,0 +1,117 @@
+/* mpf_cmp -- Compare two floats.
+
+Copyright 1993, 1994, 1996, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpf_cmp (mpf_srcptr u, mpf_srcptr v) __GMP_NOTHROW
+{
+ mp_srcptr up, vp;
+ mp_size_t usize, vsize;
+ mp_exp_t uexp, vexp;
+ int cmp;
+ int usign;
+
+ uexp = u->_mp_exp;
+ vexp = v->_mp_exp;
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+
+ /* 1. Are the signs different? */
+ if ((usize ^ vsize) >= 0)
+ {
+ /* U and V are both non-negative or both negative. */
+ if (usize == 0)
+ /* vsize >= 0 */
+ return -(vsize != 0);
+ if (vsize == 0)
+ /* usize >= 0 */
+ return usize != 0;
+ /* Fall out. */
+ }
+ else
+ {
+ /* Either U or V is negative, but not both. */
+ return usize >= 0 ? 1 : -1;
+ }
+
+ /* U and V have the same sign and are both non-zero. */
+
+ usign = usize >= 0 ? 1 : -1;
+
+ /* 2. Are the exponents different? */
+ if (uexp > vexp)
+ return usign;
+ if (uexp < vexp)
+ return -usign;
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+#define STRICT_MPF_NORMALIZATION 0
+#if ! STRICT_MPF_NORMALIZATION
+ /* Ignore zeroes at the low end of U and V. */
+ while (up[0] == 0)
+ {
+ up++;
+ usize--;
+ }
+ while (vp[0] == 0)
+ {
+ vp++;
+ vsize--;
+ }
+#endif
+
+ if (usize > vsize)
+ {
+ cmp = mpn_cmp (up + usize - vsize, vp, vsize);
+ if (cmp == 0)
+ return usign;
+ }
+ else if (vsize > usize)
+ {
+ cmp = mpn_cmp (up, vp + vsize - usize, usize);
+ if (cmp == 0)
+ return -usign;
+ }
+ else
+ {
+ cmp = mpn_cmp (up, vp, usize);
+ if (cmp == 0)
+ return 0;
+ }
+ return cmp > 0 ? usign : -usign;
+}
diff --git a/gmp/mpf/cmp_d.c b/gmp/mpf/cmp_d.c
new file mode 100644
index 0000000000..52893a781e
--- /dev/null
+++ b/gmp/mpf/cmp_d.c
@@ -0,0 +1,60 @@
+/* mpf_cmp_d -- compare mpf and double.
+
+Copyright 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if HAVE_FLOAT_H
+#include <float.h> /* for DBL_MAX */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpf_cmp_d (mpf_srcptr f, double d)
+{
+ mp_limb_t darray[LIMBS_PER_DOUBLE];
+ mpf_t df;
+
+ /* d=NaN has no sensible return value, so raise an exception.
+ d=Inf or -Inf is always bigger than z. */
+ DOUBLE_NAN_INF_ACTION (d,
+ __gmp_invalid_operation (),
+ return (d < 0.0 ? 1 : -1));
+
+ if (d == 0.0)
+ return SIZ(f);
+
+ PTR(df) = darray;
+ SIZ(df) = (d >= 0.0 ? LIMBS_PER_DOUBLE : -LIMBS_PER_DOUBLE);
+ EXP(df) = __gmp_extract_double (darray, ABS(d));
+
+ return mpf_cmp (f, df);
+}
diff --git a/gmp/mpf/cmp_si.c b/gmp/mpf/cmp_si.c
new file mode 100644
index 0000000000..eaa8b87da9
--- /dev/null
+++ b/gmp/mpf/cmp_si.c
@@ -0,0 +1,118 @@
+/* mpf_cmp_si -- Compare a float with a signed integer.
+
+Copyright 1993-1995, 1999-2002, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpf_cmp_si (mpf_srcptr u, long int vval) __GMP_NOTHROW
+{
+ mp_srcptr up;
+ mp_size_t usize;
+ mp_exp_t uexp;
+ mp_limb_t ulimb;
+ int usign;
+ unsigned long abs_vval;
+
+ uexp = u->_mp_exp;
+ usize = u->_mp_size;
+
+ /* 1. Are the signs different? */
+ if ((usize < 0) == (vval < 0)) /* don't use xor, type size may differ */
+ {
+ /* U and V are both non-negative or both negative. */
+ if (usize == 0)
+ /* vval >= 0 */
+ return -(vval != 0);
+ if (vval == 0)
+ /* usize >= 0 */
+ return usize != 0;
+ /* Fall out. */
+ }
+ else
+ {
+ /* Either U or V is negative, but not both. */
+ return usize >= 0 ? 1 : -1;
+ }
+
+ /* U and V have the same sign and are both non-zero. */
+
+ usign = usize >= 0 ? 1 : -1;
+ usize = ABS (usize);
+ abs_vval = ABS_CAST (unsigned long, vval);
+
+ /* 2. Are the exponents different (V's exponent == 1)? */
+#if GMP_NAIL_BITS != 0
+ if (uexp > 1 + (abs_vval > GMP_NUMB_MAX))
+ return usign;
+ if (uexp < 1 + (abs_vval > GMP_NUMB_MAX))
+ return -usign;
+#else
+ if (uexp > 1)
+ return usign;
+ if (uexp < 1)
+ return -usign;
+#endif
+
+ up = u->_mp_d;
+
+ ulimb = up[usize - 1];
+#if GMP_NAIL_BITS != 0
+ if (usize >= 2 && uexp == 2)
+ {
+ if ((ulimb >> GMP_NAIL_BITS) != 0)
+ return usign;
+ ulimb = (ulimb << GMP_NUMB_BITS) | up[usize - 2];
+ usize--;
+ }
+#endif
+ usize--;
+
+ /* 3. Compare the most significant mantissa limb with V. */
+ if (ulimb > abs_vval)
+ return usign;
+ else if (ulimb < abs_vval)
+ return -usign;
+
+ /* Ignore zeroes at the low end of U. */
+ while (*up == 0)
+ {
+ up++;
+ usize--;
+ }
+
+ /* 4. Now, if the number of limbs are different, we have a difference
+ since we have made sure the trailing limbs are not zero. */
+ if (usize > 0)
+ return usign;
+
+ /* Wow, we got zero even if we tried hard to avoid it. */
+ return 0;
+}
diff --git a/gmp/mpf/cmp_ui.c b/gmp/mpf/cmp_ui.c
new file mode 100644
index 0000000000..ccb76c6ce0
--- /dev/null
+++ b/gmp/mpf/cmp_ui.c
@@ -0,0 +1,100 @@
+/* mpf_cmp_ui -- Compare a float with an unsigned integer.
+
+Copyright 1993-1995, 1999, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpf_cmp_ui (mpf_srcptr u, unsigned long int vval) __GMP_NOTHROW
+{
+ mp_srcptr up;
+ mp_size_t usize;
+ mp_exp_t uexp;
+ mp_limb_t ulimb;
+
+ uexp = u->_mp_exp;
+ usize = u->_mp_size;
+
+ /* 1. Is U negative? */
+ if (usize < 0)
+ return -1;
+ /* We rely on usize being non-negative in the code that follows. */
+
+ if (vval == 0)
+ return usize != 0;
+
+ /* 2. Are the exponents different (V's exponent == 1)? */
+#if GMP_NAIL_BITS != 0
+ if (uexp > 1 + (vval > GMP_NUMB_MAX))
+ return 1;
+ if (uexp < 1 + (vval > GMP_NUMB_MAX))
+ return -1;
+#else
+ if (uexp > 1)
+ return 1;
+ if (uexp < 1)
+ return -1;
+#endif
+
+ up = u->_mp_d;
+
+ ulimb = up[usize - 1];
+#if GMP_NAIL_BITS != 0
+ if (usize >= 2 && uexp == 2)
+ {
+ if ((ulimb >> GMP_NAIL_BITS) != 0)
+ return 1;
+ ulimb = (ulimb << GMP_NUMB_BITS) | up[usize - 2];
+ usize--;
+ }
+#endif
+ usize--;
+
+ /* 3. Compare the most significant mantissa limb with V. */
+ if (ulimb > vval)
+ return 1;
+ else if (ulimb < vval)
+ return -1;
+
+ /* Ignore zeroes at the low end of U. */
+ while (*up == 0)
+ {
+ up++;
+ usize--;
+ }
+
+ /* 4. Now, if the number of limbs are different, we have a difference
+ since we have made sure the trailing limbs are not zero. */
+ if (usize > 0)
+ return 1;
+
+ /* Wow, we got zero even if we tried hard to avoid it. */
+ return 0;
+}
diff --git a/gmp/mpf/div.c b/gmp/mpf/div.c
new file mode 100644
index 0000000000..af38cb8698
--- /dev/null
+++ b/gmp/mpf/div.c
@@ -0,0 +1,138 @@
+/* mpf_div -- Divide two floats.
+
+Copyright 1993, 1994, 1996, 2000-2002, 2004, 2005, 2010, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Not done:
+
+ No attempt is made to identify an overlap u==v. The result will be
+ correct (1.0), but a full actual division is done whereas of course
+ x/x==1 needs no work. Such a call is not a sensible thing to make, and
+ it's left to an application to notice and optimize if it might arise
+ somehow through pointer aliasing or whatever.
+
+ Enhancements:
+
+ The high quotient limb is non-zero when high{up,vsize} >= {vp,vsize}. We
+ could make that comparison and use qsize==prec instead of qsize==prec+1,
+ to save one limb in the division.
+
+ If r==u but the size is enough bigger than prec that there won't be an
+ overlap between quotient and dividend in mpn_div_q, then we can avoid
+ copying up,usize. This would only arise from a prec reduced with
+ mpf_set_prec_raw and will be pretty unusual, but might be worthwhile if
+ it could be worked into the copy_u decision cleanly. */
+
+void
+mpf_div (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
+{
+ mp_srcptr up, vp;
+ mp_ptr rp, tp, new_vp;
+ mp_size_t usize, vsize, rsize, prospective_rsize, tsize, zeros;
+ mp_size_t sign_quotient, prec, high_zero, chop;
+ mp_exp_t rexp;
+ int copy_u;
+ TMP_DECL;
+
+ usize = SIZ(u);
+ vsize = SIZ(v);
+
+ if (UNLIKELY (vsize == 0))
+ DIVIDE_BY_ZERO;
+
+ if (usize == 0)
+ {
+ SIZ(r) = 0;
+ EXP(r) = 0;
+ return;
+ }
+
+ sign_quotient = usize ^ vsize;
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+ prec = PREC(r);
+
+ TMP_MARK;
+ rexp = EXP(u) - EXP(v) + 1;
+
+ rp = PTR(r);
+ up = PTR(u);
+ vp = PTR(v);
+
+ prospective_rsize = usize - vsize + 1; /* quot from using given u,v sizes */
+ rsize = prec + 1; /* desired quot */
+
+ zeros = rsize - prospective_rsize; /* padding u to give rsize */
+ copy_u = (zeros > 0 || rp == up); /* copy u if overlap or padding */
+
+ chop = MAX (-zeros, 0); /* negative zeros means shorten u */
+ up += chop;
+ usize -= chop;
+ zeros += chop; /* now zeros >= 0 */
+
+ tsize = usize + zeros; /* size for possible copy of u */
+
+ /* copy and possibly extend u if necessary */
+ if (copy_u)
+ {
+ tp = TMP_ALLOC_LIMBS (tsize + 1); /* +1 for mpn_div_q's scratch needs */
+ MPN_ZERO (tp, zeros);
+ MPN_COPY (tp+zeros, up, usize);
+ up = tp;
+ usize = tsize;
+ }
+ else
+ {
+ tp = TMP_ALLOC_LIMBS (usize + 1);
+ }
+
+ /* ensure divisor doesn't overlap quotient */
+ if (rp == vp)
+ {
+ new_vp = TMP_ALLOC_LIMBS (vsize);
+ MPN_COPY (new_vp, vp, vsize);
+ vp = new_vp;
+ }
+
+ ASSERT (usize-vsize+1 == rsize);
+ mpn_div_q (rp, up, usize, vp, vsize, tp);
+
+ /* strip possible zero high limb */
+ high_zero = (rp[rsize-1] == 0);
+ rsize -= high_zero;
+ rexp -= high_zero;
+
+ SIZ(r) = sign_quotient >= 0 ? rsize : -rsize;
+ EXP(r) = rexp;
+ TMP_FREE;
+}
diff --git a/gmp/mpf/div_2exp.c b/gmp/mpf/div_2exp.c
new file mode 100644
index 0000000000..fef8152050
--- /dev/null
+++ b/gmp/mpf/div_2exp.c
@@ -0,0 +1,139 @@
+/* mpf_div_2exp -- Divide a float by 2^n.
+
+Copyright 1993, 1994, 1996, 2000-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Multiples of GMP_NUMB_BITS in exp simply mean an amount subtracted from
+ EXP(u) to set EXP(r). The remainder exp%GMP_NUMB_BITS is then a right
+ shift for the limb data.
+
+ If exp%GMP_NUMB_BITS == 0 then there's no shifting, we effectively just
+ do an mpz_set with changed EXP(r). Like mpz_set we take prec+1 limbs in
+ this case. Although just prec would suffice, it's nice to have
+ mpf_div_2exp with exp==0 come out the same as mpz_set.
+
+ When shifting we take up to prec many limbs from the input. Our shift is
+ cy = mpn_rshift (PTR(r)+1, PTR(u)+k, ...), where k is the number of low
+ limbs dropped from u, and the carry out is stored to PTR(r)[0]. We don't
+ try to work extra bits from PTR(u)[k-1] (when k>=1 makes it available)
+ into that low carry limb. Just prec limbs (with the high non-zero) from
+ the input is enough bits for the application requested precision, no need
+ to do extra work.
+
+ If r==u the shift will have overlapping operands. When k>=1 (ie. when
+ usize > prec), the overlap is in the style supported by rshift (ie. dst
+ <= src).
+
+ But when r==u and k==0 (ie. usize <= prec), we would have an invalid
+ overlap (mpn_rshift (rp+1, rp, ...)). In this case we must instead use
+ mpn_lshift (PTR(r), PTR(u), size, NUMB-shift). An lshift by NUMB-shift
+ bits gives identical data of course, it's just its overlap restrictions
+ which differ.
+
+ In both shift cases, the resulting data is abs_usize+1 limbs. "adj" is
+ used to add +1 to that size if the high is non-zero (it may of course
+ have become zero by the shifting). EXP(u) is the exponent just above
+ those abs_usize+1 limbs, so it gets -1+adj, which means -1 if the high is
+ zero, or no change if the high is non-zero.
+
+ Enhancements:
+
+ The way mpn_lshift is used means successive mpf_div_2exp calls on the
+ same operand will accumulate low zero limbs, until prec+1 limbs is
+ reached. This is wasteful for subsequent operations. When abs_usize <=
+ prec, we should test the low exp%GMP_NUMB_BITS many bits of PTR(u)[0],
+ ie. those which would be shifted out by an mpn_rshift. If they're zero
+ then use that mpn_rshift. */
+
+void
+mpf_div_2exp (mpf_ptr r, mpf_srcptr u, mp_bitcnt_t exp)
+{
+ mp_srcptr up;
+ mp_ptr rp = r->_mp_d;
+ mp_size_t usize;
+ mp_size_t abs_usize;
+ mp_size_t prec = r->_mp_prec;
+ mp_exp_t uexp = u->_mp_exp;
+
+ usize = u->_mp_size;
+
+ if (UNLIKELY (usize == 0))
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ abs_usize = ABS (usize);
+ up = u->_mp_d;
+
+ if (exp % GMP_NUMB_BITS == 0)
+ {
+ prec++; /* retain more precision here as we don't need
+ to account for carry-out here */
+ if (abs_usize > prec)
+ {
+ up += abs_usize - prec;
+ abs_usize = prec;
+ }
+ if (rp != up)
+ MPN_COPY_INCR (rp, up, abs_usize);
+ r->_mp_exp = uexp - exp / GMP_NUMB_BITS;
+ }
+ else
+ {
+ mp_limb_t cy_limb;
+ mp_size_t adj;
+ if (abs_usize > prec)
+ {
+ up += abs_usize - prec;
+ abs_usize = prec;
+ /* Use mpn_rshift since mpn_lshift operates downwards, and we
+ therefore would clobber part of U before using that part, in case
+ R is the same variable as U. */
+ cy_limb = mpn_rshift (rp + 1, up, abs_usize, exp % GMP_NUMB_BITS);
+ rp[0] = cy_limb;
+ adj = rp[abs_usize] != 0;
+ }
+ else
+ {
+ cy_limb = mpn_lshift (rp, up, abs_usize,
+ GMP_NUMB_BITS - exp % GMP_NUMB_BITS);
+ rp[abs_usize] = cy_limb;
+ adj = cy_limb != 0;
+ }
+
+ abs_usize += adj;
+ r->_mp_exp = uexp - exp / GMP_NUMB_BITS - 1 + adj;
+ }
+ r->_mp_size = usize >= 0 ? abs_usize : -abs_usize;
+}
diff --git a/gmp/mpf/div_ui.c b/gmp/mpf/div_ui.c
new file mode 100644
index 0000000000..9be7e680be
--- /dev/null
+++ b/gmp/mpf/div_ui.c
@@ -0,0 +1,111 @@
+/* mpf_div_ui -- Divide a float with an unsigned integer.
+
+Copyright 1993, 1994, 1996, 2000-2002, 2004, 2005, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpf_div_ui (mpf_ptr r, mpf_srcptr u, unsigned long int v)
+{
+ mp_srcptr up;
+ mp_ptr rp, tp, rtp;
+ mp_size_t usize;
+ mp_size_t rsize, tsize;
+ mp_size_t sign_quotient;
+ mp_size_t prec;
+ mp_limb_t q_limb;
+ mp_exp_t rexp;
+ TMP_DECL;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (v > GMP_NUMB_MAX)
+ {
+ mpf_t vf;
+ mp_limb_t vl[2];
+ SIZ(vf) = 2;
+ EXP(vf) = 2;
+ PTR(vf) = vl;
+ vl[0] = v & GMP_NUMB_MASK;
+ vl[1] = v >> GMP_NUMB_BITS;
+ mpf_div (r, u, vf);
+ return;
+ }
+#endif
+
+ if (UNLIKELY (v == 0))
+ DIVIDE_BY_ZERO;
+
+ usize = u->_mp_size;
+
+ if (usize == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ sign_quotient = usize;
+ usize = ABS (usize);
+ prec = r->_mp_prec;
+
+ TMP_MARK;
+
+ rp = r->_mp_d;
+ up = u->_mp_d;
+
+ tsize = 1 + prec;
+ tp = TMP_ALLOC_LIMBS (tsize + 1);
+
+ if (usize > tsize)
+ {
+ up += usize - tsize;
+ usize = tsize;
+ rtp = tp;
+ }
+ else
+ {
+ MPN_ZERO (tp, tsize - usize);
+ rtp = tp + (tsize - usize);
+ }
+
+ /* Move the dividend to the remainder. */
+ MPN_COPY (rtp, up, usize);
+
+ mpn_divmod_1 (rp, tp, tsize, (mp_limb_t) v);
+ q_limb = rp[tsize - 1];
+
+ rsize = tsize - (q_limb == 0);
+ rexp = u->_mp_exp - (q_limb == 0);
+ r->_mp_size = sign_quotient >= 0 ? rsize : -rsize;
+ r->_mp_exp = rexp;
+ TMP_FREE;
+}
diff --git a/gmp/mpf/dump.c b/gmp/mpf/dump.c
new file mode 100644
index 0000000000..af67105923
--- /dev/null
+++ b/gmp/mpf/dump.c
@@ -0,0 +1,53 @@
+/* mpf_dump -- Dump a float to stdout.
+
+ THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS NOT SAFE TO
+ CALL THIS FUNCTION DIRECTLY. IN FACT, IT IS ALMOST GUARANTEED THAT THIS
+ FUNCTION WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+
+Copyright 1993-1995, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <string.h> /* for strlen */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_dump (mpf_srcptr u)
+{
+ mp_exp_t exp;
+ char *str;
+
+ str = mpf_get_str (0, &exp, 10, 0, u);
+ if (str[0] == '-')
+ printf ("-0.%se%ld\n", str + 1, exp);
+ else
+ printf ("0.%se%ld\n", str, exp);
+ (*__gmp_free_func) (str, strlen (str) + 1);
+}
diff --git a/gmp/mpf/eq.c b/gmp/mpf/eq.c
new file mode 100644
index 0000000000..30c6befd06
--- /dev/null
+++ b/gmp/mpf/eq.c
@@ -0,0 +1,150 @@
+/* mpf_eq -- Compare two floats up to a specified bit #.
+
+Copyright 1993, 1995, 1996, 2001, 2002, 2008, 2009, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+int
+mpf_eq (mpf_srcptr u, mpf_srcptr v, mp_bitcnt_t n_bits)
+{
+ mp_srcptr up, vp, p;
+ mp_size_t usize, vsize, minsize, maxsize, n_limbs, i, size;
+ mp_exp_t uexp, vexp;
+ mp_limb_t diff;
+ int cnt;
+
+ uexp = u->_mp_exp;
+ vexp = v->_mp_exp;
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+
+ /* 1. Are the signs different? */
+ if ((usize ^ vsize) >= 0)
+ {
+ /* U and V are both non-negative or both negative. */
+ if (usize == 0)
+ return vsize == 0;
+ if (vsize == 0)
+ return 0;
+
+ /* Fall out. */
+ }
+ else
+ {
+ /* Either U or V is negative, but not both. */
+ return 0;
+ }
+
+ /* U and V have the same sign and are both non-zero. */
+
+ /* 2. Are the exponents different? */
+ if (uexp != vexp)
+ return 0;
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ up += usize; /* point just above most significant limb */
+ vp += vsize; /* point just above most significant limb */
+
+ count_leading_zeros (cnt, up[-1]);
+ if ((vp[-1] >> (GMP_LIMB_BITS - 1 - cnt)) != 1)
+ return 0; /* msb positions different */
+
+ n_bits += cnt - GMP_NAIL_BITS;
+ n_limbs = (n_bits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
+
+ usize = MIN (usize, n_limbs);
+ vsize = MIN (vsize, n_limbs);
+
+#if 0
+ /* Ignore zeros at the low end of U and V. */
+ while (up[0] == 0)
+ up++, usize--;
+ while (vp[0] == 0)
+ vp++, vsize--;
+#endif
+
+ minsize = MIN (usize, vsize);
+ maxsize = usize + vsize - minsize;
+
+ up -= minsize; /* point at most significant common limb */
+ vp -= minsize; /* point at most significant common limb */
+
+ /* Compare the most significant part which has explicit limbs for U and V. */
+ for (i = minsize - 1; i > 0; i--)
+ {
+ if (up[i] != vp[i])
+ return 0;
+ }
+
+ n_bits -= (maxsize - 1) * GMP_NUMB_BITS;
+
+ size = maxsize - minsize;
+ if (size != 0)
+ {
+ if (up[0] != vp[0])
+ return 0;
+
+ /* Now either U or V has its limbs consumed, i.e, continues with an
+ infinite number of implicit zero limbs. Check that the other operand
+ has just zeros in the corresponding, relevant part. */
+
+ if (usize > vsize)
+ p = up - size;
+ else
+ p = vp - size;
+
+ for (i = size - 1; i > 0; i--)
+ {
+ if (p[i] != 0)
+ return 0;
+ }
+
+ diff = p[0];
+ }
+ else
+ {
+ /* Both U or V has its limbs consumed. */
+
+ diff = up[0] ^ vp[0];
+ }
+
+ if (n_bits < GMP_NUMB_BITS)
+ diff >>= GMP_NUMB_BITS - n_bits;
+
+ return diff == 0;
+}
diff --git a/gmp/mpf/fits_s.h b/gmp/mpf/fits_s.h
new file mode 100644
index 0000000000..ec2635f656
--- /dev/null
+++ b/gmp/mpf/fits_s.h
@@ -0,0 +1,75 @@
+/* mpf_fits_s*_p -- test whether an mpf fits a C signed type.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Notice this is equivalent to mpz_set_f + mpz_fits_s*_p. */
+
+int
+FUNCTION (mpf_srcptr f) __GMP_NOTHROW
+{
+ mp_size_t fs, fn;
+ mp_srcptr fp;
+ mp_exp_t exp;
+ mp_limb_t fl;
+
+ fs = SIZ(f);
+ if (fs == 0)
+ return 1; /* zero fits */
+
+ exp = EXP(f);
+ if (exp < 1)
+ return 1; /* -1 < f < 1 truncates to zero, so fits */
+
+ fp = PTR(f);
+ fn = ABS (fs);
+
+ if (exp == 1)
+ {
+ fl = fp[fn-1];
+ }
+#if GMP_NAIL_BITS != 0
+ else if (exp == 2 && MAXIMUM > GMP_NUMB_MAX)
+ {
+ fl = fp[fn-1];
+ if ((fl >> GMP_NAIL_BITS) != 0)
+ return 0;
+ fl = (fl << GMP_NUMB_BITS);
+ if (fn >= 2)
+ fl |= fp[fn-2];
+ }
+#endif
+ else
+ return 0;
+
+ return fl <= (fs >= 0 ? (mp_limb_t) MAXIMUM : - (mp_limb_t) MINIMUM);
+}
diff --git a/gmp/mpf/fits_sint.c b/gmp/mpf/fits_sint.c
new file mode 100644
index 0000000000..26ace07c38
--- /dev/null
+++ b/gmp/mpf/fits_sint.c
@@ -0,0 +1,36 @@
+/* mpf_fits_sint_p -- test whether an mpf fits an int.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define FUNCTION mpf_fits_sint_p
+#define MAXIMUM INT_MAX
+#define MINIMUM INT_MIN
+
+#include "fits_s.h"
diff --git a/gmp/mpf/fits_slong.c b/gmp/mpf/fits_slong.c
new file mode 100644
index 0000000000..25db68c47d
--- /dev/null
+++ b/gmp/mpf/fits_slong.c
@@ -0,0 +1,36 @@
+/* mpf_fits_slong_p -- test whether an mpf fits a long.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define FUNCTION mpf_fits_slong_p
+#define MAXIMUM LONG_MAX
+#define MINIMUM LONG_MIN
+
+#include "fits_s.h"
diff --git a/gmp/mpf/fits_sshort.c b/gmp/mpf/fits_sshort.c
new file mode 100644
index 0000000000..3bfc5a4a34
--- /dev/null
+++ b/gmp/mpf/fits_sshort.c
@@ -0,0 +1,36 @@
+/* mpf_fits_sshort_p -- test whether an mpf fits a short.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define FUNCTION mpf_fits_sshort_p
+#define MAXIMUM SHRT_MAX
+#define MINIMUM SHRT_MIN
+
+#include "fits_s.h"
diff --git a/gmp/mpf/fits_u.h b/gmp/mpf/fits_u.h
new file mode 100644
index 0000000000..65ac60e09a
--- /dev/null
+++ b/gmp/mpf/fits_u.h
@@ -0,0 +1,74 @@
+/* mpf_fits_u*_p -- test whether an mpf fits a C unsigned type.
+
+Copyright 2001, 2002, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Notice this is equivalent to mpz_set_f + mpz_fits_u*_p. */
+
+int
+FUNCTION (mpf_srcptr f) __GMP_NOTHROW
+{
+ mp_size_t fn;
+ mp_srcptr fp;
+ mp_exp_t exp;
+ mp_limb_t fl;
+
+ exp = EXP(f);
+ if (exp < 1)
+ return 1; /* -1 < f < 1 truncates to zero, so fits */
+
+ fn = SIZ(f);
+ if (fn <= 0)
+ return fn == 0; /* zero fits, negatives don't */
+
+ fp = PTR(f);
+
+ if (exp == 1)
+ {
+ fl = fp[fn-1];
+ }
+#if GMP_NAIL_BITS != 0
+ else if (exp == 2 && MAXIMUM > GMP_NUMB_MAX)
+ {
+ fl = fp[fn-1];
+ if ((fl >> GMP_NAIL_BITS) != 0)
+ return 0;
+ fl = (fl << GMP_NUMB_BITS);
+ if (fn >= 2)
+ fl |= fp[fn-2];
+ }
+#endif
+ else
+ return 0;
+
+ return fl <= MAXIMUM;
+}
diff --git a/gmp/mpf/fits_uint.c b/gmp/mpf/fits_uint.c
new file mode 100644
index 0000000000..4b107b04d8
--- /dev/null
+++ b/gmp/mpf/fits_uint.c
@@ -0,0 +1,35 @@
+/* mpf_fits_uint_p -- test whether an mpf fits an unsigned int.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define FUNCTION mpf_fits_uint_p
+#define MAXIMUM UINT_MAX
+
+#include "fits_u.h"
diff --git a/gmp/mpf/fits_ulong.c b/gmp/mpf/fits_ulong.c
new file mode 100644
index 0000000000..1db688ce4c
--- /dev/null
+++ b/gmp/mpf/fits_ulong.c
@@ -0,0 +1,35 @@
+/* mpf_fits_ulong_p -- test whether an mpf fits an unsigned long.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define FUNCTION mpf_fits_ulong_p
+#define MAXIMUM ULONG_MAX
+
+#include "fits_u.h"
diff --git a/gmp/mpf/fits_ushort.c b/gmp/mpf/fits_ushort.c
new file mode 100644
index 0000000000..76a3fd9d52
--- /dev/null
+++ b/gmp/mpf/fits_ushort.c
@@ -0,0 +1,35 @@
+/* mpf_fits_ushort_p -- test whether an mpf fits an unsigned short.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define FUNCTION mpf_fits_ushort_p
+#define MAXIMUM USHRT_MAX
+
+#include "fits_u.h"
diff --git a/gmp/mpf/get_d.c b/gmp/mpf/get_d.c
new file mode 100644
index 0000000000..8f6f9bbea1
--- /dev/null
+++ b/gmp/mpf/get_d.c
@@ -0,0 +1,47 @@
+/* double mpf_get_d (mpf_t src) -- return SRC truncated to a double.
+
+Copyright 1996, 2001-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+double
+mpf_get_d (mpf_srcptr src)
+{
+ mp_size_t size, abs_size;
+ long exp;
+
+ size = SIZ (src);
+ if (UNLIKELY (size == 0))
+ return 0.0;
+
+ abs_size = ABS (size);
+ exp = (EXP (src) - abs_size) * GMP_NUMB_BITS;
+ return mpn_get_d (PTR (src), abs_size, size, exp);
+}
diff --git a/gmp/mpf/get_d_2exp.c b/gmp/mpf/get_d_2exp.c
new file mode 100644
index 0000000000..17ce229f25
--- /dev/null
+++ b/gmp/mpf/get_d_2exp.c
@@ -0,0 +1,61 @@
+/* double mpf_get_d_2exp (signed long int *exp, mpf_t src).
+
+Copyright 2001-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+double
+mpf_get_d_2exp (signed long int *exp2, mpf_srcptr src)
+{
+ mp_size_t size, abs_size;
+ mp_srcptr ptr;
+ int cnt;
+ long exp;
+
+ size = SIZ(src);
+ if (UNLIKELY (size == 0))
+ {
+ *exp2 = 0;
+ return 0.0;
+ }
+
+ ptr = PTR(src);
+ abs_size = ABS (size);
+ count_leading_zeros (cnt, ptr[abs_size - 1]);
+ cnt -= GMP_NAIL_BITS;
+
+ exp = EXP(src) * GMP_NUMB_BITS - cnt;
+ *exp2 = exp;
+
+ return mpn_get_d (ptr, abs_size, (mp_size_t) 0,
+ (long) - (abs_size * GMP_NUMB_BITS - cnt));
+}
diff --git a/gmp/mpf/get_dfl_prec.c b/gmp/mpf/get_dfl_prec.c
new file mode 100644
index 0000000000..9a773d83ac
--- /dev/null
+++ b/gmp/mpf/get_dfl_prec.c
@@ -0,0 +1,39 @@
+/* mpf_get_default_prec -- return default precision in bits.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+mp_bitcnt_t
+mpf_get_default_prec (void) __GMP_NOTHROW
+{
+ return __GMPF_PREC_TO_BITS (__gmp_default_fp_limb_precision);
+}
diff --git a/gmp/mpf/get_prc.c b/gmp/mpf/get_prc.c
new file mode 100644
index 0000000000..3b3283a48c
--- /dev/null
+++ b/gmp/mpf/get_prc.c
@@ -0,0 +1,38 @@
+/* mpf_get_prec(x) -- Return the precision in bits of x.
+
+Copyright 1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_bitcnt_t
+mpf_get_prec (mpf_srcptr x) __GMP_NOTHROW
+{
+ return __GMPF_PREC_TO_BITS (x->_mp_prec);
+}
diff --git a/gmp/mpf/get_si.c b/gmp/mpf/get_si.c
new file mode 100644
index 0000000000..5b63dbd425
--- /dev/null
+++ b/gmp/mpf/get_si.c
@@ -0,0 +1,87 @@
+/* mpf_get_si -- mpf to long conversion
+
+Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Any fraction bits are truncated, meaning simply discarded.
+
+ For values bigger than a long, the low bits are returned, like
+ mpz_get_si, but this isn't documented.
+
+ Notice this is equivalent to mpz_set_f + mpz_get_si.
+
+
+ Implementation:
+
+ fl is established in basically the same way as for mpf_get_ui, see that
+ code for explanations of the conditions.
+
+ However unlike mpf_get_ui we need an explicit return 0 for exp<=0. When
+ f is a negative fraction (ie. size<0 and exp<=0) we can't let fl==0 go
+ through to the zany final "~ ((fl - 1) & LONG_MAX)", that would give
+ -0x80000000 instead of the desired 0. */
+
+long
+mpf_get_si (mpf_srcptr f) __GMP_NOTHROW
+{
+ mp_exp_t exp;
+ mp_size_t size, abs_size;
+ mp_srcptr fp;
+ mp_limb_t fl;
+
+ exp = EXP (f);
+ size = SIZ (f);
+ fp = PTR (f);
+
+ /* fraction alone truncates to zero
+ this also covers zero, since we have exp==0 for zero */
+ if (exp <= 0)
+ return 0L;
+
+ /* there are some limbs above the radix point */
+
+ fl = 0;
+ abs_size = ABS (size);
+ if (abs_size >= exp)
+ fl = fp[abs_size-exp];
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ if (exp > 1 && abs_size+1 >= exp)
+ fl |= fp[abs_size - exp + 1] << GMP_NUMB_BITS;
+#endif
+
+ if (size > 0)
+ return fl & LONG_MAX;
+ else
+ /* this form necessary to correctly handle -0x80..00 */
+ return -1 - (long) ((fl - 1) & LONG_MAX);
+}
diff --git a/gmp/mpf/get_str.c b/gmp/mpf/get_str.c
new file mode 100644
index 0000000000..98af03272e
--- /dev/null
+++ b/gmp/mpf/get_str.c
@@ -0,0 +1,330 @@
+/* mpf_get_str (digit_ptr, exp, base, n_digits, a) -- Convert the floating
+ point number A to a base BASE number and store N_DIGITS raw digits at
+ DIGIT_PTR, and the base BASE exponent in the word pointed to by EXP. For
+ example, the number 3.1416 would be returned as "31416" in DIGIT_PTR and
+ 1 in EXP.
+
+Copyright 1993-1997, 2000-2003, 2005, 2006, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h" /* for count_leading_zeros */
+
+/* Could use some more work.
+
+ 1. Allocation is excessive. Try to combine areas. Perhaps use result
+ string area for temp limb space?
+ 2. We generate up to two limbs of extra digits. This is because we don't
+ check the exact number of bits in the input operand, and from that
+ compute an accurate exponent (variable e in the code). It would be
+ cleaner and probably somewhat faster to change this.
+*/
+
+/* Compute base^exp and return the most significant prec limbs in rp[].
+ Put the count of omitted low limbs in *ign.
+ Return the actual size (which might be less than prec).
+ Allocation of rp[] and the temporary tp[] should be 2*prec+2 limbs. */
+static mp_size_t
+mpn_pow_1_highpart (mp_ptr rp, mp_size_t *ignp,
+ mp_limb_t base, unsigned long exp,
+ mp_size_t prec, mp_ptr tp)
+{
+ mp_size_t ign; /* counts number of ignored low limbs in r */
+ mp_size_t off; /* keeps track of offset where value starts */
+ mp_ptr passed_rp = rp;
+ mp_size_t rn;
+ int cnt;
+ int i;
+
+ if (exp == 0)
+ {
+ rp[0] = 1;
+ *ignp = 0;
+ return 1;
+ }
+
+ rp[0] = base;
+ rn = 1;
+ off = 0;
+ ign = 0;
+ count_leading_zeros (cnt, exp);
+ for (i = GMP_LIMB_BITS - cnt - 2; i >= 0; i--)
+ {
+ mpn_sqr (tp, rp + off, rn);
+ rn = 2 * rn;
+ rn -= tp[rn - 1] == 0;
+ ign <<= 1;
+
+ off = 0;
+ if (rn > prec)
+ {
+ ign += rn - prec;
+ off = rn - prec;
+ rn = prec;
+ }
+ MP_PTR_SWAP (rp, tp);
+
+ if (((exp >> i) & 1) != 0)
+ {
+ mp_limb_t cy;
+ cy = mpn_mul_1 (rp, rp + off, rn, base);
+ rp[rn] = cy;
+ rn += cy != 0;
+ off = 0;
+ }
+ }
+
+ if (rn > prec)
+ {
+ ASSERT (rn == prec + 1);
+
+ ign += rn - prec;
+ rp += rn - prec;
+ rn = prec;
+ }
+
+ /* With somewhat less than 50% probability, we can skip this copy. */
+ if (passed_rp != rp + off)
+ MPN_COPY_INCR (passed_rp, rp + off, rn);
+ *ignp = ign;
+ return rn;
+}
+
+char *
+mpf_get_str (char *dbuf, mp_exp_t *exp, int base, size_t n_digits, mpf_srcptr u)
+{
+ mp_exp_t ue;
+ mp_size_t n_limbs_needed;
+ size_t max_digits;
+ mp_ptr up, pp, tp;
+ mp_size_t un, pn, tn;
+ unsigned char *tstr;
+ mp_exp_t exp_in_base;
+ size_t n_digits_computed;
+ mp_size_t i;
+ const char *num_to_text;
+ size_t alloc_size = 0;
+ char *dp;
+ TMP_DECL;
+
+ up = PTR(u);
+ un = ABSIZ(u);
+ ue = EXP(u);
+
+ if (base >= 0)
+ {
+ num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz";
+ if (base <= 1)
+ base = 10;
+ else if (base > 36)
+ {
+ num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ if (base > 62)
+ return NULL;
+ }
+ }
+ else
+ {
+ base = -base;
+ if (base <= 1)
+ base = 10;
+ else if (base > 36)
+ return NULL;
+ num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ }
+
+ MPF_SIGNIFICANT_DIGITS (max_digits, base, PREC(u));
+ if (n_digits == 0 || n_digits > max_digits)
+ n_digits = max_digits;
+
+ if (dbuf == 0)
+ {
+ /* We didn't get a string from the user. Allocate one (and return
+ a pointer to it) with space for `-' and terminating null. */
+ alloc_size = n_digits + 2;
+ dbuf = (char *) (*__gmp_allocate_func) (n_digits + 2);
+ }
+
+ if (un == 0)
+ {
+ *exp = 0;
+ *dbuf = 0;
+ n_digits = 0;
+ goto done;
+ }
+
+ TMP_MARK;
+
+ /* Allocate temporary digit space. We can't put digits directly in the user
+ area, since we generate more digits than requested. (We allocate
+ 2 * GMP_LIMB_BITS extra bytes because of the digit block nature of the
+ conversion.) */
+ tstr = (unsigned char *) TMP_ALLOC (n_digits + 2 * GMP_LIMB_BITS + 3);
+
+ LIMBS_PER_DIGIT_IN_BASE (n_limbs_needed, n_digits, base);
+
+ if (ue <= n_limbs_needed)
+ {
+ /* We need to multiply number by base^n to get an n_digits integer part. */
+ mp_size_t n_more_limbs_needed, ign, off;
+ unsigned long e;
+
+ n_more_limbs_needed = n_limbs_needed - ue;
+ DIGITS_IN_BASE_PER_LIMB (e, n_more_limbs_needed, base);
+
+ if (un > n_limbs_needed)
+ {
+ up += un - n_limbs_needed;
+ un = n_limbs_needed;
+ }
+ pp = TMP_ALLOC_LIMBS (2 * n_limbs_needed + 2);
+ tp = TMP_ALLOC_LIMBS (2 * n_limbs_needed + 2);
+
+ pn = mpn_pow_1_highpart (pp, &ign, (mp_limb_t) base, e, n_limbs_needed, tp);
+ if (un > pn)
+ mpn_mul (tp, up, un, pp, pn); /* FIXME: mpn_mul_highpart */
+ else
+ mpn_mul (tp, pp, pn, up, un); /* FIXME: mpn_mul_highpart */
+ tn = un + pn;
+ tn -= tp[tn - 1] == 0;
+ off = un - ue - ign;
+ if (off < 0)
+ {
+ MPN_COPY_DECR (tp - off, tp, tn);
+ MPN_ZERO (tp, -off);
+ tn -= off;
+ off = 0;
+ }
+ n_digits_computed = mpn_get_str (tstr, base, tp + off, tn - off);
+
+ exp_in_base = n_digits_computed - e;
+ }
+ else
+ {
+ /* We need to divide number by base^n to get an n_digits integer part. */
+ mp_size_t n_less_limbs_needed, ign, off, xn;
+ unsigned long e;
+ mp_ptr dummyp, xp;
+
+ n_less_limbs_needed = ue - n_limbs_needed;
+ DIGITS_IN_BASE_PER_LIMB (e, n_less_limbs_needed, base);
+
+ if (un > n_limbs_needed)
+ {
+ up += un - n_limbs_needed;
+ un = n_limbs_needed;
+ }
+ pp = TMP_ALLOC_LIMBS (2 * n_limbs_needed + 2);
+ tp = TMP_ALLOC_LIMBS (2 * n_limbs_needed + 2);
+
+ pn = mpn_pow_1_highpart (pp, &ign, (mp_limb_t) base, e, n_limbs_needed, tp);
+
+ xn = n_limbs_needed + (n_less_limbs_needed-ign);
+ xp = TMP_ALLOC_LIMBS (xn);
+ off = xn - un;
+ MPN_ZERO (xp, off);
+ MPN_COPY (xp + off, up, un);
+
+ dummyp = TMP_ALLOC_LIMBS (pn);
+ mpn_tdiv_qr (tp, dummyp, (mp_size_t) 0, xp, xn, pp, pn);
+ tn = xn - pn + 1;
+ tn -= tp[tn - 1] == 0;
+ n_digits_computed = mpn_get_str (tstr, base, tp, tn);
+
+ exp_in_base = n_digits_computed + e;
+ }
+
+ /* We should normally have computed too many digits. Round the result
+ at the point indicated by n_digits. */
+ if (n_digits_computed > n_digits)
+ {
+ size_t i;
+ /* Round the result. */
+ if (tstr[n_digits] * 2 >= base)
+ {
+ n_digits_computed = n_digits;
+ for (i = n_digits - 1;; i--)
+ {
+ unsigned int x;
+ x = ++(tstr[i]);
+ if (x != base)
+ break;
+ n_digits_computed--;
+ if (i == 0)
+ {
+ /* We had something like `bbbbbbb...bd', where 2*d >= base
+ and `b' denotes digit with significance base - 1.
+ This rounds up to `1', increasing the exponent. */
+ tstr[0] = 1;
+ n_digits_computed = 1;
+ exp_in_base++;
+ break;
+ }
+ }
+ }
+ }
+
+ /* We might have fewer digits than requested as a result of rounding above,
+ (i.e. 0.999999 => 1.0) or because we have a number that simply doesn't
+ need many digits in this base (e.g., 0.125 in base 10). */
+ if (n_digits > n_digits_computed)
+ n_digits = n_digits_computed;
+
+ /* Remove trailing 0. There can be many zeros. */
+ while (n_digits != 0 && tstr[n_digits - 1] == 0)
+ n_digits--;
+
+ dp = dbuf + (SIZ(u) < 0);
+
+ /* Translate to ASCII and copy to result string. */
+ for (i = 0; i < n_digits; i++)
+ dp[i] = num_to_text[tstr[i]];
+ dp[n_digits] = 0;
+
+ *exp = exp_in_base;
+
+ if (SIZ(u) < 0)
+ {
+ dbuf[0] = '-';
+ n_digits++;
+ }
+
+ TMP_FREE;
+
+ done:
+ /* If the string was alloced then resize it down to the actual space
+ required. */
+ if (alloc_size != 0)
+ {
+ __GMP_REALLOCATE_FUNC_MAYBE_TYPE (dbuf, alloc_size, n_digits + 1, char);
+ }
+
+ return dbuf;
+}
diff --git a/gmp/mpf/get_ui.c b/gmp/mpf/get_ui.c
new file mode 100644
index 0000000000..eb9b30e69c
--- /dev/null
+++ b/gmp/mpf/get_ui.c
@@ -0,0 +1,102 @@
+/* mpf_get_ui -- mpf to ulong conversion
+
+Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Any fraction bits are truncated, meaning simply discarded.
+
+ For values bigger than a ulong, the low bits are returned (the low
+ absolute value bits actually), like mpz_get_ui, but this isn't
+ documented.
+
+ Notice this is equivalent to mpz_set_f + mpz_get_ui.
+
+
+ Implementation:
+
+ The limb just above the radix point for us to extract is ptr[size-exp].
+
+ We need to check that the size-exp index falls in our available data
+ range, 0 to size-1 inclusive. We test this without risk of an overflow
+ involving exp by requiring size>=exp (giving size-exp >= 0) and exp>0
+ (giving size-exp <= size-1).
+
+ Notice if size==0 there's no fetch, since of course size>=exp and exp>0
+ can only be true if size>0. So there's no special handling for size==0,
+ it comes out as 0 the same as any other time we have no data at our
+ target index.
+
+ For nails, the second limb above the radix point is also required, this
+ is ptr[size-exp+1].
+
+ Again we need to check that size-exp+1 falls in our data range, 0 to
+ size-1 inclusive. We test without risk of overflow by requiring
+ size+1>=exp (giving size-exp+1 >= 0) and exp>1 (giving size-exp+1 <=
+ size-1).
+
+ And again if size==0 these second fetch conditions are not satisfied
+ either since size+1>=exp and exp>1 are only true if size>0.
+
+ The code is arranged with exp>0 wrapping the exp>1 test since exp>1 is
+ mis-compiled by alpha gcc prior to version 3.4. It re-writes it as
+ exp-1>0, which is incorrect when exp==MP_EXP_T_MIN. By having exp>0
+ tested first we ensure MP_EXP_T_MIN doesn't reach exp>1. */
+
+unsigned long
+mpf_get_ui (mpf_srcptr f) __GMP_NOTHROW
+{
+ mp_size_t size;
+ mp_exp_t exp;
+ mp_srcptr fp;
+ mp_limb_t fl;
+
+ exp = EXP (f);
+ size = SIZ (f);
+ fp = PTR (f);
+
+ fl = 0;
+ if (exp > 0)
+ {
+ /* there are some limbs above the radix point */
+
+ size = ABS (size);
+ if (size >= exp)
+ fl = fp[size-exp];
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ if (exp > 1 && size+1 >= exp)
+ fl += (fp[size-exp+1] << GMP_NUMB_BITS);
+#endif
+ }
+
+ return (unsigned long) fl;
+}
diff --git a/gmp/mpf/init.c b/gmp/mpf/init.c
new file mode 100644
index 0000000000..d8590f27a7
--- /dev/null
+++ b/gmp/mpf/init.c
@@ -0,0 +1,42 @@
+/* mpf_init() -- Make a new multiple precision number with value 0.
+
+Copyright 1993-1995, 2000, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_init (mpf_ptr r)
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ r->_mp_prec = prec;
+ r->_mp_d = (mp_ptr) (*__gmp_allocate_func) ((size_t) (prec + 1) * GMP_LIMB_BYTES);
+}
diff --git a/gmp/mpf/init2.c b/gmp/mpf/init2.c
new file mode 100644
index 0000000000..a7891e33dd
--- /dev/null
+++ b/gmp/mpf/init2.c
@@ -0,0 +1,44 @@
+/* mpf_init2() -- Make a new multiple precision number with value 0.
+
+Copyright 1993-1995, 2000, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_init2 (mpf_ptr r, mp_bitcnt_t prec_in_bits)
+{
+ mp_size_t prec;
+
+ prec = __GMPF_BITS_TO_PREC (prec_in_bits);
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ r->_mp_prec = prec;
+ r->_mp_d = (mp_ptr) (*__gmp_allocate_func) ((size_t) (prec + 1) * GMP_LIMB_BYTES);
+}
diff --git a/gmp/mpf/inits.c b/gmp/mpf/inits.c
new file mode 100644
index 0000000000..fb14c6b0fd
--- /dev/null
+++ b/gmp/mpf/inits.c
@@ -0,0 +1,49 @@
+/* mpf_inits() -- Initialize multiple mpf_t variables and set them to 0.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_inits (mpf_ptr x, ...)
+{
+ va_list ap;
+
+ va_start (ap, x);
+
+ while (x != NULL)
+ {
+ mpf_init (x);
+ x = va_arg (ap, mpf_ptr);
+ }
+ va_end (ap);
+}
diff --git a/gmp/mpf/inp_str.c b/gmp/mpf/inp_str.c
new file mode 100644
index 0000000000..45cc34cebb
--- /dev/null
+++ b/gmp/mpf/inp_str.c
@@ -0,0 +1,93 @@
+/* mpf_inp_str(dest_float, stream, base) -- Input a number in base
+ BASE from stdio stream STREAM and store the result in DEST_FLOAT.
+
+Copyright 1996, 2000-2002, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+mpf_inp_str (mpf_ptr rop, FILE *stream, int base)
+{
+ char *str;
+ size_t alloc_size, str_size;
+ int c;
+ int res;
+ size_t nread;
+
+ if (stream == 0)
+ stream = stdin;
+
+ alloc_size = 100;
+ str = (char *) (*__gmp_allocate_func) (alloc_size);
+ str_size = 0;
+ nread = 0;
+
+ /* Skip whitespace. */
+ do
+ {
+ c = getc (stream);
+ nread++;
+ }
+ while (isspace (c));
+
+ for (;;)
+ {
+ if (str_size >= alloc_size)
+ {
+ size_t old_alloc_size = alloc_size;
+ alloc_size = alloc_size * 3 / 2;
+ str = (char *) (*__gmp_reallocate_func) (str, old_alloc_size, alloc_size);
+ }
+ if (c == EOF || isspace (c))
+ break;
+ str[str_size++] = c;
+ c = getc (stream);
+ }
+ ungetc (c, stream);
+ nread--;
+
+ if (str_size >= alloc_size)
+ {
+ size_t old_alloc_size = alloc_size;
+ alloc_size = alloc_size * 3 / 2;
+ str = (char *) (*__gmp_reallocate_func) (str, old_alloc_size, alloc_size);
+ }
+ str[str_size] = 0;
+
+ res = mpf_set_str (rop, str, base);
+ (*__gmp_free_func) (str, alloc_size);
+
+ if (res == -1)
+ return 0; /* error */
+
+ return str_size + nread;
+}
diff --git a/gmp/mpf/int_p.c b/gmp/mpf/int_p.c
new file mode 100644
index 0000000000..91e62266be
--- /dev/null
+++ b/gmp/mpf/int_p.c
@@ -0,0 +1,59 @@
+/* mpf_integer_p -- test whether an mpf is an integer */
+
+/*
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+mpf_integer_p (mpf_srcptr f) __GMP_NOTHROW
+{
+ mp_srcptr ptr;
+ mp_exp_t exp;
+ mp_size_t size, frac, i;
+
+ size = SIZ (f);
+ if (size == 0)
+ return 1; /* zero is an integer */
+
+ exp = EXP (f);
+ if (exp <= 0)
+ return 0; /* has only fraction limbs */
+
+ /* any fraction limbs must be zero */
+ frac = ABS (size) - exp;
+ ptr = PTR (f);
+ for (i = 0; i < frac; i++)
+ if (ptr[i] != 0)
+ return 0;
+
+ return 1;
+}
diff --git a/gmp/mpf/iset.c b/gmp/mpf/iset.c
new file mode 100644
index 0000000000..c8c35e50e9
--- /dev/null
+++ b/gmp/mpf/iset.c
@@ -0,0 +1,62 @@
+/* mpf_init_set -- Initialize a float and assign it from another float.
+
+Copyright 1993-1995, 2000, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_init_set (mpf_ptr r, mpf_srcptr s)
+{
+ mp_ptr rp, sp;
+ mp_size_t ssize, size;
+ mp_size_t prec;
+
+ prec = __gmp_default_fp_limb_precision;
+ r->_mp_d = (mp_ptr) (*__gmp_allocate_func) ((size_t) (prec + 1) * GMP_LIMB_BYTES);
+ r->_mp_prec = prec;
+
+ prec++; /* lie not to lose precision in assignment */
+ ssize = s->_mp_size;
+ size = ABS (ssize);
+
+ rp = r->_mp_d;
+ sp = s->_mp_d;
+
+ if (size > prec)
+ {
+ sp += size - prec;
+ size = prec;
+ }
+
+ r->_mp_exp = s->_mp_exp;
+ r->_mp_size = ssize >= 0 ? size : -size;
+
+ MPN_COPY (rp, sp, size);
+}
diff --git a/gmp/mpf/iset_d.c b/gmp/mpf/iset_d.c
new file mode 100644
index 0000000000..d128db9b4d
--- /dev/null
+++ b/gmp/mpf/iset_d.c
@@ -0,0 +1,42 @@
+/* mpf_init_set_d -- Initialize a float and assign it from a double.
+
+Copyright 1993-1995, 2000, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_init_set_d (mpf_ptr r, double val)
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ r->_mp_prec = prec;
+ r->_mp_d = (mp_ptr) (*__gmp_allocate_func) ((size_t) (prec + 1) * GMP_LIMB_BYTES);
+
+ mpf_set_d (r, val);
+}
diff --git a/gmp/mpf/iset_si.c b/gmp/mpf/iset_si.c
new file mode 100644
index 0000000000..f7e9005086
--- /dev/null
+++ b/gmp/mpf/iset_si.c
@@ -0,0 +1,58 @@
+/* mpf_init_set_si() -- Initialize a float and assign it from a signed int.
+
+Copyright 1993-1995, 2000, 2001, 2003, 2004, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_init_set_si (mpf_ptr r, long int val)
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ mp_size_t size;
+ mp_limb_t vl;
+
+ r->_mp_prec = prec;
+ r->_mp_d = (mp_ptr) (*__gmp_allocate_func) ((size_t) (prec + 1) * GMP_LIMB_BYTES);
+
+ vl = (mp_limb_t) ABS_CAST (unsigned long int, val);
+
+ r->_mp_d[0] = vl & GMP_NUMB_MASK;
+ size = vl != 0;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ vl >>= GMP_NUMB_BITS;
+ r->_mp_d[1] = vl;
+ size += (vl != 0);
+#endif
+
+ r->_mp_exp = size;
+ r->_mp_size = val >= 0 ? size : -size;
+}
diff --git a/gmp/mpf/iset_str.c b/gmp/mpf/iset_str.c
new file mode 100644
index 0000000000..a181f80c93
--- /dev/null
+++ b/gmp/mpf/iset_str.c
@@ -0,0 +1,44 @@
+/* mpf_init_set_str -- Initialize a float and assign it from a string.
+
+Copyright 1995, 1996, 2000, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpf_init_set_str (mpf_ptr r, const char *s, int base)
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ r->_mp_prec = prec;
+ r->_mp_d = (mp_ptr) (*__gmp_allocate_func) ((size_t) (prec + 1) * GMP_LIMB_BYTES);
+
+ return mpf_set_str (r, s, base);
+}
diff --git a/gmp/mpf/iset_ui.c b/gmp/mpf/iset_ui.c
new file mode 100644
index 0000000000..f047982116
--- /dev/null
+++ b/gmp/mpf/iset_ui.c
@@ -0,0 +1,53 @@
+/* mpf_init_set_ui() -- Initialize a float and assign it from an unsigned int.
+
+Copyright 1993-1995, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_init_set_ui (mpf_ptr r, unsigned long int val)
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ mp_size_t size;
+
+ r->_mp_prec = prec;
+ r->_mp_d = (mp_ptr) (*__gmp_allocate_func) ((size_t) (prec + 1) * GMP_LIMB_BYTES);
+ r->_mp_d[0] = val & GMP_NUMB_MASK;
+ size = (val != 0);
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ val >>= GMP_NUMB_BITS;
+ r->_mp_d[1] = val;
+ size += (val != 0);
+#endif
+
+ r->_mp_size = size;
+ r->_mp_exp = size;
+}
diff --git a/gmp/mpf/mul.c b/gmp/mpf/mul.c
new file mode 100644
index 0000000000..41d1db7c14
--- /dev/null
+++ b/gmp/mpf/mul.c
@@ -0,0 +1,96 @@
+/* mpf_mul -- Multiply two floats.
+
+Copyright 1993, 1994, 1996, 2001, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_mul (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
+{
+ mp_srcptr up, vp;
+ mp_size_t usize, vsize;
+ mp_size_t sign_product;
+ mp_size_t prec = r->_mp_prec;
+ TMP_DECL;
+
+ TMP_MARK;
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+ sign_product = usize ^ vsize;
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ if (usize > prec)
+ {
+ up += usize - prec;
+ usize = prec;
+ }
+ if (vsize > prec)
+ {
+ vp += vsize - prec;
+ vsize = prec;
+ }
+
+ if (usize == 0 || vsize == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0; /* ??? */
+ }
+ else
+ {
+ mp_size_t rsize;
+ mp_limb_t cy_limb;
+ mp_ptr rp, tp;
+ mp_size_t adj;
+
+ rsize = usize + vsize;
+ tp = TMP_ALLOC_LIMBS (rsize);
+ cy_limb = (usize >= vsize
+ ? mpn_mul (tp, up, usize, vp, vsize)
+ : mpn_mul (tp, vp, vsize, up, usize));
+
+ adj = cy_limb == 0;
+ rsize -= adj;
+ prec++;
+ if (rsize > prec)
+ {
+ tp += rsize - prec;
+ rsize = prec;
+ }
+ rp = r->_mp_d;
+ MPN_COPY (rp, tp, rsize);
+ r->_mp_exp = u->_mp_exp + v->_mp_exp - adj;
+ r->_mp_size = sign_product >= 0 ? rsize : -rsize;
+ }
+ TMP_FREE;
+}
diff --git a/gmp/mpf/mul_2exp.c b/gmp/mpf/mul_2exp.c
new file mode 100644
index 0000000000..83df2176d3
--- /dev/null
+++ b/gmp/mpf/mul_2exp.c
@@ -0,0 +1,133 @@
+/* mpf_mul_2exp -- Multiply a float by 2^n.
+
+Copyright 1993, 1994, 1996, 2000-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Multiples of GMP_NUMB_BITS in exp simply mean an amount added to EXP(u)
+ to set EXP(r). The remainder exp%GMP_NUMB_BITS is then a left shift for
+ the limb data.
+
+ If exp%GMP_NUMB_BITS == 0 then there's no shifting, we effectively just
+ do an mpz_set with changed EXP(r). Like mpz_set we take prec+1 limbs in
+ this case. Although just prec would suffice, it's nice to have
+ mpf_mul_2exp with exp==0 come out the same as mpz_set.
+
+ When shifting we take up to prec many limbs from the input. Our shift is
+ cy = mpn_lshift (PTR(r), PTR(u)+k, size, ...), where k is the number of
+ low limbs dropped from u, and the carry out is stored to PTR(r)[size].
+
+ It may be noted that the low limb PTR(r)[0] doesn't incorporate bits from
+ PTR(u)[k-1] (when k>=1 makes that limb available). Taking just prec
+ limbs from the input (with the high non-zero) is enough bits for the
+ application requested precision, there's no need for extra work.
+
+ If r==u the shift will have overlapping operands. When k==0 (ie. when
+ usize <= prec), the overlap is supported by lshift (ie. dst == src).
+
+ But when r==u and k>=1 (ie. usize > prec), we would have an invalid
+ overlap (ie. mpn_lshift (rp, rp+k, ...)). In this case we must instead
+ use mpn_rshift (PTR(r)+1, PTR(u)+k, size, NUMB-shift) with the carry out
+ stored to PTR(r)[0]. An rshift by NUMB-shift bits like this gives
+ identical data, it's just its overlap restrictions which differ.
+
+ Enhancements:
+
+ The way mpn_lshift is used means successive mpf_mul_2exp calls on the
+ same operand will accumulate low zero limbs, until prec+1 limbs is
+ reached. This is wasteful for subsequent operations. When abs_usize <=
+ prec, we should test the low exp%GMP_NUMB_BITS many bits of PTR(u)[0],
+ ie. those which would be shifted out by an mpn_rshift. If they're zero
+ then use that mpn_rshift. */
+
+void
+mpf_mul_2exp (mpf_ptr r, mpf_srcptr u, mp_bitcnt_t exp)
+{
+ mp_srcptr up;
+ mp_ptr rp = r->_mp_d;
+ mp_size_t usize;
+ mp_size_t abs_usize;
+ mp_size_t prec = r->_mp_prec;
+ mp_exp_t uexp = u->_mp_exp;
+
+ usize = u->_mp_size;
+
+ if (UNLIKELY (usize == 0))
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ abs_usize = ABS (usize);
+ up = u->_mp_d;
+
+ if (exp % GMP_NUMB_BITS == 0)
+ {
+ prec++; /* retain more precision here as we don't need
+ to account for carry-out here */
+ if (abs_usize > prec)
+ {
+ up += abs_usize - prec;
+ abs_usize = prec;
+ }
+ if (rp != up)
+ MPN_COPY_INCR (rp, up, abs_usize);
+ r->_mp_exp = uexp + exp / GMP_NUMB_BITS;
+ }
+ else
+ {
+ mp_limb_t cy_limb;
+ mp_size_t adj;
+ if (abs_usize > prec)
+ {
+ up += abs_usize - prec;
+ abs_usize = prec;
+ /* Use mpn_rshift since mpn_lshift operates downwards, and we
+ therefore would clobber part of U before using that part, in case
+ R is the same variable as U. */
+ cy_limb = mpn_rshift (rp + 1, up, abs_usize,
+ GMP_NUMB_BITS - exp % GMP_NUMB_BITS);
+ rp[0] = cy_limb;
+ adj = rp[abs_usize] != 0;
+ }
+ else
+ {
+ cy_limb = mpn_lshift (rp, up, abs_usize, exp % GMP_NUMB_BITS);
+ rp[abs_usize] = cy_limb;
+ adj = cy_limb != 0;
+ }
+
+ abs_usize += adj;
+ r->_mp_exp = uexp + exp / GMP_NUMB_BITS + adj;
+ }
+ r->_mp_size = usize >= 0 ? abs_usize : -abs_usize;
+}
diff --git a/gmp/mpf/mul_ui.c b/gmp/mpf/mul_ui.c
new file mode 100644
index 0000000000..031b2fe06f
--- /dev/null
+++ b/gmp/mpf/mul_ui.c
@@ -0,0 +1,182 @@
+/* mpf_mul_ui -- Multiply a float and an unsigned integer.
+
+Copyright 1993, 1994, 1996, 2001, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* The core operation is a multiply of PREC(r) limbs from u by v, producing
+ either PREC(r) or PREC(r)+1 result limbs. If u is shorter than PREC(r),
+ then we take only as much as it has. If u is longer we incorporate a
+ carry from the lower limbs.
+
+ If u has just 1 extra limb, then the carry to add is high(up[0]*v). That
+ is of course what mpn_mul_1 would do if it was called with PREC(r)+1
+ limbs of input.
+
+ If u has more than 1 extra limb, then there can be a further carry bit
+ out of lower uncalculated limbs (the way the low of one product adds to
+ the high of the product below it). This is of course what an mpn_mul_1
+ would do if it was called with the full u operand. But we instead work
+ downwards explicitly, until a carry occurs or until a value other than
+ GMP_NUMB_MAX occurs (that being the only value a carry bit can propagate
+ across).
+
+ The carry determination normally requires two umul_ppmm's, only rarely
+ will GMP_NUMB_MAX occur and require further products.
+
+ The carry limb is conveniently added into the mul_1 using mpn_mul_1c when
+ that function exists, otherwise a subsequent mpn_add_1 is needed.
+
+ Clearly when mpn_mul_1c is used the carry must be calculated first. But
+ this is also the case when add_1 is used, since if r==u and ABSIZ(r) >
+ PREC(r) then the mpn_mul_1 overwrites the low part of the input.
+
+ A reuse r==u with size > prec can occur from a size PREC(r)+1 in the
+ usual way, or it can occur from an mpf_set_prec_raw leaving a bigger
+ sized value. In both cases we can end up calling mpn_mul_1 with
+ overlapping src and dst regions, but this will be with dst < src and such
+ an overlap is permitted.
+
+ Not done:
+
+ No attempt is made to determine in advance whether the result will be
+ PREC(r) or PREC(r)+1 limbs. If it's going to be PREC(r)+1 then we could
+ take one less limb from u and generate just PREC(r), that of course
+ satisfying application requested precision. But any test counting bits
+ or forming the high product would almost certainly take longer than the
+ incremental cost of an extra limb in mpn_mul_1.
+
+ Enhancements:
+
+ Repeated mpf_mul_ui's with an even v will accumulate low zero bits on the
+ result, leaving low zero limbs after a while, which it might be nice to
+ strip to save work in subsequent operations. Calculating the low limb
+ explicitly would let us direct mpn_mul_1 to put the balance at rp when
+ the low is zero (instead of normally rp+1). But it's not clear whether
+ this would be worthwhile. Explicit code for the low limb will probably
+ be slower than having it done in mpn_mul_1, so we need to consider how
+ often a zero will be stripped and how much that's likely to save
+ later. */
+
+void
+mpf_mul_ui (mpf_ptr r, mpf_srcptr u, unsigned long int v)
+{
+ mp_srcptr up;
+ mp_size_t usize;
+ mp_size_t size;
+ mp_size_t prec, excess;
+ mp_limb_t cy_limb, vl, cbit, cin;
+ mp_ptr rp;
+
+ usize = u->_mp_size;
+ if (UNLIKELY (v == 0) || UNLIKELY (usize == 0))
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (v > GMP_NUMB_MAX)
+ {
+ mpf_t vf;
+ mp_limb_t vp[2];
+ vp[0] = v & GMP_NUMB_MASK;
+ vp[1] = v >> GMP_NUMB_BITS;
+ PTR(vf) = vp;
+ SIZ(vf) = 2;
+ ASSERT_CODE (PREC(vf) = 2);
+ EXP(vf) = 2;
+ mpf_mul (r, u, vf);
+ return;
+ }
+#endif
+
+ size = ABS (usize);
+ prec = r->_mp_prec;
+ up = u->_mp_d;
+ vl = v;
+ excess = size - prec;
+ cin = 0;
+
+ if (excess > 0)
+ {
+ /* up is bigger than desired rp, shorten it to prec limbs and
+ determine a carry-in */
+
+ mp_limb_t vl_shifted = vl << GMP_NAIL_BITS;
+ mp_limb_t hi, lo, next_lo, sum;
+ mp_size_t i;
+
+ /* high limb of top product */
+ i = excess - 1;
+ umul_ppmm (cin, lo, up[i], vl_shifted);
+
+ /* and carry bit out of products below that, if any */
+ for (;;)
+ {
+ i--;
+ if (i < 0)
+ break;
+
+ umul_ppmm (hi, next_lo, up[i], vl_shifted);
+ lo >>= GMP_NAIL_BITS;
+ ADDC_LIMB (cbit, sum, hi, lo);
+ cin += cbit;
+ lo = next_lo;
+
+ /* Continue only if the sum is GMP_NUMB_MAX. GMP_NUMB_MAX is the
+ only value a carry from below can propagate across. If we've
+ just seen the carry out (ie. cbit!=0) then sum!=GMP_NUMB_MAX,
+ so this test stops us for that case too. */
+ if (LIKELY (sum != GMP_NUMB_MAX))
+ break;
+ }
+
+ up += excess;
+ size = prec;
+ }
+
+ rp = r->_mp_d;
+#if HAVE_NATIVE_mpn_mul_1c
+ cy_limb = mpn_mul_1c (rp, up, size, vl, cin);
+#else
+ cy_limb = mpn_mul_1 (rp, up, size, vl);
+ __GMPN_ADD_1 (cbit, rp, rp, size, cin);
+ cy_limb += cbit;
+#endif
+ rp[size] = cy_limb;
+ cy_limb = cy_limb != 0;
+ r->_mp_exp = u->_mp_exp + cy_limb;
+ size += cy_limb;
+ r->_mp_size = usize >= 0 ? size : -size;
+}
diff --git a/gmp/mpf/neg.c b/gmp/mpf/neg.c
new file mode 100644
index 0000000000..553018f306
--- /dev/null
+++ b/gmp/mpf/neg.c
@@ -0,0 +1,62 @@
+/* mpf_neg -- Negate a float.
+
+Copyright 1993-1995, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_neg (mpf_ptr r, mpf_srcptr u)
+{
+ mp_size_t size;
+
+ size = -u->_mp_size;
+ if (r != u)
+ {
+ mp_size_t prec;
+ mp_size_t asize;
+ mp_ptr rp, up;
+
+ prec = r->_mp_prec + 1; /* lie not to lose precision in assignment */
+ asize = ABS (size);
+ rp = r->_mp_d;
+ up = u->_mp_d;
+
+ if (asize > prec)
+ {
+ up += asize - prec;
+ asize = prec;
+ }
+
+ MPN_COPY (rp, up, asize);
+ r->_mp_exp = u->_mp_exp;
+ size = size >= 0 ? asize : -asize;
+ }
+ r->_mp_size = size;
+}
diff --git a/gmp/mpf/out_str.c b/gmp/mpf/out_str.c
new file mode 100644
index 0000000000..200da74806
--- /dev/null
+++ b/gmp/mpf/out_str.c
@@ -0,0 +1,117 @@
+/* mpf_out_str (stream, base, n_digits, op) -- Print N_DIGITS digits from
+ the float OP to STREAM in base BASE. Return the number of characters
+ written, or 0 if an error occurred.
+
+Copyright 1996, 1997, 2001, 2002, 2005, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define _GNU_SOURCE /* for DECIMAL_POINT in langinfo.h */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#if HAVE_LANGINFO_H
+#include <langinfo.h> /* for nl_langinfo */
+#endif
+
+#if HAVE_LOCALE_H
+#include <locale.h> /* for localeconv */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+size_t
+mpf_out_str (FILE *stream, int base, size_t n_digits, mpf_srcptr op)
+{
+ char *str;
+ mp_exp_t exp;
+ size_t written;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ if (base == 0)
+ base = 10;
+ if (n_digits == 0)
+ MPF_SIGNIFICANT_DIGITS (n_digits, base, op->_mp_prec);
+
+ if (stream == 0)
+ stream = stdout;
+
+ /* Consider these changes:
+ * Don't allocate memory here for huge n_digits; pass NULL to mpf_get_str.
+ * Make mpf_get_str allocate extra space when passed NULL, to avoid
+ allocating two huge string buffers.
+ * Implement more/other allocation reductions tricks. */
+
+ str = (char *) TMP_ALLOC (n_digits + 2); /* extra for minus sign and \0 */
+
+ mpf_get_str (str, &exp, base, n_digits, op);
+ n_digits = strlen (str);
+
+ written = 0;
+
+ /* Write sign */
+ if (str[0] == '-')
+ {
+ str++;
+ fputc ('-', stream);
+ written = 1;
+ n_digits--;
+ }
+
+ {
+ const char *point = GMP_DECIMAL_POINT;
+ size_t pointlen = strlen (point);
+ putc ('0', stream);
+ fwrite (point, 1, pointlen, stream);
+ written += pointlen + 1;
+ }
+
+ /* Write mantissa */
+ {
+ size_t fwret;
+ fwret = fwrite (str, 1, n_digits, stream);
+ written += fwret;
+ }
+
+ /* Write exponent */
+ {
+ int fpret;
+ fpret = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), exp);
+ written += fpret;
+ }
+
+ TMP_FREE;
+ return ferror (stream) ? 0 : written;
+}
diff --git a/gmp/mpf/pow_ui.c b/gmp/mpf/pow_ui.c
new file mode 100644
index 0000000000..a5af431059
--- /dev/null
+++ b/gmp/mpf/pow_ui.c
@@ -0,0 +1,54 @@
+/* mpf_pow_ui -- Compute b^e.
+
+Copyright 1998, 1999, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_pow_ui (mpf_ptr r, mpf_srcptr b, unsigned long int e)
+{
+ mpf_t b2;
+
+ mpf_init2 (b2, mpf_get_prec (r));
+ mpf_set (b2, b);
+
+ if ((e & 1) != 0)
+ mpf_set (r, b);
+ else
+ mpf_set_ui (r, 1);
+ while (e >>= 1)
+ {
+ mpf_mul (b2, b2, b2);
+ if ((e & 1) != 0)
+ mpf_mul (r, r, b2);
+ }
+
+ mpf_clear (b2);
+}
diff --git a/gmp/mpf/random2.c b/gmp/mpf/random2.c
new file mode 100644
index 0000000000..4d7f37e976
--- /dev/null
+++ b/gmp/mpf/random2.c
@@ -0,0 +1,67 @@
+/* mpf_random2 -- Generate a positive random mpf_t of specified size, with
+ long runs of consecutive ones and zeros in the binary representation.
+ Intended for testing of other MP routines.
+
+Copyright 1995, 1996, 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpf_random2 (mpf_ptr x, mp_size_t xs, mp_exp_t exp)
+{
+ mp_size_t xn;
+ mp_size_t prec;
+ mp_limb_t elimb;
+
+ xn = ABS (xs);
+ prec = PREC(x);
+
+ if (xn == 0)
+ {
+ EXP(x) = 0;
+ SIZ(x) = 0;
+ return;
+ }
+
+ if (xn > prec + 1)
+ xn = prec + 1;
+
+ /* General random mantissa. */
+ mpn_random2 (PTR(x), xn);
+
+ /* Generate random exponent. */
+ _gmp_rand (&elimb, RANDS, GMP_NUMB_BITS);
+ exp = ABS (exp);
+ exp = elimb % (2 * exp + 1) - exp;
+
+ EXP(x) = exp;
+ SIZ(x) = xs < 0 ? -xn : xn;
+}
diff --git a/gmp/mpf/reldiff.c b/gmp/mpf/reldiff.c
new file mode 100644
index 0000000000..f49da08166
--- /dev/null
+++ b/gmp/mpf/reldiff.c
@@ -0,0 +1,65 @@
+/* mpf_reldiff -- Generate the relative difference of two floats.
+
+Copyright 1996, 2001, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* The precision we use for d = x-y is based on what mpf_div will want from
+ the dividend. It calls mpn_div_q to produce a quotient of rprec+1 limbs.
+ So rprec+1 == dsize - xsize + 1, hence dprec = rprec+xsize. */
+
+void
+mpf_reldiff (mpf_t rdiff, mpf_srcptr x, mpf_srcptr y)
+{
+ if (UNLIKELY (SIZ(x) == 0))
+ {
+ mpf_set_ui (rdiff, (unsigned long int) (mpf_sgn (y) != 0));
+ }
+ else
+ {
+ mp_size_t dprec;
+ mpf_t d;
+ TMP_DECL;
+
+ TMP_MARK;
+ dprec = PREC(rdiff) + ABSIZ(x);
+ ASSERT (PREC(rdiff)+1 == dprec - ABSIZ(x) + 1);
+
+ PREC(d) = dprec;
+ PTR(d) = TMP_ALLOC_LIMBS (dprec + 1);
+
+ mpf_sub (d, x, y);
+ SIZ(d) = ABSIZ(d);
+ mpf_div (rdiff, d, x);
+
+ TMP_FREE;
+ }
+}
diff --git a/gmp/mpf/set.c b/gmp/mpf/set.c
new file mode 100644
index 0000000000..ec8161d779
--- /dev/null
+++ b/gmp/mpf/set.c
@@ -0,0 +1,56 @@
+/* mpf_set -- Assign a float from another float.
+
+Copyright 1993-1995, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_set (mpf_ptr r, mpf_srcptr u)
+{
+ mp_ptr rp, up;
+ mp_size_t size, asize;
+ mp_size_t prec;
+
+ prec = r->_mp_prec + 1; /* lie not to lose precision in assignment */
+ size = u->_mp_size;
+ asize = ABS (size);
+ rp = r->_mp_d;
+ up = u->_mp_d;
+
+ if (asize > prec)
+ {
+ up += asize - prec;
+ asize = prec;
+ }
+
+ r->_mp_exp = u->_mp_exp;
+ r->_mp_size = size >= 0 ? asize : -asize;
+ MPN_COPY_INCR (rp, up, asize);
+}
diff --git a/gmp/mpf/set_d.c b/gmp/mpf/set_d.c
new file mode 100644
index 0000000000..100194d116
--- /dev/null
+++ b/gmp/mpf/set_d.c
@@ -0,0 +1,60 @@
+/* mpf_set_d -- Assign a float from a double.
+
+Copyright 1993-1996, 2001, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if HAVE_FLOAT_H
+#include <float.h> /* for DBL_MAX */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_set_d (mpf_ptr r, double d)
+{
+ int negative;
+
+ DOUBLE_NAN_INF_ACTION (d,
+ __gmp_invalid_operation (),
+ __gmp_invalid_operation ());
+
+ if (UNLIKELY (d == 0))
+ {
+ SIZ(r) = 0;
+ EXP(r) = 0;
+ return;
+ }
+ negative = d < 0;
+ d = ABS (d);
+
+ SIZ(r) = negative ? -LIMBS_PER_DOUBLE : LIMBS_PER_DOUBLE;
+ EXP(r) = __gmp_extract_double (PTR(r), d);
+}
diff --git a/gmp/mpf/set_dfl_prec.c b/gmp/mpf/set_dfl_prec.c
new file mode 100644
index 0000000000..04c9a55135
--- /dev/null
+++ b/gmp/mpf/set_dfl_prec.c
@@ -0,0 +1,40 @@
+/* mpf_set_default_prec --
+
+Copyright 1993-1995, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_size_t __gmp_default_fp_limb_precision = __GMPF_BITS_TO_PREC (53);
+
+void
+mpf_set_default_prec (mp_bitcnt_t prec_in_bits) __GMP_NOTHROW
+{
+ __gmp_default_fp_limb_precision = __GMPF_BITS_TO_PREC (prec_in_bits);
+}
diff --git a/gmp/mpf/set_prc.c b/gmp/mpf/set_prc.c
new file mode 100644
index 0000000000..30ba06c6e6
--- /dev/null
+++ b/gmp/mpf/set_prc.c
@@ -0,0 +1,69 @@
+/* mpf_set_prec(x) -- Change the precision of x.
+
+Copyright 1993-1995, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* A full new_prec+1 limbs are always retained, even though just new_prec
+ would satisfy the requested precision. If size==new_prec+1 then
+ certainly new_prec+1 should be kept since no copying is needed in that
+ case. If just new_prec was kept for size>new_prec+1 it'd be a bit
+ inconsistent. */
+
+void
+mpf_set_prec (mpf_ptr x, mp_bitcnt_t new_prec_in_bits)
+{
+ mp_size_t old_prec, new_prec, new_prec_plus1;
+ mp_size_t size, sign;
+ mp_ptr xp;
+
+ new_prec = __GMPF_BITS_TO_PREC (new_prec_in_bits);
+ old_prec = PREC(x);
+
+ /* do nothing if already the right precision */
+ if (new_prec == old_prec)
+ return;
+
+ PREC(x) = new_prec;
+ new_prec_plus1 = new_prec + 1;
+
+ /* retain most significant limbs */
+ sign = SIZ(x);
+ size = ABS (sign);
+ xp = PTR(x);
+ if (size > new_prec_plus1)
+ {
+ SIZ(x) = (sign >= 0 ? new_prec_plus1 : -new_prec_plus1);
+ MPN_COPY_INCR (xp, xp + size - new_prec_plus1, new_prec_plus1);
+ }
+
+ PTR(x) = __GMP_REALLOCATE_FUNC_LIMBS (xp, old_prec+1, new_prec_plus1);
+}
diff --git a/gmp/mpf/set_prc_raw.c b/gmp/mpf/set_prc_raw.c
new file mode 100644
index 0000000000..7799442299
--- /dev/null
+++ b/gmp/mpf/set_prc_raw.c
@@ -0,0 +1,40 @@
+/* mpf_set_prec_raw(x,bits) -- Change the precision of x without changing
+ allocation. For proper operation, the original precision need to be reset
+ sooner or later.
+
+Copyright 1996, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_set_prec_raw (mpf_ptr x, mp_bitcnt_t prec_in_bits) __GMP_NOTHROW
+{
+ x->_mp_prec = __GMPF_BITS_TO_PREC (prec_in_bits);
+}
diff --git a/gmp/mpf/set_q.c b/gmp/mpf/set_q.c
new file mode 100644
index 0000000000..c5739b2abe
--- /dev/null
+++ b/gmp/mpf/set_q.c
@@ -0,0 +1,155 @@
+/* mpf_set_q (mpf_t rop, mpq_t op) -- Convert the rational op to the float rop.
+
+Copyright 1996, 1999, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* As usual the aim is to produce PREC(r) limbs, with the high non-zero.
+ The basic mpn_tdiv_qr produces a quotient of nsize-dsize+1 limbs, with
+ either the high or second highest limb non-zero. We arrange for
+ nsize-dsize+1 to equal prec+1, hence giving either prec or prec+1 result
+ limbs at PTR(r).
+
+ nsize-dsize+1 == prec+1 is achieved by adjusting num(q), either dropping
+ low limbs if it's too big, or padding with low zeros if it's too small.
+ The full given den(q) is always used.
+
+ We cannot truncate den(q), because even when it's much bigger than prec
+ the last limbs can still influence the final quotient. Often they don't,
+ but we leave optimization of that to a prospective quotient-only mpn
+ division.
+
+ Not done:
+
+ If den(q) is a power of 2 then we may end up with low zero limbs on the
+ result. But nothing is done about this, since it should be unlikely on
+ random data, and can be left to an application to call mpf_div_2exp if it
+ might occur with any frequency.
+
+ Enhancements:
+
+ The high quotient limb is non-zero when high{np,dsize} >= {dp,dsize}. We
+ could make that comparison and use qsize==prec instead of qsize==prec+1,
+ to save one limb in the division.
+
+ Future:
+
+ If/when mpn_tdiv_qr supports its qxn parameter we can use that instead of
+ padding n with zeros in temporary space.
+
+ If/when a quotient-only division exists it can be used here immediately.
+ remp is only to satisfy mpn_tdiv_qr, the remainder is not used. */
+
+void
+mpf_set_q (mpf_t r, mpq_srcptr q)
+{
+ mp_srcptr np, dp;
+ mp_size_t prec, nsize, dsize, qsize, prospective_qsize, tsize, zeros;
+ mp_size_t sign_quotient, high_zero;
+ mp_ptr qp, tp, remp;
+ mp_exp_t exp;
+ TMP_DECL;
+
+ ASSERT (SIZ(&q->_mp_den) > 0); /* canonical q */
+
+ nsize = SIZ (&q->_mp_num);
+ dsize = SIZ (&q->_mp_den);
+
+ if (UNLIKELY (nsize == 0))
+ {
+ SIZ (r) = 0;
+ EXP (r) = 0;
+ return;
+ }
+
+ TMP_MARK;
+
+ prec = PREC (r);
+ qp = PTR (r);
+
+ sign_quotient = nsize;
+ nsize = ABS (nsize);
+ np = PTR (&q->_mp_num);
+ dp = PTR (&q->_mp_den);
+
+ prospective_qsize = nsize - dsize + 1; /* q from using given n,d sizes */
+ exp = prospective_qsize; /* ie. number of integer limbs */
+ qsize = prec + 1; /* desired q */
+
+ zeros = qsize - prospective_qsize; /* n zeros to get desired qsize */
+ tsize = nsize + zeros; /* possible copy of n */
+
+ if (WANT_TMP_DEBUG)
+ {
+ /* separate alloc blocks, for malloc debugging */
+ remp = TMP_ALLOC_LIMBS (dsize);
+ tp = NULL;
+ if (zeros > 0)
+ tp = TMP_ALLOC_LIMBS (tsize);
+ }
+ else
+ {
+ /* one alloc with a conditionalized size, for efficiency */
+ mp_size_t size = dsize + (zeros > 0 ? tsize : 0);
+ remp = TMP_ALLOC_LIMBS (size);
+ tp = remp + dsize;
+ }
+
+ if (zeros > 0)
+ {
+ /* pad n with zeros into temporary space */
+ MPN_ZERO (tp, zeros);
+ MPN_COPY (tp+zeros, np, nsize);
+ np = tp;
+ nsize = tsize;
+ }
+ else
+ {
+ /* shorten n to get desired qsize */
+ nsize += zeros;
+ np -= zeros;
+ }
+
+ ASSERT (nsize-dsize+1 == qsize);
+ mpn_tdiv_qr (qp, remp, (mp_size_t) 0, np, nsize, dp, dsize);
+
+ /* strip possible zero high limb */
+ high_zero = (qp[qsize-1] == 0);
+ qsize -= high_zero;
+ exp -= high_zero;
+
+ EXP (r) = exp;
+ SIZ (r) = sign_quotient >= 0 ? qsize : -qsize;
+
+ TMP_FREE;
+}
diff --git a/gmp/mpf/set_si.c b/gmp/mpf/set_si.c
new file mode 100644
index 0000000000..9c47c7511f
--- /dev/null
+++ b/gmp/mpf/set_si.c
@@ -0,0 +1,53 @@
+/* mpf_set_si() -- Assign a float from a signed int.
+
+Copyright 1993-1995, 2000-2002, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_set_si (mpf_ptr dest, long val)
+{
+ mp_size_t size;
+ mp_limb_t vl;
+
+ vl = (mp_limb_t) ABS_CAST (unsigned long int, val);
+
+ dest->_mp_d[0] = vl & GMP_NUMB_MASK;
+ size = vl != 0;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ vl >>= GMP_NUMB_BITS;
+ dest->_mp_d[1] = vl;
+ size += (vl != 0);
+#endif
+
+ dest->_mp_exp = size;
+ dest->_mp_size = val >= 0 ? size : -size;
+}
diff --git a/gmp/mpf/set_str.c b/gmp/mpf/set_str.c
new file mode 100644
index 0000000000..9053accade
--- /dev/null
+++ b/gmp/mpf/set_str.c
@@ -0,0 +1,402 @@
+/* mpf_set_str (dest, string, base) -- Convert the string STRING
+ in base BASE to a float in dest. If BASE is zero, the leading characters
+ of STRING is used to figure out the base.
+
+Copyright 1993-1997, 2000-2003, 2005, 2007, 2008, 2011, 2013 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/*
+ This still needs work, as suggested by some FIXME comments.
+ 1. Don't depend on superfluous mantissa digits.
+ 2. Allocate temp space more cleverly.
+ 3. Use mpn_div_q instead of mpn_lshift+mpn_divrem.
+*/
+
+#define _GNU_SOURCE /* for DECIMAL_POINT in langinfo.h */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#if HAVE_LANGINFO_H
+#include <langinfo.h> /* for nl_langinfo */
+#endif
+
+#if HAVE_LOCALE_H
+#include <locale.h> /* for localeconv */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#define digit_value_tab __gmp_digit_value_tab
+
+/* Compute base^exp and return the most significant prec limbs in rp[].
+ Put the count of omitted low limbs in *ign.
+ Return the actual size (which might be less than prec). */
+static mp_size_t
+mpn_pow_1_highpart (mp_ptr rp, mp_size_t *ignp,
+ mp_limb_t base, mp_exp_t exp,
+ mp_size_t prec, mp_ptr tp)
+{
+ mp_size_t ign; /* counts number of ignored low limbs in r */
+ mp_size_t off; /* keeps track of offset where value starts */
+ mp_ptr passed_rp = rp;
+ mp_size_t rn;
+ int cnt;
+ int i;
+
+ rp[0] = base;
+ rn = 1;
+ off = 0;
+ ign = 0;
+ count_leading_zeros (cnt, exp);
+ for (i = GMP_LIMB_BITS - cnt - 2; i >= 0; i--)
+ {
+ mpn_sqr (tp, rp + off, rn);
+ rn = 2 * rn;
+ rn -= tp[rn - 1] == 0;
+ ign <<= 1;
+
+ off = 0;
+ if (rn > prec)
+ {
+ ign += rn - prec;
+ off = rn - prec;
+ rn = prec;
+ }
+ MP_PTR_SWAP (rp, tp);
+
+ if (((exp >> i) & 1) != 0)
+ {
+ mp_limb_t cy;
+ cy = mpn_mul_1 (rp, rp + off, rn, base);
+ rp[rn] = cy;
+ rn += cy != 0;
+ off = 0;
+ }
+ }
+
+ if (rn > prec)
+ {
+ ign += rn - prec;
+ rp += rn - prec;
+ rn = prec;
+ }
+
+ MPN_COPY_INCR (passed_rp, rp + off, rn);
+ *ignp = ign;
+ return rn;
+}
+
+int
+mpf_set_str (mpf_ptr x, const char *str, int base)
+{
+ size_t str_size;
+ char *s, *begs;
+ size_t i, j;
+ int c;
+ int negative;
+ char *dotpos = 0;
+ const char *expptr;
+ int exp_base;
+ const char *point = GMP_DECIMAL_POINT;
+ size_t pointlen = strlen (point);
+ const unsigned char *digit_value;
+ TMP_DECL;
+
+ c = (unsigned char) *str;
+
+ /* Skip whitespace. */
+ while (isspace (c))
+ c = (unsigned char) *++str;
+
+ negative = 0;
+ if (c == '-')
+ {
+ negative = 1;
+ c = (unsigned char) *++str;
+ }
+
+ /* Default base to decimal. */
+ if (base == 0)
+ base = 10;
+
+ exp_base = base;
+
+ if (base < 0)
+ {
+ exp_base = 10;
+ base = -base;
+ }
+
+ digit_value = digit_value_tab;
+ if (base > 36)
+ {
+ /* For bases > 36, use the collating sequence
+ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz. */
+ digit_value += 208;
+ if (base > 62)
+ return -1; /* too large base */
+ }
+
+ /* Require at least one digit, possibly after an initial decimal point. */
+ if (digit_value[c] >= base)
+ {
+ /* not a digit, must be a decimal point */
+ for (i = 0; i < pointlen; i++)
+ if (str[i] != point[i])
+ return -1;
+ if (digit_value[(unsigned char) str[pointlen]] >= base)
+ return -1;
+ }
+
+ /* Locate exponent part of the input. Look from the right of the string,
+ since the exponent is usually a lot shorter than the mantissa. */
+ expptr = NULL;
+ str_size = strlen (str);
+ for (i = str_size - 1; i > 0; i--)
+ {
+ c = (unsigned char) str[i];
+ if (c == '@' || (base <= 10 && (c == 'e' || c == 'E')))
+ {
+ expptr = str + i + 1;
+ str_size = i;
+ break;
+ }
+ }
+
+ TMP_MARK;
+ s = begs = (char *) TMP_ALLOC (str_size + 1);
+
+ /* Loop through mantissa, converting it from ASCII to raw byte values. */
+ for (i = 0; i < str_size; i++)
+ {
+ c = (unsigned char) *str;
+ if (!isspace (c))
+ {
+ int dig;
+
+ for (j = 0; j < pointlen; j++)
+ if (str[j] != point[j])
+ goto not_point;
+ if (1)
+ {
+ if (dotpos != 0)
+ {
+ /* already saw a decimal point, another is invalid */
+ TMP_FREE;
+ return -1;
+ }
+ dotpos = s;
+ str += pointlen - 1;
+ i += pointlen - 1;
+ }
+ else
+ {
+ not_point:
+ dig = digit_value[c];
+ if (dig >= base)
+ {
+ TMP_FREE;
+ return -1;
+ }
+ *s++ = dig;
+ }
+ }
+ c = (unsigned char) *++str;
+ }
+
+ str_size = s - begs;
+
+ {
+ long exp_in_base;
+ mp_size_t ra, ma, rn, mn;
+ int cnt;
+ mp_ptr mp, tp, rp;
+ mp_exp_t exp_in_limbs;
+ mp_size_t prec = PREC(x) + 1;
+ int divflag;
+ mp_size_t madj, radj;
+
+#if 0
+ size_t n_chars_needed;
+
+ /* This breaks things like 0.000...0001. To safely ignore superfluous
+ digits, we need to skip over leading zeros. */
+ /* Just consider the relevant leading digits of the mantissa. */
+ LIMBS_PER_DIGIT_IN_BASE (n_chars_needed, prec, base);
+ if (str_size > n_chars_needed)
+ str_size = n_chars_needed;
+#endif
+
+ LIMBS_PER_DIGIT_IN_BASE (ma, str_size, base);
+ mp = TMP_ALLOC_LIMBS (ma);
+ mn = mpn_set_str (mp, (unsigned char *) begs, str_size, base);
+
+ if (mn == 0)
+ {
+ SIZ(x) = 0;
+ EXP(x) = 0;
+ TMP_FREE;
+ return 0;
+ }
+
+ madj = 0;
+ /* Ignore excess limbs in MP,MSIZE. */
+ if (mn > prec)
+ {
+ madj = mn - prec;
+ mp += mn - prec;
+ mn = prec;
+ }
+
+ if (expptr != 0)
+ {
+ /* Scan and convert the exponent, in base exp_base. */
+ long dig, minus, plusminus;
+ c = (unsigned char) *expptr;
+ minus = -(long) (c == '-');
+ plusminus = minus | -(long) (c == '+');
+ expptr -= plusminus; /* conditional increment */
+ c = (unsigned char) *expptr++;
+ dig = digit_value[c];
+ if (dig >= exp_base)
+ {
+ TMP_FREE;
+ return -1;
+ }
+ exp_in_base = dig;
+ c = (unsigned char) *expptr++;
+ dig = digit_value[c];
+ while (dig < exp_base)
+ {
+ exp_in_base = exp_in_base * exp_base;
+ exp_in_base += dig;
+ c = (unsigned char) *expptr++;
+ dig = digit_value[c];
+ }
+ exp_in_base = (exp_in_base ^ minus) - minus; /* conditional negation */
+ }
+ else
+ exp_in_base = 0;
+ if (dotpos != 0)
+ exp_in_base -= s - dotpos;
+ divflag = exp_in_base < 0;
+ exp_in_base = ABS (exp_in_base);
+
+ if (exp_in_base == 0)
+ {
+ MPN_COPY (PTR(x), mp, mn);
+ SIZ(x) = negative ? -mn : mn;
+ EXP(x) = mn + madj;
+ TMP_FREE;
+ return 0;
+ }
+
+ ra = 2 * (prec + 1);
+ rp = TMP_ALLOC_LIMBS (ra);
+ tp = TMP_ALLOC_LIMBS (ra);
+ rn = mpn_pow_1_highpart (rp, &radj, (mp_limb_t) base, exp_in_base, prec, tp);
+
+ if (divflag)
+ {
+#if 0
+ /* FIXME: Should use mpn_div_q here. */
+ ...
+ mpn_div_q (tp, mp, mn, rp, rn, scratch);
+ ...
+#else
+ mp_ptr qp;
+ mp_limb_t qlimb;
+ if (mn < rn)
+ {
+ /* Pad out MP,MSIZE for current divrem semantics. */
+ mp_ptr tmp = TMP_ALLOC_LIMBS (rn + 1);
+ MPN_ZERO (tmp, rn - mn);
+ MPN_COPY (tmp + rn - mn, mp, mn);
+ mp = tmp;
+ madj -= rn - mn;
+ mn = rn;
+ }
+ if ((rp[rn - 1] & GMP_NUMB_HIGHBIT) == 0)
+ {
+ mp_limb_t cy;
+ count_leading_zeros (cnt, rp[rn - 1]);
+ cnt -= GMP_NAIL_BITS;
+ mpn_lshift (rp, rp, rn, cnt);
+ cy = mpn_lshift (mp, mp, mn, cnt);
+ if (cy)
+ mp[mn++] = cy;
+ }
+
+ qp = TMP_ALLOC_LIMBS (prec + 1);
+ qlimb = mpn_divrem (qp, prec - (mn - rn), mp, mn, rp, rn);
+ tp = qp;
+ exp_in_limbs = qlimb + (mn - rn) + (madj - radj);
+ rn = prec;
+ if (qlimb != 0)
+ {
+ tp[prec] = qlimb;
+ /* Skip the least significant limb not to overrun the destination
+ variable. */
+ tp++;
+ }
+#endif
+ }
+ else
+ {
+ tp = TMP_ALLOC_LIMBS (rn + mn);
+ if (rn > mn)
+ mpn_mul (tp, rp, rn, mp, mn);
+ else
+ mpn_mul (tp, mp, mn, rp, rn);
+ rn += mn;
+ rn -= tp[rn - 1] == 0;
+ exp_in_limbs = rn + madj + radj;
+
+ if (rn > prec)
+ {
+ tp += rn - prec;
+ rn = prec;
+ exp_in_limbs += 0;
+ }
+ }
+
+ MPN_COPY (PTR(x), tp, rn);
+ SIZ(x) = negative ? -rn : rn;
+ EXP(x) = exp_in_limbs;
+ TMP_FREE;
+ return 0;
+ }
+}
diff --git a/gmp/mpf/set_ui.c b/gmp/mpf/set_ui.c
new file mode 100644
index 0000000000..617bce13c1
--- /dev/null
+++ b/gmp/mpf/set_ui.c
@@ -0,0 +1,49 @@
+/* mpf_set_ui() -- Assign a float from an unsigned int.
+
+Copyright 1993-1995, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_set_ui (mpf_ptr f, unsigned long val)
+{
+ mp_size_t size;
+
+ f->_mp_d[0] = val & GMP_NUMB_MASK;
+ size = val != 0;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ val >>= GMP_NUMB_BITS;
+ f->_mp_d[1] = val;
+ size += (val != 0);
+#endif
+
+ f->_mp_exp = f->_mp_size = size;
+}
diff --git a/gmp/mpf/set_z.c b/gmp/mpf/set_z.c
new file mode 100644
index 0000000000..fe91904563
--- /dev/null
+++ b/gmp/mpf/set_z.c
@@ -0,0 +1,57 @@
+/* mpf_set_z -- Assign a float from an integer.
+
+Copyright 1996, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_set_z (mpf_ptr r, mpz_srcptr u)
+{
+ mp_ptr rp, up;
+ mp_size_t size, asize;
+ mp_size_t prec;
+
+ prec = PREC (r) + 1;
+ size = SIZ (u);
+ asize = ABS (size);
+ rp = PTR (r);
+ up = PTR (u);
+
+ EXP (r) = asize;
+
+ if (asize > prec)
+ {
+ up += asize - prec;
+ asize = prec;
+ }
+
+ SIZ (r) = size >= 0 ? asize : -asize;
+ MPN_COPY (rp, up, asize);
+}
diff --git a/gmp/mpf/size.c b/gmp/mpf/size.c
new file mode 100644
index 0000000000..c6b22b64cc
--- /dev/null
+++ b/gmp/mpf/size.c
@@ -0,0 +1,39 @@
+/* mpf_size(x) -- return the number of limbs currently used by the
+ value of the float X.
+
+Copyright 1993-1995, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+mpf_size (mpf_srcptr f) __GMP_NOTHROW
+{
+ return __GMP_ABS (f->_mp_size);
+}
diff --git a/gmp/mpf/sqrt.c b/gmp/mpf/sqrt.c
new file mode 100644
index 0000000000..44502244e2
--- /dev/null
+++ b/gmp/mpf/sqrt.c
@@ -0,0 +1,113 @@
+/* mpf_sqrt -- Compute the square root of a float.
+
+Copyright 1993, 1994, 1996, 2000, 2001, 2004, 2005, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* As usual, the aim is to produce PREC(r) limbs of result, with the high
+ limb non-zero. This is accomplished by applying mpn_sqrtrem to either
+ 2*prec or 2*prec-1 limbs, both such sizes resulting in prec limbs.
+
+ The choice between 2*prec or 2*prec-1 limbs is based on the input
+ exponent. With b=2^GMP_NUMB_BITS the limb base then we can think of
+ effectively taking out a factor b^(2k), for suitable k, to get to an
+ integer input of the desired size ready for mpn_sqrtrem. It must be an
+ even power taken out, ie. an even number of limbs, so the square root
+ gives factor b^k and the radix point is still on a limb boundary. So if
+ EXP(r) is even we'll get an even number of input limbs 2*prec, or if
+ EXP(r) is odd we get an odd number 2*prec-1.
+
+ Further limbs below the 2*prec or 2*prec-1 used don't affect the result
+ and are simply truncated. This can be seen by considering an integer x,
+ with s=floor(sqrt(x)). s is the unique integer satisfying s^2 <= x <
+ (s+1)^2. Notice that adding a fraction part to x (ie. some further bits)
+ doesn't change the inequality, s remains the unique solution. Working
+ suitable factors of 2 into this argument lets it apply to an intended
+ precision at any position for any x, not just the integer binary point.
+
+ If the input is smaller than 2*prec or 2*prec-1, then we just pad with
+ zeros, that of course being our usual interpretation of short inputs.
+ The effect is to extend the root beyond the size of the input (for
+ instance into fractional limbs if u is an integer). */
+
+void
+mpf_sqrt (mpf_ptr r, mpf_srcptr u)
+{
+ mp_size_t usize;
+ mp_ptr up, tp;
+ mp_size_t prec, tsize;
+ mp_exp_t uexp, expodd;
+ TMP_DECL;
+
+ usize = u->_mp_size;
+ if (UNLIKELY (usize <= 0))
+ {
+ if (usize < 0)
+ SQRT_OF_NEGATIVE;
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ TMP_MARK;
+
+ uexp = u->_mp_exp;
+ prec = r->_mp_prec;
+ up = u->_mp_d;
+
+ expodd = (uexp & 1);
+ tsize = 2 * prec - expodd;
+ r->_mp_size = prec;
+ r->_mp_exp = (uexp + expodd) / 2; /* ceil(uexp/2) */
+
+ /* root size is ceil(tsize/2), this will be our desired "prec" limbs */
+ ASSERT ((tsize + 1) / 2 == prec);
+
+ tp = TMP_ALLOC_LIMBS (tsize);
+
+ if (usize > tsize)
+ {
+ up += usize - tsize;
+ usize = tsize;
+ MPN_COPY (tp, up, tsize);
+ }
+ else
+ {
+ MPN_ZERO (tp, tsize - usize);
+ MPN_COPY (tp + (tsize - usize), up, usize);
+ }
+
+ mpn_sqrtrem (r->_mp_d, NULL, tp, tsize);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpf/sqrt_ui.c b/gmp/mpf/sqrt_ui.c
new file mode 100644
index 0000000000..82dec7bcb3
--- /dev/null
+++ b/gmp/mpf/sqrt_ui.c
@@ -0,0 +1,109 @@
+/* mpf_sqrt_ui -- Compute the square root of an unsigned integer.
+
+Copyright 1993, 1994, 1996, 2000, 2001, 2004, 2005 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* As usual the aim is to produce PREC(r) limbs of result with the high limb
+ non-zero. That high limb will end up floor(sqrt(u)), and limbs below are
+ produced by padding the input with zeros, two for each desired result
+ limb, being 2*(prec-1) for a total 2*prec-1 limbs passed to mpn_sqrtrem.
+ The way mpn_sqrtrem calculates floor(sqrt(x)) ensures the root is correct
+ to the intended accuracy, ie. truncated to prec limbs.
+
+ With nails, u might be two limbs, in which case a total 2*prec limbs is
+ passed to mpn_sqrtrem (still giving a prec limb result). If uhigh is
+ zero we adjust back to 2*prec-1, since mpn_sqrtrem requires the high
+ non-zero. 2*prec limbs are always allocated, even when uhigh is zero, so
+ the store of uhigh can be done without a conditional.
+
+ u==0 is a special case so the rest of the code can assume the result is
+ non-zero (ie. will have a non-zero high limb on the result).
+
+ Not done:
+
+ No attempt is made to identify perfect squares. It's considered this can
+ be left to an application if it might occur with any frequency. As it
+ stands, mpn_sqrtrem does its normal amount of work on a perfect square
+ followed by zero limbs, though of course only an mpn_sqrtrem1 would be
+ actually needed. We also end up leaving our mpf result with lots of low
+ trailing zeros, slowing down subsequent operations.
+
+ We're not aware of any optimizations that can be made using the fact the
+ input has lots of trailing zeros (apart from the perfect square
+ case). */
+
+
+/* 1 if we (might) need two limbs for u */
+#define U2 (GMP_NUMB_BITS < BITS_PER_ULONG)
+
+void
+mpf_sqrt_ui (mpf_ptr r, unsigned long int u)
+{
+ mp_size_t rsize, zeros;
+ mp_ptr tp;
+ mp_size_t prec;
+ TMP_DECL;
+
+ if (UNLIKELY (u == 0))
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ TMP_MARK;
+
+ prec = r->_mp_prec;
+ zeros = 2 * prec - 2;
+ rsize = zeros + 1 + U2;
+
+ tp = TMP_ALLOC_LIMBS (rsize);
+
+ MPN_ZERO (tp, zeros);
+ tp[zeros] = u & GMP_NUMB_MASK;
+
+#if U2
+ {
+ mp_limb_t uhigh = u >> GMP_NUMB_BITS;
+ tp[zeros + 1] = uhigh;
+ rsize -= (uhigh == 0);
+ }
+#endif
+
+ mpn_sqrtrem (r->_mp_d, NULL, tp, rsize);
+
+ r->_mp_size = prec;
+ r->_mp_exp = 1;
+ TMP_FREE;
+}
diff --git a/gmp/mpf/sub.c b/gmp/mpf/sub.c
new file mode 100644
index 0000000000..3aaf192790
--- /dev/null
+++ b/gmp/mpf/sub.c
@@ -0,0 +1,419 @@
+/* mpf_sub -- Subtract two floats.
+
+Copyright 1993-1996, 1999-2002, 2004, 2005, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_sub (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
+{
+ mp_srcptr up, vp;
+ mp_ptr rp, tp;
+ mp_size_t usize, vsize, rsize;
+ mp_size_t prec;
+ mp_exp_t exp;
+ mp_size_t ediff;
+ int negate;
+ TMP_DECL;
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+
+ /* Handle special cases that don't work in generic code below. */
+ if (usize == 0)
+ {
+ mpf_neg (r, v);
+ return;
+ }
+ if (vsize == 0)
+ {
+ if (r != u)
+ mpf_set (r, u);
+ return;
+ }
+
+ /* If signs of U and V are different, perform addition. */
+ if ((usize ^ vsize) < 0)
+ {
+ __mpf_struct v_negated;
+ v_negated._mp_size = -vsize;
+ v_negated._mp_exp = v->_mp_exp;
+ v_negated._mp_d = v->_mp_d;
+ mpf_add (r, u, &v_negated);
+ return;
+ }
+
+ TMP_MARK;
+
+ /* Signs are now known to be the same. */
+ negate = usize < 0;
+
+ /* Make U be the operand with the largest exponent. */
+ if (u->_mp_exp < v->_mp_exp)
+ {
+ mpf_srcptr t;
+ t = u; u = v; v = t;
+ negate ^= 1;
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+ }
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ rp = r->_mp_d;
+ prec = r->_mp_prec + 1;
+ exp = u->_mp_exp;
+ ediff = u->_mp_exp - v->_mp_exp;
+
+ /* If ediff is 0 or 1, we might have a situation where the operands are
+ extremely close. We need to scan the operands from the most significant
+ end ignore the initial parts that are equal. */
+ if (ediff <= 1)
+ {
+ if (ediff == 0)
+ {
+ /* Skip leading limbs in U and V that are equal. */
+ if (up[usize - 1] == vp[vsize - 1])
+ {
+ /* This loop normally exits immediately. Optimize for that. */
+ do
+ {
+ usize--;
+ vsize--;
+ exp--;
+
+ if (usize == 0)
+ {
+ /* u cancels high limbs of v, result is rest of v */
+ negate ^= 1;
+ cancellation:
+ /* strip high zeros before truncating to prec */
+ while (vsize != 0 && vp[vsize - 1] == 0)
+ {
+ vsize--;
+ exp--;
+ }
+ if (vsize > prec)
+ {
+ vp += vsize - prec;
+ vsize = prec;
+ }
+ MPN_COPY_INCR (rp, vp, vsize);
+ rsize = vsize;
+ goto done;
+ }
+ if (vsize == 0)
+ {
+ vp = up;
+ vsize = usize;
+ goto cancellation;
+ }
+ }
+ while (up[usize - 1] == vp[vsize - 1]);
+ }
+
+ if (up[usize - 1] < vp[vsize - 1])
+ {
+ /* For simplicity, swap U and V. Note that since the loop above
+ wouldn't have exited unless up[usize - 1] and vp[vsize - 1]
+ were non-equal, this if-statement catches all cases where U
+ is smaller than V. */
+ MPN_SRCPTR_SWAP (up,usize, vp,vsize);
+ negate ^= 1;
+ /* negating ediff not necessary since it is 0. */
+ }
+
+ /* Check for
+ x+1 00000000 ...
+ x ffffffff ... */
+ if (up[usize - 1] != vp[vsize - 1] + 1)
+ goto general_case;
+ usize--;
+ vsize--;
+ exp--;
+ }
+ else /* ediff == 1 */
+ {
+ /* Check for
+ 1 00000000 ...
+ 0 ffffffff ... */
+
+ if (up[usize - 1] != 1 || vp[vsize - 1] != GMP_NUMB_MAX
+ || (usize >= 2 && up[usize - 2] != 0))
+ goto general_case;
+
+ usize--;
+ exp--;
+ }
+
+ /* Skip sequences of 00000000/ffffffff */
+ while (vsize != 0 && usize != 0 && up[usize - 1] == 0
+ && vp[vsize - 1] == GMP_NUMB_MAX)
+ {
+ usize--;
+ vsize--;
+ exp--;
+ }
+
+ if (usize == 0)
+ {
+ while (vsize != 0 && vp[vsize - 1] == GMP_NUMB_MAX)
+ {
+ vsize--;
+ exp--;
+ }
+ }
+
+ if (usize > prec - 1)
+ {
+ up += usize - (prec - 1);
+ usize = prec - 1;
+ }
+ if (vsize > prec - 1)
+ {
+ vp += vsize - (prec - 1);
+ vsize = prec - 1;
+ }
+
+ tp = TMP_ALLOC_LIMBS (prec);
+ {
+ mp_limb_t cy_limb;
+ if (vsize == 0)
+ {
+ mp_size_t size, i;
+ size = usize;
+ for (i = 0; i < size; i++)
+ tp[i] = up[i];
+ tp[size] = 1;
+ rsize = size + 1;
+ exp++;
+ goto normalize;
+ }
+ if (usize == 0)
+ {
+ mp_size_t size, i;
+ size = vsize;
+ for (i = 0; i < size; i++)
+ tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ cy_limb = 1 - mpn_add_1 (tp, tp, vsize, (mp_limb_t) 1);
+ rsize = vsize;
+ if (cy_limb == 0)
+ {
+ tp[rsize] = 1;
+ rsize++;
+ exp++;
+ }
+ goto normalize;
+ }
+ if (usize >= vsize)
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size;
+ size = usize - vsize;
+ MPN_COPY (tp, up, size);
+ cy_limb = mpn_sub_n (tp + size, up + size, vp, vsize);
+ rsize = usize;
+ }
+ else /* (usize < vsize) */
+ {
+ /* uuuu */
+ /* vvvvvvv */
+ mp_size_t size, i;
+ size = vsize - usize;
+ for (i = 0; i < size; i++)
+ tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ cy_limb = mpn_sub_n (tp + size, up, vp + size, usize);
+ cy_limb+= mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ cy_limb-= mpn_add_1 (tp, tp, vsize, (mp_limb_t) 1);
+ rsize = vsize;
+ }
+ if (cy_limb == 0)
+ {
+ tp[rsize] = 1;
+ rsize++;
+ exp++;
+ }
+ goto normalize;
+ }
+ }
+
+general_case:
+ /* If U extends beyond PREC, ignore the part that does. */
+ if (usize > prec)
+ {
+ up += usize - prec;
+ usize = prec;
+ }
+
+ /* If V extends beyond PREC, ignore the part that does.
+ Note that this may make vsize negative. */
+ if (vsize + ediff > prec)
+ {
+ vp += vsize + ediff - prec;
+ vsize = prec - ediff;
+ }
+
+ if (ediff >= prec)
+ {
+ /* V completely cancelled. */
+ if (rp != up)
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ }
+ else
+ {
+ /* Allocate temp space for the result. Allocate
+ just vsize + ediff later??? */
+ tp = TMP_ALLOC_LIMBS (prec);
+
+ /* Locate the least significant non-zero limb in (the needed
+ parts of) U and V, to simplify the code below. */
+ for (;;)
+ {
+ if (vsize == 0)
+ {
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ goto done;
+ }
+ if (vp[0] != 0)
+ break;
+ vp++, vsize--;
+ }
+ for (;;)
+ {
+ if (usize == 0)
+ {
+ MPN_COPY (rp, vp, vsize);
+ rsize = vsize;
+ negate ^= 1;
+ goto done;
+ }
+ if (up[0] != 0)
+ break;
+ up++, usize--;
+ }
+
+ /* uuuu | uuuu | uuuu | uuuu | uuuu */
+ /* vvvvvvv | vv | vvvvv | v | vv */
+
+ if (usize > ediff)
+ {
+ /* U and V partially overlaps. */
+ if (ediff == 0)
+ {
+ /* Have to compare the leading limbs of u and v
+ to determine whether to compute u - v or v - u. */
+ if (usize >= vsize)
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size;
+ size = usize - vsize;
+ MPN_COPY (tp, up, size);
+ mpn_sub_n (tp + size, up + size, vp, vsize);
+ rsize = usize;
+ }
+ else /* (usize < vsize) */
+ {
+ /* uuuu */
+ /* vvvvvvv */
+ mp_size_t size, i;
+ size = vsize - usize;
+ tp[0] = -vp[0] & GMP_NUMB_MASK;
+ for (i = 1; i < size; i++)
+ tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ mpn_sub_n (tp + size, up, vp + size, usize);
+ mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ rsize = vsize;
+ }
+ }
+ else
+ {
+ if (vsize + ediff <= usize)
+ {
+ /* uuuu */
+ /* v */
+ mp_size_t size;
+ size = usize - ediff - vsize;
+ MPN_COPY (tp, up, size);
+ mpn_sub (tp + size, up + size, usize - size, vp, vsize);
+ rsize = usize;
+ }
+ else
+ {
+ /* uuuu */
+ /* vvvvv */
+ mp_size_t size, i;
+ size = vsize + ediff - usize;
+ tp[0] = -vp[0] & GMP_NUMB_MASK;
+ for (i = 1; i < size; i++)
+ tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ mpn_sub (tp + size, up, usize, vp + size, usize - ediff);
+ mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ rsize = vsize + ediff;
+ }
+ }
+ }
+ else
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size, i;
+ size = vsize + ediff - usize;
+ tp[0] = -vp[0] & GMP_NUMB_MASK;
+ for (i = 1; i < vsize; i++)
+ tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ for (i = vsize; i < size; i++)
+ tp[i] = GMP_NUMB_MAX;
+ mpn_sub_1 (tp + size, up, usize, (mp_limb_t) 1);
+ rsize = size + usize;
+ }
+
+ normalize:
+ /* Full normalize. Optimize later. */
+ while (rsize != 0 && tp[rsize - 1] == 0)
+ {
+ rsize--;
+ exp--;
+ }
+ MPN_COPY (rp, tp, rsize);
+ }
+
+ done:
+ r->_mp_size = negate ? -rsize : rsize;
+ if (rsize == 0)
+ exp = 0;
+ r->_mp_exp = exp;
+ TMP_FREE;
+}
diff --git a/gmp/mpf/sub_ui.c b/gmp/mpf/sub_ui.c
new file mode 100644
index 0000000000..cf9b88eb00
--- /dev/null
+++ b/gmp/mpf/sub_ui.c
@@ -0,0 +1,51 @@
+/* mpf_sub_ui -- Subtract an unsigned integer from a float.
+
+Copyright 1993, 1994, 1996, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_sub_ui (mpf_ptr sum, mpf_srcptr u, unsigned long int v)
+{
+ __mpf_struct vv;
+ mp_limb_t vl;
+
+ if (v == 0)
+ {
+ mpf_set (sum, u);
+ return;
+ }
+
+ vl = v;
+ vv._mp_size = 1;
+ vv._mp_d = &vl;
+ vv._mp_exp = 1;
+ mpf_sub (sum, u, &vv);
+}
diff --git a/gmp/mpf/swap.c b/gmp/mpf/swap.c
new file mode 100644
index 0000000000..a370652876
--- /dev/null
+++ b/gmp/mpf/swap.c
@@ -0,0 +1,57 @@
+/* mpf_swap (U, V) -- Swap U and V.
+
+Copyright 1997, 1998, 2000, 2001, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_swap (mpf_ptr u, mpf_ptr v) __GMP_NOTHROW
+{
+ mp_ptr tptr;
+ mp_size_t tprec;
+ mp_size_t tsiz;
+ mp_exp_t texp;
+
+ tprec = PREC(u);
+ PREC(u) = PREC(v);
+ PREC(v) = tprec;
+
+ tsiz = SIZ(u);
+ SIZ(u) = SIZ(v);
+ SIZ(v) = tsiz;
+
+ texp = EXP(u);
+ EXP(u) = EXP(v);
+ EXP(v) = texp;
+
+ tptr = PTR(u);
+ PTR(u) = PTR(v);
+ PTR(v) = tptr;
+}
diff --git a/gmp/mpf/trunc.c b/gmp/mpf/trunc.c
new file mode 100644
index 0000000000..5f94f7aec8
--- /dev/null
+++ b/gmp/mpf/trunc.c
@@ -0,0 +1,75 @@
+/* mpf_trunc -- truncate an mpf to an integer.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Notice the use of prec+1 ensures mpf_trunc is equivalent to mpf_set if u
+ is already an integer. */
+
+void
+mpf_trunc (mpf_ptr r, mpf_srcptr u)
+{
+ mp_ptr rp;
+ mp_srcptr up;
+ mp_size_t size, asize, prec;
+ mp_exp_t exp;
+
+ exp = EXP(u);
+ size = SIZ(u);
+ if (size == 0 || exp <= 0)
+ {
+ /* u is only a fraction */
+ SIZ(r) = 0;
+ EXP(r) = 0;
+ return;
+ }
+
+ up = PTR(u);
+ EXP(r) = exp;
+ asize = ABS (size);
+ up += asize;
+
+ /* skip fraction part of u */
+ asize = MIN (asize, exp);
+
+ /* don't lose precision in the copy */
+ prec = PREC(r) + 1;
+
+ /* skip excess over target precision */
+ asize = MIN (asize, prec);
+
+ up -= asize;
+ rp = PTR(r);
+ SIZ(r) = (size >= 0 ? asize : -asize);
+ if (rp != up)
+ MPN_COPY_INCR (rp, up, asize);
+}
diff --git a/gmp/mpf/ui_div.c b/gmp/mpf/ui_div.c
new file mode 100644
index 0000000000..ceb881ebcc
--- /dev/null
+++ b/gmp/mpf/ui_div.c
@@ -0,0 +1,128 @@
+/* mpf_ui_div -- Divide an unsigned integer with a float.
+
+Copyright 1993-1996, 2000-2002, 2004, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+void
+mpf_ui_div (mpf_ptr r, unsigned long int u, mpf_srcptr v)
+{
+ mp_srcptr vp;
+ mp_ptr rp, tp, remp, new_vp;
+ mp_size_t vsize;
+ mp_size_t rsize, prospective_rsize, zeros, tsize, high_zero;
+ mp_size_t sign_quotient;
+ mp_size_t prec;
+ mp_exp_t rexp;
+ TMP_DECL;
+
+ vsize = v->_mp_size;
+ sign_quotient = vsize;
+
+ if (UNLIKELY (vsize == 0))
+ DIVIDE_BY_ZERO;
+
+ if (UNLIKELY (u == 0))
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ vsize = ABS (vsize);
+ prec = r->_mp_prec;
+
+ TMP_MARK;
+ rexp = 1 - v->_mp_exp + 1;
+
+ rp = r->_mp_d;
+ vp = v->_mp_d;
+
+ prospective_rsize = 1 - vsize + 1; /* quot from using given u,v sizes */
+ rsize = prec + 1; /* desired quot size */
+
+ zeros = rsize - prospective_rsize; /* padding u to give rsize */
+ tsize = 1 + zeros; /* u with zeros */
+
+ if (WANT_TMP_DEBUG)
+ {
+ /* separate alloc blocks, for malloc debugging */
+ remp = TMP_ALLOC_LIMBS (vsize);
+ tp = TMP_ALLOC_LIMBS (tsize);
+ new_vp = NULL;
+ if (rp == vp)
+ new_vp = TMP_ALLOC_LIMBS (vsize);
+ }
+ else
+ {
+ /* one alloc with calculated size, for efficiency */
+ mp_size_t size = vsize + tsize + (rp == vp ? vsize : 0);
+ remp = TMP_ALLOC_LIMBS (size);
+ tp = remp + vsize;
+ new_vp = tp + tsize;
+ }
+
+ /* ensure divisor doesn't overlap quotient */
+ if (rp == vp)
+ {
+ MPN_COPY (new_vp, vp, vsize);
+ vp = new_vp;
+ }
+
+ MPN_ZERO (tp, tsize-1);
+
+ tp[tsize - 1] = u & GMP_NUMB_MASK;
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ if (u > GMP_NUMB_MAX)
+ {
+ /* tsize-vsize+1 == rsize, so tsize >= rsize. rsize == prec+1 >= 2,
+ so tsize >= 2, hence there's room for 2-limb u with nails */
+ ASSERT (tsize >= 2);
+ tp[tsize - 1] = u >> GMP_NUMB_BITS;
+ tp[tsize - 2] = u & GMP_NUMB_MASK;
+ rexp++;
+ }
+#endif
+
+ ASSERT (tsize-vsize+1 == rsize);
+ mpn_tdiv_qr (rp, remp, (mp_size_t) 0, tp, tsize, vp, vsize);
+
+ /* strip possible zero high limb */
+ high_zero = (rp[rsize-1] == 0);
+ rsize -= high_zero;
+ rexp -= high_zero;
+
+ r->_mp_size = sign_quotient >= 0 ? rsize : -rsize;
+ r->_mp_exp = rexp;
+ TMP_FREE;
+}
diff --git a/gmp/mpf/ui_sub.c b/gmp/mpf/ui_sub.c
new file mode 100644
index 0000000000..b7a536eb8b
--- /dev/null
+++ b/gmp/mpf/ui_sub.c
@@ -0,0 +1,336 @@
+/* mpf_ui_sub -- Subtract a float from an unsigned long int.
+
+Copyright 1993-1996, 2001, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_ui_sub (mpf_ptr r, unsigned long int u, mpf_srcptr v)
+{
+ mp_srcptr up, vp;
+ mp_ptr rp, tp;
+ mp_size_t usize, vsize, rsize;
+ mp_size_t prec;
+ mp_exp_t uexp;
+ mp_size_t ediff;
+ int negate;
+ mp_limb_t ulimb;
+ TMP_DECL;
+
+ vsize = v->_mp_size;
+
+ /* Handle special cases that don't work in generic code below. */
+ if (u == 0)
+ {
+ mpf_neg (r, v);
+ return;
+ }
+ if (vsize == 0)
+ {
+ mpf_set_ui (r, u);
+ return;
+ }
+
+ /* If signs of U and V are different, perform addition. */
+ if (vsize < 0)
+ {
+ __mpf_struct v_negated;
+ v_negated._mp_size = -vsize;
+ v_negated._mp_exp = v->_mp_exp;
+ v_negated._mp_d = v->_mp_d;
+ mpf_add_ui (r, &v_negated, u);
+ return;
+ }
+
+ TMP_MARK;
+
+ /* Signs are now known to be the same. */
+
+ ulimb = u;
+ /* Make U be the operand with the largest exponent. */
+ if (1 < v->_mp_exp)
+ {
+ negate = 1;
+ usize = ABS (vsize);
+ vsize = 1;
+ up = v->_mp_d;
+ vp = &ulimb;
+ rp = r->_mp_d;
+ prec = r->_mp_prec + 1;
+ uexp = v->_mp_exp;
+ ediff = uexp - 1;
+ }
+ else
+ {
+ negate = 0;
+ usize = 1;
+ vsize = ABS (vsize);
+ up = &ulimb;
+ vp = v->_mp_d;
+ rp = r->_mp_d;
+ prec = r->_mp_prec;
+ uexp = 1;
+ ediff = 1 - v->_mp_exp;
+ }
+
+ /* Ignore leading limbs in U and V that are equal. Doing
+ this helps increase the precision of the result. */
+ if (ediff == 0)
+ {
+ /* This loop normally exits immediately. Optimize for that. */
+ for (;;)
+ {
+ usize--;
+ vsize--;
+ if (up[usize] != vp[vsize])
+ break;
+ uexp--;
+ if (usize == 0)
+ goto Lu0;
+ if (vsize == 0)
+ goto Lv0;
+ }
+ usize++;
+ vsize++;
+ /* Note that either operand (but not both operands) might now have
+ leading zero limbs. It matters only that U is unnormalized if
+ vsize is now zero, and vice versa. And it is only in that case
+ that we have to adjust uexp. */
+ if (vsize == 0)
+ Lv0:
+ while (usize != 0 && up[usize - 1] == 0)
+ usize--, uexp--;
+ if (usize == 0)
+ Lu0:
+ while (vsize != 0 && vp[vsize - 1] == 0)
+ vsize--, uexp--;
+ }
+
+ /* If U extends beyond PREC, ignore the part that does. */
+ if (usize > prec)
+ {
+ up += usize - prec;
+ usize = prec;
+ }
+
+ /* If V extends beyond PREC, ignore the part that does.
+ Note that this may make vsize negative. */
+ if (vsize + ediff > prec)
+ {
+ vp += vsize + ediff - prec;
+ vsize = prec - ediff;
+ }
+
+ /* Allocate temp space for the result. Allocate
+ just vsize + ediff later??? */
+ tp = TMP_ALLOC_LIMBS (prec);
+
+ if (ediff >= prec)
+ {
+ /* V completely cancelled. */
+ if (tp != up)
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ }
+ else
+ {
+ /* Locate the least significant non-zero limb in (the needed
+ parts of) U and V, to simplify the code below. */
+ for (;;)
+ {
+ if (vsize == 0)
+ {
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ goto done;
+ }
+ if (vp[0] != 0)
+ break;
+ vp++, vsize--;
+ }
+ for (;;)
+ {
+ if (usize == 0)
+ {
+ MPN_COPY (rp, vp, vsize);
+ rsize = vsize;
+ negate ^= 1;
+ goto done;
+ }
+ if (up[0] != 0)
+ break;
+ up++, usize--;
+ }
+
+ /* uuuu | uuuu | uuuu | uuuu | uuuu */
+ /* vvvvvvv | vv | vvvvv | v | vv */
+
+ if (usize > ediff)
+ {
+ /* U and V partially overlaps. */
+ if (ediff == 0)
+ {
+ /* Have to compare the leading limbs of u and v
+ to determine whether to compute u - v or v - u. */
+ if (usize > vsize)
+ {
+ /* uuuu */
+ /* vv */
+ int cmp;
+ cmp = mpn_cmp (up + usize - vsize, vp, vsize);
+ if (cmp >= 0)
+ {
+ mp_size_t size;
+ size = usize - vsize;
+ MPN_COPY (tp, up, size);
+ mpn_sub_n (tp + size, up + size, vp, vsize);
+ rsize = usize;
+ }
+ else
+ {
+ /* vv */ /* Swap U and V. */
+ /* uuuu */
+ mp_size_t size, i;
+ size = usize - vsize;
+ tp[0] = -up[0] & GMP_NUMB_MASK;
+ for (i = 1; i < size; i++)
+ tp[i] = ~up[i] & GMP_NUMB_MASK;
+ mpn_sub_n (tp + size, vp, up + size, vsize);
+ mpn_sub_1 (tp + size, tp + size, vsize, (mp_limb_t) 1);
+ negate ^= 1;
+ rsize = usize;
+ }
+ }
+ else if (usize < vsize)
+ {
+ /* uuuu */
+ /* vvvvvvv */
+ int cmp;
+ cmp = mpn_cmp (up, vp + vsize - usize, usize);
+ if (cmp > 0)
+ {
+ mp_size_t size, i;
+ size = vsize - usize;
+ tp[0] = -vp[0] & GMP_NUMB_MASK;
+ for (i = 1; i < size; i++)
+ tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ mpn_sub_n (tp + size, up, vp + size, usize);
+ mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ rsize = vsize;
+ }
+ else
+ {
+ /* vvvvvvv */ /* Swap U and V. */
+ /* uuuu */
+ /* This is the only place we can get 0.0. */
+ mp_size_t size;
+ size = vsize - usize;
+ MPN_COPY (tp, vp, size);
+ mpn_sub_n (tp + size, vp + size, up, usize);
+ negate ^= 1;
+ rsize = vsize;
+ }
+ }
+ else
+ {
+ /* uuuu */
+ /* vvvv */
+ int cmp;
+ cmp = mpn_cmp (up, vp + vsize - usize, usize);
+ if (cmp > 0)
+ {
+ mpn_sub_n (tp, up, vp, usize);
+ rsize = usize;
+ }
+ else
+ {
+ mpn_sub_n (tp, vp, up, usize);
+ negate ^= 1;
+ rsize = usize;
+ /* can give zero */
+ }
+ }
+ }
+ else
+ {
+ if (vsize + ediff <= usize)
+ {
+ /* uuuu */
+ /* v */
+ mp_size_t size;
+ size = usize - ediff - vsize;
+ MPN_COPY (tp, up, size);
+ mpn_sub (tp + size, up + size, usize - size, vp, vsize);
+ rsize = usize;
+ }
+ else
+ {
+ /* uuuu */
+ /* vvvvv */
+ mp_size_t size, i;
+ size = vsize + ediff - usize;
+ tp[0] = -vp[0] & GMP_NUMB_MASK;
+ for (i = 1; i < size; i++)
+ tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ mpn_sub (tp + size, up, usize, vp + size, usize - ediff);
+ mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ rsize = vsize + ediff;
+ }
+ }
+ }
+ else
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size, i;
+ size = vsize + ediff - usize;
+ tp[0] = -vp[0] & GMP_NUMB_MASK;
+ for (i = 1; i < vsize; i++)
+ tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ for (i = vsize; i < size; i++)
+ tp[i] = GMP_NUMB_MAX;
+ mpn_sub_1 (tp + size, up, usize, (mp_limb_t) 1);
+ rsize = size + usize;
+ }
+
+ /* Full normalize. Optimize later. */
+ while (rsize != 0 && tp[rsize - 1] == 0)
+ {
+ rsize--;
+ uexp--;
+ }
+ MPN_COPY (rp, tp, rsize);
+ }
+
+ done:
+ r->_mp_size = negate ? -rsize : rsize;
+ r->_mp_exp = uexp;
+ TMP_FREE;
+}
diff --git a/gmp/mpf/urandomb.c b/gmp/mpf/urandomb.c
new file mode 100644
index 0000000000..72271e8762
--- /dev/null
+++ b/gmp/mpf/urandomb.c
@@ -0,0 +1,69 @@
+/* mpf_urandomb (rop, state, nbits) -- Generate a uniform pseudorandom
+ real number between 0 (inclusive) and 1 (exclusive) of size NBITS,
+ using STATE as the random state previously initialized by a call to
+ gmp_randinit().
+
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpf_urandomb (mpf_t rop, gmp_randstate_t rstate, mp_bitcnt_t nbits)
+{
+ mp_ptr rp;
+ mp_size_t nlimbs;
+ mp_exp_t exp;
+ mp_size_t prec;
+
+ rp = PTR (rop);
+ nlimbs = BITS_TO_LIMBS (nbits);
+ prec = PREC (rop);
+
+ if (nlimbs > prec + 1 || nlimbs == 0)
+ {
+ nlimbs = prec + 1;
+ nbits = nlimbs * GMP_NUMB_BITS;
+ }
+
+ _gmp_rand (rp, rstate, nbits);
+
+ /* If nbits isn't a multiple of GMP_NUMB_BITS, shift up. */
+ if (nbits % GMP_NUMB_BITS != 0)
+ mpn_lshift (rp, rp, nlimbs, GMP_NUMB_BITS - nbits % GMP_NUMB_BITS);
+
+ exp = 0;
+ while (nlimbs != 0 && rp[nlimbs - 1] == 0)
+ {
+ nlimbs--;
+ exp--;
+ }
+ EXP (rop) = exp;
+ SIZ (rop) = nlimbs;
+}
diff --git a/gmp/mpn/Makeasm.am b/gmp/mpn/Makeasm.am
new file mode 100644
index 0000000000..5d7306c221
--- /dev/null
+++ b/gmp/mpn/Makeasm.am
@@ -0,0 +1,118 @@
+## Automake asm file rules.
+
+# Copyright 1996, 1998-2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# COMPILE minus CC.
+#
+COMPILE_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASMFLAGS)
+
+# Flags used for preprocessing (in ansi2knr rules).
+#
+PREPROCESS_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS)
+
+
+# Recent versions of automake (1.5 and up for instance) append automake
+# generated suffixes to this $(SUFFIXES) list. This is essential for us,
+# since .c must come after .s, .S and .asm. If .c is before .s, for
+# instance, then in the mpn directory "make" will see add_n.c mentioned in
+# an explicit rule (the ansi2knr stuff) and decide it must have add_n.c,
+# even if add_n.c doesn't exist but add_n.s does. See GNU make
+# documentation "(make)Implicit Rule Search", part 5c.
+#
+# On IRIX 6 native make this doesn't work properly though. Somehow .c
+# remains ahead of .s, perhaps because .c.s is a builtin rule. .asm works
+# fine though, and mpn/mips3 uses this.
+#
+SUFFIXES = .s .S .asm
+
+
+# .s assembler, no preprocessing.
+#
+.s.o:
+ $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+.s.obj:
+ $(CCAS) $(COMPILE_FLAGS) `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+.s.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+
+# can be overridden during development, eg. "make RM_TMP=: mul_1.lo"
+RM_TMP = rm -f
+
+
+# .S assembler, preprocessed with cpp.
+#
+# It's necessary to run $(CPP) separately, since it seems not all compilers
+# recognise .S files, in particular "cc" on HP-UX 10 and 11 doesn't (and
+# will silently do nothing if given a .S).
+#
+# For .lo we need a helper script, as described below for .asm.lo.
+#
+.S.o:
+ $(CPP) $(PREPROCESS_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$< | grep -v '^#' >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.S.obj:
+ $(CPP) $(PREPROCESS_FLAGS) `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` | grep -v '^#' >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.S.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(top_srcdir)/mpn/cpp-ccas --cpp="$(CPP) $(PREPROCESS_FLAGS)" $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+
+# .asm assembler, preprocessed with m4.
+#
+# .o and .obj are non-PIC and just need m4 followed by a compile.
+#
+# .lo is a bit tricky. Libtool (as of version 1.5) has foo.lo as a little
+# text file, and .libs/foo.o and foo.o as the PIC and non-PIC objects,
+# respectively. It'd be asking for lots of trouble to try to create foo.lo
+# ourselves, so instead arrange to invoke libtool like a --mode=compile, but
+# with a special m4-ccas script which first m4 preprocesses, then compiles.
+# --tag=CC is necessary since foo.asm is otherwise unknown to libtool.
+#
+# Libtool adds -DPIC when building a shared object and the .asm files look
+# for that. But it should be noted that the other PIC flags are on occasion
+# important too, in particular FreeBSD 2.2.8 gas 1.92.3 requires -k before
+# it accepts PIC constructs like @GOT, and gcc adds that flag only under
+# -fPIC. (Later versions of gas are happy to accept PIC stuff any time.)
+#
+.asm.o:
+ $(M4) -DOPERATION_$* `test -f '$<' || echo '$(srcdir)/'`$< >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.asm.obj:
+ $(M4) -DOPERATION_$* `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.asm.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(top_srcdir)/mpn/m4-ccas --m4="$(M4)" $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
diff --git a/gmp/mpn/Makefile.am b/gmp/mpn/Makefile.am
new file mode 100644
index 0000000000..20b8a4a116
--- /dev/null
+++ b/gmp/mpn/Makefile.am
@@ -0,0 +1,59 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 1996, 1998-2002, 2005, 2011, 2013 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir) \
+ -DOPERATION_`echo $* | sed 's/_$$//'`
+
+OFILES = @mpn_objects@
+
+noinst_LTLIBRARIES = libmpn.la
+nodist_libmpn_la_SOURCES = fib_table.c mp_bases.c
+libmpn_la_LIBADD = $(OFILES)
+libmpn_la_DEPENDENCIES = $(OFILES)
+
+TARG_DIST = alpha arm arm64 cray generic ia64 lisp m68k m88k \
+ minithres mips32 mips64 pa32 pa64 power powerpc32 powerpc64 \
+ s390_32 s390_64 sh sparc32 sparc64 thumb vax x86 x86_64
+
+EXTRA_DIST = asm-defs.m4 cpp-ccas m4-ccas $(TARG_DIST)
+
+
+# These are BUILT_SOURCES at the top-level, so normally they're built before
+# recursing into this directory.
+#
+fib_table.c:
+ cd ..; $(MAKE) $(AM_MAKEFLAGS) mpn/fib_table.c
+mp_bases.c:
+ cd ..; $(MAKE) $(AM_MAKEFLAGS) mpn/mp_bases.c
+perfsqr.h:
+ cd ..; $(MAKE) $(AM_MAKEFLAGS) mpn/perfsqr.h
+
+include Makeasm.am
diff --git a/gmp/mpn/Makefile.in b/gmp/mpn/Makefile.in
new file mode 100644
index 0000000000..099abf26ab
--- /dev/null
+++ b/gmp/mpn/Makefile.in
@@ -0,0 +1,686 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 1996, 1998-2002, 2005, 2011, 2013 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+# Copyright 1996, 1998-2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+DIST_COMMON = README $(srcdir)/Makeasm.am $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+subdir = mpn
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+nodist_libmpn_la_OBJECTS = fib_table.lo mp_bases.lo
+libmpn_la_OBJECTS = $(nodist_libmpn_la_OBJECTS)
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(nodist_libmpn_la_SOURCES)
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir) \
+ -DOPERATION_`echo $* | sed 's/_$$//'`
+
+OFILES = @mpn_objects@
+noinst_LTLIBRARIES = libmpn.la
+nodist_libmpn_la_SOURCES = fib_table.c mp_bases.c
+libmpn_la_LIBADD = $(OFILES)
+libmpn_la_DEPENDENCIES = $(OFILES)
+TARG_DIST = alpha arm arm64 cray generic ia64 lisp m68k m88k \
+ minithres mips32 mips64 pa32 pa64 power powerpc32 powerpc64 \
+ s390_32 s390_64 sh sparc32 sparc64 thumb vax x86 x86_64
+
+EXTRA_DIST = asm-defs.m4 cpp-ccas m4-ccas $(TARG_DIST)
+
+# COMPILE minus CC.
+#
+COMPILE_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASMFLAGS)
+
+
+# Flags used for preprocessing (in ansi2knr rules).
+#
+PREPROCESS_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS)
+
+
+# Recent versions of automake (1.5 and up for instance) append automake
+# generated suffixes to this $(SUFFIXES) list. This is essential for us,
+# since .c must come after .s, .S and .asm. If .c is before .s, for
+# instance, then in the mpn directory "make" will see add_n.c mentioned in
+# an explicit rule (the ansi2knr stuff) and decide it must have add_n.c,
+# even if add_n.c doesn't exist but add_n.s does. See GNU make
+# documentation "(make)Implicit Rule Search", part 5c.
+#
+# On IRIX 6 native make this doesn't work properly though. Somehow .c
+# remains ahead of .s, perhaps because .c.s is a builtin rule. .asm works
+# fine though, and mpn/mips3 uses this.
+#
+SUFFIXES = .s .S .asm
+
+# can be overridden during development, eg. "make RM_TMP=: mul_1.lo"
+RM_TMP = rm -f
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .s .S .asm .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makeasm.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 mpn/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps mpn/Makefile
+.PRECIOUS: 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;
+$(srcdir)/Makeasm.am:
+
+$(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-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libmpn.la: $(libmpn_la_OBJECTS) $(libmpn_la_DEPENDENCIES) $(EXTRA_libmpn_la_DEPENDENCIES)
+ $(LINK) $(libmpn_la_OBJECTS) $(libmpn_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+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:
+
+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-generic clean-libtool clean-noinstLTLIBRARIES \
+ 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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags 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 tags uninstall uninstall-am
+
+
+# These are BUILT_SOURCES at the top-level, so normally they're built before
+# recursing into this directory.
+#
+fib_table.c:
+ cd ..; $(MAKE) $(AM_MAKEFLAGS) mpn/fib_table.c
+mp_bases.c:
+ cd ..; $(MAKE) $(AM_MAKEFLAGS) mpn/mp_bases.c
+perfsqr.h:
+ cd ..; $(MAKE) $(AM_MAKEFLAGS) mpn/perfsqr.h
+
+# .s assembler, no preprocessing.
+#
+.s.o:
+ $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+.s.obj:
+ $(CCAS) $(COMPILE_FLAGS) `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+.s.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+# .S assembler, preprocessed with cpp.
+#
+# It's necessary to run $(CPP) separately, since it seems not all compilers
+# recognise .S files, in particular "cc" on HP-UX 10 and 11 doesn't (and
+# will silently do nothing if given a .S).
+#
+# For .lo we need a helper script, as described below for .asm.lo.
+#
+.S.o:
+ $(CPP) $(PREPROCESS_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$< | grep -v '^#' >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.S.obj:
+ $(CPP) $(PREPROCESS_FLAGS) `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` | grep -v '^#' >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.S.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(top_srcdir)/mpn/cpp-ccas --cpp="$(CPP) $(PREPROCESS_FLAGS)" $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+# .asm assembler, preprocessed with m4.
+#
+# .o and .obj are non-PIC and just need m4 followed by a compile.
+#
+# .lo is a bit tricky. Libtool (as of version 1.5) has foo.lo as a little
+# text file, and .libs/foo.o and foo.o as the PIC and non-PIC objects,
+# respectively. It'd be asking for lots of trouble to try to create foo.lo
+# ourselves, so instead arrange to invoke libtool like a --mode=compile, but
+# with a special m4-ccas script which first m4 preprocesses, then compiles.
+# --tag=CC is necessary since foo.asm is otherwise unknown to libtool.
+#
+# Libtool adds -DPIC when building a shared object and the .asm files look
+# for that. But it should be noted that the other PIC flags are on occasion
+# important too, in particular FreeBSD 2.2.8 gas 1.92.3 requires -k before
+# it accepts PIC constructs like @GOT, and gcc adds that flag only under
+# -fPIC. (Later versions of gas are happy to accept PIC stuff any time.)
+#
+.asm.o:
+ $(M4) -DOPERATION_$* `test -f '$<' || echo '$(srcdir)/'`$< >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.asm.obj:
+ $(M4) -DOPERATION_$* `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.asm.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(top_srcdir)/mpn/m4-ccas --m4="$(M4)" $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+# 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/gmp/mpn/README b/gmp/mpn/README
new file mode 100644
index 0000000000..bc046be732
--- /dev/null
+++ b/gmp/mpn/README
@@ -0,0 +1,44 @@
+Copyright 1996, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+This directory contains all code for the mpn layer of GMP.
+
+Most subdirectories contain machine-dependent code, written in assembly or C.
+The `generic' subdirectory contains default code, used when there is no
+machine-dependent replacement for a particular machine.
+
+There is one subdirectory for each ISA family. Note that e.g., 32-bit SPARC
+and 64-bit SPARC are very different ISA's, and thus cannot share any code.
+
+A particular compile will only use code from one subdirectory, and the
+`generic' subdirectory. The ISA-specific subdirectories contain hierachies of
+directories for various architecture variants and implementations; the
+top-most level contains code that runs correctly on all variants.
diff --git a/gmp/mpn/alpha/README b/gmp/mpn/alpha/README
new file mode 100644
index 0000000000..09c2f04047
--- /dev/null
+++ b/gmp/mpn/alpha/README
@@ -0,0 +1,208 @@
+Copyright 1996, 1997, 1999-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+This directory contains mpn functions optimized for DEC Alpha processors.
+
+ALPHA ASSEMBLY RULES AND REGULATIONS
+
+The `.prologue N' pseudo op marks the end of instruction that needs special
+handling by unwinding. It also says whether $27 is really needed for computing
+the gp. The `.mask M' pseudo op says which registers are saved on the stack,
+and at what offset in the frame.
+
+Cray T3 code is very very different...
+
+"$6" / "$f6" etc is the usual syntax for registers, but on Unicos instead "r6"
+/ "f6" is required. We use the "r6" / "f6" forms, and have m4 defines expand
+them to "$6" or "$f6" where necessary.
+
+"0x" introduces a hex constant in gas and DEC as, but on Unicos "^X" is
+required. The X() macro accommodates this difference.
+
+"cvttqc" is required by DEC as, "cvttq/c" is required by Unicos, and gas will
+accept either. We use cvttqc and have an m4 define expand to cvttq/c where
+necessary.
+
+"not" as an alias for "ornot r31, ..." is available in gas and DEC as, but not
+the Unicos assembler. The full "ornot" must be used.
+
+"unop" is not available in Unicos. We make an m4 define to the usual "ldq_u
+r31,0(r30)", and in fact use that define on all systems since it comes out the
+same.
+
+"!literal!123" etc explicit relocations as per Tru64 4.0 are apparently not
+available in older alpha assemblers (including gas prior to 2.12), according to
+the GCC manual, so the assembler macro forms must be used (eg. ldgp).
+
+
+
+RELEVANT OPTIMIZATION ISSUES
+
+EV4
+
+1. This chip has very limited store bandwidth. The on-chip L1 cache is write-
+ through, and a cache line is transferred from the store buffer to the off-
+ chip L2 in as much 15 cycles on most systems. This delay hurts mpn_add_n,
+ mpn_sub_n, mpn_lshift, and mpn_rshift.
+
+2. Pairing is possible between memory instructions and integer arithmetic
+ instructions.
+
+3. mulq and umulh are documented to have a latency of 23 cycles, but 2 of these
+ cycles are pipelined. Thus, multiply instructions can be issued at a rate
+ of one each 21st cycle.
+
+EV5
+
+1. The memory bandwidth of this chip is good, both for loads and stores. The
+ L1 cache can handle two loads or one store per cycle, but two cycles after a
+ store, no ld can issue.
+
+2. mulq has a latency of 12 cycles and an issue rate of 1 each 8th cycle.
+ umulh has a latency of 14 cycles and an issue rate of 1 each 10th cycle.
+ (Note that published documentation gets these numbers slightly wrong.)
+
+3. mpn_add_n. With 4-fold unrolling, we need 37 instructions, whereof 12
+ are memory operations. This will take at least
+ ceil(37/2) [dual issue] + 1 [taken branch] = 19 cycles
+ We have 12 memory cycles, plus 4 after-store conflict cycles, or 16 data
+ cache cycles, which should be completely hidden in the 19 issue cycles.
+ The computation is inherently serial, with these dependencies:
+
+ ldq ldq
+ \ /\
+ (or) addq |
+ |\ / \ |
+ | addq cmpult
+ \ | |
+ cmpult |
+ \ /
+ or
+
+ I.e., 3 operations are needed between carry-in and carry-out, making 12
+ cycles the absolute minimum for the 4 limbs. We could replace the `or' with
+ a cmoveq/cmovne, which could issue one cycle earlier that the `or', but that
+ might waste a cycle on EV4. The total depth remain unaffected, since cmov
+ has a latency of 2 cycles.
+
+ addq
+ / \
+ addq cmpult
+ | \
+ cmpult -> cmovne
+
+ Montgomery has a slightly different way of computing carry that requires one
+ less instruction, but has depth 4 (instead of the current 3). Since the code
+ is currently instruction issue bound, Montgomery's idea should save us 1/2
+ cycle per limb, or bring us down to a total of 17 cycles or 4.25 cycles/limb.
+ Unfortunately, this method will not be good for the EV6.
+
+4. addmul_1 and friends: We previously had a scheme for splitting the single-
+ limb operand in 21-bits chunks and the multi-limb operand in 32-bit chunks,
+ and then use FP operations for every 2nd multiply, and integer operations
+ for every 2nd multiply.
+
+ But it seems much better to split the single-limb operand in 16-bit chunks,
+ since we save many integer shifts and adds that way. See powerpc64/README
+ for some more details.
+
+EV6
+
+Here we have a really parallel pipeline, capable of issuing up to 4 integer
+instructions per cycle. In actual practice, it is never possible to sustain
+more than 3.5 integer insns/cycle due to rename register shortage. One integer
+multiply instruction can issue each cycle. To get optimal speed, we need to
+pretend we are vectorizing the code, i.e., minimize the depth of recurrences.
+
+There are two dependencies to watch out for. 1) Address arithmetic
+dependencies, and 2) carry propagation dependencies.
+
+We can avoid serializing due to address arithmetic by unrolling loops, so that
+addresses don't depend heavily on an index variable. Avoiding serializing
+because of carry propagation is trickier; the ultimate performance of the code
+will be determined of the number of latency cycles it takes from accepting
+carry-in to a vector point until we can generate carry-out.
+
+Most integer instructions can execute in either the L0, U0, L1, or U1
+pipelines. Shifts only execute in U0 and U1, and multiply only in U1.
+
+CMOV instructions split into two internal instructions, CMOV1 and CMOV2. CMOV
+split the mapping process (see pg 2-26 in cmpwrgd.pdf), suggesting the CMOV
+should always be placed as the last instruction of an aligned 4 instruction
+block, or perhaps simply avoided.
+
+Perhaps the most important issue is the latency between the L0/U0 and L1/U1
+clusters; a result obtained on either cluster has an extra cycle of latency for
+consumers in the opposite cluster. Because of the dynamic nature of the
+implementation, it is hard to predict where an instruction will execute.
+
+
+
+REFERENCES
+
+"Alpha Architecture Handbook", version 4, Compaq, October 1998, order number
+EC-QD2KC-TE.
+
+"Alpha 21164 Microprocessor Hardware Reference Manual", Compaq, December 1998,
+order number EC-QP99C-TE.
+
+"Alpha 21264/EV67 Microprocessor Hardware Reference Manual", revision 1.4,
+Compaq, September 2000, order number DS-0028B-TE.
+
+"Compiler Writer's Guide for the Alpha 21264", Compaq, June 1999, order number
+EC-RJ66A-TE.
+
+All of the above are available online from
+
+ http://ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html
+ ftp://ftp.compaq.com/pub/products/alphaCPUdocs
+
+"Tru64 Unix Assembly Language Programmer's Guide", Compaq, March 1996, part
+number AA-PS31D-TE.
+
+"Digital UNIX Calling Standard for Alpha Systems", Digital Equipment Corp,
+March 1996, part number AA-PY8AC-TE.
+
+The above are available online,
+
+ http://h30097.www3.hp.com/docs/pub_page/V40F_DOCS.HTM
+
+(Dunno what h30097 means in this URL, but if it moves try searching for "tru64
+online documentation" from the main www.hp.com page.)
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 79
+End:
diff --git a/gmp/mpn/alpha/add_n.asm b/gmp/mpn/alpha/add_n.asm
new file mode 100644
index 0000000000..bc572a57a9
--- /dev/null
+++ b/gmp/mpn/alpha/add_n.asm
@@ -0,0 +1,164 @@
+dnl Alpha mpn_add_n -- Add two limb vectors of the same length > 0 and
+dnl store sum in a third limb vector.
+
+dnl Copyright 1995, 1999, 2000, 2005, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 4.75
+C EV6: 3
+
+dnl INPUT PARAMETERS
+dnl res_ptr r16
+dnl s1_ptr r17
+dnl s2_ptr r18
+dnl size r19
+
+ASM_START()
+PROLOGUE(mpn_add_nc)
+ bis r20,r31,r25
+ br L(com)
+EPILOGUE()
+PROLOGUE(mpn_add_n)
+ bis r31,r31,r25 C clear cy
+L(com): subq r19,4,r19 C decr loop cnt
+ blt r19,$Lend2 C if less than 4 limbs, goto 2nd loop
+C Start software pipeline for 1st loop
+ ldq r0,0(r18)
+ ldq r4,0(r17)
+ ldq r1,8(r18)
+ ldq r5,8(r17)
+ addq r17,32,r17 C update s1_ptr
+ addq r0,r4,r28 C 1st main add
+ ldq r2,16(r18)
+ addq r25,r28,r20 C 1st carry add
+ ldq r3,24(r18)
+ cmpult r28,r4,r8 C compute cy from last add
+ ldq r6,-16(r17)
+ cmpult r20,r28,r25 C compute cy from last add
+ ldq r7,-8(r17)
+ bis r8,r25,r25 C combine cy from the two adds
+ subq r19,4,r19 C decr loop cnt
+ addq r1,r5,r28 C 2nd main add
+ addq r18,32,r18 C update s2_ptr
+ addq r28,r25,r21 C 2nd carry add
+ cmpult r28,r5,r8 C compute cy from last add
+ blt r19,$Lend1 C if less than 4 limbs remain, jump
+C 1st loop handles groups of 4 limbs in a software pipeline
+ ALIGN(16)
+$Loop: cmpult r21,r28,r25 C compute cy from last add
+ ldq r0,0(r18)
+ bis r8,r25,r25 C combine cy from the two adds
+ ldq r1,8(r18)
+ addq r2,r6,r28 C 3rd main add
+ ldq r4,0(r17)
+ addq r28,r25,r22 C 3rd carry add
+ ldq r5,8(r17)
+ cmpult r28,r6,r8 C compute cy from last add
+ cmpult r22,r28,r25 C compute cy from last add
+ stq r20,0(r16)
+ bis r8,r25,r25 C combine cy from the two adds
+ stq r21,8(r16)
+ addq r3,r7,r28 C 4th main add
+ addq r28,r25,r23 C 4th carry add
+ cmpult r28,r7,r8 C compute cy from last add
+ cmpult r23,r28,r25 C compute cy from last add
+ addq r17,32,r17 C update s1_ptr
+ bis r8,r25,r25 C combine cy from the two adds
+ addq r16,32,r16 C update res_ptr
+ addq r0,r4,r28 C 1st main add
+ ldq r2,16(r18)
+ addq r25,r28,r20 C 1st carry add
+ ldq r3,24(r18)
+ cmpult r28,r4,r8 C compute cy from last add
+ ldq r6,-16(r17)
+ cmpult r20,r28,r25 C compute cy from last add
+ ldq r7,-8(r17)
+ bis r8,r25,r25 C combine cy from the two adds
+ subq r19,4,r19 C decr loop cnt
+ stq r22,-16(r16)
+ addq r1,r5,r28 C 2nd main add
+ stq r23,-8(r16)
+ addq r25,r28,r21 C 2nd carry add
+ addq r18,32,r18 C update s2_ptr
+ cmpult r28,r5,r8 C compute cy from last add
+ bge r19,$Loop
+C Finish software pipeline for 1st loop
+$Lend1: cmpult r21,r28,r25 C compute cy from last add
+ bis r8,r25,r25 C combine cy from the two adds
+ addq r2,r6,r28 C 3rd main add
+ addq r28,r25,r22 C 3rd carry add
+ cmpult r28,r6,r8 C compute cy from last add
+ cmpult r22,r28,r25 C compute cy from last add
+ stq r20,0(r16)
+ bis r8,r25,r25 C combine cy from the two adds
+ stq r21,8(r16)
+ addq r3,r7,r28 C 4th main add
+ addq r28,r25,r23 C 4th carry add
+ cmpult r28,r7,r8 C compute cy from last add
+ cmpult r23,r28,r25 C compute cy from last add
+ bis r8,r25,r25 C combine cy from the two adds
+ addq r16,32,r16 C update res_ptr
+ stq r22,-16(r16)
+ stq r23,-8(r16)
+$Lend2: addq r19,4,r19 C restore loop cnt
+ beq r19,$Lret
+C Start software pipeline for 2nd loop
+ ldq r0,0(r18)
+ ldq r4,0(r17)
+ subq r19,1,r19
+ beq r19,$Lend0
+C 2nd loop handles remaining 1-3 limbs
+ ALIGN(16)
+$Loop0: addq r0,r4,r28 C main add
+ ldq r0,8(r18)
+ cmpult r28,r4,r8 C compute cy from last add
+ ldq r4,8(r17)
+ addq r28,r25,r20 C carry add
+ addq r18,8,r18
+ addq r17,8,r17
+ stq r20,0(r16)
+ cmpult r20,r28,r25 C compute cy from last add
+ subq r19,1,r19 C decr loop cnt
+ bis r8,r25,r25 C combine cy from the two adds
+ addq r16,8,r16
+ bne r19,$Loop0
+$Lend0: addq r0,r4,r28 C main add
+ addq r28,r25,r20 C carry add
+ cmpult r28,r4,r8 C compute cy from last add
+ cmpult r20,r28,r25 C compute cy from last add
+ stq r20,0(r16)
+ bis r8,r25,r25 C combine cy from the two adds
+
+$Lret: bis r25,r31,r0 C return cy
+ ret r31,(r26),1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/addmul_1.asm b/gmp/mpn/alpha/addmul_1.asm
new file mode 100644
index 0000000000..c4e6834b61
--- /dev/null
+++ b/gmp/mpn/alpha/addmul_1.asm
@@ -0,0 +1,99 @@
+dnl Alpha mpn_addmul_1 -- Multiply a limb vector with a limb and add the
+dnl result to a second limb vector.
+
+dnl Copyright 1992, 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 42
+C EV5: 18
+C EV6: 7
+
+C INPUT PARAMETERS
+C rp r16
+C up r17
+C n r18
+C vl r19
+
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ ldq r2,0(r17) C r2 = s1_limb
+ addq r17,8,r17 C s1_ptr++
+ subq r18,1,r18 C size--
+ mulq r2,r19,r3 C r3 = prod_low
+ ldq r5,0(r16) C r5 = *res_ptr
+ umulh r2,r19,r0 C r0 = prod_high
+ beq r18,$Lend1 C jump if size was == 1
+ ldq r2,0(r17) C r2 = s1_limb
+ addq r17,8,r17 C s1_ptr++
+ subq r18,1,r18 C size--
+ addq r5,r3,r3
+ cmpult r3,r5,r4
+ stq r3,0(r16)
+ addq r16,8,r16 C res_ptr++
+ beq r18,$Lend2 C jump if size was == 2
+
+ ALIGN(8)
+$Loop: mulq r2,r19,r3 C r3 = prod_low
+ ldq r5,0(r16) C r5 = *res_ptr
+ addq r4,r0,r0 C cy_limb = cy_limb + 'cy'
+ subq r18,1,r18 C size--
+ umulh r2,r19,r4 C r4 = cy_limb
+ ldq r2,0(r17) C r2 = s1_limb
+ addq r17,8,r17 C s1_ptr++
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ addq r5,r3,r3
+ cmpult r3,r5,r5
+ stq r3,0(r16)
+ addq r16,8,r16 C res_ptr++
+ addq r5,r0,r0 C combine carries
+ bne r18,$Loop
+
+$Lend2: mulq r2,r19,r3 C r3 = prod_low
+ ldq r5,0(r16) C r5 = *res_ptr
+ addq r4,r0,r0 C cy_limb = cy_limb + 'cy'
+ umulh r2,r19,r4 C r4 = cy_limb
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ addq r5,r3,r3
+ cmpult r3,r5,r5
+ stq r3,0(r16)
+ addq r5,r0,r0 C combine carries
+ addq r4,r0,r0 C cy_limb = prod_high + cy
+ ret r31,(r26),1
+$Lend1: addq r5,r3,r3
+ cmpult r3,r5,r5
+ stq r3,0(r16)
+ addq r0,r5,r0
+ ret r31,(r26),1
+EPILOGUE(mpn_addmul_1)
+ASM_END()
diff --git a/gmp/mpn/alpha/alpha-defs.m4 b/gmp/mpn/alpha/alpha-defs.m4
new file mode 100644
index 0000000000..af34c9294c
--- /dev/null
+++ b/gmp/mpn/alpha/alpha-defs.m4
@@ -0,0 +1,107 @@
+divert(-1)
+
+dnl m4 macros for Alpha assembler.
+
+dnl Copyright 2003, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Usage: ASSERT([reg] [,code])
+dnl
+dnl Require that the given reg is non-zero after executing the test code.
+dnl For example,
+dnl
+dnl ASSERT(r8,
+dnl ` cmpult r16, r17, r8')
+dnl
+dnl If the register argument is empty then nothing is tested, the code is
+dnl just executed. This can be used for setups required by later ASSERTs.
+dnl If the code argument is omitted then the register is just tested, with
+dnl no special setup code.
+
+define(ASSERT,
+m4_assert_numargs_range(1,2)
+m4_assert_defined(`WANT_ASSERT')
+`ifelse(WANT_ASSERT,1,
+`ifelse(`$2',,,`$2')
+ifelse(`$1',,,
+` bne $1, L(ASSERTok`'ASSERT_label_counter)
+ .long 0 C halt
+L(ASSERTok`'ASSERT_label_counter):
+define(`ASSERT_label_counter',eval(ASSERT_label_counter+1))
+')
+')')
+define(`ASSERT_label_counter',1)
+
+
+dnl Usage: bigend(`code')
+dnl
+dnl Emit the given code only for a big-endian system, like Unicos. This
+dnl can be used for instance for extra stuff needed by extwl.
+
+define(bigend,
+m4_assert_numargs(1)
+`ifdef(`HAVE_LIMB_BIG_ENDIAN',`$1',
+`ifdef(`HAVE_LIMB_LITTLE_ENDIAN',`',
+`m4_error(`Cannot assemble, unknown limb endianness')')')')
+
+
+dnl Usage: bwx_available_p
+dnl
+dnl Evaluate to 1 if the BWX byte memory instructions are available, or to
+dnl 0 if not.
+dnl
+dnl Listing the chips which do have BWX means anything we haven't looked at
+dnl will use safe non-BWX code. The only targets without BWX currently are
+dnl plain alpha (ie. ev4) and alphaev5.
+
+define(bwx_available_p,
+m4_assert_numargs(-1)
+`m4_ifdef_anyof_p(
+ `HAVE_HOST_CPU_alphaev56',
+ `HAVE_HOST_CPU_alphapca56',
+ `HAVE_HOST_CPU_alphapca57',
+ `HAVE_HOST_CPU_alphaev6',
+ `HAVE_HOST_CPU_alphaev67',
+ `HAVE_HOST_CPU_alphaev68',
+ `HAVE_HOST_CPU_alphaev69',
+ `HAVE_HOST_CPU_alphaev7',
+ `HAVE_HOST_CPU_alphaev79')')
+
+
+dnl Usage: unop
+dnl
+dnl The Cray Unicos assembler lacks unop, so give the equivalent ldq_u
+dnl explicitly.
+
+define(unop,
+m4_assert_numargs(-1)
+`ldq_u r31, 0(r30)')
+
+
+divert
diff --git a/gmp/mpn/alpha/aorslsh1_n.asm b/gmp/mpn/alpha/aorslsh1_n.asm
new file mode 100644
index 0000000000..9525e669db
--- /dev/null
+++ b/gmp/mpn/alpha/aorslsh1_n.asm
@@ -0,0 +1,164 @@
+dnl Alpha mpn_addlsh1_n/mpn_sublsh1_n -- rp[] = up[] +- (vp[] << 1).
+
+dnl Copyright 2003, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 6.25
+C EV6: 4.5
+
+define(`rp',`r16')
+define(`up',`r17')
+define(`vp',`r18')
+define(`n', `r19')
+
+define(`u0', `r8')
+define(`u1', `r1')
+define(`v0', `r4')
+define(`v1', `r5')
+
+define(`cy0', `r0')
+define(`cy1', `r20')
+define(`cy', `r22')
+define(`rr', `r24')
+define(`ps', `r25')
+define(`sl', `r28')
+
+ifdef(`OPERATION_addlsh1_n',`
+ define(ADDSUB, addq)
+ define(CARRY, `cmpult $1,$2,$3')
+ define(func, mpn_addlsh1_n)
+')
+ifdef(`OPERATION_sublsh1_n',`
+ define(ADDSUB, subq)
+ define(CARRY, `cmpult $2,$1,$3')
+ define(func, mpn_sublsh1_n)
+')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n)
+
+ASM_START()
+PROLOGUE(func)
+ and n, 2, cy0
+ blbs n, L(bx1)
+L(bx0): ldq v1, 0(vp)
+ ldq u1, 0(up)
+ nop
+ bne cy0, L(b10)
+
+L(b00): lda vp, 48(vp)
+ lda up, -16(up)
+ lda rp, -8(rp)
+ br r31, L(lo0)
+
+L(b10): lda vp, 32(vp)
+ lda rp, 8(rp)
+ lda cy0, 0(r31)
+ br r31, L(lo2)
+
+L(bx1): ldq v0, 0(vp)
+ ldq u0, 0(up)
+ lda cy1, 0(r31)
+ beq cy0, L(b01)
+
+L(b11): lda vp, 40(vp)
+ lda up, -24(up)
+ lda rp, 16(rp)
+ br r31, L(lo3)
+
+L(b01): lda n, -4(n)
+ ble n, L(end)
+ lda vp, 24(vp)
+ lda up, -8(up)
+
+ ALIGN(16)
+L(top): addq v0, v0, sl C left shift vlimb
+ ldq v1, -16(vp)
+ ADDSUB u0, sl, ps C ulimb + (vlimb << 1)
+ cmplt v0, r31, cy0 C carry out #1
+ ldq u1, 16(up)
+ ADDSUB ps, cy1, rr C consume carry from previous operation
+ CARRY( ps, u0, cy) C carry out #2
+ stq rr, 0(rp)
+ addq cy, cy0, cy0 C combine carry out #1 and #2
+ CARRY( rr, ps, cy) C carry out #3
+ addq cy, cy0, cy0 C final carry out
+ lda vp, 32(vp) C bookkeeping
+L(lo0): addq v1, v1, sl
+ ldq v0, -40(vp)
+ ADDSUB u1, sl, ps
+ cmplt v1, r31, cy1
+ ldq u0, 24(up)
+ ADDSUB ps, cy0, rr
+ CARRY( ps, u1, cy)
+ stq rr, 8(rp)
+ addq cy, cy1, cy1
+ CARRY( rr, ps, cy)
+ addq cy, cy1, cy1
+ lda rp, 32(rp) C bookkeeping
+L(lo3): addq v0, v0, sl
+ ldq v1, -32(vp)
+ ADDSUB u0, sl, ps
+ cmplt v0, r31, cy0
+ ldq u1, 32(up)
+ ADDSUB ps, cy1, rr
+ CARRY( ps, u0, cy)
+ stq rr, -16(rp)
+ addq cy, cy0, cy0
+ CARRY( rr, ps, cy)
+ addq cy, cy0, cy0
+ lda up, 32(up) C bookkeeping
+L(lo2): addq v1, v1, sl
+ ldq v0, -24(vp)
+ ADDSUB u1, sl, ps
+ cmplt v1, r31, cy1
+ ldq u0, 8(up)
+ ADDSUB ps, cy0, rr
+ CARRY( ps, u1, cy)
+ stq rr, -8(rp)
+ addq cy, cy1, cy1
+ CARRY( rr, ps, cy)
+ addq cy, cy1, cy1
+ lda n, -4(n) C bookkeeping
+ bgt n, L(top)
+
+L(end): addq v0, v0, sl
+ ADDSUB u0, sl, ps
+ ADDSUB ps, cy1, rr
+ cmplt v0, r31, cy0
+ CARRY( ps, u0, cy)
+ stq rr, 0(rp)
+ addq cy, cy0, cy0
+ CARRY( rr, ps, cy)
+ addq cy, cy0, r0
+ ret r31,(r26),1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/aorslsh2_n.asm b/gmp/mpn/alpha/aorslsh2_n.asm
new file mode 100644
index 0000000000..bdee1d6d02
--- /dev/null
+++ b/gmp/mpn/alpha/aorslsh2_n.asm
@@ -0,0 +1,167 @@
+dnl Alpha mpn_addlsh2_n/mpn_sublsh2_n -- rp[] = up[] +- (vp[] << 2).
+
+dnl Copyright 2003, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 6
+C EV6: 3.75
+
+C TODO
+C * Tune to reach 3.5 c/l on ev6 and 5.75 c/l on ev5.
+
+define(`rp',`r16')
+define(`up',`r17')
+define(`vp',`r18')
+define(`n', `r19')
+
+define(`u0', `r8')
+define(`u1', `r1')
+define(`v0', `r4')
+define(`v1', `r5')
+
+define(`cy0', `r0')
+define(`cy1', `r20')
+define(`cy', `r22')
+define(`rr', `r24')
+define(`ps', `r25')
+define(`sl', `r28')
+
+ifdef(`OPERATION_addlsh2_n',`
+ define(ADDSUB, addq)
+ define(CARRY, `cmpult $1,$2,$3')
+ define(func, mpn_addlsh2_n)
+')
+ifdef(`OPERATION_sublsh2_n',`
+ define(ADDSUB, subq)
+ define(CARRY, `cmpult $2,$1,$3')
+ define(func, mpn_sublsh2_n)
+')
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_sublsh2_n)
+
+ASM_START()
+PROLOGUE(func)
+ and n, 2, cy0
+ blbs n, L(bx1)
+L(bx0): ldq v1, 0(vp)
+ ldq u1, 0(up)
+ bis r31, r31, r2
+ bne cy0, L(b10)
+
+L(b00): lda vp, 48(vp)
+ lda up, -16(up)
+ lda rp, -8(rp)
+ s4addq v1, r31, sl
+ br r31, L(lo0)
+
+L(b10): lda vp, 32(vp)
+ lda rp, 8(rp)
+ lda cy0, 0(r31)
+ br r31, L(lo2)
+
+L(bx1): ldq v0, 0(vp)
+ ldq u0, 0(up)
+ lda cy1, 0(r31)
+ bis r31, r31, r3
+ nop
+ beq cy0, L(b01)
+
+L(b11): lda vp, 40(vp)
+ lda up, -24(up)
+ lda rp, 16(rp)
+ br r31, L(lo3)
+
+L(b01): lda n, -4(n)
+ ble n, L(end)
+ lda vp, 24(vp)
+ lda up, -8(up)
+
+ ALIGN(16)
+L(top): s4addq v0, r3, sl C combined vlimb
+ ldq v1, -16(vp)
+ ADDSUB u0, sl, ps C ulimb + (vlimb << 1)
+ ldq u1, 16(up)
+ srl v0, 62, r2 C high v bits
+ ADDSUB ps, cy1, rr C consume carry from previous operation
+ CARRY( ps, u0, cy0) C carry out #2
+ stq rr, 0(rp)
+ CARRY( rr, ps, cy) C carry out #3
+ lda vp, 32(vp) C bookkeeping
+ addq cy, cy0, cy0 C final carry out
+ s4addq v1, r2, sl
+L(lo0): ldq v0, -40(vp)
+ ADDSUB u1, sl, ps
+ ldq u0, 24(up)
+ srl v1, 62, r3
+ ADDSUB ps, cy0, rr
+ CARRY( ps, u1, cy1)
+ stq rr, 8(rp)
+ CARRY( rr, ps, cy)
+ lda rp, 32(rp) C bookkeeping
+ addq cy, cy1, cy1
+L(lo3): s4addq v0, r3, sl
+ ldq v1, -32(vp)
+ ADDSUB u0, sl, ps
+ ldq u1, 32(up)
+ srl v0, 62, r2
+ ADDSUB ps, cy1, rr
+ CARRY( ps, u0, cy0)
+ stq rr, -16(rp)
+ CARRY( rr, ps, cy)
+ lda up, 32(up) C bookkeeping
+ addq cy, cy0, cy0
+L(lo2): s4addq v1, r2, sl
+ ldq v0, -24(vp)
+ ADDSUB u1, sl, ps
+ ldq u0, 8(up)
+ srl v1, 62, r3
+ ADDSUB ps, cy0, rr
+ CARRY( ps, u1, cy1)
+ stq rr, -8(rp)
+ CARRY( rr, ps, cy)
+ lda n, -4(n) C bookkeeping
+ addq cy, cy1, cy1
+ bgt n, L(top)
+
+L(end): s4addq v0, r3, sl
+ ADDSUB u0, sl, ps
+ srl v0, 62, r2
+ ADDSUB ps, cy1, rr
+ CARRY( ps, u0, cy0)
+ stq rr, 0(rp)
+ CARRY( rr, ps, cy)
+ addq cy, cy0, cy0
+ addq cy0, r2, r0
+
+ ret r31,(r26),1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/bdiv_dbm1c.asm b/gmp/mpn/alpha/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..472966ca98
--- /dev/null
+++ b/gmp/mpn/alpha/bdiv_dbm1c.asm
@@ -0,0 +1,282 @@
+dnl Alpha mpn_bdiv_dbm1c.
+
+dnl Copyright 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 42
+C EV5: 18
+C EV6: 3
+
+C TODO
+C * Try less unrolling, 2-way should give the same performance.
+C * Optimize feed-in and wind-down code, for speed, and perhaps further for
+C code size.
+C * This runs optimally given the algorithm, r8 is on a 3 operation recurrency
+C path. We have not tried very hard to find a better algorithm. Perhaps
+C it would be a good task for the GNU superoptimizer.
+
+C INPUT PARAMETERS
+define(`rp', `r16')
+define(`up', `r17')
+define(`n', `r18')
+define(`bd', `r19')
+define(`cy', `r19')
+
+
+ASM_START()
+PROLOGUE(mpn_bdiv_dbm1c)
+ mov r20, r8
+
+ ldq r24, 0(r17)
+ and r18, 3, r28
+ lda r18, -4(r18)
+ beq r28, L(b0)
+ cmpeq r28, 1, r21
+ bne r21, L(b1)
+ cmpeq r28, 2, r21
+ bne r21, L(b2)
+
+
+L(b3): ldq r2, 8(r17)
+ ldq r3, 16(r17)
+ bgt r18, L(gt3)
+
+ mulq r24, r19, r5 C U1
+ umulh r24, r19, r21 C U1
+ mulq r2, r19, r6 C U1
+ umulh r2, r19, r22 C U1
+ mulq r3, r19, r7 C U1
+ umulh r3, r19, r23 C U1
+ lda r16, -32(r16)
+ br L(cj3)
+
+L(gt3): ldq r0, 24(r17)
+ mulq r24, r19, r5 C U1
+ umulh r24, r19, r21 C U1
+ ldq r1, 32(r17)
+ mulq r2, r19, r6 C U1
+ umulh r2, r19, r22 C U1
+ ldq r2, 40(r17)
+ mulq r3, r19, r7 C U1
+ umulh r3, r19, r23 C U1
+ ldq r3, 48(r17)
+ lda r18, -4(r18)
+ lda r17, 56(r17)
+ mulq r0, r19, r4 C U1
+ bgt r18, L(L3)
+
+ br L(cj7)
+
+
+L(b2): ldq r3, 8(r17)
+ bgt r18, L(gt2)
+
+ mulq r24, r19, r6 C U1
+ umulh r24, r19, r22 C U1
+ mulq r3, r19, r7 C U1
+ umulh r3, r19, r23 C U1
+ lda r16, -40(r16)
+ br L(cj2)
+
+L(gt2): ldq r0, 16(r17)
+ ldq r1, 24(r17)
+ mulq r24, r19, r6 C U1
+ umulh r24, r19, r22 C U1
+ ldq r2, 32(r17)
+ mulq r3, r19, r7 C U1
+ umulh r3, r19, r23 C U1
+ ldq r3, 40(r17)
+ lda r18, -4(r18)
+ lda r17, 48(r17)
+ mulq r0, r19, r4 C U1
+ umulh r0, r19, r20 C U1
+ lda r16, -8(r16)
+ bgt r18, L(gt6)
+
+ mulq r1, r19, r5 C U1
+ br L(cj6)
+
+L(gt6): ldq r0, 0(r17)
+ mulq r1, r19, r5 C U1
+ br L(L2)
+
+
+L(b1): bgt r18, L(gt1)
+
+ mulq r24, r19, r7 C U1
+ umulh r24, r19, r23 C U1
+ lda r16, -48(r16)
+ br L(cj1)
+
+L(gt1): ldq r0, 8(r17)
+ ldq r1, 16(r17)
+ ldq r2, 24(r17)
+ mulq r24, r19, r7 C U1
+ umulh r24, r19, r23 C U1
+ ldq r3, 32(r17)
+ lda r18, -4(r18)
+ lda r17, 40(r17)
+ mulq r0, r19, r4 C U1
+ umulh r0, r19, r20 C U1
+ lda r16, -16(r16)
+ bgt r18, L(gt5)
+
+ mulq r1, r19, r5 C U1
+ umulh r1, r19, r21 C U1
+ mulq r2, r19, r6 C U1
+ br L(cj5)
+
+L(gt5): ldq r0, 0(r17)
+ mulq r1, r19, r5 C U1
+ umulh r1, r19, r21 C U1
+ ldq r1, 8(r17)
+ mulq r2, r19, r6 C U1
+ br L(L1)
+
+
+L(b0): ldq r1, 8(r17)
+ ldq r2, 16(r17)
+ ldq r3, 24(r17)
+ lda r17, 32(r17)
+ lda r16, -24(r16)
+ mulq r24, r19, r4 C U1
+ umulh r24, r19, r20 C U1
+ bgt r18, L(gt4)
+
+ mulq r1, r19, r5 C U1
+ umulh r1, r19, r21 C U1
+ mulq r2, r19, r6 C U1
+ umulh r2, r19, r22 C U1
+ mulq r3, r19, r7 C U1
+ br L(cj4)
+
+L(gt4): ldq r0, 0(r17)
+ mulq r1, r19, r5 C U1
+ umulh r1, r19, r21 C U1
+ ldq r1, 8(r17)
+ mulq r2, r19, r6 C U1
+ umulh r2, r19, r22 C U1
+ ldq r2, 16(r17)
+ mulq r3, r19, r7 C U1
+ br L(L0)
+
+C *** MAIN LOOP START ***
+ ALIGN(16)
+L(top): mulq r0, r19, r4 C U1
+ subq r8, r28, r8
+L(L3): umulh r0, r19, r20 C U1
+ cmpult r8, r5, r28
+ ldq r0, 0(r17)
+ subq r8, r5, r8
+ addq r21, r28, r28
+ stq r8, 0(r16)
+
+ mulq r1, r19, r5 C U1
+ subq r8, r28, r8
+L(L2): umulh r1, r19, r21 C U1
+ cmpult r8, r6, r28
+ ldq r1, 8(r17)
+ subq r8, r6, r8
+ addq r22, r28, r28
+ stq r8, 8(r16)
+
+ mulq r2, r19, r6 C U1
+ subq r8, r28, r8
+L(L1): umulh r2, r19, r22 C U1
+ cmpult r8, r7, r28
+ ldq r2, 16(r17)
+ subq r8, r7, r8
+ addq r23, r28, r28
+ stq r8, 16(r16)
+
+ mulq r3, r19, r7 C U1
+ subq r8, r28, r8
+L(L0): umulh r3, r19, r23 C U1
+ cmpult r8, r4, r28
+ ldq r3, 24(r17)
+ subq r8, r4, r8
+ addq r20, r28, r28
+ stq r8, 24(r16)
+
+ lda r18, -4(r18)
+ lda r17, 32(r17)
+ lda r16, 32(r16)
+ bgt r18, L(top)
+C *** MAIN LOOP END ***
+
+ mulq r0, r19, r4 C U1
+ subq r8, r28, r8
+L(cj7): umulh r0, r19, r20 C U1
+ cmpult r8, r5, r28
+ subq r8, r5, r8
+ addq r21, r28, r28
+ stq r8, 0(r16)
+ mulq r1, r19, r5 C U1
+ subq r8, r28, r8
+L(cj6): umulh r1, r19, r21 C U1
+ cmpult r8, r6, r28
+ subq r8, r6, r8
+ addq r22, r28, r28
+ stq r8, 8(r16)
+ mulq r2, r19, r6 C U1
+ subq r8, r28, r8
+L(cj5): umulh r2, r19, r22 C U1
+ cmpult r8, r7, r28
+ subq r8, r7, r8
+ addq r23, r28, r28
+ stq r8, 16(r16)
+ mulq r3, r19, r7 C U1
+ subq r8, r28, r8
+L(cj4): umulh r3, r19, r23 C U1
+ cmpult r8, r4, r28
+ subq r8, r4, r8
+ addq r20, r28, r28
+ stq r8, 24(r16)
+ subq r8, r28, r8
+L(cj3): cmpult r8, r5, r28
+ subq r8, r5, r8
+ addq r21, r28, r28
+ stq r8, 32(r16)
+ subq r8, r28, r8
+L(cj2): cmpult r8, r6, r28
+ subq r8, r6, r8
+ addq r22, r28, r28
+ stq r8, 40(r16)
+ subq r8, r28, r8
+L(cj1): cmpult r8, r7, r28
+ subq r8, r7, r8
+ addq r23, r28, r28
+ stq r8, 48(r16)
+ subq r8, r28, r0
+ ret r31, (r26), 1
+
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/cntlz.asm b/gmp/mpn/alpha/cntlz.asm
new file mode 100644
index 0000000000..25af19b131
--- /dev/null
+++ b/gmp/mpn/alpha/cntlz.asm
@@ -0,0 +1,55 @@
+dnl Alpha auxiliary for longlong.h's count_leading_zeros
+
+dnl Copyright 1997, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+ASM_START()
+EXTERN(__clz_tab)
+PROLOGUE(mpn_count_leading_zeros,gp)
+ cmpbge r31, r16, r1
+ LEA(r3,__clz_tab)
+ sra r1, 1, r1
+ xor r1, 127, r1
+ srl r16, 1, r16
+ addq r1, r3, r1
+ ldq_u r0, 0(r1)
+ lda r2, 64
+ extbl r0, r1, r0
+ s8subl r0, 8, r0
+ srl r16, r0, r16
+ addq r16, r3, r16
+ ldq_u r1, 0(r16)
+ extbl r1, r16, r1
+ subq r2, r1, r2
+ subq r2, r0, r0
+ ret r31, (r26),1
+EPILOGUE(mpn_count_leading_zeros)
+ASM_END()
diff --git a/gmp/mpn/alpha/com.asm b/gmp/mpn/alpha/com.asm
new file mode 100644
index 0000000000..f084ab5e96
--- /dev/null
+++ b/gmp/mpn/alpha/com.asm
@@ -0,0 +1,176 @@
+dnl Alpha mpn_com -- mpn one's complement.
+
+dnl Copyright 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C EV4: 4.75
+C EV5: 2.0
+C EV6: 1.5
+
+
+C mp_limb_t mpn_com (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C For ev5 the main loop is 7 cycles plus 1 taken branch bubble, for a total
+C 2.0 c/l. In general, a pattern like this unrolled to N limbs per loop
+C will be 1.5+2/N c/l.
+C
+C 2 cycles of loop control are unavoidable, for pointer updates and the
+C taken branch bubble, but also since ldq cannot issue two cycles after stq
+C (and with a run of stqs that means neither of two cycles at the end of the
+C loop.
+C
+C The fbeq is forced into the second cycle of the loop using unops, since
+C the first time through it must wait for the cvtqt result. Once that
+C result is ready (a 1 cycle stall) then both the branch and following loads
+C can issue together.
+C
+C The main loop handles an odd count of limbs, being two limbs loaded before
+C each size test, plus one pipelined around from the previous iteration (or
+C setup in the entry sequence).
+C
+C An even number of limbs is handled by an explicit dst[0]=~src[0] in the
+C entry sequence, and an increment of the pointers. For an odd size there's
+C no increment and the first store in the loop (r24) is a repeat of dst[0].
+C
+C Note that the load for r24 after the possible pointer increment is done
+C before the explicit store to dst[0], in case src==dst.
+
+
+ASM_START()
+
+FLOAT64(L(dat), 2.0)
+
+ ALIGN(16)
+
+PROLOGUE(mpn_com,gp)
+
+ C r16 dst
+ C r17 src
+ C r18 size
+
+ lda r30, -16(r30) C temporary stack space
+ lda r7, -3(r18) C size - 3
+
+ ldq r20, 0(r17) C src[0]
+ srl r7, 1, r6 C (size-3)/2
+
+ stq r6, 8(r30) C (size-3)/2
+ and r7, 1, r5 C 1 if size even
+
+ LEA( r8, L(dat))
+ s8addq r5, r17, r17 C skip src[0] if even
+
+ ornot r31, r20, r20 C ~src[0]
+ unop
+
+ ldt f0, 8(r30) C (size-3)/2
+ ldq r24, 0(r17) C src[0 or 1]
+
+ stq r20, 0(r16) C dst[0]
+ s8addq r5, r16, r19 C skip dst[0] if even
+
+ ldt f1, 0(r8) C data 2.0
+ lda r30, 16(r30) C restore stack
+ unop
+ cvtqt f0, f0 C (size-3)/2 as float
+
+ ornot r31, r24, r24
+ blt r7, L(done_1) C if size<=2
+ unop
+ unop
+
+
+ C 16-byte alignment here
+L(top):
+ C r17 src, incrementing
+ C r19 dst, incrementing
+ C r24 dst[i] result, ready to store
+ C f0 (size-3)/2, decrementing
+ C f1 2.0
+
+ ldq r20, 8(r17) C src[i+1]
+ ldq r21, 16(r17) C src[i+2]
+ unop
+ unop
+
+ fbeq f0, L(done_2)
+ unop
+ ldq r22, 24(r17) C src[i+3]
+ ldq r23, 32(r17) C src[i+4]
+
+ stq r24, 0(r19) C dst[i]
+ ornot r31, r20, r20
+ subt f0, f1, f0 C count -= 2
+ unop
+
+ stq r20, 8(r19) C dst[i+1]
+ ornot r31, r21, r21
+ unop
+ unop
+
+ stq r21, 16(r19) C dst[i+2]
+ ornot r31, r22, r22
+
+ stq r22, 24(r19) C dst[i+3]
+ ornot r31, r23, r24
+
+ lda r17, 32(r17) C src += 4
+ lda r19, 32(r19) C dst += 4
+ unop
+ fbge f0, L(top)
+
+
+L(done_1):
+ C r19 &dst[size-1]
+ C r24 result for dst[size-1]
+
+ stq r24, 0(r19) C dst[size-1]
+ ret r31, (r26), 1
+
+
+L(done_2):
+ C r19 &dst[size-3]
+ C r20 src[size-2]
+ C r21 src[size-1]
+ C r24 result for dst[size-3]
+
+ stq r24, 0(r19) C dst[size-3]
+ ornot r31, r20, r20
+
+ stq r20, 8(r19) C dst[size-2]
+ ornot r31, r21, r21
+
+ stq r21, 16(r19) C dst[size-1]
+ ret r31, (r26), 1
+
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/copyd.asm b/gmp/mpn/alpha/copyd.asm
new file mode 100644
index 0000000000..b41b5366cc
--- /dev/null
+++ b/gmp/mpn/alpha/copyd.asm
@@ -0,0 +1,88 @@
+dnl Alpha mpn_copyd -- copy, decrementing.
+
+dnl Copyright 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 4
+C EV5: 1.75
+C EV6: 1
+
+C INPUT PARAMETERS
+C rp r16
+C up r17
+C n r18
+
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+ s8addq r18,r16,r16 C E0
+ s8addq r18,r17,r17 C E1
+ lda r18,-8(r18) C E0
+ blt r18,$Lend C E1
+$Loop: ldq r0,-8(r17) C E0
+ ldq r1,-16(r17) C E1
+ ldq r2,-24(r17) C E0
+ ldq r3,-32(r17) C E1
+ ldq r4,-40(r17) C E0
+ ldq r5,-48(r17) C E1
+ ldq r6,-56(r17) C E0
+ ldq r7,-64(r17) C E1
+ stq r0,-8(r16) C E0
+ lda r17,-64(r17) C E1
+ stq r1,-16(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r2,-24(r16) C E0
+ lda r18,-8(r18) C E1
+ stq r3,-32(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r4,-40(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r5,-48(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r6,-56(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r7,-64(r16) C E0
+ lda r16,-64(r16) C E1
+ bge r18,$Loop C E1
+$Lend: lda r18,7(r18) C E0
+ blt r18,$Lret C E1
+ ldq r0,-8(r17) C E0
+ beq r18,$Lend0 C E1
+$Loop0: stq r0,-8(r16) C E0
+ lda r16,-8(r16) C E1
+ ldq r0,-16(r17) C E0
+ lda r18,-1(r18) C E1
+ lda r17,-8(r17) C E0
+ bgt r18,$Loop0 C E1
+$Lend0: stq r0,-8(r16) C E0
+$Lret: ret r31,(r26),1 C E1
+EPILOGUE(mpn_copyd)
+ASM_END()
diff --git a/gmp/mpn/alpha/copyi.asm b/gmp/mpn/alpha/copyi.asm
new file mode 100644
index 0000000000..f7e2ad6f6a
--- /dev/null
+++ b/gmp/mpn/alpha/copyi.asm
@@ -0,0 +1,86 @@
+dnl Alpha mpn_copyi -- copy, incrementing.
+
+dnl Copyright 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 4
+C EV5: 1.75
+C EV6: 1
+
+C INPUT PARAMETERS
+C rp r16
+C up r17
+C n r18
+
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+ lda r18,-8(r18) C E0
+ blt r18,$Lend C E1
+$Loop: ldq r0,0(r17) C E0
+ ldq r1,8(r17) C E1
+ ldq r2,16(r17) C E0
+ ldq r3,24(r17) C E1
+ ldq r4,32(r17) C E0
+ ldq r5,40(r17) C E1
+ ldq r6,48(r17) C E0
+ ldq r7,56(r17) C E1
+ stq r0,0(r16) C E0
+ lda r17,64(r17) C E1
+ stq r1,8(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r2,16(r16) C E0
+ lda r18,-8(r18) C E1
+ stq r3,24(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r4,32(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r5,40(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r6,48(r16) C E0
+ bis r31, r31, r31 C E1
+ stq r7,56(r16) C E0
+ lda r16,64(r16) C E1
+ bge r18,$Loop C E1
+$Lend: lda r18,7(r18) C E0
+ blt r18,$Lret C E1
+ ldq r0,0(r17) C E0
+ beq r18,$Lend0 C E1
+$Loop0: stq r0,0(r16) C E0
+ lda r16,8(r16) C E1
+ ldq r0,8(r17) C E0
+ lda r18,-1(r18) C E1
+ lda r17,8(r17) C E0
+ bgt r18,$Loop0 C E1
+$Lend0: stq r0,0(r16) C E0
+$Lret: ret r31,(r26),1 C E1
+EPILOGUE(mpn_copyi)
+ASM_END()
diff --git a/gmp/mpn/alpha/default.m4 b/gmp/mpn/alpha/default.m4
new file mode 100644
index 0000000000..8fe7c4e122
--- /dev/null
+++ b/gmp/mpn/alpha/default.m4
@@ -0,0 +1,127 @@
+divert(-1)
+
+dnl m4 macros for alpha assembler (everywhere except unicos).
+
+
+dnl Copyright 2000, 2002-2004, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Usage: ASM_START()
+define(`ASM_START',
+m4_assert_numargs(0)
+` .set noreorder
+ .set noat')
+
+dnl Usage: X(value)
+define(`X',
+m4_assert_numargs(1)
+`0x$1')
+
+dnl Usage: FLOAT64(label,value)
+define(`FLOAT64',
+m4_assert_numargs(2)
+` .align 3
+$1: .t_floating $2')
+
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo[,gp|noalign])
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs_range(1,2)
+`ifelse(`$2',gp,,
+`ifelse(`$2',noalign,,
+`ifelse(`$2',,,`m4_error(`Unrecognised PROLOGUE parameter
+')')')')dnl
+ .text
+ifelse(`$2',noalign,,` ALIGN(16)')
+ .globl $1
+ .ent $1
+$1:
+ .frame r30,0,r26,0
+ifelse(`$2',gp,` ldgp r29, 0(r27)
+`$'$1..ng:')
+ .prologue ifelse(`$2',gp,1,0)')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+` .end $1')
+
+
+dnl Usage: LDGP(dst,src)
+dnl
+dnl Emit an "ldgp dst,src", but only if the system uses a GOT.
+
+define(LDGP,
+m4_assert_numargs(2)
+`ldgp `$1', `$2'')
+
+
+dnl Usage: EXTERN(variable_name)
+define(`EXTERN',
+m4_assert_numargs(1)
+)
+
+dnl Usage: r0 ... r31
+dnl f0 ... f31
+dnl
+dnl Map register names r0 to $0, and f0 to $f0, etc.
+dnl This is needed on all systems but Unicos
+dnl
+dnl defreg() is used to protect the $ in $0 (otherwise it would represent a
+dnl macro argument). Double quoting is used to protect the f0 in $f0
+dnl (otherwise it would be an infinite recursion).
+
+forloop(i,0,31,`defreg(`r'i,$i)')
+forloop(i,0,31,`deflit(`f'i,``$f''i)')
+
+
+dnl Usage: DATASTART(name,align) or DATASTART(name)
+dnl DATAEND()
+
+define(`DATASTART',
+m4_assert_numargs_range(1,2)
+` RODATA
+ ALIGN(ifelse($#,1,2,$2))
+$1:')
+define(`DATAEND',
+m4_assert_numargs(0)
+)
+
+dnl Load a symbolic address into a register
+define(`LEA',
+m4_assert_numargs(2)
+`lda $1, $2')
+
+dnl Usage: ASM_END()
+define(`ASM_END',
+m4_assert_numargs(0)
+)
+
+divert
diff --git a/gmp/mpn/alpha/dive_1.c b/gmp/mpn/alpha/dive_1.c
new file mode 100644
index 0000000000..88b82db2f7
--- /dev/null
+++ b/gmp/mpn/alpha/dive_1.c
@@ -0,0 +1,115 @@
+/* Alpha mpn_divexact_1 -- mpn by limb exact division.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2000-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* cycles/limb
+ EV4: 47.0
+ EV5: 30.0
+ EV6: 15.0
+*/
+
+
+/* The dependent chain is as follows (the same as modexact), and this is
+ what the code runs as.
+
+ ev4 ev5 ev6
+ 1 1 1 sub y = x - h
+ 23 13 7 mulq q = y * inverse
+ 23 15 7 umulh h = high (q * d)
+ -- -- --
+ 47 30 15
+
+ The time to load src[i+1] and establish x hides under the umulh latency. */
+
+void
+mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor)
+{
+ mp_limb_t inverse, lshift_mask, s, sr, s_next, c, h, x, y, q, dummy;
+ unsigned rshift, lshift;
+
+ ASSERT (size >= 1);
+ ASSERT (divisor != 0);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, size));
+ ASSERT_MPN (src, size);
+ ASSERT_LIMB (divisor);
+
+ s_next = *src++; /* src[0] */
+
+ rshift = 0;
+ lshift_mask = 0;
+ if ((divisor & 1) == 0)
+ {
+ count_trailing_zeros (rshift, divisor);
+ lshift_mask = MP_LIMB_T_MAX;
+ divisor >>= rshift;
+ }
+
+ binvert_limb (inverse, divisor);
+ lshift = 64 - rshift;
+
+ c = 0;
+ h = 0;
+ sr = s_next >> rshift;
+
+ size--;
+ if (LIKELY (size != 0))
+ {
+ do
+ {
+ s_next = *src++; /* src[i+1] */
+ s = sr | ((s_next << lshift) & lshift_mask);
+ x = s - c;
+ c = s < c;
+ sr = s_next >> rshift;
+
+ y = x - h;
+ c += (x < h);
+ q = y * inverse;
+ *dst++ = q;
+ umul_ppmm (h, dummy, q, divisor);
+
+ size--;
+ }
+ while (size != 0);
+ }
+
+ x = sr - c;
+ y = x - h;
+ q = y * inverse;
+ *dst = q; /* dst[size-1] */
+}
diff --git a/gmp/mpn/alpha/divrem_2.asm b/gmp/mpn/alpha/divrem_2.asm
new file mode 100644
index 0000000000..046b246a95
--- /dev/null
+++ b/gmp/mpn/alpha/divrem_2.asm
@@ -0,0 +1,177 @@
+dnl Alpha mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number.
+
+dnl Copyright 2007, 2008, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C norm frac
+C ev4
+C ev5 70 70
+C ev6 29 29
+
+C TODO
+C * Perhaps inline mpn_invert_limb, that would allow us to not save/restore
+C any registers (thus save ~10 cycles per call).
+C * Use negated d1 and/or d0 to speed carry propagation. Might save a cycle
+C or two.
+C * Check cluster delays (for ev6). We very likely could save some cycles.
+C * Use branch-free code for computing di.
+C * CAVEAT: We rely on r19 not being clobbered by mpn_invert_limb call.
+
+C INPUT PARAMETERS
+define(`qp', `r16')
+define(`fn', `r17')
+define(`up_param', `r18')
+define(`un_param', `r19')
+define(`dp', `r20')
+
+ASM_START()
+PROLOGUE(mpn_divrem_2,gp)
+ lda r30, -80(r30)
+ stq r26, 0(r30)
+ stq r9, 8(r30)
+ stq r10, 16(r30)
+ stq r11, 24(r30)
+ stq r12, 32(r30)
+ stq r13, 40(r30)
+C stq r14, 48(r30)
+ stq r15, 56(r30)
+ .prologue 1
+ stq r16, 64(r30)
+ bis r31, r17, r15
+ s8addq r19, r18, r13
+ lda r13, -24(r13)
+ ldq r12, 8(r20)
+ ldq r10, 0(r20)
+ ldq r11, 16(r13)
+ ldq r9, 8(r13)
+
+ bis r31, r31, r3 C most_significant_q_limb = 0
+ cmpult r11, r12, r1
+ bne r1, L(L8)
+ cmpule r11, r12, r1
+ cmpult r9, r10, r2
+ and r1, r2, r1
+ bne r1, L(L8)
+ subq r11, r12, r11
+ subq r11, r2, r11
+ subq r9, r10, r9
+ lda r3, 1(r31) C most_significant_q_limb = 1
+L(L8): stq r3, 72(r30)
+
+ addq r15, r19, r19
+ lda r19, -3(r19)
+ blt r19, L(L10)
+ bis r31, r12, r16
+ jsr r26, mpn_invert_limb
+ LDGP( r29, 0(r26))
+ mulq r0, r12, r4 C t0 = LO(di * d1)
+ umulh r0, r10, r2 C s1 = HI(di * d0)
+ addq r4, r10, r4 C t0 += d0
+ cmpule r10, r4, r7 C (t0 < d0)
+ addq r4, r2, r4 C t0 += s1
+ cmpult r4, r2, r1
+ subq r1, r7, r7 C t1 (-1, 0, or 1)
+ blt r7, L(L42)
+L(L22):
+ lda r0, -1(r0) C di--
+ cmpult r4, r12, r1 C cy for: t0 -= d1 (below)
+ subq r7, r1, r7 C t1 -= cy
+ subq r4, r12, r4 C t0 -= d1
+ bge r7, L(L22)
+L(L42):
+ ldq r16, 64(r30)
+ s8addq r19, r16, r16
+ ALIGN(16)
+L(loop):
+ mulq r11, r0, r5 C q0 (early)
+ umulh r11, r0, r6 C q (early)
+ addq r5, r9, r8 C q0 += n1
+ addq r6, r11, r6 C q += n2
+ cmpult r8, r5, r1 C cy for: q0 += n1
+ addq r6, r1, r6 C q += cy
+ unop
+ mulq r12, r6, r1 C LO(d1 * q)
+ umulh r10, r6, r7 C t1 = HI(d0 * q)
+ subq r9, r1, r9 C n1 -= LO(d1 * q)
+ mulq r10, r6, r4 C t0 = LO(d0 * q)
+ unop
+ cmple r15, r19, r5 C condition and n0...
+ beq r5, L(L31)
+ ldq r5, 0(r13)
+ lda r13, -8(r13)
+L(L31): subq r9, r12, r9 C n1 -= d1
+ cmpult r5, r10, r1 C
+ subq r9, r1, r9 C
+ subq r5, r10, r5 C n0 -= d0
+ subq r9, r7, r9 C n1 -= t0
+ cmpult r5, r4, r1 C
+ subq r9, r1, r2 C
+ subq r5, r4, r5 C n0 -= t1
+ cmpult r2, r8, r1 C (n1 < q0)
+ addq r6, r1, r6 C q += cond
+ lda r1, -1(r1) C -(n1 >= q0)
+ and r1, r10, r4 C
+ addq r5, r4, r9 C n0 += mask & d0
+ and r1, r12, r1 C
+ cmpult r9, r5, r11 C cy for: n0 += mask & d0
+ addq r2, r1, r1 C n1 += mask & d1
+ addq r1, r11, r11 C n1 += cy
+ cmpult r11, r12, r1 C
+ beq r1, L(fix) C
+L(bck): stq r6, 0(r16)
+ lda r16, -8(r16)
+ lda r19, -1(r19)
+ bge r19, L(loop)
+
+L(L10): stq r9, 8(r13)
+ stq r11, 16(r13)
+ ldq r0, 72(r30)
+ ldq r26, 0(r30)
+ ldq r9, 8(r30)
+ ldq r10, 16(r30)
+ ldq r11, 24(r30)
+ ldq r12, 32(r30)
+ ldq r13, 40(r30)
+C ldq r14, 48(r30)
+ ldq r15, 56(r30)
+ lda r30, 80(r30)
+ ret r31, (r26), 1
+
+L(fix): cmpule r11, r12, r1
+ cmpult r9, r10, r2
+ and r1, r2, r1
+ bne r1, L(bck)
+ subq r11, r12, r11
+ subq r11, r2, r11
+ subq r9, r10, r9
+ lda r6, 1(r6)
+ br L(bck)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev5/diveby3.asm b/gmp/mpn/alpha/ev5/diveby3.asm
new file mode 100644
index 0000000000..3758188e02
--- /dev/null
+++ b/gmp/mpn/alpha/ev5/diveby3.asm
@@ -0,0 +1,332 @@
+dnl Alpha mpn_divexact_by3c -- mpn division by 3, expecting no remainder.
+
+dnl Copyright 2004, 2005, 2009 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 22
+C EV5: 11.5
+C EV6: 6.3 Note that mpn_bdiv_dbm1c is faster
+
+C TODO
+C * Remove the unops, they benefit just ev6, which no longer uses this file.
+C * Try prefetch for destination, using lds.
+C * Improve feed-in code, by moving initial mulq earlier; make initial load
+C to u0/u0 to save some copying.
+C * Combine u0 and u2, u1 and u3.
+
+C INPUT PARAMETERS
+define(`rp', `r16')
+define(`up', `r17')
+define(`n', `r18')
+define(`cy', `r19')
+
+ASM_START()
+
+DATASTART(L(LC),8)
+ .quad 0xAAAAAAAAAAAAAAAB
+ .quad 0x5555555555555555
+ .quad 0xAAAAAAAAAAAAAAAA
+DATAEND()
+
+define(`xAAAAAAAAAAAAAAAB', `r20')
+define(`x5555555555555555', `r21')
+define(`xAAAAAAAAAAAAAAAA', `r22')
+define(`u0', `r0') define(`u1', `r1')
+define(`u2', `r2') define(`u3', `r3')
+define(`l0', `r25') define(`x', `r8')
+define(`q0', `r4') define(`q1', `r5')
+define(`p6', `r6') define(`p7', `r7')
+define(`t0', `r23') define(`t1', `r24')
+define(`cymask',`r28')
+
+
+PROLOGUE(mpn_divexact_by3c,gp)
+
+ ldq r28, 0(up) C load first limb early
+
+C Put magic constants in registers
+ lda r0, L(LC)
+ ldq xAAAAAAAAAAAAAAAB, 0(r0)
+ ldq x5555555555555555, 8(r0)
+ ldq xAAAAAAAAAAAAAAAA, 16(r0)
+
+C Compute initial l0 value
+ cmpeq cy, 1, p6
+ cmpeq cy, 2, p7
+ negq p6, p6
+ and p6, x5555555555555555, l0
+ cmovne p7, xAAAAAAAAAAAAAAAA, l0
+
+C Feed-in depending on (n mod 4)
+ and n, 3, r8
+ lda n, -3(n)
+ cmpeq r8, 1, r4
+ cmpeq r8, 2, r5
+ bne r4, $Lb01
+ bne r5, $Lb10
+ beq r8, $Lb00
+
+$Lb11: ldq u3, 8(up)
+ lda up, -24(up)
+ lda rp, -24(rp)
+ mulq r28, xAAAAAAAAAAAAAAAB, q0
+ mov r28, u2
+ br r31, $L11
+
+$Lb00: ldq u2, 8(up)
+ lda up, -16(up)
+ lda rp, -16(rp)
+ mulq r28, xAAAAAAAAAAAAAAAB, q1
+ mov r28, u1
+ br r31, $L00
+
+$Lb01: lda rp, -8(rp)
+ mulq r28, xAAAAAAAAAAAAAAAB, q0
+ mov r28, u0
+ blt n, $Lcj1
+ ldq u1, 8(up)
+ lda up, -8(up)
+ br r31, $L01
+
+$Lb10: ldq u0, 8(up)
+ mulq r28, xAAAAAAAAAAAAAAAB, q1
+ mov r28, u3
+ blt n, $Lend
+
+ ALIGN(16)
+$Ltop:
+C 0
+ cmpult u3, cy, cy C L0
+ mulq u0, xAAAAAAAAAAAAAAAB, q0 C U1
+ ldq u1, 16(up) C L1
+ addq q1, l0, x C U0
+C 1
+ negq cy, cymask C L0
+ unop C U1
+ unop C L1
+ cmpult x5555555555555555, x, p6 C U0
+C 2
+ cmpult xAAAAAAAAAAAAAAAA, x, p7 C U1
+ unop
+ unop
+ negq p6, t0 C L0
+C 3
+ negq p7, t1 C L0
+ and cymask, x5555555555555555, l0 C U1
+ addq p6, cy, cy
+ and t0, x5555555555555555, t0
+C 4
+ and t1, x5555555555555555, t1
+ addq p7, cy, cy
+ unop
+ addq t0, l0, l0
+C 5
+ addq t1, l0, l0
+ unop
+ stq x, 0(rp) C L1
+ unop
+$L01:
+C 0
+ cmpult u0, cy, cy C L0
+ mulq u1, xAAAAAAAAAAAAAAAB, q1 C U1
+ ldq u2, 24(up) C L1
+ addq q0, l0, x C U0
+C 1
+ negq cy, cymask C L0
+ unop C U1
+ unop C L1
+ cmpult x5555555555555555, x, p6 C U0
+C 2
+ cmpult xAAAAAAAAAAAAAAAA, x, p7 C U1
+ unop
+ unop
+ negq p6, t0 C L0
+C 3
+ negq p7, t1 C L0
+ and cymask, x5555555555555555, l0 C U1
+ addq p6, cy, cy
+ and t0, x5555555555555555, t0
+C 4
+ and t1, x5555555555555555, t1
+ addq p7, cy, cy
+ unop
+ addq t0, l0, l0
+C 5
+ addq t1, l0, l0
+ unop
+ stq x, 8(rp) C L1
+ unop
+$L00:
+C 0
+ cmpult u1, cy, cy C L0
+ mulq u2, xAAAAAAAAAAAAAAAB, q0 C U1
+ ldq u3, 32(up) C L1
+ addq q1, l0, x C U0
+C 1
+ negq cy, cymask C L0
+ unop C U1
+ unop C L1
+ cmpult x5555555555555555, x, p6 C U0
+C 2
+ cmpult xAAAAAAAAAAAAAAAA, x, p7 C U1
+ unop
+ unop
+ negq p6, t0 C L0
+C 3
+ negq p7, t1 C L0
+ and cymask, x5555555555555555, l0 C U1
+ addq p6, cy, cy
+ and t0, x5555555555555555, t0
+C 4
+ and t1, x5555555555555555, t1
+ addq p7, cy, cy
+ unop
+ addq t0, l0, l0
+C 5
+ addq t1, l0, l0
+ unop
+ stq x, 16(rp) C L1
+ unop
+$L11:
+C 0
+ cmpult u2, cy, cy C L0
+ mulq u3, xAAAAAAAAAAAAAAAB, q1 C U1
+ ldq u0, 40(up) C L1
+ addq q0, l0, x C U0
+C 1
+ negq cy, cymask C L0
+ unop C U1
+ unop C L1
+ cmpult x5555555555555555, x, p6 C U0
+C 2
+ cmpult xAAAAAAAAAAAAAAAA, x, p7 C U1
+ lda n, -4(n) C L1 bookkeeping
+ unop
+ negq p6, t0 C L0
+C 3
+ negq p7, t1 C L0
+ and cymask, x5555555555555555, l0 C U1
+ addq p6, cy, cy
+ and t0, x5555555555555555, t0
+C 4
+ and t1, x5555555555555555, t1
+ addq p7, cy, cy
+ unop
+ addq t0, l0, l0
+C 5
+ addq t1, l0, l0
+ unop
+ stq x, 24(rp) C L1
+ lda up, 32(up)
+C
+ ldl r31, 256(up) C prefetch
+ unop
+ lda rp, 32(rp)
+ bge n, $Ltop C U1
+C *** MAIN LOOP END ***
+$Lend:
+
+ cmpult u3, cy, cy C L0
+ mulq u0, xAAAAAAAAAAAAAAAB, q0 C U1
+ unop
+ addq q1, l0, x C U0
+C 1
+ negq cy, cymask C L0
+ unop C U1
+ unop C L1
+ cmpult x5555555555555555, x, p6 C U0
+C 2
+ cmpult xAAAAAAAAAAAAAAAA, x, p7 C U1
+ unop
+ unop
+ negq p6, t0 C L0
+C 3
+ negq p7, t1 C L0
+ and cymask, x5555555555555555, l0 C U1
+ addq p6, cy, cy
+ and t0, x5555555555555555, t0
+C 4
+ and t1, x5555555555555555, t1
+ addq p7, cy, cy
+ unop
+ addq t0, l0, l0
+C 5
+ addq t1, l0, l0
+ unop
+ stq x, 0(rp) C L1
+ unop
+$Lcj1:
+ cmpult u0, cy, cy C L0
+ addq q0, l0, x C U0
+ cmpult x5555555555555555, x, p6 C U0
+ cmpult xAAAAAAAAAAAAAAAA, x, p7 C U1
+ addq p6, cy, cy
+ addq p7, cy, r0
+ stq x, 8(rp) C L1
+
+ ret r31,(r26),1
+EPILOGUE()
+ASM_END()
+
+C This is useful for playing with various schedules.
+C Expand as: one(0)one(1)one(2)one(3)
+define(`one',`
+C 0
+ cmpult `$'eval(($1+3)%4), cy, cy C L0
+ mulq `$'$1, xAAAAAAAAAAAAAAAB, `$'eval(4+$1%2) C U1
+ ldq `$'eval(($1+1)%4), eval($1*8+16)(up) C L1
+ addq `$'eval(4+($1+1)%2), l0, x C U0
+C 1
+ negq cy, cymask C L0
+ unop C U1
+ unop C L1
+ cmpult x5555555555555555, x, p6 C U0
+C 2
+ cmpult xAAAAAAAAAAAAAAAA, x, p7 C U1
+ unop
+ unop
+ negq p6, t0 C L0
+C 3
+ negq p7, t1 C L0
+ and cymask, x5555555555555555, l0 C U1
+ addq p6, cy, cy
+ and t0, x5555555555555555, t0
+C 4
+ and t1, x5555555555555555, t1
+ addq p7, cy, cy
+ unop
+ addq t0, l0, l0
+C 5
+ addq t1, l0, l0
+ unop
+ stq x, eval($1*8)(rp) C L1
+ unop
+')
diff --git a/gmp/mpn/alpha/ev5/gmp-mparam.h b/gmp/mpn/alpha/ev5/gmp-mparam.h
new file mode 100644
index 0000000000..b560c20afe
--- /dev/null
+++ b/gmp/mpn/alpha/ev5/gmp-mparam.h
@@ -0,0 +1,187 @@
+/* Alpha EV5 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004, 2005, 2008-2010, 2014 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 600 MHz 21164A */
+/* FFT tuning limit = 5000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.5 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* preinv always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 22
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 15
+#define USE_PREINV_DIVREM_1 1 /* preinv always */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 76
+
+#define MUL_TOOM22_THRESHOLD 14
+#define MUL_TOOM33_THRESHOLD 50
+#define MUL_TOOM44_THRESHOLD 118
+#define MUL_TOOM6H_THRESHOLD 157
+#define MUL_TOOM8H_THRESHOLD 236
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 77
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 81
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 56
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 70
+
+#define SQR_BASECASE_THRESHOLD 0 /* always */
+#define SQR_TOOM2_THRESHOLD 22
+#define SQR_TOOM3_THRESHOLD 73
+#define SQR_TOOM4_THRESHOLD 178
+#define SQR_TOOM6_THRESHOLD 0 /* always */
+#define SQR_TOOM8_THRESHOLD 260
+
+#define MULMID_TOOM42_THRESHOLD 18
+
+#define MULMOD_BNM1_THRESHOLD 9
+#define SQRMOD_BNM1_THRESHOLD 12
+
+#define MUL_FFT_MODF_THRESHOLD 284 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 284, 5}, { 11, 6}, { 6, 5}, { 13, 6}, \
+ { 7, 5}, { 15, 6}, { 13, 7}, { 7, 6}, \
+ { 15, 7}, { 8, 6}, { 17, 7}, { 13, 8}, \
+ { 7, 7}, { 17, 8}, { 9, 7}, { 20, 8}, \
+ { 11, 7}, { 23, 8}, { 13, 9}, { 7, 8}, \
+ { 19, 9}, { 11, 8}, { 25,10}, { 7, 9}, \
+ { 15, 8}, { 33, 9}, { 19, 8}, { 39, 9}, \
+ { 23, 8}, { 47,10}, { 15, 9}, { 39,10}, \
+ { 23, 9}, { 47,11}, { 15,10}, { 31, 9}, \
+ { 67,10}, { 39, 9}, { 79,10}, { 47, 9}, \
+ { 95,10}, { 55,11}, { 31,10}, { 63, 8}, \
+ { 255, 7}, { 511,10}, { 71, 9}, { 143, 8}, \
+ { 287, 7}, { 575, 9}, { 159, 8}, { 319,11}, \
+ { 47,12}, { 31,11}, { 63, 9}, { 255, 8}, \
+ { 511,10}, { 143, 9}, { 287,11}, { 79,10}, \
+ { 159, 9}, { 319,10}, { 175, 9}, { 351, 8}, \
+ { 703,10}, { 191, 9}, { 383,10}, { 207, 9}, \
+ { 415,12}, { 63,10}, { 255,11}, { 143,10}, \
+ { 287, 9}, { 575,11}, { 159,10}, { 319, 9}, \
+ { 639,11}, { 175,12}, { 95,11}, { 191,10}, \
+ { 383,11}, { 207,10}, { 415,11}, { 223,13}, \
+ { 63,11}, { 287,10}, { 575,12}, { 159,11}, \
+ { 319,10}, { 639,11}, { 351,12}, { 191,11}, \
+ { 415,12}, { 223,11}, { 447,10}, { 895,11}, \
+ { 479,12}, { 287,11}, { 575,12}, { 351,13}, \
+ { 191,12}, { 479,13}, { 255,12}, { 575,13}, \
+ { 319,12}, { 703,13}, { 383,12}, { 831,13}, \
+ { 447,14}, { 255,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 121
+#define MUL_FFT_THRESHOLD 4224
+
+#define SQR_FFT_MODF_THRESHOLD 240 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 240, 5}, { 13, 6}, { 7, 5}, { 15, 6}, \
+ { 14, 5}, { 29, 7}, { 9, 6}, { 19, 7}, \
+ { 13, 6}, { 27, 8}, { 7, 7}, { 21, 8}, \
+ { 11, 7}, { 29, 8}, { 19, 9}, { 11, 8}, \
+ { 27,10}, { 7, 9}, { 15, 8}, { 33, 9}, \
+ { 19, 8}, { 39, 9}, { 23, 8}, { 47,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 47,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255,10}, { 71, 9}, { 143, 8}, \
+ { 287,10}, { 79,11}, { 47,12}, { 31,11}, \
+ { 63,10}, { 127, 9}, { 255,10}, { 143, 9}, \
+ { 287,11}, { 79,10}, { 159, 9}, { 319,10}, \
+ { 175,11}, { 95,10}, { 191, 9}, { 383,10}, \
+ { 207, 9}, { 415,11}, { 111,10}, { 223,12}, \
+ { 63,11}, { 175,12}, { 95,11}, { 207,13}, \
+ { 63,12}, { 127,11}, { 287,12}, { 159,11}, \
+ { 351,12}, { 191,11}, { 415,12}, { 223,11}, \
+ { 447,13}, { 127,12}, { 351,13}, { 191,12}, \
+ { 383,11}, { 767,12}, { 415,11}, { 831,12}, \
+ { 447,14}, { 127,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,13}, { 319,12}, { 703,13}, \
+ { 383,12}, { 831,13}, { 447,14}, { 255,13}, \
+ { 511,12}, { 1023,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 105
+#define SQR_FFT_THRESHOLD 3968
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 45
+#define MULLO_MUL_N_THRESHOLD 8397
+
+#define DC_DIV_QR_THRESHOLD 47
+#define DC_DIVAPPR_Q_THRESHOLD 168
+#define DC_BDIV_QR_THRESHOLD 47
+#define DC_BDIV_Q_THRESHOLD 110
+
+#define INV_MULMOD_BNM1_THRESHOLD 26
+#define INV_NEWTON_THRESHOLD 189
+#define INV_APPR_THRESHOLD 181
+
+#define BINV_NEWTON_THRESHOLD 196
+#define REDC_1_TO_REDC_N_THRESHOLD 51
+
+#define MU_DIV_QR_THRESHOLD 1558
+#define MU_DIVAPPR_Q_THRESHOLD 1558
+#define MUPI_DIV_QR_THRESHOLD 90
+#define MU_BDIV_QR_THRESHOLD 855
+#define MU_BDIV_Q_THRESHOLD 1078
+
+#define POWM_SEC_TABLE 1,16,90,452,1221
+
+#define MATRIX22_STRASSEN_THRESHOLD 11
+#define HGCD_THRESHOLD 99
+#define HGCD_APPR_THRESHOLD 103
+#define HGCD_REDUCE_THRESHOLD 2899
+#define GCD_DC_THRESHOLD 283
+#define GCDEXT_DC_THRESHOLD 201
+#define JACOBI_BASE_METHOD 3
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 28
+#define SET_STR_DC_THRESHOLD 426
+#define SET_STR_PRECOMPUTE_THRESHOLD 1505
+
+#define FAC_DSC_THRESHOLD 1404
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/alpha/ev6/add_n.asm b/gmp/mpn/alpha/ev6/add_n.asm
new file mode 100644
index 0000000000..9261f31b8a
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/add_n.asm
@@ -0,0 +1,283 @@
+dnl Alpha ev6 mpn_add_n -- Add two limb vectors of the same length > 0 and
+dnl store sum in a third limb vector.
+
+dnl Copyright 2000, 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 5.4
+C EV6: 2.125
+
+C INPUT PARAMETERS
+C rp r16
+C up r17
+C vp r18
+C n r19
+C cy r20 (for mpn_add_nc)
+
+C TODO
+C Finish cleaning up cy registers r22, r23 (make them use cy0/cy1)
+C Use multi-pronged feed-in.
+C Perform additional micro-tuning
+
+C This code was written in cooperation with ev6 pipeline expert Steve Root.
+
+C Pair loads and stores where possible
+C Store pairs oct-aligned where possible (didn't need it here)
+C Stores are delayed every third cycle
+C Loads and stores are delayed by fills
+C U stays still, put code there where possible (note alternation of U1 and U0)
+C L moves because of loads and stores
+C Note dampers in L to limit damage
+
+C This odd-looking optimization expects that were having random bits in our
+C data, so that a pure zero result is unlikely. so we penalize the unlikely
+C case to help the common case.
+
+define(`u0', `r0') define(`u1', `r3')
+define(`v0', `r1') define(`v1', `r4')
+
+define(`cy0', `r20') define(`cy1', `r21')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc)
+
+ASM_START()
+PROLOGUE(mpn_add_nc)
+ br r31, $entry
+EPILOGUE()
+PROLOGUE(mpn_add_n)
+ bis r31, r31, cy0 C clear carry in
+$entry: cmpult r19, 5, r22 C L1 move counter
+ ldq u1, 0(r17) C L0 get next ones
+ ldq v1, 0(r18) C L1
+ bne r22, $Lsmall
+
+ ldq u0, 8(r17) C L0 get next ones
+ ldq v0, 8(r18) C L1
+ addq u1, v1, r5 C U0 add two data
+
+ cmpult r5, v1, r23 C U0 did it carry
+ ldq u1, 16(r17) C L0 get next ones
+ ldq v1, 16(r18) C L1
+
+ addq u0, v0, r8 C U1 add two data
+ addq r5, cy0, r5 C U0 carry in
+
+ cmpult r8, v0, r22 C U1 did it carry
+ beq r5, $fix5f C U0 fix exact zero
+$ret5f: ldq u0, 24(r17) C L0 get next ones
+ ldq v0, 24(r18) C L1
+
+ addq r8, r23, r8 C U1 carry from last
+ addq u1, v1, r7 C U0 add two data
+
+ beq r8, $fix6f C U1 fix exact zero
+$ret6f: cmpult r7, v1, r23 C U0 did it carry
+ ldq u1, 32(r17) C L0 get next ones
+ ldq v1, 32(r18) C L1
+
+ lda r17, 40(r17) C L0 move pointer
+ lda r18, 40(r18) C L1 move pointer
+
+ lda r16, -8(r16)
+ lda r19, -13(r19) C L1 move counter
+ blt r19, $Lend C U1 loop control
+
+
+C Main loop. 8-way unrolled.
+ ALIGN(16)
+$Loop: addq u0, v0, r2 C U1 add two data
+ addq r7, r22, r7 C U0 add in carry
+ stq r5, 8(r16) C L0 put an answer
+ stq r8, 16(r16) C L1 pair
+
+ cmpult r2, v0, cy1 C U1 did it carry
+ beq r7, $fix7 C U0 fix exact 0
+$ret7: ldq u0, 0(r17) C L0 get next ones
+ ldq v0, 0(r18) C L1
+
+ bis r31, r31, r31 C L damp out
+ addq r2, r23, r2 C U1 carry from last
+ bis r31, r31, r31 C L moves in L !
+ addq u1, v1, r5 C U0 add two data
+
+ beq r2, $fix0 C U1 fix exact zero
+$ret0: cmpult r5, v1, cy0 C U0 did it carry
+ ldq u1, 8(r17) C L0 get next ones
+ ldq v1, 8(r18) C L1
+
+ addq u0, v0, r8 C U1 add two data
+ addq r5, cy1, r5 C U0 carry from last
+ stq r7, 24(r16) C L0 store pair
+ stq r2, 32(r16) C L1
+
+ cmpult r8, v0, r22 C U1 did it carry
+ beq r5, $fix1 C U0 fix exact zero
+$ret1: ldq u0, 16(r17) C L0 get next ones
+ ldq v0, 16(r18) C L1
+
+ lda r16, 64(r16) C L0 move pointer
+ addq r8, cy0, r8 C U1 carry from last
+ lda r19, -8(r19) C L1 move counter
+ addq u1, v1, r7 C U0 add two data
+
+ beq r8, $fix2 C U1 fix exact zero
+$ret2: cmpult r7, v1, r23 C U0 did it carry
+ ldq u1, 24(r17) C L0 get next ones
+ ldq v1, 24(r18) C L1
+
+ addq u0, v0, r2 C U1 add two data
+ addq r7, r22, r7 C U0 add in carry
+ stq r5, -24(r16) C L0 put an answer
+ stq r8, -16(r16) C L1 pair
+
+ cmpult r2, v0, cy1 C U1 did it carry
+ beq r7, $fix3 C U0 fix exact 0
+$ret3: ldq u0, 32(r17) C L0 get next ones
+ ldq v0, 32(r18) C L1
+
+ bis r31, r31, r31 C L damp out
+ addq r2, r23, r2 C U1 carry from last
+ bis r31, r31, r31 C L moves in L !
+ addq u1, v1, r5 C U0 add two data
+
+ beq r2, $fix4 C U1 fix exact zero
+$ret4: cmpult r5, v1, cy0 C U0 did it carry
+ ldq u1, 40(r17) C L0 get next ones
+ ldq v1, 40(r18) C L1
+
+ addq u0, v0, r8 C U1 add two data
+ addq r5, cy1, r5 C U0 carry from last
+ stq r7, -8(r16) C L0 store pair
+ stq r2, 0(r16) C L1
+
+ cmpult r8, v0, r22 C U1 did it carry
+ beq r5, $fix5 C U0 fix exact zero
+$ret5: ldq u0, 48(r17) C L0 get next ones
+ ldq v0, 48(r18) C L1
+
+ ldl r31, 256(r17) C L0 prefetch
+ addq r8, cy0, r8 C U1 carry from last
+ ldl r31, 256(r18) C L1 prefetch
+ addq u1, v1, r7 C U0 add two data
+
+ beq r8, $fix6 C U1 fix exact zero
+$ret6: cmpult r7, v1, r23 C U0 did it carry
+ ldq u1, 56(r17) C L0 get next ones
+ ldq v1, 56(r18) C L1
+
+ lda r17, 64(r17) C L0 move pointer
+ bis r31, r31, r31 C U
+ lda r18, 64(r18) C L1 move pointer
+ bge r19, $Loop C U1 loop control
+C ==== main loop end
+
+$Lend: addq u0, v0, r2 C U1 add two data
+ addq r7, r22, r7 C U0 add in carry
+ stq r5, 8(r16) C L0 put an answer
+ stq r8, 16(r16) C L1 pair
+ cmpult r2, v0, cy1 C U1 did it carry
+ beq r7, $fix7c C U0 fix exact 0
+$ret7c: addq r2, r23, r2 C U1 carry from last
+ addq u1, v1, r5 C U0 add two data
+ beq r2, $fix0c C U1 fix exact zero
+$ret0c: cmpult r5, v1, cy0 C U0 did it carry
+ addq r5, cy1, r5 C U0 carry from last
+ stq r7, 24(r16) C L0 store pair
+ stq r2, 32(r16) C L1
+ beq r5, $fix1c C U0 fix exact zero
+$ret1c: stq r5, 40(r16) C L0 put an answer
+ lda r16, 48(r16) C L0 move pointer
+
+ lda r19, 8(r19)
+ beq r19, $Lret
+
+ ldq u1, 0(r17)
+ ldq v1, 0(r18)
+$Lsmall:
+ lda r19, -1(r19)
+ beq r19, $Lend0
+
+ ALIGN(8)
+$Loop0: addq u1, v1, r2 C main add
+ cmpult r2, v1, r8 C compute cy from last add
+ ldq u1, 8(r17)
+ ldq v1, 8(r18)
+ addq r2, cy0, r5 C carry add
+ lda r17, 8(r17)
+ lda r18, 8(r18)
+ stq r5, 0(r16)
+ cmpult r5, r2, cy0 C compute cy from last add
+ lda r19, -1(r19) C decr loop cnt
+ bis r8, cy0, cy0 C combine cy from the two adds
+ lda r16, 8(r16)
+ bne r19, $Loop0
+$Lend0: addq u1, v1, r2 C main add
+ addq r2, cy0, r5 C carry add
+ cmpult r2, v1, r8 C compute cy from last add
+ cmpult r5, r2, cy0 C compute cy from last add
+ stq r5, 0(r16)
+ bis r8, cy0, r0 C combine cy from the two adds
+ ret r31,(r26),1
+
+ ALIGN(8)
+$Lret: lda r0, 0(cy0) C copy carry into return register
+ ret r31,(r26),1
+
+$fix5f: bis r23, cy0, r23 C bring forward carry
+ br r31, $ret5f
+$fix6f: bis r22, r23, r22 C bring forward carry
+ br r31, $ret6f
+$fix0: bis cy1, r23, cy1 C bring forward carry
+ br r31, $ret0
+$fix1: bis cy0, cy1, cy0 C bring forward carry
+ br r31, $ret1
+$fix2: bis r22, cy0, r22 C bring forward carry
+ br r31, $ret2
+$fix3: bis r23, r22, r23 C bring forward carry
+ br r31, $ret3
+$fix4: bis cy1, r23, cy1 C bring forward carry
+ br r31, $ret4
+$fix5: bis cy1, cy0, cy0 C bring forward carry
+ br r31, $ret5
+$fix6: bis r22, cy0, r22 C bring forward carry
+ br r31, $ret6
+$fix7: bis r23, r22, r23 C bring forward carry
+ br r31, $ret7
+$fix0c: bis cy1, r23, cy1 C bring forward carry
+ br r31, $ret0c
+$fix1c: bis cy0, cy1, cy0 C bring forward carry
+ br r31, $ret1c
+$fix7c: bis r23, r22, r23 C bring forward carry
+ br r31, $ret7c
+
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/aorslsh1_n.asm b/gmp/mpn/alpha/ev6/aorslsh1_n.asm
new file mode 100644
index 0000000000..cb966ce021
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/aorslsh1_n.asm
@@ -0,0 +1,172 @@
+dnl Alpha mpn_addlsh1_n/mpn_sublsh1_n -- rp[] = up[] +- (vp[] << 1).
+
+dnl Copyright 2003, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 7
+C EV6: 4
+
+C TODO
+C * Tune to reach 3.75 c/l on ev6.
+
+define(`rp',`r16')
+define(`up',`r17')
+define(`vp',`r18')
+define(`n', `r19')
+
+define(`u0', `r8')
+define(`u1', `r1')
+define(`v0', `r4')
+define(`v1', `r5')
+
+define(`cy0', `r0')
+define(`cy1', `r20')
+define(`cy', `r22')
+define(`rr', `r24')
+define(`ps', `r25')
+define(`sl', `r28')
+
+ifdef(`OPERATION_addlsh1_n',`
+ define(ADDSUB, addq)
+ define(CARRY, `cmpult $1,$2,$3')
+ define(func, mpn_addlsh1_n)
+')
+ifdef(`OPERATION_sublsh1_n',`
+ define(ADDSUB, subq)
+ define(CARRY, `cmpult $2,$1,$3')
+ define(func, mpn_sublsh1_n)
+')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n)
+
+ASM_START()
+PROLOGUE(func)
+ and n, 2, cy0
+ blbs n, L(bx1)
+L(bx0): ldq v1, 0(vp)
+ ldq u1, 0(up)
+ lda r2, 0(r31)
+ bne cy0, L(b10)
+
+L(b00): lda vp, 48(vp)
+ lda up, -16(up)
+ lda rp, -8(rp)
+ lda cy0, 0(r31)
+ br r31, L(lo0)
+
+L(b10): lda vp, 32(vp)
+ lda rp, 8(rp)
+ lda cy0, 0(r31)
+ br r31, L(lo2)
+
+L(bx1): ldq v0, 0(vp)
+ ldq u0, 0(up)
+ lda r3, 0(r31)
+ beq cy0, L(b01)
+
+L(b11): lda vp, 40(vp)
+ lda up, -24(up)
+ lda rp, 16(rp)
+ lda cy1, 0(r31)
+ br r31, L(lo3)
+
+L(b01): lda n, -4(n)
+ lda cy1, 0(r31)
+ ble n, L(end)
+ lda vp, 24(vp)
+ lda up, -8(up)
+
+ ALIGN(16)
+L(top): addq v0, v0, r6
+ ldq v1, -16(vp)
+ addq r6, r3, sl C combined vlimb
+ ldq u1, 16(up)
+ ADDSUB u0, sl, ps C ulimb + (vlimb << 1)
+ cmplt v0, r31, r2 C high v bits
+ ADDSUB ps, cy1, rr C consume carry from previous operation
+ CARRY( ps, u0, cy0) C carry out #2
+ stq rr, 0(rp)
+ CARRY( rr, ps, cy) C carry out #3
+ lda vp, 32(vp) C bookkeeping
+ addq cy, cy0, cy0 C final carry out
+L(lo0): addq v1, v1, r7
+ ldq v0, -40(vp)
+ addq r7, r2, sl
+ ldq u0, 24(up)
+ ADDSUB u1, sl, ps
+ cmplt v1, r31, r3
+ ADDSUB ps, cy0, rr
+ CARRY( ps, u1, cy1)
+ stq rr, 8(rp)
+ CARRY( rr, ps, cy)
+ lda rp, 32(rp) C bookkeeping
+ addq cy, cy1, cy1
+L(lo3): addq v0, v0, r6
+ ldq v1, -32(vp)
+ addq r6, r3, sl
+ ldq u1, 32(up)
+ ADDSUB u0, sl, ps
+ cmplt v0, r31, r2
+ ADDSUB ps, cy1, rr
+ CARRY( ps, u0, cy0)
+ stq rr, -16(rp)
+ CARRY( rr, ps, cy)
+ lda up, 32(up) C bookkeeping
+ addq cy, cy0, cy0
+L(lo2): addq v1, v1, r7
+ ldq v0, -24(vp)
+ addq r7, r2, sl
+ ldq u0, 8(up)
+ ADDSUB u1, sl, ps
+ cmplt v1, r31, r3
+ ADDSUB ps, cy0, rr
+ CARRY( ps, u1, cy1)
+ stq rr, -8(rp)
+ CARRY( rr, ps, cy)
+ lda n, -4(n) C bookkeeping
+ addq cy, cy1, cy1
+ bgt n, L(top)
+
+L(end): addq v0, v0, r6
+ addq r6, r3, sl
+ ADDSUB u0, sl, ps
+ cmplt v0, r31, r2
+ ADDSUB ps, cy1, rr
+ CARRY( ps, u0, cy0)
+ stq rr, 0(rp)
+ CARRY( rr, ps, cy)
+ addq cy, cy0, cy0
+ addq cy0, r2, r0
+
+ ret r31,(r26),1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/aorsmul_1.asm b/gmp/mpn/alpha/ev6/aorsmul_1.asm
new file mode 100644
index 0000000000..0e68e6e7ad
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/aorsmul_1.asm
@@ -0,0 +1,398 @@
+dnl Alpha ev6 mpn_addmul_1 and mpn_submul_1.
+
+dnl Copyright 2000, 2003-2005, 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 42
+C EV5: 18
+C EV6: 3.5
+
+C INPUT PARAMETERS
+define(`rp', `r16')
+define(`up', `r17')
+define(`n', `r18')
+define(`v0', `r19')
+
+dnl This code was written in cooperation with ev6 pipeline expert Steve Root.
+
+dnl The stores can issue a cycle late so we have paired no-op's to 'catch'
+dnl them, so that further disturbance to the schedule is damped.
+
+dnl We couldn't pair the loads, because the entangled schedule of the carry's
+dnl has to happen on one side {0} of the machine.
+
+dnl This is a great schedule for the d_cache, a poor schedule for the b_cache.
+dnl The lockup on U0 means that any stall can't be recovered from. Consider a
+dnl ldq in L1, say that load gets stalled because it collides with a fill from
+dnl the b_cache. On the next cycle, this load gets priority. If first looks
+dnl at L0, and goes there. The instruction we intended for L0 gets to look at
+dnl L1, which is NOT where we want it. It either stalls 1, because it can't
+dnl go in L0, or goes there, and causes a further instruction to stall.
+
+dnl So for b_cache, we're likely going to want to put one or more cycles back
+dnl into the code! And, of course, put in lds prefetch for the rp[] operand.
+dnl At a place where we have an mt followed by a bookkeeping, put the
+dnl bookkeeping in upper, and the prefetch into lower.
+
+dnl Note, the ldq's and stq's are at the end of the quadpacks. Note, we'd
+dnl like not to have an ldq or an stq to preceded a conditional branch in a
+dnl quadpack. The conditional branch moves the retire pointer one cycle
+dnl later.
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `addq')
+ define(`CMPCY', `cmpult $2,$1')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `subq')
+ define(`CMPCY', `cmpult $1,$2')
+ define(`func', `mpn_submul_1')
+')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+ASM_START()
+PROLOGUE(func)
+ ldq r3, 0(up) C
+ and r18, 7, r20 C
+ lda r18, -9(r18) C
+ cmpeq r20, 1, r21 C
+ beq r21, $L1 C
+
+$1mod8: ldq r5, 0(rp) C
+ mulq v0, r3, r7 C
+ umulh v0, r3, r8 C
+ ADDSUB r5, r7, r23 C
+ CMPCY( r5, r23), r20 C
+ addq r8, r20, r0 C
+ stq r23, 0(rp) C
+ bge r18, $ent1 C
+ ret r31, (r26), 1 C
+
+$L1: lda r8, 0(r31) C zero carry reg
+ lda r24, 0(r31) C zero carry reg
+ cmpeq r20, 2, r21 C
+ bne r21, $2mod8 C
+ cmpeq r20, 3, r21 C
+ bne r21, $3mod8 C
+ cmpeq r20, 4, r21 C
+ bne r21, $4mod8 C
+ cmpeq r20, 5, r21 C
+ bne r21, $5mod8 C
+ cmpeq r20, 6, r21 C
+ bne r21, $6mod8 C
+ cmpeq r20, 7, r21 C
+ beq r21, $0mod8 C
+
+$7mod8: ldq r5, 0(rp) C
+ lda up, 8(up) C
+ mulq v0, r3, r7 C
+ umulh v0, r3, r24 C
+ ADDSUB r5, r7, r23 C
+ CMPCY( r5, r23), r20 C
+ addq r24, r20, r24 C
+ stq r23, 0(rp) C
+ lda rp, 8(rp) C
+ ldq r3, 0(up) C
+$6mod8: ldq r1, 8(up) C
+ mulq v0, r3, r25 C
+ umulh v0, r3, r3 C
+ mulq v0, r1, r28 C
+ ldq r0, 16(up) C
+ ldq r4, 0(rp) C
+ umulh v0, r1, r8 C
+ ldq r1, 24(up) C
+ lda up, 48(up) C L1 bookkeeping
+ mulq v0, r0, r2 C
+ ldq r5, 8(rp) C
+ lda rp, -32(rp) C L1 bookkeeping
+ umulh v0, r0, r6 C
+ ADDSUB r4, r25, r25 C lo + acc
+ mulq v0, r1, r7 C
+ br r31, $ent6 C
+
+$ent1: lda up, 8(up) C
+ lda rp, 8(rp) C
+ lda r8, 0(r0) C
+ ldq r3, 0(up) C
+$0mod8: ldq r1, 8(up) C
+ mulq v0, r3, r2 C
+ umulh v0, r3, r6 C
+ mulq v0, r1, r7 C
+ ldq r0, 16(up) C
+ ldq r4, 0(rp) C
+ umulh v0, r1, r24 C
+ ldq r1, 24(up) C
+ mulq v0, r0, r25 C
+ ldq r5, 8(rp) C
+ umulh v0, r0, r3 C
+ ADDSUB r4, r2, r2 C lo + acc
+ mulq v0, r1, r28 C
+ lda rp, -16(rp) C
+ br r31, $ent0 C
+
+$3mod8: ldq r5, 0(rp) C
+ lda up, 8(up) C
+ mulq v0, r3, r7 C
+ umulh v0, r3, r8 C
+ ADDSUB r5, r7, r23 C
+ CMPCY( r5, r23), r20 C
+ addq r8, r20, r24 C
+ stq r23, 0(rp) C
+ lda rp, 8(rp) C
+ ldq r3, 0(up) C
+$2mod8: ldq r1, 8(up) C
+ mulq v0, r3, r25 C
+ umulh v0, r3, r3 C
+ mulq v0, r1, r28 C
+ ble r18, $n23 C
+ ldq r0, 16(up) C
+ ldq r4, 0(rp) C
+ umulh v0, r1, r8 C
+ ldq r1, 24(up) C
+ lda up, 16(up) C L1 bookkeeping
+ mulq v0, r0, r2 C
+ ldq r5, 8(rp) C
+ lda rp, 0(rp) C L1 bookkeeping
+ umulh v0, r0, r6 C
+ ADDSUB r4, r25, r25 C lo + acc
+ mulq v0, r1, r7 C
+ br r31, $ent2 C
+
+$5mod8: ldq r5, 0(rp) C
+ lda up, 8(up) C
+ mulq v0, r3, r7 C
+ umulh v0, r3, r24 C
+ ADDSUB r5, r7, r23 C
+ CMPCY( r5, r23), r20 C
+ addq r24, r20, r8 C
+ stq r23, 0(rp) C
+ lda rp, 8(rp) C
+ ldq r3, 0(up) C
+$4mod8: ldq r1, 8(up) C
+ mulq v0, r3, r2 C
+ umulh v0, r3, r6 C
+ mulq v0, r1, r7 C
+ ldq r0, 16(up) C
+ ldq r4, 0(rp) C
+ umulh v0, r1, r24 C
+ ldq r1, 24(up) C
+ lda up, 32(up) C L1 bookkeeping
+ mulq v0, r0, r25 C
+ ldq r5, 8(rp) C
+ lda rp, 16(rp) C L1 bookkeeping
+ umulh v0, r0, r3 C
+ ADDSUB r4, r2, r2 C lo + acc
+ mulq v0, r1, r28 C
+ CMPCY( r4, r2), r20 C L0 lo add => carry
+ ADDSUB r2, r8, r22 C U0 hi add => answer
+ ble r18, $Lend C
+ ALIGN(16)
+$Loop:
+ bis r31, r31, r31 C U1 mt
+ CMPCY( r2, r22), r21 C L0 hi add => carry
+ addq r6, r20, r6 C U0 hi mul + carry
+ ldq r0, 0(up) C
+
+ bis r31, r31, r31 C U1 mt
+ ADDSUB r5, r7, r7 C L0 lo + acc
+ addq r6, r21, r6 C U0 hi mul + carry
+ ldq r4, 0(rp) C L1
+
+ umulh v0, r1, r8 C U1
+ CMPCY( r5, r7), r20 C L0 lo add => carry
+ ADDSUB r7, r6, r23 C U0 hi add => answer
+ ldq r1, 8(up) C L1
+
+ mulq v0, r0, r2 C U1
+ CMPCY( r7, r23), r21 C L0 hi add => carry
+ addq r24, r20, r24 C U0 hi mul + carry
+ ldq r5, 8(rp) C L1
+
+ umulh v0, r0, r6 C U1
+ ADDSUB r4, r25, r25 C U0 lo + acc
+ stq r22, -16(rp) C L0
+ stq r23, -8(rp) C L1
+
+ bis r31, r31, r31 C L0 st slosh
+ mulq v0, r1, r7 C U1
+ bis r31, r31, r31 C L1 st slosh
+ addq r24, r21, r24 C U0 hi mul + carry
+$ent2:
+ CMPCY( r4, r25), r20 C L0 lo add => carry
+ bis r31, r31, r31 C U1 mt
+ lda r18, -8(r18) C L1 bookkeeping
+ ADDSUB r25, r24, r22 C U0 hi add => answer
+
+ bis r31, r31, r31 C U1 mt
+ CMPCY( r25, r22), r21 C L0 hi add => carry
+ addq r3, r20, r3 C U0 hi mul + carry
+ ldq r0, 16(up) C L1
+
+ bis r31, r31, r31 C U1 mt
+ ADDSUB r5, r28, r28 C L0 lo + acc
+ addq r3, r21, r3 C U0 hi mul + carry
+ ldq r4, 16(rp) C L1
+
+ umulh v0, r1, r24 C U1
+ CMPCY( r5, r28), r20 C L0 lo add => carry
+ ADDSUB r28, r3, r23 C U0 hi add => answer
+ ldq r1, 24(up) C L1
+
+ mulq v0, r0, r25 C U1
+ CMPCY( r28, r23), r21 C L0 hi add => carry
+ addq r8, r20, r8 C U0 hi mul + carry
+ ldq r5, 24(rp) C L1
+
+ umulh v0, r0, r3 C U1
+ ADDSUB r4, r2, r2 C U0 lo + acc
+ stq r22, 0(rp) C L0
+ stq r23, 8(rp) C L1
+
+ bis r31, r31, r31 C L0 st slosh
+ mulq v0, r1, r28 C U1
+ bis r31, r31, r31 C L1 st slosh
+ addq r8, r21, r8 C U0 hi mul + carry
+$ent0:
+ CMPCY( r4, r2), r20 C L0 lo add => carry
+ bis r31, r31, r31 C U1 mt
+ lda up, 64(up) C L1 bookkeeping
+ ADDSUB r2, r8, r22 C U0 hi add => answer
+
+ bis r31, r31, r31 C U1 mt
+ CMPCY( r2, r22), r21 C L0 hi add => carry
+ addq r6, r20, r6 C U0 hi mul + carry
+ ldq r0, -32(up) C L1
+
+ bis r31, r31, r31 C U1 mt
+ ADDSUB r5, r7, r7 C L0 lo + acc
+ addq r6, r21, r6 C U0 hi mul + carry
+ ldq r4, 32(rp) C L1
+
+ umulh v0, r1, r8 C U1
+ CMPCY( r5, r7), r20 C L0 lo add => carry
+ ADDSUB r7, r6, r23 C U0 hi add => answer
+ ldq r1, -24(up) C L1
+
+ mulq v0, r0, r2 C U1
+ CMPCY( r7, r23), r21 C L0 hi add => carry
+ addq r24, r20, r24 C U0 hi mul + carry
+ ldq r5, 40(rp) C L1
+
+ umulh v0, r0, r6 C U1
+ ADDSUB r4, r25, r25 C U0 lo + acc
+ stq r22, 16(rp) C L0
+ stq r23, 24(rp) C L1
+
+ bis r31, r31, r31 C L0 st slosh
+ mulq v0, r1, r7 C U1
+ bis r31, r31, r31 C L1 st slosh
+ addq r24, r21, r24 C U0 hi mul + carry
+$ent6:
+ CMPCY( r4, r25), r20 C L0 lo add => carry
+ bis r31, r31, r31 C U1 mt
+ lda rp, 64(rp) C L1 bookkeeping
+ ADDSUB r25, r24, r22 C U0 hi add => answer
+
+ bis r31, r31, r31 C U1 mt
+ CMPCY( r25, r22), r21 C L0 hi add => carry
+ addq r3, r20, r3 C U0 hi mul + carry
+ ldq r0, -16(up) C L1
+
+ bis r31, r31, r31 C U1 mt
+ ADDSUB r5, r28, r28 C L0 lo + acc
+ addq r3, r21, r3 C U0 hi mul + carry
+ ldq r4, -16(rp) C L1
+
+ umulh v0, r1, r24 C U1
+ CMPCY( r5, r28), r20 C L0 lo add => carry
+ ADDSUB r28, r3, r23 C U0 hi add => answer
+ ldq r1, -8(up) C L1
+
+ mulq v0, r0, r25 C U1
+ CMPCY( r28, r23), r21 C L0 hi add => carry
+ addq r8, r20, r8 C U0 hi mul + carry
+ ldq r5, -8(rp) C L1
+
+ umulh v0, r0, r3 C U1
+ ADDSUB r4, r2, r2 C U0 lo + acc
+ stq r22, -32(rp) C L0
+ stq r23, -24(rp) C L1
+
+ bis r31, r31, r31 C L0 st slosh
+ mulq v0, r1, r28 C U1
+ bis r31, r31, r31 C L1 st slosh
+ addq r8, r21, r8 C U0 hi mul + carry
+
+ CMPCY( r4, r2), r20 C L0 lo add => carry
+ ADDSUB r2, r8, r22 C U0 hi add => answer
+ ldl r31, 256(up) C prefetch up[]
+ bgt r18, $Loop C U1 bookkeeping
+
+$Lend: CMPCY( r2, r22), r21 C
+ addq r6, r20, r6 C
+ ADDSUB r5, r7, r7 C
+ addq r6, r21, r6 C
+ ldq r4, 0(rp) C
+ umulh v0, r1, r8 C
+ CMPCY( r5, r7), r20 C
+ ADDSUB r7, r6, r23 C
+ CMPCY(r7, r23), r21 C
+ addq r24, r20, r24 C
+ ldq r5, 8(rp) C
+ ADDSUB r4, r25, r25 C
+ stq r22, -16(rp) C
+ stq r23, -8(rp) C
+ addq r24, r21, r24 C
+ br L(x)
+
+ ALIGN(16)
+$n23: ldq r4, 0(rp) C
+ ldq r5, 8(rp) C
+ umulh v0, r1, r8 C
+ ADDSUB r4, r25, r25 C
+L(x): CMPCY( r4, r25), r20 C
+ ADDSUB r25, r24, r22 C
+ CMPCY( r25, r22), r21 C
+ addq r3, r20, r3 C
+ ADDSUB r5, r28, r28 C
+ addq r3, r21, r3 C
+ CMPCY( r5, r28), r20 C
+ ADDSUB r28, r3, r23 C
+ CMPCY( r28, r23), r21 C
+ addq r8, r20, r8 C
+ stq r22, 0(rp) C
+ stq r23, 8(rp) C
+ addq r8, r21, r0 C
+ ret r31, (r26), 1 C
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/gmp-mparam.h b/gmp/mpn/alpha/ev6/gmp-mparam.h
new file mode 100644
index 0000000000..e51d6b0d15
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/gmp-mparam.h
@@ -0,0 +1,209 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004, 2005, 2008-2010, 2014 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+#define DIVEXACT_BY3_METHOD 0 /* override ../diveby3.asm */
+
+/* 500 MHz 21164 (agnesi.math.su.se) */
+/* FFT tuning limit = 20000000 */
+/* Generated by tuneup.c, 2014-03-14, gcc 3.3 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* preinv always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 2
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 10
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 21
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 7
+#define USE_PREINV_DIVREM_1 1 /* preinv always */
+#define DIV_QR_1N_PI1_METHOD 2
+#define DIV_QR_1_NORM_THRESHOLD 5
+#define DIV_QR_1_UNNORM_THRESHOLD 1
+#define DIV_QR_2_PI2_THRESHOLD 8
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 20
+
+#define MUL_TOOM22_THRESHOLD 32
+#define MUL_TOOM33_THRESHOLD 117
+#define MUL_TOOM44_THRESHOLD 124
+#define MUL_TOOM6H_THRESHOLD 230
+#define MUL_TOOM8H_THRESHOLD 357
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 107
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 88
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 105
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 136
+
+#define SQR_BASECASE_THRESHOLD 0 /* always */
+#define SQR_TOOM2_THRESHOLD 59
+#define SQR_TOOM3_THRESHOLD 123
+#define SQR_TOOM4_THRESHOLD 163
+#define SQR_TOOM6_THRESHOLD 333
+#define SQR_TOOM8_THRESHOLD 0 /* always */
+
+#define MULMID_TOOM42_THRESHOLD 52
+
+#define MULMOD_BNM1_THRESHOLD 19
+#define SQRMOD_BNM1_THRESHOLD 5
+
+#define MUL_FFT_MODF_THRESHOLD 468 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 468, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 19, 7}, { 10, 6}, \
+ { 24, 7}, { 13, 6}, { 27, 7}, { 14, 6}, \
+ { 29, 7}, { 17, 6}, { 35, 7}, { 29, 8}, \
+ { 15, 7}, { 32, 8}, { 17, 7}, { 35, 8}, \
+ { 19, 7}, { 39, 8}, { 29, 9}, { 15, 8}, \
+ { 35, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 51, 9}, { 27, 8}, { 55, 9}, { 35, 8}, \
+ { 71, 9}, { 39,10}, { 23, 9}, { 55,10}, \
+ { 31, 9}, { 67,10}, { 39, 9}, { 79,10}, \
+ { 47, 9}, { 95,10}, { 55,11}, { 31,10}, \
+ { 79,11}, { 47,10}, { 103,12}, { 31,11}, \
+ { 63,10}, { 135,11}, { 79,10}, { 167,11}, \
+ { 95,10}, { 199,11}, { 111,12}, { 63,11}, \
+ { 143,10}, { 287, 9}, { 575,11}, { 159,10}, \
+ { 319,12}, { 95,11}, { 191,10}, { 383,11}, \
+ { 207,13}, { 63,12}, { 127,11}, { 255,10}, \
+ { 511,11}, { 271,10}, { 543,11}, { 287,10}, \
+ { 575,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 335,10}, { 671,11}, { 351,10}, { 703,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,12}, \
+ { 223,11}, { 447,13}, { 127,12}, { 255,11}, \
+ { 543,12}, { 287,11}, { 575,10}, { 1151,11}, \
+ { 607,12}, { 319,11}, { 671,12}, { 351,11}, \
+ { 703,13}, { 191,12}, { 383,11}, { 767,12}, \
+ { 415,11}, { 831,12}, { 447,14}, { 127,13}, \
+ { 255,12}, { 575,11}, { 1151,12}, { 607,13}, \
+ { 319,12}, { 735,13}, { 383,12}, { 767,11}, \
+ { 1535,12}, { 831,13}, { 447,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1087,13}, { 575,12}, \
+ { 1215,13}, { 639,12}, { 1343,13}, { 703,12}, \
+ { 1407,14}, { 383,13}, { 767,12}, { 1535,13}, \
+ { 831,12}, { 1663,13}, { 959,15}, { 255,14}, \
+ { 511,13}, { 1215,14}, { 639,13}, { 1407,14}, \
+ { 767,13}, { 1663,14}, { 895,13}, { 1855,15}, \
+ { 511,14}, { 16384,15}, { 32768,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 151
+#define MUL_FFT_THRESHOLD 5760
+
+#define SQR_FFT_MODF_THRESHOLD 412 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 412, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 12, 5}, { 25, 6}, \
+ { 27, 7}, { 14, 6}, { 29, 7}, { 28, 8}, \
+ { 15, 7}, { 31, 8}, { 17, 7}, { 36, 8}, \
+ { 19, 7}, { 39, 8}, { 29, 9}, { 15, 8}, \
+ { 35, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 49, 9}, { 27,10}, { 15, 9}, { 39,10}, \
+ { 23, 9}, { 51,11}, { 15,10}, { 31, 9}, \
+ { 67,10}, { 39, 9}, { 79,10}, { 47, 9}, \
+ { 95,10}, { 55,11}, { 31,10}, { 79,11}, \
+ { 47,10}, { 95,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255,11}, { 79,10}, { 159, 9}, \
+ { 319,10}, { 167,11}, { 95,10}, { 191, 9}, \
+ { 383,11}, { 111,12}, { 63,11}, { 127,10}, \
+ { 271,11}, { 143,10}, { 287, 9}, { 575,10}, \
+ { 303,11}, { 159,10}, { 319,12}, { 95,11}, \
+ { 191,10}, { 383,11}, { 207,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 511,11}, { 271,10}, \
+ { 543,11}, { 287,10}, { 575,11}, { 303,12}, \
+ { 159,11}, { 319,10}, { 639,11}, { 335,10}, \
+ { 671,11}, { 351,10}, { 703,11}, { 367,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,12}, \
+ { 223,11}, { 447,13}, { 127,12}, { 255,11}, \
+ { 543,12}, { 287,11}, { 575,10}, { 1151,11}, \
+ { 607,12}, { 319,11}, { 639,10}, { 1279,11}, \
+ { 671,12}, { 351,11}, { 703,13}, { 191,12}, \
+ { 383,11}, { 767,12}, { 415,11}, { 831,12}, \
+ { 447,11}, { 895,12}, { 479,14}, { 127,13}, \
+ { 255,12}, { 575,11}, { 1151,12}, { 607,13}, \
+ { 319,12}, { 703,11}, { 1407,12}, { 735,13}, \
+ { 383,12}, { 831,13}, { 447,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1087,13}, { 575,12}, \
+ { 1151,13}, { 639,12}, { 1279,13}, { 703,12}, \
+ { 1407,14}, { 383,13}, { 767,12}, { 1535,13}, \
+ { 831,12}, { 1663,13}, { 959,15}, { 255,14}, \
+ { 511,13}, { 1215,14}, { 639,13}, { 1407,14}, \
+ { 767,13}, { 1663,14}, { 895,13}, { 1791,15}, \
+ { 511,14}, { 16384,15}, { 32768,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 159
+#define SQR_FFT_THRESHOLD 5056
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 100
+#define MULLO_MUL_N_THRESHOLD 11355
+
+#define DC_DIV_QR_THRESHOLD 124
+#define DC_DIVAPPR_Q_THRESHOLD 438
+#define DC_BDIV_QR_THRESHOLD 153
+#define DC_BDIV_Q_THRESHOLD 318
+
+#define INV_MULMOD_BNM1_THRESHOLD 62
+#define INV_NEWTON_THRESHOLD 384
+#define INV_APPR_THRESHOLD 402
+
+#define BINV_NEWTON_THRESHOLD 381
+#define REDC_1_TO_REDC_N_THRESHOLD 110
+
+#define MU_DIV_QR_THRESHOLD 1752
+#define MU_DIVAPPR_Q_THRESHOLD 1895
+#define MUPI_DIV_QR_THRESHOLD 174
+#define MU_BDIV_QR_THRESHOLD 1387
+#define MU_BDIV_Q_THRESHOLD 1787
+
+#define POWM_SEC_TABLE 1,13,66,82,579
+
+#define MATRIX22_STRASSEN_THRESHOLD 15
+#define HGCD_THRESHOLD 318
+#define HGCD_APPR_THRESHOLD 363
+#define HGCD_REDUCE_THRESHOLD 2384
+#define GCD_DC_THRESHOLD 2504
+#define GCDEXT_DC_THRESHOLD 671
+#define JACOBI_BASE_METHOD 3
+
+#define GET_STR_DC_THRESHOLD 14
+#define GET_STR_PRECOMPUTE_THRESHOLD 25
+#define SET_STR_DC_THRESHOLD 3754
+#define SET_STR_PRECOMPUTE_THRESHOLD 8097
+
+#define FAC_DSC_THRESHOLD 951
+#define FAC_ODD_THRESHOLD 24
diff --git a/gmp/mpn/alpha/ev6/mod_1_4.asm b/gmp/mpn/alpha/ev6/mod_1_4.asm
new file mode 100644
index 0000000000..836de07c0f
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/mod_1_4.asm
@@ -0,0 +1,337 @@
+dnl Alpha mpn_mod_1s_4p
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2009, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO:
+C * Optimise. 2.75 c/l should be possible.
+C * Write a proper mpn_mod_1s_4p_cps. The code below was compiler generated.
+C * Optimise feed-in code, starting the sw pipeline in switch code.
+C * Shorten software pipeline. The mul instructions are scheduled too far
+C from their users. Fixing this will allow us to use fewer registers.
+C * If we cannot reduce register usage, write perhaps small-n basecase.
+C * Does this work for PIC?
+
+C cycles/limb
+C EV4: ?
+C EV5: 23
+C EV6: 3
+
+define(`ap', `r16')
+define(`n', `r17')
+define(`pl', `r24')
+define(`ph', `r25')
+define(`rl', `r6')
+define(`rh', `r7')
+define(`B1modb', `r1')
+define(`B2modb', `r2')
+define(`B3modb', `r3')
+define(`B4modb', `r4')
+define(`B5modb', `r5')
+
+ASM_START()
+PROLOGUE(mpn_mod_1s_4p)
+ lda r30, -64(r30)
+ stq r9, 8(r30)
+ ldq B1modb, 16(r19)
+ stq r10, 16(r30)
+ ldq B2modb, 24(r19)
+ stq r11, 24(r30)
+ ldq B3modb, 32(r19)
+ stq r12, 32(r30)
+ ldq B4modb, 40(r19)
+ stq r13, 40(r30)
+ ldq B5modb, 48(r19)
+ s8addq n, ap, ap C point ap at vector end
+
+ and n, 3, r0
+ lda n, -4(n)
+ beq r0, L(b0)
+ lda r6, -2(r0)
+ blt r6, L(b1)
+ beq r6, L(b2)
+
+L(b3): ldq r21, -16(ap)
+ ldq r22, -8(ap)
+ ldq r20, -24(ap)
+ mulq r21, B1modb, r8
+ umulh r21, B1modb, r12
+ mulq r22, B2modb, r9
+ umulh r22, B2modb, r13
+ addq r8, r20, pl
+ cmpult pl, r8, r0
+ addq r0, r12, ph
+ addq r9, pl, rl
+ cmpult rl, r9, r0
+ addq r13, ph, ph
+ addq r0, ph, rh
+ lda ap, -56(ap)
+ br L(com)
+
+L(b0): ldq r21, -24(ap)
+ ldq r22, -16(ap)
+ ldq r23, -8(ap)
+ ldq r20, -32(ap)
+ mulq r21, B1modb, r8
+ umulh r21, B1modb, r12
+ mulq r22, B2modb, r9
+ umulh r22, B2modb, r13
+ mulq r23, B3modb, r10
+ umulh r23, B3modb, r27
+ addq r8, r20, pl
+ cmpult pl, r8, r0
+ addq r0, r12, ph
+ addq r9, pl, pl
+ cmpult pl, r9, r0
+ addq r13, ph, ph
+ addq r0, ph, ph
+ addq r10, pl, rl
+ cmpult rl, r10, r0
+ addq r27, ph, ph
+ addq r0, ph, rh
+ lda ap, -64(ap)
+ br L(com)
+
+L(b1): bis r31, r31, rh
+ ldq rl, -8(ap)
+ lda ap, -40(ap)
+ br L(com)
+
+L(b2): ldq rh, -8(ap)
+ ldq rl, -16(ap)
+ lda ap, -48(ap)
+
+L(com): ble n, L(ed3)
+ ldq r21, 8(ap)
+ ldq r22, 16(ap)
+ ldq r23, 24(ap)
+ ldq r20, 0(ap)
+ lda n, -4(n)
+ lda ap, -32(ap)
+ mulq r21, B1modb, r8
+ umulh r21, B1modb, r12
+ mulq r22, B2modb, r9
+ umulh r22, B2modb, r13
+ mulq r23, B3modb, r10
+ umulh r23, B3modb, r27
+ mulq rl, B4modb, r11
+ umulh rl, B4modb, r28
+ ble n, L(ed2)
+
+ ALIGN(16)
+L(top): ldq r21, 8(ap)
+ mulq rh, B5modb, rl
+ addq r8, r20, pl
+ ldq r22, 16(ap)
+ cmpult pl, r8, r0
+ umulh rh, B5modb, rh
+ ldq r23, 24(ap)
+ addq r0, r12, ph
+ addq r9, pl, pl
+ mulq r21, B1modb, r8
+ cmpult pl, r9, r0
+ addq r13, ph, ph
+ umulh r21, B1modb, r12
+ lda ap, -32(ap)
+ addq r0, ph, ph
+ addq r10, pl, pl
+ mulq r22, B2modb, r9
+ cmpult pl, r10, r0
+ addq r27, ph, ph
+ addq r11, pl, pl
+ umulh r22, B2modb, r13
+ addq r0, ph, ph
+ cmpult pl, r11, r0
+ addq r28, ph, ph
+ mulq r23, B3modb, r10
+ ldq r20, 32(ap)
+ addq pl, rl, rl
+ umulh r23, B3modb, r27
+ addq r0, ph, ph
+ cmpult rl, pl, r0
+ mulq rl, B4modb, r11
+ addq ph, rh, rh
+ umulh rl, B4modb, r28
+ addq r0, rh, rh
+ lda n, -4(n)
+ bgt n, L(top)
+
+L(ed2): mulq rh, B5modb, rl
+ addq r8, r20, pl
+ umulh rh, B5modb, rh
+ cmpult pl, r8, r0
+ addq r0, r12, ph
+ addq r9, pl, pl
+ cmpult pl, r9, r0
+ addq r13, ph, ph
+ addq r0, ph, ph
+ addq r10, pl, pl
+ cmpult pl, r10, r0
+ addq r27, ph, ph
+ addq r11, pl, pl
+ addq r0, ph, ph
+ cmpult pl, r11, r0
+ addq r28, ph, ph
+ addq pl, rl, rl
+ addq r0, ph, ph
+ cmpult rl, pl, r0
+ addq ph, rh, rh
+ addq r0, rh, rh
+
+L(ed3): mulq rh, B1modb, r8
+ umulh rh, B1modb, rh
+ addq r8, rl, rl
+ cmpult rl, r8, r0
+ addq r0, rh, rh
+
+ ldq r24, 8(r19) C cnt
+ sll rh, r24, rh
+ subq r31, r24, r25
+ srl rl, r25, r2
+ sll rl, r24, rl
+ or r2, rh, rh
+
+ ldq r23, 0(r19) C bi
+ mulq rh, r23, r8
+ umulh rh, r23, r9
+ addq rh, 1, r7
+ addq r8, rl, r8 C ql
+ cmpult r8, rl, r0
+ addq r9, r7, r9
+ addq r0, r9, r9 C qh
+ mulq r9, r18, r21 C qh * b
+ subq rl, r21, rl
+ cmpult r8, rl, r0 C rl > ql
+ negq r0, r0
+ and r0, r18, r0
+ addq rl, r0, rl
+ cmpule r18, rl, r0 C rl >= b
+ negq r0, r0
+ and r0, r18, r0
+ subq rl, r0, rl
+
+ srl rl, r24, r0
+
+ ldq r9, 8(r30)
+ ldq r10, 16(r30)
+ ldq r11, 24(r30)
+ ldq r12, 32(r30)
+ ldq r13, 40(r30)
+ lda r30, 64(r30)
+ ret r31, (r26), 1
+EPILOGUE()
+
+PROLOGUE(mpn_mod_1s_4p_cps,gp)
+ lda r30, -32(r30)
+ stq r26, 0(r30)
+ stq r9, 8(r30)
+ stq r10, 16(r30)
+ stq r11, 24(r30)
+ mov r16, r11
+ LEA( r4, __clz_tab)
+ lda r10, 65(r31)
+ cmpbge r31, r17, r1
+ srl r1, 1, r1
+ xor r1, 127, r1
+ addq r1, r4, r1
+ ldq_u r2, 0(r1)
+ extbl r2, r1, r2
+ s8subq r2, 7, r2
+ srl r17, r2, r3
+ subq r10, r2, r10
+ addq r3, r4, r3
+ ldq_u r1, 0(r3)
+ extbl r1, r3, r1
+ subq r10, r1, r10
+ sll r17, r10, r9
+ mov r9, r16
+ jsr r26, mpn_invert_limb
+ ldah r29, 0(r26)
+ subq r31, r10, r2
+ lda r1, 1(r31)
+ sll r1, r10, r1
+ subq r31, r9, r3
+ srl r0, r2, r2
+ ldq r26, 0(r30)
+ bis r2, r1, r2
+ lda r29, 0(r29)
+ stq r0, 0(r11)
+ stq r10, 8(r11)
+ mulq r2, r3, r2
+ srl r2, r10, r3
+ umulh r2, r0, r1
+ stq r3, 16(r11)
+ mulq r2, r0, r3
+ ornot r31, r1, r1
+ subq r1, r2, r1
+ mulq r1, r9, r1
+ addq r1, r9, r2
+ cmpule r1, r3, r3
+ cmoveq r3, r2, r1
+ srl r1, r10, r3
+ umulh r1, r0, r2
+ stq r3, 24(r11)
+ mulq r1, r0, r3
+ ornot r31, r2, r2
+ subq r2, r1, r2
+ mulq r2, r9, r2
+ addq r2, r9, r1
+ cmpule r2, r3, r3
+ cmoveq r3, r1, r2
+ srl r2, r10, r1
+ umulh r2, r0, r3
+ stq r1, 32(r11)
+ mulq r2, r0, r1
+ ornot r31, r3, r3
+ subq r3, r2, r3
+ mulq r3, r9, r3
+ addq r3, r9, r2
+ cmpule r3, r1, r1
+ cmoveq r1, r2, r3
+ srl r3, r10, r2
+ umulh r3, r0, r1
+ stq r2, 40(r11)
+ mulq r3, r0, r0
+ ornot r31, r1, r1
+ subq r1, r3, r1
+ mulq r1, r9, r1
+ addq r1, r9, r9
+ cmpule r1, r0, r0
+ cmoveq r0, r9, r1
+ ldq r9, 8(r30)
+ srl r1, r10, r1
+ ldq r10, 16(r30)
+ stq r1, 48(r11)
+ ldq r11, 24(r30)
+ lda r30, 32(r30)
+ ret r31, (r26), 1
+EPILOGUE()
diff --git a/gmp/mpn/alpha/ev6/mul_1.asm b/gmp/mpn/alpha/ev6/mul_1.asm
new file mode 100644
index 0000000000..8ee19cd429
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/mul_1.asm
@@ -0,0 +1,496 @@
+dnl Alpha ev6 mpn_mul_1 -- Multiply a limb vector with a limb and store the
+dnl result in a second limb vector.
+
+dnl Copyright 2000, 2001, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r16
+C s1_ptr r17
+C size r18
+C s2_limb r19
+
+C This code runs at 2.25 cycles/limb on EV6.
+
+C This code was written in close cooperation with ev6 pipeline expert
+C Steve Root. Any errors are tege's fault, though.
+
+C Code structure:
+
+C code for n < 8
+C code for n > 8 code for (n mod 8)
+C code for (n div 8) feed-in code
+C 8-way unrolled loop
+C wind-down code
+
+C Some notes about unrolled loop:
+C
+C r1-r8 multiplies and workup
+C r21-r28 multiplies and workup
+C r9-r12 loads
+C r0 -1
+C r20,r29,r13-r15 scramble
+C
+C We're doing 7 of the 8 carry propagations with a br fixup code and 1 with a
+C put-the-carry-into-hi. The idea is that these branches are very rarely
+C taken, and since a non-taken branch consumes no resources, that is better
+C than an addq.
+C
+C Software pipeline: a load in cycle #09, feeds a mul in cycle #16, feeds an
+C add NEXT cycle #09 which feeds a store in NEXT cycle #02
+
+C The code could use some further work:
+C 1. Speed up really small multiplies. The default alpha/mul_1.asm code is
+C faster than this for size < 3.
+C 2. Improve feed-in code, perhaps with the equivalent of switch(n%8) unless
+C that is too costly.
+C 3. Consider using 4-way unrolling, even if that runs slower.
+C 4. Reduce register usage. In particular, try to avoid using r29.
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ cmpult r18, 8, r1
+ beq r1, $Large
+$Lsmall:
+ ldq r2,0(r17) C r2 = s1_limb
+ lda r18,-1(r18) C size--
+ mulq r2,r19,r3 C r3 = prod_low
+ bic r31,r31,r4 C clear cy_limb
+ umulh r2,r19,r0 C r0 = prod_high
+ beq r18,$Le1a C jump if size was == 1
+ ldq r2,8(r17) C r2 = s1_limb
+ lda r18,-1(r18) C size--
+ stq r3,0(r16)
+ beq r18,$Le2a C jump if size was == 2
+ ALIGN(8)
+$Lopa: mulq r2,r19,r3 C r3 = prod_low
+ addq r4,r0,r0 C cy_limb = cy_limb + 'cy'
+ lda r18,-1(r18) C size--
+ umulh r2,r19,r4 C r4 = cy_limb
+ ldq r2,16(r17) C r2 = s1_limb
+ lda r17,8(r17) C s1_ptr++
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ stq r3,8(r16)
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ lda r16,8(r16) C res_ptr++
+ bne r18,$Lopa
+
+$Le2a: mulq r2,r19,r3 C r3 = prod_low
+ addq r4,r0,r0 C cy_limb = cy_limb + 'cy'
+ umulh r2,r19,r4 C r4 = cy_limb
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ stq r3,8(r16)
+ addq r4,r0,r0 C cy_limb = prod_high + cy
+ ret r31,(r26),1
+$Le1a: stq r3,0(r16)
+ ret r31,(r26),1
+
+$Large:
+ lda r30, -224(r30)
+ stq r26, 0(r30)
+ stq r9, 8(r30)
+ stq r10, 16(r30)
+ stq r11, 24(r30)
+ stq r12, 32(r30)
+ stq r13, 40(r30)
+ stq r14, 48(r30)
+ stq r15, 56(r30)
+ stq r29, 64(r30)
+
+ and r18, 7, r20 C count for the first loop, 0-7
+ srl r18, 3, r18 C count for unrolled loop
+ bis r31, r31, r21
+ beq r20, $L_8_or_more C skip first loop
+
+$L_9_or_more:
+ ldq r2,0(r17) C r2 = s1_limb
+ lda r17,8(r17) C s1_ptr++
+ lda r20,-1(r20) C size--
+ mulq r2,r19,r3 C r3 = prod_low
+ umulh r2,r19,r21 C r21 = prod_high
+ beq r20,$Le1b C jump if size was == 1
+ bis r31, r31, r0 C FIXME: shouldn't need this
+ ldq r2,0(r17) C r2 = s1_limb
+ lda r17,8(r17) C s1_ptr++
+ lda r20,-1(r20) C size--
+ stq r3,0(r16)
+ lda r16,8(r16) C res_ptr++
+ beq r20,$Le2b C jump if size was == 2
+ ALIGN(8)
+$Lopb: mulq r2,r19,r3 C r3 = prod_low
+ addq r21,r0,r0 C cy_limb = cy_limb + 'cy'
+ lda r20,-1(r20) C size--
+ umulh r2,r19,r21 C r21 = prod_high
+ ldq r2,0(r17) C r2 = s1_limb
+ lda r17,8(r17) C s1_ptr++
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ stq r3,0(r16)
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ lda r16,8(r16) C res_ptr++
+ bne r20,$Lopb
+
+$Le2b: mulq r2,r19,r3 C r3 = prod_low
+ addq r21,r0,r0 C cy_limb = cy_limb + 'cy'
+ umulh r2,r19,r21 C r21 = prod_high
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ stq r3,0(r16)
+ lda r16,8(r16) C res_ptr++
+ addq r21,r0,r21 C cy_limb = prod_high + cy
+ br r31, $L_8_or_more
+$Le1b: stq r3,0(r16)
+ lda r16,8(r16) C res_ptr++
+
+$L_8_or_more:
+ lda r0, -1(r31) C put -1 in r0, for tricky loop control
+ lda r17, -32(r17) C L1 bookkeeping
+ lda r18, -1(r18) C decrement count
+
+ ldq r9, 32(r17) C L1
+ ldq r10, 40(r17) C L1
+ mulq r9, r19, r22 C U1 #07
+ ldq r11, 48(r17) C L1
+ umulh r9, r19, r23 C U1 #08
+ ldq r12, 56(r17) C L1
+ mulq r10, r19, r24 C U1 #09
+ ldq r9, 64(r17) C L1
+
+ lda r17, 64(r17) C L1 bookkeeping
+
+ umulh r10, r19, r25 C U1 #11
+ mulq r11, r19, r26 C U1 #12
+ umulh r11, r19, r27 C U1 #13
+ mulq r12, r19, r28 C U1 #14
+ ldq r10, 8(r17) C L1
+ umulh r12, r19, r1 C U1 #15
+ ldq r11, 16(r17) C L1
+ mulq r9, r19, r2 C U1 #16
+ ldq r12, 24(r17) C L1
+ umulh r9, r19, r3 C U1 #17
+ addq r21, r22, r13 C L1 mov
+ mulq r10, r19, r4 C U1 #18
+ addq r23, r24, r22 C L0 sum 2 mul's
+ cmpult r13, r21, r14 C L1 carry from sum
+ bgt r18, $L_16_or_more
+
+ cmpult r22, r24, r24 C U0 carry from sum
+ umulh r10, r19, r5 C U1 #02
+ addq r25, r26, r23 C U0 sum 2 mul's
+ mulq r11, r19, r6 C U1 #03
+ cmpult r23, r26, r25 C U0 carry from sum
+ umulh r11, r19, r7 C U1 #04
+ addq r27, r28, r28 C U0 sum 2 mul's
+ mulq r12, r19, r8 C U1 #05
+ cmpult r28, r27, r15 C L0 carry from sum
+ lda r16, 32(r16) C L1 bookkeeping
+ addq r13, r31, r13 C U0 start carry cascade
+ umulh r12, r19, r21 C U1 #06
+ br r31, $ret0c
+
+$L_16_or_more:
+C ---------------------------------------------------------------
+ subq r18,1,r18
+ cmpult r22, r24, r24 C U0 carry from sum
+ ldq r9, 32(r17) C L1
+
+ umulh r10, r19, r5 C U1 #02
+ addq r25, r26, r23 C U0 sum 2 mul's
+ mulq r11, r19, r6 C U1 #03
+ cmpult r23, r26, r25 C U0 carry from sum
+ umulh r11, r19, r7 C U1 #04
+ addq r27, r28, r28 C U0 sum 2 mul's
+ mulq r12, r19, r8 C U1 #05
+ cmpult r28, r27, r15 C L0 carry from sum
+ lda r16, 32(r16) C L1 bookkeeping
+ addq r13, r31, r13 C U0 start carry cascade
+
+ umulh r12, r19, r21 C U1 #06
+C beq r13, $fix0w C U0
+$ret0w: addq r22, r14, r26 C L0
+ ldq r10, 40(r17) C L1
+
+ mulq r9, r19, r22 C U1 #07
+ beq r26, $fix1w C U0
+$ret1w: addq r23, r24, r27 C L0
+ ldq r11, 48(r17) C L1
+
+ umulh r9, r19, r23 C U1 #08
+ beq r27, $fix2w C U0
+$ret2w: addq r28, r25, r28 C L0
+ ldq r12, 56(r17) C L1
+
+ mulq r10, r19, r24 C U1 #09
+ beq r28, $fix3w C U0
+$ret3w: addq r1, r2, r20 C L0 sum 2 mul's
+ ldq r9, 64(r17) C L1
+
+ addq r3, r4, r2 C L0 #10 2 mul's
+ lda r17, 64(r17) C L1 bookkeeping
+ cmpult r20, r1, r29 C U0 carry from sum
+
+ umulh r10, r19, r25 C U1 #11
+ cmpult r2, r4, r4 C U0 carry from sum
+ stq r13, -32(r16) C L0
+ stq r26, -24(r16) C L1
+
+ mulq r11, r19, r26 C U1 #12
+ addq r5, r6, r14 C U0 sum 2 mul's
+ stq r27, -16(r16) C L0
+ stq r28, -8(r16) C L1
+
+ umulh r11, r19, r27 C U1 #13
+ cmpult r14, r6, r3 C U0 carry from sum
+C could do cross-jumping here:
+C bra $L_middle_of_unrolled_loop
+ mulq r12, r19, r28 C U1 #14
+ addq r7, r3, r5 C L0 eat carry
+ addq r20, r15, r20 C U0 carry cascade
+ ldq r10, 8(r17) C L1
+
+ umulh r12, r19, r1 C U1 #15
+ beq r20, $fix4 C U0
+$ret4w: addq r2, r29, r6 C L0
+ ldq r11, 16(r17) C L1
+
+ mulq r9, r19, r2 C U1 #16
+ beq r6, $fix5 C U0
+$ret5w: addq r14, r4, r7 C L0
+ ldq r12, 24(r17) C L1
+
+ umulh r9, r19, r3 C U1 #17
+ beq r7, $fix6 C U0
+$ret6w: addq r5, r8, r8 C L0 sum 2
+ addq r21, r22, r13 C L1 sum 2 mul's
+
+ mulq r10, r19, r4 C U1 #18
+ addq r23, r24, r22 C L0 sum 2 mul's
+ cmpult r13, r21, r14 C L1 carry from sum
+ ble r18, $Lend C U0
+C ---------------------------------------------------------------
+ ALIGN(16)
+$Loop:
+ umulh r0, r18, r18 C U1 #01 decrement r18!
+ cmpult r8, r5, r29 C L0 carry from last bunch
+ cmpult r22, r24, r24 C U0 carry from sum
+ ldq r9, 32(r17) C L1
+
+ umulh r10, r19, r5 C U1 #02
+ addq r25, r26, r23 C U0 sum 2 mul's
+ stq r20, 0(r16) C L0
+ stq r6, 8(r16) C L1
+
+ mulq r11, r19, r6 C U1 #03
+ cmpult r23, r26, r25 C U0 carry from sum
+ stq r7, 16(r16) C L0
+ stq r8, 24(r16) C L1
+
+ umulh r11, r19, r7 C U1 #04
+ bis r31, r31, r31 C L0 st slosh
+ bis r31, r31, r31 C L1 st slosh
+ addq r27, r28, r28 C U0 sum 2 mul's
+
+ mulq r12, r19, r8 C U1 #05
+ cmpult r28, r27, r15 C L0 carry from sum
+ lda r16, 64(r16) C L1 bookkeeping
+ addq r13, r29, r13 C U0 start carry cascade
+
+ umulh r12, r19, r21 C U1 #06
+ beq r13, $fix0 C U0
+$ret0: addq r22, r14, r26 C L0
+ ldq r10, 40(r17) C L1
+
+ mulq r9, r19, r22 C U1 #07
+ beq r26, $fix1 C U0
+$ret1: addq r23, r24, r27 C L0
+ ldq r11, 48(r17) C L1
+
+ umulh r9, r19, r23 C U1 #08
+ beq r27, $fix2 C U0
+$ret2: addq r28, r25, r28 C L0
+ ldq r12, 56(r17) C L1
+
+ mulq r10, r19, r24 C U1 #09
+ beq r28, $fix3 C U0
+$ret3: addq r1, r2, r20 C L0 sum 2 mul's
+ ldq r9, 64(r17) C L1
+
+ addq r3, r4, r2 C L0 #10 2 mul's
+ bis r31, r31, r31 C U1 mul hole
+ lda r17, 64(r17) C L1 bookkeeping
+ cmpult r20, r1, r29 C U0 carry from sum
+
+ umulh r10, r19, r25 C U1 #11
+ cmpult r2, r4, r4 C U0 carry from sum
+ stq r13, -32(r16) C L0
+ stq r26, -24(r16) C L1
+
+ mulq r11, r19, r26 C U1 #12
+ addq r5, r6, r14 C U0 sum 2 mul's
+ stq r27, -16(r16) C L0
+ stq r28, -8(r16) C L1
+
+ umulh r11, r19, r27 C U1 #13
+ bis r31, r31, r31 C L0 st slosh
+ bis r31, r31, r31 C L1 st slosh
+ cmpult r14, r6, r3 C U0 carry from sum
+$L_middle_of_unrolled_loop:
+ mulq r12, r19, r28 C U1 #14
+ addq r7, r3, r5 C L0 eat carry
+ addq r20, r15, r20 C U0 carry cascade
+ ldq r10, 8(r17) C L1
+
+ umulh r12, r19, r1 C U1 #15
+ beq r20, $fix4 C U0
+$ret4: addq r2, r29, r6 C L0
+ ldq r11, 16(r17) C L1
+
+ mulq r9, r19, r2 C U1 #16
+ beq r6, $fix5 C U0
+$ret5: addq r14, r4, r7 C L0
+ ldq r12, 24(r17) C L1
+
+ umulh r9, r19, r3 C U1 #17
+ beq r7, $fix6 C U0
+$ret6: addq r5, r8, r8 C L0 sum 2
+ addq r21, r22, r13 C L1 sum 2 mul's
+
+ mulq r10, r19, r4 C U1 #18
+ addq r23, r24, r22 C L0 sum 2 mul's
+ cmpult r13, r21, r14 C L1 carry from sum
+ bgt r18, $Loop C U0
+C ---------------------------------------------------------------
+$Lend:
+ cmpult r8, r5, r29 C L0 carry from last bunch
+ cmpult r22, r24, r24 C U0 carry from sum
+
+ umulh r10, r19, r5 C U1 #02
+ addq r25, r26, r23 C U0 sum 2 mul's
+ stq r20, 0(r16) C L0
+ stq r6, 8(r16) C L1
+
+ mulq r11, r19, r6 C U1 #03
+ cmpult r23, r26, r25 C U0 carry from sum
+ stq r7, 16(r16) C L0
+ stq r8, 24(r16) C L1
+
+ umulh r11, r19, r7 C U1 #04
+ addq r27, r28, r28 C U0 sum 2 mul's
+
+ mulq r12, r19, r8 C U1 #05
+ cmpult r28, r27, r15 C L0 carry from sum
+ lda r16, 64(r16) C L1 bookkeeping
+ addq r13, r29, r13 C U0 start carry cascade
+
+ umulh r12, r19, r21 C U1 #06
+ beq r13, $fix0c C U0
+$ret0c: addq r22, r14, r26 C L0
+ beq r26, $fix1c C U0
+$ret1c: addq r23, r24, r27 C L0
+ beq r27, $fix2c C U0
+$ret2c: addq r28, r25, r28 C L0
+ beq r28, $fix3c C U0
+$ret3c: addq r1, r2, r20 C L0 sum 2 mul's
+ addq r3, r4, r2 C L0 #10 2 mul's
+ lda r17, 64(r17) C L1 bookkeeping
+ cmpult r20, r1, r29 C U0 carry from sum
+ cmpult r2, r4, r4 C U0 carry from sum
+ stq r13, -32(r16) C L0
+ stq r26, -24(r16) C L1
+ addq r5, r6, r14 C U0 sum 2 mul's
+ stq r27, -16(r16) C L0
+ stq r28, -8(r16) C L1
+ cmpult r14, r6, r3 C U0 carry from sum
+ addq r7, r3, r5 C L0 eat carry
+ addq r20, r15, r20 C U0 carry cascade
+ beq r20, $fix4c C U0
+$ret4c: addq r2, r29, r6 C L0
+ beq r6, $fix5c C U0
+$ret5c: addq r14, r4, r7 C L0
+ beq r7, $fix6c C U0
+$ret6c: addq r5, r8, r8 C L0 sum 2
+ cmpult r8, r5, r29 C L0 carry from last bunch
+ stq r20, 0(r16) C L0
+ stq r6, 8(r16) C L1
+ stq r7, 16(r16) C L0
+ stq r8, 24(r16) C L1
+ addq r29, r21, r0
+
+ ldq r26, 0(r30)
+ ldq r9, 8(r30)
+ ldq r10, 16(r30)
+ ldq r11, 24(r30)
+ ldq r12, 32(r30)
+ ldq r13, 40(r30)
+ ldq r14, 48(r30)
+ ldq r15, 56(r30)
+ ldq r29, 64(r30)
+ lda r30, 224(r30)
+ ret r31, (r26), 1
+
+C $fix0w: bis r14, r29, r14 C join carries
+C br r31, $ret0w
+$fix1w: bis r24, r14, r24 C join carries
+ br r31, $ret1w
+$fix2w: bis r25, r24, r25 C join carries
+ br r31, $ret2w
+$fix3w: bis r15, r25, r15 C join carries
+ br r31, $ret3w
+$fix0: bis r14, r29, r14 C join carries
+ br r31, $ret0
+$fix1: bis r24, r14, r24 C join carries
+ br r31, $ret1
+$fix2: bis r25, r24, r25 C join carries
+ br r31, $ret2
+$fix3: bis r15, r25, r15 C join carries
+ br r31, $ret3
+$fix4: bis r29, r15, r29 C join carries
+ br r31, $ret4
+$fix5: bis r4, r29, r4 C join carries
+ br r31, $ret5
+$fix6: addq r5, r4, r5 C can't carry twice!
+ br r31, $ret6
+$fix0c: bis r14, r29, r14 C join carries
+ br r31, $ret0c
+$fix1c: bis r24, r14, r24 C join carries
+ br r31, $ret1c
+$fix2c: bis r25, r24, r25 C join carries
+ br r31, $ret2c
+$fix3c: bis r15, r25, r15 C join carries
+ br r31, $ret3c
+$fix4c: bis r29, r15, r29 C join carries
+ br r31, $ret4c
+$fix5c: bis r4, r29, r4 C join carries
+ br r31, $ret5c
+$fix6c: addq r5, r4, r5 C can't carry twice!
+ br r31, $ret6c
+
+EPILOGUE(mpn_mul_1)
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/nails/README b/gmp/mpn/alpha/ev6/nails/README
new file mode 100644
index 0000000000..b214ac50ad
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/nails/README
@@ -0,0 +1,65 @@
+Copyright 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+This directory contains assembly code for nails-enabled 21264. The code is not
+very well optimized.
+
+For addmul_N, as N grows larger, we could make multiple loads together, then do
+about 3.3 i/c. 10 cycles after the last load, we can increase to 4 i/c. This
+would surely allow addmul_4 to run at 2 c/l, but the same should be possible
+also for addmul_3 and perhaps even addmul_2.
+
+
+ current fair best
+Routine c/l unroll c/l unroll c/l i/c
+mul_1 3.25 2.75 2.75 3.273
+addmul_1 4.0 4 3.5 4 14 3.25 3.385
+addmul_2 4.0 1 2.5 2 10 2.25 3.333
+addmul_3 3.0 1 2.33 2 14 2 3.333
+addmul_4 2.5 1 2.125 2 17 2 3.135
+
+addmul_5 2 1 10
+addmul_6 2 1 12
+addmul_7 2 1 14
+
+(The "best" column doesn't account for bookkeeping instructions and
+thereby assumes infinite unrolling.)
+
+Basecase usages:
+
+1 addmul_1
+2 addmul_2
+3 addmul_3
+4 addmul_4
+5 addmul_3 + addmul_2 2.3998
+6 addmul_4 + addmul_2
+7 addmul_4 + addmul_3
diff --git a/gmp/mpn/alpha/ev6/nails/addmul_1.asm b/gmp/mpn/alpha/ev6/nails/addmul_1.asm
new file mode 100644
index 0000000000..711d4e66e5
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/nails/addmul_1.asm
@@ -0,0 +1,396 @@
+dnl Alpha ev6 nails mpn_addmul_1.
+
+dnl Copyright 2002, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 42
+C EV5: 18
+C EV6: 4
+
+C TODO
+C * Reroll loop for 3.75 c/l with current 4-way unrolling.
+C * The loop is overscheduled wrt loads and wrt multiplies, in particular
+C umulh.
+C * Use FP loop count and multiple exit points, that would simplify feed-in lp0
+C and would work since the loop structure is really regular.
+
+C INPUT PARAMETERS
+define(`rp',`r16')
+define(`up',`r17')
+define(`n', `r18')
+define(`vl0',`r19')
+
+define(`numb_mask',`r6')
+
+define(`m0a',`r0')
+define(`m0b',`r1')
+define(`m1a',`r2')
+define(`m1b',`r3')
+define(`m2a',`r20')
+define(`m2b',`r21')
+define(`m3a',`r22')
+define(`m3b',`r23')
+
+define(`acc0',`r25')
+define(`acc1',`r27')
+
+define(`ul0',`r4')
+define(`ul1',`r5')
+define(`ul2',`r4')
+define(`ul3',`r5')
+
+define(`rl0',`r24')
+define(`rl1',`r24')
+define(`rl2',`r24')
+define(`rl3',`r24')
+
+define(`t0',`r7')
+define(`t1',`r8')
+
+define(`NAIL_BITS',`GMP_NAIL_BITS')
+define(`NUMB_BITS',`GMP_NUMB_BITS')
+
+dnl This declaration is munged by configure
+NAILS_SUPPORT(2-63)
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ sll vl0, NAIL_BITS, vl0
+ lda numb_mask, -1(r31)
+ srl numb_mask, NAIL_BITS, numb_mask
+
+ and n, 3, r25
+ cmpeq r25, 1, r21
+ bne r21, L(1m4)
+ cmpeq r25, 2, r21
+ bne r21, L(2m4)
+ beq r25, L(0m4)
+
+L(3m4): ldq ul3, 0(up)
+ lda n, -4(n)
+ ldq ul0, 8(up)
+ mulq vl0, ul3, m3a
+ umulh vl0, ul3, m3b
+ ldq ul1, 16(up)
+ lda up, 24(up)
+ lda rp, -8(rp)
+ mulq vl0, ul0, m0a
+ umulh vl0, ul0, m0b
+ bge n, L(ge3)
+
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq rl3, 8(rp)
+ srl m3a,NAIL_BITS, t0
+ addq t0, r31, acc1
+ addq rl3, acc1, acc1
+ ldq rl0, 16(rp)
+ srl m0a,NAIL_BITS, t0
+ addq t0, m3b, acc0
+ srl acc1,NUMB_BITS, t1
+ br r31, L(ta3)
+
+L(ge3): ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq rl3, 8(rp)
+ srl m3a,NAIL_BITS, t0
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ addq t0, r31, acc1
+ umulh vl0, ul2, m2b
+ addq rl3, acc1, acc1
+ ldq rl0, 16(rp)
+ srl m0a,NAIL_BITS, t0
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ addq t0, m3b, acc0
+ srl acc1,NUMB_BITS, t1
+ br r31, L(el3)
+
+L(0m4): lda n, -8(n)
+ ldq ul2, 0(up)
+ ldq ul3, 8(up)
+ mulq vl0, ul2, m2a
+ umulh vl0, ul2, m2b
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ umulh vl0, ul3, m3b
+ ldq ul1, 24(up)
+ lda up, 32(up)
+ mulq vl0, ul0, m0a
+ umulh vl0, ul0, m0b
+ bge n, L(ge4)
+
+ ldq rl2, 0(rp)
+ srl m2a,NAIL_BITS, t0
+ mulq vl0, ul1, m1a
+ addq t0, r31, acc0
+ umulh vl0, ul1, m1b
+ addq rl2, acc0, acc0
+ ldq rl3, 8(rp)
+ srl m3a,NAIL_BITS, t0
+ addq t0, m2b, acc1
+ srl acc0,NUMB_BITS, t1
+ br r31, L(ta4)
+
+L(ge4): ldq rl2, 0(rp)
+ srl m2a,NAIL_BITS, t0
+ ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ addq t0, r31, acc0
+ umulh vl0, ul1, m1b
+ addq rl2, acc0, acc0
+ ldq rl3, 8(rp)
+ srl m3a,NAIL_BITS, t0
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ addq t0, m2b, acc1
+ srl acc0,NUMB_BITS, t1
+ br r31, L(el0)
+
+L(2m4): lda n, -4(n)
+ ldq ul0, 0(up)
+ ldq ul1, 8(up)
+ lda up, 16(up)
+ lda rp, -16(rp)
+ mulq vl0, ul0, m0a
+ umulh vl0, ul0, m0b
+ bge n, L(ge2)
+
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq rl0, 16(rp)
+ srl m0a,NAIL_BITS, t0
+ addq t0, r31, acc0
+ addq rl0, acc0, acc0
+ ldq rl1, 24(rp)
+ srl m1a,NAIL_BITS, t0
+ addq t0, m0b, acc1
+ srl acc0,NUMB_BITS, t1
+ br r31, L(ta2)
+
+L(ge2): ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ umulh vl0, ul2, m2b
+ ldq rl0, 16(rp)
+ srl m0a,NAIL_BITS, t0
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ addq t0, r31, acc0
+ umulh vl0, ul3, m3b
+ addq rl0, acc0, acc0
+ ldq rl1, 24(rp)
+ srl m1a,NAIL_BITS, t0
+ ldq ul1, 24(up)
+ lda up, 32(up)
+ lda rp, 32(rp)
+ mulq vl0, ul0, m0a
+ addq t0, m0b, acc1
+ srl acc0,NUMB_BITS, t1
+ bge n, L(el2)
+
+ br r31, L(ta6)
+
+L(1m4): lda n, -4(n)
+ ldq ul1, 0(up)
+ lda up, 8(up)
+ lda rp, -24(rp)
+ bge n, L(ge1)
+
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq rl1, 24(rp)
+ srl m1a,NAIL_BITS, t0
+ addq rl1, t0, acc1
+ and acc1,numb_mask, r28
+ srl acc1,NUMB_BITS, t1
+ stq r28, 24(rp)
+ addq t1, m1b, r0
+ ret r31, (r26), 1
+
+L(ge1): ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ umulh vl0, ul2, m2b
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ umulh vl0, ul3, m3b
+ ldq rl1, 24(rp)
+ srl m1a,NAIL_BITS, t0
+ ldq ul1, 24(up)
+ lda up, 32(up)
+ lda rp, 32(rp)
+ mulq vl0, ul0, m0a
+ addq t0, r31, acc1
+ umulh vl0, ul0, m0b
+ addq rl1, acc1, acc1
+ ldq rl2, 0(rp)
+ srl m2a,NAIL_BITS, t0
+ mulq vl0, ul1, m1a
+ addq t0, m1b, acc0
+ srl acc1,NUMB_BITS, t1
+ blt n, L(ta5)
+
+L(ge5): ldq ul2, 0(up)
+ br r31, L(el1)
+
+ ALIGN(16)
+L(top): mulq vl0, ul0, m0a C U1
+ addq t0, m0b, acc1 C L0
+ srl acc0,NUMB_BITS, t1 C U0
+ stq r28, -24(rp) C L1
+C
+L(el2): umulh vl0, ul0, m0b C U1
+ and acc0,numb_mask, r28 C L0
+ addq rl1, acc1, acc1 C U0
+ ldq rl2, 0(rp) C L1
+C
+ unop C U1
+ addq t1, acc1, acc1 C L0
+ srl m2a,NAIL_BITS, t0 C U0
+ ldq ul2, 0(up) C L1
+C
+ mulq vl0, ul1, m1a C U1
+ addq t0, m1b, acc0 C L0
+ srl acc1,NUMB_BITS, t1 C U0
+ stq r28, -16(rp) C L1
+C
+L(el1): umulh vl0, ul1, m1b C U1
+ and acc1,numb_mask, r28 C L0
+ addq rl2, acc0, acc0 C U0
+ ldq rl3, 8(rp) C L1
+C
+ lda n, -4(n) C L1
+ addq t1, acc0, acc0 C L0
+ srl m3a,NAIL_BITS, t0 C U0
+ ldq ul3, 8(up) C L1
+C
+ mulq vl0, ul2, m2a C U1
+ addq t0, m2b, acc1 C L0
+ srl acc0,NUMB_BITS, t1 C U0
+ stq r28, -8(rp) C L1
+C
+L(el0): umulh vl0, ul2, m2b C U1
+ and acc0,numb_mask, r28 C L0
+ addq rl3, acc1, acc1 C U0
+ ldq rl0, 16(rp) C L1
+C
+ unop C U1
+ addq t1, acc1, acc1 C L0
+ srl m0a,NAIL_BITS, t0 C U0
+ ldq ul0, 16(up) C L1
+C
+ mulq vl0, ul3, m3a C U1
+ addq t0, m3b, acc0 C L0
+ srl acc1,NUMB_BITS, t1 C U0
+ stq r28, 0(rp) C L1
+C
+L(el3): umulh vl0, ul3, m3b C U1
+ and acc1,numb_mask, r28 C L0
+ addq rl0, acc0, acc0 C U0
+ ldq rl1, 24(rp) C L1
+C
+ unop C U1
+ addq t1, acc0, acc0 C L0
+ srl m1a,NAIL_BITS, t0 C U0
+ ldq ul1, 24(up) C L1
+C
+ lda up, 32(up) C L0
+ unop C U1
+ lda rp, 32(rp) C L1
+ bge n, L(top) C U0
+
+L(end): mulq vl0, ul0, m0a
+ addq t0, m0b, acc1
+ srl acc0,NUMB_BITS, t1
+ stq r28, -24(rp)
+L(ta6): umulh vl0, ul0, m0b
+ and acc0,numb_mask, r28
+ addq rl1, acc1, acc1
+ ldq rl2, 0(rp)
+ addq t1, acc1, acc1
+ srl m2a,NAIL_BITS, t0
+ mulq vl0, ul1, m1a
+ addq t0, m1b, acc0
+ srl acc1,NUMB_BITS, t1
+ stq r28, -16(rp)
+L(ta5): umulh vl0, ul1, m1b
+ and acc1,numb_mask, r28
+ addq rl2, acc0, acc0
+ ldq rl3, 8(rp)
+ addq t1, acc0, acc0
+ srl m3a,NAIL_BITS, t0
+ addq t0, m2b, acc1
+ srl acc0,NUMB_BITS, t1
+ stq r28, -8(rp)
+ unop
+ ALIGN(16)
+L(ta4): and acc0,numb_mask, r28
+ addq rl3, acc1, acc1
+ ldq rl0, 16(rp)
+ addq t1, acc1, acc1
+ srl m0a,NAIL_BITS, t0
+ addq t0, m3b, acc0
+ srl acc1,NUMB_BITS, t1
+ stq r28, 0(rp)
+ unop
+ ALIGN(16)
+L(ta3): and acc1,numb_mask, r28
+ addq rl0, acc0, acc0
+ ldq rl1, 24(rp)
+ addq t1, acc0, acc0
+ srl m1a,NAIL_BITS, t0
+ addq t0, m0b, acc1
+ srl acc0,NUMB_BITS, t1
+ stq r28, 8(rp)
+ unop
+ ALIGN(16)
+L(ta2): and acc0,numb_mask, r28
+ addq rl1, acc1, acc1
+ addq t1, acc1, acc1
+ srl acc1,NUMB_BITS, t1
+ stq r28, 16(rp)
+ and acc1,numb_mask, r28
+ addq t1, m1b, r0
+ stq r28, 24(rp)
+ ret r31, (r26), 1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/nails/addmul_2.asm b/gmp/mpn/alpha/ev6/nails/addmul_2.asm
new file mode 100644
index 0000000000..6ff6b3ad6b
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/nails/addmul_2.asm
@@ -0,0 +1,146 @@
+dnl Alpha ev6 nails mpn_addmul_2.
+
+dnl Copyright 2002, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C Runs at 4.0 cycles/limb.
+
+C We could either go for 2-way unrolling over 11 cycles, or 2.75 c/l,
+C or 4-way unrolling over 20 cycles, for 2.5 c/l.
+
+
+C INPUT PARAMETERS
+define(`rp',`r16')
+define(`up',`r17')
+define(`n',`r18')
+define(`vp',`r19')
+
+C Useful register aliases
+define(`numb_mask',`r24')
+define(`ulimb',`r25')
+define(`rlimb',`r27')
+
+define(`m0a',`r0')
+define(`m0b',`r1')
+define(`m1a',`r2')
+define(`m1b',`r3')
+
+define(`acc0',`r4')
+define(`acc1',`r5')
+
+define(`v0',`r6')
+define(`v1',`r7')
+
+C Used for temps: r8 r19 r28
+
+define(`NAIL_BITS',`GMP_NAIL_BITS')
+define(`NUMB_BITS',`GMP_NUMB_BITS')
+
+C This declaration is munged by configure
+NAILS_SUPPORT(3-63)
+
+ASM_START()
+PROLOGUE(mpn_addmul_2)
+ lda numb_mask,-1(r31)
+ srl numb_mask,NAIL_BITS,numb_mask
+
+ ldq v0, 0(vp)
+ ldq v1, 8(vp)
+
+ bis r31, r31, acc0 C zero acc0
+ sll v0,NAIL_BITS, v0
+ bis r31, r31, acc1 C zero acc1
+ sll v1,NAIL_BITS, v1
+ bis r31, r31, r19
+
+ ldq ulimb, 0(up)
+ lda up, 8(up)
+ mulq v0, ulimb, m0a C U1
+ umulh v0, ulimb, m0b C U1
+ mulq v1, ulimb, m1a C U1
+ umulh v1, ulimb, m1b C U1
+ lda n, -1(n)
+ beq n, L(end) C U0
+
+ ALIGN(16)
+L(top): bis r31, r31, r31 C U1 nop
+ addq r19, acc0, acc0 C U0 propagate nail
+ ldq rlimb, 0(rp) C L0
+ ldq ulimb, 0(up) C L1
+
+ lda rp, 8(rp) C L1
+ srl m0a,NAIL_BITS, r8 C U0
+ lda up, 8(up) C L0
+ mulq v0, ulimb, m0a C U1
+
+ addq r8, acc0, r19 C U0
+ addq m0b, acc1, acc0 C L1
+ umulh v0, ulimb, m0b C U1
+ bis r31, r31, r31 C L0 nop
+
+ addq rlimb, r19, r19 C L1 FINAL PROD-SUM
+ srl m1a,NAIL_BITS, r8 C U0
+ lda n, -1(n) C L0
+ mulq v1, ulimb, m1a C U1
+
+ addq r8, acc0, acc0 C U0
+ bis r31, m1b, acc1 C L1
+ umulh v1, ulimb, m1b C U1
+ and r19,numb_mask, r28 C L0 extract numb part
+
+ unop
+ srl r19,NUMB_BITS, r19 C U1 extract nail part
+ stq r28, -8(rp) C L1
+ bne n, L(top) C U0
+
+L(end): ldq rlimb, 0(rp)
+ addq r19, acc0, acc0 C propagate nail
+ lda rp, 8(rp)
+ srl m0a,NAIL_BITS, r8 C U0
+ addq r8, acc0, r19
+ addq m0b, acc1, acc0
+ addq rlimb, r19, r19
+ srl m1a,NAIL_BITS, r8 C U0
+ addq r8, acc0, acc0
+ bis r31, m1b, acc1
+ and r19,numb_mask, r28 C extract limb
+
+ srl r19,NUMB_BITS, r19 C extract nail
+ stq r28, -8(rp)
+
+ addq r19, acc0, acc0 C propagate nail
+ and acc0,numb_mask, r28
+ stq r28, 0(rp)
+ srl acc0,NUMB_BITS, r19
+ addq r19, acc1, r0
+
+ ret r31, (r26), 1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/nails/addmul_3.asm b/gmp/mpn/alpha/ev6/nails/addmul_3.asm
new file mode 100644
index 0000000000..a1ffb680ec
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/nails/addmul_3.asm
@@ -0,0 +1,169 @@
+dnl Alpha ev6 nails mpn_addmul_3.
+
+dnl Copyright 2002, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C Runs at 3.0 cycles/limb.
+
+C With 2-way unrolling, we could probably reach 2.25 c/l (3.33 i/c).
+
+
+C INPUT PARAMETERS
+define(`rp',`r16')
+define(`up',`r17')
+define(`n',`r18')
+define(`vp',`r19')
+
+C Useful register aliases
+define(`numb_mask',`r24')
+define(`ulimb',`r25')
+define(`rlimb',`r27')
+
+define(`m0a',`r0')
+define(`m0b',`r1')
+define(`m1a',`r2')
+define(`m1b',`r3')
+define(`m2a',`r20')
+define(`m2b',`r21')
+
+define(`acc0',`r4')
+define(`acc1',`r5')
+define(`acc2',`r22')
+
+define(`v0',`r6')
+define(`v1',`r7')
+define(`v2',`r23')
+
+C Used for temps: r8 r19 r28
+
+define(`NAIL_BITS',`GMP_NAIL_BITS')
+define(`NUMB_BITS',`GMP_NUMB_BITS')
+
+C This declaration is munged by configure
+NAILS_SUPPORT(3-63)
+
+ASM_START()
+PROLOGUE(mpn_addmul_3)
+ lda numb_mask,-1(r31)
+ srl numb_mask,NAIL_BITS,numb_mask
+
+ ldq v0, 0(vp)
+ ldq v1, 8(vp)
+ ldq v2, 16(vp)
+
+ bis r31, r31, acc0 C zero acc0
+ sll v0,NAIL_BITS, v0
+ bis r31, r31, acc1 C zero acc1
+ sll v1,NAIL_BITS, v1
+ bis r31, r31, acc2 C zero acc2
+ sll v2,NAIL_BITS, v2
+ bis r31, r31, r19
+
+ ldq ulimb, 0(up)
+ lda up, 8(up)
+ mulq v0, ulimb, m0a C U1
+ umulh v0, ulimb, m0b C U1
+ mulq v1, ulimb, m1a C U1
+ umulh v1, ulimb, m1b C U1
+ lda n, -1(n)
+ mulq v2, ulimb, m2a C U1
+ umulh v2, ulimb, m2b C U1
+ beq n, L(end) C U0
+
+ ALIGN(16)
+L(top): ldq rlimb, 0(rp) C L1
+ ldq ulimb, 0(up) C L0
+ bis r31, r31, r31 C U0 nop
+ addq r19, acc0, acc0 C U1 propagate nail
+
+ lda rp, 8(rp) C L1
+ srl m0a,NAIL_BITS, r8 C U0
+ lda up, 8(up) C L0
+ mulq v0, ulimb, m0a C U1
+
+ addq r8, acc0, r19 C U0
+ addq m0b, acc1, acc0 C L1
+ umulh v0, ulimb, m0b C U1
+ bis r31, r31, r31 C L0 nop
+
+ addq rlimb, r19, r19 C L1
+ srl m1a,NAIL_BITS, r8 C U0
+ bis r31, r31, r31 C L0 nop
+ mulq v1, ulimb, m1a C U1
+
+ addq r8, acc0, acc0 C U0
+ addq m1b, acc2, acc1 C L1
+ umulh v1, ulimb, m1b C U1
+ and r19,numb_mask, r28 C L0 extract numb part
+
+ bis r31, r31, r31 C L1 nop
+ srl m2a,NAIL_BITS, r8 C U0
+ lda n, -1(n) C L0
+ mulq v2, ulimb, m2a C U1
+
+ addq r8, acc1, acc1 C L0
+ bis r31, m2b, acc2 C L1
+ umulh v2, ulimb, m2b C U1
+ srl r19,NUMB_BITS, r19 C U0 extract nail part
+
+ stq r28, -8(rp) C L
+ bne n, L(top) C U0
+
+L(end): ldq rlimb, 0(rp)
+ addq r19, acc0, acc0 C propagate nail
+ lda rp, 8(rp)
+ srl m0a,NAIL_BITS, r8 C U0
+ addq r8, acc0, r19
+ addq m0b, acc1, acc0
+ addq rlimb, r19, r19
+ srl m1a,NAIL_BITS, r8 C U0
+ addq r8, acc0, acc0
+ addq m1b, acc2, acc1
+ and r19,numb_mask, r28 C extract limb
+ srl m2a,NAIL_BITS, r8 C U0
+ addq r8, acc1, acc1
+ bis r31, m2b, acc2
+ srl r19,NUMB_BITS, r19 C extract nail
+ stq r28, -8(rp)
+
+ addq r19, acc0, acc0 C propagate nail
+ and acc0,numb_mask, r28
+ stq r28, 0(rp)
+ srl acc0,NUMB_BITS, r19
+ addq r19, acc1, acc1
+
+ and acc1,numb_mask, r28
+ stq r28, 8(rp)
+ srl acc1,NUMB_BITS, r19
+ addq r19, acc2, m0a
+
+ ret r31, (r26), 1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/nails/addmul_4.asm b/gmp/mpn/alpha/ev6/nails/addmul_4.asm
new file mode 100644
index 0000000000..77e02a4316
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/nails/addmul_4.asm
@@ -0,0 +1,210 @@
+dnl Alpha ev6 nails mpn_addmul_4.
+
+dnl Copyright 2002, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C Runs at 2.5 cycles/limb.
+
+C We should go for 2-way unrolling over 17 cycles, for 2.125 c/l corresponding
+C to 3.24 insn/cycle.
+
+
+C INPUT PARAMETERS
+define(`rp',`r16')
+define(`up',`r17')
+define(`n',`r18')
+define(`vp',`r19')
+
+C Useful register aliases
+define(`numb_mask',`r24')
+define(`ulimb',`r25')
+define(`rlimb',`r27')
+
+define(`m0a',`r0')
+define(`m0b',`r1')
+define(`m1a',`r2')
+define(`m1b',`r3')
+define(`m2a',`r20')
+define(`m2b',`r21')
+define(`m3a',`r12')
+define(`m3b',`r13')
+
+define(`acc0',`r4')
+define(`acc1',`r5')
+define(`acc2',`r22')
+define(`acc3',`r14')
+
+define(`v0',`r6')
+define(`v1',`r7')
+define(`v2',`r23')
+define(`v3',`r15')
+
+C Used for temps: r8 r19 r28
+
+define(`NAIL_BITS',`GMP_NAIL_BITS')
+define(`NUMB_BITS',`GMP_NUMB_BITS')
+
+C This declaration is munged by configure
+NAILS_SUPPORT(4-63)
+
+ASM_START()
+PROLOGUE(mpn_addmul_4)
+ lda r30, -240(r30)
+ stq r12, 32(r30)
+ stq r13, 40(r30)
+ stq r14, 48(r30)
+ stq r15, 56(r30)
+
+ lda numb_mask,-1(r31)
+ srl numb_mask,NAIL_BITS,numb_mask
+
+ ldq v0, 0(vp)
+ ldq v1, 8(vp)
+ ldq v2, 16(vp)
+ ldq v3, 24(vp)
+
+ bis r31, r31, acc0 C zero acc0
+ sll v0,NAIL_BITS, v0
+ bis r31, r31, acc1 C zero acc1
+ sll v1,NAIL_BITS, v1
+ bis r31, r31, acc2 C zero acc2
+ sll v2,NAIL_BITS, v2
+ bis r31, r31, acc3 C zero acc3
+ sll v3,NAIL_BITS, v3
+ bis r31, r31, r19
+
+ ldq ulimb, 0(up)
+ lda up, 8(up)
+ mulq v0, ulimb, m0a C U1
+ umulh v0, ulimb, m0b C U1
+ mulq v1, ulimb, m1a C U1
+ umulh v1, ulimb, m1b C U1
+ lda n, -1(n)
+ mulq v2, ulimb, m2a C U1
+ umulh v2, ulimb, m2b C U1
+ mulq v3, ulimb, m3a C U1
+ umulh v3, ulimb, m3b C U1
+ beq n, L(end) C U0
+
+ ALIGN(16)
+L(top): bis r31, r31, r31 C U1 nop
+ ldq rlimb, 0(rp) C L0
+ ldq ulimb, 0(up) C L1
+ addq r19, acc0, acc0 C U0 propagate nail
+
+ bis r31, r31, r31 C L0 nop
+ bis r31, r31, r31 C U1 nop
+ bis r31, r31, r31 C L1 nop
+ bis r31, r31, r31 C U0 nop
+
+ lda rp, 8(rp) C L0
+ srl m0a,NAIL_BITS, r8 C U0
+ lda up, 8(up) C L1
+ mulq v0, ulimb, m0a C U1
+
+ addq r8, acc0, r19 C U0
+ addq m0b, acc1, acc0 C L0
+ umulh v0, ulimb, m0b C U1
+ bis r31, r31, r31 C L1 nop
+
+ addq rlimb, r19, r19 C L0
+ srl m1a,NAIL_BITS, r8 C U0
+ bis r31, r31, r31 C L1 nop
+ mulq v1, ulimb, m1a C U1
+
+ addq r8, acc0, acc0 C U0
+ addq m1b, acc2, acc1 C L0
+ umulh v1, ulimb, m1b C U1
+ and r19,numb_mask, r28 C L1 extract numb part
+
+ bis r31, r31, r31 C L0 nop
+ srl m2a,NAIL_BITS, r8 C U0
+ lda n, -1(n) C L1
+ mulq v2, ulimb, m2a C U1
+
+ addq r8, acc1, acc1 C L1
+ addq m2b, acc3, acc2 C L0
+ umulh v2, ulimb, m2b C U1
+ srl r19,NUMB_BITS, r19 C U0 extract nail part
+
+ bis r31, r31, r31 C L0 nop
+ srl m3a,NAIL_BITS, r8 C U0
+ stq r28, -8(rp) C L1
+ mulq v3, ulimb, m3a C U1
+
+ addq r8, acc2, acc2 C L0
+ bis r31, m3b, acc3 C L1
+ umulh v3, ulimb, m3b C U1
+ bne n, L(top) C U0
+
+L(end): ldq rlimb, 0(rp)
+ addq r19, acc0, acc0 C propagate nail
+ lda rp, 8(rp) C FIXME: DELETE
+ srl m0a,NAIL_BITS, r8 C U0
+ addq r8, acc0, r19
+ addq m0b, acc1, acc0
+ addq rlimb, r19, r19
+ srl m1a,NAIL_BITS, r8 C U0
+ addq r8, acc0, acc0
+ addq m1b, acc2, acc1
+ and r19,numb_mask, r28 C extract limb
+ srl m2a,NAIL_BITS, r8 C U0
+ addq r8, acc1, acc1
+ addq m2b, acc3, acc2
+ srl r19,NUMB_BITS, r19 C extract nail
+ srl m3a,NAIL_BITS, r8 C U0
+ stq r28, -8(rp)
+ addq r8, acc2, acc2
+ bis r31, m3b, acc3
+
+ addq r19, acc0, acc0 C propagate nail
+ and acc0,numb_mask, r28
+ stq r28, 0(rp)
+ srl acc0,NUMB_BITS, r19
+ addq r19, acc1, acc1
+
+ and acc1,numb_mask, r28
+ stq r28, 8(rp)
+ srl acc1,NUMB_BITS, r19
+ addq r19, acc2, acc2
+
+ and acc2,numb_mask, r28
+ stq r28, 16(rp)
+ srl acc2,NUMB_BITS, r19
+ addq r19, acc3, r0
+
+ ldq r12, 32(r30)
+ ldq r13, 40(r30)
+ ldq r14, 48(r30)
+ ldq r15, 56(r30)
+ lda r30, 240(r30)
+ ret r31, (r26), 1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/nails/aors_n.asm b/gmp/mpn/alpha/ev6/nails/aors_n.asm
new file mode 100644
index 0000000000..f6586773f5
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/nails/aors_n.asm
@@ -0,0 +1,233 @@
+dnl Alpha ev6 nails mpn_add_n and mpn_sub_n.
+
+dnl Copyright 2002, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Runs at 2.5 cycles/limb. It would be possible to reach 2.0 cycles/limb
+dnl with 8-way unrolling.
+
+include(`../config.m4')
+
+dnl INPUT PARAMETERS
+define(`rp',`r16')
+define(`up',`r17')
+define(`vp',`r18')
+define(`n',`r19')
+
+define(`rl0',`r0')
+define(`rl1',`r1')
+define(`rl2',`r2')
+define(`rl3',`r3')
+
+define(`ul0',`r4')
+define(`ul1',`r5')
+define(`ul2',`r6')
+define(`ul3',`r7')
+
+define(`vl0',`r22')
+define(`vl1',`r23')
+define(`vl2',`r24')
+define(`vl3',`r25')
+
+define(`numb_mask',`r21')
+
+define(`NAIL_BITS',`GMP_NAIL_BITS')
+define(`CYSH',`GMP_NUMB_BITS')
+
+dnl This declaration is munged by configure
+NAILS_SUPPORT(1-63)
+
+ifdef(`OPERATION_add_n', `
+ define(`OP', addq)
+ define(`CYSH',`GMP_NUMB_BITS')
+ define(`func', mpn_add_n)')
+ifdef(`OPERATION_sub_n', `
+ define(`OP', subq)
+ define(`CYSH',63)
+ define(`func', mpn_sub_n)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ lda numb_mask, -1(r31)
+ srl numb_mask, NAIL_BITS, numb_mask
+ bis r31, r31, r20
+
+ and n, 3, r25
+ lda n, -4(n)
+ beq r25, L(ge4)
+
+L(lp0): ldq ul0, 0(up)
+ lda up, 8(up)
+ ldq vl0, 0(vp)
+ lda vp, 8(vp)
+ lda rp, 8(rp)
+ lda r25, -1(r25)
+ OP ul0, vl0, rl0
+ OP rl0, r20, rl0
+ and rl0, numb_mask, r28
+ stq r28, -8(rp)
+ srl rl0, CYSH, r20
+ bne r25, L(lp0)
+
+ blt n, L(ret)
+
+L(ge4): ldq ul0, 0(up)
+ ldq vl0, 0(vp)
+ ldq ul1, 8(up)
+ ldq vl1, 8(vp)
+ ldq ul2, 16(up)
+ ldq vl2, 16(vp)
+ ldq ul3, 24(up)
+ ldq vl3, 24(vp)
+ lda up, 32(up)
+ lda vp, 32(vp)
+ lda n, -4(n)
+ bge n, L(ge8)
+
+ OP ul0, vl0, rl0 C main-add 0
+ OP rl0, r20, rl0 C cy-add 0
+ OP ul1, vl1, rl1 C main-add 1
+ srl rl0, CYSH, r20 C gen cy 0
+ OP rl1, r20, rl1 C cy-add 1
+ and rl0,numb_mask, r27
+ br r31, L(cj0)
+
+L(ge8): OP ul0, vl0, rl0 C main-add 0
+ ldq ul0, 0(up)
+ ldq vl0, 0(vp)
+ OP rl0, r20, rl0 C cy-add 0
+ OP ul1, vl1, rl1 C main-add 1
+ srl rl0, CYSH, r20 C gen cy 0
+ ldq ul1, 8(up)
+ ldq vl1, 8(vp)
+ OP rl1, r20, rl1 C cy-add 1
+ and rl0,numb_mask, r27
+ OP ul2, vl2, rl2 C main-add 2
+ srl rl1, CYSH, r20 C gen cy 1
+ ldq ul2, 16(up)
+ ldq vl2, 16(vp)
+ OP rl2, r20, rl2 C cy-add 2
+ and rl1,numb_mask, r28
+ stq r27, 0(rp)
+ OP ul3, vl3, rl3 C main-add 3
+ srl rl2, CYSH, r20 C gen cy 2
+ ldq ul3, 24(up)
+ ldq vl3, 24(vp)
+ OP rl3, r20, rl3 C cy-add 3
+ and rl2,numb_mask, r27
+ stq r28, 8(rp)
+ lda rp, 32(rp)
+ lda up, 32(up)
+ lda vp, 32(vp)
+ lda n, -4(n)
+ blt n, L(end)
+
+ ALIGN(32)
+L(top): OP ul0, vl0, rl0 C main-add 0
+ srl rl3, CYSH, r20 C gen cy 3
+ ldq ul0, 0(up)
+ ldq vl0, 0(vp)
+
+ OP rl0, r20, rl0 C cy-add 0
+ and rl3,numb_mask, r28
+ stq r27, -16(rp)
+ bis r31, r31, r31
+
+ OP ul1, vl1, rl1 C main-add 1
+ srl rl0, CYSH, r20 C gen cy 0
+ ldq ul1, 8(up)
+ ldq vl1, 8(vp)
+
+ OP rl1, r20, rl1 C cy-add 1
+ and rl0,numb_mask, r27
+ stq r28, -8(rp)
+ bis r31, r31, r31
+
+ OP ul2, vl2, rl2 C main-add 2
+ srl rl1, CYSH, r20 C gen cy 1
+ ldq ul2, 16(up)
+ ldq vl2, 16(vp)
+
+ OP rl2, r20, rl2 C cy-add 2
+ and rl1,numb_mask, r28
+ stq r27, 0(rp)
+ bis r31, r31, r31
+
+ OP ul3, vl3, rl3 C main-add 3
+ srl rl2, CYSH, r20 C gen cy 2
+ ldq ul3, 24(up)
+ ldq vl3, 24(vp)
+
+ OP rl3, r20, rl3 C cy-add 3
+ and rl2,numb_mask, r27
+ stq r28, 8(rp)
+ bis r31, r31, r31
+
+ bis r31, r31, r31
+ lda n, -4(n)
+ lda up, 32(up)
+ lda vp, 32(vp)
+
+ bis r31, r31, r31
+ bis r31, r31, r31
+ lda rp, 32(rp)
+ bge n, L(top)
+
+L(end): OP ul0, vl0, rl0 C main-add 0
+ srl rl3, CYSH, r20 C gen cy 3
+ OP rl0, r20, rl0 C cy-add 0
+ and rl3,numb_mask, r28
+ stq r27, -16(rp)
+ OP ul1, vl1, rl1 C main-add 1
+ srl rl0, CYSH, r20 C gen cy 0
+ OP rl1, r20, rl1 C cy-add 1
+ and rl0,numb_mask, r27
+ stq r28, -8(rp)
+L(cj0): OP ul2, vl2, rl2 C main-add 2
+ srl rl1, CYSH, r20 C gen cy 1
+ OP rl2, r20, rl2 C cy-add 2
+ and rl1,numb_mask, r28
+ stq r27, 0(rp)
+ OP ul3, vl3, rl3 C main-add 3
+ srl rl2, CYSH, r20 C gen cy 2
+ OP rl3, r20, rl3 C cy-add 3
+ and rl2,numb_mask, r27
+ stq r28, 8(rp)
+
+ srl rl3, CYSH, r20 C gen cy 3
+ and rl3,numb_mask, r28
+ stq r27, 16(rp)
+ stq r28, 24(rp)
+
+L(ret): and r20, 1, r0
+ ret r31, (r26), 1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/nails/gmp-mparam.h b/gmp/mpn/alpha/ev6/nails/gmp-mparam.h
new file mode 100644
index 0000000000..7949fe8df8
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/nails/gmp-mparam.h
@@ -0,0 +1,72 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* Generated by tuneup.c, 2004-02-07, gcc 3.3 */
+
+#define MUL_TOOM22_THRESHOLD 40
+#define MUL_TOOM33_THRESHOLD 236
+
+#define SQR_BASECASE_THRESHOLD 7 /* karatsuba */
+#define SQR_TOOM2_THRESHOLD 0 /* never sqr_basecase */
+#define SQR_TOOM3_THRESHOLD 120
+
+#define DIV_SB_PREINV_THRESHOLD MP_SIZE_T_MAX /* no preinv with nails */
+#define DIV_DC_THRESHOLD 48
+#define POWM_THRESHOLD 113
+
+#define HGCD_THRESHOLD 78
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 392
+#define JACOBI_BASE_METHOD 1
+
+#define DIVREM_1_NORM_THRESHOLD MP_SIZE_T_MAX /* no preinv with nails */
+#define DIVREM_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* no preinv with nails */
+#define MOD_1_NORM_THRESHOLD MP_SIZE_T_MAX /* no preinv with nails */
+#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* no preinv with nails */
+#define USE_PREINV_DIVREM_1 0 /* no preinv with nails */
+#define USE_PREINV_MOD_1 0 /* no preinv with nails */
+#define DIVREM_2_THRESHOLD MP_SIZE_T_MAX /* no preinv with nails */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always */
+
+#define GET_STR_DC_THRESHOLD 15
+#define GET_STR_PRECOMPUTE_THRESHOLD 24
+#define SET_STR_THRESHOLD 6336
+
+#define MUL_FFT_TABLE { 688, 1440, 3648, 6400, 25600, 0 }
+#define MUL_FFT_MODF_THRESHOLD 488
+#define MUL_FFT_THRESHOLD 3712
+
+#define SQR_FFT_TABLE { 432, 864, 3136, 6400, 25600, 0 }
+#define SQR_FFT_MODF_THRESHOLD 480
+#define SQR_FFT_THRESHOLD 2976
diff --git a/gmp/mpn/alpha/ev6/nails/mul_1.asm b/gmp/mpn/alpha/ev6/nails/mul_1.asm
new file mode 100644
index 0000000000..da2ee3d099
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/nails/mul_1.asm
@@ -0,0 +1,364 @@
+dnl Alpha ev6 nails mpn_mul_1.
+
+dnl Copyright 2002, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 42
+C EV5: 18
+C EV6: 3.25
+
+C TODO
+C * Reroll loop for 3.0 c/l with current 4-way unrolling.
+C * The loop is overscheduled wrt loads and wrt multiplies, in particular
+C umulh.
+C * Use FP loop count and multiple exit points, that would simplify feed-in lp0
+C and would work since the loop structure is really regular.
+
+C INPUT PARAMETERS
+define(`rp',`r16')
+define(`up',`r17')
+define(`n', `r18')
+define(`vl0',`r19')
+
+define(`numb_mask',`r6')
+
+define(`m0a',`r0')
+define(`m0b',`r1')
+define(`m1a',`r2')
+define(`m1b',`r3')
+define(`m2a',`r20')
+define(`m2b',`r21')
+define(`m3a',`r22')
+define(`m3b',`r23')
+
+define(`acc0',`r25')
+define(`acc1',`r27')
+
+define(`ul0',`r4')
+define(`ul1',`r5')
+define(`ul2',`r4')
+define(`ul3',`r5')
+
+define(`rl0',`r24')
+define(`rl1',`r24')
+define(`rl2',`r24')
+define(`rl3',`r24')
+
+define(`t0',`r7')
+define(`t1',`r8')
+
+define(`NAIL_BITS',`GMP_NAIL_BITS')
+define(`NUMB_BITS',`GMP_NUMB_BITS')
+
+dnl This declaration is munged by configure
+NAILS_SUPPORT(1-63)
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ sll vl0, NAIL_BITS, vl0
+ lda numb_mask, -1(r31)
+ srl numb_mask, NAIL_BITS, numb_mask
+
+ and n, 3, r25
+ cmpeq r25, 1, r21
+ bne r21, L(1m4)
+ cmpeq r25, 2, r21
+ bne r21, L(2m4)
+ beq r25, L(0m4)
+
+L(3m4): ldq ul3, 0(up)
+ lda n, -4(n)
+ ldq ul0, 8(up)
+ mulq vl0, ul3, m3a
+ umulh vl0, ul3, m3b
+ ldq ul1, 16(up)
+ lda up, 24(up)
+ lda rp, -8(rp)
+ mulq vl0, ul0, m0a
+ umulh vl0, ul0, m0b
+ bge n, L(ge3)
+
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ srl m3a,NAIL_BITS, t0
+ addq t0, r31, acc1
+ srl m0a,NAIL_BITS, t0
+ addq t0, m3b, acc0
+ srl acc1,NUMB_BITS, t1
+ br r31, L(ta3)
+
+L(ge3): ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ srl m3a,NAIL_BITS, t0
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ addq t0, r31, acc1
+ umulh vl0, ul2, m2b
+ srl m0a,NAIL_BITS, t0
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ addq t0, m3b, acc0
+ srl acc1,NUMB_BITS, t1
+ br r31, L(el3)
+
+L(0m4): lda n, -8(n)
+ ldq ul2, 0(up)
+ ldq ul3, 8(up)
+ mulq vl0, ul2, m2a
+ umulh vl0, ul2, m2b
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ umulh vl0, ul3, m3b
+ ldq ul1, 24(up)
+ lda up, 32(up)
+ mulq vl0, ul0, m0a
+ umulh vl0, ul0, m0b
+ bge n, L(ge4)
+
+ srl m2a,NAIL_BITS, t0
+ mulq vl0, ul1, m1a
+ addq t0, r31, acc0
+ umulh vl0, ul1, m1b
+ srl m3a,NAIL_BITS, t0
+ addq t0, m2b, acc1
+ srl acc0,NUMB_BITS, t1
+ br r31, L(ta4)
+
+L(ge4): srl m2a,NAIL_BITS, t0
+ ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ addq t0, r31, acc0
+ umulh vl0, ul1, m1b
+ srl m3a,NAIL_BITS, t0
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ addq t0, m2b, acc1
+ srl acc0,NUMB_BITS, t1
+ br r31, L(el0)
+
+L(2m4): lda n, -4(n)
+ ldq ul0, 0(up)
+ ldq ul1, 8(up)
+ lda up, 16(up)
+ lda rp, -16(rp)
+ mulq vl0, ul0, m0a
+ umulh vl0, ul0, m0b
+ bge n, L(ge2)
+
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ srl m0a,NAIL_BITS, t0
+ addq t0, r31, acc0
+ srl m1a,NAIL_BITS, t0
+ addq t0, m0b, acc1
+ srl acc0,NUMB_BITS, t1
+ br r31, L(ta2)
+
+L(ge2): ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ umulh vl0, ul2, m2b
+ srl m0a,NAIL_BITS, t0
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ addq t0, r31, acc0
+ umulh vl0, ul3, m3b
+ srl m1a,NAIL_BITS, t0
+ ldq ul1, 24(up)
+ lda up, 32(up)
+ lda rp, 32(rp)
+ mulq vl0, ul0, m0a
+ addq t0, m0b, acc1
+ srl acc0,NUMB_BITS, t1
+ bge n, L(el2)
+
+ br r31, L(ta6)
+
+L(1m4): lda n, -4(n)
+ ldq ul1, 0(up)
+ lda up, 8(up)
+ lda rp, -24(rp)
+ bge n, L(ge1)
+
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ srl m1a,NAIL_BITS, t0
+ addq t0, r31, acc1
+ and acc1,numb_mask, r28
+ srl acc1,NUMB_BITS, t1
+ stq r28, 24(rp)
+ addq t1, m1b, r0
+ ret r31, (r26), 1
+
+L(ge1): ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ umulh vl0, ul2, m2b
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ umulh vl0, ul3, m3b
+ srl m1a,NAIL_BITS, t0
+ ldq ul1, 24(up)
+ lda up, 32(up)
+ lda rp, 32(rp)
+ mulq vl0, ul0, m0a
+ addq t0, r31, acc1
+ umulh vl0, ul0, m0b
+ srl m2a,NAIL_BITS, t0
+ mulq vl0, ul1, m1a
+ addq t0, m1b, acc0
+ srl acc1,NUMB_BITS, t1
+ blt n, L(ta5)
+
+L(ge5): ldq ul2, 0(up)
+ br r31, L(el1)
+
+ ALIGN(16)
+L(top): mulq vl0, ul0, m0a C U1
+ addq t0, m0b, acc1 C L0
+ srl acc0,NUMB_BITS, t1 C U0
+ stq r28, -24(rp) C L1
+C
+L(el2): umulh vl0, ul0, m0b C U1
+ and acc0,numb_mask, r28 C L0
+ unop C U0
+ unop C L1
+C
+ unop C U1
+ addq t1, acc1, acc1 C L0
+ srl m2a,NAIL_BITS, t0 C U0
+ ldq ul2, 0(up) C L1
+C
+ mulq vl0, ul1, m1a C U1
+ addq t0, m1b, acc0 C L0
+ srl acc1,NUMB_BITS, t1 C U0
+ stq r28, -16(rp) C L1
+C
+L(el1): umulh vl0, ul1, m1b C U1
+ and acc1,numb_mask, r28 C L0
+ unop C U0
+ lda n, -4(n) C L1
+C
+ unop C U1
+ addq t1, acc0, acc0 C L0
+ srl m3a,NAIL_BITS, t0 C U0
+ ldq ul3, 8(up) C L1
+C
+ mulq vl0, ul2, m2a C U1
+ addq t0, m2b, acc1 C L0
+ srl acc0,NUMB_BITS, t1 C U0
+ stq r28, -8(rp) C L1
+C
+L(el0): umulh vl0, ul2, m2b C U1
+ and acc0,numb_mask, r28 C L0
+ unop C U0
+ unop C L1
+C
+ unop C U1
+ addq t1, acc1, acc1 C L0
+ srl m0a,NAIL_BITS, t0 C U0
+ ldq ul0, 16(up) C L1
+C
+ mulq vl0, ul3, m3a C U1
+ addq t0, m3b, acc0 C L0
+ srl acc1,NUMB_BITS, t1 C U0
+ stq r28, 0(rp) C L1
+C
+L(el3): umulh vl0, ul3, m3b C U1
+ and acc1,numb_mask, r28 C L0
+ unop C U0
+ unop C L1
+C
+ unop C U1
+ addq t1, acc0, acc0 C L0
+ srl m1a,NAIL_BITS, t0 C U0
+ ldq ul1, 24(up) C L1
+C
+ lda up, 32(up) C L0
+ unop C U1
+ lda rp, 32(rp) C L1
+ bge n, L(top) C U0
+
+L(end): mulq vl0, ul0, m0a
+ addq t0, m0b, acc1
+ srl acc0,NUMB_BITS, t1
+ stq r28, -24(rp)
+L(ta6): umulh vl0, ul0, m0b
+ and acc0,numb_mask, r28
+ addq t1, acc1, acc1
+ srl m2a,NAIL_BITS, t0
+ mulq vl0, ul1, m1a
+ addq t0, m1b, acc0
+ srl acc1,NUMB_BITS, t1
+ stq r28, -16(rp)
+L(ta5): umulh vl0, ul1, m1b
+ and acc1,numb_mask, r28
+ addq t1, acc0, acc0
+ srl m3a,NAIL_BITS, t0
+ addq t0, m2b, acc1
+ srl acc0,NUMB_BITS, t1
+ stq r28, -8(rp)
+ ALIGN(16)
+L(ta4): and acc0,numb_mask, r28
+ addq t1, acc1, acc1
+ srl m0a,NAIL_BITS, t0
+ addq t0, m3b, acc0
+ srl acc1,NUMB_BITS, t1
+ stq r28, 0(rp)
+ unop
+ ALIGN(16)
+L(ta3): and acc1,numb_mask, r28
+ addq t1, acc0, acc0
+ srl m1a,NAIL_BITS, t0
+ addq t0, m0b, acc1
+ srl acc0,NUMB_BITS, t1
+ stq r28, 8(rp)
+ unop
+ ALIGN(16)
+L(ta2): and acc0,numb_mask, r28
+ addq t1, acc1, acc1
+ srl acc1,NUMB_BITS, t1
+ stq r28, 16(rp)
+ and acc1,numb_mask, r28
+ addq t1, m1b, r0
+ stq r28, 24(rp)
+ ret r31, (r26), 1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/nails/submul_1.asm b/gmp/mpn/alpha/ev6/nails/submul_1.asm
new file mode 100644
index 0000000000..f473a59ba8
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/nails/submul_1.asm
@@ -0,0 +1,396 @@
+dnl Alpha ev6 nails mpn_submul_1.
+
+dnl Copyright 2002, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 42
+C EV5: 18
+C EV6: 4
+
+C TODO
+C * Reroll loop for 3.75 c/l with current 4-way unrolling.
+C * The loop is overscheduled wrt loads and wrt multiplies, in particular
+C umulh.
+C * Use FP loop count and multiple exit points, that would simplify feed-in lp0
+C and would work since the loop structure is really regular.
+
+C INPUT PARAMETERS
+define(`rp',`r16')
+define(`up',`r17')
+define(`n', `r18')
+define(`vl0',`r19')
+
+define(`numb_mask',`r6')
+
+define(`m0a',`r0')
+define(`m0b',`r1')
+define(`m1a',`r2')
+define(`m1b',`r3')
+define(`m2a',`r20')
+define(`m2b',`r21')
+define(`m3a',`r22')
+define(`m3b',`r23')
+
+define(`acc0',`r25')
+define(`acc1',`r27')
+
+define(`ul0',`r4')
+define(`ul1',`r5')
+define(`ul2',`r4')
+define(`ul3',`r5')
+
+define(`rl0',`r24')
+define(`rl1',`r24')
+define(`rl2',`r24')
+define(`rl3',`r24')
+
+define(`t0',`r7')
+define(`t1',`r8')
+
+define(`NAIL_BITS',`GMP_NAIL_BITS')
+define(`NUMB_BITS',`GMP_NUMB_BITS')
+
+dnl This declaration is munged by configure
+NAILS_SUPPORT(2-63)
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ sll vl0, NAIL_BITS, vl0
+ lda numb_mask, -1(r31)
+ srl numb_mask, NAIL_BITS, numb_mask
+
+ and n, 3, r25
+ cmpeq r25, 1, r21
+ bne r21, L(1m4)
+ cmpeq r25, 2, r21
+ bne r21, L(2m4)
+ beq r25, L(0m4)
+
+L(3m4): ldq ul3, 0(up)
+ lda n, -4(n)
+ ldq ul0, 8(up)
+ mulq vl0, ul3, m3a
+ umulh vl0, ul3, m3b
+ ldq ul1, 16(up)
+ lda up, 24(up)
+ lda rp, -8(rp)
+ mulq vl0, ul0, m0a
+ umulh vl0, ul0, m0b
+ bge n, L(ge3)
+
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq rl3, 8(rp)
+ srl m3a,NAIL_BITS, t0
+ addq t0, r31, acc1
+ subq rl3, acc1, acc1
+ ldq rl0, 16(rp)
+ srl m0a,NAIL_BITS, t0
+ addq t0, m3b, acc0
+ sra acc1,NUMB_BITS, t1
+ br r31, L(ta3)
+
+L(ge3): ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq rl3, 8(rp)
+ srl m3a,NAIL_BITS, t0
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ addq t0, r31, acc1
+ umulh vl0, ul2, m2b
+ subq rl3, acc1, acc1
+ ldq rl0, 16(rp)
+ srl m0a,NAIL_BITS, t0
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ addq t0, m3b, acc0
+ sra acc1,NUMB_BITS, t1
+ br r31, L(el3)
+
+L(0m4): lda n, -8(n)
+ ldq ul2, 0(up)
+ ldq ul3, 8(up)
+ mulq vl0, ul2, m2a
+ umulh vl0, ul2, m2b
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ umulh vl0, ul3, m3b
+ ldq ul1, 24(up)
+ lda up, 32(up)
+ mulq vl0, ul0, m0a
+ umulh vl0, ul0, m0b
+ bge n, L(ge4)
+
+ ldq rl2, 0(rp)
+ srl m2a,NAIL_BITS, t0
+ mulq vl0, ul1, m1a
+ addq t0, r31, acc0
+ umulh vl0, ul1, m1b
+ subq rl2, acc0, acc0
+ ldq rl3, 8(rp)
+ srl m3a,NAIL_BITS, t0
+ addq t0, m2b, acc1
+ sra acc0,NUMB_BITS, t1
+ br r31, L(ta4)
+
+L(ge4): ldq rl2, 0(rp)
+ srl m2a,NAIL_BITS, t0
+ ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ addq t0, r31, acc0
+ umulh vl0, ul1, m1b
+ subq rl2, acc0, acc0
+ ldq rl3, 8(rp)
+ srl m3a,NAIL_BITS, t0
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ addq t0, m2b, acc1
+ sra acc0,NUMB_BITS, t1
+ br r31, L(el0)
+
+L(2m4): lda n, -4(n)
+ ldq ul0, 0(up)
+ ldq ul1, 8(up)
+ lda up, 16(up)
+ lda rp, -16(rp)
+ mulq vl0, ul0, m0a
+ umulh vl0, ul0, m0b
+ bge n, L(ge2)
+
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq rl0, 16(rp)
+ srl m0a,NAIL_BITS, t0
+ addq t0, r31, acc0
+ subq rl0, acc0, acc0
+ ldq rl1, 24(rp)
+ srl m1a,NAIL_BITS, t0
+ addq t0, m0b, acc1
+ sra acc0,NUMB_BITS, t1
+ br r31, L(ta2)
+
+L(ge2): ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ umulh vl0, ul2, m2b
+ ldq rl0, 16(rp)
+ srl m0a,NAIL_BITS, t0
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ addq t0, r31, acc0
+ umulh vl0, ul3, m3b
+ subq rl0, acc0, acc0
+ ldq rl1, 24(rp)
+ srl m1a,NAIL_BITS, t0
+ ldq ul1, 24(up)
+ lda up, 32(up)
+ lda rp, 32(rp)
+ mulq vl0, ul0, m0a
+ addq t0, m0b, acc1
+ sra acc0,NUMB_BITS, t1
+ bge n, L(el2)
+
+ br r31, L(ta6)
+
+L(1m4): lda n, -4(n)
+ ldq ul1, 0(up)
+ lda up, 8(up)
+ lda rp, -24(rp)
+ bge n, L(ge1)
+
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq rl1, 24(rp)
+ srl m1a,NAIL_BITS, t0
+ subq rl1, t0, acc1
+ and acc1,numb_mask, r28
+ sra acc1,NUMB_BITS, t1
+ stq r28, 24(rp)
+ subq m1b, t1, r0
+ ret r31, (r26), 1
+
+L(ge1): ldq ul2, 0(up)
+ mulq vl0, ul1, m1a
+ umulh vl0, ul1, m1b
+ ldq ul3, 8(up)
+ lda n, -4(n)
+ mulq vl0, ul2, m2a
+ umulh vl0, ul2, m2b
+ ldq ul0, 16(up)
+ mulq vl0, ul3, m3a
+ umulh vl0, ul3, m3b
+ ldq rl1, 24(rp)
+ srl m1a,NAIL_BITS, t0
+ ldq ul1, 24(up)
+ lda up, 32(up)
+ lda rp, 32(rp)
+ mulq vl0, ul0, m0a
+ addq t0, r31, acc1
+ umulh vl0, ul0, m0b
+ subq rl1, acc1, acc1
+ ldq rl2, 0(rp)
+ srl m2a,NAIL_BITS, t0
+ mulq vl0, ul1, m1a
+ addq t0, m1b, acc0
+ sra acc1,NUMB_BITS, t1
+ blt n, L(ta5)
+
+L(ge5): ldq ul2, 0(up)
+ br r31, L(el1)
+
+ ALIGN(16)
+L(top): mulq vl0, ul0, m0a C U1
+ addq t0, m0b, acc1 C L0
+ sra acc0,NUMB_BITS, t1 C U0
+ stq r28, -24(rp) C L1
+C
+L(el2): umulh vl0, ul0, m0b C U1
+ and acc0,numb_mask, r28 C L0
+ subq rl1, acc1, acc1 C U0
+ ldq rl2, 0(rp) C L1
+C
+ unop C U1
+ addq t1, acc1, acc1 C L0
+ srl m2a,NAIL_BITS, t0 C U0
+ ldq ul2, 0(up) C L1
+C
+ mulq vl0, ul1, m1a C U1
+ addq t0, m1b, acc0 C L0
+ sra acc1,NUMB_BITS, t1 C U0
+ stq r28, -16(rp) C L1
+C
+L(el1): umulh vl0, ul1, m1b C U1
+ and acc1,numb_mask, r28 C L0
+ subq rl2, acc0, acc0 C U0
+ ldq rl3, 8(rp) C L1
+C
+ lda n, -4(n) C L1
+ addq t1, acc0, acc0 C L0
+ srl m3a,NAIL_BITS, t0 C U0
+ ldq ul3, 8(up) C L1
+C
+ mulq vl0, ul2, m2a C U1
+ addq t0, m2b, acc1 C L0
+ sra acc0,NUMB_BITS, t1 C U0
+ stq r28, -8(rp) C L1
+C
+L(el0): umulh vl0, ul2, m2b C U1
+ and acc0,numb_mask, r28 C L0
+ subq rl3, acc1, acc1 C U0
+ ldq rl0, 16(rp) C L1
+C
+ unop C U1
+ addq t1, acc1, acc1 C L0
+ srl m0a,NAIL_BITS, t0 C U0
+ ldq ul0, 16(up) C L1
+C
+ mulq vl0, ul3, m3a C U1
+ addq t0, m3b, acc0 C L0
+ sra acc1,NUMB_BITS, t1 C U0
+ stq r28, 0(rp) C L1
+C
+L(el3): umulh vl0, ul3, m3b C U1
+ and acc1,numb_mask, r28 C L0
+ subq rl0, acc0, acc0 C U0
+ ldq rl1, 24(rp) C L1
+C
+ unop C U1
+ addq t1, acc0, acc0 C L0
+ srl m1a,NAIL_BITS, t0 C U0
+ ldq ul1, 24(up) C L1
+C
+ lda up, 32(up) C L0
+ unop C U1
+ lda rp, 32(rp) C L1
+ bge n, L(top) C U0
+
+L(end): mulq vl0, ul0, m0a
+ addq t0, m0b, acc1
+ sra acc0,NUMB_BITS, t1
+ stq r28, -24(rp)
+L(ta6): umulh vl0, ul0, m0b
+ and acc0,numb_mask, r28
+ subq rl1, acc1, acc1
+ ldq rl2, 0(rp)
+ addq t1, acc1, acc1
+ srl m2a,NAIL_BITS, t0
+ mulq vl0, ul1, m1a
+ addq t0, m1b, acc0
+ sra acc1,NUMB_BITS, t1
+ stq r28, -16(rp)
+L(ta5): umulh vl0, ul1, m1b
+ and acc1,numb_mask, r28
+ subq rl2, acc0, acc0
+ ldq rl3, 8(rp)
+ addq t1, acc0, acc0
+ srl m3a,NAIL_BITS, t0
+ addq t0, m2b, acc1
+ sra acc0,NUMB_BITS, t1
+ stq r28, -8(rp)
+ unop
+ ALIGN(16)
+L(ta4): and acc0,numb_mask, r28
+ subq rl3, acc1, acc1
+ ldq rl0, 16(rp)
+ addq t1, acc1, acc1
+ srl m0a,NAIL_BITS, t0
+ addq t0, m3b, acc0
+ sra acc1,NUMB_BITS, t1
+ stq r28, 0(rp)
+ unop
+ ALIGN(16)
+L(ta3): and acc1,numb_mask, r28
+ subq rl0, acc0, acc0
+ ldq rl1, 24(rp)
+ addq t1, acc0, acc0
+ srl m1a,NAIL_BITS, t0
+ addq t0, m0b, acc1
+ sra acc0,NUMB_BITS, t1
+ stq r28, 8(rp)
+ unop
+ ALIGN(16)
+L(ta2): and acc0,numb_mask, r28
+ subq rl1, acc1, acc1
+ addq t1, acc1, acc1
+ sra acc1,NUMB_BITS, t1
+ stq r28, 16(rp)
+ and acc1,numb_mask, r28
+ subq m1b, t1, r0
+ stq r28, 24(rp)
+ ret r31, (r26), 1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev6/slot.pl b/gmp/mpn/alpha/ev6/slot.pl
new file mode 100755
index 0000000000..a4c8a36882
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/slot.pl
@@ -0,0 +1,318 @@
+#!/usr/bin/perl -w
+
+# Copyright 2000, 2001, 2003-2005, 2011 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: slot.pl [filename.o]...
+#
+# Run "objdump" to produce a disassembly of the given object file(s) and
+# annotate the output with "U" or "L" slotting which Alpha EV6 will use.
+#
+# When an instruction is E (ie. either U or L), an "eU" or "eL" is shown, as
+# a reminder that it wasn't a fixed requirement that gave the U or L, but
+# the octaword slotting rules.
+#
+# If an instruction is not recognised, that octaword does not get any U/L
+# shown, only lower-case "u", "l" or "e" for the instructions which are
+# known. Add any unknown instructions to %optable below.
+
+
+use strict;
+
+# The U or L which various instructions demand, or E if either.
+#
+my %optable =
+ (
+ 'addq' => 'E',
+ 'and' => 'E',
+ 'andnot' => 'E',
+ 'beq' => 'U',
+ 'bge' => 'U',
+ 'bgt' => 'U',
+ 'bic' => 'E',
+ 'bis' => 'E',
+ 'blt' => 'U',
+ 'bne' => 'U',
+ 'br' => 'L',
+ 'clr' => 'E',
+ 'cmpule' => 'E',
+ 'cmpult' => 'E',
+ 'cmpeq' => 'E',
+ 'cmoveq' => 'E',
+ 'cmovne' => 'E',
+ 'ctpop' => 'U',
+ 'ctlz' => 'U',
+ 'cttz' => 'U',
+ 'extbl' => 'U',
+ 'extlh' => 'U',
+ 'extll' => 'U',
+ 'extqh' => 'U',
+ 'extql' => 'U',
+ 'extwh' => 'U',
+ 'extwl' => 'U',
+ 'jsr' => 'L',
+ 'lda' => 'E',
+ 'ldah' => 'E',
+ 'ldbu' => 'L',
+ 'ldl' => 'L',
+ 'ldq' => 'L',
+ 'ldt' => 'L',
+ 'ret' => 'L',
+ 'mov' => 'E',
+ 'mull' => 'U',
+ 'mulq' => 'U',
+ 'negq' => 'E',
+ 'nop' => 'E',
+ 'not' => 'E',
+ 's8addq' => 'E',
+ 's8subq' => 'E',
+ # 'sextb' => ?
+ # 'sextl' => ?
+ 'sll' => 'U',
+ 'srl' => 'U',
+ 'stq' => 'L',
+ 'subq' => 'E',
+ 'umulh' => 'U',
+ 'unop' => 'E',
+ 'xor' => 'E',
+ );
+
+# Slottings used for a given pattern of U/L/E in an octaword. This is as
+# per the "Ebox Slotting" section of the EV6 hardware reference manual.
+#
+my %slottable =
+ (
+ 'EEEE' => 'ULUL',
+ 'EEEL' => 'ULUL',
+ 'EEEU' => 'ULLU',
+ 'EELE' => 'ULLU',
+ 'EELL' => 'UULL',
+ 'EELU' => 'ULLU',
+ 'EEUE' => 'ULUL',
+ 'EEUL' => 'ULUL',
+ 'EEUU' => 'LLUU',
+ 'ELEE' => 'ULUL',
+ 'ELEL' => 'ULUL',
+ 'ELEU' => 'ULLU',
+ 'ELLE' => 'ULLU',
+ 'ELLL' => 'ULLL',
+ 'ELLU' => 'ULLU',
+ 'ELUE' => 'ULUL',
+ 'ELUL' => 'ULUL',
+
+ 'LLLL' => 'LLLL',
+ 'LLLU' => 'LLLU',
+ 'LLUE' => 'LLUU',
+ 'LLUL' => 'LLUL',
+ 'LLUU' => 'LLUU',
+ 'LUEE' => 'LULU',
+ 'LUEL' => 'LUUL',
+ 'LUEU' => 'LULU',
+ 'LULE' => 'LULU',
+ 'LULL' => 'LULL',
+ 'LULU' => 'LULU',
+ 'LUUE' => 'LUUL',
+ 'LUUL' => 'LUUL',
+ 'LUUU' => 'LUUU',
+ 'UEEE' => 'ULUL',
+ 'UEEL' => 'ULUL',
+ 'UEEU' => 'ULLU',
+
+ 'ELUU' => 'LLUU',
+ 'EUEE' => 'LULU',
+ 'EUEL' => 'LUUL',
+ 'EUEU' => 'LULU',
+ 'EULE' => 'LULU',
+ 'EULL' => 'UULL',
+ 'EULU' => 'LULU',
+ 'EUUE' => 'LUUL',
+ 'EUUL' => 'LUUL',
+ 'EUUU' => 'LUUU',
+ 'LEEE' => 'LULU',
+ 'LEEL' => 'LUUL',
+ 'LEEU' => 'LULU',
+ 'LELE' => 'LULU',
+ 'LELL' => 'LULL',
+ 'LELU' => 'LULU',
+ 'LEUE' => 'LUUL',
+ 'LEUL' => 'LUUL',
+ 'LEUU' => 'LLUU',
+ 'LLEE' => 'LLUU',
+ 'LLEL' => 'LLUL',
+ 'LLEU' => 'LLUU',
+ 'LLLE' => 'LLLU',
+
+ 'UELE' => 'ULLU',
+ 'UELL' => 'UULL',
+ 'UELU' => 'ULLU',
+ 'UEUE' => 'ULUL',
+ 'UEUL' => 'ULUL',
+ 'UEUU' => 'ULUU',
+ 'ULEE' => 'ULUL',
+ 'ULEL' => 'ULUL',
+ 'ULEU' => 'ULLU',
+ 'ULLE' => 'ULLU',
+ 'ULLL' => 'ULLL',
+ 'ULLU' => 'ULLU',
+ 'ULUE' => 'ULUL',
+ 'ULUL' => 'ULUL',
+ 'ULUU' => 'ULUU',
+ 'UUEE' => 'UULL',
+ 'UUEL' => 'UULL',
+ 'UUEU' => 'UULU',
+ 'UULE' => 'UULL',
+ 'UULL' => 'UULL',
+ 'UULU' => 'UULU',
+ 'UUUE' => 'UUUL',
+ 'UUUL' => 'UUUL',
+ 'UUUU' => 'UUUU',
+ );
+
+# Check all combinations of U/L/E are present in %slottable.
+sub coverage {
+ foreach my $a ('U', 'L', 'E') {
+ foreach my $b ('U', 'L', 'E') {
+ foreach my $c ('U', 'L', 'E') {
+ foreach my $d ('U', 'L', 'E') {
+ my $x = $a . $b . $c . $d;
+ if (! defined $slottable{$x}) {
+ print "slottable missing: $x\n"
+ }
+ }
+ }
+ }
+ }
+}
+
+# Certain consistency checks for %slottable.
+sub check {
+ foreach my $x (keys %slottable) {
+ my $a = substr($x,0,1);
+ my $b = substr($x,1,1);
+ my $c = substr($x,2,1);
+ my $d = substr($x,3,1);
+ my $es = ($a eq 'E') + ($b eq 'E') + ($c eq 'E') + ($d eq 'E');
+ my $ls = ($a eq 'L') + ($b eq 'L') + ($c eq 'L') + ($d eq 'L');
+ my $us = ($a eq 'U') + ($b eq 'U') + ($c eq 'U') + ($d eq 'U');
+
+ my $got = $slottable{$x};
+ my $want = $x;
+
+ if ($es == 0) {
+
+ } elsif ($es == 1) {
+ # when only one E, it's mapped to whichever of U or L is otherwise
+ # used the least
+ if ($ls > $us) {
+ $want =~ s/E/U/;
+ } else {
+ $want =~ s/E/L/;
+ }
+ } elsif ($es == 2) {
+ # when two E's and two U, then the E's map to L; vice versa for two E
+ # and two L
+ if ($ls == 2) {
+ $want =~ s/E/U/g;
+ } elsif ($us == 2) {
+ $want =~ s/E/L/g;
+ } else {
+ next;
+ }
+ } elsif ($es == 3) {
+ next;
+
+ } else { # $es == 4
+ next;
+ }
+
+ if ($want ne $got) {
+ print "slottable $x want $want got $got\n";
+ }
+ }
+}
+
+sub disassemble {
+ my ($file) = @_;
+
+ open (IN, "objdump -Srfh $file |") || die "Cannot open pipe from objdump\n";
+
+ my (%pre, %post, %type);
+ while (<IN>) {
+ my $line = $_ . "";
+
+ if ($line =~ /(^[ \t]*[0-9a-f]*([0-9a-f]):[ \t]*[0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] )\t(([a-z0-9]+).*)/) {
+ my ($this_pre, $addr, $this_post, $opcode) = ($1, $2, $3, $4);
+
+ my $this_type = $optable{$opcode};
+ if (! defined ($this_type)) { $this_type = ' '; }
+
+ $pre{$addr} = $this_pre;
+ $post{$addr} = $this_post;
+ $type{$addr} = $this_type;
+
+ if ($addr eq 'c') {
+ my %slot = ('0'=>' ', '4'=>' ', '8'=>' ', 'c'=>' ');
+
+ my $str = $type{'c'} . $type{'8'} . $type{'4'} . $type{'0'};
+ $str = $slottable{$str};
+ if (defined $str) {
+ $slot{'c'} = substr($str,0,1);
+ $slot{'8'} = substr($str,1,1);
+ $slot{'4'} = substr($str,2,1);
+ $slot{'0'} = substr($str,3,1);
+ }
+
+ foreach my $i ('0', '4', '8', 'c') {
+ if ($slot{$i} eq $type{$i}) { $type{$i} = ' '; }
+ print $pre{$i}, ' ', lc($type{$i}),$slot{$i}, ' ', $post{$i}, "\n";
+ }
+
+ %pre = ();
+ %type = ();
+ %post = ();
+ }
+ }
+ }
+
+ close IN || die "Error from objdump (or objdump not available)\n";
+}
+
+coverage();
+check();
+
+my @files;
+if ($#ARGV >= 0) {
+ @files = @ARGV;
+} else {
+ die
+}
+
+foreach (@files) {
+ disassemble($_);
+}
diff --git a/gmp/mpn/alpha/ev6/sub_n.asm b/gmp/mpn/alpha/ev6/sub_n.asm
new file mode 100644
index 0000000000..a35ba40d34
--- /dev/null
+++ b/gmp/mpn/alpha/ev6/sub_n.asm
@@ -0,0 +1,283 @@
+dnl Alpha ev6 mpn_sub_n -- Subtract two limb vectors of the same length > 0
+dnl and store difference in a third limb vector.
+
+dnl Copyright 2000, 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 5.4
+C EV6: 2.125
+
+C INPUT PARAMETERS
+C rp r16
+C up r17
+C vp r18
+C n r19
+C cy r20 (for mpn_add_nc)
+
+C TODO
+C Finish cleaning up cy registers r22, r23 (make them use cy0/cy1)
+C Use multi-pronged feed-in.
+C Perform additional micro-tuning
+
+C This code was written in cooperation with ev6 pipeline expert Steve Root.
+
+C Pair loads and stores where possible
+C Store pairs oct-aligned where possible (didn't need it here)
+C Stores are delayed every third cycle
+C Loads and stores are delayed by fills
+C U stays still, put code there where possible (note alternation of U1 and U0)
+C L moves because of loads and stores
+C Note dampers in L to limit damage
+
+C This odd-looking optimization expects that were having random bits in our
+C data, so that a pure zero result is unlikely. so we penalize the unlikely
+C case to help the common case.
+
+define(`u0', `r0') define(`u1', `r3')
+define(`v0', `r1') define(`v1', `r4')
+
+define(`cy0', `r20') define(`cy1', `r21')
+
+MULFUNC_PROLOGUE(mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+PROLOGUE(mpn_sub_nc)
+ br r31, $entry
+EPILOGUE()
+PROLOGUE(mpn_sub_n)
+ bis r31, r31, cy0 C clear carry in
+$entry: cmpult r19, 5, r22 C L1 move counter
+ ldq u1, 0(r17) C L0 get next ones
+ ldq v1, 0(r18) C L1
+ bne r22, $Lsmall
+
+ ldq u0, 8(r17) C L0 get next ones
+ ldq v0, 8(r18) C L1
+ subq u1, v1, r5 C U0 sub two data
+
+ cmpult u1, v1, r23 C U0 did it borrow
+ ldq u1, 16(r17) C L0 get next ones
+ ldq v1, 16(r18) C L1
+
+ subq u0, v0, r8 C U1 sub two data
+ subq r5, cy0, r24 C U0 borrow in
+
+ cmpult u0, v0, r22 C U1 did it borrow
+ beq r5, $fix5f C U0 fix exact zero
+$ret5f: ldq u0, 24(r17) C L0 get next ones
+ ldq v0, 24(r18) C L1
+
+ subq r8, r23, r25 C U1 borrow from last
+ subq u1, v1, r7 C U0 sub two data
+
+ beq r8, $fix6f C U1 fix exact zero
+$ret6f: cmpult u1, v1, r23 C U0 did it borrow
+ ldq u1, 32(r17) C L0 get next ones
+ ldq v1, 32(r18) C L1
+
+ lda r17, 40(r17) C L0 move pointer
+ lda r18, 40(r18) C L1 move pointer
+
+ lda r16, -8(r16)
+ lda r19, -13(r19) C L1 move counter
+ blt r19, $Lend C U1 loop control
+
+
+C Main loop. 8-way unrolled.
+ ALIGN(16)
+$Loop: subq u0, v0, r2 C U1 sub two data
+ stq r24, 8(r16) C L0 put an answer
+ subq r7, r22, r24 C U0 borrow from last
+ stq r25, 16(r16) C L1 pair
+
+ cmpult u0, v0, cy1 C U1 did it borrow
+ beq r7, $fix7 C U0 fix exact 0
+$ret7: ldq u0, 0(r17) C L0 get next ones
+ ldq v0, 0(r18) C L1
+
+ bis r31, r31, r31 C L damp out
+ subq r2, r23, r25 C U1 borrow from last
+ bis r31, r31, r31 C L moves in L !
+ subq u1, v1, r5 C U0 sub two data
+
+ beq r2, $fix0 C U1 fix exact zero
+$ret0: cmpult u1, v1, cy0 C U0 did it borrow
+ ldq u1, 8(r17) C L0 get next ones
+ ldq v1, 8(r18) C L1
+
+ subq u0, v0, r8 C U1 sub two data
+ stq r24, 24(r16) C L0 store pair
+ subq r5, cy1, r24 C U0 borrow from last
+ stq r25, 32(r16) C L1
+
+ cmpult u0, v0, r22 C U1 did it borrow
+ beq r5, $fix1 C U0 fix exact zero
+$ret1: ldq u0, 16(r17) C L0 get next ones
+ ldq v0, 16(r18) C L1
+
+ lda r16, 64(r16) C L0 move pointer
+ subq r8, cy0, r25 C U1 borrow from last
+ lda r19, -8(r19) C L1 move counter
+ subq u1, v1, r7 C U0 sub two data
+
+ beq r8, $fix2 C U1 fix exact zero
+$ret2: cmpult u1, v1, r23 C U0 did it borrow
+ ldq u1, 24(r17) C L0 get next ones
+ ldq v1, 24(r18) C L1
+
+ subq u0, v0, r2 C U1 sub two data
+ stq r24, -24(r16) C L0 put an answer
+ subq r7, r22, r24 C U0 borrow from last
+ stq r25, -16(r16) C L1 pair
+
+ cmpult u0, v0, cy1 C U1 did it borrow
+ beq r7, $fix3 C U0 fix exact 0
+$ret3: ldq u0, 32(r17) C L0 get next ones
+ ldq v0, 32(r18) C L1
+
+ bis r31, r31, r31 C L damp out
+ subq r2, r23, r25 C U1 borrow from last
+ bis r31, r31, r31 C L moves in L !
+ subq u1, v1, r5 C U0 sub two data
+
+ beq r2, $fix4 C U1 fix exact zero
+$ret4: cmpult u1, v1, cy0 C U0 did it borrow
+ ldq u1, 40(r17) C L0 get next ones
+ ldq v1, 40(r18) C L1
+
+ subq u0, v0, r8 C U1 sub two data
+ stq r24, -8(r16) C L0 store pair
+ subq r5, cy1, r24 C U0 borrow from last
+ stq r25, 0(r16) C L1
+
+ cmpult u0, v0, r22 C U1 did it borrow
+ beq r5, $fix5 C U0 fix exact zero
+$ret5: ldq u0, 48(r17) C L0 get next ones
+ ldq v0, 48(r18) C L1
+
+ ldl r31, 256(r17) C L0 prefetch
+ subq r8, cy0, r25 C U1 borrow from last
+ ldl r31, 256(r18) C L1 prefetch
+ subq u1, v1, r7 C U0 sub two data
+
+ beq r8, $fix6 C U1 fix exact zero
+$ret6: cmpult u1, v1, r23 C U0 did it borrow
+ ldq u1, 56(r17) C L0 get next ones
+ ldq v1, 56(r18) C L1
+
+ lda r17, 64(r17) C L0 move pointer
+ bis r31, r31, r31 C U
+ lda r18, 64(r18) C L1 move pointer
+ bge r19, $Loop C U1 loop control
+C ==== main loop end
+
+$Lend: subq u0, v0, r2 C U1 sub two data
+ stq r24, 8(r16) C L0 put an answer
+ subq r7, r22, r24 C U0 borrow from last
+ stq r25, 16(r16) C L1 pair
+ cmpult u0, v0, cy1 C U1 did it borrow
+ beq r7, $fix7c C U0 fix exact 0
+$ret7c: subq r2, r23, r25 C U1 borrow from last
+ subq u1, v1, r5 C U0 sub two data
+ beq r2, $fix0c C U1 fix exact zero
+$ret0c: cmpult u1, v1, cy0 C U0 did it borrow
+ stq r24, 24(r16) C L0 store pair
+ subq r5, cy1, r24 C U0 borrow from last
+ stq r25, 32(r16) C L1
+ beq r5, $fix1c C U0 fix exact zero
+$ret1c: stq r24, 40(r16) C L0 put an answer
+ lda r16, 48(r16) C L0 move pointer
+
+ lda r19, 8(r19)
+ beq r19, $Lret
+
+ ldq u1, 0(r17)
+ ldq v1, 0(r18)
+$Lsmall:
+ lda r19, -1(r19)
+ beq r19, $Lend0
+
+ ALIGN(8)
+$Loop0: subq u1, v1, r2 C main sub
+ cmpult u1, v1, r8 C compute bw from last sub
+ ldq u1, 8(r17)
+ ldq v1, 8(r18)
+ subq r2, cy0, r5 C borrow sub
+ lda r17, 8(r17)
+ lda r18, 8(r18)
+ stq r5, 0(r16)
+ cmpult r2, cy0, cy0 C compute bw from last sub
+ lda r19, -1(r19) C decr loop cnt
+ bis r8, cy0, cy0 C combine bw from the two subs
+ lda r16, 8(r16)
+ bne r19, $Loop0
+$Lend0: subq u1, v1, r2 C main sub
+ subq r2, cy0, r5 C borrow sub
+ cmpult u1, v1, r8 C compute bw from last sub
+ cmpult r2, cy0, cy0 C compute bw from last sub
+ stq r5, 0(r16)
+ bis r8, cy0, r0 C combine bw from the two subs
+ ret r31,(r26),1
+
+ ALIGN(8)
+$Lret: lda r0, 0(cy0) C copy borrow into return register
+ ret r31,(r26),1
+
+$fix5f: bis r23, cy0, r23 C bring forward borrow
+ br r31, $ret5f
+$fix6f: bis r22, r23, r22 C bring forward borrow
+ br r31, $ret6f
+$fix0: bis cy1, r23, cy1 C bring forward borrow
+ br r31, $ret0
+$fix1: bis cy0, cy1, cy0 C bring forward borrow
+ br r31, $ret1
+$fix2: bis r22, cy0, r22 C bring forward borrow
+ br r31, $ret2
+$fix3: bis r23, r22, r23 C bring forward borrow
+ br r31, $ret3
+$fix4: bis cy1, r23, cy1 C bring forward borrow
+ br r31, $ret4
+$fix5: bis cy1, cy0, cy0 C bring forward borrow
+ br r31, $ret5
+$fix6: bis r22, cy0, r22 C bring forward borrow
+ br r31, $ret6
+$fix7: bis r23, r22, r23 C bring forward borrow
+ br r31, $ret7
+$fix0c: bis cy1, r23, cy1 C bring forward borrow
+ br r31, $ret0c
+$fix1c: bis cy0, cy1, cy0 C bring forward borrow
+ br r31, $ret1c
+$fix7c: bis r23, r22, r23 C bring forward borrow
+ br r31, $ret7c
+
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev67/gcd_1.asm b/gmp/mpn/alpha/ev67/gcd_1.asm
new file mode 100644
index 0000000000..55fa7d3673
--- /dev/null
+++ b/gmp/mpn/alpha/ev67/gcd_1.asm
@@ -0,0 +1,145 @@
+dnl Alpha ev67 mpn_gcd_1 -- Nx1 greatest common divisor.
+
+dnl Copyright 2003, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C ev67: 3.4 cycles/bitpair for 1x1 part
+
+
+C mp_limb_t mpn_gcd_1 (mp_srcptr xp, mp_size_t xsize, mp_limb_t y);
+C
+C In the 1x1 part, the algorithm is to change x,y to abs(x-y),min(x,y) and
+C strip trailing zeros from abs(x-y) to maintain x and y both odd.
+C
+C The trailing zeros are calculated from just x-y, since in twos-complement
+C there's the same number of trailing zeros on d or -d. This means the cttz
+C runs in parallel with abs(x-y).
+C
+C The loop takes 5 cycles, and at 0.68 iterations per bit for two N-bit
+C operands with this algorithm gives the measured 3.4 c/l.
+C
+C The slottings shown are for SVR4 style systems, Unicos differs in the
+C initial gp setup and the LEA.
+C
+C Enhancement:
+C
+C On the jsr, !lituse_jsr! (when available) would allow the linker to relax
+C it to a bsr, but probably only in a static binary. Plain "jsr foo" gives
+C the right object code for relaxation, and ought to be available
+C everywhere, but we prefer to schedule the GOT ldq (LEA) back earlier, for
+C the usual case of running in a shared library.
+C
+C bsr could perhaps be used explicitly anyway. We should be able to assume
+C modexact is in the same module as us (ie. shared library or mainline).
+C Would there be any worries about the size of the displacement? Could
+C always put modexact and gcd_1 in the same .o to be certain.
+
+ASM_START()
+PROLOGUE(mpn_gcd_1, gp)
+
+ C r16 xp
+ C r17 size
+ C r18 y
+
+ C ldah C l
+ C lda C u
+
+ ldq r0, 0(r16) C L x = xp[0]
+ lda r30, -32(r30) C u alloc stack
+
+ LEA( r27, mpn_modexact_1c_odd) C L modexact addr, ldq (gp)
+ stq r10, 16(r30) C L save r10
+ cttz r18, r10 C U0 y twos
+ cmpeq r17, 1, r5 C u test size==1
+
+ stq r9, 8(r30) C L save r9
+ clr r19 C u zero c for modexact
+ unop
+ unop
+
+ cttz r0, r6 C U0 x twos
+ stq r26, 0(r30) C L save ra
+
+ srl r18, r10, r18 C U y odd
+
+ mov r18, r9 C l hold y across call
+
+ cmpult r6, r10, r2 C u test x_twos < y_twos
+
+ cmovne r2, r6, r10 C l common_twos = min(x_twos,y_twos)
+ bne r5, L(one) C U no modexact if size==1
+ jsr r26, (r27), mpn_modexact_1c_odd C L0
+
+ LDGP( r29, 0(r26)) C u,l ldah,lda
+ cttz r0, r6 C U0 new x twos
+ ldq r26, 0(r30) C L restore ra
+
+L(one):
+ mov r9, r1 C u y
+ ldq r9, 8(r30) C L restore r9
+ mov r10, r2 C u common twos
+ ldq r10, 16(r30) C L restore r10
+
+ lda r30, 32(r30) C l free stack
+ beq r0, L(done) C U return y if x%y==0
+
+ srl r0, r6, r0 C U x odd
+ unop
+
+ ALIGN(16)
+L(top):
+ C r0 x
+ C r1 y
+ C r2 common twos, for use at end
+
+ subq r0, r1, r7 C l0 d = x - y
+ cmpult r0, r1, r16 C u0 test x >= y
+
+ subq r1, r0, r4 C l0 new_x = y - x
+ cttz r7, r8 C U0 d twos
+
+ cmoveq r16, r7, r4 C l0 new_x = d if x>=y
+ cmovne r16, r0, r1 C u0 y = x if x<y
+ unop C l \ force cmoveq into l0
+ unop C u /
+
+ C C cmoveq2 L0, cmovne2 U0
+
+ srl r4, r8, r0 C U0 x = new_x >> twos
+ bne r7, L(top) C U1 stop when d==0
+
+
+L(done):
+ sll r1, r2, r0 C U0 return y << common_twos
+ ret r31, (r26), 1 C L0
+
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev67/hamdist.asm b/gmp/mpn/alpha/ev67/hamdist.asm
new file mode 100644
index 0000000000..4b13e9f14f
--- /dev/null
+++ b/gmp/mpn/alpha/ev67/hamdist.asm
@@ -0,0 +1,111 @@
+dnl Alpha ev67 mpn_hamdist -- mpn hamming distance.
+
+dnl Copyright 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C ev67: 2.5 cycles/limb
+
+
+C unsigned long mpn_hamdist (mp_srcptr xp, mp_srcptr yp, mp_size_t size);
+C
+C The hope was for 2.0 c/l here, but that isn't achieved. We're limited by
+C renaming register shortage. Since we need 5 instructions per limb, further
+C unrolling could approach 1.5 c/l.
+C
+C The main loop processes two limbs from each operand on each iteration. An
+C odd size is handled by processing xp[0]^yp[0] at the start. If the size
+C is even that result is discarded, and is repeated by the main loop.
+C
+
+ASM_START()
+PROLOGUE(mpn_hamdist)
+
+ C r16 xp
+ C r17 yp
+ C r18 size
+
+ ldq r1, 0(r16) C L0 xp[0]
+ ldq r2, 0(r17) C L1 yp[0]
+ and r18, 1, r8 C U1 1 if size odd
+ srl r18, 1, r18 C U0 size, limb pairs
+
+ clr r0 C L0 initial total
+ s8addq r8, r17, r17 C U1 yp++ if size odd
+ s8addq r8, r16, r16 C L1 xp++ if size odd
+ clr r6 C U0 dummy initial xor 1
+
+ xor r1, r2, r5 C L initial xor 0
+ beq r18, L(one) C U if size==1
+
+ cmoveq r8, r31, r5 C L discard first limb if size even
+ unop C U
+
+
+ ALIGN(16)
+L(top):
+ C r0 total accumulating
+ C r7 xor 0
+ C r8 xor 1
+ C r16 xp, incrementing
+ C r17 yp, incrementing
+ C r18 size, limb pairs, decrementing
+
+ ldq r1, 0(r16) C L
+ ldq r2, 0(r17) C L
+ ctpop r5, r7 C U0
+ lda r16, 16(r16) C U
+
+ ldq r3, -8(r16) C L
+ ldq r4, 8(r17) C L
+ ctpop r6, r8 C U0
+ lda r17, 16(r17) C U
+
+ ldl r31, 256(r16) C L prefetch
+ ldl r31, 256(r17) C L prefetch
+ xor r1, r2, r5 C U
+ lda r18, -1(r18) C U
+
+ xor r3, r4, r6 C U
+ addq r0, r7, r0 C L
+ addq r0, r8, r0 C L
+ bne r18, L(top) C U
+
+
+ ctpop r6, r8 C U0
+ addq r0, r8, r0 C L
+L(one):
+ ctpop r5, r7 C U0
+ addq r0, r7, r0 C L
+
+ ret r31, (r26), 1 C L0
+
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/ev67/popcount.asm b/gmp/mpn/alpha/ev67/popcount.asm
new file mode 100644
index 0000000000..049c1cd239
--- /dev/null
+++ b/gmp/mpn/alpha/ev67/popcount.asm
@@ -0,0 +1,101 @@
+dnl Alpha ev67 mpn_popcount -- mpn bit population count.
+
+dnl Copyright 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C ev67: 1.5 cycles/limb
+
+
+C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
+C
+C This schedule seems necessary for the full 1.5 c/l, the IQ can't quite hide
+C all latencies, the addq's must be deferred to the next iteration.
+C
+C Since we need just 3 instructions per limb, further unrolling could approach
+C 1.0 c/l.
+C
+C The main loop processes two limbs at a time. An odd size is handled by
+C processing src[0] at the start. If the size is even that result is
+C discarded, and src[0] is repeated by the main loop.
+C
+
+ASM_START()
+PROLOGUE(mpn_popcount)
+
+ C r16 src
+ C r17 size
+
+ ldq r0, 0(r16) C L0 src[0]
+ and r17, 1, r8 C U1 1 if size odd
+ srl r17, 1, r17 C U0 size, limb pairs
+
+ s8addq r8, r16, r16 C L1 src++ if size odd
+ ctpop r0, r0 C U0
+ beq r17, L(one) C U1 if size==1
+
+ cmoveq r8, r31, r0 C L discard first limb if size even
+ clr r3 C L
+
+ clr r4 C L
+ unop C U
+ unop C L
+ unop C U
+
+
+ ALIGN(16)
+L(top):
+ C r0 total accumulating
+ C r3 pop 0
+ C r4 pop 1
+ C r16 src, incrementing
+ C r17 size, decrementing
+
+ ldq r1, 0(r16) C L
+ ldq r2, 8(r16) C L
+ lda r16, 16(r16) C U
+ lda r17, -1(r17) C U
+
+ addq r0, r3, r0 C L
+ addq r0, r4, r0 C L
+ ctpop r1, r3 C U0
+ ctpop r2, r4 C U0
+
+ ldl r31, 512(r16) C L prefetch
+ bne r17, L(top) C U
+
+
+ addq r0, r3, r0 C L
+ addq r0, r4, r0 C U
+L(one):
+ ret r31, (r26), 1 C L0
+
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/gmp-mparam.h b/gmp/mpn/alpha/gmp-mparam.h
new file mode 100644
index 0000000000..b850bd24b5
--- /dev/null
+++ b/gmp/mpn/alpha/gmp-mparam.h
@@ -0,0 +1,86 @@
+/* Alpha EV4 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004, 2005, 2009 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+
+/* 175MHz 21064 */
+
+/* Generated by tuneup.c, 2009-01-15, gcc 3.2 */
+
+#define MUL_TOOM22_THRESHOLD 12
+#define MUL_TOOM33_THRESHOLD 69
+#define MUL_TOOM44_THRESHOLD 88
+
+#define SQR_BASECASE_THRESHOLD 4
+#define SQR_TOOM2_THRESHOLD 20
+#define SQR_TOOM3_THRESHOLD 62
+#define SQR_TOOM4_THRESHOLD 155
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 40
+#define MULLO_MUL_N_THRESHOLD 202
+
+#define DIV_SB_PREINV_THRESHOLD 0 /* preinv always */
+#define DIV_DC_THRESHOLD 38
+#define POWM_THRESHOLD 60
+
+#define MATRIX22_STRASSEN_THRESHOLD 17
+#define HGCD_THRESHOLD 80
+#define GCD_DC_THRESHOLD 237
+#define GCDEXT_DC_THRESHOLD 198
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* preinv always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1_THRESHOLD 2
+#define MOD_1_2_THRESHOLD 9
+#define MOD_1_4_THRESHOLD 20
+#define USE_PREINV_DIVREM_1 1 /* preinv always */
+#define USE_PREINV_MOD_1 1 /* preinv always */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always */
+
+#define GET_STR_DC_THRESHOLD 20
+#define GET_STR_PRECOMPUTE_THRESHOLD 37
+#define SET_STR_DC_THRESHOLD 746
+#define SET_STR_PRECOMPUTE_THRESHOLD 1332
+
+#define MUL_FFT_TABLE { 240, 480, 1344, 2304, 5120, 20480, 49152, 0 }
+#define MUL_FFT_MODF_THRESHOLD 232
+#define MUL_FFT_THRESHOLD 1664
+
+#define SQR_FFT_TABLE { 240, 480, 1216, 2304, 5120, 12288, 49152, 0 }
+#define SQR_FFT_MODF_THRESHOLD 232
+#define SQR_FFT_THRESHOLD 1408
diff --git a/gmp/mpn/alpha/invert_limb.asm b/gmp/mpn/alpha/invert_limb.asm
new file mode 100644
index 0000000000..afc010f58c
--- /dev/null
+++ b/gmp/mpn/alpha/invert_limb.asm
@@ -0,0 +1,95 @@
+dnl Alpha mpn_invert_limb -- Invert a normalized limb.
+
+dnl Copyright 1996, 2000-2003, 2007, 2011, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 137/140 (with BWX/without BWX)
+C EV6: 71/72 (with BWX/without BWX)
+
+C This was compiler generated, with minimal manual edits. Surely several
+C cycles could be cut with some thought.
+
+ASM_START()
+PROLOGUE(mpn_invert_limb,gp)
+ LEA( r2, approx_tab)
+ srl r16, 54, r1
+ srl r16, 24, r4
+ and r16, 1, r5
+ bic r1, 1, r7
+ lda r4, 1(r4)
+ srl r16, 1, r3
+ addq r7, r2, r1
+ifelse(bwx_available_p,1,`
+ ldwu r0, -512(r1)
+',`
+ ldq_u r0, -512(r1)
+ extwl r0, r7, r0
+')
+ addq r3, r5, r3
+ mull r0, r0, r1
+ sll r0, 11, r0
+ mulq r1, r4, r1
+ srl r1, 40, r1
+ subq r0, r1, r0
+ lda r0, -1(r0)
+ mulq r0, r0, r2
+ sll r0, 60, r1
+ sll r0, 13, r0
+ mulq r2, r4, r2
+ subq r1, r2, r1
+ srl r1, 47, r1
+ addq r0, r1, r0
+ mulq r0, r3, r3
+ srl r0, 1, r1
+ cmoveq r5, 0, r1
+ subq r1, r3, r1
+ umulh r1, r0, r3
+ sll r0, 31, r0
+ srl r3, 1, r1
+ addq r0, r1, r0
+ mulq r0, r16, r2
+ umulh r0, r16, r3
+ addq r2, r16, r1
+ addq r3, r16, r16
+ cmpult r1, r2, r1
+ addq r16, r1, r3
+ subq r0, r3, r0
+ ret r31, (r26), 1
+EPILOGUE()
+DATASTART(approx_tab,8)
+forloop(i,256,512-1,dnl
+` .word eval(0x7fd00/i)
+')dnl
+ SIZE(approx_tab, 512)
+ TYPE(approx_tab, object)
+DATAEND()
+ASM_END()
diff --git a/gmp/mpn/alpha/lshift.asm b/gmp/mpn/alpha/lshift.asm
new file mode 100644
index 0000000000..c62a856aea
--- /dev/null
+++ b/gmp/mpn/alpha/lshift.asm
@@ -0,0 +1,182 @@
+dnl Alpha mpn_lshift -- Shift a number left.
+
+dnl Copyright 1994, 1995, 2000, 2003, 2009 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 3.25
+C EV6: 1.75
+
+C INPUT PARAMETERS
+C rp r16
+C up r17
+C n r18
+C cnt r19
+
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ s8addq r18,r17,r17 C make r17 point at end of s1
+ ldq r4,-8(r17) C load first limb
+ subq r31,r19,r20
+ s8addq r18,r16,r16 C make r16 point at end of RES
+ subq r18,1,r18
+ and r18,4-1,r28 C number of limbs in first loop
+ srl r4,r20,r0 C compute function result
+
+ beq r28,L(L0)
+ subq r18,r28,r18
+
+ ALIGN(8)
+L(top0):
+ ldq r3,-16(r17)
+ subq r16,8,r16
+ sll r4,r19,r5
+ subq r17,8,r17
+ subq r28,1,r28
+ srl r3,r20,r6
+ bis r3,r3,r4
+ bis r5,r6,r8
+ stq r8,0(r16)
+ bne r28,L(top0)
+
+L(L0): sll r4,r19,r24
+ beq r18,L(end)
+C warm up phase 1
+ ldq r1,-16(r17)
+ subq r18,4,r18
+ ldq r2,-24(r17)
+ ldq r3,-32(r17)
+ ldq r4,-40(r17)
+C warm up phase 2
+ srl r1,r20,r7
+ sll r1,r19,r21
+ srl r2,r20,r8
+ beq r18,L(end1)
+ ldq r1,-48(r17)
+ sll r2,r19,r22
+ ldq r2,-56(r17)
+ srl r3,r20,r5
+ bis r7,r24,r7
+ sll r3,r19,r23
+ bis r8,r21,r8
+ srl r4,r20,r6
+ ldq r3,-64(r17)
+ sll r4,r19,r24
+ ldq r4,-72(r17)
+ subq r18,4,r18
+ beq r18,L(end2)
+ ALIGN(16)
+C main loop
+L(top): stq r7,-8(r16)
+ bis r5,r22,r5
+ stq r8,-16(r16)
+ bis r6,r23,r6
+
+ srl r1,r20,r7
+ subq r18,4,r18
+ sll r1,r19,r21
+ unop C ldq r31,-96(r17)
+
+ srl r2,r20,r8
+ ldq r1,-80(r17)
+ sll r2,r19,r22
+ ldq r2,-88(r17)
+
+ stq r5,-24(r16)
+ bis r7,r24,r7
+ stq r6,-32(r16)
+ bis r8,r21,r8
+
+ srl r3,r20,r5
+ unop C ldq r31,-96(r17)
+ sll r3,r19,r23
+ subq r16,32,r16
+
+ srl r4,r20,r6
+ ldq r3,-96(r17)
+ sll r4,r19,r24
+ ldq r4,-104(r17)
+
+ subq r17,32,r17
+ bne r18,L(top)
+C cool down phase 2/1
+L(end2):
+ stq r7,-8(r16)
+ bis r5,r22,r5
+ stq r8,-16(r16)
+ bis r6,r23,r6
+ srl r1,r20,r7
+ sll r1,r19,r21
+ srl r2,r20,r8
+ sll r2,r19,r22
+ stq r5,-24(r16)
+ bis r7,r24,r7
+ stq r6,-32(r16)
+ bis r8,r21,r8
+ srl r3,r20,r5
+ sll r3,r19,r23
+ srl r4,r20,r6
+ sll r4,r19,r24
+C cool down phase 2/2
+ stq r7,-40(r16)
+ bis r5,r22,r5
+ stq r8,-48(r16)
+ bis r6,r23,r6
+ stq r5,-56(r16)
+ stq r6,-64(r16)
+C cool down phase 2/3
+ stq r24,-72(r16)
+ ret r31,(r26),1
+
+C cool down phase 1/1
+L(end1):
+ sll r2,r19,r22
+ srl r3,r20,r5
+ bis r7,r24,r7
+ sll r3,r19,r23
+ bis r8,r21,r8
+ srl r4,r20,r6
+ sll r4,r19,r24
+C cool down phase 1/2
+ stq r7,-8(r16)
+ bis r5,r22,r5
+ stq r8,-16(r16)
+ bis r6,r23,r6
+ stq r5,-24(r16)
+ stq r6,-32(r16)
+ stq r24,-40(r16)
+ ret r31,(r26),1
+
+L(end): stq r24,-8(r16)
+ ret r31,(r26),1
+EPILOGUE(mpn_lshift)
+ASM_END()
diff --git a/gmp/mpn/alpha/mod_34lsub1.asm b/gmp/mpn/alpha/mod_34lsub1.asm
new file mode 100644
index 0000000000..1b03b637d8
--- /dev/null
+++ b/gmp/mpn/alpha/mod_34lsub1.asm
@@ -0,0 +1,164 @@
+dnl Alpha mpn_mod_34lsub1.
+
+dnl Copyright 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 4 (?)
+C EV5: 2.67
+C EV6: 1.67
+
+
+dnl INPUT PARAMETERS
+dnl up r16
+dnl n r17
+
+define(`l0',`r18')
+define(`l1',`r19')
+define(`l2',`r20')
+define(`a0',`r21')
+define(`a1',`r22')
+define(`a2',`r23')
+define(`c0',`r24')
+define(`c1',`r5')
+define(`c2',`r6')
+
+ASM_START()
+PROLOGUE(mpn_mod_34lsub1)
+ bis r31, r31, c0
+ bis r31, r31, c1
+ bis r31, r31, c2
+
+ lda r17, -3(r17)
+ bge r17, $L_3_or_more
+ bis r31, r31, a0
+ bis r31, r31, a1
+ bis r31, r31, a2
+ br r31, $L_012
+
+$L_3_or_more:
+ ldq a0, 0(r16)
+ ldq a1, 8(r16)
+ ldq a2, 16(r16)
+ lda r16, 24(r16)
+ lda r17, -3(r17)
+ blt r17, $L_012
+
+$L_6_or_more:
+ ldq l0, 0(r16)
+ ldq l1, 8(r16)
+ ldq l2, 16(r16)
+ addq l0, a0, a0
+
+ lda r16, 24(r16)
+ lda r17, -3(r17)
+ blt r17, $L_end
+
+ ALIGN(16)
+C Main loop
+$L_9_or_more:
+$Loop: cmpult a0, l0, r0
+ ldq l0, 0(r16)
+ addq r0, c0, c0
+ addq l1, a1, a1
+ cmpult a1, l1, r0
+ ldq l1, 8(r16)
+ addq r0, c1, c1
+ addq l2, a2, a2
+ cmpult a2, l2, r0
+ ldq l2, 16(r16)
+ addq r0, c2, c2
+ addq l0, a0, a0
+ lda r16, 24(r16)
+ lda r17, -3(r17)
+ bge r17, $Loop
+
+$L_end: cmpult a0, l0, r0
+ addq r0, c0, c0
+ addq l1, a1, a1
+ cmpult a1, l1, r0
+ addq r0, c1, c1
+ addq l2, a2, a2
+ cmpult a2, l2, r0
+ addq r0, c2, c2
+
+C Handle the last (n mod 3) limbs
+$L_012: lda r17, 2(r17)
+ blt r17, $L_0
+ ldq l0, 0(r16)
+ addq l0, a0, a0
+ cmpult a0, l0, r0
+ addq r0, c0, c0
+ beq r17, $L_0
+ ldq l1, 8(r16)
+ addq l1, a1, a1
+ cmpult a1, l1, r0
+ addq r0, c1, c1
+
+C Align and sum our 3 main accumulators and 3 carry accumulators
+$L_0: srl a0, 48, r2
+ srl a1, 32, r4
+ifdef(`HAVE_LIMB_LITTLE_ENDIAN',
+` insll a1, 2, r1', C (a1 & 0xffffffff) << 16
+` zapnot a1, 15, r25
+ sll r25, 16, r1')
+ zapnot a0, 63, r0 C a0 & 0xffffffffffff
+ srl a2, 16, a1
+ifdef(`HAVE_LIMB_LITTLE_ENDIAN',
+` inswl a2, 4, r3', C (a2 & 0xffff) << 32
+` zapnot a2, 3, r25
+ sll r25, 32, r3')
+ addq r1, r4, r1
+ addq r0, r2, r0
+ srl c0, 32, a2
+ifdef(`HAVE_LIMB_LITTLE_ENDIAN',
+` insll c0, 2, r4', C (c0 & 0xffffffff) << 16
+` zapnot c0, 15, r25
+ sll r25, 16, r4')
+ addq r0, r1, r0
+ addq r3, a1, r3
+ addq r0, r3, r0
+ srl c1, 16, c0
+ifdef(`HAVE_LIMB_LITTLE_ENDIAN',
+` inswl c1, 4, r2', C (c1 & 0xffff) << 32
+` zapnot c1, 3, r25
+ sll r25, 32, r2')
+ addq r4, a2, r4
+C srl c2, 48, r3 C This will be 0 in practise
+ zapnot c2, 63, r1 C r1 = c2 & 0xffffffffffff
+ addq r0, r4, r0
+ addq r2, c0, r2
+ addq r0, r2, r0
+C addq r1, r3, r1
+ addq r0, r1, r0
+
+ ret r31, (r26), 1
+EPILOGUE(mpn_mod_34lsub1)
+ASM_END()
diff --git a/gmp/mpn/alpha/mode1o.asm b/gmp/mpn/alpha/mode1o.asm
new file mode 100644
index 0000000000..96dccc73ee
--- /dev/null
+++ b/gmp/mpn/alpha/mode1o.asm
@@ -0,0 +1,209 @@
+dnl Alpha mpn_modexact_1c_odd -- mpn exact remainder
+
+dnl Copyright 2003, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C EV4: 47
+C EV5: 30
+C EV6: 15
+
+
+C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size, mp_limb_t d,
+C mp_limb_t c)
+C
+C This code follows the "alternate" code in mpn/generic/mode1o.c,
+C eliminating cbit+climb from the dependent chain. This leaves,
+C
+C ev4 ev5 ev6
+C 1 3 1 subq y = x - h
+C 23 13 7 mulq q = y * inverse
+C 23 14 7 umulh h = high (q * d)
+C -- -- --
+C 47 30 15
+C
+C In each case, the load latency, loop control, and extra carry bit handling
+C hide under the multiply latencies. Those latencies are long enough that
+C we don't need to worry about alignment or pairing to squeeze out
+C performance.
+C
+C For the first limb, some of the loop code is broken out and scheduled back
+C since it can be done earlier.
+C
+C - The first ldq src[0] is near the start of the routine, for maximum
+C time from memory.
+C
+C - The subq y=x-climb can be done without waiting for the inverse.
+C
+C - The mulq y*inverse is replicated after the final subq for the inverse,
+C instead of branching to the mulq in the main loop. On ev4 a branch
+C there would cost cycles, but we can hide them under the mulq latency.
+C
+C For the last limb, high<divisor is tested and if that's true a subtract
+C and addback is done, as per the main mpn/generic/mode1o.c code. This is a
+C data-dependent branch, but we're waiting for umulh so any penalty should
+C hide there. The multiplies saved would be worth the cost anyway.
+C
+C Enhancements:
+C
+C For size==1, a plain division (done bitwise say) might be faster than
+C calculating an inverse, the latter taking about 130 cycles on ev4 or 70 on
+C ev5. A call to gcc __remqu might be a possibility.
+
+ASM_START()
+PROLOGUE(mpn_modexact_1c_odd,gp)
+
+ C r16 src
+ C r17 size
+ C r18 d
+ C r19 c
+
+ LEA(r0, binvert_limb_table)
+ srl r18, 1, r20 C d >> 1
+
+ and r20, 127, r20 C idx = d>>1 & 0x7F
+
+ addq r0, r20, r21 C table + idx
+
+ifelse(bwx_available_p,1,
+` ldbu r20, 0(r21) C table[idx], inverse 8 bits
+',`
+ ldq_u r20, 0(r21) C table[idx] qword
+ extbl r20, r21, r20 C table[idx], inverse 8 bits
+')
+
+ mull r20, r20, r7 C i*i
+ addq r20, r20, r20 C 2*i
+
+ ldq r2, 0(r16) C x = s = src[0]
+ lda r17, -1(r17) C size--
+ clr r0 C initial cbit=0
+
+ mull r7, r18, r7 C i*i*d
+
+ subq r20, r7, r20 C 2*i-i*i*d, inverse 16 bits
+
+ mull r20, r20, r7 C i*i
+ addq r20, r20, r20 C 2*i
+
+ mull r7, r18, r7 C i*i*d
+
+ subq r20, r7, r20 C 2*i-i*i*d, inverse 32 bits
+
+ mulq r20, r20, r7 C i*i
+ addq r20, r20, r20 C 2*i
+
+ mulq r7, r18, r7 C i*i*d
+ subq r2, r19, r3 C y = x - climb
+
+ subq r20, r7, r20 C inv = 2*i-i*i*d, inverse 64 bits
+
+ASSERT(r7, C should have d*inv==1 mod 2^64
+` mulq r18, r20, r7
+ cmpeq r7, 1, r7')
+
+ mulq r3, r20, r4 C first q = y * inv
+
+ beq r17, L(one) C if size==1
+ br L(entry)
+
+
+L(top):
+ C r0 cbit
+ C r16 src, incrementing
+ C r17 size, decrementing
+ C r18 d
+ C r19 climb
+ C r20 inv
+
+ ldq r1, 0(r16) C s = src[i]
+ subq r1, r0, r2 C x = s - cbit
+ cmpult r1, r0, r0 C new cbit = s < cbit
+
+ subq r2, r19, r3 C y = x - climb
+
+ mulq r3, r20, r4 C q = y * inv
+L(entry):
+ cmpult r2, r19, r5 C cbit2 = x < climb
+ addq r5, r0, r0 C cbit += cbit2
+ lda r16, 8(r16) C src++
+ lda r17, -1(r17) C size--
+
+ umulh r4, r18, r19 C climb = q * d
+ bne r17, L(top) C while 2 or more limbs left
+
+
+
+ C r0 cbit
+ C r18 d
+ C r19 climb
+ C r20 inv
+
+ ldq r1, 0(r16) C s = src[size-1] high limb
+
+ cmpult r1, r18, r2 C test high<divisor
+ bne r2, L(skip) C skip if so
+
+ C can't skip a division, repeat loop code
+
+ subq r1, r0, r2 C x = s - cbit
+ cmpult r1, r0, r0 C new cbit = s < cbit
+
+ subq r2, r19, r3 C y = x - climb
+
+ mulq r3, r20, r4 C q = y * inv
+L(one):
+ cmpult r2, r19, r5 C cbit2 = x < climb
+ addq r5, r0, r0 C cbit += cbit2
+
+ umulh r4, r18, r19 C climb = q * d
+
+ addq r19, r0, r0 C return climb + cbit
+ ret r31, (r26), 1
+
+
+ ALIGN(8)
+L(skip):
+ C with high<divisor, the final step can be just (cbit+climb)-s and
+ C an addback of d if that underflows
+
+ addq r19, r0, r19 C c = climb + cbit
+
+ subq r19, r1, r2 C c - s
+ cmpult r19, r1, r3 C c < s
+
+ addq r2, r18, r0 C return c-s + divisor
+
+ cmoveq r3, r2, r0 C return c-s if no underflow
+ ret r31, (r26), 1
+
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/mul_1.asm b/gmp/mpn/alpha/mul_1.asm
new file mode 100644
index 0000000000..a7cdbcf8eb
--- /dev/null
+++ b/gmp/mpn/alpha/mul_1.asm
@@ -0,0 +1,102 @@
+dnl Alpha mpn_mul_1 -- Multiply a limb vector with a limb and store
+dnl the result in a second limb vector.
+
+dnl Copyright 1992, 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 42
+C EV5: 18
+C EV6: 7
+
+C INPUT PARAMETERS
+C rp r16
+C up r17
+C n r18
+C vl r19
+C cl r20
+
+
+ASM_START()
+PROLOGUE(mpn_mul_1c)
+ ldq r2,0(r17) C r2 = s1_limb
+ lda r18,-1(r18) C size--
+ mulq r2,r19,r3 C r3 = prod_low
+ umulh r2,r19,r4 C r4 = prod_high
+ beq r18,$Le1c C jump if size was == 1
+ ldq r2,8(r17) C r2 = s1_limb
+ lda r18,-1(r18) C size--
+ addq r3,r20,r3 C r3 = cy_limb + cl
+ stq r3,0(r16)
+ cmpult r3,r20,r0 C r0 = carry from (cy_limb + cl)
+ bne r18,$Loop C jump if size was == 2
+ br r31,$Le2
+$Le1c: addq r3,r20,r3 C r3 = cy_limb + cl
+ cmpult r3,r20,r0 C r0 = carry from (cy_limb + cl)
+$Le1: stq r3,0(r16)
+ addq r4,r0,r0
+ ret r31,(r26),1
+EPILOGUE(mpn_mul_1c)
+
+PROLOGUE(mpn_mul_1)
+ ldq r2,0(r17) C r2 = s1_limb
+ lda r18,-1(r18) C size--
+ mulq r2,r19,r3 C r3 = prod_low
+ bic r31,r31,r0 C clear cy_limb
+ umulh r2,r19,r4 C r4 = prod_high
+ beq r18,$Le1 C jump if size was == 1
+ ldq r2,8(r17) C r2 = s1_limb
+ lda r18,-1(r18) C size--
+ stq r3,0(r16)
+ beq r18,$Le2 C jump if size was == 2
+
+ ALIGN(8)
+$Loop: mulq r2,r19,r3 C r3 = prod_low
+ addq r4,r0,r0 C cy_limb = cy_limb + 'cy'
+ lda r18,-1(r18) C size--
+ umulh r2,r19,r4 C r4 = prod_high
+ ldq r2,16(r17) C r2 = s1_limb
+ lda r17,8(r17) C s1_ptr++
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ stq r3,8(r16)
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ lda r16,8(r16) C res_ptr++
+ bne r18,$Loop
+
+$Le2: mulq r2,r19,r3 C r3 = prod_low
+ addq r4,r0,r0 C cy_limb = cy_limb + 'cy'
+ umulh r2,r19,r4 C r4 = prod_high
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ stq r3,8(r16)
+ addq r4,r0,r0 C cy_limb = prod_high + cy
+ ret r31,(r26),1
+EPILOGUE(mpn_mul_1)
+ASM_END()
diff --git a/gmp/mpn/alpha/rshift.asm b/gmp/mpn/alpha/rshift.asm
new file mode 100644
index 0000000000..6e1e214558
--- /dev/null
+++ b/gmp/mpn/alpha/rshift.asm
@@ -0,0 +1,180 @@
+dnl Alpha mpn_rshift -- Shift a number right.
+
+dnl Copyright 1994, 1995, 2000, 2009 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 3.25
+C EV6: 1.75
+
+C INPUT PARAMETERS
+C rp r16
+C up r17
+C n r18
+C cnt r19
+
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ ldq r4,0(r17) C load first limb
+ subq r31,r19,r20
+ subq r18,1,r18
+ and r18,4-1,r28 C number of limbs in first loop
+ sll r4,r20,r0 C compute function result
+
+ beq r28,L(L0)
+ subq r18,r28,r18
+
+ ALIGN(8)
+L(top0):
+ ldq r3,8(r17)
+ addq r16,8,r16
+ srl r4,r19,r5
+ addq r17,8,r17
+ subq r28,1,r28
+ sll r3,r20,r6
+ bis r3,r3,r4
+ bis r5,r6,r8
+ stq r8,-8(r16)
+ bne r28,L(top0)
+
+L(L0): srl r4,r19,r24
+ beq r18,L(end)
+C warm up phase 1
+ ldq r1,8(r17)
+ subq r18,4,r18
+ ldq r2,16(r17)
+ ldq r3,24(r17)
+ ldq r4,32(r17)
+C warm up phase 2
+ sll r1,r20,r7
+ srl r1,r19,r21
+ sll r2,r20,r8
+ beq r18,L(end1)
+ ldq r1,40(r17)
+ srl r2,r19,r22
+ ldq r2,48(r17)
+ sll r3,r20,r5
+ bis r7,r24,r7
+ srl r3,r19,r23
+ bis r8,r21,r8
+ sll r4,r20,r6
+ ldq r3,56(r17)
+ srl r4,r19,r24
+ ldq r4,64(r17)
+ subq r18,4,r18
+ beq r18,L(end2)
+ ALIGN(16)
+C main loop
+L(top): stq r7,0(r16)
+ bis r5,r22,r5
+ stq r8,8(r16)
+ bis r6,r23,r6
+
+ sll r1,r20,r7
+ subq r18,4,r18
+ srl r1,r19,r21
+ unop C ldq r31,-96(r17)
+
+ sll r2,r20,r8
+ ldq r1,72(r17)
+ srl r2,r19,r22
+ ldq r2,80(r17)
+
+ stq r5,16(r16)
+ bis r7,r24,r7
+ stq r6,24(r16)
+ bis r8,r21,r8
+
+ sll r3,r20,r5
+ unop C ldq r31,-96(r17)
+ srl r3,r19,r23
+ addq r16,32,r16
+
+ sll r4,r20,r6
+ ldq r3,88(r17)
+ srl r4,r19,r24
+ ldq r4,96(r17)
+
+ addq r17,32,r17
+ bne r18,L(top)
+C cool down phase 2/1
+L(end2):
+ stq r7,0(r16)
+ bis r5,r22,r5
+ stq r8,8(r16)
+ bis r6,r23,r6
+ sll r1,r20,r7
+ srl r1,r19,r21
+ sll r2,r20,r8
+ srl r2,r19,r22
+ stq r5,16(r16)
+ bis r7,r24,r7
+ stq r6,24(r16)
+ bis r8,r21,r8
+ sll r3,r20,r5
+ srl r3,r19,r23
+ sll r4,r20,r6
+ srl r4,r19,r24
+C cool down phase 2/2
+ stq r7,32(r16)
+ bis r5,r22,r5
+ stq r8,40(r16)
+ bis r6,r23,r6
+ stq r5,48(r16)
+ stq r6,56(r16)
+C cool down phase 2/3
+ stq r24,64(r16)
+ ret r31,(r26),1
+
+C cool down phase 1/1
+L(end1):
+ srl r2,r19,r22
+ sll r3,r20,r5
+ bis r7,r24,r7
+ srl r3,r19,r23
+ bis r8,r21,r8
+ sll r4,r20,r6
+ srl r4,r19,r24
+C cool down phase 1/2
+ stq r7,0(r16)
+ bis r5,r22,r5
+ stq r8,8(r16)
+ bis r6,r23,r6
+ stq r5,16(r16)
+ stq r6,24(r16)
+ stq r24,32(r16)
+ ret r31,(r26),1
+
+L(end): stq r24,0(r16)
+ ret r31,(r26),1
+EPILOGUE(mpn_rshift)
+ASM_END()
diff --git a/gmp/mpn/alpha/sec_tabselect.asm b/gmp/mpn/alpha/sec_tabselect.asm
new file mode 100644
index 0000000000..679b16926e
--- /dev/null
+++ b/gmp/mpn/alpha/sec_tabselect.asm
@@ -0,0 +1,137 @@
+dnl Alpha mpn_sec_tabselect.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 2.25
+C EV6: 1.64
+
+define(`rp', `r16')
+define(`tp', `r17')
+define(`n', `r18')
+define(`nents', `r19')
+define(`which', `r20')
+
+define(`i', `r21')
+define(`j', `r22')
+define(`stride', `r23')
+define(`mask', `r24')
+define(`k', `r25')
+
+
+ASM_START()
+PROLOGUE(mpn_sec_tabselect)
+ subq n, 4, j C outer loop induction variable
+
+ blt j, L(outer_end)
+L(outer_top):
+ mov tp, r8
+ lda r0, 0(r31)
+ lda r1, 0(r31)
+ lda r2, 0(r31)
+ lda r3, 0(r31)
+ subq j, 4, j C outer loop induction variable
+ subq nents, which, k
+ mov nents, i
+
+ ALIGN(16)
+L(top): ldq r4, 0(tp)
+ ldq r5, 8(tp)
+ cmpeq k, i, mask
+ subq i, 1, i
+ subq r31, mask, mask
+ ldq r6, 16(tp)
+ ldq r7, 24(tp)
+ and r4, mask, r4
+ and r5, mask, r5
+ or r0, r4, r0
+ or r1, r5, r1
+ and r6, mask, r6
+ and r7, mask, r7
+ or r2, r6, r2
+ or r3, r7, r3
+ s8addq n, tp, tp
+ bne i, L(top)
+
+ stq r0, 0(rp)
+ stq r1, 8(rp)
+ stq r2, 16(rp)
+ stq r3, 24(rp)
+ addq r8, 32, tp
+ addq rp, 32, rp
+ bge j, L(outer_top)
+L(outer_end):
+
+ and n, 2, r0
+ beq r0, L(b0x)
+L(b1x): mov tp, r8
+ lda r0, 0(r31)
+ lda r1, 0(r31)
+ subq nents, which, k
+ mov nents, i
+ ALIGN(16)
+L(tp2): ldq r4, 0(tp)
+ ldq r5, 8(tp)
+ cmpeq k, i, mask
+ subq i, 1, i
+ subq r31, mask, mask
+ and r4, mask, r4
+ and r5, mask, r5
+ or r0, r4, r0
+ or r1, r5, r1
+ s8addq n, tp, tp
+ bne i, L(tp2)
+ stq r0, 0(rp)
+ stq r1, 8(rp)
+ addq r8, 16, tp
+ addq rp, 16, rp
+
+L(b0x): and n, 1, r0
+ beq r0, L(b00)
+L(b01): lda r0, 0(r31)
+ subq nents, which, k
+ mov nents, i
+ ALIGN(16)
+L(tp1): ldq r4, 0(tp)
+ cmpeq k, i, mask
+ subq i, 1, i
+ subq r31, mask, mask
+ and r4, mask, r4
+ or r0, r4, r0
+ s8addq n, tp, tp
+ bne i, L(tp1)
+ stq r0, 0(rp)
+
+L(b00): ret r31, (r26), 1
+EPILOGUE()
diff --git a/gmp/mpn/alpha/sqr_diag_addlsh1.asm b/gmp/mpn/alpha/sqr_diag_addlsh1.asm
new file mode 100644
index 0000000000..ee219ef7e8
--- /dev/null
+++ b/gmp/mpn/alpha/sqr_diag_addlsh1.asm
@@ -0,0 +1,93 @@
+dnl Alpha mpn_sqr_diag_addlsh1.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 10.2
+C EV6: 4.5
+
+C Ideally, one-way code could run at 9 c/l (limited by mulq+umulh) on ev5 and
+C about 3.75 c/l on ev6. Two-way code could run at about 3.25 c/l on ev6.
+
+C Algorithm: We allow ourselves to propagate carry to a product high word
+C without worrying for carry out, since (B-1)^2 = B^2-2B+1 has a high word of
+C B-2, i.e, will not spill. We propagate carry similarly to a product low word
+C since the problem value B-1 is a quadratic non-residue mod B, but our
+C products are squares.
+
+define(`rp', `r16')
+define(`tp', `r17')
+define(`up', `r18')
+define(`n', `r19')
+
+ASM_START()
+PROLOGUE(mpn_sqr_diag_addlsh1)
+ ldq r0, 0(up)
+ bis r31, r31, r21
+ bis r31, r31, r3
+ mulq r0, r0, r7
+ stq r7, 0(rp)
+ umulh r0, r0, r6
+ lda n, -1(n)
+
+ ALIGN(16)
+L(top): ldq r0, 8(up)
+ lda up, 8(up)
+ ldq r8, 0(tp)
+ ldq r20, 8(tp)
+ mulq r0, r0, r7
+ lda tp, 16(tp)
+ sll r8, 1, r23
+ srl r8, 63, r22
+ or r21, r23, r23
+ sll r20, 1, r24
+ addq r3, r6, r6 C cannot carry per comment above
+ or r22, r24, r24
+ addq r23, r6, r21
+ umulh r0, r0, r6
+ cmpult r21, r23, r1
+ addq r1, r7, r7 C cannot carry per comment above
+ stq r21, 8(rp)
+ addq r24, r7, r22
+ stq r22, 16(rp)
+ lda n, -1(n)
+ cmpult r22, r7, r3
+ srl r20, 63, r21
+ lda rp, 16(rp)
+ bne n, L(top)
+
+ addq r3, r6, r6 C cannot carry per comment above
+ addq r21, r6, r21
+ stq r21, 8(rp)
+ ret r31, (r26), 1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/sub_n.asm b/gmp/mpn/alpha/sub_n.asm
new file mode 100644
index 0000000000..1bb72263f8
--- /dev/null
+++ b/gmp/mpn/alpha/sub_n.asm
@@ -0,0 +1,164 @@
+dnl Alpha mpn_sub_n -- Subtract two limb vectors of the same length > 0
+dnl and store difference in a third limb vector.
+
+dnl Copyright 1995, 1999, 2000, 2005, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: ?
+C EV5: 4.75
+C EV6: 3
+
+dnl INPUT PARAMETERS
+dnl res_ptr r16
+dnl s1_ptr r17
+dnl s2_ptr r18
+dnl size r19
+
+ASM_START()
+PROLOGUE(mpn_sub_nc)
+ bis r31,r20,r25
+ br L(com)
+EPILOGUE()
+PROLOGUE(mpn_sub_n)
+ bis r31,r31,r25 C clear cy
+L(com): subq r19,4,r19 C decr loop cnt
+ blt r19,$Lend2 C if less than 4 limbs, goto 2nd loop
+C Start software pipeline for 1st loop
+ ldq r0,0(r18)
+ ldq r4,0(r17)
+ ldq r1,8(r18)
+ ldq r5,8(r17)
+ addq r17,32,r17 C update s1_ptr
+ subq r4,r0,r28 C 1st main subtract
+ ldq r2,16(r18)
+ subq r28,r25,r20 C 1st carry subtract
+ ldq r3,24(r18)
+ cmpult r4,r0,r8 C compute cy from last subtract
+ ldq r6,-16(r17)
+ cmpult r28,r25,r25 C compute cy from last subtract
+ ldq r7,-8(r17)
+ bis r8,r25,r25 C combine cy from the two subtracts
+ subq r19,4,r19 C decr loop cnt
+ subq r5,r1,r28 C 2nd main subtract
+ addq r18,32,r18 C update s2_ptr
+ subq r28,r25,r21 C 2nd carry subtract
+ cmpult r5,r1,r8 C compute cy from last subtract
+ blt r19,$Lend1 C if less than 4 limbs remain, jump
+C 1st loop handles groups of 4 limbs in a software pipeline
+ ALIGN(16)
+$Loop: cmpult r28,r25,r25 C compute cy from last subtract
+ ldq r0,0(r18)
+ bis r8,r25,r25 C combine cy from the two subtracts
+ ldq r1,8(r18)
+ subq r6,r2,r28 C 3rd main subtract
+ ldq r4,0(r17)
+ subq r28,r25,r22 C 3rd carry subtract
+ ldq r5,8(r17)
+ cmpult r6,r2,r8 C compute cy from last subtract
+ cmpult r28,r25,r25 C compute cy from last subtract
+ stq r20,0(r16)
+ bis r8,r25,r25 C combine cy from the two subtracts
+ stq r21,8(r16)
+ subq r7,r3,r28 C 4th main subtract
+ subq r28,r25,r23 C 4th carry subtract
+ cmpult r7,r3,r8 C compute cy from last subtract
+ cmpult r28,r25,r25 C compute cy from last subtract
+ addq r17,32,r17 C update s1_ptr
+ bis r8,r25,r25 C combine cy from the two subtracts
+ addq r16,32,r16 C update res_ptr
+ subq r4,r0,r28 C 1st main subtract
+ ldq r2,16(r18)
+ subq r28,r25,r20 C 1st carry subtract
+ ldq r3,24(r18)
+ cmpult r4,r0,r8 C compute cy from last subtract
+ ldq r6,-16(r17)
+ cmpult r28,r25,r25 C compute cy from last subtract
+ ldq r7,-8(r17)
+ bis r8,r25,r25 C combine cy from the two subtracts
+ subq r19,4,r19 C decr loop cnt
+ stq r22,-16(r16)
+ subq r5,r1,r28 C 2nd main subtract
+ stq r23,-8(r16)
+ subq r28,r25,r21 C 2nd carry subtract
+ addq r18,32,r18 C update s2_ptr
+ cmpult r5,r1,r8 C compute cy from last subtract
+ bge r19,$Loop
+C Finish software pipeline for 1st loop
+$Lend1: cmpult r28,r25,r25 C compute cy from last subtract
+ bis r8,r25,r25 C combine cy from the two subtracts
+ subq r6,r2,r28 C cy add
+ subq r28,r25,r22 C 3rd main subtract
+ cmpult r6,r2,r8 C compute cy from last subtract
+ cmpult r28,r25,r25 C compute cy from last subtract
+ stq r20,0(r16)
+ bis r8,r25,r25 C combine cy from the two subtracts
+ stq r21,8(r16)
+ subq r7,r3,r28 C cy add
+ subq r28,r25,r23 C 4th main subtract
+ cmpult r7,r3,r8 C compute cy from last subtract
+ cmpult r28,r25,r25 C compute cy from last subtract
+ bis r8,r25,r25 C combine cy from the two subtracts
+ addq r16,32,r16 C update res_ptr
+ stq r22,-16(r16)
+ stq r23,-8(r16)
+$Lend2: addq r19,4,r19 C restore loop cnt
+ beq r19,$Lret
+C Start software pipeline for 2nd loop
+ ldq r0,0(r18)
+ ldq r4,0(r17)
+ subq r19,1,r19
+ beq r19,$Lend0
+C 2nd loop handles remaining 1-3 limbs
+ ALIGN(16)
+$Loop0: subq r4,r0,r28 C main subtract
+ cmpult r4,r0,r8 C compute cy from last subtract
+ ldq r0,8(r18)
+ ldq r4,8(r17)
+ subq r28,r25,r20 C carry subtract
+ addq r18,8,r18
+ addq r17,8,r17
+ stq r20,0(r16)
+ cmpult r28,r25,r25 C compute cy from last subtract
+ subq r19,1,r19 C decr loop cnt
+ bis r8,r25,r25 C combine cy from the two subtracts
+ addq r16,8,r16
+ bne r19,$Loop0
+$Lend0: subq r4,r0,r28 C main subtract
+ subq r28,r25,r20 C carry subtract
+ cmpult r4,r0,r8 C compute cy from last subtract
+ cmpult r28,r25,r25 C compute cy from last subtract
+ stq r20,0(r16)
+ bis r8,r25,r25 C combine cy from the two subtracts
+
+$Lret: bis r25,r31,r0 C return cy
+ ret r31,(r26),1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/submul_1.asm b/gmp/mpn/alpha/submul_1.asm
new file mode 100644
index 0000000000..2b63b52fa4
--- /dev/null
+++ b/gmp/mpn/alpha/submul_1.asm
@@ -0,0 +1,99 @@
+dnl Alpha mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+dnl the result from a second limb vector.
+
+dnl Copyright 1992, 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C EV4: 42
+C EV5: 18
+C EV6: 7
+
+C INPUT PARAMETERS
+C rp r16
+C up r17
+C n r18
+C limb r19
+
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ ldq r2,0(r17) C r2 = s1_limb
+ addq r17,8,r17 C s1_ptr++
+ subq r18,1,r18 C size--
+ mulq r2,r19,r3 C r3 = prod_low
+ ldq r5,0(r16) C r5 = *res_ptr
+ umulh r2,r19,r0 C r0 = prod_high
+ beq r18,$Lend1 C jump if size was == 1
+ ldq r2,0(r17) C r2 = s1_limb
+ addq r17,8,r17 C s1_ptr++
+ subq r18,1,r18 C size--
+ subq r5,r3,r3
+ cmpult r5,r3,r4
+ stq r3,0(r16)
+ addq r16,8,r16 C res_ptr++
+ beq r18,$Lend2 C jump if size was == 2
+
+ ALIGN(8)
+$Loop: mulq r2,r19,r3 C r3 = prod_low
+ ldq r5,0(r16) C r5 = *res_ptr
+ addq r4,r0,r0 C cy_limb = cy_limb + 'cy'
+ subq r18,1,r18 C size--
+ umulh r2,r19,r4 C r4 = cy_limb
+ ldq r2,0(r17) C r2 = s1_limb
+ addq r17,8,r17 C s1_ptr++
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ subq r5,r3,r3
+ cmpult r5,r3,r5
+ stq r3,0(r16)
+ addq r16,8,r16 C res_ptr++
+ addq r5,r0,r0 C combine carries
+ bne r18,$Loop
+
+$Lend2: mulq r2,r19,r3 C r3 = prod_low
+ ldq r5,0(r16) C r5 = *res_ptr
+ addq r4,r0,r0 C cy_limb = cy_limb + 'cy'
+ umulh r2,r19,r4 C r4 = cy_limb
+ addq r3,r0,r3 C r3 = cy_limb + prod_low
+ cmpult r3,r0,r0 C r0 = carry from (cy_limb + prod_low)
+ subq r5,r3,r3
+ cmpult r5,r3,r5
+ stq r3,0(r16)
+ addq r5,r0,r0 C combine carries
+ addq r4,r0,r0 C cy_limb = prod_high + cy
+ ret r31,(r26),1
+$Lend1: subq r5,r3,r3
+ cmpult r5,r3,r5
+ stq r3,0(r16)
+ addq r0,r5,r0
+ ret r31,(r26),1
+EPILOGUE(mpn_submul_1)
+ASM_END()
diff --git a/gmp/mpn/alpha/umul.asm b/gmp/mpn/alpha/umul.asm
new file mode 100644
index 0000000000..039081ed48
--- /dev/null
+++ b/gmp/mpn/alpha/umul.asm
@@ -0,0 +1,44 @@
+dnl mpn_umul_ppmm -- 1x1->2 limb multiplication
+
+dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C mp_limb_t mpn_umul_ppmm (mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2);
+C
+
+ASM_START()
+PROLOGUE(mpn_umul_ppmm)
+ mulq r17, r18, r1
+ umulh r17, r18, r0
+ stq r1, 0(r16)
+ ret r31, (r26), 1
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/alpha/unicos.m4 b/gmp/mpn/alpha/unicos.m4
new file mode 100644
index 0000000000..e05cf5cca6
--- /dev/null
+++ b/gmp/mpn/alpha/unicos.m4
@@ -0,0 +1,131 @@
+divert(-1)
+
+dnl m4 macros for alpha assembler on unicos.
+
+
+dnl Copyright 2000, 2002-2004, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Note that none of the standard GMP_ASM_ autoconf tests are done for
+dnl unicos, so none of the config.m4 results can be used here.
+
+dnl No underscores on unicos
+define(`GSYM_PREFIX')
+
+define(`ASM_START',
+m4_assert_numargs(0)
+` .ident dummy')
+
+define(`X',
+m4_assert_numargs(1)
+`^X$1')
+
+define(`FLOAT64',
+m4_assert_numargs(2)
+` .psect $1@crud,data
+$1: .t_floating $2
+ .endp')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo[,gp|noalign])
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs_range(1,2)
+`ifelse(`$2',gp,,
+`ifelse(`$2',noalign,,
+`ifelse(`$2',,,`m4_error(`Unrecognised PROLOGUE parameter
+')')')')dnl
+ .stack 192 ; What does this mean? Only Cray knows.
+ .psect $1@code,code,cache
+$1::')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+` .endp')
+
+
+dnl Usage: LDGP(dst,src)
+dnl
+dnl Emit an "ldgp dst,src", but only on systems using a GOT (which unicos
+dnl doesn't).
+
+define(LDGP,
+m4_assert_numargs(2)
+)
+
+
+dnl Usage: EXTERN(variable_name)
+define(`EXTERN',
+m4_assert_numargs(1)
+` .extern $1')
+
+define(`DATASTART',
+m4_assert_numargs_range(1,2)
+` .psect $1@crud,data
+ ALIGN(ifelse($#,1,2,$2))
+$1:')
+
+define(`DATAEND',
+m4_assert_numargs(0)
+` .endp')
+
+define(`ASM_END',
+m4_assert_numargs(0)
+` .end')
+
+define(`cvttqc',
+m4_assert_numargs(-1)
+`cvttq/c')
+
+dnl Load a symbolic address into a register
+define(`LEA',
+m4_assert_numargs(2)
+ `laum $1, $2(r31)
+ sll $1, 32, $1
+ lalm $1, $2($1)
+ lal $1, $2($1)')
+
+
+dnl Usage: ALIGN(bytes)
+dnl
+dnl Unicos assembler .align emits zeros, even in code segments, so disable
+dnl aligning.
+dnl
+dnl GCC uses a macro emiting nops until the desired alignment is reached
+dnl (see unicosmk_file_start in alpha.c). Could do something like that if
+dnl we cared. The maximum desired alignment must be established at the
+dnl start of the section though, since of course emitting nops only
+dnl advances relative to the section beginning.
+
+define(`ALIGN',
+m4_assert_numargs(1)
+)
+
+
+divert
diff --git a/gmp/mpn/arm/README b/gmp/mpn/arm/README
new file mode 100644
index 0000000000..598baa3f2e
--- /dev/null
+++ b/gmp/mpn/arm/README
@@ -0,0 +1,35 @@
+Copyright 2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+This directory contains mpn functions for ARM processors. It has been
+optimised for Cortex-A9, but the code in the top-level directory should run
+on all ARM processors at architecture level v4 or later.
diff --git a/gmp/mpn/arm/aors_n.asm b/gmp/mpn/arm/aors_n.asm
new file mode 100644
index 0000000000..fdad9f7ba6
--- /dev/null
+++ b/gmp/mpn/arm/aors_n.asm
@@ -0,0 +1,112 @@
+dnl ARM mpn_add_n and mpn_sub_n
+
+dnl Contributed to the GNU project by Robert Harley.
+
+dnl Copyright 1997, 2000, 2001, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 2.5 slightly fluctuating
+C Cortex-A15 2.25
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`vp', `r2')
+define(`n', `r3')
+
+ifdef(`OPERATION_add_n', `
+ define(`ADDSUB', adds)
+ define(`ADDSUBC', adcs)
+ define(`CLRCY', `cmn r0, #0')
+ define(`SETCY', `cmp $1, #1')
+ define(`RETVAL', `adc r0, n, #0')
+ define(`func', mpn_add_n)
+ define(`func_nc', mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(`ADDSUB', subs)
+ define(`ADDSUBC', sbcs)
+ define(`CLRCY', `cmp r0, r0')
+ define(`SETCY', `rsbs $1, $1, #0')
+ define(`RETVAL', `sbc r0, r0, r0
+ and r0, r0, #1')
+ define(`func', mpn_sub_n)
+ define(`func_nc', mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+PROLOGUE(func_nc)
+ ldr r12, [sp, #0]
+ stmfd sp!, { r8, r9, lr }
+ SETCY( r12)
+ b L(ent)
+EPILOGUE()
+PROLOGUE(func)
+ stmfd sp!, { r8, r9, lr }
+ CLRCY( r12)
+L(ent): tst n, #1
+ beq L(skip1)
+ ldr r12, [up], #4
+ ldr lr, [vp], #4
+ ADDSUBC r12, r12, lr
+ str r12, [rp], #4
+L(skip1):
+ tst n, #2
+ beq L(skip2)
+ ldmia up!, { r8, r9 }
+ ldmia vp!, { r12, lr }
+ ADDSUBC r8, r8, r12
+ ADDSUBC r9, r9, lr
+ stmia rp!, { r8, r9 }
+L(skip2):
+ bics n, n, #3
+ beq L(rtn)
+ stmfd sp!, { r4, r5, r6, r7 }
+
+L(top): ldmia up!, { r4, r5, r6, r7 }
+ ldmia vp!, { r8, r9, r12, lr }
+ ADDSUBC r4, r4, r8
+ sub n, n, #4
+ ADDSUBC r5, r5, r9
+ ADDSUBC r6, r6, r12
+ ADDSUBC r7, r7, lr
+ stmia rp!, { r4, r5, r6, r7 }
+ teq n, #0
+ bne L(top)
+
+ ldmfd sp!, { r4, r5, r6, r7 }
+
+L(rtn): RETVAL
+ ldmfd sp!, { r8, r9, pc }
+EPILOGUE()
diff --git a/gmp/mpn/arm/aorslsh1_n.asm b/gmp/mpn/arm/aorslsh1_n.asm
new file mode 100644
index 0000000000..1cbd4ba1af
--- /dev/null
+++ b/gmp/mpn/arm/aorslsh1_n.asm
@@ -0,0 +1,167 @@
+dnl ARM mpn_addlsh1_n and mpn_sublsh1_n
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C addlsh1_n sublsh1_n
+C cycles/limb cycles/limb
+C StrongARM ? ?
+C XScale ? ?
+C Cortex-A7 ? ?
+C Cortex-A8 ? ?
+C Cortex-A9 3.12 3.7
+C Cortex-A15 ? ?
+
+C TODO
+C * The addlsh1_n code runs well, but is only barely faster than mpn_addmul_1.
+C The sublsh1_n code could surely be tweaked, its REVCY slows down things
+C very much. If two insns are really needed, it might help to separate them
+C for better micro-parallelism.
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`vp', `r2')
+define(`n', `r3')
+
+ifdef(`OPERATION_addlsh1_n', `
+ define(`ADDSUB', adds)
+ define(`ADDSUBC', adcs)
+ define(`SETCY', `cmp $1, #1')
+ define(`RETVAL', `adc r0, $1, #2')
+ define(`SAVECY', `sbc $1, $2, #0')
+ define(`RESTCY', `cmn $1, #1')
+ define(`REVCY', `')
+ define(`INICYR', `mov $1, #0')
+ define(`r10r11', `r11')
+ define(`func', mpn_addlsh1_n)
+ define(`func_nc', mpn_addlsh1_nc)')
+ifdef(`OPERATION_sublsh1_n', `
+ define(`ADDSUB', subs)
+ define(`ADDSUBC', sbcs)
+ define(`SETCY', `rsbs $1, $1, #0')
+ define(`RETVAL', `adc r0, $1, #1')
+ define(`SAVECY', `sbc $1, $1, $1')
+ define(`RESTCY', `cmn $1, #1')
+ define(`REVCY', `sbc $1, $1, $1
+ cmn $1, #1')
+ define(`INICYR', `mvn $1, #0')
+ define(`r10r11', `r10')
+ define(`func', mpn_sublsh1_n)
+ define(`func_nc', mpn_sublsh1_nc)')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n)
+
+ASM_START()
+PROLOGUE(func)
+ push {r4-r10r11, r14}
+
+ifdef(`OPERATION_addlsh1_n', `
+ mvn r11, #0
+')
+ INICYR( r14)
+ subs n, n, #3
+ blt L(le2) C carry clear on branch path
+
+ cmn r0, #0 C clear carry
+ ldmia vp!, {r8, r9, r10}
+ b L(mid)
+
+L(top): RESTCY( r14)
+ ADDSUBC r4, r4, r8
+ ADDSUBC r5, r5, r9
+ ADDSUBC r6, r6, r10
+ ldmia vp!, {r8, r9, r10}
+ stmia rp!, {r4, r5, r6}
+ REVCY(r14)
+ adcs r8, r8, r8
+ adcs r9, r9, r9
+ adcs r10, r10, r10
+ ldmia up!, {r4, r5, r6}
+ SAVECY( r14, r11)
+ subs n, n, #3
+ blt L(exi)
+ RESTCY( r12)
+ ADDSUBC r4, r4, r8
+ ADDSUBC r5, r5, r9
+ ADDSUBC r6, r6, r10
+ ldmia vp!, {r8, r9, r10}
+ stmia rp!, {r4, r5, r6}
+ REVCY(r12)
+L(mid): adcs r8, r8, r8
+ adcs r9, r9, r9
+ adcs r10, r10, r10
+ ldmia up!, {r4, r5, r6}
+ SAVECY( r12, r11)
+ subs n, n, #3
+ bge L(top)
+
+ mov r7, r12 C swap alternating...
+ mov r12, r14 C ...carry-save...
+ mov r14, r7 C ...registers
+
+L(exi): RESTCY( r12)
+ ADDSUBC r4, r4, r8
+ ADDSUBC r5, r5, r9
+ ADDSUBC r6, r6, r10
+ stmia rp!, {r4, r5, r6}
+
+ REVCY(r12)
+L(le2): tst n, #1 C n = {-1,-2,-3} map to [2], [1], [0]
+ beq L(e1)
+
+L(e02): tst n, #2
+ beq L(rt0)
+ ldm vp, {r8, r9}
+ adcs r8, r8, r8
+ adcs r9, r9, r9
+ ldm up, {r4, r5}
+ SAVECY( r12, r11)
+ RESTCY( r14)
+ ADDSUBC r4, r4, r8
+ ADDSUBC r5, r5, r9
+ stm rp, {r4, r5}
+ b L(rt1)
+
+L(e1): ldr r8, [vp]
+ adcs r8, r8, r8
+ ldr r4, [up]
+ SAVECY( r12, r11)
+ RESTCY( r14)
+ ADDSUBC r4, r4, r8
+ str r4, [rp]
+
+L(rt1): mov r14, r12
+ REVCY(r12)
+L(rt0): RETVAL( r14)
+ pop {r4-r10r11, r14}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/aorsmul_1.asm b/gmp/mpn/arm/aorsmul_1.asm
new file mode 100644
index 0000000000..b02fbb3b2a
--- /dev/null
+++ b/gmp/mpn/arm/aorsmul_1.asm
@@ -0,0 +1,135 @@
+dnl ARM mpn_addmul_1 and mpn_submul_1.
+
+dnl Copyright 1998, 2000, 2001, 2003, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM: ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 5.25
+C Cortex-A15 4
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`vl', `r3')
+define(`rl', `r12')
+define(`ul', `r6')
+define(`r', `lr')
+
+ifdef(`OPERATION_addmul_1', `
+ define(`ADDSUB', adds)
+ define(`ADDSUBC', adcs)
+ define(`CLRRCY', `mov $1, #0
+ adds r0, r0, #0')
+ define(`RETVAL', `adc r0, r4, #0')
+ define(`func', mpn_addmul_1)')
+ifdef(`OPERATION_submul_1', `
+ define(`ADDSUB', subs)
+ define(`ADDSUBC', sbcs)
+ define(`CLRRCY', `subs $1, r0, r0')
+ define(`RETVAL', `sbc r0, r0, r0
+ sub r0, $1, r0')
+ define(`func', mpn_submul_1)')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+ASM_START()
+PROLOGUE(func)
+ stmfd sp!, { r4-r6, lr }
+ CLRRCY( r4)
+ tst n, #1
+ beq L(skip1)
+ ldr ul, [up], #4
+ ldr rl, [rp, #0]
+ umull r5, r4, ul, vl
+ ADDSUB r, rl, r5
+ str r, [rp], #4
+L(skip1):
+ tst n, #2
+ beq L(skip2)
+ ldr ul, [up], #4
+ ldr rl, [rp, #0]
+ mov r5, #0
+ umlal r4, r5, ul, vl
+ ldr ul, [up], #4
+ ADDSUBC r, rl, r4
+ ldr rl, [rp, #4]
+ mov r4, #0
+ umlal r5, r4, ul, vl
+ str r, [rp], #4
+ ADDSUBC r, rl, r5
+ str r, [rp], #4
+L(skip2):
+ bics n, n, #3
+ beq L(rtn)
+
+ ldr ul, [up], #4
+ ldr rl, [rp, #0]
+ mov r5, #0
+ umlal r4, r5, ul, vl
+ b L(in)
+
+L(top): ldr ul, [up], #4
+ ADDSUBC r, rl, r5
+ ldr rl, [rp, #4]
+ mov r5, #0
+ umlal r4, r5, ul, vl
+ str r, [rp], #4
+L(in): ldr ul, [up], #4
+ ADDSUBC r, rl, r4
+ ldr rl, [rp, #4]
+ mov r4, #0
+ umlal r5, r4, ul, vl
+ str r, [rp], #4
+ ldr ul, [up], #4
+ ADDSUBC r, rl, r5
+ ldr rl, [rp, #4]
+ mov r5, #0
+ umlal r4, r5, ul, vl
+ str r, [rp], #4
+ ldr ul, [up], #4
+ ADDSUBC r, rl, r4
+ ldr rl, [rp, #4]
+ mov r4, #0
+ umlal r5, r4, ul, vl
+ sub n, n, #4
+ tst n, n
+ str r, [rp], #4
+ bne L(top)
+
+ ADDSUBC r, rl, r5
+ str r, [rp]
+
+L(rtn): RETVAL( r4)
+ ldmfd sp!, { r4-r6, pc }
+EPILOGUE()
diff --git a/gmp/mpn/arm/arm-defs.m4 b/gmp/mpn/arm/arm-defs.m4
new file mode 100644
index 0000000000..6ca964a245
--- /dev/null
+++ b/gmp/mpn/arm/arm-defs.m4
@@ -0,0 +1,91 @@
+divert(-1)
+
+dnl m4 macros for ARM assembler.
+
+dnl Copyright 2001, 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Standard commenting is with @, the default m4 # is for constants and we
+dnl don't want to disable macro expansions in or after them.
+
+changecom(@&*$)
+
+
+dnl APCS register names.
+
+deflit(a1,r0)
+deflit(a2,r1)
+deflit(a3,r2)
+deflit(a4,r3)
+deflit(v1,r4)
+deflit(v2,r5)
+deflit(v3,r6)
+deflit(v4,r7)
+deflit(v5,r8)
+deflit(v6,r9)
+deflit(sb,r9)
+deflit(v7,r10)
+deflit(sl,r10)
+deflit(fp,r11)
+deflit(ip,r12)
+deflit(sp,r13)
+deflit(lr,r14)
+deflit(pc,r15)
+
+
+define(`lea_list', `')
+define(`lea_num',0)
+
+dnl LEA(reg,gmp_symbol)
+dnl
+dnl Load the address of gmp_symbol into a register. The gmp_symbol must be
+dnl either local or protected/hidden, since we assume it has a fixed distance
+dnl from the point of use.
+
+define(`LEA',`dnl
+ldr $1, L(ptr`'lea_num)
+ifdef(`PIC',dnl
+`dnl
+L(bas`'lea_num):dnl
+ add $1, $1, pc`'dnl
+ m4append(`lea_list',`
+L(ptr'lea_num`): .word GSYM_PREFIX`'$2-L(bas'lea_num`)-8')
+ define(`lea_num', eval(lea_num+1))dnl
+',`dnl
+ m4append(`lea_list',`
+L(ptr'lea_num`): .word GSYM_PREFIX`'$2')
+ define(`lea_num', eval(lea_num+1))dnl
+')dnl
+')
+
+define(`EPILOGUE_cpu',
+`lea_list
+ SIZE(`$1',.-`$1')')
+
+divert
diff --git a/gmp/mpn/arm/bdiv_dbm1c.asm b/gmp/mpn/arm/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..ec3de50e8e
--- /dev/null
+++ b/gmp/mpn/arm/bdiv_dbm1c.asm
@@ -0,0 +1,113 @@
+dnl ARM mpn_bdiv_dbm1c.
+
+dnl Copyright 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 4.25
+C Cortex-A15 2.5
+
+C TODO
+C * Try using umlal or umaal.
+C * Try using ldm/stm.
+
+define(`qp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`bd', `r3')
+define(`cy', `sp,#0')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_bdiv_dbm1c)
+ push {r4, r5, r6, r7, r8}
+ ldr r4, [up], #4
+ ldr r5, [sp, #20]
+ ands r12, n, #3
+ beq L(fi0)
+ cmp r12, #2
+ bcc L(fi1)
+ beq L(fi2)
+
+L(fi3): umull r8, r12, r4, bd
+ ldr r4, [up], #4
+ b L(lo3)
+
+L(fi0): umull r6, r7, r4, bd
+ ldr r4, [up], #4
+ b L(lo0)
+
+L(fi1): subs n, n, #1
+ umull r8, r12, r4, bd
+ bls L(wd1)
+ ldr r4, [up], #4
+ b L(lo1)
+
+L(fi2): umull r6, r7, r4, bd
+ ldr r4, [up], #4
+ b L(lo2)
+
+L(top): ldr r4, [up], #4
+ subs r5, r5, r6
+ str r5, [qp], #4
+ sbc r5, r5, r7
+L(lo1): umull r6, r7, r4, bd
+ ldr r4, [up], #4
+ subs r5, r5, r8
+ str r5, [qp], #4
+ sbc r5, r5, r12
+L(lo0): umull r8, r12, r4, bd
+ ldr r4, [up], #4
+ subs r5, r5, r6
+ str r5, [qp], #4
+ sbc r5, r5, r7
+L(lo3): umull r6, r7, r4, bd
+ ldr r4, [up], #4
+ subs r5, r5, r8
+ str r5, [qp], #4
+ sbc r5, r5, r12
+L(lo2): subs n, n, #4
+ umull r8, r12, r4, bd
+ bhi L(top)
+
+L(wd2): subs r5, r5, r6
+ str r5, [qp], #4
+ sbc r5, r5, r7
+L(wd1): subs r5, r5, r8
+ str r5, [qp]
+ sbc r0, r5, r12
+ pop {r4, r5, r6, r7, r8}
+ bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/cnd_aors_n.asm b/gmp/mpn/arm/cnd_aors_n.asm
new file mode 100644
index 0000000000..e8eb60983a
--- /dev/null
+++ b/gmp/mpn/arm/cnd_aors_n.asm
@@ -0,0 +1,134 @@
+dnl ARM mpn_cnd_add_n, mpn_cnd_sub_n
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 3
+C Cortex-A15 2.5
+
+define(`cnd', `r0')
+define(`rp', `r1')
+define(`up', `r2')
+define(`vp', `r3')
+
+define(`n', `r12')
+
+
+ifdef(`OPERATION_cnd_add_n', `
+ define(`ADDSUB', adds)
+ define(`ADDSUBC', adcs)
+ define(`INITCY', `cmn r0, #0')
+ define(`RETVAL', `adc r0, n, #0')
+ define(func, mpn_cnd_add_n)')
+ifdef(`OPERATION_cnd_sub_n', `
+ define(`ADDSUB', subs)
+ define(`ADDSUBC', sbcs)
+ define(`INITCY', `cmp r0, #0')
+ define(`RETVAL', `adc r0, n, #0
+ rsb r0, r0, #1')
+ define(func, mpn_cnd_sub_n)')
+
+MULFUNC_PROLOGUE(mpn_cnd_add_n mpn_cnd_sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ push {r4-r11}
+ ldr n, [sp, #32]
+
+ cmp cnd, #1
+ sbc cnd, cnd, cnd C conditionally set to 0xffffffff
+
+ INITCY C really only needed for n = 0 (mod 4)
+
+ ands r4, n, #3
+ beq L(top)
+ cmp r4, #2
+ bcc L(b1)
+ beq L(b2)
+
+L(b3): ldm vp!, {r4,r5,r6}
+ ldm up!, {r8,r9,r10}
+ bic r4, r4, cnd
+ bic r5, r5, cnd
+ bic r6, r6, cnd
+ ADDSUB r8, r8, r4
+ ADDSUBC r9, r9, r5
+ ADDSUBC r10, r10, r6
+ stm rp!, {r8,r9,r10}
+ sub n, n, #3
+ teq n, #0
+ bne L(top)
+ b L(end)
+
+L(b2): ldm vp!, {r4,r5}
+ ldm up!, {r8,r9}
+ bic r4, r4, cnd
+ bic r5, r5, cnd
+ ADDSUB r8, r8, r4
+ ADDSUBC r9, r9, r5
+ stm rp!, {r8,r9}
+ sub n, n, #2
+ teq n, #0
+ bne L(top)
+ b L(end)
+
+L(b1): ldr r4, [vp], #4
+ ldr r8, [up], #4
+ bic r4, r4, cnd
+ ADDSUB r8, r8, r4
+ str r8, [rp], #4
+ sub n, n, #1
+ teq n, #0
+ beq L(end)
+
+L(top): ldm vp!, {r4,r5,r6,r7}
+ ldm up!, {r8,r9,r10,r11}
+ bic r4, r4, cnd
+ bic r5, r5, cnd
+ bic r6, r6, cnd
+ bic r7, r7, cnd
+ ADDSUBC r8, r8, r4
+ ADDSUBC r9, r9, r5
+ ADDSUBC r10, r10, r6
+ ADDSUBC r11, r11, r7
+ sub n, n, #4
+ stm rp!, {r8,r9,r10,r11}
+ teq n, #0
+ bne L(top)
+
+L(end): RETVAL
+ pop {r4-r11}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/com.asm b/gmp/mpn/arm/com.asm
new file mode 100644
index 0000000000..42f8e3cbbe
--- /dev/null
+++ b/gmp/mpn/arm/com.asm
@@ -0,0 +1,75 @@
+dnl ARM mpn_com.
+
+dnl Copyright 2003, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 2.0
+C Cortex-A15 1.75
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+
+ASM_START()
+PROLOGUE(mpn_com)
+ tst n, #1
+ beq L(skip1)
+ ldr r3, [up], #4
+ mvn r3, r3
+ str r3, [rp], #4
+L(skip1):
+ tst n, #2
+ beq L(skip2)
+ ldmia up!, { r3, r12 } C load 2 limbs
+ mvn r3, r3
+ mvn r12, r12
+ stmia rp!, { r3, r12 } C store 2 limbs
+L(skip2):
+ bics n, n, #3
+ beq L(rtn)
+ stmfd sp!, { r7, r8, r9 } C save regs on stack
+
+L(top): ldmia up!, { r3, r8, r9, r12 } C load 4 limbs
+ subs n, n, #4
+ mvn r3, r3
+ mvn r8, r8
+ mvn r9, r9
+ mvn r12, r12
+ stmia rp!, { r3, r8, r9, r12 } C store 4 limbs
+ bne L(top)
+
+ ldmfd sp!, { r7, r8, r9 } C restore regs from stack
+L(rtn): bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/copyd.asm b/gmp/mpn/arm/copyd.asm
new file mode 100644
index 0000000000..3ea2035099
--- /dev/null
+++ b/gmp/mpn/arm/copyd.asm
@@ -0,0 +1,84 @@
+dnl ARM mpn_copyd.
+
+dnl Contributed to the GNU project by Robert Harley and Torbjörn Granlund.
+
+dnl Copyright 2003, 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 1.25-1.5
+C Cortex-A15 1.25
+
+C TODO
+C * Consider wider unrolling. Analogous 8-way code runs 10% faster on both A9
+C and A15. But it probably slows things down for 8 <= n < a few dozen.
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+ mov r12, n, lsl #2
+ sub r12, r12, #4
+ add rp, rp, r12
+ add up, up, r12
+
+ tst n, #1
+ beq L(skip1)
+ ldr r3, [up], #-4
+ str r3, [rp], #-4
+L(skip1):
+ tst n, #2
+ beq L(skip2)
+ ldmda up!, { r3,r12 }
+ stmda rp!, { r3,r12 }
+L(skip2):
+ bics n, n, #3
+ beq L(rtn)
+
+ push { r4-r5 }
+ subs n, n, #4
+ ldmda up!, { r3,r4,r5,r12 }
+ beq L(end)
+
+L(top): subs n, n, #4
+ stmda rp!, { r3,r4,r5,r12 }
+ ldmda up!, { r3,r4,r5,r12 }
+ bne L(top)
+
+L(end): stmda rp, { r3,r4,r5,r12 }
+ pop { r4-r5 }
+L(rtn): bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/copyi.asm b/gmp/mpn/arm/copyi.asm
new file mode 100644
index 0000000000..fa454702c1
--- /dev/null
+++ b/gmp/mpn/arm/copyi.asm
@@ -0,0 +1,79 @@
+dnl ARM mpn_copyi.
+
+dnl Contributed to the GNU project by Robert Harley and Torbjörn Granlund.
+
+dnl Copyright 2003, 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 1.25-1.5
+C Cortex-A15 1.25
+
+C TODO
+C * Consider wider unrolling. Analogous 8-way code runs 10% faster on both A9
+C and A15. But it probably slows things down for 8 <= n < a few dozen.
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+ tst n, #1
+ beq L(skip1)
+ ldr r3, [up], #4
+ str r3, [rp], #4
+L(skip1):
+ tst n, #2
+ beq L(skip2)
+ ldmia up!, { r3,r12 }
+ stmia rp!, { r3,r12 }
+L(skip2):
+ bics n, n, #3
+ beq L(rtn)
+
+ push { r4-r5 }
+ subs n, n, #4
+ ldmia up!, { r3,r4,r5,r12 }
+ beq L(end)
+
+L(top): subs n, n, #4
+ stmia rp!, { r3,r4,r5,r12 }
+ ldmia up!, { r3,r4,r5,r12 }
+ bne L(top)
+
+L(end): stm rp, { r3,r4,r5,r12 }
+ pop { r4-r5 }
+L(rtn): bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/dive_1.asm b/gmp/mpn/arm/dive_1.asm
new file mode 100644
index 0000000000..a695e47c77
--- /dev/null
+++ b/gmp/mpn/arm/dive_1.asm
@@ -0,0 +1,151 @@
+dnl ARM v4 mpn_modexact_1c_odd
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb
+C norm unorm modexact_1c_odd
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 10 12
+C Cortex-A15 9 9
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te -
+C v6 -
+C v6t2 -
+C v7a -
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`d', `r3')
+
+define(`cy', `r7')
+define(`cnt', `r6')
+define(`tnc', `r8')
+
+ASM_START()
+PROLOGUE(mpn_divexact_1)
+ tst d, #1
+ push {r4-r9}
+ mov cnt, #0
+ bne L(inv)
+
+C count trailing zeros
+ movs r4, d, lsl #16
+ moveq d, d, lsr #16
+ moveq cnt, #16
+ tst d, #0xff
+ moveq d, d, lsr #8
+ addeq cnt, cnt, #8
+ LEA( r4, ctz_tab)
+ and r5, d, #0xff
+ ldrb r4, [r4, r5]
+ mov d, d, lsr r4
+ add cnt, cnt, r4
+
+C binvert limb
+L(inv): LEA( r4, binvert_limb_table)
+ and r12, d, #254
+ ldrb r4, [r4, r12, lsr #1]
+ mul r12, r4, r4
+ mul r12, d, r12
+ rsb r12, r12, r4, lsl #1
+ mul r4, r12, r12
+ mul r4, d, r4
+ rsb r4, r4, r12, lsl #1 C r4 = inverse
+
+ tst cnt, cnt
+ ldr r5, [up], #4 C up[0]
+ mov cy, #0
+ bne L(unnorm)
+
+L(norm):
+ subs n, n, #1 C set carry as side-effect
+ beq L(end)
+
+ ALIGN(16)
+L(top): sbcs cy, r5, cy
+ ldr r5, [up], #4
+ sub n, n, #1
+ mul r9, r4, cy
+ tst n, n
+ umull r12, cy, d, r9
+ str r9, [rp], #4
+ bne L(top)
+
+L(end): sbc cy, r5, cy
+ mul r9, r4, cy
+ str r9, [rp]
+ pop {r4-r9}
+ bx r14
+
+L(unnorm):
+ rsb tnc, cnt, #32
+ mov r5, r5, lsr cnt
+ subs n, n, #1 C set carry as side-effect
+ beq L(edu)
+
+ ALIGN(16)
+L(tpu): ldr r12, [up], #4
+ orr r9, r5, r12, lsl tnc
+ mov r5, r12, lsr cnt
+ sbcs cy, r9, cy C critical path ->cy->cy->
+ sub n, n, #1
+ mul r9, r4, cy C critical path ->cy->r9->
+ tst n, n
+ umull r12, cy, d, r9 C critical path ->r9->cy->
+ str r9, [rp], #4
+ bne L(tpu)
+
+L(edu): sbc cy, r5, cy
+ mul r9, r4, cy
+ str r9, [rp]
+ pop {r4-r9}
+ bx r14
+EPILOGUE()
+
+ .section .rodata
+ctz_tab:
+ .byte 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
+ .byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
+ .byte 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
+ .byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
+ .byte 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
+ .byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
+ .byte 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
+ .byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
diff --git a/gmp/mpn/arm/gmp-mparam.h b/gmp/mpn/arm/gmp-mparam.h
new file mode 100644
index 0000000000..87eec3a149
--- /dev/null
+++ b/gmp/mpn/arm/gmp-mparam.h
@@ -0,0 +1,127 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2003, 2009, 2010 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 1193MHz ARM (gcc55.fsffrance.org) */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* preinv always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 56
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 11
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD MP_SIZE_T_MAX
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 71
+#define USE_PREINV_DIVREM_1 1 /* preinv always */
+#define DIVREM_2_THRESHOLD 0 /* preinv always */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 41
+
+#define MUL_TOOM22_THRESHOLD 36
+#define MUL_TOOM33_THRESHOLD 125
+#define MUL_TOOM44_THRESHOLD 193
+#define MUL_TOOM6H_THRESHOLD 303
+#define MUL_TOOM8H_THRESHOLD 418
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 125
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 176
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 114
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 129
+
+#define SQR_BASECASE_THRESHOLD 12
+#define SQR_TOOM2_THRESHOLD 78
+#define SQR_TOOM3_THRESHOLD 137
+#define SQR_TOOM4_THRESHOLD 212
+#define SQR_TOOM6_THRESHOLD 306
+#define SQR_TOOM8_THRESHOLD 422
+
+#define MULMOD_BNM1_THRESHOLD 20
+#define SQRMOD_BNM1_THRESHOLD 26
+
+#define MUL_FFT_MODF_THRESHOLD 436 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 436, 5}, { 27, 6}, { 28, 7}, { 15, 6}, \
+ { 32, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
+ { 39, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 49, 8}, \
+ { 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
+ { 256, 9}, { 512,10}, { 1024,11}, { 2048,12}, \
+ { 4096,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 28
+#define MUL_FFT_THRESHOLD 5760
+
+#define SQR_FFT_MODF_THRESHOLD 404 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 404, 5}, { 13, 4}, { 27, 5}, { 27, 6}, \
+ { 28, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
+ { 35, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
+ { 27, 9}, { 15, 8}, { 39, 9}, { 512,10}, \
+ { 1024,11}, { 2048,12}, { 4096,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 26
+#define SQR_FFT_THRESHOLD 3776
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 137
+#define MULLO_MUL_N_THRESHOLD 11479
+
+#define DC_DIV_QR_THRESHOLD 150
+#define DC_DIVAPPR_Q_THRESHOLD 494
+#define DC_BDIV_QR_THRESHOLD 148
+#define DC_BDIV_Q_THRESHOLD 345
+
+#define INV_MULMOD_BNM1_THRESHOLD 70
+#define INV_NEWTON_THRESHOLD 474
+#define INV_APPR_THRESHOLD 478
+
+#define BINV_NEWTON_THRESHOLD 542
+#define REDC_1_TO_REDC_N_THRESHOLD 117
+
+#define MU_DIV_QR_THRESHOLD 2089
+#define MU_DIVAPPR_Q_THRESHOLD 2172
+#define MUPI_DIV_QR_THRESHOLD 225
+#define MU_BDIV_QR_THRESHOLD 1528
+#define MU_BDIV_Q_THRESHOLD 2089
+
+#define MATRIX22_STRASSEN_THRESHOLD 16
+#define HGCD_THRESHOLD 197
+#define GCD_DC_THRESHOLD 902
+#define GCDEXT_DC_THRESHOLD 650
+#define JACOBI_BASE_METHOD 2
+
+#define GET_STR_DC_THRESHOLD 20
+#define GET_STR_PRECOMPUTE_THRESHOLD 39
+#define SET_STR_DC_THRESHOLD 1045
+#define SET_STR_PRECOMPUTE_THRESHOLD 2147
diff --git a/gmp/mpn/arm/invert_limb.asm b/gmp/mpn/arm/invert_limb.asm
new file mode 100644
index 0000000000..d4c3afe2da
--- /dev/null
+++ b/gmp/mpn/arm/invert_limb.asm
@@ -0,0 +1,93 @@
+dnl ARM mpn_invert_limb -- Invert a normalized limb.
+
+dnl Copyright 2001, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_invert_limb)
+ LEA( r2, approx_tab-512)
+ mov r3, r0, lsr #23
+ mov r3, r3, asl #1
+ ldrh r3, [r3, r2]
+ mov r1, r3, asl #17
+ mul r12, r3, r3
+ umull r3, r2, r12, r0
+ sub r1, r1, r2, asl #1
+ umull r3, r2, r1, r1
+ umull r12, r3, r0, r3
+ umull r2, r12, r0, r2
+ adds r2, r2, r3
+ adc r12, r12, #0
+ rsb r1, r12, r1
+ mvn r2, r2, lsr #30
+ add r2, r2, r1, asl #2
+ umull r12, r3, r0, r2
+ adds r1, r12, r0
+ adc r3, r3, r0
+ rsb r0, r3, r2
+ bx lr
+EPILOGUE()
+
+ .section .rodata
+ ALIGN(2)
+approx_tab:
+ .short 0xffc0,0xfec0,0xfdc0,0xfcc0,0xfbc0,0xfac0,0xfa00,0xf900
+ .short 0xf800,0xf700,0xf640,0xf540,0xf440,0xf380,0xf280,0xf180
+ .short 0xf0c0,0xefc0,0xef00,0xee00,0xed40,0xec40,0xeb80,0xeac0
+ .short 0xe9c0,0xe900,0xe840,0xe740,0xe680,0xe5c0,0xe500,0xe400
+ .short 0xe340,0xe280,0xe1c0,0xe100,0xe040,0xdf80,0xdec0,0xde00
+ .short 0xdd40,0xdc80,0xdbc0,0xdb00,0xda40,0xd980,0xd8c0,0xd800
+ .short 0xd740,0xd680,0xd600,0xd540,0xd480,0xd3c0,0xd340,0xd280
+ .short 0xd1c0,0xd140,0xd080,0xcfc0,0xcf40,0xce80,0xcdc0,0xcd40
+ .short 0xcc80,0xcc00,0xcb40,0xcac0,0xca00,0xc980,0xc8c0,0xc840
+ .short 0xc780,0xc700,0xc640,0xc5c0,0xc540,0xc480,0xc400,0xc380
+ .short 0xc2c0,0xc240,0xc1c0,0xc100,0xc080,0xc000,0xbf80,0xbec0
+ .short 0xbe40,0xbdc0,0xbd40,0xbc80,0xbc00,0xbb80,0xbb00,0xba80
+ .short 0xba00,0xb980,0xb900,0xb840,0xb7c0,0xb740,0xb6c0,0xb640
+ .short 0xb5c0,0xb540,0xb4c0,0xb440,0xb3c0,0xb340,0xb2c0,0xb240
+ .short 0xb1c0,0xb140,0xb0c0,0xb080,0xb000,0xaf80,0xaf00,0xae80
+ .short 0xae00,0xad80,0xad40,0xacc0,0xac40,0xabc0,0xab40,0xaac0
+ .short 0xaa80,0xaa00,0xa980,0xa900,0xa8c0,0xa840,0xa7c0,0xa740
+ .short 0xa700,0xa680,0xa600,0xa5c0,0xa540,0xa4c0,0xa480,0xa400
+ .short 0xa380,0xa340,0xa2c0,0xa240,0xa200,0xa180,0xa140,0xa0c0
+ .short 0xa080,0xa000,0x9f80,0x9f40,0x9ec0,0x9e80,0x9e00,0x9dc0
+ .short 0x9d40,0x9d00,0x9c80,0x9c40,0x9bc0,0x9b80,0x9b00,0x9ac0
+ .short 0x9a40,0x9a00,0x9980,0x9940,0x98c0,0x9880,0x9840,0x97c0
+ .short 0x9780,0x9700,0x96c0,0x9680,0x9600,0x95c0,0x9580,0x9500
+ .short 0x94c0,0x9440,0x9400,0x93c0,0x9340,0x9300,0x92c0,0x9240
+ .short 0x9200,0x91c0,0x9180,0x9100,0x90c0,0x9080,0x9000,0x8fc0
+ .short 0x8f80,0x8f40,0x8ec0,0x8e80,0x8e40,0x8e00,0x8d80,0x8d40
+ .short 0x8d00,0x8cc0,0x8c80,0x8c00,0x8bc0,0x8b80,0x8b40,0x8b00
+ .short 0x8a80,0x8a40,0x8a00,0x89c0,0x8980,0x8940,0x88c0,0x8880
+ .short 0x8840,0x8800,0x87c0,0x8780,0x8740,0x8700,0x8680,0x8640
+ .short 0x8600,0x85c0,0x8580,0x8540,0x8500,0x84c0,0x8480,0x8440
+ .short 0x8400,0x8380,0x8340,0x8300,0x82c0,0x8280,0x8240,0x8200
+ .short 0x81c0,0x8180,0x8140,0x8100,0x80c0,0x8080,0x8040,0x8000
+ASM_END()
diff --git a/gmp/mpn/arm/logops_n.asm b/gmp/mpn/arm/logops_n.asm
new file mode 100644
index 0000000000..5a61683fc2
--- /dev/null
+++ b/gmp/mpn/arm/logops_n.asm
@@ -0,0 +1,139 @@
+dnl ARM mpn_and_n, mpn_andn_n. mpn_nand_n, etc.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 1997, 2000, 2001, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb
+C and andn ior xor nand iorn nior xnor
+C StrongARM ? ?
+C XScale ? ?
+C Cortex-A7 ? ?
+C Cortex-A8 ? ?
+C Cortex-A9 2.5-2.72 2.75-3
+C Cortex-A15 2.25 2.75
+
+C TODO
+C * It seems that 2.25 c/l and 2.75 c/l is possible for A9.
+C * Debug popping issue, see comment below.
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`vp', `r2')
+define(`n', `r3')
+
+define(`POSTOP')
+
+ifdef(`OPERATION_and_n',`
+ define(`func', `mpn_and_n')
+ define(`LOGOP', `and $1, $2, $3')')
+ifdef(`OPERATION_andn_n',`
+ define(`func', `mpn_andn_n')
+ define(`LOGOP', `bic $1, $2, $3')')
+ifdef(`OPERATION_nand_n',`
+ define(`func', `mpn_nand_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `and $1, $2, $3')')
+ifdef(`OPERATION_ior_n',`
+ define(`func', `mpn_ior_n')
+ define(`LOGOP', `orr $1, $2, $3')')
+ifdef(`OPERATION_iorn_n',`
+ define(`func', `mpn_iorn_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `bic $1, $3, $2')')
+ifdef(`OPERATION_nior_n',`
+ define(`func', `mpn_nior_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `orr $1, $2, $3')')
+ifdef(`OPERATION_xor_n',`
+ define(`func', `mpn_xor_n')
+ define(`LOGOP', `eor $1, $2, $3')')
+ifdef(`OPERATION_xnor_n',`
+ define(`func', `mpn_xnor_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `eor $1, $2, $3')')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+ASM_START()
+PROLOGUE(func)
+ push { r8, r9, r10 }
+ tst n, #1
+ beq L(skip1)
+ ldr r10, [vp], #4
+ ldr r12, [up], #4
+ LOGOP( r12, r12, r10)
+ POSTOP( r12)
+ str r12, [rp], #4
+L(skip1):
+ tst n, #2
+ beq L(skip2)
+ ldmia vp!, { r10, r12 }
+ ldmia up!, { r8, r9 }
+ LOGOP( r8, r8, r10)
+ LOGOP( r9, r9, r12)
+ POSTOP( r8)
+ POSTOP( r9)
+ stmia rp!, { r8, r9 }
+L(skip2):
+ bics n, n, #3
+ beq L(rtn)
+ push { r4, r5, r6, r7 }
+
+ ldmia vp!, { r8, r9, r10, r12 }
+ b L(mid)
+
+L(top): ldmia vp!, { r8, r9, r10, r12 }
+ POSTOP( r4)
+ POSTOP( r5)
+ POSTOP( r6)
+ POSTOP( r7)
+ stmia rp!, { r4, r5, r6, r7 }
+L(mid): sub n, n, #4
+ ldmia up!, { r4, r5, r6, r7 }
+ teq n, #0
+ LOGOP( r4, r4, r8)
+ LOGOP( r5, r5, r9)
+ LOGOP( r6, r6, r10)
+ LOGOP( r7, r7, r12)
+ bne L(top)
+
+ POSTOP( r4)
+ POSTOP( r5)
+ POSTOP( r6)
+ POSTOP( r7)
+ stmia rp!, { r4, r5, r6, r7 }
+
+ pop { r4, r5, r6, r7 } C popping r8-r10 here strangely fails
+
+L(rtn): pop { r8, r9, r10 }
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/lshift.asm b/gmp/mpn/arm/lshift.asm
new file mode 100644
index 0000000000..9f777eb4dd
--- /dev/null
+++ b/gmp/mpn/arm/lshift.asm
@@ -0,0 +1,88 @@
+dnl ARM mpn_lshift.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 3.5
+C Cortex-A15 ?
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`cnt', `r3')
+define(`tnc', `r12')
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ add up, up, n, lsl #2
+ push {r4, r6, r7, r8}
+ ldr r4, [up, #-4]!
+ add rp, rp, n, lsl #2
+ rsb tnc, cnt, #32
+
+ mov r7, r4, lsl cnt
+ tst n, #1
+ beq L(evn) C n even
+
+L(odd): subs n, n, #2
+ bcc L(1) C n = 1
+ ldr r8, [up, #-4]!
+ b L(mid)
+
+L(evn): ldr r6, [up, #-4]!
+ subs n, n, #2
+ beq L(end)
+
+L(top): ldr r8, [up, #-4]!
+ orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]!
+ mov r7, r6, lsl cnt
+L(mid): ldr r6, [up, #-4]!
+ orr r7, r7, r8, lsr tnc
+ str r7, [rp, #-4]!
+ mov r7, r8, lsl cnt
+ subs n, n, #2
+ bgt L(top)
+
+L(end): orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]!
+ mov r7, r6, lsl cnt
+L(1): str r7, [rp, #-4]
+ mov r0, r4, lsr tnc
+ pop {r4, r6, r7, r8}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/lshiftc.asm b/gmp/mpn/arm/lshiftc.asm
new file mode 100644
index 0000000000..5f3d6e3f5b
--- /dev/null
+++ b/gmp/mpn/arm/lshiftc.asm
@@ -0,0 +1,95 @@
+dnl ARM mpn_lshiftc.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 4.0
+C Cortex-A15 ?
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`cnt', `r3')
+define(`tnc', `r12')
+
+ASM_START()
+PROLOGUE(mpn_lshiftc)
+ add up, up, n, lsl #2
+ push {r4, r6, r7, r8}
+ ldr r4, [up, #-4]!
+ add rp, rp, n, lsl #2
+ rsb tnc, cnt, #32
+ mvn r6, r4
+
+ mov r7, r6, lsl cnt
+ tst n, #1
+ beq L(evn) C n even
+
+L(odd): subs n, n, #2
+ bcc L(1) C n = 1
+ ldr r8, [up, #-4]!
+ mvn r8, r8
+ b L(mid)
+
+L(evn): ldr r6, [up, #-4]!
+ mvn r6, r6
+ subs n, n, #2
+ beq L(end)
+
+L(top): ldr r8, [up, #-4]!
+ orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]!
+ mvn r8, r8
+ mov r7, r6, lsl cnt
+L(mid): ldr r6, [up, #-4]!
+ orr r7, r7, r8, lsr tnc
+ str r7, [rp, #-4]!
+ mvn r6, r6
+ mov r7, r8, lsl cnt
+ subs n, n, #2
+ bgt L(top)
+
+L(end): orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]!
+ mov r7, r6, lsl cnt
+L(1): mvn r6, #0
+ orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]
+ mov r0, r4, lsr tnc
+ pop {r4, r6, r7, r8}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/mod_34lsub1.asm b/gmp/mpn/arm/mod_34lsub1.asm
new file mode 100644
index 0000000000..ba3c06d8db
--- /dev/null
+++ b/gmp/mpn/arm/mod_34lsub1.asm
@@ -0,0 +1,121 @@
+dnl ARM mpn_mod_34lsub1 -- remainder modulo 2^24-1.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 1.33
+C Cortex-A15 1.33
+
+define(`ap', r0)
+define(`n', r1)
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr up, mp_size_t n)
+
+C TODO
+C * Write cleverer summation code.
+C * Consider loading 6 64-bit aligned registers at a time, to approach 1 c/l.
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mod_34lsub1)
+ push { r4, r5, r6, r7 }
+
+ subs n, n, #3
+ mov r7, #0
+ blt L(le2) C n <= 2
+
+ ldmia ap!, { r2, r3, r12 }
+ subs n, n, #3
+ blt L(sum) C n <= 5
+ cmn r0, #0 C clear carry
+ sub n, n, #3
+ b L(mid)
+
+L(top): adcs r2, r2, r4
+ adcs r3, r3, r5
+ adcs r12, r12, r6
+L(mid): ldmia ap!, { r4, r5, r6 }
+ tst n, n
+ sub n, n, #3
+ bpl L(top)
+
+ add n, n, #3
+
+ adcs r2, r2, r4
+ adcs r3, r3, r5
+ adcs r12, r12, r6
+ movcs r7, #1 C r7 <= 1
+
+L(sum): cmn n, #2
+ movlo r4, #0
+ ldrhs r4, [ap], #4
+ movls r5, #0
+ ldrhi r5, [ap], #4
+
+ adds r2, r2, r4
+ adcs r3, r3, r5
+ adcs r12, r12, #0
+ adc r7, r7, #0 C r7 <= 2
+
+L(sum2):
+ bic r0, r2, #0xff000000
+ add r0, r0, r2, lsr #24
+ add r0, r0, r7
+
+ mov r7, r3, lsl #8
+ bic r1, r7, #0xff000000
+ add r0, r0, r1
+ add r0, r0, r3, lsr #16
+
+ mov r7, r12, lsl #16
+ bic r1, r7, #0xff000000
+ add r0, r0, r1
+ add r0, r0, r12, lsr #8
+
+ pop { r4, r5, r6, r7 }
+ bx lr
+
+L(le2): cmn n, #1
+ bne L(1)
+ ldmia ap!, { r2, r3 }
+ mov r12, #0
+ b L(sum2)
+L(1): ldr r2, [ap]
+ bic r0, r2, #0xff000000
+ add r0, r0, r2, lsr #24
+ pop { r4, r5, r6, r7 }
+ bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/mode1o.asm b/gmp/mpn/arm/mode1o.asm
new file mode 100644
index 0000000000..5e0f78fc8f
--- /dev/null
+++ b/gmp/mpn/arm/mode1o.asm
@@ -0,0 +1,92 @@
+dnl ARM mpn_modexact_1c_odd
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 10
+C Cortex-A15 9
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te -
+C v6 -
+C v6t2 -
+C v7a -
+
+define(`up', `r0')
+define(`n', `r1')
+define(`d', `r2')
+define(`cy', `r3')
+
+ .protected binvert_limb_table
+ASM_START()
+PROLOGUE(mpn_modexact_1c_odd)
+ stmfd sp!, {r4, r5}
+
+ LEA( r4, binvert_limb_table)
+
+ ldr r5, [up], #4 C up[0]
+
+ and r12, d, #254
+ ldrb r4, [r4, r12, lsr #1]
+ mul r12, r4, r4
+ mul r12, d, r12
+ rsb r12, r12, r4, asl #1
+ mul r4, r12, r12
+ mul r4, d, r4
+ rsb r4, r4, r12, asl #1 C r4 = inverse
+
+ subs n, n, #1 C set carry as side-effect
+ beq L(end)
+
+L(top): sbcs cy, r5, cy
+ ldr r5, [up], #4
+ sub n, n, #1
+ mul r12, r4, cy
+ tst n, n
+ umull r12, cy, d, r12
+ bne L(top)
+
+L(end): sbcs cy, r5, cy
+ mul r12, r4, cy
+ umull r12, r0, d, r12
+ addcc r0, r0, #1
+
+ ldmfd sp!, {r4, r5}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/mul_1.asm b/gmp/mpn/arm/mul_1.asm
new file mode 100644
index 0000000000..f7bc1bc386
--- /dev/null
+++ b/gmp/mpn/arm/mul_1.asm
@@ -0,0 +1,94 @@
+dnl ARM mpn_mul_1 -- Multiply a limb vector with a limb and store the result
+dnl in a second limb vector.
+dnl Contributed by Robert Harley.
+
+dnl Copyright 1998, 2000, 2001, 2003, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM 6-8
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 4.75
+C Cortex-A15 ?
+
+C We should rewrite this along the lines of addmul_1.asm. That should save a
+C cycle on StrongARM, and several cycles on XScale.
+
+define(`rp',`r0')
+define(`up',`r1')
+define(`n',`r2')
+define(`vl',`r3')
+
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ stmfd sp!, { r8, r9, lr }
+ ands r12, n, #1
+ beq L(skip1)
+ ldr lr, [up], #4
+ umull r9, r12, lr, vl
+ str r9, [rp], #4
+L(skip1):
+ tst n, #2
+ beq L(skip2)
+ mov r8, r12
+ ldmia up!, { r12, lr }
+ mov r9, #0
+ umlal r8, r9, r12, vl
+ mov r12, #0
+ umlal r9, r12, lr, vl
+ stmia rp!, { r8, r9 }
+L(skip2):
+ bics n, n, #3
+ beq L(rtn)
+ stmfd sp!, { r6, r7 }
+
+L(top): mov r6, r12
+ ldmia up!, { r8, r9, r12, lr }
+ ldr r7, [rp, #12] C cache allocate
+ mov r7, #0
+ umlal r6, r7, r8, vl
+ mov r8, #0
+ umlal r7, r8, r9, vl
+ mov r9, #0
+ umlal r8, r9, r12, vl
+ mov r12, #0
+ umlal r9, r12, lr, vl
+ subs n, n, #4
+ stmia rp!, { r6, r7, r8, r9 }
+ bne L(top)
+
+ ldmfd sp!, { r6, r7 }
+
+L(rtn): mov r0, r12
+ ldmfd sp!, { r8, r9, pc }
+EPILOGUE()
diff --git a/gmp/mpn/arm/neon/README b/gmp/mpn/arm/neon/README
new file mode 100644
index 0000000000..79e3b48ee6
--- /dev/null
+++ b/gmp/mpn/arm/neon/README
@@ -0,0 +1,2 @@
+This directory contains Neon code which runs and is efficient on all
+ARM CPUs which support Neon.
diff --git a/gmp/mpn/arm/neon/hamdist.asm b/gmp/mpn/arm/neon/hamdist.asm
new file mode 100644
index 0000000000..232089647d
--- /dev/null
+++ b/gmp/mpn/arm/neon/hamdist.asm
@@ -0,0 +1,194 @@
+dnl ARM Neon mpn_hamdist -- mpn bit hamming distance.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM: -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 1.89
+C Cortex-A15 0.95
+
+C TODO
+C * Explore using vldr and vldm. Does it help on A9? (These loads do
+C 64-bits-at-a-time, which will mess up in big-endian mode. Except not for
+C popcount. Except perhaps also for popcount for the edge loads.)
+C * Arrange to align the pointer, if that helps performance. Use the same
+C read-and-mask trick we use on PCs, for simplicity and performance. (Sorry
+C valgrind!)
+C * Explore if explicit align directives, e.g., "[ptr:128]" help.
+C * See rth's gmp-devel 2013-02/03 messages about final summation tricks.
+
+C INPUT PARAMETERS
+define(`ap', r0)
+define(`bp', r1)
+define(`n', r2)
+
+C We sum into 16 16-bit counters in q8,q9, but at the end we sum them and end
+C up with 8 16-bit counters. Therefore, we can sum to 8(2^16-1) bits, or
+C (8*2^16-1)/32 = 0x3fff limbs. We use a chunksize close to that, but which
+C can be represented as a 8-bit ARM constant.
+C
+define(`chunksize',0x3f80)
+
+ASM_START()
+PROLOGUE(mpn_hamdist)
+
+ cmp n, #chunksize
+ bhi L(gt16k)
+
+L(lt16k):
+ vmov.i64 q8, #0 C clear summation register
+ vmov.i64 q9, #0 C clear summation register
+
+ tst n, #1
+ beq L(xxx0)
+ vmov.i64 d0, #0
+ vmov.i64 d20, #0
+ sub n, n, #1
+ vld1.32 {d0[0]}, [ap]! C load 1 limb
+ vld1.32 {d20[0]}, [bp]! C load 1 limb
+ veor d0, d0, d20
+ vcnt.8 d24, d0
+ vpadal.u8 d16, d24 C d16/q8 = 0; could just splat
+
+L(xxx0):tst n, #2
+ beq L(xx00)
+ sub n, n, #2
+ vld1.32 {d0}, [ap]! C load 2 limbs
+ vld1.32 {d20}, [bp]! C load 2 limbs
+ veor d0, d0, d20
+ vcnt.8 d24, d0
+ vpadal.u8 d16, d24
+
+L(xx00):tst n, #4
+ beq L(x000)
+ sub n, n, #4
+ vld1.32 {q0}, [ap]! C load 4 limbs
+ vld1.32 {q10}, [bp]! C load 4 limbs
+ veor q0, q0, q10
+ vcnt.8 q12, q0
+ vpadal.u8 q8, q12
+
+L(x000):tst n, #8
+ beq L(0000)
+
+ subs n, n, #8
+ vld1.32 {q0,q1}, [ap]! C load 8 limbs
+ vld1.32 {q10,q11}, [bp]! C load 8 limbs
+ bls L(sum)
+
+L(gt8): vld1.32 {q2,q3}, [ap]! C load 8 limbs
+ vld1.32 {q14,q15}, [bp]! C load 8 limbs
+ veor q0, q0, q10
+ veor q1, q1, q11
+ sub n, n, #8
+ vcnt.8 q12, q0
+ vcnt.8 q13, q1
+ b L(mid)
+
+L(0000):subs n, n, #16
+ blo L(e0)
+
+ vld1.32 {q2,q3}, [ap]! C load 8 limbs
+ vld1.32 {q0,q1}, [ap]! C load 8 limbs
+ vld1.32 {q14,q15}, [bp]! C load 8 limbs
+ vld1.32 {q10,q11}, [bp]! C load 8 limbs
+ veor q2, q2, q14
+ veor q3, q3, q15
+ vcnt.8 q12, q2
+ vcnt.8 q13, q3
+ subs n, n, #16
+ blo L(end)
+
+L(top): vld1.32 {q2,q3}, [ap]! C load 8 limbs
+ vld1.32 {q14,q15}, [bp]! C load 8 limbs
+ veor q0, q0, q10
+ veor q1, q1, q11
+ vpadal.u8 q8, q12
+ vcnt.8 q12, q0
+ vpadal.u8 q9, q13
+ vcnt.8 q13, q1
+L(mid): vld1.32 {q0,q1}, [ap]! C load 8 limbs
+ vld1.32 {q10,q11}, [bp]! C load 8 limbs
+ veor q2, q2, q14
+ veor q3, q3, q15
+ subs n, n, #16
+ vpadal.u8 q8, q12
+ vcnt.8 q12, q2
+ vpadal.u8 q9, q13
+ vcnt.8 q13, q3
+ bhs L(top)
+
+L(end): vpadal.u8 q8, q12
+ vpadal.u8 q9, q13
+L(sum): veor q0, q0, q10
+ veor q1, q1, q11
+ vcnt.8 q12, q0
+ vcnt.8 q13, q1
+ vpadal.u8 q8, q12
+ vpadal.u8 q9, q13
+ vadd.i16 q8, q8, q9
+ C we have 8 16-bit counts
+L(e0): vpaddl.u16 q8, q8 C we have 4 32-bit counts
+ vpaddl.u32 q8, q8 C we have 2 64-bit counts
+ vmov.32 r0, d16[0]
+ vmov.32 r1, d17[0]
+ add r0, r0, r1
+ bx lr
+
+C Code for large count. Splits operand and calls above code.
+define(`ap2', r5)
+define(`bp2', r6)
+L(gt16k):
+ push {r4,r5,r6,r14}
+ mov ap2, ap
+ mov bp2, bp
+ mov r3, n C full count
+ mov r4, #0 C total sum
+
+1: mov n, #chunksize C count for this invocation
+ bl L(lt16k) C could jump deep inside code
+ add ap2, ap2, #chunksize*4 C point at next chunk
+ add bp2, bp2, #chunksize*4 C point at next chunk
+ add r4, r4, r0
+ mov ap, ap2 C put chunk pointer in place for call
+ mov bp, bp2 C put chunk pointer in place for call
+ sub r3, r3, #chunksize
+ cmp r3, #chunksize
+ bhi 1b
+
+ mov n, r3 C count for final invocation
+ bl L(lt16k)
+ add r0, r4, r0
+ pop {r4,r5,r6,pc}
+EPILOGUE()
diff --git a/gmp/mpn/arm/neon/lorrshift.asm b/gmp/mpn/arm/neon/lorrshift.asm
new file mode 100644
index 0000000000..3d6253fd49
--- /dev/null
+++ b/gmp/mpn/arm/neon/lorrshift.asm
@@ -0,0 +1,279 @@
+dnl ARM Neon mpn_lshift and mpn_rshift.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb cycles/limb good
+C aligned unaligned best seen for cpu?
+C StrongARM - -
+C XScale - -
+C Cortex-A7 ? ?
+C Cortex-A8 ? ?
+C Cortex-A9 3 3 Y
+C Cortex-A15 1.5 1.5 Y
+
+
+C We read 64 bits at a time at 32-bit aligned addresses, and except for the
+C first and last store, we write using 64-bit aligned addresses. All shifting
+C is done on 64-bit words in 'extension' registers.
+C
+C It should be possible to read also using 64-bit alignment, by manipulating
+C the shift count for unaligned operands. Not done, since it does not seem to
+C matter for A9 or A15.
+C
+C This will not work in big-endian mode.
+
+C TODO
+C * Try using 128-bit operations. Note that Neon lacks pure 128-bit shifts,
+C which might make it tricky.
+C * Clean up and simplify.
+C * Consider sharing most of the code for lshift and rshift, since the feed-in code,
+C the loop, and most of the wind-down code are identical.
+C * Replace the basecase code with code using 'extension' registers.
+C * Optimise. It is not clear that this loop insn permutation is optimal for
+C either A9 or A15.
+
+C INPUT PARAMETERS
+define(`rp', `r0')
+define(`ap', `r1')
+define(`n', `r2')
+define(`cnt', `r3')
+
+ifdef(`OPERATION_lshift',`
+ define(`IFLSH', `$1')
+ define(`IFRSH', `')
+ define(`X',`0')
+ define(`Y',`1')
+ define(`func',`mpn_lshift')
+')
+ifdef(`OPERATION_rshift',`
+ define(`IFLSH', `')
+ define(`IFRSH', `$1')
+ define(`X',`1')
+ define(`Y',`0')
+ define(`func',`mpn_rshift')
+')
+
+MULFUNC_PROLOGUE(mpn_lshift mpn_rshift)
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(func)
+IFLSH(` mov r12, n, lsl #2 ')
+IFLSH(` add rp, rp, r12 ')
+IFLSH(` add ap, ap, r12 ')
+
+ cmp n, #4 C SIMD code n limit
+ ble L(base)
+
+ifdef(`OPERATION_lshift',`
+ vdup.32 d6, r3 C left shift count is positive
+ sub r3, r3, #64 C right shift count is negative
+ vdup.32 d7, r3
+ mov r12, #-8') C lshift pointer update offset
+ifdef(`OPERATION_rshift',`
+ rsb r3, r3, #0 C right shift count is negative
+ vdup.32 d6, r3
+ add r3, r3, #64 C left shift count is positive
+ vdup.32 d7, r3
+ mov r12, #8') C rshift pointer update offset
+
+IFLSH(` sub ap, ap, #8 ')
+ vld1.32 {d19}, [ap], r12 C load initial 2 limbs
+ vshl.u64 d18, d19, d7 C retval
+
+ tst rp, #4 C is rp 64-bit aligned already?
+ beq L(rp_aligned) C yes, skip
+IFLSH(` add ap, ap, #4 ') C move back ap pointer
+IFRSH(` sub ap, ap, #4 ') C move back ap pointer
+ vshl.u64 d4, d19, d6
+ sub n, n, #1 C first limb handled
+IFLSH(` sub rp, rp, #4 ')
+ vst1.32 {d4[Y]}, [rp]IFRSH(!) C store first limb, rp gets aligned
+ vld1.32 {d19}, [ap], r12 C load ap[1] and ap[2]
+
+L(rp_aligned):
+IFLSH(` sub rp, rp, #8 ')
+ subs n, n, #6
+ blt L(two_or_three_more)
+ tst n, #2
+ beq L(2)
+
+L(1): vld1.32 {d17}, [ap], r12
+ vshl.u64 d5, d19, d6
+ vld1.32 {d16}, [ap], r12
+ vshl.u64 d0, d17, d7
+ vshl.u64 d4, d17, d6
+ sub n, n, #2
+ b L(mid)
+
+L(2): vld1.32 {d16}, [ap], r12
+ vshl.u64 d4, d19, d6
+ vld1.32 {d17}, [ap], r12
+ vshl.u64 d1, d16, d7
+ vshl.u64 d5, d16, d6
+ subs n, n, #4
+ blt L(end)
+
+L(top): vld1.32 {d16}, [ap], r12
+ vorr d2, d4, d1
+ vshl.u64 d0, d17, d7
+ vshl.u64 d4, d17, d6
+ vst1.32 {d2}, [rp:64], r12
+L(mid): vld1.32 {d17}, [ap], r12
+ vorr d3, d5, d0
+ vshl.u64 d1, d16, d7
+ vshl.u64 d5, d16, d6
+ vst1.32 {d3}, [rp:64], r12
+ subs n, n, #4
+ bge L(top)
+
+L(end): tst n, #1
+ beq L(evn)
+
+ vorr d2, d4, d1
+ vst1.32 {d2}, [rp:64], r12
+ b L(cj1)
+
+L(evn): vorr d2, d4, d1
+ vshl.u64 d0, d17, d7
+ vshl.u64 d16, d17, d6
+ vst1.32 {d2}, [rp:64], r12
+ vorr d2, d5, d0
+ b L(cj2)
+
+C Load last 2 - 3 limbs, store last 4 - 5 limbs
+L(two_or_three_more):
+ tst n, #1
+ beq L(l2)
+
+L(l3): vshl.u64 d5, d19, d6
+ vld1.32 {d17}, [ap], r12
+L(cj1): veor d16, d16, d16
+IFLSH(` add ap, ap, #4 ')
+ vld1.32 {d16[Y]}, [ap], r12
+ vshl.u64 d0, d17, d7
+ vshl.u64 d4, d17, d6
+ vorr d3, d5, d0
+ vshl.u64 d1, d16, d7
+ vshl.u64 d5, d16, d6
+ vst1.32 {d3}, [rp:64], r12
+ vorr d2, d4, d1
+ vst1.32 {d2}, [rp:64], r12
+IFLSH(` add rp, rp, #4 ')
+ vst1.32 {d5[Y]}, [rp]
+ vmov.32 r0, d18[X]
+ bx lr
+
+L(l2): vld1.32 {d16}, [ap], r12
+ vshl.u64 d4, d19, d6
+ vshl.u64 d1, d16, d7
+ vshl.u64 d16, d16, d6
+ vorr d2, d4, d1
+L(cj2): vst1.32 {d2}, [rp:64], r12
+ vst1.32 {d16}, [rp]
+ vmov.32 r0, d18[X]
+ bx lr
+
+
+define(`tnc', `r12')
+L(base):
+ push {r4, r6, r7, r8}
+ifdef(`OPERATION_lshift',`
+ ldr r4, [ap, #-4]!
+ rsb tnc, cnt, #32
+
+ mov r7, r4, lsl cnt
+ tst n, #1
+ beq L(ev) C n even
+
+L(od): subs n, n, #2
+ bcc L(ed1) C n = 1
+ ldr r8, [ap, #-4]!
+ b L(md) C n = 3
+
+L(ev): ldr r6, [ap, #-4]!
+ subs n, n, #2
+ beq L(ed) C n = 3
+ C n = 4
+L(tp): ldr r8, [ap, #-4]!
+ orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]!
+ mov r7, r6, lsl cnt
+L(md): ldr r6, [ap, #-4]!
+ orr r7, r7, r8, lsr tnc
+ str r7, [rp, #-4]!
+ mov r7, r8, lsl cnt
+
+L(ed): orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]!
+ mov r7, r6, lsl cnt
+L(ed1): str r7, [rp, #-4]
+ mov r0, r4, lsr tnc
+')
+ifdef(`OPERATION_rshift',`
+ ldr r4, [ap]
+ rsb tnc, cnt, #32
+
+ mov r7, r4, lsr cnt
+ tst n, #1
+ beq L(ev) C n even
+
+L(od): subs n, n, #2
+ bcc L(ed1) C n = 1
+ ldr r8, [ap, #4]!
+ b L(md) C n = 3
+
+L(ev): ldr r6, [ap, #4]!
+ subs n, n, #2
+ beq L(ed) C n = 2
+ C n = 4
+
+L(tp): ldr r8, [ap, #4]!
+ orr r7, r7, r6, lsl tnc
+ str r7, [rp], #4
+ mov r7, r6, lsr cnt
+L(md): ldr r6, [ap, #4]!
+ orr r7, r7, r8, lsl tnc
+ str r7, [rp], #4
+ mov r7, r8, lsr cnt
+
+L(ed): orr r7, r7, r6, lsl tnc
+ str r7, [rp], #4
+ mov r7, r6, lsr cnt
+L(ed1): str r7, [rp], #4
+ mov r0, r4, lsl tnc
+')
+ pop {r4, r6, r7, r8}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/neon/lshiftc.asm b/gmp/mpn/arm/neon/lshiftc.asm
new file mode 100644
index 0000000000..9e4096256d
--- /dev/null
+++ b/gmp/mpn/arm/neon/lshiftc.asm
@@ -0,0 +1,257 @@
+dnl ARM Neon mpn_lshiftc.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb cycles/limb good
+C aligned unaligned best seen for cpu?
+C StrongARM - -
+C XScale - -
+C Cortex-A7 ? ?
+C Cortex-A8 ? ?
+C Cortex-A9 3.5 3.5 Y
+C Cortex-A15 1.75 1.75 Y
+
+
+C We read 64 bits at a time at 32-bit aligned addresses, and except for the
+C first and last store, we write using 64-bit aligned addresses. All shifting
+C is done on 64-bit words in 'extension' registers.
+C
+C It should be possible to read also using 64-bit alignment, by manipulating
+C the shift count for unaligned operands. Not done, since it does not seem to
+C matter for A9 or A15.
+C
+C This will not work in big-endian mode.
+
+C TODO
+C * Try using 128-bit operations. Note that Neon lacks pure 128-bit shifts,
+C which might make it tricky.
+C * Clean up and simplify.
+C * Consider sharing most of the code for lshift and rshift, since the feed-in
+C code, the loop, and most of the wind-down code are identical.
+C * Replace the basecase code with code using 'extension' registers.
+C * Optimise. It is not clear that this loop insn permutation is optimal for
+C either A9 or A15.
+
+C INPUT PARAMETERS
+define(`rp', `r0')
+define(`ap', `r1')
+define(`n', `r2')
+define(`cnt', `r3')
+
+ define(`IFLSH', `$1')
+ define(`IFRSH', `')
+ define(`X',`0')
+ define(`Y',`1')
+ define(`func',`mpn_lshiftc')
+define(`OPERATION_lshiftc',1)
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_lshiftc)
+IFLSH(` mov r12, n, lsl #2 ')
+IFLSH(` add rp, rp, r12 ')
+IFLSH(` add ap, ap, r12 ')
+
+ cmp n, #4 C SIMD code n limit
+ ble L(base)
+
+ifdef(`OPERATION_lshiftc',`
+ vdup.32 d6, r3 C left shift count is positive
+ sub r3, r3, #64 C right shift count is negative
+ vdup.32 d7, r3
+ mov r12, #-8') C lshift pointer update offset
+ifdef(`OPERATION_rshift',`
+ rsb r3, r3, #0 C right shift count is negative
+ vdup.32 d6, r3
+ add r3, r3, #64 C left shift count is positive
+ vdup.32 d7, r3
+ mov r12, #8') C rshift pointer update offset
+
+IFLSH(` sub ap, ap, #8 ')
+ vld1.32 {d19}, [ap], r12 C load initial 2 limbs
+ vshl.u64 d18, d19, d7 C retval
+
+ tst rp, #4 C is rp 64-bit aligned already?
+ beq L(rp_aligned) C yes, skip
+ vmvn d19, d19
+IFLSH(` add ap, ap, #4 ') C move back ap pointer
+IFRSH(` sub ap, ap, #4 ') C move back ap pointer
+ vshl.u64 d4, d19, d6
+ sub n, n, #1 C first limb handled
+IFLSH(` sub rp, rp, #4 ')
+ vst1.32 {d4[Y]}, [rp]IFRSH(!) C store first limb, rp gets aligned
+ vld1.32 {d19}, [ap], r12 C load ap[1] and ap[2]
+
+L(rp_aligned):
+IFLSH(` sub rp, rp, #8 ')
+ subs n, n, #6
+ vmvn d19, d19
+ blt L(two_or_three_more)
+ tst n, #2
+ beq L(2)
+
+L(1): vld1.32 {d17}, [ap], r12
+ vshl.u64 d5, d19, d6
+ vmvn d17, d17
+ vld1.32 {d16}, [ap], r12
+ vshl.u64 d0, d17, d7
+ vshl.u64 d4, d17, d6
+ sub n, n, #2
+ b L(mid)
+
+L(2): vld1.32 {d16}, [ap], r12
+ vshl.u64 d4, d19, d6
+ vmvn d16, d16
+ vld1.32 {d17}, [ap], r12
+ vshl.u64 d1, d16, d7
+ vshl.u64 d5, d16, d6
+ subs n, n, #4
+ blt L(end)
+
+L(top): vmvn d17, d17
+ vld1.32 {d16}, [ap], r12
+ vorr d2, d4, d1
+ vshl.u64 d0, d17, d7
+ vshl.u64 d4, d17, d6
+ vst1.32 {d2}, [rp:64], r12
+L(mid): vmvn d16, d16
+ vld1.32 {d17}, [ap], r12
+ vorr d3, d5, d0
+ vshl.u64 d1, d16, d7
+ vshl.u64 d5, d16, d6
+ vst1.32 {d3}, [rp:64], r12
+ subs n, n, #4
+ bge L(top)
+
+L(end): tst n, #1
+ beq L(evn)
+
+ vorr d2, d4, d1
+ vst1.32 {d2}, [rp:64], r12
+ b L(cj1)
+
+L(evn): vmvn d17, d17
+ vorr d2, d4, d1
+ vshl.u64 d0, d17, d7
+ vshl.u64 d4, d17, d6
+ vst1.32 {d2}, [rp:64], r12
+ vmvn.u8 d17, #0
+ vorr d2, d5, d0
+ vshl.u64 d0, d17, d7
+ vorr d3, d4, d0
+ b L(cj2)
+
+C Load last 2 - 3 limbs, store last 4 - 5 limbs
+L(two_or_three_more):
+ tst n, #1
+ beq L(l2)
+
+L(l3): vshl.u64 d5, d19, d6
+ vld1.32 {d17}, [ap], r12
+L(cj1): vmov.u8 d16, #0
+IFLSH(` add ap, ap, #4 ')
+ vmvn d17, d17
+ vld1.32 {d16[Y]}, [ap], r12
+ vshl.u64 d0, d17, d7
+ vshl.u64 d4, d17, d6
+ vmvn d16, d16
+ vorr d3, d5, d0
+ vshl.u64 d1, d16, d7
+ vshl.u64 d5, d16, d6
+ vst1.32 {d3}, [rp:64], r12
+ vorr d2, d4, d1
+ vst1.32 {d2}, [rp:64], r12
+IFLSH(` add rp, rp, #4 ')
+ vst1.32 {d5[Y]}, [rp]
+ vmov.32 r0, d18[X]
+ bx lr
+
+L(l2): vld1.32 {d16}, [ap], r12
+ vshl.u64 d4, d19, d6
+ vmvn d16, d16
+ vshl.u64 d1, d16, d7
+ vshl.u64 d5, d16, d6
+ vmvn.u8 d17, #0
+ vorr d2, d4, d1
+ vshl.u64 d0, d17, d7
+ vorr d3, d5, d0
+L(cj2): vst1.32 {d2}, [rp:64], r12
+ vst1.32 {d3}, [rp]
+ vmov.32 r0, d18[X]
+ bx lr
+
+
+define(`tnc', `r12')
+L(base):
+ push {r4, r6, r7, r8}
+ ldr r4, [ap, #-4]!
+ rsb tnc, cnt, #32
+ mvn r6, r4
+
+ mov r7, r6, lsl cnt
+ tst n, #1
+ beq L(ev) C n even
+
+L(od): subs n, n, #2
+ bcc L(ed1) C n = 1
+ ldr r8, [ap, #-4]!
+ mvn r8, r8
+ b L(md) C n = 3
+
+L(ev): ldr r6, [ap, #-4]!
+ mvn r6, r6
+ subs n, n, #2
+ beq L(ed) C n = 3
+ C n = 4
+L(tp): ldr r8, [ap, #-4]!
+ orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]!
+ mvn r8, r8
+ mov r7, r6, lsl cnt
+L(md): ldr r6, [ap, #-4]!
+ orr r7, r7, r8, lsr tnc
+ str r7, [rp, #-4]!
+ mvn r6, r6
+ mov r7, r8, lsl cnt
+
+L(ed): orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]!
+ mov r7, r6, lsl cnt
+L(ed1): mvn r6, #0
+ orr r7, r7, r6, lsr tnc
+ str r7, [rp, #-4]
+ mov r0, r4, lsr tnc
+ pop {r4, r6, r7, r8}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/neon/popcount.asm b/gmp/mpn/arm/neon/popcount.asm
new file mode 100644
index 0000000000..2f8f9afc8d
--- /dev/null
+++ b/gmp/mpn/arm/neon/popcount.asm
@@ -0,0 +1,166 @@
+dnl ARM Neon mpn_popcount -- mpn bit population count.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM: -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 1.125
+C Cortex-A15 0.56
+
+C TODO
+C * Explore using vldr and vldm. Does it help on A9? (These loads do
+C 64-bits-at-a-time, which will mess up in big-endian mode. Except not for
+C popcount. Except perhaps also for popcount for the edge loads.)
+C * Arrange to align the pointer, if that helps performance. Use the same
+C read-and-mask trick we use on PCs, for simplicity and performance. (Sorry
+C valgrind!)
+C * Explore if explicit align directives, e.g., "[ptr:128]" help.
+C * See rth's gmp-devel 2013-02/03 messages about final summation tricks.
+
+C INPUT PARAMETERS
+define(`ap', r0)
+define(`n', r1)
+
+C We sum into 16 16-bit counters in q8,q9, but at the end we sum them and end
+C up with 8 16-bit counters. Therefore, we can sum to 8(2^16-1) bits, or
+C (8*2^16-1)/32 = 0x3fff limbs. We use a chunksize close to that, but which
+C can be represented as a 8-bit ARM constant.
+C
+define(`chunksize',0x3f80)
+
+ASM_START()
+PROLOGUE(mpn_popcount)
+
+ cmp n, #chunksize
+ bhi L(gt16k)
+
+L(lt16k):
+ vmov.i64 q8, #0 C clear summation register
+ vmov.i64 q9, #0 C clear summation register
+
+ tst n, #1
+ beq L(xxx0)
+ vmov.i64 d0, #0
+ sub n, n, #1
+ vld1.32 {d0[0]}, [ap]! C load 1 limb
+ vcnt.8 d24, d0
+ vpadal.u8 d16, d24 C d16/q8 = 0; could just splat
+
+L(xxx0):tst n, #2
+ beq L(xx00)
+ sub n, n, #2
+ vld1.32 {d0}, [ap]! C load 2 limbs
+ vcnt.8 d24, d0
+ vpadal.u8 d16, d24
+
+L(xx00):tst n, #4
+ beq L(x000)
+ sub n, n, #4
+ vld1.32 {q0}, [ap]! C load 4 limbs
+ vcnt.8 q12, q0
+ vpadal.u8 q8, q12
+
+L(x000):tst n, #8
+ beq L(0000)
+
+ subs n, n, #8
+ vld1.32 {q0,q1}, [ap]! C load 8 limbs
+ bls L(sum)
+
+L(gt8): vld1.32 {q2,q3}, [ap]! C load 8 limbs
+ sub n, n, #8
+ vcnt.8 q12, q0
+ vcnt.8 q13, q1
+ b L(mid)
+
+L(0000):subs n, n, #16
+ blo L(e0)
+
+ vld1.32 {q2,q3}, [ap]! C load 8 limbs
+ vld1.32 {q0,q1}, [ap]! C load 8 limbs
+ vcnt.8 q12, q2
+ vcnt.8 q13, q3
+ subs n, n, #16
+ blo L(end)
+
+L(top): vld1.32 {q2,q3}, [ap]! C load 8 limbs
+ vpadal.u8 q8, q12
+ vcnt.8 q12, q0
+ vpadal.u8 q9, q13
+ vcnt.8 q13, q1
+L(mid): vld1.32 {q0,q1}, [ap]! C load 8 limbs
+ subs n, n, #16
+ vpadal.u8 q8, q12
+ vcnt.8 q12, q2
+ vpadal.u8 q9, q13
+ vcnt.8 q13, q3
+ bhs L(top)
+
+L(end): vpadal.u8 q8, q12
+ vpadal.u8 q9, q13
+L(sum): vcnt.8 q12, q0
+ vcnt.8 q13, q1
+ vpadal.u8 q8, q12
+ vpadal.u8 q9, q13
+ vadd.i16 q8, q8, q9
+ C we have 8 16-bit counts
+L(e0): vpaddl.u16 q8, q8 C we have 4 32-bit counts
+ vpaddl.u32 q8, q8 C we have 2 64-bit counts
+ vmov.32 r0, d16[0]
+ vmov.32 r1, d17[0]
+ add r0, r0, r1
+ bx lr
+
+C Code for large count. Splits operand and calls above code.
+define(`ap2', r2) C caller-saves reg not used above
+L(gt16k):
+ push {r4,r14}
+ mov ap2, ap
+ mov r3, n C full count
+ mov r4, #0 C total sum
+
+1: mov n, #chunksize C count for this invocation
+ bl L(lt16k) C could jump deep inside code
+ add ap2, ap2, #chunksize*4 C point at next chunk
+ add r4, r4, r0
+ mov ap, ap2 C put chunk pointer in place for call
+ sub r3, r3, #chunksize
+ cmp r3, #chunksize
+ bhi 1b
+
+ mov n, r3 C count for final invocation
+ bl L(lt16k)
+ add r0, r4, r0
+ pop {r4,pc}
+EPILOGUE()
diff --git a/gmp/mpn/arm/neon/sec_tabselect.asm b/gmp/mpn/arm/neon/sec_tabselect.asm
new file mode 100644
index 0000000000..69fceb0063
--- /dev/null
+++ b/gmp/mpn/arm/neon/sec_tabselect.asm
@@ -0,0 +1,140 @@
+dnl ARM Neon mpn_sec_tabselect.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C StrongARM -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 1.15
+C Cortex-A15 0.65
+
+define(`rp', `r0')
+define(`tp', `r1')
+define(`n', `r2')
+define(`nents', `r3')
+C define(`which', on stack)
+
+define(`i', `r4')
+define(`j', `r5')
+
+define(`maskq', `q10')
+define(`maskd', `d20')
+
+ASM_START()
+PROLOGUE(mpn_sec_tabselect)
+ push {r4-r5}
+
+ add r4, sp, #8
+ vld1.32 {d30[], d31[]}, [r4] C 4 `which' copies
+ vmov.i32 q14, #1 C 4 copies of 1
+
+ subs j, n, #8
+ bmi L(outer_end)
+
+L(outer_top):
+ mov i, nents
+ mov r12, tp C preserve tp
+ veor q13, q13, q13 C 4 counter copies
+ veor q2, q2, q2
+ veor q3, q3, q3
+ ALIGN(16)
+L(top): vceq.i32 maskq, q13, q15 C compare idx copies to `which' copies
+ vld1.32 {q0,q1}, [tp]
+ vadd.i32 q13, q13, q14
+ vbit q2, q0, maskq
+ vbit q3, q1, maskq
+ add tp, tp, n, lsl #2
+ subs i, i, #1
+ bne L(top)
+ vst1.32 {q2,q3}, [rp]!
+ add tp, r12, #32 C restore tp, point to next slice
+ subs j, j, #8
+ bpl L(outer_top)
+L(outer_end):
+
+ tst n, #4
+ beq L(b0xx)
+L(b1xx):mov i, nents
+ mov r12, tp
+ veor q13, q13, q13
+ veor q2, q2, q2
+ ALIGN(16)
+L(tp4): vceq.i32 maskq, q13, q15
+ vld1.32 {q0}, [tp]
+ vadd.i32 q13, q13, q14
+ vbit q2, q0, maskq
+ add tp, tp, n, lsl #2
+ subs i, i, #1
+ bne L(tp4)
+ vst1.32 {q2}, [rp]!
+ add tp, r12, #16
+
+L(b0xx):tst n, #2
+ beq L(b00x)
+L(b01x):mov i, nents
+ mov r12, tp
+ veor d26, d26, d26
+ veor d4, d4, d4
+ ALIGN(16)
+L(tp2): vceq.i32 maskd, d26, d30
+ vld1.32 {d0}, [tp]
+ vadd.i32 d26, d26, d28
+ vbit d4, d0, maskd
+ add tp, tp, n, lsl #2
+ subs i, i, #1
+ bne L(tp2)
+ vst1.32 {d4}, [rp]!
+ add tp, r12, #8
+
+L(b00x):tst n, #1
+ beq L(b000)
+L(b001):mov i, nents
+ mov r12, tp
+ veor d26, d26, d26
+ veor d4, d4, d4
+ ALIGN(16)
+L(tp1): vceq.i32 maskd, d26, d30
+ vld1.32 {d0[0]}, [tp]
+ vadd.i32 d26, d26, d28
+ vbit d4, d0, maskd
+ add tp, tp, n, lsl #2
+ subs i, i, #1
+ bne L(tp1)
+ vst1.32 {d4[0]}, [rp]
+
+L(b000):pop {r4-r5}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/rsh1aors_n.asm b/gmp/mpn/arm/rsh1aors_n.asm
new file mode 100644
index 0000000000..95c1f79ad9
--- /dev/null
+++ b/gmp/mpn/arm/rsh1aors_n.asm
@@ -0,0 +1,124 @@
+dnl ARM mpn_rsh1add_n and mpn_rsh1sub_n.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 3.64-3.7
+C Cortex-A15 2.5
+
+C TODO
+C * Not optimised.
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`vp', `r2')
+define(`n', `r3')
+
+ifdef(`OPERATION_rsh1add_n', `
+ define(`ADDSUB', adds)
+ define(`ADDSUBC', adcs)
+ define(`RSTCY', `cmn $1, $1')
+ define(`func', mpn_rsh1add_n)
+ define(`func_nc', mpn_rsh1add_nc)')
+ifdef(`OPERATION_rsh1sub_n', `
+ define(`ADDSUB', subs)
+ define(`ADDSUBC', sbcs)
+ define(`RSTCY',
+ `mvn $2, #0x80000000
+ cmp $2, $1')
+ define(`func', mpn_rsh1sub_n)
+ define(`func_nc', mpn_rsh1sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_rsh1add_n mpn_rsh1sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ push {r4-r11}
+ ldr r4, [up], #4
+ ldr r8, [vp], #4
+ ADDSUB r4, r4, r8
+ movs r12, r7, rrx
+ and r11, r4, #1 C return value
+ subs n, n, #4
+ blo L(end)
+
+L(top): ldmia up!, {r5,r6,r7}
+ ldmia vp!, {r8,r9,r10}
+ cmn r12, r12
+ ADDSUBC r5, r5, r8
+ ADDSUBC r6, r6, r9
+ ADDSUBC r7, r7, r10
+ movs r12, r7, rrx
+ movs r6, r6, rrx
+ movs r5, r5, rrx
+ movs r4, r4, rrx
+ subs n, n, #3
+ stmia rp!, {r4,r5,r6}
+ mov r4, r7
+ bhs L(top)
+
+L(end): cmn n, #2
+ bls L(e2)
+ ldm up, {r5,r6}
+ ldm vp, {r8,r9}
+ cmn r12, r12
+ ADDSUBC r5, r5, r8
+ ADDSUBC r6, r6, r9
+ movs r12, r6, rrx
+ movs r5, r5, rrx
+ movs r4, r4, rrx
+ stmia rp!, {r4,r5}
+ mov r4, r6
+ b L(e1)
+
+L(e2): bne L(e1)
+ ldr r5, [up, #0]
+ ldr r8, [vp, #0]
+ cmn r12, r12
+ ADDSUBC r5, r5, r8
+ movs r12, r5, rrx
+ movs r4, r4, rrx
+ str r4, [rp], #4
+ mov r4, r5
+
+L(e1): RSTCY( r12, r1)
+ mov r4, r4, rrx
+ str r4, [rp, #0]
+ mov r0, r11
+ pop {r4-r11}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/rshift.asm b/gmp/mpn/arm/rshift.asm
new file mode 100644
index 0000000000..84728d038a
--- /dev/null
+++ b/gmp/mpn/arm/rshift.asm
@@ -0,0 +1,86 @@
+dnl ARM mpn_rshift.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 1997, 2000, 2001, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 3.5
+C Cortex-A15 ?
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`cnt', `r3')
+define(`tnc', `r12')
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ push {r4, r6, r7, r8}
+ ldr r4, [up]
+ rsb tnc, cnt, #32
+
+ mov r7, r4, lsr cnt
+ tst n, #1
+ beq L(evn) C n even
+
+L(odd): subs n, n, #2
+ bcc L(1) C n = 1
+ ldr r8, [up, #4]!
+ b L(mid)
+
+L(evn): ldr r6, [up, #4]!
+ subs n, n, #2
+ beq L(end)
+
+L(top): ldr r8, [up, #4]!
+ orr r7, r7, r6, lsl tnc
+ str r7, [rp], #4
+ mov r7, r6, lsr cnt
+L(mid): ldr r6, [up, #4]!
+ orr r7, r7, r8, lsl tnc
+ str r7, [rp], #4
+ mov r7, r8, lsr cnt
+ subs n, n, #2
+ bgt L(top)
+
+L(end): orr r7, r7, r6, lsl tnc
+ str r7, [rp], #4
+ mov r7, r6, lsr cnt
+L(1): str r7, [rp]
+ mov r0, r4, lsl tnc
+ pop {r4, r6, r7, r8}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/sec_tabselect.asm b/gmp/mpn/arm/sec_tabselect.asm
new file mode 100644
index 0000000000..8cf937a091
--- /dev/null
+++ b/gmp/mpn/arm/sec_tabselect.asm
@@ -0,0 +1,131 @@
+dnl ARM mpn_sec_tabselect
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 2.33
+C Cortex-A15 2.2
+
+C TODO
+C * Consider using special code for small nents, either swapping the inner and
+C outer loops, or providing a few completely unrolling the inner loops.
+
+define(`rp', `r0')
+define(`tp', `r1')
+define(`n', `r2')
+define(`nents', `r3')
+C which on stack
+
+define(`i', `r11')
+define(`j', `r12')
+define(`c', `r14')
+define(`mask', `r7')
+
+ASM_START()
+PROLOGUE(mpn_sec_tabselect)
+ push {r4-r11, r14}
+
+ subs j, n, #3
+ bmi L(outer_end)
+L(outer_top):
+ ldr c, [sp, #36]
+ mov i, nents
+ push {tp}
+
+ mov r8, #0
+ mov r9, #0
+ mov r10, #0
+
+L(top): subs c, c, #1
+ ldm tp, {r4,r5,r6}
+ sbc mask, mask, mask
+ subs i, i, #1
+ add tp, tp, n, lsl #2
+ and r4, r4, mask
+ and r5, r5, mask
+ and r6, r6, mask
+ orr r8, r8, r4
+ orr r9, r9, r5
+ orr r10, r10, r6
+ bge L(top)
+
+ stmia rp!, {r8,r9,r10}
+ pop {tp}
+ add tp, tp, #12
+ subs j, j, #3
+ bpl L(outer_top)
+L(outer_end):
+
+ cmp j, #-1
+ bne L(n2)
+
+ ldr c, [sp, #36]
+ mov i, nents
+ mov r8, #0
+ mov r9, #0
+L(tp2): subs c, c, #1
+ sbc mask, mask, mask
+ ldm tp, {r4,r5}
+ subs i, i, #1
+ add tp, tp, n, lsl #2
+ and r4, r4, mask
+ and r5, r5, mask
+ orr r8, r8, r4
+ orr r9, r9, r5
+ bge L(tp2)
+ stmia rp, {r8,r9}
+ pop {r4-r11, r14}
+ bx lr
+
+L(n2): cmp j, #-2
+ bne L(n1)
+
+ ldr c, [sp, #36]
+ mov i, nents
+ mov r8, #0
+L(tp1): subs c, c, #1
+ sbc mask, mask, mask
+ ldr r4, [tp]
+ subs i, i, #1
+ add tp, tp, n, lsl #2
+ and r4, r4, mask
+ orr r8, r8, r4
+ bge L(tp1)
+ str r8, [rp]
+L(n1): pop {r4-r11, r14}
+ bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/udiv.asm b/gmp/mpn/arm/udiv.asm
new file mode 100644
index 0000000000..8d441c74ed
--- /dev/null
+++ b/gmp/mpn/arm/udiv.asm
@@ -0,0 +1,104 @@
+dnl ARM mpn_udiv_qrnnd -- divide a two limb dividend and a one limb divisor.
+dnl Return quotient and store remainder through a supplied pointer.
+
+dnl Copyright 2001, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(`rem_ptr',`r0')
+define(`n1',`r1')
+define(`n0',`r2')
+define(`d',`r3')
+
+C divstep -- develop one quotient bit. Dividend in $1$2, divisor in $3.
+C Quotient bit is shifted into $2.
+define(`divstep',
+ `adcs $2, $2, $2
+ adc $1, $1, $1
+ cmp $1, $3
+ subcs $1, $1, $3')
+
+ASM_START()
+PROLOGUE(mpn_udiv_qrnnd)
+ mov r12, #8 C loop counter for both loops below
+ cmp d, #0x80000000 C check divisor msb and clear carry
+ bcs L(_large_divisor)
+
+L(oop): divstep(n1,n0,d)
+ divstep(n1,n0,d)
+ divstep(n1,n0,d)
+ divstep(n1,n0,d)
+ sub r12, r12, #1
+ teq r12, #0
+ bne L(oop)
+
+ str n1, [rem_ptr] C store remainder
+ adc r0, n0, n0 C quotient: add last carry from divstep
+ bx lr
+
+L(_large_divisor):
+ stmfd sp!, { r8, lr }
+
+ and r8, n0, #1 C save lsb of dividend
+ mov lr, n1, lsl #31
+ orrs n0, lr, n0, lsr #1 C n0 = lo(n1n0 >> 1)
+ mov n1, n1, lsr #1 C n1 = hi(n1n0 >> 1)
+
+ and lr, d, #1 C save lsb of divisor
+ movs d, d, lsr #1 C d = floor(orig_d / 2)
+ adc d, d, #0 C d = ceil(orig_d / 2)
+
+L(oop2):
+ divstep(n1,n0,d)
+ divstep(n1,n0,d)
+ divstep(n1,n0,d)
+ divstep(n1,n0,d)
+ sub r12, r12, #1
+ teq r12, #0
+ bne L(oop2)
+
+ adc n0, n0, n0 C shift and add last carry from divstep
+ add n1, r8, n1, lsl #1 C shift in omitted dividend lsb
+ tst lr, lr C test saved divisor lsb
+ beq L(_even_divisor)
+
+ rsb d, lr, d, lsl #1 C restore orig d value
+ adds n1, n1, n0 C fix remainder for omitted divisor lsb
+ addcs n0, n0, #1 C adjust quotient if rem. fix carried
+ subcs n1, n1, d C adjust remainder accordingly
+ cmp n1, d C remainder >= divisor?
+ subcs n1, n1, d C adjust remainder
+ addcs n0, n0, #1 C adjust quotient
+
+L(_even_divisor):
+ str n1, [rem_ptr] C store remainder
+ mov r0, n0 C quotient
+ ldmfd sp!, { r8, pc }
+EPILOGUE(mpn_udiv_qrnnd)
diff --git a/gmp/mpn/arm/v5/gcd_1.asm b/gmp/mpn/arm/v5/gcd_1.asm
new file mode 100644
index 0000000000..169d154bf0
--- /dev/null
+++ b/gmp/mpn/arm/v5/gcd_1.asm
@@ -0,0 +1,120 @@
+dnl ARM v5 mpn_gcd_1.
+
+dnl Based on the K7 gcd_1.asm, by Kevin Ryde. Rehacked for ARM by Torbjörn
+dnl Granlund.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/bit (approx)
+C StrongARM -
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 5.9
+C Cortex-A15 ?
+C Numbers measured with: speed -CD -s8-32 -t24 mpn_gcd_1
+
+C TODO
+C * Optimise inner-loop better.
+
+C Threshold of when to call bmod when U is one limb. Should be about
+C (time_in_cycles(bmod_1,1) + call_overhead) / (cycles/bit).
+define(`BMOD_THRES_LOG2', 6)
+
+C INPUT PARAMETERS
+define(`up', `r0')
+define(`n', `r1')
+define(`v0', `r2')
+
+ifdef(`BMOD_1_TO_MOD_1_THRESHOLD',,
+ `define(`BMOD_1_TO_MOD_1_THRESHOLD',0xffffffff)')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_gcd_1)
+ push {r4, r7, lr}
+ ldr r3, [up] C U low limb
+
+ orr r3, r3, v0
+ rsb r4, r3, #0
+ and r4, r4, r3
+ clz r4, r4 C min(ctz(u0),ctz(v0))
+ rsb r4, r4, #31
+
+ rsb r12, v0, #0
+ and r12, r12, v0
+ clz r12, r12
+ rsb r12, r12, #31
+ mov v0, v0, lsr r12
+
+ mov r7, v0
+
+ cmp n, #1
+ bne L(nby1)
+
+C Both U and V are single limbs, reduce with bmod if u0 >> v0.
+ ldr r3, [up]
+ cmp v0, r3, lsr #BMOD_THRES_LOG2
+ bhi L(red1)
+
+L(bmod):mov r3, #0 C carry argument
+ bl mpn_modexact_1c_odd
+ b L(red0)
+
+L(nby1):cmp n, #BMOD_1_TO_MOD_1_THRESHOLD
+ blo L(bmod)
+
+ bl mpn_mod_1
+
+L(red0):mov r3, r0
+L(red1):rsbs r12, r3, #0
+ and r12, r12, r3
+ clz r12, r12
+ rsb r12, r12, #31
+ bne L(mid)
+ b L(end)
+
+ ALIGN(8)
+L(top): rsb r12, r12, #31
+ movcc r3, r1 C if x-y < 0
+ movcc r7, r0 C use x,y-x
+L(mid): mov r3, r3, lsr r12 C
+ mov r0, r3 C
+ sub r1, r7, r3 C
+ rsbs r3, r7, r3 C
+ and r12, r1, r3 C
+ clz r12, r12 C
+ bne L(top) C
+
+L(end): mov r0, r7, lsl r4
+ pop {r4, r7, pc}
+EPILOGUE()
diff --git a/gmp/mpn/arm/v5/mod_1_1.asm b/gmp/mpn/arm/v5/mod_1_1.asm
new file mode 100644
index 0000000000..3cf0cd7763
--- /dev/null
+++ b/gmp/mpn/arm/v5/mod_1_1.asm
@@ -0,0 +1,129 @@
+dnl ARM mpn_mod_1_1p
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM -
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 7
+C Cortex-A15 6
+
+define(`ap', `r0')
+define(`n', `r1')
+define(`d', `r2')
+define(`cps',`r3')
+
+ASM_START()
+PROLOGUE(mpn_mod_1_1p)
+ push {r4-r10}
+ add r0, r0, r1, asl #2
+ ldr r5, [r0, #-4]!
+ ldr r12, [r0, #-4]!
+ subs r1, r1, #2
+ ble L(4)
+ ldr r8, [r3, #12]
+ mov r4, r12
+ mov r10, r5
+ umull r7, r5, r10, r8
+ sub r1, r1, #1
+ b L(mid)
+
+L(top): adds r12, r6, r7
+ adcs r10, r4, r5
+ sub r1, r1, #1
+ mov r6, #0
+ movcs r6, r8
+ umull r7, r5, r10, r8
+ adds r4, r12, r6
+ subcs r4, r4, r2
+L(mid): ldr r6, [r0, #-4]!
+ teq r1, #0
+ bne L(top)
+
+ adds r12, r6, r7
+ adcs r5, r4, r5
+ subcs r5, r5, r2
+L(4): ldr r1, [r3, #4]
+ cmp r1, #0
+ beq L(7)
+ ldr r4, [r3, #8]
+ umull r0, r6, r5, r4
+ adds r12, r0, r12
+ addcs r6, r6, #1
+ rsb r0, r1, #32
+ mov r0, r12, lsr r0
+ orr r5, r0, r6, asl r1
+ mov r12, r12, asl r1
+ b L(8)
+L(7): cmp r5, r2
+ subcs r5, r5, r2
+L(8): ldr r0, [r3, #0]
+ umull r4, r3, r5, r0
+ add r5, r5, #1
+ adds r0, r4, r12
+ adc r5, r3, r5
+ mul r5, r2, r5
+ sub r12, r12, r5
+ cmp r12, r0
+ addhi r12, r12, r2
+ cmp r2, r12
+ subls r12, r12, r2
+ mov r0, r12, lsr r1
+ pop {r4-r10}
+ bx r14
+EPILOGUE()
+
+PROLOGUE(mpn_mod_1_1p_cps)
+ stmfd sp!, {r4, r5, r6, r14}
+ mov r5, r0
+ clz r4, r1
+ mov r0, r1, asl r4
+ rsb r6, r0, #0
+ bl mpn_invert_limb
+ str r0, [r5, #0]
+ str r4, [r5, #4]
+ cmp r4, #0
+ beq L(2)
+ rsb r1, r4, #32
+ mov r3, #1
+ mov r3, r3, asl r4
+ orr r3, r3, r0, lsr r1
+ mul r3, r6, r3
+ mov r4, r3, lsr r4
+ str r4, [r5, #8]
+L(2): mul r0, r6, r0
+ str r0, [r5, #12]
+ ldmfd sp!, {r4, r5, r6, pc}
+EPILOGUE()
diff --git a/gmp/mpn/arm/v5/mod_1_2.asm b/gmp/mpn/arm/v5/mod_1_2.asm
new file mode 100644
index 0000000000..aa26ecb21c
--- /dev/null
+++ b/gmp/mpn/arm/v5/mod_1_2.asm
@@ -0,0 +1,156 @@
+dnl ARM mpn_mod_1s_2p
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM -
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 4.25
+C Cortex-A15 3
+
+define(`ap', `r0')
+define(`n', `r1')
+define(`d', `r2')
+define(`cps',`r3')
+
+ASM_START()
+PROLOGUE(mpn_mod_1s_2p)
+ push {r4-r10}
+ tst n, #1
+ add r7, r3, #8
+ ldmia r7, {r7, r8, r12} C load B1, B2, B3
+ add ap, ap, n, lsl #2 C put ap at operand end
+ beq L(evn)
+
+L(odd): subs n, n, #1
+ beq L(1)
+ ldmdb ap!, {r4,r6,r9}
+ mov r10, #0
+ umlal r4, r10, r6, r7
+ umlal r4, r10, r9, r8
+ b L(com)
+
+L(evn): ldmdb ap!, {r4,r10}
+L(com): subs n, n, #2
+ ble L(end)
+ ldmdb ap!, {r5,r6}
+ b L(mid)
+
+L(top): mov r9, #0
+ umlal r5, r9, r6, r7 C B1
+ umlal r5, r9, r4, r8 C B2
+ ldmdb ap!, {r4,r6}
+ umlal r5, r9, r10, r12 C B3
+ ble L(xit)
+ mov r10, #0
+ umlal r4, r10, r6, r7 C B1
+ umlal r4, r10, r5, r8 C B2
+ ldmdb ap!, {r5,r6}
+ umlal r4, r10, r9, r12 C B3
+L(mid): subs n, n, #4
+ bge L(top)
+
+ mov r9, #0
+ umlal r5, r9, r6, r7 C B1
+ umlal r5, r9, r4, r8 C B2
+ umlal r5, r9, r10, r12 C B3
+ mov r4, r5
+
+L(end): movge r9, r10 C executed iff coming via xit
+ ldr r6, [r3, #4] C cps[1] = cnt
+ mov r5, #0
+ umlal r4, r5, r9, r7
+ mov r7, r5, lsl r6
+L(x): rsb r1, r6, #32
+ orr r8, r7, r4, lsr r1
+ mov r9, r4, lsl r6
+ ldr r5, [r3, #0]
+ add r0, r8, #1
+ umull r12, r1, r8, r5
+ adds r4, r12, r9
+ adc r1, r1, r0
+ mul r5, r2, r1
+ sub r9, r9, r5
+ cmp r9, r4
+ addhi r9, r9, r2
+ cmp r2, r9
+ subls r9, r9, r2
+ mov r0, r9, lsr r6
+ pop {r4-r10}
+ bx r14
+
+L(xit): mov r10, #0
+ umlal r4, r10, r6, r7 C B1
+ umlal r4, r10, r5, r8 C B2
+ umlal r4, r10, r9, r12 C B3
+ b L(end)
+
+L(1): ldr r6, [r3, #4] C cps[1] = cnt
+ ldr r4, [ap, #-4] C ap[0]
+ mov r7, #0
+ b L(x)
+EPILOGUE()
+
+PROLOGUE(mpn_mod_1s_2p_cps)
+ push {r4-r8, r14}
+ clz r4, r1
+ mov r5, r1, lsl r4 C b <<= cnt
+ mov r6, r0 C r6 = cps
+ mov r0, r5
+ bl mpn_invert_limb
+ rsb r3, r4, #32
+ mov r3, r0, lsr r3
+ mov r2, #1
+ orr r3, r3, r2, lsl r4
+ rsb r1, r5, #0
+ mul r2, r1, r3
+ umull r3, r12, r2, r0
+ add r12, r2, r12
+ mvn r12, r12
+ mul r1, r5, r12
+ cmp r1, r3
+ addhi r1, r1, r5
+ umull r12, r7, r1, r0
+ add r7, r1, r7
+ mvn r7, r7
+ mul r3, r5, r7
+ cmp r3, r12
+ addhi r3, r3, r5
+ mov r5, r2, lsr r4
+ mov r7, r1, lsr r4
+ mov r8, r3, lsr r4
+ stmia r6, {r0,r4,r5,r7,r8} C fill cps
+ pop {r4-r8, pc}
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/addmul_1.asm b/gmp/mpn/arm/v6/addmul_1.asm
new file mode 100644
index 0000000000..57019e4b2b
--- /dev/null
+++ b/gmp/mpn/arm/v6/addmul_1.asm
@@ -0,0 +1,111 @@
+dnl ARM mpn_addmul_1.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM: -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 3.25
+C Cortex-A15 4
+
+C TODO
+C * Micro-optimise feed-in code.
+C * Optimise for n=1,2 by delaying register saving.
+C * Try using ldm/stm.
+
+define(`rp',`r0')
+define(`up',`r1')
+define(`n', `r2')
+define(`v0',`r3')
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ stmfd sp!, { r4, r5, r6, r7 }
+
+ ands r6, n, #3
+ mov r12, #0
+ beq L(fi0)
+ cmp r6, #2
+ bcc L(fi1)
+ beq L(fi2)
+
+L(fi3): ldr r4, [up], #4
+ ldr r6, [rp, #0]
+ ldr r5, [up], #4
+ b L(lo3)
+
+L(fi0): ldr r5, [up], #4
+ ldr r7, [rp], #4
+ ldr r4, [up], #4
+ b L(lo0)
+
+L(fi1): ldr r4, [up], #4
+ ldr r6, [rp], #8
+ subs n, n, #1
+ beq L(1)
+ ldr r5, [up], #4
+ b L(lo1)
+
+L(fi2): ldr r5, [up], #4
+ ldr r7, [rp], #12
+ ldr r4, [up], #4
+ b L(lo2)
+
+ ALIGN(16)
+L(top): ldr r6, [rp, #-8]
+ ldr r5, [up], #4
+ str r7, [rp, #-12]
+L(lo1): umaal r6, r12, r4, v0
+ ldr r7, [rp, #-4]
+ ldr r4, [up], #4
+ str r6, [rp, #-8]
+L(lo0): umaal r7, r12, r5, v0
+ ldr r6, [rp, #0]
+ ldr r5, [up], #4
+ str r7, [rp, #-4]
+L(lo3): umaal r6, r12, r4, v0
+ ldr r7, [rp, #4]
+ ldr r4, [up], #4
+ str r6, [rp], #16
+L(lo2): umaal r7, r12, r5, v0
+ subs n, n, #4
+ bhi L(top)
+
+ ldr r6, [rp, #-8]
+ str r7, [rp, #-12]
+L(1): umaal r6, r12, r4, v0
+ str r6, [rp, #-8]
+ mov r0, r12
+ ldmfd sp!, { r4, r5, r6, r7 }
+ bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/addmul_2.asm b/gmp/mpn/arm/v6/addmul_2.asm
new file mode 100644
index 0000000000..69817ce340
--- /dev/null
+++ b/gmp/mpn/arm/v6/addmul_2.asm
@@ -0,0 +1,138 @@
+dnl ARM mpn_addmul_2.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM: -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 2.25
+C Cortex-A15 2.5
+
+C This is believed to be optimal for A15 for any unrolling, and optimal for A9
+C for 4-way unrolling. Using separate pointer update instructions is necessary
+C for optimal A9 speed.
+
+C TODO:
+C * Start the first multiply or multiplies directly at function entry.
+
+
+define(`rp',`r0')
+define(`up',`r1')
+define(`n', `r2')
+define(`vp',`r3')
+
+define(`v0',`r6')
+define(`v1',`r7')
+define(`u0',`r3')
+define(`u1',`r9')
+
+define(`cya',`r8')
+define(`cyb',`r12')
+
+
+ASM_START()
+PROLOGUE(mpn_addmul_2)
+ push { r4, r5, r6, r7, r8, r9 }
+
+ ldm vp, { v0, v1 }
+ mov cya, #0
+ mov cyb, #0
+
+ tst n, #1
+ beq L(evn)
+
+L(odd): ldr r5, [rp, #0]
+ ldr u0, [up, #0]
+ ldr r4, [rp, #4]
+ tst n, #2
+ beq L(fi1)
+L(fi3): sub up, up, #12
+ sub rp, rp, #12
+ b L(lo3)
+L(fi1): sub n, n, #1
+ sub up, up, #4
+ sub rp, rp, #4
+ b L(lo1)
+
+L(evn): ldr r4, [rp, #0]
+ ldr u1, [up, #0]
+ ldr r5, [rp, #4]
+ tst n, #2
+ bne L(fi2)
+L(fi0): sub up, up, #8
+ sub rp, rp, #8
+ b L(lo0)
+L(fi2): subs n, n, #2
+ bls L(end)
+
+ ALIGN(16)
+L(top): ldr u0, [up, #4]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #0]
+ ldr r4, [rp, #8]
+ umaal r5, cyb, u1, v1
+L(lo1): ldr u1, [up, #8]
+ umaal r5, cya, u0, v0
+ str r5, [rp, #4]
+ ldr r5, [rp, #12]
+ umaal r4, cyb, u0, v1
+L(lo0): ldr u0, [up, #12]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #8]
+ ldr r4, [rp, #16]
+ umaal r5, cyb, u1, v1
+L(lo3): ldr u1, [up, #16]
+ umaal r5, cya, u0, v0
+ str r5, [rp, #12]
+ ldr r5, [rp, #20]
+ add rp, rp, #16
+ umaal r4, cyb, u0, v1
+ add up, up, #16
+ subs n, n, #4
+ bhi L(top)
+
+L(end): umaal r4, cya, u1, v0
+ ldr u0, [up, #4]
+ umaal r5, cyb, u1, v1
+ str r4, [rp, #0]
+ umaal r5, cya, u0, v0
+ umaal cya, cyb, u0, v1
+ str r5, [rp, #4]
+ str cya, [rp, #8]
+ mov r0, cyb
+
+ pop { r4, r5, r6, r7, r8, r9 }
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/addmul_3.asm b/gmp/mpn/arm/v6/addmul_3.asm
new file mode 100644
index 0000000000..046543020f
--- /dev/null
+++ b/gmp/mpn/arm/v6/addmul_3.asm
@@ -0,0 +1,187 @@
+dnl ARM mpn_addmul_3.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM: -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 2.125
+C Cortex-A15 2
+
+C TODO
+C * Use a fast path for n <= KARATSUBA_MUL_THRESHOLD using a jump table,
+C avoiding the current multiply.
+C * Start the first multiply or multiplies early.
+
+define(`rp',`r0')
+define(`up',`r1')
+define(`n', `r2')
+define(`vp',`r3')
+
+define(`v0',`r4') define(`v1',`r5') define(`v2',`r6')
+define(`u0',`r3') define(`u1',`r14')
+define(`w0',`r7') define(`w1',`r8') define(`w2',`r9')
+define(`cy0',`r10') define(`cy1',`r11') define(`cy2',`r12')
+
+
+ASM_START()
+PROLOGUE(mpn_addmul_3)
+ push { r4-r11, r14 }
+
+ ldr w0, =0xaaaaaaab C 3^{-1} mod 2^32
+ ldm vp, { v0,v1,v2 }
+ mov cy0, #0
+ mov cy1, #0
+ mov cy2, #0
+
+C Tricky n mod 6
+ mul w0, w0, n C n * 3^{-1} mod 2^32
+ and w0, w0, #0xc0000001 C pseudo-CRT mod 3,2
+ sub n, n, #3
+ifdef(`PIC',`
+ add pc, pc, w0, ror $28
+ nop
+ b L(b0)
+ b L(b2)
+ b L(b4)
+ .word 0xe7f000f0 C udf
+ b L(b3)
+ b L(b5)
+ b L(b1)
+',`
+ ldr pc, [pc, w0, ror $28]
+ nop
+ .word L(b0), L(b2), L(b4), 0, L(b3), L(b5), L(b1)
+')
+
+L(b5): add up, up, #-8
+ ldr w1, [rp, #0]
+ ldr w2, [rp, #4]
+ ldr u1, [up, #8]
+ b L(lo5)
+
+L(b4): add rp, rp, #-4
+ add up, up, #-12
+ ldr w2, [rp, #4]
+ ldr w0, [rp, #8]
+ ldr u0, [up, #12]
+ b L(lo4)
+
+L(b3): add rp, rp, #-8
+ add up, up, #-16
+ ldr w0, [rp, #8]
+ ldr w1, [rp, #12]
+ ldr u1, [up, #16]
+ b L(lo3)
+
+L(b1): add rp, rp, #8
+ ldr w2, [rp, #-8]
+ ldr w0, [rp, #-4]
+ ldr u1, [up, #0]
+ b L(lo1)
+
+L(b0): add rp, rp, #4
+ add up, up, #-4
+ ldr w0, [rp, #-4]
+ ldr w1, [rp, #0]
+ ldr u0, [up, #4]
+ b L(lo0)
+
+L(b2): add rp, rp, #12
+ add up, up, #4
+ ldr w1, [rp, #-12]
+ ldr w2, [rp, #-8]
+ ldr u0, [up, #-4]
+
+ ALIGN(16)
+L(top): ldr w0, [rp, #-4]
+ umaal w1, cy0, u0, v0
+ ldr u1, [up, #0]
+ umaal w2, cy1, u0, v1
+ str w1, [rp, #-12]
+ umaal w0, cy2, u0, v2
+L(lo1): ldr w1, [rp, #0]
+ umaal w2, cy0, u1, v0
+ ldr u0, [up, #4]
+ umaal w0, cy1, u1, v1
+ str w2, [rp, #-8]
+ umaal w1, cy2, u1, v2
+L(lo0): ldr w2, [rp, #4]
+ umaal w0, cy0, u0, v0
+ ldr u1, [up, #8]
+ umaal w1, cy1, u0, v1
+ str w0, [rp, #-4]
+ umaal w2, cy2, u0, v2
+L(lo5): ldr w0, [rp, #8]
+ umaal w1, cy0, u1, v0
+ ldr u0, [up, #12]
+ umaal w2, cy1, u1, v1
+ str w1, [rp, #0]
+ umaal w0, cy2, u1, v2
+L(lo4): ldr w1, [rp, #12]
+ umaal w2, cy0, u0, v0
+ ldr u1, [up, #16]
+ umaal w0, cy1, u0, v1
+ str w2, [rp, #4]
+ umaal w1, cy2, u0, v2
+L(lo3): ldr w2, [rp, #16]
+ umaal w0, cy0, u1, v0
+ ldr u0, [up, #20]
+ umaal w1, cy1, u1, v1
+ str w0, [rp, #8]
+ umaal w2, cy2, u1, v2
+L(lo2): subs n, n, #6
+ add up, up, #24
+ add rp, rp, #24
+ bge L(top)
+
+L(end): umaal w1, cy0, u0, v0
+ ldr u1, [up, #0]
+ umaal w2, cy1, u0, v1
+ str w1, [rp, #-12]
+ mov w0, #0
+ umaal w0, cy2, u0, v2
+ umaal w2, cy0, u1, v0
+ umaal w0, cy1, u1, v1
+ str w2, [rp, #-8]
+ umaal cy1, cy2, u1, v2
+ adds w0, w0, cy0
+ str w0, [rp, #-4]
+ adcs w1, cy1, #0
+ str w1, [rp, #0]
+ adc r0, cy2, #0
+
+ pop { r4-r11, pc }
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/dive_1.asm b/gmp/mpn/arm/v6/dive_1.asm
new file mode 100644
index 0000000000..92de81473f
--- /dev/null
+++ b/gmp/mpn/arm/v6/dive_1.asm
@@ -0,0 +1,149 @@
+dnl ARM v6 mpn_divexact_1
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb
+C norm unorm modexact_1c_odd
+C StrongARM - -
+C XScale - -
+C Cortex-A7 ? ?
+C Cortex-A8 ? ?
+C Cortex-A9 9 10 9
+C Cortex-A15 7 7 7
+
+C Architecture requirements:
+C v5 -
+C v5t clz
+C v5te -
+C v6 umaal
+C v6t2 -
+C v7a -
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`d', `r3')
+
+define(`cy', `r7')
+define(`cnt', `r6')
+define(`tnc', `r10')
+
+ASM_START()
+PROLOGUE(mpn_divexact_1)
+ push {r4,r5,r6,r7,r8,r9}
+
+ tst d, #1
+
+ rsb r4, d, #0
+ and r4, r4, d
+ clz r4, r4
+ rsb cnt, r4, #31 C count_trailing_zeros
+ mov d, d, lsr cnt
+
+C binvert limb
+ LEA( r4, binvert_limb_table)
+ and r12, d, #254
+ ldrb r4, [r4, r12, lsr #1]
+ mul r12, r4, r4
+ mul r12, d, r12
+ rsb r12, r12, r4, lsl #1
+ mul r4, r12, r12
+ mul r4, d, r4
+ rsb r4, r4, r12, lsl #1 C r4 = inverse
+
+ ldr r5, [up], #4 C up[0]
+ mov cy, #0
+ rsb r8, r4, #0 C r8 = -inverse
+ beq L(unnorm)
+
+L(norm):
+ subs n, n, #1
+ mul r5, r5, r4
+ beq L(end)
+
+ ALIGN(16)
+L(top): ldr r9, [up], #4
+ mov r12, #0
+ str r5, [rp], #4
+ umaal r12, cy, r5, d
+ mul r5, r9, r4
+ mla r5, cy, r8, r5
+ subs n, n, #1
+ bne L(top)
+
+L(end): str r5, [rp]
+ pop {r4,r5,r6,r7,r8,r9}
+ bx r14
+
+L(unnorm):
+ push {r10,r11}
+ rsb tnc, cnt, #32
+ mov r11, r5, lsr cnt
+ subs n, n, #1
+ beq L(edx)
+
+ ldr r12, [up], #4
+ orr r9, r11, r12, lsl tnc
+ mov r11, r12, lsr cnt
+ mul r5, r9, r4
+ subs n, n, #1
+ beq L(edu)
+
+ ALIGN(16)
+L(tpu): ldr r12, [up], #4
+ orr r9, r11, r12, lsl tnc
+ mov r11, r12, lsr cnt
+ mov r12, #0
+ str r5, [rp], #4
+ umaal r12, cy, r5, d
+ mul r5, r9, r4
+ mla r5, cy, r8, r5
+ subs n, n, #1
+ bne L(tpu)
+
+L(edu): str r5, [rp], #4
+ mov r12, #0
+ umaal r12, cy, r5, d
+ mul r5, r11, r4
+ mla r5, cy, r8, r5
+ str r5, [rp]
+ pop {r10,r11}
+ pop {r4,r5,r6,r7,r8,r9}
+ bx r14
+
+L(edx): mul r5, r11, r4
+ str r5, [rp]
+ pop {r10,r11}
+ pop {r4,r5,r6,r7,r8,r9}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/gmp-mparam.h b/gmp/mpn/arm/v6/gmp-mparam.h
new file mode 100644
index 0000000000..c9c6851769
--- /dev/null
+++ b/gmp/mpn/arm/v6/gmp-mparam.h
@@ -0,0 +1,157 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2003, 2009, 2010, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 700MHz ARM11 (raspberry pi) */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* preinv always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD MP_SIZE_T_MAX
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 29
+#define USE_PREINV_DIVREM_1 1 /* preinv always */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 33
+
+#define MUL_TOOM22_THRESHOLD 36
+#define MUL_TOOM33_THRESHOLD 117
+#define MUL_TOOM44_THRESHOLD 462
+#define MUL_TOOM6H_THRESHOLD 0 /* always */
+#define MUL_TOOM8H_THRESHOLD 620
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 130
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 573
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 209
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 209
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 305
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 50
+#define SQR_TOOM3_THRESHOLD 181
+#define SQR_TOOM4_THRESHOLD 686
+#define SQR_TOOM6_THRESHOLD 0 /* always */
+#define SQR_TOOM8_THRESHOLD 915
+
+#define MULMID_TOOM42_THRESHOLD 72
+
+#define MULMOD_BNM1_THRESHOLD 25
+#define SQRMOD_BNM1_THRESHOLD 30
+
+#define MUL_FFT_MODF_THRESHOLD 476 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 476, 5}, { 21, 6}, { 11, 5}, { 25, 6}, \
+ { 13, 5}, { 27, 6}, { 25, 7}, { 13, 6}, \
+ { 28, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 43, 8}, { 23, 7}, { 51, 8}, \
+ { 27, 7}, { 55, 8}, { 31, 7}, { 63, 8}, \
+ { 43, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
+ { 71, 9}, { 39, 8}, { 83, 9}, { 47, 8}, \
+ { 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
+ { 47, 9}, { 103,11}, { 31,10}, { 63, 9}, \
+ { 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
+ { 191,10}, { 111,11}, { 63,10}, { 127, 9}, \
+ { 255,10}, { 143, 9}, { 287,10}, { 159,11}, \
+ { 95,10}, { 191, 9}, { 383,12}, { 4096,13}, \
+ { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 63
+#define MUL_FFT_THRESHOLD 4736
+
+#define SQR_FFT_MODF_THRESHOLD 464 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 464, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 29, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
+ { 36, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 43, 8}, { 23, 7}, { 49, 8}, \
+ { 27, 7}, { 55, 8}, { 31, 7}, { 63, 8}, \
+ { 35, 7}, { 71, 8}, { 43, 9}, { 23, 8}, \
+ { 55, 9}, { 31, 8}, { 71, 9}, { 39, 8}, \
+ { 83, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
+ { 31, 9}, { 79,10}, { 47, 9}, { 103,11}, \
+ { 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
+ { 159,10}, { 95, 9}, { 191,10}, { 111,11}, \
+ { 63,10}, { 127, 9}, { 255,10}, { 143, 9}, \
+ { 287,10}, { 159,11}, { 95,10}, { 191, 9}, \
+ { 383,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 61
+#define SQR_FFT_THRESHOLD 3776
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 67
+#define MULLO_MUL_N_THRESHOLD 8907
+
+#define DC_DIV_QR_THRESHOLD 40
+#define DC_DIVAPPR_Q_THRESHOLD 156
+#define DC_BDIV_QR_THRESHOLD 71
+#define DC_BDIV_Q_THRESHOLD 208
+
+#define INV_MULMOD_BNM1_THRESHOLD 70
+#define INV_NEWTON_THRESHOLD 151
+#define INV_APPR_THRESHOLD 150
+
+#define BINV_NEWTON_THRESHOLD 375
+#define REDC_1_TO_REDC_2_THRESHOLD 5
+#define REDC_2_TO_REDC_N_THRESHOLD 134
+
+#define MU_DIV_QR_THRESHOLD 2130
+#define MU_DIVAPPR_Q_THRESHOLD 2130
+#define MUPI_DIV_QR_THRESHOLD 80
+#define MU_BDIV_QR_THRESHOLD 1787
+#define MU_BDIV_Q_THRESHOLD 2130
+
+#define POWM_SEC_TABLE 7,32,460,1705
+
+#define MATRIX22_STRASSEN_THRESHOLD 19
+#define HGCD_THRESHOLD 85
+#define HGCD_APPR_THRESHOLD 119
+#define HGCD_REDUCE_THRESHOLD 3389
+#define GCD_DC_THRESHOLD 333
+#define GCDEXT_DC_THRESHOLD 309
+#define JACOBI_BASE_METHOD 1
+
+#define GET_STR_DC_THRESHOLD 21
+#define GET_STR_PRECOMPUTE_THRESHOLD 41
+#define SET_STR_DC_THRESHOLD 527
+#define SET_STR_PRECOMPUTE_THRESHOLD 1323
+
+#define FAC_DSC_THRESHOLD 414
+#define FAC_ODD_THRESHOLD 154
diff --git a/gmp/mpn/arm/v6/mode1o.asm b/gmp/mpn/arm/v6/mode1o.asm
new file mode 100644
index 0000000000..a2f77a6bf5
--- /dev/null
+++ b/gmp/mpn/arm/v6/mode1o.asm
@@ -0,0 +1,95 @@
+dnl ARM v6 mpn_modexact_1c_odd
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 9
+C Cortex-A15 7
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te smulbb
+C v6 umaal
+C v6t2 -
+C v7a -
+
+define(`up', `r0')
+define(`n', `r1')
+define(`d', `r2')
+define(`cy', `r3')
+
+ .protected binvert_limb_table
+ASM_START()
+PROLOGUE(mpn_modexact_1c_odd)
+ stmfd sp!, {r4, r5, r6, r7}
+
+ LEA( r4, binvert_limb_table)
+
+ ldr r6, [up], #4 C up[0]
+
+ and r12, d, #254
+ ldrb r4, [r4, r12, lsr #1]
+ smulbb r12, r4, r4
+ mul r12, d, r12
+ rsb r12, r12, r4, asl #1
+ mul r4, r12, r12
+ mul r4, d, r4
+ rsb r4, r4, r12, asl #1 C r4 = inverse
+
+ subs n, n, #1
+ sub r6, r6, cy
+ mul r6, r6, r4
+ beq L(end)
+
+ rsb r5, r4, #0 C r5 = -inverse
+
+L(top): ldr r7, [up], #4
+ mov r12, #0
+ umaal r12, cy, r6, d
+ mul r6, r7, r4
+ mla r6, cy, r5, r6
+ subs n, n, #1
+ bne L(top)
+
+L(end): mov r12, #0
+ umaal r12, cy, r6, d
+ mov r0, cy
+
+ ldmfd sp!, {r4, r5, r6, r7}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/mul_1.asm b/gmp/mpn/arm/v6/mul_1.asm
new file mode 100644
index 0000000000..0fcc0e46d9
--- /dev/null
+++ b/gmp/mpn/arm/v6/mul_1.asm
@@ -0,0 +1,114 @@
+dnl ARM mpn_mul_1.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM: -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 3.25
+C Cortex-A15 4
+
+C TODO
+C * Micro-optimise feed-in code.
+C * Optimise for n=1,2 by delaying register saving.
+C * Try using ldm/stm.
+
+define(`rp',`r0')
+define(`up',`r1')
+define(`n', `r2')
+define(`v0',`r3')
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ stmfd sp!, { r4, r5, r6, r7 }
+
+ ands r6, n, #3
+ mov r12, #0
+ beq L(fi0)
+ cmp r6, #2
+ bcc L(fi1)
+ beq L(fi2)
+
+L(fi3): ldr r4, [up], #4
+ mov r6, #0
+ ldr r5, [up], #4
+ b L(lo3)
+
+L(fi0): ldr r5, [up], #4
+ add rp, rp, #4
+ mov r7, #0
+ ldr r4, [up], #4
+ b L(lo0)
+
+L(fi1): ldr r4, [up], #4
+ mov r6, #0
+ add rp, rp, #8
+ subs n, n, #1
+ beq L(1)
+ ldr r5, [up], #4
+ b L(lo1)
+
+L(fi2): ldr r5, [up], #4
+ add rp, rp, #12
+ mov r7, #0
+ ldr r4, [up], #4
+ b L(lo2)
+
+ ALIGN(16)
+L(top): mov r6, #0
+ ldr r5, [up], #4
+ str r7, [rp, #-12]
+L(lo1): umaal r6, r12, r4, v0
+ mov r7, #0
+ ldr r4, [up], #4
+ str r6, [rp, #-8]
+L(lo0): umaal r7, r12, r5, v0
+ mov r6, #0
+ ldr r5, [up], #4
+ str r7, [rp, #-4]
+L(lo3): umaal r6, r12, r4, v0
+ mov r7, #0
+ ldr r4, [up], #4
+ str r6, [rp], #16
+L(lo2): umaal r7, r12, r5, v0
+ subs n, n, #4
+ bhi L(top)
+
+ mov r6, #0
+ str r7, [rp, #-12]
+L(1): umaal r6, r12, r4, v0
+ str r6, [rp, #-8]
+ mov r0, r12
+ ldmfd sp!, { r4, r5, r6, r7 }
+ bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/mul_2.asm b/gmp/mpn/arm/v6/mul_2.asm
new file mode 100644
index 0000000000..1679542a3c
--- /dev/null
+++ b/gmp/mpn/arm/v6/mul_2.asm
@@ -0,0 +1,131 @@
+dnl ARM mpn_mul_2.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM: -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 2.25
+C Cortex-A15 2.5
+
+C TODO
+C * This is a trivial edit of the addmul_2 code. Check for simplifications,
+C and possible speedups to 2.0 c/l.
+
+define(`rp',`r0')
+define(`up',`r1')
+define(`n', `r2')
+define(`vp',`r3')
+
+define(`v0',`r6')
+define(`v1',`r7')
+define(`u0',`r3')
+define(`u1',`r9')
+
+define(`cya',`r8')
+define(`cyb',`r12')
+
+
+ASM_START()
+PROLOGUE(mpn_mul_2)
+ push { r4, r5, r6, r7, r8, r9 }
+
+ ldm vp, { v0, v1 }
+ mov cya, #0
+ mov cyb, #0
+
+ tst n, #1
+ beq L(evn)
+L(odd): mov r5, #0
+ ldr u0, [up, #0]
+ mov r4, #0
+ tst n, #2
+ beq L(fi1)
+L(fi3): sub up, up, #12
+ sub rp, rp, #16
+ b L(lo3)
+L(fi1): sub n, n, #1
+ sub up, up, #4
+ sub rp, rp, #8
+ b L(lo1)
+L(evn): mov r4, #0
+ ldr u1, [up, #0]
+ mov r5, #0
+ tst n, #2
+ bne L(fi2)
+L(fi0): sub up, up, #8
+ sub rp, rp, #12
+ b L(lo0)
+L(fi2): subs n, n, #2
+ sub rp, rp, #4
+ bls L(end)
+
+ ALIGN(16)
+L(top): ldr u0, [up, #4]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #4]
+ mov r4, #0
+ umaal r5, cyb, u1, v1
+L(lo1): ldr u1, [up, #8]
+ umaal r5, cya, u0, v0
+ str r5, [rp, #8]
+ mov r5, #0
+ umaal r4, cyb, u0, v1
+L(lo0): ldr u0, [up, #12]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #12]
+ mov r4, #0
+ umaal r5, cyb, u1, v1
+L(lo3): ldr u1, [up, #16]!
+ umaal r5, cya, u0, v0
+ str r5, [rp, #16]!
+ mov r5, #0
+ umaal r4, cyb, u0, v1
+ subs n, n, #4
+ bhi L(top)
+
+L(end): umaal r4, cya, u1, v0
+ ldr u0, [up, #4]
+ umaal r5, cyb, u1, v1
+ str r4, [rp, #4]
+ umaal r5, cya, u0, v0
+ umaal cya, cyb, u0, v1
+ str r5, [rp, #8]
+ str cya, [rp, #12]
+ mov r0, cyb
+
+ pop { r4, r5, r6, r7, r8, r9 }
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/popham.asm b/gmp/mpn/arm/v6/popham.asm
new file mode 100644
index 0000000000..44c8f2361c
--- /dev/null
+++ b/gmp/mpn/arm/v6/popham.asm
@@ -0,0 +1,138 @@
+dnl ARM mpn_popcount and mpn_hamdist.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C popcount hamdist
+C cycles/limb cycles/limb
+C StrongARM -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 8.94 9.47
+C Cortex-A15 5.67 6.44
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te ldrd strd
+C v6 usada8
+C v6t2 -
+C v7a -
+
+ifdef(`OPERATION_popcount',`
+ define(`func',`mpn_popcount')
+ define(`ap', `r0')
+ define(`n', `r1')
+ define(`a0', `r2')
+ define(`a1', `r3')
+ define(`s', `r5')
+ define(`b_01010101', `r6')
+ define(`b_00110011', `r7')
+ define(`b_00001111', `r8')
+ define(`zero', `r9')
+ define(`POPC', `$1')
+ define(`HAMD', `dnl')
+')
+ifdef(`OPERATION_hamdist',`
+ define(`func',`mpn_hamdist')
+ define(`ap', `r0')
+ define(`bp', `r1')
+ define(`n', `r2')
+ define(`a0', `r6')
+ define(`a1', `r7')
+ define(`b0', `r4')
+ define(`b1', `r5')
+ define(`s', `r11')
+ define(`b_01010101', `r8')
+ define(`b_00110011', `r9')
+ define(`b_00001111', `r10')
+ define(`zero', `r3')
+ define(`POPC', `dnl')
+ define(`HAMD', `$1')
+')
+
+
+ASM_START()
+PROLOGUE(func)
+POPC(` push { r4-r9 } ')
+HAMD(` push { r4-r11 } ')
+
+ ldr b_01010101, =0x55555555
+ mov r12, #0
+ ldr b_00110011, =0x33333333
+ mov zero, #0
+ ldr b_00001111, =0x0f0f0f0f
+
+ tst n, #1
+ beq L(evn)
+
+L(odd): ldr a1, [ap], #4 C 1 x 32 1-bit accumulators, 0-1
+HAMD(` ldr b1, [bp], #4 ') C 1 x 32 1-bit accumulators, 0-1
+HAMD(` eor a1, a1, b1 ')
+ and r4, b_01010101, a1, lsr #1
+ sub a1, a1, r4
+ and r4, a1, b_00110011
+ bic r5, a1, b_00110011
+ add r5, r4, r5, lsr #2 C 8 4-bit accumulators, 0-4
+ subs n, n, #1
+ b L(mid)
+
+L(evn): mov s, #0
+
+L(top): ldrd a0, a1, [ap], #8 C 2 x 32 1-bit accumulators, 0-1
+HAMD(` ldrd b0, b1, [bp], #8')
+HAMD(` eor a0, a0, b0 ')
+HAMD(` eor a1, a1, b1 ')
+ subs n, n, #2
+ usada8 r12, s, zero, r12
+ and r4, b_01010101, a0, lsr #1
+ sub a0, a0, r4
+ and r4, b_01010101, a1, lsr #1
+ sub a1, a1, r4
+ and r4, a0, b_00110011
+ bic r5, a0, b_00110011
+ add a0, r4, r5, lsr #2 C 8 4-bit accumulators, 0-4
+ and r4, a1, b_00110011
+ bic r5, a1, b_00110011
+ add a1, r4, r5, lsr #2 C 8 4-bit accumulators, 0-4
+ add r5, a0, a1 C 8 4-bit accumulators, 0-8
+L(mid): and r4, r5, b_00001111
+ bic r5, r5, b_00001111
+ add s, r4, r5, lsr #4 C 4 8-bit accumulators
+ bne L(top)
+
+ usada8 r0, s, zero, r12
+POPC(` pop { r4-r9 } ')
+HAMD(` pop { r4-r11 } ')
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/sqr_basecase.asm b/gmp/mpn/arm/v6/sqr_basecase.asm
new file mode 100644
index 0000000000..d52970aaa7
--- /dev/null
+++ b/gmp/mpn/arm/v6/sqr_basecase.asm
@@ -0,0 +1,518 @@
+dnl ARM v6 mpn_sqr_basecase.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C Code structure:
+C
+C
+C m_2(0m4) m_2(2m4) m_2(1m4) m_2(3m4)
+C | | | |
+C | | | |
+C | | | |
+C \|/ \|/ \|/ \|/
+C ____________ ____________
+C / \ / \
+C \|/ \ \|/ \
+C am_2(3m4) am_2(1m4) am_2(0m4) am_2(2m4)
+C \ /|\ \ /|\
+C \____________/ \____________/
+C \ /
+C \ /
+C \ /
+C tail(0m2) tail(1m2)
+C \ /
+C \ /
+C sqr_diag_addlsh1
+
+C TODO
+C * Further tweak counter and updates in outer loops. (This could save
+C perhaps 5n cycles).
+C * Try to use fewer register. Perhaps coalesce r9 branch target and n_saved.
+C (This could save 2-3 cycles for n > 4.)
+C * Optimise sqr_diag_addlsh1 loop. (This could save O(n) cycles.)
+C * Implement larger final corners (xit/tix). Also stop loops earlier
+C suppressing writes of upper-most rp[] values. (This could save 10-20
+C cycles for n > 4.)
+C * Is the branch table really faster than discrete branches?
+
+define(`rp', r0)
+define(`up', r1)
+define(`n', r2)
+
+define(`v0', r3)
+define(`v1', r6)
+define(`i', r8)
+define(`n_saved', r14)
+define(`cya', r11)
+define(`cyb', r12)
+define(`u0', r7)
+define(`u1', r9)
+
+ASM_START()
+PROLOGUE(mpn_sqr_basecase)
+ and r12, n, #3
+ cmp n, #4
+ addgt r12, r12, #4
+ add pc, pc, r12, lsl #2
+ nop
+ b L(4)
+ b L(1)
+ b L(2)
+ b L(3)
+ b L(0m4)
+ b L(1m4)
+ b L(2m4)
+ b L(3m4)
+
+
+L(1m4): push {r4-r10,r11,r14}
+ mov n_saved, n
+ sub i, n, #4
+ sub n, n, #2
+ add r10, pc, #L(am2_2m4)-.-8
+ ldm up, {v0,v1,u0}
+ sub up, up, #4
+ mov cyb, #0
+ mov r5, #0
+ umull r4, cya, v1, v0
+ str r4, [rp], #-12
+ mov r4, #0
+ b L(ko0)
+
+L(3m4): push {r4-r10,r11,r14}
+ mov n_saved, n
+ sub i, n, #4
+ sub n, n, #2
+ add r10, pc, #L(am2_0m4)-.-8
+ ldm up, {v0,v1,u0}
+ add up, up, #4
+ mov cyb, #0
+ mov r5, #0
+ umull r4, cya, v1, v0
+ str r4, [rp], #-4
+ mov r4, #0
+ b L(ko2)
+
+L(2m4): push {r4-r10,r11,r14}
+ mov n_saved, n
+ sub i, n, #4
+ sub n, n, #2
+ add r10, pc, #L(am2_3m4)-.-8
+ ldm up, {v0,v1,u1}
+ mov cyb, #0
+ mov r4, #0
+ umull r5, cya, v1, v0
+ str r5, [rp], #-8
+ mov r5, #0
+ b L(ko1)
+
+L(0m4): push {r4-r10,r11,r14}
+ mov n_saved, n
+ sub i, n, #4
+ sub n, n, #2
+ add r10, pc, #L(am2_1m4)-.-8
+ ldm up, {v0,v1,u1}
+ mov cyb, #0
+ mov r4, #0
+ add up, up, #8
+ umull r5, cya, v1, v0
+ str r5, [rp, #0]
+ mov r5, #0
+
+L(top): ldr u0, [up, #4]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #4]
+ mov r4, #0
+ umaal r5, cyb, u1, v1
+L(ko2): ldr u1, [up, #8]
+ umaal r5, cya, u0, v0
+ str r5, [rp, #8]
+ mov r5, #0
+ umaal r4, cyb, u0, v1
+L(ko1): ldr u0, [up, #12]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #12]
+ mov r4, #0
+ umaal r5, cyb, u1, v1
+L(ko0): ldr u1, [up, #16]!
+ umaal r5, cya, u0, v0
+ str r5, [rp, #16]!
+ mov r5, #0
+ umaal r4, cyb, u0, v1
+ subs i, i, #4
+ bhi L(top)
+ bx r10
+
+L(evnloop):
+ subs i, n, #4
+ sub n, n, #2
+ blt L(tix)
+ ldm up, {v0,v1,u0}
+ add up, up, #4
+ mov cya, #0
+ mov cyb, #0
+ ldm rp, {r4,r5}
+ sub rp, rp, #4
+ umaal r4, cya, v1, v0
+ str r4, [rp, #4]
+ ldr r4, [rp, #12]
+ b L(lo2)
+L(ua2): ldr u0, [up, #4]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #4]
+ ldr r4, [rp, #12]
+ umaal r5, cyb, u1, v1
+L(lo2): ldr u1, [up, #8]
+ umaal r5, cya, u0, v0
+ str r5, [rp, #8]
+ ldr r5, [rp, #16]
+ umaal r4, cyb, u0, v1
+ ldr u0, [up, #12]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #12]
+ ldr r4, [rp, #20]
+ umaal r5, cyb, u1, v1
+ ldr u1, [up, #16]!
+ umaal r5, cya, u0, v0
+ str r5, [rp, #16]!
+ ldr r5, [rp, #8]
+ umaal r4, cyb, u0, v1
+ subs i, i, #4
+ bhi L(ua2)
+L(am2_0m4):
+ umaal r4, cya, u1, v0
+ ldr u0, [up, #4]
+ umaal r5, cyb, u1, v1
+ str r4, [rp, #4]
+ umaal r5, cya, u0, v0
+ umaal cya, cyb, u0, v1
+ str r5, [rp, #8]
+ str cya, [rp, #12]
+ str cyb, [rp, #16]
+ sub up, up, n, lsl #2
+ sub rp, rp, n, lsl #2
+ add up, up, #8
+ sub i, n, #4
+ sub n, n, #2
+ ldm up, {v0,v1,u0}
+ sub up, up, #4
+ mov cya, #0
+ mov cyb, #0
+ ldr r4, [rp, #24]
+ ldr r5, [rp, #28]
+ add rp, rp, #12
+ umaal r4, cya, v1, v0
+ str r4, [rp, #12]
+ ldr r4, [rp, #20]
+ b L(lo0)
+L(ua0): ldr u0, [up, #4]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #4]
+ ldr r4, [rp, #12]
+ umaal r5, cyb, u1, v1
+ ldr u1, [up, #8]
+ umaal r5, cya, u0, v0
+ str r5, [rp, #8]
+ ldr r5, [rp, #16]
+ umaal r4, cyb, u0, v1
+ ldr u0, [up, #12]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #12]
+ ldr r4, [rp, #20]
+ umaal r5, cyb, u1, v1
+L(lo0): ldr u1, [up, #16]!
+ umaal r5, cya, u0, v0
+ str r5, [rp, #16]!
+ ldr r5, [rp, #8]
+ umaal r4, cyb, u0, v1
+ subs i, i, #4
+ bhi L(ua0)
+L(am2_2m4):
+ umaal r4, cya, u1, v0
+ ldr u0, [up, #4]
+ umaal r5, cyb, u1, v1
+ str r4, [rp, #4]
+ umaal r5, cya, u0, v0
+ umaal cya, cyb, u0, v1
+ str r5, [rp, #8]
+ str cya, [rp, #12]
+ str cyb, [rp, #16]
+ sub up, up, n, lsl #2
+ sub rp, rp, n, lsl #2
+ add up, up, #8
+ add rp, rp, #24
+ b L(evnloop)
+
+
+L(oddloop):
+ subs i, n, #4
+ sub n, n, #2
+ blt L(xit)
+ ldm up, {v0,v1,u1}
+ mov cya, #0
+ mov cyb, #0
+ sub rp, rp, #8
+ ldr r5, [rp, #8]
+ ldr r4, [rp, #12]
+ umaal r5, cya, v1, v0
+ str r5, [rp, #8]
+ ldr r5, [rp, #16]
+ b L(lo1)
+L(ua1): ldr u0, [up, #4]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #4]
+ ldr r4, [rp, #12]
+ umaal r5, cyb, u1, v1
+ ldr u1, [up, #8]
+ umaal r5, cya, u0, v0
+ str r5, [rp, #8]
+ ldr r5, [rp, #16]
+ umaal r4, cyb, u0, v1
+L(lo1): ldr u0, [up, #12]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #12]
+ ldr r4, [rp, #20]
+ umaal r5, cyb, u1, v1
+ ldr u1, [up, #16]!
+ umaal r5, cya, u0, v0
+ str r5, [rp, #16]!
+ ldr r5, [rp, #8]
+ umaal r4, cyb, u0, v1
+ subs i, i, #4
+ bhi L(ua1)
+L(am2_3m4):
+ umaal r4, cya, u1, v0
+ ldr u0, [up, #4]
+ umaal r5, cyb, u1, v1
+ str r4, [rp, #4]
+ umaal r5, cya, u0, v0
+ umaal cya, cyb, u0, v1
+ str r5, [rp, #8]
+ str cya, [rp, #12]
+ str cyb, [rp, #16]
+ sub up, up, n, lsl #2
+ sub rp, rp, n, lsl #2
+ add up, up, #8
+ add rp, rp, #24
+ subs i, n, #4
+ sub n, n, #2
+ ldm up, {v0,v1,u1}
+ mov cya, #0
+ mov cyb, #0
+ ldr r5, [rp, #0]
+ ldr r4, [rp, #4]
+ add up, up, #8
+ umaal r5, cya, v1, v0
+ str r5, [rp, #0]
+ ldr r5, [rp, #8]
+ bls L(e3)
+L(ua3): ldr u0, [up, #4]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #4]
+ ldr r4, [rp, #12]
+ umaal r5, cyb, u1, v1
+ ldr u1, [up, #8]
+ umaal r5, cya, u0, v0
+ str r5, [rp, #8]
+ ldr r5, [rp, #16]
+ umaal r4, cyb, u0, v1
+ ldr u0, [up, #12]
+ umaal r4, cya, u1, v0
+ str r4, [rp, #12]
+ ldr r4, [rp, #20]
+ umaal r5, cyb, u1, v1
+ ldr u1, [up, #16]!
+ umaal r5, cya, u0, v0
+ str r5, [rp, #16]!
+ ldr r5, [rp, #8]
+ umaal r4, cyb, u0, v1
+ subs i, i, #4
+ bhi L(ua3)
+L(e3):
+L(am2_1m4):
+ umaal r4, cya, u1, v0
+ ldr u0, [up, #4]
+ umaal r5, cyb, u1, v1
+ str r4, [rp, #4]
+ umaal r5, cya, u0, v0
+ umaal cya, cyb, u0, v1
+ str r5, [rp, #8]
+ str cya, [rp, #12]
+ str cyb, [rp, #16]
+ sub up, up, n, lsl #2
+ sub rp, rp, n, lsl #2
+ add up, up, #8
+ add rp, rp, #24
+ b L(oddloop)
+
+L(xit): ldm up!, {v0,u0}
+ ldr cya, [rp], #12
+ mov cyb, #0
+ umaal cya, cyb, u0, v0
+ b L(sqr_diag_addlsh1)
+
+L(tix): ldm up!, {v0,v1,u0}
+ ldm rp, {r4,r5}
+ mov cya, #0
+ mov cyb, #0
+ umaal r4, cya, v1, v0
+ umaal r5, cya, u0, v0
+ stm rp, {r4,r5}
+ umaal cya, cyb, u0, v1
+ add rp, rp, #20
+C b L(sqr_diag_addlsh1)
+
+
+define(`w0', r6)
+define(`w1', r7)
+define(`w2', r8)
+define(`rbx', r9)
+
+L(sqr_diag_addlsh1):
+ str cya, [rp, #-12]
+ str cyb, [rp, #-8]
+ sub n, n_saved, #1
+ sub up, up, n_saved, lsl #2
+ sub rp, rp, n_saved, lsl #3
+ ldr r3, [up], #4
+ umull w1, r5, r3, r3
+ mov w2, #0
+ mov r10, #0
+C cmn r0, #0 C clear cy (already clear by luck)
+ b L(lm)
+
+L(tsd): adds w0, w0, rbx
+ adcs w1, w1, r4
+ str w0, [rp, #0]
+L(lm): ldr w0, [rp, #4]
+ str w1, [rp, #4]
+ ldr w1, [rp, #8]!
+ add rbx, r5, w2
+ adcs w0, w0, w0
+ ldr r3, [up], #4
+ adcs w1, w1, w1
+ adc w2, r10, r10
+ umull r4, r5, r3, r3
+ subs n, n, #1
+ bne L(tsd)
+
+ adds w0, w0, rbx
+ adcs w1, w1, r4
+ adc w2, r5, w2
+ stm rp, {w0,w1,w2}
+
+ pop {r4-r10,r11,pc}
+
+
+C Straight line code for n <= 4
+
+L(1): ldr r3, [up, #0]
+ umull r1, r2, r3, r3
+ stm rp, {r1,r2}
+ bx r14
+
+L(2): push {r4-r5}
+ ldm up, {r5,r12}
+ umull r1, r2, r5, r5
+ umull r3, r4, r12, r12
+ umull r5, r12, r5, r12
+ adds r5, r5, r5
+ adcs r12, r12, r12
+ adc r4, r4, #0
+ adds r2, r2, r5
+ adcs r3, r3, r12
+ adc r4, r4, #0
+ stm rp, {r1,r2,r3,r4}
+ pop {r4-r5}
+ bx r14
+
+L(3): push {r4-r11}
+ ldm up, {r7,r8,r9}
+ umull r1, r2, r7, r7
+ umull r3, r4, r8, r8
+ umull r5, r6, r9, r9
+ umull r10, r11, r7, r8
+ mov r12, #0
+ umlal r11, r12, r7, r9
+ mov r7, #0
+ umlal r12, r7, r8, r9
+ adds r10, r10, r10
+ adcs r11, r11, r11
+ adcs r12, r12, r12
+ adcs r7, r7, r7
+ adc r6, r6, #0
+ adds r2, r2, r10
+ adcs r3, r3, r11
+ adcs r4, r4, r12
+ adcs r5, r5, r7
+ adc r6, r6, #0
+ stm rp, {r1,r2,r3,r4,r5,r6}
+ pop {r4-r11}
+ bx r14
+
+L(4): push {r4-r11, r14}
+ ldm up, {r9,r10,r11,r12}
+ umull r1, r2, r9, r9
+ umull r3, r4, r10, r10
+ umull r5, r6, r11, r11
+ umull r7, r8, r12, r12
+ stm rp, {r1,r2,r3,r4,r5,r6,r7}
+ umull r1, r2, r9, r10
+ mov r3, #0
+ umlal r2, r3, r9, r11
+ mov r4, #0
+ umlal r3, r4, r9, r12
+ mov r5, #0
+ umlal r3, r5, r10, r11
+ umaal r4, r5, r10, r12
+ mov r6, #0
+ umlal r5, r6, r11, r12
+ adds r1, r1, r1
+ adcs r2, r2, r2
+ adcs r3, r3, r3
+ adcs r4, r4, r4
+ adcs r5, r5, r5
+ adcs r6, r6, r6
+ adc r7, r8, #0
+ add rp, rp, #4
+ ldm rp, {r8,r9,r10,r11,r12,r14}
+ adds r1, r1, r8
+ adcs r2, r2, r9
+ adcs r3, r3, r10
+ adcs r4, r4, r11
+ adcs r5, r5, r12
+ adcs r6, r6, r14
+ adc r7, r7, #0
+ stm rp, {r1,r2,r3,r4,r5,r6,r7}
+ pop {r4-r11, pc}
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6/submul_1.asm b/gmp/mpn/arm/v6/submul_1.asm
new file mode 100644
index 0000000000..8a21733a0a
--- /dev/null
+++ b/gmp/mpn/arm/v6/submul_1.asm
@@ -0,0 +1,125 @@
+dnl ARM mpn_submul_1.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM: -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 3.75
+C Cortex-A15 4.0
+
+C This loop complements U on the fly,
+C U' = B^n - 1 - U
+C and then uses that
+C R - U*v = R + U'*v + v - B^n v
+
+C TODO
+C * Micro-optimise feed-in code.
+C * Optimise for n=1,2 by delaying register saving.
+C * Try using ldm/stm.
+
+define(`rp',`r0')
+define(`up',`r1')
+define(`n', `r2')
+define(`v0',`r3')
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ stmfd sp!, { r4, r5, r6, r7 }
+
+ ands r6, n, #3
+ mov r12, v0
+ beq L(fi0)
+ cmp r6, #2
+ bcc L(fi1)
+ beq L(fi2)
+
+L(fi3): ldr r4, [up], #12
+ mvn r4, r4
+ ldr r6, [rp, #0]
+ ldr r5, [up, #-8]
+ b L(lo3)
+
+L(fi0): ldr r5, [up], #16
+ mvn r5, r5
+ ldr r7, [rp], #4
+ ldr r4, [up, #-12]
+ b L(lo0)
+
+L(fi1): ldr r4, [up], #4
+ mvn r4, r4
+ ldr r6, [rp], #8
+ subs n, n, #1
+ beq L(1)
+ ldr r5, [up]
+ b L(lo1)
+
+L(fi2): ldr r5, [up], #8
+ mvn r5, r5
+ ldr r7, [rp], #12
+ ldr r4, [up, #-4]
+ b L(lo2)
+
+ ALIGN(16)
+L(top): ldr r6, [rp, #-8]
+ ldr r5, [up]
+ str r7, [rp, #-12]
+L(lo1): umaal r6, r12, r4, v0
+ add up, up, #16
+ mvn r5, r5
+ ldr r7, [rp, #-4]
+ ldr r4, [up, #-12]
+ str r6, [rp, #-8]
+L(lo0): umaal r7, r12, r5, v0
+ mvn r4, r4
+ ldr r6, [rp, #0]
+ ldr r5, [up, #-8]
+ str r7, [rp, #-4]
+L(lo3): umaal r6, r12, r4, v0
+ mvn r5, r5
+ ldr r7, [rp, #4]
+ ldr r4, [up, #-4]
+ str r6, [rp], #16
+L(lo2): umaal r7, r12, r5, v0
+ mvn r4, r4
+ subs n, n, #4
+ bhi L(top)
+
+ ldr r6, [rp, #-8]
+ str r7, [rp, #-12]
+L(1): umaal r6, r12, r4, v0
+ str r6, [rp, #-8]
+ sub r0, v0, r12
+ ldmfd sp!, { r4, r5, r6, r7 }
+ bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6t2/divrem_1.asm b/gmp/mpn/arm/v6t2/divrem_1.asm
new file mode 100644
index 0000000000..be24615acb
--- /dev/null
+++ b/gmp/mpn/arm/v6t2/divrem_1.asm
@@ -0,0 +1,212 @@
+dnl ARM v6t2 mpn_divrem_1 and mpn_preinv_divrem_1.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C norm unorm frac
+C StrongARM - - -
+C XScale - - -
+C Cortex-A7 ? ? ?
+C Cortex-A8 ? ? ?
+C Cortex-A9 13 14 13
+C Cortex-A15 11.4 11.8 11.1
+
+C TODO
+C * Optimise inner-loops better, they could likely run a cycle or two faster.
+C * Decrease register usage, streamline non-loop code.
+
+define(`qp_arg', `r0')
+define(`fn', `r1')
+define(`up_arg', `r2')
+define(`n_arg', `r3')
+define(`d_arg', `0')
+define(`dinv_arg',`4')
+define(`cnt_arg', `8')
+
+define(`n', `r9')
+define(`qp', `r5')
+define(`up', `r6')
+define(`cnt', `r7')
+define(`tnc', `r10')
+define(`dinv', `r0')
+define(`d', `r4')
+
+ASM_START()
+PROLOGUE(mpn_preinv_divrem_1)
+ stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
+ ldr d, [sp, #9*4+d_arg]
+ ldr cnt, [sp, #9*4+cnt_arg]
+ str r1, [sp, #9*4+d_arg] C reuse d stack slot for fn
+ sub n, r3, #1
+ add r3, r1, n
+ cmp d, #0
+ add qp, qp_arg, r3, lsl #2 C put qp at Q[] end
+ add up, up_arg, n, lsl #2 C put up at U[] end
+ ldr dinv, [sp, #9*4+dinv_arg]
+ blt L(nent)
+ b L(uent)
+EPILOGUE()
+
+PROLOGUE(mpn_divrem_1)
+ stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
+ sub n, r3, #1
+ ldr d, [sp, #9*4+d_arg] C d
+ str r1, [sp, #9*4+d_arg] C reuse d stack slot for fn
+ add r3, r1, n
+ cmp d, #0
+ add qp, qp_arg, r3, lsl #2 C put qp at Q[] end
+ add up, up_arg, n, lsl #2 C put up at U[] end
+ blt L(normalised)
+
+L(unnorm):
+ clz cnt, d
+ mov r0, d, lsl cnt C pass d << cnt
+ bl mpn_invert_limb
+L(uent):
+ mov d, d, lsl cnt C d <<= cnt
+ cmp n, #0
+ mov r1, #0 C r
+ blt L(frac)
+
+ ldr r11, [up, #0]
+
+ rsb tnc, cnt, #32
+ mov r1, r11, lsr tnc
+ mov r11, r11, lsl cnt
+ beq L(uend)
+
+ ldr r3, [up, #-4]!
+ orr r2, r11, r3, lsr tnc
+ b L(mid)
+
+L(utop):
+ mls r1, d, r8, r11
+ mov r11, r3, lsl cnt
+ ldr r3, [up, #-4]!
+ cmp r1, r2
+ addhi r1, r1, d
+ subhi r8, r8, #1
+ orr r2, r11, r3, lsr tnc
+ cmp r1, d
+ bcs L(ufx)
+L(uok): str r8, [qp], #-4
+L(mid): add r8, r1, #1
+ mov r11, r2
+ umlal r2, r8, r1, dinv
+ subs n, n, #1
+ bne L(utop)
+
+ mls r1, d, r8, r11
+ mov r11, r3, lsl cnt
+ cmp r1, r2
+ addhi r1, r1, d
+ subhi r8, r8, #1
+ cmp r1, d
+ rsbcs r1, d, r1
+ addcs r8, r8, #1
+ str r8, [qp], #-4
+
+L(uend):add r8, r1, #1
+ mov r2, r11
+ umlal r2, r8, r1, dinv
+ mls r1, d, r8, r11
+ cmp r1, r2
+ addhi r1, r1, d
+ subhi r8, r8, #1
+ cmp r1, d
+ rsbcs r1, d, r1
+ addcs r8, r8, #1
+ str r8, [qp], #-4
+L(frac):
+ ldr r2, [sp, #9*4+d_arg] C fn
+ cmp r2, #0
+ beq L(fend)
+
+L(ftop):mov r6, #0
+ add r3, r1, #1
+ umlal r6, r3, r1, dinv
+ mov r8, #0
+ mls r1, d, r3, r8
+ cmp r1, r6
+ addhi r1, r1, d
+ subhi r3, r3, #1
+ subs r2, r2, #1
+ str r3, [qp], #-4
+ bne L(ftop)
+
+L(fend):mov r11, r1, lsr cnt
+L(rtn): mov r0, r11
+ ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}
+
+L(normalised):
+ mov r0, d
+ bl mpn_invert_limb
+L(nent):
+ cmp n, #0
+ mov r11, #0 C r
+ blt L(nend)
+
+ ldr r11, [up, #0]
+ cmp r11, d
+ movlo r2, #0 C hi q limb
+ movhs r2, #1 C hi q limb
+ subhs r11, r11, d
+
+ str r2, [qp], #-4
+ cmp n, #0
+ beq L(nend)
+
+L(ntop):ldr r1, [up, #-4]!
+ add r12, r11, #1
+ umlal r1, r12, r11, dinv
+ ldr r3, [up, #0]
+ mls r11, d, r12, r3
+ cmp r11, r1
+ addhi r11, r11, d
+ subhi r12, r12, #1
+ cmp d, r11
+ bls L(nfx)
+L(nok): str r12, [qp], #-4
+ subs n, n, #1
+ bne L(ntop)
+
+L(nend):mov r1, r11 C r
+ mov cnt, #0 C shift cnt
+ b L(frac)
+
+L(nfx): add r12, r12, #1
+ rsb r11, d, r11
+ b L(nok)
+L(ufx): rsb r1, d, r1
+ add r8, r8, #1
+ b L(uok)
+EPILOGUE()
diff --git a/gmp/mpn/arm/v6t2/gcd_1.asm b/gmp/mpn/arm/v6t2/gcd_1.asm
new file mode 100644
index 0000000000..2063647963
--- /dev/null
+++ b/gmp/mpn/arm/v6t2/gcd_1.asm
@@ -0,0 +1,115 @@
+dnl ARM v6t2 mpn_gcd_1.
+
+dnl Based on the K7 gcd_1.asm, by Kevin Ryde. Rehacked for ARM by Torbjörn
+dnl Granlund.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/bit (approx)
+C StrongARM -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 5.3
+C Cortex-A15 3.5
+C Numbers measured with: speed -CD -s8-32 -t24 mpn_gcd_1
+
+C TODO
+C * Optimise inner-loop better.
+C * Push saving/restoring of callee-user regs into call code
+
+C Threshold of when to call bmod when U is one limb. Should be about
+C (time_in_cycles(bmod_1,1) + call_overhead) / (cycles/bit).
+define(`BMOD_THRES_LOG2', 7)
+
+C INPUT PARAMETERS
+define(`up', `r0')
+define(`n', `r1')
+define(`v0', `r2')
+
+ifdef(`BMOD_1_TO_MOD_1_THRESHOLD',,
+ `define(`BMOD_1_TO_MOD_1_THRESHOLD',0xffffffff)')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_gcd_1)
+ push {r4, r7, lr}
+ ldr r3, [up] C U low limb
+
+ orr r3, r3, v0
+ rbit r4, r3
+ clz r4, r4 C min(ctz(u0),ctz(v0))
+
+ rbit r12, v0
+ clz r12, r12
+ mov v0, v0, lsr r12
+
+ mov r7, v0
+
+ cmp n, #1
+ bne L(nby1)
+
+C Both U and V are single limbs, reduce with bmod if u0 >> v0.
+ ldr r3, [up]
+ cmp v0, r3, lsr #BMOD_THRES_LOG2
+ bhi L(red1)
+
+L(bmod):mov r3, #0 C carry argument
+ bl mpn_modexact_1c_odd
+ b L(red0)
+
+L(nby1):cmp n, #BMOD_1_TO_MOD_1_THRESHOLD
+ blo L(bmod)
+
+ bl mpn_mod_1
+
+L(red0):mov r3, r0
+L(red1):cmp r3, #0
+ rbit r12, r3
+ clz r12, r12
+ bne L(mid)
+ b L(end)
+
+ ALIGN(8)
+L(top): movcs r3, r1 C if x-y < 0
+ movcs r7, r0 C use x,y-x
+L(mid): mov r3, r3, lsr r12 C
+ mov r0, r3 C
+ subs r1, r7, r3 C
+ rsb r3, r7, r3 C
+ rbit r12, r1
+ clz r12, r12 C
+ bne L(top) C
+
+L(end): mov r0, r7, lsl r4
+ pop {r4, r7, pc}
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/addmul_1.asm b/gmp/mpn/arm/v7a/cora15/addmul_1.asm
new file mode 100644
index 0000000000..c2277b32b2
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/addmul_1.asm
@@ -0,0 +1,145 @@
+dnl ARM mpn_addmul_1 optimised for A15.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C StrongARM: -
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 6 3.25
+C Cortex-A15 2 this
+
+C This code uses umlal for adding in the rp[] data, keeping the recurrency path
+C separate from any multiply instructions. It performs well on A15, at umlal's
+C bandwidth.
+C
+C An A9 variant should perhaps stick to 3-way unrolling, and use ldm and stm
+C for all loads and stores. Alternatively, it could do 2-way or 4-way, but
+C then alignment aware code will be necessary (adding O(1) bookkeeping
+C overhead).
+C
+C We don't use r12 due to ldrd and strd limitations.
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te ldrd strd
+C v6 -
+C v6t2 -
+C v7a -
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`v0', `r3')
+
+define(`w0', `r10') define(`w1', `r11')
+define(`u0', `r8') define(`u1', `r9')
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ push { r4-r11 }
+
+ ands r6, n, #3
+ sub n, n, #3
+ beq L(b00)
+ cmp r6, #2
+ bcc L(b01)
+ beq L(b10)
+
+L(b11): mov r6, #0
+ cmn r13, #0 C carry clear
+ ldr u1, [up], #-4
+ ldr w1, [rp], #-4
+ mov r7, #0
+ b L(mid)
+
+L(b00): ldrd u0, u1, [up]
+ ldrd w0, w1, [rp]
+ mov r6, #0
+ umlal w0, r6, u0, v0
+ cmn r13, #0 C carry clear
+ mov r7, #0
+ str w0, [rp]
+ b L(mid)
+
+L(b10): ldrd u0, u1, [up], #8
+ ldrd w0, w1, [rp]
+ mov r4, #0
+ umlal w0, r4, u0, v0
+ cmn r13, #0 C carry clear
+ mov r5, #0
+ str w0, [rp], #8
+ umlal w1, r5, u1, v0
+ tst n, n
+ bmi L(end)
+ b L(top)
+
+L(b01): mov r4, #0
+ ldr u1, [up], #4
+ ldr w1, [rp], #4
+ mov r5, #0
+ umlal w1, r5, u1, v0
+ tst n, n
+ bmi L(end)
+
+ ALIGN(16)
+L(top): ldrd u0, u1, [up, #0]
+ adcs r4, r4, w1
+ ldrd w0, w1, [rp, #0]
+ mov r6, #0
+ umlal w0, r6, u0, v0 C 1 2
+ adcs r5, r5, w0
+ mov r7, #0
+ strd r4, r5, [rp, #-4]
+L(mid): umlal w1, r7, u1, v0 C 2 3
+ ldrd u0, u1, [up, #8]
+ adcs r6, r6, w1
+ ldrd w0, w1, [rp, #8]
+ mov r4, #0
+ umlal w0, r4, u0, v0 C 3 4
+ adcs r7, r7, w0
+ mov r5, #0
+ strd r6, r7, [rp, #4]
+ umlal w1, r5, u1, v0 C 0 1
+ sub n, n, #4
+ add up, up, #16
+ add rp, rp, #16
+ tst n, n
+ bpl L(top)
+
+L(end): adcs r4, r4, w1
+ str r4, [rp, #-4]
+ adc r0, r5, #0
+ pop { r4-r11 }
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/aors_n.asm b/gmp/mpn/arm/v7a/cora15/aors_n.asm
new file mode 100644
index 0000000000..dc3f83992e
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/aors_n.asm
@@ -0,0 +1,162 @@
+dnl ARM mpn_add_n/mpn_sub_n optimised for A15.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C StrongARM: -
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 3.55 2.5
+C Cortex-A15 1.27 this
+
+C This was a major improvement compared to the code we had before, but it might
+C not be the best 8-way code possible. We've tried some permutations of auto-
+C increments and separate pointer updates, but they all ran at the same speed
+C on A15.
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te ldrd strd
+C v6 -
+C v6t2 -
+C v7a -
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`vp', `r2')
+define(`n', `r3')
+
+ifdef(`OPERATION_add_n', `
+ define(`ADDSUBC', adcs)
+ define(`IFADD', `$1')
+ define(`SETCY', `cmp $1, #1')
+ define(`RETVAL', `adc r0, n, #0')
+ define(`RETVAL2', `adc r0, n, #1')
+ define(`func', mpn_add_n)
+ define(`func_nc', mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(`ADDSUBC', sbcs)
+ define(`IFADD', `')
+ define(`SETCY', `rsbs $1, $1, #0')
+ define(`RETVAL', `sbc r0, r0, r0
+ and r0, r0, #1')
+ define(`RETVAL2', `RETVAL')
+ define(`func', mpn_sub_n)
+ define(`func_nc', mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+PROLOGUE(func_nc)
+ ldr r12, [sp]
+ b L(ent)
+EPILOGUE()
+PROLOGUE(func)
+ mov r12, #0
+L(ent): push { r4-r9 }
+
+ ands r6, n, #3
+ mov n, n, lsr #2
+ beq L(b00)
+ cmp r6, #2
+ bcc L(b01)
+ beq L(b10)
+
+L(b11): ldr r5, [up], #4
+ ldr r7, [vp], #4
+ SETCY( r12)
+ ADDSUBC r9, r5, r7
+ ldrd r4, r5, [up, #0]
+ ldrd r6, r7, [vp, #0]
+ str r9, [rp], #-4
+ b L(lo)
+
+L(b00): ldrd r4, r5, [up], #-8
+ ldrd r6, r7, [vp], #-8
+ SETCY( r12)
+ sub rp, rp, #16
+ b L(mid)
+
+L(b01): ldr r5, [up], #-4
+ ldr r7, [vp], #-4
+ SETCY( r12)
+ ADDSUBC r9, r5, r7
+ str r9, [rp], #-12
+ tst n, n
+ beq L(wd1)
+L(gt1): ldrd r4, r5, [up, #8]
+ ldrd r6, r7, [vp, #8]
+ b L(mid)
+
+L(b10): ldrd r4, r5, [up]
+ ldrd r6, r7, [vp]
+ SETCY( r12)
+ sub rp, rp, #8
+ b L(lo)
+
+ ALIGN(16)
+L(top): ldrd r4, r5, [up, #8]
+ ldrd r6, r7, [vp, #8]
+ strd r8, r9, [rp, #8]
+L(mid): ADDSUBC r8, r4, r6
+ ADDSUBC r9, r5, r7
+ ldrd r4, r5, [up, #16]
+ ldrd r6, r7, [vp, #16]
+ strd r8, r9, [rp, #16]
+ ADDSUBC r8, r4, r6
+ ADDSUBC r9, r5, r7
+ sub n, n, #2
+ tst n, n
+ bmi L(dne)
+ ldrd r4, r5, [up, #24]
+ ldrd r6, r7, [vp, #24]
+ strd r8, r9, [rp, #24]
+ ADDSUBC r8, r4, r6
+ ADDSUBC r9, r5, r7
+ ldrd r4, r5, [up, #32]!
+ ldrd r6, r7, [vp, #32]!
+ strd r8, r9, [rp, #32]!
+L(lo): ADDSUBC r8, r4, r6
+ ADDSUBC r9, r5, r7
+ tst n, n
+ bne L(top)
+
+L(end): strd r8, r9, [rp, #8]
+L(wd1): RETVAL
+ pop { r4-r9 }
+ bx r14
+L(dne): strd r8, r9, [rp, #24]
+ RETVAL2
+ pop { r4-r9 }
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/cnd_aors_n.asm b/gmp/mpn/arm/v7a/cora15/cnd_aors_n.asm
new file mode 100644
index 0000000000..b9e5cd3f79
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/cnd_aors_n.asm
@@ -0,0 +1,158 @@
+dnl ARM mpn_cnd_add_n/mpn_cnd_sub_n optimised for A15.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C StrongARM: -
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 3.75 3
+C Cortex-A15 1.78 this
+
+C This code does not run as well as one could have hoped, since 1.5 c/l seems
+C realistic for this insn mix.
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te ldrd strd
+C v6 -
+C v6t2 -
+C v7a -
+
+define(`cnd',`r0')
+define(`rp', `r1')
+define(`up', `r2')
+define(`vp', `r3')
+define(`n', `r12')
+
+ifdef(`OPERATION_cnd_add_n', `
+ define(`ADDSUB', adds)
+ define(`ADDSUBC', adcs)
+ define(`IFADD', `$1')
+ define(`INITCY', `cmn r0, #0')
+ define(`RETVAL', `adc r0, n, #0')
+ define(`RETVAL2', `adc r0, n, #1')
+ define(`func', mpn_cnd_add_n)
+ define(`func_nc', mpn_add_nc)')
+ifdef(`OPERATION_cnd_sub_n', `
+ define(`ADDSUB', subs)
+ define(`ADDSUBC', sbcs)
+ define(`IFADD', `')
+ define(`INITCY', `cmp r0, #0')
+ define(`RETVAL', `sbc r0, r0, r0
+ and r0, r0, #1')
+ define(`RETVAL2', `RETVAL')
+ define(`func', mpn_cnd_sub_n)
+ define(`func_nc', mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_cnd_add_n mpn_cnd_sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ ldr n, [sp]
+ push { r4-r9 }
+
+ cmp cnd, #1
+ sbc cnd, cnd, cnd C conditionally set to 0xffffffff
+
+ ands r6, n, #3
+ mov n, n, lsr #2
+ beq L(b00)
+ cmp r6, #2
+ bcc L(b01)
+ beq L(b10)
+
+L(b11): ldr r5, [up], #4
+ ldr r7, [vp], #4
+ bic r7, r7, cnd
+ ADDSUB r9, r5, r7
+ ldrd r4, r5, [up, #0]
+ ldrd r6, r7, [vp, #0]
+ bic r6, r6, cnd
+ bic r7, r7, cnd
+ str r9, [rp], #-4
+ b L(lo)
+
+L(b00): ldrd r4, r5, [up], #-8
+ ldrd r6, r7, [vp], #-8
+ bic r6, r6, cnd
+ bic r7, r7, cnd
+ INITCY
+ sub rp, rp, #16
+ b L(mid)
+
+L(b01): ldr r5, [up], #-4
+ ldr r7, [vp], #-4
+ bic r7, r7, cnd
+ ADDSUB r9, r5, r7
+ str r9, [rp], #-12
+ tst n, n
+ beq L(wd1)
+L(gt1): ldrd r4, r5, [up, #8]
+ ldrd r6, r7, [vp, #8]
+ bic r6, r6, cnd
+ bic r7, r7, cnd
+ b L(mid)
+
+L(b10): ldrd r4, r5, [up]
+ ldrd r6, r7, [vp]
+ bic r6, r6, cnd
+ bic r7, r7, cnd
+ INITCY
+ sub rp, rp, #8
+ b L(lo)
+
+ ALIGN(16)
+L(top): ldrd r6, r7, [vp, #8]
+ ldrd r4, r5, [up, #8]
+ bic r6, r6, cnd
+ bic r7, r7, cnd
+ strd r8, r9, [rp, #8]
+L(mid): ADDSUBC r8, r4, r6
+ ADDSUBC r9, r5, r7
+ ldrd r6, r7, [vp, #16]!
+ ldrd r4, r5, [up, #16]!
+ bic r6, r6, cnd
+ bic r7, r7, cnd
+ sub n, n, #1
+ strd r8, r9, [rp, #16]!
+L(lo): ADDSUBC r8, r4, r6
+ ADDSUBC r9, r5, r7
+ tst n, n
+ bne L(top)
+
+L(end): strd r8, r9, [rp, #8]
+L(wd1): RETVAL
+ pop { r4-r9 }
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/com.asm b/gmp/mpn/arm/v7a/cora15/com.asm
new file mode 100644
index 0000000000..a258afe934
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/com.asm
@@ -0,0 +1,180 @@
+dnl ARM mpn_com optimised for A15.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 2.5
+C Cortex-A15 1.0
+
+C This is great A15 core register code, but it is a bit large.
+C We use FEEDIN_VARIANT 1 to save some space, but use 8-way unrolling.
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te ldrd strd
+C v6 -
+C v6t2 -
+C v7a -
+
+define(`FEEDIN_VARIANT', 1) C alternatives: 0 1 2
+define(`UNROLL', 4x2) C alternatives: 4 4x2
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+
+ASM_START()
+PROLOGUE(mpn_com)
+ push { r4-r5,r8-r9 }
+
+ifelse(FEEDIN_VARIANT,0,`
+ ands r12, n, #3
+ mov n, n, lsr #2
+ beq L(b00a)
+ tst r12, #1
+ beq L(bx0)
+ ldr r5, [up], #4
+ mvn r9, r5
+ str r9, [rp], #4
+ tst r12, #2
+ beq L(b00)
+L(bx0): ldrd r4, r5, [up, #0]
+ sub rp, rp, #8
+ b L(lo)
+L(b00): tst n, n
+ beq L(wd1)
+L(b00a):ldrd r4, r5, [up], #-8
+ sub rp, rp, #16
+ b L(mid)
+')
+ifelse(FEEDIN_VARIANT,1,`
+ and r12, n, #3
+ mov n, n, lsr #2
+ tst r12, #1
+ beq L(bx0)
+ ldr r5, [up], #4
+ mvn r9, r5
+ str r9, [rp], #4
+L(bx0): tst r12, #2
+ beq L(b00)
+ ldrd r4, r5, [up, #0]
+ sub rp, rp, #8
+ b L(lo)
+L(b00): tst n, n
+ beq L(wd1)
+ ldrd r4, r5, [up], #-8
+ sub rp, rp, #16
+ b L(mid)
+')
+ifelse(FEEDIN_VARIANT,2,`
+ ands r12, n, #3
+ mov n, n, lsr #2
+ beq L(b00)
+ cmp r12, #2
+ bcc L(b01)
+ beq L(b10)
+
+L(b11): ldr r5, [up], #4
+ mvn r9, r5
+ ldrd r4, r5, [up, #0]
+ str r9, [rp], #-4
+ b L(lo)
+
+L(b00): ldrd r4, r5, [up], #-8
+ sub rp, rp, #16
+ b L(mid)
+
+L(b01): ldr r5, [up], #-4
+ mvn r9, r5
+ str r9, [rp], #-12
+ tst n, n
+ beq L(wd1)
+L(gt1): ldrd r4, r5, [up, #8]
+ b L(mid)
+
+L(b10): ldrd r4, r5, [up]
+ sub rp, rp, #8
+ b L(lo)
+')
+ ALIGN(16)
+ifelse(UNROLL,4,`
+L(top): ldrd r4, r5, [up, #8]
+ strd r8, r9, [rp, #8]
+L(mid): mvn r8, r4
+ mvn r9, r5
+ ldrd r4, r5, [up, #16]!
+ strd r8, r9, [rp, #16]!
+ sub n, n, #1
+L(lo): mvn r8, r4
+ mvn r9, r5
+ tst n, n
+ bne L(top)
+')
+ifelse(UNROLL,4x2,`
+L(top): ldrd r4, r5, [up, #8]
+ strd r8, r9, [rp, #8]
+L(mid): mvn r8, r4
+ mvn r9, r5
+ ldrd r4, r5, [up, #16]
+ strd r8, r9, [rp, #16]
+ mvn r8, r4
+ mvn r9, r5
+ sub n, n, #2
+ tst n, n
+ bmi L(dne)
+ ldrd r4, r5, [up, #24]
+ strd r8, r9, [rp, #24]
+ mvn r8, r4
+ mvn r9, r5
+ ldrd r4, r5, [up, #32]!
+ strd r8, r9, [rp, #32]!
+L(lo): mvn r8, r4
+ mvn r9, r5
+ tst n, n
+ bne L(top)
+')
+
+L(end): strd r8, r9, [rp, #8]
+L(wd1): pop { r4-r5,r8-r9 }
+ bx r14
+ifelse(UNROLL,4x2,`
+L(dne): strd r8, r9, [rp, #24]
+ pop { r4-r5,r8-r9 }
+ bx r14
+')
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/gmp-mparam.h b/gmp/mpn/arm/v7a/cora15/gmp-mparam.h
new file mode 100644
index 0000000000..2a06532b3e
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/gmp-mparam.h
@@ -0,0 +1,197 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2003, 2009, 2010, 2012-2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 1700MHz Cortex-A15 with Neon (in spite of file position) */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.6 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 9
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD MP_SIZE_T_MAX
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 8
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 15
+
+#define MUL_TOOM22_THRESHOLD 23
+#define MUL_TOOM33_THRESHOLD 90
+#define MUL_TOOM44_THRESHOLD 262
+#define MUL_TOOM6H_THRESHOLD 351
+#define MUL_TOOM8H_THRESHOLD 557
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 90
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 160
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 89
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 169
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 130
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 43
+#define SQR_TOOM3_THRESHOLD 138
+#define SQR_TOOM4_THRESHOLD 363
+#define SQR_TOOM6_THRESHOLD 517
+#define SQR_TOOM8_THRESHOLD 725
+
+#define MULMID_TOOM42_THRESHOLD 52
+
+#define MULMOD_BNM1_THRESHOLD 17
+#define SQRMOD_BNM1_THRESHOLD 23
+
+#define MUL_FFT_MODF_THRESHOLD 550 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 550, 5}, { 25, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 19, 6}, { 39, 7}, { 25, 6}, \
+ { 51, 7}, { 27, 8}, { 15, 7}, { 33, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 51, 8}, \
+ { 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
+ { 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
+ { 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
+ { 47, 8}, { 99, 9}, { 55,10}, { 31, 9}, \
+ { 79,10}, { 47, 9}, { 103,11}, { 31,10}, \
+ { 63, 9}, { 135,10}, { 79, 9}, { 159,10}, \
+ { 95, 9}, { 191,10}, { 111,11}, { 63,10}, \
+ { 159,11}, { 95,10}, { 191, 9}, { 383,10}, \
+ { 207,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,11}, { 159,10}, \
+ { 319, 9}, { 639,10}, { 335, 9}, { 671,10}, \
+ { 351,11}, { 191,10}, { 383, 9}, { 767,10}, \
+ { 399, 9}, { 799,10}, { 415,11}, { 223,12}, \
+ { 127,11}, { 255,10}, { 543,11}, { 287,10}, \
+ { 607,11}, { 319,10}, { 671,11}, { 351,12}, \
+ { 191,11}, { 383,10}, { 799,11}, { 415,10}, \
+ { 831,13}, { 127,12}, { 255,11}, { 543,10}, \
+ { 1087,11}, { 607,12}, { 319,11}, { 671,10}, \
+ { 1343,11}, { 735,12}, { 383,11}, { 799,10}, \
+ { 1599,11}, { 831,12}, { 447,11}, { 895,13}, \
+ { 255,12}, { 511,11}, { 1023,12}, { 575,11}, \
+ { 1151,12}, { 639,11}, { 1279,12}, { 703,13}, \
+ { 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
+ { 1663,12}, { 895,13}, { 511,12}, { 1087,13}, \
+ { 639,12}, { 1407,13}, { 767,12}, { 1599,13}, \
+ { 895,14}, { 511,13}, { 1023,12}, { 2111,13}, \
+ { 1151,12}, { 2431,13}, { 1279,14}, { 767,13}, \
+ { 1535,12}, { 3071,15}, { 511,14}, { 1023,13}, \
+ { 2175,14}, { 1279,13}, { 2559,12}, { 5119,13}, \
+ { 2815,12}, { 5631,13}, { 2943,14}, { 16384,15}, \
+ { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 137
+#define MUL_FFT_THRESHOLD 5760
+
+#define SQR_FFT_MODF_THRESHOLD 525 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 525, 5}, { 25, 6}, { 27, 7}, { 15, 6}, \
+ { 32, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
+ { 39, 7}, { 25, 6}, { 51, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 51, 8}, { 27, 7}, { 55, 9}, \
+ { 15, 8}, { 31, 7}, { 63, 8}, { 39, 9}, \
+ { 23, 8}, { 55,10}, { 15, 9}, { 31, 8}, \
+ { 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
+ { 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
+ { 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
+ { 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
+ { 191,10}, { 111,11}, { 63,10}, { 143, 9}, \
+ { 287,10}, { 159,11}, { 95,10}, { 191, 9}, \
+ { 383,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,10}, { 287,11}, \
+ { 159,10}, { 335, 9}, { 671,10}, { 351,11}, \
+ { 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
+ { 799,10}, { 415,11}, { 223,12}, { 127,11}, \
+ { 255,10}, { 543,11}, { 287,10}, { 607,11}, \
+ { 319,10}, { 671,11}, { 351,12}, { 191,11}, \
+ { 383,10}, { 799,11}, { 415,10}, { 831,13}, \
+ { 127,12}, { 255,11}, { 543,10}, { 1087,11}, \
+ { 607,12}, { 319,11}, { 671,10}, { 1343,11}, \
+ { 735,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 831,12}, { 447,11}, { 895,12}, { 511,11}, \
+ { 1023,12}, { 575,11}, { 1151,12}, { 639,11}, \
+ { 1343,12}, { 703,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1663,12}, { 895,13}, \
+ { 511,12}, { 1087,13}, { 639,12}, { 1407,13}, \
+ { 767,12}, { 1727,13}, { 895,14}, { 511,13}, \
+ { 1023,12}, { 2047,13}, { 1151,12}, { 2431,13}, \
+ { 1279,14}, { 767,13}, { 1535,12}, { 3071,15}, \
+ { 511,14}, { 1023,13}, { 2047,12}, { 4095,13}, \
+ { 2175,14}, { 1279,13}, { 2559,12}, { 5119,13}, \
+ { 2687,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 139
+#define SQR_FFT_THRESHOLD 4736
+
+#define MULLO_BASECASE_THRESHOLD 9
+#define MULLO_DC_THRESHOLD 39
+#define MULLO_MUL_N_THRESHOLD 11278
+
+#define DC_DIV_QR_THRESHOLD 54
+#define DC_DIVAPPR_Q_THRESHOLD 296
+#define DC_BDIV_QR_THRESHOLD 52
+#define DC_BDIV_Q_THRESHOLD 300
+
+#define INV_MULMOD_BNM1_THRESHOLD 44
+#define INV_NEWTON_THRESHOLD 294
+#define INV_APPR_THRESHOLD 294
+
+#define BINV_NEWTON_THRESHOLD 375
+#define REDC_1_TO_REDC_2_THRESHOLD 102
+#define REDC_2_TO_REDC_N_THRESHOLD 0 /* always */
+
+#define MU_DIV_QR_THRESHOLD 1718
+#define MU_DIVAPPR_Q_THRESHOLD 1718
+#define MUPI_DIV_QR_THRESHOLD 108
+#define MU_BDIV_QR_THRESHOLD 1528
+#define MU_BDIV_Q_THRESHOLD 1718
+
+#define POWM_SEC_TABLE 3,32,70,416,1464
+
+#define MATRIX22_STRASSEN_THRESHOLD 22
+#define HGCD_THRESHOLD 152
+#define HGCD_APPR_THRESHOLD 230
+#define HGCD_REDUCE_THRESHOLD 3259
+#define GCD_DC_THRESHOLD 702
+#define GCDEXT_DC_THRESHOLD 538
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 18
+#define GET_STR_PRECOMPUTE_THRESHOLD 32
+#define SET_STR_DC_THRESHOLD 119
+#define SET_STR_PRECOMPUTE_THRESHOLD 1063
+
+#define FAC_DSC_THRESHOLD 262
+#define FAC_ODD_THRESHOLD 26
diff --git a/gmp/mpn/arm/v7a/cora15/logops_n.asm b/gmp/mpn/arm/v7a/cora15/logops_n.asm
new file mode 100644
index 0000000000..06026143e1
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/logops_n.asm
@@ -0,0 +1,253 @@
+dnl ARM mpn_and_n, mpn_andn_n. mpn_nand_n, etc, optimised for A15.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb
+C and andn ior xor nand iorn nior xnor
+C StrongARM ? ?
+C XScale ? ?
+C Cortex-A7 ? ?
+C Cortex-A8 ? ?
+C Cortex-A9 3.5 3.56
+C Cortex-A15 1.27 1.64
+
+C This is great A15 core register code, but it is a bit large.
+C We use FEEDIN_VARIANT 1 to save some space, but use 8-way unrolling.
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te ldrd strd
+C v6 -
+C v6t2 -
+C v7a -
+
+define(`FEEDIN_VARIANT', 1) C alternatives: 0 1 2
+define(`UNROLL', 4x2) C alternatives: 4 4x2
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`vp', `r2')
+define(`n', `r3')
+
+define(`POSTOP')
+
+ifdef(`OPERATION_and_n',`
+ define(`func', `mpn_and_n')
+ define(`LOGOP', `and $1, $2, $3')')
+ifdef(`OPERATION_andn_n',`
+ define(`func', `mpn_andn_n')
+ define(`LOGOP', `bic $1, $2, $3')')
+ifdef(`OPERATION_nand_n',`
+ define(`func', `mpn_nand_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `and $1, $2, $3')')
+ifdef(`OPERATION_ior_n',`
+ define(`func', `mpn_ior_n')
+ define(`LOGOP', `orr $1, $2, $3')')
+ifdef(`OPERATION_iorn_n',`
+ define(`func', `mpn_iorn_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `bic $1, $3, $2')')
+ifdef(`OPERATION_nior_n',`
+ define(`func', `mpn_nior_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `orr $1, $2, $3')')
+ifdef(`OPERATION_xor_n',`
+ define(`func', `mpn_xor_n')
+ define(`LOGOP', `eor $1, $2, $3')')
+ifdef(`OPERATION_xnor_n',`
+ define(`func', `mpn_xnor_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `eor $1, $2, $3')')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+ASM_START()
+PROLOGUE(func)
+ push { r4-r9 }
+
+ifelse(FEEDIN_VARIANT,0,`
+ ands r6, n, #3
+ mov n, n, lsr #2
+ beq L(b00a)
+ tst r6, #1
+ beq L(bx0)
+ ldr r5, [up], #4
+ ldr r7, [vp], #4
+ LOGOP( r9, r5, r7)
+ POSTOP( r9)
+ str r9, [rp], #4
+ tst r6, #2
+ beq L(b00)
+L(bx0): ldrd r4, r5, [up, #0]
+ ldrd r6, r7, [vp, #0]
+ sub rp, rp, #8
+ b L(lo)
+L(b00): tst n, n
+ beq L(wd1)
+L(b00a):ldrd r4, r5, [up], #-8
+ ldrd r6, r7, [vp], #-8
+ sub rp, rp, #16
+ b L(mid)
+')
+ifelse(FEEDIN_VARIANT,1,`
+ and r6, n, #3
+ mov n, n, lsr #2
+ tst r6, #1
+ beq L(bx0)
+ ldr r5, [up], #4
+ ldr r7, [vp], #4
+ LOGOP( r9, r5, r7)
+ POSTOP( r9)
+ str r9, [rp], #4
+L(bx0): tst r6, #2
+ beq L(b00)
+ ldrd r4, r5, [up, #0]
+ ldrd r6, r7, [vp, #0]
+ sub rp, rp, #8
+ b L(lo)
+L(b00): tst n, n
+ beq L(wd1)
+ ldrd r4, r5, [up], #-8
+ ldrd r6, r7, [vp], #-8
+ sub rp, rp, #16
+ b L(mid)
+')
+ifelse(FEEDIN_VARIANT,2,`
+ ands r6, n, #3
+ mov n, n, lsr #2
+ beq L(b00)
+ cmp r6, #2
+ bcc L(b01)
+ beq L(b10)
+
+L(b11): ldr r5, [up], #4
+ ldr r7, [vp], #4
+ LOGOP( r9, r5, r7)
+ ldrd r4, r5, [up, #0]
+ ldrd r6, r7, [vp, #0]
+ POSTOP( r9)
+ str r9, [rp], #-4
+ b L(lo)
+
+L(b00): ldrd r4, r5, [up], #-8
+ ldrd r6, r7, [vp], #-8
+ sub rp, rp, #16
+ b L(mid)
+
+L(b01): ldr r5, [up], #-4
+ ldr r7, [vp], #-4
+ LOGOP( r9, r5, r7)
+ POSTOP( r9)
+ str r9, [rp], #-12
+ tst n, n
+ beq L(wd1)
+L(gt1): ldrd r4, r5, [up, #8]
+ ldrd r6, r7, [vp, #8]
+ b L(mid)
+
+L(b10): ldrd r4, r5, [up]
+ ldrd r6, r7, [vp]
+ sub rp, rp, #8
+ b L(lo)
+')
+ ALIGN(16)
+ifelse(UNROLL,4,`
+L(top): ldrd r4, r5, [up, #8]
+ ldrd r6, r7, [vp, #8]
+ POSTOP( r8)
+ POSTOP( r9)
+ strd r8, r9, [rp, #8]
+L(mid): LOGOP( r8, r4, r6)
+ LOGOP( r9, r5, r7)
+ ldrd r4, r5, [up, #16]!
+ ldrd r6, r7, [vp, #16]!
+ POSTOP( r8)
+ POSTOP( r9)
+ strd r8, r9, [rp, #16]!
+ sub n, n, #1
+L(lo): LOGOP( r8, r4, r6)
+ LOGOP( r9, r5, r7)
+ tst n, n
+ bne L(top)
+')
+ifelse(UNROLL,4x2,`
+L(top): ldrd r4, r5, [up, #8]
+ ldrd r6, r7, [vp, #8]
+ POSTOP( r8)
+ POSTOP( r9)
+ strd r8, r9, [rp, #8]
+L(mid): LOGOP( r8, r4, r6)
+ LOGOP( r9, r5, r7)
+ ldrd r4, r5, [up, #16]
+ ldrd r6, r7, [vp, #16]
+ POSTOP( r8)
+ POSTOP( r9)
+ strd r8, r9, [rp, #16]
+ LOGOP( r8, r4, r6)
+ LOGOP( r9, r5, r7)
+ sub n, n, #2
+ tst n, n
+ bmi L(dne)
+ ldrd r4, r5, [up, #24]
+ ldrd r6, r7, [vp, #24]
+ POSTOP( r8)
+ POSTOP( r9)
+ strd r8, r9, [rp, #24]
+ LOGOP( r8, r4, r6)
+ LOGOP( r9, r5, r7)
+ ldrd r4, r5, [up, #32]!
+ ldrd r6, r7, [vp, #32]!
+ POSTOP( r8)
+ POSTOP( r9)
+ strd r8, r9, [rp, #32]!
+L(lo): LOGOP( r8, r4, r6)
+ LOGOP( r9, r5, r7)
+ tst n, n
+ bne L(top)
+')
+
+L(end): POSTOP( r8)
+ POSTOP( r9)
+ strd r8, r9, [rp, #8]
+L(wd1): pop { r4-r9 }
+ bx r14
+ifelse(UNROLL,4x2,`
+L(dne): POSTOP( r8)
+ POSTOP( r9)
+ strd r8, r9, [rp, #24]
+ pop { r4-r9 }
+ bx r14
+')
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/mul_1.asm b/gmp/mpn/arm/v7a/cora15/mul_1.asm
new file mode 100644
index 0000000000..766ba5c57f
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/mul_1.asm
@@ -0,0 +1,104 @@
+dnl ARM mpn_mul_1 optimised for A15.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C StrongARM: -
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 5.25 3.25
+C Cortex-A15 2.25 this
+
+
+C This runs well on A15 but very poorly on A9. By scheduling loads and adds
+C it is possible to get good A9 performance as well, but at the cost of using
+C many more (callee-saves) registers.
+
+C This is armv5 code, optimized for the armv7a cpu A15. Its location in the
+C GMP file structure might be misleading.
+
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`v0', `r3')
+
+ASM_START()
+PROLOGUE(mpn_mul_1c)
+ ldr r12, [sp]
+ b L(ent)
+EPILOGUE()
+PROLOGUE(mpn_mul_1)
+ mov r12, #0
+L(ent): push {r4-r7}
+
+ ldr r6, [up], #4
+ tst n, #1
+ beq L(bx0)
+
+L(bx1): umull r4, r7, r6, v0
+ adds r4, r4, r12
+ tst n, #2
+ beq L(lo1)
+ b L(lo3)
+
+L(bx0): umull r4, r5, r6, v0
+ adds r4, r4, r12
+ tst n, #2
+ beq L(lo0)
+ b L(lo2)
+
+L(top): ldr r6, [up], #4
+ str r4, [rp], #4
+ umull r4, r5, r6, v0
+ adds r4, r4, r7
+L(lo0): ldr r6, [up], #4
+ str r4, [rp], #4
+ umull r4, r7, r6, v0
+ adcs r4, r4, r5
+L(lo3): ldr r6, [up], #4
+ str r4, [rp], #4
+ umull r4, r5, r6, v0
+ adcs r4, r4, r7
+L(lo2): ldr r6, [up], #4
+ str r4, [rp], #4
+ umull r4, r7, r6, v0
+ adcs r4, r4, r5
+L(lo1): adc r7, r7, #0
+ subs n, n, #4
+ bgt L(top)
+
+ str r4, [rp]
+ mov r0, r7
+ pop {r4-r7}
+ bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/neon/aorsorrlsh1_n.asm b/gmp/mpn/arm/v7a/cora15/neon/aorsorrlsh1_n.asm
new file mode 100644
index 0000000000..d8cfe3f78f
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/neon/aorsorrlsh1_n.asm
@@ -0,0 +1,43 @@
+dnl ARM mpn_addlshC_n, mpn_sublshC_n, mpn_rsblshC_n
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 1)
+
+ifdef(`OPERATION_addlsh1_n',`define(`DO_add')')
+ifdef(`OPERATION_sublsh1_n',`define(`DO_sub')')
+ifdef(`OPERATION_rsblsh1_n',`define(`DO_rsb')')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n mpn_rsblsh1_n)
+
+include_mpn(`arm/v7a/cora15/neon/aorsorrlshC_n.asm')
diff --git a/gmp/mpn/arm/v7a/cora15/neon/aorsorrlsh2_n.asm b/gmp/mpn/arm/v7a/cora15/neon/aorsorrlsh2_n.asm
new file mode 100644
index 0000000000..b48204d926
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/neon/aorsorrlsh2_n.asm
@@ -0,0 +1,43 @@
+dnl ARM mpn_addlshC_n, mpn_sublshC_n, mpn_rsblshC_n
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 2)
+
+ifdef(`OPERATION_addlsh2_n',`define(`DO_add')')
+ifdef(`OPERATION_sublsh2_n',`define(`DO_sub')')
+ifdef(`OPERATION_rsblsh2_n',`define(`DO_rsb')')
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_sublsh2_n mpn_rsblsh2_n)
+
+include_mpn(`arm/v7a/cora15/neon/aorsorrlshC_n.asm')
diff --git a/gmp/mpn/arm/v7a/cora15/neon/aorsorrlshC_n.asm b/gmp/mpn/arm/v7a/cora15/neon/aorsorrlshC_n.asm
new file mode 100644
index 0000000000..16c34a2699
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/neon/aorsorrlshC_n.asm
@@ -0,0 +1,144 @@
+dnl ARM mpn_addlshC_n, mpn_sublshC_n, mpn_rsblshC_n
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+C cycles/limb
+C StrongARM -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 5.25
+C Cortex-A15 2.25
+
+C TODO
+C * Consider using 4-way feed-in code.
+C * This is ad-hoc scheduled, perhaps unnecessarily so for A15, and perhaps
+C insufficiently for A7 and A8.
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`vp', `r2')
+define(`n', `r3')
+
+ifdef(`DO_add', `
+ define(`ADCSBCS', `adcs $1, $2, $3')
+ define(`CLRCY', `cmn r13, #1')
+ define(`RETVAL', `adc r0, $1, #0')
+ define(`func', mpn_addlsh`'LSH`'_n)')
+ifdef(`DO_sub', `
+ define(`ADCSBCS', `sbcs $1, $2, $3')
+ define(`CLRCY', `cmp r13, #0')
+ define(`RETVAL', `sbc $2, $2, $2
+ cmn $2, #1
+ adc r0, $1, #0')
+ define(`func', mpn_sublsh`'LSH`'_n)')
+ifdef(`DO_rsb', `
+ define(`ADCSBCS', `sbcs $1, $3, $2')
+ define(`CLRCY', `cmp r13, #0')
+ define(`RETVAL', `sbc r0, $1, #0')
+ define(`func', mpn_rsblsh`'LSH`'_n)')
+
+
+ASM_START()
+PROLOGUE(func)
+ push {r4-r10}
+ vmov.i8 d0, #0 C could feed carry through here
+ CLRCY
+ tst n, #1
+ beq L(bb0)
+
+L(bb1): vld1.32 {d3[0]}, [vp]!
+ vsli.u32 d0, d3, #LSH
+ ldr r12, [up], #4
+ vmov.32 r5, d0[0]
+ vshr.u32 d0, d3, #32-LSH
+ ADCSBCS( r12, r12, r5)
+ str r12, [rp], #4
+ bics n, n, #1
+ beq L(rtn)
+
+L(bb0): tst n, #2
+ beq L(b00)
+
+L(b10): vld1.32 {d3}, [vp]!
+ vsli.u64 d0, d3, #LSH
+ ldmia up!, {r10,r12}
+ vmov r4, r5, d0
+ vshr.u64 d0, d3, #64-LSH
+ ADCSBCS( r10, r10, r4)
+ ADCSBCS( r12, r12, r5)
+ stmia rp!, {r10,r12}
+ bics n, n, #2
+ beq L(rtn)
+
+L(b00): vld1.32 {d2}, [vp]!
+ vsli.u64 d0, d2, #LSH
+ vshr.u64 d1, d2, #64-LSH
+ vld1.32 {d3}, [vp]!
+ vsli.u64 d1, d3, #LSH
+ vmov r6, r7, d0
+ vshr.u64 d0, d3, #64-LSH
+ sub n, n, #4
+ tst n, n
+ beq L(end)
+
+ ALIGN(16)
+L(top): ldmia up!, {r8,r9,r10,r12}
+ vld1.32 {d2}, [vp]!
+ vsli.u64 d0, d2, #LSH
+ vmov r4, r5, d1
+ vshr.u64 d1, d2, #64-LSH
+ ADCSBCS( r8, r8, r6)
+ ADCSBCS( r9, r9, r7)
+ vld1.32 {d3}, [vp]!
+ vsli.u64 d1, d3, #LSH
+ vmov r6, r7, d0
+ vshr.u64 d0, d3, #64-LSH
+ ADCSBCS( r10, r10, r4)
+ ADCSBCS( r12, r12, r5)
+ stmia rp!, {r8,r9,r10,r12}
+ sub n, n, #4
+ tst n, n
+ bne L(top)
+
+L(end): ldmia up!, {r8,r9,r10,r12}
+ vmov r4, r5, d1
+ ADCSBCS( r8, r8, r6)
+ ADCSBCS( r9, r9, r7)
+ ADCSBCS( r10, r10, r4)
+ ADCSBCS( r12, r12, r5)
+ stmia rp!, {r8,r9,r10,r12}
+L(rtn): vmov.32 r0, d0[0]
+ RETVAL( r0, r1)
+ pop {r4-r10}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/neon/com.asm b/gmp/mpn/arm/v7a/cora15/neon/com.asm
new file mode 100644
index 0000000000..9e7a629287
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/neon/com.asm
@@ -0,0 +1,97 @@
+dnl ARM Neon mpn_com optimised for A15.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM ?
+C XScale ?
+C Cortex-A8 ?
+C Cortex-A9 2.1
+C Cortex-A15 0.65
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+
+ASM_START()
+PROLOGUE(mpn_com)
+ cmp n, #7
+ ble L(bc)
+
+C Perform a few initial operation until rp is 128-bit aligned
+ tst rp, #4
+ beq L(al1)
+ vld1.32 {d0[0]}, [up]!
+ sub n, n, #1
+ vmvn d0, d0
+ vst1.32 {d0[0]}, [rp]!
+L(al1): tst rp, #8
+ beq L(al2)
+ vld1.32 {d0}, [up]!
+ sub n, n, #2
+ vmvn d0, d0
+ vst1.32 {d0}, [rp:64]!
+L(al2): vld1.32 {q2}, [up]!
+ subs n, n, #12
+ blt L(end)
+
+ ALIGN(16)
+L(top): vld1.32 {q0}, [up]!
+ vmvn q2, q2
+ subs n, n, #8
+ vst1.32 {q2}, [rp:128]!
+ vld1.32 {q2}, [up]!
+ vmvn q0, q0
+ vst1.32 {q0}, [rp:128]!
+ bge L(top)
+
+L(end): vmvn q2, q2
+ vst1.32 {q2}, [rp:128]!
+
+C Handle last 0-7 limbs. Note that rp is aligned after loop, but not when we
+C arrive here via L(bc)
+L(bc): tst n, #4
+ beq L(tl1)
+ vld1.32 {q0}, [up]!
+ vmvn q0, q0
+ vst1.32 {q0}, [rp]!
+L(tl1): tst n, #2
+ beq L(tl2)
+ vld1.32 {d0}, [up]!
+ vmvn d0, d0
+ vst1.32 {d0}, [rp]!
+L(tl2): tst n, #1
+ beq L(tl3)
+ vld1.32 {d0[0]}, [up]
+ vmvn d0, d0
+ vst1.32 {d0[0]}, [rp]
+L(tl3): bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/neon/copyd.asm b/gmp/mpn/arm/v7a/cora15/neon/copyd.asm
new file mode 100644
index 0000000000..98fe535def
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/neon/copyd.asm
@@ -0,0 +1,110 @@
+dnl ARM Neon mpn_copyd optimised for A15.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 1.75 slower than core register code
+C Cortex-A15 0.52
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+ add rp, rp, n, lsl #2
+ add up, up, n, lsl #2
+
+ cmp n, #7
+ ble L(bc)
+
+C Copy until rp is 128-bit aligned
+ tst rp, #4
+ beq L(al1)
+ sub up, up, #4
+ vld1.32 {d22[0]}, [up]
+ sub n, n, #1
+ sub rp, rp, #4
+ vst1.32 {d22[0]}, [rp]
+L(al1): tst rp, #8
+ beq L(al2)
+ sub up, up, #8
+ vld1.32 {d22}, [up]
+ sub n, n, #2
+ sub rp, rp, #8
+ vst1.32 {d22}, [rp:64]
+L(al2): sub up, up, #16
+ vld1.32 {d26-d27}, [up]
+ subs n, n, #12
+ sub rp, rp, #16 C offset rp for loop
+ blt L(end)
+
+ sub up, up, #16 C offset up for loop
+ mov r12, #-16
+
+ ALIGN(16)
+L(top): vld1.32 {d22-d23}, [up], r12
+ vst1.32 {d26-d27}, [rp:128], r12
+ vld1.32 {d26-d27}, [up], r12
+ vst1.32 {d22-d23}, [rp:128], r12
+ subs n, n, #8
+ bge L(top)
+
+ add up, up, #16 C undo up offset
+ C rp offset undoing folded
+L(end): vst1.32 {d26-d27}, [rp:128]
+
+C Copy last 0-7 limbs. Note that rp is aligned after loop, but not when we
+C arrive here via L(bc)
+L(bc): tst n, #4
+ beq L(tl1)
+ sub up, up, #16
+ vld1.32 {d22-d23}, [up]
+ sub rp, rp, #16
+ vst1.32 {d22-d23}, [rp]
+L(tl1): tst n, #2
+ beq L(tl2)
+ sub up, up, #8
+ vld1.32 {d22}, [up]
+ sub rp, rp, #8
+ vst1.32 {d22}, [rp]
+L(tl2): tst n, #1
+ beq L(tl3)
+ sub up, up, #4
+ vld1.32 {d22[0]}, [up]
+ sub rp, rp, #4
+ vst1.32 {d22[0]}, [rp]
+L(tl3): bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/neon/copyi.asm b/gmp/mpn/arm/v7a/cora15/neon/copyi.asm
new file mode 100644
index 0000000000..2e05afe5e8
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/neon/copyi.asm
@@ -0,0 +1,90 @@
+dnl ARM Neon mpn_copyi optimised for A15.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 1.75 slower than core register code
+C Cortex-A15 0.52
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+ cmp n, #7
+ ble L(bc)
+
+C Copy until rp is 128-bit aligned
+ tst rp, #4
+ beq L(al1)
+ vld1.32 {d22[0]}, [up]!
+ sub n, n, #1
+ vst1.32 {d22[0]}, [rp]!
+L(al1): tst rp, #8
+ beq L(al2)
+ vld1.32 {d22}, [up]!
+ sub n, n, #2
+ vst1.32 {d22}, [rp:64]!
+L(al2): vld1.32 {d26-d27}, [up]!
+ subs n, n, #12
+ blt L(end)
+
+ ALIGN(16)
+L(top): vld1.32 {d22-d23}, [up]!
+ vst1.32 {d26-d27}, [rp:128]!
+ vld1.32 {d26-d27}, [up]!
+ vst1.32 {d22-d23}, [rp:128]!
+ subs n, n, #8
+ bge L(top)
+
+L(end): vst1.32 {d26-d27}, [rp:128]!
+
+C Copy last 0-7 limbs. Note that rp is aligned after loop, but not when we
+C arrive here via L(bc)
+L(bc): tst n, #4
+ beq L(tl1)
+ vld1.32 {d22-d23}, [up]!
+ vst1.32 {d22-d23}, [rp]!
+L(tl1): tst n, #2
+ beq L(tl2)
+ vld1.32 {d22}, [up]!
+ vst1.32 {d22}, [rp]!
+L(tl2): tst n, #1
+ beq L(tl3)
+ vld1.32 {d22[0]}, [up]
+ vst1.32 {d22[0]}, [rp]
+L(tl3): bx lr
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/neon/rsh1aors_n.asm b/gmp/mpn/arm/v7a/cora15/neon/rsh1aors_n.asm
new file mode 100644
index 0000000000..2c11d6debd
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/neon/rsh1aors_n.asm
@@ -0,0 +1,177 @@
+dnl ARM Neon mpn_rsh1add_n, mpn_rsh1sub_n.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C StrongARM -
+C XScale -
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 4-5
+C Cortex-A15 2.5
+
+C TODO
+C * Try to make this smaller, its size (384 bytes) is excessive.
+C * Try to reach 2.25 c/l on A15, to match the addlsh_1 family.
+C * This is ad-hoc scheduled, perhaps unnecessarily so for A15, and perhaps
+C insufficiently for A7 and A8.
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`vp', `r2')
+define(`n', `r3')
+
+ifdef(`OPERATION_rsh1add_n', `
+ define(`ADDSUBS', `adds $1, $2, $3')
+ define(`ADCSBCS', `adcs $1, $2, $3')
+ define(`IFADD', `$1')
+ define(`IFSUB', `')
+ define(`func', mpn_rsh1add_n)')
+ifdef(`OPERATION_rsh1sub_n', `
+ define(`ADDSUBS', `subs $1, $2, $3')
+ define(`ADCSBCS', `sbcs $1, $2, $3')
+ define(`IFADD', `')
+ define(`IFSUB', `$1')
+ define(`func', mpn_rsh1sub_n)')
+
+MULFUNC_PROLOGUE(mpn_rsh1add_n mpn_rsh1sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ push {r4-r10}
+
+ ands r4, n, #3
+ beq L(b00)
+ cmp r4, #2
+ blo L(b01)
+ beq L(b10)
+
+L(b11): ldmia up!, {r9,r10,r12}
+ ldmia vp!, {r5,r6,r7}
+ ADDSUBS( r9, r9, r5)
+ vmov d4, r9, r9
+ ADCSBCS( r10, r10, r6)
+ ADCSBCS( r12, r12, r7)
+ vshr.u64 d3, d4, #1
+ vmov d1, r10, r12
+ vsli.u64 d3, d1, #31
+ vshr.u64 d2, d1, #1
+ vst1.32 d3[0], [rp]!
+ bics n, n, #3
+ beq L(wd2)
+L(gt3): ldmia up!, {r8,r9,r10,r12}
+ ldmia vp!, {r4,r5,r6,r7}
+ b L(mi0)
+
+L(b10): ldmia up!, {r10,r12}
+ ldmia vp!, {r6,r7}
+ ADDSUBS( r10, r10, r6)
+ ADCSBCS( r12, r12, r7)
+ vmov d4, r10, r12
+ bics n, n, #2
+ vshr.u64 d2, d4, #1
+ beq L(wd2)
+L(gt2): ldmia up!, {r8,r9,r10,r12}
+ ldmia vp!, {r4,r5,r6,r7}
+ b L(mi0)
+
+L(b01): ldr r12, [up], #4
+ ldr r7, [vp], #4
+ ADDSUBS( r12, r12, r7)
+ vmov d4, r12, r12
+ bics n, n, #1
+ bne L(gt1)
+ mov r5, r12, lsr #1
+IFADD(` adc r1, n, #0')
+IFSUB(` adc r1, n, #1')
+ bfi r5, r1, #31, #1
+ str r5, [rp]
+ and r0, r12, #1
+ pop {r4-r10}
+ bx r14
+L(gt1): ldmia up!, {r8,r9,r10,r12}
+ ldmia vp!, {r4,r5,r6,r7}
+ vshr.u64 d2, d4, #1
+ ADCSBCS( r8, r8, r4)
+ ADCSBCS( r9, r9, r5)
+ vmov d0, r8, r9
+ ADCSBCS( r10, r10, r6)
+ ADCSBCS( r12, r12, r7)
+ vsli.u64 d2, d0, #31
+ vshr.u64 d3, d0, #1
+ vst1.32 d2[0], [rp]!
+ b L(mi1)
+
+L(b00): ldmia up!, {r8,r9,r10,r12}
+ ldmia vp!, {r4,r5,r6,r7}
+ ADDSUBS( r8, r8, r4)
+ ADCSBCS( r9, r9, r5)
+ vmov d4, r8, r9
+ ADCSBCS( r10, r10, r6)
+ ADCSBCS( r12, r12, r7)
+ vshr.u64 d3, d4, #1
+ b L(mi1)
+
+ ALIGN(16)
+L(top): ldmia up!, {r8,r9,r10,r12}
+ ldmia vp!, {r4,r5,r6,r7}
+ vsli.u64 d3, d1, #63
+ vshr.u64 d2, d1, #1
+ vst1.32 d3, [rp]!
+L(mi0): ADCSBCS( r8, r8, r4)
+ ADCSBCS( r9, r9, r5)
+ vmov d0, r8, r9
+ ADCSBCS( r10, r10, r6)
+ ADCSBCS( r12, r12, r7)
+ vsli.u64 d2, d0, #63
+ vshr.u64 d3, d0, #1
+ vst1.32 d2, [rp]!
+L(mi1): vmov d1, r10, r12
+ sub n, n, #4
+ tst n, n
+ bne L(top)
+
+L(end): vsli.u64 d3, d1, #63
+ vshr.u64 d2, d1, #1
+ vst1.32 d3, [rp]!
+L(wd2): vmov r4, r5, d2
+IFADD(` adc r1, n, #0')
+IFSUB(` adc r1, n, #1')
+ bfi r5, r1, #31, #1
+ stm rp, {r4,r5}
+
+L(rtn): vmov.32 r0, d4[0]
+ and r0, r0, #1
+ pop {r4-r10}
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora15/submul_1.asm b/gmp/mpn/arm/v7a/cora15/submul_1.asm
new file mode 100644
index 0000000000..ed7bfe820b
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora15/submul_1.asm
@@ -0,0 +1,159 @@
+dnl ARM mpn_submul_1 optimised for A15.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C StrongARM: -
+C XScale ?
+C Cortex-A7 ?
+C Cortex-A8 ?
+C Cortex-A9 5.75 3.75
+C Cortex-A15 2.32 this
+
+C This code uses umlal and umaal for adding in the rp[] data, keeping the
+C recurrency path separate from any multiply instructions. It performs well on
+C A15, but not quite at the multiply bandwidth like the corresponding addmul_1
+C code.
+C
+C We don't use r12 due to ldrd and strd limitations.
+C
+C This loop complements U on the fly,
+C U' = B^n - 1 - U
+C and then uses that
+C R - U*v = R + U'*v + v - B^n v
+
+C Architecture requirements:
+C v5 -
+C v5t -
+C v5te ldrd strd
+C v6 umaal
+C v6t2 -
+C v7a -
+
+define(`rp', `r0')
+define(`up', `r1')
+define(`n', `r2')
+define(`v0', `r3')
+
+define(`w0', `r10') define(`w1', `r11')
+define(`u0', `r8') define(`u1', `r9')
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ sub sp, sp, #32
+ strd r10, r11, [sp, #24]
+ strd r8, r9, [sp, #16]
+ strd r6, r7, [sp, #8]
+ strd r4, r5, [sp, #0]
+C push { r4-r11 }
+
+ ands r6, n, #3
+ sub n, n, #3
+ beq L(b00)
+ cmp r6, #2
+ bcc L(b01)
+ beq L(b10)
+
+L(b11): mov r6, #0
+ ldr u1, [up], #-4
+ ldr w1, [rp], #-16
+ mvn u1, u1
+ adds r7, v0, #0
+ b L(mid)
+
+L(b00): ldrd u0, u1, [up]
+ ldrd w0, w1, [rp], #-12
+ mvn u0, u0
+ mvn u1, u1
+ mov r6, v0
+ umaal w0, r6, u0, v0
+ cmn r13, #0 C carry clear
+ mov r7, #0
+ str w0, [rp, #12]
+ b L(mid)
+
+L(b10): ldrd u0, u1, [up], #8
+ ldrd w0, w1, [rp]
+ mvn u0, u0
+ mvn u1, u1
+ mov r4, v0
+ umaal w0, r4, u0, v0
+ mov r5, #0
+ str w0, [rp], #-4
+ umlal w1, r5, u1, v0
+ adds n, n, #0
+ bmi L(end)
+ b L(top)
+
+L(b01): ldr u1, [up], #4
+ ldr w1, [rp], #-8
+ mvn u1, u1
+ mov r5, v0
+ mov r4, #0
+ umaal w1, r5, u1, v0
+ tst n, n
+ bmi L(end)
+
+C ALIGN(16)
+L(top): ldrd u0, u1, [up, #0]
+ adcs r4, r4, w1
+ mvn u0, u0
+ ldrd w0, w1, [rp, #12]
+ mvn u1, u1
+ mov r6, #0
+ umlal w0, r6, u0, v0 C 1 2
+ adcs r5, r5, w0
+ mov r7, #0
+ strd r4, r5, [rp, #8]
+L(mid): umaal w1, r7, u1, v0 C 2 3
+ ldrd u0, u1, [up, #8]
+ add up, up, #16
+ adcs r6, r6, w1
+ mvn u0, u0
+ ldrd w0, w1, [rp, #20]
+ mvn u1, u1
+ mov r4, #0
+ umlal w0, r4, u0, v0 C 3 4
+ adcs r7, r7, w0
+ mov r5, #0
+ strd r6, r7, [rp, #16]!
+ sub n, n, #4
+ umlal w1, r5, u1, v0 C 0 1
+ tst n, n
+ bpl L(top)
+
+L(end): adcs r4, r4, w1
+ str r4, [rp, #8]
+ adc r0, r5, #0
+ sub r0, v0, r0
+ pop { r4-r11 }
+ bx r14
+EPILOGUE()
diff --git a/gmp/mpn/arm/v7a/cora9/gmp-mparam.h b/gmp/mpn/arm/v7a/cora9/gmp-mparam.h
new file mode 100644
index 0000000000..9660257820
--- /dev/null
+++ b/gmp/mpn/arm/v7a/cora9/gmp-mparam.h
@@ -0,0 +1,209 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2003, 2009, 2010, 2012-2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 1000MHz Cortex-A9 */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.6 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 8
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD MP_SIZE_T_MAX
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 12
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 20
+
+#define MUL_TOOM22_THRESHOLD 45
+#define MUL_TOOM33_THRESHOLD 129
+#define MUL_TOOM44_THRESHOLD 387
+#define MUL_TOOM6H_THRESHOLD 517
+#define MUL_TOOM8H_THRESHOLD 774
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 137
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 222
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 137
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 235
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 208
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 54
+#define SQR_TOOM3_THRESHOLD 181
+#define SQR_TOOM4_THRESHOLD 490
+#define SQR_TOOM6_THRESHOLD 656
+#define SQR_TOOM8_THRESHOLD 0 /* always */
+
+#define MULMID_TOOM42_THRESHOLD 64
+
+#define MULMOD_BNM1_THRESHOLD 26
+#define SQRMOD_BNM1_THRESHOLD 28
+
+#define MUL_FFT_MODF_THRESHOLD 624 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 624, 5}, { 28, 6}, { 15, 5}, { 34, 6}, \
+ { 18, 5}, { 37, 6}, { 28, 7}, { 15, 6}, \
+ { 36, 7}, { 19, 6}, { 40, 7}, { 21, 6}, \
+ { 43, 7}, { 23, 6}, { 47, 7}, { 25, 6}, \
+ { 51, 7}, { 27, 6}, { 55, 7}, { 29, 8}, \
+ { 15, 7}, { 31, 6}, { 63, 7}, { 37, 8}, \
+ { 19, 7}, { 43, 8}, { 23, 7}, { 51, 8}, \
+ { 27, 7}, { 57, 9}, { 15, 8}, { 31, 7}, \
+ { 65, 8}, { 35, 7}, { 71, 8}, { 43, 9}, \
+ { 23, 8}, { 55,10}, { 15, 9}, { 31, 8}, \
+ { 71, 9}, { 39, 8}, { 83, 9}, { 47, 8}, \
+ { 99, 9}, { 55,10}, { 31, 9}, { 79,10}, \
+ { 47, 9}, { 103,11}, { 31,10}, { 63, 9}, \
+ { 135,10}, { 79, 9}, { 167,10}, { 95, 9}, \
+ { 191,10}, { 111,11}, { 63,10}, { 159,11}, \
+ { 95,10}, { 191, 9}, { 383,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271,11}, \
+ { 159,10}, { 319, 9}, { 639,10}, { 335, 9}, \
+ { 671,10}, { 351,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 399, 9}, { 799,10}, { 415,11}, \
+ { 223,12}, { 127,11}, { 255,10}, { 511, 9}, \
+ { 1023,10}, { 543,11}, { 287,10}, { 575, 9}, \
+ { 1151,11}, { 319,10}, { 671,11}, { 351,12}, \
+ { 191,11}, { 383,10}, { 799,11}, { 415,10}, \
+ { 831,13}, { 127,12}, { 255,11}, { 511,10}, \
+ { 1023,11}, { 607,12}, { 319,11}, { 735,12}, \
+ { 383,11}, { 863,12}, { 447,11}, { 959,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1215,12}, { 639,11}, { 1279,12}, { 703,13}, \
+ { 383,12}, { 767,11}, { 1535,12}, { 831,11}, \
+ { 1663,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1023,11}, { 2047,12}, { 1215,13}, { 639,12}, \
+ { 1407,13}, { 767,12}, { 1663,13}, { 895,12}, \
+ { 1791,14}, { 511,13}, { 1023,12}, { 2111,13}, \
+ { 1151,12}, { 2431,13}, { 1279,12}, { 2559,13}, \
+ { 1407,14}, { 767,13}, { 1535,12}, { 3071,13}, \
+ { 1663,12}, { 3455,13}, { 1791,15}, { 511,14}, \
+ { 1023,13}, { 2047,12}, { 4095,13}, { 2175,12}, \
+ { 4351,13}, { 2431,14}, { 1279,13}, { 2559,12}, \
+ { 5119,13}, { 2815,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 160
+#define MUL_FFT_THRESHOLD 6784
+
+#define SQR_FFT_MODF_THRESHOLD 560 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 560, 5}, { 19, 4}, { 39, 5}, { 21, 4}, \
+ { 43, 5}, { 29, 6}, { 15, 5}, { 33, 6}, \
+ { 17, 5}, { 35, 6}, { 36, 7}, { 19, 6}, \
+ { 40, 7}, { 21, 6}, { 43, 7}, { 23, 6}, \
+ { 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 43, 8}, { 23, 7}, { 49, 8}, \
+ { 27, 7}, { 55, 9}, { 15, 8}, { 31, 7}, \
+ { 65, 8}, { 35, 7}, { 71, 8}, { 43, 9}, \
+ { 23, 8}, { 55, 9}, { 31, 8}, { 71, 9}, \
+ { 39, 8}, { 83, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 103,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 159,10}, { 95, 9}, { 191,10}, \
+ { 111,11}, { 63,10}, { 159,11}, { 95,10}, \
+ { 191, 9}, { 383,10}, { 207,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511, 8}, { 1023, 9}, \
+ { 543,10}, { 287,11}, { 159,10}, { 319, 9}, \
+ { 639,10}, { 335, 9}, { 671,10}, { 351,11}, \
+ { 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
+ { 799,10}, { 415, 9}, { 831,11}, { 223,12}, \
+ { 127,11}, { 255,10}, { 511, 9}, { 1023,10}, \
+ { 543,11}, { 287,10}, { 575, 9}, { 1151,10}, \
+ { 607,11}, { 319,10}, { 671,11}, { 351,10}, \
+ { 703,12}, { 191,11}, { 383,10}, { 799,11}, \
+ { 415,10}, { 831,13}, { 127,11}, { 511,10}, \
+ { 1023,11}, { 543,10}, { 1087,11}, { 575,10}, \
+ { 1151,11}, { 607,12}, { 319,11}, { 671,10}, \
+ { 1343,11}, { 735,12}, { 383,11}, { 863,12}, \
+ { 447,11}, { 959,12}, { 511,11}, { 1087,12}, \
+ { 575,11}, { 1215,12}, { 639,11}, { 1343,12}, \
+ { 703,11}, { 1407,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1663,12}, { 895,11}, \
+ { 1791,12}, { 959,13}, { 511,12}, { 1023,11}, \
+ { 2047,12}, { 1215,13}, { 639,12}, { 1407,13}, \
+ { 767,12}, { 1663,13}, { 895,12}, { 1791,14}, \
+ { 511,13}, { 1023,12}, { 2111,13}, { 1151,12}, \
+ { 2431,13}, { 1279,12}, { 2559,13}, { 1407,14}, \
+ { 767,13}, { 1535,12}, { 3071,13}, { 1663,12}, \
+ { 3455,13}, { 1791,15}, { 511,14}, { 1023,13}, \
+ { 2047,12}, { 4095,13}, { 2175,12}, { 4351,13}, \
+ { 2431,14}, { 1279,13}, { 2559,12}, { 5119,13}, \
+ { 2815,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 167
+#define SQR_FFT_THRESHOLD 5312
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 38
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 42
+#define DC_DIVAPPR_Q_THRESHOLD 100
+#define DC_BDIV_QR_THRESHOLD 43
+#define DC_BDIV_Q_THRESHOLD 104
+
+#define INV_MULMOD_BNM1_THRESHOLD 98
+#define INV_NEWTON_THRESHOLD 138
+#define INV_APPR_THRESHOLD 133
+
+#define BINV_NEWTON_THRESHOLD 333
+#define REDC_1_TO_REDC_2_THRESHOLD 2
+#define REDC_2_TO_REDC_N_THRESHOLD 142
+
+#define MU_DIV_QR_THRESHOLD 2350
+#define MU_DIVAPPR_Q_THRESHOLD 2259
+#define MUPI_DIV_QR_THRESHOLD 70
+#define MU_BDIV_QR_THRESHOLD 2089
+#define MU_BDIV_Q_THRESHOLD 2172
+
+#define POWM_SEC_TABLE 37,48,81,615,1925
+
+#define MATRIX22_STRASSEN_THRESHOLD 22
+#define HGCD_THRESHOLD 64
+#define HGCD_APPR_THRESHOLD 50
+#define HGCD_REDUCE_THRESHOLD 4284
+#define GCD_DC_THRESHOLD 416
+#define GCDEXT_DC_THRESHOLD 298
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 18
+#define GET_STR_PRECOMPUTE_THRESHOLD 33
+#define SET_STR_DC_THRESHOLD 140
+#define SET_STR_PRECOMPUTE_THRESHOLD 748
+
+#define FAC_DSC_THRESHOLD 309
+#define FAC_ODD_THRESHOLD 29
diff --git a/gmp/mpn/arm64/aors_n.asm b/gmp/mpn/arm64/aors_n.asm
new file mode 100644
index 0000000000..a880cd35cf
--- /dev/null
+++ b/gmp/mpn/arm64/aors_n.asm
@@ -0,0 +1,98 @@
+dnl ARM64 mpn_add_n and mpn_sub_n
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Cortex-A53 ?
+C Cortex-A57 ?
+
+changecom(@&*$)
+
+define(`rp', `x0')
+define(`up', `x1')
+define(`vp', `x2')
+define(`n', `x3')
+
+ifdef(`OPERATION_add_n', `
+ define(`ADDSUBC', adcs)
+ define(`CLRCY', `cmn xzr, xzr')
+ define(`SETCY', `cmp $1, #1')
+ define(`RETVAL', `adc x0, xzr, xzr')
+ define(`func', mpn_add_n)
+ define(`func_nc', mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(`ADDSUBC', sbcs)
+ define(`CLRCY', `cmp xzr, xzr')
+ define(`SETCY', `subs $1, xzr, $1')
+ define(`RETVAL', `sbc x0, xzr, xzr
+ and x0, x0, #1')
+ define(`func', mpn_sub_n)
+ define(`func_nc', mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+PROLOGUE(func_nc)
+ SETCY( x4)
+ b L(ent)
+EPILOGUE()
+PROLOGUE(func)
+ CLRCY
+L(ent): tbz n, #0, L(b0)
+
+ ldr x4, [up],#8
+ ldr x6, [vp],#8
+ sub n, n, #1
+ ADDSUBC x8, x4, x6
+ str x8, [rp],#8
+ cbz n, L(rt)
+
+L(b0): ldp x4, x5, [up],#16
+ ldp x6, x7, [vp],#16
+ sub n, n, #2
+ ADDSUBC x8, x4, x6
+ ADDSUBC x9, x5, x7
+ cbz n, L(end)
+
+L(top): ldp x4, x5, [up],#16
+ ldp x6, x7, [vp],#16
+ sub n, n, #2
+ stp x8, x9, [rp],#16
+ ADDSUBC x8, x4, x6
+ ADDSUBC x9, x5, x7
+ cbnz n, L(top)
+
+L(end): stp x8, x9, [rp]
+L(rt): RETVAL
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/arm64/aorsmul_1.asm b/gmp/mpn/arm64/aorsmul_1.asm
new file mode 100644
index 0000000000..bf765a7f77
--- /dev/null
+++ b/gmp/mpn/arm64/aorsmul_1.asm
@@ -0,0 +1,122 @@
+dnl ARM64 mpn_submul_1
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Cortex-A53 ?
+C Cortex-A57 ?
+
+changecom(@&*$)
+
+define(`rp', `x0')
+define(`up', `x1')
+define(`n', `x2')
+define(`v0', `x3')
+
+ifdef(`OPERATION_addmul_1', `
+ define(`ADDSUB', adds)
+ define(`ADDSUBC', adcs)
+ define(`COND', `cc')
+ define(`func', mpn_addmul_1)')
+ifdef(`OPERATION_submul_1', `
+ define(`ADDSUB', subs)
+ define(`ADDSUBC', sbcs)
+ define(`COND', `cs')
+ define(`func', mpn_submul_1)')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+PROLOGUE(func)
+ mov x15, #0
+
+ tbz n, #0, L(1)
+
+ ldr x4, [up],#8
+ mul x8, x4, v0
+ umulh x12, x4, v0
+ adds x8, x8, x15
+ ldr x4, [rp,#0]
+ ADDSUB x8, x4, x8
+ csinc x15, x12, x12, COND
+ str x8, [rp],#8
+
+L(1): tbz n, #1, L(2)
+
+ ldp x4, x5, [up],#16
+ mul x8, x4, v0
+ umulh x12, x4, v0
+ mul x9, x5, v0
+ umulh x13, x5, v0
+ adds x8, x8, x15
+ adcs x9, x9, x12
+ ldp x4, x5, [rp,#0]
+ adc x15, x13, xzr
+ sub n, n, #1
+ ADDSUB x8, x4, x8
+ ADDSUBC x9, x5, x9
+ csinc x15, x15, x15, COND
+ stp x8, x9, [rp],#16
+
+L(2): lsr n, n, 2
+ cbz n, L(end)
+
+L(top): ldp x4, x5, [up],#16
+ ldp x6, x7, [up],#16
+ mul x8, x4, v0
+ umulh x12, x4, v0
+ mul x9, x5, v0
+ umulh x13, x5, v0
+ adds x8, x8, x15
+ mul x10, x6, v0
+ umulh x14, x6, v0
+ adcs x9, x9, x12
+ mul x11, x7, v0
+ umulh x15, x7, v0
+ adcs x10, x10, x13
+ ldp x4, x5, [rp,#0]
+ adcs x11, x11, x14
+ ldp x6, x7, [rp,#16]
+ adc x15, x15, xzr
+ sub n, n, #1
+ ADDSUB x8, x4, x8
+ ADDSUBC x9, x5, x9
+ ADDSUBC x10, x6, x10
+ ADDSUBC x11, x7, x11
+ stp x8, x9, [rp],#16
+ csinc x15, x15, x15, COND
+ stp x10, x11, [rp],#16
+ cbnz n, L(top)
+
+L(end): mov x0, x15
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/arm64/cnd_aors_n.asm b/gmp/mpn/arm64/cnd_aors_n.asm
new file mode 100644
index 0000000000..e7836500d5
--- /dev/null
+++ b/gmp/mpn/arm64/cnd_aors_n.asm
@@ -0,0 +1,99 @@
+dnl ARM64 mpn_cnd_add_n, mpn_cnd_sub_n
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Cortex-A53 ?
+C Cortex-A57 ?
+
+changecom(@&*$)
+
+define(`cnd', `x0')
+define(`rp', `x1')
+define(`up', `x2')
+define(`vp', `x3')
+define(`n', `x4')
+
+ifdef(`OPERATION_cnd_add_n', `
+ define(`ADDSUBC', adcs)
+ define(`CLRCY', `cmn xzr, xzr')
+ define(`RETVAL', `adc x0, xzr, xzr')
+ define(func, mpn_cnd_add_n)')
+ifdef(`OPERATION_cnd_sub_n', `
+ define(`ADDSUBC', sbcs)
+ define(`CLRCY', `cmp xzr, xzr')
+ define(`RETVAL', `sbc x0, xzr, xzr
+ and x0, x0, #1')
+ define(func, mpn_cnd_sub_n)')
+
+MULFUNC_PROLOGUE(mpn_cnd_add_n mpn_cnd_sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ cmp cnd, #1
+ sbc cnd, cnd, cnd
+
+ CLRCY C really only needed for n = 0 (mod 4)
+
+ tbz n, #0, L(1)
+ ldr x10, [up], #8
+ ldr x12, [vp], #8
+ bic x6, x12, cnd
+ ADDSUBC x8, x10, x6
+ sub n, n, #1
+ str x8, [rp], #8
+ cbz n, L(rt)
+
+L(1): ldp x10, x11, [up], #16
+ ldp x12, x13, [vp], #16
+ sub n, n, #2
+ cbz n, L(end)
+
+L(top): bic x6, x12, cnd
+ bic x7, x13, cnd
+ ldp x12, x13, [vp], #16
+ ADDSUBC x8, x10, x6
+ ADDSUBC x9, x11, x7
+ ldp x10, x11, [up], #16
+ sub n, n, #2
+ stp x8, x9, [rp], #16
+ cbnz n, L(top)
+
+L(end): bic x6, x12, cnd
+ bic x7, x13, cnd
+ ADDSUBC x8, x10, x6
+ ADDSUBC x9, x11, x7
+ stp x8, x9, [rp]
+L(rt): RETVAL
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/arm64/copyd.asm b/gmp/mpn/arm64/copyd.asm
new file mode 100644
index 0000000000..bb477716e5
--- /dev/null
+++ b/gmp/mpn/arm64/copyd.asm
@@ -0,0 +1,93 @@
+dnl ARM64 mpn_copyd.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Cortex-A53 ?
+C Cortex-A57 ?
+
+changecom(@&*$)
+
+define(`rp', `x0')
+define(`up', `x1')
+define(`n', `x2')
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+ add rp, rp, n, lsl #3
+ add up, up, n, lsl #3
+
+ cmp n, #3
+ b.le L(bc)
+
+C Copy until rp is 128-bit aligned
+ tbz rp, #3, L(al2)
+ sub up, up, #8
+ ld1 {v22.1d}, [up]
+ sub n, n, #1
+ sub rp, rp, #8
+ st1 {v22.1d}, [rp]
+
+L(al2): sub up, up, #16
+ ld1 {v26.2d}, [up]
+ subs n, n, #6
+ sub rp, rp, #16 C offset rp for loop
+ b.lt L(end)
+
+ sub up, up, #16 C offset up for loop
+ mov x12, #-16
+
+ ALIGN(16)
+L(top): ld1 {v22.2d}, [up], x12
+ st1 {v26.2d}, [rp], x12
+ ld1 {v26.2d}, [up], x12
+ st1 {v22.2d}, [rp], x12
+ subs n, n, #4
+ b.ge L(top)
+
+ add up, up, #16 C undo up offset
+
+L(end): st1 {v26.2d}, [rp]
+
+C Copy last 0-3 limbs. Note that rp is aligned after loop, but not when we
+C arrive here via L(bc)
+L(bc): tbz n, #1, L(tl1)
+ sub up, up, #16
+ ld1 {v22.2d}, [up]
+ sub rp, rp, #16
+ st1 {v22.2d}, [rp]
+L(tl1): tbz n, #0, L(tl2)
+ sub up, up, #8
+ ld1 {v22.1d}, [up]
+ sub rp, rp, #8
+ st1 {v22.1d}, [rp]
+L(tl2): ret
+EPILOGUE()
diff --git a/gmp/mpn/arm64/copyi.asm b/gmp/mpn/arm64/copyi.asm
new file mode 100644
index 0000000000..8f7dbd4f52
--- /dev/null
+++ b/gmp/mpn/arm64/copyi.asm
@@ -0,0 +1,77 @@
+dnl ARM64 mpn_copyi.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Cortex-A53 ?
+C Cortex-A57 ?
+
+changecom(@&*$)
+
+define(`rp', `x0')
+define(`up', `x1')
+define(`n', `x2')
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+ cmp n, #3
+ b.le L(bc)
+
+C Copy until rp is 128-bit aligned
+ tbz rp, #3, L(al2)
+ ld1 {v22.1d}, [up], #8
+ sub n, n, #1
+ st1 {v22.1d}, [rp], #8
+
+L(al2): ld1 {v26.2d}, [up], #16
+ subs n, n, #6
+ b.lt L(end)
+
+ ALIGN(16)
+L(top): ld1 {v22.2d}, [up], #16
+ st1 {v26.2d}, [rp], #16
+ ld1 {v26.2d}, [up], #16
+ st1 {v22.2d}, [rp], #16
+ subs n, n, #4
+ b.ge L(top)
+
+L(end): st1 {v26.2d}, [rp], #16
+
+C Copy last 0-3 limbs. Note that rp is aligned after loop, but not when we
+C arrive here via L(bc)
+L(bc): tbz n, #1, L(tl1)
+ ld1 {v22.2d}, [up], #16
+ st1 {v22.2d}, [rp], #16
+L(tl1): tbz n, #0, L(tl2)
+ ld1 {v22.1d}, [up]
+ st1 {v22.1d}, [rp]
+L(tl2): ret
+EPILOGUE()
diff --git a/gmp/mpn/arm64/gcd_1.asm b/gmp/mpn/arm64/gcd_1.asm
new file mode 100644
index 0000000000..d231dbcbb9
--- /dev/null
+++ b/gmp/mpn/arm64/gcd_1.asm
@@ -0,0 +1,125 @@
+dnl ARM v6t2 mpn_gcd_1.
+
+dnl Based on the K7 gcd_1.asm, by Kevin Ryde. Rehacked for ARM by Torbjorn
+dnl Granlund.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+changecom(@&*$)
+
+C cycles/bit (approx)
+C Cortex-A53 ?
+C Cortex-A57 ?
+
+C TODO
+C * Optimise inner-loop better.
+C * Push saving/restoring of callee-user regs into call code
+
+C Threshold of when to call bmod when U is one limb. Should be about
+C (time_in_cycles(bmod_1,1) + call_overhead) / (cycles/bit).
+define(`BMOD_THRES_LOG2', 7)
+
+C INPUT PARAMETERS
+define(`up', `x0')
+define(`n', `x1')
+define(`v0', `x2')
+
+ifdef(`BMOD_1_TO_MOD_1_THRESHOLD',,
+ `define(`BMOD_1_TO_MOD_1_THRESHOLD',30)')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_gcd_1)
+ stp x29, x30, [sp,#-32]!
+ ldr x3, [up] C U low limb
+ stp x19, x20, [sp,#16]
+
+ orr x3, x3, v0
+ rbit x4, x3
+ clz x20, x4 C min(ctz(u0),ctz(v0))
+
+ rbit x12, v0
+ clz x12, x12
+ lsr v0, v0, x12
+
+ mov x19, v0
+
+ cmp n, #1
+ bne L(nby1)
+
+C Both U and V are single limbs, reduce with bmod if u0 >> v0.
+ ldr x3, [up]
+ cmp v0, x3, lsr #BMOD_THRES_LOG2
+ bhi L(red1)
+
+L(bmod):mov x3, #0 C carry argument
+ bl mpn_modexact_1c_odd
+ b L(red0)
+
+L(nby1):cmp n, #BMOD_1_TO_MOD_1_THRESHOLD
+ blo L(bmod)
+
+ bl mpn_mod_1
+
+L(red0):mov x3, x0
+L(red1):cmp x3, #0
+ rbit x12, x3
+ clz x12, x12
+ bne L(mid)
+ b L(end)
+
+ ALIGN(8)
+L(top):
+ifelse(1,1,`
+C This shorter variant makes full use of armv8 insns
+ csneg x3, x1, x1, cs C if x-y < 0
+ csel x19, x4, x19, cs C use x,y-x
+L(mid): lsr x4, x3, x12 C
+ subs x1, x19, x4 C
+',`
+C This variant is akin to the 32-bit v6t2 code
+ csel x3, x1, x3, cs C if x-y < 0
+ csel x19, x0, x19, cs C use x,y-x
+L(mid): lsr x3, x3, x12 C
+ mov x0, x3 C
+ subs x1, x19, x3 C
+ sub x3, x3, x19 C
+')
+ rbit x12, x1
+ clz x12, x12 C
+ bne L(top) C
+
+L(end): lsl x0, x19, x20
+ ldp x19, x20, [sp,#16]
+ ldp x29, x30, [sp],#32
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/arm64/invert_limb.asm b/gmp/mpn/arm64/invert_limb.asm
new file mode 100644
index 0000000000..2302d047e5
--- /dev/null
+++ b/gmp/mpn/arm64/invert_limb.asm
@@ -0,0 +1,83 @@
+dnl ARM64 mpn_invert_limb -- Invert a normalized limb.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Cortex-A53 ?
+C Cortex-A57 ?
+
+C Compiler generated, mildly edited. Could surely be further optimised.
+
+ASM_START()
+PROLOGUE(mpn_invert_limb)
+ lsr x2, x0, 54
+ adrp x1, approx_tab
+ and x2, x2, #0x1fe
+ add x1, x1, :lo12:approx_tab
+ ldrh w3, [x1,x2]
+ lsr x4, x0, 24
+ add x4, x4, 1
+ ubfiz x2, x3, 11, 16
+ umull x3, w3, w3
+ mul x3, x3, x4
+ sub x2, x2, #1
+ sub x2, x2, x3, lsr 40
+ lsl x3, x2, 60
+ mul x1, x2, x2
+ msub x1, x1, x4, x3
+ lsl x2, x2, 13
+ add x1, x2, x1, lsr 47
+ and x2, x0, 1
+ neg x3, x2
+ and x3, x3, x1, lsr 1
+ add x2, x2, x0, lsr 1
+ msub x2, x1, x2, x3
+ umulh x2, x2, x1
+ lsl x1, x1, 31
+ add x1, x1, x2, lsr 1
+ mul x3, x1, x0
+ umulh x2, x1, x0
+ adds x4, x3, x0
+ adc x0, x2, x0
+ sub x0, x1, x0
+ ret
+EPILOGUE()
+
+ RODATA
+ ALIGN(2)
+ TYPE( approx_tab, object)
+ SIZE( approx_tab, 512)
+approx_tab:
+forloop(i,256,512-1,dnl
+` .hword eval(0x7fd00/i)
+')dnl
diff --git a/gmp/mpn/arm64/logops_n.asm b/gmp/mpn/arm64/logops_n.asm
new file mode 100644
index 0000000000..0f75700cfd
--- /dev/null
+++ b/gmp/mpn/arm64/logops_n.asm
@@ -0,0 +1,106 @@
+dnl ARM64 mpn_and_n, mpn_andn_n. mpn_nand_n, etc.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Cortex-A53 ?
+C Cortex-A57 ?
+
+changecom(@&*$)
+
+define(`rp', `x0')
+define(`up', `x1')
+define(`vp', `x2')
+define(`n', `x3')
+
+define(`POSTOP', `dnl')
+
+ifdef(`OPERATION_and_n',`
+ define(`func', `mpn_and_n')
+ define(`LOGOP', `and $1, $2, $3')')
+ifdef(`OPERATION_andn_n',`
+ define(`func', `mpn_andn_n')
+ define(`LOGOP', `bic $1, $2, $3')')
+ifdef(`OPERATION_nand_n',`
+ define(`func', `mpn_nand_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `and $1, $2, $3')')
+ifdef(`OPERATION_ior_n',`
+ define(`func', `mpn_ior_n')
+ define(`LOGOP', `orr $1, $2, $3')')
+ifdef(`OPERATION_iorn_n',`
+ define(`func', `mpn_iorn_n')
+ define(`LOGOP', `orn $1, $2, $3')')
+ifdef(`OPERATION_nior_n',`
+ define(`func', `mpn_nior_n')
+ define(`POSTOP', `mvn $1, $1')
+ define(`LOGOP', `orr $1, $2, $3')')
+ifdef(`OPERATION_xor_n',`
+ define(`func', `mpn_xor_n')
+ define(`LOGOP', `eor $1, $2, $3')')
+ifdef(`OPERATION_xnor_n',`
+ define(`func', `mpn_xnor_n')
+ define(`LOGOP', `eon $1, $2, $3')')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+ASM_START()
+PROLOGUE(func)
+ tbz n, #0, L(b0)
+
+ ldr x4, [up],#8
+ ldr x6, [vp],#8
+ sub n, n, #1
+ LOGOP( x8, x4, x6)
+ POSTOP( x8)
+ str x8, [rp],#8
+ cbz n, L(rtn)
+
+L(b0): ldp x4, x5, [up],#16
+ ldp x6, x7, [vp],#16
+ sub n, n, #2
+ b L(mid)
+
+L(top): ldp x4, x5, [up],#16
+ ldp x6, x7, [vp],#16
+ sub n, n, #2
+ stp x8, x9, [rp],#16
+L(mid): LOGOP( x8, x4, x6)
+ LOGOP( x9, x5, x7)
+ POSTOP( x8)
+ POSTOP( x9)
+ cbnz n, L(top)
+
+ stp x8, x9, [rp],#16
+L(rtn): ret
+EPILOGUE()
diff --git a/gmp/mpn/arm64/mul_1.asm b/gmp/mpn/arm64/mul_1.asm
new file mode 100644
index 0000000000..c0c2570f0d
--- /dev/null
+++ b/gmp/mpn/arm64/mul_1.asm
@@ -0,0 +1,98 @@
+dnl ARM64 mpn_mul_1
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Cortex-A53 ?
+C Cortex-A57 ?
+
+define(`rp', `x0')
+define(`up', `x1')
+define(`n', `x2')
+define(`v0', `x3')
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ ldr x12, [up], #8
+ and x6, n, #3
+ and n, n, #-4
+ cbz x6, L(fi0)
+ cmp x6, #2
+ bcc L(fi1)
+ beq L(fi2)
+
+L(fi3): mul x8, x12, v0
+ umulh x13, x12, v0
+ cmn xzr, xzr
+ b L(L3)
+L(fi2): mul x7, x12, v0
+ umulh x5, x12, v0
+ cmn xzr, xzr
+ b L(L2)
+L(fi0): mul x9, x12, v0
+ umulh x5, x12, v0
+ sub n, n, #4
+ cmn xzr, xzr
+ b L(L0)
+L(fi1): mul x10, x12, v0
+ umulh x13, x12, v0
+ cmn xzr, xzr
+ cbz n, L(end)
+
+L(top): sub n, n, #4
+ ldr x12, [up], #8
+ mul x6, x12, v0
+ umulh x5, x12, v0
+ str x10, [rp], #8
+ adcs x9, x6, x13
+L(L0): ldr x12, [up], #8
+ mul x6, x12, v0
+ umulh x13, x12, v0
+ str x9, [rp] ,#8
+ adcs x8, x6, x5
+L(L3): ldr x12, [up], #8
+ mul x6, x12, v0
+ umulh x5, x12, v0
+ str x8, [rp], #8
+ adcs x7, x6, x13
+L(L2): ldr x12, [up], #8
+ mul x6, x12, v0
+ umulh x13, x12, v0
+ str x7, [rp], #8
+ adcs x10, x6, x5
+ cbnz n, L(top)
+
+L(end): str x10, [rp]
+ adc x0, x13, xzr
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/asm-defs.m4 b/gmp/mpn/asm-defs.m4
new file mode 100644
index 0000000000..e573cc4ca8
--- /dev/null
+++ b/gmp/mpn/asm-defs.m4
@@ -0,0 +1,1761 @@
+divert(-1)
+dnl
+dnl m4 macros for gmp assembly code, shared by all CPUs.
+
+dnl Copyright 1999-2006, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl These macros are designed for use with any m4 and have been used on
+dnl GNU, FreeBSD, NetBSD, OpenBSD and SysV.
+dnl
+dnl GNU m4 and OpenBSD 2.7 m4 will give filenames and line numbers in error
+dnl messages.
+dnl
+dnl
+dnl Macros:
+dnl
+dnl Most new m4 specific macros have an "m4_" prefix to emphasise they're
+dnl m4 expansions. But new defining things like deflit() and defreg() are
+dnl named like the builtin define(), and forloop() is named following the
+dnl GNU m4 example on which it's based.
+dnl
+dnl GNU m4 with the -P option uses "m4_" as a prefix for builtins, but that
+dnl option isn't going to be used, so there's no conflict or confusion.
+dnl
+dnl
+dnl Comments in output:
+dnl
+dnl The m4 comment delimiters are left at # and \n, the normal assembler
+dnl commenting for most CPUs. m4 passes comment text through without
+dnl expanding macros in it, which is generally a good thing since it stops
+dnl unexpected expansions and possible resultant errors.
+dnl
+dnl But note that when a quoted string is being read, a # isn't special, so
+dnl apostrophes in comments in quoted strings must be avoided or they'll be
+dnl interpreted as a closing quote mark. But when the quoted text is
+dnl re-read # will still act like a normal comment, suppressing macro
+dnl expansion.
+dnl
+dnl For example,
+dnl
+dnl # apostrophes in comments that're outside quotes are ok
+dnl # and using macro names like PROLOGUE is ok too
+dnl ...
+dnl ifdef(`PIC',`
+dnl # but apostrophes aren't ok inside quotes
+dnl # ^--wrong
+dnl ...
+dnl # though macro names like PROLOGUE are still ok
+dnl ...
+dnl ')
+dnl
+dnl If macro expansion in a comment is wanted, use `#' in the .asm (ie. a
+dnl quoted hash symbol), which will turn into # in the .s but get
+dnl expansions done on that line. This can make the .s more readable to
+dnl humans, but it won't make a blind bit of difference to the assembler.
+dnl
+dnl All the above applies, mutatis mutandis, when changecom() is used to
+dnl select @ ! ; or whatever other commenting.
+dnl
+dnl
+dnl Variations in m4 affecting gmp:
+dnl
+dnl $# - When a macro is called as "foo" with no brackets, BSD m4 sets $#
+dnl to 1, whereas GNU or SysV m4 set it to 0. In all cases though
+dnl "foo()" sets $# to 1. This is worked around in various places.
+dnl
+dnl len() - When "len()" is given an empty argument, BSD m4 evaluates to
+dnl nothing, whereas GNU, SysV, and the new OpenBSD, evaluate to 0.
+dnl See m4_length() below which works around this.
+dnl
+dnl translit() - GNU m4 accepts character ranges like A-Z, and the new
+dnl OpenBSD m4 does under option -g, but basic BSD and SysV don't.
+dnl
+dnl popdef() - in BSD and SysV m4 popdef() takes multiple arguments and
+dnl pops each, but GNU m4 only takes one argument.
+dnl
+dnl push back - BSD m4 has some limits on the amount of text that can be
+dnl pushed back. The limit is reasonably big and so long as macros
+dnl don't gratuitously duplicate big arguments it isn't a problem.
+dnl Normally an error message is given, but sometimes it just hangs.
+dnl
+dnl eval() &,|,^ - GNU and SysV m4 have bitwise operators &,|,^ available,
+dnl but BSD m4 doesn't (contrary to what the man page suggests) and
+dnl instead ^ is exponentiation.
+dnl
+dnl eval() ?: - The C ternary operator "?:" is available in BSD m4, but not
+dnl in SysV or GNU m4 (as of GNU m4 1.4 and betas of 1.5).
+dnl
+dnl eval() -2^31 - BSD m4 has a bug where an eval() resulting in -2^31
+dnl (ie. -2147483648) gives "-(". Using -2147483648 within an
+dnl expression is ok, it just can't be a final result. "-(" will of
+dnl course upset parsing, with all sorts of strange effects.
+dnl
+dnl eval() <<,>> - SysV m4 doesn't support shift operators in eval() (on
+dnl Solaris 7 /usr/xpg4/m4 has them but /usr/ccs/m4 doesn't). See
+dnl m4_lshift() and m4_rshift() below for workarounds.
+dnl
+dnl ifdef() - OSF 4.0 m4 considers a macro defined to a zero value `0' or
+dnl `00' etc as not defined. See m4_ifdef below for a workaround.
+dnl
+dnl m4wrap() sequence - in BSD m4, m4wrap() replaces any previous m4wrap()
+dnl string, in SysV m4 it appends to it, and in GNU m4 it prepends.
+dnl See m4wrap_prepend() below which brings uniformity to this.
+dnl
+dnl m4wrap() 0xFF - old versions of BSD m4 store EOF in a C "char" under an
+dnl m4wrap() and on systems where char is unsigned by default a
+dnl spurious 0xFF is output. This has been observed on recent Cray
+dnl Unicos Alpha, Apple MacOS X, and HPUX 11 systems. An autoconf
+dnl test is used to check for this, see the m4wrap handling below. It
+dnl might work to end the m4wrap string with a dnl to consume the
+dnl 0xFF, but that probably induces the offending m4's to read from an
+dnl already closed "FILE *", which could be bad on a glibc style
+dnl stdio.
+dnl
+dnl __file__,__line__ - GNU m4 and OpenBSD 2.7 m4 provide these, and
+dnl they're used here to make error messages more informative. GNU m4
+dnl gives an unhelpful "NONE 0" in an m4wrap(), but that's worked
+dnl around.
+dnl
+dnl __file__ quoting - OpenBSD m4, unlike GNU m4, doesn't quote the
+dnl filename in __file__, so care should be taken that no macro has
+dnl the same name as a file, or an unwanted expansion will occur when
+dnl printing an error or warning.
+dnl
+dnl changecom() - BSD m4 changecom doesn't quite work like the man page
+dnl suggests, in particular "changecom" or "changecom()" doesn't
+dnl disable the comment feature, and multi-character comment sequences
+dnl don't seem to work. If the default `#' and newline aren't
+dnl suitable it's necessary to change it to something else,
+dnl eg. changecom(;).
+dnl
+dnl OpenBSD 2.6 m4 - in this m4, eval() rejects decimal constants containing
+dnl an 8 or 9, making it pretty much unusable. The bug is confined to
+dnl version 2.6 (it's not in 2.5, and was fixed in 2.7).
+dnl
+dnl SunOS /usr/bin/m4 - this m4 lacks a number of desired features,
+dnl including $# and $@, defn(), m4exit(), m4wrap(), pushdef(),
+dnl popdef(). /usr/5bin/m4 is a SysV style m4 which should always be
+dnl available, and "configure" will reject /usr/bin/m4 in favour of
+dnl /usr/5bin/m4 (if necessary).
+dnl
+dnl The sparc code actually has modest m4 requirements currently and
+dnl could manage with /usr/bin/m4, but there's no reason to put our
+dnl macros through contortions when /usr/5bin/m4 is available or GNU
+dnl m4 can be installed.
+
+
+ifdef(`__ASM_DEFS_M4_INCLUDED__',
+`m4_error(`asm-defs.m4 already included, dont include it twice
+')m4exit(1)')
+define(`__ASM_DEFS_M4_INCLUDED__')
+
+
+dnl Detect and give a message about the unsuitable OpenBSD 2.6 m4.
+
+ifelse(eval(89),89,,
+`errprint(
+`This m4 doesnt accept 8 and/or 9 in constants in eval(), making it unusable.
+This is probably OpenBSD 2.6 m4 (September 1999). Upgrade to OpenBSD 2.7,
+or get a bug fix from the CVS (expr.c rev 1.9), or get GNU m4. Dont forget
+to configure with M4=/wherever/m4 if you install one of these in a directory
+not in $PATH.
+')m4exit(1)')
+
+
+dnl Detect and give a message about the unsuitable SunOS /usr/bin/m4.
+dnl
+dnl Unfortunately this test doesn't work when m4 is run in the normal way
+dnl from mpn/Makefile with "m4 -DOPERATION_foo foo.asm", since the bad m4
+dnl takes "-" in "-D..." to mean read stdin, so it will look like it just
+dnl hangs. But running "m4 asm-defs.m4" to try it out will work.
+dnl
+dnl We'd like to abort immediately on finding a problem, but unfortunately
+dnl the bad m4 doesn't have an m4exit(), nor does an invalid eval() kill
+dnl it. Unexpanded $#'s in some m4_assert_numargs() later on will comment
+dnl out some closing parentheses and kill it with "m4: arg stack overflow".
+
+define(m4_dollarhash_works_test,``$#'')
+ifelse(m4_dollarhash_works_test(x),1,,
+`errprint(
+`This m4 doesnt support $# and cant be used for GMP asm processing.
+If this is on SunOS, ./configure should choose /usr/5bin/m4 if you have that
+or can get it, otherwise install GNU m4. Dont forget to configure with
+M4=/wherever/m4 if you install in a directory not in $PATH.
+')')
+undefine(`m4_dollarhash_works_test')
+
+
+dnl --------------------------------------------------------------------------
+dnl Basic error handling things.
+
+
+dnl Usage: m4_dollarhash_1_if_noparen_p
+dnl
+dnl Expand to 1 if a call "foo" gives $# set to 1 (as opposed to 0 like GNU
+dnl and SysV m4 give).
+
+define(m4_dollarhash_1_if_noparen_test,`$#')
+define(m4_dollarhash_1_if_noparen_p,
+eval(m4_dollarhash_1_if_noparen_test==1))
+undefine(`m4_dollarhash_1_if_noparen_test')
+
+
+dnl Usage: m4wrap_prepend(string)
+dnl
+dnl Prepend the given string to what will be expanded under m4wrap at the
+dnl end of input.
+dnl
+dnl This macro exists to work around variations in m4wrap() behaviour in
+dnl the various m4s (notes at the start of this file). Don't use m4wrap()
+dnl directly since it will interfere with this scheme.
+
+define(m4wrap_prepend,
+m4_assert_numargs(1)
+`define(`m4wrap_string',`$1'defn(`m4wrap_string'))')
+
+define(m4wrap_string,`')
+
+define(m4wrap_works_p,
+`ifelse(M4WRAP_SPURIOUS,yes,0,1)')
+
+ifelse(m4wrap_works_p,1,
+`m4wrap(`m4wrap_string')')
+
+
+dnl Usage: m4_file_and_line
+dnl
+dnl Expand to the current file and line number, if the GNU m4 extensions
+dnl __file__ and __line__ are available.
+dnl
+dnl In GNU m4 1.4 at the end of input when m4wrap text is expanded,
+dnl __file__ is NONE and __line__ is 0, which is not a helpful thing to
+dnl print. If m4_file_seen() has been called to note the last file seen,
+dnl then that file at a big line number is used, otherwise "end of input"
+dnl is used (although "end of input" won't parse as an error message).
+
+define(m4_file_and_line,
+`ifdef(`__file__',
+`ifelse(__file__`'__line__,`NONE0',
+`ifdef(`m4_file_seen_last',`m4_file_seen_last: 999999: ',`end of input: ')',
+`__file__: __line__: ')')')
+
+
+dnl Usage: m4_errprint_commas(arg,...)
+dnl
+dnl The same as errprint(), but commas are printed between arguments
+dnl instead of spaces.
+
+define(m4_errprint_commas,
+`errprint(`$1')dnl
+ifelse(eval($#>1),1,`errprint(`,')m4_errprint_commas(shift($@))')')
+
+
+dnl Usage: m4_error(args...)
+dnl m4_warning(args...)
+dnl
+dnl Print an error message, using m4_errprint_commas, prefixed with the
+dnl current filename and line number (if available). m4_error sets up to
+dnl give an error exit at the end of processing, m4_warning just prints.
+dnl These macros are the recommended way to print errors.
+dnl
+dnl The arguments here should be quoted in the usual way to prevent them
+dnl being expanded when the macro call is read. (m4_error takes care not
+dnl to do any further expansion.)
+dnl
+dnl For example,
+dnl
+dnl m4_error(`some error message
+dnl ')
+dnl
+dnl which prints
+dnl
+dnl foo.asm:123: some error message
+dnl
+dnl or if __file__ and __line__ aren't available
+dnl
+dnl some error message
+dnl
+dnl The "file:line:" format is a basic style, used by gcc and GNU m4, so
+dnl emacs and other editors will recognise it in their normal error message
+dnl parsing.
+
+define(m4_warning,
+`m4_errprint_commas(m4_file_and_line`'$@)')
+
+define(m4_error,
+`define(`m4_error_occurred',1)m4_warning($@)dnl
+ifelse(m4wrap_works_p,0,`m4exit(1)')')
+
+define(`m4_error_occurred',0)
+
+dnl This m4wrap_prepend() is first, so it'll be executed last.
+m4wrap_prepend(
+`ifelse(m4_error_occurred,1,
+`m4_error(`Errors occurred during m4 processing
+')m4exit(1)')')
+
+
+dnl Usage: m4_assert_numargs(num)
+dnl
+dnl Put this unquoted on a line on its own at the start of a macro
+dnl definition to add some code to check that num many arguments get passed
+dnl to the macro. For example,
+dnl
+dnl define(foo,
+dnl m4_assert_numargs(2)
+dnl `something `$1' and `$2' blah blah')
+dnl
+dnl Then a call like foo(one,two,three) will provoke an error like
+dnl
+dnl file:10: foo expected 2 arguments, got 3 arguments
+dnl
+dnl Here are some calls and how many arguments they're interpreted as passing.
+dnl
+dnl foo(abc,def) 2
+dnl foo(xyz) 1
+dnl foo() 0
+dnl foo -1
+dnl
+dnl The -1 for no parentheses at all means a macro that's meant to be used
+dnl that way can be checked with m4_assert_numargs(-1). For example,
+dnl
+dnl define(SPECIAL_SUFFIX,
+dnl m4_assert_numargs(-1)
+dnl `ifdef(`FOO',`_foo',`_bar')')
+dnl
+dnl But as an alternative see also deflit() below where parenthesized
+dnl expressions following a macro are passed through to the output.
+dnl
+dnl Note that in BSD m4 there's no way to differentiate calls "foo" and
+dnl "foo()", so in BSD m4 the distinction between the two isn't enforced.
+dnl (In GNU and SysV m4 it can be checked, and is.)
+
+
+dnl m4_assert_numargs is able to check its own arguments by calling
+dnl assert_numargs_internal directly.
+dnl
+dnl m4_doublequote($`'0) expands to ``$0'', whereas ``$`'0'' would expand
+dnl to `$`'0' and do the wrong thing, and likewise for $1. The same is
+dnl done in other assert macros.
+dnl
+dnl $`#' leaves $# in the new macro being defined, and stops # being
+dnl interpreted as a comment character.
+dnl
+dnl `dnl ' means an explicit dnl isn't necessary when m4_assert_numargs is
+dnl used. The space means that if there is a dnl it'll still work.
+
+dnl Usage: m4_doublequote(x) expands to ``x''
+define(m4_doublequote,
+`m4_assert_numargs_internal(`$0',1,$#,len(`$1'))``$1''')
+
+define(m4_assert_numargs,
+`m4_assert_numargs_internal(`$0',1,$#,len(`$1'))dnl
+`m4_assert_numargs_internal'(m4_doublequote($`'0),$1,$`#',`len'(m4_doublequote($`'1)))`dnl '')
+
+dnl Called: m4_assert_numargs_internal(`macroname',wantargs,$#,len(`$1'))
+define(m4_assert_numargs_internal,
+`m4_assert_numargs_internal_check(`$1',`$2',m4_numargs_count(`$3',`$4'))')
+
+dnl Called: m4_assert_numargs_internal_check(`macroname',wantargs,gotargs)
+dnl
+dnl If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
+dnl should be -1. If wantargs is -1 but gotargs is 0 and the two can't be
+dnl distinguished then it's allowed to pass.
+dnl
+define(m4_assert_numargs_internal_check,
+`ifelse(eval($2 == $3
+ || ($2==-1 && $3==0 && m4_dollarhash_1_if_noparen_p)),0,
+`m4_error(`$1 expected 'm4_Narguments(`$2')`, got 'm4_Narguments(`$3')
+)')')
+
+dnl Called: m4_numargs_count($#,len(`$1'))
+dnl If $#==0 then -1 args, if $#==1 but len(`$1')==0 then 0 args, otherwise
+dnl $# args.
+define(m4_numargs_count,
+`ifelse($1,0, -1,
+`ifelse(eval($1==1 && $2-0==0),1, 0, $1)')')
+
+dnl Usage: m4_Narguments(N)
+dnl "$1 argument" or "$1 arguments" with the plural according to $1.
+define(m4_Narguments,
+`$1 argument`'ifelse(`$1',1,,s)')
+
+
+dnl --------------------------------------------------------------------------
+dnl Additional error checking things.
+
+
+dnl Usage: m4_file_seen()
+dnl
+dnl Record __file__ for the benefit of m4_file_and_line in m4wrap text.
+dnl
+dnl The basic __file__ macro comes out quoted in GNU m4, like `foo.asm',
+dnl and m4_file_seen_last is defined like that too.
+dnl
+dnl This is used by PROLOGUE, since that's normally in the main .asm file,
+dnl and in particular it sets up m4wrap error checks for missing EPILOGUE.
+
+define(m4_file_seen,
+m4_assert_numargs(0)
+`ifelse(__file__,`NONE',,
+`define(`m4_file_seen_last',m4_doublequote(__file__))')')
+
+
+dnl Usage: m4_assert_onearg()
+dnl
+dnl Put this, unquoted, at the start of a macro definition to add some code
+dnl to check that one argument is passed to the macro, but with that
+dnl argument allowed to be empty. For example,
+dnl
+dnl define(foo,
+dnl m4_assert_onearg()
+dnl `blah blah $1 blah blah')
+dnl
+dnl Calls "foo(xyz)" or "foo()" are accepted. A call "foo(xyz,abc)" fails.
+dnl A call "foo" fails too, but BSD m4 can't detect this case (GNU and SysV
+dnl m4 can).
+
+define(m4_assert_onearg,
+m4_assert_numargs(0)
+`m4_assert_onearg_internal'(m4_doublequote($`'0),$`#')`dnl ')
+
+dnl Called: m4_assert_onearg(`macroname',$#)
+define(m4_assert_onearg_internal,
+`ifelse($2,1,,
+`m4_error(`$1 expected 1 argument, got 'm4_Narguments(`$2')
+)')')
+
+
+dnl Usage: m4_assert_numargs_range(low,high)
+dnl
+dnl Put this, unquoted, at the start of a macro definition to add some code
+dnl to check that between low and high many arguments get passed to the
+dnl macro. For example,
+dnl
+dnl define(foo,
+dnl m4_assert_numargs_range(3,5)
+dnl `mandatory $1 $2 $3 optional $4 $5 end')
+dnl
+dnl See m4_assert_numargs() for more info.
+
+define(m4_assert_numargs_range,
+m4_assert_numargs(2)
+``m4_assert_numargs_range_internal'(m4_doublequote($`'0),$1,$2,$`#',`len'(m4_doublequote($`'1)))`dnl '')
+
+dnl Called: m4_assert_numargs_range_internal(`name',low,high,$#,len(`$1'))
+define(m4_assert_numargs_range_internal,
+m4_assert_numargs(5)
+`m4_assert_numargs_range_check(`$1',`$2',`$3',m4_numargs_count(`$4',`$5'))')
+
+dnl Called: m4_assert_numargs_range_check(`name',low,high,gotargs)
+dnl
+dnl If m4_dollarhash_1_if_noparen_p (BSD m4) then gotargs can be 0 when it
+dnl should be -1. To ensure a `high' of -1 works, a fudge is applied to
+dnl gotargs if it's 0 and the 0 and -1 cases can't be distinguished.
+dnl
+define(m4_assert_numargs_range_check,
+m4_assert_numargs(4)
+`ifelse(eval($2 <= $4 &&
+ ($4 - ($4==0 && m4_dollarhash_1_if_noparen_p) <= $3)),0,
+`m4_error(`$1 expected $2 to $3 arguments, got 'm4_Narguments(`$4')
+)')')
+
+
+dnl Usage: m4_assert_defined(symbol)
+dnl
+dnl Put this unquoted on a line of its own at the start of a macro
+dnl definition to add some code to check that the given symbol is defined
+dnl when the macro is used. For example,
+dnl
+dnl define(foo,
+dnl m4_assert_defined(`FOO_PREFIX')
+dnl `FOO_PREFIX whatever')
+dnl
+dnl This is a convenient way to check that the user or ./configure or
+dnl whatever has defined the things needed by a macro, as opposed to
+dnl silently generating garbage.
+
+define(m4_assert_defined,
+m4_assert_numargs(1)
+``m4_assert_defined_internal'(m4_doublequote($`'0),``$1'')`dnl '')
+
+dnl Called: m4_assert_defined_internal(`macroname',`define_required')
+define(m4_assert_defined_internal,
+m4_assert_numargs(2)
+`m4_ifdef(`$2',,
+`m4_error(`$1 needs $2 defined
+')')')
+
+
+dnl Usage: m4_not_for_expansion(`SYMBOL')
+dnl define_not_for_expansion(`SYMBOL')
+dnl
+dnl m4_not_for_expansion turns SYMBOL, if defined, into something which
+dnl will give an error if expanded. For example,
+dnl
+dnl m4_not_for_expansion(`PIC')
+dnl
+dnl define_not_for_expansion is the same, but always makes a definition.
+dnl
+dnl These are for symbols that should be tested with ifdef(`FOO',...)
+dnl rather than be expanded as such. They guard against accidentally
+dnl omitting the quotes, as in ifdef(FOO,...). Note though that they only
+dnl catches this when FOO is defined, so be sure to test code both with and
+dnl without each definition.
+
+define(m4_not_for_expansion,
+m4_assert_numargs(1)
+`ifdef(`$1',`define_not_for_expansion(`$1')')')
+
+define(define_not_for_expansion,
+m4_assert_numargs(1)
+`ifelse(defn(`$1'),,,
+`m4_error(``$1' has a non-empty value, maybe it shouldnt be munged with m4_not_for_expansion()
+')')dnl
+define(`$1',`m4_not_for_expansion_internal(`$1')')')
+
+define(m4_not_for_expansion_internal,
+`m4_error(``$1' is not meant to be expanded, perhaps you mean `ifdef(`$1',...)'
+')')
+
+
+dnl --------------------------------------------------------------------------
+dnl Various generic m4 things.
+
+
+dnl Usage: m4_unquote(macro)
+dnl
+dnl Allow the argument text to be re-evaluated. This is useful for "token
+dnl pasting" like m4_unquote(foo`'bar).
+
+define(m4_unquote,
+m4_assert_onearg()
+`$1')
+
+
+dnl Usage: m4_ifdef(name,yes[,no])
+dnl
+dnl Expand to the yes argument if name is defined, or to the no argument if
+dnl not.
+dnl
+dnl This is the same as the builtin "ifdef", but avoids an OSF 4.0 m4 bug
+dnl in which a macro with a zero value `0' or `00' etc is considered not
+dnl defined.
+dnl
+dnl There's no particular need to use this everywhere, only if there might
+dnl be a zero value.
+
+define(m4_ifdef,
+m4_assert_numargs_range(2,3)
+`ifelse(eval(ifdef(`$1',1,0)+m4_length(defn(`$1'))),0,
+`$3',`$2')')
+
+
+dnl Usage: m4_ifdef_anyof_p(`symbol',...)
+dnl
+dnl Expand to 1 if any of the symbols in the argument list are defined, or
+dnl to 0 if not.
+
+define(m4_ifdef_anyof_p,
+`ifelse(eval($#<=1 && m4_length(`$1')==0),1, 0,
+`ifdef(`$1', 1,
+`m4_ifdef_anyof_p(shift($@))')')')
+
+
+dnl Usage: m4_length(string)
+dnl
+dnl Determine the length of a string. This is the same as len(), but
+dnl always expands to a number, working around the BSD len() which
+dnl evaluates to nothing given an empty argument.
+
+define(m4_length,
+m4_assert_onearg()
+`eval(len(`$1')-0)')
+
+
+dnl Usage: m4_stringequal_p(x,y)
+dnl
+dnl Expand to 1 or 0 according as strings x and y are equal or not.
+
+define(m4_stringequal_p,
+`ifelse(`$1',`$2',1,0)')
+
+
+dnl Usage: m4_incr_or_decr(n,last)
+dnl
+dnl Do an incr(n) or decr(n), whichever is in the direction of "last".
+dnl Both n and last must be numbers of course.
+
+define(m4_incr_or_decr,
+m4_assert_numargs(2)
+`ifelse(eval($1<$2),1,incr($1),decr($1))')
+
+
+dnl Usage: forloop(i, first, last, statement)
+dnl
+dnl Based on GNU m4 examples/forloop.m4, but extended.
+dnl
+dnl statement is expanded repeatedly, with i successively defined as
+dnl
+dnl first, first+1, ..., last-1, last
+dnl
+dnl Or if first > last, then it's
+dnl
+dnl first, first-1, ..., last+1, last
+dnl
+dnl If first == last, then one expansion is done.
+dnl
+dnl A pushdef/popdef of i is done to preserve any previous definition (or
+dnl lack of definition). first and last are eval()ed and so can be
+dnl expressions.
+dnl
+dnl forloop_first is defined to 1 on the first iteration, 0 on the rest.
+dnl forloop_last is defined to 1 on the last iteration, 0 on the others.
+dnl Nested forloops are allowed, in which case forloop_first and
+dnl forloop_last apply to the innermost loop that's open.
+dnl
+dnl A simple example,
+dnl
+dnl forloop(i, 1, 2*2+1, `dnl
+dnl iteration number i ... ifelse(forloop_first,1,FIRST)
+dnl ')
+
+
+dnl "i" and "statement" are carefully quoted, but "first" and "last" are
+dnl just plain numbers once eval()ed.
+
+define(`forloop',
+m4_assert_numargs(4)
+`pushdef(`$1',eval(`$2'))dnl
+pushdef(`forloop_first',1)dnl
+pushdef(`forloop_last',0)dnl
+forloop_internal(`$1',eval(`$3'),`$4')`'dnl
+popdef(`forloop_first')dnl
+popdef(`forloop_last')dnl
+popdef(`$1')')
+
+dnl Called: forloop_internal(`var',last,statement)
+define(`forloop_internal',
+m4_assert_numargs(3)
+`ifelse($1,$2,
+`define(`forloop_last',1)$3',
+`$3`'dnl
+define(`forloop_first',0)dnl
+define(`$1',m4_incr_or_decr($1,$2))dnl
+forloop_internal(`$1',$2,`$3')')')
+
+
+dnl Usage: foreach(var,body, item1,item2,...,itemN)
+dnl
+dnl For each "item" argument, define "var" to that value and expand "body".
+dnl For example,
+dnl
+dnl foreach(i, `something i
+dnl ', one, two)
+dnl gives
+dnl something one
+dnl something two
+dnl
+dnl Any previous definition of "var", or lack thereof, is saved and
+dnl restored. Empty "item"s are not allowed.
+
+define(foreach,
+m4_assert_numargs_range(2,1000)
+`ifelse(`$3',,,
+`pushdef(`$1',`$3')$2`'popdef(`$1')dnl
+foreach(`$1',`$2',shift(shift(shift($@))))')')
+
+
+dnl Usage: m4_toupper(x)
+dnl m4_tolower(x)
+dnl
+dnl Convert the argument string to upper or lower case, respectively.
+dnl Only one argument accepted.
+dnl
+dnl BSD m4 doesn't take ranges like a-z in translit(), so the full alphabet
+dnl is written out.
+
+define(m4_alphabet_lower, `abcdefghijklmnopqrstuvwxyz')
+define(m4_alphabet_upper, `ABCDEFGHIJKLMNOPQRSTUVWXYZ')
+
+define(m4_toupper,
+m4_assert_onearg()
+`translit(`$1', m4_alphabet_lower, m4_alphabet_upper)')
+
+define(m4_tolower,
+m4_assert_onearg()
+`translit(`$1', m4_alphabet_upper, m4_alphabet_lower)')
+
+
+dnl Usage: m4_empty_if_zero(x)
+dnl
+dnl Evaluate to x, or to nothing if x is 0. x is eval()ed and so can be an
+dnl expression.
+dnl
+dnl This is useful for x86 addressing mode displacements since forms like
+dnl (%ebx) are one byte shorter than 0(%ebx). A macro `foo' for use as
+dnl foo(%ebx) could be defined with the following so it'll be empty if the
+dnl expression comes out zero.
+dnl
+dnl deflit(`foo', `m4_empty_if_zero(a+b*4-c)')
+dnl
+dnl Naturally this shouldn't be done if, say, a computed jump depends on
+dnl the code being a particular size.
+
+define(m4_empty_if_zero,
+m4_assert_onearg()
+`ifelse(eval($1),0,,eval($1))')
+
+
+dnl Usage: m4_log2(x)
+dnl
+dnl Calculate a logarithm to base 2.
+dnl x must be an integral power of 2, between 2**0 and 2**30.
+dnl x is eval()ed, so it can be an expression.
+dnl An error results if x is invalid.
+dnl
+dnl 2**31 isn't supported, because an unsigned 2147483648 is out of range
+dnl of a 32-bit signed int. Also, the bug in BSD m4 where an eval()
+dnl resulting in 2147483648 (or -2147483648 as the case may be) gives `-('
+dnl means tests like eval(1<<31==(x)) would be necessary, but that then
+dnl gives an unattractive explosion of eval() error messages if x isn't
+dnl numeric.
+
+define(m4_log2,
+m4_assert_numargs(1)
+`m4_log2_internal(0,1,eval(`$1'))')
+
+dnl Called: m4_log2_internal(n,2**n,target)
+define(m4_log2_internal,
+m4_assert_numargs(3)
+`ifelse($2,$3,$1,
+`ifelse($1,30,
+`m4_error(`m4_log2() argument too big or not a power of two: $3
+')',
+`m4_log2_internal(incr($1),eval(2*$2),$3)')')')
+
+
+dnl Usage: m4_div2_towards_zero
+dnl
+dnl m4 division is probably whatever a C signed division is, and C doesn't
+dnl specify what rounding gets used on negatives, so this expression forces
+dnl a rounding towards zero.
+
+define(m4_div2_towards_zero,
+m4_assert_numargs(1)
+`eval((($1) + ((($1)<0) & ($1))) / 2)')
+
+
+dnl Usage: m4_lshift(n,count)
+dnl m4_rshift(n,count)
+dnl
+dnl Calculate n shifted left or right by count many bits. Both n and count
+dnl are eval()ed and so can be expressions.
+dnl
+dnl Negative counts are allowed and mean a shift in the opposite direction.
+dnl Negative n is allowed and right shifts will be arithmetic (meaning
+dnl divide by 2**count, rounding towards zero, also meaning the sign bit is
+dnl duplicated).
+dnl
+dnl Use these macros instead of << and >> in eval() since the basic ccs
+dnl SysV m4 doesn't have those operators.
+
+define(m4_rshift,
+m4_assert_numargs(2)
+`m4_lshift(`$1',-(`$2'))')
+
+define(m4_lshift,
+m4_assert_numargs(2)
+`m4_lshift_internal(eval(`$1'),eval(`$2'))')
+
+define(m4_lshift_internal,
+m4_assert_numargs(2)
+`ifelse(eval($2-0==0),1,$1,
+`ifelse(eval($2>0),1,
+`m4_lshift_internal(eval($1*2),decr($2))',
+`m4_lshift_internal(m4_div2_towards_zero($1),incr($2))')')')
+
+
+dnl Usage: m4_popcount(n)
+dnl
+dnl Expand to the number 1 bits in n.
+
+define(m4_popcount,
+m4_assert_numargs(1)
+`m4_popcount_internal(0,eval(`$1'))')
+
+dnl Called: m4_popcount_internal(count,rem)
+define(m4_popcount_internal,
+m4_assert_numargs(2)
+`ifelse($2,0,$1,
+`m4_popcount_internal(eval($1+($2%2)),eval($2/2))')')
+
+
+dnl Usage: m4_count_trailing_zeros(N)
+dnl
+dnl Determine the number of trailing zero bits on N. N is eval()ed and so
+dnl can be an expression. If N is zero an error is generated.
+
+define(m4_count_trailing_zeros,
+m4_assert_numargs(1)
+`m4_count_trailing_zeros_internal(eval(`$1'),0)')
+
+dnl Called: m4_count_trailing_zeros_internal(val,count)
+define(m4_count_trailing_zeros_internal,
+m4_assert_numargs(2)
+`ifelse($1,0,
+`m4_error(`m4_count_trailing_zeros() given a zero value')',
+`ifelse(eval(($1)%2),1,`$2',
+`m4_count_trailing_zeros_internal(eval($1/2),incr($2))')')')
+
+
+dnl Usage: deflit(name,value)
+dnl
+dnl Like define(), but "name" expands like a literal, rather than taking
+dnl arguments. For example "name(%eax)" expands to "value(%eax)".
+dnl
+dnl Limitations:
+dnl
+dnl $ characters in the value part must have quotes to stop them looking
+dnl like macro parameters. For example, deflit(reg,`123+$`'4+567'). See
+dnl defreg() below for handling simple register definitions like $7 etc.
+dnl
+dnl "name()" is turned into "name", unfortunately. In GNU and SysV m4 an
+dnl error is generated when this happens, but in BSD m4 it will happen
+dnl silently. The problem is that in BSD m4 $# is 1 in both "name" or
+dnl "name()", so there's no way to differentiate them. Because we want
+dnl plain "name" to turn into plain "value", we end up with "name()"
+dnl turning into plain "value" too.
+dnl
+dnl "name(foo)" will lose any whitespace after commas in "foo", for example
+dnl "disp(%eax, %ecx)" would become "128(%eax,%ecx)".
+dnl
+dnl These parentheses oddities shouldn't matter in assembler text, but if
+dnl they do the suggested workaround is to write "name ()" or "name (foo)"
+dnl to stop the parentheses looking like a macro argument list. If a space
+dnl isn't acceptable in the output, then write "name`'()" or "name`'(foo)".
+dnl The `' is stripped when read, but again stops the parentheses looking
+dnl like parameters.
+
+dnl Quoting for deflit_emptyargcheck is similar to m4_assert_numargs. The
+dnl stuff in the ifelse gives a $#, $1 and $@ evaluated in the new macro
+dnl created, not in deflit.
+define(deflit,
+m4_assert_numargs(2)
+`define(`$1',
+`deflit_emptyargcheck'(``$1'',$`#',m4_doublequote($`'1))`dnl
+$2`'dnl
+ifelse(eval($'`#>1 || m4_length('m4_doublequote($`'1)`)!=0),1,($'`@))')')
+
+dnl Called: deflit_emptyargcheck(macroname,$#,`$1')
+define(deflit_emptyargcheck,
+`ifelse(eval($2==1 && !m4_dollarhash_1_if_noparen_p && m4_length(`$3')==0),1,
+`m4_error(`dont use a deflit as $1() because it loses the brackets (see deflit in asm-defs.m4 for more information)
+')')')
+
+
+dnl Usage: m4_assert(`expr')
+dnl
+dnl Test a compile-time requirement with an m4 expression. The expression
+dnl should be quoted, and will be eval()ed and expected to be non-zero.
+dnl For example,
+dnl
+dnl m4_assert(`FOO*2+6 < 14')
+
+define(m4_assert,
+m4_assert_numargs(1)
+`ifelse(eval($1),1,,
+`m4_error(`assertion failed: $1
+')')')
+
+
+dnl Usage: m4_repeat(count,text)
+dnl
+dnl Expand to the given repetitions of the given text. A zero count is
+dnl allowed, and expands to nothing.
+
+define(m4_repeat,
+m4_assert_numargs(2)
+`m4_repeat_internal(eval($1),`$2')')
+
+define(m4_repeat_internal,
+m4_assert_numargs(2)
+`ifelse(`$1',0,,
+`forloop(m4_repeat_internal_counter,1,$1,``$2'')')')
+
+
+dnl Usage: m4_hex_lowmask(bits)
+dnl
+dnl Generate a hex constant which is a low mask of the given number of
+dnl bits. For example m4_hex_lowmask(10) would give 0x3ff.
+
+define(m4_hex_lowmask,
+m4_assert_numargs(1)
+`m4_cpu_hex_constant(m4_hex_lowmask_internal1(eval(`$1')))')
+
+dnl Called: m4_hex_lowmask_internal1(bits)
+define(m4_hex_lowmask_internal1,
+m4_assert_numargs(1)
+`ifelse($1,0,`0',
+`m4_hex_lowmask_internal2(eval(($1)%4),eval(($1)/4))')')
+
+dnl Called: m4_hex_lowmask_internal(remainder,digits)
+define(m4_hex_lowmask_internal2,
+m4_assert_numargs(2)
+`ifelse($1,1,`1',
+`ifelse($1,2,`3',
+`ifelse($1,3,`7')')')dnl
+m4_repeat($2,`f')')
+
+
+dnl --------------------------------------------------------------------------
+dnl The following m4_list functions take a list as multiple arguments.
+dnl Arguments are evaluated multiple times, there's no attempt at strict
+dnl quoting. Empty list elements are not allowed, since an empty final
+dnl argument is ignored. These restrictions don't affect the current uses,
+dnl and make the implementation easier.
+
+
+dnl Usage: m4_list_quote(list,...)
+dnl
+dnl Produce a list with quoted commas, so it can be a single argument
+dnl string. For instance m4_list_quote(a,b,c) gives
+dnl
+dnl a`,'b`,'c`,'
+dnl
+dnl This can be used to put a list in a define,
+dnl
+dnl define(foolist, m4_list_quote(a,b,c))
+dnl
+dnl Which can then be used for instance as
+dnl
+dnl m4_list_find(target, foolist)
+
+define(m4_list_quote,
+`ifelse(`$1',,,
+`$1`,'m4_list_quote(shift($@))')')
+
+
+dnl Usage: m4_list_find(key,list,...)
+dnl
+dnl Evaluate to 1 or 0 according to whether key is in the list elements.
+
+define(m4_list_find,
+m4_assert_numargs_range(1,1000)
+`ifelse(`$2',,0,
+`ifelse(`$1',`$2',1,
+`m4_list_find(`$1',shift(shift($@)))')')')
+
+
+dnl Usage: m4_list_remove(key,list,...)
+dnl
+dnl Evaluate to the given list with `key' removed (if present).
+
+define(m4_list_remove,
+m4_assert_numargs_range(1,1000)
+`ifelse(`$2',,,
+`ifelse(`$1',`$2',,`$2,')dnl
+m4_list_remove(`$1',shift(shift($@)))')')
+
+
+dnl Usage: m4_list_first(list,...)
+dnl
+dnl Evaluate to the first element of the list (if any).
+
+define(m4_list_first,`$1')
+
+
+dnl Usage: m4_list_count(list,...)
+dnl
+dnl Evaluate to the number of elements in the list. This can't just use $#
+dnl because the last element might be empty.
+
+define(m4_list_count,
+`m4_list_count_internal(0,$@)')
+
+dnl Called: m4_list_internal(count,list,...)
+define(m4_list_count_internal,
+m4_assert_numargs_range(1,1000)
+`ifelse(`$2',,$1,
+`m4_list_count_internal(eval($1+1),shift(shift($@)))')')
+
+
+dnl --------------------------------------------------------------------------
+dnl Various assembler things, not specific to any particular CPU.
+dnl
+
+
+dnl Usage: include_mpn(`filename')
+dnl
+dnl Like include(), but adds a path to the mpn source directory. For
+dnl example,
+dnl
+dnl include_mpn(`sparc64/addmul_1h.asm')
+
+define(include_mpn,
+m4_assert_numargs(1)
+m4_assert_defined(`CONFIG_TOP_SRCDIR')
+`include(CONFIG_TOP_SRCDIR`/mpn/$1')')
+
+
+dnl Usage: C comment ...
+dnl
+dnl This works like a FORTRAN-style comment character. It can be used for
+dnl comments to the right of assembly instructions, where just dnl would
+dnl remove the newline and concatenate adjacent lines.
+dnl
+dnl C and/or dnl are useful when an assembler doesn't support comments, or
+dnl where different assemblers for a particular CPU need different styles.
+dnl The intermediate ".s" files will end up with no comments, just code.
+dnl
+dnl Using C is not intended to cause offence to anyone who doesn't like
+dnl FORTRAN; but if that happens it's an unexpected bonus.
+dnl
+dnl During development, if comments are wanted in the .s files to help see
+dnl what's expanding where, C can be redefined with something like
+dnl
+dnl define(`C',`#')
+
+define(C, `
+dnl')
+
+
+dnl Normally PIC is defined (or not) by libtool, but it doesn't set it on
+dnl systems which are always PIC. PIC_ALWAYS established in config.m4
+dnl identifies these for us.
+
+ifelse(`PIC_ALWAYS',`yes',`define(`PIC')')
+
+
+dnl Various possible defines passed from the Makefile that are to be tested
+dnl with ifdef() rather than be expanded.
+
+m4_not_for_expansion(`PIC')
+m4_not_for_expansion(`DLL_EXPORT')
+
+dnl aors_n
+m4_not_for_expansion(`OPERATION_add_n')
+m4_not_for_expansion(`OPERATION_sub_n')
+
+dnl aors_err1_n
+m4_not_for_expansion(`OPERATION_add_err1_n')
+m4_not_for_expansion(`OPERATION_sub_err1_n')
+
+dnl aors_err2_n
+m4_not_for_expansion(`OPERATION_add_err2_n')
+m4_not_for_expansion(`OPERATION_sub_err2_n')
+
+dnl aors_err3_n
+m4_not_for_expansion(`OPERATION_add_err3_n')
+m4_not_for_expansion(`OPERATION_sub_err3_n')
+
+dnl aorsmul_1
+m4_not_for_expansion(`OPERATION_addmul_1')
+m4_not_for_expansion(`OPERATION_submul_1')
+
+dnl logops_n
+m4_not_for_expansion(`OPERATION_and_n')
+m4_not_for_expansion(`OPERATION_andn_n')
+m4_not_for_expansion(`OPERATION_nand_n')
+m4_not_for_expansion(`OPERATION_ior_n')
+m4_not_for_expansion(`OPERATION_iorn_n')
+m4_not_for_expansion(`OPERATION_nior_n')
+m4_not_for_expansion(`OPERATION_xor_n')
+m4_not_for_expansion(`OPERATION_xnor_n')
+
+dnl popham
+m4_not_for_expansion(`OPERATION_popcount')
+m4_not_for_expansion(`OPERATION_hamdist')
+
+dnl lorrshift
+m4_not_for_expansion(`OPERATION_lshift')
+m4_not_for_expansion(`OPERATION_rshift')
+
+dnl aorslsh1_n
+m4_not_for_expansion(`OPERATION_addlsh1_n')
+m4_not_for_expansion(`OPERATION_sublsh1_n')
+m4_not_for_expansion(`OPERATION_rsblsh1_n')
+
+dnl aorslsh2_n
+m4_not_for_expansion(`OPERATION_addlsh2_n')
+m4_not_for_expansion(`OPERATION_sublsh2_n')
+m4_not_for_expansion(`OPERATION_rsblsh2_n')
+
+dnl rsh1aors_n
+m4_not_for_expansion(`OPERATION_rsh1add_n')
+m4_not_for_expansion(`OPERATION_rsh1sub_n')
+
+
+dnl Usage: m4_config_gmp_mparam(`symbol')
+dnl
+dnl Check that `symbol' is defined. If it isn't, issue an error and
+dnl terminate immediately. The error message explains that the symbol
+dnl should be in config.m4, copied from gmp-mparam.h.
+dnl
+dnl Termination is immediate since missing say SQR_TOOM2_THRESHOLD can
+dnl lead to infinite loops and endless error messages.
+
+define(m4_config_gmp_mparam,
+m4_assert_numargs(1)
+`ifdef(`$1',,
+`m4_error(`$1 is not defined.
+ "configure" should have extracted this from gmp-mparam.h and put it
+ in config.m4 (or in <cpu>_<file>.asm for a fat binary), but somehow
+ this has failed.
+')m4exit(1)')')
+
+
+dnl Usage: defreg(name,reg)
+dnl
+dnl Give a name to a $ style register. For example,
+dnl
+dnl defreg(foo,$12)
+dnl
+dnl defreg() inserts an extra pair of quotes after the $ so that it's not
+dnl interpreted as an m4 macro parameter, ie. foo is actually $`'12. m4
+dnl strips those quotes when foo is expanded.
+dnl
+dnl deflit() is used to make the new definition, so it will expand
+dnl literally even if followed by parentheses ie. foo(99) will become
+dnl $12(99). (But there's nowhere that would be used is there?)
+dnl
+dnl When making further definitions from existing defreg() macros, remember
+dnl to use defreg() again to protect the $ in the new definitions too. For
+dnl example,
+dnl
+dnl defreg(a0,$4)
+dnl defreg(a1,$5)
+dnl ...
+dnl
+dnl defreg(PARAM_DST,a0)
+dnl
+dnl This is only because a0 is expanding at the time the PARAM_DST
+dnl definition is made, leaving a literal $4 that must be re-quoted. On
+dnl the other hand in something like the following ra is only expanded when
+dnl ret is used and its $`'31 protection will have its desired effect at
+dnl that time.
+dnl
+dnl defreg(ra,$31)
+dnl ...
+dnl define(ret,`j ra')
+dnl
+dnl Note that only $n forms are meant to be used here, and something like
+dnl 128($30) doesn't get protected and will come out wrong.
+
+define(defreg,
+m4_assert_numargs(2)
+`deflit(`$1',
+substr(`$2',0,1)``''substr(`$2',1))')
+
+
+dnl Usage: m4_instruction_wrapper()
+dnl
+dnl Put this, unquoted, on a line on its own, at the start of a macro
+dnl that's a wrapper around an assembler instruction. It adds code to give
+dnl a descriptive error message if the macro is invoked without arguments.
+dnl
+dnl For example, suppose jmp needs to be wrapped,
+dnl
+dnl define(jmp,
+dnl m4_instruction_wrapper()
+dnl m4_assert_numargs(1)
+dnl `.byte 0x42
+dnl .long $1
+dnl nop')
+dnl
+dnl The point of m4_instruction_wrapper is to get a better error message
+dnl than m4_assert_numargs would give if jmp is accidentally used as plain
+dnl "jmp foo" instead of the intended "jmp( foo)". "jmp()" with no
+dnl argument also provokes the error message.
+dnl
+dnl m4_instruction_wrapper should only be used with wrapped instructions
+dnl that take arguments, since obviously something meant to be used as say
+dnl plain "ret" doesn't want to give an error when used that way.
+
+define(m4_instruction_wrapper,
+m4_assert_numargs(0)
+``m4_instruction_wrapper_internal'(m4_doublequote($`'0),dnl
+ifdef(`__file__',`m4_doublequote(__file__)',``the m4 sources''),dnl
+$`#',m4_doublequote($`'1))`dnl'')
+
+dnl Called: m4_instruction_wrapper_internal($0,`filename',$#,$1)
+define(m4_instruction_wrapper_internal,
+`ifelse(eval($3<=1 && m4_length(`$4')==0),1,
+`m4_error(`$1 is a macro replacing that instruction and needs arguments, see $2 for details
+')')')
+
+
+dnl Usage: m4_cpu_hex_constant(string)
+dnl
+dnl Expand to the string prefixed by a suitable `0x' hex marker. This
+dnl should be redefined as necessary for CPUs with different conventions.
+
+define(m4_cpu_hex_constant,
+m4_assert_numargs(1)
+`0x`$1'')
+
+
+dnl Usage: UNROLL_LOG2, UNROLL_MASK, UNROLL_BYTES
+dnl CHUNK_LOG2, CHUNK_MASK, CHUNK_BYTES
+dnl
+dnl When code supports a variable amount of loop unrolling, the convention
+dnl is to define UNROLL_COUNT to the number of limbs processed per loop.
+dnl When testing code this can be varied to see how much the loop overhead
+dnl is costing. For example,
+dnl
+dnl deflit(UNROLL_COUNT, 32)
+dnl
+dnl If the forloop() generating the unrolled loop has a pattern processing
+dnl more than one limb, the convention is to express this with CHUNK_COUNT.
+dnl For example,
+dnl
+dnl deflit(CHUNK_COUNT, 2)
+dnl
+dnl The LOG2, MASK and BYTES definitions below are derived from these COUNT
+dnl definitions. If COUNT is redefined, the LOG2, MASK and BYTES follow
+dnl the new definition automatically.
+dnl
+dnl LOG2 is the log base 2 of COUNT. MASK is COUNT-1, which can be used as
+dnl a bit mask. BYTES is GMP_LIMB_BYTES*COUNT, the number of bytes
+dnl processed in each unrolled loop.
+dnl
+dnl GMP_LIMB_BYTES is defined in a CPU specific m4 include file. It
+dnl exists only so the BYTES definitions here can be common to all CPUs.
+dnl In the actual code for a given CPU, an explicit 4 or 8 may as well be
+dnl used because the code is only for a particular CPU, it doesn't need to
+dnl be general.
+dnl
+dnl Note that none of these macros do anything except give conventional
+dnl names to commonly used things. You still have to write your own
+dnl expressions for a forloop() and the resulting address displacements.
+dnl Something like the following would be typical for 4 bytes per limb.
+dnl
+dnl forloop(`i',0,UNROLL_COUNT-1,`
+dnl deflit(`disp',eval(i*4))
+dnl ...
+dnl ')
+dnl
+dnl Or when using CHUNK_COUNT,
+dnl
+dnl forloop(`i',0,UNROLL_COUNT/CHUNK_COUNT-1,`
+dnl deflit(`disp0',eval(i*CHUNK_COUNT*4))
+dnl deflit(`disp1',eval(disp0+4))
+dnl ...
+dnl ')
+dnl
+dnl Clearly `i' can be run starting from 1, or from high to low or whatever
+dnl best suits.
+
+deflit(UNROLL_LOG2,
+m4_assert_defined(`UNROLL_COUNT')
+`m4_log2(UNROLL_COUNT)')
+
+deflit(UNROLL_MASK,
+m4_assert_defined(`UNROLL_COUNT')
+`eval(UNROLL_COUNT-1)')
+
+deflit(UNROLL_BYTES,
+m4_assert_defined(`UNROLL_COUNT')
+m4_assert_defined(`GMP_LIMB_BYTES')
+`eval(UNROLL_COUNT * GMP_LIMB_BYTES)')
+
+deflit(CHUNK_LOG2,
+m4_assert_defined(`CHUNK_COUNT')
+`m4_log2(CHUNK_COUNT)')
+
+deflit(CHUNK_MASK,
+m4_assert_defined(`CHUNK_COUNT')
+`eval(CHUNK_COUNT-1)')
+
+deflit(CHUNK_BYTES,
+m4_assert_defined(`CHUNK_COUNT')
+m4_assert_defined(`GMP_LIMB_BYTES')
+`eval(CHUNK_COUNT * GMP_LIMB_BYTES)')
+
+
+dnl Usage: MPN(name)
+dnl
+dnl Add MPN_PREFIX to a name.
+dnl MPN_PREFIX defaults to "__gmpn_" if not defined.
+dnl
+dnl m4_unquote is used in MPN so that when it expands to say __gmpn_foo,
+dnl that identifier will be subject to further macro expansion. This is
+dnl used by some of the fat binary support for renaming symbols.
+
+ifdef(`MPN_PREFIX',,
+`define(`MPN_PREFIX',`__gmpn_')')
+
+define(MPN,
+m4_assert_numargs(1)
+`m4_unquote(MPN_PREFIX`'$1)')
+
+
+dnl Usage: mpn_add_n, etc
+dnl
+dnl Convenience definitions using MPN(), like the #defines in gmp.h. Each
+dnl function that might be implemented in assembler is here.
+
+define(define_mpn,
+m4_assert_numargs(1)
+`deflit(`mpn_$1',`MPN(`$1')')')
+
+define_mpn(add)
+define_mpn(add_1)
+define_mpn(add_err1_n)
+define_mpn(add_err2_n)
+define_mpn(add_err3_n)
+define_mpn(add_n)
+define_mpn(add_nc)
+define_mpn(addlsh1_n)
+define_mpn(addlsh1_nc)
+define_mpn(addlsh2_n)
+define_mpn(addlsh2_nc)
+define_mpn(addlsh_n)
+define_mpn(addlsh_nc)
+define_mpn(addlsh1_n_ip1)
+define_mpn(addlsh1_nc_ip1)
+define_mpn(addlsh2_n_ip1)
+define_mpn(addlsh2_nc_ip1)
+define_mpn(addlsh_n_ip1)
+define_mpn(addlsh_nc_ip1)
+define_mpn(addlsh1_n_ip2)
+define_mpn(addlsh1_nc_ip2)
+define_mpn(addlsh2_n_ip2)
+define_mpn(addlsh2_nc_ip2)
+define_mpn(addlsh_n_ip2)
+define_mpn(addlsh_nc_ip2)
+define_mpn(addmul_1)
+define_mpn(addmul_1c)
+define_mpn(addmul_2)
+define_mpn(addmul_3)
+define_mpn(addmul_4)
+define_mpn(addmul_5)
+define_mpn(addmul_6)
+define_mpn(addmul_7)
+define_mpn(addmul_8)
+define_mpn(addmul_2s)
+define_mpn(add_n_sub_n)
+define_mpn(add_n_sub_nc)
+define_mpn(addaddmul_1msb0)
+define_mpn(and_n)
+define_mpn(andn_n)
+define_mpn(bdiv_q_1)
+define_mpn(pi1_bdiv_q_1)
+define_mpn(bdiv_dbm1c)
+define_mpn(cmp)
+define_mpn(cnd_add_n)
+define_mpn(cnd_sub_n)
+define_mpn(com)
+define_mpn(copyd)
+define_mpn(copyi)
+define_mpn(count_leading_zeros)
+define_mpn(count_trailing_zeros)
+define_mpn(div_qr_1n_pi1)
+define_mpn(div_qr_2)
+define_mpn(div_qr_2n_pi1)
+define_mpn(div_qr_2u_pi1)
+define_mpn(div_qr_2n_pi2)
+define_mpn(div_qr_2u_pi2)
+define_mpn(divexact_1)
+define_mpn(divexact_by3c)
+define_mpn(divrem)
+define_mpn(divrem_1)
+define_mpn(divrem_1c)
+define_mpn(divrem_2)
+define_mpn(divrem_classic)
+define_mpn(divrem_newton)
+define_mpn(dump)
+define_mpn(gcd)
+define_mpn(gcd_1)
+define_mpn(gcdext)
+define_mpn(get_str)
+define_mpn(hamdist)
+define_mpn(invert_limb)
+define_mpn(invert_limb_table)
+define_mpn(ior_n)
+define_mpn(iorn_n)
+define_mpn(lshift)
+define_mpn(lshiftc)
+define_mpn(mod_1_1p)
+define_mpn(mod_1_1p_cps)
+define_mpn(mod_1s_2p)
+define_mpn(mod_1s_2p_cps)
+define_mpn(mod_1s_3p)
+define_mpn(mod_1s_3p_cps)
+define_mpn(mod_1s_4p)
+define_mpn(mod_1s_4p_cps)
+define_mpn(mod_1)
+define_mpn(mod_1c)
+define_mpn(mod_34lsub1)
+define_mpn(modexact_1_odd)
+define_mpn(modexact_1c_odd)
+define_mpn(mul)
+define_mpn(mul_1)
+define_mpn(mul_1c)
+define_mpn(mul_2)
+define_mpn(mul_3)
+define_mpn(mul_4)
+define_mpn(mul_5)
+define_mpn(mul_6)
+define_mpn(mul_basecase)
+define_mpn(mul_n)
+define_mpn(mullo_basecase)
+define_mpn(mulmid_basecase)
+define_mpn(perfect_square_p)
+define_mpn(popcount)
+define_mpn(preinv_divrem_1)
+define_mpn(preinv_mod_1)
+define_mpn(nand_n)
+define_mpn(neg)
+define_mpn(nior_n)
+define_mpn(powm)
+define_mpn(powlo)
+define_mpn(random)
+define_mpn(random2)
+define_mpn(redc_1)
+define_mpn(redc_2)
+define_mpn(rsblsh1_n)
+define_mpn(rsblsh1_nc)
+define_mpn(rsblsh2_n)
+define_mpn(rsblsh2_nc)
+define_mpn(rsblsh_n)
+define_mpn(rsblsh_nc)
+define_mpn(rsh1add_n)
+define_mpn(rsh1add_nc)
+define_mpn(rsh1sub_n)
+define_mpn(rsh1sub_nc)
+define_mpn(rshift)
+define_mpn(rshiftc)
+define_mpn(scan0)
+define_mpn(scan1)
+define_mpn(set_str)
+define_mpn(sqr_basecase)
+define_mpn(sqr_diagonal)
+define_mpn(sqr_diag_addlsh1)
+define_mpn(sub_n)
+define_mpn(sublsh1_n)
+define_mpn(sublsh1_nc)
+define_mpn(sublsh1_n_ip1)
+define_mpn(sublsh1_nc_ip1)
+define_mpn(sublsh2_n)
+define_mpn(sublsh2_nc)
+define_mpn(sublsh2_n_ip1)
+define_mpn(sublsh2_nc_ip1)
+define_mpn(sublsh_n)
+define_mpn(sublsh_nc)
+define_mpn(sublsh_n_ip1)
+define_mpn(sublsh_nc_ip1)
+define_mpn(sqrtrem)
+define_mpn(sub)
+define_mpn(sub_1)
+define_mpn(sub_err1_n)
+define_mpn(sub_err2_n)
+define_mpn(sub_err3_n)
+define_mpn(sub_n)
+define_mpn(sub_nc)
+define_mpn(submul_1)
+define_mpn(submul_1c)
+define_mpn(sec_tabselect)
+define_mpn(umul_ppmm)
+define_mpn(umul_ppmm_r)
+define_mpn(udiv_qrnnd)
+define_mpn(udiv_qrnnd_r)
+define_mpn(xnor_n)
+define_mpn(xor_n)
+
+
+dnl Defines for C global arrays and variables, with names matching what's
+dnl used in the C code.
+dnl
+dnl Notice that GSYM_PREFIX is included, unlike with the function defines
+dnl above. Also, "deflit" is used so that something like __clz_tab(%ebx)
+dnl comes out as __gmpn_clz_tab(%ebx), for the benefit of CPUs with that
+dnl style assembler syntax.
+
+deflit(__clz_tab,
+m4_assert_defined(`GSYM_PREFIX')
+`GSYM_PREFIX`'MPN(`clz_tab')')
+
+deflit(binvert_limb_table,
+m4_assert_defined(`GSYM_PREFIX')
+`GSYM_PREFIX`'__gmp_binvert_limb_table')
+
+
+dnl Usage: ASM_START()
+dnl
+dnl Emit any directives needed once at the start of an assembler file, like
+dnl ".set noreorder" or whatever. The default for this is nothing, but
+dnl it's redefined by CPU specific m4 files.
+
+define(ASM_START)
+
+
+dnl Usage: ASM_END()
+dnl
+dnl Emit any directives needed once at the end of an assembler file. The
+dnl default for this is nothing, but it's redefined by CPU specific m4 files.
+
+define(ASM_END)
+
+
+dnl Usage: PROLOGUE(foo[,param])
+dnl EPILOGUE(foo)
+dnl
+dnl Emit directives to start or end a function. GSYM_PREFIX is added by
+dnl these macros if necessary, so the given "foo" is what the function will
+dnl be called in C.
+dnl
+dnl The second parameter to PROLOGUE is used only for some CPUs and should
+dnl be omitted if not required.
+dnl
+dnl Nested or overlapping PROLOGUE/EPILOGUE pairs are allowed, if that
+dnl makes sense for the system. The name given to EPILOGUE must be a
+dnl currently open PROLOGUE.
+dnl
+dnl If only one PROLOGUE is open then the name can be omitted from
+dnl EPILOGUE. This is encouraged, since it means the name only has to
+dnl appear in one place, not two.
+dnl
+dnl The given name "foo" is not fully quoted here, it will be macro
+dnl expanded more than once. This is the way the m4_list macros work, and
+dnl it also helps the tune/many.pl program do a renaming like
+dnl -D__gmpn_add_n=mpn_add_n_foo when GSYM_PREFIX is not empty.
+
+define(PROLOGUE,
+m4_assert_numargs_range(1,2)
+`m4_file_seen()dnl
+define(`PROLOGUE_list',m4_list_quote($1,PROLOGUE_list))dnl
+ifelse(`$2',,
+`PROLOGUE_cpu(GSYM_PREFIX`'$1)',
+`PROLOGUE_cpu(GSYM_PREFIX`'$1,`$2')')')
+
+define(EPILOGUE,
+m4_assert_numargs_range(0,1)
+`ifelse(`$1',,
+`ifelse(m4_list_count(PROLOGUE_list),0,
+`m4_error(`no open functions for EPILOGUE
+')',
+`ifelse(m4_list_count(PROLOGUE_list),1,
+`EPILOGUE_internal(PROLOGUE_current_function)',
+`m4_error(`more than one open function for EPILOGUE
+')')')',
+`EPILOGUE_internal(`$1')')')
+
+define(EPILOGUE_internal,
+m4_assert_numargs(1)
+m4_assert_defined(`EPILOGUE_cpu')
+`ifelse(m4_list_find($1,PROLOGUE_list),0,
+`m4_error(`EPILOGUE without PROLOGUE: $1
+')')dnl
+define(`PROLOGUE_list',m4_list_quote(m4_list_remove($1,PROLOGUE_list)))dnl
+EPILOGUE_cpu(GSYM_PREFIX`$1')')
+
+dnl Currently open PROLOGUEs, as a comma-separated list.
+define(PROLOGUE_list)
+
+
+dnl Called: PROLOGUE_check(list,...)
+dnl Check there's no remaining open PROLOGUEs at the end of input.
+define(PROLOGUE_check,
+`ifelse($1,,,
+`m4_error(`no EPILOGUE for: $1
+')dnl
+PROLOGUE_check(shift($@))')')
+
+m4wrap_prepend(`PROLOGUE_check(PROLOGUE_list)')
+
+
+dnl Usage: PROLOGUE_current_function
+dnl
+dnl This macro expands to the current PROLOGUE/EPILOGUE function, or the
+dnl most recent PROLOGUE if such pairs are nested or overlapped.
+
+define(PROLOGUE_current_function,
+m4_assert_numargs(-1)
+`m4_list_first(PROLOGUE_list)')
+
+
+dnl Usage: PROLOGUE_cpu(GSYM_PREFIX`'foo[,param])
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+dnl These macros hold the CPU-specific parts of PROLOGUE and EPILOGUE.
+dnl Both are called with the function name, with GSYM_PREFIX already
+dnl prepended.
+dnl
+dnl The definitions here are something typical and sensible, but CPU or
+dnl system specific m4 files should redefine them as necessary. The
+dnl optional extra parameter to PROLOGUE_cpu is not expected and not
+dnl accepted here.
+
+define(PROLOGUE_cpu,
+m4_assert_numargs(1)
+` TEXT
+ ALIGN(8)
+ GLOBL `$1' GLOBL_ATTR
+ TYPE(`$1',`function')
+`$1'LABEL_SUFFIX')
+
+define(EPILOGUE_cpu,
+` SIZE(`$1',.-`$1')')
+
+
+dnl Usage: L(name)
+dnl
+dnl Generate a local label with the given name. This is simply a
+dnl convenient way to add LSYM_PREFIX.
+dnl
+dnl LSYM_PREFIX might be L$, so defn() must be used to quote it or the L
+dnl will expand again as the L macro, making an infinite recursion.
+
+define(`L',
+m4_assert_numargs(1)
+`defn(`LSYM_PREFIX')$1')
+
+
+dnl Usage: LDEF(name)
+dnl
+dnl Generate a directive to define a local label.
+dnl
+dnl On systems with a fixed syntax for defining labels there's no need to
+dnl use this macro, it's only meant for systems where the syntax varies,
+dnl like hppa which is "L(foo):" with gas, but just "L(foo)" in column 0
+dnl with the system `as'.
+dnl
+dnl The extra `' after LABEL_SUFFIX avoids any chance of a following
+dnl "(...)" being interpreted as an argument list. Not that it'd be
+dnl sensible to write anything like that after an LDEF(), but just in case.
+
+define(LDEF,
+m4_assert_numargs(1)
+m4_assert_defined(`LABEL_SUFFIX')
+`L(`$1')`'LABEL_SUFFIX`'')
+
+
+dnl Usage: INT32(label,value)
+dnl INT64(label,first,second)
+
+define(`INT32',
+m4_assert_defined(`W32')
+` ALIGN(4)
+LDEF(`$1')
+ W32 $2')
+
+define(`INT64',
+m4_assert_defined(`W32')
+` ALIGN(8)
+LDEF(`$1')
+ W32 $2
+ W32 $3')
+
+
+dnl Usage: ALIGN(bytes)
+dnl
+dnl Emit a ".align" directive. The alignment is specified in bytes, and
+dnl will normally need to be a power of 2. The actual ".align" generated
+dnl is either bytes or logarithmic according to what ./configure finds the
+dnl assembler needs.
+dnl
+dnl If ALIGN_FILL_0x90 is defined and equal to "yes", then ", 0x90" is
+dnl appended. This is for x86, see mpn/x86/README.
+
+define(ALIGN,
+m4_assert_numargs(1)
+m4_assert_defined(`ALIGN_LOGARITHMIC')
+`.align ifelse(ALIGN_LOGARITHMIC,yes,`m4_log2($1)',`eval($1)')dnl
+ifelse(ALIGN_FILL_0x90,yes,`, 0x90')')
+
+
+dnl Usage: MULFUNC_PROLOGUE(function function...)
+dnl
+dnl A dummy macro which is grepped for by ./configure to know what
+dnl functions a multi-function file is providing. Use this if there aren't
+dnl explicit PROLOGUE()s for each possible function.
+dnl
+dnl Multiple MULFUNC_PROLOGUEs can be used, or just one with the function
+dnl names separated by spaces.
+
+define(`MULFUNC_PROLOGUE',
+m4_assert_numargs(1)
+)
+
+
+dnl Usage: NAILS_SUPPORT(spec spec ...)
+dnl
+dnl A dummy macro which is grepped for by ./configure to know what nails
+dnl are supported in an asm file.
+dnl
+dnl Ranges can be given, or just individual values. Multiple values or
+dnl ranges can be given, separated by spaces. Multiple NAILS_SUPPORT
+dnl declarations work too. Some examples,
+dnl
+dnl NAILS_SUPPORT(1-20)
+dnl NAILS_SUPPORT(1 6 9-12)
+dnl NAILS_SUPPORT(1-10 16-20)
+
+define(NAILS_SUPPORT,
+m4_assert_numargs(1)
+)
+
+
+dnl Usage: ABI_SUPPORT(abi)
+dnl
+dnl A dummy macro which is grepped for by ./configure to know what ABIs
+dnl are supported in an asm file.
+dnl
+dnl If multiple non-standard ABIs are supported, several ABI_SUPPORT
+dnl declarations should be used:
+dnl
+dnl ABI_SUPPORT(FOOABI)
+dnl ABI_SUPPORT(BARABI)
+
+define(ABI_SUPPORT,
+m4_assert_numargs(1)
+)
+
+
+dnl Usage: GMP_NUMB_MASK
+dnl
+dnl A bit mask for the number part of a limb. Eg. with 6 bit nails in a
+dnl 32 bit limb, GMP_NUMB_MASK would be 0x3ffffff.
+
+define(GMP_NUMB_MASK,
+m4_assert_numargs(-1)
+m4_assert_defined(`GMP_NUMB_BITS')
+`m4_hex_lowmask(GMP_NUMB_BITS)')
+
+
+dnl Usage: m4append(`variable',`value-to-append')
+
+define(`m4append',
+`define(`$1', defn(`$1')`$2')
+'
+)
+
+divert`'dnl
diff --git a/gmp/mpn/cpp-ccas b/gmp/mpn/cpp-ccas
new file mode 100755
index 0000000000..25f7cdcbeb
--- /dev/null
+++ b/gmp/mpn/cpp-ccas
@@ -0,0 +1,118 @@
+#!/bin/sh
+#
+# A helper script for Makeasm.am .S.lo rule.
+
+# Copyright 2001 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: cpp-cc --cpp=CPP CC ... file.S ...
+#
+# Process file.S with the given CPP command plus any -D options in the
+# rest of the arguments, then assemble with the given CC plus all
+# arguments.
+#
+# The CPP command must be in a single --cpp= argument, and will be
+# split on whitespace. It should include -I options required.
+#
+# When CC is invoked, file.S is replaced with a temporary .s file
+# which is the CPP output.
+#
+# Any lines starting with "#" are removed from the CPP output, usually
+# these will be #line and #file markers from CPP, but they might also
+# be comments from the .S.
+#
+# To allow parallel builds, the temp file name is based on the .S file
+# name, which will be the output object filename for all uses we put
+# this script to.
+
+CPP=
+CPPDEFS=
+CC=
+S=
+SEEN_O=no
+
+for i in "$@"; do
+ case $i in
+ --cpp=*)
+ CPP=`echo "$i" | sed 's/^--cpp=//'`
+ ;;
+ -D*)
+ CPPDEFS="$CPPDEFS $i"
+ CC="$CC $i"
+ ;;
+ *.S)
+ if test -n "$S"; then
+ echo "Only one .S file permitted"
+ exit 1
+ fi
+ BASENAME=`echo "$i" | sed -e 's/\.S$//' -e 's/^.*[\\/:]//'`
+ S=$i
+ TMP_I=tmp-$BASENAME.i
+ TMP_S=tmp-$BASENAME.s
+ CC="$CC $TMP_S"
+ ;;
+ -o)
+ SEEN_O=yes
+ CC="$CC $i"
+ ;;
+ *)
+ CC="$CC $i"
+ ;;
+ esac
+done
+
+if test -z "$CPP"; then
+ echo "No --cpp specified"
+ exit 1
+fi
+
+if test -z "$S"; then
+ echo "No .S specified"
+ exit 1
+fi
+
+# Libtool adds it's own -o when sending output to .libs/foo.o, but not
+# when just wanting foo.o in the current directory. We need an
+# explicit -o in both cases since we're assembling tmp-foo.s.
+#
+if test $SEEN_O = no; then
+ CC="$CC -o $BASENAME.o"
+fi
+
+echo "$CPP $CPPDEFS $S >$TMP_I"
+$CPP $CPPDEFS $S >$TMP_I || exit
+
+echo "grep -v '^#' $TMP_I >$TMP_S"
+grep -v '^#' $TMP_I >$TMP_S
+
+echo "$CC"
+$CC || exit
+
+# Comment this out to preserve .s intermediates
+rm -f $TMP
diff --git a/gmp/mpn/cray/README b/gmp/mpn/cray/README
new file mode 100644
index 0000000000..3a347d2805
--- /dev/null
+++ b/gmp/mpn/cray/README
@@ -0,0 +1,121 @@
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+
+The code in this directory works for Cray vector systems such as C90,
+J90, T90 (both the CFP variant and the IEEE variant) and SV1. (For
+the T3E and T3D systems, see the `alpha' subdirectory at the same
+level as the directory containing this file.)
+
+The cfp subdirectory is for systems utilizing the traditional Cray
+floating-point format, and the ieee subdirectory is for the newer
+systems that use the IEEE floating-point format.
+
+There are several issues that reduces speed on Cray systems. For
+systems with cfp floating point, the main obstacle is the forming of
+128-bit products. For IEEE systems, adding, and in particular
+computing carry is the main issue. There are no vectorizing
+unsigned-less-than instructions, and the sequence that implement that
+operation is very long.
+
+Shifting is the only operation that is simple to make fast. All Cray
+systems have a bitblt instructions (Vi Vj,Vj<Ak and Vi Vj,Vj>Ak) that
+should be really useful.
+
+For best speed for cfp systems, we need a mul_basecase, since that
+reduces the need for carry propagation to a minimum. Depending on the
+size (vn) of the smaller of the two operands (V), we should split U and V
+in different chunk sizes:
+
+U split in 2 32-bit parts
+V split according to the table:
+parts 4 5 6 7 8
+bits/part 16 13 11 10 8
+max allowed vn 1 8 32 64 256
+number of multiplies 8 10 12 14 16
+peak cycles/limb 4 5 6 7 8
+
+U split in 3 22-bit parts
+V split according to the table:
+parts 3 4 5
+bits/part 22 16 13
+max allowed vn 16 1024 8192
+number of multiplies 9 12 15
+peak cycles/limb 4.5 6 7.5
+
+U split in 4 16-bit parts
+V split according to the table:
+parts 4
+bits/part 16
+max allowed vn 65536
+number of multiplies 16
+peak cycles/limb 8
+
+(A T90 CPU can accumulate two products per cycle.)
+
+IDEA:
+* Rewrite mpn_add_n:
+ short cy[n + 1];
+ #pragma _CRI ivdep
+ for (i = 0; i < n; i++)
+ { s = up[i] + vp[i];
+ rp[i] = s;
+ cy[i + 1] = s < up[i]; }
+ more_carries = 0;
+ #pragma _CRI ivdep
+ for (i = 1; i < n; i++)
+ { s = rp[i] + cy[i];
+ rp[i] = s;
+ more_carries += s < cy[i]; }
+ cys = 0;
+ if (more_carries)
+ {
+ cys = rp[1] < cy[1];
+ for (i = 2; i < n; i++)
+ { rp[i] += cys;
+ cys = rp[i] < cys; }
+ }
+ return cys + cy[n];
+
+* Write mpn_add3_n for adding three operands. First add operands 1
+ and 2, and generate cy[]. Then add operand 3 to the partial result,
+ and accumulate carry into cy[]. Finally propagate carry just like
+ in the new mpn_add_n.
+
+IDEA:
+
+Store fewer bits, perhaps 62, per limb. That brings mpn_add_n time
+down to 2.5 cycles/limb and mpn_addmul_1 times to 4 cycles/limb. By
+storing even fewer bits per limb, perhaps 56, it would be possible to
+write a mul_mul_basecase that would run at effectively 1 cycle/limb.
+(Use VM here to better handle the romb-shaped multiply area, perhaps
+rounding operand sizes up to the next power of 2.)
diff --git a/gmp/mpn/cray/add_n.c b/gmp/mpn/cray/add_n.c
new file mode 100644
index 0000000000..65b53bf87a
--- /dev/null
+++ b/gmp/mpn/cray/add_n.c
@@ -0,0 +1,91 @@
+/* Cray PVP mpn_add_n -- add two limb vectors and store their sum in a third
+ limb vector.
+
+Copyright 1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* This code runs at 4 cycles/limb. It may be possible to bring it down
+ to 3 cycles/limb. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_add_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t cy[n];
+ mp_limb_t a, b, r, s0, c0, c1;
+ mp_size_t i;
+ int more_carries;
+
+ /* Main add loop. Generate a raw output sum in rp[] and a carry vector
+ in cy[]. */
+#pragma _CRI ivdep
+ for (i = 0; i < n; i++)
+ {
+ a = up[i];
+ b = vp[i];
+ s0 = a + b;
+ rp[i] = s0;
+ c0 = ((a & b) | ((a | b) & ~s0)) >> 63;
+ cy[i] = c0;
+ }
+ /* Carry add loop. Add the carry vector cy[] to the raw sum rp[] and
+ store the new sum back to rp[0]. If this generates further carry, set
+ more_carries. */
+ more_carries = 0;
+#pragma _CRI ivdep
+ for (i = 1; i < n; i++)
+ {
+ r = rp[i];
+ c0 = cy[i - 1];
+ s0 = r + c0;
+ rp[i] = s0;
+ c0 = (r & ~s0) >> 63;
+ more_carries += c0;
+ }
+ /* If that second loop generated carry, handle that in scalar loop. */
+ if (more_carries)
+ {
+ mp_limb_t cyrec = 0;
+ /* Look for places where rp[k] is zero and cy[k-1] is non-zero.
+ These are where we got a recurrency carry. */
+ for (i = 1; i < n; i++)
+ {
+ r = rp[i];
+ c0 = (r == 0 && cy[i - 1] != 0);
+ s0 = r + cyrec;
+ rp[i] = s0;
+ c1 = (r & ~s0) >> 63;
+ cyrec = c0 | c1;
+ }
+ return cyrec | cy[n - 1];
+ }
+
+ return cy[n - 1];
+}
diff --git a/gmp/mpn/cray/cfp/addmul_1.c b/gmp/mpn/cray/cfp/addmul_1.c
new file mode 100644
index 0000000000..e1d52e4a5f
--- /dev/null
+++ b/gmp/mpn/cray/cfp/addmul_1.c
@@ -0,0 +1,49 @@
+/* mpn_addmul_1 for Cray PVP.
+
+Copyright 1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t limb)
+{
+ mp_limb_t p0[n], p1[n], tp[n];
+ mp_limb_t cy_limb;
+
+ GMPN_MULWW (p1, p0, up, &n, &limb);
+ cy_limb = mpn_add_n (tp, rp, p0, n);
+ rp[0] = tp[0];
+ if (n != 1)
+ cy_limb += mpn_add_n (rp + 1, tp + 1, p1, n - 1);
+ cy_limb += p1[n - 1];
+
+ return cy_limb;
+}
diff --git a/gmp/mpn/cray/cfp/mul_1.c b/gmp/mpn/cray/cfp/mul_1.c
new file mode 100644
index 0000000000..611a9d2532
--- /dev/null
+++ b/gmp/mpn/cray/cfp/mul_1.c
@@ -0,0 +1,48 @@
+/* mpn_mul_1 for Cray PVP.
+
+Copyright 1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t limb)
+{
+ mp_limb_t p0[n], p1[n];
+ mp_limb_t cy_limb;
+
+ GMPN_MULWW (p1, p0, up, &n, &limb);
+ rp[0] = p0[0];
+ cy_limb = p1[n - 1];
+ if (n != 1)
+ cy_limb += mpn_add_n (rp + 1, p0 + 1, p1, n - 1);
+
+ return cy_limb;
+}
diff --git a/gmp/mpn/cray/cfp/mulwwc90.s b/gmp/mpn/cray/cfp/mulwwc90.s
new file mode 100644
index 0000000000..71d2285fd7
--- /dev/null
+++ b/gmp/mpn/cray/cfp/mulwwc90.s
@@ -0,0 +1,254 @@
+* Helper for mpn_mul_1, mpn_addmul_1, and mpn_submul_1 for Cray PVP.
+
+* Copyright 1996, 2000 Free Software Foundation, Inc.
+* This file is generated from mulww.f in this same directory.
+
+* This file is part of the GNU MP Library.
+*
+* The GNU MP Library is free software; you can redistribute it and/or modify
+* it under the terms of either:
+*
+* * the GNU Lesser General Public License as published by the Free
+* Software Foundation; either version 3 of the License, or (at your
+* option) any later version.
+*
+* or
+*
+* * the GNU General Public License as published by the Free Software
+* Foundation; either version 2 of the License, or (at your option) any
+* later version.
+*
+* or both in parallel, as here.
+*
+* The GNU MP Library is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* for more details.
+*
+* You should have received copies of the GNU General Public License and the
+* GNU Lesser General Public License along with the GNU MP Library. If not,
+* see https://www.gnu.org/licenses/.
+
+ IDENT GMPN_MULWW
+**********************************************
+* Assemble with Cal Version 2.0 *
+* *
+* Generated by CFT77 6.0.4.19 *
+* on 06/27/00 at 04:34:13 *
+* *
+**********************************************
+* ALLOW UNDERSCORES IN IDENTIFIERS
+ EDIT OFF
+ FORMAT NEW
+@DATA SECTION DATA,CM
+@DATA = W.*
+ CON O'0000000000040000000000
+ CON O'0435152404713723252514
+ CON O'0535270000000000000000
+ CON O'0000000000000001200012
+ VWD 32/0,32/P.GMPN_MULWW
+ CON O'0014003000000000001416
+ CON O'0000000000000000000011
+ CON O'0000000000000000000215
+ BSSZ 1
+@CODE SECTION CODE
+@CODE = P.*
+L3 = P.*
+ A0 A6
+ A5 6
+ B03,A5 0,A0
+ A0 A1+A2
+ A5 1
+ 0,A0 T00,A5
+ B02 A2
+ B66 A3
+ B01 A6
+ A7 P.L4
+ B00 A7
+ A6 @DATA
+ J $STKOFEN
+GMPN_MULWW = P.*
+ A0 @DATA+3
+ B77 A0
+ A1 13
+ A0 B66
+ A2 B66
+ A4 B67
+ 0,A0 B77,A1
+ A7 782
+ A3 A2+A7
+ A0 A4-A3
+ JAM L3
+ A0 A6
+ A5 6
+ B03,A5 0,A0
+ A0 A1+A2
+ A5 1
+ 0,A0 T00,A5
+ B02 A2
+ B66 A3
+ B01 A6
+L4 = P.*
+ A7 B07
+ S7 0,A7
+ A6 B10
+ S6 0,A6
+ S5 1
+ S4 <22
+ S7 S7-S5
+ S5 #S7
+ T00 S6
+ S6 S6>22
+ S7 T00
+ S7 S7>44
+ S3 T00
+ S3 S3&S4
+ S6 S6&S4
+ S7 S7&S4
+ S3 S3<24
+ S6 S6<24
+ S7 S7<24
+ S0 S5
+ S4 S5
+ S1 S6
+ S2 S3
+ S3 S7
+ JSP L5
+L6 = P.*
+ S7 -S4
+ A2 S7
+ VL A2
+ A3 B06
+ A5 B05
+ A4 B04
+ A1 VL
+ A2 S4
+L7 = P.*
+ A0 A3
+ VL A1
+ V7 ,A0,1
+ B11 A5
+ A7 22
+ B12 A4
+ V6 V7>A7
+ B13 A3
+ S7 <22
+ A3 B02
+ V5 S7&V6
+ A6 24
+ V4 V5<A6
+ V3 S1*FV4
+ V2 S7&V7
+ V1 V2<A6
+ V0 S3*FV1
+ V6 V0+V3
+ A5 44
+ V5 V7>A5
+ V2 S1*FV1
+ V3 S7&V5
+ A0 14
+ B77 A0
+ A4 B77
+ A0 A4+A3
+ ,A0,1 V2
+ V0 V3<A6
+ V7 S2*FV1
+ A4 142
+ A0 A4+A3
+ ,A0,1 V7
+ V5 V7>A7
+ V2 S2*FV0
+ V3 V6+V2
+ S7 <20
+ V1 S7&V3
+ A4 270
+ A0 A4+A3
+ ,A0,1 V0
+ A4 14
+ A0 A4+A3
+ V7 ,A0,1
+ V6 V1<A7
+ V2 S2*FV4
+ V0 V7+V2
+ S7 <42
+ V1 S7&V0
+ A4 398
+ A0 A4+A3
+ ,A0,1 V0
+ V7 S3*FV4
+ V2 V5+V1
+ V0 V3<A5
+ A5 526
+ A0 A5+A3
+ ,A0,1 V0
+ A5 270
+ A0 A5+A3
+ V4 ,A0,1
+ V5 V2+V6
+ A5 20
+ V1 V3>A5
+ V0 S1*FV4
+ A5 654
+ A0 A5+A3
+ ,A0,1 V1
+ V6 V7+V0
+ A5 2
+ V2 V6<A5
+ V3 S3*FV4
+ A5 142
+ A0 A5+A3
+ V1 ,A0,1
+ A5 526
+ A0 A5+A3
+ V7 ,A0,1
+ V0 V1+V7
+ V6 V3<A6
+ V4 V6+V2
+ A6 42
+ V7 V5>A6
+ A5 654
+ CPW
+ A0 A5+A3
+ V1 ,A0,1
+ A5 398
+ A0 A5+A3
+ V3 ,A0,1
+ V6 V4+V1
+ V2 V3>A6
+ V5 V6+V2
+ A6 B12
+ V4 V3<A7
+ A7 B13
+ A3 A7+A1
+ A7 B11
+ A5 A7+A1
+ A4 A6+A1
+ A7 A2+A1
+ A0 A2+A1
+ A2 128
+ B13 A0
+ V1 V0+V4
+ A0 B11
+ ,A0,1 V1
+ V6 V5+V7
+ A0 A6
+ ,A0,1 V6
+ A0 B13
+ A1 A2
+ A2 A7
+ JAN L7
+L8 = P.*
+L5 = P.*
+ S1 0
+ A0 B02
+ A2 B02
+ A1 13
+ B66 A0
+ B77,A1 0,A0
+ A0 A2+A1
+ A1 1
+ T00,A1 0,A0
+ J B00
+ EXT $STKOFEN:p
+ ENTRY GMPN_MULWW
+ END
diff --git a/gmp/mpn/cray/cfp/mulwwj90.s b/gmp/mpn/cray/cfp/mulwwj90.s
new file mode 100644
index 0000000000..1c2c7cddbe
--- /dev/null
+++ b/gmp/mpn/cray/cfp/mulwwj90.s
@@ -0,0 +1,253 @@
+* Helper for mpn_mul_1, mpn_addmul_1, and mpn_submul_1 for Cray PVP.
+
+* Copyright 1996, 2000 Free Software Foundation, Inc.
+* This file is generated from mulww.f in this same directory.
+
+* This file is part of the GNU MP Library.
+*
+* The GNU MP Library is free software; you can redistribute it and/or modify
+* it under the terms of either:
+*
+* * the GNU Lesser General Public License as published by the Free
+* Software Foundation; either version 3 of the License, or (at your
+* option) any later version.
+*
+* or
+*
+* * the GNU General Public License as published by the Free Software
+* Foundation; either version 2 of the License, or (at your option) any
+* later version.
+*
+* or both in parallel, as here.
+*
+* The GNU MP Library is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* for more details.
+*
+* You should have received copies of the GNU General Public License and the
+* GNU Lesser General Public License along with the GNU MP Library. If not,
+* see https://www.gnu.org/licenses/.
+
+ IDENT GMPN_MULWW
+**********************************************
+* Assemble with Cal Version 2.0 *
+* *
+* Generated by CFT77 6.0.4.19 *
+* on 06/27/00 at 04:34:13 *
+* *
+**********************************************
+* ALLOW UNDERSCORES IN IDENTIFIERS
+ EDIT OFF
+ FORMAT NEW
+@DATA SECTION DATA,CM
+@DATA = W.*
+ CON O'0000000000040000000000
+ CON O'0435152404713723252514
+ CON O'0535270000000000000000
+ CON O'0000000000000001200012
+ VWD 32/0,32/P.GMPN_MULWW
+ CON O'0014003000000000001416
+ CON O'0000000000000000000011
+ CON O'0000000000000000000215
+ BSSZ 1
+@CODE SECTION CODE
+@CODE = P.*
+L3 = P.*
+ A0 A6
+ A5 6
+ B03,A5 0,A0
+ A0 A1+A2
+ A5 1
+ 0,A0 T00,A5
+ B02 A2
+ B66 A3
+ B01 A6
+ A7 P.L4
+ B00 A7
+ A6 @DATA
+ J $STKOFEN
+GMPN_MULWW = P.*
+ A0 @DATA+3
+ B77 A0
+ A1 13
+ A0 B66
+ A2 B66
+ A4 B67
+ 0,A0 B77,A1
+ A7 782
+ A3 A2+A7
+ A0 A4-A3
+ JAM L3
+ A0 A6
+ A5 6
+ B03,A5 0,A0
+ A0 A1+A2
+ A5 1
+ 0,A0 T00,A5
+ B02 A2
+ B66 A3
+ B01 A6
+L4 = P.*
+ A7 B07
+ S7 0,A7
+ A6 B10
+ S6 0,A6
+ S5 1
+ S4 <22
+ S7 S7-S5
+ S5 #S7
+ T00 S6
+ S6 S6>22
+ S7 T00
+ S7 S7>44
+ S3 T00
+ S3 S3&S4
+ S6 S6&S4
+ S7 S7&S4
+ S3 S3<24
+ S6 S6<24
+ S7 S7<24
+ S0 S5
+ S4 S5
+ S1 S6
+ S2 S3
+ S3 S7
+ JSP L5
+L6 = P.*
+ S7 -S4
+ A2 S7
+ VL A2
+ A3 B06
+ A5 B05
+ A4 B04
+ A1 VL
+ A2 S4
+L7 = P.*
+ A0 A3
+ VL A1
+ V7 ,A0,1
+ B11 A5
+ A7 22
+ B12 A4
+ V6 V7>A7
+ B13 A3
+ S7 <22
+ A3 B02
+ V5 S7&V6
+ A6 24
+ V4 V5<A6
+ V3 S1*FV4
+ V2 S7&V7
+ V1 V2<A6
+ V0 S3*FV1
+ V6 V0+V3
+ A5 44
+ V5 V7>A5
+ V2 S1*FV1
+ V3 S7&V5
+ A0 14
+ B77 A0
+ A4 B77
+ A0 A4+A3
+ ,A0,1 V2
+ V0 V3<A6
+ V7 S2*FV1
+ A4 142
+ A0 A4+A3
+ ,A0,1 V7
+ V5 V7>A7
+ V2 S2*FV0
+ V3 V6+V2
+ S7 <20
+ V1 S7&V3
+ A4 270
+ A0 A4+A3
+ ,A0,1 V0
+ A4 14
+ A0 A4+A3
+ V7 ,A0,1
+ V6 V1<A7
+ V2 S2*FV4
+ V0 V7+V2
+ S7 <42
+ V1 S7&V0
+ A4 398
+ A0 A4+A3
+ ,A0,1 V0
+ V7 S3*FV4
+ V2 V5+V1
+ V0 V3<A5
+ A5 526
+ A0 A5+A3
+ ,A0,1 V0
+ A5 270
+ A0 A5+A3
+ V4 ,A0,1
+ V5 V2+V6
+ A5 20
+ V1 V3>A5
+ V0 S1*FV4
+ A5 654
+ A0 A5+A3
+ ,A0,1 V1
+ V6 V7+V0
+ A5 2
+ V2 V6<A5
+ V3 S3*FV4
+ A5 142
+ A0 A5+A3
+ V1 ,A0,1
+ A5 526
+ A0 A5+A3
+ V7 ,A0,1
+ V0 V1+V7
+ V6 V3<A6
+ V4 V6+V2
+ A6 42
+ V7 V5>A6
+ A5 654
+ A0 A5+A3
+ V1 ,A0,1
+ A5 398
+ A0 A5+A3
+ V3 ,A0,1
+ V6 V4+V1
+ V2 V3>A6
+ V5 V6+V2
+ A6 B12
+ V4 V3<A7
+ A7 B13
+ A3 A7+A1
+ A7 B11
+ A5 A7+A1
+ A4 A6+A1
+ A7 A2+A1
+ A0 A2+A1
+ A2 64
+ B13 A0
+ V1 V0+V4
+ A0 B11
+ ,A0,1 V1
+ V6 V5+V7
+ A0 A6
+ ,A0,1 V6
+ A0 B13
+ A1 A2
+ A2 A7
+ JAN L7
+L8 = P.*
+L5 = P.*
+ S1 0
+ A0 B02
+ A2 B02
+ A1 13
+ B66 A0
+ B77,A1 0,A0
+ A0 A2+A1
+ A1 1
+ T00,A1 0,A0
+ J B00
+ EXT $STKOFEN:p
+ ENTRY GMPN_MULWW
+ END
diff --git a/gmp/mpn/cray/cfp/submul_1.c b/gmp/mpn/cray/cfp/submul_1.c
new file mode 100644
index 0000000000..b44c97df45
--- /dev/null
+++ b/gmp/mpn/cray/cfp/submul_1.c
@@ -0,0 +1,49 @@
+/* mpn_submul_1 for Cray PVP.
+
+Copyright 1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t limb)
+{
+ mp_limb_t p0[n], p1[n], tp[n];
+ mp_limb_t cy_limb;
+
+ GMPN_MULWW (p1, p0, up, &n, &limb);
+ cy_limb = mpn_sub_n (tp, rp, p0, n);
+ rp[0] = tp[0];
+ if (n != 1)
+ cy_limb += mpn_sub_n (rp + 1, tp + 1, p1, n - 1);
+ cy_limb += p1[n - 1];
+
+ return cy_limb;
+}
diff --git a/gmp/mpn/cray/gmp-mparam.h b/gmp/mpn/cray/gmp-mparam.h
new file mode 100644
index 0000000000..ea8c25b32e
--- /dev/null
+++ b/gmp/mpn/cray/gmp-mparam.h
@@ -0,0 +1,79 @@
+/* Cray T90 CFP gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1996, 2000-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+#if 0
+#define UMUL_TIME 519
+#define UDIV_TIME 2360
+#endif
+
+/* T90 Unicos 10.0.X in CFP mode */
+
+/* Generated by tuneup.c, 2004-02-07, system compiler */
+
+#define MUL_TOOM22_THRESHOLD 71
+#define MUL_TOOM33_THRESHOLD 131
+
+#define SQR_BASECASE_THRESHOLD 32
+#define SQR_TOOM2_THRESHOLD 199
+#define SQR_TOOM3_THRESHOLD 363
+
+#define DIV_SB_PREINV_THRESHOLD 0 /* (preinv always) */
+#define DIV_DC_THRESHOLD 996
+#define POWM_THRESHOLD 601
+
+#define HGCD_THRESHOLD 964
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 2874
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* preinv always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define USE_PREINV_DIVREM_1 1 /* preinv always */
+#define USE_PREINV_MOD_1 1 /* preinv always */
+#define DIVREM_2_THRESHOLD 0 /* preinv always */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always */
+
+#define GET_STR_DC_THRESHOLD 26
+#define GET_STR_PRECOMPUTE_THRESHOLD 42
+#define SET_STR_THRESHOLD 145756
+
+#define MUL_FFT_TABLE { 272, 544, 1088, 2304, 5120, 12288, 49152, 0 }
+#define MUL_FFT_MODF_THRESHOLD 200
+#define MUL_FFT_THRESHOLD 1664
+
+#define SQR_FFT_TABLE { 1008, 2080, 3904, 7936, 17408, 45056, 0 }
+#define SQR_FFT_MODF_THRESHOLD 600
+#define SQR_FFT_THRESHOLD 2976
diff --git a/gmp/mpn/cray/hamdist.c b/gmp/mpn/cray/hamdist.c
new file mode 100644
index 0000000000..8eb9ba018c
--- /dev/null
+++ b/gmp/mpn/cray/hamdist.c
@@ -0,0 +1,43 @@
+/* Cray mpn_hamdist -- hamming distance count.
+
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <intrinsics.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpn_hamdist (mp_srcptr p1, mp_srcptr p2, mp_size_t n)
+{
+ unsigned long int result = 0;
+ mp_size_t i;
+ for (i = 0; i < n; i++)
+ result += _popcnt (p1[i] ^ p2[i]);
+ return result;
+}
diff --git a/gmp/mpn/cray/ieee/addmul_1.c b/gmp/mpn/cray/ieee/addmul_1.c
new file mode 100644
index 0000000000..6318b7c9c2
--- /dev/null
+++ b/gmp/mpn/cray/ieee/addmul_1.c
@@ -0,0 +1,112 @@
+/* Cray PVP/IEEE mpn_addmul_1 -- multiply a limb vector with a limb and add the
+ result to a second limb vector.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* This code runs at just under 9 cycles/limb on a T90. That is not perfect,
+ mainly due to vector register shortage in the main loop. Assembly code
+ should bring it down to perhaps 7 cycles/limb. */
+
+#include <intrinsics.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t cy[n];
+ mp_limb_t a, b, r, s0, s1, c0, c1;
+ mp_size_t i;
+ int more_carries;
+
+ if (up == rp)
+ {
+ /* The algorithm used below cannot handle overlap. Handle it here by
+ making a temporary copy of the source vector, then call ourselves. */
+ mp_limb_t xp[n];
+ MPN_COPY (xp, up, n);
+ return mpn_addmul_1 (rp, xp, n, vl);
+ }
+
+ a = up[0] * vl;
+ r = rp[0];
+ s0 = a + r;
+ rp[0] = s0;
+ c0 = ((a & r) | ((a | r) & ~s0)) >> 63;
+ cy[0] = c0;
+
+ /* Main multiply loop. Generate a raw accumulated output product in rp[]
+ and a carry vector in cy[]. */
+#pragma _CRI ivdep
+ for (i = 1; i < n; i++)
+ {
+ a = up[i] * vl;
+ b = _int_mult_upper (up[i - 1], vl);
+ s0 = a + b;
+ c0 = ((a & b) | ((a | b) & ~s0)) >> 63;
+ r = rp[i];
+ s1 = s0 + r;
+ rp[i] = s1;
+ c1 = ((s0 & r) | ((s0 | r) & ~s1)) >> 63;
+ cy[i] = c0 + c1;
+ }
+ /* Carry add loop. Add the carry vector cy[] to the raw result rp[] and
+ store the new result back to rp[]. */
+ more_carries = 0;
+#pragma _CRI ivdep
+ for (i = 1; i < n; i++)
+ {
+ r = rp[i];
+ c0 = cy[i - 1];
+ s0 = r + c0;
+ rp[i] = s0;
+ c0 = (r & ~s0) >> 63;
+ more_carries += c0;
+ }
+ /* If that second loop generated carry, handle that in scalar loop. */
+ if (more_carries)
+ {
+ mp_limb_t cyrec = 0;
+ /* Look for places where rp[k] == 0 and cy[k-1] == 1 or
+ rp[k] == 1 and cy[k-1] == 2.
+ These are where we got a recurrency carry. */
+ for (i = 1; i < n; i++)
+ {
+ r = rp[i];
+ c0 = r < cy[i - 1];
+ s0 = r + cyrec;
+ rp[i] = s0;
+ c1 = (r & ~s0) >> 63;
+ cyrec = c0 | c1;
+ }
+ return _int_mult_upper (up[n - 1], vl) + cyrec + cy[n - 1];
+ }
+
+ return _int_mult_upper (up[n - 1], vl) + cy[n - 1];
+}
diff --git a/gmp/mpn/cray/ieee/gmp-mparam.h b/gmp/mpn/cray/ieee/gmp-mparam.h
new file mode 100644
index 0000000000..1fdc286574
--- /dev/null
+++ b/gmp/mpn/cray/ieee/gmp-mparam.h
@@ -0,0 +1,73 @@
+/* Cray T90 IEEE gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1996, 2000-2002, 2004 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* Generated by tuneup.c, 2004-02-07, system compiler */
+
+#define MUL_TOOM22_THRESHOLD 130
+#define MUL_TOOM33_THRESHOLD 260
+
+#define SQR_BASECASE_THRESHOLD 9 /* karatsuba */
+#define SQR_TOOM2_THRESHOLD 0 /* never sqr_basecase */
+#define SQR_TOOM3_THRESHOLD 34
+
+#define DIV_SB_PREINV_THRESHOLD 0 /* preinv always */
+#define DIV_DC_THRESHOLD 390
+#define POWM_THRESHOLD 656
+
+#define HGCD_THRESHOLD 964
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 964
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* preinv always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define USE_PREINV_DIVREM_1 1 /* preinv always */
+#define USE_PREINV_MOD_1 1 /* preinv always */
+#define DIVREM_2_THRESHOLD 0 /* preinv always */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always */
+
+#define GET_STR_DC_THRESHOLD 45
+#define GET_STR_PRECOMPUTE_THRESHOLD 77
+#define SET_STR_THRESHOLD 145756
+
+#define MUL_FFT_TABLE { 1104, 2208, 4416, 8960, 19456, 45056, 0 }
+#define MUL_FFT_MODF_THRESHOLD 1168
+#define MUL_FFT_THRESHOLD 6528
+
+#define SQR_FFT_TABLE { 368, 736, 1600, 2816, 7168, 12288, 0 }
+#define SQR_FFT_MODF_THRESHOLD 296
+#define SQR_FFT_THRESHOLD 1312
diff --git a/gmp/mpn/cray/ieee/invert_limb.c b/gmp/mpn/cray/ieee/invert_limb.c
new file mode 100644
index 0000000000..f951a6e138
--- /dev/null
+++ b/gmp/mpn/cray/ieee/invert_limb.c
@@ -0,0 +1,128 @@
+/* mpn_invert_limb -- Invert a normalized limb.
+
+Copyright 1991, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/*
+ This is needed to make configure define HAVE_NATIVE_mpn_invert_limb:
+ PROLOGUE(mpn_invert_limb)
+*/
+
+static const unsigned short int approx_tab[0x100] =
+{
+ /* 0x400, */
+ 0x3ff,
+ 0x3fc, 0x3f8, 0x3f4, 0x3f0, 0x3ec, 0x3e8, 0x3e4,
+ 0x3e0, 0x3dd, 0x3d9, 0x3d5, 0x3d2, 0x3ce, 0x3ca, 0x3c7,
+ 0x3c3, 0x3c0, 0x3bc, 0x3b9, 0x3b5, 0x3b2, 0x3ae, 0x3ab,
+ 0x3a8, 0x3a4, 0x3a1, 0x39e, 0x39b, 0x397, 0x394, 0x391,
+ 0x38e, 0x38b, 0x387, 0x384, 0x381, 0x37e, 0x37b, 0x378,
+ 0x375, 0x372, 0x36f, 0x36c, 0x369, 0x366, 0x364, 0x361,
+ 0x35e, 0x35b, 0x358, 0x355, 0x353, 0x350, 0x34d, 0x34a,
+ 0x348, 0x345, 0x342, 0x340, 0x33d, 0x33a, 0x338, 0x335,
+ 0x333, 0x330, 0x32e, 0x32b, 0x329, 0x326, 0x324, 0x321,
+ 0x31f, 0x31c, 0x31a, 0x317, 0x315, 0x313, 0x310, 0x30e,
+ 0x30c, 0x309, 0x307, 0x305, 0x303, 0x300, 0x2fe, 0x2fc,
+ 0x2fa, 0x2f7, 0x2f5, 0x2f3, 0x2f1, 0x2ef, 0x2ec, 0x2ea,
+ 0x2e8, 0x2e6, 0x2e4, 0x2e2, 0x2e0, 0x2de, 0x2dc, 0x2da,
+ 0x2d8, 0x2d6, 0x2d4, 0x2d2, 0x2d0, 0x2ce, 0x2cc, 0x2ca,
+ 0x2c8, 0x2c6, 0x2c4, 0x2c2, 0x2c0, 0x2be, 0x2bc, 0x2bb,
+ 0x2b9, 0x2b7, 0x2b5, 0x2b3, 0x2b1, 0x2b0, 0x2ae, 0x2ac,
+ 0x2aa, 0x2a8, 0x2a7, 0x2a5, 0x2a3, 0x2a1, 0x2a0, 0x29e,
+ 0x29c, 0x29b, 0x299, 0x297, 0x295, 0x294, 0x292, 0x291,
+ 0x28f, 0x28d, 0x28c, 0x28a, 0x288, 0x287, 0x285, 0x284,
+ 0x282, 0x280, 0x27f, 0x27d, 0x27c, 0x27a, 0x279, 0x277,
+ 0x276, 0x274, 0x273, 0x271, 0x270, 0x26e, 0x26d, 0x26b,
+ 0x26a, 0x268, 0x267, 0x265, 0x264, 0x263, 0x261, 0x260,
+ 0x25e, 0x25d, 0x25c, 0x25a, 0x259, 0x257, 0x256, 0x255,
+ 0x253, 0x252, 0x251, 0x24f, 0x24e, 0x24d, 0x24b, 0x24a,
+ 0x249, 0x247, 0x246, 0x245, 0x243, 0x242, 0x241, 0x240,
+ 0x23e, 0x23d, 0x23c, 0x23b, 0x239, 0x238, 0x237, 0x236,
+ 0x234, 0x233, 0x232, 0x231, 0x230, 0x22e, 0x22d, 0x22c,
+ 0x22b, 0x22a, 0x229, 0x227, 0x226, 0x225, 0x224, 0x223,
+ 0x222, 0x220, 0x21f, 0x21e, 0x21d, 0x21c, 0x21b, 0x21a,
+ 0x219, 0x218, 0x216, 0x215, 0x214, 0x213, 0x212, 0x211,
+ 0x210, 0x20f, 0x20e, 0x20d, 0x20c, 0x20b, 0x20a, 0x209,
+ 0x208, 0x207, 0x206, 0x205, 0x204, 0x203, 0x202, 0x201,
+};
+
+/* iteration: z = 2z-(z**2)d */
+
+mp_limb_t
+mpn_invert_limb (mp_limb_t d)
+{
+ mp_limb_t z, z2l, z2h, tl, th;
+ mp_limb_t xh, xl;
+ mp_limb_t zh, zl;
+
+#if GMP_LIMB_BITS == 32
+ z = approx_tab[(d >> 23) - 0x100] << 6; /* z < 2^16 */
+
+ z2l = z * z; /* z2l < 2^32 */
+ umul_ppmm (th, tl, z2l, d);
+ z = (z << 17) - (th << 1);
+#endif
+#if GMP_LIMB_BITS == 64
+ z = approx_tab[(d >> 55) - 0x100] << 6; /* z < 2^16 */
+
+ z2l = z * z; /* z2l < 2^32 */
+ th = z2l * (d >> 32); /* th < 2^64 */
+ z = (z << 17) - (th >> 31); /* z < 2^32 */
+
+ z2l = z * z;
+ umul_ppmm (th, tl, z2l, d);
+ z = (z << 33) - (th << 1);
+#endif
+
+ umul_ppmm (z2h, z2l, z, z);
+ umul_ppmm (th, tl, z2h, d);
+ umul_ppmm (xh, xl, z2l, d);
+ tl += xh;
+ th += tl < xh;
+ th = (th << 2) | (tl >> GMP_LIMB_BITS - 2);
+ tl = tl << 2;
+ sub_ddmmss (zh, zl, z << 2, 0, th, tl);
+
+ umul_ppmm (xh, xl, d, zh);
+ xh += d; /* add_ssaaaa (xh, xl, xh, xl, d, 0); */
+ if (~xh != 0)
+ {
+ add_ssaaaa (xh, xl, xh, xl, 0, d);
+ zh++;
+ }
+
+ add_ssaaaa (xh, xl, xh, xl, 0, d);
+ if (xh != 0)
+ zh++;
+
+ return zh;
+}
diff --git a/gmp/mpn/cray/ieee/mul_1.c b/gmp/mpn/cray/ieee/mul_1.c
new file mode 100644
index 0000000000..dad09fa8cf
--- /dev/null
+++ b/gmp/mpn/cray/ieee/mul_1.c
@@ -0,0 +1,104 @@
+/* Cray PVP/IEEE mpn_mul_1 -- multiply a limb vector with a limb and store the
+ result in a second limb vector.
+
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* This code runs at 5 cycles/limb on a T90. That would probably
+ be hard to improve upon, even with assembly code. */
+
+#include <intrinsics.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t cy[n];
+ mp_limb_t a, b, r, s0, s1, c0, c1;
+ mp_size_t i;
+ int more_carries;
+
+ if (up == rp)
+ {
+ /* The algorithm used below cannot handle overlap. Handle it here by
+ making a temporary copy of the source vector, then call ourselves. */
+ mp_limb_t xp[n];
+ MPN_COPY (xp, up, n);
+ return mpn_mul_1 (rp, xp, n, vl);
+ }
+
+ a = up[0] * vl;
+ rp[0] = a;
+ cy[0] = 0;
+
+ /* Main multiply loop. Generate a raw accumulated output product in rp[]
+ and a carry vector in cy[]. */
+#pragma _CRI ivdep
+ for (i = 1; i < n; i++)
+ {
+ a = up[i] * vl;
+ b = _int_mult_upper (up[i - 1], vl);
+ s0 = a + b;
+ c0 = ((a & b) | ((a | b) & ~s0)) >> 63;
+ rp[i] = s0;
+ cy[i] = c0;
+ }
+ /* Carry add loop. Add the carry vector cy[] to the raw sum rp[] and
+ store the new sum back to rp[0]. */
+ more_carries = 0;
+#pragma _CRI ivdep
+ for (i = 2; i < n; i++)
+ {
+ r = rp[i];
+ c0 = cy[i - 1];
+ s0 = r + c0;
+ rp[i] = s0;
+ c0 = (r & ~s0) >> 63;
+ more_carries += c0;
+ }
+ /* If that second loop generated carry, handle that in scalar loop. */
+ if (more_carries)
+ {
+ mp_limb_t cyrec = 0;
+ /* Look for places where rp[k] is zero and cy[k-1] is non-zero.
+ These are where we got a recurrency carry. */
+ for (i = 2; i < n; i++)
+ {
+ r = rp[i];
+ c0 = (r == 0 && cy[i - 1] != 0);
+ s0 = r + cyrec;
+ rp[i] = s0;
+ c1 = (r & ~s0) >> 63;
+ cyrec = c0 | c1;
+ }
+ return _int_mult_upper (up[n - 1], vl) + cyrec + cy[n - 1];
+ }
+
+ return _int_mult_upper (up[n - 1], vl) + cy[n - 1];
+}
diff --git a/gmp/mpn/cray/ieee/mul_basecase.c b/gmp/mpn/cray/ieee/mul_basecase.c
new file mode 100644
index 0000000000..6dc845dd99
--- /dev/null
+++ b/gmp/mpn/cray/ieee/mul_basecase.c
@@ -0,0 +1,108 @@
+/* Cray PVP/IEEE mpn_mul_basecase.
+
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* The most critical loop of this code runs at about 5 cycles/limb on a T90.
+ That is not perfect, mainly due to vector register shortage. */
+
+#include <intrinsics.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_mul_basecase (mp_ptr rp,
+ mp_srcptr up, mp_size_t un,
+ mp_srcptr vp, mp_size_t vn)
+{
+ mp_limb_t cy[un + vn];
+ mp_limb_t vl;
+ mp_limb_t a, b, r, s0, s1, c0, c1;
+ mp_size_t i, j;
+ int more_carries;
+
+ for (i = 0; i < un + vn; i++)
+ {
+ rp[i] = 0;
+ cy[i] = 0;
+ }
+
+#pragma _CRI novector
+ for (j = 0; j < vn; j++)
+ {
+ vl = vp[j];
+
+ a = up[0] * vl;
+ r = rp[j];
+ s0 = a + r;
+ rp[j] = s0;
+ c0 = ((a & r) | ((a | r) & ~s0)) >> 63;
+ cy[j] += c0;
+
+#pragma _CRI ivdep
+ for (i = 1; i < un; i++)
+ {
+ a = up[i] * vl;
+ b = _int_mult_upper (up[i - 1], vl);
+ s0 = a + b;
+ c0 = ((a & b) | ((a | b) & ~s0)) >> 63;
+ r = rp[j + i];
+ s1 = s0 + r;
+ rp[j + i] = s1;
+ c1 = ((s0 & r) | ((s0 | r) & ~s1)) >> 63;
+ cy[j + i] += c0 + c1;
+ }
+ rp[j + un] = _int_mult_upper (up[un - 1], vl);
+ }
+
+ more_carries = 0;
+#pragma _CRI ivdep
+ for (i = 1; i < un + vn; i++)
+ {
+ r = rp[i];
+ c0 = cy[i - 1];
+ s0 = r + c0;
+ rp[i] = s0;
+ c0 = (r & ~s0) >> 63;
+ more_carries += c0;
+ }
+ /* If that second loop generated carry, handle that in scalar loop. */
+ if (more_carries)
+ {
+ mp_limb_t cyrec = 0;
+ for (i = 1; i < un + vn; i++)
+ {
+ r = rp[i];
+ c0 = (r < cy[i - 1]);
+ s0 = r + cyrec;
+ rp[i] = s0;
+ c1 = (r & ~s0) >> 63;
+ cyrec = c0 | c1;
+ }
+ }
+}
diff --git a/gmp/mpn/cray/ieee/sqr_basecase.c b/gmp/mpn/cray/ieee/sqr_basecase.c
new file mode 100644
index 0000000000..840d3dd260
--- /dev/null
+++ b/gmp/mpn/cray/ieee/sqr_basecase.c
@@ -0,0 +1,106 @@
+/* Cray PVP/IEEE mpn_sqr_basecase.
+
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* This is just mpn_mul_basecase with trivial modifications. */
+
+#include <intrinsics.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_sqr_basecase (mp_ptr rp,
+ mp_srcptr up, mp_size_t un)
+{
+ mp_limb_t cy[un + un];
+ mp_limb_t ul;
+ mp_limb_t a, b, r, s0, s1, c0, c1;
+ mp_size_t i, j;
+ int more_carries;
+
+ for (i = 0; i < un + un; i++)
+ {
+ rp[i] = 0;
+ cy[i] = 0;
+ }
+
+#pragma _CRI novector
+ for (j = 0; j < un; j++)
+ {
+ ul = up[j];
+
+ a = up[0] * ul;
+ r = rp[j];
+ s0 = a + r;
+ rp[j] = s0;
+ c0 = ((a & r) | ((a | r) & ~s0)) >> 63;
+ cy[j] += c0;
+
+#pragma _CRI ivdep
+ for (i = 1; i < un; i++)
+ {
+ a = up[i] * ul;
+ b = _int_mult_upper (up[i - 1], ul);
+ s0 = a + b;
+ c0 = ((a & b) | ((a | b) & ~s0)) >> 63;
+ r = rp[j + i];
+ s1 = s0 + r;
+ rp[j + i] = s1;
+ c1 = ((s0 & r) | ((s0 | r) & ~s1)) >> 63;
+ cy[j + i] += c0 + c1;
+ }
+ rp[j + un] = _int_mult_upper (up[un - 1], ul);
+ }
+
+ more_carries = 0;
+#pragma _CRI ivdep
+ for (i = 1; i < un + un; i++)
+ {
+ r = rp[i];
+ c0 = cy[i - 1];
+ s0 = r + c0;
+ rp[i] = s0;
+ c0 = (r & ~s0) >> 63;
+ more_carries += c0;
+ }
+ /* If that second loop generated carry, handle that in scalar loop. */
+ if (more_carries)
+ {
+ mp_limb_t cyrec = 0;
+ for (i = 1; i < un + un; i++)
+ {
+ r = rp[i];
+ c0 = (r < cy[i - 1]);
+ s0 = r + cyrec;
+ rp[i] = s0;
+ c1 = (r & ~s0) >> 63;
+ cyrec = c0 | c1;
+ }
+ }
+}
diff --git a/gmp/mpn/cray/ieee/submul_1.c b/gmp/mpn/cray/ieee/submul_1.c
new file mode 100644
index 0000000000..27a1939019
--- /dev/null
+++ b/gmp/mpn/cray/ieee/submul_1.c
@@ -0,0 +1,112 @@
+/* Cray PVP/IEEE mpn_submul_1 -- multiply a limb vector with a limb and
+ subtract the result from a second limb vector.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* This code runs at just under 9 cycles/limb on a T90. That is not perfect,
+ mainly due to vector register shortage in the main loop. Assembly code
+ should bring it down to perhaps 7 cycles/limb. */
+
+#include <intrinsics.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t cy[n];
+ mp_limb_t a, b, r, s0, s1, c0, c1;
+ mp_size_t i;
+ int more_carries;
+
+ if (up == rp)
+ {
+ /* The algorithm used below cannot handle overlap. Handle it here by
+ making a temporary copy of the source vector, then call ourselves. */
+ mp_limb_t xp[n];
+ MPN_COPY (xp, up, n);
+ return mpn_submul_1 (rp, xp, n, vl);
+ }
+
+ a = up[0] * vl;
+ r = rp[0];
+ s0 = r - a;
+ rp[0] = s0;
+ c1 = ((s0 & a) | ((s0 | a) & ~r)) >> 63;
+ cy[0] = c1;
+
+ /* Main multiply loop. Generate a raw accumulated output product in rp[]
+ and a carry vector in cy[]. */
+#pragma _CRI ivdep
+ for (i = 1; i < n; i++)
+ {
+ a = up[i] * vl;
+ b = _int_mult_upper (up[i - 1], vl);
+ s0 = a + b;
+ c0 = ((a & b) | ((a | b) & ~s0)) >> 63;
+ r = rp[i];
+ s1 = r - s0;
+ rp[i] = s1;
+ c1 = ((s1 & s0) | ((s1 | s0) & ~r)) >> 63;
+ cy[i] = c0 + c1;
+ }
+ /* Carry subtract loop. Subtract the carry vector cy[] from the raw result
+ rp[] and store the new result back to rp[]. */
+ more_carries = 0;
+#pragma _CRI ivdep
+ for (i = 1; i < n; i++)
+ {
+ r = rp[i];
+ c0 = cy[i - 1];
+ s0 = r - c0;
+ rp[i] = s0;
+ c0 = (s0 & ~r) >> 63;
+ more_carries += c0;
+ }
+ /* If that second loop generated carry, handle that in scalar loop. */
+ if (more_carries)
+ {
+ mp_limb_t cyrec = 0;
+ /* Look for places where rp[k] == ~0 and cy[k-1] == 1 or
+ rp[k] == ~1 and cy[k-1] == 2.
+ These are where we got a recurrency carry. */
+ for (i = 1; i < n; i++)
+ {
+ r = rp[i];
+ c0 = ~r < cy[i - 1];
+ s0 = r - cyrec;
+ rp[i] = s0;
+ c1 = (s0 & ~r) >> 63;
+ cyrec = c0 | c1;
+ }
+ return _int_mult_upper (up[n - 1], vl) + cyrec + cy[n - 1];
+ }
+
+ return _int_mult_upper (up[n - 1], vl) + cy[n - 1];
+}
diff --git a/gmp/mpn/cray/lshift.c b/gmp/mpn/cray/lshift.c
new file mode 100644
index 0000000000..074f38041a
--- /dev/null
+++ b/gmp/mpn/cray/lshift.c
@@ -0,0 +1,59 @@
+/* mpn_lshift -- Shift left low level for Cray vector processors.
+
+Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <intrinsics.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t n, unsigned int cnt)
+{
+ unsigned sh_1, sh_2;
+ mp_size_t i;
+ mp_limb_t retval;
+
+ sh_1 = cnt;
+ sh_2 = GMP_LIMB_BITS - sh_1;
+ retval = up[n - 1] >> sh_2;
+
+#pragma _CRI ivdep
+ for (i = n - 1; i > 0; i--)
+ {
+#if 1
+ wp[i] = (up[i] << sh_1) | (up[i - 1] >> sh_2);
+#else
+ /* This is the recommended way, but at least on SV1 it is slower. */
+ wp[i] = _dshiftl (up[i], up[i - 1], sh_1);
+#endif
+ }
+
+ wp[0] = up[0] << sh_1;
+ return retval;
+}
diff --git a/gmp/mpn/cray/mulww.f b/gmp/mpn/cray/mulww.f
new file mode 100644
index 0000000000..9bddf05bc9
--- /dev/null
+++ b/gmp/mpn/cray/mulww.f
@@ -0,0 +1,63 @@
+c Helper for mpn_mul_1, mpn_addmul_1, and mpn_submul_1 for Cray PVP.
+
+c Copyright 1996, 2000 Free Software Foundation, Inc.
+
+c This file is part of the GNU MP Library.
+c
+c The GNU MP Library is free software; you can redistribute it and/or modify
+c it under the terms of either:
+c
+c * the GNU Lesser General Public License as published by the Free
+c Software Foundation; either version 3 of the License, or (at your
+c option) any later version.
+c
+c or
+c
+c * the GNU General Public License as published by the Free Software
+c Foundation; either version 2 of the License, or (at your option) any
+c later version.
+c
+c or both in parallel, as here.
+c
+c The GNU MP Library is distributed in the hope that it will be useful, but
+c WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+c or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+c for more details.
+c
+c You should have received copies of the GNU General Public License and the
+c GNU Lesser General Public License along with the GNU MP Library. If not,
+c see https://www.gnu.org/licenses/.
+
+c p1[] = hi(a[]*s); the upper limbs of each product
+c p0[] = low(a[]*s); the corresponding lower limbs
+c n is number of limbs in the vectors
+
+ subroutine gmpn_mulww(p1,p0,a,n,s)
+ integer*8 p1(0:*),p0(0:*),a(0:*),s
+ integer n
+
+ integer*8 a0,a1,a2,s0,s1,s2,c
+ integer*8 ai,t0,t1,t2,t3,t4
+
+ s0 = shiftl(and(s,4194303),24)
+ s1 = shiftl(and(shiftr(s,22),4194303),24)
+ s2 = shiftl(and(shiftr(s,44),4194303),24)
+
+ do i = 0,n-1
+ ai = a(i)
+ a0 = shiftl(and(ai,4194303),24)
+ a1 = shiftl(and(shiftr(ai,22),4194303),24)
+ a2 = shiftl(and(shiftr(ai,44),4194303),24)
+
+ t0 = i24mult(a0,s0)
+ t1 = i24mult(a0,s1)+i24mult(a1,s0)
+ t2 = i24mult(a0,s2)+i24mult(a1,s1)+i24mult(a2,s0)
+ t3 = i24mult(a1,s2)+i24mult(a2,s1)
+ t4 = i24mult(a2,s2)
+
+ p0(i)=shiftl(t2,44)+shiftl(t1,22)+t0
+ c=shiftr(shiftr(t0,22)+and(t1,4398046511103)+
+ $ shiftl(and(t2,1048575),22),42)
+ p1(i)=shiftl(t4,24)+shiftl(t3,2)+shiftr(t2,20)+shiftr(t1,42)+c
+ end do
+ end
diff --git a/gmp/mpn/cray/popcount.c b/gmp/mpn/cray/popcount.c
new file mode 100644
index 0000000000..48ddab875e
--- /dev/null
+++ b/gmp/mpn/cray/popcount.c
@@ -0,0 +1,43 @@
+/* Cray mpn_popcount -- population count.
+
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <intrinsics.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpn_popcount (mp_srcptr p, mp_size_t n)
+{
+ unsigned long int result = 0;
+ mp_size_t i;
+ for (i = 0; i < n; i++)
+ result += _popcnt (p[i]);
+ return result;
+}
diff --git a/gmp/mpn/cray/rshift.c b/gmp/mpn/cray/rshift.c
new file mode 100644
index 0000000000..424bede9db
--- /dev/null
+++ b/gmp/mpn/cray/rshift.c
@@ -0,0 +1,59 @@
+/* mpn_rshift -- Shift right low level for Cray vector processors.
+
+Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <intrinsics.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_rshift (mp_ptr wp, mp_srcptr up, mp_size_t n, unsigned int cnt)
+{
+ unsigned sh_1, sh_2;
+ mp_size_t i;
+ mp_limb_t retval;
+
+ sh_1 = cnt;
+ sh_2 = GMP_LIMB_BITS - sh_1;
+ retval = up[0] << sh_2;
+
+#pragma _CRI ivdep
+ for (i = 0; i < n - 1; i++)
+ {
+#if 1
+ wp[i] = (up[i] >> sh_1) | (up[i + 1] << sh_2);
+#else
+ /* This is the recommended way, but at least on SV1 it is slower. */
+ wp[i] = _dshiftr (up[i + 1], up[i], sh_1);
+#endif
+ }
+
+ wp[n - 1] = up[n - 1] >> sh_1;
+ return retval;
+}
diff --git a/gmp/mpn/cray/sub_n.c b/gmp/mpn/cray/sub_n.c
new file mode 100644
index 0000000000..0cc9ad1e04
--- /dev/null
+++ b/gmp/mpn/cray/sub_n.c
@@ -0,0 +1,91 @@
+/* Cray PVP mpn_sub_n -- subtract two limb vectors and store their difference
+ in a third limb vector.
+
+Copyright 1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* This code runs at 4 cycles/limb. It may be possible to bring it down
+ to 3 cycles/limb. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_sub_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t cy[n];
+ mp_limb_t a, b, r, s0, c0, c1;
+ mp_size_t i;
+ int more_carries;
+
+ /* Main subtract loop. Generate a raw output difference in rp[] and a
+ borrow vector in cy[]. */
+#pragma _CRI ivdep
+ for (i = 0; i < n; i++)
+ {
+ a = up[i];
+ b = vp[i];
+ s0 = a - b; /* a = s0 + b */
+ rp[i] = s0;
+ c0 = ((s0 & b) | ((s0 | b) & ~a)) >> 63;
+ cy[i] = c0;
+ }
+ /* Borrow subtract loop. Subtract the borrow vector cy[] from the raw
+ difference rp[] and store the new difference back to rp[0]. If this
+ generates further borrow, set more_carries. */
+ more_carries = 0;
+#pragma _CRI ivdep
+ for (i = 1; i < n; i++)
+ {
+ r = rp[i];
+ c0 = cy[i - 1];
+ s0 = r - c0; /* r = s0 + c0 */
+ rp[i] = s0;
+ c0 = (s0 & ~r) >> 63;
+ more_carries += c0;
+ }
+ /* If that second loop generated borrow, handle that in scalar loop. */
+ if (more_carries)
+ {
+ mp_limb_t cyrec = 0;
+ /* Look for places where rp[k] contains just ones and cy[k-1] is
+ non-zero. These are where we got a recurrency borrow. */
+ for (i = 1; i < n; i++)
+ {
+ r = rp[i];
+ c0 = (~r == 0 && cy[i - 1] != 0);
+ s0 = r - cyrec;
+ rp[i] = s0;
+ c1 = (s0 & ~r) >> 63;
+ cyrec = c0 | c1;
+ }
+ return cyrec | cy[n - 1];
+ }
+
+ return cy[n - 1];
+}
diff --git a/gmp/mpn/generic/add.c b/gmp/mpn/generic/add.c
new file mode 100644
index 0000000000..559f26133c
--- /dev/null
+++ b/gmp/mpn/generic/add.c
@@ -0,0 +1,34 @@
+/* mpn_add - add mpn to mpn.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpn_add 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpn/generic/add_1.c b/gmp/mpn/generic/add_1.c
new file mode 100644
index 0000000000..ca2d866852
--- /dev/null
+++ b/gmp/mpn/generic/add_1.c
@@ -0,0 +1,34 @@
+/* mpn_add_1 - add limb to mpn.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpn_add_1 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpn/generic/add_err1_n.c b/gmp/mpn/generic/add_err1_n.c
new file mode 100644
index 0000000000..b8cb75f6e8
--- /dev/null
+++ b/gmp/mpn/generic/add_err1_n.c
@@ -0,0 +1,101 @@
+/* mpn_add_err1_n -- add_n with one error term
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*
+ Computes:
+
+ (1) {rp,n} := {up,n} + {vp,n} (just like mpn_add_n) with incoming carry cy,
+ return value is carry out.
+
+ (2) Let c[i+1] = carry from i-th limb addition (c[0] = cy).
+ Computes c[1]*yp[n-1] + ... + c[n]*yp[0], stores two-limb result at ep.
+
+ Requires n >= 1.
+
+ None of the outputs may overlap each other or any of the inputs, except
+ that {rp,n} may be equal to {up,n} or {vp,n}.
+*/
+mp_limb_t
+mpn_add_err1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_ptr ep, mp_srcptr yp,
+ mp_size_t n, mp_limb_t cy)
+{
+ mp_limb_t el, eh, ul, vl, yl, zl, rl, sl, cy1, cy2;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 2, up, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 2, vp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 2, yp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 2, rp, n));
+
+ yp += n - 1;
+ el = eh = 0;
+
+ do
+ {
+ yl = *yp--;
+ ul = *up++;
+ vl = *vp++;
+
+ /* ordinary add_n */
+ ADDC_LIMB (cy1, sl, ul, vl);
+ ADDC_LIMB (cy2, rl, sl, cy);
+ cy = cy1 | cy2;
+ *rp++ = rl;
+
+ /* update (eh:el) */
+ zl = (-cy) & yl;
+ el += zl;
+ eh += el < zl;
+ }
+ while (--n);
+
+#if GMP_NAIL_BITS != 0
+ eh = (eh << GMP_NAIL_BITS) + (el >> GMP_NUMB_BITS);
+ el &= GMP_NUMB_MASK;
+#endif
+
+ ep[0] = el;
+ ep[1] = eh;
+
+ return cy;
+}
diff --git a/gmp/mpn/generic/add_err2_n.c b/gmp/mpn/generic/add_err2_n.c
new file mode 100644
index 0000000000..4b0242a32d
--- /dev/null
+++ b/gmp/mpn/generic/add_err2_n.c
@@ -0,0 +1,117 @@
+/* mpn_add_err2_n -- add_n with two error terms
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*
+ Computes:
+
+ (1) {rp,n} := {up,n} + {vp,n} (just like mpn_add_n) with incoming carry cy,
+ return value is carry out.
+
+ (2) Let c[i+1] = carry from i-th limb addition (c[0] = cy).
+ Computes c[1]*yp1[n-1] + ... + c[n]*yp1[0],
+ c[1]*yp2[n-1] + ... + c[n]*yp2[0],
+ stores two-limb results at {ep,2} and {ep+2,2} respectively.
+
+ Requires n >= 1.
+
+ None of the outputs may overlap each other or any of the inputs, except
+ that {rp,n} may be equal to {up,n} or {vp,n}.
+*/
+mp_limb_t
+mpn_add_err2_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_ptr ep, mp_srcptr yp1, mp_srcptr yp2,
+ mp_size_t n, mp_limb_t cy)
+{
+ mp_limb_t el1, eh1, el2, eh2, ul, vl, yl1, yl2, zl1, zl2, rl, sl, cy1, cy2;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp1, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp2, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, up, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, vp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, yp1, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, yp2, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, rp, n));
+
+ yp1 += n - 1;
+ yp2 += n - 1;
+ el1 = eh1 = 0;
+ el2 = eh2 = 0;
+
+ do
+ {
+ yl1 = *yp1--;
+ yl2 = *yp2--;
+ ul = *up++;
+ vl = *vp++;
+
+ /* ordinary add_n */
+ ADDC_LIMB (cy1, sl, ul, vl);
+ ADDC_LIMB (cy2, rl, sl, cy);
+ cy = cy1 | cy2;
+ *rp++ = rl;
+
+ /* update (eh1:el1) */
+ zl1 = (-cy) & yl1;
+ el1 += zl1;
+ eh1 += el1 < zl1;
+
+ /* update (eh2:el2) */
+ zl2 = (-cy) & yl2;
+ el2 += zl2;
+ eh2 += el2 < zl2;
+ }
+ while (--n);
+
+#if GMP_NAIL_BITS != 0
+ eh1 = (eh1 << GMP_NAIL_BITS) + (el1 >> GMP_NUMB_BITS);
+ el1 &= GMP_NUMB_MASK;
+ eh2 = (eh2 << GMP_NAIL_BITS) + (el2 >> GMP_NUMB_BITS);
+ el2 &= GMP_NUMB_MASK;
+#endif
+
+ ep[0] = el1;
+ ep[1] = eh1;
+ ep[2] = el2;
+ ep[3] = eh2;
+
+ return cy;
+}
diff --git a/gmp/mpn/generic/add_err3_n.c b/gmp/mpn/generic/add_err3_n.c
new file mode 100644
index 0000000000..28cd7facf9
--- /dev/null
+++ b/gmp/mpn/generic/add_err3_n.c
@@ -0,0 +1,132 @@
+/* mpn_add_err3_n -- add_n with three error terms
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*
+ Computes:
+
+ (1) {rp,n} := {up,n} + {vp,n} (just like mpn_add_n) with incoming carry cy,
+ return value is carry out.
+
+ (2) Let c[i+1] = carry from i-th limb addition (c[0] = cy).
+ Computes c[1]*yp1[n-1] + ... + c[n]*yp1[0],
+ c[1]*yp2[n-1] + ... + c[n]*yp2[0],
+ c[1]*yp3[n-1] + ... + c[n]*yp3[0],
+ stores two-limb results at {ep,2}, {ep+2,2} and {ep+4,2} respectively.
+
+ Requires n >= 1.
+
+ None of the outputs may overlap each other or any of the inputs, except
+ that {rp,n} may be equal to {up,n} or {vp,n}.
+*/
+mp_limb_t
+mpn_add_err3_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_ptr ep, mp_srcptr yp1, mp_srcptr yp2, mp_srcptr yp3,
+ mp_size_t n, mp_limb_t cy)
+{
+ mp_limb_t el1, eh1, el2, eh2, el3, eh3, ul, vl, yl1, yl2, yl3, zl1, zl2, zl3, rl, sl, cy1, cy2;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp1, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp2, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp3, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, up, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, vp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, yp1, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, yp2, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, yp3, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, rp, n));
+
+ yp1 += n - 1;
+ yp2 += n - 1;
+ yp3 += n - 1;
+ el1 = eh1 = 0;
+ el2 = eh2 = 0;
+ el3 = eh3 = 0;
+
+ do
+ {
+ yl1 = *yp1--;
+ yl2 = *yp2--;
+ yl3 = *yp3--;
+ ul = *up++;
+ vl = *vp++;
+
+ /* ordinary add_n */
+ ADDC_LIMB (cy1, sl, ul, vl);
+ ADDC_LIMB (cy2, rl, sl, cy);
+ cy = cy1 | cy2;
+ *rp++ = rl;
+
+ /* update (eh1:el1) */
+ zl1 = (-cy) & yl1;
+ el1 += zl1;
+ eh1 += el1 < zl1;
+
+ /* update (eh2:el2) */
+ zl2 = (-cy) & yl2;
+ el2 += zl2;
+ eh2 += el2 < zl2;
+
+ /* update (eh3:el3) */
+ zl3 = (-cy) & yl3;
+ el3 += zl3;
+ eh3 += el3 < zl3;
+ }
+ while (--n);
+
+#if GMP_NAIL_BITS != 0
+ eh1 = (eh1 << GMP_NAIL_BITS) + (el1 >> GMP_NUMB_BITS);
+ el1 &= GMP_NUMB_MASK;
+ eh2 = (eh2 << GMP_NAIL_BITS) + (el2 >> GMP_NUMB_BITS);
+ el2 &= GMP_NUMB_MASK;
+ eh3 = (eh3 << GMP_NAIL_BITS) + (el3 >> GMP_NUMB_BITS);
+ el3 &= GMP_NUMB_MASK;
+#endif
+
+ ep[0] = el1;
+ ep[1] = eh1;
+ ep[2] = el2;
+ ep[3] = eh2;
+ ep[4] = el3;
+ ep[5] = eh3;
+
+ return cy;
+}
diff --git a/gmp/mpn/generic/add_n.c b/gmp/mpn/generic/add_n.c
new file mode 100644
index 0000000000..1a07670900
--- /dev/null
+++ b/gmp/mpn/generic/add_n.c
@@ -0,0 +1,90 @@
+/* mpn_add_n -- Add equal length limb vectors.
+
+Copyright 1992-1994, 1996, 2000, 2002, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#if GMP_NAIL_BITS == 0
+
+mp_limb_t
+mpn_add_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t ul, vl, sl, rl, cy, cy1, cy2;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_INCR_P (rp, vp, n));
+
+ cy = 0;
+ do
+ {
+ ul = *up++;
+ vl = *vp++;
+ sl = ul + vl;
+ cy1 = sl < ul;
+ rl = sl + cy;
+ cy2 = rl < sl;
+ cy = cy1 | cy2;
+ *rp++ = rl;
+ }
+ while (--n != 0);
+
+ return cy;
+}
+
+#endif
+
+#if GMP_NAIL_BITS >= 1
+
+mp_limb_t
+mpn_add_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t ul, vl, rl, cy;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_INCR_P (rp, vp, n));
+
+ cy = 0;
+ do
+ {
+ ul = *up++;
+ vl = *vp++;
+ rl = ul + vl + cy;
+ cy = rl >> GMP_NUMB_BITS;
+ *rp++ = rl & GMP_NUMB_MASK;
+ }
+ while (--n != 0);
+
+ return cy;
+}
+
+#endif
diff --git a/gmp/mpn/generic/add_n_sub_n.c b/gmp/mpn/generic/add_n_sub_n.c
new file mode 100644
index 0000000000..012eb3e33a
--- /dev/null
+++ b/gmp/mpn/generic/add_n_sub_n.c
@@ -0,0 +1,173 @@
+/* mpn_add_n_sub_n -- Add and Subtract two limb vectors of equal, non-zero length.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 1999-2001, 2006 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef L1_CACHE_SIZE
+#define L1_CACHE_SIZE 8192 /* only 68040 has less than this */
+#endif
+
+#define PART_SIZE (L1_CACHE_SIZE / GMP_LIMB_BYTES / 6)
+
+
+/* mpn_add_n_sub_n.
+ r1[] = s1[] + s2[]
+ r2[] = s1[] - s2[]
+ All operands have n limbs.
+ In-place operations allowed. */
+mp_limb_t
+mpn_add_n_sub_n (mp_ptr r1p, mp_ptr r2p, mp_srcptr s1p, mp_srcptr s2p, mp_size_t n)
+{
+ mp_limb_t acyn, acyo; /* carry for add */
+ mp_limb_t scyn, scyo; /* carry for subtract */
+ mp_size_t off; /* offset in operands */
+ mp_size_t this_n; /* size of current chunk */
+
+ /* We alternatingly add and subtract in chunks that fit into the (L1)
+ cache. Since the chunks are several hundred limbs, the function call
+ overhead is insignificant, but we get much better locality. */
+
+ /* We have three variant of the inner loop, the proper loop is chosen
+ depending on whether r1 or r2 are the same operand as s1 or s2. */
+
+ if (r1p != s1p && r1p != s2p)
+ {
+ /* r1 is not identical to either input operand. We can therefore write
+ to r1 directly, without using temporary storage. */
+ acyo = 0;
+ scyo = 0;
+ for (off = 0; off < n; off += PART_SIZE)
+ {
+ this_n = MIN (n - off, PART_SIZE);
+#if HAVE_NATIVE_mpn_add_nc
+ acyo = mpn_add_nc (r1p + off, s1p + off, s2p + off, this_n, acyo);
+#else
+ acyn = mpn_add_n (r1p + off, s1p + off, s2p + off, this_n);
+ acyo = acyn + mpn_add_1 (r1p + off, r1p + off, this_n, acyo);
+#endif
+#if HAVE_NATIVE_mpn_sub_nc
+ scyo = mpn_sub_nc (r2p + off, s1p + off, s2p + off, this_n, scyo);
+#else
+ scyn = mpn_sub_n (r2p + off, s1p + off, s2p + off, this_n);
+ scyo = scyn + mpn_sub_1 (r2p + off, r2p + off, this_n, scyo);
+#endif
+ }
+ }
+ else if (r2p != s1p && r2p != s2p)
+ {
+ /* r2 is not identical to either input operand. We can therefore write
+ to r2 directly, without using temporary storage. */
+ acyo = 0;
+ scyo = 0;
+ for (off = 0; off < n; off += PART_SIZE)
+ {
+ this_n = MIN (n - off, PART_SIZE);
+#if HAVE_NATIVE_mpn_sub_nc
+ scyo = mpn_sub_nc (r2p + off, s1p + off, s2p + off, this_n, scyo);
+#else
+ scyn = mpn_sub_n (r2p + off, s1p + off, s2p + off, this_n);
+ scyo = scyn + mpn_sub_1 (r2p + off, r2p + off, this_n, scyo);
+#endif
+#if HAVE_NATIVE_mpn_add_nc
+ acyo = mpn_add_nc (r1p + off, s1p + off, s2p + off, this_n, acyo);
+#else
+ acyn = mpn_add_n (r1p + off, s1p + off, s2p + off, this_n);
+ acyo = acyn + mpn_add_1 (r1p + off, r1p + off, this_n, acyo);
+#endif
+ }
+ }
+ else
+ {
+ /* r1 and r2 are identical to s1 and s2 (r1==s1 and r2==s2 or vice versa)
+ Need temporary storage. */
+ mp_limb_t tp[PART_SIZE];
+ acyo = 0;
+ scyo = 0;
+ for (off = 0; off < n; off += PART_SIZE)
+ {
+ this_n = MIN (n - off, PART_SIZE);
+#if HAVE_NATIVE_mpn_add_nc
+ acyo = mpn_add_nc (tp, s1p + off, s2p + off, this_n, acyo);
+#else
+ acyn = mpn_add_n (tp, s1p + off, s2p + off, this_n);
+ acyo = acyn + mpn_add_1 (tp, tp, this_n, acyo);
+#endif
+#if HAVE_NATIVE_mpn_sub_nc
+ scyo = mpn_sub_nc (r2p + off, s1p + off, s2p + off, this_n, scyo);
+#else
+ scyn = mpn_sub_n (r2p + off, s1p + off, s2p + off, this_n);
+ scyo = scyn + mpn_sub_1 (r2p + off, r2p + off, this_n, scyo);
+#endif
+ MPN_COPY (r1p + off, tp, this_n);
+ }
+ }
+
+ return 2 * acyo + scyo;
+}
+
+#ifdef MAIN
+#include <stdlib.h>
+#include <stdio.h>
+#include "timing.h"
+
+long cputime ();
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr r1p, r2p, s1p, s2p;
+ double t;
+ mp_size_t n;
+
+ n = strtol (argv[1], 0, 0);
+
+ r1p = malloc (n * GMP_LIMB_BYTES);
+ r2p = malloc (n * GMP_LIMB_BYTES);
+ s1p = malloc (n * GMP_LIMB_BYTES);
+ s2p = malloc (n * GMP_LIMB_BYTES);
+ TIME (t,(mpn_add_n(r1p,s1p,s2p,n),mpn_sub_n(r1p,s1p,s2p,n)));
+ printf (" separate add and sub: %.3f\n", t);
+ TIME (t,mpn_add_n_sub_n(r1p,r2p,s1p,s2p,n));
+ printf ("combined addsub separate variables: %.3f\n", t);
+ TIME (t,mpn_add_n_sub_n(r1p,r2p,r1p,s2p,n));
+ printf (" combined addsub r1 overlap: %.3f\n", t);
+ TIME (t,mpn_add_n_sub_n(r1p,r2p,r1p,s2p,n));
+ printf (" combined addsub r2 overlap: %.3f\n", t);
+ TIME (t,mpn_add_n_sub_n(r1p,r2p,r1p,r2p,n));
+ printf (" combined addsub in-place: %.3f\n", t);
+
+ return 0;
+}
+#endif
diff --git a/gmp/mpn/generic/addmul_1.c b/gmp/mpn/generic/addmul_1.c
new file mode 100644
index 0000000000..d76b4ad135
--- /dev/null
+++ b/gmp/mpn/generic/addmul_1.c
@@ -0,0 +1,139 @@
+/* mpn_addmul_1 -- multiply the N long limb vector pointed to by UP by VL,
+ add the N least significant limbs of the product to the limb vector
+ pointed to by RP. Return the most significant limb of the product,
+ adjusted for carry-out from the addition.
+
+Copyright 1992-1994, 1996, 2000, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#if GMP_NAIL_BITS == 0
+
+mp_limb_t
+mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t ul, cl, hpl, lpl, rl;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+
+ cl = 0;
+ do
+ {
+ ul = *up++;
+ umul_ppmm (hpl, lpl, ul, vl);
+
+ lpl += cl;
+ cl = (lpl < cl) + hpl;
+
+ rl = *rp;
+ lpl = rl + lpl;
+ cl += lpl < rl;
+ *rp++ = lpl;
+ }
+ while (--n != 0);
+
+ return cl;
+}
+
+#endif
+
+#if GMP_NAIL_BITS == 1
+
+mp_limb_t
+mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t shifted_vl, ul, rl, lpl, hpl, prev_hpl, cl, xl, c1, c2, c3;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT_MPN (rp, n);
+ ASSERT_MPN (up, n);
+ ASSERT_LIMB (vl);
+
+ shifted_vl = vl << GMP_NAIL_BITS;
+ cl = 0;
+ prev_hpl = 0;
+ do
+ {
+ ul = *up++;
+ rl = *rp;
+ umul_ppmm (hpl, lpl, ul, shifted_vl);
+ lpl >>= GMP_NAIL_BITS;
+ ADDC_LIMB (c1, xl, prev_hpl, lpl);
+ ADDC_LIMB (c2, xl, xl, rl);
+ ADDC_LIMB (c3, xl, xl, cl);
+ cl = c1 + c2 + c3;
+ *rp++ = xl;
+ prev_hpl = hpl;
+ }
+ while (--n != 0);
+
+ return prev_hpl + cl;
+}
+
+#endif
+
+#if GMP_NAIL_BITS >= 2
+
+mp_limb_t
+mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t shifted_vl, ul, rl, lpl, hpl, prev_hpl, xw, cl, xl;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT_MPN (rp, n);
+ ASSERT_MPN (up, n);
+ ASSERT_LIMB (vl);
+
+ shifted_vl = vl << GMP_NAIL_BITS;
+ cl = 0;
+ prev_hpl = 0;
+ do
+ {
+ ul = *up++;
+ rl = *rp;
+ umul_ppmm (hpl, lpl, ul, shifted_vl);
+ lpl >>= GMP_NAIL_BITS;
+ xw = prev_hpl + lpl + rl + cl;
+ cl = xw >> GMP_NUMB_BITS;
+ xl = xw & GMP_NUMB_MASK;
+ *rp++ = xl;
+ prev_hpl = hpl;
+ }
+ while (--n != 0);
+
+ return prev_hpl + cl;
+}
+
+#endif
diff --git a/gmp/mpn/generic/bdiv_dbm1c.c b/gmp/mpn/generic/bdiv_dbm1c.c
new file mode 100644
index 0000000000..22c3cfd2c8
--- /dev/null
+++ b/gmp/mpn/generic/bdiv_dbm1c.c
@@ -0,0 +1,59 @@
+/* mpn_bdiv_dbm1c -- divide an mpn number by a divisor of B-1, where B is the
+ limb base. The dbm1c moniker means "Divisor of B Minus 1 with Carry".
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2008, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+mp_limb_t
+mpn_bdiv_dbm1c (mp_ptr qp, mp_srcptr ap, mp_size_t n, mp_limb_t bd, mp_limb_t h)
+{
+ mp_limb_t a, p0, p1, cy;
+ mp_size_t i;
+
+ for (i = 0; i < n; i++)
+ {
+ a = ap[i];
+ umul_ppmm (p1, p0, a, bd << GMP_NAIL_BITS);
+ p0 >>= GMP_NAIL_BITS;
+ cy = h < p0;
+ h = (h - p0) & GMP_NUMB_MASK;
+ qp[i] = h;
+ h = h - p1 - cy;
+ }
+
+ return h;
+}
diff --git a/gmp/mpn/generic/bdiv_q.c b/gmp/mpn/generic/bdiv_q.c
new file mode 100644
index 0000000000..1fc1bb7c09
--- /dev/null
+++ b/gmp/mpn/generic/bdiv_q.c
@@ -0,0 +1,77 @@
+/* mpn_bdiv_q -- Hensel division with precomputed inverse, returning quotient.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Computes Q = N / D mod B^n. */
+
+void
+mpn_bdiv_q (mp_ptr qp,
+ mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_ptr tp)
+{
+ mp_limb_t di;
+
+ if (BELOW_THRESHOLD (dn, DC_BDIV_Q_THRESHOLD))
+ {
+ MPN_COPY (tp, np, nn);
+ binvert_limb (di, dp[0]); di = -di;
+ mpn_sbpi1_bdiv_q (qp, tp, nn, dp, dn, di);
+ }
+ else if (BELOW_THRESHOLD (dn, MU_BDIV_Q_THRESHOLD))
+ {
+ MPN_COPY (tp, np, nn);
+ binvert_limb (di, dp[0]); di = -di;
+ mpn_dcpi1_bdiv_q (qp, tp, nn, dp, dn, di);
+ }
+ else
+ {
+ mpn_mu_bdiv_q (qp, np, nn, dp, dn, tp);
+ }
+ return;
+}
+
+mp_size_t
+mpn_bdiv_q_itch (mp_size_t nn, mp_size_t dn)
+{
+ if (BELOW_THRESHOLD (dn, MU_BDIV_Q_THRESHOLD))
+ return nn;
+ else
+ return mpn_mu_bdiv_q_itch (nn, dn);
+}
diff --git a/gmp/mpn/generic/bdiv_q_1.c b/gmp/mpn/generic/bdiv_q_1.c
new file mode 100644
index 0000000000..74b247d5a9
--- /dev/null
+++ b/gmp/mpn/generic/bdiv_q_1.c
@@ -0,0 +1,126 @@
+/* mpn_bdiv_q_1, mpn_pi1_bdiv_q_1 -- schoolbook Hensel division by 1-limb
+ divisor, returning quotient only.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2000-2003, 2005, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_pi1_bdiv_q_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t d,
+ mp_limb_t di, int shift)
+{
+ mp_size_t i;
+ mp_limb_t c, h, l, u, u_next, dummy;
+
+ ASSERT (n >= 1);
+ ASSERT (d != 0);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT_MPN (up, n);
+ ASSERT_LIMB (d);
+
+ d <<= GMP_NAIL_BITS;
+
+ if (shift != 0)
+ {
+ c = 0;
+
+ u = up[0];
+ rp--;
+ for (i = 1; i < n; i++)
+ {
+ u_next = up[i];
+ u = ((u >> shift) | (u_next << (GMP_NUMB_BITS-shift))) & GMP_NUMB_MASK;
+
+ SUBC_LIMB (c, l, u, c);
+
+ l = (l * di) & GMP_NUMB_MASK;
+ rp[i] = l;
+
+ umul_ppmm (h, dummy, l, d);
+ c += h;
+ u = u_next;
+ }
+
+ u = u >> shift;
+ l = u - c;
+ l = (l * di) & GMP_NUMB_MASK;
+ rp[i] = l;
+ }
+ else
+ {
+ u = up[0];
+ l = (u * di) & GMP_NUMB_MASK;
+ rp[0] = l;
+ c = 0;
+
+ for (i = 1; i < n; i++)
+ {
+ umul_ppmm (h, dummy, l, d);
+ c += h;
+
+ u = up[i];
+ SUBC_LIMB (c, l, u, c);
+
+ l = (l * di) & GMP_NUMB_MASK;
+ rp[i] = l;
+ }
+ }
+
+ return c;
+}
+
+mp_limb_t
+mpn_bdiv_q_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t d)
+{
+ mp_limb_t di;
+ int shift;
+
+ ASSERT (n >= 1);
+ ASSERT (d != 0);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT_MPN (up, n);
+ ASSERT_LIMB (d);
+
+ if ((d & 1) == 0)
+ {
+ count_trailing_zeros (shift, d);
+ d >>= shift;
+ }
+ else
+ shift = 0;
+
+ binvert_limb (di, d);
+ return mpn_pi1_bdiv_q_1 (rp, up, n, d, di, shift);
+}
diff --git a/gmp/mpn/generic/bdiv_qr.c b/gmp/mpn/generic/bdiv_qr.c
new file mode 100644
index 0000000000..6a5eedbbc2
--- /dev/null
+++ b/gmp/mpn/generic/bdiv_qr.c
@@ -0,0 +1,85 @@
+/* mpn_bdiv_qr -- Hensel division with precomputed inverse, returning quotient
+ and remainder.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2006, 2007, 2009, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Computes Q = N / D mod B^n,
+ R = N - QD. */
+
+mp_limb_t
+mpn_bdiv_qr (mp_ptr qp, mp_ptr rp,
+ mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_ptr tp)
+{
+ mp_limb_t di;
+ mp_limb_t rh;
+
+ ASSERT (nn > dn);
+ if (BELOW_THRESHOLD (dn, DC_BDIV_QR_THRESHOLD) ||
+ BELOW_THRESHOLD (nn - dn, DC_BDIV_QR_THRESHOLD))
+ {
+ MPN_COPY (tp, np, nn);
+ binvert_limb (di, dp[0]); di = -di;
+ rh = mpn_sbpi1_bdiv_qr (qp, tp, nn, dp, dn, di);
+ MPN_COPY (rp, tp + nn - dn, dn);
+ }
+ else if (BELOW_THRESHOLD (dn, MU_BDIV_QR_THRESHOLD))
+ {
+ MPN_COPY (tp, np, nn);
+ binvert_limb (di, dp[0]); di = -di;
+ rh = mpn_dcpi1_bdiv_qr (qp, tp, nn, dp, dn, di);
+ MPN_COPY (rp, tp + nn - dn, dn);
+ }
+ else
+ {
+ rh = mpn_mu_bdiv_qr (qp, rp, np, nn, dp, dn, tp);
+ }
+
+ return rh;
+}
+
+mp_size_t
+mpn_bdiv_qr_itch (mp_size_t nn, mp_size_t dn)
+{
+ if (BELOW_THRESHOLD (dn, MU_BDIV_QR_THRESHOLD))
+ return nn;
+ else
+ return mpn_mu_bdiv_qr_itch (nn, dn);
+}
diff --git a/gmp/mpn/generic/binvert.c b/gmp/mpn/generic/binvert.c
new file mode 100644
index 0000000000..be27ea552e
--- /dev/null
+++ b/gmp/mpn/generic/binvert.c
@@ -0,0 +1,102 @@
+/* Compute {up,n}^(-1) mod B^n.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright (C) 2004-2007, 2009, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/*
+ r[k+1] = r[k] - r[k] * (u*r[k] - 1)
+ r[k+1] = r[k] + r[k] - r[k]*(u*r[k])
+*/
+
+#if TUNE_PROGRAM_BUILD
+#define NPOWS \
+ ((sizeof(mp_size_t) > 6 ? 48 : 8*sizeof(mp_size_t)))
+#else
+#define NPOWS \
+ ((sizeof(mp_size_t) > 6 ? 48 : 8*sizeof(mp_size_t)) - LOG2C (BINV_NEWTON_THRESHOLD))
+#endif
+
+mp_size_t
+mpn_binvert_itch (mp_size_t n)
+{
+ mp_size_t itch_local = mpn_mulmod_bnm1_next_size (n);
+ mp_size_t itch_out = mpn_mulmod_bnm1_itch (itch_local, n, (n + 1) >> 1);
+ return itch_local + itch_out;
+}
+
+void
+mpn_binvert (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_ptr scratch)
+{
+ mp_ptr xp;
+ mp_size_t rn, newrn;
+ mp_size_t sizes[NPOWS], *sizp;
+ mp_limb_t di;
+
+ /* Compute the computation precisions from highest to lowest, leaving the
+ base case size in 'rn'. */
+ sizp = sizes;
+ for (rn = n; ABOVE_THRESHOLD (rn, BINV_NEWTON_THRESHOLD); rn = (rn + 1) >> 1)
+ *sizp++ = rn;
+
+ xp = scratch;
+
+ /* Compute a base value of rn limbs. */
+ MPN_ZERO (xp, rn);
+ xp[0] = 1;
+ binvert_limb (di, up[0]);
+ if (BELOW_THRESHOLD (rn, DC_BDIV_Q_THRESHOLD))
+ mpn_sbpi1_bdiv_q (rp, xp, rn, up, rn, -di);
+ else
+ mpn_dcpi1_bdiv_q (rp, xp, rn, up, rn, -di);
+
+ /* Use Newton iterations to get the desired precision. */
+ for (; rn < n; rn = newrn)
+ {
+ mp_size_t m;
+ newrn = *--sizp;
+
+ /* X <- UR. */
+ m = mpn_mulmod_bnm1_next_size (newrn);
+ mpn_mulmod_bnm1 (xp, m, up, newrn, rp, rn, xp + m);
+ mpn_sub_1 (xp + m, xp, rn - (m - newrn), 1);
+
+ /* R = R(X/B^rn) */
+ mpn_mullo_n (rp + rn, rp, xp + rn, newrn - rn);
+ mpn_neg (rp + rn, rp + rn, newrn - rn);
+ }
+}
diff --git a/gmp/mpn/generic/broot.c b/gmp/mpn/generic/broot.c
new file mode 100644
index 0000000000..6974ac8b9e
--- /dev/null
+++ b/gmp/mpn/generic/broot.c
@@ -0,0 +1,196 @@
+/* mpn_broot -- Compute hensel sqrt
+
+ Contributed to the GNU project by Niels Möller
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Computes a^e (mod B). Uses right-to-left binary algorithm, since
+ typical use will have e small. */
+static mp_limb_t
+powlimb (mp_limb_t a, mp_limb_t e)
+{
+ mp_limb_t r = 1;
+ mp_limb_t s = a;
+
+ for (r = 1, s = a; e > 0; e >>= 1, s *= s)
+ if (e & 1)
+ r *= s;
+
+ return r;
+}
+
+/* Computes a^{1/k - 1} (mod B^n). Both a and k must be odd.
+
+ Iterates
+
+ r' <-- r - r * (a^{k-1} r^k - 1) / n
+
+ If
+
+ a^{k-1} r^k = 1 (mod 2^m),
+
+ then
+
+ a^{k-1} r'^k = 1 (mod 2^{2m}),
+
+ Compute the update term as
+
+ r' = r - (a^{k-1} r^{k+1} - r) / k
+
+ where we still have cancellation of low limbs.
+
+ */
+void
+mpn_broot_invm1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t k)
+{
+ mp_size_t sizes[GMP_LIMB_BITS * 2];
+ mp_ptr akm1, tp, rnp, ep;
+ mp_limb_t a0, r0, km1, kp1h, kinv;
+ mp_size_t rn;
+ unsigned i;
+
+ TMP_DECL;
+
+ ASSERT (n > 0);
+ ASSERT (ap[0] & 1);
+ ASSERT (k & 1);
+ ASSERT (k >= 3);
+
+ TMP_MARK;
+
+ akm1 = TMP_ALLOC_LIMBS (4*n);
+ tp = akm1 + n;
+
+ km1 = k-1;
+ /* FIXME: Could arrange the iteration so we don't need to compute
+ this up front, computing a^{k-1} * r^k as (a r)^{k-1} * r. Note
+ that we can use wraparound also for a*r, since the low half is
+ unchanged from the previous iteration. Or possibly mulmid. Also,
+ a r = a^{1/k}, so we get that value too, for free? */
+ mpn_powlo (akm1, ap, &km1, 1, n, tp); /* 3 n scratch space */
+
+ a0 = ap[0];
+ binvert_limb (kinv, k);
+
+ /* 4 bits: a^{1/k - 1} (mod 16):
+
+ a % 8
+ 1 3 5 7
+ k%4 +-------
+ 1 |1 1 1 1
+ 3 |1 9 9 1
+ */
+ r0 = 1 + (((k << 2) & ((a0 << 1) ^ (a0 << 2))) & 8);
+ r0 = kinv * r0 * (k+1 - akm1[0] * powlimb (r0, k & 0x7f)); /* 8 bits */
+ r0 = kinv * r0 * (k+1 - akm1[0] * powlimb (r0, k & 0x7fff)); /* 16 bits */
+ r0 = kinv * r0 * (k+1 - akm1[0] * powlimb (r0, k)); /* 32 bits */
+#if GMP_NUMB_BITS > 32
+ {
+ unsigned prec = 32;
+ do
+ {
+ r0 = kinv * r0 * (k+1 - akm1[0] * powlimb (r0, k));
+ prec *= 2;
+ }
+ while (prec < GMP_NUMB_BITS);
+ }
+#endif
+
+ rp[0] = r0;
+ if (n == 1)
+ {
+ TMP_FREE;
+ return;
+ }
+
+ /* For odd k, (k+1)/2 = k/2+1, and the latter avoids overflow. */
+ kp1h = k/2 + 1;
+
+ /* FIXME: Special case for two limb iteration. */
+ rnp = TMP_ALLOC_LIMBS (2*n + 1);
+ ep = rnp + n;
+
+ /* FIXME: Possible to this on the fly with some bit fiddling. */
+ for (i = 0; n > 1; n = (n + 1)/2)
+ sizes[i++] = n;
+
+ rn = 1;
+
+ while (i-- > 0)
+ {
+ /* Compute x^{k+1}. */
+ mpn_sqr (ep, rp, rn); /* For odd n, writes n+1 limbs in the
+ final iteration. */
+ mpn_powlo (rnp, ep, &kp1h, 1, sizes[i], tp);
+
+ /* Multiply by a^{k-1}. Can use wraparound; low part equals r. */
+
+ mpn_mullo_n (ep, rnp, akm1, sizes[i]);
+ ASSERT (mpn_cmp (ep, rp, rn) == 0);
+
+ ASSERT (sizes[i] <= 2*rn);
+ mpn_pi1_bdiv_q_1 (rp + rn, ep + rn, sizes[i] - rn, k, kinv, 0);
+ mpn_neg (rp + rn, rp + rn, sizes[i] - rn);
+ rn = sizes[i];
+ }
+ TMP_FREE;
+}
+
+/* Computes a^{1/k} (mod B^n). Both a and k must be odd. */
+void
+mpn_broot (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t k)
+{
+ mp_ptr tp;
+ TMP_DECL;
+
+ ASSERT (n > 0);
+ ASSERT (ap[0] & 1);
+ ASSERT (k & 1);
+
+ if (k == 1)
+ {
+ MPN_COPY (rp, ap, n);
+ return;
+ }
+
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS (n);
+
+ mpn_broot_invm1 (tp, ap, n, k);
+ mpn_mullo_n (rp, tp, ap, n);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/brootinv.c b/gmp/mpn/generic/brootinv.c
new file mode 100644
index 0000000000..b96c97f1d3
--- /dev/null
+++ b/gmp/mpn/generic/brootinv.c
@@ -0,0 +1,140 @@
+/* mpn_brootinv, compute r such that r^k * y = 1 (mod 2^b).
+
+ Contributed to the GNU project by Martin Boij (as part of perfpow.c).
+
+Copyright 2009, 2010, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Computes a^e (mod B). Uses right-to-left binary algorithm, since
+ typical use will have e small. */
+static mp_limb_t
+powlimb (mp_limb_t a, mp_limb_t e)
+{
+ mp_limb_t r;
+
+ for (r = 1; e > 0; e >>= 1, a *= a)
+ if (e & 1)
+ r *= a;
+
+ return r;
+}
+
+/* Compute r such that r^k * y = 1 (mod B^n).
+
+ Iterates
+ r' <-- k^{-1} ((k+1) r - r^{k+1} y) (mod 2^b)
+ using Hensel lifting, each time doubling the number of known bits in r.
+
+ Works just for odd k. Else the Hensel lifting degenerates.
+
+ FIXME:
+
+ (1) Make it work for k == GMP_LIMB_MAX (k+1 below overflows).
+
+ (2) Rewrite iteration as
+ r' <-- r - k^{-1} r (r^k y - 1)
+ and take advantage of the zero low part of r^k y - 1.
+
+ (3) Use wrap-around trick.
+
+ (4) Use a small table to get starting value.
+
+ Scratch need: 5*bn, where bn = ceil (bnb / GMP_NUMB_BITS).
+*/
+
+void
+mpn_brootinv (mp_ptr rp, mp_srcptr yp, mp_size_t bn, mp_limb_t k, mp_ptr tp)
+{
+ mp_ptr tp2, tp3;
+ mp_limb_t kinv, k2, r0, y0;
+ mp_size_t order[GMP_LIMB_BITS + 1];
+ int i, d;
+
+ ASSERT (bn > 0);
+ ASSERT ((k & 1) != 0);
+
+ tp2 = tp + bn;
+ tp3 = tp + 2 * bn;
+ k2 = k + 1;
+
+ binvert_limb (kinv, k);
+
+ /* 4-bit initial approximation:
+
+ y%16 | 1 3 5 7 9 11 13 15,
+ k%4 +-------------------------+k2%4
+ 1 | 1 11 13 7 9 3 5 15 | 2
+ 3 | 1 3 5 7 9 11 13 15 | 0
+
+ */
+ y0 = yp[0];
+
+ r0 = y0 ^ (((y0 << 1) ^ (y0 << 2)) & (k2 << 2) & 8); /* 4 bits */
+ r0 = kinv * (k2 * r0 - y0 * powlimb(r0, k2 & 0x7f)); /* 8 bits */
+ r0 = kinv * (k2 * r0 - y0 * powlimb(r0, k2 & 0x7fff)); /* 16 bits */
+#if GMP_NUMB_BITS > 16
+ {
+ unsigned prec = 16;
+ do
+ {
+ r0 = kinv * (k2 * r0 - y0 * powlimb(r0, k2));
+ prec *= 2;
+ }
+ while (prec < GMP_NUMB_BITS);
+ }
+#endif
+
+ rp[0] = r0;
+ if (bn == 1)
+ return;
+
+ /* This initialization doesn't matter for the result (any garbage is
+ cancelled in the iteration), but proper initialization makes
+ valgrind happier. */
+ MPN_ZERO (rp+1, bn-1);
+
+ d = 0;
+ for (; bn > 1; bn = (bn + 1) >> 1)
+ order[d++] = bn;
+
+ for (i = d - 1; i >= 0; i--)
+ {
+ bn = order[i];
+
+ mpn_mul_1 (tp, rp, bn, k2);
+
+ mpn_powlo (tp2, rp, &k2, 1, bn, tp3);
+ mpn_mullo_n (rp, yp, tp2, bn);
+
+ mpn_sub_n (tp2, tp, rp, bn);
+ mpn_pi1_bdiv_q_1 (rp, tp2, bn, k, kinv, 0);
+ }
+}
diff --git a/gmp/mpn/generic/bsqrt.c b/gmp/mpn/generic/bsqrt.c
new file mode 100644
index 0000000000..18ba26f440
--- /dev/null
+++ b/gmp/mpn/generic/bsqrt.c
@@ -0,0 +1,48 @@
+/* mpn_bsqrt, a^{1/2} (mod 2^n).
+
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpn_bsqrt (mp_ptr rp, mp_srcptr ap, mp_bitcnt_t nb, mp_ptr tp)
+{
+ mp_ptr sp;
+ mp_size_t n;
+
+ ASSERT (nb > 0);
+
+ n = nb / GMP_NUMB_BITS;
+ sp = tp + n;
+
+ mpn_bsqrtinv (sp, ap, nb, tp);
+ mpn_mullo_n (rp, sp, ap, n);
+}
diff --git a/gmp/mpn/generic/bsqrtinv.c b/gmp/mpn/generic/bsqrtinv.c
new file mode 100644
index 0000000000..33df6a3c15
--- /dev/null
+++ b/gmp/mpn/generic/bsqrtinv.c
@@ -0,0 +1,105 @@
+/* mpn_bsqrtinv, compute r such that r^2 * y = 1 (mod 2^{b+1}).
+
+ Contributed to the GNU project by Martin Boij (as part of perfpow.c).
+
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Compute r such that r^2 * y = 1 (mod 2^{b+1}).
+ Return non-zero if such an integer r exists.
+
+ Iterates
+ r' <-- (3r - r^3 y) / 2
+ using Hensel lifting. Since we divide by two, the Hensel lifting is
+ somewhat degenerates. Therefore, we lift from 2^b to 2^{b+1}-1.
+
+ FIXME:
+ (1) Simplify to do precision book-keeping in limbs rather than bits.
+
+ (2) Rewrite iteration as
+ r' <-- r - r (r^2 y - 1) / 2
+ and take advantage of zero low part of r^2 y - 1.
+
+ (3) Use wrap-around trick.
+
+ (4) Use a small table to get starting value.
+*/
+int
+mpn_bsqrtinv (mp_ptr rp, mp_srcptr yp, mp_bitcnt_t bnb, mp_ptr tp)
+{
+ mp_ptr tp2, tp3;
+ mp_limb_t k;
+ mp_size_t bn, order[GMP_LIMB_BITS + 1];
+ int i, d;
+
+ ASSERT (bnb > 0);
+
+ bn = 1 + bnb / GMP_LIMB_BITS;
+
+ tp2 = tp + bn;
+ tp3 = tp + 2 * bn;
+ k = 3;
+
+ rp[0] = 1;
+ if (bnb == 1)
+ {
+ if ((yp[0] & 3) != 1)
+ return 0;
+ }
+ else
+ {
+ if ((yp[0] & 7) != 1)
+ return 0;
+
+ d = 0;
+ for (; bnb != 2; bnb = (bnb + 2) >> 1)
+ order[d++] = bnb;
+
+ for (i = d - 1; i >= 0; i--)
+ {
+ bnb = order[i];
+ bn = 1 + bnb / GMP_LIMB_BITS;
+
+ mpn_mul_1 (tp, rp, bn, k);
+
+ mpn_powlo (tp2, rp, &k, 1, bn, tp3);
+ mpn_mullo_n (rp, yp, tp2, bn);
+
+#if HAVE_NATIVE_mpn_rsh1sub_n
+ mpn_rsh1sub_n (rp, tp, rp, bn);
+#else
+ mpn_sub_n (tp2, tp, rp, bn);
+ mpn_rshift (rp, tp2, bn, 1);
+#endif
+ }
+ }
+ return 1;
+}
diff --git a/gmp/mpn/generic/cmp.c b/gmp/mpn/generic/cmp.c
new file mode 100644
index 0000000000..18c7b42844
--- /dev/null
+++ b/gmp/mpn/generic/cmp.c
@@ -0,0 +1,34 @@
+/* mpn_cmp -- Compare two low-level natural-number integers.
+
+Copyright 1991, 1993, 1994, 1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpn_cmp 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpn/generic/cnd_add_n.c b/gmp/mpn/generic/cnd_add_n.c
new file mode 100644
index 0000000000..443f9858da
--- /dev/null
+++ b/gmp/mpn/generic/cnd_add_n.c
@@ -0,0 +1,70 @@
+/* mpn_cnd_add_n -- Compute R = U + V if CND != 0 or R = U if CND == 0.
+ Both cases should take the same time and perform the exact same memory
+ accesses, since this function is intended to be used where side-channel
+ attack resilience is relevant.
+
+Copyright 1992-1994, 1996, 2000, 2002, 2008, 2009, 2011, 2013 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_cnd_add_n (mp_limb_t cnd, mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t ul, vl, sl, rl, cy, cy1, cy2, mask;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n));
+
+ mask = -(mp_limb_t) (cnd != 0);
+ cy = 0;
+ do
+ {
+ ul = *up++;
+ vl = *vp++ & mask;
+#if GMP_NAIL_BITS == 0
+ sl = ul + vl;
+ cy1 = sl < ul;
+ rl = sl + cy;
+ cy2 = rl < sl;
+ cy = cy1 | cy2;
+ *rp++ = rl;
+#else
+ rl = ul + vl;
+ rl += cy;
+ cy = rl >> GMP_NUMB_BITS;
+ *rp++ = rl & GMP_NUMB_MASK;
+#endif
+ }
+ while (--n != 0);
+
+ return cy;
+}
diff --git a/gmp/mpn/generic/cnd_sub_n.c b/gmp/mpn/generic/cnd_sub_n.c
new file mode 100644
index 0000000000..bd8e029a36
--- /dev/null
+++ b/gmp/mpn/generic/cnd_sub_n.c
@@ -0,0 +1,70 @@
+/* mpn_cnd_sub_n -- Compute R = U - V if CND != 0 or R = U if CND == 0.
+ Both cases should take the same time and perform the exact same memory
+ accesses, since this function is intended to be used where side-channel
+ attack resilience is relevant.
+
+Copyright 1992-1994, 1996, 2000, 2002, 2008, 2009, 2011, 2013 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_cnd_sub_n (mp_limb_t cnd, mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t ul, vl, sl, rl, cy, cy1, cy2, mask;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n));
+
+ mask = -(mp_limb_t) (cnd != 0);
+ cy = 0;
+ do
+ {
+ ul = *up++;
+ vl = *vp++ & mask;
+#if GMP_NAIL_BITS == 0
+ sl = ul - vl;
+ cy1 = sl > ul;
+ rl = sl - cy;
+ cy2 = rl > sl;
+ cy = cy1 | cy2;
+ *rp++ = rl;
+#else
+ rl = ul - vl;
+ rl -= cy;
+ cy = rl >> (GMP_LIMB_BITS - 1);
+ *rp++ = rl & GMP_NUMB_MASK;
+#endif
+ }
+ while (--n != 0);
+
+ return cy;
+}
diff --git a/gmp/mpn/generic/com.c b/gmp/mpn/generic/com.c
new file mode 100644
index 0000000000..cd8551df5b
--- /dev/null
+++ b/gmp/mpn/generic/com.c
@@ -0,0 +1,45 @@
+/* mpn_com - complement an mpn.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef mpn_com
+#define mpn_com __MPN(com)
+
+void
+mpn_com (mp_ptr rp, mp_srcptr up, mp_size_t n)
+{
+ mp_limb_t ul;
+ do {
+ ul = *up++;
+ *rp++ = ~ul & GMP_NUMB_MASK;
+ } while (--n != 0);
+}
diff --git a/gmp/mpn/generic/comb_tables.c b/gmp/mpn/generic/comb_tables.c
new file mode 100644
index 0000000000..41bcb5f879
--- /dev/null
+++ b/gmp/mpn/generic/comb_tables.c
@@ -0,0 +1,48 @@
+/* Const tables shared among combinatoric functions.
+
+ THE CONTENTS OF THIS FILE ARE FOR INTERNAL USE AND ARE ALMOST CERTAIN TO
+ BE SUBJECT TO INCOMPATIBLE CHANGES IN FUTURE GNU MP RELEASES.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Entry i contains (i!/2^t) where t is chosen such that the parenthesis
+ is an odd integer. */
+const mp_limb_t __gmp_oddfac_table[] = { ONE_LIMB_ODD_FACTORIAL_TABLE, ONE_LIMB_ODD_FACTORIAL_EXTTABLE };
+
+/* Entry i contains ((2i+1)!!/2^t) where t is chosen such that the parenthesis
+ is an odd integer. */
+const mp_limb_t __gmp_odd2fac_table[] = { ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE };
+
+/* Entry i contains 2i-popc(2i). */
+const unsigned char __gmp_fac2cnt_table[] = { TABLE_2N_MINUS_POPC_2N };
+
+const mp_limb_t __gmp_limbroots_table[] = { NTH_ROOT_NUMB_MASK_TABLE };
diff --git a/gmp/mpn/generic/copyd.c b/gmp/mpn/generic/copyd.c
new file mode 100644
index 0000000000..ba3380a82b
--- /dev/null
+++ b/gmp/mpn/generic/copyd.c
@@ -0,0 +1,41 @@
+/* mpn_copyd
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_copyd (mp_ptr rp, mp_srcptr up, mp_size_t n)
+{
+ mp_size_t i;
+
+ for (i = n - 1; i >= 0; i--)
+ rp[i] = up[i];
+}
diff --git a/gmp/mpn/generic/copyi.c b/gmp/mpn/generic/copyi.c
new file mode 100644
index 0000000000..0c39b4534b
--- /dev/null
+++ b/gmp/mpn/generic/copyi.c
@@ -0,0 +1,43 @@
+/* mpn_copyi
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_copyi (mp_ptr rp, mp_srcptr up, mp_size_t n)
+{
+ mp_size_t i;
+
+ up += n;
+ rp += n;
+ for (i = -n; i != 0; i++)
+ rp[i] = up[i];
+}
diff --git a/gmp/mpn/generic/dcpi1_bdiv_q.c b/gmp/mpn/generic/dcpi1_bdiv_q.c
new file mode 100644
index 0000000000..a7b86c96d4
--- /dev/null
+++ b/gmp/mpn/generic/dcpi1_bdiv_q.c
@@ -0,0 +1,160 @@
+/* mpn_dcpi1_bdiv_q -- divide-and-conquer Hensel division with precomputed
+ inverse, returning quotient.
+
+ Contributed to the GNU project by Niels Möller and Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2006, 2007, 2009-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+mp_size_t
+mpn_dcpi1_bdiv_q_n_itch (mp_size_t n)
+{
+ /* NOTE: Depends on mullo_n interface */
+ return n;
+}
+
+/* Computes Q = N / D mod B^n, destroys N.
+
+ N = {np,n}
+ D = {dp,n}
+*/
+
+void
+mpn_dcpi1_bdiv_q_n (mp_ptr qp,
+ mp_ptr np, mp_srcptr dp, mp_size_t n,
+ mp_limb_t dinv, mp_ptr tp)
+{
+ while (ABOVE_THRESHOLD (n, DC_BDIV_Q_THRESHOLD))
+ {
+ mp_size_t lo, hi;
+ mp_limb_t cy;
+
+ lo = n >> 1; /* floor(n/2) */
+ hi = n - lo; /* ceil(n/2) */
+
+ cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, lo, dinv, tp);
+
+ mpn_mullo_n (tp, qp, dp + hi, lo);
+ mpn_sub_n (np + hi, np + hi, tp, lo);
+
+ if (lo < hi)
+ {
+ cy += mpn_submul_1 (np + lo, qp, lo, dp[lo]);
+ np[n - 1] -= cy;
+ }
+ qp += lo;
+ np += lo;
+ n -= lo;
+ }
+ mpn_sbpi1_bdiv_q (qp, np, n, dp, n, dinv);
+}
+
+/* Computes Q = N / D mod B^nn, destroys N.
+
+ N = {np,nn}
+ D = {dp,dn}
+*/
+
+void
+mpn_dcpi1_bdiv_q (mp_ptr qp,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_limb_t dinv)
+{
+ mp_size_t qn;
+ mp_limb_t cy;
+ mp_ptr tp;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ ASSERT (dn >= 2);
+ ASSERT (nn - dn >= 0);
+ ASSERT (dp[0] & 1);
+
+ tp = TMP_SALLOC_LIMBS (dn);
+
+ qn = nn;
+
+ if (qn > dn)
+ {
+ /* Reduce qn mod dn in a super-efficient manner. */
+ do
+ qn -= dn;
+ while (qn > dn);
+
+ /* Perform the typically smaller block first. */
+ if (BELOW_THRESHOLD (qn, DC_BDIV_QR_THRESHOLD))
+ cy = mpn_sbpi1_bdiv_qr (qp, np, 2 * qn, dp, qn, dinv);
+ else
+ cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, qn, dinv, tp);
+
+ if (qn != dn)
+ {
+ if (qn > dn - qn)
+ mpn_mul (tp, qp, qn, dp + qn, dn - qn);
+ else
+ mpn_mul (tp, dp + qn, dn - qn, qp, qn);
+ mpn_incr_u (tp + qn, cy);
+
+ mpn_sub (np + qn, np + qn, nn - qn, tp, dn);
+ cy = 0;
+ }
+
+ np += qn;
+ qp += qn;
+
+ qn = nn - qn;
+ while (qn > dn)
+ {
+ mpn_sub_1 (np + dn, np + dn, qn - dn, cy);
+ cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, dn, dinv, tp);
+ qp += dn;
+ np += dn;
+ qn -= dn;
+ }
+ mpn_dcpi1_bdiv_q_n (qp, np, dp, dn, dinv, tp);
+ }
+ else
+ {
+ if (BELOW_THRESHOLD (qn, DC_BDIV_Q_THRESHOLD))
+ mpn_sbpi1_bdiv_q (qp, np, qn, dp, qn, dinv);
+ else
+ mpn_dcpi1_bdiv_q_n (qp, np, dp, qn, dinv, tp);
+ }
+
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/dcpi1_bdiv_qr.c b/gmp/mpn/generic/dcpi1_bdiv_qr.c
new file mode 100644
index 0000000000..8a251f8d9d
--- /dev/null
+++ b/gmp/mpn/generic/dcpi1_bdiv_qr.c
@@ -0,0 +1,177 @@
+/* mpn_dcpi1_bdiv_qr -- divide-and-conquer Hensel division with precomputed
+ inverse, returning quotient and remainder.
+
+ Contributed to the GNU project by Niels Möller and Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Computes Hensel binary division of {np, 2*n} by {dp, n}.
+
+ Output:
+
+ q = n * d^{-1} mod 2^{qn * GMP_NUMB_BITS},
+
+ r = (n - q * d) * 2^{-qn * GMP_NUMB_BITS}
+
+ Stores q at qp. Stores the n least significant limbs of r at the high half
+ of np, and returns the borrow from the subtraction n - q*d.
+
+ d must be odd. dinv is (-d)^-1 mod 2^GMP_NUMB_BITS. */
+
+mp_size_t
+mpn_dcpi1_bdiv_qr_n_itch (mp_size_t n)
+{
+ return n;
+}
+
+mp_limb_t
+mpn_dcpi1_bdiv_qr_n (mp_ptr qp, mp_ptr np, mp_srcptr dp, mp_size_t n,
+ mp_limb_t dinv, mp_ptr tp)
+{
+ mp_size_t lo, hi;
+ mp_limb_t cy;
+ mp_limb_t rh;
+
+ lo = n >> 1; /* floor(n/2) */
+ hi = n - lo; /* ceil(n/2) */
+
+ if (BELOW_THRESHOLD (lo, DC_BDIV_QR_THRESHOLD))
+ cy = mpn_sbpi1_bdiv_qr (qp, np, 2 * lo, dp, lo, dinv);
+ else
+ cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, lo, dinv, tp);
+
+ mpn_mul (tp, dp + lo, hi, qp, lo);
+
+ mpn_incr_u (tp + lo, cy);
+ rh = mpn_sub (np + lo, np + lo, n + hi, tp, n);
+
+ if (BELOW_THRESHOLD (hi, DC_BDIV_QR_THRESHOLD))
+ cy = mpn_sbpi1_bdiv_qr (qp + lo, np + lo, 2 * hi, dp, hi, dinv);
+ else
+ cy = mpn_dcpi1_bdiv_qr_n (qp + lo, np + lo, dp, hi, dinv, tp);
+
+ mpn_mul (tp, qp + lo, hi, dp + hi, lo);
+
+ mpn_incr_u (tp + hi, cy);
+ rh += mpn_sub_n (np + n, np + n, tp, n);
+
+ return rh;
+}
+
+mp_limb_t
+mpn_dcpi1_bdiv_qr (mp_ptr qp, mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn, mp_limb_t dinv)
+{
+ mp_size_t qn;
+ mp_limb_t rr, cy;
+ mp_ptr tp;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ ASSERT (dn >= 2); /* to adhere to mpn_sbpi1_div_qr's limits */
+ ASSERT (nn - dn >= 1); /* to adhere to mpn_sbpi1_div_qr's limits */
+ ASSERT (dp[0] & 1);
+
+ tp = TMP_SALLOC_LIMBS (dn);
+
+ qn = nn - dn;
+
+ if (qn > dn)
+ {
+ /* Reduce qn mod dn without division, optimizing small operations. */
+ do
+ qn -= dn;
+ while (qn > dn);
+
+ /* Perform the typically smaller block first. */
+ if (BELOW_THRESHOLD (qn, DC_BDIV_QR_THRESHOLD))
+ cy = mpn_sbpi1_bdiv_qr (qp, np, 2 * qn, dp, qn, dinv);
+ else
+ cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, qn, dinv, tp);
+
+ rr = 0;
+ if (qn != dn)
+ {
+ if (qn > dn - qn)
+ mpn_mul (tp, qp, qn, dp + qn, dn - qn);
+ else
+ mpn_mul (tp, dp + qn, dn - qn, qp, qn);
+ mpn_incr_u (tp + qn, cy);
+
+ rr = mpn_sub (np + qn, np + qn, nn - qn, tp, dn);
+ cy = 0;
+ }
+
+ np += qn;
+ qp += qn;
+
+ qn = nn - dn - qn;
+ do
+ {
+ rr += mpn_sub_1 (np + dn, np + dn, qn, cy);
+ cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, dn, dinv, tp);
+ qp += dn;
+ np += dn;
+ qn -= dn;
+ }
+ while (qn > 0);
+ TMP_FREE;
+ return rr + cy;
+ }
+
+ if (BELOW_THRESHOLD (qn, DC_BDIV_QR_THRESHOLD))
+ cy = mpn_sbpi1_bdiv_qr (qp, np, 2 * qn, dp, qn, dinv);
+ else
+ cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, qn, dinv, tp);
+
+ rr = 0;
+ if (qn != dn)
+ {
+ if (qn > dn - qn)
+ mpn_mul (tp, qp, qn, dp + qn, dn - qn);
+ else
+ mpn_mul (tp, dp + qn, dn - qn, qp, qn);
+ mpn_incr_u (tp + qn, cy);
+
+ rr = mpn_sub (np + qn, np + qn, nn - qn, tp, dn);
+ cy = 0;
+ }
+
+ TMP_FREE;
+ return rr + cy;
+}
diff --git a/gmp/mpn/generic/dcpi1_div_q.c b/gmp/mpn/generic/dcpi1_div_q.c
new file mode 100644
index 0000000000..32d74c31a9
--- /dev/null
+++ b/gmp/mpn/generic/dcpi1_div_q.c
@@ -0,0 +1,87 @@
+/* mpn_dc_div_q -- divide-and-conquer division, returning exact quotient
+ only.
+
+ Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+mp_limb_t
+mpn_dcpi1_div_q (mp_ptr qp, mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn, gmp_pi1_t *dinv)
+{
+ mp_ptr tp, wp;
+ mp_limb_t qh;
+ mp_size_t qn;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ ASSERT (dn >= 6);
+ ASSERT (nn - dn >= 3);
+ ASSERT (dp[dn-1] & GMP_NUMB_HIGHBIT);
+
+ tp = TMP_SALLOC_LIMBS (nn + 1);
+ MPN_COPY (tp + 1, np, nn);
+ tp[0] = 0;
+
+ qn = nn - dn;
+ wp = TMP_SALLOC_LIMBS (qn + 1);
+
+ qh = mpn_dcpi1_divappr_q (wp, tp, nn + 1, dp, dn, dinv);
+
+ if (wp[0] == 0)
+ {
+ mp_limb_t cy;
+
+ if (qn > dn)
+ mpn_mul (tp, wp + 1, qn, dp, dn);
+ else
+ mpn_mul (tp, dp, dn, wp + 1, qn);
+
+ cy = (qh != 0) ? mpn_add_n (tp + qn, tp + qn, dp, dn) : 0;
+
+ if (cy || mpn_cmp (tp, np, nn) > 0) /* At most is wrong by one, no cycle. */
+ qh -= mpn_sub_1 (qp, wp + 1, qn, 1);
+ else /* Same as below */
+ MPN_COPY (qp, wp + 1, qn);
+ }
+ else
+ MPN_COPY (qp, wp + 1, qn);
+
+ TMP_FREE;
+ return qh;
+}
diff --git a/gmp/mpn/generic/dcpi1_div_qr.c b/gmp/mpn/generic/dcpi1_div_qr.c
new file mode 100644
index 0000000000..4d80c7b769
--- /dev/null
+++ b/gmp/mpn/generic/dcpi1_div_qr.c
@@ -0,0 +1,249 @@
+/* mpn_dcpi1_div_qr_n -- recursive divide-and-conquer division for arbitrary
+ size operands.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+mp_limb_t
+mpn_dcpi1_div_qr_n (mp_ptr qp, mp_ptr np, mp_srcptr dp, mp_size_t n,
+ gmp_pi1_t *dinv, mp_ptr tp)
+{
+ mp_size_t lo, hi;
+ mp_limb_t cy, qh, ql;
+
+ lo = n >> 1; /* floor(n/2) */
+ hi = n - lo; /* ceil(n/2) */
+
+ if (BELOW_THRESHOLD (hi, DC_DIV_QR_THRESHOLD))
+ qh = mpn_sbpi1_div_qr (qp + lo, np + 2 * lo, 2 * hi, dp + lo, hi, dinv->inv32);
+ else
+ qh = mpn_dcpi1_div_qr_n (qp + lo, np + 2 * lo, dp + lo, hi, dinv, tp);
+
+ mpn_mul (tp, qp + lo, hi, dp, lo);
+
+ cy = mpn_sub_n (np + lo, np + lo, tp, n);
+ if (qh != 0)
+ cy += mpn_sub_n (np + n, np + n, dp, lo);
+
+ while (cy != 0)
+ {
+ qh -= mpn_sub_1 (qp + lo, qp + lo, hi, 1);
+ cy -= mpn_add_n (np + lo, np + lo, dp, n);
+ }
+
+ if (BELOW_THRESHOLD (lo, DC_DIV_QR_THRESHOLD))
+ ql = mpn_sbpi1_div_qr (qp, np + hi, 2 * lo, dp + hi, lo, dinv->inv32);
+ else
+ ql = mpn_dcpi1_div_qr_n (qp, np + hi, dp + hi, lo, dinv, tp);
+
+ mpn_mul (tp, dp, hi, qp, lo);
+
+ cy = mpn_sub_n (np, np, tp, n);
+ if (ql != 0)
+ cy += mpn_sub_n (np + lo, np + lo, dp, hi);
+
+ while (cy != 0)
+ {
+ mpn_sub_1 (qp, qp, lo, 1);
+ cy -= mpn_add_n (np, np, dp, n);
+ }
+
+ return qh;
+}
+
+mp_limb_t
+mpn_dcpi1_div_qr (mp_ptr qp,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ gmp_pi1_t *dinv)
+{
+ mp_size_t qn;
+ mp_limb_t qh, cy;
+ mp_ptr tp;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ ASSERT (dn >= 6); /* to adhere to mpn_sbpi1_div_qr's limits */
+ ASSERT (nn - dn >= 3); /* to adhere to mpn_sbpi1_div_qr's limits */
+ ASSERT (dp[dn-1] & GMP_NUMB_HIGHBIT);
+
+ tp = TMP_SALLOC_LIMBS (dn);
+
+ qn = nn - dn;
+ qp += qn;
+ np += nn;
+ dp += dn;
+
+ if (qn > dn)
+ {
+ /* Reduce qn mod dn without division, optimizing small operations. */
+ do
+ qn -= dn;
+ while (qn > dn);
+
+ qp -= qn; /* point at low limb of next quotient block */
+ np -= qn; /* point in the middle of partial remainder */
+
+ /* Perform the typically smaller block first. */
+ if (qn == 1)
+ {
+ mp_limb_t q, n2, n1, n0, d1, d0;
+
+ /* Handle qh up front, for simplicity. */
+ qh = mpn_cmp (np - dn + 1, dp - dn, dn) >= 0;
+ if (qh)
+ ASSERT_NOCARRY (mpn_sub_n (np - dn + 1, np - dn + 1, dp - dn, dn));
+
+ /* A single iteration of schoolbook: One 3/2 division,
+ followed by the bignum update and adjustment. */
+ n2 = np[0];
+ n1 = np[-1];
+ n0 = np[-2];
+ d1 = dp[-1];
+ d0 = dp[-2];
+
+ ASSERT (n2 < d1 || (n2 == d1 && n1 <= d0));
+
+ if (UNLIKELY (n2 == d1) && n1 == d0)
+ {
+ q = GMP_NUMB_MASK;
+ cy = mpn_submul_1 (np - dn, dp - dn, dn, q);
+ ASSERT (cy == n2);
+ }
+ else
+ {
+ udiv_qr_3by2 (q, n1, n0, n2, n1, n0, d1, d0, dinv->inv32);
+
+ if (dn > 2)
+ {
+ mp_limb_t cy, cy1;
+ cy = mpn_submul_1 (np - dn, dp - dn, dn - 2, q);
+
+ cy1 = n0 < cy;
+ n0 = (n0 - cy) & GMP_NUMB_MASK;
+ cy = n1 < cy1;
+ n1 = (n1 - cy1) & GMP_NUMB_MASK;
+ np[-2] = n0;
+
+ if (UNLIKELY (cy != 0))
+ {
+ n1 += d1 + mpn_add_n (np - dn, np - dn, dp - dn, dn - 1);
+ qh -= (q == 0);
+ q = (q - 1) & GMP_NUMB_MASK;
+ }
+ }
+ else
+ np[-2] = n0;
+
+ np[-1] = n1;
+ }
+ qp[0] = q;
+ }
+ else
+ {
+ /* Do a 2qn / qn division */
+ if (qn == 2)
+ qh = mpn_divrem_2 (qp, 0L, np - 2, 4, dp - 2); /* FIXME: obsolete function. Use 5/3 division? */
+ else if (BELOW_THRESHOLD (qn, DC_DIV_QR_THRESHOLD))
+ qh = mpn_sbpi1_div_qr (qp, np - qn, 2 * qn, dp - qn, qn, dinv->inv32);
+ else
+ qh = mpn_dcpi1_div_qr_n (qp, np - qn, dp - qn, qn, dinv, tp);
+
+ if (qn != dn)
+ {
+ if (qn > dn - qn)
+ mpn_mul (tp, qp, qn, dp - dn, dn - qn);
+ else
+ mpn_mul (tp, dp - dn, dn - qn, qp, qn);
+
+ cy = mpn_sub_n (np - dn, np - dn, tp, dn);
+ if (qh != 0)
+ cy += mpn_sub_n (np - dn + qn, np - dn + qn, dp - dn, dn - qn);
+
+ while (cy != 0)
+ {
+ qh -= mpn_sub_1 (qp, qp, qn, 1);
+ cy -= mpn_add_n (np - dn, np - dn, dp - dn, dn);
+ }
+ }
+ }
+
+ qn = nn - dn - qn;
+ do
+ {
+ qp -= dn;
+ np -= dn;
+ mpn_dcpi1_div_qr_n (qp, np - dn, dp - dn, dn, dinv, tp);
+ qn -= dn;
+ }
+ while (qn > 0);
+ }
+ else
+ {
+ qp -= qn; /* point at low limb of next quotient block */
+ np -= qn; /* point in the middle of partial remainder */
+
+ if (BELOW_THRESHOLD (qn, DC_DIV_QR_THRESHOLD))
+ qh = mpn_sbpi1_div_qr (qp, np - qn, 2 * qn, dp - qn, qn, dinv->inv32);
+ else
+ qh = mpn_dcpi1_div_qr_n (qp, np - qn, dp - qn, qn, dinv, tp);
+
+ if (qn != dn)
+ {
+ if (qn > dn - qn)
+ mpn_mul (tp, qp, qn, dp - dn, dn - qn);
+ else
+ mpn_mul (tp, dp - dn, dn - qn, qp, qn);
+
+ cy = mpn_sub_n (np - dn, np - dn, tp, dn);
+ if (qh != 0)
+ cy += mpn_sub_n (np - dn + qn, np - dn + qn, dp - dn, dn - qn);
+
+ while (cy != 0)
+ {
+ qh -= mpn_sub_1 (qp, qp, qn, 1);
+ cy -= mpn_add_n (np - dn, np - dn, dp - dn, dn);
+ }
+ }
+ }
+
+ TMP_FREE;
+ return qh;
+}
diff --git a/gmp/mpn/generic/dcpi1_divappr_q.c b/gmp/mpn/generic/dcpi1_divappr_q.c
new file mode 100644
index 0000000000..c7b03c7f49
--- /dev/null
+++ b/gmp/mpn/generic/dcpi1_divappr_q.c
@@ -0,0 +1,257 @@
+/* mpn_dcpi1_divappr_q -- divide-and-conquer division, returning approximate
+ quotient. The quotient returned is either correct, or one too large.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+mp_limb_t
+mpn_dcpi1_divappr_q_n (mp_ptr qp, mp_ptr np, mp_srcptr dp, mp_size_t n,
+ gmp_pi1_t *dinv, mp_ptr tp)
+{
+ mp_size_t lo, hi;
+ mp_limb_t cy, qh, ql;
+
+ lo = n >> 1; /* floor(n/2) */
+ hi = n - lo; /* ceil(n/2) */
+
+ if (BELOW_THRESHOLD (hi, DC_DIV_QR_THRESHOLD))
+ qh = mpn_sbpi1_div_qr (qp + lo, np + 2 * lo, 2 * hi, dp + lo, hi, dinv->inv32);
+ else
+ qh = mpn_dcpi1_div_qr_n (qp + lo, np + 2 * lo, dp + lo, hi, dinv, tp);
+
+ mpn_mul (tp, qp + lo, hi, dp, lo);
+
+ cy = mpn_sub_n (np + lo, np + lo, tp, n);
+ if (qh != 0)
+ cy += mpn_sub_n (np + n, np + n, dp, lo);
+
+ while (cy != 0)
+ {
+ qh -= mpn_sub_1 (qp + lo, qp + lo, hi, 1);
+ cy -= mpn_add_n (np + lo, np + lo, dp, n);
+ }
+
+ if (BELOW_THRESHOLD (lo, DC_DIVAPPR_Q_THRESHOLD))
+ ql = mpn_sbpi1_divappr_q (qp, np + hi, 2 * lo, dp + hi, lo, dinv->inv32);
+ else
+ ql = mpn_dcpi1_divappr_q_n (qp, np + hi, dp + hi, lo, dinv, tp);
+
+ if (UNLIKELY (ql != 0))
+ {
+ mp_size_t i;
+ for (i = 0; i < lo; i++)
+ qp[i] = GMP_NUMB_MASK;
+ }
+
+ return qh;
+}
+
+mp_limb_t
+mpn_dcpi1_divappr_q (mp_ptr qp, mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn, gmp_pi1_t *dinv)
+{
+ mp_size_t qn;
+ mp_limb_t qh, cy, qsave;
+ mp_ptr tp;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ ASSERT (dn >= 6);
+ ASSERT (nn > dn);
+ ASSERT (dp[dn-1] & GMP_NUMB_HIGHBIT);
+
+ qn = nn - dn;
+ qp += qn;
+ np += nn;
+ dp += dn;
+
+ if (qn >= dn)
+ {
+ qn++; /* pretend we'll need an extra limb */
+ /* Reduce qn mod dn without division, optimizing small operations. */
+ do
+ qn -= dn;
+ while (qn > dn);
+
+ qp -= qn; /* point at low limb of next quotient block */
+ np -= qn; /* point in the middle of partial remainder */
+
+ tp = TMP_SALLOC_LIMBS (dn);
+
+ /* Perform the typically smaller block first. */
+ if (qn == 1)
+ {
+ mp_limb_t q, n2, n1, n0, d1, d0;
+
+ /* Handle qh up front, for simplicity. */
+ qh = mpn_cmp (np - dn + 1, dp - dn, dn) >= 0;
+ if (qh)
+ ASSERT_NOCARRY (mpn_sub_n (np - dn + 1, np - dn + 1, dp - dn, dn));
+
+ /* A single iteration of schoolbook: One 3/2 division,
+ followed by the bignum update and adjustment. */
+ n2 = np[0];
+ n1 = np[-1];
+ n0 = np[-2];
+ d1 = dp[-1];
+ d0 = dp[-2];
+
+ ASSERT (n2 < d1 || (n2 == d1 && n1 <= d0));
+
+ if (UNLIKELY (n2 == d1) && n1 == d0)
+ {
+ q = GMP_NUMB_MASK;
+ cy = mpn_submul_1 (np - dn, dp - dn, dn, q);
+ ASSERT (cy == n2);
+ }
+ else
+ {
+ udiv_qr_3by2 (q, n1, n0, n2, n1, n0, d1, d0, dinv->inv32);
+
+ if (dn > 2)
+ {
+ mp_limb_t cy, cy1;
+ cy = mpn_submul_1 (np - dn, dp - dn, dn - 2, q);
+
+ cy1 = n0 < cy;
+ n0 = (n0 - cy) & GMP_NUMB_MASK;
+ cy = n1 < cy1;
+ n1 = (n1 - cy1) & GMP_NUMB_MASK;
+ np[-2] = n0;
+
+ if (UNLIKELY (cy != 0))
+ {
+ n1 += d1 + mpn_add_n (np - dn, np - dn, dp - dn, dn - 1);
+ qh -= (q == 0);
+ q = (q - 1) & GMP_NUMB_MASK;
+ }
+ }
+ else
+ np[-2] = n0;
+
+ np[-1] = n1;
+ }
+ qp[0] = q;
+ }
+ else
+ {
+ if (qn == 2)
+ qh = mpn_divrem_2 (qp, 0L, np - 2, 4, dp - 2);
+ else if (BELOW_THRESHOLD (qn, DC_DIV_QR_THRESHOLD))
+ qh = mpn_sbpi1_div_qr (qp, np - qn, 2 * qn, dp - qn, qn, dinv->inv32);
+ else
+ qh = mpn_dcpi1_div_qr_n (qp, np - qn, dp - qn, qn, dinv, tp);
+
+ if (qn != dn)
+ {
+ if (qn > dn - qn)
+ mpn_mul (tp, qp, qn, dp - dn, dn - qn);
+ else
+ mpn_mul (tp, dp - dn, dn - qn, qp, qn);
+
+ cy = mpn_sub_n (np - dn, np - dn, tp, dn);
+ if (qh != 0)
+ cy += mpn_sub_n (np - dn + qn, np - dn + qn, dp - dn, dn - qn);
+
+ while (cy != 0)
+ {
+ qh -= mpn_sub_1 (qp, qp, qn, 1);
+ cy -= mpn_add_n (np - dn, np - dn, dp - dn, dn);
+ }
+ }
+ }
+ qn = nn - dn - qn + 1;
+ while (qn > dn)
+ {
+ qp -= dn;
+ np -= dn;
+ mpn_dcpi1_div_qr_n (qp, np - dn, dp - dn, dn, dinv, tp);
+ qn -= dn;
+ }
+
+ /* Since we pretended we'd need an extra quotient limb before, we now
+ have made sure the code above left just dn-1=qn quotient limbs to
+ develop. Develop that plus a guard limb. */
+ qn--;
+ qp -= qn;
+ np -= dn;
+ qsave = qp[qn];
+ mpn_dcpi1_divappr_q_n (qp, np - dn, dp - dn, dn, dinv, tp);
+ MPN_COPY_INCR (qp, qp + 1, qn);
+ qp[qn] = qsave;
+ }
+ else /* (qn < dn) */
+ {
+ mp_ptr q2p;
+#if 0 /* not possible since we demand nn > dn */
+ if (qn == 0)
+ {
+ qh = mpn_cmp (np - dn, dp - dn, dn) >= 0;
+ if (qh)
+ mpn_sub_n (np - dn, np - dn, dp - dn, dn);
+ TMP_FREE;
+ return qh;
+ }
+#endif
+
+ qp -= qn; /* point at low limb of next quotient block */
+ np -= qn; /* point in the middle of partial remainder */
+
+ q2p = TMP_SALLOC_LIMBS (qn + 1);
+ /* Should we at all check DC_DIVAPPR_Q_THRESHOLD here, or reply on
+ callers not to be silly? */
+ if (BELOW_THRESHOLD (qn, DC_DIVAPPR_Q_THRESHOLD))
+ {
+ qh = mpn_sbpi1_divappr_q (q2p, np - qn - 2, 2 * (qn + 1),
+ dp - (qn + 1), qn + 1, dinv->inv32);
+ }
+ else
+ {
+ /* It is tempting to use qp for recursive scratch and put quotient in
+ tp, but the recursive scratch needs one limb too many. */
+ tp = TMP_SALLOC_LIMBS (qn + 1);
+ qh = mpn_dcpi1_divappr_q_n (q2p, np - qn - 2, dp - (qn + 1), qn + 1, dinv, tp);
+ }
+ MPN_COPY (qp, q2p + 1, qn);
+ }
+
+ TMP_FREE;
+ return qh;
+}
diff --git a/gmp/mpn/generic/div_q.c b/gmp/mpn/generic/div_q.c
new file mode 100644
index 0000000000..aabcef0825
--- /dev/null
+++ b/gmp/mpn/generic/div_q.c
@@ -0,0 +1,323 @@
+/* mpn_div_q -- division for arbitrary size operands.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2009, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Compute Q = N/D with truncation.
+ N = {np,nn}
+ D = {dp,dn}
+ Q = {qp,nn-dn+1}
+ T = {scratch,nn+1} is scratch space
+ N and D are both untouched by the computation.
+ N and T may overlap; pass the same space if N is irrelevant after the call,
+ but note that tp needs an extra limb.
+
+ Operand requirements:
+ N >= D > 0
+ dp[dn-1] != 0
+ No overlap between the N, D, and Q areas.
+
+ This division function does not clobber its input operands, since it is
+ intended to support average-O(qn) division, and for that to be effective, it
+ cannot put requirements on callers to copy a O(nn) operand.
+
+ If a caller does not care about the value of {np,nn+1} after calling this
+ function, it should pass np also for the scratch argument. This function
+ will then save some time and space by avoiding allocation and copying.
+ (FIXME: Is this a good design? We only really save any copying for
+ already-normalised divisors, which should be rare. It also prevents us from
+ reasonably asking for all scratch space we need.)
+
+ We write nn-dn+1 limbs for the quotient, but return void. Why not return
+ the most significant quotient limb? Look at the 4 main code blocks below
+ (consisting of an outer if-else where each arm contains an if-else). It is
+ tricky for the first code block, since the mpn_*_div_q calls will typically
+ generate all nn-dn+1 and return 0 or 1. I don't see how to fix that unless
+ we generate the most significant quotient limb here, before calling
+ mpn_*_div_q, or put the quotient in a temporary area. Since this is a
+ critical division case (the SB sub-case in particular) copying is not a good
+ idea.
+
+ It might make sense to split the if-else parts of the (qn + FUDGE
+ >= dn) blocks into separate functions, since we could promise quite
+ different things to callers in these two cases. The 'then' case
+ benefits from np=scratch, and it could perhaps even tolerate qp=np,
+ saving some headache for many callers.
+
+ FIXME: Scratch allocation leaves a lot to be desired. E.g., for the MU size
+ operands, we do not reuse the huge scratch for adjustments. This can be a
+ serious waste of memory for the largest operands.
+*/
+
+/* FUDGE determines when to try getting an approximate quotient from the upper
+ parts of the dividend and divisor, then adjust. N.B. FUDGE must be >= 2
+ for the code to be correct. */
+#define FUDGE 5 /* FIXME: tune this */
+
+#define DC_DIV_Q_THRESHOLD DC_DIVAPPR_Q_THRESHOLD
+#define MU_DIV_Q_THRESHOLD MU_DIVAPPR_Q_THRESHOLD
+#define MUPI_DIV_Q_THRESHOLD MUPI_DIVAPPR_Q_THRESHOLD
+#ifndef MUPI_DIVAPPR_Q_THRESHOLD
+#define MUPI_DIVAPPR_Q_THRESHOLD MUPI_DIV_QR_THRESHOLD
+#endif
+
+void
+mpn_div_q (mp_ptr qp,
+ mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn, mp_ptr scratch)
+{
+ mp_ptr new_dp, new_np, tp, rp;
+ mp_limb_t cy, dh, qh;
+ mp_size_t new_nn, qn;
+ gmp_pi1_t dinv;
+ int cnt;
+ TMP_DECL;
+ TMP_MARK;
+
+ ASSERT (nn >= dn);
+ ASSERT (dn > 0);
+ ASSERT (dp[dn - 1] != 0);
+ ASSERT (! MPN_OVERLAP_P (qp, nn - dn + 1, np, nn));
+ ASSERT (! MPN_OVERLAP_P (qp, nn - dn + 1, dp, dn));
+ ASSERT (MPN_SAME_OR_SEPARATE_P (np, scratch, nn));
+
+ ASSERT_ALWAYS (FUDGE >= 2);
+
+ if (dn == 1)
+ {
+ mpn_divrem_1 (qp, 0L, np, nn, dp[dn - 1]);
+ return;
+ }
+
+ qn = nn - dn + 1; /* Quotient size, high limb might be zero */
+
+ if (qn + FUDGE >= dn)
+ {
+ /* |________________________|
+ |_______| */
+ new_np = scratch;
+
+ dh = dp[dn - 1];
+ if (LIKELY ((dh & GMP_NUMB_HIGHBIT) == 0))
+ {
+ count_leading_zeros (cnt, dh);
+
+ cy = mpn_lshift (new_np, np, nn, cnt);
+ new_np[nn] = cy;
+ new_nn = nn + (cy != 0);
+
+ new_dp = TMP_ALLOC_LIMBS (dn);
+ mpn_lshift (new_dp, dp, dn, cnt);
+
+ if (dn == 2)
+ {
+ qh = mpn_divrem_2 (qp, 0L, new_np, new_nn, new_dp);
+ }
+ else if (BELOW_THRESHOLD (dn, DC_DIV_Q_THRESHOLD) ||
+ BELOW_THRESHOLD (new_nn - dn, DC_DIV_Q_THRESHOLD))
+ {
+ invert_pi1 (dinv, new_dp[dn - 1], new_dp[dn - 2]);
+ qh = mpn_sbpi1_div_q (qp, new_np, new_nn, new_dp, dn, dinv.inv32);
+ }
+ else if (BELOW_THRESHOLD (dn, MUPI_DIV_Q_THRESHOLD) || /* fast condition */
+ BELOW_THRESHOLD (nn, 2 * MU_DIV_Q_THRESHOLD) || /* fast condition */
+ (double) (2 * (MU_DIV_Q_THRESHOLD - MUPI_DIV_Q_THRESHOLD)) * dn /* slow... */
+ + (double) MUPI_DIV_Q_THRESHOLD * nn > (double) dn * nn) /* ...condition */
+ {
+ invert_pi1 (dinv, new_dp[dn - 1], new_dp[dn - 2]);
+ qh = mpn_dcpi1_div_q (qp, new_np, new_nn, new_dp, dn, &dinv);
+ }
+ else
+ {
+ mp_size_t itch = mpn_mu_div_q_itch (new_nn, dn, 0);
+ mp_ptr scratch = TMP_ALLOC_LIMBS (itch);
+ qh = mpn_mu_div_q (qp, new_np, new_nn, new_dp, dn, scratch);
+ }
+ if (cy == 0)
+ qp[qn - 1] = qh;
+ else if (UNLIKELY (qh != 0))
+ {
+ /* This happens only when the quotient is close to B^n and
+ mpn_*_divappr_q returned B^n. */
+ mp_size_t i, n;
+ n = new_nn - dn;
+ for (i = 0; i < n; i++)
+ qp[i] = GMP_NUMB_MAX;
+ qh = 0; /* currently ignored */
+ }
+ }
+ else /* divisor is already normalised */
+ {
+ if (new_np != np)
+ MPN_COPY (new_np, np, nn);
+
+ if (dn == 2)
+ {
+ qh = mpn_divrem_2 (qp, 0L, new_np, nn, dp);
+ }
+ else if (BELOW_THRESHOLD (dn, DC_DIV_Q_THRESHOLD) ||
+ BELOW_THRESHOLD (nn - dn, DC_DIV_Q_THRESHOLD))
+ {
+ invert_pi1 (dinv, dh, dp[dn - 2]);
+ qh = mpn_sbpi1_div_q (qp, new_np, nn, dp, dn, dinv.inv32);
+ }
+ else if (BELOW_THRESHOLD (dn, MUPI_DIV_Q_THRESHOLD) || /* fast condition */
+ BELOW_THRESHOLD (nn, 2 * MU_DIV_Q_THRESHOLD) || /* fast condition */
+ (double) (2 * (MU_DIV_Q_THRESHOLD - MUPI_DIV_Q_THRESHOLD)) * dn /* slow... */
+ + (double) MUPI_DIV_Q_THRESHOLD * nn > (double) dn * nn) /* ...condition */
+ {
+ invert_pi1 (dinv, dh, dp[dn - 2]);
+ qh = mpn_dcpi1_div_q (qp, new_np, nn, dp, dn, &dinv);
+ }
+ else
+ {
+ mp_size_t itch = mpn_mu_div_q_itch (nn, dn, 0);
+ mp_ptr scratch = TMP_ALLOC_LIMBS (itch);
+ qh = mpn_mu_div_q (qp, np, nn, dp, dn, scratch);
+ }
+ qp[nn - dn] = qh;
+ }
+ }
+ else
+ {
+ /* |________________________|
+ |_________________| */
+ tp = TMP_ALLOC_LIMBS (qn + 1);
+
+ new_np = scratch;
+ new_nn = 2 * qn + 1;
+ if (new_np == np)
+ /* We need {np,nn} to remain untouched until the final adjustment, so
+ we need to allocate separate space for new_np. */
+ new_np = TMP_ALLOC_LIMBS (new_nn + 1);
+
+
+ dh = dp[dn - 1];
+ if (LIKELY ((dh & GMP_NUMB_HIGHBIT) == 0))
+ {
+ count_leading_zeros (cnt, dh);
+
+ cy = mpn_lshift (new_np, np + nn - new_nn, new_nn, cnt);
+ new_np[new_nn] = cy;
+
+ new_nn += (cy != 0);
+
+ new_dp = TMP_ALLOC_LIMBS (qn + 1);
+ mpn_lshift (new_dp, dp + dn - (qn + 1), qn + 1, cnt);
+ new_dp[0] |= dp[dn - (qn + 1) - 1] >> (GMP_NUMB_BITS - cnt);
+
+ if (qn + 1 == 2)
+ {
+ qh = mpn_divrem_2 (tp, 0L, new_np, new_nn, new_dp);
+ }
+ else if (BELOW_THRESHOLD (qn, DC_DIVAPPR_Q_THRESHOLD - 1))
+ {
+ invert_pi1 (dinv, new_dp[qn], new_dp[qn - 1]);
+ qh = mpn_sbpi1_divappr_q (tp, new_np, new_nn, new_dp, qn + 1, dinv.inv32);
+ }
+ else if (BELOW_THRESHOLD (qn, MU_DIVAPPR_Q_THRESHOLD - 1))
+ {
+ invert_pi1 (dinv, new_dp[qn], new_dp[qn - 1]);
+ qh = mpn_dcpi1_divappr_q (tp, new_np, new_nn, new_dp, qn + 1, &dinv);
+ }
+ else
+ {
+ mp_size_t itch = mpn_mu_divappr_q_itch (new_nn, qn + 1, 0);
+ mp_ptr scratch = TMP_ALLOC_LIMBS (itch);
+ qh = mpn_mu_divappr_q (tp, new_np, new_nn, new_dp, qn + 1, scratch);
+ }
+ if (cy == 0)
+ tp[qn] = qh;
+ else if (UNLIKELY (qh != 0))
+ {
+ /* This happens only when the quotient is close to B^n and
+ mpn_*_divappr_q returned B^n. */
+ mp_size_t i, n;
+ n = new_nn - (qn + 1);
+ for (i = 0; i < n; i++)
+ tp[i] = GMP_NUMB_MAX;
+ qh = 0; /* currently ignored */
+ }
+ }
+ else /* divisor is already normalised */
+ {
+ MPN_COPY (new_np, np + nn - new_nn, new_nn); /* pointless of MU will be used */
+
+ new_dp = (mp_ptr) dp + dn - (qn + 1);
+
+ if (qn == 2 - 1)
+ {
+ qh = mpn_divrem_2 (tp, 0L, new_np, new_nn, new_dp);
+ }
+ else if (BELOW_THRESHOLD (qn, DC_DIVAPPR_Q_THRESHOLD - 1))
+ {
+ invert_pi1 (dinv, dh, new_dp[qn - 1]);
+ qh = mpn_sbpi1_divappr_q (tp, new_np, new_nn, new_dp, qn + 1, dinv.inv32);
+ }
+ else if (BELOW_THRESHOLD (qn, MU_DIVAPPR_Q_THRESHOLD - 1))
+ {
+ invert_pi1 (dinv, dh, new_dp[qn - 1]);
+ qh = mpn_dcpi1_divappr_q (tp, new_np, new_nn, new_dp, qn + 1, &dinv);
+ }
+ else
+ {
+ mp_size_t itch = mpn_mu_divappr_q_itch (new_nn, qn + 1, 0);
+ mp_ptr scratch = TMP_ALLOC_LIMBS (itch);
+ qh = mpn_mu_divappr_q (tp, new_np, new_nn, new_dp, qn + 1, scratch);
+ }
+ tp[qn] = qh;
+ }
+
+ MPN_COPY (qp, tp + 1, qn);
+ if (tp[0] <= 4)
+ {
+ mp_size_t rn;
+
+ rp = TMP_ALLOC_LIMBS (dn + qn);
+ mpn_mul (rp, dp, dn, tp + 1, qn);
+ rn = dn + qn;
+ rn -= rp[rn - 1] == 0;
+
+ if (rn > nn || mpn_cmp (np, rp, nn) < 0)
+ mpn_decr_u (qp, 1);
+ }
+ }
+
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/div_qr_1.c b/gmp/mpn/generic/div_qr_1.c
new file mode 100644
index 0000000000..09401ac535
--- /dev/null
+++ b/gmp/mpn/generic/div_qr_1.c
@@ -0,0 +1,126 @@
+/* mpn_div_qr_1 -- mpn by limb division.
+
+ Contributed to the GNU project by Niels Möller and Torbjörn Granlund
+
+Copyright 1991, 1993, 1994, 1996, 1998-2000, 2002, 2003, 2013 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef DIV_QR_1_NORM_THRESHOLD
+#define DIV_QR_1_NORM_THRESHOLD 3
+#endif
+#ifndef DIV_QR_1_UNNORM_THRESHOLD
+#define DIV_QR_1_UNNORM_THRESHOLD 3
+#endif
+
+#if GMP_NAIL_BITS > 0
+#error Nail bits not supported
+#endif
+
+/* Divides {up, n} by d. Writes the n-1 low quotient limbs at {qp,
+ * n-1}, and the high quote limb at *qh. Returns remainder. */
+mp_limb_t
+mpn_div_qr_1 (mp_ptr qp, mp_limb_t *qh, mp_srcptr up, mp_size_t n,
+ mp_limb_t d)
+{
+ unsigned cnt;
+ mp_limb_t uh;
+
+ ASSERT (n > 0);
+ ASSERT (d > 0);
+
+ if (d & GMP_NUMB_HIGHBIT)
+ {
+ /* Normalized case */
+ mp_limb_t dinv, q;
+
+ uh = up[--n];
+
+ q = (uh >= d);
+ *qh = q;
+ uh -= (-q) & d;
+
+ if (BELOW_THRESHOLD (n, DIV_QR_1_NORM_THRESHOLD))
+ {
+ cnt = 0;
+ plain:
+ while (n > 0)
+ {
+ mp_limb_t ul = up[--n];
+ udiv_qrnnd (qp[n], uh, uh, ul, d);
+ }
+ return uh >> cnt;
+ }
+ invert_limb (dinv, d);
+ return mpn_div_qr_1n_pi1 (qp, up, n, uh, d, dinv);
+ }
+ else
+ {
+ /* Unnormalized case */
+ mp_limb_t dinv, ul;
+
+ if (! UDIV_NEEDS_NORMALIZATION
+ && BELOW_THRESHOLD (n, DIV_QR_1_UNNORM_THRESHOLD))
+ {
+ uh = up[--n];
+ udiv_qrnnd (*qh, uh, CNST_LIMB(0), uh, d);
+ cnt = 0;
+ goto plain;
+ }
+
+ count_leading_zeros (cnt, d);
+ d <<= cnt;
+
+#if HAVE_NATIVE_div_qr_1u_pi1
+ /* FIXME: Call loop doing on-the-fly normalization */
+#endif
+
+ /* Shift up front, use qp area for shifted copy. A bit messy,
+ since we have only n-1 limbs available, and shift the high
+ limb manually. */
+ uh = up[--n];
+ ul = (uh << cnt) | mpn_lshift (qp, up, n, cnt);
+ uh >>= (GMP_LIMB_BITS - cnt);
+
+ if (UDIV_NEEDS_NORMALIZATION
+ && BELOW_THRESHOLD (n, DIV_QR_1_UNNORM_THRESHOLD))
+ {
+ udiv_qrnnd (*qh, uh, uh, ul, d);
+ up = qp;
+ goto plain;
+ }
+ invert_limb (dinv, d);
+
+ udiv_qrnnd_preinv (*qh, uh, uh, ul, d, dinv);
+ return mpn_div_qr_1n_pi1 (qp, qp, n, uh, d, dinv) >> cnt;
+ }
+}
diff --git a/gmp/mpn/generic/div_qr_1n_pi1.c b/gmp/mpn/generic/div_qr_1n_pi1.c
new file mode 100644
index 0000000000..229ee091a4
--- /dev/null
+++ b/gmp/mpn/generic/div_qr_1n_pi1.c
@@ -0,0 +1,277 @@
+/* mpn_div_qr_1n_pi1
+
+ Contributed to the GNU project by Niels Möller
+
+ THIS FILE CONTAINS INTERNAL FUNCTIONS WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#if GMP_NAIL_BITS > 0
+#error Nail bits not supported
+#endif
+
+#ifndef DIV_QR_1N_METHOD
+#define DIV_QR_1N_METHOD 2
+#endif
+
+/* FIXME: Duplicated in mod_1_1.c. Move to gmp-impl.h */
+
+#if defined (__GNUC__)
+
+#if HAVE_HOST_CPU_FAMILY_x86 && W_TYPE_SIZE == 32
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ __asm__ ( "add %6, %k2\n\t" \
+ "adc %4, %k1\n\t" \
+ "sbb %k0, %k0" \
+ : "=r" (m), "=r" (s1), "=&r" (s0) \
+ : "1" ((USItype)(a1)), "g" ((USItype)(b1)), \
+ "%2" ((USItype)(a0)), "g" ((USItype)(b0)))
+#endif
+
+#if HAVE_HOST_CPU_FAMILY_x86_64 && W_TYPE_SIZE == 64
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ __asm__ ( "add %6, %q2\n\t" \
+ "adc %4, %q1\n\t" \
+ "sbb %q0, %q0" \
+ : "=r" (m), "=r" (s1), "=&r" (s0) \
+ : "1" ((UDItype)(a1)), "rme" ((UDItype)(b1)), \
+ "%2" ((UDItype)(a0)), "rme" ((UDItype)(b0)))
+#endif
+
+#if defined (__sparc__) && W_TYPE_SIZE == 32
+#define add_mssaaaa(m, sh, sl, ah, al, bh, bl) \
+ __asm__ ( "addcc %r5, %6, %2\n\t" \
+ "addxcc %r3, %4, %1\n\t" \
+ "subx %%g0, %%g0, %0" \
+ : "=r" (m), "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl) \
+ __CLOBBER_CC)
+#endif
+
+#if defined (__sparc__) && W_TYPE_SIZE == 64
+#define add_mssaaaa(m, sh, sl, ah, al, bh, bl) \
+ __asm__ ( "addcc %r5, %6, %2\n\t" \
+ "addccc %r7, %8, %%g0\n\t" \
+ "addccc %r3, %4, %1\n\t" \
+ "clr %0\n\t" \
+ "movcs %%xcc, -1, %0" \
+ : "=r" (m), "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl), \
+ "rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ __CLOBBER_CC)
+#if __VIS__ >= 0x300
+#undef add_mssaaaa
+#define add_mssaaaa(m, sh, sl, ah, al, bh, bl) \
+ __asm__ ( "addcc %r5, %6, %2\n\t" \
+ "addxccc %r3, %4, %1\n\t" \
+ "clr %0\n\t" \
+ "movcs %%xcc, -1, %0" \
+ : "=r" (m), "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl) \
+ __CLOBBER_CC)
+#endif
+#endif
+
+#if HAVE_HOST_CPU_FAMILY_powerpc && !defined (_LONG_LONG_LIMB)
+/* This works fine for 32-bit and 64-bit limbs, except for 64-bit limbs with a
+ processor running in 32-bit mode, since the carry flag then gets the 32-bit
+ carry. */
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ __asm__ ( "add%I6c %2, %5, %6\n\t" \
+ "adde %1, %3, %4\n\t" \
+ "subfe %0, %0, %0\n\t" \
+ "nor %0, %0, %0" \
+ : "=r" (m), "=r" (s1), "=&r" (s0) \
+ : "r" (a1), "r" (b1), "%r" (a0), "rI" (b0))
+#endif
+
+#if defined (__s390x__) && W_TYPE_SIZE == 64
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ __asm__ ( "algr %2, %6\n\t" \
+ "alcgr %1, %4\n\t" \
+ "lghi %0, 0\n\t" \
+ "alcgr %0, %0\n\t" \
+ "lcgr %0, %0" \
+ : "=r" (m), "=r" (s1), "=&r" (s0) \
+ : "1" ((UDItype)(a1)), "r" ((UDItype)(b1)), \
+ "%2" ((UDItype)(a0)), "r" ((UDItype)(b0)) __CLOBBER_CC)
+#endif
+
+#if defined (__arm__) && W_TYPE_SIZE == 32
+#define add_mssaaaa(m, sh, sl, ah, al, bh, bl) \
+ __asm__ ( "adds %2, %5, %6\n\t" \
+ "adcs %1, %3, %4\n\t" \
+ "movcc %0, #0\n\t" \
+ "movcs %0, #-1" \
+ : "=r" (m), "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC)
+#endif
+#endif /* defined (__GNUC__) */
+
+#ifndef add_mssaaaa
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ do { \
+ UWtype __s0, __s1, __c0, __c1; \
+ __s0 = (a0) + (b0); \
+ __s1 = (a1) + (b1); \
+ __c0 = __s0 < (a0); \
+ __c1 = __s1 < (a1); \
+ (s0) = __s0; \
+ __s1 = __s1 + __c0; \
+ (s1) = __s1; \
+ (m) = - (__c1 + (__s1 < __c0)); \
+ } while (0)
+#endif
+
+#if DIV_QR_1N_METHOD == 1
+
+/* Divides (uh B^n + {up, n}) by d, storing the quotient at {qp, n}.
+ Requires that uh < d. */
+mp_limb_t
+mpn_div_qr_1n_pi1 (mp_ptr qp, mp_srcptr up, mp_size_t n, mp_limb_t uh,
+ mp_limb_t d, mp_limb_t dinv)
+{
+ ASSERT (n > 0);
+ ASSERT (uh < d);
+ ASSERT (d & GMP_NUMB_HIGHBIT);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (qp, up, n));
+
+ do
+ {
+ mp_limb_t q, ul;
+
+ ul = up[--n];
+ udiv_qrnnd_preinv (q, uh, uh, ul, d, dinv);
+ qp[n] = q;
+ }
+ while (n > 0);
+
+ return uh;
+}
+
+#elif DIV_QR_1N_METHOD == 2
+
+mp_limb_t
+mpn_div_qr_1n_pi1 (mp_ptr qp, mp_srcptr up, mp_size_t n, mp_limb_t u1,
+ mp_limb_t d, mp_limb_t dinv)
+{
+ mp_limb_t B2;
+ mp_limb_t u0, u2;
+ mp_limb_t q0, q1;
+ mp_limb_t p0, p1;
+ mp_limb_t t;
+ mp_size_t j;
+
+ ASSERT (d & GMP_LIMB_HIGHBIT);
+ ASSERT (n > 0);
+ ASSERT (u1 < d);
+
+ if (n == 1)
+ {
+ udiv_qrnnd_preinv (qp[0], u1, u1, up[0], d, dinv);
+ return u1;
+ }
+
+ /* FIXME: Could be precomputed */
+ B2 = -d*dinv;
+
+ umul_ppmm (q1, q0, dinv, u1);
+ umul_ppmm (p1, p0, B2, u1);
+ q1 += u1;
+ ASSERT (q1 >= u1);
+ u0 = up[n-1]; /* Early read, to allow qp == up. */
+ qp[n-1] = q1;
+
+ add_mssaaaa (u2, u1, u0, u0, up[n-2], p1, p0);
+
+ /* FIXME: Keep q1 in a variable between iterations, to reduce number
+ of memory accesses. */
+ for (j = n-2; j-- > 0; )
+ {
+ mp_limb_t q2, cy;
+
+ /* Additions for the q update:
+ * +-------+
+ * |u1 * v |
+ * +---+---+
+ * | u1|
+ * +---+---+
+ * | 1 | v | (conditional on u2)
+ * +---+---+
+ * | 1 | (conditional on u0 + u2 B2 carry)
+ * +---+
+ * + | q0|
+ * -+---+---+---+
+ * | q2| q1| q0|
+ * +---+---+---+
+ */
+ umul_ppmm (p1, t, u1, dinv);
+ add_ssaaaa (q2, q1, -u2, u2 & dinv, CNST_LIMB(0), u1);
+ add_ssaaaa (q2, q1, q2, q1, CNST_LIMB(0), p1);
+ add_ssaaaa (q2, q1, q2, q1, CNST_LIMB(0), q0);
+ q0 = t;
+
+ umul_ppmm (p1, p0, u1, B2);
+ ADDC_LIMB (cy, u0, u0, u2 & B2);
+ u0 -= (-cy) & d;
+
+ /* Final q update */
+ add_ssaaaa (q2, q1, q2, q1, CNST_LIMB(0), cy);
+ qp[j+1] = q1;
+ MPN_INCR_U (qp+j+2, n-j-2, q2);
+
+ add_mssaaaa (u2, u1, u0, u0, up[j], p1, p0);
+ }
+
+ q1 = (u2 > 0);
+ u1 -= (-q1) & d;
+
+ t = (u1 >= d);
+ q1 += t;
+ u1 -= (-t) & d;
+
+ udiv_qrnnd_preinv (t, u0, u1, u0, d, dinv);
+ add_ssaaaa (q1, q0, q1, q0, CNST_LIMB(0), t);
+
+ MPN_INCR_U (qp+1, n-1, q1);
+
+ qp[0] = q0;
+ return u0;
+}
+
+#else
+#error Unknown DIV_QR_1N_METHOD
+#endif
diff --git a/gmp/mpn/generic/div_qr_1n_pi2.c b/gmp/mpn/generic/div_qr_1n_pi2.c
new file mode 100644
index 0000000000..7ea3410cb6
--- /dev/null
+++ b/gmp/mpn/generic/div_qr_1n_pi2.c
@@ -0,0 +1,195 @@
+/* mpn_div_qr_1u_pi2.
+
+ THIS FILE CONTAINS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS
+ ONLY SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* ISSUES:
+
+ * Can we really use the high pi2 inverse limb for udiv_qrnnd_preinv?
+
+ * Are there any problems with generating n quotient limbs in the q area? It
+ surely simplifies things.
+
+ * Not yet adequately tested.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Define some longlong.h-style macros, but for wider operations.
+ * add_sssaaaa is like longlong.h's add_ssaaaa but propagating
+ carry-out into an additional sum operand.
+*/
+#if defined (__GNUC__) && ! defined (__INTEL_COMPILER)
+
+#if HAVE_HOST_CPU_FAMILY_x86 && W_TYPE_SIZE == 32
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ __asm__ ("add\t%7, %k2\n\tadc\t%5, %k1\n\tadc\t$0, %k0" \
+ : "=r" (s2), "=&r" (s1), "=&r" (s0) \
+ : "0" ((USItype)(s2)), \
+ "1" ((USItype)(a1)), "g" ((USItype)(b1)), \
+ "%2" ((USItype)(a0)), "g" ((USItype)(b0)))
+#endif
+
+#if defined (__amd64__) && W_TYPE_SIZE == 64
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ __asm__ ("add\t%7, %q2\n\tadc\t%5, %q1\n\tadc\t$0, %q0" \
+ : "=r" (s2), "=&r" (s1), "=&r" (s0) \
+ : "0" ((UDItype)(s2)), \
+ "1" ((UDItype)(a1)), "rme" ((UDItype)(b1)), \
+ "%2" ((UDItype)(a0)), "rme" ((UDItype)(b0)))
+#endif
+
+#if HAVE_HOST_CPU_FAMILY_powerpc && !defined (_LONG_LONG_LIMB)
+/* This works fine for 32-bit and 64-bit limbs, except for 64-bit limbs with a
+ processor running in 32-bit mode, since the carry flag then gets the 32-bit
+ carry. */
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ __asm__ ("add%I7c\t%2,%6,%7\n\tadde\t%1,%4,%5\n\taddze\t%0,%0" \
+ : "=r" (s2), "=&r" (s1), "=&r" (s0) \
+ : "r" (s2), "r" (a1), "r" (b1), "%r" (a0), "rI" (b0))
+#endif
+
+#endif /* __GNUC__ */
+
+#ifndef add_sssaaaa
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ do { \
+ UWtype __s0, __s1, __c0, __c1; \
+ __s0 = (a0) + (b0); \
+ __s1 = (a1) + (b1); \
+ __c0 = __s0 < (a0); \
+ __c1 = __s1 < (a1); \
+ (s0) = __s0; \
+ __s1 = __s1 + __c0; \
+ (s1) = __s1; \
+ (s2) += __c1 + (__s1 < __c0); \
+ } while (0)
+#endif
+
+struct precomp_div_1_pi2
+{
+ mp_limb_t dip[2];
+ mp_limb_t d;
+ int norm_cnt;
+};
+
+mp_limb_t
+mpn_div_qr_1n_pi2 (mp_ptr qp,
+ mp_srcptr up, mp_size_t un,
+ struct precomp_div_1_pi2 *pd)
+{
+ mp_limb_t most_significant_q_limb;
+ mp_size_t i;
+ mp_limb_t r, u2, u1, u0;
+ mp_limb_t d0, di1, di0;
+ mp_limb_t q3a, q2a, q2b, q1b, q2c, q1c, q1d, q0d;
+ mp_limb_t cnd;
+
+ ASSERT (un >= 2);
+ ASSERT ((pd->d & GMP_NUMB_HIGHBIT) != 0);
+ ASSERT (! MPN_OVERLAP_P (qp, un-2, up, un) || qp+2 >= up);
+ ASSERT_MPN (up, un);
+
+#define q3 q3a
+#define q2 q2b
+#define q1 q1b
+
+ up += un - 3;
+ r = up[2];
+ d0 = pd->d;
+
+ most_significant_q_limb = (r >= d0);
+ r -= d0 & -most_significant_q_limb;
+
+ qp += un - 3;
+ qp[2] = most_significant_q_limb;
+
+ di1 = pd->dip[1];
+ di0 = pd->dip[0];
+
+ for (i = un - 3; i >= 0; i -= 2)
+ {
+ u2 = r;
+ u1 = up[1];
+ u0 = up[0];
+
+ /* Dividend in {r,u1,u0} */
+
+ umul_ppmm (q1d,q0d, u1, di0);
+ umul_ppmm (q2b,q1b, u1, di1);
+ q2b++; /* cannot spill */
+ add_sssaaaa (r,q2b,q1b, q2b,q1b, u1,u0);
+
+ umul_ppmm (q2c,q1c, u2, di0);
+ add_sssaaaa (r,q2b,q1b, q2b,q1b, q2c,q1c);
+ umul_ppmm (q3a,q2a, u2, di1);
+
+ add_sssaaaa (r,q2b,q1b, q2b,q1b, q2a,q1d);
+
+ q3 += r;
+
+ r = u0 - q2 * d0;
+
+ cnd = (r >= q1);
+ r += d0 & -cnd;
+ sub_ddmmss (q3,q2, q3,q2, 0,cnd);
+
+ if (UNLIKELY (r >= d0))
+ {
+ r -= d0;
+ add_ssaaaa (q3,q2, q3,q2, 0,1);
+ }
+
+ qp[0] = q2;
+ qp[1] = q3;
+
+ up -= 2;
+ qp -= 2;
+ }
+
+ if ((un & 1) == 0)
+ {
+ u2 = r;
+ u1 = up[1];
+
+ udiv_qrnnd_preinv (q3, r, u2, u1, d0, di1);
+ qp[1] = q3;
+ }
+
+ return r;
+
+#undef q3
+#undef q2
+#undef q1
+}
diff --git a/gmp/mpn/generic/div_qr_1u_pi2.c b/gmp/mpn/generic/div_qr_1u_pi2.c
new file mode 100644
index 0000000000..83d66ef29e
--- /dev/null
+++ b/gmp/mpn/generic/div_qr_1u_pi2.c
@@ -0,0 +1,228 @@
+/* mpn_div_qr_1u_pi2.
+
+ THIS FILE CONTAINS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS
+ ONLY SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* ISSUES:
+
+ * Can we really use the high pi2 inverse limb for udiv_qrnnd_preinv?
+
+ * Are there any problems with generating n quotient limbs in the q area? It
+ surely simplifies things.
+
+ * Not yet adequately tested.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Define some longlong.h-style macros, but for wider operations.
+ * add_sssaaaa is like longlong.h's add_ssaaaa but propagating
+ carry-out into an additional sum operand.
+*/
+#if defined (__GNUC__) && ! defined (__INTEL_COMPILER)
+
+#if HAVE_HOST_CPU_FAMILY_x86 && W_TYPE_SIZE == 32
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ __asm__ ("add\t%7, %k2\n\tadc\t%5, %k1\n\tadc\t$0, %k0" \
+ : "=r" (s2), "=&r" (s1), "=&r" (s0) \
+ : "0" ((USItype)(s2)), \
+ "1" ((USItype)(a1)), "g" ((USItype)(b1)), \
+ "%2" ((USItype)(a0)), "g" ((USItype)(b0)))
+#endif
+
+#if defined (__amd64__) && W_TYPE_SIZE == 64
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ __asm__ ("add\t%7, %q2\n\tadc\t%5, %q1\n\tadc\t$0, %q0" \
+ : "=r" (s2), "=&r" (s1), "=&r" (s0) \
+ : "0" ((UDItype)(s2)), \
+ "1" ((UDItype)(a1)), "rme" ((UDItype)(b1)), \
+ "%2" ((UDItype)(a0)), "rme" ((UDItype)(b0)))
+#endif
+
+#if HAVE_HOST_CPU_FAMILY_powerpc && !defined (_LONG_LONG_LIMB)
+/* This works fine for 32-bit and 64-bit limbs, except for 64-bit limbs with a
+ processor running in 32-bit mode, since the carry flag then gets the 32-bit
+ carry. */
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ __asm__ ("add%I7c\t%2,%6,%7\n\tadde\t%1,%4,%5\n\taddze\t%0,%0" \
+ : "=r" (s2), "=&r" (s1), "=&r" (s0) \
+ : "r" (s2), "r" (a1), "r" (b1), "%r" (a0), "rI" (b0))
+#endif
+
+#endif /* __GNUC__ */
+
+#ifndef add_sssaaaa
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ do { \
+ UWtype __s0, __s1, __c0, __c1; \
+ __s0 = (a0) + (b0); \
+ __s1 = (a1) + (b1); \
+ __c0 = __s0 < (a0); \
+ __c1 = __s1 < (a1); \
+ (s0) = __s0; \
+ __s1 = __s1 + __c0; \
+ (s1) = __s1; \
+ (s2) += __c1 + (__s1 < __c0); \
+ } while (0)
+#endif
+
+struct precomp_div_1_pi2
+{
+ mp_limb_t dip[2];
+ mp_limb_t d;
+ int norm_cnt;
+};
+
+mp_limb_t
+mpn_div_qr_1u_pi2 (mp_ptr qp,
+ mp_srcptr up, mp_size_t un,
+ struct precomp_div_1_pi2 *pd)
+{
+ mp_size_t i;
+ mp_limb_t r, u2, u1, u0;
+ mp_limb_t d0, di1, di0;
+ mp_limb_t q3a, q2a, q2b, q1b, q2c, q1c, q1d, q0d;
+ mp_limb_t cnd;
+ int cnt;
+
+ ASSERT (un >= 2);
+ ASSERT ((pd->d & GMP_NUMB_HIGHBIT) == 0);
+ ASSERT (! MPN_OVERLAP_P (qp, un-2, up, un) || qp+2 >= up);
+ ASSERT_MPN (up, un);
+
+#define q3 q3a
+#define q2 q2b
+#define q1 q1b
+
+ up += un - 3;
+ cnt = pd->norm_cnt;
+ r = up[2] >> (GMP_NUMB_BITS - cnt);
+ d0 = pd->d << cnt;
+
+ qp += un - 2;
+
+ di1 = pd->dip[1];
+ di0 = pd->dip[0];
+
+ for (i = un - 3; i >= 0; i -= 2)
+ {
+ u2 = r;
+ u1 = (up[2] << cnt) | (up[1] >> (GMP_NUMB_BITS - cnt));
+ u0 = (up[1] << cnt) | (up[0] >> (GMP_NUMB_BITS - cnt));
+
+ /* Dividend in {r,u1,u0} */
+
+ umul_ppmm (q1d,q0d, u1, di0);
+ umul_ppmm (q2b,q1b, u1, di1);
+ q2b++; /* cannot spill */
+ add_sssaaaa (r,q2b,q1b, q2b,q1b, u1,u0);
+
+ umul_ppmm (q2c,q1c, u2, di0);
+ add_sssaaaa (r,q2b,q1b, q2b,q1b, q2c,q1c);
+ umul_ppmm (q3a,q2a, u2, di1);
+
+ add_sssaaaa (r,q2b,q1b, q2b,q1b, q2a,q1d);
+
+ q3 += r;
+
+ r = u0 - q2 * d0;
+
+ cnd = (r >= q1);
+ r += d0 & -cnd;
+ sub_ddmmss (q3,q2, q3,q2, 0,cnd);
+
+ if (UNLIKELY (r >= d0))
+ {
+ r -= d0;
+ add_ssaaaa (q3,q2, q3,q2, 0,1);
+ }
+
+ qp[0] = q2;
+ qp[1] = q3;
+
+ up -= 2;
+ qp -= 2;
+ }
+
+ if ((un & 1) != 0)
+ {
+ u2 = r;
+ u1 = (up[2] << cnt);
+
+ udiv_qrnnd_preinv (q3, r, u2, u1, d0, di1);
+ qp[1] = q3;
+ }
+ else
+ {
+ u2 = r;
+ u1 = (up[2] << cnt) | (up[1] >> (GMP_NUMB_BITS - cnt));
+ u0 = (up[1] << cnt);
+
+ /* Dividend in {r,u1,u0} */
+
+ umul_ppmm (q1d,q0d, u1, di0);
+ umul_ppmm (q2b,q1b, u1, di1);
+ q2b++; /* cannot spill */
+ add_sssaaaa (r,q2b,q1b, q2b,q1b, u1,u0);
+
+ umul_ppmm (q2c,q1c, u2, di0);
+ add_sssaaaa (r,q2b,q1b, q2b,q1b, q2c,q1c);
+ umul_ppmm (q3a,q2a, u2, di1);
+
+ add_sssaaaa (r,q2b,q1b, q2b,q1b, q2a,q1d);
+
+ q3 += r;
+
+ r = u0 - q2 * d0;
+
+ cnd = (r >= q1);
+ r += d0 & -cnd;
+ sub_ddmmss (q3,q2, q3,q2, 0,cnd);
+
+ if (UNLIKELY (r >= d0))
+ {
+ r -= d0;
+ add_ssaaaa (q3,q2, q3,q2, 0,1);
+ }
+
+ qp[0] = q2;
+ qp[1] = q3;
+ }
+
+ return r >> cnt;
+
+#undef q3
+#undef q2
+#undef q1
+}
diff --git a/gmp/mpn/generic/div_qr_2.c b/gmp/mpn/generic/div_qr_2.c
new file mode 100644
index 0000000000..cb07e0e3b4
--- /dev/null
+++ b/gmp/mpn/generic/div_qr_2.c
@@ -0,0 +1,332 @@
+/* mpn_div_qr_2 -- Divide natural numbers, producing both remainder and
+ quotient. The divisor is two limbs.
+
+ Contributed to the GNU project by Torbjorn Granlund and Niels Möller
+
+ THIS FILE CONTAINS INTERNAL FUNCTIONS WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+
+Copyright 1993-1996, 1999-2002, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef DIV_QR_2_PI2_THRESHOLD
+/* Disabled unless explicitly tuned. */
+#define DIV_QR_2_PI2_THRESHOLD MP_LIMB_T_MAX
+#endif
+
+#ifndef SANITY_CHECK
+#define SANITY_CHECK 0
+#endif
+
+/* Define some longlong.h-style macros, but for wider operations.
+ * add_sssaaaa is like longlong.h's add_ssaaaa but the propagating
+ carry-out into an additional sum operand.
+ * add_csaac accepts two addends and a carry in, and generates a sum
+ and a carry out. A little like a "full adder".
+*/
+#if defined (__GNUC__) && ! defined (__INTEL_COMPILER)
+
+#if HAVE_HOST_CPU_FAMILY_x86 && W_TYPE_SIZE == 32
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ __asm__ ("add\t%7, %k2\n\tadc\t%5, %k1\n\tadc\t$0, %k0" \
+ : "=r" (s2), "=&r" (s1), "=&r" (s0) \
+ : "0" ((USItype)(s2)), \
+ "1" ((USItype)(a1)), "g" ((USItype)(b1)), \
+ "%2" ((USItype)(a0)), "g" ((USItype)(b0)))
+#define add_csaac(co, s, a, b, ci) \
+ __asm__ ("bt\t$0, %2\n\tadc\t%5, %k1\n\tadc\t%k0, %k0" \
+ : "=r" (co), "=r" (s) \
+ : "rm" ((USItype)(ci)), "0" (CNST_LIMB(0)), \
+ "%1" ((USItype)(a)), "g" ((USItype)(b)))
+#endif
+
+#if defined (__amd64__) && W_TYPE_SIZE == 64
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ __asm__ ("add\t%7, %q2\n\tadc\t%5, %q1\n\tadc\t$0, %q0" \
+ : "=r" (s2), "=&r" (s1), "=&r" (s0) \
+ : "0" ((UDItype)(s2)), \
+ "1" ((UDItype)(a1)), "rme" ((UDItype)(b1)), \
+ "%2" ((UDItype)(a0)), "rme" ((UDItype)(b0)))
+#define add_csaac(co, s, a, b, ci) \
+ __asm__ ("bt\t$0, %2\n\tadc\t%5, %q1\n\tadc\t%q0, %q0" \
+ : "=r" (co), "=r" (s) \
+ : "rm" ((UDItype)(ci)), "0" (CNST_LIMB(0)), \
+ "%1" ((UDItype)(a)), "g" ((UDItype)(b)))
+#endif
+
+#if HAVE_HOST_CPU_FAMILY_powerpc && !defined (_LONG_LONG_LIMB)
+/* This works fine for 32-bit and 64-bit limbs, except for 64-bit limbs with a
+ processor running in 32-bit mode, since the carry flag then gets the 32-bit
+ carry. */
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ __asm__ ("add%I7c\t%2,%6,%7\n\tadde\t%1,%4,%5\n\taddze\t%0,%0" \
+ : "=r" (s2), "=&r" (s1), "=&r" (s0) \
+ : "r" (s2), "r" (a1), "r" (b1), "%r" (a0), "rI" (b0))
+#endif
+
+#endif /* __GNUC__ */
+
+#ifndef add_sssaaaa
+#define add_sssaaaa(s2, s1, s0, a1, a0, b1, b0) \
+ do { \
+ UWtype __s0, __s1, __c0, __c1; \
+ __s0 = (a0) + (b0); \
+ __s1 = (a1) + (b1); \
+ __c0 = __s0 < (a0); \
+ __c1 = __s1 < (a1); \
+ (s0) = __s0; \
+ __s1 = __s1 + __c0; \
+ (s1) = __s1; \
+ (s2) += __c1 + (__s1 < __c0); \
+ } while (0)
+#endif
+
+#ifndef add_csaac
+#define add_csaac(co, s, a, b, ci) \
+ do { \
+ UWtype __s, __c; \
+ __s = (a) + (b); \
+ __c = __s < (a); \
+ __s = __s + (ci); \
+ (s) = __s; \
+ (co) = __c + (__s < (ci)); \
+ } while (0)
+#endif
+
+/* Typically used with r1, r0 same as n3, n2. Other types of overlap
+ between inputs and outputs are not supported. */
+#define udiv_qr_4by2(q1,q0, r1,r0, n3,n2,n1,n0, d1,d0, di1,di0) \
+ do { \
+ mp_limb_t _q3, _q2a, _q2, _q1, _q2c, _q1c, _q1d, _q0; \
+ mp_limb_t _t1, _t0; \
+ mp_limb_t _c, _mask; \
+ \
+ umul_ppmm (_q3,_q2a, n3, di1); \
+ umul_ppmm (_q2,_q1, n2, di1); \
+ umul_ppmm (_q2c,_q1c, n3, di0); \
+ add_sssaaaa (_q3,_q2,_q1, _q2,_q1, _q2c,_q1c); \
+ umul_ppmm (_q1d,_q0, n2, di0); \
+ add_sssaaaa (_q3,_q2,_q1, _q2,_q1, _q2a,_q1d); \
+ \
+ add_ssaaaa (r1, r0, n3, n2, CNST_LIMB(0), CNST_LIMB(1)); \
+ \
+ /* [q3,q2,q1,q0] += [n3,n3,n1,n0] */ \
+ add_csaac (_c, _q0, _q0, n0, CNST_LIMB(0)); \
+ add_csaac (_c, _q1, _q1, n1, _c); \
+ add_csaac (_c, _q2, _q2, r0, _c); \
+ _q3 = _q3 + r1 + _c; \
+ \
+ umul_ppmm (_t1,_t0, _q2, d0); \
+ _t1 += _q2 * d1 + _q3 * d0; \
+ \
+ sub_ddmmss (r1, r0, n1, n0, _t1, _t0); \
+ \
+ _mask = -(mp_limb_t) (r1 >= _q1 & (r1 > _q1 | r0 >= _q0)); /* (r1,r0) >= (q1,q0) */ \
+ add_ssaaaa (r1, r0, r1, r0, d1 & _mask, d0 & _mask); \
+ sub_ddmmss (_q3, _q2, _q3, _q2, CNST_LIMB(0), -_mask); \
+ \
+ if (UNLIKELY (r1 >= d1)) \
+ { \
+ if (r1 > d1 || r0 >= d0) \
+ { \
+ sub_ddmmss (r1, r0, r1, r0, d1, d0); \
+ add_ssaaaa (_q3, _q2, _q3, _q2, CNST_LIMB(0), CNST_LIMB(1));\
+ } \
+ } \
+ (q1) = _q3; \
+ (q0) = _q2; \
+ } while (0)
+
+static void
+invert_4by2 (mp_ptr di, mp_limb_t d1, mp_limb_t d0)
+{
+ mp_limb_t v1, v0, p1, t1, t0, p0, mask;
+ invert_limb (v1, d1);
+ p1 = d1 * v1;
+ /* <1, v1> * d1 = <B-1, p1> */
+ p1 += d0;
+ if (p1 < d0)
+ {
+ v1--;
+ mask = -(mp_limb_t) (p1 >= d1);
+ p1 -= d1;
+ v1 += mask;
+ p1 -= mask & d1;
+ }
+ /* <1, v1> * d1 + d0 = <B-1, p1> */
+ umul_ppmm (t1, p0, d0, v1);
+ p1 += t1;
+ if (p1 < t1)
+ {
+ if (UNLIKELY (p1 >= d1))
+ {
+ if (p1 > d1 || p0 >= d0)
+ {
+ sub_ddmmss (p1, p0, p1, p0, d1, d0);
+ v1--;
+ }
+ }
+ sub_ddmmss (p1, p0, p1, p0, d1, d0);
+ v1--;
+ }
+ /* Now v1 is the 3/2 inverse, <1, v1> * <d1, d0> = <B-1, p1, p0>,
+ * with <p1, p0> + <d1, d0> >= B^2.
+ *
+ * The 4/2 inverse is (B^4 - 1) / <d1, d0> = <1, v1, v0>. The
+ * partial remainder after <1, v1> is
+ *
+ * B^4 - 1 - B <1, v1> <d1, d0> = <B-1, B-1, B-1, B-1> - <B-1, p1, p0, 0>
+ * = <~p1, ~p0, B-1>
+ */
+ udiv_qr_3by2 (v0, t1, t0, ~p1, ~p0, MP_LIMB_T_MAX, d1, d0, v1);
+ di[0] = v0;
+ di[1] = v1;
+
+#if SANITY_CHECK
+ {
+ mp_limb_t tp[4];
+ mp_limb_t dp[2];
+ dp[0] = d0;
+ dp[1] = d1;
+ mpn_mul_n (tp, dp, di, 2);
+ ASSERT_ALWAYS (mpn_add_n (tp+2, tp+2, dp, 2) == 0);
+ ASSERT_ALWAYS (tp[2] == MP_LIMB_T_MAX);
+ ASSERT_ALWAYS (tp[3] == MP_LIMB_T_MAX);
+ ASSERT_ALWAYS (mpn_add_n (tp, tp, dp, 2) == 1);
+ }
+#endif
+}
+
+static mp_limb_t
+mpn_div_qr_2n_pi2 (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn,
+ mp_limb_t d1, mp_limb_t d0, mp_limb_t di1, mp_limb_t di0)
+{
+ mp_limb_t qh;
+ mp_size_t i;
+ mp_limb_t r1, r0;
+
+ ASSERT (nn >= 2);
+ ASSERT (d1 & GMP_NUMB_HIGHBIT);
+
+ r1 = np[nn-1];
+ r0 = np[nn-2];
+
+ qh = 0;
+ if (r1 >= d1 && (r1 > d1 || r0 >= d0))
+ {
+#if GMP_NAIL_BITS == 0
+ sub_ddmmss (r1, r0, r1, r0, d1, d0);
+#else
+ r0 = r0 - d0;
+ r1 = r1 - d1 - (r0 >> GMP_LIMB_BITS - 1);
+ r0 &= GMP_NUMB_MASK;
+#endif
+ qh = 1;
+ }
+
+ for (i = nn - 2; i >= 2; i -= 2)
+ {
+ mp_limb_t n1, n0, q1, q0;
+ n1 = np[i-1];
+ n0 = np[i-2];
+ udiv_qr_4by2 (q1, q0, r1, r0, r1, r0, n1, n0, d1, d0, di1, di0);
+ qp[i-1] = q1;
+ qp[i-2] = q0;
+ }
+
+ if (i > 0)
+ {
+ mp_limb_t q;
+ udiv_qr_3by2 (q, r1, r0, r1, r0, np[0], d1, d0, di1);
+ qp[0] = q;
+ }
+ rp[1] = r1;
+ rp[0] = r0;
+
+ return qh;
+}
+
+
+/* Divide num {np,nn} by den {dp,2} and write the nn-2 least
+ significant quotient limbs at qp and the 2 long remainder at np.
+ Return the most significant limb of the quotient.
+
+ Preconditions:
+ 1. qp must either not overlap with the input operands at all, or
+ qp >= np + 2 must hold true. (This means that it's possible to put
+ the quotient in the high part of {np,nn}, right above the remainder.
+ 2. nn >= 2. */
+
+mp_limb_t
+mpn_div_qr_2 (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp)
+{
+ mp_limb_t d1;
+ mp_limb_t d0;
+ gmp_pi1_t dinv;
+
+ ASSERT (nn >= 2);
+ ASSERT (! MPN_OVERLAP_P (qp, nn-2, np, nn) || qp >= np + 2);
+ ASSERT_MPN (np, nn);
+ ASSERT_MPN (dp, 2);
+
+ d1 = dp[1]; d0 = dp[0];
+
+ ASSERT (d1 > 0);
+
+ if (UNLIKELY (d1 & GMP_NUMB_HIGHBIT))
+ {
+ if (BELOW_THRESHOLD (nn, DIV_QR_2_PI2_THRESHOLD))
+ {
+ gmp_pi1_t dinv;
+ invert_pi1 (dinv, d1, d0);
+ return mpn_div_qr_2n_pi1 (qp, rp, np, nn, d1, d0, dinv.inv32);
+ }
+ else
+ {
+ mp_limb_t di[2];
+ invert_4by2 (di, d1, d0);
+ return mpn_div_qr_2n_pi2 (qp, rp, np, nn, d1, d0, di[1], di[0]);
+ }
+ }
+ else
+ {
+ int shift;
+ count_leading_zeros (shift, d1);
+ d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift));
+ d0 <<= shift;
+ invert_pi1 (dinv, d1, d0);
+ return mpn_div_qr_2u_pi1 (qp, rp, np, nn, d1, d0, shift, dinv.inv32);
+ }
+}
diff --git a/gmp/mpn/generic/div_qr_2n_pi1.c b/gmp/mpn/generic/div_qr_2n_pi1.c
new file mode 100644
index 0000000000..da500e2170
--- /dev/null
+++ b/gmp/mpn/generic/div_qr_2n_pi1.c
@@ -0,0 +1,85 @@
+/* mpn_div_qr_2n_pi1
+
+ Contributed to the GNU project by Torbjorn Granlund and Niels Möller
+
+ THIS FILE CONTAINS INTERNAL FUNCTIONS WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+
+Copyright 1993-1996, 1999-2002, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* 3/2 loop, for normalized divisor */
+mp_limb_t
+mpn_div_qr_2n_pi1 (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn,
+ mp_limb_t d1, mp_limb_t d0, mp_limb_t di)
+{
+ mp_limb_t qh;
+ mp_size_t i;
+ mp_limb_t r1, r0;
+
+ ASSERT (nn >= 2);
+ ASSERT (d1 & GMP_NUMB_HIGHBIT);
+
+ np += nn - 2;
+ r1 = np[1];
+ r0 = np[0];
+
+ qh = 0;
+ if (r1 >= d1 && (r1 > d1 || r0 >= d0))
+ {
+#if GMP_NAIL_BITS == 0
+ sub_ddmmss (r1, r0, r1, r0, d1, d0);
+#else
+ r0 = r0 - d0;
+ r1 = r1 - d1 - (r0 >> GMP_LIMB_BITS - 1);
+ r0 &= GMP_NUMB_MASK;
+#endif
+ qh = 1;
+ }
+
+ for (i = nn - 2 - 1; i >= 0; i--)
+ {
+ mp_limb_t n0, q;
+ n0 = np[-1];
+ udiv_qr_3by2 (q, r1, r0, r1, r0, n0, d1, d0, di);
+ np--;
+ qp[i] = q;
+ }
+
+ rp[1] = r1;
+ rp[0] = r0;
+
+ return qh;
+}
diff --git a/gmp/mpn/generic/div_qr_2u_pi1.c b/gmp/mpn/generic/div_qr_2u_pi1.c
new file mode 100644
index 0000000000..0b9ddf5753
--- /dev/null
+++ b/gmp/mpn/generic/div_qr_2u_pi1.c
@@ -0,0 +1,77 @@
+/* mpn_div_qr_2u_pi1
+
+ Contributed to the GNU project by Niels Möller
+
+ THIS FILE CONTAINS INTERNAL FUNCTIONS WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* 3/2 loop, for unnormalized divisor. Caller must pass shifted d1 and
+ d0, while {np,nn} is shifted on the fly. */
+mp_limb_t
+mpn_div_qr_2u_pi1 (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn,
+ mp_limb_t d1, mp_limb_t d0, int shift, mp_limb_t di)
+{
+ mp_limb_t qh;
+ mp_limb_t r2, r1, r0;
+ mp_size_t i;
+
+ ASSERT (nn >= 2);
+ ASSERT (d1 & GMP_NUMB_HIGHBIT);
+ ASSERT (shift > 0);
+
+ r2 = np[nn-1] >> (GMP_LIMB_BITS - shift);
+ r1 = (np[nn-1] << shift) | (np[nn-2] >> (GMP_LIMB_BITS - shift));
+ r0 = np[nn-2] << shift;
+
+ udiv_qr_3by2 (qh, r2, r1, r2, r1, r0, d1, d0, di);
+
+ for (i = nn - 2 - 1; i >= 0; i--)
+ {
+ mp_limb_t q;
+ r0 = np[i];
+ r1 |= r0 >> (GMP_LIMB_BITS - shift);
+ r0 <<= shift;
+ udiv_qr_3by2 (q, r2, r1, r2, r1, r0, d1, d0, di);
+ qp[i] = q;
+ }
+
+ rp[0] = (r1 >> shift) | (r2 << (GMP_LIMB_BITS - shift));
+ rp[1] = r2 >> shift;
+
+ return qh;
+}
diff --git a/gmp/mpn/generic/dive_1.c b/gmp/mpn/generic/dive_1.c
new file mode 100644
index 0000000000..1c0a4e894d
--- /dev/null
+++ b/gmp/mpn/generic/dive_1.c
@@ -0,0 +1,148 @@
+/* mpn_divexact_1 -- mpn by limb exact division.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2000-2003, 2005, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+
+/* Divide a={src,size} by d=divisor and store the quotient in q={dst,size}.
+ q will only be correct if d divides a exactly.
+
+ A separate loop is used for shift==0 because n<<GMP_LIMB_BITS doesn't
+ give zero on all CPUs (for instance it doesn't on the x86s). This
+ separate loop might run faster too, helping odd divisors.
+
+ Possibilities:
+
+ mpn_divexact_1c could be created, accepting and returning c. This would
+ let a long calculation be done piece by piece. Currently there's no
+ particular need for that, and not returning c means that a final umul can
+ be skipped.
+
+ Another use for returning c would be letting the caller know whether the
+ division was in fact exact. It would work just to return the carry bit
+ "c=(l>s)" and let the caller do a final umul if interested.
+
+ When the divisor is even, the factors of two could be handled with a
+ separate mpn_rshift, instead of shifting on the fly. That might be
+ faster on some CPUs and would mean just the shift==0 style loop would be
+ needed.
+
+ If n<<GMP_LIMB_BITS gives zero on a particular CPU then the separate
+ shift==0 loop is unnecessary, and could be eliminated if there's no great
+ speed difference.
+
+ It's not clear whether "/" is the best way to handle size==1. Alpha gcc
+ 2.95 for instance has a poor "/" and might prefer the modular method.
+ Perhaps a tuned parameter should control this.
+
+ If src[size-1] < divisor then dst[size-1] will be zero, and one divide
+ step could be skipped. A test at last step for s<divisor (or ls in the
+ even case) might be a good way to do that. But if this code is often
+ used with small divisors then it might not be worth bothering */
+
+void
+mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor)
+{
+ mp_size_t i;
+ mp_limb_t c, h, l, ls, s, s_next, inverse, dummy;
+ unsigned shift;
+
+ ASSERT (size >= 1);
+ ASSERT (divisor != 0);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, size));
+ ASSERT_MPN (src, size);
+ ASSERT_LIMB (divisor);
+
+ if ((divisor & 1) == 0)
+ {
+ count_trailing_zeros (shift, divisor);
+ divisor >>= shift;
+ }
+ else
+ shift = 0;
+
+ binvert_limb (inverse, divisor);
+ divisor <<= GMP_NAIL_BITS;
+
+ if (shift != 0)
+ {
+ c = 0;
+
+ s = src[0];
+
+ for (i = 1; i < size; i++)
+ {
+ s_next = src[i];
+ ls = ((s >> shift) | (s_next << (GMP_NUMB_BITS-shift))) & GMP_NUMB_MASK;
+ s = s_next;
+
+ SUBC_LIMB (c, l, ls, c);
+
+ l = (l * inverse) & GMP_NUMB_MASK;
+ dst[i - 1] = l;
+
+ umul_ppmm (h, dummy, l, divisor);
+ c += h;
+ }
+ while (i < size);
+
+ ls = s >> shift;
+ l = ls - c;
+ l = (l * inverse) & GMP_NUMB_MASK;
+ dst[size - 1] = l;
+ }
+ else
+ {
+ s = src[0];
+
+ l = (s * inverse) & GMP_NUMB_MASK;
+ dst[0] = l;
+ c = 0;
+
+ for (i = 1; i < size; i++)
+ {
+ umul_ppmm (h, dummy, l, divisor);
+ c += h;
+
+ s = src[i];
+ SUBC_LIMB (c, l, s, c);
+
+ l = (l * inverse) & GMP_NUMB_MASK;
+ dst[i] = l;
+ }
+ }
+}
diff --git a/gmp/mpn/generic/diveby3.c b/gmp/mpn/generic/diveby3.c
new file mode 100644
index 0000000000..2ffd9fe777
--- /dev/null
+++ b/gmp/mpn/generic/diveby3.c
@@ -0,0 +1,174 @@
+/* mpn_divexact_by3c -- mpn exact division by 3.
+
+Copyright 2000-2003, 2008 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if DIVEXACT_BY3_METHOD == 0
+
+mp_limb_t
+mpn_divexact_by3c (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_limb_t c)
+{
+ mp_limb_t r;
+ r = mpn_bdiv_dbm1c (rp, up, un, GMP_NUMB_MASK / 3, GMP_NUMB_MASK / 3 * c);
+
+ /* Possible bdiv_dbm1 return values are C * (GMP_NUMB_MASK / 3), 0 <= C < 3.
+ We want to return C. We compute the remainder mod 4 and notice that the
+ inverse of (2^(2k)-1)/3 mod 4 is 1. */
+ return r & 3;
+}
+
+#endif
+
+#if DIVEXACT_BY3_METHOD == 1
+
+/* The algorithm here is basically the same as mpn_divexact_1, as described
+ in the manual. Namely at each step q = (src[i]-c)*inverse, and new c =
+ borrow(src[i]-c) + high(divisor*q). But because the divisor is just 3,
+ high(divisor*q) can be determined with two comparisons instead of a
+ multiply.
+
+ The "c += ..."s add the high limb of 3*l to c. That high limb will be 0,
+ 1 or 2. Doing two separate "+="s seems to give better code on gcc (as of
+ 2.95.2 at least).
+
+ It will be noted that the new c is formed by adding three values each 0
+ or 1. But the total is only 0, 1 or 2. When the subtraction src[i]-c
+ causes a borrow, that leaves a limb value of either 0xFF...FF or
+ 0xFF...FE. The multiply by MODLIMB_INVERSE_3 gives 0x55...55 or
+ 0xAA...AA respectively, and in those cases high(3*q) is only 0 or 1
+ respectively, hence a total of no more than 2.
+
+ Alternatives:
+
+ This implementation has each multiply on the dependent chain, due to
+ "l=s-c". See below for alternative code which avoids that. */
+
+mp_limb_t
+mpn_divexact_by3c (mp_ptr restrict rp, mp_srcptr restrict up, mp_size_t un, mp_limb_t c)
+{
+ mp_limb_t l, q, s;
+ mp_size_t i;
+
+ ASSERT (un >= 1);
+ ASSERT (c == 0 || c == 1 || c == 2);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, un));
+
+ i = 0;
+ do
+ {
+ s = up[i];
+ SUBC_LIMB (c, l, s, c);
+
+ q = (l * MODLIMB_INVERSE_3) & GMP_NUMB_MASK;
+ rp[i] = q;
+
+ c += (q >= GMP_NUMB_CEIL_MAX_DIV3);
+ c += (q >= GMP_NUMB_CEIL_2MAX_DIV3);
+ }
+ while (++i < un);
+
+ ASSERT (c == 0 || c == 1 || c == 2);
+ return c;
+}
+
+
+#endif
+
+#if DIVEXACT_BY3_METHOD == 2
+
+/* The following alternative code re-arranges the quotient calculation from
+ (src[i]-c)*inverse to instead
+
+ q = src[i]*inverse - c*inverse
+
+ thereby allowing src[i]*inverse to be scheduled back as far as desired,
+ making full use of multiplier throughput and leaving just some carry
+ handing on the dependent chain.
+
+ The carry handling consists of determining the c for the next iteration.
+ This is the same as described above, namely look for any borrow from
+ src[i]-c, and at the high of 3*q.
+
+ high(3*q) is done with two comparisons as above (in c2 and c3). The
+ borrow from src[i]-c is incorporated into those by noting that if there's
+ a carry then then we have src[i]-c == 0xFF..FF or 0xFF..FE, in turn
+ giving q = 0x55..55 or 0xAA..AA. Adding 1 to either of those q values is
+ enough to make high(3*q) come out 1 bigger, as required.
+
+ l = -c*inverse is calculated at the same time as c, since for most chips
+ it can be more conveniently derived from separate c1/c2/c3 values than
+ from a combined c equal to 0, 1 or 2.
+
+ The net effect is that with good pipelining this loop should be able to
+ run at perhaps 4 cycles/limb, depending on available execute resources
+ etc.
+
+ Usage:
+
+ This code is not used by default, since we really can't rely on the
+ compiler generating a good software pipeline, nor on such an approach
+ even being worthwhile on all CPUs.
+
+ Itanium is one chip where this algorithm helps though, see
+ mpn/ia64/diveby3.asm. */
+
+mp_limb_t
+mpn_divexact_by3c (mp_ptr restrict rp, mp_srcptr restrict up, mp_size_t un, mp_limb_t cy)
+{
+ mp_limb_t s, sm, cl, q, qx, c2, c3;
+ mp_size_t i;
+
+ ASSERT (un >= 1);
+ ASSERT (cy == 0 || cy == 1 || cy == 2);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, un));
+
+ cl = cy == 0 ? 0 : cy == 1 ? -MODLIMB_INVERSE_3 : -2*MODLIMB_INVERSE_3;
+
+ for (i = 0; i < un; i++)
+ {
+ s = up[i];
+ sm = (s * MODLIMB_INVERSE_3) & GMP_NUMB_MASK;
+
+ q = (cl + sm) & GMP_NUMB_MASK;
+ rp[i] = q;
+ qx = q + (s < cy);
+
+ c2 = qx >= GMP_NUMB_CEIL_MAX_DIV3;
+ c3 = qx >= GMP_NUMB_CEIL_2MAX_DIV3 ;
+
+ cy = c2 + c3;
+ cl = (-c2 & -MODLIMB_INVERSE_3) + (-c3 & -MODLIMB_INVERSE_3);
+ }
+
+ return cy;
+}
+
+#endif
diff --git a/gmp/mpn/generic/divexact.c b/gmp/mpn/generic/divexact.c
new file mode 100644
index 0000000000..47a47e3d80
--- /dev/null
+++ b/gmp/mpn/generic/divexact.c
@@ -0,0 +1,294 @@
+/* mpn_divexact(qp,np,nn,dp,dn,tp) -- Divide N = {np,nn} by D = {dp,dn} storing
+ the result in Q = {qp,nn-dn+1} expecting no remainder. Overlap allowed
+ between Q and N; all other overlap disallowed.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#if 1
+void
+mpn_divexact (mp_ptr qp,
+ mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn)
+{
+ unsigned shift;
+ mp_size_t qn;
+ mp_ptr tp;
+ TMP_DECL;
+
+ ASSERT (dn > 0);
+ ASSERT (nn >= dn);
+ ASSERT (dp[dn-1] > 0);
+
+ while (dp[0] == 0)
+ {
+ ASSERT (np[0] == 0);
+ dp++;
+ np++;
+ dn--;
+ nn--;
+ }
+
+ if (dn == 1)
+ {
+ MPN_DIVREM_OR_DIVEXACT_1 (qp, np, nn, dp[0]);
+ return;
+ }
+
+ TMP_MARK;
+
+ qn = nn + 1 - dn;
+ count_trailing_zeros (shift, dp[0]);
+
+ if (shift > 0)
+ {
+ mp_ptr wp;
+ mp_size_t ss;
+ ss = (dn > qn) ? qn + 1 : dn;
+
+ tp = TMP_ALLOC_LIMBS (ss);
+ mpn_rshift (tp, dp, ss, shift);
+ dp = tp;
+
+ /* Since we have excluded dn == 1, we have nn > qn, and we need
+ to shift one limb beyond qn. */
+ wp = TMP_ALLOC_LIMBS (qn + 1);
+ mpn_rshift (wp, np, qn + 1, shift);
+ np = wp;
+ }
+
+ if (dn > qn)
+ dn = qn;
+
+ tp = TMP_ALLOC_LIMBS (mpn_bdiv_q_itch (qn, dn));
+ mpn_bdiv_q (qp, np, qn, dp, dn, tp);
+ TMP_FREE;
+}
+
+#else
+
+/* We use the Jebelean's bidirectional exact division algorithm. This is
+ somewhat naively implemented, with equal quotient parts done by 2-adic
+ division and truncating division. Since 2-adic division is faster, it
+ should be used for a larger chunk.
+
+ This code is horrendously ugly, in all sorts of ways.
+
+ * It was hacked without much care or thought, but with a testing program.
+ * It handles scratch space frivolously, and furthermore the itch function
+ is broken.
+ * Doesn't provide any measures to deal with mu_divappr_q's +3 error. We
+ have yet to provoke an error due to this, though.
+ * Algorithm selection leaves a lot to be desired. In particular, the choice
+ between DC and MU isn't a point, but we treat it like one.
+ * It makes the msb part 1 or 2 limbs larger than the lsb part, in spite of
+ that the latter is faster. We should at least reverse this, but perhaps
+ we should make the lsb part considerably larger. (How do we tune this?)
+*/
+
+mp_size_t
+mpn_divexact_itch (mp_size_t nn, mp_size_t dn)
+{
+ return nn + dn; /* FIXME this is not right */
+}
+
+void
+mpn_divexact (mp_ptr qp,
+ mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_ptr scratch)
+{
+ mp_size_t qn;
+ mp_size_t nn0, qn0;
+ mp_size_t nn1, qn1;
+ mp_ptr tp;
+ mp_limb_t qml;
+ mp_limb_t qh;
+ int cnt;
+ mp_ptr xdp;
+ mp_limb_t di;
+ mp_limb_t cy;
+ gmp_pi1_t dinv;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ qn = nn - dn + 1;
+
+ /* For small divisors, and small quotients, don't use Jebelean's algorithm. */
+ if (dn < DIVEXACT_JEB_THRESHOLD || qn < DIVEXACT_JEB_THRESHOLD)
+ {
+ tp = scratch;
+ MPN_COPY (tp, np, qn);
+ binvert_limb (di, dp[0]); di = -di;
+ dn = MIN (dn, qn);
+ mpn_sbpi1_bdiv_q (qp, tp, qn, dp, dn, di);
+ TMP_FREE;
+ return;
+ }
+
+ qn0 = ((nn - dn) >> 1) + 1; /* low quotient size */
+
+ /* If quotient is much larger than the divisor, the bidirectional algorithm
+ does not work as currently implemented. Fall back to plain bdiv. */
+ if (qn0 > dn)
+ {
+ if (BELOW_THRESHOLD (dn, DC_BDIV_Q_THRESHOLD))
+ {
+ tp = scratch;
+ MPN_COPY (tp, np, qn);
+ binvert_limb (di, dp[0]); di = -di;
+ dn = MIN (dn, qn);
+ mpn_sbpi1_bdiv_q (qp, tp, qn, dp, dn, di);
+ }
+ else if (BELOW_THRESHOLD (dn, MU_BDIV_Q_THRESHOLD))
+ {
+ tp = scratch;
+ MPN_COPY (tp, np, qn);
+ binvert_limb (di, dp[0]); di = -di;
+ mpn_dcpi1_bdiv_q (qp, tp, qn, dp, dn, di);
+ }
+ else
+ {
+ mpn_mu_bdiv_q (qp, np, qn, dp, dn, scratch);
+ }
+ TMP_FREE;
+ return;
+ }
+
+ nn0 = qn0 + qn0;
+
+ nn1 = nn0 - 1 + ((nn-dn) & 1);
+ qn1 = qn0;
+ if (LIKELY (qn0 != dn))
+ {
+ nn1 = nn1 + 1;
+ qn1 = qn1 + 1;
+ if (UNLIKELY (dp[dn - 1] == 1 && qn1 != dn))
+ {
+ /* If the leading divisor limb == 1, i.e. has just one bit, we have
+ to include an extra limb in order to get the needed overlap. */
+ /* FIXME: Now with the mu_divappr_q function, we should really need
+ more overlap. That indicates one of two things: (1) The test code
+ is not good. (2) We actually overlap too much by default. */
+ nn1 = nn1 + 1;
+ qn1 = qn1 + 1;
+ }
+ }
+
+ tp = TMP_ALLOC_LIMBS (nn1 + 1);
+
+ count_leading_zeros (cnt, dp[dn - 1]);
+
+ /* Normalize divisor, store into tmp area. */
+ if (cnt != 0)
+ {
+ xdp = TMP_ALLOC_LIMBS (qn1);
+ mpn_lshift (xdp, dp + dn - qn1, qn1, cnt);
+ }
+ else
+ {
+ xdp = (mp_ptr) dp + dn - qn1;
+ }
+
+ /* Shift dividend according to the divisor normalization. */
+ /* FIXME: We compute too much here for XX_divappr_q, but these functions'
+ interfaces want a pointer to the imaginative least significant limb, not
+ to the least significant *used* limb. Of course, we could leave nn1-qn1
+ rubbish limbs in the low part, to save some time. */
+ if (cnt != 0)
+ {
+ cy = mpn_lshift (tp, np + nn - nn1, nn1, cnt);
+ if (cy != 0)
+ {
+ tp[nn1] = cy;
+ nn1++;
+ }
+ }
+ else
+ {
+ /* FIXME: This copy is not needed for mpn_mu_divappr_q, except when the
+ mpn_sub_n right before is executed. */
+ MPN_COPY (tp, np + nn - nn1, nn1);
+ }
+
+ invert_pi1 (dinv, xdp[qn1 - 1], xdp[qn1 - 2]);
+ if (BELOW_THRESHOLD (qn1, DC_DIVAPPR_Q_THRESHOLD))
+ {
+ qp[qn0 - 1 + nn1 - qn1] = mpn_sbpi1_divappr_q (qp + qn0 - 1, tp, nn1, xdp, qn1, dinv.inv32);
+ }
+ else if (BELOW_THRESHOLD (qn1, MU_DIVAPPR_Q_THRESHOLD))
+ {
+ qp[qn0 - 1 + nn1 - qn1] = mpn_dcpi1_divappr_q (qp + qn0 - 1, tp, nn1, xdp, qn1, &dinv);
+ }
+ else
+ {
+ /* FIXME: mpn_mu_divappr_q doesn't handle qh != 0. Work around it with a
+ conditional subtraction here. */
+ qh = mpn_cmp (tp + nn1 - qn1, xdp, qn1) >= 0;
+ if (qh)
+ mpn_sub_n (tp + nn1 - qn1, tp + nn1 - qn1, xdp, qn1);
+ mpn_mu_divappr_q (qp + qn0 - 1, tp, nn1, xdp, qn1, scratch);
+ qp[qn0 - 1 + nn1 - qn1] = qh;
+ }
+ qml = qp[qn0 - 1];
+
+ binvert_limb (di, dp[0]); di = -di;
+
+ if (BELOW_THRESHOLD (qn0, DC_BDIV_Q_THRESHOLD))
+ {
+ MPN_COPY (tp, np, qn0);
+ mpn_sbpi1_bdiv_q (qp, tp, qn0, dp, qn0, di);
+ }
+ else if (BELOW_THRESHOLD (qn0, MU_BDIV_Q_THRESHOLD))
+ {
+ MPN_COPY (tp, np, qn0);
+ mpn_dcpi1_bdiv_q (qp, tp, qn0, dp, qn0, di);
+ }
+ else
+ {
+ mpn_mu_bdiv_q (qp, np, qn0, dp, qn0, scratch);
+ }
+
+ if (qml < qp[qn0 - 1])
+ mpn_decr_u (qp + qn0, 1);
+
+ TMP_FREE;
+}
+#endif
diff --git a/gmp/mpn/generic/divis.c b/gmp/mpn/generic/divis.c
new file mode 100644
index 0000000000..9e162e60d2
--- /dev/null
+++ b/gmp/mpn/generic/divis.c
@@ -0,0 +1,201 @@
+/* mpn_divisible_p -- mpn by mpn divisibility test
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001, 2002, 2005, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Determine whether A={ap,an} is divisible by D={dp,dn}. Must have both
+ operands normalized, meaning high limbs non-zero, except that an==0 is
+ allowed.
+
+ There usually won't be many low zero bits on D, but the checks for this
+ are fast and might pick up a few operand combinations, in particular they
+ might reduce D to fit the single-limb mod_1/modexact_1 code.
+
+ Future:
+
+ Getting the remainder limb by limb would make an early exit possible on
+ finding a non-zero. This would probably have to be bdivmod style so
+ there's no addback, but it would need a multi-precision inverse and so
+ might be slower than the plain method (on small sizes at least).
+
+ When D must be normalized (shifted to low bit set), it's possible to
+ suppress the bit-shifting of A down, as long as it's already been checked
+ that A has at least as many trailing zero bits as D. */
+
+int
+mpn_divisible_p (mp_srcptr ap, mp_size_t an,
+ mp_srcptr dp, mp_size_t dn)
+{
+ mp_limb_t alow, dlow, dmask;
+ mp_ptr qp, rp, tp;
+ mp_size_t i;
+ mp_limb_t di;
+ unsigned twos;
+ TMP_DECL;
+
+ ASSERT (an >= 0);
+ ASSERT (an == 0 || ap[an-1] != 0);
+ ASSERT (dn >= 1);
+ ASSERT (dp[dn-1] != 0);
+ ASSERT_MPN (ap, an);
+ ASSERT_MPN (dp, dn);
+
+ /* When a<d only a==0 is divisible.
+ Notice this test covers all cases of an==0. */
+ if (an < dn)
+ return (an == 0);
+
+ /* Strip low zero limbs from d, requiring a==0 on those. */
+ for (;;)
+ {
+ alow = *ap;
+ dlow = *dp;
+
+ if (dlow != 0)
+ break;
+
+ if (alow != 0)
+ return 0; /* a has fewer low zero limbs than d, so not divisible */
+
+ /* a!=0 and d!=0 so won't get to n==0 */
+ an--; ASSERT (an >= 1);
+ dn--; ASSERT (dn >= 1);
+ ap++;
+ dp++;
+ }
+
+ /* a must have at least as many low zero bits as d */
+ dmask = LOW_ZEROS_MASK (dlow);
+ if ((alow & dmask) != 0)
+ return 0;
+
+ if (dn == 1)
+ {
+ if (ABOVE_THRESHOLD (an, BMOD_1_TO_MOD_1_THRESHOLD))
+ return mpn_mod_1 (ap, an, dlow) == 0;
+
+ count_trailing_zeros (twos, dlow);
+ dlow >>= twos;
+ return mpn_modexact_1_odd (ap, an, dlow) == 0;
+ }
+
+ if (dn == 2)
+ {
+ mp_limb_t dsecond = dp[1];
+ if (dsecond <= dmask)
+ {
+ count_trailing_zeros (twos, dlow);
+ dlow = (dlow >> twos) | (dsecond << (GMP_NUMB_BITS-twos));
+ ASSERT_LIMB (dlow);
+ return MPN_MOD_OR_MODEXACT_1_ODD (ap, an, dlow) == 0;
+ }
+ }
+
+ /* Should we compute Q = A * D^(-1) mod B^k,
+ R = A - Q * D mod B^k
+ here, for some small values of k? Then check if R = 0 (mod B^k). */
+
+ /* We could also compute A' = A mod T and D' = D mod P, for some
+ P = 3 * 5 * 7 * 11 ..., and then check if any prime factor from P
+ dividing D' also divides A'. */
+
+ TMP_MARK;
+
+ rp = TMP_ALLOC_LIMBS (an + 1);
+ qp = TMP_ALLOC_LIMBS (an - dn + 1); /* FIXME: Could we avoid this? */
+
+ count_trailing_zeros (twos, dp[0]);
+
+ if (twos != 0)
+ {
+ tp = TMP_ALLOC_LIMBS (dn);
+ ASSERT_NOCARRY (mpn_rshift (tp, dp, dn, twos));
+ dp = tp;
+
+ ASSERT_NOCARRY (mpn_rshift (rp, ap, an, twos));
+ }
+ else
+ {
+ MPN_COPY (rp, ap, an);
+ }
+ if (rp[an - 1] >= dp[dn - 1])
+ {
+ rp[an] = 0;
+ an++;
+ }
+ else if (an == dn)
+ {
+ TMP_FREE;
+ return 0;
+ }
+
+ ASSERT (an > dn); /* requirement of functions below */
+
+ if (BELOW_THRESHOLD (dn, DC_BDIV_QR_THRESHOLD) ||
+ BELOW_THRESHOLD (an - dn, DC_BDIV_QR_THRESHOLD))
+ {
+ binvert_limb (di, dp[0]);
+ mpn_sbpi1_bdiv_qr (qp, rp, an, dp, dn, -di);
+ rp += an - dn;
+ }
+ else if (BELOW_THRESHOLD (dn, MU_BDIV_QR_THRESHOLD))
+ {
+ binvert_limb (di, dp[0]);
+ mpn_dcpi1_bdiv_qr (qp, rp, an, dp, dn, -di);
+ rp += an - dn;
+ }
+ else
+ {
+ tp = TMP_ALLOC_LIMBS (mpn_mu_bdiv_qr_itch (an, dn));
+ mpn_mu_bdiv_qr (qp, rp, rp, an, dp, dn, tp);
+ }
+
+ /* test for {rp,dn} zero or non-zero */
+ i = 0;
+ do
+ {
+ if (rp[i] != 0)
+ {
+ TMP_FREE;
+ return 0;
+ }
+ }
+ while (++i < dn);
+
+ TMP_FREE;
+ return 1;
+}
diff --git a/gmp/mpn/generic/divrem.c b/gmp/mpn/generic/divrem.c
new file mode 100644
index 0000000000..f420992746
--- /dev/null
+++ b/gmp/mpn/generic/divrem.c
@@ -0,0 +1,108 @@
+/* mpn_divrem -- Divide natural numbers, producing both remainder and
+ quotient. This is now just a middle layer calling mpn_tdiv_qr.
+
+Copyright 1993-1997, 1999-2002, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_divrem (mp_ptr qp, mp_size_t qxn,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn)
+{
+ ASSERT (qxn >= 0);
+ ASSERT (nn >= dn);
+ ASSERT (dn >= 1);
+ ASSERT (dp[dn-1] & GMP_NUMB_HIGHBIT);
+ ASSERT (! MPN_OVERLAP_P (np, nn, dp, dn));
+ ASSERT (! MPN_OVERLAP_P (qp, nn-dn+qxn, np, nn) || qp==np+dn+qxn);
+ ASSERT (! MPN_OVERLAP_P (qp, nn-dn+qxn, dp, dn));
+ ASSERT_MPN (np, nn);
+ ASSERT_MPN (dp, dn);
+
+ if (dn == 1)
+ {
+ mp_limb_t ret;
+ mp_ptr q2p;
+ mp_size_t qn;
+ TMP_DECL;
+
+ TMP_MARK;
+ q2p = TMP_ALLOC_LIMBS (nn + qxn);
+
+ np[0] = mpn_divrem_1 (q2p, qxn, np, nn, dp[0]);
+ qn = nn + qxn - 1;
+ MPN_COPY (qp, q2p, qn);
+ ret = q2p[qn];
+
+ TMP_FREE;
+ return ret;
+ }
+ else if (dn == 2)
+ {
+ return mpn_divrem_2 (qp, qxn, np, nn, dp);
+ }
+ else
+ {
+ mp_ptr rp, q2p;
+ mp_limb_t qhl;
+ mp_size_t qn;
+ TMP_DECL;
+
+ TMP_MARK;
+ if (UNLIKELY (qxn != 0))
+ {
+ mp_ptr n2p;
+ n2p = TMP_ALLOC_LIMBS (nn + qxn);
+ MPN_ZERO (n2p, qxn);
+ MPN_COPY (n2p + qxn, np, nn);
+ q2p = TMP_ALLOC_LIMBS (nn - dn + qxn + 1);
+ rp = TMP_ALLOC_LIMBS (dn);
+ mpn_tdiv_qr (q2p, rp, 0L, n2p, nn + qxn, dp, dn);
+ MPN_COPY (np, rp, dn);
+ qn = nn - dn + qxn;
+ MPN_COPY (qp, q2p, qn);
+ qhl = q2p[qn];
+ }
+ else
+ {
+ q2p = TMP_ALLOC_LIMBS (nn - dn + 1);
+ rp = TMP_ALLOC_LIMBS (dn);
+ mpn_tdiv_qr (q2p, rp, 0L, np, nn, dp, dn);
+ MPN_COPY (np, rp, dn); /* overwrite np area with remainder */
+ qn = nn - dn;
+ MPN_COPY (qp, q2p, qn);
+ qhl = q2p[qn];
+ }
+ TMP_FREE;
+ return qhl;
+ }
+}
diff --git a/gmp/mpn/generic/divrem_1.c b/gmp/mpn/generic/divrem_1.c
new file mode 100644
index 0000000000..9157b5735e
--- /dev/null
+++ b/gmp/mpn/generic/divrem_1.c
@@ -0,0 +1,255 @@
+/* mpn_divrem_1 -- mpn by limb division.
+
+Copyright 1991, 1993, 1994, 1996, 1998-2000, 2002, 2003 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* The size where udiv_qrnnd_preinv should be used rather than udiv_qrnnd,
+ meaning the quotient size where that should happen, the quotient size
+ being how many udiv divisions will be done.
+
+ The default is to use preinv always, CPUs where this doesn't suit have
+ tuned thresholds. Note in particular that preinv should certainly be
+ used if that's the only division available (USE_PREINV_ALWAYS). */
+
+#ifndef DIVREM_1_NORM_THRESHOLD
+#define DIVREM_1_NORM_THRESHOLD 0
+#endif
+#ifndef DIVREM_1_UNNORM_THRESHOLD
+#define DIVREM_1_UNNORM_THRESHOLD 0
+#endif
+
+
+
+/* If the cpu only has multiply-by-inverse division (eg. alpha), then NORM
+ and UNNORM thresholds are 0 and only the inversion code is included.
+
+ If multiply-by-inverse is never viable, then NORM and UNNORM thresholds
+ will be MP_SIZE_T_MAX and only the plain division code is included.
+
+ Otherwise mul-by-inverse is better than plain division above some
+ threshold, and best results are obtained by having code for both present.
+
+ The main reason for separating the norm and unnorm cases is that not all
+ CPUs give zero for "n0 >> GMP_LIMB_BITS" which would arise in the unnorm
+ code used on an already normalized divisor.
+
+ If UDIV_NEEDS_NORMALIZATION is false then plain division uses the same
+ non-shifting code for both the norm and unnorm cases, though with
+ different criteria for skipping a division, and with different thresholds
+ of course. And in fact if inversion is never viable, then that simple
+ non-shifting division would be all that's left.
+
+ The NORM and UNNORM thresholds might not differ much, but if there's
+ going to be separate code for norm and unnorm then it makes sense to have
+ separate thresholds. One thing that's possible is that the
+ mul-by-inverse might be better only for normalized divisors, due to that
+ case not needing variable bit shifts.
+
+ Notice that the thresholds are tested after the decision to possibly skip
+ one divide step, so they're based on the actual number of divisions done.
+
+ For the unnorm case, it would be possible to call mpn_lshift to adjust
+ the dividend all in one go (into the quotient space say), rather than
+ limb-by-limb in the loop. This might help if mpn_lshift is a lot faster
+ than what the compiler can generate for EXTRACT. But this is left to CPU
+ specific implementations to consider, especially since EXTRACT isn't on
+ the dependent chain. */
+
+mp_limb_t
+mpn_divrem_1 (mp_ptr qp, mp_size_t qxn,
+ mp_srcptr up, mp_size_t un, mp_limb_t d)
+{
+ mp_size_t n;
+ mp_size_t i;
+ mp_limb_t n1, n0;
+ mp_limb_t r = 0;
+
+ ASSERT (qxn >= 0);
+ ASSERT (un >= 0);
+ ASSERT (d != 0);
+ /* FIXME: What's the correct overlap rule when qxn!=0? */
+ ASSERT (MPN_SAME_OR_SEPARATE_P (qp+qxn, up, un));
+
+ n = un + qxn;
+ if (n == 0)
+ return 0;
+
+ d <<= GMP_NAIL_BITS;
+
+ qp += (n - 1); /* Make qp point at most significant quotient limb */
+
+ if ((d & GMP_LIMB_HIGHBIT) != 0)
+ {
+ if (un != 0)
+ {
+ /* High quotient limb is 0 or 1, skip a divide step. */
+ mp_limb_t q;
+ r = up[un - 1] << GMP_NAIL_BITS;
+ q = (r >= d);
+ *qp-- = q;
+ r -= (d & -q);
+ r >>= GMP_NAIL_BITS;
+ n--;
+ un--;
+ }
+
+ if (BELOW_THRESHOLD (n, DIVREM_1_NORM_THRESHOLD))
+ {
+ plain:
+ for (i = un - 1; i >= 0; i--)
+ {
+ n0 = up[i] << GMP_NAIL_BITS;
+ udiv_qrnnd (*qp, r, r, n0, d);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ }
+ for (i = qxn - 1; i >= 0; i--)
+ {
+ udiv_qrnnd (*qp, r, r, CNST_LIMB(0), d);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ }
+ return r;
+ }
+ else
+ {
+ /* Multiply-by-inverse, divisor already normalized. */
+ mp_limb_t dinv;
+ invert_limb (dinv, d);
+
+ for (i = un - 1; i >= 0; i--)
+ {
+ n0 = up[i] << GMP_NAIL_BITS;
+ udiv_qrnnd_preinv (*qp, r, r, n0, d, dinv);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ }
+ for (i = qxn - 1; i >= 0; i--)
+ {
+ udiv_qrnnd_preinv (*qp, r, r, CNST_LIMB(0), d, dinv);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ }
+ return r;
+ }
+ }
+ else
+ {
+ /* Most significant bit of divisor == 0. */
+ int cnt;
+
+ /* Skip a division if high < divisor (high quotient 0). Testing here
+ before normalizing will still skip as often as possible. */
+ if (un != 0)
+ {
+ n1 = up[un - 1] << GMP_NAIL_BITS;
+ if (n1 < d)
+ {
+ r = n1 >> GMP_NAIL_BITS;
+ *qp-- = 0;
+ n--;
+ if (n == 0)
+ return r;
+ un--;
+ }
+ }
+
+ if (! UDIV_NEEDS_NORMALIZATION
+ && BELOW_THRESHOLD (n, DIVREM_1_UNNORM_THRESHOLD))
+ goto plain;
+
+ count_leading_zeros (cnt, d);
+ d <<= cnt;
+ r <<= cnt;
+
+ if (UDIV_NEEDS_NORMALIZATION
+ && BELOW_THRESHOLD (n, DIVREM_1_UNNORM_THRESHOLD))
+ {
+ mp_limb_t nshift;
+ if (un != 0)
+ {
+ n1 = up[un - 1] << GMP_NAIL_BITS;
+ r |= (n1 >> (GMP_LIMB_BITS - cnt));
+ for (i = un - 2; i >= 0; i--)
+ {
+ n0 = up[i] << GMP_NAIL_BITS;
+ nshift = (n1 << cnt) | (n0 >> (GMP_NUMB_BITS - cnt));
+ udiv_qrnnd (*qp, r, r, nshift, d);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ n1 = n0;
+ }
+ udiv_qrnnd (*qp, r, r, n1 << cnt, d);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ }
+ for (i = qxn - 1; i >= 0; i--)
+ {
+ udiv_qrnnd (*qp, r, r, CNST_LIMB(0), d);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ }
+ return r >> cnt;
+ }
+ else
+ {
+ mp_limb_t dinv, nshift;
+ invert_limb (dinv, d);
+ if (un != 0)
+ {
+ n1 = up[un - 1] << GMP_NAIL_BITS;
+ r |= (n1 >> (GMP_LIMB_BITS - cnt));
+ for (i = un - 2; i >= 0; i--)
+ {
+ n0 = up[i] << GMP_NAIL_BITS;
+ nshift = (n1 << cnt) | (n0 >> (GMP_NUMB_BITS - cnt));
+ udiv_qrnnd_preinv (*qp, r, r, nshift, d, dinv);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ n1 = n0;
+ }
+ udiv_qrnnd_preinv (*qp, r, r, n1 << cnt, d, dinv);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ }
+ for (i = qxn - 1; i >= 0; i--)
+ {
+ udiv_qrnnd_preinv (*qp, r, r, CNST_LIMB(0), d, dinv);
+ r >>= GMP_NAIL_BITS;
+ qp--;
+ }
+ return r >> cnt;
+ }
+ }
+}
diff --git a/gmp/mpn/generic/divrem_2.c b/gmp/mpn/generic/divrem_2.c
new file mode 100644
index 0000000000..30d24bb102
--- /dev/null
+++ b/gmp/mpn/generic/divrem_2.c
@@ -0,0 +1,119 @@
+/* mpn_divrem_2 -- Divide natural numbers, producing both remainder and
+ quotient. The divisor is two limbs.
+
+ THIS FILE CONTAINS INTERNAL FUNCTIONS WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+
+Copyright 1993-1996, 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Divide num {np,nn} by den {dp,2} and write the nn-2 least significant
+ quotient limbs at qp and the 2 long remainder at np. If qxn is non-zero,
+ generate that many fraction bits and append them after the other quotient
+ limbs. Return the most significant limb of the quotient, this is always 0
+ or 1.
+
+ Preconditions:
+ 1. The most significant bit of the divisor must be set.
+ 2. qp must either not overlap with the input operands at all, or
+ qp >= np + 2 must hold true. (This means that it's possible to put
+ the quotient in the high part of {np,nn}, right above the remainder.
+ 3. nn >= 2, even if qxn is non-zero. */
+
+mp_limb_t
+mpn_divrem_2 (mp_ptr qp, mp_size_t qxn,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp)
+{
+ mp_limb_t most_significant_q_limb;
+ mp_size_t i;
+ mp_limb_t r1, r0, d1, d0;
+ gmp_pi1_t di;
+
+ ASSERT (nn >= 2);
+ ASSERT (qxn >= 0);
+ ASSERT (dp[1] & GMP_NUMB_HIGHBIT);
+ ASSERT (! MPN_OVERLAP_P (qp, nn-2+qxn, np, nn) || qp >= np+2);
+ ASSERT_MPN (np, nn);
+ ASSERT_MPN (dp, 2);
+
+ np += nn - 2;
+ d1 = dp[1];
+ d0 = dp[0];
+ r1 = np[1];
+ r0 = np[0];
+
+ most_significant_q_limb = 0;
+ if (r1 >= d1 && (r1 > d1 || r0 >= d0))
+ {
+#if GMP_NAIL_BITS == 0
+ sub_ddmmss (r1, r0, r1, r0, d1, d0);
+#else
+ r0 = r0 - d0;
+ r1 = r1 - d1 - (r0 >> GMP_LIMB_BITS - 1);
+ r0 &= GMP_NUMB_MASK;
+#endif
+ most_significant_q_limb = 1;
+ }
+
+ invert_pi1 (di, d1, d0);
+
+ qp += qxn;
+
+ for (i = nn - 2 - 1; i >= 0; i--)
+ {
+ mp_limb_t n0, q;
+ n0 = np[-1];
+ udiv_qr_3by2 (q, r1, r0, r1, r0, n0, d1, d0, di.inv32);
+ np--;
+ qp[i] = q;
+ }
+
+ if (UNLIKELY (qxn != 0))
+ {
+ qp -= qxn;
+ for (i = qxn - 1; i >= 0; i--)
+ {
+ mp_limb_t q;
+ udiv_qr_3by2 (q, r1, r0, r1, r0, CNST_LIMB(0), d1, d0, di.inv32);
+ qp[i] = q;
+ }
+ }
+
+ np[1] = r1;
+ np[0] = r0;
+
+ return most_significant_q_limb;
+}
diff --git a/gmp/mpn/generic/dump.c b/gmp/mpn/generic/dump.c
new file mode 100644
index 0000000000..3a73fe49e3
--- /dev/null
+++ b/gmp/mpn/generic/dump.c
@@ -0,0 +1,100 @@
+/* THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS NOT SAFE TO
+ CALL THIS FUNCTION DIRECTLY. IN FACT, IT IS ALMOST GUARANTEED THAT THIS
+ FUNCTION WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+
+Copyright 1996, 2000-2002, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if GMP_NUMB_BITS % 4 == 0
+void
+mpn_dump (mp_srcptr ptr, mp_size_t n)
+{
+ MPN_NORMALIZE (ptr, n);
+
+ if (n == 0)
+ printf ("0\n");
+ else
+ {
+ n--;
+#if _LONG_LONG_LIMB
+ if ((ptr[n] >> GMP_LIMB_BITS / 2) != 0)
+ {
+ printf ("%lX", (unsigned long) (ptr[n] >> GMP_LIMB_BITS / 2));
+ printf ("%0*lX", (GMP_LIMB_BITS / 2 / 4), (unsigned long) ptr[n]);
+ }
+ else
+#endif
+ printf ("%lX", (unsigned long) ptr[n]);
+
+ while (n)
+ {
+ n--;
+#if _LONG_LONG_LIMB
+ printf ("%0*lX", (GMP_NUMB_BITS - GMP_LIMB_BITS / 2) / 4,
+ (unsigned long) (ptr[n] >> GMP_LIMB_BITS / 2));
+ printf ("%0*lX", GMP_LIMB_BITS / 2 / 4, (unsigned long) ptr[n]);
+#else
+ printf ("%0*lX", GMP_NUMB_BITS / 4, (unsigned long) ptr[n]);
+#endif
+ }
+ printf ("\n");
+ }
+}
+
+#else
+
+static void
+mpn_recdump (mp_ptr p, mp_size_t n)
+{
+ mp_limb_t lo;
+ if (n != 0)
+ {
+ lo = p[0] & 0xf;
+ mpn_rshift (p, p, n, 4);
+ mpn_recdump (p, n);
+ printf ("%lX", lo);
+ }
+}
+
+void
+mpn_dump (mp_srcptr p, mp_size_t n)
+{
+ mp_ptr tp;
+ TMP_DECL;
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS (n);
+ MPN_COPY (tp, p, n);
+ TMP_FREE;
+}
+
+#endif
diff --git a/gmp/mpn/generic/fib2_ui.c b/gmp/mpn/generic/fib2_ui.c
new file mode 100644
index 0000000000..eb6e56e736
--- /dev/null
+++ b/gmp/mpn/generic/fib2_ui.c
@@ -0,0 +1,189 @@
+/* mpn_fib2_ui -- calculate Fibonacci numbers.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001, 2002, 2005, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* change this to "#define TRACE(x) x" for diagnostics */
+#define TRACE(x)
+
+
+/* Store F[n] at fp and F[n-1] at f1p. fp and f1p should have room for
+ MPN_FIB2_SIZE(n) limbs.
+
+ The return value is the actual number of limbs stored, this will be at
+ least 1. fp[size-1] will be non-zero, except when n==0, in which case
+ fp[0] is 0 and f1p[0] is 1. f1p[size-1] can be zero, since F[n-1]<F[n]
+ (for n>0).
+
+ Notes:
+
+ In F[2k+1] with k even, +2 is applied to 4*F[k]^2 just by ORing into the
+ low limb.
+
+ In F[2k+1] with k odd, -2 is applied to the low limb of 4*F[k]^2 -
+ F[k-1]^2. This F[2k+1] is an F[4m+3] and such numbers are congruent to
+ 1, 2 or 5 mod 8, which means no underflow reaching it with a -2 (since
+ that would leave 6 or 7 mod 8).
+
+ This property of F[4m+3] can be verified by induction on F[4m+3] =
+ 7*F[4m-1] - F[4m-5], that formula being a standard lucas sequence
+ identity U[i+j] = U[i]*V[j] - U[i-j]*Q^j.
+*/
+
+mp_size_t
+mpn_fib2_ui (mp_ptr fp, mp_ptr f1p, unsigned long int n)
+{
+ mp_size_t size;
+ unsigned long nfirst, mask;
+
+ TRACE (printf ("mpn_fib2_ui n=%lu\n", n));
+
+ ASSERT (! MPN_OVERLAP_P (fp, MPN_FIB2_SIZE(n), f1p, MPN_FIB2_SIZE(n)));
+
+ /* Take a starting pair from the table. */
+ mask = 1;
+ for (nfirst = n; nfirst > FIB_TABLE_LIMIT; nfirst /= 2)
+ mask <<= 1;
+ TRACE (printf ("nfirst=%lu mask=0x%lX\n", nfirst, mask));
+
+ f1p[0] = FIB_TABLE ((int) nfirst - 1);
+ fp[0] = FIB_TABLE (nfirst);
+ size = 1;
+
+ /* Skip to the end if the table lookup gives the final answer. */
+ if (mask != 1)
+ {
+ mp_size_t alloc;
+ mp_ptr xp;
+ TMP_DECL;
+
+ TMP_MARK;
+ alloc = MPN_FIB2_SIZE (n);
+ xp = TMP_ALLOC_LIMBS (alloc);
+
+ do
+ {
+ /* Here fp==F[k] and f1p==F[k-1], with k being the bits of n from
+ n&mask upwards.
+
+ The next bit of n is n&(mask>>1) and we'll double to the pair
+ fp==F[2k],f1p==F[2k-1] or fp==F[2k+1],f1p==F[2k], according as
+ that bit is 0 or 1 respectively. */
+
+ TRACE (printf ("k=%lu mask=0x%lX size=%ld alloc=%ld\n",
+ n >> refmpn_count_trailing_zeros(mask),
+ mask, size, alloc);
+ mpn_trace ("fp ", fp, size);
+ mpn_trace ("f1p", f1p, size));
+
+ /* fp normalized, f1p at most one high zero */
+ ASSERT (fp[size-1] != 0);
+ ASSERT (f1p[size-1] != 0 || f1p[size-2] != 0);
+
+ /* f1p[size-1] might be zero, but this occurs rarely, so it's not
+ worth bothering checking for it */
+ ASSERT (alloc >= 2*size);
+ mpn_sqr (xp, fp, size);
+ mpn_sqr (fp, f1p, size);
+ size *= 2;
+
+ /* Shrink if possible. Since fp was normalized there'll be at
+ most one high zero on xp (and if there is then there's one on
+ yp too). */
+ ASSERT (xp[size-1] != 0 || fp[size-1] == 0);
+ size -= (xp[size-1] == 0);
+ ASSERT (xp[size-1] != 0); /* only one xp high zero */
+
+ /* Calculate F[2k-1] = F[k]^2 + F[k-1]^2. */
+ f1p[size] = mpn_add_n (f1p, xp, fp, size);
+
+ /* Calculate F[2k+1] = 4*F[k]^2 - F[k-1]^2 + 2*(-1)^k.
+ n&mask is the low bit of our implied k. */
+#if HAVE_NATIVE_mpn_rsblsh2_n || HAVE_NATIVE_mpn_rsblsh_n
+#if HAVE_NATIVE_mpn_rsblsh2_n
+ fp[size] = mpn_rsblsh2_n (fp, fp, xp, size);
+#else /* HAVE_NATIVE_mpn_rsblsh_n */
+ fp[size] = mpn_rsblsh_n (fp, fp, xp, size, 2);
+#endif
+ if ((n & mask) == 0)
+ MPN_INCR_U(fp, size + 1, 2); /* possible +2 */
+ else
+ {
+ ASSERT (fp[0] >= 2);
+ fp[0] -= 2; /* possible -2 */
+ }
+#else
+ {
+ mp_limb_t c;
+
+ c = mpn_lshift (xp, xp, size, 2);
+ xp[0] |= (n & mask ? 0 : 2); /* possible +2 */
+ c -= mpn_sub_n (fp, xp, fp, size);
+ ASSERT (n & mask ? fp[0] != 0 && fp[0] != 1 : 1);
+ fp[0] -= (n & mask ? 2 : 0); /* possible -2 */
+ fp[size] = c;
+ }
+#endif
+ ASSERT (alloc >= size+1);
+ size += (fp[size] != 0);
+
+ /* now n&mask is the new bit of n being considered */
+ mask >>= 1;
+
+ /* Calculate F[2k] = F[2k+1] - F[2k-1], replacing the unwanted one of
+ F[2k+1] and F[2k-1]. */
+ if (n & mask)
+ ASSERT_NOCARRY (mpn_sub_n (f1p, fp, f1p, size));
+ else {
+ ASSERT_NOCARRY (mpn_sub_n ( fp, fp, f1p, size));
+
+ /* Can have a high zero after replacing F[2k+1] with F[2k].
+ f1p will have a high zero if fp does. */
+ ASSERT (fp[size-1] != 0 || f1p[size-1] == 0);
+ size -= (fp[size-1] == 0);
+ }
+ }
+ while (mask != 1);
+
+ TMP_FREE;
+ }
+
+ TRACE (printf ("done size=%ld\n", size);
+ mpn_trace ("fp ", fp, size);
+ mpn_trace ("f1p", f1p, size));
+
+ return size;
+}
diff --git a/gmp/mpn/generic/gcd.c b/gmp/mpn/generic/gcd.c
new file mode 100644
index 0000000000..b14e1ad888
--- /dev/null
+++ b/gmp/mpn/generic/gcd.c
@@ -0,0 +1,310 @@
+/* mpn/gcd.c: mpn_gcd for gcd of two odd integers.
+
+Copyright 1991, 1993-1998, 2000-2005, 2008, 2010, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Uses the HGCD operation described in
+
+ N. Möller, On Schönhage's algorithm and subquadratic integer gcd
+ computation, Math. Comp. 77 (2008), 589-607.
+
+ to reduce inputs until they are of size below GCD_DC_THRESHOLD, and
+ then uses Lehmer's algorithm.
+*/
+
+/* Some reasonable choices are n / 2 (same as in hgcd), and p = (n +
+ * 2)/3, which gives a balanced multiplication in
+ * mpn_hgcd_matrix_adjust. However, p = 2 n/3 gives slightly better
+ * performance. The matrix-vector multiplication is then
+ * 4:1-unbalanced, with matrix elements of size n/6, and vector
+ * elements of size p = 2n/3. */
+
+/* From analysis of the theoretical running time, it appears that when
+ * multiplication takes time O(n^alpha), p should be chosen so that
+ * the ratio of the time for the mpn_hgcd call, and the time for the
+ * multiplication in mpn_hgcd_matrix_adjust, is roughly 1/(alpha -
+ * 1). */
+#ifdef TUNE_GCD_P
+#define P_TABLE_SIZE 10000
+mp_size_t p_table[P_TABLE_SIZE];
+#define CHOOSE_P(n) ( (n) < P_TABLE_SIZE ? p_table[n] : 2*(n)/3)
+#else
+#define CHOOSE_P(n) (2*(n) / 3)
+#endif
+
+struct gcd_ctx
+{
+ mp_ptr gp;
+ mp_size_t gn;
+};
+
+static void
+gcd_hook (void *p, mp_srcptr gp, mp_size_t gn,
+ mp_srcptr qp, mp_size_t qn, int d)
+{
+ struct gcd_ctx *ctx = (struct gcd_ctx *) p;
+ MPN_COPY (ctx->gp, gp, gn);
+ ctx->gn = gn;
+}
+
+#if GMP_NAIL_BITS > 0
+/* Nail supports should be easy, replacing the sub_ddmmss with nails
+ * logic. */
+#error Nails not supported.
+#endif
+
+/* Use binary algorithm to compute G <-- GCD (U, V) for usize, vsize == 2.
+ Both U and V must be odd. */
+static inline mp_size_t
+gcd_2 (mp_ptr gp, mp_srcptr up, mp_srcptr vp)
+{
+ mp_limb_t u0, u1, v0, v1;
+ mp_size_t gn;
+
+ u0 = up[0];
+ u1 = up[1];
+ v0 = vp[0];
+ v1 = vp[1];
+
+ ASSERT (u0 & 1);
+ ASSERT (v0 & 1);
+
+ /* Check for u0 != v0 needed to ensure that argument to
+ * count_trailing_zeros is non-zero. */
+ while (u1 != v1 && u0 != v0)
+ {
+ unsigned long int r;
+ if (u1 > v1)
+ {
+ sub_ddmmss (u1, u0, u1, u0, v1, v0);
+ count_trailing_zeros (r, u0);
+ u0 = ((u1 << (GMP_NUMB_BITS - r)) & GMP_NUMB_MASK) | (u0 >> r);
+ u1 >>= r;
+ }
+ else /* u1 < v1. */
+ {
+ sub_ddmmss (v1, v0, v1, v0, u1, u0);
+ count_trailing_zeros (r, v0);
+ v0 = ((v1 << (GMP_NUMB_BITS - r)) & GMP_NUMB_MASK) | (v0 >> r);
+ v1 >>= r;
+ }
+ }
+
+ gp[0] = u0, gp[1] = u1, gn = 1 + (u1 != 0);
+
+ /* If U == V == GCD, done. Otherwise, compute GCD (V, |U - V|). */
+ if (u1 == v1 && u0 == v0)
+ return gn;
+
+ v0 = (u0 == v0) ? ((u1 > v1) ? u1-v1 : v1-u1) : ((u0 > v0) ? u0-v0 : v0-u0);
+ gp[0] = mpn_gcd_1 (gp, gn, v0);
+
+ return 1;
+}
+
+mp_size_t
+mpn_gcd (mp_ptr gp, mp_ptr up, mp_size_t usize, mp_ptr vp, mp_size_t n)
+{
+ mp_size_t talloc;
+ mp_size_t scratch;
+ mp_size_t matrix_scratch;
+
+ struct gcd_ctx ctx;
+ mp_ptr tp;
+ TMP_DECL;
+
+ ASSERT (usize >= n);
+ ASSERT (n > 0);
+ ASSERT (vp[n-1] > 0);
+
+ /* FIXME: Check for small sizes first, before setting up temporary
+ storage etc. */
+ talloc = MPN_GCD_SUBDIV_STEP_ITCH(n);
+
+ /* For initial division */
+ scratch = usize - n + 1;
+ if (scratch > talloc)
+ talloc = scratch;
+
+#if TUNE_GCD_P
+ if (CHOOSE_P (n) > 0)
+#else
+ if (ABOVE_THRESHOLD (n, GCD_DC_THRESHOLD))
+#endif
+ {
+ mp_size_t hgcd_scratch;
+ mp_size_t update_scratch;
+ mp_size_t p = CHOOSE_P (n);
+ mp_size_t scratch;
+#if TUNE_GCD_P
+ /* Worst case, since we don't guarantee that n - CHOOSE_P(n)
+ is increasing */
+ matrix_scratch = MPN_HGCD_MATRIX_INIT_ITCH (n);
+ hgcd_scratch = mpn_hgcd_itch (n);
+ update_scratch = 2*(n - 1);
+#else
+ matrix_scratch = MPN_HGCD_MATRIX_INIT_ITCH (n - p);
+ hgcd_scratch = mpn_hgcd_itch (n - p);
+ update_scratch = p + n - 1;
+#endif
+ scratch = matrix_scratch + MAX(hgcd_scratch, update_scratch);
+ if (scratch > talloc)
+ talloc = scratch;
+ }
+
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS(talloc);
+
+ if (usize > n)
+ {
+ mpn_tdiv_qr (tp, up, 0, up, usize, vp, n);
+
+ if (mpn_zero_p (up, n))
+ {
+ MPN_COPY (gp, vp, n);
+ ctx.gn = n;
+ goto done;
+ }
+ }
+
+ ctx.gp = gp;
+
+#if TUNE_GCD_P
+ while (CHOOSE_P (n) > 0)
+#else
+ while (ABOVE_THRESHOLD (n, GCD_DC_THRESHOLD))
+#endif
+ {
+ struct hgcd_matrix M;
+ mp_size_t p = CHOOSE_P (n);
+ mp_size_t matrix_scratch = MPN_HGCD_MATRIX_INIT_ITCH (n - p);
+ mp_size_t nn;
+ mpn_hgcd_matrix_init (&M, n - p, tp);
+ nn = mpn_hgcd (up + p, vp + p, n - p, &M, tp + matrix_scratch);
+ if (nn > 0)
+ {
+ ASSERT (M.n <= (n - p - 1)/2);
+ ASSERT (M.n + p <= (p + n - 1) / 2);
+ /* Temporary storage 2 (p + M->n) <= p + n - 1. */
+ n = mpn_hgcd_matrix_adjust (&M, p + nn, up, vp, p, tp + matrix_scratch);
+ }
+ else
+ {
+ /* Temporary storage n */
+ n = mpn_gcd_subdiv_step (up, vp, n, 0, gcd_hook, &ctx, tp);
+ if (n == 0)
+ goto done;
+ }
+ }
+
+ while (n > 2)
+ {
+ struct hgcd_matrix1 M;
+ mp_limb_t uh, ul, vh, vl;
+ mp_limb_t mask;
+
+ mask = up[n-1] | vp[n-1];
+ ASSERT (mask > 0);
+
+ if (mask & GMP_NUMB_HIGHBIT)
+ {
+ uh = up[n-1]; ul = up[n-2];
+ vh = vp[n-1]; vl = vp[n-2];
+ }
+ else
+ {
+ int shift;
+
+ count_leading_zeros (shift, mask);
+ uh = MPN_EXTRACT_NUMB (shift, up[n-1], up[n-2]);
+ ul = MPN_EXTRACT_NUMB (shift, up[n-2], up[n-3]);
+ vh = MPN_EXTRACT_NUMB (shift, vp[n-1], vp[n-2]);
+ vl = MPN_EXTRACT_NUMB (shift, vp[n-2], vp[n-3]);
+ }
+
+ /* Try an mpn_hgcd2 step */
+ if (mpn_hgcd2 (uh, ul, vh, vl, &M))
+ {
+ n = mpn_matrix22_mul1_inverse_vector (&M, tp, up, vp, n);
+ MP_PTR_SWAP (up, tp);
+ }
+ else
+ {
+ /* mpn_hgcd2 has failed. Then either one of a or b is very
+ small, or the difference is very small. Perform one
+ subtraction followed by one division. */
+
+ /* Temporary storage n */
+ n = mpn_gcd_subdiv_step (up, vp, n, 0, &gcd_hook, &ctx, tp);
+ if (n == 0)
+ goto done;
+ }
+ }
+
+ ASSERT(up[n-1] | vp[n-1]);
+
+ if (n == 1)
+ {
+ *gp = mpn_gcd_1(up, 1, vp[0]);
+ ctx.gn = 1;
+ goto done;
+ }
+
+ /* Due to the calling convention for mpn_gcd, at most one can be
+ even. */
+
+ if (! (up[0] & 1))
+ MP_PTR_SWAP (up, vp);
+
+ ASSERT (up[0] & 1);
+
+ if (vp[0] == 0)
+ {
+ *gp = mpn_gcd_1 (up, 2, vp[1]);
+ ctx.gn = 1;
+ goto done;
+ }
+ else if (! (vp[0] & 1))
+ {
+ int r;
+ count_trailing_zeros (r, vp[0]);
+ vp[0] = ((vp[1] << (GMP_NUMB_BITS - r)) & GMP_NUMB_MASK) | (vp[0] >> r);
+ vp[1] >>= r;
+ }
+
+ ctx.gn = gcd_2(gp, up, vp);
+
+done:
+ TMP_FREE;
+ return ctx.gn;
+}
diff --git a/gmp/mpn/generic/gcd_1.c b/gmp/mpn/generic/gcd_1.c
new file mode 100644
index 0000000000..f6dcb4a2eb
--- /dev/null
+++ b/gmp/mpn/generic/gcd_1.c
@@ -0,0 +1,199 @@
+/* mpn_gcd_1 -- mpn and limb greatest common divisor.
+
+Copyright 1994, 1996, 2000, 2001, 2009, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef GCD_1_METHOD
+#define GCD_1_METHOD 2
+#endif
+
+#define USE_ZEROTAB 0
+
+#if USE_ZEROTAB
+#define MAXSHIFT 4
+#define MASK ((1 << MAXSHIFT) - 1)
+static const unsigned char zerotab[1 << MAXSHIFT] =
+{
+#if MAXSHIFT > 4
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+#endif
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+#endif
+
+/* Does not work for U == 0 or V == 0. It would be tough to make it work for
+ V == 0 since gcd(x,0) = x, and U does not generally fit in an mp_limb_t.
+
+ The threshold for doing u%v when size==1 will vary by CPU according to
+ the speed of a division and the code generated for the main loop. Any
+ tuning for this is left to a CPU specific implementation. */
+
+mp_limb_t
+mpn_gcd_1 (mp_srcptr up, mp_size_t size, mp_limb_t vlimb)
+{
+ mp_limb_t ulimb;
+ unsigned long zero_bits, u_low_zero_bits;
+
+ ASSERT (size >= 1);
+ ASSERT (vlimb != 0);
+ ASSERT_MPN_NONZERO_P (up, size);
+
+ ulimb = up[0];
+
+ /* Need vlimb odd for modexact, want it odd to get common zeros. */
+ count_trailing_zeros (zero_bits, vlimb);
+ vlimb >>= zero_bits;
+
+ if (size > 1)
+ {
+ /* Must get common zeros before the mod reduction. If ulimb==0 then
+ vlimb already gives the common zeros. */
+ if (ulimb != 0)
+ {
+ count_trailing_zeros (u_low_zero_bits, ulimb);
+ zero_bits = MIN (zero_bits, u_low_zero_bits);
+ }
+
+ ulimb = MPN_MOD_OR_MODEXACT_1_ODD (up, size, vlimb);
+ if (ulimb == 0)
+ goto done;
+
+ goto strip_u_maybe;
+ }
+
+ /* size==1, so up[0]!=0 */
+ count_trailing_zeros (u_low_zero_bits, ulimb);
+ ulimb >>= u_low_zero_bits;
+ zero_bits = MIN (zero_bits, u_low_zero_bits);
+
+ /* make u bigger */
+ if (vlimb > ulimb)
+ MP_LIMB_T_SWAP (ulimb, vlimb);
+
+ /* if u is much bigger than v, reduce using a division rather than
+ chipping away at it bit-by-bit */
+ if ((ulimb >> 16) > vlimb)
+ {
+ ulimb %= vlimb;
+ if (ulimb == 0)
+ goto done;
+ goto strip_u_maybe;
+ }
+
+ ASSERT (ulimb & 1);
+ ASSERT (vlimb & 1);
+
+#if GCD_1_METHOD == 1
+ while (ulimb != vlimb)
+ {
+ ASSERT (ulimb & 1);
+ ASSERT (vlimb & 1);
+
+ if (ulimb > vlimb)
+ {
+ ulimb -= vlimb;
+ do
+ {
+ ulimb >>= 1;
+ ASSERT (ulimb != 0);
+ strip_u_maybe:
+ ;
+ }
+ while ((ulimb & 1) == 0);
+ }
+ else /* vlimb > ulimb. */
+ {
+ vlimb -= ulimb;
+ do
+ {
+ vlimb >>= 1;
+ ASSERT (vlimb != 0);
+ }
+ while ((vlimb & 1) == 0);
+ }
+ }
+#else
+# if GCD_1_METHOD == 2
+
+ ulimb >>= 1;
+ vlimb >>= 1;
+
+ while (ulimb != vlimb)
+ {
+ int c;
+ mp_limb_t t;
+ mp_limb_t vgtu;
+
+ t = ulimb - vlimb;
+ vgtu = LIMB_HIGHBIT_TO_MASK (t);
+
+ /* v <-- min (u, v) */
+ vlimb += (vgtu & t);
+
+ /* u <-- |u - v| */
+ ulimb = (t ^ vgtu) - vgtu;
+
+#if USE_ZEROTAB
+ /* Number of trailing zeros is the same no matter if we look at
+ * t or ulimb, but using t gives more parallelism. */
+ c = zerotab[t & MASK];
+
+ while (UNLIKELY (c == MAXSHIFT))
+ {
+ ulimb >>= MAXSHIFT;
+ if (0)
+ strip_u_maybe:
+ vlimb >>= 1;
+
+ c = zerotab[ulimb & MASK];
+ }
+#else
+ if (0)
+ {
+ strip_u_maybe:
+ vlimb >>= 1;
+ t = ulimb;
+ }
+ count_trailing_zeros (c, t);
+#endif
+ ulimb >>= (c + 1);
+ }
+
+ vlimb = (vlimb << 1) | 1;
+# else
+# error Unknown GCD_1_METHOD
+# endif
+#endif
+
+ done:
+ return vlimb << zero_bits;
+}
diff --git a/gmp/mpn/generic/gcd_subdiv_step.c b/gmp/mpn/generic/gcd_subdiv_step.c
new file mode 100644
index 0000000000..18634bec9f
--- /dev/null
+++ b/gmp/mpn/generic/gcd_subdiv_step.c
@@ -0,0 +1,205 @@
+/* gcd_subdiv_step.c.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2003-2005, 2008, 2010, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h> /* for NULL */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Used when mpn_hgcd or mpn_hgcd2 has failed. Then either one of a or
+ b is small, or the difference is small. Perform one subtraction
+ followed by one division. The normal case is to compute the reduced
+ a and b, and return the new size.
+
+ If s == 0 (used for gcd and gcdext), returns zero if the gcd is
+ found.
+
+ If s > 0, don't reduce to size <= s, and return zero if no
+ reduction is possible (if either a, b or |a-b| is of size <= s). */
+
+/* The hook function is called as
+
+ hook(ctx, gp, gn, qp, qn, d)
+
+ in the following cases:
+
+ + If A = B at the start, G is the gcd, Q is NULL, d = -1.
+
+ + If one input is zero at the start, G is the gcd, Q is NULL,
+ d = 0 if A = G and d = 1 if B = G.
+
+ Otherwise, if d = 0 we have just subtracted a multiple of A from B,
+ and if d = 1 we have subtracted a multiple of B from A.
+
+ + If A = B after subtraction, G is the gcd, Q is NULL.
+
+ + If we get a zero remainder after division, G is the gcd, Q is the
+ quotient.
+
+ + Otherwise, G is NULL, Q is the quotient (often 1).
+
+ */
+
+mp_size_t
+mpn_gcd_subdiv_step (mp_ptr ap, mp_ptr bp, mp_size_t n, mp_size_t s,
+ gcd_subdiv_step_hook *hook, void *ctx,
+ mp_ptr tp)
+{
+ static const mp_limb_t one = CNST_LIMB(1);
+ mp_size_t an, bn, qn;
+
+ int swapped;
+
+ ASSERT (n > 0);
+ ASSERT (ap[n-1] > 0 || bp[n-1] > 0);
+
+ an = bn = n;
+ MPN_NORMALIZE (ap, an);
+ MPN_NORMALIZE (bp, bn);
+
+ swapped = 0;
+
+ /* Arrange so that a < b, subtract b -= a, and maintain
+ normalization. */
+ if (an == bn)
+ {
+ int c;
+ MPN_CMP (c, ap, bp, an);
+ if (UNLIKELY (c == 0))
+ {
+ /* For gcdext, return the smallest of the two cofactors, so
+ pass d = -1. */
+ if (s == 0)
+ hook (ctx, ap, an, NULL, 0, -1);
+ return 0;
+ }
+ else if (c > 0)
+ {
+ MP_PTR_SWAP (ap, bp);
+ swapped ^= 1;
+ }
+ }
+ else
+ {
+ if (an > bn)
+ {
+ MPN_PTR_SWAP (ap, an, bp, bn);
+ swapped ^= 1;
+ }
+ }
+ if (an <= s)
+ {
+ if (s == 0)
+ hook (ctx, bp, bn, NULL, 0, swapped ^ 1);
+ return 0;
+ }
+
+ ASSERT_NOCARRY (mpn_sub (bp, bp, bn, ap, an));
+ MPN_NORMALIZE (bp, bn);
+ ASSERT (bn > 0);
+
+ if (bn <= s)
+ {
+ /* Undo subtraction. */
+ mp_limb_t cy = mpn_add (bp, ap, an, bp, bn);
+ if (cy > 0)
+ bp[an] = cy;
+ return 0;
+ }
+
+ /* Arrange so that a < b */
+ if (an == bn)
+ {
+ int c;
+ MPN_CMP (c, ap, bp, an);
+ if (UNLIKELY (c == 0))
+ {
+ if (s > 0)
+ /* Just record subtraction and return */
+ hook (ctx, NULL, 0, &one, 1, swapped);
+ else
+ /* Found gcd. */
+ hook (ctx, bp, bn, NULL, 0, swapped);
+ return 0;
+ }
+
+ hook (ctx, NULL, 0, &one, 1, swapped);
+
+ if (c > 0)
+ {
+ MP_PTR_SWAP (ap, bp);
+ swapped ^= 1;
+ }
+ }
+ else
+ {
+ hook (ctx, NULL, 0, &one, 1, swapped);
+
+ if (an > bn)
+ {
+ MPN_PTR_SWAP (ap, an, bp, bn);
+ swapped ^= 1;
+ }
+ }
+
+ mpn_tdiv_qr (tp, bp, 0, bp, bn, ap, an);
+ qn = bn - an + 1;
+ bn = an;
+ MPN_NORMALIZE (bp, bn);
+
+ if (UNLIKELY (bn <= s))
+ {
+ if (s == 0)
+ {
+ hook (ctx, ap, an, tp, qn, swapped);
+ return 0;
+ }
+
+ /* Quotient is one too large, so decrement it and add back A. */
+ if (bn > 0)
+ {
+ mp_limb_t cy = mpn_add (bp, ap, an, bp, bn);
+ if (cy)
+ bp[an++] = cy;
+ }
+ else
+ MPN_COPY (bp, ap, an);
+
+ MPN_DECR_U (tp, qn, 1);
+ }
+
+ hook (ctx, NULL, 0, tp, qn, swapped);
+ return an;
+}
diff --git a/gmp/mpn/generic/gcdext.c b/gmp/mpn/generic/gcdext.c
new file mode 100644
index 0000000000..1c4ff75aab
--- /dev/null
+++ b/gmp/mpn/generic/gcdext.c
@@ -0,0 +1,558 @@
+/* mpn_gcdext -- Extended Greatest Common Divisor.
+
+Copyright 1996, 1998, 2000-2005, 2008, 2009, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Computes (r;b) = (a; b) M. Result is of size n + M->n +/- 1, and
+ the size is returned (if inputs are non-normalized, result may be
+ non-normalized too). Temporary space needed is M->n + n.
+ */
+static size_t
+hgcd_mul_matrix_vector (struct hgcd_matrix *M,
+ mp_ptr rp, mp_srcptr ap, mp_ptr bp, mp_size_t n, mp_ptr tp)
+{
+ mp_limb_t ah, bh;
+
+ /* Compute (r,b) <-- (u00 a + u10 b, u01 a + u11 b) as
+
+ t = u00 * a
+ r = u10 * b
+ r += t;
+
+ t = u11 * b
+ b = u01 * a
+ b += t;
+ */
+
+ if (M->n >= n)
+ {
+ mpn_mul (tp, M->p[0][0], M->n, ap, n);
+ mpn_mul (rp, M->p[1][0], M->n, bp, n);
+ }
+ else
+ {
+ mpn_mul (tp, ap, n, M->p[0][0], M->n);
+ mpn_mul (rp, bp, n, M->p[1][0], M->n);
+ }
+
+ ah = mpn_add_n (rp, rp, tp, n + M->n);
+
+ if (M->n >= n)
+ {
+ mpn_mul (tp, M->p[1][1], M->n, bp, n);
+ mpn_mul (bp, M->p[0][1], M->n, ap, n);
+ }
+ else
+ {
+ mpn_mul (tp, bp, n, M->p[1][1], M->n);
+ mpn_mul (bp, ap, n, M->p[0][1], M->n);
+ }
+ bh = mpn_add_n (bp, bp, tp, n + M->n);
+
+ n += M->n;
+ if ( (ah | bh) > 0)
+ {
+ rp[n] = ah;
+ bp[n] = bh;
+ n++;
+ }
+ else
+ {
+ /* Normalize */
+ while ( (rp[n-1] | bp[n-1]) == 0)
+ n--;
+ }
+
+ return n;
+}
+
+#define COMPUTE_V_ITCH(n) (2*(n))
+
+/* Computes |v| = |(g - u a)| / b, where u may be positive or
+ negative, and v is of the opposite sign. max(a, b) is of size n, u and
+ v at most size n, and v must have space for n+1 limbs. */
+static mp_size_t
+compute_v (mp_ptr vp,
+ mp_srcptr ap, mp_srcptr bp, mp_size_t n,
+ mp_srcptr gp, mp_size_t gn,
+ mp_srcptr up, mp_size_t usize,
+ mp_ptr tp)
+{
+ mp_size_t size;
+ mp_size_t an;
+ mp_size_t bn;
+ mp_size_t vn;
+
+ ASSERT (n > 0);
+ ASSERT (gn > 0);
+ ASSERT (usize != 0);
+
+ size = ABS (usize);
+ ASSERT (size <= n);
+ ASSERT (up[size-1] > 0);
+
+ an = n;
+ MPN_NORMALIZE (ap, an);
+ ASSERT (gn <= an);
+
+ if (an >= size)
+ mpn_mul (tp, ap, an, up, size);
+ else
+ mpn_mul (tp, up, size, ap, an);
+
+ size += an;
+
+ if (usize > 0)
+ {
+ /* |v| = -v = (u a - g) / b */
+
+ ASSERT_NOCARRY (mpn_sub (tp, tp, size, gp, gn));
+ MPN_NORMALIZE (tp, size);
+ if (size == 0)
+ return 0;
+ }
+ else
+ { /* |v| = v = (g - u a) / b = (g + |u| a) / b. Since g <= a,
+ (g + |u| a) always fits in (|usize| + an) limbs. */
+
+ ASSERT_NOCARRY (mpn_add (tp, tp, size, gp, gn));
+ size -= (tp[size - 1] == 0);
+ }
+
+ /* Now divide t / b. There must be no remainder */
+ bn = n;
+ MPN_NORMALIZE (bp, bn);
+ ASSERT (size >= bn);
+
+ vn = size + 1 - bn;
+ ASSERT (vn <= n + 1);
+
+ mpn_divexact (vp, tp, size, bp, bn);
+ vn -= (vp[vn-1] == 0);
+
+ return vn;
+}
+
+/* Temporary storage:
+
+ Initial division: Quotient of at most an - n + 1 <= an limbs.
+
+ Storage for u0 and u1: 2(n+1).
+
+ Storage for hgcd matrix M, with input ceil(n/2): 5 * ceil(n/4)
+
+ Storage for hgcd, input (n + 1)/2: 9 n/4 plus some.
+
+ When hgcd succeeds: 1 + floor(3n/2) for adjusting a and b, and 2(n+1) for the cofactors.
+
+ When hgcd fails: 2n + 1 for mpn_gcdext_subdiv_step, which is less.
+
+ For the lehmer call after the loop, Let T denote
+ GCDEXT_DC_THRESHOLD. For the gcdext_lehmer call, we need T each for
+ u, a and b, and 4T+3 scratch space. Next, for compute_v, we need T
+ for u, T+1 for v and 2T scratch space. In all, 7T + 3 is
+ sufficient for both operations.
+
+*/
+
+/* Optimal choice of p seems difficult. In each iteration the division
+ * of work between hgcd and the updates of u0 and u1 depends on the
+ * current size of the u. It may be desirable to use a different
+ * choice of p in each iteration. Also the input size seems to matter;
+ * choosing p = n / 3 in the first iteration seems to improve
+ * performance slightly for input size just above the threshold, but
+ * degrade performance for larger inputs. */
+#define CHOOSE_P_1(n) ((n) / 2)
+#define CHOOSE_P_2(n) ((n) / 3)
+
+mp_size_t
+mpn_gcdext (mp_ptr gp, mp_ptr up, mp_size_t *usizep,
+ mp_ptr ap, mp_size_t an, mp_ptr bp, mp_size_t n)
+{
+ mp_size_t talloc;
+ mp_size_t scratch;
+ mp_size_t matrix_scratch;
+ mp_size_t ualloc = n + 1;
+
+ struct gcdext_ctx ctx;
+ mp_size_t un;
+ mp_ptr u0;
+ mp_ptr u1;
+
+ mp_ptr tp;
+
+ TMP_DECL;
+
+ ASSERT (an >= n);
+ ASSERT (n > 0);
+ ASSERT (bp[n-1] > 0);
+
+ TMP_MARK;
+
+ /* FIXME: Check for small sizes first, before setting up temporary
+ storage etc. */
+ talloc = MPN_GCDEXT_LEHMER_N_ITCH(n);
+
+ /* For initial division */
+ scratch = an - n + 1;
+ if (scratch > talloc)
+ talloc = scratch;
+
+ if (ABOVE_THRESHOLD (n, GCDEXT_DC_THRESHOLD))
+ {
+ /* For hgcd loop. */
+ mp_size_t hgcd_scratch;
+ mp_size_t update_scratch;
+ mp_size_t p1 = CHOOSE_P_1 (n);
+ mp_size_t p2 = CHOOSE_P_2 (n);
+ mp_size_t min_p = MIN(p1, p2);
+ mp_size_t max_p = MAX(p1, p2);
+ matrix_scratch = MPN_HGCD_MATRIX_INIT_ITCH (n - min_p);
+ hgcd_scratch = mpn_hgcd_itch (n - min_p);
+ update_scratch = max_p + n - 1;
+
+ scratch = matrix_scratch + MAX(hgcd_scratch, update_scratch);
+ if (scratch > talloc)
+ talloc = scratch;
+
+ /* Final mpn_gcdext_lehmer_n call. Need space for u and for
+ copies of a and b. */
+ scratch = MPN_GCDEXT_LEHMER_N_ITCH (GCDEXT_DC_THRESHOLD)
+ + 3*GCDEXT_DC_THRESHOLD;
+
+ if (scratch > talloc)
+ talloc = scratch;
+
+ /* Cofactors u0 and u1 */
+ talloc += 2*(n+1);
+ }
+
+ tp = TMP_ALLOC_LIMBS(talloc);
+
+ if (an > n)
+ {
+ mpn_tdiv_qr (tp, ap, 0, ap, an, bp, n);
+
+ if (mpn_zero_p (ap, n))
+ {
+ MPN_COPY (gp, bp, n);
+ *usizep = 0;
+ TMP_FREE;
+ return n;
+ }
+ }
+
+ if (BELOW_THRESHOLD (n, GCDEXT_DC_THRESHOLD))
+ {
+ mp_size_t gn = mpn_gcdext_lehmer_n(gp, up, usizep, ap, bp, n, tp);
+
+ TMP_FREE;
+ return gn;
+ }
+
+ MPN_ZERO (tp, 2*ualloc);
+ u0 = tp; tp += ualloc;
+ u1 = tp; tp += ualloc;
+
+ ctx.gp = gp;
+ ctx.up = up;
+ ctx.usize = usizep;
+
+ {
+ /* For the first hgcd call, there are no u updates, and it makes
+ some sense to use a different choice for p. */
+
+ /* FIXME: We could trim use of temporary storage, since u0 and u1
+ are not used yet. For the hgcd call, we could swap in the u0
+ and u1 pointers for the relevant matrix elements. */
+
+ struct hgcd_matrix M;
+ mp_size_t p = CHOOSE_P_1 (n);
+ mp_size_t nn;
+
+ mpn_hgcd_matrix_init (&M, n - p, tp);
+ nn = mpn_hgcd (ap + p, bp + p, n - p, &M, tp + matrix_scratch);
+ if (nn > 0)
+ {
+ ASSERT (M.n <= (n - p - 1)/2);
+ ASSERT (M.n + p <= (p + n - 1) / 2);
+
+ /* Temporary storage 2 (p + M->n) <= p + n - 1 */
+ n = mpn_hgcd_matrix_adjust (&M, p + nn, ap, bp, p, tp + matrix_scratch);
+
+ MPN_COPY (u0, M.p[1][0], M.n);
+ MPN_COPY (u1, M.p[1][1], M.n);
+ un = M.n;
+ while ( (u0[un-1] | u1[un-1] ) == 0)
+ un--;
+ }
+ else
+ {
+ /* mpn_hgcd has failed. Then either one of a or b is very
+ small, or the difference is very small. Perform one
+ subtraction followed by one division. */
+ u1[0] = 1;
+
+ ctx.u0 = u0;
+ ctx.u1 = u1;
+ ctx.tp = tp + n; /* ualloc */
+ ctx.un = 1;
+
+ /* Temporary storage n */
+ n = mpn_gcd_subdiv_step (ap, bp, n, 0, mpn_gcdext_hook, &ctx, tp);
+ if (n == 0)
+ {
+ TMP_FREE;
+ return ctx.gn;
+ }
+
+ un = ctx.un;
+ ASSERT (un < ualloc);
+ }
+ }
+
+ while (ABOVE_THRESHOLD (n, GCDEXT_DC_THRESHOLD))
+ {
+ struct hgcd_matrix M;
+ mp_size_t p = CHOOSE_P_2 (n);
+ mp_size_t nn;
+
+ mpn_hgcd_matrix_init (&M, n - p, tp);
+ nn = mpn_hgcd (ap + p, bp + p, n - p, &M, tp + matrix_scratch);
+ if (nn > 0)
+ {
+ mp_ptr t0;
+
+ t0 = tp + matrix_scratch;
+ ASSERT (M.n <= (n - p - 1)/2);
+ ASSERT (M.n + p <= (p + n - 1) / 2);
+
+ /* Temporary storage 2 (p + M->n) <= p + n - 1 */
+ n = mpn_hgcd_matrix_adjust (&M, p + nn, ap, bp, p, t0);
+
+ /* By the same analysis as for mpn_hgcd_matrix_mul */
+ ASSERT (M.n + un <= ualloc);
+
+ /* FIXME: This copying could be avoided by some swapping of
+ * pointers. May need more temporary storage, though. */
+ MPN_COPY (t0, u0, un);
+
+ /* Temporary storage ualloc */
+ un = hgcd_mul_matrix_vector (&M, u0, t0, u1, un, t0 + un);
+
+ ASSERT (un < ualloc);
+ ASSERT ( (u0[un-1] | u1[un-1]) > 0);
+ }
+ else
+ {
+ /* mpn_hgcd has failed. Then either one of a or b is very
+ small, or the difference is very small. Perform one
+ subtraction followed by one division. */
+ ctx.u0 = u0;
+ ctx.u1 = u1;
+ ctx.tp = tp + n; /* ualloc */
+ ctx.un = un;
+
+ /* Temporary storage n */
+ n = mpn_gcd_subdiv_step (ap, bp, n, 0, mpn_gcdext_hook, &ctx, tp);
+ if (n == 0)
+ {
+ TMP_FREE;
+ return ctx.gn;
+ }
+
+ un = ctx.un;
+ ASSERT (un < ualloc);
+ }
+ }
+ /* We have A = ... a + ... b
+ B = u0 a + u1 b
+
+ a = u1 A + ... B
+ b = -u0 A + ... B
+
+ with bounds
+
+ |u0|, |u1| <= B / min(a, b)
+
+ We always have u1 > 0, and u0 == 0 is possible only if u1 == 1,
+ in which case the only reduction done so far is a = A - k B for
+ some k.
+
+ Compute g = u a + v b = (u u1 - v u0) A + (...) B
+ Here, u, v are bounded by
+
+ |u| <= b,
+ |v| <= a
+ */
+
+ ASSERT ( (ap[n-1] | bp[n-1]) > 0);
+
+ if (UNLIKELY (mpn_cmp (ap, bp, n) == 0))
+ {
+ /* Must return the smallest cofactor, +u1 or -u0 */
+ int c;
+
+ MPN_COPY (gp, ap, n);
+
+ MPN_CMP (c, u0, u1, un);
+ /* c == 0 can happen only when A = (2k+1) G, B = 2 G. And in
+ this case we choose the cofactor + 1, corresponding to G = A
+ - k B, rather than -1, corresponding to G = - A + (k+1) B. */
+ ASSERT (c != 0 || (un == 1 && u0[0] == 1 && u1[0] == 1));
+ if (c < 0)
+ {
+ MPN_NORMALIZE (u0, un);
+ MPN_COPY (up, u0, un);
+ *usizep = -un;
+ }
+ else
+ {
+ MPN_NORMALIZE_NOT_ZERO (u1, un);
+ MPN_COPY (up, u1, un);
+ *usizep = un;
+ }
+
+ TMP_FREE;
+ return n;
+ }
+ else if (UNLIKELY (u0[0] == 0) && un == 1)
+ {
+ mp_size_t gn;
+ ASSERT (u1[0] == 1);
+
+ /* g = u a + v b = (u u1 - v u0) A + (...) B = u A + (...) B */
+ gn = mpn_gcdext_lehmer_n (gp, up, usizep, ap, bp, n, tp);
+
+ TMP_FREE;
+ return gn;
+ }
+ else
+ {
+ mp_size_t u0n;
+ mp_size_t u1n;
+ mp_size_t lehmer_un;
+ mp_size_t lehmer_vn;
+ mp_size_t gn;
+
+ mp_ptr lehmer_up;
+ mp_ptr lehmer_vp;
+ int negate;
+
+ lehmer_up = tp; tp += n;
+
+ /* Call mpn_gcdext_lehmer_n with copies of a and b. */
+ MPN_COPY (tp, ap, n);
+ MPN_COPY (tp + n, bp, n);
+ gn = mpn_gcdext_lehmer_n (gp, lehmer_up, &lehmer_un, tp, tp + n, n, tp + 2*n);
+
+ u0n = un;
+ MPN_NORMALIZE (u0, u0n);
+ ASSERT (u0n > 0);
+
+ if (lehmer_un == 0)
+ {
+ /* u == 0 ==> v = g / b == 1 ==> g = - u0 A + (...) B */
+ MPN_COPY (up, u0, u0n);
+ *usizep = -u0n;
+
+ TMP_FREE;
+ return gn;
+ }
+
+ lehmer_vp = tp;
+ /* Compute v = (g - u a) / b */
+ lehmer_vn = compute_v (lehmer_vp,
+ ap, bp, n, gp, gn, lehmer_up, lehmer_un, tp + n + 1);
+
+ if (lehmer_un > 0)
+ negate = 0;
+ else
+ {
+ lehmer_un = -lehmer_un;
+ negate = 1;
+ }
+
+ u1n = un;
+ MPN_NORMALIZE (u1, u1n);
+ ASSERT (u1n > 0);
+
+ ASSERT (lehmer_un + u1n <= ualloc);
+ ASSERT (lehmer_vn + u0n <= ualloc);
+
+ /* We may still have v == 0 */
+
+ /* Compute u u0 */
+ if (lehmer_un <= u1n)
+ /* Should be the common case */
+ mpn_mul (up, u1, u1n, lehmer_up, lehmer_un);
+ else
+ mpn_mul (up, lehmer_up, lehmer_un, u1, u1n);
+
+ un = u1n + lehmer_un;
+ un -= (up[un - 1] == 0);
+
+ if (lehmer_vn > 0)
+ {
+ mp_limb_t cy;
+
+ /* Overwrites old u1 value */
+ if (lehmer_vn <= u0n)
+ /* Should be the common case */
+ mpn_mul (u1, u0, u0n, lehmer_vp, lehmer_vn);
+ else
+ mpn_mul (u1, lehmer_vp, lehmer_vn, u0, u0n);
+
+ u1n = u0n + lehmer_vn;
+ u1n -= (u1[u1n - 1] == 0);
+
+ if (u1n <= un)
+ {
+ cy = mpn_add (up, up, un, u1, u1n);
+ }
+ else
+ {
+ cy = mpn_add (up, u1, u1n, up, un);
+ un = u1n;
+ }
+ up[un] = cy;
+ un += (cy != 0);
+
+ ASSERT (un < ualloc);
+ }
+ *usizep = negate ? -un : un;
+
+ TMP_FREE;
+ return gn;
+ }
+}
diff --git a/gmp/mpn/generic/gcdext_1.c b/gmp/mpn/generic/gcdext_1.c
new file mode 100644
index 0000000000..ea46cceb72
--- /dev/null
+++ b/gmp/mpn/generic/gcdext_1.c
@@ -0,0 +1,328 @@
+/* mpn_gcdext -- Extended Greatest Common Divisor.
+
+Copyright 1996, 1998, 2000-2005, 2008, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef GCDEXT_1_USE_BINARY
+#define GCDEXT_1_USE_BINARY 0
+#endif
+
+#ifndef GCDEXT_1_BINARY_METHOD
+#define GCDEXT_1_BINARY_METHOD 2
+#endif
+
+#ifndef USE_ZEROTAB
+#define USE_ZEROTAB 1
+#endif
+
+#if GCDEXT_1_USE_BINARY
+
+#if USE_ZEROTAB
+static unsigned char zerotab[0x40] = {
+ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+#endif
+
+mp_limb_t
+mpn_gcdext_1 (mp_limb_signed_t *sp, mp_limb_signed_t *tp,
+ mp_limb_t u, mp_limb_t v)
+{
+ /* Maintain
+
+ U = t1 u + t0 v
+ V = s1 u + s0 v
+
+ where U, V are the inputs (without any shared power of two),
+ and the matrix has determinant ± 2^{shift}.
+ */
+ mp_limb_t s0 = 1;
+ mp_limb_t t0 = 0;
+ mp_limb_t s1 = 0;
+ mp_limb_t t1 = 1;
+ mp_limb_t ug;
+ mp_limb_t vg;
+ mp_limb_t ugh;
+ mp_limb_t vgh;
+ unsigned zero_bits;
+ unsigned shift;
+ unsigned i;
+#if GCDEXT_1_BINARY_METHOD == 2
+ mp_limb_t det_sign;
+#endif
+
+ ASSERT (u > 0);
+ ASSERT (v > 0);
+
+ count_trailing_zeros (zero_bits, u | v);
+ u >>= zero_bits;
+ v >>= zero_bits;
+
+ if ((u & 1) == 0)
+ {
+ count_trailing_zeros (shift, u);
+ u >>= shift;
+ t1 <<= shift;
+ }
+ else if ((v & 1) == 0)
+ {
+ count_trailing_zeros (shift, v);
+ v >>= shift;
+ s0 <<= shift;
+ }
+ else
+ shift = 0;
+
+#if GCDEXT_1_BINARY_METHOD == 1
+ while (u != v)
+ {
+ unsigned count;
+ if (u > v)
+ {
+ u -= v;
+#if USE_ZEROTAB
+ count = zerotab [u & 0x3f];
+ u >>= count;
+ if (UNLIKELY (count == 6))
+ {
+ unsigned c;
+ do
+ {
+ c = zerotab[u & 0x3f];
+ u >>= c;
+ count += c;
+ }
+ while (c == 6);
+ }
+#else
+ count_trailing_zeros (count, u);
+ u >>= count;
+#endif
+ t0 += t1; t1 <<= count;
+ s0 += s1; s1 <<= count;
+ }
+ else
+ {
+ v -= u;
+#if USE_ZEROTAB
+ count = zerotab [v & 0x3f];
+ v >>= count;
+ if (UNLIKELY (count == 6))
+ {
+ unsigned c;
+ do
+ {
+ c = zerotab[v & 0x3f];
+ v >>= c;
+ count += c;
+ }
+ while (c == 6);
+ }
+#else
+ count_trailing_zeros (count, v);
+ v >>= count;
+#endif
+ t1 += t0; t0 <<= count;
+ s1 += s0; s0 <<= count;
+ }
+ shift += count;
+ }
+#else
+# if GCDEXT_1_BINARY_METHOD == 2
+ u >>= 1;
+ v >>= 1;
+
+ det_sign = 0;
+
+ while (u != v)
+ {
+ unsigned count;
+ mp_limb_t d = u - v;
+ mp_limb_t vgtu = LIMB_HIGHBIT_TO_MASK (d);
+ mp_limb_t sx;
+ mp_limb_t tx;
+
+ /* When v <= u (vgtu == 0), the updates are:
+
+ (u; v) <-- ( (u - v) >> count; v) (det = +(1<<count) for corr. M factor)
+ (t1, t0) <-- (t1 << count, t0 + t1)
+
+ and when v > 0, the updates are
+
+ (u; v) <-- ( (v - u) >> count; u) (det = -(1<<count))
+ (t1, t0) <-- (t0 << count, t0 + t1)
+
+ and similarly for s1, s0
+ */
+
+ /* v <-- min (u, v) */
+ v += (vgtu & d);
+
+ /* u <-- |u - v| */
+ u = (d ^ vgtu) - vgtu;
+
+ /* Number of trailing zeros is the same no matter if we look at
+ * d or u, but using d gives more parallelism. */
+#if USE_ZEROTAB
+ count = zerotab[d & 0x3f];
+ if (UNLIKELY (count == 6))
+ {
+ unsigned c = 6;
+ do
+ {
+ d >>= c;
+ c = zerotab[d & 0x3f];
+ count += c;
+ }
+ while (c == 6);
+ }
+#else
+ count_trailing_zeros (count, d);
+#endif
+ det_sign ^= vgtu;
+
+ tx = vgtu & (t0 - t1);
+ sx = vgtu & (s0 - s1);
+ t0 += t1;
+ s0 += s1;
+ t1 += tx;
+ s1 += sx;
+
+ count++;
+ u >>= count;
+ t1 <<= count;
+ s1 <<= count;
+ shift += count;
+ }
+ u = (u << 1) + 1;
+# else /* GCDEXT_1_BINARY_METHOD == 2 */
+# error Unknown GCDEXT_1_BINARY_METHOD
+# endif
+#endif
+
+ /* Now u = v = g = gcd (u,v). Compute U/g and V/g */
+ ug = t0 + t1;
+ vg = s0 + s1;
+
+ ugh = ug/2 + (ug & 1);
+ vgh = vg/2 + (vg & 1);
+
+ /* Now ±2^{shift} g = s0 U - t0 V. Get rid of the power of two, using
+ s0 U - t0 V = (s0 + V/g) U - (t0 + U/g) V. */
+ for (i = 0; i < shift; i++)
+ {
+ mp_limb_t mask = - ( (s0 | t0) & 1);
+
+ s0 /= 2;
+ t0 /= 2;
+ s0 += mask & vgh;
+ t0 += mask & ugh;
+ }
+ /* FIXME: Try simplifying this condition. */
+ if ( (s0 > 1 && 2*s0 >= vg) || (t0 > 1 && 2*t0 >= ug) )
+ {
+ s0 -= vg;
+ t0 -= ug;
+ }
+#if GCDEXT_1_BINARY_METHOD == 2
+ /* Conditional negation. */
+ s0 = (s0 ^ det_sign) - det_sign;
+ t0 = (t0 ^ det_sign) - det_sign;
+#endif
+ *sp = s0;
+ *tp = -t0;
+
+ return u << zero_bits;
+}
+
+#else /* !GCDEXT_1_USE_BINARY */
+
+
+/* FIXME: Takes two single-word limbs. It could be extended to a
+ * function that accepts a bignum for the first input, and only
+ * returns the first co-factor. */
+
+mp_limb_t
+mpn_gcdext_1 (mp_limb_signed_t *up, mp_limb_signed_t *vp,
+ mp_limb_t a, mp_limb_t b)
+{
+ /* Maintain
+
+ a = u0 A + v0 B
+ b = u1 A + v1 B
+
+ where A, B are the original inputs.
+ */
+ mp_limb_signed_t u0 = 1;
+ mp_limb_signed_t v0 = 0;
+ mp_limb_signed_t u1 = 0;
+ mp_limb_signed_t v1 = 1;
+
+ ASSERT (a > 0);
+ ASSERT (b > 0);
+
+ if (a < b)
+ goto divide_by_b;
+
+ for (;;)
+ {
+ mp_limb_t q;
+
+ q = a / b;
+ a -= q * b;
+
+ if (a == 0)
+ {
+ *up = u1;
+ *vp = v1;
+ return b;
+ }
+ u0 -= q * u1;
+ v0 -= q * v1;
+
+ divide_by_b:
+ q = b / a;
+ b -= q * a;
+
+ if (b == 0)
+ {
+ *up = u0;
+ *vp = v0;
+ return a;
+ }
+ u1 -= q * u0;
+ v1 -= q * v0;
+ }
+}
+#endif /* !GCDEXT_1_USE_BINARY */
diff --git a/gmp/mpn/generic/gcdext_lehmer.c b/gmp/mpn/generic/gcdext_lehmer.c
new file mode 100644
index 0000000000..547f69a409
--- /dev/null
+++ b/gmp/mpn/generic/gcdext_lehmer.c
@@ -0,0 +1,337 @@
+/* mpn_gcdext -- Extended Greatest Common Divisor.
+
+Copyright 1996, 1998, 2000-2005, 2008, 2009, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Here, d is the index of the cofactor to update. FIXME: Could use qn
+ = 0 for the common case q = 1. */
+void
+mpn_gcdext_hook (void *p, mp_srcptr gp, mp_size_t gn,
+ mp_srcptr qp, mp_size_t qn, int d)
+{
+ struct gcdext_ctx *ctx = (struct gcdext_ctx *) p;
+ mp_size_t un = ctx->un;
+
+ if (gp)
+ {
+ mp_srcptr up;
+
+ ASSERT (gn > 0);
+ ASSERT (gp[gn-1] > 0);
+
+ MPN_COPY (ctx->gp, gp, gn);
+ ctx->gn = gn;
+
+ if (d < 0)
+ {
+ int c;
+
+ /* Must return the smallest cofactor, +u1 or -u0 */
+ MPN_CMP (c, ctx->u0, ctx->u1, un);
+ ASSERT (c != 0 || (un == 1 && ctx->u0[0] == 1 && ctx->u1[0] == 1));
+
+ d = c < 0;
+ }
+
+ up = d ? ctx->u0 : ctx->u1;
+
+ MPN_NORMALIZE (up, un);
+ MPN_COPY (ctx->up, up, un);
+
+ *ctx->usize = d ? -un : un;
+ }
+ else
+ {
+ mp_limb_t cy;
+ mp_ptr u0 = ctx->u0;
+ mp_ptr u1 = ctx->u1;
+
+ ASSERT (d >= 0);
+
+ if (d)
+ MP_PTR_SWAP (u0, u1);
+
+ qn -= (qp[qn-1] == 0);
+
+ /* Update u0 += q * u1 */
+ if (qn == 1)
+ {
+ mp_limb_t q = qp[0];
+
+ if (q == 1)
+ /* A common case. */
+ cy = mpn_add_n (u0, u0, u1, un);
+ else
+ cy = mpn_addmul_1 (u0, u1, un, q);
+ }
+ else
+ {
+ mp_size_t u1n;
+ mp_ptr tp;
+
+ u1n = un;
+ MPN_NORMALIZE (u1, u1n);
+
+ if (u1n == 0)
+ return;
+
+ /* Should always have u1n == un here, and u1 >= u0. The
+ reason is that we alternate adding u0 to u1 and u1 to u0
+ (corresponding to subtractions a - b and b - a), and we
+ can get a large quotient only just after a switch, which
+ means that we'll add (a multiple of) the larger u to the
+ smaller. */
+
+ tp = ctx->tp;
+
+ if (qn > u1n)
+ mpn_mul (tp, qp, qn, u1, u1n);
+ else
+ mpn_mul (tp, u1, u1n, qp, qn);
+
+ u1n += qn;
+ u1n -= tp[u1n-1] == 0;
+
+ if (u1n >= un)
+ {
+ cy = mpn_add (u0, tp, u1n, u0, un);
+ un = u1n;
+ }
+ else
+ /* Note: Unlikely case, maybe never happens? */
+ cy = mpn_add (u0, u0, un, tp, u1n);
+
+ }
+ u0[un] = cy;
+ ctx->un = un + (cy > 0);
+ }
+}
+
+/* Temporary storage: 3*(n+1) for u. If hgcd2 succeeds, we need n for
+ the matrix-vector multiplication adjusting a, b. If hgcd fails, we
+ need at most n for the quotient and n+1 for the u update (reusing
+ the extra u). In all, 4n + 3. */
+
+mp_size_t
+mpn_gcdext_lehmer_n (mp_ptr gp, mp_ptr up, mp_size_t *usize,
+ mp_ptr ap, mp_ptr bp, mp_size_t n,
+ mp_ptr tp)
+{
+ mp_size_t ualloc = n + 1;
+
+ /* Keeps track of the second row of the reduction matrix
+ *
+ * M = (v0, v1 ; u0, u1)
+ *
+ * which correspond to the first column of the inverse
+ *
+ * M^{-1} = (u1, -v1; -u0, v0)
+ *
+ * This implies that
+ *
+ * a = u1 A (mod B)
+ * b = -u0 A (mod B)
+ *
+ * where A, B denotes the input values.
+ */
+
+ struct gcdext_ctx ctx;
+ mp_size_t un;
+ mp_ptr u0;
+ mp_ptr u1;
+ mp_ptr u2;
+
+ MPN_ZERO (tp, 3*ualloc);
+ u0 = tp; tp += ualloc;
+ u1 = tp; tp += ualloc;
+ u2 = tp; tp += ualloc;
+
+ u1[0] = 1; un = 1;
+
+ ctx.gp = gp;
+ ctx.up = up;
+ ctx.usize = usize;
+
+ /* FIXME: Handle n == 2 differently, after the loop? */
+ while (n >= 2)
+ {
+ struct hgcd_matrix1 M;
+ mp_limb_t ah, al, bh, bl;
+ mp_limb_t mask;
+
+ mask = ap[n-1] | bp[n-1];
+ ASSERT (mask > 0);
+
+ if (mask & GMP_NUMB_HIGHBIT)
+ {
+ ah = ap[n-1]; al = ap[n-2];
+ bh = bp[n-1]; bl = bp[n-2];
+ }
+ else if (n == 2)
+ {
+ /* We use the full inputs without truncation, so we can
+ safely shift left. */
+ int shift;
+
+ count_leading_zeros (shift, mask);
+ ah = MPN_EXTRACT_NUMB (shift, ap[1], ap[0]);
+ al = ap[0] << shift;
+ bh = MPN_EXTRACT_NUMB (shift, bp[1], bp[0]);
+ bl = bp[0] << shift;
+ }
+ else
+ {
+ int shift;
+
+ count_leading_zeros (shift, mask);
+ ah = MPN_EXTRACT_NUMB (shift, ap[n-1], ap[n-2]);
+ al = MPN_EXTRACT_NUMB (shift, ap[n-2], ap[n-3]);
+ bh = MPN_EXTRACT_NUMB (shift, bp[n-1], bp[n-2]);
+ bl = MPN_EXTRACT_NUMB (shift, bp[n-2], bp[n-3]);
+ }
+
+ /* Try an mpn_nhgcd2 step */
+ if (mpn_hgcd2 (ah, al, bh, bl, &M))
+ {
+ n = mpn_matrix22_mul1_inverse_vector (&M, tp, ap, bp, n);
+ MP_PTR_SWAP (ap, tp);
+ un = mpn_hgcd_mul_matrix1_vector(&M, u2, u0, u1, un);
+ MP_PTR_SWAP (u0, u2);
+ }
+ else
+ {
+ /* mpn_hgcd2 has failed. Then either one of a or b is very
+ small, or the difference is very small. Perform one
+ subtraction followed by one division. */
+ ctx.u0 = u0;
+ ctx.u1 = u1;
+ ctx.tp = u2;
+ ctx.un = un;
+
+ /* Temporary storage n for the quotient and ualloc for the
+ new cofactor. */
+ n = mpn_gcd_subdiv_step (ap, bp, n, 0, mpn_gcdext_hook, &ctx, tp);
+ if (n == 0)
+ return ctx.gn;
+
+ un = ctx.un;
+ }
+ }
+ ASSERT_ALWAYS (ap[0] > 0);
+ ASSERT_ALWAYS (bp[0] > 0);
+
+ if (ap[0] == bp[0])
+ {
+ int c;
+
+ /* Which cofactor to return now? Candidates are +u1 and -u0,
+ depending on which of a and b was most recently reduced,
+ which we don't keep track of. So compare and get the smallest
+ one. */
+
+ gp[0] = ap[0];
+
+ MPN_CMP (c, u0, u1, un);
+ ASSERT (c != 0 || (un == 1 && u0[0] == 1 && u1[0] == 1));
+ if (c < 0)
+ {
+ MPN_NORMALIZE (u0, un);
+ MPN_COPY (up, u0, un);
+ *usize = -un;
+ }
+ else
+ {
+ MPN_NORMALIZE_NOT_ZERO (u1, un);
+ MPN_COPY (up, u1, un);
+ *usize = un;
+ }
+ return 1;
+ }
+ else
+ {
+ mp_limb_t uh, vh;
+ mp_limb_signed_t u;
+ mp_limb_signed_t v;
+ int negate;
+
+ gp[0] = mpn_gcdext_1 (&u, &v, ap[0], bp[0]);
+
+ /* Set up = u u1 - v u0. Keep track of size, un grows by one or
+ two limbs. */
+
+ if (u == 0)
+ {
+ ASSERT (v == 1);
+ MPN_NORMALIZE (u0, un);
+ MPN_COPY (up, u0, un);
+ *usize = -un;
+ return 1;
+ }
+ else if (v == 0)
+ {
+ ASSERT (u == 1);
+ MPN_NORMALIZE (u1, un);
+ MPN_COPY (up, u1, un);
+ *usize = un;
+ return 1;
+ }
+ else if (u > 0)
+ {
+ negate = 0;
+ ASSERT (v < 0);
+ v = -v;
+ }
+ else
+ {
+ negate = 1;
+ ASSERT (v > 0);
+ u = -u;
+ }
+
+ uh = mpn_mul_1 (up, u1, un, u);
+ vh = mpn_addmul_1 (up, u0, un, v);
+
+ if ( (uh | vh) > 0)
+ {
+ uh += vh;
+ up[un++] = uh;
+ if (uh < vh)
+ up[un++] = 1;
+ }
+
+ MPN_NORMALIZE_NOT_ZERO (up, un);
+
+ *usize = negate ? -un : un;
+ return 1;
+ }
+}
diff --git a/gmp/mpn/generic/get_d.c b/gmp/mpn/generic/get_d.c
new file mode 100644
index 0000000000..d73d314856
--- /dev/null
+++ b/gmp/mpn/generic/get_d.c
@@ -0,0 +1,412 @@
+/* mpn_get_d -- limbs to double conversion.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2003, 2004, 2007, 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef _GMP_IEEE_FLOATS
+#define _GMP_IEEE_FLOATS 0
+#endif
+
+/* To force use of the generic C code for testing, put
+ "#define _GMP_IEEE_FLOATS 0" at this point. */
+
+
+/* In alpha gcc prior to 3.4, signed DI comparisons involving constants are
+ rearranged from "x < n" to "x+(-n) < 0", which is of course hopelessly
+ wrong if that addition overflows.
+
+ The workaround here avoids this bug by ensuring n is not a literal constant.
+ Note that this is alpha specific. The offending transformation is/was in
+ alpha.c alpha_emit_conditional_branch() under "We want to use cmpcc/bcc".
+
+ Bizarrely, this happens also with Cray cc on alphaev5-cray-unicosmk2.0.6.X,
+ and has the same solution. Don't know why or how. */
+
+#if HAVE_HOST_CPU_FAMILY_alpha \
+ && ((defined (__GNUC__) && ! __GMP_GNUC_PREREQ(3,4)) \
+ || defined (_CRAY))
+static volatile const long CONST_1024 = 1024;
+static volatile const long CONST_NEG_1023 = -1023;
+static volatile const long CONST_NEG_1022_SUB_53 = -1022 - 53;
+#else
+#define CONST_1024 (1024)
+#define CONST_NEG_1023 (-1023)
+#define CONST_NEG_1022_SUB_53 (-1022 - 53)
+#endif
+
+
+/* Return the value {ptr,size}*2^exp, and negative if sign<0. Must have
+ size>=1, and a non-zero high limb ptr[size-1].
+
+ When we know the fp format, the result is truncated towards zero. This is
+ consistent with other gmp conversions, like mpz_set_f or mpz_set_q, and is
+ easy to implement and test.
+
+ When we do not know the format, such truncation seems much harder. One
+ would need to defeat any rounding mode, including round-up.
+
+ It's felt that GMP is not primarily concerned with hardware floats, and
+ really isn't enhanced by getting involved with hardware rounding modes
+ (which could even be some weird unknown style), so something unambiguous and
+ straightforward is best.
+
+
+ The IEEE code below is the usual case, it knows either a 32-bit or 64-bit
+ limb and is done with shifts and masks. The 64-bit case in particular
+ should come out nice and compact.
+
+ The generic code used to work one bit at a time, which was not only slow,
+ but implicitly relied upon denorms for intermediates, since the lowest bits'
+ weight of a perfectly valid fp number underflows in non-denorm. Therefore,
+ the generic code now works limb-per-limb, initially creating a number x such
+ that 1 <= x <= BASE. (BASE is reached only as result of rounding.) Then
+ x's exponent is scaled with explicit code (not ldexp to avoid libm
+ dependency). It is a tap-dance to avoid underflow or overflow, beware!
+
+
+ Traps:
+
+ Hardware traps for overflow to infinity, underflow to zero, or unsupported
+ denorms may or may not be taken. The IEEE code works bitwise and so
+ probably won't trigger them, the generic code works by float operations and
+ so probably will. This difference might be thought less than ideal, but
+ again its felt straightforward code is better than trying to get intimate
+ with hardware exceptions (of perhaps unknown nature).
+
+
+ Not done:
+
+ mpz_get_d in the past handled size==1 with a cast limb->double. This might
+ still be worthwhile there (for up to the mantissa many bits), but for
+ mpn_get_d here, the cost of applying "exp" to the resulting exponent would
+ probably use up any benefit a cast may have over bit twiddling. Also, if
+ the exponent is pushed into denorm range then bit twiddling is the only
+ option, to ensure the desired truncation is obtained.
+
+
+ Other:
+
+ For reference, note that HPPA 8000, 8200, 8500 and 8600 trap FCNV,UDW,DBL
+ to the kernel for values >= 2^63. This makes it slow, and worse the kernel
+ Linux (what versions?) apparently uses untested code in its trap handling
+ routines, and gets the sign wrong. We don't use such a limb-to-double
+ cast, neither in the IEEE or generic code. */
+
+
+
+#undef FORMAT_RECOGNIZED
+
+double
+mpn_get_d (mp_srcptr up, mp_size_t size, mp_size_t sign, long exp)
+{
+ int lshift, nbits;
+ mp_limb_t x, mhi, mlo;
+
+ ASSERT (size >= 0);
+ ASSERT_MPN (up, size);
+ ASSERT (size == 0 || up[size-1] != 0);
+
+ if (size == 0)
+ return 0.0;
+
+ /* Adjust exp to a radix point just above {up,size}, guarding against
+ overflow. After this exp can of course be reduced to anywhere within
+ the {up,size} region without underflow. */
+ if (UNLIKELY ((unsigned long) (GMP_NUMB_BITS * size)
+ > ((unsigned long) LONG_MAX - exp)))
+ {
+#if _GMP_IEEE_FLOATS
+ goto ieee_infinity;
+#endif
+
+ /* generic */
+ exp = LONG_MAX;
+ }
+ else
+ {
+ exp += GMP_NUMB_BITS * size;
+ }
+
+#if _GMP_IEEE_FLOATS
+ {
+ union ieee_double_extract u;
+
+ up += size;
+
+#if GMP_LIMB_BITS == 64
+ mlo = up[-1];
+ count_leading_zeros (lshift, mlo);
+
+ exp -= (lshift - GMP_NAIL_BITS) + 1;
+ mlo <<= lshift;
+
+ nbits = GMP_LIMB_BITS - lshift;
+
+ if (nbits < 53 && size > 1)
+ {
+ x = up[-2];
+ x <<= GMP_NAIL_BITS;
+ x >>= nbits;
+ mlo |= x;
+ nbits += GMP_NUMB_BITS;
+
+ if (LIMBS_PER_DOUBLE >= 3 && nbits < 53 && size > 2)
+ {
+ x = up[-3];
+ x <<= GMP_NAIL_BITS;
+ x >>= nbits;
+ mlo |= x;
+ nbits += GMP_NUMB_BITS;
+ }
+ }
+ mhi = mlo >> (32 + 11);
+ mlo = mlo >> 11; /* later implicitly truncated to 32 bits */
+#endif
+#if GMP_LIMB_BITS == 32
+ x = *--up;
+ count_leading_zeros (lshift, x);
+
+ exp -= (lshift - GMP_NAIL_BITS) + 1;
+ x <<= lshift;
+ mhi = x >> 11;
+
+ if (lshift < 11) /* FIXME: never true if NUMB < 20 bits */
+ {
+ /* All 20 bits in mhi */
+ mlo = x << 21;
+ /* >= 1 bit in mlo */
+ nbits = GMP_LIMB_BITS - lshift - 21;
+ }
+ else
+ {
+ if (size > 1)
+ {
+ nbits = GMP_LIMB_BITS - lshift;
+
+ x = *--up, size--;
+ x <<= GMP_NAIL_BITS;
+ mhi |= x >> nbits >> 11;
+
+ mlo = x << GMP_LIMB_BITS - nbits - 11;
+ nbits = nbits + 11 - GMP_NAIL_BITS;
+ }
+ else
+ {
+ mlo = 0;
+ goto done;
+ }
+ }
+
+ /* Now all needed bits in mhi have been accumulated. Add bits to mlo. */
+
+ if (LIMBS_PER_DOUBLE >= 2 && nbits < 32 && size > 1)
+ {
+ x = up[-1];
+ x <<= GMP_NAIL_BITS;
+ x >>= nbits;
+ mlo |= x;
+ nbits += GMP_NUMB_BITS;
+
+ if (LIMBS_PER_DOUBLE >= 3 && nbits < 32 && size > 2)
+ {
+ x = up[-2];
+ x <<= GMP_NAIL_BITS;
+ x >>= nbits;
+ mlo |= x;
+ nbits += GMP_NUMB_BITS;
+
+ if (LIMBS_PER_DOUBLE >= 4 && nbits < 32 && size > 3)
+ {
+ x = up[-3];
+ x <<= GMP_NAIL_BITS;
+ x >>= nbits;
+ mlo |= x;
+ nbits += GMP_NUMB_BITS;
+ }
+ }
+ }
+
+ done:;
+
+#endif
+ if (UNLIKELY (exp >= CONST_1024))
+ {
+ /* overflow, return infinity */
+ ieee_infinity:
+ mhi = 0;
+ mlo = 0;
+ exp = 1024;
+ }
+ else if (UNLIKELY (exp <= CONST_NEG_1023))
+ {
+ int rshift;
+
+ if (LIKELY (exp <= CONST_NEG_1022_SUB_53))
+ return 0.0; /* denorm underflows to zero */
+
+ rshift = -1022 - exp;
+ ASSERT (rshift > 0 && rshift < 53);
+#if GMP_LIMB_BITS > 53
+ mlo >>= rshift;
+ mhi = mlo >> 32;
+#else
+ if (rshift >= 32)
+ {
+ mlo = mhi;
+ mhi = 0;
+ rshift -= 32;
+ }
+ lshift = GMP_LIMB_BITS - rshift;
+ mlo = (mlo >> rshift) | (rshift == 0 ? 0 : mhi << lshift);
+ mhi >>= rshift;
+#endif
+ exp = -1023;
+ }
+ u.s.manh = mhi;
+ u.s.manl = mlo;
+ u.s.exp = exp + 1023;
+ u.s.sig = (sign < 0);
+ return u.d;
+ }
+#define FORMAT_RECOGNIZED 1
+#endif
+
+#if HAVE_DOUBLE_VAX_D
+ {
+ union double_extract u;
+
+ up += size;
+
+ mhi = up[-1];
+
+ count_leading_zeros (lshift, mhi);
+ exp -= lshift;
+ mhi <<= lshift;
+
+ mlo = 0;
+ if (size > 1)
+ {
+ mlo = up[-2];
+ if (lshift != 0)
+ mhi += mlo >> (GMP_LIMB_BITS - lshift);
+ mlo <<= lshift;
+
+ if (size > 2 && lshift > 8)
+ {
+ x = up[-3];
+ mlo += x >> (GMP_LIMB_BITS - lshift);
+ }
+ }
+
+ if (UNLIKELY (exp >= 128))
+ {
+ /* overflow, return maximum number */
+ mhi = 0xffffffff;
+ mlo = 0xffffffff;
+ exp = 127;
+ }
+ else if (UNLIKELY (exp < -128))
+ {
+ return 0.0; /* underflows to zero */
+ }
+
+ u.s.man3 = mhi >> 24; /* drop msb, since implicit */
+ u.s.man2 = mhi >> 8;
+ u.s.man1 = (mhi << 8) + (mlo >> 24);
+ u.s.man0 = mlo >> 8;
+ u.s.exp = exp + 128;
+ u.s.sig = sign < 0;
+ return u.d;
+ }
+#define FORMAT_RECOGNIZED 1
+#endif
+
+#if ! FORMAT_RECOGNIZED
+ { /* Non-IEEE or strange limb size, do something generic. */
+ mp_size_t i;
+ double d, weight;
+ unsigned long uexp;
+
+ /* First generate an fp number disregarding exp, instead keeping things
+ within the numb base factor from 1, which should prevent overflow and
+ underflow even for the most exponent limited fp formats. The
+ termination criteria should be refined, since we now include too many
+ limbs. */
+ weight = 1/MP_BASE_AS_DOUBLE;
+ d = up[size - 1];
+ for (i = size - 2; i >= 0; i--)
+ {
+ d += up[i] * weight;
+ weight /= MP_BASE_AS_DOUBLE;
+ if (weight == 0)
+ break;
+ }
+
+ /* Now apply exp. */
+ exp -= GMP_NUMB_BITS;
+ if (exp > 0)
+ {
+ weight = 2.0;
+ uexp = exp;
+ }
+ else
+ {
+ weight = 0.5;
+ uexp = 1 - (unsigned long) (exp + 1);
+ }
+#if 1
+ /* Square-and-multiply exponentiation. */
+ if (uexp & 1)
+ d *= weight;
+ while (uexp >>= 1)
+ {
+ weight *= weight;
+ if (uexp & 1)
+ d *= weight;
+ }
+#else
+ /* Plain exponentiation. */
+ while (uexp > 0)
+ {
+ d *= weight;
+ uexp--;
+ }
+#endif
+
+ return sign >= 0 ? d : -d;
+ }
+#endif
+}
diff --git a/gmp/mpn/generic/get_str.c b/gmp/mpn/generic/get_str.c
new file mode 100644
index 0000000000..42e93c9cee
--- /dev/null
+++ b/gmp/mpn/generic/get_str.c
@@ -0,0 +1,553 @@
+/* mpn_get_str -- Convert {UP,USIZE} to a base BASE string in STR.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE, EXCEPT mpn_get_str, ARE INTERNAL WITH A MUTABLE
+ INTERFACE. IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN
+ FACT, IT IS ALMOST GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE
+ GNU MP RELEASE.
+
+Copyright 1991-1994, 1996, 2000-2002, 2004, 2006-2008, 2011, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Conversion of U {up,un} to a string in base b. Internally, we convert to
+ base B = b^m, the largest power of b that fits a limb. Basic algorithms:
+
+ A) Divide U repeatedly by B, generating a quotient and remainder, until the
+ quotient becomes zero. The remainders hold the converted digits. Digits
+ come out from right to left. (Used in mpn_sb_get_str.)
+
+ B) Divide U by b^g, for g such that 1/b <= U/b^g < 1, generating a fraction.
+ Then develop digits by multiplying the fraction repeatedly by b. Digits
+ come out from left to right. (Currently not used herein, except for in
+ code for converting single limbs to individual digits.)
+
+ C) Compute B^1, B^2, B^4, ..., B^s, for s such that B^s is just above
+ sqrt(U). Then divide U by B^s, generating quotient and remainder.
+ Recursively convert the quotient, then the remainder, using the
+ precomputed powers. Digits come out from left to right. (Used in
+ mpn_dc_get_str.)
+
+ When using algorithm C, algorithm B might be suitable for basecase code,
+ since the required b^g power will be readily accessible.
+
+ Optimization ideas:
+ 1. The recursive function of (C) could use less temporary memory. The powtab
+ allocation could be trimmed with some computation, and the tmp area could
+ be reduced, or perhaps eliminated if up is reused for both quotient and
+ remainder (it is currently used just for remainder).
+ 2. Store the powers of (C) in normalized form, with the normalization count.
+ Quotients will usually need to be left-shifted before each divide, and
+ remainders will either need to be left-shifted of right-shifted.
+ 3. In the code for developing digits from a single limb, we could avoid using
+ a full umul_ppmm except for the first (or first few) digits, provided base
+ is even. Subsequent digits can be developed using plain multiplication.
+ (This saves on register-starved machines (read x86) and on all machines
+ that generate the upper product half using a separate instruction (alpha,
+ powerpc, IA-64) or lacks such support altogether (sparc64, hppa64).
+ 4. Separate mpn_dc_get_str basecase code from code for small conversions. The
+ former code will have the exact right power readily available in the
+ powtab parameter for dividing the current number into a fraction. Convert
+ that using algorithm B.
+ 5. Completely avoid division. Compute the inverses of the powers now in
+ powtab instead of the actual powers.
+ 6. Decrease powtab allocation for even bases. E.g. for base 10 we could save
+ about 30% (1-log(5)/log(10)).
+
+ Basic structure of (C):
+ mpn_get_str:
+ if POW2_P (n)
+ ...
+ else
+ if (un < GET_STR_PRECOMPUTE_THRESHOLD)
+ mpn_sb_get_str (str, base, up, un);
+ else
+ precompute_power_tables
+ mpn_dc_get_str
+
+ mpn_dc_get_str:
+ mpn_tdiv_qr
+ if (qn < GET_STR_DC_THRESHOLD)
+ mpn_sb_get_str
+ else
+ mpn_dc_get_str
+ if (rn < GET_STR_DC_THRESHOLD)
+ mpn_sb_get_str
+ else
+ mpn_dc_get_str
+
+
+ The reason for the two threshold values is the cost of
+ precompute_power_tables. GET_STR_PRECOMPUTE_THRESHOLD will be considerably
+ larger than GET_STR_PRECOMPUTE_THRESHOLD. */
+
+
+/* The x86s and m68020 have a quotient and remainder "div" instruction and
+ gcc recognises an adjacent "/" and "%" can be combined using that.
+ Elsewhere "/" and "%" are either separate instructions, or separate
+ libgcc calls (which unfortunately gcc as of version 3.0 doesn't combine).
+ A multiply and subtract should be faster than a "%" in those cases. */
+#if HAVE_HOST_CPU_FAMILY_x86 \
+ || HAVE_HOST_CPU_m68020 \
+ || HAVE_HOST_CPU_m68030 \
+ || HAVE_HOST_CPU_m68040 \
+ || HAVE_HOST_CPU_m68060 \
+ || HAVE_HOST_CPU_m68360 /* CPU32 */
+#define udiv_qrnd_unnorm(q,r,n,d) \
+ do { \
+ mp_limb_t __q = (n) / (d); \
+ mp_limb_t __r = (n) % (d); \
+ (q) = __q; \
+ (r) = __r; \
+ } while (0)
+#else
+#define udiv_qrnd_unnorm(q,r,n,d) \
+ do { \
+ mp_limb_t __q = (n) / (d); \
+ mp_limb_t __r = (n) - __q*(d); \
+ (q) = __q; \
+ (r) = __r; \
+ } while (0)
+#endif
+
+
+/* Convert {up,un} to a string in base base, and put the result in str.
+ Generate len characters, possibly padding with zeros to the left. If len is
+ zero, generate as many characters as required. Return a pointer immediately
+ after the last digit of the result string. Complexity is O(un^2); intended
+ for small conversions. */
+static unsigned char *
+mpn_sb_get_str (unsigned char *str, size_t len,
+ mp_ptr up, mp_size_t un, int base)
+{
+ mp_limb_t rl, ul;
+ unsigned char *s;
+ size_t l;
+ /* Allocate memory for largest possible string, given that we only get here
+ for operands with un < GET_STR_PRECOMPUTE_THRESHOLD and that the smallest
+ base is 3. 7/11 is an approximation to 1/log2(3). */
+#if TUNE_PROGRAM_BUILD
+#define BUF_ALLOC (GET_STR_THRESHOLD_LIMIT * GMP_LIMB_BITS * 7 / 11)
+#else
+#define BUF_ALLOC (GET_STR_PRECOMPUTE_THRESHOLD * GMP_LIMB_BITS * 7 / 11)
+#endif
+ unsigned char buf[BUF_ALLOC];
+#if TUNE_PROGRAM_BUILD
+ mp_limb_t rp[GET_STR_THRESHOLD_LIMIT];
+#else
+ mp_limb_t rp[GET_STR_PRECOMPUTE_THRESHOLD];
+#endif
+
+ if (base == 10)
+ {
+ /* Special case code for base==10 so that the compiler has a chance to
+ optimize things. */
+
+ MPN_COPY (rp + 1, up, un);
+
+ s = buf + BUF_ALLOC;
+ while (un > 1)
+ {
+ int i;
+ mp_limb_t frac, digit;
+ MPN_DIVREM_OR_PREINV_DIVREM_1 (rp, (mp_size_t) 1, rp + 1, un,
+ MP_BASES_BIG_BASE_10,
+ MP_BASES_BIG_BASE_INVERTED_10,
+ MP_BASES_NORMALIZATION_STEPS_10);
+ un -= rp[un] == 0;
+ frac = (rp[0] + 1) << GMP_NAIL_BITS;
+ s -= MP_BASES_CHARS_PER_LIMB_10;
+#if HAVE_HOST_CPU_FAMILY_x86
+ /* The code below turns out to be a bit slower for x86 using gcc.
+ Use plain code. */
+ i = MP_BASES_CHARS_PER_LIMB_10;
+ do
+ {
+ umul_ppmm (digit, frac, frac, 10);
+ *s++ = digit;
+ }
+ while (--i);
+#else
+ /* Use the fact that 10 in binary is 1010, with the lowest bit 0.
+ After a few umul_ppmm, we will have accumulated enough low zeros
+ to use a plain multiply. */
+ if (MP_BASES_NORMALIZATION_STEPS_10 == 0)
+ {
+ umul_ppmm (digit, frac, frac, 10);
+ *s++ = digit;
+ }
+ if (MP_BASES_NORMALIZATION_STEPS_10 <= 1)
+ {
+ umul_ppmm (digit, frac, frac, 10);
+ *s++ = digit;
+ }
+ if (MP_BASES_NORMALIZATION_STEPS_10 <= 2)
+ {
+ umul_ppmm (digit, frac, frac, 10);
+ *s++ = digit;
+ }
+ if (MP_BASES_NORMALIZATION_STEPS_10 <= 3)
+ {
+ umul_ppmm (digit, frac, frac, 10);
+ *s++ = digit;
+ }
+ i = (MP_BASES_CHARS_PER_LIMB_10 - ((MP_BASES_NORMALIZATION_STEPS_10 < 4)
+ ? (4-MP_BASES_NORMALIZATION_STEPS_10)
+ : 0));
+ frac = (frac + 0xf) >> 4;
+ do
+ {
+ frac *= 10;
+ digit = frac >> (GMP_LIMB_BITS - 4);
+ *s++ = digit;
+ frac &= (~(mp_limb_t) 0) >> 4;
+ }
+ while (--i);
+#endif
+ s -= MP_BASES_CHARS_PER_LIMB_10;
+ }
+
+ ul = rp[1];
+ while (ul != 0)
+ {
+ udiv_qrnd_unnorm (ul, rl, ul, 10);
+ *--s = rl;
+ }
+ }
+ else /* not base 10 */
+ {
+ unsigned chars_per_limb;
+ mp_limb_t big_base, big_base_inverted;
+ unsigned normalization_steps;
+
+ chars_per_limb = mp_bases[base].chars_per_limb;
+ big_base = mp_bases[base].big_base;
+ big_base_inverted = mp_bases[base].big_base_inverted;
+ count_leading_zeros (normalization_steps, big_base);
+
+ MPN_COPY (rp + 1, up, un);
+
+ s = buf + BUF_ALLOC;
+ while (un > 1)
+ {
+ int i;
+ mp_limb_t frac;
+ MPN_DIVREM_OR_PREINV_DIVREM_1 (rp, (mp_size_t) 1, rp + 1, un,
+ big_base, big_base_inverted,
+ normalization_steps);
+ un -= rp[un] == 0;
+ frac = (rp[0] + 1) << GMP_NAIL_BITS;
+ s -= chars_per_limb;
+ i = chars_per_limb;
+ do
+ {
+ mp_limb_t digit;
+ umul_ppmm (digit, frac, frac, base);
+ *s++ = digit;
+ }
+ while (--i);
+ s -= chars_per_limb;
+ }
+
+ ul = rp[1];
+ while (ul != 0)
+ {
+ udiv_qrnd_unnorm (ul, rl, ul, base);
+ *--s = rl;
+ }
+ }
+
+ l = buf + BUF_ALLOC - s;
+ while (l < len)
+ {
+ *str++ = 0;
+ len--;
+ }
+ while (l != 0)
+ {
+ *str++ = *s++;
+ l--;
+ }
+ return str;
+}
+
+
+/* Convert {UP,UN} to a string with a base as represented in POWTAB, and put
+ the string in STR. Generate LEN characters, possibly padding with zeros to
+ the left. If LEN is zero, generate as many characters as required.
+ Return a pointer immediately after the last digit of the result string.
+ This uses divide-and-conquer and is intended for large conversions. */
+static unsigned char *
+mpn_dc_get_str (unsigned char *str, size_t len,
+ mp_ptr up, mp_size_t un,
+ const powers_t *powtab, mp_ptr tmp)
+{
+ if (BELOW_THRESHOLD (un, GET_STR_DC_THRESHOLD))
+ {
+ if (un != 0)
+ str = mpn_sb_get_str (str, len, up, un, powtab->base);
+ else
+ {
+ while (len != 0)
+ {
+ *str++ = 0;
+ len--;
+ }
+ }
+ }
+ else
+ {
+ mp_ptr pwp, qp, rp;
+ mp_size_t pwn, qn;
+ mp_size_t sn;
+
+ pwp = powtab->p;
+ pwn = powtab->n;
+ sn = powtab->shift;
+
+ if (un < pwn + sn || (un == pwn + sn && mpn_cmp (up + sn, pwp, un - sn) < 0))
+ {
+ str = mpn_dc_get_str (str, len, up, un, powtab - 1, tmp);
+ }
+ else
+ {
+ qp = tmp; /* (un - pwn + 1) limbs for qp */
+ rp = up; /* pwn limbs for rp; overwrite up area */
+
+ mpn_tdiv_qr (qp, rp + sn, 0L, up + sn, un - sn, pwp, pwn);
+ qn = un - sn - pwn; qn += qp[qn] != 0; /* quotient size */
+
+ ASSERT (qn < pwn + sn || (qn == pwn + sn && mpn_cmp (qp + sn, pwp, pwn) < 0));
+
+ if (len != 0)
+ len = len - powtab->digits_in_base;
+
+ str = mpn_dc_get_str (str, len, qp, qn, powtab - 1, tmp + qn);
+ str = mpn_dc_get_str (str, powtab->digits_in_base, rp, pwn + sn, powtab - 1, tmp);
+ }
+ }
+ return str;
+}
+
+
+/* There are no leading zeros on the digits generated at str, but that's not
+ currently a documented feature. The current mpz_out_str and mpz_get_str
+ rely on it. */
+
+size_t
+mpn_get_str (unsigned char *str, int base, mp_ptr up, mp_size_t un)
+{
+ mp_ptr powtab_mem, powtab_mem_ptr;
+ mp_limb_t big_base;
+ size_t digits_in_base;
+ powers_t powtab[GMP_LIMB_BITS];
+ int pi;
+ mp_size_t n;
+ mp_ptr p, t;
+ size_t out_len;
+ mp_ptr tmp;
+ TMP_DECL;
+
+ /* Special case zero, as the code below doesn't handle it. */
+ if (un == 0)
+ {
+ str[0] = 0;
+ return 1;
+ }
+
+ if (POW2_P (base))
+ {
+ /* The base is a power of 2. Convert from most significant end. */
+ mp_limb_t n1, n0;
+ int bits_per_digit = mp_bases[base].big_base;
+ int cnt;
+ int bit_pos;
+ mp_size_t i;
+ unsigned char *s = str;
+ mp_bitcnt_t bits;
+
+ n1 = up[un - 1];
+ count_leading_zeros (cnt, n1);
+
+ /* BIT_POS should be R when input ends in least significant nibble,
+ R + bits_per_digit * n when input ends in nth least significant
+ nibble. */
+
+ bits = (mp_bitcnt_t) GMP_NUMB_BITS * un - cnt + GMP_NAIL_BITS;
+ cnt = bits % bits_per_digit;
+ if (cnt != 0)
+ bits += bits_per_digit - cnt;
+ bit_pos = bits - (mp_bitcnt_t) (un - 1) * GMP_NUMB_BITS;
+
+ /* Fast loop for bit output. */
+ i = un - 1;
+ for (;;)
+ {
+ bit_pos -= bits_per_digit;
+ while (bit_pos >= 0)
+ {
+ *s++ = (n1 >> bit_pos) & ((1 << bits_per_digit) - 1);
+ bit_pos -= bits_per_digit;
+ }
+ i--;
+ if (i < 0)
+ break;
+ n0 = (n1 << -bit_pos) & ((1 << bits_per_digit) - 1);
+ n1 = up[i];
+ bit_pos += GMP_NUMB_BITS;
+ *s++ = n0 | (n1 >> bit_pos);
+ }
+
+ return s - str;
+ }
+
+ /* General case. The base is not a power of 2. */
+
+ if (BELOW_THRESHOLD (un, GET_STR_PRECOMPUTE_THRESHOLD))
+ return mpn_sb_get_str (str, (size_t) 0, up, un, base) - str;
+
+ TMP_MARK;
+
+ /* Allocate one large block for the powers of big_base. */
+ powtab_mem = TMP_BALLOC_LIMBS (mpn_dc_get_str_powtab_alloc (un));
+ powtab_mem_ptr = powtab_mem;
+
+ /* Compute a table of powers, were the largest power is >= sqrt(U). */
+
+ big_base = mp_bases[base].big_base;
+ digits_in_base = mp_bases[base].chars_per_limb;
+
+ {
+ mp_size_t n_pows, xn, pn, exptab[GMP_LIMB_BITS], bexp;
+ mp_limb_t cy;
+ mp_size_t shift;
+ size_t ndig;
+
+ DIGITS_IN_BASE_PER_LIMB (ndig, un, base);
+ xn = 1 + ndig / mp_bases[base].chars_per_limb; /* FIXME: scalar integer division */
+
+ n_pows = 0;
+ for (pn = xn; pn != 1; pn = (pn + 1) >> 1)
+ {
+ exptab[n_pows] = pn;
+ n_pows++;
+ }
+ exptab[n_pows] = 1;
+
+ powtab[0].p = &big_base;
+ powtab[0].n = 1;
+ powtab[0].digits_in_base = digits_in_base;
+ powtab[0].base = base;
+ powtab[0].shift = 0;
+
+ powtab[1].p = powtab_mem_ptr; powtab_mem_ptr += 2;
+ powtab[1].p[0] = big_base;
+ powtab[1].n = 1;
+ powtab[1].digits_in_base = digits_in_base;
+ powtab[1].base = base;
+ powtab[1].shift = 0;
+
+ n = 1;
+ p = &big_base;
+ bexp = 1;
+ shift = 0;
+ for (pi = 2; pi < n_pows; pi++)
+ {
+ t = powtab_mem_ptr;
+ powtab_mem_ptr += 2 * n + 2;
+
+ ASSERT_ALWAYS (powtab_mem_ptr < powtab_mem + mpn_dc_get_str_powtab_alloc (un));
+
+ mpn_sqr (t, p, n);
+
+ digits_in_base *= 2;
+ n *= 2; n -= t[n - 1] == 0;
+ bexp *= 2;
+
+ if (bexp + 1 < exptab[n_pows - pi])
+ {
+ digits_in_base += mp_bases[base].chars_per_limb;
+ cy = mpn_mul_1 (t, t, n, big_base);
+ t[n] = cy;
+ n += cy != 0;
+ bexp += 1;
+ }
+ shift *= 2;
+ /* Strip low zero limbs. */
+ while (t[0] == 0)
+ {
+ t++;
+ n--;
+ shift++;
+ }
+ p = t;
+ powtab[pi].p = p;
+ powtab[pi].n = n;
+ powtab[pi].digits_in_base = digits_in_base;
+ powtab[pi].base = base;
+ powtab[pi].shift = shift;
+ }
+
+ for (pi = 1; pi < n_pows; pi++)
+ {
+ t = powtab[pi].p;
+ n = powtab[pi].n;
+ cy = mpn_mul_1 (t, t, n, big_base);
+ t[n] = cy;
+ n += cy != 0;
+ if (t[0] == 0)
+ {
+ powtab[pi].p = t + 1;
+ n--;
+ powtab[pi].shift++;
+ }
+ powtab[pi].n = n;
+ powtab[pi].digits_in_base += mp_bases[base].chars_per_limb;
+ }
+
+#if 0
+ { int i;
+ printf ("Computed table values for base=%d, un=%d, xn=%d:\n", base, un, xn);
+ for (i = 0; i < n_pows; i++)
+ printf ("%2d: %10ld %10ld %11ld %ld\n", i, exptab[n_pows-i], powtab[i].n, powtab[i].digits_in_base, powtab[i].shift);
+ }
+#endif
+ }
+
+ /* Using our precomputed powers, now in powtab[], convert our number. */
+ tmp = TMP_BALLOC_LIMBS (mpn_dc_get_str_itch (un));
+ out_len = mpn_dc_get_str (str, 0, up, un, powtab + (pi - 1), tmp) - str;
+ TMP_FREE;
+
+ return out_len;
+}
diff --git a/gmp/mpn/generic/gmp-mparam.h b/gmp/mpn/generic/gmp-mparam.h
new file mode 100644
index 0000000000..7dc057aa0c
--- /dev/null
+++ b/gmp/mpn/generic/gmp-mparam.h
@@ -0,0 +1,33 @@
+/* Generic C gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* Values for GMP_LIMB_BITS etc will be determined by ./configure and put
+ in config.h. */
diff --git a/gmp/mpn/generic/hgcd.c b/gmp/mpn/generic/hgcd.c
new file mode 100644
index 0000000000..e27a9bdd82
--- /dev/null
+++ b/gmp/mpn/generic/hgcd.c
@@ -0,0 +1,183 @@
+/* hgcd.c.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2003-2005, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Size analysis for hgcd:
+
+ For the recursive calls, we have n1 <= ceil(n / 2). Then the
+ storage need is determined by the storage for the recursive call
+ computing M1, and hgcd_matrix_adjust and hgcd_matrix_mul calls that use M1
+ (after this, the storage needed for M1 can be recycled).
+
+ Let S(r) denote the required storage. For M1 we need 4 * (ceil(n1/2) + 1)
+ = 4 * (ceil(n/4) + 1), for the hgcd_matrix_adjust call, we need n + 2,
+ and for the hgcd_matrix_mul, we may need 3 ceil(n/2) + 8. In total,
+ 4 * ceil(n/4) + 3 ceil(n/2) + 12 <= 10 ceil(n/4) + 12.
+
+ For the recursive call, we need S(n1) = S(ceil(n/2)).
+
+ S(n) <= 10*ceil(n/4) + 12 + S(ceil(n/2))
+ <= 10*(ceil(n/4) + ... + ceil(n/2^(1+k))) + 12k + S(ceil(n/2^k))
+ <= 10*(2 ceil(n/4) + k) + 12k + S(ceil(n/2^k))
+ <= 20 ceil(n/4) + 22k + S(ceil(n/2^k))
+*/
+
+mp_size_t
+mpn_hgcd_itch (mp_size_t n)
+{
+ unsigned k;
+ int count;
+ mp_size_t nscaled;
+
+ if (BELOW_THRESHOLD (n, HGCD_THRESHOLD))
+ return n;
+
+ /* Get the recursion depth. */
+ nscaled = (n - 1) / (HGCD_THRESHOLD - 1);
+ count_leading_zeros (count, nscaled);
+ k = GMP_LIMB_BITS - count;
+
+ return 20 * ((n+3) / 4) + 22 * k + HGCD_THRESHOLD;
+}
+
+/* Reduces a,b until |a-b| fits in n/2 + 1 limbs. Constructs matrix M
+ with elements of size at most (n+1)/2 - 1. Returns new size of a,
+ b, or zero if no reduction is possible. */
+
+mp_size_t
+mpn_hgcd (mp_ptr ap, mp_ptr bp, mp_size_t n,
+ struct hgcd_matrix *M, mp_ptr tp)
+{
+ mp_size_t s = n/2 + 1;
+
+ mp_size_t nn;
+ int success = 0;
+
+ if (n <= s)
+ /* Happens when n <= 2, a fairly uninteresting case but exercised
+ by the random inputs of the testsuite. */
+ return 0;
+
+ ASSERT ((ap[n-1] | bp[n-1]) > 0);
+
+ ASSERT ((n+1)/2 - 1 < M->alloc);
+
+ if (ABOVE_THRESHOLD (n, HGCD_THRESHOLD))
+ {
+ mp_size_t n2 = (3*n)/4 + 1;
+ mp_size_t p = n/2;
+
+ nn = mpn_hgcd_reduce (M, ap, bp, n, p, tp);
+ if (nn)
+ {
+ n = nn;
+ success = 1;
+ }
+
+ /* NOTE: It appears this loop never runs more than once (at
+ least when not recursing to hgcd_appr). */
+ while (n > n2)
+ {
+ /* Needs n + 1 storage */
+ nn = mpn_hgcd_step (n, ap, bp, s, M, tp);
+ if (!nn)
+ return success ? n : 0;
+
+ n = nn;
+ success = 1;
+ }
+
+ if (n > s + 2)
+ {
+ struct hgcd_matrix M1;
+ mp_size_t scratch;
+
+ p = 2*s - n + 1;
+ scratch = MPN_HGCD_MATRIX_INIT_ITCH (n-p);
+
+ mpn_hgcd_matrix_init(&M1, n - p, tp);
+
+ /* FIXME: Should use hgcd_reduce, but that may require more
+ scratch space, which requires review. */
+
+ nn = mpn_hgcd (ap + p, bp + p, n - p, &M1, tp + scratch);
+ if (nn > 0)
+ {
+ /* We always have max(M) > 2^{-(GMP_NUMB_BITS + 1)} max(M1) */
+ ASSERT (M->n + 2 >= M1.n);
+
+ /* Furthermore, assume M ends with a quotient (1, q; 0, 1),
+ then either q or q + 1 is a correct quotient, and M1 will
+ start with either (1, 0; 1, 1) or (2, 1; 1, 1). This
+ rules out the case that the size of M * M1 is much
+ smaller than the expected M->n + M1->n. */
+
+ ASSERT (M->n + M1.n < M->alloc);
+
+ /* Needs 2 (p + M->n) <= 2 (2*s - n2 + 1 + n2 - s - 1)
+ = 2*s <= 2*(floor(n/2) + 1) <= n + 2. */
+ n = mpn_hgcd_matrix_adjust (&M1, p + nn, ap, bp, p, tp + scratch);
+
+ /* We need a bound for of M->n + M1.n. Let n be the original
+ input size. Then
+
+ ceil(n/2) - 1 >= size of product >= M.n + M1.n - 2
+
+ and it follows that
+
+ M.n + M1.n <= ceil(n/2) + 1
+
+ Then 3*(M.n + M1.n) + 5 <= 3 * ceil(n/2) + 8 is the
+ amount of needed scratch space. */
+ mpn_hgcd_matrix_mul (M, &M1, tp + scratch);
+ success = 1;
+ }
+ }
+ }
+
+ for (;;)
+ {
+ /* Needs s+3 < n */
+ nn = mpn_hgcd_step (n, ap, bp, s, M, tp);
+ if (!nn)
+ return success ? n : 0;
+
+ n = nn;
+ success = 1;
+ }
+}
diff --git a/gmp/mpn/generic/hgcd2.c b/gmp/mpn/generic/hgcd2.c
new file mode 100644
index 0000000000..129637063f
--- /dev/null
+++ b/gmp/mpn/generic/hgcd2.c
@@ -0,0 +1,447 @@
+/* hgcd2.c
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 1996, 1998, 2000-2004, 2008, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#if GMP_NAIL_BITS == 0
+
+/* Copied from the old mpn/generic/gcdext.c, and modified slightly to return
+ the remainder. */
+
+/* Single-limb division optimized for small quotients. */
+static inline mp_limb_t
+div1 (mp_ptr rp,
+ mp_limb_t n0,
+ mp_limb_t d0)
+{
+ mp_limb_t q = 0;
+
+ if ((mp_limb_signed_t) n0 < 0)
+ {
+ int cnt;
+ for (cnt = 1; (mp_limb_signed_t) d0 >= 0; cnt++)
+ {
+ d0 = d0 << 1;
+ }
+
+ q = 0;
+ while (cnt)
+ {
+ q <<= 1;
+ if (n0 >= d0)
+ {
+ n0 = n0 - d0;
+ q |= 1;
+ }
+ d0 = d0 >> 1;
+ cnt--;
+ }
+ }
+ else
+ {
+ int cnt;
+ for (cnt = 0; n0 >= d0; cnt++)
+ {
+ d0 = d0 << 1;
+ }
+
+ q = 0;
+ while (cnt)
+ {
+ d0 = d0 >> 1;
+ q <<= 1;
+ if (n0 >= d0)
+ {
+ n0 = n0 - d0;
+ q |= 1;
+ }
+ cnt--;
+ }
+ }
+ *rp = n0;
+ return q;
+}
+
+/* Two-limb division optimized for small quotients. */
+static inline mp_limb_t
+div2 (mp_ptr rp,
+ mp_limb_t nh, mp_limb_t nl,
+ mp_limb_t dh, mp_limb_t dl)
+{
+ mp_limb_t q = 0;
+
+ if ((mp_limb_signed_t) nh < 0)
+ {
+ int cnt;
+ for (cnt = 1; (mp_limb_signed_t) dh >= 0; cnt++)
+ {
+ dh = (dh << 1) | (dl >> (GMP_LIMB_BITS - 1));
+ dl = dl << 1;
+ }
+
+ while (cnt)
+ {
+ q <<= 1;
+ if (nh > dh || (nh == dh && nl >= dl))
+ {
+ sub_ddmmss (nh, nl, nh, nl, dh, dl);
+ q |= 1;
+ }
+ dl = (dh << (GMP_LIMB_BITS - 1)) | (dl >> 1);
+ dh = dh >> 1;
+ cnt--;
+ }
+ }
+ else
+ {
+ int cnt;
+ for (cnt = 0; nh > dh || (nh == dh && nl >= dl); cnt++)
+ {
+ dh = (dh << 1) | (dl >> (GMP_LIMB_BITS - 1));
+ dl = dl << 1;
+ }
+
+ while (cnt)
+ {
+ dl = (dh << (GMP_LIMB_BITS - 1)) | (dl >> 1);
+ dh = dh >> 1;
+ q <<= 1;
+ if (nh > dh || (nh == dh && nl >= dl))
+ {
+ sub_ddmmss (nh, nl, nh, nl, dh, dl);
+ q |= 1;
+ }
+ cnt--;
+ }
+ }
+
+ rp[0] = nl;
+ rp[1] = nh;
+
+ return q;
+}
+
+#if 0
+/* This div2 uses less branches, but it seems to nevertheless be
+ slightly slower than the above code. */
+static inline mp_limb_t
+div2 (mp_ptr rp,
+ mp_limb_t nh, mp_limb_t nl,
+ mp_limb_t dh, mp_limb_t dl)
+{
+ mp_limb_t q = 0;
+ int ncnt;
+ int dcnt;
+
+ count_leading_zeros (ncnt, nh);
+ count_leading_zeros (dcnt, dh);
+ dcnt -= ncnt;
+
+ dh = (dh << dcnt) + (-(dcnt > 0) & (dl >> (GMP_LIMB_BITS - dcnt)));
+ dl <<= dcnt;
+
+ do
+ {
+ mp_limb_t bit;
+ q <<= 1;
+ if (UNLIKELY (nh == dh))
+ bit = (nl >= dl);
+ else
+ bit = (nh > dh);
+
+ q |= bit;
+
+ sub_ddmmss (nh, nl, nh, nl, (-bit) & dh, (-bit) & dl);
+
+ dl = (dh << (GMP_LIMB_BITS - 1)) | (dl >> 1);
+ dh = dh >> 1;
+ }
+ while (dcnt--);
+
+ rp[0] = nl;
+ rp[1] = nh;
+
+ return q;
+}
+#endif
+
+#else /* GMP_NAIL_BITS != 0 */
+/* Check all functions for nail support. */
+/* hgcd2 should be defined to take inputs including nail bits, and
+ produce a matrix with elements also including nail bits. This is
+ necessary, for the matrix elements to be useful with mpn_mul_1,
+ mpn_addmul_1 and friends. */
+#error Not implemented
+#endif /* GMP_NAIL_BITS != 0 */
+
+/* Reduces a,b until |a-b| (almost) fits in one limb + 1 bit. Constructs
+ matrix M. Returns 1 if we make progress, i.e. can perform at least
+ one subtraction. Otherwise returns zero. */
+
+/* FIXME: Possible optimizations:
+
+ The div2 function starts with checking the most significant bit of
+ the numerator. We can maintained normalized operands here, call
+ hgcd with normalized operands only, which should make the code
+ simpler and possibly faster.
+
+ Experiment with table lookups on the most significant bits.
+
+ This function is also a candidate for assembler implementation.
+*/
+int
+mpn_hgcd2 (mp_limb_t ah, mp_limb_t al, mp_limb_t bh, mp_limb_t bl,
+ struct hgcd_matrix1 *M)
+{
+ mp_limb_t u00, u01, u10, u11;
+
+ if (ah < 2 || bh < 2)
+ return 0;
+
+ if (ah > bh || (ah == bh && al > bl))
+ {
+ sub_ddmmss (ah, al, ah, al, bh, bl);
+ if (ah < 2)
+ return 0;
+
+ u00 = u01 = u11 = 1;
+ u10 = 0;
+ }
+ else
+ {
+ sub_ddmmss (bh, bl, bh, bl, ah, al);
+ if (bh < 2)
+ return 0;
+
+ u00 = u10 = u11 = 1;
+ u01 = 0;
+ }
+
+ if (ah < bh)
+ goto subtract_a;
+
+ for (;;)
+ {
+ ASSERT (ah >= bh);
+ if (ah == bh)
+ goto done;
+
+ if (ah < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2)))
+ {
+ ah = (ah << (GMP_LIMB_BITS / 2) ) + (al >> (GMP_LIMB_BITS / 2));
+ bh = (bh << (GMP_LIMB_BITS / 2) ) + (bl >> (GMP_LIMB_BITS / 2));
+
+ break;
+ }
+
+ /* Subtract a -= q b, and multiply M from the right by (1 q ; 0
+ 1), affecting the second column of M. */
+ ASSERT (ah > bh);
+ sub_ddmmss (ah, al, ah, al, bh, bl);
+
+ if (ah < 2)
+ goto done;
+
+ if (ah <= bh)
+ {
+ /* Use q = 1 */
+ u01 += u00;
+ u11 += u10;
+ }
+ else
+ {
+ mp_limb_t r[2];
+ mp_limb_t q = div2 (r, ah, al, bh, bl);
+ al = r[0]; ah = r[1];
+ if (ah < 2)
+ {
+ /* A is too small, but q is correct. */
+ u01 += q * u00;
+ u11 += q * u10;
+ goto done;
+ }
+ q++;
+ u01 += q * u00;
+ u11 += q * u10;
+ }
+ subtract_a:
+ ASSERT (bh >= ah);
+ if (ah == bh)
+ goto done;
+
+ if (bh < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2)))
+ {
+ ah = (ah << (GMP_LIMB_BITS / 2) ) + (al >> (GMP_LIMB_BITS / 2));
+ bh = (bh << (GMP_LIMB_BITS / 2) ) + (bl >> (GMP_LIMB_BITS / 2));
+
+ goto subtract_a1;
+ }
+
+ /* Subtract b -= q a, and multiply M from the right by (1 0 ; q
+ 1), affecting the first column of M. */
+ sub_ddmmss (bh, bl, bh, bl, ah, al);
+
+ if (bh < 2)
+ goto done;
+
+ if (bh <= ah)
+ {
+ /* Use q = 1 */
+ u00 += u01;
+ u10 += u11;
+ }
+ else
+ {
+ mp_limb_t r[2];
+ mp_limb_t q = div2 (r, bh, bl, ah, al);
+ bl = r[0]; bh = r[1];
+ if (bh < 2)
+ {
+ /* B is too small, but q is correct. */
+ u00 += q * u01;
+ u10 += q * u11;
+ goto done;
+ }
+ q++;
+ u00 += q * u01;
+ u10 += q * u11;
+ }
+ }
+
+ /* NOTE: Since we discard the least significant half limb, we don't
+ get a truly maximal M (corresponding to |a - b| <
+ 2^{GMP_LIMB_BITS +1}). */
+ /* Single precision loop */
+ for (;;)
+ {
+ ASSERT (ah >= bh);
+
+ ah -= bh;
+ if (ah < (CNST_LIMB (1) << (GMP_LIMB_BITS / 2 + 1)))
+ break;
+
+ if (ah <= bh)
+ {
+ /* Use q = 1 */
+ u01 += u00;
+ u11 += u10;
+ }
+ else
+ {
+ mp_limb_t r;
+ mp_limb_t q = div1 (&r, ah, bh);
+ ah = r;
+ if (ah < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2 + 1)))
+ {
+ /* A is too small, but q is correct. */
+ u01 += q * u00;
+ u11 += q * u10;
+ break;
+ }
+ q++;
+ u01 += q * u00;
+ u11 += q * u10;
+ }
+ subtract_a1:
+ ASSERT (bh >= ah);
+
+ bh -= ah;
+ if (bh < (CNST_LIMB (1) << (GMP_LIMB_BITS / 2 + 1)))
+ break;
+
+ if (bh <= ah)
+ {
+ /* Use q = 1 */
+ u00 += u01;
+ u10 += u11;
+ }
+ else
+ {
+ mp_limb_t r;
+ mp_limb_t q = div1 (&r, bh, ah);
+ bh = r;
+ if (bh < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2 + 1)))
+ {
+ /* B is too small, but q is correct. */
+ u00 += q * u01;
+ u10 += q * u11;
+ break;
+ }
+ q++;
+ u00 += q * u01;
+ u10 += q * u11;
+ }
+ }
+
+ done:
+ M->u[0][0] = u00; M->u[0][1] = u01;
+ M->u[1][0] = u10; M->u[1][1] = u11;
+
+ return 1;
+}
+
+/* Sets (r;b) = (a;b) M, with M = (u00, u01; u10, u11). Vector must
+ * have space for n + 1 limbs. Uses three buffers to avoid a copy*/
+mp_size_t
+mpn_hgcd_mul_matrix1_vector (const struct hgcd_matrix1 *M,
+ mp_ptr rp, mp_srcptr ap, mp_ptr bp, mp_size_t n)
+{
+ mp_limb_t ah, bh;
+
+ /* Compute (r,b) <-- (u00 a + u10 b, u01 a + u11 b) as
+
+ r = u00 * a
+ r += u10 * b
+ b *= u11
+ b += u01 * a
+ */
+
+#if HAVE_NATIVE_mpn_addaddmul_1msb0
+ ah = mpn_addaddmul_1msb0 (rp, ap, bp, n, M->u[0][0], M->u[1][0]);
+ bh = mpn_addaddmul_1msb0 (bp, bp, ap, n, M->u[1][1], M->u[0][1]);
+#else
+ ah = mpn_mul_1 (rp, ap, n, M->u[0][0]);
+ ah += mpn_addmul_1 (rp, bp, n, M->u[1][0]);
+
+ bh = mpn_mul_1 (bp, bp, n, M->u[1][1]);
+ bh += mpn_addmul_1 (bp, ap, n, M->u[0][1]);
+#endif
+ rp[n] = ah;
+ bp[n] = bh;
+
+ n += (ah | bh) > 0;
+ return n;
+}
diff --git a/gmp/mpn/generic/hgcd2_jacobi.c b/gmp/mpn/generic/hgcd2_jacobi.c
new file mode 100644
index 0000000000..e59c32a341
--- /dev/null
+++ b/gmp/mpn/generic/hgcd2_jacobi.c
@@ -0,0 +1,366 @@
+/* hgcd2_jacobi.c
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 1996, 1998, 2000-2004, 2008, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#if GMP_NAIL_BITS > 0
+#error Nails not supported.
+#endif
+
+/* FIXME: Duplicated in hgcd2.c. Should move to gmp-impl.h, and
+ possibly be renamed. */
+static inline mp_limb_t
+div1 (mp_ptr rp,
+ mp_limb_t n0,
+ mp_limb_t d0)
+{
+ mp_limb_t q = 0;
+
+ if ((mp_limb_signed_t) n0 < 0)
+ {
+ int cnt;
+ for (cnt = 1; (mp_limb_signed_t) d0 >= 0; cnt++)
+ {
+ d0 = d0 << 1;
+ }
+
+ q = 0;
+ while (cnt)
+ {
+ q <<= 1;
+ if (n0 >= d0)
+ {
+ n0 = n0 - d0;
+ q |= 1;
+ }
+ d0 = d0 >> 1;
+ cnt--;
+ }
+ }
+ else
+ {
+ int cnt;
+ for (cnt = 0; n0 >= d0; cnt++)
+ {
+ d0 = d0 << 1;
+ }
+
+ q = 0;
+ while (cnt)
+ {
+ d0 = d0 >> 1;
+ q <<= 1;
+ if (n0 >= d0)
+ {
+ n0 = n0 - d0;
+ q |= 1;
+ }
+ cnt--;
+ }
+ }
+ *rp = n0;
+ return q;
+}
+
+/* Two-limb division optimized for small quotients. */
+static inline mp_limb_t
+div2 (mp_ptr rp,
+ mp_limb_t nh, mp_limb_t nl,
+ mp_limb_t dh, mp_limb_t dl)
+{
+ mp_limb_t q = 0;
+
+ if ((mp_limb_signed_t) nh < 0)
+ {
+ int cnt;
+ for (cnt = 1; (mp_limb_signed_t) dh >= 0; cnt++)
+ {
+ dh = (dh << 1) | (dl >> (GMP_LIMB_BITS - 1));
+ dl = dl << 1;
+ }
+
+ while (cnt)
+ {
+ q <<= 1;
+ if (nh > dh || (nh == dh && nl >= dl))
+ {
+ sub_ddmmss (nh, nl, nh, nl, dh, dl);
+ q |= 1;
+ }
+ dl = (dh << (GMP_LIMB_BITS - 1)) | (dl >> 1);
+ dh = dh >> 1;
+ cnt--;
+ }
+ }
+ else
+ {
+ int cnt;
+ for (cnt = 0; nh > dh || (nh == dh && nl >= dl); cnt++)
+ {
+ dh = (dh << 1) | (dl >> (GMP_LIMB_BITS - 1));
+ dl = dl << 1;
+ }
+
+ while (cnt)
+ {
+ dl = (dh << (GMP_LIMB_BITS - 1)) | (dl >> 1);
+ dh = dh >> 1;
+ q <<= 1;
+ if (nh > dh || (nh == dh && nl >= dl))
+ {
+ sub_ddmmss (nh, nl, nh, nl, dh, dl);
+ q |= 1;
+ }
+ cnt--;
+ }
+ }
+
+ rp[0] = nl;
+ rp[1] = nh;
+
+ return q;
+}
+
+int
+mpn_hgcd2_jacobi (mp_limb_t ah, mp_limb_t al, mp_limb_t bh, mp_limb_t bl,
+ struct hgcd_matrix1 *M, unsigned *bitsp)
+{
+ mp_limb_t u00, u01, u10, u11;
+ unsigned bits = *bitsp;
+
+ if (ah < 2 || bh < 2)
+ return 0;
+
+ if (ah > bh || (ah == bh && al > bl))
+ {
+ sub_ddmmss (ah, al, ah, al, bh, bl);
+ if (ah < 2)
+ return 0;
+
+ u00 = u01 = u11 = 1;
+ u10 = 0;
+ bits = mpn_jacobi_update (bits, 1, 1);
+ }
+ else
+ {
+ sub_ddmmss (bh, bl, bh, bl, ah, al);
+ if (bh < 2)
+ return 0;
+
+ u00 = u10 = u11 = 1;
+ u01 = 0;
+ bits = mpn_jacobi_update (bits, 0, 1);
+ }
+
+ if (ah < bh)
+ goto subtract_a;
+
+ for (;;)
+ {
+ ASSERT (ah >= bh);
+ if (ah == bh)
+ goto done;
+
+ if (ah < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2)))
+ {
+ ah = (ah << (GMP_LIMB_BITS / 2) ) + (al >> (GMP_LIMB_BITS / 2));
+ bh = (bh << (GMP_LIMB_BITS / 2) ) + (bl >> (GMP_LIMB_BITS / 2));
+
+ break;
+ }
+
+ /* Subtract a -= q b, and multiply M from the right by (1 q ; 0
+ 1), affecting the second column of M. */
+ ASSERT (ah > bh);
+ sub_ddmmss (ah, al, ah, al, bh, bl);
+
+ if (ah < 2)
+ goto done;
+
+ if (ah <= bh)
+ {
+ /* Use q = 1 */
+ u01 += u00;
+ u11 += u10;
+ bits = mpn_jacobi_update (bits, 1, 1);
+ }
+ else
+ {
+ mp_limb_t r[2];
+ mp_limb_t q = div2 (r, ah, al, bh, bl);
+ al = r[0]; ah = r[1];
+ if (ah < 2)
+ {
+ /* A is too small, but q is correct. */
+ u01 += q * u00;
+ u11 += q * u10;
+ bits = mpn_jacobi_update (bits, 1, q & 3);
+ goto done;
+ }
+ q++;
+ u01 += q * u00;
+ u11 += q * u10;
+ bits = mpn_jacobi_update (bits, 1, q & 3);
+ }
+ subtract_a:
+ ASSERT (bh >= ah);
+ if (ah == bh)
+ goto done;
+
+ if (bh < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2)))
+ {
+ ah = (ah << (GMP_LIMB_BITS / 2) ) + (al >> (GMP_LIMB_BITS / 2));
+ bh = (bh << (GMP_LIMB_BITS / 2) ) + (bl >> (GMP_LIMB_BITS / 2));
+
+ goto subtract_a1;
+ }
+
+ /* Subtract b -= q a, and multiply M from the right by (1 0 ; q
+ 1), affecting the first column of M. */
+ sub_ddmmss (bh, bl, bh, bl, ah, al);
+
+ if (bh < 2)
+ goto done;
+
+ if (bh <= ah)
+ {
+ /* Use q = 1 */
+ u00 += u01;
+ u10 += u11;
+ bits = mpn_jacobi_update (bits, 0, 1);
+ }
+ else
+ {
+ mp_limb_t r[2];
+ mp_limb_t q = div2 (r, bh, bl, ah, al);
+ bl = r[0]; bh = r[1];
+ if (bh < 2)
+ {
+ /* B is too small, but q is correct. */
+ u00 += q * u01;
+ u10 += q * u11;
+ bits = mpn_jacobi_update (bits, 0, q & 3);
+ goto done;
+ }
+ q++;
+ u00 += q * u01;
+ u10 += q * u11;
+ bits = mpn_jacobi_update (bits, 0, q & 3);
+ }
+ }
+
+ /* NOTE: Since we discard the least significant half limb, we don't
+ get a truly maximal M (corresponding to |a - b| <
+ 2^{GMP_LIMB_BITS +1}). */
+ /* Single precision loop */
+ for (;;)
+ {
+ ASSERT (ah >= bh);
+ if (ah == bh)
+ break;
+
+ ah -= bh;
+ if (ah < (CNST_LIMB (1) << (GMP_LIMB_BITS / 2 + 1)))
+ break;
+
+ if (ah <= bh)
+ {
+ /* Use q = 1 */
+ u01 += u00;
+ u11 += u10;
+ bits = mpn_jacobi_update (bits, 1, 1);
+ }
+ else
+ {
+ mp_limb_t r;
+ mp_limb_t q = div1 (&r, ah, bh);
+ ah = r;
+ if (ah < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2 + 1)))
+ {
+ /* A is too small, but q is correct. */
+ u01 += q * u00;
+ u11 += q * u10;
+ bits = mpn_jacobi_update (bits, 1, q & 3);
+ break;
+ }
+ q++;
+ u01 += q * u00;
+ u11 += q * u10;
+ bits = mpn_jacobi_update (bits, 1, q & 3);
+ }
+ subtract_a1:
+ ASSERT (bh >= ah);
+ if (ah == bh)
+ break;
+
+ bh -= ah;
+ if (bh < (CNST_LIMB (1) << (GMP_LIMB_BITS / 2 + 1)))
+ break;
+
+ if (bh <= ah)
+ {
+ /* Use q = 1 */
+ u00 += u01;
+ u10 += u11;
+ bits = mpn_jacobi_update (bits, 0, 1);
+ }
+ else
+ {
+ mp_limb_t r;
+ mp_limb_t q = div1 (&r, bh, ah);
+ bh = r;
+ if (bh < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2 + 1)))
+ {
+ /* B is too small, but q is correct. */
+ u00 += q * u01;
+ u10 += q * u11;
+ bits = mpn_jacobi_update (bits, 0, q & 3);
+ break;
+ }
+ q++;
+ u00 += q * u01;
+ u10 += q * u11;
+ bits = mpn_jacobi_update (bits, 0, q & 3);
+ }
+ }
+
+ done:
+ M->u[0][0] = u00; M->u[0][1] = u01;
+ M->u[1][0] = u10; M->u[1][1] = u11;
+ *bitsp = bits;
+
+ return 1;
+}
diff --git a/gmp/mpn/generic/hgcd_appr.c b/gmp/mpn/generic/hgcd_appr.c
new file mode 100644
index 0000000000..660219372f
--- /dev/null
+++ b/gmp/mpn/generic/hgcd_appr.c
@@ -0,0 +1,268 @@
+/* hgcd_appr.c.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Identical to mpn_hgcd_itch. FIXME: Do we really need to add
+ HGCD_THRESHOLD at the end? */
+mp_size_t
+mpn_hgcd_appr_itch (mp_size_t n)
+{
+ if (BELOW_THRESHOLD (n, HGCD_APPR_THRESHOLD))
+ return n;
+ else
+ {
+ unsigned k;
+ int count;
+ mp_size_t nscaled;
+
+ /* Get the recursion depth. */
+ nscaled = (n - 1) / (HGCD_APPR_THRESHOLD - 1);
+ count_leading_zeros (count, nscaled);
+ k = GMP_LIMB_BITS - count;
+
+ return 20 * ((n+3) / 4) + 22 * k + HGCD_THRESHOLD;
+ }
+}
+
+/* Destroys inputs. */
+int
+mpn_hgcd_appr (mp_ptr ap, mp_ptr bp, mp_size_t n,
+ struct hgcd_matrix *M, mp_ptr tp)
+{
+ mp_size_t s;
+ int success = 0;
+
+ ASSERT (n > 0);
+
+ ASSERT ((ap[n-1] | bp[n-1]) != 0);
+
+ if (n <= 2)
+ /* Implies s = n. A fairly uninteresting case but exercised by the
+ random inputs of the testsuite. */
+ return 0;
+
+ ASSERT ((n+1)/2 - 1 < M->alloc);
+
+ /* We aim for reduction of to GMP_NUMB_BITS * s bits. But each time
+ we discard some of the least significant limbs, we must keep one
+ additional bit to account for the truncation error. We maintain
+ the GMP_NUMB_BITS * s - extra_bits as the current target size. */
+
+ s = n/2 + 1;
+ if (BELOW_THRESHOLD (n, HGCD_APPR_THRESHOLD))
+ {
+ unsigned extra_bits = 0;
+
+ while (n > 2)
+ {
+ mp_size_t nn;
+
+ ASSERT (n > s);
+ ASSERT (n <= 2*s);
+
+ nn = mpn_hgcd_step (n, ap, bp, s, M, tp);
+ if (!nn)
+ break;
+
+ n = nn;
+ success = 1;
+
+ /* We can truncate and discard the lower p bits whenever nbits <=
+ 2*sbits - p. To account for the truncation error, we must
+ adjust
+
+ sbits <-- sbits + 1 - p,
+
+ rather than just sbits <-- sbits - p. This adjustment makes
+ the produced matrix slightly smaller than it could be. */
+
+ if (GMP_NUMB_BITS * (n + 1) + 2 * extra_bits <= 2*GMP_NUMB_BITS * s)
+ {
+ mp_size_t p = (GMP_NUMB_BITS * (2*s - n) - 2*extra_bits) / GMP_NUMB_BITS;
+
+ if (extra_bits == 0)
+ {
+ /* We cross a limb boundary and bump s. We can't do that
+ if the result is that it makes makes min(U, V)
+ smaller than 2^{GMP_NUMB_BITS} s. */
+ if (s + 1 == n
+ || mpn_zero_p (ap + s + 1, n - s - 1)
+ || mpn_zero_p (bp + s + 1, n - s - 1))
+ continue;
+
+ extra_bits = GMP_NUMB_BITS - 1;
+ s++;
+ }
+ else
+ {
+ extra_bits--;
+ }
+
+ /* Drop the p least significant limbs */
+ ap += p; bp += p; n -= p; s -= p;
+ }
+ }
+
+ ASSERT (s > 0);
+
+ if (extra_bits > 0)
+ {
+ /* We can get here only of we have dropped at least one of the least
+ significant bits, so we can decrement ap and bp. We can then shift
+ left extra bits using mpn_rshift. */
+ /* NOTE: In the unlikely case that n is large, it would be preferable
+ to do an initial subdiv step to reduce the size before shifting,
+ but that would mean duplicating mpn_gcd_subdiv_step with a bit
+ count rather than a limb count. */
+ ap--; bp--;
+ ap[0] = mpn_rshift (ap+1, ap+1, n, GMP_NUMB_BITS - extra_bits);
+ bp[0] = mpn_rshift (bp+1, bp+1, n, GMP_NUMB_BITS - extra_bits);
+ n += (ap[n] | bp[n]) > 0;
+
+ ASSERT (success);
+
+ while (n > 2)
+ {
+ mp_size_t nn;
+
+ ASSERT (n > s);
+ ASSERT (n <= 2*s);
+
+ nn = mpn_hgcd_step (n, ap, bp, s, M, tp);
+
+ if (!nn)
+ return 1;
+
+ n = nn;
+ }
+ }
+
+ if (n == 2)
+ {
+ struct hgcd_matrix1 M1;
+ ASSERT (s == 1);
+
+ if (mpn_hgcd2 (ap[1], ap[0], bp[1], bp[0], &M1))
+ {
+ /* Multiply M <- M * M1 */
+ mpn_hgcd_matrix_mul_1 (M, &M1, tp);
+ success = 1;
+ }
+ }
+ return success;
+ }
+ else
+ {
+ mp_size_t n2 = (3*n)/4 + 1;
+ mp_size_t p = n/2;
+ mp_size_t nn;
+
+ nn = mpn_hgcd_reduce (M, ap, bp, n, p, tp);
+ if (nn)
+ {
+ n = nn;
+ /* FIXME: Discard some of the low limbs immediately? */
+ success = 1;
+ }
+
+ while (n > n2)
+ {
+ mp_size_t nn;
+
+ /* Needs n + 1 storage */
+ nn = mpn_hgcd_step (n, ap, bp, s, M, tp);
+ if (!nn)
+ return success;
+
+ n = nn;
+ success = 1;
+ }
+ if (n > s + 2)
+ {
+ struct hgcd_matrix M1;
+ mp_size_t scratch;
+
+ p = 2*s - n + 1;
+ scratch = MPN_HGCD_MATRIX_INIT_ITCH (n-p);
+
+ mpn_hgcd_matrix_init(&M1, n - p, tp);
+ if (mpn_hgcd_appr (ap + p, bp + p, n - p, &M1, tp + scratch))
+ {
+ /* We always have max(M) > 2^{-(GMP_NUMB_BITS + 1)} max(M1) */
+ ASSERT (M->n + 2 >= M1.n);
+
+ /* Furthermore, assume M ends with a quotient (1, q; 0, 1),
+ then either q or q + 1 is a correct quotient, and M1 will
+ start with either (1, 0; 1, 1) or (2, 1; 1, 1). This
+ rules out the case that the size of M * M1 is much
+ smaller than the expected M->n + M1->n. */
+
+ ASSERT (M->n + M1.n < M->alloc);
+
+ /* We need a bound for of M->n + M1.n. Let n be the original
+ input size. Then
+
+ ceil(n/2) - 1 >= size of product >= M.n + M1.n - 2
+
+ and it follows that
+
+ M.n + M1.n <= ceil(n/2) + 1
+
+ Then 3*(M.n + M1.n) + 5 <= 3 * ceil(n/2) + 8 is the
+ amount of needed scratch space. */
+ mpn_hgcd_matrix_mul (M, &M1, tp + scratch);
+ return 1;
+ }
+ }
+
+ for(;;)
+ {
+ mp_size_t nn;
+
+ ASSERT (n > s);
+ ASSERT (n <= 2*s);
+
+ nn = mpn_hgcd_step (n, ap, bp, s, M, tp);
+
+ if (!nn)
+ return success;
+
+ n = nn;
+ success = 1;
+ }
+ }
+}
diff --git a/gmp/mpn/generic/hgcd_jacobi.c b/gmp/mpn/generic/hgcd_jacobi.c
new file mode 100644
index 0000000000..0a49e5b3a7
--- /dev/null
+++ b/gmp/mpn/generic/hgcd_jacobi.c
@@ -0,0 +1,244 @@
+/* hgcd_jacobi.c.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2003-2005, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* This file is almost a copy of hgcd.c, with some added calls to
+ mpn_jacobi_update */
+
+struct hgcd_jacobi_ctx
+{
+ struct hgcd_matrix *M;
+ unsigned *bitsp;
+};
+
+static void
+hgcd_jacobi_hook (void *p, mp_srcptr gp, mp_size_t gn,
+ mp_srcptr qp, mp_size_t qn, int d)
+{
+ ASSERT (!gp);
+ ASSERT (d >= 0);
+
+ MPN_NORMALIZE (qp, qn);
+ if (qn > 0)
+ {
+ struct hgcd_jacobi_ctx *ctx = (struct hgcd_jacobi_ctx *) p;
+ /* NOTES: This is a bit ugly. A tp area is passed to
+ gcd_subdiv_step, which stores q at the start of that area. We
+ now use the rest. */
+ mp_ptr tp = (mp_ptr) qp + qn;
+
+ mpn_hgcd_matrix_update_q (ctx->M, qp, qn, d, tp);
+ *ctx->bitsp = mpn_jacobi_update (*ctx->bitsp, d, qp[0] & 3);
+ }
+}
+
+/* Perform a few steps, using some of mpn_hgcd2, subtraction and
+ division. Reduces the size by almost one limb or more, but never
+ below the given size s. Return new size for a and b, or 0 if no
+ more steps are possible.
+
+ If hgcd2 succeeds, needs temporary space for hgcd_matrix_mul_1, M->n
+ limbs, and hgcd_mul_matrix1_inverse_vector, n limbs. If hgcd2
+ fails, needs space for the quotient, qn <= n - s + 1 limbs, for and
+ hgcd_matrix_update_q, qn + (size of the appropriate column of M) <=
+ resulting size of M.
+
+ If N is the input size to the calling hgcd, then s = floor(N/2) +
+ 1, M->n < N, qn + matrix size <= n - s + 1 + n - s = 2 (n - s) + 1
+ < N, so N is sufficient.
+*/
+
+static mp_size_t
+hgcd_jacobi_step (mp_size_t n, mp_ptr ap, mp_ptr bp, mp_size_t s,
+ struct hgcd_matrix *M, unsigned *bitsp, mp_ptr tp)
+{
+ struct hgcd_matrix1 M1;
+ mp_limb_t mask;
+ mp_limb_t ah, al, bh, bl;
+
+ ASSERT (n > s);
+
+ mask = ap[n-1] | bp[n-1];
+ ASSERT (mask > 0);
+
+ if (n == s + 1)
+ {
+ if (mask < 4)
+ goto subtract;
+
+ ah = ap[n-1]; al = ap[n-2];
+ bh = bp[n-1]; bl = bp[n-2];
+ }
+ else if (mask & GMP_NUMB_HIGHBIT)
+ {
+ ah = ap[n-1]; al = ap[n-2];
+ bh = bp[n-1]; bl = bp[n-2];
+ }
+ else
+ {
+ int shift;
+
+ count_leading_zeros (shift, mask);
+ ah = MPN_EXTRACT_NUMB (shift, ap[n-1], ap[n-2]);
+ al = MPN_EXTRACT_NUMB (shift, ap[n-2], ap[n-3]);
+ bh = MPN_EXTRACT_NUMB (shift, bp[n-1], bp[n-2]);
+ bl = MPN_EXTRACT_NUMB (shift, bp[n-2], bp[n-3]);
+ }
+
+ /* Try an mpn_hgcd2 step */
+ if (mpn_hgcd2_jacobi (ah, al, bh, bl, &M1, bitsp))
+ {
+ /* Multiply M <- M * M1 */
+ mpn_hgcd_matrix_mul_1 (M, &M1, tp);
+
+ /* Can't swap inputs, so we need to copy. */
+ MPN_COPY (tp, ap, n);
+ /* Multiply M1^{-1} (a;b) */
+ return mpn_matrix22_mul1_inverse_vector (&M1, ap, tp, bp, n);
+ }
+
+ subtract:
+ {
+ struct hgcd_jacobi_ctx ctx;
+ ctx.M = M;
+ ctx.bitsp = bitsp;
+
+ return mpn_gcd_subdiv_step (ap, bp, n, s, hgcd_jacobi_hook, &ctx, tp);
+ }
+}
+
+/* Reduces a,b until |a-b| fits in n/2 + 1 limbs. Constructs matrix M
+ with elements of size at most (n+1)/2 - 1. Returns new size of a,
+ b, or zero if no reduction is possible. */
+
+/* Same scratch requirements as for mpn_hgcd. */
+mp_size_t
+mpn_hgcd_jacobi (mp_ptr ap, mp_ptr bp, mp_size_t n,
+ struct hgcd_matrix *M, unsigned *bitsp, mp_ptr tp)
+{
+ mp_size_t s = n/2 + 1;
+
+ mp_size_t nn;
+ int success = 0;
+
+ if (n <= s)
+ /* Happens when n <= 2, a fairly uninteresting case but exercised
+ by the random inputs of the testsuite. */
+ return 0;
+
+ ASSERT ((ap[n-1] | bp[n-1]) > 0);
+
+ ASSERT ((n+1)/2 - 1 < M->alloc);
+
+ if (ABOVE_THRESHOLD (n, HGCD_THRESHOLD))
+ {
+ mp_size_t n2 = (3*n)/4 + 1;
+ mp_size_t p = n/2;
+
+ nn = mpn_hgcd_jacobi (ap + p, bp + p, n - p, M, bitsp, tp);
+ if (nn > 0)
+ {
+ /* Needs 2*(p + M->n) <= 2*(floor(n/2) + ceil(n/2) - 1)
+ = 2 (n - 1) */
+ n = mpn_hgcd_matrix_adjust (M, p + nn, ap, bp, p, tp);
+ success = 1;
+ }
+ while (n > n2)
+ {
+ /* Needs n + 1 storage */
+ nn = hgcd_jacobi_step (n, ap, bp, s, M, bitsp, tp);
+ if (!nn)
+ return success ? n : 0;
+ n = nn;
+ success = 1;
+ }
+
+ if (n > s + 2)
+ {
+ struct hgcd_matrix M1;
+ mp_size_t scratch;
+
+ p = 2*s - n + 1;
+ scratch = MPN_HGCD_MATRIX_INIT_ITCH (n-p);
+
+ mpn_hgcd_matrix_init(&M1, n - p, tp);
+ nn = mpn_hgcd_jacobi (ap + p, bp + p, n - p, &M1, bitsp, tp + scratch);
+ if (nn > 0)
+ {
+ /* We always have max(M) > 2^{-(GMP_NUMB_BITS + 1)} max(M1) */
+ ASSERT (M->n + 2 >= M1.n);
+
+ /* Furthermore, assume M ends with a quotient (1, q; 0, 1),
+ then either q or q + 1 is a correct quotient, and M1 will
+ start with either (1, 0; 1, 1) or (2, 1; 1, 1). This
+ rules out the case that the size of M * M1 is much
+ smaller than the expected M->n + M1->n. */
+
+ ASSERT (M->n + M1.n < M->alloc);
+
+ /* Needs 2 (p + M->n) <= 2 (2*s - n2 + 1 + n2 - s - 1)
+ = 2*s <= 2*(floor(n/2) + 1) <= n + 2. */
+ n = mpn_hgcd_matrix_adjust (&M1, p + nn, ap, bp, p, tp + scratch);
+
+ /* We need a bound for of M->n + M1.n. Let n be the original
+ input size. Then
+
+ ceil(n/2) - 1 >= size of product >= M.n + M1.n - 2
+
+ and it follows that
+
+ M.n + M1.n <= ceil(n/2) + 1
+
+ Then 3*(M.n + M1.n) + 5 <= 3 * ceil(n/2) + 8 is the
+ amount of needed scratch space. */
+ mpn_hgcd_matrix_mul (M, &M1, tp + scratch);
+ success = 1;
+ }
+ }
+ }
+
+ for (;;)
+ {
+ /* Needs s+3 < n */
+ nn = hgcd_jacobi_step (n, ap, bp, s, M, bitsp, tp);
+ if (!nn)
+ return success ? n : 0;
+
+ n = nn;
+ success = 1;
+ }
+}
diff --git a/gmp/mpn/generic/hgcd_matrix.c b/gmp/mpn/generic/hgcd_matrix.c
new file mode 100644
index 0000000000..d9db331603
--- /dev/null
+++ b/gmp/mpn/generic/hgcd_matrix.c
@@ -0,0 +1,266 @@
+/* hgcd_matrix.c.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2003-2005, 2008, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* For input of size n, matrix elements are of size at most ceil(n/2)
+ - 1, but we need two limbs extra. */
+void
+mpn_hgcd_matrix_init (struct hgcd_matrix *M, mp_size_t n, mp_ptr p)
+{
+ mp_size_t s = (n+1)/2 + 1;
+ M->alloc = s;
+ M->n = 1;
+ MPN_ZERO (p, 4 * s);
+ M->p[0][0] = p;
+ M->p[0][1] = p + s;
+ M->p[1][0] = p + 2 * s;
+ M->p[1][1] = p + 3 * s;
+
+ M->p[0][0][0] = M->p[1][1][0] = 1;
+}
+
+/* Update column COL, adding in Q * column (1-COL). Temporary storage:
+ * qn + n <= M->alloc, where n is the size of the largest element in
+ * column 1 - COL. */
+void
+mpn_hgcd_matrix_update_q (struct hgcd_matrix *M, mp_srcptr qp, mp_size_t qn,
+ unsigned col, mp_ptr tp)
+{
+ ASSERT (col < 2);
+
+ if (qn == 1)
+ {
+ mp_limb_t q = qp[0];
+ mp_limb_t c0, c1;
+
+ c0 = mpn_addmul_1 (M->p[0][col], M->p[0][1-col], M->n, q);
+ c1 = mpn_addmul_1 (M->p[1][col], M->p[1][1-col], M->n, q);
+
+ M->p[0][col][M->n] = c0;
+ M->p[1][col][M->n] = c1;
+
+ M->n += (c0 | c1) != 0;
+ }
+ else
+ {
+ unsigned row;
+
+ /* Carries for the unlikely case that we get both high words
+ from the multiplication and carries from the addition. */
+ mp_limb_t c[2];
+ mp_size_t n;
+
+ /* The matrix will not necessarily grow in size by qn, so we
+ need normalization in order not to overflow M. */
+
+ for (n = M->n; n + qn > M->n; n--)
+ {
+ ASSERT (n > 0);
+ if (M->p[0][1-col][n-1] > 0 || M->p[1][1-col][n-1] > 0)
+ break;
+ }
+
+ ASSERT (qn + n <= M->alloc);
+
+ for (row = 0; row < 2; row++)
+ {
+ if (qn <= n)
+ mpn_mul (tp, M->p[row][1-col], n, qp, qn);
+ else
+ mpn_mul (tp, qp, qn, M->p[row][1-col], n);
+
+ ASSERT (n + qn >= M->n);
+ c[row] = mpn_add (M->p[row][col], tp, n + qn, M->p[row][col], M->n);
+ }
+
+ n += qn;
+
+ if (c[0] | c[1])
+ {
+ M->p[0][col][n] = c[0];
+ M->p[1][col][n] = c[1];
+ n++;
+ }
+ else
+ {
+ n -= (M->p[0][col][n-1] | M->p[1][col][n-1]) == 0;
+ ASSERT (n >= M->n);
+ }
+ M->n = n;
+ }
+
+ ASSERT (M->n < M->alloc);
+}
+
+/* Multiply M by M1 from the right. Since the M1 elements fit in
+ GMP_NUMB_BITS - 1 bits, M grows by at most one limb. Needs
+ temporary space M->n */
+void
+mpn_hgcd_matrix_mul_1 (struct hgcd_matrix *M, const struct hgcd_matrix1 *M1,
+ mp_ptr tp)
+{
+ mp_size_t n0, n1;
+
+ /* Could avoid copy by some swapping of pointers. */
+ MPN_COPY (tp, M->p[0][0], M->n);
+ n0 = mpn_hgcd_mul_matrix1_vector (M1, M->p[0][0], tp, M->p[0][1], M->n);
+ MPN_COPY (tp, M->p[1][0], M->n);
+ n1 = mpn_hgcd_mul_matrix1_vector (M1, M->p[1][0], tp, M->p[1][1], M->n);
+
+ /* Depends on zero initialization */
+ M->n = MAX(n0, n1);
+ ASSERT (M->n < M->alloc);
+}
+
+/* Multiply M by M1 from the right. Needs 3*(M->n + M1->n) + 5 limbs
+ of temporary storage (see mpn_matrix22_mul_itch). */
+void
+mpn_hgcd_matrix_mul (struct hgcd_matrix *M, const struct hgcd_matrix *M1,
+ mp_ptr tp)
+{
+ mp_size_t n;
+
+ /* About the new size of M:s elements. Since M1's diagonal elements
+ are > 0, no element can decrease. The new elements are of size
+ M->n + M1->n, one limb more or less. The computation of the
+ matrix product produces elements of size M->n + M1->n + 1. But
+ the true size, after normalization, may be three limbs smaller.
+
+ The reason that the product has normalized size >= M->n + M1->n -
+ 2 is subtle. It depends on the fact that M and M1 can be factored
+ as products of (1,1; 0,1) and (1,0; 1,1), and that we can't have
+ M ending with a large power and M1 starting with a large power of
+ the same matrix. */
+
+ /* FIXME: Strassen multiplication gives only a small speedup. In FFT
+ multiplication range, this function could be sped up quite a lot
+ using invariance. */
+ ASSERT (M->n + M1->n < M->alloc);
+
+ ASSERT ((M->p[0][0][M->n-1] | M->p[0][1][M->n-1]
+ | M->p[1][0][M->n-1] | M->p[1][1][M->n-1]) > 0);
+
+ ASSERT ((M1->p[0][0][M1->n-1] | M1->p[0][1][M1->n-1]
+ | M1->p[1][0][M1->n-1] | M1->p[1][1][M1->n-1]) > 0);
+
+ mpn_matrix22_mul (M->p[0][0], M->p[0][1],
+ M->p[1][0], M->p[1][1], M->n,
+ M1->p[0][0], M1->p[0][1],
+ M1->p[1][0], M1->p[1][1], M1->n, tp);
+
+ /* Index of last potentially non-zero limb, size is one greater. */
+ n = M->n + M1->n;
+
+ n -= ((M->p[0][0][n] | M->p[0][1][n] | M->p[1][0][n] | M->p[1][1][n]) == 0);
+ n -= ((M->p[0][0][n] | M->p[0][1][n] | M->p[1][0][n] | M->p[1][1][n]) == 0);
+ n -= ((M->p[0][0][n] | M->p[0][1][n] | M->p[1][0][n] | M->p[1][1][n]) == 0);
+
+ ASSERT ((M->p[0][0][n] | M->p[0][1][n] | M->p[1][0][n] | M->p[1][1][n]) > 0);
+
+ M->n = n + 1;
+}
+
+/* Multiplies the least significant p limbs of (a;b) by M^-1.
+ Temporary space needed: 2 * (p + M->n)*/
+mp_size_t
+mpn_hgcd_matrix_adjust (const struct hgcd_matrix *M,
+ mp_size_t n, mp_ptr ap, mp_ptr bp,
+ mp_size_t p, mp_ptr tp)
+{
+ /* M^-1 (a;b) = (r11, -r01; -r10, r00) (a ; b)
+ = (r11 a - r01 b; - r10 a + r00 b */
+
+ mp_ptr t0 = tp;
+ mp_ptr t1 = tp + p + M->n;
+ mp_limb_t ah, bh;
+ mp_limb_t cy;
+
+ ASSERT (p + M->n < n);
+
+ /* First compute the two values depending on a, before overwriting a */
+
+ if (M->n >= p)
+ {
+ mpn_mul (t0, M->p[1][1], M->n, ap, p);
+ mpn_mul (t1, M->p[1][0], M->n, ap, p);
+ }
+ else
+ {
+ mpn_mul (t0, ap, p, M->p[1][1], M->n);
+ mpn_mul (t1, ap, p, M->p[1][0], M->n);
+ }
+
+ /* Update a */
+ MPN_COPY (ap, t0, p);
+ ah = mpn_add (ap + p, ap + p, n - p, t0 + p, M->n);
+
+ if (M->n >= p)
+ mpn_mul (t0, M->p[0][1], M->n, bp, p);
+ else
+ mpn_mul (t0, bp, p, M->p[0][1], M->n);
+
+ cy = mpn_sub (ap, ap, n, t0, p + M->n);
+ ASSERT (cy <= ah);
+ ah -= cy;
+
+ /* Update b */
+ if (M->n >= p)
+ mpn_mul (t0, M->p[0][0], M->n, bp, p);
+ else
+ mpn_mul (t0, bp, p, M->p[0][0], M->n);
+
+ MPN_COPY (bp, t0, p);
+ bh = mpn_add (bp + p, bp + p, n - p, t0 + p, M->n);
+ cy = mpn_sub (bp, bp, n, t1, p + M->n);
+ ASSERT (cy <= bh);
+ bh -= cy;
+
+ if (ah > 0 || bh > 0)
+ {
+ ap[n] = ah;
+ bp[n] = bh;
+ n++;
+ }
+ else
+ {
+ /* The subtraction can reduce the size by at most one limb. */
+ if (ap[n-1] == 0 && bp[n-1] == 0)
+ n--;
+ }
+ ASSERT (ap[n-1] > 0 || bp[n-1] > 0);
+ return n;
+}
diff --git a/gmp/mpn/generic/hgcd_reduce.c b/gmp/mpn/generic/hgcd_reduce.c
new file mode 100644
index 0000000000..6f3d61ecea
--- /dev/null
+++ b/gmp/mpn/generic/hgcd_reduce.c
@@ -0,0 +1,247 @@
+/* hgcd_reduce.c.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Computes R -= A * B. Result must be non-negative. Normalized down
+ to size an, and resulting size is returned. */
+static mp_size_t
+submul (mp_ptr rp, mp_size_t rn,
+ mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
+{
+ mp_ptr tp;
+ TMP_DECL;
+
+ ASSERT (bn > 0);
+ ASSERT (an >= bn);
+ ASSERT (rn >= an);
+ ASSERT (an + bn <= rn + 1);
+
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS (an + bn);
+
+ mpn_mul (tp, ap, an, bp, bn);
+ if (an + bn > rn)
+ {
+ ASSERT (tp[rn] == 0);
+ bn--;
+ }
+ ASSERT_NOCARRY (mpn_sub (rp, rp, rn, tp, an + bn));
+ TMP_FREE;
+
+ while (rn > an && (rp[rn-1] == 0))
+ rn--;
+
+ return rn;
+}
+
+/* Computes (a, b) <-- M^{-1} (a; b) */
+/* FIXME:
+ x Take scratch parameter, and figure out scratch need.
+
+ x Use some fallback for small M->n?
+*/
+static mp_size_t
+hgcd_matrix_apply (const struct hgcd_matrix *M,
+ mp_ptr ap, mp_ptr bp,
+ mp_size_t n)
+{
+ mp_size_t an, bn, un, vn, nn;
+ mp_size_t mn[2][2];
+ mp_size_t modn;
+ mp_ptr tp, sp, scratch;
+ mp_limb_t cy;
+ unsigned i, j;
+
+ TMP_DECL;
+
+ ASSERT ( (ap[n-1] | bp[n-1]) > 0);
+
+ an = n;
+ MPN_NORMALIZE (ap, an);
+ bn = n;
+ MPN_NORMALIZE (bp, bn);
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 2; j++)
+ {
+ mp_size_t k;
+ k = M->n;
+ MPN_NORMALIZE (M->p[i][j], k);
+ mn[i][j] = k;
+ }
+
+ ASSERT (mn[0][0] > 0);
+ ASSERT (mn[1][1] > 0);
+ ASSERT ( (mn[0][1] | mn[1][0]) > 0);
+
+ TMP_MARK;
+
+ if (mn[0][1] == 0)
+ {
+ /* A unchanged, M = (1, 0; q, 1) */
+ ASSERT (mn[0][0] == 1);
+ ASSERT (M->p[0][0][0] == 1);
+ ASSERT (mn[1][1] == 1);
+ ASSERT (M->p[1][1][0] == 1);
+
+ /* Put B <-- B - q A */
+ nn = submul (bp, bn, ap, an, M->p[1][0], mn[1][0]);
+ }
+ else if (mn[1][0] == 0)
+ {
+ /* B unchanged, M = (1, q; 0, 1) */
+ ASSERT (mn[0][0] == 1);
+ ASSERT (M->p[0][0][0] == 1);
+ ASSERT (mn[1][1] == 1);
+ ASSERT (M->p[1][1][0] == 1);
+
+ /* Put A <-- A - q * B */
+ nn = submul (ap, an, bp, bn, M->p[0][1], mn[0][1]);
+ }
+ else
+ {
+ /* A = m00 a + m01 b ==> a <= A / m00, b <= A / m01.
+ B = m10 a + m11 b ==> a <= B / m10, b <= B / m11. */
+ un = MIN (an - mn[0][0], bn - mn[1][0]) + 1;
+ vn = MIN (an - mn[0][1], bn - mn[1][1]) + 1;
+
+ nn = MAX (un, vn);
+ /* In the range of interest, mulmod_bnm1 should always beat mullo. */
+ modn = mpn_mulmod_bnm1_next_size (nn + 1);
+
+ scratch = TMP_ALLOC_LIMBS (mpn_mulmod_bnm1_itch (modn, modn, M->n));
+ tp = TMP_ALLOC_LIMBS (modn);
+ sp = TMP_ALLOC_LIMBS (modn);
+
+ ASSERT (n <= 2*modn);
+
+ if (n > modn)
+ {
+ cy = mpn_add (ap, ap, modn, ap + modn, n - modn);
+ MPN_INCR_U (ap, modn, cy);
+
+ cy = mpn_add (bp, bp, modn, bp + modn, n - modn);
+ MPN_INCR_U (bp, modn, cy);
+
+ n = modn;
+ }
+
+ mpn_mulmod_bnm1 (tp, modn, ap, n, M->p[1][1], mn[1][1], scratch);
+ mpn_mulmod_bnm1 (sp, modn, bp, n, M->p[0][1], mn[0][1], scratch);
+
+ /* FIXME: Handle the small n case in some better way. */
+ if (n + mn[1][1] < modn)
+ MPN_ZERO (tp + n + mn[1][1], modn - n - mn[1][1]);
+ if (n + mn[0][1] < modn)
+ MPN_ZERO (sp + n + mn[0][1], modn - n - mn[0][1]);
+
+ cy = mpn_sub_n (tp, tp, sp, modn);
+ MPN_DECR_U (tp, modn, cy);
+
+ ASSERT (mpn_zero_p (tp + nn, modn - nn));
+
+ mpn_mulmod_bnm1 (sp, modn, ap, n, M->p[1][0], mn[1][0], scratch);
+ MPN_COPY (ap, tp, nn);
+ mpn_mulmod_bnm1 (tp, modn, bp, n, M->p[0][0], mn[0][0], scratch);
+
+ if (n + mn[1][0] < modn)
+ MPN_ZERO (sp + n + mn[1][0], modn - n - mn[1][0]);
+ if (n + mn[0][0] < modn)
+ MPN_ZERO (tp + n + mn[0][0], modn - n - mn[0][0]);
+
+ cy = mpn_sub_n (tp, tp, sp, modn);
+ MPN_DECR_U (tp, modn, cy);
+
+ ASSERT (mpn_zero_p (tp + nn, modn - nn));
+ MPN_COPY (bp, tp, nn);
+
+ while ( (ap[nn-1] | bp[nn-1]) == 0)
+ {
+ nn--;
+ ASSERT (nn > 0);
+ }
+ }
+ TMP_FREE;
+
+ return nn;
+}
+
+mp_size_t
+mpn_hgcd_reduce_itch (mp_size_t n, mp_size_t p)
+{
+ mp_size_t itch;
+ if (BELOW_THRESHOLD (n, HGCD_REDUCE_THRESHOLD))
+ {
+ itch = mpn_hgcd_itch (n-p);
+
+ /* For arbitrary p, the storage for _adjust is 2*(p + M->n) = 2 *
+ (p + ceil((n-p)/2) - 1 <= n + p - 1 */
+ if (itch < n + p - 1)
+ itch = n + p - 1;
+ }
+ else
+ {
+ itch = 2*(n-p) + mpn_hgcd_itch (n-p);
+ /* Currently, hgcd_matrix_apply allocates its own storage. */
+ }
+ return itch;
+}
+
+/* FIXME: Document storage need. */
+mp_size_t
+mpn_hgcd_reduce (struct hgcd_matrix *M,
+ mp_ptr ap, mp_ptr bp, mp_size_t n, mp_size_t p,
+ mp_ptr tp)
+{
+ mp_size_t nn;
+ if (BELOW_THRESHOLD (n, HGCD_REDUCE_THRESHOLD))
+ {
+ nn = mpn_hgcd (ap + p, bp + p, n - p, M, tp);
+ if (nn > 0)
+ /* Needs 2*(p + M->n) <= 2*(floor(n/2) + ceil(n/2) - 1)
+ = 2 (n - 1) */
+ return mpn_hgcd_matrix_adjust (M, p + nn, ap, bp, p, tp);
+ }
+ else
+ {
+ MPN_COPY (tp, ap + p, n - p);
+ MPN_COPY (tp + n - p, bp + p, n - p);
+ if (mpn_hgcd_appr (tp, tp + n - p, n - p, M, tp + 2*(n-p)))
+ return hgcd_matrix_apply (M, ap, bp, n);
+ }
+ return 0;
+}
diff --git a/gmp/mpn/generic/hgcd_step.c b/gmp/mpn/generic/hgcd_step.c
new file mode 100644
index 0000000000..e58894ff3b
--- /dev/null
+++ b/gmp/mpn/generic/hgcd_step.c
@@ -0,0 +1,128 @@
+/* hgcd_step.c.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2003-2005, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+static void
+hgcd_hook (void *p, mp_srcptr gp, mp_size_t gn,
+ mp_srcptr qp, mp_size_t qn, int d)
+{
+ ASSERT (!gp);
+ ASSERT (d >= 0);
+ ASSERT (d <= 1);
+
+ MPN_NORMALIZE (qp, qn);
+ if (qn > 0)
+ {
+ struct hgcd_matrix *M = (struct hgcd_matrix *) p;
+ /* NOTES: This is a bit ugly. A tp area is passed to
+ gcd_subdiv_step, which stores q at the start of that area. We
+ now use the rest. */
+ mp_ptr tp = (mp_ptr) qp + qn;
+ mpn_hgcd_matrix_update_q (M, qp, qn, d, tp);
+ }
+}
+
+/* Perform a few steps, using some of mpn_hgcd2, subtraction and
+ division. Reduces the size by almost one limb or more, but never
+ below the given size s. Return new size for a and b, or 0 if no
+ more steps are possible.
+
+ If hgcd2 succeeds, needs temporary space for hgcd_matrix_mul_1, M->n
+ limbs, and hgcd_mul_matrix1_inverse_vector, n limbs. If hgcd2
+ fails, needs space for the quotient, qn <= n - s limbs, for and
+ hgcd_matrix_update_q, qn + (size of the appropriate column of M) <=
+ (resulting size of M) + 1.
+
+ If N is the input size to the calling hgcd, then s = floor(N/2) +
+ 1, M->n < N, qn + product size <= n - s + n - s + 1 = 2 (n - s) + 1
+ <= N.
+*/
+
+mp_size_t
+mpn_hgcd_step (mp_size_t n, mp_ptr ap, mp_ptr bp, mp_size_t s,
+ struct hgcd_matrix *M, mp_ptr tp)
+{
+ struct hgcd_matrix1 M1;
+ mp_limb_t mask;
+ mp_limb_t ah, al, bh, bl;
+
+ ASSERT (n > s);
+
+ mask = ap[n-1] | bp[n-1];
+ ASSERT (mask > 0);
+
+ if (n == s + 1)
+ {
+ if (mask < 4)
+ goto subtract;
+
+ ah = ap[n-1]; al = ap[n-2];
+ bh = bp[n-1]; bl = bp[n-2];
+ }
+ else if (mask & GMP_NUMB_HIGHBIT)
+ {
+ ah = ap[n-1]; al = ap[n-2];
+ bh = bp[n-1]; bl = bp[n-2];
+ }
+ else
+ {
+ int shift;
+
+ count_leading_zeros (shift, mask);
+ ah = MPN_EXTRACT_NUMB (shift, ap[n-1], ap[n-2]);
+ al = MPN_EXTRACT_NUMB (shift, ap[n-2], ap[n-3]);
+ bh = MPN_EXTRACT_NUMB (shift, bp[n-1], bp[n-2]);
+ bl = MPN_EXTRACT_NUMB (shift, bp[n-2], bp[n-3]);
+ }
+
+ /* Try an mpn_hgcd2 step */
+ if (mpn_hgcd2 (ah, al, bh, bl, &M1))
+ {
+ /* Multiply M <- M * M1 */
+ mpn_hgcd_matrix_mul_1 (M, &M1, tp);
+
+ /* Can't swap inputs, so we need to copy. */
+ MPN_COPY (tp, ap, n);
+ /* Multiply M1^{-1} (a;b) */
+ return mpn_matrix22_mul1_inverse_vector (&M1, ap, tp, bp, n);
+ }
+
+ subtract:
+
+ return mpn_gcd_subdiv_step (ap, bp, n, s, hgcd_hook, M, tp);
+}
diff --git a/gmp/mpn/generic/invert.c b/gmp/mpn/generic/invert.c
new file mode 100644
index 0000000000..4bc459d728
--- /dev/null
+++ b/gmp/mpn/generic/invert.c
@@ -0,0 +1,91 @@
+/* invert.c -- Compute floor((B^{2n}-1)/U) - B^n.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright (C) 2007, 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpn_invert (mp_ptr ip, mp_srcptr dp, mp_size_t n, mp_ptr scratch)
+{
+ ASSERT (n > 0);
+ ASSERT (dp[n-1] & GMP_NUMB_HIGHBIT);
+ ASSERT (! MPN_OVERLAP_P (ip, n, dp, n));
+ ASSERT (! MPN_OVERLAP_P (ip, n, scratch, mpn_invertappr_itch(n)));
+ ASSERT (! MPN_OVERLAP_P (dp, n, scratch, mpn_invertappr_itch(n)));
+
+ if (n == 1)
+ invert_limb (*ip, *dp);
+ else {
+ TMP_DECL;
+
+ TMP_MARK;
+ if (BELOW_THRESHOLD (n, INV_APPR_THRESHOLD))
+ {
+ /* Maximum scratch needed by this branch: 2*n */
+ mp_size_t i;
+ mp_ptr xp;
+
+ xp = scratch; /* 2 * n limbs */
+ for (i = n - 1; i >= 0; i--)
+ xp[i] = GMP_NUMB_MAX;
+ mpn_com (xp + n, dp, n);
+ if (n == 2) {
+ mpn_divrem_2 (ip, 0, xp, 4, dp);
+ } else {
+ gmp_pi1_t inv;
+ invert_pi1 (inv, dp[n-1], dp[n-2]);
+ /* FIXME: should we use dcpi1_div_q, for big sizes? */
+ mpn_sbpi1_div_q (ip, xp, 2 * n, dp, n, inv.inv32);
+ }
+ }
+ else { /* Use approximated inverse; correct the result if needed. */
+ mp_limb_t e; /* The possible error in the approximate inverse */
+
+ ASSERT ( mpn_invert_itch (n) >= mpn_invertappr_itch (n) );
+ e = mpn_ni_invertappr (ip, dp, n, scratch);
+
+ if (UNLIKELY (e)) { /* Assume the error can only be "0" (no error) or "1". */
+ /* Code to detect and correct the "off by one" approximation. */
+ mpn_mul_n (scratch, ip, dp, n);
+ ASSERT_NOCARRY (mpn_add_n (scratch + n, scratch + n, dp, n));
+ if (! mpn_add (scratch, scratch, 2*n, dp, n))
+ MPN_INCR_U (ip, n, 1); /* The value was wrong, correct it. */
+ }
+ }
+ TMP_FREE;
+ }
+}
diff --git a/gmp/mpn/generic/invertappr.c b/gmp/mpn/generic/invertappr.c
new file mode 100644
index 0000000000..12326b8b75
--- /dev/null
+++ b/gmp/mpn/generic/invertappr.c
@@ -0,0 +1,314 @@
+/* mpn_invertappr and helper functions. Compute I such that
+ floor((B^{2n}-1)/U - 1 <= I + B^n <= floor((B^{2n}-1)/U.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ The algorithm used here was inspired by ApproximateReciprocal from "Modern
+ Computer Arithmetic", by Richard P. Brent and Paul Zimmermann. Special
+ thanks to Paul Zimmermann for his very valuable suggestions on all the
+ theoretical aspects during the work on this code.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright (C) 2007, 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* FIXME: Remove NULL and TMP_*, as soon as all the callers properly
+ allocate and pass the scratch to the function. */
+#include <stdlib.h> /* for NULL */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* FIXME: The iterative version splits the operand in two slightly unbalanced
+ parts, the use of log_2 (or counting the bits) underestimate the maximum
+ number of iterations. */
+
+#if TUNE_PROGRAM_BUILD
+#define NPOWS \
+ ((sizeof(mp_size_t) > 6 ? 48 : 8*sizeof(mp_size_t)))
+#define MAYBE_dcpi1_divappr 1
+#else
+#define NPOWS \
+ ((sizeof(mp_size_t) > 6 ? 48 : 8*sizeof(mp_size_t)) - LOG2C (INV_NEWTON_THRESHOLD))
+#define MAYBE_dcpi1_divappr \
+ (INV_NEWTON_THRESHOLD < DC_DIVAPPR_Q_THRESHOLD)
+#if (INV_NEWTON_THRESHOLD > INV_MULMOD_BNM1_THRESHOLD) && \
+ (INV_APPR_THRESHOLD > INV_MULMOD_BNM1_THRESHOLD)
+#undef INV_MULMOD_BNM1_THRESHOLD
+#define INV_MULMOD_BNM1_THRESHOLD 0 /* always when Newton */
+#endif
+#endif
+
+/* All the three functions mpn{,_bc,_ni}_invertappr (ip, dp, n, scratch), take
+ the strictly normalised value {dp,n} (i.e., most significant bit must be set)
+ as an input, and compute {ip,n}: the approximate reciprocal of {dp,n}.
+
+ Let e = mpn*_invertappr (ip, dp, n, scratch) be the returned value; the
+ following conditions are satisfied by the output:
+ 0 <= e <= 1;
+ {dp,n}*(B^n+{ip,n}) < B^{2n} <= {dp,n}*(B^n+{ip,n}+1+e) .
+ I.e. e=0 means that the result {ip,n} equals the one given by mpn_invert.
+ e=1 means that the result _may_ be one less than expected.
+
+ The _bc version returns e=1 most of the time.
+ The _ni version should return e=0 most of the time; only about 1% of
+ possible random input should give e=1.
+
+ When the strict result is needed, i.e., e=0 in the relation above:
+ {dp,n}*(B^n+{ip,n}) < B^{2n} <= {dp,n}*(B^n+{ip,n}+1) ;
+ the function mpn_invert (ip, dp, n, scratch) should be used instead. */
+
+/* Maximum scratch needed by this branch (at tp): 3*n + 2 */
+static mp_limb_t
+mpn_bc_invertappr (mp_ptr ip, mp_srcptr dp, mp_size_t n, mp_ptr tp)
+{
+ mp_ptr xp;
+
+ ASSERT (n > 0);
+ ASSERT (dp[n-1] & GMP_NUMB_HIGHBIT);
+ ASSERT (! MPN_OVERLAP_P (ip, n, dp, n));
+ ASSERT (! MPN_OVERLAP_P (ip, n, tp, mpn_invertappr_itch(n)));
+ ASSERT (! MPN_OVERLAP_P (dp, n, tp, mpn_invertappr_itch(n)));
+
+ /* Compute a base value of r limbs. */
+ if (n == 1)
+ invert_limb (*ip, *dp);
+ else {
+ mp_size_t i;
+ xp = tp + n + 2; /* 2 * n limbs */
+
+ for (i = n - 1; i >= 0; i--)
+ xp[i] = GMP_NUMB_MAX;
+ mpn_com (xp + n, dp, n);
+
+ /* Now xp contains B^2n - {dp,n}*B^n - 1 */
+
+ /* FIXME: if mpn_*pi1_divappr_q handles n==2, use it! */
+ if (n == 2) {
+ mpn_divrem_2 (ip, 0, xp, 4, dp);
+ } else {
+ gmp_pi1_t inv;
+ invert_pi1 (inv, dp[n-1], dp[n-2]);
+ if (! MAYBE_dcpi1_divappr
+ || BELOW_THRESHOLD (n, DC_DIVAPPR_Q_THRESHOLD))
+ mpn_sbpi1_divappr_q (ip, xp, 2 * n, dp, n, inv.inv32);
+ else
+ mpn_dcpi1_divappr_q (ip, xp, 2 * n, dp, n, &inv);
+ MPN_DECR_U(ip, n, 1);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* mpn_ni_invertappr: computes the approximate reciprocal using Newton's
+ iterations (at least one).
+
+ Inspired by Algorithm "ApproximateReciprocal", published in "Modern Computer
+ Arithmetic" by Richard P. Brent and Paul Zimmermann, algorithm 3.5, page 121
+ in version 0.4 of the book.
+
+ Some adaptations were introduced, to allow product mod B^m-1 and return the
+ value e.
+
+ USE_MUL_N = 1 (default) introduces a correction in such a way that "the
+ value of B^{n+h}-T computed at step 8 cannot exceed B^n-1" (the book reads
+ "2B^n-1"). This correction should not require to modify the proof.
+
+ We use a wrapped product modulo B^m-1. NOTE: is there any normalisation
+ problem for the [0] class? It shouldn't: we compute 2*|A*X_h - B^{n+h}| <
+ B^m-1. We may get [0] if and only if we get AX_h = B^{n+h}. This can
+ happen only if A=B^{n}/2, but this implies X_h = B^{h}*2-1 i.e., AX_h =
+ B^{n+h} - A, then we get into the "negative" branch, where X_h is not
+ incremented (because A < B^n).
+
+ FIXME: the scratch for mulmod_bnm1 does not currently fit in the scratch, it
+ is allocated apart. */
+
+#define USE_MUL_N 1
+
+mp_limb_t
+mpn_ni_invertappr (mp_ptr ip, mp_srcptr dp, mp_size_t n, mp_ptr scratch)
+{
+ mp_limb_t cy;
+ mp_ptr xp;
+ mp_size_t rn, mn;
+ mp_size_t sizes[NPOWS], *sizp;
+ mp_ptr tp;
+ TMP_DECL;
+#define rp scratch
+
+ ASSERT (n > 2);
+ ASSERT (dp[n-1] & GMP_NUMB_HIGHBIT);
+ ASSERT (! MPN_OVERLAP_P (ip, n, dp, n));
+ ASSERT (! MPN_OVERLAP_P (ip, n, scratch, mpn_invertappr_itch(n)));
+ ASSERT (! MPN_OVERLAP_P (dp, n, scratch, mpn_invertappr_itch(n)));
+
+ /* Compute the computation precisions from highest to lowest, leaving the
+ base case size in 'rn'. */
+ sizp = sizes;
+ rn = n;
+ do {
+ *sizp = rn;
+ rn = ((rn) >> 1) + 1;
+ sizp ++;
+ } while (ABOVE_THRESHOLD (rn, INV_NEWTON_THRESHOLD));
+
+ /* We search the inverse of 0.{dp,n}, we compute it as 1.{ip,n} */
+ dp += n;
+ ip += n;
+
+ /* Compute a base value of rn limbs. */
+ mpn_bc_invertappr (ip - rn, dp - rn, rn, scratch);
+
+ TMP_MARK;
+
+ if (ABOVE_THRESHOLD (n, INV_MULMOD_BNM1_THRESHOLD))
+ {
+ mn = mpn_mulmod_bnm1_next_size (n + 1);
+ tp = TMP_ALLOC_LIMBS (mpn_mulmod_bnm1_itch (mn, n, (n >> 1) + 1));
+ }
+ /* Use Newton's iterations to get the desired precision.*/
+
+ /* define rp scratch; 2rn + 1 limbs <= 2(n>>1 + 1) + 1 <= n + 3 limbs */
+ /* Maximum scratch needed by this branch <= 3*n + 2 */
+ xp = scratch + n + 3; /* n + rn limbs */
+ while (1) {
+ mp_limb_t method;
+
+ n = *--sizp;
+ /*
+ v n v
+ +----+--+
+ ^ rn ^
+ */
+
+ /* Compute i_jd . */
+ if (BELOW_THRESHOLD (n, INV_MULMOD_BNM1_THRESHOLD)
+ || ((mn = mpn_mulmod_bnm1_next_size (n + 1)) > (n + rn))) {
+ /* FIXME: We do only need {xp,n+1}*/
+ mpn_mul (xp, dp - n, n, ip - rn, rn);
+ mpn_add_n (xp + rn, xp + rn, dp - n, n - rn + 1);
+ method = 1; /* Remember we used (truncated) product */
+ /* We computed cy.{xp,rn+n} <- 1.{ip,rn} * 0.{dp,n} */
+ } else { /* Use B^n-1 wraparound */
+ mpn_mulmod_bnm1 (xp, mn, dp - n, n, ip - rn, rn, tp);
+ /* We computed {xp,mn} <- {ip,rn} * {dp,n} mod (B^mn-1) */
+ /* We know that 2*|ip*dp + dp*B^rn - B^{rn+n}| < B^mn-1 */
+ /* Add dp*B^rn mod (B^mn-1) */
+ ASSERT (n >= mn - rn);
+ xp[mn] = 1 + mpn_add_n (xp + rn, xp + rn, dp - n, mn - rn);
+ cy = mpn_add_n (xp, xp, dp - (n - (mn - rn)), n - (mn - rn));
+ MPN_INCR_U (xp + n - (mn - rn), mn + 1 - n + (mn - rn), cy);
+ ASSERT (n + rn >= mn);
+ /* Subtract B^{rn+n} */
+ MPN_DECR_U (xp + rn + n - mn, 2*mn + 1 - rn - n, 1);
+ if (xp[mn])
+ MPN_INCR_U (xp, mn, xp[mn] - 1);
+ else
+ MPN_DECR_U (xp, mn, 1);
+ method = 0; /* Remember we are working Mod B^m-1 */
+ }
+
+ if (xp[n] < 2) { /* "positive" residue class */
+ cy = 1;
+ while (xp[n] || mpn_cmp (xp, dp - n, n)>0) {
+ xp[n] -= mpn_sub_n (xp, xp, dp - n, n);
+ cy ++;
+ }
+ MPN_DECR_U(ip - rn, rn, cy);
+ ASSERT (cy <= 4); /* at most 3 cycles for the while above */
+ ASSERT_NOCARRY (mpn_sub_n (xp, dp - n, xp, n));
+ ASSERT (xp[n] == 0);
+ } else { /* "negative" residue class */
+ mpn_com (xp, xp, n + 1);
+ MPN_INCR_U(xp, n + 1, method);
+ ASSERT (xp[n] <= 1);
+#if USE_MUL_N
+ if (xp[n]) {
+ MPN_INCR_U(ip - rn, rn, 1);
+ ASSERT_CARRY (mpn_sub_n (xp, xp, dp - n, n));
+ }
+#endif
+ }
+
+ /* Compute x_ju_j. FIXME:We need {rp+rn,rn}, mulhi? */
+#if USE_MUL_N
+ mpn_mul_n (rp, xp + n - rn, ip - rn, rn);
+#else
+ rp[2*rn] = 0;
+ mpn_mul (rp, xp + n - rn, rn + xp[n], ip - rn, rn);
+#endif
+ /* We need _only_ the carry from the next addition */
+ /* Anyway 2rn-n <= 2... we don't need to optimise. */
+ cy = mpn_add_n (rp + rn, rp + rn, xp + n - rn, 2*rn - n);
+ cy = mpn_add_nc (ip - n, rp + 3*rn - n, xp + rn, n - rn, cy);
+ MPN_INCR_U (ip - rn, rn, cy + (1-USE_MUL_N)*(rp[2*rn] + xp[n]));
+ if (sizp == sizes) { /* Get out of the cycle */
+ /* Check for possible carry propagation from below. */
+ cy = rp[3*rn - n - 1] > GMP_NUMB_MAX - 7; /* Be conservative. */
+/* cy = mpn_add_1 (rp + rn, rp + rn, 2*rn - n, 4); */
+ break;
+ }
+ rn = n;
+ }
+ TMP_FREE;
+
+ return cy;
+#undef rp
+}
+
+mp_limb_t
+mpn_invertappr (mp_ptr ip, mp_srcptr dp, mp_size_t n, mp_ptr scratch)
+{
+ mp_limb_t res;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ if (scratch == NULL)
+ scratch = TMP_ALLOC_LIMBS (mpn_invertappr_itch (n));
+
+ ASSERT (n > 0);
+ ASSERT (dp[n-1] & GMP_NUMB_HIGHBIT);
+ ASSERT (! MPN_OVERLAP_P (ip, n, dp, n));
+ ASSERT (! MPN_OVERLAP_P (ip, n, scratch, mpn_invertappr_itch(n)));
+ ASSERT (! MPN_OVERLAP_P (dp, n, scratch, mpn_invertappr_itch(n)));
+
+ if (BELOW_THRESHOLD (n, INV_NEWTON_THRESHOLD))
+ res = mpn_bc_invertappr (ip, dp, n, scratch);
+ else
+ res = mpn_ni_invertappr (ip, dp, n, scratch);
+
+ TMP_FREE;
+ return res;
+}
diff --git a/gmp/mpn/generic/jacbase.c b/gmp/mpn/generic/jacbase.c
new file mode 100644
index 0000000000..cd52bc9513
--- /dev/null
+++ b/gmp/mpn/generic/jacbase.c
@@ -0,0 +1,243 @@
+/* mpn_jacobi_base -- limb/limb Jacobi symbol with restricted arguments.
+
+ THIS INTERFACE IS PRELIMINARY AND MIGHT DISAPPEAR OR BE SUBJECT TO
+ INCOMPATIBLE CHANGES IN A FUTURE RELEASE OF GMP.
+
+Copyright 1999-2002, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Use the simple loop by default. The generic count_trailing_zeros is not
+ very fast, and the extra trickery of method 3 has proven to be less use
+ than might have been though. */
+#ifndef JACOBI_BASE_METHOD
+#define JACOBI_BASE_METHOD 2
+#endif
+
+
+/* Use count_trailing_zeros. */
+#if JACOBI_BASE_METHOD == 1
+#define PROCESS_TWOS_ANY \
+ { \
+ mp_limb_t twos; \
+ count_trailing_zeros (twos, a); \
+ result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, b); \
+ a >>= twos; \
+ }
+#define PROCESS_TWOS_EVEN PROCESS_TWOS_ANY
+#endif
+
+/* Use a simple loop. A disadvantage of this is that there's a branch on a
+ 50/50 chance of a 0 or 1 low bit. */
+#if JACOBI_BASE_METHOD == 2
+#define PROCESS_TWOS_EVEN \
+ { \
+ int two; \
+ two = JACOBI_TWO_U_BIT1 (b); \
+ do \
+ { \
+ a >>= 1; \
+ result_bit1 ^= two; \
+ ASSERT (a != 0); \
+ } \
+ while ((a & 1) == 0); \
+ }
+#define PROCESS_TWOS_ANY \
+ if ((a & 1) == 0) \
+ PROCESS_TWOS_EVEN;
+#endif
+
+/* Process one bit arithmetically, then a simple loop. This cuts the loop
+ condition down to a 25/75 chance, which should branch predict better.
+ The CPU will need a reasonable variable left shift. */
+#if JACOBI_BASE_METHOD == 3
+#define PROCESS_TWOS_EVEN \
+ { \
+ int two, mask, shift; \
+ \
+ two = JACOBI_TWO_U_BIT1 (b); \
+ mask = (~a & 2); \
+ a >>= 1; \
+ \
+ shift = (~a & 1); \
+ a >>= shift; \
+ result_bit1 ^= two ^ (two & mask); \
+ \
+ while ((a & 1) == 0) \
+ { \
+ a >>= 1; \
+ result_bit1 ^= two; \
+ ASSERT (a != 0); \
+ } \
+ }
+#define PROCESS_TWOS_ANY \
+ { \
+ int two, mask, shift; \
+ \
+ two = JACOBI_TWO_U_BIT1 (b); \
+ shift = (~a & 1); \
+ a >>= shift; \
+ \
+ mask = shift << 1; \
+ result_bit1 ^= (two & mask); \
+ \
+ while ((a & 1) == 0) \
+ { \
+ a >>= 1; \
+ result_bit1 ^= two; \
+ ASSERT (a != 0); \
+ } \
+ }
+#endif
+
+#if JACOBI_BASE_METHOD < 4
+/* Calculate the value of the Jacobi symbol (a/b) of two mp_limb_t's, but
+ with a restricted range of inputs accepted, namely b>1, b odd.
+
+ The initial result_bit1 is taken as a parameter for the convenience of
+ mpz_kronecker_ui() et al. The sign changes both here and in those
+ routines accumulate nicely in bit 1, see the JACOBI macros.
+
+ The return value here is the normal +1, 0, or -1. Note that +1 and -1
+ have bit 1 in the "BIT1" sense, which could be useful if the caller is
+ accumulating it into some extended calculation.
+
+ Duplicating the loop body to avoid the MP_LIMB_T_SWAP(a,b) would be
+ possible, but a couple of tests suggest it's not a significant speedup,
+ and may even be a slowdown, so what's here is good enough for now. */
+
+int
+mpn_jacobi_base (mp_limb_t a, mp_limb_t b, int result_bit1)
+{
+ ASSERT (b & 1); /* b odd */
+ ASSERT (b != 1);
+
+ if (a == 0)
+ return 0;
+
+ PROCESS_TWOS_ANY;
+ if (a == 1)
+ goto done;
+
+ if (a >= b)
+ goto a_gt_b;
+
+ for (;;)
+ {
+ result_bit1 ^= JACOBI_RECIP_UU_BIT1 (a, b);
+ MP_LIMB_T_SWAP (a, b);
+
+ a_gt_b:
+ do
+ {
+ /* working on (a/b), a,b odd, a>=b */
+ ASSERT (a & 1);
+ ASSERT (b & 1);
+ ASSERT (a >= b);
+
+ if ((a -= b) == 0)
+ return 0;
+
+ PROCESS_TWOS_EVEN;
+ if (a == 1)
+ goto done;
+ }
+ while (a >= b);
+ }
+
+ done:
+ return JACOBI_BIT1_TO_PN (result_bit1);
+}
+#endif
+
+#if JACOBI_BASE_METHOD == 4
+/* Computes (a/b) for odd b > 1 and any a. The initial bit is taken as a
+ * parameter. We have no need for the convention that the sign is in
+ * bit 1, internally we use bit 0. */
+
+/* FIXME: Could try table-based count_trailing_zeros. */
+int
+mpn_jacobi_base (mp_limb_t a, mp_limb_t b, int bit)
+{
+ int c;
+
+ ASSERT (b & 1);
+ ASSERT (b > 1);
+
+ if (a == 0)
+ /* This is the only line which depends on b > 1 */
+ return 0;
+
+ bit >>= 1;
+
+ /* Below, we represent a and b shifted right so that the least
+ significant one bit is implicit. */
+
+ b >>= 1;
+
+ count_trailing_zeros (c, a);
+ bit ^= c & (b ^ (b >> 1));
+
+ /* We may have c==GMP_LIMB_BITS-1, so we can't use a>>c+1. */
+ a >>= c;
+ a >>= 1;
+
+ do
+ {
+ mp_limb_t t = a - b;
+ mp_limb_t bgta = LIMB_HIGHBIT_TO_MASK (t);
+
+ if (t == 0)
+ return 0;
+
+ /* If b > a, invoke reciprocity */
+ bit ^= (bgta & a & b);
+
+ /* b <-- min (a, b) */
+ b += (bgta & t);
+
+ /* a <-- |a - b| */
+ a = (t ^ bgta) - bgta;
+
+ /* Number of trailing zeros is the same no matter if we look at
+ * t or a, but using t gives more parallelism. */
+ count_trailing_zeros (c, t);
+ c ++;
+ /* (2/b) = -1 if b = 3 or 5 mod 8 */
+ bit ^= c & (b ^ (b >> 1));
+ a >>= c;
+ }
+ while (b > 0);
+
+ return 1-2*(bit & 1);
+}
+#endif /* JACOBI_BASE_METHOD == 4 */
diff --git a/gmp/mpn/generic/jacobi.c b/gmp/mpn/generic/jacobi.c
new file mode 100644
index 0000000000..bdc3ec67da
--- /dev/null
+++ b/gmp/mpn/generic/jacobi.c
@@ -0,0 +1,295 @@
+/* jacobi.c
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 1996, 1998, 2000-2004, 2008, 2010, 2011 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef JACOBI_DC_THRESHOLD
+#define JACOBI_DC_THRESHOLD GCD_DC_THRESHOLD
+#endif
+
+/* Schönhage's rules:
+ *
+ * Assume r0 = r1 q1 + r2, with r0 odd, and r1 = q2 r2 + r3
+ *
+ * If r1 is odd, then
+ *
+ * (r1 | r0) = s(r1, r0) (r0 | r1) = s(r1, r0) (r2, r1)
+ *
+ * where s(x,y) = (-1)^{(x-1)(y-1)/4} = (-1)^[x = y = 3 (mod 4)].
+ *
+ * If r1 is even, r2 must be odd. We have
+ *
+ * (r1 | r0) = (r1 - r0 | r0) = (-1)^(r0-1)/2 (r0 - r1 | r0)
+ * = (-1)^(r0-1)/2 s(r0, r0 - r1) (r0 | r0 - r1)
+ * = (-1)^(r0-1)/2 s(r0, r0 - r1) (r1 | r0 - r1)
+ *
+ * Now, if r1 = 0 (mod 4), then the sign factor is +1, and repeating
+ * q1 times gives
+ *
+ * (r1 | r0) = (r1 | r2) = (r3 | r2)
+ *
+ * On the other hand, if r1 = 2 (mod 4), the sign factor is
+ * (-1)^{(r0-1)/2}, and repeating q1 times gives the exponent
+ *
+ * (r0-1)/2 + (r0-r1-1)/2 + ... + (r0 - (q1-1) r1)/2
+ * = q1 (r0-1)/2 + q1 (q1-1)/2
+ *
+ * and we can summarize the even case as
+ *
+ * (r1 | r0) = t(r1, r0, q1) (r3 | r2)
+ *
+ * where t(x,y,q) = (-1)^{[x = 2 (mod 4)] (q(y-1)/2 + y(q-1)/2)}
+ *
+ * What about termination? The remainder sequence ends with (0|1) = 1
+ * (or (0 | r) = 0 if r != 1). What are the possible cases? If r1 is
+ * odd, r2 may be zero. If r1 is even, then r2 = r0 - q1 r1 is odd and
+ * hence non-zero. We may have r3 = r1 - q2 r2 = 0.
+ *
+ * Examples: (11|15) = - (15|11) = - (4|11)
+ * (4|11) = (4| 3) = (1| 3)
+ * (1| 3) = (3|1) = (0|1) = 1
+ *
+ * (2|7) = (2|1) = (0|1) = 1
+ *
+ * Detail: (2|7) = (2-7|7) = (-1|7)(5|7) = -(7|5) = -(2|5)
+ * (2|5) = (2-5|5) = (-1|5)(3|5) = (5|3) = (2|3)
+ * (2|3) = (2-3|3) = (-1|3)(1|3) = -(3|1) = -(2|1)
+ *
+ */
+
+/* In principle, the state consists of four variables: e (one bit), a,
+ b (two bits each), d (one bit). Collected factors are (-1)^e. a and
+ b are the least significant bits of the current remainders. d
+ (denominator) is 0 if we're currently subtracting multiplies of a
+ from b, and 1 if we're subtracting b from a.
+
+ e is stored in the least significant bit, while a, b and d are
+ coded as only 13 distinct values in bits 1-4, according to the
+ following table. For rows not mentioning d, the value is either
+ implied, or it doesn't matter. */
+
+#if WANT_ASSERT
+static const struct
+{
+ unsigned char a;
+ unsigned char b;
+} decode_table[13] = {
+ /* 0 */ { 0, 1 },
+ /* 1 */ { 0, 3 },
+ /* 2 */ { 1, 1 },
+ /* 3 */ { 1, 3 },
+ /* 4 */ { 2, 1 },
+ /* 5 */ { 2, 3 },
+ /* 6 */ { 3, 1 },
+ /* 7 */ { 3, 3 }, /* d = 1 */
+ /* 8 */ { 1, 0 },
+ /* 9 */ { 1, 2 },
+ /* 10 */ { 3, 0 },
+ /* 11 */ { 3, 2 },
+ /* 12 */ { 3, 3 }, /* d = 0 */
+};
+#define JACOBI_A(bits) (decode_table[(bits)>>1].a)
+#define JACOBI_B(bits) (decode_table[(bits)>>1].b)
+#endif /* WANT_ASSERT */
+
+const unsigned char jacobi_table[208] = {
+#include "jacobitab.h"
+};
+
+#define BITS_FAIL 31
+
+static void
+jacobi_hook (void *p, mp_srcptr gp, mp_size_t gn,
+ mp_srcptr qp, mp_size_t qn, int d)
+{
+ unsigned *bitsp = (unsigned *) p;
+
+ if (gp)
+ {
+ ASSERT (gn > 0);
+ if (gn != 1 || gp[0] != 1)
+ {
+ *bitsp = BITS_FAIL;
+ return;
+ }
+ }
+
+ if (qp)
+ {
+ ASSERT (qn > 0);
+ ASSERT (d >= 0);
+ *bitsp = mpn_jacobi_update (*bitsp, d, qp[0] & 3);
+ }
+}
+
+#define CHOOSE_P(n) (2*(n) / 3)
+
+int
+mpn_jacobi_n (mp_ptr ap, mp_ptr bp, mp_size_t n, unsigned bits)
+{
+ mp_size_t scratch;
+ mp_size_t matrix_scratch;
+ mp_ptr tp;
+
+ TMP_DECL;
+
+ ASSERT (n > 0);
+ ASSERT ( (ap[n-1] | bp[n-1]) > 0);
+ ASSERT ( (bp[0] | ap[0]) & 1);
+
+ /* FIXME: Check for small sizes first, before setting up temporary
+ storage etc. */
+ scratch = MPN_GCD_SUBDIV_STEP_ITCH(n);
+
+ if (ABOVE_THRESHOLD (n, GCD_DC_THRESHOLD))
+ {
+ mp_size_t hgcd_scratch;
+ mp_size_t update_scratch;
+ mp_size_t p = CHOOSE_P (n);
+ mp_size_t dc_scratch;
+
+ matrix_scratch = MPN_HGCD_MATRIX_INIT_ITCH (n - p);
+ hgcd_scratch = mpn_hgcd_itch (n - p);
+ update_scratch = p + n - 1;
+
+ dc_scratch = matrix_scratch + MAX(hgcd_scratch, update_scratch);
+ if (dc_scratch > scratch)
+ scratch = dc_scratch;
+ }
+
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS(scratch);
+
+ while (ABOVE_THRESHOLD (n, JACOBI_DC_THRESHOLD))
+ {
+ struct hgcd_matrix M;
+ mp_size_t p = 2*n/3;
+ mp_size_t matrix_scratch = MPN_HGCD_MATRIX_INIT_ITCH (n - p);
+ mp_size_t nn;
+ mpn_hgcd_matrix_init (&M, n - p, tp);
+
+ nn = mpn_hgcd_jacobi (ap + p, bp + p, n - p, &M, &bits,
+ tp + matrix_scratch);
+ if (nn > 0)
+ {
+ ASSERT (M.n <= (n - p - 1)/2);
+ ASSERT (M.n + p <= (p + n - 1) / 2);
+ /* Temporary storage 2 (p + M->n) <= p + n - 1. */
+ n = mpn_hgcd_matrix_adjust (&M, p + nn, ap, bp, p, tp + matrix_scratch);
+ }
+ else
+ {
+ /* Temporary storage n */
+ n = mpn_gcd_subdiv_step (ap, bp, n, 0, jacobi_hook, &bits, tp);
+ if (!n)
+ {
+ TMP_FREE;
+ return bits == BITS_FAIL ? 0 : mpn_jacobi_finish (bits);
+ }
+ }
+ }
+
+ while (n > 2)
+ {
+ struct hgcd_matrix1 M;
+ mp_limb_t ah, al, bh, bl;
+ mp_limb_t mask;
+
+ mask = ap[n-1] | bp[n-1];
+ ASSERT (mask > 0);
+
+ if (mask & GMP_NUMB_HIGHBIT)
+ {
+ ah = ap[n-1]; al = ap[n-2];
+ bh = bp[n-1]; bl = bp[n-2];
+ }
+ else
+ {
+ int shift;
+
+ count_leading_zeros (shift, mask);
+ ah = MPN_EXTRACT_NUMB (shift, ap[n-1], ap[n-2]);
+ al = MPN_EXTRACT_NUMB (shift, ap[n-2], ap[n-3]);
+ bh = MPN_EXTRACT_NUMB (shift, bp[n-1], bp[n-2]);
+ bl = MPN_EXTRACT_NUMB (shift, bp[n-2], bp[n-3]);
+ }
+
+ /* Try an mpn_nhgcd2 step */
+ if (mpn_hgcd2_jacobi (ah, al, bh, bl, &M, &bits))
+ {
+ n = mpn_matrix22_mul1_inverse_vector (&M, tp, ap, bp, n);
+ MP_PTR_SWAP (ap, tp);
+ }
+ else
+ {
+ /* mpn_hgcd2 has failed. Then either one of a or b is very
+ small, or the difference is very small. Perform one
+ subtraction followed by one division. */
+ n = mpn_gcd_subdiv_step (ap, bp, n, 0, &jacobi_hook, &bits, tp);
+ if (!n)
+ {
+ TMP_FREE;
+ return bits == BITS_FAIL ? 0 : mpn_jacobi_finish (bits);
+ }
+ }
+ }
+
+ if (bits >= 16)
+ MP_PTR_SWAP (ap, bp);
+
+ ASSERT (bp[0] & 1);
+
+ if (n == 1)
+ {
+ mp_limb_t al, bl;
+ al = ap[0];
+ bl = bp[0];
+
+ TMP_FREE;
+ if (bl == 1)
+ return 1 - 2*(bits & 1);
+ else
+ return mpn_jacobi_base (al, bl, bits << 1);
+ }
+
+ else
+ {
+ int res = mpn_jacobi_2 (ap, bp, bits & 1);
+ TMP_FREE;
+ return res;
+ }
+}
diff --git a/gmp/mpn/generic/jacobi_2.c b/gmp/mpn/generic/jacobi_2.c
new file mode 100644
index 0000000000..9f480f7834
--- /dev/null
+++ b/gmp/mpn/generic/jacobi_2.c
@@ -0,0 +1,352 @@
+/* jacobi_2.c
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 1996, 1998, 2000-2004, 2008, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef JACOBI_2_METHOD
+#define JACOBI_2_METHOD 2
+#endif
+
+/* Computes (a / b) where b is odd, and a and b are otherwise arbitrary
+ two-limb numbers. */
+#if JACOBI_2_METHOD == 1
+int
+mpn_jacobi_2 (mp_srcptr ap, mp_srcptr bp, unsigned bit)
+{
+ mp_limb_t ah, al, bh, bl;
+ int c;
+
+ al = ap[0];
+ ah = ap[1];
+ bl = bp[0];
+ bh = bp[1];
+
+ ASSERT (bl & 1);
+
+ bl = ((bh << (GMP_NUMB_BITS - 1)) & GMP_NUMB_MASK) | (bl >> 1);
+ bh >>= 1;
+
+ if ( (bh | bl) == 0)
+ return 1 - 2*(bit & 1);
+
+ if ( (ah | al) == 0)
+ return 0;
+
+ if (al == 0)
+ {
+ al = ah;
+ ah = 0;
+ bit ^= GMP_NUMB_BITS & (bl ^ (bl >> 1));
+ }
+ count_trailing_zeros (c, al);
+ bit ^= c & (bl ^ (bl >> 1));
+
+ c++;
+ if (UNLIKELY (c == GMP_NUMB_BITS))
+ {
+ al = ah;
+ ah = 0;
+ }
+ else
+ {
+ al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
+ ah >>= c;
+ }
+ while ( (ah | bh) > 0)
+ {
+ mp_limb_t th, tl;
+ mp_limb_t bgta;
+
+ sub_ddmmss (th, tl, ah, al, bh, bl);
+ if ( (tl | th) == 0)
+ return 0;
+
+ bgta = LIMB_HIGHBIT_TO_MASK (th);
+
+ /* If b > a, invoke reciprocity */
+ bit ^= (bgta & al & bl);
+
+ /* b <-- min (a, b) */
+ add_ssaaaa (bh, bl, bh, bl, th & bgta, tl & bgta);
+
+ if ( (bh | bl) == 0)
+ return 1 - 2*(bit & 1);
+
+ /* a <-- |a - b| */
+ al = (bgta ^ tl) - bgta;
+ ah = (bgta ^ th);
+
+ if (UNLIKELY (al == 0))
+ {
+ /* If b > a, al == 0 implies that we have a carry to
+ propagate. */
+ al = ah - bgta;
+ ah = 0;
+ bit ^= GMP_NUMB_BITS & (bl ^ (bl >> 1));
+ }
+ count_trailing_zeros (c, al);
+ c++;
+ bit ^= c & (bl ^ (bl >> 1));
+
+ if (UNLIKELY (c == GMP_NUMB_BITS))
+ {
+ al = ah;
+ ah = 0;
+ }
+ else
+ {
+ al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
+ ah >>= c;
+ }
+ }
+
+ ASSERT (bl > 0);
+
+ while ( (al | bl) & GMP_LIMB_HIGHBIT)
+ {
+ /* Need an extra comparison to get the mask. */
+ mp_limb_t t = al - bl;
+ mp_limb_t bgta = - (bl > al);
+
+ if (t == 0)
+ return 0;
+
+ /* If b > a, invoke reciprocity */
+ bit ^= (bgta & al & bl);
+
+ /* b <-- min (a, b) */
+ bl += (bgta & t);
+
+ /* a <-- |a - b| */
+ al = (t ^ bgta) - bgta;
+
+ /* Number of trailing zeros is the same no matter if we look at
+ * t or a, but using t gives more parallelism. */
+ count_trailing_zeros (c, t);
+ c ++;
+ /* (2/b) = -1 if b = 3 or 5 mod 8 */
+ bit ^= c & (bl ^ (bl >> 1));
+
+ if (UNLIKELY (c == GMP_NUMB_BITS))
+ return 1 - 2*(bit & 1);
+
+ al >>= c;
+ }
+
+ /* Here we have a little impedance mismatch. Better to inline it? */
+ return mpn_jacobi_base (2*al+1, 2*bl+1, bit << 1);
+}
+#elif JACOBI_2_METHOD == 2
+int
+mpn_jacobi_2 (mp_srcptr ap, mp_srcptr bp, unsigned bit)
+{
+ mp_limb_t ah, al, bh, bl;
+ int c;
+
+ al = ap[0];
+ ah = ap[1];
+ bl = bp[0];
+ bh = bp[1];
+
+ ASSERT (bl & 1);
+
+ /* Use bit 1. */
+ bit <<= 1;
+
+ if (bh == 0 && bl == 1)
+ /* (a|1) = 1 */
+ return 1 - (bit & 2);
+
+ if (al == 0)
+ {
+ if (ah == 0)
+ /* (0|b) = 0, b > 1 */
+ return 0;
+
+ count_trailing_zeros (c, ah);
+ bit ^= ((GMP_NUMB_BITS + c) << 1) & (bl ^ (bl >> 1));
+
+ al = bl;
+ bl = ah >> c;
+
+ if (bl == 1)
+ /* (1|b) = 1 */
+ return 1 - (bit & 2);
+
+ ah = bh;
+
+ bit ^= al & bl;
+
+ goto b_reduced;
+ }
+ if ( (al & 1) == 0)
+ {
+ count_trailing_zeros (c, al);
+
+ al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
+ ah >>= c;
+ bit ^= (c << 1) & (bl ^ (bl >> 1));
+ }
+ if (ah == 0)
+ {
+ if (bh > 0)
+ {
+ bit ^= al & bl;
+ MP_LIMB_T_SWAP (al, bl);
+ ah = bh;
+ goto b_reduced;
+ }
+ goto ab_reduced;
+ }
+
+ while (bh > 0)
+ {
+ /* Compute (a|b) */
+ while (ah > bh)
+ {
+ sub_ddmmss (ah, al, ah, al, bh, bl);
+ if (al == 0)
+ {
+ count_trailing_zeros (c, ah);
+ bit ^= ((GMP_NUMB_BITS + c) << 1) & (bl ^ (bl >> 1));
+
+ al = bl;
+ bl = ah >> c;
+ ah = bh;
+
+ bit ^= al & bl;
+ goto b_reduced;
+ }
+ count_trailing_zeros (c, al);
+ bit ^= (c << 1) & (bl ^ (bl >> 1));
+ al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
+ ah >>= c;
+ }
+ if (ah == bh)
+ goto cancel_hi;
+
+ if (ah == 0)
+ {
+ bit ^= al & bl;
+ MP_LIMB_T_SWAP (al, bl);
+ ah = bh;
+ break;
+ }
+
+ bit ^= al & bl;
+
+ /* Compute (b|a) */
+ while (bh > ah)
+ {
+ sub_ddmmss (bh, bl, bh, bl, ah, al);
+ if (bl == 0)
+ {
+ count_trailing_zeros (c, bh);
+ bit ^= ((GMP_NUMB_BITS + c) << 1) & (al ^ (al >> 1));
+
+ bl = bh >> c;
+ bit ^= al & bl;
+ goto b_reduced;
+ }
+ count_trailing_zeros (c, bl);
+ bit ^= (c << 1) & (al ^ (al >> 1));
+ bl = ((bh << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (bl >> c);
+ bh >>= c;
+ }
+ bit ^= al & bl;
+
+ /* Compute (a|b) */
+ if (ah == bh)
+ {
+ cancel_hi:
+ if (al < bl)
+ {
+ MP_LIMB_T_SWAP (al, bl);
+ bit ^= al & bl;
+ }
+ al -= bl;
+ if (al == 0)
+ return 0;
+
+ count_trailing_zeros (c, al);
+ bit ^= (c << 1) & (bl ^ (bl >> 1));
+ al >>= c;
+
+ if (al == 1)
+ return 1 - (bit & 2);
+
+ MP_LIMB_T_SWAP (al, bl);
+ bit ^= al & bl;
+ break;
+ }
+ }
+
+ b_reduced:
+ /* Compute (a|b), with b a single limb. */
+ ASSERT (bl & 1);
+
+ if (bl == 1)
+ /* (a|1) = 1 */
+ return 1 - (bit & 2);
+
+ while (ah > 0)
+ {
+ ah -= (al < bl);
+ al -= bl;
+ if (al == 0)
+ {
+ if (ah == 0)
+ return 0;
+ count_trailing_zeros (c, ah);
+ bit ^= ((GMP_NUMB_BITS + c) << 1) & (bl ^ (bl >> 1));
+ al = ah >> c;
+ goto ab_reduced;
+ }
+ count_trailing_zeros (c, al);
+
+ al = ((ah << (GMP_NUMB_BITS - c)) & GMP_NUMB_MASK) | (al >> c);
+ ah >>= c;
+ bit ^= (c << 1) & (bl ^ (bl >> 1));
+ }
+ ab_reduced:
+ ASSERT (bl & 1);
+ ASSERT (bl > 1);
+
+ return mpn_jacobi_base (al, bl, bit);
+}
+#else
+#error Unsupported value for JACOBI_2_METHOD
+#endif
diff --git a/gmp/mpn/generic/logops_n.c b/gmp/mpn/generic/logops_n.c
new file mode 100644
index 0000000000..1b534ff4ba
--- /dev/null
+++ b/gmp/mpn/generic/logops_n.c
@@ -0,0 +1,78 @@
+/* mpn_and_n, mpn_ior_n, etc -- mpn logical operations.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifdef OPERATION_and_n
+#define func __MPN(and_n)
+#define call mpn_and_n
+#endif
+
+#ifdef OPERATION_andn_n
+#define func __MPN(andn_n)
+#define call mpn_andn_n
+#endif
+
+#ifdef OPERATION_nand_n
+#define func __MPN(nand_n)
+#define call mpn_nand_n
+#endif
+
+#ifdef OPERATION_ior_n
+#define func __MPN(ior_n)
+#define call mpn_ior_n
+#endif
+
+#ifdef OPERATION_iorn_n
+#define func __MPN(iorn_n)
+#define call mpn_iorn_n
+#endif
+
+#ifdef OPERATION_nior_n
+#define func __MPN(nior_n)
+#define call mpn_nior_n
+#endif
+
+#ifdef OPERATION_xor_n
+#define func __MPN(xor_n)
+#define call mpn_xor_n
+#endif
+
+#ifdef OPERATION_xnor_n
+#define func __MPN(xnor_n)
+#define call mpn_xnor_n
+#endif
+
+void
+func (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ call (rp, up, vp, n);
+}
diff --git a/gmp/mpn/generic/lshift.c b/gmp/mpn/generic/lshift.c
new file mode 100644
index 0000000000..5182632976
--- /dev/null
+++ b/gmp/mpn/generic/lshift.c
@@ -0,0 +1,73 @@
+/* mpn_lshift -- Shift left low level.
+
+Copyright 1991, 1993, 1994, 1996, 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Shift U (pointed to by up and n limbs long) cnt bits to the left
+ and store the n least significant limbs of the result at rp.
+ Return the bits shifted out from the most significant limb.
+
+ Argument constraints:
+ 1. 0 < cnt < GMP_NUMB_BITS.
+ 2. If the result is to be written over the input, rp must be >= up.
+*/
+
+mp_limb_t
+mpn_lshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt)
+{
+ mp_limb_t high_limb, low_limb;
+ unsigned int tnc;
+ mp_size_t i;
+ mp_limb_t retval;
+
+ ASSERT (n >= 1);
+ ASSERT (cnt >= 1);
+ ASSERT (cnt < GMP_NUMB_BITS);
+ ASSERT (MPN_SAME_OR_DECR_P (rp, up, n));
+
+ up += n;
+ rp += n;
+
+ tnc = GMP_NUMB_BITS - cnt;
+ low_limb = *--up;
+ retval = low_limb >> tnc;
+ high_limb = (low_limb << cnt) & GMP_NUMB_MASK;
+
+ for (i = n - 1; i != 0; i--)
+ {
+ low_limb = *--up;
+ *--rp = high_limb | (low_limb >> tnc);
+ high_limb = (low_limb << cnt) & GMP_NUMB_MASK;
+ }
+ *--rp = high_limb;
+
+ return retval;
+}
diff --git a/gmp/mpn/generic/lshiftc.c b/gmp/mpn/generic/lshiftc.c
new file mode 100644
index 0000000000..e8051b7b93
--- /dev/null
+++ b/gmp/mpn/generic/lshiftc.c
@@ -0,0 +1,74 @@
+/* mpn_lshiftc -- Shift left low level with complement.
+
+Copyright 1991, 1993, 1994, 1996, 2000-2002, 2009 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Shift U (pointed to by up and n limbs long) cnt bits to the left
+ and store the n least significant limbs of the result at rp.
+ Return the bits shifted out from the most significant limb.
+
+ Argument constraints:
+ 1. 0 < cnt < GMP_NUMB_BITS.
+ 2. If the result is to be written over the input, rp must be >= up.
+*/
+
+mp_limb_t
+mpn_lshiftc (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt)
+{
+ mp_limb_t high_limb, low_limb;
+ unsigned int tnc;
+ mp_size_t i;
+ mp_limb_t retval;
+
+ ASSERT (n >= 1);
+ ASSERT (cnt >= 1);
+ ASSERT (cnt < GMP_NUMB_BITS);
+ ASSERT (MPN_SAME_OR_DECR_P (rp, up, n));
+
+ up += n;
+ rp += n;
+
+ tnc = GMP_NUMB_BITS - cnt;
+ low_limb = *--up;
+ retval = low_limb >> tnc;
+ high_limb = (low_limb << cnt);
+
+ for (i = n - 1; i != 0; i--)
+ {
+ low_limb = *--up;
+ *--rp = (~(high_limb | (low_limb >> tnc))) & GMP_NUMB_MASK;
+ high_limb = low_limb << cnt;
+ }
+ *--rp = (~high_limb) & GMP_NUMB_MASK;
+
+ return retval;
+}
diff --git a/gmp/mpn/generic/matrix22_mul.c b/gmp/mpn/generic/matrix22_mul.c
new file mode 100644
index 0000000000..59531eb1b2
--- /dev/null
+++ b/gmp/mpn/generic/matrix22_mul.c
@@ -0,0 +1,322 @@
+/* matrix22_mul.c.
+
+ Contributed by Niels Möller and Marco Bodrato.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2003-2005, 2008, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#define MUL(rp, ap, an, bp, bn) do { \
+ if (an >= bn) \
+ mpn_mul (rp, ap, an, bp, bn); \
+ else \
+ mpn_mul (rp, bp, bn, ap, an); \
+} while (0)
+
+/* Inputs are unsigned. */
+static int
+abs_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
+{
+ int c;
+ MPN_CMP (c, ap, bp, n);
+ if (c >= 0)
+ {
+ mpn_sub_n (rp, ap, bp, n);
+ return 0;
+ }
+ else
+ {
+ mpn_sub_n (rp, bp, ap, n);
+ return 1;
+ }
+}
+
+static int
+add_signed_n (mp_ptr rp,
+ mp_srcptr ap, int as, mp_srcptr bp, int bs, mp_size_t n)
+{
+ if (as != bs)
+ return as ^ abs_sub_n (rp, ap, bp, n);
+ else
+ {
+ ASSERT_NOCARRY (mpn_add_n (rp, ap, bp, n));
+ return as;
+ }
+}
+
+mp_size_t
+mpn_matrix22_mul_itch (mp_size_t rn, mp_size_t mn)
+{
+ if (BELOW_THRESHOLD (rn, MATRIX22_STRASSEN_THRESHOLD)
+ || BELOW_THRESHOLD (mn, MATRIX22_STRASSEN_THRESHOLD))
+ return 3*rn + 2*mn;
+ else
+ return 3*(rn + mn) + 5;
+}
+
+/* Algorithm:
+
+ / s0 \ / 1 0 0 0 \ / r0 \
+ | s1 | | 0 1 0 1 | | r1 |
+ | s2 | | 0 0 -1 1 | | r2 |
+ | s3 | = | 0 1 -1 1 | \ r3 /
+ | s4 | | -1 1 -1 1 |
+ | s5 | | 0 1 0 0 |
+ \ s6 / \ 0 0 1 0 /
+
+ / t0 \ / 1 0 0 0 \ / m0 \
+ | t1 | | 0 1 0 1 | | m1 |
+ | t2 | | 0 0 -1 1 | | m2 |
+ | t3 | = | 0 1 -1 1 | \ m3 /
+ | t4 | | -1 1 -1 1 |
+ | t5 | | 0 1 0 0 |
+ \ t6 / \ 0 0 1 0 /
+
+ Note: the two matrices above are the same, but s_i and t_i are used
+ in the same product, only for i<4, see "A Strassen-like Matrix
+ Multiplication suited for squaring and higher power computation" by
+ M. Bodrato, in Proceedings of ISSAC 2010.
+
+ / r0 \ / 1 0 0 0 0 1 0 \ / s0*t0 \
+ | r1 | = | 0 0 -1 1 -1 1 0 | | s1*t1 |
+ | r2 | | 0 1 0 -1 0 -1 -1 | | s2*t2 |
+ \ r3 / \ 0 1 1 -1 0 -1 0 / | s3*t3 |
+ | s4*t5 |
+ | s5*t6 |
+ \ s6*t4 /
+
+ The scheduling uses two temporaries U0 and U1 to store products, and
+ two, S0 and T0, to store combinations of entries of the two
+ operands.
+*/
+
+/* Computes R = R * M. Elements are numbers R = (r0, r1; r2, r3).
+ *
+ * Resulting elements are of size up to rn + mn + 1.
+ *
+ * Temporary storage: 3 rn + 3 mn + 5. */
+void
+mpn_matrix22_mul_strassen (mp_ptr r0, mp_ptr r1, mp_ptr r2, mp_ptr r3, mp_size_t rn,
+ mp_srcptr m0, mp_srcptr m1, mp_srcptr m2, mp_srcptr m3, mp_size_t mn,
+ mp_ptr tp)
+{
+ mp_ptr s0, t0, u0, u1;
+ int r1s, r3s, s0s, t0s, u1s;
+ s0 = tp; tp += rn + 1;
+ t0 = tp; tp += mn + 1;
+ u0 = tp; tp += rn + mn + 1;
+ u1 = tp; /* rn + mn + 2 */
+
+ MUL (u0, r1, rn, m2, mn); /* u5 = s5 * t6 */
+ r3s = abs_sub_n (r3, r3, r2, rn); /* r3 - r2 */
+ if (r3s)
+ {
+ r1s = abs_sub_n (r1, r1, r3, rn);
+ r1[rn] = 0;
+ }
+ else
+ {
+ r1[rn] = mpn_add_n (r1, r1, r3, rn);
+ r1s = 0; /* r1 - r2 + r3 */
+ }
+ if (r1s)
+ {
+ s0[rn] = mpn_add_n (s0, r1, r0, rn);
+ s0s = 0;
+ }
+ else if (r1[rn] != 0)
+ {
+ s0[rn] = r1[rn] - mpn_sub_n (s0, r1, r0, rn);
+ s0s = 1; /* s4 = -r0 + r1 - r2 + r3 */
+ /* Reverse sign! */
+ }
+ else
+ {
+ s0s = abs_sub_n (s0, r0, r1, rn);
+ s0[rn] = 0;
+ }
+ MUL (u1, r0, rn, m0, mn); /* u0 = s0 * t0 */
+ r0[rn+mn] = mpn_add_n (r0, u0, u1, rn + mn);
+ ASSERT (r0[rn+mn] < 2); /* u0 + u5 */
+
+ t0s = abs_sub_n (t0, m3, m2, mn);
+ u1s = r3s^t0s^1; /* Reverse sign! */
+ MUL (u1, r3, rn, t0, mn); /* u2 = s2 * t2 */
+ u1[rn+mn] = 0;
+ if (t0s)
+ {
+ t0s = abs_sub_n (t0, m1, t0, mn);
+ t0[mn] = 0;
+ }
+ else
+ {
+ t0[mn] = mpn_add_n (t0, t0, m1, mn);
+ }
+
+ /* FIXME: Could be simplified if we had space for rn + mn + 2 limbs
+ at r3. I'd expect that for matrices of random size, the high
+ words t0[mn] and r1[rn] are non-zero with a pretty small
+ probability. If that can be confirmed this should be done as an
+ unconditional rn x (mn+1) followed by an if (UNLIKELY (r1[rn]))
+ add_n. */
+ if (t0[mn] != 0)
+ {
+ MUL (r3, r1, rn, t0, mn + 1); /* u3 = s3 * t3 */
+ ASSERT (r1[rn] < 2);
+ if (r1[rn] != 0)
+ mpn_add_n (r3 + rn, r3 + rn, t0, mn + 1);
+ }
+ else
+ {
+ MUL (r3, r1, rn + 1, t0, mn);
+ }
+
+ ASSERT (r3[rn+mn] < 4);
+
+ u0[rn+mn] = 0;
+ if (r1s^t0s)
+ {
+ r3s = abs_sub_n (r3, u0, r3, rn + mn + 1);
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_add_n (r3, r3, u0, rn + mn + 1));
+ r3s = 0; /* u3 + u5 */
+ }
+
+ if (t0s)
+ {
+ t0[mn] = mpn_add_n (t0, t0, m0, mn);
+ }
+ else if (t0[mn] != 0)
+ {
+ t0[mn] -= mpn_sub_n (t0, t0, m0, mn);
+ }
+ else
+ {
+ t0s = abs_sub_n (t0, t0, m0, mn);
+ }
+ MUL (u0, r2, rn, t0, mn + 1); /* u6 = s6 * t4 */
+ ASSERT (u0[rn+mn] < 2);
+ if (r1s)
+ {
+ ASSERT_NOCARRY (mpn_sub_n (r1, r2, r1, rn));
+ }
+ else
+ {
+ r1[rn] += mpn_add_n (r1, r1, r2, rn);
+ }
+ rn++;
+ t0s = add_signed_n (r2, r3, r3s, u0, t0s, rn + mn);
+ /* u3 + u5 + u6 */
+ ASSERT (r2[rn+mn-1] < 4);
+ r3s = add_signed_n (r3, r3, r3s, u1, u1s, rn + mn);
+ /* -u2 + u3 + u5 */
+ ASSERT (r3[rn+mn-1] < 3);
+ MUL (u0, s0, rn, m1, mn); /* u4 = s4 * t5 */
+ ASSERT (u0[rn+mn-1] < 2);
+ t0[mn] = mpn_add_n (t0, m3, m1, mn);
+ MUL (u1, r1, rn, t0, mn + 1); /* u1 = s1 * t1 */
+ mn += rn;
+ ASSERT (u1[mn-1] < 4);
+ ASSERT (u1[mn] == 0);
+ ASSERT_NOCARRY (add_signed_n (r1, r3, r3s, u0, s0s, mn));
+ /* -u2 + u3 - u4 + u5 */
+ ASSERT (r1[mn-1] < 2);
+ if (r3s)
+ {
+ ASSERT_NOCARRY (mpn_add_n (r3, u1, r3, mn));
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_sub_n (r3, u1, r3, mn));
+ /* u1 + u2 - u3 - u5 */
+ }
+ ASSERT (r3[mn-1] < 2);
+ if (t0s)
+ {
+ ASSERT_NOCARRY (mpn_add_n (r2, u1, r2, mn));
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_sub_n (r2, u1, r2, mn));
+ /* u1 - u3 - u5 - u6 */
+ }
+ ASSERT (r2[mn-1] < 2);
+}
+
+void
+mpn_matrix22_mul (mp_ptr r0, mp_ptr r1, mp_ptr r2, mp_ptr r3, mp_size_t rn,
+ mp_srcptr m0, mp_srcptr m1, mp_srcptr m2, mp_srcptr m3, mp_size_t mn,
+ mp_ptr tp)
+{
+ if (BELOW_THRESHOLD (rn, MATRIX22_STRASSEN_THRESHOLD)
+ || BELOW_THRESHOLD (mn, MATRIX22_STRASSEN_THRESHOLD))
+ {
+ mp_ptr p0, p1;
+ unsigned i;
+
+ /* Temporary storage: 3 rn + 2 mn */
+ p0 = tp + rn;
+ p1 = p0 + rn + mn;
+
+ for (i = 0; i < 2; i++)
+ {
+ MPN_COPY (tp, r0, rn);
+
+ if (rn >= mn)
+ {
+ mpn_mul (p0, r0, rn, m0, mn);
+ mpn_mul (p1, r1, rn, m3, mn);
+ mpn_mul (r0, r1, rn, m2, mn);
+ mpn_mul (r1, tp, rn, m1, mn);
+ }
+ else
+ {
+ mpn_mul (p0, m0, mn, r0, rn);
+ mpn_mul (p1, m3, mn, r1, rn);
+ mpn_mul (r0, m2, mn, r1, rn);
+ mpn_mul (r1, m1, mn, tp, rn);
+ }
+ r0[rn+mn] = mpn_add_n (r0, r0, p0, rn + mn);
+ r1[rn+mn] = mpn_add_n (r1, r1, p1, rn + mn);
+
+ r0 = r2; r1 = r3;
+ }
+ }
+ else
+ mpn_matrix22_mul_strassen (r0, r1, r2, r3, rn,
+ m0, m1, m2, m3, mn, tp);
+}
diff --git a/gmp/mpn/generic/matrix22_mul1_inverse_vector.c b/gmp/mpn/generic/matrix22_mul1_inverse_vector.c
new file mode 100644
index 0000000000..83b2fb5134
--- /dev/null
+++ b/gmp/mpn/generic/matrix22_mul1_inverse_vector.c
@@ -0,0 +1,65 @@
+/* matrix22_mul1_inverse_vector.c
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2008, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Sets (r;b) = M^{-1}(a;b), with M^{-1} = (u11, -u01; -u10, u00) from
+ the left. Uses three buffers, to avoid a copy. */
+mp_size_t
+mpn_matrix22_mul1_inverse_vector (const struct hgcd_matrix1 *M,
+ mp_ptr rp, mp_srcptr ap, mp_ptr bp, mp_size_t n)
+{
+ mp_limb_t h0, h1;
+
+ /* Compute (r;b) <-- (u11 a - u01 b; -u10 a + u00 b) as
+
+ r = u11 * a
+ r -= u01 * b
+ b *= u00
+ b -= u10 * a
+ */
+
+ h0 = mpn_mul_1 (rp, ap, n, M->u[1][1]);
+ h1 = mpn_submul_1 (rp, bp, n, M->u[0][1]);
+ ASSERT (h0 == h1);
+
+ h0 = mpn_mul_1 (bp, bp, n, M->u[0][0]);
+ h1 = mpn_submul_1 (bp, ap, n, M->u[1][0]);
+ ASSERT (h0 == h1);
+
+ n -= (rp[n-1] | bp[n-1]) == 0;
+ return n;
+}
diff --git a/gmp/mpn/generic/mod_1.c b/gmp/mpn/generic/mod_1.c
new file mode 100644
index 0000000000..0212020201
--- /dev/null
+++ b/gmp/mpn/generic/mod_1.c
@@ -0,0 +1,281 @@
+/* mpn_mod_1(dividend_ptr, dividend_size, divisor_limb) --
+ Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ Return the single-limb remainder.
+ There are no constraints on the value of the divisor.
+
+Copyright 1991, 1993, 1994, 1999, 2000, 2002, 2007-2009, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* The size where udiv_qrnnd_preinv should be used rather than udiv_qrnnd,
+ meaning the quotient size where that should happen, the quotient size
+ being how many udiv divisions will be done.
+
+ The default is to use preinv always, CPUs where this doesn't suit have
+ tuned thresholds. Note in particular that preinv should certainly be
+ used if that's the only division available (USE_PREINV_ALWAYS). */
+
+#ifndef MOD_1_NORM_THRESHOLD
+#define MOD_1_NORM_THRESHOLD 0
+#endif
+
+#ifndef MOD_1_UNNORM_THRESHOLD
+#define MOD_1_UNNORM_THRESHOLD 0
+#endif
+
+#ifndef MOD_1U_TO_MOD_1_1_THRESHOLD
+#define MOD_1U_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX /* default is not to use mpn_mod_1s */
+#endif
+
+#ifndef MOD_1N_TO_MOD_1_1_THRESHOLD
+#define MOD_1N_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX /* default is not to use mpn_mod_1s */
+#endif
+
+#ifndef MOD_1_1_TO_MOD_1_2_THRESHOLD
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 10
+#endif
+
+#ifndef MOD_1_2_TO_MOD_1_4_THRESHOLD
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 20
+#endif
+
+#if TUNE_PROGRAM_BUILD && !HAVE_NATIVE_mpn_mod_1_1p
+/* Duplicates declarations in tune/speed.h */
+mp_limb_t mpn_mod_1_1p_1 (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t [4]);
+mp_limb_t mpn_mod_1_1p_2 (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t [4]);
+
+void mpn_mod_1_1p_cps_1 (mp_limb_t [4], mp_limb_t);
+void mpn_mod_1_1p_cps_2 (mp_limb_t [4], mp_limb_t);
+
+#undef mpn_mod_1_1p
+#define mpn_mod_1_1p(ap, n, b, pre) \
+ (mod_1_1p_method == 1 ? mpn_mod_1_1p_1 (ap, n, b, pre) \
+ : (mod_1_1p_method == 2 ? mpn_mod_1_1p_2 (ap, n, b, pre) \
+ : __gmpn_mod_1_1p (ap, n, b, pre)))
+
+#undef mpn_mod_1_1p_cps
+#define mpn_mod_1_1p_cps(pre, b) \
+ (mod_1_1p_method == 1 ? mpn_mod_1_1p_cps_1 (pre, b) \
+ : (mod_1_1p_method == 2 ? mpn_mod_1_1p_cps_2 (pre, b) \
+ : __gmpn_mod_1_1p_cps (pre, b)))
+#endif /* TUNE_PROGRAM_BUILD && !HAVE_NATIVE_mpn_mod_1_1p */
+
+
+/* The comments in mpn/generic/divrem_1.c apply here too.
+
+ As noted in the algorithms section of the manual, the shifts in the loop
+ for the unnorm case can be avoided by calculating r = a%(d*2^n), followed
+ by a final (r*2^n)%(d*2^n). In fact if it happens that a%(d*2^n) can
+ skip a division where (a*2^n)%(d*2^n) can't then there's the same number
+ of divide steps, though how often that happens depends on the assumed
+ distributions of dividend and divisor. In any case this idea is left to
+ CPU specific implementations to consider. */
+
+static mp_limb_t
+mpn_mod_1_unnorm (mp_srcptr up, mp_size_t un, mp_limb_t d)
+{
+ mp_size_t i;
+ mp_limb_t n1, n0, r;
+ mp_limb_t dummy;
+ int cnt;
+
+ ASSERT (un > 0);
+ ASSERT (d != 0);
+
+ d <<= GMP_NAIL_BITS;
+
+ /* Skip a division if high < divisor. Having the test here before
+ normalizing will still skip as often as possible. */
+ r = up[un - 1] << GMP_NAIL_BITS;
+ if (r < d)
+ {
+ r >>= GMP_NAIL_BITS;
+ un--;
+ if (un == 0)
+ return r;
+ }
+ else
+ r = 0;
+
+ /* If udiv_qrnnd doesn't need a normalized divisor, can use the simple
+ code above. */
+ if (! UDIV_NEEDS_NORMALIZATION
+ && BELOW_THRESHOLD (un, MOD_1_UNNORM_THRESHOLD))
+ {
+ for (i = un - 1; i >= 0; i--)
+ {
+ n0 = up[i] << GMP_NAIL_BITS;
+ udiv_qrnnd (dummy, r, r, n0, d);
+ r >>= GMP_NAIL_BITS;
+ }
+ return r;
+ }
+
+ count_leading_zeros (cnt, d);
+ d <<= cnt;
+
+ n1 = up[un - 1] << GMP_NAIL_BITS;
+ r = (r << cnt) | (n1 >> (GMP_LIMB_BITS - cnt));
+
+ if (UDIV_NEEDS_NORMALIZATION
+ && BELOW_THRESHOLD (un, MOD_1_UNNORM_THRESHOLD))
+ {
+ mp_limb_t nshift;
+ for (i = un - 2; i >= 0; i--)
+ {
+ n0 = up[i] << GMP_NAIL_BITS;
+ nshift = (n1 << cnt) | (n0 >> (GMP_NUMB_BITS - cnt));
+ udiv_qrnnd (dummy, r, r, nshift, d);
+ r >>= GMP_NAIL_BITS;
+ n1 = n0;
+ }
+ udiv_qrnnd (dummy, r, r, n1 << cnt, d);
+ r >>= GMP_NAIL_BITS;
+ return r >> cnt;
+ }
+ else
+ {
+ mp_limb_t inv, nshift;
+ invert_limb (inv, d);
+
+ for (i = un - 2; i >= 0; i--)
+ {
+ n0 = up[i] << GMP_NAIL_BITS;
+ nshift = (n1 << cnt) | (n0 >> (GMP_NUMB_BITS - cnt));
+ udiv_rnnd_preinv (r, r, nshift, d, inv);
+ r >>= GMP_NAIL_BITS;
+ n1 = n0;
+ }
+ udiv_rnnd_preinv (r, r, n1 << cnt, d, inv);
+ r >>= GMP_NAIL_BITS;
+ return r >> cnt;
+ }
+}
+
+static mp_limb_t
+mpn_mod_1_norm (mp_srcptr up, mp_size_t un, mp_limb_t d)
+{
+ mp_size_t i;
+ mp_limb_t n0, r;
+ mp_limb_t dummy;
+
+ ASSERT (un > 0);
+
+ d <<= GMP_NAIL_BITS;
+
+ ASSERT (d & GMP_LIMB_HIGHBIT);
+
+ /* High limb is initial remainder, possibly with one subtract of
+ d to get r<d. */
+ r = up[un - 1] << GMP_NAIL_BITS;
+ if (r >= d)
+ r -= d;
+ r >>= GMP_NAIL_BITS;
+ un--;
+ if (un == 0)
+ return r;
+
+ if (BELOW_THRESHOLD (un, MOD_1_NORM_THRESHOLD))
+ {
+ for (i = un - 1; i >= 0; i--)
+ {
+ n0 = up[i] << GMP_NAIL_BITS;
+ udiv_qrnnd (dummy, r, r, n0, d);
+ r >>= GMP_NAIL_BITS;
+ }
+ return r;
+ }
+ else
+ {
+ mp_limb_t inv;
+ invert_limb (inv, d);
+ for (i = un - 1; i >= 0; i--)
+ {
+ n0 = up[i] << GMP_NAIL_BITS;
+ udiv_rnnd_preinv (r, r, n0, d, inv);
+ r >>= GMP_NAIL_BITS;
+ }
+ return r;
+ }
+}
+
+mp_limb_t
+mpn_mod_1 (mp_srcptr ap, mp_size_t n, mp_limb_t b)
+{
+ ASSERT (n >= 0);
+ ASSERT (b != 0);
+
+ /* Should this be handled at all? Rely on callers? Note un==0 is currently
+ required by mpz/fdiv_r_ui.c and possibly other places. */
+ if (n == 0)
+ return 0;
+
+ if (UNLIKELY ((b & GMP_NUMB_HIGHBIT) != 0))
+ {
+ if (BELOW_THRESHOLD (n, MOD_1N_TO_MOD_1_1_THRESHOLD))
+ {
+ return mpn_mod_1_norm (ap, n, b);
+ }
+ else
+ {
+ mp_limb_t pre[4];
+ mpn_mod_1_1p_cps (pre, b);
+ return mpn_mod_1_1p (ap, n, b, pre);
+ }
+ }
+ else
+ {
+ if (BELOW_THRESHOLD (n, MOD_1U_TO_MOD_1_1_THRESHOLD))
+ {
+ return mpn_mod_1_unnorm (ap, n, b);
+ }
+ else if (BELOW_THRESHOLD (n, MOD_1_1_TO_MOD_1_2_THRESHOLD))
+ {
+ mp_limb_t pre[4];
+ mpn_mod_1_1p_cps (pre, b);
+ return mpn_mod_1_1p (ap, n, b << pre[1], pre);
+ }
+ else if (BELOW_THRESHOLD (n, MOD_1_2_TO_MOD_1_4_THRESHOLD) || UNLIKELY (b > GMP_NUMB_MASK / 4))
+ {
+ mp_limb_t pre[5];
+ mpn_mod_1s_2p_cps (pre, b);
+ return mpn_mod_1s_2p (ap, n, b << pre[1], pre);
+ }
+ else
+ {
+ mp_limb_t pre[7];
+ mpn_mod_1s_4p_cps (pre, b);
+ return mpn_mod_1s_4p (ap, n, b << pre[1], pre);
+ }
+ }
+}
diff --git a/gmp/mpn/generic/mod_1_1.c b/gmp/mpn/generic/mod_1_1.c
new file mode 100644
index 0000000000..2e111399ed
--- /dev/null
+++ b/gmp/mpn/generic/mod_1_1.c
@@ -0,0 +1,332 @@
+/* mpn_mod_1_1p (ap, n, b, cps)
+ Divide (ap,,n) by b. Return the single-limb remainder.
+
+ Contributed to the GNU project by Torbjorn Granlund and Niels Möller.
+ Based on a suggestion by Peter L. Montgomery.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2008-2011, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef MOD_1_1P_METHOD
+# define MOD_1_1P_METHOD 1 /* need to make sure this is 2 for asm testing */
+#endif
+
+/* Define some longlong.h-style macros, but for wider operations.
+ * add_mssaaaa is like longlong.h's add_ssaaaa, but also generates
+ * carry out, in the form of a mask. */
+
+#if defined (__GNUC__)
+
+#if HAVE_HOST_CPU_FAMILY_x86 && W_TYPE_SIZE == 32
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ __asm__ ( "add %6, %k2\n\t" \
+ "adc %4, %k1\n\t" \
+ "sbb %k0, %k0" \
+ : "=r" (m), "=r" (s1), "=&r" (s0) \
+ : "1" ((USItype)(a1)), "g" ((USItype)(b1)), \
+ "%2" ((USItype)(a0)), "g" ((USItype)(b0)))
+#endif
+
+#if HAVE_HOST_CPU_FAMILY_x86_64 && W_TYPE_SIZE == 64
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ __asm__ ( "add %6, %q2\n\t" \
+ "adc %4, %q1\n\t" \
+ "sbb %q0, %q0" \
+ : "=r" (m), "=r" (s1), "=&r" (s0) \
+ : "1" ((UDItype)(a1)), "rme" ((UDItype)(b1)), \
+ "%2" ((UDItype)(a0)), "rme" ((UDItype)(b0)))
+#endif
+
+#if defined (__sparc__) && W_TYPE_SIZE == 32
+#define add_mssaaaa(m, sh, sl, ah, al, bh, bl) \
+ __asm__ ( "addcc %r5, %6, %2\n\t" \
+ "addxcc %r3, %4, %1\n\t" \
+ "subx %%g0, %%g0, %0" \
+ : "=r" (m), "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl) \
+ __CLOBBER_CC)
+#endif
+
+#if defined (__sparc__) && W_TYPE_SIZE == 64
+#define add_mssaaaa(m, sh, sl, ah, al, bh, bl) \
+ __asm__ ( "addcc %r5, %6, %2\n\t" \
+ "addccc %r7, %8, %%g0\n\t" \
+ "addccc %r3, %4, %1\n\t" \
+ "clr %0\n\t" \
+ "movcs %%xcc, -1, %0" \
+ : "=r" (m), "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl), \
+ "rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ __CLOBBER_CC)
+#if __VIS__ >= 0x300
+#undef add_mssaaaa
+#define add_mssaaaa(m, sh, sl, ah, al, bh, bl) \
+ __asm__ ( "addcc %r5, %6, %2\n\t" \
+ "addxccc %r3, %4, %1\n\t" \
+ "clr %0\n\t" \
+ "movcs %%xcc, -1, %0" \
+ : "=r" (m), "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl) \
+ __CLOBBER_CC)
+#endif
+#endif
+
+#if HAVE_HOST_CPU_FAMILY_powerpc && !defined (_LONG_LONG_LIMB)
+/* This works fine for 32-bit and 64-bit limbs, except for 64-bit limbs with a
+ processor running in 32-bit mode, since the carry flag then gets the 32-bit
+ carry. */
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ __asm__ ( "add%I6c %2, %5, %6\n\t" \
+ "adde %1, %3, %4\n\t" \
+ "subfe %0, %0, %0\n\t" \
+ "nor %0, %0, %0" \
+ : "=r" (m), "=r" (s1), "=&r" (s0) \
+ : "r" (a1), "r" (b1), "%r" (a0), "rI" (b0))
+#endif
+
+#if defined (__s390x__) && W_TYPE_SIZE == 64
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ __asm__ ( "algr %2, %6\n\t" \
+ "alcgr %1, %4\n\t" \
+ "lghi %0, 0\n\t" \
+ "alcgr %0, %0\n\t" \
+ "lcgr %0, %0" \
+ : "=r" (m), "=r" (s1), "=&r" (s0) \
+ : "1" ((UDItype)(a1)), "r" ((UDItype)(b1)), \
+ "%2" ((UDItype)(a0)), "r" ((UDItype)(b0)) __CLOBBER_CC)
+#endif
+
+#if defined (__arm__) && W_TYPE_SIZE == 32
+#define add_mssaaaa(m, sh, sl, ah, al, bh, bl) \
+ __asm__ ( "adds %2, %5, %6\n\t" \
+ "adcs %1, %3, %4\n\t" \
+ "movcc %0, #0\n\t" \
+ "movcs %0, #-1" \
+ : "=r" (m), "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC)
+#endif
+#endif /* defined (__GNUC__) */
+
+#ifndef add_mssaaaa
+#define add_mssaaaa(m, s1, s0, a1, a0, b1, b0) \
+ do { \
+ UWtype __s0, __s1, __c0, __c1; \
+ __s0 = (a0) + (b0); \
+ __s1 = (a1) + (b1); \
+ __c0 = __s0 < (a0); \
+ __c1 = __s1 < (a1); \
+ (s0) = __s0; \
+ __s1 = __s1 + __c0; \
+ (s1) = __s1; \
+ (m) = - (__c1 + (__s1 < __c0)); \
+ } while (0)
+#endif
+
+#if MOD_1_1P_METHOD == 1
+void
+mpn_mod_1_1p_cps (mp_limb_t cps[4], mp_limb_t b)
+{
+ mp_limb_t bi;
+ mp_limb_t B1modb, B2modb;
+ int cnt;
+
+ count_leading_zeros (cnt, b);
+
+ b <<= cnt;
+ invert_limb (bi, b);
+
+ cps[0] = bi;
+ cps[1] = cnt;
+
+ B1modb = -b;
+ if (LIKELY (cnt != 0))
+ B1modb *= ((bi >> (GMP_LIMB_BITS-cnt)) | (CNST_LIMB(1) << cnt));
+ ASSERT (B1modb <= b); /* NB: not fully reduced mod b */
+ cps[2] = B1modb >> cnt;
+
+ /* In the normalized case, this can be simplified to
+ *
+ * B2modb = - b * bi;
+ * ASSERT (B2modb <= b); // NB: equality iff b = B/2
+ */
+ udiv_rnnd_preinv (B2modb, B1modb, CNST_LIMB(0), b, bi);
+ cps[3] = B2modb >> cnt;
+}
+
+mp_limb_t
+mpn_mod_1_1p (mp_srcptr ap, mp_size_t n, mp_limb_t b, const mp_limb_t bmodb[4])
+{
+ mp_limb_t rh, rl, bi, ph, pl, r;
+ mp_limb_t B1modb, B2modb;
+ mp_size_t i;
+ int cnt;
+ mp_limb_t mask;
+
+ ASSERT (n >= 2); /* fix tuneup.c if this is changed */
+
+ B1modb = bmodb[2];
+ B2modb = bmodb[3];
+
+ rl = ap[n - 1];
+ umul_ppmm (ph, pl, rl, B1modb);
+ add_ssaaaa (rh, rl, ph, pl, CNST_LIMB(0), ap[n - 2]);
+
+ for (i = n - 3; i >= 0; i -= 1)
+ {
+ /* rr = ap[i] < B
+ + LO(rr) * (B mod b) <= (B-1)(b-1)
+ + HI(rr) * (B^2 mod b) <= (B-1)(b-1)
+ */
+ umul_ppmm (ph, pl, rl, B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[i]);
+
+ umul_ppmm (rh, rl, rh, B2modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ }
+
+ cnt = bmodb[1];
+ bi = bmodb[0];
+
+ if (LIKELY (cnt != 0))
+ rh = (rh << cnt) | (rl >> (GMP_LIMB_BITS - cnt));
+
+ mask = -(mp_limb_t) (rh >= b);
+ rh -= mask & b;
+
+ udiv_rnnd_preinv (r, rh, rl << cnt, b, bi);
+
+ return r >> cnt;
+}
+#endif /* MOD_1_1P_METHOD == 1 */
+
+#if MOD_1_1P_METHOD == 2
+void
+mpn_mod_1_1p_cps (mp_limb_t cps[4], mp_limb_t b)
+{
+ mp_limb_t bi;
+ mp_limb_t B2modb;
+ int cnt;
+
+ count_leading_zeros (cnt, b);
+
+ b <<= cnt;
+ invert_limb (bi, b);
+
+ cps[0] = bi;
+ cps[1] = cnt;
+
+ if (LIKELY (cnt != 0))
+ {
+ mp_limb_t B1modb = -b;
+ B1modb *= ((bi >> (GMP_LIMB_BITS-cnt)) | (CNST_LIMB(1) << cnt));
+ ASSERT (B1modb <= b); /* NB: not fully reduced mod b */
+ cps[2] = B1modb >> cnt;
+ }
+ B2modb = - b * bi;
+ ASSERT (B2modb <= b); // NB: equality iff b = B/2
+ cps[3] = B2modb;
+}
+
+mp_limb_t
+mpn_mod_1_1p (mp_srcptr ap, mp_size_t n, mp_limb_t b, const mp_limb_t bmodb[4])
+{
+ int cnt;
+ mp_limb_t bi, B1modb;
+ mp_limb_t r0, r1;
+ mp_limb_t r;
+
+ ASSERT (n >= 2); /* fix tuneup.c if this is changed */
+
+ r0 = ap[n-2];
+ r1 = ap[n-1];
+
+ if (n > 2)
+ {
+ mp_limb_t B2modb, B2mb;
+ mp_limb_t p0, p1;
+ mp_limb_t r2;
+ mp_size_t j;
+
+ B2modb = bmodb[3];
+ B2mb = B2modb - b;
+
+ umul_ppmm (p1, p0, r1, B2modb);
+ add_mssaaaa (r2, r1, r0, r0, ap[n-3], p1, p0);
+
+ for (j = n-4; j >= 0; j--)
+ {
+ mp_limb_t cy;
+ /* mp_limb_t t = r0 + B2mb; */
+ umul_ppmm (p1, p0, r1, B2modb);
+
+ ADDC_LIMB (cy, r0, r0, r2 & B2modb);
+ /* Alternative, for cmov: if (cy) r0 = t; */
+ r0 -= (-cy) & b;
+ add_mssaaaa (r2, r1, r0, r0, ap[j], p1, p0);
+ }
+
+ r1 -= (r2 & b);
+ }
+
+ cnt = bmodb[1];
+
+ if (LIKELY (cnt != 0))
+ {
+ mp_limb_t t;
+ mp_limb_t B1modb = bmodb[2];
+
+ umul_ppmm (r1, t, r1, B1modb);
+ r0 += t;
+ r1 += (r0 < t);
+
+ /* Normalize */
+ r1 = (r1 << cnt) | (r0 >> (GMP_LIMB_BITS - cnt));
+ r0 <<= cnt;
+
+ /* NOTE: Might get r1 == b here, but udiv_rnnd_preinv allows that. */
+ }
+ else
+ {
+ mp_limb_t mask = -(mp_limb_t) (r1 >= b);
+ r1 -= mask & b;
+ }
+
+ bi = bmodb[0];
+
+ udiv_rnnd_preinv (r, r1, r0, b, bi);
+ return r >> cnt;
+}
+#endif /* MOD_1_1P_METHOD == 2 */
diff --git a/gmp/mpn/generic/mod_1_2.c b/gmp/mpn/generic/mod_1_2.c
new file mode 100644
index 0000000000..7acf3dbdd1
--- /dev/null
+++ b/gmp/mpn/generic/mod_1_2.c
@@ -0,0 +1,149 @@
+/* mpn_mod_1s_2p (ap, n, b, cps)
+ Divide (ap,,n) by b. Return the single-limb remainder.
+ Requires that b < B / 2.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+ Based on a suggestion by Peter L. Montgomery.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2008-2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpn_mod_1s_2p_cps (mp_limb_t cps[5], mp_limb_t b)
+{
+ mp_limb_t bi;
+ mp_limb_t B1modb, B2modb, B3modb;
+ int cnt;
+
+ ASSERT (b <= (~(mp_limb_t) 0) / 2);
+
+ count_leading_zeros (cnt, b);
+
+ b <<= cnt;
+ invert_limb (bi, b);
+
+ cps[0] = bi;
+ cps[1] = cnt;
+
+ B1modb = -b * ((bi >> (GMP_LIMB_BITS-cnt)) | (CNST_LIMB(1) << cnt));
+ ASSERT (B1modb <= b); /* NB: not fully reduced mod b */
+ cps[2] = B1modb >> cnt;
+
+ udiv_rnnd_preinv (B2modb, B1modb, CNST_LIMB(0), b, bi);
+ cps[3] = B2modb >> cnt;
+
+ udiv_rnnd_preinv (B3modb, B2modb, CNST_LIMB(0), b, bi);
+ cps[4] = B3modb >> cnt;
+
+#if WANT_ASSERT
+ {
+ int i;
+ b = cps[2];
+ for (i = 3; i <= 4; i++)
+ {
+ b += cps[i];
+ ASSERT (b >= cps[i]);
+ }
+ }
+#endif
+}
+
+mp_limb_t
+mpn_mod_1s_2p (mp_srcptr ap, mp_size_t n, mp_limb_t b, const mp_limb_t cps[5])
+{
+ mp_limb_t rh, rl, bi, ph, pl, ch, cl, r;
+ mp_limb_t B1modb, B2modb, B3modb;
+ mp_size_t i;
+ int cnt;
+
+ ASSERT (n >= 1);
+
+ B1modb = cps[2];
+ B2modb = cps[3];
+ B3modb = cps[4];
+
+ if ((n & 1) != 0)
+ {
+ if (n == 1)
+ {
+ rl = ap[n - 1];
+ bi = cps[0];
+ cnt = cps[1];
+ udiv_rnnd_preinv (r, rl >> (GMP_LIMB_BITS - cnt),
+ rl << cnt, b, bi);
+ return r >> cnt;
+ }
+
+ umul_ppmm (ph, pl, ap[n - 2], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[n - 3]);
+ umul_ppmm (rh, rl, ap[n - 1], B2modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ n--;
+ }
+ else
+ {
+ rh = ap[n - 1];
+ rl = ap[n - 2];
+ }
+
+ for (i = n - 4; i >= 0; i -= 2)
+ {
+ /* rr = ap[i] < B
+ + ap[i+1] * (B mod b) <= (B-1)(b-1)
+ + LO(rr) * (B^2 mod b) <= (B-1)(b-1)
+ + HI(rr) * (B^3 mod b) <= (B-1)(b-1)
+ */
+ umul_ppmm (ph, pl, ap[i + 1], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[i + 0]);
+
+ umul_ppmm (ch, cl, rl, B2modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm (rh, rl, rh, B3modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ }
+
+ umul_ppmm (rh, cl, rh, B1modb);
+ add_ssaaaa (rh, rl, rh, rl, CNST_LIMB(0), cl);
+
+ cnt = cps[1];
+ bi = cps[0];
+
+ r = (rh << cnt) | (rl >> (GMP_LIMB_BITS - cnt));
+ udiv_rnnd_preinv (r, r, rl << cnt, b, bi);
+
+ return r >> cnt;
+}
diff --git a/gmp/mpn/generic/mod_1_3.c b/gmp/mpn/generic/mod_1_3.c
new file mode 100644
index 0000000000..f4137f4315
--- /dev/null
+++ b/gmp/mpn/generic/mod_1_3.c
@@ -0,0 +1,157 @@
+/* mpn_mod_1s_3p (ap, n, b, cps)
+ Divide (ap,,n) by b. Return the single-limb remainder.
+ Requires that d < B / 3.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+ Based on a suggestion by Peter L. Montgomery.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2008-2010, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpn_mod_1s_3p_cps (mp_limb_t cps[6], mp_limb_t b)
+{
+ mp_limb_t bi;
+ mp_limb_t B1modb, B2modb, B3modb, B4modb;
+ int cnt;
+
+ ASSERT (b <= (~(mp_limb_t) 0) / 3);
+
+ count_leading_zeros (cnt, b);
+
+ b <<= cnt;
+ invert_limb (bi, b);
+
+ cps[0] = bi;
+ cps[1] = cnt;
+
+ B1modb = -b * ((bi >> (GMP_LIMB_BITS-cnt)) | (CNST_LIMB(1) << cnt));
+ ASSERT (B1modb <= b); /* NB: not fully reduced mod b */
+ cps[2] = B1modb >> cnt;
+
+ udiv_rnnd_preinv (B2modb, B1modb, CNST_LIMB(0), b, bi);
+ cps[3] = B2modb >> cnt;
+
+ udiv_rnnd_preinv (B3modb, B2modb, CNST_LIMB(0), b, bi);
+ cps[4] = B3modb >> cnt;
+
+ udiv_rnnd_preinv (B4modb, B3modb, CNST_LIMB(0), b, bi);
+ cps[5] = B4modb >> cnt;
+
+#if WANT_ASSERT
+ {
+ int i;
+ b = cps[2];
+ for (i = 3; i <= 5; i++)
+ {
+ b += cps[i];
+ ASSERT (b >= cps[i]);
+ }
+ }
+#endif
+}
+
+mp_limb_t
+mpn_mod_1s_3p (mp_srcptr ap, mp_size_t n, mp_limb_t b, const mp_limb_t cps[6])
+{
+ mp_limb_t rh, rl, bi, ph, pl, ch, cl, r;
+ mp_limb_t B1modb, B2modb, B3modb, B4modb;
+ mp_size_t i;
+ int cnt;
+
+ ASSERT (n >= 1);
+
+ B1modb = cps[2];
+ B2modb = cps[3];
+ B3modb = cps[4];
+ B4modb = cps[5];
+
+ /* We compute n mod 3 in a tricky way, which works except for when n is so
+ close to the maximum size that we don't need to support it. The final
+ cast to int is a workaround for HP cc. */
+ switch ((int) ((mp_limb_t) n * MODLIMB_INVERSE_3 >> (GMP_NUMB_BITS - 2)))
+ {
+ case 0:
+ umul_ppmm (ph, pl, ap[n - 2], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[n - 3]);
+ umul_ppmm (rh, rl, ap[n - 1], B2modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ n -= 3;
+ break;
+ case 2: /* n mod 3 = 1 */
+ rh = 0;
+ rl = ap[n - 1];
+ n -= 1;
+ break;
+ case 1: /* n mod 3 = 2 */
+ rh = ap[n - 1];
+ rl = ap[n - 2];
+ n -= 2;
+ break;
+ }
+
+ for (i = n - 3; i >= 0; i -= 3)
+ {
+ /* rr = ap[i] < B
+ + ap[i+1] * (B mod b) <= (B-1)(b-1)
+ + ap[i+2] * (B^2 mod b) <= (B-1)(b-1)
+ + LO(rr) * (B^3 mod b) <= (B-1)(b-1)
+ + HI(rr) * (B^4 mod b) <= (B-1)(b-1)
+ */
+ umul_ppmm (ph, pl, ap[i + 1], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[i + 0]);
+
+ umul_ppmm (ch, cl, ap[i + 2], B2modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm (ch, cl, rl, B3modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm (rh, rl, rh, B4modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ }
+
+ umul_ppmm (rh, cl, rh, B1modb);
+ add_ssaaaa (rh, rl, rh, rl, CNST_LIMB(0), cl);
+
+ cnt = cps[1];
+ bi = cps[0];
+
+ r = (rh << cnt) | (rl >> (GMP_LIMB_BITS - cnt));
+ udiv_rnnd_preinv (r, r, rl << cnt, b, bi);
+
+ return r >> cnt;
+}
diff --git a/gmp/mpn/generic/mod_1_4.c b/gmp/mpn/generic/mod_1_4.c
new file mode 100644
index 0000000000..716a0c66de
--- /dev/null
+++ b/gmp/mpn/generic/mod_1_4.c
@@ -0,0 +1,171 @@
+/* mpn_mod_1s_4p (ap, n, b, cps)
+ Divide (ap,,n) by b. Return the single-limb remainder.
+ Requires that d < B / 4.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+ Based on a suggestion by Peter L. Montgomery.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2008-2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpn_mod_1s_4p_cps (mp_limb_t cps[7], mp_limb_t b)
+{
+ mp_limb_t bi;
+ mp_limb_t B1modb, B2modb, B3modb, B4modb, B5modb;
+ int cnt;
+
+ ASSERT (b <= (~(mp_limb_t) 0) / 4);
+
+ count_leading_zeros (cnt, b);
+
+ b <<= cnt;
+ invert_limb (bi, b);
+
+ cps[0] = bi;
+ cps[1] = cnt;
+
+ B1modb = -b * ((bi >> (GMP_LIMB_BITS-cnt)) | (CNST_LIMB(1) << cnt));
+ ASSERT (B1modb <= b); /* NB: not fully reduced mod b */
+ cps[2] = B1modb >> cnt;
+
+ udiv_rnnd_preinv (B2modb, B1modb, CNST_LIMB(0), b, bi);
+ cps[3] = B2modb >> cnt;
+
+ udiv_rnnd_preinv (B3modb, B2modb, CNST_LIMB(0), b, bi);
+ cps[4] = B3modb >> cnt;
+
+ udiv_rnnd_preinv (B4modb, B3modb, CNST_LIMB(0), b, bi);
+ cps[5] = B4modb >> cnt;
+
+ udiv_rnnd_preinv (B5modb, B4modb, CNST_LIMB(0), b, bi);
+ cps[6] = B5modb >> cnt;
+
+#if WANT_ASSERT
+ {
+ int i;
+ b = cps[2];
+ for (i = 3; i <= 6; i++)
+ {
+ b += cps[i];
+ ASSERT (b >= cps[i]);
+ }
+ }
+#endif
+}
+
+mp_limb_t
+mpn_mod_1s_4p (mp_srcptr ap, mp_size_t n, mp_limb_t b, const mp_limb_t cps[7])
+{
+ mp_limb_t rh, rl, bi, ph, pl, ch, cl, r;
+ mp_limb_t B1modb, B2modb, B3modb, B4modb, B5modb;
+ mp_size_t i;
+ int cnt;
+
+ ASSERT (n >= 1);
+
+ B1modb = cps[2];
+ B2modb = cps[3];
+ B3modb = cps[4];
+ B4modb = cps[5];
+ B5modb = cps[6];
+
+ switch (n & 3)
+ {
+ case 0:
+ umul_ppmm (ph, pl, ap[n - 3], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[n - 4]);
+ umul_ppmm (ch, cl, ap[n - 2], B2modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+ umul_ppmm (rh, rl, ap[n - 1], B3modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ n -= 4;
+ break;
+ case 1:
+ rh = 0;
+ rl = ap[n - 1];
+ n -= 1;
+ break;
+ case 2:
+ rh = ap[n - 1];
+ rl = ap[n - 2];
+ n -= 2;
+ break;
+ case 3:
+ umul_ppmm (ph, pl, ap[n - 2], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[n - 3]);
+ umul_ppmm (rh, rl, ap[n - 1], B2modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ n -= 3;
+ break;
+ }
+
+ for (i = n - 4; i >= 0; i -= 4)
+ {
+ /* rr = ap[i] < B
+ + ap[i+1] * (B mod b) <= (B-1)(b-1)
+ + ap[i+2] * (B^2 mod b) <= (B-1)(b-1)
+ + ap[i+3] * (B^3 mod b) <= (B-1)(b-1)
+ + LO(rr) * (B^4 mod b) <= (B-1)(b-1)
+ + HI(rr) * (B^5 mod b) <= (B-1)(b-1)
+ */
+ umul_ppmm (ph, pl, ap[i + 1], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[i + 0]);
+
+ umul_ppmm (ch, cl, ap[i + 2], B2modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm (ch, cl, ap[i + 3], B3modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm (ch, cl, rl, B4modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm (rh, rl, rh, B5modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ }
+
+ umul_ppmm (rh, cl, rh, B1modb);
+ add_ssaaaa (rh, rl, rh, rl, CNST_LIMB(0), cl);
+
+ cnt = cps[1];
+ bi = cps[0];
+
+ r = (rh << cnt) | (rl >> (GMP_LIMB_BITS - cnt));
+ udiv_rnnd_preinv (r, r, rl << cnt, b, bi);
+
+ return r >> cnt;
+}
diff --git a/gmp/mpn/generic/mod_34lsub1.c b/gmp/mpn/generic/mod_34lsub1.c
new file mode 100644
index 0000000000..7c07af7acc
--- /dev/null
+++ b/gmp/mpn/generic/mod_34lsub1.c
@@ -0,0 +1,131 @@
+/* mpn_mod_34lsub1 -- remainder modulo 2^(GMP_NUMB_BITS*3/4)-1.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Calculate a remainder from {p,n} divided by 2^(GMP_NUMB_BITS*3/4)-1.
+ The remainder is not fully reduced, it's any limb value congruent to
+ {p,n} modulo that divisor.
+
+ This implementation is only correct when GMP_NUMB_BITS is a multiple of
+ 4.
+
+ FIXME: If GMP_NAIL_BITS is some silly big value during development then
+ it's possible the carry accumulators c0,c1,c2 could overflow.
+
+ General notes:
+
+ The basic idea is to use a set of N accumulators (N=3 in this case) to
+ effectively get a remainder mod 2^(GMP_NUMB_BITS*N)-1 followed at the end
+ by a reduction to GMP_NUMB_BITS*N/M bits (M=4 in this case) for a
+ remainder mod 2^(GMP_NUMB_BITS*N/M)-1. N and M are chosen to give a good
+ set of small prime factors in 2^(GMP_NUMB_BITS*N/M)-1.
+
+ N=3 M=4 suits GMP_NUMB_BITS==32 and GMP_NUMB_BITS==64 quite well, giving
+ a few more primes than a single accumulator N=1 does, and for no extra
+ cost (assuming the processor has a decent number of registers).
+
+ For strange nailified values of GMP_NUMB_BITS the idea would be to look
+ for what N and M give good primes. With GMP_NUMB_BITS not a power of 2
+ the choices for M may be opened up a bit. But such things are probably
+ best done in separate code, not grafted on here. */
+
+#if GMP_NUMB_BITS % 4 == 0
+
+#define B1 (GMP_NUMB_BITS / 4)
+#define B2 (B1 * 2)
+#define B3 (B1 * 3)
+
+#define M1 ((CNST_LIMB(1) << B1) - 1)
+#define M2 ((CNST_LIMB(1) << B2) - 1)
+#define M3 ((CNST_LIMB(1) << B3) - 1)
+
+#define LOW0(n) ((n) & M3)
+#define HIGH0(n) ((n) >> B3)
+
+#define LOW1(n) (((n) & M2) << B1)
+#define HIGH1(n) ((n) >> B2)
+
+#define LOW2(n) (((n) & M1) << B2)
+#define HIGH2(n) ((n) >> B1)
+
+#define PARTS0(n) (LOW0(n) + HIGH0(n))
+#define PARTS1(n) (LOW1(n) + HIGH1(n))
+#define PARTS2(n) (LOW2(n) + HIGH2(n))
+
+#define ADD(c,a,val) \
+ do { \
+ mp_limb_t new_c; \
+ ADDC_LIMB (new_c, a, a, val); \
+ (c) += new_c; \
+ } while (0)
+
+mp_limb_t
+mpn_mod_34lsub1 (mp_srcptr p, mp_size_t n)
+{
+ mp_limb_t c0 = 0;
+ mp_limb_t c1 = 0;
+ mp_limb_t c2 = 0;
+ mp_limb_t a0, a1, a2;
+
+ ASSERT (n >= 1);
+ ASSERT (n/3 < GMP_NUMB_MAX);
+
+ a0 = a1 = a2 = 0;
+ c0 = c1 = c2 = 0;
+
+ while ((n -= 3) >= 0)
+ {
+ ADD (c0, a0, p[0]);
+ ADD (c1, a1, p[1]);
+ ADD (c2, a2, p[2]);
+ p += 3;
+ }
+
+ if (n != -3)
+ {
+ ADD (c0, a0, p[0]);
+ if (n != -2)
+ ADD (c1, a1, p[1]);
+ }
+
+ return
+ PARTS0 (a0) + PARTS1 (a1) + PARTS2 (a2)
+ + PARTS1 (c0) + PARTS2 (c1) + PARTS0 (c2);
+}
+
+#endif
diff --git a/gmp/mpn/generic/mode1o.c b/gmp/mpn/generic/mode1o.c
new file mode 100644
index 0000000000..ec91da223d
--- /dev/null
+++ b/gmp/mpn/generic/mode1o.c
@@ -0,0 +1,236 @@
+/* mpn_modexact_1c_odd -- mpn by limb exact division style remainder.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2000-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Calculate an r satisfying
+
+ r*B^k + a - c == q*d
+
+ where B=2^GMP_LIMB_BITS, a is {src,size}, k is either size or size-1
+ (the caller won't know which), and q is the quotient (discarded). d must
+ be odd, c can be any limb value.
+
+ If c<d then r will be in the range 0<=r<d, or if c>=d then 0<=r<=d.
+
+ This slightly strange function suits the initial Nx1 reduction for GCDs
+ or Jacobi symbols since the factors of 2 in B^k can be ignored, leaving
+ -r == a mod d (by passing c=0). For a GCD the factor of -1 on r can be
+ ignored, or for the Jacobi symbol it can be accounted for. The function
+ also suits divisibility and congruence testing since if r=0 (or r=d) is
+ obtained then a==c mod d.
+
+
+ r is a bit like the remainder returned by mpn_divexact_by3c, and is the
+ sort of remainder mpn_divexact_1 might return. Like mpn_divexact_by3c, r
+ represents a borrow, since effectively quotient limbs are chosen so that
+ subtracting that multiple of d from src at each step will produce a zero
+ limb.
+
+ A long calculation can be done piece by piece from low to high by passing
+ the return value from one part as the carry parameter to the next part.
+ The effective final k becomes anything between size and size-n, if n
+ pieces are used.
+
+
+ A similar sort of routine could be constructed based on adding multiples
+ of d at each limb, much like redc in mpz_powm does. Subtracting however
+ has a small advantage that when subtracting to cancel out l there's never
+ a borrow into h, whereas using an addition would put a carry into h
+ depending whether l==0 or l!=0.
+
+
+ In terms of efficiency, this function is similar to a mul-by-inverse
+ mpn_mod_1. Both are essentially two multiplies and are best suited to
+ CPUs with low latency multipliers (in comparison to a divide instruction
+ at least.) But modexact has a few less supplementary operations, only
+ needs low part and high part multiplies, and has fewer working quantities
+ (helping CPUs with few registers).
+
+
+ In the main loop it will be noted that the new carry (call it r) is the
+ sum of the high product h and any borrow from l=s-c. If c<d then we will
+ have r<d too, for the following reasons. Let q=l*inverse be the quotient
+ limb, so that q*d = B*h + l, where B=2^GMP_NUMB_BITS. Now if h=d-1 then
+
+ l = q*d - B*(d-1) <= (B-1)*d - B*(d-1) = B-d
+
+ But if l=s-c produces a borrow when c<d, then l>=B-d+1 and hence will
+ never have h=d-1 and so r=h+borrow <= d-1.
+
+ When c>=d, on the other hand, h=d-1 can certainly occur together with a
+ borrow, thereby giving only r<=d, as per the function definition above.
+
+ As a design decision it's left to the caller to check for r=d if it might
+ be passing c>=d. Several applications have c<d initially so the extra
+ test is often unnecessary, for example the GCDs or a plain divisibility
+ d|a test will pass c=0.
+
+
+ The special case for size==1 is so that it can be assumed c<=d in the
+ high<=divisor test at the end. c<=d is only guaranteed after at least
+ one iteration of the main loop. There's also a decent chance one % is
+ faster than a binvert_limb, though that will depend on the processor.
+
+ A CPU specific implementation might want to omit the size==1 code or the
+ high<divisor test. mpn/x86/k6/mode1o.asm for instance finds neither
+ useful. */
+
+
+mp_limb_t
+mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size, mp_limb_t d,
+ mp_limb_t orig_c)
+{
+ mp_limb_t s, h, l, inverse, dummy, dmul, ret;
+ mp_limb_t c = orig_c;
+ mp_size_t i;
+
+ ASSERT (size >= 1);
+ ASSERT (d & 1);
+ ASSERT_MPN (src, size);
+ ASSERT_LIMB (d);
+ ASSERT_LIMB (c);
+
+ if (size == 1)
+ {
+ s = src[0];
+ if (s > c)
+ {
+ l = s-c;
+ h = l % d;
+ if (h != 0)
+ h = d - h;
+ }
+ else
+ {
+ l = c-s;
+ h = l % d;
+ }
+ return h;
+ }
+
+
+ binvert_limb (inverse, d);
+ dmul = d << GMP_NAIL_BITS;
+
+ i = 0;
+ do
+ {
+ s = src[i];
+ SUBC_LIMB (c, l, s, c);
+ l = (l * inverse) & GMP_NUMB_MASK;
+ umul_ppmm (h, dummy, l, dmul);
+ c += h;
+ }
+ while (++i < size-1);
+
+
+ s = src[i];
+ if (s <= d)
+ {
+ /* With high<=d the final step can be a subtract and addback. If c==0
+ then the addback will restore to l>=0. If c==d then will get l==d
+ if s==0, but that's ok per the function definition. */
+
+ l = c - s;
+ if (c < s)
+ l += d;
+
+ ret = l;
+ }
+ else
+ {
+ /* Can't skip a divide, just do the loop code once more. */
+
+ SUBC_LIMB (c, l, s, c);
+ l = (l * inverse) & GMP_NUMB_MASK;
+ umul_ppmm (h, dummy, l, dmul);
+ c += h;
+ ret = c;
+ }
+
+ ASSERT (orig_c < d ? ret < d : ret <= d);
+ return ret;
+}
+
+
+
+#if 0
+
+/* The following is an alternate form that might shave one cycle on a
+ superscalar processor since it takes c+=h off the dependent chain,
+ leaving just a low product, high product, and a subtract.
+
+ This is for CPU specific implementations to consider. A special case for
+ high<divisor and/or size==1 can be added if desired.
+
+ Notice that c is only ever 0 or 1, since if s-c produces a borrow then
+ x=0xFF..FF and x-h cannot produce a borrow. The c=(x>s) could become
+ c=(x==0xFF..FF) too, if that helped. */
+
+mp_limb_t
+mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size, mp_limb_t d, mp_limb_t h)
+{
+ mp_limb_t s, x, y, inverse, dummy, dmul, c1, c2;
+ mp_limb_t c = 0;
+ mp_size_t i;
+
+ ASSERT (size >= 1);
+ ASSERT (d & 1);
+
+ binvert_limb (inverse, d);
+ dmul = d << GMP_NAIL_BITS;
+
+ for (i = 0; i < size; i++)
+ {
+ ASSERT (c==0 || c==1);
+
+ s = src[i];
+ SUBC_LIMB (c1, x, s, c);
+
+ SUBC_LIMB (c2, y, x, h);
+ c = c1 + c2;
+
+ y = (y * inverse) & GMP_NUMB_MASK;
+ umul_ppmm (h, dummy, y, dmul);
+ }
+
+ h += c;
+ return h;
+}
+
+#endif
diff --git a/gmp/mpn/generic/mu_bdiv_q.c b/gmp/mpn/generic/mu_bdiv_q.c
new file mode 100644
index 0000000000..0a8010ec15
--- /dev/null
+++ b/gmp/mpn/generic/mu_bdiv_q.c
@@ -0,0 +1,271 @@
+/* mpn_mu_bdiv_q(qp,np,nn,dp,dn,tp) -- Compute {np,nn} / {dp,dn} mod B^nn.
+ storing the result in {qp,nn}. Overlap allowed between Q and N; all other
+ overlap disallowed.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2005-2007, 2009, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/*
+ The idea of the algorithm used herein is to compute a smaller inverted value
+ than used in the standard Barrett algorithm, and thus save time in the
+ Newton iterations, and pay just a small price when using the inverted value
+ for developing quotient bits. This algorithm was presented at ICMS 2006.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* N = {np,nn}
+ D = {dp,dn}
+
+ Requirements: N >= D
+ D >= 1
+ D odd
+ dn >= 2
+ nn >= 2
+ scratch space as determined by mpn_mu_bdiv_q_itch(nn,dn).
+
+ Write quotient to Q = {qp,nn}.
+
+ FIXME: When iterating, perhaps do the small step before loop, not after.
+ FIXME: Try to avoid the scalar divisions when computing inverse size.
+ FIXME: Trim allocation for (qn > dn) case, 3*dn might be possible. In
+ particular, when dn==in, tp and rp could use the same space.
+ FIXME: Trim final quotient calculation to qn limbs of precision.
+*/
+void
+mpn_mu_bdiv_q (mp_ptr qp,
+ mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_ptr scratch)
+{
+ mp_size_t qn;
+ mp_size_t in;
+ int cy, c0;
+ mp_size_t tn, wn;
+
+ qn = nn;
+
+ ASSERT (dn >= 2);
+ ASSERT (qn >= 2);
+
+ if (qn > dn)
+ {
+ mp_size_t b;
+
+ /* |_______________________| dividend
+ |________| divisor */
+
+#define ip scratch /* in */
+#define rp (scratch + in) /* dn or rest >= binvert_itch(in) */
+#define tp (scratch + in + dn) /* dn+in or next_size(dn) */
+#define scratch_out (scratch + in + dn + tn) /* mulmod_bnm1_itch(next_size(dn)) */
+
+ /* Compute an inverse size that is a nice partition of the quotient. */
+ b = (qn - 1) / dn + 1; /* ceil(qn/dn), number of blocks */
+ in = (qn - 1) / b + 1; /* ceil(qn/b) = ceil(qn / ceil(qn/dn)) */
+
+ /* Some notes on allocation:
+
+ When in = dn, R dies when mpn_mullo returns, if in < dn the low in
+ limbs of R dies at that point. We could save memory by letting T live
+ just under R, and let the upper part of T expand into R. These changes
+ should reduce itch to perhaps 3dn.
+ */
+
+ mpn_binvert (ip, dp, in, rp);
+
+ cy = 0;
+
+ MPN_COPY (rp, np, dn);
+ np += dn;
+ mpn_mullo_n (qp, rp, ip, in);
+ qn -= in;
+
+ while (qn > in)
+ {
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ mpn_mul (tp, dp, dn, qp, in); /* mulhi, need tp[dn+in-1...in] */
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn);
+ mpn_mulmod_bnm1 (tp, tn, dp, dn, qp, in, scratch_out);
+ wn = dn + in - tn; /* number of wrapped limbs */
+ if (wn > 0)
+ {
+ c0 = mpn_sub_n (tp + tn, tp, rp, wn);
+ mpn_decr_u (tp + wn, c0);
+ }
+ }
+
+ qp += in;
+ if (dn != in)
+ {
+ /* Subtract tp[dn-1...in] from partial remainder. */
+ cy += mpn_sub_n (rp, rp + in, tp + in, dn - in);
+ if (cy == 2)
+ {
+ mpn_incr_u (tp + dn, 1);
+ cy = 1;
+ }
+ }
+ /* Subtract tp[dn+in-1...dn] from dividend. */
+ cy = mpn_sub_nc (rp + dn - in, np, tp + dn, in, cy);
+ np += in;
+ mpn_mullo_n (qp, rp, ip, in);
+ qn -= in;
+ }
+
+ /* Generate last qn limbs.
+ FIXME: It should be possible to limit precision here, since qn is
+ typically somewhat smaller than dn. No big gains expected. */
+
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ mpn_mul (tp, dp, dn, qp, in); /* mulhi, need tp[qn+in-1...in] */
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn);
+ mpn_mulmod_bnm1 (tp, tn, dp, dn, qp, in, scratch_out);
+ wn = dn + in - tn; /* number of wrapped limbs */
+ if (wn > 0)
+ {
+ c0 = mpn_sub_n (tp + tn, tp, rp, wn);
+ mpn_decr_u (tp + wn, c0);
+ }
+ }
+
+ qp += in;
+ if (dn != in)
+ {
+ cy += mpn_sub_n (rp, rp + in, tp + in, dn - in);
+ if (cy == 2)
+ {
+ mpn_incr_u (tp + dn, 1);
+ cy = 1;
+ }
+ }
+
+ mpn_sub_nc (rp + dn - in, np, tp + dn, qn - (dn - in), cy);
+ mpn_mullo_n (qp, rp, ip, qn);
+
+#undef ip
+#undef rp
+#undef tp
+#undef scratch_out
+ }
+ else
+ {
+ /* |_______________________| dividend
+ |________________| divisor */
+
+#define ip scratch /* in */
+#define tp (scratch + in) /* qn+in or next_size(qn) or rest >= binvert_itch(in) */
+#define scratch_out (scratch + in + tn)/* mulmod_bnm1_itch(next_size(qn)) */
+
+ /* Compute half-sized inverse. */
+ in = qn - (qn >> 1);
+
+ mpn_binvert (ip, dp, in, tp);
+
+ mpn_mullo_n (qp, np, ip, in); /* low `in' quotient limbs */
+
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ mpn_mul (tp, dp, qn, qp, in); /* mulhigh */
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (qn);
+ mpn_mulmod_bnm1 (tp, tn, dp, qn, qp, in, scratch_out);
+ wn = qn + in - tn; /* number of wrapped limbs */
+ if (wn > 0)
+ {
+ c0 = mpn_cmp (tp, np, wn) < 0;
+ mpn_decr_u (tp + wn, c0);
+ }
+ }
+
+ mpn_sub_n (tp, np + in, tp + in, qn - in);
+ mpn_mullo_n (qp + in, tp, ip, qn - in); /* high qn-in quotient limbs */
+
+#undef ip
+#undef tp
+#undef scratch_out
+ }
+}
+
+mp_size_t
+mpn_mu_bdiv_q_itch (mp_size_t nn, mp_size_t dn)
+{
+ mp_size_t qn, in, tn, itch_binvert, itch_out, itches;
+ mp_size_t b;
+
+ qn = nn;
+
+ if (qn > dn)
+ {
+ b = (qn - 1) / dn + 1; /* ceil(qn/dn), number of blocks */
+ in = (qn - 1) / b + 1; /* ceil(qn/b) = ceil(qn / ceil(qn/dn)) */
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ {
+ tn = dn + in;
+ itch_out = 0;
+ }
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn);
+ itch_out = mpn_mulmod_bnm1_itch (tn, dn, in);
+ }
+ itch_binvert = mpn_binvert_itch (in);
+ itches = dn + tn + itch_out;
+ return in + MAX (itches, itch_binvert);
+ }
+ else
+ {
+ in = qn - (qn >> 1);
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ {
+ tn = qn + in;
+ itch_out = 0;
+ }
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (qn);
+ itch_out = mpn_mulmod_bnm1_itch (tn, qn, in);
+ }
+ itch_binvert = mpn_binvert_itch (in);
+ itches = tn + itch_out;
+ return in + MAX (itches, itch_binvert);
+ }
+}
diff --git a/gmp/mpn/generic/mu_bdiv_qr.c b/gmp/mpn/generic/mu_bdiv_qr.c
new file mode 100644
index 0000000000..d265440f2b
--- /dev/null
+++ b/gmp/mpn/generic/mu_bdiv_qr.c
@@ -0,0 +1,289 @@
+/* mpn_mu_bdiv_qr(qp,rp,np,nn,dp,dn,tp) -- Compute {np,nn} / {dp,dn} mod B^qn,
+ where qn = nn-dn, storing the result in {qp,qn}. Overlap allowed between Q
+ and N; all other overlap disallowed.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2005-2007, 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/*
+ The idea of the algorithm used herein is to compute a smaller inverted value
+ than used in the standard Barrett algorithm, and thus save time in the
+ Newton iterations, and pay just a small price when using the inverted value
+ for developing quotient bits. This algorithm was presented at ICMS 2006.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* N = {np,nn}
+ D = {dp,dn}
+
+ Requirements: N >= D
+ D >= 1
+ D odd
+ dn >= 2
+ nn >= 2
+ scratch space as determined by mpn_mu_bdiv_qr_itch(nn,dn).
+
+ Write quotient to Q = {qp,nn-dn}.
+
+ FIXME: When iterating, perhaps do the small step before loop, not after.
+ FIXME: Try to avoid the scalar divisions when computing inverse size.
+ FIXME: Trim allocation for (qn > dn) case, 3*dn might be possible. In
+ particular, when dn==in, tp and rp could use the same space.
+*/
+mp_limb_t
+mpn_mu_bdiv_qr (mp_ptr qp,
+ mp_ptr rp,
+ mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_ptr scratch)
+{
+ mp_size_t qn;
+ mp_size_t in;
+ mp_limb_t cy, c0;
+ mp_size_t tn, wn;
+
+ qn = nn - dn;
+
+ ASSERT (dn >= 2);
+ ASSERT (qn >= 2);
+
+ if (qn > dn)
+ {
+ mp_size_t b;
+
+ /* |_______________________| dividend
+ |________| divisor */
+
+#define ip scratch /* in */
+#define tp (scratch + in) /* dn+in or next_size(dn) or rest >= binvert_itch(in) */
+#define scratch_out (scratch + in + tn)/* mulmod_bnm1_itch(next_size(dn)) */
+
+ /* Compute an inverse size that is a nice partition of the quotient. */
+ b = (qn - 1) / dn + 1; /* ceil(qn/dn), number of blocks */
+ in = (qn - 1) / b + 1; /* ceil(qn/b) = ceil(qn / ceil(qn/dn)) */
+
+ /* Some notes on allocation:
+
+ When in = dn, R dies when mpn_mullo returns, if in < dn the low in
+ limbs of R dies at that point. We could save memory by letting T live
+ just under R, and let the upper part of T expand into R. These changes
+ should reduce itch to perhaps 3dn.
+ */
+
+ mpn_binvert (ip, dp, in, tp);
+
+ MPN_COPY (rp, np, dn);
+ np += dn;
+ cy = 0;
+
+ while (qn > in)
+ {
+ mpn_mullo_n (qp, rp, ip, in);
+
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ mpn_mul (tp, dp, dn, qp, in); /* mulhi, need tp[dn+in-1...in] */
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn);
+ mpn_mulmod_bnm1 (tp, tn, dp, dn, qp, in, scratch_out);
+ wn = dn + in - tn; /* number of wrapped limbs */
+ if (wn > 0)
+ {
+ c0 = mpn_sub_n (tp + tn, tp, rp, wn);
+ mpn_decr_u (tp + wn, c0);
+ }
+ }
+
+ qp += in;
+ qn -= in;
+
+ if (dn != in)
+ {
+ /* Subtract tp[dn-1...in] from partial remainder. */
+ cy += mpn_sub_n (rp, rp + in, tp + in, dn - in);
+ if (cy == 2)
+ {
+ mpn_incr_u (tp + dn, 1);
+ cy = 1;
+ }
+ }
+ /* Subtract tp[dn+in-1...dn] from dividend. */
+ cy = mpn_sub_nc (rp + dn - in, np, tp + dn, in, cy);
+ np += in;
+ }
+
+ /* Generate last qn limbs. */
+ mpn_mullo_n (qp, rp, ip, qn);
+
+ if (BELOW_THRESHOLD (qn, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ mpn_mul (tp, dp, dn, qp, qn); /* mulhi, need tp[qn+in-1...in] */
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn);
+ mpn_mulmod_bnm1 (tp, tn, dp, dn, qp, qn, scratch_out);
+ wn = dn + qn - tn; /* number of wrapped limbs */
+ if (wn > 0)
+ {
+ c0 = mpn_sub_n (tp + tn, tp, rp, wn);
+ mpn_decr_u (tp + wn, c0);
+ }
+ }
+
+ if (dn != qn)
+ {
+ cy += mpn_sub_n (rp, rp + qn, tp + qn, dn - qn);
+ if (cy == 2)
+ {
+ mpn_incr_u (tp + dn, 1);
+ cy = 1;
+ }
+ }
+ return mpn_sub_nc (rp + dn - qn, np, tp + dn, qn, cy);
+
+#undef ip
+#undef tp
+#undef scratch_out
+ }
+ else
+ {
+ /* |_______________________| dividend
+ |________________| divisor */
+
+#define ip scratch /* in */
+#define tp (scratch + in) /* dn+in or next_size(dn) or rest >= binvert_itch(in) */
+#define scratch_out (scratch + in + tn)/* mulmod_bnm1_itch(next_size(dn)) */
+
+ /* Compute half-sized inverse. */
+ in = qn - (qn >> 1);
+
+ mpn_binvert (ip, dp, in, tp);
+
+ mpn_mullo_n (qp, np, ip, in); /* low `in' quotient limbs */
+
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ mpn_mul (tp, dp, dn, qp, in); /* mulhigh */
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn);
+ mpn_mulmod_bnm1 (tp, tn, dp, dn, qp, in, scratch_out);
+ wn = dn + in - tn; /* number of wrapped limbs */
+ if (wn > 0)
+ {
+ c0 = mpn_sub_n (tp + tn, tp, np, wn);
+ mpn_decr_u (tp + wn, c0);
+ }
+ }
+
+ qp += in;
+ qn -= in;
+
+ cy = mpn_sub_n (rp, np + in, tp + in, dn);
+ mpn_mullo_n (qp, rp, ip, qn); /* high qn quotient limbs */
+
+ if (BELOW_THRESHOLD (qn, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ mpn_mul (tp, dp, dn, qp, qn); /* mulhigh */
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn);
+ mpn_mulmod_bnm1 (tp, tn, dp, dn, qp, qn, scratch_out);
+ wn = dn + qn - tn; /* number of wrapped limbs */
+ if (wn > 0)
+ {
+ c0 = mpn_sub_n (tp + tn, tp, rp, wn);
+ mpn_decr_u (tp + wn, c0);
+ }
+ }
+
+ cy += mpn_sub_n (rp, rp + qn, tp + qn, dn - qn);
+ if (cy == 2)
+ {
+ mpn_incr_u (tp + dn, 1);
+ cy = 1;
+ }
+ return mpn_sub_nc (rp + dn - qn, np + dn + in, tp + dn, qn, cy);
+
+#undef ip
+#undef tp
+#undef scratch_out
+ }
+}
+
+mp_size_t
+mpn_mu_bdiv_qr_itch (mp_size_t nn, mp_size_t dn)
+{
+ mp_size_t qn, in, tn, itch_binvert, itch_out, itches;
+ mp_size_t b;
+
+ qn = nn - dn;
+
+ if (qn > dn)
+ {
+ b = (qn - 1) / dn + 1; /* ceil(qn/dn), number of blocks */
+ in = (qn - 1) / b + 1; /* ceil(qn/b) = ceil(qn / ceil(qn/dn)) */
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ {
+ tn = dn + in;
+ itch_out = 0;
+ }
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn);
+ itch_out = mpn_mulmod_bnm1_itch (tn, dn, in);
+ }
+ itch_binvert = mpn_binvert_itch (in);
+ itches = tn + itch_out;
+ return in + MAX (itches, itch_binvert);
+ }
+ else
+ {
+ in = qn - (qn >> 1);
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ {
+ tn = dn + in;
+ itch_out = 0;
+ }
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn);
+ itch_out = mpn_mulmod_bnm1_itch (tn, dn, in);
+ }
+ }
+ itch_binvert = mpn_binvert_itch (in);
+ itches = tn + itch_out;
+ return in + MAX (itches, itch_binvert);
+}
diff --git a/gmp/mpn/generic/mu_div_q.c b/gmp/mpn/generic/mu_div_q.c
new file mode 100644
index 0000000000..8768ba6c60
--- /dev/null
+++ b/gmp/mpn/generic/mu_div_q.c
@@ -0,0 +1,185 @@
+/* mpn_mu_div_q.
+
+ Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2005-2007, 2009, 2010, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/*
+ The idea of the algorithm used herein is to compute a smaller inverted value
+ than used in the standard Barrett algorithm, and thus save time in the
+ Newton iterations, and pay just a small price when using the inverted value
+ for developing quotient bits. This algorithm was presented at ICMS 2006.
+*/
+
+/*
+ Things to work on:
+
+ 1. This is a rudimentary implementation of mpn_mu_div_q. The algorithm is
+ probably close to optimal, except when mpn_mu_divappr_q fails.
+
+ 2. We used to fall back to mpn_mu_div_qr when we detect a possible
+ mpn_mu_divappr_q rounding problem, now we multiply and compare.
+ Unfortunately, since mpn_mu_divappr_q does not return the partial
+ remainder, this also doesn't become optimal. A mpn_mu_divappr_qr could
+ solve that.
+
+ 3. The allocations done here should be made from the scratch area, which
+ then would need to be amended.
+*/
+
+#include <stdlib.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+mp_limb_t
+mpn_mu_div_q (mp_ptr qp,
+ mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_ptr scratch)
+{
+ mp_ptr tp, rp;
+ mp_size_t qn;
+ mp_limb_t cy, qh;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ qn = nn - dn;
+
+ tp = TMP_BALLOC_LIMBS (qn + 1);
+
+ if (qn >= dn) /* nn >= 2*dn + 1 */
+ {
+ /* |_______________________| dividend
+ |________| divisor */
+
+ rp = TMP_BALLOC_LIMBS (nn + 1);
+ MPN_COPY (rp + 1, np, nn);
+ rp[0] = 0;
+
+ qh = mpn_cmp (rp + 1 + nn - dn, dp, dn) >= 0;
+ if (qh != 0)
+ mpn_sub_n (rp + 1 + nn - dn, rp + 1 + nn - dn, dp, dn);
+
+ cy = mpn_mu_divappr_q (tp, rp, nn + 1, dp, dn, scratch);
+
+ if (UNLIKELY (cy != 0))
+ {
+ /* Since the partial remainder fed to mpn_preinv_mu_divappr_q was
+ canonically reduced, replace the returned value of B^(qn-dn)+eps
+ by the largest possible value. */
+ mp_size_t i;
+ for (i = 0; i < qn + 1; i++)
+ tp[i] = GMP_NUMB_MAX;
+ }
+
+ /* The max error of mpn_mu_divappr_q is +4. If the low quotient limb is
+ greater than the max error, we cannot trust the quotient. */
+ if (tp[0] > 4)
+ {
+ MPN_COPY (qp, tp + 1, qn);
+ }
+ else
+ {
+ mp_limb_t cy;
+ mp_ptr pp;
+
+ pp = rp;
+ mpn_mul (pp, tp + 1, qn, dp, dn);
+
+ cy = (qh != 0) ? mpn_add_n (pp + qn, pp + qn, dp, dn) : 0;
+
+ if (cy || mpn_cmp (pp, np, nn) > 0) /* At most is wrong by one, no cycle. */
+ qh -= mpn_sub_1 (qp, tp + 1, qn, 1);
+ else /* Same as above */
+ MPN_COPY (qp, tp + 1, qn);
+ }
+ }
+ else
+ {
+ /* |_______________________| dividend
+ |________________| divisor */
+
+ /* FIXME: When nn = 2dn-1, qn becomes dn-1, and the numerator size passed
+ here becomes 2dn, i.e., more than nn. This shouldn't hurt, since only
+ the most significant dn-1 limbs will actually be read, but it is not
+ pretty. */
+
+ qh = mpn_mu_divappr_q (tp, np + nn - (2 * qn + 2), 2 * qn + 2,
+ dp + dn - (qn + 1), qn + 1, scratch);
+
+ /* The max error of mpn_mu_divappr_q is +4, but we get an additional
+ error from the divisor truncation. */
+ if (tp[0] > 6)
+ {
+ MPN_COPY (qp, tp + 1, qn);
+ }
+ else
+ {
+ mp_limb_t cy;
+
+ /* FIXME: a shorter product should be enough; we may use already
+ allocated space... */
+ rp = TMP_BALLOC_LIMBS (nn);
+ mpn_mul (rp, dp, dn, tp + 1, qn);
+
+ cy = (qh != 0) ? mpn_add_n (rp + qn, rp + qn, dp, dn) : 0;
+
+ if (cy || mpn_cmp (rp, np, nn) > 0) /* At most is wrong by one, no cycle. */
+ qh -= mpn_sub_1 (qp, tp + 1, qn, 1);
+ else /* Same as above */
+ MPN_COPY (qp, tp + 1, qn);
+ }
+ }
+
+ TMP_FREE;
+ return qh;
+}
+
+mp_size_t
+mpn_mu_div_q_itch (mp_size_t nn, mp_size_t dn, int mua_k)
+{
+ mp_size_t qn;
+
+ qn = nn - dn;
+ if (qn >= dn)
+ {
+ return mpn_mu_divappr_q_itch (nn + 1, dn, mua_k);
+ }
+ else
+ {
+ return mpn_mu_divappr_q_itch (2 * qn + 2, qn + 1, mua_k);
+ }
+}
diff --git a/gmp/mpn/generic/mu_div_qr.c b/gmp/mpn/generic/mu_div_qr.c
new file mode 100644
index 0000000000..f4700a1ea6
--- /dev/null
+++ b/gmp/mpn/generic/mu_div_qr.c
@@ -0,0 +1,416 @@
+/* mpn_mu_div_qr, mpn_preinv_mu_div_qr.
+
+ Compute Q = floor(N / D) and R = N-QD. N is nn limbs and D is dn limbs and
+ must be normalized, and Q must be nn-dn limbs. The requirement that Q is
+ nn-dn limbs (and not nn-dn+1 limbs) was put in place in order to allow us to
+ let N be unmodified during the operation.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2005-2007, 2009, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/*
+ The idea of the algorithm used herein is to compute a smaller inverted value
+ than used in the standard Barrett algorithm, and thus save time in the
+ Newton iterations, and pay just a small price when using the inverted value
+ for developing quotient bits. This algorithm was presented at ICMS 2006.
+*/
+
+/* CAUTION: This code and the code in mu_divappr_q.c should be edited in sync.
+
+ Things to work on:
+
+ * This isn't optimal when the quotient isn't needed, as it might take a lot
+ of space. The computation is always needed, though, so there is no time to
+ save with special code.
+
+ * The itch/scratch scheme isn't perhaps such a good idea as it once seemed,
+ demonstrated by the fact that the mpn_invertappr function's scratch needs
+ mean that we need to keep a large allocation long after it is needed.
+ Things are worse as mpn_mul_fft does not accept any scratch parameter,
+ which means we'll have a large memory hole while in mpn_mul_fft. In
+ general, a peak scratch need in the beginning of a function isn't
+ well-handled by the itch/scratch scheme.
+*/
+
+#ifdef STAT
+#undef STAT
+#define STAT(x) x
+#else
+#define STAT(x)
+#endif
+
+#include <stdlib.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* FIXME: The MU_DIV_QR_SKEW_THRESHOLD was not analysed properly. It gives a
+ speedup according to old measurements, but does the decision mechanism
+ really make sense? It seem like the quotient between dn and qn might be
+ what we really should be checking. */
+#ifndef MU_DIV_QR_SKEW_THRESHOLD
+#define MU_DIV_QR_SKEW_THRESHOLD 100
+#endif
+
+#ifdef CHECK /* FIXME: Enable in minithres */
+#undef MU_DIV_QR_SKEW_THRESHOLD
+#define MU_DIV_QR_SKEW_THRESHOLD 1
+#endif
+
+
+static mp_limb_t mpn_mu_div_qr2 (mp_ptr, mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t, mp_ptr);
+
+
+mp_limb_t
+mpn_mu_div_qr (mp_ptr qp,
+ mp_ptr rp,
+ mp_srcptr np,
+ mp_size_t nn,
+ mp_srcptr dp,
+ mp_size_t dn,
+ mp_ptr scratch)
+{
+ mp_size_t qn;
+ mp_limb_t cy, qh;
+
+ qn = nn - dn;
+ if (qn + MU_DIV_QR_SKEW_THRESHOLD < dn)
+ {
+ /* |______________|_ign_first__| dividend nn
+ |_______|_ign_first__| divisor dn
+
+ |______| quotient (prel) qn
+
+ |___________________| quotient * ignored-divisor-part dn-1
+ */
+
+ /* Compute a preliminary quotient and a partial remainder by dividing the
+ most significant limbs of each operand. */
+ qh = mpn_mu_div_qr2 (qp, rp + nn - (2 * qn + 1),
+ np + nn - (2 * qn + 1), 2 * qn + 1,
+ dp + dn - (qn + 1), qn + 1,
+ scratch);
+
+ /* Multiply the quotient by the divisor limbs ignored above. */
+ if (dn - (qn + 1) > qn)
+ mpn_mul (scratch, dp, dn - (qn + 1), qp, qn); /* prod is dn-1 limbs */
+ else
+ mpn_mul (scratch, qp, qn, dp, dn - (qn + 1)); /* prod is dn-1 limbs */
+
+ if (qh)
+ cy = mpn_add_n (scratch + qn, scratch + qn, dp, dn - (qn + 1));
+ else
+ cy = 0;
+ scratch[dn - 1] = cy;
+
+ cy = mpn_sub_n (rp, np, scratch, nn - (2 * qn + 1));
+ cy = mpn_sub_nc (rp + nn - (2 * qn + 1),
+ rp + nn - (2 * qn + 1),
+ scratch + nn - (2 * qn + 1),
+ qn + 1, cy);
+ if (cy)
+ {
+ qh -= mpn_sub_1 (qp, qp, qn, 1);
+ mpn_add_n (rp, rp, dp, dn);
+ }
+ }
+ else
+ {
+ qh = mpn_mu_div_qr2 (qp, rp, np, nn, dp, dn, scratch);
+ }
+
+ return qh;
+}
+
+static mp_limb_t
+mpn_mu_div_qr2 (mp_ptr qp,
+ mp_ptr rp,
+ mp_srcptr np,
+ mp_size_t nn,
+ mp_srcptr dp,
+ mp_size_t dn,
+ mp_ptr scratch)
+{
+ mp_size_t qn, in;
+ mp_limb_t cy, qh;
+ mp_ptr ip, tp;
+
+ ASSERT (dn > 1);
+
+ qn = nn - dn;
+
+ /* Compute the inverse size. */
+ in = mpn_mu_div_qr_choose_in (qn, dn, 0);
+ ASSERT (in <= dn);
+
+#if 1
+ /* This alternative inverse computation method gets slightly more accurate
+ results. FIXMEs: (1) Temp allocation needs not analysed (2) itch function
+ not adapted (3) mpn_invertappr scratch needs not met. */
+ ip = scratch;
+ tp = scratch + in + 1;
+
+ /* compute an approximate inverse on (in+1) limbs */
+ if (dn == in)
+ {
+ MPN_COPY (tp + 1, dp, in);
+ tp[0] = 1;
+ mpn_invertappr (ip, tp, in + 1, NULL);
+ MPN_COPY_INCR (ip, ip + 1, in);
+ }
+ else
+ {
+ cy = mpn_add_1 (tp, dp + dn - (in + 1), in + 1, 1);
+ if (UNLIKELY (cy != 0))
+ MPN_ZERO (ip, in);
+ else
+ {
+ mpn_invertappr (ip, tp, in + 1, NULL);
+ MPN_COPY_INCR (ip, ip + 1, in);
+ }
+ }
+#else
+ /* This older inverse computation method gets slightly worse results than the
+ one above. */
+ ip = scratch;
+ tp = scratch + in;
+
+ /* Compute inverse of D to in+1 limbs, then round to 'in' limbs. Ideally the
+ inversion function should do this automatically. */
+ if (dn == in)
+ {
+ tp[in + 1] = 0;
+ MPN_COPY (tp + in + 2, dp, in);
+ mpn_invertappr (tp, tp + in + 1, in + 1, NULL);
+ }
+ else
+ {
+ mpn_invertappr (tp, dp + dn - (in + 1), in + 1, NULL);
+ }
+ cy = mpn_sub_1 (tp, tp, in + 1, GMP_NUMB_HIGHBIT);
+ if (UNLIKELY (cy != 0))
+ MPN_ZERO (tp + 1, in);
+ MPN_COPY (ip, tp + 1, in);
+#endif
+
+ qh = mpn_preinv_mu_div_qr (qp, rp, np, nn, dp, dn, ip, in, scratch + in);
+
+ return qh;
+}
+
+mp_limb_t
+mpn_preinv_mu_div_qr (mp_ptr qp,
+ mp_ptr rp,
+ mp_srcptr np,
+ mp_size_t nn,
+ mp_srcptr dp,
+ mp_size_t dn,
+ mp_srcptr ip,
+ mp_size_t in,
+ mp_ptr scratch)
+{
+ mp_size_t qn;
+ mp_limb_t cy, cx, qh;
+ mp_limb_t r;
+ mp_size_t tn, wn;
+
+#define tp scratch
+#define scratch_out (scratch + tn)
+
+ qn = nn - dn;
+
+ np += qn;
+ qp += qn;
+
+ qh = mpn_cmp (np, dp, dn) >= 0;
+ if (qh != 0)
+ mpn_sub_n (rp, np, dp, dn);
+ else
+ MPN_COPY_INCR (rp, np, dn);
+
+ if (qn == 0)
+ return qh; /* Degenerate use. Should we allow this? */
+
+ while (qn > 0)
+ {
+ if (qn < in)
+ {
+ ip += in - qn;
+ in = qn;
+ }
+ np -= in;
+ qp -= in;
+
+ /* Compute the next block of quotient limbs by multiplying the inverse I
+ by the upper part of the partial remainder R. */
+ mpn_mul_n (tp, rp + dn - in, ip, in); /* mulhi */
+ cy = mpn_add_n (qp, tp + in, rp + dn - in, in); /* I's msb implicit */
+ ASSERT_ALWAYS (cy == 0);
+
+ qn -= in;
+
+ /* Compute the product of the quotient block and the divisor D, to be
+ subtracted from the partial remainder combined with new limbs from the
+ dividend N. We only really need the low dn+1 limbs. */
+
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ mpn_mul (tp, dp, dn, qp, in); /* dn+in limbs, high 'in' cancels */
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn + 1);
+ mpn_mulmod_bnm1 (tp, tn, dp, dn, qp, in, scratch_out);
+ wn = dn + in - tn; /* number of wrapped limbs */
+ if (wn > 0)
+ {
+ cy = mpn_sub_n (tp, tp, rp + dn - wn, wn);
+ cy = mpn_sub_1 (tp + wn, tp + wn, tn - wn, cy);
+ cx = mpn_cmp (rp + dn - in, tp + dn, tn - dn) < 0;
+ ASSERT_ALWAYS (cx >= cy);
+ mpn_incr_u (tp, cx - cy);
+ }
+ }
+
+ r = rp[dn - in] - tp[dn];
+
+ /* Subtract the product from the partial remainder combined with new
+ limbs from the dividend N, generating a new partial remainder R. */
+ if (dn != in)
+ {
+ cy = mpn_sub_n (tp, np, tp, in); /* get next 'in' limbs from N */
+ cy = mpn_sub_nc (tp + in, rp, tp + in, dn - in, cy);
+ MPN_COPY (rp, tp, dn); /* FIXME: try to avoid this */
+ }
+ else
+ {
+ cy = mpn_sub_n (rp, np, tp, in); /* get next 'in' limbs from N */
+ }
+
+ STAT (int i; int err = 0;
+ static int errarr[5]; static int err_rec; static int tot);
+
+ /* Check the remainder R and adjust the quotient as needed. */
+ r -= cy;
+ while (r != 0)
+ {
+ /* We loop 0 times with about 69% probability, 1 time with about 31%
+ probability, 2 times with about 0.6% probability, if inverse is
+ computed as recommended. */
+ mpn_incr_u (qp, 1);
+ cy = mpn_sub_n (rp, rp, dp, dn);
+ r -= cy;
+ STAT (err++);
+ }
+ if (mpn_cmp (rp, dp, dn) >= 0)
+ {
+ /* This is executed with about 76% probability. */
+ mpn_incr_u (qp, 1);
+ cy = mpn_sub_n (rp, rp, dp, dn);
+ STAT (err++);
+ }
+
+ STAT (
+ tot++;
+ errarr[err]++;
+ if (err > err_rec)
+ err_rec = err;
+ if (tot % 0x10000 == 0)
+ {
+ for (i = 0; i <= err_rec; i++)
+ printf (" %d(%.1f%%)", errarr[i], 100.0*errarr[i]/tot);
+ printf ("\n");
+ }
+ );
+ }
+
+ return qh;
+}
+
+/* In case k=0 (automatic choice), we distinguish 3 cases:
+ (a) dn < qn: in = ceil(qn / ceil(qn/dn))
+ (b) dn/3 < qn <= dn: in = ceil(qn / 2)
+ (c) qn < dn/3: in = qn
+ In all cases we have in <= dn.
+ */
+mp_size_t
+mpn_mu_div_qr_choose_in (mp_size_t qn, mp_size_t dn, int k)
+{
+ mp_size_t in;
+
+ if (k == 0)
+ {
+ mp_size_t b;
+ if (qn > dn)
+ {
+ /* Compute an inverse size that is a nice partition of the quotient. */
+ b = (qn - 1) / dn + 1; /* ceil(qn/dn), number of blocks */
+ in = (qn - 1) / b + 1; /* ceil(qn/b) = ceil(qn / ceil(qn/dn)) */
+ }
+ else if (3 * qn > dn)
+ {
+ in = (qn - 1) / 2 + 1; /* b = 2 */
+ }
+ else
+ {
+ in = (qn - 1) / 1 + 1; /* b = 1 */
+ }
+ }
+ else
+ {
+ mp_size_t xn;
+ xn = MIN (dn, qn);
+ in = (xn - 1) / k + 1;
+ }
+
+ return in;
+}
+
+mp_size_t
+mpn_mu_div_qr_itch (mp_size_t nn, mp_size_t dn, int mua_k)
+{
+ mp_size_t itch_local = mpn_mulmod_bnm1_next_size (dn + 1);
+ mp_size_t in = mpn_mu_div_qr_choose_in (nn - dn, dn, mua_k);
+ mp_size_t itch_out = mpn_mulmod_bnm1_itch (itch_local, dn, in);
+
+ return in + itch_local + itch_out;
+}
+
+mp_size_t
+mpn_preinv_mu_div_qr_itch (mp_size_t nn, mp_size_t dn, mp_size_t in)
+{
+ mp_size_t itch_local = mpn_mulmod_bnm1_next_size (dn + 1);
+ mp_size_t itch_out = mpn_mulmod_bnm1_itch (itch_local, dn, in);
+
+ return itch_local + itch_out;
+}
diff --git a/gmp/mpn/generic/mu_divappr_q.c b/gmp/mpn/generic/mu_divappr_q.c
new file mode 100644
index 0000000000..c218b59fee
--- /dev/null
+++ b/gmp/mpn/generic/mu_divappr_q.c
@@ -0,0 +1,363 @@
+/* mpn_mu_divappr_q, mpn_preinv_mu_divappr_q.
+
+ Compute Q = floor(N / D) + e. N is nn limbs, D is dn limbs and must be
+ normalized, and Q must be nn-dn limbs, 0 <= e <= 4. The requirement that Q
+ is nn-dn limbs (and not nn-dn+1 limbs) was put in place in order to allow us
+ to let N be unmodified during the operation.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2005-2007, 2009, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/*
+ The idea of the algorithm used herein is to compute a smaller inverted value
+ than used in the standard Barrett algorithm, and thus save time in the
+ Newton iterations, and pay just a small price when using the inverted value
+ for developing quotient bits. This algorithm was presented at ICMS 2006.
+*/
+
+/* CAUTION: This code and the code in mu_div_qr.c should be edited in sync.
+
+ Things to work on:
+
+ * The itch/scratch scheme isn't perhaps such a good idea as it once seemed,
+ demonstrated by the fact that the mpn_invertappr function's scratch needs
+ mean that we need to keep a large allocation long after it is needed.
+ Things are worse as mpn_mul_fft does not accept any scratch parameter,
+ which means we'll have a large memory hole while in mpn_mul_fft. In
+ general, a peak scratch need in the beginning of a function isn't
+ well-handled by the itch/scratch scheme.
+*/
+
+#ifdef STAT
+#undef STAT
+#define STAT(x) x
+#else
+#define STAT(x)
+#endif
+
+#include <stdlib.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+mp_limb_t
+mpn_mu_divappr_q (mp_ptr qp,
+ mp_srcptr np,
+ mp_size_t nn,
+ mp_srcptr dp,
+ mp_size_t dn,
+ mp_ptr scratch)
+{
+ mp_size_t qn, in;
+ mp_limb_t cy, qh;
+ mp_ptr ip, tp;
+
+ ASSERT (dn > 1);
+
+ qn = nn - dn;
+
+ /* If Q is smaller than D, truncate operands. */
+ if (qn + 1 < dn)
+ {
+ np += dn - (qn + 1);
+ nn -= dn - (qn + 1);
+ dp += dn - (qn + 1);
+ dn = qn + 1;
+ }
+
+ /* Compute the inverse size. */
+ in = mpn_mu_divappr_q_choose_in (qn, dn, 0);
+ ASSERT (in <= dn);
+
+#if 1
+ /* This alternative inverse computation method gets slightly more accurate
+ results. FIXMEs: (1) Temp allocation needs not analysed (2) itch function
+ not adapted (3) mpn_invertappr scratch needs not met. */
+ ip = scratch;
+ tp = scratch + in + 1;
+
+ /* compute an approximate inverse on (in+1) limbs */
+ if (dn == in)
+ {
+ MPN_COPY (tp + 1, dp, in);
+ tp[0] = 1;
+ mpn_invertappr (ip, tp, in + 1, NULL);
+ MPN_COPY_INCR (ip, ip + 1, in);
+ }
+ else
+ {
+ cy = mpn_add_1 (tp, dp + dn - (in + 1), in + 1, 1);
+ if (UNLIKELY (cy != 0))
+ MPN_ZERO (ip, in);
+ else
+ {
+ mpn_invertappr (ip, tp, in + 1, NULL);
+ MPN_COPY_INCR (ip, ip + 1, in);
+ }
+ }
+#else
+ /* This older inverse computation method gets slightly worse results than the
+ one above. */
+ ip = scratch;
+ tp = scratch + in;
+
+ /* Compute inverse of D to in+1 limbs, then round to 'in' limbs. Ideally the
+ inversion function should do this automatically. */
+ if (dn == in)
+ {
+ tp[in + 1] = 0;
+ MPN_COPY (tp + in + 2, dp, in);
+ mpn_invertappr (tp, tp + in + 1, in + 1, NULL);
+ }
+ else
+ {
+ mpn_invertappr (tp, dp + dn - (in + 1), in + 1, NULL);
+ }
+ cy = mpn_sub_1 (tp, tp, in + 1, GMP_NUMB_HIGHBIT);
+ if (UNLIKELY (cy != 0))
+ MPN_ZERO (tp + 1, in);
+ MPN_COPY (ip, tp + 1, in);
+#endif
+
+ qh = mpn_preinv_mu_divappr_q (qp, np, nn, dp, dn, ip, in, scratch + in);
+
+ return qh;
+}
+
+mp_limb_t
+mpn_preinv_mu_divappr_q (mp_ptr qp,
+ mp_srcptr np,
+ mp_size_t nn,
+ mp_srcptr dp,
+ mp_size_t dn,
+ mp_srcptr ip,
+ mp_size_t in,
+ mp_ptr scratch)
+{
+ mp_size_t qn;
+ mp_limb_t cy, cx, qh;
+ mp_limb_t r;
+ mp_size_t tn, wn;
+
+#define rp scratch
+#define tp (scratch + dn)
+#define scratch_out (scratch + dn + tn)
+
+ qn = nn - dn;
+
+ np += qn;
+ qp += qn;
+
+ qh = mpn_cmp (np, dp, dn) >= 0;
+ if (qh != 0)
+ mpn_sub_n (rp, np, dp, dn);
+ else
+ MPN_COPY (rp, np, dn);
+
+ if (qn == 0)
+ return qh; /* Degenerate use. Should we allow this? */
+
+ while (qn > 0)
+ {
+ if (qn < in)
+ {
+ ip += in - qn;
+ in = qn;
+ }
+ np -= in;
+ qp -= in;
+
+ /* Compute the next block of quotient limbs by multiplying the inverse I
+ by the upper part of the partial remainder R. */
+ mpn_mul_n (tp, rp + dn - in, ip, in); /* mulhi */
+ cy = mpn_add_n (qp, tp + in, rp + dn - in, in); /* I's msb implicit */
+ ASSERT_ALWAYS (cy == 0);
+
+ qn -= in;
+ if (qn == 0)
+ break;
+
+ /* Compute the product of the quotient block and the divisor D, to be
+ subtracted from the partial remainder combined with new limbs from the
+ dividend N. We only really need the low dn limbs. */
+
+ if (BELOW_THRESHOLD (in, MUL_TO_MULMOD_BNM1_FOR_2NXN_THRESHOLD))
+ mpn_mul (tp, dp, dn, qp, in); /* dn+in limbs, high 'in' cancels */
+ else
+ {
+ tn = mpn_mulmod_bnm1_next_size (dn + 1);
+ mpn_mulmod_bnm1 (tp, tn, dp, dn, qp, in, scratch_out);
+ wn = dn + in - tn; /* number of wrapped limbs */
+ if (wn > 0)
+ {
+ cy = mpn_sub_n (tp, tp, rp + dn - wn, wn);
+ cy = mpn_sub_1 (tp + wn, tp + wn, tn - wn, cy);
+ cx = mpn_cmp (rp + dn - in, tp + dn, tn - dn) < 0;
+ ASSERT_ALWAYS (cx >= cy);
+ mpn_incr_u (tp, cx - cy);
+ }
+ }
+
+ r = rp[dn - in] - tp[dn];
+
+ /* Subtract the product from the partial remainder combined with new
+ limbs from the dividend N, generating a new partial remainder R. */
+ if (dn != in)
+ {
+ cy = mpn_sub_n (tp, np, tp, in); /* get next 'in' limbs from N */
+ cy = mpn_sub_nc (tp + in, rp, tp + in, dn - in, cy);
+ MPN_COPY (rp, tp, dn); /* FIXME: try to avoid this */
+ }
+ else
+ {
+ cy = mpn_sub_n (rp, np, tp, in); /* get next 'in' limbs from N */
+ }
+
+ STAT (int i; int err = 0;
+ static int errarr[5]; static int err_rec; static int tot);
+
+ /* Check the remainder R and adjust the quotient as needed. */
+ r -= cy;
+ while (r != 0)
+ {
+ /* We loop 0 times with about 69% probability, 1 time with about 31%
+ probability, 2 times with about 0.6% probability, if inverse is
+ computed as recommended. */
+ mpn_incr_u (qp, 1);
+ cy = mpn_sub_n (rp, rp, dp, dn);
+ r -= cy;
+ STAT (err++);
+ }
+ if (mpn_cmp (rp, dp, dn) >= 0)
+ {
+ /* This is executed with about 76% probability. */
+ mpn_incr_u (qp, 1);
+ cy = mpn_sub_n (rp, rp, dp, dn);
+ STAT (err++);
+ }
+
+ STAT (
+ tot++;
+ errarr[err]++;
+ if (err > err_rec)
+ err_rec = err;
+ if (tot % 0x10000 == 0)
+ {
+ for (i = 0; i <= err_rec; i++)
+ printf (" %d(%.1f%%)", errarr[i], 100.0*errarr[i]/tot);
+ printf ("\n");
+ }
+ );
+ }
+
+ /* FIXME: We should perhaps be somewhat more elegant in our rounding of the
+ quotient. For now, just make sure the returned quotient is >= the real
+ quotient; add 3 with saturating arithmetic. */
+ qn = nn - dn;
+ cy += mpn_add_1 (qp, qp, qn, 3);
+ if (cy != 0)
+ {
+ if (qh != 0)
+ {
+ /* Return a quotient of just 1-bits, with qh set. */
+ mp_size_t i;
+ for (i = 0; i < qn; i++)
+ qp[i] = GMP_NUMB_MAX;
+ }
+ else
+ {
+ /* Propagate carry into qh. */
+ qh = 1;
+ }
+ }
+
+ return qh;
+}
+
+/* In case k=0 (automatic choice), we distinguish 3 cases:
+ (a) dn < qn: in = ceil(qn / ceil(qn/dn))
+ (b) dn/3 < qn <= dn: in = ceil(qn / 2)
+ (c) qn < dn/3: in = qn
+ In all cases we have in <= dn.
+ */
+mp_size_t
+mpn_mu_divappr_q_choose_in (mp_size_t qn, mp_size_t dn, int k)
+{
+ mp_size_t in;
+
+ if (k == 0)
+ {
+ mp_size_t b;
+ if (qn > dn)
+ {
+ /* Compute an inverse size that is a nice partition of the quotient. */
+ b = (qn - 1) / dn + 1; /* ceil(qn/dn), number of blocks */
+ in = (qn - 1) / b + 1; /* ceil(qn/b) = ceil(qn / ceil(qn/dn)) */
+ }
+ else if (3 * qn > dn)
+ {
+ in = (qn - 1) / 2 + 1; /* b = 2 */
+ }
+ else
+ {
+ in = (qn - 1) / 1 + 1; /* b = 1 */
+ }
+ }
+ else
+ {
+ mp_size_t xn;
+ xn = MIN (dn, qn);
+ in = (xn - 1) / k + 1;
+ }
+
+ return in;
+}
+
+mp_size_t
+mpn_mu_divappr_q_itch (mp_size_t nn, mp_size_t dn, int mua_k)
+{
+ mp_size_t qn, in, itch_local, itch_out;
+
+ qn = nn - dn;
+ if (qn + 1 < dn)
+ {
+ dn = qn + 1;
+ }
+ in = mpn_mu_divappr_q_choose_in (qn, dn, mua_k);
+
+ itch_local = mpn_mulmod_bnm1_next_size (dn + 1);
+ itch_out = mpn_mulmod_bnm1_itch (itch_local, dn, in);
+ return in + dn + itch_local + itch_out;
+}
diff --git a/gmp/mpn/generic/mul.c b/gmp/mpn/generic/mul.c
new file mode 100644
index 0000000000..2d72df3d4d
--- /dev/null
+++ b/gmp/mpn/generic/mul.c
@@ -0,0 +1,428 @@
+/* mpn_mul -- Multiply two natural numbers.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 1999-2003, 2005-2007, 2009, 2010, 2012
+Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#ifndef MUL_BASECASE_MAX_UN
+#define MUL_BASECASE_MAX_UN 500
+#endif
+
+/* Areas where the different toom algorithms can be called (extracted
+ from the t-toom*.c files, and ignoring small constant offsets):
+
+ 1/6 1/5 1/4 4/13 1/3 3/8 2/5 5/11 1/2 3/5 2/3 3/4 4/5 1 vn/un
+ 4/7 6/7
+ 6/11
+ |--------------------| toom22 (small)
+ || toom22 (large)
+ |xxxx| toom22 called
+ |-------------------------------------| toom32
+ |xxxxxxxxxxxxxxxx| | toom32 called
+ |------------| toom33
+ |x| toom33 called
+ |---------------------------------| | toom42
+ |xxxxxxxxxxxxxxxxxxxxxxxx| | toom42 called
+ |--------------------| toom43
+ |xxxxxxxxxx| toom43 called
+ |-----------------------------| toom52 (unused)
+ |--------| toom44
+ |xxxxxxxx| toom44 called
+ |--------------------| | toom53
+ |xxxxxx| toom53 called
+ |-------------------------| toom62 (unused)
+ |----------------| toom54 (unused)
+ |--------------------| toom63
+ |xxxxxxxxx| | toom63 called
+ |---------------------------------| toom6h
+ |xxxxxxxx| toom6h called
+ |-------------------------| toom8h (32 bit)
+ |------------------------------------------| toom8h (64 bit)
+ |xxxxxxxx| toom8h called
+*/
+
+#define TOOM33_OK(an,bn) (6 + 2 * an < 3 * bn)
+#define TOOM44_OK(an,bn) (12 + 3 * an < 4 * bn)
+
+/* Multiply the natural numbers u (pointed to by UP, with UN limbs) and v
+ (pointed to by VP, with VN limbs), and store the result at PRODP. The
+ result is UN + VN limbs. Return the most significant limb of the result.
+
+ NOTE: The space pointed to by PRODP is overwritten before finished with U
+ and V, so overlap is an error.
+
+ Argument constraints:
+ 1. UN >= VN.
+ 2. PRODP != UP and PRODP != VP, i.e. the destination must be distinct from
+ the multiplier and the multiplicand. */
+
+/*
+ * The cutoff lines in the toomX2 and toomX3 code are now exactly between the
+ ideal lines of the surrounding algorithms. Is that optimal?
+
+ * The toomX3 code now uses a structure similar to the one of toomX2, except
+ that it loops longer in the unbalanced case. The result is that the
+ remaining area might have un < vn. Should we fix the toomX2 code in a
+ similar way?
+
+ * The toomX3 code is used for the largest non-FFT unbalanced operands. It
+ therefore calls mpn_mul recursively for certain cases.
+
+ * Allocate static temp space using THRESHOLD variables (except for toom44
+ when !WANT_FFT). That way, we can typically have no TMP_ALLOC at all.
+
+ * We sort ToomX2 algorithms together, assuming the toom22, toom32, toom42
+ have the same vn threshold. This is not true, we should actually use
+ mul_basecase for slightly larger operands for toom32 than for toom22, and
+ even larger for toom42.
+
+ * That problem is even more prevalent for toomX3. We therefore use special
+ THRESHOLD variables there.
+
+ * Is our ITCH allocation correct?
+*/
+
+#define ITCH (16*vn + 100)
+
+mp_limb_t
+mpn_mul (mp_ptr prodp,
+ mp_srcptr up, mp_size_t un,
+ mp_srcptr vp, mp_size_t vn)
+{
+ ASSERT (un >= vn);
+ ASSERT (vn >= 1);
+ ASSERT (! MPN_OVERLAP_P (prodp, un+vn, up, un));
+ ASSERT (! MPN_OVERLAP_P (prodp, un+vn, vp, vn));
+
+ if (un == vn)
+ {
+ if (up == vp)
+ mpn_sqr (prodp, up, un);
+ else
+ mpn_mul_n (prodp, up, vp, un);
+ }
+ else if (vn < MUL_TOOM22_THRESHOLD)
+ { /* plain schoolbook multiplication */
+
+ /* Unless un is very large, or else if have an applicable mpn_mul_N,
+ perform basecase multiply directly. */
+ if (un <= MUL_BASECASE_MAX_UN
+#if HAVE_NATIVE_mpn_mul_2
+ || vn <= 2
+#else
+ || vn == 1
+#endif
+ )
+ mpn_mul_basecase (prodp, up, un, vp, vn);
+ else
+ {
+ /* We have un >> MUL_BASECASE_MAX_UN > vn. For better memory
+ locality, split up[] into MUL_BASECASE_MAX_UN pieces and multiply
+ these pieces with the vp[] operand. After each such partial
+ multiplication (but the last) we copy the most significant vn
+ limbs into a temporary buffer since that part would otherwise be
+ overwritten by the next multiplication. After the next
+ multiplication, we add it back. This illustrates the situation:
+
+ -->vn<--
+ | |<------- un ------->|
+ _____________________|
+ X /|
+ /XX__________________/ |
+ _____________________ |
+ X / |
+ /XX__________________/ |
+ _____________________ |
+ / / |
+ /____________________/ |
+ ==================================================================
+
+ The parts marked with X are the parts whose sums are copied into
+ the temporary buffer. */
+
+ mp_limb_t tp[MUL_TOOM22_THRESHOLD_LIMIT];
+ mp_limb_t cy;
+ ASSERT (MUL_TOOM22_THRESHOLD <= MUL_TOOM22_THRESHOLD_LIMIT);
+
+ mpn_mul_basecase (prodp, up, MUL_BASECASE_MAX_UN, vp, vn);
+ prodp += MUL_BASECASE_MAX_UN;
+ MPN_COPY (tp, prodp, vn); /* preserve high triangle */
+ up += MUL_BASECASE_MAX_UN;
+ un -= MUL_BASECASE_MAX_UN;
+ while (un > MUL_BASECASE_MAX_UN)
+ {
+ mpn_mul_basecase (prodp, up, MUL_BASECASE_MAX_UN, vp, vn);
+ cy = mpn_add_n (prodp, prodp, tp, vn); /* add back preserved triangle */
+ mpn_incr_u (prodp + vn, cy);
+ prodp += MUL_BASECASE_MAX_UN;
+ MPN_COPY (tp, prodp, vn); /* preserve high triangle */
+ up += MUL_BASECASE_MAX_UN;
+ un -= MUL_BASECASE_MAX_UN;
+ }
+ if (un > vn)
+ {
+ mpn_mul_basecase (prodp, up, un, vp, vn);
+ }
+ else
+ {
+ ASSERT (un > 0);
+ mpn_mul_basecase (prodp, vp, vn, up, un);
+ }
+ cy = mpn_add_n (prodp, prodp, tp, vn); /* add back preserved triangle */
+ mpn_incr_u (prodp + vn, cy);
+ }
+ }
+ else if (BELOW_THRESHOLD (vn, MUL_TOOM33_THRESHOLD))
+ {
+ /* Use ToomX2 variants */
+ mp_ptr scratch;
+ TMP_SDECL; TMP_SMARK;
+
+ scratch = TMP_SALLOC_LIMBS (ITCH);
+
+ /* FIXME: This condition (repeated in the loop below) leaves from a vn*vn
+ square to a (3vn-1)*vn rectangle. Leaving such a rectangle is hardly
+ wise; we would get better balance by slightly moving the bound. We
+ will sometimes end up with un < vn, like in the X3 arm below. */
+ if (un >= 3 * vn)
+ {
+ mp_limb_t cy;
+ mp_ptr ws;
+
+ /* The maximum ws usage is for the mpn_mul result. */
+ ws = TMP_SALLOC_LIMBS (4 * vn);
+
+ mpn_toom42_mul (prodp, up, 2 * vn, vp, vn, scratch);
+ un -= 2 * vn;
+ up += 2 * vn;
+ prodp += 2 * vn;
+
+ while (un >= 3 * vn)
+ {
+ mpn_toom42_mul (ws, up, 2 * vn, vp, vn, scratch);
+ un -= 2 * vn;
+ up += 2 * vn;
+ cy = mpn_add_n (prodp, prodp, ws, vn);
+ MPN_COPY (prodp + vn, ws + vn, 2 * vn);
+ mpn_incr_u (prodp + vn, cy);
+ prodp += 2 * vn;
+ }
+
+ /* vn <= un < 3vn */
+
+ if (4 * un < 5 * vn)
+ mpn_toom22_mul (ws, up, un, vp, vn, scratch);
+ else if (4 * un < 7 * vn)
+ mpn_toom32_mul (ws, up, un, vp, vn, scratch);
+ else
+ mpn_toom42_mul (ws, up, un, vp, vn, scratch);
+
+ cy = mpn_add_n (prodp, prodp, ws, vn);
+ MPN_COPY (prodp + vn, ws + vn, un);
+ mpn_incr_u (prodp + vn, cy);
+ }
+ else
+ {
+ if (4 * un < 5 * vn)
+ mpn_toom22_mul (prodp, up, un, vp, vn, scratch);
+ else if (4 * un < 7 * vn)
+ mpn_toom32_mul (prodp, up, un, vp, vn, scratch);
+ else
+ mpn_toom42_mul (prodp, up, un, vp, vn, scratch);
+ }
+ TMP_SFREE;
+ }
+ else if (BELOW_THRESHOLD ((un + vn) >> 1, MUL_FFT_THRESHOLD) ||
+ BELOW_THRESHOLD (3 * vn, MUL_FFT_THRESHOLD))
+ {
+ /* Handle the largest operands that are not in the FFT range. The 2nd
+ condition makes very unbalanced operands avoid the FFT code (except
+ perhaps as coefficient products of the Toom code. */
+
+ if (BELOW_THRESHOLD (vn, MUL_TOOM44_THRESHOLD) || !TOOM44_OK (un, vn))
+ {
+ /* Use ToomX3 variants */
+ mp_ptr scratch;
+ TMP_SDECL; TMP_SMARK;
+
+ scratch = TMP_SALLOC_LIMBS (ITCH);
+
+ if (2 * un >= 5 * vn)
+ {
+ mp_limb_t cy;
+ mp_ptr ws;
+
+ /* The maximum ws usage is for the mpn_mul result. */
+ ws = TMP_SALLOC_LIMBS (7 * vn >> 1);
+
+ if (BELOW_THRESHOLD (vn, MUL_TOOM42_TO_TOOM63_THRESHOLD))
+ mpn_toom42_mul (prodp, up, 2 * vn, vp, vn, scratch);
+ else
+ mpn_toom63_mul (prodp, up, 2 * vn, vp, vn, scratch);
+ un -= 2 * vn;
+ up += 2 * vn;
+ prodp += 2 * vn;
+
+ while (2 * un >= 5 * vn) /* un >= 2.5vn */
+ {
+ if (BELOW_THRESHOLD (vn, MUL_TOOM42_TO_TOOM63_THRESHOLD))
+ mpn_toom42_mul (ws, up, 2 * vn, vp, vn, scratch);
+ else
+ mpn_toom63_mul (ws, up, 2 * vn, vp, vn, scratch);
+ un -= 2 * vn;
+ up += 2 * vn;
+ cy = mpn_add_n (prodp, prodp, ws, vn);
+ MPN_COPY (prodp + vn, ws + vn, 2 * vn);
+ mpn_incr_u (prodp + vn, cy);
+ prodp += 2 * vn;
+ }
+
+ /* vn / 2 <= un < 2.5vn */
+
+ if (un < vn)
+ mpn_mul (ws, vp, vn, up, un);
+ else
+ mpn_mul (ws, up, un, vp, vn);
+
+ cy = mpn_add_n (prodp, prodp, ws, vn);
+ MPN_COPY (prodp + vn, ws + vn, un);
+ mpn_incr_u (prodp + vn, cy);
+ }
+ else
+ {
+ if (6 * un < 7 * vn)
+ mpn_toom33_mul (prodp, up, un, vp, vn, scratch);
+ else if (2 * un < 3 * vn)
+ {
+ if (BELOW_THRESHOLD (vn, MUL_TOOM32_TO_TOOM43_THRESHOLD))
+ mpn_toom32_mul (prodp, up, un, vp, vn, scratch);
+ else
+ mpn_toom43_mul (prodp, up, un, vp, vn, scratch);
+ }
+ else if (6 * un < 11 * vn)
+ {
+ if (4 * un < 7 * vn)
+ {
+ if (BELOW_THRESHOLD (vn, MUL_TOOM32_TO_TOOM53_THRESHOLD))
+ mpn_toom32_mul (prodp, up, un, vp, vn, scratch);
+ else
+ mpn_toom53_mul (prodp, up, un, vp, vn, scratch);
+ }
+ else
+ {
+ if (BELOW_THRESHOLD (vn, MUL_TOOM42_TO_TOOM53_THRESHOLD))
+ mpn_toom42_mul (prodp, up, un, vp, vn, scratch);
+ else
+ mpn_toom53_mul (prodp, up, un, vp, vn, scratch);
+ }
+ }
+ else
+ {
+ if (BELOW_THRESHOLD (vn, MUL_TOOM42_TO_TOOM63_THRESHOLD))
+ mpn_toom42_mul (prodp, up, un, vp, vn, scratch);
+ else
+ mpn_toom63_mul (prodp, up, un, vp, vn, scratch);
+ }
+ }
+ TMP_SFREE;
+ }
+ else
+ {
+ mp_ptr scratch;
+ TMP_DECL; TMP_MARK;
+
+ if (BELOW_THRESHOLD (vn, MUL_TOOM6H_THRESHOLD))
+ {
+ scratch = TMP_ALLOC_LIMBS (mpn_toom44_mul_itch (un, vn));
+ mpn_toom44_mul (prodp, up, un, vp, vn, scratch);
+ }
+ else if (BELOW_THRESHOLD (vn, MUL_TOOM8H_THRESHOLD))
+ {
+ scratch = TMP_ALLOC_LIMBS (mpn_toom6h_mul_itch (un, vn));
+ mpn_toom6h_mul (prodp, up, un, vp, vn, scratch);
+ }
+ else
+ {
+ scratch = TMP_ALLOC_LIMBS (mpn_toom8h_mul_itch (un, vn));
+ mpn_toom8h_mul (prodp, up, un, vp, vn, scratch);
+ }
+ TMP_FREE;
+ }
+ }
+ else
+ {
+ if (un >= 8 * vn)
+ {
+ mp_limb_t cy;
+ mp_ptr ws;
+ TMP_DECL; TMP_MARK;
+
+ /* The maximum ws usage is for the mpn_mul result. */
+ ws = TMP_BALLOC_LIMBS (9 * vn >> 1);
+
+ mpn_fft_mul (prodp, up, 3 * vn, vp, vn);
+ un -= 3 * vn;
+ up += 3 * vn;
+ prodp += 3 * vn;
+
+ while (2 * un >= 7 * vn) /* un >= 3.5vn */
+ {
+ mpn_fft_mul (ws, up, 3 * vn, vp, vn);
+ un -= 3 * vn;
+ up += 3 * vn;
+ cy = mpn_add_n (prodp, prodp, ws, vn);
+ MPN_COPY (prodp + vn, ws + vn, 3 * vn);
+ mpn_incr_u (prodp + vn, cy);
+ prodp += 3 * vn;
+ }
+
+ /* vn / 2 <= un < 3.5vn */
+
+ if (un < vn)
+ mpn_mul (ws, vp, vn, up, un);
+ else
+ mpn_mul (ws, up, un, vp, vn);
+
+ cy = mpn_add_n (prodp, prodp, ws, vn);
+ MPN_COPY (prodp + vn, ws + vn, un);
+ mpn_incr_u (prodp + vn, cy);
+
+ TMP_FREE;
+ }
+ else
+ mpn_fft_mul (prodp, up, un, vp, vn);
+ }
+
+ return prodp[un + vn - 1]; /* historic */
+}
diff --git a/gmp/mpn/generic/mul_1.c b/gmp/mpn/generic/mul_1.c
new file mode 100644
index 0000000000..6b2ee59a2c
--- /dev/null
+++ b/gmp/mpn/generic/mul_1.c
@@ -0,0 +1,97 @@
+/* mpn_mul_1 -- Multiply a limb vector with a single limb and store the
+ product in a second limb vector.
+
+Copyright 1991-1994, 1996, 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#if GMP_NAIL_BITS == 0
+
+mp_limb_t
+mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t ul, cl, hpl, lpl;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
+
+ cl = 0;
+ do
+ {
+ ul = *up++;
+ umul_ppmm (hpl, lpl, ul, vl);
+
+ lpl += cl;
+ cl = (lpl < cl) + hpl;
+
+ *rp++ = lpl;
+ }
+ while (--n != 0);
+
+ return cl;
+}
+
+#endif
+
+#if GMP_NAIL_BITS >= 1
+
+mp_limb_t
+mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t shifted_vl, ul, lpl, hpl, prev_hpl, xw, cl, xl;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
+ ASSERT_MPN (up, n);
+ ASSERT_LIMB (vl);
+
+ shifted_vl = vl << GMP_NAIL_BITS;
+ cl = 0;
+ prev_hpl = 0;
+ do
+ {
+ ul = *up++;
+
+ umul_ppmm (hpl, lpl, ul, shifted_vl);
+ lpl >>= GMP_NAIL_BITS;
+ xw = prev_hpl + lpl + cl;
+ cl = xw >> GMP_NUMB_BITS;
+ xl = xw & GMP_NUMB_MASK;
+ *rp++ = xl;
+ prev_hpl = hpl;
+ }
+ while (--n != 0);
+
+ return prev_hpl + cl;
+}
+
+#endif
diff --git a/gmp/mpn/generic/mul_basecase.c b/gmp/mpn/generic/mul_basecase.c
new file mode 100644
index 0000000000..9309ef72c8
--- /dev/null
+++ b/gmp/mpn/generic/mul_basecase.c
@@ -0,0 +1,166 @@
+/* mpn_mul_basecase -- Internal routine to multiply two natural numbers
+ of length m and n.
+
+ THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES.
+
+Copyright 1991-1994, 1996, 1997, 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Multiply {up,usize} by {vp,vsize} and write the result to
+ {prodp,usize+vsize}. Must have usize>=vsize.
+
+ Note that prodp gets usize+vsize limbs stored, even if the actual result
+ only needs usize+vsize-1.
+
+ There's no good reason to call here with vsize>=MUL_TOOM22_THRESHOLD.
+ Currently this is allowed, but it might not be in the future.
+
+ This is the most critical code for multiplication. All multiplies rely
+ on this, both small and huge. Small ones arrive here immediately, huge
+ ones arrive here as this is the base case for Karatsuba's recursive
+ algorithm. */
+
+void
+mpn_mul_basecase (mp_ptr rp,
+ mp_srcptr up, mp_size_t un,
+ mp_srcptr vp, mp_size_t vn)
+{
+ ASSERT (un >= vn);
+ ASSERT (vn >= 1);
+ ASSERT (! MPN_OVERLAP_P (rp, un+vn, up, un));
+ ASSERT (! MPN_OVERLAP_P (rp, un+vn, vp, vn));
+
+ /* We first multiply by the low order limb (or depending on optional function
+ availability, limbs). This result can be stored, not added, to rp. We
+ also avoid a loop for zeroing this way. */
+
+#if HAVE_NATIVE_mpn_mul_2
+ if (vn >= 2)
+ {
+ rp[un + 1] = mpn_mul_2 (rp, up, un, vp);
+ rp += 2, vp += 2, vn -= 2;
+ }
+ else
+ {
+ rp[un] = mpn_mul_1 (rp, up, un, vp[0]);
+ return;
+ }
+#else
+ rp[un] = mpn_mul_1 (rp, up, un, vp[0]);
+ rp += 1, vp += 1, vn -= 1;
+#endif
+
+ /* Now accumulate the product of up[] and the next higher limb (or depending
+ on optional function availability, limbs) from vp[]. */
+
+#define MAX_LEFT MP_SIZE_T_MAX /* Used to simplify loops into if statements */
+
+
+#if HAVE_NATIVE_mpn_addmul_6
+ while (vn >= 6)
+ {
+ rp[un + 6 - 1] = mpn_addmul_6 (rp, up, un, vp);
+ if (MAX_LEFT == 6)
+ return;
+ rp += 6, vp += 6, vn -= 6;
+ if (MAX_LEFT < 2 * 6)
+ break;
+ }
+#undef MAX_LEFT
+#define MAX_LEFT (6 - 1)
+#endif
+
+#if HAVE_NATIVE_mpn_addmul_5
+ while (vn >= 5)
+ {
+ rp[un + 5 - 1] = mpn_addmul_5 (rp, up, un, vp);
+ if (MAX_LEFT == 5)
+ return;
+ rp += 5, vp += 5, vn -= 5;
+ if (MAX_LEFT < 2 * 5)
+ break;
+ }
+#undef MAX_LEFT
+#define MAX_LEFT (5 - 1)
+#endif
+
+#if HAVE_NATIVE_mpn_addmul_4
+ while (vn >= 4)
+ {
+ rp[un + 4 - 1] = mpn_addmul_4 (rp, up, un, vp);
+ if (MAX_LEFT == 4)
+ return;
+ rp += 4, vp += 4, vn -= 4;
+ if (MAX_LEFT < 2 * 4)
+ break;
+ }
+#undef MAX_LEFT
+#define MAX_LEFT (4 - 1)
+#endif
+
+#if HAVE_NATIVE_mpn_addmul_3
+ while (vn >= 3)
+ {
+ rp[un + 3 - 1] = mpn_addmul_3 (rp, up, un, vp);
+ if (MAX_LEFT == 3)
+ return;
+ rp += 3, vp += 3, vn -= 3;
+ if (MAX_LEFT < 2 * 3)
+ break;
+ }
+#undef MAX_LEFT
+#define MAX_LEFT (3 - 1)
+#endif
+
+#if HAVE_NATIVE_mpn_addmul_2
+ while (vn >= 2)
+ {
+ rp[un + 2 - 1] = mpn_addmul_2 (rp, up, un, vp);
+ if (MAX_LEFT == 2)
+ return;
+ rp += 2, vp += 2, vn -= 2;
+ if (MAX_LEFT < 2 * 2)
+ break;
+ }
+#undef MAX_LEFT
+#define MAX_LEFT (2 - 1)
+#endif
+
+ while (vn >= 1)
+ {
+ rp[un] = mpn_addmul_1 (rp, up, un, vp[0]);
+ if (MAX_LEFT == 1)
+ return;
+ rp += 1, vp += 1, vn -= 1;
+ }
+}
diff --git a/gmp/mpn/generic/mul_fft.c b/gmp/mpn/generic/mul_fft.c
new file mode 100644
index 0000000000..5e763a3a73
--- /dev/null
+++ b/gmp/mpn/generic/mul_fft.c
@@ -0,0 +1,1014 @@
+/* Schoenhage's fast multiplication modulo 2^N+1.
+
+ Contributed by Paul Zimmermann.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 1998-2010, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* References:
+
+ Schnelle Multiplikation grosser Zahlen, by Arnold Schoenhage and Volker
+ Strassen, Computing 7, p. 281-292, 1971.
+
+ Asymptotically fast algorithms for the numerical multiplication and division
+ of polynomials with complex coefficients, by Arnold Schoenhage, Computer
+ Algebra, EUROCAM'82, LNCS 144, p. 3-15, 1982.
+
+ Tapes versus Pointers, a study in implementing fast algorithms, by Arnold
+ Schoenhage, Bulletin of the EATCS, 30, p. 23-32, 1986.
+
+ TODO:
+
+ Implement some of the tricks published at ISSAC'2007 by Gaudry, Kruppa, and
+ Zimmermann.
+
+ It might be possible to avoid a small number of MPN_COPYs by using a
+ rotating temporary or two.
+
+ Cleanup and simplify the code!
+*/
+
+#ifdef TRACE
+#undef TRACE
+#define TRACE(x) x
+#include <stdio.h>
+#else
+#define TRACE(x)
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifdef WANT_ADDSUB
+#include "generic/add_n_sub_n.c"
+#define HAVE_NATIVE_mpn_add_n_sub_n 1
+#endif
+
+static mp_limb_t mpn_mul_fft_internal (mp_ptr, mp_size_t, int, mp_ptr *,
+ mp_ptr *, mp_ptr, mp_ptr, mp_size_t,
+ mp_size_t, mp_size_t, int **, mp_ptr, int);
+static void mpn_mul_fft_decompose (mp_ptr, mp_ptr *, mp_size_t, mp_size_t, mp_srcptr,
+ mp_size_t, mp_size_t, mp_size_t, mp_ptr);
+
+
+/* Find the best k to use for a mod 2^(m*GMP_NUMB_BITS)+1 FFT for m >= n.
+ We have sqr=0 if for a multiply, sqr=1 for a square.
+ There are three generations of this code; we keep the old ones as long as
+ some gmp-mparam.h is not updated. */
+
+
+/*****************************************************************************/
+
+#if TUNE_PROGRAM_BUILD || (defined (MUL_FFT_TABLE3) && defined (SQR_FFT_TABLE3))
+
+#ifndef FFT_TABLE3_SIZE /* When tuning this is defined in gmp-impl.h */
+#if defined (MUL_FFT_TABLE3_SIZE) && defined (SQR_FFT_TABLE3_SIZE)
+#if MUL_FFT_TABLE3_SIZE > SQR_FFT_TABLE3_SIZE
+#define FFT_TABLE3_SIZE MUL_FFT_TABLE3_SIZE
+#else
+#define FFT_TABLE3_SIZE SQR_FFT_TABLE3_SIZE
+#endif
+#endif
+#endif
+
+#ifndef FFT_TABLE3_SIZE
+#define FFT_TABLE3_SIZE 200
+#endif
+
+FFT_TABLE_ATTRS struct fft_table_nk mpn_fft_table3[2][FFT_TABLE3_SIZE] =
+{
+ MUL_FFT_TABLE3,
+ SQR_FFT_TABLE3
+};
+
+int
+mpn_fft_best_k (mp_size_t n, int sqr)
+{
+ FFT_TABLE_ATTRS struct fft_table_nk *fft_tab, *tab;
+ mp_size_t tab_n, thres;
+ int last_k;
+
+ fft_tab = mpn_fft_table3[sqr];
+ last_k = fft_tab->k;
+ for (tab = fft_tab + 1; ; tab++)
+ {
+ tab_n = tab->n;
+ thres = tab_n << last_k;
+ if (n <= thres)
+ break;
+ last_k = tab->k;
+ }
+ return last_k;
+}
+
+#define MPN_FFT_BEST_READY 1
+#endif
+
+/*****************************************************************************/
+
+#if ! defined (MPN_FFT_BEST_READY)
+FFT_TABLE_ATTRS mp_size_t mpn_fft_table[2][MPN_FFT_TABLE_SIZE] =
+{
+ MUL_FFT_TABLE,
+ SQR_FFT_TABLE
+};
+
+int
+mpn_fft_best_k (mp_size_t n, int sqr)
+{
+ int i;
+
+ for (i = 0; mpn_fft_table[sqr][i] != 0; i++)
+ if (n < mpn_fft_table[sqr][i])
+ return i + FFT_FIRST_K;
+
+ /* treat 4*last as one further entry */
+ if (i == 0 || n < 4 * mpn_fft_table[sqr][i - 1])
+ return i + FFT_FIRST_K;
+ else
+ return i + FFT_FIRST_K + 1;
+}
+#endif
+
+/*****************************************************************************/
+
+
+/* Returns smallest possible number of limbs >= pl for a fft of size 2^k,
+ i.e. smallest multiple of 2^k >= pl.
+
+ Don't declare static: needed by tuneup.
+*/
+
+mp_size_t
+mpn_fft_next_size (mp_size_t pl, int k)
+{
+ pl = 1 + ((pl - 1) >> k); /* ceil (pl/2^k) */
+ return pl << k;
+}
+
+
+/* Initialize l[i][j] with bitrev(j) */
+static void
+mpn_fft_initl (int **l, int k)
+{
+ int i, j, K;
+ int *li;
+
+ l[0][0] = 0;
+ for (i = 1, K = 1; i <= k; i++, K *= 2)
+ {
+ li = l[i];
+ for (j = 0; j < K; j++)
+ {
+ li[j] = 2 * l[i - 1][j];
+ li[K + j] = 1 + li[j];
+ }
+ }
+}
+
+
+/* r <- a*2^d mod 2^(n*GMP_NUMB_BITS)+1 with a = {a, n+1}
+ Assumes a is semi-normalized, i.e. a[n] <= 1.
+ r and a must have n+1 limbs, and not overlap.
+*/
+static void
+mpn_fft_mul_2exp_modF (mp_ptr r, mp_srcptr a, mp_bitcnt_t d, mp_size_t n)
+{
+ unsigned int sh;
+ mp_size_t m;
+ mp_limb_t cc, rd;
+
+ sh = d % GMP_NUMB_BITS;
+ m = d / GMP_NUMB_BITS;
+
+ if (m >= n) /* negate */
+ {
+ /* r[0..m-1] <-- lshift(a[n-m]..a[n-1], sh)
+ r[m..n-1] <-- -lshift(a[0]..a[n-m-1], sh) */
+
+ m -= n;
+ if (sh != 0)
+ {
+ /* no out shift below since a[n] <= 1 */
+ mpn_lshift (r, a + n - m, m + 1, sh);
+ rd = r[m];
+ cc = mpn_lshiftc (r + m, a, n - m, sh);
+ }
+ else
+ {
+ MPN_COPY (r, a + n - m, m);
+ rd = a[n];
+ mpn_com (r + m, a, n - m);
+ cc = 0;
+ }
+
+ /* add cc to r[0], and add rd to r[m] */
+
+ /* now add 1 in r[m], subtract 1 in r[n], i.e. add 1 in r[0] */
+
+ r[n] = 0;
+ /* cc < 2^sh <= 2^(GMP_NUMB_BITS-1) thus no overflow here */
+ cc++;
+ mpn_incr_u (r, cc);
+
+ rd++;
+ /* rd might overflow when sh=GMP_NUMB_BITS-1 */
+ cc = (rd == 0) ? 1 : rd;
+ r = r + m + (rd == 0);
+ mpn_incr_u (r, cc);
+ }
+ else
+ {
+ /* r[0..m-1] <-- -lshift(a[n-m]..a[n-1], sh)
+ r[m..n-1] <-- lshift(a[0]..a[n-m-1], sh) */
+ if (sh != 0)
+ {
+ /* no out bits below since a[n] <= 1 */
+ mpn_lshiftc (r, a + n - m, m + 1, sh);
+ rd = ~r[m];
+ /* {r, m+1} = {a+n-m, m+1} << sh */
+ cc = mpn_lshift (r + m, a, n - m, sh); /* {r+m, n-m} = {a, n-m}<<sh */
+ }
+ else
+ {
+ /* r[m] is not used below, but we save a test for m=0 */
+ mpn_com (r, a + n - m, m + 1);
+ rd = a[n];
+ MPN_COPY (r + m, a, n - m);
+ cc = 0;
+ }
+
+ /* now complement {r, m}, subtract cc from r[0], subtract rd from r[m] */
+
+ /* if m=0 we just have r[0]=a[n] << sh */
+ if (m != 0)
+ {
+ /* now add 1 in r[0], subtract 1 in r[m] */
+ if (cc-- == 0) /* then add 1 to r[0] */
+ cc = mpn_add_1 (r, r, n, CNST_LIMB(1));
+ cc = mpn_sub_1 (r, r, m, cc) + 1;
+ /* add 1 to cc instead of rd since rd might overflow */
+ }
+
+ /* now subtract cc and rd from r[m..n] */
+
+ r[n] = -mpn_sub_1 (r + m, r + m, n - m, cc);
+ r[n] -= mpn_sub_1 (r + m, r + m, n - m, rd);
+ if (r[n] & GMP_LIMB_HIGHBIT)
+ r[n] = mpn_add_1 (r, r, n, CNST_LIMB(1));
+ }
+}
+
+
+/* r <- a+b mod 2^(n*GMP_NUMB_BITS)+1.
+ Assumes a and b are semi-normalized.
+*/
+static inline void
+mpn_fft_add_modF (mp_ptr r, mp_srcptr a, mp_srcptr b, mp_size_t n)
+{
+ mp_limb_t c, x;
+
+ c = a[n] + b[n] + mpn_add_n (r, a, b, n);
+ /* 0 <= c <= 3 */
+
+#if 1
+ /* GCC 4.1 outsmarts most expressions here, and generates a 50% branch. The
+ result is slower code, of course. But the following outsmarts GCC. */
+ x = (c - 1) & -(c != 0);
+ r[n] = c - x;
+ MPN_DECR_U (r, n + 1, x);
+#endif
+#if 0
+ if (c > 1)
+ {
+ r[n] = 1; /* r[n] - c = 1 */
+ MPN_DECR_U (r, n + 1, c - 1);
+ }
+ else
+ {
+ r[n] = c;
+ }
+#endif
+}
+
+/* r <- a-b mod 2^(n*GMP_NUMB_BITS)+1.
+ Assumes a and b are semi-normalized.
+*/
+static inline void
+mpn_fft_sub_modF (mp_ptr r, mp_srcptr a, mp_srcptr b, mp_size_t n)
+{
+ mp_limb_t c, x;
+
+ c = a[n] - b[n] - mpn_sub_n (r, a, b, n);
+ /* -2 <= c <= 1 */
+
+#if 1
+ /* GCC 4.1 outsmarts most expressions here, and generates a 50% branch. The
+ result is slower code, of course. But the following outsmarts GCC. */
+ x = (-c) & -((c & GMP_LIMB_HIGHBIT) != 0);
+ r[n] = x + c;
+ MPN_INCR_U (r, n + 1, x);
+#endif
+#if 0
+ if ((c & GMP_LIMB_HIGHBIT) != 0)
+ {
+ r[n] = 0;
+ MPN_INCR_U (r, n + 1, -c);
+ }
+ else
+ {
+ r[n] = c;
+ }
+#endif
+}
+
+/* input: A[0] ... A[inc*(K-1)] are residues mod 2^N+1 where
+ N=n*GMP_NUMB_BITS, and 2^omega is a primitive root mod 2^N+1
+ output: A[inc*l[k][i]] <- \sum (2^omega)^(ij) A[inc*j] mod 2^N+1 */
+
+static void
+mpn_fft_fft (mp_ptr *Ap, mp_size_t K, int **ll,
+ mp_size_t omega, mp_size_t n, mp_size_t inc, mp_ptr tp)
+{
+ if (K == 2)
+ {
+ mp_limb_t cy;
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ cy = mpn_add_n_sub_n (Ap[0], Ap[inc], Ap[0], Ap[inc], n + 1) & 1;
+#else
+ MPN_COPY (tp, Ap[0], n + 1);
+ mpn_add_n (Ap[0], Ap[0], Ap[inc], n + 1);
+ cy = mpn_sub_n (Ap[inc], tp, Ap[inc], n + 1);
+#endif
+ if (Ap[0][n] > 1) /* can be 2 or 3 */
+ Ap[0][n] = 1 - mpn_sub_1 (Ap[0], Ap[0], n, Ap[0][n] - 1);
+ if (cy) /* Ap[inc][n] can be -1 or -2 */
+ Ap[inc][n] = mpn_add_1 (Ap[inc], Ap[inc], n, ~Ap[inc][n] + 1);
+ }
+ else
+ {
+ mp_size_t j, K2 = K >> 1;
+ int *lk = *ll;
+
+ mpn_fft_fft (Ap, K2, ll-1, 2 * omega, n, inc * 2, tp);
+ mpn_fft_fft (Ap+inc, K2, ll-1, 2 * omega, n, inc * 2, tp);
+ /* A[2*j*inc] <- A[2*j*inc] + omega^l[k][2*j*inc] A[(2j+1)inc]
+ A[(2j+1)inc] <- A[2*j*inc] + omega^l[k][(2j+1)inc] A[(2j+1)inc] */
+ for (j = 0; j < K2; j++, lk += 2, Ap += 2 * inc)
+ {
+ /* Ap[inc] <- Ap[0] + Ap[inc] * 2^(lk[1] * omega)
+ Ap[0] <- Ap[0] + Ap[inc] * 2^(lk[0] * omega) */
+ mpn_fft_mul_2exp_modF (tp, Ap[inc], lk[0] * omega, n);
+ mpn_fft_sub_modF (Ap[inc], Ap[0], tp, n);
+ mpn_fft_add_modF (Ap[0], Ap[0], tp, n);
+ }
+ }
+}
+
+/* input: A[0] ... A[inc*(K-1)] are residues mod 2^N+1 where
+ N=n*GMP_NUMB_BITS, and 2^omega is a primitive root mod 2^N+1
+ output: A[inc*l[k][i]] <- \sum (2^omega)^(ij) A[inc*j] mod 2^N+1
+ tp must have space for 2*(n+1) limbs.
+*/
+
+
+/* Given ap[0..n] with ap[n]<=1, reduce it modulo 2^(n*GMP_NUMB_BITS)+1,
+ by subtracting that modulus if necessary.
+
+ If ap[0..n] is exactly 2^(n*GMP_NUMB_BITS) then mpn_sub_1 produces a
+ borrow and the limbs must be zeroed out again. This will occur very
+ infrequently. */
+
+static inline void
+mpn_fft_normalize (mp_ptr ap, mp_size_t n)
+{
+ if (ap[n] != 0)
+ {
+ MPN_DECR_U (ap, n + 1, CNST_LIMB(1));
+ if (ap[n] == 0)
+ {
+ /* This happens with very low probability; we have yet to trigger it,
+ and thereby make sure this code is correct. */
+ MPN_ZERO (ap, n);
+ ap[n] = 1;
+ }
+ else
+ ap[n] = 0;
+ }
+}
+
+/* a[i] <- a[i]*b[i] mod 2^(n*GMP_NUMB_BITS)+1 for 0 <= i < K */
+static void
+mpn_fft_mul_modF_K (mp_ptr *ap, mp_ptr *bp, mp_size_t n, mp_size_t K)
+{
+ int i;
+ int sqr = (ap == bp);
+ TMP_DECL;
+
+ TMP_MARK;
+
+ if (n >= (sqr ? SQR_FFT_MODF_THRESHOLD : MUL_FFT_MODF_THRESHOLD))
+ {
+ mp_size_t K2, nprime2, Nprime2, M2, maxLK, l, Mp2;
+ int k;
+ int **fft_l, *tmp;
+ mp_ptr *Ap, *Bp, A, B, T;
+
+ k = mpn_fft_best_k (n, sqr);
+ K2 = (mp_size_t) 1 << k;
+ ASSERT_ALWAYS((n & (K2 - 1)) == 0);
+ maxLK = (K2 > GMP_NUMB_BITS) ? K2 : GMP_NUMB_BITS;
+ M2 = n * GMP_NUMB_BITS >> k;
+ l = n >> k;
+ Nprime2 = ((2 * M2 + k + 2 + maxLK) / maxLK) * maxLK;
+ /* Nprime2 = ceil((2*M2+k+3)/maxLK)*maxLK*/
+ nprime2 = Nprime2 / GMP_NUMB_BITS;
+
+ /* we should ensure that nprime2 is a multiple of the next K */
+ if (nprime2 >= (sqr ? SQR_FFT_MODF_THRESHOLD : MUL_FFT_MODF_THRESHOLD))
+ {
+ mp_size_t K3;
+ for (;;)
+ {
+ K3 = (mp_size_t) 1 << mpn_fft_best_k (nprime2, sqr);
+ if ((nprime2 & (K3 - 1)) == 0)
+ break;
+ nprime2 = (nprime2 + K3 - 1) & -K3;
+ Nprime2 = nprime2 * GMP_LIMB_BITS;
+ /* warning: since nprime2 changed, K3 may change too! */
+ }
+ }
+ ASSERT_ALWAYS(nprime2 < n); /* otherwise we'll loop */
+
+ Mp2 = Nprime2 >> k;
+
+ Ap = TMP_BALLOC_MP_PTRS (K2);
+ Bp = TMP_BALLOC_MP_PTRS (K2);
+ A = TMP_BALLOC_LIMBS (2 * (nprime2 + 1) << k);
+ T = TMP_BALLOC_LIMBS (2 * (nprime2 + 1));
+ B = A + ((nprime2 + 1) << k);
+ fft_l = TMP_BALLOC_TYPE (k + 1, int *);
+ tmp = TMP_BALLOC_TYPE ((size_t) 2 << k, int);
+ for (i = 0; i <= k; i++)
+ {
+ fft_l[i] = tmp;
+ tmp += (mp_size_t) 1 << i;
+ }
+
+ mpn_fft_initl (fft_l, k);
+
+ TRACE (printf ("recurse: %ldx%ld limbs -> %ld times %ldx%ld (%1.2f)\n", n,
+ n, K2, nprime2, nprime2, 2.0*(double)n/nprime2/K2));
+ for (i = 0; i < K; i++, ap++, bp++)
+ {
+ mp_limb_t cy;
+ mpn_fft_normalize (*ap, n);
+ if (!sqr)
+ mpn_fft_normalize (*bp, n);
+
+ mpn_mul_fft_decompose (A, Ap, K2, nprime2, *ap, (l << k) + 1, l, Mp2, T);
+ if (!sqr)
+ mpn_mul_fft_decompose (B, Bp, K2, nprime2, *bp, (l << k) + 1, l, Mp2, T);
+
+ cy = mpn_mul_fft_internal (*ap, n, k, Ap, Bp, A, B, nprime2,
+ l, Mp2, fft_l, T, sqr);
+ (*ap)[n] = cy;
+ }
+ }
+ else
+ {
+ mp_ptr a, b, tp, tpn;
+ mp_limb_t cc;
+ mp_size_t n2 = 2 * n;
+ tp = TMP_BALLOC_LIMBS (n2);
+ tpn = tp + n;
+ TRACE (printf (" mpn_mul_n %ld of %ld limbs\n", K, n));
+ for (i = 0; i < K; i++)
+ {
+ a = *ap++;
+ b = *bp++;
+ if (sqr)
+ mpn_sqr (tp, a, n);
+ else
+ mpn_mul_n (tp, b, a, n);
+ if (a[n] != 0)
+ cc = mpn_add_n (tpn, tpn, b, n);
+ else
+ cc = 0;
+ if (b[n] != 0)
+ cc += mpn_add_n (tpn, tpn, a, n) + a[n];
+ if (cc != 0)
+ {
+ /* FIXME: use MPN_INCR_U here, since carry is not expected. */
+ cc = mpn_add_1 (tp, tp, n2, cc);
+ ASSERT (cc == 0);
+ }
+ a[n] = mpn_sub_n (a, tp, tpn, n) && mpn_add_1 (a, a, n, CNST_LIMB(1));
+ }
+ }
+ TMP_FREE;
+}
+
+
+/* input: A^[l[k][0]] A^[l[k][1]] ... A^[l[k][K-1]]
+ output: K*A[0] K*A[K-1] ... K*A[1].
+ Assumes the Ap[] are pseudo-normalized, i.e. 0 <= Ap[][n] <= 1.
+ This condition is also fulfilled at exit.
+*/
+static void
+mpn_fft_fftinv (mp_ptr *Ap, mp_size_t K, mp_size_t omega, mp_size_t n, mp_ptr tp)
+{
+ if (K == 2)
+ {
+ mp_limb_t cy;
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ cy = mpn_add_n_sub_n (Ap[0], Ap[1], Ap[0], Ap[1], n + 1) & 1;
+#else
+ MPN_COPY (tp, Ap[0], n + 1);
+ mpn_add_n (Ap[0], Ap[0], Ap[1], n + 1);
+ cy = mpn_sub_n (Ap[1], tp, Ap[1], n + 1);
+#endif
+ if (Ap[0][n] > 1) /* can be 2 or 3 */
+ Ap[0][n] = 1 - mpn_sub_1 (Ap[0], Ap[0], n, Ap[0][n] - 1);
+ if (cy) /* Ap[1][n] can be -1 or -2 */
+ Ap[1][n] = mpn_add_1 (Ap[1], Ap[1], n, ~Ap[1][n] + 1);
+ }
+ else
+ {
+ mp_size_t j, K2 = K >> 1;
+
+ mpn_fft_fftinv (Ap, K2, 2 * omega, n, tp);
+ mpn_fft_fftinv (Ap + K2, K2, 2 * omega, n, tp);
+ /* A[j] <- A[j] + omega^j A[j+K/2]
+ A[j+K/2] <- A[j] + omega^(j+K/2) A[j+K/2] */
+ for (j = 0; j < K2; j++, Ap++)
+ {
+ /* Ap[K2] <- Ap[0] + Ap[K2] * 2^((j + K2) * omega)
+ Ap[0] <- Ap[0] + Ap[K2] * 2^(j * omega) */
+ mpn_fft_mul_2exp_modF (tp, Ap[K2], j * omega, n);
+ mpn_fft_sub_modF (Ap[K2], Ap[0], tp, n);
+ mpn_fft_add_modF (Ap[0], Ap[0], tp, n);
+ }
+ }
+}
+
+
+/* R <- A/2^k mod 2^(n*GMP_NUMB_BITS)+1 */
+static void
+mpn_fft_div_2exp_modF (mp_ptr r, mp_srcptr a, mp_bitcnt_t k, mp_size_t n)
+{
+ mp_bitcnt_t i;
+
+ ASSERT (r != a);
+ i = (mp_bitcnt_t) 2 * n * GMP_NUMB_BITS - k;
+ mpn_fft_mul_2exp_modF (r, a, i, n);
+ /* 1/2^k = 2^(2nL-k) mod 2^(n*GMP_NUMB_BITS)+1 */
+ /* normalize so that R < 2^(n*GMP_NUMB_BITS)+1 */
+ mpn_fft_normalize (r, n);
+}
+
+
+/* {rp,n} <- {ap,an} mod 2^(n*GMP_NUMB_BITS)+1, n <= an <= 3*n.
+ Returns carry out, i.e. 1 iff {ap,an} = -1 mod 2^(n*GMP_NUMB_BITS)+1,
+ then {rp,n}=0.
+*/
+static mp_size_t
+mpn_fft_norm_modF (mp_ptr rp, mp_size_t n, mp_ptr ap, mp_size_t an)
+{
+ mp_size_t l, m, rpn;
+ mp_limb_t cc;
+
+ ASSERT ((n <= an) && (an <= 3 * n));
+ m = an - 2 * n;
+ if (m > 0)
+ {
+ l = n;
+ /* add {ap, m} and {ap+2n, m} in {rp, m} */
+ cc = mpn_add_n (rp, ap, ap + 2 * n, m);
+ /* copy {ap+m, n-m} to {rp+m, n-m} */
+ rpn = mpn_add_1 (rp + m, ap + m, n - m, cc);
+ }
+ else
+ {
+ l = an - n; /* l <= n */
+ MPN_COPY (rp, ap, n);
+ rpn = 0;
+ }
+
+ /* remains to subtract {ap+n, l} from {rp, n+1} */
+ cc = mpn_sub_n (rp, rp, ap + n, l);
+ rpn -= mpn_sub_1 (rp + l, rp + l, n - l, cc);
+ if (rpn < 0) /* necessarily rpn = -1 */
+ rpn = mpn_add_1 (rp, rp, n, CNST_LIMB(1));
+ return rpn;
+}
+
+/* store in A[0..nprime] the first M bits from {n, nl},
+ in A[nprime+1..] the following M bits, ...
+ Assumes M is a multiple of GMP_NUMB_BITS (M = l * GMP_NUMB_BITS).
+ T must have space for at least (nprime + 1) limbs.
+ We must have nl <= 2*K*l.
+*/
+static void
+mpn_mul_fft_decompose (mp_ptr A, mp_ptr *Ap, mp_size_t K, mp_size_t nprime,
+ mp_srcptr n, mp_size_t nl, mp_size_t l, mp_size_t Mp,
+ mp_ptr T)
+{
+ mp_size_t i, j;
+ mp_ptr tmp;
+ mp_size_t Kl = K * l;
+ TMP_DECL;
+ TMP_MARK;
+
+ if (nl > Kl) /* normalize {n, nl} mod 2^(Kl*GMP_NUMB_BITS)+1 */
+ {
+ mp_size_t dif = nl - Kl;
+ mp_limb_signed_t cy;
+
+ tmp = TMP_BALLOC_LIMBS(Kl + 1);
+
+ if (dif > Kl)
+ {
+ int subp = 0;
+
+ cy = mpn_sub_n (tmp, n, n + Kl, Kl);
+ n += 2 * Kl;
+ dif -= Kl;
+
+ /* now dif > 0 */
+ while (dif > Kl)
+ {
+ if (subp)
+ cy += mpn_sub_n (tmp, tmp, n, Kl);
+ else
+ cy -= mpn_add_n (tmp, tmp, n, Kl);
+ subp ^= 1;
+ n += Kl;
+ dif -= Kl;
+ }
+ /* now dif <= Kl */
+ if (subp)
+ cy += mpn_sub (tmp, tmp, Kl, n, dif);
+ else
+ cy -= mpn_add (tmp, tmp, Kl, n, dif);
+ if (cy >= 0)
+ cy = mpn_add_1 (tmp, tmp, Kl, cy);
+ else
+ cy = mpn_sub_1 (tmp, tmp, Kl, -cy);
+ }
+ else /* dif <= Kl, i.e. nl <= 2 * Kl */
+ {
+ cy = mpn_sub (tmp, n, Kl, n + Kl, dif);
+ cy = mpn_add_1 (tmp, tmp, Kl, cy);
+ }
+ tmp[Kl] = cy;
+ nl = Kl + 1;
+ n = tmp;
+ }
+ for (i = 0; i < K; i++)
+ {
+ Ap[i] = A;
+ /* store the next M bits of n into A[0..nprime] */
+ if (nl > 0) /* nl is the number of remaining limbs */
+ {
+ j = (l <= nl && i < K - 1) ? l : nl; /* store j next limbs */
+ nl -= j;
+ MPN_COPY (T, n, j);
+ MPN_ZERO (T + j, nprime + 1 - j);
+ n += l;
+ mpn_fft_mul_2exp_modF (A, T, i * Mp, nprime);
+ }
+ else
+ MPN_ZERO (A, nprime + 1);
+ A += nprime + 1;
+ }
+ ASSERT_ALWAYS (nl == 0);
+ TMP_FREE;
+}
+
+/* op <- n*m mod 2^N+1 with fft of size 2^k where N=pl*GMP_NUMB_BITS
+ op is pl limbs, its high bit is returned.
+ One must have pl = mpn_fft_next_size (pl, k).
+ T must have space for 2 * (nprime + 1) limbs.
+*/
+
+static mp_limb_t
+mpn_mul_fft_internal (mp_ptr op, mp_size_t pl, int k,
+ mp_ptr *Ap, mp_ptr *Bp, mp_ptr A, mp_ptr B,
+ mp_size_t nprime, mp_size_t l, mp_size_t Mp,
+ int **fft_l, mp_ptr T, int sqr)
+{
+ mp_size_t K, i, pla, lo, sh, j;
+ mp_ptr p;
+ mp_limb_t cc;
+
+ K = (mp_size_t) 1 << k;
+
+ /* direct fft's */
+ mpn_fft_fft (Ap, K, fft_l + k, 2 * Mp, nprime, 1, T);
+ if (!sqr)
+ mpn_fft_fft (Bp, K, fft_l + k, 2 * Mp, nprime, 1, T);
+
+ /* term to term multiplications */
+ mpn_fft_mul_modF_K (Ap, sqr ? Ap : Bp, nprime, K);
+
+ /* inverse fft's */
+ mpn_fft_fftinv (Ap, K, 2 * Mp, nprime, T);
+
+ /* division of terms after inverse fft */
+ Bp[0] = T + nprime + 1;
+ mpn_fft_div_2exp_modF (Bp[0], Ap[0], k, nprime);
+ for (i = 1; i < K; i++)
+ {
+ Bp[i] = Ap[i - 1];
+ mpn_fft_div_2exp_modF (Bp[i], Ap[i], k + (K - i) * Mp, nprime);
+ }
+
+ /* addition of terms in result p */
+ MPN_ZERO (T, nprime + 1);
+ pla = l * (K - 1) + nprime + 1; /* number of required limbs for p */
+ p = B; /* B has K*(n' + 1) limbs, which is >= pla, i.e. enough */
+ MPN_ZERO (p, pla);
+ cc = 0; /* will accumulate the (signed) carry at p[pla] */
+ for (i = K - 1, lo = l * i + nprime,sh = l * i; i >= 0; i--,lo -= l,sh -= l)
+ {
+ mp_ptr n = p + sh;
+
+ j = (K - i) & (K - 1);
+
+ if (mpn_add_n (n, n, Bp[j], nprime + 1))
+ cc += mpn_add_1 (n + nprime + 1, n + nprime + 1,
+ pla - sh - nprime - 1, CNST_LIMB(1));
+ T[2 * l] = i + 1; /* T = (i + 1)*2^(2*M) */
+ if (mpn_cmp (Bp[j], T, nprime + 1) > 0)
+ { /* subtract 2^N'+1 */
+ cc -= mpn_sub_1 (n, n, pla - sh, CNST_LIMB(1));
+ cc -= mpn_sub_1 (p + lo, p + lo, pla - lo, CNST_LIMB(1));
+ }
+ }
+ if (cc == -CNST_LIMB(1))
+ {
+ if ((cc = mpn_add_1 (p + pla - pl, p + pla - pl, pl, CNST_LIMB(1))))
+ {
+ /* p[pla-pl]...p[pla-1] are all zero */
+ mpn_sub_1 (p + pla - pl - 1, p + pla - pl - 1, pl + 1, CNST_LIMB(1));
+ mpn_sub_1 (p + pla - 1, p + pla - 1, 1, CNST_LIMB(1));
+ }
+ }
+ else if (cc == 1)
+ {
+ if (pla >= 2 * pl)
+ {
+ while ((cc = mpn_add_1 (p + pla - 2 * pl, p + pla - 2 * pl, 2 * pl, cc)))
+ ;
+ }
+ else
+ {
+ cc = mpn_sub_1 (p + pla - pl, p + pla - pl, pl, cc);
+ ASSERT (cc == 0);
+ }
+ }
+ else
+ ASSERT (cc == 0);
+
+ /* here p < 2^(2M) [K 2^(M(K-1)) + (K-1) 2^(M(K-2)) + ... ]
+ < K 2^(2M) [2^(M(K-1)) + 2^(M(K-2)) + ... ]
+ < K 2^(2M) 2^(M(K-1))*2 = 2^(M*K+M+k+1) */
+ return mpn_fft_norm_modF (op, pl, p, pla);
+}
+
+/* return the lcm of a and 2^k */
+static mp_bitcnt_t
+mpn_mul_fft_lcm (mp_bitcnt_t a, int k)
+{
+ mp_bitcnt_t l = k;
+
+ while (a % 2 == 0 && k > 0)
+ {
+ a >>= 1;
+ k --;
+ }
+ return a << l;
+}
+
+
+mp_limb_t
+mpn_mul_fft (mp_ptr op, mp_size_t pl,
+ mp_srcptr n, mp_size_t nl,
+ mp_srcptr m, mp_size_t ml,
+ int k)
+{
+ int i;
+ mp_size_t K, maxLK;
+ mp_size_t N, Nprime, nprime, M, Mp, l;
+ mp_ptr *Ap, *Bp, A, T, B;
+ int **fft_l, *tmp;
+ int sqr = (n == m && nl == ml);
+ mp_limb_t h;
+ TMP_DECL;
+
+ TRACE (printf ("\nmpn_mul_fft pl=%ld nl=%ld ml=%ld k=%d\n", pl, nl, ml, k));
+ ASSERT_ALWAYS (mpn_fft_next_size (pl, k) == pl);
+
+ TMP_MARK;
+ N = pl * GMP_NUMB_BITS;
+ fft_l = TMP_BALLOC_TYPE (k + 1, int *);
+ tmp = TMP_BALLOC_TYPE ((size_t) 2 << k, int);
+ for (i = 0; i <= k; i++)
+ {
+ fft_l[i] = tmp;
+ tmp += (mp_size_t) 1 << i;
+ }
+
+ mpn_fft_initl (fft_l, k);
+ K = (mp_size_t) 1 << k;
+ M = N >> k; /* N = 2^k M */
+ l = 1 + (M - 1) / GMP_NUMB_BITS;
+ maxLK = mpn_mul_fft_lcm (GMP_NUMB_BITS, k); /* lcm (GMP_NUMB_BITS, 2^k) */
+
+ Nprime = (1 + (2 * M + k + 2) / maxLK) * maxLK;
+ /* Nprime = ceil((2*M+k+3)/maxLK)*maxLK; */
+ nprime = Nprime / GMP_NUMB_BITS;
+ TRACE (printf ("N=%ld K=%ld, M=%ld, l=%ld, maxLK=%ld, Np=%ld, np=%ld\n",
+ N, K, M, l, maxLK, Nprime, nprime));
+ /* we should ensure that recursively, nprime is a multiple of the next K */
+ if (nprime >= (sqr ? SQR_FFT_MODF_THRESHOLD : MUL_FFT_MODF_THRESHOLD))
+ {
+ mp_size_t K2;
+ for (;;)
+ {
+ K2 = (mp_size_t) 1 << mpn_fft_best_k (nprime, sqr);
+ if ((nprime & (K2 - 1)) == 0)
+ break;
+ nprime = (nprime + K2 - 1) & -K2;
+ Nprime = nprime * GMP_LIMB_BITS;
+ /* warning: since nprime changed, K2 may change too! */
+ }
+ TRACE (printf ("new maxLK=%ld, Np=%ld, np=%ld\n", maxLK, Nprime, nprime));
+ }
+ ASSERT_ALWAYS (nprime < pl); /* otherwise we'll loop */
+
+ T = TMP_BALLOC_LIMBS (2 * (nprime + 1));
+ Mp = Nprime >> k;
+
+ TRACE (printf ("%ldx%ld limbs -> %ld times %ldx%ld limbs (%1.2f)\n",
+ pl, pl, K, nprime, nprime, 2.0 * (double) N / Nprime / K);
+ printf (" temp space %ld\n", 2 * K * (nprime + 1)));
+
+ A = TMP_BALLOC_LIMBS (K * (nprime + 1));
+ Ap = TMP_BALLOC_MP_PTRS (K);
+ mpn_mul_fft_decompose (A, Ap, K, nprime, n, nl, l, Mp, T);
+ if (sqr)
+ {
+ mp_size_t pla;
+ pla = l * (K - 1) + nprime + 1; /* number of required limbs for p */
+ B = TMP_BALLOC_LIMBS (pla);
+ Bp = TMP_BALLOC_MP_PTRS (K);
+ }
+ else
+ {
+ B = TMP_BALLOC_LIMBS (K * (nprime + 1));
+ Bp = TMP_BALLOC_MP_PTRS (K);
+ mpn_mul_fft_decompose (B, Bp, K, nprime, m, ml, l, Mp, T);
+ }
+ h = mpn_mul_fft_internal (op, pl, k, Ap, Bp, A, B, nprime, l, Mp, fft_l, T, sqr);
+
+ TMP_FREE;
+ return h;
+}
+
+#if WANT_OLD_FFT_FULL
+/* multiply {n, nl} by {m, ml}, and put the result in {op, nl+ml} */
+void
+mpn_mul_fft_full (mp_ptr op,
+ mp_srcptr n, mp_size_t nl,
+ mp_srcptr m, mp_size_t ml)
+{
+ mp_ptr pad_op;
+ mp_size_t pl, pl2, pl3, l;
+ mp_size_t cc, c2, oldcc;
+ int k2, k3;
+ int sqr = (n == m && nl == ml);
+
+ pl = nl + ml; /* total number of limbs of the result */
+
+ /* perform a fft mod 2^(2N)+1 and one mod 2^(3N)+1.
+ We must have pl3 = 3/2 * pl2, with pl2 a multiple of 2^k2, and
+ pl3 a multiple of 2^k3. Since k3 >= k2, both are multiples of 2^k2,
+ and pl2 must be an even multiple of 2^k2. Thus (pl2,pl3) =
+ (2*j*2^k2,3*j*2^k2), which works for 3*j <= pl/2^k2 <= 5*j.
+ We need that consecutive intervals overlap, i.e. 5*j >= 3*(j+1),
+ which requires j>=2. Thus this scheme requires pl >= 6 * 2^FFT_FIRST_K. */
+
+ /* ASSERT_ALWAYS(pl >= 6 * (1 << FFT_FIRST_K)); */
+
+ pl2 = (2 * pl - 1) / 5; /* ceil (2pl/5) - 1 */
+ do
+ {
+ pl2++;
+ k2 = mpn_fft_best_k (pl2, sqr); /* best fft size for pl2 limbs */
+ pl2 = mpn_fft_next_size (pl2, k2);
+ pl3 = 3 * pl2 / 2; /* since k>=FFT_FIRST_K=4, pl2 is a multiple of 2^4,
+ thus pl2 / 2 is exact */
+ k3 = mpn_fft_best_k (pl3, sqr);
+ }
+ while (mpn_fft_next_size (pl3, k3) != pl3);
+
+ TRACE (printf ("mpn_mul_fft_full nl=%ld ml=%ld -> pl2=%ld pl3=%ld k=%d\n",
+ nl, ml, pl2, pl3, k2));
+
+ ASSERT_ALWAYS(pl3 <= pl);
+ cc = mpn_mul_fft (op, pl3, n, nl, m, ml, k3); /* mu */
+ ASSERT(cc == 0);
+ pad_op = __GMP_ALLOCATE_FUNC_LIMBS (pl2);
+ cc = mpn_mul_fft (pad_op, pl2, n, nl, m, ml, k2); /* lambda */
+ cc = -cc + mpn_sub_n (pad_op, pad_op, op, pl2); /* lambda - low(mu) */
+ /* 0 <= cc <= 1 */
+ ASSERT(0 <= cc && cc <= 1);
+ l = pl3 - pl2; /* l = pl2 / 2 since pl3 = 3/2 * pl2 */
+ c2 = mpn_add_n (pad_op, pad_op, op + pl2, l);
+ cc = mpn_add_1 (pad_op + l, pad_op + l, l, (mp_limb_t) c2) - cc;
+ ASSERT(-1 <= cc && cc <= 1);
+ if (cc < 0)
+ cc = mpn_add_1 (pad_op, pad_op, pl2, (mp_limb_t) -cc);
+ ASSERT(0 <= cc && cc <= 1);
+ /* now lambda-mu = {pad_op, pl2} - cc mod 2^(pl2*GMP_NUMB_BITS)+1 */
+ oldcc = cc;
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ c2 = mpn_add_n_sub_n (pad_op + l, pad_op, pad_op, pad_op + l, l);
+ /* c2 & 1 is the borrow, c2 & 2 is the carry */
+ cc += c2 >> 1; /* carry out from high <- low + high */
+ c2 = c2 & 1; /* borrow out from low <- low - high */
+#else
+ {
+ mp_ptr tmp;
+ TMP_DECL;
+
+ TMP_MARK;
+ tmp = TMP_BALLOC_LIMBS (l);
+ MPN_COPY (tmp, pad_op, l);
+ c2 = mpn_sub_n (pad_op, pad_op, pad_op + l, l);
+ cc += mpn_add_n (pad_op + l, tmp, pad_op + l, l);
+ TMP_FREE;
+ }
+#endif
+ c2 += oldcc;
+ /* first normalize {pad_op, pl2} before dividing by 2: c2 is the borrow
+ at pad_op + l, cc is the carry at pad_op + pl2 */
+ /* 0 <= cc <= 2 */
+ cc -= mpn_sub_1 (pad_op + l, pad_op + l, l, (mp_limb_t) c2);
+ /* -1 <= cc <= 2 */
+ if (cc > 0)
+ cc = -mpn_sub_1 (pad_op, pad_op, pl2, (mp_limb_t) cc);
+ /* now -1 <= cc <= 0 */
+ if (cc < 0)
+ cc = mpn_add_1 (pad_op, pad_op, pl2, (mp_limb_t) -cc);
+ /* now {pad_op, pl2} is normalized, with 0 <= cc <= 1 */
+ if (pad_op[0] & 1) /* if odd, add 2^(pl2*GMP_NUMB_BITS)+1 */
+ cc += 1 + mpn_add_1 (pad_op, pad_op, pl2, CNST_LIMB(1));
+ /* now 0 <= cc <= 2, but cc=2 cannot occur since it would give a carry
+ out below */
+ mpn_rshift (pad_op, pad_op, pl2, 1); /* divide by two */
+ if (cc) /* then cc=1 */
+ pad_op [pl2 - 1] |= (mp_limb_t) 1 << (GMP_NUMB_BITS - 1);
+ /* now {pad_op,pl2}-cc = (lambda-mu)/(1-2^(l*GMP_NUMB_BITS))
+ mod 2^(pl2*GMP_NUMB_BITS) + 1 */
+ c2 = mpn_add_n (op, op, pad_op, pl2); /* no need to add cc (is 0) */
+ /* since pl2+pl3 >= pl, necessary the extra limbs (including cc) are zero */
+ MPN_COPY (op + pl3, pad_op, pl - pl3);
+ ASSERT_MPN_ZERO_P (pad_op + pl - pl3, pl2 + pl3 - pl);
+ __GMP_FREE_FUNC_LIMBS (pad_op, pl2);
+ /* since the final result has at most pl limbs, no carry out below */
+ mpn_add_1 (op + pl2, op + pl2, pl - pl2, (mp_limb_t) c2);
+}
+#endif
diff --git a/gmp/mpn/generic/mul_n.c b/gmp/mpn/generic/mul_n.c
new file mode 100644
index 0000000000..5df8b16fa0
--- /dev/null
+++ b/gmp/mpn/generic/mul_n.c
@@ -0,0 +1,97 @@
+/* mpn_mul_n -- multiply natural numbers.
+
+Copyright 1991, 1993, 1994, 1996-2003, 2005, 2008, 2009 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpn_mul_n (mp_ptr p, mp_srcptr a, mp_srcptr b, mp_size_t n)
+{
+ ASSERT (n >= 1);
+ ASSERT (! MPN_OVERLAP_P (p, 2 * n, a, n));
+ ASSERT (! MPN_OVERLAP_P (p, 2 * n, b, n));
+
+ if (BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD))
+ {
+ mpn_mul_basecase (p, a, n, b, n);
+ }
+ else if (BELOW_THRESHOLD (n, MUL_TOOM33_THRESHOLD))
+ {
+ /* Allocate workspace of fixed size on stack: fast! */
+ mp_limb_t ws[mpn_toom22_mul_itch (MUL_TOOM33_THRESHOLD_LIMIT-1,
+ MUL_TOOM33_THRESHOLD_LIMIT-1)];
+ ASSERT (MUL_TOOM33_THRESHOLD <= MUL_TOOM33_THRESHOLD_LIMIT);
+ mpn_toom22_mul (p, a, n, b, n, ws);
+ }
+ else if (BELOW_THRESHOLD (n, MUL_TOOM44_THRESHOLD))
+ {
+ mp_ptr ws;
+ TMP_SDECL;
+ TMP_SMARK;
+ ws = TMP_SALLOC_LIMBS (mpn_toom33_mul_itch (n, n));
+ mpn_toom33_mul (p, a, n, b, n, ws);
+ TMP_SFREE;
+ }
+ else if (BELOW_THRESHOLD (n, MUL_TOOM6H_THRESHOLD))
+ {
+ mp_ptr ws;
+ TMP_SDECL;
+ TMP_SMARK;
+ ws = TMP_SALLOC_LIMBS (mpn_toom44_mul_itch (n, n));
+ mpn_toom44_mul (p, a, n, b, n, ws);
+ TMP_SFREE;
+ }
+ else if (BELOW_THRESHOLD (n, MUL_TOOM8H_THRESHOLD))
+ {
+ mp_ptr ws;
+ TMP_SDECL;
+ TMP_SMARK;
+ ws = TMP_SALLOC_LIMBS (mpn_toom6_mul_n_itch (n));
+ mpn_toom6h_mul (p, a, n, b, n, ws);
+ TMP_SFREE;
+ }
+ else if (BELOW_THRESHOLD (n, MUL_FFT_THRESHOLD))
+ {
+ mp_ptr ws;
+ TMP_DECL;
+ TMP_MARK;
+ ws = TMP_ALLOC_LIMBS (mpn_toom8_mul_n_itch (n));
+ mpn_toom8h_mul (p, a, n, b, n, ws);
+ TMP_FREE;
+ }
+ else
+ {
+ /* The current FFT code allocates its own space. That should probably
+ change. */
+ mpn_fft_mul (p, a, n, b, n);
+ }
+}
diff --git a/gmp/mpn/generic/mullo_basecase.c b/gmp/mpn/generic/mullo_basecase.c
new file mode 100644
index 0000000000..2120f44c3d
--- /dev/null
+++ b/gmp/mpn/generic/mullo_basecase.c
@@ -0,0 +1,52 @@
+/* mpn_mullo_basecase -- Internal routine to multiply two natural
+ numbers of length m and n and return the low part.
+
+ THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES.
+
+
+Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*
+ FIXME: Should use mpn_addmul_2 (and higher).
+*/
+
+void
+mpn_mullo_basecase (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_size_t i;
+
+ mpn_mul_1 (rp, up, n, vp[0]);
+
+ for (i = 1; i < n; i++)
+ mpn_addmul_1 (rp + i, up, n - i, vp[i]);
+}
diff --git a/gmp/mpn/generic/mullo_n.c b/gmp/mpn/generic/mullo_n.c
new file mode 100644
index 0000000000..dad75ee8f7
--- /dev/null
+++ b/gmp/mpn/generic/mullo_n.c
@@ -0,0 +1,256 @@
+/* mpn_mullo_n -- multiply two n-limb numbers and return the low n limbs
+ of their products.
+
+ Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+ THIS IS (FOR NOW) AN INTERNAL FUNCTION. IT IS ONLY SAFE TO REACH THIS
+ FUNCTION THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST GUARANTEED
+ THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2004, 2005, 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#ifndef MULLO_BASECASE_THRESHOLD
+#define MULLO_BASECASE_THRESHOLD 0 /* never use mpn_mul_basecase */
+#endif
+
+#ifndef MULLO_DC_THRESHOLD
+#define MULLO_DC_THRESHOLD 3*MUL_TOOM22_THRESHOLD
+#endif
+
+#ifndef MULLO_MUL_N_THRESHOLD
+#define MULLO_MUL_N_THRESHOLD MUL_FFT_THRESHOLD
+#endif
+
+#if TUNE_PROGRAM_BUILD || WANT_FAT_BINARY
+#define MAYBE_range_basecase 1
+#define MAYBE_range_toom22 1
+#else
+#define MAYBE_range_basecase \
+ ((MULLO_DC_THRESHOLD == 0 ? MULLO_BASECASE_THRESHOLD : MULLO_DC_THRESHOLD) < MUL_TOOM22_THRESHOLD*36/(36-11))
+#define MAYBE_range_toom22 \
+ ((MULLO_DC_THRESHOLD == 0 ? MULLO_BASECASE_THRESHOLD : MULLO_DC_THRESHOLD) < MUL_TOOM33_THRESHOLD*36/(36-11) )
+#endif
+
+/* THINK: The DC strategy uses different constants in different Toom's
+ ranges. Something smoother?
+*/
+
+/*
+ Compute the least significant half of the product {xy,n}*{yp,n}, or
+ formally {rp,n} = {xy,n}*{yp,n} Mod (B^n).
+
+ Above the given threshold, the Divide and Conquer strategy is used.
+ The operands are split in two, and a full product plus two mullo
+ are used to obtain the final result. The more natural strategy is to
+ split in two halves, but this is far from optimal when a
+ sub-quadratic multiplication is used.
+
+ Mulders suggests an unbalanced split in favour of the full product,
+ split n = n1 + n2, where an = n1 <= n2 = (1-a)n; i.e. 0 < a <= 1/2.
+
+ To compute the value of a, we assume that the cost of mullo for a
+ given size ML(n) is a fraction of the cost of a full product with
+ same size M(n), and the cost M(n)=n^e for some exponent 1 < e <= 2;
+ then we can write:
+
+ ML(n) = 2*ML(an) + M((1-a)n) => k*M(n) = 2*k*M(n)*a^e + M(n)*(1-a)^e
+
+ Given a value for e, want to minimise the value of k, i.e. the
+ function k=(1-a)^e/(1-2*a^e).
+
+ With e=2, the exponent for schoolbook multiplication, the minimum is
+ given by the values a=1-a=1/2.
+
+ With e=log(3)/log(2), the exponent for Karatsuba (aka toom22),
+ Mulders compute (1-a) = 0.694... and we approximate a with 11/36.
+
+ Other possible approximations follow:
+ e=log(5)/log(3) [Toom-3] -> a ~= 9/40
+ e=log(7)/log(4) [Toom-4] -> a ~= 7/39
+ e=log(11)/log(6) [Toom-6] -> a ~= 1/8
+ e=log(15)/log(8) [Toom-8] -> a ~= 1/10
+
+ The values above where obtained with the following trivial commands
+ in the gp-pari shell:
+
+fun(e,a)=(1-a)^e/(1-2*a^e)
+mul(a,b,c)={local(m,x,p);if(b-c<1/10000,(b+c)/2,m=1;x=b;forstep(p=c,b,(b-c)/8,if(fun(a,p)<m,m=fun(a,p);x=p));mul(a,(b+x)/2,(c+x)/2))}
+contfracpnqn(contfrac(mul(log(2*2-1)/log(2),1/2,0),5))
+contfracpnqn(contfrac(mul(log(3*2-1)/log(3),1/2,0),5))
+contfracpnqn(contfrac(mul(log(4*2-1)/log(4),1/2,0),5))
+contfracpnqn(contfrac(mul(log(6*2-1)/log(6),1/2,0),3))
+contfracpnqn(contfrac(mul(log(8*2-1)/log(8),1/2,0),3))
+
+ ,
+ |\
+ | \
+ +----,
+ | |
+ | |
+ | |\
+ | | \
+ +----+--`
+ ^ n2 ^n1^
+
+ For an actual implementation, the assumption that M(n)=n^e is
+ incorrect, as a consequence also the assumption that ML(n)=k*M(n)
+ with a constant k is wrong.
+
+ But theory suggest us two things:
+ - the best the multiplication product is (lower e), the more k
+ approaches 1, and a approaches 0.
+
+ - A value for a smaller than optimal is probably less bad than a
+ bigger one: e.g. let e=log(3)/log(2), a=0.3058_ the optimal
+ value, and k(a)=0.808_ the mul/mullo speed ratio. We get
+ k(a+1/6)=0.929_ but k(a-1/6)=0.865_.
+*/
+
+static mp_size_t
+mpn_mullo_n_itch (mp_size_t n)
+{
+ return 2*n;
+}
+
+/*
+ mpn_dc_mullo_n requires a scratch space of 2*n limbs at tp.
+ It accepts tp == rp.
+*/
+static void
+mpn_dc_mullo_n (mp_ptr rp, mp_srcptr xp, mp_srcptr yp, mp_size_t n, mp_ptr tp)
+{
+ mp_size_t n2, n1;
+ ASSERT (n >= 2);
+ ASSERT (! MPN_OVERLAP_P (rp, n, xp, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp, n));
+ ASSERT (MPN_SAME_OR_SEPARATE2_P(rp, n, tp, 2*n));
+
+ /* Divide-and-conquer */
+
+ /* We need fractional approximation of the value 0 < a <= 1/2
+ giving the minimum in the function k=(1-a)^e/(1-2*a^e).
+ */
+ if (MAYBE_range_basecase && BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD*36/(36-11)))
+ n1 = n >> 1;
+ else if (MAYBE_range_toom22 && BELOW_THRESHOLD (n, MUL_TOOM33_THRESHOLD*36/(36-11)))
+ n1 = n * 11 / (size_t) 36; /* n1 ~= n*(1-.694...) */
+ else if (BELOW_THRESHOLD (n, MUL_TOOM44_THRESHOLD*40/(40-9)))
+ n1 = n * 9 / (size_t) 40; /* n1 ~= n*(1-.775...) */
+ else if (BELOW_THRESHOLD (n, MUL_TOOM8H_THRESHOLD*10/9))
+ n1 = n * 7 / (size_t) 39; /* n1 ~= n*(1-.821...) */
+ /* n1 = n * 4 / (size_t) 31; // n1 ~= n*(1-.871...) [TOOM66] */
+ else
+ n1 = n / (size_t) 10; /* n1 ~= n*(1-.899...) [TOOM88] */
+
+ n2 = n - n1;
+
+ /* Split as x = x1 2^(n2 GMP_NUMB_BITS) + x0,
+ y = y1 2^(n2 GMP_NUMB_BITS) + y0 */
+
+ /* x0 * y0 */
+ mpn_mul_n (tp, xp, yp, n2);
+ MPN_COPY (rp, tp, n2);
+
+ /* x1 * y0 * 2^(n2 GMP_NUMB_BITS) */
+ if (BELOW_THRESHOLD (n1, MULLO_BASECASE_THRESHOLD))
+ mpn_mul_basecase (tp + n, xp + n2, n1, yp, n1);
+ else if (BELOW_THRESHOLD (n1, MULLO_DC_THRESHOLD))
+ mpn_mullo_basecase (tp + n, xp + n2, yp, n1);
+ else
+ mpn_dc_mullo_n (tp + n, xp + n2, yp, n1, tp + n);
+ mpn_add_n (rp + n2, tp + n2, tp + n, n1);
+
+ /* x0 * y1 * 2^(n2 GMP_NUMB_BITS) */
+ if (BELOW_THRESHOLD (n1, MULLO_BASECASE_THRESHOLD))
+ mpn_mul_basecase (tp + n, xp, n1, yp + n2, n1);
+ else if (BELOW_THRESHOLD (n1, MULLO_DC_THRESHOLD))
+ mpn_mullo_basecase (tp + n, xp, yp + n2, n1);
+ else
+ mpn_dc_mullo_n (tp + n, xp, yp + n2, n1, tp + n);
+ mpn_add_n (rp + n2, rp + n2, tp + n, n1);
+}
+
+/* Avoid zero allocations when MULLO_BASECASE_THRESHOLD is 0. */
+#define MUL_BASECASE_ALLOC \
+ (MULLO_BASECASE_THRESHOLD_LIMIT == 0 ? 1 : 2*MULLO_BASECASE_THRESHOLD_LIMIT)
+
+/* FIXME: This function should accept a temporary area; dc_mullow_n
+ accepts a pointer tp, and handle the case tp == rp, do the same here.
+ Maybe recombine the two functions.
+ THINK: If mpn_mul_basecase is always faster than mpn_mullo_basecase
+ (typically thanks to mpn_addmul_2) should we unconditionally use
+ mpn_mul_n?
+*/
+
+void
+mpn_mullo_n (mp_ptr rp, mp_srcptr xp, mp_srcptr yp, mp_size_t n)
+{
+ ASSERT (n >= 1);
+ ASSERT (! MPN_OVERLAP_P (rp, n, xp, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp, n));
+
+ if (BELOW_THRESHOLD (n, MULLO_BASECASE_THRESHOLD))
+ {
+ /* Allocate workspace of fixed size on stack: fast! */
+ mp_limb_t tp[MUL_BASECASE_ALLOC];
+ mpn_mul_basecase (tp, xp, n, yp, n);
+ MPN_COPY (rp, tp, n);
+ }
+ else if (BELOW_THRESHOLD (n, MULLO_DC_THRESHOLD))
+ {
+ mpn_mullo_basecase (rp, xp, yp, n);
+ }
+ else
+ {
+ mp_ptr tp;
+ TMP_DECL;
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS (mpn_mullo_n_itch (n));
+ if (BELOW_THRESHOLD (n, MULLO_MUL_N_THRESHOLD))
+ {
+ mpn_dc_mullo_n (rp, xp, yp, n, tp);
+ }
+ else
+ {
+ /* For really large operands, use plain mpn_mul_n but throw away upper n
+ limbs of result. */
+#if !TUNE_PROGRAM_BUILD && (MULLO_MUL_N_THRESHOLD > MUL_FFT_THRESHOLD)
+ mpn_fft_mul (tp, xp, n, yp, n);
+#else
+ mpn_mul_n (tp, xp, yp, n);
+#endif
+ MPN_COPY (rp, tp, n);
+ }
+ TMP_FREE;
+ }
+}
diff --git a/gmp/mpn/generic/mulmid.c b/gmp/mpn/generic/mulmid.c
new file mode 100644
index 0000000000..6b4ea3253d
--- /dev/null
+++ b/gmp/mpn/generic/mulmid.c
@@ -0,0 +1,256 @@
+/* mpn_mulmid -- middle product
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#define CHUNK (200 + MULMID_TOOM42_THRESHOLD)
+
+
+void
+mpn_mulmid (mp_ptr rp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn)
+{
+ mp_size_t rn, k;
+ mp_ptr scratch, temp;
+
+ ASSERT (an >= bn);
+ ASSERT (bn >= 1);
+ ASSERT (! MPN_OVERLAP_P (rp, an - bn + 3, ap, an));
+ ASSERT (! MPN_OVERLAP_P (rp, an - bn + 3, bp, bn));
+
+ if (bn < MULMID_TOOM42_THRESHOLD)
+ {
+ /* region not tall enough to make toom42 worthwhile for any portion */
+
+ if (an < CHUNK)
+ {
+ /* region not too wide either, just call basecase directly */
+ mpn_mulmid_basecase (rp, ap, an, bp, bn);
+ return;
+ }
+
+ /* Region quite wide. For better locality, use basecase on chunks:
+
+ AAABBBCC..
+ .AAABBBCC.
+ ..AAABBBCC
+ */
+
+ k = CHUNK - bn + 1; /* number of diagonals per chunk */
+
+ /* first chunk (marked A in the above diagram) */
+ mpn_mulmid_basecase (rp, ap, CHUNK, bp, bn);
+
+ /* remaining chunks (B, C, etc) */
+ an -= k;
+
+ while (an >= CHUNK)
+ {
+ mp_limb_t t0, t1, cy;
+ ap += k, rp += k;
+ t0 = rp[0], t1 = rp[1];
+ mpn_mulmid_basecase (rp, ap, CHUNK, bp, bn);
+ ADDC_LIMB (cy, rp[0], rp[0], t0); /* add back saved limbs */
+ MPN_INCR_U (rp + 1, k + 1, t1 + cy);
+ an -= k;
+ }
+
+ if (an >= bn)
+ {
+ /* last remaining chunk */
+ mp_limb_t t0, t1, cy;
+ ap += k, rp += k;
+ t0 = rp[0], t1 = rp[1];
+ mpn_mulmid_basecase (rp, ap, an, bp, bn);
+ ADDC_LIMB (cy, rp[0], rp[0], t0);
+ MPN_INCR_U (rp + 1, an - bn + 2, t1 + cy);
+ }
+
+ return;
+ }
+
+ /* region is tall enough for toom42 */
+
+ rn = an - bn + 1;
+
+ if (rn < MULMID_TOOM42_THRESHOLD)
+ {
+ /* region not wide enough to make toom42 worthwhile for any portion */
+
+ TMP_DECL;
+
+ if (bn < CHUNK)
+ {
+ /* region not too tall either, just call basecase directly */
+ mpn_mulmid_basecase (rp, ap, an, bp, bn);
+ return;
+ }
+
+ /* Region quite tall. For better locality, use basecase on chunks:
+
+ AAAAA....
+ .AAAAA...
+ ..BBBBB..
+ ...BBBBB.
+ ....CCCCC
+ */
+
+ TMP_MARK;
+
+ temp = TMP_ALLOC_LIMBS (rn + 2);
+
+ /* first chunk (marked A in the above diagram) */
+ bp += bn - CHUNK, an -= bn - CHUNK;
+ mpn_mulmid_basecase (rp, ap, an, bp, CHUNK);
+
+ /* remaining chunks (B, C, etc) */
+ bn -= CHUNK;
+
+ while (bn >= CHUNK)
+ {
+ ap += CHUNK, bp -= CHUNK;
+ mpn_mulmid_basecase (temp, ap, an, bp, CHUNK);
+ mpn_add_n (rp, rp, temp, rn + 2);
+ bn -= CHUNK;
+ }
+
+ if (bn)
+ {
+ /* last remaining chunk */
+ ap += CHUNK, bp -= bn;
+ mpn_mulmid_basecase (temp, ap, rn + bn - 1, bp, bn);
+ mpn_add_n (rp, rp, temp, rn + 2);
+ }
+
+ TMP_FREE;
+ return;
+ }
+
+ /* we're definitely going to use toom42 somewhere */
+
+ if (bn > rn)
+ {
+ /* slice region into chunks, use toom42 on all chunks except possibly
+ the last:
+
+ AA....
+ .AA...
+ ..BB..
+ ...BB.
+ ....CC
+ */
+
+ TMP_DECL;
+ TMP_MARK;
+
+ temp = TMP_ALLOC_LIMBS (rn + 2 + mpn_toom42_mulmid_itch (rn));
+ scratch = temp + rn + 2;
+
+ /* first chunk (marked A in the above diagram) */
+ bp += bn - rn;
+ mpn_toom42_mulmid (rp, ap, bp, rn, scratch);
+
+ /* remaining chunks (B, C, etc) */
+ bn -= rn;
+
+ while (bn >= rn)
+ {
+ ap += rn, bp -= rn;
+ mpn_toom42_mulmid (temp, ap, bp, rn, scratch);
+ mpn_add_n (rp, rp, temp, rn + 2);
+ bn -= rn;
+ }
+
+ if (bn)
+ {
+ /* last remaining chunk */
+ ap += rn, bp -= bn;
+ mpn_mulmid (temp, ap, rn + bn - 1, bp, bn);
+ mpn_add_n (rp, rp, temp, rn + 2);
+ }
+
+ TMP_FREE;
+ }
+ else
+ {
+ /* slice region into chunks, use toom42 on all chunks except possibly
+ the last:
+
+ AAABBBCC..
+ .AAABBBCC.
+ ..AAABBBCC
+ */
+
+ TMP_DECL;
+ TMP_MARK;
+
+ scratch = TMP_ALLOC_LIMBS (mpn_toom42_mulmid_itch (bn));
+
+ /* first chunk (marked A in the above diagram) */
+ mpn_toom42_mulmid (rp, ap, bp, bn, scratch);
+
+ /* remaining chunks (B, C, etc) */
+ rn -= bn;
+
+ while (rn >= bn)
+ {
+ mp_limb_t t0, t1, cy;
+ ap += bn, rp += bn;
+ t0 = rp[0], t1 = rp[1];
+ mpn_toom42_mulmid (rp, ap, bp, bn, scratch);
+ ADDC_LIMB (cy, rp[0], rp[0], t0); /* add back saved limbs */
+ MPN_INCR_U (rp + 1, bn + 1, t1 + cy);
+ rn -= bn;
+ }
+
+ TMP_FREE;
+
+ if (rn)
+ {
+ /* last remaining chunk */
+ mp_limb_t t0, t1, cy;
+ ap += bn, rp += bn;
+ t0 = rp[0], t1 = rp[1];
+ mpn_mulmid (rp, ap, rn + bn - 1, bp, bn);
+ ADDC_LIMB (cy, rp[0], rp[0], t0);
+ MPN_INCR_U (rp + 1, rn + 1, t1 + cy);
+ }
+ }
+}
diff --git a/gmp/mpn/generic/mulmid_basecase.c b/gmp/mpn/generic/mulmid_basecase.c
new file mode 100644
index 0000000000..400e976424
--- /dev/null
+++ b/gmp/mpn/generic/mulmid_basecase.c
@@ -0,0 +1,83 @@
+/* mpn_mulmid_basecase -- classical middle product algorithm
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Middle product of {up,un} and {vp,vn}, write result to {rp,un-vn+3}.
+ Must have un >= vn >= 1.
+
+ Neither input buffer may overlap with the output buffer. */
+
+void
+mpn_mulmid_basecase (mp_ptr rp,
+ mp_srcptr up, mp_size_t un,
+ mp_srcptr vp, mp_size_t vn)
+{
+ mp_limb_t lo, hi; /* last two limbs of output */
+ mp_limb_t cy;
+
+ ASSERT (un >= vn);
+ ASSERT (vn >= 1);
+ ASSERT (! MPN_OVERLAP_P (rp, un - vn + 3, up, un));
+ ASSERT (! MPN_OVERLAP_P (rp, un - vn + 3, vp, vn));
+
+ up += vn - 1;
+ un -= vn - 1;
+
+ /* multiply by first limb, store result */
+ lo = mpn_mul_1 (rp, up, un, vp[0]);
+ hi = 0;
+
+ /* accumulate remaining rows */
+ for (vn--; vn; vn--)
+ {
+ up--, vp++;
+ cy = mpn_addmul_1 (rp, up, un, vp[0]);
+ add_ssaaaa (hi, lo, hi, lo, CNST_LIMB(0), cy);
+ }
+
+ /* store final limbs */
+#if GMP_NAIL_BITS != 0
+ hi = (hi << GMP_NAIL_BITS) + (lo >> GMP_NUMB_BITS);
+ lo &= GMP_NUMB_MASK;
+#endif
+
+ rp[un] = lo;
+ rp[un + 1] = hi;
+}
diff --git a/gmp/mpn/generic/mulmid_n.c b/gmp/mpn/generic/mulmid_n.c
new file mode 100644
index 0000000000..2280ba3a36
--- /dev/null
+++ b/gmp/mpn/generic/mulmid_n.c
@@ -0,0 +1,62 @@
+/* mpn_mulmid_n -- balanced middle product
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpn_mulmid_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
+{
+ ASSERT (n >= 1);
+ ASSERT (! MPN_OVERLAP_P (rp, n + 2, ap, 2*n - 1));
+ ASSERT (! MPN_OVERLAP_P (rp, n + 2, bp, n));
+
+ if (n < MULMID_TOOM42_THRESHOLD)
+ {
+ mpn_mulmid_basecase (rp, ap, 2*n - 1, bp, n);
+ }
+ else
+ {
+ mp_ptr scratch;
+ TMP_DECL;
+ TMP_MARK;
+ scratch = TMP_ALLOC_LIMBS (mpn_toom42_mulmid_itch (n));
+ mpn_toom42_mulmid (rp, ap, bp, n, scratch);
+ TMP_FREE;
+ }
+}
diff --git a/gmp/mpn/generic/mulmod_bnm1.c b/gmp/mpn/generic/mulmod_bnm1.c
new file mode 100644
index 0000000000..8710324583
--- /dev/null
+++ b/gmp/mpn/generic/mulmod_bnm1.c
@@ -0,0 +1,355 @@
+/* mulmod_bnm1.c -- multiplication mod B^n-1.
+
+ Contributed to the GNU project by Niels Möller, Torbjorn Granlund and
+ Marco Bodrato.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2010, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Inputs are {ap,rn} and {bp,rn}; output is {rp,rn}, computation is
+ mod B^rn - 1, and values are semi-normalised; zero is represented
+ as either 0 or B^n - 1. Needs a scratch of 2rn limbs at tp.
+ tp==rp is allowed. */
+void
+mpn_bc_mulmod_bnm1 (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t rn,
+ mp_ptr tp)
+{
+ mp_limb_t cy;
+
+ ASSERT (0 < rn);
+
+ mpn_mul_n (tp, ap, bp, rn);
+ cy = mpn_add_n (rp, tp, tp + rn, rn);
+ /* If cy == 1, then the value of rp is at most B^rn - 2, so there can
+ * be no overflow when adding in the carry. */
+ MPN_INCR_U (rp, rn, cy);
+}
+
+
+/* Inputs are {ap,rn+1} and {bp,rn+1}; output is {rp,rn+1}, in
+ semi-normalised representation, computation is mod B^rn + 1. Needs
+ a scratch area of 2rn + 2 limbs at tp; tp == rp is allowed.
+ Output is normalised. */
+static void
+mpn_bc_mulmod_bnp1 (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t rn,
+ mp_ptr tp)
+{
+ mp_limb_t cy;
+
+ ASSERT (0 < rn);
+
+ mpn_mul_n (tp, ap, bp, rn + 1);
+ ASSERT (tp[2*rn+1] == 0);
+ ASSERT (tp[2*rn] < GMP_NUMB_MAX);
+ cy = tp[2*rn] + mpn_sub_n (rp, tp, tp+rn, rn);
+ rp[rn] = 0;
+ MPN_INCR_U (rp, rn+1, cy );
+}
+
+
+/* Computes {rp,MIN(rn,an+bn)} <- {ap,an}*{bp,bn} Mod(B^rn-1)
+ *
+ * The result is expected to be ZERO if and only if one of the operand
+ * already is. Otherwise the class [0] Mod(B^rn-1) is represented by
+ * B^rn-1. This should not be a problem if mulmod_bnm1 is used to
+ * combine results and obtain a natural number when one knows in
+ * advance that the final value is less than (B^rn-1).
+ * Moreover it should not be a problem if mulmod_bnm1 is used to
+ * compute the full product with an+bn <= rn, because this condition
+ * implies (B^an-1)(B^bn-1) < (B^rn-1) .
+ *
+ * Requires 0 < bn <= an <= rn and an + bn > rn/2
+ * Scratch need: rn + (need for recursive call OR rn + 4). This gives
+ *
+ * S(n) <= rn + MAX (rn + 4, S(n/2)) <= 2rn + 4
+ */
+void
+mpn_mulmod_bnm1 (mp_ptr rp, mp_size_t rn, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn, mp_ptr tp)
+{
+ ASSERT (0 < bn);
+ ASSERT (bn <= an);
+ ASSERT (an <= rn);
+
+ if ((rn & 1) != 0 || BELOW_THRESHOLD (rn, MULMOD_BNM1_THRESHOLD))
+ {
+ if (UNLIKELY (bn < rn))
+ {
+ if (UNLIKELY (an + bn <= rn))
+ {
+ mpn_mul (rp, ap, an, bp, bn);
+ }
+ else
+ {
+ mp_limb_t cy;
+ mpn_mul (tp, ap, an, bp, bn);
+ cy = mpn_add (rp, tp, rn, tp + rn, an + bn - rn);
+ MPN_INCR_U (rp, rn, cy);
+ }
+ }
+ else
+ mpn_bc_mulmod_bnm1 (rp, ap, bp, rn, tp);
+ }
+ else
+ {
+ mp_size_t n;
+ mp_limb_t cy;
+ mp_limb_t hi;
+
+ n = rn >> 1;
+
+ /* We need at least an + bn >= n, to be able to fit one of the
+ recursive products at rp. Requiring strict inequality makes
+ the coded slightly simpler. If desired, we could avoid this
+ restriction by initially halving rn as long as rn is even and
+ an + bn <= rn/2. */
+
+ ASSERT (an + bn > n);
+
+ /* Compute xm = a*b mod (B^n - 1), xp = a*b mod (B^n + 1)
+ and crt together as
+
+ x = -xp * B^n + (B^n + 1) * [ (xp + xm)/2 mod (B^n-1)]
+ */
+
+#define a0 ap
+#define a1 (ap + n)
+#define b0 bp
+#define b1 (bp + n)
+
+#define xp tp /* 2n + 2 */
+ /* am1 maybe in {xp, n} */
+ /* bm1 maybe in {xp + n, n} */
+#define sp1 (tp + 2*n + 2)
+ /* ap1 maybe in {sp1, n + 1} */
+ /* bp1 maybe in {sp1 + n + 1, n + 1} */
+
+ {
+ mp_srcptr am1, bm1;
+ mp_size_t anm, bnm;
+ mp_ptr so;
+
+ bm1 = b0;
+ bnm = bn;
+ if (LIKELY (an > n))
+ {
+ am1 = xp;
+ cy = mpn_add (xp, a0, n, a1, an - n);
+ MPN_INCR_U (xp, n, cy);
+ anm = n;
+ so = xp + n;
+ if (LIKELY (bn > n))
+ {
+ bm1 = so;
+ cy = mpn_add (so, b0, n, b1, bn - n);
+ MPN_INCR_U (so, n, cy);
+ bnm = n;
+ so += n;
+ }
+ }
+ else
+ {
+ so = xp;
+ am1 = a0;
+ anm = an;
+ }
+
+ mpn_mulmod_bnm1 (rp, n, am1, anm, bm1, bnm, so);
+ }
+
+ {
+ int k;
+ mp_srcptr ap1, bp1;
+ mp_size_t anp, bnp;
+
+ bp1 = b0;
+ bnp = bn;
+ if (LIKELY (an > n)) {
+ ap1 = sp1;
+ cy = mpn_sub (sp1, a0, n, a1, an - n);
+ sp1[n] = 0;
+ MPN_INCR_U (sp1, n + 1, cy);
+ anp = n + ap1[n];
+ if (LIKELY (bn > n)) {
+ bp1 = sp1 + n + 1;
+ cy = mpn_sub (sp1 + n + 1, b0, n, b1, bn - n);
+ sp1[2*n+1] = 0;
+ MPN_INCR_U (sp1 + n + 1, n + 1, cy);
+ bnp = n + bp1[n];
+ }
+ } else {
+ ap1 = a0;
+ anp = an;
+ }
+
+ if (BELOW_THRESHOLD (n, MUL_FFT_MODF_THRESHOLD))
+ k=0;
+ else
+ {
+ int mask;
+ k = mpn_fft_best_k (n, 0);
+ mask = (1<<k) - 1;
+ while (n & mask) {k--; mask >>=1;};
+ }
+ if (k >= FFT_FIRST_K)
+ xp[n] = mpn_mul_fft (xp, n, ap1, anp, bp1, bnp, k);
+ else if (UNLIKELY (bp1 == b0))
+ {
+ ASSERT (anp + bnp <= 2*n+1);
+ ASSERT (anp + bnp > n);
+ ASSERT (anp >= bnp);
+ mpn_mul (xp, ap1, anp, bp1, bnp);
+ anp = anp + bnp - n;
+ ASSERT (anp <= n || xp[2*n]==0);
+ anp-= anp > n;
+ cy = mpn_sub (xp, xp, n, xp + n, anp);
+ xp[n] = 0;
+ MPN_INCR_U (xp, n+1, cy);
+ }
+ else
+ mpn_bc_mulmod_bnp1 (xp, ap1, bp1, n, xp);
+ }
+
+ /* Here the CRT recomposition begins.
+
+ xm <- (xp + xm)/2 = (xp + xm)B^n/2 mod (B^n-1)
+ Division by 2 is a bitwise rotation.
+
+ Assumes xp normalised mod (B^n+1).
+
+ The residue class [0] is represented by [B^n-1]; except when
+ both input are ZERO.
+ */
+
+#if HAVE_NATIVE_mpn_rsh1add_n || HAVE_NATIVE_mpn_rsh1add_nc
+#if HAVE_NATIVE_mpn_rsh1add_nc
+ cy = mpn_rsh1add_nc(rp, rp, xp, n, xp[n]); /* B^n = 1 */
+ hi = cy << (GMP_NUMB_BITS - 1);
+ cy = 0;
+ /* next update of rp[n-1] will set cy = 1 only if rp[n-1]+=hi
+ overflows, i.e. a further increment will not overflow again. */
+#else /* ! _nc */
+ cy = xp[n] + mpn_rsh1add_n(rp, rp, xp, n); /* B^n = 1 */
+ hi = (cy<<(GMP_NUMB_BITS-1))&GMP_NUMB_MASK; /* (cy&1) << ... */
+ cy >>= 1;
+ /* cy = 1 only if xp[n] = 1 i.e. {xp,n} = ZERO, this implies that
+ the rsh1add was a simple rshift: the top bit is 0. cy=1 => hi=0. */
+#endif
+#if GMP_NAIL_BITS == 0
+ add_ssaaaa(cy, rp[n-1], cy, rp[n-1], 0, hi);
+#else
+ cy += (hi & rp[n-1]) >> (GMP_NUMB_BITS-1);
+ rp[n-1] ^= hi;
+#endif
+#else /* ! HAVE_NATIVE_mpn_rsh1add_n */
+#if HAVE_NATIVE_mpn_add_nc
+ cy = mpn_add_nc(rp, rp, xp, n, xp[n]);
+#else /* ! _nc */
+ cy = xp[n] + mpn_add_n(rp, rp, xp, n); /* xp[n] == 1 implies {xp,n} == ZERO */
+#endif
+ cy += (rp[0]&1);
+ mpn_rshift(rp, rp, n, 1);
+ ASSERT (cy <= 2);
+ hi = (cy<<(GMP_NUMB_BITS-1))&GMP_NUMB_MASK; /* (cy&1) << ... */
+ cy >>= 1;
+ /* We can have cy != 0 only if hi = 0... */
+ ASSERT ((rp[n-1] & GMP_NUMB_HIGHBIT) == 0);
+ rp[n-1] |= hi;
+ /* ... rp[n-1] + cy can not overflow, the following INCR is correct. */
+#endif
+ ASSERT (cy <= 1);
+ /* Next increment can not overflow, read the previous comments about cy. */
+ ASSERT ((cy == 0) || ((rp[n-1] & GMP_NUMB_HIGHBIT) == 0));
+ MPN_INCR_U(rp, n, cy);
+
+ /* Compute the highest half:
+ ([(xp + xm)/2 mod (B^n-1)] - xp ) * B^n
+ */
+ if (UNLIKELY (an + bn < rn))
+ {
+ /* Note that in this case, the only way the result can equal
+ zero mod B^{rn} - 1 is if one of the inputs is zero, and
+ then the output of both the recursive calls and this CRT
+ reconstruction is zero, not B^{rn} - 1. Which is good,
+ since the latter representation doesn't fit in the output
+ area.*/
+ cy = mpn_sub_n (rp + n, rp, xp, an + bn - n);
+
+ /* FIXME: This subtraction of the high parts is not really
+ necessary, we do it to get the carry out, and for sanity
+ checking. */
+ cy = xp[n] + mpn_sub_nc (xp + an + bn - n, rp + an + bn - n,
+ xp + an + bn - n, rn - (an + bn), cy);
+ ASSERT (an + bn == rn - 1 ||
+ mpn_zero_p (xp + an + bn - n + 1, rn - 1 - (an + bn)));
+ cy = mpn_sub_1 (rp, rp, an + bn, cy);
+ ASSERT (cy == (xp + an + bn - n)[0]);
+ }
+ else
+ {
+ cy = xp[n] + mpn_sub_n (rp + n, rp, xp, n);
+ /* cy = 1 only if {xp,n+1} is not ZERO, i.e. {rp,n} is not ZERO.
+ DECR will affect _at most_ the lowest n limbs. */
+ MPN_DECR_U (rp, 2*n, cy);
+ }
+#undef a0
+#undef a1
+#undef b0
+#undef b1
+#undef xp
+#undef sp1
+ }
+}
+
+mp_size_t
+mpn_mulmod_bnm1_next_size (mp_size_t n)
+{
+ mp_size_t nh;
+
+ if (BELOW_THRESHOLD (n, MULMOD_BNM1_THRESHOLD))
+ return n;
+ if (BELOW_THRESHOLD (n, 4 * (MULMOD_BNM1_THRESHOLD - 1) + 1))
+ return (n + (2-1)) & (-2);
+ if (BELOW_THRESHOLD (n, 8 * (MULMOD_BNM1_THRESHOLD - 1) + 1))
+ return (n + (4-1)) & (-4);
+
+ nh = (n + 1) >> 1;
+
+ if (BELOW_THRESHOLD (nh, MUL_FFT_MODF_THRESHOLD))
+ return (n + (8-1)) & (-8);
+
+ return 2 * mpn_fft_next_size (nh, mpn_fft_best_k (nh, 0));
+}
diff --git a/gmp/mpn/generic/neg.c b/gmp/mpn/generic/neg.c
new file mode 100644
index 0000000000..2d752e912d
--- /dev/null
+++ b/gmp/mpn/generic/neg.c
@@ -0,0 +1,34 @@
+/* mpn_neg - negate an mpn.
+
+Copyright 2001, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpn_neg 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpn/generic/nussbaumer_mul.c b/gmp/mpn/generic/nussbaumer_mul.c
new file mode 100644
index 0000000000..d2bf19ad56
--- /dev/null
+++ b/gmp/mpn/generic/nussbaumer_mul.c
@@ -0,0 +1,71 @@
+/* mpn_nussbaumer_mul -- Multiply {ap,an} and {bp,bn} using
+ Nussbaumer's negacyclic convolution.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Multiply {ap,an} by {bp,bn}, and put the result in {pp, an+bn} */
+void
+mpn_nussbaumer_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn)
+{
+ mp_size_t rn;
+ mp_ptr tp;
+ TMP_DECL;
+
+ ASSERT (an >= bn);
+ ASSERT (bn > 0);
+
+ TMP_MARK;
+
+ if ((ap == bp) && (an == bn))
+ {
+ rn = mpn_sqrmod_bnm1_next_size (2*an);
+ tp = TMP_ALLOC_LIMBS (mpn_sqrmod_bnm1_itch (rn, an));
+ mpn_sqrmod_bnm1 (pp, rn, ap, an, tp);
+ }
+ else
+ {
+ rn = mpn_mulmod_bnm1_next_size (an + bn);
+ tp = TMP_ALLOC_LIMBS (mpn_mulmod_bnm1_itch (rn, an, bn));
+ mpn_mulmod_bnm1 (pp, rn, ap, an, bp, bn, tp);
+ }
+
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/perfpow.c b/gmp/mpn/generic/perfpow.c
new file mode 100644
index 0000000000..bbed6309d5
--- /dev/null
+++ b/gmp/mpn/generic/perfpow.c
@@ -0,0 +1,417 @@
+/* mpn_perfect_power_p -- mpn perfect power detection.
+
+ Contributed to the GNU project by Martin Boij.
+
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#define SMALL 20
+#define MEDIUM 100
+
+/* Return non-zero if {np,nn} == {xp,xn} ^ k.
+ Algorithm:
+ For s = 1, 2, 4, ..., s_max, compute the s least significant limbs of
+ {xp,xn}^k. Stop if they don't match the s least significant limbs of
+ {np,nn}.
+
+ FIXME: Low xn limbs can be expected to always match, if computed as a mod
+ B^{xn} root. So instead of using mpn_powlo, compute an approximation of the
+ most significant (normalized) limb of {xp,xn} ^ k (and an error bound), and
+ compare to {np, nn}. Or use an even cruder approximation based on fix-point
+ base 2 logarithm. */
+static int
+pow_equals (mp_srcptr np, mp_size_t n,
+ mp_srcptr xp,mp_size_t xn,
+ mp_limb_t k, mp_bitcnt_t f,
+ mp_ptr tp)
+{
+ mp_limb_t *tp2;
+ mp_bitcnt_t y, z;
+ mp_size_t i, bn;
+ int ans;
+ mp_limb_t h, l;
+ TMP_DECL;
+
+ ASSERT (n > 1 || (n == 1 && np[0] > 1));
+ ASSERT (np[n - 1] > 0);
+ ASSERT (xn > 0);
+
+ if (xn == 1 && xp[0] == 1)
+ return 0;
+
+ z = 1 + (n >> 1);
+ for (bn = 1; bn < z; bn <<= 1)
+ {
+ mpn_powlo (tp, xp, &k, 1, bn, tp + bn);
+ if (mpn_cmp (tp, np, bn) != 0)
+ return 0;
+ }
+
+ TMP_MARK;
+
+ /* Final check. Estimate the size of {xp,xn}^k before computing the power
+ with full precision. Optimization: It might pay off to make a more
+ accurate estimation of the logarithm of {xp,xn}, rather than using the
+ index of the MSB. */
+
+ MPN_SIZEINBASE_2EXP(y, xp, xn, 1);
+ y -= 1; /* msb_index (xp, xn) */
+
+ umul_ppmm (h, l, k, y);
+ h -= l == 0; l--; /* two-limb decrement */
+
+ z = f - 1; /* msb_index (np, n) */
+ if (h == 0 && l <= z)
+ {
+ mp_limb_t size;
+ size = l + k;
+ ASSERT_ALWAYS (size >= k);
+
+ y = 2 + size / GMP_LIMB_BITS;
+ tp2 = TMP_ALLOC_LIMBS (y);
+
+ i = mpn_pow_1 (tp, xp, xn, k, tp2);
+ if (i == n && mpn_cmp (tp, np, n) == 0)
+ ans = 1;
+ else
+ ans = 0;
+ }
+ else
+ {
+ ans = 0;
+ }
+
+ TMP_FREE;
+ return ans;
+}
+
+
+/* Return non-zero if N = {np,n} is a kth power.
+ I = {ip,n} = N^(-1) mod B^n. */
+static int
+is_kth_power (mp_ptr rp, mp_srcptr np,
+ mp_limb_t k, mp_srcptr ip,
+ mp_size_t n, mp_bitcnt_t f,
+ mp_ptr tp)
+{
+ mp_bitcnt_t b;
+ mp_size_t rn, xn;
+
+ ASSERT (n > 0);
+ ASSERT ((k & 1) != 0 || k == 2);
+ ASSERT ((np[0] & 1) != 0);
+
+ if (k == 2)
+ {
+ b = (f + 1) >> 1;
+ rn = 1 + b / GMP_LIMB_BITS;
+ if (mpn_bsqrtinv (rp, ip, b, tp) != 0)
+ {
+ rp[rn - 1] &= (CNST_LIMB(1) << (b % GMP_LIMB_BITS)) - 1;
+ xn = rn;
+ MPN_NORMALIZE (rp, xn);
+ if (pow_equals (np, n, rp, xn, k, f, tp) != 0)
+ return 1;
+
+ /* Check if (2^b - r)^2 == n */
+ mpn_neg (rp, rp, rn);
+ rp[rn - 1] &= (CNST_LIMB(1) << (b % GMP_LIMB_BITS)) - 1;
+ MPN_NORMALIZE (rp, rn);
+ if (pow_equals (np, n, rp, rn, k, f, tp) != 0)
+ return 1;
+ }
+ }
+ else
+ {
+ b = 1 + (f - 1) / k;
+ rn = 1 + (b - 1) / GMP_LIMB_BITS;
+ mpn_brootinv (rp, ip, rn, k, tp);
+ if ((b % GMP_LIMB_BITS) != 0)
+ rp[rn - 1] &= (CNST_LIMB(1) << (b % GMP_LIMB_BITS)) - 1;
+ MPN_NORMALIZE (rp, rn);
+ if (pow_equals (np, n, rp, rn, k, f, tp) != 0)
+ return 1;
+ }
+ MPN_ZERO (rp, rn); /* Untrash rp */
+ return 0;
+}
+
+static int
+perfpow (mp_srcptr np, mp_size_t n,
+ mp_limb_t ub, mp_limb_t g,
+ mp_bitcnt_t f, int neg)
+{
+ mp_ptr ip, tp, rp;
+ mp_limb_t k;
+ int ans;
+ mp_bitcnt_t b;
+ gmp_primesieve_t ps;
+ TMP_DECL;
+
+ ASSERT (n > 0);
+ ASSERT ((np[0] & 1) != 0);
+ ASSERT (ub > 0);
+
+ TMP_MARK;
+ gmp_init_primesieve (&ps);
+ b = (f + 3) >> 1;
+
+ ip = TMP_ALLOC_LIMBS (n);
+ rp = TMP_ALLOC_LIMBS (n);
+ tp = TMP_ALLOC_LIMBS (5 * n); /* FIXME */
+ MPN_ZERO (rp, n);
+
+ /* FIXME: It seems the inverse in ninv is needed only to get non-inverted
+ roots. I.e., is_kth_power computes n^{1/2} as (n^{-1})^{-1/2} and
+ similarly for nth roots. It should be more efficient to compute n^{1/2} as
+ n * n^{-1/2}, with a mullo instead of a binvert. And we can do something
+ similar for kth roots if we switch to an iteration converging to n^{1/k -
+ 1}, and we can then eliminate this binvert call. */
+ mpn_binvert (ip, np, 1 + (b - 1) / GMP_LIMB_BITS, tp);
+ if (b % GMP_LIMB_BITS)
+ ip[(b - 1) / GMP_LIMB_BITS] &= (CNST_LIMB(1) << (b % GMP_LIMB_BITS)) - 1;
+
+ if (neg)
+ gmp_nextprime (&ps);
+
+ ans = 0;
+ if (g > 0)
+ {
+ ub = MIN (ub, g + 1);
+ while ((k = gmp_nextprime (&ps)) < ub)
+ {
+ if ((g % k) == 0)
+ {
+ if (is_kth_power (rp, np, k, ip, n, f, tp) != 0)
+ {
+ ans = 1;
+ goto ret;
+ }
+ }
+ }
+ }
+ else
+ {
+ while ((k = gmp_nextprime (&ps)) < ub)
+ {
+ if (is_kth_power (rp, np, k, ip, n, f, tp) != 0)
+ {
+ ans = 1;
+ goto ret;
+ }
+ }
+ }
+ ret:
+ TMP_FREE;
+ return ans;
+}
+
+static const unsigned short nrtrial[] = { 100, 500, 1000 };
+
+/* Table of (log_{p_i} 2) values, where p_i is the (nrtrial[i] + 1)'th prime
+ number. */
+static const double logs[] =
+ { 0.1099457228193620, 0.0847016403115322, 0.0772048195144415 };
+
+int
+mpn_perfect_power_p (mp_srcptr np, mp_size_t n)
+{
+ mp_size_t ncn, s, pn, xn;
+ mp_limb_t *nc, factor, g;
+ mp_limb_t exp, *prev, *next, d, l, r, c, *tp, cry;
+ mp_bitcnt_t twos, count;
+ int ans, where, neg, trial;
+ TMP_DECL;
+
+ nc = (mp_ptr) np;
+
+ neg = 0;
+ if (n < 0)
+ {
+ neg = 1;
+ n = -n;
+ }
+
+ if (n == 0 || (n == 1 && np[0] == 1))
+ return 1;
+
+ TMP_MARK;
+
+ g = 0;
+
+ ncn = n;
+ twos = mpn_scan1 (np, 0);
+ if (twos > 0)
+ {
+ if (twos == 1)
+ {
+ ans = 0;
+ goto ret;
+ }
+ s = twos / GMP_LIMB_BITS;
+ if (s + 1 == n && POW2_P (np[s]))
+ {
+ ans = ! (neg && POW2_P (twos));
+ goto ret;
+ }
+ count = twos % GMP_LIMB_BITS;
+ ncn = n - s;
+ nc = TMP_ALLOC_LIMBS (ncn);
+ if (count > 0)
+ {
+ mpn_rshift (nc, np + s, ncn, count);
+ ncn -= (nc[ncn - 1] == 0);
+ }
+ else
+ {
+ MPN_COPY (nc, np + s, ncn);
+ }
+ g = twos;
+ }
+
+ if (ncn <= SMALL)
+ trial = 0;
+ else if (ncn <= MEDIUM)
+ trial = 1;
+ else
+ trial = 2;
+
+ where = 0;
+ factor = mpn_trialdiv (nc, ncn, nrtrial[trial], &where);
+
+ if (factor != 0)
+ {
+ if (twos == 0)
+ {
+ nc = TMP_ALLOC_LIMBS (ncn);
+ MPN_COPY (nc, np, ncn);
+ }
+
+ /* Remove factors found by trialdiv. Optimization: Perhaps better to use
+ the strategy in mpz_remove (). */
+ prev = TMP_ALLOC_LIMBS (ncn + 2);
+ next = TMP_ALLOC_LIMBS (ncn + 2);
+ tp = TMP_ALLOC_LIMBS (4 * ncn);
+
+ do
+ {
+ binvert_limb (d, factor);
+ prev[0] = d;
+ pn = 1;
+ exp = 1;
+ while (2 * pn - 1 <= ncn)
+ {
+ mpn_sqr (next, prev, pn);
+ xn = 2 * pn;
+ xn -= (next[xn - 1] == 0);
+
+ if (mpn_divisible_p (nc, ncn, next, xn) == 0)
+ break;
+
+ exp <<= 1;
+ pn = xn;
+ MP_PTR_SWAP (next, prev);
+ }
+
+ /* Binary search for the exponent */
+ l = exp + 1;
+ r = 2 * exp - 1;
+ while (l <= r)
+ {
+ c = (l + r) >> 1;
+ if (c - exp > 1)
+ {
+ xn = mpn_pow_1 (tp, &d, 1, c - exp, next);
+ if (pn + xn - 1 > ncn)
+ {
+ r = c - 1;
+ continue;
+ }
+ mpn_mul (next, prev, pn, tp, xn);
+ xn += pn;
+ xn -= (next[xn - 1] == 0);
+ }
+ else
+ {
+ cry = mpn_mul_1 (next, prev, pn, d);
+ next[pn] = cry;
+ xn = pn + (cry != 0);
+ }
+
+ if (mpn_divisible_p (nc, ncn, next, xn) == 0)
+ {
+ r = c - 1;
+ }
+ else
+ {
+ exp = c;
+ l = c + 1;
+ MP_PTR_SWAP (next, prev);
+ pn = xn;
+ }
+ }
+
+ if (g == 0)
+ g = exp;
+ else
+ g = mpn_gcd_1 (&g, 1, exp);
+
+ if (g == 1)
+ {
+ ans = 0;
+ goto ret;
+ }
+
+ mpn_divexact (next, nc, ncn, prev, pn);
+ ncn = ncn - pn;
+ ncn += next[ncn] != 0;
+ MPN_COPY (nc, next, ncn);
+
+ if (ncn == 1 && nc[0] == 1)
+ {
+ ans = ! (neg && POW2_P (g));
+ goto ret;
+ }
+
+ factor = mpn_trialdiv (nc, ncn, nrtrial[trial], &where);
+ }
+ while (factor != 0);
+ }
+
+ MPN_SIZEINBASE_2EXP(count, nc, ncn, 1); /* log (nc) + 1 */
+ d = (mp_limb_t) (count * logs[trial] + 1e-9) + 1;
+ ans = perfpow (nc, ncn, d, g, count, neg);
+
+ ret:
+ TMP_FREE;
+ return ans;
+}
diff --git a/gmp/mpn/generic/perfsqr.c b/gmp/mpn/generic/perfsqr.c
new file mode 100644
index 0000000000..bdd82ccd96
--- /dev/null
+++ b/gmp/mpn/generic/perfsqr.c
@@ -0,0 +1,240 @@
+/* mpn_perfect_square_p(u,usize) -- Return non-zero if U is a perfect square,
+ zero otherwise.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2005, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#include "perfsqr.h"
+
+
+/* change this to "#define TRACE(x) x" for diagnostics */
+#define TRACE(x)
+
+
+
+/* PERFSQR_MOD_* detects non-squares using residue tests.
+
+ A macro PERFSQR_MOD_TEST is setup by gen-psqr.c in perfsqr.h. It takes
+ {up,usize} modulo a selected modulus to get a remainder r. For 32-bit or
+ 64-bit limbs this modulus will be 2^24-1 or 2^48-1 using PERFSQR_MOD_34,
+ or for other limb or nail sizes a PERFSQR_PP is chosen and PERFSQR_MOD_PP
+ used. PERFSQR_PP_NORM and PERFSQR_PP_INVERTED are pre-calculated in this
+ case too.
+
+ PERFSQR_MOD_TEST then makes various calls to PERFSQR_MOD_1 or
+ PERFSQR_MOD_2 with divisors d which are factors of the modulus, and table
+ data indicating residues and non-residues modulo those divisors. The
+ table data is in 1 or 2 limbs worth of bits respectively, per the size of
+ each d.
+
+ A "modexact" style remainder is taken to reduce r modulo d.
+ PERFSQR_MOD_IDX implements this, producing an index "idx" for use with
+ the table data. Notice there's just one multiplication by a constant
+ "inv", for each d.
+
+ The modexact doesn't produce a true r%d remainder, instead idx satisfies
+ "-(idx<<PERFSQR_MOD_BITS) == r mod d". Because d is odd, this factor
+ -2^PERFSQR_MOD_BITS is a one-to-one mapping between r and idx, and is
+ accounted for by having the table data suitably permuted.
+
+ The remainder r fits within PERFSQR_MOD_BITS which is less than a limb.
+ In fact the GMP_LIMB_BITS - PERFSQR_MOD_BITS spare bits are enough to fit
+ each divisor d meaning the modexact multiply can take place entirely
+ within one limb, giving the compiler the chance to optimize it, in a way
+ that say umul_ppmm would not give.
+
+ There's no need for the divisors d to be prime, in fact gen-psqr.c makes
+ a deliberate effort to combine factors so as to reduce the number of
+ separate tests done on r. But such combining is limited to d <=
+ 2*GMP_LIMB_BITS so that the table data fits in at most 2 limbs.
+
+ Alternatives:
+
+ It'd be possible to use bigger divisors d, and more than 2 limbs of table
+ data, but this doesn't look like it would be of much help to the prime
+ factors in the usual moduli 2^24-1 or 2^48-1.
+
+ The moduli 2^24-1 or 2^48-1 are nothing particularly special, they're
+ just easy to calculate (see mpn_mod_34lsub1) and have a nice set of prime
+ factors. 2^32-1 and 2^64-1 would be equally easy to calculate, but have
+ fewer prime factors.
+
+ The nails case usually ends up using mpn_mod_1, which is a lot slower
+ than mpn_mod_34lsub1. Perhaps other such special moduli could be found
+ for the nails case. Two-term things like 2^30-2^15-1 might be
+ candidates. Or at worst some on-the-fly de-nailing would allow the plain
+ 2^24-1 to be used. Currently nails are too preliminary to be worried
+ about.
+
+*/
+
+#define PERFSQR_MOD_MASK ((CNST_LIMB(1) << PERFSQR_MOD_BITS) - 1)
+
+#define MOD34_BITS (GMP_NUMB_BITS / 4 * 3)
+#define MOD34_MASK ((CNST_LIMB(1) << MOD34_BITS) - 1)
+
+#define PERFSQR_MOD_34(r, up, usize) \
+ do { \
+ (r) = mpn_mod_34lsub1 (up, usize); \
+ (r) = ((r) & MOD34_MASK) + ((r) >> MOD34_BITS); \
+ } while (0)
+
+/* FIXME: The %= here isn't good, and might destroy any savings from keeping
+ the PERFSQR_MOD_IDX stuff within a limb (rather than needing umul_ppmm).
+ Maybe a new sort of mpn_preinv_mod_1 could accept an unnormalized divisor
+ and a shift count, like mpn_preinv_divrem_1. But mod_34lsub1 is our
+ normal case, so lets not worry too much about mod_1. */
+#define PERFSQR_MOD_PP(r, up, usize) \
+ do { \
+ if (BELOW_THRESHOLD (usize, PREINV_MOD_1_TO_MOD_1_THRESHOLD)) \
+ { \
+ (r) = mpn_preinv_mod_1 (up, usize, PERFSQR_PP_NORM, \
+ PERFSQR_PP_INVERTED); \
+ (r) %= PERFSQR_PP; \
+ } \
+ else \
+ { \
+ (r) = mpn_mod_1 (up, usize, PERFSQR_PP); \
+ } \
+ } while (0)
+
+#define PERFSQR_MOD_IDX(idx, r, d, inv) \
+ do { \
+ mp_limb_t q; \
+ ASSERT ((r) <= PERFSQR_MOD_MASK); \
+ ASSERT ((((inv) * (d)) & PERFSQR_MOD_MASK) == 1); \
+ ASSERT (MP_LIMB_T_MAX / (d) >= PERFSQR_MOD_MASK); \
+ \
+ q = ((r) * (inv)) & PERFSQR_MOD_MASK; \
+ ASSERT (r == ((q * (d)) & PERFSQR_MOD_MASK)); \
+ (idx) = (q * (d)) >> PERFSQR_MOD_BITS; \
+ } while (0)
+
+#define PERFSQR_MOD_1(r, d, inv, mask) \
+ do { \
+ unsigned idx; \
+ ASSERT ((d) <= GMP_LIMB_BITS); \
+ PERFSQR_MOD_IDX(idx, r, d, inv); \
+ TRACE (printf (" PERFSQR_MOD_1 d=%u r=%lu idx=%u\n", \
+ d, r%d, idx)); \
+ if ((((mask) >> idx) & 1) == 0) \
+ { \
+ TRACE (printf (" non-square\n")); \
+ return 0; \
+ } \
+ } while (0)
+
+/* The expression "(int) idx - GMP_LIMB_BITS < 0" lets the compiler use the
+ sign bit from "idx-GMP_LIMB_BITS", which might help avoid a branch. */
+#define PERFSQR_MOD_2(r, d, inv, mhi, mlo) \
+ do { \
+ mp_limb_t m; \
+ unsigned idx; \
+ ASSERT ((d) <= 2*GMP_LIMB_BITS); \
+ \
+ PERFSQR_MOD_IDX (idx, r, d, inv); \
+ TRACE (printf (" PERFSQR_MOD_2 d=%u r=%lu idx=%u\n", \
+ d, r%d, idx)); \
+ m = ((int) idx - GMP_LIMB_BITS < 0 ? (mlo) : (mhi)); \
+ idx %= GMP_LIMB_BITS; \
+ if (((m >> idx) & 1) == 0) \
+ { \
+ TRACE (printf (" non-square\n")); \
+ return 0; \
+ } \
+ } while (0)
+
+
+int
+mpn_perfect_square_p (mp_srcptr up, mp_size_t usize)
+{
+ ASSERT (usize >= 1);
+
+ TRACE (gmp_printf ("mpn_perfect_square_p %Nd\n", up, usize));
+
+ /* The first test excludes 212/256 (82.8%) of the perfect square candidates
+ in O(1) time. */
+ {
+ unsigned idx = up[0] % 0x100;
+ if (((sq_res_0x100[idx / GMP_LIMB_BITS]
+ >> (idx % GMP_LIMB_BITS)) & 1) == 0)
+ return 0;
+ }
+
+#if 0
+ /* Check that we have even multiplicity of 2, and then check that the rest is
+ a possible perfect square. Leave disabled until we can determine this
+ really is an improvement. It it is, it could completely replace the
+ simple probe above, since this should throw out more non-squares, but at
+ the expense of somewhat more cycles. */
+ {
+ mp_limb_t lo;
+ int cnt;
+ lo = up[0];
+ while (lo == 0)
+ up++, lo = up[0], usize--;
+ count_trailing_zeros (cnt, lo);
+ if ((cnt & 1) != 0)
+ return 0; /* return of not even multiplicity of 2 */
+ lo >>= cnt; /* shift down to align lowest non-zero bit */
+ lo >>= 1; /* shift away lowest non-zero bit */
+ if ((lo & 3) != 0)
+ return 0;
+ }
+#endif
+
+
+ /* The second test uses mpn_mod_34lsub1 or mpn_mod_1 to detect non-squares
+ according to their residues modulo small primes (or powers of
+ primes). See perfsqr.h. */
+ PERFSQR_MOD_TEST (up, usize);
+
+
+ /* For the third and last test, we finally compute the square root,
+ to make sure we've really got a perfect square. */
+ {
+ mp_ptr root_ptr;
+ int res;
+ TMP_DECL;
+
+ TMP_MARK;
+ root_ptr = TMP_ALLOC_LIMBS ((usize + 1) / 2);
+
+ /* Iff mpn_sqrtrem returns zero, the square is perfect. */
+ res = ! mpn_sqrtrem (root_ptr, NULL, up, usize);
+ TMP_FREE;
+
+ return res;
+ }
+}
diff --git a/gmp/mpn/generic/popham.c b/gmp/mpn/generic/popham.c
new file mode 100644
index 0000000000..13e529b7cd
--- /dev/null
+++ b/gmp/mpn/generic/popham.c
@@ -0,0 +1,126 @@
+/* mpn_popcount, mpn_hamdist -- mpn bit population count/hamming distance.
+
+Copyright 1994, 1996, 2000-2002, 2005, 2011, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if OPERATION_popcount
+#define FNAME mpn_popcount
+#define POPHAM(u,v) u
+#endif
+
+#if OPERATION_hamdist
+#define FNAME mpn_hamdist
+#define POPHAM(u,v) u ^ v
+#endif
+
+mp_bitcnt_t
+FNAME (mp_srcptr up,
+#if OPERATION_hamdist
+ mp_srcptr vp,
+#endif
+ mp_size_t n) __GMP_NOTHROW
+{
+ mp_bitcnt_t result = 0;
+ mp_limb_t p0, p1, p2, p3, x, p01, p23;
+ mp_size_t i;
+
+ ASSERT (n >= 1); /* Actually, this code handles any n, but some
+ assembly implementations do not. */
+
+ for (i = n >> 2; i != 0; i--)
+ {
+ p0 = POPHAM (up[0], vp[0]);
+ p0 -= (p0 >> 1) & MP_LIMB_T_MAX/3; /* 2 0-2 */
+ p0 = ((p0 >> 2) & MP_LIMB_T_MAX/5) + (p0 & MP_LIMB_T_MAX/5); /* 4 0-4 */
+
+ p1 = POPHAM (up[1], vp[1]);
+ p1 -= (p1 >> 1) & MP_LIMB_T_MAX/3; /* 2 0-2 */
+ p1 = ((p1 >> 2) & MP_LIMB_T_MAX/5) + (p1 & MP_LIMB_T_MAX/5); /* 4 0-4 */
+
+ p01 = p0 + p1; /* 8 0-8 */
+ p01 = ((p01 >> 4) & MP_LIMB_T_MAX/17) + (p01 & MP_LIMB_T_MAX/17); /* 8 0-16 */
+
+ p2 = POPHAM (up[2], vp[2]);
+ p2 -= (p2 >> 1) & MP_LIMB_T_MAX/3; /* 2 0-2 */
+ p2 = ((p2 >> 2) & MP_LIMB_T_MAX/5) + (p2 & MP_LIMB_T_MAX/5); /* 4 0-4 */
+
+ p3 = POPHAM (up[3], vp[3]);
+ p3 -= (p3 >> 1) & MP_LIMB_T_MAX/3; /* 2 0-2 */
+ p3 = ((p3 >> 2) & MP_LIMB_T_MAX/5) + (p3 & MP_LIMB_T_MAX/5); /* 4 0-4 */
+
+ p23 = p2 + p3; /* 8 0-8 */
+ p23 = ((p23 >> 4) & MP_LIMB_T_MAX/17) + (p23 & MP_LIMB_T_MAX/17); /* 8 0-16 */
+
+ x = p01 + p23; /* 8 0-32 */
+ x = (x >> 8) + x; /* 8 0-64 */
+ x = (x >> 16) + x; /* 8 0-128 */
+#if GMP_LIMB_BITS > 32
+ x = ((x >> 32) & 0xff) + (x & 0xff); /* 8 0-256 */
+ result += x;
+#else
+ result += x & 0xff;
+#endif
+ up += 4;
+#if OPERATION_hamdist
+ vp += 4;
+#endif
+ }
+
+ n &= 3;
+ if (n != 0)
+ {
+ x = 0;
+ do
+ {
+ p0 = POPHAM (up[0], vp[0]);
+ p0 -= (p0 >> 1) & MP_LIMB_T_MAX/3; /* 2 0-2 */
+ p0 = ((p0 >> 2) & MP_LIMB_T_MAX/5) + (p0 & MP_LIMB_T_MAX/5); /* 4 0-4 */
+ p0 = ((p0 >> 4) + p0) & MP_LIMB_T_MAX/17; /* 8 0-8 */
+
+ x += p0;
+ up += 1;
+#if OPERATION_hamdist
+ vp += 1;
+#endif
+ }
+ while (--n);
+
+ x = (x >> 8) + x;
+ x = (x >> 16) + x;
+#if GMP_LIMB_BITS > 32
+ x = (x >> 32) + x;
+#endif
+ result += x & 0xff;
+ }
+
+ return result;
+}
diff --git a/gmp/mpn/generic/pow_1.c b/gmp/mpn/generic/pow_1.c
new file mode 100644
index 0000000000..2333206554
--- /dev/null
+++ b/gmp/mpn/generic/pow_1.c
@@ -0,0 +1,134 @@
+/* mpn_pow_1 -- Compute powers R = U^exp.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2002, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_size_t
+mpn_pow_1 (mp_ptr rp, mp_srcptr bp, mp_size_t bn, mp_limb_t exp, mp_ptr tp)
+{
+ mp_limb_t x;
+ int cnt, i;
+ mp_size_t rn;
+ int par;
+
+ ASSERT (bn >= 1);
+ /* FIXME: Add operand overlap criteria */
+
+ if (exp <= 1)
+ {
+ if (exp == 0)
+ {
+ rp[0] = 1;
+ return 1;
+ }
+ else
+ {
+ MPN_COPY (rp, bp, bn);
+ return bn;
+ }
+ }
+
+ /* Count number of bits in exp, and compute where to put initial square in
+ order to magically get results in the entry rp. Use simple code,
+ optimized for small exp. For large exp, the bignum operations will take
+ so much time that the slowness of this code will be negligible. */
+ par = 0;
+ cnt = GMP_LIMB_BITS;
+ x = exp;
+ do
+ {
+ par ^= x;
+ cnt--;
+ x >>= 1;
+ } while (x != 0);
+ exp <<= cnt;
+
+ if (bn == 1)
+ {
+ mp_limb_t bl = bp[0];
+
+ if ((cnt & 1) != 0)
+ MP_PTR_SWAP (rp, tp);
+
+ mpn_sqr (rp, bp, bn);
+ rn = 2 * bn; rn -= rp[rn - 1] == 0;
+
+ for (i = GMP_LIMB_BITS - cnt - 1;;)
+ {
+ exp <<= 1;
+ if ((exp & GMP_LIMB_HIGHBIT) != 0)
+ {
+ rp[rn] = mpn_mul_1 (rp, rp, rn, bl);
+ rn += rp[rn] != 0;
+ }
+
+ if (--i == 0)
+ break;
+
+ mpn_sqr (tp, rp, rn);
+ rn = 2 * rn; rn -= tp[rn - 1] == 0;
+ MP_PTR_SWAP (rp, tp);
+ }
+ }
+ else
+ {
+ if (((par ^ cnt) & 1) == 0)
+ MP_PTR_SWAP (rp, tp);
+
+ mpn_sqr (rp, bp, bn);
+ rn = 2 * bn; rn -= rp[rn - 1] == 0;
+
+ for (i = GMP_LIMB_BITS - cnt - 1;;)
+ {
+ exp <<= 1;
+ if ((exp & GMP_LIMB_HIGHBIT) != 0)
+ {
+ rn = rn + bn - (mpn_mul (tp, rp, rn, bp, bn) == 0);
+ MP_PTR_SWAP (rp, tp);
+ }
+
+ if (--i == 0)
+ break;
+
+ mpn_sqr (tp, rp, rn);
+ rn = 2 * rn; rn -= tp[rn - 1] == 0;
+ MP_PTR_SWAP (rp, tp);
+ }
+ }
+
+ return rn;
+}
diff --git a/gmp/mpn/generic/powlo.c b/gmp/mpn/generic/powlo.c
new file mode 100644
index 0000000000..adcd96eb51
--- /dev/null
+++ b/gmp/mpn/generic/powlo.c
@@ -0,0 +1,174 @@
+/* mpn_powlo -- Compute R = U^E mod B^n, where B is the limb base.
+
+Copyright 2007-2009, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#define getbit(p,bi) \
+ ((p[(bi - 1) / GMP_LIMB_BITS] >> (bi - 1) % GMP_LIMB_BITS) & 1)
+
+static inline mp_limb_t
+getbits (const mp_limb_t *p, mp_bitcnt_t bi, int nbits)
+{
+ int nbits_in_r;
+ mp_limb_t r;
+ mp_size_t i;
+
+ if (bi < nbits)
+ {
+ return p[0] & (((mp_limb_t) 1 << bi) - 1);
+ }
+ else
+ {
+ bi -= nbits; /* bit index of low bit to extract */
+ i = bi / GMP_NUMB_BITS; /* word index of low bit to extract */
+ bi %= GMP_NUMB_BITS; /* bit index in low word */
+ r = p[i] >> bi; /* extract (low) bits */
+ nbits_in_r = GMP_NUMB_BITS - bi; /* number of bits now in r */
+ if (nbits_in_r < nbits) /* did we get enough bits? */
+ r += p[i + 1] << nbits_in_r; /* prepend bits from higher word */
+ return r & (((mp_limb_t ) 1 << nbits) - 1);
+ }
+}
+
+static inline int
+win_size (mp_bitcnt_t eb)
+{
+ int k;
+ static mp_bitcnt_t x[] = {1,7,25,81,241,673,1793,4609,11521,28161,~(mp_bitcnt_t)0};
+ for (k = 0; eb > x[k]; k++)
+ ;
+ return k;
+}
+
+/* rp[n-1..0] = bp[n-1..0] ^ ep[en-1..0] mod B^n, B is the limb base.
+ Requires that ep[en-1] is non-zero.
+ Uses scratch space tp[3n-1..0], i.e., 3n words. */
+void
+mpn_powlo (mp_ptr rp, mp_srcptr bp,
+ mp_srcptr ep, mp_size_t en,
+ mp_size_t n, mp_ptr tp)
+{
+ int cnt;
+ mp_bitcnt_t ebi;
+ int windowsize, this_windowsize;
+ mp_limb_t expbits;
+ mp_limb_t *pp, *this_pp, *last_pp;
+ mp_limb_t *b2p;
+ long i;
+ TMP_DECL;
+
+ ASSERT (en > 1 || (en == 1 && ep[0] > 1));
+
+ TMP_MARK;
+
+ MPN_SIZEINBASE_2EXP(ebi, ep, en, 1);
+
+ windowsize = win_size (ebi);
+
+ pp = TMP_ALLOC_LIMBS ((n << (windowsize - 1)) + n); /* + n is for mullo ign part */
+
+ this_pp = pp;
+
+ MPN_COPY (this_pp, bp, n);
+
+ b2p = tp + 2*n;
+
+ /* Store b^2 in b2. */
+ mpn_sqr (tp, bp, n); /* FIXME: Use "mpn_sqrlo" */
+ MPN_COPY (b2p, tp, n);
+
+ /* Precompute odd powers of b and put them in the temporary area at pp. */
+ for (i = (1 << (windowsize - 1)) - 1; i > 0; i--)
+ {
+ last_pp = this_pp;
+ this_pp += n;
+ mpn_mullo_n (this_pp, last_pp, b2p, n);
+ }
+
+ expbits = getbits (ep, ebi, windowsize);
+ if (ebi < windowsize)
+ ebi = 0;
+ else
+ ebi -= windowsize;
+
+ count_trailing_zeros (cnt, expbits);
+ ebi += cnt;
+ expbits >>= cnt;
+
+ MPN_COPY (rp, pp + n * (expbits >> 1), n);
+
+ while (ebi != 0)
+ {
+ while (getbit (ep, ebi) == 0)
+ {
+ mpn_sqr (tp, rp, n); /* FIXME: Use "mpn_sqrlo" */
+ MPN_COPY (rp, tp, n);
+ ebi--;
+ if (ebi == 0)
+ goto done;
+ }
+
+ /* The next bit of the exponent is 1. Now extract the largest block of
+ bits <= windowsize, and such that the least significant bit is 1. */
+
+ expbits = getbits (ep, ebi, windowsize);
+ this_windowsize = windowsize;
+ if (ebi < windowsize)
+ {
+ this_windowsize -= windowsize - ebi;
+ ebi = 0;
+ }
+ else
+ ebi -= windowsize;
+
+ count_trailing_zeros (cnt, expbits);
+ this_windowsize -= cnt;
+ ebi += cnt;
+ expbits >>= cnt;
+
+ do
+ {
+ mpn_sqr (tp, rp, n);
+ MPN_COPY (rp, tp, n);
+ this_windowsize--;
+ }
+ while (this_windowsize != 0);
+
+ mpn_mullo_n (tp, rp, pp + n * (expbits >> 1), n);
+ MPN_COPY (rp, tp, n);
+ }
+
+ done:
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/powm.c b/gmp/mpn/generic/powm.c
new file mode 100644
index 0000000000..9968116016
--- /dev/null
+++ b/gmp/mpn/generic/powm.c
@@ -0,0 +1,590 @@
+/* mpn_powm -- Compute R = U^E mod M.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2007-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/*
+ BASIC ALGORITHM, Compute U^E mod M, where M < B^n is odd.
+
+ 1. W <- U
+
+ 2. T <- (B^n * U) mod M Convert to REDC form
+
+ 3. Compute table U^1, U^3, U^5... of E-dependent size
+
+ 4. While there are more bits in E
+ W <- power left-to-right base-k
+
+
+ TODO:
+
+ * Make getbits a macro, thereby allowing it to update the index operand.
+ That will simplify the code using getbits. (Perhaps make getbits' sibling
+ getbit then have similar form, for symmetry.)
+
+ * Write an itch function. Or perhaps get rid of tp parameter since the huge
+ pp area is allocated locally anyway?
+
+ * Choose window size without looping. (Superoptimize or think(tm).)
+
+ * Handle small bases with initial, reduction-free exponentiation.
+
+ * Call new division functions, not mpn_tdiv_qr.
+
+ * Consider special code for one-limb M.
+
+ * How should we handle the redc1/redc2/redc_n choice?
+ - redc1: T(binvert_1limb) + e * (n) * (T(mullo-1x1) + n*T(addmul_1))
+ - redc2: T(binvert_2limbs) + e * (n/2) * (T(mullo-2x2) + n*T(addmul_2))
+ - redc_n: T(binvert_nlimbs) + e * (T(mullo-nxn) + T(M(n)))
+ This disregards the addmul_N constant term, but we could think of
+ that as part of the respective mullo.
+
+ * When U (the base) is small, we should start the exponentiation with plain
+ operations, then convert that partial result to REDC form.
+
+ * When U is just one limb, should it be handled without the k-ary tricks?
+ We could keep a factor of B^n in W, but use U' = BU as base. After
+ multiplying by this (pseudo two-limb) number, we need to multiply by 1/B
+ mod M.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#undef MPN_REDC_1
+#define MPN_REDC_1(rp, up, mp, n, invm) \
+ do { \
+ mp_limb_t cy; \
+ cy = mpn_redc_1 (rp, up, mp, n, invm); \
+ if (cy != 0) \
+ mpn_sub_n (rp, rp, mp, n); \
+ } while (0)
+
+#undef MPN_REDC_2
+#define MPN_REDC_2(rp, up, mp, n, mip) \
+ do { \
+ mp_limb_t cy; \
+ cy = mpn_redc_2 (rp, up, mp, n, mip); \
+ if (cy != 0) \
+ mpn_sub_n (rp, rp, mp, n); \
+ } while (0)
+
+#if HAVE_NATIVE_mpn_addmul_2 || HAVE_NATIVE_mpn_redc_2
+#define WANT_REDC_2 1
+#endif
+
+#define getbit(p,bi) \
+ ((p[(bi - 1) / GMP_LIMB_BITS] >> (bi - 1) % GMP_LIMB_BITS) & 1)
+
+static inline mp_limb_t
+getbits (const mp_limb_t *p, mp_bitcnt_t bi, int nbits)
+{
+ int nbits_in_r;
+ mp_limb_t r;
+ mp_size_t i;
+
+ if (bi < nbits)
+ {
+ return p[0] & (((mp_limb_t) 1 << bi) - 1);
+ }
+ else
+ {
+ bi -= nbits; /* bit index of low bit to extract */
+ i = bi / GMP_NUMB_BITS; /* word index of low bit to extract */
+ bi %= GMP_NUMB_BITS; /* bit index in low word */
+ r = p[i] >> bi; /* extract (low) bits */
+ nbits_in_r = GMP_NUMB_BITS - bi; /* number of bits now in r */
+ if (nbits_in_r < nbits) /* did we get enough bits? */
+ r += p[i + 1] << nbits_in_r; /* prepend bits from higher word */
+ return r & (((mp_limb_t ) 1 << nbits) - 1);
+ }
+}
+
+static inline int
+win_size (mp_bitcnt_t eb)
+{
+ int k;
+ static mp_bitcnt_t x[] = {0,7,25,81,241,673,1793,4609,11521,28161,~(mp_bitcnt_t)0};
+ for (k = 1; eb > x[k]; k++)
+ ;
+ return k;
+}
+
+/* Convert U to REDC form, U_r = B^n * U mod M */
+static void
+redcify (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr mp, mp_size_t n)
+{
+ mp_ptr tp, qp;
+ TMP_DECL;
+ TMP_MARK;
+
+ tp = TMP_ALLOC_LIMBS (un + n);
+ qp = TMP_ALLOC_LIMBS (un + 1); /* FIXME: Put at tp+? */
+
+ MPN_ZERO (tp, n);
+ MPN_COPY (tp + n, up, un);
+ mpn_tdiv_qr (qp, rp, 0L, tp, un + n, mp, n);
+ TMP_FREE;
+}
+
+/* rp[n-1..0] = bp[bn-1..0] ^ ep[en-1..0] mod mp[n-1..0]
+ Requires that mp[n-1..0] is odd.
+ Requires that ep[en-1..0] is > 1.
+ Uses scratch space at tp of MAX(mpn_binvert_itch(n),2n) limbs. */
+void
+mpn_powm (mp_ptr rp, mp_srcptr bp, mp_size_t bn,
+ mp_srcptr ep, mp_size_t en,
+ mp_srcptr mp, mp_size_t n, mp_ptr tp)
+{
+ mp_limb_t ip[2], *mip;
+ int cnt;
+ mp_bitcnt_t ebi;
+ int windowsize, this_windowsize;
+ mp_limb_t expbits;
+ mp_ptr pp, this_pp;
+ long i;
+ TMP_DECL;
+
+ ASSERT (en > 1 || (en == 1 && ep[0] > 1));
+ ASSERT (n >= 1 && ((mp[0] & 1) != 0));
+
+ TMP_MARK;
+
+ MPN_SIZEINBASE_2EXP(ebi, ep, en, 1);
+
+#if 0
+ if (bn < n)
+ {
+ /* Do the first few exponent bits without mod reductions,
+ until the result is greater than the mod argument. */
+ for (;;)
+ {
+ mpn_sqr (tp, this_pp, tn);
+ tn = tn * 2 - 1, tn += tp[tn] != 0;
+ if (getbit (ep, ebi) != 0)
+ mpn_mul (..., tp, tn, bp, bn);
+ ebi--;
+ }
+ }
+#endif
+
+ windowsize = win_size (ebi);
+
+#if WANT_REDC_2
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ {
+ mip = ip;
+ binvert_limb (mip[0], mp[0]);
+ mip[0] = -mip[0];
+ }
+ else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD))
+ {
+ mip = ip;
+ mpn_binvert (mip, mp, 2, tp);
+ mip[0] = -mip[0]; mip[1] = ~mip[1];
+ }
+#else
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD))
+ {
+ mip = ip;
+ binvert_limb (mip[0], mp[0]);
+ mip[0] = -mip[0];
+ }
+#endif
+ else
+ {
+ mip = TMP_ALLOC_LIMBS (n);
+ mpn_binvert (mip, mp, n, tp);
+ }
+
+ pp = TMP_ALLOC_LIMBS (n << (windowsize - 1));
+
+ this_pp = pp;
+ redcify (this_pp, bp, bn, mp, n);
+
+ /* Store b^2 at rp. */
+ mpn_sqr (tp, this_pp, n);
+#if WANT_REDC_2
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ MPN_REDC_1 (rp, tp, mp, n, mip[0]);
+ else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD))
+ MPN_REDC_2 (rp, tp, mp, n, mip);
+#else
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD))
+ MPN_REDC_1 (rp, tp, mp, n, mip[0]);
+#endif
+ else
+ mpn_redc_n (rp, tp, mp, n, mip);
+
+ /* Precompute odd powers of b and put them in the temporary area at pp. */
+ for (i = (1 << (windowsize - 1)) - 1; i > 0; i--)
+ {
+ mpn_mul_n (tp, this_pp, rp, n);
+ this_pp += n;
+#if WANT_REDC_2
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ MPN_REDC_1 (this_pp, tp, mp, n, mip[0]);
+ else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD))
+ MPN_REDC_2 (this_pp, tp, mp, n, mip);
+#else
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD))
+ MPN_REDC_1 (this_pp, tp, mp, n, mip[0]);
+#endif
+ else
+ mpn_redc_n (this_pp, tp, mp, n, mip);
+ }
+
+ expbits = getbits (ep, ebi, windowsize);
+ if (ebi < windowsize)
+ ebi = 0;
+ else
+ ebi -= windowsize;
+
+ count_trailing_zeros (cnt, expbits);
+ ebi += cnt;
+ expbits >>= cnt;
+
+ MPN_COPY (rp, pp + n * (expbits >> 1), n);
+
+#define INNERLOOP \
+ while (ebi != 0) \
+ { \
+ while (getbit (ep, ebi) == 0) \
+ { \
+ MPN_SQR (tp, rp, n); \
+ MPN_REDUCE (rp, tp, mp, n, mip); \
+ ebi--; \
+ if (ebi == 0) \
+ goto done; \
+ } \
+ \
+ /* The next bit of the exponent is 1. Now extract the largest \
+ block of bits <= windowsize, and such that the least \
+ significant bit is 1. */ \
+ \
+ expbits = getbits (ep, ebi, windowsize); \
+ this_windowsize = windowsize; \
+ if (ebi < windowsize) \
+ { \
+ this_windowsize -= windowsize - ebi; \
+ ebi = 0; \
+ } \
+ else \
+ ebi -= windowsize; \
+ \
+ count_trailing_zeros (cnt, expbits); \
+ this_windowsize -= cnt; \
+ ebi += cnt; \
+ expbits >>= cnt; \
+ \
+ do \
+ { \
+ MPN_SQR (tp, rp, n); \
+ MPN_REDUCE (rp, tp, mp, n, mip); \
+ this_windowsize--; \
+ } \
+ while (this_windowsize != 0); \
+ \
+ MPN_MUL_N (tp, rp, pp + n * (expbits >> 1), n); \
+ MPN_REDUCE (rp, tp, mp, n, mip); \
+ }
+
+
+#if WANT_REDC_2
+ if (REDC_1_TO_REDC_2_THRESHOLD < MUL_TOOM22_THRESHOLD)
+ {
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ {
+ if (REDC_1_TO_REDC_2_THRESHOLD < SQR_BASECASE_THRESHOLD
+ || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ }
+ else if (BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD))
+ {
+ if (MUL_TOOM22_THRESHOLD < SQR_BASECASE_THRESHOLD
+ || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_2 (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_2 (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ }
+ else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_2 (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ }
+ else
+ {
+ if (BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD))
+ {
+ if (MUL_TOOM22_THRESHOLD < SQR_BASECASE_THRESHOLD
+ || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ }
+ else if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_2 (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ }
+
+#else /* WANT_REDC_2 */
+
+ if (REDC_1_TO_REDC_N_THRESHOLD < MUL_TOOM22_THRESHOLD)
+ {
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD))
+ {
+ if (REDC_1_TO_REDC_N_THRESHOLD < SQR_BASECASE_THRESHOLD
+ || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ }
+ else if (BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD))
+ {
+ if (MUL_TOOM22_THRESHOLD < SQR_BASECASE_THRESHOLD
+ || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ }
+ else
+ {
+ if (BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD))
+ {
+ if (MUL_TOOM22_THRESHOLD < SQR_BASECASE_THRESHOLD
+ || BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_mul_basecase (r,a,n,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ }
+ else if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1 (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_n (r,a,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) mpn_redc_n (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+ }
+#endif /* WANT_REDC_2 */
+
+ done:
+
+ MPN_COPY (tp, rp, n);
+ MPN_ZERO (tp + n, n);
+
+#if WANT_REDC_2
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ MPN_REDC_1 (rp, tp, mp, n, mip[0]);
+ else if (BELOW_THRESHOLD (n, REDC_2_TO_REDC_N_THRESHOLD))
+ MPN_REDC_2 (rp, tp, mp, n, mip);
+#else
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_N_THRESHOLD))
+ MPN_REDC_1 (rp, tp, mp, n, mip[0]);
+#endif
+ else
+ mpn_redc_n (rp, tp, mp, n, mip);
+
+ if (mpn_cmp (rp, mp, n) >= 0)
+ mpn_sub_n (rp, rp, mp, n);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/pre_divrem_1.c b/gmp/mpn/generic/pre_divrem_1.c
new file mode 100644
index 0000000000..8027f0216e
--- /dev/null
+++ b/gmp/mpn/generic/pre_divrem_1.c
@@ -0,0 +1,146 @@
+/* mpn_preinv_divrem_1 -- mpn by limb division with pre-inverted divisor.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2000-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Don't bloat a shared library with unused code. */
+#if USE_PREINV_DIVREM_1
+
+/* Same test here for skipping one divide step as in mpn_divrem_1.
+
+ The main reason for a separate shift==0 case is that not all CPUs give
+ zero for "n0 >> GMP_LIMB_BITS" which would arise in the general case
+ code used on shift==0. shift==0 is also reasonably common in mp_bases
+ big_base, for instance base==10 on a 64-bit limb.
+
+ Under shift!=0 it would be possible to call mpn_lshift to adjust the
+ dividend all in one go (into the quotient space say), rather than
+ limb-by-limb in the loop. This might help if mpn_lshift is a lot faster
+ than what the compiler can generate for EXTRACT. But this is left to CPU
+ specific implementations to consider, especially since EXTRACT isn't on
+ the dependent chain.
+
+ If size==0 then the result is simply xsize limbs of zeros, but nothing
+ special is done for that, since it wouldn't be a usual call, and
+ certainly never arises from mpn_get_str which is our main caller. */
+
+mp_limb_t
+mpn_preinv_divrem_1 (mp_ptr qp, mp_size_t xsize,
+ mp_srcptr ap, mp_size_t size, mp_limb_t d_unnorm,
+ mp_limb_t dinv, int shift)
+{
+ mp_limb_t ahigh, qhigh, r;
+ mp_size_t i;
+ mp_limb_t n1, n0;
+ mp_limb_t d;
+
+ ASSERT (xsize >= 0);
+ ASSERT (size >= 1);
+ ASSERT (d_unnorm != 0);
+#if WANT_ASSERT
+ {
+ int want_shift;
+ mp_limb_t want_dinv;
+ count_leading_zeros (want_shift, d_unnorm);
+ ASSERT (shift == want_shift);
+ invert_limb (want_dinv, d_unnorm << shift);
+ ASSERT (dinv == want_dinv);
+ }
+#endif
+ /* FIXME: What's the correct overlap rule when xsize!=0? */
+ ASSERT (MPN_SAME_OR_SEPARATE_P (qp+xsize, ap, size));
+
+ ahigh = ap[size-1];
+ d = d_unnorm << shift;
+ qp += (size + xsize - 1); /* dest high limb */
+
+ if (shift == 0)
+ {
+ /* High quotient limb is 0 or 1, and skip a divide step. */
+ r = ahigh;
+ qhigh = (r >= d);
+ r = (qhigh ? r-d : r);
+ *qp-- = qhigh;
+ size--;
+
+ for (i = size-1; i >= 0; i--)
+ {
+ n0 = ap[i];
+ udiv_qrnnd_preinv (*qp, r, r, n0, d, dinv);
+ qp--;
+ }
+ }
+ else
+ {
+ r = 0;
+ if (ahigh < d_unnorm)
+ {
+ r = ahigh << shift;
+ *qp-- = 0;
+ size--;
+ if (size == 0)
+ goto done_integer;
+ }
+
+ n1 = ap[size-1];
+ r |= n1 >> (GMP_LIMB_BITS - shift);
+
+ for (i = size-2; i >= 0; i--)
+ {
+ ASSERT (r < d);
+ n0 = ap[i];
+ udiv_qrnnd_preinv (*qp, r, r,
+ ((n1 << shift) | (n0 >> (GMP_LIMB_BITS - shift))),
+ d, dinv);
+ qp--;
+ n1 = n0;
+ }
+ udiv_qrnnd_preinv (*qp, r, r, n1 << shift, d, dinv);
+ qp--;
+ }
+
+ done_integer:
+ for (i = 0; i < xsize; i++)
+ {
+ udiv_qrnnd_preinv (*qp, r, r, CNST_LIMB(0), d, dinv);
+ qp--;
+ }
+
+ return r >> shift;
+}
+
+#endif /* USE_PREINV_DIVREM_1 */
diff --git a/gmp/mpn/generic/pre_mod_1.c b/gmp/mpn/generic/pre_mod_1.c
new file mode 100644
index 0000000000..cb38f4a48f
--- /dev/null
+++ b/gmp/mpn/generic/pre_mod_1.c
@@ -0,0 +1,62 @@
+/* mpn_preinv_mod_1 (up, un, d, dinv) -- Divide (UP,,UN) by the normalized D.
+ DINV should be 2^(2*GMP_LIMB_BITS) / D - 2^GMP_LIMB_BITS.
+ Return the single-limb remainder.
+
+Copyright 1991, 1993, 1994, 2000-2002, 2004, 2005 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* This function used to be documented, but is now considered obsolete. It
+ continues to exist for binary compatibility, even when not required
+ internally. */
+
+mp_limb_t
+mpn_preinv_mod_1 (mp_srcptr up, mp_size_t un, mp_limb_t d, mp_limb_t dinv)
+{
+ mp_size_t i;
+ mp_limb_t n0, r;
+
+ ASSERT (un >= 1);
+ ASSERT (d & GMP_LIMB_HIGHBIT);
+
+ r = up[un - 1];
+ if (r >= d)
+ r -= d;
+
+ for (i = un - 2; i >= 0; i--)
+ {
+ n0 = up[i];
+ udiv_rnnd_preinv (r, r, n0, d, dinv);
+ }
+ return r;
+}
diff --git a/gmp/mpn/generic/random.c b/gmp/mpn/generic/random.c
new file mode 100644
index 0000000000..5489becf4d
--- /dev/null
+++ b/gmp/mpn/generic/random.c
@@ -0,0 +1,51 @@
+/* mpn_random -- Generate random numbers.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_random (mp_ptr ptr, mp_size_t size)
+{
+ gmp_randstate_ptr rands;
+
+ /* FIXME: Is size==0 supposed to be allowed? */
+ ASSERT (size >= 0);
+
+ if (size == 0)
+ return;
+
+ rands = RANDS;
+ _gmp_rand (ptr, rands, size * GMP_NUMB_BITS);
+
+ /* Make sure the most significant limb is non-zero. */
+ while (ptr[size-1] == 0)
+ _gmp_rand (&ptr[size-1], rands, GMP_NUMB_BITS);
+}
diff --git a/gmp/mpn/generic/random2.c b/gmp/mpn/generic/random2.c
new file mode 100644
index 0000000000..980b15367f
--- /dev/null
+++ b/gmp/mpn/generic/random2.c
@@ -0,0 +1,106 @@
+/* mpn_random2 -- Generate random numbers with relatively long strings
+ of ones and zeroes. Suitable for border testing.
+
+Copyright 1992-1994, 1996, 2000-2002, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+static void gmp_rrandomb (mp_ptr, gmp_randstate_t, mp_bitcnt_t);
+
+/* Ask _gmp_rand for 32 bits per call unless that's more than a limb can hold.
+ Thus, we get the same random number sequence in the common cases.
+ FIXME: We should always generate the same random number sequence! */
+#if GMP_NUMB_BITS < 32
+#define BITS_PER_RANDCALL GMP_NUMB_BITS
+#else
+#define BITS_PER_RANDCALL 32
+#endif
+
+void
+mpn_random2 (mp_ptr rp, mp_size_t n)
+{
+ gmp_randstate_ptr rstate = RANDS;
+ int bit_pos; /* bit number of least significant bit where
+ next bit field to be inserted */
+ mp_limb_t ran, ranm; /* buffer for random bits */
+
+ /* FIXME: Is n==0 supposed to be allowed? */
+ ASSERT (n >= 0);
+
+ _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL);
+ ran = ranm;
+
+ /* Start off at a random bit position in the most significant limb. */
+ bit_pos = ran % GMP_NUMB_BITS;
+
+ gmp_rrandomb (rp, rstate, n * GMP_NUMB_BITS - bit_pos);
+}
+
+static void
+gmp_rrandomb (mp_ptr rp, gmp_randstate_t rstate, mp_bitcnt_t nbits)
+{
+ mp_bitcnt_t bi;
+ mp_limb_t ranm; /* buffer for random bits */
+ unsigned cap_chunksize, chunksize;
+ mp_size_t i;
+
+ /* Set entire result to 111..1 */
+ i = BITS_TO_LIMBS (nbits) - 1;
+ rp[i] = GMP_NUMB_MAX >> (GMP_NUMB_BITS - (nbits % GMP_NUMB_BITS)) % GMP_NUMB_BITS;
+ for (i = i - 1; i >= 0; i--)
+ rp[i] = GMP_NUMB_MAX;
+
+ _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL);
+ cap_chunksize = nbits / (ranm % 4 + 1);
+ cap_chunksize += cap_chunksize == 0; /* make it at least 1 */
+
+ bi = nbits;
+
+ for (;;)
+ {
+ _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL);
+ chunksize = 1 + ranm % cap_chunksize;
+ bi = (bi < chunksize) ? 0 : bi - chunksize;
+
+ if (bi == 0)
+ break; /* low chunk is ...1 */
+
+ rp[bi / GMP_NUMB_BITS] ^= CNST_LIMB (1) << bi % GMP_NUMB_BITS;
+
+ _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL);
+ chunksize = 1 + ranm % cap_chunksize;
+ bi = (bi < chunksize) ? 0 : bi - chunksize;
+
+ mpn_incr_u (rp + bi / GMP_NUMB_BITS, CNST_LIMB (1) << bi % GMP_NUMB_BITS);
+
+ if (bi == 0)
+ break; /* low chunk is ...0 */
+ }
+}
diff --git a/gmp/mpn/generic/redc_1.c b/gmp/mpn/generic/redc_1.c
new file mode 100644
index 0000000000..0d33421f63
--- /dev/null
+++ b/gmp/mpn/generic/redc_1.c
@@ -0,0 +1,57 @@
+/* mpn_redc_1. Set rp[] <- up[]/R^n mod mp[]. Clobber up[].
+ mp[] is n limbs; up[] is 2n limbs.
+
+ THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES.
+
+Copyright (C) 2000-2002, 2004, 2008, 2009, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+mpn_redc_1 (mp_ptr rp, mp_ptr up, mp_srcptr mp, mp_size_t n, mp_limb_t invm)
+{
+ mp_size_t j;
+ mp_limb_t cy;
+
+ ASSERT (n > 0);
+ ASSERT_MPN (up, 2*n);
+
+ for (j = n - 1; j >= 0; j--)
+ {
+ cy = mpn_addmul_1 (up, mp, n, (up[0] * invm) & GMP_NUMB_MASK);
+ ASSERT (up[0] == 0);
+ up[0] = cy;
+ up++;
+ }
+
+ cy = mpn_add_n (rp, up, up - n, n);
+ return cy;
+}
diff --git a/gmp/mpn/generic/redc_2.c b/gmp/mpn/generic/redc_2.c
new file mode 100644
index 0000000000..07d90fa20d
--- /dev/null
+++ b/gmp/mpn/generic/redc_2.c
@@ -0,0 +1,110 @@
+/* mpn_redc_2. Set rp[] <- up[]/R^n mod mp[]. Clobber up[].
+ mp[] is n limbs; up[] is 2n limbs.
+
+ THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES.
+
+Copyright (C) 2000-2002, 2004, 2008, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#if GMP_NAIL_BITS != 0
+you lose
+#endif
+
+/* For testing purposes, define our own mpn_addmul_2 if there is none already
+ available. */
+#ifndef HAVE_NATIVE_mpn_addmul_2
+#undef mpn_addmul_2
+static mp_limb_t
+mpn_addmul_2 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_srcptr vp)
+{
+ rp[n] = mpn_addmul_1 (rp, up, n, vp[0]);
+ return mpn_addmul_1 (rp + 1, up, n, vp[1]);
+}
+#endif
+
+#if defined (__GNUC__) && defined (__ia64) && W_TYPE_SIZE == 64
+#define umul2low(ph, pl, uh, ul, vh, vl) \
+ do { \
+ mp_limb_t _ph, _pl; \
+ __asm__ ("xma.hu %0 = %3, %5, f0\n\t" \
+ "xma.l %1 = %3, %5, f0\n\t" \
+ ";;\n\t" \
+ "xma.l %0 = %3, %4, %0\n\t" \
+ ";;\n\t" \
+ "xma.l %0 = %2, %5, %0" \
+ : "=&f" (ph), "=&f" (pl) \
+ : "f" (uh), "f" (ul), "f" (vh), "f" (vl)); \
+ } while (0)
+#endif
+
+#ifndef umul2low
+#define umul2low(ph, pl, uh, ul, vh, vl) \
+ do { \
+ mp_limb_t _ph, _pl; \
+ umul_ppmm (_ph, _pl, ul, vl); \
+ (ph) = _ph + (ul) * (vh) + (uh) * (vl); \
+ (pl) = _pl; \
+ } while (0)
+#endif
+
+mp_limb_t
+mpn_redc_2 (mp_ptr rp, mp_ptr up, mp_srcptr mp, mp_size_t n, mp_srcptr mip)
+{
+ mp_limb_t q[2];
+ mp_size_t j;
+ mp_limb_t upn;
+ mp_limb_t cy;
+
+ ASSERT (n > 0);
+ ASSERT_MPN (up, 2*n);
+
+ if ((n & 1) != 0)
+ {
+ up[0] = mpn_addmul_1 (up, mp, n, (up[0] * mip[0]) & GMP_NUMB_MASK);
+ up++;
+ }
+
+ for (j = n - 2; j >= 0; j -= 2)
+ {
+ umul2low (q[1], q[0], mip[1], mip[0], up[1], up[0]);
+ upn = up[n]; /* mpn_addmul_2 overwrites this */
+ up[1] = mpn_addmul_2 (up, mp, n, q);
+ up[0] = up[n];
+ up[n] = upn;
+ up += 2;
+ }
+
+ cy = mpn_add_n (rp, up, up - n, n);
+ return cy;
+}
diff --git a/gmp/mpn/generic/redc_n.c b/gmp/mpn/generic/redc_n.c
new file mode 100644
index 0000000000..c3d0cfe7fa
--- /dev/null
+++ b/gmp/mpn/generic/redc_n.c
@@ -0,0 +1,81 @@
+/* mpn_redc_n. Set rp[] <- up[]/R^n mod mp[]. Clobber up[].
+ mp[] is n limbs; up[] is 2n limbs, the inverse ip[] is n limbs.
+
+ THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES.
+
+Copyright 2009, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*
+ TODO
+
+ * We assume mpn_mulmod_bnm1 is always faster than plain mpn_mul_n (or a
+ future mpn_mulhi) for the range we will be called. Follow up that
+ assumption.
+
+ * Decrease scratch usage.
+
+ * Consider removing the residue canonicalisation.
+*/
+
+void
+mpn_redc_n (mp_ptr rp, mp_ptr up, mp_srcptr mp, mp_size_t n, mp_srcptr ip)
+{
+ mp_ptr xp, yp, scratch;
+ mp_limb_t cy;
+ mp_size_t rn;
+ TMP_DECL;
+ TMP_MARK;
+
+ ASSERT (n > 8);
+
+ rn = mpn_mulmod_bnm1_next_size (n);
+
+ scratch = TMP_ALLOC_LIMBS (n + rn + mpn_mulmod_bnm1_itch (rn, n, n));
+
+ xp = scratch;
+ mpn_mullo_n (xp, up, ip, n);
+
+ yp = scratch + n;
+ mpn_mulmod_bnm1 (yp, rn, xp, n, mp, n, scratch + n + rn);
+
+ ASSERT_ALWAYS (2 * n > rn); /* could handle this */
+
+ cy = mpn_sub_n (yp + rn, yp, up, 2*n - rn); /* undo wrap around */
+ MPN_DECR_U (yp + 2*n - rn, rn, cy);
+
+ cy = mpn_sub_n (rp, up + n, yp + n, n);
+ if (cy != 0)
+ mpn_add_n (rp, rp, mp, n);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/remove.c b/gmp/mpn/generic/remove.c
new file mode 100644
index 0000000000..ef1a06ea14
--- /dev/null
+++ b/gmp/mpn/generic/remove.c
@@ -0,0 +1,172 @@
+/* mpn_remove -- divide out all multiples of odd mpn number from another mpn
+ number.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2009, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if GMP_LIMB_BITS > 50
+#define LOG 50
+#else
+#define LOG GMP_LIMB_BITS
+#endif
+
+
+/* Input: U = {up,un}, V = {vp,vn} must be odd, cap
+ Ouput W = {wp,*wn} allocation need is exactly *wn
+
+ Set W = U / V^k, where k is the largest integer <= cap such that the
+ division yields an integer.
+
+ FIXME: We currently allow any operand overlap. This is quite non mpn-ish
+ and might be changed, since it cost significant temporary space.
+ * If we require W to have space for un + 1 limbs, we could save qp or qp2
+ (but we will still need to copy things into wp 50% of the time).
+ * If we allow ourselves to clobber U, we could save the other of qp and qp2,
+ and the initial COPY (but also here we would need un + 1 limbs).
+*/
+
+/* FIXME: We need to wrap mpn_bdiv_qr due to the itch interface. This need
+ indicates a flaw in the current itch mechanism: Which operands not greater
+ than un,un will incur the worst itch? We need a parallel foo_maxitch set
+ of functions. */
+static void
+mpn_bdiv_qr_wrap (mp_ptr qp, mp_ptr rp,
+ mp_srcptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn)
+{
+ mp_ptr scratch_out;
+ TMP_DECL;
+
+ TMP_MARK;
+ scratch_out = TMP_ALLOC_LIMBS (mpn_bdiv_qr_itch (nn, dn));
+ mpn_bdiv_qr (qp, rp, np, nn, dp, dn, scratch_out);
+
+ TMP_FREE;
+}
+
+mp_bitcnt_t
+mpn_remove (mp_ptr wp, mp_size_t *wn,
+ mp_ptr up, mp_size_t un, mp_ptr vp, mp_size_t vn,
+ mp_bitcnt_t cap)
+{
+ mp_ptr pwpsp[LOG];
+ mp_size_t pwpsn[LOG];
+ mp_size_t npowers;
+ mp_ptr tp, qp, np, pp, qp2;
+ mp_size_t pn, nn, qn, i;
+ mp_bitcnt_t pwr;
+ TMP_DECL;
+
+ ASSERT (un > 0);
+ ASSERT (vn > 0);
+ ASSERT (vp[0] % 2 != 0); /* 2-adic division wants odd numbers */
+ ASSERT (vn > 1 || vp[0] > 1); /* else we would loop indefinitely */
+
+ TMP_MARK;
+
+ tp = TMP_ALLOC_LIMBS ((un + 1 + vn) / 2); /* remainder */
+ qp = TMP_ALLOC_LIMBS (un + 1); /* quotient, alternating */
+ qp2 = TMP_ALLOC_LIMBS (un + 1); /* quotient, alternating */
+ pp = vp;
+ pn = vn;
+
+ MPN_COPY (qp, up, un);
+ qn = un;
+
+ npowers = 0;
+ while (qn >= pn)
+ {
+ qp[qn] = 0;
+ mpn_bdiv_qr_wrap (qp2, tp, qp, qn + 1, pp, pn);
+ if (!mpn_zero_p (tp, pn))
+ break; /* could not divide by V^npowers */
+
+ MP_PTR_SWAP (qp, qp2);
+ qn = qn - pn;
+ qn += qp[qn] != 0;
+
+ pwpsp[npowers] = pp;
+ pwpsn[npowers] = pn;
+ npowers++;
+
+ if (((mp_bitcnt_t) 2 << npowers) - 1 > cap)
+ break;
+
+ nn = 2 * pn - 1; /* next power will be at least this large */
+ if (nn > qn)
+ break; /* next power would be overlarge */
+
+ if (npowers == 1) /* Alloc once, but only if it's needed */
+ np = TMP_ALLOC_LIMBS (qn + LOG); /* powers of V */
+ else
+ np += pn;
+
+ mpn_sqr (np, pp, pn);
+ pn = nn + (np[nn] != 0);
+ pp = np;
+ }
+
+ pwr = ((mp_bitcnt_t) 1 << npowers) - 1;
+
+ for (i = npowers - 1; i >= 0; i--)
+ {
+ pn = pwpsn[i];
+ if (qn < pn)
+ continue;
+
+ if (pwr + ((mp_bitcnt_t) 1 << i) > cap)
+ continue; /* V^i would bring us past cap */
+
+ qp[qn] = 0;
+ mpn_bdiv_qr_wrap (qp2, tp, qp, qn + 1, pwpsp[i], pn);
+ if (!mpn_zero_p (tp, pn))
+ continue; /* could not divide by V^i */
+
+ MP_PTR_SWAP (qp, qp2);
+ qn = qn - pn;
+ qn += qp[qn] != 0;
+
+ pwr += (mp_bitcnt_t) 1 << i;
+ }
+
+ MPN_COPY (wp, qp, qn);
+ *wn = qn;
+
+ TMP_FREE;
+
+ return pwr;
+}
diff --git a/gmp/mpn/generic/rootrem.c b/gmp/mpn/generic/rootrem.c
new file mode 100644
index 0000000000..2edc74baa3
--- /dev/null
+++ b/gmp/mpn/generic/rootrem.c
@@ -0,0 +1,415 @@
+/* mpn_rootrem(rootp,remp,ap,an,nth) -- Compute the nth root of {ap,an}, and
+ store the truncated integer part at rootp and the remainder at remp.
+
+ Contributed by Paul Zimmermann (algorithm) and
+ Paul Zimmermann and Torbjorn Granlund (implementation).
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL, AND HAVE MUTABLE INTERFACES. IT'S
+ ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT'S ALMOST
+ GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2002, 2005, 2009-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* FIXME:
+ This implementation is not optimal when remp == NULL, since the complexity
+ is M(n), whereas it should be M(n/k) on average.
+*/
+
+#include <stdio.h> /* for NULL */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+static mp_size_t mpn_rootrem_internal (mp_ptr, mp_ptr, mp_srcptr, mp_size_t,
+ mp_limb_t, int);
+
+#define MPN_RSHIFT(cy,rp,up,un,cnt) \
+ do { \
+ if ((cnt) != 0) \
+ cy = mpn_rshift (rp, up, un, cnt); \
+ else \
+ { \
+ MPN_COPY_INCR (rp, up, un); \
+ cy = 0; \
+ } \
+ } while (0)
+
+#define MPN_LSHIFT(cy,rp,up,un,cnt) \
+ do { \
+ if ((cnt) != 0) \
+ cy = mpn_lshift (rp, up, un, cnt); \
+ else \
+ { \
+ MPN_COPY_DECR (rp, up, un); \
+ cy = 0; \
+ } \
+ } while (0)
+
+
+/* Put in {rootp, ceil(un/k)} the kth root of {up, un}, rounded toward zero.
+ If remp <> NULL, put in {remp, un} the remainder.
+ Return the size (in limbs) of the remainder if remp <> NULL,
+ or a non-zero value iff the remainder is non-zero when remp = NULL.
+ Assumes:
+ (a) up[un-1] is not zero
+ (b) rootp has at least space for ceil(un/k) limbs
+ (c) remp has at least space for un limbs (in case remp <> NULL)
+ (d) the operands do not overlap.
+
+ The auxiliary memory usage is 3*un+2 if remp = NULL,
+ and 2*un+2 if remp <> NULL. FIXME: This is an incorrect comment.
+*/
+mp_size_t
+mpn_rootrem (mp_ptr rootp, mp_ptr remp,
+ mp_srcptr up, mp_size_t un, mp_limb_t k)
+{
+ mp_size_t m;
+ ASSERT (un > 0);
+ ASSERT (up[un - 1] != 0);
+ ASSERT (k > 1);
+
+ m = (un - 1) / k; /* ceil(un/k) - 1 */
+ if (remp == NULL && m > 2)
+ /* Pad {up,un} with k zero limbs. This will produce an approximate root
+ with one more limb, allowing us to compute the exact integral result. */
+ {
+ mp_ptr sp, wp;
+ mp_size_t rn, sn, wn;
+ TMP_DECL;
+ TMP_MARK;
+ wn = un + k;
+ wp = TMP_ALLOC_LIMBS (wn); /* will contain the padded input */
+ sn = m + 2; /* ceil(un/k) + 1 */
+ sp = TMP_ALLOC_LIMBS (sn); /* approximate root of padded input */
+ MPN_COPY (wp + k, up, un);
+ MPN_ZERO (wp, k);
+ rn = mpn_rootrem_internal (sp, NULL, wp, wn, k, 1);
+ /* The approximate root S = {sp,sn} is either the correct root of
+ {sp,sn}, or 1 too large. Thus unless the least significant limb of
+ S is 0 or 1, we can deduce the root of {up,un} is S truncated by one
+ limb. (In case sp[0]=1, we can deduce the root, but not decide
+ whether it is exact or not.) */
+ MPN_COPY (rootp, sp + 1, sn - 1);
+ TMP_FREE;
+ return rn;
+ }
+ else
+ {
+ return mpn_rootrem_internal (rootp, remp, up, un, k, 0);
+ }
+}
+
+/* if approx is non-zero, does not compute the final remainder */
+static mp_size_t
+mpn_rootrem_internal (mp_ptr rootp, mp_ptr remp, mp_srcptr up, mp_size_t un,
+ mp_limb_t k, int approx)
+{
+ mp_ptr qp, rp, sp, wp, scratch;
+ mp_size_t qn, rn, sn, wn, nl, bn;
+ mp_limb_t save, save2, cy;
+ unsigned long int unb; /* number of significant bits of {up,un} */
+ unsigned long int xnb; /* number of significant bits of the result */
+ unsigned long b, kk;
+ unsigned long sizes[GMP_NUMB_BITS + 1];
+ int ni, i;
+ int c;
+ int logk;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ if (remp == NULL)
+ {
+ rp = TMP_ALLOC_LIMBS (un + 1); /* will contain the remainder */
+ scratch = rp; /* used by mpn_div_q */
+ }
+ else
+ {
+ scratch = TMP_ALLOC_LIMBS (un + 1); /* used by mpn_div_q */
+ rp = remp;
+ }
+ sp = rootp;
+
+ MPN_SIZEINBASE_2EXP(unb, up, un, 1);
+ /* unb is the number of bits of the input U */
+
+ xnb = (unb - 1) / k + 1; /* ceil (unb / k) */
+ /* xnb is the number of bits of the root R */
+
+ if (xnb == 1) /* root is 1 */
+ {
+ if (remp == NULL)
+ remp = rp;
+ mpn_sub_1 (remp, up, un, (mp_limb_t) 1);
+ MPN_NORMALIZE (remp, un); /* There should be at most one zero limb,
+ if we demand u to be normalized */
+ rootp[0] = 1;
+ TMP_FREE;
+ return un;
+ }
+
+ /* We initialize the algorithm with a 1-bit approximation to zero: since we
+ know the root has exactly xnb bits, we write r0 = 2^(xnb-1), so that
+ r0^k = 2^(k*(xnb-1)), that we subtract to the input. */
+ kk = k * (xnb - 1); /* number of truncated bits in the input */
+ rn = un - kk / GMP_NUMB_BITS; /* number of limbs of the non-truncated part */
+ MPN_RSHIFT (cy, rp, up + kk / GMP_NUMB_BITS, rn, kk % GMP_NUMB_BITS);
+ mpn_sub_1 (rp, rp, rn, 1); /* subtract the initial approximation: since
+ the non-truncated part is less than 2^k, it
+ is <= k bits: rn <= ceil(k/GMP_NUMB_BITS) */
+ sp[0] = 1; /* initial approximation */
+ sn = 1; /* it has one limb */
+
+ for (logk = 1; ((k - 1) >> logk) != 0; logk++)
+ ;
+ /* logk = ceil(log(k)/log(2)) */
+
+ b = xnb - 1; /* number of remaining bits to determine in the kth root */
+ ni = 0;
+ while (b != 0)
+ {
+ /* invariant: here we want b+1 total bits for the kth root */
+ sizes[ni] = b;
+ /* if c is the new value of b, this means that we'll go from a root
+ of c+1 bits (say s') to a root of b+1 bits.
+ It is proved in the book "Modern Computer Arithmetic" from Brent
+ and Zimmermann, Chapter 1, that
+ if s' >= k*beta, then at most one correction is necessary.
+ Here beta = 2^(b-c), and s' >= 2^c, thus it suffices that
+ c >= ceil((b + log2(k))/2). */
+ b = (b + logk + 1) / 2;
+ if (b >= sizes[ni])
+ b = sizes[ni] - 1; /* add just one bit at a time */
+ ni++;
+ }
+ sizes[ni] = 0;
+ ASSERT_ALWAYS (ni < GMP_NUMB_BITS + 1);
+ /* We have sizes[0] = b > sizes[1] > ... > sizes[ni] = 0 with
+ sizes[i] <= 2 * sizes[i+1].
+ Newton iteration will first compute sizes[ni-1] extra bits,
+ then sizes[ni-2], ..., then sizes[0] = b. */
+
+ /* qp and wp need enough space to store S'^k where S' is an approximate
+ root. Since S' can be as large as S+2, the worst case is when S=2 and
+ S'=4. But then since we know the number of bits of S in advance, S'
+ can only be 3 at most. Similarly for S=4, then S' can be 6 at most.
+ So the worst case is S'/S=3/2, thus S'^k <= (3/2)^k * S^k. Since S^k
+ fits in un limbs, the number of extra limbs needed is bounded by
+ ceil(k*log2(3/2)/GMP_NUMB_BITS). */
+#define EXTRA 2 + (mp_size_t) (0.585 * (double) k / (double) GMP_NUMB_BITS)
+ qp = TMP_ALLOC_LIMBS (un + EXTRA); /* will contain quotient and remainder
+ of R/(k*S^(k-1)), and S^k */
+ wp = TMP_ALLOC_LIMBS (un + EXTRA); /* will contain S^(k-1), k*S^(k-1),
+ and temporary for mpn_pow_1 */
+
+ wp[0] = 1; /* {sp,sn}^(k-1) = 1 */
+ wn = 1;
+ for (i = ni; i != 0; i--)
+ {
+ /* 1: loop invariant:
+ {sp, sn} is the current approximation of the root, which has
+ exactly 1 + sizes[ni] bits.
+ {rp, rn} is the current remainder
+ {wp, wn} = {sp, sn}^(k-1)
+ kk = number of truncated bits of the input
+ */
+ b = sizes[i - 1] - sizes[i]; /* number of bits to compute in that
+ iteration */
+
+ /* Reinsert a low zero limb if we normalized away the entire remainder */
+ if (rn == 0)
+ {
+ rp[0] = 0;
+ rn = 1;
+ }
+
+ /* first multiply the remainder by 2^b */
+ MPN_LSHIFT (cy, rp + b / GMP_NUMB_BITS, rp, rn, b % GMP_NUMB_BITS);
+ rn = rn + b / GMP_NUMB_BITS;
+ if (cy != 0)
+ {
+ rp[rn] = cy;
+ rn++;
+ }
+
+ kk = kk - b;
+
+ /* 2: current buffers: {sp,sn}, {rp,rn}, {wp,wn} */
+
+ /* Now insert bits [kk,kk+b-1] from the input U */
+ bn = b / GMP_NUMB_BITS; /* lowest limb from high part of rp[] */
+ save = rp[bn];
+ /* nl is the number of limbs in U which contain bits [kk,kk+b-1] */
+ nl = 1 + (kk + b - 1) / GMP_NUMB_BITS - (kk / GMP_NUMB_BITS);
+ /* nl = 1 + floor((kk + b - 1) / GMP_NUMB_BITS)
+ - floor(kk / GMP_NUMB_BITS)
+ <= 1 + (kk + b - 1) / GMP_NUMB_BITS
+ - (kk - GMP_NUMB_BITS + 1) / GMP_NUMB_BITS
+ = 2 + (b - 2) / GMP_NUMB_BITS
+ thus since nl is an integer:
+ nl <= 2 + floor(b/GMP_NUMB_BITS) <= 2 + bn. */
+ /* we have to save rp[bn] up to rp[nl-1], i.e. 1 or 2 limbs */
+ if (nl - 1 > bn)
+ save2 = rp[bn + 1];
+ MPN_RSHIFT (cy, rp, up + kk / GMP_NUMB_BITS, nl, kk % GMP_NUMB_BITS);
+ /* set to zero high bits of rp[bn] */
+ rp[bn] &= ((mp_limb_t) 1 << (b % GMP_NUMB_BITS)) - 1;
+ /* restore corresponding bits */
+ rp[bn] |= save;
+ if (nl - 1 > bn)
+ rp[bn + 1] = save2; /* the low b bits go in rp[0..bn] only, since
+ they start by bit 0 in rp[0], so they use
+ at most ceil(b/GMP_NUMB_BITS) limbs */
+
+ /* 3: current buffers: {sp,sn}, {rp,rn}, {wp,wn} */
+
+ /* compute {wp, wn} = k * {sp, sn}^(k-1) */
+ cy = mpn_mul_1 (wp, wp, wn, k);
+ wp[wn] = cy;
+ wn += cy != 0;
+
+ /* 4: current buffers: {sp,sn}, {rp,rn}, {wp,wn} */
+
+ /* now divide {rp, rn} by {wp, wn} to get the low part of the root */
+ if (rn < wn)
+ {
+ qn = 0;
+ }
+ else
+ {
+ qn = rn - wn; /* expected quotient size */
+ mpn_div_q (qp, rp, rn, wp, wn, scratch);
+ qn += qp[qn] != 0;
+ }
+
+ /* 5: current buffers: {sp,sn}, {qp,qn}.
+ Note: {rp,rn} is not needed any more since we'll compute it from
+ scratch at the end of the loop.
+ */
+
+ /* Number of limbs used by b bits, when least significant bit is
+ aligned to least limb */
+ bn = (b - 1) / GMP_NUMB_BITS + 1;
+
+ /* the quotient should be smaller than 2^b, since the previous
+ approximation was correctly rounded toward zero */
+ if (qn > bn || (qn == bn && (b % GMP_NUMB_BITS != 0) &&
+ qp[qn - 1] >= ((mp_limb_t) 1 << (b % GMP_NUMB_BITS))))
+ {
+ qn = b / GMP_NUMB_BITS + 1; /* b+1 bits */
+ MPN_ZERO (qp, qn);
+ qp[qn - 1] = (mp_limb_t) 1 << (b % GMP_NUMB_BITS);
+ MPN_DECR_U (qp, qn, 1);
+ qn -= qp[qn - 1] == 0;
+ }
+
+ /* 6: current buffers: {sp,sn}, {qp,qn} */
+
+ /* multiply the root approximation by 2^b */
+ MPN_LSHIFT (cy, sp + b / GMP_NUMB_BITS, sp, sn, b % GMP_NUMB_BITS);
+ sn = sn + b / GMP_NUMB_BITS;
+ if (cy != 0)
+ {
+ sp[sn] = cy;
+ sn++;
+ }
+
+ /* 7: current buffers: {sp,sn}, {qp,qn} */
+
+ ASSERT_ALWAYS (bn >= qn); /* this is ok since in the case qn > bn
+ above, q is set to 2^b-1, which has
+ exactly bn limbs */
+
+ /* Combine sB and q to form sB + q. */
+ save = sp[b / GMP_NUMB_BITS];
+ MPN_COPY (sp, qp, qn);
+ MPN_ZERO (sp + qn, bn - qn);
+ sp[b / GMP_NUMB_BITS] |= save;
+
+ /* 8: current buffer: {sp,sn} */
+
+ /* Since each iteration treats b bits from the root and thus k*b bits
+ from the input, and we already considered b bits from the input,
+ we now have to take another (k-1)*b bits from the input. */
+ kk -= (k - 1) * b; /* remaining input bits */
+ /* {rp, rn} = floor({up, un} / 2^kk) */
+ MPN_RSHIFT (cy, rp, up + kk / GMP_NUMB_BITS, un - kk / GMP_NUMB_BITS, kk % GMP_NUMB_BITS);
+ rn = un - kk / GMP_NUMB_BITS;
+ rn -= rp[rn - 1] == 0;
+
+ /* 9: current buffers: {sp,sn}, {rp,rn} */
+
+ for (c = 0;; c++)
+ {
+ /* Compute S^k in {qp,qn}. */
+ if (i == 1)
+ {
+ /* Last iteration: we don't need W anymore. */
+ /* mpn_pow_1 requires that both qp and wp have enough space to
+ store the result {sp,sn}^k + 1 limb */
+ approx = approx && (sp[0] > 1);
+ qn = (approx == 0) ? mpn_pow_1 (qp, sp, sn, k, wp) : 0;
+ }
+ else
+ {
+ /* W <- S^(k-1) for the next iteration,
+ and S^k = W * S. */
+ wn = mpn_pow_1 (wp, sp, sn, k - 1, qp);
+ mpn_mul (qp, wp, wn, sp, sn);
+ qn = wn + sn;
+ qn -= qp[qn - 1] == 0;
+ }
+
+ /* if S^k > floor(U/2^kk), the root approximation was too large */
+ if (qn > rn || (qn == rn && mpn_cmp (qp, rp, rn) > 0))
+ MPN_DECR_U (sp, sn, 1);
+ else
+ break;
+ }
+
+ /* 10: current buffers: {sp,sn}, {rp,rn}, {qp,qn}, {wp,wn} */
+
+ ASSERT_ALWAYS (c <= 1);
+ ASSERT_ALWAYS (rn >= qn);
+
+ /* R = R - Q = floor(U/2^kk) - S^k */
+ if (i > 1 || approx == 0)
+ {
+ mpn_sub (rp, rp, rn, qp, qn);
+ MPN_NORMALIZE (rp, rn);
+ }
+ /* otherwise we have rn > 0, thus the return value is ok */
+
+ /* 11: current buffers: {sp,sn}, {rp,rn}, {wp,wn} */
+ }
+
+ TMP_FREE;
+ return rn;
+}
diff --git a/gmp/mpn/generic/rshift.c b/gmp/mpn/generic/rshift.c
new file mode 100644
index 0000000000..ec61f2f7e2
--- /dev/null
+++ b/gmp/mpn/generic/rshift.c
@@ -0,0 +1,70 @@
+/* mpn_rshift -- Shift right low level.
+
+Copyright 1991, 1993, 1994, 1996, 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Shift U (pointed to by up and N limbs long) cnt bits to the right
+ and store the n least significant limbs of the result at rp.
+ The bits shifted out to the right are returned.
+
+ Argument constraints:
+ 1. 0 < cnt < GMP_NUMB_BITS.
+ 2. If the result is to be written over the input, rp must be <= up.
+*/
+
+mp_limb_t
+mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt)
+{
+ mp_limb_t high_limb, low_limb;
+ unsigned int tnc;
+ mp_size_t i;
+ mp_limb_t retval;
+
+ ASSERT (n >= 1);
+ ASSERT (cnt >= 1);
+ ASSERT (cnt < GMP_NUMB_BITS);
+ ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
+
+ tnc = GMP_NUMB_BITS - cnt;
+ high_limb = *up++;
+ retval = (high_limb << tnc) & GMP_NUMB_MASK;
+ low_limb = high_limb >> cnt;
+
+ for (i = n - 1; i != 0; i--)
+ {
+ high_limb = *up++;
+ *rp++ = low_limb | ((high_limb << tnc) & GMP_NUMB_MASK);
+ low_limb = high_limb >> cnt;
+ }
+ *rp = low_limb;
+
+ return retval;
+}
diff --git a/gmp/mpn/generic/sbpi1_bdiv_q.c b/gmp/mpn/generic/sbpi1_bdiv_q.c
new file mode 100644
index 0000000000..645b1d9b6a
--- /dev/null
+++ b/gmp/mpn/generic/sbpi1_bdiv_q.c
@@ -0,0 +1,100 @@
+/* mpn_sbpi1_bdiv_q -- schoolbook Hensel division with precomputed inverse,
+ returning quotient only.
+
+ Contributed to the GNU project by Niels Möller.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL FUNCTIONS WITH MUTABLE INTERFACES.
+ IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS
+ ALMOST GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2005, 2006, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Computes Q = N / D mod B^nn, destroys N.
+
+ D must be odd. dinv is (-D)^-1 mod B.
+
+
+ The straightforward way to compute Q is to cancel one limb at a time, using
+
+ qp[i] = D^{-1} * np[i] (mod B)
+ N -= B^i * qp[i] * D
+
+ But we prefer addition to subtraction, since mpn_addmul_1 is often faster
+ than mpn_submul_1. Q = - N / D can be computed by iterating
+
+ qp[i] = (-D)^{-1} * np[i] (mod B)
+ N += B^i * qp[i] * D
+
+ And then we flip the sign, -Q = (not Q) + 1. */
+
+void
+mpn_sbpi1_bdiv_q (mp_ptr qp,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_limb_t dinv)
+{
+ mp_size_t i;
+ mp_limb_t cy, q;
+
+ ASSERT (dn > 0);
+ ASSERT (nn >= dn);
+ ASSERT ((dp[0] & 1) != 0);
+ /* FIXME: Add ASSERTs for allowable overlapping; i.e., that qp = np is OK,
+ but some over N/Q overlaps will not work. */
+
+ for (i = nn - dn; i > 0; i--)
+ {
+ q = dinv * np[0];
+ cy = mpn_addmul_1 (np, dp, dn, q);
+ mpn_add_1 (np + dn, np + dn, i, cy);
+ ASSERT (np[0] == 0);
+ qp[0] = ~q;
+ qp++;
+ np++;
+ }
+
+ for (i = dn; i > 1; i--)
+ {
+ q = dinv * np[0];
+ mpn_addmul_1 (np, dp, i, q);
+ ASSERT (np[0] == 0);
+ qp[0] = ~q;
+ qp++;
+ np++;
+ }
+
+ /* Final limb */
+ q = dinv * np[0];
+ qp[0] = ~q;
+ mpn_add_1 (qp - nn + 1, qp - nn + 1, nn, 1);
+}
diff --git a/gmp/mpn/generic/sbpi1_bdiv_qr.c b/gmp/mpn/generic/sbpi1_bdiv_qr.c
new file mode 100644
index 0000000000..0e56f58148
--- /dev/null
+++ b/gmp/mpn/generic/sbpi1_bdiv_qr.c
@@ -0,0 +1,119 @@
+/* mpn_sbpi1_bdiv_qr -- schoolbook Hensel division with precomputed inverse,
+ returning quotient and remainder.
+
+ Contributed to the GNU project by Niels Möller.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL FUNCTIONS WITH MUTABLE INTERFACES.
+ IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS
+ ALMOST GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2006, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Computes a binary quotient of size qn = nn - dn.
+ Output:
+
+ Q = N * D^{-1} mod B^qn,
+
+ R = (N - Q * D) * B^(-qn)
+
+ Stores the dn least significant limbs of R at {np + nn - dn, dn},
+ and returns the borrow from the subtraction N - Q*D.
+
+ D must be odd. dinv is (-D)^-1 mod B. */
+
+mp_limb_t
+mpn_sbpi1_bdiv_qr (mp_ptr qp,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn, mp_limb_t dinv)
+{
+ mp_size_t qn;
+ mp_size_t i;
+ mp_limb_t rh;
+ mp_limb_t ql;
+
+ ASSERT (dn > 0);
+ ASSERT (nn > dn);
+ ASSERT ((dp[0] & 1) != 0);
+ /* FIXME: Add ASSERTs for allowable overlapping; i.e., that qp = np is OK,
+ but some over N/Q overlaps will not work. */
+
+ qn = nn - dn;
+
+ rh = 0;
+
+ /* To complete the negation, this value is added to q. */
+ ql = 1;
+ while (qn > dn)
+ {
+ for (i = 0; i < dn; i++)
+ {
+ mp_limb_t q;
+
+ q = dinv * np[i];
+ np[i] = mpn_addmul_1 (np + i, dp, dn, q);
+ qp[i] = ~q;
+ }
+ rh += mpn_add (np + dn, np + dn, qn, np, dn);
+ ql = mpn_add_1 (qp, qp, dn, ql);
+
+ qp += dn; qn -= dn;
+ np += dn; nn -= dn;
+ }
+
+ for (i = 0; i < qn; i++)
+ {
+ mp_limb_t q;
+
+ q = dinv * np[i];
+ np[i] = mpn_addmul_1 (np + i, dp, dn, q);
+ qp[i] = ~q;
+ }
+
+ rh += mpn_add_n (np + dn, np + dn, np, qn);
+ ql = mpn_add_1 (qp, qp, qn, ql);
+
+ if (UNLIKELY (ql > 0))
+ {
+ /* q == 0 */
+ ASSERT (rh == 0);
+ return 0;
+ }
+ else
+ {
+ mp_limb_t cy;
+
+ cy = mpn_sub_n (np + qn, np + qn, dp, dn);
+ ASSERT (cy >= rh);
+ return cy - rh;
+ }
+}
diff --git a/gmp/mpn/generic/sbpi1_div_q.c b/gmp/mpn/generic/sbpi1_div_q.c
new file mode 100644
index 0000000000..3abbd57933
--- /dev/null
+++ b/gmp/mpn/generic/sbpi1_div_q.c
@@ -0,0 +1,303 @@
+/* mpn_sbpi1_div_q -- Schoolbook division using the Möller-Granlund 3/2
+ division algorithm.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2007, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_sbpi1_div_q (mp_ptr qp,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_limb_t dinv)
+{
+ mp_limb_t qh;
+ mp_size_t qn, i;
+ mp_limb_t n1, n0;
+ mp_limb_t d1, d0;
+ mp_limb_t cy, cy1;
+ mp_limb_t q;
+ mp_limb_t flag;
+
+ mp_size_t dn_orig = dn;
+ mp_srcptr dp_orig = dp;
+ mp_ptr np_orig = np;
+
+ ASSERT (dn > 2);
+ ASSERT (nn >= dn);
+ ASSERT ((dp[dn-1] & GMP_NUMB_HIGHBIT) != 0);
+
+ np += nn;
+
+ qn = nn - dn;
+ if (qn + 1 < dn)
+ {
+ dp += dn - (qn + 1);
+ dn = qn + 1;
+ }
+
+ qh = mpn_cmp (np - dn, dp, dn) >= 0;
+ if (qh != 0)
+ mpn_sub_n (np - dn, np - dn, dp, dn);
+
+ qp += qn;
+
+ dn -= 2; /* offset dn by 2 for main division loops,
+ saving two iterations in mpn_submul_1. */
+ d1 = dp[dn + 1];
+ d0 = dp[dn + 0];
+
+ np -= 2;
+
+ n1 = np[1];
+
+ for (i = qn - (dn + 2); i >= 0; i--)
+ {
+ np--;
+ if (UNLIKELY (n1 == d1) && np[1] == d0)
+ {
+ q = GMP_NUMB_MASK;
+ mpn_submul_1 (np - dn, dp, dn + 2, q);
+ n1 = np[1]; /* update n1, last loop's value will now be invalid */
+ }
+ else
+ {
+ udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
+
+ cy = mpn_submul_1 (np - dn, dp, dn, q);
+
+ cy1 = n0 < cy;
+ n0 = (n0 - cy) & GMP_NUMB_MASK;
+ cy = n1 < cy1;
+ n1 -= cy1;
+ np[0] = n0;
+
+ if (UNLIKELY (cy != 0))
+ {
+ n1 += d1 + mpn_add_n (np - dn, np - dn, dp, dn + 1);
+ q--;
+ }
+ }
+
+ *--qp = q;
+ }
+
+ flag = ~CNST_LIMB(0);
+
+ if (dn >= 0)
+ {
+ for (i = dn; i > 0; i--)
+ {
+ np--;
+ if (UNLIKELY (n1 >= (d1 & flag)))
+ {
+ q = GMP_NUMB_MASK;
+ cy = mpn_submul_1 (np - dn, dp, dn + 2, q);
+
+ if (UNLIKELY (n1 != cy))
+ {
+ if (n1 < (cy & flag))
+ {
+ q--;
+ mpn_add_n (np - dn, np - dn, dp, dn + 2);
+ }
+ else
+ flag = 0;
+ }
+ n1 = np[1];
+ }
+ else
+ {
+ udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
+
+ cy = mpn_submul_1 (np - dn, dp, dn, q);
+
+ cy1 = n0 < cy;
+ n0 = (n0 - cy) & GMP_NUMB_MASK;
+ cy = n1 < cy1;
+ n1 -= cy1;
+ np[0] = n0;
+
+ if (UNLIKELY (cy != 0))
+ {
+ n1 += d1 + mpn_add_n (np - dn, np - dn, dp, dn + 1);
+ q--;
+ }
+ }
+
+ *--qp = q;
+
+ /* Truncate operands. */
+ dn--;
+ dp++;
+ }
+
+ np--;
+ if (UNLIKELY (n1 >= (d1 & flag)))
+ {
+ q = GMP_NUMB_MASK;
+ cy = mpn_submul_1 (np, dp, 2, q);
+
+ if (UNLIKELY (n1 != cy))
+ {
+ if (n1 < (cy & flag))
+ {
+ q--;
+ add_ssaaaa (np[1], np[0], np[1], np[0], dp[1], dp[0]);
+ }
+ else
+ flag = 0;
+ }
+ n1 = np[1];
+ }
+ else
+ {
+ udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
+
+ np[0] = n0;
+ np[1] = n1;
+ }
+
+ *--qp = q;
+ }
+ ASSERT_ALWAYS (np[1] == n1);
+ np += 2;
+
+
+ dn = dn_orig;
+ if (UNLIKELY (n1 < (dn & flag)))
+ {
+ mp_limb_t q, x;
+
+ /* The quotient may be too large if the remainder is small. Recompute
+ for above ignored operand parts, until the remainder spills.
+
+ FIXME: The quality of this code isn't the same as the code above.
+ 1. We don't compute things in an optimal order, high-to-low, in order
+ to terminate as quickly as possible.
+ 2. We mess with pointers and sizes, adding and subtracting and
+ adjusting to get things right. It surely could be streamlined.
+ 3. The only termination criteria are that we determine that the
+ quotient needs to be adjusted, or that we have recomputed
+ everything. We should stop when the remainder is so large
+ that no additional subtracting could make it spill.
+ 4. If nothing else, we should not do two loops of submul_1 over the
+ data, instead handle both the triangularization and chopping at
+ once. */
+
+ x = n1;
+
+ if (dn > 2)
+ {
+ /* Compensate for triangularization. */
+ mp_limb_t y;
+
+ dp = dp_orig;
+ if (qn + 1 < dn)
+ {
+ dp += dn - (qn + 1);
+ dn = qn + 1;
+ }
+
+ y = np[-2];
+
+ for (i = dn - 3; i >= 0; i--)
+ {
+ q = qp[i];
+ cy = mpn_submul_1 (np - (dn - i), dp, dn - i - 2, q);
+
+ if (y < cy)
+ {
+ if (x == 0)
+ {
+ cy = mpn_sub_1 (qp, qp, qn, 1);
+ ASSERT_ALWAYS (cy == 0);
+ return qh - cy;
+ }
+ x--;
+ }
+ y -= cy;
+ }
+ np[-2] = y;
+ }
+
+ dn = dn_orig;
+ if (qn + 1 < dn)
+ {
+ /* Compensate for ignored dividend and divisor tails. */
+
+ dp = dp_orig;
+ np = np_orig;
+
+ if (qh != 0)
+ {
+ cy = mpn_sub_n (np + qn, np + qn, dp, dn - (qn + 1));
+ if (cy != 0)
+ {
+ if (x == 0)
+ {
+ if (qn != 0)
+ cy = mpn_sub_1 (qp, qp, qn, 1);
+ return qh - cy;
+ }
+ x--;
+ }
+ }
+
+ if (qn == 0)
+ return qh;
+
+ for (i = dn - qn - 2; i >= 0; i--)
+ {
+ cy = mpn_submul_1 (np + i, qp, qn, dp[i]);
+ cy = mpn_sub_1 (np + qn + i, np + qn + i, dn - qn - i - 1, cy);
+ if (cy != 0)
+ {
+ if (x == 0)
+ {
+ cy = mpn_sub_1 (qp, qp, qn, 1);
+ return qh;
+ }
+ x--;
+ }
+ }
+ }
+ }
+
+ return qh;
+}
diff --git a/gmp/mpn/generic/sbpi1_div_qr.c b/gmp/mpn/generic/sbpi1_div_qr.c
new file mode 100644
index 0000000000..0c3e4cb729
--- /dev/null
+++ b/gmp/mpn/generic/sbpi1_div_qr.c
@@ -0,0 +1,110 @@
+/* mpn_sbpi1_div_qr -- Schoolbook division using the Möller-Granlund 3/2
+ division algorithm.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2007, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_sbpi1_div_qr (mp_ptr qp,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_limb_t dinv)
+{
+ mp_limb_t qh;
+ mp_size_t i;
+ mp_limb_t n1, n0;
+ mp_limb_t d1, d0;
+ mp_limb_t cy, cy1;
+ mp_limb_t q;
+
+ ASSERT (dn > 2);
+ ASSERT (nn >= dn);
+ ASSERT ((dp[dn-1] & GMP_NUMB_HIGHBIT) != 0);
+
+ np += nn;
+
+ qh = mpn_cmp (np - dn, dp, dn) >= 0;
+ if (qh != 0)
+ mpn_sub_n (np - dn, np - dn, dp, dn);
+
+ qp += nn - dn;
+
+ dn -= 2; /* offset dn by 2 for main division loops,
+ saving two iterations in mpn_submul_1. */
+ d1 = dp[dn + 1];
+ d0 = dp[dn + 0];
+
+ np -= 2;
+
+ n1 = np[1];
+
+ for (i = nn - (dn + 2); i > 0; i--)
+ {
+ np--;
+ if (UNLIKELY (n1 == d1) && np[1] == d0)
+ {
+ q = GMP_NUMB_MASK;
+ mpn_submul_1 (np - dn, dp, dn + 2, q);
+ n1 = np[1]; /* update n1, last loop's value will now be invalid */
+ }
+ else
+ {
+ udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
+
+ cy = mpn_submul_1 (np - dn, dp, dn, q);
+
+ cy1 = n0 < cy;
+ n0 = (n0 - cy) & GMP_NUMB_MASK;
+ cy = n1 < cy1;
+ n1 = (n1 - cy1) & GMP_NUMB_MASK;
+ np[0] = n0;
+
+ if (UNLIKELY (cy != 0))
+ {
+ n1 += d1 + mpn_add_n (np - dn, np - dn, dp, dn + 1);
+ q--;
+ }
+ }
+
+ *--qp = q;
+ }
+ np[1] = n1;
+
+ return qh;
+}
diff --git a/gmp/mpn/generic/sbpi1_divappr_q.c b/gmp/mpn/generic/sbpi1_divappr_q.c
new file mode 100644
index 0000000000..3e7cf91ba6
--- /dev/null
+++ b/gmp/mpn/generic/sbpi1_divappr_q.c
@@ -0,0 +1,199 @@
+/* mpn_sbpi1_divappr_q -- Schoolbook division using the Möller-Granlund 3/2
+ division algorithm, returning approximate quotient. The quotient returned
+ is either correct, or one too large.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 2007, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_sbpi1_divappr_q (mp_ptr qp,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_limb_t dinv)
+{
+ mp_limb_t qh;
+ mp_size_t qn, i;
+ mp_limb_t n1, n0;
+ mp_limb_t d1, d0;
+ mp_limb_t cy, cy1;
+ mp_limb_t q;
+ mp_limb_t flag;
+
+ ASSERT (dn > 2);
+ ASSERT (nn >= dn);
+ ASSERT ((dp[dn-1] & GMP_NUMB_HIGHBIT) != 0);
+
+ np += nn;
+
+ qn = nn - dn;
+ if (qn + 1 < dn)
+ {
+ dp += dn - (qn + 1);
+ dn = qn + 1;
+ }
+
+ qh = mpn_cmp (np - dn, dp, dn) >= 0;
+ if (qh != 0)
+ mpn_sub_n (np - dn, np - dn, dp, dn);
+
+ qp += qn;
+
+ dn -= 2; /* offset dn by 2 for main division loops,
+ saving two iterations in mpn_submul_1. */
+ d1 = dp[dn + 1];
+ d0 = dp[dn + 0];
+
+ np -= 2;
+
+ n1 = np[1];
+
+ for (i = qn - (dn + 2); i >= 0; i--)
+ {
+ np--;
+ if (UNLIKELY (n1 == d1) && np[1] == d0)
+ {
+ q = GMP_NUMB_MASK;
+ mpn_submul_1 (np - dn, dp, dn + 2, q);
+ n1 = np[1]; /* update n1, last loop's value will now be invalid */
+ }
+ else
+ {
+ udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
+
+ cy = mpn_submul_1 (np - dn, dp, dn, q);
+
+ cy1 = n0 < cy;
+ n0 = (n0 - cy) & GMP_NUMB_MASK;
+ cy = n1 < cy1;
+ n1 -= cy1;
+ np[0] = n0;
+
+ if (UNLIKELY (cy != 0))
+ {
+ n1 += d1 + mpn_add_n (np - dn, np - dn, dp, dn + 1);
+ q--;
+ }
+ }
+
+ *--qp = q;
+ }
+
+ flag = ~CNST_LIMB(0);
+
+ if (dn >= 0)
+ {
+ for (i = dn; i > 0; i--)
+ {
+ np--;
+ if (UNLIKELY (n1 >= (d1 & flag)))
+ {
+ q = GMP_NUMB_MASK;
+ cy = mpn_submul_1 (np - dn, dp, dn + 2, q);
+
+ if (UNLIKELY (n1 != cy))
+ {
+ if (n1 < (cy & flag))
+ {
+ q--;
+ mpn_add_n (np - dn, np - dn, dp, dn + 2);
+ }
+ else
+ flag = 0;
+ }
+ n1 = np[1];
+ }
+ else
+ {
+ udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
+
+ cy = mpn_submul_1 (np - dn, dp, dn, q);
+
+ cy1 = n0 < cy;
+ n0 = (n0 - cy) & GMP_NUMB_MASK;
+ cy = n1 < cy1;
+ n1 -= cy1;
+ np[0] = n0;
+
+ if (UNLIKELY (cy != 0))
+ {
+ n1 += d1 + mpn_add_n (np - dn, np - dn, dp, dn + 1);
+ q--;
+ }
+ }
+
+ *--qp = q;
+
+ /* Truncate operands. */
+ dn--;
+ dp++;
+ }
+
+ np--;
+ if (UNLIKELY (n1 >= (d1 & flag)))
+ {
+ q = GMP_NUMB_MASK;
+ cy = mpn_submul_1 (np, dp, 2, q);
+
+ if (UNLIKELY (n1 != cy))
+ {
+ if (n1 < (cy & flag))
+ {
+ q--;
+ add_ssaaaa (np[1], np[0], np[1], np[0], dp[1], dp[0]);
+ }
+ else
+ flag = 0;
+ }
+ n1 = np[1];
+ }
+ else
+ {
+ udiv_qr_3by2 (q, n1, n0, n1, np[1], np[0], d1, d0, dinv);
+
+ np[1] = n1;
+ np[0] = n0;
+ }
+
+ *--qp = q;
+ }
+
+ ASSERT_ALWAYS (np[1] == n1);
+
+ return qh;
+}
diff --git a/gmp/mpn/generic/scan0.c b/gmp/mpn/generic/scan0.c
new file mode 100644
index 0000000000..8171fd5afe
--- /dev/null
+++ b/gmp/mpn/generic/scan0.c
@@ -0,0 +1,60 @@
+/* mpn_scan0 -- Scan from a given bit position for the next clear bit.
+
+Copyright 1994, 1996, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Argument constraints:
+ 1. U must sooner or later have a limb with a clear bit.
+ */
+
+mp_bitcnt_t
+mpn_scan0 (mp_srcptr up, mp_bitcnt_t starting_bit)
+{
+ mp_size_t starting_word;
+ mp_limb_t alimb;
+ int cnt;
+ mp_srcptr p;
+
+ /* Start at the word implied by STARTING_BIT. */
+ starting_word = starting_bit / GMP_NUMB_BITS;
+ p = up + starting_word;
+ alimb = *p++ ^ GMP_NUMB_MASK;
+
+ /* Mask off any bits before STARTING_BIT in the first limb. */
+ alimb &= - (mp_limb_t) 1 << (starting_bit % GMP_NUMB_BITS);
+
+ while (alimb == 0)
+ alimb = *p++ ^ GMP_NUMB_MASK;
+
+ count_trailing_zeros (cnt, alimb);
+ return (p - up - 1) * GMP_NUMB_BITS + cnt;
+}
diff --git a/gmp/mpn/generic/scan1.c b/gmp/mpn/generic/scan1.c
new file mode 100644
index 0000000000..e22ad5d827
--- /dev/null
+++ b/gmp/mpn/generic/scan1.c
@@ -0,0 +1,60 @@
+/* mpn_scan1 -- Scan from a given bit position for the next set bit.
+
+Copyright 1994, 1996, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Argument constraints:
+ 1. U must sooner or later have a limb != 0.
+ */
+
+mp_bitcnt_t
+mpn_scan1 (mp_srcptr up, mp_bitcnt_t starting_bit)
+{
+ mp_size_t starting_word;
+ mp_limb_t alimb;
+ int cnt;
+ mp_srcptr p;
+
+ /* Start at the word implied by STARTING_BIT. */
+ starting_word = starting_bit / GMP_NUMB_BITS;
+ p = up + starting_word;
+ alimb = *p++;
+
+ /* Mask off any bits before STARTING_BIT in the first limb. */
+ alimb &= - (mp_limb_t) 1 << (starting_bit % GMP_NUMB_BITS);
+
+ while (alimb == 0)
+ alimb = *p++;
+
+ count_trailing_zeros (cnt, alimb);
+ return (p - up - 1) * GMP_NUMB_BITS + cnt;
+}
diff --git a/gmp/mpn/generic/sec_aors_1.c b/gmp/mpn/generic/sec_aors_1.c
new file mode 100644
index 0000000000..d789a5792e
--- /dev/null
+++ b/gmp/mpn/generic/sec_aors_1.c
@@ -0,0 +1,60 @@
+/* mpn_sec_add_1, mpn_sec_sub_1
+
+ Contributed to the GNU project by Niels Möller
+
+Copyright 2013, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if OPERATION_sec_add_1
+#define FNAME mpn_sec_add_1
+#define FNAME_itch mpn_sec_add_1_itch
+#define OP_N mpn_add_n
+#endif
+#if OPERATION_sec_sub_1
+#define FNAME mpn_sec_sub_1
+#define FNAME_itch mpn_sec_sub_1_itch
+#define OP_N mpn_sub_n
+#endif
+
+/* It's annoying to that we need scratch space */
+mp_size_t
+FNAME_itch (mp_size_t n)
+{
+ return n;
+}
+
+mp_limb_t
+FNAME (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b, mp_ptr scratch)
+{
+ scratch[0] = b;
+ MPN_ZERO (scratch + 1, n-1);
+ return OP_N (rp, ap, scratch, n);
+}
diff --git a/gmp/mpn/generic/sec_div.c b/gmp/mpn/generic/sec_div.c
new file mode 100644
index 0000000000..483b118d0d
--- /dev/null
+++ b/gmp/mpn/generic/sec_div.c
@@ -0,0 +1,133 @@
+/* mpn_sec_div_qr, mpn_sec_div_r -- Compute Q = floor(U / V), U = U mod V.
+ Side-channel silent under the assumption that the used instructions are
+ side-channel silent.
+
+ Contributed to the GNU project by Torbjörn Granlund.
+
+Copyright 2011-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#if OPERATION_sec_div_qr
+#define FNAME mpn_sec_div_qr
+#define FNAME_itch mpn_sec_div_qr_itch
+#define Q(q) q,
+#define RETTYPE mp_limb_t
+#endif
+#if OPERATION_sec_div_r
+#define FNAME mpn_sec_div_r
+#define FNAME_itch mpn_sec_div_r_itch
+#define Q(q)
+#define RETTYPE void
+#endif
+
+mp_size_t
+FNAME_itch (mp_size_t nn, mp_size_t dn)
+{
+#if OPERATION_sec_div_qr
+/* Needs (nn + dn + 1) + mpn_sec_pi1_div_qr's needs of (2nn' - dn + 1) for a
+ total of 3nn + 4 limbs at tp. Note that mpn_sec_pi1_div_qr's nn is one
+ greater than ours, therefore +4 and not just +2. */
+ return 3 * nn + 4;
+#endif
+#if OPERATION_sec_div_r
+/* Needs (nn + dn + 1) + mpn_sec_pi1_div_r's needs of (dn + 1) for a total of
+ nn + 2dn + 2 limbs at tp. */
+ return nn + 2 * dn + 2;
+#endif
+}
+
+RETTYPE
+FNAME (Q(mp_ptr qp)
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_ptr tp)
+{
+ mp_limb_t d1, d0;
+ unsigned int cnt;
+ gmp_pi1_t dinv;
+ mp_limb_t inv32;
+
+ ASSERT (dn >= 1);
+ ASSERT (nn >= dn);
+ ASSERT (dp[dn - 1] != 0);
+
+ d1 = dp[dn - 1];
+ count_leading_zeros (cnt, d1);
+
+ if (cnt != 0)
+ {
+ mp_limb_t qh, cy;
+ mp_ptr np2, dp2;
+ dp2 = tp; /* dn limbs */
+ mpn_lshift (dp2, dp, dn, cnt);
+
+ np2 = tp + dn; /* (nn + 1) limbs */
+ cy = mpn_lshift (np2, np, nn, cnt);
+ np2[nn++] = cy;
+
+ d0 = dp2[dn - 1];
+ d0 += (~d0 != 0);
+ invert_limb (inv32, d0);
+
+ /* We add nn + dn to tp here, not nn + 1 + dn, as expected. This is
+ since nn here will have been incremented. */
+#if OPERATION_sec_div_qr
+ qh = mpn_sec_pi1_div_qr (np2 + dn, np2, nn, dp2, dn, inv32, tp + nn + dn);
+ ASSERT (qh == 0); /* FIXME: this indicates inefficiency! */
+ MPN_COPY (qp, np2 + dn, nn - dn - 1);
+ qh = np2[nn - 1];
+#else
+ mpn_sec_pi1_div_r (np2, nn, dp2, dn, inv32, tp + nn + dn);
+#endif
+
+ mpn_rshift (np, np2, dn, cnt);
+
+#if OPERATION_sec_div_qr
+ return qh;
+#endif
+ }
+ else
+ {
+ /* FIXME: Consider copying np => np2 here, adding a 0-limb at the top.
+ That would simplify the underlying pi1 function, since then it could
+ assume nn > dn. */
+ d0 = dp[dn - 1];
+ d0 += (~d0 != 0);
+ invert_limb (inv32, d0);
+
+#if OPERATION_sec_div_qr
+ return mpn_sec_pi1_div_qr (qp, np, nn, dp, dn, inv32, tp);
+#else
+ mpn_sec_pi1_div_r (np, nn, dp, dn, inv32, tp);
+#endif
+ }
+}
diff --git a/gmp/mpn/generic/sec_invert.c b/gmp/mpn/generic/sec_invert.c
new file mode 100644
index 0000000000..43a578b2a1
--- /dev/null
+++ b/gmp/mpn/generic/sec_invert.c
@@ -0,0 +1,195 @@
+/* mpn_sec_invert
+
+ Contributed to the GNU project by Niels Möller
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if 0
+/* Currently unused. Should be resurrected once mpn_cnd_neg is
+ advertised. */
+static mp_size_t
+mpn_cnd_neg_itch (mp_size_t n)
+{
+ return n;
+}
+#endif
+
+/* FIXME: Ought to return carry */
+static void
+mpn_cnd_neg (int cnd, mp_limb_t *rp, const mp_limb_t *ap, mp_size_t n,
+ mp_ptr scratch)
+{
+ mpn_lshift (scratch, ap, n, 1);
+ mpn_cnd_sub_n (cnd, rp, ap, scratch, n);
+}
+
+static void
+mpn_cnd_swap (int cnd, volatile mp_limb_t *ap, volatile mp_limb_t *bp,
+ mp_size_t n)
+{
+ volatile mp_limb_t mask = - (mp_limb_t) (cnd != 0);
+ mp_size_t i;
+ for (i = 0; i < n; i++)
+ {
+ mp_limb_t a, b, t;
+ a = ap[i];
+ b = bp[i];
+ t = (a ^ b) & mask;
+ ap[i] = a ^ t;
+ bp[i] = b ^ t;
+ }
+}
+
+static int
+mpn_sec_eq_ui (mp_srcptr ap, mp_size_t n, mp_limb_t b)
+{
+ mp_limb_t d;
+ ASSERT (n > 0);
+
+ d = ap[0] ^ b;
+
+ while (--n > 0)
+ d |= ap[n];
+
+ return d == 0;
+}
+
+mp_size_t
+mpn_sec_invert_itch (mp_size_t n)
+{
+ return 4*n;
+}
+
+/* Compute V <-- A^{-1} (mod M), in data-independent time. M must be
+ odd. Returns 1 on success, and 0 on failure (i.e., if gcd (A, m) !=
+ 1). Inputs and outputs of size n, and no overlap allowed. The {ap,
+ n} area is destroyed. For arbitrary inputs, bit_size should be
+ 2*n*GMP_NUMB_BITS, but if A or M are known to be smaller, e.g., if
+ M = 2^521 - 1 and A < M, bit_size can be any bound on the sum of
+ the bit sizes of A and M. */
+int
+mpn_sec_invert (mp_ptr vp, mp_ptr ap, mp_srcptr mp,
+ mp_size_t n, mp_bitcnt_t bit_size,
+ mp_ptr scratch)
+{
+ ASSERT (n > 0);
+ ASSERT (bit_size > 0);
+ ASSERT (mp[0] & 1);
+ ASSERT (! MPN_OVERLAP_P (ap, n, vp, n));
+#define bp (scratch + n)
+#define up (scratch + 2*n)
+#define m1hp (scratch + 3*n)
+
+ /* Maintain
+
+ a = u * orig_a (mod m)
+ b = v * orig_a (mod m)
+
+ and b odd at all times. Initially,
+
+ a = a_orig, u = 1
+ b = m, v = 0
+ */
+
+
+ up[0] = 1;
+ mpn_zero (up+1, n - 1);
+ mpn_copyi (bp, mp, n);
+ mpn_zero (vp, n);
+
+ ASSERT_CARRY (mpn_rshift (m1hp, mp, n, 1));
+ ASSERT_NOCARRY (mpn_sec_add_1 (m1hp, m1hp, n, 1, scratch));
+
+ while (bit_size-- > 0)
+ {
+ mp_limb_t odd, swap, cy;
+
+ /* Always maintain b odd. The logic of the iteration is as
+ follows. For a, b:
+
+ odd = a & 1
+ a -= odd * b
+ if (underflow from a-b)
+ {
+ b += a, assigns old a
+ a = B^n-a
+ }
+
+ a /= 2
+
+ For u, v:
+
+ if (underflow from a - b)
+ swap u, v
+ u -= odd * v
+ if (underflow from u - v)
+ u += m
+
+ u /= 2
+ if (a one bit was shifted out)
+ u += (m+1)/2
+
+ As long as a > 0, the quantity
+
+ (bitsize of a) + (bitsize of b)
+
+ is reduced by at least one bit per iteration, hence after (bit_size of
+ orig_a) + (bit_size of m) - 1 iterations we surely have a = 0. Then b
+ = gcd(orig_a, m) and if b = 1 then also v = orig_a^{-1} (mod m).
+ */
+
+ ASSERT (bp[0] & 1);
+ odd = ap[0] & 1;
+
+ swap = mpn_cnd_sub_n (odd, ap, ap, bp, n);
+ mpn_cnd_add_n (swap, bp, bp, ap, n);
+ mpn_cnd_neg (swap, ap, ap, n, scratch);
+
+ mpn_cnd_swap (swap, up, vp, n);
+ cy = mpn_cnd_sub_n (odd, up, up, vp, n);
+ cy -= mpn_cnd_add_n (cy, up, up, mp, n);
+ ASSERT (cy == 0);
+
+ cy = mpn_rshift (ap, ap, n, 1);
+ ASSERT (cy == 0);
+ cy = mpn_rshift (up, up, n, 1);
+ cy = mpn_cnd_add_n (cy, up, up, m1hp, n);
+ ASSERT (cy == 0);
+ }
+ /* Should be all zeros, but check only extreme limbs */
+ ASSERT ( (ap[0] | ap[n-1]) == 0);
+ /* Check if indeed gcd == 1. */
+ return mpn_sec_eq_ui (bp, n, 1);
+#undef bp
+#undef up
+#undef m1hp
+}
diff --git a/gmp/mpn/generic/sec_mul.c b/gmp/mpn/generic/sec_mul.c
new file mode 100644
index 0000000000..2cd87fab1d
--- /dev/null
+++ b/gmp/mpn/generic/sec_mul.c
@@ -0,0 +1,49 @@
+/* mpn_sec_mul.
+
+ Contributed to the GNU project by Torbjörn Granlund.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_sec_mul (mp_ptr rp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn,
+ mp_ptr tp)
+{
+ mpn_mul_basecase (rp, ap, an, bp, bn);
+}
+
+mp_size_t
+mpn_sec_mul_itch (mp_size_t an, mp_size_t bn)
+{
+ return 0;
+}
diff --git a/gmp/mpn/generic/sec_pi1_div.c b/gmp/mpn/generic/sec_pi1_div.c
new file mode 100644
index 0000000000..1e075daf73
--- /dev/null
+++ b/gmp/mpn/generic/sec_pi1_div.c
@@ -0,0 +1,173 @@
+/* mpn_sec_pi1_div_qr, mpn_sec_pi1_div_r -- Compute Q = floor(U / V), U = U
+ mod V. Side-channel silent under the assumption that the used instructions
+ are side-channel silent.
+
+ Contributed to the GNU project by Torbjörn Granlund.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011-2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* This side-channel silent division algorithm reduces the partial remainder by
+ GMP_NUMB_BITS/2 bits at a time, compared to GMP_NUMB_BITS for the main
+ division algorithm. We actually do not insist on reducing by exactly
+ GMP_NUMB_BITS/2, but may leave a partial remainder that is D*B^i to 3D*B^i
+ too large (B is the limb base, D is the divisor, and i is the induction
+ variable); the subsequent step will handle the extra partial remainder bits.
+
+ With that partial remainder reduction, each step generates a quotient "half
+ limb". The outer loop generates two quotient half limbs, an upper (q1h) and
+ a lower (q0h) which are stored sparsely in separate limb arrays. These
+ arrays are added at the end; using separate arrays avoids data-dependent
+ carry propagation which could else pose a side-channel leakage problem.
+
+ The quotient half limbs may be between -3 to 0 from the accurate value
+ ("accurate" being the one which corresponds to a reduction to a principal
+ partial remainder). Too small quotient half limbs correspond to too large
+ remainders, which we reduce later, as described above.
+
+ In order to keep quotients from getting too big, corresponding to a negative
+ partial remainder, we use an inverse which is slightly smaller than usually.
+*/
+
+#if OPERATION_sec_pi1_div_qr
+/* Needs (dn + 1) + (nn - dn) + (nn - dn) = 2nn - dn + 1 limbs at tp. */
+#define FNAME mpn_sec_pi1_div_qr
+#define Q(q) q,
+#define RETTYPE mp_limb_t
+#endif
+#if OPERATION_sec_pi1_div_r
+/* Needs (dn + 1) limbs at tp. */
+#define FNAME mpn_sec_pi1_div_r
+#define Q(q)
+#define RETTYPE void
+#endif
+
+RETTYPE
+FNAME (Q(mp_ptr qp)
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp, mp_size_t dn,
+ mp_limb_t dinv,
+ mp_ptr tp)
+{
+ mp_limb_t nh, cy, q1h, q0h, dummy, cnd;
+ mp_size_t i;
+ mp_ptr hp;
+#if OPERATION_sec_pi1_div_qr
+ mp_limb_t qh;
+ mp_ptr qlp, qhp;
+#endif
+
+ ASSERT (dn >= 1);
+ ASSERT (nn >= dn);
+ ASSERT ((dp[dn - 1] & GMP_NUMB_HIGHBIT) != 0);
+
+ if (nn == dn)
+ {
+ cy = mpn_sub_n (np, np, dp, dn);
+ mpn_cnd_add_n (cy, np, np, dp, dn);
+#if OPERATION_sec_pi1_div_qr
+ return 1 - cy;
+#else
+ return;
+#endif
+ }
+
+ /* Create a divisor copy shifted half a limb. */
+ hp = tp; /* (dn + 1) limbs */
+ hp[dn] = mpn_lshift (hp, dp, dn, GMP_NUMB_BITS / 2);
+
+#if OPERATION_sec_pi1_div_qr
+ qlp = tp + (dn + 1); /* (nn - dn) limbs */
+ qhp = tp + (nn + 1); /* (nn - dn) limbs */
+#endif
+
+ np += nn - dn;
+ nh = 0;
+
+ for (i = nn - dn - 1; i >= 0; i--)
+ {
+ np--;
+
+ nh = (nh << GMP_NUMB_BITS/2) + (np[dn] >> GMP_NUMB_BITS/2);
+ umul_ppmm (q1h, dummy, nh, dinv);
+ q1h += nh;
+#if OPERATION_sec_pi1_div_qr
+ qhp[i] = q1h;
+#endif
+ mpn_submul_1 (np, hp, dn + 1, q1h);
+
+ nh = np[dn];
+ umul_ppmm (q0h, dummy, nh, dinv);
+ q0h += nh;
+#if OPERATION_sec_pi1_div_qr
+ qlp[i] = q0h;
+#endif
+ nh -= mpn_submul_1 (np, dp, dn, q0h);
+ }
+
+ /* 1st adjustment depends on extra high remainder limb. */
+ cnd = nh != 0; /* FIXME: cmp-to-int */
+#if OPERATION_sec_pi1_div_qr
+ qlp[0] += cnd;
+#endif
+ nh -= mpn_cnd_sub_n (cnd, np, np, dp, dn);
+
+ /* 2nd adjustment depends on remainder/divisor comparison as well as whether
+ extra remainder limb was nullified by previous subtract. */
+ cy = mpn_sub_n (np, np, dp, dn);
+ cy = cy - nh;
+#if OPERATION_sec_pi1_div_qr
+ qlp[0] += 1 - cy;
+#endif
+ mpn_cnd_add_n (cy, np, np, dp, dn);
+
+ /* 3rd adjustment depends on remainder/divisor comparison. */
+ cy = mpn_sub_n (np, np, dp, dn);
+#if OPERATION_sec_pi1_div_qr
+ qlp[0] += 1 - cy;
+#endif
+ mpn_cnd_add_n (cy, np, np, dp, dn);
+
+#if OPERATION_sec_pi1_div_qr
+ /* Combine quotient halves into final quotient. */
+ qh = mpn_lshift (qhp, qhp, nn - dn, GMP_NUMB_BITS/2);
+ qh += mpn_add_n (qp, qhp, qlp, nn - dn);
+
+ return qh;
+#else
+ return;
+#endif
+}
diff --git a/gmp/mpn/generic/sec_powm.c b/gmp/mpn/generic/sec_powm.c
new file mode 100644
index 0000000000..67de44e10a
--- /dev/null
+++ b/gmp/mpn/generic/sec_powm.c
@@ -0,0 +1,438 @@
+/* mpn_sec_powm -- Compute R = U^E mod M. Secure variant, side-channel silent
+ under the assumption that the multiply instruction is side channel silent.
+
+ Contributed to the GNU project by Torbjörn Granlund.
+
+Copyright 2007-2009, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/*
+ BASIC ALGORITHM, Compute U^E mod M, where M < B^n is odd.
+
+ 1. T <- (B^n * U) mod M Convert to REDC form
+
+ 2. Compute table U^0, U^1, U^2... of E-dependent size
+
+ 3. While there are more bits in E
+ W <- power left-to-right base-k
+
+
+ TODO:
+
+ * Make getbits a macro, thereby allowing it to update the index operand.
+ That will simplify the code using getbits. (Perhaps make getbits' sibling
+ getbit then have similar form, for symmetry.)
+
+ * Choose window size without looping. (Superoptimize or think(tm).)
+
+ * REDC_1_TO_REDC_2_THRESHOLD might actually represent the cutoff between
+ redc_1 and redc_n. On such systems, we will switch to redc_2 causing
+ slowdown.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#undef MPN_REDC_1_SEC
+#define MPN_REDC_1_SEC(rp, up, mp, n, invm) \
+ do { \
+ mp_limb_t cy; \
+ cy = mpn_redc_1 (rp, up, mp, n, invm); \
+ mpn_cnd_sub_n (cy, rp, rp, mp, n); \
+ } while (0)
+
+#undef MPN_REDC_2_SEC
+#define MPN_REDC_2_SEC(rp, up, mp, n, mip) \
+ do { \
+ mp_limb_t cy; \
+ cy = mpn_redc_2 (rp, up, mp, n, mip); \
+ mpn_cnd_sub_n (cy, rp, rp, mp, n); \
+ } while (0)
+
+#if HAVE_NATIVE_mpn_addmul_2 || HAVE_NATIVE_mpn_redc_2
+#define WANT_REDC_2 1
+#endif
+
+/* Define our own mpn squaring function. We do this since we cannot use a
+ native mpn_sqr_basecase over TUNE_SQR_TOOM2_MAX, or a non-native one over
+ SQR_TOOM2_THRESHOLD. This is so because of fixed size stack allocations
+ made inside mpn_sqr_basecase. */
+
+#if HAVE_NATIVE_mpn_sqr_diagonal
+#define MPN_SQR_DIAGONAL(rp, up, n) \
+ mpn_sqr_diagonal (rp, up, n)
+#else
+#define MPN_SQR_DIAGONAL(rp, up, n) \
+ do { \
+ mp_size_t _i; \
+ for (_i = 0; _i < (n); _i++) \
+ { \
+ mp_limb_t ul, lpl; \
+ ul = (up)[_i]; \
+ umul_ppmm ((rp)[2 * _i + 1], lpl, ul, ul << GMP_NAIL_BITS); \
+ (rp)[2 * _i] = lpl >> GMP_NAIL_BITS; \
+ } \
+ } while (0)
+#endif
+
+
+#if ! HAVE_NATIVE_mpn_sqr_basecase
+/* The limit of the generic code is SQR_TOOM2_THRESHOLD. */
+#define SQR_BASECASE_LIM SQR_TOOM2_THRESHOLD
+#endif
+
+#if HAVE_NATIVE_mpn_sqr_basecase
+#ifdef TUNE_SQR_TOOM2_MAX
+/* We slightly abuse TUNE_SQR_TOOM2_MAX here. If it is set for an assembly
+ mpn_sqr_basecase, it comes from SQR_TOOM2_THRESHOLD_MAX in the assembly
+ file. An assembly mpn_sqr_basecase that does not define it, should allow
+ any size. */
+#define SQR_BASECASE_LIM SQR_TOOM2_THRESHOLD
+#endif
+#endif
+
+#ifdef WANT_FAT_BINARY
+/* For fat builds, we use SQR_TOOM2_THRESHOLD which will expand to a read from
+ __gmpn_cpuvec. Perhaps any possible sqr_basecase.asm allow any size, and we
+ limit the use unnecessarily. We cannot tell, so play it safe. FIXME. */
+#define SQR_BASECASE_LIM SQR_TOOM2_THRESHOLD
+#endif
+
+#ifndef SQR_BASECASE_LIM
+/* If SQR_BASECASE_LIM is now not defined, use mpn_sqr_basecase for any operand
+ size. */
+#define mpn_local_sqr(rp,up,n,tp) mpn_sqr_basecase(rp,up,n)
+#else
+/* Define our own squaring function, which uses mpn_sqr_basecase for its
+ allowed sizes, but its own code for larger sizes. */
+static void
+mpn_local_sqr (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_ptr tp)
+{
+ mp_size_t i;
+
+ ASSERT (n >= 1);
+ ASSERT (! MPN_OVERLAP_P (rp, 2*n, up, n));
+
+ if (BELOW_THRESHOLD (n, SQR_BASECASE_LIM))
+ {
+ mpn_sqr_basecase (rp, up, n);
+ return;
+ }
+
+ {
+ mp_limb_t ul, lpl;
+ ul = up[0];
+ umul_ppmm (rp[1], lpl, ul, ul << GMP_NAIL_BITS);
+ rp[0] = lpl >> GMP_NAIL_BITS;
+ }
+ if (n > 1)
+ {
+ mp_limb_t cy;
+
+ cy = mpn_mul_1 (tp, up + 1, n - 1, up[0]);
+ tp[n - 1] = cy;
+ for (i = 2; i < n; i++)
+ {
+ mp_limb_t cy;
+ cy = mpn_addmul_1 (tp + 2 * i - 2, up + i, n - i, up[i - 1]);
+ tp[n + i - 2] = cy;
+ }
+ MPN_SQR_DIAGONAL (rp + 2, up + 1, n - 1);
+
+ {
+ mp_limb_t cy;
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (rp + 1, rp + 1, tp, 2 * n - 2);
+#else
+ cy = mpn_lshift (tp, tp, 2 * n - 2, 1);
+ cy += mpn_add_n (rp + 1, rp + 1, tp, 2 * n - 2);
+#endif
+ rp[2 * n - 1] += cy;
+ }
+ }
+}
+#endif
+
+#define getbit(p,bi) \
+ ((p[(bi - 1) / GMP_NUMB_BITS] >> (bi - 1) % GMP_NUMB_BITS) & 1)
+
+/* FIXME: Maybe some things would get simpler if all callers ensure
+ that bi >= nbits. As far as I understand, with the current code bi
+ < nbits can happen only for the final iteration. */
+static inline mp_limb_t
+getbits (const mp_limb_t *p, mp_bitcnt_t bi, int nbits)
+{
+ int nbits_in_r;
+ mp_limb_t r;
+ mp_size_t i;
+
+ if (bi < nbits)
+ {
+ return p[0] & (((mp_limb_t) 1 << bi) - 1);
+ }
+ else
+ {
+ bi -= nbits; /* bit index of low bit to extract */
+ i = bi / GMP_NUMB_BITS; /* word index of low bit to extract */
+ bi %= GMP_NUMB_BITS; /* bit index in low word */
+ r = p[i] >> bi; /* extract (low) bits */
+ nbits_in_r = GMP_NUMB_BITS - bi; /* number of bits now in r */
+ if (nbits_in_r < nbits) /* did we get enough bits? */
+ r += p[i + 1] << nbits_in_r; /* prepend bits from higher word */
+ return r & (((mp_limb_t ) 1 << nbits) - 1);
+ }
+}
+
+#ifndef POWM_SEC_TABLE
+#if GMP_NUMB_BITS < 50
+#define POWM_SEC_TABLE 2,33,96,780,2741
+#else
+#define POWM_SEC_TABLE 2,130,524,2578
+#endif
+#endif
+
+#if TUNE_PROGRAM_BUILD
+extern int win_size (mp_bitcnt_t);
+#else
+static inline int
+win_size (mp_bitcnt_t enb)
+{
+ int k;
+ /* Find k, such that x[k-1] < enb <= x[k].
+
+ We require that x[k] >= k, then it follows that enb > x[k-1] >=
+ k-1, which implies k <= enb.
+ */
+ static const mp_bitcnt_t x[] = {0,POWM_SEC_TABLE,~(mp_bitcnt_t)0};
+ for (k = 1; enb > x[k]; k++)
+ ;
+ ASSERT (k <= enb);
+ return k;
+}
+#endif
+
+/* Convert U to REDC form, U_r = B^n * U mod M.
+ Uses scratch space at tp of size 2un + n + 1. */
+static void
+redcify (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr mp, mp_size_t n, mp_ptr tp)
+{
+ MPN_ZERO (tp, n);
+ MPN_COPY (tp + n, up, un);
+
+ mpn_sec_div_r (tp, un + n, mp, n, tp + un + n);
+ MPN_COPY (rp, tp, n);
+}
+
+/* {rp, n} <-- {bp, bn} ^ {ep, en} mod {mp, n},
+ where en = ceil (enb / GMP_NUMB_BITS)
+ Requires that {mp, n} is odd (and hence also mp[0] odd).
+ Uses scratch space at tp as defined by mpn_sec_powm_itch. */
+void
+mpn_sec_powm (mp_ptr rp, mp_srcptr bp, mp_size_t bn,
+ mp_srcptr ep, mp_bitcnt_t enb,
+ mp_srcptr mp, mp_size_t n, mp_ptr tp)
+{
+ mp_limb_t ip[2], *mip;
+ int windowsize, this_windowsize;
+ mp_limb_t expbits;
+ mp_ptr pp, this_pp;
+ long i;
+ int cnd;
+
+ ASSERT (enb > 0);
+ ASSERT (n > 0);
+ /* The code works for bn = 0, but the defined scratch space is 2 limbs
+ greater than we supply, when converting 1 to redc form . */
+ ASSERT (bn > 0);
+ ASSERT ((mp[0] & 1) != 0);
+
+ windowsize = win_size (enb);
+
+#if WANT_REDC_2
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ {
+ mip = ip;
+ binvert_limb (mip[0], mp[0]);
+ mip[0] = -mip[0];
+ }
+ else
+ {
+ mip = ip;
+ mpn_binvert (mip, mp, 2, tp);
+ mip[0] = -mip[0]; mip[1] = ~mip[1];
+ }
+#else
+ mip = ip;
+ binvert_limb (mip[0], mp[0]);
+ mip[0] = -mip[0];
+#endif
+
+ pp = tp;
+ tp += (n << windowsize); /* put tp after power table */
+
+ /* Compute pp[0] table entry */
+ /* scratch: | n | 1 | n+2 | */
+ /* | pp[0] | 1 | redcify | */
+ this_pp = pp;
+ this_pp[n] = 1;
+ redcify (this_pp, this_pp + n, 1, mp, n, this_pp + n + 1);
+ this_pp += n;
+
+ /* Compute pp[1] table entry. To avoid excessive scratch usage in the
+ degenerate situation where B >> M, we let redcify use scratch space which
+ will later be used by the pp table (element 2 and up). */
+ /* scratch: | n | n | bn + n + 1 | */
+ /* | pp[0] | pp[1] | redcify | */
+ redcify (this_pp, bp, bn, mp, n, this_pp + n);
+
+ /* Precompute powers of b and put them in the temporary area at pp. */
+ /* scratch: | n | n | ... | | 2n | */
+ /* | pp[0] | pp[1] | ... | pp[2^windowsize-1] | product | */
+ for (i = (1 << windowsize) - 2; i > 0; i--)
+ {
+ mpn_mul_basecase (tp, this_pp, n, pp + n, n);
+ this_pp += n;
+#if WANT_REDC_2
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ MPN_REDC_1_SEC (this_pp, tp, mp, n, mip[0]);
+ else
+ MPN_REDC_2_SEC (this_pp, tp, mp, n, mip);
+#else
+ MPN_REDC_1_SEC (this_pp, tp, mp, n, mip[0]);
+#endif
+ }
+
+ expbits = getbits (ep, enb, windowsize);
+ ASSERT_ALWAYS (enb >= windowsize);
+ enb -= windowsize;
+
+ mpn_sec_tabselect (rp, pp, n, 1 << windowsize, expbits);
+
+ /* Main exponentiation loop. */
+ /* scratch: | n | n | ... | | 3n-4n | */
+ /* | pp[0] | pp[1] | ... | pp[2^windowsize-1] | loop scratch | */
+
+#define INNERLOOP \
+ while (enb != 0) \
+ { \
+ expbits = getbits (ep, enb, windowsize); \
+ this_windowsize = windowsize; \
+ if (enb < windowsize) \
+ { \
+ this_windowsize -= windowsize - enb; \
+ enb = 0; \
+ } \
+ else \
+ enb -= windowsize; \
+ \
+ do \
+ { \
+ mpn_local_sqr (tp, rp, n, tp + 2 * n); \
+ MPN_REDUCE (rp, tp, mp, n, mip); \
+ this_windowsize--; \
+ } \
+ while (this_windowsize != 0); \
+ \
+ mpn_sec_tabselect (tp + 2*n, pp, n, 1 << windowsize, expbits); \
+ mpn_mul_basecase (tp, rp, n, tp + 2*n, n); \
+ \
+ MPN_REDUCE (rp, tp, mp, n, mip); \
+ }
+
+#if WANT_REDC_2
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1_SEC (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+ }
+ else
+ {
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_2_SEC (rp, tp, mp, n, mip)
+ INNERLOOP;
+ }
+#else
+#undef MPN_MUL_N
+#undef MPN_SQR
+#undef MPN_REDUCE
+#define MPN_MUL_N(r,a,b,n) mpn_mul_basecase (r,a,n,b,n)
+#define MPN_SQR(r,a,n) mpn_sqr_basecase (r,a,n)
+#define MPN_REDUCE(rp,tp,mp,n,mip) MPN_REDC_1_SEC (rp, tp, mp, n, mip[0])
+ INNERLOOP;
+#endif
+
+ MPN_COPY (tp, rp, n);
+ MPN_ZERO (tp + n, n);
+
+#if WANT_REDC_2
+ if (BELOW_THRESHOLD (n, REDC_1_TO_REDC_2_THRESHOLD))
+ MPN_REDC_1_SEC (rp, tp, mp, n, mip[0]);
+ else
+ MPN_REDC_2_SEC (rp, tp, mp, n, mip);
+#else
+ MPN_REDC_1_SEC (rp, tp, mp, n, mip[0]);
+#endif
+ cnd = mpn_sub_n (tp, rp, mp, n); /* we need just retval */
+ mpn_cnd_sub_n (!cnd, rp, rp, mp, n);
+}
+
+mp_size_t
+mpn_sec_powm_itch (mp_size_t bn, mp_bitcnt_t enb, mp_size_t n)
+{
+ int windowsize;
+ mp_size_t redcify_itch, itch;
+
+ /* The top scratch usage will either be when reducing B in the 2nd redcify
+ call, or more typically n*2^windowsize + 3n or 4n, in the main loop. (It
+ is 3n or 4n depending on if we use mpn_local_sqr or a native
+ mpn_sqr_basecase. We assume 4n always for now.) */
+
+ windowsize = win_size (enb);
+
+ /* The 2n term is due to pp[0] and pp[1] at the time of the 2nd redcify call,
+ the (bn + n) term is due to redcify's own usage, and the rest is due to
+ mpn_sec_div_r's usage when called from redcify. */
+ redcify_itch = (2 * n) + (bn + n) + ((bn + n) + 2 * n + 2);
+
+ /* The n * 2^windowsize term is due to the power table, the 4n term is due to
+ scratch needs of squaring/multiplication in the exponentiation loop. */
+ itch = (n << windowsize) + (4 * n);
+
+ return MAX (itch, redcify_itch);
+}
diff --git a/gmp/mpn/generic/sec_sqr.c b/gmp/mpn/generic/sec_sqr.c
new file mode 100644
index 0000000000..736924cc22
--- /dev/null
+++ b/gmp/mpn/generic/sec_sqr.c
@@ -0,0 +1,48 @@
+/* mpn_sec_sqr.
+
+ Contributed to the GNU project by Torbjörn Granlund.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_sec_sqr (mp_ptr rp,
+ mp_srcptr ap, mp_size_t an,
+ mp_ptr tp)
+{
+ mpn_sqr_basecase (rp, ap, an);
+}
+
+mp_size_t
+mpn_sec_sqr_itch (mp_size_t an)
+{
+ return 0;
+}
diff --git a/gmp/mpn/generic/sec_tabselect.c b/gmp/mpn/generic/sec_tabselect.c
new file mode 100644
index 0000000000..a79c73a575
--- /dev/null
+++ b/gmp/mpn/generic/sec_tabselect.c
@@ -0,0 +1,55 @@
+/* mpn_sec_tabselect.
+
+Copyright 2007-2009, 2011, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Select entry `which' from table `tab', which has nents entries, each `n'
+ limbs. Store the selected entry at rp. Reads entire table to avoid
+ side-channel information leaks. O(n*nents). */
+void
+mpn_sec_tabselect (volatile mp_limb_t *rp, volatile const mp_limb_t *tab,
+ mp_size_t n, mp_size_t nents, mp_size_t which)
+{
+ mp_size_t k, i;
+ mp_limb_t mask;
+ volatile mp_limb_t *tp;
+
+ for (k = 0; k < nents; k++)
+ {
+ mask = -(mp_limb_t) (which == k);
+ tp = tab + n * k;
+ for (i = 0; i < n; i++)
+ {
+ rp[i] = (rp[i] & ~mask) | (tp[i] & mask);
+ }
+ }
+}
diff --git a/gmp/mpn/generic/set_str.c b/gmp/mpn/generic/set_str.c
new file mode 100644
index 0000000000..71034e34bf
--- /dev/null
+++ b/gmp/mpn/generic/set_str.c
@@ -0,0 +1,374 @@
+/* mpn_set_str (mp_ptr res_ptr, const char *str, size_t str_len, int base) --
+ Convert a STR_LEN long base BASE byte string pointed to by STR to a limb
+ vector pointed to by RES_PTR. Return the number of limbs in RES_PTR.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTIONS IN THIS FILE, EXCEPT mpn_set_str, ARE INTERNAL WITH A MUTABLE
+ INTERFACE. IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN
+ FACT, IT IS ALMOST GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE
+ GNU MP RELEASE.
+
+Copyright 1991-1994, 1996, 2000-2002, 2004, 2006-2008, 2012, 2013 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* TODO:
+
+ Perhaps do not compute the highest power?
+ Instead, multiply twice by the 2nd highest power:
+
+ _______
+ |_______| hp
+ |_______| pow
+ _______________
+ |_______________| final result
+
+
+ _______
+ |_______| hp
+ |___| pow[-1]
+ ___________
+ |___________| intermediate result
+ |___| pow[-1]
+ _______________
+ |_______________| final result
+
+ Generalizing that idea, perhaps we should make powtab contain successive
+ cubes, not squares.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_size_t
+mpn_set_str (mp_ptr rp, const unsigned char *str, size_t str_len, int base)
+{
+ if (POW2_P (base))
+ {
+ /* The base is a power of 2. Read the input string from least to most
+ significant character/digit. */
+
+ const unsigned char *s;
+ int next_bitpos;
+ mp_limb_t res_digit;
+ mp_size_t size;
+ int bits_per_indigit = mp_bases[base].big_base;
+
+ size = 0;
+ res_digit = 0;
+ next_bitpos = 0;
+
+ for (s = str + str_len - 1; s >= str; s--)
+ {
+ int inp_digit = *s;
+
+ res_digit |= ((mp_limb_t) inp_digit << next_bitpos) & GMP_NUMB_MASK;
+ next_bitpos += bits_per_indigit;
+ if (next_bitpos >= GMP_NUMB_BITS)
+ {
+ rp[size++] = res_digit;
+ next_bitpos -= GMP_NUMB_BITS;
+ res_digit = inp_digit >> (bits_per_indigit - next_bitpos);
+ }
+ }
+
+ if (res_digit != 0)
+ rp[size++] = res_digit;
+ return size;
+ }
+
+ if (BELOW_THRESHOLD (str_len, SET_STR_PRECOMPUTE_THRESHOLD))
+ return mpn_bc_set_str (rp, str, str_len, base);
+ else
+ {
+ mp_ptr powtab_mem, tp;
+ powers_t powtab[GMP_LIMB_BITS];
+ int chars_per_limb;
+ mp_size_t size;
+ mp_size_t un;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ chars_per_limb = mp_bases[base].chars_per_limb;
+
+ un = str_len / chars_per_limb + 1;
+
+ /* Allocate one large block for the powers of big_base. */
+ powtab_mem = TMP_BALLOC_LIMBS (mpn_dc_set_str_powtab_alloc (un));
+
+ mpn_set_str_compute_powtab (powtab, powtab_mem, un, base);
+
+ tp = TMP_BALLOC_LIMBS (mpn_dc_set_str_itch (un));
+ size = mpn_dc_set_str (rp, str, str_len, powtab, tp);
+
+ TMP_FREE;
+ return size;
+ }
+}
+
+void
+mpn_set_str_compute_powtab (powers_t *powtab, mp_ptr powtab_mem, mp_size_t un, int base)
+{
+ mp_ptr powtab_mem_ptr;
+ long i, pi;
+ mp_size_t n;
+ mp_ptr p, t;
+ mp_limb_t big_base;
+ int chars_per_limb;
+ size_t digits_in_base;
+ mp_size_t shift;
+
+ powtab_mem_ptr = powtab_mem;
+
+ chars_per_limb = mp_bases[base].chars_per_limb;
+ big_base = mp_bases[base].big_base;
+
+ p = powtab_mem_ptr;
+ powtab_mem_ptr += 1;
+
+ digits_in_base = chars_per_limb;
+
+ p[0] = big_base;
+ n = 1;
+
+ count_leading_zeros (i, un - 1);
+ i = GMP_LIMB_BITS - 1 - i;
+
+ powtab[i].p = p;
+ powtab[i].n = n;
+ powtab[i].digits_in_base = digits_in_base;
+ powtab[i].base = base;
+ powtab[i].shift = 0;
+
+ shift = 0;
+ for (pi = i - 1; pi >= 0; pi--)
+ {
+ t = powtab_mem_ptr;
+ powtab_mem_ptr += 2 * n;
+
+ ASSERT_ALWAYS (powtab_mem_ptr < powtab_mem + mpn_dc_set_str_powtab_alloc (un));
+
+ mpn_sqr (t, p, n);
+ n = 2 * n - 1; n += t[n] != 0;
+ digits_in_base *= 2;
+#if 1
+ if ((((un - 1) >> pi) & 2) == 0)
+ {
+ mpn_divexact_1 (t, t, n, big_base);
+ n -= t[n - 1] == 0;
+ digits_in_base -= chars_per_limb;
+ }
+#else
+ if (CLEVER_CONDITION_1 ())
+ {
+ /* perform adjustment operation of previous */
+ cy = mpn_mul_1 (p, p, n, big_base);
+ }
+ if (CLEVER_CONDITION_2 ())
+ {
+ /* perform adjustment operation of new */
+ cy = mpn_mul_1 (t, t, n, big_base);
+ }
+#endif
+ shift *= 2;
+ /* Strip low zero limbs, but be careful to keep the result divisible by
+ big_base. */
+ while (t[0] == 0 && (t[1] & ((big_base & -big_base) - 1)) == 0)
+ {
+ t++;
+ n--;
+ shift++;
+ }
+ p = t;
+ powtab[pi].p = p;
+ powtab[pi].n = n;
+ powtab[pi].digits_in_base = digits_in_base;
+ powtab[pi].base = base;
+ powtab[pi].shift = shift;
+ }
+}
+
+mp_size_t
+mpn_dc_set_str (mp_ptr rp, const unsigned char *str, size_t str_len,
+ const powers_t *powtab, mp_ptr tp)
+{
+ size_t len_lo, len_hi;
+ mp_limb_t cy;
+ mp_size_t ln, hn, n, sn;
+
+ len_lo = powtab->digits_in_base;
+
+ if (str_len <= len_lo)
+ {
+ if (BELOW_THRESHOLD (str_len, SET_STR_DC_THRESHOLD))
+ return mpn_bc_set_str (rp, str, str_len, powtab->base);
+ else
+ return mpn_dc_set_str (rp, str, str_len, powtab + 1, tp);
+ }
+
+ len_hi = str_len - len_lo;
+ ASSERT (len_lo >= len_hi);
+
+ if (BELOW_THRESHOLD (len_hi, SET_STR_DC_THRESHOLD))
+ hn = mpn_bc_set_str (tp, str, len_hi, powtab->base);
+ else
+ hn = mpn_dc_set_str (tp, str, len_hi, powtab + 1, rp);
+
+ sn = powtab->shift;
+
+ if (hn == 0)
+ {
+ /* Zero +1 limb here, to avoid reading an allocated but uninitialised
+ limb in mpn_incr_u below. */
+ MPN_ZERO (rp, powtab->n + sn + 1);
+ }
+ else
+ {
+ if (powtab->n > hn)
+ mpn_mul (rp + sn, powtab->p, powtab->n, tp, hn);
+ else
+ mpn_mul (rp + sn, tp, hn, powtab->p, powtab->n);
+ MPN_ZERO (rp, sn);
+ }
+
+ str = str + str_len - len_lo;
+ if (BELOW_THRESHOLD (len_lo, SET_STR_DC_THRESHOLD))
+ ln = mpn_bc_set_str (tp, str, len_lo, powtab->base);
+ else
+ ln = mpn_dc_set_str (tp, str, len_lo, powtab + 1, tp + powtab->n + sn + 1);
+
+ if (ln != 0)
+ {
+ cy = mpn_add_n (rp, rp, tp, ln);
+ mpn_incr_u (rp + ln, cy);
+ }
+ n = hn + powtab->n + sn;
+ return n - (rp[n - 1] == 0);
+}
+
+mp_size_t
+mpn_bc_set_str (mp_ptr rp, const unsigned char *str, size_t str_len, int base)
+{
+ mp_size_t size;
+ size_t i;
+ long j;
+ mp_limb_t cy_limb;
+
+ mp_limb_t big_base;
+ int chars_per_limb;
+ mp_limb_t res_digit;
+
+ ASSERT (base >= 2);
+ ASSERT (base < numberof (mp_bases));
+ ASSERT (str_len >= 1);
+
+ big_base = mp_bases[base].big_base;
+ chars_per_limb = mp_bases[base].chars_per_limb;
+
+ size = 0;
+ for (i = chars_per_limb; i < str_len; i += chars_per_limb)
+ {
+ res_digit = *str++;
+ if (base == 10)
+ { /* This is a common case.
+ Help the compiler to avoid multiplication. */
+ for (j = MP_BASES_CHARS_PER_LIMB_10 - 1; j != 0; j--)
+ res_digit = res_digit * 10 + *str++;
+ }
+ else
+ {
+ for (j = chars_per_limb - 1; j != 0; j--)
+ res_digit = res_digit * base + *str++;
+ }
+
+ if (size == 0)
+ {
+ if (res_digit != 0)
+ {
+ rp[0] = res_digit;
+ size = 1;
+ }
+ }
+ else
+ {
+#if HAVE_NATIVE_mpn_mul_1c
+ cy_limb = mpn_mul_1c (rp, rp, size, big_base, res_digit);
+#else
+ cy_limb = mpn_mul_1 (rp, rp, size, big_base);
+ cy_limb += mpn_add_1 (rp, rp, size, res_digit);
+#endif
+ if (cy_limb != 0)
+ rp[size++] = cy_limb;
+ }
+ }
+
+ big_base = base;
+ res_digit = *str++;
+ if (base == 10)
+ { /* This is a common case.
+ Help the compiler to avoid multiplication. */
+ for (j = str_len - (i - MP_BASES_CHARS_PER_LIMB_10) - 1; j > 0; j--)
+ {
+ res_digit = res_digit * 10 + *str++;
+ big_base *= 10;
+ }
+ }
+ else
+ {
+ for (j = str_len - (i - chars_per_limb) - 1; j > 0; j--)
+ {
+ res_digit = res_digit * base + *str++;
+ big_base *= base;
+ }
+ }
+
+ if (size == 0)
+ {
+ if (res_digit != 0)
+ {
+ rp[0] = res_digit;
+ size = 1;
+ }
+ }
+ else
+ {
+#if HAVE_NATIVE_mpn_mul_1c
+ cy_limb = mpn_mul_1c (rp, rp, size, big_base, res_digit);
+#else
+ cy_limb = mpn_mul_1 (rp, rp, size, big_base);
+ cy_limb += mpn_add_1 (rp, rp, size, res_digit);
+#endif
+ if (cy_limb != 0)
+ rp[size++] = cy_limb;
+ }
+ return size;
+}
diff --git a/gmp/mpn/generic/sizeinbase.c b/gmp/mpn/generic/sizeinbase.c
new file mode 100644
index 0000000000..16633569ec
--- /dev/null
+++ b/gmp/mpn/generic/sizeinbase.c
@@ -0,0 +1,50 @@
+/* mpn_sizeinbase -- approximation to chars required for an mpn.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 1991, 1993-1995, 2001, 2002, 2011, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Same as mpz_sizeinbase, meaning exact for power-of-2 bases, and either
+ exact or 1 too big for other bases. */
+
+size_t
+mpn_sizeinbase (mp_srcptr xp, mp_size_t xsize, int base)
+{
+ size_t result;
+ MPN_SIZEINBASE (result, xp, xsize, base);
+ return result;
+}
diff --git a/gmp/mpn/generic/sqr.c b/gmp/mpn/generic/sqr.c
new file mode 100644
index 0000000000..3743761f78
--- /dev/null
+++ b/gmp/mpn/generic/sqr.c
@@ -0,0 +1,99 @@
+/* mpn_sqr -- square natural numbers.
+
+Copyright 1991, 1993, 1994, 1996-2003, 2005, 2008, 2009 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpn_sqr (mp_ptr p, mp_srcptr a, mp_size_t n)
+{
+ ASSERT (n >= 1);
+ ASSERT (! MPN_OVERLAP_P (p, 2 * n, a, n));
+
+ if (BELOW_THRESHOLD (n, SQR_BASECASE_THRESHOLD))
+ { /* mul_basecase is faster than sqr_basecase on small sizes sometimes */
+ mpn_mul_basecase (p, a, n, a, n);
+ }
+ else if (BELOW_THRESHOLD (n, SQR_TOOM2_THRESHOLD))
+ {
+ mpn_sqr_basecase (p, a, n);
+ }
+ else if (BELOW_THRESHOLD (n, SQR_TOOM3_THRESHOLD))
+ {
+ /* Allocate workspace of fixed size on stack: fast! */
+ mp_limb_t ws[mpn_toom2_sqr_itch (SQR_TOOM3_THRESHOLD_LIMIT-1)];
+ ASSERT (SQR_TOOM3_THRESHOLD <= SQR_TOOM3_THRESHOLD_LIMIT);
+ mpn_toom2_sqr (p, a, n, ws);
+ }
+ else if (BELOW_THRESHOLD (n, SQR_TOOM4_THRESHOLD))
+ {
+ mp_ptr ws;
+ TMP_SDECL;
+ TMP_SMARK;
+ ws = TMP_SALLOC_LIMBS (mpn_toom3_sqr_itch (n));
+ mpn_toom3_sqr (p, a, n, ws);
+ TMP_SFREE;
+ }
+ else if (BELOW_THRESHOLD (n, SQR_TOOM6_THRESHOLD))
+ {
+ mp_ptr ws;
+ TMP_SDECL;
+ TMP_SMARK;
+ ws = TMP_SALLOC_LIMBS (mpn_toom4_sqr_itch (n));
+ mpn_toom4_sqr (p, a, n, ws);
+ TMP_SFREE;
+ }
+ else if (BELOW_THRESHOLD (n, SQR_TOOM8_THRESHOLD))
+ {
+ mp_ptr ws;
+ TMP_SDECL;
+ TMP_SMARK;
+ ws = TMP_SALLOC_LIMBS (mpn_toom6_sqr_itch (n));
+ mpn_toom6_sqr (p, a, n, ws);
+ TMP_SFREE;
+ }
+ else if (BELOW_THRESHOLD (n, SQR_FFT_THRESHOLD))
+ {
+ mp_ptr ws;
+ TMP_DECL;
+ TMP_MARK;
+ ws = TMP_ALLOC_LIMBS (mpn_toom8_sqr_itch (n));
+ mpn_toom8_sqr (p, a, n, ws);
+ TMP_FREE;
+ }
+ else
+ {
+ /* The current FFT code allocates its own space. That should probably
+ change. */
+ mpn_fft_mul (p, a, n, a, n);
+ }
+}
diff --git a/gmp/mpn/generic/sqr_basecase.c b/gmp/mpn/generic/sqr_basecase.c
new file mode 100644
index 0000000000..fc6a043a94
--- /dev/null
+++ b/gmp/mpn/generic/sqr_basecase.c
@@ -0,0 +1,325 @@
+/* mpn_sqr_basecase -- Internal routine to square a natural number
+ of length n.
+
+ THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES.
+
+
+Copyright 1991-1994, 1996, 1997, 2000-2005, 2008, 2010, 2011 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#if HAVE_NATIVE_mpn_sqr_diagonal
+#define MPN_SQR_DIAGONAL(rp, up, n) \
+ mpn_sqr_diagonal (rp, up, n)
+#else
+#define MPN_SQR_DIAGONAL(rp, up, n) \
+ do { \
+ mp_size_t _i; \
+ for (_i = 0; _i < (n); _i++) \
+ { \
+ mp_limb_t ul, lpl; \
+ ul = (up)[_i]; \
+ umul_ppmm ((rp)[2 * _i + 1], lpl, ul, ul << GMP_NAIL_BITS); \
+ (rp)[2 * _i] = lpl >> GMP_NAIL_BITS; \
+ } \
+ } while (0)
+#endif
+
+#if HAVE_NATIVE_mpn_sqr_diag_addlsh1
+#define MPN_SQR_DIAG_ADDLSH1(rp, tp, up, n) \
+ mpn_sqr_diag_addlsh1 (rp, tp, up, n)
+#else
+#if HAVE_NATIVE_mpn_addlsh1_n
+#define MPN_SQR_DIAG_ADDLSH1(rp, tp, up, n) \
+ do { \
+ mp_limb_t cy; \
+ MPN_SQR_DIAGONAL (rp, up, n); \
+ cy = mpn_addlsh1_n (rp + 1, rp + 1, tp, 2 * n - 2); \
+ rp[2 * n - 1] += cy; \
+ } while (0)
+#else
+#define MPN_SQR_DIAG_ADDLSH1(rp, tp, up, n) \
+ do { \
+ mp_limb_t cy; \
+ MPN_SQR_DIAGONAL (rp, up, n); \
+ cy = mpn_lshift (tp, tp, 2 * n - 2, 1); \
+ cy += mpn_add_n (rp + 1, rp + 1, tp, 2 * n - 2); \
+ rp[2 * n - 1] += cy; \
+ } while (0)
+#endif
+#endif
+
+
+#undef READY_WITH_mpn_sqr_basecase
+
+
+#if ! defined (READY_WITH_mpn_sqr_basecase) && HAVE_NATIVE_mpn_addmul_2s
+void
+mpn_sqr_basecase (mp_ptr rp, mp_srcptr up, mp_size_t n)
+{
+ mp_size_t i;
+ mp_limb_t tarr[2 * SQR_TOOM2_THRESHOLD];
+ mp_ptr tp = tarr;
+ mp_limb_t cy;
+
+ /* must fit 2*n limbs in tarr */
+ ASSERT (n <= SQR_TOOM2_THRESHOLD);
+
+ if ((n & 1) != 0)
+ {
+ if (n == 1)
+ {
+ mp_limb_t ul, lpl;
+ ul = up[0];
+ umul_ppmm (rp[1], lpl, ul, ul << GMP_NAIL_BITS);
+ rp[0] = lpl >> GMP_NAIL_BITS;
+ return;
+ }
+
+ MPN_ZERO (tp, n);
+
+ for (i = 0; i <= n - 2; i += 2)
+ {
+ cy = mpn_addmul_2s (tp + 2 * i, up + i + 1, n - (i + 1), up + i);
+ tp[n + i] = cy;
+ }
+ }
+ else
+ {
+ if (n == 2)
+ {
+#if HAVE_NATIVE_mpn_mul_2
+ rp[3] = mpn_mul_2 (rp, up, 2, up);
+#else
+ rp[0] = 0;
+ rp[1] = 0;
+ rp[3] = mpn_addmul_2 (rp, up, 2, up);
+#endif
+ return;
+ }
+
+ MPN_ZERO (tp, n);
+
+ for (i = 0; i <= n - 4; i += 2)
+ {
+ cy = mpn_addmul_2s (tp + 2 * i, up + i + 1, n - (i + 1), up + i);
+ tp[n + i] = cy;
+ }
+ cy = mpn_addmul_1 (tp + 2 * n - 4, up + n - 1, 1, up[n - 2]);
+ tp[2 * n - 3] = cy;
+ }
+
+ MPN_SQR_DIAG_ADDLSH1 (rp, tp, up, n);
+}
+#define READY_WITH_mpn_sqr_basecase
+#endif
+
+
+#if ! defined (READY_WITH_mpn_sqr_basecase) && HAVE_NATIVE_mpn_addmul_2
+
+/* mpn_sqr_basecase using plain mpn_addmul_2.
+
+ This is tricky, since we have to let mpn_addmul_2 make some undesirable
+ multiplies, u[k]*u[k], that we would like to let mpn_sqr_diagonal handle.
+ This forces us to conditionally add or subtract the mpn_sqr_diagonal
+ results. Examples of the product we form:
+
+ n = 4 n = 5 n = 6
+ u1u0 * u3u2u1 u1u0 * u4u3u2u1 u1u0 * u5u4u3u2u1
+ u2 * u3 u3u2 * u4u3 u3u2 * u5u4u3
+ u4 * u5
+ add: u0 u2 u3 add: u0 u2 u4 add: u0 u2 u4 u5
+ sub: u1 sub: u1 u3 sub: u1 u3
+*/
+
+void
+mpn_sqr_basecase (mp_ptr rp, mp_srcptr up, mp_size_t n)
+{
+ mp_size_t i;
+ mp_limb_t tarr[2 * SQR_TOOM2_THRESHOLD];
+ mp_ptr tp = tarr;
+ mp_limb_t cy;
+
+ /* must fit 2*n limbs in tarr */
+ ASSERT (n <= SQR_TOOM2_THRESHOLD);
+
+ if ((n & 1) != 0)
+ {
+ mp_limb_t x0, x1;
+
+ if (n == 1)
+ {
+ mp_limb_t ul, lpl;
+ ul = up[0];
+ umul_ppmm (rp[1], lpl, ul, ul << GMP_NAIL_BITS);
+ rp[0] = lpl >> GMP_NAIL_BITS;
+ return;
+ }
+
+ /* The code below doesn't like unnormalized operands. Since such
+ operands are unusual, handle them with a dumb recursion. */
+ if (up[n - 1] == 0)
+ {
+ rp[2 * n - 2] = 0;
+ rp[2 * n - 1] = 0;
+ mpn_sqr_basecase (rp, up, n - 1);
+ return;
+ }
+
+ MPN_ZERO (tp, n);
+
+ for (i = 0; i <= n - 2; i += 2)
+ {
+ cy = mpn_addmul_2 (tp + 2 * i, up + i + 1, n - (i + 1), up + i);
+ tp[n + i] = cy;
+ }
+
+ MPN_SQR_DIAGONAL (rp, up, n);
+
+ for (i = 2;; i += 4)
+ {
+ x0 = rp[i + 0];
+ rp[i + 0] = (-x0) & GMP_NUMB_MASK;
+ x1 = rp[i + 1];
+ rp[i + 1] = (-x1 - (x0 != 0)) & GMP_NUMB_MASK;
+ __GMPN_SUB_1 (cy, rp + i + 2, rp + i + 2, 2, (x1 | x0) != 0);
+ if (i + 4 >= 2 * n)
+ break;
+ mpn_incr_u (rp + i + 4, cy);
+ }
+ }
+ else
+ {
+ mp_limb_t x0, x1;
+
+ if (n == 2)
+ {
+#if HAVE_NATIVE_mpn_mul_2
+ rp[3] = mpn_mul_2 (rp, up, 2, up);
+#else
+ rp[0] = 0;
+ rp[1] = 0;
+ rp[3] = mpn_addmul_2 (rp, up, 2, up);
+#endif
+ return;
+ }
+
+ /* The code below doesn't like unnormalized operands. Since such
+ operands are unusual, handle them with a dumb recursion. */
+ if (up[n - 1] == 0)
+ {
+ rp[2 * n - 2] = 0;
+ rp[2 * n - 1] = 0;
+ mpn_sqr_basecase (rp, up, n - 1);
+ return;
+ }
+
+ MPN_ZERO (tp, n);
+
+ for (i = 0; i <= n - 4; i += 2)
+ {
+ cy = mpn_addmul_2 (tp + 2 * i, up + i + 1, n - (i + 1), up + i);
+ tp[n + i] = cy;
+ }
+ cy = mpn_addmul_1 (tp + 2 * n - 4, up + n - 1, 1, up[n - 2]);
+ tp[2 * n - 3] = cy;
+
+ MPN_SQR_DIAGONAL (rp, up, n);
+
+ for (i = 2;; i += 4)
+ {
+ x0 = rp[i + 0];
+ rp[i + 0] = (-x0) & GMP_NUMB_MASK;
+ x1 = rp[i + 1];
+ rp[i + 1] = (-x1 - (x0 != 0)) & GMP_NUMB_MASK;
+ if (i + 6 >= 2 * n)
+ break;
+ __GMPN_SUB_1 (cy, rp + i + 2, rp + i + 2, 2, (x1 | x0) != 0);
+ mpn_incr_u (rp + i + 4, cy);
+ }
+ mpn_decr_u (rp + i + 2, (x1 | x0) != 0);
+ }
+
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (rp + 1, rp + 1, tp, 2 * n - 2);
+#else
+ cy = mpn_lshift (tp, tp, 2 * n - 2, 1);
+ cy += mpn_add_n (rp + 1, rp + 1, tp, 2 * n - 2);
+#endif
+ rp[2 * n - 1] += cy;
+}
+#define READY_WITH_mpn_sqr_basecase
+#endif
+
+
+#if ! defined (READY_WITH_mpn_sqr_basecase)
+
+/* Default mpn_sqr_basecase using mpn_addmul_1. */
+
+void
+mpn_sqr_basecase (mp_ptr rp, mp_srcptr up, mp_size_t n)
+{
+ mp_size_t i;
+
+ ASSERT (n >= 1);
+ ASSERT (! MPN_OVERLAP_P (rp, 2*n, up, n));
+
+ {
+ mp_limb_t ul, lpl;
+ ul = up[0];
+ umul_ppmm (rp[1], lpl, ul, ul << GMP_NAIL_BITS);
+ rp[0] = lpl >> GMP_NAIL_BITS;
+ }
+ if (n > 1)
+ {
+ mp_limb_t tarr[2 * SQR_TOOM2_THRESHOLD];
+ mp_ptr tp = tarr;
+ mp_limb_t cy;
+
+ /* must fit 2*n limbs in tarr */
+ ASSERT (n <= SQR_TOOM2_THRESHOLD);
+
+ cy = mpn_mul_1 (tp, up + 1, n - 1, up[0]);
+ tp[n - 1] = cy;
+ for (i = 2; i < n; i++)
+ {
+ mp_limb_t cy;
+ cy = mpn_addmul_1 (tp + 2 * i - 2, up + i, n - i, up[i - 1]);
+ tp[n + i - 2] = cy;
+ }
+
+ MPN_SQR_DIAG_ADDLSH1 (rp, tp, up, n);
+ }
+}
+#endif
diff --git a/gmp/mpn/generic/sqrmod_bnm1.c b/gmp/mpn/generic/sqrmod_bnm1.c
new file mode 100644
index 0000000000..fd0868b90b
--- /dev/null
+++ b/gmp/mpn/generic/sqrmod_bnm1.c
@@ -0,0 +1,313 @@
+/* sqrmod_bnm1.c -- squaring mod B^n-1.
+
+ Contributed to the GNU project by Niels Möller, Torbjorn Granlund and
+ Marco Bodrato.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Input is {ap,rn}; output is {rp,rn}, computation is
+ mod B^rn - 1, and values are semi-normalised; zero is represented
+ as either 0 or B^n - 1. Needs a scratch of 2rn limbs at tp.
+ tp==rp is allowed. */
+static void
+mpn_bc_sqrmod_bnm1 (mp_ptr rp, mp_srcptr ap, mp_size_t rn, mp_ptr tp)
+{
+ mp_limb_t cy;
+
+ ASSERT (0 < rn);
+
+ mpn_sqr (tp, ap, rn);
+ cy = mpn_add_n (rp, tp, tp + rn, rn);
+ /* If cy == 1, then the value of rp is at most B^rn - 2, so there can
+ * be no overflow when adding in the carry. */
+ MPN_INCR_U (rp, rn, cy);
+}
+
+
+/* Input is {ap,rn+1}; output is {rp,rn+1}, in
+ semi-normalised representation, computation is mod B^rn + 1. Needs
+ a scratch area of 2rn + 2 limbs at tp; tp == rp is allowed.
+ Output is normalised. */
+static void
+mpn_bc_sqrmod_bnp1 (mp_ptr rp, mp_srcptr ap, mp_size_t rn, mp_ptr tp)
+{
+ mp_limb_t cy;
+
+ ASSERT (0 < rn);
+
+ mpn_sqr (tp, ap, rn + 1);
+ ASSERT (tp[2*rn+1] == 0);
+ ASSERT (tp[2*rn] < GMP_NUMB_MAX);
+ cy = tp[2*rn] + mpn_sub_n (rp, tp, tp+rn, rn);
+ rp[rn] = 0;
+ MPN_INCR_U (rp, rn+1, cy );
+}
+
+
+/* Computes {rp,MIN(rn,2an)} <- {ap,an}^2 Mod(B^rn-1)
+ *
+ * The result is expected to be ZERO if and only if the operand
+ * already is. Otherwise the class [0] Mod(B^rn-1) is represented by
+ * B^rn-1.
+ * It should not be a problem if sqrmod_bnm1 is used to
+ * compute the full square with an <= 2*rn, because this condition
+ * implies (B^an-1)^2 < (B^rn-1) .
+ *
+ * Requires rn/4 < an <= rn
+ * Scratch need: rn/2 + (need for recursive call OR rn + 3). This gives
+ *
+ * S(n) <= rn/2 + MAX (rn + 4, S(n/2)) <= 3/2 rn + 4
+ */
+void
+mpn_sqrmod_bnm1 (mp_ptr rp, mp_size_t rn, mp_srcptr ap, mp_size_t an, mp_ptr tp)
+{
+ ASSERT (0 < an);
+ ASSERT (an <= rn);
+
+ if ((rn & 1) != 0 || BELOW_THRESHOLD (rn, SQRMOD_BNM1_THRESHOLD))
+ {
+ if (UNLIKELY (an < rn))
+ {
+ if (UNLIKELY (2*an <= rn))
+ {
+ mpn_sqr (rp, ap, an);
+ }
+ else
+ {
+ mp_limb_t cy;
+ mpn_sqr (tp, ap, an);
+ cy = mpn_add (rp, tp, rn, tp + rn, 2*an - rn);
+ MPN_INCR_U (rp, rn, cy);
+ }
+ }
+ else
+ mpn_bc_sqrmod_bnm1 (rp, ap, rn, tp);
+ }
+ else
+ {
+ mp_size_t n;
+ mp_limb_t cy;
+ mp_limb_t hi;
+
+ n = rn >> 1;
+
+ ASSERT (2*an > n);
+
+ /* Compute xm = a^2 mod (B^n - 1), xp = a^2 mod (B^n + 1)
+ and crt together as
+
+ x = -xp * B^n + (B^n + 1) * [ (xp + xm)/2 mod (B^n-1)]
+ */
+
+#define a0 ap
+#define a1 (ap + n)
+
+#define xp tp /* 2n + 2 */
+ /* am1 maybe in {xp, n} */
+#define sp1 (tp + 2*n + 2)
+ /* ap1 maybe in {sp1, n + 1} */
+
+ {
+ mp_srcptr am1;
+ mp_size_t anm;
+ mp_ptr so;
+
+ if (LIKELY (an > n))
+ {
+ so = xp + n;
+ am1 = xp;
+ cy = mpn_add (xp, a0, n, a1, an - n);
+ MPN_INCR_U (xp, n, cy);
+ anm = n;
+ }
+ else
+ {
+ so = xp;
+ am1 = a0;
+ anm = an;
+ }
+
+ mpn_sqrmod_bnm1 (rp, n, am1, anm, so);
+ }
+
+ {
+ int k;
+ mp_srcptr ap1;
+ mp_size_t anp;
+
+ if (LIKELY (an > n)) {
+ ap1 = sp1;
+ cy = mpn_sub (sp1, a0, n, a1, an - n);
+ sp1[n] = 0;
+ MPN_INCR_U (sp1, n + 1, cy);
+ anp = n + ap1[n];
+ } else {
+ ap1 = a0;
+ anp = an;
+ }
+
+ if (BELOW_THRESHOLD (n, MUL_FFT_MODF_THRESHOLD))
+ k=0;
+ else
+ {
+ int mask;
+ k = mpn_fft_best_k (n, 1);
+ mask = (1<<k) -1;
+ while (n & mask) {k--; mask >>=1;};
+ }
+ if (k >= FFT_FIRST_K)
+ xp[n] = mpn_mul_fft (xp, n, ap1, anp, ap1, anp, k);
+ else if (UNLIKELY (ap1 == a0))
+ {
+ ASSERT (anp <= n);
+ ASSERT (2*anp > n);
+ mpn_sqr (xp, a0, an);
+ anp = 2*an - n;
+ cy = mpn_sub (xp, xp, n, xp + n, anp);
+ xp[n] = 0;
+ MPN_INCR_U (xp, n+1, cy);
+ }
+ else
+ mpn_bc_sqrmod_bnp1 (xp, ap1, n, xp);
+ }
+
+ /* Here the CRT recomposition begins.
+
+ xm <- (xp + xm)/2 = (xp + xm)B^n/2 mod (B^n-1)
+ Division by 2 is a bitwise rotation.
+
+ Assumes xp normalised mod (B^n+1).
+
+ The residue class [0] is represented by [B^n-1]; except when
+ both input are ZERO.
+ */
+
+#if HAVE_NATIVE_mpn_rsh1add_n || HAVE_NATIVE_mpn_rsh1add_nc
+#if HAVE_NATIVE_mpn_rsh1add_nc
+ cy = mpn_rsh1add_nc(rp, rp, xp, n, xp[n]); /* B^n = 1 */
+ hi = cy << (GMP_NUMB_BITS - 1);
+ cy = 0;
+ /* next update of rp[n-1] will set cy = 1 only if rp[n-1]+=hi
+ overflows, i.e. a further increment will not overflow again. */
+#else /* ! _nc */
+ cy = xp[n] + mpn_rsh1add_n(rp, rp, xp, n); /* B^n = 1 */
+ hi = (cy<<(GMP_NUMB_BITS-1))&GMP_NUMB_MASK; /* (cy&1) << ... */
+ cy >>= 1;
+ /* cy = 1 only if xp[n] = 1 i.e. {xp,n} = ZERO, this implies that
+ the rsh1add was a simple rshift: the top bit is 0. cy=1 => hi=0. */
+#endif
+#if GMP_NAIL_BITS == 0
+ add_ssaaaa(cy, rp[n-1], cy, rp[n-1], CNST_LIMB(0), hi);
+#else
+ cy += (hi & rp[n-1]) >> (GMP_NUMB_BITS-1);
+ rp[n-1] ^= hi;
+#endif
+#else /* ! HAVE_NATIVE_mpn_rsh1add_n */
+#if HAVE_NATIVE_mpn_add_nc
+ cy = mpn_add_nc(rp, rp, xp, n, xp[n]);
+#else /* ! _nc */
+ cy = xp[n] + mpn_add_n(rp, rp, xp, n); /* xp[n] == 1 implies {xp,n} == ZERO */
+#endif
+ cy += (rp[0]&1);
+ mpn_rshift(rp, rp, n, 1);
+ ASSERT (cy <= 2);
+ hi = (cy<<(GMP_NUMB_BITS-1))&GMP_NUMB_MASK; /* (cy&1) << ... */
+ cy >>= 1;
+ /* We can have cy != 0 only if hi = 0... */
+ ASSERT ((rp[n-1] & GMP_NUMB_HIGHBIT) == 0);
+ rp[n-1] |= hi;
+ /* ... rp[n-1] + cy can not overflow, the following INCR is correct. */
+#endif
+ ASSERT (cy <= 1);
+ /* Next increment can not overflow, read the previous comments about cy. */
+ ASSERT ((cy == 0) || ((rp[n-1] & GMP_NUMB_HIGHBIT) == 0));
+ MPN_INCR_U(rp, n, cy);
+
+ /* Compute the highest half:
+ ([(xp + xm)/2 mod (B^n-1)] - xp ) * B^n
+ */
+ if (UNLIKELY (2*an < rn))
+ {
+ /* Note that in this case, the only way the result can equal
+ zero mod B^{rn} - 1 is if the input is zero, and
+ then the output of both the recursive calls and this CRT
+ reconstruction is zero, not B^{rn} - 1. */
+ cy = mpn_sub_n (rp + n, rp, xp, 2*an - n);
+
+ /* FIXME: This subtraction of the high parts is not really
+ necessary, we do it to get the carry out, and for sanity
+ checking. */
+ cy = xp[n] + mpn_sub_nc (xp + 2*an - n, rp + 2*an - n,
+ xp + 2*an - n, rn - 2*an, cy);
+ ASSERT (mpn_zero_p (xp + 2*an - n+1, rn - 1 - 2*an));
+ cy = mpn_sub_1 (rp, rp, 2*an, cy);
+ ASSERT (cy == (xp + 2*an - n)[0]);
+ }
+ else
+ {
+ cy = xp[n] + mpn_sub_n (rp + n, rp, xp, n);
+ /* cy = 1 only if {xp,n+1} is not ZERO, i.e. {rp,n} is not ZERO.
+ DECR will affect _at most_ the lowest n limbs. */
+ MPN_DECR_U (rp, 2*n, cy);
+ }
+#undef a0
+#undef a1
+#undef xp
+#undef sp1
+ }
+}
+
+mp_size_t
+mpn_sqrmod_bnm1_next_size (mp_size_t n)
+{
+ mp_size_t nh;
+
+ if (BELOW_THRESHOLD (n, SQRMOD_BNM1_THRESHOLD))
+ return n;
+ if (BELOW_THRESHOLD (n, 4 * (SQRMOD_BNM1_THRESHOLD - 1) + 1))
+ return (n + (2-1)) & (-2);
+ if (BELOW_THRESHOLD (n, 8 * (SQRMOD_BNM1_THRESHOLD - 1) + 1))
+ return (n + (4-1)) & (-4);
+
+ nh = (n + 1) >> 1;
+
+ if (BELOW_THRESHOLD (nh, SQR_FFT_MODF_THRESHOLD))
+ return (n + (8-1)) & (-8);
+
+ return 2 * mpn_fft_next_size (nh, mpn_fft_best_k (nh, 1));
+}
diff --git a/gmp/mpn/generic/sqrtrem.c b/gmp/mpn/generic/sqrtrem.c
new file mode 100644
index 0000000000..7d0f120001
--- /dev/null
+++ b/gmp/mpn/generic/sqrtrem.c
@@ -0,0 +1,357 @@
+/* mpn_sqrtrem -- square root and remainder
+
+ Contributed to the GNU project by Paul Zimmermann (most code) and
+ Torbjorn Granlund (mpn_sqrtrem1).
+
+ THE FUNCTIONS IN THIS FILE EXCEPT mpn_sqrtrem ARE INTERNAL WITH A
+ MUTABLE INTERFACE. IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED
+ INTERFACES. IN FACT, IT IS ALMOST GUARANTEED THAT THEY WILL CHANGE OR
+ DISAPPEAR IN A FUTURE GMP RELEASE.
+
+Copyright 1999-2002, 2004, 2005, 2008, 2010, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* See "Karatsuba Square Root", reference in gmp.texi. */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+static const unsigned char invsqrttab[384] = /* The common 0x100 was removed */
+{
+ 0xff,0xfd,0xfb,0xf9,0xf7,0xf5,0xf3,0xf2, /* sqrt(1/80)..sqrt(1/87) */
+ 0xf0,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe4, /* sqrt(1/88)..sqrt(1/8f) */
+ 0xe2,0xe0,0xdf,0xdd,0xdb,0xda,0xd8,0xd7, /* sqrt(1/90)..sqrt(1/97) */
+ 0xd5,0xd4,0xd2,0xd1,0xcf,0xce,0xcc,0xcb, /* sqrt(1/98)..sqrt(1/9f) */
+ 0xc9,0xc8,0xc6,0xc5,0xc4,0xc2,0xc1,0xc0, /* sqrt(1/a0)..sqrt(1/a7) */
+ 0xbe,0xbd,0xbc,0xba,0xb9,0xb8,0xb7,0xb5, /* sqrt(1/a8)..sqrt(1/af) */
+ 0xb4,0xb3,0xb2,0xb0,0xaf,0xae,0xad,0xac, /* sqrt(1/b0)..sqrt(1/b7) */
+ 0xaa,0xa9,0xa8,0xa7,0xa6,0xa5,0xa4,0xa3, /* sqrt(1/b8)..sqrt(1/bf) */
+ 0xa2,0xa0,0x9f,0x9e,0x9d,0x9c,0x9b,0x9a, /* sqrt(1/c0)..sqrt(1/c7) */
+ 0x99,0x98,0x97,0x96,0x95,0x94,0x93,0x92, /* sqrt(1/c8)..sqrt(1/cf) */
+ 0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8c,0x8b, /* sqrt(1/d0)..sqrt(1/d7) */
+ 0x8a,0x89,0x88,0x87,0x86,0x85,0x84,0x83, /* sqrt(1/d8)..sqrt(1/df) */
+ 0x83,0x82,0x81,0x80,0x7f,0x7e,0x7e,0x7d, /* sqrt(1/e0)..sqrt(1/e7) */
+ 0x7c,0x7b,0x7a,0x79,0x79,0x78,0x77,0x76, /* sqrt(1/e8)..sqrt(1/ef) */
+ 0x76,0x75,0x74,0x73,0x72,0x72,0x71,0x70, /* sqrt(1/f0)..sqrt(1/f7) */
+ 0x6f,0x6f,0x6e,0x6d,0x6d,0x6c,0x6b,0x6a, /* sqrt(1/f8)..sqrt(1/ff) */
+ 0x6a,0x69,0x68,0x68,0x67,0x66,0x66,0x65, /* sqrt(1/100)..sqrt(1/107) */
+ 0x64,0x64,0x63,0x62,0x62,0x61,0x60,0x60, /* sqrt(1/108)..sqrt(1/10f) */
+ 0x5f,0x5e,0x5e,0x5d,0x5c,0x5c,0x5b,0x5a, /* sqrt(1/110)..sqrt(1/117) */
+ 0x5a,0x59,0x59,0x58,0x57,0x57,0x56,0x56, /* sqrt(1/118)..sqrt(1/11f) */
+ 0x55,0x54,0x54,0x53,0x53,0x52,0x52,0x51, /* sqrt(1/120)..sqrt(1/127) */
+ 0x50,0x50,0x4f,0x4f,0x4e,0x4e,0x4d,0x4d, /* sqrt(1/128)..sqrt(1/12f) */
+ 0x4c,0x4b,0x4b,0x4a,0x4a,0x49,0x49,0x48, /* sqrt(1/130)..sqrt(1/137) */
+ 0x48,0x47,0x47,0x46,0x46,0x45,0x45,0x44, /* sqrt(1/138)..sqrt(1/13f) */
+ 0x44,0x43,0x43,0x42,0x42,0x41,0x41,0x40, /* sqrt(1/140)..sqrt(1/147) */
+ 0x40,0x3f,0x3f,0x3e,0x3e,0x3d,0x3d,0x3c, /* sqrt(1/148)..sqrt(1/14f) */
+ 0x3c,0x3b,0x3b,0x3a,0x3a,0x39,0x39,0x39, /* sqrt(1/150)..sqrt(1/157) */
+ 0x38,0x38,0x37,0x37,0x36,0x36,0x35,0x35, /* sqrt(1/158)..sqrt(1/15f) */
+ 0x35,0x34,0x34,0x33,0x33,0x32,0x32,0x32, /* sqrt(1/160)..sqrt(1/167) */
+ 0x31,0x31,0x30,0x30,0x2f,0x2f,0x2f,0x2e, /* sqrt(1/168)..sqrt(1/16f) */
+ 0x2e,0x2d,0x2d,0x2d,0x2c,0x2c,0x2b,0x2b, /* sqrt(1/170)..sqrt(1/177) */
+ 0x2b,0x2a,0x2a,0x29,0x29,0x29,0x28,0x28, /* sqrt(1/178)..sqrt(1/17f) */
+ 0x27,0x27,0x27,0x26,0x26,0x26,0x25,0x25, /* sqrt(1/180)..sqrt(1/187) */
+ 0x24,0x24,0x24,0x23,0x23,0x23,0x22,0x22, /* sqrt(1/188)..sqrt(1/18f) */
+ 0x21,0x21,0x21,0x20,0x20,0x20,0x1f,0x1f, /* sqrt(1/190)..sqrt(1/197) */
+ 0x1f,0x1e,0x1e,0x1e,0x1d,0x1d,0x1d,0x1c, /* sqrt(1/198)..sqrt(1/19f) */
+ 0x1c,0x1b,0x1b,0x1b,0x1a,0x1a,0x1a,0x19, /* sqrt(1/1a0)..sqrt(1/1a7) */
+ 0x19,0x19,0x18,0x18,0x18,0x18,0x17,0x17, /* sqrt(1/1a8)..sqrt(1/1af) */
+ 0x17,0x16,0x16,0x16,0x15,0x15,0x15,0x14, /* sqrt(1/1b0)..sqrt(1/1b7) */
+ 0x14,0x14,0x13,0x13,0x13,0x12,0x12,0x12, /* sqrt(1/1b8)..sqrt(1/1bf) */
+ 0x12,0x11,0x11,0x11,0x10,0x10,0x10,0x0f, /* sqrt(1/1c0)..sqrt(1/1c7) */
+ 0x0f,0x0f,0x0f,0x0e,0x0e,0x0e,0x0d,0x0d, /* sqrt(1/1c8)..sqrt(1/1cf) */
+ 0x0d,0x0c,0x0c,0x0c,0x0c,0x0b,0x0b,0x0b, /* sqrt(1/1d0)..sqrt(1/1d7) */
+ 0x0a,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x09, /* sqrt(1/1d8)..sqrt(1/1df) */
+ 0x08,0x08,0x08,0x07,0x07,0x07,0x07,0x06, /* sqrt(1/1e0)..sqrt(1/1e7) */
+ 0x06,0x06,0x06,0x05,0x05,0x05,0x04,0x04, /* sqrt(1/1e8)..sqrt(1/1ef) */
+ 0x04,0x04,0x03,0x03,0x03,0x03,0x02,0x02, /* sqrt(1/1f0)..sqrt(1/1f7) */
+ 0x02,0x02,0x01,0x01,0x01,0x01,0x00,0x00 /* sqrt(1/1f8)..sqrt(1/1ff) */
+};
+
+/* Compute s = floor(sqrt(a0)), and *rp = a0 - s^2. */
+
+#if GMP_NUMB_BITS > 32
+#define MAGIC CNST_LIMB(0x10000000000) /* 0xffe7debbfc < MAGIC < 0x232b1850f410 */
+#else
+#define MAGIC CNST_LIMB(0x100000) /* 0xfee6f < MAGIC < 0x29cbc8 */
+#endif
+
+static mp_limb_t
+mpn_sqrtrem1 (mp_ptr rp, mp_limb_t a0)
+{
+#if GMP_NUMB_BITS > 32
+ mp_limb_t a1;
+#endif
+ mp_limb_t x0, t2, t, x2;
+ unsigned abits;
+
+ ASSERT_ALWAYS (GMP_NAIL_BITS == 0);
+ ASSERT_ALWAYS (GMP_LIMB_BITS == 32 || GMP_LIMB_BITS == 64);
+ ASSERT (a0 >= GMP_NUMB_HIGHBIT / 2);
+
+ /* Use Newton iterations for approximating 1/sqrt(a) instead of sqrt(a),
+ since we can do the former without division. As part of the last
+ iteration convert from 1/sqrt(a) to sqrt(a). */
+
+ abits = a0 >> (GMP_LIMB_BITS - 1 - 8); /* extract bits for table lookup */
+ x0 = 0x100 | invsqrttab[abits - 0x80]; /* initial 1/sqrt(a) */
+
+ /* x0 is now an 8 bits approximation of 1/sqrt(a0) */
+
+#if GMP_NUMB_BITS > 32
+ a1 = a0 >> (GMP_LIMB_BITS - 1 - 32);
+ t = (mp_limb_signed_t) (CNST_LIMB(0x2000000000000) - 0x30000 - a1 * x0 * x0) >> 16;
+ x0 = (x0 << 16) + ((mp_limb_signed_t) (x0 * t) >> (16+2));
+
+ /* x0 is now a 16 bits approximation of 1/sqrt(a0) */
+
+ t2 = x0 * (a0 >> (32-8));
+ t = t2 >> 25;
+ t = ((mp_limb_signed_t) ((a0 << 14) - t * t - MAGIC) >> (32-8));
+ x0 = t2 + ((mp_limb_signed_t) (x0 * t) >> 15);
+ x0 >>= 32;
+#else
+ t2 = x0 * (a0 >> (16-8));
+ t = t2 >> 13;
+ t = ((mp_limb_signed_t) ((a0 << 6) - t * t - MAGIC) >> (16-8));
+ x0 = t2 + ((mp_limb_signed_t) (x0 * t) >> 7);
+ x0 >>= 16;
+#endif
+
+ /* x0 is now a full limb approximation of sqrt(a0) */
+
+ x2 = x0 * x0;
+ if (x2 + 2*x0 <= a0 - 1)
+ {
+ x2 += 2*x0 + 1;
+ x0++;
+ }
+
+ *rp = a0 - x2;
+ return x0;
+}
+
+
+#define Prec (GMP_NUMB_BITS >> 1)
+
+/* same as mpn_sqrtrem, but for size=2 and {np, 2} normalized
+ return cc such that {np, 2} = sp[0]^2 + cc*2^GMP_NUMB_BITS + rp[0] */
+static mp_limb_t
+mpn_sqrtrem2 (mp_ptr sp, mp_ptr rp, mp_srcptr np)
+{
+ mp_limb_t qhl, q, u, np0, sp0, rp0, q2;
+ int cc;
+
+ ASSERT (np[1] >= GMP_NUMB_HIGHBIT / 2);
+
+ np0 = np[0];
+ sp0 = mpn_sqrtrem1 (rp, np[1]);
+ qhl = 0;
+ rp0 = rp[0];
+ while (rp0 >= sp0)
+ {
+ qhl++;
+ rp0 -= sp0;
+ }
+ /* now rp0 < sp0 < 2^Prec */
+ rp0 = (rp0 << Prec) + (np0 >> Prec);
+ u = 2 * sp0;
+ q = rp0 / u;
+ u = rp0 - q * u;
+ q += (qhl & 1) << (Prec - 1);
+ qhl >>= 1; /* if qhl=1, necessary q=0 as qhl*2^Prec + q <= 2^Prec */
+ /* now we have (initial rp0)<<Prec + np0>>Prec = (qhl<<Prec + q) * (2sp0) + u */
+ sp0 = ((sp0 + qhl) << Prec) + q;
+ cc = u >> Prec;
+ rp0 = ((u << Prec) & GMP_NUMB_MASK) + (np0 & (((mp_limb_t) 1 << Prec) - 1));
+ /* subtract q * q or qhl*2^(2*Prec) from rp */
+ q2 = q * q;
+ cc -= (rp0 < q2) + qhl;
+ rp0 -= q2;
+ /* now subtract 2*q*2^Prec + 2^(2*Prec) if qhl is set */
+ if (cc < 0)
+ {
+ if (sp0 != 0)
+ {
+ rp0 += sp0;
+ cc += rp0 < sp0;
+ }
+ else
+ cc++;
+ --sp0;
+ rp0 += sp0;
+ cc += rp0 < sp0;
+ }
+
+ rp[0] = rp0;
+ sp[0] = sp0;
+ return cc;
+}
+
+/* writes in {sp, n} the square root (rounded towards zero) of {np, 2n},
+ and in {np, n} the low n limbs of the remainder, returns the high
+ limb of the remainder (which is 0 or 1).
+ Assumes {np, 2n} is normalized, i.e. np[2n-1] >= B/4
+ where B=2^GMP_NUMB_BITS. */
+static mp_limb_t
+mpn_dc_sqrtrem (mp_ptr sp, mp_ptr np, mp_size_t n)
+{
+ mp_limb_t q; /* carry out of {sp, n} */
+ int c, b; /* carry out of remainder */
+ mp_size_t l, h;
+
+ ASSERT (np[2 * n - 1] >= GMP_NUMB_HIGHBIT / 2);
+
+ if (n == 1)
+ c = mpn_sqrtrem2 (sp, np, np);
+ else
+ {
+ l = n / 2;
+ h = n - l;
+ q = mpn_dc_sqrtrem (sp + l, np + 2 * l, h);
+ if (q != 0)
+ mpn_sub_n (np + 2 * l, np + 2 * l, sp + l, h);
+ q += mpn_divrem (sp, 0, np + l, n, sp + l, h);
+ c = sp[0] & 1;
+ mpn_rshift (sp, sp, l, 1);
+ sp[l - 1] |= (q << (GMP_NUMB_BITS - 1)) & GMP_NUMB_MASK;
+ q >>= 1;
+ if (c != 0)
+ c = mpn_add_n (np + l, np + l, sp + l, h);
+ mpn_sqr (np + n, sp, l);
+ b = q + mpn_sub_n (np, np, np + n, 2 * l);
+ c -= (l == h) ? b : mpn_sub_1 (np + 2 * l, np + 2 * l, 1, (mp_limb_t) b);
+ q = mpn_add_1 (sp + l, sp + l, h, q);
+
+ if (c < 0)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ c += mpn_addlsh1_n (np, np, sp, n) + 2 * q;
+#else
+ c += mpn_addmul_1 (np, sp, n, CNST_LIMB(2)) + 2 * q;
+#endif
+ c -= mpn_sub_1 (np, np, n, CNST_LIMB(1));
+ q -= mpn_sub_1 (sp, sp, n, CNST_LIMB(1));
+ }
+ }
+
+ return c;
+}
+
+
+mp_size_t
+mpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr np, mp_size_t nn)
+{
+ mp_limb_t *tp, s0[1], cc, high, rl;
+ int c;
+ mp_size_t rn, tn;
+ TMP_DECL;
+
+ ASSERT (nn >= 0);
+ ASSERT_MPN (np, nn);
+
+ /* If OP is zero, both results are zero. */
+ if (nn == 0)
+ return 0;
+
+ ASSERT (np[nn - 1] != 0);
+ ASSERT (rp == NULL || MPN_SAME_OR_SEPARATE_P (np, rp, nn));
+ ASSERT (rp == NULL || ! MPN_OVERLAP_P (sp, (nn + 1) / 2, rp, nn));
+ ASSERT (! MPN_OVERLAP_P (sp, (nn + 1) / 2, np, nn));
+
+ high = np[nn - 1];
+ if (nn == 1 && (high & GMP_NUMB_HIGHBIT))
+ {
+ mp_limb_t r;
+ sp[0] = mpn_sqrtrem1 (&r, high);
+ if (rp != NULL)
+ rp[0] = r;
+ return r != 0;
+ }
+ count_leading_zeros (c, high);
+ c -= GMP_NAIL_BITS;
+
+ c = c / 2; /* we have to shift left by 2c bits to normalize {np, nn} */
+ tn = (nn + 1) / 2; /* 2*tn is the smallest even integer >= nn */
+
+ TMP_MARK;
+ if (nn % 2 != 0 || c > 0)
+ {
+ tp = TMP_ALLOC_LIMBS (2 * tn);
+ tp[0] = 0; /* needed only when 2*tn > nn, but saves a test */
+ if (c != 0)
+ mpn_lshift (tp + 2 * tn - nn, np, nn, 2 * c);
+ else
+ MPN_COPY (tp + 2 * tn - nn, np, nn);
+ rl = mpn_dc_sqrtrem (sp, tp, tn);
+ /* We have 2^(2k)*N = S^2 + R where k = c + (2tn-nn)*GMP_NUMB_BITS/2,
+ thus 2^(2k)*N = (S-s0)^2 + 2*S*s0 - s0^2 + R where s0=S mod 2^k */
+ c += (nn % 2) * GMP_NUMB_BITS / 2; /* c now represents k */
+ s0[0] = sp[0] & (((mp_limb_t) 1 << c) - 1); /* S mod 2^k */
+ rl += mpn_addmul_1 (tp, sp, tn, 2 * s0[0]); /* R = R + 2*s0*S */
+ cc = mpn_submul_1 (tp, s0, 1, s0[0]);
+ rl -= (tn > 1) ? mpn_sub_1 (tp + 1, tp + 1, tn - 1, cc) : cc;
+ mpn_rshift (sp, sp, tn, c);
+ tp[tn] = rl;
+ if (rp == NULL)
+ rp = tp;
+ c = c << 1;
+ if (c < GMP_NUMB_BITS)
+ tn++;
+ else
+ {
+ tp++;
+ c -= GMP_NUMB_BITS;
+ }
+ if (c != 0)
+ mpn_rshift (rp, tp, tn, c);
+ else
+ MPN_COPY_INCR (rp, tp, tn);
+ rn = tn;
+ }
+ else
+ {
+ if (rp == NULL)
+ rp = TMP_ALLOC_LIMBS (nn);
+ if (rp != np)
+ MPN_COPY (rp, np, nn);
+ rn = tn + (rp[tn] = mpn_dc_sqrtrem (sp, rp, tn));
+ }
+
+ MPN_NORMALIZE (rp, rn);
+
+ TMP_FREE;
+ return rn;
+}
diff --git a/gmp/mpn/generic/sub.c b/gmp/mpn/generic/sub.c
new file mode 100644
index 0000000000..3fbcbbe98b
--- /dev/null
+++ b/gmp/mpn/generic/sub.c
@@ -0,0 +1,34 @@
+/* mpn_sub - subtract mpn from mpn.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpn_sub 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpn/generic/sub_1.c b/gmp/mpn/generic/sub_1.c
new file mode 100644
index 0000000000..db2e6f948f
--- /dev/null
+++ b/gmp/mpn/generic/sub_1.c
@@ -0,0 +1,34 @@
+/* mpn_sub_1 - subtract limb from mpn.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpn_sub_1 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpn/generic/sub_err1_n.c b/gmp/mpn/generic/sub_err1_n.c
new file mode 100644
index 0000000000..340313a323
--- /dev/null
+++ b/gmp/mpn/generic/sub_err1_n.c
@@ -0,0 +1,101 @@
+/* mpn_sub_err1_n -- sub_n with one error term
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*
+ Computes:
+
+ (1) {rp,n} := {up,n} - {vp,n} (just like mpn_sub_n) with incoming borrow cy,
+ return value is borrow out.
+
+ (2) Let c[i+1] = borrow from i-th limb subtraction (c[0] = cy).
+ Computes c[1]*yp[n-1] + ... + c[n]*yp[0], stores two-limb result at ep.
+
+ Requires n >= 1.
+
+ None of the outputs may overlap each other or any of the inputs, except
+ that {rp,n} may be equal to {up,n} or {vp,n}.
+*/
+mp_limb_t
+mpn_sub_err1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_ptr ep, mp_srcptr yp,
+ mp_size_t n, mp_limb_t cy)
+{
+ mp_limb_t el, eh, ul, vl, yl, zl, rl, sl, cy1, cy2;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 2, up, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 2, vp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 2, yp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 2, rp, n));
+
+ yp += n - 1;
+ el = eh = 0;
+
+ do
+ {
+ yl = *yp--;
+ ul = *up++;
+ vl = *vp++;
+
+ /* ordinary sub_n */
+ SUBC_LIMB (cy1, sl, ul, vl);
+ SUBC_LIMB (cy2, rl, sl, cy);
+ cy = cy1 | cy2;
+ *rp++ = rl;
+
+ /* update (eh:el) */
+ zl = (-cy) & yl;
+ el += zl;
+ eh += el < zl;
+ }
+ while (--n);
+
+#if GMP_NAIL_BITS != 0
+ eh = (eh << GMP_NAIL_BITS) + (el >> GMP_NUMB_BITS);
+ el &= GMP_NUMB_MASK;
+#endif
+
+ ep[0] = el;
+ ep[1] = eh;
+
+ return cy;
+}
diff --git a/gmp/mpn/generic/sub_err2_n.c b/gmp/mpn/generic/sub_err2_n.c
new file mode 100644
index 0000000000..63ea2451b4
--- /dev/null
+++ b/gmp/mpn/generic/sub_err2_n.c
@@ -0,0 +1,117 @@
+/* mpn_sub_err2_n -- sub_n with two error terms
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*
+ Computes:
+
+ (1) {rp,n} := {up,n} - {vp,n} (just like mpn_sub_n) with incoming borrow cy,
+ return value is borrow out.
+
+ (2) Let c[i+1] = borrow from i-th limb subtraction (c[0] = cy).
+ Computes c[1]*yp1[n-1] + ... + c[n]*yp1[0],
+ c[1]*yp2[n-1] + ... + c[n]*yp2[0],
+ stores two-limb results at {ep,2} and {ep+2,2} respectively.
+
+ Requires n >= 1.
+
+ None of the outputs may overlap each other or any of the inputs, except
+ that {rp,n} may be equal to {up,n} or {vp,n}.
+*/
+mp_limb_t
+mpn_sub_err2_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_ptr ep, mp_srcptr yp1, mp_srcptr yp2,
+ mp_size_t n, mp_limb_t cy)
+{
+ mp_limb_t el1, eh1, el2, eh2, ul, vl, yl1, yl2, zl1, zl2, rl, sl, cy1, cy2;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp1, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp2, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, up, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, vp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, yp1, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, yp2, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 4, rp, n));
+
+ yp1 += n - 1;
+ yp2 += n - 1;
+ el1 = eh1 = 0;
+ el2 = eh2 = 0;
+
+ do
+ {
+ yl1 = *yp1--;
+ yl2 = *yp2--;
+ ul = *up++;
+ vl = *vp++;
+
+ /* ordinary sub_n */
+ SUBC_LIMB (cy1, sl, ul, vl);
+ SUBC_LIMB (cy2, rl, sl, cy);
+ cy = cy1 | cy2;
+ *rp++ = rl;
+
+ /* update (eh1:el1) */
+ zl1 = (-cy) & yl1;
+ el1 += zl1;
+ eh1 += el1 < zl1;
+
+ /* update (eh2:el2) */
+ zl2 = (-cy) & yl2;
+ el2 += zl2;
+ eh2 += el2 < zl2;
+ }
+ while (--n);
+
+#if GMP_NAIL_BITS != 0
+ eh1 = (eh1 << GMP_NAIL_BITS) + (el1 >> GMP_NUMB_BITS);
+ el1 &= GMP_NUMB_MASK;
+ eh2 = (eh2 << GMP_NAIL_BITS) + (el2 >> GMP_NUMB_BITS);
+ el2 &= GMP_NUMB_MASK;
+#endif
+
+ ep[0] = el1;
+ ep[1] = eh1;
+ ep[2] = el2;
+ ep[3] = eh2;
+
+ return cy;
+}
diff --git a/gmp/mpn/generic/sub_err3_n.c b/gmp/mpn/generic/sub_err3_n.c
new file mode 100644
index 0000000000..a80e05d0d9
--- /dev/null
+++ b/gmp/mpn/generic/sub_err3_n.c
@@ -0,0 +1,132 @@
+/* mpn_sub_err3_n -- sub_n with three error terms
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*
+ Computes:
+
+ (1) {rp,n} := {up,n} - {vp,n} (just like mpn_sub_n) with incoming borrow cy,
+ return value is borrow out.
+
+ (2) Let c[i+1] = borrow from i-th limb subtraction (c[0] = cy).
+ Computes c[1]*yp1[n-1] + ... + c[n]*yp1[0],
+ c[1]*yp2[n-1] + ... + c[n]*yp2[0],
+ c[1]*yp3[n-1] + ... + c[n]*yp3[0],
+ stores two-limb results at {ep,2}, {ep+2,2} and {ep+4,2} respectively.
+
+ Requires n >= 1.
+
+ None of the outputs may overlap each other or any of the inputs, except
+ that {rp,n} may be equal to {up,n} or {vp,n}.
+*/
+mp_limb_t
+mpn_sub_err3_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_ptr ep, mp_srcptr yp1, mp_srcptr yp2, mp_srcptr yp3,
+ mp_size_t n, mp_limb_t cy)
+{
+ mp_limb_t el1, eh1, el2, eh2, el3, eh3, ul, vl, yl1, yl2, yl3, zl1, zl2, zl3, rl, sl, cy1, cy2;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp1, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp2, n));
+ ASSERT (! MPN_OVERLAP_P (rp, n, yp3, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, up, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, vp, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, yp1, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, yp2, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, yp3, n));
+ ASSERT (! MPN_OVERLAP_P (ep, 6, rp, n));
+
+ yp1 += n - 1;
+ yp2 += n - 1;
+ yp3 += n - 1;
+ el1 = eh1 = 0;
+ el2 = eh2 = 0;
+ el3 = eh3 = 0;
+
+ do
+ {
+ yl1 = *yp1--;
+ yl2 = *yp2--;
+ yl3 = *yp3--;
+ ul = *up++;
+ vl = *vp++;
+
+ /* ordinary sub_n */
+ SUBC_LIMB (cy1, sl, ul, vl);
+ SUBC_LIMB (cy2, rl, sl, cy);
+ cy = cy1 | cy2;
+ *rp++ = rl;
+
+ /* update (eh1:el1) */
+ zl1 = (-cy) & yl1;
+ el1 += zl1;
+ eh1 += el1 < zl1;
+
+ /* update (eh2:el2) */
+ zl2 = (-cy) & yl2;
+ el2 += zl2;
+ eh2 += el2 < zl2;
+
+ /* update (eh3:el3) */
+ zl3 = (-cy) & yl3;
+ el3 += zl3;
+ eh3 += el3 < zl3;
+ }
+ while (--n);
+
+#if GMP_NAIL_BITS != 0
+ eh1 = (eh1 << GMP_NAIL_BITS) + (el1 >> GMP_NUMB_BITS);
+ el1 &= GMP_NUMB_MASK;
+ eh2 = (eh2 << GMP_NAIL_BITS) + (el2 >> GMP_NUMB_BITS);
+ el2 &= GMP_NUMB_MASK;
+ eh3 = (eh3 << GMP_NAIL_BITS) + (el3 >> GMP_NUMB_BITS);
+ el3 &= GMP_NUMB_MASK;
+#endif
+
+ ep[0] = el1;
+ ep[1] = eh1;
+ ep[2] = el2;
+ ep[3] = eh2;
+ ep[4] = el3;
+ ep[5] = eh3;
+
+ return cy;
+}
diff --git a/gmp/mpn/generic/sub_n.c b/gmp/mpn/generic/sub_n.c
new file mode 100644
index 0000000000..29de2d2d89
--- /dev/null
+++ b/gmp/mpn/generic/sub_n.c
@@ -0,0 +1,90 @@
+/* mpn_sub_n -- Subtract equal length limb vectors.
+
+Copyright 1992-1994, 1996, 2000, 2002, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#if GMP_NAIL_BITS == 0
+
+mp_limb_t
+mpn_sub_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t ul, vl, sl, rl, cy, cy1, cy2;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_INCR_P (rp, vp, n));
+
+ cy = 0;
+ do
+ {
+ ul = *up++;
+ vl = *vp++;
+ sl = ul - vl;
+ cy1 = sl > ul;
+ rl = sl - cy;
+ cy2 = rl > sl;
+ cy = cy1 | cy2;
+ *rp++ = rl;
+ }
+ while (--n != 0);
+
+ return cy;
+}
+
+#endif
+
+#if GMP_NAIL_BITS >= 1
+
+mp_limb_t
+mpn_sub_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t ul, vl, rl, cy;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_INCR_P (rp, up, n));
+ ASSERT (MPN_SAME_OR_INCR_P (rp, vp, n));
+
+ cy = 0;
+ do
+ {
+ ul = *up++;
+ vl = *vp++;
+ rl = ul - vl - cy;
+ cy = rl >> (GMP_LIMB_BITS - 1);
+ *rp++ = rl & GMP_NUMB_MASK;
+ }
+ while (--n != 0);
+
+ return cy;
+}
+
+#endif
diff --git a/gmp/mpn/generic/submul_1.c b/gmp/mpn/generic/submul_1.c
new file mode 100644
index 0000000000..fbc3501389
--- /dev/null
+++ b/gmp/mpn/generic/submul_1.c
@@ -0,0 +1,139 @@
+/* mpn_submul_1 -- multiply the N long limb vector pointed to by UP by VL,
+ subtract the N least significant limbs of the product from the limb
+ vector pointed to by RP. Return the most significant limb of the
+ product, adjusted for carry-out from the subtraction.
+
+Copyright 1992-1994, 1996, 2000, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#if GMP_NAIL_BITS == 0
+
+mp_limb_t
+mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t ul, cl, hpl, lpl, rl;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+
+ cl = 0;
+ do
+ {
+ ul = *up++;
+ umul_ppmm (hpl, lpl, ul, vl);
+
+ lpl += cl;
+ cl = (lpl < cl) + hpl;
+
+ rl = *rp;
+ lpl = rl - lpl;
+ cl += lpl > rl;
+ *rp++ = lpl;
+ }
+ while (--n != 0);
+
+ return cl;
+}
+
+#endif
+
+#if GMP_NAIL_BITS == 1
+
+mp_limb_t
+mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t shifted_vl, ul, rl, lpl, hpl, prev_hpl, cl, xl, c1, c2, c3;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT_MPN (rp, n);
+ ASSERT_MPN (up, n);
+ ASSERT_LIMB (vl);
+
+ shifted_vl = vl << GMP_NAIL_BITS;
+ cl = 0;
+ prev_hpl = 0;
+ do
+ {
+ ul = *up++;
+ rl = *rp;
+ umul_ppmm (hpl, lpl, ul, shifted_vl);
+ lpl >>= GMP_NAIL_BITS;
+ SUBC_LIMB (c1, xl, rl, prev_hpl);
+ SUBC_LIMB (c2, xl, xl, lpl);
+ SUBC_LIMB (c3, xl, xl, cl);
+ cl = c1 + c2 + c3;
+ *rp++ = xl;
+ prev_hpl = hpl;
+ }
+ while (--n != 0);
+
+ return prev_hpl + cl;
+}
+
+#endif
+
+#if GMP_NAIL_BITS >= 2
+
+mp_limb_t
+mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
+{
+ mp_limb_t shifted_vl, ul, rl, lpl, hpl, prev_hpl, xw, cl, xl;
+
+ ASSERT (n >= 1);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
+ ASSERT_MPN (rp, n);
+ ASSERT_MPN (up, n);
+ ASSERT_LIMB (vl);
+
+ shifted_vl = vl << GMP_NAIL_BITS;
+ cl = 0;
+ prev_hpl = 0;
+ do
+ {
+ ul = *up++;
+ rl = *rp;
+ umul_ppmm (hpl, lpl, ul, shifted_vl);
+ lpl >>= GMP_NAIL_BITS;
+ xw = rl - (prev_hpl + lpl) + cl;
+ cl = (mp_limb_signed_t) xw >> GMP_NUMB_BITS; /* FIXME: non-portable */
+ xl = xw & GMP_NUMB_MASK;
+ *rp++ = xl;
+ prev_hpl = hpl;
+ }
+ while (--n != 0);
+
+ return prev_hpl - cl;
+}
+
+#endif
diff --git a/gmp/mpn/generic/tdiv_qr.c b/gmp/mpn/generic/tdiv_qr.c
new file mode 100644
index 0000000000..be213b0467
--- /dev/null
+++ b/gmp/mpn/generic/tdiv_qr.c
@@ -0,0 +1,389 @@
+/* mpn_tdiv_qr -- Divide the numerator (np,nn) by the denominator (dp,dn) and
+ write the nn-dn+1 quotient limbs at qp and the dn remainder limbs at rp. If
+ qxn is non-zero, generate that many fraction limbs and append them after the
+ other quotient limbs, and update the remainder accordingly. The input
+ operands are unaffected.
+
+ Preconditions:
+ 1. The most significant limb of of the divisor must be non-zero.
+ 2. nn >= dn, even if qxn is non-zero. (??? relax this ???)
+
+ The time complexity of this is O(qn*qn+M(dn,qn)), where M(m,n) is the time
+ complexity of multiplication.
+
+Copyright 1997, 2000-2002, 2005, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+void
+mpn_tdiv_qr (mp_ptr qp, mp_ptr rp, mp_size_t qxn,
+ mp_srcptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn)
+{
+ ASSERT_ALWAYS (qxn == 0);
+
+ ASSERT (nn >= 0);
+ ASSERT (dn >= 0);
+ ASSERT (dn == 0 || dp[dn - 1] != 0);
+ ASSERT (! MPN_OVERLAP_P (qp, nn - dn + 1 + qxn, np, nn));
+ ASSERT (! MPN_OVERLAP_P (qp, nn - dn + 1 + qxn, dp, dn));
+
+ switch (dn)
+ {
+ case 0:
+ DIVIDE_BY_ZERO;
+
+ case 1:
+ {
+ rp[0] = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, dp[0]);
+ return;
+ }
+
+ case 2:
+ {
+ mp_ptr n2p, d2p;
+ mp_limb_t qhl, cy;
+ TMP_DECL;
+ TMP_MARK;
+ if ((dp[1] & GMP_NUMB_HIGHBIT) == 0)
+ {
+ int cnt;
+ mp_limb_t dtmp[2];
+ count_leading_zeros (cnt, dp[1]);
+ cnt -= GMP_NAIL_BITS;
+ d2p = dtmp;
+ d2p[1] = (dp[1] << cnt) | (dp[0] >> (GMP_NUMB_BITS - cnt));
+ d2p[0] = (dp[0] << cnt) & GMP_NUMB_MASK;
+ n2p = TMP_ALLOC_LIMBS (nn + 1);
+ cy = mpn_lshift (n2p, np, nn, cnt);
+ n2p[nn] = cy;
+ qhl = mpn_divrem_2 (qp, 0L, n2p, nn + (cy != 0), d2p);
+ if (cy == 0)
+ qp[nn - 2] = qhl; /* always store nn-2+1 quotient limbs */
+ rp[0] = (n2p[0] >> cnt)
+ | ((n2p[1] << (GMP_NUMB_BITS - cnt)) & GMP_NUMB_MASK);
+ rp[1] = (n2p[1] >> cnt);
+ }
+ else
+ {
+ d2p = (mp_ptr) dp;
+ n2p = TMP_ALLOC_LIMBS (nn);
+ MPN_COPY (n2p, np, nn);
+ qhl = mpn_divrem_2 (qp, 0L, n2p, nn, d2p);
+ qp[nn - 2] = qhl; /* always store nn-2+1 quotient limbs */
+ rp[0] = n2p[0];
+ rp[1] = n2p[1];
+ }
+ TMP_FREE;
+ return;
+ }
+
+ default:
+ {
+ int adjust;
+ gmp_pi1_t dinv;
+ TMP_DECL;
+ TMP_MARK;
+ adjust = np[nn - 1] >= dp[dn - 1]; /* conservative tests for quotient size */
+ if (nn + adjust >= 2 * dn)
+ {
+ mp_ptr n2p, d2p;
+ mp_limb_t cy;
+ int cnt;
+
+ qp[nn - dn] = 0; /* zero high quotient limb */
+ if ((dp[dn - 1] & GMP_NUMB_HIGHBIT) == 0) /* normalize divisor */
+ {
+ count_leading_zeros (cnt, dp[dn - 1]);
+ cnt -= GMP_NAIL_BITS;
+ d2p = TMP_ALLOC_LIMBS (dn);
+ mpn_lshift (d2p, dp, dn, cnt);
+ n2p = TMP_ALLOC_LIMBS (nn + 1);
+ cy = mpn_lshift (n2p, np, nn, cnt);
+ n2p[nn] = cy;
+ nn += adjust;
+ }
+ else
+ {
+ cnt = 0;
+ d2p = (mp_ptr) dp;
+ n2p = TMP_ALLOC_LIMBS (nn + 1);
+ MPN_COPY (n2p, np, nn);
+ n2p[nn] = 0;
+ nn += adjust;
+ }
+
+ invert_pi1 (dinv, d2p[dn - 1], d2p[dn - 2]);
+ if (BELOW_THRESHOLD (dn, DC_DIV_QR_THRESHOLD))
+ mpn_sbpi1_div_qr (qp, n2p, nn, d2p, dn, dinv.inv32);
+ else if (BELOW_THRESHOLD (dn, MUPI_DIV_QR_THRESHOLD) || /* fast condition */
+ BELOW_THRESHOLD (nn, 2 * MU_DIV_QR_THRESHOLD) || /* fast condition */
+ (double) (2 * (MU_DIV_QR_THRESHOLD - MUPI_DIV_QR_THRESHOLD)) * dn /* slow... */
+ + (double) MUPI_DIV_QR_THRESHOLD * nn > (double) dn * nn) /* ...condition */
+ mpn_dcpi1_div_qr (qp, n2p, nn, d2p, dn, &dinv);
+ else
+ {
+ mp_size_t itch = mpn_mu_div_qr_itch (nn, dn, 0);
+ mp_ptr scratch = TMP_ALLOC_LIMBS (itch);
+ mpn_mu_div_qr (qp, rp, n2p, nn, d2p, dn, scratch);
+ n2p = rp;
+ }
+
+ if (cnt != 0)
+ mpn_rshift (rp, n2p, dn, cnt);
+ else
+ MPN_COPY (rp, n2p, dn);
+ TMP_FREE;
+ return;
+ }
+
+ /* When we come here, the numerator/partial remainder is less
+ than twice the size of the denominator. */
+
+ {
+ /* Problem:
+
+ Divide a numerator N with nn limbs by a denominator D with dn
+ limbs forming a quotient of qn=nn-dn+1 limbs. When qn is small
+ compared to dn, conventional division algorithms perform poorly.
+ We want an algorithm that has an expected running time that is
+ dependent only on qn.
+
+ Algorithm (very informally stated):
+
+ 1) Divide the 2 x qn most significant limbs from the numerator
+ by the qn most significant limbs from the denominator. Call
+ the result qest. This is either the correct quotient, but
+ might be 1 or 2 too large. Compute the remainder from the
+ division. (This step is implemented by a mpn_divrem call.)
+
+ 2) Is the most significant limb from the remainder < p, where p
+ is the product of the most significant limb from the quotient
+ and the next(d)? (Next(d) denotes the next ignored limb from
+ the denominator.) If it is, decrement qest, and adjust the
+ remainder accordingly.
+
+ 3) Is the remainder >= qest? If it is, qest is the desired
+ quotient. The algorithm terminates.
+
+ 4) Subtract qest x next(d) from the remainder. If there is
+ borrow out, decrement qest, and adjust the remainder
+ accordingly.
+
+ 5) Skip one word from the denominator (i.e., let next(d) denote
+ the next less significant limb. */
+
+ mp_size_t qn;
+ mp_ptr n2p, d2p;
+ mp_ptr tp;
+ mp_limb_t cy;
+ mp_size_t in, rn;
+ mp_limb_t quotient_too_large;
+ unsigned int cnt;
+
+ qn = nn - dn;
+ qp[qn] = 0; /* zero high quotient limb */
+ qn += adjust; /* qn cannot become bigger */
+
+ if (qn == 0)
+ {
+ MPN_COPY (rp, np, dn);
+ TMP_FREE;
+ return;
+ }
+
+ in = dn - qn; /* (at least partially) ignored # of limbs in ops */
+ /* Normalize denominator by shifting it to the left such that its
+ most significant bit is set. Then shift the numerator the same
+ amount, to mathematically preserve quotient. */
+ if ((dp[dn - 1] & GMP_NUMB_HIGHBIT) == 0)
+ {
+ count_leading_zeros (cnt, dp[dn - 1]);
+ cnt -= GMP_NAIL_BITS;
+
+ d2p = TMP_ALLOC_LIMBS (qn);
+ mpn_lshift (d2p, dp + in, qn, cnt);
+ d2p[0] |= dp[in - 1] >> (GMP_NUMB_BITS - cnt);
+
+ n2p = TMP_ALLOC_LIMBS (2 * qn + 1);
+ cy = mpn_lshift (n2p, np + nn - 2 * qn, 2 * qn, cnt);
+ if (adjust)
+ {
+ n2p[2 * qn] = cy;
+ n2p++;
+ }
+ else
+ {
+ n2p[0] |= np[nn - 2 * qn - 1] >> (GMP_NUMB_BITS - cnt);
+ }
+ }
+ else
+ {
+ cnt = 0;
+ d2p = (mp_ptr) dp + in;
+
+ n2p = TMP_ALLOC_LIMBS (2 * qn + 1);
+ MPN_COPY (n2p, np + nn - 2 * qn, 2 * qn);
+ if (adjust)
+ {
+ n2p[2 * qn] = 0;
+ n2p++;
+ }
+ }
+
+ /* Get an approximate quotient using the extracted operands. */
+ if (qn == 1)
+ {
+ mp_limb_t q0, r0;
+ udiv_qrnnd (q0, r0, n2p[1], n2p[0] << GMP_NAIL_BITS, d2p[0] << GMP_NAIL_BITS);
+ n2p[0] = r0 >> GMP_NAIL_BITS;
+ qp[0] = q0;
+ }
+ else if (qn == 2)
+ mpn_divrem_2 (qp, 0L, n2p, 4L, d2p); /* FIXME: obsolete function */
+ else
+ {
+ invert_pi1 (dinv, d2p[qn - 1], d2p[qn - 2]);
+ if (BELOW_THRESHOLD (qn, DC_DIV_QR_THRESHOLD))
+ mpn_sbpi1_div_qr (qp, n2p, 2 * qn, d2p, qn, dinv.inv32);
+ else if (BELOW_THRESHOLD (qn, MU_DIV_QR_THRESHOLD))
+ mpn_dcpi1_div_qr (qp, n2p, 2 * qn, d2p, qn, &dinv);
+ else
+ {
+ mp_size_t itch = mpn_mu_div_qr_itch (2 * qn, qn, 0);
+ mp_ptr scratch = TMP_ALLOC_LIMBS (itch);
+ mp_ptr r2p = rp;
+ if (np == r2p) /* If N and R share space, put ... */
+ r2p += nn - qn; /* intermediate remainder at N's upper end. */
+ mpn_mu_div_qr (qp, r2p, n2p, 2 * qn, d2p, qn, scratch);
+ MPN_COPY (n2p, r2p, qn);
+ }
+ }
+
+ rn = qn;
+ /* Multiply the first ignored divisor limb by the most significant
+ quotient limb. If that product is > the partial remainder's
+ most significant limb, we know the quotient is too large. This
+ test quickly catches most cases where the quotient is too large;
+ it catches all cases where the quotient is 2 too large. */
+ {
+ mp_limb_t dl, x;
+ mp_limb_t h, dummy;
+
+ if (in - 2 < 0)
+ dl = 0;
+ else
+ dl = dp[in - 2];
+
+#if GMP_NAIL_BITS == 0
+ x = (dp[in - 1] << cnt) | ((dl >> 1) >> ((~cnt) % GMP_LIMB_BITS));
+#else
+ x = (dp[in - 1] << cnt) & GMP_NUMB_MASK;
+ if (cnt != 0)
+ x |= dl >> (GMP_NUMB_BITS - cnt);
+#endif
+ umul_ppmm (h, dummy, x, qp[qn - 1] << GMP_NAIL_BITS);
+
+ if (n2p[qn - 1] < h)
+ {
+ mp_limb_t cy;
+
+ mpn_decr_u (qp, (mp_limb_t) 1);
+ cy = mpn_add_n (n2p, n2p, d2p, qn);
+ if (cy)
+ {
+ /* The partial remainder is safely large. */
+ n2p[qn] = cy;
+ ++rn;
+ }
+ }
+ }
+
+ quotient_too_large = 0;
+ if (cnt != 0)
+ {
+ mp_limb_t cy1, cy2;
+
+ /* Append partially used numerator limb to partial remainder. */
+ cy1 = mpn_lshift (n2p, n2p, rn, GMP_NUMB_BITS - cnt);
+ n2p[0] |= np[in - 1] & (GMP_NUMB_MASK >> cnt);
+
+ /* Update partial remainder with partially used divisor limb. */
+ cy2 = mpn_submul_1 (n2p, qp, qn, dp[in - 1] & (GMP_NUMB_MASK >> cnt));
+ if (qn != rn)
+ {
+ ASSERT_ALWAYS (n2p[qn] >= cy2);
+ n2p[qn] -= cy2;
+ }
+ else
+ {
+ n2p[qn] = cy1 - cy2; /* & GMP_NUMB_MASK; */
+
+ quotient_too_large = (cy1 < cy2);
+ ++rn;
+ }
+ --in;
+ }
+ /* True: partial remainder now is neutral, i.e., it is not shifted up. */
+
+ tp = TMP_ALLOC_LIMBS (dn);
+
+ if (in < qn)
+ {
+ if (in == 0)
+ {
+ MPN_COPY (rp, n2p, rn);
+ ASSERT_ALWAYS (rn == dn);
+ goto foo;
+ }
+ mpn_mul (tp, qp, qn, dp, in);
+ }
+ else
+ mpn_mul (tp, dp, in, qp, qn);
+
+ cy = mpn_sub (n2p, n2p, rn, tp + in, qn);
+ MPN_COPY (rp + in, n2p, dn - in);
+ quotient_too_large |= cy;
+ cy = mpn_sub_n (rp, np, tp, in);
+ cy = mpn_sub_1 (rp + in, rp + in, rn, cy);
+ quotient_too_large |= cy;
+ foo:
+ if (quotient_too_large)
+ {
+ mpn_decr_u (qp, (mp_limb_t) 1);
+ mpn_add_n (rp, rp, dp, dn);
+ }
+ }
+ TMP_FREE;
+ return;
+ }
+ }
+}
diff --git a/gmp/mpn/generic/toom22_mul.c b/gmp/mpn/generic/toom22_mul.c
new file mode 100644
index 0000000000..36ac29b72d
--- /dev/null
+++ b/gmp/mpn/generic/toom22_mul.c
@@ -0,0 +1,210 @@
+/* mpn_toom22_mul -- Multiply {ap,an} and {bp,bn} where an >= bn. Or more
+ accurately, bn <= an < 2bn.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: -1, 0, +inf
+
+ <-s--><--n-->
+ ____ ______
+ |_a1_|___a0_|
+ |b1_|___b0_|
+ <-t-><--n-->
+
+ v0 = a0 * b0 # A(0)*B(0)
+ vm1 = (a0- a1)*(b0- b1) # A(-1)*B(-1)
+ vinf= a1 * b1 # A(inf)*B(inf)
+*/
+
+#if TUNE_PROGRAM_BUILD || WANT_FAT_BINARY
+#define MAYBE_mul_toom22 1
+#else
+#define MAYBE_mul_toom22 \
+ (MUL_TOOM33_THRESHOLD >= 2 * MUL_TOOM22_THRESHOLD)
+#endif
+
+#define TOOM22_MUL_N_REC(p, a, b, n, ws) \
+ do { \
+ if (! MAYBE_mul_toom22 \
+ || BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD)) \
+ mpn_mul_basecase (p, a, n, b, n); \
+ else \
+ mpn_toom22_mul (p, a, n, b, n, ws); \
+ } while (0)
+
+/* Normally, this calls mul_basecase or toom22_mul. But when when the fraction
+ MUL_TOOM33_THRESHOLD / MUL_TOOM22_THRESHOLD is large, an initially small
+ relative unbalance will become a larger and larger relative unbalance with
+ each recursion (the difference s-t will be invariant over recursive calls).
+ Therefore, we need to call toom32_mul. FIXME: Suppress depending on
+ MUL_TOOM33_THRESHOLD / MUL_TOOM22_THRESHOLD and on MUL_TOOM22_THRESHOLD. */
+#define TOOM22_MUL_REC(p, a, an, b, bn, ws) \
+ do { \
+ if (! MAYBE_mul_toom22 \
+ || BELOW_THRESHOLD (bn, MUL_TOOM22_THRESHOLD)) \
+ mpn_mul_basecase (p, a, an, b, bn); \
+ else if (4 * an < 5 * bn) \
+ mpn_toom22_mul (p, a, an, b, bn, ws); \
+ else \
+ mpn_toom32_mul (p, a, an, b, bn, ws); \
+ } while (0)
+
+void
+mpn_toom22_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn,
+ mp_ptr scratch)
+{
+ const int __gmpn_cpuvec_initialized = 1;
+ mp_size_t n, s, t;
+ int vm1_neg;
+ mp_limb_t cy, cy2;
+ mp_ptr asm1;
+ mp_ptr bsm1;
+
+#define a0 ap
+#define a1 (ap + n)
+#define b0 bp
+#define b1 (bp + n)
+
+ s = an >> 1;
+ n = an - s;
+ t = bn - n;
+
+ ASSERT (an >= bn);
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= s);
+
+ asm1 = pp;
+ bsm1 = pp + n;
+
+ vm1_neg = 0;
+
+ /* Compute asm1. */
+ if (s == n)
+ {
+ if (mpn_cmp (a0, a1, n) < 0)
+ {
+ mpn_sub_n (asm1, a1, a0, n);
+ vm1_neg = 1;
+ }
+ else
+ {
+ mpn_sub_n (asm1, a0, a1, n);
+ }
+ }
+ else
+ {
+ if (mpn_zero_p (a0 + s, n - s) && mpn_cmp (a0, a1, s) < 0)
+ {
+ mpn_sub_n (asm1, a1, a0, s);
+ MPN_ZERO (asm1 + s, n - s);
+ vm1_neg = 1;
+ }
+ else
+ {
+ mpn_sub (asm1, a0, n, a1, s);
+ }
+ }
+
+ /* Compute bsm1. */
+ if (t == n)
+ {
+ if (mpn_cmp (b0, b1, n) < 0)
+ {
+ mpn_sub_n (bsm1, b1, b0, n);
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ mpn_sub_n (bsm1, b0, b1, n);
+ }
+ }
+ else
+ {
+ if (mpn_zero_p (b0 + t, n - t) && mpn_cmp (b0, b1, t) < 0)
+ {
+ mpn_sub_n (bsm1, b1, b0, t);
+ MPN_ZERO (bsm1 + t, n - t);
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ mpn_sub (bsm1, b0, n, b1, t);
+ }
+ }
+
+#define v0 pp /* 2n */
+#define vinf (pp + 2 * n) /* s+t */
+#define vm1 scratch /* 2n */
+#define scratch_out scratch + 2 * n
+
+ /* vm1, 2n limbs */
+ TOOM22_MUL_N_REC (vm1, asm1, bsm1, n, scratch_out);
+
+ if (s > t) TOOM22_MUL_REC (vinf, a1, s, b1, t, scratch_out);
+ else TOOM22_MUL_N_REC (vinf, a1, b1, s, scratch_out);
+
+ /* v0, 2n limbs */
+ TOOM22_MUL_N_REC (v0, ap, bp, n, scratch_out);
+
+ /* H(v0) + L(vinf) */
+ cy = mpn_add_n (pp + 2 * n, v0 + n, vinf, n);
+
+ /* L(v0) + H(v0) */
+ cy2 = cy + mpn_add_n (pp + n, pp + 2 * n, v0, n);
+
+ /* L(vinf) + H(vinf) */
+ cy += mpn_add (pp + 2 * n, pp + 2 * n, n, vinf + n, s + t - n);
+
+ if (vm1_neg)
+ cy += mpn_add_n (pp + n, pp + n, vm1, 2 * n);
+ else
+ cy -= mpn_sub_n (pp + n, pp + n, vm1, 2 * n);
+
+ ASSERT (cy + 1 <= 3);
+ ASSERT (cy2 <= 2);
+
+ mpn_incr_u (pp + 2 * n, cy2);
+ if (LIKELY (cy <= 2))
+ mpn_incr_u (pp + 3 * n, cy);
+ else
+ mpn_decr_u (pp + 3 * n, 1);
+}
diff --git a/gmp/mpn/generic/toom2_sqr.c b/gmp/mpn/generic/toom2_sqr.c
new file mode 100644
index 0000000000..2f2fdaee6f
--- /dev/null
+++ b/gmp/mpn/generic/toom2_sqr.c
@@ -0,0 +1,146 @@
+/* mpn_toom2_sqr -- Square {ap,an}.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: -1, 0, +inf
+
+ <-s--><--n-->
+ ____ ______
+ |_a1_|___a0_|
+
+ v0 = a0 ^2 # A(0)^2
+ vm1 = (a0- a1)^2 # A(-1)^2
+ vinf= a1 ^2 # A(inf)^2
+*/
+
+#if TUNE_PROGRAM_BUILD || WANT_FAT_BINARY
+#define MAYBE_sqr_toom2 1
+#else
+#define MAYBE_sqr_toom2 \
+ (SQR_TOOM3_THRESHOLD >= 2 * SQR_TOOM2_THRESHOLD)
+#endif
+
+#define TOOM2_SQR_REC(p, a, n, ws) \
+ do { \
+ if (! MAYBE_sqr_toom2 \
+ || BELOW_THRESHOLD (n, SQR_TOOM2_THRESHOLD)) \
+ mpn_sqr_basecase (p, a, n); \
+ else \
+ mpn_toom2_sqr (p, a, n, ws); \
+ } while (0)
+
+void
+mpn_toom2_sqr (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_ptr scratch)
+{
+ const int __gmpn_cpuvec_initialized = 1;
+ mp_size_t n, s;
+ mp_limb_t cy, cy2;
+ mp_ptr asm1;
+
+#define a0 ap
+#define a1 (ap + n)
+
+ s = an >> 1;
+ n = an - s;
+
+ ASSERT (0 < s && s <= n);
+
+ asm1 = pp;
+
+ /* Compute asm1. */
+ if (s == n)
+ {
+ if (mpn_cmp (a0, a1, n) < 0)
+ {
+ mpn_sub_n (asm1, a1, a0, n);
+ }
+ else
+ {
+ mpn_sub_n (asm1, a0, a1, n);
+ }
+ }
+ else
+ {
+ if (mpn_zero_p (a0 + s, n - s) && mpn_cmp (a0, a1, s) < 0)
+ {
+ mpn_sub_n (asm1, a1, a0, s);
+ MPN_ZERO (asm1 + s, n - s);
+ }
+ else
+ {
+ mpn_sub (asm1, a0, n, a1, s);
+ }
+ }
+
+#define v0 pp /* 2n */
+#define vinf (pp + 2 * n) /* s+s */
+#define vm1 scratch /* 2n */
+#define scratch_out scratch + 2 * n
+
+ /* vm1, 2n limbs */
+ TOOM2_SQR_REC (vm1, asm1, n, scratch_out);
+
+ /* vinf, s+s limbs */
+ TOOM2_SQR_REC (vinf, a1, s, scratch_out);
+
+ /* v0, 2n limbs */
+ TOOM2_SQR_REC (v0, ap, n, scratch_out);
+
+ /* H(v0) + L(vinf) */
+ cy = mpn_add_n (pp + 2 * n, v0 + n, vinf, n);
+
+ /* L(v0) + H(v0) */
+ cy2 = cy + mpn_add_n (pp + n, pp + 2 * n, v0, n);
+
+ /* L(vinf) + H(vinf) */
+ cy += mpn_add (pp + 2 * n, pp + 2 * n, n, vinf + n, s + s - n);
+
+ cy -= mpn_sub_n (pp + n, pp + n, vm1, 2 * n);
+
+ ASSERT (cy + 1 <= 3);
+ ASSERT (cy2 <= 2);
+
+ mpn_incr_u (pp + 2 * n, cy2);
+ if (LIKELY (cy <= 2))
+ mpn_incr_u (pp + 3 * n, cy);
+ else
+ mpn_decr_u (pp + 3 * n, 1);
+}
diff --git a/gmp/mpn/generic/toom32_mul.c b/gmp/mpn/generic/toom32_mul.c
new file mode 100644
index 0000000000..0b05669cc4
--- /dev/null
+++ b/gmp/mpn/generic/toom32_mul.c
@@ -0,0 +1,323 @@
+/* mpn_toom32_mul -- Multiply {ap,an} and {bp,bn} where an is nominally 1.5
+ times as large as bn. Or more accurately, bn < an < 3bn.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+ Improvements by Marco Bodrato and Niels Möller.
+
+ The idea of applying toom to unbalanced multiplication is due to Marco
+ Bodrato and Alberto Zanoni.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: -1, 0, +1, +inf
+
+ <-s-><--n--><--n-->
+ ___ ______ ______
+ |a2_|___a1_|___a0_|
+ |_b1_|___b0_|
+ <-t--><--n-->
+
+ v0 = a0 * b0 # A(0)*B(0)
+ v1 = (a0+ a1+ a2)*(b0+ b1) # A(1)*B(1) ah <= 2 bh <= 1
+ vm1 = (a0- a1+ a2)*(b0- b1) # A(-1)*B(-1) |ah| <= 1 bh = 0
+ vinf= a2 * b1 # A(inf)*B(inf)
+*/
+
+#define TOOM32_MUL_N_REC(p, a, b, n, ws) \
+ do { \
+ mpn_mul_n (p, a, b, n); \
+ } while (0)
+
+void
+mpn_toom32_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn,
+ mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ int vm1_neg;
+ mp_limb_t cy;
+ mp_limb_signed_t hi;
+ mp_limb_t ap1_hi, bp1_hi;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2 * n)
+#define b0 bp
+#define b1 (bp + n)
+
+ /* Required, to ensure that s + t >= n. */
+ ASSERT (bn + 2 <= an && an + 6 <= 3*bn);
+
+ n = 1 + (2 * an >= 3 * bn ? (an - 1) / (size_t) 3 : (bn - 1) >> 1);
+
+ s = an - 2 * n;
+ t = bn - n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+ ASSERT (s + t >= n);
+
+ /* Product area of size an + bn = 3*n + s + t >= 4*n + 2. */
+#define ap1 (pp) /* n, most significant limb in ap1_hi */
+#define bp1 (pp + n) /* n, most significant bit in bp1_hi */
+#define am1 (pp + 2*n) /* n, most significant bit in hi */
+#define bm1 (pp + 3*n) /* n */
+#define v1 (scratch) /* 2n + 1 */
+#define vm1 (pp) /* 2n + 1 */
+#define scratch_out (scratch + 2*n + 1) /* Currently unused. */
+
+ /* Scratch need: 2*n + 1 + scratch for the recursive multiplications. */
+
+ /* FIXME: Keep v1[2*n] and vm1[2*n] in scalar variables? */
+
+ /* Compute ap1 = a0 + a1 + a3, am1 = a0 - a1 + a3 */
+ ap1_hi = mpn_add (ap1, a0, n, a2, s);
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (ap1_hi == 0 && mpn_cmp (ap1, a1, n) < 0)
+ {
+ ap1_hi = mpn_add_n_sub_n (ap1, am1, a1, ap1, n) >> 1;
+ hi = 0;
+ vm1_neg = 1;
+ }
+ else
+ {
+ cy = mpn_add_n_sub_n (ap1, am1, ap1, a1, n);
+ hi = ap1_hi - (cy & 1);
+ ap1_hi += (cy >> 1);
+ vm1_neg = 0;
+ }
+#else
+ if (ap1_hi == 0 && mpn_cmp (ap1, a1, n) < 0)
+ {
+ ASSERT_NOCARRY (mpn_sub_n (am1, a1, ap1, n));
+ hi = 0;
+ vm1_neg = 1;
+ }
+ else
+ {
+ hi = ap1_hi - mpn_sub_n (am1, ap1, a1, n);
+ vm1_neg = 0;
+ }
+ ap1_hi += mpn_add_n (ap1, ap1, a1, n);
+#endif
+
+ /* Compute bp1 = b0 + b1 and bm1 = b0 - b1. */
+ if (t == n)
+ {
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (mpn_cmp (b0, b1, n) < 0)
+ {
+ cy = mpn_add_n_sub_n (bp1, bm1, b1, b0, n);
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ cy = mpn_add_n_sub_n (bp1, bm1, b0, b1, n);
+ }
+ bp1_hi = cy >> 1;
+#else
+ bp1_hi = mpn_add_n (bp1, b0, b1, n);
+
+ if (mpn_cmp (b0, b1, n) < 0)
+ {
+ ASSERT_NOCARRY (mpn_sub_n (bm1, b1, b0, n));
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_sub_n (bm1, b0, b1, n));
+ }
+#endif
+ }
+ else
+ {
+ /* FIXME: Should still use mpn_add_n_sub_n for the main part. */
+ bp1_hi = mpn_add (bp1, b0, n, b1, t);
+
+ if (mpn_zero_p (b0 + t, n - t) && mpn_cmp (b0, b1, t) < 0)
+ {
+ ASSERT_NOCARRY (mpn_sub_n (bm1, b1, b0, t));
+ MPN_ZERO (bm1 + t, n - t);
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_sub (bm1, b0, n, b1, t));
+ }
+ }
+
+ TOOM32_MUL_N_REC (v1, ap1, bp1, n, scratch_out);
+ if (ap1_hi == 1)
+ {
+ cy = bp1_hi + mpn_add_n (v1 + n, v1 + n, bp1, n);
+ }
+ else if (ap1_hi == 2)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = 2 * bp1_hi + mpn_addlsh1_n (v1 + n, v1 + n, bp1, n);
+#else
+ cy = 2 * bp1_hi + mpn_addmul_1 (v1 + n, bp1, n, CNST_LIMB(2));
+#endif
+ }
+ else
+ cy = 0;
+ if (bp1_hi != 0)
+ cy += mpn_add_n (v1 + n, v1 + n, ap1, n);
+ v1[2 * n] = cy;
+
+ TOOM32_MUL_N_REC (vm1, am1, bm1, n, scratch_out);
+ if (hi)
+ hi = mpn_add_n (vm1+n, vm1+n, bm1, n);
+
+ vm1[2*n] = hi;
+
+ /* v1 <-- (v1 + vm1) / 2 = x0 + x2 */
+ if (vm1_neg)
+ {
+#if HAVE_NATIVE_mpn_rsh1sub_n
+ mpn_rsh1sub_n (v1, v1, vm1, 2*n+1);
+#else
+ mpn_sub_n (v1, v1, vm1, 2*n+1);
+ ASSERT_NOCARRY (mpn_rshift (v1, v1, 2*n+1, 1));
+#endif
+ }
+ else
+ {
+#if HAVE_NATIVE_mpn_rsh1add_n
+ mpn_rsh1add_n (v1, v1, vm1, 2*n+1);
+#else
+ mpn_add_n (v1, v1, vm1, 2*n+1);
+ ASSERT_NOCARRY (mpn_rshift (v1, v1, 2*n+1, 1));
+#endif
+ }
+
+ /* We get x1 + x3 = (x0 + x2) - (x0 - x1 + x2 - x3), and hence
+
+ y = x1 + x3 + (x0 + x2) * B
+ = (x0 + x2) * B + (x0 + x2) - vm1.
+
+ y is 3*n + 1 limbs, y = y0 + y1 B + y2 B^2. We store them as
+ follows: y0 at scratch, y1 at pp + 2*n, and y2 at scratch + n
+ (already in place, except for carry propagation).
+
+ We thus add
+
+ B^3 B^2 B 1
+ | | | |
+ +-----+----+
+ + | x0 + x2 |
+ +----+-----+----+
+ + | x0 + x2 |
+ +----------+
+ - | vm1 |
+ --+----++----+----+-
+ | y2 | y1 | y0 |
+ +-----+----+----+
+
+ Since we store y0 at the same location as the low half of x0 + x2, we
+ need to do the middle sum first. */
+
+ hi = vm1[2*n];
+ cy = mpn_add_n (pp + 2*n, v1, v1 + n, n);
+ MPN_INCR_U (v1 + n, n + 1, cy + v1[2*n]);
+
+ /* FIXME: Can we get rid of this second vm1_neg conditional by
+ swapping the location of +1 and -1 values? */
+ if (vm1_neg)
+ {
+ cy = mpn_add_n (v1, v1, vm1, n);
+ hi += mpn_add_nc (pp + 2*n, pp + 2*n, vm1 + n, n, cy);
+ MPN_INCR_U (v1 + n, n+1, hi);
+ }
+ else
+ {
+ cy = mpn_sub_n (v1, v1, vm1, n);
+ hi += mpn_sub_nc (pp + 2*n, pp + 2*n, vm1 + n, n, cy);
+ MPN_DECR_U (v1 + n, n+1, hi);
+ }
+
+ TOOM32_MUL_N_REC (pp, a0, b0, n, scratch_out);
+ /* vinf, s+t limbs. Use mpn_mul for now, to handle unbalanced operands */
+ if (s > t) mpn_mul (pp+3*n, a2, s, b1, t);
+ else mpn_mul (pp+3*n, b1, t, a2, s);
+
+ /* Remaining interpolation.
+
+ y * B + x0 + x3 B^3 - x0 B^2 - x3 B
+ = (x1 + x3) B + (x0 + x2) B^2 + x0 + x3 B^3 - x0 B^2 - x3 B
+ = y0 B + y1 B^2 + y3 B^3 + Lx0 + H x0 B
+ + L x3 B^3 + H x3 B^4 - Lx0 B^2 - H x0 B^3 - L x3 B - H x3 B^2
+ = L x0 + (y0 + H x0 - L x3) B + (y1 - L x0 - H x3) B^2
+ + (y2 - (H x0 - L x3)) B^3 + H x3 B^4
+
+ B^4 B^3 B^2 B 1
+ | | | | | |
+ +-------+ +---------+---------+
+ | Hx3 | | Hx0-Lx3 | Lx0 |
+ +------+----------+---------+---------+---------+
+ | y2 | y1 | y0 |
+ ++---------+---------+---------+
+ -| Hx0-Lx3 | - Lx0 |
+ +---------+---------+
+ | - Hx3 |
+ +--------+
+
+ We must take into account the carry from Hx0 - Lx3.
+ */
+
+ cy = mpn_sub_n (pp + n, pp + n, pp+3*n, n);
+ hi = scratch[2*n] + cy;
+
+ cy = mpn_sub_nc (pp + 2*n, pp + 2*n, pp, n, cy);
+ hi -= mpn_sub_nc (pp + 3*n, scratch + n, pp + n, n, cy);
+
+ hi += mpn_add (pp + n, pp + n, 3*n, scratch, n);
+
+ /* FIXME: Is support for s + t == n needed? */
+ if (LIKELY (s + t > n))
+ {
+ hi -= mpn_sub (pp + 2*n, pp + 2*n, 2*n, pp + 4*n, s+t-n);
+
+ if (hi < 0)
+ MPN_DECR_U (pp + 4*n, s+t-n, -hi);
+ else
+ MPN_INCR_U (pp + 4*n, s+t-n, hi);
+ }
+ else
+ ASSERT (hi == 0);
+}
diff --git a/gmp/mpn/generic/toom33_mul.c b/gmp/mpn/generic/toom33_mul.c
new file mode 100644
index 0000000000..655355c39a
--- /dev/null
+++ b/gmp/mpn/generic/toom33_mul.c
@@ -0,0 +1,316 @@
+/* mpn_toom33_mul -- Multiply {ap,an} and {p,bn} where an and bn are close in
+ size. Or more accurately, bn <= an < (3/2)bn.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+ Additional improvements by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2008, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: -1, 0, +1, +2, +inf
+
+ <-s--><--n--><--n-->
+ ____ ______ ______
+ |_a2_|___a1_|___a0_|
+ |b2_|___b1_|___b0_|
+ <-t-><--n--><--n-->
+
+ v0 = a0 * b0 # A(0)*B(0)
+ v1 = (a0+ a1+ a2)*(b0+ b1+ b2) # A(1)*B(1) ah <= 2 bh <= 2
+ vm1 = (a0- a1+ a2)*(b0- b1+ b2) # A(-1)*B(-1) |ah| <= 1 bh <= 1
+ v2 = (a0+2a1+4a2)*(b0+2b1+4b2) # A(2)*B(2) ah <= 6 bh <= 6
+ vinf= a2 * b2 # A(inf)*B(inf)
+*/
+
+#if TUNE_PROGRAM_BUILD || WANT_FAT_BINARY
+#define MAYBE_mul_basecase 1
+#define MAYBE_mul_toom33 1
+#else
+#define MAYBE_mul_basecase \
+ (MUL_TOOM33_THRESHOLD < 3 * MUL_TOOM22_THRESHOLD)
+#define MAYBE_mul_toom33 \
+ (MUL_TOOM44_THRESHOLD >= 3 * MUL_TOOM33_THRESHOLD)
+#endif
+
+/* FIXME: TOOM33_MUL_N_REC is not quite right for a balanced
+ multiplication at the infinity point. We may have
+ MAYBE_mul_basecase == 0, and still get s just below
+ MUL_TOOM22_THRESHOLD. If MUL_TOOM33_THRESHOLD == 7, we can even get
+ s == 1 and mpn_toom22_mul will crash.
+*/
+
+#define TOOM33_MUL_N_REC(p, a, b, n, ws) \
+ do { \
+ if (MAYBE_mul_basecase \
+ && BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD)) \
+ mpn_mul_basecase (p, a, n, b, n); \
+ else if (! MAYBE_mul_toom33 \
+ || BELOW_THRESHOLD (n, MUL_TOOM33_THRESHOLD)) \
+ mpn_toom22_mul (p, a, n, b, n, ws); \
+ else \
+ mpn_toom33_mul (p, a, n, b, n, ws); \
+ } while (0)
+
+void
+mpn_toom33_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn,
+ mp_ptr scratch)
+{
+ const int __gmpn_cpuvec_initialized = 1;
+ mp_size_t n, s, t;
+ int vm1_neg;
+ mp_limb_t cy, vinf0;
+ mp_ptr gp;
+ mp_ptr as1, asm1, as2;
+ mp_ptr bs1, bsm1, bs2;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2*n)
+#define b0 bp
+#define b1 (bp + n)
+#define b2 (bp + 2*n)
+
+ n = (an + 2) / (size_t) 3;
+
+ s = an - 2 * n;
+ t = bn - 2 * n;
+
+ ASSERT (an >= bn);
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+
+ as1 = scratch + 4 * n + 4;
+ asm1 = scratch + 2 * n + 2;
+ as2 = pp + n + 1;
+
+ bs1 = pp;
+ bsm1 = scratch + 3 * n + 3; /* we need 4n+4 <= 4n+s+t */
+ bs2 = pp + 2 * n + 2;
+
+ gp = scratch;
+
+ vm1_neg = 0;
+
+ /* Compute as1 and asm1. */
+ cy = mpn_add (gp, a0, n, a2, s);
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (cy == 0 && mpn_cmp (gp, a1, n) < 0)
+ {
+ cy = mpn_add_n_sub_n (as1, asm1, a1, gp, n);
+ as1[n] = cy >> 1;
+ asm1[n] = 0;
+ vm1_neg = 1;
+ }
+ else
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_add_n_sub_n (as1, asm1, gp, a1, n);
+ as1[n] = cy + (cy2 >> 1);
+ asm1[n] = cy - (cy2 & 1);
+ }
+#else
+ as1[n] = cy + mpn_add_n (as1, gp, a1, n);
+ if (cy == 0 && mpn_cmp (gp, a1, n) < 0)
+ {
+ mpn_sub_n (asm1, a1, gp, n);
+ asm1[n] = 0;
+ vm1_neg = 1;
+ }
+ else
+ {
+ cy -= mpn_sub_n (asm1, gp, a1, n);
+ asm1[n] = cy;
+ }
+#endif
+
+ /* Compute as2. */
+#if HAVE_NATIVE_mpn_rsblsh1_n
+ cy = mpn_add_n (as2, a2, as1, s);
+ if (s != n)
+ cy = mpn_add_1 (as2 + s, as1 + s, n - s, cy);
+ cy += as1[n];
+ cy = 2 * cy + mpn_rsblsh1_n (as2, a0, as2, n);
+#else
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (as2, a1, a2, s);
+ if (s != n)
+ cy = mpn_add_1 (as2 + s, a1 + s, n - s, cy);
+ cy = 2 * cy + mpn_addlsh1_n (as2, a0, as2, n);
+#else
+ cy = mpn_add_n (as2, a2, as1, s);
+ if (s != n)
+ cy = mpn_add_1 (as2 + s, as1 + s, n - s, cy);
+ cy += as1[n];
+ cy = 2 * cy + mpn_lshift (as2, as2, n, 1);
+ cy -= mpn_sub_n (as2, as2, a0, n);
+#endif
+#endif
+ as2[n] = cy;
+
+ /* Compute bs1 and bsm1. */
+ cy = mpn_add (gp, b0, n, b2, t);
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (cy == 0 && mpn_cmp (gp, b1, n) < 0)
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, b1, gp, n);
+ bs1[n] = cy >> 1;
+ bsm1[n] = 0;
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_add_n_sub_n (bs1, bsm1, gp, b1, n);
+ bs1[n] = cy + (cy2 >> 1);
+ bsm1[n] = cy - (cy2 & 1);
+ }
+#else
+ bs1[n] = cy + mpn_add_n (bs1, gp, b1, n);
+ if (cy == 0 && mpn_cmp (gp, b1, n) < 0)
+ {
+ mpn_sub_n (bsm1, b1, gp, n);
+ bsm1[n] = 0;
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ cy -= mpn_sub_n (bsm1, gp, b1, n);
+ bsm1[n] = cy;
+ }
+#endif
+
+ /* Compute bs2. */
+#if HAVE_NATIVE_mpn_rsblsh1_n
+ cy = mpn_add_n (bs2, b2, bs1, t);
+ if (t != n)
+ cy = mpn_add_1 (bs2 + t, bs1 + t, n - t, cy);
+ cy += bs1[n];
+ cy = 2 * cy + mpn_rsblsh1_n (bs2, b0, bs2, n);
+#else
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (bs2, b1, b2, t);
+ if (t != n)
+ cy = mpn_add_1 (bs2 + t, b1 + t, n - t, cy);
+ cy = 2 * cy + mpn_addlsh1_n (bs2, b0, bs2, n);
+#else
+ cy = mpn_add_n (bs2, bs1, b2, t);
+ if (t != n)
+ cy = mpn_add_1 (bs2 + t, bs1 + t, n - t, cy);
+ cy += bs1[n];
+ cy = 2 * cy + mpn_lshift (bs2, bs2, n, 1);
+ cy -= mpn_sub_n (bs2, bs2, b0, n);
+#endif
+#endif
+ bs2[n] = cy;
+
+ ASSERT (as1[n] <= 2);
+ ASSERT (bs1[n] <= 2);
+ ASSERT (asm1[n] <= 1);
+ ASSERT (bsm1[n] <= 1);
+ ASSERT (as2[n] <= 6);
+ ASSERT (bs2[n] <= 6);
+
+#define v0 pp /* 2n */
+#define v1 (pp + 2 * n) /* 2n+1 */
+#define vinf (pp + 4 * n) /* s+t */
+#define vm1 scratch /* 2n+1 */
+#define v2 (scratch + 2 * n + 1) /* 2n+2 */
+#define scratch_out (scratch + 5 * n + 5)
+
+ /* vm1, 2n+1 limbs */
+#ifdef SMALLER_RECURSION
+ TOOM33_MUL_N_REC (vm1, asm1, bsm1, n, scratch_out);
+ cy = 0;
+ if (asm1[n] != 0)
+ cy = bsm1[n] + mpn_add_n (vm1 + n, vm1 + n, bsm1, n);
+ if (bsm1[n] != 0)
+ cy += mpn_add_n (vm1 + n, vm1 + n, asm1, n);
+ vm1[2 * n] = cy;
+#else
+ TOOM33_MUL_N_REC (vm1, asm1, bsm1, n + 1, scratch_out);
+#endif
+
+ TOOM33_MUL_N_REC (v2, as2, bs2, n + 1, scratch_out); /* v2, 2n+1 limbs */
+
+ /* vinf, s+t limbs */
+ if (s > t) mpn_mul (vinf, a2, s, b2, t);
+ else TOOM33_MUL_N_REC (vinf, a2, b2, s, scratch_out);
+
+ vinf0 = vinf[0]; /* v1 overlaps with this */
+
+#ifdef SMALLER_RECURSION
+ /* v1, 2n+1 limbs */
+ TOOM33_MUL_N_REC (v1, as1, bs1, n, scratch_out);
+ if (as1[n] == 1)
+ {
+ cy = bs1[n] + mpn_add_n (v1 + n, v1 + n, bs1, n);
+ }
+ else if (as1[n] != 0)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = 2 * bs1[n] + mpn_addlsh1_n (v1 + n, v1 + n, bs1, n);
+#else
+ cy = 2 * bs1[n] + mpn_addmul_1 (v1 + n, bs1, n, CNST_LIMB(2));
+#endif
+ }
+ else
+ cy = 0;
+ if (bs1[n] == 1)
+ {
+ cy += mpn_add_n (v1 + n, v1 + n, as1, n);
+ }
+ else if (bs1[n] != 0)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy += mpn_addlsh1_n (v1 + n, v1 + n, as1, n);
+#else
+ cy += mpn_addmul_1 (v1 + n, as1, n, CNST_LIMB(2));
+#endif
+ }
+ v1[2 * n] = cy;
+#else
+ cy = vinf[1];
+ TOOM33_MUL_N_REC (v1, as1, bs1, n + 1, scratch_out);
+ vinf[1] = cy;
+#endif
+
+ TOOM33_MUL_N_REC (v0, ap, bp, n, scratch_out); /* v0, 2n limbs */
+
+ mpn_toom_interpolate_5pts (pp, v2, vm1, n, s + t, vm1_neg, vinf0);
+}
diff --git a/gmp/mpn/generic/toom3_sqr.c b/gmp/mpn/generic/toom3_sqr.c
new file mode 100644
index 0000000000..6117c67ca6
--- /dev/null
+++ b/gmp/mpn/generic/toom3_sqr.c
@@ -0,0 +1,226 @@
+/* mpn_toom3_sqr -- Square {ap,an}.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+ Additional improvements by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: -1, 0, +1, +2, +inf
+
+ <-s--><--n--><--n-->
+ ____ ______ ______
+ |_a2_|___a1_|___a0_|
+
+ v0 = a0 ^2 # A(0)^2
+ v1 = (a0+ a1+ a2)^2 # A(1)^2 ah <= 2
+ vm1 = (a0- a1+ a2)^2 # A(-1)^2 |ah| <= 1
+ v2 = (a0+2a1+4a2)^2 # A(2)^2 ah <= 6
+ vinf= a2 ^2 # A(inf)^2
+*/
+
+#if TUNE_PROGRAM_BUILD || WANT_FAT_BINARY
+#define MAYBE_sqr_basecase 1
+#define MAYBE_sqr_toom3 1
+#else
+#define MAYBE_sqr_basecase \
+ (SQR_TOOM3_THRESHOLD < 3 * SQR_TOOM2_THRESHOLD)
+#define MAYBE_sqr_toom3 \
+ (SQR_TOOM4_THRESHOLD >= 3 * SQR_TOOM3_THRESHOLD)
+#endif
+
+#define TOOM3_SQR_REC(p, a, n, ws) \
+ do { \
+ if (MAYBE_sqr_basecase \
+ && BELOW_THRESHOLD (n, SQR_TOOM2_THRESHOLD)) \
+ mpn_sqr_basecase (p, a, n); \
+ else if (! MAYBE_sqr_toom3 \
+ || BELOW_THRESHOLD (n, SQR_TOOM3_THRESHOLD)) \
+ mpn_toom2_sqr (p, a, n, ws); \
+ else \
+ mpn_toom3_sqr (p, a, n, ws); \
+ } while (0)
+
+void
+mpn_toom3_sqr (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_ptr scratch)
+{
+ const int __gmpn_cpuvec_initialized = 1;
+ mp_size_t n, s;
+ mp_limb_t cy, vinf0;
+ mp_ptr gp;
+ mp_ptr as1, asm1, as2;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2*n)
+
+ n = (an + 2) / (size_t) 3;
+
+ s = an - 2 * n;
+
+ ASSERT (0 < s && s <= n);
+
+ as1 = scratch + 4 * n + 4;
+ asm1 = scratch + 2 * n + 2;
+ as2 = pp + n + 1;
+
+ gp = scratch;
+
+ /* Compute as1 and asm1. */
+ cy = mpn_add (gp, a0, n, a2, s);
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (cy == 0 && mpn_cmp (gp, a1, n) < 0)
+ {
+ cy = mpn_add_n_sub_n (as1, asm1, a1, gp, n);
+ as1[n] = cy >> 1;
+ asm1[n] = 0;
+ }
+ else
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_add_n_sub_n (as1, asm1, gp, a1, n);
+ as1[n] = cy + (cy2 >> 1);
+ asm1[n] = cy - (cy2 & 1);
+ }
+#else
+ as1[n] = cy + mpn_add_n (as1, gp, a1, n);
+ if (cy == 0 && mpn_cmp (gp, a1, n) < 0)
+ {
+ mpn_sub_n (asm1, a1, gp, n);
+ asm1[n] = 0;
+ }
+ else
+ {
+ cy -= mpn_sub_n (asm1, gp, a1, n);
+ asm1[n] = cy;
+ }
+#endif
+
+ /* Compute as2. */
+#if HAVE_NATIVE_mpn_rsblsh1_n
+ cy = mpn_add_n (as2, a2, as1, s);
+ if (s != n)
+ cy = mpn_add_1 (as2 + s, as1 + s, n - s, cy);
+ cy += as1[n];
+ cy = 2 * cy + mpn_rsblsh1_n (as2, a0, as2, n);
+#else
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (as2, a1, a2, s);
+ if (s != n)
+ cy = mpn_add_1 (as2 + s, a1 + s, n - s, cy);
+ cy = 2 * cy + mpn_addlsh1_n (as2, a0, as2, n);
+#else
+ cy = mpn_add_n (as2, a2, as1, s);
+ if (s != n)
+ cy = mpn_add_1 (as2 + s, as1 + s, n - s, cy);
+ cy += as1[n];
+ cy = 2 * cy + mpn_lshift (as2, as2, n, 1);
+ cy -= mpn_sub_n (as2, as2, a0, n);
+#endif
+#endif
+ as2[n] = cy;
+
+ ASSERT (as1[n] <= 2);
+ ASSERT (asm1[n] <= 1);
+
+#define v0 pp /* 2n */
+#define v1 (pp + 2 * n) /* 2n+1 */
+#define vinf (pp + 4 * n) /* s+s */
+#define vm1 scratch /* 2n+1 */
+#define v2 (scratch + 2 * n + 1) /* 2n+2 */
+#define scratch_out (scratch + 5 * n + 5)
+
+ /* vm1, 2n+1 limbs */
+#ifdef SMALLER_RECURSION
+ TOOM3_SQR_REC (vm1, asm1, n, scratch_out);
+ cy = 0;
+ if (asm1[n] != 0)
+ cy = asm1[n] + mpn_add_n (vm1 + n, vm1 + n, asm1, n);
+ if (asm1[n] != 0)
+ cy += mpn_add_n (vm1 + n, vm1 + n, asm1, n);
+ vm1[2 * n] = cy;
+#else
+ TOOM3_SQR_REC (vm1, asm1, n + 1, scratch_out);
+#endif
+
+ TOOM3_SQR_REC (v2, as2, n + 1, scratch_out); /* v2, 2n+1 limbs */
+
+ TOOM3_SQR_REC (vinf, a2, s, scratch_out); /* vinf, s+s limbs */
+
+ vinf0 = vinf[0]; /* v1 overlaps with this */
+
+#ifdef SMALLER_RECURSION
+ /* v1, 2n+1 limbs */
+ TOOM3_SQR_REC (v1, as1, n, scratch_out);
+ if (as1[n] == 1)
+ {
+ cy = as1[n] + mpn_add_n (v1 + n, v1 + n, as1, n);
+ }
+ else if (as1[n] != 0)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = 2 * as1[n] + mpn_addlsh1_n (v1 + n, v1 + n, as1, n);
+#else
+ cy = 2 * as1[n] + mpn_addmul_1 (v1 + n, as1, n, CNST_LIMB(2));
+#endif
+ }
+ else
+ cy = 0;
+ if (as1[n] == 1)
+ {
+ cy += mpn_add_n (v1 + n, v1 + n, as1, n);
+ }
+ else if (as1[n] != 0)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy += mpn_addlsh1_n (v1 + n, v1 + n, as1, n);
+#else
+ cy += mpn_addmul_1 (v1 + n, as1, n, CNST_LIMB(2));
+#endif
+ }
+ v1[2 * n] = cy;
+#else
+ cy = vinf[1];
+ TOOM3_SQR_REC (v1, as1, n + 1, scratch_out);
+ vinf[1] = cy;
+#endif
+
+ TOOM3_SQR_REC (v0, ap, n, scratch_out); /* v0, 2n limbs */
+
+ mpn_toom_interpolate_5pts (pp, v2, vm1, n, s + s, 0, vinf0);
+}
diff --git a/gmp/mpn/generic/toom42_mul.c b/gmp/mpn/generic/toom42_mul.c
new file mode 100644
index 0000000000..9b1e7d491b
--- /dev/null
+++ b/gmp/mpn/generic/toom42_mul.c
@@ -0,0 +1,234 @@
+/* mpn_toom42_mul -- Multiply {ap,an} and {bp,bn} where an is nominally twice
+ as large as bn. Or more accurately, (3/2)bn < an < 4bn.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+ Additional improvements by Marco Bodrato.
+
+ The idea of applying toom to unbalanced multiplication is due to Marco
+ Bodrato and Alberto Zanoni.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2008, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: -1, 0, +1, +2, +inf
+
+ <-s-><--n--><--n--><--n-->
+ ___ ______ ______ ______
+ |a3_|___a2_|___a1_|___a0_|
+ |_b1_|___b0_|
+ <-t--><--n-->
+
+ v0 = a0 * b0 # A(0)*B(0)
+ v1 = (a0+ a1+ a2+ a3)*(b0+ b1) # A(1)*B(1) ah <= 3 bh <= 1
+ vm1 = (a0- a1+ a2- a3)*(b0- b1) # A(-1)*B(-1) |ah| <= 1 bh = 0
+ v2 = (a0+2a1+4a2+8a3)*(b0+2b1) # A(2)*B(2) ah <= 14 bh <= 2
+ vinf= a3 * b1 # A(inf)*B(inf)
+*/
+
+#define TOOM42_MUL_N_REC(p, a, b, n, ws) \
+ do { \
+ mpn_mul_n (p, a, b, n); \
+ } while (0)
+
+void
+mpn_toom42_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn,
+ mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ int vm1_neg;
+ mp_limb_t cy, vinf0;
+ mp_ptr a0_a2;
+ mp_ptr as1, asm1, as2;
+ mp_ptr bs1, bsm1, bs2;
+ TMP_DECL;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2*n)
+#define a3 (ap + 3*n)
+#define b0 bp
+#define b1 (bp + n)
+
+ n = an >= 2 * bn ? (an + 3) >> 2 : (bn + 1) >> 1;
+
+ s = an - 3 * n;
+ t = bn - n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+
+ TMP_MARK;
+
+ as1 = TMP_SALLOC_LIMBS (n + 1);
+ asm1 = TMP_SALLOC_LIMBS (n + 1);
+ as2 = TMP_SALLOC_LIMBS (n + 1);
+
+ bs1 = TMP_SALLOC_LIMBS (n + 1);
+ bsm1 = TMP_SALLOC_LIMBS (n);
+ bs2 = TMP_SALLOC_LIMBS (n + 1);
+
+ a0_a2 = pp;
+
+ /* Compute as1 and asm1. */
+ vm1_neg = mpn_toom_eval_dgr3_pm1 (as1, asm1, ap, n, s, a0_a2) & 1;
+
+ /* Compute as2. */
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (as2, a2, a3, s);
+ if (s != n)
+ cy = mpn_add_1 (as2 + s, a2 + s, n - s, cy);
+ cy = 2 * cy + mpn_addlsh1_n (as2, a1, as2, n);
+ cy = 2 * cy + mpn_addlsh1_n (as2, a0, as2, n);
+#else
+ cy = mpn_lshift (as2, a3, s, 1);
+ cy += mpn_add_n (as2, a2, as2, s);
+ if (s != n)
+ cy = mpn_add_1 (as2 + s, a2 + s, n - s, cy);
+ cy = 2 * cy + mpn_lshift (as2, as2, n, 1);
+ cy += mpn_add_n (as2, a1, as2, n);
+ cy = 2 * cy + mpn_lshift (as2, as2, n, 1);
+ cy += mpn_add_n (as2, a0, as2, n);
+#endif
+ as2[n] = cy;
+
+ /* Compute bs1 and bsm1. */
+ if (t == n)
+ {
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (mpn_cmp (b0, b1, n) < 0)
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, b1, b0, n);
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, b0, b1, n);
+ }
+ bs1[n] = cy >> 1;
+#else
+ bs1[n] = mpn_add_n (bs1, b0, b1, n);
+
+ if (mpn_cmp (b0, b1, n) < 0)
+ {
+ mpn_sub_n (bsm1, b1, b0, n);
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ mpn_sub_n (bsm1, b0, b1, n);
+ }
+#endif
+ }
+ else
+ {
+ bs1[n] = mpn_add (bs1, b0, n, b1, t);
+
+ if (mpn_zero_p (b0 + t, n - t) && mpn_cmp (b0, b1, t) < 0)
+ {
+ mpn_sub_n (bsm1, b1, b0, t);
+ MPN_ZERO (bsm1 + t, n - t);
+ vm1_neg ^= 1;
+ }
+ else
+ {
+ mpn_sub (bsm1, b0, n, b1, t);
+ }
+ }
+
+ /* Compute bs2, recycling bs1. bs2=bs1+b1 */
+ mpn_add (bs2, bs1, n + 1, b1, t);
+
+ ASSERT (as1[n] <= 3);
+ ASSERT (bs1[n] <= 1);
+ ASSERT (asm1[n] <= 1);
+/*ASSERT (bsm1[n] == 0);*/
+ ASSERT (as2[n] <= 14);
+ ASSERT (bs2[n] <= 2);
+
+#define v0 pp /* 2n */
+#define v1 (pp + 2 * n) /* 2n+1 */
+#define vinf (pp + 4 * n) /* s+t */
+#define vm1 scratch /* 2n+1 */
+#define v2 (scratch + 2 * n + 1) /* 2n+2 */
+#define scratch_out scratch + 4 * n + 4 /* Currently unused. */
+
+ /* vm1, 2n+1 limbs */
+ TOOM42_MUL_N_REC (vm1, asm1, bsm1, n, scratch_out);
+ cy = 0;
+ if (asm1[n] != 0)
+ cy = mpn_add_n (vm1 + n, vm1 + n, bsm1, n);
+ vm1[2 * n] = cy;
+
+ TOOM42_MUL_N_REC (v2, as2, bs2, n + 1, scratch_out); /* v2, 2n+1 limbs */
+
+ /* vinf, s+t limbs */
+ if (s > t) mpn_mul (vinf, a3, s, b1, t);
+ else mpn_mul (vinf, b1, t, a3, s);
+
+ vinf0 = vinf[0]; /* v1 overlaps with this */
+
+ /* v1, 2n+1 limbs */
+ TOOM42_MUL_N_REC (v1, as1, bs1, n, scratch_out);
+ if (as1[n] == 1)
+ {
+ cy = bs1[n] + mpn_add_n (v1 + n, v1 + n, bs1, n);
+ }
+ else if (as1[n] == 2)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = 2 * bs1[n] + mpn_addlsh1_n (v1 + n, v1 + n, bs1, n);
+#else
+ cy = 2 * bs1[n] + mpn_addmul_1 (v1 + n, bs1, n, CNST_LIMB(2));
+#endif
+ }
+ else if (as1[n] == 3)
+ {
+ cy = 3 * bs1[n] + mpn_addmul_1 (v1 + n, bs1, n, CNST_LIMB(3));
+ }
+ else
+ cy = 0;
+ if (bs1[n] != 0)
+ cy += mpn_add_n (v1 + n, v1 + n, as1, n);
+ v1[2 * n] = cy;
+
+ TOOM42_MUL_N_REC (v0, ap, bp, n, scratch_out); /* v0, 2n limbs */
+
+ mpn_toom_interpolate_5pts (pp, v2, vm1, n, s + t, vm1_neg, vinf0);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/toom42_mulmid.c b/gmp/mpn/generic/toom42_mulmid.c
new file mode 100644
index 0000000000..0251a6d7ed
--- /dev/null
+++ b/gmp/mpn/generic/toom42_mulmid.c
@@ -0,0 +1,238 @@
+/* mpn_toom42_mulmid -- toom42 middle product
+
+ Contributed by David Harvey.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+
+/*
+ Middle product of {ap,2n-1} and {bp,n}, output written to {rp,n+2}.
+
+ Neither ap nor bp may overlap rp.
+
+ Must have n >= 4.
+
+ Amount of scratch space required is given by mpn_toom42_mulmid_itch().
+
+ FIXME: this code assumes that n is small compared to GMP_NUMB_MAX. The exact
+ requirements should be clarified.
+*/
+void
+mpn_toom42_mulmid (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n,
+ mp_ptr scratch)
+{
+ mp_limb_t cy, e[12], zh, zl;
+ mp_size_t m;
+ int neg;
+
+ ASSERT (n >= 4);
+ ASSERT (! MPN_OVERLAP_P (rp, n + 2, ap, 2*n - 1));
+ ASSERT (! MPN_OVERLAP_P (rp, n + 2, bp, n));
+
+ ap += n & 1; /* handle odd row and diagonal later */
+ m = n / 2;
+
+ /* (e0h:e0l) etc are correction terms, in 2's complement */
+#define e0l (e[0])
+#define e0h (e[1])
+#define e1l (e[2])
+#define e1h (e[3])
+#define e2l (e[4])
+#define e2h (e[5])
+#define e3l (e[6])
+#define e3h (e[7])
+#define e4l (e[8])
+#define e4h (e[9])
+#define e5l (e[10])
+#define e5h (e[11])
+
+#define s (scratch + 2)
+#define t (rp + m + 2)
+#define p0 rp
+#define p1 scratch
+#define p2 (rp + m)
+#define next_scratch (scratch + 3*m + 1)
+
+ /*
+ rp scratch
+ |---------|-----------| |---------|---------|----------|
+ 0 m 2m+2 0 m 2m 3m+1
+ <----p2----> <-------------s------------->
+ <----p0----><---t----> <----p1---->
+ */
+
+ /* compute {s,3m-1} = {a,3m-1} + {a+m,3m-1} and error terms e0, e1, e2, e3 */
+ cy = mpn_add_err1_n (s, ap, ap + m, &e0l, bp + m, m - 1, 0);
+ cy = mpn_add_err2_n (s + m - 1, ap + m - 1, ap + 2*m - 1, &e1l,
+ bp + m, bp, m, cy);
+ mpn_add_err1_n (s + 2*m - 1, ap + 2*m - 1, ap + 3*m - 1, &e3l, bp, m, cy);
+
+ /* compute t = (-1)^neg * ({b,m} - {b+m,m}) and error terms e4, e5 */
+ if (mpn_cmp (bp + m, bp, m) < 0)
+ {
+ ASSERT_NOCARRY (mpn_sub_err2_n (t, bp, bp + m, &e4l,
+ ap + m - 1, ap + 2*m - 1, m, 0));
+ neg = 1;
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_sub_err2_n (t, bp + m, bp, &e4l,
+ ap + m - 1, ap + 2*m - 1, m, 0));
+ neg = 0;
+ }
+
+ /* recursive middle products. The picture is:
+
+ b[2m-1] A A A B B B - - - - -
+ ... - A A A B B B - - - -
+ b[m] - - A A A B B B - - -
+ b[m-1] - - - C C C D D D - -
+ ... - - - - C C C D D D -
+ b[0] - - - - - C C C D D D
+ a[0] ... a[m] ... a[2m] ... a[4m-2]
+ */
+
+ if (m < MULMID_TOOM42_THRESHOLD)
+ {
+ /* A + B */
+ mpn_mulmid_basecase (p0, s, 2*m - 1, bp + m, m);
+ /* accumulate high limbs of p0 into e1 */
+ ADDC_LIMB (cy, e1l, e1l, p0[m]);
+ e1h += p0[m + 1] + cy;
+ /* (-1)^neg * (B - C) (overwrites first m limbs of s) */
+ mpn_mulmid_basecase (p1, ap + m, 2*m - 1, t, m);
+ /* C + D (overwrites t) */
+ mpn_mulmid_basecase (p2, s + m, 2*m - 1, bp, m);
+ }
+ else
+ {
+ /* as above, but use toom42 instead */
+ mpn_toom42_mulmid (p0, s, bp + m, m, next_scratch);
+ ADDC_LIMB (cy, e1l, e1l, p0[m]);
+ e1h += p0[m + 1] + cy;
+ mpn_toom42_mulmid (p1, ap + m, t, m, next_scratch);
+ mpn_toom42_mulmid (p2, s + m, bp, m, next_scratch);
+ }
+
+ /* apply error terms */
+
+ /* -e0 at rp[0] */
+ SUBC_LIMB (cy, rp[0], rp[0], e0l);
+ SUBC_LIMB (cy, rp[1], rp[1], e0h + cy);
+ if (UNLIKELY (cy))
+ {
+ cy = (m > 2) ? mpn_sub_1 (rp + 2, rp + 2, m - 2, 1) : 1;
+ SUBC_LIMB (cy, e1l, e1l, cy);
+ e1h -= cy;
+ }
+
+ /* z = e1 - e2 + high(p0) */
+ SUBC_LIMB (cy, zl, e1l, e2l);
+ zh = e1h - e2h - cy;
+
+ /* z at rp[m] */
+ ADDC_LIMB (cy, rp[m], rp[m], zl);
+ zh = (zh + cy) & GMP_NUMB_MASK;
+ ADDC_LIMB (cy, rp[m + 1], rp[m + 1], zh);
+ cy -= (zh >> (GMP_NUMB_BITS - 1));
+ if (UNLIKELY (cy))
+ {
+ if (cy == 1)
+ mpn_add_1 (rp + m + 2, rp + m + 2, m, 1);
+ else /* cy == -1 */
+ mpn_sub_1 (rp + m + 2, rp + m + 2, m, 1);
+ }
+
+ /* e3 at rp[2*m] */
+ ADDC_LIMB (cy, rp[2*m], rp[2*m], e3l);
+ rp[2*m + 1] = (rp[2*m + 1] + e3h + cy) & GMP_NUMB_MASK;
+
+ /* e4 at p1[0] */
+ ADDC_LIMB (cy, p1[0], p1[0], e4l);
+ ADDC_LIMB (cy, p1[1], p1[1], e4h + cy);
+ if (UNLIKELY (cy))
+ mpn_add_1 (p1 + 2, p1 + 2, m, 1);
+
+ /* -e5 at p1[m] */
+ SUBC_LIMB (cy, p1[m], p1[m], e5l);
+ p1[m + 1] = (p1[m + 1] - e5h - cy) & GMP_NUMB_MASK;
+
+ /* adjustment if p1 ends up negative */
+ cy = (p1[m + 1] >> (GMP_NUMB_BITS - 1));
+
+ /* add (-1)^neg * (p1 - B^m * p1) to output */
+ if (neg)
+ {
+ mpn_sub_1 (rp + m + 2, rp + m + 2, m, cy);
+ mpn_add (rp, rp, 2*m + 2, p1, m + 2); /* A + C */
+ mpn_sub_n (rp + m, rp + m, p1, m + 2); /* B + D */
+ }
+ else
+ {
+ mpn_add_1 (rp + m + 2, rp + m + 2, m, cy);
+ mpn_sub (rp, rp, 2*m + 2, p1, m + 2); /* A + C */
+ mpn_add_n (rp + m, rp + m, p1, m + 2); /* B + D */
+ }
+
+ /* odd row and diagonal */
+ if (n & 1)
+ {
+ /*
+ Products marked E are already done. We need to do products marked O.
+
+ OOOOO----
+ -EEEEO---
+ --EEEEO--
+ ---EEEEO-
+ ----EEEEO
+ */
+
+ /* first row of O's */
+ cy = mpn_addmul_1 (rp, ap - 1, n, bp[n - 1]);
+ ADDC_LIMB (rp[n + 1], rp[n], rp[n], cy);
+
+ /* O's on diagonal */
+ /* FIXME: should probably define an interface "mpn_mulmid_diag_1"
+ that can handle the sum below. Currently we're relying on
+ mulmid_basecase being pretty fast for a diagonal sum like this,
+ which is true at least for the K8 asm version, but surely false
+ for the generic version. */
+ mpn_mulmid_basecase (e, ap + n - 1, n - 1, bp, n - 1);
+ mpn_add_n (rp + n - 1, rp + n - 1, e, 3);
+ }
+}
diff --git a/gmp/mpn/generic/toom43_mul.c b/gmp/mpn/generic/toom43_mul.c
new file mode 100644
index 0000000000..59d45576b8
--- /dev/null
+++ b/gmp/mpn/generic/toom43_mul.c
@@ -0,0 +1,234 @@
+/* mpn_toom43_mul -- Multiply {ap,an} and {bp,bn} where an is nominally 4/3
+ times as large as bn. Or more accurately, bn < an < 2 bn.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ The idea of applying toom to unbalanced multiplication is due to Marco
+ Bodrato and Alberto Zanoni.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: -2, -1, 0, +1, +2, +inf
+
+ <-s-><--n--><--n--><--n-->
+ ___ ______ ______ ______
+ |a3_|___a2_|___a1_|___a0_|
+ |_b2_|___b1_|___b0_|
+ <-t--><--n--><--n-->
+
+ v0 = a0 * b0 # A(0)*B(0)
+ v1 = (a0+ a1+ a2+ a3)*(b0+ b1+ b2) # A(1)*B(1) ah <= 3 bh <= 2
+ vm1 = (a0- a1+ a2- a3)*(b0- b1+ b2) # A(-1)*B(-1) |ah| <= 1 |bh|<= 1
+ v2 = (a0+2a1+4a2+8a3)*(b0+2b1+4b2) # A(2)*B(2) ah <= 14 bh <= 6
+ vm2 = (a0-2a1+4a2-8a3)*(b0-2b1+4b2) # A(-2)*B(-2) |ah| <= 9 |bh|<= 4
+ vinf= a3 * b2 # A(inf)*B(inf)
+*/
+
+void
+mpn_toom43_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn, mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ enum toom6_flags flags;
+ mp_limb_t cy;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2 * n)
+#define a3 (ap + 3 * n)
+#define b0 bp
+#define b1 (bp + n)
+#define b2 (bp + 2 * n)
+
+ n = 1 + (3 * an >= 4 * bn ? (an - 1) >> 2 : (bn - 1) / (size_t) 3);
+
+ s = an - 3 * n;
+ t = bn - 2 * n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+
+ /* This is true whenever an >= 25 or bn >= 19, I think. It
+ guarantees that we can fit 5 values of size n+1 in the product
+ area. */
+ ASSERT (s+t >= 5);
+
+#define v0 pp /* 2n */
+#define vm1 (scratch) /* 2n+1 */
+#define v1 (pp + 2*n) /* 2n+1 */
+#define vm2 (scratch + 2 * n + 1) /* 2n+1 */
+#define v2 (scratch + 4 * n + 2) /* 2n+1 */
+#define vinf (pp + 5 * n) /* s+t */
+#define bs1 pp /* n+1 */
+#define bsm1 (scratch + 2 * n + 2) /* n+1 */
+#define asm1 (scratch + 3 * n + 3) /* n+1 */
+#define asm2 (scratch + 4 * n + 4) /* n+1 */
+#define bsm2 (pp + n + 1) /* n+1 */
+#define bs2 (pp + 2 * n + 2) /* n+1 */
+#define as2 (pp + 3 * n + 3) /* n+1 */
+#define as1 (pp + 4 * n + 4) /* n+1 */
+
+ /* Total sccratch need is 6 * n + 3 + 1; we allocate one extra
+ limb, because products will overwrite 2n+2 limbs. */
+
+#define a0a2 scratch
+#define b0b2 scratch
+#define a1a3 asm1
+#define b1d bsm1
+
+ /* Compute as2 and asm2. */
+ flags = (enum toom6_flags) (toom6_vm2_neg & mpn_toom_eval_dgr3_pm2 (as2, asm2, ap, n, s, a1a3));
+
+ /* Compute bs2 and bsm2. */
+ b1d[n] = mpn_lshift (b1d, b1, n, 1); /* 2b1 */
+ cy = mpn_lshift (b0b2, b2, t, 2); /* 4b2 */
+ cy += mpn_add_n (b0b2, b0b2, b0, t); /* 4b2 + b0 */
+ if (t != n)
+ cy = mpn_add_1 (b0b2 + t, b0 + t, n - t, cy);
+ b0b2[n] = cy;
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (mpn_cmp (b0b2, b1d, n+1) < 0)
+ {
+ mpn_add_n_sub_n (bs2, bsm2, b1d, b0b2, n+1);
+ flags = (enum toom6_flags) (flags ^ toom6_vm2_neg);
+ }
+ else
+ {
+ mpn_add_n_sub_n (bs2, bsm2, b0b2, b1d, n+1);
+ }
+#else
+ mpn_add_n (bs2, b0b2, b1d, n+1);
+ if (mpn_cmp (b0b2, b1d, n+1) < 0)
+ {
+ mpn_sub_n (bsm2, b1d, b0b2, n+1);
+ flags = (enum toom6_flags) (flags ^ toom6_vm2_neg);
+ }
+ else
+ {
+ mpn_sub_n (bsm2, b0b2, b1d, n+1);
+ }
+#endif
+
+ /* Compute as1 and asm1. */
+ flags = (enum toom6_flags) (flags ^ toom6_vm1_neg & mpn_toom_eval_dgr3_pm1 (as1, asm1, ap, n, s, a0a2));
+
+ /* Compute bs1 and bsm1. */
+ bsm1[n] = mpn_add (bsm1, b0, n, b2, t);
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (bsm1[n] == 0 && mpn_cmp (bsm1, b1, n) < 0)
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, b1, bsm1, n);
+ bs1[n] = cy >> 1;
+ flags = (enum toom6_flags) (flags ^ toom6_vm1_neg);
+ }
+ else
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, bsm1, b1, n);
+ bs1[n] = bsm1[n] + (cy >> 1);
+ bsm1[n]-= cy & 1;
+ }
+#else
+ bs1[n] = bsm1[n] + mpn_add_n (bs1, bsm1, b1, n);
+ if (bsm1[n] == 0 && mpn_cmp (bsm1, b1, n) < 0)
+ {
+ mpn_sub_n (bsm1, b1, bsm1, n);
+ flags = (enum toom6_flags) (flags ^ toom6_vm1_neg);
+ }
+ else
+ {
+ bsm1[n] -= mpn_sub_n (bsm1, bsm1, b1, n);
+ }
+#endif
+
+ ASSERT (as1[n] <= 3);
+ ASSERT (bs1[n] <= 2);
+ ASSERT (asm1[n] <= 1);
+ ASSERT (bsm1[n] <= 1);
+ ASSERT (as2[n] <=14);
+ ASSERT (bs2[n] <= 6);
+ ASSERT (asm2[n] <= 9);
+ ASSERT (bsm2[n] <= 4);
+
+ /* vm1, 2n+1 limbs */
+ mpn_mul_n (vm1, asm1, bsm1, n+1); /* W4 */
+
+ /* vm2, 2n+1 limbs */
+ mpn_mul_n (vm2, asm2, bsm2, n+1); /* W2 */
+
+ /* v2, 2n+1 limbs */
+ mpn_mul_n (v2, as2, bs2, n+1); /* W1 */
+
+ /* v1, 2n+1 limbs */
+ mpn_mul_n (v1, as1, bs1, n+1); /* W3 */
+
+ /* vinf, s+t limbs */ /* W0 */
+ if (s > t) mpn_mul (vinf, a3, s, b2, t);
+ else mpn_mul (vinf, b2, t, a3, s);
+
+ /* v0, 2n limbs */
+ mpn_mul_n (v0, ap, bp, n); /* W5 */
+
+ mpn_toom_interpolate_6pts (pp, n, flags, vm1, vm2, v2, t + s);
+
+#undef v0
+#undef vm1
+#undef v1
+#undef vm2
+#undef v2
+#undef vinf
+#undef bs1
+#undef bs2
+#undef bsm1
+#undef bsm2
+#undef asm1
+#undef asm2
+/* #undef as1 */
+/* #undef as2 */
+#undef a0a2
+#undef b0b2
+#undef a1a3
+#undef b1d
+#undef a0
+#undef a1
+#undef a2
+#undef a3
+#undef b0
+#undef b1
+#undef b2
+}
diff --git a/gmp/mpn/generic/toom44_mul.c b/gmp/mpn/generic/toom44_mul.c
new file mode 100644
index 0000000000..5abf2d14a9
--- /dev/null
+++ b/gmp/mpn/generic/toom44_mul.c
@@ -0,0 +1,236 @@
+/* mpn_toom44_mul -- Multiply {ap,an} and {bp,bn} where an and bn are close in
+ size. Or more accurately, bn <= an < (4/3)bn.
+
+ Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2008, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: 0, +1, -1, +2, -2, 1/2, +inf
+
+ <-s--><--n--><--n--><--n-->
+ ____ ______ ______ ______
+ |_a3_|___a2_|___a1_|___a0_|
+ |b3_|___b2_|___b1_|___b0_|
+ <-t-><--n--><--n--><--n-->
+
+ v0 = a0 * b0 # A(0)*B(0)
+ v1 = ( a0+ a1+ a2+ a3)*( b0+ b1+ b2+ b3) # A(1)*B(1) ah <= 3 bh <= 3
+ vm1 = ( a0- a1+ a2- a3)*( b0- b1+ b2- b3) # A(-1)*B(-1) |ah| <= 1 |bh| <= 1
+ v2 = ( a0+2a1+4a2+8a3)*( b0+2b1+4b2+8b3) # A(2)*B(2) ah <= 14 bh <= 14
+ vm2 = ( a0-2a1+4a2-8a3)*( b0-2b1+4b2-8b3) # A(2)*B(2) ah <= 9 |bh| <= 9
+ vh = (8a0+4a1+2a2+ a3)*(8b0+4b1+2b2+ b3) # A(1/2)*B(1/2) ah <= 14 bh <= 14
+ vinf= a3 * b2 # A(inf)*B(inf)
+*/
+
+#if TUNE_PROGRAM_BUILD
+#define MAYBE_mul_basecase 1
+#define MAYBE_mul_toom22 1
+#define MAYBE_mul_toom44 1
+#else
+#define MAYBE_mul_basecase \
+ (MUL_TOOM44_THRESHOLD < 4 * MUL_TOOM22_THRESHOLD)
+#define MAYBE_mul_toom22 \
+ (MUL_TOOM44_THRESHOLD < 4 * MUL_TOOM33_THRESHOLD)
+#define MAYBE_mul_toom44 \
+ (MUL_TOOM6H_THRESHOLD >= 4 * MUL_TOOM44_THRESHOLD)
+#endif
+
+#define TOOM44_MUL_N_REC(p, a, b, n, ws) \
+ do { \
+ if (MAYBE_mul_basecase \
+ && BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD)) \
+ mpn_mul_basecase (p, a, n, b, n); \
+ else if (MAYBE_mul_toom22 \
+ && BELOW_THRESHOLD (n, MUL_TOOM33_THRESHOLD)) \
+ mpn_toom22_mul (p, a, n, b, n, ws); \
+ else if (! MAYBE_mul_toom44 \
+ || BELOW_THRESHOLD (n, MUL_TOOM44_THRESHOLD)) \
+ mpn_toom33_mul (p, a, n, b, n, ws); \
+ else \
+ mpn_toom44_mul (p, a, n, b, n, ws); \
+ } while (0)
+
+/* Use of scratch space. In the product area, we store
+
+ ___________________
+ |vinf|____|_v1_|_v0_|
+ s+t 2n-1 2n+1 2n
+
+ The other recursive products, vm1, v2, vm2, vh are stored in the
+ scratch area. When computing them, we use the product area for
+ intermediate values.
+
+ Next, we compute v1. We can store the intermediate factors at v0
+ and at vh + 2n + 2.
+
+ Finally, for v0 and vinf, factors are parts of the input operands,
+ and we need scratch space only for the recursive multiplication.
+
+ In all, if S(an) is the scratch need, the needed space is bounded by
+
+ S(an) <= 4 (2*ceil(an/4) + 1) + 1 + S(ceil(an/4) + 1)
+
+ which should give S(n) = 8 n/3 + c log(n) for some constant c.
+*/
+
+void
+mpn_toom44_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn,
+ mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ mp_limb_t cy;
+ enum toom7_flags flags;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2*n)
+#define a3 (ap + 3*n)
+#define b0 bp
+#define b1 (bp + n)
+#define b2 (bp + 2*n)
+#define b3 (bp + 3*n)
+
+ ASSERT (an >= bn);
+
+ n = (an + 3) >> 2;
+
+ s = an - 3 * n;
+ t = bn - 3 * n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+ ASSERT (s >= t);
+
+ /* NOTE: The multiplications to v2, vm2, vh and vm1 overwrites the
+ * following limb, so these must be computed in order, and we need a
+ * one limb gap to tp. */
+#define v0 pp /* 2n */
+#define v1 (pp + 2 * n) /* 2n+1 */
+#define vinf (pp + 6 * n) /* s+t */
+#define v2 scratch /* 2n+1 */
+#define vm2 (scratch + 2 * n + 1) /* 2n+1 */
+#define vh (scratch + 4 * n + 2) /* 2n+1 */
+#define vm1 (scratch + 6 * n + 3) /* 2n+1 */
+#define tp (scratch + 8*n + 5)
+
+ /* apx and bpx must not overlap with v1 */
+#define apx pp /* n+1 */
+#define amx (pp + n + 1) /* n+1 */
+#define bmx (pp + 2*n + 2) /* n+1 */
+#define bpx (pp + 4*n + 2) /* n+1 */
+
+ /* Total scratch need: 8*n + 5 + scratch for recursive calls. This
+ gives roughly 32 n/3 + log term. */
+
+ /* Compute apx = a0 + 2 a1 + 4 a2 + 8 a3 and amx = a0 - 2 a1 + 4 a2 - 8 a3. */
+ flags = (enum toom7_flags) (toom7_w1_neg & mpn_toom_eval_dgr3_pm2 (apx, amx, ap, n, s, tp));
+
+ /* Compute bpx = b0 + 2 b1 + 4 b2 + 8 b3 and bmx = b0 - 2 b1 + 4 b2 - 8 b3. */
+ flags = (enum toom7_flags) (flags ^ toom7_w1_neg & mpn_toom_eval_dgr3_pm2 (bpx, bmx, bp, n, t, tp));
+
+ TOOM44_MUL_N_REC (v2, apx, bpx, n + 1, tp); /* v2, 2n+1 limbs */
+ TOOM44_MUL_N_REC (vm2, amx, bmx, n + 1, tp); /* vm2, 2n+1 limbs */
+
+ /* Compute apx = 8 a0 + 4 a1 + 2 a2 + a3 = (((2*a0 + a1) * 2 + a2) * 2 + a3 */
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (apx, a1, a0, n);
+ cy = 2*cy + mpn_addlsh1_n (apx, a2, apx, n);
+ if (s < n)
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_addlsh1_n (apx, a3, apx, s);
+ apx[n] = 2*cy + mpn_lshift (apx + s, apx + s, n - s, 1);
+ MPN_INCR_U (apx + s, n+1-s, cy2);
+ }
+ else
+ apx[n] = 2*cy + mpn_addlsh1_n (apx, a3, apx, n);
+#else
+ cy = mpn_lshift (apx, a0, n, 1);
+ cy += mpn_add_n (apx, apx, a1, n);
+ cy = 2*cy + mpn_lshift (apx, apx, n, 1);
+ cy += mpn_add_n (apx, apx, a2, n);
+ cy = 2*cy + mpn_lshift (apx, apx, n, 1);
+ apx[n] = cy + mpn_add (apx, apx, n, a3, s);
+#endif
+
+ /* Compute bpx = 8 b0 + 4 b1 + 2 b2 + b3 = (((2*b0 + b1) * 2 + b2) * 2 + b3 */
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (bpx, b1, b0, n);
+ cy = 2*cy + mpn_addlsh1_n (bpx, b2, bpx, n);
+ if (t < n)
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_addlsh1_n (bpx, b3, bpx, t);
+ bpx[n] = 2*cy + mpn_lshift (bpx + t, bpx + t, n - t, 1);
+ MPN_INCR_U (bpx + t, n+1-t, cy2);
+ }
+ else
+ bpx[n] = 2*cy + mpn_addlsh1_n (bpx, b3, bpx, n);
+#else
+ cy = mpn_lshift (bpx, b0, n, 1);
+ cy += mpn_add_n (bpx, bpx, b1, n);
+ cy = 2*cy + mpn_lshift (bpx, bpx, n, 1);
+ cy += mpn_add_n (bpx, bpx, b2, n);
+ cy = 2*cy + mpn_lshift (bpx, bpx, n, 1);
+ bpx[n] = cy + mpn_add (bpx, bpx, n, b3, t);
+#endif
+
+ ASSERT (apx[n] < 15);
+ ASSERT (bpx[n] < 15);
+
+ TOOM44_MUL_N_REC (vh, apx, bpx, n + 1, tp); /* vh, 2n+1 limbs */
+
+ /* Compute apx = a0 + a1 + a2 + a3 and amx = a0 - a1 + a2 - a3. */
+ flags = (enum toom7_flags) (flags | toom7_w3_neg & mpn_toom_eval_dgr3_pm1 (apx, amx, ap, n, s, tp));
+
+ /* Compute bpx = b0 + b1 + b2 + b3 bnd bmx = b0 - b1 + b2 - b3. */
+ flags = (enum toom7_flags) (flags ^ toom7_w3_neg & mpn_toom_eval_dgr3_pm1 (bpx, bmx, bp, n, t, tp));
+
+ TOOM44_MUL_N_REC (vm1, amx, bmx, n + 1, tp); /* vm1, 2n+1 limbs */
+ /* Clobbers amx, bmx. */
+ TOOM44_MUL_N_REC (v1, apx, bpx, n + 1, tp); /* v1, 2n+1 limbs */
+
+ TOOM44_MUL_N_REC (v0, a0, b0, n, tp);
+ if (s > t)
+ mpn_mul (vinf, a3, s, b3, t);
+ else
+ TOOM44_MUL_N_REC (vinf, a3, b3, s, tp); /* vinf, s+t limbs */
+
+ mpn_toom_interpolate_7pts (pp, n, flags, vm2, vm1, v2, vh, s + t, tp);
+}
diff --git a/gmp/mpn/generic/toom4_sqr.c b/gmp/mpn/generic/toom4_sqr.c
new file mode 100644
index 0000000000..b4154ba83f
--- /dev/null
+++ b/gmp/mpn/generic/toom4_sqr.c
@@ -0,0 +1,164 @@
+/* mpn_toom4_sqr -- Square {ap,an}.
+
+ Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2010, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: -1, -1/2, 0, +1/2, +1, +2, +inf
+
+ <-s--><--n--><--n--><--n-->
+ ____ ______ ______ ______
+ |_a3_|___a2_|___a1_|___a0_|
+
+ v0 = a0 ^2 # A(0)^2
+ v1 = ( a0+ a1+ a2+ a3)^2 # A(1)^2 ah <= 3
+ vm1 = ( a0- a1+ a2- a3)^2 # A(-1)^2 |ah| <= 1
+ v2 = ( a0+2a1+4a2+8a3)^2 # A(2)^2 ah <= 14
+ vh = (8a0+4a1+2a2+ a3)^2 # A(1/2)^2 ah <= 14
+ vmh = (8a0-4a1+2a2- a3)^2 # A(-1/2)^2 -4<=ah<=9
+ vinf= a3 ^2 # A(inf)^2
+*/
+
+#if TUNE_PROGRAM_BUILD
+#define MAYBE_sqr_basecase 1
+#define MAYBE_sqr_toom2 1
+#define MAYBE_sqr_toom4 1
+#else
+#define MAYBE_sqr_basecase \
+ (SQR_TOOM4_THRESHOLD < 4 * SQR_TOOM2_THRESHOLD)
+#define MAYBE_sqr_toom2 \
+ (SQR_TOOM4_THRESHOLD < 4 * SQR_TOOM3_THRESHOLD)
+#define MAYBE_sqr_toom4 \
+ (SQR_TOOM6_THRESHOLD >= 4 * SQR_TOOM4_THRESHOLD)
+#endif
+
+#define TOOM4_SQR_REC(p, a, n, ws) \
+ do { \
+ if (MAYBE_sqr_basecase \
+ && BELOW_THRESHOLD (n, SQR_TOOM2_THRESHOLD)) \
+ mpn_sqr_basecase (p, a, n); \
+ else if (MAYBE_sqr_toom2 \
+ && BELOW_THRESHOLD (n, SQR_TOOM3_THRESHOLD)) \
+ mpn_toom2_sqr (p, a, n, ws); \
+ else if (! MAYBE_sqr_toom4 \
+ || BELOW_THRESHOLD (n, SQR_TOOM4_THRESHOLD)) \
+ mpn_toom3_sqr (p, a, n, ws); \
+ else \
+ mpn_toom4_sqr (p, a, n, ws); \
+ } while (0)
+
+void
+mpn_toom4_sqr (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_ptr scratch)
+{
+ mp_size_t n, s;
+ mp_limb_t cy;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2*n)
+#define a3 (ap + 3*n)
+
+ n = (an + 3) >> 2;
+
+ s = an - 3 * n;
+
+ ASSERT (0 < s && s <= n);
+
+ /* NOTE: The multiplications to v2, vm2, vh and vm1 overwrites the
+ * following limb, so these must be computed in order, and we need a
+ * one limb gap to tp. */
+#define v0 pp /* 2n */
+#define v1 (pp + 2 * n) /* 2n+1 */
+#define vinf (pp + 6 * n) /* s+t */
+#define v2 scratch /* 2n+1 */
+#define vm2 (scratch + 2 * n + 1) /* 2n+1 */
+#define vh (scratch + 4 * n + 2) /* 2n+1 */
+#define vm1 (scratch + 6 * n + 3) /* 2n+1 */
+#define tp (scratch + 8*n + 5)
+
+ /* No overlap with v1 */
+#define apx pp /* n+1 */
+#define amx (pp + 4*n + 2) /* n+1 */
+
+ /* Total scratch need: 8*n + 5 + scratch for recursive calls. This
+ gives roughly 32 n/3 + log term. */
+
+ /* Compute apx = a0 + 2 a1 + 4 a2 + 8 a3 and amx = a0 - 2 a1 + 4 a2 - 8 a3. */
+ mpn_toom_eval_dgr3_pm2 (apx, amx, ap, n, s, tp);
+
+ TOOM4_SQR_REC (v2, apx, n + 1, tp); /* v2, 2n+1 limbs */
+ TOOM4_SQR_REC (vm2, amx, n + 1, tp); /* vm2, 2n+1 limbs */
+
+ /* Compute apx = 8 a0 + 4 a1 + 2 a2 + a3 = (((2*a0 + a1) * 2 + a2) * 2 + a3 */
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (apx, a1, a0, n);
+ cy = 2*cy + mpn_addlsh1_n (apx, a2, apx, n);
+ if (s < n)
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_addlsh1_n (apx, a3, apx, s);
+ apx[n] = 2*cy + mpn_lshift (apx + s, apx + s, n - s, 1);
+ MPN_INCR_U (apx + s, n+1-s, cy2);
+ }
+ else
+ apx[n] = 2*cy + mpn_addlsh1_n (apx, a3, apx, n);
+#else
+ cy = mpn_lshift (apx, a0, n, 1);
+ cy += mpn_add_n (apx, apx, a1, n);
+ cy = 2*cy + mpn_lshift (apx, apx, n, 1);
+ cy += mpn_add_n (apx, apx, a2, n);
+ cy = 2*cy + mpn_lshift (apx, apx, n, 1);
+ apx[n] = cy + mpn_add (apx, apx, n, a3, s);
+#endif
+
+ ASSERT (apx[n] < 15);
+
+ TOOM4_SQR_REC (vh, apx, n + 1, tp); /* vh, 2n+1 limbs */
+
+ /* Compute apx = a0 + a1 + a2 + a3 and amx = a0 - a1 + a2 - a3. */
+ mpn_toom_eval_dgr3_pm1 (apx, amx, ap, n, s, tp);
+
+ TOOM4_SQR_REC (v1, apx, n + 1, tp); /* v1, 2n+1 limbs */
+ TOOM4_SQR_REC (vm1, amx, n + 1, tp); /* vm1, 2n+1 limbs */
+
+ TOOM4_SQR_REC (v0, a0, n, tp);
+ TOOM4_SQR_REC (vinf, a3, s, tp); /* vinf, 2s limbs */
+
+ mpn_toom_interpolate_7pts (pp, n, (enum toom7_flags) 0, vm2, vm1, v2, vh, 2*s, tp);
+}
diff --git a/gmp/mpn/generic/toom52_mul.c b/gmp/mpn/generic/toom52_mul.c
new file mode 100644
index 0000000000..e15b5833aa
--- /dev/null
+++ b/gmp/mpn/generic/toom52_mul.c
@@ -0,0 +1,257 @@
+/* mpn_toom52_mul -- Multiply {ap,an} and {bp,bn} where an is nominally 4/3
+ times as large as bn. Or more accurately, bn < an < 2 bn.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ The idea of applying toom to unbalanced multiplication is due to Marco
+ Bodrato and Alberto Zanoni.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: -2, -1, 0, +1, +2, +inf
+
+ <-s-><--n--><--n--><--n--><--n-->
+ ___ ______ ______ ______ ______
+ |a4_|___a3_|___a2_|___a1_|___a0_|
+ |b1|___b0_|
+ <t-><--n-->
+
+ v0 = a0 * b0 # A(0)*B(0)
+ v1 = (a0+ a1+ a2+ a3+ a4)*(b0+ b1) # A(1)*B(1) ah <= 4 bh <= 1
+ vm1 = (a0- a1+ a2- a3+ a4)*(b0- b1) # A(-1)*B(-1) |ah| <= 2 bh = 0
+ v2 = (a0+2a1+4a2+8a3+16a4)*(b0+2b1) # A(2)*B(2) ah <= 30 bh <= 2
+ vm2 = (a0-2a1+4a2-8a3+16a4)*(b0-2b1) # A(-2)*B(-2) |ah| <= 20 |bh|<= 1
+ vinf= a4 * b1 # A(inf)*B(inf)
+
+ Some slight optimization in evaluation are taken from the paper:
+ "Towards Optimal Toom-Cook Multiplication for Univariate and
+ Multivariate Polynomials in Characteristic 2 and 0."
+*/
+
+void
+mpn_toom52_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn, mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ enum toom6_flags flags;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2 * n)
+#define a3 (ap + 3 * n)
+#define a4 (ap + 4 * n)
+#define b0 bp
+#define b1 (bp + n)
+
+ n = 1 + (2 * an >= 5 * bn ? (an - 1) / (size_t) 5 : (bn - 1) >> 1);
+
+ s = an - 4 * n;
+ t = bn - n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+
+ /* Ensures that 5 values of n+1 limbs each fits in the product area.
+ Borderline cases are an = 32, bn = 8, n = 7, and an = 36, bn = 9,
+ n = 8. */
+ ASSERT (s+t >= 5);
+
+#define v0 pp /* 2n */
+#define vm1 (scratch) /* 2n+1 */
+#define v1 (pp + 2 * n) /* 2n+1 */
+#define vm2 (scratch + 2 * n + 1) /* 2n+1 */
+#define v2 (scratch + 4 * n + 2) /* 2n+1 */
+#define vinf (pp + 5 * n) /* s+t */
+#define bs1 pp /* n+1 */
+#define bsm1 (scratch + 2 * n + 2) /* n */
+#define asm1 (scratch + 3 * n + 3) /* n+1 */
+#define asm2 (scratch + 4 * n + 4) /* n+1 */
+#define bsm2 (pp + n + 1) /* n+1 */
+#define bs2 (pp + 2 * n + 2) /* n+1 */
+#define as2 (pp + 3 * n + 3) /* n+1 */
+#define as1 (pp + 4 * n + 4) /* n+1 */
+
+ /* Scratch need is 6 * n + 3 + 1. We need one extra limb, because
+ products will overwrite 2n+2 limbs. */
+
+#define a0a2 scratch
+#define a1a3 asm1
+
+ /* Compute as2 and asm2. */
+ flags = (enum toom6_flags) (toom6_vm2_neg & mpn_toom_eval_pm2 (as2, asm2, 4, ap, n, s, a1a3));
+
+ /* Compute bs1 and bsm1. */
+ if (t == n)
+ {
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ mp_limb_t cy;
+
+ if (mpn_cmp (b0, b1, n) < 0)
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, b1, b0, n);
+ flags = (enum toom6_flags) (flags ^ toom6_vm1_neg);
+ }
+ else
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, b0, b1, n);
+ }
+ bs1[n] = cy >> 1;
+#else
+ bs1[n] = mpn_add_n (bs1, b0, b1, n);
+ if (mpn_cmp (b0, b1, n) < 0)
+ {
+ mpn_sub_n (bsm1, b1, b0, n);
+ flags = (enum toom6_flags) (flags ^ toom6_vm1_neg);
+ }
+ else
+ {
+ mpn_sub_n (bsm1, b0, b1, n);
+ }
+#endif
+ }
+ else
+ {
+ bs1[n] = mpn_add (bs1, b0, n, b1, t);
+ if (mpn_zero_p (b0 + t, n - t) && mpn_cmp (b0, b1, t) < 0)
+ {
+ mpn_sub_n (bsm1, b1, b0, t);
+ MPN_ZERO (bsm1 + t, n - t);
+ flags = (enum toom6_flags) (flags ^ toom6_vm1_neg);
+ }
+ else
+ {
+ mpn_sub (bsm1, b0, n, b1, t);
+ }
+ }
+
+ /* Compute bs2 and bsm2, recycling bs1 and bsm1. bs2=bs1+b1; bsm2=bsm1-b1 */
+ mpn_add (bs2, bs1, n+1, b1, t);
+ if (flags & toom6_vm1_neg )
+ {
+ bsm2[n] = mpn_add (bsm2, bsm1, n, b1, t);
+ flags = (enum toom6_flags) (flags ^ toom6_vm2_neg);
+ }
+ else
+ {
+ bsm2[n] = 0;
+ if (t == n)
+ {
+ if (mpn_cmp (bsm1, b1, n) < 0)
+ {
+ mpn_sub_n (bsm2, b1, bsm1, n);
+ flags = (enum toom6_flags) (flags ^ toom6_vm2_neg);
+ }
+ else
+ {
+ mpn_sub_n (bsm2, bsm1, b1, n);
+ }
+ }
+ else
+ {
+ if (mpn_zero_p (bsm1 + t, n - t) && mpn_cmp (bsm1, b1, t) < 0)
+ {
+ mpn_sub_n (bsm2, b1, bsm1, t);
+ MPN_ZERO (bsm2 + t, n - t);
+ flags = (enum toom6_flags) (flags ^ toom6_vm2_neg);
+ }
+ else
+ {
+ mpn_sub (bsm2, bsm1, n, b1, t);
+ }
+ }
+ }
+
+ /* Compute as1 and asm1. */
+ flags = (enum toom6_flags) (flags ^ toom6_vm1_neg & mpn_toom_eval_pm1 (as1, asm1, 4, ap, n, s, a0a2));
+
+ ASSERT (as1[n] <= 4);
+ ASSERT (bs1[n] <= 1);
+ ASSERT (asm1[n] <= 2);
+/* ASSERT (bsm1[n] <= 1); */
+ ASSERT (as2[n] <=30);
+ ASSERT (bs2[n] <= 2);
+ ASSERT (asm2[n] <= 20);
+ ASSERT (bsm2[n] <= 1);
+
+ /* vm1, 2n+1 limbs */
+ mpn_mul (vm1, asm1, n+1, bsm1, n); /* W4 */
+
+ /* vm2, 2n+1 limbs */
+ mpn_mul_n (vm2, asm2, bsm2, n+1); /* W2 */
+
+ /* v2, 2n+1 limbs */
+ mpn_mul_n (v2, as2, bs2, n+1); /* W1 */
+
+ /* v1, 2n+1 limbs */
+ mpn_mul_n (v1, as1, bs1, n+1); /* W3 */
+
+ /* vinf, s+t limbs */ /* W0 */
+ if (s > t) mpn_mul (vinf, a4, s, b1, t);
+ else mpn_mul (vinf, b1, t, a4, s);
+
+ /* v0, 2n limbs */
+ mpn_mul_n (v0, ap, bp, n); /* W5 */
+
+ mpn_toom_interpolate_6pts (pp, n, flags, vm1, vm2, v2, t + s);
+
+#undef v0
+#undef vm1
+#undef v1
+#undef vm2
+#undef v2
+#undef vinf
+#undef bs1
+#undef bs2
+#undef bsm1
+#undef bsm2
+#undef asm1
+#undef asm2
+#undef as1
+#undef as2
+#undef a0a2
+#undef b0b2
+#undef a1a3
+#undef a0
+#undef a1
+#undef a2
+#undef a3
+#undef b0
+#undef b1
+#undef b2
+
+}
diff --git a/gmp/mpn/generic/toom53_mul.c b/gmp/mpn/generic/toom53_mul.c
new file mode 100644
index 0000000000..41274d48e0
--- /dev/null
+++ b/gmp/mpn/generic/toom53_mul.c
@@ -0,0 +1,331 @@
+/* mpn_toom53_mul -- Multiply {ap,an} and {bp,bn} where an is nominally 5/3
+ times as large as bn. Or more accurately, (4/3)bn < an < (5/2)bn.
+
+ Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+ The idea of applying toom to unbalanced multiplication is due to Marco
+ Bodrato and Alberto Zanoni.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2008, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in: 0, +1, -1, +2, -2, 1/2, +inf
+
+ <-s-><--n--><--n--><--n--><--n-->
+ ___ ______ ______ ______ ______
+ |a4_|___a3_|___a2_|___a1_|___a0_|
+ |__b2|___b1_|___b0_|
+ <-t--><--n--><--n-->
+
+ v0 = a0 * b0 # A(0)*B(0)
+ v1 = ( a0+ a1+ a2+ a3+ a4)*( b0+ b1+ b2) # A(1)*B(1) ah <= 4 bh <= 2
+ vm1 = ( a0- a1+ a2- a3+ a4)*( b0- b1+ b2) # A(-1)*B(-1) |ah| <= 2 bh <= 1
+ v2 = ( a0+2a1+4a2+8a3+16a4)*( b0+2b1+4b2) # A(2)*B(2) ah <= 30 bh <= 6
+ vm2 = ( a0-2a1+4a2-8a3+16a4)*( b0-2b1+4b2) # A(2)*B(2) -9<=ah<=20 -1<=bh<=4
+ vh = (16a0+8a1+4a2+2a3+ a4)*(4b0+2b1+ b2) # A(1/2)*B(1/2) ah <= 30 bh <= 6
+ vinf= a4 * b2 # A(inf)*B(inf)
+*/
+
+void
+mpn_toom53_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn,
+ mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ mp_limb_t cy;
+ mp_ptr gp;
+ mp_ptr as1, asm1, as2, asm2, ash;
+ mp_ptr bs1, bsm1, bs2, bsm2, bsh;
+ enum toom7_flags flags;
+ TMP_DECL;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2*n)
+#define a3 (ap + 3*n)
+#define a4 (ap + 4*n)
+#define b0 bp
+#define b1 (bp + n)
+#define b2 (bp + 2*n)
+
+ n = 1 + (3 * an >= 5 * bn ? (an - 1) / (size_t) 5 : (bn - 1) / (size_t) 3);
+
+ s = an - 4 * n;
+ t = bn - 2 * n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+
+ TMP_MARK;
+
+ as1 = TMP_SALLOC_LIMBS (n + 1);
+ asm1 = TMP_SALLOC_LIMBS (n + 1);
+ as2 = TMP_SALLOC_LIMBS (n + 1);
+ asm2 = TMP_SALLOC_LIMBS (n + 1);
+ ash = TMP_SALLOC_LIMBS (n + 1);
+
+ bs1 = TMP_SALLOC_LIMBS (n + 1);
+ bsm1 = TMP_SALLOC_LIMBS (n + 1);
+ bs2 = TMP_SALLOC_LIMBS (n + 1);
+ bsm2 = TMP_SALLOC_LIMBS (n + 1);
+ bsh = TMP_SALLOC_LIMBS (n + 1);
+
+ gp = pp;
+
+ /* Compute as1 and asm1. */
+ flags = (enum toom7_flags) (toom7_w3_neg & mpn_toom_eval_pm1 (as1, asm1, 4, ap, n, s, gp));
+
+ /* Compute as2 and asm2. */
+ flags = (enum toom7_flags) (flags | toom7_w1_neg & mpn_toom_eval_pm2 (as2, asm2, 4, ap, n, s, gp));
+
+ /* Compute ash = 16 a0 + 8 a1 + 4 a2 + 2 a3 + a4
+ = 2*(2*(2*(2*a0 + a1) + a2) + a3) + a4 */
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (ash, a1, a0, n);
+ cy = 2*cy + mpn_addlsh1_n (ash, a2, ash, n);
+ cy = 2*cy + mpn_addlsh1_n (ash, a3, ash, n);
+ if (s < n)
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_addlsh1_n (ash, a4, ash, s);
+ ash[n] = 2*cy + mpn_lshift (ash + s, ash + s, n - s, 1);
+ MPN_INCR_U (ash + s, n+1-s, cy2);
+ }
+ else
+ ash[n] = 2*cy + mpn_addlsh1_n (ash, a4, ash, n);
+#else
+ cy = mpn_lshift (ash, a0, n, 1);
+ cy += mpn_add_n (ash, ash, a1, n);
+ cy = 2*cy + mpn_lshift (ash, ash, n, 1);
+ cy += mpn_add_n (ash, ash, a2, n);
+ cy = 2*cy + mpn_lshift (ash, ash, n, 1);
+ cy += mpn_add_n (ash, ash, a3, n);
+ cy = 2*cy + mpn_lshift (ash, ash, n, 1);
+ ash[n] = cy + mpn_add (ash, ash, n, a4, s);
+#endif
+
+ /* Compute bs1 and bsm1. */
+ bs1[n] = mpn_add (bs1, b0, n, b2, t); /* b0 + b2 */
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (bs1[n] == 0 && mpn_cmp (bs1, b1, n) < 0)
+ {
+ bs1[n] = mpn_add_n_sub_n (bs1, bsm1, b1, bs1, n) >> 1;
+ bsm1[n] = 0;
+ flags = (enum toom7_flags) (flags ^ toom7_w3_neg);
+ }
+ else
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, bs1, b1, n);
+ bsm1[n] = bs1[n] - (cy & 1);
+ bs1[n] += (cy >> 1);
+ }
+#else
+ if (bs1[n] == 0 && mpn_cmp (bs1, b1, n) < 0)
+ {
+ mpn_sub_n (bsm1, b1, bs1, n);
+ bsm1[n] = 0;
+ flags = (enum toom7_flags) (flags ^ toom7_w3_neg);
+ }
+ else
+ {
+ bsm1[n] = bs1[n] - mpn_sub_n (bsm1, bs1, b1, n);
+ }
+ bs1[n] += mpn_add_n (bs1, bs1, b1, n); /* b0+b1+b2 */
+#endif
+
+ /* Compute bs2 and bsm2. */
+#if HAVE_NATIVE_mpn_addlsh_n || HAVE_NATIVE_mpn_addlsh2_n
+#if HAVE_NATIVE_mpn_addlsh2_n
+ cy = mpn_addlsh2_n (bs2, b0, b2, t);
+#else /* HAVE_NATIVE_mpn_addlsh_n */
+ cy = mpn_addlsh_n (bs2, b0, b2, t, 2);
+#endif
+ if (t < n)
+ cy = mpn_add_1 (bs2 + t, b0 + t, n - t, cy);
+ bs2[n] = cy;
+#else
+ cy = mpn_lshift (gp, b2, t, 2);
+ bs2[n] = mpn_add (bs2, b0, n, gp, t);
+ MPN_INCR_U (bs2 + t, n+1-t, cy);
+#endif
+
+ gp[n] = mpn_lshift (gp, b1, n, 1);
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (mpn_cmp (bs2, gp, n+1) < 0)
+ {
+ ASSERT_NOCARRY (mpn_add_n_sub_n (bs2, bsm2, gp, bs2, n+1));
+ flags = (enum toom7_flags) (flags ^ toom7_w1_neg);
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_add_n_sub_n (bs2, bsm2, bs2, gp, n+1));
+ }
+#else
+ if (mpn_cmp (bs2, gp, n+1) < 0)
+ {
+ ASSERT_NOCARRY (mpn_sub_n (bsm2, gp, bs2, n+1));
+ flags = (enum toom7_flags) (flags ^ toom7_w1_neg);
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_sub_n (bsm2, bs2, gp, n+1));
+ }
+ mpn_add_n (bs2, bs2, gp, n+1);
+#endif
+
+ /* Compute bsh = 4 b0 + 2 b1 + b2 = 2*(2*b0 + b1)+b2. */
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (bsh, b1, b0, n);
+ if (t < n)
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_addlsh1_n (bsh, b2, bsh, t);
+ bsh[n] = 2*cy + mpn_lshift (bsh + t, bsh + t, n - t, 1);
+ MPN_INCR_U (bsh + t, n+1-t, cy2);
+ }
+ else
+ bsh[n] = 2*cy + mpn_addlsh1_n (bsh, b2, bsh, n);
+#else
+ cy = mpn_lshift (bsh, b0, n, 1);
+ cy += mpn_add_n (bsh, bsh, b1, n);
+ cy = 2*cy + mpn_lshift (bsh, bsh, n, 1);
+ bsh[n] = cy + mpn_add (bsh, bsh, n, b2, t);
+#endif
+
+ ASSERT (as1[n] <= 4);
+ ASSERT (bs1[n] <= 2);
+ ASSERT (asm1[n] <= 2);
+ ASSERT (bsm1[n] <= 1);
+ ASSERT (as2[n] <= 30);
+ ASSERT (bs2[n] <= 6);
+ ASSERT (asm2[n] <= 20);
+ ASSERT (bsm2[n] <= 4);
+ ASSERT (ash[n] <= 30);
+ ASSERT (bsh[n] <= 6);
+
+#define v0 pp /* 2n */
+#define v1 (pp + 2 * n) /* 2n+1 */
+#define vinf (pp + 6 * n) /* s+t */
+#define v2 scratch /* 2n+1 */
+#define vm2 (scratch + 2 * n + 1) /* 2n+1 */
+#define vh (scratch + 4 * n + 2) /* 2n+1 */
+#define vm1 (scratch + 6 * n + 3) /* 2n+1 */
+#define scratch_out (scratch + 8 * n + 4) /* 2n+1 */
+ /* Total scratch need: 10*n+5 */
+
+ /* Must be in allocation order, as they overwrite one limb beyond
+ * 2n+1. */
+ mpn_mul_n (v2, as2, bs2, n + 1); /* v2, 2n+1 limbs */
+ mpn_mul_n (vm2, asm2, bsm2, n + 1); /* vm2, 2n+1 limbs */
+ mpn_mul_n (vh, ash, bsh, n + 1); /* vh, 2n+1 limbs */
+
+ /* vm1, 2n+1 limbs */
+#ifdef SMALLER_RECURSION
+ mpn_mul_n (vm1, asm1, bsm1, n);
+ if (asm1[n] == 1)
+ {
+ cy = bsm1[n] + mpn_add_n (vm1 + n, vm1 + n, bsm1, n);
+ }
+ else if (asm1[n] == 2)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = 2 * bsm1[n] + mpn_addlsh1_n (vm1 + n, vm1 + n, bsm1, n);
+#else
+ cy = 2 * bsm1[n] + mpn_addmul_1 (vm1 + n, bsm1, n, CNST_LIMB(2));
+#endif
+ }
+ else
+ cy = 0;
+ if (bsm1[n] != 0)
+ cy += mpn_add_n (vm1 + n, vm1 + n, asm1, n);
+ vm1[2 * n] = cy;
+#else /* SMALLER_RECURSION */
+ vm1[2 * n] = 0;
+ mpn_mul_n (vm1, asm1, bsm1, n + ((asm1[n] | bsm1[n]) != 0));
+#endif /* SMALLER_RECURSION */
+
+ /* v1, 2n+1 limbs */
+#ifdef SMALLER_RECURSION
+ mpn_mul_n (v1, as1, bs1, n);
+ if (as1[n] == 1)
+ {
+ cy = bs1[n] + mpn_add_n (v1 + n, v1 + n, bs1, n);
+ }
+ else if (as1[n] == 2)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = 2 * bs1[n] + mpn_addlsh1_n (v1 + n, v1 + n, bs1, n);
+#else
+ cy = 2 * bs1[n] + mpn_addmul_1 (v1 + n, bs1, n, CNST_LIMB(2));
+#endif
+ }
+ else if (as1[n] != 0)
+ {
+ cy = as1[n] * bs1[n] + mpn_addmul_1 (v1 + n, bs1, n, as1[n]);
+ }
+ else
+ cy = 0;
+ if (bs1[n] == 1)
+ {
+ cy += mpn_add_n (v1 + n, v1 + n, as1, n);
+ }
+ else if (bs1[n] == 2)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy += mpn_addlsh1_n (v1 + n, v1 + n, as1, n);
+#else
+ cy += mpn_addmul_1 (v1 + n, as1, n, CNST_LIMB(2));
+#endif
+ }
+ v1[2 * n] = cy;
+#else /* SMALLER_RECURSION */
+ v1[2 * n] = 0;
+ mpn_mul_n (v1, as1, bs1, n + ((as1[n] | bs1[n]) != 0));
+#endif /* SMALLER_RECURSION */
+
+ mpn_mul_n (v0, a0, b0, n); /* v0, 2n limbs */
+
+ /* vinf, s+t limbs */
+ if (s > t) mpn_mul (vinf, a4, s, b2, t);
+ else mpn_mul (vinf, b2, t, a4, s);
+
+ mpn_toom_interpolate_7pts (pp, n, flags, vm2, vm1, v2, vh, s + t,
+ scratch_out);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/toom54_mul.c b/gmp/mpn/generic/toom54_mul.c
new file mode 100644
index 0000000000..939bb53ab6
--- /dev/null
+++ b/gmp/mpn/generic/toom54_mul.c
@@ -0,0 +1,143 @@
+/* Implementation of the algorithm for Toom-Cook 4.5-way.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Toom-4.5, the splitting 5x4 unbalanced version.
+ Evaluate in: infinity, +4, -4, +2, -2, +1, -1, 0.
+
+ <--s-><--n--><--n--><--n--><--n-->
+ ____ ______ ______ ______ ______
+ |_a4_|__a3__|__a2__|__a1__|__a0__|
+ |b3_|__b2__|__b1__|__b0__|
+ <-t-><--n--><--n--><--n-->
+
+*/
+#define TOOM_54_MUL_N_REC(p, a, b, n, ws) \
+ do { mpn_mul_n (p, a, b, n); \
+ } while (0)
+
+#define TOOM_54_MUL_REC(p, a, na, b, nb, ws) \
+ do { mpn_mul (p, a, na, b, nb); \
+ } while (0)
+
+void
+mpn_toom54_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn, mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ int sign;
+
+ /***************************** decomposition *******************************/
+#define a4 (ap + 4 * n)
+#define b3 (bp + 3 * n)
+
+ ASSERT (an >= bn);
+ n = 1 + (4 * an >= 5 * bn ? (an - 1) / (size_t) 5 : (bn - 1) / (size_t) 4);
+
+ s = an - 4 * n;
+ t = bn - 3 * n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+ /* Required by mpn_toom_interpolate_8pts. */
+ ASSERT ( s + t >= n );
+ ASSERT ( s + t > 4);
+ ASSERT ( n > 2);
+
+#define r8 pp /* 2n */
+#define r7 scratch /* 3n+1 */
+#define r5 (pp + 3*n) /* 3n+1 */
+#define v0 (pp + 3*n) /* n+1 */
+#define v1 (pp + 4*n+1) /* n+1 */
+#define v2 (pp + 5*n+2) /* n+1 */
+#define v3 (pp + 6*n+3) /* n+1 */
+#define r3 (scratch + 3 * n + 1) /* 3n+1 */
+#define r1 (pp + 7*n) /* s+t <= 2*n */
+#define ws (scratch + 6 * n + 2) /* ??? */
+
+ /* Alloc also 3n+1 limbs for ws... mpn_toom_interpolate_8pts may
+ need all of them, when DO_mpn_sublsh_n usea a scratch */
+ /********************** evaluation and recursive calls *********************/
+ /* $\pm4$ */
+ sign = mpn_toom_eval_pm2exp (v2, v0, 4, ap, n, s, 2, pp)
+ ^ mpn_toom_eval_pm2exp (v3, v1, 3, bp, n, t, 2, pp);
+ TOOM_54_MUL_N_REC(pp, v0, v1, n + 1, ws); /* A(-4)*B(-4) */
+ TOOM_54_MUL_N_REC(r3, v2, v3, n + 1, ws); /* A(+4)*B(+4) */
+ mpn_toom_couple_handling (r3, 2*n+1, pp, sign, n, 2, 4);
+
+ /* $\pm1$ */
+ sign = mpn_toom_eval_pm1 (v2, v0, 4, ap, n, s, pp)
+ ^ mpn_toom_eval_dgr3_pm1 (v3, v1, bp, n, t, pp);
+ TOOM_54_MUL_N_REC(pp, v0, v1, n + 1, ws); /* A(-1)*B(-1) */
+ TOOM_54_MUL_N_REC(r7, v2, v3, n + 1, ws); /* A(1)*B(1) */
+ mpn_toom_couple_handling (r7, 2*n+1, pp, sign, n, 0, 0);
+
+ /* $\pm2$ */
+ sign = mpn_toom_eval_pm2 (v2, v0, 4, ap, n, s, pp)
+ ^ mpn_toom_eval_dgr3_pm2 (v3, v1, bp, n, t, pp);
+ TOOM_54_MUL_N_REC(pp, v0, v1, n + 1, ws); /* A(-2)*B(-2) */
+ TOOM_54_MUL_N_REC(r5, v2, v3, n + 1, ws); /* A(+2)*B(+2) */
+ mpn_toom_couple_handling (r5, 2*n+1, pp, sign, n, 1, 2);
+
+ /* A(0)*B(0) */
+ TOOM_54_MUL_N_REC(pp, ap, bp, n, ws);
+
+ /* Infinity */
+ if (s > t) {
+ TOOM_54_MUL_REC(r1, a4, s, b3, t, ws);
+ } else {
+ TOOM_54_MUL_REC(r1, b3, t, a4, s, ws);
+ };
+
+ mpn_toom_interpolate_8pts (pp, n, r3, r7, s + t, ws);
+
+#undef a4
+#undef b3
+#undef r1
+#undef r3
+#undef r5
+#undef v0
+#undef v1
+#undef v2
+#undef v3
+#undef r7
+#undef r8
+#undef ws
+}
diff --git a/gmp/mpn/generic/toom62_mul.c b/gmp/mpn/generic/toom62_mul.c
new file mode 100644
index 0000000000..3759e3cb3c
--- /dev/null
+++ b/gmp/mpn/generic/toom62_mul.c
@@ -0,0 +1,311 @@
+/* mpn_toom62_mul -- Multiply {ap,an} and {bp,bn} where an is nominally 3 times
+ as large as bn. Or more accurately, (5/2)bn < an < 6bn.
+
+ Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+ The idea of applying toom to unbalanced multiplication is due to Marco
+ Bodrato and Alberto Zanoni.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006-2008, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluate in:
+ 0, +1, -1, +2, -2, 1/2, +inf
+
+ <-s-><--n--><--n--><--n--><--n--><--n-->
+ ___ ______ ______ ______ ______ ______
+ |a5_|___a4_|___a3_|___a2_|___a1_|___a0_|
+ |_b1_|___b0_|
+ <-t--><--n-->
+
+ v0 = a0 * b0 # A(0)*B(0)
+ v1 = ( a0+ a1+ a2+ a3+ a4+ a5)*( b0+ b1) # A(1)*B(1) ah <= 5 bh <= 1
+ vm1 = ( a0- a1+ a2- a3+ a4- a5)*( b0- b1) # A(-1)*B(-1) |ah| <= 2 bh = 0
+ v2 = ( a0+ 2a1+4a2+8a3+16a4+32a5)*( b0+2b1) # A(2)*B(2) ah <= 62 bh <= 2
+ vm2 = ( a0- 2a1+4a2-8a3+16a4-32a5)*( b0-2b1) # A(-2)*B(-2) -41<=ah<=20 -1<=bh<=0
+ vh = (32a0+16a1+8a2+4a3+ 2a4+ a5)*(2b0+ b1) # A(1/2)*B(1/2) ah <= 62 bh <= 2
+ vinf= a5 * b1 # A(inf)*B(inf)
+*/
+
+void
+mpn_toom62_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn,
+ mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ mp_limb_t cy;
+ mp_ptr as1, asm1, as2, asm2, ash;
+ mp_ptr bs1, bsm1, bs2, bsm2, bsh;
+ mp_ptr gp;
+ enum toom7_flags aflags, bflags;
+ TMP_DECL;
+
+#define a0 ap
+#define a1 (ap + n)
+#define a2 (ap + 2*n)
+#define a3 (ap + 3*n)
+#define a4 (ap + 4*n)
+#define a5 (ap + 5*n)
+#define b0 bp
+#define b1 (bp + n)
+
+ n = 1 + (an >= 3 * bn ? (an - 1) / (size_t) 6 : (bn - 1) >> 1);
+
+ s = an - 5 * n;
+ t = bn - n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+
+ TMP_MARK;
+
+ as1 = TMP_SALLOC_LIMBS (n + 1);
+ asm1 = TMP_SALLOC_LIMBS (n + 1);
+ as2 = TMP_SALLOC_LIMBS (n + 1);
+ asm2 = TMP_SALLOC_LIMBS (n + 1);
+ ash = TMP_SALLOC_LIMBS (n + 1);
+
+ bs1 = TMP_SALLOC_LIMBS (n + 1);
+ bsm1 = TMP_SALLOC_LIMBS (n);
+ bs2 = TMP_SALLOC_LIMBS (n + 1);
+ bsm2 = TMP_SALLOC_LIMBS (n + 1);
+ bsh = TMP_SALLOC_LIMBS (n + 1);
+
+ gp = pp;
+
+ /* Compute as1 and asm1. */
+ aflags = (enum toom7_flags) (toom7_w3_neg & mpn_toom_eval_pm1 (as1, asm1, 5, ap, n, s, gp));
+
+ /* Compute as2 and asm2. */
+ aflags = (enum toom7_flags) (aflags | toom7_w1_neg & mpn_toom_eval_pm2 (as2, asm2, 5, ap, n, s, gp));
+
+ /* Compute ash = 32 a0 + 16 a1 + 8 a2 + 4 a3 + 2 a4 + a5
+ = 2*(2*(2*(2*(2*a0 + a1) + a2) + a3) + a4) + a5 */
+
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (ash, a1, a0, n);
+ cy = 2*cy + mpn_addlsh1_n (ash, a2, ash, n);
+ cy = 2*cy + mpn_addlsh1_n (ash, a3, ash, n);
+ cy = 2*cy + mpn_addlsh1_n (ash, a4, ash, n);
+ if (s < n)
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_addlsh1_n (ash, a5, ash, s);
+ ash[n] = 2*cy + mpn_lshift (ash + s, ash + s, n - s, 1);
+ MPN_INCR_U (ash + s, n+1-s, cy2);
+ }
+ else
+ ash[n] = 2*cy + mpn_addlsh1_n (ash, a5, ash, n);
+#else
+ cy = mpn_lshift (ash, a0, n, 1);
+ cy += mpn_add_n (ash, ash, a1, n);
+ cy = 2*cy + mpn_lshift (ash, ash, n, 1);
+ cy += mpn_add_n (ash, ash, a2, n);
+ cy = 2*cy + mpn_lshift (ash, ash, n, 1);
+ cy += mpn_add_n (ash, ash, a3, n);
+ cy = 2*cy + mpn_lshift (ash, ash, n, 1);
+ cy += mpn_add_n (ash, ash, a4, n);
+ cy = 2*cy + mpn_lshift (ash, ash, n, 1);
+ ash[n] = cy + mpn_add (ash, ash, n, a5, s);
+#endif
+
+ /* Compute bs1 and bsm1. */
+ if (t == n)
+ {
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (mpn_cmp (b0, b1, n) < 0)
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, b1, b0, n);
+ bflags = toom7_w3_neg;
+ }
+ else
+ {
+ cy = mpn_add_n_sub_n (bs1, bsm1, b0, b1, n);
+ bflags = (enum toom7_flags) 0;
+ }
+ bs1[n] = cy >> 1;
+#else
+ bs1[n] = mpn_add_n (bs1, b0, b1, n);
+ if (mpn_cmp (b0, b1, n) < 0)
+ {
+ mpn_sub_n (bsm1, b1, b0, n);
+ bflags = toom7_w3_neg;
+ }
+ else
+ {
+ mpn_sub_n (bsm1, b0, b1, n);
+ bflags = (enum toom7_flags) 0;
+ }
+#endif
+ }
+ else
+ {
+ bs1[n] = mpn_add (bs1, b0, n, b1, t);
+ if (mpn_zero_p (b0 + t, n - t) && mpn_cmp (b0, b1, t) < 0)
+ {
+ mpn_sub_n (bsm1, b1, b0, t);
+ MPN_ZERO (bsm1 + t, n - t);
+ bflags = toom7_w3_neg;
+ }
+ else
+ {
+ mpn_sub (bsm1, b0, n, b1, t);
+ bflags = (enum toom7_flags) 0;
+ }
+ }
+
+ /* Compute bs2 and bsm2. Recycling bs1 and bsm1; bs2=bs1+b1, bsm2 =
+ bsm1 - b1 */
+ mpn_add (bs2, bs1, n + 1, b1, t);
+ if (bflags & toom7_w3_neg)
+ {
+ bsm2[n] = mpn_add (bsm2, bsm1, n, b1, t);
+ bflags = (enum toom7_flags) (bflags | toom7_w1_neg);
+ }
+ else
+ {
+ /* FIXME: Simplify this logic? */
+ if (t < n)
+ {
+ if (mpn_zero_p (bsm1 + t, n - t) && mpn_cmp (bsm1, b1, t) < 0)
+ {
+ ASSERT_NOCARRY (mpn_sub_n (bsm2, b1, bsm1, t));
+ MPN_ZERO (bsm2 + t, n + 1 - t);
+ bflags = (enum toom7_flags) (bflags | toom7_w1_neg);
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_sub (bsm2, bsm1, n, b1, t));
+ bsm2[n] = 0;
+ }
+ }
+ else
+ {
+ if (mpn_cmp (bsm1, b1, n) < 0)
+ {
+ ASSERT_NOCARRY (mpn_sub_n (bsm2, b1, bsm1, n));
+ bflags = (enum toom7_flags) (bflags | toom7_w1_neg);
+ }
+ else
+ {
+ ASSERT_NOCARRY (mpn_sub_n (bsm2, bsm1, b1, n));
+ }
+ bsm2[n] = 0;
+ }
+ }
+
+ /* Compute bsh, recycling bs1. bsh=bs1+b0; */
+ bsh[n] = bs1[n] + mpn_add_n (bsh, bs1, b0, n);
+
+ ASSERT (as1[n] <= 5);
+ ASSERT (bs1[n] <= 1);
+ ASSERT (asm1[n] <= 2);
+ ASSERT (as2[n] <= 62);
+ ASSERT (bs2[n] <= 2);
+ ASSERT (asm2[n] <= 41);
+ ASSERT (bsm2[n] <= 1);
+ ASSERT (ash[n] <= 62);
+ ASSERT (bsh[n] <= 2);
+
+#define v0 pp /* 2n */
+#define v1 (pp + 2 * n) /* 2n+1 */
+#define vinf (pp + 6 * n) /* s+t */
+#define v2 scratch /* 2n+1 */
+#define vm2 (scratch + 2 * n + 1) /* 2n+1 */
+#define vh (scratch + 4 * n + 2) /* 2n+1 */
+#define vm1 (scratch + 6 * n + 3) /* 2n+1 */
+#define scratch_out (scratch + 8 * n + 4) /* 2n+1 */
+ /* Total scratch need: 10*n+5 */
+
+ /* Must be in allocation order, as they overwrite one limb beyond
+ * 2n+1. */
+ mpn_mul_n (v2, as2, bs2, n + 1); /* v2, 2n+1 limbs */
+ mpn_mul_n (vm2, asm2, bsm2, n + 1); /* vm2, 2n+1 limbs */
+ mpn_mul_n (vh, ash, bsh, n + 1); /* vh, 2n+1 limbs */
+
+ /* vm1, 2n+1 limbs */
+ mpn_mul_n (vm1, asm1, bsm1, n);
+ cy = 0;
+ if (asm1[n] == 1)
+ {
+ cy = mpn_add_n (vm1 + n, vm1 + n, bsm1, n);
+ }
+ else if (asm1[n] == 2)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = mpn_addlsh1_n (vm1 + n, vm1 + n, bsm1, n);
+#else
+ cy = mpn_addmul_1 (vm1 + n, bsm1, n, CNST_LIMB(2));
+#endif
+ }
+ vm1[2 * n] = cy;
+
+ /* v1, 2n+1 limbs */
+ mpn_mul_n (v1, as1, bs1, n);
+ if (as1[n] == 1)
+ {
+ cy = bs1[n] + mpn_add_n (v1 + n, v1 + n, bs1, n);
+ }
+ else if (as1[n] == 2)
+ {
+#if HAVE_NATIVE_mpn_addlsh1_n
+ cy = 2 * bs1[n] + mpn_addlsh1_n (v1 + n, v1 + n, bs1, n);
+#else
+ cy = 2 * bs1[n] + mpn_addmul_1 (v1 + n, bs1, n, CNST_LIMB(2));
+#endif
+ }
+ else if (as1[n] != 0)
+ {
+ cy = as1[n] * bs1[n] + mpn_addmul_1 (v1 + n, bs1, n, as1[n]);
+ }
+ else
+ cy = 0;
+ if (bs1[n] != 0)
+ cy += mpn_add_n (v1 + n, v1 + n, as1, n);
+ v1[2 * n] = cy;
+
+ mpn_mul_n (v0, a0, b0, n); /* v0, 2n limbs */
+
+ /* vinf, s+t limbs */
+ if (s > t) mpn_mul (vinf, a5, s, b1, t);
+ else mpn_mul (vinf, b1, t, a5, s);
+
+ mpn_toom_interpolate_7pts (pp, n, (enum toom7_flags) (aflags ^ bflags),
+ vm2, vm1, v2, vh, s + t, scratch_out);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpn/generic/toom63_mul.c b/gmp/mpn/generic/toom63_mul.c
new file mode 100644
index 0000000000..57c5d3e3dd
--- /dev/null
+++ b/gmp/mpn/generic/toom63_mul.c
@@ -0,0 +1,232 @@
+/* Implementation of the algorithm for Toom-Cook 4.5-way.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Stores |{ap,n}-{bp,n}| in {rp,n}, returns the sign. */
+static int
+abs_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
+{
+ mp_limb_t x, y;
+ while (--n >= 0)
+ {
+ x = ap[n];
+ y = bp[n];
+ if (x != y)
+ {
+ n++;
+ if (x > y)
+ {
+ mpn_sub_n (rp, ap, bp, n);
+ return 0;
+ }
+ else
+ {
+ mpn_sub_n (rp, bp, ap, n);
+ return ~0;
+ }
+ }
+ rp[n] = 0;
+ }
+ return 0;
+}
+
+static int
+abs_sub_add_n (mp_ptr rm, mp_ptr rp, mp_srcptr rs, mp_size_t n) {
+ int result;
+ result = abs_sub_n (rm, rp, rs, n);
+ ASSERT_NOCARRY(mpn_add_n (rp, rp, rs, n));
+ return result;
+}
+
+
+/* Toom-4.5, the splitting 6x3 unbalanced version.
+ Evaluate in: infinity, +4, -4, +2, -2, +1, -1, 0.
+
+ <--s-><--n--><--n--><--n--><--n--><--n-->
+ ____ ______ ______ ______ ______ ______
+ |_a5_|__a4__|__a3__|__a2__|__a1__|__a0__|
+ |b2_|__b1__|__b0__|
+ <-t-><--n--><--n-->
+
+*/
+#define TOOM_63_MUL_N_REC(p, a, b, n, ws) \
+ do { mpn_mul_n (p, a, b, n); \
+ } while (0)
+
+#define TOOM_63_MUL_REC(p, a, na, b, nb, ws) \
+ do { mpn_mul (p, a, na, b, nb); \
+ } while (0)
+
+void
+mpn_toom63_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn, mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ mp_limb_t cy;
+ int sign;
+
+ /***************************** decomposition *******************************/
+#define a5 (ap + 5 * n)
+#define b0 (bp + 0 * n)
+#define b1 (bp + 1 * n)
+#define b2 (bp + 2 * n)
+
+ ASSERT (an >= bn);
+ n = 1 + (an >= 2 * bn ? (an - 1) / (size_t) 6 : (bn - 1) / (size_t) 3);
+
+ s = an - 5 * n;
+ t = bn - 2 * n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+ /* WARNING! it assumes s+t>=n */
+ ASSERT ( s + t >= n );
+ ASSERT ( s + t > 4);
+ /* WARNING! it assumes n>1 */
+ ASSERT ( n > 2);
+
+#define r8 pp /* 2n */
+#define r7 scratch /* 3n+1 */
+#define r5 (pp + 3*n) /* 3n+1 */
+#define v0 (pp + 3*n) /* n+1 */
+#define v1 (pp + 4*n+1) /* n+1 */
+#define v2 (pp + 5*n+2) /* n+1 */
+#define v3 (pp + 6*n+3) /* n+1 */
+#define r3 (scratch + 3 * n + 1) /* 3n+1 */
+#define r1 (pp + 7*n) /* s+t <= 2*n */
+#define ws (scratch + 6 * n + 2) /* ??? */
+
+ /* Alloc also 3n+1 limbs for ws... mpn_toom_interpolate_8pts may
+ need all of them, when DO_mpn_sublsh_n usea a scratch */
+/* if (scratch == NULL) scratch = TMP_SALLOC_LIMBS (9 * n + 3); */
+
+ /********************** evaluation and recursive calls *********************/
+ /* $\pm4$ */
+ sign = mpn_toom_eval_pm2exp (v2, v0, 5, ap, n, s, 2, pp);
+ pp[n] = mpn_lshift (pp, b1, n, 2); /* 4b1 */
+ /* FIXME: use addlsh */
+ v3[t] = mpn_lshift (v3, b2, t, 4);/* 16b2 */
+ if ( n == t )
+ v3[n]+= mpn_add_n (v3, v3, b0, n); /* 16b2+b0 */
+ else
+ v3[n] = mpn_add (v3, b0, n, v3, t+1); /* 16b2+b0 */
+ sign ^= abs_sub_add_n (v1, v3, pp, n + 1);
+ TOOM_63_MUL_N_REC(pp, v0, v1, n + 1, ws); /* A(-4)*B(-4) */
+ TOOM_63_MUL_N_REC(r3, v2, v3, n + 1, ws); /* A(+4)*B(+4) */
+ mpn_toom_couple_handling (r3, 2*n+1, pp, sign, n, 2, 4);
+
+ /* $\pm1$ */
+ sign = mpn_toom_eval_pm1 (v2, v0, 5, ap, n, s, pp);
+ /* Compute bs1 and bsm1. Code taken from toom33 */
+ cy = mpn_add (ws, b0, n, b2, t);
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (cy == 0 && mpn_cmp (ws, b1, n) < 0)
+ {
+ cy = mpn_add_n_sub_n (v3, v1, b1, ws, n);
+ v3[n] = cy >> 1;
+ v1[n] = 0;
+ sign = ~sign;
+ }
+ else
+ {
+ mp_limb_t cy2;
+ cy2 = mpn_add_n_sub_n (v3, v1, ws, b1, n);
+ v3[n] = cy + (cy2 >> 1);
+ v1[n] = cy - (cy2 & 1);
+ }
+#else
+ v3[n] = cy + mpn_add_n (v3, ws, b1, n);
+ if (cy == 0 && mpn_cmp (ws, b1, n) < 0)
+ {
+ mpn_sub_n (v1, b1, ws, n);
+ v1[n] = 0;
+ sign = ~sign;
+ }
+ else
+ {
+ cy -= mpn_sub_n (v1, ws, b1, n);
+ v1[n] = cy;
+ }
+#endif
+ TOOM_63_MUL_N_REC(pp, v0, v1, n + 1, ws); /* A(-1)*B(-1) */
+ TOOM_63_MUL_N_REC(r7, v2, v3, n + 1, ws); /* A(1)*B(1) */
+ mpn_toom_couple_handling (r7, 2*n+1, pp, sign, n, 0, 0);
+
+ /* $\pm2$ */
+ sign = mpn_toom_eval_pm2 (v2, v0, 5, ap, n, s, pp);
+ pp[n] = mpn_lshift (pp, b1, n, 1); /* 2b1 */
+ /* FIXME: use addlsh or addlsh2 */
+ v3[t] = mpn_lshift (v3, b2, t, 2);/* 4b2 */
+ if ( n == t )
+ v3[n]+= mpn_add_n (v3, v3, b0, n); /* 4b2+b0 */
+ else
+ v3[n] = mpn_add (v3, b0, n, v3, t+1); /* 4b2+b0 */
+ sign ^= abs_sub_add_n (v1, v3, pp, n + 1);
+ TOOM_63_MUL_N_REC(pp, v0, v1, n + 1, ws); /* A(-2)*B(-2) */
+ TOOM_63_MUL_N_REC(r5, v2, v3, n + 1, ws); /* A(+2)*B(+2) */
+ mpn_toom_couple_handling (r5, 2*n+1, pp, sign, n, 1, 2);
+
+ /* A(0)*B(0) */
+ TOOM_63_MUL_N_REC(pp, ap, bp, n, ws);
+
+ /* Infinity */
+ if (s > t) {
+ TOOM_63_MUL_REC(r1, a5, s, b2, t, ws);
+ } else {
+ TOOM_63_MUL_REC(r1, b2, t, a5, s, ws);
+ };
+
+ mpn_toom_interpolate_8pts (pp, n, r3, r7, s + t, ws);
+
+#undef a5
+#undef b0
+#undef b1
+#undef b2
+#undef r1
+#undef r3
+#undef r5
+#undef v0
+#undef v1
+#undef v2
+#undef v3
+#undef r7
+#undef r8
+#undef ws
+}
diff --git a/gmp/mpn/generic/toom6_sqr.c b/gmp/mpn/generic/toom6_sqr.c
new file mode 100644
index 0000000000..e5ab7dcd1d
--- /dev/null
+++ b/gmp/mpn/generic/toom6_sqr.c
@@ -0,0 +1,182 @@
+/* Implementation of the squaring algorithm with Toom-Cook 6.5-way.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#if GMP_NUMB_BITS < 21
+#error Not implemented.
+#endif
+
+
+#if TUNE_PROGRAM_BUILD
+#define MAYBE_sqr_basecase 1
+#define MAYBE_sqr_above_basecase 1
+#define MAYBE_sqr_toom2 1
+#define MAYBE_sqr_above_toom2 1
+#define MAYBE_sqr_toom3 1
+#define MAYBE_sqr_above_toom3 1
+#define MAYBE_sqr_above_toom4 1
+#else
+#ifdef SQR_TOOM8_THRESHOLD
+#define SQR_TOOM6_MAX ((SQR_TOOM8_THRESHOLD+6*2-1+5)/6)
+#else
+#define SQR_TOOM6_MAX \
+ ((SQR_FFT_THRESHOLD <= MP_SIZE_T_MAX - (6*2-1+5)) ? \
+ ((SQR_FFT_THRESHOLD+6*2-1+5)/6) \
+ : MP_SIZE_T_MAX )
+#endif
+#define MAYBE_sqr_basecase \
+ (SQR_TOOM6_THRESHOLD < 6 * SQR_TOOM2_THRESHOLD)
+#define MAYBE_sqr_above_basecase \
+ (SQR_TOOM6_MAX >= SQR_TOOM2_THRESHOLD)
+#define MAYBE_sqr_toom2 \
+ (SQR_TOOM6_THRESHOLD < 6 * SQR_TOOM3_THRESHOLD)
+#define MAYBE_sqr_above_toom2 \
+ (SQR_TOOM6_MAX >= SQR_TOOM3_THRESHOLD)
+#define MAYBE_sqr_toom3 \
+ (SQR_TOOM6_THRESHOLD < 6 * SQR_TOOM4_THRESHOLD)
+#define MAYBE_sqr_above_toom3 \
+ (SQR_TOOM6_MAX >= SQR_TOOM4_THRESHOLD)
+#define MAYBE_sqr_above_toom4 \
+ (SQR_TOOM6_MAX >= SQR_TOOM6_THRESHOLD)
+#endif
+
+#define TOOM6_SQR_REC(p, a, n, ws) \
+ do { \
+ if (MAYBE_sqr_basecase && ( !MAYBE_sqr_above_basecase \
+ || BELOW_THRESHOLD (n, SQR_TOOM2_THRESHOLD))) \
+ mpn_sqr_basecase (p, a, n); \
+ else if (MAYBE_sqr_toom2 && ( !MAYBE_sqr_above_toom2 \
+ || BELOW_THRESHOLD (n, SQR_TOOM3_THRESHOLD))) \
+ mpn_toom2_sqr (p, a, n, ws); \
+ else if (MAYBE_sqr_toom3 && ( !MAYBE_sqr_above_toom3 \
+ || BELOW_THRESHOLD (n, SQR_TOOM4_THRESHOLD))) \
+ mpn_toom3_sqr (p, a, n, ws); \
+ else if (! MAYBE_sqr_above_toom4 \
+ || BELOW_THRESHOLD (n, SQR_TOOM6_THRESHOLD)) \
+ mpn_toom4_sqr (p, a, n, ws); \
+ else \
+ mpn_toom6_sqr (p, a, n, ws); \
+ } while (0)
+
+void
+mpn_toom6_sqr (mp_ptr pp, mp_srcptr ap, mp_size_t an, mp_ptr scratch)
+{
+ mp_size_t n, s;
+
+ /***************************** decomposition *******************************/
+
+ ASSERT( an >= 18 );
+
+ n = 1 + (an - 1) / (size_t) 6;
+
+ s = an - 5 * n;
+
+ ASSERT (0 < s && s <= n);
+
+#define r4 (pp + 3 * n) /* 3n+1 */
+#define r2 (pp + 7 * n) /* 3n+1 */
+#define r0 (pp +11 * n) /* s+t <= 2*n */
+#define r5 (scratch) /* 3n+1 */
+#define r3 (scratch + 3 * n + 1) /* 3n+1 */
+#define r1 (scratch + 6 * n + 2) /* 3n+1 */
+#define v0 (pp + 7 * n) /* n+1 */
+#define v2 (pp + 9 * n+2) /* n+1 */
+#define wse (scratch + 9 * n + 3) /* 3n+1 */
+
+ /* Alloc also 3n+1 limbs for ws... toom_interpolate_12pts may
+ need all of them, when DO_mpn_sublsh_n usea a scratch */
+/* if (scratch== NULL) */
+/* scratch = TMP_SALLOC_LIMBS (12 * n + 6); */
+
+ /********************** evaluation and recursive calls *********************/
+ /* $\pm1/2$ */
+ mpn_toom_eval_pm2rexp (v2, v0, 5, ap, n, s, 1, pp);
+ TOOM6_SQR_REC(pp, v0, n + 1, wse); /* A(-1/2)*B(-1/2)*2^. */
+ TOOM6_SQR_REC(r5, v2, n + 1, wse); /* A(+1/2)*B(+1/2)*2^. */
+ mpn_toom_couple_handling (r5, 2 * n + 1, pp, 0, n, 1, 0);
+
+ /* $\pm1$ */
+ mpn_toom_eval_pm1 (v2, v0, 5, ap, n, s, pp);
+ TOOM6_SQR_REC(pp, v0, n + 1, wse); /* A(-1)*B(-1) */
+ TOOM6_SQR_REC(r3, v2, n + 1, wse); /* A(1)*B(1) */
+ mpn_toom_couple_handling (r3, 2 * n + 1, pp, 0, n, 0, 0);
+
+ /* $\pm4$ */
+ mpn_toom_eval_pm2exp (v2, v0, 5, ap, n, s, 2, pp);
+ TOOM6_SQR_REC(pp, v0, n + 1, wse); /* A(-4)*B(-4) */
+ TOOM6_SQR_REC(r1, v2, n + 1, wse); /* A(+4)*B(+4) */
+ mpn_toom_couple_handling (r1, 2 * n + 1, pp, 0, n, 2, 4);
+
+ /* $\pm1/4$ */
+ mpn_toom_eval_pm2rexp (v2, v0, 5, ap, n, s, 2, pp);
+ TOOM6_SQR_REC(pp, v0, n + 1, wse); /* A(-1/4)*B(-1/4)*4^. */
+ TOOM6_SQR_REC(r4, v2, n + 1, wse); /* A(+1/4)*B(+1/4)*4^. */
+ mpn_toom_couple_handling (r4, 2 * n + 1, pp, 0, n, 2, 0);
+
+ /* $\pm2$ */
+ mpn_toom_eval_pm2 (v2, v0, 5, ap, n, s, pp);
+ TOOM6_SQR_REC(pp, v0, n + 1, wse); /* A(-2)*B(-2) */
+ TOOM6_SQR_REC(r2, v2, n + 1, wse); /* A(+2)*B(+2) */
+ mpn_toom_couple_handling (r2, 2 * n + 1, pp, 0, n, 1, 2);
+
+#undef v0
+#undef v2
+
+ /* A(0)*B(0) */
+ TOOM6_SQR_REC(pp, ap, n, wse);
+
+ mpn_toom_interpolate_12pts (pp, r1, r3, r5, n, 2 * s, 0, wse);
+
+#undef r0
+#undef r1
+#undef r2
+#undef r3
+#undef r4
+#undef r5
+
+}
+#undef TOOM6_SQR_REC
+#undef MAYBE_sqr_basecase
+#undef MAYBE_sqr_above_basecase
+#undef MAYBE_sqr_toom2
+#undef MAYBE_sqr_above_toom2
+#undef MAYBE_sqr_toom3
+#undef MAYBE_sqr_above_toom3
+#undef MAYBE_sqr_above_toom4
diff --git a/gmp/mpn/generic/toom6h_mul.c b/gmp/mpn/generic/toom6h_mul.c
new file mode 100644
index 0000000000..420895be8f
--- /dev/null
+++ b/gmp/mpn/generic/toom6h_mul.c
@@ -0,0 +1,263 @@
+/* Implementation of the multiplication algorithm for Toom-Cook 6.5-way.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#if GMP_NUMB_BITS < 21
+#error Not implemented.
+#endif
+
+#if TUNE_PROGRAM_BUILD
+#define MAYBE_mul_basecase 1
+#define MAYBE_mul_toom22 1
+#define MAYBE_mul_toom33 1
+#define MAYBE_mul_toom6h 1
+#else
+#define MAYBE_mul_basecase \
+ (MUL_TOOM6H_THRESHOLD < 6 * MUL_TOOM22_THRESHOLD)
+#define MAYBE_mul_toom22 \
+ (MUL_TOOM6H_THRESHOLD < 6 * MUL_TOOM33_THRESHOLD)
+#define MAYBE_mul_toom33 \
+ (MUL_TOOM6H_THRESHOLD < 6 * MUL_TOOM44_THRESHOLD)
+#define MAYBE_mul_toom6h \
+ (MUL_FFT_THRESHOLD >= 6 * MUL_TOOM6H_THRESHOLD)
+#endif
+
+#define TOOM6H_MUL_N_REC(p, a, b, f, p2, a2, b2, n, ws) \
+ do { \
+ if (MAYBE_mul_basecase \
+ && BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD)) { \
+ mpn_mul_basecase (p, a, n, b, n); \
+ if (f) \
+ mpn_mul_basecase (p2, a2, n, b2, n); \
+ } else if (MAYBE_mul_toom22 \
+ && BELOW_THRESHOLD (n, MUL_TOOM33_THRESHOLD)) { \
+ mpn_toom22_mul (p, a, n, b, n, ws); \
+ if (f) \
+ mpn_toom22_mul (p2, a2, n, b2, n, ws); \
+ } else if (MAYBE_mul_toom33 \
+ && BELOW_THRESHOLD (n, MUL_TOOM44_THRESHOLD)) { \
+ mpn_toom33_mul (p, a, n, b, n, ws); \
+ if (f) \
+ mpn_toom33_mul (p2, a2, n, b2, n, ws); \
+ } else if (! MAYBE_mul_toom6h \
+ || BELOW_THRESHOLD (n, MUL_TOOM6H_THRESHOLD)) { \
+ mpn_toom44_mul (p, a, n, b, n, ws); \
+ if (f) \
+ mpn_toom44_mul (p2, a2, n, b2, n, ws); \
+ } else { \
+ mpn_toom6h_mul (p, a, n, b, n, ws); \
+ if (f) \
+ mpn_toom6h_mul (p2, a2, n, b2, n, ws); \
+ } \
+ } while (0)
+
+#define TOOM6H_MUL_REC(p, a, na, b, nb, ws) \
+ do { mpn_mul (p, a, na, b, nb); \
+ } while (0)
+
+/* Toom-6.5 , compute the product {pp,an+bn} <- {ap,an} * {bp,bn}
+ With: an >= bn >= 46, an*6 < bn * 17.
+ It _may_ work with bn<=46 and bn*17 < an*6 < bn*18
+
+ Evaluate in: infinity, +4, -4, +2, -2, +1, -1, +1/2, -1/2, +1/4, -1/4, 0.
+*/
+/* Estimate on needed scratch:
+ S(n) <= (n+5)\6*10+4+MAX(S((n+5)\6),1+2*(n+5)\6),
+ since n>42; S(n) <= ceil(log(n)/log(6))*(10+4)+n*12\6 < n*2 + lg2(n)*6
+ */
+
+void
+mpn_toom6h_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn, mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ int p, q, half;
+ int sign;
+
+ /***************************** decomposition *******************************/
+
+ ASSERT (an >= bn);
+ /* Can not handle too much unbalancement */
+ ASSERT (bn >= 42);
+ /* Can not handle too much unbalancement */
+ ASSERT ((an*3 < bn * 8) || (bn >= 46 && an * 6 < bn * 17));
+
+ /* Limit num/den is a rational number between
+ (12/11)^(log(4)/log(2*4-1)) and (12/11)^(log(6)/log(2*6-1)) */
+#define LIMIT_numerator (18)
+#define LIMIT_denominat (17)
+
+ if (LIKELY (an * LIMIT_denominat < LIMIT_numerator * bn)) /* is 6*... < 6*... */
+ {
+ n = 1 + (an - 1) / (size_t) 6;
+ p = q = 5;
+ half = 0;
+
+ s = an - 5 * n;
+ t = bn - 5 * n;
+ }
+ else {
+ if (an * 5 * LIMIT_numerator < LIMIT_denominat * 7 * bn)
+ { p = 7; q = 6; }
+ else if (an * 5 * LIMIT_denominat < LIMIT_numerator * 7 * bn)
+ { p = 7; q = 5; }
+ else if (an * LIMIT_numerator < LIMIT_denominat * 2 * bn) /* is 4*... < 8*... */
+ { p = 8; q = 5; }
+ else if (an * LIMIT_denominat < LIMIT_numerator * 2 * bn) /* is 4*... < 8*... */
+ { p = 8; q = 4; }
+ else
+ { p = 9; q = 4; }
+
+ half = (p ^ q) & 1;
+ n = 1 + (q * an >= p * bn ? (an - 1) / (size_t) p : (bn - 1) / (size_t) q);
+ p--; q--;
+
+ s = an - p * n;
+ t = bn - q * n;
+
+ /* With LIMIT = 16/15, the following recover is needed only if bn<=73*/
+ if (half) { /* Recover from badly chosen splitting */
+ if (UNLIKELY (s<1)) {p--; s+=n; half=0;}
+ else if (UNLIKELY (t<1)) {q--; t+=n; half=0;}
+ }
+ }
+#undef LIMIT_numerator
+#undef LIMIT_denominat
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+ ASSERT (half || s + t > 3);
+ ASSERT (n > 2);
+
+#define r4 (pp + 3 * n) /* 3n+1 */
+#define r2 (pp + 7 * n) /* 3n+1 */
+#define r0 (pp +11 * n) /* s+t <= 2*n */
+#define r5 (scratch) /* 3n+1 */
+#define r3 (scratch + 3 * n + 1) /* 3n+1 */
+#define r1 (scratch + 6 * n + 2) /* 3n+1 */
+#define v0 (pp + 7 * n) /* n+1 */
+#define v1 (pp + 8 * n+1) /* n+1 */
+#define v2 (pp + 9 * n+2) /* n+1 */
+#define v3 (scratch + 9 * n + 3) /* n+1 */
+#define wsi (scratch + 9 * n + 3) /* 3n+1 */
+#define wse (scratch +10 * n + 4) /* 2n+1 */
+
+ /* Alloc also 3n+1 limbs for wsi... toom_interpolate_12pts may
+ need all of them */
+/* if (scratch == NULL) */
+/* scratch = TMP_SALLOC_LIMBS(mpn_toom6_sqr_itch(n * 6)); */
+ ASSERT (12 * n + 6 <= mpn_toom6h_mul_itch(an,bn));
+ ASSERT (12 * n + 6 <= mpn_toom6_sqr_itch(n * 6));
+
+ /********************** evaluation and recursive calls *********************/
+ /* $\pm1/2$ */
+ sign = mpn_toom_eval_pm2rexp (v2, v0, p, ap, n, s, 1, pp) ^
+ mpn_toom_eval_pm2rexp (v3, v1, q, bp, n, t, 1, pp);
+ /* A(-1/2)*B(-1/2)*2^. */ /* A(+1/2)*B(+1/2)*2^. */
+ TOOM6H_MUL_N_REC(pp, v0, v1, 2, r5, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r5, 2 * n + 1, pp, sign, n, 1+half , half);
+
+ /* $\pm1$ */
+ sign = mpn_toom_eval_pm1 (v2, v0, p, ap, n, s, pp);
+ if (UNLIKELY (q == 3))
+ sign ^= mpn_toom_eval_dgr3_pm1 (v3, v1, bp, n, t, pp);
+ else
+ sign ^= mpn_toom_eval_pm1 (v3, v1, q, bp, n, t, pp);
+ /* A(-1)*B(-1) */ /* A(1)*B(1) */
+ TOOM6H_MUL_N_REC(pp, v0, v1, 2, r3, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r3, 2 * n + 1, pp, sign, n, 0, 0);
+
+ /* $\pm4$ */
+ sign = mpn_toom_eval_pm2exp (v2, v0, p, ap, n, s, 2, pp) ^
+ mpn_toom_eval_pm2exp (v3, v1, q, bp, n, t, 2, pp);
+ /* A(-4)*B(-4) */
+ TOOM6H_MUL_N_REC(pp, v0, v1, 2, r1, v2, v3, n + 1, wse); /* A(+4)*B(+4) */
+ mpn_toom_couple_handling (r1, 2 * n + 1, pp, sign, n, 2, 4);
+
+ /* $\pm1/4$ */
+ sign = mpn_toom_eval_pm2rexp (v2, v0, p, ap, n, s, 2, pp) ^
+ mpn_toom_eval_pm2rexp (v3, v1, q, bp, n, t, 2, pp);
+ /* A(-1/4)*B(-1/4)*4^. */ /* A(+1/4)*B(+1/4)*4^. */
+ TOOM6H_MUL_N_REC(pp, v0, v1, 2, r4, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r4, 2 * n + 1, pp, sign, n, 2*(1+half), 2*(half));
+
+ /* $\pm2$ */
+ sign = mpn_toom_eval_pm2 (v2, v0, p, ap, n, s, pp) ^
+ mpn_toom_eval_pm2 (v3, v1, q, bp, n, t, pp);
+ /* A(-2)*B(-2) */ /* A(+2)*B(+2) */
+ TOOM6H_MUL_N_REC(pp, v0, v1, 2, r2, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r2, 2 * n + 1, pp, sign, n, 1, 2);
+
+#undef v0
+#undef v1
+#undef v2
+#undef v3
+#undef wse
+
+ /* A(0)*B(0) */
+ TOOM6H_MUL_N_REC(pp, ap, bp, 0, pp, ap, bp, n, wsi);
+
+ /* Infinity */
+ if (UNLIKELY (half != 0)) {
+ if (s > t) {
+ TOOM6H_MUL_REC(r0, ap + p * n, s, bp + q * n, t, wsi);
+ } else {
+ TOOM6H_MUL_REC(r0, bp + q * n, t, ap + p * n, s, wsi);
+ };
+ };
+
+ mpn_toom_interpolate_12pts (pp, r1, r3, r5, n, s+t, half, wsi);
+
+#undef r0
+#undef r1
+#undef r2
+#undef r3
+#undef r4
+#undef r5
+#undef wsi
+}
+
+#undef TOOM6H_MUL_N_REC
+#undef TOOM6H_MUL_REC
+#undef MAYBE_mul_basecase
+#undef MAYBE_mul_toom22
+#undef MAYBE_mul_toom33
+#undef MAYBE_mul_toom6h
diff --git a/gmp/mpn/generic/toom8_sqr.c b/gmp/mpn/generic/toom8_sqr.c
new file mode 100644
index 0000000000..0c93678815
--- /dev/null
+++ b/gmp/mpn/generic/toom8_sqr.c
@@ -0,0 +1,226 @@
+/* Implementation of the squaring algorithm with Toom-Cook 8.5-way.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if GMP_NUMB_BITS < 29
+#error Not implemented.
+#endif
+
+#if GMP_NUMB_BITS < 43
+#define BIT_CORRECTION 1
+#define CORRECTION_BITS GMP_NUMB_BITS
+#else
+#define BIT_CORRECTION 0
+#define CORRECTION_BITS 0
+#endif
+
+#ifndef SQR_TOOM8_THRESHOLD
+#define SQR_TOOM8_THRESHOLD MUL_TOOM8H_THRESHOLD
+#endif
+
+#ifndef SQR_TOOM6_THRESHOLD
+#define SQR_TOOM6_THRESHOLD MUL_TOOM6H_THRESHOLD
+#endif
+
+#if TUNE_PROGRAM_BUILD
+#define MAYBE_sqr_basecase 1
+#define MAYBE_sqr_above_basecase 1
+#define MAYBE_sqr_toom2 1
+#define MAYBE_sqr_above_toom2 1
+#define MAYBE_sqr_toom3 1
+#define MAYBE_sqr_above_toom3 1
+#define MAYBE_sqr_toom4 1
+#define MAYBE_sqr_above_toom4 1
+#define MAYBE_sqr_above_toom6 1
+#else
+#define SQR_TOOM8_MAX \
+ ((SQR_FFT_THRESHOLD <= MP_SIZE_T_MAX - (8*2-1+7)) ? \
+ ((SQR_FFT_THRESHOLD+8*2-1+7)/8) \
+ : MP_SIZE_T_MAX )
+#define MAYBE_sqr_basecase \
+ (SQR_TOOM8_THRESHOLD < 8 * SQR_TOOM2_THRESHOLD)
+#define MAYBE_sqr_above_basecase \
+ (SQR_TOOM8_MAX >= SQR_TOOM2_THRESHOLD)
+#define MAYBE_sqr_toom2 \
+ (SQR_TOOM8_THRESHOLD < 8 * SQR_TOOM3_THRESHOLD)
+#define MAYBE_sqr_above_toom2 \
+ (SQR_TOOM8_MAX >= SQR_TOOM3_THRESHOLD)
+#define MAYBE_sqr_toom3 \
+ (SQR_TOOM8_THRESHOLD < 8 * SQR_TOOM4_THRESHOLD)
+#define MAYBE_sqr_above_toom3 \
+ (SQR_TOOM8_MAX >= SQR_TOOM4_THRESHOLD)
+#define MAYBE_sqr_toom4 \
+ (SQR_TOOM8_THRESHOLD < 8 * SQR_TOOM6_THRESHOLD)
+#define MAYBE_sqr_above_toom4 \
+ (SQR_TOOM8_MAX >= SQR_TOOM6_THRESHOLD)
+#define MAYBE_sqr_above_toom6 \
+ (SQR_TOOM8_MAX >= SQR_TOOM8_THRESHOLD)
+#endif
+
+#define TOOM8_SQR_REC(p, a, f, p2, a2, n, ws) \
+ do { \
+ if (MAYBE_sqr_basecase && ( !MAYBE_sqr_above_basecase \
+ || BELOW_THRESHOLD (n, SQR_TOOM2_THRESHOLD))) { \
+ mpn_sqr_basecase (p, a, n); \
+ if (f) mpn_sqr_basecase (p2, a2, n); \
+ } else if (MAYBE_sqr_toom2 && ( !MAYBE_sqr_above_toom2 \
+ || BELOW_THRESHOLD (n, SQR_TOOM3_THRESHOLD))) { \
+ mpn_toom2_sqr (p, a, n, ws); \
+ if (f) mpn_toom2_sqr (p2, a2, n, ws); \
+ } else if (MAYBE_sqr_toom3 && ( !MAYBE_sqr_above_toom3 \
+ || BELOW_THRESHOLD (n, SQR_TOOM4_THRESHOLD))) { \
+ mpn_toom3_sqr (p, a, n, ws); \
+ if (f) mpn_toom3_sqr (p2, a2, n, ws); \
+ } else if (MAYBE_sqr_toom4 && ( !MAYBE_sqr_above_toom4 \
+ || BELOW_THRESHOLD (n, SQR_TOOM6_THRESHOLD))) { \
+ mpn_toom4_sqr (p, a, n, ws); \
+ if (f) mpn_toom4_sqr (p2, a2, n, ws); \
+ } else if (! MAYBE_sqr_above_toom6 \
+ || BELOW_THRESHOLD (n, SQR_TOOM8_THRESHOLD)) { \
+ mpn_toom6_sqr (p, a, n, ws); \
+ if (f) mpn_toom6_sqr (p2, a2, n, ws); \
+ } else { \
+ mpn_toom8_sqr (p, a, n, ws); \
+ if (f) mpn_toom8_sqr (p2, a2, n, ws); \
+ } \
+ } while (0)
+
+void
+mpn_toom8_sqr (mp_ptr pp, mp_srcptr ap, mp_size_t an, mp_ptr scratch)
+{
+ mp_size_t n, s;
+
+ /***************************** decomposition *******************************/
+
+ ASSERT ( an >= 40 );
+
+ n = 1 + ((an - 1)>>3);
+
+ s = an - 7 * n;
+
+ ASSERT (0 < s && s <= n);
+ ASSERT ( s + s > 3 );
+
+#define r6 (pp + 3 * n) /* 3n+1 */
+#define r4 (pp + 7 * n) /* 3n+1 */
+#define r2 (pp +11 * n) /* 3n+1 */
+#define r0 (pp +15 * n) /* s+t <= 2*n */
+#define r7 (scratch) /* 3n+1 */
+#define r5 (scratch + 3 * n + 1) /* 3n+1 */
+#define r3 (scratch + 6 * n + 2) /* 3n+1 */
+#define r1 (scratch + 9 * n + 3) /* 3n+1 */
+#define v0 (pp +11 * n) /* n+1 */
+#define v2 (pp +13 * n+2) /* n+1 */
+#define wse (scratch +12 * n + 4) /* 3n+1 */
+
+ /* Alloc also 3n+1 limbs for ws... toom_interpolate_16pts may
+ need all of them, when DO_mpn_sublsh_n usea a scratch */
+/* if (scratch == NULL) */
+/* scratch = TMP_SALLOC_LIMBS (30 * n + 6); */
+
+ /********************** evaluation and recursive calls *********************/
+ /* $\pm1/8$ */
+ mpn_toom_eval_pm2rexp (v2, v0, 7, ap, n, s, 3, pp);
+ /* A(-1/8)*B(-1/8)*8^. */ /* A(+1/8)*B(+1/8)*8^. */
+ TOOM8_SQR_REC(pp, v0, 2, r7, v2, n + 1, wse);
+ mpn_toom_couple_handling (r7, 2 * n + 1 + BIT_CORRECTION, pp, 0, n, 3, 0);
+
+ /* $\pm1/4$ */
+ mpn_toom_eval_pm2rexp (v2, v0, 7, ap, n, s, 2, pp);
+ /* A(-1/4)*B(-1/4)*4^. */ /* A(+1/4)*B(+1/4)*4^. */
+ TOOM8_SQR_REC(pp, v0, 2, r5, v2, n + 1, wse);
+ mpn_toom_couple_handling (r5, 2 * n + 1, pp, 0, n, 2, 0);
+
+ /* $\pm2$ */
+ mpn_toom_eval_pm2 (v2, v0, 7, ap, n, s, pp);
+ /* A(-2)*B(-2) */ /* A(+2)*B(+2) */
+ TOOM8_SQR_REC(pp, v0, 2, r3, v2, n + 1, wse);
+ mpn_toom_couple_handling (r3, 2 * n + 1, pp, 0, n, 1, 2);
+
+ /* $\pm8$ */
+ mpn_toom_eval_pm2exp (v2, v0, 7, ap, n, s, 3, pp);
+ /* A(-8)*B(-8) */ /* A(+8)*B(+8) */
+ TOOM8_SQR_REC(pp, v0, 2, r1, v2, n + 1, wse);
+ mpn_toom_couple_handling (r1, 2 * n + 1 + BIT_CORRECTION, pp, 0, n, 3, 6);
+
+ /* $\pm1/2$ */
+ mpn_toom_eval_pm2rexp (v2, v0, 7, ap, n, s, 1, pp);
+ /* A(-1/2)*B(-1/2)*2^. */ /* A(+1/2)*B(+1/2)*2^. */
+ TOOM8_SQR_REC(pp, v0, 2, r6, v2, n + 1, wse);
+ mpn_toom_couple_handling (r6, 2 * n + 1, pp, 0, n, 1, 0);
+
+ /* $\pm1$ */
+ mpn_toom_eval_pm1 (v2, v0, 7, ap, n, s, pp);
+ /* A(-1)*B(-1) */ /* A(1)*B(1) */
+ TOOM8_SQR_REC(pp, v0, 2, r4, v2, n + 1, wse);
+ mpn_toom_couple_handling (r4, 2 * n + 1, pp, 0, n, 0, 0);
+
+ /* $\pm4$ */
+ mpn_toom_eval_pm2exp (v2, v0, 7, ap, n, s, 2, pp);
+ /* A(-4)*B(-4) */ /* A(+4)*B(+4) */
+ TOOM8_SQR_REC(pp, v0, 2, r2, v2, n + 1, wse);
+ mpn_toom_couple_handling (r2, 2 * n + 1, pp, 0, n, 2, 4);
+
+#undef v0
+#undef v2
+
+ /* A(0)*B(0) */
+ TOOM8_SQR_REC(pp, ap, 0, pp, ap, n, wse);
+
+ mpn_toom_interpolate_16pts (pp, r1, r3, r5, r7, n, 2 * s, 0, wse);
+
+#undef r0
+#undef r1
+#undef r2
+#undef r3
+#undef r4
+#undef r5
+#undef r6
+#undef wse
+
+}
+
+#undef TOOM8_SQR_REC
+#undef MAYBE_sqr_basecase
+#undef MAYBE_sqr_above_basecase
+#undef MAYBE_sqr_toom2
+#undef MAYBE_sqr_above_toom2
+#undef MAYBE_sqr_toom3
+#undef MAYBE_sqr_above_toom3
+#undef MAYBE_sqr_above_toom4
diff --git a/gmp/mpn/generic/toom8h_mul.c b/gmp/mpn/generic/toom8h_mul.c
new file mode 100644
index 0000000000..8f593903f5
--- /dev/null
+++ b/gmp/mpn/generic/toom8h_mul.c
@@ -0,0 +1,306 @@
+/* Implementation of the multiplication algorithm for Toom-Cook 8.5-way.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#if GMP_NUMB_BITS < 29
+#error Not implemented.
+#endif
+
+#if GMP_NUMB_BITS < 43
+#define BIT_CORRECTION 1
+#define CORRECTION_BITS GMP_NUMB_BITS
+#else
+#define BIT_CORRECTION 0
+#define CORRECTION_BITS 0
+#endif
+
+
+#if TUNE_PROGRAM_BUILD
+#define MAYBE_mul_basecase 1
+#define MAYBE_mul_toom22 1
+#define MAYBE_mul_toom33 1
+#define MAYBE_mul_toom44 1
+#define MAYBE_mul_toom8h 1
+#else
+#define MAYBE_mul_basecase \
+ (MUL_TOOM8H_THRESHOLD < 8 * MUL_TOOM22_THRESHOLD)
+#define MAYBE_mul_toom22 \
+ (MUL_TOOM8H_THRESHOLD < 8 * MUL_TOOM33_THRESHOLD)
+#define MAYBE_mul_toom33 \
+ (MUL_TOOM8H_THRESHOLD < 8 * MUL_TOOM44_THRESHOLD)
+#define MAYBE_mul_toom44 \
+ (MUL_TOOM8H_THRESHOLD < 8 * MUL_TOOM6H_THRESHOLD)
+#define MAYBE_mul_toom8h \
+ (MUL_FFT_THRESHOLD >= 8 * MUL_TOOM8H_THRESHOLD)
+#endif
+
+#define TOOM8H_MUL_N_REC(p, a, b, f, p2, a2, b2, n, ws) \
+ do { \
+ if (MAYBE_mul_basecase \
+ && BELOW_THRESHOLD (n, MUL_TOOM22_THRESHOLD)) { \
+ mpn_mul_basecase (p, a, n, b, n); \
+ if (f) mpn_mul_basecase (p2, a2, n, b2, n); \
+ } else if (MAYBE_mul_toom22 \
+ && BELOW_THRESHOLD (n, MUL_TOOM33_THRESHOLD)) { \
+ mpn_toom22_mul (p, a, n, b, n, ws); \
+ if (f) mpn_toom22_mul (p2, a2, n, b2, n, ws); \
+ } else if (MAYBE_mul_toom33 \
+ && BELOW_THRESHOLD (n, MUL_TOOM44_THRESHOLD)) { \
+ mpn_toom33_mul (p, a, n, b, n, ws); \
+ if (f) mpn_toom33_mul (p2, a2, n, b2, n, ws); \
+ } else if (MAYBE_mul_toom44 \
+ && BELOW_THRESHOLD (n, MUL_TOOM6H_THRESHOLD)) { \
+ mpn_toom44_mul (p, a, n, b, n, ws); \
+ if (f) mpn_toom44_mul (p2, a2, n, b2, n, ws); \
+ } else if (! MAYBE_mul_toom8h \
+ || BELOW_THRESHOLD (n, MUL_TOOM8H_THRESHOLD)) { \
+ mpn_toom6h_mul (p, a, n, b, n, ws); \
+ if (f) mpn_toom6h_mul (p2, a2, n, b2, n, ws); \
+ } else { \
+ mpn_toom8h_mul (p, a, n, b, n, ws); \
+ if (f) mpn_toom8h_mul (p2, a2, n, b2, n, ws); \
+ } \
+ } while (0)
+
+#define TOOM8H_MUL_REC(p, a, na, b, nb, ws) \
+ do { mpn_mul (p, a, na, b, nb); } while (0)
+
+/* Toom-8.5 , compute the product {pp,an+bn} <- {ap,an} * {bp,bn}
+ With: an >= bn >= 86, an*5 < bn * 11.
+ It _may_ work with bn<=?? and bn*?? < an*? < bn*??
+
+ Evaluate in: infinity, +8,-8,+4,-4,+2,-2,+1,-1,+1/2,-1/2,+1/4,-1/4,+1/8,-1/8,0.
+*/
+/* Estimate on needed scratch:
+ S(n) <= (n+7)\8*13+5+MAX(S((n+7)\8),1+2*(n+7)\8),
+ since n>80; S(n) <= ceil(log(n/10)/log(8))*(13+5)+n*15\8 < n*15\8 + lg2(n)*6
+ */
+
+void
+mpn_toom8h_mul (mp_ptr pp,
+ mp_srcptr ap, mp_size_t an,
+ mp_srcptr bp, mp_size_t bn, mp_ptr scratch)
+{
+ mp_size_t n, s, t;
+ int p, q, half;
+ int sign;
+
+ /***************************** decomposition *******************************/
+
+ ASSERT (an >= bn);
+ /* Can not handle too small operands */
+ ASSERT (bn >= 86);
+ /* Can not handle too much unbalancement */
+ ASSERT (an <= bn*4);
+ ASSERT (GMP_NUMB_BITS > 11*3 || an*4 <= bn*11);
+ ASSERT (GMP_NUMB_BITS > 10*3 || an*1 <= bn* 2);
+ ASSERT (GMP_NUMB_BITS > 9*3 || an*2 <= bn* 3);
+
+ /* Limit num/den is a rational number between
+ (16/15)^(log(6)/log(2*6-1)) and (16/15)^(log(8)/log(2*8-1)) */
+#define LIMIT_numerator (21)
+#define LIMIT_denominat (20)
+
+ if (LIKELY (an == bn) || an * (LIMIT_denominat>>1) < LIMIT_numerator * (bn>>1) ) /* is 8*... < 8*... */
+ {
+ half = 0;
+ n = 1 + ((an - 1)>>3);
+ p = q = 7;
+ s = an - 7 * n;
+ t = bn - 7 * n;
+ }
+ else
+ {
+ if (an * 13 < 16 * bn) /* (an*7*LIMIT_numerator<LIMIT_denominat*9*bn) */
+ { p = 9; q = 8; }
+ else if (GMP_NUMB_BITS <= 9*3 ||
+ an *(LIMIT_denominat>>1) < (LIMIT_numerator/7*9) * (bn>>1))
+ { p = 9; q = 7; }
+ else if (an * 10 < 33 * (bn>>1)) /* (an*3*LIMIT_numerator<LIMIT_denominat*5*bn) */
+ { p =10; q = 7; }
+ else if (GMP_NUMB_BITS <= 10*3 ||
+ an * (LIMIT_denominat/5) < (LIMIT_numerator/3) * bn)
+ { p =10; q = 6; }
+ else if (an * 6 < 13 * bn) /*(an * 5 * LIMIT_numerator < LIMIT_denominat *11 * bn)*/
+ { p =11; q = 6; }
+ else if (GMP_NUMB_BITS <= 11*3 ||
+ an * 4 < 9 * bn)
+ { p =11; q = 5; }
+ else if (an *(LIMIT_numerator/3) < LIMIT_denominat * bn) /* is 4*... <12*... */
+ { p =12; q = 5; }
+ else if (GMP_NUMB_BITS <= 12*3 ||
+ an * 9 < 28 * bn ) /* is 4*... <12*... */
+ { p =12; q = 4; }
+ else
+ { p =13; q = 4; }
+
+ half = (p+q)&1;
+ n = 1 + (q * an >= p * bn ? (an - 1) / (size_t) p : (bn - 1) / (size_t) q);
+ p--; q--;
+
+ s = an - p * n;
+ t = bn - q * n;
+
+ if(half) { /* Recover from badly chosen splitting */
+ if (UNLIKELY (s<1)) {p--; s+=n; half=0;}
+ else if (UNLIKELY (t<1)) {q--; t+=n; half=0;}
+ }
+ }
+#undef LIMIT_numerator
+#undef LIMIT_denominat
+
+ ASSERT (0 < s && s <= n);
+ ASSERT (0 < t && t <= n);
+ ASSERT (half || s + t > 3);
+ ASSERT (n > 2);
+
+#define r6 (pp + 3 * n) /* 3n+1 */
+#define r4 (pp + 7 * n) /* 3n+1 */
+#define r2 (pp +11 * n) /* 3n+1 */
+#define r0 (pp +15 * n) /* s+t <= 2*n */
+#define r7 (scratch) /* 3n+1 */
+#define r5 (scratch + 3 * n + 1) /* 3n+1 */
+#define r3 (scratch + 6 * n + 2) /* 3n+1 */
+#define r1 (scratch + 9 * n + 3) /* 3n+1 */
+#define v0 (pp +11 * n) /* n+1 */
+#define v1 (pp +12 * n+1) /* n+1 */
+#define v2 (pp +13 * n+2) /* n+1 */
+#define v3 (scratch +12 * n + 4) /* n+1 */
+#define wsi (scratch +12 * n + 4) /* 3n+1 */
+#define wse (scratch +13 * n + 5) /* 2n+1 */
+
+ /* Alloc also 3n+1 limbs for wsi... toom_interpolate_16pts may
+ need all of them */
+/* if (scratch == NULL) */
+/* scratch = TMP_SALLOC_LIMBS(mpn_toom8_sqr_itch(n * 8)); */
+ ASSERT (15 * n + 6 <= mpn_toom8h_mul_itch (an, bn));
+ ASSERT (15 * n + 6 <= mpn_toom8_sqr_itch (n * 8));
+
+ /********************** evaluation and recursive calls *********************/
+
+ /* $\pm1/8$ */
+ sign = mpn_toom_eval_pm2rexp (v2, v0, p, ap, n, s, 3, pp) ^
+ mpn_toom_eval_pm2rexp (v3, v1, q, bp, n, t, 3, pp);
+ /* A(-1/8)*B(-1/8)*8^. */ /* A(+1/8)*B(+1/8)*8^. */
+ TOOM8H_MUL_N_REC(pp, v0, v1, 2, r7, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r7, 2 * n + 1 + BIT_CORRECTION, pp, sign, n, 3*(1+half), 3*(half));
+
+ /* $\pm1/4$ */
+ sign = mpn_toom_eval_pm2rexp (v2, v0, p, ap, n, s, 2, pp) ^
+ mpn_toom_eval_pm2rexp (v3, v1, q, bp, n, t, 2, pp);
+ /* A(-1/4)*B(-1/4)*4^. */ /* A(+1/4)*B(+1/4)*4^. */
+ TOOM8H_MUL_N_REC(pp, v0, v1, 2, r5, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r5, 2 * n + 1, pp, sign, n, 2*(1+half), 2*(half));
+
+ /* $\pm2$ */
+ sign = mpn_toom_eval_pm2 (v2, v0, p, ap, n, s, pp) ^
+ mpn_toom_eval_pm2 (v3, v1, q, bp, n, t, pp);
+ /* A(-2)*B(-2) */ /* A(+2)*B(+2) */
+ TOOM8H_MUL_N_REC(pp, v0, v1, 2, r3, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r3, 2 * n + 1, pp, sign, n, 1, 2);
+
+ /* $\pm8$ */
+ sign = mpn_toom_eval_pm2exp (v2, v0, p, ap, n, s, 3, pp) ^
+ mpn_toom_eval_pm2exp (v3, v1, q, bp, n, t, 3, pp);
+ /* A(-8)*B(-8) */ /* A(+8)*B(+8) */
+ TOOM8H_MUL_N_REC(pp, v0, v1, 2, r1, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r1, 2 * n + 1 + BIT_CORRECTION, pp, sign, n, 3, 6);
+
+ /* $\pm1/2$ */
+ sign = mpn_toom_eval_pm2rexp (v2, v0, p, ap, n, s, 1, pp) ^
+ mpn_toom_eval_pm2rexp (v3, v1, q, bp, n, t, 1, pp);
+ /* A(-1/2)*B(-1/2)*2^. */ /* A(+1/2)*B(+1/2)*2^. */
+ TOOM8H_MUL_N_REC(pp, v0, v1, 2, r6, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r6, 2 * n + 1, pp, sign, n, 1+half, half);
+
+ /* $\pm1$ */
+ sign = mpn_toom_eval_pm1 (v2, v0, p, ap, n, s, pp);
+ if (GMP_NUMB_BITS > 12*3 && UNLIKELY (q == 3))
+ sign ^= mpn_toom_eval_dgr3_pm1 (v3, v1, bp, n, t, pp);
+ else
+ sign ^= mpn_toom_eval_pm1 (v3, v1, q, bp, n, t, pp);
+ /* A(-1)*B(-1) */ /* A(1)*B(1) */
+ TOOM8H_MUL_N_REC(pp, v0, v1, 2, r4, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r4, 2 * n + 1, pp, sign, n, 0, 0);
+
+ /* $\pm4$ */
+ sign = mpn_toom_eval_pm2exp (v2, v0, p, ap, n, s, 2, pp) ^
+ mpn_toom_eval_pm2exp (v3, v1, q, bp, n, t, 2, pp);
+ /* A(-4)*B(-4) */ /* A(+4)*B(+4) */
+ TOOM8H_MUL_N_REC(pp, v0, v1, 2, r2, v2, v3, n + 1, wse);
+ mpn_toom_couple_handling (r2, 2 * n + 1, pp, sign, n, 2, 4);
+
+#undef v0
+#undef v1
+#undef v2
+#undef v3
+#undef wse
+
+ /* A(0)*B(0) */
+ TOOM8H_MUL_N_REC(pp, ap, bp, 0, pp, ap, bp, n, wsi);
+
+ /* Infinity */
+ if (UNLIKELY (half != 0)) {
+ if (s > t) {
+ TOOM8H_MUL_REC(r0, ap + p * n, s, bp + q * n, t, wsi);
+ } else {
+ TOOM8H_MUL_REC(r0, bp + q * n, t, ap + p * n, s, wsi);
+ };
+ };
+
+ mpn_toom_interpolate_16pts (pp, r1, r3, r5, r7, n, s+t, half, wsi);
+
+#undef r0
+#undef r1
+#undef r2
+#undef r3
+#undef r4
+#undef r5
+#undef r6
+#undef wsi
+}
+
+#undef TOOM8H_MUL_N_REC
+#undef TOOM8H_MUL_REC
+#undef MAYBE_mul_basecase
+#undef MAYBE_mul_toom22
+#undef MAYBE_mul_toom33
+#undef MAYBE_mul_toom44
+#undef MAYBE_mul_toom8h
diff --git a/gmp/mpn/generic/toom_couple_handling.c b/gmp/mpn/generic/toom_couple_handling.c
new file mode 100644
index 0000000000..9e62bcba1c
--- /dev/null
+++ b/gmp/mpn/generic/toom_couple_handling.c
@@ -0,0 +1,81 @@
+/* Helper function for high degree Toom-Cook algorithms.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Gets {pp,n} and (sign?-1:1)*{np,n}. Computes at once:
+ {pp,n} <- ({pp,n}+{np,n})/2^{ps+1}
+ {pn,n} <- ({pp,n}-{np,n})/2^{ns+1}
+ Finally recompose them obtaining:
+ {pp,n+off} <- {pp,n}+{np,n}*2^{off*GMP_NUMB_BITS}
+*/
+void
+mpn_toom_couple_handling (mp_ptr pp, mp_size_t n, mp_ptr np,
+ int nsign, mp_size_t off, int ps, int ns)
+{
+ if (nsign) {
+#ifdef HAVE_NATIVE_mpn_rsh1sub_n
+ mpn_rsh1sub_n (np, pp, np, n);
+#else
+ mpn_sub_n (np, pp, np, n);
+ mpn_rshift (np, np, n, 1);
+#endif
+ } else {
+#ifdef HAVE_NATIVE_mpn_rsh1add_n
+ mpn_rsh1add_n (np, pp, np, n);
+#else
+ mpn_add_n (np, pp, np, n);
+ mpn_rshift (np, np, n, 1);
+#endif
+ }
+
+#ifdef HAVE_NATIVE_mpn_rsh1sub_n
+ if (ps == 1)
+ mpn_rsh1sub_n (pp, pp, np, n);
+ else
+#endif
+ {
+ mpn_sub_n (pp, pp, np, n);
+ if (ps > 0)
+ mpn_rshift (pp, pp, n, ps);
+ }
+ if (ns > 0)
+ mpn_rshift (np, np, n, ns);
+ pp[n] = mpn_add_n (pp+off, pp+off, np, n-off);
+ ASSERT_NOCARRY (mpn_add_1(pp+n, np+n-off, off, pp[n]) );
+}
diff --git a/gmp/mpn/generic/toom_eval_dgr3_pm1.c b/gmp/mpn/generic/toom_eval_dgr3_pm1.c
new file mode 100644
index 0000000000..50411bd3ca
--- /dev/null
+++ b/gmp/mpn/generic/toom_eval_dgr3_pm1.c
@@ -0,0 +1,73 @@
+/* mpn_toom_eval_dgr3_pm1 -- Evaluate a degree 3 polynomial in +1 and -1
+
+ Contributed to the GNU project by Niels Möller
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpn_toom_eval_dgr3_pm1 (mp_ptr xp1, mp_ptr xm1,
+ mp_srcptr xp, mp_size_t n, mp_size_t x3n, mp_ptr tp)
+{
+ int neg;
+
+ ASSERT (x3n > 0);
+ ASSERT (x3n <= n);
+
+ xp1[n] = mpn_add_n (xp1, xp, xp + 2*n, n);
+ tp[n] = mpn_add (tp, xp + n, n, xp + 3*n, x3n);
+
+ neg = (mpn_cmp (xp1, tp, n + 1) < 0) ? ~0 : 0;
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (neg)
+ mpn_add_n_sub_n (xp1, xm1, tp, xp1, n + 1);
+ else
+ mpn_add_n_sub_n (xp1, xm1, xp1, tp, n + 1);
+#else
+ if (neg)
+ mpn_sub_n (xm1, tp, xp1, n + 1);
+ else
+ mpn_sub_n (xm1, xp1, tp, n + 1);
+
+ mpn_add_n (xp1, xp1, tp, n + 1);
+#endif
+
+ ASSERT (xp1[n] <= 3);
+ ASSERT (xm1[n] <= 1);
+
+ return neg;
+}
diff --git a/gmp/mpn/generic/toom_eval_dgr3_pm2.c b/gmp/mpn/generic/toom_eval_dgr3_pm2.c
new file mode 100644
index 0000000000..3ba6d15f3d
--- /dev/null
+++ b/gmp/mpn/generic/toom_eval_dgr3_pm2.c
@@ -0,0 +1,98 @@
+/* mpn_toom_eval_dgr3_pm2 -- Evaluate a degree 3 polynomial in +2 and -2
+
+ Contributed to the GNU project by Niels Möller
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Needs n+1 limbs of temporary storage. */
+int
+mpn_toom_eval_dgr3_pm2 (mp_ptr xp2, mp_ptr xm2,
+ mp_srcptr xp, mp_size_t n, mp_size_t x3n, mp_ptr tp)
+{
+ mp_limb_t cy;
+ int neg;
+
+ ASSERT (x3n > 0);
+ ASSERT (x3n <= n);
+
+ /* (x0 + 4 * x2) +/- (2 x1 + 8 x_3) */
+#if HAVE_NATIVE_mpn_addlsh_n || HAVE_NATIVE_mpn_addlsh2_n
+#if HAVE_NATIVE_mpn_addlsh2_n
+ xp2[n] = mpn_addlsh2_n (xp2, xp, xp + 2*n, n);
+
+ cy = mpn_addlsh2_n (tp, xp + n, xp + 3*n, x3n);
+#else /* HAVE_NATIVE_mpn_addlsh_n */
+ xp2[n] = mpn_addlsh_n (xp2, xp, xp + 2*n, n, 2);
+
+ cy = mpn_addlsh_n (tp, xp + n, xp + 3*n, x3n, 2);
+#endif
+ if (x3n < n)
+ cy = mpn_add_1 (tp + x3n, xp + n + x3n, n - x3n, cy);
+ tp[n] = cy;
+#else
+ cy = mpn_lshift (tp, xp + 2*n, n, 2);
+ xp2[n] = cy + mpn_add_n (xp2, tp, xp, n);
+
+ tp[x3n] = mpn_lshift (tp, xp + 3*n, x3n, 2);
+ if (x3n < n)
+ tp[n] = mpn_add (tp, xp + n, n, tp, x3n + 1);
+ else
+ tp[n] += mpn_add_n (tp, xp + n, tp, n);
+#endif
+ mpn_lshift (tp, tp, n+1, 1);
+
+ neg = (mpn_cmp (xp2, tp, n + 1) < 0) ? ~0 : 0;
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (neg)
+ mpn_add_n_sub_n (xp2, xm2, tp, xp2, n + 1);
+ else
+ mpn_add_n_sub_n (xp2, xm2, xp2, tp, n + 1);
+#else
+ if (neg)
+ mpn_sub_n (xm2, tp, xp2, n + 1);
+ else
+ mpn_sub_n (xm2, xp2, tp, n + 1);
+
+ mpn_add_n (xp2, xp2, tp, n + 1);
+#endif
+
+ ASSERT (xp2[n] < 15);
+ ASSERT (xm2[n] < 10);
+
+ return neg;
+}
diff --git a/gmp/mpn/generic/toom_eval_pm1.c b/gmp/mpn/generic/toom_eval_pm1.c
new file mode 100644
index 0000000000..2334b0aff4
--- /dev/null
+++ b/gmp/mpn/generic/toom_eval_pm1.c
@@ -0,0 +1,90 @@
+/* mpn_toom_eval_pm1 -- Evaluate a polynomial in +1 and -1
+
+ Contributed to the GNU project by Niels Möller
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluates a polynomial of degree k > 3, in the points +1 and -1. */
+int
+mpn_toom_eval_pm1 (mp_ptr xp1, mp_ptr xm1, unsigned k,
+ mp_srcptr xp, mp_size_t n, mp_size_t hn, mp_ptr tp)
+{
+ unsigned i;
+ int neg;
+
+ ASSERT (k >= 4);
+
+ ASSERT (hn > 0);
+ ASSERT (hn <= n);
+
+ /* The degree k is also the number of full-size coefficients, so
+ * that last coefficient, of size hn, starts at xp + k*n. */
+
+ xp1[n] = mpn_add_n (xp1, xp, xp + 2*n, n);
+ for (i = 4; i < k; i += 2)
+ ASSERT_NOCARRY (mpn_add (xp1, xp1, n+1, xp+i*n, n));
+
+ tp[n] = mpn_add_n (tp, xp + n, xp + 3*n, n);
+ for (i = 5; i < k; i += 2)
+ ASSERT_NOCARRY (mpn_add (tp, tp, n+1, xp+i*n, n));
+
+ if (k & 1)
+ ASSERT_NOCARRY (mpn_add (tp, tp, n+1, xp+k*n, hn));
+ else
+ ASSERT_NOCARRY (mpn_add (xp1, xp1, n+1, xp+k*n, hn));
+
+ neg = (mpn_cmp (xp1, tp, n + 1) < 0) ? ~0 : 0;
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (neg)
+ mpn_add_n_sub_n (xp1, xm1, tp, xp1, n + 1);
+ else
+ mpn_add_n_sub_n (xp1, xm1, xp1, tp, n + 1);
+#else
+ if (neg)
+ mpn_sub_n (xm1, tp, xp1, n + 1);
+ else
+ mpn_sub_n (xm1, xp1, tp, n + 1);
+
+ mpn_add_n (xp1, xp1, tp, n + 1);
+#endif
+
+ ASSERT (xp1[n] <= k);
+ ASSERT (xm1[n] <= k/2 + 1);
+
+ return neg;
+}
diff --git a/gmp/mpn/generic/toom_eval_pm2.c b/gmp/mpn/generic/toom_eval_pm2.c
new file mode 100644
index 0000000000..67afcc638e
--- /dev/null
+++ b/gmp/mpn/generic/toom_eval_pm2.c
@@ -0,0 +1,131 @@
+/* mpn_toom_eval_pm2 -- Evaluate a polynomial in +2 and -2
+
+ Contributed to the GNU project by Niels Möller and Marco Bodrato
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* DO_addlsh2(d,a,b,n,cy) computes cy,{d,n} <- {a,n} + 4*(cy,{b,n}), it
+ can be used as DO_addlsh2(d,a,d,n,d[n]), for accumulation on {d,n+1}. */
+#if HAVE_NATIVE_mpn_addlsh2_n
+#define DO_addlsh2(d, a, b, n, cy) \
+do { \
+ (cy) <<= 2; \
+ (cy) += mpn_addlsh2_n(d, a, b, n); \
+} while (0)
+#else
+#if HAVE_NATIVE_mpn_addlsh_n
+#define DO_addlsh2(d, a, b, n, cy) \
+do { \
+ (cy) <<= 2; \
+ (cy) += mpn_addlsh_n(d, a, b, n, 2); \
+} while (0)
+#else
+/* The following is not a general substitute for addlsh2.
+ It is correct if d == b, but it is not if d == a. */
+#define DO_addlsh2(d, a, b, n, cy) \
+do { \
+ (cy) <<= 2; \
+ (cy) += mpn_lshift(d, b, n, 2); \
+ (cy) += mpn_add_n(d, d, a, n); \
+} while (0)
+#endif
+#endif
+
+/* Evaluates a polynomial of degree 2 < k < GMP_NUMB_BITS, in the
+ points +2 and -2. */
+int
+mpn_toom_eval_pm2 (mp_ptr xp2, mp_ptr xm2, unsigned k,
+ mp_srcptr xp, mp_size_t n, mp_size_t hn, mp_ptr tp)
+{
+ int i;
+ int neg;
+ mp_limb_t cy;
+
+ ASSERT (k >= 3);
+ ASSERT (k < GMP_NUMB_BITS);
+
+ ASSERT (hn > 0);
+ ASSERT (hn <= n);
+
+ /* The degree k is also the number of full-size coefficients, so
+ * that last coefficient, of size hn, starts at xp + k*n. */
+
+ cy = 0;
+ DO_addlsh2 (xp2, xp + (k-2) * n, xp + k * n, hn, cy);
+ if (hn != n)
+ cy = mpn_add_1 (xp2 + hn, xp + (k-2) * n + hn, n - hn, cy);
+ for (i = k - 4; i >= 0; i -= 2)
+ DO_addlsh2 (xp2, xp + i * n, xp2, n, cy);
+ xp2[n] = cy;
+
+ k--;
+
+ cy = 0;
+ DO_addlsh2 (tp, xp + (k-2) * n, xp + k * n, n, cy);
+ for (i = k - 4; i >= 0; i -= 2)
+ DO_addlsh2 (tp, xp + i * n, tp, n, cy);
+ tp[n] = cy;
+
+ if (k & 1)
+ ASSERT_NOCARRY(mpn_lshift (tp , tp , n + 1, 1));
+ else
+ ASSERT_NOCARRY(mpn_lshift (xp2, xp2, n + 1, 1));
+
+ neg = (mpn_cmp (xp2, tp, n + 1) < 0) ? ~0 : 0;
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (neg)
+ mpn_add_n_sub_n (xp2, xm2, tp, xp2, n + 1);
+ else
+ mpn_add_n_sub_n (xp2, xm2, xp2, tp, n + 1);
+#else /* !HAVE_NATIVE_mpn_add_n_sub_n */
+ if (neg)
+ mpn_sub_n (xm2, tp, xp2, n + 1);
+ else
+ mpn_sub_n (xm2, xp2, tp, n + 1);
+
+ mpn_add_n (xp2, xp2, tp, n + 1);
+#endif /* !HAVE_NATIVE_mpn_add_n_sub_n */
+
+ ASSERT (xp2[n] < (1<<(k+2))-1);
+ ASSERT (xm2[n] < ((1<<(k+3))-1 - (1^k&1))/3);
+
+ neg ^= ((k & 1) - 1);
+
+ return neg;
+}
+
+#undef DO_addlsh2
diff --git a/gmp/mpn/generic/toom_eval_pm2exp.c b/gmp/mpn/generic/toom_eval_pm2exp.c
new file mode 100644
index 0000000000..b178fcac24
--- /dev/null
+++ b/gmp/mpn/generic/toom_eval_pm2exp.c
@@ -0,0 +1,128 @@
+/* mpn_toom_eval_pm2exp -- Evaluate a polynomial in +2^k and -2^k
+
+ Contributed to the GNU project by Niels Möller
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Evaluates a polynomial of degree k > 2, in the points +2^shift and -2^shift. */
+int
+mpn_toom_eval_pm2exp (mp_ptr xp2, mp_ptr xm2, unsigned k,
+ mp_srcptr xp, mp_size_t n, mp_size_t hn, unsigned shift,
+ mp_ptr tp)
+{
+ unsigned i;
+ int neg;
+#if HAVE_NATIVE_mpn_addlsh_n
+ mp_limb_t cy;
+#endif
+
+ ASSERT (k >= 3);
+ ASSERT (shift*k < GMP_NUMB_BITS);
+
+ ASSERT (hn > 0);
+ ASSERT (hn <= n);
+
+ /* The degree k is also the number of full-size coefficients, so
+ * that last coefficient, of size hn, starts at xp + k*n. */
+
+#if HAVE_NATIVE_mpn_addlsh_n
+ xp2[n] = mpn_addlsh_n (xp2, xp, xp + 2*n, n, 2*shift);
+ for (i = 4; i < k; i += 2)
+ xp2[n] += mpn_addlsh_n (xp2, xp2, xp + i*n, n, i*shift);
+
+ tp[n] = mpn_lshift (tp, xp+n, n, shift);
+ for (i = 3; i < k; i+= 2)
+ tp[n] += mpn_addlsh_n (tp, tp, xp+i*n, n, i*shift);
+
+ if (k & 1)
+ {
+ cy = mpn_addlsh_n (tp, tp, xp+k*n, hn, k*shift);
+ MPN_INCR_U (tp + hn, n+1 - hn, cy);
+ }
+ else
+ {
+ cy = mpn_addlsh_n (xp2, xp2, xp+k*n, hn, k*shift);
+ MPN_INCR_U (xp2 + hn, n+1 - hn, cy);
+ }
+
+#else /* !HAVE_NATIVE_mpn_addlsh_n */
+ xp2[n] = mpn_lshift (tp, xp+2*n, n, 2*shift);
+ xp2[n] += mpn_add_n (xp2, xp, tp, n);
+ for (i = 4; i < k; i += 2)
+ {
+ xp2[n] += mpn_lshift (tp, xp + i*n, n, i*shift);
+ xp2[n] += mpn_add_n (xp2, xp2, tp, n);
+ }
+
+ tp[n] = mpn_lshift (tp, xp+n, n, shift);
+ for (i = 3; i < k; i+= 2)
+ {
+ tp[n] += mpn_lshift (xm2, xp + i*n, n, i*shift);
+ tp[n] += mpn_add_n (tp, tp, xm2, n);
+ }
+
+ xm2[hn] = mpn_lshift (xm2, xp + k*n, hn, k*shift);
+ if (k & 1)
+ mpn_add (tp, tp, n+1, xm2, hn+1);
+ else
+ mpn_add (xp2, xp2, n+1, xm2, hn+1);
+#endif /* !HAVE_NATIVE_mpn_addlsh_n */
+
+ neg = (mpn_cmp (xp2, tp, n + 1) < 0) ? ~0 : 0;
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (neg)
+ mpn_add_n_sub_n (xp2, xm2, tp, xp2, n + 1);
+ else
+ mpn_add_n_sub_n (xp2, xm2, xp2, tp, n + 1);
+#else /* !HAVE_NATIVE_mpn_add_n_sub_n */
+ if (neg)
+ mpn_sub_n (xm2, tp, xp2, n + 1);
+ else
+ mpn_sub_n (xm2, xp2, tp, n + 1);
+
+ mpn_add_n (xp2, xp2, tp, n + 1);
+#endif /* !HAVE_NATIVE_mpn_add_n_sub_n */
+
+ /* FIXME: the following asserts are useless if (k+1)*shift >= GMP_LIMB_BITS */
+ ASSERT ((k+1)*shift >= GMP_LIMB_BITS ||
+ xp2[n] < ((CNST_LIMB(1)<<((k+1)*shift))-1)/((CNST_LIMB(1)<<shift)-1));
+ ASSERT ((k+2)*shift >= GMP_LIMB_BITS ||
+ xm2[n] < ((CNST_LIMB(1)<<((k+2)*shift))-((k&1)?(CNST_LIMB(1)<<shift):1))/((CNST_LIMB(1)<<(2*shift))-1));
+
+ return neg;
+}
diff --git a/gmp/mpn/generic/toom_eval_pm2rexp.c b/gmp/mpn/generic/toom_eval_pm2rexp.c
new file mode 100644
index 0000000000..3cac46bd90
--- /dev/null
+++ b/gmp/mpn/generic/toom_eval_pm2rexp.c
@@ -0,0 +1,102 @@
+/* mpn_toom_eval_pm2rexp -- Evaluate a polynomial in +2^-k and -2^-k
+
+ Contributed to the GNU project by Marco Bodrato
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if HAVE_NATIVE_mpn_addlsh_n
+#define DO_mpn_addlsh_n(dst,src,n,s,ws) mpn_addlsh_n(dst,dst,src,n,s)
+#else
+static mp_limb_t
+DO_mpn_addlsh_n(mp_ptr dst, mp_srcptr src, mp_size_t n, unsigned int s, mp_ptr ws)
+{
+#if USE_MUL_1 && 0
+ return mpn_addmul_1(dst,src,n,CNST_LIMB(1) <<(s));
+#else
+ mp_limb_t __cy;
+ __cy = mpn_lshift(ws,src,n,s);
+ return __cy + mpn_add_n(dst,dst,ws,n);
+#endif
+}
+#endif
+
+/* Evaluates a polynomial of degree k >= 3. */
+int
+mpn_toom_eval_pm2rexp (mp_ptr rp, mp_ptr rm,
+ unsigned int q, mp_srcptr ap, mp_size_t n, mp_size_t t,
+ unsigned int s, mp_ptr ws)
+{
+ unsigned int i;
+ int neg;
+ /* {ap,q*n+t} -> {rp,n+1} {rm,n+1} , with {ws, n+1}*/
+ ASSERT (n >= t);
+ ASSERT (s != 0); /* or _eval_pm1 should be used */
+ ASSERT (q > 1);
+ ASSERT (s*q < GMP_NUMB_BITS);
+ rp[n] = mpn_lshift(rp, ap, n, s*q);
+ ws[n] = mpn_lshift(ws, ap+n, n, s*(q-1));
+ if( (q & 1) != 0) {
+ ASSERT_NOCARRY(mpn_add(ws,ws,n+1,ap+n*q,t));
+ rp[n] += DO_mpn_addlsh_n(rp, ap+n*(q-1), n, s, rm);
+ } else {
+ ASSERT_NOCARRY(mpn_add(rp,rp,n+1,ap+n*q,t));
+ }
+ for(i=2; i<q-1; i++)
+ {
+ rp[n] += DO_mpn_addlsh_n(rp, ap+n*i, n, s*(q-i), rm);
+ i++;
+ ws[n] += DO_mpn_addlsh_n(ws, ap+n*i, n, s*(q-i), rm);
+ };
+
+ neg = (mpn_cmp (rp, ws, n + 1) < 0) ? ~0 : 0;
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ if (neg)
+ mpn_add_n_sub_n (rp, rm, ws, rp, n + 1);
+ else
+ mpn_add_n_sub_n (rp, rm, rp, ws, n + 1);
+#else /* !HAVE_NATIVE_mpn_add_n_sub_n */
+ if (neg)
+ mpn_sub_n (rm, ws, rp, n + 1);
+ else
+ mpn_sub_n (rm, rp, ws, n + 1);
+
+ ASSERT_NOCARRY (mpn_add_n (rp, rp, ws, n + 1));
+#endif /* !HAVE_NATIVE_mpn_add_n_sub_n */
+
+ return neg;
+}
diff --git a/gmp/mpn/generic/toom_interpolate_12pts.c b/gmp/mpn/generic/toom_interpolate_12pts.c
new file mode 100644
index 0000000000..180b0329a3
--- /dev/null
+++ b/gmp/mpn/generic/toom_interpolate_12pts.c
@@ -0,0 +1,361 @@
+/* Interpolation for the algorithm Toom-Cook 6.5-way.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#if HAVE_NATIVE_mpn_sublsh_n
+#define DO_mpn_sublsh_n(dst,src,n,s,ws) mpn_sublsh_n(dst,dst,src,n,s)
+#else
+static mp_limb_t
+DO_mpn_sublsh_n(mp_ptr dst, mp_srcptr src, mp_size_t n, unsigned int s, mp_ptr ws)
+{
+#if USE_MUL_1 && 0
+ return mpn_submul_1(dst,src,n,CNST_LIMB(1) <<(s));
+#else
+ mp_limb_t __cy;
+ __cy = mpn_lshift(ws,src,n,s);
+ return __cy + mpn_sub_n(dst,dst,ws,n);
+#endif
+}
+#endif
+
+#if HAVE_NATIVE_mpn_addlsh_n
+#define DO_mpn_addlsh_n(dst,src,n,s,ws) mpn_addlsh_n(dst,dst,src,n,s)
+#else
+static mp_limb_t
+DO_mpn_addlsh_n(mp_ptr dst, mp_srcptr src, mp_size_t n, unsigned int s, mp_ptr ws)
+{
+#if USE_MUL_1 && 0
+ return mpn_addmul_1(dst,src,n,CNST_LIMB(1) <<(s));
+#else
+ mp_limb_t __cy;
+ __cy = mpn_lshift(ws,src,n,s);
+ return __cy + mpn_add_n(dst,dst,ws,n);
+#endif
+}
+#endif
+
+#if HAVE_NATIVE_mpn_subrsh
+#define DO_mpn_subrsh(dst,nd,src,ns,s,ws) mpn_subrsh(dst,nd,src,ns,s)
+#else
+/* FIXME: This is not a correct definition, it assumes no carry */
+#define DO_mpn_subrsh(dst,nd,src,ns,s,ws) \
+do { \
+ mp_limb_t __cy; \
+ MPN_DECR_U (dst, nd, src[0] >> s); \
+ __cy = DO_mpn_sublsh_n (dst, src + 1, ns - 1, GMP_NUMB_BITS - s, ws); \
+ MPN_DECR_U (dst + ns - 1, nd - ns + 1, __cy); \
+} while (0)
+#endif
+
+
+#if GMP_NUMB_BITS < 21
+#error Not implemented: Both sublsh_n(,,,20) should be corrected.
+#endif
+
+#if GMP_NUMB_BITS < 16
+#error Not implemented: divexact_by42525 needs splitting.
+#endif
+
+#if GMP_NUMB_BITS < 12
+#error Not implemented: Hard to adapt...
+#endif
+
+/* FIXME: tuneup should decide the best variant */
+#ifndef AORSMUL_FASTER_AORS_AORSLSH
+#define AORSMUL_FASTER_AORS_AORSLSH 1
+#endif
+#ifndef AORSMUL_FASTER_AORS_2AORSLSH
+#define AORSMUL_FASTER_AORS_2AORSLSH 1
+#endif
+#ifndef AORSMUL_FASTER_2AORSLSH
+#define AORSMUL_FASTER_2AORSLSH 1
+#endif
+#ifndef AORSMUL_FASTER_3AORSLSH
+#define AORSMUL_FASTER_3AORSLSH 1
+#endif
+
+#define BINVERT_9 \
+ ((((GMP_NUMB_MAX / 9) << (6 - GMP_NUMB_BITS % 6)) * 8 & GMP_NUMB_MAX) | 0x39)
+
+#define BINVERT_255 \
+ (GMP_NUMB_MAX - ((GMP_NUMB_MAX / 255) << (8 - GMP_NUMB_BITS % 8)))
+
+ /* FIXME: find some more general expressions for 2835^-1, 42525^-1 */
+#if GMP_LIMB_BITS == 32
+#define BINVERT_2835 (GMP_NUMB_MASK & CNST_LIMB(0x53E3771B))
+#define BINVERT_42525 (GMP_NUMB_MASK & CNST_LIMB(0x9F314C35))
+#else
+#if GMP_LIMB_BITS == 64
+#define BINVERT_2835 (GMP_NUMB_MASK & CNST_LIMB(0x938CC70553E3771B))
+#define BINVERT_42525 (GMP_NUMB_MASK & CNST_LIMB(0xE7B40D449F314C35))
+#endif
+#endif
+
+#ifndef mpn_divexact_by255
+#if GMP_NUMB_BITS % 8 == 0
+#define mpn_divexact_by255(dst,src,size) \
+ (255 & 1 * mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 255)))
+#else
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by255(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(255),BINVERT_255,0)
+#else
+#define mpn_divexact_by255(dst,src,size) mpn_divexact_1(dst,src,size,CNST_LIMB(255))
+#endif
+#endif
+#endif
+
+#ifndef mpn_divexact_by9x4
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by9x4(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(9),BINVERT_9,2)
+#else
+#define mpn_divexact_by9x4(dst,src,size) mpn_divexact_1(dst,src,size,CNST_LIMB(9)<<2)
+#endif
+#endif
+
+#ifndef mpn_divexact_by42525
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1 && defined(BINVERT_42525)
+#define mpn_divexact_by42525(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(42525),BINVERT_42525,0)
+#else
+#define mpn_divexact_by42525(dst,src,size) mpn_divexact_1(dst,src,size,CNST_LIMB(42525))
+#endif
+#endif
+
+#ifndef mpn_divexact_by2835x4
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1 && defined(BINVERT_2835)
+#define mpn_divexact_by2835x4(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(2835),BINVERT_2835,2)
+#else
+#define mpn_divexact_by2835x4(dst,src,size) mpn_divexact_1(dst,src,size,CNST_LIMB(2835)<<2)
+#endif
+#endif
+
+/* Interpolation for Toom-6.5 (or Toom-6), using the evaluation
+ points: infinity(6.5 only), +-4, +-2, +-1, +-1/4, +-1/2, 0. More precisely,
+ we want to compute f(2^(GMP_NUMB_BITS * n)) for a polynomial f of
+ degree 11 (or 10), given the 12 (rsp. 11) values:
+
+ r0 = limit at infinity of f(x) / x^7,
+ r1 = f(4),f(-4),
+ r2 = f(2),f(-2),
+ r3 = f(1),f(-1),
+ r4 = f(1/4),f(-1/4),
+ r5 = f(1/2),f(-1/2),
+ r6 = f(0).
+
+ All couples of the form f(n),f(-n) must be already mixed with
+ toom_couple_handling(f(n),...,f(-n),...)
+
+ The result is stored in {pp, spt + 7*n (or 6*n)}.
+ At entry, r6 is stored at {pp, 2n},
+ r4 is stored at {pp + 3n, 3n + 1}.
+ r2 is stored at {pp + 7n, 3n + 1}.
+ r0 is stored at {pp +11n, spt}.
+
+ The other values are 3n+1 limbs each (with most significant limbs small).
+
+ Negative intermediate results are stored two-complemented.
+ Inputs are destroyed.
+*/
+
+void
+mpn_toom_interpolate_12pts (mp_ptr pp, mp_ptr r1, mp_ptr r3, mp_ptr r5,
+ mp_size_t n, mp_size_t spt, int half, mp_ptr wsi)
+{
+ mp_limb_t cy;
+ mp_size_t n3;
+ mp_size_t n3p1;
+ n3 = 3 * n;
+ n3p1 = n3 + 1;
+
+#define r4 (pp + n3) /* 3n+1 */
+#define r2 (pp + 7 * n) /* 3n+1 */
+#define r0 (pp +11 * n) /* s+t <= 2*n */
+
+ /******************************* interpolation *****************************/
+ if (half != 0) {
+ cy = mpn_sub_n (r3, r3, r0, spt);
+ MPN_DECR_U (r3 + spt, n3p1 - spt, cy);
+
+ cy = DO_mpn_sublsh_n (r2, r0, spt, 10, wsi);
+ MPN_DECR_U (r2 + spt, n3p1 - spt, cy);
+ DO_mpn_subrsh(r5, n3p1, r0, spt, 2, wsi);
+
+ cy = DO_mpn_sublsh_n (r1, r0, spt, 20, wsi);
+ MPN_DECR_U (r1 + spt, n3p1 - spt, cy);
+ DO_mpn_subrsh(r4, n3p1, r0, spt, 4, wsi);
+ };
+
+ r4[n3] -= DO_mpn_sublsh_n (r4 + n, pp, 2 * n, 20, wsi);
+ DO_mpn_subrsh(r1 + n, 2 * n + 1, pp, 2 * n, 4, wsi);
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ mpn_add_n_sub_n (r1, r4, r4, r1, n3p1);
+#else
+ ASSERT_NOCARRY(mpn_add_n (wsi, r1, r4, n3p1));
+ mpn_sub_n (r4, r4, r1, n3p1); /* can be negative */
+ MP_PTR_SWAP(r1, wsi);
+#endif
+
+ r5[n3] -= DO_mpn_sublsh_n (r5 + n, pp, 2 * n, 10, wsi);
+ DO_mpn_subrsh(r2 + n, 2 * n + 1, pp, 2 * n, 2, wsi);
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ mpn_add_n_sub_n (r2, r5, r5, r2, n3p1);
+#else
+ mpn_sub_n (wsi, r5, r2, n3p1); /* can be negative */
+ ASSERT_NOCARRY(mpn_add_n (r2, r2, r5, n3p1));
+ MP_PTR_SWAP(r5, wsi);
+#endif
+
+ r3[n3] -= mpn_sub_n (r3+n, r3+n, pp, 2 * n);
+
+#if AORSMUL_FASTER_AORS_AORSLSH
+ mpn_submul_1 (r4, r5, n3p1, 257); /* can be negative */
+#else
+ mpn_sub_n (r4, r4, r5, n3p1); /* can be negative */
+ DO_mpn_sublsh_n (r4, r5, n3p1, 8, wsi); /* can be negative */
+#endif
+ /* A division by 2835x4 follows. Warning: the operand can be negative! */
+ mpn_divexact_by2835x4(r4, r4, n3p1);
+ if ((r4[n3] & (GMP_NUMB_MAX << (GMP_NUMB_BITS-3))) != 0)
+ r4[n3] |= (GMP_NUMB_MAX << (GMP_NUMB_BITS-2));
+
+#if AORSMUL_FASTER_2AORSLSH
+ mpn_addmul_1 (r5, r4, n3p1, 60); /* can be negative */
+#else
+ DO_mpn_sublsh_n (r5, r4, n3p1, 2, wsi); /* can be negative */
+ DO_mpn_addlsh_n (r5, r4, n3p1, 6, wsi); /* can give a carry */
+#endif
+ mpn_divexact_by255(r5, r5, n3p1);
+
+ ASSERT_NOCARRY(DO_mpn_sublsh_n (r2, r3, n3p1, 5, wsi));
+
+#if AORSMUL_FASTER_3AORSLSH
+ ASSERT_NOCARRY(mpn_submul_1 (r1, r2, n3p1, 100));
+#else
+ ASSERT_NOCARRY(DO_mpn_sublsh_n (r1, r2, n3p1, 6, wsi));
+ ASSERT_NOCARRY(DO_mpn_sublsh_n (r1, r2, n3p1, 5, wsi));
+ ASSERT_NOCARRY(DO_mpn_sublsh_n (r1, r2, n3p1, 2, wsi));
+#endif
+ ASSERT_NOCARRY(DO_mpn_sublsh_n (r1, r3, n3p1, 9, wsi));
+ mpn_divexact_by42525(r1, r1, n3p1);
+
+#if AORSMUL_FASTER_AORS_2AORSLSH
+ ASSERT_NOCARRY(mpn_submul_1 (r2, r1, n3p1, 225));
+#else
+ ASSERT_NOCARRY(mpn_sub_n (r2, r2, r1, n3p1));
+ ASSERT_NOCARRY(DO_mpn_addlsh_n (r2, r1, n3p1, 5, wsi));
+ ASSERT_NOCARRY(DO_mpn_sublsh_n (r2, r1, n3p1, 8, wsi));
+#endif
+ mpn_divexact_by9x4(r2, r2, n3p1);
+
+ ASSERT_NOCARRY(mpn_sub_n (r3, r3, r2, n3p1));
+
+ mpn_sub_n (r4, r2, r4, n3p1);
+ ASSERT_NOCARRY(mpn_rshift(r4, r4, n3p1, 1));
+ ASSERT_NOCARRY(mpn_sub_n (r2, r2, r4, n3p1));
+
+ mpn_add_n (r5, r5, r1, n3p1);
+ ASSERT_NOCARRY(mpn_rshift(r5, r5, n3p1, 1));
+
+ /* last interpolation steps... */
+ ASSERT_NOCARRY(mpn_sub_n (r3, r3, r1, n3p1));
+ ASSERT_NOCARRY(mpn_sub_n (r1, r1, r5, n3p1));
+ /* ... could be mixed with recomposition
+ ||H-r5|M-r5|L-r5| ||H-r1|M-r1|L-r1|
+ */
+
+ /***************************** recomposition *******************************/
+ /*
+ pp[] prior to operations:
+ |M r0|L r0|___||H r2|M r2|L r2|___||H r4|M r4|L r4|____|H_r6|L r6|pp
+
+ summation scheme for remaining operations:
+ |__12|n_11|n_10|n__9|n__8|n__7|n__6|n__5|n__4|n__3|n__2|n___|n___|pp
+ |M r0|L r0|___||H r2|M r2|L r2|___||H r4|M r4|L r4|____|H_r6|L r6|pp
+ ||H r1|M r1|L r1| ||H r3|M r3|L r3| ||H_r5|M_r5|L_r5|
+ */
+
+ cy = mpn_add_n (pp + n, pp + n, r5, n);
+ cy = mpn_add_1 (pp + 2 * n, r5 + n, n, cy);
+#if HAVE_NATIVE_mpn_add_nc
+ cy = r5[n3] + mpn_add_nc(pp + n3, pp + n3, r5 + 2 * n, n, cy);
+#else
+ MPN_INCR_U (r5 + 2 * n, n + 1, cy);
+ cy = r5[n3] + mpn_add_n (pp + n3, pp + n3, r5 + 2 * n, n);
+#endif
+ MPN_INCR_U (pp + n3 + n, 2 * n + 1, cy);
+
+ pp[2 * n3]+= mpn_add_n (pp + 5 * n, pp + 5 * n, r3, n);
+ cy = mpn_add_1 (pp + 2 * n3, r3 + n, n, pp[2 * n3]);
+#if HAVE_NATIVE_mpn_add_nc
+ cy = r3[n3] + mpn_add_nc(pp + 7 * n, pp + 7 * n, r3 + 2 * n, n, cy);
+#else
+ MPN_INCR_U (r3 + 2 * n, n + 1, cy);
+ cy = r3[n3] + mpn_add_n (pp + 7 * n, pp + 7 * n, r3 + 2 * n, n);
+#endif
+ MPN_INCR_U (pp + 8 * n, 2 * n + 1, cy);
+
+ pp[10*n]+=mpn_add_n (pp + 9 * n, pp + 9 * n, r1, n);
+ if (half) {
+ cy = mpn_add_1 (pp + 10 * n, r1 + n, n, pp[10 * n]);
+#if HAVE_NATIVE_mpn_add_nc
+ if (LIKELY (spt > n)) {
+ cy = r1[n3] + mpn_add_nc(pp + 11 * n, pp + 11 * n, r1 + 2 * n, n, cy);
+ MPN_INCR_U (pp + 4 * n3, spt - n, cy);
+ } else {
+ ASSERT_NOCARRY(mpn_add_nc(pp + 11 * n, pp + 11 * n, r1 + 2 * n, spt, cy));
+ }
+#else
+ MPN_INCR_U (r1 + 2 * n, n + 1, cy);
+ if (LIKELY (spt > n)) {
+ cy = r1[n3] + mpn_add_n (pp + 11 * n, pp + 11 * n, r1 + 2 * n, n);
+ MPN_INCR_U (pp + 4 * n3, spt - n, cy);
+ } else {
+ ASSERT_NOCARRY(mpn_add_n (pp + 11 * n, pp + 11 * n, r1 + 2 * n, spt));
+ }
+#endif
+ } else {
+ ASSERT_NOCARRY(mpn_add_1 (pp + 10 * n, r1 + n, spt, pp[10 * n]));
+ }
+
+#undef r0
+#undef r2
+#undef r4
+}
diff --git a/gmp/mpn/generic/toom_interpolate_16pts.c b/gmp/mpn/generic/toom_interpolate_16pts.c
new file mode 100644
index 0000000000..5afe6641f6
--- /dev/null
+++ b/gmp/mpn/generic/toom_interpolate_16pts.c
@@ -0,0 +1,527 @@
+/* Interpolation for the algorithm Toom-Cook 8.5-way.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if GMP_NUMB_BITS < 29
+#error Not implemented: Both sublsh_n(,,,28) should be corrected; r2 and r5 need one more LIMB.
+#endif
+
+#if GMP_NUMB_BITS < 28
+#error Not implemented: divexact_by188513325 and _by182712915 will not work.
+#endif
+
+
+#if HAVE_NATIVE_mpn_sublsh_n
+#define DO_mpn_sublsh_n(dst,src,n,s,ws) mpn_sublsh_n(dst,dst,src,n,s)
+#else
+static mp_limb_t
+DO_mpn_sublsh_n(mp_ptr dst, mp_srcptr src, mp_size_t n, unsigned int s, mp_ptr ws)
+{
+#if USE_MUL_1 && 0
+ return mpn_submul_1(dst,src,n,CNST_LIMB(1) <<(s));
+#else
+ mp_limb_t __cy;
+ __cy = mpn_lshift(ws,src,n,s);
+ return __cy + mpn_sub_n(dst,dst,ws,n);
+#endif
+}
+#endif
+
+#if HAVE_NATIVE_mpn_addlsh_n
+#define DO_mpn_addlsh_n(dst,src,n,s,ws) mpn_addlsh_n(dst,dst,src,n,s)
+#else
+static mp_limb_t
+DO_mpn_addlsh_n(mp_ptr dst, mp_srcptr src, mp_size_t n, unsigned int s, mp_ptr ws)
+{
+#if USE_MUL_1 && 0
+ return mpn_addmul_1(dst,src,n,CNST_LIMB(1) <<(s));
+#else
+ mp_limb_t __cy;
+ __cy = mpn_lshift(ws,src,n,s);
+ return __cy + mpn_add_n(dst,dst,ws,n);
+#endif
+}
+#endif
+
+#if HAVE_NATIVE_mpn_subrsh
+#define DO_mpn_subrsh(dst,nd,src,ns,s,ws) mpn_subrsh(dst,nd,src,ns,s)
+#else
+/* FIXME: This is not a correct definition, it assumes no carry */
+#define DO_mpn_subrsh(dst,nd,src,ns,s,ws) \
+do { \
+ mp_limb_t __cy; \
+ MPN_DECR_U (dst, nd, src[0] >> s); \
+ __cy = DO_mpn_sublsh_n (dst, src + 1, ns - 1, GMP_NUMB_BITS - s, ws); \
+ MPN_DECR_U (dst + ns - 1, nd - ns + 1, __cy); \
+} while (0)
+#endif
+
+
+/* FIXME: tuneup should decide the best variant */
+#ifndef AORSMUL_FASTER_AORS_AORSLSH
+#define AORSMUL_FASTER_AORS_AORSLSH 1
+#endif
+#ifndef AORSMUL_FASTER_AORS_2AORSLSH
+#define AORSMUL_FASTER_AORS_2AORSLSH 1
+#endif
+#ifndef AORSMUL_FASTER_2AORSLSH
+#define AORSMUL_FASTER_2AORSLSH 1
+#endif
+#ifndef AORSMUL_FASTER_3AORSLSH
+#define AORSMUL_FASTER_3AORSLSH 1
+#endif
+
+#if GMP_NUMB_BITS < 43
+#define BIT_CORRECTION 1
+#define CORRECTION_BITS GMP_NUMB_BITS
+#else
+#define BIT_CORRECTION 0
+#define CORRECTION_BITS 0
+#endif
+
+#define BINVERT_9 \
+ ((((GMP_NUMB_MAX / 9) << (6 - GMP_NUMB_BITS % 6)) * 8 & GMP_NUMB_MAX) | 0x39)
+
+#define BINVERT_255 \
+ (GMP_NUMB_MAX - ((GMP_NUMB_MAX / 255) << (8 - GMP_NUMB_BITS % 8)))
+
+ /* FIXME: find some more general expressions for inverses */
+#if GMP_LIMB_BITS == 32
+#define BINVERT_2835 (GMP_NUMB_MASK & CNST_LIMB(0x53E3771B))
+#define BINVERT_42525 (GMP_NUMB_MASK & CNST_LIMB(0x9F314C35))
+#define BINVERT_182712915 (GMP_NUMB_MASK & CNST_LIMB(0x550659DB))
+#define BINVERT_188513325 (GMP_NUMB_MASK & CNST_LIMB(0xFBC333A5))
+#define BINVERT_255x182712915L (GMP_NUMB_MASK & CNST_LIMB(0x6FC4CB25))
+#define BINVERT_255x188513325L (GMP_NUMB_MASK & CNST_LIMB(0x6864275B))
+#if GMP_NAIL_BITS == 0
+#define BINVERT_255x182712915H CNST_LIMB(0x1B649A07)
+#define BINVERT_255x188513325H CNST_LIMB(0x06DB993A)
+#else /* GMP_NAIL_BITS != 0 */
+#define BINVERT_255x182712915H \
+ (GMP_NUMB_MASK & CNST_LIMB((0x1B649A07<<GMP_NAIL_BITS) | (0x6FC4CB25>>GMP_NUMB_BITS)))
+#define BINVERT_255x188513325H \
+ (GMP_NUMB_MASK & CNST_LIMB((0x06DB993A<<GMP_NAIL_BITS) | (0x6864275B>>GMP_NUMB_BITS)))
+#endif
+#else
+#if GMP_LIMB_BITS == 64
+#define BINVERT_2835 (GMP_NUMB_MASK & CNST_LIMB(0x938CC70553E3771B))
+#define BINVERT_42525 (GMP_NUMB_MASK & CNST_LIMB(0xE7B40D449F314C35))
+#define BINVERT_255x182712915 (GMP_NUMB_MASK & CNST_LIMB(0x1B649A076FC4CB25))
+#define BINVERT_255x188513325 (GMP_NUMB_MASK & CNST_LIMB(0x06DB993A6864275B))
+#endif
+#endif
+
+#ifndef mpn_divexact_by255
+#if GMP_NUMB_BITS % 8 == 0
+#define mpn_divexact_by255(dst,src,size) \
+ (255 & 1 * mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 255)))
+#else
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by255(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(255),BINVERT_255,0)
+#else
+#define mpn_divexact_by255(dst,src,size) mpn_divexact_1(dst,src,size,CNST_LIMB(255))
+#endif
+#endif
+#endif
+
+#ifndef mpn_divexact_by255x4
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by255x4(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(255),BINVERT_255,2)
+#else
+#define mpn_divexact_by255x4(dst,src,size) mpn_divexact_1(dst,src,size,CNST_LIMB(255)<<2)
+#endif
+#endif
+
+#ifndef mpn_divexact_by9x16
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by9x16(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(9),BINVERT_9,4)
+#else
+#define mpn_divexact_by9x16(dst,src,size) mpn_divexact_1(dst,src,size,CNST_LIMB(9)<<4)
+#endif
+#endif
+
+#ifndef mpn_divexact_by42525x16
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1 && defined(BINVERT_42525)
+#define mpn_divexact_by42525x16(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(42525),BINVERT_42525,4)
+#else
+#define mpn_divexact_by42525x16(dst,src,size) mpn_divexact_1(dst,src,size,CNST_LIMB(42525)<<4)
+#endif
+#endif
+
+#ifndef mpn_divexact_by2835x64
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1 && defined(BINVERT_2835)
+#define mpn_divexact_by2835x64(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(2835),BINVERT_2835,6)
+#else
+#define mpn_divexact_by2835x64(dst,src,size) mpn_divexact_1(dst,src,size,CNST_LIMB(2835)<<6)
+#endif
+#endif
+
+#ifndef mpn_divexact_by255x182712915
+#if GMP_NUMB_BITS < 36
+#if HAVE_NATIVE_mpn_bdiv_q_2_pi2 && defined(BINVERT_255x182712915H)
+/* FIXME: use mpn_bdiv_q_2_pi2 */
+#endif
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1 && defined(BINVERT_182712915)
+#define mpn_divexact_by255x182712915(dst,src,size) \
+ do { \
+ mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(182712915),BINVERT_182712915,0); \
+ mpn_divexact_by255(dst,dst,size); \
+ } while(0)
+#else
+#define mpn_divexact_by255x182712915(dst,src,size) \
+ do { \
+ mpn_divexact_1(dst,src,size,CNST_LIMB(182712915)); \
+ mpn_divexact_by255(dst,dst,size); \
+ } while(0)
+#endif
+#else /* GMP_NUMB_BITS > 35 */
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1 && defined(BINVERT_255x182712915)
+#define mpn_divexact_by255x182712915(dst,src,size) \
+ mpn_pi1_bdiv_q_1(dst,src,size,255*CNST_LIMB(182712915),BINVERT_255x182712915,0)
+#else
+#define mpn_divexact_by255x182712915(dst,src,size) mpn_divexact_1(dst,src,size,255*CNST_LIMB(182712915))
+#endif
+#endif /* GMP_NUMB_BITS >?< 36 */
+#endif
+
+#ifndef mpn_divexact_by255x188513325
+#if GMP_NUMB_BITS < 36
+#if HAVE_NATIVE_mpn_bdiv_q_1_pi2 && defined(BINVERT_255x188513325H)
+/* FIXME: use mpn_bdiv_q_1_pi2 */
+#endif
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1 && defined(BINVERT_188513325)
+#define mpn_divexact_by255x188513325(dst,src,size) \
+ do { \
+ mpn_pi1_bdiv_q_1(dst,src,size,CNST_LIMB(188513325),BINVERT_188513325,0); \
+ mpn_divexact_by255(dst,dst,size); \
+ } while(0)
+#else
+#define mpn_divexact_by255x188513325(dst,src,size) \
+ do { \
+ mpn_divexact_1(dst,src,size,CNST_LIMB(188513325)); \
+ mpn_divexact_by255(dst,dst,size); \
+ } while(0)
+#endif
+#else /* GMP_NUMB_BITS > 35 */
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1 && defined(BINVERT_255x188513325)
+#define mpn_divexact_by255x188513325(dst,src,size) \
+ mpn_pi1_bdiv_q_1(dst,src,size,255*CNST_LIMB(188513325),BINVERT_255x188513325,0)
+#else
+#define mpn_divexact_by255x188513325(dst,src,size) mpn_divexact_1(dst,src,size,255*CNST_LIMB(188513325))
+#endif
+#endif /* GMP_NUMB_BITS >?< 36 */
+#endif
+
+/* Interpolation for Toom-8.5 (or Toom-8), using the evaluation
+ points: infinity(8.5 only), +-8, +-4, +-2, +-1, +-1/4, +-1/2,
+ +-1/8, 0. More precisely, we want to compute
+ f(2^(GMP_NUMB_BITS * n)) for a polynomial f of degree 15 (or
+ 14), given the 16 (rsp. 15) values:
+
+ r0 = limit at infinity of f(x) / x^7,
+ r1 = f(8),f(-8),
+ r2 = f(4),f(-4),
+ r3 = f(2),f(-2),
+ r4 = f(1),f(-1),
+ r5 = f(1/4),f(-1/4),
+ r6 = f(1/2),f(-1/2),
+ r7 = f(1/8),f(-1/8),
+ r8 = f(0).
+
+ All couples of the form f(n),f(-n) must be already mixed with
+ toom_couple_handling(f(n),...,f(-n),...)
+
+ The result is stored in {pp, spt + 7*n (or 8*n)}.
+ At entry, r8 is stored at {pp, 2n},
+ r6 is stored at {pp + 3n, 3n + 1}.
+ r4 is stored at {pp + 7n, 3n + 1}.
+ r2 is stored at {pp +11n, 3n + 1}.
+ r0 is stored at {pp +15n, spt}.
+
+ The other values are 3n+1 limbs each (with most significant limbs small).
+
+ Negative intermediate results are stored two-complemented.
+ Inputs are destroyed.
+*/
+
+void
+mpn_toom_interpolate_16pts (mp_ptr pp, mp_ptr r1, mp_ptr r3, mp_ptr r5, mp_ptr r7,
+ mp_size_t n, mp_size_t spt, int half, mp_ptr wsi)
+{
+ mp_limb_t cy;
+ mp_size_t n3;
+ mp_size_t n3p1;
+ n3 = 3 * n;
+ n3p1 = n3 + 1;
+
+#define r6 (pp + n3) /* 3n+1 */
+#define r4 (pp + 7 * n) /* 3n+1 */
+#define r2 (pp +11 * n) /* 3n+1 */
+#define r0 (pp +15 * n) /* s+t <= 2*n */
+
+ ASSERT( spt <= 2 * n );
+ /******************************* interpolation *****************************/
+ if( half != 0) {
+ cy = mpn_sub_n (r4, r4, r0, spt);
+ MPN_DECR_U (r4 + spt, n3p1 - spt, cy);
+
+ cy = DO_mpn_sublsh_n (r3, r0, spt, 14, wsi);
+ MPN_DECR_U (r3 + spt, n3p1 - spt, cy);
+ DO_mpn_subrsh(r6, n3p1, r0, spt, 2, wsi);
+
+ cy = DO_mpn_sublsh_n (r2, r0, spt, 28, wsi);
+ MPN_DECR_U (r2 + spt, n3p1 - spt, cy);
+ DO_mpn_subrsh(r5, n3p1, r0, spt, 4, wsi);
+
+ cy = DO_mpn_sublsh_n (r1 + BIT_CORRECTION, r0, spt, 42 - CORRECTION_BITS, wsi);
+#if BIT_CORRECTION
+ cy = mpn_sub_1 (r1 + spt + BIT_CORRECTION, r1 + spt + BIT_CORRECTION,
+ n3p1 - spt - BIT_CORRECTION, cy);
+ ASSERT (BIT_CORRECTION > 0 || cy == 0);
+ /* FIXME: assumes r7[n3p1] is writable (it is if r5 follows). */
+ cy = r7[n3p1];
+ r7[n3p1] = 0x80;
+#else
+ MPN_DECR_U (r1 + spt + BIT_CORRECTION, n3p1 - spt - BIT_CORRECTION, cy);
+#endif
+ DO_mpn_subrsh(r7, n3p1 + BIT_CORRECTION, r0, spt, 6, wsi);
+#if BIT_CORRECTION
+ /* FIXME: assumes r7[n3p1] is writable. */
+ ASSERT ( BIT_CORRECTION > 0 || r7[n3p1] == 0x80 );
+ r7[n3p1] = cy;
+#endif
+ };
+
+ r5[n3] -= DO_mpn_sublsh_n (r5 + n, pp, 2 * n, 28, wsi);
+ DO_mpn_subrsh(r2 + n, 2 * n + 1, pp, 2 * n, 4, wsi);
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ mpn_add_n_sub_n (r2, r5, r5, r2, n3p1);
+#else
+ mpn_sub_n (wsi, r5, r2, n3p1); /* can be negative */
+ ASSERT_NOCARRY(mpn_add_n (r2, r2, r5, n3p1));
+ MP_PTR_SWAP(r5, wsi);
+#endif
+
+ r6[n3] -= DO_mpn_sublsh_n (r6 + n, pp, 2 * n, 14, wsi);
+ DO_mpn_subrsh(r3 + n, 2 * n + 1, pp, 2 * n, 2, wsi);
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ mpn_add_n_sub_n (r3, r6, r6, r3, n3p1);
+#else
+ ASSERT_NOCARRY(mpn_add_n (wsi, r3, r6, n3p1));
+ mpn_sub_n (r6, r6, r3, n3p1); /* can be negative */
+ MP_PTR_SWAP(r3, wsi);
+#endif
+
+ cy = DO_mpn_sublsh_n (r7 + n + BIT_CORRECTION, pp, 2 * n, 42 - CORRECTION_BITS, wsi);
+#if BIT_CORRECTION
+ MPN_DECR_U (r1 + n, 2 * n + 1, pp[0] >> 6);
+ cy = DO_mpn_sublsh_n (r1 + n, pp + 1, 2 * n - 1, GMP_NUMB_BITS - 6, wsi);
+ cy = mpn_sub_1(r1 + 3 * n - 1, r1 + 3 * n - 1, 2, cy);
+ ASSERT ( BIT_CORRECTION > 0 || cy != 0 );
+#else
+ r7[n3] -= cy;
+ DO_mpn_subrsh(r1 + n, 2 * n + 1, pp, 2 * n, 6, wsi);
+#endif
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ mpn_add_n_sub_n (r1, r7, r7, r1, n3p1);
+#else
+ mpn_sub_n (wsi, r7, r1, n3p1); /* can be negative */
+ mpn_add_n (r1, r1, r7, n3p1); /* if BIT_CORRECTION != 0, can give a carry. */
+ MP_PTR_SWAP(r7, wsi);
+#endif
+
+ r4[n3] -= mpn_sub_n (r4+n, r4+n, pp, 2 * n);
+
+#if AORSMUL_FASTER_2AORSLSH
+ mpn_submul_1 (r5, r6, n3p1, 1028); /* can be negative */
+#else
+ DO_mpn_sublsh_n (r5, r6, n3p1, 2, wsi); /* can be negative */
+ DO_mpn_sublsh_n (r5, r6, n3p1,10, wsi); /* can be negative */
+#endif
+
+ mpn_submul_1 (r7, r5, n3p1, 1300); /* can be negative */
+#if AORSMUL_FASTER_3AORSLSH
+ mpn_submul_1 (r7, r6, n3p1, 1052688); /* can be negative */
+#else
+ DO_mpn_sublsh_n (r7, r6, n3p1, 4, wsi); /* can be negative */
+ DO_mpn_sublsh_n (r7, r6, n3p1,12, wsi); /* can be negative */
+ DO_mpn_sublsh_n (r7, r6, n3p1,20, wsi); /* can be negative */
+#endif
+ mpn_divexact_by255x188513325(r7, r7, n3p1);
+
+ mpn_submul_1 (r5, r7, n3p1, 12567555); /* can be negative */
+ /* A division by 2835x64 follows. Warning: the operand can be negative! */
+ mpn_divexact_by2835x64(r5, r5, n3p1);
+ if ((r5[n3] & (GMP_NUMB_MAX << (GMP_NUMB_BITS-7))) != 0)
+ r5[n3] |= (GMP_NUMB_MAX << (GMP_NUMB_BITS-6));
+
+#if AORSMUL_FASTER_AORS_AORSLSH
+ mpn_submul_1 (r6, r7, n3p1, 4095); /* can be negative */
+#else
+ mpn_add_n (r6, r6, r7, n3p1); /* can give a carry */
+ DO_mpn_sublsh_n (r6, r7, n3p1, 12, wsi); /* can be negative */
+#endif
+#if AORSMUL_FASTER_2AORSLSH
+ mpn_addmul_1 (r6, r5, n3p1, 240); /* can be negative */
+#else
+ DO_mpn_addlsh_n (r6, r5, n3p1, 8, wsi); /* can give a carry */
+ DO_mpn_sublsh_n (r6, r5, n3p1, 4, wsi); /* can be negative */
+#endif
+ /* A division by 255x4 follows. Warning: the operand can be negative! */
+ mpn_divexact_by255x4(r6, r6, n3p1);
+ if ((r6[n3] & (GMP_NUMB_MAX << (GMP_NUMB_BITS-3))) != 0)
+ r6[n3] |= (GMP_NUMB_MAX << (GMP_NUMB_BITS-2));
+
+ ASSERT_NOCARRY(DO_mpn_sublsh_n (r3, r4, n3p1, 7, wsi));
+
+ ASSERT_NOCARRY(DO_mpn_sublsh_n (r2, r4, n3p1, 13, wsi));
+ ASSERT_NOCARRY(mpn_submul_1 (r2, r3, n3p1, 400));
+
+ /* If GMP_NUMB_BITS < 42 next operations on r1 can give a carry!*/
+ DO_mpn_sublsh_n (r1, r4, n3p1, 19, wsi);
+ mpn_submul_1 (r1, r2, n3p1, 1428);
+ mpn_submul_1 (r1, r3, n3p1, 112896);
+ mpn_divexact_by255x182712915(r1, r1, n3p1);
+
+ ASSERT_NOCARRY(mpn_submul_1 (r2, r1, n3p1, 15181425));
+ mpn_divexact_by42525x16(r2, r2, n3p1);
+
+#if AORSMUL_FASTER_AORS_2AORSLSH
+ ASSERT_NOCARRY(mpn_submul_1 (r3, r1, n3p1, 3969));
+#else
+ ASSERT_NOCARRY(mpn_sub_n (r3, r3, r1, n3p1));
+ ASSERT_NOCARRY(DO_mpn_addlsh_n (r3, r1, n3p1, 7, wsi));
+ ASSERT_NOCARRY(DO_mpn_sublsh_n (r3, r1, n3p1, 12, wsi));
+#endif
+ ASSERT_NOCARRY(mpn_submul_1 (r3, r2, n3p1, 900));
+ mpn_divexact_by9x16(r3, r3, n3p1);
+
+ ASSERT_NOCARRY(mpn_sub_n (r4, r4, r1, n3p1));
+ ASSERT_NOCARRY(mpn_sub_n (r4, r4, r3, n3p1));
+ ASSERT_NOCARRY(mpn_sub_n (r4, r4, r2, n3p1));
+
+ mpn_add_n (r6, r2, r6, n3p1);
+ ASSERT_NOCARRY(mpn_rshift(r6, r6, n3p1, 1));
+ ASSERT_NOCARRY(mpn_sub_n (r2, r2, r6, n3p1));
+
+ mpn_sub_n (r5, r3, r5, n3p1);
+ ASSERT_NOCARRY(mpn_rshift(r5, r5, n3p1, 1));
+ ASSERT_NOCARRY(mpn_sub_n (r3, r3, r5, n3p1));
+
+ mpn_add_n (r7, r1, r7, n3p1);
+ ASSERT_NOCARRY(mpn_rshift(r7, r7, n3p1, 1));
+ ASSERT_NOCARRY(mpn_sub_n (r1, r1, r7, n3p1));
+
+ /* last interpolation steps... */
+ /* ... could be mixed with recomposition
+ ||H-r7|M-r7|L-r7| ||H-r5|M-r5|L-r5|
+ */
+
+ /***************************** recomposition *******************************/
+ /*
+ pp[] prior to operations:
+ |M r0|L r0|___||H r2|M r2|L r2|___||H r4|M r4|L r4|___||H r6|M r6|L r6|____|H_r8|L r8|pp
+
+ summation scheme for remaining operations:
+ |__16|n_15|n_14|n_13|n_12|n_11|n_10|n__9|n__8|n__7|n__6|n__5|n__4|n__3|n__2|n___|n___|pp
+ |M r0|L r0|___||H r2|M r2|L r2|___||H r4|M r4|L r4|___||H r6|M r6|L r6|____|H_r8|L r8|pp
+ ||H r1|M r1|L r1| ||H r3|M r3|L r3| ||H_r5|M_r5|L_r5| ||H r7|M r7|L r7|
+ */
+
+ cy = mpn_add_n (pp + n, pp + n, r7, n);
+ cy = mpn_add_1 (pp + 2 * n, r7 + n, n, cy);
+#if HAVE_NATIVE_mpn_add_nc
+ cy = r7[n3] + mpn_add_nc(pp + n3, pp + n3, r7 + 2 * n, n, cy);
+#else
+ MPN_INCR_U (r7 + 2 * n, n + 1, cy);
+ cy = r7[n3] + mpn_add_n (pp + n3, pp + n3, r7 + 2 * n, n);
+#endif
+ MPN_INCR_U (pp + 4 * n, 2 * n + 1, cy);
+
+ pp[2 * n3]+= mpn_add_n (pp + 5 * n, pp + 5 * n, r5, n);
+ cy = mpn_add_1 (pp + 2 * n3, r5 + n, n, pp[2 * n3]);
+#if HAVE_NATIVE_mpn_add_nc
+ cy = r5[n3] + mpn_add_nc(pp + 7 * n, pp + 7 * n, r5 + 2 * n, n, cy);
+#else
+ MPN_INCR_U (r5 + 2 * n, n + 1, cy);
+ cy = r5[n3] + mpn_add_n (pp + 7 * n, pp + 7 * n, r5 + 2 * n, n);
+#endif
+ MPN_INCR_U (pp + 8 * n, 2 * n + 1, cy);
+
+ pp[10 * n]+= mpn_add_n (pp + 9 * n, pp + 9 * n, r3, n);
+ cy = mpn_add_1 (pp + 10 * n, r3 + n, n, pp[10 * n]);
+#if HAVE_NATIVE_mpn_add_nc
+ cy = r3[n3] + mpn_add_nc(pp +11 * n, pp +11 * n, r3 + 2 * n, n, cy);
+#else
+ MPN_INCR_U (r3 + 2 * n, n + 1, cy);
+ cy = r3[n3] + mpn_add_n (pp +11 * n, pp +11 * n, r3 + 2 * n, n);
+#endif
+ MPN_INCR_U (pp +12 * n, 2 * n + 1, cy);
+
+ pp[14 * n]+=mpn_add_n (pp +13 * n, pp +13 * n, r1, n);
+ if ( half ) {
+ cy = mpn_add_1 (pp + 14 * n, r1 + n, n, pp[14 * n]);
+#if HAVE_NATIVE_mpn_add_nc
+ if(LIKELY(spt > n)) {
+ cy = r1[n3] + mpn_add_nc(pp + 15 * n, pp + 15 * n, r1 + 2 * n, n, cy);
+ MPN_INCR_U (pp + 16 * n, spt - n, cy);
+ } else {
+ ASSERT_NOCARRY(mpn_add_nc(pp + 15 * n, pp + 15 * n, r1 + 2 * n, spt, cy));
+ }
+#else
+ MPN_INCR_U (r1 + 2 * n, n + 1, cy);
+ if(LIKELY(spt > n)) {
+ cy = r1[n3] + mpn_add_n (pp + 15 * n, pp + 15 * n, r1 + 2 * n, n);
+ MPN_INCR_U (pp + 16 * n, spt - n, cy);
+ } else {
+ ASSERT_NOCARRY(mpn_add_n (pp + 15 * n, pp + 15 * n, r1 + 2 * n, spt));
+ }
+#endif
+ } else {
+ ASSERT_NOCARRY(mpn_add_1 (pp + 14 * n, r1 + n, spt, pp[14 * n]));
+ }
+
+#undef r0
+#undef r2
+#undef r4
+#undef r6
+}
diff --git a/gmp/mpn/generic/toom_interpolate_5pts.c b/gmp/mpn/generic/toom_interpolate_5pts.c
new file mode 100644
index 0000000000..9fa5f0b7a6
--- /dev/null
+++ b/gmp/mpn/generic/toom_interpolate_5pts.c
@@ -0,0 +1,199 @@
+/* mpn_toom_interpolate_5pts -- Interpolate for toom3, 33, 42.
+
+ Contributed to the GNU project by Robert Harley.
+ Improvements by Paul Zimmermann and Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2000-2003, 2005-2007, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_toom_interpolate_5pts (mp_ptr c, mp_ptr v2, mp_ptr vm1,
+ mp_size_t k, mp_size_t twor, int sa,
+ mp_limb_t vinf0)
+{
+ mp_limb_t cy, saved;
+ mp_size_t twok;
+ mp_size_t kk1;
+ mp_ptr c1, v1, c3, vinf;
+
+ twok = k + k;
+ kk1 = twok + 1;
+
+ c1 = c + k;
+ v1 = c1 + k;
+ c3 = v1 + k;
+ vinf = c3 + k;
+
+#define v0 (c)
+ /* (1) v2 <- v2-vm1 < v2+|vm1|, (16 8 4 2 1) - (1 -1 1 -1 1) =
+ thus 0 <= v2 < 50*B^(2k) < 2^6*B^(2k) (15 9 3 3 0)
+ */
+ if (sa)
+ ASSERT_NOCARRY (mpn_add_n (v2, v2, vm1, kk1));
+ else
+ ASSERT_NOCARRY (mpn_sub_n (v2, v2, vm1, kk1));
+
+ /* {c,2k} {c+2k,2k+1} {c+4k+1,2r-1} {t,2k+1} {t+2k+1,2k+1} {t+4k+2,2r}
+ v0 v1 hi(vinf) |vm1| v2-vm1 EMPTY */
+
+ ASSERT_NOCARRY (mpn_divexact_by3 (v2, v2, kk1)); /* v2 <- v2 / 3 */
+ /* (5 3 1 1 0)*/
+
+ /* {c,2k} {c+2k,2k+1} {c+4k+1,2r-1} {t,2k+1} {t+2k+1,2k+1} {t+4k+2,2r}
+ v0 v1 hi(vinf) |vm1| (v2-vm1)/3 EMPTY */
+
+ /* (2) vm1 <- tm1 := (v1 - vm1) / 2 [(1 1 1 1 1) - (1 -1 1 -1 1)] / 2 =
+ tm1 >= 0 (0 1 0 1 0)
+ No carry comes out from {v1, kk1} +/- {vm1, kk1},
+ and the division by two is exact.
+ If (sa!=0) the sign of vm1 is negative */
+ if (sa)
+ {
+#ifdef HAVE_NATIVE_mpn_rsh1add_n
+ mpn_rsh1add_n (vm1, v1, vm1, kk1);
+#else
+ ASSERT_NOCARRY (mpn_add_n (vm1, v1, vm1, kk1));
+ ASSERT_NOCARRY (mpn_rshift (vm1, vm1, kk1, 1));
+#endif
+ }
+ else
+ {
+#ifdef HAVE_NATIVE_mpn_rsh1sub_n
+ mpn_rsh1sub_n (vm1, v1, vm1, kk1);
+#else
+ ASSERT_NOCARRY (mpn_sub_n (vm1, v1, vm1, kk1));
+ ASSERT_NOCARRY (mpn_rshift (vm1, vm1, kk1, 1));
+#endif
+ }
+
+ /* {c,2k} {c+2k,2k+1} {c+4k+1,2r-1} {t,2k+1} {t+2k+1,2k+1} {t+4k+2,2r}
+ v0 v1 hi(vinf) tm1 (v2-vm1)/3 EMPTY */
+
+ /* (3) v1 <- t1 := v1 - v0 (1 1 1 1 1) - (0 0 0 0 1) = (1 1 1 1 0)
+ t1 >= 0
+ */
+ vinf[0] -= mpn_sub_n (v1, v1, c, twok);
+
+ /* {c,2k} {c+2k,2k+1} {c+4k+1,2r-1} {t,2k+1} {t+2k+1,2k+1} {t+4k+2,2r}
+ v0 v1-v0 hi(vinf) tm1 (v2-vm1)/3 EMPTY */
+
+ /* (4) v2 <- t2 := ((v2-vm1)/3-t1)/2 = (v2-vm1-3*t1)/6
+ t2 >= 0 [(5 3 1 1 0) - (1 1 1 1 0)]/2 = (2 1 0 0 0)
+ */
+#ifdef HAVE_NATIVE_mpn_rsh1sub_n
+ mpn_rsh1sub_n (v2, v2, v1, kk1);
+#else
+ ASSERT_NOCARRY (mpn_sub_n (v2, v2, v1, kk1));
+ ASSERT_NOCARRY (mpn_rshift (v2, v2, kk1, 1));
+#endif
+
+ /* {c,2k} {c+2k,2k+1} {c+4k+1,2r-1} {t,2k+1} {t+2k+1,2k+1} {t+4k+2,2r}
+ v0 v1-v0 hi(vinf) tm1 (v2-vm1-3t1)/6 EMPTY */
+
+ /* (5) v1 <- t1-tm1 (1 1 1 1 0) - (0 1 0 1 0) = (1 0 1 0 0)
+ result is v1 >= 0
+ */
+ ASSERT_NOCARRY (mpn_sub_n (v1, v1, vm1, kk1));
+
+ /* We do not need to read the value in vm1, so we add it in {c+k, ...} */
+ cy = mpn_add_n (c1, c1, vm1, kk1);
+ MPN_INCR_U (c3 + 1, twor + k - 1, cy); /* 2n-(3k+1) = 2r+k-1 */
+ /* Memory allocated for vm1 is now free, it can be recycled ...*/
+
+ /* (6) v2 <- v2 - 2*vinf, (2 1 0 0 0) - 2*(1 0 0 0 0) = (0 1 0 0 0)
+ result is v2 >= 0 */
+ saved = vinf[0]; /* Remember v1's highest byte (will be overwritten). */
+ vinf[0] = vinf0; /* Set the right value for vinf0 */
+#ifdef HAVE_NATIVE_mpn_sublsh1_n_ip1
+ cy = mpn_sublsh1_n_ip1 (v2, vinf, twor);
+#else
+ /* Overwrite unused vm1 */
+ cy = mpn_lshift (vm1, vinf, twor, 1);
+ cy += mpn_sub_n (v2, v2, vm1, twor);
+#endif
+ MPN_DECR_U (v2 + twor, kk1 - twor, cy);
+
+ /* Current matrix is
+ [1 0 0 0 0; vinf
+ 0 1 0 0 0; v2
+ 1 0 1 0 0; v1
+ 0 1 0 1 0; vm1
+ 0 0 0 0 1] v0
+ Some values already are in-place (we added vm1 in the correct position)
+ | vinf| v1 | v0 |
+ | vm1 |
+ One still is in a separated area
+ | +v2 |
+ We have to compute v1-=vinf; vm1 -= v2,
+ |-vinf|
+ | -v2 |
+ Carefully reordering operations we can avoid to compute twice the sum
+ of the high half of v2 plus the low half of vinf.
+ */
+
+ /* Add the high half of t2 in {vinf} */
+ if ( LIKELY(twor > k + 1) ) { /* This is the expected flow */
+ cy = mpn_add_n (vinf, vinf, v2 + k, k + 1);
+ MPN_INCR_U (c3 + kk1, twor - k - 1, cy); /* 2n-(5k+1) = 2r-k-1 */
+ } else { /* triggered only by very unbalanced cases like
+ (k+k+(k-2))x(k+k+1) , should be handled by toom32 */
+ ASSERT_NOCARRY (mpn_add_n (vinf, vinf, v2 + k, twor));
+ }
+ /* (7) v1 <- v1 - vinf, (1 0 1 0 0) - (1 0 0 0 0) = (0 0 1 0 0)
+ result is >= 0 */
+ /* Side effect: we also subtracted (high half) vm1 -= v2 */
+ cy = mpn_sub_n (v1, v1, vinf, twor); /* vinf is at most twor long. */
+ vinf0 = vinf[0]; /* Save again the right value for vinf0 */
+ vinf[0] = saved;
+ MPN_DECR_U (v1 + twor, kk1 - twor, cy); /* Treat the last bytes. */
+
+ /* (8) vm1 <- vm1-v2 (0 1 0 1 0) - (0 1 0 0 0) = (0 0 0 1 0)
+ Operate only on the low half.
+ */
+ cy = mpn_sub_n (c1, c1, v2, k);
+ MPN_DECR_U (v1, kk1, cy);
+
+ /********************* Beginning the final phase **********************/
+
+ /* Most of the recomposition was done */
+
+ /* add t2 in {c+3k, ...}, but only the low half */
+ cy = mpn_add_n (c3, c3, v2, k);
+ vinf[0] += cy;
+ ASSERT(vinf[0] >= cy); /* No carry */
+ MPN_INCR_U (vinf, twor, vinf0); /* Add vinf0, propagate carry. */
+
+#undef v0
+}
diff --git a/gmp/mpn/generic/toom_interpolate_6pts.c b/gmp/mpn/generic/toom_interpolate_6pts.c
new file mode 100644
index 0000000000..bdb2e95b89
--- /dev/null
+++ b/gmp/mpn/generic/toom_interpolate_6pts.c
@@ -0,0 +1,240 @@
+/* mpn_toom_interpolate_6pts -- Interpolate for toom43, 52
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* For odd divisors, mpn_divexact_1 works fine with two's complement. */
+#ifndef mpn_divexact_by3
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1 && MODLIMB_INVERSE_3
+#define mpn_divexact_by3(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,3,MODLIMB_INVERSE_3,0)
+#else
+#define mpn_divexact_by3(dst,src,size) mpn_divexact_1(dst,src,size,3)
+#endif
+#endif
+
+/* Interpolation for Toom-3.5, using the evaluation points: infinity,
+ 1, -1, 2, -2. More precisely, we want to compute
+ f(2^(GMP_NUMB_BITS * n)) for a polynomial f of degree 5, given the
+ six values
+
+ w5 = f(0),
+ w4 = f(-1),
+ w3 = f(1)
+ w2 = f(-2),
+ w1 = f(2),
+ w0 = limit at infinity of f(x) / x^5,
+
+ The result is stored in {pp, 5*n + w0n}. At entry, w5 is stored at
+ {pp, 2n}, w3 is stored at {pp + 2n, 2n+1}, and w0 is stored at
+ {pp + 5n, w0n}. The other values are 2n + 1 limbs each (with most
+ significant limbs small). f(-1) and f(-2) may be negative, signs
+ determined by the flag bits. All intermediate results are positive.
+ Inputs are destroyed.
+
+ Interpolation sequence was taken from the paper: "Integer and
+ Polynomial Multiplication: Towards Optimal Toom-Cook Matrices".
+ Some slight variations were introduced: adaptation to "gmp
+ instruction set", and a final saving of an operation by interlacing
+ interpolation and recomposition phases.
+*/
+
+void
+mpn_toom_interpolate_6pts (mp_ptr pp, mp_size_t n, enum toom6_flags flags,
+ mp_ptr w4, mp_ptr w2, mp_ptr w1,
+ mp_size_t w0n)
+{
+ mp_limb_t cy;
+ /* cy6 can be stored in w1[2*n], cy4 in w4[0], embankment in w2[0] */
+ mp_limb_t cy4, cy6, embankment;
+
+ ASSERT( n > 0 );
+ ASSERT( 2*n >= w0n && w0n > 0 );
+
+#define w5 pp /* 2n */
+#define w3 (pp + 2 * n) /* 2n+1 */
+#define w0 (pp + 5 * n) /* w0n */
+
+ /* Interpolate with sequence:
+ W2 =(W1 - W2)>>2
+ W1 =(W1 - W5)>>1
+ W1 =(W1 - W2)>>1
+ W4 =(W3 - W4)>>1
+ W2 =(W2 - W4)/3
+ W3 = W3 - W4 - W5
+ W1 =(W1 - W3)/3
+ // Last steps are mixed with recomposition...
+ W2 = W2 - W0<<2
+ W4 = W4 - W2
+ W3 = W3 - W1
+ W2 = W2 - W0
+ */
+
+ /* W2 =(W1 - W2)>>2 */
+ if (flags & toom6_vm2_neg)
+ mpn_add_n (w2, w1, w2, 2 * n + 1);
+ else
+ mpn_sub_n (w2, w1, w2, 2 * n + 1);
+ mpn_rshift (w2, w2, 2 * n + 1, 2);
+
+ /* W1 =(W1 - W5)>>1 */
+ w1[2*n] -= mpn_sub_n (w1, w1, w5, 2*n);
+ mpn_rshift (w1, w1, 2 * n + 1, 1);
+
+ /* W1 =(W1 - W2)>>1 */
+#if HAVE_NATIVE_mpn_rsh1sub_n
+ mpn_rsh1sub_n (w1, w1, w2, 2 * n + 1);
+#else
+ mpn_sub_n (w1, w1, w2, 2 * n + 1);
+ mpn_rshift (w1, w1, 2 * n + 1, 1);
+#endif
+
+ /* W4 =(W3 - W4)>>1 */
+ if (flags & toom6_vm1_neg)
+ {
+#if HAVE_NATIVE_mpn_rsh1add_n
+ mpn_rsh1add_n (w4, w3, w4, 2 * n + 1);
+#else
+ mpn_add_n (w4, w3, w4, 2 * n + 1);
+ mpn_rshift (w4, w4, 2 * n + 1, 1);
+#endif
+ }
+ else
+ {
+#if HAVE_NATIVE_mpn_rsh1sub_n
+ mpn_rsh1sub_n (w4, w3, w4, 2 * n + 1);
+#else
+ mpn_sub_n (w4, w3, w4, 2 * n + 1);
+ mpn_rshift (w4, w4, 2 * n + 1, 1);
+#endif
+ }
+
+ /* W2 =(W2 - W4)/3 */
+ mpn_sub_n (w2, w2, w4, 2 * n + 1);
+ mpn_divexact_by3 (w2, w2, 2 * n + 1);
+
+ /* W3 = W3 - W4 - W5 */
+ mpn_sub_n (w3, w3, w4, 2 * n + 1);
+ w3[2 * n] -= mpn_sub_n (w3, w3, w5, 2 * n);
+
+ /* W1 =(W1 - W3)/3 */
+ mpn_sub_n (w1, w1, w3, 2 * n + 1);
+ mpn_divexact_by3 (w1, w1, 2 * n + 1);
+
+ /*
+ [1 0 0 0 0 0;
+ 0 1 0 0 0 0;
+ 1 0 1 0 0 0;
+ 0 1 0 1 0 0;
+ 1 0 1 0 1 0;
+ 0 0 0 0 0 1]
+
+ pp[] prior to operations:
+ |_H w0__|_L w0__|______||_H w3__|_L w3__|_H w5__|_L w5__|
+
+ summation scheme for remaining operations:
+ |______________5|n_____4|n_____3|n_____2|n______|n______|pp
+ |_H w0__|_L w0__|______||_H w3__|_L w3__|_H w5__|_L w5__|
+ || H w4 | L w4 |
+ || H w2 | L w2 |
+ || H w1 | L w1 |
+ ||-H w1 |-L w1 |
+ |-H w0 |-L w0 ||-H w2 |-L w2 |
+ */
+ cy = mpn_add_n (pp + n, pp + n, w4, 2 * n + 1);
+ MPN_INCR_U (pp + 3 * n + 1, n, cy);
+
+ /* W2 -= W0<<2 */
+#if HAVE_NATIVE_mpn_sublsh_n || HAVE_NATIVE_mpn_sublsh2_n_ip1
+#if HAVE_NATIVE_mpn_sublsh2_n_ip1
+ cy = mpn_sublsh2_n_ip1 (w2, w0, w0n);
+#else
+ cy = mpn_sublsh_n (w2, w2, w0, w0n, 2);
+#endif
+#else
+ /* {W4,2*n+1} is now free and can be overwritten. */
+ cy = mpn_lshift(w4, w0, w0n, 2);
+ cy+= mpn_sub_n(w2, w2, w4, w0n);
+#endif
+ MPN_DECR_U (w2 + w0n, 2 * n + 1 - w0n, cy);
+
+ /* W4L = W4L - W2L */
+ cy = mpn_sub_n (pp + n, pp + n, w2, n);
+ MPN_DECR_U (w3, 2 * n + 1, cy);
+
+ /* W3H = W3H + W2L */
+ cy4 = w3[2 * n] + mpn_add_n (pp + 3 * n, pp + 3 * n, w2, n);
+ /* W1L + W2H */
+ cy = w2[2 * n] + mpn_add_n (pp + 4 * n, w1, w2 + n, n);
+ MPN_INCR_U (w1 + n, n + 1, cy);
+
+ /* W0 = W0 + W1H */
+ if (LIKELY (w0n > n))
+ cy6 = w1[2 * n] + mpn_add_n (w0, w0, w1 + n, n);
+ else
+ cy6 = mpn_add_n (w0, w0, w1 + n, w0n);
+
+ /*
+ summation scheme for the next operation:
+ |...____5|n_____4|n_____3|n_____2|n______|n______|pp
+ |...w0___|_w1_w2_|_H w3__|_L w3__|_H w5__|_L w5__|
+ ...-w0___|-w1_w2 |
+ */
+ /* if(LIKELY(w0n>n)) the two operands below DO overlap! */
+ cy = mpn_sub_n (pp + 2 * n, pp + 2 * n, pp + 4 * n, n + w0n);
+
+ /* embankment is a "dirty trick" to avoid carry/borrow propagation
+ beyond allocated memory */
+ embankment = w0[w0n - 1] - 1;
+ w0[w0n - 1] = 1;
+ if (LIKELY (w0n > n)) {
+ if (cy4 > cy6)
+ MPN_INCR_U (pp + 4 * n, w0n + n, cy4 - cy6);
+ else
+ MPN_DECR_U (pp + 4 * n, w0n + n, cy6 - cy4);
+ MPN_DECR_U (pp + 3 * n + w0n, 2 * n, cy);
+ MPN_INCR_U (w0 + n, w0n - n, cy6);
+ } else {
+ MPN_INCR_U (pp + 4 * n, w0n + n, cy4);
+ MPN_DECR_U (pp + 3 * n + w0n, 2 * n, cy + cy6);
+ }
+ w0[w0n - 1] += embankment;
+
+#undef w5
+#undef w3
+#undef w0
+
+}
diff --git a/gmp/mpn/generic/toom_interpolate_7pts.c b/gmp/mpn/generic/toom_interpolate_7pts.c
new file mode 100644
index 0000000000..2a67dba82f
--- /dev/null
+++ b/gmp/mpn/generic/toom_interpolate_7pts.c
@@ -0,0 +1,266 @@
+/* mpn_toom_interpolate_7pts -- Interpolate for toom44, 53, 62.
+
+ Contributed to the GNU project by Niels Möller.
+ Improvements by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#define BINVERT_3 MODLIMB_INVERSE_3
+
+#define BINVERT_9 \
+ ((((GMP_NUMB_MAX / 9) << (6 - GMP_NUMB_BITS % 6)) * 8 & GMP_NUMB_MAX) | 0x39)
+
+#define BINVERT_15 \
+ ((((GMP_NUMB_MAX >> (GMP_NUMB_BITS % 4)) / 15) * 14 * 16 & GMP_NUMB_MAX) + 15)
+
+/* For the various mpn_divexact_byN here, fall back to using either
+ mpn_pi1_bdiv_q_1 or mpn_divexact_1. The former has less overhead and is
+ many faster if it is native. For now, since mpn_divexact_1 is native on
+ several platforms where mpn_pi1_bdiv_q_1 does not yet exist, do not use
+ mpn_pi1_bdiv_q_1 unconditionally. FIXME. */
+
+/* For odd divisors, mpn_divexact_1 works fine with two's complement. */
+#ifndef mpn_divexact_by3
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by3(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,3,BINVERT_3,0)
+#else
+#define mpn_divexact_by3(dst,src,size) mpn_divexact_1(dst,src,size,3)
+#endif
+#endif
+
+#ifndef mpn_divexact_by9
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by9(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,9,BINVERT_9,0)
+#else
+#define mpn_divexact_by9(dst,src,size) mpn_divexact_1(dst,src,size,9)
+#endif
+#endif
+
+#ifndef mpn_divexact_by15
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by15(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,15,BINVERT_15,0)
+#else
+#define mpn_divexact_by15(dst,src,size) mpn_divexact_1(dst,src,size,15)
+#endif
+#endif
+
+/* Interpolation for toom4, using the evaluation points 0, infinity,
+ 1, -1, 2, -2, 1/2. More precisely, we want to compute
+ f(2^(GMP_NUMB_BITS * n)) for a polynomial f of degree 6, given the
+ seven values
+
+ w0 = f(0),
+ w1 = f(-2),
+ w2 = f(1),
+ w3 = f(-1),
+ w4 = f(2)
+ w5 = 64 * f(1/2)
+ w6 = limit at infinity of f(x) / x^6,
+
+ The result is 6*n + w6n limbs. At entry, w0 is stored at {rp, 2n },
+ w2 is stored at { rp + 2n, 2n+1 }, and w6 is stored at { rp + 6n,
+ w6n }. The other values are 2n + 1 limbs each (with most
+ significant limbs small). f(-1) and f(-1/2) may be negative, signs
+ determined by the flag bits. Inputs are destroyed.
+
+ Needs (2*n + 1) limbs of temporary storage.
+*/
+
+void
+mpn_toom_interpolate_7pts (mp_ptr rp, mp_size_t n, enum toom7_flags flags,
+ mp_ptr w1, mp_ptr w3, mp_ptr w4, mp_ptr w5,
+ mp_size_t w6n, mp_ptr tp)
+{
+ mp_size_t m;
+ mp_limb_t cy;
+
+ m = 2*n + 1;
+#define w0 rp
+#define w2 (rp + 2*n)
+#define w6 (rp + 6*n)
+
+ ASSERT (w6n > 0);
+ ASSERT (w6n <= 2*n);
+
+ /* Using formulas similar to Marco Bodrato's
+
+ W5 = W5 + W4
+ W1 =(W4 - W1)/2
+ W4 = W4 - W0
+ W4 =(W4 - W1)/4 - W6*16
+ W3 =(W2 - W3)/2
+ W2 = W2 - W3
+
+ W5 = W5 - W2*65 May be negative.
+ W2 = W2 - W6 - W0
+ W5 =(W5 + W2*45)/2 Now >= 0 again.
+ W4 =(W4 - W2)/3
+ W2 = W2 - W4
+
+ W1 = W5 - W1 May be negative.
+ W5 =(W5 - W3*8)/9
+ W3 = W3 - W5
+ W1 =(W1/15 + W5)/2 Now >= 0 again.
+ W5 = W5 - W1
+
+ where W0 = f(0), W1 = f(-2), W2 = f(1), W3 = f(-1),
+ W4 = f(2), W5 = f(1/2), W6 = f(oo),
+
+ Note that most intermediate results are positive; the ones that
+ may be negative are represented in two's complement. We must
+ never shift right a value that may be negative, since that would
+ invalidate the sign bit. On the other hand, divexact by odd
+ numbers work fine with two's complement.
+ */
+
+ mpn_add_n (w5, w5, w4, m);
+ if (flags & toom7_w1_neg)
+ {
+#ifdef HAVE_NATIVE_mpn_rsh1add_n
+ mpn_rsh1add_n (w1, w1, w4, m);
+#else
+ mpn_add_n (w1, w1, w4, m); ASSERT (!(w1[0] & 1));
+ mpn_rshift (w1, w1, m, 1);
+#endif
+ }
+ else
+ {
+#ifdef HAVE_NATIVE_mpn_rsh1sub_n
+ mpn_rsh1sub_n (w1, w4, w1, m);
+#else
+ mpn_sub_n (w1, w4, w1, m); ASSERT (!(w1[0] & 1));
+ mpn_rshift (w1, w1, m, 1);
+#endif
+ }
+ mpn_sub (w4, w4, m, w0, 2*n);
+ mpn_sub_n (w4, w4, w1, m); ASSERT (!(w4[0] & 3));
+ mpn_rshift (w4, w4, m, 2); /* w4>=0 */
+
+ tp[w6n] = mpn_lshift (tp, w6, w6n, 4);
+ mpn_sub (w4, w4, m, tp, w6n+1);
+
+ if (flags & toom7_w3_neg)
+ {
+#ifdef HAVE_NATIVE_mpn_rsh1add_n
+ mpn_rsh1add_n (w3, w3, w2, m);
+#else
+ mpn_add_n (w3, w3, w2, m); ASSERT (!(w3[0] & 1));
+ mpn_rshift (w3, w3, m, 1);
+#endif
+ }
+ else
+ {
+#ifdef HAVE_NATIVE_mpn_rsh1sub_n
+ mpn_rsh1sub_n (w3, w2, w3, m);
+#else
+ mpn_sub_n (w3, w2, w3, m); ASSERT (!(w3[0] & 1));
+ mpn_rshift (w3, w3, m, 1);
+#endif
+ }
+
+ mpn_sub_n (w2, w2, w3, m);
+
+ mpn_submul_1 (w5, w2, m, 65);
+ mpn_sub (w2, w2, m, w6, w6n);
+ mpn_sub (w2, w2, m, w0, 2*n);
+
+ mpn_addmul_1 (w5, w2, m, 45); ASSERT (!(w5[0] & 1));
+ mpn_rshift (w5, w5, m, 1);
+ mpn_sub_n (w4, w4, w2, m);
+
+ mpn_divexact_by3 (w4, w4, m);
+ mpn_sub_n (w2, w2, w4, m);
+
+ mpn_sub_n (w1, w5, w1, m);
+ mpn_lshift (tp, w3, m, 3);
+ mpn_sub_n (w5, w5, tp, m);
+ mpn_divexact_by9 (w5, w5, m);
+ mpn_sub_n (w3, w3, w5, m);
+
+ mpn_divexact_by15 (w1, w1, m);
+ mpn_add_n (w1, w1, w5, m); ASSERT (!(w1[0] & 1));
+ mpn_rshift (w1, w1, m, 1); /* w1>=0 now */
+ mpn_sub_n (w5, w5, w1, m);
+
+ /* These bounds are valid for the 4x4 polynomial product of toom44,
+ * and they are conservative for toom53 and toom62. */
+ ASSERT (w1[2*n] < 2);
+ ASSERT (w2[2*n] < 3);
+ ASSERT (w3[2*n] < 4);
+ ASSERT (w4[2*n] < 3);
+ ASSERT (w5[2*n] < 2);
+
+ /* Addition chain. Note carries and the 2n'th limbs that need to be
+ * added in.
+ *
+ * Special care is needed for w2[2n] and the corresponding carry,
+ * since the "simple" way of adding it all together would overwrite
+ * the limb at wp[2*n] and rp[4*n] (same location) with the sum of
+ * the high half of w3 and the low half of w4.
+ *
+ * 7 6 5 4 3 2 1 0
+ * | | | | | | | | |
+ * ||w3 (2n+1)|
+ * ||w4 (2n+1)|
+ * ||w5 (2n+1)| ||w1 (2n+1)|
+ * + | w6 (w6n)| ||w2 (2n+1)| w0 (2n) | (share storage with r)
+ * -----------------------------------------------
+ * r | | | | | | | | |
+ * c7 c6 c5 c4 c3 Carries to propagate
+ */
+
+ cy = mpn_add_n (rp + n, rp + n, w1, m);
+ MPN_INCR_U (w2 + n + 1, n , cy);
+ cy = mpn_add_n (rp + 3*n, rp + 3*n, w3, n);
+ MPN_INCR_U (w3 + n, n + 1, w2[2*n] + cy);
+ cy = mpn_add_n (rp + 4*n, w3 + n, w4, n);
+ MPN_INCR_U (w4 + n, n + 1, w3[2*n] + cy);
+ cy = mpn_add_n (rp + 5*n, w4 + n, w5, n);
+ MPN_INCR_U (w5 + n, n + 1, w4[2*n] + cy);
+ if (w6n > n + 1)
+ ASSERT_NOCARRY (mpn_add (rp + 6*n, rp + 6*n, w6n, w5 + n, n + 1));
+ else
+ {
+ ASSERT_NOCARRY (mpn_add_n (rp + 6*n, rp + 6*n, w5 + n, w6n));
+#if WANT_ASSERT
+ {
+ mp_size_t i;
+ for (i = w6n; i <= n; i++)
+ ASSERT (w5[n + i] == 0);
+ }
+#endif
+ }
+}
diff --git a/gmp/mpn/generic/toom_interpolate_8pts.c b/gmp/mpn/generic/toom_interpolate_8pts.c
new file mode 100644
index 0000000000..9e8808334e
--- /dev/null
+++ b/gmp/mpn/generic/toom_interpolate_8pts.c
@@ -0,0 +1,212 @@
+/* mpn_toom_interpolate_8pts -- Interpolate for toom54, 63, 72.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#define BINVERT_3 MODLIMB_INVERSE_3
+
+#define BINVERT_15 \
+ ((((GMP_NUMB_MAX >> (GMP_NUMB_BITS % 4)) / 15) * 14 * 16 & GMP_NUMB_MAX) + 15)
+
+#define BINVERT_45 ((BINVERT_15 * BINVERT_3) & GMP_NUMB_MASK)
+
+#ifndef mpn_divexact_by3
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by3(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,3,BINVERT_3,0)
+#else
+#define mpn_divexact_by3(dst,src,size) mpn_divexact_1(dst,src,size,3)
+#endif
+#endif
+
+#ifndef mpn_divexact_by45
+#if GMP_NUMB_BITS % 12 == 0
+#define mpn_divexact_by45(dst,src,size) \
+ (63 & 19 * mpn_bdiv_dbm1 (dst, src, size, __GMP_CAST (mp_limb_t, GMP_NUMB_MASK / 45)))
+#else
+#if HAVE_NATIVE_mpn_pi1_bdiv_q_1
+#define mpn_divexact_by45(dst,src,size) mpn_pi1_bdiv_q_1(dst,src,size,45,BINVERT_45,0)
+#else
+#define mpn_divexact_by45(dst,src,size) mpn_divexact_1(dst,src,size,45)
+#endif
+#endif
+#endif
+
+#if HAVE_NATIVE_mpn_sublsh2_n_ip1
+#define DO_mpn_sublsh2_n(dst,src,n,ws) mpn_sublsh2_n_ip1(dst,src,n)
+#else
+#define DO_mpn_sublsh2_n(dst,src,n,ws) DO_mpn_sublsh_n(dst,src,n,2,ws)
+#endif
+
+#if HAVE_NATIVE_mpn_sublsh_n
+#define DO_mpn_sublsh_n(dst,src,n,s,ws) mpn_sublsh_n (dst,dst,src,n,s)
+#else
+static mp_limb_t
+DO_mpn_sublsh_n (mp_ptr dst, mp_srcptr src, mp_size_t n, unsigned int s, mp_ptr ws)
+{
+#if USE_MUL_1 && 0
+ return mpn_submul_1(dst,src,n,CNST_LIMB(1) <<(s));
+#else
+ mp_limb_t __cy;
+ __cy = mpn_lshift (ws,src,n,s);
+ return __cy + mpn_sub_n (dst,dst,ws,n);
+#endif
+}
+#endif
+
+
+#if HAVE_NATIVE_mpn_subrsh
+#define DO_mpn_subrsh(dst,nd,src,ns,s,ws) mpn_subrsh (dst,nd,src,ns,s)
+#else
+/* This is not a correct definition, it assumes no carry */
+#define DO_mpn_subrsh(dst,nd,src,ns,s,ws) \
+do { \
+ mp_limb_t __cy; \
+ MPN_DECR_U (dst, nd, src[0] >> s); \
+ __cy = DO_mpn_sublsh_n (dst, src + 1, ns - 1, GMP_NUMB_BITS - s, ws); \
+ MPN_DECR_U (dst + ns - 1, nd - ns + 1, __cy); \
+} while (0)
+#endif
+
+/* Interpolation for Toom-4.5 (or Toom-4), using the evaluation
+ points: infinity(4.5 only), 4, -4, 2, -2, 1, -1, 0. More precisely,
+ we want to compute f(2^(GMP_NUMB_BITS * n)) for a polynomial f of
+ degree 7 (or 6), given the 8 (rsp. 7) values:
+
+ r1 = limit at infinity of f(x) / x^7,
+ r2 = f(4),
+ r3 = f(-4),
+ r4 = f(2),
+ r5 = f(-2),
+ r6 = f(1),
+ r7 = f(-1),
+ r8 = f(0).
+
+ All couples of the form f(n),f(-n) must be already mixed with
+ toom_couple_handling(f(n),...,f(-n),...)
+
+ The result is stored in {pp, spt + 7*n (or 6*n)}.
+ At entry, r8 is stored at {pp, 2n},
+ r5 is stored at {pp + 3n, 3n + 1}.
+
+ The other values are 2n+... limbs each (with most significant limbs small).
+
+ All intermediate results are positive.
+ Inputs are destroyed.
+*/
+
+void
+mpn_toom_interpolate_8pts (mp_ptr pp, mp_size_t n,
+ mp_ptr r3, mp_ptr r7,
+ mp_size_t spt, mp_ptr ws)
+{
+ mp_limb_signed_t cy;
+ mp_ptr r5, r1;
+ r5 = (pp + 3 * n); /* 3n+1 */
+ r1 = (pp + 7 * n); /* spt */
+
+ /******************************* interpolation *****************************/
+
+ DO_mpn_subrsh(r3+n, 2 * n + 1, pp, 2 * n, 4, ws);
+ cy = DO_mpn_sublsh_n (r3, r1, spt, 12, ws);
+ MPN_DECR_U (r3 + spt, 3 * n + 1 - spt, cy);
+
+ DO_mpn_subrsh(r5+n, 2 * n + 1, pp, 2 * n, 2, ws);
+ cy = DO_mpn_sublsh_n (r5, r1, spt, 6, ws);
+ MPN_DECR_U (r5 + spt, 3 * n + 1 - spt, cy);
+
+ r7[3*n] -= mpn_sub_n (r7+n, r7+n, pp, 2 * n);
+ cy = mpn_sub_n (r7, r7, r1, spt);
+ MPN_DECR_U (r7 + spt, 3 * n + 1 - spt, cy);
+
+ ASSERT_NOCARRY(mpn_sub_n (r3, r3, r5, 3 * n + 1));
+ ASSERT_NOCARRY(mpn_rshift(r3, r3, 3 * n + 1, 2));
+
+ ASSERT_NOCARRY(mpn_sub_n (r5, r5, r7, 3 * n + 1));
+
+ ASSERT_NOCARRY(mpn_sub_n (r3, r3, r5, 3 * n + 1));
+
+ mpn_divexact_by45 (r3, r3, 3 * n + 1);
+
+ ASSERT_NOCARRY(mpn_divexact_by3 (r5, r5, 3 * n + 1));
+
+ ASSERT_NOCARRY(DO_mpn_sublsh2_n (r5, r3, 3 * n + 1, ws));
+
+ /* last interpolation steps... */
+ /* ... are mixed with recomposition */
+
+ /***************************** recomposition *******************************/
+ /*
+ pp[] prior to operations:
+ |_H r1|_L r1|____||_H r5|_M_r5|_L r5|_____|_H r8|_L r8|pp
+
+ summation scheme for remaining operations:
+ |____8|n___7|n___6|n___5|n___4|n___3|n___2|n____|n____|pp
+ |_H r1|_L r1|____||_H*r5|_M r5|_L r5|_____|_H_r8|_L r8|pp
+ ||_H r3|_M r3|_L*r3|
+ ||_H_r7|_M_r7|_L_r7|
+ ||-H r3|-M r3|-L*r3|
+ ||-H*r5|-M_r5|-L_r5|
+ */
+
+ cy = mpn_add_n (pp + n, pp + n, r7, n); /* Hr8+Lr7-Lr5 */
+ cy-= mpn_sub_n (pp + n, pp + n, r5, n);
+ if (0 > cy)
+ MPN_DECR_U (r7 + n, 2*n + 1, 1);
+ else
+ MPN_INCR_U (r7 + n, 2*n + 1, cy);
+
+ cy = mpn_sub_n (pp + 2*n, r7 + n, r5 + n, n); /* Mr7-Mr5 */
+ MPN_DECR_U (r7 + 2*n, n + 1, cy);
+
+ cy = mpn_add_n (pp + 3*n, r5, r7+ 2*n, n+1); /* Hr7+Lr5 */
+ r5[3*n]+= mpn_add_n (r5 + 2*n, r5 + 2*n, r3, n); /* Hr5+Lr3 */
+ cy-= mpn_sub_n (pp + 3*n, pp + 3*n, r5 + 2*n, n+1); /* Hr7-Hr5+Lr5-Lr3 */
+ if (UNLIKELY(0 > cy))
+ MPN_DECR_U (r5 + n + 1, 2*n, 1);
+ else
+ MPN_INCR_U (r5 + n + 1, 2*n, cy);
+
+ ASSERT_NOCARRY(mpn_sub_n(pp + 4*n, r5 + n, r3 + n, 2*n +1)); /* Mr5-Mr3,Hr5-Hr3 */
+
+ cy = mpn_add_1 (pp + 6*n, r3 + n, n, pp[6*n]);
+ MPN_INCR_U (r3 + 2*n, n + 1, cy);
+ cy = mpn_add_n (pp + 7*n, pp + 7*n, r3 + 2*n, n);
+ if (LIKELY(spt != n))
+ MPN_INCR_U (pp + 8*n, spt - n, cy + r3[3*n]);
+ else
+ ASSERT (r3[3*n] | cy == 0);
+}
diff --git a/gmp/mpn/generic/trialdiv.c b/gmp/mpn/generic/trialdiv.c
new file mode 100644
index 0000000000..cad159c3a0
--- /dev/null
+++ b/gmp/mpn/generic/trialdiv.c
@@ -0,0 +1,132 @@
+/* mpn_trialdiv -- find small factors of an mpn number using trial division.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+ THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
+ SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009, 2010, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/*
+ This function finds the first (smallest) factor represented in
+ trialdivtab.h. It does not stop the factoring effort just because it has
+ reached some sensible limit, such as the square root of the input number.
+
+ The caller can limit the factoring effort by passing NPRIMES. The function
+ will then divide until that limit, or perhaps a few primes more. A position
+ which only mpn_trialdiv can make sense of is returned in the WHERE
+ parameter. It can be used for restarting the factoring effort; the first
+ call should pass 0 here.
+
+ Input: 1. A non-negative number T = {tp,tn}
+ 2. NPRIMES as described above,
+ 3. *WHERE as described above.
+ Output: 1. *WHERE updated as described above.
+ 2. Return value is non-zero if we found a factor, else zero
+ To get the actual prime factor, compute the mod B inverse
+ of the return value.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+struct gmp_primes_dtab {
+ mp_limb_t binv;
+ mp_limb_t lim;
+};
+
+struct gmp_primes_ptab {
+ mp_limb_t ppp; /* primes, multiplied together */
+ mp_limb_t cps[7]; /* ppp values pre-computed for mpn_mod_1s_4p */
+ unsigned int idx:24; /* index of first primes in dtab */
+ unsigned int np :8; /* number of primes related to this entry */
+};
+
+
+static const struct gmp_primes_dtab gmp_primes_dtab[] =
+{
+#define WANT_dtab
+#define P(p,inv,lim) {inv,lim}
+#include "trialdivtab.h"
+#undef WANT_dtab
+#undef P
+ {0,0}
+};
+
+static const struct gmp_primes_ptab gmp_primes_ptab[] =
+{
+#define WANT_ptab
+#include "trialdivtab.h"
+#undef WANT_ptab
+};
+
+#define PTAB_LINES (sizeof (gmp_primes_ptab) / sizeof (gmp_primes_ptab[0]))
+
+/* FIXME: We could optimize out one of the outer loop conditions if we
+ had a final ptab entry with a huge nd field. */
+mp_limb_t
+mpn_trialdiv (mp_srcptr tp, mp_size_t tn, mp_size_t nprimes, int *where)
+{
+ mp_limb_t ppp;
+ const mp_limb_t *cps;
+ const struct gmp_primes_dtab *dp;
+ long i, j, idx, np;
+ mp_limb_t r, q;
+
+ ASSERT (tn >= 1);
+
+ for (i = *where; i < PTAB_LINES; i++)
+ {
+ ppp = gmp_primes_ptab[i].ppp;
+ cps = gmp_primes_ptab[i].cps;
+
+ r = mpn_mod_1s_4p (tp, tn, ppp << cps[1], cps);
+
+ idx = gmp_primes_ptab[i].idx;
+ np = gmp_primes_ptab[i].np;
+
+ /* Check divisibility by individual primes. */
+ dp = &gmp_primes_dtab[idx] + np;
+ for (j = -np; j < 0; j++)
+ {
+ q = r * dp[j].binv;
+ if (q <= dp[j].lim)
+ {
+ *where = i;
+ return dp[j].binv;
+ }
+ }
+
+ nprimes -= np;
+ if (nprimes <= 0)
+ return 0;
+ }
+ return 0;
+}
diff --git a/gmp/mpn/generic/udiv_w_sdiv.c b/gmp/mpn/generic/udiv_w_sdiv.c
new file mode 100644
index 0000000000..7136429f0f
--- /dev/null
+++ b/gmp/mpn/generic/udiv_w_sdiv.c
@@ -0,0 +1,142 @@
+/* mpn_udiv_w_sdiv -- implement udiv_qrnnd on machines with only signed
+ division.
+
+ Contributed by Peter L. Montgomery.
+
+ THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS ONLY SAFE
+ TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS
+ ALMOST GUARANTEED THAT THIS FUNCTION WILL CHANGE OR DISAPPEAR IN A FUTURE
+ GNU MP RELEASE.
+
+
+Copyright 1992, 1994, 1996, 2000, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_udiv_w_sdiv (mp_limb_t *rp, mp_limb_t a1, mp_limb_t a0, mp_limb_t d)
+{
+ mp_limb_t q, r;
+ mp_limb_t c0, c1, b1;
+
+ ASSERT (d != 0);
+ ASSERT (a1 < d);
+
+ if ((mp_limb_signed_t) d >= 0)
+ {
+ if (a1 < d - a1 - (a0 >> (GMP_LIMB_BITS - 1)))
+ {
+ /* dividend, divisor, and quotient are nonnegative */
+ sdiv_qrnnd (q, r, a1, a0, d);
+ }
+ else
+ {
+ /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
+ sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (GMP_LIMB_BITS - 1));
+ /* Divide (c1*2^32 + c0) by d */
+ sdiv_qrnnd (q, r, c1, c0, d);
+ /* Add 2^31 to quotient */
+ q += (mp_limb_t) 1 << (GMP_LIMB_BITS - 1);
+ }
+ }
+ else
+ {
+ b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
+ c1 = a1 >> 1; /* A/2 */
+ c0 = (a1 << (GMP_LIMB_BITS - 1)) + (a0 >> 1);
+
+ if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
+ {
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
+ {
+ c1 = (b1 - 1) - c1;
+ c0 = ~c0; /* logical NOT */
+
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ q = ~q; /* (A/2)/b1 */
+ r = (b1 - 1) - r;
+
+ r = 2*r + (a0 & 1); /* A/(2*b1) */
+
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else /* Implies c1 = b1 */
+ { /* Hence a1 = d - 1 = 2*b1 - 1 */
+ if (a0 >= -d)
+ {
+ q = -CNST_LIMB(1);
+ r = a0 + d;
+ }
+ else
+ {
+ q = -CNST_LIMB(2);
+ r = a0 + 2*d;
+ }
+ }
+ }
+
+ *rp = r;
+ return q;
+}
diff --git a/gmp/mpn/generic/zero.c b/gmp/mpn/generic/zero.c
new file mode 100644
index 0000000000..e6e7fd3101
--- /dev/null
+++ b/gmp/mpn/generic/zero.c
@@ -0,0 +1,42 @@
+/* mpn_zero
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_zero (mp_ptr rp, mp_size_t n)
+{
+ mp_size_t i;
+
+ rp += n;
+ for (i = -n; i != 0; i++)
+ rp[i] = 0;
+}
diff --git a/gmp/mpn/ia64/README b/gmp/mpn/ia64/README
new file mode 100644
index 0000000000..45c2d6337f
--- /dev/null
+++ b/gmp/mpn/ia64/README
@@ -0,0 +1,281 @@
+Copyright 2000-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+ IA-64 MPN SUBROUTINES
+
+
+This directory contains mpn functions for the IA-64 architecture.
+
+
+CODE ORGANIZATION
+
+ mpn/ia64 itanium-2, and generic ia64
+
+The code here has been optimized primarily for Itanium 2. Very few Itanium 1
+chips were ever sold, and Itanium 2 is more powerful, so the latter is what
+we concentrate on.
+
+
+
+CHIP NOTES
+
+The IA-64 ISA keeps instructions three and three in 128 bit bundles.
+Programmers/compilers need to put explicit breaks `;;' when there are WAW or
+RAW dependencies, with some notable exceptions. Such "breaks" are typically
+at the end of a bundle, but can be put between operations within some bundle
+types too.
+
+The Itanium 1 and Itanium 2 implementations can under ideal conditions
+execute two bundles per cycle. The Itanium 1 allows 4 of these instructions
+to do integer operations, while the Itanium 2 allows all 6 to be integer
+operations.
+
+Taken cloop branches seem to insert a bubble into the pipeline most of the
+time on Itanium 1.
+
+Loads to the fp registers bypass the L1 cache and thus get extremely long
+latencies, 9 cycles on the Itanium 1 and 6 cycles on the Itanium 2.
+
+The software pipeline stuff using br.ctop instruction causes delays, since
+many issue slots are taken up by instructions with zero predicates, and
+since many extra instructions are needed to set things up. These features
+are clearly designed for code density, not speed.
+
+Misc pipeline limitations (Itanium 1):
+* The getf.sig instruction can only execute in M0.
+* At most four integer instructions/cycle.
+* Nops take up resources like any plain instructions.
+
+Misc pipeline limitations (Itanium 2):
+* The getf.sig instruction can only execute in M0.
+* Nops take up resources like any plain instructions.
+
+
+ASSEMBLY SYNTAX
+
+.align pads with nops in a text segment, but gas 2.14 and earlier
+incorrectly byte-swaps its nop bundle in big endian mode (eg. hpux), making
+it come out as break instructions. We use the ALIGN() macro in
+mpn/ia64/ia64-defs.m4 when it might be executed across. That macro
+suppresses any .align if the problem is detected by configure. Lack of
+alignment might hurt performance but will at least be correct.
+
+foo:: to create a global symbol is not accepted by gas. Use separate
+".global foo" and "foo:" instead.
+
+.global is the standard global directive. gas accepts .globl, but hpux "as"
+doesn't.
+
+.proc / .endp generates the appropriate .type and .size information for ELF,
+so the latter directives don't need to be given explicitly.
+
+.pred.rel "mutex"... is standard for annotating predicate register
+relationships. gas also accepts .pred.rel.mutex, but hpux "as" doesn't.
+
+.pred directives can't be put on a line with a label, like
+".Lfoo: .pred ...", the HP assembler on HP-UX 11.23 rejects that.
+gas is happy with it, and past versions of HP had seemed ok.
+
+// is the standard comment sequence, but we prefer "C" since it inhibits m4
+macro expansion. See comments in ia64-defs.m4.
+
+
+REGISTER USAGE
+
+Special:
+ r0: constant 0
+ r1: global pointer (gp)
+ r8: return value
+ r12: stack pointer (sp)
+ r13: thread pointer (tp)
+Caller-saves: r8-r11 r14-r31 f6-f15 f32-f127
+Caller-saves but rotating: r32-
+
+
+================================================================
+mpn_add_n, mpn_sub_n:
+
+The current code runs at 1.25 c/l on Itanium 2.
+
+================================================================
+mpn_mul_1:
+
+The current code runs at 2 c/l on Itanium 2.
+
+Using a blocked approach, working off of 4 separate places in the operands,
+one could make use of the xma accumulation, and approach 1 c/l.
+
+ ldf8 [up]
+ xma.l
+ xma.hu
+ stf8 [wrp]
+
+================================================================
+mpn_addmul_1:
+
+The current code runs at 2 c/l on Itanium 2.
+
+It seems possible to use a blocked approach, as with mpn_mul_1. We should
+read rp[] to integer registers, allowing for just one getf.sig per cycle.
+
+ ld8 [rp]
+ ldf8 [up]
+ xma.l
+ xma.hu
+ getf.sig
+ add+add+cmp+cmp
+ st8 [wrp]
+
+These 10 instructions can be scheduled to approach 1.667 cycles, and with
+the 4 cycle latency of xma, this means we need at least 3 blocks. Using
+ldfp8 we could approach 1.583 c/l.
+
+================================================================
+mpn_submul_1:
+
+The current code runs at 2.25 c/l on Itanium 2. Getting to 2 c/l requires
+ldfp8 with all alignment headache that implies.
+
+================================================================
+mpn_addmul_N
+
+For best speed, we need to give up using mpn_addmul_2 as the main multiply
+building block, and instead take multiple v limbs per loop. For the Itanium
+1, we need to take about 8 limbs at a time for full speed. For the Itanium
+2, something like mpn_addmul_4 should be enough.
+
+The add+cmp+cmp+add we use on the other codes is optimal for shortening
+recurrencies (1 cycle) but the sequence takes up 4 execution slots. When
+recurrency depth is not critical, a more standard 3-cycle add+cmp+add is
+better.
+
+/* First load the 8 values from v */
+ ldfp8 v0, v1 = [r35], 16;;
+ ldfp8 v2, v3 = [r35], 16;;
+ ldfp8 v4, v5 = [r35], 16;;
+ ldfp8 v6, v7 = [r35], 16;;
+
+/* In the inner loop, get a new U limb and store a result limb. */
+ mov lc = un
+Loop: ldf8 u0 = [r33], 8
+ ld8 r0 = [r32]
+ xma.l lp0 = v0, u0, hp0
+ xma.hu hp0 = v0, u0, hp0
+ xma.l lp1 = v1, u0, hp1
+ xma.hu hp1 = v1, u0, hp1
+ xma.l lp2 = v2, u0, hp2
+ xma.hu hp2 = v2, u0, hp2
+ xma.l lp3 = v3, u0, hp3
+ xma.hu hp3 = v3, u0, hp3
+ xma.l lp4 = v4, u0, hp4
+ xma.hu hp4 = v4, u0, hp4
+ xma.l lp5 = v5, u0, hp5
+ xma.hu hp5 = v5, u0, hp5
+ xma.l lp6 = v6, u0, hp6
+ xma.hu hp6 = v6, u0, hp6
+ xma.l lp7 = v7, u0, hp7
+ xma.hu hp7 = v7, u0, hp7
+ getf.sig l0 = lp0
+ getf.sig l1 = lp1
+ getf.sig l2 = lp2
+ getf.sig l3 = lp3
+ getf.sig l4 = lp4
+ getf.sig l5 = lp5
+ getf.sig l6 = lp6
+ add+cmp+add xx, l0, r0
+ add+cmp+add acc0, acc1, l1
+ add+cmp+add acc1, acc2, l2
+ add+cmp+add acc2, acc3, l3
+ add+cmp+add acc3, acc4, l4
+ add+cmp+add acc4, acc5, l5
+ add+cmp+add acc5, acc6, l6
+ getf.sig acc6 = lp7
+ st8 [r32] = xx, 8
+ br.cloop Loop
+
+ 49 insn at max 6 insn/cycle: 8.167 cycles/limb8
+ 11 memops at max 2 memops/cycle: 5.5 cycles/limb8
+ 16 fpops at max 2 fpops/cycle: 8 cycles/limb8
+ 21 intops at max 4 intops/cycle: 5.25 cycles/limb8
+ 11+21 memops+intops at max 4/cycle 8 cycles/limb8
+
+================================================================
+mpn_lshift, mpn_rshift
+
+The current code runs at 1 cycle/limb on Itanium 2.
+
+Using 63 separate loops, we could use the double-word shrp instruction.
+That instruction has a plain single-cycle latency. We need 63 loops since
+this instruction only accept immediate count. That would lead to a somewhat
+silly code size, but the speed would be 0.75 c/l on Itanium 2 (by using shrp
+each cycle plus shl/shr going down I1 for a further limb every second
+cycle).
+
+================================================================
+mpn_copyi, mpn_copyd
+
+The current code runs at 0.5 c/l on Itanium 2. But that is just for L1
+cache hit. The 4-way unrolled loop takes just 2 cycles, and thus load-use
+scheduling isn't great. It might be best to actually use modulo scheduled
+loops, since that will allow us to do better load-use scheduling without too
+much unrolling.
+
+Depending on size or operand alignment, we get 1 c/l or 0.5 c/l on Itanium
+2, according to tune/speed. Cache bank conflicts?
+
+
+
+REFERENCES
+
+Intel Itanium Architecture Software Developer's Manual, volumes 1 to 3,
+Intel document 245317-004, 245318-004, 245319-004 October 2002. Volume 1
+includes an Itanium optimization guide.
+
+Intel Itanium Processor-specific Application Binary Interface (ABI), Intel
+document 245370-003, May 2001. Describes C type sizes, dynamic linking,
+etc.
+
+Intel Itanium Architecture Assembly Language Reference Guide, Intel document
+248801-004, 2000-2002. Describes assembly instruction syntax and other
+directives.
+
+Itanium Software Conventions and Runtime Architecture Guide, Intel document
+245358-003, May 2001. Describes calling conventions, including stack
+unwinding requirements.
+
+Intel Itanium Processor Reference Manual for Software Optimization, Intel
+document 245473-003, November 2001.
+
+Intel Itanium-2 Processor Reference Manual for Software Development and
+Optimization, Intel document 251110-003, May 2004.
+
+All the above documents can be found online at
+
+ http://developer.intel.com/design/itanium/manuals.htm
diff --git a/gmp/mpn/ia64/add_n_sub_n.asm b/gmp/mpn/ia64/add_n_sub_n.asm
new file mode 100644
index 0000000000..34a506568f
--- /dev/null
+++ b/gmp/mpn/ia64/add_n_sub_n.asm
@@ -0,0 +1,309 @@
+dnl IA-64 mpn_add_n_sub_n -- mpn parallel addition and subtraction.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: ?
+C Itanium 2: 2.25
+
+C INPUT PARAMETERS
+define(`sp', `r32')
+define(`dp', `r33')
+define(`up', `r34')
+define(`vp', `r35')
+define(`n', `r36')
+
+C Some useful aliases for registers we use
+define(`u0',`r16') define(`u1',`r17') define(`u2',`r18') define(`u3',`r19')
+define(`v0',`r20') define(`v1',`r21') define(`v2',`r22') define(`v3',`r23')
+define(`s0',`r24') define(`s1',`r25') define(`s2',`r26') define(`s3',`r27')
+define(`d0',`r28') define(`d1',`r29') define(`d2',`r30') define(`d3',`r31')
+define(`up0',`up')
+define(`up1',`r14')
+define(`vp0',`vp')
+define(`vp1',`r15')
+
+define(`cmpltu', `cmp.ltu')
+define(`cmpeqor', `cmp.eq.or')
+
+ASM_START()
+PROLOGUE(mpn_add_n_sub_n)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',`
+ addp4 sp = 0, sp C M I
+ addp4 dp = 0, dp C M I
+ nop.i 0
+ addp4 up = 0, up C M I
+ addp4 vp = 0, vp C M I
+ zxt4 n = n C I
+ ;;
+')
+
+ and r9 = 3, n C M I
+ mov.i r2 = ar.lc C I0
+ add up1 = 8, up0 C M I
+ add vp1 = 8, vp0 C M I
+ add r8 = -2, n C M I
+ add r10 = 256, up C M I
+ ;;
+ shr.u r8 = r8, 2 C I0
+ cmp.eq p10, p0 = 0, r9 C M I
+ cmp.eq p11, p0 = 2, r9 C M I
+ cmp.eq p12, p0 = 3, r9 C M I
+ add r11 = 256, vp C M I
+ ;;
+ mov.i ar.lc = r8 C I0
+ (p10) br L(b0) C B
+ (p11) br L(b2) C B
+ (p12) br L(b3) C B
+
+L(b1): ld8 u3 = [up0], 8 C M01
+ add up1 = 8, up1 C M I
+ cmpltu p14, p15 = 4, n C M I
+ ld8 v3 = [vp0], 8 C M01
+ add vp1 = 8, vp1 C M I
+ ;;
+ add s3 = u3, v3 C M I
+ sub d3 = u3, v3 C M I
+ mov r8 = 0 C M I
+ ;;
+ cmpltu p9, p0 = s3, v3 C carry from add3 M I
+ cmpltu p13, p0 = u3, v3 C borrow from sub3 M I
+ (p15) br L(cj1) C B
+ st8 [sp] = s3, 8 C M23
+ st8 [dp] = d3, 8 C M23
+ br L(c0) C B
+
+L(b0): cmp.ne p9, p0 = r0, r0 C M I
+ cmp.ne p13, p0 = r0, r0 C M I
+L(c0): ld8 u0 = [up0], 16 C M01
+ ld8 u1 = [up1], 16 C M01
+ ;;
+ ld8 v0 = [vp0], 16 C M01
+ ld8 v1 = [vp1], 16 C M01
+ ;;
+ ld8 u2 = [up0], 16 C M01
+ ld8 u3 = [up1], 16 C M01
+ ;;
+ ld8 v2 = [vp0], 16 C M01
+ ld8 v3 = [vp1], 16 C M01
+ ;;
+ add s0 = u0, v0 C M I
+ add s1 = u1, v1 C M I
+ sub d0 = u0, v0 C M I
+ sub d1 = u1, v1 C M I
+ ;;
+ cmpltu p6, p0 = s0, v0 C carry from add0 M I
+ cmpltu p7, p0 = s1, v1 C carry from add1 M I
+ cmpltu p10, p0 = u0, v0 C borrow from sub0 M I
+ cmpltu p11, p0 = u1, v1 C borrow from sub1 M I
+ ;;
+ nop 0 C
+ br.cloop.dptk L(top) C B
+ br L(end) C B
+
+L(b3): ld8 u1 = [up0], 8 C M01
+ add up1 = 8, up1 C M I
+ ld8 v1 = [vp0], 8 C M01
+ ;;
+ add vp1 = 8, vp1 C M I
+ add s1 = u1, v1 C M I
+ sub d1 = u1, v1 C M I
+ ;;
+ cmpltu p7, p0 = s1, v1 C carry from add1 M I
+ cmpltu p11, p0 = u1, v1 C borrow from sub1 M I
+ ;;
+ st8 [sp] = s1, 8 C M23
+ st8 [dp] = d1, 8 C M23
+ br L(c2) C B
+
+ ALIGN(32)
+L(b2): cmp.ne p7, p0 = r0, r0 C M I
+ cmp.ne p11, p0 = r0, r0 C M I
+ nop 0
+L(c2): ld8 u2 = [up0], 16 C M01
+ ld8 u3 = [up1], 16 C M01
+ cmpltu p14, p0 = 4, n C M I
+ ;;
+ ld8 v2 = [vp0], 16 C M01
+ ld8 v3 = [vp1], 16 C M01
+ (p14) br L(gt4) C B
+ ;;
+ add s2 = u2, v2 C M I
+ add s3 = u3, v3 C M I
+ sub d2 = u2, v2 C M I
+ sub d3 = u3, v3 C M I
+ ;;
+ cmpltu p8, p0 = s2, v2 C carry from add0 M I
+ cmpltu p9, p0 = s3, v3 C carry from add3 M I
+ cmpltu p12, p0 = u2, v2 C borrow from sub2 M I
+ cmpltu p13, p0 = u3, v3 C borrow from sub3 M I
+ br L(cj2) C B
+ ;;
+L(gt4): ld8 u0 = [up0], 16 C M01
+ ld8 u1 = [up1], 16 C M01
+ ;;
+ ld8 v0 = [vp0], 16 C M01
+ ld8 v1 = [vp1], 16 C M01
+ ;;
+ add s2 = u2, v2 C M I
+ add s3 = u3, v3 C M I
+ sub d2 = u2, v2 C M I
+ sub d3 = u3, v3 C M I
+ ;;
+ cmpltu p8, p0 = s2, v2 C carry from add0 M I
+ cmpltu p9, p0 = s3, v3 C carry from add1 M I
+ cmpltu p12, p0 = u2, v2 C borrow from sub0 M I
+ cmpltu p13, p0 = u3, v3 C borrow from sub1 M I
+ br.cloop.dptk L(mid) C B
+
+ ALIGN(32)
+L(top):
+ ld8 u0 = [up0], 16 C M01
+ ld8 u1 = [up1], 16 C M01
+ (p9) cmpeqor p6, p0 = -1, s0 C M I
+ (p9) add s0 = 1, s0 C M I
+ (p13) cmpeqor p10, p0 = 0, d0 C M I
+ (p13) add d0 = -1, d0 C M I
+ ;;
+ ld8 v0 = [vp0], 16 C M01
+ ld8 v1 = [vp1], 16 C M01
+ (p6) cmpeqor p7, p0 = -1, s1 C M I
+ (p6) add s1 = 1, s1 C M I
+ (p10) cmpeqor p11, p0 = 0, d1 C M I
+ (p10) add d1 = -1, d1 C M I
+ ;;
+ st8 [sp] = s0, 8 C M23
+ st8 [dp] = d0, 8 C M23
+ add s2 = u2, v2 C M I
+ add s3 = u3, v3 C M I
+ sub d2 = u2, v2 C M I
+ sub d3 = u3, v3 C M I
+ ;;
+ st8 [sp] = s1, 8 C M23
+ st8 [dp] = d1, 8 C M23
+ cmpltu p8, p0 = s2, v2 C carry from add2 M I
+ cmpltu p9, p0 = s3, v3 C carry from add3 M I
+ cmpltu p12, p0 = u2, v2 C borrow from sub2 M I
+ cmpltu p13, p0 = u3, v3 C borrow from sub3 M I
+ ;;
+L(mid):
+ ld8 u2 = [up0], 16 C M01
+ ld8 u3 = [up1], 16 C M01
+ (p7) cmpeqor p8, p0 = -1, s2 C M I
+ (p7) add s2 = 1, s2 C M I
+ (p11) cmpeqor p12, p0 = 0, d2 C M I
+ (p11) add d2 = -1, d2 C M I
+ ;;
+ ld8 v2 = [vp0], 16 C M01
+ ld8 v3 = [vp1], 16 C M01
+ (p8) cmpeqor p9, p0 = -1, s3 C M I
+ (p8) add s3 = 1, s3 C M I
+ (p12) cmpeqor p13, p0 = 0, d3 C M I
+ (p12) add d3 = -1, d3 C M I
+ ;;
+ st8 [sp] = s2, 8 C M23
+ st8 [dp] = d2, 8 C M23
+ add s0 = u0, v0 C M I
+ add s1 = u1, v1 C M I
+ sub d0 = u0, v0 C M I
+ sub d1 = u1, v1 C M I
+ ;;
+ st8 [sp] = s3, 8 C M23
+ st8 [dp] = d3, 8 C M23
+ cmpltu p6, p0 = s0, v0 C carry from add0 M I
+ cmpltu p7, p0 = s1, v1 C carry from add1 M I
+ cmpltu p10, p0 = u0, v0 C borrow from sub0 M I
+ cmpltu p11, p0 = u1, v1 C borrow from sub1 M I
+ ;;
+ lfetch [r10], 32 C M?
+ lfetch [r11], 32 C M?
+ br.cloop.dptk L(top) C B
+ ;;
+
+L(end):
+ nop 0
+ nop 0
+ (p9) cmpeqor p6, p0 = -1, s0 C M I
+ (p9) add s0 = 1, s0 C M I
+ (p13) cmpeqor p10, p0 = 0, d0 C M I
+ (p13) add d0 = -1, d0 C M I
+ ;;
+ nop 0
+ nop 0
+ (p6) cmpeqor p7, p0 = -1, s1 C M I
+ (p6) add s1 = 1, s1 C M I
+ (p10) cmpeqor p11, p0 = 0, d1 C M I
+ (p10) add d1 = -1, d1 C M I
+ ;;
+ st8 [sp] = s0, 8 C M23
+ st8 [dp] = d0, 8 C M23
+ add s2 = u2, v2 C M I
+ add s3 = u3, v3 C M I
+ sub d2 = u2, v2 C M I
+ sub d3 = u3, v3 C M I
+ ;;
+ st8 [sp] = s1, 8 C M23
+ st8 [dp] = d1, 8 C M23
+ cmpltu p8, p0 = s2, v2 C carry from add2 M I
+ cmpltu p9, p0 = s3, v3 C carry from add3 M I
+ cmpltu p12, p0 = u2, v2 C borrow from sub2 M I
+ cmpltu p13, p0 = u3, v3 C borrow from sub3 M I
+ ;;
+L(cj2):
+ (p7) cmpeqor p8, p0 = -1, s2 C M I
+ (p7) add s2 = 1, s2 C M I
+ (p11) cmpeqor p12, p0 = 0, d2 C M I
+ (p11) add d2 = -1, d2 C M I
+ mov r8 = 0 C M I
+ nop 0
+ ;;
+ st8 [sp] = s2, 8 C M23
+ st8 [dp] = d2, 8 C M23
+ (p8) cmpeqor p9, p0 = -1, s3 C M I
+ (p8) add s3 = 1, s3 C M I
+ (p12) cmpeqor p13, p0 = 0, d3 C M I
+ (p12) add d3 = -1, d3 C M I
+ ;;
+L(cj1):
+ (p9) mov r8 = 2 C M I
+ ;;
+ mov.i ar.lc = r2 C I0
+ (p13) add r8 = 1, r8 C M I
+ st8 [sp] = s3 C M23
+ st8 [dp] = d3 C M23
+ br.ret.sptk.many b0 C B
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/addmul_1.asm b/gmp/mpn/ia64/addmul_1.asm
new file mode 100644
index 0000000000..ffa3297763
--- /dev/null
+++ b/gmp/mpn/ia64/addmul_1.asm
@@ -0,0 +1,602 @@
+dnl IA-64 mpn_addmul_1 -- Multiply a limb vector with a limb and add the
+dnl result to a second limb vector.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2000-2005, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 3.0
+C Itanium 2: 2.0
+
+C TODO
+C * Further optimize feed-in and wind-down code, both for speed and code size.
+C * Handle low limb input and results specially, using a common stf8 in the
+C epilogue.
+C * Use 1 c/l carry propagation scheme in wind-down code.
+C * Use extra pointer registers for `up' and rp to speed up feed-in loads.
+C * Work out final differences with mul_1.asm. That function is 300 bytes
+C smaller than this due to better loop scheduling and thus simpler feed-in
+C code.
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`n', `r34')
+define(`vl', `r35')
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ .prologue
+ .save ar.lc, r2
+ .body
+
+ifdef(`HAVE_ABI_32',
+` addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ zxt4 n = n C I
+ ;;
+')
+{.mmi
+ adds r15 = -1, n C M I
+ mov r20 = rp C M I
+ mov.i r2 = ar.lc C I0
+}
+{.mmi
+ ldf8 f7 = [up], 8 C M
+ ldf8 f8 = [rp], 8 C M
+ and r14 = 3, n C M I
+ ;;
+}
+{.mmi
+ setf.sig f6 = vl C M2 M3
+ cmp.eq p10, p0 = 0, r14 C M I
+ shr.u r31 = r15, 2 C I0
+}
+{.mmi
+ cmp.eq p11, p0 = 2, r14 C M I
+ cmp.eq p12, p0 = 3, r14 C M I
+ nop.i 0 C I
+ ;;
+}
+{.mii
+ cmp.ne p6, p7 = r0, r0 C M I
+ mov.i ar.lc = r31 C I0
+ cmp.ne p8, p9 = r0, r0 C M I
+}
+{.bbb
+ (p10) br.dptk .Lb00 C B
+ (p11) br.dptk .Lb10 C B
+ (p12) br.dptk .Lb11 C B
+ ;;
+}
+
+.Lb01: br.cloop.dptk .grt1 C B
+
+ xma.l f39 = f7, f6, f8 C F
+ xma.hu f43 = f7, f6, f8 C F
+ ;;
+ getf.sig r8 = f43 C M2
+ stf8 [r20] = f39 C M2 M3
+ mov.i ar.lc = r2 C I0
+ br.ret.sptk.many b0 C B
+
+.grt1:
+ ldf8 f32 = [up], 8
+ ldf8 f44 = [rp], 8
+ ;;
+ ldf8 f33 = [up], 8
+ ldf8 f45 = [rp], 8
+ ;;
+ ldf8 f34 = [up], 8
+ xma.l f39 = f7, f6, f8
+ ldf8 f46 = [rp], 8
+ xma.hu f43 = f7, f6, f8
+ ;;
+ ldf8 f35 = [up], 8
+ ldf8 f47 = [rp], 8
+ br.cloop.dptk .grt5
+
+ xma.l f36 = f32, f6, f44
+ xma.hu f40 = f32, f6, f44
+ ;;
+ stf8 [r20] = f39, 8
+ xma.l f37 = f33, f6, f45
+ xma.hu f41 = f33, f6, f45
+ ;;
+ getf.sig r31 = f43
+ getf.sig r24 = f36
+ xma.l f38 = f34, f6, f46
+ xma.hu f42 = f34, f6, f46
+ ;;
+ getf.sig r28 = f40
+ getf.sig r25 = f37
+ xma.l f39 = f35, f6, f47
+ xma.hu f43 = f35, f6, f47
+ ;;
+ getf.sig r29 = f41
+ getf.sig r26 = f38
+ br .Lcj5
+
+.grt5:
+ mov r30 = 0
+ xma.l f36 = f32, f6, f44
+ xma.hu f40 = f32, f6, f44
+ ;;
+ ldf8 f32 = [up], 8
+ xma.l f37 = f33, f6, f45
+ ldf8 f44 = [rp], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ ldf8 f33 = [up], 8
+ getf.sig r27 = f39
+ ;;
+ getf.sig r31 = f43
+ xma.l f38 = f34, f6, f46
+ ldf8 f45 = [rp], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ ldf8 f34 = [up], 8
+ getf.sig r24 = f36
+ ;;
+ getf.sig r28 = f40
+ xma.l f39 = f35, f6, f47
+ ldf8 f46 = [rp], 8
+ xma.hu f43 = f35, f6, f47
+ ;;
+ ldf8 f35 = [up], 8
+ getf.sig r25 = f37
+ br.cloop.dptk .Loop
+ br .Le0
+
+
+.Lb10: ldf8 f35 = [up], 8
+ ldf8 f47 = [rp], 8
+ br.cloop.dptk .grt2
+
+ xma.l f38 = f7, f6, f8
+ xma.hu f42 = f7, f6, f8
+ ;;
+ xma.l f39 = f35, f6, f47
+ xma.hu f43 = f35, f6, f47
+ ;;
+ getf.sig r30 = f42
+ stf8 [r20] = f38, 8
+ getf.sig r27 = f39
+ getf.sig r8 = f43
+ br .Lcj2
+
+.grt2:
+ ldf8 f32 = [up], 8
+ ldf8 f44 = [rp], 8
+ ;;
+ ldf8 f33 = [up], 8
+ xma.l f38 = f7, f6, f8
+ ldf8 f45 = [rp], 8
+ xma.hu f42 = f7, f6, f8
+ ;;
+ ldf8 f34 = [up], 8
+ xma.l f39 = f35, f6, f47
+ ldf8 f46 = [rp], 8
+ xma.hu f43 = f35, f6, f47
+ ;;
+ ldf8 f35 = [up], 8
+ ldf8 f47 = [rp], 8
+ br.cloop.dptk .grt6
+
+ stf8 [r20] = f38, 8
+ xma.l f36 = f32, f6, f44
+ xma.hu f40 = f32, f6, f44
+ ;;
+ getf.sig r30 = f42
+ getf.sig r27 = f39
+ xma.l f37 = f33, f6, f45
+ xma.hu f41 = f33, f6, f45
+ ;;
+ getf.sig r31 = f43
+ getf.sig r24 = f36
+ xma.l f38 = f34, f6, f46
+ xma.hu f42 = f34, f6, f46
+ ;;
+ getf.sig r28 = f40
+ getf.sig r25 = f37
+ xma.l f39 = f35, f6, f47
+ xma.hu f43 = f35, f6, f47
+ br .Lcj6
+
+.grt6:
+ mov r29 = 0
+ xma.l f36 = f32, f6, f44
+ xma.hu f40 = f32, f6, f44
+ ;;
+ ldf8 f32 = [up], 8
+ getf.sig r26 = f38
+ ;;
+ getf.sig r30 = f42
+ xma.l f37 = f33, f6, f45
+ ldf8 f44 = [rp], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ ldf8 f33 = [up], 8
+ getf.sig r27 = f39
+ ;;
+ getf.sig r31 = f43
+ xma.l f38 = f34, f6, f46
+ ldf8 f45 = [rp], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ ldf8 f34 = [up], 8
+ getf.sig r24 = f36
+ br .LL10
+
+
+.Lb11: ldf8 f34 = [up], 8
+ ldf8 f46 = [rp], 8
+ ;;
+ ldf8 f35 = [up], 8
+ ldf8 f47 = [rp], 8
+ br.cloop.dptk .grt3
+ ;;
+
+ xma.l f37 = f7, f6, f8
+ xma.hu f41 = f7, f6, f8
+ xma.l f38 = f34, f6, f46
+ xma.hu f42 = f34, f6, f46
+ xma.l f39 = f35, f6, f47
+ xma.hu f43 = f35, f6, f47
+ ;;
+ getf.sig r29 = f41
+ stf8 [r20] = f37, 8
+ getf.sig r26 = f38
+ getf.sig r30 = f42
+ getf.sig r27 = f39
+ getf.sig r8 = f43
+ br .Lcj3
+
+.grt3:
+ ldf8 f32 = [up], 8
+ xma.l f37 = f7, f6, f8
+ ldf8 f44 = [rp], 8
+ xma.hu f41 = f7, f6, f8
+ ;;
+ ldf8 f33 = [up], 8
+ xma.l f38 = f34, f6, f46
+ ldf8 f45 = [rp], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ ldf8 f34 = [up], 8
+ xma.l f39 = f35, f6, f47
+ ldf8 f46 = [rp], 8
+ xma.hu f43 = f35, f6, f47
+ ;;
+ ldf8 f35 = [up], 8
+ getf.sig r25 = f37 C FIXME
+ ldf8 f47 = [rp], 8
+ br.cloop.dptk .grt7
+
+ getf.sig r29 = f41
+ stf8 [r20] = f37, 8 C FIXME
+ xma.l f36 = f32, f6, f44
+ getf.sig r26 = f38
+ xma.hu f40 = f32, f6, f44
+ ;;
+ getf.sig r30 = f42
+ xma.l f37 = f33, f6, f45
+ getf.sig r27 = f39
+ xma.hu f41 = f33, f6, f45
+ ;;
+ getf.sig r31 = f43
+ xma.l f38 = f34, f6, f46
+ getf.sig r24 = f36
+ xma.hu f42 = f34, f6, f46
+ br .Lcj7
+
+.grt7:
+ getf.sig r29 = f41
+ xma.l f36 = f32, f6, f44
+ mov r28 = 0
+ xma.hu f40 = f32, f6, f44
+ ;;
+ ldf8 f32 = [up], 8
+ getf.sig r26 = f38
+ ;;
+ getf.sig r30 = f42
+ xma.l f37 = f33, f6, f45
+ ldf8 f44 = [rp], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ ldf8 f33 = [up], 8
+ getf.sig r27 = f39
+ br .LL11
+
+
+.Lb00: ldf8 f33 = [up], 8
+ ldf8 f45 = [rp], 8
+ ;;
+ ldf8 f34 = [up], 8
+ ldf8 f46 = [rp], 8
+ ;;
+ ldf8 f35 = [up], 8
+ xma.l f36 = f7, f6, f8
+ ldf8 f47 = [rp], 8
+ xma.hu f40 = f7, f6, f8
+ br.cloop.dptk .grt4
+
+ xma.l f37 = f33, f6, f45
+ xma.hu f41 = f33, f6, f45
+ xma.l f38 = f34, f6, f46
+ xma.hu f42 = f34, f6, f46
+ ;;
+ getf.sig r28 = f40
+ stf8 [r20] = f36, 8
+ xma.l f39 = f35, f6, f47
+ getf.sig r25 = f37
+ xma.hu f43 = f35, f6, f47
+ ;;
+ getf.sig r29 = f41
+ getf.sig r26 = f38
+ getf.sig r30 = f42
+ getf.sig r27 = f39
+ br .Lcj4
+
+.grt4:
+ ldf8 f32 = [up], 8
+ xma.l f37 = f33, f6, f45
+ ldf8 f44 = [rp], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ ldf8 f33 = [up], 8
+ xma.l f38 = f34, f6, f46
+ ldf8 f45 = [rp], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ ldf8 f34 = [up], 8
+ getf.sig r24 = f36 C FIXME
+ xma.l f39 = f35, f6, f47
+ ldf8 f46 = [rp], 8
+ getf.sig r28 = f40
+ xma.hu f43 = f35, f6, f47
+ ;;
+ ldf8 f35 = [up], 8
+ getf.sig r25 = f37
+ ldf8 f47 = [rp], 8
+ br.cloop.dptk .grt8
+
+ getf.sig r29 = f41
+ stf8 [r20] = f36, 8 C FIXME
+ xma.l f36 = f32, f6, f44
+ getf.sig r26 = f38
+ getf.sig r30 = f42
+ xma.hu f40 = f32, f6, f44
+ ;;
+ xma.l f37 = f33, f6, f45
+ getf.sig r27 = f39
+ xma.hu f41 = f33, f6, f45
+ br .Lcj8
+
+.grt8:
+ getf.sig r29 = f41
+ xma.l f36 = f32, f6, f44
+ mov r31 = 0
+ xma.hu f40 = f32, f6, f44
+ ;;
+ ldf8 f32 = [up], 8
+ getf.sig r26 = f38
+ br .LL00
+
+
+C *** MAIN LOOP START ***
+ ALIGN(32) C insn fed cycle #
+.Loop:
+ .pred.rel "mutex", p6, p7 C num by i1 i2
+ getf.sig r29 = f41 C 00 16 0 0
+ xma.l f36 = f32, f6, f44 C 01 06,15 0 0
+ (p6) add r14 = r30, r27, 1 C 02 0 0
+ ldf8 f47 = [rp], 8 C 03 0 0
+ xma.hu f40 = f32, f6, f44 C 04 06,15 0 0
+ (p7) add r14 = r30, r27 C 05 0 0
+ ;;
+ .pred.rel "mutex", p6, p7
+ ldf8 f32 = [up], 8 C 06 1 1
+ (p6) cmp.leu p8, p9 = r14, r27 C 07 1 1
+ (p7) cmp.ltu p8, p9 = r14, r27 C 08 1 1
+ getf.sig r26 = f38 C 09 25 2 1
+ st8 [r20] = r14, 8 C 10 2 1
+ nop.b 0 C 11 2 1
+ ;;
+.LL00:
+ .pred.rel "mutex", p8, p9
+ getf.sig r30 = f42 C 12 28 3 2
+ xma.l f37 = f33, f6, f45 C 13 18,27 3 2
+ (p8) add r16 = r31, r24, 1 C 14 3 2
+ ldf8 f44 = [rp], 8 C 15 3 2
+ xma.hu f41 = f33, f6, f45 C 16 18,27 3 2
+ (p9) add r16 = r31, r24 C 17 3 2
+ ;;
+ .pred.rel "mutex", p8, p9
+ ldf8 f33 = [up], 8 C 18 4 3
+ (p8) cmp.leu p6, p7 = r16, r24 C 19 4 3
+ (p9) cmp.ltu p6, p7 = r16, r24 C 20 4 3
+ getf.sig r27 = f39 C 21 37 5 3
+ st8 [r20] = r16, 8 C 22 5 3
+ nop.b 0 C 23 5 3
+ ;;
+.LL11:
+ .pred.rel "mutex", p6, p7
+ getf.sig r31 = f43 C 24 40 6 4
+ xma.l f38 = f34, f6, f46 C 25 30,39 6 4
+ (p6) add r14 = r28, r25, 1 C 26 6 4
+ ldf8 f45 = [rp], 8 C 27 6 4
+ xma.hu f42 = f34, f6, f46 C 28 30,39 6 4
+ (p7) add r14 = r28, r25 C 29 6 4
+ ;;
+ .pred.rel "mutex", p6, p7
+ ldf8 f34 = [up], 8 C 30 7 5
+ (p6) cmp.leu p8, p9 = r14, r25 C 31 7 5
+ (p7) cmp.ltu p8, p9 = r14, r25 C 32 7 5
+ getf.sig r24 = f36 C 33 01 8 5
+ st8 [r20] = r14, 8 C 34 8 5
+ nop.b 0 C 35 8 5
+ ;;
+.LL10:
+ .pred.rel "mutex", p8, p9
+ getf.sig r28 = f40 C 36 04 9 6
+ xma.l f39 = f35, f6, f47 C 37 42,03 9 6
+ (p8) add r16 = r29, r26, 1 C 38 9 6
+ ldf8 f46 = [rp], 8 C 39 9 6
+ xma.hu f43 = f35, f6, f47 C 40 42,03 9 6
+ (p9) add r16 = r29, r26 C 41 9 6
+ ;;
+ .pred.rel "mutex", p8, p9
+ ldf8 f35 = [up], 8 C 42 10 7
+ (p8) cmp.leu p6, p7 = r16, r26 C 43 10 7
+ (p9) cmp.ltu p6, p7 = r16, r26 C 44 10 7
+ getf.sig r25 = f37 C 45 13 11 7
+ st8 [r20] = r16, 8 C 46 11 7
+ br.cloop.dptk .Loop C 47 11 7
+C *** MAIN LOOP END ***
+ ;;
+.Le0:
+ .pred.rel "mutex", p6, p7
+ getf.sig r29 = f41 C
+ xma.l f36 = f32, f6, f44 C
+ (p6) add r14 = r30, r27, 1 C
+ ldf8 f47 = [rp], 8 C
+ xma.hu f40 = f32, f6, f44 C
+ (p7) add r14 = r30, r27 C
+ ;;
+ .pred.rel "mutex", p6, p7
+ (p6) cmp.leu p8, p9 = r14, r27 C
+ (p7) cmp.ltu p8, p9 = r14, r27 C
+ getf.sig r26 = f38 C
+ st8 [r20] = r14, 8 C
+ ;;
+ .pred.rel "mutex", p8, p9
+ getf.sig r30 = f42 C
+ xma.l f37 = f33, f6, f45 C
+ (p8) add r16 = r31, r24, 1 C
+ xma.hu f41 = f33, f6, f45 C
+ (p9) add r16 = r31, r24 C
+ ;;
+ .pred.rel "mutex", p8, p9
+ (p8) cmp.leu p6, p7 = r16, r24 C
+ (p9) cmp.ltu p6, p7 = r16, r24 C
+ getf.sig r27 = f39 C
+ st8 [r20] = r16, 8 C
+ ;;
+.Lcj8:
+ .pred.rel "mutex", p6, p7
+ getf.sig r31 = f43 C
+ xma.l f38 = f34, f6, f46 C
+ (p6) add r14 = r28, r25, 1 C
+ xma.hu f42 = f34, f6, f46 C
+ (p7) add r14 = r28, r25 C
+ ;;
+ .pred.rel "mutex", p6, p7
+ (p6) cmp.leu p8, p9 = r14, r25 C
+ (p7) cmp.ltu p8, p9 = r14, r25 C
+ getf.sig r24 = f36 C
+ st8 [r20] = r14, 8 C
+ ;;
+.Lcj7:
+ .pred.rel "mutex", p8, p9
+ getf.sig r28 = f40 C
+ xma.l f39 = f35, f6, f47 C
+ (p8) add r16 = r29, r26, 1 C
+ xma.hu f43 = f35, f6, f47 C
+ (p9) add r16 = r29, r26 C
+ ;;
+ .pred.rel "mutex", p8, p9
+ (p8) cmp.leu p6, p7 = r16, r26 C
+ (p9) cmp.ltu p6, p7 = r16, r26 C
+ getf.sig r25 = f37 C
+ st8 [r20] = r16, 8 C
+ ;;
+.Lcj6:
+ .pred.rel "mutex", p6, p7
+ getf.sig r29 = f41 C
+ (p6) add r14 = r30, r27, 1 C
+ (p7) add r14 = r30, r27 C
+ ;;
+ .pred.rel "mutex", p6, p7
+ (p6) cmp.leu p8, p9 = r14, r27 C
+ (p7) cmp.ltu p8, p9 = r14, r27 C
+ getf.sig r26 = f38 C
+ st8 [r20] = r14, 8 C
+ ;;
+.Lcj5:
+ .pred.rel "mutex", p8, p9
+ getf.sig r30 = f42 C
+ (p8) add r16 = r31, r24, 1 C
+ (p9) add r16 = r31, r24 C
+ ;;
+ .pred.rel "mutex", p8, p9
+ (p8) cmp.leu p6, p7 = r16, r24 C
+ (p9) cmp.ltu p6, p7 = r16, r24 C
+ getf.sig r27 = f39 C
+ st8 [r20] = r16, 8 C
+ ;;
+.Lcj4:
+ .pred.rel "mutex", p6, p7
+ getf.sig r8 = f43 C
+ (p6) add r14 = r28, r25, 1 C
+ (p7) add r14 = r28, r25 C
+ ;;
+ .pred.rel "mutex", p6, p7
+ st8 [r20] = r14, 8 C
+ (p6) cmp.leu p8, p9 = r14, r25 C
+ (p7) cmp.ltu p8, p9 = r14, r25 C
+ ;;
+.Lcj3:
+ .pred.rel "mutex", p8, p9
+ (p8) add r16 = r29, r26, 1 C
+ (p9) add r16 = r29, r26 C
+ ;;
+ .pred.rel "mutex", p8, p9
+ st8 [r20] = r16, 8 C
+ (p8) cmp.leu p6, p7 = r16, r26 C
+ (p9) cmp.ltu p6, p7 = r16, r26 C
+ ;;
+.Lcj2:
+ .pred.rel "mutex", p6, p7
+ (p6) add r14 = r30, r27, 1 C
+ (p7) add r14 = r30, r27 C
+ ;;
+ .pred.rel "mutex", p6, p7
+ st8 [r20] = r14 C
+ (p6) cmp.leu p8, p9 = r14, r27 C
+ (p7) cmp.ltu p8, p9 = r14, r27 C
+ ;;
+ (p8) add r8 = 1, r8 C M I
+ mov.i ar.lc = r2 C I0
+ br.ret.sptk.many b0 C B
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/addmul_2.asm b/gmp/mpn/ia64/addmul_2.asm
new file mode 100644
index 0000000000..f5bc46b75d
--- /dev/null
+++ b/gmp/mpn/ia64/addmul_2.asm
@@ -0,0 +1,708 @@
+dnl IA-64 mpn_addmul_2 -- Multiply a n-limb number with a 2-limb number and
+dnl add the result to a (n+1)-limb number.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2004, 2005, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 3.65
+C Itanium 2: 1.625
+
+C TODO
+C * Clean up variable names, and try to decrease the number of distinct
+C registers used.
+C * Clean up feed-in code to not require zeroing several registers.
+C * Make sure we don't depend on uninitialised predicate registers.
+C * Could perhaps save a few cycles by using 1 c/l carry propagation in
+C wind-down code.
+C * Ultimately rewrite. The problem with this code is that it first uses a
+C loaded u value in one xma pair, then leaves it live over several unrelated
+C xma pairs, before it uses it again. It should actually be quite possible
+C to just swap some aligned xma pairs around. But we should then schedule
+C u loads further from the first use.
+
+C INPUT PARAMETERS
+define(`rp',`r32')
+define(`up',`r33')
+define(`n',`r34')
+define(`vp',`r35')
+
+define(`srp',`r3')
+
+define(`v0',`f6')
+define(`v1',`f7')
+
+define(`s0',`r14')
+define(`acc0',`r15')
+
+define(`pr0_0',`r16') define(`pr0_1',`r17')
+define(`pr0_2',`r18') define(`pr0_3',`r19')
+
+define(`pr1_0',`r20') define(`pr1_1',`r21')
+define(`pr1_2',`r22') define(`pr1_3',`r23')
+
+define(`acc1_0',`r24') define(`acc1_1',`r25')
+define(`acc1_2',`r26') define(`acc1_3',`r27')
+
+dnl define(`',`r28')
+dnl define(`',`r29')
+dnl define(`',`r30')
+dnl define(`',`r31')
+
+define(`fp0b_0',`f8') define(`fp0b_1',`f9')
+define(`fp0b_2',`f10') define(`fp0b_3',`f11')
+
+define(`fp1a_0',`f12') define(`fp1a_1',`f13')
+define(`fp1a_2',`f14') define(`fp1a_3',`f15')
+
+define(`fp1b_0',`f32') define(`fp1b_1',`f33')
+define(`fp1b_2',`f34') define(`fp1b_3',`f35')
+
+define(`fp2a_0',`f36') define(`fp2a_1',`f37')
+define(`fp2a_2',`f38') define(`fp2a_3',`f39')
+
+define(`r_0',`f40') define(`r_1',`f41')
+define(`r_2',`f42') define(`r_3',`f43')
+
+define(`u_0',`f44') define(`u_1',`f45')
+define(`u_2',`f46') define(`u_3',`f47')
+
+define(`rx',`f48')
+define(`ux',`f49')
+define(`ry',`f50')
+define(`uy',`f51')
+
+ASM_START()
+PROLOGUE(mpn_addmul_2s)
+ .prologue
+ .save ar.lc, r2
+ .body
+
+ifdef(`HAVE_ABI_32',`
+.mmi; addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ addp4 vp = 0, vp C M I
+.mmi; nop 1
+ nop 1
+ zxt4 n = n C I
+ ;;')
+
+.mmi; ldf8 ux = [up], 8 C M
+ ldf8 v0 = [vp], 8 C M
+ mov r2 = ar.lc C I0
+.mmi; ldf8 rx = [rp], 8 C M
+ and r14 = 3, n C M I
+ add n = -2, n C M I
+ ;;
+.mmi; ldf8 uy = [up], 8 C M
+ ldf8 v1 = [vp] C M
+ shr.u n = n, 2 C I0
+.mmi; ldf8 ry = [rp], -8 C M
+ cmp.eq p14, p0 = 1, r14 C M I
+ cmp.eq p11, p0 = 2, r14 C M I
+ ;;
+.mmi; add srp = 16, rp C M I
+ cmp.eq p15, p0 = 3, r14 C M I
+ mov ar.lc = n C I0
+.bbb; (p14) br.dptk L(x01) C B
+ (p11) br.dptk L(x10) C B
+ (p15) br.dptk L(x11) C B
+ ;;
+
+L(x00): cmp.ne p6, p0 = r0, r0 C suppress initial xma pair
+ mov fp2a_3 = f0
+ br L(b00)
+L(x01): cmp.ne p14, p0 = r0, r0 C suppress initial xma pair
+ mov fp2a_2 = f0
+ br L(b01)
+L(x10): cmp.ne p11, p0 = r0, r0 C suppress initial xma pair
+ mov fp2a_1 = f0
+ br L(b10)
+L(x11): cmp.ne p15, p0 = r0, r0 C suppress initial xma pair
+ mov fp2a_0 = f0
+ br L(b11)
+
+EPILOGUE()
+
+PROLOGUE(mpn_addmul_2)
+ .prologue
+ .save ar.lc, r2
+ .body
+
+ifdef(`HAVE_ABI_32',`
+.mmi; addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ addp4 vp = 0, vp C M I
+.mmi; nop 1
+ nop 1
+ zxt4 n = n C I
+ ;;')
+
+.mmi; ldf8 ux = [up], 8 C M
+ ldf8 v0 = [vp], 8 C M
+ mov r2 = ar.lc C I0
+.mmi; ldf8 rx = [rp], 8 C M
+ and r14 = 3, n C M I
+ add n = -2, n C M I
+ ;;
+.mmi; ldf8 uy = [up], 8 C M
+ ldf8 v1 = [vp] C M
+ shr.u n = n, 2 C I0
+.mmi; ldf8 ry = [rp], -8 C M
+ cmp.eq p14, p0 = 1, r14 C M I
+ cmp.eq p11, p0 = 2, r14 C M I
+ ;;
+.mmi; add srp = 16, rp C M I
+ cmp.eq p15, p6 = 3, r14 C M I
+ mov ar.lc = n C I0
+.bbb; (p14) br.dptk L(b01) C B
+ (p11) br.dptk L(b10) C B
+ (p15) br.dptk L(b11) C B
+ ;;
+
+ ALIGN(32)
+L(b00):
+.mmi; ldf8 r_1 = [srp], 8
+ ldf8 u_1 = [up], 8
+ mov acc1_2 = 0
+.mmi; mov pr1_2 = 0
+ mov pr0_3 = 0
+ cmp.ne p8, p9 = r0, r0
+ ;;
+.mfi; ldf8 r_2 = [srp], 8
+ xma.l fp0b_3 = ux, v0, rx
+ cmp.ne p12, p13 = r0, r0
+.mfb; ldf8 u_2 = [up], 8
+ xma.hu fp1b_3 = ux, v0, rx
+ br.cloop.dptk L(gt4)
+
+ xma.l fp0b_0 = uy, v0, ry
+ xma.hu fp1a_0 = uy, v0, ry
+ ;;
+ getfsig acc0 = fp0b_3
+ (p6) xma.hu fp2a_3 = ux, v1, fp1b_3 C suppressed for addmul_2s
+ (p6) xma.l fp1b_3 = ux, v1, fp1b_3 C suppressed for addmul_2s
+ ;;
+ xma.l fp0b_1 = u_1, v0, r_1
+ xma.hu fp1a_1 = u_1, v0, r_1
+ ;;
+ getfsig pr0_0 = fp0b_0
+ xma.l fp1b_0 = uy, v1, fp1a_0
+ xma.hu fp2a_0 = uy, v1, fp1a_0
+ ;;
+ getfsig pr1_3 = fp1b_3
+ getfsig acc1_3 = fp2a_3
+ xma.l fp0b_2 = u_2, v0, r_2
+ xma.hu fp1a_2 = u_2, v0, r_2
+ br L(cj4)
+
+L(gt4): xma.l fp0b_0 = uy, v0, ry
+ xma.hu fp1a_0 = uy, v0, ry
+ ;;
+ ldf8 r_3 = [srp], 8
+ getfsig acc0 = fp0b_3
+ (p6) xma.hu fp2a_3 = ux, v1, fp1b_3 C suppressed for addmul_2s
+ ldf8 u_3 = [up], 8
+ (p6) xma.l fp1b_3 = ux, v1, fp1b_3 C suppressed for addmul_2s
+ ;;
+ xma.l fp0b_1 = u_1, v0, r_1
+ xma.hu fp1a_1 = u_1, v0, r_1
+ ;;
+ ldf8 r_0 = [srp], 8
+ getfsig pr0_0 = fp0b_0
+ xma.l fp1b_0 = uy, v1, fp1a_0
+ xma.hu fp2a_0 = uy, v1, fp1a_0
+ ;;
+ ldf8 u_0 = [up], 8
+ getfsig pr1_3 = fp1b_3
+ xma.l fp0b_2 = u_2, v0, r_2
+ ;;
+ getfsig acc1_3 = fp2a_3
+ xma.hu fp1a_2 = u_2, v0, r_2
+ br L(00)
+
+
+ ALIGN(32)
+L(b01):
+.mmi; ldf8 r_0 = [srp], 8 C M
+ ldf8 u_0 = [up], 8 C M
+ mov acc1_1 = 0 C M I
+.mmi; mov pr1_1 = 0 C M I
+ mov pr0_2 = 0 C M I
+ cmp.ne p6, p7 = r0, r0 C M I
+ ;;
+.mfi; ldf8 r_1 = [srp], 8 C M
+ xma.l fp0b_2 = ux, v0, rx C F
+ cmp.ne p10, p11 = r0, r0 C M I
+.mfi; ldf8 u_1 = [up], 8 C M
+ xma.hu fp1b_2 = ux, v0, rx C F
+ nop 1
+ ;;
+ xma.l fp0b_3 = uy, v0, ry C F
+ xma.hu fp1a_3 = uy, v0, ry C F
+ ;;
+.mmf; getfsig acc0 = fp0b_2 C M
+ ldf8 r_2 = [srp], 8 C M
+ (p14) xma.hu fp2a_2 = ux, v1,fp1b_2 C F suppressed for addmul_2s
+.mfb; ldf8 u_2 = [up], 8 C M
+ (p14) xma.l fp1b_2 = ux, v1,fp1b_2 C F suppressed for addmul_2s
+ br.cloop.dptk L(gt5)
+
+ xma.l fp0b_0 = u_0, v0, r_0 C F
+ xma.hu fp1a_0 = u_0, v0, r_0 C F
+ ;;
+ getfsig pr0_3 = fp0b_3 C M
+ xma.l fp1b_3 = uy, v1,fp1a_3 C F
+ xma.hu fp2a_3 = uy, v1,fp1a_3 C F
+ ;;
+ getfsig pr1_2 = fp1b_2 C M
+ getfsig acc1_2 = fp2a_2 C M
+ xma.l fp0b_1 = u_1, v0, r_1 C F
+ xma.hu fp1a_1 = u_1, v0, r_1 C F
+ br L(cj5)
+
+L(gt5): xma.l fp0b_0 = u_0, v0, r_0
+ xma.hu fp1a_0 = u_0, v0, r_0
+ ;;
+ getfsig pr0_3 = fp0b_3
+ ldf8 r_3 = [srp], 8
+ xma.l fp1b_3 = uy, v1, fp1a_3
+ xma.hu fp2a_3 = uy, v1, fp1a_3
+ ;;
+ ldf8 u_3 = [up], 8
+ getfsig pr1_2 = fp1b_2
+ xma.l fp0b_1 = u_1, v0, r_1
+ ;;
+ getfsig acc1_2 = fp2a_2
+ xma.hu fp1a_1 = u_1, v0, r_1
+ br L(01)
+
+
+ ALIGN(32)
+L(b10): br.cloop.dptk L(gt2)
+ xma.l fp0b_1 = ux, v0, rx
+ xma.hu fp1b_1 = ux, v0, rx
+ ;;
+ xma.l fp0b_2 = uy, v0, ry
+ xma.hu fp1a_2 = uy, v0, ry
+ ;;
+ stf8 [rp] = fp0b_1, 8
+ (p11) xma.hu fp2a_1 = ux, v1, fp1b_1 C suppressed for addmul_2s
+ (p11) xma.l fp1b_1 = ux, v1, fp1b_1 C suppressed for addmul_2s
+ ;;
+ getfsig acc0 = fp0b_2
+ xma.l fp1b_2 = uy, v1, fp1a_2
+ xma.hu fp2a_2 = uy, v1, fp1a_2
+ ;;
+ getfsig pr1_1 = fp1b_1
+ getfsig acc1_1 = fp2a_1
+ mov ar.lc = r2
+ getfsig pr1_2 = fp1b_2
+ getfsig r8 = fp2a_2
+ ;;
+ add s0 = pr1_1, acc0
+ ;;
+ st8 [rp] = s0, 8
+ cmp.ltu p8, p9 = s0, pr1_1
+ sub r31 = -1, acc1_1
+ ;;
+ .pred.rel "mutex", p8, p9
+ (p8) add acc0 = pr1_2, acc1_1, 1
+ (p9) add acc0 = pr1_2, acc1_1
+ (p8) cmp.leu p10, p0 = r31, pr1_2
+ (p9) cmp.ltu p10, p0 = r31, pr1_2
+ ;;
+ st8 [rp] = acc0, 8
+ (p10) add r8 = 1, r8
+ br.ret.sptk.many b0
+
+
+L(gt2):
+.mmi; ldf8 r_3 = [srp], 8
+ ldf8 u_3 = [up], 8
+ mov acc1_0 = 0
+ ;;
+.mfi; ldf8 r_0 = [srp], 8
+ xma.l fp0b_1 = ux, v0, rx
+ mov pr1_0 = 0
+.mfi; ldf8 u_0 = [up], 8
+ xma.hu fp1b_1 = ux, v0, rx
+ mov pr0_1 = 0
+ ;;
+ xma.l fp0b_2 = uy, v0, ry
+ xma.hu fp1a_2 = uy, v0, ry
+ ;;
+ getfsig acc0 = fp0b_1
+ ldf8 r_1 = [srp], 8
+ (p11) xma.hu fp2a_1 = ux, v1, fp1b_1 C suppressed for addmul_2s
+ (p11) xma.l fp1b_1 = ux, v1, fp1b_1 C suppressed for addmul_2s
+ ;;
+ ldf8 u_1 = [up], 8
+ xma.l fp0b_3 = u_3, v0, r_3
+ xma.hu fp1a_3 = u_3, v0, r_3
+ ;;
+ getfsig pr0_2 = fp0b_2
+ ldf8 r_2 = [srp], 8
+ xma.l fp1b_2 = uy, v1, fp1a_2
+ xma.hu fp2a_2 = uy, v1, fp1a_2
+ ;;
+ ldf8 u_2 = [up], 8
+ getfsig pr1_1 = fp1b_1
+ ;;
+.mfi; getfsig acc1_1 = fp2a_1
+ xma.l fp0b_0 = u_0, v0, r_0
+ cmp.ne p8, p9 = r0, r0
+.mfb; cmp.ne p12, p13 = r0, r0
+ xma.hu fp1a_0 = u_0, v0, r_0
+ br.cloop.sptk.clr L(top)
+ br.many L(end)
+
+
+ ALIGN(32)
+L(b11): ldf8 r_2 = [srp], 8
+ mov pr1_3 = 0
+ mov pr0_0 = 0
+ ;;
+ ldf8 u_2 = [up], 8
+ mov acc1_3 = 0
+ br.cloop.dptk L(gt3)
+ ;;
+ cmp.ne p6, p7 = r0, r0
+ xma.l fp0b_0 = ux, v0, rx
+ xma.hu fp1b_0 = ux, v0, rx
+ ;;
+ cmp.ne p10, p11 = r0, r0
+ xma.l fp0b_1 = uy, v0, ry
+ xma.hu fp1a_1 = uy, v0, ry
+ ;;
+ getfsig acc0 = fp0b_0
+ (p15) xma.hu fp2a_0 = ux, v1, fp1b_0 C suppressed for addmul_2s
+ (p15) xma.l fp1b_0 = ux, v1, fp1b_0 C suppressed for addmul_2s
+ ;;
+ xma.l fp0b_2 = uy, v1, r_2
+ xma.hu fp1a_2 = uy, v1, r_2
+ ;;
+ getfsig pr0_1 = fp0b_1
+ xma.l fp1b_1 = u_2, v0, fp1a_1
+ xma.hu fp2a_1 = u_2, v0, fp1a_1
+ ;;
+ getfsig pr1_0 = fp1b_0
+ getfsig acc1_0 = fp2a_0
+ br L(cj3)
+
+L(gt3): ldf8 r_3 = [srp], 8
+ xma.l fp0b_0 = ux, v0, rx
+ cmp.ne p10, p11 = r0, r0
+ ldf8 u_3 = [up], 8
+ xma.hu fp1b_0 = ux, v0, rx
+ cmp.ne p6, p7 = r0, r0
+ ;;
+ xma.l fp0b_1 = uy, v0, ry
+ xma.hu fp1a_1 = uy, v0, ry
+ ;;
+ getfsig acc0 = fp0b_0
+ ldf8 r_0 = [srp], 8
+ (p15) xma.hu fp2a_0 = ux, v1, fp1b_0 C suppressed for addmul_2s
+ ldf8 u_0 = [up], 8
+ (p15) xma.l fp1b_0 = ux, v1, fp1b_0 C suppressed for addmul_2s
+ ;;
+ xma.l fp0b_2 = u_2, v0, r_2
+ xma.hu fp1a_2 = u_2, v0, r_2
+ ;;
+ getfsig pr0_1 = fp0b_1
+ ldf8 r_1 = [srp], 8
+ xma.l fp1b_1 = uy, v1, fp1a_1
+ xma.hu fp2a_1 = uy, v1, fp1a_1
+ ;;
+ ldf8 u_1 = [up], 8
+ getfsig pr1_0 = fp1b_0
+ ;;
+ getfsig acc1_0 = fp2a_0
+ xma.l fp0b_3 = u_3, v0, r_3
+ xma.hu fp1a_3 = u_3, v0, r_3
+ br L(11)
+
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+L(top): C 00
+ .pred.rel "mutex", p12, p13
+ getfsig pr0_3 = fp0b_3
+ ldf8 r_3 = [srp], 8
+ xma.l fp1b_3 = u_3, v1, fp1a_3
+ (p12) add s0 = pr1_0, acc0, 1
+ (p13) add s0 = pr1_0, acc0
+ xma.hu fp2a_3 = u_3, v1, fp1a_3
+ ;; C 01
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+ ldf8 u_3 = [up], 8
+ getfsig pr1_2 = fp1b_2
+ (p8) cmp.leu p6, p7 = acc0, pr0_1
+ (p9) cmp.ltu p6, p7 = acc0, pr0_1
+ (p12) cmp.leu p10, p11 = s0, pr1_0
+ (p13) cmp.ltu p10, p11 = s0, pr1_0
+ ;; C 02
+ .pred.rel "mutex", p6, p7
+ getfsig acc1_2 = fp2a_2
+ st8 [rp] = s0, 8
+ xma.l fp0b_1 = u_1, v0, r_1
+ (p6) add acc0 = pr0_2, acc1_0, 1
+ (p7) add acc0 = pr0_2, acc1_0
+ xma.hu fp1a_1 = u_1, v0, r_1
+ ;; C 03
+L(01):
+ .pred.rel "mutex", p10, p11
+ getfsig pr0_0 = fp0b_0
+ ldf8 r_0 = [srp], 8
+ xma.l fp1b_0 = u_0, v1, fp1a_0
+ (p10) add s0 = pr1_1, acc0, 1
+ (p11) add s0 = pr1_1, acc0
+ xma.hu fp2a_0 = u_0, v1, fp1a_0
+ ;; C 04
+ .pred.rel "mutex", p6, p7
+ .pred.rel "mutex", p10, p11
+ ldf8 u_0 = [up], 8
+ getfsig pr1_3 = fp1b_3
+ (p6) cmp.leu p8, p9 = acc0, pr0_2
+ (p7) cmp.ltu p8, p9 = acc0, pr0_2
+ (p10) cmp.leu p12, p13 = s0, pr1_1
+ (p11) cmp.ltu p12, p13 = s0, pr1_1
+ ;; C 05
+ .pred.rel "mutex", p8, p9
+ getfsig acc1_3 = fp2a_3
+ st8 [rp] = s0, 8
+ xma.l fp0b_2 = u_2, v0, r_2
+ (p8) add acc0 = pr0_3, acc1_1, 1
+ (p9) add acc0 = pr0_3, acc1_1
+ xma.hu fp1a_2 = u_2, v0, r_2
+ ;; C 06
+L(00):
+ .pred.rel "mutex", p12, p13
+ getfsig pr0_1 = fp0b_1
+ ldf8 r_1 = [srp], 8
+ xma.l fp1b_1 = u_1, v1, fp1a_1
+ (p12) add s0 = pr1_2, acc0, 1
+ (p13) add s0 = pr1_2, acc0
+ xma.hu fp2a_1 = u_1, v1, fp1a_1
+ ;; C 07
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+ ldf8 u_1 = [up], 8
+ getfsig pr1_0 = fp1b_0
+ (p8) cmp.leu p6, p7 = acc0, pr0_3
+ (p9) cmp.ltu p6, p7 = acc0, pr0_3
+ (p12) cmp.leu p10, p11 = s0, pr1_2
+ (p13) cmp.ltu p10, p11 = s0, pr1_2
+ ;; C 08
+ .pred.rel "mutex", p6, p7
+ getfsig acc1_0 = fp2a_0
+ st8 [rp] = s0, 8
+ xma.l fp0b_3 = u_3, v0, r_3
+ (p6) add acc0 = pr0_0, acc1_2, 1
+ (p7) add acc0 = pr0_0, acc1_2
+ xma.hu fp1a_3 = u_3, v0, r_3
+ ;; C 09
+L(11):
+ .pred.rel "mutex", p10, p11
+ getfsig pr0_2 = fp0b_2
+ ldf8 r_2 = [srp], 8
+ xma.l fp1b_2 = u_2, v1, fp1a_2
+ (p10) add s0 = pr1_3, acc0, 1
+ (p11) add s0 = pr1_3, acc0
+ xma.hu fp2a_2 = u_2, v1, fp1a_2
+ ;; C 10
+ .pred.rel "mutex", p6, p7
+ .pred.rel "mutex", p10, p11
+ ldf8 u_2 = [up], 8
+ getfsig pr1_1 = fp1b_1
+ (p6) cmp.leu p8, p9 = acc0, pr0_0
+ (p7) cmp.ltu p8, p9 = acc0, pr0_0
+ (p10) cmp.leu p12, p13 = s0, pr1_3
+ (p11) cmp.ltu p12, p13 = s0, pr1_3
+ ;; C 11
+ .pred.rel "mutex", p8, p9
+ getfsig acc1_1 = fp2a_1
+ st8 [rp] = s0, 8
+ xma.l fp0b_0 = u_0, v0, r_0
+ (p8) add acc0 = pr0_1, acc1_3, 1
+ (p9) add acc0 = pr0_1, acc1_3
+ xma.hu fp1a_0 = u_0, v0, r_0
+L(10): br.cloop.sptk.clr L(top) C 12
+ ;;
+C *** MAIN LOOP END ***
+L(end):
+ .pred.rel "mutex", p12, p13
+.mfi; getfsig pr0_3 = fp0b_3
+ xma.l fp1b_3 = u_3, v1, fp1a_3
+ (p12) add s0 = pr1_0, acc0, 1
+.mfi; (p13) add s0 = pr1_0, acc0
+ xma.hu fp2a_3 = u_3, v1, fp1a_3
+ nop 1
+ ;;
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+.mmi; getfsig pr1_2 = fp1b_2
+ st8 [rp] = s0, 8
+ (p8) cmp.leu p6, p7 = acc0, pr0_1
+.mmi; (p9) cmp.ltu p6, p7 = acc0, pr0_1
+ (p12) cmp.leu p10, p11 = s0, pr1_0
+ (p13) cmp.ltu p10, p11 = s0, pr1_0
+ ;;
+ .pred.rel "mutex", p6, p7
+.mfi; getfsig acc1_2 = fp2a_2
+ xma.l fp0b_1 = u_1, v0, r_1
+ nop 1
+.mmf; (p6) add acc0 = pr0_2, acc1_0, 1
+ (p7) add acc0 = pr0_2, acc1_0
+ xma.hu fp1a_1 = u_1, v0, r_1
+ ;;
+L(cj5):
+ .pred.rel "mutex", p10, p11
+.mfi; getfsig pr0_0 = fp0b_0
+ xma.l fp1b_0 = u_0, v1, fp1a_0
+ (p10) add s0 = pr1_1, acc0, 1
+.mfi; (p11) add s0 = pr1_1, acc0
+ xma.hu fp2a_0 = u_0, v1, fp1a_0
+ nop 1
+ ;;
+ .pred.rel "mutex", p6, p7
+ .pred.rel "mutex", p10, p11
+.mmi; getfsig pr1_3 = fp1b_3
+ st8 [rp] = s0, 8
+ (p6) cmp.leu p8, p9 = acc0, pr0_2
+.mmi; (p7) cmp.ltu p8, p9 = acc0, pr0_2
+ (p10) cmp.leu p12, p13 = s0, pr1_1
+ (p11) cmp.ltu p12, p13 = s0, pr1_1
+ ;;
+ .pred.rel "mutex", p8, p9
+.mfi; getfsig acc1_3 = fp2a_3
+ xma.l fp0b_2 = u_2, v0, r_2
+ nop 1
+.mmf; (p8) add acc0 = pr0_3, acc1_1, 1
+ (p9) add acc0 = pr0_3, acc1_1
+ xma.hu fp1a_2 = u_2, v0, r_2
+ ;;
+L(cj4):
+ .pred.rel "mutex", p12, p13
+.mfi; getfsig pr0_1 = fp0b_1
+ xma.l fp1b_1 = u_1, v1, fp1a_1
+ (p12) add s0 = pr1_2, acc0, 1
+.mfi; (p13) add s0 = pr1_2, acc0
+ xma.hu fp2a_1 = u_1, v1, fp1a_1
+ nop 1
+ ;;
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+.mmi; getfsig pr1_0 = fp1b_0
+ st8 [rp] = s0, 8
+ (p8) cmp.leu p6, p7 = acc0, pr0_3
+.mmi; (p9) cmp.ltu p6, p7 = acc0, pr0_3
+ (p12) cmp.leu p10, p11 = s0, pr1_2
+ (p13) cmp.ltu p10, p11 = s0, pr1_2
+ ;;
+ .pred.rel "mutex", p6, p7
+.mmi; getfsig acc1_0 = fp2a_0
+ (p6) add acc0 = pr0_0, acc1_2, 1
+ (p7) add acc0 = pr0_0, acc1_2
+ ;;
+L(cj3):
+ .pred.rel "mutex", p10, p11
+.mfi; getfsig pr0_2 = fp0b_2
+ xma.l fp1b_2 = u_2, v1, fp1a_2
+ (p10) add s0 = pr1_3, acc0, 1
+.mfi; (p11) add s0 = pr1_3, acc0
+ xma.hu fp2a_2 = u_2, v1, fp1a_2
+ nop 1
+ ;;
+ .pred.rel "mutex", p6, p7
+ .pred.rel "mutex", p10, p11
+.mmi; getfsig pr1_1 = fp1b_1
+ st8 [rp] = s0, 8
+ (p6) cmp.leu p8, p9 = acc0, pr0_0
+.mmi; (p7) cmp.ltu p8, p9 = acc0, pr0_0
+ (p10) cmp.leu p12, p13 = s0, pr1_3
+ (p11) cmp.ltu p12, p13 = s0, pr1_3
+ ;;
+ .pred.rel "mutex", p8, p9
+.mmi; getfsig acc1_1 = fp2a_1
+ (p8) add acc0 = pr0_1, acc1_3, 1
+ (p9) add acc0 = pr0_1, acc1_3
+ ;;
+ .pred.rel "mutex", p12, p13
+.mmi; (p12) add s0 = pr1_0, acc0, 1
+ (p13) add s0 = pr1_0, acc0
+ nop 1
+ ;;
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+.mmi; getfsig pr1_2 = fp1b_2
+ st8 [rp] = s0, 8
+ (p8) cmp.leu p6, p7 = acc0, pr0_1
+.mmi; (p9) cmp.ltu p6, p7 = acc0, pr0_1
+ (p12) cmp.leu p10, p11 = s0, pr1_0
+ (p13) cmp.ltu p10, p11 = s0, pr1_0
+ ;;
+ .pred.rel "mutex", p6, p7
+.mmi; getfsig r8 = fp2a_2
+ (p6) add acc0 = pr0_2, acc1_0, 1
+ (p7) add acc0 = pr0_2, acc1_0
+ ;;
+ .pred.rel "mutex", p10, p11
+.mmi; (p10) add s0 = pr1_1, acc0, 1
+ (p11) add s0 = pr1_1, acc0
+ (p6) cmp.leu p8, p9 = acc0, pr0_2
+ ;;
+ .pred.rel "mutex", p10, p11
+.mmi; (p7) cmp.ltu p8, p9 = acc0, pr0_2
+ (p10) cmp.leu p12, p13 = s0, pr1_1
+ (p11) cmp.ltu p12, p13 = s0, pr1_1
+ ;;
+ .pred.rel "mutex", p8, p9
+.mmi; st8 [rp] = s0, 8
+ (p8) add acc0 = pr1_2, acc1_1, 1
+ (p9) add acc0 = pr1_2, acc1_1
+ ;;
+ .pred.rel "mutex", p8, p9
+.mmi; (p8) cmp.leu p10, p11 = acc0, pr1_2
+ (p9) cmp.ltu p10, p11 = acc0, pr1_2
+ (p12) add acc0 = 1, acc0
+ ;;
+.mmi; st8 [rp] = acc0, 8
+ (p12) cmpeqor p10, p0 = 0, acc0
+ nop 1
+ ;;
+.mib; (p10) add r8 = 1, r8
+ mov ar.lc = r2
+ br.ret.sptk.many b0
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/aors_n.asm b/gmp/mpn/ia64/aors_n.asm
new file mode 100644
index 0000000000..81be606190
--- /dev/null
+++ b/gmp/mpn/ia64/aors_n.asm
@@ -0,0 +1,856 @@
+dnl IA-64 mpn_add_n/mpn_sub_n -- mpn addition and subtraction.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2003-2005, 2010, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 2.67
+C Itanium 2: 1.25
+
+C TODO
+C * Consider using special code for small n, using something like
+C "switch (8 * (n >= 8) + (n mod 8))" to enter it and feed-in code.
+C * The non-nc code was trimmed cycle for cycle to its current state. It is
+C probably hard to save more that an odd cycle there. The nc code is much
+C cruder (since tune/speed doesn't have any applicable direct measurements).
+C * Without the nc entry points, this becomes around 1800 bytes of object
+C code; the nc code adds over 1000 bytes. We should perhaps sacrifice a
+C few cycles for the non-nc code and let it fall into the nc code.
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`vp', `r34')
+define(`n', `r35')
+define(`cy', `r36')
+
+ifdef(`OPERATION_add_n',`
+ define(ADDSUB, add)
+ define(CND, ltu)
+ define(INCR, 1)
+ define(LIM, -1)
+ define(LIM2, 0)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)
+')
+ifdef(`OPERATION_sub_n',`
+ define(ADDSUB, sub)
+ define(CND, gtu)
+ define(INCR, -1)
+ define(LIM, 0)
+ define(LIM2, -1)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)
+')
+
+define(cmpeqor, `cmp.eq.or')
+define(PFDIST, 500)
+
+C Some useful aliases for registers we use
+define(`u0',`r14') define(`u1',`r15') define(`u2',`r16') define(`u3',`r17')
+define(`v0',`r24') define(`v1',`r25') define(`v2',`r26') define(`v3',`r27')
+define(`w0',`r28') define(`w1',`r29') define(`w2',`r30') define(`w3',`r31')
+define(`rpx',`r3')
+define(`upadv',`r20') define(`vpadv',`r21')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+PROLOGUE(func_nc)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',`
+ addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ nop.i 0
+ addp4 vp = 0, vp C M I
+ nop.m 0
+ zxt4 n = n C I
+ ;;
+')
+
+ {.mmi; ld8 r11 = [vp], 8 C M01
+ ld8 r10 = [up], 8 C M01
+ mov r2 = ar.lc C I0
+}{.mmi; and r14 = 7, n C M I
+ cmp.lt p15, p14 = 8, n C M I
+ add n = -6, n C M I
+ ;;
+}
+.mmi; add upadv = PFDIST, up C Merging these lines into the feed-in
+ add vpadv = PFDIST, vp C code could save a cycle per call at
+ mov r23 = cy C the expense of code size.
+ ;;
+{.mmi; cmp.eq p6, p0 = 1, r14 C M I
+ cmp.eq p7, p0 = 2, r14 C M I
+ cmp.eq p8, p0 = 3, r14 C M I
+}{.bbb
+ (p6) br.dptk .Lc001 C B
+ (p7) br.dptk .Lc010 C B
+ (p8) br.dptk .Lc011 C B
+ ;;
+}{.mmi; cmp.eq p9, p0 = 4, r14 C M I
+ cmp.eq p10, p0 = 5, r14 C M I
+ cmp.eq p11, p0 = 6, r14 C M I
+}{.bbb
+ (p9) br.dptk .Lc100 C B
+ (p10) br.dptk .Lc101 C B
+ (p11) br.dptk .Lc110 C B
+ ;;
+}{.mmi; ld8 r19 = [vp], 8 C M01
+ ld8 r18 = [up], 8 C M01
+ cmp.ne p13, p0 = 0, cy C copy cy to p13 M I
+}{.mmb; cmp.eq p12, p0 = 7, r14 C M I
+ nop 0
+ (p12) br.dptk .Lc111 C B
+ ;;
+}
+
+.Lc000:
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; add vpadv = PFDIST, vp C M I
+ ld8 v0 = [vp], 8 C M01
+ mov ar.lc = n C I0
+.mmi; ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = r10, r11 C M I
+ nop 0
+ ;;
+.mmi; add upadv = PFDIST, up C M I
+ ld8 v1 = [vp], 8 C M01
+ cmp.CND p7, p0 = w1, r10 C M I
+.mmi; ld8 u1 = [up], 8 C M01
+ ADDSUB w2 = r18, r19 C M I
+ add rpx = 8, rp C M I
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ cmp.CND p8, p0 = w2, r18 C M I
+ (p13) cmpeqor p7, p0 = LIM, w1 C M I
+.mmi; ld8 u2 = [up], 8 C M01
+ (p13) add w1 = INCR, w1 C M I
+ ADDSUB w3 = u3, v3 C M I
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, u3 C M I
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+.mmb; ld8 u3 = [up], 8 C M01
+ (p7) add w2 = INCR, w2 C M I
+ br L(m0)
+
+
+.Lc001:
+.mmi;
+ (p15) ld8 v1 = [vp], 8 C M01
+ (p15) ld8 u1 = [up], 8 C M01
+ ADDSUB w0 = r10, r11 C M I
+.mmb; nop 0
+ nop 0
+ (p15) br 1f
+ ;;
+.mmi; cmp.ne p9, p0 = 0, r23 C M I
+ mov r8 = 0
+ cmp.CND p6, p0 = w0, r10 C M I
+ ;;
+.mmb;
+ (p9) cmpeqor p6, p0 = LIM, w0 C M I
+ (p9) add w0 = INCR, w0 C M I
+ br L(cj1) C B
+1:
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ mov ar.lc = n C I0
+.mmi; nop 0
+ cmp.ne p9, p0 = 0, r23 C M I
+ nop 0
+ ;;
+.mmi; ld8 v0 = [vp], 8 C M01
+ cmp.CND p6, p0 = w0, r10 C M I
+ add rpx = 16, rp C M I
+.mmb; ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = u1, v1 C M I
+ br L(c1) C B
+
+
+.Lc010:
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ mov r8 = 0 C M I
+.mmb; ADDSUB w3 = r10, r11 C M I
+ cmp.ne p8, p0 = 0, r23 C M I
+ (p15) br 1f C B
+ ;;
+.mmi; cmp.CND p9, p0 = w3, r10 C M I
+ ADDSUB w0 = u0, v0 C M I
+ (p8) add w3 = INCR, w3 C M I
+ ;;
+.mmb; cmp.CND p6, p0 = w0, u0 C M I
+ (p8) cmpeqor p9, p0 = LIM2, w3 C M I
+ br L(cj2) C B
+1:
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ mov ar.lc = n C I0
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ cmp.CND p9, p0 = w3, r10 C M I
+ ;;
+.mmi;
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+ (p8) add w3 = INCR, w3 C M I
+ ADDSUB w0 = u0, v0 C M I
+.mmb; add rpx = 24, rp C M I
+ nop 0
+ br L(m23) C B
+
+
+.Lc011:
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+.mmi; ADDSUB w2 = r10, r11 C M I
+ cmp.ne p7, p0 = 0, r23 C M I
+ nop 0
+ ;;
+.mmb; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ (p15) br 1f C B
+.mmi; cmp.CND p8, p0 = w2, r10 C M I
+ ADDSUB w3 = u3, v3 C M I
+ nop 0
+ ;;
+.mmb;
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+ (p7) add w2 = INCR, w2 C M I
+ br L(cj3) C B
+1:
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ ADDSUB w3 = u3, v3 C M I
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ cmp.CND p8, p0 = w2, r10 C M I
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, u3 C M I
+ mov ar.lc = n C I0
+.mmi; ld8 u3 = [up], 8 C M01
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+ (p7) add w2 = INCR, w2 C M I
+ ;;
+.mmi; add rpx = 32, rp C M I
+ st8 [rp] = w2, 8 C M23
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+.mmb;
+ (p8) add w3 = INCR, w3 C M I
+ ADDSUB w0 = u0, v0 C M I
+ br L(m23)
+
+
+.Lc100:
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+.mmi; ADDSUB w1 = r10, r11 C M I
+ nop 0
+ nop 0
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ add rpx = 8, rp C M I
+.mmi; cmp.ne p6, p0 = 0, r23 C M I
+ cmp.CND p7, p0 = w1, r10 C M I
+ nop 0
+ ;;
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ ADDSUB w2 = u2, v2 C M I
+.mmb;
+ (p6) cmpeqor p7, p0 = LIM, w1 C M I
+ (p6) add w1 = INCR, w1 C M I
+ (p14) br L(cj4)
+ ;;
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ mov ar.lc = n C I0
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ cmp.CND p8, p0 = w2, u2 C M I
+ nop 0
+.mmi; ld8 u2 = [up], 8 C M01
+ nop 0
+ ADDSUB w3 = u3, v3 C M I
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, u3 C M I
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+.mmb; ld8 u3 = [up], 8 C M01
+ (p7) add w2 = INCR, w2 C M I
+ br L(m4)
+
+
+.Lc101:
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ mov ar.lc = n C I0
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ ADDSUB w0 = r10, r11 C M I
+.mmi; cmp.ne p9, p0 = 0, r23 C M I
+ add rpx = 16, rp C M I
+ nop 0
+ ;;
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ cmp.CND p6, p0 = w0, r10 C M I
+.mbb; ADDSUB w1 = u1, v1 C M I
+ (p15) br L(c5) C B
+ br L(end) C B
+
+
+.Lc110:
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; add upadv = PFDIST, up C M I
+ add vpadv = PFDIST, vp C M I
+ mov ar.lc = n C I0
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ ADDSUB w3 = r10, r11 C M I
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ ADDSUB w0 = u0, v0 C M I
+.mmi; cmp.CND p9, p0 = w3, r10 C M I
+ cmp.ne p8, p0 = 0, r23 C M I
+ add rpx = 24, rp C M I
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ nop 0
+.mmb;
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+ (p8) add w3 = INCR, w3 C M I
+ br L(m67) C B
+
+
+.Lc111:
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; add upadv = PFDIST, up C M I
+ ld8 v1 = [vp], 8 C M01
+ mov ar.lc = n C I0
+.mmi; ld8 u1 = [up], 8 C M01
+ ADDSUB w2 = r10, r11 C M I
+ nop 0
+ ;;
+.mmi; add vpadv = PFDIST, vp C M I
+ ld8 v2 = [vp], 8 C M01
+ cmp.CND p8, p0 = w2, r10 C M I
+.mmi; ld8 u2 = [up], 8 C M01
+ ADDSUB w3 = r18, r19 C M I
+ nop 0
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, r18 C M I
+ (p13) cmpeqor p8, p0 = LIM, w2 C M I
+.mmi; ld8 u3 = [up], 8 C M01
+ (p13) add w2 = INCR, w2 C M I
+ nop 0
+ ;;
+.mmi; add rpx = 32, rp C M I
+ st8 [rp] = w2, 8 C M23
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+.mmb;
+ (p8) add w3 = INCR, w3 C M I
+ ADDSUB w0 = u0, v0 C M I
+ br L(m67)
+
+EPILOGUE()
+
+PROLOGUE(func)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',`
+ addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ nop.i 0
+ addp4 vp = 0, vp C M I
+ nop.m 0
+ zxt4 n = n C I
+ ;;
+')
+
+ {.mmi; ld8 r11 = [vp], 8 C M01
+ ld8 r10 = [up], 8 C M01
+ mov r2 = ar.lc C I0
+}{.mmi; and r14 = 7, n C M I
+ cmp.lt p15, p14 = 8, n C M I
+ add n = -6, n C M I
+ ;;
+}{.mmi; cmp.eq p6, p0 = 1, r14 C M I
+ cmp.eq p7, p0 = 2, r14 C M I
+ cmp.eq p8, p0 = 3, r14 C M I
+}{.bbb
+ (p6) br.dptk .Lb001 C B
+ (p7) br.dptk .Lb010 C B
+ (p8) br.dptk .Lb011 C B
+ ;;
+}{.mmi; cmp.eq p9, p0 = 4, r14 C M I
+ cmp.eq p10, p0 = 5, r14 C M I
+ cmp.eq p11, p0 = 6, r14 C M I
+}{.bbb
+ (p9) br.dptk .Lb100 C B
+ (p10) br.dptk .Lb101 C B
+ (p11) br.dptk .Lb110 C B
+ ;;
+}{.mmi; ld8 r19 = [vp], 8 C M01
+ ld8 r18 = [up], 8 C M01
+ cmp.ne p13, p0 = r0, r0 C clear "CF" M I
+}{.mmb; cmp.eq p12, p0 = 7, r14 C M I
+ mov r23 = 0 C M I
+ (p12) br.dptk .Lb111 C B
+ ;;
+}
+
+.Lb000:
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = r10, r11 C M I
+ ;;
+.mmi; ld8 v1 = [vp], 8 C M01
+ cmp.CND p7, p0 = w1, r10 C M I
+ mov ar.lc = n C I0
+.mmi; ld8 u1 = [up], 8 C M01
+ ADDSUB w2 = r18, r19 C M I
+ add rpx = 8, rp C M I
+ ;;
+.mmi; add upadv = PFDIST, up
+ add vpadv = PFDIST, vp
+ cmp.CND p8, p0 = w2, r18 C M I
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ ADDSUB w3 = u3, v3 C M I
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, u3 C M I
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+.mmb; ld8 u3 = [up], 8 C M01
+ (p7) add w2 = INCR, w2 C M I
+ br L(m0) C B
+
+
+ ALIGN(32)
+.Lb001:
+.mmi; ADDSUB w0 = r10, r11 C M I
+ (p15) ld8 v1 = [vp], 8 C M01
+ mov r8 = 0 C M I
+ ;;
+.mmb; cmp.CND p6, p0 = w0, r10 C M I
+ (p15) ld8 u1 = [up], 8 C M01
+ (p14) br L(cj1) C B
+ ;;
+.mmi; add upadv = PFDIST, up
+ add vpadv = PFDIST, vp
+ shr.u n = n, 3 C I0
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ cmp.CND p6, p0 = w0, r10 C M I
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ mov ar.lc = n C I0
+ ;;
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = u1, v1 C M I
+ ;;
+.mmi; ld8 v1 = [vp], 8 C M01
+ cmp.CND p7, p0 = w1, u1 C M I
+ ADDSUB w2 = u2, v2 C M I
+.mmb; ld8 u1 = [up], 8 C M01
+ add rpx = 16, rp C M I
+ br L(m1) C B
+
+
+ ALIGN(32)
+.Lb010:
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+.mmb; ADDSUB w3 = r10, r11 C M I
+ nop 0
+ (p15) br L(gt2) C B
+ ;;
+.mmi; cmp.CND p9, p0 = w3, r10 C M I
+ ADDSUB w0 = u0, v0 C M I
+ mov r8 = 0 C M I
+ ;;
+.mmb; nop 0
+ cmp.CND p6, p0 = w0, u0 C M I
+ br L(cj2) C B
+L(gt2):
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ nop 0
+ ;;
+.mmi; add upadv = PFDIST, up
+ add vpadv = PFDIST, vp
+ mov ar.lc = n C I0
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ nop 0
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, r10 C M I
+ ADDSUB w0 = u0, v0 C M I
+.mmb; ld8 u3 = [up], 8 C M01
+ add rpx = 24, rp C M I
+ br L(m23) C B
+
+
+ ALIGN(32)
+.Lb011:
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ ADDSUB w2 = r10, r11 C M I
+ ;;
+.mmb; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ (p15) br 1f C B
+.mmb; cmp.CND p8, p0 = w2, r10 C M I
+ ADDSUB w3 = u3, v3 C M I
+ br L(cj3) C B
+1:
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; add upadv = PFDIST, up
+ add vpadv = PFDIST, vp
+ ADDSUB w3 = u3, v3 C M I
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ cmp.CND p8, p0 = w2, r10 C M I
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, u3 C M I
+ mov ar.lc = n C I0
+.mmi; ld8 u3 = [up], 8 C M01
+ nop 0
+ nop 0
+ ;;
+.mmi; add rpx = 32, rp C M I
+ st8 [rp] = w2, 8 C M23
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+.mmb;
+ (p8) add w3 = INCR, w3 C M I
+ ADDSUB w0 = u0, v0 C M I
+ br L(m23) C B
+
+
+ ALIGN(32)
+.Lb100:
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ ADDSUB w1 = r10, r11 C M I
+ ;;
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ cmp.CND p7, p0 = w1, r10 C M I
+.mmb; nop 0
+ ADDSUB w2 = u2, v2 C M I
+ (p14) br L(cj4) C B
+ ;;
+L(gt4):
+.mmi; add upadv = PFDIST, up
+ add vpadv = PFDIST, vp
+ mov ar.lc = n C I0
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ nop 0
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ cmp.CND p8, p0 = w2, u2 C M I
+ nop 0
+.mmi; ld8 u2 = [up], 8 C M01
+ ADDSUB w3 = u3, v3 C M I
+ add rpx = 8, rp C M I
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, u3 C M I
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+.mmb; ld8 u3 = [up], 8 C M01
+ (p7) add w2 = INCR, w2 C M I
+ br L(m4) C B
+
+
+ ALIGN(32)
+.Lb101:
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ ADDSUB w0 = r10, r11 C M I
+ ;;
+.mmi; add upadv = PFDIST, up
+ add vpadv = PFDIST, vp
+ add rpx = 16, rp C M I
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ nop 0
+ ;;
+.mmi; ld8 v0 = [vp], 8 C M01
+ cmp.CND p6, p0 = w0, r10 C M I
+ nop 0
+.mmb; ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = u1, v1 C M I
+ (p14) br L(cj5) C B
+ ;;
+L(gt5):
+.mmi; ld8 v1 = [vp], 8 C M01
+ cmp.CND p7, p0 = w1, u1 C M I
+ mov ar.lc = n C I0
+.mmb; ld8 u1 = [up], 8 C M01
+ ADDSUB w2 = u2, v2 C M I
+ br L(m5) C B
+
+
+ ALIGN(32)
+.Lb110:
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ ADDSUB w3 = r10, r11 C M I
+ ;;
+.mmi; add upadv = PFDIST, up
+ add vpadv = PFDIST, vp
+ mov ar.lc = n C I0
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ nop 0
+ ;;
+.mmi; ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, r10 C M I
+ ADDSUB w0 = u0, v0 C M I
+.mmb; ld8 u3 = [up], 8 C M01
+ add rpx = 24, rp C M I
+ br L(m67) C B
+
+
+ ALIGN(32)
+.Lb111:
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ shr.u n = n, 3 C I0
+ ;;
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ ADDSUB w2 = r10, r11 C M I
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ cmp.CND p8, p0 = w2, r10 C M I
+ mov ar.lc = n C I0
+.mmi; ld8 u2 = [up], 8 C M01
+ ADDSUB w3 = r18, r19 C M I
+ nop 0
+ ;;
+.mmi; add upadv = PFDIST, up
+ add vpadv = PFDIST, vp
+ nop 0
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ cmp.CND p9, p0 = w3, r18 C M I
+ ;;
+.mmi; add rpx = 32, rp C M I
+ st8 [rp] = w2, 8 C M23
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+.mmb;
+ (p8) add w3 = INCR, w3 C M I
+ ADDSUB w0 = u0, v0 C M I
+ br L(m67) C B
+
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+L(top):
+L(c5): ld8 v1 = [vp], 8 C M01
+ cmp.CND p7, p0 = w1, u1 C M I
+ (p9) cmpeqor p6, p0 = LIM, w0 C M I
+ ld8 u1 = [up], 8 C M01
+ (p9) add w0 = INCR, w0 C M I
+ ADDSUB w2 = u2, v2 C M I
+ ;;
+L(m5): ld8 v2 = [vp], 8 C M01
+ cmp.CND p8, p0 = w2, u2 C M I
+ (p6) cmpeqor p7, p0 = LIM, w1 C M I
+ ld8 u2 = [up], 8 C M01
+ (p6) add w1 = INCR, w1 C M I
+ ADDSUB w3 = u3, v3 C M I
+ ;;
+ st8 [rp] = w0, 8 C M23
+ ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, u3 C M I
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+ ld8 u3 = [up], 8 C M01
+ (p7) add w2 = INCR, w2 C M I
+ ;;
+L(m4): st8 [rp] = w1, 16 C M23
+ st8 [rpx] = w2, 32 C M23
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+ lfetch [upadv], 64
+ (p8) add w3 = INCR, w3 C M I
+ ADDSUB w0 = u0, v0 C M I
+ ;;
+L(m23): st8 [rp] = w3, 8 C M23
+ ld8 v0 = [vp], 8 C M01
+ cmp.CND p6, p0 = w0, u0 C M I
+ ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = u1, v1 C M I
+ nop.b 0
+ ;;
+L(c1): ld8 v1 = [vp], 8 C M01
+ cmp.CND p7, p0 = w1, u1 C M I
+ (p9) cmpeqor p6, p0 = LIM, w0 C M I
+ ld8 u1 = [up], 8 C M01
+ (p9) add w0 = INCR, w0 C M I
+ ADDSUB w2 = u2, v2 C M I
+ ;;
+L(m1): ld8 v2 = [vp], 8 C M01
+ cmp.CND p8, p0 = w2, u2 C M I
+ (p6) cmpeqor p7, p0 = LIM, w1 C M I
+ ld8 u2 = [up], 8 C M01
+ (p6) add w1 = INCR, w1 C M I
+ ADDSUB w3 = u3, v3 C M I
+ ;;
+ st8 [rp] = w0, 8 C M23
+ ld8 v3 = [vp], 8 C M01
+ cmp.CND p9, p0 = w3, u3 C M I
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+ ld8 u3 = [up], 8 C M01
+ (p7) add w2 = INCR, w2 C M I
+ ;;
+L(m0): st8 [rp] = w1, 16 C M23
+ st8 [rpx] = w2, 32 C M23
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+ lfetch [vpadv], 64
+ (p8) add w3 = INCR, w3 C M I
+ ADDSUB w0 = u0, v0 C M I
+ ;;
+L(m67): st8 [rp] = w3, 8 C M23
+ ld8 v0 = [vp], 8 C M01
+ cmp.CND p6, p0 = w0, u0 C M I
+ ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = u1, v1 C M I
+ br.cloop.dptk L(top) C B
+ ;;
+C *** MAIN LOOP END ***
+
+L(end):
+.mmi;
+ (p9) cmpeqor p6, p0 = LIM, w0 C M I
+ (p9) add w0 = INCR, w0 C M I
+ mov ar.lc = r2 C I0
+L(cj5):
+.mmi; cmp.CND p7, p0 = w1, u1 C M I
+ ADDSUB w2 = u2, v2 C M I
+ nop 0
+ ;;
+.mmi; st8 [rp] = w0, 8 C M23
+ (p6) cmpeqor p7, p0 = LIM, w1 C M I
+ (p6) add w1 = INCR, w1 C M I
+L(cj4):
+.mmi; cmp.CND p8, p0 = w2, u2 C M I
+ ADDSUB w3 = u3, v3 C M I
+ nop 0
+ ;;
+.mmi; st8 [rp] = w1, 8 C M23
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+ (p7) add w2 = INCR, w2 C M I
+L(cj3):
+.mmi; cmp.CND p9, p0 = w3, u3 C M I
+ ADDSUB w0 = u0, v0 C M I
+ nop 0
+ ;;
+.mmi; st8 [rp] = w2, 8 C M23
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+ (p8) add w3 = INCR, w3 C M I
+.mmi; cmp.CND p6, p0 = w0, u0 C M I
+ nop 0
+ mov r8 = 0 C M I
+ ;;
+L(cj2):
+.mmi; st8 [rp] = w3, 8 C M23
+ (p9) cmpeqor p6, p0 = LIM, w0 C M I
+ (p9) add w0 = INCR, w0 C M I
+ ;;
+L(cj1):
+.mmb; st8 [rp] = w0, 8 C M23
+ (p6) mov r8 = 1 C M I
+ br.ret.sptk.many b0 C B
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/aorsorrlsh1_n.asm b/gmp/mpn/ia64/aorsorrlsh1_n.asm
new file mode 100644
index 0000000000..9b58b9e11f
--- /dev/null
+++ b/gmp/mpn/ia64/aorsorrlsh1_n.asm
@@ -0,0 +1,48 @@
+dnl IA-64 mpn_addlsh1_n, mpn_sublsh1_n, mpn_rsblsh1_n
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 3.0
+C Itanium 2: 1.5
+
+
+define(LSH, 1)
+
+ifdef(`OPERATION_addlsh1_n',`define(`DO_add')')
+ifdef(`OPERATION_sublsh1_n',`define(`DO_sub')')
+ifdef(`OPERATION_rsblsh1_n',`define(`DO_rsb')')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n mpn_rsblsh1_n)
+
+include_mpn(`ia64/aorsorrlshC_n.asm')
diff --git a/gmp/mpn/ia64/aorsorrlsh2_n.asm b/gmp/mpn/ia64/aorsorrlsh2_n.asm
new file mode 100644
index 0000000000..39b384a91b
--- /dev/null
+++ b/gmp/mpn/ia64/aorsorrlsh2_n.asm
@@ -0,0 +1,48 @@
+dnl IA-64 mpn_addlsh2_n, mpn_sublsh2_n, mpn_rsblsh2_n
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 3.0
+C Itanium 2: 1.5
+
+
+define(LSH, 2)
+
+ifdef(`OPERATION_addlsh2_n',`define(`DO_add')')
+ifdef(`OPERATION_sublsh2_n',`define(`DO_sub')')
+ifdef(`OPERATION_rsblsh2_n',`define(`DO_rsb')')
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_sublsh2_n mpn_rsblsh2_n)
+
+include_mpn(`ia64/aorsorrlshC_n.asm')
diff --git a/gmp/mpn/ia64/aorsorrlshC_n.asm b/gmp/mpn/ia64/aorsorrlshC_n.asm
new file mode 100644
index 0000000000..d327838402
--- /dev/null
+++ b/gmp/mpn/ia64/aorsorrlshC_n.asm
@@ -0,0 +1,397 @@
+dnl IA-64 mpn_addlshC_n, mpn_sublshC_n, mpn_rsblshC_n.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+C cycles/limb
+C Itanium: ?
+C Itanium 2: 1.5
+
+C TODO
+C * Use shladd in feed-in code (for mpn_addlshC_n).
+C * Rewrite loop to schedule loads closer to use, since we do prefetch.
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`vp', `r34')
+define(`n', `r35')
+
+ifdef(`DO_add', `
+ define(`ADDSUB', `add $1 = $2, $3')
+ define(`CMP', `cmp.ltu $1,p0 = $2, $3')
+ define(`INCR', 1)
+ define(`LIM', -1)
+ define(`func', mpn_addlsh`'LSH`'_n)')
+ifdef(`DO_sub', `
+ define(`ADDSUB', `sub $1 = $2, $3')
+ define(`CMP', `cmp.gtu $1,p0 = $2, $3')
+ define(`INCR', -1)
+ define(`LIM', 0)
+ define(`func', mpn_sublsh`'LSH`'_n)')
+ifdef(`DO_rsb', `
+ define(`ADDSUB', `sub $1 = $3, $2')
+ define(`CMP', `cmp.gtu $1,p0 = $2, $4')
+ define(`INCR', -1)
+ define(`LIM', 0)
+ define(`func', mpn_rsblsh`'LSH`'_n)')
+
+define(cmpeqor, `cmp.eq.or')
+define(PFDIST, 500)
+
+define(`u0',`r14') define(`u1',`r15') define(`u2',`r16') define(`u3',`r17')
+define(`v0',`r18') define(`v1',`r19') define(`v2',`r20') define(`v3',`r21')
+define(`w0',`r22') define(`w1',`r23') define(`w2',`r24') define(`w3',`r25')
+define(`s0',`r26') define(`s1',`r27') define(`s2',`r28') define(`s3',`r29')
+define(`x0',`r30') define(`x1',`r31') define(`x2',`r3') define(`x3',`r9')
+
+C r3 r8 r9 r10 r11
+
+ASM_START()
+PROLOGUE(func)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',`
+ addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ nop.i 0
+ addp4 vp = 0, vp C M I
+ nop.m 0
+ zxt4 n = n C I
+ ;;
+')
+ {.mmi; ld8 r11 = [vp], 8 C M01
+ ld8 r10 = [up], 8 C M01
+ mov.i r2 = ar.lc C I0
+}{.mmi; and r14 = 3, n C M I
+ cmp.lt p15, p0 = 4, n C M I
+ add n = -5, n C M I
+ ;;
+}{.mmi; cmp.eq p6, p0 = 1, r14 C M I
+ cmp.eq p7, p0 = 2, r14 C M I
+ cmp.eq p8, p0 = 3, r14 C M I
+}{.bbb
+ (p6) br.dptk .Lb01 C B
+ (p7) br.dptk .Lb10 C B
+ (p8) br.dptk .Lb11 C B
+}
+
+.Lb00: ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ ;;
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ shl x3 = r11, LSH C I0
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ shrp x0 = v0, r11, 64-LSH C I0
+.mmb; ADDSUB( w3, r10, x3) C M I
+ nop 0
+ (p15) br.dpnt .grt4 C B
+ ;;
+.mii; CMP( p7, w3, r10, x3) C M II0
+ shrp x1 = v1, v0, 64-LSH C I0
+ ADDSUB( w0, u0, x0) C M I
+ ;;
+.mii; CMP( p8, w0, u0, x0) C M I
+ shrp x2 = v2, v1, 64-LSH C I0
+ ADDSUB( w1, u1, x1) C M I
+.mmb; nop 0
+ nop 0
+ br .Lcj4 C B
+
+ALIGN(32)
+.grt4: ld8 v3 = [vp], 8 C M01
+ shrp x0 = v0, r11, 64-LSH C I0
+ CMP( p8, w3, r10, x3) C M I
+ ;;
+.mmi; ld8 u3 = [up], 8 C M01
+ add r11 = PFDIST, vp
+ shrp x1 = v1, v0, 64-LSH C I0
+.mmi; ld8 v0 = [vp], 8 C M01
+ ADDSUB( w0, u0, x0) C M I
+ nop 0
+ ;;
+.mmi; CMP( p6, w0, u0, x0) C M I
+ add r10 = PFDIST, up
+ mov.i ar.lc = n C I0
+.mmb; ADDSUB( w1, u1, x1) C M I
+ ld8 u0 = [up], 8 C M01
+ br .LL00 C B
+
+
+ ALIGN(32)
+.Lb01:
+ifdef(`DO_add',
+` shladd w2 = r11, LSH, r10 C M I
+ shr.u r8 = r11, 64-LSH C retval I0
+ (p15) br.dpnt .grt1 C B
+ ;;
+',`
+ shl x2 = r11, LSH C I0
+ (p15) br.dpnt .grt1 C B
+ ;;
+ ADDSUB( w2, r10, x2) C M I
+ shr.u r8 = r11, 64-LSH C retval I0
+ ;;
+')
+ CMP( p6, w2, r10, x2) C M I
+ br .Lcj1
+
+.grt1: ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ ;;
+ ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ mov.i ar.lc = n C FIXME swap with next I0
+ifdef(`DO_add',
+`',`
+ ADDSUB( w2, r10, x2)
+')
+ ;;
+.mmi; ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ shrp x3 = v3, r11, 64-LSH C I0
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ shrp x0 = v0, v3, 64-LSH C I0
+.mmb; CMP( p6, w2, r10, x2) C M I
+ ADDSUB( w3, u3, x3) C M I
+ br.cloop.dptk .grt5 C B
+ ;;
+.mmi; CMP( p7, w3, u3, x3) C M I
+ ADDSUB( w0, u0, x0) C M I
+ shrp x1 = v1, v0, 64-LSH C I0
+.mmb; nop 0
+ nop 0
+ br .Lcj5 C B
+.grt5:
+.mmi; add r10 = PFDIST, up
+ add r11 = PFDIST, vp
+ shrp x0 = v0, v3, 64-LSH C I0
+.mmb; ld8 v3 = [vp], 8 C M01
+ CMP( p8, w3, u3, x3) C M I
+ br .LL01 C B
+
+ ALIGN(32)
+.Lb10: ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ shl x1 = r11, LSH C I0
+.mmb; nop 0
+ nop 0
+ (p15) br.dpnt .grt2 C B
+ ;;
+.mmi; ADDSUB( w1, r10, x1) C M I
+ nop 0
+ shrp x2 = v2, r11, 64-LSH C I0
+ ;;
+.mmi; CMP( p9, w1, r10, x1) C M I
+ ADDSUB( w2, u2, x2) C M I
+ shr.u r8 = v2, 64-LSH C retval I0
+ ;;
+.mmb; CMP( p6, w2, u2, x2) C M I
+ nop 0
+ br .Lcj2 C B
+
+.grt2: ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ ;;
+.mmi; ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ mov.i ar.lc = n C I0
+.mmi; ADDSUB( w1, r10, x1) C M I
+ nop 0
+ nop 0
+ ;;
+.mii; ld8 v1 = [vp], 8 C M01
+ shrp x2 = v2, r11, 64-LSH C I0
+ CMP( p8, w1, r10, x1) C M I
+ ;;
+.mmi; add r10 = PFDIST, up
+ ld8 u1 = [up], 8 C M01
+ shrp x3 = v3, v2, 64-LSH C I0
+.mmi; add r11 = PFDIST, vp
+ ld8 v2 = [vp], 8 C M01
+ ADDSUB( w2, u2, x2) C M I
+ ;;
+.mmi; CMP( p6, w2, u2, x2) C M I
+ ld8 u2 = [up], 8 C M01
+ shrp x0 = v0, v3, 64-LSH C I0
+.mbb; ADDSUB( w3, u3, x3) C M I
+ br.cloop.dpnt L(top) C B
+ br L(end) C B
+
+.Lb11: ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ shl x0 = r11, LSH C I0
+ ;;
+.mmi; ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+.mmb; nop 0
+ nop 0
+ (p15) br.dpnt .grt3 C B
+ ;;
+.mii; nop 0
+ shrp x1 = v1, r11, 64-LSH C I0
+ ADDSUB( w0, r10, x0) C M I
+ ;;
+.mii; CMP( p8, w0, r10, x0) C M I
+ shrp x2 = v2, v1, 64-LSH C I0
+ ADDSUB( w1, u1, x1) C M I
+ ;;
+.mmb; CMP( p9, w1, u1, x1) C M I
+ ADDSUB( w2, u2, x2) C M I
+ br .Lcj3 C B
+.grt3:
+.mmi; ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ shrp x1 = v1, r11, 64-LSH C I0
+.mmi; ADDSUB( w0, r10, x0) C M I
+ nop 0
+ nop 0
+ ;;
+.mmi; ld8 v0 = [vp], 8 C M01
+ CMP( p6, w0, r10, x0) C M I
+ mov.i ar.lc = n C I0
+.mmi; ld8 u0 = [up], 8 C M01
+ ADDSUB( w1, u1, x1) C M I
+ nop 0
+ ;;
+.mmi; add r10 = PFDIST, up
+ add r11 = PFDIST, vp
+ shrp x2 = v2, v1, 64-LSH C I0
+.mmb; ld8 v1 = [vp], 8 C M01
+ CMP( p8, w1, u1, x1) C M I
+ br .LL11 C B
+
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+L(top): st8 [rp] = w1, 8 C M23
+ lfetch [r10], 32
+ (p8) cmpeqor p6, p0 = LIM, w2 C M I
+ (p8) add w2 = INCR, w2 C M I
+ ld8 v3 = [vp], 8 C M01
+ CMP( p8, w3, u3, x3) C M I
+ ;;
+.LL01: ld8 u3 = [up], 8 C M01
+ shrp x1 = v1, v0, 64-LSH C I0
+ (p6) cmpeqor p8, p0 = LIM, w3 C M I
+ (p6) add w3 = INCR, w3 C M I
+ ld8 v0 = [vp], 8 C M01
+ ADDSUB( w0, u0, x0) C M I
+ ;;
+ st8 [rp] = w2, 8 C M23
+ CMP( p6, w0, u0, x0) C M I
+ nop.b 0
+ ld8 u0 = [up], 8 C M01
+ lfetch [r11], 32
+ ADDSUB( w1, u1, x1) C M I
+ ;;
+.LL00: st8 [rp] = w3, 8 C M23
+ shrp x2 = v2, v1, 64-LSH C I0
+ (p8) cmpeqor p6, p0 = LIM, w0 C M I
+ (p8) add w0 = INCR, w0 C M I
+ ld8 v1 = [vp], 8 C M01
+ CMP( p8, w1, u1, x1) C M I
+ ;;
+.LL11: ld8 u1 = [up], 8 C M01
+ shrp x3 = v3, v2, 64-LSH C I0
+ (p6) cmpeqor p8, p0 = LIM, w1 C M I
+ (p6) add w1 = INCR, w1 C M I
+ ld8 v2 = [vp], 8 C M01
+ ADDSUB( w2, u2, x2) C M I
+ ;;
+.mmi; st8 [rp] = w0, 8 C M23
+ CMP( p6, w2, u2, x2) C M I
+ shrp x0 = v0, v3, 64-LSH C I0
+ ld8 u2 = [up], 8 C M01
+ ADDSUB( w3, u3, x3) C M I
+ br.cloop.dptk L(top) C B
+ ;;
+C *** MAIN LOOP END ***
+
+L(end):
+.mmi; st8 [rp] = w1, 8 C M23
+ (p8) cmpeqor p6, p0 = LIM, w2 C M I
+ shrp x1 = v1, v0, 64-LSH C I0
+.mmi;
+ (p8) add w2 = INCR, w2 C M I
+ CMP( p7, w3, u3, x3) C M I
+ ADDSUB( w0, u0, x0) C M I
+ ;;
+.Lcj5:
+.mmi; st8 [rp] = w2, 8 C M23
+ (p6) cmpeqor p7, p0 = LIM, w3 C M I
+ shrp x2 = v2, v1, 64-LSH C I0
+.mmi;
+ (p6) add w3 = INCR, w3 C M I
+ CMP( p8, w0, u0, x0) C M I
+ ADDSUB( w1, u1, x1) C M I
+ ;;
+.Lcj4:
+.mmi; st8 [rp] = w3, 8 C M23
+ (p7) cmpeqor p8, p0 = LIM, w0 C M I
+ mov.i ar.lc = r2 C I0
+.mmi;
+ (p7) add w0 = INCR, w0 C M I
+ CMP( p9, w1, u1, x1) C M I
+ ADDSUB( w2, u2, x2) C M I
+ ;;
+.Lcj3:
+.mmi; st8 [rp] = w0, 8 C M23
+ (p8) cmpeqor p9, p0 = LIM, w1 C M I
+ shr.u r8 = v2, 64-LSH C I0
+.mmi;
+ (p8) add w1 = INCR, w1 C M I
+ CMP( p6, w2, u2, x2) C M I
+ nop 0
+ ;;
+.Lcj2:
+.mmi; st8 [rp] = w1, 8 C M23
+ (p9) cmpeqor p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ ;;
+.Lcj1:
+.mmb; st8 [rp] = w2 C M23
+ifdef(`DO_rsb',`
+ (p6) add r8 = -1, r8 C M I
+',`
+ (p6) add r8 = 1, r8 C M I
+') br.ret.sptk.many b0 C B
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/bdiv_dbm1c.asm b/gmp/mpn/ia64/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..47e4553cda
--- /dev/null
+++ b/gmp/mpn/ia64/bdiv_dbm1c.asm
@@ -0,0 +1,516 @@
+dnl IA-64 mpn_bdiv_dbm1.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2009 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 4
+C Itanium 2: 2
+
+C TODO
+C * Optimize feed-in and wind-down code, both for speed and code size.
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`n', `r34')
+define(`bd', `r35')
+
+ASM_START()
+PROLOGUE(mpn_bdiv_dbm1c)
+ .prologue
+ .save ar.lc, r2
+ .body
+
+ifdef(`HAVE_ABI_32',
+` addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ zxt4 n = n C I
+ ;;
+')
+{.mmb
+ mov r15 = r36 C M I
+ ldf8 f9 = [up], 8 C M
+ nop.b 0 C B
+}
+.Lcommon:
+{.mii
+ adds r16 = -1, n C M I
+ mov r2 = ar.lc C I0
+ and r14 = 3, n C M I
+ ;;
+}
+{.mii
+ setf.sig f6 = bd C M2 M3
+ shr.u r31 = r16, 2 C I0
+ cmp.eq p10, p0 = 0, r14 C M I
+}
+{.mii
+ nop.m 0 C M
+ cmp.eq p11, p0 = 2, r14 C M I
+ cmp.eq p12, p0 = 3, r14 C M I
+ ;;
+}
+{.mii
+ cmp.ne p6, p7 = r0, r0 C M I
+ mov.i ar.lc = r31 C I0
+ cmp.ne p8, p9 = r0, r0 C M I
+}
+{.bbb
+ (p10) br.dptk .Lb00 C B
+ (p11) br.dptk .Lb10 C B
+ (p12) br.dptk .Lb11 C B
+ ;;
+}
+
+.Lb01: br.cloop.dptk .grt1
+ ;;
+ xma.l f38 = f9, f6, f0
+ xma.hu f39 = f9, f6, f0
+ ;;
+ getf.sig r26 = f38
+ getf.sig r27 = f39
+ br .Lcj1
+
+.grt1: ldf8 f10 = [r33], 8
+ ;;
+ ldf8 f11 = [r33], 8
+ ;;
+ ldf8 f12 = [r33], 8
+ ;;
+ xma.l f38 = f9, f6, f0
+ xma.hu f39 = f9, f6, f0
+ ;;
+ ldf8 f13 = [r33], 8
+ ;;
+ xma.l f32 = f10, f6, f0
+ xma.hu f33 = f10, f6, f0
+ br.cloop.dptk .grt5
+
+ ;;
+ getf.sig r26 = f38
+ xma.l f34 = f11, f6, f0
+ xma.hu f35 = f11, f6, f0
+ ;;
+ getf.sig r27 = f39
+ ;;
+ getf.sig r20 = f32
+ xma.l f36 = f12, f6, f0
+ xma.hu f37 = f12, f6, f0
+ ;;
+ getf.sig r21 = f33
+ ;;
+ getf.sig r22 = f34
+ xma.l f38 = f13, f6, f0
+ xma.hu f39 = f13, f6, f0
+ br .Lcj5
+
+.grt5: ldf8 f10 = [r33], 8
+ ;;
+ getf.sig r26 = f38
+ xma.l f34 = f11, f6, f0
+ xma.hu f35 = f11, f6, f0
+ ;;
+ getf.sig r27 = f39
+ ldf8 f11 = [r33], 8
+ ;;
+ getf.sig r20 = f32
+ xma.l f36 = f12, f6, f0
+ xma.hu f37 = f12, f6, f0
+ ;;
+ getf.sig r21 = f33
+ ldf8 f12 = [r33], 8
+ ;;
+ getf.sig r22 = f34
+ xma.l f38 = f13, f6, f0
+ xma.hu f39 = f13, f6, f0
+ br .LL01
+
+.Lb10: ldf8 f13 = [r33], 8
+ br.cloop.dptk .grt2
+ ;;
+
+ xma.l f36 = f9, f6, f0
+ xma.hu f37 = f9, f6, f0
+ ;;
+ xma.l f38 = f13, f6, f0
+ xma.hu f39 = f13, f6, f0
+ ;;
+ getf.sig r24 = f36
+ ;;
+ getf.sig r25 = f37
+ ;;
+ getf.sig r26 = f38
+ ;;
+ getf.sig r27 = f39
+ br .Lcj2
+
+.grt2: ldf8 f10 = [r33], 8
+ ;;
+ ldf8 f11 = [r33], 8
+ ;;
+ xma.l f36 = f9, f6, f0
+ xma.hu f37 = f9, f6, f0
+ ;;
+ ldf8 f12 = [r33], 8
+ ;;
+ xma.l f38 = f13, f6, f0
+ xma.hu f39 = f13, f6, f0
+ ;;
+ ldf8 f13 = [r33], 8
+ ;;
+ getf.sig r24 = f36
+ xma.l f32 = f10, f6, f0
+ xma.hu f33 = f10, f6, f0
+ br.cloop.dptk .grt6
+
+ getf.sig r25 = f37
+ ;;
+ getf.sig r26 = f38
+ xma.l f34 = f11, f6, f0
+ xma.hu f35 = f11, f6, f0
+ ;;
+ getf.sig r27 = f39
+ ;;
+ getf.sig r20 = f32
+ xma.l f36 = f12, f6, f0
+ xma.hu f37 = f12, f6, f0
+ br .Lcj6
+
+.grt6: getf.sig r25 = f37
+ ldf8 f10 = [r33], 8
+ ;;
+ getf.sig r26 = f38
+ xma.l f34 = f11, f6, f0
+ xma.hu f35 = f11, f6, f0
+ ;;
+ getf.sig r27 = f39
+ ldf8 f11 = [r33], 8
+ ;;
+ getf.sig r20 = f32
+ xma.l f36 = f12, f6, f0
+ xma.hu f37 = f12, f6, f0
+ br .LL10
+
+
+.Lb11: ldf8 f12 = [r33], 8
+ ;;
+ ldf8 f13 = [r33], 8
+ br.cloop.dptk .grt3
+ ;;
+
+ xma.l f34 = f9, f6, f0
+ xma.hu f35 = f9, f6, f0
+ ;;
+ xma.l f36 = f12, f6, f0
+ xma.hu f37 = f12, f6, f0
+ ;;
+ getf.sig r22 = f34
+ xma.l f38 = f13, f6, f0
+ xma.hu f39 = f13, f6, f0
+ ;;
+ getf.sig r23 = f35
+ ;;
+ getf.sig r24 = f36
+ ;;
+ getf.sig r25 = f37
+ ;;
+ getf.sig r26 = f38
+ br .Lcj3
+
+.grt3: ldf8 f10 = [r33], 8
+ ;;
+ xma.l f34 = f9, f6, f0
+ xma.hu f35 = f9, f6, f0
+ ;;
+ ldf8 f11 = [r33], 8
+ ;;
+ xma.l f36 = f12, f6, f0
+ xma.hu f37 = f12, f6, f0
+ ;;
+ ldf8 f12 = [r33], 8
+ ;;
+ getf.sig r22 = f34
+ xma.l f38 = f13, f6, f0
+ xma.hu f39 = f13, f6, f0
+ ;;
+ getf.sig r23 = f35
+ ldf8 f13 = [r33], 8
+ ;;
+ getf.sig r24 = f36
+ xma.l f32 = f10, f6, f0
+ xma.hu f33 = f10, f6, f0
+ br.cloop.dptk .grt7
+
+ getf.sig r25 = f37
+ ;;
+ getf.sig r26 = f38
+ xma.l f34 = f11, f6, f0
+ xma.hu f35 = f11, f6, f0
+ br .Lcj7
+
+.grt7: getf.sig r25 = f37
+ ldf8 f10 = [r33], 8
+ ;;
+ getf.sig r26 = f38
+ xma.l f34 = f11, f6, f0
+ xma.hu f35 = f11, f6, f0
+ br .LL11
+
+
+.Lb00: ldf8 f11 = [r33], 8
+ ;;
+ ldf8 f12 = [r33], 8
+ ;;
+ ldf8 f13 = [r33], 8
+ br.cloop.dptk .grt4
+ ;;
+
+ xma.l f32 = f9, f6, f0
+ xma.hu f33 = f9, f6, f0
+ ;;
+ xma.l f34 = f11, f6, f0
+ xma.hu f35 = f11, f6, f0
+ ;;
+ getf.sig r20 = f32
+ xma.l f36 = f12, f6, f0
+ xma.hu f37 = f12, f6, f0
+ ;;
+ getf.sig r21 = f33
+ ;;
+ getf.sig r22 = f34
+ xma.l f38 = f13, f6, f0
+ xma.hu f39 = f13, f6, f0
+ ;;
+ getf.sig r23 = f35
+ ;;
+ getf.sig r24 = f36
+ br .Lcj4
+
+.grt4: xma.l f32 = f9, f6, f0
+ xma.hu f33 = f9, f6, f0
+ ;;
+ ldf8 f10 = [r33], 8
+ ;;
+ xma.l f34 = f11, f6, f0
+ xma.hu f35 = f11, f6, f0
+ ;;
+ ldf8 f11 = [r33], 8
+ ;;
+ getf.sig r20 = f32
+ xma.l f36 = f12, f6, f0
+ xma.hu f37 = f12, f6, f0
+ ;;
+ getf.sig r21 = f33
+ ldf8 f12 = [r33], 8
+ ;;
+ getf.sig r22 = f34
+ xma.l f38 = f13, f6, f0
+ xma.hu f39 = f13, f6, f0
+ ;;
+ getf.sig r23 = f35
+ ldf8 f13 = [r33], 8
+ ;;
+ getf.sig r24 = f36
+ xma.l f32 = f10, f6, f0
+ xma.hu f33 = f10, f6, f0
+ br.cloop.dptk .LL00
+ br .Lcj8
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+.Ltop:
+ .pred.rel "mutex",p6,p7
+C .mfi
+ getf.sig r24 = f36
+ xma.l f32 = f10, f6, f0
+ (p6) sub r15 = r19, r27, 1
+C .mfi
+ st8 [r32] = r19, 8
+ xma.hu f33 = f10, f6, f0
+ (p7) sub r15 = r19, r27
+ ;;
+.LL00:
+C .mfi
+ getf.sig r25 = f37
+ nop.f 0
+ cmp.ltu p6, p7 = r15, r20
+C .mib
+ ldf8 f10 = [r33], 8
+ sub r16 = r15, r20
+ nop.b 0
+ ;;
+
+C .mfi
+ getf.sig r26 = f38
+ xma.l f34 = f11, f6, f0
+ (p6) sub r15 = r16, r21, 1
+C .mfi
+ st8 [r32] = r16, 8
+ xma.hu f35 = f11, f6, f0
+ (p7) sub r15 = r16, r21
+ ;;
+.LL11:
+C .mfi
+ getf.sig r27 = f39
+ nop.f 0
+ cmp.ltu p6, p7 = r15, r22
+C .mib
+ ldf8 f11 = [r33], 8
+ sub r17 = r15, r22
+ nop.b 0
+ ;;
+
+C .mfi
+ getf.sig r20 = f32
+ xma.l f36 = f12, f6, f0
+ (p6) sub r15 = r17, r23, 1
+C .mfi
+ st8 [r32] = r17, 8
+ xma.hu f37 = f12, f6, f0
+ (p7) sub r15 = r17, r23
+ ;;
+.LL10:
+C .mfi
+ getf.sig r21 = f33
+ nop.f 0
+ cmp.ltu p6, p7 = r15, r24
+C .mib
+ ldf8 f12 = [r33], 8
+ sub r18 = r15, r24
+ nop.b 0
+ ;;
+
+C .mfi
+ getf.sig r22 = f34
+ xma.l f38 = f13, f6, f0
+ (p6) sub r15 = r18, r25, 1
+C .mfi
+ st8 [r32] = r18, 8
+ xma.hu f39 = f13, f6, f0
+ (p7) sub r15 = r18, r25
+ ;;
+.LL01:
+C .mfi
+ getf.sig r23 = f35
+ nop.f 0
+ cmp.ltu p6, p7 = r15, r26
+C .mib
+ ldf8 f13 = [r33], 8
+ sub r19 = r15, r26
+ br.cloop.sptk.few .Ltop
+C *** MAIN LOOP END ***
+ ;;
+
+ getf.sig r24 = f36
+ xma.l f32 = f10, f6, f0
+ (p6) sub r15 = r19, r27, 1
+ st8 [r32] = r19, 8
+ xma.hu f33 = f10, f6, f0
+ (p7) sub r15 = r19, r27
+ ;;
+.Lcj8: getf.sig r25 = f37
+ cmp.ltu p6, p7 = r15, r20
+ sub r16 = r15, r20
+ ;;
+ getf.sig r26 = f38
+ xma.l f34 = f11, f6, f0
+ (p6) sub r15 = r16, r21, 1
+ st8 [r32] = r16, 8
+ xma.hu f35 = f11, f6, f0
+ (p7) sub r15 = r16, r21
+ ;;
+.Lcj7: getf.sig r27 = f39
+ cmp.ltu p6, p7 = r15, r22
+ sub r17 = r15, r22
+ ;;
+ getf.sig r20 = f32
+ xma.l f36 = f12, f6, f0
+ (p6) sub r15 = r17, r23, 1
+ st8 [r32] = r17, 8
+ xma.hu f37 = f12, f6, f0
+ (p7) sub r15 = r17, r23
+ ;;
+.Lcj6: getf.sig r21 = f33
+ cmp.ltu p6, p7 = r15, r24
+ sub r18 = r15, r24
+ ;;
+ getf.sig r22 = f34
+ xma.l f38 = f13, f6, f0
+ (p6) sub r15 = r18, r25, 1
+ st8 [r32] = r18, 8
+ xma.hu f39 = f13, f6, f0
+ (p7) sub r15 = r18, r25
+ ;;
+.Lcj5: getf.sig r23 = f35
+ cmp.ltu p6, p7 = r15, r26
+ sub r19 = r15, r26
+ ;;
+ getf.sig r24 = f36
+ (p6) sub r15 = r19, r27, 1
+ st8 [r32] = r19, 8
+ (p7) sub r15 = r19, r27
+ ;;
+.Lcj4: getf.sig r25 = f37
+ cmp.ltu p6, p7 = r15, r20
+ sub r16 = r15, r20
+ ;;
+ getf.sig r26 = f38
+ (p6) sub r15 = r16, r21, 1
+ st8 [r32] = r16, 8
+ (p7) sub r15 = r16, r21
+ ;;
+.Lcj3: getf.sig r27 = f39
+ cmp.ltu p6, p7 = r15, r22
+ sub r17 = r15, r22
+ ;;
+ (p6) sub r15 = r17, r23, 1
+ st8 [r32] = r17, 8
+ (p7) sub r15 = r17, r23
+ ;;
+.Lcj2: cmp.ltu p6, p7 = r15, r24
+ sub r18 = r15, r24
+ ;;
+ (p6) sub r15 = r18, r25, 1
+ st8 [r32] = r18, 8
+ (p7) sub r15 = r18, r25
+ ;;
+.Lcj1: cmp.ltu p6, p7 = r15, r26
+ sub r19 = r15, r26
+ ;;
+ (p6) sub r8 = r19, r27, 1
+ st8 [r32] = r19
+ (p7) sub r8 = r19, r27
+ mov ar.lc = r2
+ br.ret.sptk.many b0
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/cnd_aors_n.asm b/gmp/mpn/ia64/cnd_aors_n.asm
new file mode 100644
index 0000000000..dc4a937403
--- /dev/null
+++ b/gmp/mpn/ia64/cnd_aors_n.asm
@@ -0,0 +1,259 @@
+dnl IA-64 mpn_cnd_add_n/mpn_cnd_sub_n.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: ?
+C Itanium 2: 1.5
+
+C INPUT PARAMETERS
+define(`cnd', `r32')
+define(`rp', `r33')
+define(`up', `r34')
+define(`vp', `r35')
+define(`n', `r36')
+
+ifdef(`OPERATION_cnd_add_n',`
+ define(ADDSUB, add)
+ define(CND, ltu)
+ define(INCR, 1)
+ define(LIM, -1)
+ define(func, mpn_cnd_add_n)
+')
+ifdef(`OPERATION_cnd_sub_n',`
+ define(ADDSUB, sub)
+ define(CND, gtu)
+ define(INCR, -1)
+ define(LIM, 0)
+ define(func, mpn_cnd_sub_n)
+')
+
+define(cmpeqor, `cmp.eq.or')
+define(PFDIST, 160)
+
+C Some useful aliases for registers we use
+define(`u0',`r14') define(`u1',`r15') define(`u2',`r16') define(`u3',`r17')
+define(`x0',`r20') define(`x1',`r21') define(`x2',`r22') define(`x3',`r23')
+define(`v0',`r24') define(`v1',`r25') define(`v2',`r26') define(`v3',`r27')
+define(`w0',`r28') define(`w1',`r29') define(`w2',`r30') define(`w3',`r31')
+define(`up1',`up') define(`up2',`r8') define(`upadv',`r1')
+define(`vp1',`vp') define(`vp2',`r9') define(`vpadv',`r11')
+define(`rp1',`rp') define(`rp2',`r10')
+
+MULFUNC_PROLOGUE(mpn_cnd_add_n mpn_cnd_sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',`
+ addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ nop.i 0
+ addp4 vp = 0, vp C M I
+ nop.m 0
+ zxt4 n = n C I
+ ;;
+')
+.mmi; and r3 = 3, n C M I
+ add n = -1, n C M I
+ mov r2 = ar.lc C I0
+.mmi; cmp.ne p6, p7 = 0, cnd C M I
+ add vp2 = 8, vp C M I
+ add up2 = 8, up C M I
+ ;;
+.mmi; add upadv = PFDIST, up C M I
+ add vpadv = PFDIST, vp C M I
+ shr.u n = n, 2 C I0
+ .pred.rel "mutex", p6, p7
+.mmi; add rp2 = 8, rp C M I
+ (p6) mov cnd = -1 C M I
+ (p7) mov cnd = 0 C M I
+ ;;
+ cmp.eq p9, p0 = 1, r3 C M I
+ cmp.eq p7, p0 = 2, r3 C M I
+ cmp.eq p8, p0 = 3, r3 C M I
+ (p9) br L(b1) C B
+ (p7) br L(b2) C B
+ (p8) br L(b3) C B
+ ;;
+L(b0):
+.mmi; ld8 v2 = [vp1], 16 C M01
+ ld8 v3 = [vp2], 16 C M01
+ mov ar.lc = n C I0
+ ;;
+ ld8 u2 = [up1], 16 C M01
+ ld8 u3 = [up2], 16 C M01
+ and x2 = v2, cnd C M I
+ and x3 = v3, cnd C M I
+ ;;
+ ADDSUB w2 = u2, x2 C M I
+ ADDSUB w3 = u3, x3 C M I
+ ;;
+ ld8 v0 = [vp1], 16 C M01
+ ld8 v1 = [vp2], 16 C M01
+ cmp.CND p8, p0 = w2, u2 C M I
+ cmp.CND p9, p0 = w3, u3 C M I
+ br L(lo0)
+
+L(b1): ld8 v1 = [vp1], 8 C M01
+ add vp2 = 8, vp2 C M I
+ add rp2 = 8, rp2 C M I
+ ;;
+ ld8 u1 = [up1], 8 C M01
+ add up2 = 8, up2 C M I
+ and x1 = v1, cnd C M I
+ ;;
+ ADDSUB w1 = u1, x1 C M I
+ cmp.ne p10, p0 = 0, n
+ add n = -1, n
+ ;;
+ cmp.CND p7, p0 = w1, u1 C M I
+ st8 [rp1] = w1, 8 C M23
+ (p10) br L(b0)
+ ;;
+ mov r8 = 0 C M I
+ br L(e1)
+
+L(b3): ld8 v3 = [vp1], 8 C M01
+ add vp2 = 8, vp2 C M I
+ add rp2 = 8, rp2 C M I
+ ;;
+ ld8 u3 = [up1], 8 C M01
+ add up2 = 8, up2 C M I
+ and x3 = v3, cnd C M I
+ ;;
+ ADDSUB w3 = u3, x3 C M I
+ ;;
+ cmp.CND p9, p0 = w3, u3 C M I
+ st8 [rp1] = w3, 8 C M23
+ C fall through
+
+L(b2):
+.mmi; ld8 v0 = [vp1], 16 C M01
+ ld8 v1 = [vp2], 16 C M01
+ mov ar.lc = n C I0
+ ;;
+ ld8 u0 = [up1], 16 C M01
+ ld8 u1 = [up2], 16 C M01
+ and x0 = v0, cnd C M I
+ and x1 = v1, cnd C M I
+ ;;
+ ADDSUB w0 = u0, x0 C M I
+ ADDSUB w1 = u1, x1 C M I
+ br.cloop.dptk L(gt2) C B
+ ;;
+ cmp.CND p6, p0 = w0, u0 C M I
+ br L(e2) C B
+L(gt2):
+ ld8 v2 = [vp1], 16 C M01
+ ld8 v3 = [vp2], 16 C M01
+ cmp.CND p6, p0 = w0, u0 C M I
+ cmp.CND p7, p0 = w1, u1 C M I
+ br L(lo2) C B
+
+
+C *** MAIN LOOP START ***
+C ALIGN(32)
+L(top):
+.mmi; ld8 v2 = [vp1], 16 C M01
+ ld8 v3 = [vp2], 16 C M01
+ cmp.CND p6, p0 = w0, u0 C M I
+.mmi; st8 [rp1] = w2, 16 C M23
+ st8 [rp2] = w3, 16 C M23
+ cmp.CND p7, p0 = w1, u1 C M I
+ ;;
+L(lo2):
+.mmi; ld8 u2 = [up1], 16 C M01
+ ld8 u3 = [up2], 16 C M01
+ (p9) cmpeqor p6, p0 = LIM, w0 C M I
+.mmi; and x2 = v2, cnd C M I
+ and x3 = v3, cnd C M I
+ (p9) add w0 = INCR, w0 C M I
+ ;;
+.mmi; ADDSUB w2 = u2, x2 C M I
+ (p6) cmpeqor p7, p0 = LIM, w1 C M I
+ (p6) add w1 = INCR, w1 C M I
+.mmi; ADDSUB w3 = u3, x3 C M I
+ lfetch [upadv], 32
+ nop 0
+ ;;
+.mmi; ld8 v0 = [vp1], 16 C M01
+ ld8 v1 = [vp2], 16 C M01
+ cmp.CND p8, p0 = w2, u2 C M I
+.mmi; st8 [rp1] = w0, 16 C M23
+ st8 [rp2] = w1, 16 C M23
+ cmp.CND p9, p0 = w3, u3 C M I
+ ;;
+L(lo0):
+.mmi; ld8 u0 = [up1], 16 C M01
+ ld8 u1 = [up2], 16 C M01
+ (p7) cmpeqor p8, p0 = LIM, w2 C M I
+.mmi; and x0 = v0, cnd C M I
+ and x1 = v1, cnd C M I
+ (p7) add w2 = INCR, w2 C M I
+ ;;
+.mmi; ADDSUB w0 = u0, x0 C M I
+ (p8) cmpeqor p9, p0 = LIM, w3 C M I
+ (p8) add w3 = INCR, w3 C M I
+.mmb; ADDSUB w1 = u1, x1 C M I
+ lfetch [vpadv], 32
+ br.cloop.dptk L(top) C B
+ ;;
+C *** MAIN LOOP END ***
+
+
+L(end):
+.mmi; st8 [rp1] = w2, 16 C M23
+ st8 [rp2] = w3, 16 C M23
+ cmp.CND p6, p0 = w0, u0 C M I
+ ;;
+L(e2):
+.mmi; cmp.CND p7, p0 = w1, u1 C M I
+ (p9) cmpeqor p6, p0 = LIM, w0 C M I
+ (p9) add w0 = INCR, w0 C M I
+ ;;
+.mmi; mov r8 = 0 C M I
+ (p6) cmpeqor p7, p0 = LIM, w1 C M I
+ (p6) add w1 = INCR, w1 C M I
+ ;;
+.mmi; st8 [rp1] = w0, 16 C M23
+ st8 [rp2] = w1, 16 C M23
+ mov ar.lc = r2 C I0
+L(e1):
+.mmb; nop 0
+ (p7) mov r8 = 1 C M I
+ br.ret.sptk.many b0 C B
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/copyd.asm b/gmp/mpn/ia64/copyd.asm
new file mode 100644
index 0000000000..b94a1af362
--- /dev/null
+++ b/gmp/mpn/ia64/copyd.asm
@@ -0,0 +1,186 @@
+dnl IA-64 mpn_copyd -- copy limb vector, decrementing.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 1
+C Itanium 2: 0.5
+
+C INPUT PARAMETERS
+C rp = r32
+C sp = r33
+C n = r34
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',
+` addp4 r32 = 0, r32
+ addp4 r33 = 0, r33
+ sxt4 r34 = r34
+ ;;
+')
+{.mmi
+ shladd r32 = r34, 3, r32
+ shladd r33 = r34, 3, r33
+ mov.i r2 = ar.lc
+}
+{.mmi
+ and r14 = 3, r34
+ cmp.ge p14, p15 = 3, r34
+ add r34 = -4, r34
+ ;;
+}
+{.mmi
+ cmp.eq p8, p0 = 1, r14
+ cmp.eq p10, p0 = 2, r14
+ cmp.eq p12, p0 = 3, r14
+}
+{.bbb
+ (p8) br.dptk .Lb01
+ (p10) br.dptk .Lb10
+ (p12) br.dptk .Lb11
+}
+
+.Lb00: C n = 0, 4, 8, 12, ...
+ add r32 = -8, r32
+ add r33 = -8, r33
+ (p14) br.dptk .Ls00
+ ;;
+ add r21 = -8, r33
+ ld8 r16 = [r33], -16
+ shr r15 = r34, 2
+ ;;
+ ld8 r17 = [r21], -16
+ mov.i ar.lc = r15
+ ld8 r18 = [r33], -16
+ add r20 = -8, r32
+ ;;
+ ld8 r19 = [r21], -16
+ br.cloop.dptk .Loop
+ ;;
+ br.sptk .Lend
+ ;;
+
+.Lb01: C n = 1, 5, 9, 13, ...
+ add r21 = -8, r33
+ add r20 = -8, r32
+ add r33 = -16, r33
+ add r32 = -16, r32
+ ;;
+ ld8 r19 = [r21], -16
+ shr r15 = r34, 2
+ (p14) br.dptk .Ls01
+ ;;
+ ld8 r16 = [r33], -16
+ mov.i ar.lc = r15
+ ;;
+ ld8 r17 = [r21], -16
+ ld8 r18 = [r33], -16
+ br.sptk .Li01
+ ;;
+
+.Lb10: C n = 2,6, 10, 14, ...
+ add r21 = -16, r33
+ shr r15 = r34, 2
+ add r20 = -16, r32
+ add r32 = -8, r32
+ add r33 = -8, r33
+ ;;
+ ld8 r18 = [r33], -16
+ ld8 r19 = [r21], -16
+ mov.i ar.lc = r15
+ (p14) br.dptk .Ls10
+ ;;
+ ld8 r16 = [r33], -16
+ ld8 r17 = [r21], -16
+ br.sptk .Li10
+ ;;
+
+.Lb11: C n = 3, 7, 11, 15, ...
+ add r21 = -8, r33
+ add r20 = -8, r32
+ add r33 = -16, r33
+ add r32 = -16, r32
+ ;;
+ ld8 r17 = [r21], -16
+ shr r15 = r34, 2
+ ;;
+ ld8 r18 = [r33], -16
+ mov.i ar.lc = r15
+ ld8 r19 = [r21], -16
+ (p14) br.dptk .Ls11
+ ;;
+ ld8 r16 = [r33], -16
+ br.sptk .Li11
+ ;;
+
+ ALIGN(32)
+.Loop:
+.Li00:
+{.mmb
+ st8 [r32] = r16, -16
+ ld8 r16 = [r33], -16
+ nop.b 0
+}
+.Li11:
+{.mmb
+ st8 [r20] = r17, -16
+ ld8 r17 = [r21], -16
+ nop.b 0
+ ;;
+}
+.Li10:
+{.mmb
+ st8 [r32] = r18, -16
+ ld8 r18 = [r33], -16
+ nop.b 0
+}
+.Li01:
+{.mmb
+ st8 [r20] = r19, -16
+ ld8 r19 = [r21], -16
+ br.cloop.dptk .Loop
+ ;;
+}
+.Lend: st8 [r32] = r16, -16
+.Ls11: st8 [r20] = r17, -16
+ ;;
+.Ls10: st8 [r32] = r18, -16
+.Ls01: st8 [r20] = r19, -16
+.Ls00: mov.i ar.lc = r2
+ br.ret.sptk.many b0
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/copyi.asm b/gmp/mpn/ia64/copyi.asm
new file mode 100644
index 0000000000..49ed192021
--- /dev/null
+++ b/gmp/mpn/ia64/copyi.asm
@@ -0,0 +1,182 @@
+dnl IA-64 mpn_copyi -- copy limb vector, incrementing.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 1
+C Itanium 2: 0.5
+
+C INPUT PARAMETERS
+C rp = r32
+C sp = r33
+C n = r34
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',
+` addp4 r32 = 0, r32
+ addp4 r33 = 0, r33
+ sxt4 r34 = r34
+ ;;
+')
+{.mmi
+ nop 0
+ nop 0
+ mov.i r2 = ar.lc
+}
+{.mmi
+ and r14 = 3, r34
+ cmp.ge p14, p15 = 3, r34
+ add r34 = -4, r34
+ ;;
+}
+{.mmi
+ cmp.eq p8, p0 = 1, r14
+ cmp.eq p10, p0 = 2, r14
+ cmp.eq p12, p0 = 3, r14
+}
+{.bbb
+ (p8) br.dptk .Lb01
+ (p10) br.dptk .Lb10
+ (p12) br.dptk .Lb11
+}
+
+.Lb00: C n = 0, 4, 8, 12, ...
+ (p14) br.dptk .Ls00
+ ;;
+ add r21 = 8, r33
+ ld8 r16 = [r33], 16
+ shr r15 = r34, 2
+ ;;
+ ld8 r17 = [r21], 16
+ mov.i ar.lc = r15
+ ld8 r18 = [r33], 16
+ add r20 = 8, r32
+ ;;
+ ld8 r19 = [r21], 16
+ br.cloop.dptk .Loop
+ ;;
+ br.sptk .Lend
+ ;;
+
+.Lb01: C n = 1, 5, 9, 13, ...
+ add r21 = 0, r33
+ add r20 = 0, r32
+ add r33 = 8, r33
+ add r32 = 8, r32
+ ;;
+ ld8 r19 = [r21], 16
+ shr r15 = r34, 2
+ (p14) br.dptk .Ls01
+ ;;
+ ld8 r16 = [r33], 16
+ mov.i ar.lc = r15
+ ;;
+ ld8 r17 = [r21], 16
+ ld8 r18 = [r33], 16
+ br.sptk .Li01
+ ;;
+
+.Lb10: C n = 2,6, 10, 14, ...
+ add r21 = 8, r33
+ add r20 = 8, r32
+ ld8 r18 = [r33], 16
+ shr r15 = r34, 2
+ ;;
+ ld8 r19 = [r21], 16
+ mov.i ar.lc = r15
+ (p14) br.dptk .Ls10
+ ;;
+ ld8 r16 = [r33], 16
+ ld8 r17 = [r21], 16
+ br.sptk .Li10
+ ;;
+
+.Lb11: C n = 3, 7, 11, 15, ...
+ add r21 = 0, r33
+ add r20 = 0, r32
+ add r33 = 8, r33
+ add r32 = 8, r32
+ ;;
+ ld8 r17 = [r21], 16
+ shr r15 = r34, 2
+ ;;
+ ld8 r18 = [r33], 16
+ mov.i ar.lc = r15
+ ld8 r19 = [r21], 16
+ (p14) br.dptk .Ls11
+ ;;
+ ld8 r16 = [r33], 16
+ br.sptk .Li11
+ ;;
+
+ ALIGN(32)
+.Loop:
+.Li00:
+{.mmb
+ st8 [r32] = r16, 16
+ ld8 r16 = [r33], 16
+ nop.b 0
+}
+.Li11:
+{.mmb
+ st8 [r20] = r17, 16
+ ld8 r17 = [r21], 16
+ nop.b 0
+ ;;
+}
+.Li10:
+{.mmb
+ st8 [r32] = r18, 16
+ ld8 r18 = [r33], 16
+ nop.b 0
+}
+.Li01:
+{.mmb
+ st8 [r20] = r19, 16
+ ld8 r19 = [r21], 16
+ br.cloop.dptk .Loop
+ ;;
+}
+.Lend: st8 [r32] = r16, 16
+.Ls11: st8 [r20] = r17, 16
+ ;;
+.Ls10: st8 [r32] = r18, 16
+.Ls01: st8 [r20] = r19, 16
+.Ls00: mov.i ar.lc = r2
+ br.ret.sptk.many b0
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/dive_1.asm b/gmp/mpn/ia64/dive_1.asm
new file mode 100644
index 0000000000..5e4a273530
--- /dev/null
+++ b/gmp/mpn/ia64/dive_1.asm
@@ -0,0 +1,236 @@
+dnl IA-64 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Kevin Ryde.
+
+dnl Copyright 2003-2005, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 16
+C Itanium 2: 8
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`n', `r34')
+define(`divisor', `r35')
+
+define(`lshift', `r24')
+define(`rshift', `r25')
+
+C This code is a bit messy, and not as similar to mode1o.asm as desired.
+
+C The critical path during initialization is for computing the inverse of the
+C divisor. Since odd divisors are probably common, we conditionally execute
+C the initial count_trailing_zeros code and the downshift.
+
+C Possible improvement: Merge more of the feed-in code into the inverse
+C computation.
+
+ASM_START()
+ .text
+ .align 32
+.Ltab:
+data1 0,0x01, 0,0xAB, 0,0xCD, 0,0xB7, 0,0x39, 0,0xA3, 0,0xC5, 0,0xEF
+data1 0,0xF1, 0,0x1B, 0,0x3D, 0,0xA7, 0,0x29, 0,0x13, 0,0x35, 0,0xDF
+data1 0,0xE1, 0,0x8B, 0,0xAD, 0,0x97, 0,0x19, 0,0x83, 0,0xA5, 0,0xCF
+data1 0,0xD1, 0,0xFB, 0,0x1D, 0,0x87, 0,0x09, 0,0xF3, 0,0x15, 0,0xBF
+data1 0,0xC1, 0,0x6B, 0,0x8D, 0,0x77, 0,0xF9, 0,0x63, 0,0x85, 0,0xAF
+data1 0,0xB1, 0,0xDB, 0,0xFD, 0,0x67, 0,0xE9, 0,0xD3, 0,0xF5, 0,0x9F
+data1 0,0xA1, 0,0x4B, 0,0x6D, 0,0x57, 0,0xD9, 0,0x43, 0,0x65, 0,0x8F
+data1 0,0x91, 0,0xBB, 0,0xDD, 0,0x47, 0,0xC9, 0,0xB3, 0,0xD5, 0,0x7F
+data1 0,0x81, 0,0x2B, 0,0x4D, 0,0x37, 0,0xB9, 0,0x23, 0,0x45, 0,0x6F
+data1 0,0x71, 0,0x9B, 0,0xBD, 0,0x27, 0,0xA9, 0,0x93, 0,0xB5, 0,0x5F
+data1 0,0x61, 0,0x0B, 0,0x2D, 0,0x17, 0,0x99, 0,0x03, 0,0x25, 0,0x4F
+data1 0,0x51, 0,0x7B, 0,0x9D, 0,0x07, 0,0x89, 0,0x73, 0,0x95, 0,0x3F
+data1 0,0x41, 0,0xEB, 0,0x0D, 0,0xF7, 0,0x79, 0,0xE3, 0,0x05, 0,0x2F
+data1 0,0x31, 0,0x5B, 0,0x7D, 0,0xE7, 0,0x69, 0,0x53, 0,0x75, 0,0x1F
+data1 0,0x21, 0,0xCB, 0,0xED, 0,0xD7, 0,0x59, 0,0xC3, 0,0xE5, 0,0x0F
+data1 0,0x11, 0,0x3B, 0,0x5D, 0,0xC7, 0,0x49, 0,0x33, 0,0x55, 0,0xFF
+
+
+PROLOGUE(mpn_divexact_1)
+ .prologue
+ .save ar.lc, r2
+ .body
+
+ {.mmi; add r8 = -1, divisor C M0
+ nop 0 C M1
+ tbit.z p8, p9 = divisor, 0 C I0
+}
+ifdef(`HAVE_ABI_32',
+` addp4 rp = 0, rp C M2 rp extend
+ addp4 up = 0, up C M3 up extend
+ sxt4 n = n') C I1 size extend
+ ;;
+.Lhere:
+ {.mmi; ld8 r20 = [up], 8 C M0 up[0]
+ (p8) andcm r8 = r8, divisor C M1
+ mov r15 = ip C I0 .Lhere
+ ;;
+}{.mii
+ .pred.rel "mutex", p8, p9
+ (p9) mov rshift = 0 C M0
+ (p8) popcnt rshift = r8 C I0 r8 = cnt_lo_zeros(divisor)
+ cmp.eq p6, p10 = 1, n C I1
+ ;;
+}{.mii; add r9 = .Ltab-.Lhere, r15 C M0
+ (p8) shr.u divisor = divisor, rshift C I0
+ nop 0 C I1
+ ;;
+}{.mmi; add n = -4, n C M0 size-1
+ (p10) ld8 r21 = [up], 8 C M1 up[1]
+ mov r14 = 2 C M1 2
+}{.mfi; setf.sig f6 = divisor C M2 divisor
+ mov f9 = f0 C M3 carry FIXME
+ zxt1 r3 = divisor C I1 divisor low byte
+ ;;
+}{.mmi; add r3 = r9, r3 C M0 table offset ip and index
+ sub r16 = 0, divisor C M1 -divisor
+ mov r2 = ar.lc C I0
+}{.mmi; sub lshift = 64, rshift C M2
+ setf.sig f13 = r14 C M3 2 in significand
+ mov r17 = -1 C I1 -1
+ ;;
+}{.mmi; ld1 r3 = [r3] C M0 inverse, 8 bits
+ nop 0 C M1
+ mov ar.lc = n C I0 size-1 loop count
+}{.mmi; setf.sig f12 = r16 C M2 -divisor
+ setf.sig f8 = r17 C M3 -1
+ cmp.eq p7, p0 = -2, n C I1
+ ;;
+}{.mmi; setf.sig f7 = r3 C M2 inverse, 8 bits
+ cmp.eq p8, p0 = -1, n C M0
+ shr.u r23 = r20, rshift C I0
+ ;;
+}
+
+ C f6 divisor
+ C f7 inverse, being calculated
+ C f8 -1, will be -inverse
+ C f9 carry
+ C f12 -divisor
+ C f13 2
+ C f14 scratch
+
+ xmpy.l f14 = f13, f7 C Newton 2*i
+ xmpy.l f7 = f7, f7 C Newton i*i
+ ;;
+ xma.l f7 = f7, f12, f14 C Newton i*i*-d + 2*i, 16 bits
+ ;;
+ setf.sig f10 = r23 C speculative, used iff n = 1
+ xmpy.l f14 = f13, f7 C Newton 2*i
+ shl r22 = r21, lshift C speculative, used iff n > 1
+ xmpy.l f7 = f7, f7 C Newton i*i
+ ;;
+ or r31 = r22, r23 C speculative, used iff n > 1
+ xma.l f7 = f7, f12, f14 C Newton i*i*-d + 2*i, 32 bits
+ shr.u r23 = r21, rshift C speculative, used iff n > 1
+ ;;
+ setf.sig f11 = r31 C speculative, used iff n > 1
+ xmpy.l f14 = f13, f7 C Newton 2*i
+ xmpy.l f7 = f7, f7 C Newton i*i
+ ;;
+ xma.l f7 = f7, f12, f14 C Newton i*i*-d + 2*i, 64 bits
+
+ (p7) br.cond.dptk .Ln2
+ (p10) br.cond.dptk .grt3
+ ;;
+
+.Ln1: xmpy.l f12 = f10, f7 C q = ulimb * inverse
+ br .Lx1
+
+.Ln2:
+ xmpy.l f8 = f7, f8 C -inverse = inverse * -1
+ xmpy.l f12 = f11, f7 C q = ulimb * inverse
+ setf.sig f11 = r23
+ br .Lx2
+
+.grt3:
+ ld8 r21 = [up], 8 C up[2]
+ xmpy.l f8 = f7, f8 C -inverse = inverse * -1
+ ;;
+ shl r22 = r21, lshift
+ ;;
+ xmpy.l f12 = f11, f7 C q = ulimb * inverse
+ ;;
+ or r31 = r22, r23
+ shr.u r23 = r21, rshift
+ ;;
+ setf.sig f11 = r31
+ (p8) br.cond.dptk .Lx3 C branch for n = 3
+ ;;
+ ld8 r21 = [up], 8
+ br .Lent
+
+.Ltop: ld8 r21 = [up], 8
+ xma.l f12 = f9, f8, f10 C q = c * -inverse + si
+ nop.b 0
+ ;;
+.Lent: add r16 = 160, up
+ shl r22 = r21, lshift
+ nop.b 0
+ ;;
+ stf8 [rp] = f12, 8
+ xma.hu f9 = f12, f6, f9 C c = high(q * divisor + c)
+ nop.b 0
+ nop.m 0
+ xmpy.l f10 = f11, f7 C si = ulimb * inverse
+ nop.b 0
+ ;;
+ or r31 = r22, r23
+ shr.u r23 = r21, rshift
+ nop.b 0
+ ;;
+ lfetch [r16]
+ setf.sig f11 = r31
+ br.cloop.sptk.few.clr .Ltop
+
+
+ xma.l f12 = f9, f8, f10 C q = c * -inverse + si
+ ;;
+.Lx3: stf8 [rp] = f12, 8
+ xma.hu f9 = f12, f6, f9 C c = high(q * divisor + c)
+ xmpy.l f10 = f11, f7 C si = ulimb * inverse
+ ;;
+ setf.sig f11 = r23
+ ;;
+ xma.l f12 = f9, f8, f10 C q = c * -inverse + si
+ ;;
+.Lx2: stf8 [rp] = f12, 8
+ xma.hu f9 = f12, f6, f9 C c = high(q * divisor + c)
+ xmpy.l f10 = f11, f7 C si = ulimb * inverse
+ ;;
+ xma.l f12 = f9, f8, f10 C q = c * -inverse + si
+ ;;
+.Lx1: stf8 [rp] = f12, 8
+ mov ar.lc = r2 C I0
+ br.ret.sptk.many b0
+EPILOGUE()
diff --git a/gmp/mpn/ia64/divrem_1.asm b/gmp/mpn/ia64/divrem_1.asm
new file mode 100644
index 0000000000..e8878209db
--- /dev/null
+++ b/gmp/mpn/ia64/divrem_1.asm
@@ -0,0 +1,477 @@
+dnl IA-64 mpn_divrem_1 and mpn_preinv_divrem_1 -- Divide an mpn number by an
+dnl unnormalized limb.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2002, 2004, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C Itanium: 40-42
+C Itanium 2: 29-30
+
+C This was generated by gcc, then the loops were optimized. The preinv entry
+C point was shoehorned into the file. Lots of things outside the loops could
+C be streamlined. It would probably be a good idea to merge the loops for
+C normalized and unnormalized divisor, since the shifting stuff is done for
+C free in parallel with other operations. It would even be possible to merge
+C all loops, if the ld8 were made conditional.
+
+C TODO
+C * Consider delaying inversion for normalized mpn_divrem_1 entry till after
+C computing leading limb.
+C * Inline and interleave limb inversion code with loop setup code.
+
+ASM_START()
+
+C HP's assembler requires these declarations for importing mpn_invert_limb
+ .global mpn_invert_limb
+ .type mpn_invert_limb,@function
+
+C INPUT PARAMETERS
+C rp = r32
+C qxn = r33
+C up = r34
+C n = r35
+C vl = r36
+C vlinv = r37 (preinv only)
+C cnt = r38 (preinv only)
+
+PROLOGUE(mpn_preinv_divrem_1)
+ .prologue
+ .save ar.pfs, r42
+ alloc r42 = ar.pfs, 7, 8, 1, 0
+ .save ar.lc, r44
+ mov r44 = ar.lc
+ .save rp, r41
+ mov r41 = b0
+ .body
+ifdef(`HAVE_ABI_32',
+` addp4 r32 = 0, r32
+ sxt4 r33 = r33
+ addp4 r34 = 0, r34
+ sxt4 r35 = r35
+ ;;
+')
+ mov r40 = r38
+ shladd r34 = r35, 3, r34
+ ;;
+ adds r34 = -8, r34
+ ;;
+ ld8 r39 = [r34], -8
+ ;;
+
+ add r15 = r35, r33
+ ;;
+ mov r8 = r37
+ shladd r32 = r15, 3, r32 C r32 = rp + n + qxn
+ cmp.le p8, p0 = 0, r36
+ ;;
+ adds r32 = -8, r32 C r32 = rp + n + qxn - 1
+ cmp.leu p6, p7 = r36, r39
+ (p8) br.cond.dpnt .Lpunnorm
+ ;;
+
+ (p6) addl r15 = 1, r0
+ (p7) mov r15 = r0
+ ;;
+ (p6) sub r38 = r39, r36
+ (p7) mov r38 = r39
+ st8 [r32] = r15, -8
+ adds r35 = -2, r35 C un -= 2
+ br .Lpn
+
+.Lpunnorm:
+ (p6) add r34 = 8, r34
+ mov r38 = 0 C r = 0
+ shl r36 = r36, r40
+ (p6) br.cond.dptk .Lpu
+ ;;
+ shl r38 = r39, r40 C r = ahigh << cnt
+ cmp.ne p8, p0 = 1, r35
+ st8 [r32] = r0, -8
+ adds r35 = -1, r35 C un--
+ (p8) br.cond.dpnt .Lpu
+
+ mov r23 = 1
+ ;;
+ setf.sig f6 = r8
+ setf.sig f12 = r23
+ br .L435
+EPILOGUE()
+
+
+PROLOGUE(mpn_divrem_1)
+ .prologue
+ .save ar.pfs, r42
+ alloc r42 = ar.pfs, 5, 8, 1, 0
+ .save ar.lc, r44
+ mov r44 = ar.lc
+ .save rp, r41
+ mov r41 = b0
+ .body
+ifdef(`HAVE_ABI_32',
+` addp4 r32 = 0, r32
+ sxt4 r33 = r33
+ addp4 r34 = 0, r34
+ sxt4 r35 = r35
+ ;;
+')
+ mov r38 = r0
+ add r15 = r35, r33
+ ;;
+ cmp.ne p6, p7 = 0, r15
+ ;;
+ (p7) mov r8 = r0
+ (p7) br.cond.dpnt .Lret
+ shladd r14 = r15, 3, r32 C r14 = rp + n + qxn
+ cmp.le p6, p7 = 0, r36
+ ;;
+ adds r32 = -8, r14 C r32 = rp + n + qxn - 1
+ (p6) br.cond.dpnt .Lunnorm
+ cmp.eq p6, p7 = 0, r35
+ (p6) br.cond.dpnt .L179
+ shladd r14 = r35, 3, r34
+ ;;
+ adds r14 = -8, r14
+ adds r35 = -1, r35
+ ;;
+ ld8 r38 = [r14]
+ ;;
+ cmp.leu p6, p7 = r36, r38
+ ;;
+ (p6) addl r15 = 1, r0
+ (p7) mov r15 = r0
+ ;;
+ st8 [r32] = r15, -8
+ (p6) sub r38 = r38, r36
+
+.L179:
+ mov r45 = r36
+ adds r35 = -1, r35
+ br.call.sptk.many b0 = mpn_invert_limb
+ ;;
+ shladd r34 = r35, 3, r34
+.Lpn:
+ mov r23 = 1
+ ;;
+ setf.sig f6 = r8
+ setf.sig f12 = r23
+ cmp.le p6, p7 = 0, r35
+ mov r40 = 0
+ (p7) br.cond.dpnt .L435
+ setf.sig f10 = r36
+ mov ar.lc = r35
+ setf.sig f7 = r38
+ ;;
+ sub r28 = -1, r36
+C Develop quotient limbs for normalized divisor
+.Loop1: C 00 C q=r18 nh=r38/f7
+ ld8 r20 = [r34], -8
+ xma.hu f11 = f7, f6, f0
+ ;; C 04
+ xma.l f8 = f11, f12, f7 C q = q + nh
+ ;; C 08
+ getf.sig r18 = f8
+ xma.hu f9 = f8, f10, f0
+ xma.l f8 = f8, f10, f0
+ ;; C 12
+ getf.sig r16 = f9
+ C 13
+ getf.sig r15 = f8
+ ;; C 18
+ cmp.ltu p6, p7 = r20, r15
+ sub r15 = r20, r15
+ sub r16 = r38, r16
+ ;; C 19
+ (p6) cmp.ne p8, p9 = 1, r16 C is rH != 0?
+ (p7) cmp.ne p8, p9 = 0, r16 C is rH != 0?
+ (p6) add r16 = -1, r16
+ (p0) cmp.ne.unc p6, p7 = r0, r0
+ ;; C 20
+ (p8) cmp.ltu p6, p7 = r15, r36
+ (p8) sub r15 = r15, r36
+ (p8) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;; C 21
+ .pred.rel "mutex",p6,p7
+ (p6) cmp.ne p8, p9 = 1, r16 C is rH != 0 still?
+ (p7) cmp.ne p8, p9 = 0, r16 C is rH != 0 still?
+ cmp.ltu p6, p7 = r15, r36 C speculative
+ sub r28 = r15, r36 C speculative, just for cmp
+ ;; C 22
+ (p8) cmp.ltu p6, p7 = r28, r36 C redo last cmp if needed
+ (p8) mov r15 = r28
+ (p8) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;; C 23
+ (p6) setf.sig f7 = r15
+ (p7) sub r15 = r15, r36
+ (p7) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;; C 24
+ (p7) setf.sig f7 = r15
+ st8 [r32] = r18, -8
+ mov r38 = r15
+ br.cloop.dptk .Loop1
+ C 29/30
+ br.sptk .L435
+ ;;
+.Lunnorm:
+ mux1 r16 = r36, @rev
+ cmp.eq p6, p7 = 0, r35
+ (p6) br.cond.dpnt .L322
+ shladd r34 = r35, 3, r34
+ ;;
+ adds r34 = -8, r34
+ ;;
+ ld8 r39 = [r34]
+ ;;
+ cmp.leu p6, p7 = r36, r39
+ (p6) br.cond.dptk .L322
+ adds r34 = -8, r34
+ ;;
+ mov r38 = r39
+ ;;
+ cmp.ne p6, p7 = 1, r15
+ st8 [r32] = r0, -8
+ ;;
+ (p7) mov r8 = r38
+ (p7) br.cond.dpnt .Lret
+ adds r35 = -1, r35
+.L322:
+ sub r14 = r0, r16
+ ;;
+ or r14 = r16, r14
+ ;;
+ mov r16 = -8
+ czx1.l r14 = r14
+ ;;
+ shladd r16 = r14, 3, r16
+ ;;
+ shr.u r14 = r36, r16
+ ;;
+ cmp.geu p6, p7 = 15, r14
+ ;;
+ (p7) shr.u r14 = r14, 4
+ (p7) adds r16 = 4, r16
+ ;;
+ cmp.geu p6, p7 = 3, r14
+ ;;
+ (p7) shr.u r14 = r14, 2
+ (p7) adds r16 = 2, r16
+ ;;
+ tbit.nz p6, p7 = r14, 1
+ ;;
+ .pred.rel "mutex",p6,p7
+ (p6) sub r40 = 62, r16
+ (p7) sub r40 = 63, r16
+ ;;
+ shl r45 = r36, r40
+ shl r36 = r36, r40
+ shl r38 = r38, r40
+ br.call.sptk.many b0 = mpn_invert_limb
+ ;;
+.Lpu:
+ mov r23 = 1
+ ;;
+ setf.sig f6 = r8
+ setf.sig f12 = r23
+ cmp.eq p6, p7 = 0, r35
+ (p6) br.cond.dpnt .L435
+ sub r16 = 64, r40
+ adds r35 = -2, r35
+ ;;
+ ld8 r39 = [r34], -8
+ cmp.le p6, p7 = 0, r35
+ ;;
+ shr.u r14 = r39, r16
+ ;;
+ or r38 = r14, r38
+ (p7) br.cond.dpnt .Lend3
+ ;;
+ mov r22 = r16
+ setf.sig f10 = r36
+ setf.sig f7 = r38
+ mov ar.lc = r35
+ ;;
+C Develop quotient limbs for unnormalized divisor
+.Loop3:
+ ld8 r14 = [r34], -8
+ xma.hu f11 = f7, f6, f0
+ ;;
+ xma.l f8 = f11, f12, f7 C q = q + nh
+ ;;
+ getf.sig r18 = f8
+ xma.hu f9 = f8, f10, f0
+ shl r20 = r39, r40
+ xma.l f8 = f8, f10, f0
+ shr.u r24 = r14, r22
+ ;;
+ getf.sig r16 = f9
+ getf.sig r15 = f8
+ or r20 = r24, r20
+ ;;
+ cmp.ltu p6, p7 = r20, r15
+ sub r15 = r20, r15
+ sub r16 = r38, r16
+ ;;
+ (p6) cmp.ne p8, p9 = 1, r16 C is rH != 0?
+ (p7) cmp.ne p8, p9 = 0, r16 C is rH != 0?
+ (p6) add r16 = -1, r16
+ (p0) cmp.ne.unc p6, p7 = r0, r0
+ ;;
+ (p8) cmp.ltu p6, p7 = r15, r36
+ (p8) sub r15 = r15, r36
+ (p8) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;;
+ .pred.rel "mutex",p6,p7
+ (p6) cmp.ne p8, p9 = 1, r16 C is rH != 0 still?
+ (p7) cmp.ne p8, p9 = 0, r16 C is rH != 0 still?
+ cmp.ltu p6, p7 = r15, r36 C speculative
+ sub r28 = r15, r36 C speculative, just for cmp
+ ;;
+ (p8) cmp.ltu p6, p7 = r28, r36 C redo last cmp if needed
+ (p8) mov r15 = r28
+ (p8) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;;
+ (p6) setf.sig f7 = r15
+ (p7) sub r15 = r15, r36
+ (p7) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;;
+ (p7) setf.sig f7 = r15
+ st8 [r32] = r18, -8
+ mov r39 = r14
+ mov r38 = r15
+ br.cloop.dptk .Loop3
+ ;;
+.Lend3:
+ setf.sig f10 = r36
+ setf.sig f7 = r38
+ ;;
+ xma.hu f11 = f7, f6, f0
+ ;;
+ xma.l f8 = f11, f12, f7 C q = q + nh
+ ;;
+ getf.sig r18 = f8
+ xma.hu f9 = f8, f10, f0
+ shl r20 = r39, r40
+ xma.l f8 = f8, f10, f0
+ ;;
+ getf.sig r16 = f9
+ getf.sig r15 = f8
+ ;;
+ cmp.ltu p6, p7 = r20, r15
+ sub r15 = r20, r15
+ sub r16 = r38, r16
+ ;;
+ (p6) cmp.ne p8, p9 = 1, r16 C is rH != 0?
+ (p7) cmp.ne p8, p9 = 0, r16 C is rH != 0?
+ (p6) add r16 = -1, r16
+ (p0) cmp.ne.unc p6, p7 = r0, r0
+ ;;
+ (p8) cmp.ltu p6, p7 = r15, r36
+ (p8) sub r15 = r15, r36
+ (p8) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;;
+ .pred.rel "mutex",p6,p7
+ (p6) cmp.ne p8, p9 = 1, r16 C is rH != 0 still?
+ (p7) cmp.ne p8, p9 = 0, r16 C is rH != 0 still?
+ ;;
+ (p8) sub r15 = r15, r36
+ (p8) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;;
+ cmp.ltu p6, p7 = r15, r36
+ ;;
+ (p7) sub r15 = r15, r36
+ (p7) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;;
+ st8 [r32] = r18, -8
+ mov r38 = r15
+.L435:
+ adds r35 = -1, r33
+ cmp.le p6, p7 = 1, r33
+ (p7) br.cond.dpnt .Lend4
+ ;;
+ setf.sig f7 = r38
+ setf.sig f10 = r36
+ mov ar.lc = r35
+ ;;
+.Loop4:
+ xma.hu f11 = f7, f6, f0
+ ;;
+ xma.l f8 = f11, f12, f7 C q = q + nh
+ ;;
+ getf.sig r18 = f8
+ xma.hu f9 = f8, f10, f0
+ xma.l f8 = f8, f10, f0
+ ;;
+ getf.sig r16 = f9
+ getf.sig r15 = f8
+ ;;
+ cmp.ltu p6, p7 = 0, r15
+ sub r15 = 0, r15
+ sub r16 = r38, r16
+ ;;
+ (p6) cmp.ne p8, p9 = 1, r16 C is rH != 0?
+ (p7) cmp.ne p8, p9 = 0, r16 C is rH != 0?
+ (p6) add r16 = -1, r16
+ (p0) cmp.ne.unc p6, p7 = r0, r0
+ ;;
+ (p8) cmp.ltu p6, p7 = r15, r36
+ (p8) sub r15 = r15, r36
+ (p8) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;;
+ .pred.rel "mutex",p6,p7
+ (p6) cmp.ne p8, p9 = 1, r16 C is rH != 0 still?
+ (p7) cmp.ne p8, p9 = 0, r16 C is rH != 0 still?
+ cmp.ltu p6, p7 = r15, r36 C speculative
+ sub r28 = r15, r36 C speculative, just for cmp
+ ;;
+ (p8) cmp.ltu p6, p7 = r28, r36 C redo last cmp if needed
+ (p8) mov r15 = r28
+ (p8) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;;
+ (p6) setf.sig f7 = r15
+ (p7) sub r15 = r15, r36
+ (p7) add r18 = 1, r18 C q = q + 1; done if: rH > 0
+ ;;
+ (p7) setf.sig f7 = r15
+ st8 [r32] = r18, -8
+ mov r38 = r15
+ br.cloop.dptk .Loop4
+ ;;
+.Lend4:
+ shr.u r8 = r38, r40
+.Lret:
+ mov ar.pfs = r42
+ mov ar.lc = r44
+ mov b0 = r41
+ br.ret.sptk.many b0
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/divrem_2.asm b/gmp/mpn/ia64/divrem_2.asm
new file mode 100644
index 0000000000..9864311278
--- /dev/null
+++ b/gmp/mpn/ia64/divrem_2.asm
@@ -0,0 +1,280 @@
+dnl IA-64 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number.
+
+dnl Copyright 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C norm frac
+C itanium 1
+C itanium 2 29 29
+
+
+C TODO
+C * Inline and interleave limb inversion code with loop setup code.
+C * We should use explicit bundling in much of the code, since it typically
+C cuts some cycles with the GNU assembler.
+
+
+ASM_START()
+
+C HP's assembler requires these declarations for importing mpn_invert_limb
+ .global mpn_invert_limb
+ .type mpn_invert_limb,@function
+
+C INPUT PARAMETERS
+C qp = r32
+C fn = r33
+C np = r34
+C nn = r35
+C dp = r36
+
+define(`f0x1', `f15')
+
+ASM_START()
+PROLOGUE(mpn_divrem_2)
+ .prologue
+ifdef(`HAVE_ABI_32',
+` addp4 r32 = 0, r32 C M I
+ addp4 r34 = 0, r34 C M I
+ zxt4 r35 = r35 C I
+ addp4 r36 = 0, r36 C M I
+ nop.m 0
+ zxt4 r33 = r33 C I
+ ;;
+')
+ .save ar.pfs, r42
+ alloc r42 = ar.pfs, 5, 9, 1, 0
+ shladd r34 = r35, 3, r34
+ adds r14 = 8, r36
+ mov r43 = r1
+ ;;
+ adds r15 = -8, r34
+ ld8 r39 = [r14]
+ .save ar.lc, r45
+ mov r45 = ar.lc
+ adds r14 = -16, r34
+ mov r40 = r0
+ adds r34 = -24, r34
+ ;;
+ ld8 r38 = [r15]
+ .save rp, r41
+ mov r41 = b0
+ .body
+ ld8 r36 = [r36]
+ ld8 r37 = [r14]
+ ;;
+ cmp.gtu p6, p7 = r39, r38
+ (p6) br.cond.dptk .L8
+ ;;
+ cmp.leu p8, p9 = r36, r37
+ cmp.geu p6, p7 = r39, r38
+ ;;
+ (p8) cmp4.ne.and.orcm p6, p7 = 0, r0
+ (p7) br.cond.dptk .L51
+.L8:
+ add r14 = r33, r35 // un + fn
+ mov r46 = r39 // argument to mpn_invert_limb
+ ;;
+ adds r35 = -3, r14
+ ;;
+ cmp.gt p12, p0 = r0, r35
+ (p12) br.cond.dpnt L(end)
+ br.call.sptk.many b0 = mpn_invert_limb
+ ;;
+ setf.sig f11 = r8 // di (non-final)
+ setf.sig f34 = r39 // d1
+ setf.sig f33 = r36 // d0
+ mov r1 = r43
+ ;;
+ mov r17 = 1
+ setf.sig f9 = r38 // n2
+ xma.l f6 = f11, f34, f0 // t0 = LO(di * d1)
+ ;;
+ setf.sig f10 = r37 // n1
+ setf.sig f15 = r17 // 1
+ xma.hu f8 = f11, f33, f0 // s0 = HI(di * d0)
+ ;;
+ getf.sig r17 = f6
+ getf.sig r16 = f8
+ mov ar.lc = r35
+ ;;
+ sub r18 = r0, r39 // -d1
+ add r14 = r17, r36
+ ;;
+ setf.sig f14 = r18 // -d1
+ cmp.leu p8, p9 = r17, r14
+ add r16 = r14, r16
+ ;;
+ (p9) adds r19 = 0, r0
+ (p8) adds r19 = -1, r0
+ cmp.gtu p6, p7 = r14, r16
+ ;;
+ (p6) adds r19 = 1, r19
+ ;;
+ifelse(1,1,`
+ cmp.gt p7, p6 = r0, r19
+ ;;
+ (p6) adds r8 = -1, r8 // di--
+ (p6) sub r14 = r16, r39 // t0 -= d1
+ (p6) cmp.ltu p6, p7 = r16, r39 // cy for: t0 - d1
+ ;;
+ (p6) cmp.gt p9, p8 = 1, r19
+ (p7) cmp.gt p9, p8 = 0, r19
+ (p6) adds r19 = -1, r19 // t1 -= cy
+ mov r16 = r14
+ ;;
+ (p8) adds r8 = -1, r8 // di--
+ (p8) sub r14 = r16, r39 // t0 -= d1
+ (p8) cmp.ltu p8, p9 = r16, r39 // cy for: t0 - d1
+ ;;
+ (p8) cmp.gt p7, p6 = 1, r19
+ (p9) cmp.gt p7, p6 = 0, r19
+ (p8) adds r19 = -1, r19 // t1 -= cy
+ mov r16 = r14
+ ;;
+ (p6) adds r8 = -1, r8 // di--
+ (p6) sub r14 = r16, r39 // t0 -= d1
+ (p6) cmp.ltu p6, p7 = r16, r39 // cy for: t0 - d1
+ ;;
+ (p6) cmp.gt p9, p8 = 1, r19
+ (p7) cmp.gt p9, p8 = 0, r19
+ (p6) adds r19 = -1, r19 // t1 -= cy
+ mov r16 = r14
+ ;;
+ (p8) adds r8 = -1, r8 // di--
+ (p8) sub r14 = r16, r39 // t0 -= d1
+ (p8) cmp.ltu p8, p9 = r16, r39 // cy for: t0 - d1
+ ;;
+ (p8) adds r19 = -1, r19 // t1 -= cy
+ mov r16 = r14
+',`
+ cmp.gt p8, p9 = r0, r19
+ (p8) br.cond.dpnt .L46
+.L52:
+ cmp.leu p6, p7 = r39, r16
+ sub r14 = r16, r39
+ adds r8 = -1, r8
+ ;;
+ (p7) adds r19 = -1, r19
+ mov r16 = r14
+ ;;
+ (p7) cmp.gt p8, p9 = r0, r19
+ (p9) br.cond.dptk .L52
+.L46:
+')
+ setf.sig f32 = r8 // di
+ shladd r32 = r35, 3, r32
+ ;;
+
+ ALIGN(16)
+L(top): nop 0
+ nop 0
+ cmp.gt p8, p9 = r33, r35
+ ;;
+ (p8) mov r37 = r0
+ (p9) ld8 r37 = [r34], -8
+ xma.hu f8 = f9, f32, f10 // 0,29
+ xma.l f12 = f9, f32, f10 // 0
+ ;;
+ getf.sig r20 = f12 // q0 4
+ xma.l f13 = f15, f8, f9 // q += n2 4
+ sub r8 = -1, r36 // bitnot d0
+ ;;
+ getf.sig r18 = f13 // 8
+ xma.l f7 = f14, f13, f10 // 8
+ xma.l f6 = f33, f13, f33 // t0 = LO(d0*q+d0) 8
+ xma.hu f9 = f33, f13, f33 // t1 = HI(d0*q+d0) 9
+ ;;
+ getf.sig r38 = f7 // n1 12
+ getf.sig r16 = f6 // 13
+ getf.sig r19 = f9 // 14
+ ;;
+ sub r38 = r38, r39 // n1 -= d1 17
+ ;;
+ cmp.ne p9, p0 = r0, r0 // clear p9
+ cmp.leu p10, p11 = r16, r37 // cy for: n0 - t0 18
+ ;;
+ sub r37 = r37, r16 // n0 -= t0 19
+ (p11) sub r38 = r38, r19, 1 // n1 -= t1 - cy 19
+ (p10) sub r38 = r38, r19 // n1 -= t1 19
+ ;;
+ cmp.gtu p6, p7 = r20, r38 // n1 >= q0 20
+ ;;
+ (p7) cmp.ltu p9, p0 = r8, r37 // 21
+ (p6) add r18 = 1, r18 //
+ (p7) add r37 = r37, r36 // 21
+ (p7) add r38 = r38, r39 // 21
+ ;;
+ setf.sig f10 = r37 // n1 22
+ (p9) add r38 = 1, r38 // 22
+ ;;
+ setf.sig f9 = r38 // n2 23
+ cmp.gtu p6, p7 = r39, r38 // 23
+ (p7) br.cond.spnt L(fix)
+L(bck): st8 [r32] = r18, -8
+ adds r35 = -1, r35
+ br.cloop.sptk.few L(top)
+ ;;
+
+L(end): add r14 = 8, r34
+ add r15 = 16, r34
+ mov b0 = r41
+ ;;
+ st8 [r14] = r37
+ st8 [r15] = r38
+ mov ar.pfs = r42
+ mov r8 = r40
+ mov ar.lc = r45
+ br.ret.sptk.many b0
+ ;;
+.L51:
+ .pred.rel "mutex", p8, p9
+ sub r37 = r37, r36
+ (p9) sub r38 = r38, r39, 1
+ (p8) sub r38 = r38, r39
+ adds r40 = 1, r0
+ br .L8
+ ;;
+
+L(fix): cmp.geu p6, p7 = r39, r38
+ cmp.leu p8, p9 = r36, r37
+ ;;
+ (p8) cmp4.ne.and.orcm p6, p7 = 0, r0
+ (p6) br.cond.dptk L(bck)
+ sub r37 = r37, r36
+ (p9) sub r38 = r38, r39, 1
+ (p8) sub r38 = r38, r39
+ adds r18 = 1, r18
+ ;;
+ setf.sig f9 = r38 // n2
+ setf.sig f10 = r37 // n1
+ br L(bck)
+
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/gcd_1.asm b/gmp/mpn/ia64/gcd_1.asm
new file mode 100644
index 0000000000..28e9a63ca3
--- /dev/null
+++ b/gmp/mpn/ia64/gcd_1.asm
@@ -0,0 +1,234 @@
+dnl Itanium-2 mpn_gcd_1 -- mpn by 1 gcd.
+
+dnl Contributed to the GNU project by Kevin Ryde, innerloop by Torbjorn
+dnl Granlund.
+
+dnl Copyright 2002-2005, 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/bitpair (1x1 gcd)
+C Itanium: ?
+C Itanium 2: 5.1
+
+
+C mpn_gcd_1 (mp_srcptr xp, mp_size_t xsize, mp_limb_t y);
+C
+C The entry sequence is designed to expect xsize>1 and hence a modexact
+C call. This ought to be more common than a 1x1 operation. Our critical
+C path is thus stripping factors of 2 from y, calling modexact, then
+C stripping factors of 2 from the x remainder returned.
+C
+C The common factors of 2 between x and y must be determined using the
+C original x, not the remainder from the modexact. This is done with
+C x_orig which is xp[0]. There's plenty of time to do this while the rest
+C of the modexact etc is happening.
+C
+C It's possible xp[0] is zero. In this case the trailing zeros calculation
+C popc((x-1)&~x) gives 63, and that's clearly no less than what y will
+C have, making min(x_twos,y_twos) == y_twos.
+C
+C The main loop consists of transforming x,y to abs(x-y),min(x,y), and then
+C stripping factors of 2 from abs(x-y). Those factors of two are
+C determined from just y-x, without the abs(), since there's the same
+C number of trailing zeros on n or -n in twos complement. That makes the
+C dependent chain 8 cycles deep.
+C
+C The selection of x-y versus y-x for abs(x-y), and the selection of the
+C minimum of x and y, is done in parallel with the critical path.
+C
+C The algorithm takes about 0.68 iterations per bit (two N bit operands) on
+C average, hence the final 5.8 cycles/bitpair.
+C
+C Not done:
+C
+C An alternate algorithm which didn't strip all twos, but instead applied
+C tbit and predicated extr on x, and then y, was attempted. The loop was 6
+C cycles, but the algorithm is an average 1.25 iterations per bitpair for a
+C total 7.25 c/bp, which is slower than the current approach.
+C
+C Alternatives:
+C
+C Perhaps we could do something tricky by extracting a few high bits and a
+C few low bits from the operands, and looking up a table which would give a
+C set of predicates to control some shifts or subtracts or whatever. That
+C could knock off multiple bits per iteration.
+C
+C The right shifts are a bit of a bottleneck (shr at 2 or 3 cycles, or extr
+C only going down I0), perhaps it'd be possible to shift left instead,
+C using add. That would mean keeping track of the lowest not-yet-zeroed
+C bit, using some sort of mask.
+C
+C TODO:
+C * Once mod_1_N exists in assembly for Itanium, add conditional calls.
+C * Call bmod_1 even for n=1 when up[0] >> v0 (like other gcd_1 impls).
+C * Probably avoid popcnt also outside of loop, instead use ctz_table.
+
+ASM_START()
+ .explicit C What does this mean?
+
+C HP's assembler requires these declarations for importing mpn_modexact_1c_odd
+ .global mpn_modexact_1c_odd
+ .type mpn_modexact_1c_odd,@function
+
+C ctz_table[n] is the number of trailing zeros on n, or MAXSHIFT if n==0.
+
+deflit(MAXSHIFT, 7)
+deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))
+
+ .section ".rodata"
+ ALIGN(m4_lshift(1,MAXSHIFT)) C align table to allow using dep
+ctz_table:
+ .byte MAXSHIFT
+forloop(i,1,MASK,
+` .byte m4_count_trailing_zeros(i)
+')
+
+PROLOGUE(mpn_gcd_1)
+
+ C r32 xp
+ C r33 xsize
+ C r34 y
+
+define(x, r8)
+define(xp_orig, r32)
+define(xsize, r33)
+define(y, r34) define(inputs, 3)
+define(save_rp, r35)
+define(save_pfs, r36)
+define(x_orig, r37)
+define(x_orig_one, r38)
+define(y_twos, r39) define(locals, 5)
+define(out_xp, r40)
+define(out_xsize, r41)
+define(out_divisor, r42)
+define(out_carry, r43) define(outputs, 4)
+
+ .prologue
+{ .mmi;
+ifdef(`HAVE_ABI_32',
+` addp4 r9 = 0, xp_orig define(xp,r9)', C M0
+` define(xp,xp_orig)')
+ .save ar.pfs, save_pfs
+ alloc save_pfs = ar.pfs, inputs, locals, outputs, 0 C M2
+ .save rp, save_rp
+ mov save_rp = b0 C I0
+}{ .body
+ add r10 = -1, y C M3 y-1
+} ;;
+
+{ .mmi; ld8 x = [xp] C M0 x = xp[0] if no modexact
+ ld8 x_orig = [xp] C M1 orig x for common twos
+ cmp.ne p6,p0 = 1, xsize C I0
+}{ .mmi; andcm y_twos = r10, y C M2 (y-1)&~y
+ mov out_xp = xp_orig C M3
+ mov out_xsize = xsize C I1
+} ;;
+
+ mov out_carry = 0
+
+ popcnt y_twos = y_twos C I0 y twos
+ ;;
+
+{ .mmi; add x_orig_one = -1, x_orig C M0 orig x-1
+ shr.u out_divisor = y, y_twos C I0 y without twos
+}{ shr.u y = y, y_twos C I1 y without twos
+ (p6) br.call.sptk.many b0 = mpn_modexact_1c_odd C if xsize>1
+} ;;
+
+ C modexact can leave x==0
+{ .mmi; cmp.eq p6,p0 = 0, x C M0 if {xp,xsize} % y == 0
+ andcm x_orig = x_orig_one, x_orig C M1 orig (x-1)&~x
+ add r9 = -1, x C I0 x-1
+} ;;
+
+{ .mmi; andcm r9 = r9, x C M0 (x-1)&~x
+ mov b0 = save_rp C I0
+} ;;
+
+ popcnt x_orig = x_orig C I0 orig x twos
+ popcnt r9 = r9 C I0 x twos
+ ;;
+
+{ cmp.lt p7,p0 = x_orig, y_twos C M0 orig x_twos < y_twos
+ shr.u x = x, r9 C I0 x odd
+} ;;
+
+{ (p7) mov y_twos = x_orig C M0 common twos
+ add r10 = -1, y C I0 y-1
+ (p6) br.dpnt.few L(done_y) C B0 x%y==0 then result y
+} ;;
+
+ addl r22 = @ltoffx(ctz_table#), r1
+ mov r25 = m4_lshift(MASK, MAXSHIFT)
+ ;;
+ ld8.mov r22 = [r22], ctz_table#
+ br L(ent)
+
+ ALIGN(32)
+L(top): .pred.rel "mutex", p6,p7
+.mmi; (p7) mov y = x
+ (p6) sub x = x, y
+ dep r21 = r19, r22, 0, MAXSHIFT C concat(table,lowbits)
+.mmi; and r20 = MASK, r19
+ (p7) mov x = r19
+ nop 0
+ ;;
+L(mid):
+.mmb; ld1 r16 = [r21]
+ cmp.eq p10,p0 = 0, r20
+ (p10) br.spnt.few.clr L(shift_alot)
+ ;;
+.mmi; nop 0
+ nop 0
+ shr.u x = x, r16
+ ;;
+L(ent):
+.mmi; sub r19 = y, x
+ cmp.gtu p6,p7 = x, y
+ cmp.ne p8,p0 = x, y
+.mmb; nop 0
+ nop 0
+ (p8) br.sptk.few.clr L(top)
+
+
+ C result is y
+L(done_y):
+ mov ar.pfs = save_pfs C I0
+ shl r8 = y, y_twos C I common factors of 2
+ br.ret.sptk.many b0
+
+L(shift_alot):
+ and r20 = x, r25
+ shr.u x = x, MAXSHIFT
+ ;;
+ dep r21 = x, r22, 0, MAXSHIFT
+ br L(mid)
+EPILOGUE()
diff --git a/gmp/mpn/ia64/gmp-mparam.h b/gmp/mpn/ia64/gmp-mparam.h
new file mode 100644
index 0000000000..bdbd62d974
--- /dev/null
+++ b/gmp/mpn/ia64/gmp-mparam.h
@@ -0,0 +1,204 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2000-2005, 2009-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 900MHz Itanium2 (titanic.gmplib.org) */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.4 */
+
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 26
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 10
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD 12
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 40
+#define MUL_TOOM33_THRESHOLD 129
+#define MUL_TOOM44_THRESHOLD 212
+#define MUL_TOOM6H_THRESHOLD 318
+#define MUL_TOOM8H_THRESHOLD 430
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 153
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 129
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 151
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 208
+
+#define SQR_BASECASE_THRESHOLD 11
+#define SQR_TOOM2_THRESHOLD 82
+#define SQR_TOOM3_THRESHOLD 131
+#define SQR_TOOM4_THRESHOLD 494
+#define SQR_TOOM6_THRESHOLD 0 /* always */
+#define SQR_TOOM8_THRESHOLD 0 /* always */
+
+#define MULMID_TOOM42_THRESHOLD 98
+
+#define MULMOD_BNM1_THRESHOLD 23
+#define SQRMOD_BNM1_THRESHOLD 19
+
+#define MUL_FFT_MODF_THRESHOLD 500 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 500, 5}, { 27, 6}, { 14, 5}, { 29, 6}, \
+ { 31, 7}, { 16, 6}, { 35, 7}, { 18, 6}, \
+ { 37, 7}, { 19, 6}, { 39, 7}, { 33, 8}, \
+ { 17, 7}, { 37, 8}, { 19, 7}, { 39, 8}, \
+ { 21, 7}, { 43, 8}, { 37, 9}, { 19, 8}, \
+ { 43, 9}, { 23, 8}, { 49, 9}, { 27, 8}, \
+ { 57, 9}, { 31, 8}, { 63, 9}, { 43,10}, \
+ { 23, 9}, { 59,10}, { 31, 9}, { 71,10}, \
+ { 39, 9}, { 83,10}, { 47, 9}, { 99,10}, \
+ { 55,11}, { 31,10}, { 87,11}, { 47,10}, \
+ { 111,12}, { 31,11}, { 63,10}, { 143,11}, \
+ { 79,10}, { 167,11}, { 95,10}, { 199,11}, \
+ { 111,12}, { 63,11}, { 143,10}, { 287,11}, \
+ { 159,12}, { 95,11}, { 191,10}, { 399,11}, \
+ { 207,10}, { 415,13}, { 63,12}, { 127,11}, \
+ { 271,10}, { 543,11}, { 287,10}, { 575,12}, \
+ { 159,11}, { 335,10}, { 671,11}, { 367,12}, \
+ { 191,11}, { 399,10}, { 799,11}, { 431,12}, \
+ { 223,11}, { 447,13}, { 127,12}, { 255,11}, \
+ { 543,12}, { 287,11}, { 607,12}, { 319,11}, \
+ { 671,12}, { 351,11}, { 703,13}, { 191,12}, \
+ { 383,11}, { 799,12}, { 415,11}, { 863,12}, \
+ { 447,14}, { 127,13}, { 255,12}, { 607,13}, \
+ { 319,12}, { 735,13}, { 383,12}, { 863,13}, \
+ { 447,12}, { 927,11}, { 1855,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1055,13}, { 575,12}, \
+ { 1215,13}, { 639,12}, { 1279,13}, { 703,14}, \
+ { 383,13}, { 767,12}, { 1535,13}, { 831,12}, \
+ { 1727,13}, { 895,12}, { 1791,13}, { 959,15}, \
+ { 255,14}, { 511,13}, { 1087,12}, { 2175,13}, \
+ { 1215,14}, { 639,13}, { 1343,12}, { 2687,13}, \
+ { 1471,14}, { 767,13}, { 1599,12}, { 3199,13}, \
+ { 1727,14}, { 895,13}, { 1855,15}, { 511,14}, \
+ { 1023,13}, { 2111,12}, { 4223,13}, { 2175,14}, \
+ { 1151,13}, { 2431,14}, { 1279,13}, { 2687,14}, \
+ { 1407,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 150
+#define MUL_FFT_THRESHOLD 6272
+
+#define SQR_FFT_MODF_THRESHOLD 468 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 468, 5}, { 29, 6}, { 15, 5}, { 31, 6}, \
+ { 35, 7}, { 18, 6}, { 37, 7}, { 37, 8}, \
+ { 19, 7}, { 40, 8}, { 29, 9}, { 15, 8}, \
+ { 37, 9}, { 19, 8}, { 43, 9}, { 23, 8}, \
+ { 49, 9}, { 27, 8}, { 57, 9}, { 43,10}, \
+ { 23, 9}, { 55,10}, { 31, 9}, { 71,10}, \
+ { 39, 9}, { 83,10}, { 47, 9}, { 99,10}, \
+ { 55,11}, { 31,10}, { 87,11}, { 47,10}, \
+ { 111,12}, { 31,11}, { 63,10}, { 143,11}, \
+ { 79,10}, { 167,11}, { 95,10}, { 191,11}, \
+ { 111,12}, { 63,11}, { 127,10}, { 255,11}, \
+ { 143,10}, { 287, 9}, { 575,10}, { 303,11}, \
+ { 159,10}, { 319,12}, { 95,11}, { 191,10}, \
+ { 399,11}, { 207,10}, { 415,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 511,11}, { 271,10}, \
+ { 543,11}, { 287,10}, { 575,11}, { 303,12}, \
+ { 159,11}, { 335,10}, { 671,11}, { 367,10}, \
+ { 735,12}, { 191,11}, { 399,10}, { 799,11}, \
+ { 431,10}, { 863,12}, { 223,11}, { 463,13}, \
+ { 127,12}, { 255,11}, { 543,12}, { 287,11}, \
+ { 607,12}, { 319,11}, { 671,12}, { 351,11}, \
+ { 735,13}, { 191,12}, { 383,11}, { 799,12}, \
+ { 415,11}, { 863,12}, { 447,11}, { 895,14}, \
+ { 127,13}, { 255,12}, { 543,11}, { 1087,12}, \
+ { 607,13}, { 319,12}, { 735,13}, { 383,12}, \
+ { 863,13}, { 447,12}, { 959,14}, { 255,13}, \
+ { 511,12}, { 1087,13}, { 575,12}, { 1215,13}, \
+ { 639,12}, { 1279,13}, { 703,12}, { 1407,14}, \
+ { 383,13}, { 767,12}, { 1535,13}, { 831,12}, \
+ { 1663,13}, { 895,12}, { 1791,13}, { 959,15}, \
+ { 255,14}, { 511,13}, { 1023,12}, { 2047,13}, \
+ { 1087,12}, { 2175,13}, { 1215,14}, { 639,13}, \
+ { 1343,12}, { 2687,13}, { 1471,14}, { 767,13}, \
+ { 1599,12}, { 3199,13}, { 1663,14}, { 895,13}, \
+ { 1919,15}, { 511,14}, { 1023,13}, { 2175,14}, \
+ { 1151,13}, { 2431,14}, { 1279,13}, { 2687,14}, \
+ { 1407,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 154
+#define SQR_FFT_THRESHOLD 4032
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 62
+#define MULLO_MUL_N_THRESHOLD 11616
+
+#define DC_DIV_QR_THRESHOLD 61
+#define DC_DIVAPPR_Q_THRESHOLD 222
+#define DC_BDIV_QR_THRESHOLD 95
+#define DC_BDIV_Q_THRESHOLD 264
+
+#define INV_MULMOD_BNM1_THRESHOLD 78
+#define INV_NEWTON_THRESHOLD 133
+#define INV_APPR_THRESHOLD 141
+
+#define BINV_NEWTON_THRESHOLD 248
+#define REDC_1_TO_REDC_2_THRESHOLD 0 /* always */
+#define REDC_2_TO_REDC_N_THRESHOLD 148
+
+#define MU_DIV_QR_THRESHOLD 1187
+#define MU_DIVAPPR_Q_THRESHOLD 1142
+#define MUPI_DIV_QR_THRESHOLD 0 /* always */
+#define MU_BDIV_QR_THRESHOLD 1308
+#define MU_BDIV_Q_THRESHOLD 1470
+
+#define POWM_SEC_TABLE 1,28,251,1925
+
+#define MATRIX22_STRASSEN_THRESHOLD 23
+#define HGCD_THRESHOLD 120
+#define HGCD_APPR_THRESHOLD 77
+#define HGCD_REDUCE_THRESHOLD 3389
+#define GCD_DC_THRESHOLD 393
+#define GCDEXT_DC_THRESHOLD 440
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 14
+#define GET_STR_PRECOMPUTE_THRESHOLD 20
+#define SET_STR_DC_THRESHOLD 1216
+#define SET_STR_PRECOMPUTE_THRESHOLD 3170
+
+#define FAC_DSC_THRESHOLD 746
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/ia64/hamdist.asm b/gmp/mpn/ia64/hamdist.asm
new file mode 100644
index 0000000000..477df4cd71
--- /dev/null
+++ b/gmp/mpn/ia64/hamdist.asm
@@ -0,0 +1,365 @@
+dnl IA-64 mpn_hamdist -- mpn hamming distance.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2003-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 2
+C Itanium 2: 1
+
+C INPUT PARAMETERS
+define(`up', `r32')
+define(`vp', `r33')
+define(`n', `r34')
+
+define(`u0',`r16') define(`u1',`r17') define(`u2',`r18') define(`u3',`r19')
+define(`v0',`r20') define(`v1',`r21') define(`v2',`r22') define(`v3',`r23')
+define(`x0',`r24') define(`x1',`r25') define(`x2',`r26') define(`x3',`r27')
+define(`c0',`r28') define(`c1',`r29') define(`c2',`r30') define(`c3',`r31')
+define(`s',`r8')
+
+
+ASM_START()
+PROLOGUE(mpn_hamdist)
+ .prologue
+ifdef(`HAVE_ABI_32',
+` addp4 up = 0, up C M I
+ addp4 vp = 0, vp C M I
+ zxt4 n = n C I
+ ;;
+')
+
+ {.mmi; ld8 r10 = [up], 8 C load first ulimb M01
+ ld8 r11 = [vp], 8 C load first vlimb M01
+ mov.i r2 = ar.lc C save ar.lc I0
+}{.mmi; and r14 = 3, n C M I
+ cmp.lt p15, p0 = 4, n C small count? M I
+ add n = -5, n C M I
+ ;;
+}{.mmi; cmp.eq p6, p0 = 1, r14 C M I
+ cmp.eq p7, p0 = 2, r14 C M I
+ cmp.eq p8, p0 = 3, r14 C M I
+}{.bbb
+ (p6) br.dptk .Lb01 C B
+ (p7) br.dptk .Lb10 C B
+ (p8) br.dptk .Lb11 C B
+}
+
+
+.Lb00: ld8 u1 = [up], 8 C M01
+ ld8 v1 = [vp], 8 C M01
+ shr.u n = n, 2 C I0
+ xor x0 = r10, r11 C M I
+ ;;
+ ld8 u2 = [up], 8 C M01
+ ld8 v2 = [vp], 8 C M01
+ mov.i ar.lc = n C I0
+ xor x1 = u1, v1 C M I
+ ;;
+ ld8 u3 = [up], 8 C M01
+ ld8 v3 = [vp], 8 C M01
+ xor x2 = u2, v2 C M I
+ mov s = 0 C M I
+ (p15) br.cond.dptk .grt4 C B
+ ;;
+ popcnt c0 = x0 C I0
+ xor x3 = u3, v3 C M I
+ ;;
+ popcnt c1 = x1 C I0
+ ;;
+ popcnt c2 = x2 C I0
+ br .Lcj4 C B
+
+.grt4: ld8 u0 = [up], 8 C M01
+ ld8 v0 = [vp], 8 C M01
+ xor x1 = u1, v1 C M I
+ ;;
+ ld8 u1 = [up], 8 C M01
+ ld8 v1 = [vp], 8 C M01
+ xor x2 = u2, v2 C M I
+ ;;
+ ld8 u2 = [up], 8 C M01
+ ld8 v2 = [vp], 8 C M01
+ popcnt c0 = x0 C I0
+ xor x3 = u3, v3 C M I
+ ;;
+ ld8 u3 = [up], 8 C M01
+ ld8 v3 = [vp], 8 C M01
+ popcnt c1 = x1 C I0
+ xor x0 = u0, v0 C M I
+ br.cloop.dpnt .grt8 C B
+
+ popcnt c2 = x2 C I0
+ xor x1 = u1, v1 C M I
+ br .Lcj8 C B
+
+.grt8: ld8 u0 = [up], 8 C M01
+ ld8 v0 = [vp], 8 C M01
+ popcnt c2 = x2 C I0
+ xor x1 = u1, v1 C M I
+ br .LL00 C B
+
+
+.Lb01: xor x3 = r10, r11 C M I
+ shr.u n = n, 2 C I0
+ (p15) br.cond.dptk .grt1 C B
+ ;;
+ popcnt r8 = x3 C I0
+ br.ret.sptk.many b0 C B
+
+.grt1: ld8 u0 = [up], 8 C M01
+ ld8 v0 = [vp], 8 C M01
+ mov.i ar.lc = n C I0
+ ;;
+ ld8 u1 = [up], 8 C M01
+ ld8 v1 = [vp], 8 C M01
+ mov s = 0 C M I
+ ;;
+ ld8 u2 = [up], 8 C M01
+ ld8 v2 = [vp], 8 C M01
+ ;;
+ ld8 u3 = [up], 8 C M01
+ ld8 v3 = [vp], 8 C M01
+ xor x0 = u0, v0 C M I
+ br.cloop.dpnt .grt5 C B
+
+ xor x1 = u1, v1 C M I
+ ;;
+ popcnt c3 = x3 C I0
+ xor x2 = u2, v2 C M I
+ ;;
+ popcnt c0 = x0 C I0
+ xor x3 = u3, v3 C M I
+ ;;
+ popcnt c1 = x1 C I0
+ br .Lcj5 C B
+
+.grt5: ld8 u0 = [up], 8 C M01
+ ld8 v0 = [vp], 8 C M01
+ xor x1 = u1, v1 C M I
+ ;;
+ ld8 u1 = [up], 8 C M01
+ ld8 v1 = [vp], 8 C M01
+ popcnt c3 = x3 C I0
+ xor x2 = u2, v2 C M I
+ ;;
+ ld8 u2 = [up], 8 C M01
+ ld8 v2 = [vp], 8 C M01
+ popcnt c0 = x0 C I0
+ xor x3 = u3, v3 C M I
+ ;;
+ ld8 u3 = [up], 8 C M01
+ ld8 v3 = [vp], 8 C M01
+ popcnt c1 = x1 C I0
+ xor x0 = u0, v0 C M I
+ br.cloop.dpnt .Loop C B
+ br .Lend C B
+
+
+.Lb10: ld8 u3 = [up], 8 C M01
+ ld8 v3 = [vp], 8 C M01
+ xor x2 = r10, r11 C M I
+ (p15) br.cond.dptk .grt2 C B
+ ;;
+ xor x3 = u3, v3 C M I
+ ;;
+ popcnt c2 = x2 C I0
+ ;;
+ popcnt c3 = x3 C I0
+ ;;
+ add s = c2, c3 C M I
+ br.ret.sptk.many b0 C B
+
+.grt2: ld8 u0 = [up], 8 C M01
+ ld8 v0 = [vp], 8 C M01
+ shr.u n = n, 2 C I0
+ ;;
+ ld8 u1 = [up], 8 C M01
+ ld8 v1 = [vp], 8 C M01
+ mov.i ar.lc = n C I0
+ mov s = 0 C M I
+ ;;
+ ld8 u2 = [up], 8 C M01
+ ld8 v2 = [vp], 8 C M01
+ xor x3 = u3, v3 C M I
+ ;;
+ ld8 u3 = [up], 8 C M01
+ ld8 v3 = [vp], 8 C M01
+ xor x0 = u0, v0 C M I
+ br.cloop.dptk .grt6 C B
+
+ popcnt c2 = x2 C I0
+ xor x1 = u1, v1 C M I
+ ;;
+ popcnt c3 = x3 C I0
+ xor x2 = u2, v2 C M I
+ ;;
+ popcnt c0 = x0 C I0
+ xor x3 = u3, v3 C M I
+ br .Lcj6 C B
+
+.grt6: ld8 u0 = [up], 8 C M01
+ ld8 v0 = [vp], 8 C M01
+ popcnt c2 = x2 C I0
+ xor x1 = u1, v1 C M I
+ ;;
+ ld8 u1 = [up], 8 C M01
+ ld8 v1 = [vp], 8 C M01
+ popcnt c3 = x3 C I0
+ xor x2 = u2, v2 C M I
+ ;;
+ ld8 u2 = [up], 8 C M01
+ ld8 v2 = [vp], 8 C M01
+ popcnt c0 = x0 C I0
+ xor x3 = u3, v3 C M I
+ br .LL10 C B
+
+
+.Lb11: ld8 u2 = [up], 8 C M01
+ ld8 v2 = [vp], 8 C M01
+ shr.u n = n, 2 C I0
+ xor x1 = r10, r11 C M I
+ ;;
+ ld8 u3 = [up], 8 C M01
+ ld8 v3 = [vp], 8 C M01
+ xor x2 = u2, v2 C M I
+ (p15) br.cond.dptk .grt3 C B
+ ;;
+ xor x3 = u3, v3 C M I
+ ;;
+ popcnt c1 = x1 C I0
+ ;;
+ popcnt c2 = x2 C I0
+ ;;
+ popcnt c3 = x3 C I0
+ ;;
+ add s = c1, c2 C M I
+ ;;
+ add s = s, c3 C M I
+ br.ret.sptk.many b0 C B
+
+.grt3: ld8 u0 = [up], 8 C M01
+ ld8 v0 = [vp], 8 C M01
+ mov.i ar.lc = n C I0
+ ;;
+ ld8 u1 = [up], 8 C M01
+ ld8 v1 = [vp], 8 C M01
+ mov s = 0 C M I
+ ;;
+ ld8 u2 = [up], 8 C M01
+ ld8 v2 = [vp], 8 C M01
+ xor x3 = u3, v3 C M I
+ ;;
+ ld8 u3 = [up], 8 C M01
+ ld8 v3 = [vp], 8 C M01
+ popcnt c1 = x1 C I0
+ xor x0 = u0, v0 C M I
+ br.cloop.dptk .grt7 C B
+ popcnt c2 = x2 C I0
+ xor x1 = u1, v1 C M I
+ ;;
+ popcnt c3 = x3 C I0
+ xor x2 = u2, v2 C M I
+ br .Lcj7 C B
+
+.grt7: ld8 u0 = [up], 8 C M01
+ ld8 v0 = [vp], 8 C M01
+ popcnt c2 = x2 C I0
+ xor x1 = u1, v1 C M I
+ ;;
+ ld8 u1 = [up], 8 C M01
+ ld8 v1 = [vp], 8 C M01
+ popcnt c3 = x3 C I0
+ xor x2 = u2, v2 C M I
+ br .LL11 C B
+
+
+ ALIGN(32)
+.Loop: ld8 u0 = [up], 8 C M01
+ ld8 v0 = [vp], 8 C M01
+ popcnt c2 = x2 C I0
+ add s = s, c3 C M I
+ xor x1 = u1, v1 C M I
+ nop.b 1 C -
+ ;;
+.LL00: ld8 u1 = [up], 8 C M01
+ ld8 v1 = [vp], 8 C M01
+ popcnt c3 = x3 C I0
+ add s = s, c0 C M I
+ xor x2 = u2, v2 C M I
+ nop.b 1 C -
+ ;;
+.LL11: ld8 u2 = [up], 8 C M01
+ ld8 v2 = [vp], 8 C M01
+ popcnt c0 = x0 C I0
+ add s = s, c1 C M I
+ xor x3 = u3, v3 C M I
+ nop.b 1 C -
+ ;;
+.LL10: ld8 u3 = [up], 8 C M01
+ ld8 v3 = [vp], 8 C M01
+ popcnt c1 = x1 C I0
+ add s = s, c2 C M I
+ xor x0 = u0, v0 C M I
+ br.cloop.dptk .Loop C B
+ ;;
+
+.Lend: popcnt c2 = x2 C I0
+ add s = s, c3 C M I
+ xor x1 = u1, v1 C M I
+ ;;
+.Lcj8: popcnt c3 = x3 C I0
+ add s = s, c0 C M I
+ xor x2 = u2, v2 C M I
+ ;;
+.Lcj7: popcnt c0 = x0 C I0
+ add s = s, c1 C M I
+ xor x3 = u3, v3 C M I
+ ;;
+.Lcj6: popcnt c1 = x1 C I0
+ add s = s, c2 C M I
+ ;;
+.Lcj5: popcnt c2 = x2 C I0
+ add s = s, c3 C M I
+ ;;
+.Lcj4: popcnt c3 = x3 C I0
+ add s = s, c0 C M I
+ ;;
+ add s = s, c1 C M I
+ ;;
+ add s = s, c2 C M I
+ ;;
+ add s = s, c3 C M I
+ mov.i ar.lc = r2 C I0
+ br.ret.sptk.many b0 C B
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/ia64-defs.m4 b/gmp/mpn/ia64/ia64-defs.m4
new file mode 100644
index 0000000000..f71d280b17
--- /dev/null
+++ b/gmp/mpn/ia64/ia64-defs.m4
@@ -0,0 +1,147 @@
+divert(-1)
+
+
+dnl Copyright 2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl ia64 assembler comments are C++ style "//" to the end of line. gas
+dnl also accepts "#" as a comment, if it's the first non-blank on a line.
+dnl
+dnl BSD m4 can't handle a multi-character comment like "//" (see notes in
+dnl mpn/asm-defs.m4). For now the default "#" is left, but with care taken
+dnl not to put any macros after "foo#" (since of course they won't expand).
+
+
+define(`ASM_START',
+m4_assert_numargs(0)
+`')
+
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+dnl 32-byte alignment is used for the benefit of itanium-2, where the code
+dnl fetcher will only take 2 bundles from a 32-byte aligned target. At
+dnl 16mod32 it only reads 1 in the first cycle. This might not make any
+dnl difference if the rotate buffers are full or there's other work holding
+dnl up execution, but we use 32-bytes to give the best chance of peak
+dnl throughput.
+dnl
+dnl We can use .align here despite the gas bug noted in mpn/ia64/README,
+dnl since we're not expecting to execute across a PROLOGUE(), at least not
+dnl currently.
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+ `
+ .text
+ .align 32
+ .global $1#
+ .proc $1#
+$1:')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+ `
+ .endp $1#
+')
+
+define(`DATASTART',
+ `dnl
+ DATA
+$1:')
+define(`DATAEND',`dnl')
+
+define(`ASM_END',`dnl')
+
+
+dnl Usage: ALIGN(bytes)
+dnl
+dnl Emit a ".align" directive. "bytes" is eval()ed, so can be an
+dnl expression.
+dnl
+dnl This version overrides the definition in mpn/asm-defs.m4. We suppress
+dnl any .align if the gas byte-swapped-nops bug was detected by configure
+dnl GMP_ASM_IA64_ALIGN_OK.
+
+define(`ALIGN',
+m4_assert_numargs(1)
+m4_assert_defined(`IA64_ALIGN_OK')
+`ifelse(IA64_ALIGN_OK,no,,
+`.align eval($1)')')
+
+
+dnl Usage: ASSERT([pr] [,code])
+dnl
+dnl Require that the given predicate register is true after executing the
+dnl test code. For example,
+dnl
+dnl ASSERT(p6,
+dnl ` cmp.eq p6,p0 = r3, r4')
+dnl
+dnl If the predicate register argument is empty then nothing is tested, the
+dnl code is just executed. This can be used for setups required by later
+dnl ASSERTs. The code argument can be omitted to just test a predicate
+dnl with no special setup code.
+dnl
+dnl For convenience, stops are inserted before and after the code emitted.
+
+define(ASSERT,
+m4_assert_numargs_range(1,2)
+m4_assert_defined(`WANT_ASSERT')
+`ifelse(WANT_ASSERT,1,
+` ;;
+ifelse(`$2',,,
+`$2
+ ;;
+')
+ifelse(`$1',,,
+`($1) br .LASSERTok`'ASSERT_label_counter ;;
+ cmp.ne p6,p6 = r0, r0 C illegal instruction
+ ;;
+.LASSERTok`'ASSERT_label_counter:
+define(`ASSERT_label_counter',eval(ASSERT_label_counter+1))
+')
+')')
+define(`ASSERT_label_counter',1)
+
+define(`getfsig', `getf.sig')
+define(`setfsig', `setf.sig')
+define(`cmpeq', `cmp.eq')
+define(`cmpne', `cmp.ne')
+define(`cmpltu', `cmp.ltu')
+define(`cmpleu', `cmp.leu')
+define(`cmpgtu', `cmp.gtu')
+define(`cmpgeu', `cmp.geu')
+define(`cmple', `cmp.le')
+define(`cmpgt', `cmp.gt')
+define(`cmpeqor', `cmp.eq.or')
+define(`cmpequc', `cmp.eq.unc')
+
+divert
diff --git a/gmp/mpn/ia64/invert_limb.asm b/gmp/mpn/ia64/invert_limb.asm
new file mode 100644
index 0000000000..5effdda815
--- /dev/null
+++ b/gmp/mpn/ia64/invert_limb.asm
@@ -0,0 +1,105 @@
+dnl IA-64 mpn_invert_limb -- Invert a normalized limb.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Kevin Ryde.
+
+dnl Copyright 2000, 2002, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C d = r32
+
+C cycles
+C Itanium: 74
+C Itanium 2: 50+6
+
+C It should be possible to avoid the xmpy.hu and the following tests by
+C explicitly chopping in the last fma. That would save about 10 cycles.
+
+ASM_START()
+ .sdata
+ .align 16
+ifdef(`HAVE_DOUBLE_IEEE_LITTLE_ENDIAN',`
+.LC0: data4 0x00000000, 0x80000000, 0x0000403f, 0x00000000 C 2^64
+.LC1: data4 0x00000000, 0x80000000, 0x0000407f, 0x00000000 C 2^128
+
+',`ifdef(`HAVE_DOUBLE_IEEE_BIG_ENDIAN',`
+.LC0: data4 0x403f8000, 0x00000000, 0x00000000, 0x00000000 C 2^64
+.LC1: data4 0x407f8000, 0x00000000, 0x00000000, 0x00000000 C 2^128
+
+',`m4_error(`Oops, need to know float endianness
+')')')
+
+
+PROLOGUE(mpn_invert_limb)
+ C 00
+ addl r14 = @gprel(.LC0), gp
+ addl r15 = @gprel(.LC1), gp
+ setf.sig f7 = r32
+ add r9 = r32, r32 C check for d = 2^63
+ ;; C 01
+ ldfe f10 = [r14] C 2^64
+ ldfe f8 = [r15] C 2^128
+ cmp.eq p6, p0 = 0, r9 C check for d = 2^63
+ mov r8 = -1 C retval for 2^63
+ (p6) br.ret.spnt.many b0
+ ;; C 07
+ fmpy.s1 f11 = f7, f10 C f11 = d * 2^64
+ fnma.s1 f6 = f7, f10, f8 C f6 = 2^128 - d * 2^64
+ ;; C 11
+ frcpa.s1 f8, p6 = f6, f7
+ ;; C 15
+ (p6) fnma.s1 f9 = f7, f8, f1
+ (p6) fmpy.s1 f10 = f6, f8
+ ;; C 19
+ (p6) fmpy.s1 f11 = f9, f9
+ (p6) fma.s1 f10 = f9, f10, f10
+ ;; C 23
+ (p6) fma.s1 f8 = f9, f8, f8
+ (p6) fma.s1 f9 = f11, f10, f10
+ ;; C 27
+ (p6) fma.s1 f8 = f11, f8, f8
+ (p6) fnma.s1 f10 = f7, f9, f6
+ ;; C 31
+ (p6) fma.s1 f8 = f10, f8, f9
+ ;; C 35
+ fcvt.fxu.trunc.s1 f8 = f8
+ ;; C 39
+ getf.sig r8 = f8
+ xmpy.hu f10 = f8, f7 C di * d
+ ;; C 43
+ getf.sig r14 = f10
+ andcm r9 = -1, r32 C one's complement
+ ;; C 48
+ cmp.ltu p6, p0 = r9, r14 C got overflow?
+ ;; C 49
+ (p6) add r8 = -1, r8 C adjust di down
+ br.ret.sptk.many b0
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/logops_n.asm b/gmp/mpn/ia64/logops_n.asm
new file mode 100644
index 0000000000..e4a2f61cce
--- /dev/null
+++ b/gmp/mpn/ia64/logops_n.asm
@@ -0,0 +1,292 @@
+dnl IA-64 mpn_and_n, mpn_andn_n, mpn_nand_n, mpn_ior_n, mpn_iorn_n,
+dnl mpn_nior_n, mpn_xor_n, mpn_xnor_n -- mpn bitwise logical operations.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2003-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 2
+C Itanium 2: 1
+
+C TODO
+C * Use rp,rpx scheme of aors_n.asm to allow parallel stores (useful in
+C wind-down code).
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`vp', `r34')
+define(`n', `r35')
+
+ifdef(`OPERATION_and_n',
+` define(`func',`mpn_and_n')
+ define(`logop', `and $1 = $2, $3')
+ define(`notormov', `mov $1 = $2')')
+ifdef(`OPERATION_andn_n',
+` define(`func',`mpn_andn_n')
+ define(`logop', `andcm $1 = $2, $3')
+ define(`notormov', `mov $1 = $2')')
+ifdef(`OPERATION_nand_n',
+` define(`func',`mpn_nand_n')
+ define(`logop', `and $1 = $2, $3')
+ define(`notormov', `sub $1 = -1, $2')')
+ifdef(`OPERATION_ior_n',
+` define(`func',`mpn_ior_n')
+ define(`logop', `or $1 = $2, $3')
+ define(`notormov', `mov $1 = $2')')
+ifdef(`OPERATION_iorn_n',
+` define(`func',`mpn_iorn_n')
+ define(`logop', `andcm $1 = $3, $2')
+ define(`notormov', `sub $1 = -1, $2')')
+ifdef(`OPERATION_nior_n',
+` define(`func',`mpn_nior_n')
+ define(`logop', `or $1 = $2, $3')
+ define(`notormov', `sub $1 = -1, $2')')
+ifdef(`OPERATION_xor_n',
+` define(`func',`mpn_xor_n')
+ define(`logop', `xor $1 = $2, $3')
+ define(`notormov', `mov $1 = $2')')
+ifdef(`OPERATION_xnor_n',
+` define(`func',`mpn_xnor_n')
+ define(`logop', `xor $1 = $2, $3')
+ define(`notormov', `sub $1 = -1, $2')')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+ASM_START()
+PROLOGUE(func)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',
+` addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ addp4 vp = 0, vp C M I
+ nop.m 0
+ nop.m 0
+ zxt4 n = n C I
+ ;;
+')
+{.mmi
+ ld8 r10 = [up], 8 C M
+ ld8 r11 = [vp], 8 C M
+ mov.i r2 = ar.lc C I0
+}
+{.mmi
+ and r14 = 3, n C M I
+ cmp.lt p15, p14 = 4, n C M I
+ shr.u n = n, 2 C I0
+ ;;
+}
+{.mmi
+ cmp.eq p6, p0 = 1, r14 C M I
+ cmp.eq p7, p0 = 2, r14 C M I
+ cmp.eq p8, p0 = 3, r14 C M I
+}
+{.bbb
+ (p6) br.dptk .Lb01 C B
+ (p7) br.dptk .Lb10 C B
+ (p8) br.dptk .Lb11 C B
+}
+
+.Lb00: ld8 r17 = [up], 8 C M
+ ld8 r21 = [vp], 8 C M
+ add n = -2, n C M I
+ ;;
+ ld8 r18 = [up], 8 C M
+ ld8 r22 = [vp], 8 C M
+ ;;
+ ld8 r19 = [up], 8 C M
+ ld8 r23 = [vp], 8 C M
+ (p15) br.cond.dpnt .grt4 C B
+
+ logop( r14, r10, r11) C M I
+ ;;
+ logop( r15, r17, r21) C M I
+ notormov( r8, r14) C M I
+ br .Lcj4 C B
+
+.grt4: logop( r14, r10, r11) C M I
+ ld8 r16 = [up], 8 C M
+ ld8 r20 = [vp], 8 C M
+ ;;
+ logop( r15, r17, r21) C M I
+ ld8 r17 = [up], 8 C M
+ mov.i ar.lc = n C I0
+ notormov( r8, r14) C M I
+ ld8 r21 = [vp], 8 C M
+ br .LL00 C B
+
+.Lb01: add n = -1, n C M I
+ logop( r15, r10, r11) C M I
+ (p15) br.cond.dpnt .grt1 C B
+ ;;
+
+ notormov( r9, r15) C M I
+ br .Lcj1 C B
+
+.grt1: ld8 r16 = [up], 8 C M
+ ld8 r20 = [vp], 8 C M
+ ;;
+ ld8 r17 = [up], 8 C M
+ ld8 r21 = [vp], 8 C M
+ mov.i ar.lc = n C I0
+ ;;
+ ld8 r18 = [up], 8 C M
+ ld8 r22 = [vp], 8 C M
+ ;;
+ ld8 r19 = [up], 8 C M
+ ld8 r23 = [vp], 8 C M
+ br.cloop.dptk .grt5 C B
+ ;;
+
+ logop( r14, r16, r20) C M I
+ notormov( r9, r15) C M I
+ br .Lcj5 C B
+
+.grt5: logop( r14, r16, r20) C M I
+ ld8 r16 = [up], 8 C M
+ notormov( r9, r15) C M I
+ ld8 r20 = [vp], 8 C M
+ br .LL01 C B
+
+.Lb10: ld8 r19 = [up], 8 C M
+ ld8 r23 = [vp], 8 C M
+ (p15) br.cond.dpnt .grt2 C B
+
+ logop( r14, r10, r11) C M I
+ ;;
+ logop( r15, r19, r23) C M I
+ notormov( r8, r14) C M I
+ br .Lcj2 C B
+
+.grt2: ld8 r16 = [up], 8 C M
+ ld8 r20 = [vp], 8 C M
+ add n = -1, n C M I
+ ;;
+ ld8 r17 = [up], 8 C M
+ ld8 r21 = [vp], 8 C M
+ logop( r14, r10, r11) C M I
+ ;;
+ ld8 r18 = [up], 8 C M
+ ld8 r22 = [vp], 8 C M
+ mov.i ar.lc = n C I0
+ ;;
+ logop( r15, r19, r23) C M I
+ ld8 r19 = [up], 8 C M
+ notormov( r8, r14) C M I
+ ld8 r23 = [vp], 8 C M
+ br.cloop.dptk .Loop C B
+ br .Lcj6 C B
+
+.Lb11: ld8 r18 = [up], 8 C M
+ ld8 r22 = [vp], 8 C M
+ add n = -1, n C M I
+ ;;
+ ld8 r19 = [up], 8 C M
+ ld8 r23 = [vp], 8 C M
+ logop( r15, r10, r11) C M I
+ (p15) br.cond.dpnt .grt3 C B
+ ;;
+
+ logop( r14, r18, r22) C M I
+ notormov( r9, r15) C M I
+ br .Lcj3 C B
+
+.grt3: ld8 r16 = [up], 8 C M
+ ld8 r20 = [vp], 8 C M
+ ;;
+ ld8 r17 = [up], 8 C M
+ ld8 r21 = [vp], 8 C M
+ mov.i ar.lc = n C I0
+ ;;
+ logop( r14, r18, r22) C M I
+ ld8 r18 = [up], 8 C M
+ notormov( r9, r15) C M I
+ ld8 r22 = [vp], 8 C M
+ br .LL11 C B
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+.Loop: st8 [rp] = r8, 8 C M
+ logop( r14, r16, r20) C M I
+ notormov( r9, r15) C M I
+ ld8 r16 = [up], 8 C M
+ ld8 r20 = [vp], 8 C M
+ nop.b 0
+ ;;
+.LL01: st8 [rp] = r9, 8 C M
+ logop( r15, r17, r21) C M I
+ notormov( r8, r14) C M I
+ ld8 r17 = [up], 8 C M
+ ld8 r21 = [vp], 8 C M
+ nop.b 0
+ ;;
+.LL00: st8 [rp] = r8, 8 C M
+ logop( r14, r18, r22) C M I
+ notormov( r9, r15) C M I
+ ld8 r18 = [up], 8 C M
+ ld8 r22 = [vp], 8 C M
+ nop.b 0
+ ;;
+.LL11: st8 [rp] = r9, 8 C M
+ logop( r15, r19, r23) C M I
+ notormov( r8, r14) C M I
+ ld8 r19 = [up], 8 C M
+ ld8 r23 = [vp], 8 C M
+ br.cloop.dptk .Loop ;; C B
+C *** MAIN LOOP END ***
+
+.Lcj6: st8 [rp] = r8, 8 C M
+ logop( r14, r16, r20) C M I
+ notormov( r9, r15) C M I
+ ;;
+.Lcj5: st8 [rp] = r9, 8 C M
+ logop( r15, r17, r21) C M I
+ notormov( r8, r14) C M I
+ ;;
+.Lcj4: st8 [rp] = r8, 8 C M
+ logop( r14, r18, r22) C M I
+ notormov( r9, r15) C M I
+ ;;
+.Lcj3: st8 [rp] = r9, 8 C M
+ logop( r15, r19, r23) C M I
+ notormov( r8, r14) C M I
+ ;;
+.Lcj2: st8 [rp] = r8, 8 C M
+ notormov( r9, r15) C M I
+ ;;
+.Lcj1: st8 [rp] = r9, 8 C M
+ mov.i ar.lc = r2 C I0
+ br.ret.sptk.many b0 C B
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/lorrshift.asm b/gmp/mpn/ia64/lorrshift.asm
new file mode 100644
index 0000000000..694aaf0f40
--- /dev/null
+++ b/gmp/mpn/ia64/lorrshift.asm
@@ -0,0 +1,358 @@
+dnl IA-64 mpn_lshift/mpn_rshift.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2000-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 2
+C Itanium 2: 1
+
+C This code is scheduled deeply since the plain shift instructions shr and shl
+C have a latency of 4 (on Itanium) or 3 (on Itanium 2). Poor scheduling of
+C these instructions cause a 10 cycle replay trap on Itanium.
+
+C The ld8 scheduling should probably be decreased to make the function smaller.
+C Good lfetch will make sure we never stall anyway.
+
+C We should actually issue the first ld8 at cycle 0, and the first BSH/FSH pair
+C at cycle 2. Judicious use of predicates could allow us to issue more ld8's
+C in the prologue.
+
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`n', `r34')
+define(`cnt',`r35')
+
+define(`tnc',`r9')
+
+ifdef(`OPERATION_lshift',`
+ define(`FSH',`shl')
+ define(`BSH',`shr.u')
+ define(`UPD',`-8')
+ define(`POFF',`-512')
+ define(`PUPD',`-32')
+ define(`func',`mpn_lshift')
+')
+ifdef(`OPERATION_rshift',`
+ define(`FSH',`shr.u')
+ define(`BSH',`shl')
+ define(`UPD',`8')
+ define(`POFF',`512')
+ define(`PUPD',`32')
+ define(`func',`mpn_rshift')
+')
+
+MULFUNC_PROLOGUE(mpn_lshift mpn_rshift)
+
+ASM_START()
+PROLOGUE(func)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',
+` addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ sxt4 n = n C M I
+ nop.m 0
+ nop.m 0
+ zxt4 cnt = cnt C I
+ ;;
+')
+
+ {.mmi; cmp.lt p14, p15 = 4, n C M I
+ and r14 = 3, n C M I
+ mov.i r2 = ar.lc C I0
+}{.mmi; add r15 = -1, n C M I
+ sub tnc = 64, cnt C M I
+ add r16 = -5, n
+ ;;
+}{.mmi; cmp.eq p6, p0 = 1, r14 C M I
+ cmp.eq p7, p0 = 2, r14 C M I
+ shr.u n = r16, 2 C I0
+}{.mmi; cmp.eq p8, p0 = 3, r14 C M I
+ifdef(`OPERATION_lshift',
+` shladd up = r15, 3, up C M I
+ shladd rp = r15, 3, rp') C M I
+ ;;
+}{.mmi; add r11 = POFF, up C M I
+ ld8 r10 = [up], UPD C M01
+ mov.i ar.lc = n C I0
+}{.bbb;
+ (p6) br.dptk .Lb01
+ (p7) br.dptk .Lb10
+ (p8) br.dptk .Lb11
+ ;; }
+
+.Lb00: ld8 r19 = [up], UPD
+ ;;
+ ld8 r16 = [up], UPD
+ ;;
+ ld8 r17 = [up], UPD
+ BSH r8 = r10, tnc C function return value
+ ;;
+ FSH r24 = r10, cnt
+ BSH r25 = r19, tnc
+ (p14) br.cond.dptk .grt4
+ ;;
+ FSH r26 = r19, cnt
+ BSH r27 = r16, tnc
+ ;;
+ FSH r20 = r16, cnt
+ BSH r21 = r17, tnc
+ ;;
+ or r14 = r25, r24
+ FSH r22 = r17, cnt
+ BSH r23 = r10, tnc
+ br .Lr4
+
+.grt4: ld8 r18 = [up], UPD
+ FSH r26 = r19, cnt
+ BSH r27 = r16, tnc
+ ;;
+ ld8 r19 = [up], UPD
+ FSH r20 = r16, cnt
+ BSH r21 = r17, tnc
+ ;;
+ ld8 r16 = [up], UPD
+ FSH r22 = r17, cnt
+ BSH r23 = r18, tnc
+ ;;
+ or r14 = r25, r24
+ ld8 r17 = [up], UPD
+ br.cloop.dpnt .Ltop
+ br .Lbot
+
+.Lb01:
+ (p15) BSH r8 = r10, tnc C function return value I
+ (p15) FSH r22 = r10, cnt C I
+ (p15) br.cond.dptk .Lr1 C return B
+
+.grt1: ld8 r18 = [up], UPD
+ ;;
+ ld8 r19 = [up], UPD
+ BSH r8 = r10, tnc C function return value
+ ;;
+ ld8 r16 = [up], UPD
+ FSH r22 = r10, cnt
+ BSH r23 = r18, tnc
+ ;;
+ ld8 r17 = [up], UPD
+ FSH r24 = r18, cnt
+ BSH r25 = r19, tnc
+ br.cloop.dpnt .grt5
+ ;;
+ or r15 = r23, r22
+ FSH r26 = r19, cnt
+ BSH r27 = r16, tnc
+ ;;
+ FSH r20 = r16, cnt
+ BSH r21 = r17, tnc
+ br .Lr5
+
+.grt5: ld8 r18 = [up], UPD
+ FSH r26 = r19, cnt
+ BSH r27 = r16, tnc
+ ;;
+ ld8 r19 = [up], UPD
+ FSH r20 = r16, cnt
+ BSH r21 = r17, tnc
+ ;;
+ or r15 = r23, r22
+ ld8 r16 = [up], UPD
+ br .LL01
+
+
+.Lb10: ld8 r17 = [up], UPD
+ (p14) br.cond.dptk .grt2
+
+ BSH r8 = r10, tnc C function return value
+ ;;
+ FSH r20 = r10, cnt
+ BSH r21 = r17, tnc
+ ;;
+ or r14 = r21, r20
+ FSH r22 = r17, cnt
+ br .Lr2 C return
+
+.grt2: ld8 r18 = [up], UPD
+ BSH r8 = r10, tnc C function return value
+ ;;
+ ld8 r19 = [up], UPD
+ FSH r20 = r10, cnt
+ BSH r21 = r17, tnc
+ ;;
+ ld8 r16 = [up], UPD
+ FSH r22 = r17, cnt
+ BSH r23 = r18, tnc
+ ;;
+ {.mmi; ld8 r17 = [up], UPD
+ or r14 = r21, r20
+ FSH r24 = r18, cnt
+}{.mib; nop 0
+ BSH r25 = r19, tnc
+ br.cloop.dpnt .grt6
+ ;; }
+
+ FSH r26 = r19, cnt
+ BSH r27 = r16, tnc
+ br .Lr6
+
+.grt6: ld8 r18 = [up], UPD
+ FSH r26 = r19, cnt
+ BSH r27 = r16, tnc
+ ;;
+ ld8 r19 = [up], UPD
+ br .LL10
+
+
+.Lb11: ld8 r16 = [up], UPD
+ ;;
+ ld8 r17 = [up], UPD
+ BSH r8 = r10, tnc C function return value
+ (p14) br.cond.dptk .grt3
+ ;;
+
+ FSH r26 = r10, cnt
+ BSH r27 = r16, tnc
+ ;;
+ FSH r20 = r16, cnt
+ BSH r21 = r17, tnc
+ ;;
+ or r15 = r27, r26
+ FSH r22 = r17, cnt
+ br .Lr3 C return
+
+.grt3: ld8 r18 = [up], UPD
+ FSH r26 = r10, cnt
+ BSH r27 = r16, tnc
+ ;;
+ ld8 r19 = [up], UPD
+ FSH r20 = r16, cnt
+ BSH r21 = r17, tnc
+ ;;
+ ld8 r16 = [up], UPD
+ FSH r22 = r17, cnt
+ BSH r23 = r18, tnc
+ ;;
+ ld8 r17 = [up], UPD
+ br.cloop.dpnt .grt7
+
+ or r15 = r27, r26
+ FSH r24 = r18, cnt
+ BSH r25 = r19, tnc
+ br .Lr7
+
+.grt7: or r15 = r27, r26
+ FSH r24 = r18, cnt
+ BSH r25 = r19, tnc
+ ld8 r18 = [up], UPD
+ br .LL11
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+.Ltop:
+ {.mmi; st8 [rp] = r14, UPD C M2
+ or r15 = r27, r26 C M3
+ FSH r24 = r18, cnt C I0
+}{.mmi; ld8 r18 = [up], UPD C M1
+ lfetch [r11], PUPD
+ BSH r25 = r19, tnc C I1
+ ;; }
+.LL11:
+ {.mmi; st8 [rp] = r15, UPD
+ or r14 = r21, r20
+ FSH r26 = r19, cnt
+}{.mmi; ld8 r19 = [up], UPD
+ nop.m 0
+ BSH r27 = r16, tnc
+ ;; }
+.LL10:
+ {.mmi; st8 [rp] = r14, UPD
+ or r15 = r23, r22
+ FSH r20 = r16, cnt
+}{.mmi; ld8 r16 = [up], UPD
+ nop.m 0
+ BSH r21 = r17, tnc
+ ;; }
+.LL01:
+ {.mmi; st8 [rp] = r15, UPD
+ or r14 = r25, r24
+ FSH r22 = r17, cnt
+}{.mib; ld8 r17 = [up], UPD
+ BSH r23 = r18, tnc
+ br.cloop.dptk .Ltop
+ ;; }
+C *** MAIN LOOP END ***
+
+.Lbot:
+ {.mmi; st8 [rp] = r14, UPD
+ or r15 = r27, r26
+ FSH r24 = r18, cnt
+}{.mib; nop 0
+ BSH r25 = r19, tnc
+ nop 0
+ ;; }
+.Lr7:
+ {.mmi; st8 [rp] = r15, UPD
+ or r14 = r21, r20
+ FSH r26 = r19, cnt
+}{.mib; nop 0
+ BSH r27 = r16, tnc
+ nop 0
+ ;; }
+.Lr6:
+ {.mmi; st8 [rp] = r14, UPD
+ or r15 = r23, r22
+ FSH r20 = r16, cnt
+}{.mib; nop 0
+ BSH r21 = r17, tnc
+ nop 0
+ ;; }
+.Lr5: st8 [rp] = r15, UPD
+ or r14 = r25, r24
+ FSH r22 = r17, cnt
+ ;;
+.Lr4: st8 [rp] = r14, UPD
+ or r15 = r27, r26
+ ;;
+.Lr3: st8 [rp] = r15, UPD
+ or r14 = r21, r20
+ ;;
+.Lr2: st8 [rp] = r14, UPD
+ ;;
+.Lr1: st8 [rp] = r22, UPD C M23
+ mov ar.lc = r2 C I0
+ br.ret.sptk.many b0 C B
+EPILOGUE(func)
+ASM_END()
diff --git a/gmp/mpn/ia64/lshiftc.asm b/gmp/mpn/ia64/lshiftc.asm
new file mode 100644
index 0000000000..c402486484
--- /dev/null
+++ b/gmp/mpn/ia64/lshiftc.asm
@@ -0,0 +1,463 @@
+dnl IA-64 mpn_lshiftc.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2000-2005, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: ?
+C Itanium 2: 1.25
+
+C This code is scheduled deeply since the plain shift instructions shr and shl
+C have a latency of 4 (on Itanium) or 3 (on Itanium 2). Poor scheduling of
+C these instructions cause a 10 cycle replay trap on Itanium.
+
+C The ld8 scheduling should probably be decreased to make the function smaller.
+C Good lfetch will make sure we never stall anyway.
+
+C We should actually issue the first ld8 at cycle 0, and the first BSH/FSH pair
+C at cycle 2. Judicious use of predicates could allow us to issue more ld8's
+C in the prologue.
+
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`n', `r34')
+define(`cnt',`r35')
+
+define(`tnc',`r9')
+
+define(`FSH',`shl')
+define(`BSH',`shr.u')
+define(`UPD',`-8')
+define(`POFF',`-512')
+define(`PUPD',`-32')
+define(`func',`mpn_lshiftc')
+
+ASM_START()
+PROLOGUE(mpn_lshiftc)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',
+` addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ sxt4 n = n C M I
+ nop.m 0
+ nop.m 0
+ zxt4 cnt = cnt C I
+ ;;
+')
+
+ {.mmi; nop 0 C M I
+ and r14 = 3, n C M I
+ mov.i r2 = ar.lc C I0
+}{.mmi; add r15 = -1, n C M I
+ sub tnc = 64, cnt C M I
+ nop 0
+ ;;
+}{.mmi; cmp.eq p6, p0 = 1, r14 C M I
+ cmp.eq p7, p0 = 2, r14 C M I
+ shr.u n = r15, 2 C I0
+}{.mmi; cmp.eq p8, p0 = 3, r14 C M I
+ shladd up = r15, 3, up C M I
+ shladd rp = r15, 3, rp C M I
+ ;;
+}{.mmi; add r11 = POFF, up C M I
+ ld8 r10 = [up], UPD C M01
+ mov.i ar.lc = n C I0
+}{.bbb;
+ (p6) br.dptk .Lb01
+ (p7) br.dptk .Lb10
+ (p8) br.dptk .Lb11
+ ;; }
+
+.Lb00:
+ ld8 r19 = [up], UPD
+ ;;
+ ld8 r16 = [up], UPD
+ ;;
+ ld8 r17 = [up], UPD
+ BSH r8 = r10, tnc
+ br.cloop.dptk L(gt4)
+ ;;
+ FSH r24 = r10, cnt
+ BSH r25 = r19, tnc
+ ;;
+ FSH r26 = r19, cnt
+ BSH r27 = r16, tnc
+ ;;
+ FSH r20 = r16, cnt
+ BSH r21 = r17, tnc
+ ;;
+ or r14 = r25, r24
+ FSH r22 = r17, cnt
+ ;;
+ or r15 = r27, r26
+ sub r31 = -1, r14
+ br .Lr4
+
+L(gt4):
+ {.mmi; nop 0
+ nop 0
+ FSH r24 = r10, cnt
+}{.mmi; ld8 r18 = [up], UPD
+ nop 0
+ BSH r25 = r19, tnc
+ ;; }
+ {.mmi; nop 0
+ nop 0
+ FSH r26 = r19, cnt
+}{.mmi; ld8 r19 = [up], UPD
+ nop 0
+ BSH r27 = r16, tnc
+ ;; }
+ {.mmi; nop 0
+ nop 0
+ FSH r20 = r16, cnt
+}{.mmi; ld8 r16 = [up], UPD
+ nop 0
+ BSH r21 = r17, tnc
+ ;; }
+ {.mmi; nop 0
+ or r14 = r25, r24
+ FSH r22 = r17, cnt
+}{.mib; ld8 r17 = [up], UPD
+ BSH r23 = r18, tnc
+ br.cloop.dptk L(gt8)
+ ;; }
+ {.mmi; nop 0
+ or r15 = r27, r26
+ FSH r24 = r18, cnt
+}{.mib; sub r31 = -1, r14
+ BSH r25 = r19, tnc
+ br .Lr8 }
+
+L(gt8):
+ or r15 = r27, r26
+ FSH r24 = r18, cnt
+ ld8 r18 = [up], UPD
+ sub r31 = -1, r14
+ BSH r25 = r19, tnc
+ br .LL00
+
+.Lb01:
+ br.cloop.dptk L(gt1)
+ ;;
+ BSH r8 = r10, tnc
+ FSH r22 = r10, cnt
+ ;;
+ sub r31 = -1, r22
+ br .Lr1
+ ;;
+L(gt1):
+ ld8 r18 = [up], UPD
+ BSH r8 = r10, tnc
+ FSH r22 = r10, cnt
+ ;;
+ ld8 r19 = [up], UPD
+ ;;
+ ld8 r16 = [up], UPD
+ ;;
+ ld8 r17 = [up], UPD
+ BSH r23 = r18, tnc
+ br.cloop.dptk L(gt5)
+ ;;
+ nop 0
+ FSH r24 = r18, cnt
+ BSH r25 = r19, tnc
+ ;;
+ nop 0
+ FSH r26 = r19, cnt
+ BSH r27 = r16, tnc
+ ;;
+ or r15 = r23, r22
+ FSH r20 = r16, cnt
+ BSH r21 = r17, tnc
+ ;;
+ or r14 = r25, r24
+ FSH r22 = r17, cnt
+ sub r31 = -1, r15
+ br .Lr5
+
+L(gt5):
+ {.mmi; nop 0
+ nop 0
+ FSH r24 = r18, cnt
+}{.mmi; ld8 r18 = [up], UPD
+ nop 0
+ BSH r25 = r19, tnc
+ ;; }
+ {.mmi; nop 0
+ nop 0
+ FSH r26 = r19, cnt
+}{.mmi; ld8 r19 = [up], UPD
+ nop 0
+ BSH r27 = r16, tnc
+ ;; }
+ {.mmi; nop 0
+ or r15 = r23, r22
+ FSH r20 = r16, cnt
+}{.mmi; ld8 r16 = [up], UPD
+ nop 0
+ BSH r21 = r17, tnc
+ ;; }
+ {.mmi; or r14 = r25, r24
+ sub r31 = -1, r15
+ FSH r22 = r17, cnt
+}{.mib; ld8 r17 = [up], UPD
+ BSH r23 = r18, tnc
+ br L(end)
+ ;; }
+
+.Lb10:
+ ld8 r17 = [up], UPD
+ br.cloop.dptk L(gt2)
+ ;;
+ BSH r8 = r10, tnc
+ FSH r20 = r10, cnt
+ ;;
+ BSH r21 = r17, tnc
+ FSH r22 = r17, cnt
+ ;;
+ or r14 = r21, r20
+ ;;
+ sub r31 = -1, r14
+ br .Lr2
+ ;;
+L(gt2):
+ ld8 r18 = [up], UPD
+ BSH r8 = r10, tnc
+ FSH r20 = r10, cnt
+ ;;
+ ld8 r19 = [up], UPD
+ ;;
+ ld8 r16 = [up], UPD
+ BSH r21 = r17, tnc
+ FSH r22 = r17, cnt
+ ;;
+ ld8 r17 = [up], UPD
+ BSH r23 = r18, tnc
+ br.cloop.dptk L(gt6)
+ ;;
+ nop 0
+ FSH r24 = r18, cnt
+ BSH r25 = r19, tnc
+ ;;
+ or r14 = r21, r20
+ FSH r26 = r19, cnt
+ BSH r27 = r16, tnc
+ ;;
+ {.mmi; nop 0
+ or r15 = r23, r22
+ FSH r20 = r16, cnt
+}{.mib; sub r31 = -1, r14
+ BSH r21 = r17, tnc
+ br .Lr6
+ ;; }
+L(gt6):
+ {.mmi; nop 0
+ nop 0
+ FSH r24 = r18, cnt
+}{.mmi; ld8 r18 = [up], UPD
+ nop 0
+ BSH r25 = r19, tnc
+ ;; }
+ {.mmi; nop 0
+ or r14 = r21, r20
+ FSH r26 = r19, cnt
+}{.mmi; ld8 r19 = [up], UPD
+ nop 0
+ BSH r27 = r16, tnc
+ ;; }
+ {.mmi; or r15 = r23, r22
+ sub r31 = -1, r14
+ FSH r20 = r16, cnt
+}{.mib; ld8 r16 = [up], UPD
+ BSH r21 = r17, tnc
+ br .LL10
+}
+
+.Lb11:
+ ld8 r16 = [up], UPD
+ ;;
+ ld8 r17 = [up], UPD
+ BSH r8 = r10, tnc
+ FSH r26 = r10, cnt
+ br.cloop.dptk L(gt3)
+ ;;
+ BSH r27 = r16, tnc
+ ;;
+ FSH r20 = r16, cnt
+ BSH r21 = r17, tnc
+ ;;
+ FSH r22 = r17, cnt
+ ;;
+ or r15 = r27, r26
+ ;;
+ or r14 = r21, r20
+ sub r31 = -1, r15
+ br .Lr3
+ ;;
+L(gt3):
+ ld8 r18 = [up], UPD
+ ;;
+ ld8 r19 = [up], UPD
+ BSH r27 = r16, tnc
+ ;;
+ {.mmi; nop 0
+ nop 0
+ FSH r20 = r16, cnt
+}{.mmi; ld8 r16 = [up], UPD
+ nop 0
+ BSH r21 = r17, tnc
+ ;; }
+ {.mmi nop 0
+ nop 0
+ FSH r22 = r17, cnt
+}{.mib; ld8 r17 = [up], UPD
+ BSH r23 = r18, tnc
+ br.cloop.dptk L(gt7)
+ ;; }
+ or r15 = r27, r26
+ FSH r24 = r18, cnt
+ BSH r25 = r19, tnc
+ ;;
+ {.mmi; nop 0
+ or r14 = r21, r20
+ FSH r26 = r19, cnt
+}{.mib; sub r31 = -1, r15
+ BSH r27 = r16, tnc
+ br .Lr7
+}
+L(gt7):
+ {.mmi; nop 0
+ or r15 = r27, r26
+ FSH r24 = r18, cnt
+}{.mmi; ld8 r18 = [up], UPD
+ nop 0
+ BSH r25 = r19, tnc
+ ;; }
+ {.mmi; or r14 = r21, r20
+ sub r31 = -1, r15
+ FSH r26 = r19, cnt
+}{.mib; ld8 r19 = [up], UPD
+ BSH r27 = r16, tnc
+ br .LL11
+}
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+L(top):
+.LL01:
+ {.mmi; st8 [rp] = r31, UPD C M2
+ or r15 = r27, r26 C M3
+ FSH r24 = r18, cnt C I0
+}{.mmi; ld8 r18 = [up], UPD C M0
+ sub r31 = -1, r14 C M1
+ BSH r25 = r19, tnc C I1
+ ;; }
+.LL00:
+ {.mmi; st8 [rp] = r31, UPD
+ or r14 = r21, r20
+ FSH r26 = r19, cnt
+}{.mmi; ld8 r19 = [up], UPD
+ sub r31 = -1, r15
+ BSH r27 = r16, tnc
+ ;; }
+.LL11:
+ {.mmi; st8 [rp] = r31, UPD
+ or r15 = r23, r22
+ FSH r20 = r16, cnt
+}{.mmi; ld8 r16 = [up], UPD
+ sub r31 = -1, r14
+ BSH r21 = r17, tnc
+ ;; }
+.LL10:
+ {.mmi; st8 [rp] = r31, UPD
+ or r14 = r25, r24
+ FSH r22 = r17, cnt
+}{.mmi; ld8 r17 = [up], UPD
+ sub r31 = -1, r15
+ BSH r23 = r18, tnc
+ ;; }
+L(end): lfetch [r11], PUPD
+ br.cloop.dptk L(top)
+C *** MAIN LOOP END ***
+
+ {.mmi; st8 [rp] = r31, UPD
+ or r15 = r27, r26
+ FSH r24 = r18, cnt
+}{.mib; sub r31 = -1, r14
+ BSH r25 = r19, tnc
+ nop 0
+ ;; }
+.Lr8:
+ {.mmi; st8 [rp] = r31, UPD
+ or r14 = r21, r20
+ FSH r26 = r19, cnt
+}{.mib; sub r31 = -1, r15
+ BSH r27 = r16, tnc
+ nop 0
+ ;; }
+.Lr7:
+ {.mmi; st8 [rp] = r31, UPD
+ or r15 = r23, r22
+ FSH r20 = r16, cnt
+}{.mib; sub r31 = -1, r14
+ BSH r21 = r17, tnc
+ nop 0
+ ;; }
+.Lr6: st8 [rp] = r31, UPD
+ or r14 = r25, r24
+ FSH r22 = r17, cnt
+ sub r31 = -1, r15
+ ;;
+.Lr5: st8 [rp] = r31, UPD
+ or r15 = r27, r26
+ sub r31 = -1, r14
+ ;;
+.Lr4: st8 [rp] = r31, UPD
+ or r14 = r21, r20
+ sub r31 = -1, r15
+ ;;
+.Lr3: st8 [rp] = r31, UPD
+ sub r31 = -1, r14
+ ;;
+.Lr2: st8 [rp] = r31, UPD
+ sub r31 = -1, r22
+ ;;
+.Lr1: st8 [rp] = r31, UPD C M23
+ mov ar.lc = r2 C I0
+ br.ret.sptk.many b0 C B
+EPILOGUE(func)
+ASM_END()
diff --git a/gmp/mpn/ia64/mod_34lsub1.asm b/gmp/mpn/ia64/mod_34lsub1.asm
new file mode 100644
index 0000000000..edf3602c4c
--- /dev/null
+++ b/gmp/mpn/ia64/mod_34lsub1.asm
@@ -0,0 +1,236 @@
+dnl IA-64 mpn_mod_34lsub1
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2003-2005, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: ?
+C Itanium 2: 1
+
+
+C INPUT PARAMETERS
+define(`up', `r32')
+define(`n', `r33')
+
+C Some useful aliases for registers we use
+define(`u0',`r14') define(`u1',`r15') define(`u2',`r16')
+define(`a0',`r17') define(`a1',`r18') define(`a2',`r19')
+define(`c0',`r20') define(`c1',`r21') define(`c2',`r22')
+
+C This is a fairly simple-minded implementation. One could approach 0.67 c/l
+C with a more sophisticated implementation. If we're really crazy, we could
+C super-unroll, storing carries just in predicate registers, then copy them to
+C a general register, and population count them from there. That'd bring us
+C close to 3 insn/limb, for nearly 0.5 c/l.
+
+C Computing n/3 needs 16 cycles, which is a lot of startup overhead.
+C We therefore use a plain while-style loop:
+C add n = -3, n
+C cmp.le p9, p0 = 3, n
+C (p9) br.cond .Loop
+C Alternatively, we could table n/3 for, say, n < 256, and predicate the
+C 16-cycle code.
+
+C The summing-up code at the end was written quickly, and could surely be
+C vastly improved.
+
+ASM_START()
+PROLOGUE(mpn_mod_34lsub1)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',`
+ addp4 up = 0, up C M I
+ nop.m 0
+ zxt4 n = n C I
+ ;;
+')
+
+ifelse(0,1,`
+ movl r14 = 0xAAAAAAAAAAAAAAAB
+ ;;
+ setf.sig f6 = r14
+ setf.sig f7 = r33
+ ;;
+ xmpy.hu f6 = f6, f7
+ ;;
+ getf.sig r8 = f6
+ ;;
+ shr.u r8 = r8, 1 C Loop count
+ ;;
+ mov.i ar.lc = r8
+')
+
+ ld8 u0 = [up], 8
+ cmp.ne p9, p0 = 1, n
+ (p9) br L(gt1)
+ ;;
+ shr.u r8 = u0, 48
+ dep.z r27 = u0, 0, 48
+ ;;
+ add r8 = r8, r27
+ br.ret.sptk.many b0
+
+
+L(gt1):
+.mmi; nop.m 0
+ mov a0 = 0
+ add n = -2, n
+.mmi; mov c0 = 0
+ mov c1 = 0
+ mov c2 = 0
+ ;;
+.mmi; ld8 u1 = [up], 8
+ mov a1 = 0
+ cmp.ltu p6, p0 = r0, r0 C clear p6
+.mmb; cmp.gt p9, p0 = 3, n
+ mov a2 = 0
+ (p9) br.cond.dptk L(end)
+ ;;
+
+ ALIGN(32)
+L(top):
+.mmi; ld8 u2 = [up], 8
+ (p6) add c0 = 1, c0
+ cmp.ltu p7, p0 = a0, u0
+.mmb; sub a0 = a0, u0
+ add n = -3, n
+ nop.b 0
+ ;;
+.mmi; ld8 u0 = [up], 8
+ (p7) add c1 = 1, c1
+ cmp.ltu p8, p0 = a1, u1
+.mmb; sub a1 = a1, u1
+ cmp.le p9, p0 = 3, n
+ nop.b 0
+ ;;
+.mmi; ld8 u1 = [up], 8
+ (p8) add c2 = 1, c2
+ cmp.ltu p6, p0 = a2, u2
+.mmb; sub a2 = a2, u2
+ nop.m 0
+dnl br.cloop.dptk L(top)
+ (p9) br.cond.dptk L(top)
+ ;;
+
+L(end):
+ cmp.eq p10, p0 = 0, n
+ cmp.eq p11, p0 = 1, n
+ (p10) br L(0)
+
+L(2):
+.mmi; ld8 u2 = [up], 8
+ (p6) add c0 = 1, c0
+ cmp.ltu p7, p0 = a0, u0
+.mmb; sub a0 = a0, u0
+ nop.m 0
+ (p11) br L(1)
+ ;;
+ ld8 u0 = [up], 8
+ (p7) add c1 = 1, c1
+ cmp.ltu p8, p0 = a1, u1
+ sub a1 = a1, u1
+ ;;
+ (p8) add c2 = 1, c2
+ cmp.ltu p6, p0 = a2, u2
+ sub a2 = a2, u2
+ ;;
+ (p6) add c0 = 1, c0
+ cmp.ltu p7, p0 = a0, u0
+ sub a0 = a0, u0
+ ;;
+ (p7) add c1 = 1, c1
+ br L(com)
+
+
+L(1):
+ (p7) add c1 = 1, c1
+ cmp.ltu p8, p0 = a1, u1
+ sub a1 = a1, u1
+ ;;
+ (p8) add c2 = 1, c2
+ cmp.ltu p6, p0 = a2, u2
+ sub a2 = a2, u2
+ ;;
+ (p6) add c0 = 1, c0
+ br L(com)
+
+
+L(0):
+ (p6) add c0 = 1, c0
+ cmp.ltu p7, p0 = a0, u0
+ sub a0 = a0, u0
+ ;;
+ (p7) add c1 = 1, c1
+ cmp.ltu p8, p0 = a1, u1
+ sub a1 = a1, u1
+ ;;
+ (p8) add c2 = 1, c2
+
+L(com):
+C | a2 | a1 | a0 |
+C | | | | |
+ shr.u r24 = a0, 48 C 16 bits
+ shr.u r25 = a1, 32 C 32 bits
+ shr.u r26 = a2, 16 C 48 bits
+ ;;
+ shr.u r10 = c0, 48 C 16 bits, always zero
+ shr.u r11 = c1, 32 C 32 bits
+ shr.u r30 = c2, 16 C 48 bits
+ ;;
+ dep.z r27 = a0, 0, 48 C 48 bits
+ dep.z r28 = a1, 16, 32 C 48 bits
+ dep.z r29 = a2, 32, 16 C 48 bits
+ dep.z r31 = c0, 0, 48 C 48 bits
+ dep.z r14 = c1, 16, 32 C 48 bits
+ dep.z r15 = c2, 32, 16 C 48 bits
+ ;;
+.mmi; add r24 = r24, r25
+ add r26 = r26, r27
+ add r28 = r28, r29
+.mmi; add r10 = r10, r11
+ add r30 = r30, r31
+ add r14 = r14, r15
+ ;;
+ movl r8 = 0xffffffffffff0
+ add r24 = r24, r26
+ add r10 = r10, r30
+ ;;
+ add r24 = r24, r28
+ add r10 = r10, r14
+ ;;
+ sub r8 = r8, r24
+ ;;
+ add r8 = r8, r10
+ br.ret.sptk.many b0
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/mode1o.asm b/gmp/mpn/ia64/mode1o.asm
new file mode 100644
index 0000000000..14d5e81602
--- /dev/null
+++ b/gmp/mpn/ia64/mode1o.asm
@@ -0,0 +1,342 @@
+dnl Itanium-2 mpn_modexact_1c_odd -- mpn by 1 exact remainder.
+
+dnl Contributed to the GNU project by Kevin Ryde.
+
+dnl Copyright 2003-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C Itanium: 15
+C Itanium 2: 8
+
+
+dnl Usage: ABI32(`code')
+dnl
+dnl Emit the given code only under HAVE_ABI_32.
+dnl
+define(ABI32,
+m4_assert_onearg()
+`ifdef(`HAVE_ABI_32',`$1')')
+
+
+C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C
+C The modexact algorithm is usually conceived as a dependent chain
+C
+C l = src[i] - c
+C q = low(l * inverse)
+C c = high(q*divisor) + (src[i]<c)
+C
+C but we can work the src[i]-c into an xma by calculating si=src[i]*inverse
+C separately (off the dependent chain) and using
+C
+C q = low(c * inverse + si)
+C c = high(q*divisor + c)
+C
+C This means the dependent chain is simply xma.l followed by xma.hu, for a
+C total 8 cycles/limb on itanium-2.
+C
+C The reason xma.hu works for the new c is that the low of q*divisor is
+C src[i]-c (being the whole purpose of the q generated, and it can be
+C verified algebraically). If there was an underflow from src[i]-c, then
+C there will be an overflow from (src-c)+c, thereby adding 1 to the new c
+C the same as the borrow bit (src[i]<c) gives in the first style shown.
+C
+C Incidentally, fcmp is not an option for treating src[i]-c, since it
+C apparently traps to the kernel for unnormalized operands like those used
+C and generated by ldf8 and xma. On one GNU/Linux system it took about 1200
+C cycles.
+C
+C
+C First Limb:
+C
+C The first limb uses q = (src[0]-c) * inverse shown in the first style.
+C This lets us get the first q as soon as the inverse is ready, without
+C going through si=s*inverse. Basically at the start we have c and can use
+C it while waiting for the inverse, whereas for the second and subsequent
+C limbs it's the other way around, ie. we have the inverse and are waiting
+C for c.
+C
+C At .Lentry the first two instructions in the loop have been done already.
+C The load of f11=src[1] at the start (predicated on size>=2), and the
+C calculation of q by the initial different scheme.
+C
+C
+C Entry Sequence:
+C
+C In the entry sequence, the critical path is the calculation of the
+C inverse, so this is begun first and optimized. Apart from that, ar.lc is
+C established nice and early so the br.cloop's should predict perfectly.
+C And the load for the low limbs src[0] and src[1] can be initiated long
+C ahead of where they're needed.
+C
+C
+C Inverse Calculation:
+C
+C The initial 8-bit inverse is calculated using a table lookup. If it hits
+C L1 (which is likely if we're called several times) then it should take a
+C total 4 cycles, otherwise hopefully L2 for 9 cycles. This is considered
+C the best approach, on balance. It could be done bitwise, but that would
+C probably be about 14 cycles (2 per bit beyond the first couple). Or it
+C could be taken from 4 bits to 8 with xmpy doubling as used beyond 8 bits,
+C but that would be about 11 cycles.
+C
+C The table is not the same as binvert_limb_table, instead it's 256 bytes,
+C designed to be indexed by the low byte of the divisor. The divisor is
+C always odd, so the relevant data is every second byte in the table. The
+C padding lets us use zxt1 instead of extr.u, the latter would cost an extra
+C cycle because it must go down I0, and we're using the first I0 slot to get
+C ip. The extra 128 bytes of padding should be insignificant compared to
+C typical ia64 code bloat.
+C
+C Having the table in .text allows us to use IP-relative addressing,
+C avoiding a fetch from ltoff. .rodata is apparently not suitable for use
+C IP-relative, it gets a linker relocation overflow on GNU/Linux.
+C
+C
+C Load Scheduling:
+C
+C In the main loop, the data loads are scheduled for an L2 hit, which means
+C 6 cycles for the data ready to use. In fact we end up 7 cycles ahead. In
+C any case that scheduling is achieved simply by doing the load (and xmpy.l
+C for "si") in the immediately preceding iteration.
+C
+C The main loop requires size >= 2, and we handle size==1 by an initial
+C br.cloop to enter the loop only if size>1. Since ar.lc is established
+C early, this should predict perfectly.
+C
+C
+C Not done:
+C
+C Consideration was given to using a plain "(src[0]-c) % divisor" for
+C size==1, but cycle counting suggests about 50 for the sort of approach
+C taken by gcc __umodsi3, versus about 47 for the modexact. (Both assuming
+C L1 hits for their respective fetching.)
+C
+C Consideration was given to a test for high<divisor and replacing the last
+C loop iteration with instead c-=src[size-1] followed by c+=d if underflow.
+C Branching on high<divisor wouldn't be good since a mispredict would cost
+C more than the loop iteration saved, and the condition is of course data
+C dependent. So the theory would be to shorten the loop count if
+C high<divisor, and predicate extra operations at the end. That would mean
+C a gain of 6 when high<divisor, or a cost of 2 if not.
+C
+C Whether such a tradeoff is a win on average depends on assumptions about
+C how many bits in the high and the divisor. If both are uniformly
+C distributed then high<divisor about 50% of the time. But smallish
+C divisors (less chance of high<divisor) might be more likely from
+C applications (mpz_divisible_ui, mpz_gcd_ui, etc). Though biggish divisors
+C would be normal internally from say mpn/generic/perfsqr.c. On balance,
+C for the moment, it's felt the gain is not really enough to be worth the
+C trouble.
+C
+C
+C Enhancement:
+C
+C Process two source limbs per iteration using a two-limb inverse and a
+C sequence like
+C
+C ql = low (c * il + sil) quotient low limb
+C qlc = high(c * il + sil)
+C qh1 = low (c * ih + sih) quotient high, partial
+C
+C cl = high (ql * d + c) carry out of low
+C qh = low (qlc * 1 + qh1) quotient high limb
+C
+C new c = high (qh * d + cl) carry out of high
+C
+C This would be 13 cycles/iteration, giving 6.5 cycles/limb. The two limb
+C s*inverse as sih:sil = sh:sl * ih:il would be calculated off the dependent
+C chain with 4 multiplies. The bigger inverse would take extra time to
+C calculate, but a one limb iteration to handle an odd size could be done as
+C soon as 64-bits of inverse were ready.
+C
+C Perhaps this could even extend to a 3 limb inverse, which might promise 17
+C or 18 cycles for 3 limbs, giving 5.66 or 6.0 cycles/limb.
+C
+
+ASM_START()
+ .explicit
+
+ .text
+ .align 32
+.Ltable:
+data1 0,0x01, 0,0xAB, 0,0xCD, 0,0xB7, 0,0x39, 0,0xA3, 0,0xC5, 0,0xEF
+data1 0,0xF1, 0,0x1B, 0,0x3D, 0,0xA7, 0,0x29, 0,0x13, 0,0x35, 0,0xDF
+data1 0,0xE1, 0,0x8B, 0,0xAD, 0,0x97, 0,0x19, 0,0x83, 0,0xA5, 0,0xCF
+data1 0,0xD1, 0,0xFB, 0,0x1D, 0,0x87, 0,0x09, 0,0xF3, 0,0x15, 0,0xBF
+data1 0,0xC1, 0,0x6B, 0,0x8D, 0,0x77, 0,0xF9, 0,0x63, 0,0x85, 0,0xAF
+data1 0,0xB1, 0,0xDB, 0,0xFD, 0,0x67, 0,0xE9, 0,0xD3, 0,0xF5, 0,0x9F
+data1 0,0xA1, 0,0x4B, 0,0x6D, 0,0x57, 0,0xD9, 0,0x43, 0,0x65, 0,0x8F
+data1 0,0x91, 0,0xBB, 0,0xDD, 0,0x47, 0,0xC9, 0,0xB3, 0,0xD5, 0,0x7F
+data1 0,0x81, 0,0x2B, 0,0x4D, 0,0x37, 0,0xB9, 0,0x23, 0,0x45, 0,0x6F
+data1 0,0x71, 0,0x9B, 0,0xBD, 0,0x27, 0,0xA9, 0,0x93, 0,0xB5, 0,0x5F
+data1 0,0x61, 0,0x0B, 0,0x2D, 0,0x17, 0,0x99, 0,0x03, 0,0x25, 0,0x4F
+data1 0,0x51, 0,0x7B, 0,0x9D, 0,0x07, 0,0x89, 0,0x73, 0,0x95, 0,0x3F
+data1 0,0x41, 0,0xEB, 0,0x0D, 0,0xF7, 0,0x79, 0,0xE3, 0,0x05, 0,0x2F
+data1 0,0x31, 0,0x5B, 0,0x7D, 0,0xE7, 0,0x69, 0,0x53, 0,0x75, 0,0x1F
+data1 0,0x21, 0,0xCB, 0,0xED, 0,0xD7, 0,0x59, 0,0xC3, 0,0xE5, 0,0x0F
+data1 0,0x11, 0,0x3B, 0,0x5D, 0,0xC7, 0,0x49, 0,0x33, 0,0x55, 0,0xFF
+
+
+PROLOGUE(mpn_modexact_1c_odd)
+
+ C r32 src
+ C r33 size
+ C r34 divisor
+ C r35 carry
+
+ .prologue
+.Lhere:
+{ .mmi; add r33 = -1, r33 C M0 size-1
+ mov r14 = 2 C M1 2
+ mov r15 = ip C I0 .Lhere
+}{.mmi; setf.sig f6 = r34 C M2 divisor
+ setf.sig f9 = r35 C M3 carry
+ zxt1 r3 = r34 C I1 divisor low byte
+} ;;
+
+{ .mmi; add r3 = .Ltable-.Lhere, r3 C M0 table offset ip and index
+ sub r16 = 0, r34 C M1 -divisor
+ .save ar.lc, r2
+ mov r2 = ar.lc C I0
+}{.mmi; .body
+ setf.sig f13 = r14 C M2 2 in significand
+ mov r17 = -1 C M3 -1
+ABI32(` zxt4 r33 = r33') C I1 size extend
+} ;;
+
+{ .mmi; add r3 = r3, r15 C M0 table entry address
+ABI32(` addp4 r32 = 0, r32') C M1 src extend
+ mov ar.lc = r33 C I0 size-1 loop count
+}{.mmi; setf.sig f12 = r16 C M2 -divisor
+ setf.sig f8 = r17 C M3 -1
+} ;;
+
+{ .mmi; ld1 r3 = [r3] C M0 inverse, 8 bits
+ ldf8 f10 = [r32], 8 C M1 src[0]
+ cmp.ne p6,p0 = 0, r33 C I0 test size!=1
+} ;;
+
+ C Wait for table load.
+ C Hope for an L1 hit of 1 cycles to ALU, but could be more.
+ setf.sig f7 = r3 C M2 inverse, 8 bits
+(p6) ldf8 f11 = [r32], 8 C M1 src[1], if size!=1
+ ;;
+
+ C 5 cycles
+
+ C f6 divisor
+ C f7 inverse, being calculated
+ C f8 -1, will be -inverse
+ C f9 carry
+ C f10 src[0]
+ C f11 src[1]
+ C f12 -divisor
+ C f13 2
+ C f14 scratch
+
+ xmpy.l f14 = f13, f7 C 2*i
+ xmpy.l f7 = f7, f7 C i*i
+ ;;
+ xma.l f7 = f7, f12, f14 C i*i*-d + 2*i, inverse 16 bits
+ ;;
+
+ xmpy.l f14 = f13, f7 C 2*i
+ xmpy.l f7 = f7, f7 C i*i
+ ;;
+ xma.l f7 = f7, f12, f14 C i*i*-d + 2*i, inverse 32 bits
+ ;;
+
+ xmpy.l f14 = f13, f7 C 2*i
+ xmpy.l f7 = f7, f7 C i*i
+ ;;
+
+ xma.l f7 = f7, f12, f14 C i*i*-d + 2*i, inverse 64 bits
+ xma.l f10 = f9, f8, f10 C sc = c * -1 + src[0]
+ ;;
+ASSERT(p6, `
+ xmpy.l f15 = f6, f7 ;; C divisor*inverse
+ getf.sig r31 = f15 ;;
+ cmp.eq p6,p0 = 1, r31 C should == 1
+')
+
+ xmpy.l f10 = f10, f7 C q = sc * inverse
+ xmpy.l f8 = f7, f8 C -inverse = inverse * -1
+ br.cloop.sptk.few.clr .Lentry C main loop, if size > 1
+ ;;
+
+ C size==1, finish up now
+ xma.hu f9 = f10, f6, f9 C c = high(q * divisor + c)
+ mov ar.lc = r2 C I0
+ ;;
+ getf.sig r8 = f9 C M2 return c
+ br.ret.sptk.many b0
+
+
+
+.Ltop:
+ C r2 saved ar.lc
+ C f6 divisor
+ C f7 inverse
+ C f8 -inverse
+ C f9 carry
+ C f10 src[i] * inverse
+ C f11 scratch src[i+1]
+
+ add r16 = 160, r32
+ ldf8 f11 = [r32], 8 C src[i+1]
+ ;;
+ C 2 cycles
+
+ lfetch [r16]
+ xma.l f10 = f9, f8, f10 C q = c * -inverse + si
+ ;;
+ C 3 cycles
+
+.Lentry:
+ xma.hu f9 = f10, f6, f9 C c = high(q * divisor + c)
+ xmpy.l f10 = f11, f7 C si = src[i] * inverse
+ br.cloop.sptk.few.clr .Ltop
+ ;;
+
+
+
+ xma.l f10 = f9, f8, f10 C q = c * -inverse + si
+ mov ar.lc = r2 C I0
+ ;;
+ xma.hu f9 = f10, f6, f9 C c = high(q * divisor + c)
+ ;;
+ getf.sig r8 = f9 C M2 return c
+ br.ret.sptk.many b0
+
+EPILOGUE()
diff --git a/gmp/mpn/ia64/mul_1.asm b/gmp/mpn/ia64/mul_1.asm
new file mode 100644
index 0000000000..21bf6d0e14
--- /dev/null
+++ b/gmp/mpn/ia64/mul_1.asm
@@ -0,0 +1,584 @@
+dnl IA-64 mpn_mul_1, mpn_mul_1c -- Multiply a limb vector with a limb and
+dnl store the result in a second limb vector.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2000-2004, 2006, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 4.0
+C Itanium 2: 2.0
+
+C TODO
+C * Further optimize feed-in and wind-down code, both for speed and code size.
+C * Handle low limb input and results specially, using a common stf8 in the
+C epilogue.
+C * Use 1 c/l carry propagation scheme in wind-down code.
+C * Use extra pointer register for `up' to speed up feed-in loads.
+C * Work out final differences with addmul_1.asm.
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`n', `r34')
+define(`vl', `r35')
+define(`cy', `r36') C for mpn_mul_1c
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ .prologue
+ .save ar.lc, r2
+ .body
+
+ifdef(`HAVE_ABI_32',
+` addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ zxt4 n = n C I
+ ;;
+')
+{.mfi
+ adds r15 = -1, n C M I
+ mov f9 = f0 C F
+ mov.i r2 = ar.lc C I0
+}
+{.mmi
+ ldf8 f7 = [up], 8 C M
+ nop.m 0 C M
+ and r14 = 3, n C M I
+ ;;
+}
+.Lcommon:
+{.mii
+ setf.sig f6 = vl C M2 M3
+ shr.u r31 = r15, 2 C I0
+ cmp.eq p10, p0 = 0, r14 C M I
+}
+{.mii
+ cmp.eq p11, p0 = 2, r14 C M I
+ cmp.eq p12, p0 = 3, r14 C M I
+ nop.i 0 C I
+ ;;
+}
+{.mii
+ cmp.ne p6, p7 = r0, r0 C M I
+ mov.i ar.lc = r31 C I0
+ cmp.ne p8, p9 = r0, r0 C M I
+}
+{.bbb
+ (p10) br.dptk .Lb00 C B
+ (p11) br.dptk .Lb10 C B
+ (p12) br.dptk .Lb11 C B
+ ;;
+}
+
+.Lb01: mov r20 = 0
+ br.cloop.dptk .grt1 C B
+
+ xma.l f39 = f7, f6, f9 C F
+ xma.hu f43 = f7, f6, f9 C F
+ ;;
+ getf.sig r8 = f43 C M2
+ stf8 [rp] = f39 C M2 M3
+ mov.i ar.lc = r2 C I0
+ br.ret.sptk.many b0 C B
+
+.grt1:
+ ldf8 f32 = [up], 8
+ ;;
+ ldf8 f33 = [up], 8
+ ;;
+ ldf8 f34 = [up], 8
+ xma.l f39 = f7, f6, f9
+ xma.hu f43 = f7, f6, f9
+ ;;
+ ldf8 f35 = [up], 8
+ br.cloop.dptk .grt5
+
+ xma.l f36 = f32, f6, f0
+ xma.hu f40 = f32, f6, f0
+ ;;
+ stf8 [rp] = f39, 8
+ xma.l f37 = f33, f6, f0
+ xma.hu f41 = f33, f6, f0
+ ;;
+ getf.sig r21 = f43
+ getf.sig r18 = f36
+ xma.l f38 = f34, f6, f0
+ xma.hu f42 = f34, f6, f0
+ ;;
+ getf.sig r22 = f40
+ getf.sig r19 = f37
+ xma.l f39 = f35, f6, f0
+ xma.hu f43 = f35, f6, f0
+ ;;
+ getf.sig r23 = f41
+ getf.sig r16 = f38
+ br .Lcj5
+
+.grt5:
+ xma.l f36 = f32, f6, f0
+ xma.hu f40 = f32, f6, f0
+ ;;
+ getf.sig r17 = f39
+ ldf8 f32 = [up], 8
+ xma.l f37 = f33, f6, f0
+ xma.hu f41 = f33, f6, f0
+ ;;
+ getf.sig r21 = f43
+ ldf8 f33 = [up], 8
+ xma.l f38 = f34, f6, f0
+ ;;
+ getf.sig r18 = f36
+ xma.hu f42 = f34, f6, f0
+ ;;
+ getf.sig r22 = f40
+ ldf8 f34 = [up], 8
+ xma.l f39 = f35, f6, f0
+ ;;
+ getf.sig r19 = f37
+ xma.hu f43 = f35, f6, f0
+ br .LL01
+
+
+.Lb10: ldf8 f35 = [up], 8
+ mov r23 = 0
+ br.cloop.dptk .grt2
+
+ xma.l f38 = f7, f6, f9
+ xma.hu f42 = f7, f6, f9
+ ;;
+ stf8 [rp] = f38, 8
+ xma.l f39 = f35, f6, f42
+ xma.hu f43 = f35, f6, f42
+ ;;
+ getf.sig r8 = f43
+ stf8 [rp] = f39
+ mov.i ar.lc = r2
+ br.ret.sptk.many b0
+
+
+.grt2:
+ ldf8 f32 = [up], 8
+ ;;
+ ldf8 f33 = [up], 8
+ xma.l f38 = f7, f6, f9
+ xma.hu f42 = f7, f6, f9
+ ;;
+ ldf8 f34 = [up], 8
+ xma.l f39 = f35, f6, f0
+ xma.hu f43 = f35, f6, f0
+ ;;
+ ldf8 f35 = [up], 8
+ br.cloop.dptk .grt6
+
+ stf8 [rp] = f38, 8
+ xma.l f36 = f32, f6, f0
+ xma.hu f40 = f32, f6, f0
+ ;;
+ getf.sig r20 = f42
+ getf.sig r17 = f39
+ xma.l f37 = f33, f6, f0
+ xma.hu f41 = f33, f6, f0
+ ;;
+ getf.sig r21 = f43
+ getf.sig r18 = f36
+ xma.l f38 = f34, f6, f0
+ xma.hu f42 = f34, f6, f0
+ ;;
+ getf.sig r22 = f40
+ getf.sig r19 = f37
+ xma.l f39 = f35, f6, f0
+ xma.hu f43 = f35, f6, f0
+ br .Lcj6
+
+.grt6:
+ getf.sig r16 = f38
+ xma.l f36 = f32, f6, f0
+ xma.hu f40 = f32, f6, f0
+ ;;
+ getf.sig r20 = f42
+ ldf8 f32 = [up], 8
+ xma.l f37 = f33, f6, f0
+ ;;
+ getf.sig r17 = f39
+ xma.hu f41 = f33, f6, f0
+ ;;
+ getf.sig r21 = f43
+ ldf8 f33 = [up], 8
+ xma.l f38 = f34, f6, f0
+ ;;
+ getf.sig r18 = f36
+ xma.hu f42 = f34, f6, f0
+ br .LL10
+
+
+.Lb11: ldf8 f34 = [up], 8
+ mov r22 = 0
+ ;;
+ ldf8 f35 = [up], 8
+ br.cloop.dptk .grt3
+ ;;
+
+ xma.l f37 = f7, f6, f9
+ xma.hu f41 = f7, f6, f9
+ xma.l f38 = f34, f6, f0
+ xma.hu f42 = f34, f6, f0
+ xma.l f39 = f35, f6, f0
+ xma.hu f43 = f35, f6, f0
+ ;;
+ getf.sig r23 = f41
+ stf8 [rp] = f37, 8
+ getf.sig r16 = f38
+ getf.sig r20 = f42
+ getf.sig r17 = f39
+ getf.sig r8 = f43
+ br .Lcj3
+
+.grt3:
+ ldf8 f32 = [up], 8
+ xma.l f37 = f7, f6, f9
+ xma.hu f41 = f7, f6, f9
+ ;;
+ ldf8 f33 = [up], 8
+ xma.l f38 = f34, f6, f0
+ xma.hu f42 = f34, f6, f0
+ ;;
+ getf.sig r19 = f37
+ ldf8 f34 = [up], 8
+ xma.l f39 = f35, f6, f0
+ xma.hu f43 = f35, f6, f0
+ ;;
+ getf.sig r23 = f41
+ ldf8 f35 = [up], 8
+ br.cloop.dptk .grt7
+
+ getf.sig r16 = f38
+ xma.l f36 = f32, f6, f0
+ getf.sig r20 = f42
+ xma.hu f40 = f32, f6, f0
+ ;;
+ getf.sig r17 = f39
+ xma.l f37 = f33, f6, f0
+ getf.sig r21 = f43
+ xma.hu f41 = f33, f6, f0
+ ;;
+ getf.sig r18 = f36
+ st8 [rp] = r19, 8
+ xma.l f38 = f34, f6, f0
+ xma.hu f42 = f34, f6, f0
+ br .Lcj7
+
+.grt7:
+ getf.sig r16 = f38
+ xma.l f36 = f32, f6, f0
+ xma.hu f40 = f32, f6, f0
+ ;;
+ getf.sig r20 = f42
+ ldf8 f32 = [up], 8
+ xma.l f37 = f33, f6, f0
+ ;;
+ getf.sig r17 = f39
+ xma.hu f41 = f33, f6, f0
+ br .LL11
+
+
+.Lb00: ldf8 f33 = [up], 8
+ mov r21 = 0
+ ;;
+ ldf8 f34 = [up], 8
+ ;;
+ ldf8 f35 = [up], 8
+ xma.l f36 = f7, f6, f9
+ xma.hu f40 = f7, f6, f9
+ br.cloop.dptk .grt4
+
+ xma.l f37 = f33, f6, f0
+ xma.hu f41 = f33, f6, f0
+ xma.l f38 = f34, f6, f0
+ xma.hu f42 = f34, f6, f0
+ ;;
+ getf.sig r22 = f40
+ stf8 [rp] = f36, 8
+ xma.l f39 = f35, f6, f0
+ getf.sig r19 = f37
+ xma.hu f43 = f35, f6, f0
+ ;;
+ getf.sig r23 = f41
+ getf.sig r16 = f38
+ getf.sig r20 = f42
+ getf.sig r17 = f39
+ br .Lcj4
+
+.grt4:
+ ldf8 f32 = [up], 8
+ xma.l f37 = f33, f6, f0
+ xma.hu f41 = f33, f6, f0
+ ;;
+ getf.sig r18 = f36
+ ldf8 f33 = [up], 8
+ xma.l f38 = f34, f6, f0
+ xma.hu f42 = f34, f6, f0
+ ;;
+ getf.sig r22 = f40
+ ldf8 f34 = [up], 8
+ xma.l f39 = f35, f6, f0
+ ;;
+ getf.sig r19 = f37
+ getf.sig r23 = f41
+ xma.hu f43 = f35, f6, f0
+ ldf8 f35 = [up], 8
+ br.cloop.dptk .grt8
+
+ getf.sig r16 = f38
+ xma.l f36 = f32, f6, f0
+ getf.sig r20 = f42
+ xma.hu f40 = f32, f6, f0
+ ;;
+ getf.sig r17 = f39
+ st8 [rp] = r18, 8
+ xma.l f37 = f33, f6, f0
+ xma.hu f41 = f33, f6, f0
+ br .Lcj8
+
+.grt8:
+ getf.sig r16 = f38
+ xma.l f36 = f32, f6, f0
+ xma.hu f40 = f32, f6, f0
+ br .LL00
+
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+.Loop:
+ .pred.rel "mutex",p6,p7
+ getf.sig r16 = f38
+ xma.l f36 = f32, f6, f0
+ (p6) cmp.leu p8, p9 = r24, r17
+ st8 [rp] = r24, 8
+ xma.hu f40 = f32, f6, f0
+ (p7) cmp.ltu p8, p9 = r24, r17
+ ;;
+.LL00:
+ .pred.rel "mutex",p8,p9
+ getf.sig r20 = f42
+ (p8) add r24 = r18, r21, 1
+ nop.b 0
+ ldf8 f32 = [up], 8
+ (p9) add r24 = r18, r21
+ nop.b 0
+ ;;
+ .pred.rel "mutex",p8,p9
+ getf.sig r17 = f39
+ xma.l f37 = f33, f6, f0
+ (p8) cmp.leu p6, p7 = r24, r18
+ st8 [rp] = r24, 8
+ xma.hu f41 = f33, f6, f0
+ (p9) cmp.ltu p6, p7 = r24, r18
+ ;;
+.LL11:
+ .pred.rel "mutex",p6,p7
+ getf.sig r21 = f43
+ (p6) add r24 = r19, r22, 1
+ nop.b 0
+ ldf8 f33 = [up], 8
+ (p7) add r24 = r19, r22
+ nop.b 0
+ ;;
+ .pred.rel "mutex",p6,p7
+ getf.sig r18 = f36
+ xma.l f38 = f34, f6, f0
+ (p6) cmp.leu p8, p9 = r24, r19
+ st8 [rp] = r24, 8
+ xma.hu f42 = f34, f6, f0
+ (p7) cmp.ltu p8, p9 = r24, r19
+ ;;
+.LL10:
+ .pred.rel "mutex",p8,p9
+ getf.sig r22 = f40
+ (p8) add r24 = r16, r23, 1
+ nop.b 0
+ ldf8 f34 = [up], 8
+ (p9) add r24 = r16, r23
+ nop.b 0
+ ;;
+ .pred.rel "mutex",p8,p9
+ getf.sig r19 = f37
+ xma.l f39 = f35, f6, f0
+ (p8) cmp.leu p6, p7 = r24, r16
+ st8 [rp] = r24, 8
+ xma.hu f43 = f35, f6, f0
+ (p9) cmp.ltu p6, p7 = r24, r16
+ ;;
+.LL01:
+ .pred.rel "mutex",p6,p7
+ getf.sig r23 = f41
+ (p6) add r24 = r17, r20, 1
+ nop.b 0
+ ldf8 f35 = [up], 8
+ (p7) add r24 = r17, r20
+ br.cloop.dptk .Loop
+C *** MAIN LOOP END ***
+ ;;
+
+.Lcj9:
+ .pred.rel "mutex",p6,p7
+ getf.sig r16 = f38
+ xma.l f36 = f32, f6, f0
+ (p6) cmp.leu p8, p9 = r24, r17
+ st8 [rp] = r24, 8
+ xma.hu f40 = f32, f6, f0
+ (p7) cmp.ltu p8, p9 = r24, r17
+ ;;
+ .pred.rel "mutex",p8,p9
+ getf.sig r20 = f42
+ (p8) add r24 = r18, r21, 1
+ (p9) add r24 = r18, r21
+ ;;
+ .pred.rel "mutex",p8,p9
+ getf.sig r17 = f39
+ xma.l f37 = f33, f6, f0
+ (p8) cmp.leu p6, p7 = r24, r18
+ st8 [rp] = r24, 8
+ xma.hu f41 = f33, f6, f0
+ (p9) cmp.ltu p6, p7 = r24, r18
+ ;;
+.Lcj8:
+ .pred.rel "mutex",p6,p7
+ getf.sig r21 = f43
+ (p6) add r24 = r19, r22, 1
+ (p7) add r24 = r19, r22
+ ;;
+ .pred.rel "mutex",p6,p7
+ getf.sig r18 = f36
+ xma.l f38 = f34, f6, f0
+ (p6) cmp.leu p8, p9 = r24, r19
+ st8 [rp] = r24, 8
+ xma.hu f42 = f34, f6, f0
+ (p7) cmp.ltu p8, p9 = r24, r19
+ ;;
+.Lcj7:
+ .pred.rel "mutex",p8,p9
+ getf.sig r22 = f40
+ (p8) add r24 = r16, r23, 1
+ (p9) add r24 = r16, r23
+ ;;
+ .pred.rel "mutex",p8,p9
+ getf.sig r19 = f37
+ xma.l f39 = f35, f6, f0
+ (p8) cmp.leu p6, p7 = r24, r16
+ st8 [rp] = r24, 8
+ xma.hu f43 = f35, f6, f0
+ (p9) cmp.ltu p6, p7 = r24, r16
+ ;;
+.Lcj6:
+ .pred.rel "mutex",p6,p7
+ getf.sig r23 = f41
+ (p6) add r24 = r17, r20, 1
+ (p7) add r24 = r17, r20
+ ;;
+ .pred.rel "mutex",p6,p7
+ (p6) cmp.leu p8, p9 = r24, r17
+ (p7) cmp.ltu p8, p9 = r24, r17
+ getf.sig r16 = f38
+ st8 [rp] = r24, 8
+ ;;
+.Lcj5:
+ .pred.rel "mutex",p8,p9
+ getf.sig r20 = f42
+ (p8) add r24 = r18, r21, 1
+ (p9) add r24 = r18, r21
+ ;;
+ .pred.rel "mutex",p8,p9
+ (p8) cmp.leu p6, p7 = r24, r18
+ (p9) cmp.ltu p6, p7 = r24, r18
+ getf.sig r17 = f39
+ st8 [rp] = r24, 8
+ ;;
+.Lcj4:
+ .pred.rel "mutex",p6,p7
+ getf.sig r8 = f43
+ (p6) add r24 = r19, r22, 1
+ (p7) add r24 = r19, r22
+ ;;
+ .pred.rel "mutex",p6,p7
+ st8 [rp] = r24, 8
+ (p6) cmp.leu p8, p9 = r24, r19
+ (p7) cmp.ltu p8, p9 = r24, r19
+ ;;
+.Lcj3:
+ .pred.rel "mutex",p8,p9
+ (p8) add r24 = r16, r23, 1
+ (p9) add r24 = r16, r23
+ ;;
+ .pred.rel "mutex",p8,p9
+ st8 [rp] = r24, 8
+ (p8) cmp.leu p6, p7 = r24, r16
+ (p9) cmp.ltu p6, p7 = r24, r16
+ ;;
+.Lcj2:
+ .pred.rel "mutex",p6,p7
+ (p6) add r24 = r17, r20, 1
+ (p7) add r24 = r17, r20
+ ;;
+ .pred.rel "mutex",p6,p7
+ st8 [rp] = r24, 8
+ (p6) cmp.leu p8, p9 = r24, r17
+ (p7) cmp.ltu p8, p9 = r24, r17
+ ;;
+ (p8) add r8 = 1, r8
+ mov.i ar.lc = r2
+ br.ret.sptk.many b0
+EPILOGUE()
+
+PROLOGUE(mpn_mul_1c)
+ .prologue
+ .save ar.lc, r2
+ .body
+
+ifdef(`HAVE_ABI_32',
+` addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ zxt4 n = n C I
+ ;;
+')
+{.mmi
+ adds r15 = -1, n C M I
+ setf.sig f9 = cy C M2 M3
+ mov.i r2 = ar.lc C I0
+}
+{.mmb
+ ldf8 f7 = [up], 8 C M
+ and r14 = 3, n C M I
+ br.sptk .Lcommon
+ ;;
+}
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/mul_2.asm b/gmp/mpn/ia64/mul_2.asm
new file mode 100644
index 0000000000..2bbce97267
--- /dev/null
+++ b/gmp/mpn/ia64/mul_2.asm
@@ -0,0 +1,620 @@
+dnl IA-64 mpn_mul_2 -- Multiply a n-limb number with a 2-limb number and store
+dnl store the result to a (n+1)-limb number.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2004, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: ?
+C Itanium 2: 1.5
+
+C TODO
+C * Clean up variable names, and try to decrease the number of distinct
+C registers used.
+C * Clean up feed-in code to not require zeroing several registers.
+C * Make sure we don't depend on uninitialized predicate registers.
+C * Could perhaps save a few cycles by using 1 c/l carry propagation in
+C wind-down code.
+C * Ultimately rewrite. The problem with this code is that it first uses a
+C loaded u value in one xma pair, then leaves it live over several unrelated
+C xma pairs, before it uses it again. It should actually be quite possible
+C to just swap some aligned xma pairs around. But we should then schedule
+C u loads further from the first use.
+
+C INPUT PARAMETERS
+define(`rp',`r32')
+define(`up',`r33')
+define(`n',`r34')
+define(`vp',`r35')
+
+define(`srp',`r3')
+
+define(`v0',`f6')
+define(`v1',`f7')
+
+define(`s0',`r14')
+define(`acc0',`r15')
+
+define(`pr0_0',`r16') define(`pr0_1',`r17')
+define(`pr0_2',`r18') define(`pr0_3',`r19')
+
+define(`pr1_0',`r20') define(`pr1_1',`r21')
+define(`pr1_2',`r22') define(`pr1_3',`r23')
+
+define(`acc1_0',`r24') define(`acc1_1',`r25')
+define(`acc1_2',`r26') define(`acc1_3',`r27')
+
+dnl define(`',`r28')
+dnl define(`',`r29')
+dnl define(`',`r30')
+dnl define(`',`r31')
+
+define(`fp0b_0',`f8') define(`fp0b_1',`f9')
+define(`fp0b_2',`f10') define(`fp0b_3',`f11')
+
+define(`fp1a_0',`f12') define(`fp1a_1',`f13')
+define(`fp1a_2',`f14') define(`fp1a_3',`f15')
+
+define(`fp1b_0',`f32') define(`fp1b_1',`f33')
+define(`fp1b_2',`f34') define(`fp1b_3',`f35')
+
+define(`fp2a_0',`f36') define(`fp2a_1',`f37')
+define(`fp2a_2',`f38') define(`fp2a_3',`f39')
+
+define(`u_0',`f44') define(`u_1',`f45')
+define(`u_2',`f46') define(`u_3',`f47')
+
+define(`ux',`f49')
+define(`uy',`f51')
+
+ASM_START()
+PROLOGUE(mpn_mul_2)
+ .prologue
+ .save ar.lc, r2
+ .body
+
+ifdef(`HAVE_ABI_32',`
+.mmi; addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ addp4 vp = 0, vp C M I
+.mmi; nop 1
+ nop 1
+ zxt4 n = n C I
+ ;;')
+
+.mmi; ldf8 ux = [up], 8 C M
+ ldf8 v0 = [vp], 8 C M
+ mov r2 = ar.lc C I0
+.mmi; nop 1 C M
+ and r14 = 3, n C M I
+ add n = -2, n C M I
+ ;;
+.mmi; ldf8 uy = [up], 8 C M
+ ldf8 v1 = [vp] C M
+ shr.u n = n, 2 C I0
+.mmi; nop 1 C M
+ cmp.eq p10, p0 = 1, r14 C M I
+ cmp.eq p11, p0 = 2, r14 C M I
+ ;;
+.mmi; nop 1 C M
+ cmp.eq p12, p0 = 3, r14 C M I
+ mov ar.lc = n C I0
+.bbb; (p10) br.dptk L(b01) C B
+ (p11) br.dptk L(b10) C B
+ (p12) br.dptk L(b11) C B
+ ;;
+
+ ALIGN(32)
+L(b00): ldf8 u_1 = [up], 8
+ mov acc1_2 = 0
+ mov pr1_2 = 0
+ mov pr0_3 = 0
+ cmp.ne p8, p9 = r0, r0
+ ;;
+ xma.l fp0b_3 = ux, v0, f0
+ cmp.ne p12, p13 = r0, r0
+ ldf8 u_2 = [up], 8
+ xma.hu fp1a_3 = ux, v0, f0
+ br.cloop.dptk L(gt4)
+
+ xma.l fp0b_0 = uy, v0, f0
+ xma.hu fp1a_0 = uy, v0, f0
+ ;;
+ getfsig acc0 = fp0b_3
+ xma.l fp1b_3 = ux, v1, fp1a_3
+ xma.hu fp2a_3 = ux, v1, fp1a_3
+ ;;
+ xma.l fp0b_1 = u_1, v0, f0
+ xma.hu fp1a_1 = u_1, v0, f0
+ ;;
+ getfsig pr0_0 = fp0b_0
+ xma.l fp1b_0 = uy, v1, fp1a_0
+ xma.hu fp2a_0 = uy, v1, fp1a_0
+ ;;
+ getfsig pr1_3 = fp1b_3
+ getfsig acc1_3 = fp2a_3
+ xma.l fp0b_2 = u_2, v0, f0
+ xma.hu fp1a_2 = u_2, v0, f0
+ br L(cj4)
+
+L(gt4): xma.l fp0b_0 = uy, v0, f0
+ xma.hu fp1a_0 = uy, v0, f0
+ ;;
+ getfsig acc0 = fp0b_3
+ xma.l fp1b_3 = ux, v1, fp1a_3
+ ldf8 u_3 = [up], 8
+ xma.hu fp2a_3 = ux, v1, fp1a_3
+ ;;
+ xma.l fp0b_1 = u_1, v0, f0
+ xma.hu fp1a_1 = u_1, v0, f0
+ ;;
+ getfsig pr0_0 = fp0b_0
+ xma.l fp1b_0 = uy, v1, fp1a_0
+ xma.hu fp2a_0 = uy, v1, fp1a_0
+ ;;
+ ldf8 u_0 = [up], 8
+ getfsig pr1_3 = fp1b_3
+ xma.l fp0b_2 = u_2, v0, f0
+ ;;
+ getfsig acc1_3 = fp2a_3
+ xma.hu fp1a_2 = u_2, v0, f0
+ br L(00)
+
+
+ ALIGN(32)
+L(b01): ldf8 u_0 = [up], 8 C M
+ mov acc1_1 = 0 C M I
+ mov pr1_1 = 0 C M I
+ mov pr0_2 = 0 C M I
+ cmp.ne p6, p7 = r0, r0 C M I
+ ;;
+ xma.l fp0b_2 = ux, v0, f0 C F
+ cmp.ne p10, p11 = r0, r0 C M I
+ ldf8 u_1 = [up], 8 C M
+ xma.hu fp1a_2 = ux, v0, f0 C F
+ ;;
+ xma.l fp0b_3 = uy, v0, f0 C F
+ xma.hu fp1a_3 = uy, v0, f0 C F
+ ;;
+ getfsig acc0 = fp0b_2 C M
+ xma.l fp1b_2 = ux, v1,fp1a_2 C F
+ ldf8 u_2 = [up], 8 C M
+ xma.hu fp2a_2 = ux, v1,fp1a_2 C F
+ br.cloop.dptk L(gt5)
+
+ xma.l fp0b_0 = u_0, v0, f0 C F
+ xma.hu fp1a_0 = u_0, v0, f0 C F
+ ;;
+ getfsig pr0_3 = fp0b_3 C M
+ xma.l fp1b_3 = uy, v1,fp1a_3 C F
+ xma.hu fp2a_3 = uy, v1,fp1a_3 C F
+ ;;
+ getfsig pr1_2 = fp1b_2 C M
+ getfsig acc1_2 = fp2a_2 C M
+ xma.l fp0b_1 = u_1, v0, f0 C F
+ xma.hu fp1a_1 = u_1, v0, f0 C F
+ br L(cj5)
+
+L(gt5): xma.l fp0b_0 = u_0, v0, f0
+ xma.hu fp1a_0 = u_0, v0, f0
+ ;;
+ getfsig pr0_3 = fp0b_3
+ xma.l fp1b_3 = uy, v1, fp1a_3
+ xma.hu fp2a_3 = uy, v1, fp1a_3
+ ;;
+ ldf8 u_3 = [up], 8
+ getfsig pr1_2 = fp1b_2
+ xma.l fp0b_1 = u_1, v0, f0
+ ;;
+ getfsig acc1_2 = fp2a_2
+ xma.hu fp1a_1 = u_1, v0, f0
+ br L(01)
+
+
+ ALIGN(32)
+L(b10): br.cloop.dptk L(gt2)
+ xma.l fp0b_1 = ux, v0, f0
+ xma.hu fp1a_1 = ux, v0, f0
+ ;;
+ xma.l fp0b_2 = uy, v0, f0
+ xma.hu fp1a_2 = uy, v0, f0
+ ;;
+ stf8 [rp] = fp0b_1, 8
+ xma.l fp1b_1 = ux, v1, fp1a_1
+ xma.hu fp2a_1 = ux, v1, fp1a_1
+ ;;
+ getfsig acc0 = fp0b_2
+ xma.l fp1b_2 = uy, v1, fp1a_2
+ xma.hu fp2a_2 = uy, v1, fp1a_2
+ ;;
+ getfsig pr1_1 = fp1b_1
+ getfsig acc1_1 = fp2a_1
+ mov ar.lc = r2
+ getfsig pr1_2 = fp1b_2
+ getfsig r8 = fp2a_2
+ ;;
+ add s0 = pr1_1, acc0
+ ;;
+ st8 [rp] = s0, 8
+ cmp.ltu p8, p9 = s0, pr1_1
+ sub r31 = -1, acc1_1
+ ;;
+ .pred.rel "mutex", p8, p9
+ (p8) add acc0 = pr1_2, acc1_1, 1
+ (p9) add acc0 = pr1_2, acc1_1
+ (p8) cmp.leu p10, p0 = r31, pr1_2
+ (p9) cmp.ltu p10, p0 = r31, pr1_2
+ ;;
+ st8 [rp] = acc0, 8
+ (p10) add r8 = 1, r8
+ br.ret.sptk.many b0
+
+L(gt2): ldf8 u_3 = [up], 8
+ mov acc1_0 = 0
+ mov pr1_0 = 0
+ ;;
+ mov pr0_1 = 0
+ xma.l fp0b_1 = ux, v0, f0
+ ldf8 u_0 = [up], 8
+ xma.hu fp1a_1 = ux, v0, f0
+ ;;
+ xma.l fp0b_2 = uy, v0, f0
+ xma.hu fp1a_2 = uy, v0, f0
+ ;;
+ getfsig acc0 = fp0b_1
+ xma.l fp1b_1 = ux, v1, fp1a_1
+ xma.hu fp2a_1 = ux, v1, fp1a_1
+ ;;
+ ldf8 u_1 = [up], 8
+ xma.l fp0b_3 = u_3, v0, f0
+ xma.hu fp1a_3 = u_3, v0, f0
+ ;;
+ getfsig pr0_2 = fp0b_2
+ xma.l fp1b_2 = uy, v1, fp1a_2
+ xma.hu fp2a_2 = uy, v1, fp1a_2
+ ;;
+ ldf8 u_2 = [up], 8
+ getfsig pr1_1 = fp1b_1
+ ;;
+.mfi; getfsig acc1_1 = fp2a_1
+ xma.l fp0b_0 = u_0, v0, f0
+ cmp.ne p8, p9 = r0, r0
+.mfb; cmp.ne p12, p13 = r0, r0
+ xma.hu fp1a_0 = u_0, v0, f0
+ br L(10)
+
+
+ ALIGN(32)
+L(b11): mov acc1_3 = 0
+ mov pr1_3 = 0
+ mov pr0_0 = 0
+ ldf8 u_2 = [up], 8
+ cmp.ne p6, p7 = r0, r0
+ br.cloop.dptk L(gt3)
+ ;;
+ xma.l fp0b_0 = ux, v0, f0
+ xma.hu fp1a_0 = ux, v0, f0
+ ;;
+ cmp.ne p10, p11 = r0, r0
+ xma.l fp0b_1 = uy, v0, f0
+ xma.hu fp1a_1 = uy, v0, f0
+ ;;
+ getfsig acc0 = fp0b_0
+ xma.l fp1b_0 = ux, v1, fp1a_0
+ xma.hu fp2a_0 = ux, v1, fp1a_0
+ ;;
+ xma.l fp0b_2 = u_2, v0, f0
+ xma.hu fp1a_2 = u_2, v0, f0
+ ;;
+ getfsig pr0_1 = fp0b_1
+ xma.l fp1b_1 = uy, v1, fp1a_1
+ xma.hu fp2a_1 = uy, v1, fp1a_1
+ ;;
+ getfsig pr1_0 = fp1b_0
+ getfsig acc1_0 = fp2a_0
+ br L(cj3)
+
+L(gt3): xma.l fp0b_0 = ux, v0, f0
+ cmp.ne p10, p11 = r0, r0
+ ldf8 u_3 = [up], 8
+ xma.hu fp1a_0 = ux, v0, f0
+ ;;
+ xma.l fp0b_1 = uy, v0, f0
+ xma.hu fp1a_1 = uy, v0, f0
+ ;;
+ getfsig acc0 = fp0b_0
+ xma.l fp1b_0 = ux, v1, fp1a_0
+ ldf8 u_0 = [up], 8
+ xma.hu fp2a_0 = ux, v1, fp1a_0
+ ;;
+ xma.l fp0b_2 = u_2, v0, f0
+ xma.hu fp1a_2 = u_2, v0, f0
+ ;;
+ getfsig pr0_1 = fp0b_1
+ xma.l fp1b_1 = uy, v1, fp1a_1
+ xma.hu fp2a_1 = uy, v1, fp1a_1
+ ;;
+ ldf8 u_1 = [up], 8
+ getfsig pr1_0 = fp1b_0
+ ;;
+ getfsig acc1_0 = fp2a_0
+ xma.l fp0b_3 = u_3, v0, f0
+ xma.hu fp1a_3 = u_3, v0, f0
+ br L(11)
+
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+L(top): C 00
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+ ldf8 u_3 = [up], 8
+ getfsig pr1_2 = fp1b_2
+ (p8) cmp.leu p6, p7 = acc0, pr0_1
+ (p9) cmp.ltu p6, p7 = acc0, pr0_1
+ (p12) cmp.leu p10, p11 = s0, pr1_0
+ (p13) cmp.ltu p10, p11 = s0, pr1_0
+ ;; C 01
+ .pred.rel "mutex", p6, p7
+ getfsig acc1_2 = fp2a_2
+ st8 [rp] = s0, 8
+ xma.l fp0b_1 = u_1, v0, f0
+ (p6) add acc0 = pr0_2, acc1_0, 1
+ (p7) add acc0 = pr0_2, acc1_0
+ xma.hu fp1a_1 = u_1, v0, f0
+ ;; C 02
+L(01):
+ .pred.rel "mutex", p10, p11
+ getfsig pr0_0 = fp0b_0
+ xma.l fp1b_0 = u_0, v1, fp1a_0
+ (p10) add s0 = pr1_1, acc0, 1
+ (p11) add s0 = pr1_1, acc0
+ xma.hu fp2a_0 = u_0, v1, fp1a_0
+ nop 1
+ ;; C 03
+ .pred.rel "mutex", p6, p7
+ .pred.rel "mutex", p10, p11
+ ldf8 u_0 = [up], 8
+ getfsig pr1_3 = fp1b_3
+ (p6) cmp.leu p8, p9 = acc0, pr0_2
+ (p7) cmp.ltu p8, p9 = acc0, pr0_2
+ (p10) cmp.leu p12, p13 = s0, pr1_1
+ (p11) cmp.ltu p12, p13 = s0, pr1_1
+ ;; C 04
+ .pred.rel "mutex", p8, p9
+ getfsig acc1_3 = fp2a_3
+ st8 [rp] = s0, 8
+ xma.l fp0b_2 = u_2, v0, f0
+ (p8) add acc0 = pr0_3, acc1_1, 1
+ (p9) add acc0 = pr0_3, acc1_1
+ xma.hu fp1a_2 = u_2, v0, f0
+ ;; C 05
+L(00):
+ .pred.rel "mutex", p12, p13
+ getfsig pr0_1 = fp0b_1
+ xma.l fp1b_1 = u_1, v1, fp1a_1
+ (p12) add s0 = pr1_2, acc0, 1
+ (p13) add s0 = pr1_2, acc0
+ xma.hu fp2a_1 = u_1, v1, fp1a_1
+ nop 1
+ ;; C 06
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+ ldf8 u_1 = [up], 8
+ getfsig pr1_0 = fp1b_0
+ (p8) cmp.leu p6, p7 = acc0, pr0_3
+ (p9) cmp.ltu p6, p7 = acc0, pr0_3
+ (p12) cmp.leu p10, p11 = s0, pr1_2
+ (p13) cmp.ltu p10, p11 = s0, pr1_2
+ ;; C 07
+ .pred.rel "mutex", p6, p7
+ getfsig acc1_0 = fp2a_0
+ st8 [rp] = s0, 8
+ xma.l fp0b_3 = u_3, v0, f0
+ (p6) add acc0 = pr0_0, acc1_2, 1
+ (p7) add acc0 = pr0_0, acc1_2
+ xma.hu fp1a_3 = u_3, v0, f0
+ ;; C 08
+L(11):
+ .pred.rel "mutex", p10, p11
+ getfsig pr0_2 = fp0b_2
+ xma.l fp1b_2 = u_2, v1, fp1a_2
+ (p10) add s0 = pr1_3, acc0, 1
+ (p11) add s0 = pr1_3, acc0
+ xma.hu fp2a_2 = u_2, v1, fp1a_2
+ nop 1
+ ;; C 09
+ .pred.rel "mutex", p6, p7
+ .pred.rel "mutex", p10, p11
+ ldf8 u_2 = [up], 8
+ getfsig pr1_1 = fp1b_1
+ (p6) cmp.leu p8, p9 = acc0, pr0_0
+ (p7) cmp.ltu p8, p9 = acc0, pr0_0
+ (p10) cmp.leu p12, p13 = s0, pr1_3
+ (p11) cmp.ltu p12, p13 = s0, pr1_3
+ ;; C 10
+ .pred.rel "mutex", p8, p9
+ getfsig acc1_1 = fp2a_1
+ st8 [rp] = s0, 8
+ xma.l fp0b_0 = u_0, v0, f0
+ (p8) add acc0 = pr0_1, acc1_3, 1
+ (p9) add acc0 = pr0_1, acc1_3
+ xma.hu fp1a_0 = u_0, v0, f0
+ ;; C 11
+L(10):
+ .pred.rel "mutex", p12, p13
+ getfsig pr0_3 = fp0b_3
+ xma.l fp1b_3 = u_3, v1, fp1a_3
+ (p12) add s0 = pr1_0, acc0, 1
+ (p13) add s0 = pr1_0, acc0
+ xma.hu fp2a_3 = u_3, v1, fp1a_3
+ br.cloop.dptk L(top)
+ ;;
+C *** MAIN LOOP END ***
+
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+.mmi; getfsig pr1_2 = fp1b_2
+ st8 [rp] = s0, 8
+ (p8) cmp.leu p6, p7 = acc0, pr0_1
+.mmi; (p9) cmp.ltu p6, p7 = acc0, pr0_1
+ (p12) cmp.leu p10, p11 = s0, pr1_0
+ (p13) cmp.ltu p10, p11 = s0, pr1_0
+ ;;
+ .pred.rel "mutex", p6, p7
+.mfi; getfsig acc1_2 = fp2a_2
+ xma.l fp0b_1 = u_1, v0, f0
+ nop 1
+.mmf; (p6) add acc0 = pr0_2, acc1_0, 1
+ (p7) add acc0 = pr0_2, acc1_0
+ xma.hu fp1a_1 = u_1, v0, f0
+ ;;
+L(cj5):
+ .pred.rel "mutex", p10, p11
+.mfi; getfsig pr0_0 = fp0b_0
+ xma.l fp1b_0 = u_0, v1, fp1a_0
+ (p10) add s0 = pr1_1, acc0, 1
+.mfi; (p11) add s0 = pr1_1, acc0
+ xma.hu fp2a_0 = u_0, v1, fp1a_0
+ nop 1
+ ;;
+ .pred.rel "mutex", p6, p7
+ .pred.rel "mutex", p10, p11
+.mmi; getfsig pr1_3 = fp1b_3
+ st8 [rp] = s0, 8
+ (p6) cmp.leu p8, p9 = acc0, pr0_2
+.mmi; (p7) cmp.ltu p8, p9 = acc0, pr0_2
+ (p10) cmp.leu p12, p13 = s0, pr1_1
+ (p11) cmp.ltu p12, p13 = s0, pr1_1
+ ;;
+ .pred.rel "mutex", p8, p9
+.mfi; getfsig acc1_3 = fp2a_3
+ xma.l fp0b_2 = u_2, v0, f0
+ nop 1
+.mmf; (p8) add acc0 = pr0_3, acc1_1, 1
+ (p9) add acc0 = pr0_3, acc1_1
+ xma.hu fp1a_2 = u_2, v0, f0
+ ;;
+L(cj4):
+ .pred.rel "mutex", p12, p13
+.mfi; getfsig pr0_1 = fp0b_1
+ xma.l fp1b_1 = u_1, v1, fp1a_1
+ (p12) add s0 = pr1_2, acc0, 1
+.mfi; (p13) add s0 = pr1_2, acc0
+ xma.hu fp2a_1 = u_1, v1, fp1a_1
+ nop 1
+ ;;
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+.mmi; getfsig pr1_0 = fp1b_0
+ st8 [rp] = s0, 8
+ (p8) cmp.leu p6, p7 = acc0, pr0_3
+.mmi; (p9) cmp.ltu p6, p7 = acc0, pr0_3
+ (p12) cmp.leu p10, p11 = s0, pr1_2
+ (p13) cmp.ltu p10, p11 = s0, pr1_2
+ ;;
+ .pred.rel "mutex", p6, p7
+.mmi; getfsig acc1_0 = fp2a_0
+ (p6) add acc0 = pr0_0, acc1_2, 1
+ (p7) add acc0 = pr0_0, acc1_2
+ ;;
+L(cj3):
+ .pred.rel "mutex", p10, p11
+.mfi; getfsig pr0_2 = fp0b_2
+ xma.l fp1b_2 = u_2, v1, fp1a_2
+ (p10) add s0 = pr1_3, acc0, 1
+.mfi; (p11) add s0 = pr1_3, acc0
+ xma.hu fp2a_2 = u_2, v1, fp1a_2
+ nop 1
+ ;;
+ .pred.rel "mutex", p6, p7
+ .pred.rel "mutex", p10, p11
+.mmi; getfsig pr1_1 = fp1b_1
+ st8 [rp] = s0, 8
+ (p6) cmp.leu p8, p9 = acc0, pr0_0
+.mmi; (p7) cmp.ltu p8, p9 = acc0, pr0_0
+ (p10) cmp.leu p12, p13 = s0, pr1_3
+ (p11) cmp.ltu p12, p13 = s0, pr1_3
+ ;;
+ .pred.rel "mutex", p8, p9
+.mmi; getfsig acc1_1 = fp2a_1
+ (p8) add acc0 = pr0_1, acc1_3, 1
+ (p9) add acc0 = pr0_1, acc1_3
+ ;;
+ .pred.rel "mutex", p12, p13
+.mmi; (p12) add s0 = pr1_0, acc0, 1
+ (p13) add s0 = pr1_0, acc0
+ nop 1
+ ;;
+ .pred.rel "mutex", p8, p9
+ .pred.rel "mutex", p12, p13
+.mmi; getfsig pr1_2 = fp1b_2
+ st8 [rp] = s0, 8
+ (p8) cmp.leu p6, p7 = acc0, pr0_1
+.mmi; (p9) cmp.ltu p6, p7 = acc0, pr0_1
+ (p12) cmp.leu p10, p11 = s0, pr1_0
+ (p13) cmp.ltu p10, p11 = s0, pr1_0
+ ;;
+ .pred.rel "mutex", p6, p7
+.mmi; getfsig r8 = fp2a_2
+ (p6) add acc0 = pr0_2, acc1_0, 1
+ (p7) add acc0 = pr0_2, acc1_0
+ ;;
+ .pred.rel "mutex", p10, p11
+.mmi; (p10) add s0 = pr1_1, acc0, 1
+ (p11) add s0 = pr1_1, acc0
+ (p6) cmp.leu p8, p9 = acc0, pr0_2
+ ;;
+ .pred.rel "mutex", p10, p11
+.mmi; (p7) cmp.ltu p8, p9 = acc0, pr0_2
+ (p10) cmp.leu p12, p13 = s0, pr1_1
+ (p11) cmp.ltu p12, p13 = s0, pr1_1
+ ;;
+ .pred.rel "mutex", p8, p9
+.mmi; st8 [rp] = s0, 8
+ (p8) add acc0 = pr1_2, acc1_1, 1
+ (p9) add acc0 = pr1_2, acc1_1
+ ;;
+ .pred.rel "mutex", p8, p9
+.mmi; (p8) cmp.leu p10, p11 = acc0, pr1_2
+ (p9) cmp.ltu p10, p11 = acc0, pr1_2
+ (p12) add acc0 = 1, acc0
+ ;;
+.mmi; st8 [rp] = acc0, 8
+ (p12) cmpeqor p10, p0 = 0, acc0
+ nop 1
+ ;;
+.mib; (p10) add r8 = 1, r8
+ mov ar.lc = r2
+ br.ret.sptk.many b0
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/popcount.asm b/gmp/mpn/ia64/popcount.asm
new file mode 100644
index 0000000000..c0b5c5c1cf
--- /dev/null
+++ b/gmp/mpn/ia64/popcount.asm
@@ -0,0 +1,200 @@
+dnl IA-64 mpn_popcount -- mpn population count.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2000-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 1.5
+C Itanium 2: 1
+
+C INPUT PARAMETERS
+define(`up', `r32')
+define(`n', `r33')
+
+define(`u0',`r16') define(`u1',`r17') define(`u2',`r18') define(`u3',`r19')
+define(`c0',`r28') define(`c1',`r29') define(`c2',`r30') define(`c3',`r31')
+define(`s',`r8')
+
+
+ASM_START()
+PROLOGUE(mpn_popcount)
+ .prologue
+ifdef(`HAVE_ABI_32',
+` addp4 up = 0, up C M I
+ nop.m 0
+ zxt4 n = n C I
+ ;;
+')
+
+ {.mmi; add r9 = 512, up C prefetch pointer M I
+ ld8 r10 = [up], 8 C load first limb M01
+ mov.i r2 = ar.lc C save ar.lc I0
+}{.mmi; and r14 = 3, n C M I
+ cmp.lt p15, p14 = 4, n C small count? M I
+ add n = -5, n C M I
+ ;;
+}{.mmi; cmp.eq p6, p0 = 1, r14 C M I
+ cmp.eq p7, p0 = 2, r14 C M I
+ cmp.eq p8, p0 = 3, r14 C M I
+}{.bbb
+ (p6) br.dptk .Lb01 C B
+ (p7) br.dptk .Lb10 C B
+ (p8) br.dptk .Lb11 C B
+}
+
+
+.Lb00: ld8 u1 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ mov s = 0 C M I
+ ;;
+ ld8 u2 = [up], 8 C M01
+ popcnt c0 = r10 C I0
+ mov.i ar.lc = n C I0
+ ;;
+ ld8 u3 = [up], 8 C M01
+ popcnt c1 = u1 C I0
+ (p15) br.cond.dptk .grt4 C B
+ ;;
+ nop.m 0 C -
+ nop.m 0 C -
+ popcnt c2 = u2 C I0
+ ;;
+ mov s = c0 C M I
+ popcnt c3 = u3 C I0
+ br .Lcj4 C B
+
+.grt4: ld8 u0 = [up], 8 C M01
+ popcnt c2 = u2 C I0
+ br .LL00 C B
+
+
+.Lb01:
+ popcnt s = r10 C I0
+ (p14) br.ret.sptk.many b0 C B
+
+.grt1: ld8 u0 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ ;;
+ ld8 u1 = [up], 8 C M01
+ mov.i ar.lc = n C I0
+ ;;
+ ld8 u2 = [up], 8 C M01
+ popcnt c0 = u0 C I0
+ mov c3 = 0 C I0
+
+ ;;
+ ld8 u3 = [up], 8 C M01
+ popcnt c1 = u1 C I0
+ br.cloop.dptk .Loop C B
+ br .Lend C B
+
+
+.Lb10: ld8 u3 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ (p15) br.cond.dptk .grt2 C B
+
+ popcnt s = r10 C I0
+ ;;
+ popcnt c3 = u3 C I0
+ br .Lcj2 C B
+
+.grt2: ld8 u0 = [up], 8 C M01
+ mov.i ar.lc = n C I0
+ popcnt c2 = r10 C I0
+ ;;
+ ld8 u1 = [up], 8 C M01
+ popcnt c3 = u3 C I0
+ mov s = 0 C M I
+ ;;
+ ld8 u2 = [up], 8 C M01
+ popcnt c0 = u0 C I0
+ br .LL10 C B
+
+
+.Lb11: ld8 u2 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ mov s = 0 C M I
+ ;;
+ ld8 u3 = [up], 8 C M01
+ popcnt s = r10 C I0
+ (p15) br.cond.dptk .grt3 C B
+
+ popcnt c2 = u2 C I0
+ ;;
+ popcnt c3 = u3 C I0
+ br .Lcj3 C B
+
+.grt3: ld8 u0 = [up], 8 C M01
+ popcnt c2 = u2 C I0
+ mov.i ar.lc = n C I0
+ mov c1 = 0
+ ;;
+ ld8 u1 = [up], 8 C M01
+ popcnt c3 = u3 C I0
+ br .LL11 C B
+
+
+.Loop: ld8 u0 = [up], 8 C M01
+ popcnt c2 = u2 C I0
+ add s = s, c3 C M I
+ ;;
+.LL00: ld8 u1 = [up], 8 C M01
+ popcnt c3 = u3 C I0
+ add s = s, c0 C M I
+ ;;
+.LL11: ld8 u2 = [up], 8 C M01
+ popcnt c0 = u0 C I0
+ add s = s, c1 C M I
+ ;;
+.LL10: ld8 u3 = [up], 8 C M01
+ popcnt c1 = u1 C I0
+ add s = s, c2 C M I
+ lfetch [r9], 32 C M01
+ nop.m 0 C -
+ br.cloop.dptk .Loop C B
+ ;;
+
+.Lend: popcnt c2 = u2 C I0
+ add s = s, c3 C M I
+ ;;
+ popcnt c3 = u3 C I0
+ add s = s, c0 C M I
+ ;;
+.Lcj4: add s = s, c1 C M I
+ ;;
+.Lcj3: add s = s, c2 C M I
+ ;;
+.Lcj2: add s = s, c3 C M I
+ mov.i ar.lc = r2 C I0
+ br.ret.sptk.many b0 C B
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/ia64/rsh1aors_n.asm b/gmp/mpn/ia64/rsh1aors_n.asm
new file mode 100644
index 0000000000..3c7defb0ba
--- /dev/null
+++ b/gmp/mpn/ia64/rsh1aors_n.asm
@@ -0,0 +1,447 @@
+dnl IA-64 mpn_rsh1add_n/mpn_rsh1sub_n -- rp[] = (up[] +- vp[]) >> 1.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2003-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 2.5
+C Itanium 2: 1.5
+
+C TODO
+C * Rewrite function entry code using aorslsh1_n.asm style.
+C * Micro-optimize feed-in and wind-down code.
+
+C INPUT PARAMETERS
+define(`rp',`r32')
+define(`up',`r33')
+define(`vp',`r34')
+define(`n',`r35')
+
+ifdef(`OPERATION_rsh1add_n',`
+ define(ADDSUB, add)
+ define(PRED, ltu)
+ define(INCR, 1)
+ define(LIM, -1)
+ define(func, mpn_rsh1add_n)
+')
+ifdef(`OPERATION_rsh1sub_n',`
+ define(ADDSUB, sub)
+ define(PRED, gtu)
+ define(INCR, -1)
+ define(LIM, 0)
+ define(func, mpn_rsh1sub_n)
+')
+
+C Some useful aliases for registers we use
+define(`u0',`r14') define(`u1',`r15') define(`u2',`r16') define(`u3',`r17')
+define(`v0',`r18') define(`v1',`r19') define(`v2',`r20') define(`v3',`r21')
+define(`w0',`r22') define(`w1',`r23') define(`w2',`r24') define(`w3',`r25')
+define(`x0',`r26') define(`x1',`r9') define(`x2',`r30') define(`x3',`r31')
+
+MULFUNC_PROLOGUE(mpn_rsh1add_n mpn_rsh1sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',`
+ addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ addp4 vp = 0, vp C M I
+ nop.m 0
+ nop.m 0
+ zxt4 n = n C I
+ ;;
+')
+ {.mmi; ld8 r11 = [vp], 8 C M01
+ ld8 r10 = [up], 8 C M01
+ mov.i r2 = ar.lc C I0
+}{.mmi; and r14 = 3, n C M I
+ cmp.lt p15, p0 = 4, n C M I
+ add n = -4, n C M I
+ ;;
+}{.mmi; cmp.eq p6, p0 = 1, r14 C M I
+ cmp.eq p7, p0 = 2, r14 C M I
+ cmp.eq p8, p0 = 3, r14 C M I
+}{.bbb
+ (p6) br.dptk .Lb01 C B
+ (p7) br.dptk .Lb10 C B
+ (p8) br.dptk .Lb11 C B
+}
+
+.Lb00: ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ ;;
+ ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ ADDSUB w3 = r10, r11 C M I
+ ;;
+ ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ (p15) br.dpnt .grt4 C B
+ ;;
+
+ cmp.PRED p7, p0 = w3, r10 C M I
+ and r8 = 1, w3 C M I
+ ADDSUB w0 = u0, v0 C M I
+ ;;
+ cmp.PRED p8, p0 = w0, u0 C M I
+ ADDSUB w1 = u1, v1 C M I
+ ;;
+ cmp.PRED p9, p0 = w1, u1 C M I
+ (p7) cmp.eq.or p8, p0 = LIM, w0 C M I
+ (p7) add w0 = INCR, w0 C M I
+ ;;
+ shrp x3 = w0, w3, 1 C I0
+ ADDSUB w2 = u2, v2 C M I
+ (p8) cmp.eq.or p9, p0 = LIM, w1 C M I
+ (p8) add w1 = INCR, w1 C M I
+ br .Lcj4 C B
+
+.grt4: ld8 v3 = [vp], 8 C M01
+ cmp.PRED p7, p0 = w3, r10 C M I
+ ld8 u3 = [up], 8 C M01
+ and r8 = 1, w3 C M I
+ ;;
+ ADDSUB w0 = u0, v0 C M I
+ ld8 v0 = [vp], 8 C M01
+ add n = -1, n
+ ;;
+ cmp.PRED p8, p0 = w0, u0 C M I
+ ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = u1, v1 C M I
+ ;;
+ ld8 v1 = [vp], 8 C M01
+ mov.i ar.lc = n C I0
+ cmp.PRED p9, p0 = w1, u1 C M I
+ ld8 u1 = [up], 8 C M01
+ (p7) cmp.eq.or p8, p0 = LIM, w0 C M I
+ (p7) add w0 = INCR, w0 C M I
+ ;;
+ ADDSUB w2 = u2, v2 C M I
+ ld8 v2 = [vp], 8 C M01
+ shrp x3 = w0, w3, 1 C I0
+ (p8) cmp.eq.or p9, p0 = LIM, w1 C M I
+ (p8) add w1 = INCR, w1 C M I
+ br .LL00 C B
+
+
+.Lb01: ADDSUB w2 = r10, r11 C M I
+ shr.u n = n, 2 C I0
+ (p15) br.dpnt .grt1 C B
+ ;;
+
+ cmp.PRED p6, p7 = w2, r10 C M I
+ shr.u x2 = w2, 1 C I0
+ and r8 = 1, w2 C M I
+ ;;
+ (p6) dep x2 = -1, x2, 63, 1 C I0
+ br .Lcj1 C B
+
+.grt1: ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ ;;
+ ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ mov.i ar.lc = n C FIXME swap with next I0
+ ;;
+ ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ ;;
+ ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ cmp.PRED p6, p0 = w2, r10 C M I
+ and r8 = 1, w2 C M I
+ ADDSUB w3 = u3, v3 C M I
+ br.cloop.dptk .grt5 C B
+ ;;
+
+ cmp.PRED p7, p0 = w3, u3 C M I
+ ;;
+ ADDSUB w0 = u0, v0 C M I
+ (p6) cmp.eq.or p7, p0 = LIM, w3 C M I
+ (p6) add w3 = INCR, w3 C M I
+ ;;
+ cmp.PRED p8, p0 = w0, u0 C M I
+ shrp x2 = w3, w2, 1 C I0
+ ADDSUB w1 = u1, v1 C M I
+ ;;
+ cmp.PRED p9, p0 = w1, u1 C M I
+ (p7) cmp.eq.or p8, p0 = LIM, w0 C M I
+ (p7) add w0 = INCR, w0 C M I
+ br .Lcj5 C B
+
+.grt5: ld8 v3 = [vp], 8 C M01
+ cmp.PRED p7, p0 = w3, u3 C M I
+ ld8 u3 = [up], 8 C M01
+ ;;
+ ADDSUB w0 = u0, v0 C M I
+ ld8 v0 = [vp], 8 C M01
+ (p6) cmp.eq.or p7, p0 = LIM, w3 C M I
+ (p6) add w3 = INCR, w3 C M I
+ ;;
+ cmp.PRED p8, p0 = w0, u0 C M I
+ shrp x2 = w3, w2, 1 C I0
+ ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = u1, v1 C M I
+ ;;
+ ld8 v1 = [vp], 8 C M01
+ cmp.PRED p9, p0 = w1, u1 C M I
+ ld8 u1 = [up], 8 C M01
+ (p7) cmp.eq.or p8, p0 = LIM, w0 C M I
+ (p7) add w0 = INCR, w0 C M I
+ br .LL01 C B
+
+
+.Lb10: ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ ADDSUB w1 = r10, r11 C M I
+ (p15) br.dpnt .grt2 C B
+ ;;
+
+ cmp.PRED p9, p0 = w1, r10 C M I
+ and r8 = 1, w1 C M I
+ ADDSUB w2 = u2, v2 C M I
+ ;;
+ cmp.PRED p6, p0 = w2, u2 C M I
+ ;;
+ (p9) cmp.eq.or p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ ;;
+ shrp x1 = w2, w1, 1 C I0
+ shr.u x2 = w2, 1 C I0
+ br .Lcj2 C B
+
+.grt2: ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ ;;
+ ld8 v0 = [vp], 8 C M01
+ ld8 u0 = [up], 8 C M01
+ mov.i ar.lc = n C I0
+ ;;
+ ld8 v1 = [vp], 8 C M01
+ cmp.PRED p9, p0 = w1, r10 C M I
+ ld8 u1 = [up], 8 C M01
+ and r8 = 1, w1 C M I
+ ;;
+ ADDSUB w2 = u2, v2 C M I
+ ld8 v2 = [vp], 8 C M01
+ ;;
+ cmp.PRED p6, p0 = w2, u2 C M I
+ ld8 u2 = [up], 8 C M01
+ ADDSUB w3 = u3, v3 C M I
+ br.cloop.dptk .grt6 C B
+ ;;
+
+ cmp.PRED p7, p0 = w3, u3 C M I
+ (p9) cmp.eq.or p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ ;;
+ shrp x1 = w2, w1, 1 C I0
+ ADDSUB w0 = u0, v0 C M I
+ (p6) cmp.eq.or p7, p0 = LIM, w3 C M I
+ (p6) add w3 = INCR, w3 C M I
+ br .Lcj6 C B
+
+.grt6: ld8 v3 = [vp], 8 C M01
+ cmp.PRED p7, p0 = w3, u3 C M I
+ ld8 u3 = [up], 8 C M01
+ (p9) cmp.eq.or p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ ;;
+ shrp x1 = w2, w1, 1 C I0
+ ADDSUB w0 = u0, v0 C M I
+ ld8 v0 = [vp], 8 C M01
+ (p6) cmp.eq.or p7, p0 = LIM, w3 C M I
+ (p6) add w3 = INCR, w3 C M I
+ br .LL10 C B
+
+
+.Lb11: ld8 v1 = [vp], 8 C M01
+ ld8 u1 = [up], 8 C M01
+ shr.u n = n, 2 C I0
+ ;;
+ ld8 v2 = [vp], 8 C M01
+ ld8 u2 = [up], 8 C M01
+ ADDSUB w0 = r10, r11 C M I
+ (p15) br.dpnt .grt3 C B
+ ;;
+
+ cmp.PRED p8, p0 = w0, r10 C M I
+ ADDSUB w1 = u1, v1 C M I
+ and r8 = 1, w0 C M I
+ ;;
+ cmp.PRED p9, p0 = w1, u1 C M I
+ ;;
+ ADDSUB w2 = u2, v2 C M I
+ (p8) cmp.eq.or p9, p0 = LIM, w1 C M I
+ (p8) add w1 = INCR, w1 C M I
+ ;;
+ cmp.PRED p6, p0 = w2, u2 C M I
+ shrp x0 = w1, w0, 1 C I0
+ ;;
+ (p9) cmp.eq.or p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ br .Lcj3 C B
+
+.grt3: ld8 v3 = [vp], 8 C M01
+ ld8 u3 = [up], 8 C M01
+ ;;
+ ld8 v0 = [vp], 8 C M01
+ mov.i ar.lc = n C I0
+ cmp.PRED p8, p0 = w0, r10 C M I
+ ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = u1, v1 C M I
+ and r8 = 1, w0 C M I
+ ;;
+ ld8 v1 = [vp], 8 C M01
+ cmp.PRED p9, p0 = w1, u1 C M I
+ ld8 u1 = [up], 8 C M01
+ ;;
+ ADDSUB w2 = u2, v2 C M I
+ ld8 v2 = [vp], 8 C M01
+ (p8) cmp.eq.or p9, p0 = LIM, w1 C M I
+ (p8) add w1 = INCR, w1 C M I
+ ;;
+ cmp.PRED p6, p0 = w2, u2 C M I
+ shrp x0 = w1, w0, 1 C I0
+ ld8 u2 = [up], 8 C M01
+ ADDSUB w3 = u3, v3 C M I
+ br.cloop.dptk .grt7 C B
+ ;;
+
+ cmp.PRED p7, p0 = w3, u3 C M I
+ (p9) cmp.eq.or p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ br .Lcj7 C B
+
+.grt7: ld8 v3 = [vp], 8 C M01
+ cmp.PRED p7, p0 = w3, u3 C M I
+ ld8 u3 = [up], 8 C M01
+ (p9) cmp.eq.or p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ br .LL11 C B
+
+
+C *** MAIN LOOP START ***
+ ALIGN(32)
+.Loop: st8 [rp] = x3, 8 C M23
+ ld8 v3 = [vp], 8 C M01
+ cmp.PRED p7, p0 = w3, u3 C M I
+ ld8 u3 = [up], 8 C M01
+ (p9) cmp.eq.or p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ ;;
+.LL11: st8 [rp] = x0, 8 C M23
+ shrp x1 = w2, w1, 1 C I0
+ ADDSUB w0 = u0, v0 C M I
+ ld8 v0 = [vp], 8 C M01
+ (p6) cmp.eq.or p7, p0 = LIM, w3 C M I
+ (p6) add w3 = INCR, w3 C M I
+ ;;
+.LL10: cmp.PRED p8, p0 = w0, u0 C M I
+ shrp x2 = w3, w2, 1 C I0
+ nop.b 0
+ ld8 u0 = [up], 8 C M01
+ ADDSUB w1 = u1, v1 C M I
+ nop.b 0
+ ;;
+ st8 [rp] = x1, 8 C M23
+ ld8 v1 = [vp], 8 C M01
+ cmp.PRED p9, p0 = w1, u1 C M I
+ ld8 u1 = [up], 8 C M01
+ (p7) cmp.eq.or p8, p0 = LIM, w0 C M I
+ (p7) add w0 = INCR, w0 C M I
+ ;;
+.LL01: st8 [rp] = x2, 8 C M23
+ shrp x3 = w0, w3, 1 C I0
+ ADDSUB w2 = u2, v2 C M I
+ ld8 v2 = [vp], 8 C M01
+ (p8) cmp.eq.or p9, p0 = LIM, w1 C M I
+ (p8) add w1 = INCR, w1 C M I
+ ;;
+.LL00: cmp.PRED p6, p0 = w2, u2 C M I
+ shrp x0 = w1, w0, 1 C I0
+ nop.b 0
+ ld8 u2 = [up], 8 C M01
+ ADDSUB w3 = u3, v3 C M I
+ br.cloop.dptk .Loop C B
+ ;;
+C *** MAIN LOOP END ***
+
+.Lskip: st8 [rp] = x3, 8 C M23
+ cmp.PRED p7, p0 = w3, u3 C M I
+ (p9) cmp.eq.or p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ ;;
+.Lcj7: st8 [rp] = x0, 8 C M23
+ shrp x1 = w2, w1, 1 C I0
+ ADDSUB w0 = u0, v0 C M I
+ (p6) cmp.eq.or p7, p0 = LIM, w3 C M I
+ (p6) add w3 = INCR, w3 C M I
+ ;;
+.Lcj6: cmp.PRED p8, p0 = w0, u0 C M I
+ shrp x2 = w3, w2, 1 C I0
+ ADDSUB w1 = u1, v1 C M I
+ ;;
+ st8 [rp] = x1, 8 C M23
+ cmp.PRED p9, p0 = w1, u1 C M I
+ (p7) cmp.eq.or p8, p0 = LIM, w0 C M I
+ (p7) add w0 = INCR, w0 C M I
+ ;;
+.Lcj5: st8 [rp] = x2, 8 C M23
+ shrp x3 = w0, w3, 1 C I0
+ ADDSUB w2 = u2, v2 C M I
+ (p8) cmp.eq.or p9, p0 = LIM, w1 C M I
+ (p8) add w1 = INCR, w1 C M I
+ ;;
+.Lcj4: cmp.PRED p6, p0 = w2, u2 C M I
+ shrp x0 = w1, w0, 1 C I0
+ ;;
+ st8 [rp] = x3, 8 C M23
+ (p9) cmp.eq.or p6, p0 = LIM, w2 C M I
+ (p9) add w2 = INCR, w2 C M I
+ ;;
+.Lcj3: st8 [rp] = x0, 8 C M23
+ shrp x1 = w2, w1, 1 C I0
+ shr.u x2 = w2, 1 C I0
+ ;;
+.Lcj2: st8 [rp] = x1, 8 C M23
+ (p6) dep x2 = -1, x2, 63, 1 C I0
+ ;;
+.Lcj1: st8 [rp] = x2 C M23
+ mov.i ar.lc = r2 C I0
+ br.ret.sptk.many b0 C B
+EPILOGUE()
diff --git a/gmp/mpn/ia64/sec_tabselect.asm b/gmp/mpn/ia64/sec_tabselect.asm
new file mode 100644
index 0000000000..f116ea3843
--- /dev/null
+++ b/gmp/mpn/ia64/sec_tabselect.asm
@@ -0,0 +1,150 @@
+dnl IA-64 mpn_sec_tabselect.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: ?
+C Itanium 2: 2.5
+
+C NOTES
+C * Using software pipelining could trivially yield 2 c/l without unrolling,
+C or 1+epsilon with unrolling. (This code was modelled after the powerpc64
+C code, for simplicity.)
+
+C mpn_sec_tabselect (mp_limb_t *rp, mp_limb_t *tp, mp_size_t n, mp_size_t nents, mp_size_t which)
+define(`rp', `r32')
+define(`tp', `r33')
+define(`n', `r34')
+define(`nents', `r35')
+define(`which', `r36')
+
+define(`mask', `r8')
+
+define(`rp1', `r32')
+define(`tp1', `r33')
+define(`rp2', `r14')
+define(`tp2', `r15')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sec_tabselect)
+ .prologue
+ .save ar.lc, r2
+ .body
+ifdef(`HAVE_ABI_32',`
+.mmi; addp4 rp = 0, rp C M I
+ addp4 tp = 0, tp C M I
+ zxt4 n = n C I
+.mii; nop 0
+ zxt4 nents = nents C I
+ zxt4 which = which C I
+ ;;
+')
+.mmi; add rp2 = 8, rp1
+ add tp2 = 8, tp1
+ add r6 = -2, n
+ ;;
+.mmi; cmp.eq p10, p0 = 1, n
+ and r9 = 1, n C set cr0 for use in inner loop
+ shr.u r6 = r6, 1 C inner loop count
+ ;;
+.mmi; cmp.eq p8, p0 = 0, r9
+ sub which = nents, which
+ shl n = n, 3
+ ;;
+
+L(outer):
+.mmi cmp.eq p6, p7 = which, nents C are we at the selected table entry?
+ nop 0
+ mov ar.lc = r6 C I0
+ ;;
+.mmb;
+ (p6) mov mask = -1
+ (p7) mov mask = 0
+ (p8) br.dptk L(top) C branch to loop entry if n even
+ ;;
+
+.mmi; ld8 r16 = [tp1], 8
+ add tp2 = 8, tp2
+ nop 0
+ ;;
+.mmi; ld8 r18 = [rp1]
+ and r16 = r16, mask
+ nop 0
+ ;;
+.mmi; andcm r18 = r18, mask
+ ;;
+ or r16 = r16, r18
+ nop 0
+ ;;
+.mmb; st8 [rp1] = r16, 8
+ add rp2 = 8, rp2
+ (p10) br.dpnt L(end)
+
+ ALIGN(32)
+L(top):
+.mmi; ld8 r16 = [tp1], 16
+ ld8 r17 = [tp2], 16
+ nop 0
+ ;;
+.mmi; ld8 r18 = [rp1]
+ and r16 = r16, mask
+ nop 0
+.mmi; ld8 r19 = [rp2]
+ and r17 = r17, mask
+ nop 0
+ ;;
+.mmi; andcm r18 = r18, mask
+ andcm r19 = r19, mask
+ nop 0
+ ;;
+.mmi; or r16 = r16, r18
+ or r17 = r17, r19
+ nop 0
+ ;;
+.mmb; st8 [rp1] = r16, 16
+ st8 [rp2] = r17, 16
+ br.cloop.dptk L(top)
+ ;;
+L(end):
+.mmi; sub rp1 = rp1, n C move rp back to beginning
+ sub rp2 = rp2, n C move rp back to beginning
+ cmp.ne p9, p0 = 1, nents
+.mmb; add nents = -1, nents
+ nop 0
+ (p9) br.dptk L(outer)
+ ;;
+
+.mib; nop 0
+ nop 0
+ br.ret.sptk.many b0
+EPILOGUE()
diff --git a/gmp/mpn/ia64/sqr_diag_addlsh1.asm b/gmp/mpn/ia64/sqr_diag_addlsh1.asm
new file mode 100644
index 0000000000..f9288298b3
--- /dev/null
+++ b/gmp/mpn/ia64/sqr_diag_addlsh1.asm
@@ -0,0 +1,144 @@
+dnl IA-64 mpn_sqr_diag_addlsh1
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2010, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: ?
+C Itanium 2: 2 Unrolling could bring it to 1.5 + epsilon
+
+C Exact performance table. The 2nd line is this code, the 3rd line is ctop-
+C less code. In an assembly sqr_basecase, the ctop-full numbers will become a
+C few cycles better since we can mitigate the many I0 instructions.
+C
+C 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+C - 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 Needs updating
+C - 13 16 17 18 20 21 23 25 26 30 31 31 33 34 36 38 39 42 43
+
+C We should keep in mind that this code takes linear time in a O(n^2) context
+C and that it will only be used under SQR_TOOM2_THRESHOLD, which might become
+C around 60. Keeping overhead down for smallish operands (< 10) is more
+C important than optimal cycle counts.
+
+C TODO
+C * Make sure we don't depend on uninitialised r-registers, f-registers, or
+C * p-registers.
+C * Optimise by doing first two loop iterations in function header.
+
+C INPUT PARAMETERS
+define(`rp_param', `r32') define(`rp', `r14') C size: 2n
+define(`tp_param', `r33') define(`tp', `r15') C size: 2n - 2
+define(`up_param', `r34') define(`up', `r31') C size: n
+define(`n', `r35')
+
+
+ASM_START()
+PROLOGUE(mpn_sqr_diag_addlsh1)
+
+ .prologue
+ .save ar.pfs, r2
+ .save ar.lc, r3
+ .body
+
+.mmi; alloc r2 = ar.pfs, 4,24,0,24 C M
+ nop 4711
+ mov r3 = ar.lc C I0
+.mmi; mov tp = tp_param C M I
+ mov up = up_param C M I
+ mov rp = rp_param C M I
+ ;;
+.mmi; ld8 r36 = [tp], 8 C M
+ add r20 = -2, n C M I
+ mov r9 = ar.ec C I0
+ ;;
+.mmi; ld8 r32 = [tp], 8 C M
+ mov r16 = 0 C M I
+ mov ar.ec = 7 C I0
+ ;;
+.mmi; nop 4711
+ mov r44 = 0 C M I
+ mov ar.lc = r20 C I0
+ ;;
+.mii; mov r33 = 0
+ mov r10 = pr C I0
+ mov pr.rot = 0x30000 C I0
+ ;;
+ br.cexit.spnt.few.clr L(end)
+
+dnl *** MAIN LOOP START ***
+ ALIGN(32)
+L(top):
+.mfi; (p18) ldf8 f33 = [up], 8 C M
+ (p20) xma.l f36 = f35, f35, f42 C F
+ (p41) cmpequc p50, p0 = -1, r44 C M I
+.mfi; setfsig f40 = r16 C M23
+ (p20) xma.hu f38 = f35, f35, f42 C F
+ (p23) add r50 = r41, r49 C M I
+ ;;
+.mmi; (p16) ld8 r36 = [tp], 8 C M
+ (p23) cmpltu p40, p0 = r50, r41 C cyout hi M I
+ (p19) shrp r45 = r38, r35, 63 C non-critical I0
+.mmi; (p21) getfsig r39 = f39 C hi M2
+ (p24) st8 [rp] = r51, 8 C hi M23
+ (p41) add r44 = 1, r44 C M I
+ ;;
+.mmi; (p16) ld8 r32 = [tp], 8 C M
+ (p50) cmpeqor p40, p0 = -1, r50 C cyout hi M I
+ (p17) shrp r16 = r33, r37, 63 C critical I0
+.mmi; (p21) getfsig r42 = f37 C lo M2
+ (p23) st8 [rp] = r44, 8 C lo M23
+ (p50) add r50 = 1, r50 C M I
+ ;;
+ br.ctop.sptk.few.clr L(top) C B
+dnl *** MAIN LOOP END ***
+ ;;
+L(end):
+.mmi; nop 4711
+ (p41) add r44 = 1, r44 C M I
+ shr.u r48 = r39, 63 C I0
+ ;;
+.mmi; st8 [rp] = r51, 8 C M23
+ (p41) cmpequc p6, p0 = 0, r44 C M I
+ add r50 = r41, r48 C M I
+ ;;
+.mmi; st8 [rp] = r44, 8 C M23
+ (p6) add r50 = 1, r50 C M I
+ mov ar.lc = r3 C I0
+ ;;
+.mii; st8 [rp] = r50 C M23
+ mov ar.ec = r9 C I0
+ mov pr = r10 C I0
+ ;;
+.mib; nop 4711
+ mov ar.pfs = r2 C I0
+ br.ret.sptk.many b0 C B
+EPILOGUE()
diff --git a/gmp/mpn/ia64/submul_1.asm b/gmp/mpn/ia64/submul_1.asm
new file mode 100644
index 0000000000..cb2a5525b5
--- /dev/null
+++ b/gmp/mpn/ia64/submul_1.asm
@@ -0,0 +1,647 @@
+dnl IA-64 mpn_submul_1 -- Multiply a limb vector with a limb and subtract the
+dnl result from a second limb vector.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2000-2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C Itanium: 4.0
+C Itanium 2: 2.25 (alignment dependent, sometimes it seems to need 3 c/l)
+
+C TODO
+C * Optimize feed-in and wind-down code, both for speed and code size.
+C * Handle low limb input and results specially, using a common stf8 in the
+C epilogue.
+C * Delay r8, r10 initialization, put cmp-p6 in 1st bundle and br .Ldone in
+C 2nd bundle. This will allow the bbb bundle to be one cycle earlier and
+C save a cycle.
+
+C INPUT PARAMETERS
+define(`rp', `r32')
+define(`up', `r33')
+define(`n', `r34')
+define(`vl', `r35')
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ .prologue
+ .save ar.lc, r2
+ .body
+
+ifdef(`HAVE_ABI_32',
+` addp4 rp = 0, rp C M I
+ addp4 up = 0, up C M I
+ zxt4 n = n C I
+ ;;
+')
+{.mmi
+ mov r10 = rp C M I
+ mov r9 = up C M I
+ sub vl = r0, vl C M I negate vl
+}
+{.mmi
+ ldf8 f8 = [rp], 8 C M
+ ldf8 f7 = [up], 8 C M
+ add r19 = -1, n C M I n - 1
+ ;;
+}
+{.mmi
+ cmp.eq p6, p0 = 0, vl C M I
+ mov r8 = 0 C M I zero cylimb
+ mov r2 = ar.lc C I0
+}
+{.mmi
+ setf.sig f6 = vl C M2 M3
+ and r14 = 3, n C M I
+ shr.u r19 = r19, 2 C I0
+ ;;
+}
+{.mmb
+ nop 0
+ cmp.eq p10, p0 = 0, r14 C M I
+ (p6) br.spnt .Ldone C B vl == 0
+}
+{.mmi
+ cmp.eq p11, p0 = 2, r14 C M I
+ cmp.eq p12, p0 = 3, r14 C M I
+ mov ar.lc = r19 C I0
+}
+{.bbb
+ (p10) br.dptk .Lb00 C B
+ (p11) br.dptk .Lb10 C B
+ (p12) br.dptk .Lb11 C B
+ ;;
+}
+
+.Lb01: br.cloop.dptk .grt1
+
+ xma.l f39 = f7, f6, f8
+ xma.hu f43 = f7, f6, f8
+ ;;
+ getf.sig r27 = f39 C lo
+ getf.sig r31 = f43 C hi
+ ld8 r20 = [r9], 8
+ br .Lcj1
+
+.grt1: ldf8 f44 = [rp], 8
+ ldf8 f32 = [up], 8
+ ;;
+ ldf8 f45 = [rp], 8
+ ldf8 f33 = [up], 8
+ ;;
+ ldf8 f46 = [rp], 8
+ xma.l f39 = f7, f6, f8
+ ldf8 f34 = [up], 8
+ xma.hu f43 = f7, f6, f8
+ ;;
+ ldf8 f47 = [rp], 8
+ xma.l f36 = f32, f6, f44
+ ldf8 f35 = [up], 8
+ xma.hu f40 = f32, f6, f44
+ br.cloop.dptk .grt5
+ ;;
+
+ getf.sig r27 = f39 C lo
+ xma.l f37 = f33, f6, f45
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ getf.sig r31 = f43 C hi
+ getf.sig r24 = f36 C lo
+ xma.l f38 = f34, f6, f46
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ getf.sig r28 = f40 C hi
+ getf.sig r25 = f37 C lo
+ xma.l f39 = f35, f6, f47
+ ld8 r22 = [r9], 8
+ xma.hu f43 = f35, f6, f47
+ ;;
+ getf.sig r29 = f41 C hi
+ getf.sig r26 = f38 C lo
+ ld8 r23 = [r9], 8
+ br .Lcj5
+
+.grt5: ldf8 f44 = [rp], 8
+ ldf8 f32 = [up], 8
+ ;;
+ getf.sig r27 = f39 C lo
+ xma.l f37 = f33, f6, f45
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ ldf8 f45 = [rp], 8
+ getf.sig r31 = f43 C hi
+ ldf8 f33 = [up], 8
+ ;;
+ getf.sig r24 = f36 C lo
+ xma.l f38 = f34, f6, f46
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ ldf8 f46 = [rp], 8
+ getf.sig r28 = f40 C hi
+ ldf8 f34 = [up], 8
+ ;;
+ getf.sig r25 = f37 C lo
+ xma.l f39 = f35, f6, f47
+ ld8 r22 = [r9], 8
+ xma.hu f43 = f35, f6, f47
+ ;;
+ ldf8 f47 = [rp], 8
+ getf.sig r29 = f41 C hi
+ ldf8 f35 = [up], 8
+ ;;
+ getf.sig r26 = f38 C lo
+ xma.l f36 = f32, f6, f44
+ ld8 r23 = [r9], 8
+ xma.hu f40 = f32, f6, f44
+ br.cloop.dptk .Loop
+ br .Lend
+
+
+.Lb10: ldf8 f47 = [rp], 8
+ ldf8 f35 = [up], 8
+ br.cloop.dptk .grt2
+
+ xma.l f38 = f7, f6, f8
+ xma.hu f42 = f7, f6, f8
+ ;;
+ xma.l f39 = f35, f6, f47
+ xma.hu f43 = f35, f6, f47
+ ;;
+ getf.sig r26 = f38 C lo
+ getf.sig r30 = f42 C hi
+ ld8 r23 = [r9], 8
+ ;;
+ getf.sig r27 = f39 C lo
+ getf.sig r31 = f43 C hi
+ ld8 r20 = [r9], 8
+ br .Lcj2
+
+.grt2: ldf8 f44 = [rp], 8
+ ldf8 f32 = [up], 8
+ ;;
+ ldf8 f45 = [rp], 8
+ ldf8 f33 = [up], 8
+ xma.l f38 = f7, f6, f8
+ xma.hu f42 = f7, f6, f8
+ ;;
+ ldf8 f46 = [rp], 8
+ ldf8 f34 = [up], 8
+ xma.l f39 = f35, f6, f47
+ xma.hu f43 = f35, f6, f47
+ ;;
+ ldf8 f47 = [rp], 8
+ ldf8 f35 = [up], 8
+ ;;
+ getf.sig r26 = f38 C lo
+ xma.l f36 = f32, f6, f44
+ ld8 r23 = [r9], 8
+ xma.hu f40 = f32, f6, f44
+ br.cloop.dptk .grt6
+
+ getf.sig r30 = f42 C hi
+ ;;
+ getf.sig r27 = f39 C lo
+ xma.l f37 = f33, f6, f45
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ getf.sig r31 = f43 C hi
+ getf.sig r24 = f36 C lo
+ xma.l f38 = f34, f6, f46
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ getf.sig r28 = f40 C hi
+ getf.sig r25 = f37 C lo
+ xma.l f39 = f35, f6, f47
+ ld8 r22 = [r9], 8
+ xma.hu f43 = f35, f6, f47
+ br .Lcj6
+
+.grt6: ldf8 f44 = [rp], 8
+ getf.sig r30 = f42 C hi
+ ldf8 f32 = [up], 8
+ ;;
+ getf.sig r27 = f39 C lo
+ xma.l f37 = f33, f6, f45
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ ldf8 f45 = [rp], 8
+ getf.sig r31 = f43 C hi
+ ldf8 f33 = [up], 8
+ ;;
+ getf.sig r24 = f36 C lo
+ xma.l f38 = f34, f6, f46
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ ldf8 f46 = [rp], 8
+ getf.sig r28 = f40 C hi
+ ldf8 f34 = [up], 8
+ ;;
+ getf.sig r25 = f37 C lo
+ xma.l f39 = f35, f6, f47
+ ld8 r22 = [r9], 8
+ xma.hu f43 = f35, f6, f47
+ br .LL10
+
+
+.Lb11: ldf8 f46 = [rp], 8
+ ldf8 f34 = [up], 8
+ ;;
+ ldf8 f47 = [rp], 8
+ ldf8 f35 = [up], 8
+ br.cloop.dptk .grt3
+
+ xma.l f37 = f7, f6, f8
+ xma.hu f41 = f7, f6, f8
+ ;;
+ xma.l f38 = f34, f6, f46
+ xma.hu f42 = f34, f6, f46
+ ;;
+ getf.sig r25 = f37 C lo
+ xma.l f39 = f35, f6, f47
+ xma.hu f43 = f35, f6, f47
+ ;;
+ getf.sig r29 = f41 C hi
+ ld8 r22 = [r9], 8
+ ;;
+ getf.sig r26 = f38 C lo
+ getf.sig r30 = f42 C hi
+ ld8 r23 = [r9], 8
+ ;;
+ getf.sig r27 = f39 C lo
+ getf.sig r31 = f43 C hi
+ ld8 r20 = [r9], 8
+ br .Lcj3
+
+.grt3: ldf8 f44 = [rp], 8
+ xma.l f37 = f7, f6, f8
+ ldf8 f32 = [up], 8
+ xma.hu f41 = f7, f6, f8
+ ;;
+ ldf8 f45 = [rp], 8
+ xma.l f38 = f34, f6, f46
+ ldf8 f33 = [up], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ ldf8 f46 = [rp], 8
+ ldf8 f34 = [up], 8
+ ;;
+ getf.sig r25 = f37 C lo
+ xma.l f39 = f35, f6, f47
+ ld8 r22 = [r9], 8
+ xma.hu f43 = f35, f6, f47
+ ;;
+ ldf8 f47 = [rp], 8
+ getf.sig r29 = f41 C hi
+ ldf8 f35 = [up], 8
+ ;;
+ getf.sig r26 = f38 C lo
+ xma.l f36 = f32, f6, f44
+ ld8 r23 = [r9], 8
+ xma.hu f40 = f32, f6, f44
+ br.cloop.dptk .grt7
+ ;;
+
+ getf.sig r30 = f42 C hi
+ getf.sig r27 = f39 C lo
+ xma.l f37 = f33, f6, f45
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ getf.sig r31 = f43 C hi
+ getf.sig r24 = f36 C lo
+ xma.l f38 = f34, f6, f46
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ br .Lcj7
+
+.grt7: ldf8 f44 = [rp], 8
+ getf.sig r30 = f42 C hi
+ ldf8 f32 = [up], 8
+ ;;
+ getf.sig r27 = f39 C lo
+ xma.l f37 = f33, f6, f45
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ ldf8 f45 = [rp], 8
+ getf.sig r31 = f43 C hi
+ ldf8 f33 = [up], 8
+ ;;
+ getf.sig r24 = f36 C lo
+ xma.l f38 = f34, f6, f46
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ br .LL11
+
+
+.Lb00: ldf8 f45 = [rp], 8
+ ldf8 f33 = [up], 8
+ ;;
+ ldf8 f46 = [rp], 8
+ ldf8 f34 = [up], 8
+ ;;
+ ldf8 f47 = [rp], 8
+ xma.l f36 = f7, f6, f8
+ ldf8 f35 = [up], 8
+ xma.hu f40 = f7, f6, f8
+ br.cloop.dptk .grt4
+
+ xma.l f37 = f33, f6, f45
+ xma.hu f41 = f33, f6, f45
+ ;;
+ getf.sig r24 = f36 C lo
+ xma.l f38 = f34, f6, f46
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ getf.sig r28 = f40 C hi
+ xma.l f39 = f35, f6, f47
+ getf.sig r25 = f37 C lo
+ ld8 r22 = [r9], 8
+ xma.hu f43 = f35, f6, f47
+ ;;
+ getf.sig r29 = f41 C hi
+ getf.sig r26 = f38 C lo
+ ld8 r23 = [r9], 8
+ ;;
+ getf.sig r30 = f42 C hi
+ getf.sig r27 = f39 C lo
+ ld8 r20 = [r9], 8
+ br .Lcj4
+
+.grt4: ldf8 f44 = [rp], 8
+ xma.l f37 = f33, f6, f45
+ ldf8 f32 = [up], 8
+ xma.hu f41 = f33, f6, f45
+ ;;
+ ldf8 f45 = [rp], 8
+ ldf8 f33 = [up], 8
+ xma.l f38 = f34, f6, f46
+ getf.sig r24 = f36 C lo
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ ;;
+ ldf8 f46 = [rp], 8
+ getf.sig r28 = f40 C hi
+ ldf8 f34 = [up], 8
+ xma.l f39 = f35, f6, f47
+ getf.sig r25 = f37 C lo
+ ld8 r22 = [r9], 8
+ xma.hu f43 = f35, f6, f47
+ ;;
+ ldf8 f47 = [rp], 8
+ getf.sig r29 = f41 C hi
+ ldf8 f35 = [up], 8
+ ;;
+ getf.sig r26 = f38 C lo
+ xma.l f36 = f32, f6, f44
+ ld8 r23 = [r9], 8
+ xma.hu f40 = f32, f6, f44
+ br.cloop.dptk .grt8
+ ;;
+
+ getf.sig r30 = f42 C hi
+ getf.sig r27 = f39 C lo
+ xma.l f37 = f33, f6, f45
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ br .Lcj8
+
+.grt8: ldf8 f44 = [rp], 8
+ getf.sig r30 = f42 C hi
+ ldf8 f32 = [up], 8
+ ;;
+ getf.sig r27 = f39 C lo
+ xma.l f37 = f33, f6, f45
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ br .LL00
+
+ ALIGN(32)
+.Loop:
+{.mmi
+ ldf8 f44 = [rp], 8
+ cmp.ltu p6, p0 = r27, r8 C lo cmp
+ sub r14 = r27, r8 C lo sub
+}
+{.mmi
+ getf.sig r30 = f42 C hi
+ ldf8 f32 = [up], 8
+ sub r8 = r20, r31 C hi sub
+ ;; C 01
+}
+{.mmf
+ getf.sig r27 = f39 C lo
+ st8 [r10] = r14, 8
+ xma.l f37 = f33, f6, f45
+}
+{.mfi
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ (p6) add r8 = 1, r8
+ ;; C 02
+}
+{.mmi
+.LL00: ldf8 f45 = [rp], 8
+ cmp.ltu p6, p0 = r24, r8
+ sub r14 = r24, r8
+}
+{.mmi
+ getf.sig r31 = f43 C hi
+ ldf8 f33 = [up], 8
+ sub r8 = r21, r28
+ ;; C 03
+}
+{.mmf
+ getf.sig r24 = f36 C lo
+ st8 [r10] = r14, 8
+ xma.l f38 = f34, f6, f46
+}
+{.mfi
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ (p6) add r8 = 1, r8
+ ;; C 04
+}
+{.mmi
+.LL11: ldf8 f46 = [rp], 8
+ cmp.ltu p6, p0 = r25, r8
+ sub r14 = r25, r8
+}
+{.mmi
+ getf.sig r28 = f40 C hi
+ ldf8 f34 = [up], 8
+ sub r8 = r22, r29
+ ;; C 05
+}
+{.mmf
+ getf.sig r25 = f37 C lo
+ st8 [r10] = r14, 8
+ xma.l f39 = f35, f6, f47
+}
+{.mfi
+ ld8 r22 = [r9], 8
+ xma.hu f43 = f35, f6, f47
+ (p6) add r8 = 1, r8
+ ;; C 06
+}
+{.mmi
+.LL10: ldf8 f47 = [rp], 8
+ cmp.ltu p6, p0 = r26, r8
+ sub r14 = r26, r8
+}
+{.mmi
+ getf.sig r29 = f41 C hi
+ ldf8 f35 = [up], 8
+ sub r8 = r23, r30
+ ;; C 07
+}
+{.mmf
+ getf.sig r26 = f38 C lo
+ st8 [r10] = r14, 8
+ xma.l f36 = f32, f6, f44
+}
+{.mfi
+ ld8 r23 = [r9], 8
+ xma.hu f40 = f32, f6, f44
+ (p6) add r8 = 1, r8
+}
+ br.cloop.dptk .Loop
+ ;;
+
+.Lend:
+ cmp.ltu p6, p0 = r27, r8
+ sub r14 = r27, r8
+ getf.sig r30 = f42
+ sub r8 = r20, r31
+ ;;
+ getf.sig r27 = f39
+ st8 [r10] = r14, 8
+ xma.l f37 = f33, f6, f45
+ ld8 r20 = [r9], 8
+ xma.hu f41 = f33, f6, f45
+ (p6) add r8 = 1, r8
+ ;;
+.Lcj8:
+ cmp.ltu p6, p0 = r24, r8
+ sub r14 = r24, r8
+ getf.sig r31 = f43
+ sub r8 = r21, r28
+ ;;
+ getf.sig r24 = f36
+ st8 [r10] = r14, 8
+ xma.l f38 = f34, f6, f46
+ ld8 r21 = [r9], 8
+ xma.hu f42 = f34, f6, f46
+ (p6) add r8 = 1, r8
+ ;;
+.Lcj7:
+ cmp.ltu p6, p0 = r25, r8
+ sub r14 = r25, r8
+ getf.sig r28 = f40
+ sub r8 = r22, r29
+ ;;
+ getf.sig r25 = f37
+ st8 [r10] = r14, 8
+ xma.l f39 = f35, f6, f47
+ ld8 r22 = [r9], 8
+ xma.hu f43 = f35, f6, f47
+ (p6) add r8 = 1, r8
+ ;;
+.Lcj6:
+ cmp.ltu p6, p0 = r26, r8
+ sub r14 = r26, r8
+ getf.sig r29 = f41
+ sub r8 = r23, r30
+ ;;
+ getf.sig r26 = f38
+ st8 [r10] = r14, 8
+ ld8 r23 = [r9], 8
+ (p6) add r8 = 1, r8
+ ;;
+.Lcj5:
+ cmp.ltu p6, p0 = r27, r8
+ sub r14 = r27, r8
+ getf.sig r30 = f42
+ sub r8 = r20, r31
+ ;;
+ getf.sig r27 = f39
+ st8 [r10] = r14, 8
+ ld8 r20 = [r9], 8
+ (p6) add r8 = 1, r8
+ ;;
+.Lcj4:
+ cmp.ltu p6, p0 = r24, r8
+ sub r14 = r24, r8
+ getf.sig r31 = f43
+ sub r8 = r21, r28
+ ;;
+ st8 [r10] = r14, 8
+ (p6) add r8 = 1, r8
+ ;;
+.Lcj3:
+ cmp.ltu p6, p0 = r25, r8
+ sub r14 = r25, r8
+ sub r8 = r22, r29
+ ;;
+ st8 [r10] = r14, 8
+ (p6) add r8 = 1, r8
+ ;;
+.Lcj2:
+ cmp.ltu p6, p0 = r26, r8
+ sub r14 = r26, r8
+ sub r8 = r23, r30
+ ;;
+ st8 [r10] = r14, 8
+ (p6) add r8 = 1, r8
+ ;;
+.Lcj1:
+ cmp.ltu p6, p0 = r27, r8
+ sub r14 = r27, r8
+ sub r8 = r20, r31
+ ;;
+ st8 [r10] = r14, 8
+ mov ar.lc = r2
+ (p6) add r8 = 1, r8
+ br.ret.sptk.many b0
+.Ldone: mov ar.lc = r2
+ br.ret.sptk.many b0
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/lisp/gmpasm-mode.el b/gmp/mpn/lisp/gmpasm-mode.el
new file mode 100644
index 0000000000..06b74bd6ce
--- /dev/null
+++ b/gmp/mpn/lisp/gmpasm-mode.el
@@ -0,0 +1,385 @@
+;;; gmpasm-mode.el -- GNU MP asm and m4 editing mode.
+
+
+;; Copyright 1999-2002 Free Software Foundation, Inc.
+
+;; This file is part of the GNU MP Library.
+;;
+;; The GNU MP Library is free software; you can redistribute it and/or modify
+;; it under the terms of either:
+;;
+;; * the GNU Lesser General Public License as published by the Free
+;; Software Foundation; either version 3 of the License, or (at your
+;; option) any later version.
+;;
+;; or
+;;
+;; * the GNU General Public License as published by the Free Software
+;; Foundation; either version 2 of the License, or (at your option) any
+;; later version.
+;;
+;; or both in parallel, as here.
+;;
+;; The GNU MP Library is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+;; for more details.
+;;
+;; You should have received copies of the GNU General Public License and the
+;; GNU Lesser General Public License along with the GNU MP Library. If not,
+;; see https://www.gnu.org/licenses/.
+
+
+;;; Commentary:
+;;
+;; gmpasm-mode is a major mode for editing m4 processed assembler code and
+;; m4 macro files in GMP. It's similar to m4-mode, but has a number of
+;; settings better suited to GMP.
+;;
+;;
+;; Install
+;; -------
+;;
+;; To make M-x gmpasm-mode available, put gmpasm-mode.el somewhere in your
+;; load-path and the following in your .emacs
+;;
+;; (autoload 'gmpasm-mode "gmpasm-mode" nil t)
+;;
+;; To use gmpasm-mode automatically on all .asm and .m4 files, put the
+;; following in your .emacs
+;;
+;; (add-to-list 'auto-mode-alist '("\\.asm\\'" . gmpasm-mode))
+;; (add-to-list 'auto-mode-alist '("\\.m4\\'" . gmpasm-mode))
+;;
+;; To have gmpasm-mode only on gmp files, try instead something like the
+;; following, which uses it only in a directory starting with "gmp", or a
+;; sub-directory of such.
+;;
+;; (add-to-list 'auto-mode-alist
+;; '("/gmp.*/.*\\.\\(asm\\|m4\\)\\'" . gmpasm-mode))
+;;
+;; Byte compiling will slightly speed up loading. If you want a docstring
+;; in the autoload you can use M-x update-file-autoloads if you set it up
+;; right.
+;;
+;;
+;; Emacsen
+;; -------
+;;
+;; GNU Emacs 20.x, 21.x and XEmacs 20.x all work well. GNU Emacs 19.x
+;; should work if replacements for the various 20.x-isms are available,
+;; though comment-region with "C" doesn't do the right thing.
+
+
+;;; Code:
+
+(defgroup gmpasm nil
+ "GNU MP m4 and asm editing."
+ :prefix "gmpasm-"
+ :group 'languages)
+
+(defcustom gmpasm-mode-hook nil
+ "*Hook called by `gmpasm-mode'."
+ :type 'hook
+ :group 'gmpasm)
+
+(defcustom gmpasm-comment-start-regexp "\\([#;!@*|C]\\|//\\)"
+ "*Regexp matching possible comment styles.
+See `gmpasm-mode' docstring for how this is used.
+
+Commenting styles within GMP include
+ # - alpha, i386, i960, vax, traditional unix
+ ; - a29k, clipper, hppa, m88k, ppc
+ ! - sh, sparc, z8000
+ | - m68k
+ @ - arm
+ * - cray
+ C - GMP m4, see mpn/asm-defs.m4
+ // - ia64"
+ :type 'regexp
+ :group 'gmpasm)
+
+
+(defun gmpasm-add-to-list-second (list-var element)
+ "(gmpasm-add-to-list-second LIST-VAR ELEMENT)
+
+Add ELEMENT to LIST-VAR as the second element in the list, if it isn't
+already in the list. If LIST-VAR is nil, then ELEMENT is just added as the
+sole element in the list.
+
+This is like `add-to-list', but it puts the new value second in the list.
+
+The first cons cell is copied rather than changed in-place, so references to
+the list elsewhere won't be affected."
+
+ (if (member element (symbol-value list-var))
+ (symbol-value list-var)
+ (set list-var
+ (if (symbol-value list-var)
+ (cons (car (symbol-value list-var))
+ (cons element
+ (cdr (symbol-value list-var))))
+ (list element)))))
+
+
+(defun gmpasm-remove-from-list (list-var element)
+ "(gmpasm-remove-from-list LIST-VAR ELEMENT)
+
+Remove ELEMENT from LIST-VAR, using `copy-sequence' and `delete'.
+This is vaguely like `add-to-list', but the element is removed from the list.
+The list is copied rather than changed in-place, so references to it elsewhere
+aren't affected."
+
+;; Only the portion of the list up to the removed element needs to be
+;; copied, but there's no need to bother arranging that, since this function
+;; is only used for a couple of initializations.
+
+ (set list-var (delete element (copy-sequence (symbol-value list-var)))))
+
+
+(defvar gmpasm-mode-map
+ (let ((map (make-sparse-keymap)))
+
+ ;; assembler and dnl commenting
+ (define-key map "\C-c\C-c" 'comment-region)
+ (define-key map "\C-c\C-d" 'gmpasm-comment-region-dnl)
+
+ ;; kill an M-x compile, since it's not hard to put m4 into an infinite
+ ;; loop
+ (define-key map "\C-c\C-k" 'kill-compilation)
+
+ map)
+ "Keymap for `gmpasm-mode'.")
+
+
+(defvar gmpasm-mode-syntax-table
+ (let ((table (make-syntax-table)))
+ ;; underscore left as a symbol char, like C mode
+
+ ;; m4 quotes
+ (modify-syntax-entry ?` "('" table)
+ (modify-syntax-entry ?' ")`" table)
+
+ table)
+ "Syntax table used in `gmpasm-mode'.
+
+'#' and '\n' aren't set as comment syntax. In m4 these are a comment
+outside quotes, but not inside. Omitting a syntax entry ensures that when
+inside quotes emacs treats parentheses and apostrophes the same way that m4
+does. When outside quotes this is not quite right, but having it right when
+nesting expressions is more important.
+
+'*', '!' or '|' aren't setup as comment syntax either, on CPUs which use
+these for comments. The GMP macro setups don't set them in m4 changecom(),
+since that prevents them being used in eval() expressions, and on that basis
+they don't change the way quotes and parentheses are treated by m4 and
+should be treated by emacs.")
+
+
+(defvar gmpasm-font-lock-keywords
+ (eval-when-compile
+ (list
+ (cons
+ (concat
+ "\\b"
+ (regexp-opt
+ '("deflit" "defreg" "defframe" "defframe_pushl"
+ "define_not_for_expansion"
+ "m4_error" "m4_warning"
+ "ASM_START" "ASM_END"
+ "PROLOGUE" "PROLOGUE_GP" "MULFUNC_PROLOGUE" "EPILOGUE"
+ "DATASTART" "DATAEND"
+ "forloop"
+ "TEXT" "DATA" "ALIGN" "W32" "FLOAT64"
+ "builtin" "changecom" "changequote" "changeword" "debugfile"
+ "debugmode" "decr" "define" "defn" "divert" "divnum" "dumpdef"
+ "errprint" "esyscmd" "eval" "__file__" "format" "gnu" "ifdef"
+ "ifelse" "include" "incr" "index" "indir" "len" "__line__"
+ "m4exit" "m4wrap" "maketemp" "patsubst" "popdef" "pushdef"
+ "regexp" "shift" "sinclude" "substr" "syscmd" "sysval"
+ "traceoff" "traceon" "translit" "undefine" "undivert" "unix")
+ t)
+ "\\b") 'font-lock-keyword-face)))
+
+ "`font-lock-keywords' for `gmpasm-mode'.
+
+The keywords are m4 builtins and some of the GMP macros used in asm files.
+L doesn't look good fontified, so it's omitted.
+
+The right assembler comment regexp is added dynamically buffer-local (with
+dnl too).")
+
+
+;; Initialized if gmpasm-mode finds filladapt loaded.
+(defvar gmpasm-filladapt-token-table nil
+ "Filladapt token table used in `gmpasm-mode'.")
+(defvar gmpasm-filladapt-token-match-table nil
+ "Filladapt token match table used in `gmpasm-mode'.")
+(defvar gmpasm-filladapt-token-conversion-table nil
+ "Filladapt token conversion table used in `gmpasm-mode'.")
+
+
+;;;###autoload
+(defun gmpasm-mode ()
+ "A major mode for editing GNU MP asm and m4 files.
+
+\\{gmpasm-mode-map}
+`comment-start' and `comment-end' are set buffer-local to assembler
+commenting appropriate for the CPU by looking for something matching
+`gmpasm-comment-start-regexp' at the start of a line, or \"#\" is used if
+there's no match (if \"#\" isn't what you want, type in a desired comment
+and do \\[gmpasm-mode] to reinitialize).
+
+`adaptive-fill-regexp' is set buffer-local to the standard regexp with
+`comment-start' and dnl added. If filladapt.el has been loaded it similarly
+gets `comment-start' and dnl added as buffer-local fill prefixes.
+
+Font locking has the m4 builtins, some of the GMP macros, m4 dnl commenting,
+and assembler commenting (based on the `comment-start' determined).
+
+Note that `gmpasm-comment-start-regexp' is only matched as a whole word, so
+the `C' in it is only matched as a whole word, not on something that happens
+to start with `C'. Also it's only the particular `comment-start' determined
+that's added for filling etc, not the whole `gmpasm-comment-start-regexp'.
+
+`gmpasm-mode-hook' is run after initializations are complete."
+
+ (interactive)
+ (kill-all-local-variables)
+ (setq major-mode 'gmpasm-mode
+ mode-name "gmpasm")
+ (use-local-map gmpasm-mode-map)
+ (set-syntax-table gmpasm-mode-syntax-table)
+ (setq fill-column 76)
+
+ ;; Short instructions might fit with 32, but anything with labels or
+ ;; expressions soon needs the comments pushed out to column 40.
+ (setq comment-column 40)
+
+ ;; Don't want to find out the hard way which dumb assemblers don't like a
+ ;; missing final newline.
+ (set (make-local-variable 'require-final-newline) t)
+
+ ;; The first match of gmpasm-comment-start-regexp at the start of a line
+ ;; determines comment-start, or "#" if no match.
+ (set (make-local-variable 'comment-start)
+ (save-excursion
+ (goto-char (point-min))
+ (if (re-search-forward
+ (concat "^\\(" gmpasm-comment-start-regexp "\\)\\(\\s-\\|$\\)")
+ nil t)
+ (match-string 1)
+ "#")))
+ (set (make-local-variable 'comment-end) "")
+
+ ;; If comment-start ends in an alphanumeric then \b is used to match it
+ ;; only as a separate word. The test is for an alphanumeric rather than
+ ;; \w since we might try # or ! as \w characters but without wanting \b on
+ ;; them.
+ (let ((comment-regexp
+ (concat (regexp-quote comment-start)
+ (if (string-match "[a-zA-Z0-9]\\'" comment-start) "\\b"))))
+
+ ;; Whitespace is required before a comment-start so m4 $# doesn't match
+ ;; when comment-start is "#".
+ (set (make-local-variable 'comment-start-skip)
+ (concat "\\(^\\|\\s-\\)\\(\\<dnl\\>\\|" comment-regexp "\\)[ \t]*"))
+
+ ;; Comment fontification based on comment-start, and always with dnl.
+ ;; Same treatment of a space before "#" as in comment-start-skip, but
+ ;; don't fontify that space.
+ (add-to-list (make-local-variable 'gmpasm-font-lock-keywords)
+ (list (concat "\\(^\\|\\s-\\)\\(\\(\\<dnl\\>\\|"
+ comment-regexp
+ "\\).*$\\)")
+ 2 'font-lock-comment-face))
+
+ (set (make-local-variable 'font-lock-defaults)
+ '(gmpasm-font-lock-keywords
+ t ; no syntactic fontification (of strings etc)
+ nil ; no case-fold
+ ((?_ . "w")) ; _ part of a word while fontifying
+ ))
+
+ ;; Paragraphs are separated by blank lines, or lines with only dnl or
+ ;; comment-start.
+ (set (make-local-variable 'paragraph-separate)
+ (concat "[ \t\f]*\\(\\(" comment-regexp "\\|dnl\\)[ \t]*\\)*$"))
+ (set (make-local-variable 'paragraph-start)
+ (concat "\f\\|" paragraph-separate))
+
+ ;; Some sort of "def...(" m4 define, possibly with ` for quoting.
+ ;; Could do something with PROLOGUE here, but in GMP the filename is
+ ;; enough, it's not normally necessary to say the function name.
+ (set (make-local-variable 'add-log-current-defun-header-regexp)
+ "^def[a-z0-9_]+(`?\\([a-zA-Z0-9_]+\\)")
+
+ ;; Adaptive fill gets dnl and comment-start as comment style prefixes on
+ ;; top of the standard regexp (which has # and ; already actually).
+ (set (make-local-variable 'adaptive-fill-regexp)
+ (concat "[ \t]*\\(\\("
+ comment-regexp
+ "\\|dnl\\|[-|#;>*]+\\|(?[0-9]+[.)]\\)[ \t]*\\)*"))
+ (set (make-local-variable 'adaptive-fill-first-line-regexp)
+ "\\`\\([ \t]*dnl\\)?[ \t]*\\'")
+
+ (when (fboundp 'filladapt-mode)
+ (unless gmpasm-filladapt-token-table
+ (setq gmpasm-filladapt-token-table
+ filladapt-token-table)
+ (setq gmpasm-filladapt-token-match-table
+ filladapt-token-match-table)
+ (setq gmpasm-filladapt-token-conversion-table
+ filladapt-token-conversion-table)
+
+ ;; Numbered bullet points like "2.1" get matched at the start of a
+ ;; line when it's really something like "2.1 cycles/limb", so remove
+ ;; this from the list. The regexp for "1.", "2." etc is left
+ ;; though.
+ (gmpasm-remove-from-list 'gmpasm-filladapt-token-table
+ '("[0-9]+\\(\\.[0-9]+\\)+[ \t]"
+ bullet))
+
+ ;; "%" as a comment prefix interferes with register names on some
+ ;; CPUs, like %eax on x86, so remove this.
+ (gmpasm-remove-from-list 'gmpasm-filladapt-token-table
+ '("%+" postscript-comment))
+
+ (add-to-list 'gmpasm-filladapt-token-match-table
+ '(gmpasm-comment gmpasm-comment))
+ (add-to-list 'gmpasm-filladapt-token-conversion-table
+ '(gmpasm-comment . exact)))
+
+ (set (make-local-variable 'filladapt-token-table)
+ gmpasm-filladapt-token-table)
+ (set (make-local-variable 'filladapt-token-match-table)
+ gmpasm-filladapt-token-match-table)
+ (set (make-local-variable 'filladapt-token-conversion-table)
+ gmpasm-filladapt-token-conversion-table)
+
+ ;; Add dnl and comment-start as fill prefixes.
+ ;; Comments in filladapt.el say filladapt-token-table must begin
+ ;; with ("^" beginning-of-line), so put our addition second.
+ (gmpasm-add-to-list-second 'filladapt-token-table
+ (list (concat "dnl[ \t]\\|" comment-regexp)
+ 'gmpasm-comment))))
+
+ (run-hooks 'gmpasm-mode-hook))
+
+
+(defun gmpasm-comment-region-dnl (beg end &optional arg)
+ "(gmpasm-comment-region-dnl BEG END &optional ARG)
+
+Comment or uncomment each line in the region using `dnl'.
+With \\[universal-argument] prefix arg, uncomment each line in region.
+This is `comment-region', but using \"dnl\"."
+
+ (interactive "r\nP")
+ (let ((comment-start "dnl")
+ (comment-end ""))
+ (comment-region beg end arg)))
+
+
+(provide 'gmpasm-mode)
+
+;;; gmpasm-mode.el ends here
diff --git a/gmp/mpn/m4-ccas b/gmp/mpn/m4-ccas
new file mode 100755
index 0000000000..16d80c6f51
--- /dev/null
+++ b/gmp/mpn/m4-ccas
@@ -0,0 +1,107 @@
+#!/bin/sh
+#
+# A helper script for Makeasm.am .asm.lo rule.
+
+# Copyright 2001 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: m4-ccas --m4=M4 CC ... file.asm ...
+#
+# Process file.asm with the given M4 plus any -D arguments, then
+# assemble with the given CC plus all arguments.
+#
+# The M4 command must be in a single --m4= argument, and will be split
+# on whitespace. When CC is invoked file.asm is replaced with a
+# temporary .s file which is the M4 output.
+#
+# To allow parallel builds, the temp file name is based on the .asm
+# file name, which will be the output object filename for all uses we
+# put this script to.
+
+M4=
+CC=
+DEFS=
+ASM=
+SEEN_O=no
+
+for i in "$@"; do
+ case $i in
+ --m4=*)
+ M4=`echo "$i" | sed 's/^--m4=//'`
+ ;;
+ -D*)
+ DEFS="$DEFS $i"
+ CC="$CC $i"
+ ;;
+ *.asm)
+ if test -n "$ASM"; then
+ echo "Only one .asm file permitted"
+ exit 1
+ fi
+ BASENAME=`echo "$i" | sed -e 's/\.asm$//' -e 's/^.*[\\/:]//'`
+ TMP=tmp-$BASENAME.s
+ ASM=$i
+ CC="$CC $TMP"
+ ;;
+ -o)
+ SEEN_O=yes
+ CC="$CC $i"
+ ;;
+ *)
+ CC="$CC $i"
+ ;;
+ esac
+done
+
+if test -z "$M4"; then
+ echo "No --m4 specified"
+ exit 1
+fi
+
+if test -z "$ASM"; then
+ echo "No .asm specified"
+ exit 1
+fi
+
+# Libtool adds it's own -o when sending output to .libs/foo.o, but not
+# when just wanting foo.o in the current directory. We need an
+# explicit -o in both cases since we're assembling tmp-foo.s.
+#
+if test $SEEN_O = no; then
+ CC="$CC -o $BASENAME.o"
+fi
+
+echo "$M4 $DEFS $ASM >$TMP"
+$M4 $DEFS $ASM >$TMP || exit
+
+echo "$CC"
+$CC || exit
+
+# Comment this out to preserve .s intermediates
+rm -f $TMP
diff --git a/gmp/mpn/m68k/README b/gmp/mpn/m68k/README
new file mode 100644
index 0000000000..5261564df2
--- /dev/null
+++ b/gmp/mpn/m68k/README
@@ -0,0 +1,138 @@
+Copyright 2001, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ M68K MPN SUBROUTINES
+
+
+This directory contains mpn functions for various m68k family chips.
+
+
+CODE ORGANIZATION
+
+ m68k m68000, m68010, m68060
+ m68k/mc68020 m68020, m68030, m68040, and CPU32
+
+
+The m5200 "coldfire", which is m68000 less a few instructions, currently has
+no assembler code support.
+
+
+STATUS
+
+The code herein is old and poorly maintained. If somebody really cared, it
+could be optimized substantially. For example,
+
+* mpn_add_n and mpn_sub_n could, with more unrolling be improved from 6 to
+ close to 4 c/l (on m68040).
+
+* The multiplication loops could be sped up by using the FPU.
+
+* mpn_lshift by 31 should use the special-case mpn_rshift by 1 code, and
+ vice versa mpn_rshift by 31 use the special lshift by 1, when operand
+ overlap permits.
+
+* On 68000, mpn_mul_1, mpn_addmul_1 and mpn_submul_1 could check for a
+ 16-bit multiplier and use two multiplies per limb, not four.
+
+ Similarly various other _1 operations like mpn_mod_1, mpn_divrem_1,
+ mpn_divexact_1, mpn_modexact_1c_odd.
+
+* On 68000, mpn_lshift and mpn_rshift could use a roll and mask instead of
+ lsrl and lsll. This promises to be a speedup, effectively trading a 6+2*n
+ shift for one or two 4 cycle masks. Suggested by Jean-Charles Meyrignac.
+
+* config.guess detects 68000, 68010, CPU32 and 68020 by running some code,
+ but relies on system information for 030, 040 and 060. Can they be
+ identified by running some code? Currently this only makes a difference
+ to the compiler options selected, since we have no specific asm code for
+ those chips.
+
+One novel idea for 68000 would be to use a 16-bit limb instead of 32-bits.
+This would suit the native 16x16 multiply, but might make it difficult to
+get full value from the native 32x32 add/sub/etc. This would be an ABI
+option, and would select "__GMP_SHORT_LIMB" in gmp.h.
+
+Naturally an entirely new set of asm subroutines would be needed for a
+16-bit limb. Also there's various places in the C code assuming limb>=long,
+which would need to be updated, eg. mpz_set_ui. Some of the nails changes
+may have helped cover some of this.
+
+
+ASM FILES
+
+The .asm files are put through m4 for macro processing, and with the help of
+configure give either MIT or Motorola syntax. The generic mpn/asm-defs.m4
+is used, together with mpn/m68k/m68k-defs.m4. See comments in those files.
+
+Not all possible syntax variations are covered. GCC config/m68k for
+instance has things like $ for immediates on CRDS or reversed cmp order for
+AT&T SGS. These could probably be handled if anyone really needs it.
+
+
+CALLING CONVENTIONS
+
+The SVR4 standard has an int of 32 bits, and all parameters 32-bit aligned
+on the stack.
+
+PalmOS and perhaps various embedded systems intended for 68000 however use
+an int of 16 bits and parameters only 16-bit aligned on the stack. This is
+generated by "gcc -mshort" (and is the default for the PalmOS gcc port, we
+believe).
+
+The asm files adapt to these two ABIs by checking sizeof(unsigned), coming
+through config.m4 as SIZEOF_UNSIGNED. Only mpn_lshift and mpn_rshift are
+affected, all other routines take longs and pointers, which are 32-bits in
+both cases.
+
+Strictly speaking the size of an int doesn't determine the stack padding
+convention. But if int is 16 bits then we can definitely say the host
+system is not SVR4, and therefore may as well assume we're in 16-bit stack
+alignment.
+
+
+REFERENCES
+
+"Motorola M68000 Family Programmer's Reference Manual", available online,
+
+ http://e-www.motorola.com/brdata/PDFDB/docs/M68000PM.pdf
+
+"System V Application Binary Interface: Motorola 68000 Processor Family
+Supplement", AT&T, 1990, ISBN 0-13-877553-6. Has details of calling
+conventions and ELF style PIC coding.
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/m68k/aors_n.asm b/gmp/mpn/m68k/aors_n.asm
new file mode 100644
index 0000000000..f7d379ec01
--- /dev/null
+++ b/gmp/mpn/m68k/aors_n.asm
@@ -0,0 +1,99 @@
+dnl mc68020 mpn_add_n, mpn_sub_n -- add or subtract limb vectors
+
+dnl Copyright 1992, 1994, 1996, 1999-2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 68040: 6
+
+ifdef(`OPERATION_add_n',`
+ define(M4_inst, addxl)
+ define(M4_function_n, mpn_add_n)
+',`ifdef(`OPERATION_sub_n',`
+ define(M4_inst, subxl)
+ define(M4_function_n, mpn_sub_n)
+',
+`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
+')')')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_sub_n)
+
+
+C INPUT PARAMETERS
+C res_ptr (sp + 4)
+C s1_ptr (sp + 8)
+C s2_ptr (sp + 12)
+C size (sp + 16)
+
+
+PROLOGUE(M4_function_n)
+
+C Save used registers on the stack.
+ movel d2, M(-,sp)
+ movel a2, M(-,sp)
+
+C Copy the arguments to registers. Better use movem?
+ movel M(sp,12), a2
+ movel M(sp,16), a0
+ movel M(sp,20), a1
+ movel M(sp,24), d2
+
+ eorw #1, d2
+ lsrl #1, d2
+ bcc L(L1)
+ subql #1, d2 C clears cy as side effect
+
+L(Loop):
+ movel M(a0,+), d0
+ movel M(a1,+), d1
+ M4_inst d1, d0
+ movel d0, M(a2,+)
+L(L1): movel M(a0,+), d0
+ movel M(a1,+), d1
+ M4_inst d1, d0
+ movel d0, M(a2,+)
+
+ dbf d2, L(Loop) C loop until 16 lsb of %4 == -1
+ subxl d0, d0 C d0 <= -cy; save cy as 0 or -1 in d0
+ subl #0x10000, d2
+ bcs L(L2)
+ addl d0, d0 C restore cy
+ bra L(Loop)
+
+L(L2):
+ negl d0
+
+C Restore used registers from stack frame.
+ movel M(sp,+), a2
+ movel M(sp,+), d2
+
+ rts
+
+EPILOGUE(M4_function_n)
diff --git a/gmp/mpn/m68k/gmp-mparam.h b/gmp/mpn/m68k/gmp-mparam.h
new file mode 100644
index 0000000000..9ac7b41019
--- /dev/null
+++ b/gmp/mpn/m68k/gmp-mparam.h
@@ -0,0 +1,76 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2000-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* 25MHz 68040 */
+
+/* Generated by tuneup.c, 2004-02-05, gcc 3.2 */
+
+#define MUL_TOOM22_THRESHOLD 14
+#define MUL_TOOM33_THRESHOLD 90
+
+#define SQR_BASECASE_THRESHOLD 5
+#define SQR_TOOM2_THRESHOLD 28
+#define SQR_TOOM3_THRESHOLD 98
+
+#define DIV_SB_PREINV_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_DC_THRESHOLD 55
+#define POWM_THRESHOLD 65
+
+#define HGCD_THRESHOLD 116
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 590
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVREM_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define USE_PREINV_DIVREM_1 0
+#define USE_PREINV_MOD_1 0
+#define DIVREM_2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MODEXACT_1_ODD_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define GET_STR_DC_THRESHOLD 18
+#define GET_STR_PRECOMPUTE_THRESHOLD 43
+#define SET_STR_THRESHOLD 937
+
+#define MUL_FFT_TABLE { 336, 672, 1408, 3584, 10240, 24576, 0 }
+#define MUL_FFT_MODF_THRESHOLD 296
+#define MUL_FFT_THRESHOLD 1728
+
+#define SQR_FFT_TABLE { 336, 736, 1408, 3584, 10240, 24576, 0 }
+#define SQR_FFT_MODF_THRESHOLD 296
+#define SQR_FFT_THRESHOLD 2304
diff --git a/gmp/mpn/m68k/lshift.asm b/gmp/mpn/m68k/lshift.asm
new file mode 100644
index 0000000000..f202abfe43
--- /dev/null
+++ b/gmp/mpn/m68k/lshift.asm
@@ -0,0 +1,175 @@
+dnl mc68020 mpn_lshift -- mpn left shift.
+
+dnl Copyright 1996, 1999-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C shift==1 shift>1
+C 68040: 5 12
+
+
+C mp_limb_t mpn_lshift (mp_ptr res_ptr, mp_srcptr s_ptr, mp_size_t s_size,
+C unsigned cnt);
+C
+C The "cnt" parameter is either 16 bits or 32 bits depending on
+C SIZEOF_UNSIGNED (see ABI notes in mpn/m68k/README). The value is of
+C course only 1 to 31. When loaded as 16 bits there's garbage in the upper
+C half, hence the use of cmpw. The shift instructions take the their count
+C modulo 64, so the upper part doesn't matter to them either.
+C
+
+C INPUT PARAMETERS
+C res_ptr (sp + 4)
+C s_ptr (sp + 8)
+C s_size (sp + 12)
+C cnt (sp + 16)
+
+define(res_ptr, `a1')
+define(s_ptr, `a0')
+define(s_size, `d6')
+define(cnt, `d4')
+
+ifdef(`SIZEOF_UNSIGNED',,
+`m4_error(`SIZEOF_UNSIGNED not defined, should be in config.m4
+')')
+
+PROLOGUE(mpn_lshift)
+C Save used registers on the stack.
+ moveml d2-d6/a2, M(-,sp)
+
+C Copy the arguments to registers.
+ movel M(sp,28), res_ptr
+ movel M(sp,32), s_ptr
+ movel M(sp,36), s_size
+ifelse(SIZEOF_UNSIGNED,2,
+` movew M(sp,40), cnt',
+` movel M(sp,40), cnt')
+
+ moveql #1, d5
+ cmpw d5, cnt
+ bne L(Lnormal)
+ cmpl s_ptr, res_ptr
+ bls L(Lspecial) C jump if s_ptr >= res_ptr
+
+ifelse(scale_available_p,1,`
+ lea M(s_ptr,s_size,l,4), a2
+',`
+ movel s_size, d0
+ asll #2, d0
+ lea M(s_ptr,d0,l), a2
+')
+ cmpl res_ptr, a2
+ bls L(Lspecial) C jump if res_ptr >= s_ptr + s_size
+
+L(Lnormal):
+ moveql #32, d5
+ subl cnt, d5
+
+ifelse(scale_available_p,1,`
+ lea M(s_ptr,s_size,l,4), s_ptr
+ lea M(res_ptr,s_size,l,4), res_ptr
+',`
+ movel s_size, d0
+ asll #2, d0
+ addl d0, s_ptr
+ addl d0, res_ptr
+')
+ movel M(-,s_ptr), d2
+ movel d2, d0
+ lsrl d5, d0 C compute carry limb
+
+ lsll cnt, d2
+ movel d2, d1
+ subql #1, s_size
+ beq L(Lend)
+ lsrl #1, s_size
+ bcs L(L1)
+ subql #1, s_size
+
+L(Loop):
+ movel M(-,s_ptr), d2
+ movel d2, d3
+ lsrl d5, d3
+ orl d3, d1
+ movel d1, M(-,res_ptr)
+ lsll cnt, d2
+L(L1):
+ movel M(-,s_ptr), d1
+ movel d1, d3
+ lsrl d5, d3
+ orl d3, d2
+ movel d2, M(-,res_ptr)
+ lsll cnt, d1
+
+ dbf s_size, L(Loop)
+ subl #0x10000, s_size
+ bcc L(Loop)
+
+L(Lend):
+ movel d1, M(-,res_ptr) C store least significant limb
+
+C Restore used registers from stack frame.
+ moveml M(sp,+), d2-d6/a2
+ rts
+
+C We loop from least significant end of the arrays, which is only
+C permissable if the source and destination don't overlap, since the
+C function is documented to work for overlapping source and destination.
+
+L(Lspecial):
+ clrl d0 C initialize carry
+ eorw #1, s_size
+ lsrl #1, s_size
+ bcc L(LL1)
+ subql #1, s_size
+
+L(LLoop):
+ movel M(s_ptr,+), d2
+ addxl d2, d2
+ movel d2, M(res_ptr,+)
+L(LL1):
+ movel M(s_ptr,+), d2
+ addxl d2, d2
+ movel d2, M(res_ptr,+)
+
+ dbf s_size, L(LLoop)
+ addxl d0, d0 C save cy in lsb
+ subl #0x10000, s_size
+ bcs L(LLend)
+ lsrl #1, d0 C restore cy
+ bra L(LLoop)
+
+L(LLend):
+C Restore used registers from stack frame.
+ moveml M(sp,+), d2-d6/a2
+ rts
+
+EPILOGUE(mpn_lshift)
diff --git a/gmp/mpn/m68k/m68k-defs.m4 b/gmp/mpn/m68k/m68k-defs.m4
new file mode 100644
index 0000000000..15289f676f
--- /dev/null
+++ b/gmp/mpn/m68k/m68k-defs.m4
@@ -0,0 +1,230 @@
+divert(-1)
+
+dnl m4 macros for 68k assembler.
+
+dnl Copyright 2001-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl The default m4 `#' commenting interferes with the assembler syntax for
+dnl immediates. `|' would be correct, but it interferes with "||" in
+dnl eval(). Would like to disable commenting, but that's not possible (see
+dnl mpn/asm-defs.m4), so use `;' which should be harmless.
+
+changecom(;)
+
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+dnl Same as the standard PROLOGUE, but align to 2 bytes not 4.
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+` TEXT
+ ALIGN(2)
+ GLOBL `$1' GLOBL_ATTR
+ TYPE(`$1',`function')
+`$1'LABEL_SUFFIX')
+
+
+dnl Usage: d0, etc
+dnl
+dnl Expand to d0 or %d0 according to the assembler's requirements.
+dnl
+dnl Actually d0 expands to `d0' or %`d0', the quotes protecting against
+dnl further expansion. Definitions are made even if d0 is to be just `d0',
+dnl so that any m4 quoting problems will show up everywhere, not just on a
+dnl %d0 system.
+dnl
+dnl Care must be taken with quoting when using these in a definition. For
+dnl instance the quotes in the following are essential or two %'s will be
+dnl produced when `counter' is used.
+dnl
+dnl define(counter, `d7')
+dnl
+
+dnl Called: m68k_reg(r)
+define(m68k_reg,
+m4_assert_numargs(1)
+m4_assert_defined(`WANT_REGISTER_PERCENT')
+`ifelse(WANT_REGISTER_PERCENT,yes,%)`$1'')
+
+dnl Usage: m68k_defreg(r)
+define(m68k_defreg,
+m4_assert_numargs(1)
+`deflit($1,`m68k_reg(`$1')')')
+
+m68k_defreg(d0)
+m68k_defreg(d1)
+m68k_defreg(d2)
+m68k_defreg(d3)
+m68k_defreg(d4)
+m68k_defreg(d5)
+m68k_defreg(d6)
+m68k_defreg(d7)
+
+m68k_defreg(a0)
+m68k_defreg(a1)
+m68k_defreg(a2)
+m68k_defreg(a3)
+m68k_defreg(a4)
+m68k_defreg(a5)
+m68k_defreg(a6)
+m68k_defreg(a7)
+
+m68k_defreg(sp)
+m68k_defreg(pc)
+
+
+dnl Usage: M(base)
+dnl M(base,displacement)
+dnl M(base,index,size)
+dnl M(base,index,size,scale)
+dnl M(base,+)
+dnl M(-,base)
+dnl
+dnl `base' is an address register, `index' is a data register, `size' is w
+dnl or l, and scale is 1, 2, 4 or 8.
+dnl
+dnl M(-,base) has it's arguments that way around to emphasise it's a
+dnl pre-decrement, as opposed to M(base,+) a post-increment.
+dnl
+dnl Enhancement: Add the memory indirect modes, if/when they're needed.
+
+define(M,
+m4_assert_numargs_range(1,4)
+m4_assert_defined(`WANT_ADDRESSING')
+`ifelse(WANT_ADDRESSING,mit,
+`ifelse($#,1, ``$1'@')dnl
+ifelse($#,2,
+`ifelse($2,+, ``$1'@+',
+`ifelse($1,-, ``$2'@-',
+ ``$1'@($2)')')')dnl
+ifelse($#,3, ``$1'@(`$2':`$3')')dnl
+ifelse($#,4, ``$1'@(`$2':`$3':$4)')',
+
+dnl WANT_ADDRESSING `motorola'
+`ifelse($#,1, `(`$1')')dnl
+ifelse($#,2,
+`ifelse($2,+, `(`$1')+',
+`ifelse($1,-, `-(`$2')',
+ `$2(`$1')')')')dnl
+ifelse($#,3, `(`$1',`$2'.$3)')dnl
+ifelse($#,4, `(`$1',`$2'.$3*$4)')')')
+
+
+dnl Usage: addl etc
+dnl
+dnl m68k instructions with special handling for the suffix, with for
+dnl instance addl expanding to addl or add.l as necessary.
+dnl
+dnl See also t-m68k-defs.pl which verifies all mnemonics used in the asm
+dnl files have entries here.
+
+dnl Called: m68k_insn(mnemonic,suffix)
+define(m68k_insn,
+m4_assert_numargs(2)
+m4_assert_defined(`WANT_DOT_SIZE')
+`ifelse(WANT_DOT_SIZE,yes, ``$1'.``$2''',
+ ``$1$2'')')
+
+dnl Usage: m68k_definsn(mnemonic,suffix)
+define(m68k_definsn,
+m4_assert_numargs(2)
+`deflit($1`'$2,`m68k_insn(`$1',`$2')')')
+
+m68k_definsn(add, l)
+m68k_definsn(addx, l)
+m68k_definsn(addq, l)
+m68k_definsn(asl, l)
+m68k_definsn(cmp, l)
+m68k_definsn(cmp, w)
+m68k_definsn(clr, l)
+m68k_definsn(divu, l)
+m68k_definsn(eor, w)
+m68k_definsn(lsl, l)
+m68k_definsn(lsr, l)
+m68k_definsn(move, l)
+m68k_definsn(move, w)
+m68k_definsn(movem,l)
+m68k_definsn(moveq,l)
+m68k_definsn(mulu, l)
+m68k_definsn(neg, l)
+m68k_definsn(or, l)
+m68k_definsn(roxl, l)
+m68k_definsn(roxr, l)
+m68k_definsn(sub, l)
+m68k_definsn(subx, l)
+m68k_definsn(subq, l)
+
+
+dnl Usage: bra etc
+dnl
+dnl Expand to `bra', `jra' or `jbra' according to what the assembler will
+dnl accept. The latter two give variable-sized branches in gas.
+dnl
+dnl See also t-m68k-defs.pl which verifies all the bXX branches used in the
+dnl asm files have entries here.
+
+dnl Called: m68k_branch(cond)
+define(m68k_branch,
+m4_assert_numargs(1)
+m4_assert_defined(`WANT_BRANCHES')
+`ifelse(WANT_BRANCHES,jra, `j$1',
+`ifelse(WANT_BRANCHES,jbra,`jb$1',
+ ``b$1'')')')
+
+dnl Called: m68k_defbranch(cond)
+define(m68k_defbranch,
+m4_assert_numargs(1)
+`deflit(b$1,`m68k_branch(`$1')')')
+
+m68k_defbranch(ra)
+m68k_defbranch(cc)
+m68k_defbranch(cs)
+m68k_defbranch(ls)
+m68k_defbranch(eq)
+m68k_defbranch(ne)
+
+
+dnl Usage: scale_available_p
+dnl
+dnl Expand to 1 if a scale factor can be used in addressing modes, or 0 if
+dnl not. M(a0,d0,l,4), meaning a0+d0*4, is not available in 68000 or
+dnl 68010, but is in CPU32 and in 68020 and up.
+
+define(scale_available_p,
+`m4_ifdef_anyof_p(
+`HAVE_HOST_CPU_m68360'
+`HAVE_HOST_CPU_m68020'
+`HAVE_HOST_CPU_m68030'
+`HAVE_HOST_CPU_m68040'
+`HAVE_HOST_CPU_m68060')')
+
+
+divert
diff --git a/gmp/mpn/m68k/mc68020/aorsmul_1.asm b/gmp/mpn/m68k/mc68020/aorsmul_1.asm
new file mode 100644
index 0000000000..4ee30ad9b3
--- /dev/null
+++ b/gmp/mpn/m68k/mc68020/aorsmul_1.asm
@@ -0,0 +1,101 @@
+dnl mc68020 mpn_addmul_1, mpn_submul_1 -- add or subtract mpn multiple.
+
+dnl Copyright 1992, 1994, 1996, 1999-2002, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 68040: 25
+
+ifdef(`OPERATION_addmul_1',`
+ define(M4_inst, addl)
+ define(M4_function_1, mpn_addmul_1)
+',`ifdef(`OPERATION_submul_1',`
+ define(M4_inst, subl)
+ define(M4_function_1, mpn_submul_1)
+',
+`m4_error(`Need OPERATION_addmul_1 or OPERATION_submul_1
+')')')
+
+
+C INPUT PARAMETERS
+C res_ptr (sp + 4)
+C s1_ptr (sp + 8)
+C s1_size (sp + 12)
+C s2_limb (sp + 16)
+
+define(res_ptr, `a0')
+define(s1_ptr, `a1')
+define(s1_size, `d2')
+define(s2_limb, `d4')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+PROLOGUE(M4_function_1)
+
+C Save used registers on the stack.
+ moveml d2-d5, M(-,sp)
+
+C Copy the arguments to registers. Better use movem?
+ movel M(sp,20), res_ptr
+ movel M(sp,24), s1_ptr
+ movel M(sp,28), s1_size
+ movel M(sp,32), s2_limb
+
+ eorw #1, s1_size
+ clrl d1
+ clrl d5
+ lsrl #1, s1_size
+ bcc L(L1)
+ subql #1, s1_size
+ subl d0, d0 C (d0,cy) <= (0,0)
+
+L(Loop):
+ movel M(s1_ptr,+), d3
+ mulul s2_limb, d1:d3
+ addxl d0, d3
+ addxl d5, d1
+ M4_inst d3, M(res_ptr,+)
+L(L1): movel M(s1_ptr,+), d3
+ mulul s2_limb, d0:d3
+ addxl d1, d3
+ addxl d5, d0
+ M4_inst d3, M(res_ptr,+)
+
+ dbf s1_size, L(Loop)
+ addxl d5, d0
+ subl #0x10000, s1_size
+ bcc L(Loop)
+
+C Restore used registers from stack frame.
+ moveml M(sp,+), d2-d5
+
+ rts
+
+EPILOGUE(M4_function_1)
diff --git a/gmp/mpn/m68k/mc68020/mul_1.asm b/gmp/mpn/m68k/mc68020/mul_1.asm
new file mode 100644
index 0000000000..f5fbb3063b
--- /dev/null
+++ b/gmp/mpn/m68k/mc68020/mul_1.asm
@@ -0,0 +1,96 @@
+dnl mc68020 mpn_mul_1 -- mpn by limb multiply
+
+dnl Copyright 1992, 1994, 1996, 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 68040: 24
+
+C INPUT PARAMETERS
+C res_ptr (sp + 4)
+C s1_ptr (sp + 8)
+C s1_size (sp + 12)
+C s2_limb (sp + 16)
+
+
+define(res_ptr, `a0')
+define(s1_ptr, `a1')
+define(s1_size, `d2')
+define(s2_limb, `d4')
+
+
+PROLOGUE(mpn_mul_1)
+
+C Save used registers on the stack.
+ moveml d2-d4, M(-,sp)
+
+C movel d2, M(-,sp)
+C movel d3, M(-,sp)
+C movel d4, M(-,sp)
+
+C Copy the arguments to registers. Better use movem?
+ movel M(sp,16), res_ptr
+ movel M(sp,20), s1_ptr
+ movel M(sp,24), s1_size
+ movel M(sp,28), s2_limb
+
+ eorw #1, s1_size
+ clrl d1
+ lsrl #1, s1_size
+ bcc L(L1)
+ subql #1, s1_size
+ subl d0, d0 C (d0,cy) <= (0,0)
+
+L(Loop):
+ movel M(s1_ptr,+), d3
+ mulul s2_limb, d1:d3
+ addxl d0, d3
+ movel d3, M(res_ptr,+)
+L(L1): movel M(s1_ptr,+), d3
+ mulul s2_limb, d0:d3
+ addxl d1, d3
+ movel d3, M(res_ptr,+)
+
+ dbf s1_size, L(Loop)
+ clrl d3
+ addxl d3, d0
+ subl #0x10000, s1_size
+ bcc L(Loop)
+
+C Restore used registers from stack frame.
+ moveml M(sp,+), d2-d4
+
+C movel M(sp,+),d4
+C movel M(sp,+),d3
+C movel M(sp,+),d2
+
+ rts
+
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/m68k/mc68020/udiv.asm b/gmp/mpn/m68k/mc68020/udiv.asm
new file mode 100644
index 0000000000..aadeab999a
--- /dev/null
+++ b/gmp/mpn/m68k/mc68020/udiv.asm
@@ -0,0 +1,45 @@
+dnl mc68020 mpn_udiv_qrnnd -- 2x1 limb division
+
+dnl Copyright 1999-2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C mp_limb_t mpn_udiv_qrnnd (mp_limb_t *rp,
+C mp_limb_t nh, mp_limb_t nl, mp_limb_t d);
+C
+
+PROLOGUE(mpn_udiv_qrnnd)
+ movel M(sp,4), a0 C rp
+ movel M(sp,8), d1 C nh
+ movel M(sp,12), d0 C nl
+ divul M(sp,16), d1:d0
+ movel d1, M(a0) C r
+ rts
+EPILOGUE(mpn_udiv_qrnnd)
diff --git a/gmp/mpn/m68k/mc68020/umul.asm b/gmp/mpn/m68k/mc68020/umul.asm
new file mode 100644
index 0000000000..f19314e9bb
--- /dev/null
+++ b/gmp/mpn/m68k/mc68020/umul.asm
@@ -0,0 +1,44 @@
+dnl mc68020 mpn_umul_ppmm -- limb by limb multiplication
+
+dnl Copyright 1999-2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C mp_limb_t mpn_umul_ppmm (mp_limb_t *lp, mp_limb_t x, mp_limb_t y);
+C
+
+PROLOGUE(mpn_umul_ppmm)
+ movel M(sp,4), a0 C lp
+ movel M(sp,8), d1 C x
+ movel M(sp,12), d0 C y
+ mulul d0, d0:d1
+ movel d1, M(a0) C low
+ rts
+EPILOGUE(mpn_umul_ppmm)
diff --git a/gmp/mpn/m68k/rshift.asm b/gmp/mpn/m68k/rshift.asm
new file mode 100644
index 0000000000..21b5f89f48
--- /dev/null
+++ b/gmp/mpn/m68k/rshift.asm
@@ -0,0 +1,175 @@
+dnl mc68020 mpn_rshift -- mpn right shift.
+
+dnl Copyright 1996, 1999-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C shift==1 shift>1
+C 68040: 9 12
+
+
+C mp_limb_t mpn_rshift (mp_ptr res_ptr, mp_srcptr s_ptr, mp_size_t s_size,
+C unsigned cnt);
+C
+C The "cnt" parameter is either 16 bits or 32 bits depending on
+C SIZEOF_UNSIGNED (see ABI notes in mpn/m68k/README). The value is of
+C course only 1 to 31. When loaded as 16 bits there's garbage in the upper
+C half, hence the use of cmpw. The shift instructions take the their count
+C modulo 64, so the upper part doesn't matter to them either.
+C
+
+C INPUT PARAMETERS
+C res_ptr (sp + 4)
+C s_ptr (sp + 8)
+C s_size (sp + 12)
+C cnt (sp + 16)
+
+define(res_ptr, `a1')
+define(s_ptr, `a0')
+define(s_size, `d6')
+define(cnt, `d4')
+
+ifdef(`SIZEOF_UNSIGNED',,
+`m4_error(`SIZEOF_UNSIGNED not defined, should be in config.m4
+')')
+
+PROLOGUE(mpn_rshift)
+C Save used registers on the stack.
+ moveml d2-d6/a2, M(-,sp)
+
+C Copy the arguments to registers.
+ movel M(sp,28), res_ptr
+ movel M(sp,32), s_ptr
+ movel M(sp,36), s_size
+ifelse(SIZEOF_UNSIGNED,2,
+` movew M(sp,40), cnt',
+` movel M(sp,40), cnt')
+
+ moveql #1, d5
+ cmpw d5, cnt
+ bne L(Lnormal)
+ cmpl res_ptr, s_ptr
+ bls L(Lspecial) C jump if res_ptr >= s_ptr
+
+ifelse(scale_available_p,1,`
+ lea M(res_ptr,s_size,l,4), a2
+',`
+ movel s_size, d0
+ asll #2, d0
+ lea M(res_ptr,d0,l), a2
+')
+ cmpl s_ptr, a2
+ bls L(Lspecial) C jump if s_ptr >= res_ptr + s_size
+
+L(Lnormal):
+ moveql #32, d5
+ subl cnt, d5
+ movel M(s_ptr,+), d2
+ movel d2, d0
+ lsll d5, d0 C compute carry limb
+
+ lsrl cnt, d2
+ movel d2, d1
+ subql #1, s_size
+ beq L(Lend)
+ lsrl #1, s_size
+ bcs L(L1)
+ subql #1, s_size
+
+L(Loop):
+ movel M(s_ptr,+), d2
+ movel d2, d3
+ lsll d5, d3
+ orl d3, d1
+ movel d1, M(res_ptr,+)
+ lsrl cnt, d2
+L(L1):
+ movel M(s_ptr,+), d1
+ movel d1, d3
+ lsll d5, d3
+ orl d3, d2
+ movel d2, M(res_ptr,+)
+ lsrl cnt, d1
+
+ dbf s_size, L(Loop)
+ subl #0x10000, s_size
+ bcc L(Loop)
+
+L(Lend):
+ movel d1, M(res_ptr) C store most significant limb
+
+C Restore used registers from stack frame.
+ moveml M(sp,+), d2-d6/a2
+ rts
+
+C We loop from most significant end of the arrays, which is only permissable
+C if the source and destination don't overlap, since the function is
+C documented to work for overlapping source and destination.
+
+L(Lspecial):
+ifelse(scale_available_p,1,`
+ lea M(s_ptr,s_size,l,4), s_ptr
+ lea M(res_ptr,s_size,l,4), res_ptr
+',`
+ movel s_size, d0
+ asll #2, d0
+ addl d0, s_ptr
+ addl d0, res_ptr
+')
+
+ clrl d0 C initialize carry
+ eorw #1, s_size
+ lsrl #1, s_size
+ bcc L(LL1)
+ subql #1, s_size
+
+L(LLoop):
+ movel M(-,s_ptr), d2
+ roxrl #1, d2
+ movel d2, M(-,res_ptr)
+L(LL1):
+ movel M(-,s_ptr), d2
+ roxrl #1, d2
+ movel d2, M(-,res_ptr)
+
+ dbf s_size, L(LLoop)
+ roxrl #1, d0 C save cy in msb
+ subl #0x10000, s_size
+ bcs L(LLend)
+ addl d0, d0 C restore cy
+ bra L(LLoop)
+
+L(LLend):
+C Restore used registers from stack frame.
+ moveml M(sp,+), d2-d6/a2
+ rts
+
+EPILOGUE(mpn_rshift)
diff --git a/gmp/mpn/m68k/t-m68k-defs.pl b/gmp/mpn/m68k/t-m68k-defs.pl
new file mode 100644
index 0000000000..91c21fa1f8
--- /dev/null
+++ b/gmp/mpn/m68k/t-m68k-defs.pl
@@ -0,0 +1,91 @@
+#! /usr/bin/perl -w
+
+# Copyright 2001, 2003 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: perl t-m68k-defs.pl [-t]
+#
+# Run this in the mpn/m68k source directory to check that m68k-defs.m4 has
+# m68k_defbranch()s or m68k_definsn()s for each instruction used in *.asm
+# and */*.asm. Print nothing if everything is ok. The -t option prints
+# some diagnostic traces.
+
+use strict;
+use Getopt::Std;
+
+my %opt;
+getopts('t', \%opt);
+
+my %branch;
+my %insn;
+
+open(FD, "<m68k-defs.m4")
+ or die "Cannot open m68k-defs.m4: $!\nIs this the mpn/m68k source directory?\n";
+my ($srcdir, $top_srcdir);
+while (<FD>) {
+ if (/^m68k_defbranch\(\s*(.*)\)/) { $branch{"b".$1} = 1; }
+ if (/^m68k_definsn\(\s*(.*),\s*(.*)\)/) { $insn{$1.$2} = 1; }
+}
+close(FD);
+
+print "branches: ", join(" ",keys(%branch)), "\n" if $opt{'t'};
+print "insns: ", join(" ",keys(%insn)), "\n" if $opt{'t'};
+
+
+foreach my $file (glob("*.asm"), glob("*/*.asm")) {
+ print "file $file\n" if $opt{'t'};
+
+ open(FD, "<$file") or die "Cannot open $file: $!";
+ while (<FD>) {
+ if (/^[ \t]*C/) { next; };
+ if (/^\t([a-z0-9]+)/) {
+ my $opcode = $1;
+ print "opcode $1\n" if $opt{'t'};
+
+ # instructions with an l, w or b suffix should have a definsn
+ # (unless they're already a defbranch)
+ if ($opcode =~ /[lwb]$/
+ && ! defined $insn{$opcode}
+ && ! defined $branch{$opcode})
+ {
+ print "$file: $.: missing m68k_definsn: $opcode\n";
+ }
+
+ # instructions bXX should have a defbranch (unless they're
+ # already a definsn)
+ if ($opcode =~ /^b/
+ && ! defined $insn{$opcode}
+ && ! defined $branch{$opcode})
+ {
+ print "$file: $.: missing m68k_defbranch: $opcode\n";
+ }
+ }
+ }
+ close(FD);
+}
diff --git a/gmp/mpn/m88k/README b/gmp/mpn/m88k/README
new file mode 100644
index 0000000000..1b51e83079
--- /dev/null
+++ b/gmp/mpn/m88k/README
@@ -0,0 +1,61 @@
+Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ M88K MPN SUBROUTINES
+
+This directory contains mpn functions for various m88k family chips.
+
+CODE ORGANIZATION
+
+ m88k m88000, m88100
+ m88k/mc88110 m88110
+
+STATUS
+
+The code herein is old and poorly maintained.
+
+* The .s files assume the system uses a "_" underscore prefix, which
+ should be controlled by configure.
+
+* The mc88110/*.S files are using the defunct "sysdep.h" configuration
+ scheme and won't compile.
+
+Conversion to the current m4 .asm style wouldn't be difficult.
+
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/m88k/add_n.s b/gmp/mpn/m88k/add_n.s
new file mode 100644
index 0000000000..dbdb22f888
--- /dev/null
+++ b/gmp/mpn/m88k/add_n.s
@@ -0,0 +1,113 @@
+; mc88100 mpn_add_n -- Add two limb vectors of the same length > 0 and store
+; sum in a third limb vector.
+
+; Copyright 1992, 1994, 1995, 2000 Free Software Foundation, Inc.
+
+; This file is part of the GNU MP Library.
+;
+; The GNU MP Library is free software; you can redistribute it and/or modify
+; it under the terms of either:
+;
+; * the GNU Lesser General Public License as published by the Free
+; Software Foundation; either version 3 of the License, or (at your
+; option) any later version.
+;
+; or
+;
+; * the GNU General Public License as published by the Free Software
+; Foundation; either version 2 of the License, or (at your option) any
+; later version.
+;
+; or both in parallel, as here.
+;
+; The GNU MP Library is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+; for more details.
+;
+; You should have received copies of the GNU General Public License and the
+; GNU Lesser General Public License along with the GNU MP Library. If not,
+; see https://www.gnu.org/licenses/.
+
+
+; INPUT PARAMETERS
+; res_ptr r2
+; s1_ptr r3
+; s2_ptr r4
+; size r5
+
+; This code has been optimized to run one instruction per clock, avoiding
+; load stalls and writeback contention. As a result, the instruction
+; order is not always natural.
+
+; The speed is about 4.6 clocks/limb + 18 clocks/limb-vector on an 88100,
+; but on the 88110, it seems to run much slower, 6.6 clocks/limb.
+
+ text
+ align 16
+ global ___gmpn_add_n
+___gmpn_add_n:
+ ld r6,r3,0 ; read first limb from s1_ptr
+ extu r10,r5,3
+ ld r7,r4,0 ; read first limb from s2_ptr
+
+ subu.co r5,r0,r5 ; (clear carry as side effect)
+ mak r5,r5,3<4>
+ bcnd eq0,r5,Lzero
+
+ or r12,r0,lo16(Lbase)
+ or.u r12,r12,hi16(Lbase)
+ addu r12,r12,r5 ; r12 is address for entering in loop
+
+ extu r5,r5,2 ; divide by 4
+ subu r2,r2,r5 ; adjust res_ptr
+ subu r3,r3,r5 ; adjust s1_ptr
+ subu r4,r4,r5 ; adjust s2_ptr
+
+ or r8,r6,r0
+
+ jmp.n r12
+ or r9,r7,r0
+
+Loop: addu r3,r3,32
+ st r8,r2,28
+ addu r4,r4,32
+ ld r6,r3,0
+ addu r2,r2,32
+ ld r7,r4,0
+Lzero: subu r10,r10,1 ; add 0 + 8r limbs (adj loop cnt)
+Lbase: ld r8,r3,4
+ addu.cio r6,r6,r7
+ ld r9,r4,4
+ st r6,r2,0
+ ld r6,r3,8 ; add 7 + 8r limbs
+ addu.cio r8,r8,r9
+ ld r7,r4,8
+ st r8,r2,4
+ ld r8,r3,12 ; add 6 + 8r limbs
+ addu.cio r6,r6,r7
+ ld r9,r4,12
+ st r6,r2,8
+ ld r6,r3,16 ; add 5 + 8r limbs
+ addu.cio r8,r8,r9
+ ld r7,r4,16
+ st r8,r2,12
+ ld r8,r3,20 ; add 4 + 8r limbs
+ addu.cio r6,r6,r7
+ ld r9,r4,20
+ st r6,r2,16
+ ld r6,r3,24 ; add 3 + 8r limbs
+ addu.cio r8,r8,r9
+ ld r7,r4,24
+ st r8,r2,20
+ ld r8,r3,28 ; add 2 + 8r limbs
+ addu.cio r6,r6,r7
+ ld r9,r4,28
+ st r6,r2,24
+ bcnd.n ne0,r10,Loop ; add 1 + 8r limbs
+ addu.cio r8,r8,r9
+
+ st r8,r2,28 ; store most significant limb
+
+ jmp.n r1
+ addu.ci r2,r0,r0 ; return carry-out from most sign. limb
diff --git a/gmp/mpn/m88k/mc88110/add_n.S b/gmp/mpn/m88k/mc88110/add_n.S
new file mode 100644
index 0000000000..c3b12b3cd0
--- /dev/null
+++ b/gmp/mpn/m88k/mc88110/add_n.S
@@ -0,0 +1,209 @@
+; mc88110 __gmpn_add_n -- Add two limb vectors of the same length > 0 and store
+; sum in a third limb vector.
+
+; Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
+
+; This file is part of the GNU MP Library.
+;
+; The GNU MP Library is free software; you can redistribute it and/or modify
+; it under the terms of either:
+;
+; * the GNU Lesser General Public License as published by the Free
+; Software Foundation; either version 3 of the License, or (at your
+; option) any later version.
+;
+; or
+;
+; * the GNU General Public License as published by the Free Software
+; Foundation; either version 2 of the License, or (at your option) any
+; later version.
+;
+; or both in parallel, as here.
+;
+; The GNU MP Library is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+; for more details.
+;
+; You should have received copies of the GNU General Public License and the
+; GNU Lesser General Public License along with the GNU MP Library. If not,
+; see https://www.gnu.org/licenses/.
+
+
+; INPUT PARAMETERS
+#define res_ptr r2
+#define s1_ptr r3
+#define s2_ptr r4
+#define size r5
+
+#include "sysdep.h"
+
+ text
+ align 16
+ global C_SYMBOL_NAME(__gmpn_add_n)
+C_SYMBOL_NAME(__gmpn_add_n):
+ addu.co r0,r0,r0 ; clear cy flag
+ xor r12,s2_ptr,res_ptr
+ bb1 2,r12,L1
+; ** V1a **
+L0: bb0 2,res_ptr,L_v1 ; branch if res_ptr is aligned?
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+ ld r10,s1_ptr,0
+ addu s1_ptr,s1_ptr,4
+ ld r8,s2_ptr,0
+ addu s2_ptr,s2_ptr,4
+ subu size,size,1
+ addu.co r6,r10,r8
+ st r6,res_ptr,0
+ addu res_ptr,res_ptr,4
+L_v1: cmp r12,size,2
+ bb1 lt,r12,Lend2
+
+ ld r10,s1_ptr,0
+ ld r12,s1_ptr,4
+ ld.d r8,s2_ptr,0
+ subu size,size,10
+ bcnd lt0,size,Lfin1
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+ align 8
+Loop1: subu size,size,8
+ addu.cio r6,r10,r8
+ ld r10,s1_ptr,8
+ addu.cio r7,r12,r9
+ ld r12,s1_ptr,12
+ ld.d r8,s2_ptr,8
+ st.d r6,res_ptr,0
+ addu.cio r6,r10,r8
+ ld r10,s1_ptr,16
+ addu.cio r7,r12,r9
+ ld r12,s1_ptr,20
+ ld.d r8,s2_ptr,16
+ st.d r6,res_ptr,8
+ addu.cio r6,r10,r8
+ ld r10,s1_ptr,24
+ addu.cio r7,r12,r9
+ ld r12,s1_ptr,28
+ ld.d r8,s2_ptr,24
+ st.d r6,res_ptr,16
+ addu.cio r6,r10,r8
+ ld r10,s1_ptr,32
+ addu.cio r7,r12,r9
+ ld r12,s1_ptr,36
+ addu s1_ptr,s1_ptr,32
+ ld.d r8,s2_ptr,32
+ addu s2_ptr,s2_ptr,32
+ st.d r6,res_ptr,24
+ addu res_ptr,res_ptr,32
+ bcnd ge0,size,Loop1
+
+Lfin1: addu size,size,8-2
+ bcnd lt0,size,Lend1
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1: addu.cio r6,r10,r8
+ ld r10,s1_ptr,8
+ addu.cio r7,r12,r9
+ ld r12,s1_ptr,12
+ ld.d r8,s2_ptr,8
+ st.d r6,res_ptr,0
+ subu size,size,2
+ addu s1_ptr,s1_ptr,8
+ addu s2_ptr,s2_ptr,8
+ addu res_ptr,res_ptr,8
+ bcnd ge0,size,Loope1
+Lend1: addu.cio r6,r10,r8
+ addu.cio r7,r12,r9
+ st.d r6,res_ptr,0
+
+ bb0 0,size,Lret1
+/* Add last limb */
+ ld r10,s1_ptr,8
+ ld r8,s2_ptr,8
+ addu.cio r6,r10,r8
+ st r6,res_ptr,8
+
+Lret1: jmp.n r1
+ addu.ci r2,r0,r0 ; return carry-out from most sign. limb
+
+L1: xor r12,s1_ptr,res_ptr
+ bb1 2,r12,L2
+; ** V1b **
+ or r12,r0,s2_ptr
+ or s2_ptr,r0,s1_ptr
+ or s1_ptr,r0,r12
+ br L0
+
+; ** V2 **
+/* If we come here, the alignment of s1_ptr and res_ptr as well as the
+ alignment of s2_ptr and res_ptr differ. Since there are only two ways
+ things can be aligned (that we care about) we now know that the alignment
+ of s1_ptr and s2_ptr are the same. */
+
+L2: cmp r12,size,1
+ bb1 eq,r12,Ljone
+ bb0 2,s1_ptr,L_v2 ; branch if s1_ptr is aligned
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+ ld r10,s1_ptr,0
+ addu s1_ptr,s1_ptr,4
+ ld r8,s2_ptr,0
+ addu s2_ptr,s2_ptr,4
+ subu size,size,1
+ addu.co r6,r10,r8
+ st r6,res_ptr,0
+ addu res_ptr,res_ptr,4
+
+L_v2: subu size,size,8
+ bcnd lt0,size,Lfin2
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+ align 8
+Loop2: subu size,size,8
+ ld.d r8,s1_ptr,0
+ ld.d r6,s2_ptr,0
+ addu.cio r8,r8,r6
+ st r8,res_ptr,0
+ addu.cio r9,r9,r7
+ st r9,res_ptr,4
+ ld.d r8,s1_ptr,8
+ ld.d r6,s2_ptr,8
+ addu.cio r8,r8,r6
+ st r8,res_ptr,8
+ addu.cio r9,r9,r7
+ st r9,res_ptr,12
+ ld.d r8,s1_ptr,16
+ ld.d r6,s2_ptr,16
+ addu.cio r8,r8,r6
+ st r8,res_ptr,16
+ addu.cio r9,r9,r7
+ st r9,res_ptr,20
+ ld.d r8,s1_ptr,24
+ ld.d r6,s2_ptr,24
+ addu.cio r8,r8,r6
+ st r8,res_ptr,24
+ addu.cio r9,r9,r7
+ st r9,res_ptr,28
+ addu s1_ptr,s1_ptr,32
+ addu s2_ptr,s2_ptr,32
+ addu res_ptr,res_ptr,32
+ bcnd ge0,size,Loop2
+
+Lfin2: addu size,size,8-2
+ bcnd lt0,size,Lend2
+Loope2: ld.d r8,s1_ptr,0
+ ld.d r6,s2_ptr,0
+ addu.cio r8,r8,r6
+ st r8,res_ptr,0
+ addu.cio r9,r9,r7
+ st r9,res_ptr,4
+ subu size,size,2
+ addu s1_ptr,s1_ptr,8
+ addu s2_ptr,s2_ptr,8
+ addu res_ptr,res_ptr,8
+ bcnd ge0,size,Loope2
+Lend2: bb0 0,size,Lret2
+/* Add last limb */
+Ljone: ld r10,s1_ptr,0
+ ld r8,s2_ptr,0
+ addu.cio r6,r10,r8
+ st r6,res_ptr,0
+
+Lret2: jmp.n r1
+ addu.ci r2,r0,r0 ; return carry-out from most sign. limb
diff --git a/gmp/mpn/m88k/mc88110/addmul_1.s b/gmp/mpn/m88k/mc88110/addmul_1.s
new file mode 100644
index 0000000000..321221f23c
--- /dev/null
+++ b/gmp/mpn/m88k/mc88110/addmul_1.s
@@ -0,0 +1,70 @@
+; mc88110 __gmpn_addmul_1 -- Multiply a limb vector with a single limb and
+; store the product in a second limb vector.
+
+; Copyright 1996, 2000 Free Software Foundation, Inc.
+
+; This file is part of the GNU MP Library.
+;
+; The GNU MP Library is free software; you can redistribute it and/or modify
+; it under the terms of either:
+;
+; * the GNU Lesser General Public License as published by the Free
+; Software Foundation; either version 3 of the License, or (at your
+; option) any later version.
+;
+; or
+;
+; * the GNU General Public License as published by the Free Software
+; Foundation; either version 2 of the License, or (at your option) any
+; later version.
+;
+; or both in parallel, as here.
+;
+; The GNU MP Library is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+; for more details.
+;
+; You should have received copies of the GNU General Public License and the
+; GNU Lesser General Public License along with the GNU MP Library. If not,
+; see https://www.gnu.org/licenses/.
+
+
+; INPUT PARAMETERS
+; res_ptr r2
+; s1_ptr r3
+; size r4
+; s2_limb r5
+
+ text
+ align 16
+ global ___gmpn_addmul_1
+___gmpn_addmul_1:
+ lda r3,r3[r4]
+ lda r8,r2[r4] ; RES_PTR in r8 since r2 is retval
+ subu r4,r0,r4
+ addu.co r2,r0,r0 ; r2 = cy = 0
+
+ ld r6,r3[r4]
+ addu r4,r4,1
+ subu r8,r8,4
+ bcnd.n eq0,r4,Lend
+ mulu.d r10,r6,r5
+
+Loop: ld r7,r8[r4]
+ ld r6,r3[r4]
+ addu.cio r9,r11,r2
+ addu.ci r2,r10,r0
+ addu.co r9,r9,r7
+ st r9,r8[r4]
+ addu r4,r4,1
+ mulu.d r10,r6,r5
+ bcnd ne0,r4,Loop
+
+Lend: ld r7,r8,0
+ addu.cio r9,r11,r2
+ addu.ci r2,r10,r0
+ addu.co r9,r9,r7
+ st r9,r8,0
+ jmp.n r1
+ addu.ci r2,r2,r0
diff --git a/gmp/mpn/m88k/mc88110/mul_1.s b/gmp/mpn/m88k/mc88110/mul_1.s
new file mode 100644
index 0000000000..28fd14b77b
--- /dev/null
+++ b/gmp/mpn/m88k/mc88110/mul_1.s
@@ -0,0 +1,68 @@
+; mc88110 __gmpn_mul_1 -- Multiply a limb vector with a single limb and
+; store the product in a second limb vector.
+
+; Copyright 1992, 1994, 1995, 2000 Free Software Foundation, Inc.
+
+; This file is part of the GNU MP Library.
+;
+; The GNU MP Library is free software; you can redistribute it and/or modify
+; it under the terms of either:
+;
+; * the GNU Lesser General Public License as published by the Free
+; Software Foundation; either version 3 of the License, or (at your
+; option) any later version.
+;
+; or
+;
+; * the GNU General Public License as published by the Free Software
+; Foundation; either version 2 of the License, or (at your option) any
+; later version.
+;
+; or both in parallel, as here.
+;
+; The GNU MP Library is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+; for more details.
+;
+; You should have received copies of the GNU General Public License and the
+; GNU Lesser General Public License along with the GNU MP Library. If not,
+; see https://www.gnu.org/licenses/.
+
+
+; INPUT PARAMETERS
+; res_ptr r2
+; s1_ptr r3
+; size r4
+; s2_limb r5
+
+ text
+ align 16
+ global ___gmpn_mul_1
+___gmpn_mul_1:
+ ; Make S1_PTR and RES_PTR point at the end of their blocks
+ ; and negate SIZE.
+ lda r3,r3[r4]
+ lda r8,r2[r4] ; RES_PTR in r8 since r2 is retval
+ subu r4,r0,r4
+
+ addu.co r2,r0,r0 ; r2 = cy = 0
+
+ ld r6,r3[r4]
+ addu r4,r4,1
+ mulu.d r10,r6,r5
+ bcnd.n eq0,r4,Lend
+ subu r8,r8,8
+
+Loop: ld r6,r3[r4]
+ addu.cio r9,r11,r2
+ or r2,r10,r0 ; could be avoided if unrolled
+ addu r4,r4,1
+ mulu.d r10,r6,r5
+ bcnd.n ne0,r4,Loop
+ st r9,r8[r4]
+
+Lend: addu.cio r9,r11,r2
+ st r9,r8,4
+ jmp.n r1
+ addu.ci r2,r10,r0
diff --git a/gmp/mpn/m88k/mc88110/sub_n.S b/gmp/mpn/m88k/mc88110/sub_n.S
new file mode 100644
index 0000000000..f0a8ecb3f0
--- /dev/null
+++ b/gmp/mpn/m88k/mc88110/sub_n.S
@@ -0,0 +1,285 @@
+; mc88110 __gmpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+; store difference in a third limb vector.
+
+; Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
+
+; This file is part of the GNU MP Library.
+;
+; The GNU MP Library is free software; you can redistribute it and/or modify
+; it under the terms of either:
+;
+; * the GNU Lesser General Public License as published by the Free
+; Software Foundation; either version 3 of the License, or (at your
+; option) any later version.
+;
+; or
+;
+; * the GNU General Public License as published by the Free Software
+; Foundation; either version 2 of the License, or (at your option) any
+; later version.
+;
+; or both in parallel, as here.
+;
+; The GNU MP Library is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+; for more details.
+;
+; You should have received copies of the GNU General Public License and the
+; GNU Lesser General Public License along with the GNU MP Library. If not,
+; see https://www.gnu.org/licenses/.
+
+
+; INPUT PARAMETERS
+#define res_ptr r2
+#define s1_ptr r3
+#define s2_ptr r4
+#define size r5
+
+#include "sysdep.h"
+
+ text
+ align 16
+ global C_SYMBOL_NAME(__gmpn_sub_n)
+C_SYMBOL_NAME(__gmpn_sub_n):
+ subu.co r0,r0,r0 ; set cy flag
+ xor r12,s2_ptr,res_ptr
+ bb1 2,r12,L1
+; ** V1a **
+L0: bb0 2,res_ptr,L_v1 ; branch if res_ptr is aligned
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+ ld r10,s1_ptr,0
+ addu s1_ptr,s1_ptr,4
+ ld r8,s2_ptr,0
+ addu s2_ptr,s2_ptr,4
+ subu size,size,1
+ subu.co r6,r10,r8
+ st r6,res_ptr,0
+ addu res_ptr,res_ptr,4
+L_v1: cmp r12,size,2
+ bb1 lt,r12,Lend2
+
+ ld r10,s1_ptr,0
+ ld r12,s1_ptr,4
+ ld.d r8,s2_ptr,0
+ subu size,size,10
+ bcnd lt0,size,Lfin1
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+ align 8
+Loop1: subu size,size,8
+ subu.cio r6,r10,r8
+ ld r10,s1_ptr,8
+ subu.cio r7,r12,r9
+ ld r12,s1_ptr,12
+ ld.d r8,s2_ptr,8
+ st.d r6,res_ptr,0
+ subu.cio r6,r10,r8
+ ld r10,s1_ptr,16
+ subu.cio r7,r12,r9
+ ld r12,s1_ptr,20
+ ld.d r8,s2_ptr,16
+ st.d r6,res_ptr,8
+ subu.cio r6,r10,r8
+ ld r10,s1_ptr,24
+ subu.cio r7,r12,r9
+ ld r12,s1_ptr,28
+ ld.d r8,s2_ptr,24
+ st.d r6,res_ptr,16
+ subu.cio r6,r10,r8
+ ld r10,s1_ptr,32
+ subu.cio r7,r12,r9
+ ld r12,s1_ptr,36
+ addu s1_ptr,s1_ptr,32
+ ld.d r8,s2_ptr,32
+ addu s2_ptr,s2_ptr,32
+ st.d r6,res_ptr,24
+ addu res_ptr,res_ptr,32
+ bcnd ge0,size,Loop1
+
+Lfin1: addu size,size,8-2
+ bcnd lt0,size,Lend1
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1: subu.cio r6,r10,r8
+ ld r10,s1_ptr,8
+ subu.cio r7,r12,r9
+ ld r12,s1_ptr,12
+ ld.d r8,s2_ptr,8
+ st.d r6,res_ptr,0
+ subu size,size,2
+ addu s1_ptr,s1_ptr,8
+ addu s2_ptr,s2_ptr,8
+ addu res_ptr,res_ptr,8
+ bcnd ge0,size,Loope1
+Lend1: subu.cio r6,r10,r8
+ subu.cio r7,r12,r9
+ st.d r6,res_ptr,0
+
+ bb0 0,size,Lret1
+/* Add last limb */
+ ld r10,s1_ptr,8
+ ld r8,s2_ptr,8
+ subu.cio r6,r10,r8
+ st r6,res_ptr,8
+
+Lret1: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
+ jmp.n r1
+ xor r2,r2,1
+
+L1: xor r12,s1_ptr,res_ptr
+ bb1 2,r12,L2
+; ** V1b **
+ bb0 2,res_ptr,L_v1b ; branch if res_ptr is aligned
+/* Add least significant limb separately to align res_ptr and s1_ptr */
+ ld r10,s2_ptr,0
+ addu s2_ptr,s2_ptr,4
+ ld r8,s1_ptr,0
+ addu s1_ptr,s1_ptr,4
+ subu size,size,1
+ subu.co r6,r8,r10
+ st r6,res_ptr,0
+ addu res_ptr,res_ptr,4
+L_v1b: cmp r12,size,2
+ bb1 lt,r12,Lend2
+
+ ld r10,s2_ptr,0
+ ld r12,s2_ptr,4
+ ld.d r8,s1_ptr,0
+ subu size,size,10
+ bcnd lt0,size,Lfin1b
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+ align 8
+Loop1b: subu size,size,8
+ subu.cio r6,r8,r10
+ ld r10,s2_ptr,8
+ subu.cio r7,r9,r12
+ ld r12,s2_ptr,12
+ ld.d r8,s1_ptr,8
+ st.d r6,res_ptr,0
+ subu.cio r6,r8,r10
+ ld r10,s2_ptr,16
+ subu.cio r7,r9,r12
+ ld r12,s2_ptr,20
+ ld.d r8,s1_ptr,16
+ st.d r6,res_ptr,8
+ subu.cio r6,r8,r10
+ ld r10,s2_ptr,24
+ subu.cio r7,r9,r12
+ ld r12,s2_ptr,28
+ ld.d r8,s1_ptr,24
+ st.d r6,res_ptr,16
+ subu.cio r6,r8,r10
+ ld r10,s2_ptr,32
+ subu.cio r7,r9,r12
+ ld r12,s2_ptr,36
+ addu s2_ptr,s2_ptr,32
+ ld.d r8,s1_ptr,32
+ addu s1_ptr,s1_ptr,32
+ st.d r6,res_ptr,24
+ addu res_ptr,res_ptr,32
+ bcnd ge0,size,Loop1b
+
+Lfin1b: addu size,size,8-2
+ bcnd lt0,size,Lend1b
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1b:subu.cio r6,r8,r10
+ ld r10,s2_ptr,8
+ subu.cio r7,r9,r12
+ ld r12,s2_ptr,12
+ ld.d r8,s1_ptr,8
+ st.d r6,res_ptr,0
+ subu size,size,2
+ addu s1_ptr,s1_ptr,8
+ addu s2_ptr,s2_ptr,8
+ addu res_ptr,res_ptr,8
+ bcnd ge0,size,Loope1b
+Lend1b: subu.cio r6,r8,r10
+ subu.cio r7,r9,r12
+ st.d r6,res_ptr,0
+
+ bb0 0,size,Lret1b
+/* Add last limb */
+ ld r10,s2_ptr,8
+ ld r8,s1_ptr,8
+ subu.cio r6,r8,r10
+ st r6,res_ptr,8
+
+Lret1b: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
+ jmp.n r1
+ xor r2,r2,1
+
+; ** V2 **
+/* If we come here, the alignment of s1_ptr and res_ptr as well as the
+ alignment of s2_ptr and res_ptr differ. Since there are only two ways
+ things can be aligned (that we care about) we now know that the alignment
+ of s1_ptr and s2_ptr are the same. */
+
+L2: cmp r12,size,1
+ bb1 eq,r12,Ljone
+ bb0 2,s1_ptr,L_v2 ; branch if s1_ptr is aligned
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+ ld r10,s1_ptr,0
+ addu s1_ptr,s1_ptr,4
+ ld r8,s2_ptr,0
+ addu s2_ptr,s2_ptr,4
+ subu size,size,1
+ subu.co r6,r10,r8
+ st r6,res_ptr,0
+ addu res_ptr,res_ptr,4
+
+L_v2: subu size,size,8
+ bcnd lt0,size,Lfin2
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+ align 8
+Loop2: subu size,size,8
+ ld.d r8,s1_ptr,0
+ ld.d r6,s2_ptr,0
+ subu.cio r8,r8,r6
+ st r8,res_ptr,0
+ subu.cio r9,r9,r7
+ st r9,res_ptr,4
+ ld.d r8,s1_ptr,8
+ ld.d r6,s2_ptr,8
+ subu.cio r8,r8,r6
+ st r8,res_ptr,8
+ subu.cio r9,r9,r7
+ st r9,res_ptr,12
+ ld.d r8,s1_ptr,16
+ ld.d r6,s2_ptr,16
+ subu.cio r8,r8,r6
+ st r8,res_ptr,16
+ subu.cio r9,r9,r7
+ st r9,res_ptr,20
+ ld.d r8,s1_ptr,24
+ ld.d r6,s2_ptr,24
+ subu.cio r8,r8,r6
+ st r8,res_ptr,24
+ subu.cio r9,r9,r7
+ st r9,res_ptr,28
+ addu s1_ptr,s1_ptr,32
+ addu s2_ptr,s2_ptr,32
+ addu res_ptr,res_ptr,32
+ bcnd ge0,size,Loop2
+
+Lfin2: addu size,size,8-2
+ bcnd lt0,size,Lend2
+Loope2: ld.d r8,s1_ptr,0
+ ld.d r6,s2_ptr,0
+ subu.cio r8,r8,r6
+ st r8,res_ptr,0
+ subu.cio r9,r9,r7
+ st r9,res_ptr,4
+ subu size,size,2
+ addu s1_ptr,s1_ptr,8
+ addu s2_ptr,s2_ptr,8
+ addu res_ptr,res_ptr,8
+ bcnd ge0,size,Loope2
+Lend2: bb0 0,size,Lret2
+/* Add last limb */
+Ljone: ld r10,s1_ptr,0
+ ld r8,s2_ptr,0
+ subu.cio r6,r10,r8
+ st r6,res_ptr,0
+
+Lret2: addu.ci r2,r0,r0 ; return carry-out from most sign. limb
+ jmp.n r1
+ xor r2,r2,1
diff --git a/gmp/mpn/m88k/mul_1.s b/gmp/mpn/m88k/mul_1.s
new file mode 100644
index 0000000000..c8abdc0b7f
--- /dev/null
+++ b/gmp/mpn/m88k/mul_1.s
@@ -0,0 +1,136 @@
+; mc88100 __gmpn_mul_1 -- Multiply a limb vector with a single limb and
+; store the product in a second limb vector.
+
+; Copyright 1992, 1994, 1995, 2000 Free Software Foundation, Inc.
+
+; This file is part of the GNU MP Library.
+;
+; The GNU MP Library is free software; you can redistribute it and/or modify
+; it under the terms of either:
+;
+; * the GNU Lesser General Public License as published by the Free
+; Software Foundation; either version 3 of the License, or (at your
+; option) any later version.
+;
+; or
+;
+; * the GNU General Public License as published by the Free Software
+; Foundation; either version 2 of the License, or (at your option) any
+; later version.
+;
+; or both in parallel, as here.
+;
+; The GNU MP Library is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+; for more details.
+;
+; You should have received copies of the GNU General Public License and the
+; GNU Lesser General Public License along with the GNU MP Library. If not,
+; see https://www.gnu.org/licenses/.
+
+
+; INPUT PARAMETERS
+; res_ptr r2
+; s1_ptr r3
+; size r4
+; s2_limb r5
+
+; Common overhead is about 11 cycles/invocation.
+
+; The speed for S2_LIMB >= 0x10000 is approximately 21 cycles/limb. (The
+; pipeline stalls 2 cycles due to WB contention.)
+
+; The speed for S2_LIMB < 0x10000 is approximately 16 cycles/limb. (The
+; pipeline stalls 2 cycles due to WB contention and 1 cycle due to latency.)
+
+; To enhance speed:
+; 1. Unroll main loop 4-8 times.
+; 2. Schedule code to avoid WB contention. It might be tempting to move the
+; ld instruction in the loops down to save 2 cycles (less WB contention),
+; but that looses because the ultimate value will be read from outside
+; the allocated space. But if we handle the ultimate multiplication in
+; the tail, we can do this.
+; 3. Make the multiplication with less instructions. I think the code for
+; (S2_LIMB >= 0x10000) is not minimal.
+; With these techniques the (S2_LIMB >= 0x10000) case would run in 17 or
+; less cycles/limb; the (S2_LIMB < 0x10000) case would run in 11
+; cycles/limb. (Assuming infinite unrolling.)
+
+ text
+ align 16
+ global ___gmpn_mul_1
+___gmpn_mul_1:
+
+ ; Make S1_PTR and RES_PTR point at the end of their blocks
+ ; and negate SIZE.
+ lda r3,r3[r4]
+ lda r6,r2[r4] ; RES_PTR in r6 since r2 is retval
+ subu r4,r0,r4
+
+ addu.co r2,r0,r0 ; r2 = cy = 0
+ ld r9,r3[r4]
+ mask r7,r5,0xffff ; r7 = lo(S2_LIMB)
+ extu r8,r5,16 ; r8 = hi(S2_LIMB)
+ bcnd.n eq0,r8,Lsmall ; jump if (hi(S2_LIMB) == 0)
+ subu r6,r6,4
+
+; General code for any value of S2_LIMB.
+
+ ; Make a stack frame and save r25 and r26
+ subu r31,r31,16
+ st.d r25,r31,8
+
+ ; Enter the loop in the middle
+ br.n L1
+ addu r4,r4,1
+
+Loop: ld r9,r3[r4]
+ st r26,r6[r4]
+; bcnd ne0,r0,0 ; bubble
+ addu r4,r4,1
+L1: mul r26,r9,r5 ; low word of product mul_1 WB ld
+ mask r12,r9,0xffff ; r12 = lo(s1_limb) mask_1
+ mul r11,r12,r7 ; r11 = prod_0 mul_2 WB mask_1
+ mul r10,r12,r8 ; r10 = prod_1a mul_3
+ extu r13,r9,16 ; r13 = hi(s1_limb) extu_1 WB mul_1
+ mul r12,r13,r7 ; r12 = prod_1b mul_4 WB extu_1
+ mul r25,r13,r8 ; r25 = prod_2 mul_5 WB mul_2
+ extu r11,r11,16 ; r11 = hi(prod_0) extu_2 WB mul_3
+ addu r10,r10,r11 ; addu_1 WB extu_2
+; bcnd ne0,r0,0 ; bubble WB addu_1
+ addu.co r10,r10,r12 ; WB mul_4
+ mask.u r10,r10,0xffff ; move the 16 most significant bits...
+ addu.ci r10,r10,r0 ; ...to the low half of the word...
+ rot r10,r10,16 ; ...and put carry in pos 16.
+ addu.co r26,r26,r2 ; add old carry limb
+ bcnd.n ne0,r4,Loop
+ addu.ci r2,r25,r10 ; compute new carry limb
+
+ st r26,r6[r4]
+ ld.d r25,r31,8
+ jmp.n r1
+ addu r31,r31,16
+
+; Fast code for S2_LIMB < 0x10000
+Lsmall:
+ ; Enter the loop in the middle
+ br.n SL1
+ addu r4,r4,1
+
+SLoop: ld r9,r3[r4] ;
+ st r8,r6[r4] ;
+ addu r4,r4,1 ;
+SL1: mul r8,r9,r5 ; low word of product
+ mask r12,r9,0xffff ; r12 = lo(s1_limb)
+ extu r13,r9,16 ; r13 = hi(s1_limb)
+ mul r11,r12,r7 ; r11 = prod_0
+ mul r12,r13,r7 ; r12 = prod_1b
+ addu.cio r8,r8,r2 ; add old carry limb
+ extu r10,r11,16 ; r11 = hi(prod_0)
+ addu r10,r10,r12 ;
+ bcnd.n ne0,r4,SLoop
+ extu r2,r10,16 ; r2 = new carry limb
+
+ jmp.n r1
+ st r8,r6[r4]
diff --git a/gmp/mpn/m88k/sub_n.s b/gmp/mpn/m88k/sub_n.s
new file mode 100644
index 0000000000..2bd8f09ca3
--- /dev/null
+++ b/gmp/mpn/m88k/sub_n.s
@@ -0,0 +1,115 @@
+; mc88100 mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+; store difference in a third limb vector.
+
+; Copyright 1992, 1994, 1996, 2000 Free Software Foundation, Inc.
+
+; This file is part of the GNU MP Library.
+;
+; The GNU MP Library is free software; you can redistribute it and/or modify
+; it under the terms of either:
+;
+; * the GNU Lesser General Public License as published by the Free
+; Software Foundation; either version 3 of the License, or (at your
+; option) any later version.
+;
+; or
+;
+; * the GNU General Public License as published by the Free Software
+; Foundation; either version 2 of the License, or (at your option) any
+; later version.
+;
+; or both in parallel, as here.
+;
+; The GNU MP Library is distributed in the hope that it will be useful, but
+; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+; for more details.
+;
+; You should have received copies of the GNU General Public License and the
+; GNU Lesser General Public License along with the GNU MP Library. If not,
+; see https://www.gnu.org/licenses/.
+
+
+; INPUT PARAMETERS
+; res_ptr r2
+; s1_ptr r3
+; s2_ptr r4
+; size r5
+
+; This code has been optimized to run one instruction per clock, avoiding
+; load stalls and writeback contention. As a result, the instruction
+; order is not always natural.
+
+; The speed is about 4.6 clocks/limb + 18 clocks/limb-vector on an 88100,
+; but on the 88110, it seems to run much slower, 6.6 clocks/limb.
+
+ text
+ align 16
+ global ___gmpn_sub_n
+___gmpn_sub_n:
+ ld r6,r3,0 ; read first limb from s1_ptr
+ extu r10,r5,3
+ ld r7,r4,0 ; read first limb from s2_ptr
+
+ subu r5,r0,r5
+ mak r5,r5,3<4>
+ bcnd.n eq0,r5,Lzero
+ subu.co r0,r0,r0 ; initialize carry
+
+ or r12,r0,lo16(Lbase)
+ or.u r12,r12,hi16(Lbase)
+ addu r12,r12,r5 ; r12 is address for entering in loop
+
+ extu r5,r5,2 ; divide by 4
+ subu r2,r2,r5 ; adjust res_ptr
+ subu r3,r3,r5 ; adjust s1_ptr
+ subu r4,r4,r5 ; adjust s2_ptr
+
+ or r8,r6,r0
+
+ jmp.n r12
+ or r9,r7,r0
+
+Loop: addu r3,r3,32
+ st r8,r2,28
+ addu r4,r4,32
+ ld r6,r3,0
+ addu r2,r2,32
+ ld r7,r4,0
+Lzero: subu r10,r10,1 ; subtract 0 + 8r limbs (adj loop cnt)
+Lbase: ld r8,r3,4
+ subu.cio r6,r6,r7
+ ld r9,r4,4
+ st r6,r2,0
+ ld r6,r3,8 ; subtract 7 + 8r limbs
+ subu.cio r8,r8,r9
+ ld r7,r4,8
+ st r8,r2,4
+ ld r8,r3,12 ; subtract 6 + 8r limbs
+ subu.cio r6,r6,r7
+ ld r9,r4,12
+ st r6,r2,8
+ ld r6,r3,16 ; subtract 5 + 8r limbs
+ subu.cio r8,r8,r9
+ ld r7,r4,16
+ st r8,r2,12
+ ld r8,r3,20 ; subtract 4 + 8r limbs
+ subu.cio r6,r6,r7
+ ld r9,r4,20
+ st r6,r2,16
+ ld r6,r3,24 ; subtract 3 + 8r limbs
+ subu.cio r8,r8,r9
+ ld r7,r4,24
+ st r8,r2,20
+ ld r8,r3,28 ; subtract 2 + 8r limbs
+ subu.cio r6,r6,r7
+ ld r9,r4,28
+ st r6,r2,24
+ bcnd.n ne0,r10,Loop ; subtract 1 + 8r limbs
+ subu.cio r8,r8,r9
+
+ st r8,r2,28 ; store most significant limb
+
+ addu.ci r2,r0,r0 ; return carry-out from most sign. limb
+ jmp.n r1
+ xor r2,r2,1
diff --git a/gmp/mpn/minithres/gmp-mparam.h b/gmp/mpn/minithres/gmp-mparam.h
new file mode 100644
index 0000000000..1b8f311516
--- /dev/null
+++ b/gmp/mpn/minithres/gmp-mparam.h
@@ -0,0 +1,109 @@
+/* Minimal values gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000, 2006, 2008-2010, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* The values in this file are not currently minimal.
+ Trimming them further would be good. */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 2
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 2
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 3
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 4
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 1
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 3
+
+#define MUL_TOOM22_THRESHOLD 8
+#define MUL_TOOM33_THRESHOLD 20
+#define MUL_TOOM44_THRESHOLD 24
+#define MUL_TOOM6H_THRESHOLD 70 /* FIXME */
+#define MUL_TOOM8H_THRESHOLD 86
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 50 /* FIXME */
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 50 /* FIXME */
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 50 /* FIXME */
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 50 /* FIXME */
+
+#define SQR_BASECASE_THRESHOLD 0
+#define SQR_TOOM2_THRESHOLD 8
+#define SQR_TOOM3_THRESHOLD 20
+#define SQR_TOOM4_THRESHOLD 24
+#define SQR_TOOM6H_THRESHOLD 70 /* FIXME */
+#define SQR_TOOM8H_THRESHOLD 86
+
+#define MULMOD_BNM1_THRESHOLD 10
+#define SQRMOD_BNM1_THRESHOLD 10
+
+#define MUL_FFT_TABLE {64, 256, 1024, 4096, 8192, 65536, 0}
+#define MUL_FFT_MODF_THRESHOLD 65
+#define MUL_FFT_THRESHOLD 200
+
+#define SQR_FFT_TABLE {64, 256, 1024, 4096, 8192, 65536, 0}
+#define SQR_FFT_MODF_THRESHOLD 65
+#define SQR_FFT_THRESHOLD 200
+
+#define MULLO_BASECASE_THRESHOLD 0
+#define MULLO_DC_THRESHOLD 2
+#define MULLO_MUL_N_THRESHOLD 4
+
+#define DC_DIV_QR_THRESHOLD 6
+#define DC_DIVAPPR_Q_THRESHOLD 6
+#define DC_BDIV_QR_THRESHOLD 4
+#define DC_BDIV_Q_THRESHOLD 4
+
+#define INV_MULMOD_BNM1_THRESHOLD 2
+#define INV_NEWTON_THRESHOLD 6
+#define INV_APPR_THRESHOLD 4
+
+#define BINV_NEWTON_THRESHOLD 6
+#define REDC_1_TO_REDC_N_THRESHOLD 9
+
+#define MU_DIV_QR_THRESHOLD 8
+#define MU_DIVAPPR_Q_THRESHOLD 8
+#define MUPI_DIV_QR_THRESHOLD 8
+#define MU_BDIV_QR_THRESHOLD 8
+#define MU_BDIV_Q_THRESHOLD 8
+
+#define MATRIX22_STRASSEN_THRESHOLD 2
+#define HGCD_THRESHOLD 10
+#define GCD_DC_THRESHOLD 20
+#define GCDEXT_SCHOENHAGE_THRESHOLD 20
+#define JACOBI_BASE_METHOD 1
+
+#define GET_STR_DC_THRESHOLD 4
+#define GET_STR_PRECOMPUTE_THRESHOLD 10
+#define SET_STR_THRESHOLD 64
+#define SET_STR_PRECOMPUTE_THRESHOLD 100
+
+#define FAC_ODD_THRESHOLD 0 /* always */
+#define FAC_DSC_THRESHOLD 70
diff --git a/gmp/mpn/mips32/add_n.asm b/gmp/mpn/mips32/add_n.asm
new file mode 100644
index 0000000000..e7d4c48f48
--- /dev/null
+++ b/gmp/mpn/mips32/add_n.asm
@@ -0,0 +1,124 @@
+dnl MIPS32 mpn_add_n -- Add two limb vectors of the same length > 0 and store
+dnl sum in a third limb vector.
+
+dnl Copyright 1995, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C s2_ptr $6
+C size $7
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+
+ lw $10,0($5)
+ lw $11,0($6)
+
+ addiu $7,$7,-1
+ and $9,$7,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ subu $7,$7,$9
+
+.Loop0: addiu $9,$9,-1
+ lw $12,4($5)
+ addu $11,$11,$2
+ lw $13,4($6)
+ sltu $8,$11,$2
+ addu $11,$10,$11
+ sltu $2,$11,$10
+ sw $11,0($4)
+ or $2,$2,$8
+
+ addiu $5,$5,4
+ addiu $6,$6,4
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ addiu $4,$4,4
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: addiu $7,$7,-4
+
+ lw $12,4($5)
+ addu $11,$11,$2
+ lw $13,4($6)
+ sltu $8,$11,$2
+ addu $11,$10,$11
+ sltu $2,$11,$10
+ sw $11,0($4)
+ or $2,$2,$8
+
+ lw $10,8($5)
+ addu $13,$13,$2
+ lw $11,8($6)
+ sltu $8,$13,$2
+ addu $13,$12,$13
+ sltu $2,$13,$12
+ sw $13,4($4)
+ or $2,$2,$8
+
+ lw $12,12($5)
+ addu $11,$11,$2
+ lw $13,12($6)
+ sltu $8,$11,$2
+ addu $11,$10,$11
+ sltu $2,$11,$10
+ sw $11,8($4)
+ or $2,$2,$8
+
+ lw $10,16($5)
+ addu $13,$13,$2
+ lw $11,16($6)
+ sltu $8,$13,$2
+ addu $13,$12,$13
+ sltu $2,$13,$12
+ sw $13,12($4)
+ or $2,$2,$8
+
+ addiu $5,$5,16
+ addiu $6,$6,16
+
+ bne $7,$0,.Loop
+ addiu $4,$4,16
+
+.Lend: addu $11,$11,$2
+ sltu $8,$11,$2
+ addu $11,$10,$11
+ sltu $2,$11,$10
+ sw $11,0($4)
+ j $31
+ or $2,$2,$8
+EPILOGUE(mpn_add_n)
diff --git a/gmp/mpn/mips32/addmul_1.asm b/gmp/mpn/mips32/addmul_1.asm
new file mode 100644
index 0000000000..9aa9e163ce
--- /dev/null
+++ b/gmp/mpn/mips32/addmul_1.asm
@@ -0,0 +1,101 @@
+dnl MIPS32 mpn_addmul_1 -- Multiply a limb vector with a single limb and add
+dnl the product to a second limb vector.
+
+dnl Copyright 1992, 1994, 1996, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C size $6
+C s2_limb $7
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+
+C feed-in phase 0
+ lw $8,0($5)
+
+C feed-in phase 1
+ addiu $5,$5,4
+ multu $8,$7
+
+ addiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 C zero cy2
+
+ addiu $6,$6,-1
+ beq $6,$0,$LC1
+ lw $8,0($5) C load new s1 limb as early as possible
+
+Loop: lw $10,0($4)
+ mflo $3
+ mfhi $9
+ addiu $5,$5,4
+ addu $3,$3,$2 C add old carry limb to low product limb
+ multu $8,$7
+ lw $8,0($5) C load new s1 limb as early as possible
+ addiu $6,$6,-1 C decrement loop counter
+ sltu $2,$3,$2 C carry from previous addition -> $2
+ addu $3,$10,$3
+ sltu $10,$3,$10
+ addu $2,$2,$10
+ sw $3,0($4)
+ addiu $4,$4,4
+ bne $6,$0,Loop
+ addu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 1
+$LC1: lw $10,0($4)
+ mflo $3
+ mfhi $9
+ addu $3,$3,$2
+ sltu $2,$3,$2
+ multu $8,$7
+ addu $3,$10,$3
+ sltu $10,$3,$10
+ addu $2,$2,$10
+ sw $3,0($4)
+ addiu $4,$4,4
+ addu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 0
+$LC0: lw $10,0($4)
+ mflo $3
+ mfhi $9
+ addu $3,$3,$2
+ sltu $2,$3,$2
+ addu $3,$10,$3
+ sltu $10,$3,$10
+ addu $2,$2,$10
+ sw $3,0($4)
+ j $31
+ addu $2,$9,$2 C add high product limb and carry from addition
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/mips32/gmp-mparam.h b/gmp/mpn/mips32/gmp-mparam.h
new file mode 100644
index 0000000000..986135df96
--- /dev/null
+++ b/gmp/mpn/mips32/gmp-mparam.h
@@ -0,0 +1,72 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* Generated by tuneup.c, 2002-02-20, gcc 2.95 (R3000) */
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 50
+
+#define SQR_BASECASE_THRESHOLD 7
+#define SQR_TOOM2_THRESHOLD 57
+#define SQR_TOOM3_THRESHOLD 78
+
+#define DIV_SB_PREINV_THRESHOLD 0 /* always */
+#define DIV_DC_THRESHOLD 57
+#define POWM_THRESHOLD 78
+
+#define GCD_ACCEL_THRESHOLD 3
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define USE_PREINV_DIVREM_1 1
+#define USE_PREINV_MOD_1 1
+#define DIVREM_2_THRESHOLD 0 /* always */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always */
+
+#define GET_STR_DC_THRESHOLD 19
+#define GET_STR_PRECOMPUTE_THRESHOLD 25
+#define SET_STR_THRESHOLD 309
+
+#define MUL_FFT_TABLE { 496, 1056, 2176, 5632, 14336, 40960, 0 }
+#define MUL_FFT_MODF_THRESHOLD 624
+#define MUL_FFT_THRESHOLD 5888
+
+#define SQR_FFT_TABLE { 496, 1184, 2176, 5632, 14336, 40960, 0 }
+#define SQR_FFT_MODF_THRESHOLD 560
+#define SQR_FFT_THRESHOLD 5376
diff --git a/gmp/mpn/mips32/lshift.asm b/gmp/mpn/mips32/lshift.asm
new file mode 100644
index 0000000000..6a58bb4579
--- /dev/null
+++ b/gmp/mpn/mips32/lshift.asm
@@ -0,0 +1,99 @@
+dnl MIPS32 mpn_lshift -- Left shift.
+
+dnl Copyright 1995, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C src_ptr $5
+C size $6
+C cnt $7
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ sll $2,$6,2
+ addu $5,$5,$2 C make r5 point at end of src
+ lw $10,-4($5) C load first limb
+ subu $13,$0,$7
+ addu $4,$4,$2 C make r4 point at end of res
+ addiu $6,$6,-1
+ and $9,$6,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ srl $2,$10,$13 C compute function result
+
+ subu $6,$6,$9
+
+.Loop0: lw $3,-8($5)
+ addiu $4,$4,-4
+ addiu $5,$5,-4
+ addiu $9,$9,-1
+ sll $11,$10,$7
+ srl $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sw $8,0($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: lw $3,-8($5)
+ addiu $4,$4,-16
+ addiu $6,$6,-4
+ sll $11,$10,$7
+ srl $12,$3,$13
+
+ lw $10,-12($5)
+ sll $14,$3,$7
+ or $8,$11,$12
+ sw $8,12($4)
+ srl $9,$10,$13
+
+ lw $3,-16($5)
+ sll $11,$10,$7
+ or $8,$14,$9
+ sw $8,8($4)
+ srl $12,$3,$13
+
+ lw $10,-20($5)
+ sll $14,$3,$7
+ or $8,$11,$12
+ sw $8,4($4)
+ srl $9,$10,$13
+
+ addiu $5,$5,-16
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sw $8,0($4)
+
+.Lend: sll $8,$10,$7
+ j $31
+ sw $8,-4($4)
+EPILOGUE(mpn_lshift)
diff --git a/gmp/mpn/mips32/mips-defs.m4 b/gmp/mpn/mips32/mips-defs.m4
new file mode 100644
index 0000000000..5fa89eca35
--- /dev/null
+++ b/gmp/mpn/mips32/mips-defs.m4
@@ -0,0 +1,80 @@
+divert(-1)
+
+dnl m4 macros for MIPS assembly code (both 32-bit and 64-bit).
+
+
+dnl Copyright 2000-2002 Free Software Foundation, Inc.
+dnl
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Usage: ASM_START()
+define(`ASM_START',
+m4_assert_numargs(0)
+` .set noreorder
+ .set nomacro')
+
+dnl Usage: X(value)
+define(`X',
+m4_assert_numargs(1)
+`0x$1')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+` .text
+ .align 4
+ .globl $1
+ .ent $1
+$1:')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+` .end $1')
+
+
+dnl Usage: r0 ... r31
+dnl f0 ... f31
+dnl
+dnl Map register names r0 to $0, and f0 to $f0, etc.
+dnl
+dnl defreg() is used to protect the $ in $0 (otherwise it would represent a
+dnl macro argument). Double quoting is used to protect the f0 in $f0
+dnl (otherwise it would be an infinite recursion).
+
+forloop(i,0,31,`defreg(`r'i,$i)')
+forloop(i,0,31,`deflit(`f'i,``$f''i)')
+
+
+dnl Usage: ASM_END()
+define(`ASM_END',
+m4_assert_numargs(0)
+)
+
+divert
diff --git a/gmp/mpn/mips32/mips.m4 b/gmp/mpn/mips32/mips.m4
new file mode 100644
index 0000000000..8b49e575e4
--- /dev/null
+++ b/gmp/mpn/mips32/mips.m4
@@ -0,0 +1,80 @@
+divert(-1)
+
+dnl m4 macros for MIPS assembly code.
+
+
+dnl Copyright 2000-2002 Free Software Foundation, Inc.
+dnl
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Usage: ASM_START()
+define(`ASM_START',
+m4_assert_numargs(0)
+` .set noreorder
+ .set nomacro')
+
+dnl Usage: X(value)
+define(`X',
+m4_assert_numargs(1)
+`0x$1')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+` .text
+ .align 4
+ .globl $1
+ .ent $1
+$1:')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+` .end $1')
+
+
+dnl Usage: r0 ... r31
+dnl f0 ... f31
+dnl
+dnl Map register names r0 to $0, and f0 to $f0, etc.
+dnl
+dnl defreg() is used to protect the $ in $0 (otherwise it would represent a
+dnl macro argument). Double quoting is used to protect the f0 in $f0
+dnl (otherwise it would be an infinite recursion).
+
+forloop(i,0,31,`defreg(`r'i,$i)')
+forloop(i,0,31,`deflit(`f'i,``$f''i)')
+
+
+dnl Usage: ASM_END()
+define(`ASM_END',
+m4_assert_numargs(0)
+)
+
+divert
diff --git a/gmp/mpn/mips32/mul_1.asm b/gmp/mpn/mips32/mul_1.asm
new file mode 100644
index 0000000000..4337bc2bd4
--- /dev/null
+++ b/gmp/mpn/mips32/mul_1.asm
@@ -0,0 +1,89 @@
+dnl MIPS32 mpn_mul_1 -- Multiply a limb vector with a single limb and store
+dnl the product in a second limb vector.
+
+dnl Copyright 1992, 1994, 1996, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C size $6
+C s2_limb $7
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+
+C feed-in phase 0
+ lw $8,0($5)
+
+C feed-in phase 1
+ addiu $5,$5,4
+ multu $8,$7
+
+ addiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 C zero cy2
+
+ addiu $6,$6,-1
+ beq $6,$0,$LC1
+ lw $8,0($5) C load new s1 limb as early as possible
+
+Loop: mflo $10
+ mfhi $9
+ addiu $5,$5,4
+ addu $10,$10,$2 C add old carry limb to low product limb
+ multu $8,$7
+ lw $8,0($5) C load new s1 limb as early as possible
+ addiu $6,$6,-1 C decrement loop counter
+ sltu $2,$10,$2 C carry from previous addition -> $2
+ sw $10,0($4)
+ addiu $4,$4,4
+ bne $6,$0,Loop
+ addu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 1
+$LC1: mflo $10
+ mfhi $9
+ addu $10,$10,$2
+ sltu $2,$10,$2
+ multu $8,$7
+ sw $10,0($4)
+ addiu $4,$4,4
+ addu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 0
+$LC0: mflo $10
+ mfhi $9
+ addu $10,$10,$2
+ sltu $2,$10,$2
+ sw $10,0($4)
+ j $31
+ addu $2,$9,$2 C add high product limb and carry from addition
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/mips32/rshift.asm b/gmp/mpn/mips32/rshift.asm
new file mode 100644
index 0000000000..4b54510408
--- /dev/null
+++ b/gmp/mpn/mips32/rshift.asm
@@ -0,0 +1,96 @@
+dnl MIPS32 mpn_rshift -- Right shift.
+
+dnl Copyright 1995, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C src_ptr $5
+C size $6
+C cnt $7
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ lw $10,0($5) C load first limb
+ subu $13,$0,$7
+ addiu $6,$6,-1
+ and $9,$6,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ sll $2,$10,$13 C compute function result
+
+ subu $6,$6,$9
+
+.Loop0: lw $3,4($5)
+ addiu $4,$4,4
+ addiu $5,$5,4
+ addiu $9,$9,-1
+ srl $11,$10,$7
+ sll $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sw $8,-4($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: lw $3,4($5)
+ addiu $4,$4,16
+ addiu $6,$6,-4
+ srl $11,$10,$7
+ sll $12,$3,$13
+
+ lw $10,8($5)
+ srl $14,$3,$7
+ or $8,$11,$12
+ sw $8,-16($4)
+ sll $9,$10,$13
+
+ lw $3,12($5)
+ srl $11,$10,$7
+ or $8,$14,$9
+ sw $8,-12($4)
+ sll $12,$3,$13
+
+ lw $10,16($5)
+ srl $14,$3,$7
+ or $8,$11,$12
+ sw $8,-8($4)
+ sll $9,$10,$13
+
+ addiu $5,$5,16
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sw $8,-4($4)
+
+.Lend: srl $8,$10,$7
+ j $31
+ sw $8,0($4)
+EPILOGUE(mpn_rshift)
diff --git a/gmp/mpn/mips32/sub_n.asm b/gmp/mpn/mips32/sub_n.asm
new file mode 100644
index 0000000000..a962ce1b79
--- /dev/null
+++ b/gmp/mpn/mips32/sub_n.asm
@@ -0,0 +1,123 @@
+dnl MIPS32 mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+dnl store difference in a third limb vector.
+
+dnl Copyright 1995, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C s2_ptr $6
+C size $7
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ lw $10,0($5)
+ lw $11,0($6)
+
+ addiu $7,$7,-1
+ and $9,$7,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ subu $7,$7,$9
+
+.Loop0: addiu $9,$9,-1
+ lw $12,4($5)
+ addu $11,$11,$2
+ lw $13,4($6)
+ sltu $8,$11,$2
+ subu $11,$10,$11
+ sltu $2,$10,$11
+ sw $11,0($4)
+ or $2,$2,$8
+
+ addiu $5,$5,4
+ addiu $6,$6,4
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ addiu $4,$4,4
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: addiu $7,$7,-4
+
+ lw $12,4($5)
+ addu $11,$11,$2
+ lw $13,4($6)
+ sltu $8,$11,$2
+ subu $11,$10,$11
+ sltu $2,$10,$11
+ sw $11,0($4)
+ or $2,$2,$8
+
+ lw $10,8($5)
+ addu $13,$13,$2
+ lw $11,8($6)
+ sltu $8,$13,$2
+ subu $13,$12,$13
+ sltu $2,$12,$13
+ sw $13,4($4)
+ or $2,$2,$8
+
+ lw $12,12($5)
+ addu $11,$11,$2
+ lw $13,12($6)
+ sltu $8,$11,$2
+ subu $11,$10,$11
+ sltu $2,$10,$11
+ sw $11,8($4)
+ or $2,$2,$8
+
+ lw $10,16($5)
+ addu $13,$13,$2
+ lw $11,16($6)
+ sltu $8,$13,$2
+ subu $13,$12,$13
+ sltu $2,$12,$13
+ sw $13,12($4)
+ or $2,$2,$8
+
+ addiu $5,$5,16
+ addiu $6,$6,16
+
+ bne $7,$0,.Loop
+ addiu $4,$4,16
+
+.Lend: addu $11,$11,$2
+ sltu $8,$11,$2
+ subu $11,$10,$11
+ sltu $2,$10,$11
+ sw $11,0($4)
+ j $31
+ or $2,$2,$8
+EPILOGUE(mpn_sub_n)
diff --git a/gmp/mpn/mips32/submul_1.asm b/gmp/mpn/mips32/submul_1.asm
new file mode 100644
index 0000000000..335722b4e5
--- /dev/null
+++ b/gmp/mpn/mips32/submul_1.asm
@@ -0,0 +1,101 @@
+dnl MIPS32 mpn_submul_1 -- Multiply a limb vector with a single limb and
+dnl subtract the product from a second limb vector.
+
+dnl Copyright 1992, 1994, 1996, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C size $6
+C s2_limb $7
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+
+C feed-in phase 0
+ lw $8,0($5)
+
+C feed-in phase 1
+ addiu $5,$5,4
+ multu $8,$7
+
+ addiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 C zero cy2
+
+ addiu $6,$6,-1
+ beq $6,$0,$LC1
+ lw $8,0($5) C load new s1 limb as early as possible
+
+Loop: lw $10,0($4)
+ mflo $3
+ mfhi $9
+ addiu $5,$5,4
+ addu $3,$3,$2 C add old carry limb to low product limb
+ multu $8,$7
+ lw $8,0($5) C load new s1 limb as early as possible
+ addiu $6,$6,-1 C decrement loop counter
+ sltu $2,$3,$2 C carry from previous addition -> $2
+ subu $3,$10,$3
+ sgtu $10,$3,$10
+ addu $2,$2,$10
+ sw $3,0($4)
+ addiu $4,$4,4
+ bne $6,$0,Loop
+ addu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 1
+$LC1: lw $10,0($4)
+ mflo $3
+ mfhi $9
+ addu $3,$3,$2
+ sltu $2,$3,$2
+ multu $8,$7
+ subu $3,$10,$3
+ sgtu $10,$3,$10
+ addu $2,$2,$10
+ sw $3,0($4)
+ addiu $4,$4,4
+ addu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 0
+$LC0: lw $10,0($4)
+ mflo $3
+ mfhi $9
+ addu $3,$3,$2
+ sltu $2,$3,$2
+ subu $3,$10,$3
+ sgtu $10,$3,$10
+ addu $2,$2,$10
+ sw $3,0($4)
+ j $31
+ addu $2,$9,$2 C add high product limb and carry from addition
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/mips32/umul.asm b/gmp/mpn/mips32/umul.asm
new file mode 100644
index 0000000000..1ced0eb883
--- /dev/null
+++ b/gmp/mpn/mips32/umul.asm
@@ -0,0 +1,45 @@
+dnl MIPS32 umul_ppmm -- longlong.h support.
+
+dnl Copyright 1999, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C plp $4
+C u $5
+C v $6
+
+ASM_START()
+PROLOGUE(mpn_umul_ppmm)
+ multu $5,$6
+ mflo $3
+ mfhi $2
+ j $31
+ sw $3,0($4)
+EPILOGUE(mpn_umul_ppmm)
diff --git a/gmp/mpn/mips64/README b/gmp/mpn/mips64/README
new file mode 100644
index 0000000000..7ddd0e572c
--- /dev/null
+++ b/gmp/mpn/mips64/README
@@ -0,0 +1,60 @@
+Copyright 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+This directory contains mpn functions optimized for MIPS3. Example of
+processors that implement MIPS3 are R4000, R4400, R4600, R4700, and R8000.
+
+RELEVANT OPTIMIZATION ISSUES
+
+1. On the R4000 and R4400, branches, both the plain and the "likely" ones,
+ take 3 cycles to execute. (The fastest possible loop will take 4 cycles,
+ because of the delay insn.)
+
+ On the R4600, branches takes a single cycle
+
+ On the R8000, branches often take no noticeable cycles, as they are
+ executed in a separate function unit..
+
+2. The R4000 and R4400 have a load latency of 4 cycles.
+
+3. On the R4000 and R4400, multiplies take a data-dependent number of
+ cycles, contrary to the SGI documentation. There seem to be 3 or 4
+ possible latencies.
+
+4. The R1x000 processors can issue one floating-point operation, two integer
+ operations, and one memory operation per cycle. The FPU has very short
+ latencies, while the integer multiply unit is non-pipelined. We should
+ therefore write fp based mpn_Xmul_1.
+
+STATUS
+
+Good...
diff --git a/gmp/mpn/mips64/add_n.asm b/gmp/mpn/mips64/add_n.asm
new file mode 100644
index 0000000000..6856407efd
--- /dev/null
+++ b/gmp/mpn/mips64/add_n.asm
@@ -0,0 +1,134 @@
+dnl MIPS64 mpn_add_n -- Add two limb vectors of the same length > 0 and store
+dnl sum in a third limb vector.
+
+dnl Copyright 1995, 2000-2002, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C s2_ptr $6
+C size $7
+
+ASM_START()
+PROLOGUE(mpn_add_nc)
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ move $2,$8
+ b .Loop0
+ dsubu $7,$7,$9
+EPILOGUE()
+PROLOGUE(mpn_add_n)
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ daddu $11,$11,$10
+ ld $13,8($6)
+ sltu $8,$11,$10
+ daddu $11,$11,$2
+ sltu $2,$11,$2
+ sd $11,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ daddu $13,$13,$12
+ ld $11,16($6)
+ sltu $8,$13,$12
+ daddu $13,$13,$2
+ sltu $2,$13,$2
+ sd $13,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ daddu $11,$11,$10
+ ld $13,24($6)
+ sltu $8,$11,$10
+ daddu $11,$11,$2
+ sltu $2,$11,$2
+ sd $11,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ daddu $13,$13,$12
+ ld $11,32($6)
+ sltu $8,$13,$12
+ daddu $13,$13,$2
+ sltu $2,$13,$2
+ sd $13,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+EPILOGUE()
diff --git a/gmp/mpn/mips64/addmul_1.asm b/gmp/mpn/mips64/addmul_1.asm
new file mode 100644
index 0000000000..8ff0976e25
--- /dev/null
+++ b/gmp/mpn/mips64/addmul_1.asm
@@ -0,0 +1,101 @@
+dnl MIPS64 mpn_addmul_1 -- Multiply a limb vector with a single limb and add
+dnl the product to a second limb vector.
+
+dnl Copyright 1992, 1994, 1995, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C size $6
+C s2_limb $7
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+
+C feed-in phase 0
+ ld $8,0($5)
+
+C feed-in phase 1
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 C zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) C load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 C add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) C load new s1 limb as early as possible
+ daddiu $6,$6,-1 C decrement loop counter
+ sltu $2,$3,$2 C carry from previous addition -> $2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 1
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 0
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 C add high product limb and carry from addition
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/mips64/gmp-mparam.h b/gmp/mpn/mips64/gmp-mparam.h
new file mode 100644
index 0000000000..b7fcf24a41
--- /dev/null
+++ b/gmp/mpn/mips64/gmp-mparam.h
@@ -0,0 +1,72 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+
+/* Generated by tuneup.c, 2004-02-10, gcc 3.2 & MIPSpro C 7.2.1 (R1x000) */
+
+#define MUL_TOOM22_THRESHOLD 16
+#define MUL_TOOM33_THRESHOLD 89
+
+#define SQR_BASECASE_THRESHOLD 6
+#define SQR_TOOM2_THRESHOLD 32
+#define SQR_TOOM3_THRESHOLD 98
+
+#define DIV_SB_PREINV_THRESHOLD 0 /* always */
+#define DIV_DC_THRESHOLD 53
+#define POWM_THRESHOLD 61
+
+#define HGCD_THRESHOLD 116
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 492
+#define JACOBI_BASE_METHOD 2
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define USE_PREINV_DIVREM_1 1
+#define USE_PREINV_MOD_1 1
+#define DIVREM_2_THRESHOLD 0 /* always */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always */
+
+#define GET_STR_DC_THRESHOLD 21
+#define GET_STR_PRECOMPUTE_THRESHOLD 26
+#define SET_STR_THRESHOLD 3962
+
+#define MUL_FFT_TABLE { 368, 736, 1600, 3328, 7168, 20480, 49152, 0 }
+#define MUL_FFT_MODF_THRESHOLD 264
+#define MUL_FFT_THRESHOLD 1920
+
+#define SQR_FFT_TABLE { 368, 736, 1856, 3328, 7168, 20480, 49152, 0 }
+#define SQR_FFT_MODF_THRESHOLD 280
+#define SQR_FFT_THRESHOLD 1920
diff --git a/gmp/mpn/mips64/lshift.asm b/gmp/mpn/mips64/lshift.asm
new file mode 100644
index 0000000000..3440eaf80b
--- /dev/null
+++ b/gmp/mpn/mips64/lshift.asm
@@ -0,0 +1,99 @@
+dnl MIPS64 mpn_lshift -- Left shift.
+
+dnl Copyright 1995, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C src_ptr $5
+C size $6
+C cnt $7
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ dsll $2,$6,3
+ daddu $5,$5,$2 C make r5 point at end of src
+ ld $10,-8($5) C load first limb
+ dsubu $13,$0,$7
+ daddu $4,$4,$2 C make r4 point at end of res
+ daddiu $6,$6,-1
+ and $9,$6,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ dsrl $2,$10,$13 C compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,-16($5)
+ daddiu $4,$4,-8
+ daddiu $5,$5,-8
+ daddiu $9,$9,-1
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,0($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,-16($5)
+ daddiu $4,$4,-32
+ daddiu $6,$6,-4
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+
+ ld $10,-24($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,24($4)
+ dsrl $9,$10,$13
+
+ ld $3,-32($5)
+ dsll $11,$10,$7
+ or $8,$14,$9
+ sd $8,16($4)
+ dsrl $12,$3,$13
+
+ ld $10,-40($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,8($4)
+ dsrl $9,$10,$13
+
+ daddiu $5,$5,-32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,0($4)
+
+.Lend: dsll $8,$10,$7
+ j $31
+ sd $8,-8($4)
+EPILOGUE(mpn_lshift)
diff --git a/gmp/mpn/mips64/mul_1.asm b/gmp/mpn/mips64/mul_1.asm
new file mode 100644
index 0000000000..77acf0ac25
--- /dev/null
+++ b/gmp/mpn/mips64/mul_1.asm
@@ -0,0 +1,92 @@
+dnl MIPS64 mpn_mul_1 -- Multiply a limb vector with a single limb and store
+dnl the product in a second limb vector.
+
+dnl Copyright 1992, 1994, 1995, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C size $6
+C s2_limb $7
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+
+C feed-in phase 0
+ ld $8,0($5)
+
+C feed-in phase 1
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 C zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) C load new s1 limb as early as possible
+
+Loop: nop
+ mflo $10
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $10,$10,$2 C add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) C load new s1 limb as early as possible
+ daddiu $6,$6,-1 C decrement loop counter
+ sltu $2,$10,$2 C carry from previous addition -> $2
+ nop
+ nop
+ sd $10,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 1
+$LC1: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ dmultu $8,$7
+ sd $10,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 0
+$LC0: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ sd $10,0($4)
+ j $31
+ daddu $2,$9,$2 C add high product limb and carry from addition
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/mips64/rshift.asm b/gmp/mpn/mips64/rshift.asm
new file mode 100644
index 0000000000..9253cb51d8
--- /dev/null
+++ b/gmp/mpn/mips64/rshift.asm
@@ -0,0 +1,96 @@
+dnl MIPS64 mpn_rshift -- Right shift.
+
+dnl Copyright 1995, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C src_ptr $5
+C size $6
+C cnt $7
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ ld $10,0($5) C load first limb
+ dsubu $13,$0,$7
+ daddiu $6,$6,-1
+ and $9,$6,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ dsll $2,$10,$13 C compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,8($5)
+ daddiu $4,$4,8
+ daddiu $5,$5,8
+ daddiu $9,$9,-1
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,-8($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,8($5)
+ daddiu $4,$4,32
+ daddiu $6,$6,-4
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+
+ ld $10,16($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-32($4)
+ dsll $9,$10,$13
+
+ ld $3,24($5)
+ dsrl $11,$10,$7
+ or $8,$14,$9
+ sd $8,-24($4)
+ dsll $12,$3,$13
+
+ ld $10,32($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-16($4)
+ dsll $9,$10,$13
+
+ daddiu $5,$5,32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,-8($4)
+
+.Lend: dsrl $8,$10,$7
+ j $31
+ sd $8,0($4)
+EPILOGUE(mpn_rshift)
diff --git a/gmp/mpn/mips64/sqr_diagonal.asm b/gmp/mpn/mips64/sqr_diagonal.asm
new file mode 100644
index 0000000000..dcb87dc21f
--- /dev/null
+++ b/gmp/mpn/mips64/sqr_diagonal.asm
@@ -0,0 +1,77 @@
+dnl MIPS64 mpn_sqr_diagonal.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl INPUT PARAMETERS
+dnl rp $4
+dnl up $5
+dnl n $6
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_sqr_diagonal)
+ ld r8,0(r5)
+ daddiu r6,r6,-2
+ dmultu r8,r8
+ bltz r6,$Lend1
+ nop
+ ld r8,8(r5)
+ beq r6,r0,$Lend2
+ nop
+
+$Loop: mflo r10
+ mfhi r9
+ daddiu r6,r6,-1
+ sd r10,0(r4)
+ sd r9,8(r4)
+ dmultu r8,r8
+ ld r8,16(r5)
+ daddiu r5,r5,8
+ bne r6,r0,$Loop
+ daddiu r4,r4,16
+
+$Lend2: mflo r10
+ mfhi r9
+ sd r10,0(r4)
+ sd r9,8(r4)
+ dmultu r8,r8
+ mflo r10
+ mfhi r9
+ sd r10,16(r4)
+ j r31
+ sd r9,24(r4)
+
+$Lend1: mflo r10
+ mfhi r9
+ sd r10,0(r4)
+ j r31
+ sd r9,8(r4)
+EPILOGUE(mpn_sqr_diagonal)
diff --git a/gmp/mpn/mips64/sub_n.asm b/gmp/mpn/mips64/sub_n.asm
new file mode 100644
index 0000000000..6a698976eb
--- /dev/null
+++ b/gmp/mpn/mips64/sub_n.asm
@@ -0,0 +1,134 @@
+dnl MIPS64 mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+dnl store difference in a third limb vector.
+
+dnl Copyright 1995, 2000-2002, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C s2_ptr $6
+C size $7
+
+ASM_START()
+PROLOGUE(mpn_sub_nc)
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ move $2,$8
+ b .Loop0
+ dsubu $7,$7,$9
+EPILOGUE()
+PROLOGUE(mpn_sub_n)
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 C number of limbs in first loop
+ beq $9,$0,.L0 C if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ dsubu $11,$10,$11
+ ld $13,8($6)
+ sltu $8,$10,$11
+ dsubu $14,$11,$2
+ sltu $2,$11,$14
+ sd $14,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ dsubu $13,$12,$13
+ ld $11,16($6)
+ sltu $8,$12,$13
+ dsubu $14,$13,$2
+ sltu $2,$13,$14
+ sd $14,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ dsubu $11,$10,$11
+ ld $13,24($6)
+ sltu $8,$10,$11
+ dsubu $14,$11,$2
+ sltu $2,$11,$14
+ sd $14,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ dsubu $13,$12,$13
+ ld $11,32($6)
+ sltu $8,$12,$13
+ dsubu $14,$13,$2
+ sltu $2,$13,$14
+ sd $14,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+EPILOGUE()
diff --git a/gmp/mpn/mips64/submul_1.asm b/gmp/mpn/mips64/submul_1.asm
new file mode 100644
index 0000000000..089589cd73
--- /dev/null
+++ b/gmp/mpn/mips64/submul_1.asm
@@ -0,0 +1,101 @@
+dnl MIPS64 mpn_submul_1 -- Multiply a limb vector with a single limb and
+dnl subtract the product from a second limb vector.
+
+dnl Copyright 1992, 1994, 1995, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr $4
+C s1_ptr $5
+C size $6
+C s2_limb $7
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+
+C feed-in phase 0
+ ld $8,0($5)
+
+C feed-in phase 1
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 C zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) C load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 C add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) C load new s1 limb as early as possible
+ daddiu $6,$6,-1 C decrement loop counter
+ sltu $2,$3,$2 C carry from previous addition -> $2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 1
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 C add high product limb and carry from addition
+
+C wind-down phase 0
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 C add high product limb and carry from addition
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/mips64/umul.asm b/gmp/mpn/mips64/umul.asm
new file mode 100644
index 0000000000..b9aac57591
--- /dev/null
+++ b/gmp/mpn/mips64/umul.asm
@@ -0,0 +1,45 @@
+dnl MIPS64 umul_ppmm -- longlong.h support.
+
+dnl Copyright 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C plp $4
+C u $5
+C v $6
+
+ASM_START()
+PROLOGUE(mpn_umul_ppmm)
+ dmultu $5,$6
+ mflo $3
+ mfhi $2
+ j $31
+ sd $3,0($4)
+EPILOGUE(mpn_umul_ppmm)
diff --git a/gmp/mpn/pa32/README b/gmp/mpn/pa32/README
new file mode 100644
index 0000000000..4323390c9b
--- /dev/null
+++ b/gmp/mpn/pa32/README
@@ -0,0 +1,162 @@
+Copyright 1996, 1999, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+
+This directory contains mpn functions for various HP PA-RISC chips. Code
+that runs faster on the PA7100 and later implementations, is in the pa7100
+directory.
+
+RELEVANT OPTIMIZATION ISSUES
+
+ Load and Store timing
+
+On the PA7000 no memory instructions can issue the two cycles after a store.
+For the PA7100, this is reduced to one cycle.
+
+The PA7100 has a lookup-free cache, so it helps to schedule loads and the
+dependent instruction really far from each other.
+
+STATUS
+
+1. mpn_mul_1 could be improved to 6.5 cycles/limb on the PA7100, using the
+ instructions below (but some sw pipelining is needed to avoid the
+ xmpyu-fstds delay):
+
+ fldds s1_ptr
+
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+
+ addib Loop
+
+2. mpn_addmul_1 could be improved from the current 10 to 7.5 cycles/limb
+ (asymptotically) on the PA7100, using the instructions below. With proper
+ sw pipelining and the unrolling level below, the speed becomes 8
+ cycles/limb.
+
+ fldds s1_ptr
+ fldds s1_ptr
+
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ addc
+ addc
+ addc
+ addc
+ addc %r0,%r0,cy-limb
+
+ ldws res_ptr
+ ldws res_ptr
+ ldws res_ptr
+ ldws res_ptr
+ add
+ stws res_ptr
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+
+ addib
+
+3. For the PA8000 we have to stick to using 32-bit limbs before compiler
+ support emerges. But we want to use 64-bit operations whenever possible,
+ in particular for loads and stores. It is possible to handle mpn_add_n
+ efficiently by rotating (when s1/s2 are aligned), masking+bit field
+ inserting when (they are not). The speed should double compared to the
+ code used today.
+
+
+
+
+LABEL SYNTAX
+
+The HP-UX assembler takes labels starting in column 0 with no colon,
+
+ L$loop ldws,mb -4(0,%r25),%r22
+
+Gas on hppa GNU/Linux however requires a colon,
+
+ L$loop: ldws,mb -4(0,%r25),%r22
+
+This is covered by using LDEF() from asm-defs.m4. An alternative would be
+to use ".label" which is accepted by both,
+
+ .label L$loop
+ ldws,mb -4(0,%r25),%r22
+
+but that's not as nice to look at, not if you're used to assembler code
+having labels in column 0.
+
+
+
+
+REFERENCES
+
+Hewlett Packard, "HP Assembler Reference Manual", 9th edition, June 1998,
+part number 92432-90012.
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/pa32/add_n.asm b/gmp/mpn/pa32/add_n.asm
new file mode 100644
index 0000000000..46f39377ea
--- /dev/null
+++ b/gmp/mpn/pa32/add_n.asm
@@ -0,0 +1,63 @@
+dnl HP-PA mpn_add_n -- Add two limb vectors of the same length > 0 and store
+dnl sum in a third limb vector.
+
+dnl Copyright 1992, 1994, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr gr26
+C s1_ptr gr25
+C s2_ptr gr24
+C size gr23
+
+C One might want to unroll this as for other processors, but it turns out that
+C the data cache contention after a store makes such unrolling useless. We
+C can't come under 5 cycles/limb anyway.
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,= -1,%r23,L(end) C check for (SIZE == 1)
+ add %r20,%r19,%r28 C add first limbs ignoring cy
+
+LDEF(loop)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,<> -1,%r23,L(loop)
+ addc %r20,%r19,%r28
+
+LDEF(end)
+ stws %r28,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r0,%r28
+EPILOGUE()
diff --git a/gmp/mpn/pa32/gmp-mparam.h b/gmp/mpn/pa32/gmp-mparam.h
new file mode 100644
index 0000000000..377efcb156
--- /dev/null
+++ b/gmp/mpn/pa32/gmp-mparam.h
@@ -0,0 +1,61 @@
+/* HP-PA 1.0 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* These values are for the PA7100 using GCC. */
+/* Generated by tuneup.c, 2000-10-27. */
+
+#ifndef MUL_TOOM22_THRESHOLD
+#define MUL_TOOM22_THRESHOLD 30
+#endif
+#ifndef MUL_TOOM33_THRESHOLD
+#define MUL_TOOM33_THRESHOLD 141
+#endif
+
+#ifndef SQR_TOOM2_THRESHOLD
+#define SQR_TOOM2_THRESHOLD 59
+#endif
+#ifndef SQR_TOOM3_THRESHOLD
+#define SQR_TOOM3_THRESHOLD 177
+#endif
+
+#ifndef DIV_DC_THRESHOLD
+#define DIV_DC_THRESHOLD 108
+#endif
+
+#ifndef POWM_THRESHOLD
+#define POWM_THRESHOLD 18
+#endif
+
+#ifndef GCDEXT_THRESHOLD
+#define GCDEXT_THRESHOLD 33
+#endif
diff --git a/gmp/mpn/pa32/hppa1_1/addmul_1.asm b/gmp/mpn/pa32/hppa1_1/addmul_1.asm
new file mode 100644
index 0000000000..ec2f2198e8
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/addmul_1.asm
@@ -0,0 +1,106 @@
+dnl HP-PA 1.1 mpn_addmul_1 -- Multiply a limb vector with a limb and add the
+dnl result to a second limb vector.
+
+dnl Copyright 1992-1994, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r26
+C s1_ptr r25
+C size r24
+C s2_limb r23
+
+C This runs at 11 cycles/limb on a PA7000. With the used instructions, it can
+C not become faster due to data cache contention after a store. On the PA7100
+C it runs at 10 cycles/limb.
+
+C There are some ideas described in mul_1.asm that applies to this code too.
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+C .callinfo frame=64,no_calls
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) C move s2_limb ...
+ addib,= -1,%r24,L(just_one_limb)
+ fldws -16(%r30),%fr4 C ... into fr4
+ add %r0,%r0,%r0 C clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r19 C least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L(end)
+ ldw -12(%r30),%r1
+
+C Main loop
+LDEF(loop)
+ ldws 0(%r26),%r29
+ fldws,ma 4(%r25),%fr5
+ add %r29,%r19,%r19
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addc %r0,%r28,%r28
+ addib,<> -1,%r24,L(loop)
+ ldw -12(%r30),%r1
+
+LDEF(end)
+ ldw 0(%r26),%r29
+ add %r29,%r19,%r19
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ ldw -16(%r30),%r28
+ ldws 0(%r26),%r29
+ addc %r0,%r28,%r28
+ add %r29,%r19,%r19
+ stws,ma %r19,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+LDEF(just_one_limb)
+ xmpyu %fr4,%fr5,%fr6
+ ldw 0(%r26),%r29
+ fstds %fr6,-16(%r30)
+ ldw -12(%r30),%r1
+ ldw -16(%r30),%r28
+ add %r29,%r1,%r19
+ stw %r19,0(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+EPILOGUE()
diff --git a/gmp/mpn/pa32/hppa1_1/gmp-mparam.h b/gmp/mpn/pa32/hppa1_1/gmp-mparam.h
new file mode 100644
index 0000000000..1261b24c83
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/gmp-mparam.h
@@ -0,0 +1,72 @@
+/* HP-PA 1.1 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* Generated by tuneup.c, 2004-02-07, gcc 2.8 (pa7100/100MHz) */
+
+#define MUL_TOOM22_THRESHOLD 30
+#define MUL_TOOM33_THRESHOLD 89
+
+#define SQR_BASECASE_THRESHOLD 4
+#define SQR_TOOM2_THRESHOLD 55
+#define SQR_TOOM3_THRESHOLD 101
+
+#define DIV_SB_PREINV_THRESHOLD 0 /* always */
+#define DIV_DC_THRESHOLD 84
+#define POWM_THRESHOLD 166
+
+#define HGCD_THRESHOLD 231
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 823
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD 5
+#define DIVREM_1_UNNORM_THRESHOLD 11
+#define MOD_1_NORM_THRESHOLD 5
+#define MOD_1_UNNORM_THRESHOLD 10
+#define USE_PREINV_DIVREM_1 1
+#define USE_PREINV_MOD_1 1
+#define DIVREM_2_THRESHOLD 0 /* always */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always */
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 23
+#define SET_STR_THRESHOLD 6589
+
+#define MUL_FFT_TABLE { 464, 928, 1920, 4608, 14336, 40960, 0 }
+#define MUL_FFT_MODF_THRESHOLD 480
+#define MUL_FFT_THRESHOLD 3328
+
+#define SQR_FFT_TABLE { 528, 1184, 2176, 5632, 14336, 40960, 0 }
+#define SQR_FFT_MODF_THRESHOLD 520
+#define SQR_FFT_THRESHOLD 3328
diff --git a/gmp/mpn/pa32/hppa1_1/mul_1.asm b/gmp/mpn/pa32/hppa1_1/mul_1.asm
new file mode 100644
index 0000000000..6e60c2f61f
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/mul_1.asm
@@ -0,0 +1,102 @@
+dnl HP-PA 1.1 mpn_mul_1 -- Multiply a limb vector with a limb and store the
+dnl result in a second limb vector.
+
+dnl Copyright 1992-1994, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r26
+C s1_ptr r25
+C size r24
+C s2_limb r23
+
+C This runs at 9 cycles/limb on a PA7000. With the used instructions, it can
+C not become faster due to data cache contention after a store. On the PA7100
+C it runs at 7 cycles/limb.
+
+C We could use fldds to read two limbs at a time from the S1 array, and that
+C could bring down the times to 8.5 and 6.5 cycles/limb for the PA7000 and
+C PA7100, respectively. We don't do that since it does not seem worth the
+C (alignment) troubles...
+
+C At least the PA7100 is rumored to be able to deal with cache-misses without
+C stalling instruction issue. If this is true, and the cache is actually also
+C lockup-free, we should use a deeper software pipeline, and load from S1 very
+C early! (The loads and stores to -12(sp) will surely be in the cache.)
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+C .callinfo frame=64,no_calls
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) C move s2_limb ...
+ addib,= -1,%r24,L(just_one_limb)
+ fldws -16(%r30),%fr4 C ... into fr4
+ add %r0,%r0,%r0 C clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r19 C least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L(end)
+ ldw -12(%r30),%r1
+
+C Main loop
+LDEF(loop)
+ fldws,ma 4(%r25),%fr5
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addib,<> -1,%r24,L(loop)
+ ldw -12(%r30),%r1
+
+LDEF(end)
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ ldw -16(%r30),%r28
+ stws,ma %r19,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+LDEF(just_one_limb)
+ xmpyu %fr4,%fr5,%fr6
+ fstds %fr6,-16(%r30)
+ ldw -16(%r30),%r28
+ ldo -64(%r30),%r30
+ bv 0(%r2)
+ fstws %fr6R,0(%r26)
+EPILOGUE()
diff --git a/gmp/mpn/pa32/hppa1_1/pa7100/add_n.asm b/gmp/mpn/pa32/hppa1_1/pa7100/add_n.asm
new file mode 100644
index 0000000000..b96d403826
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/pa7100/add_n.asm
@@ -0,0 +1,83 @@
+dnl HP-PA mpn_add_n -- Add two limb vectors of the same length > 0 and store
+dnl sum in a third limb vector. Optimized for the PA7100, where is runs at
+dnl 4.25 cycles/limb.
+
+dnl Copyright 1992, 1994, 2000-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r26
+C s1_ptr r25
+C s2_ptr r24
+C size r23
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,<= -5,%r23,L(rest)
+ add %r20,%r19,%r28 C add first limbs ignoring cy
+
+LDEF(loop)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addc %r20,%r19,%r28
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addc %r20,%r19,%r28
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addc %r20,%r19,%r28
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,> -4,%r23,L(loop)
+ addc %r20,%r19,%r28
+
+LDEF(rest)
+ addib,= 4,%r23,L(end)
+ nop
+
+LDEF(eloop)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,> -1,%r23,L(eloop)
+ addc %r20,%r19,%r28
+
+LDEF(end)
+ stws %r28,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r0,%r28
+EPILOGUE()
diff --git a/gmp/mpn/pa32/hppa1_1/pa7100/addmul_1.asm b/gmp/mpn/pa32/hppa1_1/pa7100/addmul_1.asm
new file mode 100644
index 0000000000..fb16100d83
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/pa7100/addmul_1.asm
@@ -0,0 +1,201 @@
+dnl HP-PA 7100/7200 mpn_addmul_1 -- Multiply a limb vector with a limb and
+dnl add the result to a second limb vector.
+
+dnl Copyright 1995, 2000-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(`res_ptr',`%r26')
+define(`s1_ptr',`%r25')
+define(`size_param',`%r24')
+define(`s2_limb',`%r23')
+
+define(`cylimb',`%r28')
+define(`s0',`%r19')
+define(`s1',`%r20')
+define(`s2',`%r3')
+define(`s3',`%r4')
+define(`lo0',`%r21')
+define(`lo1',`%r5')
+define(`lo2',`%r6')
+define(`lo3',`%r7')
+define(`hi0',`%r22')
+define(`hi1',`%r23') C safe to reuse
+define(`hi2',`%r29')
+define(`hi3',`%r1')
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+C .callinfo frame=128,no_calls
+
+ ldo 128(%r30),%r30
+ stws s2_limb,-16(%r30)
+ add %r0,%r0,cylimb C clear cy and cylimb
+ addib,< -4,size_param,L(few_limbs)
+ fldws -16(%r30),%fr31R
+
+ ldo -112(%r30),%r31
+ stw %r3,-96(%r30)
+ stw %r4,-92(%r30)
+ stw %r5,-88(%r30)
+ stw %r6,-84(%r30)
+ stw %r7,-80(%r30)
+
+ bb,>=,n s1_ptr,29,L(0)
+
+ fldws,ma 4(s1_ptr),%fr4
+ ldws 0(res_ptr),s0
+ xmpyu %fr4,%fr31R,%fr5
+ fstds %fr5,-16(%r31)
+ ldws -16(%r31),cylimb
+ ldws -12(%r31),lo0
+ add s0,lo0,s0
+ addib,< -1,size_param,L(few_limbs)
+ stws,ma s0,4(res_ptr)
+
+C start software pipeline ----------------------------------------------------
+LDEF(0)
+ fldds,ma 8(s1_ptr),%fr4
+ fldds,ma 8(s1_ptr),%fr8
+
+ xmpyu %fr4L,%fr31R,%fr5
+ xmpyu %fr4R,%fr31R,%fr6
+ xmpyu %fr8L,%fr31R,%fr9
+ xmpyu %fr8R,%fr31R,%fr10
+
+ fstds %fr5,-16(%r31)
+ fstds %fr6,-8(%r31)
+ fstds %fr9,0(%r31)
+ fstds %fr10,8(%r31)
+
+ ldws -16(%r31),hi0
+ ldws -12(%r31),lo0
+ ldws -8(%r31),hi1
+ ldws -4(%r31),lo1
+ ldws 0(%r31),hi2
+ ldws 4(%r31),lo2
+ ldws 8(%r31),hi3
+ ldws 12(%r31),lo3
+
+ addc lo0,cylimb,lo0
+ addc lo1,hi0,lo1
+ addc lo2,hi1,lo2
+ addc lo3,hi2,lo3
+
+ addib,< -4,size_param,L(end)
+ addc %r0,hi3,cylimb C propagate carry into cylimb
+C main loop ------------------------------------------------------------------
+LDEF(loop)
+ fldds,ma 8(s1_ptr),%fr4
+ fldds,ma 8(s1_ptr),%fr8
+
+ ldws 0(res_ptr),s0
+ xmpyu %fr4L,%fr31R,%fr5
+ ldws 4(res_ptr),s1
+ xmpyu %fr4R,%fr31R,%fr6
+ ldws 8(res_ptr),s2
+ xmpyu %fr8L,%fr31R,%fr9
+ ldws 12(res_ptr),s3
+ xmpyu %fr8R,%fr31R,%fr10
+
+ fstds %fr5,-16(%r31)
+ add s0,lo0,s0
+ fstds %fr6,-8(%r31)
+ addc s1,lo1,s1
+ fstds %fr9,0(%r31)
+ addc s2,lo2,s2
+ fstds %fr10,8(%r31)
+ addc s3,lo3,s3
+
+ ldws -16(%r31),hi0
+ ldws -12(%r31),lo0
+ ldws -8(%r31),hi1
+ ldws -4(%r31),lo1
+ ldws 0(%r31),hi2
+ ldws 4(%r31),lo2
+ ldws 8(%r31),hi3
+ ldws 12(%r31),lo3
+
+ addc lo0,cylimb,lo0
+ stws,ma s0,4(res_ptr)
+ addc lo1,hi0,lo1
+ stws,ma s1,4(res_ptr)
+ addc lo2,hi1,lo2
+ stws,ma s2,4(res_ptr)
+ addc lo3,hi2,lo3
+ stws,ma s3,4(res_ptr)
+
+ addib,>= -4,size_param,L(loop)
+ addc %r0,hi3,cylimb C propagate carry into cylimb
+C finish software pipeline ---------------------------------------------------
+LDEF(end)
+ ldws 0(res_ptr),s0
+ ldws 4(res_ptr),s1
+ ldws 8(res_ptr),s2
+ ldws 12(res_ptr),s3
+
+ add s0,lo0,s0
+ stws,ma s0,4(res_ptr)
+ addc s1,lo1,s1
+ stws,ma s1,4(res_ptr)
+ addc s2,lo2,s2
+ stws,ma s2,4(res_ptr)
+ addc s3,lo3,s3
+ stws,ma s3,4(res_ptr)
+
+C restore callee-saves registers ---------------------------------------------
+ ldw -96(%r30),%r3
+ ldw -92(%r30),%r4
+ ldw -88(%r30),%r5
+ ldw -84(%r30),%r6
+ ldw -80(%r30),%r7
+
+LDEF(few_limbs)
+ addib,=,n 4,size_param,L(ret)
+
+LDEF(loop2)
+ fldws,ma 4(s1_ptr),%fr4
+ ldws 0(res_ptr),s0
+ xmpyu %fr4,%fr31R,%fr5
+ fstds %fr5,-16(%r30)
+ ldws -16(%r30),hi0
+ ldws -12(%r30),lo0
+ addc lo0,cylimb,lo0
+ addc %r0,hi0,cylimb
+ add s0,lo0,s0
+ stws,ma s0,4(res_ptr)
+ addib,<> -1,size_param,L(loop2)
+ nop
+
+LDEF(ret)
+ addc %r0,cylimb,cylimb
+ bv 0(%r2)
+ ldo -128(%r30),%r30
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/pa32/hppa1_1/pa7100/lshift.asm b/gmp/mpn/pa32/hppa1_1/pa7100/lshift.asm
new file mode 100644
index 0000000000..d65db2a76b
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/pa7100/lshift.asm
@@ -0,0 +1,95 @@
+dnl HP-PA mpn_lshift -- Shift a number left.
+dnl Optimized for the PA7100, where is runs at 3.25 cycles/limb.
+
+dnl Copyright 1992, 1994, 2000-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r26
+C s_ptr r25
+C size r24
+C cnt r23
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ sh2add %r24,%r25,%r25
+ sh2add %r24,%r26,%r26
+ ldws,mb -4(0,%r25),%r22
+ subi 32,%r23,%r1
+ mtsar %r1
+ addib,= -1,%r24,L(0004)
+ vshd %r0,%r22,%r28 C compute carry out limb
+ ldws,mb -4(0,%r25),%r29
+ addib,<= -5,%r24,L(rest)
+ vshd %r22,%r29,%r20
+
+LDEF(loop)
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,> -4,%r24,L(loop)
+ vshd %r22,%r29,%r20
+
+LDEF(rest)
+ addib,= 4,%r24,L(end1)
+ nop
+
+LDEF(eloop)
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ addib,<= -1,%r24,L(end2)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,> -1,%r24,L(eloop)
+ vshd %r22,%r29,%r20
+
+LDEF(end1)
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+
+LDEF(end2)
+ stws,mb %r20,-4(0,%r26)
+
+LDEF(0004)
+ vshd %r22,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+EPILOGUE()
diff --git a/gmp/mpn/pa32/hppa1_1/pa7100/rshift.asm b/gmp/mpn/pa32/hppa1_1/pa7100/rshift.asm
new file mode 100644
index 0000000000..f7896fc949
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/pa7100/rshift.asm
@@ -0,0 +1,92 @@
+dnl HP-PA mpn_rshift -- Shift a number right.
+dnl Optimized for the PA7100, where is runs at 3.25 cycles/limb.
+
+dnl Copyright 1992, 1994, 2000-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r26
+C s_ptr r25
+C size r24
+C cnt r23
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ ldws,ma 4(0,%r25),%r22
+ mtsar %r23
+ addib,= -1,%r24,L(0004)
+ vshd %r22,%r0,%r28 C compute carry out limb
+ ldws,ma 4(0,%r25),%r29
+ addib,<= -5,%r24,L(rest)
+ vshd %r29,%r22,%r20
+
+LDEF(loop)
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,> -4,%r24,L(loop)
+ vshd %r29,%r22,%r20
+
+LDEF(rest)
+ addib,= 4,%r24,L(end1)
+ nop
+
+LDEF(eloop)
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ addib,<= -1,%r24,L(end2)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,> -1,%r24,L(eloop)
+ vshd %r29,%r22,%r20
+
+LDEF(end1)
+ stws,ma %r20,4(0,%r26)
+ vshd %r0,%r29,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+
+LDEF(end2)
+ stws,ma %r20,4(0,%r26)
+
+LDEF(0004)
+ vshd %r0,%r22,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+EPILOGUE()
diff --git a/gmp/mpn/pa32/hppa1_1/pa7100/sub_n.asm b/gmp/mpn/pa32/hppa1_1/pa7100/sub_n.asm
new file mode 100644
index 0000000000..df3f6e8b81
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/pa7100/sub_n.asm
@@ -0,0 +1,84 @@
+dnl HP-PA mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+dnl store difference in a third limb vector. Optimized for the PA7100, where
+dnl is runs at 4.25 cycles/limb.
+
+dnl Copyright 1992, 1994, 2000-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r26
+C s1_ptr r25
+C s2_ptr r24
+C size r23
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,<= -5,%r23,L(rest)
+ sub %r20,%r19,%r28 C subtract first limbs ignoring cy
+
+LDEF(loop)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ subb %r20,%r19,%r28
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ subb %r20,%r19,%r28
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ subb %r20,%r19,%r28
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,> -4,%r23,L(loop)
+ subb %r20,%r19,%r28
+
+LDEF(rest)
+ addib,= 4,%r23,L(end)
+ nop
+
+LDEF(eloop)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,> -1,%r23,L(eloop)
+ subb %r20,%r19,%r28
+
+LDEF(end)
+ stws %r28,0(0,%r26)
+ addc %r0,%r0,%r28
+ bv 0(%r2)
+ subi 1,%r28,%r28
+EPILOGUE()
diff --git a/gmp/mpn/pa32/hppa1_1/pa7100/submul_1.asm b/gmp/mpn/pa32/hppa1_1/pa7100/submul_1.asm
new file mode 100644
index 0000000000..5ea08cbee5
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/pa7100/submul_1.asm
@@ -0,0 +1,207 @@
+dnl HP-PA 7100/7200 mpn_submul_1 -- Multiply a limb vector with a limb and
+dnl subtract the result from a second limb vector.
+
+dnl Copyright 1995, 2000-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(`res_ptr',`%r26')
+define(`s1_ptr',`%r25')
+define(`size_param',`%r24')
+define(`s2_limb',`%r23')
+
+define(`cylimb',`%r28')
+define(`s0',`%r19')
+define(`s1',`%r20')
+define(`s2',`%r3')
+define(`s3',`%r4')
+define(`lo0',`%r21')
+define(`lo1',`%r5')
+define(`lo2',`%r6')
+define(`lo3',`%r7')
+define(`hi0',`%r22')
+define(`hi1',`%r23') C safe to reuse
+define(`hi2',`%r29')
+define(`hi3',`%r1')
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+C .callinfo frame=128,no_calls
+
+ ldo 128(%r30),%r30
+ stws s2_limb,-16(%r30)
+ add %r0,%r0,cylimb C clear cy and cylimb
+ addib,< -4,size_param,L(few_limbs)
+ fldws -16(%r30),%fr31R
+
+ ldo -112(%r30),%r31
+ stw %r3,-96(%r30)
+ stw %r4,-92(%r30)
+ stw %r5,-88(%r30)
+ stw %r6,-84(%r30)
+ stw %r7,-80(%r30)
+
+ bb,>=,n s1_ptr,29,L(0)
+
+ fldws,ma 4(s1_ptr),%fr4
+ ldws 0(res_ptr),s0
+ xmpyu %fr4,%fr31R,%fr5
+ fstds %fr5,-16(%r31)
+ ldws -16(%r31),cylimb
+ ldws -12(%r31),lo0
+ sub s0,lo0,s0
+ add s0,lo0,%r0 C invert cy
+ addib,< -1,size_param,L(few_limbs)
+ stws,ma s0,4(res_ptr)
+
+C start software pipeline ----------------------------------------------------
+LDEF(0)
+ fldds,ma 8(s1_ptr),%fr4
+ fldds,ma 8(s1_ptr),%fr8
+
+ xmpyu %fr4L,%fr31R,%fr5
+ xmpyu %fr4R,%fr31R,%fr6
+ xmpyu %fr8L,%fr31R,%fr9
+ xmpyu %fr8R,%fr31R,%fr10
+
+ fstds %fr5,-16(%r31)
+ fstds %fr6,-8(%r31)
+ fstds %fr9,0(%r31)
+ fstds %fr10,8(%r31)
+
+ ldws -16(%r31),hi0
+ ldws -12(%r31),lo0
+ ldws -8(%r31),hi1
+ ldws -4(%r31),lo1
+ ldws 0(%r31),hi2
+ ldws 4(%r31),lo2
+ ldws 8(%r31),hi3
+ ldws 12(%r31),lo3
+
+ addc lo0,cylimb,lo0
+ addc lo1,hi0,lo1
+ addc lo2,hi1,lo2
+ addc lo3,hi2,lo3
+
+ addib,< -4,size_param,L(end)
+ addc %r0,hi3,cylimb C propagate carry into cylimb
+C main loop ------------------------------------------------------------------
+LDEF(loop)
+ fldds,ma 8(s1_ptr),%fr4
+ fldds,ma 8(s1_ptr),%fr8
+
+ ldws 0(res_ptr),s0
+ xmpyu %fr4L,%fr31R,%fr5
+ ldws 4(res_ptr),s1
+ xmpyu %fr4R,%fr31R,%fr6
+ ldws 8(res_ptr),s2
+ xmpyu %fr8L,%fr31R,%fr9
+ ldws 12(res_ptr),s3
+ xmpyu %fr8R,%fr31R,%fr10
+
+ fstds %fr5,-16(%r31)
+ sub s0,lo0,s0
+ fstds %fr6,-8(%r31)
+ subb s1,lo1,s1
+ fstds %fr9,0(%r31)
+ subb s2,lo2,s2
+ fstds %fr10,8(%r31)
+ subb s3,lo3,s3
+ subb %r0,%r0,lo0 C these two insns ...
+ add lo0,lo0,%r0 C ... just invert cy
+
+ ldws -16(%r31),hi0
+ ldws -12(%r31),lo0
+ ldws -8(%r31),hi1
+ ldws -4(%r31),lo1
+ ldws 0(%r31),hi2
+ ldws 4(%r31),lo2
+ ldws 8(%r31),hi3
+ ldws 12(%r31),lo3
+
+ addc lo0,cylimb,lo0
+ stws,ma s0,4(res_ptr)
+ addc lo1,hi0,lo1
+ stws,ma s1,4(res_ptr)
+ addc lo2,hi1,lo2
+ stws,ma s2,4(res_ptr)
+ addc lo3,hi2,lo3
+ stws,ma s3,4(res_ptr)
+
+ addib,>= -4,size_param,L(loop)
+ addc %r0,hi3,cylimb C propagate carry into cylimb
+C finish software pipeline ---------------------------------------------------
+LDEF(end)
+ ldws 0(res_ptr),s0
+ ldws 4(res_ptr),s1
+ ldws 8(res_ptr),s2
+ ldws 12(res_ptr),s3
+
+ sub s0,lo0,s0
+ stws,ma s0,4(res_ptr)
+ subb s1,lo1,s1
+ stws,ma s1,4(res_ptr)
+ subb s2,lo2,s2
+ stws,ma s2,4(res_ptr)
+ subb s3,lo3,s3
+ stws,ma s3,4(res_ptr)
+ subb %r0,%r0,lo0 C these two insns ...
+ add lo0,lo0,%r0 C ... invert cy
+
+C restore callee-saves registers ---------------------------------------------
+ ldw -96(%r30),%r3
+ ldw -92(%r30),%r4
+ ldw -88(%r30),%r5
+ ldw -84(%r30),%r6
+ ldw -80(%r30),%r7
+
+LDEF(few_limbs)
+ addib,=,n 4,size_param,L(ret)
+
+LDEF(loop2)
+ fldws,ma 4(s1_ptr),%fr4
+ ldws 0(res_ptr),s0
+ xmpyu %fr4,%fr31R,%fr5
+ fstds %fr5,-16(%r30)
+ ldws -16(%r30),hi0
+ ldws -12(%r30),lo0
+ addc lo0,cylimb,lo0
+ addc %r0,hi0,cylimb
+ sub s0,lo0,s0
+ add s0,lo0,%r0 C invert cy
+ stws,ma s0,4(res_ptr)
+ addib,<> -1,size_param,L(loop2)
+ nop
+
+LDEF(ret)
+ addc %r0,cylimb,cylimb
+ bv 0(%r2)
+ ldo -128(%r30),%r30
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/pa32/hppa1_1/sqr_diagonal.asm b/gmp/mpn/pa32/hppa1_1/sqr_diagonal.asm
new file mode 100644
index 0000000000..1c7a18e37d
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/sqr_diagonal.asm
@@ -0,0 +1,60 @@
+dnl HP-PA 1.1 32-bit mpn_sqr_diagonal.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C This code runs at 6 cycles/limb on the PA7100 and 2.5 cycles/limb on PA8x00.
+C 2-way unrolling wouldn't help the PA7100; it could however bring times down
+C to 2.0 cycles/limb for the PA8x00.
+
+C INPUT PARAMETERS
+define(`rp',`%r26')
+define(`up',`%r25')
+define(`n',`%r24')
+
+ASM_START()
+PROLOGUE(mpn_sqr_diagonal)
+ ldo 4(rp),rp
+ fldws,ma 4(up),%fr4r
+ addib,= -1,n,L(exit)
+ xmpyu %fr4r,%fr4r,%fr5
+
+LDEF(loop)
+ fldws,ma 4(up),%fr4r
+ fstws %fr5r,-4(rp)
+ fstws,ma %fr5l,8(rp)
+ addib,<> -1,n,L(loop)
+ xmpyu %fr4r,%fr4r,%fr5
+
+LDEF(exit)
+ fstws %fr5r,-4(rp)
+ bv 0(%r2)
+ fstws %fr5l,0(rp)
+EPILOGUE(mpn_sqr_diagonal)
diff --git a/gmp/mpn/pa32/hppa1_1/submul_1.asm b/gmp/mpn/pa32/hppa1_1/submul_1.asm
new file mode 100644
index 0000000000..a9b11d24a8
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/submul_1.asm
@@ -0,0 +1,115 @@
+dnl HP-PA 1.1 mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+dnl the result from a second limb vector.
+
+dnl Copyright 1992-1994, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r26
+C s1_ptr r25
+C size r24
+C s2_limb r23
+
+C This runs at 12 cycles/limb on a PA7000. With the used instructions, it can
+C not become faster due to data cache contention after a store. On the PA7100
+C it runs at 11 cycles/limb.
+
+C There are some ideas described in mul_1.asm that applies to this code too.
+
+C It seems possible to make this run as fast as mpn_addmul_1, if we use
+C sub,>>= %r29,%r19,%r22
+C addi 1,%r28,%r28
+C but that requires reworking the hairy software pipeline...
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+C .callinfo frame=64,no_calls
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) C move s2_limb ...
+ addib,= -1,%r24,L(just_one_limb)
+ fldws -16(%r30),%fr4 C ... into fr4
+ add %r0,%r0,%r0 C clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r19 C least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L(end)
+ ldw -12(%r30),%r1
+
+C Main loop
+LDEF(loop)
+ ldws 0(%r26),%r29
+ fldws,ma 4(%r25),%fr5
+ sub %r29,%r19,%r22
+ add %r22,%r19,%r0
+ stws,ma %r22,4(%r26)
+ addc %r28,%r1,%r19
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addc %r0,%r28,%r28
+ addib,<> -1,%r24,L(loop)
+ ldw -12(%r30),%r1
+
+LDEF(end)
+ ldw 0(%r26),%r29
+ sub %r29,%r19,%r22
+ add %r22,%r19,%r0
+ stws,ma %r22,4(%r26)
+ addc %r28,%r1,%r19
+ ldw -16(%r30),%r28
+ ldws 0(%r26),%r29
+ addc %r0,%r28,%r28
+ sub %r29,%r19,%r22
+ add %r22,%r19,%r0
+ stws,ma %r22,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+LDEF(just_one_limb)
+ xmpyu %fr4,%fr5,%fr6
+ ldw 0(%r26),%r29
+ fstds %fr6,-16(%r30)
+ ldw -12(%r30),%r1
+ ldw -16(%r30),%r28
+ sub %r29,%r1,%r22
+ add %r22,%r1,%r0
+ stw %r22,0(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+EPILOGUE()
diff --git a/gmp/mpn/pa32/hppa1_1/udiv.asm b/gmp/mpn/pa32/hppa1_1/udiv.asm
new file mode 100644
index 0000000000..626ecd202b
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/udiv.asm
@@ -0,0 +1,102 @@
+dnl HP-PA __udiv_qrnnd division support, used from longlong.h.
+dnl This version runs fast on PA 7000 and later.
+
+dnl Copyright 1993, 1994, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rem_ptr gr26
+C n1 gr25
+C n0 gr24
+C d gr23
+
+C This file has caused a lot of trouble, since it demands PIC reference to
+C static data, which triggers bugs in gas (at least version 2.7 through
+C 2.11.2). When the bug is triggered, many bogus relocs are generated. The
+C current solution is to stuff data right into the code, and refer it using
+C absolute offsets. Fragile to be sure, but nothing else seems to work.
+
+ASM_START()
+ifdef(`PIC',`',
+` RODATA
+ INT64(0000, 0x43f00000, 0x0) C 2^64
+')
+
+PROLOGUE(mpn_udiv_qrnnd)
+C .callinfo frame=64,no_calls
+
+ ldo 64(%r30),%r30
+
+ stws %r25,-16(0,%r30) C n_hi
+ stws %r24,-12(0,%r30) C n_lo
+
+ifdef(`PIC',
+` bl .+20,%r31
+ dep %r0,31,2,%r31
+ .word 0x0 C padding for alignment
+ .word 0x43f00000, 0x0 C 2^64
+ ldo 4(%r31),%r31',
+` ldil `L'%L(0000),%r31
+ ldo R%L(0000)(%r31),%r31')
+
+ fldds -16(0,%r30),%fr5
+ stws %r23,-12(0,%r30)
+ comib,<= 0,%r25,L(1)
+ fcnvxf,dbl,dbl %fr5,%fr5
+ fldds 0(0,%r31),%fr4
+ fadd,dbl %fr4,%fr5,%fr5
+
+LDEF(1)
+ fcpy,sgl %fr0,%fr6L
+ fldws -12(0,%r30),%fr6R
+ fcnvxf,dbl,dbl %fr6,%fr4
+
+ fdiv,dbl %fr5,%fr4,%fr5
+
+ fcnvfx,dbl,dbl %fr5,%fr4
+ fstws %fr4R,-16(%r30)
+ xmpyu %fr4R,%fr6R,%fr6
+ ldws -16(%r30),%r28
+ fstds %fr6,-16(0,%r30)
+ ldws -12(0,%r30),%r21
+ ldws -16(0,%r30),%r20
+ sub %r24,%r21,%r22
+ subb %r25,%r20,%r20
+ comib,= 0,%r20,L(2)
+ ldo -64(%r30),%r30
+
+ add %r22,%r23,%r22
+ ldo -1(%r28),%r28
+
+LDEF(2)
+ bv 0(%r2)
+ stws %r22,0(0,%r26)
+
+EPILOGUE(mpn_udiv_qrnnd)
diff --git a/gmp/mpn/pa32/hppa1_1/umul.asm b/gmp/mpn/pa32/hppa1_1/umul.asm
new file mode 100644
index 0000000000..18b923cd5a
--- /dev/null
+++ b/gmp/mpn/pa32/hppa1_1/umul.asm
@@ -0,0 +1,47 @@
+dnl Copyright 1999, 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_umul_ppmm)
+C .callinfo frame=64,no_calls
+
+ ldo 64(%r30),%r30
+ stw %r25,-16(0,%r30)
+ fldws -16(0,%r30),%fr22R
+ stw %r24,-16(0,%r30)
+ fldws -16(0,%r30),%fr22L
+ xmpyu %fr22R,%fr22L,%fr22
+ fstds %fr22,-16(0,%r30)
+ ldw -16(0,%r30),%r28
+ ldw -12(0,%r30),%r29
+ stw %r29,0(0,%r26)
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+EPILOGUE()
diff --git a/gmp/mpn/pa32/hppa2_0/add_n.asm b/gmp/mpn/pa32/hppa2_0/add_n.asm
new file mode 100644
index 0000000000..8d881b8b08
--- /dev/null
+++ b/gmp/mpn/pa32/hppa2_0/add_n.asm
@@ -0,0 +1,107 @@
+dnl HP-PA 2.0 32-bit mpn_add_n -- Add two limb vectors of the same length > 0
+dnl and store sum in a third limb vector.
+
+dnl Copyright 1997, 1998, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr gr26
+C s1_ptr gr25
+C s2_ptr gr24
+C size gr23
+
+C This runs at 2 cycles/limb on PA8000.
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+ sub %r0,%r23,%r22
+ zdep %r22,30,3,%r28 C r28 = 2 * (-n & 7)
+ zdep %r22,29,3,%r22 C r22 = 4 * (-n & 7)
+ sub %r25,%r22,%r25 C offset s1_ptr
+ sub %r24,%r22,%r24 C offset s2_ptr
+ sub %r26,%r22,%r26 C offset res_ptr
+ blr %r28,%r0 C branch into loop
+ add %r0,%r0,%r0 C reset carry
+
+LDEF(loop)
+ ldw 0(%r25),%r20
+ ldw 0(%r24),%r31
+ addc %r20,%r31,%r20
+ stw %r20,0(%r26)
+
+LDEF(7)
+ ldw 4(%r25),%r21
+ ldw 4(%r24),%r19
+ addc %r21,%r19,%r21
+ stw %r21,4(%r26)
+
+LDEF(6)
+ ldw 8(%r25),%r20
+ ldw 8(%r24),%r31
+ addc %r20,%r31,%r20
+ stw %r20,8(%r26)
+
+LDEF(5)
+ ldw 12(%r25),%r21
+ ldw 12(%r24),%r19
+ addc %r21,%r19,%r21
+ stw %r21,12(%r26)
+
+LDEF(4)
+ ldw 16(%r25),%r20
+ ldw 16(%r24),%r31
+ addc %r20,%r31,%r20
+ stw %r20,16(%r26)
+
+LDEF(3)
+ ldw 20(%r25),%r21
+ ldw 20(%r24),%r19
+ addc %r21,%r19,%r21
+ stw %r21,20(%r26)
+
+LDEF(2)
+ ldw 24(%r25),%r20
+ ldw 24(%r24),%r31
+ addc %r20,%r31,%r20
+ stw %r20,24(%r26)
+
+LDEF(1)
+ ldw 28(%r25),%r21
+ ldo 32(%r25),%r25
+ ldw 28(%r24),%r19
+ addc %r21,%r19,%r21
+ stw %r21,28(%r26)
+ ldo 32(%r24),%r24
+ addib,> -8,%r23,L(loop)
+ ldo 32(%r26),%r26
+
+ bv (%r2)
+ addc %r0,%r0,%r28
+EPILOGUE()
diff --git a/gmp/mpn/pa32/hppa2_0/gmp-mparam.h b/gmp/mpn/pa32/hppa2_0/gmp-mparam.h
new file mode 100644
index 0000000000..6016274714
--- /dev/null
+++ b/gmp/mpn/pa32/hppa2_0/gmp-mparam.h
@@ -0,0 +1,167 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2009, 2010 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 552 MHz PA8600 (gcc61.fsffrance.org) */
+
+#define DIVREM_1_NORM_THRESHOLD 3
+#define DIVREM_1_UNNORM_THRESHOLD 3
+#define MOD_1_NORM_THRESHOLD 3
+#define MOD_1_UNNORM_THRESHOLD 4
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 11
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 8
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 22
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 28
+#define USE_PREINV_DIVREM_1 1
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 36
+
+#define MUL_TOOM22_THRESHOLD 18
+#define MUL_TOOM33_THRESHOLD 65
+#define MUL_TOOM44_THRESHOLD 166
+#define MUL_TOOM6H_THRESHOLD 202
+#define MUL_TOOM8H_THRESHOLD 333
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 105
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 138
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 105
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 102
+
+#define SQR_BASECASE_THRESHOLD 7
+#define SQR_TOOM2_THRESHOLD 55
+#define SQR_TOOM3_THRESHOLD 93
+#define SQR_TOOM4_THRESHOLD 250
+#define SQR_TOOM6_THRESHOLD 306
+#define SQR_TOOM8_THRESHOLD 527
+
+#define MULMOD_BNM1_THRESHOLD 13
+#define SQRMOD_BNM1_THRESHOLD 15
+
+#define MUL_FFT_MODF_THRESHOLD 244 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 244, 5}, { 8, 4}, { 17, 5}, { 13, 6}, \
+ { 7, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 13, 7}, { 7, 6}, { 17, 7}, { 9, 6}, \
+ { 19, 7}, { 11, 6}, { 24, 7}, { 13, 8}, \
+ { 7, 7}, { 19, 8}, { 11, 7}, { 25, 8}, \
+ { 15, 7}, { 33, 8}, { 23, 9}, { 15, 8}, \
+ { 39, 9}, { 23,10}, { 15, 9}, { 31, 8}, \
+ { 67, 9}, { 39, 8}, { 79, 9}, { 47,10}, \
+ { 31, 9}, { 71, 8}, { 143, 9}, { 79,10}, \
+ { 47,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 9}, { 135, 8}, { 271, 9}, { 143,10}, \
+ { 79, 9}, { 159, 8}, { 319, 9}, { 175, 8}, \
+ { 351,10}, { 95, 9}, { 191, 8}, { 383, 9}, \
+ { 207,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511, 9}, { 271,10}, { 143, 9}, { 287, 8}, \
+ { 575,10}, { 159, 9}, { 319,10}, { 175, 9}, \
+ { 351,11}, { 95,10}, { 191, 9}, { 383,10}, \
+ { 207, 9}, { 415,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271, 9}, { 543, 8}, \
+ { 1087,10}, { 287, 9}, { 575,10}, { 303,11}, \
+ { 159,10}, { 351, 9}, { 703, 8}, { 1407,11}, \
+ { 191,10}, { 415, 9}, { 831,11}, { 223, 9}, \
+ { 895,10}, { 479,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607, 9}, \
+ { 1215,11}, { 351,10}, { 703, 9}, { 1407,12}, \
+ { 191,11}, { 415,10}, { 831,11}, { 479,13}, \
+ { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 107
+#define MUL_FFT_THRESHOLD 2112
+
+#define SQR_FFT_MODF_THRESHOLD 240 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 240, 5}, { 8, 4}, { 17, 5}, { 19, 6}, \
+ { 17, 7}, { 9, 6}, { 20, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 19, 8}, \
+ { 11, 7}, { 25, 8}, { 15, 7}, { 33, 8}, \
+ { 19, 7}, { 39, 8}, { 23, 9}, { 15, 8}, \
+ { 39, 9}, { 23,10}, { 15, 9}, { 31, 8}, \
+ { 63, 9}, { 47,10}, { 31, 9}, { 63, 8}, \
+ { 127, 9}, { 71, 8}, { 143, 9}, { 79,10}, \
+ { 47,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 7}, { 511, 9}, { 135, 8}, { 271, 9}, \
+ { 143,10}, { 79, 9}, { 159, 8}, { 319, 9}, \
+ { 175, 8}, { 351, 7}, { 703,10}, { 95, 9}, \
+ { 191, 8}, { 383, 9}, { 207,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511, 9}, { 271,10}, \
+ { 143, 9}, { 287, 8}, { 575,10}, { 159, 9}, \
+ { 319,10}, { 175, 9}, { 351, 8}, { 703,11}, \
+ { 95,10}, { 191, 9}, { 383,10}, { 207, 9}, \
+ { 415,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543, 8}, { 1087,10}, \
+ { 287, 9}, { 575,11}, { 159,10}, { 319, 9}, \
+ { 639,10}, { 351, 9}, { 703, 8}, { 1407,11}, \
+ { 191,10}, { 415, 9}, { 831,11}, { 223, 8}, \
+ { 1791,10}, { 479, 9}, { 959,12}, { 127,11}, \
+ { 255,10}, { 543,11}, { 287,10}, { 607,11}, \
+ { 319,10}, { 639,11}, { 351,10}, { 703, 9}, \
+ { 1407,12}, { 191,11}, { 415,10}, { 831,11}, \
+ { 479,10}, { 959,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 109
+#define SQR_FFT_THRESHOLD 1600
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 116
+#define MULLO_MUL_N_THRESHOLD 3574
+
+#define DC_DIV_QR_THRESHOLD 100
+#define DC_DIVAPPR_Q_THRESHOLD 348
+#define DC_BDIV_QR_THRESHOLD 109
+#define DC_BDIV_Q_THRESHOLD 254
+
+#define INV_MULMOD_BNM1_THRESHOLD 34
+#define INV_NEWTON_THRESHOLD 276
+#define INV_APPR_THRESHOLD 276
+
+#define BINV_NEWTON_THRESHOLD 278
+#define REDC_1_TO_REDC_N_THRESHOLD 78
+
+#define MU_DIV_QR_THRESHOLD 979
+#define MU_DIVAPPR_Q_THRESHOLD 263
+#define MUPI_DIV_QR_THRESHOLD 102
+#define MU_BDIV_QR_THRESHOLD 807
+#define MU_BDIV_Q_THRESHOLD 1187
+
+#define MATRIX22_STRASSEN_THRESHOLD 11
+#define HGCD_THRESHOLD 100
+#define GCD_DC_THRESHOLD 379
+#define GCDEXT_DC_THRESHOLD 249
+#define JACOBI_BASE_METHOD 2
+
+#define GET_STR_DC_THRESHOLD 7
+#define GET_STR_PRECOMPUTE_THRESHOLD 16
+#define SET_STR_DC_THRESHOLD 270
+#define SET_STR_PRECOMPUTE_THRESHOLD 782
diff --git a/gmp/mpn/pa32/hppa2_0/sqr_diagonal.asm b/gmp/mpn/pa32/hppa2_0/sqr_diagonal.asm
new file mode 100644
index 0000000000..c55112fac5
--- /dev/null
+++ b/gmp/mpn/pa32/hppa2_0/sqr_diagonal.asm
@@ -0,0 +1,112 @@
+dnl HP-PA 32-bit mpn_sqr_diagonal optimized for the PA8x00.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C This code runs at 6 cycles/limb on the PA7100 and 2 cycles/limb on PA8x00.
+C The 2-way unrolling is actually not helping the PA7100.
+
+C INPUT PARAMETERS
+define(`rp',`%r26')
+define(`up',`%r25')
+define(`n',`%r24')
+
+ASM_START()
+PROLOGUE(mpn_sqr_diagonal)
+
+ fldws,ma 4(up),%fr4r
+ addib,= -1,n,L(end1)
+ ldo 4(rp),rp
+
+ fldws,ma 4(up),%fr6r
+ addib,= -1,n,L(end2)
+ xmpyu %fr4r,%fr4r,%fr5
+
+ fldws,ma 4(up),%fr4r
+ addib,= -1,n,L(end3)
+ xmpyu %fr6r,%fr6r,%fr7
+
+
+LDEF(loop)
+ fldws,ma 4(up),%fr6r
+ fstws %fr5r,-4(rp)
+ fstws,ma %fr5l,8(rp)
+ addib,= -1,n,L(exite)
+ xmpyu %fr4r,%fr4r,%fr5
+ fldws,ma 4(up),%fr4r
+ fstws %fr7r,-4(rp)
+ fstws,ma %fr7l,8(rp)
+ addib,<> -1,n,L(loop)
+ xmpyu %fr6r,%fr6r,%fr7
+
+LDEF(exito)
+ fstws %fr5r,-4(rp)
+ fstws %fr5l,0(rp)
+ xmpyu %fr4r,%fr4r,%fr5
+ fstws %fr7r,4(rp)
+ fstws %fr7l,8(rp)
+ fstws,mb %fr5r,12(rp)
+ bv 0(%r2)
+ fstws %fr5l,4(rp)
+
+LDEF(exite)
+ fstws %fr7r,-4(rp)
+ fstws %fr7l,0(rp)
+ xmpyu %fr6r,%fr6r,%fr7
+ fstws %fr5r,4(rp)
+ fstws %fr5l,8(rp)
+ fstws,mb %fr7r,12(rp)
+ bv 0(%r2)
+ fstws %fr7l,4(rp)
+
+LDEF(end1)
+ xmpyu %fr4r,%fr4r,%fr5
+ fstws %fr5r,-4(rp)
+ bv 0(%r2)
+ fstws,ma %fr5l,8(rp)
+
+LDEF(end2)
+ xmpyu %fr6r,%fr6r,%fr7
+ fstws %fr5r,-4(rp)
+ fstws %fr5l,0(rp)
+ fstws %fr7r,4(rp)
+ bv 0(%r2)
+ fstws %fr7l,8(rp)
+
+LDEF(end3)
+ fstws %fr5r,-4(rp)
+ fstws %fr5l,0(rp)
+ xmpyu %fr4r,%fr4r,%fr5
+ fstws %fr7r,4(rp)
+ fstws %fr7l,8(rp)
+ fstws,mb %fr5r,12(rp)
+ bv 0(%r2)
+ fstws %fr5l,4(rp)
+EPILOGUE(mpn_sqr_diagonal)
diff --git a/gmp/mpn/pa32/hppa2_0/sub_n.asm b/gmp/mpn/pa32/hppa2_0/sub_n.asm
new file mode 100644
index 0000000000..47b3163fe3
--- /dev/null
+++ b/gmp/mpn/pa32/hppa2_0/sub_n.asm
@@ -0,0 +1,107 @@
+dnl HP-PA 2.0 32-bit mpn_sub_n -- Subtract two limb vectors of the same
+dnl length > 0 and store difference in a third limb vector.
+
+dnl Copyright 1997, 1998, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr gr26
+C s1_ptr gr25
+C s2_ptr gr24
+C size gr23
+
+C This runs at 2 cycles/limb on PA8000.
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ sub %r0,%r23,%r22
+ zdep %r22,30,3,%r28 C r28 = 2 * (-n & 7)
+ zdep %r22,29,3,%r22 C r22 = 4 * (-n & 7)
+ sub %r25,%r22,%r25 C offset s1_ptr
+ sub %r24,%r22,%r24 C offset s2_ptr
+ blr %r28,%r0 C branch into loop
+ sub %r26,%r22,%r26 C offset res_ptr and set carry
+
+LDEF(loop)
+ ldw 0(%r25),%r20
+ ldw 0(%r24),%r31
+ subb %r20,%r31,%r20
+ stw %r20,0(%r26)
+
+LDEF(7)
+ ldw 4(%r25),%r21
+ ldw 4(%r24),%r19
+ subb %r21,%r19,%r21
+ stw %r21,4(%r26)
+
+LDEF(6)
+ ldw 8(%r25),%r20
+ ldw 8(%r24),%r31
+ subb %r20,%r31,%r20
+ stw %r20,8(%r26)
+
+LDEF(5)
+ ldw 12(%r25),%r21
+ ldw 12(%r24),%r19
+ subb %r21,%r19,%r21
+ stw %r21,12(%r26)
+
+LDEF(4)
+ ldw 16(%r25),%r20
+ ldw 16(%r24),%r31
+ subb %r20,%r31,%r20
+ stw %r20,16(%r26)
+
+LDEF(3)
+ ldw 20(%r25),%r21
+ ldw 20(%r24),%r19
+ subb %r21,%r19,%r21
+ stw %r21,20(%r26)
+
+LDEF(2)
+ ldw 24(%r25),%r20
+ ldw 24(%r24),%r31
+ subb %r20,%r31,%r20
+ stw %r20,24(%r26)
+
+LDEF(1)
+ ldw 28(%r25),%r21
+ ldo 32(%r25),%r25
+ ldw 28(%r24),%r19
+ subb %r21,%r19,%r21
+ stw %r21,28(%r26)
+ ldo 32(%r24),%r24
+ addib,> -8,%r23,L(loop)
+ ldo 32(%r26),%r26
+
+ addc %r0,%r0,%r28
+ bv (%r2)
+ subi 1,%r28,%r28
+EPILOGUE()
diff --git a/gmp/mpn/pa32/lshift.asm b/gmp/mpn/pa32/lshift.asm
new file mode 100644
index 0000000000..5ea497c1f1
--- /dev/null
+++ b/gmp/mpn/pa32/lshift.asm
@@ -0,0 +1,75 @@
+dnl HP-PA mpn_lshift -- Shift a number left.
+
+dnl Copyright 1992, 1994, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr gr26
+C s_ptr gr25
+C size gr24
+C cnt gr23
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ sh2add %r24,%r25,%r25
+ sh2add %r24,%r26,%r26
+ ldws,mb -4(0,%r25),%r22
+ subi 32,%r23,%r1
+ mtsar %r1
+ addib,= -1,%r24,L(0004)
+ vshd %r0,%r22,%r28 C compute carry out limb
+ ldws,mb -4(0,%r25),%r29
+ addib,= -1,%r24,L(0002)
+ vshd %r22,%r29,%r20
+
+LDEF(loop)
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ addib,= -1,%r24,L(0003)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,<> -1,%r24,L(loop)
+ vshd %r22,%r29,%r20
+
+LDEF(0002)
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+
+LDEF(0003)
+ stws,mb %r20,-4(0,%r26)
+
+LDEF(0004)
+ vshd %r22,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+EPILOGUE()
diff --git a/gmp/mpn/pa32/pa-defs.m4 b/gmp/mpn/pa32/pa-defs.m4
new file mode 100644
index 0000000000..b26e715fc5
--- /dev/null
+++ b/gmp/mpn/pa32/pa-defs.m4
@@ -0,0 +1,64 @@
+divert(-1)
+
+dnl m4 macros for HPPA assembler.
+
+dnl Copyright 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl hppa assembler comments are introduced with ";".
+dnl
+dnl For cooperation with cpp, apparently lines "# 123" set the line number,
+dnl and other lines starting with a "#" are ignored.
+
+changecom(;)
+
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+dnl These are the same as the basic PROLOGUE_cpu and EPILOGUE_cpu in
+dnl mpn/asm-defs.m4, but using .proc / .procend. These are standard and on
+dnl an ELF system they do what .type and .size normally do.
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+ `.code
+ ALIGN(8)
+ .export `$1',entry
+`$1'LABEL_SUFFIX'
+ .proc
+ .callinfo) dnl This is really bogus, but allows us to compile
+ dnl again on hppa machines.
+
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+` .procend')
+
+divert
diff --git a/gmp/mpn/pa32/rshift.asm b/gmp/mpn/pa32/rshift.asm
new file mode 100644
index 0000000000..c5eac830c9
--- /dev/null
+++ b/gmp/mpn/pa32/rshift.asm
@@ -0,0 +1,72 @@
+dnl HP-PA mpn_rshift -- Shift a number right.
+
+dnl Copyright 1992, 1994, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr gr26
+C s_ptr gr25
+C size gr24
+C cnt gr23
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ ldws,ma 4(0,%r25),%r22
+ mtsar %r23
+ addib,= -1,%r24,L(0004)
+ vshd %r22,%r0,%r28 C compute carry out limb
+ ldws,ma 4(0,%r25),%r29
+ addib,= -1,%r24,L(0002)
+ vshd %r29,%r22,%r20
+
+LDEF(loop)
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ addib,= -1,%r24,L(0003)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,<> -1,%r24,L(loop)
+ vshd %r29,%r22,%r20
+
+LDEF(0002)
+ stws,ma %r20,4(0,%r26)
+ vshd %r0,%r29,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+
+LDEF(0003)
+ stws,ma %r20,4(0,%r26)
+
+LDEF(0004)
+ vshd %r0,%r22,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+EPILOGUE()
diff --git a/gmp/mpn/pa32/sub_n.asm b/gmp/mpn/pa32/sub_n.asm
new file mode 100644
index 0000000000..9c71655b98
--- /dev/null
+++ b/gmp/mpn/pa32/sub_n.asm
@@ -0,0 +1,64 @@
+dnl HP-PA mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+dnl store difference in a third limb vector.
+
+dnl Copyright 1992, 1994, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr gr26
+C s1_ptr gr25
+C s2_ptr gr24
+C size gr23
+
+C One might want to unroll this as for other processors, but it turns out that
+C the data cache contention after a store makes such unrolling useless. We
+C can't come under 5 cycles/limb anyway.
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,= -1,%r23,L(end) C check for (SIZE == 1)
+ sub %r20,%r19,%r28 C subtract first limbs ignoring cy
+
+LDEF(loop)
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,<> -1,%r23,L(loop)
+ subb %r20,%r19,%r28
+
+LDEF(end)
+ stws %r28,0(0,%r26)
+ addc %r0,%r0,%r28
+ bv 0(%r2)
+ subi 1,%r28,%r28
+EPILOGUE()
diff --git a/gmp/mpn/pa32/udiv.asm b/gmp/mpn/pa32/udiv.asm
new file mode 100644
index 0000000000..addbf41ef5
--- /dev/null
+++ b/gmp/mpn/pa32/udiv.asm
@@ -0,0 +1,291 @@
+dnl HP-PA __udiv_qrnnd division support, used from longlong.h.
+dnl This version runs fast on pre-PA7000 CPUs.
+
+dnl Copyright 1993, 1994, 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rem_ptr gr26
+C n1 gr25
+C n0 gr24
+C d gr23
+
+C The code size is a bit excessive. We could merge the last two ds;addc
+C sequences by simply moving the "bb,< Odd" instruction down. The only
+C trouble is the FFFFFFFF code that would need some hacking.
+
+ASM_START()
+PROLOGUE(mpn_udiv_qrnnd)
+ comb,< %r23,0,L(largedivisor)
+ sub %r0,%r23,%r1 C clear cy as side-effect
+ ds %r0,%r1,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r28
+ ds %r25,%r23,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r23,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r28,%r28,%r28
+
+LDEF(largedivisor)
+ extru %r24,31,1,%r19 C r19 = n0 & 1
+ bb,< %r23,31,L(odd)
+ extru %r23,30,31,%r22 C r22 = d >> 1
+ shd %r25,%r24,1,%r24 C r24 = new n0
+ extru %r25,30,31,%r25 C r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r19,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r24,%r24,%r28
+
+LDEF(odd)
+ addib,sv,n 1,%r22,L(FFFFFFFF) C r22 = (d / 2 + 1)
+ shd %r25,%r24,1,%r24 C r24 = new n0
+ extru %r25,30,31,%r25 C r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r28
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r19,%r25
+C We have computed (n1,,n0) / (d + 1), q' = r28, r' = r25
+ add,nuv %r28,%r25,%r25
+ addl %r25,%r1,%r25
+ addc %r0,%r28,%r28
+ sub,<< %r25,%r23,%r0
+ addl %r25,%r1,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r28,%r28
+
+C This is just a special case of the code above.
+C We come here when d == 0xFFFFFFFF
+LDEF(FFFFFFFF)
+ add,uv %r25,%r24,%r24
+ sub,<< %r24,%r23,%r0
+ ldo 1(%r24),%r24
+ stws %r24,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r25,%r28
+EPILOGUE()
diff --git a/gmp/mpn/pa64/README b/gmp/mpn/pa64/README
new file mode 100644
index 0000000000..a51ce028a4
--- /dev/null
+++ b/gmp/mpn/pa64/README
@@ -0,0 +1,78 @@
+Copyright 1999, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+This directory contains mpn functions for 64-bit PA-RISC 2.0.
+
+PIPELINE SUMMARY
+
+The PA8x00 processors have an orthogonal 4-way out-of-order pipeline. Each
+cycle two ALU operations and two MEM operations can issue, but just one of the
+MEM operations may be a store. The two ALU operations can be almost any
+combination of non-memory operations. Unlike every other processor, integer
+and fp operations are completely equal here; they both count as just ALU
+operations.
+
+Unfortunately, some operations cause hickups in the pipeline. Combining
+carry-consuming operations like ADD,DC with operations that does not set carry
+like ADD,L cause long delays. Skip operations also seem to cause hickups. If
+several ADD,DC are issued consecutively, or if plain carry-generating ADD feed
+ADD,DC, stalling does not occur. We can effectively issue two ADD,DC
+operations/cycle.
+
+Latency scheduling is not as important as making sure to have a mix of ALU and
+MEM operations, but for full pipeline utilization, it is still a good idea to
+do some amount of latency scheduling.
+
+Like for all other processors, RAW memory scheduling is critically important.
+Since integer multiplication takes place in the floating-point unit, the GMP
+code needs to handle this problem frequently.
+
+STATUS
+
+* mpn_lshift and mpn_rshift run at 1.5 cycles/limb on PA8000 and at 1.0
+ cycles/limb on PA8500. With latency scheduling, the numbers could
+ probably be improved to 1.0 cycles/limb for all PA8x00 chips.
+
+* mpn_add_n and mpn_sub_n run at 2.0 cycles/limb on PA8000 and at about
+ 1.6875 cycles/limb on PA8500. With latency scheduling, this could
+ probably be improved to get close to 1.5 cycles/limb. A problem is the
+ stalling of carry-inputting instructions after instructions that do not
+ write to carry.
+
+* mpn_mul_1, mpn_addmul_1, and mpn_submul_1 run at between 5.625 and 6.375
+ on PA8500 and later, and about a cycle/limb slower on older chips. The
+ code uses ADD,DC for adjacent limbs, and relies heavily on reordering.
+
+
+REFERENCES
+
+Hewlett Packard, "64-Bit Runtime Architecture for PA-RISC 2.0", version 3.3,
+October 1997.
diff --git a/gmp/mpn/pa64/addmul_1.asm b/gmp/mpn/pa64/addmul_1.asm
new file mode 100644
index 0000000000..2cb9af9f14
--- /dev/null
+++ b/gmp/mpn/pa64/addmul_1.asm
@@ -0,0 +1,693 @@
+dnl HP-PA 2.0 64-bit mpn_addmul_1 -- Multiply a limb vector with a limb and
+dnl add the result to a second limb vector.
+
+dnl Copyright 1998-2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 8000,8200: 7
+C 8500,8600,8700: 6.375
+
+C The feed-in and wind-down code has not yet been scheduled. Many cycles
+C could be saved there per call.
+
+C DESCRIPTION:
+C The main loop "BIG" is 4-way unrolled, mainly to allow
+C effective use of ADD,DC. Delays in moving data via the cache from the FP
+C registers to the IU registers, have demanded a deep software pipeline, and
+C a lot of stack slots for partial products in flight.
+C
+C CODE STRUCTURE:
+C save-some-registers
+C do 0, 1, 2, or 3 limbs
+C if done, restore-some-regs and return
+C save-many-regs
+C do 4, 8, ... limb
+C restore-all-regs
+
+C STACK LAYOUT:
+C HP-PA stack grows upwards. We could allocate 8 fewer slots by using the
+C slots marked FREE, as well as some slots in the caller's "frame marker".
+C
+C -00 <- r30
+C -08 FREE
+C -10 tmp
+C -18 tmp
+C -20 tmp
+C -28 tmp
+C -30 tmp
+C -38 tmp
+C -40 tmp
+C -48 tmp
+C -50 tmp
+C -58 tmp
+C -60 tmp
+C -68 tmp
+C -70 tmp
+C -78 tmp
+C -80 tmp
+C -88 tmp
+C -90 FREE
+C -98 FREE
+C -a0 FREE
+C -a8 FREE
+C -b0 r13
+C -b8 r12
+C -c0 r11
+C -c8 r10
+C -d0 r8
+C -d8 r8
+C -e0 r7
+C -e8 r6
+C -f0 r5
+C -f8 r4
+C -100 r3
+C Previous frame:
+C [unused area]
+C -38/-138 vlimb home slot. For 2.0N, the vlimb arg will arrive here.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS:
+define(`rp',`%r26') C
+define(`up',`%r25') C
+define(`n',`%r24') C
+define(`vlimb',`%r23') C
+
+define(`climb',`%r23') C
+
+ifdef(`HAVE_ABI_2_0w',
+` .level 2.0w
+',` .level 2.0
+')
+PROLOGUE(mpn_addmul_1)
+
+ifdef(`HAVE_ABI_2_0w',
+` std vlimb, -0x38(%r30) C store vlimb into "home" slot
+')
+ std,ma %r3, 0x100(%r30)
+ std %r4, -0xf8(%r30)
+ std %r5, -0xf0(%r30)
+ ldo 0(%r0), climb C clear climb
+ fldd -0x138(%r30), %fr8 C put vlimb in fp register
+
+define(`p032a1',`%r1') C
+define(`p032a2',`%r19') C
+
+define(`m032',`%r20') C
+define(`m096',`%r21') C
+
+define(`p000a',`%r22') C
+define(`p064a',`%r29') C
+
+define(`s000',`%r31') C
+
+define(`ma000',`%r4') C
+define(`ma064',`%r20') C
+
+define(`r000',`%r3') C
+
+ extrd,u n, 63, 2, %r5
+ cmpb,= %r5, %r0, L(BIG)
+ nop
+
+ fldd 0(up), %fr4
+ ldo 8(up), up
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr4R, %fr24
+ xmpyu %fr8L, %fr4L, %fr25
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+ addib,<> -1, %r5, L(two_or_more)
+ fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+LDEF(one)
+ ldd -0x78(%r30), p032a1
+ ldd -0x70(%r30), p032a2
+ ldd -0x80(%r30), p000a
+ b L(0_one_out)
+ ldd -0x68(%r30), p064a
+
+LDEF(two_or_more)
+ fldd 0(up), %fr4
+ ldo 8(up), up
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ ldd -0x78(%r30), p032a1
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr4R, %fr24
+ xmpyu %fr8L, %fr4L, %fr25
+ ldd -0x70(%r30), p032a2
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ ldd -0x80(%r30), p000a
+ fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+ ldd -0x68(%r30), p064a
+ addib,<> -1, %r5, L(three_or_more)
+ fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+LDEF(two)
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ ldd 0(rp), r000
+ b L(0_two_out)
+ depd m096, 31, 32, ma064
+
+LDEF(three_or_more)
+ fldd 0(up), %fr4
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ ldd 0(rp), r000
+C addib,= -1, %r5, L(0_out)
+ depd m096, 31, 32, ma064
+LDEF(loop0)
+C xmpyu %fr8R, %fr4L, %fr22
+C xmpyu %fr8L, %fr4R, %fr23
+C ldd -0x78(%r30), p032a1
+C fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+C
+C xmpyu %fr8R, %fr4R, %fr24
+C xmpyu %fr8L, %fr4L, %fr25
+C ldd -0x70(%r30), p032a2
+C fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+C
+C ldo 8(rp), rp
+C add climb, p000a, s000
+C ldd -0x80(%r30), p000a
+C fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+C
+C add,dc p064a, %r0, climb
+C ldo 8(up), up
+C ldd -0x68(%r30), p064a
+C fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+C
+C add ma000, s000, s000
+C add,dc ma064, climb, climb
+C fldd 0(up), %fr4
+C
+C add r000, s000, s000
+C add,dc %r0, climb, climb
+C std s000, -8(rp)
+C
+C add p032a1, p032a2, m032
+C add,dc %r0, %r0, m096
+C
+C depd,z m032, 31, 32, ma000
+C extrd,u m032, 31, 32, ma064
+C ldd 0(rp), r000
+C addib,<> -1, %r5, L(loop0)
+C depd m096, 31, 32, ma064
+LDEF(0_out)
+ ldo 8(up), up
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ ldd -0x78(%r30), p032a1
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr4R, %fr24
+ xmpyu %fr8L, %fr4L, %fr25
+ ldd -0x70(%r30), p032a2
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ ldo 8(rp), rp
+ add climb, p000a, s000
+ ldd -0x80(%r30), p000a
+ fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+ add,dc p064a, %r0, climb
+ ldd -0x68(%r30), p064a
+ fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+ add ma000, s000, s000
+ add,dc ma064, climb, climb
+ add r000, s000, s000
+ add,dc %r0, climb, climb
+ std s000, -8(rp)
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ ldd 0(rp), r000
+ depd m096, 31, 32, ma064
+LDEF(0_two_out)
+ ldd -0x78(%r30), p032a1
+ ldd -0x70(%r30), p032a2
+ ldo 8(rp), rp
+ add climb, p000a, s000
+ ldd -0x80(%r30), p000a
+ add,dc p064a, %r0, climb
+ ldd -0x68(%r30), p064a
+ add ma000, s000, s000
+ add,dc ma064, climb, climb
+ add r000, s000, s000
+ add,dc %r0, climb, climb
+ std s000, -8(rp)
+LDEF(0_one_out)
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ ldd 0(rp), r000
+ depd m096, 31, 32, ma064
+
+ add climb, p000a, s000
+ add,dc p064a, %r0, climb
+ add ma000, s000, s000
+ add,dc ma064, climb, climb
+ add r000, s000, s000
+ add,dc %r0, climb, climb
+ std s000, 0(rp)
+
+ cmpib,>= 4, n, L(done)
+ ldo 8(rp), rp
+
+C 4-way unrolled code.
+
+LDEF(BIG)
+
+define(`p032a1',`%r1') C
+define(`p032a2',`%r19') C
+define(`p096b1',`%r20') C
+define(`p096b2',`%r21') C
+define(`p160c1',`%r22') C
+define(`p160c2',`%r29') C
+define(`p224d1',`%r31') C
+define(`p224d2',`%r3') C
+ C
+define(`m032',`%r4') C
+define(`m096',`%r5') C
+define(`m160',`%r6') C
+define(`m224',`%r7') C
+define(`m288',`%r8') C
+ C
+define(`p000a',`%r1') C
+define(`p064a',`%r19') C
+define(`p064b',`%r20') C
+define(`p128b',`%r21') C
+define(`p128c',`%r22') C
+define(`p192c',`%r29') C
+define(`p192d',`%r31') C
+define(`p256d',`%r3') C
+ C
+define(`s000',`%r10') C
+define(`s064',`%r11') C
+define(`s128',`%r12') C
+define(`s192',`%r13') C
+ C
+define(`ma000',`%r9') C
+define(`ma064',`%r4') C
+define(`ma128',`%r5') C
+define(`ma192',`%r6') C
+define(`ma256',`%r7') C
+ C
+define(`r000',`%r1') C
+define(`r064',`%r19') C
+define(`r128',`%r20') C
+define(`r192',`%r21') C
+
+ std %r6, -0xe8(%r30)
+ std %r7, -0xe0(%r30)
+ std %r8, -0xd8(%r30)
+ std %r9, -0xd0(%r30)
+ std %r10, -0xc8(%r30)
+ std %r11, -0xc0(%r30)
+ std %r12, -0xb8(%r30)
+ std %r13, -0xb0(%r30)
+
+ifdef(`HAVE_ABI_2_0w',
+` extrd,u n, 61, 62, n C right shift 2
+',` extrd,u n, 61, 30, n C right shift 2, zero extend
+')
+
+LDEF(4_or_more)
+ fldd 0(up), %fr4
+ fldd 8(up), %fr5
+ fldd 16(up), %fr6
+ fldd 24(up), %fr7
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ xmpyu %fr8R, %fr5L, %fr24
+ xmpyu %fr8L, %fr5R, %fr25
+ xmpyu %fr8R, %fr6L, %fr26
+ xmpyu %fr8L, %fr6R, %fr27
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr7L, %fr28
+ xmpyu %fr8L, %fr7R, %fr29
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ xmpyu %fr8R, %fr4R, %fr30
+ xmpyu %fr8L, %fr4L, %fr31
+ fstd %fr24, -0x38(%r30) C mid product to -0x38..-0x31
+ xmpyu %fr8R, %fr5R, %fr22
+ xmpyu %fr8L, %fr5L, %fr23
+ fstd %fr25, -0x30(%r30) C mid product to -0x30..-0x29
+ xmpyu %fr8R, %fr6R, %fr24
+ xmpyu %fr8L, %fr6L, %fr25
+ fstd %fr26, -0x58(%r30) C mid product to -0x58..-0x51
+ xmpyu %fr8R, %fr7R, %fr26
+ fstd %fr27, -0x50(%r30) C mid product to -0x50..-0x49
+ addib,<> -1, n, L(8_or_more)
+ xmpyu %fr8L, %fr7L, %fr27
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+ ldd -0x78(%r30), p032a1
+ ldd -0x70(%r30), p032a2
+ ldd -0x38(%r30), p096b1
+ ldd -0x30(%r30), p096b2
+ ldd -0x58(%r30), p160c1
+ ldd -0x50(%r30), p160c2
+ ldd -0x18(%r30), p224d1
+ ldd -0x10(%r30), p224d2
+ b L(end1)
+ nop
+
+LDEF(8_or_more)
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+ ldo 32(up), up
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+ fldd 0(up), %fr4
+ fldd 8(up), %fr5
+ fldd 16(up), %fr6
+ fldd 24(up), %fr7
+ xmpyu %fr8R, %fr4L, %fr22
+ ldd -0x78(%r30), p032a1
+ xmpyu %fr8L, %fr4R, %fr23
+ xmpyu %fr8R, %fr5L, %fr24
+ ldd -0x70(%r30), p032a2
+ xmpyu %fr8L, %fr5R, %fr25
+ xmpyu %fr8R, %fr6L, %fr26
+ ldd -0x38(%r30), p096b1
+ xmpyu %fr8L, %fr6R, %fr27
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr7L, %fr28
+ ldd -0x30(%r30), p096b2
+ xmpyu %fr8L, %fr7R, %fr29
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ xmpyu %fr8R, %fr4R, %fr30
+ ldd -0x58(%r30), p160c1
+ xmpyu %fr8L, %fr4L, %fr31
+ fstd %fr24, -0x38(%r30) C mid product to -0x38..-0x31
+ xmpyu %fr8R, %fr5R, %fr22
+ ldd -0x50(%r30), p160c2
+ xmpyu %fr8L, %fr5L, %fr23
+ fstd %fr25, -0x30(%r30) C mid product to -0x30..-0x29
+ xmpyu %fr8R, %fr6R, %fr24
+ ldd -0x18(%r30), p224d1
+ xmpyu %fr8L, %fr6L, %fr25
+ fstd %fr26, -0x58(%r30) C mid product to -0x58..-0x51
+ xmpyu %fr8R, %fr7R, %fr26
+ ldd -0x10(%r30), p224d2
+ fstd %fr27, -0x50(%r30) C mid product to -0x50..-0x49
+ addib,= -1, n, L(end2)
+ xmpyu %fr8L, %fr7L, %fr27
+LDEF(loop)
+ add p032a1, p032a2, m032
+ ldd -0x80(%r30), p000a
+ add,dc p096b1, p096b2, m096
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+
+ add,dc p160c1, p160c2, m160
+ ldd -0x68(%r30), p064a
+ add,dc p224d1, p224d2, m224
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+
+ add,dc %r0, %r0, m288
+ ldd -0x40(%r30), p064b
+ ldo 32(up), up
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+
+ depd,z m032, 31, 32, ma000
+ ldd -0x28(%r30), p128b
+ extrd,u m032, 31, 32, ma064
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+
+ depd m096, 31, 32, ma064
+ ldd -0x60(%r30), p128c
+ extrd,u m096, 31, 32, ma128
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+
+ depd m160, 31, 32, ma128
+ ldd -0x48(%r30), p192c
+ extrd,u m160, 31, 32, ma192
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+
+ depd m224, 31, 32, ma192
+ ldd -0x20(%r30), p192d
+ extrd,u m224, 31, 32, ma256
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+
+ depd m288, 31, 32, ma256
+ ldd -0x88(%r30), p256d
+ add climb, p000a, s000
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+
+ add,dc p064a, p064b, s064
+ ldd 0(rp), r000
+ add,dc p128b, p128c, s128
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+
+ add,dc p192c, p192d, s192
+ ldd 8(rp), r064
+ add,dc p256d, %r0, climb
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+
+ ldd 16(rp), r128
+ add ma000, s000, s000 C accum mid 0
+ ldd 24(rp), r192
+ add,dc ma064, s064, s064 C accum mid 1
+
+ add,dc ma128, s128, s128 C accum mid 2
+ fldd 0(up), %fr4
+ add,dc ma192, s192, s192 C accum mid 3
+ fldd 8(up), %fr5
+
+ add,dc ma256, climb, climb
+ fldd 16(up), %fr6
+ add r000, s000, s000 C accum rlimb 0
+ fldd 24(up), %fr7
+
+ add,dc r064, s064, s064 C accum rlimb 1
+ add,dc r128, s128, s128 C accum rlimb 2
+ std s000, 0(rp)
+
+ add,dc r192, s192, s192 C accum rlimb 3
+ add,dc %r0, climb, climb
+ std s064, 8(rp)
+
+ xmpyu %fr8R, %fr4L, %fr22
+ ldd -0x78(%r30), p032a1
+ xmpyu %fr8L, %fr4R, %fr23
+ std s128, 16(rp)
+
+ xmpyu %fr8R, %fr5L, %fr24
+ ldd -0x70(%r30), p032a2
+ xmpyu %fr8L, %fr5R, %fr25
+ std s192, 24(rp)
+
+ xmpyu %fr8R, %fr6L, %fr26
+ ldd -0x38(%r30), p096b1
+ xmpyu %fr8L, %fr6R, %fr27
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+
+ xmpyu %fr8R, %fr7L, %fr28
+ ldd -0x30(%r30), p096b2
+ xmpyu %fr8L, %fr7R, %fr29
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+
+ xmpyu %fr8R, %fr4R, %fr30
+ ldd -0x58(%r30), p160c1
+ xmpyu %fr8L, %fr4L, %fr31
+ fstd %fr24, -0x38(%r30) C mid product to -0x38..-0x31
+
+ xmpyu %fr8R, %fr5R, %fr22
+ ldd -0x50(%r30), p160c2
+ xmpyu %fr8L, %fr5L, %fr23
+ fstd %fr25, -0x30(%r30) C mid product to -0x30..-0x29
+
+ xmpyu %fr8R, %fr6R, %fr24
+ ldd -0x18(%r30), p224d1
+ xmpyu %fr8L, %fr6L, %fr25
+ fstd %fr26, -0x58(%r30) C mid product to -0x58..-0x51
+
+ xmpyu %fr8R, %fr7R, %fr26
+ ldd -0x10(%r30), p224d2
+ fstd %fr27, -0x50(%r30) C mid product to -0x50..-0x49
+ xmpyu %fr8L, %fr7L, %fr27
+
+ addib,<> -1, n, L(loop)
+ ldo 32(rp), rp
+
+LDEF(end2)
+ add p032a1, p032a2, m032
+ ldd -0x80(%r30), p000a
+ add,dc p096b1, p096b2, m096
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+ add,dc p160c1, p160c2, m160
+ ldd -0x68(%r30), p064a
+ add,dc p224d1, p224d2, m224
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+ add,dc %r0, %r0, m288
+ ldd -0x40(%r30), p064b
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+ depd,z m032, 31, 32, ma000
+ ldd -0x28(%r30), p128b
+ extrd,u m032, 31, 32, ma064
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+ depd m096, 31, 32, ma064
+ ldd -0x60(%r30), p128c
+ extrd,u m096, 31, 32, ma128
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+ depd m160, 31, 32, ma128
+ ldd -0x48(%r30), p192c
+ extrd,u m160, 31, 32, ma192
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+ depd m224, 31, 32, ma192
+ ldd -0x20(%r30), p192d
+ extrd,u m224, 31, 32, ma256
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+ depd m288, 31, 32, ma256
+ ldd -0x88(%r30), p256d
+ add climb, p000a, s000
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+ add,dc p064a, p064b, s064
+ ldd 0(rp), r000
+ add,dc p128b, p128c, s128
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+ add,dc p192c, p192d, s192
+ ldd 8(rp), r064
+ add,dc p256d, %r0, climb
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+ ldd 16(rp), r128
+ add ma000, s000, s000 C accum mid 0
+ ldd 24(rp), r192
+ add,dc ma064, s064, s064 C accum mid 1
+ add,dc ma128, s128, s128 C accum mid 2
+ add,dc ma192, s192, s192 C accum mid 3
+ add,dc ma256, climb, climb
+ add r000, s000, s000 C accum rlimb 0
+ add,dc r064, s064, s064 C accum rlimb 1
+ add,dc r128, s128, s128 C accum rlimb 2
+ std s000, 0(rp)
+ add,dc r192, s192, s192 C accum rlimb 3
+ add,dc %r0, climb, climb
+ std s064, 8(rp)
+ ldd -0x78(%r30), p032a1
+ std s128, 16(rp)
+ ldd -0x70(%r30), p032a2
+ std s192, 24(rp)
+ ldd -0x38(%r30), p096b1
+ ldd -0x30(%r30), p096b2
+ ldd -0x58(%r30), p160c1
+ ldd -0x50(%r30), p160c2
+ ldd -0x18(%r30), p224d1
+ ldd -0x10(%r30), p224d2
+ ldo 32(rp), rp
+
+LDEF(end1)
+ add p032a1, p032a2, m032
+ ldd -0x80(%r30), p000a
+ add,dc p096b1, p096b2, m096
+ add,dc p160c1, p160c2, m160
+ ldd -0x68(%r30), p064a
+ add,dc p224d1, p224d2, m224
+ add,dc %r0, %r0, m288
+ ldd -0x40(%r30), p064b
+ depd,z m032, 31, 32, ma000
+ ldd -0x28(%r30), p128b
+ extrd,u m032, 31, 32, ma064
+ depd m096, 31, 32, ma064
+ ldd -0x60(%r30), p128c
+ extrd,u m096, 31, 32, ma128
+ depd m160, 31, 32, ma128
+ ldd -0x48(%r30), p192c
+ extrd,u m160, 31, 32, ma192
+ depd m224, 31, 32, ma192
+ ldd -0x20(%r30), p192d
+ extrd,u m224, 31, 32, ma256
+ depd m288, 31, 32, ma256
+ ldd -0x88(%r30), p256d
+ add climb, p000a, s000
+ add,dc p064a, p064b, s064
+ ldd 0(rp), r000
+ add,dc p128b, p128c, s128
+ add,dc p192c, p192d, s192
+ ldd 8(rp), r064
+ add,dc p256d, %r0, climb
+ ldd 16(rp), r128
+ add ma000, s000, s000 C accum mid 0
+ ldd 24(rp), r192
+ add,dc ma064, s064, s064 C accum mid 1
+ add,dc ma128, s128, s128 C accum mid 2
+ add,dc ma192, s192, s192 C accum mid 3
+ add,dc ma256, climb, climb
+ add r000, s000, s000 C accum rlimb 0
+ add,dc r064, s064, s064 C accum rlimb 1
+ add,dc r128, s128, s128 C accum rlimb 2
+ std s000, 0(rp)
+ add,dc r192, s192, s192 C accum rlimb 3
+ add,dc %r0, climb, climb
+ std s064, 8(rp)
+ std s128, 16(rp)
+ std s192, 24(rp)
+
+ ldd -0xb0(%r30), %r13
+ ldd -0xb8(%r30), %r12
+ ldd -0xc0(%r30), %r11
+ ldd -0xc8(%r30), %r10
+ ldd -0xd0(%r30), %r9
+ ldd -0xd8(%r30), %r8
+ ldd -0xe0(%r30), %r7
+ ldd -0xe8(%r30), %r6
+LDEF(done)
+ifdef(`HAVE_ABI_2_0w',
+` copy climb, %r28
+',` extrd,u climb, 63, 32, %r29
+ extrd,u climb, 31, 32, %r28
+')
+ ldd -0xf0(%r30), %r5
+ ldd -0xf8(%r30), %r4
+ bve (%r2)
+ ldd,mb -0x100(%r30), %r3
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/pa64/aors_n.asm b/gmp/mpn/pa64/aors_n.asm
new file mode 100644
index 0000000000..ab4536fefb
--- /dev/null
+++ b/gmp/mpn/pa64/aors_n.asm
@@ -0,0 +1,130 @@
+dnl HP-PA 2.0 mpn_add_n, mpn_sub_n
+
+dnl Copyright 1997, 2000, 2002, 2003, 2009, 2010 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl This runs at 2 cycles/limb on PA8000 and 1.6875 cycles/limb on PA8500. It
+dnl should be possible to reach the cache bandwidth 1.5 cycles/limb at least
+dnl with PA8500. The problem now is stalling of the first ADD,DC after LDO,
+dnl where the processor gets confused about where carry comes from.
+
+include(`../config.m4')
+
+dnl INPUT PARAMETERS
+define(`rp',`%r26')
+define(`up',`%r25')
+define(`vp',`%r24')
+define(`n',`%r23')
+
+ifdef(`OPERATION_add_n', `
+ define(ADCSBC, `add,dc')
+ define(INITCY, `addi -1,%r22,%r0')
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(ADCSBC, `sub,db')
+ define(INITCY, `subi 0,%r22,%r0')
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ifdef(`HAVE_ABI_2_0w',
+` .level 2.0w
+',` .level 2.0
+')
+PROLOGUE(func_nc)
+ifdef(`HAVE_ABI_2_0w',
+` b L(com)
+ nop
+',` b L(com)
+ ldw -52(%r30), %r22
+')
+EPILOGUE()
+PROLOGUE(func)
+ ldi 0, %r22
+LDEF(com)
+ sub %r0, n, %r21
+ depw,z %r21, 30, 3, %r28 C r28 = 2 * (-n & 7)
+ depw,z %r21, 28, 3, %r21 C r21 = 8 * (-n & 7)
+ sub up, %r21, up C offset up
+ sub vp, %r21, vp C offset vp
+ sub rp, %r21, rp C offset rp
+ blr %r28, %r0 C branch into loop
+ INITCY
+
+LDEF(loop)
+ ldd 0(up), %r20
+ ldd 0(vp), %r31
+ ADCSBC %r20, %r31, %r20
+ std %r20, 0(rp)
+LDEF(7) ldd 8(up), %r21
+ ldd 8(vp), %r19
+ ADCSBC %r21, %r19, %r21
+ std %r21, 8(rp)
+LDEF(6) ldd 16(up), %r20
+ ldd 16(vp), %r31
+ ADCSBC %r20, %r31, %r20
+ std %r20, 16(rp)
+LDEF(5) ldd 24(up), %r21
+ ldd 24(vp), %r19
+ ADCSBC %r21, %r19, %r21
+ std %r21, 24(rp)
+LDEF(4) ldd 32(up), %r20
+ ldd 32(vp), %r31
+ ADCSBC %r20, %r31, %r20
+ std %r20, 32(rp)
+LDEF(3) ldd 40(up), %r21
+ ldd 40(vp), %r19
+ ADCSBC %r21, %r19, %r21
+ std %r21, 40(rp)
+LDEF(2) ldd 48(up), %r20
+ ldd 48(vp), %r31
+ ADCSBC %r20, %r31, %r20
+ std %r20, 48(rp)
+LDEF(1) ldd 56(up), %r21
+ ldd 56(vp), %r19
+ ADCSBC %r21, %r19, %r21
+ ldo 64(up), up
+ std %r21, 56(rp)
+ ldo 64(vp), vp
+ addib,> -8, n, L(loop)
+ ldo 64(rp), rp
+
+ add,dc %r0, %r0, %r29
+ifdef(`OPERATION_sub_n',`
+ subi 1, %r29, %r29
+')
+ bve (%r2)
+ifdef(`HAVE_ABI_2_0w',
+` copy %r29, %r28
+',` ldi 0, %r28
+')
+EPILOGUE()
diff --git a/gmp/mpn/pa64/aorslsh1_n.asm b/gmp/mpn/pa64/aorslsh1_n.asm
new file mode 100644
index 0000000000..2a55ddea30
--- /dev/null
+++ b/gmp/mpn/pa64/aorslsh1_n.asm
@@ -0,0 +1,228 @@
+dnl PA64 mpn_addlsh1_n/mpn_sublsh1_n -- rp[] = up[] +- (vp[] << 1).
+
+dnl Copyright 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 8000,8200: 2
+C 8500,8600,8700: 1.75
+
+C TODO
+C * Write special feed-in code for each (n mod 8). (See the ia64 code.)
+C * Try to make this run at closer to 1.5 c/l.
+C * Set up register aliases (define(`u0',`%r19')).
+C * Explicitly align loop.
+
+dnl INPUT PARAMETERS
+define(`rp',`%r26')
+define(`up',`%r25')
+define(`vp',`%r24')
+define(`n',`%r23')
+
+ifdef(`OPERATION_addlsh1_n',`
+ define(ADCSBC, `add,dc')
+ define(INITC, `ldi 0,')
+ define(func, mpn_addlsh1_n)
+')
+ifdef(`OPERATION_sublsh1_n',`
+ define(ADCSBC, `sub,db')
+ define(INITC, `ldi 1,')
+ define(func, mpn_sublsh1_n)
+')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n)
+
+ifdef(`HAVE_ABI_2_0w',`
+ define(LEVEL, `.level 2.0w')
+ define(RETREG, `%r28')
+ define(CLRRET1, `dnl')
+')
+ifdef(`HAVE_ABI_2_0n',`
+ define(LEVEL, `.level 2.0')
+ define(RETREG, `%r29')
+ define(CLRRET1, `ldi 0, %r28')
+')
+
+ LEVEL
+PROLOGUE(func)
+ std,ma %r3, 0x100(%r30) C save reg
+
+ INITC %r1 C init saved cy
+
+C Primitive code for the first (n mod 8) limbs:
+ extrd,u n, 63, 3, %r22 C count for loop0
+ comib,= 0, %r22, L(unrolled) C skip loop0?
+ copy %r0, %r28
+LDEF(loop0)
+ ldd 0(vp), %r21
+ ldo 8(vp), vp
+ ldd 0(up), %r19
+ ldo 8(up), up
+ shrpd %r21, %r28, 63, %r31
+ addi -1, %r1, %r0 C restore cy
+ ADCSBC %r19, %r31, %r29
+ std %r29, 0(rp)
+ add,dc %r0, %r0, %r1 C save cy
+ copy %r21, %r28
+ addib,> -1, %r22, L(loop0)
+ ldo 8(rp), rp
+
+ addib,>= -8, n, L(unrolled)
+ addi -1, %r1, %r0 C restore cy
+
+ shrpd %r0, %r28, 63, %r28
+ ADCSBC %r0, %r28, RETREG
+ifdef(`OPERATION_sublsh1_n',
+` sub %r0, RETREG, RETREG')
+ CLRRET1
+
+ bve (%r2)
+ ldd,mb -0x100(%r30), %r3
+
+
+LDEF(unrolled)
+ std %r4, -0xf8(%r30) C save reg
+ ldd 0(vp), %r4
+ std %r5, -0xf0(%r30) C save reg
+ ldd 8(vp), %r5
+ std %r6, -0xe8(%r30) C save reg
+ ldd 16(vp), %r6
+ std %r7, -0xe0(%r30) C save reg
+
+ ldd 24(vp), %r7
+ shrpd %r4, %r28, 63, %r31
+ std %r8, -0xd8(%r30) C save reg
+ ldd 32(vp), %r8
+ shrpd %r5, %r4, 63, %r4
+ std %r9, -0xd0(%r30) C save reg
+ ldd 40(vp), %r9
+ shrpd %r6, %r5, 63, %r5
+ ldd 48(vp), %r3
+ shrpd %r7, %r6, 63, %r6
+ ldd 56(vp), %r28
+ shrpd %r8, %r7, 63, %r7
+ ldd 0(up), %r19
+ shrpd %r9, %r8, 63, %r8
+ ldd 8(up), %r20
+ shrpd %r3, %r9, 63, %r9
+ ldd 16(up), %r21
+ shrpd %r28, %r3, 63, %r3
+ ldd 24(up), %r22
+
+ nop C alignment FIXME
+ addib,<= -8, n, L(end)
+ addi -1, %r1, %r0 C restore cy
+LDEF(loop)
+ ADCSBC %r19, %r31, %r29
+ ldd 32(up), %r19
+ std %r29, 0(rp)
+ ADCSBC %r20, %r4, %r29
+ ldd 40(up), %r20
+ std %r29, 8(rp)
+ ADCSBC %r21, %r5, %r29
+ ldd 48(up), %r21
+ std %r29, 16(rp)
+ ADCSBC %r22, %r6, %r29
+ ldd 56(up), %r22
+ std %r29, 24(rp)
+ ADCSBC %r19, %r7, %r29
+ ldd 64(vp), %r4
+ std %r29, 32(rp)
+ ADCSBC %r20, %r8, %r29
+ ldd 72(vp), %r5
+ std %r29, 40(rp)
+ ADCSBC %r21, %r9, %r29
+ ldd 80(vp), %r6
+ std %r29, 48(rp)
+ ADCSBC %r22, %r3, %r29
+ std %r29, 56(rp)
+
+ add,dc %r0, %r0, %r1 C save cy
+
+ ldd 88(vp), %r7
+ shrpd %r4, %r28, 63, %r31
+ ldd 96(vp), %r8
+ shrpd %r5, %r4, 63, %r4
+ ldd 104(vp), %r9
+ shrpd %r6, %r5, 63, %r5
+ ldd 112(vp), %r3
+ shrpd %r7, %r6, 63, %r6
+ ldd 120(vp), %r28
+ shrpd %r8, %r7, 63, %r7
+ ldd 64(up), %r19
+ shrpd %r9, %r8, 63, %r8
+ ldd 72(up), %r20
+ shrpd %r3, %r9, 63, %r9
+ ldd 80(up), %r21
+ shrpd %r28, %r3, 63, %r3
+ ldd 88(up), %r22
+
+ ldo 64(vp), vp
+ ldo 64(rp), rp
+ ldo 64(up), up
+ addib,> -8, n, L(loop)
+ addi -1, %r1, %r0 C restore cy
+LDEF(end)
+ ADCSBC %r19, %r31, %r29
+ ldd 32(up), %r19
+ std %r29, 0(rp)
+ ADCSBC %r20, %r4, %r29
+ ldd 40(up), %r20
+ std %r29, 8(rp)
+ ADCSBC %r21, %r5, %r29
+ ldd 48(up), %r21
+ std %r29, 16(rp)
+ ADCSBC %r22, %r6, %r29
+ ldd 56(up), %r22
+ std %r29, 24(rp)
+ ADCSBC %r19, %r7, %r29
+ ldd -0xf8(%r30), %r4 C restore reg
+ std %r29, 32(rp)
+ ADCSBC %r20, %r8, %r29
+ ldd -0xf0(%r30), %r5 C restore reg
+ std %r29, 40(rp)
+ ADCSBC %r21, %r9, %r29
+ ldd -0xe8(%r30), %r6 C restore reg
+ std %r29, 48(rp)
+ ADCSBC %r22, %r3, %r29
+ ldd -0xe0(%r30), %r7 C restore reg
+ std %r29, 56(rp)
+
+ shrpd %r0, %r28, 63, %r28
+ ldd -0xd8(%r30), %r8 C restore reg
+ ADCSBC %r0, %r28, RETREG
+ifdef(`OPERATION_sublsh1_n',
+` sub %r0, RETREG, RETREG')
+ CLRRET1
+
+ ldd -0xd0(%r30), %r9 C restore reg
+ bve (%r2)
+ ldd,mb -0x100(%r30), %r3 C restore reg
+EPILOGUE()
diff --git a/gmp/mpn/pa64/gmp-mparam.h b/gmp/mpn/pa64/gmp-mparam.h
new file mode 100644
index 0000000000..c2719c3c89
--- /dev/null
+++ b/gmp/mpn/pa64/gmp-mparam.h
@@ -0,0 +1,247 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004, 2008-2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 440MHz PA8200 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 10
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 14
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 11
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_2_PI2_THRESHOLD 21
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 31
+#define MUL_TOOM33_THRESHOLD 114
+#define MUL_TOOM44_THRESHOLD 179
+#define MUL_TOOM6H_THRESHOLD 222
+#define MUL_TOOM8H_THRESHOLD 296
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 130
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 229
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 129
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 54
+
+#define SQR_BASECASE_THRESHOLD 5
+#define SQR_TOOM2_THRESHOLD 58
+#define SQR_TOOM3_THRESHOLD 153
+#define SQR_TOOM4_THRESHOLD 278
+#define SQR_TOOM6_THRESHOLD 0 /* always */
+#define SQR_TOOM8_THRESHOLD 0 /* always */
+
+#define MULMID_TOOM42_THRESHOLD 56
+
+#define MULMOD_BNM1_THRESHOLD 15
+#define SQRMOD_BNM1_THRESHOLD 19
+
+#define POWM_SEC_TABLE 2,23,228,1084
+
+#define MUL_FFT_MODF_THRESHOLD 336 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 336, 5}, { 11, 4}, { 23, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 23, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 19, 7}, { 39, 8}, \
+ { 27, 9}, { 15, 8}, { 33, 9}, { 19, 8}, \
+ { 39, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 51,10}, \
+ { 31, 9}, { 67,10}, { 39, 9}, { 79,10}, \
+ { 47, 9}, { 95,10}, { 55,11}, { 31,10}, \
+ { 63, 9}, { 127,10}, { 71, 8}, { 287,10}, \
+ { 79,11}, { 47,10}, { 95, 9}, { 191, 8}, \
+ { 383, 7}, { 767,10}, { 103, 9}, { 207, 8}, \
+ { 415, 7}, { 831,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 543, 7}, { 1087, 6}, \
+ { 2175,10}, { 143, 9}, { 287, 8}, { 575,11}, \
+ { 79, 9}, { 319, 8}, { 639, 7}, { 1279, 9}, \
+ { 335, 8}, { 671,10}, { 175, 9}, { 351, 8}, \
+ { 703,11}, { 95,10}, { 191, 9}, { 383, 8}, \
+ { 767,10}, { 207, 9}, { 415, 8}, { 831, 7}, \
+ { 1663,11}, { 111,10}, { 223, 9}, { 447, 8}, \
+ { 895,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 543, 8}, { 1087, 7}, { 2175,10}, { 287, 9}, \
+ { 575, 8}, { 1215, 7}, { 2431,10}, { 319, 9}, \
+ { 639, 8}, { 1279,10}, { 335, 9}, { 671, 8}, \
+ { 1343, 9}, { 703, 8}, { 1407,12}, { 95,11}, \
+ { 191,10}, { 383,11}, { 207, 9}, { 831, 8}, \
+ { 1663,11}, { 223,10}, { 447, 9}, { 959,13}, \
+ { 63,12}, { 127,11}, { 255, 8}, { 2047,11}, \
+ { 271,10}, { 543, 9}, { 1087, 8}, { 2175,11}, \
+ { 287,10}, { 575, 9}, { 1215, 8}, { 2431,11}, \
+ { 319,10}, { 671, 9}, { 1343, 8}, { 2687,11}, \
+ { 351,10}, { 703, 9}, { 1471, 8}, { 2943,12}, \
+ { 191,11}, { 383, 8}, { 3071,11}, { 415,10}, \
+ { 831, 9}, { 1663,11}, { 479,10}, { 959, 9}, \
+ { 1919, 8}, { 3839,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087, 9}, { 2175,12}, { 287,11}, \
+ { 607,10}, { 1215, 9}, { 2431, 8}, { 4863,12}, \
+ { 319,11}, { 671,10}, { 1343,13}, { 191, 9}, \
+ { 3071,12}, { 415,11}, { 831,10}, { 1663, 8}, \
+ { 6655, 9}, { 3455,12}, { 447, 9}, { 3583,13}, \
+ { 255,12}, { 511,11}, { 1023,10}, { 2175,13}, \
+ { 319,11}, { 1279,12}, { 671,10}, { 2815,12}, \
+ { 735,10}, { 2943, 9}, { 5887,13}, { 383,12}, \
+ { 767,11}, { 1535,10}, { 3071,13}, { 447,10}, \
+ { 3583,12}, { 959,13}, { 511,12}, { 1087,13}, \
+ { 639,12}, { 1343,13}, { 767,11}, { 3071,13}, \
+ { 831,12}, { 1663,11}, { 3455,10}, { 6911,13}, \
+ { 895,14}, { 511,13}, { 1023,12}, { 2047,13}, \
+ { 1087,12}, { 2303,13}, { 1215,12}, { 2431,14}, \
+ { 639,13}, { 1279,12}, { 2559,13}, { 1343,12}, \
+ { 2687,11}, { 5375,13}, { 1407,12}, { 2815,11}, \
+ { 5631,12}, { 2943,13}, { 1535,12}, { 3199,13}, \
+ { 1663,12}, { 3327,13}, { 1727,14}, { 895,13}, \
+ { 1791,12}, { 3583,13}, { 1919,15}, { 511,14}, \
+ { 1023,13}, { 2047,12}, { 4095,14}, { 1151,13}, \
+ { 2431,14}, { 1279,13}, { 2687,14}, { 1407,13}, \
+ { 2815,12}, { 5631,15}, { 767,14}, { 1535,13}, \
+ { 3071,14}, { 1663,13}, { 3327,14}, { 1791,13}, \
+ { 3583,14}, { 1919,15}, { 1023,14}, { 2303,13}, \
+ { 4607,14}, { 2431,13}, { 4863,15}, { 32768,16}, \
+ { 65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+ {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 252
+#define MUL_FFT_THRESHOLD 2368
+
+#define SQR_FFT_MODF_THRESHOLD 284 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 284, 5}, { 9, 4}, { 21, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 25, 7}, { 25, 8}, \
+ { 13, 7}, { 27, 8}, { 15, 7}, { 31, 8}, \
+ { 27, 9}, { 15, 8}, { 33, 9}, { 19, 8}, \
+ { 39, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 51,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 63, 8}, { 255, 7}, { 511,10}, \
+ { 71, 8}, { 287, 7}, { 575,10}, { 79,11}, \
+ { 47,10}, { 95, 9}, { 191, 8}, { 383, 7}, \
+ { 767,10}, { 103, 9}, { 207, 8}, { 415,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 543, 7}, { 1087, 8}, { 575, 7}, { 1151,11}, \
+ { 79, 8}, { 639, 7}, { 1279, 9}, { 335, 8}, \
+ { 671, 7}, { 1343,10}, { 175, 8}, { 703, 7}, \
+ { 1407,11}, { 95,10}, { 191, 9}, { 383, 8}, \
+ { 767,10}, { 207, 9}, { 415, 8}, { 831, 7}, \
+ { 1663, 9}, { 447, 8}, { 895,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 543, 8}, { 1087, 7}, \
+ { 2175, 9}, { 575, 8}, { 1151,10}, { 303, 9}, \
+ { 607, 8}, { 1215, 7}, { 2431,10}, { 319, 9}, \
+ { 639, 8}, { 1279, 9}, { 671, 8}, { 1343, 7}, \
+ { 2687,10}, { 351, 9}, { 703, 8}, { 1407,12}, \
+ { 95,11}, { 191,10}, { 383, 9}, { 767,11}, \
+ { 207,10}, { 415, 9}, { 831, 8}, { 1663,11}, \
+ { 223,10}, { 447, 9}, { 895,13}, { 63,11}, \
+ { 255,10}, { 543, 8}, { 2175,11}, { 287,10}, \
+ { 575, 9}, { 1151,10}, { 607, 9}, { 1215, 8}, \
+ { 2431,11}, { 319, 9}, { 1279,10}, { 671, 9}, \
+ { 1343, 8}, { 2687,11}, { 351,10}, { 703, 9}, \
+ { 1407,10}, { 735,12}, { 191,11}, { 383,10}, \
+ { 831, 9}, { 1663,12}, { 223,11}, { 447,10}, \
+ { 895,11}, { 479, 9}, { 1919, 8}, { 3839,12}, \
+ { 255,11}, { 511,10}, { 1023,11}, { 543,10}, \
+ { 1087, 9}, { 2175,12}, { 287,11}, { 575,10}, \
+ { 1151,11}, { 607,10}, { 1215, 9}, { 2431, 8}, \
+ { 4863,10}, { 1279,11}, { 671,10}, { 1343, 9}, \
+ { 2687,12}, { 351,11}, { 703,10}, { 1407,11}, \
+ { 735,13}, { 191, 9}, { 3071, 7}, { 12287,11}, \
+ { 799,12}, { 415,11}, { 831,10}, { 1663,12}, \
+ { 447, 8}, { 7167,12}, { 479, 9}, { 3839,14}, \
+ { 127,13}, { 255,12}, { 511,11}, { 1023,12}, \
+ { 543,10}, { 2175, 9}, { 4607,11}, { 1215,10}, \
+ { 2431,11}, { 1279,10}, { 2559,13}, { 383,12}, \
+ { 767,11}, { 1535,12}, { 799,10}, { 3199, 9}, \
+ { 6399,12}, { 895,13}, { 511,12}, { 1023,11}, \
+ { 2047,12}, { 1087,13}, { 575,12}, { 1151,10}, \
+ { 4607,13}, { 639,12}, { 1279,11}, { 2687,14}, \
+ { 383,13}, { 767,11}, { 3071,12}, { 1599,13}, \
+ { 895,12}, { 1791,11}, { 3583,13}, { 959,15}, \
+ { 255,12}, { 2175,13}, { 1215,14}, { 639,13}, \
+ { 1279,12}, { 2559,13}, { 1343,12}, { 2687,13}, \
+ { 1471,11}, { 5887,14}, { 767,13}, { 1535,12}, \
+ { 3071,13}, { 1599,12}, { 3199,13}, { 1663,12}, \
+ { 3327,13}, { 1727,14}, { 895,13}, { 1791,12}, \
+ { 3583,15}, { 511,14}, { 1023,13}, { 2175,14}, \
+ { 1151,12}, { 4607,13}, { 2431,14}, { 1279,13}, \
+ { 2687,14}, { 1407,13}, { 2815,15}, { 767,13}, \
+ { 3199,14}, { 1663,13}, { 3327,14}, { 1791,13}, \
+ { 3583,14}, { 1919,15}, { 1023,14}, { 2047,13}, \
+ { 4095,14}, { 2303,13}, { 4607,14}, { 2431,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 257
+#define SQR_FFT_THRESHOLD 1856
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 113
+#define MULLO_MUL_N_THRESHOLD 4658
+
+#define DC_DIV_QR_THRESHOLD 123
+#define DC_DIVAPPR_Q_THRESHOLD 372
+#define DC_BDIV_QR_THRESHOLD 142
+#define DC_BDIV_Q_THRESHOLD 312
+
+#define INV_MULMOD_BNM1_THRESHOLD 58
+#define INV_NEWTON_THRESHOLD 315
+#define INV_APPR_THRESHOLD 315
+
+#define BINV_NEWTON_THRESHOLD 360
+#define REDC_1_TO_REDC_N_THRESHOLD 101
+
+#define MU_DIV_QR_THRESHOLD 979
+#define MU_DIVAPPR_Q_THRESHOLD 1142
+#define MUPI_DIV_QR_THRESHOLD 93
+#define MU_BDIV_QR_THRESHOLD 889
+#define MU_BDIV_Q_THRESHOLD 1187
+
+#define MATRIX22_STRASSEN_THRESHOLD 9
+#define HGCD_THRESHOLD 234
+#define HGCD_APPR_THRESHOLD 300
+#define HGCD_REDUCE_THRESHOLD 1553
+#define GCD_DC_THRESHOLD 684
+#define GCDEXT_DC_THRESHOLD 525
+#define JACOBI_BASE_METHOD 2
+
+#define GET_STR_DC_THRESHOLD 21
+#define GET_STR_PRECOMPUTE_THRESHOLD 24
+#define SET_STR_DC_THRESHOLD 1951
+#define SET_STR_PRECOMPUTE_THRESHOLD 4034
diff --git a/gmp/mpn/pa64/lshift.asm b/gmp/mpn/pa64/lshift.asm
new file mode 100644
index 0000000000..c0fc2921c1
--- /dev/null
+++ b/gmp/mpn/pa64/lshift.asm
@@ -0,0 +1,114 @@
+dnl HP-PA 2.0 mpn_lshift -- Left shift.
+
+dnl Copyright 1997, 2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl This runs at 1.5 cycles/limb on PA8000 and 1.0 cycles/limb on PA8500.
+
+include(`../config.m4')
+
+dnl INPUT PARAMETERS
+define(`rp',`%r26')
+define(`up',`%r25')
+define(`n',`%r24')
+define(`cnt',`%r23')
+
+ifdef(`HAVE_ABI_2_0w',
+` .level 2.0w
+',` .level 2.0
+')
+PROLOGUE(mpn_lshift)
+ shladd n, 3, up, up
+ shladd n, 3, rp, rp
+ subi 64, cnt, cnt
+ mtsar cnt
+ ldd -8(up), %r21
+ addib,= -1, n, L(end)
+ shrpd %r0, %r21, %sar, %r29 C compute carry out limb
+ depw,z n, 31, 3, %r28 C r28 = (size & 7)
+ sub %r0, n, %r22
+ depw,z %r22, 28, 3, %r22 C r22 = 8 * (-size & 7)
+ add up, %r22, up C offset up
+ blr %r28, %r0 C branch into jump table
+ add rp, %r22, rp C offset rp
+ b L(0)
+ nop
+ b L(1)
+ copy %r21, %r20
+ b L(2)
+ nop
+ b L(3)
+ copy %r21, %r20
+ b L(4)
+ nop
+ b L(5)
+ copy %r21, %r20
+ b L(6)
+ nop
+ b L(7)
+ copy %r21, %r20
+
+LDEF(loop)
+LDEF(0) ldd -16(up), %r20
+ shrpd %r21, %r20, %sar, %r21
+ std %r21, -8(rp)
+LDEF(7) ldd -24(up), %r21
+ shrpd %r20, %r21, %sar, %r20
+ std %r20, -16(rp)
+LDEF(6) ldd -32(up), %r20
+ shrpd %r21, %r20, %sar, %r21
+ std %r21, -24(rp)
+LDEF(5) ldd -40(up), %r21
+ shrpd %r20, %r21, %sar, %r20
+ std %r20, -32(rp)
+LDEF(4) ldd -48(up), %r20
+ shrpd %r21, %r20, %sar, %r21
+ std %r21, -40(rp)
+LDEF(3) ldd -56(up), %r21
+ shrpd %r20, %r21, %sar, %r20
+ std %r20, -48(rp)
+LDEF(2) ldd -64(up), %r20
+ shrpd %r21, %r20, %sar, %r21
+ std %r21, -56(rp)
+LDEF(1) ldd -72(up), %r21
+ ldo -64(up), up
+ shrpd %r20, %r21, %sar, %r20
+ std %r20, -64(rp)
+ addib,> -8, n, L(loop)
+ ldo -64(rp), rp
+
+LDEF(end)
+ shrpd %r21, %r0, %sar, %r21
+ std %r21, -8(rp)
+ bve (%r2)
+ifdef(`HAVE_ABI_2_0w',
+` copy %r29,%r28
+',` extrd,u %r29, 31, 32, %r28
+')
+EPILOGUE(mpn_lshift)
diff --git a/gmp/mpn/pa64/mul_1.asm b/gmp/mpn/pa64/mul_1.asm
new file mode 100644
index 0000000000..6935c23ccd
--- /dev/null
+++ b/gmp/mpn/pa64/mul_1.asm
@@ -0,0 +1,646 @@
+dnl HP-PA 2.0 64-bit mpn_mul_1 -- Multiply a limb vector with a limb and store
+dnl the result in a second limb vector.
+
+dnl Copyright 1998-2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 8000,8200: 6.5
+C 8500,8600,8700: 5.625
+
+C The feed-in and wind-down code has not yet been scheduled. Many cycles
+C could be saved there per call.
+
+C DESCRIPTION:
+C The main loop "BIG" is 4-way unrolled, mainly to allow
+C effective use of ADD,DC. Delays in moving data via the cache from the FP
+C registers to the IU registers, have demanded a deep software pipeline, and
+C a lot of stack slots for partial products in flight.
+C
+C CODE STRUCTURE:
+C save-some-registers
+C do 0, 1, 2, or 3 limbs
+C if done, restore-some-regs and return
+C save-many-regs
+C do 4, 8, ... limb
+C restore-all-regs
+
+C STACK LAYOUT:
+C HP-PA stack grows upwards. We could allocate 8 fewer slots by using the
+C slots marked FREE, as well as some slots in the caller's "frame marker".
+C
+C -00 <- r30
+C -08 FREE
+C -10 tmp
+C -18 tmp
+C -20 tmp
+C -28 tmp
+C -30 tmp
+C -38 tmp
+C -40 tmp
+C -48 tmp
+C -50 tmp
+C -58 tmp
+C -60 tmp
+C -68 tmp
+C -70 tmp
+C -78 tmp
+C -80 tmp
+C -88 tmp
+C -90 FREE
+C -98 FREE
+C -a0 FREE
+C -a8 FREE
+C -b0 r13
+C -b8 r12
+C -c0 r11
+C -c8 r10
+C -d0 r8
+C -d8 r8
+C -e0 r7
+C -e8 r6
+C -f0 r5
+C -f8 r4
+C -100 r3
+C Previous frame:
+C [unused area]
+C -38/-138 vlimb home slot. For 2.0N, the vlimb arg will arrive here.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS:
+define(`rp',`%r26') C
+define(`up',`%r25') C
+define(`n',`%r24') C
+define(`vlimb',`%r23') C
+
+define(`climb',`%r23') C
+
+ifdef(`HAVE_ABI_2_0w',
+` .level 2.0w
+',` .level 2.0
+')
+PROLOGUE(mpn_mul_1)
+
+ifdef(`HAVE_ABI_2_0w',
+` std vlimb, -0x38(%r30) C store vlimb into "home" slot
+')
+ std,ma %r3, 0x100(%r30)
+ std %r4, -0xf8(%r30)
+ std %r5, -0xf0(%r30)
+ ldo 0(%r0), climb C clear climb
+ fldd -0x138(%r30), %fr8 C put vlimb in fp register
+
+define(`p032a1',`%r1') C
+define(`p032a2',`%r19') C
+
+define(`m032',`%r20') C
+define(`m096',`%r21') C
+
+define(`p000a',`%r22') C
+define(`p064a',`%r29') C
+
+define(`s000',`%r31') C
+
+define(`ma000',`%r4') C
+define(`ma064',`%r20') C
+
+C define(`r000',`%r3') C FIXME don't save r3 for n < 4.
+
+ extrd,u n, 63, 2, %r5
+ cmpb,= %r5, %r0, L(BIG)
+ nop
+
+ fldd 0(up), %fr4
+ ldo 8(up), up
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr4R, %fr24
+ xmpyu %fr8L, %fr4L, %fr25
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+ addib,<> -1, %r5, L(two_or_more)
+ fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+LDEF(one)
+ ldd -0x78(%r30), p032a1
+ ldd -0x70(%r30), p032a2
+ ldd -0x80(%r30), p000a
+ b L(0_one_out)
+ ldd -0x68(%r30), p064a
+
+LDEF(two_or_more)
+ fldd 0(up), %fr4
+ ldo 8(up), up
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ ldd -0x78(%r30), p032a1
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr4R, %fr24
+ xmpyu %fr8L, %fr4L, %fr25
+ ldd -0x70(%r30), p032a2
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ ldd -0x80(%r30), p000a
+ fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+ ldd -0x68(%r30), p064a
+ addib,<> -1, %r5, L(three_or_more)
+ fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+LDEF(two)
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ b L(0_two_out)
+ depd m096, 31, 32, ma064
+
+LDEF(three_or_more)
+ fldd 0(up), %fr4
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+C addib,= -1, %r5, L(0_out)
+ depd m096, 31, 32, ma064
+LDEF(loop0)
+C xmpyu %fr8R, %fr4L, %fr22
+C xmpyu %fr8L, %fr4R, %fr23
+C ldd -0x78(%r30), p032a1
+C fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+C
+C xmpyu %fr8R, %fr4R, %fr24
+C xmpyu %fr8L, %fr4L, %fr25
+C ldd -0x70(%r30), p032a2
+C fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+C
+C ldo 8(rp), rp
+C add climb, p000a, s000
+C ldd -0x80(%r30), p000a
+C fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+C
+C add,dc p064a, %r0, climb
+C ldo 8(up), up
+C ldd -0x68(%r30), p064a
+C fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+C
+C add ma000, s000, s000
+C add,dc ma064, climb, climb
+C fldd 0(up), %fr4
+C
+C std s000, -8(rp)
+C
+C add p032a1, p032a2, m032
+C add,dc %r0, %r0, m096
+C
+C depd,z m032, 31, 32, ma000
+C extrd,u m032, 31, 32, ma064
+C addib,<> -1, %r5, L(loop0)
+C depd m096, 31, 32, ma064
+LDEF(0_out)
+ ldo 8(up), up
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ ldd -0x78(%r30), p032a1
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr4R, %fr24
+ xmpyu %fr8L, %fr4L, %fr25
+ ldd -0x70(%r30), p032a2
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ ldo 8(rp), rp
+ add climb, p000a, s000
+ ldd -0x80(%r30), p000a
+ fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+ add,dc p064a, %r0, climb
+ ldd -0x68(%r30), p064a
+ fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+ add ma000, s000, s000
+ add,dc ma064, climb, climb
+ std s000, -8(rp)
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ depd m096, 31, 32, ma064
+LDEF(0_two_out)
+ ldd -0x78(%r30), p032a1
+ ldd -0x70(%r30), p032a2
+ ldo 8(rp), rp
+ add climb, p000a, s000
+ ldd -0x80(%r30), p000a
+ add,dc p064a, %r0, climb
+ ldd -0x68(%r30), p064a
+ add ma000, s000, s000
+ add,dc ma064, climb, climb
+ std s000, -8(rp)
+LDEF(0_one_out)
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ depd m096, 31, 32, ma064
+
+ add climb, p000a, s000
+ add,dc p064a, %r0, climb
+ add ma000, s000, s000
+ add,dc ma064, climb, climb
+ std s000, 0(rp)
+
+ cmpib,>= 4, n, L(done)
+ ldo 8(rp), rp
+
+C 4-way unrolled code.
+
+LDEF(BIG)
+
+define(`p032a1',`%r1') C
+define(`p032a2',`%r19') C
+define(`p096b1',`%r20') C
+define(`p096b2',`%r21') C
+define(`p160c1',`%r22') C
+define(`p160c2',`%r29') C
+define(`p224d1',`%r31') C
+define(`p224d2',`%r3') C
+ C
+define(`m032',`%r4') C
+define(`m096',`%r5') C
+define(`m160',`%r6') C
+define(`m224',`%r7') C
+define(`m288',`%r8') C
+ C
+define(`p000a',`%r1') C
+define(`p064a',`%r19') C
+define(`p064b',`%r20') C
+define(`p128b',`%r21') C
+define(`p128c',`%r22') C
+define(`p192c',`%r29') C
+define(`p192d',`%r31') C
+define(`p256d',`%r3') C
+ C
+define(`s000',`%r10') C
+define(`s064',`%r11') C
+define(`s128',`%r12') C
+define(`s192',`%r13') C
+ C
+define(`ma000',`%r9') C
+define(`ma064',`%r4') C
+define(`ma128',`%r5') C
+define(`ma192',`%r6') C
+define(`ma256',`%r7') C
+
+ std %r6, -0xe8(%r30)
+ std %r7, -0xe0(%r30)
+ std %r8, -0xd8(%r30)
+ std %r9, -0xd0(%r30)
+ std %r10, -0xc8(%r30)
+ std %r11, -0xc0(%r30)
+ std %r12, -0xb8(%r30)
+ std %r13, -0xb0(%r30)
+
+ifdef(`HAVE_ABI_2_0w',
+` extrd,u n, 61, 62, n C right shift 2
+',` extrd,u n, 61, 30, n C right shift 2, zero extend
+')
+
+LDEF(4_or_more)
+ fldd 0(up), %fr4
+ fldd 8(up), %fr5
+ fldd 16(up), %fr6
+ fldd 24(up), %fr7
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ xmpyu %fr8R, %fr5L, %fr24
+ xmpyu %fr8L, %fr5R, %fr25
+ xmpyu %fr8R, %fr6L, %fr26
+ xmpyu %fr8L, %fr6R, %fr27
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr7L, %fr28
+ xmpyu %fr8L, %fr7R, %fr29
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ xmpyu %fr8R, %fr4R, %fr30
+ xmpyu %fr8L, %fr4L, %fr31
+ fstd %fr24, -0x38(%r30) C mid product to -0x38..-0x31
+ xmpyu %fr8R, %fr5R, %fr22
+ xmpyu %fr8L, %fr5L, %fr23
+ fstd %fr25, -0x30(%r30) C mid product to -0x30..-0x29
+ xmpyu %fr8R, %fr6R, %fr24
+ xmpyu %fr8L, %fr6L, %fr25
+ fstd %fr26, -0x58(%r30) C mid product to -0x58..-0x51
+ xmpyu %fr8R, %fr7R, %fr26
+ fstd %fr27, -0x50(%r30) C mid product to -0x50..-0x49
+ addib,<> -1, n, L(8_or_more)
+ xmpyu %fr8L, %fr7L, %fr27
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+ ldd -0x78(%r30), p032a1
+ ldd -0x70(%r30), p032a2
+ ldd -0x38(%r30), p096b1
+ ldd -0x30(%r30), p096b2
+ ldd -0x58(%r30), p160c1
+ ldd -0x50(%r30), p160c2
+ ldd -0x18(%r30), p224d1
+ ldd -0x10(%r30), p224d2
+ b L(end1)
+ nop
+
+LDEF(8_or_more)
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+ ldo 32(up), up
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+ fldd 0(up), %fr4
+ fldd 8(up), %fr5
+ fldd 16(up), %fr6
+ fldd 24(up), %fr7
+ xmpyu %fr8R, %fr4L, %fr22
+ ldd -0x78(%r30), p032a1
+ xmpyu %fr8L, %fr4R, %fr23
+ xmpyu %fr8R, %fr5L, %fr24
+ ldd -0x70(%r30), p032a2
+ xmpyu %fr8L, %fr5R, %fr25
+ xmpyu %fr8R, %fr6L, %fr26
+ ldd -0x38(%r30), p096b1
+ xmpyu %fr8L, %fr6R, %fr27
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr7L, %fr28
+ ldd -0x30(%r30), p096b2
+ xmpyu %fr8L, %fr7R, %fr29
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ xmpyu %fr8R, %fr4R, %fr30
+ ldd -0x58(%r30), p160c1
+ xmpyu %fr8L, %fr4L, %fr31
+ fstd %fr24, -0x38(%r30) C mid product to -0x38..-0x31
+ xmpyu %fr8R, %fr5R, %fr22
+ ldd -0x50(%r30), p160c2
+ xmpyu %fr8L, %fr5L, %fr23
+ fstd %fr25, -0x30(%r30) C mid product to -0x30..-0x29
+ xmpyu %fr8R, %fr6R, %fr24
+ ldd -0x18(%r30), p224d1
+ xmpyu %fr8L, %fr6L, %fr25
+ fstd %fr26, -0x58(%r30) C mid product to -0x58..-0x51
+ xmpyu %fr8R, %fr7R, %fr26
+ ldd -0x10(%r30), p224d2
+ fstd %fr27, -0x50(%r30) C mid product to -0x50..-0x49
+ addib,= -1, n, L(end2)
+ xmpyu %fr8L, %fr7L, %fr27
+LDEF(loop)
+ add p032a1, p032a2, m032
+ ldd -0x80(%r30), p000a
+ add,dc p096b1, p096b2, m096
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+
+ add,dc p160c1, p160c2, m160
+ ldd -0x68(%r30), p064a
+ add,dc p224d1, p224d2, m224
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+
+ add,dc %r0, %r0, m288
+ ldd -0x40(%r30), p064b
+ ldo 32(up), up
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+
+ depd,z m032, 31, 32, ma000
+ ldd -0x28(%r30), p128b
+ extrd,u m032, 31, 32, ma064
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+
+ depd m096, 31, 32, ma064
+ ldd -0x60(%r30), p128c
+ extrd,u m096, 31, 32, ma128
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+
+ depd m160, 31, 32, ma128
+ ldd -0x48(%r30), p192c
+ extrd,u m160, 31, 32, ma192
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+
+ depd m224, 31, 32, ma192
+ ldd -0x20(%r30), p192d
+ extrd,u m224, 31, 32, ma256
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+
+ depd m288, 31, 32, ma256
+ ldd -0x88(%r30), p256d
+ add climb, p000a, s000
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+
+ add,dc p064a, p064b, s064
+ add,dc p128b, p128c, s128
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+
+ add,dc p192c, p192d, s192
+ add,dc p256d, %r0, climb
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+
+ add ma000, s000, s000 C accum mid 0
+ fldd 0(up), %fr4
+ add,dc ma064, s064, s064 C accum mid 1
+ std s000, 0(rp)
+
+ add,dc ma128, s128, s128 C accum mid 2
+ fldd 8(up), %fr5
+ add,dc ma192, s192, s192 C accum mid 3
+ std s064, 8(rp)
+
+ add,dc ma256, climb, climb
+ fldd 16(up), %fr6
+ std s128, 16(rp)
+
+ xmpyu %fr8R, %fr4L, %fr22
+ ldd -0x78(%r30), p032a1
+ xmpyu %fr8L, %fr4R, %fr23
+ fldd 24(up), %fr7
+
+ xmpyu %fr8R, %fr5L, %fr24
+ ldd -0x70(%r30), p032a2
+ xmpyu %fr8L, %fr5R, %fr25
+ std s192, 24(rp)
+
+ xmpyu %fr8R, %fr6L, %fr26
+ ldd -0x38(%r30), p096b1
+ xmpyu %fr8L, %fr6R, %fr27
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+
+ xmpyu %fr8R, %fr7L, %fr28
+ ldd -0x30(%r30), p096b2
+ xmpyu %fr8L, %fr7R, %fr29
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+
+ xmpyu %fr8R, %fr4R, %fr30
+ ldd -0x58(%r30), p160c1
+ xmpyu %fr8L, %fr4L, %fr31
+ fstd %fr24, -0x38(%r30) C mid product to -0x38..-0x31
+
+ xmpyu %fr8R, %fr5R, %fr22
+ ldd -0x50(%r30), p160c2
+ xmpyu %fr8L, %fr5L, %fr23
+ fstd %fr25, -0x30(%r30) C mid product to -0x30..-0x29
+
+ xmpyu %fr8R, %fr6R, %fr24
+ ldd -0x18(%r30), p224d1
+ xmpyu %fr8L, %fr6L, %fr25
+ fstd %fr26, -0x58(%r30) C mid product to -0x58..-0x51
+
+ xmpyu %fr8R, %fr7R, %fr26
+ ldd -0x10(%r30), p224d2
+ fstd %fr27, -0x50(%r30) C mid product to -0x50..-0x49
+ xmpyu %fr8L, %fr7L, %fr27
+
+ addib,<> -1, n, L(loop)
+ ldo 32(rp), rp
+
+LDEF(end2)
+ add p032a1, p032a2, m032
+ ldd -0x80(%r30), p000a
+ add,dc p096b1, p096b2, m096
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+ add,dc p160c1, p160c2, m160
+ ldd -0x68(%r30), p064a
+ add,dc p224d1, p224d2, m224
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+ add,dc %r0, %r0, m288
+ ldd -0x40(%r30), p064b
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+ depd,z m032, 31, 32, ma000
+ ldd -0x28(%r30), p128b
+ extrd,u m032, 31, 32, ma064
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+ depd m096, 31, 32, ma064
+ ldd -0x60(%r30), p128c
+ extrd,u m096, 31, 32, ma128
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+ depd m160, 31, 32, ma128
+ ldd -0x48(%r30), p192c
+ extrd,u m160, 31, 32, ma192
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+ depd m224, 31, 32, ma192
+ ldd -0x20(%r30), p192d
+ extrd,u m224, 31, 32, ma256
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+ depd m288, 31, 32, ma256
+ ldd -0x88(%r30), p256d
+ add climb, p000a, s000
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+ add,dc p064a, p064b, s064
+ add,dc p128b, p128c, s128
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+ add,dc p192c, p192d, s192
+ add,dc p256d, %r0, climb
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+ add ma000, s000, s000 C accum mid 0
+ add,dc ma064, s064, s064 C accum mid 1
+ add,dc ma128, s128, s128 C accum mid 2
+ add,dc ma192, s192, s192 C accum mid 3
+ add,dc ma256, climb, climb
+ std s000, 0(rp)
+ std s064, 8(rp)
+ ldd -0x78(%r30), p032a1
+ std s128, 16(rp)
+ ldd -0x70(%r30), p032a2
+ std s192, 24(rp)
+ ldd -0x38(%r30), p096b1
+ ldd -0x30(%r30), p096b2
+ ldd -0x58(%r30), p160c1
+ ldd -0x50(%r30), p160c2
+ ldd -0x18(%r30), p224d1
+ ldd -0x10(%r30), p224d2
+ ldo 32(rp), rp
+
+LDEF(end1)
+ add p032a1, p032a2, m032
+ ldd -0x80(%r30), p000a
+ add,dc p096b1, p096b2, m096
+ add,dc p160c1, p160c2, m160
+ ldd -0x68(%r30), p064a
+ add,dc p224d1, p224d2, m224
+ add,dc %r0, %r0, m288
+ ldd -0x40(%r30), p064b
+ depd,z m032, 31, 32, ma000
+ ldd -0x28(%r30), p128b
+ extrd,u m032, 31, 32, ma064
+ depd m096, 31, 32, ma064
+ ldd -0x60(%r30), p128c
+ extrd,u m096, 31, 32, ma128
+ depd m160, 31, 32, ma128
+ ldd -0x48(%r30), p192c
+ extrd,u m160, 31, 32, ma192
+ depd m224, 31, 32, ma192
+ ldd -0x20(%r30), p192d
+ extrd,u m224, 31, 32, ma256
+ depd m288, 31, 32, ma256
+ ldd -0x88(%r30), p256d
+ add climb, p000a, s000
+ add,dc p064a, p064b, s064
+ add,dc p128b, p128c, s128
+ add,dc p192c, p192d, s192
+ add,dc p256d, %r0, climb
+ add ma000, s000, s000 C accum mid 0
+ add,dc ma064, s064, s064 C accum mid 1
+ add,dc ma128, s128, s128 C accum mid 2
+ add,dc ma192, s192, s192 C accum mid 3
+ add,dc ma256, climb, climb
+ std s000, 0(rp)
+ std s064, 8(rp)
+ std s128, 16(rp)
+ std s192, 24(rp)
+
+ ldd -0xb0(%r30), %r13
+ ldd -0xb8(%r30), %r12
+ ldd -0xc0(%r30), %r11
+ ldd -0xc8(%r30), %r10
+ ldd -0xd0(%r30), %r9
+ ldd -0xd8(%r30), %r8
+ ldd -0xe0(%r30), %r7
+ ldd -0xe8(%r30), %r6
+LDEF(done)
+ifdef(`HAVE_ABI_2_0w',
+` copy climb, %r28
+',` extrd,u climb, 63, 32, %r29
+ extrd,u climb, 31, 32, %r28
+')
+ ldd -0xf0(%r30), %r5
+ ldd -0xf8(%r30), %r4
+ bve (%r2)
+ ldd,mb -0x100(%r30), %r3
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/pa64/rshift.asm b/gmp/mpn/pa64/rshift.asm
new file mode 100644
index 0000000000..cfc242ea9c
--- /dev/null
+++ b/gmp/mpn/pa64/rshift.asm
@@ -0,0 +1,111 @@
+dnl HP-PA 2.0 mpn_rshift -- Right shift.
+
+dnl Copyright 1997, 2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl This runs at 1.5 cycles/limb on PA8000 and 1.0 cycles/limb on PA8500.
+
+include(`../config.m4')
+
+dnl INPUT PARAMETERS
+define(`rp',`%r26')
+define(`up',`%r25')
+define(`n',`%r24')
+define(`cnt',`%r23')
+
+ifdef(`HAVE_ABI_2_0w',
+` .level 2.0w
+',` .level 2.0
+')
+PROLOGUE(mpn_rshift)
+ mtsar cnt
+ ldd 0(up), %r21
+ addib,= -1, n, L(end)
+ shrpd %r21, %r0, %sar, %r29 C compute carry out limb
+ depw,z n, 31, 3, %r28 C r28 = (size & 7)
+ sub %r0, n, %r22
+ depw,z %r22, 28, 3, %r22 C r22 = 8 * (-size & 7)
+ sub up, %r22, up C offset up
+ blr %r28, %r0 C branch into jump table
+ sub rp, %r22, rp C offset rp
+ b L(0)
+ nop
+ b L(1)
+ copy %r21, %r20
+ b L(2)
+ nop
+ b L(3)
+ copy %r21, %r20
+ b L(4)
+ nop
+ b L(5)
+ copy %r21, %r20
+ b L(6)
+ nop
+ b L(7)
+ copy %r21, %r20
+
+LDEF(loop)
+LDEF(0) ldd 8(up), %r20
+ shrpd %r20, %r21, %sar, %r21
+ std %r21, 0(rp)
+LDEF(7) ldd 16(up), %r21
+ shrpd %r21, %r20, %sar, %r20
+ std %r20, 8(rp)
+LDEF(6) ldd 24(up), %r20
+ shrpd %r20, %r21, %sar, %r21
+ std %r21, 16(rp)
+LDEF(5) ldd 32(up), %r21
+ shrpd %r21, %r20, %sar, %r20
+ std %r20, 24(rp)
+LDEF(4) ldd 40(up), %r20
+ shrpd %r20, %r21, %sar, %r21
+ std %r21, 32(rp)
+LDEF(3) ldd 48(up), %r21
+ shrpd %r21, %r20, %sar, %r20
+ std %r20, 40(rp)
+LDEF(2) ldd 56(up), %r20
+ shrpd %r20, %r21, %sar, %r21
+ std %r21, 48(rp)
+LDEF(1) ldd 64(up), %r21
+ ldo 64(up), up
+ shrpd %r21, %r20, %sar, %r20
+ std %r20, 56(rp)
+ addib,> -8, n, L(loop)
+ ldo 64(rp), rp
+
+LDEF(end)
+ shrpd %r0, %r21, %sar, %r21
+ std %r21, 0(rp)
+ bve (%r2)
+ifdef(`HAVE_ABI_2_0w',
+` copy %r29,%r28
+',` extrd,u %r29, 31, 32, %r28
+')
+EPILOGUE(mpn_rshift)
diff --git a/gmp/mpn/pa64/sqr_diagonal.asm b/gmp/mpn/pa64/sqr_diagonal.asm
new file mode 100644
index 0000000000..f6fadc93c6
--- /dev/null
+++ b/gmp/mpn/pa64/sqr_diagonal.asm
@@ -0,0 +1,191 @@
+dnl HP-PA 2.0 64-bit mpn_sqr_diagonal.
+
+dnl Copyright 2001-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl This code runs at 7.25 cycles/limb on PA8000 and 7.75 cycles/limb on
+dnl PA8500. The cache would saturate at 5 cycles/limb, so there is some room
+dnl for optimization.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(`rp',`%r26')
+define(`up',`%r25')
+define(`n',`%r24')
+
+define(`p00',`%r28')
+define(`p32',`%r29')
+define(`p64',`%r31')
+define(`t0',`%r19')
+define(`t1',`%r20')
+
+ifdef(`HAVE_ABI_2_0w',
+` .level 2.0w
+',` .level 2.0
+')
+PROLOGUE(mpn_sqr_diagonal)
+ ldo 128(%r30),%r30
+
+ fldds,ma 8(up),%fr8
+ addib,= -1,n,L(end1)
+ nop
+ fldds,ma 8(up),%fr4
+ xmpyu %fr8l,%fr8r,%fr10
+ fstd %fr10,-120(%r30)
+ xmpyu %fr8r,%fr8r,%fr9
+ fstd %fr9,0(rp)
+ xmpyu %fr8l,%fr8l,%fr11
+ fstd %fr11,8(rp)
+ addib,= -1,n,L(end2)
+ ldo 16(rp),rp
+
+LDEF(loop)
+ fldds,ma 8(up),%fr8 C load next up limb
+ xmpyu %fr4l,%fr4r,%fr6
+ fstd %fr6,-128(%r30)
+ xmpyu %fr4r,%fr4r,%fr5 C multiply in fp regs
+ fstd %fr5,0(rp)
+ xmpyu %fr4l,%fr4l,%fr7
+ fstd %fr7,8(rp)
+ ldd -120(%r30),p32
+ ldd -16(rp),p00 C accumulate in int regs
+ ldd -8(rp),p64
+ depd,z p32,30,31,t0
+ add t0,p00,p00
+ std p00,-16(rp)
+ extrd,u p32,32,33,t1
+ add,dc t1,p64,p64
+ std p64,-8(rp)
+ addib,= -1,n,L(exit)
+ ldo 16(rp),rp
+
+ fldds,ma 8(up),%fr4
+ xmpyu %fr8l,%fr8r,%fr10
+ fstd %fr10,-120(%r30)
+ xmpyu %fr8r,%fr8r,%fr9
+ fstd %fr9,0(rp)
+ xmpyu %fr8l,%fr8l,%fr11
+ fstd %fr11,8(rp)
+ ldd -128(%r30),p32
+ ldd -16(rp),p00
+ ldd -8(rp),p64
+ depd,z p32,30,31,t0
+ add t0,p00,p00
+ std p00,-16(rp)
+ extrd,u p32,32,33,t1
+ add,dc t1,p64,p64
+ std p64,-8(rp)
+ addib,<> -1,n,L(loop)
+ ldo 16(rp),rp
+
+LDEF(end2)
+ xmpyu %fr4l,%fr4r,%fr6
+ fstd %fr6,-128(%r30)
+ xmpyu %fr4r,%fr4r,%fr5
+ fstd %fr5,0(rp)
+ xmpyu %fr4l,%fr4l,%fr7
+ fstd %fr7,8(rp)
+ ldd -120(%r30),p32
+ ldd -16(rp),p00
+ ldd -8(rp),p64
+ depd,z p32,30,31,t0
+ add t0,p00,p00
+ std p00,-16(rp)
+ extrd,u p32,32,33,t1
+ add,dc t1,p64,p64
+ std p64,-8(rp)
+ ldo 16(rp),rp
+ ldd -128(%r30),p32
+ ldd -16(rp),p00
+ ldd -8(rp),p64
+ depd,z p32,30,31,t0
+ add t0,p00,p00
+ std p00,-16(rp)
+ extrd,u p32,32,33,t1
+ add,dc t1,p64,p64
+ std p64,-8(rp)
+ bve (%r2)
+ ldo -128(%r30),%r30
+
+LDEF(exit)
+ xmpyu %fr8l,%fr8r,%fr10
+ fstd %fr10,-120(%r30)
+ xmpyu %fr8r,%fr8r,%fr9
+ fstd %fr9,0(rp)
+ xmpyu %fr8l,%fr8l,%fr11
+ fstd %fr11,8(rp)
+ ldd -128(%r30),p32
+ ldd -16(rp),p00
+ ldd -8(rp),p64
+ depd,z p32,31,32,t0
+ add t0,p00,p00
+ extrd,u p32,31,32,t1
+ add,dc t1,p64,p64
+ add t0,p00,p00
+ add,dc t1,p64,p64
+ std p00,-16(rp)
+ std p64,-8(rp)
+ ldo 16(rp),rp
+ ldd -120(%r30),p32
+ ldd -16(rp),p00
+ ldd -8(rp),p64
+ depd,z p32,31,32,t0
+ add t0,p00,p00
+ extrd,u p32,31,32,t1
+ add,dc t1,p64,p64
+ add t0,p00,p00
+ add,dc t1,p64,p64
+ std p00,-16(rp)
+ std p64,-8(rp)
+ bve (%r2)
+ ldo -128(%r30),%r30
+
+LDEF(end1)
+ xmpyu %fr8l,%fr8r,%fr10
+ fstd %fr10,-128(%r30)
+ xmpyu %fr8r,%fr8r,%fr9
+ fstd %fr9,0(rp)
+ xmpyu %fr8l,%fr8l,%fr11
+ fstd %fr11,8(rp)
+ ldo 16(rp),rp
+ ldd -128(%r30),p32
+ ldd -16(rp),p00
+ ldd -8(rp),p64
+ depd,z p32,31,32,t0
+ add t0,p00,p00
+ extrd,u p32,31,32,t1
+ add,dc t1,p64,p64
+ add t0,p00,p00
+ add,dc t1,p64,p64
+ std p00,-16(rp)
+ std p64,-8(rp)
+ bve (%r2)
+ ldo -128(%r30),%r30
+EPILOGUE(mpn_sqr_diagonal)
diff --git a/gmp/mpn/pa64/submul_1.asm b/gmp/mpn/pa64/submul_1.asm
new file mode 100644
index 0000000000..f8a1968e45
--- /dev/null
+++ b/gmp/mpn/pa64/submul_1.asm
@@ -0,0 +1,700 @@
+dnl HP-PA 2.0 64-bit mpn_submul_1 -- Multiply a limb vector with a limb and
+dnl subtract the result from a second limb vector.
+
+dnl Copyright 1998-2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 8000,8200: 7
+C 8500,8600,8700: 6.5
+
+C The feed-in and wind-down code has not yet been scheduled. Many cycles
+C could be saved there per call.
+
+C DESCRIPTION:
+C The main loop "BIG" is 4-way unrolled, mainly to allow
+C effective use of ADD,DC. Delays in moving data via the cache from the FP
+C registers to the IU registers, have demanded a deep software pipeline, and
+C a lot of stack slots for partial products in flight.
+C
+C CODE STRUCTURE:
+C save-some-registers
+C do 0, 1, 2, or 3 limbs
+C if done, restore-some-regs and return
+C save-many-regs
+C do 4, 8, ... limb
+C restore-all-regs
+
+C STACK LAYOUT:
+C HP-PA stack grows upwards. We could allocate 8 fewer slots by using the
+C slots marked FREE, as well as some slots in the caller's "frame marker".
+C
+C -00 <- r30
+C -08 FREE
+C -10 tmp
+C -18 tmp
+C -20 tmp
+C -28 tmp
+C -30 tmp
+C -38 tmp
+C -40 tmp
+C -48 tmp
+C -50 tmp
+C -58 tmp
+C -60 tmp
+C -68 tmp
+C -70 tmp
+C -78 tmp
+C -80 tmp
+C -88 tmp
+C -90 FREE
+C -98 FREE
+C -a0 FREE
+C -a8 FREE
+C -b0 r13
+C -b8 r12
+C -c0 r11
+C -c8 r10
+C -d0 r8
+C -d8 r8
+C -e0 r7
+C -e8 r6
+C -f0 r5
+C -f8 r4
+C -100 r3
+C Previous frame:
+C [unused area]
+C -38/-138 vlimb home slot. For 2.0N, the vlimb arg will arrive here.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS:
+define(`rp',`%r26') C
+define(`up',`%r25') C
+define(`n',`%r24') C
+define(`vlimb',`%r23') C
+
+define(`climb',`%r23') C
+
+ifdef(`HAVE_ABI_2_0w',
+` .level 2.0w
+',` .level 2.0
+')
+PROLOGUE(mpn_submul_1)
+
+ifdef(`HAVE_ABI_2_0w',
+` std vlimb, -0x38(%r30) C store vlimb into "home" slot
+')
+ std,ma %r3, 0x100(%r30)
+ std %r4, -0xf8(%r30)
+ std %r5, -0xf0(%r30)
+ ldo 0(%r0), climb C clear climb
+ fldd -0x138(%r30), %fr8 C put vlimb in fp register
+
+define(`p032a1',`%r1') C
+define(`p032a2',`%r19') C
+
+define(`m032',`%r20') C
+define(`m096',`%r21') C
+
+define(`p000a',`%r22') C
+define(`p064a',`%r29') C
+
+define(`s000',`%r31') C
+
+define(`ma000',`%r4') C
+define(`ma064',`%r20') C
+
+define(`r000',`%r3') C
+
+ extrd,u n, 63, 2, %r5
+ cmpb,= %r5, %r0, L(BIG)
+ nop
+
+ fldd 0(up), %fr4
+ ldo 8(up), up
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr4R, %fr24
+ xmpyu %fr8L, %fr4L, %fr25
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+ addib,<> -1, %r5, L(two_or_more)
+ fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+LDEF(one)
+ ldd -0x78(%r30), p032a1
+ ldd -0x70(%r30), p032a2
+ ldd -0x80(%r30), p000a
+ b L(0_one_out)
+ ldd -0x68(%r30), p064a
+
+LDEF(two_or_more)
+ fldd 0(up), %fr4
+ ldo 8(up), up
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ ldd -0x78(%r30), p032a1
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr4R, %fr24
+ xmpyu %fr8L, %fr4L, %fr25
+ ldd -0x70(%r30), p032a2
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ ldd -0x80(%r30), p000a
+ fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+ ldd -0x68(%r30), p064a
+ addib,<> -1, %r5, L(three_or_more)
+ fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+LDEF(two)
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ ldd 0(rp), r000
+ b L(0_two_out)
+ depd m096, 31, 32, ma064
+
+LDEF(three_or_more)
+ fldd 0(up), %fr4
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ ldd 0(rp), r000
+C addib,= -1, %r5, L(0_out)
+ depd m096, 31, 32, ma064
+LDEF(loop0)
+C xmpyu %fr8R, %fr4L, %fr22
+C xmpyu %fr8L, %fr4R, %fr23
+C ldd -0x78(%r30), p032a1
+C fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+C
+C xmpyu %fr8R, %fr4R, %fr24
+C xmpyu %fr8L, %fr4L, %fr25
+C ldd -0x70(%r30), p032a2
+C fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+C
+C ldo 8(rp), rp
+C add climb, p000a, s000
+C ldd -0x80(%r30), p000a
+C fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+C
+C add,dc p064a, %r0, climb
+C ldo 8(up), up
+C ldd -0x68(%r30), p064a
+C fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+C
+C add ma000, s000, s000
+C add,dc ma064, climb, climb
+C fldd 0(up), %fr4
+C
+C sub r000, s000, s000
+C sub,db %r0, climb, climb
+C sub %r0, climb, climb
+C std s000, -8(rp)
+C
+C add p032a1, p032a2, m032
+C add,dc %r0, %r0, m096
+C
+C depd,z m032, 31, 32, ma000
+C extrd,u m032, 31, 32, ma064
+C ldd 0(rp), r000
+C addib,<> -1, %r5, L(loop0)
+C depd m096, 31, 32, ma064
+LDEF(0_out)
+ ldo 8(up), up
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ ldd -0x78(%r30), p032a1
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr4R, %fr24
+ xmpyu %fr8L, %fr4L, %fr25
+ ldd -0x70(%r30), p032a2
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ ldo 8(rp), rp
+ add climb, p000a, s000
+ ldd -0x80(%r30), p000a
+ fstd %fr24, -0x80(%r30) C low product to -0x80..-0x79
+ add,dc p064a, %r0, climb
+ ldd -0x68(%r30), p064a
+ fstd %fr25, -0x68(%r30) C high product to -0x68..-0x61
+ add ma000, s000, s000
+ add,dc ma064, climb, climb
+ sub r000, s000, s000
+ sub,db %r0, climb, climb
+ sub %r0, climb, climb
+ std s000, -8(rp)
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ ldd 0(rp), r000
+ depd m096, 31, 32, ma064
+LDEF(0_two_out)
+ ldd -0x78(%r30), p032a1
+ ldd -0x70(%r30), p032a2
+ ldo 8(rp), rp
+ add climb, p000a, s000
+ ldd -0x80(%r30), p000a
+ add,dc p064a, %r0, climb
+ ldd -0x68(%r30), p064a
+ add ma000, s000, s000
+ add,dc ma064, climb, climb
+ sub r000, s000, s000
+ sub,db %r0, climb, climb
+ sub %r0, climb, climb
+ std s000, -8(rp)
+LDEF(0_one_out)
+ add p032a1, p032a2, m032
+ add,dc %r0, %r0, m096
+ depd,z m032, 31, 32, ma000
+ extrd,u m032, 31, 32, ma064
+ ldd 0(rp), r000
+ depd m096, 31, 32, ma064
+
+ add climb, p000a, s000
+ add,dc p064a, %r0, climb
+ add ma000, s000, s000
+ add,dc ma064, climb, climb
+ sub r000, s000, s000
+ sub,db %r0, climb, climb
+ sub %r0, climb, climb
+ std s000, 0(rp)
+
+ cmpib,>= 4, n, L(done)
+ ldo 8(rp), rp
+
+C 4-way unrolled code.
+
+LDEF(BIG)
+
+define(`p032a1',`%r1') C
+define(`p032a2',`%r19') C
+define(`p096b1',`%r20') C
+define(`p096b2',`%r21') C
+define(`p160c1',`%r22') C
+define(`p160c2',`%r29') C
+define(`p224d1',`%r31') C
+define(`p224d2',`%r3') C
+ C
+define(`m032',`%r4') C
+define(`m096',`%r5') C
+define(`m160',`%r6') C
+define(`m224',`%r7') C
+define(`m288',`%r8') C
+ C
+define(`p000a',`%r1') C
+define(`p064a',`%r19') C
+define(`p064b',`%r20') C
+define(`p128b',`%r21') C
+define(`p128c',`%r22') C
+define(`p192c',`%r29') C
+define(`p192d',`%r31') C
+define(`p256d',`%r3') C
+ C
+define(`s000',`%r10') C
+define(`s064',`%r11') C
+define(`s128',`%r12') C
+define(`s192',`%r13') C
+ C
+define(`ma000',`%r9') C
+define(`ma064',`%r4') C
+define(`ma128',`%r5') C
+define(`ma192',`%r6') C
+define(`ma256',`%r7') C
+ C
+define(`r000',`%r1') C
+define(`r064',`%r19') C
+define(`r128',`%r20') C
+define(`r192',`%r21') C
+
+ std %r6, -0xe8(%r30)
+ std %r7, -0xe0(%r30)
+ std %r8, -0xd8(%r30)
+ std %r9, -0xd0(%r30)
+ std %r10, -0xc8(%r30)
+ std %r11, -0xc0(%r30)
+ std %r12, -0xb8(%r30)
+ std %r13, -0xb0(%r30)
+
+ifdef(`HAVE_ABI_2_0w',
+` extrd,u n, 61, 62, n C right shift 2
+',` extrd,u n, 61, 30, n C right shift 2, zero extend
+')
+
+LDEF(4_or_more)
+ fldd 0(up), %fr4
+ fldd 8(up), %fr5
+ fldd 16(up), %fr6
+ fldd 24(up), %fr7
+ xmpyu %fr8R, %fr4L, %fr22
+ xmpyu %fr8L, %fr4R, %fr23
+ xmpyu %fr8R, %fr5L, %fr24
+ xmpyu %fr8L, %fr5R, %fr25
+ xmpyu %fr8R, %fr6L, %fr26
+ xmpyu %fr8L, %fr6R, %fr27
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr7L, %fr28
+ xmpyu %fr8L, %fr7R, %fr29
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ xmpyu %fr8R, %fr4R, %fr30
+ xmpyu %fr8L, %fr4L, %fr31
+ fstd %fr24, -0x38(%r30) C mid product to -0x38..-0x31
+ xmpyu %fr8R, %fr5R, %fr22
+ xmpyu %fr8L, %fr5L, %fr23
+ fstd %fr25, -0x30(%r30) C mid product to -0x30..-0x29
+ xmpyu %fr8R, %fr6R, %fr24
+ xmpyu %fr8L, %fr6L, %fr25
+ fstd %fr26, -0x58(%r30) C mid product to -0x58..-0x51
+ xmpyu %fr8R, %fr7R, %fr26
+ fstd %fr27, -0x50(%r30) C mid product to -0x50..-0x49
+ addib,<> -1, n, L(8_or_more)
+ xmpyu %fr8L, %fr7L, %fr27
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+ ldd -0x78(%r30), p032a1
+ ldd -0x70(%r30), p032a2
+ ldd -0x38(%r30), p096b1
+ ldd -0x30(%r30), p096b2
+ ldd -0x58(%r30), p160c1
+ ldd -0x50(%r30), p160c2
+ ldd -0x18(%r30), p224d1
+ ldd -0x10(%r30), p224d2
+ b L(end1)
+ nop
+
+LDEF(8_or_more)
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+ ldo 32(up), up
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+ fldd 0(up), %fr4
+ fldd 8(up), %fr5
+ fldd 16(up), %fr6
+ fldd 24(up), %fr7
+ xmpyu %fr8R, %fr4L, %fr22
+ ldd -0x78(%r30), p032a1
+ xmpyu %fr8L, %fr4R, %fr23
+ xmpyu %fr8R, %fr5L, %fr24
+ ldd -0x70(%r30), p032a2
+ xmpyu %fr8L, %fr5R, %fr25
+ xmpyu %fr8R, %fr6L, %fr26
+ ldd -0x38(%r30), p096b1
+ xmpyu %fr8L, %fr6R, %fr27
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+ xmpyu %fr8R, %fr7L, %fr28
+ ldd -0x30(%r30), p096b2
+ xmpyu %fr8L, %fr7R, %fr29
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+ xmpyu %fr8R, %fr4R, %fr30
+ ldd -0x58(%r30), p160c1
+ xmpyu %fr8L, %fr4L, %fr31
+ fstd %fr24, -0x38(%r30) C mid product to -0x38..-0x31
+ xmpyu %fr8R, %fr5R, %fr22
+ ldd -0x50(%r30), p160c2
+ xmpyu %fr8L, %fr5L, %fr23
+ fstd %fr25, -0x30(%r30) C mid product to -0x30..-0x29
+ xmpyu %fr8R, %fr6R, %fr24
+ ldd -0x18(%r30), p224d1
+ xmpyu %fr8L, %fr6L, %fr25
+ fstd %fr26, -0x58(%r30) C mid product to -0x58..-0x51
+ xmpyu %fr8R, %fr7R, %fr26
+ ldd -0x10(%r30), p224d2
+ fstd %fr27, -0x50(%r30) C mid product to -0x50..-0x49
+ addib,= -1, n, L(end2)
+ xmpyu %fr8L, %fr7L, %fr27
+LDEF(loop)
+ add p032a1, p032a2, m032
+ ldd -0x80(%r30), p000a
+ add,dc p096b1, p096b2, m096
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+
+ add,dc p160c1, p160c2, m160
+ ldd -0x68(%r30), p064a
+ add,dc p224d1, p224d2, m224
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+
+ add,dc %r0, %r0, m288
+ ldd -0x40(%r30), p064b
+ ldo 32(up), up
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+
+ depd,z m032, 31, 32, ma000
+ ldd -0x28(%r30), p128b
+ extrd,u m032, 31, 32, ma064
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+
+ depd m096, 31, 32, ma064
+ ldd -0x60(%r30), p128c
+ extrd,u m096, 31, 32, ma128
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+
+ depd m160, 31, 32, ma128
+ ldd -0x48(%r30), p192c
+ extrd,u m160, 31, 32, ma192
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+
+ depd m224, 31, 32, ma192
+ ldd -0x20(%r30), p192d
+ extrd,u m224, 31, 32, ma256
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+
+ depd m288, 31, 32, ma256
+ ldd -0x88(%r30), p256d
+ add climb, p000a, s000
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+
+ add,dc p064a, p064b, s064
+ ldd 0(rp), r000
+ add,dc p128b, p128c, s128
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+
+ add,dc p192c, p192d, s192
+ ldd 8(rp), r064
+ add,dc p256d, %r0, climb
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+
+ ldd 16(rp), r128
+ add ma000, s000, s000 C accum mid 0
+ ldd 24(rp), r192
+ add,dc ma064, s064, s064 C accum mid 1
+
+ add,dc ma128, s128, s128 C accum mid 2
+ fldd 0(up), %fr4
+ add,dc ma192, s192, s192 C accum mid 3
+ fldd 8(up), %fr5
+
+ add,dc ma256, climb, climb
+ fldd 16(up), %fr6
+ sub r000, s000, s000 C accum rlimb 0
+ fldd 24(up), %fr7
+
+ sub,db r064, s064, s064 C accum rlimb 1
+ sub,db r128, s128, s128 C accum rlimb 2
+ std s000, 0(rp)
+
+ sub,db r192, s192, s192 C accum rlimb 3
+ sub,db %r0, climb, climb
+ sub %r0, climb, climb
+ std s064, 8(rp)
+
+ xmpyu %fr8R, %fr4L, %fr22
+ ldd -0x78(%r30), p032a1
+ xmpyu %fr8L, %fr4R, %fr23
+ std s128, 16(rp)
+
+ xmpyu %fr8R, %fr5L, %fr24
+ ldd -0x70(%r30), p032a2
+ xmpyu %fr8L, %fr5R, %fr25
+ std s192, 24(rp)
+
+ xmpyu %fr8R, %fr6L, %fr26
+ ldd -0x38(%r30), p096b1
+ xmpyu %fr8L, %fr6R, %fr27
+ fstd %fr22, -0x78(%r30) C mid product to -0x78..-0x71
+
+ xmpyu %fr8R, %fr7L, %fr28
+ ldd -0x30(%r30), p096b2
+ xmpyu %fr8L, %fr7R, %fr29
+ fstd %fr23, -0x70(%r30) C mid product to -0x70..-0x69
+
+ xmpyu %fr8R, %fr4R, %fr30
+ ldd -0x58(%r30), p160c1
+ xmpyu %fr8L, %fr4L, %fr31
+ fstd %fr24, -0x38(%r30) C mid product to -0x38..-0x31
+
+ xmpyu %fr8R, %fr5R, %fr22
+ ldd -0x50(%r30), p160c2
+ xmpyu %fr8L, %fr5L, %fr23
+ fstd %fr25, -0x30(%r30) C mid product to -0x30..-0x29
+
+ xmpyu %fr8R, %fr6R, %fr24
+ ldd -0x18(%r30), p224d1
+ xmpyu %fr8L, %fr6L, %fr25
+ fstd %fr26, -0x58(%r30) C mid product to -0x58..-0x51
+
+ xmpyu %fr8R, %fr7R, %fr26
+ ldd -0x10(%r30), p224d2
+ fstd %fr27, -0x50(%r30) C mid product to -0x50..-0x49
+ xmpyu %fr8L, %fr7L, %fr27
+
+ addib,<> -1, n, L(loop)
+ ldo 32(rp), rp
+
+LDEF(end2)
+ add p032a1, p032a2, m032
+ ldd -0x80(%r30), p000a
+ add,dc p096b1, p096b2, m096
+ fstd %fr28, -0x18(%r30) C mid product to -0x18..-0x11
+ add,dc p160c1, p160c2, m160
+ ldd -0x68(%r30), p064a
+ add,dc p224d1, p224d2, m224
+ fstd %fr29, -0x10(%r30) C mid product to -0x10..-0x09
+ add,dc %r0, %r0, m288
+ ldd -0x40(%r30), p064b
+ fstd %fr30, -0x80(%r30) C low product to -0x80..-0x79
+ depd,z m032, 31, 32, ma000
+ ldd -0x28(%r30), p128b
+ extrd,u m032, 31, 32, ma064
+ fstd %fr31, -0x68(%r30) C high product to -0x68..-0x61
+ depd m096, 31, 32, ma064
+ ldd -0x60(%r30), p128c
+ extrd,u m096, 31, 32, ma128
+ fstd %fr22, -0x40(%r30) C low product to -0x40..-0x39
+ depd m160, 31, 32, ma128
+ ldd -0x48(%r30), p192c
+ extrd,u m160, 31, 32, ma192
+ fstd %fr23, -0x28(%r30) C high product to -0x28..-0x21
+ depd m224, 31, 32, ma192
+ ldd -0x20(%r30), p192d
+ extrd,u m224, 31, 32, ma256
+ fstd %fr24, -0x60(%r30) C low product to -0x60..-0x59
+ depd m288, 31, 32, ma256
+ ldd -0x88(%r30), p256d
+ add climb, p000a, s000
+ fstd %fr25, -0x48(%r30) C high product to -0x48..-0x41
+ add,dc p064a, p064b, s064
+ ldd 0(rp), r000
+ add,dc p128b, p128c, s128
+ fstd %fr26, -0x20(%r30) C low product to -0x20..-0x19
+ add,dc p192c, p192d, s192
+ ldd 8(rp), r064
+ add,dc p256d, %r0, climb
+ fstd %fr27, -0x88(%r30) C high product to -0x88..-0x81
+ ldd 16(rp), r128
+ add ma000, s000, s000 C accum mid 0
+ ldd 24(rp), r192
+ add,dc ma064, s064, s064 C accum mid 1
+ add,dc ma128, s128, s128 C accum mid 2
+ add,dc ma192, s192, s192 C accum mid 3
+ add,dc ma256, climb, climb
+ sub r000, s000, s000 C accum rlimb 0
+ sub,db r064, s064, s064 C accum rlimb 1
+ sub,db r128, s128, s128 C accum rlimb 2
+ std s000, 0(rp)
+ sub,db r192, s192, s192 C accum rlimb 3
+ sub,db %r0, climb, climb
+ sub %r0, climb, climb
+ std s064, 8(rp)
+ ldd -0x78(%r30), p032a1
+ std s128, 16(rp)
+ ldd -0x70(%r30), p032a2
+ std s192, 24(rp)
+ ldd -0x38(%r30), p096b1
+ ldd -0x30(%r30), p096b2
+ ldd -0x58(%r30), p160c1
+ ldd -0x50(%r30), p160c2
+ ldd -0x18(%r30), p224d1
+ ldd -0x10(%r30), p224d2
+ ldo 32(rp), rp
+
+LDEF(end1)
+ add p032a1, p032a2, m032
+ ldd -0x80(%r30), p000a
+ add,dc p096b1, p096b2, m096
+ add,dc p160c1, p160c2, m160
+ ldd -0x68(%r30), p064a
+ add,dc p224d1, p224d2, m224
+ add,dc %r0, %r0, m288
+ ldd -0x40(%r30), p064b
+ depd,z m032, 31, 32, ma000
+ ldd -0x28(%r30), p128b
+ extrd,u m032, 31, 32, ma064
+ depd m096, 31, 32, ma064
+ ldd -0x60(%r30), p128c
+ extrd,u m096, 31, 32, ma128
+ depd m160, 31, 32, ma128
+ ldd -0x48(%r30), p192c
+ extrd,u m160, 31, 32, ma192
+ depd m224, 31, 32, ma192
+ ldd -0x20(%r30), p192d
+ extrd,u m224, 31, 32, ma256
+ depd m288, 31, 32, ma256
+ ldd -0x88(%r30), p256d
+ add climb, p000a, s000
+ add,dc p064a, p064b, s064
+ ldd 0(rp), r000
+ add,dc p128b, p128c, s128
+ add,dc p192c, p192d, s192
+ ldd 8(rp), r064
+ add,dc p256d, %r0, climb
+ ldd 16(rp), r128
+ add ma000, s000, s000 C accum mid 0
+ ldd 24(rp), r192
+ add,dc ma064, s064, s064 C accum mid 1
+ add,dc ma128, s128, s128 C accum mid 2
+ add,dc ma192, s192, s192 C accum mid 3
+ add,dc ma256, climb, climb
+ sub r000, s000, s000 C accum rlimb 0
+ sub,db r064, s064, s064 C accum rlimb 1
+ sub,db r128, s128, s128 C accum rlimb 2
+ std s000, 0(rp)
+ sub,db r192, s192, s192 C accum rlimb 3
+ sub,db %r0, climb, climb
+ sub %r0, climb, climb
+ std s064, 8(rp)
+ std s128, 16(rp)
+ std s192, 24(rp)
+
+ ldd -0xb0(%r30), %r13
+ ldd -0xb8(%r30), %r12
+ ldd -0xc0(%r30), %r11
+ ldd -0xc8(%r30), %r10
+ ldd -0xd0(%r30), %r9
+ ldd -0xd8(%r30), %r8
+ ldd -0xe0(%r30), %r7
+ ldd -0xe8(%r30), %r6
+LDEF(done)
+ifdef(`HAVE_ABI_2_0w',
+` copy climb, %r28
+',` extrd,u climb, 63, 32, %r29
+ extrd,u climb, 31, 32, %r28
+')
+ ldd -0xf0(%r30), %r5
+ ldd -0xf8(%r30), %r4
+ bve (%r2)
+ ldd,mb -0x100(%r30), %r3
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/pa64/udiv.asm b/gmp/mpn/pa64/udiv.asm
new file mode 100644
index 0000000000..1380a85932
--- /dev/null
+++ b/gmp/mpn/pa64/udiv.asm
@@ -0,0 +1,125 @@
+dnl HP-PA 2.0 64-bit mpn_udiv_qrnnd_r.
+
+dnl Copyright 2001-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C This runs at about 280 cycles on both PA8000 and PA8500, corresponding to a
+C bit more than 4 cycles/bit.
+
+C INPUT PARAMETERS
+define(`n1',`%r26')
+define(`n0',`%r25')
+define(`d',`%r24')
+define(`remptr',`%r23')
+
+define(`q',`%r28')
+define(`dn',`%r29')
+
+define(`old_divstep',
+ `add,dc n0,n0,n0
+ add,dc n1,n1,n1
+ sub,*<< n1,d,%r22
+ copy %r22,n1')
+
+define(`divstep',
+ `add n0,n0,n0
+ add,dc n1,n1,n1
+ sub n1,d,%r1
+ add,dc q,q,q
+ cmpclr,*<< n1,d,%r0
+ copy %r1,n1
+')
+
+ifdef(`HAVE_ABI_2_0w',
+` .level 2.0w
+',` .level 2.0
+')
+PROLOGUE(mpn_udiv_qrnnd_r)
+ifdef(`HAVE_ABI_2_0n',
+` depd %r25,31,32,%r26
+ depd %r23,31,32,%r24
+ copy %r24,%r25
+ ldd -56(%r30),%r24
+ ldw -60(%r30),%r23
+')
+ ldi 0,q
+ cmpib,*>= 0,d,L(large_divisor)
+ ldi 8,%r31 C setup loop counter
+
+ sub %r0,d,dn
+LDEF(Loop)
+ divstep divstep divstep divstep divstep divstep divstep divstep
+ addib,<> -1,%r31,L(Loop)
+ nop
+
+ifdef(`HAVE_ABI_2_0n',
+` copy %r28,%r29
+ extrd,u %r28,31,32,%r28
+')
+ bve (%r2)
+ std n1,0(remptr) C store remainder
+
+LDEF(large_divisor)
+ extrd,u n0,63,1,%r19 C save lsb of dividend
+ shrpd n1,n0,1,n0 C n0 = lo(n1n0 >> 1)
+ shrpd %r0,n1,1,n1 C n1 = hi(n1n0 >> 1)
+ extrd,u d,63,1,%r20 C save lsb of divisor
+ shrpd %r0,d,1,d C d = floor(orig_d / 2)
+ add,l %r20,d,d C d = ceil(orig_d / 2)
+
+ sub %r0,d,dn
+LDEF(Loop2)
+ divstep divstep divstep divstep divstep divstep divstep divstep
+ addib,<> -1,%r31,L(Loop2)
+ nop
+
+ cmpib,*= 0,%r20,L(even_divisor)
+ shladd n1,1,%r19,n1 C shift in omitted dividend lsb
+
+ add d,d,d C restore orig...
+ sub d,%r20,d C ...d value
+ sub %r0,d,dn C r21 = -d
+
+ add,*nuv n1,q,n1 C fix remainder for omitted divisor lsb
+ add,l n1,dn,n1 C adjust remainder if rem. fix carried
+ add,dc %r0,q,q C adjust quotient accordingly
+
+ sub,*<< n1,d,%r0 C remainder >= divisor?
+ add,l n1,dn,n1 C adjust remainder
+ add,dc %r0,q,q C adjust quotient
+
+LDEF(even_divisor)
+ifdef(`HAVE_ABI_2_0n',
+` copy %r28,%r29
+ extrd,u %r28,31,32,%r28
+')
+ bve (%r2)
+ std n1,0(remptr) C store remainder
+EPILOGUE(mpn_udiv_qrnnd_r)
diff --git a/gmp/mpn/pa64/umul.asm b/gmp/mpn/pa64/umul.asm
new file mode 100644
index 0000000000..c3341ecfe6
--- /dev/null
+++ b/gmp/mpn/pa64/umul.asm
@@ -0,0 +1,98 @@
+dnl Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Optimizations:
+dnl * Avoid skip instructions
+dnl * Put carry-generating and carry-consuming insns consecutively
+dnl * Don't allocate any stack, "home" positions for parameters could be used.
+
+include(`../config.m4')
+
+define(`p0',`%r28')
+define(`p1',`%r29')
+define(`t32',`%r19')
+define(`t0',`%r20')
+define(`t1',`%r21')
+define(`x',`%r22')
+define(`m0',`%r23')
+define(`m1',`%r24')
+
+ifdef(`HAVE_ABI_2_0w',
+` .level 2.0w
+',` .level 2.0
+')
+PROLOGUE(mpn_umul_ppmm_r)
+ ldo 128(%r30),%r30
+ifdef(`HAVE_ABI_2_0w',
+` std %r26,-64(%r30)
+ std %r25,-56(%r30)
+ copy %r24,%r31
+',`
+ depd %r25,31,32,%r26
+ std %r26,-64(%r30)
+ depd %r23,31,32,%r24
+ std %r24,-56(%r30)
+ ldw -180(%r30),%r31
+')
+
+ fldd -64(%r30),%fr4
+ fldd -56(%r30),%fr5
+
+ xmpyu %fr5R,%fr4R,%fr6
+ fstd %fr6,-128(%r30)
+ xmpyu %fr5R,%fr4L,%fr7
+ fstd %fr7,-120(%r30)
+ xmpyu %fr5L,%fr4R,%fr8
+ fstd %fr8,-112(%r30)
+ xmpyu %fr5L,%fr4L,%fr9
+ fstd %fr9,-104(%r30)
+
+ depdi,z 1,31,1,t32 C t32 = 2^32
+
+ ldd -128(%r30),p0 C lo = low 64 bit of product
+ ldd -120(%r30),m0 C m0 = mid0 64 bit of product
+ ldd -112(%r30),m1 C m1 = mid1 64 bit of product
+ ldd -104(%r30),p1 C hi = high 64 bit of product
+
+ add,l,*nuv m0,m1,x C x = m1+m0
+ add,l t32,p1,p1 C propagate carry to mid of p1
+ depd,z x,31,32,t0 C lo32(m1+m0)
+ add t0,p0,p0
+ extrd,u x,31,32,t1 C hi32(m1+m0)
+ add,dc t1,p1,p1
+
+ std p0,0(%r31) C store low half of product
+ifdef(`HAVE_ABI_2_0w',
+` copy p1,%r28 C return val in %r28
+',` extrd,u p1,31,32,%r28 C return val in %r28,%r29
+')
+ bve (%r2)
+ ldo -128(%r30),%r30
+EPILOGUE(mpn_umul_ppmm_r)
+
diff --git a/gmp/mpn/power/add_n.asm b/gmp/mpn/power/add_n.asm
new file mode 100644
index 0000000000..6d6ca73da9
--- /dev/null
+++ b/gmp/mpn/power/add_n.asm
@@ -0,0 +1,83 @@
+dnl IBM POWER mpn_add_n -- Add two limb vectors of equal, non-zero length.
+
+dnl Copyright 1992, 1994-1996, 1999-2001, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl INPUT PARAMETERS
+dnl res_ptr r3
+dnl s1_ptr r4
+dnl s2_ptr r5
+dnl size r6
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+ andil. 10,6,1 C odd or even number of limbs?
+ l 8,0(4) C load least significant s1 limb
+ l 0,0(5) C load least significant s2 limb
+ cal 3,-4(3) C offset res_ptr, it's updated before it's used
+ sri 10,6,1 C count for unrolled loop
+ a 7,0,8 C add least significant limbs, set cy
+ mtctr 10 C copy count into CTR
+ beq 0,Leven C branch if even # of limbs (# of limbs >= 2)
+
+C We have an odd # of limbs. Add the first limbs separately.
+ cmpi 1,10,0 C is count for unrolled loop zero?
+ bc 4,6,L1 C bne cr1,L1 (misassembled by gas)
+ st 7,4(3)
+ aze 3,10 C use the fact that r10 is zero...
+ br C return
+
+C We added least significant limbs. Now reload the next limbs to enter loop.
+L1: lu 8,4(4) C load s1 limb and update s1_ptr
+ lu 0,4(5) C load s2 limb and update s2_ptr
+ stu 7,4(3)
+ ae 7,0,8 C add limbs, set cy
+Leven: lu 9,4(4) C load s1 limb and update s1_ptr
+ lu 10,4(5) C load s2 limb and update s2_ptr
+ bdz Lend C If done, skip loop
+
+Loop: lu 8,4(4) C load s1 limb and update s1_ptr
+ lu 0,4(5) C load s2 limb and update s2_ptr
+ ae 11,10,9 C add previous limbs with cy, set cy
+ stu 7,4(3) C
+ lu 9,4(4) C load s1 limb and update s1_ptr
+ lu 10,4(5) C load s2 limb and update s2_ptr
+ ae 7,0,8 C add previous limbs with cy, set cy
+ stu 11,4(3) C
+ bdn Loop C decrement CTR and loop back
+
+Lend: ae 11,10,9 C add limbs with cy, set cy
+ st 7,4(3) C
+ st 11,8(3) C
+ lil 3,0 C load cy into ...
+ aze 3,3 C ... return value register
+ br
+EPILOGUE(mpn_add_n)
diff --git a/gmp/mpn/power/addmul_1.asm b/gmp/mpn/power/addmul_1.asm
new file mode 100644
index 0000000000..76d8df3c76
--- /dev/null
+++ b/gmp/mpn/power/addmul_1.asm
@@ -0,0 +1,126 @@
+dnl IBM POWER mpn_addmul_1 -- Multiply a limb vector with a limb and add the
+dnl result to a second limb vector.
+
+dnl Copyright 1992, 1994, 1999-2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl INPUT PARAMETERS
+dnl res_ptr r3
+dnl s1_ptr r4
+dnl size r5
+dnl s2_limb r6
+
+dnl The POWER architecture has no unsigned 32x32->64 bit multiplication
+dnl instruction. To obtain that operation, we have to use the 32x32->64
+dnl signed multiplication instruction, and add the appropriate compensation to
+dnl the high limb of the result. We add the multiplicand if the multiplier
+dnl has its most significant bit set, and we add the multiplier if the
+dnl multiplicand has its most significant bit set. We need to preserve the
+dnl carry flag between each iteration, so we have to compute the compensation
+dnl carefully (the natural, srai+and doesn't work). Since all POWER can
+dnl branch in zero cycles, we use conditional branches for the compensation.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 8
+ cax 9,9,7
+ l 7,4(3)
+ a 8,8,7 C add res_limb
+ blt Lneg
+Lpos: bdz Lend
+
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 8,0,9 C low limb + old_cy_limb + old cy
+ l 7,4(3)
+ aze 10,10 C propagate cy to new cy_limb
+ a 8,8,7 C add res_limb
+ bge Lp0
+ cax 10,10,6 C adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 8,0,10
+ l 7,4(3)
+ aze 9,9
+ a 8,8,7
+ bge Lp1
+ cax 9,9,6 C adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 7
+ ae 8,7,9
+ l 7,4(3)
+ ae 10,10,0 C propagate cy to new cy_limb
+ a 8,8,7 C add res_limb
+ bge Ln0
+ cax 10,10,6 C adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 7
+ ae 8,7,10
+ l 7,4(3)
+ ae 9,9,0 C propagate cy to new cy_limb
+ a 8,8,7 C add res_limb
+ bge Ln1
+ cax 9,9,6 C adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/power/gmp-mparam.h b/gmp/mpn/power/gmp-mparam.h
new file mode 100644
index 0000000000..7cb36f963e
--- /dev/null
+++ b/gmp/mpn/power/gmp-mparam.h
@@ -0,0 +1,69 @@
+/* POWER gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2002-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* Generated by tuneup.c, 2003-02-10, gcc 3.2, POWER2 66.7MHz */
+
+#define MUL_TOOM22_THRESHOLD 12
+#define MUL_TOOM33_THRESHOLD 75
+
+#define SQR_BASECASE_THRESHOLD 7
+#define SQR_TOOM2_THRESHOLD 28
+#define SQR_TOOM3_THRESHOLD 86
+
+#define DIV_SB_PREINV_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_DC_THRESHOLD 36
+#define POWM_THRESHOLD 69
+
+#define HGCD_THRESHOLD 97
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 590
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD 12
+#define DIVREM_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1_NORM_THRESHOLD 10
+#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define USE_PREINV_DIVREM_1 0
+#define USE_PREINV_MOD_1 1
+#define DIVREM_2_THRESHOLD 11
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always */
+
+#define GET_STR_DC_THRESHOLD 10
+#define GET_STR_PRECOMPUTE_THRESHOLD 20
+#define SET_STR_THRESHOLD 2899
+
+#define MUL_FFT_TABLE { 336, 800, 1408, 3584, 10240, 24576, 0 }
+#define MUL_FFT_MODF_THRESHOLD 296
+#define MUL_FFT_THRESHOLD 2304
+
+#define SQR_FFT_TABLE { 336, 800, 1408, 3584, 10240, 24576, 0 }
+#define SQR_FFT_MODF_THRESHOLD 296
+#define SQR_FFT_THRESHOLD 2304
diff --git a/gmp/mpn/power/lshift.asm b/gmp/mpn/power/lshift.asm
new file mode 100644
index 0000000000..efa210556d
--- /dev/null
+++ b/gmp/mpn/power/lshift.asm
@@ -0,0 +1,61 @@
+dnl IBM POWER mpn_lshift -- Shift a number left.
+
+dnl Copyright 1992, 1994, 1999-2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl INPUT PARAMETERS
+dnl res_ptr r3
+dnl s_ptr r4
+dnl size r5
+dnl cnt r6
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ sli 0,5,2
+ cax 9,3,0
+ cax 4,4,0
+ sfi 8,6,32
+ mtctr 5 C put limb count in CTR loop register
+ lu 0,-4(4) C read most significant limb
+ sre 3,0,8 C compute carry out limb, and init MQ register
+ bdz Lend2 C if just one limb, skip loop
+ lu 0,-4(4) C read 2:nd most significant limb
+ sreq 7,0,8 C compute most significant limb of result
+ bdz Lend C if just two limb, skip loop
+Loop: lu 0,-4(4) C load next lower limb
+ stu 7,-4(9) C store previous result during read latency
+ sreq 7,0,8 C compute result limb
+ bdn Loop C loop back until CTR is zero
+Lend: stu 7,-4(9) C store 2:nd least significant limb
+Lend2: sle 7,0,6 C compute least significant limb
+ st 7,-4(9) C store it
+ br
+EPILOGUE(mpn_lshift)
diff --git a/gmp/mpn/power/mul_1.asm b/gmp/mpn/power/mul_1.asm
new file mode 100644
index 0000000000..38b7b66be0
--- /dev/null
+++ b/gmp/mpn/power/mul_1.asm
@@ -0,0 +1,113 @@
+dnl IBM POWER mpn_mul_1 -- Multiply a limb vector with a limb and store the
+dnl result in a second limb vector.
+
+dnl Copyright 1992, 1994, 1999-2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl INPUT PARAMETERS
+dnl res_ptr r3
+dnl s1_ptr r4
+dnl size r5
+dnl s2_limb r6
+
+dnl The POWER architecture has no unsigned 32x32->64 bit multiplication
+dnl instruction. To obtain that operation, we have to use the 32x32->64
+dnl signed multiplication instruction, and add the appropriate compensation to
+dnl the high limb of the result. We add the multiplicand if the multiplier
+dnl has its most significant bit set, and we add the multiplier if the
+dnl multiplicand has its most significant bit set. We need to preserve the
+dnl carry flag between each iteration, so we have to compute the compensation
+dnl carefully (the natural, srai+and doesn't work). Since all POWER can
+dnl branch in zero cycles, we use conditional branches for the compensation.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 8
+ ai 0,0,0 C reset carry
+ cax 9,9,7
+ blt Lneg
+Lpos: bdz Lend
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 8,0,9
+ bge Lp0
+ cax 10,10,6 C adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 8,0,10
+ bge Lp1
+ cax 9,9,6 C adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ cax 10,10,0 C adjust high limb for negative s2_limb
+ mfmq 0
+ ae 8,0,9
+ bge Ln0
+ cax 10,10,6 C adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ cax 9,9,0 C adjust high limb for negative s2_limb
+ mfmq 0
+ ae 8,0,10
+ bge Ln1
+ cax 9,9,6 C adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/power/rshift.asm b/gmp/mpn/power/rshift.asm
new file mode 100644
index 0000000000..1d1815ccb5
--- /dev/null
+++ b/gmp/mpn/power/rshift.asm
@@ -0,0 +1,59 @@
+dnl IBM POWER mpn_rshift -- Shift a number right.
+
+dnl Copyright 1992, 1994, 1999-2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl INPUT PARAMETERS
+dnl res_ptr r3
+dnl s_ptr r4
+dnl size r5
+dnl cnt r6
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ sfi 8,6,32
+ mtctr 5 C put limb count in CTR loop register
+ l 0,0(4) C read least significant limb
+ ai 9,3,-4 C adjust res_ptr since it's offset in the stu:s
+ sle 3,0,8 C compute carry limb, and init MQ register
+ bdz Lend2 C if just one limb, skip loop
+ lu 0,4(4) C read 2:nd least significant limb
+ sleq 7,0,8 C compute least significant limb of result
+ bdz Lend C if just two limb, skip loop
+Loop: lu 0,4(4) C load next higher limb
+ stu 7,4(9) C store previous result during read latency
+ sleq 7,0,8 C compute result limb
+ bdn Loop C loop back until CTR is zero
+Lend: stu 7,4(9) C store 2:nd most significant limb
+Lend2: sre 7,0,6 C compute most significant limb
+ st 7,4(9) C store it
+ br
+EPILOGUE(mpn_rshift)
diff --git a/gmp/mpn/power/sdiv.asm b/gmp/mpn/power/sdiv.asm
new file mode 100644
index 0000000000..4a9ed143b8
--- /dev/null
+++ b/gmp/mpn/power/sdiv.asm
@@ -0,0 +1,39 @@
+dnl Copyright 1999, 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_sdiv_qrnnd)
+ mtmq 5
+ div 0,4,6
+ mfmq 9
+ st 9,0(3)
+ mr 3,0
+ br
+EPILOGUE(mpn_sdiv_qrnnd)
diff --git a/gmp/mpn/power/sub_n.asm b/gmp/mpn/power/sub_n.asm
new file mode 100644
index 0000000000..390c802d8b
--- /dev/null
+++ b/gmp/mpn/power/sub_n.asm
@@ -0,0 +1,85 @@
+dnl IBM POWER mpn_sub_n -- Subtract two limb vectors of equal, non-zero
+dnl length.
+
+dnl Copyright 1992, 1994-1996, 1999-2001, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl INPUT PARAMETERS
+dnl res_ptr r3
+dnl s1_ptr r4
+dnl s2_ptr r5
+dnl size r6
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ andil. 10,6,1 C odd or even number of limbs?
+ l 8,0(4) C load least significant s1 limb
+ l 0,0(5) C load least significant s2 limb
+ cal 3,-4(3) C offset res_ptr, it's updated before it's used
+ sri 10,6,1 C count for unrolled loop
+ sf 7,0,8 C subtract least significant limbs, set cy
+ mtctr 10 C copy count into CTR
+ beq 0,Leven C branch if even # of limbs (# of limbs >= 2)
+
+C We have an odd # of limbs. Add the first limbs separately.
+ cmpi 1,10,0 C is count for unrolled loop zero?
+ bc 4,6,L1 C bne cr1,L1 (misassembled by gas)
+ st 7,4(3)
+ sfe 3,0,0 C load !cy into ...
+ sfi 3,3,0 C ... return value register
+ br C return
+
+C We added least significant limbs. Now reload the next limbs to enter loop.
+L1: lu 8,4(4) C load s1 limb and update s1_ptr
+ lu 0,4(5) C load s2 limb and update s2_ptr
+ stu 7,4(3)
+ sfe 7,0,8 C subtract limbs, set cy
+Leven: lu 9,4(4) C load s1 limb and update s1_ptr
+ lu 10,4(5) C load s2 limb and update s2_ptr
+ bdz Lend C If done, skip loop
+
+Loop: lu 8,4(4) C load s1 limb and update s1_ptr
+ lu 0,4(5) C load s2 limb and update s2_ptr
+ sfe 11,10,9 C subtract previous limbs with cy, set cy
+ stu 7,4(3) C
+ lu 9,4(4) C load s1 limb and update s1_ptr
+ lu 10,4(5) C load s2 limb and update s2_ptr
+ sfe 7,0,8 C subtract previous limbs with cy, set cy
+ stu 11,4(3) C
+ bdn Loop C decrement CTR and loop back
+
+Lend: sfe 11,10,9 C subtract limbs with cy, set cy
+ st 7,4(3) C
+ st 11,8(3) C
+ sfe 3,0,0 C load !cy into ...
+ sfi 3,3,0 C ... return value register
+ br
+EPILOGUE(mpn_sub_n)
diff --git a/gmp/mpn/power/submul_1.asm b/gmp/mpn/power/submul_1.asm
new file mode 100644
index 0000000000..1788e0d4f4
--- /dev/null
+++ b/gmp/mpn/power/submul_1.asm
@@ -0,0 +1,131 @@
+dnl IBM POWER mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+dnl the result from a second limb vector.
+
+dnl Copyright 1992, 1994, 1999-2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl INPUT PARAMETERS
+dnl res_ptr r3
+dnl s1_ptr r4
+dnl size r5
+dnl s2_limb r6
+
+dnl The POWER architecture has no unsigned 32x32->64 bit multiplication
+dnl instruction. To obtain that operation, we have to use the 32x32->64
+dnl signed multiplication instruction, and add the appropriate compensation to
+dnl the high limb of the result. We add the multiplicand if the multiplier
+dnl has its most significant bit set, and we add the multiplier if the
+dnl multiplicand has its most significant bit set. We need to preserve the
+dnl carry flag between each iteration, so we have to compute the compensation
+dnl carefully (the natural, srai+and doesn't work). Since all POWER can
+dnl branch in zero cycles, we use conditional branches for the compensation.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 11
+ cax 9,9,7
+ l 7,4(3)
+ sf 8,11,7 C add res_limb
+ a 11,8,11 C invert cy (r11 is junk)
+ blt Lneg
+Lpos: bdz Lend
+
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 11,0,9 C low limb + old_cy_limb + old cy
+ l 7,4(3)
+ aze 10,10 C propagate cy to new cy_limb
+ sf 8,11,7 C add res_limb
+ a 11,8,11 C invert cy (r11 is junk)
+ bge Lp0
+ cax 10,10,6 C adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 11,0,10
+ l 7,4(3)
+ aze 9,9
+ sf 8,11,7
+ a 11,8,11 C invert cy (r11 is junk)
+ bge Lp1
+ cax 9,9,6 C adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 7
+ ae 11,7,9
+ l 7,4(3)
+ ae 10,10,0 C propagate cy to new cy_limb
+ sf 8,11,7 C add res_limb
+ a 11,8,11 C invert cy (r11 is junk)
+ bge Ln0
+ cax 10,10,6 C adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 7
+ ae 11,7,10
+ l 7,4(3)
+ ae 9,9,0 C propagate cy to new cy_limb
+ sf 8,11,7 C add res_limb
+ a 11,8,11 C invert cy (r11 is junk)
+ bge Ln1
+ cax 9,9,6 C adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/power/umul.asm b/gmp/mpn/power/umul.asm
new file mode 100644
index 0000000000..5a0599e21d
--- /dev/null
+++ b/gmp/mpn/power/umul.asm
@@ -0,0 +1,43 @@
+dnl Copyright 1999, 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_umul_ppmm)
+ mul 9,4,5
+ srai 0,4,31
+ and 0,0,5
+ srai 5,5,31
+ and 5,5,4
+ cax 0,0,5
+ mfmq 11
+ st 11,0(3)
+ cax 3,9,0
+ br
+EPILOGUE(mpn_umul_ppmm)
diff --git a/gmp/mpn/powerpc32/750/com.asm b/gmp/mpn/powerpc32/750/com.asm
new file mode 100644
index 0000000000..1b8b574b9c
--- /dev/null
+++ b/gmp/mpn/powerpc32/750/com.asm
@@ -0,0 +1,79 @@
+dnl PowerPC 750 mpn_com -- mpn bitwise one's complement
+
+dnl Copyright 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C 603e: ?
+C 604e: 3.0
+C 75x (G3): 2.0
+C 7400,7410 (G4): 2.0
+C 744x,745x (G4+): 3.0
+
+C void mpn_com (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C This loop form is necessary for the claimed speed.
+
+ASM_START()
+PROLOGUE(mpn_com)
+
+ C r3 dst
+ C r4 src
+ C r5 size
+
+ mtctr r5 C size
+ lwz r5, 0(r4) C src low limb
+
+ sub r4, r4, r3 C src-dst
+ subi r3, r3, 4 C dst-4
+
+ addi r4, r4, 8 C src-dst+8
+ bdz L(one)
+
+L(top):
+ C r3 &dst[i-1]
+ C r4 src-dst
+ C r5 src[i]
+ C r6 scratch
+
+ not r6, r5 C ~src[i]
+ lwzx r5, r4,r3 C src[i+1]
+
+ stwu r6, 4(r3) C dst[i]
+ bdnz L(top)
+
+L(one):
+ not r6, r5
+
+ stw r6, 4(r3) C dst[size-1]
+ blr
+
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/750/gmp-mparam.h b/gmp/mpn/powerpc32/750/gmp-mparam.h
new file mode 100644
index 0000000000..3667e8596d
--- /dev/null
+++ b/gmp/mpn/powerpc32/750/gmp-mparam.h
@@ -0,0 +1,192 @@
+/* PowerPC-32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2002, 2004, 2009, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* This file is used for 75x (G3) and for 7400/7410 (G4), both which have
+ much slow multiply instructions. */
+
+/* 450 MHz PPC 7400 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_NORM_THRESHOLD 3
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 11
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 11
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 18
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 38
+#define USE_PREINV_DIVREM_1 1
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 10
+#define MUL_TOOM33_THRESHOLD 38
+#define MUL_TOOM44_THRESHOLD 99
+#define MUL_TOOM6H_THRESHOLD 141
+#define MUL_TOOM8H_THRESHOLD 212
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 65
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 69
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 65
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 66
+
+#define SQR_BASECASE_THRESHOLD 4
+#define SQR_TOOM2_THRESHOLD 18
+#define SQR_TOOM3_THRESHOLD 57
+#define SQR_TOOM4_THRESHOLD 142
+#define SQR_TOOM6_THRESHOLD 173
+#define SQR_TOOM8_THRESHOLD 309
+
+#define MULMOD_BNM1_THRESHOLD 9
+#define SQRMOD_BNM1_THRESHOLD 11
+
+#define MUL_FFT_MODF_THRESHOLD 220 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 220, 5}, { 13, 6}, { 7, 5}, { 15, 6}, \
+ { 8, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 13, 7}, { 7, 6}, { 17, 7}, { 9, 6}, \
+ { 19, 7}, { 11, 6}, { 23, 7}, { 13, 8}, \
+ { 7, 7}, { 19, 8}, { 11, 7}, { 23, 9}, \
+ { 7, 8}, { 15, 7}, { 33, 8}, { 19, 7}, \
+ { 39, 8}, { 23, 9}, { 15, 8}, { 39, 9}, \
+ { 23, 8}, { 47,10}, { 15, 9}, { 31, 8}, \
+ { 67, 9}, { 55,10}, { 31, 9}, { 63, 8}, \
+ { 127, 7}, { 255, 9}, { 71, 8}, { 143, 7}, \
+ { 287, 9}, { 79,10}, { 47, 9}, { 95,11}, \
+ { 31,10}, { 63, 9}, { 127, 8}, { 255, 9}, \
+ { 143, 8}, { 287,10}, { 79, 9}, { 159, 8}, \
+ { 319, 9}, { 175, 8}, { 351, 7}, { 703,10}, \
+ { 95, 9}, { 191, 8}, { 383, 9}, { 207,10}, \
+ { 111,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 143, 9}, { 287, 8}, { 575,10}, { 159, 9}, \
+ { 319,10}, { 175, 9}, { 351, 8}, { 703,11}, \
+ { 95,10}, { 191, 9}, { 383,10}, { 207, 9}, \
+ { 415, 8}, { 831,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271, 9}, { 543,10}, \
+ { 287, 9}, { 575,11}, { 159,10}, { 351, 9}, \
+ { 703, 8}, { 1407,11}, { 191,10}, { 415, 9}, \
+ { 831,11}, { 223,10}, { 447, 9}, { 895,12}, \
+ { 127,11}, { 255,10}, { 543,11}, { 287,10}, \
+ { 575,11}, { 351,10}, { 703, 9}, { 1407,12}, \
+ { 191,11}, { 415,10}, { 831,11}, { 447,10}, \
+ { 895,13}, { 127,12}, { 255,11}, { 543,10}, \
+ { 1087,11}, { 575,12}, { 319,11}, { 703,10}, \
+ { 1407,12}, { 383,11}, { 831,12}, { 447,11}, \
+ { 895,10}, { 1791,11}, { 959,13}, { 255,12}, \
+ { 511,11}, { 1087,12}, { 575,11}, { 1215,12}, \
+ { 703,11}, { 1407,13}, { 383,12}, { 895,11}, \
+ { 1791,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1215,13}, { 639,12}, { 1407,13}, { 895,12}, \
+ { 1919,14}, { 511,13}, { 1023,12}, { 2047,13}, \
+ { 1151,12}, { 2303,13}, { 1407,14}, { 767,13}, \
+ { 1919,10}, { 15359,12}, { 4096,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 154
+#define MUL_FFT_THRESHOLD 2688
+
+#define SQR_FFT_MODF_THRESHOLD 184 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 184, 5}, { 6, 4}, { 13, 5}, { 13, 6}, \
+ { 7, 5}, { 15, 6}, { 13, 7}, { 7, 6}, \
+ { 16, 7}, { 9, 6}, { 19, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 19, 8}, \
+ { 11, 7}, { 25, 9}, { 7, 8}, { 15, 7}, \
+ { 31, 8}, { 19, 7}, { 39, 8}, { 27, 9}, \
+ { 15, 8}, { 39, 9}, { 23,10}, { 15, 9}, \
+ { 31, 8}, { 63, 9}, { 39, 8}, { 79, 9}, \
+ { 47, 8}, { 95,10}, { 31, 9}, { 63, 8}, \
+ { 127, 7}, { 255, 9}, { 71, 8}, { 143, 7}, \
+ { 287, 9}, { 79, 8}, { 159,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 9}, { 143, 8}, { 287, 7}, { 575,10}, \
+ { 79, 9}, { 159, 8}, { 319, 9}, { 175, 8}, \
+ { 351,10}, { 95, 9}, { 191, 8}, { 383, 9}, \
+ { 207,10}, { 111,11}, { 63,10}, { 127, 9}, \
+ { 255,10}, { 143, 9}, { 287, 8}, { 575,10}, \
+ { 159, 9}, { 319,10}, { 175, 9}, { 351,11}, \
+ { 95,10}, { 191, 9}, { 383,10}, { 207, 9}, \
+ { 415, 8}, { 831,10}, { 223,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 351, 9}, { 703,11}, \
+ { 191,10}, { 415, 9}, { 831,11}, { 223,10}, \
+ { 447, 9}, { 895,12}, { 127,11}, { 255,10}, \
+ { 511,11}, { 287,10}, { 575,11}, { 319,10}, \
+ { 639,11}, { 351,10}, { 703, 9}, { 1407,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,10}, \
+ { 831,11}, { 447,10}, { 895,13}, { 127,12}, \
+ { 255,11}, { 511,10}, { 1023,11}, { 575,12}, \
+ { 319,11}, { 703,10}, { 1407,12}, { 383,11}, \
+ { 831,12}, { 447,11}, { 895,10}, { 1791,11}, \
+ { 959,13}, { 255,12}, { 511,11}, { 1023,12}, \
+ { 575,11}, { 1215,12}, { 703,11}, { 1407,13}, \
+ { 383,12}, { 895,11}, { 1791,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1215,13}, { 639,12}, \
+ { 1471,13}, { 767,12}, { 1535,13}, { 895,12}, \
+ { 1919,14}, { 511,13}, { 1151,12}, { 2431,13}, \
+ { 1407,14}, { 767,13}, { 1919,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 152
+#define SQR_FFT_THRESHOLD 1728
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 33
+#define MULLO_MUL_N_THRESHOLD 5240
+
+#define DC_DIV_QR_THRESHOLD 31
+#define DC_DIVAPPR_Q_THRESHOLD 108
+#define DC_BDIV_QR_THRESHOLD 35
+#define DC_BDIV_Q_THRESHOLD 88
+
+#define INV_MULMOD_BNM1_THRESHOLD 42
+#define INV_NEWTON_THRESHOLD 149
+#define INV_APPR_THRESHOLD 125
+
+#define BINV_NEWTON_THRESHOLD 156
+#define REDC_1_TO_REDC_N_THRESHOLD 39
+
+#define MU_DIV_QR_THRESHOLD 807
+#define MU_DIVAPPR_Q_THRESHOLD 807
+#define MUPI_DIV_QR_THRESHOLD 66
+#define MU_BDIV_QR_THRESHOLD 667
+#define MU_BDIV_Q_THRESHOLD 807
+
+#define MATRIX22_STRASSEN_THRESHOLD 11
+#define HGCD_THRESHOLD 87
+#define GCD_DC_THRESHOLD 233
+#define GCDEXT_DC_THRESHOLD 198
+#define JACOBI_BASE_METHOD 1
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 28
+#define SET_STR_DC_THRESHOLD 390
+#define SET_STR_PRECOMPUTE_THRESHOLD 814
diff --git a/gmp/mpn/powerpc32/750/lshift.asm b/gmp/mpn/powerpc32/750/lshift.asm
new file mode 100644
index 0000000000..3a1c1a7212
--- /dev/null
+++ b/gmp/mpn/powerpc32/750/lshift.asm
@@ -0,0 +1,155 @@
+dnl PowerPC 750 mpn_lshift -- mpn left shift.
+
+dnl Copyright 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C 750: 3.0
+C 7400: 3.0
+
+
+C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C This code is the same per-limb speed as mpn/powerpc32/lshift.asm, but
+C smaller and saving about 30 or so cycles of overhead.
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+
+ C r3 dst
+ C r4 src
+ C r5 size
+ C r6 shift
+
+ mtctr r5 C size
+ slwi r5, r5, 2 C 4*size
+
+ subfic r7, r6, 32 C 32-shift
+ add r4, r4, r5 C &src[size]
+
+ add r5, r3, r5 C &dst[size]
+ lwz r8, -4(r4) C src[size-1]
+ bdz L(one)
+
+ lwzu r9, -8(r4) C src[size-2]
+
+ srw r3, r8, r7 C return value
+ slw r8, r8, r6 C src[size-1] << shift
+ bdz L(two)
+
+
+L(top):
+ C r3 return value
+ C r4 src, incrementing
+ C r5 dst, incrementing
+ C r6 lshift
+ C r7 32-shift
+ C r8 src[i+1] << shift
+ C r9 src[i]
+ C r10
+
+ lwzu r10, -4(r4)
+ srw r11, r9, r7
+
+ or r8, r8, r11
+ stwu r8, -4(r5)
+
+ slw r8, r9, r6
+ bdz L(odd)
+
+ C r8 src[i+1] << shift
+ C r9
+ C r10 src[i]
+
+ lwzu r9, -4(r4)
+ srw r11, r10, r7
+
+ or r8, r8, r11
+ stwu r8, -4(r5)
+
+ slw r8, r10, r6
+ bdnz L(top)
+
+
+L(two):
+ C r3 return value
+ C r4
+ C r5 &dst[2]
+ C r6 shift
+ C r7 32-shift
+ C r8 src[1] << shift
+ C r9 src[0]
+ C r10
+
+ srw r11, r9, r7
+ slw r12, r9, r6 C src[0] << shift
+
+ or r8, r8, r11
+ stw r12, -8(r5) C dst[0]
+
+ stw r8, -4(r5) C dst[1]
+ blr
+
+
+L(odd):
+ C r3 return value
+ C r4
+ C r5 &dst[2]
+ C r6 shift
+ C r7 32-shift
+ C r8 src[1] << shift
+ C r9
+ C r10 src[0]
+
+ srw r11, r10, r7
+ slw r12, r10, r6
+
+ or r8, r8, r11
+ stw r12, -8(r5) C dst[0]
+
+ stw r8, -4(r5) C dst[1]
+ blr
+
+
+L(one):
+ C r5 &dst[1]
+ C r6 shift
+ C r7 32-shift
+ C r8 src[0]
+
+ srw r3, r8, r7 C return value
+ slw r8, r8, r6 C src[size-1] << shift
+
+ stw r8, -4(r5) C dst[0]
+ blr
+
+EPILOGUE(mpn_lshift)
diff --git a/gmp/mpn/powerpc32/750/rshift.asm b/gmp/mpn/powerpc32/750/rshift.asm
new file mode 100644
index 0000000000..4825fee618
--- /dev/null
+++ b/gmp/mpn/powerpc32/750/rshift.asm
@@ -0,0 +1,153 @@
+dnl PowerPC 750 mpn_rshift -- mpn right shift.
+
+dnl Copyright 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C 750: 3.0
+C 7400: 3.0
+
+
+C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C This code is the same per-limb speed as mpn/powerpc32/rshift.asm, but
+C smaller and saving about 30 or so cycles of overhead.
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+
+ C r3 dst
+ C r4 src
+ C r5 size
+ C r6 shift
+
+ mtctr r5 C size
+ lwz r8, 0(r4) C src[0]
+
+ subfic r7, r6, 32 C 32-shift
+ addi r5, r3, -4 C dst-4
+
+ slw r3, r8, r7 C return value
+ bdz L(one)
+
+ lwzu r9, 4(r4) C src[1]
+ srw r8, r8, r6 C src[0] >> shift
+ bdz L(two)
+
+
+L(top):
+ C r3 return value
+ C r4 src, incrementing
+ C r5 dst, incrementing
+ C r6 shift
+ C r7 32-shift
+ C r8 src[i-1] >> shift
+ C r9 src[i]
+ C r10
+
+ lwzu r10, 4(r4)
+ slw r11, r9, r7
+
+ or r8, r8, r11
+ stwu r8, 4(r5)
+
+ srw r8, r9, r6
+ bdz L(odd)
+
+ C r8 src[i-1] >> shift
+ C r9
+ C r10 src[i]
+
+ lwzu r9, 4(r4)
+ slw r11, r10, r7
+
+ or r8, r8, r11
+ stwu r8, 4(r5)
+
+ srw r8, r10, r6
+ bdnz L(top)
+
+
+L(two):
+ C r3 return value
+ C r4
+ C r5 &dst[size-2]
+ C r6 shift
+ C r7 32-shift
+ C r8 src[size-2] >> shift
+ C r9 src[size-1]
+ C r10
+
+ slw r11, r9, r7
+ srw r12, r9, r6 C src[size-1] >> shift
+
+ or r8, r8, r11
+ stw r12, 8(r5) C dst[size-1]
+
+ stw r8, 4(r5) C dst[size-2]
+ blr
+
+
+L(odd):
+ C r3 return value
+ C r4
+ C r5 &dst[size-2]
+ C r6 shift
+ C r7 32-shift
+ C r8 src[size-2] >> shift
+ C r9
+ C r10 src[size-1]
+
+ slw r11, r10, r7
+ srw r12, r10, r6
+
+ or r8, r8, r11
+ stw r12, 8(r5) C dst[size-1]
+
+ stw r8, 4(r5) C dst[size-2]
+ blr
+
+
+L(one):
+ C r3 return value
+ C r4
+ C r5 dst-4
+ C r6 shift
+ C r7
+ C r8 src[0]
+
+ srw r8, r8, r6
+
+ stw r8, 4(r5) C dst[0]
+ blr
+
+EPILOGUE(mpn_rshift)
diff --git a/gmp/mpn/powerpc32/README b/gmp/mpn/powerpc32/README
new file mode 100644
index 0000000000..887e78b290
--- /dev/null
+++ b/gmp/mpn/powerpc32/README
@@ -0,0 +1,180 @@
+Copyright 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ POWERPC 32-BIT MPN SUBROUTINES
+
+
+This directory contains mpn functions for various 32-bit PowerPC chips.
+
+
+CODE ORGANIZATION
+
+ directory used for
+ ================================================
+ powerpc generic, 604, 604e, 744x, 745x
+ powerpc/750 740, 750, 7400, 7410
+
+
+The top-level powerpc directory is currently mostly aimed at 604/604e but
+should be reasonable on all powerpcs.
+
+
+
+STATUS
+
+The code is quite well optimized for the 604e, other chips have had less
+attention.
+
+Altivec SIMD available in 74xx might hold some promise, but unfortunately
+GMP only guarantees 32-bit data alignment, so there's lots of fiddling
+around with partial operations at the start and end of limb vectors. A
+128-bit limb would be a novel idea, but is unlikely to be practical, since
+it would have to work with ordinary +, -, * etc in the C code.
+
+Also, Altivec isn't very well suited for the GMP multiplication needs.
+Using floating-point based multiplication has much better better performance
+potential for all current powerpcs, both the ones with slow integer multiply
+units (603, 740, 750, 7400, 7410) and those with fast (604, 604e, 744x,
+745x). This is because all powerpcs do some level of pipelining in the FPU:
+
+603 and 750 can sustain one fmadd every 2nd cycle.
+604 and 604e can sustain one fmadd per cycle.
+7400 and 7410 can sustain 3 fmadd in 4 cycles.
+744x and 745x can sustain 4 fmadd in 5 cycles.
+
+
+
+REGISTER NAMES
+
+The normal powerpc convention is to give registers as plain numbers, like
+"mtctr 6", but on Apple MacOS X (powerpc*-*-rhapsody* and
+powerpc*-*-darwin*) the assembler demands an "r" like "mtctr r6". Note
+however when register 0 in an instruction means a literal zero the "r" is
+omitted, for instance "lwzx r6,0,r7".
+
+The GMP code uses the "r" forms, powerpc-defs.m4 transforms them to plain
+numbers according to what GMP_ASM_POWERPC_R_REGISTERS finds is needed.
+(Note that this style isn't fully general, as the identifier r4 and the
+register r4 will not be distinguishable on some systems. However, this is
+not a problem for the limited GMP assembly usage.)
+
+
+
+GLOBAL REFERENCES
+
+Linux non-PIC
+ lis 9, __gmp_binvert_limb_table@ha
+ rlwinm 11, 5, 31, 25, 31
+ la 9, __gmp_binvert_limb_table@l(9)
+ lbzx 11, 9, 11
+
+Linux PIC (FIXME)
+.LCL0:
+ .long .LCTOC1-.LCF0
+ bcl 20, 31, .LCF0
+.LCF0:
+ mflr 30
+ lwz 7, .LCL0-.LCF0(30)
+ add 30, 7, 30
+ lwz 11, .LC0-.LCTOC1(30)
+ rlwinm 3, 5, 31, 25, 31
+ lbzx 7, 11, 3
+
+AIX (always PIC)
+LC..0:
+ .tc __gmp_binvert_limb_table[TC],__gmp_binvert_limb_table[RW]
+ lwz 9, LC..0(2)
+ rlwinm 0, 5, 31, 25, 31
+ lbzx 0, 9, 0
+
+Darwin (non-PIC)
+ lis r2, ha16(___gmp_binvert_limb_table)
+ rlwinm r9, r5, 31, 25, 31
+ la r2, lo16(___gmp_binvert_limb_table)(r2)
+ lbzx r0, r2, r9
+Darwin (PIC)
+ mflr r0
+ bcl 20, 31, L0001$pb
+L0001$pb:
+ mflr r7
+ mtlr r0
+ addis r2, r7, ha16(L___gmp_binvert_limb_table$non_lazy_ptr-L0001$pb)
+ rlwinm r9, r5, 31, 25, 31
+ lwz r2, lo16(L___gmp_binvert_limb_table$non_lazy_ptr-L0001$pb)(r2)
+ lbzx r0, r2, r9
+------
+ .non_lazy_symbol_pointer
+L___gmp_binvert_limb_table$non_lazy_ptr:
+ .indirect_symbol ___gmp_binvert_limb_table
+ .long 0
+ .subsections_via_symbols
+
+
+For GNU/Linux and Darwin, we might want to duplicate __gmp_binvert_limb_table
+into the text section in this file. We should thus be able to reach it like
+this:
+
+ blr L0
+L0: mflr r2
+ rlwinm r9, r5, 31, 25, 31
+ addi r9, r9, lo16(local_binvert_table-L0)
+ lbzx r0, r2, r9
+
+
+
+REFERENCES
+
+PowerPC Microprocessor Family: The Programming Environments for 32-bit
+Microprocessors, IBM document G522-0290-01, 2000.
+
+PowerPC 604e RISC Microprocessor User's Manual with Supplement for PowerPC
+604 Microprocessor, IBM document G552-0330-00, Freescale document
+MPC604EUM/AD, 3/1998.
+
+MPC7410/MPC7400 RISC Microprocessor User's Manual, Freescale document
+MPC7400UM/D, rev 1, 11/2002.
+
+MPC7450 RISC Microprocessor Family Reference Manual, Freescale document
+MPC7450UM, rev 5, 1/2005.
+
+The above are available online from
+
+ http://www.ibm.com/chips/techlib/techlib.nsf/productfamilies/PowerPC
+ http://www.freescale.com/PowerPC
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/powerpc32/addlsh1_n.asm b/gmp/mpn/powerpc32/addlsh1_n.asm
new file mode 100644
index 0000000000..71645c3ec3
--- /dev/null
+++ b/gmp/mpn/powerpc32/addlsh1_n.asm
@@ -0,0 +1,100 @@
+dnl PowerPC-32 mpn_addlsh1_n -- rp[] = up[] + (vp[] << 1)
+
+dnl Copyright 2003, 2005, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: 4.0
+C 75x (G3): 5.0
+C 7400,7410 (G4): 5.0
+C 744x,745x (G4+): 5.0
+C power4/ppc970: 4.25
+C power5: 5.0
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C vp r5
+C n r6
+
+define(`rp',`r3')
+define(`up',`r4')
+define(`vp',`r5')
+
+define(`s0',`r6')
+define(`s1',`r7')
+define(`u0',`r8')
+define(`v0',`r10')
+define(`v1',`r11')
+
+ASM_START()
+PROLOGUE(mpn_addlsh1_n)
+ mtctr r6 C copy n in ctr
+ addic r31, r31, 0 C clear cy
+
+ lwz v0, 0(vp) C load v limb
+ lwz u0, 0(up) C load u limb
+ addi up, up, -4 C update up
+ addi rp, rp, -4 C update rp
+ slwi s1, v0, 1
+ bdz L(end) C If done, skip loop
+
+L(loop):
+ lwz v1, 4(vp) C load v limb
+ adde s1, s1, u0 C add limbs with cy, set cy
+ srwi s0, v0, 31 C shift down previous v limb
+ stw s1, 4(rp) C store result limb
+ lwzu u0, 8(up) C load u limb and update up
+ rlwimi s0, v1, 1, 0,30 C left shift v limb and merge with prev v limb
+
+ bdz L(exit) C decrement ctr and exit if done
+
+ lwzu v0, 8(vp) C load v limb and update vp
+ adde s0, s0, u0 C add limbs with cy, set cy
+ srwi s1, v1, 31 C shift down previous v limb
+ stwu s0, 8(rp) C store result limb and update rp
+ lwz u0, 4(up) C load u limb
+ rlwimi s1, v0, 1, 0,30 C left shift v limb and merge with prev v limb
+
+ bdnz L(loop) C decrement ctr and loop back
+
+L(end): adde r7, s1, u0
+ srwi r4, v0, 31
+ stw r7, 4(rp) C store last result limb
+ addze r3, r4
+ blr
+L(exit):
+ adde r7, s0, u0
+ srwi r4, v1, 31
+ stw r7, 8(rp) C store last result limb
+ addze r3, r4
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/addmul_1.asm b/gmp/mpn/powerpc32/addmul_1.asm
new file mode 100644
index 0000000000..7f47ab2ce7
--- /dev/null
+++ b/gmp/mpn/powerpc32/addmul_1.asm
@@ -0,0 +1,155 @@
+dnl PowerPC-32 mpn_addmul_1 -- Multiply a limb vector with a limb and add the
+dnl result to a second limb vector.
+
+dnl Copyright 1995, 1997, 1998, 2000-2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: 6.75
+C 75x (G3): 8.7-14.3
+C 7400,7410 (G4): 8.7-14.3
+C 744x,745x (G4+): 9.5
+C power4/ppc970: 6.25
+C power5: 6.25
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+C vl r6
+
+C This is optimized for the PPC604. It has not been tuned for other
+C PowerPC processors.
+C
+C Loop Analysis for the 604:
+C 12 mem insn
+C 8 serializing insn
+C 8 int multiply
+C 25 int reg write
+C 9 int ops (8 of which serialize)
+C
+C The multiply insns need 16 cycles/4limb.
+C The integer register writes will need 13 cycles/4limb.
+C All-in-all, it should be possible to get to 4 or 5 cycles/limb on PPC604,
+C but that will require some clever FPNOPS and BNOPS for exact
+C issue control.
+
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ cmpwi cr0,r5,9 C more than 9 limbs?
+ bgt cr0,L(big) C branch if more than 9 limbs
+
+ mtctr r5
+ lwz r0,0(r4)
+ mullw r7,r0,r6
+ mulhwu r10,r0,r6
+ lwz r9,0(r3)
+ addc r8,r7,r9
+ addi r3,r3,-4
+ bdz L(end)
+L(loop):
+ lwzu r0,4(r4)
+ stwu r8,4(r3)
+ mullw r8,r0,r6
+ adde r7,r8,r10
+ mulhwu r10,r0,r6
+ lwz r9,4(r3)
+ addze r10,r10
+ addc r8,r7,r9
+ bdnz L(loop)
+L(end): stw r8,4(r3)
+ addze r3,r10
+ blr
+
+L(big): stmw r30,-32(r1)
+ addi r5,r5,-1
+ srwi r0,r5,2
+ mtctr r0
+
+ lwz r7,0(r4)
+ mullw r8,r7,r6
+ mulhwu r0,r7,r6
+ lwz r7,0(r3)
+ addc r8,r8,r7
+ stw r8,0(r3)
+
+L(loopU):
+ lwz r7,4(r4)
+ lwz r12,8(r4)
+ lwz r30,12(r4)
+ lwzu r31,16(r4)
+ mullw r8,r7,r6
+ mullw r9,r12,r6
+ mullw r10,r30,r6
+ mullw r11,r31,r6
+ adde r8,r8,r0 C add cy_limb
+ mulhwu r0,r7,r6
+ lwz r7,4(r3)
+ adde r9,r9,r0
+ mulhwu r0,r12,r6
+ lwz r12,8(r3)
+ adde r10,r10,r0
+ mulhwu r0,r30,r6
+ lwz r30,12(r3)
+ adde r11,r11,r0
+ mulhwu r0,r31,r6
+ lwz r31,16(r3)
+ addze r0,r0 C new cy_limb
+ addc r8,r8,r7
+ stw r8,4(r3)
+ adde r9,r9,r12
+ stw r9,8(r3)
+ adde r10,r10,r30
+ stw r10,12(r3)
+ adde r11,r11,r31
+ stwu r11,16(r3)
+ bdnz L(loopU)
+
+ andi. r31,r5,3
+ mtctr r31
+ beq cr0,L(endx)
+
+L(loopE):
+ lwzu r7,4(r4)
+ mullw r8,r7,r6
+ adde r8,r8,r0 C add cy_limb
+ mulhwu r0,r7,r6
+ lwz r7,4(r3)
+ addze r0,r0 C new cy_limb
+ addc r8,r8,r7
+ stwu r8,4(r3)
+ bdnz L(loopE)
+L(endx):
+ addze r3,r0
+ lmw r30,-32(r1)
+ blr
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/powerpc32/aix.m4 b/gmp/mpn/powerpc32/aix.m4
new file mode 100644
index 0000000000..fde20200b2
--- /dev/null
+++ b/gmp/mpn/powerpc32/aix.m4
@@ -0,0 +1,82 @@
+divert(-1)
+dnl m4 macros for AIX 32-bit assembly.
+
+dnl Copyright 2000-2002, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`ASM_START',
+` .toc')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+dnl Don't want ELF style .size in the epilogue.
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+ `
+ .globl $1
+ .globl .$1
+ .csect [DS], 2
+$1:
+ .long .$1, TOC[tc0], 0
+ .csect [PR]
+ .align 2
+.$1:')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+`')
+
+define(`TOC_ENTRY', `')
+
+define(`LEA',
+m4_assert_numargs(2)
+`define(`TOC_ENTRY',
+` .toc
+tc$2:
+ .tc $2[TC], $2')'
+` lwz $1, tc$2(2)')
+
+define(`EXTERN',
+m4_assert_numargs(1)
+` .globl $1')
+
+define(`DEF_OBJECT',
+m4_assert_numargs_range(1,2)
+` .csect [RO], 3
+ ALIGN(ifelse($#,1,2,$2))
+$1:
+')
+
+define(`END_OBJECT',
+m4_assert_numargs(1))
+
+define(`ASM_END', `TOC_ENTRY')
+
+divert
diff --git a/gmp/mpn/powerpc32/aors_n.asm b/gmp/mpn/powerpc32/aors_n.asm
new file mode 100644
index 0000000000..25ece0966e
--- /dev/null
+++ b/gmp/mpn/powerpc32/aors_n.asm
@@ -0,0 +1,157 @@
+dnl PowerPC-32 mpn_add_n and mpn_sub_n.
+
+dnl Copyright 2002, 2005, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: ? old: 3.25
+C 75x (G3): ? old: 3.5
+C 7400,7410 (G4): 3.25
+C 744x,745x (G4+): 4
+C POWER3/PPC630 2
+C POWER4/PPC970 2.4
+C POWER5 2.75
+C POWER6 40-140
+C POWER7 3
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`vp', `r5')
+define(`n', `r6')
+define(`cy', `r7')
+
+ifdef(`OPERATION_add_n', `
+ define(ADCSBC, adde)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)
+ define(IFADD, `$1')
+ define(IFSUB, `')')
+ifdef(`OPERATION_sub_n', `
+ define(ADCSBC, subfe)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)
+ define(IFADD, `')
+ define(IFSUB, `$1')')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+
+PROLOGUE(func_nc)
+IFADD(` addic r0, cy, -1') C set carry from argument
+IFSUB(` subfic r0, cy, 0') C set carry from argument
+ b L(ent)
+EPILOGUE()
+
+PROLOGUE(func)
+IFADD(` addic r0, n, 0') C clear carry
+IFSUB(` addic r0, n, -1') C set carry
+L(ent): andi. r0, n, 3
+ addi r3, r3, -12
+ addi n, n, 1
+ cmpwi cr7, r0, 2
+ srwi r0, n, 2
+ sub r4, r4, r3
+ sub r5, r5, r3
+ mtctr r0
+ bne cr0, L(n00)
+
+ lwzx r7, r4, r3 C n = 4, 8, 12, ...
+ lwzx r8, r5, r3
+ addi r3, r3, 4
+ lwzx r9, r4, r3
+ ADCSBC r7, r8, r7
+ lwzx r10, r5, r3
+ addi r3, r3, 4
+ b L(00)
+
+L(n00): bge cr7, L(n01)
+ cmpwi cr0, r0, 0 C n = 1, 5, 9, 13, ...
+ lwzx r0, r4, r3
+ lwzx r6, r5, r3
+ addi r3, r3, 4
+ ADCSBC r0, r6, r0
+ ble L(ret)
+L(gt1): lwzx r7, r4, r3
+ lwzx r8, r5, r3
+ addi r3, r3, 4
+ b L(01)
+
+L(n10):
+ lwzx r9, r4, r3 C n = 3, 7, 11, 15, ...
+ lwzx r10, r5, r3
+ addi r3, r3, 4
+ lwzx r11, r4, r3
+ ADCSBC r9, r10, r9
+ lwzx r12, r5, r3
+ addi r3, r3, 4
+ b L(11)
+
+L(n01): bne cr7, L(n10)
+ cmpwi cr0, r0, 0 C n = 2, 6, 10, 14, ...
+ lwzx r11, r4, r3
+ lwzx r12, r5, r3
+ addi r3, r3, 4
+ lwzx r0, r4, r3
+ ADCSBC r11, r12, r11
+ lwzx r6, r5, r3
+ addi r3, r3, 4
+ ble cr0, L(end)
+
+
+L(lp): lwzx r7, r4, r3
+ ADCSBC r0, r6, r0
+ lwzx r8, r5, r3
+ stwu r11, 4(r3)
+L(01): lwzx r9, r4, r3
+ ADCSBC r7, r8, r7
+ lwzx r10, r5, r3
+ stwu r0, 4(r3)
+L(00): lwzx r11, r4, r3
+ ADCSBC r9, r10, r9
+ lwzx r12, r5, r3
+ stwu r7, 4(r3)
+L(11): lwzx r0, r4, r3
+ ADCSBC r11, r12, r11
+ lwzx r6, r5, r3
+ stwu r9, 4(r3)
+ bdnz L(lp)
+
+L(end): ADCSBC r0, r6, r0
+ stw r11, 4(r3)
+L(ret): stw r0, 8(r3)
+IFADD(` li r3, 0 ')
+IFADD(` addze r3, r3 ')
+IFSUB(` subfe r3, r0, r0')
+IFSUB(` neg r3, r3')
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/bdiv_dbm1c.asm b/gmp/mpn/powerpc32/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..72b2c482e4
--- /dev/null
+++ b/gmp/mpn/powerpc32/bdiv_dbm1c.asm
@@ -0,0 +1,131 @@
+dnl PPC32 mpn_bdiv_dbm1c.
+
+dnl Copyright 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: ?
+C 75x (G3): ?
+C 7400,7410 (G4): 9.43
+C 744x,745x (G4+): 6.28
+C power4/ppc970: ?
+C power5: ?
+
+C TODO
+C * Nothing to do...
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`bd', `r6')
+define(`cy', `r7')
+
+ASM_START()
+PROLOGUE(mpn_bdiv_dbm1c)
+ lwz r0, 0(r4)
+
+ rlwinm. r12, r5, 0,30,31
+ cmplwi cr6, r12, 2
+ cmplwi cr7, r5, 4
+ addi r5, r5, 1
+ srwi r5, r5, 2
+ mtctr r5
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ beq cr6, L(b10)
+
+L(b11): mullw r5, r0, r6
+ mulhwu r12, r0, r6
+ lwz r0, 4(r4)
+ addi r4, r4, -12
+ addi r3, r3, -12
+ b L(3)
+
+L(b00): mullw r9, r0, r6
+ mulhwu r8, r0, r6
+ lwz r0, 4(r4)
+ addi r4, r4, -8
+ addi r3, r3, -8
+ b L(0)
+
+L(b01): mullw r5, r0, r6
+ mulhwu r12, r0, r6
+ addi r3, r3, -4
+ ble cr7, L(e1)
+ lwz r0, 4(r4)
+ addi r4, r4, -4
+ b L(1)
+
+L(b10): mullw r9, r0, r6
+ mulhwu r8, r0, r6
+ lwz r0, 4(r4)
+ ble cr7, L(e2)
+
+ ALIGN(16)
+L(top): mullw r5, r0, r6
+ mulhwu r12, r0, r6
+ subfc r11, r9, r7
+ lwz r0, 8(r4)
+ subfe r7, r8, r11
+ stw r11, 0(r3)
+L(1): mullw r9, r0, r6
+ mulhwu r8, r0, r6
+ subfc r11, r5, r7
+ lwz r0, 12(r4)
+ subfe r7, r12, r11
+ stw r11, 4(r3)
+L(0): mullw r5, r0, r6
+ mulhwu r12, r0, r6
+ subfc r11, r9, r7
+ lwz r0, 16(r4)
+ subfe r7, r8, r11
+ stw r11, 8(r3)
+L(3): mullw r9, r0, r6
+ mulhwu r8, r0, r6
+ subfc r11, r5, r7
+ lwz r0, 20(r4)
+ subfe r7, r12, r11
+ stw r11, 12(r3)
+ addi r4, r4, 16
+ addi r3, r3, 16
+ bdnz L(top)
+
+L(e2): mullw r5, r0, r6
+ mulhwu r12, r0, r6
+ subfc r11, r9, r7
+ subfe r7, r8, r11
+ stw r11, 0(r3)
+L(e1): subfc r11, r5, r7
+ stw r11, 4(r3)
+ subfe r3, r12, r11
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/darwin.m4 b/gmp/mpn/powerpc32/darwin.m4
new file mode 100644
index 0000000000..db4226800b
--- /dev/null
+++ b/gmp/mpn/powerpc32/darwin.m4
@@ -0,0 +1,91 @@
+divert(-1)
+dnl m4 macros for Mac OS 32-bit assembly.
+
+dnl Copyright 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`ASM_START',`')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo[,toc])
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs_range(1,2)
+`ifelse(`$2',toc,,
+`ifelse(`$2',,,`m4_error(`Unrecognised PROLOGUE parameter')')')dnl
+ .text
+ .globl $1
+ .align 3
+$1:')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1))
+
+
+dnl LEA -- Load Effective Address.
+
+define(`LEA',
+m4_assert_numargs(2)
+`ifdef(`PIC',
+` mflr r0 C save return address
+ bcl 20, 31, 1f
+1: mflr $1
+ addis $1, $1, ha16($2-1b)
+ la $1, lo16($2-1b)($1)
+ mtlr r0 C restore return address
+',`
+ lis $1, ha16($2)
+ la $1, lo16($2)($1)
+')')
+
+define(`LEAL',
+m4_assert_numargs(2)
+`LEA($1,$2)')
+
+
+define(`EXTERN',
+m4_assert_numargs(1)
+`dnl')
+
+define(`DEF_OBJECT',
+m4_assert_numargs_range(1,2)
+` .const
+ ALIGN(ifelse($#,1,2,$2))
+$1:
+')
+
+define(`END_OBJECT',
+m4_assert_numargs(1))
+
+define(`ASM_END', `dnl')
+
+ifdef(`PIC',`
+define(`PIC_SLOW')')
+
+divert
diff --git a/gmp/mpn/powerpc32/diveby3.asm b/gmp/mpn/powerpc32/diveby3.asm
new file mode 100644
index 0000000000..288a7d30ac
--- /dev/null
+++ b/gmp/mpn/powerpc32/diveby3.asm
@@ -0,0 +1,93 @@
+dnl PowerPC-32 mpn_divexact_by3 -- mpn by 3 exact division
+
+dnl Copyright 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: 5
+C 75x (G3): ?
+C 7400,7410 (G4): 8
+C 744x,745x (G4+): 6
+C power4/ppc970: 12
+C power5: ?
+
+C void mpn_divexact_by3 (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C We avoid the slow subfe instruction and instead rely on an extremely unlikely
+C branch.
+C
+C The mullw has the inverse in the first operand, since 0xAA..AB won't allow
+C any early-out. The src[] data normally won't either, but there's at least
+C a chance, whereas 0xAA..AB never will. If, for instance, src[] is all
+C zeros (not a sensible input of course) we run at 7.0 c/l on ppc750.
+C
+C The mulhwu has the "3" multiplier in the second operand, which lets 750 and
+C 7400 use an early-out.
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`cy', `r6')
+
+ASM_START()
+PROLOGUE(mpn_divexact_by3c)
+ lwz r11, 0(up)
+ mtctr n
+ lis r12, 0xAAAA
+ ori r12, r12, 0xAAAB
+ li r10, 3
+
+ cmplw cr7, cy, r11
+ subf r11, cy, r11
+
+ mullw r0, r11, r12
+ stw r0, 0(rp)
+ bdz L(one)
+
+L(top): lwzu r9, 4(up)
+ mulhwu r7, r0, r10
+ bgt- cr7, L(adj) C very unlikely branch
+L(bko): cmplw cr7, r7, r9
+ subf r0, r7, r9
+ mullw r0, r12, r0
+ stwu r0, 4(rp)
+ bdnz L(top)
+
+L(one): mulhwu r3, r0, r10
+ blelr+ cr7
+ addi r3, r3, 1
+ blr
+
+L(adj): addi r7, r7, 1
+ b L(bko)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/powerpc32/divrem_2.asm b/gmp/mpn/powerpc32/divrem_2.asm
new file mode 100644
index 0000000000..c6e64efe23
--- /dev/null
+++ b/gmp/mpn/powerpc32/divrem_2.asm
@@ -0,0 +1,182 @@
+dnl PPC-32 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number.
+
+dnl Copyright 2007, 2008, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C norm frac
+C 7410 ~36.5 ~36.5
+C 744x, 745x 29 29
+
+C INPUT PARAMETERS
+C qp = r3
+C fn = r4
+C up = r5
+C un = r6
+C d = r7
+
+C TODO
+C * Decrease register usage.
+C * Make sure mul operands and optimal for early-out.
+C * Check that things work well for a shared library build.
+C * Write an invert_limb, perhaps inline, perhaps as a private call. Or at
+C least vastly improve the current __udiv_qrnnd_c based code.
+
+
+ASM_START()
+PROLOGUE(mpn_divrem_2)
+ stwu r1, -32(r1)
+ slwi r0, r6, 2
+ add r5, r5, r0
+ stmw r28, 8(r1)
+ addi r29, r5, -8 C up = up_param + un - 2
+ lwz r10, 4(r7)
+ lwz r12, 4(r29)
+ addi r8, r3, -12
+ lwz r7, 0(r7)
+ cmplw cr7, r12, r10
+ lwz r28, 0(r29)
+ blt- cr7, L(2)
+ bgt+ cr7, L(4)
+ cmplw cr7, r28, r7
+ blt- cr7, L(2)
+L(4): subfc r28, r7, r28
+ subfe r12, r10, r12
+ li r3, 1
+ b L(6)
+L(2): li r3, 0
+
+L(6): add r0, r4, r6
+ addic. r30, r0, -2
+ ble- cr0, L(ret)
+
+ slwi r9, r0, 2
+ add r8, r8, r9 C rp += un + fn
+ mtctr r30
+
+C Compute di from d1
+ srwi r11, r10, 16
+ nor r0, r10, r10
+ divwu r31, r0, r11
+ rlwinm r5, r10, 0, 16, 31
+ mullw r9, r11, r31
+ mullw r6, r5, r31
+ subf r0, r9, r0
+ slwi r0, r0, 16
+ ori r0, r0, 65535
+ cmplw cr7, r0, r6
+ bge- cr7, L(9)
+ add r0, r0, r10
+ cmplw cr7, r0, r10
+ cmplw cr6, r6, r0
+ addi r31, r31, -1 C q1--
+ crorc 28, 28, 25
+ bc+ 12, 28, L(9)
+ addi r31, r31, -1 C q1--
+ add r0, r0, r10
+L(9): subf r0, r6, r0
+ divwu r6, r0, r11
+ mullw r9, r11, r6
+ mullw r11, r5, r6
+ subf r0, r9, r0
+ slwi r0, r0, 16
+ ori r0, r0, 65535
+ cmplw cr7, r0, r11
+ bge- cr7, L(13)
+ add r0, r0, r10
+ cmplw cr7, r0, r10
+ cmplw cr6, r11, r0
+ addi r6, r6, -1 C q0--
+ crorc 28, 28, 25
+ bc+ 12, 28, L(13)
+C add r0, r0, r10 C final remainder
+ addi r6, r6, -1 C q0--
+L(13): rlwimi r6, r31, 16, 0, 15 C assemble final quotient
+
+C Adjust di by including d0
+ mullw r9, r10, r6 C t0 = LO(di * d1)
+ addc r11, r9, r7
+ subfe r0, r1, r1
+ mulhwu r9, r6, r7 C s1 = HI(di * d0)
+ addc r9, r11, r9
+ addze. r0, r0
+ blt cr0, L(17)
+L(18): subfc r9, r10, r9
+ addi r6, r6, -1
+ addme. r0, r0
+ bge+ cr0, L(18)
+L(17):
+
+C r0 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r28 r29 r30 r31
+C msl di d0 qp d1 fn up un
+L(loop):
+ mullw r0, r12, r6 C q0 = LO(n2 * di)
+ cmpw cr7, r30, r4
+ addc r31, r0, r28 C q0 += n1
+ mulhwu r9, r12, r6 C q = HI(n2 * di)
+ adde r12, r9, r12 C q += n2
+ addi r30, r30, -1
+ mullw r0, r10, r12 C d1 * q
+ li r9, 0
+ subf r0, r0, r28 C n1 -= d1 * q
+ addi r5, r12, 1
+ ble- cr7, L(23)
+ lwzu r9, -4(r29)
+L(23): mullw r11, r12, r7 C t0 = LO(d0 * q)
+ subfc r28, r7, r9 C n0 -= d0
+ subfe r0, r10, r0 C n1 -= d1
+ mulhwu r12, r12, r7 C t1 = HI(d0 * q)
+ subfc r28, r11, r28 C n0 -= t0
+ subfe r12, r12, r0 C n1 -= t1
+ cmplw cr7, r12, r31
+ blt+ cr7, L(24)
+ addc r28, r28, r7
+ adde r12, r12, r10
+ addi r5, r5, -1
+L(24): cmplw cr7, r12, r10
+ bge- cr7, L(fix)
+L(bck): stw r5, 0(r8)
+ addi r8, r8, -4
+ bdnz L(loop)
+
+L(ret): stw r28, 0(r29)
+ stw r12, 4(r29)
+ lmw r28, 8(r1)
+ addi r1, r1, 32
+ blr
+
+L(fix): cmplw cr6, r28, r7
+ bgt+ cr7, L(28)
+ blt- cr6, L(bck)
+L(28): subfc r28, r7, r28
+ subfe r12, r10, r12
+ addi r5, r5, 1
+ b L(bck)
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/eabi.m4 b/gmp/mpn/powerpc32/eabi.m4
new file mode 100644
index 0000000000..cd7633c633
--- /dev/null
+++ b/gmp/mpn/powerpc32/eabi.m4
@@ -0,0 +1,86 @@
+divert(-1)
+dnl m4 macros for powerpc32 eABI assembly.
+
+dnl Copyright 2003, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`ASM_START',`')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+ `
+ .section ".text"
+ .align 3
+ .globl $1
+ .type $1, @function
+$1:')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+` .size $1, .-$1')
+
+dnl This ought to support PIC, but it is unclear how that is done for eABI
+define(`LEA',
+m4_assert_numargs(2)
+`
+ lis $1, $2@ha
+ la $1, $2@l($1)
+')
+
+define(`EXTERN',
+m4_assert_numargs(1)
+`dnl')
+
+define(`DEF_OBJECT',
+m4_assert_numargs_range(1,2)
+`
+ .section .rodata
+ ALIGN(ifelse($#,1,2,$2))
+ .type $1, @object
+$1:
+')
+
+define(`END_OBJECT',
+m4_assert_numargs(1)
+` .size $1, .-$1')
+
+define(`ASM_END', `dnl')
+
+ifdef(`PIC',`
+define(`PIC_SLOW')')
+
+dnl 64-bit "long long" parameters are put in an even-odd pair, skipping an
+dnl even register if that was in turn. I wish somebody could explain why that
+dnl is a good idea.
+define(`BROKEN_LONGLONG_PARAM')
+
+divert
diff --git a/gmp/mpn/powerpc32/elf.m4 b/gmp/mpn/powerpc32/elf.m4
new file mode 100644
index 0000000000..a64a1271ff
--- /dev/null
+++ b/gmp/mpn/powerpc32/elf.m4
@@ -0,0 +1,97 @@
+divert(-1)
+dnl m4 macros for powerpc32 GNU/Linux assembly.
+
+dnl Copyright 2003, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`ASM_START',`')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo[,toc])
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs_range(1,2)
+`ifelse(`$2',toc,,
+`ifelse(`$2',,,`m4_error(`Unrecognised PROLOGUE parameter')')')dnl
+ .section ".text"
+ .align 3
+ .globl $1
+ .type $1, @function
+$1:')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+` .size $1, .-$1')
+
+define(`LEA',
+m4_assert_numargs(2)
+`ifdef(`PIC',`
+ mflr r0
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr $1
+ mtlr r0
+ lwz $1, $2@got($1)
+',`
+ lis $1, $2@ha
+ la $1, $2@l($1)
+')')
+
+define(`LEAL',
+m4_assert_numargs(2)
+`LEA($1,$2)')
+
+
+define(`EXTERN',
+m4_assert_numargs(1)
+`dnl')
+
+define(`DEF_OBJECT',
+m4_assert_numargs_range(1,2)
+`
+ .section .rodata
+ ALIGN(ifelse($#,1,2,$2))
+ .type $1, @object
+$1:
+')
+
+define(`END_OBJECT',
+m4_assert_numargs(1)
+` .size $1, .-$1')
+
+define(`ASM_END', `dnl')
+
+ifdef(`PIC',`
+define(`PIC_SLOW')')
+
+dnl 64-bit "long long" parameters are put in an even-odd pair, skipping an
+dnl even register if that was in turn. I wish somebody could explain why that
+dnl is a good idea.
+define(`BROKEN_LONGLONG_PARAM')
+
+divert
diff --git a/gmp/mpn/powerpc32/gmp-mparam.h b/gmp/mpn/powerpc32/gmp-mparam.h
new file mode 100644
index 0000000000..784a6d7b74
--- /dev/null
+++ b/gmp/mpn/powerpc32/gmp-mparam.h
@@ -0,0 +1,217 @@
+/* PowerPC-32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004, 2008-2010, 2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* This file is supposed to be used for 604, 604e, 744x/745x/747x (G4+), i.e.,
+ 32-bit PowerPC processors with reasonably fast integer multiply insns. The
+ values below are chosen to be best for the latter processors, since 604 is
+ largely irrelevant today.
+
+ In mpn/powerpc32/750/gmp-mparam.h there are values for 75x (G3) and for
+ 7400/7410 (G4), both which have much slower multiply instructions. */
+
+/* 1417 MHz PPC 7447A */
+/* FFT tuning limit = 12500000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.6 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 1
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 8
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 8
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 49
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 18
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 2
+#define DIV_QR_1_UNNORM_THRESHOLD 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 69
+
+#define MUL_TOOM22_THRESHOLD 14
+#define MUL_TOOM33_THRESHOLD 73
+#define MUL_TOOM44_THRESHOLD 106
+#define MUL_TOOM6H_THRESHOLD 156
+#define MUL_TOOM8H_THRESHOLD 236
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 71
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 73
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 72
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 82
+
+#define SQR_BASECASE_THRESHOLD 0 /* always */
+#define SQR_TOOM2_THRESHOLD 22
+#define SQR_TOOM3_THRESHOLD 74
+#define SQR_TOOM4_THRESHOLD 130
+#define SQR_TOOM6_THRESHOLD 189
+#define SQR_TOOM8_THRESHOLD 284
+
+#define MULMID_TOOM42_THRESHOLD 32
+
+#define MULMOD_BNM1_THRESHOLD 9
+#define SQRMOD_BNM1_THRESHOLD 14
+
+#define MUL_FFT_MODF_THRESHOLD 284 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 284, 5}, { 15, 6}, { 8, 5}, { 17, 6}, \
+ { 17, 7}, { 9, 6}, { 20, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 19, 8}, \
+ { 11, 7}, { 25, 9}, { 7, 8}, { 15, 7}, \
+ { 33, 8}, { 19, 7}, { 39, 8}, { 23, 7}, \
+ { 47, 8}, { 27, 9}, { 15, 8}, { 39, 9}, \
+ { 23, 8}, { 47,10}, { 15, 9}, { 31, 8}, \
+ { 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
+ { 95,10}, { 31, 9}, { 71, 8}, { 143, 9}, \
+ { 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
+ { 63, 9}, { 127, 8}, { 255, 9}, { 135, 8}, \
+ { 271, 9}, { 143,10}, { 79, 9}, { 159, 8}, \
+ { 319, 9}, { 175,10}, { 95, 9}, { 191, 8}, \
+ { 383, 9}, { 207, 8}, { 415,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511, 9}, { 271,10}, \
+ { 143, 9}, { 287, 8}, { 575,10}, { 159, 9}, \
+ { 319,10}, { 175,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207, 9}, { 415, 8}, { 831,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
+ { 271, 9}, { 543, 8}, { 1087,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 319, 9}, { 639,10}, \
+ { 351, 9}, { 703,11}, { 191,10}, { 415, 9}, \
+ { 831,11}, { 223,10}, { 447, 9}, { 895,10}, \
+ { 479, 9}, { 959,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 575,11}, \
+ { 319,10}, { 639,11}, { 351,10}, { 703, 9}, \
+ { 1407,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,10}, { 831,11}, { 447,10}, { 895,11}, \
+ { 479,10}, { 959,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,11}, { 607,12}, { 319,11}, \
+ { 639,10}, { 1279,11}, { 703,10}, { 1407,12}, \
+ { 383,11}, { 831,12}, { 447,11}, { 959,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1215,10}, { 2431,12}, { 639,11}, { 1279,12}, \
+ { 703,11}, { 1407,13}, { 383,12}, { 895,11}, \
+ { 1791,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1215,11}, { 2431,13}, { 639,12}, { 1471,13}, \
+ { 767,12}, { 1599,13}, { 895,12}, { 1919,14}, \
+ { 511,13}, { 1023,12}, { 2111,13}, { 1151,12}, \
+ { 2431,13}, { 1407,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 160
+#define MUL_FFT_THRESHOLD 3712
+
+#define SQR_FFT_MODF_THRESHOLD 248 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 248, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 17, 7}, { 9, 6}, { 20, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 19, 8}, \
+ { 11, 7}, { 25, 9}, { 7, 8}, { 15, 7}, \
+ { 33, 8}, { 19, 7}, { 39, 8}, { 27, 9}, \
+ { 15, 8}, { 39, 9}, { 23, 8}, { 47,10}, \
+ { 15, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95,10}, { 31, 9}, \
+ { 63, 8}, { 127, 9}, { 71, 8}, { 143, 9}, \
+ { 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
+ { 63, 9}, { 127, 8}, { 255, 7}, { 511, 9}, \
+ { 143,10}, { 79, 9}, { 159, 8}, { 319, 9}, \
+ { 175, 8}, { 351,10}, { 95, 9}, { 191, 8}, \
+ { 383, 9}, { 207, 8}, { 415, 7}, { 831,11}, \
+ { 63,10}, { 127, 9}, { 255, 8}, { 511,10}, \
+ { 143, 9}, { 287, 8}, { 575,10}, { 159, 9}, \
+ { 319,10}, { 175, 9}, { 351,11}, { 95,10}, \
+ { 191, 9}, { 383,10}, { 207, 9}, { 415, 8}, \
+ { 831,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 319, 9}, { 639,10}, \
+ { 351, 9}, { 703,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 415, 9}, { 831,11}, { 223,10}, \
+ { 447, 9}, { 895,12}, { 127,11}, { 255,10}, \
+ { 543,11}, { 287,10}, { 607,11}, { 319,10}, \
+ { 639,11}, { 351,10}, { 703, 9}, { 1407,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,10}, \
+ { 831,11}, { 447,10}, { 895,11}, { 479,13}, \
+ { 127,12}, { 255,11}, { 543,10}, { 1087,11}, \
+ { 607,12}, { 319,11}, { 639,10}, { 1279,11}, \
+ { 703,10}, { 1407,12}, { 383,11}, { 831,12}, \
+ { 447,11}, { 959,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
+ { 1279,12}, { 703,11}, { 1407,13}, { 383,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1215,13}, \
+ { 639,12}, { 1471,13}, { 767,12}, { 1599,13}, \
+ { 895,12}, { 1919,14}, { 511,13}, { 1023,12}, \
+ { 2111,13}, { 1151,12}, { 2431,13}, { 1407,14}, \
+ { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 154
+#define SQR_FFT_THRESHOLD 2688
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 45
+#define MULLO_MUL_N_THRESHOLD 6633
+
+#define DC_DIV_QR_THRESHOLD 44
+#define DC_DIVAPPR_Q_THRESHOLD 142
+#define DC_BDIV_QR_THRESHOLD 54
+#define DC_BDIV_Q_THRESHOLD 124
+
+#define INV_MULMOD_BNM1_THRESHOLD 43
+#define INV_NEWTON_THRESHOLD 179
+#define INV_APPR_THRESHOLD 157
+
+#define BINV_NEWTON_THRESHOLD 214
+#define REDC_1_TO_REDC_N_THRESHOLD 55
+
+#define MU_DIV_QR_THRESHOLD 998
+#define MU_DIVAPPR_Q_THRESHOLD 1078
+#define MUPI_DIV_QR_THRESHOLD 84
+#define MU_BDIV_QR_THRESHOLD 872
+#define MU_BDIV_Q_THRESHOLD 1078
+
+#define POWM_SEC_TABLE 1,19,102,428,1378
+
+#define MATRIX22_STRASSEN_THRESHOLD 12
+#define HGCD_THRESHOLD 120
+#define HGCD_APPR_THRESHOLD 166
+#define HGCD_REDUCE_THRESHOLD 1679
+#define GCD_DC_THRESHOLD 339
+#define GCDEXT_DC_THRESHOLD 273
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 27
+#define SET_STR_DC_THRESHOLD 781
+#define SET_STR_PRECOMPUTE_THRESHOLD 1505
+
+#define FAC_DSC_THRESHOLD 141
+#define FAC_ODD_THRESHOLD 29
diff --git a/gmp/mpn/powerpc32/invert_limb.asm b/gmp/mpn/powerpc32/invert_limb.asm
new file mode 100644
index 0000000000..612bfe523c
--- /dev/null
+++ b/gmp/mpn/powerpc32/invert_limb.asm
@@ -0,0 +1,142 @@
+dnl PowerPC-32 mpn_invert_limb -- Invert a normalized limb.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: ?
+C 75x (G3): ?
+C 7400,7410 (G4): ?
+C 744x,745x (G4+): 32
+C power4/ppc970: ?
+C power5: ?
+
+EXTERN(approx_tab)
+
+ASM_START()
+PROLOGUE(mpn_invert_limb)
+ rlwinm r6, r3, 11, 22, 30 C extract bits 30..22 to pos 2^1
+ srwi r10, r3, 11 C extract bits 31..11
+ LEA( r9, approx_tab) C N.B. clobbers r0 for ELF and Darwin
+ lhzx r9, r9, r6 C w2
+ addi r0, r10, 1
+ mullw r11, r9, r9
+ slwi r9, r9, 4
+ mulhwu r7, r11, r0
+ rlwinm r11, r3, 0, 31, 31 C extract bit 0
+ addi r0, r9, -1
+ srwi r9, r3, 1 C d >> 1
+ subf r0, r7, r0 C w1
+ add r9, r9, r11 C d31
+ mullw r9, r0, r9 C w1 * d31
+ srwi r10, r0, 1 C w1 >> 1
+ neg r11, r11
+ and r11, r10, r11
+ subf r11, r9, r11
+ mulhwu r9, r11, r0
+ slwi r0, r0, 15
+ srwi r9, r9, 1
+ add r0, r9, r0 C w0
+ mullw r10, r0, r3
+ mulhwu r9, r0, r3
+ addc r11, r10, r3
+ adde r3, r9, r3
+ subf r3, r3, r0
+ blr
+EPILOGUE()
+
+DEF_OBJECT(approx_tab)
+ .short 0x7fe1,0x7fa1,0x7f61,0x7f22,0x7ee3,0x7ea4,0x7e65,0x7e27
+ .short 0x7de9,0x7dab,0x7d6d,0x7d30,0x7cf3,0x7cb6,0x7c79,0x7c3d
+ .short 0x7c00,0x7bc4,0x7b89,0x7b4d,0x7b12,0x7ad7,0x7a9c,0x7a61
+ .short 0x7a27,0x79ec,0x79b2,0x7979,0x793f,0x7906,0x78cc,0x7894
+ .short 0x785b,0x7822,0x77ea,0x77b2,0x777a,0x7742,0x770b,0x76d3
+ .short 0x769c,0x7665,0x762f,0x75f8,0x75c2,0x758c,0x7556,0x7520
+ .short 0x74ea,0x74b5,0x7480,0x744b,0x7416,0x73e2,0x73ad,0x7379
+ .short 0x7345,0x7311,0x72dd,0x72aa,0x7277,0x7243,0x7210,0x71de
+ .short 0x71ab,0x7179,0x7146,0x7114,0x70e2,0x70b1,0x707f,0x704e
+ .short 0x701c,0x6feb,0x6fba,0x6f8a,0x6f59,0x6f29,0x6ef9,0x6ec8
+ .short 0x6e99,0x6e69,0x6e39,0x6e0a,0x6ddb,0x6dab,0x6d7d,0x6d4e
+ .short 0x6d1f,0x6cf1,0x6cc2,0x6c94,0x6c66,0x6c38,0x6c0a,0x6bdd
+ .short 0x6bb0,0x6b82,0x6b55,0x6b28,0x6afb,0x6acf,0x6aa2,0x6a76
+ .short 0x6a49,0x6a1d,0x69f1,0x69c6,0x699a,0x696e,0x6943,0x6918
+ .short 0x68ed,0x68c2,0x6897,0x686c,0x6842,0x6817,0x67ed,0x67c3
+ .short 0x6799,0x676f,0x6745,0x671b,0x66f2,0x66c8,0x669f,0x6676
+ .short 0x664d,0x6624,0x65fc,0x65d3,0x65aa,0x6582,0x655a,0x6532
+ .short 0x650a,0x64e2,0x64ba,0x6493,0x646b,0x6444,0x641c,0x63f5
+ .short 0x63ce,0x63a7,0x6381,0x635a,0x6333,0x630d,0x62e7,0x62c1
+ .short 0x629a,0x6275,0x624f,0x6229,0x6203,0x61de,0x61b8,0x6193
+ .short 0x616e,0x6149,0x6124,0x60ff,0x60da,0x60b6,0x6091,0x606d
+ .short 0x6049,0x6024,0x6000,0x5fdc,0x5fb8,0x5f95,0x5f71,0x5f4d
+ .short 0x5f2a,0x5f07,0x5ee3,0x5ec0,0x5e9d,0x5e7a,0x5e57,0x5e35
+ .short 0x5e12,0x5def,0x5dcd,0x5dab,0x5d88,0x5d66,0x5d44,0x5d22
+ .short 0x5d00,0x5cde,0x5cbd,0x5c9b,0x5c7a,0x5c58,0x5c37,0x5c16
+ .short 0x5bf5,0x5bd4,0x5bb3,0x5b92,0x5b71,0x5b51,0x5b30,0x5b10
+ .short 0x5aef,0x5acf,0x5aaf,0x5a8f,0x5a6f,0x5a4f,0x5a2f,0x5a0f
+ .short 0x59ef,0x59d0,0x59b0,0x5991,0x5972,0x5952,0x5933,0x5914
+ .short 0x58f5,0x58d6,0x58b7,0x5899,0x587a,0x585b,0x583d,0x581f
+ .short 0x5800,0x57e2,0x57c4,0x57a6,0x5788,0x576a,0x574c,0x572e
+ .short 0x5711,0x56f3,0x56d5,0x56b8,0x569b,0x567d,0x5660,0x5643
+ .short 0x5626,0x5609,0x55ec,0x55cf,0x55b2,0x5596,0x5579,0x555d
+ .short 0x5540,0x5524,0x5507,0x54eb,0x54cf,0x54b3,0x5497,0x547b
+ .short 0x545f,0x5443,0x5428,0x540c,0x53f0,0x53d5,0x53b9,0x539e
+ .short 0x5383,0x5368,0x534c,0x5331,0x5316,0x52fb,0x52e0,0x52c6
+ .short 0x52ab,0x5290,0x5276,0x525b,0x5240,0x5226,0x520c,0x51f1
+ .short 0x51d7,0x51bd,0x51a3,0x5189,0x516f,0x5155,0x513b,0x5121
+ .short 0x5108,0x50ee,0x50d5,0x50bb,0x50a2,0x5088,0x506f,0x5056
+ .short 0x503c,0x5023,0x500a,0x4ff1,0x4fd8,0x4fbf,0x4fa6,0x4f8e
+ .short 0x4f75,0x4f5c,0x4f44,0x4f2b,0x4f13,0x4efa,0x4ee2,0x4eca
+ .short 0x4eb1,0x4e99,0x4e81,0x4e69,0x4e51,0x4e39,0x4e21,0x4e09
+ .short 0x4df1,0x4dda,0x4dc2,0x4daa,0x4d93,0x4d7b,0x4d64,0x4d4d
+ .short 0x4d35,0x4d1e,0x4d07,0x4cf0,0x4cd8,0x4cc1,0x4caa,0x4c93
+ .short 0x4c7d,0x4c66,0x4c4f,0x4c38,0x4c21,0x4c0b,0x4bf4,0x4bde
+ .short 0x4bc7,0x4bb1,0x4b9a,0x4b84,0x4b6e,0x4b58,0x4b41,0x4b2b
+ .short 0x4b15,0x4aff,0x4ae9,0x4ad3,0x4abd,0x4aa8,0x4a92,0x4a7c
+ .short 0x4a66,0x4a51,0x4a3b,0x4a26,0x4a10,0x49fb,0x49e5,0x49d0
+ .short 0x49bb,0x49a6,0x4990,0x497b,0x4966,0x4951,0x493c,0x4927
+ .short 0x4912,0x48fe,0x48e9,0x48d4,0x48bf,0x48ab,0x4896,0x4881
+ .short 0x486d,0x4858,0x4844,0x482f,0x481b,0x4807,0x47f3,0x47de
+ .short 0x47ca,0x47b6,0x47a2,0x478e,0x477a,0x4766,0x4752,0x473e
+ .short 0x472a,0x4717,0x4703,0x46ef,0x46db,0x46c8,0x46b4,0x46a1
+ .short 0x468d,0x467a,0x4666,0x4653,0x4640,0x462c,0x4619,0x4606
+ .short 0x45f3,0x45e0,0x45cd,0x45ba,0x45a7,0x4594,0x4581,0x456e
+ .short 0x455b,0x4548,0x4536,0x4523,0x4510,0x44fe,0x44eb,0x44d8
+ .short 0x44c6,0x44b3,0x44a1,0x448f,0x447c,0x446a,0x4458,0x4445
+ .short 0x4433,0x4421,0x440f,0x43fd,0x43eb,0x43d9,0x43c7,0x43b5
+ .short 0x43a3,0x4391,0x437f,0x436d,0x435c,0x434a,0x4338,0x4327
+ .short 0x4315,0x4303,0x42f2,0x42e0,0x42cf,0x42bd,0x42ac,0x429b
+ .short 0x4289,0x4278,0x4267,0x4256,0x4244,0x4233,0x4222,0x4211
+ .short 0x4200,0x41ef,0x41de,0x41cd,0x41bc,0x41ab,0x419a,0x418a
+ .short 0x4179,0x4168,0x4157,0x4147,0x4136,0x4125,0x4115,0x4104
+ .short 0x40f4,0x40e3,0x40d3,0x40c2,0x40b2,0x40a2,0x4091,0x4081
+ .short 0x4071,0x4061,0x4050,0x4040,0x4030,0x4020,0x4010,0x4000
+END_OBJECT(approx_tab)
+ASM_END()
diff --git a/gmp/mpn/powerpc32/lshift.asm b/gmp/mpn/powerpc32/lshift.asm
new file mode 100644
index 0000000000..948f8c6cf3
--- /dev/null
+++ b/gmp/mpn/powerpc32/lshift.asm
@@ -0,0 +1,166 @@
+dnl PowerPC-32 mpn_lshift -- Shift a number left.
+
+dnl Copyright 1995, 1998, 2000, 2002-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: 3.0
+C 75x (G3): 3.0
+C 7400,7410 (G4): 3.0
+C 7445,7455 (G4+): 2.5
+C 7447,7457 (G4+): 2.25
+C power4/ppc970: 2.5
+C power5: 2.5
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+C cnt r6
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ cmpwi cr0, r5, 30 C more than 30 limbs?
+ slwi r0, r5, 2
+ add r4, r4, r0 C make r4 point at end of s1
+ add r7, r3, r0 C make r7 point at end of res
+ bgt L(BIG) C branch if more than 12 limbs
+
+ mtctr r5 C copy size into CTR
+ subfic r8, r6, 32
+ lwzu r11, -4(r4) C load first s1 limb
+ srw r3, r11, r8 C compute function return value
+ bdz L(end1)
+
+L(oop): lwzu r10, -4(r4)
+ slw r9, r11, r6
+ srw r12, r10, r8
+ or r9, r9, r12
+ stwu r9, -4(r7)
+ bdz L(end2)
+ lwzu r11, -4(r4)
+ slw r9, r10, r6
+ srw r12, r11, r8
+ or r9, r9, r12
+ stwu r9, -4(r7)
+ bdnz L(oop)
+
+L(end1):
+ slw r0, r11, r6
+ stw r0, -4(r7)
+ blr
+L(end2):
+ slw r0, r10, r6
+ stw r0, -4(r7)
+ blr
+
+L(BIG):
+ stmw r24, -32(r1) C save registers we are supposed to preserve
+ lwzu r9, -4(r4)
+ subfic r8, r6, 32
+ srw r3, r9, r8 C compute function return value
+ slw r0, r9, r6
+ addi r5, r5, -1
+
+ andi. r10, r5, 3 C count for spill loop
+ beq L(e)
+ mtctr r10
+ lwzu r28, -4(r4)
+ bdz L(xe0)
+
+L(loop0):
+ slw r12, r28, r6
+ srw r24, r28, r8
+ lwzu r28, -4(r4)
+ or r24, r0, r24
+ stwu r24, -4(r7)
+ mr r0, r12
+ bdnz L(loop0) C taken at most once!
+
+L(xe0): slw r12, r28, r6
+ srw r24, r28, r8
+ or r24, r0, r24
+ stwu r24, -4(r7)
+ mr r0, r12
+
+L(e): srwi r5, r5, 2 C count for unrolled loop
+ addi r5, r5, -1
+ mtctr r5
+ lwz r28, -4(r4)
+ lwz r29, -8(r4)
+ lwz r30, -12(r4)
+ lwzu r31, -16(r4)
+
+L(loopU):
+ slw r9, r28, r6
+ srw r24, r28, r8
+ lwz r28, -4(r4)
+ slw r10, r29, r6
+ srw r25, r29, r8
+ lwz r29, -8(r4)
+ slw r11, r30, r6
+ srw r26, r30, r8
+ lwz r30, -12(r4)
+ slw r12, r31, r6
+ srw r27, r31, r8
+ lwzu r31, -16(r4)
+ or r24, r0, r24
+ stw r24, -4(r7)
+ or r25, r9, r25
+ stw r25, -8(r7)
+ or r26, r10, r26
+ stw r26, -12(r7)
+ or r27, r11, r27
+ stwu r27, -16(r7)
+ mr r0, r12
+ bdnz L(loopU)
+
+ slw r9, r28, r6
+ srw r24, r28, r8
+ slw r10, r29, r6
+ srw r25, r29, r8
+ slw r11, r30, r6
+ srw r26, r30, r8
+ slw r12, r31, r6
+ srw r27, r31, r8
+ or r24, r0, r24
+ stw r24, -4(r7)
+ or r25, r9, r25
+ stw r25, -8(r7)
+ or r26, r10, r26
+ stw r26, -12(r7)
+ or r27, r11, r27
+ stw r27, -16(r7)
+
+ stw r12, -20(r7)
+ lmw r24, -32(r1) C restore registers
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/lshiftc.asm b/gmp/mpn/powerpc32/lshiftc.asm
new file mode 100644
index 0000000000..61606d1b66
--- /dev/null
+++ b/gmp/mpn/powerpc32/lshiftc.asm
@@ -0,0 +1,168 @@
+dnl PowerPC-32 mpn_lshiftc.
+
+dnl Copyright 1995, 1998, 2000, 2002-2005, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: 3.0
+C 75x (G3): 3.0
+C 7400,7410 (G4): 3.0
+C 7445,7455 (G4+): 2.5
+C 7447,7457 (G4+): 2.25
+C power4/ppc970: 2.5
+C power5: 2.5
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+C cnt r6
+
+ASM_START()
+PROLOGUE(mpn_lshiftc)
+ cmpwi cr0, r5, 30 C more than 30 limbs?
+ slwi r0, r5, 2
+ add r4, r4, r0 C make r4 point at end of s1
+ add r7, r3, r0 C make r7 point at end of res
+ bgt L(BIG) C branch if more than 12 limbs
+
+ mtctr r5 C copy size into CTR
+ subfic r8, r6, 32
+ lwzu r11, -4(r4) C load first s1 limb
+ srw r3, r11, r8 C compute function return value
+ bdz L(end1)
+
+L(oop): lwzu r10, -4(r4)
+ slw r9, r11, r6
+ srw r12, r10, r8
+ nor r9, r9, r12
+ stwu r9, -4(r7)
+ bdz L(end2)
+ lwzu r11, -4(r4)
+ slw r9, r10, r6
+ srw r12, r11, r8
+ nor r9, r9, r12
+ stwu r9, -4(r7)
+ bdnz L(oop)
+
+L(end1):
+ slw r0, r11, r6
+ nor r0, r0, r0
+ stw r0, -4(r7)
+ blr
+L(end2):
+ slw r0, r10, r6
+ nor r0, r0, r0
+ stw r0, -4(r7)
+ blr
+
+L(BIG):
+ stmw r24, -32(r1) C save registers we are supposed to preserve
+ lwzu r9, -4(r4)
+ subfic r8, r6, 32
+ srw r3, r9, r8 C compute function return value
+ slw r0, r9, r6
+ addi r5, r5, -1
+
+ andi. r10, r5, 3 C count for spill loop
+ beq L(e)
+ mtctr r10
+ lwzu r28, -4(r4)
+ bdz L(xe0)
+
+L(loop0):
+ slw r12, r28, r6
+ srw r24, r28, r8
+ lwzu r28, -4(r4)
+ nor r24, r0, r24
+ stwu r24, -4(r7)
+ mr r0, r12
+ bdnz L(loop0) C taken at most once!
+
+L(xe0): slw r12, r28, r6
+ srw r24, r28, r8
+ nor r24, r0, r24
+ stwu r24, -4(r7)
+ mr r0, r12
+
+L(e): srwi r5, r5, 2 C count for unrolled loop
+ addi r5, r5, -1
+ mtctr r5
+ lwz r28, -4(r4)
+ lwz r29, -8(r4)
+ lwz r30, -12(r4)
+ lwzu r31, -16(r4)
+
+L(loopU):
+ slw r9, r28, r6
+ srw r24, r28, r8
+ lwz r28, -4(r4)
+ slw r10, r29, r6
+ srw r25, r29, r8
+ lwz r29, -8(r4)
+ slw r11, r30, r6
+ srw r26, r30, r8
+ lwz r30, -12(r4)
+ slw r12, r31, r6
+ srw r27, r31, r8
+ lwzu r31, -16(r4)
+ nor r24, r0, r24
+ stw r24, -4(r7)
+ nor r25, r9, r25
+ stw r25, -8(r7)
+ nor r26, r10, r26
+ stw r26, -12(r7)
+ nor r27, r11, r27
+ stwu r27, -16(r7)
+ mr r0, r12
+ bdnz L(loopU)
+
+ slw r9, r28, r6
+ srw r24, r28, r8
+ slw r10, r29, r6
+ srw r25, r29, r8
+ slw r11, r30, r6
+ srw r26, r30, r8
+ slw r12, r31, r6
+ srw r27, r31, r8
+ nor r24, r0, r24
+ stw r24, -4(r7)
+ nor r25, r9, r25
+ stw r25, -8(r7)
+ nor r26, r10, r26
+ stw r26, -12(r7)
+ nor r27, r11, r27
+ stw r27, -16(r7)
+ nor r12, r12, r12
+ stw r12, -20(r7)
+ lmw r24, -32(r1) C restore registers
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/mod_34lsub1.asm b/gmp/mpn/powerpc32/mod_34lsub1.asm
new file mode 100644
index 0000000000..6d7fe4d089
--- /dev/null
+++ b/gmp/mpn/powerpc32/mod_34lsub1.asm
@@ -0,0 +1,145 @@
+dnl PowerPC-32 mpn_mod_34lsub1 -- mpn remainder mod 2^24-1.
+
+dnl Copyright 2002, 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C 603e: ?
+C 604e: 3
+C 75x (G3): 3
+C 7400,7410 (G4): 3
+C 744x,745x (G4+): 3
+C power4/ppc970: 2.5
+C power5: 2.5
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr src, mp_size_t size)
+C
+C There seems no need to schedule the loads back, the code is still 3.0 c/l
+C on 750/7400 no matter where they're placed.
+C
+C Alternatives:
+C
+C Fetching half words would allow add instead for accumulating, instead of
+C adde and its serialization. An outer loop would be required though, since
+C 2^16 halfwords can overflow. lhz+add would be 2.0 c/l, but if there's
+C also a bdz or bdnz for each and a pointer update say every three limbs
+C then the total would be 2.67 c/l which isn't much faster than the current
+C simpler code.
+
+ASM_START()
+PROLOGUE(mpn_mod_34lsub1)
+
+ C r3 src
+ C r4 size
+
+ mtctr r4
+ addic r6, r3, 8 C &src[2], and clear CA
+
+ lwz r3, 0(r3) C acc0 = src[0]
+ bdz L(done)
+
+ lwz r4, -4(r6) C acc1 = src[1]
+ bdz L(two)
+
+ lwz r5, 0(r6) C acc2 = src[2]
+ lis r7, 0 C no carry if just three limbs
+
+ bdz L(three)
+ lis r7, 1 C 0x10000 carry pos
+
+L(top):
+ C r3 acc0
+ C r4 acc1
+ C r5 acc2
+ C r6 src, incrementing
+ C r7 carry pos
+
+ lwz r0, 4(r6)
+ adde r3, r3, r0
+ bdz L(end0)
+
+ lwz r0, 8(r6)
+ adde r4, r4, r0
+ bdz L(end1)
+
+ lwzu r0, 12(r6)
+ adde r5, r5, r0
+ bdnz L(top)
+
+
+ srwi r7, r7, 8
+L(end0):
+ srwi r7, r7, 8
+L(end1):
+ subfe r0, r0, r0 C -1 if not CA
+
+ andc r7, r7, r0 C final carry, 0x10000, 0x100, 1 or 0
+L(three):
+ rlwinm r6, r3, 0,8,31 C acc0 low
+
+ add r7, r7, r6
+ rlwinm r6, r3, 8,24,31 C acc0 high
+
+ add r7, r7, r6
+ rlwinm r6, r4, 8,8,23 C acc1 low
+
+ add r7, r7, r6
+ rlwinm r6, r4, 16,16,31 C acc1 high
+
+ add r7, r7, r6
+ rlwinm r6, r5, 16,8,15 C acc2 low
+
+ add r7, r7, r6
+ rlwinm r6, r5, 24,8,31 C acc2 high
+
+ add r3, r7, r6
+
+L(done):
+ blr
+
+L(two):
+ C r3 acc0
+ C r4 acc1
+
+ rlwinm r5, r3, 8,24,31 C acc0 high
+ rlwinm r3, r3, 0,8,31 C acc0 low
+
+ add r3, r3, r5 C acc0 high + low
+ rlwinm r5, r4, 16,16,31 C acc1 high
+
+ add r3, r3, r5 C add acc1 high
+ rlwinm r5, r4, 8,8,23 C acc1 low
+
+ add r3, r3, r5 C add acc1 low
+
+ blr
+
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/mode1o.asm b/gmp/mpn/powerpc32/mode1o.asm
new file mode 100644
index 0000000000..e8a6b5e28a
--- /dev/null
+++ b/gmp/mpn/powerpc32/mode1o.asm
@@ -0,0 +1,127 @@
+dnl PowerPC-32 mpn_modexact_1_odd -- mpn by limb exact remainder.
+
+dnl Copyright 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C 603e: ?
+C 604e: 6.0
+C 75x (G3): 6.0-13.0, depending on divisor
+C 7400,7410 (G4): 6.0-13.0, depending on divisor
+C 744x,745x (G4+): 8.0-10.0, depending on divisor
+C power4/ppc970: 12.0
+C power5: 12.0
+
+
+C mp_limb_t mpn_modexact_1_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C
+C For PIC, the inverse is established arithmetically since it measures about
+C 5 cycles faster than the nonsense needed to access binvert_limb_table in
+C SVR4 or Darwin style PIC. AIX might be better, since it avoids bl/mflr to
+C get at the GOT/TOC/whatever.
+C
+C Using divwu for size==1 measured about 10 cycles slower on 604e, or about
+C 3-5 cycles faster on 750. For now it doesn't seem worth bothering with.
+C
+C The loop allows an early-out on mullw for the inverse, and on mulhwu for
+C the divisor. So the fastest is for instance divisor==1 (inverse==-1), and
+C the slowest is anything giving a full 32-bits in both, such as
+C divisor==0xDEADBEEF (inverse==0x904B300F). These establish the stated
+C range above for 750 and 7400.
+
+
+ASM_START()
+
+EXTERN(binvert_limb_table)
+
+PROLOGUE(mpn_modexact_1_odd)
+ li r6, 0
+
+PROLOGUE(mpn_modexact_1c_odd)
+
+ mtctr r4 C size
+
+ifdef(`PIC_SLOW',`
+C Load from our table with PIC is so slow on Linux and Darwin that we avoid it
+ rlwinm r7, r5, 1,28,28 C (divisor << 1) & 8
+ rlwinm r8, r5, 2,28,28 C (divisor << 2) & 8
+ xor r7, r7, r8 C ((divisor << 1) ^ (divisor << 2)) & 8
+ rlwinm r4, r5, 0,28,31 C divisor low 4 bits, speedup mullw
+ xor r4, r4, r7 C inverse, 4 bits
+ mullw r7, r4, r4 C i*i
+ slwi r4, r4, 1 C 2*i
+ rlwinm r8, r5, 0,24,31 C divisor low 8 bits, speedup mullw
+ mullw r7, r7, r8 C i*i*d
+ sub r4, r4, r7 C inverse, 8 bits
+',`
+ LEA( r7, binvert_limb_table)
+ rlwinm r4, r5, 31,25,31 C (divisor/2) & 0x7F
+ lbzx r4, r4,r7 C inverse, 8 bits
+')
+
+ mullw r7, r4, r4 C i*i
+ slwi r4, r4, 1 C 2*i
+ mullw r7, r5, r7 C i*i*d [i*i is 16 bits, so second operand]
+ sub r4, r4, r7 C inverse, 16 bits
+ mullw r7, r4, r4 C i*i
+ slwi r4, r4, 1 C 2*i
+ mullw r7, r7, r5 C i*i*d
+ lwz r0, 0(r3) C src[0]
+ sub r4, r4, r7 C inverse, 32 bits
+ subfc r7, r6, r0 C l = src[0] - carry
+
+ mullw r7, r7, r4 C q = l * inverse
+ bdz L(one)
+
+ lwzu r0, 4(r3) C src[1]
+ mulhwu r6, r7, r5 C carry = high(q*divisor)
+ subfe r7, r6, r0 C l = src[1] - carry
+ bdz L(two)
+
+L(top):
+ mullw r7, r7, r4 C q = l * inverse
+ lwzu r0, 4(r3) C src[i]
+ mulhwu r6, r7, r5 C carry = high(q*divisor)
+ subfe r7, r6, r0 C l = src[i] - carry
+ bdnz L(top)
+
+L(two): mullw r7, r7, r4 C q = l * inverse
+L(one): subfe r3, r3, r3 C ca 0 or -1
+ mulhwu r6, r7, r5 C carry = high(q*divisor)
+ subf r3, r3, r6 C carry + ca
+ blr
+
+EPILOGUE(mpn_modexact_1c_odd)
+EPILOGUE(mpn_modexact_1_odd)
+ASM_END()
diff --git a/gmp/mpn/powerpc32/mul_1.asm b/gmp/mpn/powerpc32/mul_1.asm
new file mode 100644
index 0000000000..e42087cfa8
--- /dev/null
+++ b/gmp/mpn/powerpc32/mul_1.asm
@@ -0,0 +1,101 @@
+dnl PowerPC-32 mpn_mul_1 -- Multiply a limb vector with a limb and store the
+dnl result in a second limb vector.
+
+dnl Copyright 1995, 1997, 2000, 2002, 2003, 2005 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: 4.0
+C 75x (G3): 4.5-11
+C 7400,7410 (G4): 4.5-11
+C 744x,745x (G4+): 6.0
+C power4/ppc970: 6.0
+C power5: 5.63
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+C vl r6
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ mtctr r5
+ addi r3,r3,-4 C adjust res_ptr, it's offset before it's used
+ li r12,0 C clear upper product reg
+ addic r0,r0,0 C clear cy
+C Start software pipeline
+ lwz r8,0(r4)
+ bdz L(end3)
+ lwzu r9,4(r4)
+ mullw r11,r8,r6
+ mulhwu r0,r8,r6
+ bdz L(end1)
+C Software pipelined main loop
+L(loop):
+ lwz r8,4(r4)
+ mullw r10,r9,r6
+ adde r5,r11,r12
+ mulhwu r12,r9,r6
+ stw r5,4(r3)
+ bdz L(end2)
+ lwzu r9,8(r4)
+ mullw r11,r8,r6
+ adde r7,r10,r0
+ mulhwu r0,r8,r6
+ stwu r7,8(r3)
+ bdnz L(loop)
+C Finish software pipeline
+L(end1):
+ mullw r10,r9,r6
+ adde r5,r11,r12
+ mulhwu r12,r9,r6
+ stw r5,4(r3)
+ adde r7,r10,r0
+ stwu r7,8(r3)
+ addze r3,r12
+ blr
+L(end2):
+ mullw r11,r8,r6
+ adde r7,r10,r0
+ mulhwu r0,r8,r6
+ stwu r7,8(r3)
+ adde r5,r11,r12
+ stw r5,4(r3)
+ addze r3,r0
+ blr
+L(end3):
+ mullw r11,r8,r6
+ stw r11,4(r3)
+ mulhwu r3,r8,r6
+ blr
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/powerpc32/p3-p7/aors_n.asm b/gmp/mpn/powerpc32/p3-p7/aors_n.asm
new file mode 100644
index 0000000000..c44df8fa50
--- /dev/null
+++ b/gmp/mpn/powerpc32/p3-p7/aors_n.asm
@@ -0,0 +1,186 @@
+dnl PowerPC-32 mpn_add_n/mpn_sub_n -- mpn addition and subtraction.
+
+dnl Copyright 1999-2001, 2003-2005, 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 1.5
+C POWER4/PPC970 2
+C POWER5 2
+C POWER6 2.78
+C POWER7 2.15-2.87
+
+C This code is based on powerpc64/aors_n.asm.
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C vp r5
+C n r6
+
+ifdef(`OPERATION_add_n',`
+ define(ADDSUBC, adde)
+ define(ADDSUB, addc)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)
+ define(GENRVAL, `addi r3, r3, 1')
+ define(SETCBR, `addic r0, $1, -1')
+ define(CLRCB, `addic r0, r0, 0')
+')
+ifdef(`OPERATION_sub_n',`
+ define(ADDSUBC, subfe)
+ define(ADDSUB, subfc)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)
+ define(GENRVAL, `neg r3, r3')
+ define(SETCBR, `subfic r0, $1, 0')
+ define(CLRCB, `addic r0, r1, -1')
+')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+PROLOGUE(func_nc)
+ SETCBR(r7)
+ b L(ent)
+EPILOGUE()
+
+PROLOGUE(func)
+ CLRCB
+L(ent): stw r31, -4(r1)
+ stw r30, -8(r1)
+ stw r29, -12(r1)
+ stw r28, -16(r1)
+
+ rlwinm. r0, r6, 0,30,31 C r0 = n & 3, set cr0
+ cmpwi cr6, r0, 2
+ addi r6, r6, 3 C compute count...
+ srwi r6, r6, 2 C ...for ctr
+ mtctr r6 C copy count into ctr
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ beq cr6, L(b10)
+
+L(b11): lwz r8, 0(r4) C load s1 limb
+ lwz r9, 0(r5) C load s2 limb
+ lwz r10, 4(r4) C load s1 limb
+ lwz r11, 4(r5) C load s2 limb
+ lwz r12, 8(r4) C load s1 limb
+ addi r4, r4, 12
+ lwz r0, 8(r5) C load s2 limb
+ addi r5, r5, 12
+ ADDSUBC r29, r9, r8
+ ADDSUBC r30, r11, r10
+ ADDSUBC r31, r0, r12
+ stw r29, 0(r3)
+ stw r30, 4(r3)
+ stw r31, 8(r3)
+ addi r3, r3, 12
+ bdnz L(go)
+ b L(ret)
+
+L(b01): lwz r12, 0(r4) C load s1 limb
+ addi r4, r4, 4
+ lwz r0, 0(r5) C load s2 limb
+ addi r5, r5, 4
+ ADDSUBC r31, r0, r12 C add
+ stw r31, 0(r3)
+ addi r3, r3, 4
+ bdnz L(go)
+ b L(ret)
+
+L(b10): lwz r10, 0(r4) C load s1 limb
+ lwz r11, 0(r5) C load s2 limb
+ lwz r12, 4(r4) C load s1 limb
+ addi r4, r4, 8
+ lwz r0, 4(r5) C load s2 limb
+ addi r5, r5, 8
+ ADDSUBC r30, r11, r10 C add
+ ADDSUBC r31, r0, r12 C add
+ stw r30, 0(r3)
+ stw r31, 4(r3)
+ addi r3, r3, 8
+ bdnz L(go)
+ b L(ret)
+
+L(b00): C INITCY C clear/set cy
+L(go): lwz r6, 0(r4) C load s1 limb
+ lwz r7, 0(r5) C load s2 limb
+ lwz r8, 4(r4) C load s1 limb
+ lwz r9, 4(r5) C load s2 limb
+ lwz r10, 8(r4) C load s1 limb
+ lwz r11, 8(r5) C load s2 limb
+ lwz r12, 12(r4) C load s1 limb
+ lwz r0, 12(r5) C load s2 limb
+ bdz L(end)
+
+ addi r4, r4, 16
+ addi r5, r5, 16
+
+ ALIGN(16)
+L(top): ADDSUBC r28, r7, r6
+ lwz r6, 0(r4) C load s1 limb
+ lwz r7, 0(r5) C load s2 limb
+ ADDSUBC r29, r9, r8
+ lwz r8, 4(r4) C load s1 limb
+ lwz r9, 4(r5) C load s2 limb
+ ADDSUBC r30, r11, r10
+ lwz r10, 8(r4) C load s1 limb
+ lwz r11, 8(r5) C load s2 limb
+ ADDSUBC r31, r0, r12
+ lwz r12, 12(r4) C load s1 limb
+ lwz r0, 12(r5) C load s2 limb
+ stw r28, 0(r3)
+ addi r4, r4, 16
+ stw r29, 4(r3)
+ addi r5, r5, 16
+ stw r30, 8(r3)
+ stw r31, 12(r3)
+ addi r3, r3, 16
+ bdnz L(top) C decrement ctr and loop back
+
+L(end): ADDSUBC r28, r7, r6
+ ADDSUBC r29, r9, r8
+ ADDSUBC r30, r11, r10
+ ADDSUBC r31, r0, r12
+ stw r28, 0(r3)
+ stw r29, 4(r3)
+ stw r30, 8(r3)
+ stw r31, 12(r3)
+
+L(ret): lwz r31, -4(r1)
+ lwz r30, -8(r1)
+ lwz r29, -12(r1)
+ lwz r28, -16(r1)
+
+ subfe r3, r0, r0 C -cy
+ GENRVAL
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/p3/gmp-mparam.h b/gmp/mpn/powerpc32/p3/gmp-mparam.h
new file mode 100644
index 0000000000..33826956a2
--- /dev/null
+++ b/gmp/mpn/powerpc32/p3/gmp-mparam.h
@@ -0,0 +1,155 @@
+/* PowerPC-32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004, 2008-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 450 MHz POWER3 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 2
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 12
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 18
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 8
+#define USE_PREINV_DIVREM_1 1
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 10
+#define MUL_TOOM33_THRESHOLD 38
+#define MUL_TOOM44_THRESHOLD 58
+#define MUL_TOOM6H_THRESHOLD 129
+#define MUL_TOOM8H_THRESHOLD 212
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 65
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 63
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 59
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 64
+
+#define SQR_BASECASE_THRESHOLD 0 /* always */
+#define SQR_TOOM2_THRESHOLD 14
+#define SQR_TOOM3_THRESHOLD 53
+#define SQR_TOOM4_THRESHOLD 76
+#define SQR_TOOM6_THRESHOLD 106
+#define SQR_TOOM8_THRESHOLD 284
+
+#define MULMOD_BNM1_THRESHOLD 9
+#define SQRMOD_BNM1_THRESHOLD 9
+
+#define MUL_FFT_MODF_THRESHOLD 220 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 220, 5}, { 13, 6}, { 7, 5}, { 15, 6}, \
+ { 9, 5}, { 19, 6}, { 13, 7}, { 7, 6}, \
+ { 16, 7}, { 13, 8}, { 7, 7}, { 19, 8}, \
+ { 11, 7}, { 23, 9}, { 7, 8}, { 15, 7}, \
+ { 33, 8}, { 23, 9}, { 15, 8}, { 35, 9}, \
+ { 23,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47,10}, { 31, 9}, \
+ { 63, 8}, { 127, 9}, { 71, 8}, { 143, 9}, \
+ { 79,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255, 9}, { 143,10}, { 79, 9}, \
+ { 159, 8}, { 319, 9}, { 175, 8}, { 351,10}, \
+ { 95, 9}, { 191, 8}, { 383,10}, { 111,11}, \
+ { 63,10}, { 127, 9}, { 255,10}, { 143, 9}, \
+ { 287, 8}, { 575,10}, { 159, 9}, { 319,10}, \
+ { 175, 9}, { 351,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207, 9}, { 415,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 351, 9}, { 703, 8}, \
+ { 1407,11}, { 191,10}, { 415,11}, { 223,10}, \
+ { 447, 9}, { 895,12}, { 4096,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 82
+#define MUL_FFT_THRESHOLD 2688
+
+#define SQR_FFT_MODF_THRESHOLD 176 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 176, 5}, { 13, 6}, { 7, 5}, { 15, 6}, \
+ { 13, 7}, { 7, 6}, { 16, 7}, { 9, 6}, \
+ { 19, 7}, { 11, 6}, { 23, 7}, { 13, 8}, \
+ { 7, 7}, { 19, 8}, { 11, 7}, { 23, 9}, \
+ { 7, 8}, { 15, 7}, { 31, 8}, { 23, 9}, \
+ { 15, 8}, { 39, 9}, { 23,10}, { 15, 9}, \
+ { 31, 8}, { 63, 9}, { 39, 8}, { 79, 9}, \
+ { 47, 8}, { 95,10}, { 31, 9}, { 63, 8}, \
+ { 127, 9}, { 71, 8}, { 143, 7}, { 287, 6}, \
+ { 575, 9}, { 79, 8}, { 159,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 9}, { 143, 8}, { 287, 7}, { 575,10}, \
+ { 79, 9}, { 159, 8}, { 319, 9}, { 175,10}, \
+ { 95, 9}, { 191, 8}, { 383,10}, { 111, 9}, \
+ { 223,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 143, 9}, { 287, 8}, { 575,10}, { 159, 9}, \
+ { 319,10}, { 175,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 223,12}, { 63,11}, { 127,10}, \
+ { 287, 9}, { 575,11}, { 159,10}, { 351, 9}, \
+ { 703, 8}, { 1407,11}, { 191,10}, { 383,11}, \
+ { 223,10}, { 447, 9}, { 895,12}, { 4096,13}, \
+ { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 87
+#define SQR_FFT_THRESHOLD 1728
+
+#define MULLO_BASECASE_THRESHOLD 2
+#define MULLO_DC_THRESHOLD 33
+#define MULLO_MUL_N_THRESHOLD 5240
+
+#define DC_DIV_QR_THRESHOLD 32
+#define DC_DIVAPPR_Q_THRESHOLD 123
+#define DC_BDIV_QR_THRESHOLD 34
+#define DC_BDIV_Q_THRESHOLD 84
+
+#define INV_MULMOD_BNM1_THRESHOLD 42
+#define INV_NEWTON_THRESHOLD 129
+#define INV_APPR_THRESHOLD 124
+
+#define BINV_NEWTON_THRESHOLD 148
+#define REDC_1_TO_REDC_N_THRESHOLD 38
+
+#define MU_DIV_QR_THRESHOLD 748
+#define MU_DIVAPPR_Q_THRESHOLD 748
+#define MUPI_DIV_QR_THRESHOLD 59
+#define MU_BDIV_QR_THRESHOLD 562
+#define MU_BDIV_Q_THRESHOLD 654
+
+#define MATRIX22_STRASSEN_THRESHOLD 11
+#define HGCD_THRESHOLD 76
+#define GCD_DC_THRESHOLD 205
+#define GCDEXT_DC_THRESHOLD 174
+#define JACOBI_BASE_METHOD 1
+
+#define GET_STR_DC_THRESHOLD 14
+#define GET_STR_PRECOMPUTE_THRESHOLD 27
+#define SET_STR_DC_THRESHOLD 181
+#define SET_STR_PRECOMPUTE_THRESHOLD 525
diff --git a/gmp/mpn/powerpc32/p4/gmp-mparam.h b/gmp/mpn/powerpc32/p4/gmp-mparam.h
new file mode 100644
index 0000000000..20830a0bd7
--- /dev/null
+++ b/gmp/mpn/powerpc32/p4/gmp-mparam.h
@@ -0,0 +1,204 @@
+/* PowerPC-32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004, 2008-2011, 2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* 1800 MHz PowerPC-970 */
+/* FFT tuning limit = 10000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.0 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 1
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 9
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 42
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 14
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 45
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 73
+#define MUL_TOOM44_THRESHOLD 130
+#define MUL_TOOM6H_THRESHOLD 222
+#define MUL_TOOM8H_THRESHOLD 333
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 107
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 108
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 89
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 92
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 100
+
+#define SQR_BASECASE_THRESHOLD 5
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 85
+#define SQR_TOOM4_THRESHOLD 160
+#define SQR_TOOM6_THRESHOLD 197
+#define SQR_TOOM8_THRESHOLD 357
+
+#define MULMID_TOOM42_THRESHOLD 32
+
+#define MULMOD_BNM1_THRESHOLD 15
+#define SQRMOD_BNM1_THRESHOLD 16
+
+#define MUL_FFT_MODF_THRESHOLD 444 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 444, 5}, { 17, 6}, { 9, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 24, 7}, { 13, 6}, { 28, 7}, { 15, 6}, \
+ { 31, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
+ { 15, 7}, { 33, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
+ { 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
+ { 47, 8}, { 95,10}, { 31, 9}, { 63, 8}, \
+ { 127, 9}, { 79,10}, { 47, 9}, { 95,11}, \
+ { 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
+ { 167,10}, { 95, 9}, { 191, 8}, { 383,10}, \
+ { 111,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511,10}, { 143, 9}, { 287, 8}, { 575, 9}, \
+ { 303,10}, { 159, 9}, { 319,11}, { 95,10}, \
+ { 191, 9}, { 383,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271, 9}, { 543, 8}, \
+ { 1087,10}, { 287, 9}, { 575,10}, { 303,11}, \
+ { 159,10}, { 335, 9}, { 671, 8}, { 1343,10}, \
+ { 351, 9}, { 703,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 415, 9}, { 831,11}, { 223,10}, \
+ { 447,12}, { 127,11}, { 255,10}, { 543, 9}, \
+ { 1087,11}, { 287,10}, { 607, 9}, { 1215,11}, \
+ { 319,10}, { 671, 9}, { 1343,11}, { 351,10}, \
+ { 703, 9}, { 1407,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 415,10}, { 831,11}, { 447,13}, \
+ { 127,12}, { 255,11}, { 543,10}, { 1087,11}, \
+ { 607,10}, { 1215,12}, { 319,11}, { 671,10}, \
+ { 1343,11}, { 703,10}, { 1407,11}, { 735,12}, \
+ { 383,11}, { 767,10}, { 1535,11}, { 831,12}, \
+ { 447,10}, { 1791,11}, { 959,13}, { 255,12}, \
+ { 511,11}, { 1087,12}, { 575,11}, { 1215,10}, \
+ { 2431,12}, { 639,11}, { 1343,12}, { 703,11}, \
+ { 1407,13}, { 383,12}, { 767,11}, { 1535,12}, \
+ { 831,11}, { 1727,10}, { 3455,11}, { 1791,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1215,11}, \
+ { 2431,13}, { 639,12}, { 1471,13}, { 767,12}, \
+ { 1727,11}, { 3455,12}, { 1791,14}, { 511,13}, \
+ { 1151,12}, { 2431,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 157
+#define MUL_FFT_THRESHOLD 6784
+
+#define SQR_FFT_MODF_THRESHOLD 340 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 340, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 21, 7}, { 11, 6}, { 24, 7}, { 13, 6}, \
+ { 28, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
+ { 15, 7}, { 33, 8}, { 19, 7}, { 39, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 8}, { 47,10}, { 15, 9}, \
+ { 31, 8}, { 63, 9}, { 39, 8}, { 79, 9}, \
+ { 47,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 9}, { 135,10}, { 79, 9}, { 159, 8}, \
+ { 319,10}, { 95, 9}, { 191, 8}, { 383, 9}, \
+ { 207,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511, 9}, { 271,10}, { 143, 9}, { 287, 8}, \
+ { 575, 9}, { 303, 8}, { 607,10}, { 159, 9}, \
+ { 319,10}, { 175,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271, 9}, { 543, 8}, \
+ { 1087,10}, { 287, 9}, { 575,10}, { 303, 9}, \
+ { 607,11}, { 159,10}, { 319, 9}, { 639,10}, \
+ { 335, 9}, { 671,10}, { 351, 9}, { 703,11}, \
+ { 191,10}, { 383, 9}, { 767,10}, { 415, 9}, \
+ { 831,11}, { 223,10}, { 447,12}, { 127,11}, \
+ { 255,10}, { 543, 9}, { 1087,11}, { 287,10}, \
+ { 607, 9}, { 1215,11}, { 319,10}, { 671,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 415,10}, { 831,11}, { 479,13}, \
+ { 127,12}, { 255,11}, { 543,10}, { 1087,11}, \
+ { 607,10}, { 1215,12}, { 319,11}, { 671,10}, \
+ { 1343,11}, { 703,10}, { 1407,11}, { 735,12}, \
+ { 383,11}, { 831,12}, { 447,11}, { 959,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1215,12}, { 639,11}, { 1343,12}, { 703,11}, \
+ { 1407,13}, { 383,12}, { 831,11}, { 1727,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1215,13}, \
+ { 639,12}, { 1471,13}, { 767,12}, { 1727,13}, \
+ { 895,12}, { 1919,14}, { 511,13}, { 1023,12}, \
+ { 2111,13}, { 1151,12}, { 2431,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 150
+#define SQR_FFT_THRESHOLD 4736
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 55
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 50
+#define DC_DIVAPPR_Q_THRESHOLD 196
+#define DC_BDIV_QR_THRESHOLD 51
+#define DC_BDIV_Q_THRESHOLD 166
+
+#define INV_MULMOD_BNM1_THRESHOLD 50
+#define INV_NEWTON_THRESHOLD 226
+#define INV_APPR_THRESHOLD 202
+
+#define BINV_NEWTON_THRESHOLD 228
+#define REDC_1_TO_REDC_N_THRESHOLD 67
+
+#define MU_DIV_QR_THRESHOLD 1187
+#define MU_DIVAPPR_Q_THRESHOLD 1308
+#define MUPI_DIV_QR_THRESHOLD 114
+#define MU_BDIV_QR_THRESHOLD 998
+#define MU_BDIV_Q_THRESHOLD 1142
+
+#define POWM_SEC_TABLE 3,28,78,480,1099
+
+#define MATRIX22_STRASSEN_THRESHOLD 9
+#define HGCD_THRESHOLD 93
+#define HGCD_APPR_THRESHOLD 109
+#define HGCD_REDUCE_THRESHOLD 2479
+#define GCD_DC_THRESHOLD 379
+#define GCDEXT_DC_THRESHOLD 273
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 11
+#define GET_STR_PRECOMPUTE_THRESHOLD 24
+#define SET_STR_DC_THRESHOLD 381
+#define SET_STR_PRECOMPUTE_THRESHOLD 1002
+
+#define FAC_DSC_THRESHOLD 179
+#define FAC_ODD_THRESHOLD 28
diff --git a/gmp/mpn/powerpc32/p5/gmp-mparam.h b/gmp/mpn/powerpc32/p5/gmp-mparam.h
new file mode 100644
index 0000000000..faa1e81da4
--- /dev/null
+++ b/gmp/mpn/powerpc32/p5/gmp-mparam.h
@@ -0,0 +1,156 @@
+/* PowerPC-32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004, 2008-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 1650 MHz POWER5 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 1
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 8
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 9
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 50
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 18
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 61
+
+#define MUL_TOOM22_THRESHOLD 22
+#define MUL_TOOM33_THRESHOLD 57
+#define MUL_TOOM44_THRESHOLD 130
+#define MUL_TOOM6H_THRESHOLD 189
+#define MUL_TOOM8H_THRESHOLD 309
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 89
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 99
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 83
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 88
+
+#define SQR_BASECASE_THRESHOLD 6
+#define SQR_TOOM2_THRESHOLD 40
+#define SQR_TOOM3_THRESHOLD 77
+#define SQR_TOOM4_THRESHOLD 124
+#define SQR_TOOM6_THRESHOLD 140
+#define SQR_TOOM8_THRESHOLD 238
+
+#define MULMID_TOOM42_THRESHOLD 40
+
+#define MULMOD_BNM1_THRESHOLD 15
+#define SQRMOD_BNM1_THRESHOLD 16
+
+#define POWM_SEC_TABLE 4,29,252,840,2080
+
+#define MUL_FFT_MODF_THRESHOLD 412 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 412, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 12, 5}, { 25, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 21, 8}, \
+ { 11, 7}, { 27, 8}, { 15, 7}, { 33, 8}, \
+ { 19, 7}, { 39, 8}, { 23, 7}, { 47, 8}, \
+ { 27, 9}, { 15, 8}, { 39, 9}, { 23, 8}, \
+ { 51,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 55,10}, { 31, 9}, \
+ { 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
+ { 63, 9}, { 135,10}, { 79, 9}, { 159,10}, \
+ { 95,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 143, 9}, { 287,10}, { 159,11}, { 95,10}, \
+ { 191,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,10}, { 287,11}, \
+ { 159,10}, { 335, 9}, { 671,10}, { 351, 9}, \
+ { 703,11}, { 191,10}, { 383, 9}, { 767,10}, \
+ { 415, 9}, { 831,11}, { 223,12}, { 4096,13}, \
+ { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 71
+#define MUL_FFT_THRESHOLD 4736
+
+#define SQR_FFT_MODF_THRESHOLD 340 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 340, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 21, 7}, { 11, 6}, { 24, 7}, { 13, 6}, \
+ { 27, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
+ { 15, 7}, { 33, 8}, { 19, 7}, { 39, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 8}, { 47,10}, { 15, 9}, \
+ { 31, 8}, { 67, 9}, { 47,10}, { 31, 9}, \
+ { 71,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255, 9}, { 135,10}, { 79, 9}, \
+ { 159,10}, { 95, 9}, { 191,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511, 9}, { 271,10}, \
+ { 143, 9}, { 287, 8}, { 575, 9}, { 303,10}, \
+ { 159,11}, { 95,10}, { 191,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
+ { 543,10}, { 287, 9}, { 575,10}, { 303,11}, \
+ { 159,10}, { 319, 9}, { 639,10}, { 335, 9}, \
+ { 671,10}, { 351,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 415,11}, { 223,10}, { 447,12}, \
+ { 4096,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 76
+#define SQR_FFT_THRESHOLD 3712
+
+#define MULLO_BASECASE_THRESHOLD 2
+#define MULLO_DC_THRESHOLD 68
+#define MULLO_MUL_N_THRESHOLD 9236
+
+#define DC_DIV_QR_THRESHOLD 69
+#define DC_DIVAPPR_Q_THRESHOLD 220
+#define DC_BDIV_QR_THRESHOLD 75
+#define DC_BDIV_Q_THRESHOLD 188
+
+#define INV_MULMOD_BNM1_THRESHOLD 54
+#define INV_NEWTON_THRESHOLD 230
+#define INV_APPR_THRESHOLD 230
+
+#define BINV_NEWTON_THRESHOLD 278
+#define REDC_1_TO_REDC_N_THRESHOLD 87
+
+#define MU_DIV_QR_THRESHOLD 1210
+#define MU_DIVAPPR_Q_THRESHOLD 1308
+#define MUPI_DIV_QR_THRESHOLD 106
+#define MU_BDIV_QR_THRESHOLD 1017
+#define MU_BDIV_Q_THRESHOLD 1210
+
+#define MATRIX22_STRASSEN_THRESHOLD 14
+#define HGCD_THRESHOLD 110
+#define HGCD_APPR_THRESHOLD 138
+#define HGCD_REDUCE_THRESHOLD 2578
+#define GCD_DC_THRESHOLD 408
+#define GCDEXT_DC_THRESHOLD 298
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 24
+#define SET_STR_DC_THRESHOLD 527
+#define SET_STR_PRECOMPUTE_THRESHOLD 1090
diff --git a/gmp/mpn/powerpc32/p6/gmp-mparam.h b/gmp/mpn/powerpc32/p6/gmp-mparam.h
new file mode 100644
index 0000000000..c9504b63b3
--- /dev/null
+++ b/gmp/mpn/powerpc32/p6/gmp-mparam.h
@@ -0,0 +1,165 @@
+/* PowerPC-32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004, 2008-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 3500 MHz POWER6 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 3
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD MP_SIZE_T_MAX
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 8
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 19
+#define MUL_TOOM33_THRESHOLD 55
+#define MUL_TOOM44_THRESHOLD 88
+#define MUL_TOOM6H_THRESHOLD 137
+#define MUL_TOOM8H_THRESHOLD 181
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 57
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 56
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 57
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 56
+
+#define SQR_BASECASE_THRESHOLD 0 /* always */
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 56
+#define SQR_TOOM4_THRESHOLD 130
+#define SQR_TOOM6_THRESHOLD 189
+#define SQR_TOOM8_THRESHOLD 296
+
+#define MULMID_TOOM42_THRESHOLD 26
+
+#define MULMOD_BNM1_THRESHOLD 7
+#define SQRMOD_BNM1_THRESHOLD 12
+
+#define POWM_SEC_TABLE 2,26,127,453,1068
+
+#define MUL_FFT_MODF_THRESHOLD 212 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 212, 5}, { 13, 6}, { 7, 5}, { 15, 6}, \
+ { 13, 7}, { 7, 6}, { 16, 7}, { 9, 6}, \
+ { 19, 7}, { 13, 8}, { 7, 7}, { 19, 8}, \
+ { 11, 7}, { 25, 9}, { 7, 8}, { 15, 7}, \
+ { 31, 8}, { 19, 7}, { 39, 8}, { 23, 9}, \
+ { 15, 8}, { 39, 9}, { 23, 8}, { 47,10}, \
+ { 15, 9}, { 31, 8}, { 63, 9}, { 39, 8}, \
+ { 79, 9}, { 47,10}, { 31, 9}, { 63, 8}, \
+ { 127, 9}, { 71, 8}, { 143, 7}, { 287, 9}, \
+ { 79,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255, 7}, { 511, 9}, { 143, 8}, \
+ { 287,10}, { 79, 9}, { 159, 8}, { 319, 9}, \
+ { 175, 8}, { 351,10}, { 95, 9}, { 191, 8}, \
+ { 383, 9}, { 207,10}, { 111,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511,10}, { 143, 9}, \
+ { 287, 8}, { 575,10}, { 159, 9}, { 319,10}, \
+ { 175, 9}, { 351,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207, 9}, { 415,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 351, 9}, { 703,11}, \
+ { 191,10}, { 415, 9}, { 831,11}, { 223,10}, \
+ { 447,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 89
+#define MUL_FFT_THRESHOLD 1728
+
+#define SQR_FFT_MODF_THRESHOLD 184 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 184, 5}, { 6, 4}, { 13, 5}, { 13, 6}, \
+ { 7, 5}, { 15, 6}, { 13, 7}, { 7, 6}, \
+ { 16, 7}, { 9, 6}, { 19, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 19, 8}, \
+ { 11, 7}, { 23, 9}, { 7, 8}, { 23, 9}, \
+ { 15, 8}, { 39, 9}, { 23,10}, { 15, 9}, \
+ { 31, 8}, { 63, 9}, { 39, 8}, { 79, 9}, \
+ { 47,10}, { 31, 9}, { 63, 8}, { 127, 7}, \
+ { 255, 9}, { 71, 8}, { 143, 7}, { 287, 6}, \
+ { 575, 9}, { 79,10}, { 47,11}, { 31,10}, \
+ { 63, 9}, { 127, 8}, { 255, 9}, { 143, 8}, \
+ { 287, 7}, { 575,10}, { 79, 9}, { 159, 8}, \
+ { 319, 9}, { 175, 8}, { 351,10}, { 95, 9}, \
+ { 191, 8}, { 383, 9}, { 207,10}, { 111, 9}, \
+ { 223,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 143, 9}, { 287, 8}, { 575,10}, { 159, 9}, \
+ { 319,10}, { 175, 9}, { 351,11}, { 95,10}, \
+ { 191, 9}, { 383,10}, { 207, 9}, { 415,10}, \
+ { 223,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 287, 9}, { 575,11}, { 159,10}, \
+ { 351, 9}, { 703, 8}, { 1407,11}, { 191,10}, \
+ { 415,11}, { 223,10}, { 447, 9}, { 895,12}, \
+ { 4096,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 92
+#define SQR_FFT_THRESHOLD 1600
+
+#define MULLO_BASECASE_THRESHOLD 2
+#define MULLO_DC_THRESHOLD 57
+#define MULLO_MUL_N_THRESHOLD 3176
+
+#define DC_DIV_QR_THRESHOLD 52
+#define DC_DIVAPPR_Q_THRESHOLD 187
+#define DC_BDIV_QR_THRESHOLD 64
+#define DC_BDIV_Q_THRESHOLD 146
+
+#define INV_MULMOD_BNM1_THRESHOLD 68
+#define INV_NEWTON_THRESHOLD 182
+#define INV_APPR_THRESHOLD 182
+
+#define BINV_NEWTON_THRESHOLD 186
+#define REDC_1_TO_REDC_N_THRESHOLD 60
+
+#define MU_DIV_QR_THRESHOLD 924
+#define MU_DIVAPPR_Q_THRESHOLD 807
+#define MUPI_DIV_QR_THRESHOLD 73
+#define MU_BDIV_QR_THRESHOLD 667
+#define MU_BDIV_Q_THRESHOLD 823
+
+#define MATRIX22_STRASSEN_THRESHOLD 8
+#define HGCD_THRESHOLD 61
+#define HGCD_APPR_THRESHOLD 50
+#define HGCD_REDUCE_THRESHOLD 974
+#define GCD_DC_THRESHOLD 195
+#define GCDEXT_DC_THRESHOLD 134
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 9
+#define GET_STR_PRECOMPUTE_THRESHOLD 21
+#define SET_STR_DC_THRESHOLD 190
+#define SET_STR_PRECOMPUTE_THRESHOLD 411
diff --git a/gmp/mpn/powerpc32/p7/gmp-mparam.h b/gmp/mpn/powerpc32/p7/gmp-mparam.h
new file mode 100644
index 0000000000..35bb61dca2
--- /dev/null
+++ b/gmp/mpn/powerpc32/p7/gmp-mparam.h
@@ -0,0 +1,159 @@
+/* PowerPC-32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004, 2008-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 3550 MHz POWER7/T4 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 1
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 34
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 15
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 34
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 89
+#define MUL_TOOM44_THRESHOLD 130
+#define MUL_TOOM6H_THRESHOLD 286
+#define MUL_TOOM8H_THRESHOLD 363
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 121
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 114
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 89
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 113
+
+#define SQR_BASECASE_THRESHOLD 4
+#define SQR_TOOM2_THRESHOLD 50
+#define SQR_TOOM3_THRESHOLD 89
+#define SQR_TOOM4_THRESHOLD 154
+#define SQR_TOOM6_THRESHOLD 222
+#define SQR_TOOM8_THRESHOLD 381
+
+#define MULMID_TOOM42_THRESHOLD 40
+
+#define MULMOD_BNM1_THRESHOLD 18
+#define SQRMOD_BNM1_THRESHOLD 17
+
+#define POWM_SEC_TABLE 4,35,225,780,2212
+
+#define MUL_FFT_MODF_THRESHOLD 476 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 476, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 12, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 14, 5}, { 29, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 13, 6}, { 29, 7}, { 15, 6}, \
+ { 31, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
+ { 39, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 27, 9}, { 15, 8}, { 39, 9}, { 23, 8}, \
+ { 51,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 159,10}, { 95,11}, { 63,10}, \
+ { 159,11}, { 95,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271, 9}, { 543, 8}, \
+ { 1087,11}, { 159,10}, { 319, 9}, { 639,10}, \
+ { 335, 9}, { 671, 8}, { 1343,10}, { 351,11}, \
+ { 191,10}, { 415, 9}, { 831,10}, { 431,11}, \
+ { 223,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 77
+#define MUL_FFT_THRESHOLD 5312
+
+#define SQR_FFT_MODF_THRESHOLD 344 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 344, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 21, 7}, { 11, 6}, { 24, 7}, { 13, 6}, \
+ { 27, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
+ { 11, 7}, { 27, 8}, { 15, 7}, { 33, 8}, \
+ { 19, 7}, { 39, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 8}, { 47,10}, { 15, 9}, \
+ { 31, 8}, { 63, 9}, { 39, 8}, { 79, 9}, \
+ { 47,10}, { 31, 9}, { 79,10}, { 47,11}, \
+ { 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
+ { 159,10}, { 95, 9}, { 191,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511, 9}, { 271,10}, \
+ { 143, 9}, { 287, 8}, { 575, 9}, { 303,10}, \
+ { 159,11}, { 95,10}, { 191,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
+ { 543, 8}, { 1087,10}, { 287, 9}, { 575,10}, \
+ { 303,11}, { 159,10}, { 319, 9}, { 639,10}, \
+ { 335, 9}, { 671,10}, { 351, 9}, { 703,11}, \
+ { 191,10}, { 383, 9}, { 767,10}, { 415, 9}, \
+ { 831,11}, { 223,10}, { 447,12}, { 4096,13}, \
+ { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 79
+#define SQR_FFT_THRESHOLD 3712
+
+#define MULLO_BASECASE_THRESHOLD 2
+#define MULLO_DC_THRESHOLD 34
+#define MULLO_MUL_N_THRESHOLD 10323
+
+#define DC_DIV_QR_THRESHOLD 52
+#define DC_DIVAPPR_Q_THRESHOLD 202
+#define DC_BDIV_QR_THRESHOLD 68
+#define DC_BDIV_Q_THRESHOLD 152
+
+#define INV_MULMOD_BNM1_THRESHOLD 66
+#define INV_NEWTON_THRESHOLD 226
+#define INV_APPR_THRESHOLD 189
+
+#define BINV_NEWTON_THRESHOLD 292
+#define REDC_1_TO_REDC_N_THRESHOLD 79
+
+#define MU_DIV_QR_THRESHOLD 1442
+#define MU_DIVAPPR_Q_THRESHOLD 1442
+#define MUPI_DIV_QR_THRESHOLD 91
+#define MU_BDIV_QR_THRESHOLD 1308
+#define MU_BDIV_Q_THRESHOLD 1442
+
+#define MATRIX22_STRASSEN_THRESHOLD 16
+#define HGCD_THRESHOLD 126
+#define HGCD_APPR_THRESHOLD 139
+#define HGCD_REDUCE_THRESHOLD 2681
+#define GCD_DC_THRESHOLD 573
+#define GCDEXT_DC_THRESHOLD 448
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 9
+#define GET_STR_PRECOMPUTE_THRESHOLD 20
+#define SET_STR_DC_THRESHOLD 834
+#define SET_STR_PRECOMPUTE_THRESHOLD 1888
diff --git a/gmp/mpn/powerpc32/powerpc-defs.m4 b/gmp/mpn/powerpc32/powerpc-defs.m4
new file mode 100644
index 0000000000..0c142a2e0c
--- /dev/null
+++ b/gmp/mpn/powerpc32/powerpc-defs.m4
@@ -0,0 +1,104 @@
+divert(-1)
+
+dnl m4 macros for PowerPC assembler (32 and 64 bit).
+
+dnl Copyright 2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+dnl This is the same as the default in mpn/asm-defs.m4, but with ALIGN(4)
+dnl not 8.
+dnl
+dnl 4-byte alignment is normally enough, certainly it's what gcc gives. We
+dnl don't want bigger alignment within PROLOGUE since it can introduce
+dnl padding into multiple-entrypoint routines, and with gas such padding is
+dnl zero words, which are not valid instructions.
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+` TEXT
+ ALIGN(4)
+ GLOBL `$1' GLOBL_ATTR
+ TYPE(`$1',`function')
+`$1'LABEL_SUFFIX')
+
+
+dnl Usage: r0 ... r31, cr0 ... cr7
+dnl
+dnl Registers names, either left as "r0" etc or mapped to plain 0 etc,
+dnl according to the result of the GMP_ASM_POWERPC_REGISTERS configure
+dnl test.
+
+ifelse(WANT_R_REGISTERS,no,`
+forloop(i,0,31,`deflit(`r'i,i)')
+forloop(i,0,31,`deflit(`v'i,i)')
+forloop(i,0,31,`deflit(`f'i,i)')
+forloop(i,0,7, `deflit(`cr'i,i)')
+')
+
+
+dnl Usage: ASSERT(cond,instructions)
+dnl
+dnl If WANT_ASSERT is 1, output the given instructions and expect the given
+dnl flags condition to then be satisfied. For example,
+dnl
+dnl ASSERT(eq, `cmpwi r6, 123')
+dnl
+dnl The instructions can be omitted to just assert a flags condition with
+dnl no extra calculation. For example,
+dnl
+dnl ASSERT(ne)
+dnl
+dnl The condition can be omitted to just output the given instructions when
+dnl assertion checking is wanted. For example,
+dnl
+dnl ASSERT(, `mr r11, r0')
+dnl
+dnl Using a zero word for an illegal instruction is probably not ideal,
+dnl since it marks the beginning of a traceback table in the 64-bit ABI.
+dnl But assertions are only for development, so it doesn't matter too much.
+
+define(ASSERT,
+m4_assert_numargs_range(1,2)
+m4_assert_defined(`WANT_ASSERT')
+`ifelse(WANT_ASSERT,1,
+ `C ASSERT
+ $2
+ifelse(`$1',,,
+` b$1 L(ASSERT_ok`'ASSERT_counter)
+ W32 0 C assertion failed
+L(ASSERT_ok`'ASSERT_counter):
+define(`ASSERT_counter',incr(ASSERT_counter))
+')')')
+
+define(ASSERT_counter,1)
+
+
+divert
diff --git a/gmp/mpn/powerpc32/rshift.asm b/gmp/mpn/powerpc32/rshift.asm
new file mode 100644
index 0000000000..cb0046d5ee
--- /dev/null
+++ b/gmp/mpn/powerpc32/rshift.asm
@@ -0,0 +1,164 @@
+dnl PowerPC-32 mpn_rshift -- Shift a number right.
+
+dnl Copyright 1995, 1998, 2000, 2002-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: 3.0
+C 75x (G3): 3.0
+C 7400,7410 (G4): 3.0
+C 7445,7455 (G4+): 2.5
+C 7447,7457 (G4+): 2.25
+C power4/ppc970: 2.5
+C power5: 2.5
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+C cnt r6
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ cmpwi cr0, r5, 30 C more than 30 limbs?
+ addi r7, r3, -4 C dst-4
+ bgt L(BIG) C branch if more than 12 limbs
+
+ mtctr r5 C copy size into CTR
+ subfic r8, r6, 32
+ lwz r11, 0(r4) C load first s1 limb
+ slw r3, r11, r8 C compute function return value
+ bdz L(end1)
+
+L(oop): lwzu r10, 4(r4)
+ srw r9, r11, r6
+ slw r12, r10, r8
+ or r9, r9, r12
+ stwu r9, 4(r7)
+ bdz L(end2)
+ lwzu r11, 4(r4)
+ srw r9, r10, r6
+ slw r12, r11, r8
+ or r9, r9, r12
+ stwu r9, 4(r7)
+ bdnz L(oop)
+
+L(end1):
+ srw r0, r11, r6
+ stw r0, 4(r7)
+ blr
+L(end2):
+ srw r0, r10, r6
+ stw r0, 4(r7)
+ blr
+
+L(BIG):
+ stmw r24, -32(r1) C save registers we are supposed to preserve
+ lwz r9, 0(r4)
+ subfic r8, r6, 32
+ slw r3, r9, r8 C compute function return value
+ srw r0, r9, r6
+ addi r5, r5, -1
+
+ andi. r10, r5, 3 C count for spill loop
+ beq L(e)
+ mtctr r10
+ lwzu r28, 4(r4)
+ bdz L(xe0)
+
+L(loop0):
+ srw r12, r28, r6
+ slw r24, r28, r8
+ lwzu r28, 4(r4)
+ or r24, r0, r24
+ stwu r24, 4(r7)
+ mr r0, r12
+ bdnz L(loop0) C taken at most once!
+
+L(xe0): srw r12, r28, r6
+ slw r24, r28, r8
+ or r24, r0, r24
+ stwu r24, 4(r7)
+ mr r0, r12
+
+L(e): srwi r5, r5, 2 C count for unrolled loop
+ addi r5, r5, -1
+ mtctr r5
+ lwz r28, 4(r4)
+ lwz r29, 8(r4)
+ lwz r30, 12(r4)
+ lwzu r31, 16(r4)
+
+L(loopU):
+ srw r9, r28, r6
+ slw r24, r28, r8
+ lwz r28, 4(r4)
+ srw r10, r29, r6
+ slw r25, r29, r8
+ lwz r29, 8(r4)
+ srw r11, r30, r6
+ slw r26, r30, r8
+ lwz r30, 12(r4)
+ srw r12, r31, r6
+ slw r27, r31, r8
+ lwzu r31, 16(r4)
+ or r24, r0, r24
+ stw r24, 4(r7)
+ or r25, r9, r25
+ stw r25, 8(r7)
+ or r26, r10, r26
+ stw r26, 12(r7)
+ or r27, r11, r27
+ stwu r27, 16(r7)
+ mr r0, r12
+ bdnz L(loopU)
+
+ srw r9, r28, r6
+ slw r24, r28, r8
+ srw r10, r29, r6
+ slw r25, r29, r8
+ srw r11, r30, r6
+ slw r26, r30, r8
+ srw r12, r31, r6
+ slw r27, r31, r8
+ or r24, r0, r24
+ stw r24, 4(r7)
+ or r25, r9, r25
+ stw r25, 8(r7)
+ or r26, r10, r26
+ stw r26, 12(r7)
+ or r27, r11, r27
+ stw r27, 16(r7)
+
+ stw r12, 20(r7)
+ lmw r24, -32(r1) C restore registers
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/sec_tabselect.asm b/gmp/mpn/powerpc32/sec_tabselect.asm
new file mode 100644
index 0000000000..a3f24d5678
--- /dev/null
+++ b/gmp/mpn/powerpc32/sec_tabselect.asm
@@ -0,0 +1,141 @@
+dnl PowerPC-32 mpn_sec_tabselect.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: ?
+C 75x (G3): ?
+C 7400,7410 (G4): 2.5
+C 744x,745x (G4+): 2.0
+C power4/ppc970: 2.0
+C power5: ?
+
+define(`rp', `r3')
+define(`tp', `r4')
+define(`n', `r5')
+define(`nents', `r6')
+define(`which', `r7')
+
+define(`i', `r8')
+define(`j', `r9')
+define(`stride', `r12')
+define(`mask', `r11')
+
+
+ASM_START()
+PROLOGUE(mpn_sec_tabselect)
+ addic. j, n, -4 C outer loop induction variable
+ stmw r27, -32(r1)
+ slwi stride, n, 2
+
+ blt cr0, L(outer_end)
+L(outer_top):
+ mtctr nents
+ mr r10, tp
+ li r28, 0
+ li r29, 0
+ li r30, 0
+ li r31, 0
+ addic. j, j, -4 C outer loop induction variable
+ mr i, which
+
+ ALIGN(16)
+L(top): addic i, i, -1 C set carry iff i != 0
+ subfe mask, mask, mask
+ lwz r0, 0(tp)
+ lwz r27, 4(tp)
+ and r0, r0, mask
+ and r27, r27, mask
+ or r28, r28, r0
+ or r29, r29, r27
+ lwz r0, 8(tp)
+ lwz r27, 12(tp)
+ and r0, r0, mask
+ and r27, r27, mask
+ or r30, r30, r0
+ or r31, r31, r27
+ add tp, tp, stride
+ bdnz L(top)
+
+ stw r28, 0(rp)
+ stw r29, 4(rp)
+ stw r30, 8(rp)
+ stw r31, 12(rp)
+ addi tp, r10, 16
+ addi rp, rp, 16
+ bge cr0, L(outer_top)
+L(outer_end):
+
+ andi. r0, n, 2
+ beq cr0, L(b0x)
+L(b1x): mtctr nents
+ mr r10, tp
+ li r28, 0
+ li r29, 0
+ mr i, which
+ ALIGN(16)
+L(tp2): addic i, i, -1
+ subfe mask, mask, mask
+ lwz r0, 0(tp)
+ lwz r27, 4(tp)
+ and r0, r0, mask
+ and r27, r27, mask
+ or r28, r28, r0
+ or r29, r29, r27
+ add tp, tp, stride
+ bdnz L(tp2)
+ stw r28, 0(rp)
+ stw r29, 4(rp)
+ addi tp, r10, 8
+ addi rp, rp, 8
+
+L(b0x): andi. r0, n, 1
+ beq cr0, L(b00)
+L(b01): mtctr nents
+ mr r10, tp
+ li r28, 0
+ mr i, which
+ ALIGN(16)
+L(tp1): addic i, i, -1
+ subfe mask, mask, mask
+ lwz r0, 0(tp)
+ and r0, r0, mask
+ or r28, r28, r0
+ add tp, tp, stride
+ bdnz L(tp1)
+ stw r28, 0(rp)
+
+L(b00): lmw r27, -32(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/sqr_diag_addlsh1.asm b/gmp/mpn/powerpc32/sqr_diag_addlsh1.asm
new file mode 100644
index 0000000000..f7aba33ee5
--- /dev/null
+++ b/gmp/mpn/powerpc32/sqr_diag_addlsh1.asm
@@ -0,0 +1,80 @@
+dnl PowerPC-32 mpn_sqr_diag_addlsh1.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e ?
+C 604e ?
+C 75x (G3) ?
+C 7400,7410 (G4) ?
+C 744x,745x (G4+) 6
+C power4/ppc970 ?
+C power5 ?
+
+C This has been feebly optimised for 7447 but not for any other CPU.
+
+define(`rp', r3)
+define(`tp', r4)
+define(`up', r5)
+define(`n', r6)
+
+ASM_START()
+PROLOGUE(mpn_sqr_diag_addlsh1)
+ addi n, n, -1
+ addi tp, tp, -4
+ mtctr n
+ lwz r0, 0(up)
+ li r10, 0
+ mullw r7, r0, r0
+ stw r7, 0(rp)
+ mulhwu r6, r0, r0
+ addic r31, r31, 0 C clear CF
+
+ ALIGN(16)
+L(top): lwzu r0, 4(up)
+ mullw r7, r0, r0
+ lwz r8, 4(tp)
+ lwzu r9, 8(tp)
+ rlwimi r10, r8, 1,0,30
+ srwi r11, r8, 31
+ rlwimi r11, r9, 1,0,30
+ adde r10, r10, r6
+ adde r11, r11, r7
+ stw r10, 4(rp)
+ srwi r10, r9, 31
+ mulhwu r6, r0, r0
+ stwu r11, 8(rp)
+ bdnz L(top)
+
+ adde r10, r10, r6
+ stw r10, 4(rp)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/sublsh1_n.asm b/gmp/mpn/powerpc32/sublsh1_n.asm
new file mode 100644
index 0000000000..6dc6460016
--- /dev/null
+++ b/gmp/mpn/powerpc32/sublsh1_n.asm
@@ -0,0 +1,101 @@
+dnl PowerPC-32 mpn_sublsh1_n -- rp[] = up[] - (vp[] << 1)
+
+dnl Copyright 2003, 2005, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: 4.0
+C 75x (G3): 5.0
+C 7400,7410 (G4): 5.0
+C 744x,745x (G4+): 5.0
+C power4/ppc970: 4.25
+C power5: 5.0
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C vp r5
+C n r6
+
+define(`rp',`r3')
+define(`up',`r4')
+define(`vp',`r5')
+
+define(`s0',`r6')
+define(`s1',`r7')
+define(`u0',`r8')
+define(`v0',`r10')
+define(`v1',`r11')
+
+ASM_START()
+PROLOGUE(mpn_sublsh1_n)
+ mtctr r6 C copy n in ctr
+
+ lwz v0, 0(vp) C load v limb
+ lwz u0, 0(up) C load u limb
+ addic up, up, -4 C update up; set cy
+ addi rp, rp, -4 C update rp
+ slwi s1, v0, 1
+ bdz L(end) C If done, skip loop
+
+L(loop):
+ lwz v1, 4(vp) C load v limb
+ subfe s1, s1, u0 C add limbs with cy, set cy
+ srwi s0, v0, 31 C shift down previous v limb
+ stw s1, 4(rp) C store result limb
+ lwzu u0, 8(up) C load u limb and update up
+ rlwimi s0, v1, 1, 0,30 C left shift v limb and merge with prev v limb
+
+ bdz L(exit) C decrement ctr and exit if done
+
+ lwzu v0, 8(vp) C load v limb and update vp
+ subfe s0, s0, u0 C add limbs with cy, set cy
+ srwi s1, v1, 31 C shift down previous v limb
+ stwu s0, 8(rp) C store result limb and update rp
+ lwz u0, 4(up) C load u limb
+ rlwimi s1, v0, 1, 0,30 C left shift v limb and merge with prev v limb
+
+ bdnz L(loop) C decrement ctr and loop back
+
+L(end): subfe r7, s1, u0
+ srwi r4, v0, 31
+ stw r7, 4(rp) C store last result limb
+ subfze r3, r4
+ neg r3, r3
+ blr
+L(exit):
+ subfe r7, s0, u0
+ srwi r4, v1, 31
+ stw r7, 8(rp) C store last result limb
+ subfze r3, r4
+ neg r3, r3
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/submul_1.asm b/gmp/mpn/powerpc32/submul_1.asm
new file mode 100644
index 0000000000..9fcdaa291b
--- /dev/null
+++ b/gmp/mpn/powerpc32/submul_1.asm
@@ -0,0 +1,147 @@
+dnl PowerPC-32 mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+dnl the result from a second limb vector.
+
+dnl Copyright 1995, 1997, 1998, 2000, 2002, 2005 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 603e: ?
+C 604e: 7.5
+C 75x (G3): 9.3-15
+C 7400,7410 (G4): 9.3-15
+C 744x,745x (G4+): 10.5
+C power4/ppc970: 6.75
+C power5: 6.5
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+C vl r6
+
+C This is optimized for the PPC604. See addmul_1.asm for additional comments.
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ cmpwi cr0,r5,9 C more than 9 limbs?
+ bgt cr0,L(big) C branch if more than 9 limbs
+
+ mtctr r5
+ lwz r0,0(r4)
+ mullw r7,r0,r6
+ mulhwu r10,r0,r6
+ lwz r9,0(r3)
+ subfc r8,r7,r9
+ addc r7,r7,r8 C invert cy (r7 is junk)
+ addi r3,r3,-4
+ bdz L(end)
+L(loop):
+ lwzu r0,4(r4)
+ stwu r8,4(r3)
+ mullw r8,r0,r6
+ adde r7,r8,r10
+ mulhwu r10,r0,r6
+ lwz r9,4(r3)
+ addze r10,r10
+ subfc r8,r7,r9
+ addc r7,r7,r8 C invert cy (r7 is junk)
+ bdnz L(loop)
+L(end): stw r8,4(r3)
+ addze r3,r10
+ blr
+
+L(big): stmw r30,-32(r1)
+ addi r5,r5,-1
+ srwi r0,r5,2
+ mtctr r0
+
+ lwz r7,0(r4)
+ mullw r8,r7,r6
+ mulhwu r0,r7,r6
+ lwz r7,0(r3)
+ subfc r7,r8,r7
+ addc r8,r8,r7
+ stw r7,0(r3)
+
+L(loopU):
+ lwz r7,4(r4)
+ lwz r12,8(r4)
+ lwz r30,12(r4)
+ lwzu r31,16(r4)
+ mullw r8,r7,r6
+ mullw r9,r12,r6
+ mullw r10,r30,r6
+ mullw r11,r31,r6
+ adde r8,r8,r0 C add cy_limb
+ mulhwu r0,r7,r6
+ lwz r7,4(r3)
+ adde r9,r9,r0
+ mulhwu r0,r12,r6
+ lwz r12,8(r3)
+ adde r10,r10,r0
+ mulhwu r0,r30,r6
+ lwz r30,12(r3)
+ adde r11,r11,r0
+ mulhwu r0,r31,r6
+ lwz r31,16(r3)
+ addze r0,r0 C new cy_limb
+ subfc r7,r8,r7
+ stw r7,4(r3)
+ subfe r12,r9,r12
+ stw r12,8(r3)
+ subfe r30,r10,r30
+ stw r30,12(r3)
+ subfe r31,r11,r31
+ stwu r31,16(r3)
+ subfe r11,r11,r11 C invert ...
+ addic r11,r11,1 C ... carry
+ bdnz L(loopU)
+
+ andi. r31,r5,3
+ mtctr r31
+ beq cr0,L(endx)
+
+L(loopE):
+ lwzu r7,4(r4)
+ mullw r8,r7,r6
+ adde r8,r8,r0 C add cy_limb
+ mulhwu r0,r7,r6
+ lwz r7,4(r3)
+ addze r0,r0 C new cy_limb
+ subfc r7,r8,r7
+ addc r8,r8,r7
+ stwu r7,4(r3)
+ bdnz L(loopE)
+L(endx):
+ addze r3,r0
+ lmw r30,-32(r1)
+ blr
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/powerpc32/umul.asm b/gmp/mpn/powerpc32/umul.asm
new file mode 100644
index 0000000000..a5811e1651
--- /dev/null
+++ b/gmp/mpn/powerpc32/umul.asm
@@ -0,0 +1,50 @@
+dnl PowerPC-32 umul_ppmm -- support for longlong.h
+
+dnl Copyright 2000, 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C mp_limb_t mpn_umul_ppmm (mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2);
+C
+
+ASM_START()
+PROLOGUE(mpn_umul_ppmm)
+
+ C r3 lowptr
+ C r4 m1
+ C r5 m2
+
+ mullw r0, r4, r5
+ mulhwu r9, r4, r5
+ stw r0, 0(r3)
+ mr r3, r9
+ blr
+
+EPILOGUE(mpn_umul_ppmm)
diff --git a/gmp/mpn/powerpc32/vmx/copyd.asm b/gmp/mpn/powerpc32/vmx/copyd.asm
new file mode 100644
index 0000000000..6aac6b8389
--- /dev/null
+++ b/gmp/mpn/powerpc32/vmx/copyd.asm
@@ -0,0 +1,203 @@
+dnl PowerPC-32/VMX and PowerPC-64/VMX mpn_copyd.
+
+dnl Copyright 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C 16-byte coaligned unaligned
+C cycles/limb cycles/limb
+C 7400,7410 (G4): 0.5 0.64
+C 744x,745x (G4+): 0.75 0.82
+C 970 (G5): 0.78 1.02 (64-bit limbs)
+
+C STATUS
+C * Works for all sizes and alignments.
+
+C TODO
+C * Optimize unaligned case. Some basic tests with 2-way and 4-way unrolling
+C indicate that we can reach 0.56 c/l for 7400, 0.75 c/l for 745x, and 0.80
+C c/l for 970.
+C * Consider using VMX instructions also for head and tail, by using some
+C read-modify-write tricks.
+C * The VMX code is used from the smallest sizes it handles, but measurements
+C show a large speed bump at the cutoff points. Small copying (perhaps
+C using some read-modify-write technique) should be optimized.
+C * Make a mpn_com based on this code.
+
+define(`GMP_LIMB_BYTES', eval(GMP_LIMB_BITS/8))
+define(`LIMBS_PER_VR', eval(16/GMP_LIMB_BYTES))
+define(`LIMBS_PER_2VR', eval(32/GMP_LIMB_BYTES))
+
+
+ifelse(GMP_LIMB_BITS,32,`
+ define(`LIMB32',` $1')
+ define(`LIMB64',`')
+',`
+ define(`LIMB32',`')
+ define(`LIMB64',` $1')
+')
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+
+define(`us', `v4')
+
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+
+LIMB32(`slwi. r0, n, 2 ')
+LIMB64(`sldi. r0, n, 3 ')
+ add rp, rp, r0
+ add up, up, r0
+
+LIMB32(`cmpi cr7, n, 11 ')
+LIMB64(`cmpdi cr7, n, 5 ')
+ bge cr7, L(big)
+
+ beqlr cr0
+
+C Handle small cases with plain operations
+ mtctr n
+L(topS):
+LIMB32(`lwz r0, -4(up) ')
+LIMB64(`ld r0, -8(up) ')
+ addi up, up, -GMP_LIMB_BYTES
+LIMB32(`stw r0, -4(rp) ')
+LIMB64(`std r0, -8(rp) ')
+ addi rp, rp, -GMP_LIMB_BYTES
+ bdnz L(topS)
+ blr
+
+C Handle large cases with VMX operations
+L(big):
+ addi rp, rp, -16
+ addi up, up, -16
+ mfspr r12, 256
+ oris r0, r12, 0xf800 C Set VRSAVE bit 0-4
+ mtspr 256, r0
+
+LIMB32(`rlwinm. r7, rp, 30,30,31') C (rp >> 2) mod 4
+LIMB64(`rlwinm. r7, rp, 29,31,31') C (rp >> 3) mod 2
+ beq L(rp_aligned)
+
+ subf n, r7, n
+L(top0):
+LIMB32(`lwz r0, 12(up) ')
+LIMB64(`ld r0, 8(up) ')
+ addi up, up, -GMP_LIMB_BYTES
+LIMB32(`addic. r7, r7, -1 ')
+LIMB32(`stw r0, 12(rp) ')
+LIMB64(`std r0, 8(rp) ')
+ addi rp, rp, -GMP_LIMB_BYTES
+LIMB32(`bne L(top0) ')
+
+L(rp_aligned):
+
+LIMB32(`rlwinm. r0, up, 30,30,31') C (up >> 2) mod 4
+LIMB64(`rlwinm. r0, up, 29,31,31') C (up >> 3) mod 2
+
+LIMB64(`srdi r7, n, 2 ') C loop count corresponding to n
+LIMB32(`srwi r7, n, 3 ') C loop count corresponding to n
+ mtctr r7 C copy n to count register
+
+ li r10, -16
+
+ beq L(up_aligned)
+
+ lvsl us, 0, up
+
+ addi up, up, 16
+LIMB32(`andi. r0, n, 0x4 ')
+LIMB64(`andi. r0, n, 0x2 ')
+ beq L(1)
+ lvx v0, 0, up
+ lvx v2, r10, up
+ vperm v3, v2, v0, us
+ stvx v3, 0, rp
+ addi up, up, -32
+ addi rp, rp, -16
+ b L(lpu)
+L(1): lvx v2, 0, up
+ addi up, up, -16
+ b L(lpu)
+
+ ALIGN(32)
+L(lpu): lvx v0, 0, up
+ vperm v3, v0, v2, us
+ stvx v3, 0, rp
+ lvx v2, r10, up
+ addi up, up, -32
+ vperm v3, v2, v0, us
+ stvx v3, r10, rp
+ addi rp, rp, -32
+ bdnz L(lpu)
+
+ b L(tail)
+
+L(up_aligned):
+
+LIMB32(`andi. r0, n, 0x4 ')
+LIMB64(`andi. r0, n, 0x2 ')
+ beq L(lpa)
+ lvx v0, 0, up
+ stvx v0, 0, rp
+ addi up, up, -16
+ addi rp, rp, -16
+ b L(lpa)
+
+ ALIGN(32)
+L(lpa): lvx v0, 0, up
+ lvx v1, r10, up
+ addi up, up, -32
+ nop
+ stvx v0, 0, rp
+ stvx v1, r10, rp
+ addi rp, rp, -32
+ bdnz L(lpa)
+
+L(tail):
+LIMB32(`rlwinm. r7, n, 0,30,31 ') C r7 = n mod 4
+LIMB64(`rlwinm. r7, n, 0,31,31 ') C r7 = n mod 2
+ beq L(ret)
+LIMB32(`li r10, 12 ')
+L(top2):
+LIMB32(`lwzx r0, r10, up ')
+LIMB64(`ld r0, 8(up) ')
+LIMB32(`addic. r7, r7, -1 ')
+LIMB32(`stwx r0, r10, rp ')
+LIMB64(`std r0, 8(rp) ')
+LIMB32(`addi r10, r10, -GMP_LIMB_BYTES')
+LIMB32(`bne L(top2) ')
+
+L(ret): mtspr 256, r12
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/vmx/copyi.asm b/gmp/mpn/powerpc32/vmx/copyi.asm
new file mode 100644
index 0000000000..a97a0fa6dc
--- /dev/null
+++ b/gmp/mpn/powerpc32/vmx/copyi.asm
@@ -0,0 +1,198 @@
+dnl PowerPC-32/VMX and PowerPC-64/VMX mpn_copyi.
+
+dnl Copyright 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C 16-byte coaligned unaligned
+C cycles/limb cycles/limb
+C 7400,7410 (G4): 0.5 0.64
+C 744x,745x (G4+): 0.75 0.82
+C 970 (G5): 0.78 1.02 (64-bit limbs)
+
+C STATUS
+C * Works for all sizes and alignments.
+
+C TODO
+C * Optimize unaligned case. Some basic tests with 2-way and 4-way unrolling
+C indicate that we can reach 0.56 c/l for 7400, 0.75 c/l for 745x, and 0.80
+C c/l for 970.
+C * Consider using VMX instructions also for head and tail, by using some
+C read-modify-write tricks.
+C * The VMX code is used from the smallest sizes it handles, but measurements
+C show a large speed bump at the cutoff points. Small copying (perhaps
+C using some read-modify-write technique) should be optimized.
+C * Make a mpn_com based on this code.
+
+define(`GMP_LIMB_BYTES', eval(GMP_LIMB_BITS/8))
+define(`LIMBS_PER_VR', eval(16/GMP_LIMB_BYTES))
+define(`LIMBS_PER_2VR', eval(32/GMP_LIMB_BYTES))
+
+
+ifelse(GMP_LIMB_BITS,32,`
+ define(`LIMB32',` $1')
+ define(`LIMB64',`')
+',`
+ define(`LIMB32',`')
+ define(`LIMB64',` $1')
+')
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+
+define(`us', `v4')
+
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+
+LIMB32(`cmpi cr7, n, 11 ')
+LIMB64(`cmpdi cr7, n, 5 ')
+ bge cr7, L(big)
+
+ or. r0, n, n
+ beqlr cr0
+
+C Handle small cases with plain operations
+ mtctr n
+L(topS):
+LIMB32(`lwz r0, 0(up) ')
+LIMB64(`ld r0, 0(up) ')
+ addi up, up, GMP_LIMB_BYTES
+LIMB32(`stw r0, 0(rp) ')
+LIMB64(`std r0, 0(rp) ')
+ addi rp, rp, GMP_LIMB_BYTES
+ bdnz L(topS)
+ blr
+
+C Handle large cases with VMX operations
+L(big):
+ mfspr r12, 256
+ oris r0, r12, 0xf800 C Set VRSAVE bit 0-4
+ mtspr 256, r0
+
+LIMB32(`rlwinm. r7, rp, 30,30,31') C (rp >> 2) mod 4
+LIMB64(`rlwinm. r7, rp, 29,31,31') C (rp >> 3) mod 2
+ beq L(rp_aligned)
+
+ subfic r7, r7, LIMBS_PER_VR
+ subf n, r7, n
+L(top0):
+LIMB32(`lwz r0, 0(up) ')
+LIMB64(`ld r0, 0(up) ')
+ addi up, up, GMP_LIMB_BYTES
+LIMB32(`addic. r7, r7, -1 ')
+LIMB32(`stw r0, 0(rp) ')
+LIMB64(`std r0, 0(rp) ')
+ addi rp, rp, GMP_LIMB_BYTES
+LIMB32(`bne L(top0) ')
+
+L(rp_aligned):
+
+LIMB32(`rlwinm. r0, up, 30,30,31') C (up >> 2) mod 4
+LIMB64(`rlwinm. r0, up, 29,31,31') C (up >> 3) mod 2
+
+LIMB64(`srdi r7, n, 2 ') C loop count corresponding to n
+LIMB32(`srwi r7, n, 3 ') C loop count corresponding to n
+ mtctr r7 C copy n to count register
+
+ li r10, 16
+
+ beq L(up_aligned)
+
+ lvsl us, 0, up
+
+LIMB32(`andi. r0, n, 0x4 ')
+LIMB64(`andi. r0, n, 0x2 ')
+ beq L(1)
+ lvx v0, 0, up
+ lvx v2, r10, up
+ vperm v3, v0, v2, us
+ stvx v3, 0, rp
+ addi up, up, 32
+ addi rp, rp, 16
+ b L(lpu)
+L(1): lvx v2, 0, up
+ addi up, up, 16
+ b L(lpu)
+
+ ALIGN(32)
+L(lpu): lvx v0, 0, up
+ vperm v3, v2, v0, us
+ stvx v3, 0, rp
+ lvx v2, r10, up
+ addi up, up, 32
+ vperm v3, v0, v2, us
+ stvx v3, r10, rp
+ addi rp, rp, 32
+ bdnz L(lpu)
+
+ addi up, up, -16
+ b L(tail)
+
+L(up_aligned):
+
+LIMB32(`andi. r0, n, 0x4 ')
+LIMB64(`andi. r0, n, 0x2 ')
+ beq L(lpa)
+ lvx v0, 0, up
+ stvx v0, 0, rp
+ addi up, up, 16
+ addi rp, rp, 16
+ b L(lpa)
+
+ ALIGN(32)
+L(lpa): lvx v0, 0, up
+ lvx v1, r10, up
+ addi up, up, 32
+ nop
+ stvx v0, 0, rp
+ stvx v1, r10, rp
+ addi rp, rp, 32
+ bdnz L(lpa)
+
+L(tail):
+LIMB32(`rlwinm. r7, n, 0,30,31 ') C r7 = n mod 4
+LIMB64(`rlwinm. r7, n, 0,31,31 ') C r7 = n mod 2
+ beq L(ret)
+LIMB32(`li r10, 0 ')
+L(top2):
+LIMB32(`lwzx r0, r10, up ')
+LIMB64(`ld r0, 0(up) ')
+LIMB32(`addic. r7, r7, -1 ')
+LIMB32(`stwx r0, r10, rp ')
+LIMB64(`std r0, 0(rp) ')
+LIMB32(`addi r10, r10, GMP_LIMB_BYTES')
+LIMB32(`bne L(top2) ')
+
+L(ret): mtspr 256, r12
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc32/vmx/logops_n.asm b/gmp/mpn/powerpc32/vmx/logops_n.asm
new file mode 100644
index 0000000000..d656d3b73f
--- /dev/null
+++ b/gmp/mpn/powerpc32/vmx/logops_n.asm
@@ -0,0 +1,310 @@
+dnl PowerPC-32/VMX and PowerPC-64/VMX mpn_and_n, mpn_andn_n, mpn_nand_n,
+dnl mpn_ior_n, mpn_iorn_n, mpn_nior_n, mpn_xor_n, mpn_xnor_n -- mpn bitwise
+dnl logical operations.
+
+dnl Copyright 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C and,ior,andn,nior,xor iorn,xnor nand
+C cycles/limb cycles/limb cycles/limb
+C 7400,7410 (G4): 1.39 ? ?
+C 744x,745x (G4+): 1.14 1.39 1.39
+C 970: 1.7 2.0 2.0
+
+C STATUS
+C * Works for all sizes and alignment for 32-bit limbs.
+C * Works for n >= 4 for 64-bit limbs; untested for smaller operands.
+C * Current performance makes this pointless for 970
+
+C TODO
+C * Might want to make variants when just one of the source operands needs
+C vperm, and when neither needs it. The latter runs 50% faster on 7400.
+C * Idea: If the source operands are equally aligned, we could do the logops
+C first, then vperm before storing! That means we never need more than one
+C vperm, ever!
+C * Perhaps align `rp' after initial alignment loop?
+C * Instead of having scalar code in the beginning and end, consider using
+C read-modify-write vector code.
+C * Software pipeline? Hopefully not too important, this is hairy enough
+C already.
+C * At least be more clever about operand loading, i.e., load v operands before
+C u operands, since v operands are sometimes negated.
+
+define(`GMP_LIMB_BYTES', eval(GMP_LIMB_BITS/8))
+define(`LIMBS_PER_VR', eval(16/GMP_LIMB_BYTES))
+define(`LIMBS_PER_2VR', eval(32/GMP_LIMB_BYTES))
+
+define(`vnegb', `') C default neg-before to null
+define(`vnega', `') C default neg-before to null
+
+ifdef(`OPERATION_and_n',
+` define(`func', `mpn_and_n')
+ define(`logopS',`and $1,$2,$3')
+ define(`logop', `vand $1,$2,$3')')
+ifdef(`OPERATION_andn_n',
+` define(`func', `mpn_andn_n')
+ define(`logopS',`andc $1,$2,$3')
+ define(`logop', `vandc $1,$2,$3')')
+ifdef(`OPERATION_nand_n',
+` define(`func', `mpn_nand_n')
+ define(`logopS',`nand $1,$2,$3')
+ define(`logop', `vand $1,$2,$3')
+ define(`vnega', `vnor $1,$2,$2')')
+ifdef(`OPERATION_ior_n',
+` define(`func', `mpn_ior_n')
+ define(`logopS',`or $1,$2,$3')
+ define(`logop', `vor $1,$2,$3')')
+ifdef(`OPERATION_iorn_n',
+` define(`func', `mpn_iorn_n')
+ define(`logopS',`orc $1,$2,$3')
+ define(`vnegb', `vnor $1,$2,$2')
+ define(`logop', `vor $1,$2,$3')')
+ifdef(`OPERATION_nior_n',
+` define(`func', `mpn_nior_n')
+ define(`logopS',`nor $1,$2,$3')
+ define(`logop', `vnor $1,$2,$3')')
+ifdef(`OPERATION_xor_n',
+` define(`func', `mpn_xor_n')
+ define(`logopS',`xor $1,$2,$3')
+ define(`logop', `vxor $1,$2,$3')')
+ifdef(`OPERATION_xnor_n',
+` define(`func',`mpn_xnor_n')
+ define(`logopS',`eqv $1,$2,$3')
+ define(`vnegb', `vnor $1,$2,$2')
+ define(`logop', `vxor $1,$2,$3')')
+
+ifelse(GMP_LIMB_BITS,`32',`
+ define(`LIMB32',` $1')
+ define(`LIMB64',`')
+',`
+ define(`LIMB32',`')
+ define(`LIMB64',` $1')
+')
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`vp', `r5')
+define(`n', `r6')
+
+define(`us', `v8')
+define(`vs', `v9')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+ASM_START()
+PROLOGUE(func)
+
+LIMB32(`cmpwi cr0, n, 8 ')
+LIMB64(`cmpdi cr0, n, 4 ')
+ bge L(big)
+
+ mtctr n
+
+LIMB32(`lwz r8, 0(up) ')
+LIMB32(`lwz r9, 0(vp) ')
+LIMB32(`logopS( r0, r8, r9) ')
+LIMB32(`stw r0, 0(rp) ')
+LIMB32(`bdz L(endS) ')
+
+L(topS):
+LIMB32(`lwzu r8, 4(up) ')
+LIMB64(`ld r8, 0(up) ')
+LIMB64(`addi up, up, GMP_LIMB_BYTES ')
+LIMB32(`lwzu r9, 4(vp) ')
+LIMB64(`ld r9, 0(vp) ')
+LIMB64(`addi vp, vp, GMP_LIMB_BYTES ')
+ logopS( r0, r8, r9)
+LIMB32(`stwu r0, 4(rp) ')
+LIMB64(`std r0, 0(rp) ')
+LIMB64(`addi rp, rp, GMP_LIMB_BYTES ')
+ bdnz L(topS)
+L(endS):
+ blr
+
+L(big): mfspr r12, 256
+ oris r0, r12, 0xfffc C Set VRSAVE bit 0-13 FIXME
+ mtspr 256, r0
+
+C First loop until the destination is 16-byte aligned. This will execute 0 or 1
+C times for 64-bit machines, and 0 to 3 times for 32-bit machines.
+
+LIMB32(`rlwinm. r0, rp, 30,30,31') C (rp >> 2) mod 4
+LIMB64(`rlwinm. r0, rp, 29,31,31') C (rp >> 3) mod 2
+ beq L(aligned)
+
+ subfic r7, r0, LIMBS_PER_VR
+LIMB32(`li r10, 0 ')
+ subf n, r7, n
+L(top0):
+LIMB32(`lwz r8, 0(up) ')
+LIMB64(`ld r8, 0(up) ')
+ addi up, up, GMP_LIMB_BYTES
+LIMB32(`lwz r9, 0(vp) ')
+LIMB64(`ld r9, 0(vp) ')
+ addi vp, vp, GMP_LIMB_BYTES
+LIMB32(`addic. r7, r7, -1 ')
+ logopS( r0, r8, r9)
+LIMB32(`stwx r0, r10, rp ')
+LIMB64(`std r0, 0(rp) ')
+LIMB32(`addi r10, r10, GMP_LIMB_BYTES')
+LIMB32(`bne L(top0) ')
+
+ addi rp, rp, 16 C update rp, but preserve its alignment
+
+L(aligned):
+LIMB64(`srdi r7, n, 1 ') C loop count corresponding to n
+LIMB32(`srwi r7, n, 2 ') C loop count corresponding to n
+ mtctr r7 C copy n to count register
+
+ li r10, 16
+ lvsl us, 0, up
+ lvsl vs, 0, vp
+
+ lvx v2, 0, up
+ lvx v3, 0, vp
+ bdnz L(gt1)
+ lvx v0, r10, up
+ lvx v1, r10, vp
+ vperm v4, v2, v0, us
+ vperm v5, v3, v1, vs
+ vnegb( v5, v5)
+ logop( v6, v4, v5)
+ vnega( v6, v6)
+ stvx v6, 0, rp
+ addi up, up, 16
+ addi vp, vp, 16
+ addi rp, rp, 4
+ b L(tail)
+
+L(gt1): addi up, up, 16
+ addi vp, vp, 16
+
+L(top): lvx v0, 0, up
+ lvx v1, 0, vp
+ vperm v4, v2, v0, us
+ vperm v5, v3, v1, vs
+ vnegb( v5, v5)
+ logop( v6, v4, v5)
+ vnega( v6, v6)
+ stvx v6, 0, rp
+ bdz L(end)
+ lvx v2, r10, up
+ lvx v3, r10, vp
+ vperm v4, v0, v2, us
+ vperm v5, v1, v3, vs
+ vnegb( v5, v5)
+ logop( v6, v4, v5)
+ vnega( v6, v6)
+ stvx v6, r10, rp
+ addi up, up, 32
+ addi vp, vp, 32
+ addi rp, rp, 32
+ bdnz L(top)
+
+ andi. r0, up, 15
+ vxor v0, v0, v0
+ beq 1f
+ lvx v0, 0, up
+1: andi. r0, vp, 15
+ vxor v1, v1, v1
+ beq 1f
+ lvx v1, 0, vp
+1: vperm v4, v2, v0, us
+ vperm v5, v3, v1, vs
+ vnegb( v5, v5)
+ logop( v6, v4, v5)
+ vnega( v6, v6)
+ stvx v6, 0, rp
+ addi rp, rp, 4
+ b L(tail)
+
+L(end): andi. r0, up, 15
+ vxor v2, v2, v2
+ beq 1f
+ lvx v2, r10, up
+1: andi. r0, vp, 15
+ vxor v3, v3, v3
+ beq 1f
+ lvx v3, r10, vp
+1: vperm v4, v0, v2, us
+ vperm v5, v1, v3, vs
+ vnegb( v5, v5)
+ logop( v6, v4, v5)
+ vnega( v6, v6)
+ stvx v6, r10, rp
+
+ addi up, up, 16
+ addi vp, vp, 16
+ addi rp, rp, 20
+
+L(tail):
+LIMB32(`rlwinm. r7, n, 0,30,31 ') C r7 = n mod 4
+LIMB64(`rlwinm. r7, n, 0,31,31 ') C r7 = n mod 2
+ beq L(ret)
+ addi rp, rp, 15
+LIMB32(`rlwinm rp, rp, 0,0,27 ')
+LIMB64(`rldicr rp, rp, 0,59 ')
+ li r10, 0
+L(top2):
+LIMB32(`lwzx r8, r10, up ')
+LIMB64(`ldx r8, r10, up ')
+LIMB32(`lwzx r9, r10, vp ')
+LIMB64(`ldx r9, r10, vp ')
+LIMB32(`addic. r7, r7, -1 ')
+ logopS( r0, r8, r9)
+LIMB32(`stwx r0, r10, rp ')
+LIMB64(`std r0, 0(rp) ')
+LIMB32(`addi r10, r10, GMP_LIMB_BYTES')
+LIMB32(`bne L(top2) ')
+
+L(ret): mtspr 256, r12
+ blr
+EPILOGUE()
+
+C This works for 64-bit PowerPC, since a limb ptr can only be aligned
+C in 2 relevant ways, which means we can always find a pair of aligned
+C pointers of rp, up, and vp.
+C process words until rp is 16-byte aligned
+C if (((up | vp) & 15) == 0)
+C process with VMX without any vperm
+C else if ((up & 15) != 0 && (vp & 15) != 0)
+C process with VMX using vperm on store data
+C else if ((up & 15) != 0)
+C process with VMX using vperm on up data
+C else
+C process with VMX using vperm on vp data
+C
+C rlwinm, r0, up, 0,28,31
+C rlwinm r0, vp, 0,28,31
+C cmpwi cr7, r0, 0
+C cror cr6, cr0, cr7
+C crand cr0, cr0, cr7
diff --git a/gmp/mpn/powerpc32/vmx/mod_34lsub1.asm b/gmp/mpn/powerpc32/vmx/mod_34lsub1.asm
new file mode 100644
index 0000000000..9b7e4f1a50
--- /dev/null
+++ b/gmp/mpn/powerpc32/vmx/mod_34lsub1.asm
@@ -0,0 +1,386 @@
+dnl PowerPC-32 mpn_mod_34lsub1 -- mpn remainder mod 2^24-1.
+
+dnl Copyright 2002, 2003, 2005-2007, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+
+C cycles/limb
+C 603e: -
+C 604e: -
+C 75x (G3): -
+C 7400,7410 (G4): 1 simple load-use scheduling results in 0.75
+C 744x,745x (G4+): 0.75
+C ppc970: 0.75
+C power4: -
+C power5: -
+
+C TODO
+C * Either start using the low-end masking constants, or remove them.
+C * Merge multiple feed-in cases into a parameterized code block.
+C * Reduce register usage. It should be possible to almost halve it.
+
+define(`up', `r3')
+define(`n', `r4')
+
+define(`a0', `v3')
+define(`a1', `v4')
+define(`a2', `v5')
+define(`c0', `v6')
+define(`c1', `v7')
+define(`c2', `v8')
+define(`z', `v9')
+define(`x0', `v10')
+define(`x1', `v11')
+define(`x2', `v12')
+define(`x3', `v13')
+define(`pv', `v14')
+define(`y0', `v0')
+define(`y1', `v1')
+define(`y2', `v2')
+define(`y3', `v15')
+
+ASM_START()
+PROLOGUE(mpn_mod_34lsub1)
+ cmpwi cr0, n, 20 C tuned cutoff point
+ bge L(large)
+
+ li r9, 0 C result accumulator
+ mulli r10, n, 0xb C 0xb = ceil(32/3)
+ srwi. r10, r10, 5 C r10 = floor(n/3), n < 32
+ beq L(small_tail)
+ mtctr r10
+ lwz r6, 0(up)
+ lwz r7, 4(up)
+ lwzu r8, 8(up)
+ subf n, r10, n
+ subf n, r10, n
+ subf n, r10, n
+ bdz L(small_end)
+
+ ALIGN(16)
+L(los): rlwinm r0, r6, 0,8,31
+ add r9, r9, r0 C add 24b from u0
+ srwi r0, r6, 24
+ lwz r6, 4(up)
+ rlwimi r0, r7, 8, 0x00ffff00 C --111100
+ add r9, r9, r0 C add 8b from u0 and 16b from u1
+ srwi r0, r7, 16
+ lwz r7, 8(up)
+ rlwimi r0, r8, 16, 0x00ff0000 C --221111
+ add r9, r9, r0 C add 16b from u1 and 8b from u2
+ srwi r0, r8, 8 C --222222
+ lwzu r8, 12(up)
+ add r9, r9, r0 C add 24b from u2
+ bdnz L(los)
+L(small_end):
+ rlwinm r0, r6, 0,8,31
+ add r9, r9, r0 C add 24b from u0
+ srwi r0, r6, 24
+ rlwimi r0, r7, 8, 0x00ffff00 C --111100
+ add r9, r9, r0 C add 8b from u0 and 16b from u1
+ srwi r0, r7, 16
+ rlwimi r0, r8, 16, 0x00ff0000 C --221111
+ add r9, r9, r0 C add 16b from u1 and 8b from u2
+ srwi r0, r8, 8 C --222222
+ add r9, r9, r0 C add 24b from u2
+
+ addi up, up, 4
+ rlwinm r0, r9, 0,8,31
+ srwi r9, r9, 24
+ add r9, r9, r0
+
+L(small_tail):
+ cmpi cr0, n, 1
+ blt L(ret)
+
+ lwz r6, 0(up)
+ rlwinm r0, r6, 0,8,31
+ srwi r6, r6, 24
+ add r9, r9, r0
+ add r9, r9, r6
+
+ beq L(ret)
+
+ lwz r6, 4(up)
+ rlwinm r0, r6, 8,8,23
+ srwi r6, r6, 16
+ add r9, r9, r0
+ add r9, r9, r6
+
+L(ret): mr r3, r9
+ blr
+
+
+L(large):
+ mfspr r10, 256
+ oris r0, r10, 0xffff C Set VRSAVE bit 0-15
+ mtspr 256, r0
+
+ andi. r7, up, 15
+ vxor a0, v0, v0
+ lis r9, 0xaaaa
+ vxor a1, v0, v0
+ ori r9, r9, 0xaaab
+ vxor a2, v0, v0
+ li r5, 16
+ vxor c0, v0, v0
+ li r6, 32
+ vxor c1, v0, v0
+ LEAL( r11, cnsts) C CAUTION clobbers r0 for elf, darwin
+ vxor c2, v0, v0
+ vxor z, v0, v0
+
+ beq L(aligned16)
+
+ cmpwi cr7, r7, 8
+ bge cr7, L(na4)
+
+ lvx a2, 0, up
+ addi up, up, 16
+ vsldoi a2, a2, z, 4
+ vsldoi a2, z, a2, 12
+
+ addi n, n, 9
+ mulhwu r0, n, r9
+ srwi r0, r0, 3 C r0 = floor(n/12)
+ mtctr r0
+
+ mulli r8, r0, 12
+ subf n, r8, n
+ b L(2)
+
+L(na4): bne cr7, L(na8)
+
+ lvx a1, 0, up
+ addi up, up, -16
+ vsldoi a1, a1, z, 8
+ vsldoi a1, z, a1, 8
+
+ addi n, n, 6
+ mulhwu r0, n, r9
+ srwi r0, r0, 3 C r0 = floor(n/12)
+ mtctr r0
+
+ mulli r8, r0, 12
+ subf n, r8, n
+ b L(1)
+
+L(na8):
+ lvx a0, 0, up
+ vsldoi a0, a0, z, 12
+ vsldoi a0, z, a0, 4
+
+ addi n, n, 3
+ mulhwu r0, n, r9
+ srwi r0, r0, 3 C r0 = floor(n/12)
+ mtctr r0
+
+ mulli r8, r0, 12
+ subf n, r8, n
+ b L(0)
+
+L(aligned16):
+ mulhwu r0, n, r9
+ srwi r0, r0, 3 C r0 = floor(n/12)
+ mtctr r0
+
+ mulli r8, r0, 12
+ subf n, r8, n
+
+ lvx a0, 0, up
+L(0): lvx a1, r5, up
+L(1): lvx a2, r6, up
+ addi up, up, 48
+L(2): bdz L(end)
+ li r12, 256
+ li r9, 288
+ ALIGN(32)
+L(top):
+ lvx v0, 0, up
+ vaddcuw v10, a0, v0
+ vadduwm a0, a0, v0
+ vadduwm c0, c0, v10
+
+ lvx v1, r5, up
+ vaddcuw v10, a1, v1
+ vadduwm a1, a1, v1
+ vadduwm c1, c1, v10
+
+ lvx v2, r6, up
+ dcbt up, r12
+ dcbt up, r9
+ addi up, up, 48
+ vaddcuw v10, a2, v2
+ vadduwm a2, a2, v2
+ vadduwm c2, c2, v10
+ bdnz L(top)
+
+L(end):
+C n = 0...11
+ cmpwi cr0, n, 0
+ beq L(sum)
+ cmpwi cr0, n, 4
+ ble L(tail.1..4)
+ cmpwi cr0, n, 8
+ ble L(tail.5..8)
+
+L(tail.9..11):
+ lvx v0, 0, up
+ vaddcuw v10, a0, v0
+ vadduwm a0, a0, v0
+ vadduwm c0, c0, v10
+
+ lvx v1, r5, up
+ vaddcuw v10, a1, v1
+ vadduwm a1, a1, v1
+ vadduwm c1, c1, v10
+
+ lvx v2, r6, up
+
+ addi r8, r11, 96
+ rlwinm r3, n ,4,26,27
+ lvx v11, r3, r8
+ vand v2, v2, v11
+
+ vaddcuw v10, a2, v2
+ vadduwm a2, a2, v2
+ vadduwm c2, c2, v10
+ b L(sum)
+
+L(tail.5..8):
+ lvx v0, 0, up
+ vaddcuw v10, a0, v0
+ vadduwm a0, a0, v0
+ vadduwm c0, c0, v10
+
+ lvx v1, r5, up
+
+ addi r8, r11, 96
+ rlwinm r3, n ,4,26,27
+ lvx v11, r3, r8
+ vand v1, v1, v11
+
+ vaddcuw v10, a1, v1
+ vadduwm a1, a1, v1
+ vadduwm c1, c1, v10
+ b L(sum)
+
+L(tail.1..4):
+ lvx v0, 0, up
+
+ addi r8, r11, 96
+ rlwinm r3, n ,4,26,27
+ lvx v11, r3, r8
+ vand v0, v0, v11
+
+ vaddcuw v10, a0, v0
+ vadduwm a0, a0, v0
+ vadduwm c0, c0, v10
+
+L(sum): lvx pv, 0, r11
+ vperm x0, a0, z, pv C extract 4 24-bit field from a0
+ vperm y0, c2, z, pv
+ lvx pv, r5, r11
+ vperm x1, a1, z, pv C extract 4 24-bit field from a1
+ vperm y1, c0, z, pv C extract 4 24-bit field from a1
+ lvx pv, r6, r11
+ vperm x2, a2, z, pv C extract 4 24-bit field from a1
+ vperm y2, c1, z, pv C extract 4 24-bit field from a1
+ li r10, 48
+ lvx pv, r10, r11
+ vperm x3, a0, z, pv C extract remaining/partial a0 fields
+ vperm y3, c2, z, pv C extract remaining/partial a0 fields
+ li r10, 64
+ lvx pv, r10, r11
+ vperm x3, a1, x3, pv C insert remaining/partial a1 fields
+ vperm y3, c0, y3, pv C insert remaining/partial a1 fields
+ li r10, 80
+ lvx pv, r10, r11
+ vperm x3, a2, x3, pv C insert remaining/partial a2 fields
+ vperm y3, c1, y3, pv C insert remaining/partial a2 fields
+
+C We now have 4 128-bit accumulators to sum
+ vadduwm x0, x0, x1
+ vadduwm x2, x2, x3
+ vadduwm x0, x0, x2
+
+ vadduwm y0, y0, y1
+ vadduwm y2, y2, y3
+ vadduwm y0, y0, y2
+
+ vadduwm x0, x0, y0
+
+C Reduce 32-bit fields
+ vsumsws x0, x0, z
+
+ li r7, -16 C FIXME: does all ppc32 ABIs...
+ stvx x0, r7, r1 C FIXME: ...support storing below sp?
+ lwz r3, -4(r1)
+
+ mtspr 256, r10
+ blr
+EPILOGUE()
+
+C load | v0 | v1 | v2 |
+C acc | a0 | a1 | a2 |
+C carry | c0 | c1 | c2 |
+C | 0 1 2 3 | 4 5 6 7 | 8 9 10 11 | 128
+C |---|---|---|---|---|---|---|---|---|---|---|---| 32
+C | | | | | | | | | | | | | | | | | 24
+C | | | | | | | | | 48
+
+C $---------------$---------------$---------------$---------------$
+C | . . . . . . . . . . . . . . . |
+C |_______________________________________________________________|
+C | | | | | | |
+C <-hi16-> <--- 24 --> <--- 24 --> <--- 24 --> <--- 24 --> <-lo16->
+
+
+DEF_OBJECT(cnsts,16)
+C Permutation vectors in the order they are used above
+C # 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
+ .byte 0x10,0x01,0x02,0x03, 0x10,0x06,0x07,0x00, 0x10,0x0b,0x04,0x05, 0x10,0x08,0x09,0x0a C a0
+ .byte 0x10,0x07,0x00,0x01, 0x10,0x04,0x05,0x06, 0x10,0x09,0x0a,0x0b, 0x10,0x0e,0x0f,0x08 C a1
+ .byte 0x10,0x00,0x01,0x02, 0x10,0x05,0x06,0x07, 0x10,0x0a,0x0b,0x04, 0x10,0x0f,0x08,0x09 C a2
+ .byte 0x10,0x0d,0x0e,0x0f, 0x10,0x10,0x10,0x0c, 0x10,0x10,0x10,0x10, 0x10,0x10,0x10,0x10 C part a0
+ .byte 0x10,0x11,0x12,0x13, 0x10,0x02,0x03,0x17, 0x10,0x10,0x0c,0x0d, 0x10,0x10,0x10,0x10 C part a1
+ .byte 0x10,0x11,0x12,0x13, 0x10,0x15,0x16,0x17, 0x10,0x03,0x1a,0x1b, 0x10,0x0c,0x0d,0x0e C part a2
+C Masks for high end of number
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ .byte 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00
+C Masks for low end of number
+C .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+C .byte 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+C .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+C .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
+END_OBJECT(cnsts)
diff --git a/gmp/mpn/powerpc32/vmx/popcount.asm b/gmp/mpn/powerpc32/vmx/popcount.asm
new file mode 100644
index 0000000000..943c92d127
--- /dev/null
+++ b/gmp/mpn/powerpc32/vmx/popcount.asm
@@ -0,0 +1,34 @@
+dnl PowerPC-32/VMX mpn_popcount.
+
+dnl Copyright 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_popcount)
+include_mpn(`powerpc64/vmx/popcount.asm')
diff --git a/gmp/mpn/powerpc64/README b/gmp/mpn/powerpc64/README
new file mode 100644
index 0000000000..50dd3995c3
--- /dev/null
+++ b/gmp/mpn/powerpc64/README
@@ -0,0 +1,166 @@
+Copyright 1999-2001, 2003-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+ POWERPC-64 MPN SUBROUTINES
+
+
+This directory contains mpn functions for 64-bit PowerPC chips.
+
+
+CODE ORGANIZATION
+
+ mpn/powerpc64 mode-neutral code
+ mpn/powerpc64/mode32 code for mode32
+ mpn/powerpc64/mode64 code for mode64
+
+
+The mode32 and mode64 sub-directories contain code which is for use in the
+respective chip mode, 32 or 64. The top-level directory is code that's
+unaffected by the mode.
+
+The "adde" instruction is the main difference between mode32 and mode64. It
+operates on either on a 32-bit or 64-bit quantity according to the chip mode.
+Other instructions have an operand size in their opcode and hence don't vary.
+
+
+
+POWER3/PPC630 pipeline information:
+
+Decoding is 4-way + branch and issue is 8-way with some out-of-order
+capability.
+
+Functional units:
+LS1 - ld/st unit 1
+LS2 - ld/st unit 2
+FXU1 - integer unit 1, handles any simple integer instruction
+FXU2 - integer unit 2, handles any simple integer instruction
+FXU3 - integer unit 3, handles integer multiply and divide
+FPU1 - floating-point unit 1
+FPU2 - floating-point unit 2
+
+Memory: Any two memory operations can issue, but memory subsystem
+ can sustain just one store per cycle. No need for data
+ prefetch; the hardware has very sophisticated prefetch logic.
+Simple integer: 2 operations (such as add, rl*)
+Integer multiply: 1 operation every 9th cycle worst case; exact timing depends
+ on 2nd operand's most significant bit position (10 bits per
+ cycle). Multiply unit is not pipelined, only one multiply
+ operation in progress is allowed.
+Integer divide: ?
+Floating-point: Any plain 2 arithmetic instructions (such as fmul, fadd, and
+ fmadd), latency 4 cycles.
+Floating-point divide:
+ ?
+Floating-point square root:
+ ?
+
+POWER3/PPC630 best possible times for the main loops:
+shift: 1.5 cycles limited by integer unit contention.
+ With 63 special loops, one for each shift count, we could
+ reduce the needed integer instructions to 2, which would
+ reduce the best possible time to 1 cycle.
+add/sub: 1.5 cycles, limited by ld/st unit contention.
+mul: 18 cycles (average) unless floating-point operations are used,
+ but that would only help for multiplies of perhaps 10 and more
+ limbs.
+addmul/submul:Same situation as for mul.
+
+
+POWER4/PPC970 and POWER5 pipeline information:
+
+This is a very odd pipeline, it is basically a VLIW masquerading as a plain
+architecture. Its issue rules are not made public, and since it is so weird,
+it is very hard to figure out any useful information from experimentation.
+An example:
+
+ A well-aligned loop with nop's take 3, 4, 6, 7, ... cycles.
+ 3 cycles for 0, 1, 2, 3, 4, 5, 6, 7 nop's
+ 4 cycles for 8, 9, 10, 11, 12, 13, 14, 15 nop's
+ 6 cycles for 16, 17, 18, 19, 20, 21, 22, 23 nop's
+ 7 cycles for 24, 25, 26, 27 nop's
+ 8 cycles for 28, 29, 30, 31 nop's
+ ... continues regularly
+
+
+Functional units:
+LS1 - ld/st unit 1
+LS2 - ld/st unit 2
+FXU1 - integer unit 1, handles any integer instruction
+FXU2 - integer unit 2, handles any integer instruction
+FPU1 - floating-point unit 1
+FPU2 - floating-point unit 2
+
+While this is one integer unit less than POWER3/PPC630, the remaining units
+are more powerful; here they handle multiply and divide.
+
+Memory: 2 ld/st. Stores go to the L2 cache, which can sustain just
+ one store per cycle.
+ L1 load latency: to gregs 3-4 cycles, to fregs 5-6 cycles.
+ Operations that modify the address register might be split
+ to use also an integer issue slot.
+Simple integer: 2 operations every cycle, latency 2.
+Integer multiply: 2 operations every 6th cycle, latency 7 cycles.
+Integer divide: ?
+Floating-point: Any plain 2 arithmetic instructions (such as fmul, fadd, and
+ fmadd), latency 6 cycles.
+Floating-point divide:
+ ?
+Floating-point square root:
+ ?
+
+
+IDEAS
+
+*mul_1: Handling one limb using mulld/mulhdu and two limbs using floating-
+point operations should give performance of about 20 cycles for 3 limbs, or 7
+cycles/limb.
+
+We should probably split the single-limb operand in 32-bit chunks, and the
+multi-limb operand in 16-bit chunks, allowing us to accumulate well in fp
+registers.
+
+Problem is to get 32-bit or 16-bit words to the fp registers. Only 64-bit fp
+memops copies bits without fiddling with them. We might therefore need to
+load to integer registers with zero extension, store as 64 bits into temp
+space, and then load to fp regs. Alternatively, load directly to fp space
+and add well-chosen constants to get cancellation. (Other part after given by
+subsequent subtraction.)
+
+Possible code mix for load-via-intregs variant:
+
+lwz,std,lfd
+fmadd,fmadd,fmul,fmul
+fctidz,stfd,ld,fctidz,stfd,ld
+add,adde
+lwz,std,lfd
+fmadd,fmadd,fmul,fmul
+fctidz,stfd,ld,fctidz,stfd,ld
+add,adde
+srd,sld,add,adde,add,adde
diff --git a/gmp/mpn/powerpc64/aix.m4 b/gmp/mpn/powerpc64/aix.m4
new file mode 100644
index 0000000000..bf6517d69d
--- /dev/null
+++ b/gmp/mpn/powerpc64/aix.m4
@@ -0,0 +1,97 @@
+divert(-1)
+dnl m4 macros for AIX 64-bit assembly.
+
+dnl Copyright 2000-2002, 2005, 2006, 2010, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`ASM_START',
+ `.machine "any"
+ .toc')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo[,toc])
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+dnl Don't want ELF style .size in the epilogue.
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs_range(1,2)
+`ifelse(`$2',toc,,
+`ifelse(`$2',,,`m4_error(`Unrecognised PROLOGUE parameter')')')dnl
+ .globl $1
+ .globl .$1
+ .csect [DS], 3
+$1:
+ .llong .$1, TOC[tc0], 0
+ .csect .$1[PR], 6
+.$1:')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+`')
+
+define(`TOC_ENTRY', `')
+
+define(`LEA',
+m4_assert_numargs(2)
+`define(`TOC_ENTRY',
+` .toc
+..$2: .tc $2[TC], $2')'
+ `ld $1, ..$2(2)')
+
+define(`LEAL',
+m4_assert_numargs(2)
+`LEA($1,$2)')
+
+
+define(`EXTERN',
+m4_assert_numargs(1)
+` .globl $1')
+
+define(`EXTERN_FUNC',
+m4_assert_numargs(1)
+` .globl .$1')
+
+define(`DEF_OBJECT',
+m4_assert_numargs_range(1,2)
+` .csect [RO], 3
+ ALIGN(ifelse($#,1,2,$2))
+$1:
+')
+
+define(`END_OBJECT',
+m4_assert_numargs(1))
+
+define(`CALL',
+ `bl .$1
+ nop')
+
+define(`ASM_END', `TOC_ENTRY')
+
+undefine(`EXTRA_REGISTER')
+
+divert
diff --git a/gmp/mpn/powerpc64/com.asm b/gmp/mpn/powerpc64/com.asm
new file mode 100644
index 0000000000..074b7ff6e4
--- /dev/null
+++ b/gmp/mpn/powerpc64/com.asm
@@ -0,0 +1,136 @@
+dnl PowerPC-64 mpn_com.
+
+dnl Copyright 2004, 2005, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 1.25
+C POWER5 ?
+C POWER6 1.32
+C POWER7 1.13
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+
+ASM_START()
+PROLOGUE(mpn_com)
+
+ifdef(`HAVE_ABI_mode32',
+` rldicl n, n, 0,32')
+
+ cmpdi cr0, n, 4
+ blt L(sml)
+
+ addi r10, n, 4
+ srdi r10, r10, 3
+ mtctr r10
+
+ andi. r0, n, 1
+ rlwinm r11, n, 0,30,30
+ rlwinm r12, n, 0,29,29
+ cmpdi cr6, r11, 0
+ cmpdi cr7, r12, 0
+
+ beq cr0, L(xx0)
+L(xx1): ld r6, 0(up)
+ addi up, up, 8
+ nor r6, r6, r6
+ std r6, 0(rp)
+ addi rp, rp, 8
+
+L(xx0): bne cr6, L(x10)
+L(x00): ld r6, 0(r4)
+ ld r7, 8(r4)
+ bne cr7, L(100)
+L(000): addi rp, rp, -32
+ b L(lo0)
+L(100): addi up, up, -32
+ b L(lo4)
+L(x10): ld r8, 0(r4)
+ ld r9, 8(r4)
+ bne cr7, L(110)
+L(010): addi up, up, 16
+ addi rp, rp, -16
+ b L(lo2)
+L(110): addi up, up, -16
+ addi rp, rp, -48
+ b L(lo6)
+
+L(sml): mtctr n
+L(t): ld r6, 0(up)
+ addi up, up, 8
+ nor r6, r6, r6
+ std r6, 0(rp)
+ addi rp, rp, 8
+ bdnz L(t)
+ blr
+
+ ALIGN(32)
+L(top): nor r6, r6, r6
+ nor r7, r7, r7
+ std r6, 0(rp)
+ std r7, 8(rp)
+L(lo2): ld r6, 0(up)
+ ld r7, 8(up)
+ nor r8, r8, r8
+ nor r9, r9, r9
+ std r8, 16(rp)
+ std r9, 24(rp)
+L(lo0): ld r8, 16(up)
+ ld r9, 24(up)
+ nor r6, r6, r6
+ nor r7, r7, r7
+ std r6, 32(rp)
+ std r7, 40(rp)
+L(lo6): ld r6, 32(up)
+ ld r7, 40(up)
+ nor r8, r8, r8
+ nor r9, r9, r9
+ std r8, 48(rp)
+ std r9, 56(rp)
+ addi rp, rp, 64
+L(lo4): ld r8, 48(up)
+ ld r9, 56(up)
+ addi up, up, 64
+ bdnz L(top)
+
+L(end): nor r6, r6, r6
+ nor r7, r7, r7
+ std r6, 0(rp)
+ std r7, 8(rp)
+ nor r8, r8, r8
+ nor r9, r9, r9
+ std r8, 16(rp)
+ std r9, 24(rp)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/copyd.asm b/gmp/mpn/powerpc64/copyd.asm
new file mode 100644
index 0000000000..c6ce9309f1
--- /dev/null
+++ b/gmp/mpn/powerpc64/copyd.asm
@@ -0,0 +1,84 @@
+dnl PowerPC-64 mpn_copyd
+
+dnl Copyright 2004, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 1
+C POWER4/PPC970 1
+C POWER5 ?
+C POWER6 ?
+C POWER7 1.4
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+ rldic. r0, r5, 3, 59 C r0 = (r5 & 3) << 3; cr0 = (n == 4t)?
+ cmpldi cr6, r0, 16 C cr6 = (n cmp 4t + 2)?
+
+ifdef(`HAVE_ABI_mode32',
+` rldic r6, r5, 3, 32', C byte count corresponding to n
+` rldicr r6, r5, 3, 60') C byte count corresponding to n
+
+ addi r5, r5, 4 C compute...
+ifdef(`HAVE_ABI_mode32',
+` rldicl r5, r5, 62,34', C ...branch count
+` rldicl r5, r5, 62, 2') C ...branch count
+ mtctr r5
+
+ add r4, r4, r6
+ add r3, r3, r6
+ sub r4, r4, r0 C offset up
+ sub r3, r3, r0 C offset rp
+
+ beq cr0, L(L00)
+ blt cr6, L(L01)
+ beq cr6, L(L10)
+ b L(L11)
+
+ ALIGN(16)
+L(oop): ld r6, 24(r4)
+ std r6, 24(r3)
+L(L11): ld r6, 16(r4)
+ std r6, 16(r3)
+L(L10): ld r6, 8(r4)
+ std r6, 8(r3)
+L(L01): ld r6, 0(r4)
+ std r6, 0(r3)
+L(L00): addi r4, r4, -32
+ addi r3, r3, -32
+ bdnz L(oop)
+
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/copyi.asm b/gmp/mpn/powerpc64/copyi.asm
new file mode 100644
index 0000000000..9a86cb21cc
--- /dev/null
+++ b/gmp/mpn/powerpc64/copyi.asm
@@ -0,0 +1,78 @@
+dnl PowerPC-64 mpn_copyi.
+
+dnl Copyright 2004, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 1
+C POWER4/PPC970 1
+C POWER5 ?
+C POWER6 ?
+C POWER7 1.4
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+ rldic. r0, r5, 3, 59 C r0 = (r5 & 3) << 3; cr0 = (n == 4t)?
+ cmpldi cr6, r0, 16 C cr6 = (n cmp 4t + 2)?
+
+ addi r5, r5, 4 C compute...
+ifdef(`HAVE_ABI_mode32',
+` rldicl r5, r5, 62,34', C ...branch count
+` rldicl r5, r5, 62, 2') C ...branch count
+ mtctr r5
+
+ add r4, r4, r0 C offset up
+ add r3, r3, r0 C offset rp
+
+ beq cr0, L(L00)
+ blt cr6, L(L01)
+ beq cr6, L(L10)
+ b L(L11)
+
+ ALIGN(16)
+L(oop): ld r6, -32(r4)
+ std r6, -32(r3)
+L(L11): ld r6, -24(r4)
+ std r6, -24(r3)
+L(L10): ld r6, -16(r4)
+ std r6, -16(r3)
+L(L01): ld r6, -8(r4)
+ std r6, -8(r3)
+L(L00): addi r4, r4, 32
+ addi r3, r3, 32
+ bdnz L(oop)
+
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/darwin.m4 b/gmp/mpn/powerpc64/darwin.m4
new file mode 100644
index 0000000000..a3180e48fd
--- /dev/null
+++ b/gmp/mpn/powerpc64/darwin.m4
@@ -0,0 +1,119 @@
+divert(-1)
+dnl m4 macros for Mac OS 64-bit assembly.
+
+dnl Copyright 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`ASM_START',`')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo[,toc])
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+
+define(`DARWIN')
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs_range(1,2)
+`ifelse(`$2',toc,,
+`ifelse(`$2',,,`m4_error(`Unrecognised PROLOGUE parameter')')')dnl
+ .text
+ .globl $1
+ .align 5
+$1:')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1))
+
+dnl LEAL -- Load Effective Address Local. This is to be used for symbols
+dnl defined in the same file. It will not work for externally defined
+dnl symbols.
+
+define(`LEAL',
+m4_assert_numargs(2)
+`ifdef(`PIC',
+`
+ mflr r0 C save return address
+ bcl 20, 31, 1f
+1: mflr $1
+ addis $1, $1, ha16($2-1b)
+ la $1, lo16($2-1b)($1)
+ mtlr r0 C restore return address
+',`
+ lis $1, ha16($2)
+ la $1, lo16($2)($1)
+')')
+
+dnl LEA -- Load Effective Address. This is to be used for symbols defined in
+dnl another file. It will not work for locally defined symbols.
+
+define(`LEA',
+m4_assert_numargs(2)
+`ifdef(`PIC',
+`define(`EPILOGUE_cpu',
+` .non_lazy_symbol_pointer
+`L'$2`'$non_lazy_ptr:
+ .indirect_symbol $2
+ .quad 0
+')
+ mflr r0 C save return address
+ bcl 20, 31, 1f
+1: mflr $1
+ addis $1, $1, ha16(`L'$2`'$non_lazy_ptr-1b)
+ ld $1, lo16(`L'$2`'$non_lazy_ptr-1b)($1)
+ mtlr r0 C restore return address
+',`
+ lis $1, ha16($2)
+ la $1, lo16($2)($1)
+')')
+
+define(`EXTERN',
+m4_assert_numargs(1)
+`dnl')
+
+define(`EXTERN_FUNC',
+m4_assert_numargs(1)
+`dnl')
+
+define(`DEF_OBJECT',
+m4_assert_numargs_range(1,2)
+` .const
+ ALIGN(ifelse($#,1,2,$2))
+$1:
+')
+
+define(`END_OBJECT',
+m4_assert_numargs(1))
+
+define(`CALL',
+ `bl GSYM_PREFIX`'$1')
+
+define(`ASM_END', `dnl')
+
+define(`EXTRA_REGISTER', r2)
+
+divert
diff --git a/gmp/mpn/powerpc64/elf.m4 b/gmp/mpn/powerpc64/elf.m4
new file mode 100644
index 0000000000..ddb5a8ed79
--- /dev/null
+++ b/gmp/mpn/powerpc64/elf.m4
@@ -0,0 +1,123 @@
+divert(-1)
+dnl m4 macros for powerpc64 GNU/Linux assembly.
+
+dnl Copyright 2003, 2005, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`ASM_START',
+`ifdef(`ELFv2_ABI',
+`
+ .abiversion 2
+')')
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo[,toc])
+dnl EPILOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs_range(1,2)
+`ifelse(`$2',toc,,
+`ifelse(`$2',,,`m4_error(`Unrecognised PROLOGUE parameter')')')dnl
+ifdef(`ELFv2_ABI',
+`
+ .globl $1
+ .type $1, @function
+ .section ".text"
+ .align 5
+$1:
+ifelse(`$2',toc,`
+0: addis 2, 12, (.TOC.-0b)@ha
+ addi 2, 2, (.TOC.-0b)@l
+ .localentry $1, .-$1
+',)
+',`
+ .globl $1
+ .globl .$1
+ .section ".opd","aw"
+ .align 3
+$1:
+ .llong .$1, .TOC.@tocbase, 0
+ .size $1, 24
+ .type .$1, @function
+ .section ".text"
+ .align 5
+.$1:
+')')
+
+define(`EPILOGUE_cpu',
+m4_assert_numargs(1)
+`ifdef(`ELFv2_ABI',`
+ .size $1, .-$1
+',`
+ .size .$1, .-.$1
+')')
+
+define(`TOC_ENTRY', `')
+
+define(`LEA',
+m4_assert_numargs(2)
+`define(`TOC_ENTRY',
+` .section ".toc", "aw"
+..$2: .tc $2[TC], $2')'
+ `ld $1, ..$2@toc(2)')
+
+define(`LEAL',
+m4_assert_numargs(2)
+`LEA($1,$2)')
+
+
+define(`EXTERN',
+m4_assert_numargs(1)
+`dnl')
+
+define(`EXTERN_FUNC',
+m4_assert_numargs(1)
+`dnl')
+
+define(`DEF_OBJECT',
+m4_assert_numargs_range(1,2)
+`
+ .section .rodata
+ ALIGN(ifelse($#,1,2,$2))
+ .type $1, @object
+$1:
+')
+
+define(`END_OBJECT',
+m4_assert_numargs(1)
+` .size $1, .-$1')
+
+define(`CALL',
+ `bl GSYM_PREFIX`'$1
+ nop')
+
+define(`ASM_END', `TOC_ENTRY')
+
+undefine(`EXTRA_REGISTER')
+
+divert
diff --git a/gmp/mpn/powerpc64/logops_n.asm b/gmp/mpn/powerpc64/logops_n.asm
new file mode 100644
index 0000000000..2fa6985d7a
--- /dev/null
+++ b/gmp/mpn/powerpc64/logops_n.asm
@@ -0,0 +1,151 @@
+dnl PowerPC-64 mpn_and_n, mpn_andn_n, mpn_nand_n, mpn_ior_n, mpn_iorn_n,
+dnl mpn_nior_n, mpn_xor_n, mpn_xnor_n -- mpn bitwise logical operations.
+
+dnl Copyright 2003-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 1.75
+C POWER4/PPC970 2.10
+C POWER5 ?
+C POWER6 ?
+C POWER7 1.75
+
+C n POWER3/PPC630 POWER4/PPC970
+C 1 15.00 15.33
+C 2 7.50 7.99
+C 3 5.33 6.00
+C 4 4.50 4.74
+C 5 4.20 4.39
+C 6 3.50 3.99
+C 7 3.14 3.64
+C 8 3.00 3.36
+C 9 3.00 3.36
+C 10 2.70 3.25
+C 11 2.63 3.11
+C 12 2.58 3.00
+C 13 2.61 3.02
+C 14 2.42 2.82
+C 15 2.40 2.79
+C 50 2.08 2.67
+C 100 1.85 2.31
+C 200 1.80 2.18
+C 400 1.77 2.14
+C 1000 1.76 2.10#
+C 2000 1.75# 2.13
+C 4000 2.30 2.57
+C 8000 2.62 2.58
+C 16000 2.52 4.25
+C 32000 2.49 16.25
+C 64000 2.66 18.76
+
+ifdef(`OPERATION_and_n',
+` define(`func',`mpn_and_n')
+ define(`logop', `and')')
+ifdef(`OPERATION_andn_n',
+` define(`func',`mpn_andn_n')
+ define(`logop', `andc')')
+ifdef(`OPERATION_nand_n',
+` define(`func',`mpn_nand_n')
+ define(`logop', `nand')')
+ifdef(`OPERATION_ior_n',
+` define(`func',`mpn_ior_n')
+ define(`logop', `or')')
+ifdef(`OPERATION_iorn_n',
+` define(`func',`mpn_iorn_n')
+ define(`logop', `orc')')
+ifdef(`OPERATION_nior_n',
+` define(`func',`mpn_nior_n')
+ define(`logop', `nor')')
+ifdef(`OPERATION_xor_n',
+` define(`func',`mpn_xor_n')
+ define(`logop', `xor')')
+ifdef(`OPERATION_xnor_n',
+` define(`func',`mpn_xnor_n')
+ define(`logop', `eqv')')
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C vp r5
+C n r6
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+ASM_START()
+PROLOGUE(func)
+ ld r8, 0(r4) C read lowest u limb
+ ld r9, 0(r5) C read lowest v limb
+ addi r6, r6, 3 C compute branch count (1)
+ rldic. r0, r6, 3, 59 C r0 = (n-1 & 3) << 3; cr0 = (n == 4(t+1))?
+ cmpldi cr6, r0, 16 C cr6 = (n cmp 4t + 3)
+
+ifdef(`HAVE_ABI_mode32',
+` rldicl r6, r6, 62,34', C ...branch count
+` rldicl r6, r6, 62, 2') C ...branch count
+ mtctr r6
+
+ ld r6, 0(r4) C read lowest u limb (again)
+ ld r7, 0(r5) C read lowest v limb (again)
+
+ add r5, r5, r0 C offset vp
+ add r4, r4, r0 C offset up
+ add r3, r3, r0 C offset rp
+
+ beq cr0, L(L01)
+ blt cr6, L(L10)
+ beq cr6, L(L11)
+ b L(L00)
+
+L(oop): ld r8, -24(r4)
+ ld r9, -24(r5)
+ logop r10, r6, r7
+ std r10, -32(r3)
+L(L00): ld r6, -16(r4)
+ ld r7, -16(r5)
+ logop r10, r8, r9
+ std r10, -24(r3)
+L(L11): ld r8, -8(r4)
+ ld r9, -8(r5)
+ logop r10, r6, r7
+ std r10, -16(r3)
+L(L10): ld r6, 0(r4)
+ ld r7, 0(r5)
+ logop r10, r8, r9
+ std r10, -8(r3)
+L(L01): addi r5, r5, 32
+ addi r4, r4, 32
+ addi r3, r3, 32
+ bdnz L(oop)
+
+ logop r10, r6, r7
+ std r10, -32(r3)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/lshift.asm b/gmp/mpn/powerpc64/lshift.asm
new file mode 100644
index 0000000000..880944a4ae
--- /dev/null
+++ b/gmp/mpn/powerpc64/lshift.asm
@@ -0,0 +1,207 @@
+dnl PowerPC-64 mpn_lshift -- rp[] = up[] << cnt
+
+dnl Copyright 2003, 2005, 2010, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 2.25
+C POWER6 9.75
+C POWER7 2.15
+
+C TODO
+C * Try to reduce the number of needed live registers
+C * Micro-optimise header code
+C * Keep in synch with rshift.asm and lshiftc.asm
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`cnt', `r6')
+
+define(`tnc',`r0')
+define(`u0',`r30')
+define(`u1',`r31')
+define(`retval',`r5')
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ std r31, -8(r1)
+ std r30, -16(r1)
+ subfic tnc, cnt, 64
+ sldi r7, n, 3 C byte count corresponding to n
+ add up, up, r7 C up = up + n
+ add rp, rp, r7 C rp = rp + n
+ rldicl. r30, n, 0,62 C r30 = n & 3, set cr0
+ cmpdi cr6, r30, 2
+ addi r31, n, 3 C compute count...
+ ld r10, -8(up) C load 1st limb for b00...b11
+ srd retval, r10, tnc
+ifdef(`HAVE_ABI_mode32',
+` rldicl r31, r31, 62,34', C ...branch count
+` srdi r31, r31, 2') C ...for ctr
+ mtctr r31 C copy count into ctr
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ ld r11, -16(up) C load 2nd limb for b10 and b11
+ beq cr6, L(b10)
+
+ ALIGN(16)
+L(b11): sld r8, r10, cnt
+ srd r9, r11, tnc
+ ld u1, -24(up)
+ addi up, up, -24
+ sld r12, r11, cnt
+ srd r7, u1, tnc
+ addi rp, rp, 16
+ bdnz L(gt3)
+
+ or r11, r8, r9
+ sld r8, u1, cnt
+ b L(cj3)
+
+ ALIGN(16)
+L(gt3): ld u0, -8(up)
+ or r11, r8, r9
+ sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -16(up)
+ or r10, r12, r7
+ b L(L11)
+
+ ALIGN(32)
+L(b10): sld r12, r10, cnt
+ addi rp, rp, 24
+ srd r7, r11, tnc
+ bdnz L(gt2)
+
+ sld r8, r11, cnt
+ or r10, r12, r7
+ b L(cj2)
+
+L(gt2): ld u0, -24(up)
+ sld r8, r11, cnt
+ srd r9, u0, tnc
+ ld u1, -32(up)
+ or r10, r12, r7
+ sld r12, u0, cnt
+ srd r7, u1, tnc
+ ld u0, -40(up)
+ or r11, r8, r9
+ addi up, up, -16
+ b L(L10)
+
+ ALIGN(16)
+L(b00): ld u1, -16(up)
+ sld r12, r10, cnt
+ srd r7, u1, tnc
+ ld u0, -24(up)
+ sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -32(up)
+ or r10, r12, r7
+ sld r12, u0, cnt
+ srd r7, u1, tnc
+ addi rp, rp, 8
+ bdz L(cj4)
+
+L(gt4): addi up, up, -32
+ ld u0, -8(up)
+ or r11, r8, r9
+ b L(L00)
+
+ ALIGN(16)
+L(b01): bdnz L(gt1)
+ sld r8, r10, cnt
+ std r8, -8(rp)
+ b L(ret)
+
+L(gt1): ld u0, -16(up)
+ sld r8, r10, cnt
+ srd r9, u0, tnc
+ ld u1, -24(up)
+ sld r12, u0, cnt
+ srd r7, u1, tnc
+ ld u0, -32(up)
+ or r11, r8, r9
+ sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -40(up)
+ addi up, up, -40
+ or r10, r12, r7
+ bdz L(end)
+
+ ALIGN(32)
+L(top): sld r12, u0, cnt
+ srd r7, u1, tnc
+ ld u0, -8(up)
+ std r11, -8(rp)
+ or r11, r8, r9
+L(L00): sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -16(up)
+ std r10, -16(rp)
+ or r10, r12, r7
+L(L11): sld r12, u0, cnt
+ srd r7, u1, tnc
+ ld u0, -24(up)
+ std r11, -24(rp)
+ or r11, r8, r9
+L(L10): sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -32(up)
+ addi up, up, -32
+ std r10, -32(rp)
+ addi rp, rp, -32
+ or r10, r12, r7
+ bdnz L(top)
+
+ ALIGN(32)
+L(end): sld r12, u0, cnt
+ srd r7, u1, tnc
+ std r11, -8(rp)
+L(cj4): or r11, r8, r9
+ sld r8, u1, cnt
+ std r10, -16(rp)
+L(cj3): or r10, r12, r7
+ std r11, -24(rp)
+L(cj2): std r10, -32(rp)
+ std r8, -40(rp)
+
+L(ret): ld r31, -8(r1)
+ ld r30, -16(r1)
+ifdef(`HAVE_ABI_mode32',
+` srdi r3, retval, 32
+ mr r4, retval
+',` mr r3, retval')
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/lshiftc.asm b/gmp/mpn/powerpc64/lshiftc.asm
new file mode 100644
index 0000000000..7cf6a83428
--- /dev/null
+++ b/gmp/mpn/powerpc64/lshiftc.asm
@@ -0,0 +1,210 @@
+dnl PowerPC-64 mpn_lshiftc -- rp[] = ~up[] << cnt
+
+dnl Copyright 2003, 2005, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 2.25
+C POWER6 9.5
+C POWER7 2.15
+
+C TODO
+C * Try to reduce the number of needed live registers
+C * Micro-optimise header code
+C * Keep in synch with lshift.asm and rshift.asm
+C * Could the long-scheduled std insns be less scheduled?
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`cnt', `r6')
+
+define(`tnc',`r0')
+define(`u0',`r30')
+define(`u1',`r31')
+define(`retval',`r5')
+
+ASM_START()
+PROLOGUE(mpn_lshiftc)
+ std r31, -8(r1)
+ std r30, -16(r1)
+ subfic tnc, cnt, 64
+ sldi r7, n, 3 C byte count corresponding to n
+ add up, up, r7 C up = up + n
+ add rp, rp, r7 C rp = rp + n
+ rldicl. r30, n, 0,62 C r30 = n & 3, set cr0
+ cmpdi cr6, r30, 2
+ addi r31, n, 3 C compute count...
+ ld r10, -8(up) C load 1st limb for b00...b11
+ srd retval, r10, tnc
+ srdi r31, r31, 2 C ...for ctr
+ mtctr r31 C copy count into ctr
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ ld r11, -16(up) C load 2nd limb for b10 and b11
+ beq cr6, L(b10)
+
+ ALIGN(16)
+L(b11): sld r8, r10, cnt
+ srd r9, r11, tnc
+ ld u1, -24(up)
+ addi up, up, -24
+ sld r12, r11, cnt
+ srd r7, u1, tnc
+ addi rp, rp, 16
+ bdnz L(gt3)
+
+ nor r11, r8, r9
+ sld r8, u1, cnt
+ nor r8, r8, r8
+ b L(cj3)
+
+ ALIGN(16)
+L(gt3): ld u0, -8(up)
+ nor r11, r8, r9
+ sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -16(up)
+ nor r10, r12, r7
+ b L(L11)
+
+ ALIGN(32)
+L(b10): sld r12, r10, cnt
+ addi rp, rp, 24
+ srd r7, r11, tnc
+ bdnz L(gt2)
+
+ sld r8, r11, cnt
+ nor r10, r12, r7
+ nor r8, r8, r8
+ b L(cj2)
+
+L(gt2): ld u0, -24(up)
+ sld r8, r11, cnt
+ srd r9, u0, tnc
+ ld u1, -32(up)
+ nor r10, r12, r7
+ sld r12, u0, cnt
+ srd r7, u1, tnc
+ ld u0, -40(up)
+ nor r11, r8, r9
+ addi up, up, -16
+ b L(L10)
+
+ ALIGN(16)
+L(b00): ld u1, -16(up)
+ sld r12, r10, cnt
+ srd r7, u1, tnc
+ ld u0, -24(up)
+ sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -32(up)
+ nor r10, r12, r7
+ sld r12, u0, cnt
+ srd r7, u1, tnc
+ addi rp, rp, 8
+ bdz L(cj4)
+
+L(gt4): addi up, up, -32
+ ld u0, -8(up)
+ nor r11, r8, r9
+ b L(L00)
+
+ ALIGN(16)
+L(b01): bdnz L(gt1)
+ sld r8, r10, cnt
+ nor r8, r8, r8
+ std r8, -8(rp)
+ b L(ret)
+
+L(gt1): ld u0, -16(up)
+ sld r8, r10, cnt
+ srd r9, u0, tnc
+ ld u1, -24(up)
+ sld r12, u0, cnt
+ srd r7, u1, tnc
+ ld u0, -32(up)
+ nor r11, r8, r9
+ sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -40(up)
+ addi up, up, -40
+ nor r10, r12, r7
+ bdz L(end)
+
+ ALIGN(32)
+L(top): sld r12, u0, cnt
+ srd r7, u1, tnc
+ ld u0, -8(up)
+ std r11, -8(rp)
+ nor r11, r8, r9
+L(L00): sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -16(up)
+ std r10, -16(rp)
+ nor r10, r12, r7
+L(L11): sld r12, u0, cnt
+ srd r7, u1, tnc
+ ld u0, -24(up)
+ std r11, -24(rp)
+ nor r11, r8, r9
+L(L10): sld r8, u1, cnt
+ srd r9, u0, tnc
+ ld u1, -32(up)
+ addi up, up, -32
+ std r10, -32(rp)
+ addi rp, rp, -32
+ nor r10, r12, r7
+ bdnz L(top)
+
+ ALIGN(32)
+L(end): sld r12, u0, cnt
+ srd r7, u1, tnc
+ std r11, -8(rp)
+L(cj4): nor r11, r8, r9
+ sld r8, u1, cnt
+ std r10, -16(rp)
+ nor r8, r8, r8
+L(cj3): nor r10, r12, r7
+ std r11, -24(rp)
+L(cj2): std r10, -32(rp)
+ std r8, -40(rp)
+
+L(ret): ld r31, -8(r1)
+ ld r30, -16(r1)
+ifdef(`HAVE_ABI_mode32',
+` srdi r3, retval, 32
+ mr r4, retval
+',` mr r3, retval')
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode32/add_n.asm b/gmp/mpn/powerpc64/mode32/add_n.asm
new file mode 100644
index 0000000000..1da8087fe1
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode32/add_n.asm
@@ -0,0 +1,86 @@
+dnl PowerPC-64/mode32 mpn_add_n -- Add two limb vectors of the same length > 0
+dnl and store sum in a third limb vector.
+
+dnl Copyright 1999-2001, 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630: ?
+C POWER4/PPC970: 4.25
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C vp r5
+C n r6
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+ mtctr r6 C copy size into CTR
+ addic r0, r0, 0 C clear cy
+ ld r8, 0(r4) C load least significant s1 limb
+ ld r0, 0(r5) C load least significant s2 limb
+ addi r3, r3, -8 C offset res_ptr, it's updated before it's used
+ bdz L(end) C If done, skip loop
+
+L(oop): ld r9, 8(r4) C load s1 limb
+ ld r10, 8(r5) C load s2 limb
+ adde r7, r0, r8 C add limbs with cy, set cy
+ srdi r6, r0, 32
+ srdi r11, r8, 32
+ adde r6, r6, r11 C add high limb parts, set cy
+ std r7, 8(r3) C store result limb
+ bdz L(exit) C decrement CTR and exit if done
+ ldu r8, 16(r4) C load s1 limb and update s1_ptr
+ ldu r0, 16(r5) C load s2 limb and update s2_ptr
+ adde r7, r10, r9 C add limbs with cy, set cy
+ srdi r6, r10, 32
+ srdi r11, r9, 32
+ adde r6, r6, r11 C add high limb parts, set cy
+ stdu r7, 16(r3) C store result limb and update res_ptr
+ bdnz L(oop) C decrement CTR and loop back
+
+L(end): adde r7, r0, r8
+ srdi r6, r0, 32
+ srdi r11, r8, 32
+ adde r6, r6, r11 C add limbs with cy, set cy
+ std r7, 8(r3) C store ultimate result limb
+ li r3, 0 C load cy into ...
+ addze r4, r3 C ... return value register
+ blr
+L(exit): adde r7, r10, r9
+ srdi r6, r10, 32
+ srdi r11, r9, 32
+ adde r6, r6, r11 C add limbs with cy, set cy
+ std r7, 16(r3)
+ li r3, 0 C load cy into ...
+ addze r4, r3 C ... return value register
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode32/addmul_1.asm b/gmp/mpn/powerpc64/mode32/addmul_1.asm
new file mode 100644
index 0000000000..bdc39512ac
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode32/addmul_1.asm
@@ -0,0 +1,79 @@
+dnl PowerPC-64 mpn_addmul_1 -- Multiply a limb vector with a limb and add
+dnl the result to a second limb vector.
+
+dnl Copyright 1999-2001, 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630: ?
+C POWER4/PPC970: 12.5
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+C v r6,r7 or r7,r8
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+
+ifdef(`BROKEN_LONGLONG_PARAM',
+` rldimi r8, r7, 32,0 C assemble vlimb from separate 32-bit arguments
+ mr r6, r8
+',`
+ rldimi r7, r6, 32,0 C assemble vlimb from separate 32-bit arguments
+ mr r6, r7
+')
+ li r7, 0 C cy_limb = 0
+ mtctr r5
+ addic r0, r0, 0
+ addi r3, r3, -8
+ addi r4, r4, -8
+
+L(oop): ldu r0, 8(r4)
+ mulld r9, r0, r6
+ adde r12, r9, r7 C add old high limb and new low limb
+ srdi r5, r9, 32
+ srdi r11, r7, 32
+ adde r5, r5, r11 C add high limb parts, set cy
+ mulhdu r7, r0, r6
+ addze r7, r7
+ ld r10, 8(r3)
+ addc r9, r12, r10
+ srdi r5, r12, 32
+ srdi r11, r10, 32
+ adde r5, r5, r11 C add high limb parts, set cy
+ stdu r9, 8(r3)
+ bdnz L(oop)
+
+ addze r4, r7
+ srdi r3, r4, 32
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode32/mul_1.asm b/gmp/mpn/powerpc64/mode32/mul_1.asm
new file mode 100644
index 0000000000..3a17e98797
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode32/mul_1.asm
@@ -0,0 +1,73 @@
+dnl PowerPC-64 mpn_mul_1 -- Multiply a limb vector with a limb and add
+dnl the result to a second limb vector.
+
+dnl Copyright 1999-2001, 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630: ?
+C POWER4/PPC970: 10
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+C v r6,r7 or r7,r8
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+
+ifdef(`BROKEN_LONGLONG_PARAM',
+` rldimi r8, r7, 32,0 C assemble vlimb from separate 32-bit arguments
+ mr r6, r8
+',`
+ rldimi r7, r6, 32,0 C assemble vlimb from separate 32-bit arguments
+ mr r6, r7
+')
+ li r7, 0 C cy_limb = 0
+ mtctr r5
+ addic r0, r0, 0
+ addi r3, r3, -8
+ addi r4, r4, -8
+
+L(oop): ldu r0, 8(r4)
+ mulld r9, r0, r6
+ adde r12, r9, r7 C add old high limb and new low limb
+ srdi r5, r9, 32
+ srdi r11, r7, 32
+ adde r5, r5, r11 C add high limb parts, set cy
+ mulhdu r7, r0, r6
+ stdu r12, 8(r3)
+ bdnz L(oop)
+
+ addze r4, r7
+ srdi r3, r4, 32
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode32/p4/gmp-mparam.h b/gmp/mpn/powerpc64/mode32/p4/gmp-mparam.h
new file mode 100644
index 0000000000..a7271381c5
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode32/p4/gmp-mparam.h
@@ -0,0 +1,173 @@
+/* PowerPC-64 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2008, 2009, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* 1800 MHz PPC970 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 1
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 6
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 46
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 14
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_2_PI2_THRESHOLD 12
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 90
+
+#define MUL_TOOM22_THRESHOLD 16
+#define MUL_TOOM33_THRESHOLD 57
+#define MUL_TOOM44_THRESHOLD 94
+#define MUL_TOOM6H_THRESHOLD 125
+#define MUL_TOOM8H_THRESHOLD 187
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 65
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 99
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 61
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 56
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 70
+
+#define SQR_BASECASE_THRESHOLD 4
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 98
+#define SQR_TOOM4_THRESHOLD 136
+#define SQR_TOOM6_THRESHOLD 180
+#define SQR_TOOM8_THRESHOLD 272
+
+#define MULMID_TOOM42_THRESHOLD 34
+
+#define MULMOD_BNM1_THRESHOLD 12
+#define SQRMOD_BNM1_THRESHOLD 13
+
+#define MUL_FFT_MODF_THRESHOLD 244 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 244, 5}, { 13, 6}, { 7, 5}, { 15, 6}, \
+ { 15, 7}, { 8, 6}, { 17, 7}, { 9, 6}, \
+ { 19, 7}, { 13, 8}, { 7, 7}, { 17, 8}, \
+ { 9, 7}, { 20, 8}, { 11, 7}, { 23, 8}, \
+ { 13, 7}, { 29, 8}, { 19, 9}, { 11, 8}, \
+ { 27,10}, { 7, 9}, { 15, 8}, { 33, 9}, \
+ { 19, 8}, { 39, 9}, { 23, 8}, { 47, 9}, \
+ { 27,10}, { 15, 9}, { 39,10}, { 23, 9}, \
+ { 47,11}, { 15,10}, { 31, 9}, { 67,10}, \
+ { 39, 9}, { 83,10}, { 47, 9}, { 95, 8}, \
+ { 191, 9}, { 99,10}, { 55,11}, { 31,10}, \
+ { 63, 9}, { 127, 8}, { 255,10}, { 71, 9}, \
+ { 143, 8}, { 287,10}, { 79, 9}, { 159, 8}, \
+ { 319,11}, { 47,10}, { 95, 9}, { 191, 8}, \
+ { 383,10}, { 103,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511,10}, { 143, 9}, \
+ { 287,11}, { 79,10}, { 159, 9}, { 319, 8}, \
+ { 639,10}, { 175, 9}, { 351, 8}, { 703,11}, \
+ { 95,10}, { 191, 9}, { 383, 8}, { 767,10}, \
+ { 207, 9}, { 415,10}, { 223, 9}, { 447,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,11}, \
+ { 143,10}, { 287, 9}, { 575, 8}, { 1151,11}, \
+ { 159,10}, { 319, 9}, { 639,11}, { 175,10}, \
+ { 351, 9}, { 703,12}, { 95,11}, { 191,10}, \
+ { 383, 9}, { 767,11}, { 207,10}, { 415, 9}, \
+ { 831,11}, { 223,10}, { 447,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 106
+#define MUL_FFT_THRESHOLD 2688
+
+#define SQR_FFT_MODF_THRESHOLD 212 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 212, 5}, { 13, 6}, { 15, 7}, { 8, 6}, \
+ { 17, 7}, { 9, 6}, { 19, 7}, { 13, 8}, \
+ { 7, 7}, { 17, 8}, { 9, 7}, { 20, 8}, \
+ { 11, 7}, { 23, 8}, { 13, 7}, { 27, 9}, \
+ { 7, 8}, { 21, 9}, { 11, 8}, { 25,10}, \
+ { 7, 9}, { 15, 8}, { 33, 9}, { 19, 8}, \
+ { 39, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 47,11}, \
+ { 15,10}, { 31, 9}, { 63, 8}, { 127, 9}, \
+ { 67,10}, { 39, 9}, { 79, 8}, { 159,10}, \
+ { 47, 9}, { 95, 8}, { 191,11}, { 31,10}, \
+ { 63, 9}, { 127, 8}, { 255,10}, { 71, 9}, \
+ { 143, 8}, { 287,10}, { 79, 9}, { 159, 8}, \
+ { 319,11}, { 47, 9}, { 191, 8}, { 383,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511,10}, { 143, 9}, { 287, 8}, { 575,11}, \
+ { 79,10}, { 159, 9}, { 319, 8}, { 639,10}, \
+ { 175, 9}, { 351, 8}, { 703,10}, { 191, 9}, \
+ { 383, 8}, { 767,10}, { 207, 9}, { 415,11}, \
+ { 111,10}, { 223,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,11}, { 143,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 319, 9}, { 639,11}, \
+ { 175,10}, { 351, 9}, { 703, 8}, { 1407,11}, \
+ { 191,10}, { 383, 9}, { 767,11}, { 207,10}, \
+ { 415,11}, { 223,10}, { 447,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 102
+#define SQR_FFT_THRESHOLD 1984
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 55
+#define MULLO_MUL_N_THRESHOLD 5240
+
+#define DC_DIV_QR_THRESHOLD 27
+#define DC_DIVAPPR_Q_THRESHOLD 108
+#define DC_BDIV_QR_THRESHOLD 51
+#define DC_BDIV_Q_THRESHOLD 126
+
+#define INV_MULMOD_BNM1_THRESHOLD 38
+#define INV_NEWTON_THRESHOLD 129
+#define INV_APPR_THRESHOLD 116
+
+#define BINV_NEWTON_THRESHOLD 198
+#define REDC_1_TO_REDC_N_THRESHOLD 51
+
+#define MU_DIV_QR_THRESHOLD 807
+#define MU_DIVAPPR_Q_THRESHOLD 807
+#define MUPI_DIV_QR_THRESHOLD 54
+#define MU_BDIV_QR_THRESHOLD 748
+#define MU_BDIV_Q_THRESHOLD 872
+
+#define POWM_SEC_TABLE 4,35,152,780,2145
+
+#define MATRIX22_STRASSEN_THRESHOLD 11
+#define HGCD_THRESHOLD 104
+#define HGCD_APPR_THRESHOLD 118
+#define HGCD_REDUCE_THRESHOLD 1329
+#define GCD_DC_THRESHOLD 268
+#define GCDEXT_DC_THRESHOLD 241
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 9
+#define GET_STR_PRECOMPUTE_THRESHOLD 18
+#define SET_STR_DC_THRESHOLD 996
+#define SET_STR_PRECOMPUTE_THRESHOLD 2170
+
+#define FAC_DSC_THRESHOLD 442
+#define FAC_ODD_THRESHOLD 26
diff --git a/gmp/mpn/powerpc64/mode32/sqr_diagonal.asm b/gmp/mpn/powerpc64/mode32/sqr_diagonal.asm
new file mode 100644
index 0000000000..ff5f4b3cfb
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode32/sqr_diagonal.asm
@@ -0,0 +1,117 @@
+dnl PowerPC-64 mpn_sqr_diagonal.
+
+dnl Copyright 2001-2003, 2005, 2006, 20010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 18
+C POWER4/PPC970 ?
+C POWER5 7.25
+C POWER6 9.5
+
+C INPUT PARAMETERS
+define(`rp', r3)
+define(`up', r4)
+define(`n', r5)
+
+ASM_START()
+PROLOGUE(mpn_sqr_diagonal)
+ifdef(`HAVE_ABI_mode32',
+` rldicl n, n, 0, 32') C zero extend n
+
+ rldicl. r0, n, 0,62 C r0 = n & 3, set cr0
+ addi n, n, 3 C compute count...
+ cmpdi cr6, r0, 2
+ srdi n, n, 2 C ...for ctr
+ mtctr n C copy count into ctr
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ beq cr6, L(b10)
+
+L(b11): ld r0, 0(up)
+ ld r10, 8(up)
+ ld r12, 16(up)
+ addi rp, rp, -16
+ mulld r7, r0, r0
+ mulhdu r8, r0, r0
+ mulld r9, r10, r10
+ mulhdu r10, r10, r10
+ mulld r11, r12, r12
+ mulhdu r12, r12, r12
+ addi up, up, 24
+ b L(11)
+
+ ALIGN(16)
+L(b01): ld r0, 0(up)
+ addi rp, rp, -48
+ addi up, up, 8
+ mulld r11, r0, r0
+ mulhdu r12, r0, r0
+ b L(01)
+
+ ALIGN(16)
+L(b10): ld r0, 0(up)
+ ld r12, 8(up)
+ addi rp, rp, -32
+ addi up, up, 16
+ mulld r9, r0, r0
+ mulhdu r10, r0, r0
+ mulld r11, r12, r12
+ mulhdu r12, r12, r12
+ b L(10)
+
+ ALIGN(32)
+L(b00):
+L(top): ld r0, 0(up)
+ ld r8, 8(up)
+ ld r10, 16(up)
+ ld r12, 24(up)
+ mulld r5, r0, r0
+ mulhdu r6, r0, r0
+ mulld r7, r8, r8
+ mulhdu r8, r8, r8
+ mulld r9, r10, r10
+ mulhdu r10, r10, r10
+ mulld r11, r12, r12
+ mulhdu r12, r12, r12
+ addi up, up, 32
+ std r5, 0(rp)
+ std r6, 8(rp)
+L(11): std r7, 16(rp)
+ std r8, 24(rp)
+L(10): std r9, 32(rp)
+ std r10, 40(rp)
+L(01): std r11, 48(rp)
+ std r12, 56(rp)
+ addi rp, rp, 64
+ bdnz L(top)
+
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode32/sub_n.asm b/gmp/mpn/powerpc64/mode32/sub_n.asm
new file mode 100644
index 0000000000..6fdc1d4719
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode32/sub_n.asm
@@ -0,0 +1,88 @@
+dnl PowerPC-64/mode32 mpn_sub_n -- Subtract two limb vectors of the same
+dnl length and store difference in a third limb vector.
+
+dnl Copyright 1999-2001, 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630: ?
+C POWER4/PPC970: 4.25
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C vp r5
+C n r6
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ mtctr r6 C copy size into CTR
+ addic r0, r6, -1 C set cy
+ ld r8, 0(r4) C load least significant s1 limb
+ ld r0, 0(r5) C load least significant s2 limb
+ addi r3, r3, -8 C offset res_ptr, it's updated before it's used
+ bdz L(end) C If done, skip loop
+
+L(oop): ld r9, 8(r4) C load s1 limb
+ ld r10, 8(r5) C load s2 limb
+ subfe r7, r0, r8 C subtract limbs with cy, set cy
+ srdi r6, r0, 32
+ srdi r11, r8, 32
+ subfe r6, r6, r11
+ std r7, 8(r3) C store result limb
+ bdz L(exit) C decrement CTR and exit if done
+ ldu r8, 16(r4) C load s1 limb and update s1_ptr
+ ldu r0, 16(r5) C load s2 limb and update s2_ptr
+ subfe r7, r10, r9 C subtract limbs with cy, set cy
+ srdi r6, r10, 32
+ srdi r11, r9, 32
+ subfe r6, r6, r11
+ stdu r7, 16(r3) C store result limb and update res_ptr
+ bdnz L(oop) C decrement CTR and loop back
+
+L(end): subfe r7, r0, r8
+ srdi r6, r0, 32
+ srdi r11, r8, 32
+ subfe r6, r6, r11
+ std r7, 8(r3) C store ultimate result limb
+ subfe r3, r0, r0 C load !cy into ...
+ subfic r4, r3, 0 C ... return value register
+ li r3, 0 C zero extend return value
+ blr
+L(exit): subfe r7, r10, r9
+ srdi r6, r10, 32
+ srdi r11, r9, 32
+ subfe r6, r6, r11
+ std r7, 16(r3)
+ subfe r3, r0, r0 C load !cy into ...
+ subfic r4, r3, 0 C ... return value register
+ li r3, 0 C zero extend return value
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode32/submul_1.asm b/gmp/mpn/powerpc64/mode32/submul_1.asm
new file mode 100644
index 0000000000..22601c417e
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode32/submul_1.asm
@@ -0,0 +1,82 @@
+dnl PowerPC-64 mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+dnl the result from a second limb vector.
+
+dnl Copyright 1999-2001, 2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630: ?
+C POWER4/PPC970: 16
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C n r5
+C v r6,r7 or r7,r8
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+
+ifdef(`BROKEN_LONGLONG_PARAM',
+` rldimi r8, r7, 32,0 C assemble vlimb from separate 32-bit arguments
+ mr r6, r8
+',`
+ rldimi r7, r6, 32,0 C assemble vlimb from separate 32-bit arguments
+ mr r6, r7
+')
+ li r7, 0 C cy_limb = 0
+ mtctr r5
+ addic r0, r0, 0
+ addi r3, r3, -8
+ addi r4, r4, -8
+
+L(oop): ldu r0, 8(r4)
+ mulld r9, r0, r6
+ adde r12, r9, r7 C add old high limb and new low limb
+ srdi r5, r9, 32
+ srdi r11, r7, 32
+ adde r5, r5, r11 C add high limb parts, set cy
+ mulhdu r7, r0, r6
+ addze r7, r7
+ ld r10, 8(r3)
+ subfc r9, r12, r10
+ srdi r5, r12, 32
+ srdi r11, r10, 32
+ subfe r5, r5, r11 C subtract high limb parts, set cy
+ stdu r9, 8(r3)
+ subfe r11, r11, r11 C invert ...
+ addic r11, r11, 1 C ... carry
+ bdnz L(oop)
+
+ addze r4, r7
+ srdi r3, r4, 32
+ blr
+EPILOGUE()
+
diff --git a/gmp/mpn/powerpc64/mode64/aors_n.asm b/gmp/mpn/powerpc64/mode64/aors_n.asm
new file mode 100644
index 0000000000..0e8474fdcc
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/aors_n.asm
@@ -0,0 +1,189 @@
+dnl PowerPC-64 mpn_add_n/mpn_sub_n -- mpn addition and subtraction.
+
+dnl Copyright 1999-2001, 2003-2005, 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 1.5
+C POWER4/PPC970 2
+C POWER5 2
+C POWER6 2.63
+C POWER7 2.25-2.87
+
+C This code is a little bit slower for POWER3/PPC630 than the simple code used
+C previously, but it is much faster for POWER4/PPC970. The reason for the
+C POWER3/PPC630 slowdown can be attributed to the saving and restoring of 4
+C registers.
+
+C INPUT PARAMETERS
+C rp r3
+C up r4
+C vp r5
+C n r6
+
+ifdef(`OPERATION_add_n',`
+ define(ADDSUBC, adde)
+ define(ADDSUB, addc)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)
+ define(GENRVAL, `addi r3, r3, 1')
+ define(SETCBR, `addic r0, $1, -1')
+ define(CLRCB, `addic r0, r0, 0')
+')
+ifdef(`OPERATION_sub_n',`
+ define(ADDSUBC, subfe)
+ define(ADDSUB, subfc)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)
+ define(GENRVAL, `neg r3, r3')
+ define(SETCBR, `subfic r0, $1, 0')
+ define(CLRCB, `addic r0, r1, -1')
+')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+PROLOGUE(func_nc)
+ SETCBR(r7)
+ b L(ent)
+EPILOGUE()
+
+PROLOGUE(func)
+ CLRCB
+L(ent): std r31, -8(r1)
+ std r30, -16(r1)
+ std r29, -24(r1)
+ std r28, -32(r1)
+
+ rldicl. r0, r6, 0,62 C r0 = n & 3, set cr0
+ cmpdi cr6, r0, 2
+ addi r6, r6, 3 C compute count...
+ srdi r6, r6, 2 C ...for ctr
+ mtctr r6 C copy count into ctr
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ beq cr6, L(b10)
+
+L(b11): ld r8, 0(r4) C load s1 limb
+ ld r9, 0(r5) C load s2 limb
+ ld r10, 8(r4) C load s1 limb
+ ld r11, 8(r5) C load s2 limb
+ ld r12, 16(r4) C load s1 limb
+ addi r4, r4, 24
+ ld r0, 16(r5) C load s2 limb
+ addi r5, r5, 24
+ ADDSUBC r29, r9, r8
+ ADDSUBC r30, r11, r10
+ ADDSUBC r31, r0, r12
+ std r29, 0(r3)
+ std r30, 8(r3)
+ std r31, 16(r3)
+ addi r3, r3, 24
+ bdnz L(go)
+ b L(ret)
+
+L(b01): ld r12, 0(r4) C load s1 limb
+ addi r4, r4, 8
+ ld r0, 0(r5) C load s2 limb
+ addi r5, r5, 8
+ ADDSUBC r31, r0, r12 C add
+ std r31, 0(r3)
+ addi r3, r3, 8
+ bdnz L(go)
+ b L(ret)
+
+L(b10): ld r10, 0(r4) C load s1 limb
+ ld r11, 0(r5) C load s2 limb
+ ld r12, 8(r4) C load s1 limb
+ addi r4, r4, 16
+ ld r0, 8(r5) C load s2 limb
+ addi r5, r5, 16
+ ADDSUBC r30, r11, r10 C add
+ ADDSUBC r31, r0, r12 C add
+ std r30, 0(r3)
+ std r31, 8(r3)
+ addi r3, r3, 16
+ bdnz L(go)
+ b L(ret)
+
+L(b00): C INITCY C clear/set cy
+L(go): ld r6, 0(r4) C load s1 limb
+ ld r7, 0(r5) C load s2 limb
+ ld r8, 8(r4) C load s1 limb
+ ld r9, 8(r5) C load s2 limb
+ ld r10, 16(r4) C load s1 limb
+ ld r11, 16(r5) C load s2 limb
+ ld r12, 24(r4) C load s1 limb
+ ld r0, 24(r5) C load s2 limb
+ bdz L(end)
+
+ addi r4, r4, 32
+ addi r5, r5, 32
+
+ ALIGN(16)
+L(top): ADDSUBC r28, r7, r6
+ ld r6, 0(r4) C load s1 limb
+ ld r7, 0(r5) C load s2 limb
+ ADDSUBC r29, r9, r8
+ ld r8, 8(r4) C load s1 limb
+ ld r9, 8(r5) C load s2 limb
+ ADDSUBC r30, r11, r10
+ ld r10, 16(r4) C load s1 limb
+ ld r11, 16(r5) C load s2 limb
+ ADDSUBC r31, r0, r12
+ ld r12, 24(r4) C load s1 limb
+ ld r0, 24(r5) C load s2 limb
+ std r28, 0(r3)
+ addi r4, r4, 32
+ std r29, 8(r3)
+ addi r5, r5, 32
+ std r30, 16(r3)
+ std r31, 24(r3)
+ addi r3, r3, 32
+ bdnz L(top) C decrement ctr and loop back
+
+L(end): ADDSUBC r28, r7, r6
+ ADDSUBC r29, r9, r8
+ ADDSUBC r30, r11, r10
+ ADDSUBC r31, r0, r12
+ std r28, 0(r3)
+ std r29, 8(r3)
+ std r30, 16(r3)
+ std r31, 24(r3)
+
+L(ret): ld r31, -8(r1)
+ ld r30, -16(r1)
+ ld r29, -24(r1)
+ ld r28, -32(r1)
+
+ subfe r3, r0, r0 C -cy
+ GENRVAL
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/aorsmul_1.asm b/gmp/mpn/powerpc64/mode64/aorsmul_1.asm
new file mode 100644
index 0000000000..0c12f9b660
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/aorsmul_1.asm
@@ -0,0 +1,225 @@
+dnl PowerPC-64 mpn_addmul_1 and mpn_submul_1.
+
+dnl Copyright 1999-2001, 2003-2006, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C mpn_addmul_1 mpn_submul_1
+C cycles/limb cycles/limb
+C POWER3/PPC630 6-18 6-18
+C POWER4/PPC970 8 8.3
+C POWER5 8 8.25
+C POWER6 16.25 16.75
+C POWER7 3.77 4.9
+
+C TODO
+C * Try to reduce the number of needed live registers
+C * Add support for _1c entry points
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`vl', `r6')
+
+ifdef(`OPERATION_addmul_1',`
+ define(ADDSUBC, adde)
+ define(ADDSUB, addc)
+ define(func, mpn_addmul_1)
+ define(func_nc, mpn_addmul_1c) C FIXME: not really supported
+ define(SM, `')
+')
+ifdef(`OPERATION_submul_1',`
+ define(ADDSUBC, subfe)
+ define(ADDSUB, subfc)
+ define(func, mpn_submul_1)
+ define(func_nc, mpn_submul_1c) C FIXME: not really supported
+ define(SM, `$1')
+')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+ASM_START()
+PROLOGUE(func)
+ std r31, -8(r1)
+ rldicl. r0, n, 0,62 C r0 = n & 3, set cr0
+ std r30, -16(r1)
+ cmpdi cr6, r0, 2
+ std r29, -24(r1)
+ addi n, n, 3 C compute count...
+ std r28, -32(r1)
+ srdi n, n, 2 C ...for ctr
+ std r27, -40(r1)
+ mtctr n C copy count into ctr
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ beq cr6, L(b10)
+
+L(b11): ld r9, 0(up)
+ ld r28, 0(rp)
+ mulld r0, r9, r6
+ mulhdu r12, r9, r6
+ ADDSUB r0, r0, r28
+ std r0, 0(rp)
+ addi rp, rp, 8
+ ld r9, 8(up)
+ ld r27, 16(up)
+ addi up, up, 24
+SM(` subfe r11, r11, r11 ')
+ b L(bot)
+
+ ALIGN(16)
+L(b00): ld r9, 0(up)
+ ld r27, 8(up)
+ ld r28, 0(rp)
+ ld r29, 8(rp)
+ mulld r0, r9, r6
+ mulhdu r5, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ addc r7, r7, r5
+ addze r12, r8
+ ADDSUB r0, r0, r28
+ std r0, 0(rp)
+ ADDSUBC r7, r7, r29
+ std r7, 8(rp)
+ addi rp, rp, 16
+ ld r9, 16(up)
+ ld r27, 24(up)
+ addi up, up, 32
+SM(` subfe r11, r11, r11 ')
+ b L(bot)
+
+ ALIGN(16)
+L(b01): bdnz L(gt1)
+ ld r9, 0(up)
+ ld r11, 0(rp)
+ mulld r0, r9, r6
+ mulhdu r8, r9, r6
+ ADDSUB r0, r0, r11
+ std r0, 0(rp)
+SM(` subfe r11, r11, r11 ')
+SM(` addic r11, r11, 1 ')
+ addze r3, r8
+ blr
+L(gt1): ld r9, 0(up)
+ ld r27, 8(up)
+ mulld r0, r9, r6
+ mulhdu r5, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r9, 16(up)
+ ld r28, 0(rp)
+ ld r29, 8(rp)
+ ld r30, 16(rp)
+ mulld r11, r9, r6
+ mulhdu r10, r9, r6
+ addc r7, r7, r5
+ adde r11, r11, r8
+ addze r12, r10
+ ADDSUB r0, r0, r28
+ std r0, 0(rp)
+ ADDSUBC r7, r7, r29
+ std r7, 8(rp)
+ ADDSUBC r11, r11, r30
+ std r11, 16(rp)
+ addi rp, rp, 24
+ ld r9, 24(up)
+ ld r27, 32(up)
+ addi up, up, 40
+SM(` subfe r11, r11, r11 ')
+ b L(bot)
+
+L(b10): addic r0, r0, 0
+ li r12, 0 C cy_limb = 0
+ ld r9, 0(up)
+ ld r27, 8(up)
+ bdz L(end)
+ addi up, up, 16
+
+ ALIGN(16)
+L(top): mulld r0, r9, r6
+ mulhdu r5, r9, r6 C 9
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6 C 27
+ ld r9, 0(up)
+ ld r28, 0(rp)
+ ld r27, 8(up)
+ ld r29, 8(rp)
+ adde r0, r0, r12 C 0 12
+ adde r7, r7, r5 C 5 7
+ mulld r5, r9, r6
+ mulhdu r10, r9, r6 C 9
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6 C 27
+ ld r9, 16(up)
+ ld r30, 16(rp)
+ ld r27, 24(up)
+ ld r31, 24(rp)
+ adde r5, r5, r8 C 8 5
+ adde r11, r11, r10 C 10 11
+ addze r12, r12 C 12
+ ADDSUB r0, r0, r28 C 0 28
+ std r0, 0(rp) C 0
+ ADDSUBC r7, r7, r29 C 7 29
+ std r7, 8(rp) C 7
+ ADDSUBC r5, r5, r30 C 5 30
+ std r5, 16(rp) C 5
+ ADDSUBC r11, r11, r31 C 11 31
+ std r11, 24(rp) C 11
+ addi up, up, 32
+SM(` subfe r11, r11, r11 ')
+ addi rp, rp, 32
+L(bot):
+SM(` addic r11, r11, 1 ')
+ bdnz L(top)
+
+L(end): mulld r0, r9, r6
+ mulhdu r5, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r28, 0(rp)
+ ld r29, 8(rp)
+ adde r0, r0, r12
+ adde r7, r7, r5
+ addze r8, r8
+ ADDSUB r0, r0, r28
+ std r0, 0(rp)
+ ADDSUBC r7, r7, r29
+ std r7, 8(rp)
+SM(` subfe r11, r11, r11 ')
+SM(` addic r11, r11, 1 ')
+ addze r3, r8
+ ld r31, -8(r1)
+ ld r30, -16(r1)
+ ld r29, -24(r1)
+ ld r28, -32(r1)
+ ld r27, -40(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/aorsorrlsh1_n.asm b/gmp/mpn/powerpc64/mode64/aorsorrlsh1_n.asm
new file mode 100644
index 0000000000..2c5400ab52
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/aorsorrlsh1_n.asm
@@ -0,0 +1,43 @@
+dnl PowerPC-64 mpn_addlsh1_n, mpn_sublsh1_n, mpn_rsblsh1_n.
+
+dnl Copyright 2003, 2005, 2009, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 1)
+define(RSH, 63)
+
+ifdef(`OPERATION_addlsh1_n',`define(`DO_add')')
+ifdef(`OPERATION_sublsh1_n',`define(`DO_sub')')
+ifdef(`OPERATION_rsblsh1_n',`define(`DO_rsb')')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n mpn_rsblsh1_n)
+
+include_mpn(`powerpc64/mode64/aorsorrlshC_n.asm')
diff --git a/gmp/mpn/powerpc64/mode64/aorsorrlsh2_n.asm b/gmp/mpn/powerpc64/mode64/aorsorrlsh2_n.asm
new file mode 100644
index 0000000000..447791abb0
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/aorsorrlsh2_n.asm
@@ -0,0 +1,43 @@
+dnl PowerPC-64 mpn_addlsh2_n, mpn_sublsh2_n, mpn_rsblsh2_n.
+
+dnl Copyright 2003, 2005, 2009, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 2)
+define(RSH, 62)
+
+ifdef(`OPERATION_addlsh2_n',`define(`DO_add')')
+ifdef(`OPERATION_sublsh2_n',`define(`DO_sub')')
+ifdef(`OPERATION_rsblsh2_n',`define(`DO_rsb')')
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_sublsh2_n mpn_rsblsh2_n)
+
+include_mpn(`powerpc64/mode64/aorsorrlshC_n.asm')
diff --git a/gmp/mpn/powerpc64/mode64/aorsorrlshC_n.asm b/gmp/mpn/powerpc64/mode64/aorsorrlshC_n.asm
new file mode 100644
index 0000000000..6158f541fc
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/aorsorrlshC_n.asm
@@ -0,0 +1,187 @@
+dnl PowerPC-64 mpn_addlshC_n, mpn_sublshC_n, mpn_rsblshC_n.
+
+dnl Copyright 2003, 2005, 2009, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+C cycles/limb
+C POWER3/PPC630 1.83 (1.5 c/l should be possible)
+C POWER4/PPC970 3 (2.0 c/l should be possible)
+C POWER5 3
+C POWER6 3.5-47
+C POWER7 3
+
+C STATUS
+C * Try combining upx+up, and vpx+vp.
+C * The worst case 47 c/l for POWER6 happens if the 3rd operand for ldx is
+C greater than the 2nd operand. Yes, this addition is non-commutative wrt
+C performance.
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`vp', `r5')
+define(`n', `r6')
+
+ifdef(`DO_add', `
+ define(`ADDSUBC', `addc $1, $2, $3')
+ define(`ADDSUBE', `adde $1, $2, $3')
+ define(INITCY, `addic $1, r1, 0')
+ define(RETVAL, `addze r3, $1')
+ define(`func', mpn_addlsh`'LSH`'_n)')
+ifdef(`DO_sub', `
+ define(`ADDSUBC', `subfc $1, $2, $3')
+ define(`ADDSUBE', `subfe $1, $2, $3')
+ define(INITCY, `addic $1, r1, -1')
+ define(RETVAL, `subfze r3, $1
+ neg r3, r3')
+ define(`func', mpn_sublsh`'LSH`'_n)')
+ifdef(`DO_rsb', `
+ define(`ADDSUBC', `subfc $1, $3, $2')
+ define(`ADDSUBE', `subfe $1, $3, $2')
+ define(INITCY, `addic $1, r1, -1')
+ define(RETVAL, `addme r3, $1')
+ define(`func', mpn_rsblsh`'LSH`'_n)')
+
+define(`rpx', `r6')
+define(`upx', `r7')
+define(`vpx', `r12')
+
+define(`s0', `r0') define(`s1', `r9')
+define(`u0', `r8')
+define(`v0', `r10') define(`v1', `r11')
+
+
+ASM_START()
+PROLOGUE(func)
+ cmpldi cr0, n, 13
+ bgt L(big)
+
+ mtctr n C copy n in ctr
+ INITCY( r0) C clear cy
+
+ ld v0, 0(vp) C load v limb
+ ld u0, 0(up) C load u limb
+ addi up, up, -8 C update up
+ addi rp, rp, -8 C update rp
+ sldi s1, v0, LSH
+ bdz L(ex1) C If done, skip loop
+
+ ALIGN(16)
+L(lo0): ld v1, 8(vp) C load v limb
+ ADDSUBE(s1, s1, u0) C add limbs with cy, set cy
+ ldu u0, 16(up) C load u limb and update up
+ srdi s0, v0, RSH C shift down previous v limb
+ std s1, 8(rp) C store result limb
+ rldimi s0, v1, LSH, 0 C left shift v limb and merge with prev v limb
+ bdz L(ex0) C decrement ctr and exit if done
+ ldu v0, 16(vp) C load v limb and update vp
+ ADDSUBE(s0, s0, u0) C add limbs with cy, set cy
+ ld u0, 8(up) C load u limb
+ srdi s1, v1, RSH C shift down previous v limb
+ stdu s0, 16(rp) C store result limb and update rp
+ rldimi s1, v0, LSH, 0 C left shift v limb and merge with prev v limb
+ bdnz L(lo0) C decrement ctr and loop back
+
+L(ex1): ADDSUBE(r7, s1, u0)
+ std r7, 8(rp) C store last result limb
+ srdi r0, v0, RSH
+ RETVAL( r0)
+ blr
+L(ex0): ADDSUBE(r7, s0, u0)
+ std r7, 16(rp) C store last result limb
+ srdi r0, v1, RSH
+ RETVAL( r0)
+ blr
+
+
+L(big): rldicl. r0, n, 0,63 C r0 = n & 1, set cr0
+ addi r6, n, -1 C ...for ctr
+ srdi r6, r6, 1 C ...for ctr
+ mtctr r6 C copy count into ctr
+ beq cr0, L(b0)
+
+L(b1): ld v1, 0(vp)
+ ld u0, 0(up)
+ sldi s1, v1, LSH
+ srdi s0, v1, RSH
+ ld v0, 8(vp)
+ ADDSUBC(s1, s1, u0) C add limbs without cy, set cy
+ addi rpx, rp, -16
+ addi rp, rp, -8
+ sub upx, up, rp
+ sub vpx, vp, rp
+ sub up, up, rpx
+ sub vp, vp, rpx
+ addi up, up, 8
+ addi upx, upx, 16
+ addi vp, vp, 16
+ addi vpx, vpx, 24
+ b L(mid)
+
+L(b0): ld v0, 0(vp)
+ ld u0, 0(up)
+ sldi s0, v0, LSH
+ srdi s1, v0, RSH
+ ld v1, 8(vp)
+ ADDSUBC(s0, s0, u0) C add limbs without cy, set cy
+ addi rpx, rp, -8
+ addi rp, rp, -16
+ sub upx, up, rpx
+ sub vpx, vp, rpx
+ sub up, up, rp
+ sub vp, vp, rp
+ addi up, up, 8
+ addi upx, upx, 16
+ addi vp, vp, 16
+ addi vpx, vpx, 24
+
+ ALIGN(32)
+L(top): ldx u0, rp, up
+ ldx v0, rp, vp
+ rldimi s1, v1, LSH, 0
+ stdu s0, 16(rp)
+ srdi s0, v1, RSH
+ ADDSUBE(s1, s1, u0) C add limbs with cy, set cy
+L(mid): ldx u0, rpx, upx
+ ldx v1, rpx, vpx
+ rldimi s0, v0, LSH, 0
+ stdu s1, 16(rpx)
+ srdi s1, v0, RSH
+ ADDSUBE(s0, s0, u0) C add limbs with cy, set cy
+ bdnz L(top) C decrement CTR and loop back
+
+ ldx u0, rp, up
+ rldimi s1, v1, LSH, 0
+ std s0, 16(rp)
+ srdi s0, v1, RSH
+ ADDSUBE(s1, s1, u0) C add limbs with cy, set cy
+ std s1, 24(rp)
+
+ RETVAL( s0)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/bdiv_dbm1c.asm b/gmp/mpn/powerpc64/mode64/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..45cded9715
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/bdiv_dbm1c.asm
@@ -0,0 +1,132 @@
+dnl PPC64 mpn_bdiv_dbm1c.
+
+dnl Copyright 2008, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 6-18
+C POWER4/PPC970 8.25
+C POWER5 8.5 fluctuating as function of n % 3
+C POWER6 15
+C POWER7 4.75
+
+C TODO
+C * Nothing to do...
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`bd', `r6')
+define(`cy', `r7')
+
+ASM_START()
+PROLOGUE(mpn_bdiv_dbm1c)
+ ld r0, 0(r4)
+
+ rldicl. r12, r5, 0,62
+ cmpldi cr6, r12, 2
+ cmpldi cr7, r5, 4
+ addi r5, r5, 1
+ srwi r5, r5, 2
+ mtctr r5
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ beq cr6, L(b10)
+
+ ALIGN(16)
+L(b11): mulld r5, r0, r6
+ mulhdu r12, r0, r6
+ ld r0, 8(r4)
+ addi r4, r4, -24
+ addi r3, r3, -24
+ b L(3)
+
+ ALIGN(16)
+L(b00): mulld r9, r0, r6
+ mulhdu r8, r0, r6
+ addi r4, r4, -16
+ addi r3, r3, -16
+ b L(0)
+
+ ALIGN(16)
+L(b01): mulld r5, r0, r6
+ mulhdu r12, r0, r6
+ addi r3, r3, -8
+ ble cr7, L(e1)
+ ld r0, 8(r4)
+ addi r4, r4, -8
+ b L(1)
+
+ ALIGN(16)
+L(b10): mulld r9, r0, r6
+ mulhdu r8, r0, r6
+ ble cr7, L(e2)
+
+ ALIGN(16)
+L(top): subfc r11, r9, r7
+ ld r10, 8(r4)
+ ld r0, 16(r4)
+ subfe r7, r8, r11
+ std r11, 0(r3)
+ mulld r5, r10, r6
+ mulhdu r12, r10, r6
+L(1): mulld r9, r0, r6
+ mulhdu r8, r0, r6
+ subfc r11, r5, r7
+ subfe r7, r12, r11
+ std r11, 8(r3)
+L(0): subfc r11, r9, r7
+ ld r10, 24(r4)
+ ld r0, 32(r4)
+ subfe r7, r8, r11
+ std r11, 16(r3)
+ mulld r5, r10, r6
+ mulhdu r12, r10, r6
+L(3): mulld r9, r0, r6
+ mulhdu r8, r0, r6
+ subfc r11, r5, r7
+ subfe r7, r12, r11
+ std r11, 24(r3)
+ addi r4, r4, 32
+ addi r3, r3, 32
+ bdnz L(top)
+
+L(e2): ld r10, 8(r4)
+ mulld r5, r10, r6
+ mulhdu r12, r10, r6
+ subfc r11, r9, r7
+ subfe r7, r8, r11
+ std r11, 0(r3)
+L(e1): subfc r11, r5, r7
+ std r11, 8(r3)
+ subfe r3, r12, r11
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/cnd_aors_n.asm b/gmp/mpn/powerpc64/mode64/cnd_aors_n.asm
new file mode 100644
index 0000000000..24968c1912
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/cnd_aors_n.asm
@@ -0,0 +1,196 @@
+dnl PowerPC-64 mpn_cnd_add_n/mpn_cnd_sub_n.
+
+dnl Copyright 1999-2001, 2003-2005, 2007, 2011, 2012 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 2.25
+C POWER5 ?
+C POWER6 3
+C POWER7 2
+
+C INPUT PARAMETERS
+define(`cnd', `r3')
+define(`rp', `r4')
+define(`up', `r5')
+define(`vp', `r6')
+define(`n', `r7')
+
+ifdef(`OPERATION_cnd_add_n',`
+ define(ADDSUBC, adde)
+ define(ADDSUB, addc)
+ define(func, mpn_cnd_add_n)
+ define(GENRVAL, `addi r3, r3, 1')
+ define(SETCBR, `addic r0, $1, -1')
+ define(CLRCB, `addic r0, r0, 0')
+')
+ifdef(`OPERATION_cnd_sub_n',`
+ define(ADDSUBC, subfe)
+ define(ADDSUB, subfc)
+ define(func, mpn_cnd_sub_n)
+ define(GENRVAL, `neg r3, r3')
+ define(SETCBR, `subfic r0, $1, 0')
+ define(CLRCB, `addic r0, r1, -1')
+')
+
+MULFUNC_PROLOGUE(mpn_cnd_add_n mpn_cnd_sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ std r31, -8(r1)
+ std r30, -16(r1)
+ std r29, -24(r1)
+ std r28, -32(r1)
+ std r27, -40(r1)
+
+ subfic cnd, cnd, 0
+ subfe cnd, cnd, cnd
+
+ rldicl. r0, n, 0,62 C r0 = n & 3, set cr0
+ cmpdi cr6, r0, 2
+ addi n, n, 3 C compute count...
+ srdi n, n, 2 C ...for ctr
+ mtctr n C copy count into ctr
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ beq cr6, L(b10)
+
+L(b11): ld r8, 0(up) C load s1 limb
+ ld r9, 0(vp) C load s2 limb
+ ld r10, 8(up) C load s1 limb
+ ld r11, 8(vp) C load s2 limb
+ ld r12, 16(up) C load s1 limb
+ addi up, up, 24
+ ld r0, 16(vp) C load s2 limb
+ addi vp, vp, 24
+ and r9, r9, cnd
+ and r11, r11, cnd
+ and r0, r0, cnd
+ ADDSUB r29, r9, r8
+ ADDSUBC r30, r11, r10
+ ADDSUBC r31, r0, r12
+ std r29, 0(rp)
+ std r30, 8(rp)
+ std r31, 16(rp)
+ addi rp, rp, 24
+ bdnz L(go)
+ b L(ret)
+
+L(b01): ld r12, 0(up) C load s1 limb
+ addi up, up, 8
+ ld r0, 0(vp) C load s2 limb
+ addi vp, vp, 8
+ and r0, r0, cnd
+ ADDSUB r31, r0, r12 C add
+ std r31, 0(rp)
+ addi rp, rp, 8
+ bdnz L(go)
+ b L(ret)
+
+L(b10): ld r10, 0(up) C load s1 limb
+ ld r11, 0(vp) C load s2 limb
+ ld r12, 8(up) C load s1 limb
+ addi up, up, 16
+ ld r0, 8(vp) C load s2 limb
+ addi vp, vp, 16
+ and r11, r11, cnd
+ and r0, r0, cnd
+ ADDSUB r30, r11, r10 C add
+ ADDSUBC r31, r0, r12 C add
+ std r30, 0(rp)
+ std r31, 8(rp)
+ addi rp, rp, 16
+ bdnz L(go)
+ b L(ret)
+
+L(b00): CLRCB C clear/set cy
+L(go): ld r7, 0(up) C load s1 limb
+ ld r27, 0(vp) C load s2 limb
+ ld r8, 8(up) C load s1 limb
+ ld r9, 8(vp) C load s2 limb
+ ld r10, 16(up) C load s1 limb
+ ld r11, 16(vp) C load s2 limb
+ ld r12, 24(up) C load s1 limb
+ ld r0, 24(vp) C load s2 limb
+ and r27, r27, cnd
+ and r9, r9, cnd
+ and r11, r11, cnd
+ and r0, r0, cnd
+ bdz L(end)
+
+ addi up, up, 32
+ addi vp, vp, 32
+
+L(top): ADDSUBC r28, r27, r7
+ ld r7, 0(up) C load s1 limb
+ ld r27, 0(vp) C load s2 limb
+ ADDSUBC r29, r9, r8
+ ld r8, 8(up) C load s1 limb
+ ld r9, 8(vp) C load s2 limb
+ ADDSUBC r30, r11, r10
+ ld r10, 16(up) C load s1 limb
+ ld r11, 16(vp) C load s2 limb
+ ADDSUBC r31, r0, r12
+ ld r12, 24(up) C load s1 limb
+ ld r0, 24(vp) C load s2 limb
+ std r28, 0(rp)
+ addi up, up, 32
+ std r29, 8(rp)
+ addi vp, vp, 32
+ std r30, 16(rp)
+ std r31, 24(rp)
+ addi rp, rp, 32
+ and r27, r27, cnd
+ and r9, r9, cnd
+ and r11, r11, cnd
+ and r0, r0, cnd
+ bdnz L(top) C decrement ctr and loop back
+
+L(end): ADDSUBC r28, r27, r7
+ ADDSUBC r29, r9, r8
+ ADDSUBC r30, r11, r10
+ ADDSUBC r31, r0, r12
+ std r28, 0(rp)
+ std r29, 8(rp)
+ std r30, 16(rp)
+ std r31, 24(rp)
+
+L(ret): ld r31, -8(r1)
+ ld r30, -16(r1)
+ ld r29, -24(r1)
+ ld r28, -32(r1)
+ ld r27, -40(r1)
+
+ subfe r3, r0, r0 C -cy
+ GENRVAL
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/dive_1.asm b/gmp/mpn/powerpc64/mode64/dive_1.asm
new file mode 100644
index 0000000000..434dde9145
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/dive_1.asm
@@ -0,0 +1,132 @@
+dnl PowerPC-64 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2006, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C norm unorm
+C POWER3/PPC630 13-19
+C POWER4/PPC970 16
+C POWER5 16 16
+C POWER6 37 46
+C POWER7 12 12
+
+C TODO
+C * Check if n=1 code is really an improvement. It probably isn't.
+C * Make more similar to mode1o.asm.
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`d', `r6')
+
+
+ASM_START()
+
+EXTERN(binvert_limb_table)
+
+PROLOGUE(mpn_divexact_1,toc)
+ addic. n, n, -1
+ ld r12, 0(up)
+ bne cr0, L(2)
+ divdu r0, r12, d
+ std r0, 0(rp)
+ blr
+L(2):
+ rldicl. r0, d, 0, 63
+ li r10, 0
+ bne cr0, L(7)
+ neg r0, d
+ and r0, d, r0
+ cntlzd r0, r0
+ subfic r0, r0, 63
+ rldicl r10, r0, 0, 32
+ srd d, d, r0
+L(7):
+ mtctr n
+ LEA( r5, binvert_limb_table)
+ rldicl r11, d, 63, 57
+ lbzx r0, r5, r11
+ mulld r9, r0, r0
+ sldi r0, r0, 1
+ mulld r9, d, r9
+ subf r0, r9, r0
+ mulld r5, r0, r0
+ sldi r0, r0, 1
+ mulld r5, d, r5
+ subf r0, r5, r0
+ mulld r9, r0, r0
+ sldi r0, r0, 1
+ mulld r9, d, r9
+ subf r7, r9, r0 C r7 = 1/d mod 2^64
+ bne cr0, L(norm)
+ subfic r8, r10, 64 C set carry as side effect
+ li r5, 0
+ srd r11, r12, r10
+
+ ALIGN(16)
+L(loop0):
+ ld r12, 8(up)
+ nop
+ addi up, up, 8
+ sld r0, r12, r8
+ or r11, r11, r0
+ subfe r9, r5, r11
+ srd r11, r12, r10
+ mulld r0, r7, r9
+ mulhdu r5, r0, d
+ std r0, 0(rp)
+ addi rp, rp, 8
+ bdnz L(loop0)
+
+ subfe r0, r5, r11
+ mulld r0, r7, r0
+ std r0, 0(rp)
+ blr
+
+ ALIGN(16)
+L(norm):
+ mulld r11, r12, r7
+ mulhdu r5, r11, d
+ std r11, 0(rp)
+ ALIGN(16)
+L(loop1):
+ ld r9, 8(up)
+ addi up, up, 8
+ subfe r5, r5, r9
+ mulld r11, r7, r5
+ mulhdu r5, r11, d C result not used
+ std r11, 8(rp)
+ addi rp, rp, 8
+ bdnz L(loop1)
+ blr
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/powerpc64/mode64/divrem_1.asm b/gmp/mpn/powerpc64/mode64/divrem_1.asm
new file mode 100644
index 0000000000..b283877006
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/divrem_1.asm
@@ -0,0 +1,274 @@
+dnl PowerPC-64 mpn_divrem_1 -- Divide an mpn number by an unnormalized limb.
+
+dnl Copyright 2003-2005, 2007, 2008, 2010, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C norm unorm frac
+C POWER3/PPC630 16-34 16-34 ~11 outdated figures
+C POWER4/PPC970 28 28 19
+C POWER5 29 29 ~19
+C POWER6 49 59 ~42
+C POWER7 24.5 23 ~14
+
+C INPUT PARAMETERS
+C qp = r3
+C fn = r4
+C up = r5
+C un = r6
+C d = r7
+
+C We use a not very predictable branch in the frac code, therefore the cycle
+C count wobbles somewhat. With the alternative branch-free code, things run
+C considerably slower on POWER4/PPC970 and POWER5.
+
+C Add preinv entry point.
+
+
+ASM_START()
+
+EXTERN_FUNC(mpn_invert_limb)
+
+PROLOGUE(mpn_divrem_1,toc)
+
+ mfcr r12
+ add. r10, r6, r4
+ std r25, -56(r1)
+ mr r25, r4
+ mflr r0
+ std r26, -48(r1)
+ mr r26, r5
+ std r28, -32(r1)
+ mr r28, r6
+ std r29, -24(r1)
+ mr r29, r3
+ li r3, 0
+ std r30, -16(r1)
+ mr r30, r7
+ std r31, -8(r1)
+ li r31, 0
+ std r27, -40(r1)
+ std r0, 16(r1)
+ stw r12, 8(r1)
+ stdu r1, -176(r1)
+ beq- cr0, L(1)
+ cmpdi cr7, r7, 0
+ sldi r0, r10, 3
+ add r11, r0, r29
+ addi r29, r11, -8
+ blt- cr7, L(162)
+ cmpdi cr4, r6, 0
+ beq+ cr4, L(71)
+L(163):
+ sldi r9, r6, 3
+ add r9, r9, r5
+ ld r7, -8(r9)
+ cmpld cr7, r7, r30
+ bge- cr7, L(71)
+ cmpdi cr7, r10, 1
+ li r0, 0
+ mr r31, r7
+ std r0, -8(r11)
+ addi r29, r29, -8
+ mr r3, r7
+ beq- cr7, L(1)
+ addi r28, r6, -1
+ cmpdi cr4, r28, 0
+L(71):
+ cntlzd r27, r30
+ sld r30, r30, r27
+ sld r31, r31, r27
+ mr r3, r30
+ CALL( mpn_invert_limb)
+ beq- cr4, L(110)
+ sldi r9, r28, 3
+ addic. r6, r28, -2
+ add r9, r9, r26
+ subfic r5, r27, 64
+ ld r8, -8(r9)
+ srd r0, r8, r5
+ or r31, r31, r0
+ sld r7, r8, r27
+ blt- cr0, L(154)
+ addi r28, r28, -1
+ mtctr r28
+ sldi r6, r6, 3
+ ALIGN(16)
+L(uloop):
+ ldx r8, r26, r6
+ nop
+ mulld r0, r31, r3
+ mulhdu r10, r31, r3
+ addi r11, r31, 1
+ srd r9, r8, r5
+ addi r6, r6, -8
+ or r9, r7, r9
+ addc r0, r0, r9
+ adde r10, r10, r11
+ mulld r31, r10, r30
+ subf r31, r31, r9
+ subfc r0, r31, r0 C r <= ql
+ subfe r0, r0, r0 C r0 = -(r <= ql)
+ and r9, r30, r0
+ add r31, r31, r9
+ add r10, r0, r10 C qh -= (r >= ql)
+ cmpld cr7, r31, r30
+ bge- cr7, L(164)
+L(123):
+ std r10, 0(r29)
+ addi r29, r29, -8
+ sld r7, r8, r27
+ bdnz L(uloop)
+L(154):
+ addi r11, r31, 1
+ nop
+ mulld r0, r31, r3
+ mulhdu r8, r31, r3
+ addc r0, r0, r7
+ adde r8, r8, r11
+ mulld r31, r8, r30
+ subf r31, r31, r7
+ subfc r0, r0, r31 C r >= ql
+ subfe r0, r0, r0 C r0 = -(r >= ql)
+ not r7, r0
+ add r8, r7, r8 C qh -= (r >= ql)
+ andc r0, r30, r0
+ add r31, r31, r0
+ cmpld cr7, r31, r30
+ bge- cr7, L(165)
+L(134):
+ std r8, 0(r29)
+ addi r29, r29, -8
+L(110):
+ addic. r0, r25, -1
+ blt- cr0, L(156)
+ mtctr r25
+ neg r9, r30
+ ALIGN(16)
+L(ufloop):
+ addi r11, r31, 1
+ nop
+ mulld r0, r3, r31
+ mulhdu r10, r3, r31
+ add r10, r10, r11
+ mulld r31, r9, r10
+ifelse(0,1,`
+ subfc r0, r0, r31
+ subfe r0, r0, r0 C r0 = -(r >= ql)
+ not r7, r0
+ add r10, r7, r10 C qh -= (r >= ql)
+ andc r0, r30, r0
+ add r31, r31, r0
+',`
+ cmpld cr7, r31, r0
+ blt cr7, L(29)
+ add r31, r30, r31
+ addi r10, r10, -1
+L(29):
+')
+ std r10, 0(r29)
+ addi r29, r29, -8
+ bdnz L(ufloop)
+L(156):
+ srd r3, r31, r27
+L(1):
+ addi r1, r1, 176
+ ld r0, 16(r1)
+ lwz r12, 8(r1)
+ mtlr r0
+ ld r25, -56(r1)
+ ld r26, -48(r1)
+ mtcrf 8, r12
+ ld r27, -40(r1)
+ ld r28, -32(r1)
+ ld r29, -24(r1)
+ ld r30, -16(r1)
+ ld r31, -8(r1)
+ blr
+L(162):
+ cmpdi cr7, r6, 0
+ beq- cr7, L(8)
+ sldi r9, r6, 3
+ addi r29, r29, -8
+ add r9, r9, r5
+ addi r28, r6, -1
+ ld r31, -8(r9)
+ subfc r9, r7, r31
+ li r9, 0
+ adde r9, r9, r9
+ neg r0, r9
+ std r9, -8(r11)
+ and r0, r0, r7
+ subf r31, r0, r31
+L(8):
+ mr r3, r30
+ CALL( mpn_invert_limb)
+ li r27, 0
+ addic. r6, r28, -1
+ blt- cr0, L(110)
+ mtctr r28
+ sldi r6, r6, 3
+ ALIGN(16)
+L(nloop):
+ addi r11, r31, 1
+ ldx r8, r26, r6
+ mulld r0, r31, r3
+ mulhdu r10, r31, r3
+ addi r6, r6, -8
+ addc r0, r0, r8
+ adde r10, r10, r11
+ mulld r31, r10, r30
+ subf r31, r31, r8 C r = nl - qh * d
+ subfc r0, r31, r0 C r <= ql
+ subfe r0, r0, r0 C r0 = -(r <= ql)
+ and r9, r30, r0
+ add r31, r31, r9
+ add r10, r0, r10 C qh -= (r >= ql)
+ cmpld cr7, r31, r30
+ bge- cr7, L(167)
+L(51):
+ std r10, 0(r29)
+ addi r29, r29, -8
+ bdnz L(nloop)
+ b L(110)
+
+L(164):
+ subf r31, r30, r31
+ addi r10, r10, 1
+ b L(123)
+L(167):
+ subf r31, r30, r31
+ addi r10, r10, 1
+ b L(51)
+L(165):
+ subf r31, r30, r31
+ addi r8, r8, 1
+ b L(134)
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/divrem_2.asm b/gmp/mpn/powerpc64/mode64/divrem_2.asm
new file mode 100644
index 0000000000..73ec23c94d
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/divrem_2.asm
@@ -0,0 +1,187 @@
+dnl PPC-64 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number.
+
+dnl Copyright 2007, 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C norm frac
+C POWER3/PPC630
+C POWER4/PPC970 ? ?
+C POWER5 37 ?
+C POWER6 62 ?
+C POWER6 30.5 ?
+
+C INPUT PARAMETERS
+C qp = r3
+C fn = r4
+C up = r5
+C un = r6
+C dp = r7
+
+
+ifdef(`DARWIN',,`
+define(`r2',`r31')') C FIXME!
+
+ASM_START()
+
+EXTERN_FUNC(mpn_invert_limb)
+
+PROLOGUE(mpn_divrem_2,toc)
+ mflr r0
+ std r23, -72(r1)
+ std r24, -64(r1)
+ std r25, -56(r1)
+ std r26, -48(r1)
+ std r27, -40(r1)
+ std r28, -32(r1)
+ std r29, -24(r1)
+ std r30, -16(r1)
+ std r31, -8(r1)
+ std r0, 16(r1)
+ stdu r1, -192(r1)
+ mr r24, r3
+ mr r25, r4
+ sldi r0, r6, 3
+ add r26, r5, r0
+ addi r26, r26, -24
+ ld r30, 8(r7)
+ ld r28, 0(r7)
+ ld r29, 16(r26)
+ ld r31, 8(r26)
+
+ifelse(0,1,`
+ li r23, 0
+ cmpld cr7, r29, r30
+ blt cr7, L(8)
+ bgt cr7, L(9)
+ cmpld cr0, r31, r28
+ blt cr0, L(8)
+L(9): subfc r31, r28, r31
+ subfe r29, r30, r29
+ li r23, 1
+',`
+ li r23, 0
+ cmpld cr7, r29, r30
+ blt cr7, L(8)
+ mfcr r0
+ rlwinm r0, r0, 30, 1
+ subfc r9, r28, r31
+ addze. r0, r0
+ nop
+ beq cr0, L(8)
+ subfc r31, r28, r31
+ subfe r29, r30, r29
+ li r23, 1
+')
+
+L(8):
+ add r27, r25, r6
+ addic. r27, r27, -3
+ blt cr0, L(18)
+ mr r3, r30
+ CALL( mpn_invert_limb)
+ mulld r10, r3, r30
+ mulhdu r0, r3, r28
+ addc r8, r10, r28
+ subfe r11, r1, r1
+ addc r10, r8, r0
+ addze. r11, r11
+ blt cr0, L(91)
+L(40):
+ subfc r10, r30, r10
+ addme. r11, r11
+ addi r3, r3, -1
+ bge cr0, L(40)
+L(91):
+ addi r5, r27, 1
+ mtctr r5
+ sldi r0, r27, 3
+ add r24, r24, r0
+ ALIGN(16)
+L(loop):
+ mulhdu r8, r29, r3
+ mulld r6, r29, r3
+ addc r6, r6, r31
+ adde r8, r8, r29
+ cmpd cr7, r27, r25
+ mulld r0, r30, r8
+ mulhdu r11, r28, r8
+ mulld r10, r28, r8
+ subf r31, r0, r31
+ li r7, 0
+ blt cr7, L(60)
+ ld r7, 0(r26)
+ addi r26, r26, -8
+ nop
+L(60): subfc r7, r28, r7
+ subfe r31, r30, r31
+ subfc r7, r10, r7
+ subfe r4, r11, r31
+ subfc r9, r6, r4
+ subfe r9, r1, r1
+ andc r6, r28, r9
+ andc r0, r30, r9
+ addc r31, r7, r6
+ adde r29, r4, r0
+ subf r8, r9, r8
+ cmpld cr7, r29, r30
+ bge- cr7, L(fix)
+L(bck): std r8, 0(r24)
+ addi r24, r24, -8
+ addi r27, r27, -1
+ bdnz L(loop)
+L(18):
+ std r31, 8(r26)
+ std r29, 16(r26)
+ mr r3, r23
+ addi r1, r1, 192
+ ld r0, 16(r1)
+ mtlr r0
+ ld r23, -72(r1)
+ ld r24, -64(r1)
+ ld r25, -56(r1)
+ ld r26, -48(r1)
+ ld r27, -40(r1)
+ ld r28, -32(r1)
+ ld r29, -24(r1)
+ ld r30, -16(r1)
+ ld r31, -8(r1)
+ blr
+L(fix):
+ mfcr r0
+ rlwinm r0, r0, 30, 1
+ subfc r9, r28, r31
+ addze. r0, r0
+ beq cr0, L(bck)
+ subfc r31, r28, r31
+ subfe r29, r30, r29
+ addi r8, r8, 1
+ b L(bck)
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/gcd_1.asm b/gmp/mpn/powerpc64/mode64/gcd_1.asm
new file mode 100644
index 0000000000..8762bbbef5
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/gcd_1.asm
@@ -0,0 +1,122 @@
+dnl PowerPC-64 mpn_gcd_1.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/bit (approx)
+C POWER3/PPC630 ?
+C POWER4/PPC970 8.5
+C POWER5 ?
+C POWER6 10.1
+C POWER7 9.4
+C Numbers measured with: speed -CD -s16-64 -t48 mpn_gcd_1
+
+C INPUT PARAMETERS
+define(`up', `r3')
+define(`n', `r4')
+define(`v0', `r5')
+
+EXTERN_FUNC(mpn_mod_1)
+EXTERN_FUNC(mpn_modexact_1c_odd)
+
+ASM_START()
+PROLOGUE(mpn_gcd_1,toc)
+ mflr r0
+ std r30, -16(r1)
+ std r31, -8(r1)
+ std r0, 16(r1)
+ stdu r1, -128(r1)
+
+ ld r7, 0(up) C U low limb
+ or r0, r5, r7 C x | y
+
+ neg r6, r0
+ and r6, r6, r0
+ cntlzd r31, r6 C common twos
+ subfic r31, r31, 63
+
+ neg r6, r5
+ and r6, r6, r5
+ cntlzd r8, r6
+ subfic r8, r8, 63
+ srd r5, r5, r8
+ mr r30, r5 C v0 saved
+
+ cmpdi r4, BMOD_1_TO_MOD_1_THRESHOLD
+ blt L(bmod)
+ CALL( mpn_mod_1)
+ b L(reduced)
+L(bmod):
+ li r6, 0
+ CALL( mpn_modexact_1c_odd)
+L(reduced):
+
+define(`mask', `r0')dnl
+define(`a1', `r4')dnl
+define(`a2', `r5')dnl
+define(`d1', `r6')dnl
+define(`d2', `r7')dnl
+define(`cnt', `r9')dnl
+
+ neg. r6, r3
+ and r6, r6, r3
+ cntlzd cnt, r6
+ subfic cnt, cnt, 63
+ li r12, 63
+ bne L(mid)
+ b L(end)
+
+ ALIGN(16)
+L(top):
+ and a1, r10, mask C d - a
+ andc a2, r11, mask C a - d
+ and d1, r3, mask C a
+ andc d2, r30, mask C d
+ or r3, a1, a2 C new a
+ subf cnt, cnt, r12
+ or r30, d1, d2 C new d
+L(mid): srd r3, r3, cnt
+ sub. r10, r30, r3 C r10 = d - a
+ subc r11, r3, r30 C r11 = a - d
+ neg r8, r10
+ and r8, r8, r10
+ subfe mask, mask, mask
+ cntlzd cnt, r8
+ bne L(top)
+
+L(end): sld r3, r30, r31
+
+ addi r1, r1, 128
+ ld r0, 16(r1)
+ ld r30, -16(r1)
+ ld r31, -8(r1)
+ mtlr r0
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/gmp-mparam.h b/gmp/mpn/powerpc64/mode64/gmp-mparam.h
new file mode 100644
index 0000000000..f8305f4720
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/gmp-mparam.h
@@ -0,0 +1,82 @@
+/* PowerPC-64 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2008, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 1600MHz PPC970 */
+
+/* Generated by tuneup.c, 2009-01-14, gcc 4.0 */
+
+#define MUL_TOOM22_THRESHOLD 14
+#define MUL_TOOM33_THRESHOLD 93
+#define MUL_TOOM44_THRESHOLD 135
+
+#define SQR_BASECASE_THRESHOLD 6
+#define SQR_TOOM2_THRESHOLD 32
+#define SQR_TOOM3_THRESHOLD 74
+#define SQR_TOOM4_THRESHOLD 136
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 44
+#define MULLO_MUL_N_THRESHOLD 234
+
+#define DIV_SB_PREINV_THRESHOLD 0 /* always */
+#define DIV_DC_THRESHOLD 33
+#define POWM_THRESHOLD 89
+
+#define MATRIX22_STRASSEN_THRESHOLD 15
+#define HGCD_THRESHOLD 93
+#define GCD_DC_THRESHOLD 237
+#define GCDEXT_DC_THRESHOLD 273
+#define JACOBI_BASE_METHOD 1
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1_THRESHOLD 6
+#define MOD_1_2_THRESHOLD 9
+#define MOD_1_4_THRESHOLD 23
+#define USE_PREINV_DIVREM_1 0
+#define USE_PREINV_MOD_1 0
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always (native) */
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 24
+#define SET_STR_DC_THRESHOLD 650
+#define SET_STR_PRECOMPUTE_THRESHOLD 1713
+
+#define MUL_FFT_TABLE { 336, 672, 1856, 2816, 7168, 20480, 81920, 327680, 0 }
+#define MUL_FFT_MODF_THRESHOLD 304
+#define MUL_FFT_THRESHOLD 4224
+
+#define SQR_FFT_TABLE { 272, 672, 1600, 2816, 7168, 20480, 81920, 327680, 786432, 0 }
+#define SQR_FFT_MODF_THRESHOLD 272
+#define SQR_FFT_THRESHOLD 2688
diff --git a/gmp/mpn/powerpc64/mode64/invert_limb.asm b/gmp/mpn/powerpc64/mode64/invert_limb.asm
new file mode 100644
index 0000000000..dfdba6451e
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/invert_limb.asm
@@ -0,0 +1,88 @@
+dnl PowerPC-64 mpn_invert_limb -- Invert a normalized limb.
+
+dnl Copyright 2004-2006, 2008, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb (approximate)
+C POWER3/PPC630 80
+C POWER4/PPC970 86
+C POWER5 86
+C POWER6 170
+C POWER7 66
+
+ASM_START()
+PROLOGUE(mpn_invert_limb,toc)
+ LEAL( r12, approx_tab)
+ srdi r9, r3, 32
+ rlwinm r9, r9, 10, 23, 30 C (d >> 55) & 0x1fe
+ srdi r10, r3, 24 C d >> 24
+ lis r11, 0x1000
+ rldicl r8, r3, 0, 63 C d mod 2
+ addi r10, r10, 1 C d40
+ sldi r11, r11, 32 C 2^60
+ srdi r7, r3, 1 C d/2
+ add r7, r7, r8 C d63 = ceil(d/2)
+ neg r8, r8 C mask = -(d mod 2)
+ lhzx r0, r9, r12
+ mullw r9, r0, r0 C v0*v0
+ sldi r6, r0, 11 C v0 << 11
+ addi r0, r6, -1 C (v0 << 11) - 1
+ mulld r9, r9, r10 C v0*v0*d40
+ srdi r9, r9, 40 C v0*v0*d40 >> 40
+ subf r9, r9, r0 C v1 = (v0 << 11) - (v0*v0*d40 >> 40) - 1
+ mulld r0, r9, r10 C v1*d40
+ sldi r6, r9, 13 C v1 << 13
+ subf r0, r0, r11 C 2^60 - v1*d40
+ mulld r0, r0, r9 C v1 * (2^60 - v1*d40)
+ srdi r0, r0, 47 C v1 * (2^60 - v1*d40) >> 47
+ add r0, r0, r6 C v2 = (v1 << 13) + (v1 * (2^60 - v1*d40) >> 47)
+ mulld r11, r0, r7 C v2 * d63
+ srdi r10, r0, 1 C v2 >> 1
+ sldi r9, r0, 31 C v2 << 31
+ and r8, r10, r8 C (v2 >> 1) & mask
+ subf r8, r11, r8 C ((v2 >> 1) & mask) - v2 * d63
+ mulhdu r0, r8, r0 C p1 = v2 * (((v2 >> 1) & mask) - v2 * d63)
+ srdi r0, r0, 1 C p1 >> 1
+ add r0, r0, r9 C v3 = (v2 << 31) + (p1 >> 1)
+ nop
+ mulld r11, r0, r3
+ mulhdu r9, r0, r3
+ addc r10, r11, r3
+ adde r3, r9, r3
+ subf r3, r3, r0
+ blr
+EPILOGUE()
+
+DEF_OBJECT(approx_tab)
+forloop(i,256,512-1,dnl
+` .short eval(0x7fd00/i)
+')dnl
+END_OBJECT(approx_tab)
+ASM_END()
diff --git a/gmp/mpn/powerpc64/mode64/mod_1_1.asm b/gmp/mpn/powerpc64/mode64/mod_1_1.asm
new file mode 100644
index 0000000000..873373054f
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/mod_1_1.asm
@@ -0,0 +1,164 @@
+dnl PowerPC-64 mpn_mod_1_1p
+
+dnl Copyright 2010, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 17
+C POWER5 16
+C POWER6 30
+C POWER7 10.2
+
+C TODO
+C * Optimise, in particular the cps function. This was compiler-generated and
+C then hand optimised.
+
+C INPUT PARAMETERS
+define(`ap', `r3')
+define(`n', `r4')
+define(`d', `r5')
+define(`cps', `r6')
+
+ASM_START()
+
+EXTERN_FUNC(mpn_invert_limb)
+
+PROLOGUE(mpn_mod_1_1p)
+ sldi r10, r4, 3
+ addi r4, r4, -1
+ add r3, r3, r10
+ ld r0, 16(r6) C B1modb
+ ld r12, 24(r6) C B2modb
+ ld r9, -8(r3)
+ ld r10, -16(r3)
+ mtctr r4
+ mulhdu r8, r9, r0
+ mulld r7, r9, r0
+ addc r11, r7, r10
+ addze r9, r8
+ bdz L(end)
+
+ ALIGN(16)
+L(top): ld r4, -24(r3)
+ addi r3, r3, -8
+ nop
+ mulld r10, r11, r0
+ mulld r8, r9, r12
+ mulhdu r11, r11, r0
+ mulhdu r9, r9, r12
+ addc r7, r10, r4
+ addze r10, r11
+ addc r11, r8, r7
+ adde r9, r9, r10
+ bdnz L(top)
+
+L(end):
+ifdef(`HAVE_LIMB_LITTLE_ENDIAN',
+` lwz r0, 8(r6)',
+` lwz r0, 12(r6)')
+ ld r3, 0(r6)
+ cmpdi cr7, r0, 0
+ beq- cr7, L(4)
+ subfic r10, r0, 64
+ sld r9, r9, r0
+ srd r10, r11, r10
+ or r9, r10, r9
+L(4): subfc r10, r5, r9
+ subfe r10, r10, r10
+ nand r10, r10, r10
+ sld r11, r11, r0
+ and r10, r10, r5
+ subf r9, r10, r9
+ mulhdu r10, r9, r3
+ mulld r3, r9, r3
+ addi r9, r9, 1
+ addc r8, r3, r11
+ adde r3, r10, r9
+ mulld r3, r3, r5
+ subf r3, r3, r11
+ cmpld cr7, r8, r3
+ bge cr7, L(5) C FIXME: Make branch-less
+ add r3, r3, r5
+L(5): cmpld cr7, r3, r5
+ bge- cr7, L(10)
+ srd r3, r3, r0
+ blr
+
+L(10): subf r3, r5, r3
+ srd r3, r3, r0
+ blr
+EPILOGUE()
+
+PROLOGUE(mpn_mod_1_1p_cps,toc)
+ mflr r0
+ std r29, -24(r1)
+ std r30, -16(r1)
+ std r31, -8(r1)
+ cntlzd r31, r4
+ std r0, 16(r1)
+ extsw r31, r31
+ mr r29, r3
+ stdu r1, -144(r1)
+ sld r30, r4, r31
+ mr r3, r30
+ CALL( mpn_invert_limb)
+ cmpdi cr7, r31, 0
+ neg r0, r30
+ beq- cr7, L(13)
+ subfic r11, r31, 64
+ li r0, 1
+ neg r9, r30
+ srd r11, r3, r11
+ sld r0, r0, r31
+ or r0, r11, r0
+ mulld r0, r0, r9
+L(13): mulhdu r9, r0, r3
+ mulld r11, r0, r3
+ add r9, r0, r9
+ nor r9, r9, r9
+ mulld r9, r9, r30
+ cmpld cr7, r11, r9
+ bge cr7, L(14)
+ add r9, r9, r30
+L(14): addi r1, r1, 144
+ srd r0, r0, r31
+ std r31, 8(r29)
+ std r3, 0(r29)
+ std r0, 16(r29)
+ ld r0, 16(r1)
+ srd r9, r9, r31
+ ld r30, -16(r1)
+ ld r31, -8(r1)
+ std r9, 24(r29)
+ ld r29, -24(r1)
+ mtlr r0
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/mod_1_4.asm b/gmp/mpn/powerpc64/mode64/mod_1_4.asm
new file mode 100644
index 0000000000..0b7d6bf699
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/mod_1_4.asm
@@ -0,0 +1,270 @@
+dnl PowerPC-64 mpn_mod_1s_4p
+
+dnl Copyright 2010, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 9
+C POWER5 9
+C POWER6 13
+C POWER7 3.5
+
+C TODO
+C * Optimise, in particular the cps function. This was compiler-generated and
+C then hand optimised.
+
+C INPUT PARAMETERS
+define(`ap', `r3')
+define(`n', `r4')
+define(`d', `r5')
+define(`cps', `r6')
+
+ASM_START()
+
+EXTERN_FUNC(mpn_invert_limb)
+
+PROLOGUE(mpn_mod_1s_4p)
+ std r23, -72(r1)
+ ld r23, 48(cps)
+ std r24, -64(r1)
+ std r25, -56(r1)
+ ld r24, 32(cps)
+ ld r25, 24(cps)
+ std r26, -48(r1)
+ std r27, -40(r1)
+ ld r26, 16(cps)
+ std r28, -32(r1)
+ std r29, -24(r1)
+ std r30, -16(r1)
+ std r31, -8(r1)
+ ld r30, 40(cps)
+
+ rldicl. r0, n, 0,62
+ sldi r31, n, 3
+ add ap, ap, r31 C make ap point at end of operand
+
+ cmpdi cr7, r0, 2
+ beq cr0, L(b00)
+ blt cr7, L(b01)
+ beq cr7, L(b10)
+
+L(b11): ld r11, -16(ap)
+ ld r9, -8(ap)
+ ld r0, -24(ap)
+ mulhdu r27, r11, r26
+ mulld r8, r11, r26
+ mulhdu r11, r9, r25
+ mulld r9, r9, r25
+ addc r31, r8, r0
+ addze r10, r27
+ addc r0, r9, r31
+ adde r9, r11, r10
+ addi ap, ap, -40
+ b L(6)
+
+ ALIGN(16)
+L(b00): ld r11, -24(ap)
+ ld r10, -16(ap)
+ ld r9, -8(ap)
+ ld r0, -32(ap)
+ mulld r8, r11, r26
+ mulhdu r7, r10, r25
+ mulhdu r27, r11, r26
+ mulhdu r11, r9, r24
+ mulld r10, r10, r25
+ mulld r9, r9, r24
+ addc r31, r8, r0
+ addze r0, r27
+ addc r8, r31, r10
+ adde r10, r0, r7
+ addc r0, r9, r8
+ adde r9, r11, r10
+ addi ap, ap, -48
+ b L(6)
+
+ ALIGN(16)
+L(b01): li r9, 0
+ ld r0, -8(ap)
+ addi ap, ap, -24
+ b L(6)
+
+ ALIGN(16)
+L(b10): ld r9, -8(ap)
+ ld r0, -16(ap)
+ addi ap, ap, -32
+
+ ALIGN(16)
+L(6): addi r10, n, 3
+ srdi r7, r10, 2
+ mtctr r7
+ bdz L(end)
+
+ ALIGN(16)
+L(top): ld r31, -16(ap)
+ ld r10, -8(ap)
+ ld r11, 8(ap)
+ ld r12, 0(ap)
+ mulld r29, r0, r30 C rl * B4modb
+ mulhdu r0, r0, r30 C rl * B4modb
+ mulhdu r27, r10, r26
+ mulld r10, r10, r26
+ mulhdu r7, r9, r23 C rh * B5modb
+ mulld r9, r9, r23 C rh * B5modb
+ mulhdu r28, r11, r24
+ mulld r11, r11, r24
+ mulhdu r4, r12, r25
+ mulld r12, r12, r25
+ addc r8, r10, r31
+ addze r10, r27
+ addi ap, ap, -32
+ addc r27, r8, r12
+ adde r12, r10, r4
+ addc r11, r27, r11
+ adde r31, r12, r28
+ addc r12, r11, r29
+ adde r4, r31, r0
+ addc r0, r9, r12
+ adde r9, r7, r4
+ bdnz L(top)
+
+L(end):
+ifdef(`HAVE_LIMB_LITTLE_ENDIAN',
+` lwz r3, 8(cps)',
+` lwz r3, 12(cps)')
+ mulld r10, r9, r26
+ mulhdu r9, r9, r26
+ addc r11, r0, r10
+ addze r9, r9
+ ld r10, 0(cps)
+ subfic r8, r3, 64
+ sld r9, r9, r3
+ srd r8, r11, r8
+ sld r11, r11, r3
+ or r9, r8, r9
+ mulld r0, r9, r10
+ mulhdu r10, r9, r10
+ addi r9, r9, 1
+ addc r8, r0, r11
+ adde r0, r10, r9
+ mulld r0, r0, d
+ subf r0, r0, r11
+ cmpld cr7, r8, r0
+ bge cr7, L(9)
+ add r0, r0, d
+L(9): cmpld cr7, r0, d
+ bge- cr7, L(16)
+L(10): srd r3, r0, r3
+ ld r23, -72(r1)
+ ld r24, -64(r1)
+ ld r25, -56(r1)
+ ld r26, -48(r1)
+ ld r27, -40(r1)
+ ld r28, -32(r1)
+ ld r29, -24(r1)
+ ld r30, -16(r1)
+ ld r31, -8(r1)
+ blr
+
+L(16): subf r0, d, r0
+ b L(10)
+EPILOGUE()
+
+PROLOGUE(mpn_mod_1s_4p_cps,toc)
+ mflr r0
+ std r29, -24(r1)
+ std r30, -16(r1)
+ mr r29, r3
+ std r0, 16(r1)
+ std r31, -8(r1)
+ stdu r1, -144(r1)
+ cntlzd r31, r4
+ sld r30, r4, r31
+ mr r3, r30
+ CALL( mpn_invert_limb)
+ subfic r9, r31, 64
+ li r10, 1
+ sld r10, r10, r31
+ srd r9, r3, r9
+ neg r0, r30
+ or r10, r10, r9
+ mulld r10, r10, r0
+ mulhdu r11, r10, r3
+ nor r11, r11, r11
+ subf r11, r10, r11
+ mulld r11, r11, r30
+ mulld r0, r10, r3
+ cmpld cr7, r0, r11
+ bge cr7, L(18)
+ add r11, r11, r30
+L(18): mulhdu r9, r11, r3
+ add r9, r11, r9
+ nor r9, r9, r9
+ mulld r9, r9, r30
+ mulld r0, r11, r3
+ cmpld cr7, r0, r9
+ bge cr7, L(19)
+ add r9, r9, r30
+L(19): mulhdu r0, r9, r3
+ add r0, r9, r0
+ nor r0, r0, r0
+ mulld r0, r0, r30
+ mulld r8, r9, r3
+ cmpld cr7, r8, r0
+ bge cr7, L(20)
+ add r0, r0, r30
+L(20): mulhdu r8, r0, r3
+ add r8, r0, r8
+ nor r8, r8, r8
+ mulld r8, r8, r30
+ mulld r7, r0, r3
+ cmpld cr7, r7, r8
+ bge cr7, L(21)
+ add r8, r8, r30
+L(21): srd r0, r0, r31
+ addi r1, r1, 144
+ srd r8, r8, r31
+ srd r10, r10, r31
+ srd r11, r11, r31
+ std r0, 40(r29)
+ std r31, 8(r29)
+ srd r9, r9, r31
+ ld r0, 16(r1)
+ ld r30, -16(r1)
+ std r8, 48(r29)
+ std r3, 0(r29)
+ mtlr r0
+ ld r31, -8(r1)
+ std r10, 16(r29)
+ std r11, 24(r29)
+ std r9, 32(r29)
+ ld r29, -24(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/mod_34lsub1.asm b/gmp/mpn/powerpc64/mode64/mod_34lsub1.asm
new file mode 100644
index 0000000000..c35e0e37a4
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/mod_34lsub1.asm
@@ -0,0 +1,132 @@
+dnl PowerPC-64 mpn_mod_34lsub1 -- modulo 2^48-1.
+
+dnl Copyright 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 1.33
+C POWER4/PPC970 1.5
+C POWER5 1.32
+C POWER6 2.35
+C POWER7 1
+
+C INPUT PARAMETERS
+define(`up',`r3')
+define(`n',`r4')
+
+ASM_START()
+PROLOGUE(mpn_mod_34lsub1)
+ li r8, 0
+ li r9, 0
+ li r10, 0
+ li r11, 0
+
+ cmpdi cr6, n, 3
+ blt cr6, L(lt3)
+
+ li r0, -0x5556 C 0xFFFFFFFFFFFFAAAA
+ rldimi r0, r0, 16, 32 C 0xFFFFFFFFAAAAAAAA
+ rldimi r0, r0, 32, 63 C 0xAAAAAAAAAAAAAAAB
+ mulhdu r0, r0, n
+ srdi r0, r0, 1 C r0 = [n / 3]
+ mtctr r0
+
+ ld r5, 0(up)
+ ld r6, 8(up)
+ ld r7, 16(up)
+ addi up, up, 24
+ bdz L(end)
+
+ ALIGN(16)
+L(top): addc r8, r8, r5
+ nop
+ ld r5, 0(up)
+ adde r9, r9, r6
+ ld r6, 8(up)
+ adde r10, r10, r7
+ ld r7, 16(up)
+ addi up, up, 48
+ addze r11, r11
+ bdz L(endx)
+ addc r8, r8, r5
+ nop
+ ld r5, -24(up)
+ adde r9, r9, r6
+ ld r6, -16(up)
+ adde r10, r10, r7
+ ld r7, -8(up)
+ addze r11, r11
+ bdnz L(top)
+
+ addi up, up, 24
+L(endx):
+ addi up, up, -24
+
+L(end): addc r8, r8, r5
+ adde r9, r9, r6
+ adde r10, r10, r7
+ addze r11, r11
+
+ sldi r5, r0, 1
+ add r5, r5, r0 C r11 = n / 3 * 3
+ sub n, n, r5 C n = n mod 3
+L(lt3): cmpdi cr6, n, 1
+ blt cr6, L(2)
+
+ ld r5, 0(up)
+ addc r8, r8, r5
+ li r6, 0
+ beq cr6, L(1)
+
+ ld r6, 8(up)
+L(1): adde r9, r9, r6
+ addze r10, r10
+ addze r11, r11
+
+L(2): rldicl r0, r8, 0, 16 C r0 = r8 mod 2^48
+ srdi r3, r8, 48 C r3 = r8 div 2^48
+ rldic r4, r9, 16, 16 C r4 = (r9 mod 2^32) << 16
+ srdi r5, r9, 32 C r5 = r9 div 2^32
+ rldic r6, r10, 32, 16 C r6 = (r10 mod 2^16) << 32
+ srdi r7, r10, 16 C r7 = r10 div 2^16
+
+ add r0, r0, r3
+ add r4, r4, r5
+ add r6, r6, r7
+
+ add r0, r0, r4
+ add r6, r6, r11
+
+ add r3, r0, r6
+ blr
+EPILOGUE()
+
+C |__r10__|__r9___|__r8___|
+C |-----|-----|-----|-----|
diff --git a/gmp/mpn/powerpc64/mode64/mode1o.asm b/gmp/mpn/powerpc64/mode64/mode1o.asm
new file mode 100644
index 0000000000..726339a931
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/mode1o.asm
@@ -0,0 +1,117 @@
+dnl PowerPC-64 mpn_modexact_1_odd -- mpn by limb exact remainder.
+
+dnl Copyright 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 13-19
+C POWER4/PPC970 16
+C POWER5 16
+C POWER6 ?
+C POWER7 12
+
+C TODO
+C * Check if n=1 code is really an improvement. It probably isn't.
+C * Make more similar to dive_1.asm.
+
+C INPUT PARAMETERS
+define(`up', `r3')
+define(`n', `r4')
+define(`d', `r5')
+define(`cy', `r6')
+
+
+ASM_START()
+
+EXTERN(binvert_limb_table)
+
+PROLOGUE(mpn_modexact_1c_odd,toc)
+ addic. n, n, -1 C set carry as side effect
+ ld r8, 0(up)
+ bne cr0, L(2)
+ cmpld cr7, r6, r8
+ bge cr7, L(4)
+ subf r8, r6, r8
+ divdu r3, r8, d
+ mulld r3, r3, d
+ subf. r3, r3, r8
+ beqlr cr0
+ subf r3, r3, d
+ blr
+
+L(4): subf r3, r8, r6
+ divdu r8, r3, d
+ mulld r8, r8, d
+ subf r3, r8, r3
+ blr
+
+L(2): LEA( r7, binvert_limb_table)
+ rldicl r9, d, 63, 57
+ mtctr n
+ lbzx r0, r7, r9
+ mulld r7, r0, r0
+ sldi r0, r0, 1
+ mulld r7, d, r7
+ subf r0, r7, r0
+ mulld r9, r0, r0
+ sldi r0, r0, 1
+ mulld r9, d, r9
+ subf r0, r9, r0
+ mulld r7, r0, r0
+ sldi r0, r0, 1
+ mulld r7, d, r7
+ subf r9, r7, r0
+
+ ALIGN(16)
+L(loop):
+ subfe r0, r6, r8
+ ld r8, 8(up)
+ addi up, up, 8
+ mulld r0, r9, r0
+ mulhdu r6, r0, d
+ bdnz L(loop)
+
+ cmpld cr7, d, r8
+ blt cr7, L(10)
+
+ subfe r0, r0, r0
+ subf r6, r0, r6
+ cmpld cr7, r6, r8
+ subf r3, r8, r6
+ bgelr cr7
+ add r3, d, r3
+ blr
+
+L(10): subfe r0, r6, r8
+ mulld r0, r9, r0
+ mulhdu r3, r0, d
+ blr
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/powerpc64/mode64/mul_1.asm b/gmp/mpn/powerpc64/mode64/mul_1.asm
new file mode 100644
index 0000000000..27a8f8fb4d
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/mul_1.asm
@@ -0,0 +1,168 @@
+dnl PowerPC-64 mpn_mul_1 -- Multiply a limb vector with a limb and store
+dnl the result in a second limb vector.
+
+dnl Copyright 1999-2001, 2003-2006, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 6-18
+C POWER4/PPC970 7.25? not updated for last file revision
+C POWER5 7.25
+C POWER6 14
+C POWER7 2.9
+
+C TODO
+C * Try to reduce the number of needed live registers (at least r5 and r10
+C could be combined)
+C * Optimize feed-in code, for speed and size.
+C * Clean up r12/r7 usage in feed-in code.
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`vl', `r6')
+
+ASM_START()
+PROLOGUE(mpn_mul_1c)
+ std r27, -40(r1)
+ std r26, -48(r1)
+ mr r12, r7
+ b L(ent)
+EPILOGUE()
+PROLOGUE(mpn_mul_1)
+ std r27, -40(r1)
+ std r26, -48(r1)
+ li r12, 0 C cy_limb = 0
+L(ent): ld r26, 0(up)
+
+ rldicl. r0, n, 0,62 C r0 = n & 3, set cr0
+ cmpdi cr6, r0, 2
+ addic n, n, 3 C compute count...
+ srdi n, n, 2 C ...for ctr
+ mtctr n C copy count into ctr
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ beq cr6, L(b10)
+
+L(b11): mr r7, r12
+ mulld r0, r26, r6
+ mulhdu r12, r26, r6
+ addi up, up, 8
+ addc r0, r0, r7
+ std r0, 0(rp)
+ addi rp, rp, 8
+ b L(fic)
+
+L(b00): ld r27, 8(up)
+ addi up, up, 16
+ mulld r0, r26, r6
+ mulhdu r5, r26, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ addc r0, r0, r12
+ adde r7, r7, r5
+ addze r12, r8
+ std r0, 0(rp)
+ std r7, 8(rp)
+ addi rp, rp, 16
+ b L(fic)
+
+ nop C alignment
+L(b01): bdnz L(gt1)
+ mulld r0, r26, r6
+ mulhdu r8, r26, r6
+ addc r0, r0, r12
+ std r0, 0(rp)
+ b L(ret)
+L(gt1): ld r27, 8(up)
+ nop
+ mulld r0, r26, r6
+ mulhdu r5, r26, r6
+ ld r26, 16(up)
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ mulld r9, r26, r6
+ mulhdu r10, r26, r6
+ addc r0, r0, r12
+ adde r7, r7, r5
+ adde r9, r9, r8
+ addze r12, r10
+ std r0, 0(rp)
+ std r7, 8(rp)
+ std r9, 16(rp)
+ addi up, up, 24
+ addi rp, rp, 24
+ b L(fic)
+
+ nop
+L(fic): ld r26, 0(up)
+L(b10): ld r27, 8(up)
+ addi up, up, 16
+ bdz L(end)
+
+L(top): mulld r0, r26, r6
+ mulhdu r5, r26, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r26, 0(up)
+ ld r27, 8(up)
+ adde r0, r0, r12
+ adde r7, r7, r5
+ mulld r9, r26, r6
+ mulhdu r10, r26, r6
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6
+ ld r26, 16(up)
+ ld r27, 24(up)
+ std r0, 0(rp)
+ adde r9, r9, r8
+ std r7, 8(rp)
+ adde r11, r11, r10
+ std r9, 16(rp)
+ addi up, up, 32
+ std r11, 24(rp)
+
+ addi rp, rp, 32
+ bdnz L(top)
+
+L(end): mulld r0, r26, r6
+ mulhdu r5, r26, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ adde r0, r0, r12
+ adde r7, r7, r5
+ std r0, 0(rp)
+ std r7, 8(rp)
+L(ret): addze r3, r8
+ ld r27, -40(r1)
+ ld r26, -48(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/mul_basecase.asm b/gmp/mpn/powerpc64/mode64/mul_basecase.asm
new file mode 100644
index 0000000000..18731879e4
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/mul_basecase.asm
@@ -0,0 +1,708 @@
+dnl PowerPC-64 mpn_mul_basecase.
+
+dnl Copyright 1999-2001, 2003-2006, 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 6-18
+C POWER4/PPC970 8
+C POWER5 8
+C POWER6 24
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`un', `r5')
+define(`vp', `r6')
+define(`vn', `r7')
+
+define(`v0', `r25')
+define(`outer_rp', `r22')
+define(`outer_up', `r23')
+
+ASM_START()
+PROLOGUE(mpn_mul_basecase)
+
+C Special code for un <= 2, for efficiency of these important cases,
+C and since it simplifies the default code.
+ cmpdi cr0, un, 2
+ bgt cr0, L(un_gt2)
+ cmpdi cr6, vn, 1
+ ld r7, 0(vp)
+ ld r5, 0(up)
+ mulld r8, r5, r7 C weight 0
+ mulhdu r9, r5, r7 C weight 1
+ std r8, 0(rp)
+ beq cr0, L(2x)
+ std r9, 8(rp)
+ blr
+ ALIGN(16)
+L(2x): ld r0, 8(up)
+ mulld r8, r0, r7 C weight 1
+ mulhdu r10, r0, r7 C weight 2
+ addc r9, r9, r8
+ addze r10, r10
+ bne cr6, L(2x2)
+ std r9, 8(rp)
+ std r10, 16(rp)
+ blr
+ ALIGN(16)
+L(2x2): ld r6, 8(vp)
+ nop
+ mulld r8, r5, r6 C weight 1
+ mulhdu r11, r5, r6 C weight 2
+ addc r9, r9, r8
+ std r9, 8(rp)
+ adde r11, r11, r10
+ mulld r12, r0, r6 C weight 2
+ mulhdu r0, r0, r6 C weight 3
+ addze r0, r0
+ addc r11, r11, r12
+ addze r0, r0
+ std r11, 16(rp)
+ std r0, 24(rp)
+ blr
+
+L(un_gt2):
+ std r31, -8(r1)
+ std r30, -16(r1)
+ std r29, -24(r1)
+ std r28, -32(r1)
+ std r27, -40(r1)
+ std r26, -48(r1)
+ std r25, -56(r1)
+ std r24, -64(r1)
+ std r23, -72(r1)
+ std r22, -80(r1)
+
+ mr outer_rp, rp
+ mr outer_up, up
+
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ ld r26, 0(up)
+
+ rldicl. r0, un, 0,62 C r0 = n & 3, set cr0
+ cmpdi cr6, r0, 2
+ addi un, un, 1 C compute count...
+ srdi un, un, 2 C ...for ctr
+ mtctr un C copy inner loop count into ctr
+ beq cr0, L(b0)
+ blt cr6, L(b1)
+ beq cr6, L(b2)
+
+
+ ALIGN(16)
+L(b3): mulld r0, r26, v0
+ mulhdu r12, r26, v0
+ addic r0, r0, 0
+ std r0, 0(rp)
+ ld r26, 8(up)
+ ld r27, 16(up)
+ bdz L(end_m_3)
+
+ ALIGN(16)
+L(lo_m_3):
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ ld r26, 24(up)
+ nop
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ ld r27, 32(up)
+ nop
+ adde r0, r0, r12
+ adde r24, r24, r31
+ mulld r9, r26, v0
+ mulhdu r10, r26, v0
+ ld r26, 40(up)
+ nop
+ mulld r11, r27, v0
+ mulhdu r12, r27, v0
+ ld r27, 48(up)
+ std r0, 8(rp)
+ adde r9, r9, r8
+ std r24, 16(rp)
+ adde r11, r11, r10
+ std r9, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ bdnz L(lo_m_3)
+
+ ALIGN(16)
+L(end_m_3):
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+
+ adde r0, r0, r12
+ adde r24, r24, r31
+
+ std r0, 8(rp)
+ std r24, 16(rp)
+ addze r8, r8
+ std r8, 24(rp)
+ addic. vn, vn, -1
+ beq L(ret)
+
+ ALIGN(16)
+L(outer_lo_3):
+ mtctr un C copy inner loop count into ctr
+ addi rp, outer_rp, 8
+ mr up, outer_up
+ addi outer_rp, outer_rp, 8
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ ld r26, 0(up)
+ ld r28, 0(rp)
+ mulld r0, r26, v0
+ mulhdu r12, r26, v0
+ addc r0, r0, r28
+ std r0, 0(rp)
+ ld r26, 8(up)
+ ld r27, 16(up)
+ bdz L(end_3)
+
+ ALIGN(16) C registers dying
+L(lo_3):
+ mulld r0, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ ld r26, 24(up) C
+ ld r28, 8(rp) C
+ mulld r24, r27, v0 C
+ mulhdu r8, r27, v0 C 27
+ ld r27, 32(up) C
+ ld r29, 16(rp) C
+ adde r0, r0, r12 C 0 12
+ adde r24, r24, r10 C 24 10
+ mulld r9, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ ld r26, 40(up) C
+ ld r30, 24(rp) C
+ mulld r11, r27, v0 C
+ mulhdu r12, r27, v0 C 27
+ ld r27, 48(up) C
+ ld r31, 32(rp) C
+ adde r9, r9, r8 C 8 9
+ adde r11, r11, r10 C 10 11
+ addze r12, r12 C 12
+ addc r0, r0, r28 C 0 28
+ std r0, 8(rp) C 0
+ adde r24, r24, r29 C 7 29
+ std r24, 16(rp) C 7
+ adde r9, r9, r30 C 9 30
+ std r9, 24(rp) C 9
+ adde r11, r11, r31 C 11 31
+ std r11, 32(rp) C 11
+ addi up, up, 32 C
+ addi rp, rp, 32 C
+ bdnz L(lo_3) C
+
+ ALIGN(16)
+L(end_3):
+ mulld r0, r26, v0
+ mulhdu r10, r26, v0
+ ld r28, 8(rp)
+ nop
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ ld r29, 16(rp)
+ nop
+ adde r0, r0, r12
+ adde r24, r24, r10
+ addze r8, r8
+ addc r0, r0, r28
+ std r0, 8(rp)
+ adde r24, r24, r29
+ std r24, 16(rp)
+ addze r8, r8
+ std r8, 24(rp)
+
+ addic. vn, vn, -1
+ bne L(outer_lo_3)
+ b L(ret)
+
+
+ ALIGN(16)
+L(b0): ld r27, 8(up)
+ addi up, up, 8
+ mulld r0, r26, v0
+ mulhdu r10, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ addc r24, r24, r10
+ addze r12, r8
+ std r0, 0(rp)
+ std r24, 8(rp)
+ addi rp, rp, 8
+ ld r26, 8(up)
+ ld r27, 16(up)
+ bdz L(end_m_0)
+
+ ALIGN(16)
+L(lo_m_0):
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ ld r26, 24(up)
+ nop
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ ld r27, 32(up)
+ nop
+ adde r0, r0, r12
+ adde r24, r24, r31
+ mulld r9, r26, v0
+ mulhdu r10, r26, v0
+ ld r26, 40(up)
+ nop
+ mulld r11, r27, v0
+ mulhdu r12, r27, v0
+ ld r27, 48(up)
+ std r0, 8(rp)
+ adde r9, r9, r8
+ std r24, 16(rp)
+ adde r11, r11, r10
+ std r9, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ bdnz L(lo_m_0)
+
+ ALIGN(16)
+L(end_m_0):
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+
+ adde r0, r0, r12
+ adde r24, r24, r31
+
+ std r0, 8(rp)
+ addze r8, r8
+ std r24, 16(rp)
+ addic. vn, vn, -1
+ std r8, 24(rp)
+ nop
+ beq L(ret)
+
+ ALIGN(16)
+L(outer_lo_0):
+ mtctr un C copy inner loop count into ctr
+ addi rp, outer_rp, 16
+ addi up, outer_up, 8
+ addi outer_rp, outer_rp, 8
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ ld r26, -8(up)
+ ld r27, 0(up)
+ ld r28, -8(rp)
+ ld r29, 0(rp)
+ nop
+ nop
+ mulld r0, r26, v0
+ mulhdu r10, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ addc r24, r24, r10
+ addze r12, r8
+ addc r0, r0, r28
+ std r0, -8(rp)
+ adde r24, r24, r29
+ std r24, 0(rp)
+ ld r26, 8(up)
+ ld r27, 16(up)
+ bdz L(end_0)
+
+ ALIGN(16) C registers dying
+L(lo_0):
+ mulld r0, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ ld r26, 24(up) C
+ ld r28, 8(rp) C
+ mulld r24, r27, v0 C
+ mulhdu r8, r27, v0 C 27
+ ld r27, 32(up) C
+ ld r29, 16(rp) C
+ adde r0, r0, r12 C 0 12
+ adde r24, r24, r10 C 24 10
+ mulld r9, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ ld r26, 40(up) C
+ ld r30, 24(rp) C
+ mulld r11, r27, v0 C
+ mulhdu r12, r27, v0 C 27
+ ld r27, 48(up) C
+ ld r31, 32(rp) C
+ adde r9, r9, r8 C 8 9
+ adde r11, r11, r10 C 10 11
+ addze r12, r12 C 12
+ addc r0, r0, r28 C 0 28
+ std r0, 8(rp) C 0
+ adde r24, r24, r29 C 7 29
+ std r24, 16(rp) C 7
+ adde r9, r9, r30 C 9 30
+ std r9, 24(rp) C 9
+ adde r11, r11, r31 C 11 31
+ std r11, 32(rp) C 11
+ addi up, up, 32 C
+ addi rp, rp, 32 C
+ bdnz L(lo_0) C
+
+ ALIGN(16)
+L(end_0):
+ mulld r0, r26, v0
+ mulhdu r10, r26, v0
+ ld r28, 8(rp)
+ nop
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ ld r29, 16(rp)
+ nop
+ adde r0, r0, r12
+ adde r24, r24, r10
+ addze r8, r8
+ addic. vn, vn, -1
+ addc r0, r0, r28
+ std r0, 8(rp)
+ adde r24, r24, r29
+ std r24, 16(rp)
+ addze r8, r8
+ std r8, 24(rp)
+ bne L(outer_lo_0)
+ b L(ret)
+
+
+ ALIGN(16)
+L(b1): ld r27, 8(up)
+ nop
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ ld r26, 16(up)
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ mulld r9, r26, v0
+ mulhdu r10, r26, v0
+ addc r24, r24, r31
+ adde r9, r9, r8
+ addze r12, r10
+ std r0, 0(rp)
+ std r24, 8(rp)
+ std r9, 16(rp)
+ addi up, up, 16
+ addi rp, rp, 16
+ ld r26, 8(up)
+ ld r27, 16(up)
+ bdz L(end_m_1)
+
+ ALIGN(16)
+L(lo_m_1):
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ ld r26, 24(up)
+ nop
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ ld r27, 32(up)
+ nop
+ adde r0, r0, r12
+ adde r24, r24, r31
+ mulld r9, r26, v0
+ mulhdu r10, r26, v0
+ ld r26, 40(up)
+ nop
+ mulld r11, r27, v0
+ mulhdu r12, r27, v0
+ ld r27, 48(up)
+ std r0, 8(rp)
+ adde r9, r9, r8
+ std r24, 16(rp)
+ adde r11, r11, r10
+ std r9, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ bdnz L(lo_m_1)
+
+ ALIGN(16)
+L(end_m_1):
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+
+ adde r0, r0, r12
+ adde r24, r24, r31
+
+ std r0, 8(rp)
+ addze r8, r8
+ std r24, 16(rp)
+ addic. vn, vn, -1
+ std r8, 24(rp)
+ nop
+ beq L(ret)
+
+ ALIGN(16)
+L(outer_lo_1):
+ mtctr un C copy inner loop count into ctr
+ addi rp, outer_rp, 24
+ addi up, outer_up, 16
+ addi outer_rp, outer_rp, 8
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ ld r26, -16(up)
+ ld r27, -8(up)
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ ld r26, 0(up)
+ ld r28, -16(rp)
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ ld r29, -8(rp)
+ ld r30, 0(rp)
+ mulld r9, r26, v0
+ mulhdu r10, r26, v0
+ addc r24, r24, r31
+ adde r9, r9, r8
+ addze r12, r10
+ addc r0, r0, r28
+ std r0, -16(rp)
+ adde r24, r24, r29
+ std r24, -8(rp)
+ adde r9, r9, r30
+ std r9, 0(rp)
+ ld r26, 8(up)
+ ld r27, 16(up)
+ bdz L(end_1)
+
+ ALIGN(16) C registers dying
+L(lo_1):
+ mulld r0, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ ld r26, 24(up) C
+ ld r28, 8(rp) C
+ mulld r24, r27, v0 C
+ mulhdu r8, r27, v0 C 27
+ ld r27, 32(up) C
+ ld r29, 16(rp) C
+ adde r0, r0, r12 C 0 12
+ adde r24, r24, r10 C 24 10
+ mulld r9, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ ld r26, 40(up) C
+ ld r30, 24(rp) C
+ mulld r11, r27, v0 C
+ mulhdu r12, r27, v0 C 27
+ ld r27, 48(up) C
+ ld r31, 32(rp) C
+ adde r9, r9, r8 C 8 9
+ adde r11, r11, r10 C 10 11
+ addze r12, r12 C 12
+ addc r0, r0, r28 C 0 28
+ std r0, 8(rp) C 0
+ adde r24, r24, r29 C 7 29
+ std r24, 16(rp) C 7
+ adde r9, r9, r30 C 9 30
+ std r9, 24(rp) C 9
+ adde r11, r11, r31 C 11 31
+ std r11, 32(rp) C 11
+ addi up, up, 32 C
+ addi rp, rp, 32 C
+ bdnz L(lo_1) C
+
+ ALIGN(16)
+L(end_1):
+ mulld r0, r26, v0
+ mulhdu r10, r26, v0
+ ld r28, 8(rp)
+ nop
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ ld r29, 16(rp)
+ nop
+ adde r0, r0, r12
+ adde r24, r24, r10
+ addze r8, r8
+ addic. vn, vn, -1
+ addc r0, r0, r28
+ std r0, 8(rp)
+ adde r24, r24, r29
+ std r24, 16(rp)
+ addze r8, r8
+ std r8, 24(rp)
+ bne L(outer_lo_1)
+ b L(ret)
+
+
+ ALIGN(16)
+L(b2): ld r27, 8(up)
+ addi up, up, -8
+ addi rp, rp, -8
+ li r12, 0
+ addic r12, r12, 0
+
+ ALIGN(16)
+L(lo_m_2):
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ ld r26, 24(up)
+ nop
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ ld r27, 32(up)
+ nop
+ adde r0, r0, r12
+ adde r24, r24, r31
+ mulld r9, r26, v0
+ mulhdu r10, r26, v0
+ ld r26, 40(up)
+ nop
+ mulld r11, r27, v0
+ mulhdu r12, r27, v0
+ ld r27, 48(up)
+ std r0, 8(rp)
+ adde r9, r9, r8
+ std r24, 16(rp)
+ adde r11, r11, r10
+ std r9, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+
+ addi rp, rp, 32
+ bdnz L(lo_m_2)
+
+ ALIGN(16)
+L(end_m_2):
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+
+ adde r0, r0, r12
+ adde r24, r24, r31
+
+ std r0, 8(rp)
+ addze r8, r8
+ std r24, 16(rp)
+ addic. vn, vn, -1
+ std r8, 24(rp)
+ nop
+ beq L(ret)
+
+ ALIGN(16)
+L(outer_lo_2):
+ mtctr un C copy inner loop count into ctr
+ addi rp, outer_rp, 0
+ addi up, outer_up, -8
+ addi outer_rp, outer_rp, 8
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ ld r26, 8(up)
+ ld r27, 16(up)
+ li r12, 0
+ addic r12, r12, 0
+
+ ALIGN(16) C registers dying
+L(lo_2):
+ mulld r0, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ ld r26, 24(up) C
+ ld r28, 8(rp) C
+ mulld r24, r27, v0 C
+ mulhdu r8, r27, v0 C 27
+ ld r27, 32(up) C
+ ld r29, 16(rp) C
+ adde r0, r0, r12 C 0 12
+ adde r24, r24, r10 C 24 10
+ mulld r9, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ ld r26, 40(up) C
+ ld r30, 24(rp) C
+ mulld r11, r27, v0 C
+ mulhdu r12, r27, v0 C 27
+ ld r27, 48(up) C
+ ld r31, 32(rp) C
+ adde r9, r9, r8 C 8 9
+ adde r11, r11, r10 C 10 11
+ addze r12, r12 C 12
+ addc r0, r0, r28 C 0 28
+ std r0, 8(rp) C 0
+ adde r24, r24, r29 C 7 29
+ std r24, 16(rp) C 7
+ adde r9, r9, r30 C 9 30
+ std r9, 24(rp) C 9
+ adde r11, r11, r31 C 11 31
+ std r11, 32(rp) C 11
+ addi up, up, 32 C
+ addi rp, rp, 32 C
+ bdnz L(lo_2) C
+
+ ALIGN(16)
+L(end_2):
+ mulld r0, r26, v0
+ mulhdu r10, r26, v0
+ ld r28, 8(rp)
+ nop
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ ld r29, 16(rp)
+ nop
+ adde r0, r0, r12
+ adde r24, r24, r10
+ addze r8, r8
+ addic. vn, vn, -1
+ addc r0, r0, r28
+ std r0, 8(rp)
+ adde r24, r24, r29
+ std r24, 16(rp)
+ addze r8, r8
+ std r8, 24(rp)
+ bne L(outer_lo_2)
+ b L(ret)
+
+
+L(ret): ld r31, -8(r1)
+ ld r30, -16(r1)
+ ld r29, -24(r1)
+ ld r28, -32(r1)
+ ld r27, -40(r1)
+ ld r26, -48(r1)
+ ld r25, -56(r1)
+ ld r24, -64(r1)
+ ld r23, -72(r1)
+ ld r22, -80(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/p3/gmp-mparam.h b/gmp/mpn/powerpc64/mode64/p3/gmp-mparam.h
new file mode 100644
index 0000000000..61a437b6e6
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p3/gmp-mparam.h
@@ -0,0 +1,179 @@
+/* POWER3/PowerPC630 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2008-2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 18
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 17
+#define USE_PREINV_DIVREM_1 0
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 10
+#define MUL_TOOM33_THRESHOLD 33
+#define MUL_TOOM44_THRESHOLD 46
+#define MUL_TOOM6H_THRESHOLD 77
+#define MUL_TOOM8H_THRESHOLD 139
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 49
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 47
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 49
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 49
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 34
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 14
+#define SQR_TOOM3_THRESHOLD 45
+#define SQR_TOOM4_THRESHOLD 64
+#define SQR_TOOM6_THRESHOLD 85
+#define SQR_TOOM8_THRESHOLD 139
+
+#define MULMID_TOOM42_THRESHOLD 22
+
+#define MULMOD_BNM1_THRESHOLD 8
+#define SQRMOD_BNM1_THRESHOLD 10
+
+#define MUL_FFT_MODF_THRESHOLD 220 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 220, 5}, { 9, 6}, { 5, 5}, { 11, 6}, \
+ { 13, 7}, { 7, 6}, { 15, 7}, { 13, 8}, \
+ { 7, 7}, { 15, 8}, { 13, 9}, { 7, 8}, \
+ { 19, 9}, { 11, 8}, { 23,10}, { 7, 9}, \
+ { 15, 8}, { 33, 9}, { 23,10}, { 15, 9}, \
+ { 35, 8}, { 71,10}, { 23, 9}, { 47,11}, \
+ { 15,10}, { 31, 9}, { 71,10}, { 39, 9}, \
+ { 79,10}, { 55,11}, { 31,10}, { 63, 9}, \
+ { 127,10}, { 71, 9}, { 143, 8}, { 287,10}, \
+ { 79,11}, { 47,10}, { 95, 9}, { 191,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511,10}, { 143, 9}, { 287,11}, { 79,10}, \
+ { 159, 9}, { 319, 8}, { 639,10}, { 175, 9}, \
+ { 351,11}, { 95,10}, { 191, 9}, { 383,11}, \
+ { 111,10}, { 223,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,11}, { 143,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 319, 9}, { 639,11}, \
+ { 175,10}, { 351,12}, { 95,11}, { 191,10}, \
+ { 383, 9}, { 767,11}, { 223,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 511,11}, { 287,10}, \
+ { 575, 9}, { 1151,12}, { 159,11}, { 319,10}, \
+ { 639,11}, { 351,12}, { 191,11}, { 383,10}, \
+ { 767,12}, { 223,11}, { 447,10}, { 895,13}, \
+ { 127,12}, { 255,11}, { 511,12}, { 287,11}, \
+ { 575,10}, { 1151,12}, { 319,11}, { 639,12}, \
+ { 351,11}, { 703,13}, { 191,12}, { 383,11}, \
+ { 767,12}, { 415,11}, { 831,10}, { 1663,12}, \
+ { 447,11}, { 895,14}, { 16384,15}, { 32768,16}, \
+ { 65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+ {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 120
+#define MUL_FFT_THRESHOLD 2688
+
+#define SQR_FFT_MODF_THRESHOLD 188 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 188, 5}, { 9, 6}, { 5, 5}, { 11, 6}, \
+ { 13, 7}, { 13, 8}, { 7, 7}, { 16, 8}, \
+ { 9, 7}, { 19, 8}, { 13, 9}, { 7, 8}, \
+ { 19, 9}, { 11, 8}, { 23,10}, { 7, 9}, \
+ { 15, 8}, { 31, 9}, { 19, 8}, { 39, 9}, \
+ { 23,10}, { 15, 9}, { 39,10}, { 23,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79, 8}, { 159,10}, { 47, 9}, { 95, 8}, \
+ { 191,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255,10}, { 71, 9}, { 143, 8}, { 287,10}, \
+ { 79, 9}, { 159,11}, { 47,10}, { 95, 9}, \
+ { 191,12}, { 31,11}, { 63,10}, { 127, 9}, \
+ { 255, 8}, { 511,10}, { 143, 9}, { 287,11}, \
+ { 79,10}, { 159, 9}, { 319, 8}, { 639,10}, \
+ { 175,11}, { 95,10}, { 191, 9}, { 383,11}, \
+ { 111,10}, { 223,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,11}, { 143,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 319, 9}, { 639,11}, \
+ { 175,12}, { 95,11}, { 191,10}, { 383, 9}, \
+ { 767,11}, { 223,13}, { 63,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 287,10}, { 575,12}, \
+ { 159,11}, { 319,10}, { 639,11}, { 351,12}, \
+ { 191,11}, { 383,10}, { 767,12}, { 223,11}, \
+ { 447,10}, { 895,13}, { 127,12}, { 255,11}, \
+ { 511,12}, { 287,11}, { 575,10}, { 1151,12}, \
+ { 319,11}, { 639,12}, { 351,13}, { 191,12}, \
+ { 383,11}, { 767,12}, { 447,11}, { 895,14}, \
+ { 16384,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 118
+#define SQR_FFT_THRESHOLD 1728
+
+#define MULLO_BASECASE_THRESHOLD 2
+#define MULLO_DC_THRESHOLD 27
+#define MULLO_MUL_N_THRESHOLD 2511
+
+#define DC_DIV_QR_THRESHOLD 23
+#define DC_DIVAPPR_Q_THRESHOLD 87
+#define DC_BDIV_QR_THRESHOLD 27
+#define DC_BDIV_Q_THRESHOLD 60
+
+#define INV_MULMOD_BNM1_THRESHOLD 27
+#define INV_NEWTON_THRESHOLD 91
+#define INV_APPR_THRESHOLD 91
+
+#define BINV_NEWTON_THRESHOLD 115
+#define REDC_1_TO_REDC_N_THRESHOLD 31
+
+#define MU_DIV_QR_THRESHOLD 551
+#define MU_DIVAPPR_Q_THRESHOLD 551
+#define MUPI_DIV_QR_THRESHOLD 42
+#define MU_BDIV_QR_THRESHOLD 483
+#define MU_BDIV_Q_THRESHOLD 492
+
+#define POWM_SEC_TABLE 2,23,140,556,713,746
+
+#define MATRIX22_STRASSEN_THRESHOLD 8
+#define HGCD_THRESHOLD 56
+#define HGCD_APPR_THRESHOLD 51
+#define HGCD_REDUCE_THRESHOLD 688
+#define GCD_DC_THRESHOLD 333
+#define GCDEXT_DC_THRESHOLD 126
+#define JACOBI_BASE_METHOD 1
+
+#define GET_STR_DC_THRESHOLD 17
+#define GET_STR_PRECOMPUTE_THRESHOLD 28
+#define SET_STR_DC_THRESHOLD 375
+#define SET_STR_PRECOMPUTE_THRESHOLD 812
+
+#define FAC_DSC_THRESHOLD 351
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/powerpc64/mode64/p4/gmp-mparam.h b/gmp/mpn/powerpc64/mode64/p4/gmp-mparam.h
new file mode 100644
index 0000000000..d909b292bb
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p4/gmp-mparam.h
@@ -0,0 +1,208 @@
+/* POWER4/PowerPC970 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2008-2010, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 1800 MHz PPC970 */
+/* FFT tuning limit = 10000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.0 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 10
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 22
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 16
+#define USE_PREINV_DIVREM_1 0
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 34
+
+#define MUL_TOOM22_THRESHOLD 14
+#define MUL_TOOM33_THRESHOLD 53
+#define MUL_TOOM44_THRESHOLD 136
+#define MUL_TOOM6H_THRESHOLD 197
+#define MUL_TOOM8H_THRESHOLD 296
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 89
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 91
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 89
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 96
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 79
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 24
+#define SQR_TOOM3_THRESHOLD 85
+#define SQR_TOOM4_THRESHOLD 142
+#define SQR_TOOM6_THRESHOLD 270
+#define SQR_TOOM8_THRESHOLD 430
+
+#define MULMID_TOOM42_THRESHOLD 32
+
+#define MULMOD_BNM1_THRESHOLD 11
+#define SQRMOD_BNM1_THRESHOLD 15
+
+#define MUL_FFT_MODF_THRESHOLD 380 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 380, 5}, { 13, 6}, { 7, 5}, { 17, 6}, \
+ { 9, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 13, 5}, { 28, 6}, { 21, 7}, { 11, 6}, \
+ { 23, 7}, { 12, 6}, { 25, 7}, { 21, 8}, \
+ { 11, 7}, { 25, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 21, 9}, { 11, 8}, \
+ { 27, 9}, { 15, 8}, { 35, 9}, { 19, 8}, \
+ { 39, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 55,11}, \
+ { 15,10}, { 31, 9}, { 71,10}, { 39, 9}, \
+ { 83,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 63, 9}, { 127,10}, { 87,11}, \
+ { 47,10}, { 95, 9}, { 191,10}, { 103,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511,10}, { 135, 9}, { 271,11}, { 79,10}, \
+ { 159, 9}, { 319,10}, { 167, 9}, { 335,11}, \
+ { 95,10}, { 191, 9}, { 383, 8}, { 767,10}, \
+ { 207, 9}, { 415,11}, { 111,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
+ { 543,11}, { 143,10}, { 287, 9}, { 575,10}, \
+ { 303, 9}, { 607,10}, { 319, 9}, { 639,10}, \
+ { 335, 9}, { 671,10}, { 351,12}, { 95,11}, \
+ { 191,10}, { 383, 9}, { 767,11}, { 207,10}, \
+ { 415, 9}, { 831,13}, { 63,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 271,10}, { 543,11}, \
+ { 287,10}, { 575,11}, { 303,10}, { 607,11}, \
+ { 319,10}, { 639,11}, { 335,10}, { 671,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 415,10}, { 831,12}, { 223,10}, \
+ { 895,11}, { 479,13}, { 127,12}, { 255,11}, \
+ { 543,12}, { 287,11}, { 607,12}, { 319,11}, \
+ { 671,12}, { 351,11}, { 703,13}, { 191,12}, \
+ { 383,11}, { 767,12}, { 415,11}, { 895,12}, \
+ { 479,14}, { 127,13}, { 255,12}, { 607,13}, \
+ { 319,12}, { 703,13}, { 383,12}, { 895,14}, \
+ { 255,13}, { 511,12}, { 1023,13}, { 575,12}, \
+ { 1151,13}, { 703,14}, { 383,13}, { 895,15}, \
+ { 255,14}, { 511,13}, { 1023,12}, { 2047,13}, \
+ { 1087,12}, { 2175,13}, { 1151,14}, { 16384,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 165
+#define MUL_FFT_THRESHOLD 9088
+
+#define SQR_FFT_MODF_THRESHOLD 308 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 308, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 13, 5}, { 28, 6}, { 21, 7}, { 11, 6}, \
+ { 23, 7}, { 14, 6}, { 29, 7}, { 21, 8}, \
+ { 11, 7}, { 25, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 21, 9}, { 11, 8}, \
+ { 27, 9}, { 15, 8}, { 35, 9}, { 19, 8}, \
+ { 39, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 51,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 83,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 79,11}, { 47,10}, { 95, 9}, \
+ { 191, 8}, { 383,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511,10}, { 135, 9}, \
+ { 271, 8}, { 543,11}, { 79,10}, { 159, 9}, \
+ { 319, 8}, { 639,10}, { 175, 9}, { 351,11}, \
+ { 95,10}, { 191, 9}, { 383, 8}, { 767,10}, \
+ { 207, 9}, { 415,11}, { 111,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
+ { 543,10}, { 287, 9}, { 575,10}, { 303,11}, \
+ { 159,10}, { 319, 9}, { 639,11}, { 175,10}, \
+ { 351,12}, { 95,11}, { 191,10}, { 383, 9}, \
+ { 767,11}, { 207,10}, { 415, 9}, { 831,11}, \
+ { 223,13}, { 63,12}, { 127,11}, { 255,10}, \
+ { 511,11}, { 271,10}, { 543,11}, { 287,10}, \
+ { 575,11}, { 303,10}, { 607,12}, { 159,11}, \
+ { 319,10}, { 639,11}, { 351,10}, { 703,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,10}, \
+ { 831,12}, { 223,10}, { 895,11}, { 479,13}, \
+ { 127,12}, { 255,11}, { 543,12}, { 287,11}, \
+ { 607,12}, { 319,11}, { 639,12}, { 351,11}, \
+ { 703,13}, { 191,12}, { 383,11}, { 767,12}, \
+ { 415,11}, { 895,12}, { 479,14}, { 127,13}, \
+ { 255,12}, { 607,13}, { 319,12}, { 703,13}, \
+ { 383,12}, { 927,14}, { 255,13}, { 511,12}, \
+ { 1023,13}, { 575,12}, { 1151,13}, { 639,12}, \
+ { 1279,13}, { 703,14}, { 383,13}, { 895,12}, \
+ { 1791,15}, { 255,14}, { 511,13}, { 1023,12}, \
+ { 2047,13}, { 1087,12}, { 2175,13}, { 1151,14}, \
+ { 16384,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 162
+#define SQR_FFT_THRESHOLD 6272
+
+#define MULLO_BASECASE_THRESHOLD 5
+#define MULLO_DC_THRESHOLD 44
+#define MULLO_MUL_N_THRESHOLD 18087
+
+#define DC_DIV_QR_THRESHOLD 42
+#define DC_DIVAPPR_Q_THRESHOLD 167
+#define DC_BDIV_QR_THRESHOLD 46
+#define DC_BDIV_Q_THRESHOLD 110
+
+#define INV_MULMOD_BNM1_THRESHOLD 30
+#define INV_NEWTON_THRESHOLD 181
+#define INV_APPR_THRESHOLD 173
+
+#define BINV_NEWTON_THRESHOLD 214
+#define REDC_1_TO_REDC_N_THRESHOLD 56
+
+#define MU_DIV_QR_THRESHOLD 998
+#define MU_DIVAPPR_Q_THRESHOLD 1017
+#define MUPI_DIV_QR_THRESHOLD 92
+#define MU_BDIV_QR_THRESHOLD 889
+#define MU_BDIV_Q_THRESHOLD 1017
+
+#define POWM_SEC_TABLE 2,22,87,579,1925
+
+#define MATRIX22_STRASSEN_THRESHOLD 15
+#define HGCD_THRESHOLD 109
+#define HGCD_APPR_THRESHOLD 115
+#define HGCD_REDUCE_THRESHOLD 4633
+#define GCD_DC_THRESHOLD 318
+#define GCDEXT_DC_THRESHOLD 242
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 11
+#define GET_STR_PRECOMPUTE_THRESHOLD 23
+#define SET_STR_DC_THRESHOLD 802
+#define SET_STR_PRECOMPUTE_THRESHOLD 1712
+
+#define FAC_DSC_THRESHOLD 507
+#define FAC_ODD_THRESHOLD 25
diff --git a/gmp/mpn/powerpc64/mode64/p5/gmp-mparam.h b/gmp/mpn/powerpc64/mode64/p5/gmp-mparam.h
new file mode 100644
index 0000000000..15b009c357
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p5/gmp-mparam.h
@@ -0,0 +1,219 @@
+/* POWER5 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2003, 2009, 2010 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* POWER5 (friggms.hpc.ntnu.no) */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 15
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 11
+#define USE_PREINV_DIVREM_1 0
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 40
+
+#define MUL_TOOM22_THRESHOLD 21
+#define MUL_TOOM33_THRESHOLD 24
+#define MUL_TOOM44_THRESHOLD 70
+#define MUL_TOOM6H_THRESHOLD 262
+#define MUL_TOOM8H_THRESHOLD 393
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 49
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 126
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 85
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 94
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 70
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 24
+#define SQR_TOOM3_THRESHOLD 81
+#define SQR_TOOM4_THRESHOLD 142
+#define SQR_TOOM6_THRESHOLD 189
+#define SQR_TOOM8_THRESHOLD 284
+
+#define MULMID_TOOM42_THRESHOLD 36
+
+#define MULMOD_BNM1_THRESHOLD 12
+#define SQRMOD_BNM1_THRESHOLD 15
+
+#define MUL_FFT_MODF_THRESHOLD 304 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 348, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 10, 5}, { 21, 6}, { 21, 7}, { 11, 6}, \
+ { 23, 7}, { 12, 6}, { 25, 7}, { 21, 8}, \
+ { 11, 7}, { 25, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 21, 9}, { 11, 8}, \
+ { 27, 9}, { 15, 8}, { 33, 9}, { 19, 8}, \
+ { 39, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 51,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 79,11}, { 47,10}, { 95,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 135,11}, { 79,10}, { 159, 9}, { 319,11}, \
+ { 95,10}, { 191, 9}, { 383,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271,11}, \
+ { 143,10}, { 287, 9}, { 575,10}, { 319,12}, \
+ { 95,11}, { 191,10}, { 383,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 511,11}, { 271,10}, \
+ { 543,11}, { 287,10}, { 575, 9}, { 1151,11}, \
+ { 319,10}, { 639,11}, { 351,10}, { 703,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,12}, \
+ { 223,11}, { 447,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087,12}, \
+ { 287,11}, { 575,10}, { 1151,12}, { 319,11}, \
+ { 639,12}, { 351,11}, { 703,13}, { 191,12}, \
+ { 383,11}, { 767,12}, { 415,11}, { 831,12}, \
+ { 447,11}, { 895,14}, { 127,13}, { 255,12}, \
+ { 511,11}, { 1023,12}, { 543,11}, { 1087,10}, \
+ { 2175,12}, { 575,11}, { 1151,12}, { 607,13}, \
+ { 319,12}, { 639,11}, { 1279,12}, { 671,11}, \
+ { 1343,12}, { 703,11}, { 1407,13}, { 383,12}, \
+ { 767,11}, { 1535,12}, { 831,13}, { 447,12}, \
+ { 959,11}, { 1919,14}, { 255,13}, { 511,12}, \
+ { 1087,11}, { 2175,13}, { 575,12}, { 1215,11}, \
+ { 2431,10}, { 4863,13}, { 639,12}, { 1343,13}, \
+ { 703,12}, { 1407,14}, { 383,13}, { 767,12}, \
+ { 1535,13}, { 831,12}, { 1663,13}, { 959,12}, \
+ { 1919,11}, { 3839,15}, { 255,14}, { 511,13}, \
+ { 1087,12}, { 2175,13}, { 1215,12}, { 2431,11}, \
+ { 4863,14}, { 639,13}, { 1343,12}, { 2687,13}, \
+ { 1407,12}, { 2815,13}, { 1471,12}, { 2943,14}, \
+ { 767,13}, { 1599,12}, { 3199,13}, { 1663,14}, \
+ { 895,13}, { 1919,12}, { 3839,15}, { 511,14}, \
+ { 1023,13}, { 2175,14}, { 1151,13}, { 2431,12}, \
+ { 4863,14}, { 1279,13}, { 2687,14}, { 1407,13}, \
+ { 2943,15}, { 767,14}, { 1535,13}, { 3199,14}, \
+ { 1663,13}, { 3327,14}, { 1919,13}, { 3839,16}, \
+ { 511,15}, { 1023,14}, { 2431,13}, { 4863,15}, \
+ { 1279,14}, { 2943,12}, { 11775,15}, { 1535,14}, \
+ { 3327,15}, { 1791,14}, { 16384,15}, { 32768,16}, \
+ { 65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+ {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 208
+#define MUL_FFT_THRESHOLD 4224
+
+#define SQR_FFT_MODF_THRESHOLD 284 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 272, 5}, { 15, 6}, { 8, 5}, { 17, 6}, \
+ { 19, 7}, { 17, 8}, { 9, 7}, { 21, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 21, 9}, { 11, 8}, \
+ { 27, 9}, { 15, 8}, { 33, 9}, { 19, 8}, \
+ { 39, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 47,11}, \
+ { 15,10}, { 31, 9}, { 63,10}, { 47,11}, \
+ { 31,10}, { 71, 9}, { 143,10}, { 79,11}, \
+ { 47,10}, { 95,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511, 9}, { 271,10}, \
+ { 143,11}, { 79,10}, { 159, 9}, { 319,10}, \
+ { 175, 9}, { 351,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207, 9}, { 415,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271,11}, \
+ { 143,10}, { 287, 9}, { 575,11}, { 159,10}, \
+ { 319,11}, { 175,10}, { 351,12}, { 95,11}, \
+ { 191,10}, { 383,11}, { 207,10}, { 415,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 271,10}, { 543,11}, { 287,10}, { 575,12}, \
+ { 159,11}, { 319,10}, { 639,11}, { 351,10}, \
+ { 703,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,12}, { 223,11}, { 447,10}, { 895,11}, \
+ { 479,10}, { 959,12}, { 255,11}, { 511,10}, \
+ { 1023,11}, { 543,12}, { 287,11}, { 575,12}, \
+ { 319,11}, { 639,12}, { 351,11}, { 703,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,12}, { 447,11}, { 895,12}, { 479,11}, \
+ { 959,13}, { 255,12}, { 511,11}, { 1023,12}, \
+ { 543,11}, { 1087,12}, { 575,13}, { 319,12}, \
+ { 639,11}, { 1279,12}, { 703,11}, { 1407,13}, \
+ { 383,12}, { 831,13}, { 447,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1087,13}, { 575,12}, \
+ { 1215,13}, { 639,12}, { 1279,13}, { 703,12}, \
+ { 1407,14}, { 383,13}, { 831,12}, { 1663,13}, \
+ { 959,12}, { 1919,15}, { 255,14}, { 511,13}, \
+ { 1023,12}, { 2047,13}, { 1087,12}, { 2175,13}, \
+ { 1215,14}, { 639,13}, { 1407,12}, { 2815,14}, \
+ { 767,13}, { 1663,14}, { 895,13}, { 1919,15}, \
+ { 511,14}, { 1023,13}, { 2175,14}, { 1151,13}, \
+ { 2431,12}, { 4863,14}, { 1407,13}, { 2815,15}, \
+ { 767,14}, { 1663,13}, { 3327,14}, { 1919,13}, \
+ { 3839,16}, { 511,15}, { 1023,14}, { 2431,13}, \
+ { 4863,15}, { 1279,14}, { 2943,13}, { 5887,12}, \
+ { 11775,15}, { 1535,14}, { 3327,15}, { 1791,14}, \
+ { 16384,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 190
+#define SQR_FFT_THRESHOLD 3264
+
+#define MULLO_BASECASE_THRESHOLD 6
+#define MULLO_DC_THRESHOLD 60
+#define MULLO_MUL_N_THRESHOLD 7463
+
+#define DC_DIV_QR_THRESHOLD 58
+#define DC_DIVAPPR_Q_THRESHOLD 232
+#define DC_BDIV_QR_THRESHOLD 78
+#define DC_BDIV_Q_THRESHOLD 238
+
+#define INV_MULMOD_BNM1_THRESHOLD 92
+#define INV_NEWTON_THRESHOLD 155
+#define INV_APPR_THRESHOLD 157
+
+#define BINV_NEWTON_THRESHOLD 155
+#define REDC_1_TO_REDC_N_THRESHOLD 61
+
+#define MU_DIV_QR_THRESHOLD 998
+#define MU_DIVAPPR_Q_THRESHOLD 979
+#define MUPI_DIV_QR_THRESHOLD 79
+#define MU_BDIV_QR_THRESHOLD 823
+#define MU_BDIV_Q_THRESHOLD 942
+
+#define MATRIX22_STRASSEN_THRESHOLD 14
+#define HGCD_THRESHOLD 74
+#define HGCD_APPR_THRESHOLD 155
+#define HGCD_REDUCE_THRESHOLD 2479
+#define GCD_DC_THRESHOLD 351
+#define GCDEXT_DC_THRESHOLD 288
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 21
+#define SET_STR_DC_THRESHOLD 650
+#define SET_STR_PRECOMPUTE_THRESHOLD 1585
+
+#define FAC_DSC_THRESHOLD 662
+#define FAC_ODD_THRESHOLD 28
diff --git a/gmp/mpn/powerpc64/mode64/p6/aorsmul_1.asm b/gmp/mpn/powerpc64/mode64/p6/aorsmul_1.asm
new file mode 100644
index 0000000000..5a85f84f4a
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p6/aorsmul_1.asm
@@ -0,0 +1,183 @@
+dnl PowerPC-64 mpn_addmul_1 and mpn_submul_1 optimised for power6.
+
+dnl Copyright 1999-2001, 2003-2006, 2008, 2010, 2011 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C mpn_addmul_1 mpn_submul_1
+C cycles/limb cycles/limb
+C POWER3/PPC630 ? ?
+C POWER4/PPC970 ? ?
+C POWER5 ? ?
+C POWER6 12.25 12.8
+C POWER7 ? ?
+
+C TODO
+C * Reduce register usage.
+C * Schedule function entry code.
+C * Unroll more. 8-way unrolling would bring us to 10 c/l, 16-way unrolling
+C would bring us to 9 c/l.
+C * Handle n = 1 and perhaps n = 2 separately, without saving any registers.
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`v0', `r6')
+
+ifdef(`OPERATION_addmul_1',`
+ define(ADDSUBC, adde)
+ define(ADDSUB, addc)
+ define(func, mpn_addmul_1)
+ define(func_nc, mpn_addmul_1c) C FIXME: not really supported
+ define(AM, `$1')
+ define(SM, `')
+ define(CLRRSC, `addic $1, r0, 0')
+')
+ifdef(`OPERATION_submul_1',`
+ define(ADDSUBC, subfe)
+ define(ADDSUB, subfc)
+ define(func, mpn_submul_1)
+ define(func_nc, mpn_submul_1c) C FIXME: not really supported
+ define(AM, `')
+ define(SM, `$1')
+ define(CLRRSC, `subfc $1, r0, r0')
+')
+
+ASM_START()
+PROLOGUE(func)
+ std r31, -8(r1)
+ std r30, -16(r1)
+ std r29, -24(r1)
+ std r28, -32(r1)
+ std r27, -40(r1)
+
+ rldicl. r0, n, 0,62 C r0 = n & 3, set cr0
+ cmpdi cr6, r0, 2
+ addi n, n, 3 C compute count...
+ srdi n, n, 2 C ...for ctr
+ mtctr n C copy loop count into ctr
+ beq cr0, L(b0)
+ blt cr6, L(b1)
+ beq cr6, L(b2)
+
+L(b3): ld r8, 0(up)
+ ld r7, 8(up)
+ ld r27, 16(up)
+ addi up, up, 16
+ addi rp, rp, 16
+ mulld r5, r8, v0
+ mulhdu r8, r8, v0
+ mulld r9, r7, v0
+ mulhdu r7, r7, v0
+ mulld r11, r27, v0
+ mulhdu r27, r27, v0
+ ld r29, -16(rp)
+ ld r30, -8(rp)
+ ld r31, 0(rp)
+ addc r9, r9, r8
+ adde r11, r11, r7
+ addze r12, r27
+ ADDSUB r5, r5, r29
+ b L(l3)
+
+L(b2): ld r7, 0(up)
+ ld r27, 8(up)
+ addi up, up, 8
+ addi rp, rp, 8
+ mulld r9, r7, v0
+ mulhdu r7, r7, v0
+ mulld r11, r27, v0
+ mulhdu r27, r27, v0
+ ld r30, -8(rp)
+ ld r31, 0(rp)
+ addc r11, r11, r7
+ addze r12, r27
+ ADDSUB r9, r9, r30
+ b L(l2)
+
+L(b1): ld r27, 0(up)
+ ld r31, 0(rp)
+ mulld r11, r27, v0
+ mulhdu r12, r27, v0
+ ADDSUB r11, r11, r31
+ b L(l1)
+
+L(b0): addi up, up, -8
+ addi rp, rp, -8
+ CLRRSC( r12) C clear r12 and clr/set cy
+
+ ALIGN(32)
+L(top):
+SM(` subfe r11, r0, r0') C complement...
+SM(` addic r11, r11, 1') C ...carry flag
+ ld r10, 8(up)
+ ld r8, 16(up)
+ ld r7, 24(up)
+ ld r27, 32(up)
+ addi up, up, 32
+ addi rp, rp, 32
+ mulld r0, r10, v0
+ mulhdu r10, r10, v0
+ mulld r5, r8, v0
+ mulhdu r8, r8, v0
+ mulld r9, r7, v0
+ mulhdu r7, r7, v0
+ mulld r11, r27, v0
+ mulhdu r27, r27, v0
+ ld r28, -24(rp)
+ adde r0, r0, r12
+ ld r29, -16(rp)
+ adde r5, r5, r10
+ ld r30, -8(rp)
+ ld r31, 0(rp)
+ adde r9, r9, r8
+ adde r11, r11, r7
+ addze r12, r27
+ ADDSUB r0, r0, r28
+ std r0, -24(rp)
+ ADDSUBC r5, r5, r29
+L(l3): std r5, -16(rp)
+ ADDSUBC r9, r9, r30
+L(l2): std r9, -8(rp)
+ ADDSUBC r11, r11, r31
+L(l1): std r11, 0(rp)
+ bdnz L(top)
+
+AM(` addze r3, r12')
+SM(` subfe r11, r0, r0') C complement...
+ ld r31, -8(r1)
+SM(` subf r3, r11, r12')
+ ld r30, -16(r1)
+ ld r29, -24(r1)
+ ld r28, -32(r1)
+ ld r27, -40(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/p6/gmp-mparam.h b/gmp/mpn/powerpc64/mode64/p6/gmp-mparam.h
new file mode 100644
index 0000000000..c7e2f894ad
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p6/gmp-mparam.h
@@ -0,0 +1,160 @@
+/* POWER6 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2003, 2009-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 3500 MHz POWER6 (kolga.bibsys.no) */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 12
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 6
+#define USE_PREINV_DIVREM_1 0
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 21
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 50
+#define MUL_TOOM44_THRESHOLD 106
+#define MUL_TOOM6H_THRESHOLD 274
+#define MUL_TOOM8H_THRESHOLD 339
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 62
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 76
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 73
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 66
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 88
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 24
+#define SQR_TOOM3_THRESHOLD 49
+#define SQR_TOOM4_THRESHOLD 130
+#define SQR_TOOM6_THRESHOLD 226
+#define SQR_TOOM8_THRESHOLD 272
+
+#define MULMID_TOOM42_THRESHOLD 36
+
+#define MULMOD_BNM1_THRESHOLD 14
+#define SQRMOD_BNM1_THRESHOLD 14
+
+#define MUL_FFT_MODF_THRESHOLD 380 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 340, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 23, 7}, { 12, 6}, { 25, 7}, { 21, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 7}, { 27, 8}, \
+ { 21, 9}, { 11, 8}, { 25, 9}, { 15, 8}, \
+ { 33, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 47,11}, \
+ { 15,10}, { 31, 9}, { 63,10}, { 47,11}, \
+ { 31,10}, { 71,11}, { 47,12}, { 31,11}, \
+ { 63,10}, { 127, 9}, { 255, 8}, { 511,10}, \
+ { 135, 9}, { 271,11}, { 79, 9}, { 319, 8}, \
+ { 639,10}, { 175,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207,12}, { 63,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,11}, { 143,10}, \
+ { 287, 9}, { 575,10}, { 303, 9}, { 607,10}, \
+ { 319, 9}, { 639,11}, { 175,12}, { 95,11}, \
+ { 191,10}, { 383,11}, { 207,10}, { 415,13}, \
+ { 8192,14}, { 16384,15}, { 32768,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 79
+#define MUL_FFT_THRESHOLD 3520
+
+#define SQR_FFT_MODF_THRESHOLD 308 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 280, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 21, 7}, { 11, 6}, { 23, 7}, { 21, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 7}, { 27, 8}, \
+ { 21, 9}, { 11, 8}, { 25, 9}, { 15, 8}, \
+ { 33, 9}, { 19, 8}, { 39, 9}, { 23, 8}, \
+ { 47, 9}, { 27,10}, { 15, 9}, { 39,10}, \
+ { 23, 9}, { 47,11}, { 15,10}, { 31, 9}, \
+ { 63,10}, { 47,11}, { 31,10}, { 71, 9}, \
+ { 143,11}, { 47,12}, { 31,11}, { 63, 9}, \
+ { 255, 8}, { 511, 9}, { 271,10}, { 143,11}, \
+ { 79,10}, { 159, 9}, { 319,10}, { 175, 9}, \
+ { 351,11}, { 95,10}, { 191, 9}, { 383,10}, \
+ { 207,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511, 8}, { 1023,10}, { 271, 9}, { 543,11}, \
+ { 143,10}, { 287, 9}, { 575,11}, { 159,10}, \
+ { 319, 9}, { 639,11}, { 175,10}, { 351,12}, \
+ { 95,11}, { 191,10}, { 383,11}, { 207,10}, \
+ { 415,13}, { 8192,14}, { 16384,15}, { 32768,16}, \
+ { 65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+ {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 80
+#define SQR_FFT_THRESHOLD 2752
+
+#define MULLO_BASECASE_THRESHOLD 5
+#define MULLO_DC_THRESHOLD 62
+#define MULLO_MUL_N_THRESHOLD 2995
+
+#define DC_DIV_QR_THRESHOLD 59
+#define DC_DIVAPPR_Q_THRESHOLD 200
+#define DC_BDIV_QR_THRESHOLD 70
+#define DC_BDIV_Q_THRESHOLD 168
+
+#define INV_MULMOD_BNM1_THRESHOLD 53
+#define INV_NEWTON_THRESHOLD 170
+#define INV_APPR_THRESHOLD 166
+
+#define BINV_NEWTON_THRESHOLD 220
+#define REDC_1_TO_REDC_N_THRESHOLD 67
+
+#define MU_DIV_QR_THRESHOLD 998
+#define MU_DIVAPPR_Q_THRESHOLD 942
+#define MUPI_DIV_QR_THRESHOLD 57
+#define MU_BDIV_QR_THRESHOLD 889
+#define MU_BDIV_Q_THRESHOLD 1078
+
+#define POWM_SEC_TABLE 4,26,216,804,1731
+
+#define MATRIX22_STRASSEN_THRESHOLD 13
+#define HGCD_THRESHOLD 106
+#define HGCD_APPR_THRESHOLD 109
+#define HGCD_REDUCE_THRESHOLD 2205
+#define GCD_DC_THRESHOLD 492
+#define GCDEXT_DC_THRESHOLD 327
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 16
+#define GET_STR_PRECOMPUTE_THRESHOLD 28
+#define SET_STR_DC_THRESHOLD 537
+#define SET_STR_PRECOMPUTE_THRESHOLD 1576
+
+#define FAC_DSC_THRESHOLD 426
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/powerpc64/mode64/p6/mul_basecase.asm b/gmp/mpn/powerpc64/mode64/p6/mul_basecase.asm
new file mode 100644
index 0000000000..3d32b46c35
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p6/mul_basecase.asm
@@ -0,0 +1,589 @@
+dnl PowerPC-64 mpn_mul_basecase.
+
+dnl Copyright 1999-2001, 2003-2006, 2008, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 ?
+C POWER6 12.25
+
+C TODO
+C * Reduce register usage. At least 4 register less can be used.
+C * Unroll more. 8-way unrolling would bring us to 10 c/l, 16-way unrolling
+C would bring us to 9 c/l.
+C * The bdz insns for b1 and b2 will never branch,
+C * Align things better, perhaps by moving things like pointer updates from
+C before to after loops.
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`un', `r5')
+define(`vp', `r6')
+define(`vn', `r7')
+
+define(`v0', `r25')
+define(`outer_rp', `r22')
+define(`outer_up', `r23')
+
+ASM_START()
+PROLOGUE(mpn_mul_basecase)
+
+C Special code for un <= 2, for efficiency of these important cases,
+C and since it simplifies the default code.
+ cmpdi cr0, un, 2
+ bgt cr0, L(un_gt2)
+ cmpdi cr6, vn, 1
+ ld r7, 0(vp)
+ ld r5, 0(up)
+ mulld r8, r5, r7 C weight 0
+ mulhdu r9, r5, r7 C weight 1
+ std r8, 0(rp)
+ beq cr0, L(2x)
+ std r9, 8(rp)
+ blr
+ ALIGN(16)
+L(2x): ld r0, 8(up)
+ mulld r8, r0, r7 C weight 1
+ mulhdu r10, r0, r7 C weight 2
+ addc r9, r9, r8
+ addze r10, r10
+ bne cr6, L(2x2)
+ std r9, 8(rp)
+ std r10, 16(rp)
+ blr
+ ALIGN(16)
+L(2x2): ld r6, 8(vp)
+ nop
+ mulld r8, r5, r6 C weight 1
+ mulhdu r11, r5, r6 C weight 2
+ mulld r12, r0, r6 C weight 2
+ mulhdu r0, r0, r6 C weight 3
+ addc r9, r9, r8
+ std r9, 8(rp)
+ adde r11, r11, r10
+ addze r0, r0
+ addc r11, r11, r12
+ addze r0, r0
+ std r11, 16(rp)
+ std r0, 24(rp)
+ blr
+
+L(un_gt2):
+ std r31, -8(r1)
+ std r30, -16(r1)
+ std r29, -24(r1)
+ std r28, -32(r1)
+ std r27, -40(r1)
+ std r26, -48(r1)
+ std r25, -56(r1)
+ std r24, -64(r1)
+ std r23, -72(r1)
+ std r22, -80(r1)
+ std r21, -88(r1)
+ std r20, -96(r1)
+
+ mr outer_rp, rp
+ mr outer_up, up
+
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ ld r26, 0(up)
+
+ rldicl. r0, un, 0,62 C r0 = n & 3, set cr0
+ cmpdi cr6, r0, 2
+ addi un, un, 4 C compute count...
+ srdi un, un, 2 C ...for ctr
+ mtctr un C copy inner loop count into ctr
+ beq cr0, L(b0)
+ blt cr6, L(b1)
+ beq cr6, L(b2)
+
+
+ ALIGN(16)
+L(b3):
+ ld r27, 8(up)
+ ld r20, 16(up)
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ mulld r9, r20, v0
+ mulhdu r10, r20, v0
+ addc r24, r24, r31
+ adde r9, r9, r8
+ addze r12, r10
+ std r0, 0(rp)
+ std r24, 8(rp)
+ std r9, 16(rp)
+ addi up, up, 16
+ addi rp, rp, 16
+ bdz L(end_m_3)
+
+ ALIGN(32)
+L(lo_m_3):
+ ld r26, 8(up)
+ ld r27, 16(up)
+ ld r20, 24(up)
+ ld r21, 32(up)
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ mulld r9, r20, v0
+ mulhdu r27, r20, v0
+ mulld r11, r21, v0
+ mulhdu r26, r21, v0
+ adde r0, r0, r12
+ adde r24, r24, r31
+ std r0, 8(rp)
+ adde r9, r9, r8
+ std r24, 16(rp)
+ adde r11, r11, r27
+ std r9, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ mr r12, r26
+ bdnz L(lo_m_3)
+
+ ALIGN(16)
+L(end_m_3):
+ addze r12, r12
+ addic. vn, vn, -1
+ std r12, 8(rp)
+ beq L(ret)
+
+ ALIGN(16)
+L(outer_lo_3):
+ mtctr un C copy inner loop count into ctr
+ addi rp, outer_rp, 24
+ addi up, outer_up, 16
+ addi outer_rp, outer_rp, 8
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ ld r26, -16(up)
+ ld r27, -8(up)
+ ld r20, 0(up)
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ mulld r9, r20, v0
+ mulhdu r10, r20, v0
+ ld r28, -16(rp)
+ ld r29, -8(rp)
+ ld r30, 0(rp)
+ addc r24, r24, r31
+ adde r9, r9, r8
+ addze r12, r10
+ addc r0, r0, r28
+ std r0, -16(rp)
+ adde r24, r24, r29
+ std r24, -8(rp)
+ adde r9, r9, r30
+ std r9, 0(rp)
+ bdz L(end_3)
+
+ ALIGN(32) C registers dying
+L(lo_3):
+ ld r26, 8(up)
+ ld r27, 16(up)
+ ld r20, 24(up) C
+ ld r21, 32(up) C
+ addi up, up, 32 C
+ addi rp, rp, 32 C
+ mulld r0, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ mulld r24, r27, v0 C
+ mulhdu r8, r27, v0 C 27
+ mulld r9, r20, v0 C
+ mulhdu r27, r20, v0 C 26
+ mulld r11, r21, v0 C
+ mulhdu r26, r21, v0 C 27
+ ld r28, -24(rp) C
+ adde r0, r0, r12 C 0 12
+ ld r29, -16(rp) C
+ adde r24, r24, r10 C 24 10
+ ld r30, -8(rp) C
+ ld r31, 0(rp) C
+ adde r9, r9, r8 C 8 9
+ adde r11, r11, r27 C 27 11
+ addze r12, r26 C 26
+ addc r0, r0, r28 C 0 28
+ std r0, -24(rp) C 0
+ adde r24, r24, r29 C 7 29
+ std r24, -16(rp) C 7
+ adde r9, r9, r30 C 9 30
+ std r9, -8(rp) C 9
+ adde r11, r11, r31 C 11 31
+ std r11, 0(rp) C 11
+ bdnz L(lo_3) C
+
+ ALIGN(16)
+L(end_3):
+ addze r12, r12
+ addic. vn, vn, -1
+ std r12, 8(rp)
+ bne L(outer_lo_3)
+ b L(ret)
+
+
+ ALIGN(16)
+L(b1):
+ mulld r0, r26, v0
+ mulhdu r12, r26, v0
+ addic r0, r0, 0
+ std r0, 0(rp)
+ bdz L(end_m_1)
+
+ ALIGN(16)
+L(lo_m_1):
+ ld r26, 8(up)
+ ld r27, 16(up)
+ ld r20, 24(up)
+ ld r21, 32(up)
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ mulld r9, r20, v0
+ mulhdu r27, r20, v0
+ mulld r11, r21, v0
+ mulhdu r26, r21, v0
+ adde r0, r0, r12
+ adde r24, r24, r31
+ std r0, 8(rp)
+ adde r9, r9, r8
+ std r24, 16(rp)
+ adde r11, r11, r27
+ std r9, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ mr r12, r26
+ bdnz L(lo_m_1)
+
+ ALIGN(16)
+L(end_m_1):
+ addze r12, r12
+ addic. vn, vn, -1
+ std r12, 8(rp)
+ beq L(ret)
+
+ ALIGN(16)
+L(outer_lo_1):
+ mtctr un C copy inner loop count into ctr
+ addi rp, outer_rp, 8
+ mr up, outer_up
+ addi outer_rp, outer_rp, 8
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ ld r26, 0(up)
+ ld r28, 0(rp)
+ mulld r0, r26, v0
+ mulhdu r12, r26, v0
+ addc r0, r0, r28
+ std r0, 0(rp)
+ bdz L(end_1)
+
+ ALIGN(32) C registers dying
+L(lo_1):
+ ld r26, 8(up)
+ ld r27, 16(up)
+ ld r20, 24(up) C
+ ld r21, 32(up) C
+ addi up, up, 32 C
+ addi rp, rp, 32 C
+ mulld r0, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ mulld r24, r27, v0 C
+ mulhdu r8, r27, v0 C 27
+ mulld r9, r20, v0 C
+ mulhdu r27, r20, v0 C 26
+ mulld r11, r21, v0 C
+ mulhdu r26, r21, v0 C 27
+ ld r28, -24(rp) C
+ adde r0, r0, r12 C 0 12
+ ld r29, -16(rp) C
+ adde r24, r24, r10 C 24 10
+ ld r30, -8(rp) C
+ ld r31, 0(rp) C
+ adde r9, r9, r8 C 8 9
+ adde r11, r11, r27 C 27 11
+ addze r12, r26 C 26
+ addc r0, r0, r28 C 0 28
+ std r0, -24(rp) C 0
+ adde r24, r24, r29 C 7 29
+ std r24, -16(rp) C 7
+ adde r9, r9, r30 C 9 30
+ std r9, -8(rp) C 9
+ adde r11, r11, r31 C 11 31
+ std r11, 0(rp) C 11
+ bdnz L(lo_1) C
+
+ ALIGN(16)
+L(end_1):
+ addze r12, r12
+ addic. vn, vn, -1
+ std r12, 8(rp)
+ bne L(outer_lo_1)
+ b L(ret)
+
+
+ ALIGN(16)
+L(b0):
+ addi up, up, -8
+ addi rp, rp, -8
+ li r12, 0
+ addic r12, r12, 0
+ bdz L(end_m_0)
+
+ ALIGN(16)
+L(lo_m_0):
+ ld r26, 8(up)
+ ld r27, 16(up)
+ ld r20, 24(up)
+ ld r21, 32(up)
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ mulld r9, r20, v0
+ mulhdu r27, r20, v0
+ mulld r11, r21, v0
+ mulhdu r26, r21, v0
+ adde r0, r0, r12
+ adde r24, r24, r31
+ std r0, 8(rp)
+ adde r9, r9, r8
+ std r24, 16(rp)
+ adde r11, r11, r27
+ std r9, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ mr r12, r26
+ bdnz L(lo_m_0)
+
+ ALIGN(16)
+L(end_m_0):
+ addze r12, r12
+ addic. vn, vn, -1
+ std r12, 8(rp)
+ beq L(ret)
+
+ ALIGN(16)
+L(outer_lo_0):
+ mtctr un C copy inner loop count into ctr
+ addi rp, outer_rp, 0
+ addi up, outer_up, -8
+ addi outer_rp, outer_rp, 8
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ li r12, 0
+ addic r12, r12, 0
+ bdz L(end_0)
+
+ ALIGN(32) C registers dying
+L(lo_0):
+ ld r26, 8(up)
+ ld r27, 16(up)
+ ld r20, 24(up) C
+ ld r21, 32(up) C
+ addi up, up, 32 C
+ addi rp, rp, 32 C
+ mulld r0, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ mulld r24, r27, v0 C
+ mulhdu r8, r27, v0 C 27
+ mulld r9, r20, v0 C
+ mulhdu r27, r20, v0 C 26
+ mulld r11, r21, v0 C
+ mulhdu r26, r21, v0 C 27
+ ld r28, -24(rp) C
+ adde r0, r0, r12 C 0 12
+ ld r29, -16(rp) C
+ adde r24, r24, r10 C 24 10
+ ld r30, -8(rp) C
+ ld r31, 0(rp) C
+ adde r9, r9, r8 C 8 9
+ adde r11, r11, r27 C 27 11
+ addze r12, r26 C 26
+ addc r0, r0, r28 C 0 28
+ std r0, -24(rp) C 0
+ adde r24, r24, r29 C 7 29
+ std r24, -16(rp) C 7
+ adde r9, r9, r30 C 9 30
+ std r9, -8(rp) C 9
+ adde r11, r11, r31 C 11 31
+ std r11, 0(rp) C 11
+ bdnz L(lo_0) C
+
+ ALIGN(16)
+L(end_0):
+ addze r12, r12
+ addic. vn, vn, -1
+ std r12, 8(rp)
+ bne L(outer_lo_0)
+ b L(ret)
+
+
+ ALIGN(16)
+L(b2): ld r27, 8(up)
+ addi up, up, 8
+ mulld r0, r26, v0
+ mulhdu r10, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ addc r24, r24, r10
+ addze r12, r8
+ std r0, 0(rp)
+ std r24, 8(rp)
+ addi rp, rp, 8
+ bdz L(end_m_2)
+
+ ALIGN(16)
+L(lo_m_2):
+ ld r26, 8(up)
+ ld r27, 16(up)
+ ld r20, 24(up)
+ ld r21, 32(up)
+ mulld r0, r26, v0
+ mulhdu r31, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ mulld r9, r20, v0
+ mulhdu r27, r20, v0
+ mulld r11, r21, v0
+ mulhdu r26, r21, v0
+ adde r0, r0, r12
+ adde r24, r24, r31
+ std r0, 8(rp)
+ adde r9, r9, r8
+ std r24, 16(rp)
+ adde r11, r11, r27
+ std r9, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ mr r12, r26
+ bdnz L(lo_m_2)
+
+ ALIGN(16)
+L(end_m_2):
+ addze r12, r12
+ addic. vn, vn, -1
+ std r12, 8(rp)
+ beq L(ret)
+
+ ALIGN(16)
+L(outer_lo_2):
+ mtctr un C copy inner loop count into ctr
+ addi rp, outer_rp, 16
+ addi up, outer_up, 8
+ addi outer_rp, outer_rp, 8
+ ld v0, 0(vp) C new v limb
+ addi vp, vp, 8
+ ld r26, -8(up)
+ ld r27, 0(up)
+ ld r28, -8(rp)
+ ld r29, 0(rp)
+ mulld r0, r26, v0
+ mulhdu r10, r26, v0
+ mulld r24, r27, v0
+ mulhdu r8, r27, v0
+ addc r24, r24, r10
+ addze r12, r8
+ addc r0, r0, r28
+ std r0, -8(rp)
+ adde r24, r24, r29
+ std r24, 0(rp)
+ bdz L(end_2)
+
+ ALIGN(16) C registers dying
+L(lo_2):
+ ld r26, 8(up)
+ ld r27, 16(up)
+ ld r20, 24(up) C
+ ld r21, 32(up) C
+ addi up, up, 32 C
+ addi rp, rp, 32 C
+ mulld r0, r26, v0 C
+ mulhdu r10, r26, v0 C 26
+ mulld r24, r27, v0 C
+ mulhdu r8, r27, v0 C 27
+ mulld r9, r20, v0 C
+ mulhdu r27, r20, v0 C 26
+ mulld r11, r21, v0 C
+ mulhdu r26, r21, v0 C 27
+ ld r28, -24(rp) C
+ adde r0, r0, r12 C 0 12
+ ld r29, -16(rp) C
+ adde r24, r24, r10 C 24 10
+ ld r30, -8(rp) C
+ ld r31, 0(rp) C
+ adde r9, r9, r8 C 8 9
+ adde r11, r11, r27 C 27 11
+ addze r12, r26 C 26
+ addc r0, r0, r28 C 0 28
+ std r0, -24(rp) C 0
+ adde r24, r24, r29 C 7 29
+ std r24, -16(rp) C 7
+ adde r9, r9, r30 C 9 30
+ std r9, -8(rp) C 9
+ adde r11, r11, r31 C 11 31
+ std r11, 0(rp) C 11
+ bdnz L(lo_2) C
+
+ ALIGN(16)
+L(end_2):
+ addze r12, r12
+ addic. vn, vn, -1
+ std r12, 8(rp)
+ bne L(outer_lo_2)
+C b L(ret)
+
+L(ret): ld r31, -8(r1)
+ ld r30, -16(r1)
+ ld r29, -24(r1)
+ ld r28, -32(r1)
+ ld r27, -40(r1)
+ ld r26, -48(r1)
+ ld r25, -56(r1)
+ ld r24, -64(r1)
+ ld r23, -72(r1)
+ ld r22, -80(r1)
+ ld r21, -88(r1)
+ ld r20, -96(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/p7/aormul_2.asm b/gmp/mpn/powerpc64/mode64/p7/aormul_2.asm
new file mode 100644
index 0000000000..8731e01a89
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p7/aormul_2.asm
@@ -0,0 +1,135 @@
+dnl PowerPC-64 mpn_mul_2 and mpn_addmul_2.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb
+C mul_2 addmul_2
+C POWER3/PPC630 ? ?
+C POWER4/PPC970 ? ?
+C POWER5 ? ?
+C POWER6 ? ?
+C POWER7-SMT4 3 3
+C POWER7-SMT2 ? ?
+C POWER7-SMT1 ? ?
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`vp', `r6')
+
+define(`cy0', `r10')
+ifdef(`EXTRA_REGISTER',
+` define(`cy1', EXTRA_REGISTER)',
+` define(`cy1', `r31')')
+
+ifdef(`OPERATION_mul_2',`
+ define(`AM', `')
+ define(`ADDX', `addc')
+ define(`func', `mpn_mul_2')
+')
+ifdef(`OPERATION_addmul_2',`
+ define(`AM', `$1')
+ define(`ADDX', `adde')
+ define(`func', `mpn_addmul_2')
+')
+
+MULFUNC_PROLOGUE(mpn_mul_2 mpn_addmul_2)
+
+ASM_START()
+PROLOGUE(func)
+
+ifdef(`EXTRA_REGISTER',,`
+ std r31, -8(r1)
+')
+ andi. r12, n, 1
+ addi r0, n, 1
+ srdi r0, r0, 1
+ mtctr r0
+ ld r11, 0(vp) C v0
+ li cy0, 0
+ ld r12, 8(vp) C v1
+ li cy1, 0
+ ld r5, 0(up)
+ beq L(lo0)
+ addi up, up, -8
+ addi rp, rp, -8
+ b L(lo1)
+
+ ALIGN(32)
+L(top):
+AM(` ld r0, -8(rp)')
+ ld r5, 0(up)
+AM(` addc r6, r6, r0')
+ ADDX r7, r7, r8
+ addze r9, r9
+ addc r6, r6, cy0
+ adde cy0, r7, cy1
+ std r6, -8(rp)
+ addze cy1, r9
+L(lo0): mulld r6, r11, r5 C v0 * u[i] weight 0
+ mulhdu r7, r11, r5 C v0 * u[i] weight 1
+ mulld r8, r12, r5 C v1 * u[i] weight 1
+ mulhdu r9, r12, r5 C v1 * u[i] weight 2
+AM(` ld r0, 0(rp)')
+ ld r5, 8(up)
+AM(` addc r6, r6, r0')
+ ADDX r7, r7, r8
+ addze r9, r9
+ addc r6, r6, cy0
+ adde cy0, r7, cy1
+ std r6, 0(rp)
+ addze cy1, r9
+L(lo1): mulld r6, r11, r5 C v0 * u[i] weight 0
+ mulhdu r7, r11, r5 C v0 * u[i] weight 1
+ addi up, up, 16
+ addi rp, rp, 16
+ mulld r8, r12, r5 C v1 * u[i] weight 1
+ mulhdu r9, r12, r5 C v1 * u[i] weight 2
+ bdnz L(top)
+
+L(end):
+AM(` ld r0, -8(rp)')
+AM(` addc r6, r6, r0')
+ ADDX r7, r7, r8
+ addze r9, r9
+ addc r6, r6, cy0
+ std r6, -8(rp)
+ adde cy0, r7, cy1
+ addze cy1, r9
+ std cy0, 0(rp)
+ mr r3, cy1
+
+ifdef(`EXTRA_REGISTER',,`
+ ld r31, -8(r1)
+')
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/p7/aors_n.asm b/gmp/mpn/powerpc64/mode64/p7/aors_n.asm
new file mode 100644
index 0000000000..857c701dec
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p7/aors_n.asm
@@ -0,0 +1,128 @@
+dnl PowerPC-64 mpn_add_n, mpn_sub_n optimised for POWER7.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 ?
+C POWER6 ?
+C POWER7 2.18
+
+C This is a tad bit slower than the cnd_aors_n.asm code, which is of course an
+C anomaly.
+
+ifdef(`OPERATION_add_n',`
+ define(ADDSUBC, adde)
+ define(ADDSUB, addc)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)
+ define(GENRVAL, `addi r3, r3, 1')
+ define(SETCBR, `addic r0, $1, -1')
+ define(CLRCB, `addic r0, r0, 0')
+')
+ifdef(`OPERATION_sub_n',`
+ define(ADDSUBC, subfe)
+ define(ADDSUB, subfc)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)
+ define(GENRVAL, `neg r3, r3')
+ define(SETCBR, `subfic r0, $1, 0')
+ define(CLRCB, `addic r0, r1, -1')
+')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`vp', `r5')
+define(`n', `r6')
+
+ASM_START()
+PROLOGUE(func_nc)
+ SETCBR(r7)
+ b L(ent)
+EPILOGUE()
+
+PROLOGUE(func)
+ CLRCB
+L(ent):
+ andi. r7, n, 1
+ beq L(bx0)
+
+L(bx1): ld r7, 0(up)
+ ld r9, 0(vp)
+ ADDSUBC r11, r9, r7
+ std r11, 0(rp)
+ cmpldi cr6, n, 1
+ beq cr6, L(end)
+ addi up, up, 8
+ addi vp, vp, 8
+ addi rp, rp, 8
+
+L(bx0): addi r0, n, 2 C compute branch...
+ srdi r0, r0, 2 C ...count
+ mtctr r0
+
+ andi. r7, n, 2
+ bne L(mid)
+
+ addi up, up, 16
+ addi vp, vp, 16
+ addi rp, rp, 16
+
+ ALIGN(32)
+L(top): ld r6, -16(up)
+ ld r7, -8(up)
+ ld r8, -16(vp)
+ ld r9, -8(vp)
+ ADDSUBC r10, r8, r6
+ ADDSUBC r11, r9, r7
+ std r10, -16(rp)
+ std r11, -8(rp)
+L(mid): ld r6, 0(up)
+ ld r7, 8(up)
+ ld r8, 0(vp)
+ ld r9, 8(vp)
+ ADDSUBC r10, r8, r6
+ ADDSUBC r11, r9, r7
+ std r10, 0(rp)
+ std r11, 8(rp)
+ addi up, up, 32
+ addi vp, vp, 32
+ addi rp, rp, 32
+ bdnz L(top)
+
+L(end): subfe r3, r0, r0 C -cy
+ GENRVAL
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/p7/aorsorrlsh1_n.asm b/gmp/mpn/powerpc64/mode64/p7/aorsorrlsh1_n.asm
new file mode 100644
index 0000000000..ddf5fd84b1
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p7/aorsorrlsh1_n.asm
@@ -0,0 +1,43 @@
+dnl PowerPC-64 mpn_addlsh1_n, mpn_sublsh1_n, mpn_rsblsh1_n.
+
+dnl Copyright 2003, 2005, 2009, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 1)
+define(RSH, 63)
+
+ifdef(`OPERATION_addlsh1_n',`define(`DO_add')')
+ifdef(`OPERATION_sublsh1_n',`define(`DO_sub')')
+ifdef(`OPERATION_rsblsh1_n',`define(`DO_rsb')')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n mpn_rsblsh1_n)
+
+include_mpn(`powerpc64/mode64/p7/aorsorrlshC_n.asm')
diff --git a/gmp/mpn/powerpc64/mode64/p7/aorsorrlsh2_n.asm b/gmp/mpn/powerpc64/mode64/p7/aorsorrlsh2_n.asm
new file mode 100644
index 0000000000..3f9d88d6ca
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p7/aorsorrlsh2_n.asm
@@ -0,0 +1,43 @@
+dnl PowerPC-64 mpn_addlsh2_n, mpn_sublsh2_n, mpn_rsblsh2_n.
+
+dnl Copyright 2003, 2005, 2009, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 2)
+define(RSH, 62)
+
+ifdef(`OPERATION_addlsh2_n',`define(`DO_add')')
+ifdef(`OPERATION_sublsh2_n',`define(`DO_sub')')
+ifdef(`OPERATION_rsblsh2_n',`define(`DO_rsb')')
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_sublsh2_n mpn_rsblsh2_n)
+
+include_mpn(`powerpc64/mode64/p7/aorsorrlshC_n.asm')
diff --git a/gmp/mpn/powerpc64/mode64/p7/aorsorrlshC_n.asm b/gmp/mpn/powerpc64/mode64/p7/aorsorrlshC_n.asm
new file mode 100644
index 0000000000..525120262f
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p7/aorsorrlshC_n.asm
@@ -0,0 +1,129 @@
+dnl PowerPC-64 mpn_addlshC_n, mpn_sublshC_n, mpn_rsblshC_n.
+
+dnl Copyright 2003, 2005, 2009, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 ?
+C POWER6 ?
+C POWER7 2.5
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`vp', `r5')
+define(`n', `r6')
+
+ifdef(`DO_add', `
+ define(`ADDSUBC', `addc $1, $2, $3')
+ define(`ADDSUBE', `adde $1, $2, $3')
+ define(INITCY, `addic $1, r1, 0')
+ define(RETVAL, `addze r3, $1')
+ define(`func', mpn_addlsh`'LSH`'_n)')
+ifdef(`DO_sub', `
+ define(`ADDSUBC', `subfc $1, $2, $3')
+ define(`ADDSUBE', `subfe $1, $2, $3')
+ define(INITCY, `addic $1, r1, -1')
+ define(RETVAL, `subfze r3, $1
+ neg r3, r3')
+ define(`func', mpn_sublsh`'LSH`'_n)')
+ifdef(`DO_rsb', `
+ define(`ADDSUBC', `subfc $1, $3, $2')
+ define(`ADDSUBE', `subfe $1, $3, $2')
+ define(INITCY, `addic $1, r1, -1')
+ define(RETVAL, `addme r3, $1')
+ define(`func', mpn_rsblsh`'LSH`'_n)')
+
+define(`s0', `r0') define(`s1', `r9')
+define(`u0', `r6') define(`u1', `r7')
+define(`v0', `r10') define(`v1', `r11')
+
+
+ASM_START()
+PROLOGUE(func)
+ rldic r7, n, 3, 59
+ add up, up, r7
+ add vp, vp, r7
+ add rp, rp, r7
+
+ifdef(`DO_add', `
+ addic r0, n, 3 C set cy flag as side effect
+',`
+ subfc r0, r0, r0 C set cy flag
+ addi r0, n, 3
+')
+ srdi r0, r0, 2
+ mtctr r0
+
+ andi. r0, n, 1
+ beq L(bx0)
+
+L(bx1): andi. r0, n, 2
+ li s0, 0
+ bne L(lo3)
+ b L(lo1)
+
+L(bx0): andi. r0, n, 2
+ li s1, 0
+ bne L(lo2)
+
+ ALIGN(32)
+L(top): addi rp, rp, 32
+ ld v0, 0(vp)
+ addi vp, vp, 32
+ rldimi s1, v0, LSH, 0
+ ld u0, 0(up)
+ addi up, up, 32
+ srdi s0, v0, RSH
+ ADDSUBE(s1, s1, u0)
+ std s1, -32(rp)
+L(lo3): ld v1, -24(vp)
+ rldimi s0, v1, LSH, 0
+ ld u1, -24(up)
+ srdi s1, v1, RSH
+ ADDSUBE(s0, s0, u1)
+ std s0, -24(rp)
+L(lo2): ld v0, -16(vp)
+ rldimi s1, v0, LSH, 0
+ ld u0, -16(up)
+ srdi s0, v0, RSH
+ ADDSUBE(s1, s1, u0)
+ std s1, -16(rp)
+L(lo1): ld v1, -8(vp)
+ rldimi s0, v1, LSH, 0
+ ld u1, -8(up)
+ srdi s1, v1, RSH
+ ADDSUBE(s0, s0, u1)
+ std s0, -8(rp)
+ bdnz L(top) C decrement CTR and loop back
+
+ RETVAL( s1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/p7/gcd_1.asm b/gmp/mpn/powerpc64/mode64/p7/gcd_1.asm
new file mode 100644
index 0000000000..47cb40bdc5
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p7/gcd_1.asm
@@ -0,0 +1,110 @@
+dnl PowerPC-64 mpn_gcd_1.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/bit (approx)
+C POWER3/PPC630 -
+C POWER4/PPC970 -
+C POWER5 -
+C POWER6 -
+C POWER7 7.6
+C Numbers measured with: speed -CD -s16-64 -t48 mpn_gcd_1
+
+C INPUT PARAMETERS
+define(`up', `r3')
+define(`n', `r4')
+define(`v0', `r5')
+
+EXTERN_FUNC(mpn_mod_1)
+EXTERN_FUNC(mpn_modexact_1c_odd)
+
+ASM_START()
+PROLOGUE(mpn_gcd_1,toc)
+ mflr r0
+ std r30, -16(r1)
+ std r31, -8(r1)
+ std r0, 16(r1)
+ stdu r1, -128(r1)
+
+ ld r7, 0(up) C U low limb
+ or r0, r5, r7 C x | y
+
+ neg r6, r0
+ and r6, r6, r0
+ cntlzd r31, r6 C common twos
+ subfic r31, r31, 63
+
+ neg r6, r5
+ and r6, r6, r5
+ cntlzd r8, r6
+ subfic r8, r8, 63
+ srd r5, r5, r8
+ mr r30, r5 C v0 saved
+
+ cmpdi r4, BMOD_1_TO_MOD_1_THRESHOLD
+ blt L(bmod)
+ CALL( mpn_mod_1)
+ b L(reduced)
+L(bmod):
+ li r6, 0
+ CALL( mpn_modexact_1c_odd)
+L(reduced):
+
+define(`cnt', `r9')dnl
+
+ neg. r6, r3
+ and r6, r6, r3
+ cntlzd cnt, r6
+ li r12, 63
+ bne L(mid)
+ b L(end)
+
+ ALIGN(16)
+L(top): isel r30, r3, r30, 29 C y = min(x,y)
+ isel r3, r10, r11, 29 C x = |y - x|
+L(mid): subf cnt, cnt, r12 C cnt = 63-cnt
+ srd r3, r3, cnt
+ subf r10, r3, r30 C r10 = y - x
+ subf r11, r30, r3 C r11 = x - y
+ cmpld cr7, r30, r3
+ and r8, r11, r10 C isolate lsb
+ cntlzd cnt, r8
+ bne cr7, L(top)
+
+L(end): sld r3, r30, r31
+
+ addi r1, r1, 128
+ ld r0, 16(r1)
+ ld r30, -16(r1)
+ ld r31, -8(r1)
+ mtlr r0
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/p7/gmp-mparam.h b/gmp/mpn/powerpc64/mode64/p7/gmp-mparam.h
new file mode 100644
index 0000000000..7e719e8aac
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/p7/gmp-mparam.h
@@ -0,0 +1,243 @@
+/* POWER7 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2003, 2009-2011, 2013, 2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 3700 MHz POWER7/SMT4 (gcc111.fsffrance.org) */
+/* FFT tuning limit = 40000000 */
+/* Generated by tuneup.c, 2014-03-13, gcc 4.8 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 8
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 24
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 13
+#define USE_PREINV_DIVREM_1 0
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 28
+
+#define MUL_TOOM22_THRESHOLD 22
+#define MUL_TOOM33_THRESHOLD 72
+#define MUL_TOOM44_THRESHOLD 200
+#define MUL_TOOM6H_THRESHOLD 298
+#define MUL_TOOM8H_THRESHOLD 406
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 69
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 140
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 132
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 138
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 124
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 36
+#define SQR_TOOM3_THRESHOLD 109
+#define SQR_TOOM4_THRESHOLD 196
+#define SQR_TOOM6_THRESHOLD 414
+#define SQR_TOOM8_THRESHOLD 547
+
+#define MULMID_TOOM42_THRESHOLD 58
+
+#define MULMOD_BNM1_THRESHOLD 15
+#define SQRMOD_BNM1_THRESHOLD 20
+
+#define MUL_FFT_MODF_THRESHOLD 412 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 412, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 21, 7}, { 11, 6}, { 23, 7}, { 12, 6}, \
+ { 25, 7}, { 21, 8}, { 11, 7}, { 25, 8}, \
+ { 13, 7}, { 28, 8}, { 15, 7}, { 33, 8}, \
+ { 17, 7}, { 35, 8}, { 19, 7}, { 39, 8}, \
+ { 21, 9}, { 11, 8}, { 29, 9}, { 15, 8}, \
+ { 35, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 47, 9}, { 27,10}, { 15, 9}, { 31, 8}, \
+ { 63, 9}, { 43,10}, { 23, 9}, { 51,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 79,11}, { 47,10}, { 95,12}, \
+ { 31,11}, { 63,10}, { 135,11}, { 79,10}, \
+ { 159,11}, { 95,10}, { 191, 9}, { 383,11}, \
+ { 111,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,11}, { 143,10}, { 287, 9}, { 575,11}, \
+ { 159,10}, { 319,12}, { 95,11}, { 191,10}, \
+ { 383, 9}, { 767,13}, { 63,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 271,10}, { 543, 9}, \
+ { 1087,11}, { 287,10}, { 575,11}, { 303,12}, \
+ { 159,11}, { 319,10}, { 639,11}, { 335,10}, \
+ { 671,11}, { 351,10}, { 703, 9}, { 1407,11}, \
+ { 383,10}, { 767,11}, { 415,10}, { 831,12}, \
+ { 223,11}, { 447,10}, { 895,13}, { 127,12}, \
+ { 255,11}, { 511,10}, { 1023,11}, { 543,12}, \
+ { 287,11}, { 575,10}, { 1151,11}, { 607,12}, \
+ { 319,11}, { 639,10}, { 1279,11}, { 671,12}, \
+ { 351,11}, { 703,12}, { 383,11}, { 767,12}, \
+ { 415,11}, { 831,10}, { 1663,12}, { 447,11}, \
+ { 895,12}, { 479,14}, { 127,13}, { 255,12}, \
+ { 511,11}, { 1023,12}, { 543,11}, { 1087,10}, \
+ { 2175,12}, { 575,11}, { 1151,12}, { 607,11}, \
+ { 1215,13}, { 319,12}, { 639,11}, { 1279,12}, \
+ { 671,11}, { 1343,10}, { 2687,12}, { 703,11}, \
+ { 1407,13}, { 383,12}, { 767,11}, { 1535,12}, \
+ { 799,11}, { 1599,12}, { 831,11}, { 1663,13}, \
+ { 447,12}, { 895,11}, { 1791,12}, { 959,11}, \
+ { 1919,14}, { 255,13}, { 511,12}, { 1087,11}, \
+ { 2175,13}, { 575,12}, { 1215,11}, { 2431,13}, \
+ { 639,12}, { 1343,11}, { 2687,13}, { 703,12}, \
+ { 1407,11}, { 2815,14}, { 383,13}, { 767,12}, \
+ { 1599,13}, { 831,12}, { 1663,13}, { 895,12}, \
+ { 1791,13}, { 959,12}, { 1919,11}, { 3839,14}, \
+ { 511,13}, { 1023,12}, { 2047,13}, { 1087,12}, \
+ { 2175,13}, { 1215,12}, { 2431,11}, { 4863,14}, \
+ { 639,13}, { 1279,12}, { 2559,13}, { 1343,12}, \
+ { 2687,13}, { 1407,12}, { 2815,13}, { 1471,12}, \
+ { 2943,14}, { 767,13}, { 1599,12}, { 3199,13}, \
+ { 1663,14}, { 895,13}, { 1791,12}, { 3583,13}, \
+ { 1919,12}, { 3839,15}, { 511,14}, { 1023,13}, \
+ { 2175,14}, { 1151,13}, { 2431,12}, { 4863,14}, \
+ { 1279,13}, { 2687,14}, { 1407,13}, { 2815,15}, \
+ { 767,14}, { 1535,13}, { 3199,14}, { 1663,13}, \
+ { 3455,12}, { 6911,14}, { 1919,13}, { 3839,16}, \
+ { 511,15}, { 1023,14}, { 2175,13}, { 4351,14}, \
+ { 2431,13}, { 4863,15}, { 32768,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 231
+#define MUL_FFT_THRESHOLD 4288
+
+#define SQR_FFT_MODF_THRESHOLD 368 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 368, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 21, 7}, { 11, 6}, { 23, 7}, { 12, 6}, \
+ { 25, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
+ { 11, 7}, { 25, 8}, { 13, 7}, { 28, 8}, \
+ { 15, 7}, { 32, 8}, { 17, 7}, { 35, 8}, \
+ { 21, 9}, { 11, 8}, { 29, 9}, { 15, 8}, \
+ { 35, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 47, 9}, { 27,10}, { 15, 9}, { 31, 8}, \
+ { 63, 9}, { 39,10}, { 23, 9}, { 51,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 79,11}, { 47,10}, { 95,12}, \
+ { 31,11}, { 63,10}, { 135,11}, { 79,10}, \
+ { 159, 9}, { 319,11}, { 95,10}, { 191, 9}, \
+ { 383,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271,11}, { 143,10}, { 287, 9}, \
+ { 575,10}, { 303,11}, { 159,10}, { 319, 9}, \
+ { 639,12}, { 95,11}, { 191,10}, { 383,11}, \
+ { 207,13}, { 63,12}, { 127,11}, { 255,10}, \
+ { 511,11}, { 271,10}, { 543, 9}, { 1087,11}, \
+ { 287,10}, { 575, 9}, { 1151,11}, { 303,10}, \
+ { 607,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 335,10}, { 671,11}, { 351,10}, { 703,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,10}, \
+ { 831,12}, { 223,11}, { 447,10}, { 895,11}, \
+ { 479,13}, { 127,12}, { 255,11}, { 543,10}, \
+ { 1087,12}, { 287,11}, { 575,10}, { 1151,11}, \
+ { 607,12}, { 319,11}, { 639,10}, { 1279,11}, \
+ { 671,12}, { 351,11}, { 703,13}, { 191,12}, \
+ { 383,11}, { 767,12}, { 415,11}, { 831,10}, \
+ { 1663,12}, { 447,11}, { 895,12}, { 479,14}, \
+ { 127,13}, { 255,12}, { 511,11}, { 1023,12}, \
+ { 543,11}, { 1087,12}, { 575,11}, { 1151,12}, \
+ { 607,13}, { 319,12}, { 639,11}, { 1279,12}, \
+ { 703,11}, { 1407,10}, { 2815,13}, { 383,12}, \
+ { 767,11}, { 1535,12}, { 799,11}, { 1599,12}, \
+ { 831,11}, { 1663,13}, { 447,12}, { 895,11}, \
+ { 1791,12}, { 959,11}, { 1919,10}, { 3839,14}, \
+ { 255,13}, { 511,12}, { 1087,13}, { 575,12}, \
+ { 1215,11}, { 2431,13}, { 639,12}, { 1343,11}, \
+ { 2687,13}, { 703,12}, { 1407,14}, { 383,13}, \
+ { 767,12}, { 1599,13}, { 831,12}, { 1663,13}, \
+ { 895,12}, { 1791,13}, { 959,12}, { 1919,14}, \
+ { 511,13}, { 1087,12}, { 2175,13}, { 1151,12}, \
+ { 2303,13}, { 1215,12}, { 2431,14}, { 639,13}, \
+ { 1279,12}, { 2559,13}, { 1343,12}, { 2687,13}, \
+ { 1407,12}, { 2815,13}, { 1471,14}, { 767,13}, \
+ { 1663,12}, { 3327,13}, { 1727,14}, { 895,13}, \
+ { 1791,12}, { 3583,13}, { 1919,15}, { 511,14}, \
+ { 1023,13}, { 2175,14}, { 1151,13}, { 2431,12}, \
+ { 4863,14}, { 1279,13}, { 2687,14}, { 1407,13}, \
+ { 2943,15}, { 767,14}, { 1535,13}, { 3199,14}, \
+ { 1663,13}, { 3455,14}, { 1791,13}, { 3583,14}, \
+ { 1919,13}, { 3839,16}, { 511,15}, { 1023,14}, \
+ { 2175,13}, { 4479,14}, { 2303,13}, { 4607,14}, \
+ { 2431,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 230
+#define SQR_FFT_THRESHOLD 3264
+
+#define MULLO_BASECASE_THRESHOLD 3
+#define MULLO_DC_THRESHOLD 34
+#define MULLO_MUL_N_THRESHOLD 9174
+
+#define DC_DIV_QR_THRESHOLD 33
+#define DC_DIVAPPR_Q_THRESHOLD 126
+#define DC_BDIV_QR_THRESHOLD 63
+#define DC_BDIV_Q_THRESHOLD 152
+
+#define INV_MULMOD_BNM1_THRESHOLD 54
+#define INV_NEWTON_THRESHOLD 155
+#define INV_APPR_THRESHOLD 125
+
+#define BINV_NEWTON_THRESHOLD 294
+#define REDC_1_TO_REDC_2_THRESHOLD 17
+#define REDC_2_TO_REDC_N_THRESHOLD 115
+
+#define MU_DIV_QR_THRESHOLD 1334
+#define MU_DIVAPPR_Q_THRESHOLD 1334
+#define MUPI_DIV_QR_THRESHOLD 54
+#define MU_BDIV_QR_THRESHOLD 1142
+#define MU_BDIV_Q_THRESHOLD 1470
+
+#define POWM_SEC_TABLE 1,14,62,642,960
+
+#define MATRIX22_STRASSEN_THRESHOLD 14
+#define HGCD_THRESHOLD 126
+#define HGCD_APPR_THRESHOLD 184
+#define HGCD_REDUCE_THRESHOLD 3014
+#define GCD_DC_THRESHOLD 440
+#define GCDEXT_DC_THRESHOLD 386
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 11
+#define GET_STR_PRECOMPUTE_THRESHOLD 17
+#define SET_STR_DC_THRESHOLD 1655
+#define SET_STR_PRECOMPUTE_THRESHOLD 3417
+
+#define FAC_DSC_THRESHOLD 1138
+#define FAC_ODD_THRESHOLD 27
diff --git a/gmp/mpn/powerpc64/mode64/rsh1aors_n.asm b/gmp/mpn/powerpc64/mode64/rsh1aors_n.asm
new file mode 100644
index 0000000000..7f7734bcef
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/rsh1aors_n.asm
@@ -0,0 +1,172 @@
+dnl PowerPC-64 mpn_rsh1add_n, mpn_rsh1sub_n
+
+dnl Copyright 2003, 2005, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 2.9
+C POWER5 ?
+C POWER6 3.5
+C POWER7 2.25
+
+define(`rp', `r3')
+define(`up', `r4')
+define(`vp', `r5')
+define(`n', `r6')
+
+ifdef(`OPERATION_rsh1add_n', `
+ define(`ADDSUBC', `addc')
+ define(`ADDSUBE', `adde')
+ define(INITCY, `addic $1, r1, 0')
+ define(`func', mpn_rsh1add_n)')
+ifdef(`OPERATION_rsh1sub_n', `
+ define(`ADDSUBC', `subfc')
+ define(`ADDSUBE', `subfe')
+ define(INITCY, `addic $1, r1, -1')
+ define(`func', mpn_rsh1sub_n)')
+
+define(`s0', `r9')
+define(`s1', `r7')
+define(`x0', `r0')
+define(`x1', `r12')
+define(`u0', `r8')
+define(`v0', `r10')
+
+
+ASM_START()
+PROLOGUE(func)
+ ld u0, 0(up)
+ ld v0, 0(vp)
+
+ cmpdi cr6, n, 2
+
+ addi r0, n, 1
+ srdi r0, r0, 2
+ mtctr r0 C copy size to count register
+
+ andi. r0, n, 1
+ bne cr0, L(bx1)
+
+L(bx0): ADDSUBC x1, v0, u0
+ ld u0, 8(up)
+ ld v0, 8(vp)
+ ADDSUBE x0, v0, u0
+ ble cr6, L(n2)
+ ld u0, 16(up)
+ ld v0, 16(vp)
+ srdi s0, x1, 1
+ rldicl r11, x1, 0, 63 C return value
+ ADDSUBE x1, v0, u0
+ andi. n, n, 2
+ bne cr0, L(b10)
+L(b00): addi rp, rp, -24
+ b L(lo0)
+L(b10): addi up, up, 16
+ addi vp, vp, 16
+ addi rp, rp, -8
+ b L(lo2)
+
+ ALIGN(16)
+L(bx1): ADDSUBC x0, v0, u0
+ ble cr6, L(n1)
+ ld u0, 8(up)
+ ld v0, 8(vp)
+ ADDSUBE x1, v0, u0
+ ld u0, 16(up)
+ ld v0, 16(vp)
+ srdi s1, x0, 1
+ rldicl r11, x0, 0, 63 C return value
+ ADDSUBE x0, v0, u0
+ andi. n, n, 2
+ bne cr0, L(b11)
+L(b01): addi up, up, 8
+ addi vp, vp, 8
+ addi rp, rp, -16
+ b L(lo1)
+L(b11): addi up, up, 24
+ addi vp, vp, 24
+ bdz L(end)
+
+ ALIGN(32)
+L(top): ld u0, 0(up)
+ ld v0, 0(vp)
+ srdi s0, x1, 1
+ rldimi s1, x1, 63, 0
+ std s1, 0(rp)
+ ADDSUBE x1, v0, u0
+L(lo2): ld u0, 8(up)
+ ld v0, 8(vp)
+ srdi s1, x0, 1
+ rldimi s0, x0, 63, 0
+ std s0, 8(rp)
+ ADDSUBE x0, v0, u0
+L(lo1): ld u0, 16(up)
+ ld v0, 16(vp)
+ srdi s0, x1, 1
+ rldimi s1, x1, 63, 0
+ std s1, 16(rp)
+ ADDSUBE x1, v0, u0
+L(lo0): ld u0, 24(up)
+ ld v0, 24(vp)
+ srdi s1, x0, 1
+ rldimi s0, x0, 63, 0
+ std s0, 24(rp)
+ ADDSUBE x0, v0, u0
+ addi up, up, 32
+ addi vp, vp, 32
+ addi rp, rp, 32
+ bdnz L(top)
+
+L(end): srdi s0, x1, 1
+ rldimi s1, x1, 63, 0
+ std s1, 0(rp)
+L(cj2): srdi s1, x0, 1
+ rldimi s0, x0, 63, 0
+ std s0, 8(rp)
+L(cj1): ADDSUBE x1, x1, x1 C pseudo-depends on x1
+ rldimi s1, x1, 63, 0
+ std s1, 16(rp)
+ mr r3, r11
+ blr
+
+L(n1): srdi s1, x0, 1
+ rldicl r11, x0, 0, 63 C return value
+ ADDSUBE x1, x1, x1 C pseudo-depends on x1
+ rldimi s1, x1, 63, 0
+ std s1, 0(rp)
+ mr r3, r11
+ blr
+
+L(n2): addi rp, rp, -8
+ srdi s0, x1, 1
+ rldicl r11, x1, 0, 63 C return value
+ b L(cj2)
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/mode64/sqr_basecase.asm b/gmp/mpn/powerpc64/mode64/sqr_basecase.asm
new file mode 100644
index 0000000000..e76bb8878d
--- /dev/null
+++ b/gmp/mpn/powerpc64/mode64/sqr_basecase.asm
@@ -0,0 +1,863 @@
+dnl PowerPC-64 mpn_sqr_basecase.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 1999-2001, 2003-2006, 2008, 2010, 2011 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 6-18
+C POWER4/PPC970 8
+C POWER5 8
+C POWER6 16.25
+C POWER7 3.77
+
+C NOTES
+C * This is very crude, cleanup!
+C * Try to reduce the number of needed live registers.
+C * Rewrite for POWER6 to use 8 consecutive muls, not 2 groups of 4. The
+C cost will be more live registers.
+C * Rewrite for POWER7 to use addmul_2 building blocks; this will reduce code
+C size a lot and speed things up perhaps 25%.
+C * Use computed goto in order to compress the code.
+C * Implement a larger final corner.
+C * Schedule callee-saves register saves into other insns. This could save
+C about 5 cycles/call. (We cannot analogously optimise the restores, since
+C the sqr_diag_addlsh1 loop has no wind-down code as currently written.)
+C * Should the alternating std/adde sequences be split? Some pipelines handle
+C adde poorly, and might sequentialise all these instructions.
+C * The sqr_diag_addlsh1 loop was written for POWER6 and its preferences for
+C adjacent integer multiply insns. Except for the multiply insns, the code
+C was not carefully optimised for POWER6 or any other CPU.
+C * Perform cross-jumping in sqr_diag_addlsh1's feed-in code, into the loop.
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+
+define(`rp_outer', `r25')
+define(`up_outer', `r21')
+define(`rp_saved', `r22')
+define(`up_saved', `r23')
+define(`n_saved', `r24')
+
+ASM_START()
+PROLOGUE(mpn_sqr_basecase)
+ cmpdi cr0, n, 2
+ bge cr0, L(ge2)
+ ld r5, 0(up) C n = 1
+ nop
+ mulld r8, r5, r5 C weight 0
+ mulhdu r9, r5, r5 C weight 1
+ std r8, 0(rp)
+ std r9, 8(rp)
+ blr
+ ALIGN(16)
+L(ge2): bgt cr0, L(gt2)
+ ld r0, 0(up) C n = 2
+ nop
+ mulld r8, r0, r0 C u0 * u0
+ mulhdu r9, r0, r0 C u0 * u0
+ ld r6, 8(up)
+ mulld r10, r6, r6 C u1 * u1
+ mulhdu r11, r6, r6 C u1 * u1
+ mulld r4, r6, r0 C u1 * u0
+ mulhdu r5, r6, r0 C u1 * u0
+ addc r4, r4, r4
+ adde r5, r5, r5
+ addze r11, r11
+ addc r9, r9, r4
+ adde r10, r10, r5
+ addze r11, r11
+ std r8, 0(rp)
+ std r9, 8(rp)
+ std r10, 16(rp)
+ std r11, 24(rp)
+ blr
+
+ ALIGN(16)
+L(gt2): std r31, -8(r1)
+ std r30, -16(r1)
+ std r29, -24(r1)
+ std r28, -32(r1)
+ std r27, -40(r1)
+ std r26, -48(r1)
+ std r25, -56(r1)
+ std r24, -64(r1)
+ std r23, -72(r1)
+ std r22, -80(r1)
+ std r21, -88(r1)
+
+ mr rp_saved, rp
+ mr up_saved, up
+ mr n_saved, n
+ mr rp_outer, rp
+ mr up_outer, up
+
+ rldicl. r0, n, 0,62 C r0 = n & 3, set cr0
+ cmpdi cr6, r0, 2
+ addic r7, n, 2 C compute count...
+ srdi r7, r7, 2 C ...for ctr
+ mtctr r7 C copy count into ctr
+ beq- cr0, L(b0)
+ blt- cr6, L(b1)
+ beq- cr6, L(b2)
+
+L(b3): ld r6, 0(up)
+ ld r9, 8(up)
+ ld r27, 16(up)
+ addi up, up, 24
+ li r12, 0 C carry limb
+ bdz L(em3)
+
+ ALIGN(16)
+L(tm3): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r9, 0(up)
+ ld r27, 8(up)
+ adde r0, r0, r12
+ adde r7, r7, r26
+ mulld r26, r9, r6
+ mulhdu r10, r9, r6
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6
+ ld r9, 16(up)
+ ld r27, 24(up)
+ std r0, 8(rp)
+ adde r26, r26, r8
+ std r7, 16(rp)
+ adde r11, r11, r10
+ std r26, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ bdnz L(tm3)
+
+L(em3): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ adde r0, r0, r12
+ adde r7, r7, r26
+ std r0, 8(rp)
+ std r7, 16(rp)
+ addze r8, r8
+ std r8, 24(rp)
+ addi n, n, 2
+ b L(outer_loop)
+
+L(b0): ld r6, 0(up)
+ ld r27, 8(up)
+ mulld r7, r27, r6
+ mulhdu r12, r27, r6
+ std r7, 8(rp)
+ addi rp, rp, 8
+ ld r9, 16(up)
+ ld r27, 24(up)
+ addi up, up, 32
+ bdz L(em0)
+
+ ALIGN(16)
+L(tm0): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r9, 0(up)
+ ld r27, 8(up)
+ adde r0, r0, r12
+ adde r7, r7, r26
+ mulld r26, r9, r6
+ mulhdu r10, r9, r6
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6
+ ld r9, 16(up)
+ ld r27, 24(up)
+ std r0, 8(rp)
+ adde r26, r26, r8
+ std r7, 16(rp)
+ adde r11, r11, r10
+ std r26, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ bdnz L(tm0)
+
+L(em0): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ adde r0, r0, r12
+ adde r7, r7, r26
+ std r0, 8(rp)
+ std r7, 16(rp)
+ addze r8, r8
+ std r8, 24(rp)
+ addi n, n, 2
+ b L(outer_loop_ent_2)
+
+L(b1): ld r6, 0(up)
+ ld r9, 8(up)
+ ld r27, 16(up)
+ mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r12, r27, r6
+ addc r7, r7, r26
+ std r0, 8(rp)
+ std r7, 16(rp)
+ addi rp, rp, 16
+ ld r9, 24(up)
+ ld r27, 32(up)
+ addi up, up, 40
+ bdz L(em1)
+
+ ALIGN(16)
+L(tm1): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r9, 0(up)
+ ld r27, 8(up)
+ adde r0, r0, r12
+ adde r7, r7, r26
+ mulld r26, r9, r6
+ mulhdu r10, r9, r6
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6
+ ld r9, 16(up)
+ ld r27, 24(up)
+ std r0, 8(rp)
+ adde r26, r26, r8
+ std r7, 16(rp)
+ adde r11, r11, r10
+ std r26, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ bdnz L(tm1)
+
+L(em1): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ adde r0, r0, r12
+ adde r7, r7, r26
+ std r0, 8(rp)
+ std r7, 16(rp)
+ addze r8, r8
+ std r8, 24(rp)
+ addi n, n, 2
+ b L(outer_loop_ent_3)
+
+L(b2): addi r7, r7, -1 C FIXME
+ mtctr r7 C FIXME
+ ld r6, 0(up)
+ ld r9, 8(up)
+ ld r27, 16(up)
+ mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r9, 24(up)
+ mulld r11, r9, r6
+ mulhdu r10, r9, r6
+ addc r7, r7, r26
+ adde r11, r11, r8
+ addze r12, r10
+ std r0, 8(rp)
+ std r7, 16(rp)
+ std r11, 24(rp)
+ addi rp, rp, 24
+ ld r9, 32(up)
+ ld r27, 40(up)
+ addi up, up, 48
+ bdz L(em2)
+
+ ALIGN(16)
+L(tm2): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r9, 0(up)
+ ld r27, 8(up)
+ adde r0, r0, r12
+ adde r7, r7, r26
+ mulld r26, r9, r6
+ mulhdu r10, r9, r6
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6
+ ld r9, 16(up)
+ ld r27, 24(up)
+ std r0, 8(rp)
+ adde r26, r26, r8
+ std r7, 16(rp)
+ adde r11, r11, r10
+ std r26, 24(rp)
+ addi up, up, 32
+ std r11, 32(rp)
+ addi rp, rp, 32
+ bdnz L(tm2)
+
+L(em2): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ adde r0, r0, r12
+ adde r7, r7, r26
+ std r0, 8(rp)
+ std r7, 16(rp)
+ addze r8, r8
+ std r8, 24(rp)
+ addi n, n, 2
+ b L(outer_loop_ent_0)
+
+
+L(outer_loop):
+ addi n, n, -1
+ addi up_outer, up_outer, 8
+ addi rp_outer, rp_outer, 16
+
+ mr up, up_outer
+ addi rp, rp_outer, 8
+
+ srdi r0, n, 2
+ mtctr r0
+
+ bdz L(outer_end)
+
+ ld r6, 0(up)
+ ld r9, 8(up)
+ ld r27, 16(up)
+ mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r9, 24(up)
+ ld r28, 0(rp)
+ ld r29, 8(rp)
+ ld r30, 16(rp)
+ mulld r11, r9, r6
+ mulhdu r10, r9, r6
+ addc r7, r7, r26
+ adde r11, r11, r8
+ addze r12, r10
+ addc r0, r0, r28
+ std r0, 0(rp)
+ adde r7, r7, r29
+ std r7, 8(rp)
+ adde r11, r11, r30
+ std r11, 16(rp)
+ addi rp, rp, 24
+ ld r9, 32(up)
+ ld r27, 40(up)
+ addi up, up, 48
+ bdz L(ea1)
+
+ ALIGN(16)
+L(ta1): mulld r0, r9, r6
+ mulhdu r26, r9, r6 C 9
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6 C 27
+ ld r9, 0(up)
+ ld r28, 0(rp)
+ ld r27, 8(up)
+ ld r29, 8(rp)
+ adde r0, r0, r12 C 0 12
+ adde r7, r7, r26 C 5 7
+ mulld r26, r9, r6
+ mulhdu r10, r9, r6 C 9
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6 C 27
+ ld r9, 16(up)
+ ld r30, 16(rp)
+ ld r27, 24(up)
+ ld r31, 24(rp)
+ adde r26, r26, r8 C 8 5
+ adde r11, r11, r10 C 10 11
+ addze r12, r12 C 12
+ addc r0, r0, r28 C 0 28
+ std r0, 0(rp) C 0
+ adde r7, r7, r29 C 7 29
+ std r7, 8(rp) C 7
+ adde r26, r26, r30 C 5 30
+ std r26, 16(rp) C 5
+ adde r11, r11, r31 C 11 31
+ std r11, 24(rp) C 11
+ addi up, up, 32
+ addi rp, rp, 32
+ bdnz L(ta1)
+
+L(ea1): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r28, 0(rp)
+ ld r29, 8(rp)
+ adde r0, r0, r12
+ adde r7, r7, r26
+ addze r8, r8
+ addc r0, r0, r28
+ std r0, 0(rp)
+ adde r7, r7, r29
+ std r7, 8(rp)
+ addze r8, r8
+ std r8, 16(rp)
+
+L(outer_loop_ent_0):
+ addi n, n, -1
+ addi up_outer, up_outer, 8
+ addi rp_outer, rp_outer, 16
+
+ mr up, up_outer
+ addi rp, rp_outer, 8
+
+ srdi r0, n, 2
+ mtctr r0
+
+ ld r6, 0(up)
+ ld r9, 8(up)
+ ld r27, 16(up)
+ ld r28, 0(rp)
+ ld r29, 8(rp)
+ mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ addc r0, r0, r28
+ adde r7, r7, r26
+ addze r12, r8
+ std r0, 0(rp)
+ adde r7, r7, r29
+ std r7, 8(rp)
+ addi rp, rp, 16
+ ld r9, 24(up)
+ ld r27, 32(up)
+ addi up, up, 40
+ bdz L(ea0)
+
+ ALIGN(16)
+L(ta0): mulld r0, r9, r6
+ mulhdu r26, r9, r6 C 9
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6 C 27
+ ld r9, 0(up)
+ ld r28, 0(rp)
+ ld r27, 8(up)
+ ld r29, 8(rp)
+ adde r0, r0, r12 C 0 12
+ adde r7, r7, r26 C 5 7
+ mulld r26, r9, r6
+ mulhdu r10, r9, r6 C 9
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6 C 27
+ ld r9, 16(up)
+ ld r30, 16(rp)
+ ld r27, 24(up)
+ ld r31, 24(rp)
+ adde r26, r26, r8 C 8 5
+ adde r11, r11, r10 C 10 11
+ addze r12, r12 C 12
+ addc r0, r0, r28 C 0 28
+ std r0, 0(rp) C 0
+ adde r7, r7, r29 C 7 29
+ std r7, 8(rp) C 7
+ adde r26, r26, r30 C 5 30
+ std r26, 16(rp) C 5
+ adde r11, r11, r31 C 11 31
+ std r11, 24(rp) C 11
+ addi up, up, 32
+ addi rp, rp, 32
+ bdnz L(ta0)
+
+L(ea0): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r28, 0(rp)
+ ld r29, 8(rp)
+ adde r0, r0, r12
+ adde r7, r7, r26
+ addze r8, r8
+ addc r0, r0, r28
+ std r0, 0(rp)
+ adde r7, r7, r29
+ std r7, 8(rp)
+ addze r8, r8
+ std r8, 16(rp)
+
+L(outer_loop_ent_3):
+ addi n, n, -1
+ addi up_outer, up_outer, 8
+ addi rp_outer, rp_outer, 16
+
+ mr up, up_outer
+ addi rp, rp_outer, 8
+
+ srdi r0, n, 2
+ mtctr r0
+
+ ld r6, 0(up)
+ ld r9, 8(up)
+ ld r28, 0(rp)
+ mulld r0, r9, r6
+ mulhdu r12, r9, r6
+ addc r0, r0, r28
+ std r0, 0(rp)
+ addi rp, rp, 8
+ ld r9, 16(up)
+ ld r27, 24(up)
+ addi up, up, 32
+ bdz L(ea3)
+
+ ALIGN(16)
+L(ta3): mulld r0, r9, r6
+ mulhdu r26, r9, r6 C 9
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6 C 27
+ ld r9, 0(up)
+ ld r28, 0(rp)
+ ld r27, 8(up)
+ ld r29, 8(rp)
+ adde r0, r0, r12 C 0 12
+ adde r7, r7, r26 C 5 7
+ mulld r26, r9, r6
+ mulhdu r10, r9, r6 C 9
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6 C 27
+ ld r9, 16(up)
+ ld r30, 16(rp)
+ ld r27, 24(up)
+ ld r31, 24(rp)
+ adde r26, r26, r8 C 8 5
+ adde r11, r11, r10 C 10 11
+ addze r12, r12 C 12
+ addc r0, r0, r28 C 0 28
+ std r0, 0(rp) C 0
+ adde r7, r7, r29 C 7 29
+ std r7, 8(rp) C 7
+ adde r26, r26, r30 C 5 30
+ std r26, 16(rp) C 5
+ adde r11, r11, r31 C 11 31
+ std r11, 24(rp) C 11
+ addi up, up, 32
+ addi rp, rp, 32
+ bdnz L(ta3)
+
+L(ea3): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r28, 0(rp)
+ ld r29, 8(rp)
+ adde r0, r0, r12
+ adde r7, r7, r26
+ addze r8, r8
+ addc r0, r0, r28
+ std r0, 0(rp)
+ adde r7, r7, r29
+ std r7, 8(rp)
+ addze r8, r8
+ std r8, 16(rp)
+
+
+L(outer_loop_ent_2):
+ addi n, n, -1
+ addi up_outer, up_outer, 8
+ addi rp_outer, rp_outer, 16
+
+ mr up, up_outer
+ addi rp, rp_outer, 8
+
+ srdi r0, n, 2
+ mtctr r0
+
+ addic r0, r0, 0
+ li r12, 0 C cy_limb = 0
+ ld r6, 0(up)
+ ld r9, 8(up)
+ ld r27, 16(up)
+ bdz L(ea2)
+ addi up, up, 24
+
+ ALIGN(16)
+L(ta2): mulld r0, r9, r6
+ mulhdu r26, r9, r6 C 9
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6 C 27
+ ld r9, 0(up)
+ ld r28, 0(rp)
+ ld r27, 8(up)
+ ld r29, 8(rp)
+ adde r0, r0, r12 C 0 12
+ adde r7, r7, r26 C 5 7
+ mulld r26, r9, r6
+ mulhdu r10, r9, r6 C 9
+ mulld r11, r27, r6
+ mulhdu r12, r27, r6 C 27
+ ld r9, 16(up)
+ ld r30, 16(rp)
+ ld r27, 24(up)
+ ld r31, 24(rp)
+ adde r26, r26, r8 C 8 5
+ adde r11, r11, r10 C 10 11
+ addze r12, r12 C 12
+ addc r0, r0, r28 C 0 28
+ std r0, 0(rp) C 0
+ adde r7, r7, r29 C 7 29
+ std r7, 8(rp) C 7
+ adde r26, r26, r30 C 5 30
+ std r26, 16(rp) C 5
+ adde r11, r11, r31 C 11 31
+ std r11, 24(rp) C 11
+ addi up, up, 32
+ addi rp, rp, 32
+ bdnz L(ta2)
+
+L(ea2): mulld r0, r9, r6
+ mulhdu r26, r9, r6
+ mulld r7, r27, r6
+ mulhdu r8, r27, r6
+ ld r28, 0(rp)
+ ld r29, 8(rp)
+ adde r0, r0, r12
+ adde r7, r7, r26
+ addze r8, r8
+ addc r0, r0, r28
+ std r0, 0(rp)
+ adde r7, r7, r29
+ std r7, 8(rp)
+ addze r8, r8
+ std r8, 16(rp)
+
+ b L(outer_loop)
+
+L(outer_end):
+ ld r6, 0(up)
+ ld r9, 8(up)
+ ld r11, 0(rp)
+ mulld r0, r9, r6
+ mulhdu r8, r9, r6
+ addc r0, r0, r11
+ std r0, 0(rp)
+ addze r8, r8
+ std r8, 8(rp)
+
+define(`rp', `rp_saved')
+define(`up', `r5')
+define(`n', `r6')
+define(`climb', `r0')
+
+ addi r4, rp_saved, 8
+ mr r5, up_saved
+ mr r6, n_saved
+
+ rldicl. r0, n, 0,62 C r0 = n & 3, set cr0
+ cmpdi cr6, r0, 2
+ addi n, n, 2 C compute count...
+ srdi n, n, 2 C ...for ctr
+ mtctr n C put loop count into ctr
+ beq cr0, L(xb0)
+ blt cr6, L(xb1)
+ beq cr6, L(xb2)
+
+L(xb3): ld r6, 0(up)
+ ld r7, 8(up)
+ ld r12, 16(up)
+ addi up, up, 24
+ mulld r24, r6, r6
+ mulhdu r25, r6, r6
+ mulld r26, r7, r7
+ mulhdu r27, r7, r7
+ mulld r28, r12, r12
+ mulhdu r29, r12, r12
+ ld r10, 8(rp)
+ ld r11, 16(rp)
+ ld r6, 24(rp)
+ ld r7, 32(rp)
+ addc r10, r10, r10
+ adde r11, r11, r11
+ adde r6, r6, r6
+ adde r7, r7, r7
+ addze climb, r29
+ addc r10, r10, r25
+ adde r11, r11, r26
+ adde r6, r6, r27
+ adde r7, r7, r28
+ std r24, 0(rp)
+ std r10, 8(rp)
+ std r11, 16(rp)
+ std r6, 24(rp)
+ std r7, 32(rp)
+ addi rp, rp, 40
+ bdnz L(top)
+ b L(end)
+
+L(xb2): ld r6, 0(up)
+ ld r7, 8(up)
+ addi up, up, 16
+ mulld r24, r6, r6
+ mulhdu r25, r6, r6
+ mulld r26, r7, r7
+ mulhdu r27, r7, r7
+ ld r10, 8(rp)
+ ld r11, 16(rp)
+ addc r10, r10, r10
+ adde r11, r11, r11
+ addze climb, r27
+ addc r10, r10, r25
+ adde r11, r11, r26
+ std r24, 0(rp)
+ std r10, 8(rp)
+ std r11, 16(rp)
+ addi rp, rp, 24
+ bdnz L(top)
+ b L(end)
+
+L(xb0): ld r6, 0(up)
+ ld r7, 8(up)
+ ld r12, 16(up)
+ ld r23, 24(up)
+ addi up, up, 32
+ mulld r24, r6, r6
+ mulhdu r25, r6, r6
+ mulld r26, r7, r7
+ mulhdu r27, r7, r7
+ mulld r28, r12, r12
+ mulhdu r29, r12, r12
+ mulld r30, r23, r23
+ mulhdu r31, r23, r23
+ ld r10, 8(rp)
+ ld r11, 16(rp)
+ ld r6, 24(rp)
+ ld r7, 32(rp)
+ ld r12, 40(rp)
+ ld r23, 48(rp)
+ addc r10, r10, r10
+ adde r11, r11, r11
+ adde r6, r6, r6
+ adde r7, r7, r7
+ adde r12, r12, r12
+ adde r23, r23, r23
+ addze climb, r31
+ std r24, 0(rp)
+ addc r10, r10, r25
+ std r10, 8(rp)
+ adde r11, r11, r26
+ std r11, 16(rp)
+ adde r6, r6, r27
+ std r6, 24(rp)
+ adde r7, r7, r28
+ std r7, 32(rp)
+ adde r12, r12, r29
+ std r12, 40(rp)
+ adde r23, r23, r30
+ std r23, 48(rp)
+ addi rp, rp, 56
+ bdnz L(top)
+ b L(end)
+
+L(xb1): ld r6, 0(up)
+ addi up, up, 8
+ mulld r24, r6, r6
+ mulhdu climb, r6, r6
+ std r24, 0(rp)
+ addic rp, rp, 8 C clear carry as side-effect
+
+ ALIGN(32)
+L(top): ld r6, 0(up)
+ ld r7, 8(up)
+ ld r12, 16(up)
+ ld r23, 24(up)
+ addi up, up, 32
+ mulld r24, r6, r6
+ mulhdu r25, r6, r6
+ mulld r26, r7, r7
+ mulhdu r27, r7, r7
+ mulld r28, r12, r12
+ mulhdu r29, r12, r12
+ mulld r30, r23, r23
+ mulhdu r31, r23, r23
+ ld r8, 0(rp)
+ ld r9, 8(rp)
+ adde r8, r8, r8
+ adde r9, r9, r9
+ ld r10, 16(rp)
+ ld r11, 24(rp)
+ adde r10, r10, r10
+ adde r11, r11, r11
+ ld r6, 32(rp)
+ ld r7, 40(rp)
+ adde r6, r6, r6
+ adde r7, r7, r7
+ ld r12, 48(rp)
+ ld r23, 56(rp)
+ adde r12, r12, r12
+ adde r23, r23, r23
+ addze r31, r31
+ addc r8, r8, climb
+ std r8, 0(rp)
+ adde r9, r9, r24
+ std r9, 8(rp)
+ adde r10, r10, r25
+ std r10, 16(rp)
+ adde r11, r11, r26
+ std r11, 24(rp)
+ adde r6, r6, r27
+ std r6, 32(rp)
+ adde r7, r7, r28
+ std r7, 40(rp)
+ adde r12, r12, r29
+ std r12, 48(rp)
+ adde r23, r23, r30
+ std r23, 56(rp)
+ mr climb, r31
+ addi rp, rp, 64
+ bdnz L(top)
+
+L(end): addze climb, climb
+ std climb, 0(rp)
+
+ ld r31, -8(r1)
+ ld r30, -16(r1)
+ ld r29, -24(r1)
+ ld r28, -32(r1)
+ ld r27, -40(r1)
+ ld r26, -48(r1)
+ ld r25, -56(r1)
+ ld r24, -64(r1)
+ ld r23, -72(r1)
+ ld r22, -80(r1)
+ ld r21, -88(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/p6/lshift.asm b/gmp/mpn/powerpc64/p6/lshift.asm
new file mode 100644
index 0000000000..1a200fb346
--- /dev/null
+++ b/gmp/mpn/powerpc64/p6/lshift.asm
@@ -0,0 +1,132 @@
+dnl PowerPC-64 mpn_lshift -- rp[] = up[] << cnt
+
+dnl Copyright 2003, 2005, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 2.25
+C POWER6 4
+
+C TODO
+C * Micro-optimise header code
+C * Perhaps do 4-way unrolling, for 2.5 c/l on POWER6. The code is 4236
+C bytes, 4-way code would become about 50% larger.
+
+C INPUT PARAMETERS
+define(`rp_param', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`cnt', `r6')
+
+define(`tnc',`r0')
+define(`retval',`r3')
+define(`rp', `r7')
+
+ASM_START()
+PROLOGUE(mpn_lshift,toc)
+
+ifdef(`HAVE_ABI_mode32',`
+ rldicl n, n, 0,32 C FIXME: avoid this zero extend
+')
+ mflr r12
+ sldi r8, n, 3
+ sldi r10, cnt, 6 C multiply cnt by size of a SHIFT block
+ LEAL( r11, L(e1)) C address of L(e1) label in SHIFT(1)
+ add up, up, r8 C make up point at end of up[]
+ add r11, r11, r10 C address of L(oN) for N = cnt
+ srdi r10, n, 1
+ add rp, rp_param, r8 C make rp point at end of rp[]
+ subfic tnc, cnt, 64
+ rlwinm. r8, n, 0,31,31 C extract bit 0
+ mtctr r10
+ beq L(evn)
+
+L(odd): ld r9, -8(up)
+ cmpdi cr0, n, 1 C n = 1?
+ beq L(1)
+ ld r8, -16(up)
+ addi r11, r11, -84 C L(o1) - L(e1) - 64
+ mtlr r11
+ srd r3, r9, tnc C retval
+ addi up, up, 8
+ addi rp, rp, -8
+ blr C branch to L(oN)
+
+L(evn): ld r8, -8(up)
+ ld r9, -16(up)
+ addi r11, r11, -64
+ mtlr r11
+ srd r3, r8, tnc C retval
+ blr C branch to L(eN)
+
+L(1): srd r3, r9, tnc C retval
+ sld r8, r9, cnt
+ std r8, -8(rp)
+ mtlr r12
+ifdef(`HAVE_ABI_mode32',
+` mr r4, r3
+ srdi r3, r3, 32
+')
+ blr
+
+
+define(SHIFT,`
+L(lo$1):ld r8, -24(up)
+ std r11, -8(rp)
+ addi rp, rp, -16
+L(o$1): srdi r10, r8, eval(64-$1)
+ rldimi r10, r9, $1, 0
+ ld r9, -32(up)
+ addi up, up, -16
+ std r10, 0(rp)
+L(e$1): srdi r11, r9, eval(64-$1)
+ rldimi r11, r8, $1, 0
+ bdnz L(lo$1)
+ std r11, -8(rp)
+ sldi r10, r9, $1
+ b L(com)
+ nop
+ nop
+')
+
+ ALIGN(64)
+forloop(`i',1,63,`SHIFT(i)')
+
+L(com): std r10, -16(rp)
+ mtlr r12
+ifdef(`HAVE_ABI_mode32',
+` mr r4, r3
+ srdi r3, r3, 32
+')
+ blr
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/powerpc64/p6/lshiftc.asm b/gmp/mpn/powerpc64/p6/lshiftc.asm
new file mode 100644
index 0000000000..e4b3caaab8
--- /dev/null
+++ b/gmp/mpn/powerpc64/p6/lshiftc.asm
@@ -0,0 +1,136 @@
+dnl PowerPC-64 mpn_lshiftc -- rp[] = ~up[] << cnt
+
+dnl Copyright 2003, 2005, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 2.25
+C POWER6 4
+
+C TODO
+C * Micro-optimise header code
+C * Perhaps do 4-way unrolling, for 2.5 c/l on POWER6. The code is 4236
+C bytes, 4-way code would become about 50% larger.
+
+C INPUT PARAMETERS
+define(`rp_param', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`cnt', `r6')
+
+define(`tnc',`r0')
+define(`retval',`r3')
+define(`rp', `r7')
+
+ASM_START()
+PROLOGUE(mpn_lshiftc,toc)
+
+ifdef(`HAVE_ABI_mode32',`
+ rldicl n, n, 0,32 C FIXME: avoid this zero extend
+')
+ mflr r12
+ sldi r8, n, 3
+ sldi r10, cnt, 6 C multiply cnt by size of a SHIFT block
+ LEAL( r11, L(e1)) C address of L(e1) label in SHIFT(1)
+ add up, up, r8 C make up point at end of up[]
+ add r11, r11, r10 C address of L(oN) for N = cnt
+ srdi r10, n, 1
+ add rp, rp_param, r8 C make rp point at end of rp[]
+ subfic tnc, cnt, 64
+ rlwinm. r8, n, 0,31,31 C extract bit 0
+ mtctr r10
+ beq L(evn)
+
+L(odd): ld r9, -8(up)
+ cmpdi cr0, n, 1 C n = 1?
+ beq L(1)
+ ld r8, -16(up)
+ addi r11, r11, -88 C L(o1) - L(e1) - 64
+ mtlr r11
+ srd r3, r9, tnc C retval
+ addi up, up, 8
+ addi rp, rp, -8
+ blr C branch to L(oN)
+
+L(evn): ld r8, -8(up)
+ ld r9, -16(up)
+ addi r11, r11, -64
+ mtlr r11
+ srd r3, r8, tnc C retval
+ blr C branch to L(eN)
+
+L(1): srd r3, r9, tnc C retval
+ sld r8, r9, cnt
+ nor r8, r8, r8
+ std r8, -8(rp)
+ mtlr r12
+ifdef(`HAVE_ABI_mode32',
+` mr r4, r3
+ srdi r3, r3, 32
+')
+ blr
+
+
+define(SHIFT,`
+L(lo$1):ld r8, -24(up)
+ nor r11, r11, r11
+ std r11, -8(rp)
+ addi rp, rp, -16
+L(o$1): srdi r10, r8, eval(64-$1)
+ rldimi r10, r9, $1, 0
+ ld r9, -32(up)
+ addi up, up, -16
+ nor r10, r10, r10
+ std r10, 0(rp)
+L(e$1): srdi r11, r9, eval(64-$1)
+ rldimi r11, r8, $1, 0
+ bdnz L(lo$1)
+ sldi r10, r9, $1
+ b L(com)
+ nop
+')
+
+ ALIGN(64)
+forloop(`i',1,63,`SHIFT(i)')
+
+L(com): nor r11, r11, r11
+ nor r10, r10, r10
+ std r11, -8(rp)
+ std r10, -16(rp)
+ mtlr r12
+ifdef(`HAVE_ABI_mode32',
+` mr r4, r3
+ srdi r3, r3, 32
+')
+ blr
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/powerpc64/p6/rshift.asm b/gmp/mpn/powerpc64/p6/rshift.asm
new file mode 100644
index 0000000000..9e848c1fc7
--- /dev/null
+++ b/gmp/mpn/powerpc64/p6/rshift.asm
@@ -0,0 +1,131 @@
+dnl PowerPC-64 mpn_rshift -- rp[] = up[] << cnt
+
+dnl Copyright 2003, 2005, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 2
+C POWER6 3.5 (mysteriously 3.0 for cnt=1)
+
+C TODO
+C * Micro-optimise header code
+C * Perhaps do 4-way unrolling, for 2.5 c/l on POWER6. The code is 4248
+C bytes, 4-way code would become about 50% larger.
+
+C INPUT PARAMETERS
+define(`rp_param', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`cnt', `r6')
+
+define(`tnc',`r0')
+define(`retval',`r3')
+define(`rp', `r7')
+
+ASM_START()
+PROLOGUE(mpn_rshift,toc)
+
+ifdef(`HAVE_ABI_mode32',`
+ rldicl n, n, 0,32 C FIXME: avoid this zero extend
+')
+ mflr r12
+ LEAL( r11, L(e1)) C address of L(e1) label in SHIFT(1)
+ sldi r10, cnt, 6 C multiply cnt by size of a SHIFT block
+ add r11, r11, r10 C address of L(oN) for N = cnt
+ srdi r10, n, 1
+ mr rp, rp_param
+ subfic tnc, cnt, 64
+ rlwinm. r8, n, 0,31,31 C extract bit 0
+ mtctr r10
+ beq L(evn)
+
+L(odd): ld r9, 0(up)
+ cmpdi cr0, n, 1 C n = 1?
+ beq L(1)
+ ld r8, 8(up)
+ addi r11, r11, -84 C L(o1) - L(e1) - 64
+ mtlr r11
+ sld r3, r9, tnc C retval
+ addi up, up, 8
+ addi rp, rp, 8
+ blr C branch to L(oN)
+
+L(evn): ld r8, 0(up)
+ ld r9, 8(up)
+ addi r11, r11, -64
+ mtlr r11
+ sld r3, r8, tnc C retval
+ addi up, up, 16
+ blr C branch to L(eN)
+
+L(1): sld r3, r9, tnc C retval
+ srd r8, r9, cnt
+ std r8, 0(rp)
+ mtlr r12
+ifdef(`HAVE_ABI_mode32',
+` mr r4, r3
+ srdi r3, r3, 32
+')
+ blr
+
+
+define(SHIFT,`
+L(lo$1):ld r8, 0(up)
+ std r11, 0(rp)
+ addi rp, rp, 16
+L(o$1): srdi r10, r9, $1
+ rldimi r10, r8, eval(64-$1), 0
+ ld r9, 8(up)
+ addi up, up, 16
+ std r10, -8(rp)
+L(e$1): srdi r11, r8, $1
+ rldimi r11, r9, eval(64-$1), 0
+ bdnz L(lo$1)
+ std r11, 0(rp)
+ srdi r10, r9, $1
+ b L(com)
+ nop
+ nop
+')
+
+ ALIGN(64)
+forloop(`i',1,63,`SHIFT(i)')
+
+L(com): std r10, 8(rp)
+ mtlr r12
+ifdef(`HAVE_ABI_mode32',
+` mr r4, r3
+ srdi r3, r3, 32
+')
+ blr
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/powerpc64/p7/copyd.asm b/gmp/mpn/powerpc64/p7/copyd.asm
new file mode 100644
index 0000000000..f04ca586e8
--- /dev/null
+++ b/gmp/mpn/powerpc64/p7/copyd.asm
@@ -0,0 +1,128 @@
+dnl PowerPC-64 mpn_copyd.
+
+dnl Copyright 2004, 2005, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 ?
+C POWER6 1.25
+C POWER7 1.09
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+
+ifdef(`HAVE_ABI_mode32',
+` rldicl n, n, 0,32')
+
+ sldi r0, n, 3
+ add up, up, r0 C point at u[] end
+ add rp, rp, r0 C point at r[] end
+
+ cmpdi cr0, n, 4
+ blt L(sml)
+
+ addi r10, n, 4
+ srdi r10, r10, 3
+ mtctr r10
+
+ andi. r0, n, 1
+ rlwinm r11, n, 0,30,30
+ rlwinm r12, n, 0,29,29
+ cmpdi cr6, r11, 0
+ cmpdi cr7, r12, 0
+
+ beq cr0, L(xx0)
+L(xx1): ld r6, -8(up)
+ addi up, up, -8
+ std r6, -8(rp)
+ addi rp, rp, -8
+
+L(xx0): bne cr6, L(x10)
+L(x00): ld r6, -8(up)
+ ld r7, -16(up)
+ bne cr7, L(100)
+L(000): addi rp, rp, 32
+ b L(lo0)
+L(100): addi up, up, 32
+ b L(lo4)
+L(x10): ld r8, -8(up)
+ ld r9, -16(up)
+ bne cr7, L(110)
+L(010): addi up, up, -16
+ addi rp, rp, 16
+ b L(lo2)
+L(110): addi up, up, 16
+ addi rp, rp, 48
+ b L(lo6)
+
+L(sml): cmpdi cr0, n, 0
+ beqlr- cr0
+ mtctr n
+L(t): ld r6, -8(up)
+ addi up, up, -8
+ std r6, -8(rp)
+ addi rp, rp, -8
+ bdnz L(t)
+ blr
+
+ ALIGN(32)
+L(top): std r6, -8(rp)
+ std r7, -16(rp)
+L(lo2): ld r6, -8(up)
+ ld r7, -16(up)
+ std r8, -24(rp)
+ std r9, -32(rp)
+L(lo0): ld r8, -24(up)
+ ld r9, -32(up)
+ std r6, -40(rp)
+ std r7, -48(rp)
+L(lo6): ld r6, -40(up)
+ ld r7, -48(up)
+ std r8, -56(rp)
+ std r9, -64(rp)
+ addi rp, rp, -64
+L(lo4): ld r8, -56(up)
+ ld r9, -64(up)
+ addi up, up, -64
+ bdnz L(top)
+
+L(end): std r6, -8(rp)
+ std r7, -16(rp)
+ std r8, -24(rp)
+ std r9, -32(rp)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/p7/copyi.asm b/gmp/mpn/powerpc64/p7/copyi.asm
new file mode 100644
index 0000000000..854cf9f809
--- /dev/null
+++ b/gmp/mpn/powerpc64/p7/copyi.asm
@@ -0,0 +1,129 @@
+dnl PowerPC-64 mpn_copyi.
+
+dnl Copyright 2004, 2005, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 ?
+C POWER6 1.25
+C POWER7 1.09
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+
+C TODO
+C * Try rolling the two loop leading std to the end, allowing the code to
+C handle also n = 2.
+C * Consider using 4 pointers, schedule ptr update early wrt use.
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+
+ifdef(`HAVE_ABI_mode32',
+` rldicl n, n, 0,32')
+
+ cmpdi cr0, n, 4
+ blt L(sml)
+
+ addi r10, n, 4
+ srdi r10, r10, 3
+ mtctr r10
+
+ andi. r0, n, 1
+ rlwinm r11, n, 0,30,30
+ rlwinm r12, n, 0,29,29
+ cmpdi cr6, r11, 0
+ cmpdi cr7, r12, 0
+
+ beq cr0, L(xx0)
+L(xx1): ld r6, 0(up)
+ addi up, up, 8
+ std r6, 0(rp)
+ addi rp, rp, 8
+
+L(xx0): bne cr6, L(x10)
+L(x00): ld r6, 0(up)
+ ld r7, 8(up)
+ bne cr7, L(100)
+L(000): addi rp, rp, -32
+ b L(lo0)
+L(100): addi up, up, -32
+ b L(lo4)
+L(x10): ld r8, 0(up)
+ ld r9, 8(up)
+ bne cr7, L(110)
+L(010): addi up, up, 16
+ addi rp, rp, -16
+ b L(lo2)
+L(110): addi up, up, -16
+ addi rp, rp, -48
+ b L(lo6)
+
+L(sml): cmpdi cr0, n, 0
+ beqlr- cr0
+ mtctr n
+L(t): ld r6, 0(up)
+ addi up, up, 8
+ std r6, 0(rp)
+ addi rp, rp, 8
+ bdnz L(t)
+ blr
+
+ ALIGN(32)
+L(top): std r6, 0(rp)
+ std r7, 8(rp)
+L(lo2): ld r6, 0(up)
+ ld r7, 8(up)
+ std r8, 16(rp)
+ std r9, 24(rp)
+L(lo0): ld r8, 16(up)
+ ld r9, 24(up)
+ std r6, 32(rp)
+ std r7, 40(rp)
+L(lo6): ld r6, 32(up)
+ ld r7, 40(up)
+ std r8, 48(rp)
+ std r9, 56(rp)
+ addi rp, rp, 64
+L(lo4): ld r8, 48(up)
+ ld r9, 56(up)
+ addi up, up, 64
+ bdnz L(top)
+
+L(end): std r6, 0(rp)
+ std r7, 8(rp)
+ std r8, 16(rp)
+ std r9, 24(rp)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/p7/hamdist.asm b/gmp/mpn/powerpc64/p7/hamdist.asm
new file mode 100644
index 0000000000..5af98946f7
--- /dev/null
+++ b/gmp/mpn/powerpc64/p7/hamdist.asm
@@ -0,0 +1,110 @@
+dnl PowerPC-64 mpn_hamdist.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 -
+C POWER4/PPC970 -
+C POWER5 -
+C POWER6 -
+C POWER7 2.87
+
+define(`up', r3)
+define(`vp', r4)
+define(`n', r5)
+
+ASM_START()
+PROLOGUE(mpn_hamdist)
+ std r30, -16(r1)
+ std r31, -8(r1)
+
+ addi r0, n, 1
+ifdef(`HAVE_ABI_mode32',
+` rldicl r0, r0, 63,33', C ...branch count
+` srdi r0, r0, 1') C ...for ctr
+ mtctr r0
+
+ andi. r0, n, 1
+
+ li r0, 0
+ li r12, 0
+
+ beq L(evn)
+
+L(odd): ld r6, 0(up)
+ addi up, up, 8
+ ld r8, 0(vp)
+ addi vp, vp, 8
+ xor r10, r6, r8
+ popcntd r0, r10
+ bdz L(e1)
+
+L(evn): ld r6, 0(up)
+ ld r8, 0(vp)
+ ld r7, 8(up)
+ ld r9, 8(vp)
+ xor r10, r6, r8
+ addi up, up, 16
+ addi vp, vp, 16
+ li r30, 0
+ li r31, 0
+ bdz L(end)
+
+ nop
+ nop
+C ALIGN(16)
+L(top): add r0, r0, r30
+ ld r6, 0(up)
+ ld r8, 0(vp)
+ xor r11, r7, r9
+ popcntd r30, r10
+ add r12, r12, r31
+ ld r7, 8(up)
+ ld r9, 8(vp)
+ xor r10, r6, r8
+ popcntd r31, r11
+ addi up, up, 16
+ addi vp, vp, 16
+ bdnz L(top)
+
+L(end): add r0, r0, r30
+ xor r11, r7, r9
+ popcntd r30, r10
+ add r12, r12, r31
+ popcntd r31, r11
+
+ add r0, r0, r30
+ add r12, r12, r31
+L(e1): add r3, r0, r12
+ ld r30, -16(r1)
+ ld r31, -8(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/p7/popcount.asm b/gmp/mpn/powerpc64/p7/popcount.asm
new file mode 100644
index 0000000000..eac72a6493
--- /dev/null
+++ b/gmp/mpn/powerpc64/p7/popcount.asm
@@ -0,0 +1,90 @@
+dnl PowerPC-64 mpn_popcount.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 -
+C POWER4/PPC970 -
+C POWER5 -
+C POWER6 -
+C POWER7 2
+
+define(`up', r3)
+define(`n', r4)
+
+ASM_START()
+PROLOGUE(mpn_popcount)
+ addi r0, n, 1
+ifdef(`HAVE_ABI_mode32',
+` rldicl r0, r0, 63,33', C ...branch count
+` srdi r0, r0, 1') C ...for ctr
+ mtctr r0
+
+ andi. r0, n, 1
+
+ li r0, 0
+ li r12, 0
+ beq L(evn)
+
+L(odd): ld r4, 0(up)
+ addi up, up, 8
+ popcntd r0, r4
+ bdz L(e1)
+
+L(evn): ld r4, 0(up)
+ ld r5, 8(up)
+ popcntd r8, r4
+ popcntd r9, r5
+ bdz L(e2)
+
+ ld r4, 16(up)
+ ld r5, 24(up)
+ bdz L(e4)
+ addi up, up, 32
+
+L(top): add r0, r0, r8
+ popcntd r8, r4
+ ld r4, 0(up)
+ add r12, r12, r9
+ popcntd r9, r5
+ ld r5, 8(up)
+ addi up, up, 16
+ bdnz L(top)
+
+L(e4): add r0, r0, r8
+ popcntd r8, r4
+ add r12, r12, r9
+ popcntd r9, r5
+L(e2): add r0, r0, r8
+ add r12, r12, r9
+L(e1): add r3, r0, r12
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/rshift.asm b/gmp/mpn/powerpc64/rshift.asm
new file mode 100644
index 0000000000..7654a16ae8
--- /dev/null
+++ b/gmp/mpn/powerpc64/rshift.asm
@@ -0,0 +1,207 @@
+dnl PowerPC-64 mpn_rshift -- rp[] = up[] >> cnt
+
+dnl Copyright 2003, 2005, 2010, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 ?
+C POWER4/PPC970 ?
+C POWER5 2.25
+C POWER6 9.75
+C POWER7 2.15
+
+C TODO
+C * Try to reduce the number of needed live registers
+C * Micro-optimise header code
+C * Keep in synch with lshift.asm and lshiftc.asm
+
+C INPUT PARAMETERS
+define(`rp', `r3')
+define(`up', `r4')
+define(`n', `r5')
+define(`cnt', `r6')
+
+define(`tnc',`r0')
+define(`u0',`r30')
+define(`u1',`r31')
+define(`retval',`r5')
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ std r31, -8(r1)
+ std r30, -16(r1)
+ subfic tnc, cnt, 64
+C sldi r30, n, 3 C byte count corresponding to n
+C add rp, rp, r30 C rp = rp + n
+C add up, up, r30 C up = up + n
+ rldicl. r30, n, 0,62 C r30 = n & 3, set cr0
+ cmpdi cr6, r30, 2
+ addi r31, n, 3 C compute count...
+ ld r10, 0(up) C load 1st limb for b00...b11
+ sld retval, r10, tnc
+ifdef(`HAVE_ABI_mode32',
+` rldicl r31, r31, 62,34', C ...branch count
+` srdi r31, r31, 2') C ...for ctr
+ mtctr r31 C copy count into ctr
+ beq cr0, L(b00)
+ blt cr6, L(b01)
+ ld r11, 8(up) C load 2nd limb for b10 and b11
+ beq cr6, L(b10)
+
+ ALIGN(16)
+L(b11): srd r8, r10, cnt
+ sld r9, r11, tnc
+ ld u1, 16(up)
+ addi up, up, 24
+ srd r12, r11, cnt
+ sld r7, u1, tnc
+ addi rp, rp, -16
+ bdnz L(gt3)
+
+ or r11, r8, r9
+ srd r8, u1, cnt
+ b L(cj3)
+
+ ALIGN(16)
+L(gt3): ld u0, 0(up)
+ or r11, r8, r9
+ srd r8, u1, cnt
+ sld r9, u0, tnc
+ ld u1, 8(up)
+ or r10, r12, r7
+ b L(L11)
+
+ ALIGN(32)
+L(b10): srd r12, r10, cnt
+ addi rp, rp, -24
+ sld r7, r11, tnc
+ bdnz L(gt2)
+
+ srd r8, r11, cnt
+ or r10, r12, r7
+ b L(cj2)
+
+L(gt2): ld u0, 16(up)
+ srd r8, r11, cnt
+ sld r9, u0, tnc
+ ld u1, 24(up)
+ or r10, r12, r7
+ srd r12, u0, cnt
+ sld r7, u1, tnc
+ ld u0, 32(up)
+ or r11, r8, r9
+ addi up, up, 16
+ b L(L10)
+
+ ALIGN(16)
+L(b00): ld u1, 8(up)
+ srd r12, r10, cnt
+ sld r7, u1, tnc
+ ld u0, 16(up)
+ srd r8, u1, cnt
+ sld r9, u0, tnc
+ ld u1, 24(up)
+ or r10, r12, r7
+ srd r12, u0, cnt
+ sld r7, u1, tnc
+ addi rp, rp, -8
+ bdz L(cj4)
+
+L(gt4): addi up, up, 32
+ ld u0, 0(up)
+ or r11, r8, r9
+ b L(L00)
+
+ ALIGN(16)
+L(b01): bdnz L(gt1)
+ srd r8, r10, cnt
+ std r8, 0(rp)
+ b L(ret)
+
+L(gt1): ld u0, 8(up)
+ srd r8, r10, cnt
+ sld r9, u0, tnc
+ ld u1, 16(up)
+ srd r12, u0, cnt
+ sld r7, u1, tnc
+ ld u0, 24(up)
+ or r11, r8, r9
+ srd r8, u1, cnt
+ sld r9, u0, tnc
+ ld u1, 32(up)
+ addi up, up, 40
+ or r10, r12, r7
+ bdz L(end)
+
+ ALIGN(32)
+L(top): srd r12, u0, cnt
+ sld r7, u1, tnc
+ ld u0, 0(up)
+ std r11, 0(rp)
+ or r11, r8, r9
+L(L00): srd r8, u1, cnt
+ sld r9, u0, tnc
+ ld u1, 8(up)
+ std r10, 8(rp)
+ or r10, r12, r7
+L(L11): srd r12, u0, cnt
+ sld r7, u1, tnc
+ ld u0, 16(up)
+ std r11, 16(rp)
+ or r11, r8, r9
+L(L10): srd r8, u1, cnt
+ sld r9, u0, tnc
+ ld u1, 24(up)
+ addi up, up, 32
+ std r10, 24(rp)
+ addi rp, rp, 32
+ or r10, r12, r7
+ bdnz L(top)
+
+ ALIGN(32)
+L(end): srd r12, u0, cnt
+ sld r7, u1, tnc
+ std r11, 0(rp)
+L(cj4): or r11, r8, r9
+ srd r8, u1, cnt
+ std r10, 8(rp)
+L(cj3): or r10, r12, r7
+ std r11, 16(rp)
+L(cj2): std r10, 24(rp)
+ std r8, 32(rp)
+
+L(ret): ld r31, -8(r1)
+ ld r30, -16(r1)
+ifdef(`HAVE_ABI_mode32',
+` srdi r3, retval, 32
+ mr r4, retval
+',` mr r3, retval')
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/sec_tabselect.asm b/gmp/mpn/powerpc64/sec_tabselect.asm
new file mode 100644
index 0000000000..085577ca9b
--- /dev/null
+++ b/gmp/mpn/powerpc64/sec_tabselect.asm
@@ -0,0 +1,147 @@
+dnl PowerPC-64 mpn_sec_tabselect.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C POWER3/PPC630 1.75
+C POWER4/PPC970 2.0
+C POWER5 ?
+C POWER6 5.0
+C POWER7 1.75
+
+define(`rp', `r3')
+define(`tp', `r4')
+define(`n', `r5')
+define(`nents', `r6')
+define(`which', `r7')
+
+define(`i', `r8')
+define(`j', `r9')
+define(`stride', `r12')
+define(`mask', `r11')
+
+
+ASM_START()
+PROLOGUE(mpn_sec_tabselect)
+ addic. j, n, -4 C outer loop induction variable
+ std r31, -8(r1)
+ std r30, -16(r1)
+ std r29, -24(r1)
+ std r28, -32(r1)
+ std r27, -40(r1)
+ sldi stride, n, 3
+
+ blt cr0, L(outer_end)
+L(outer_top):
+ mtctr nents
+ mr r10, tp
+ li r28, 0
+ li r29, 0
+ li r30, 0
+ li r31, 0
+ addic. j, j, -4 C outer loop induction variable
+ mr i, which
+
+ ALIGN(16)
+L(top): addic i, i, -1 C set carry iff i != 0
+ subfe mask, mask, mask
+ ld r0, 0(tp)
+ ld r27, 8(tp)
+ and r0, r0, mask
+ and r27, r27, mask
+ or r28, r28, r0
+ or r29, r29, r27
+ ld r0, 16(tp)
+ ld r27, 24(tp)
+ and r0, r0, mask
+ and r27, r27, mask
+ or r30, r30, r0
+ or r31, r31, r27
+ add tp, tp, stride
+ bdnz L(top)
+
+ std r28, 0(rp)
+ std r29, 8(rp)
+ std r30, 16(rp)
+ std r31, 24(rp)
+ addi tp, r10, 32
+ addi rp, rp, 32
+ bge cr0, L(outer_top)
+L(outer_end):
+
+ rldicl. r0, n, 63, 63
+ beq cr0, L(b0x)
+L(b1x): mtctr nents
+ mr r10, tp
+ li r28, 0
+ li r29, 0
+ mr i, which
+ ALIGN(16)
+L(tp2): addic i, i, -1
+ subfe mask, mask, mask
+ ld r0, 0(tp)
+ ld r27, 8(tp)
+ and r0, r0, mask
+ and r27, r27, mask
+ or r28, r28, r0
+ or r29, r29, r27
+ add tp, tp, stride
+ bdnz L(tp2)
+ std r28, 0(rp)
+ std r29, 8(rp)
+ addi tp, r10, 16
+ addi rp, rp, 16
+
+L(b0x): rldicl. r0, n, 0, 63
+ beq cr0, L(b00)
+L(b01): mtctr nents
+ mr r10, tp
+ li r28, 0
+ mr i, which
+ ALIGN(16)
+L(tp1): addic i, i, -1
+ subfe mask, mask, mask
+ ld r0, 0(tp)
+ and r0, r0, mask
+ or r28, r28, r0
+ add tp, tp, stride
+ bdnz L(tp1)
+ std r28, 0(rp)
+
+L(b00): ld r31, -8(r1)
+ ld r30, -16(r1)
+ ld r29, -24(r1)
+ ld r28, -32(r1)
+ ld r27, -40(r1)
+ blr
+EPILOGUE()
diff --git a/gmp/mpn/powerpc64/umul.asm b/gmp/mpn/powerpc64/umul.asm
new file mode 100644
index 0000000000..7fcc72f18f
--- /dev/null
+++ b/gmp/mpn/powerpc64/umul.asm
@@ -0,0 +1,53 @@
+dnl PowerPC-64 umul_ppmm -- support for longlong.h
+
+dnl Copyright 2000, 2001, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C mp_limb_t mpn_umul_ppmm (mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2);
+C
+
+ASM_START()
+PROLOGUE(mpn_umul_ppmm)
+
+ C r3 lowptr
+ C r4 m1
+ C r5 m2
+
+ mulld r0, r4, r5
+ mulhdu r4, r4, r5
+ std r0, 0(r3)
+ifdef(`HAVE_ABI_mode32',
+` srdi r3, r4, 32
+',` mr r3, r4
+')
+ blr
+
+EPILOGUE(mpn_umul_ppmm)
diff --git a/gmp/mpn/powerpc64/vmx/popcount.asm b/gmp/mpn/powerpc64/vmx/popcount.asm
new file mode 100644
index 0000000000..b95fb88b1a
--- /dev/null
+++ b/gmp/mpn/powerpc64/vmx/popcount.asm
@@ -0,0 +1,230 @@
+dnl PowerPC-32/VMX and PowerPC-64/VMX mpn_popcount.
+
+dnl Copyright 2006, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C 7400,7410 (G4): ?
+C 744x,745x (G4+): 1.125
+C 970 (G5): 2.25
+
+C TODO
+C * Rewrite the awkward huge n outer loop code.
+C * Two lvx, two vperm, and two vxor could make us a similar hamdist.
+C * Compress cnsts table in 64-bit mode, only half the values are needed.
+
+define(`GMP_LIMB_BYTES', eval(GMP_LIMB_BITS/8))
+define(`LIMBS_PER_VR', eval(16/GMP_LIMB_BYTES))
+define(`LIMBS_PER_2VR', eval(32/GMP_LIMB_BYTES))
+
+define(`OPERATION_popcount')
+
+define(`ap', `r3')
+define(`n', `r4')
+
+define(`rtab', `v10')
+define(`cnt4', `v11')
+
+ifelse(GMP_LIMB_BITS,32,`
+ define(`LIMB32',` $1')
+ define(`LIMB64',`')
+',`
+ define(`LIMB32',`')
+ define(`LIMB64',` $1')
+')
+
+C The inner loop handles up to 2^34 bits, i.e., 2^31 64-limbs, due to overflow
+C in vsum4ubs. For large operands, we work in chunks, of size LIMBS_PER_CHUNK.
+define(`LIMBS_PER_CHUNK', 0x1000)
+define(`LIMBS_CHUNK_THRES', 0x1001)
+
+ASM_START()
+PROLOGUE(mpn_popcount,toc)
+ mfspr r10, 256
+ oris r0, r10, 0xfffc C Set VRSAVE bit 0-13
+ mtspr 256, r0
+
+ifdef(`HAVE_ABI_mode32',
+` rldicl n, n, 0, 32') C zero extend n
+
+C Load various constants into vector registers
+ LEAL( r11, cnsts)
+ li r12, 16
+ vspltisb cnt4, 4 C 0x0404...04 used as shift count
+
+ li r7, 160
+ lvx rtab, 0, r11
+
+LIMB64(`lis r0, LIMBS_CHUNK_THRES ')
+LIMB64(`cmpd cr7, n, r0 ')
+
+ lvx v0, 0, ap
+ addi r7, r11, 80
+ rlwinm r6, ap, 2,26,29
+ lvx v8, r7, r6
+ vand v0, v0, v8
+
+LIMB32(`rlwinm r8, ap, 30,30,31 ')
+LIMB64(`rlwinm r8, ap, 29,31,31 ')
+ add n, n, r8 C compensate n for rounded down `ap'
+
+ vxor v1, v1, v1
+ li r8, 0 C grand total count
+
+ vxor v12, v12, v12 C zero total count
+ vxor v13, v13, v13 C zero total count
+
+ addic. n, n, -LIMBS_PER_VR
+ ble L(sum)
+
+ addic. n, n, -LIMBS_PER_VR
+ ble L(lsum)
+
+C For 64-bit machines, handle huge n that would overflow vsum4ubs
+LIMB64(`ble cr7, L(small) ')
+LIMB64(`addis r9, n, -LIMBS_PER_CHUNK ') C remaining n
+LIMB64(`lis n, LIMBS_PER_CHUNK ')
+
+ ALIGN(16)
+L(small):
+LIMB32(`srwi r7, n, 3 ') C loop count corresponding to n
+LIMB64(`srdi r7, n, 2 ') C loop count corresponding to n
+ addi r7, r7, 1
+ mtctr r7 C copy n to count register
+ b L(ent)
+
+ ALIGN(16)
+L(top):
+ lvx v0, 0, ap
+L(ent): lvx v1, r12, ap
+ addi ap, ap, 32
+ vsrb v8, v0, cnt4
+ vsrb v9, v1, cnt4
+ vperm v2, rtab, rtab, v0
+ vperm v3, rtab, rtab, v8
+ vperm v4, rtab, rtab, v1
+ vperm v5, rtab, rtab, v9
+ vaddubm v6, v2, v3
+ vaddubm v7, v4, v5
+ vsum4ubs v12, v6, v12
+ vsum4ubs v13, v7, v13
+ bdnz L(top)
+
+ andi. n, n, eval(LIMBS_PER_2VR-1)
+ beq L(rt)
+
+ lvx v0, 0, ap
+ vxor v1, v1, v1
+ cmpwi n, LIMBS_PER_VR
+ ble L(sum)
+L(lsum):
+ vor v1, v0, v0
+ lvx v0, r12, ap
+L(sum):
+LIMB32(`rlwinm r6, n, 4,26,27 ')
+LIMB64(`rlwinm r6, n, 5,26,26 ')
+ addi r7, r11, 16
+ lvx v8, r7, r6
+ vand v0, v0, v8
+ vsrb v8, v0, cnt4
+ vsrb v9, v1, cnt4
+ vperm v2, rtab, rtab, v0
+ vperm v3, rtab, rtab, v8
+ vperm v4, rtab, rtab, v1
+ vperm v5, rtab, rtab, v9
+ vaddubm v6, v2, v3
+ vaddubm v7, v4, v5
+ vsum4ubs v12, v6, v12
+ vsum4ubs v13, v7, v13
+
+ ALIGN(16)
+L(rt): vadduwm v3, v12, v13
+ li r7, -16 C FIXME: does all ppc32 and ppc64 ABIs
+ stvx v3, r7, r1 C FIXME: ...support storing below sp?
+
+ lwz r7, -16(r1)
+ add r8, r8, r7
+ lwz r7, -12(r1)
+ add r8, r8, r7
+ lwz r7, -8(r1)
+ add r8, r8, r7
+ lwz r7, -4(r1)
+ add r8, r8, r7
+
+C Handle outer loop for huge n. We inherit cr7 and r0 from above.
+LIMB64(`ble cr7, L(ret)
+ vxor v12, v12, v12 C zero total count
+ vxor v13, v13, v13 C zero total count
+ mr n, r9
+ cmpd cr7, n, r0
+ ble cr7, L(2)
+ addis r9, n, -LIMBS_PER_CHUNK C remaining n
+ lis n, LIMBS_PER_CHUNK
+L(2): srdi r7, n, 2 C loop count corresponding to n
+ mtctr r7 C copy n to count register
+ b L(top)
+')
+
+ ALIGN(16)
+L(ret): mr r3, r8
+ mtspr 256, r10
+ blr
+EPILOGUE()
+
+DEF_OBJECT(cnsts,16)
+C Counts for vperm
+ .byte 0x00,0x01,0x01,0x02,0x01,0x02,0x02,0x03
+ .byte 0x01,0x02,0x02,0x03,0x02,0x03,0x03,0x04
+C Masks for high end of number
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+
+ .byte 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00
+ .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ .byte 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00
+C Masks for low end of number
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+
+ .byte 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+
+ .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+
+ .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ .byte 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
+END_OBJECT(cnsts)
+ASM_END()
diff --git a/gmp/mpn/s390_32/README b/gmp/mpn/s390_32/README
new file mode 100644
index 0000000000..59519ba538
--- /dev/null
+++ b/gmp/mpn/s390_32/README
@@ -0,0 +1,37 @@
+All current (2001) S/390 and z/Architecture machines are single-issue,
+but some newer machines have a deep pipeline. Software-pipelining is
+therefore beneficial.
+
+* mpn_add_n, mpn_sub_n: Use code along the lines below. Two-way unrolling
+ would be adequate.
+
+ mp_limb_t
+ mpn_add_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+ {
+ mp_limb_t a, b, r, cy;
+ mp_size_t i;
+ mp_limb_t mm = -1;
+
+ cy = 0;
+ up += n;
+ vp += n;
+ rp += n;
+ i = -n;
+ do
+ {
+ a = up[i];
+ b = vp[i];
+ r = a + b + cy;
+ rp[i] = r;
+ cy = (((a & b) | ((a | b) & (r ^ mm)))) >> 31;
+ i++;
+ }
+ while (i < 0);
+ return cy;
+ }
+
+* mpn_lshift, mpn_rshift: Use SLDL/SRDL, and two-way unrolling.
+
+* mpn_mul_1, mpn_addmul_1, mpn_submul_1: For machines with just signed
+ multiply (MR), use two loops, similar to the corresponding VAX or
+ POWER functions. Handle carry like for mpn_add_n.
diff --git a/gmp/mpn/s390_32/addmul_1.asm b/gmp/mpn/s390_32/addmul_1.asm
new file mode 100644
index 0000000000..97189a8e76
--- /dev/null
+++ b/gmp/mpn/s390_32/addmul_1.asm
@@ -0,0 +1,93 @@
+dnl S/390 mpn_addmul_1 -- Multiply a limb vector with a limb and add the
+dnl result to a second limb vector.
+
+dnl Copyright 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(`rp',2)
+define(`up',3)
+define(`n',4)
+define(`vlimb',5)
+define(`cylimb',7)
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ stm 6,7,24(15)
+ slr cylimb,cylimb # clear cylimb
+ ltr vlimb,vlimb
+ jnl .Loopp
+
+.Loopn: l 1,0(up) # load from u
+ lr 6,1 #
+ mr 0,vlimb # multiply signed
+ alr 0,6 # add vlimb to phi
+ sra 6,31 # make mask
+ nr 6,vlimb # 0 or vlimb
+ alr 0,6 # conditionally add vlimb to phi
+ alr 1,cylimb # add carry limb to plo
+ brc 8+4,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ l 6,0(rp) # load r limb
+ alr 6,1 # add u limb to plo
+ brc 8+4,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ lr cylimb,0 # new cylimb
+ st 6,0(rp) # store
+ la up,4(,up)
+ la rp,4(,rp)
+ brct n,.Loopn
+
+ lr 2,cylimb
+ lm 6,7,24(15)
+ br 14
+
+.Loopp: l 1,0(up) # load from u
+ lr 6,1 #
+ mr 0,vlimb # multiply signed
+ sra 6,31 # make mask
+ nr 6,vlimb # 0 or vlimb
+ alr 0,6 # conditionally add vlimb to phi
+ alr 1,cylimb # add carry limb to plo
+ brc 8+4,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ l 6,0(rp) # load r limb
+ alr 6,1 # add u limb to plo
+ brc 8+4,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ lr cylimb,0 # new cylimb
+ st 6,0(rp) # store
+ la up,4(,up)
+ la rp,4(,rp)
+ brct n,.Loopp
+
+ lr 2,cylimb
+ lm 6,7,24(15)
+ br 14
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/s390_32/copyd.asm b/gmp/mpn/s390_32/copyd.asm
new file mode 100644
index 0000000000..ff252bc1a6
--- /dev/null
+++ b/gmp/mpn/s390_32/copyd.asm
@@ -0,0 +1,145 @@
+dnl S/390-32 mpn_copyd
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C cycles/limb
+C cycles/limb
+C z900 1.65
+C z990 1.125
+C z9 ?
+C z10 ?
+C z196 ?
+
+C FIXME:
+C * Avoid saving/restoring callee-saves registers for n < 3. This could be
+C done by setting rp=r1, up=r2, i=r0 and r3,r4,r5 for clock regs.
+C We could then use r3...r10 in main loop.
+
+C INPUT PARAMETERS
+define(`rp_param', `%r2')
+define(`up_param', `%r3')
+define(`n', `%r4')
+
+define(`rp', `%r8')
+define(`up', `%r9')
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+ stm %r6, %r11, 24(%r15)
+
+ lr %r1, n
+ sll %r1, 2
+ la %r10, 8(n)
+ ahi %r1, -32
+ srl %r10, 3
+ lhi %r11, -32
+
+ la rp, 0(%r1,rp_param) C FIXME use lay on z990 and later
+ la up, 0(%r1,up_param) C FIXME use lay on z990 and later
+
+ lhi %r7, 7
+ nr %r7, n C n mod 8
+ chi %r7, 2
+ jh L(b34567)
+ chi %r7, 1
+ je L(b1)
+ jh L(b2)
+
+L(b0): brct %r10, L(top)
+ j L(end)
+
+L(b1): l %r0, 28(up)
+ ahi up, -4
+ st %r0, 28(rp)
+ ahi rp, -4
+ brct %r10, L(top)
+ j L(end)
+
+L(b2): lm %r0, %r1, 24(up)
+ ahi up, -8
+ stm %r0, %r1, 24(rp)
+ ahi rp, -8
+ brct %r10, L(top)
+ j L(end)
+
+L(b34567):
+ chi %r7, 4
+ jl L(b3)
+ je L(b4)
+ chi %r7, 6
+ je L(b6)
+ jh L(b7)
+
+L(b5): lm %r0, %r4, 12(up)
+ ahi up, -20
+ stm %r0, %r4, 12(rp)
+ ahi rp, -20
+ brct %r10, L(top)
+ j L(end)
+
+L(b3): lm %r0, %r2, 20(up)
+ ahi up, -12
+ stm %r0, %r2, 20(rp)
+ ahi rp, -12
+ brct %r10, L(top)
+ j L(end)
+
+L(b4): lm %r0, %r3, 16(up)
+ ahi up, -16
+ stm %r0, %r3, 16(rp)
+ ahi rp, -16
+ brct %r10, L(top)
+ j L(end)
+
+L(b6): lm %r0, %r5, 8(up)
+ ahi up, -24
+ stm %r0, %r5, 8(rp)
+ ahi rp, -24
+ brct %r10, L(top)
+ j L(end)
+
+L(b7): lm %r0, %r6, 4(up)
+ ahi up, -28
+ stm %r0, %r6, 4(rp)
+ ahi rp, -28
+ brct %r10, L(top)
+ j L(end)
+
+L(top): lm %r0, %r7, 0(up)
+ la up, 0(%r11,up)
+ stm %r0, %r7, 0(rp)
+ la rp, 0(%r11,rp)
+ brct %r10, L(top)
+
+L(end): lm %r6, %r11, 24(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/copyi.asm b/gmp/mpn/s390_32/copyi.asm
new file mode 100644
index 0000000000..1df32f100e
--- /dev/null
+++ b/gmp/mpn/s390_32/copyi.asm
@@ -0,0 +1,69 @@
+dnl S/390-32 mpn_copyi
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 0.75
+C z990 0.375
+C z9 ?
+C z10 ?
+C z196 ?
+
+C NOTE
+C * This is based on GNU libc memcpy which was written by Martin Schwidefsky.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+ ltr %r4, %r4
+ sll %r4, 2
+ je L(rtn)
+ ahi %r4, -1
+ lr %r5, %r4
+ srl %r5, 8
+ ltr %r5, %r5 C < 256 bytes to copy?
+ je L(1)
+
+L(top): mvc 0(256, rp), 0(up)
+ la rp, 256(rp)
+ la up, 256(up)
+ brct %r5, L(top)
+
+L(1): bras %r5, L(2) C make r5 point to mvc insn
+ mvc 0(1, rp), 0(up)
+L(2): ex %r4, 0(%r5) C execute mvc with length ((n-1) mod 256)+1
+L(rtn): br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/esame/addmul_1.asm b/gmp/mpn/s390_32/esame/addmul_1.asm
new file mode 100644
index 0000000000..4375b74ae0
--- /dev/null
+++ b/gmp/mpn/s390_32/esame/addmul_1.asm
@@ -0,0 +1,72 @@
+dnl S/390-32 mpn_addmul_1 for systems with MLR instruction
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 18.5
+C z990 10
+C z9 ?
+C z10 ?
+C z196 ?
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`v0', `%r5')
+
+define(`z', `%r9')
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ stm %r9, %r12, 36(%r15)
+ lhi %r12, 0 C zero index register
+ ahi %r12, 0 C clear carry fla
+ lhi %r11, 0 C clear carry limb
+ lhi z, 0 C clear carry limb
+
+L(top): l %r1, 0(%r12,up)
+ l %r10, 0(%r12,rp)
+ mlr %r0, v0
+ alcr %r1, %r10
+ alcr %r0, z
+ alr %r1, %r11
+ lr %r11, %r0
+ st %r1, 0(%r12,rp)
+ la %r12, 4(%r12)
+ brct n, L(top)
+
+ lhi %r2, 0
+ alcr %r2, %r11
+
+ lm %r9, %r12, 36(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/esame/aors_n.asm b/gmp/mpn/s390_32/esame/aors_n.asm
new file mode 100644
index 0000000000..98b0dbc7b0
--- /dev/null
+++ b/gmp/mpn/s390_32/esame/aors_n.asm
@@ -0,0 +1,137 @@
+dnl S/390-32 mpn_add_n and mpn_sub_n.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 ?
+C z990 2.75-3 (fast for even n, slow for odd n)
+C z9 ?
+C z10 ?
+C z196 ?
+
+C TODO
+C * Optimise for small n
+C * Use r0 and save/restore one less register
+C * Using logops_n's v1 inner loop operand order make the loop about 20%
+C faster, at the expense of highly alignment-dependent performance.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`vp', `%r4')
+define(`n', `%r5')
+
+ifdef(`OPERATION_add_n', `
+ define(ADSB, al)
+ define(ADSBCR, alcr)
+ define(ADSBC, alc)
+ define(RETVAL,`dnl
+ lhi %r2, 0
+ alcr %r2, %r2')
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(ADSB, sl)
+ define(ADSBCR, slbr)
+ define(ADSBC, slb)
+ define(RETVAL,`dnl
+ slbr %r2, %r2
+ lcr %r2, %r2')
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ stm %r6, %r8, 24(%r15)
+
+ ahi n, 3
+ lhi %r7, 3
+ lr %r1, n
+ srl %r1, 2
+ nr %r7, n C n mod 4
+ je L(b1)
+ chi %r7, 2
+ jl L(b2)
+ jne L(b0)
+
+L(b3): lm %r5, %r7, 0(up)
+ la up, 12(up)
+ ADSB %r5, 0(vp)
+ ADSBC %r6, 4(vp)
+ ADSBC %r7, 8(vp)
+ la vp, 12(vp)
+ stm %r5, %r7, 0(rp)
+ la rp, 12(rp)
+ brct %r1, L(top)
+ j L(end)
+
+L(b0): lm %r5, %r8, 0(up) C This redundant insns is no mistake,
+ la up, 16(up) C it is needed to make main loop run
+ ADSB %r5, 0(vp) C fast for n = 0 (mod 4).
+ ADSBC %r6, 4(vp)
+ j L(m0)
+
+L(b1): l %r5, 0(up)
+ la up, 4(up)
+ ADSB %r5, 0(vp)
+ la vp, 4(vp)
+ st %r5, 0(rp)
+ la rp, 4(rp)
+ brct %r1, L(top)
+ j L(end)
+
+L(b2): lm %r5, %r6, 0(up)
+ la up, 8(up)
+ ADSB %r5, 0(vp)
+ ADSBC %r6, 4(vp)
+ la vp, 8(vp)
+ stm %r5, %r6, 0(rp)
+ la rp, 8(rp)
+ brct %r1, L(top)
+ j L(end)
+
+L(top): lm %r5, %r8, 0(up)
+ la up, 16(up)
+ ADSBC %r5, 0(vp)
+ ADSBC %r6, 4(vp)
+L(m0): ADSBC %r7, 8(vp)
+ ADSBC %r8, 12(vp)
+ la vp, 16(vp)
+ stm %r5, %r8, 0(rp)
+ la rp, 16(rp)
+ brct %r1, L(top)
+
+L(end): RETVAL
+ lm %r6, %r8, 24(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/esame/aorslsh1_n.asm b/gmp/mpn/s390_32/esame/aorslsh1_n.asm
new file mode 100644
index 0000000000..f2b222b121
--- /dev/null
+++ b/gmp/mpn/s390_32/esame/aorslsh1_n.asm
@@ -0,0 +1,173 @@
+dnl S/390-32 mpn_addlsh1_n
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 9.25
+C z990 5
+C z9 ?
+C z10 ?
+C z196 ?
+
+C TODO
+C * Optimise for small n
+C * Compute RETVAL for sublsh1_n less stupidly
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`vp', `%r4')
+define(`n', `%r5')
+
+ifdef(`OPERATION_addlsh1_n',`
+ define(ADDSUBC, alr)
+ define(ADDSUBE, alcr)
+ define(INITCY, `lhi %r13, -1')
+ define(RETVAL, `alr %r1, %r13
+ lhi %r2, 2
+ alr %r2, %r1')
+ define(func, mpn_addlsh1_n)
+')
+ifdef(`OPERATION_sublsh1_n',`
+ define(ADDSUBC, slr)
+ define(ADDSUBE, slbr)
+ define(INITCY, `lhi %r13, 0')
+ define(RETVAL, `slr %r1, %r13
+ lhi %r2, 1
+ alr %r2, %r1')
+ define(func, mpn_sublsh1_n)
+')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n)
+
+ASM_START()
+PROLOGUE(func)
+ stm %r6, %r13, 24(%r15)
+
+ la %r0, 3(n)
+ lhi %r7, 3
+ srl %r0, 2
+ nr %r7, n C n mod 4
+ je L(b0)
+ chi %r7, 2
+ jl L(b1)
+ je L(b2)
+
+L(b3): lm %r5, %r7, 0(up)
+ la up, 12(up)
+ lm %r9, %r11, 0(vp)
+ la vp, 12(vp)
+
+ alr %r9, %r9
+ alcr %r10, %r10
+ alcr %r11, %r11
+ slbr %r1, %r1
+
+ ADDSUBC %r5, %r9
+ ADDSUBE %r6, %r10
+ ADDSUBE %r7, %r11
+ slbr %r13, %r13
+
+ stm %r5, %r7, 0(rp)
+ la rp, 12(rp)
+ brct %r0, L(top)
+ j L(end)
+
+L(b0): lhi %r1, -1
+ INITCY
+ j L(top)
+
+L(b1): l %r5, 0(up)
+ la up, 4(up)
+ l %r9, 0(vp)
+ la vp, 4(vp)
+
+ alr %r9, %r9
+ slbr %r1, %r1
+ ADDSUBC %r5, %r9
+ slbr %r13, %r13
+
+ st %r5, 0(rp)
+ la rp, 4(rp)
+ brct %r0, L(top)
+ j L(end)
+
+L(b2): lm %r5, %r6, 0(up)
+ la up, 8(up)
+ lm %r9, %r10, 0(vp)
+ la vp, 8(vp)
+
+ alr %r9, %r9
+ alcr %r10, %r10
+ slbr %r1, %r1
+
+ ADDSUBC %r5, %r9
+ ADDSUBE %r6, %r10
+ slbr %r13, %r13
+
+ stm %r5, %r6, 0(rp)
+ la rp, 8(rp)
+ brct %r0, L(top)
+ j L(end)
+
+L(top): lm %r9, %r12, 0(vp)
+ la vp, 16(vp)
+
+ ahi %r1, 1 C restore carry
+
+ alcr %r9, %r9
+ alcr %r10, %r10
+ alcr %r11, %r11
+ alcr %r12, %r12
+
+ slbr %r1, %r1 C save carry
+
+ lm %r5, %r8, 0(up)
+ la up, 16(up)
+
+ ahi %r13, 1 C restore carry
+
+ ADDSUBE %r5, %r9
+ ADDSUBE %r6, %r10
+ ADDSUBE %r7, %r11
+ ADDSUBE %r8, %r12
+
+ slbr %r13, %r13
+
+ stm %r5, %r8, 0(rp)
+ la rp, 16(rp)
+ brct %r0, L(top)
+
+L(end):
+ RETVAL
+ lm %r6, %r13, 24(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/esame/bdiv_dbm1c.asm b/gmp/mpn/s390_32/esame/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..568a2a44e8
--- /dev/null
+++ b/gmp/mpn/s390_32/esame/bdiv_dbm1c.asm
@@ -0,0 +1,65 @@
+dnl S/390-32 mpn_bdiv_dbm1c for systems with MLR instruction.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 14
+C z990 10
+C z9 ?
+C z10 ?
+C z196 ?
+
+C INPUT PARAMETERS
+define(`qp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`bd', `%r5')
+define(`cy', `%r6')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_bdiv_dbm1c)
+ stm %r6, %r7, 24(%r15)
+ lhi %r7, 0 C zero index register
+
+L(top): l %r1, 0(%r7,up)
+ mlr %r0, bd
+ slr %r6, %r1
+ st %r6, 0(%r7,qp)
+ slbr %r6, %r0
+ la %r7, 4(%r7)
+ brct n, L(top)
+
+ lr %r2, %r6
+ lm %r6, %r7, 24(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/esame/gmp-mparam.h b/gmp/mpn/s390_32/esame/gmp-mparam.h
new file mode 100644
index 0000000000..a805fa1492
--- /dev/null
+++ b/gmp/mpn/s390_32/esame/gmp-mparam.h
@@ -0,0 +1,207 @@
+/* S/390-32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2008-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 4400 MHz IBM z10 running in 32-bit mode */
+/* FFT tuning limit = 15000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.7 */
+
+#define DIVREM_1_NORM_THRESHOLD 3
+#define DIVREM_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1_1P_METHOD 1
+#define MOD_1_NORM_THRESHOLD 4
+#define MOD_1_UNNORM_THRESHOLD 8
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 16
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 8
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 38
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 30
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 3
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 56
+
+#define MUL_TOOM22_THRESHOLD 8
+#define MUL_TOOM33_THRESHOLD 59
+#define MUL_TOOM44_THRESHOLD 88
+#define MUL_TOOM6H_THRESHOLD 125
+#define MUL_TOOM8H_THRESHOLD 169
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 57
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 55
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 57
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 56
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 82
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 14
+#define SQR_TOOM3_THRESHOLD 90
+#define SQR_TOOM4_THRESHOLD 144
+#define SQR_TOOM6_THRESHOLD 196
+#define SQR_TOOM8_THRESHOLD 309
+
+#define MULMID_TOOM42_THRESHOLD 24
+
+#define MULMOD_BNM1_THRESHOLD 12
+#define SQRMOD_BNM1_THRESHOLD 10
+
+#define MUL_FFT_MODF_THRESHOLD 252 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 252, 5}, { 9, 6}, { 5, 5}, { 13, 6}, \
+ { 7, 5}, { 15, 6}, { 13, 7}, { 7, 6}, \
+ { 15, 7}, { 9, 6}, { 19, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 15, 6}, \
+ { 31, 7}, { 19, 8}, { 11, 7}, { 23, 9}, \
+ { 7, 8}, { 15, 7}, { 31, 8}, { 19, 7}, \
+ { 39, 8}, { 27, 9}, { 15, 8}, { 39, 9}, \
+ { 23,10}, { 15, 9}, { 31, 8}, { 63, 9}, \
+ { 39, 8}, { 79, 9}, { 47,10}, { 31, 9}, \
+ { 79,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255,10}, { 79, 8}, { 319, 9}, \
+ { 175, 8}, { 351, 7}, { 703, 6}, { 1407,10}, \
+ { 95, 9}, { 191, 8}, { 383, 9}, { 207, 8}, \
+ { 415, 7}, { 831, 9}, { 223,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 143, 9}, { 287, 8}, \
+ { 575, 9}, { 319,10}, { 175, 9}, { 351, 8}, \
+ { 703, 7}, { 1407,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207, 9}, { 415, 8}, { 831,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 575,11}, \
+ { 159,10}, { 351, 9}, { 703, 8}, { 1407,11}, \
+ { 191,10}, { 415, 9}, { 831,11}, { 223,10}, \
+ { 447, 9}, { 895, 8}, { 1791,10}, { 479, 9}, \
+ { 959,12}, { 127,11}, { 287,10}, { 575,11}, \
+ { 351,10}, { 703, 9}, { 1407,12}, { 191,11}, \
+ { 415,10}, { 831,11}, { 447,10}, { 895, 9}, \
+ { 1791,11}, { 479,10}, { 959,13}, { 127,12}, \
+ { 255,11}, { 575,12}, { 319,11}, { 703,10}, \
+ { 1407,12}, { 383,11}, { 831,12}, { 447,11}, \
+ { 895,10}, { 1791,11}, { 959,10}, { 1919, 9}, \
+ { 3839,13}, { 255,12}, { 575,11}, { 1215,10}, \
+ { 2431,12}, { 703,11}, { 1407,13}, { 383,12}, \
+ { 895,11}, { 1791,12}, { 959,11}, { 1919,10}, \
+ { 3839,14}, { 255,13}, { 511,12}, { 1215,11}, \
+ { 2431,13}, { 639,12}, { 1471,13}, { 895,12}, \
+ { 1919,11}, { 3839,10}, { 7679,14}, { 511,13}, \
+ { 1023,12}, { 2047,13}, { 1151,12}, { 2431,13}, \
+ { 1407,14}, { 767,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 149
+#define MUL_FFT_THRESHOLD 2240
+
+#define SQR_FFT_MODF_THRESHOLD 244 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 244, 5}, { 11, 6}, { 6, 5}, { 13, 6}, \
+ { 7, 5}, { 15, 6}, { 8, 5}, { 17, 6}, \
+ { 11, 5}, { 23, 6}, { 13, 7}, { 7, 6}, \
+ { 16, 7}, { 9, 6}, { 19, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 19, 8}, \
+ { 11, 7}, { 23, 9}, { 7, 8}, { 15, 7}, \
+ { 31, 8}, { 19, 7}, { 39, 8}, { 23, 9}, \
+ { 15, 8}, { 39, 9}, { 23,10}, { 15, 9}, \
+ { 31, 8}, { 63, 9}, { 39, 8}, { 79, 9}, \
+ { 47,10}, { 31, 9}, { 63, 8}, { 127, 9}, \
+ { 71, 8}, { 143, 7}, { 287,10}, { 47,11}, \
+ { 31,10}, { 63, 9}, { 127, 8}, { 255, 9}, \
+ { 143, 8}, { 287,10}, { 79, 9}, { 159, 8}, \
+ { 319, 9}, { 175, 8}, { 351, 7}, { 703, 6}, \
+ { 1407,10}, { 95, 9}, { 191, 8}, { 383,11}, \
+ { 63,10}, { 127, 9}, { 255,10}, { 143, 9}, \
+ { 287, 8}, { 575,10}, { 159, 9}, { 319,10}, \
+ { 175, 9}, { 351, 8}, { 703, 7}, { 1407,11}, \
+ { 95,10}, { 191, 9}, { 383,10}, { 207,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
+ { 287, 9}, { 575,11}, { 159,10}, { 351, 9}, \
+ { 703, 8}, { 1407,11}, { 191,10}, { 415,11}, \
+ { 223,10}, { 447, 9}, { 895, 8}, { 1791,10}, \
+ { 479, 9}, { 959,12}, { 127,11}, { 255,10}, \
+ { 511,11}, { 287,10}, { 575,11}, { 319,10}, \
+ { 639,11}, { 351,10}, { 703, 9}, { 1407,12}, \
+ { 191,11}, { 415,10}, { 831,11}, { 447,10}, \
+ { 895, 9}, { 1791,11}, { 479,13}, { 127,12}, \
+ { 255,11}, { 575,12}, { 319,11}, { 703,10}, \
+ { 1407,12}, { 383,11}, { 831,12}, { 447,11}, \
+ { 895,10}, { 1791,11}, { 959,10}, { 1919,13}, \
+ { 255,12}, { 511,11}, { 1023,12}, { 575,11}, \
+ { 1215,10}, { 2431,12}, { 703,11}, { 1407,13}, \
+ { 383,12}, { 895,11}, { 1791,12}, { 959,11}, \
+ { 1919,14}, { 255,13}, { 511,12}, { 1215,11}, \
+ { 2431,13}, { 639,12}, { 1471,11}, { 2943,10}, \
+ { 5887,13}, { 895,12}, { 1919,11}, { 3839,10}, \
+ { 7679,14}, { 511,13}, { 1023,12}, { 2047,13}, \
+ { 1151,12}, { 2431,13}, { 1407,12}, { 2943,11}, \
+ { 5887,14}, { 767,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 161
+#define SQR_FFT_THRESHOLD 1728
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 33
+#define MULLO_MUL_N_THRESHOLD 4392
+
+#define DC_DIV_QR_THRESHOLD 43
+#define DC_DIVAPPR_Q_THRESHOLD 150
+#define DC_BDIV_QR_THRESHOLD 38
+#define DC_BDIV_Q_THRESHOLD 107
+
+#define INV_MULMOD_BNM1_THRESHOLD 14
+#define INV_NEWTON_THRESHOLD 165
+#define INV_APPR_THRESHOLD 149
+
+#define BINV_NEWTON_THRESHOLD 147
+#define REDC_1_TO_REDC_N_THRESHOLD 43
+
+#define MU_DIV_QR_THRESHOLD 777
+#define MU_DIVAPPR_Q_THRESHOLD 942
+#define MUPI_DIV_QR_THRESHOLD 69
+#define MU_BDIV_QR_THRESHOLD 654
+#define MU_BDIV_Q_THRESHOLD 777
+
+#define POWM_SEC_TABLE 3,32,126,692,1486
+
+#define MATRIX22_STRASSEN_THRESHOLD 17
+#define HGCD_THRESHOLD 103
+#define HGCD_APPR_THRESHOLD 144
+#define HGCD_REDUCE_THRESHOLD 1437
+#define GCD_DC_THRESHOLD 275
+#define GCDEXT_DC_THRESHOLD 206
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 9
+#define GET_STR_PRECOMPUTE_THRESHOLD 20
+#define SET_STR_DC_THRESHOLD 532
+#define SET_STR_PRECOMPUTE_THRESHOLD 999
+
+#define FAC_DSC_THRESHOLD 156
+#define FAC_ODD_THRESHOLD 24
diff --git a/gmp/mpn/s390_32/esame/mul_1.asm b/gmp/mpn/s390_32/esame/mul_1.asm
new file mode 100644
index 0000000000..04be963651
--- /dev/null
+++ b/gmp/mpn/s390_32/esame/mul_1.asm
@@ -0,0 +1,66 @@
+dnl S/390-32 mpn_mul_1 for systems with MLR instruction
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 14
+C z990 9
+C z9 ?
+C z10 ?
+C z196 ?
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`v0', `%r5')
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ stm %r11, %r12, 44(%r15)
+ lhi %r12, 0 C zero index register
+ ahi %r12, 0 C clear carry flag
+ lhi %r11, 0 C clear carry limb
+
+L(top): l %r1, 0(%r12,up)
+ mlr %r0, v0
+ alcr %r1, %r11
+ lr %r11, %r0 C copy high part to carry limb
+ st %r1, 0(%r12,rp)
+ la %r12, 4(%r12)
+ brct n, L(top)
+
+ lhi %r2, 0
+ alcr %r2, %r11
+
+ lm %r11, %r12, 44(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/esame/mul_basecase.asm b/gmp/mpn/s390_32/esame/mul_basecase.asm
new file mode 100644
index 0000000000..2c8138d8d2
--- /dev/null
+++ b/gmp/mpn/s390_32/esame/mul_basecase.asm
@@ -0,0 +1,130 @@
+dnl S/390-32/esame mpn_mul_basecase.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 ?
+C z990 ?
+C z9 ?
+C z10 ?
+C z196 ?
+
+C TODO
+C * Perhaps add special case for un <= 2.
+C * Replace loops by faster code. The mul_1 and addmul_1 loops could be sped
+C up by about 10%.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`un', `%r4')
+define(`vp', `%r5')
+define(`vn', `%r6')
+
+define(`zero', `%r8')
+
+ASM_START()
+PROLOGUE(mpn_mul_basecase)
+ chi un, 2
+ jhe L(ge2)
+
+C un = vn = 1
+ l %r1, 0(vp)
+ ml %r0, 0(up)
+ st %r1, 0(rp)
+ st %r0, 4(rp)
+ br %r14
+
+L(ge2): C jne L(gen)
+
+
+L(gen):
+C mul_1 =======================================================================
+
+ stm %r6, %r12, 24(%r15)
+ lhi zero, 0
+ ahi un, -1
+
+ l %r7, 0(vp)
+ l %r11, 0(up)
+ lhi %r12, 4 C init index register
+ mlr %r10, %r7
+ lr %r9, un
+ st %r11, 0(rp)
+ cr %r15, %r15 C clear carry flag
+
+L(tm): l %r1, 0(%r12,up)
+ mlr %r0, %r7
+ alcr %r1, %r10
+ lr %r10, %r0 C copy high part to carry limb
+ st %r1, 0(%r12,rp)
+ la %r12, 4(%r12)
+ brct %r9, L(tm)
+
+ alcr %r0, zero
+ st %r0, 0(%r12,rp)
+
+C addmul_1 loop ===============================================================
+
+ ahi vn, -1
+ je L(outer_end)
+L(outer_loop):
+
+ la rp, 4(rp) C rp += 1
+ la vp, 4(vp) C up += 1
+ l %r7, 0(vp)
+ l %r11, 0(up)
+ lhi %r12, 4 C init index register
+ mlr %r10, %r7
+ lr %r9, un
+ al %r11, 0(rp)
+ st %r11, 0(rp)
+
+L(tam): l %r1, 0(%r12,up)
+ l %r11, 0(%r12,rp)
+ mlr %r0, %r7
+ alcr %r1, %r11
+ alcr %r0, zero
+ alr %r1, %r10
+ lr %r10, %r0
+ st %r1, 0(%r12,rp)
+ la %r12, 4(%r12)
+ brct %r9, L(tam)
+
+ alcr %r0, zero
+ st %r0, 0(%r12,rp)
+
+ brct vn, L(outer_loop)
+L(outer_end):
+
+ lm %r6, %r12, 24(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/esame/sqr_basecase.asm b/gmp/mpn/s390_32/esame/sqr_basecase.asm
new file mode 100644
index 0000000000..dcc13112bf
--- /dev/null
+++ b/gmp/mpn/s390_32/esame/sqr_basecase.asm
@@ -0,0 +1,203 @@
+dnl S/390-32 mpn_sqr_basecase.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 ?
+C z990 23
+C z9 ?
+C z10 ?
+C z196 ?
+
+C TODO
+C * Clean up.
+C * Stop iterating addmul_1 loop at latest for n = 2, implement longer tail.
+C This will ask for basecase handling of n = 3.
+C * Update counters and pointers more straightforwardly, possibly lowering
+C register usage.
+C * Should we use this allocation-free style for more sqr_basecase asm
+C implementations? The only disadvantage is that it requires R != U.
+C * Replace loops by faster code. The mul_1 and addmul_1 loops could be sped
+C up by about 10%. The sqr_diag_addlsh1 loop could probably be sped up even
+C more.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+
+define(`zero', `%r8')
+define(`rp_saved', `%r9')
+define(`up_saved', `%r13')
+define(`n_saved', `%r14')
+
+ASM_START()
+PROLOGUE(mpn_sqr_basecase)
+ ahi n, -2
+ jhe L(ge2)
+
+C n = 1
+ l %r5, 0(up)
+ mlr %r4, %r5
+ st %r5, 0(rp)
+ st %r4, 4(rp)
+ br %r14
+
+L(ge2): jne L(gen)
+
+C n = 2
+ stm %r6, %r8, 24(%r15)
+ lhi zero, 0
+
+ l %r5, 0(up)
+ mlr %r4, %r5 C u0 * u0
+ l %r1, 4(up)
+ mlr %r0, %r1 C u1 * u1
+ st %r5, 0(rp)
+
+ l %r7, 0(up)
+ ml %r6, 4(up) C u0 * u1
+ alr %r7, %r7
+ alcr %r6, %r6
+ alcr %r0, zero
+
+ alr %r4, %r7
+ alcr %r1, %r6
+ alcr %r0, zero
+ st %r4, 4(rp)
+ st %r1, 8(rp)
+ st %r0, 12(rp)
+
+ lm %r6, %r8, 24(%r15)
+ br %r14
+
+L(gen):
+C mul_1 =======================================================================
+
+ stm %r6, %r14, 24(%r15)
+ lhi zero, 0
+ lr up_saved, up
+ lr rp_saved, rp
+ lr n_saved, n
+
+ l %r6, 0(up)
+ l %r11, 4(up)
+ lhi %r12, 8 C init index register
+ mlr %r10, %r6
+ lr %r5, n
+ st %r11, 4(rp)
+ cr %r15, %r15 C clear carry flag
+
+L(tm): l %r1, 0(%r12,up)
+ mlr %r0, %r6
+ alcr %r1, %r10
+ lr %r10, %r0 C copy high part to carry limb
+ st %r1, 0(%r12,rp)
+ la %r12, 4(%r12)
+ brct %r5, L(tm)
+
+ alcr %r0, zero
+ st %r0, 0(%r12,rp)
+
+C addmul_1 loop ===============================================================
+
+ ahi n, -1
+ je L(outer_end)
+L(outer_loop):
+
+ la rp, 8(rp) C rp += 2
+ la up, 4(up) C up += 1
+ l %r6, 0(up)
+ l %r11, 4(up)
+ lhi %r12, 8 C init index register
+ mlr %r10, %r6
+ lr %r5, n
+ al %r11, 4(rp)
+ st %r11, 4(rp)
+
+L(tam): l %r1, 0(%r12,up)
+ l %r7, 0(%r12,rp)
+ mlr %r0, %r6
+ alcr %r1, %r7
+ alcr %r0, zero
+ alr %r1, %r10
+ lr %r10, %r0
+ st %r1, 0(%r12,rp)
+ la %r12, 4(%r12)
+ brct %r5, L(tam)
+
+ alcr %r0, zero
+ st %r0, 0(%r12,rp)
+
+ brct n, L(outer_loop)
+L(outer_end):
+
+ l %r6, 4(up)
+ l %r1, 8(up)
+ lr %r7, %r0 C Same as: l %r7, 12(,rp)
+ mlr %r0, %r6
+ alr %r1, %r7
+ alcr %r0, zero
+ st %r1, 12(rp)
+ st %r0, 16(rp)
+
+C sqr_dia_addlsh1 ============================================================
+
+define(`up', `up_saved')
+define(`rp', `rp_saved')
+ la n, 1(n_saved)
+
+ l %r1, 0(up)
+ mlr %r0, %r1
+ st %r1, 0(rp)
+C clr %r15, %r15 C clear carry (already clear per above)
+
+L(top): l %r11, 4(up)
+ la up, 4(up)
+ l %r6, 4(rp)
+ l %r7, 8(rp)
+ mlr %r10, %r11
+ alcr %r6, %r6
+ alcr %r7, %r7
+ alcr %r10, zero C propagate carry to high product limb
+ alr %r6, %r0
+ alcr %r7, %r11
+ stm %r6, %r7, 4(rp)
+ la rp, 8(rp)
+ lr %r0, %r10 C copy carry limb
+ brct n, L(top)
+
+ alcr %r0, zero
+ st %r0, 4(rp)
+
+ lm %r6, %r14, 24(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/esame/submul_1.asm b/gmp/mpn/s390_32/esame/submul_1.asm
new file mode 100644
index 0000000000..a71e57e230
--- /dev/null
+++ b/gmp/mpn/s390_32/esame/submul_1.asm
@@ -0,0 +1,70 @@
+dnl S/390-32 mpn_submul_1 for systems with MLR instruction.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 20
+C z990 11
+C z9 ?
+C z10 ?
+C z196 ?
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`v0', `%r5')
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ stm %r9, %r12, 36(%r15)
+ lhi %r12, 0
+ slr %r11, %r11
+
+L(top): l %r1, 0(%r12, up)
+ l %r10, 0(%r12, rp)
+ mlr %r0, v0
+ slbr %r10, %r1
+ slbr %r9, %r9
+ slr %r0, %r9 C conditional incr
+ slr %r10, %r11
+ lr %r11, %r0
+ st %r10, 0(%r12, rp)
+ la %r12, 4(%r12)
+ brct %r4, L(top)
+
+ lr %r2, %r11
+ slbr %r9, %r9
+ slr %r2, %r9
+
+ lm %r9, %r12, 36(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/gmp-mparam.h b/gmp/mpn/s390_32/gmp-mparam.h
new file mode 100644
index 0000000000..1aca74a818
--- /dev/null
+++ b/gmp/mpn/s390_32/gmp-mparam.h
@@ -0,0 +1,138 @@
+/* S/390-32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 770 MHz IBM z900 running in 32-bit mode, using just traditional insns */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 5
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 5
+#define MOD_1N_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 15
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 30
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 19
+#define MUL_TOOM33_THRESHOLD 114
+#define MUL_TOOM44_THRESHOLD 166
+#define MUL_TOOM6H_THRESHOLD 226
+#define MUL_TOOM8H_THRESHOLD 333
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 106
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 122
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 105
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 113
+
+#define SQR_BASECASE_THRESHOLD 7
+#define SQR_TOOM2_THRESHOLD 40
+#define SQR_TOOM3_THRESHOLD 126
+#define SQR_TOOM4_THRESHOLD 192
+#define SQR_TOOM6_THRESHOLD 246
+#define SQR_TOOM8_THRESHOLD 357
+
+#define MULMID_TOOM42_THRESHOLD 28
+
+#define MULMOD_BNM1_THRESHOLD 12
+#define SQRMOD_BNM1_THRESHOLD 18
+
+#define MUL_FFT_MODF_THRESHOLD 244 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 244, 5}, { 13, 6}, { 7, 5}, { 15, 6}, \
+ { 8, 5}, { 17, 6}, { 13, 7}, { 7, 6}, \
+ { 16, 7}, { 9, 6}, { 19, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 19, 8}, \
+ { 11, 7}, { 25, 9}, { 7, 8}, { 15, 7}, \
+ { 33, 8}, { 19, 7}, { 39, 8}, { 23, 7}, \
+ { 47, 8}, { 27, 9}, { 15, 8}, { 39, 9}, \
+ { 23, 8}, { 47,10}, { 15, 9}, { 31, 8}, \
+ { 63, 9}, { 39, 8}, { 79, 9}, { 47,10}, \
+ { 31, 9}, { 63, 8}, { 127, 9}, { 71, 8}, \
+ { 143, 9}, { 79,10}, { 47,11}, { 2048,12}, \
+ { 4096,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 48
+#define MUL_FFT_THRESHOLD 2688
+
+#define SQR_FFT_MODF_THRESHOLD 216 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 216, 5}, { 7, 4}, { 15, 5}, { 17, 6}, \
+ { 13, 7}, { 7, 6}, { 17, 7}, { 9, 6}, \
+ { 20, 7}, { 11, 6}, { 23, 7}, { 13, 8}, \
+ { 7, 7}, { 19, 8}, { 11, 7}, { 25, 9}, \
+ { 7, 8}, { 15, 7}, { 33, 8}, { 19, 7}, \
+ { 39, 8}, { 23, 9}, { 15, 8}, { 39, 9}, \
+ { 23, 8}, { 47,10}, { 15, 9}, { 31, 8}, \
+ { 63, 9}, { 39, 8}, { 79, 9}, { 47,10}, \
+ { 31, 9}, { 63, 8}, { 127, 9}, { 71, 8}, \
+ { 143, 9}, { 79,10}, { 47,11}, { 2048,12}, \
+ { 4096,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 44
+#define SQR_FFT_THRESHOLD 1856
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 61
+#define MULLO_MUL_N_THRESHOLD 5240
+
+#define DC_DIV_QR_THRESHOLD 70
+#define DC_DIVAPPR_Q_THRESHOLD 234
+#define DC_BDIV_QR_THRESHOLD 59
+#define DC_BDIV_Q_THRESHOLD 137
+
+#define INV_MULMOD_BNM1_THRESHOLD 36
+#define INV_NEWTON_THRESHOLD 327
+#define INV_APPR_THRESHOLD 268
+
+#define BINV_NEWTON_THRESHOLD 324
+#define REDC_1_TO_REDC_N_THRESHOLD 63
+
+#define MU_DIV_QR_THRESHOLD 1099
+#define MU_DIVAPPR_Q_THRESHOLD 1360
+#define MUPI_DIV_QR_THRESHOLD 138
+#define MU_BDIV_QR_THRESHOLD 889
+#define MU_BDIV_Q_THRESHOLD 1234
+
+#define MATRIX22_STRASSEN_THRESHOLD 18
+#define HGCD_THRESHOLD 167
+#define GCD_DC_THRESHOLD 518
+#define GCDEXT_DC_THRESHOLD 378
+#define JACOBI_BASE_METHOD 2
+
+#define GET_STR_DC_THRESHOLD 14
+#define GET_STR_PRECOMPUTE_THRESHOLD 25
+#define SET_STR_DC_THRESHOLD 577
+#define SET_STR_PRECOMPUTE_THRESHOLD 1217
diff --git a/gmp/mpn/s390_32/logops_n.asm b/gmp/mpn/s390_32/logops_n.asm
new file mode 100644
index 0000000000..1f2cd2a8f6
--- /dev/null
+++ b/gmp/mpn/s390_32/logops_n.asm
@@ -0,0 +1,295 @@
+dnl S/390-32 logops.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb variant 1 variant 2 variant 3
+C rp!=up rp=up
+C z900 ? ? ? ?
+C z990 2.5 1 2.75 2.75
+C z9 ? ? ?
+C z10 ? ? ?
+C z196 ? ? ?
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`vp', `%r4')
+define(`nn', `%r5')
+
+ifdef(`OPERATION_and_n',`
+ define(`func',`mpn_and_n')
+ define(`VARIANT_1')
+ define(`LOGOPC',`nc')
+ define(`LOGOP',`n')')
+ifdef(`OPERATION_andn_n',`
+ define(`func',`mpn_andn_n')
+ define(`VARIANT_2')
+ define(`LOGOP',`n')')
+ifdef(`OPERATION_nand_n',`
+ define(`func',`mpn_nand_n')
+ define(`VARIANT_3')
+ define(`LOGOP',`n')')
+ifdef(`OPERATION_ior_n',`
+ define(`func',`mpn_ior_n')
+ define(`VARIANT_1')
+ define(`LOGOPC',`oc')
+ define(`LOGOP',`o')')
+ifdef(`OPERATION_iorn_n',`
+ define(`func',`mpn_iorn_n')
+ define(`VARIANT_2')
+ define(`LOGOP',`o')')
+ifdef(`OPERATION_nior_n',`
+ define(`func',`mpn_nior_n')
+ define(`VARIANT_3')
+ define(`LOGOP',`o')')
+ifdef(`OPERATION_xor_n',`
+ define(`func',`mpn_xor_n')
+ define(`VARIANT_1')
+ define(`LOGOPC',`xc')
+ define(`LOGOP',`x')')
+ifdef(`OPERATION_xnor_n',`
+ define(`func',`mpn_xnor_n')
+ define(`VARIANT_2')
+ define(`LOGOP',`x')')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+ASM_START()
+PROLOGUE(func)
+ifdef(`VARIANT_1',`
+ cr rp, up
+ jne L(normal)
+
+ sll nn, 2
+ ahi nn, -1
+ lr %r1, nn
+ srl %r1, 8
+ ltr %r1, %r1 C < 256 bytes to copy?
+ je L(1)
+
+L(tp): LOGOPC 0(256, rp), 0(vp)
+ la rp, 256(rp)
+ la vp, 256(vp)
+ brct %r1, L(tp)
+
+L(1): bras %r1, L(2) C make r1 point to mvc insn
+ LOGOPC 0(1, rp), 0(vp)
+L(2): ex nn, 0(%r1) C execute mvc with length ((nn-1) mod 256)+1
+L(rtn): br %r14
+
+
+L(normal):
+ stm %r6, %r8, 12(%r15)
+ ahi nn, 3
+ lhi %r7, 3
+ lr %r0, nn
+ srl %r0, 2
+ nr %r7, nn C nn mod 4
+ je L(b1)
+ chi %r7, 2
+ jl L(b2)
+ jne L(top)
+
+L(b3): lm %r5, %r7, 0(up)
+ la up, 12(up)
+ LOGOP %r5, 0(vp)
+ LOGOP %r6, 4(vp)
+ LOGOP %r7, 8(vp)
+ stm %r5, %r7, 0(rp)
+ la rp, 12(rp)
+ la vp, 12(vp)
+ j L(mid)
+
+L(b1): l %r5, 0(up)
+ la up, 4(up)
+ LOGOP %r5, 0(vp)
+ st %r5, 0(rp)
+ la rp, 4(rp)
+ la vp, 4(vp)
+ j L(mid)
+
+L(b2): lm %r5, %r6, 0(up)
+ la up, 8(up)
+ LOGOP %r5, 0(vp)
+ LOGOP %r6, 4(vp)
+ stm %r5, %r6, 0(rp)
+ la rp, 8(rp)
+ la vp, 8(vp)
+ j L(mid)
+
+L(top): lm %r5, %r8, 0(up)
+ la up, 16(up)
+ LOGOP %r5, 0(vp)
+ LOGOP %r6, 4(vp)
+ LOGOP %r7, 8(vp)
+ LOGOP %r8, 12(vp)
+ stm %r5, %r8, 0(rp)
+ la rp, 16(rp)
+ la vp, 16(vp)
+L(mid): brct %r0, L(top)
+
+ lm %r6, %r8, 12(%r15)
+ br %r14
+')
+
+ifdef(`VARIANT_2',`
+ stm %r6, %r8, 12(%r15)
+ lhi %r1, -1
+
+ ahi nn, 3
+ lhi %r7, 3
+ lr %r0, nn
+ srl %r0, 2
+ nr %r7, nn C nn mod 4
+ je L(b1)
+ chi %r7, 2
+ jl L(b2)
+ jne L(top)
+
+L(b3): lm %r5, %r7, 0(vp)
+ la vp, 12(vp)
+ xr %r5, %r1
+ xr %r6, %r1
+ xr %r7, %r1
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 4(up)
+ LOGOP %r7, 8(up)
+ stm %r5, %r7, 0(rp)
+ la rp, 12(rp)
+ la up, 12(up)
+ j L(mid)
+
+L(b1): l %r5, 0(vp)
+ la vp, 4(vp)
+ xr %r5, %r1
+ LOGOP %r5, 0(up)
+ st %r5, 0(rp)
+ la rp, 4(rp)
+ la up, 4(up)
+ j L(mid)
+
+L(b2): lm %r5, %r6, 0(vp)
+ la vp, 8(vp)
+ xr %r5, %r1
+ xr %r6, %r1
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 4(up)
+ stm %r5, %r6, 0(rp)
+ la rp, 8(rp)
+ la up, 8(up)
+ j L(mid)
+
+L(top): lm %r5, %r8, 0(vp)
+ la vp, 16(vp)
+ xr %r5, %r1
+ xr %r6, %r1
+ xr %r7, %r1
+ xr %r8, %r1
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 4(up)
+ LOGOP %r7, 8(up)
+ LOGOP %r8, 12(up)
+ la up, 16(up)
+ stm %r5, %r8, 0(rp)
+ la rp, 16(rp)
+L(mid): brct %r0, L(top)
+
+ lm %r6, %r8, 12(%r15)
+ br %r14
+')
+
+ifdef(`VARIANT_3',`
+ stm %r6, %r8, 12(%r15)
+ lhi %r1, -1
+
+ ahi nn, 3
+ lhi %r7, 3
+ lr %r0, nn
+ srl %r0, 2
+ nr %r7, nn C nn mod 4
+ je L(b1)
+ chi %r7, 2
+ jl L(b2)
+ jne L(top)
+
+L(b3): lm %r5, %r7, 0(vp)
+ la vp, 12(vp)
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 4(up)
+ xr %r5, %r1
+ xr %r6, %r1
+ LOGOP %r7, 8(up)
+ xr %r7, %r1
+ stm %r5, %r7, 0(rp)
+ la rp, 12(rp)
+ la up, 12(up)
+ j L(mid)
+
+L(b1): l %r5, 0(vp)
+ la vp, 4(vp)
+ LOGOP %r5, 0(up)
+ xr %r5, %r1
+ st %r5, 0(rp)
+ la rp, 4(rp)
+ la up, 4(up)
+ j L(mid)
+
+L(b2): lm %r5, %r6, 0(vp)
+ la vp, 8(vp)
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 4(up)
+ xr %r5, %r1
+ xr %r6, %r1
+ stm %r5, %r6, 0(rp)
+ la rp, 8(rp)
+ la up, 8(up)
+ j L(mid)
+
+L(top): lm %r5, %r8, 0(vp)
+ la vp, 16(vp)
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 4(up)
+ xr %r5, %r1
+ xr %r6, %r1
+ LOGOP %r7, 8(up)
+ LOGOP %r8, 12(up)
+ xr %r7, %r1
+ xr %r8, %r1
+ stm %r5, %r8, 0(rp)
+ la up, 16(up)
+ la rp, 16(rp)
+L(mid): brct %r0, L(top)
+
+ lm %r6, %r8, 12(%r15)
+ br %r14
+')
+
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/lshift.asm b/gmp/mpn/s390_32/lshift.asm
new file mode 100644
index 0000000000..da7d76e844
--- /dev/null
+++ b/gmp/mpn/s390_32/lshift.asm
@@ -0,0 +1,144 @@
+dnl S/390-32 mpn_lshift.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 6
+C z990 3
+C z9 ?
+C z10 ?
+C z196 ?
+
+C TODO
+C *
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`cnt', `%r5')
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ lr %r1, n
+ sll %r1, 2
+ stm %r6, %r12, 24(%r15)
+ la up, 0(%r1,up) C put up near end of U
+ la rp, 0(%r1,rp) C put rp near end of R
+ ahi up, -20
+ ahi rp, -16
+ lhi %r8, 32
+ sr %r8, cnt
+ l %r12, 16(up)
+ srl %r12, 0(%r8) C return value
+ lhi %r7, 3
+ nr %r7, n
+ srl n, 2
+ je L(b0)
+ chi %r7, 2
+ jl L(b1)
+ je L(b2)
+
+L(b3): l %r10, 16(up)
+ l %r11, 12(up)
+ l %r9, 8(up)
+ ahi up, -8
+ lr %r8, %r11
+ sldl %r10, 0(cnt)
+ sldl %r8, 0(cnt)
+ st %r10, 12(rp)
+ st %r8, 8(rp)
+ ahi rp, -8
+ ltr n, n
+ je L(end)
+ j L(top)
+
+L(b2): l %r10, 16(up)
+ l %r11, 12(up)
+ ahi up, -4
+ sldl %r10, 0(cnt)
+ st %r10, 12(rp)
+ ahi rp, -4
+ ltr n, n
+ je L(end)
+ j L(top)
+
+L(b1): ltr n, n
+ je L(end)
+ j L(top)
+
+L(b0): l %r10,16(up)
+ l %r8, 12(up)
+ l %r6, 8(up)
+ l %r0, 4(up)
+ ahi up, -12
+ lr %r11, %r8
+ lr %r9, %r6
+ lr %r7, %r0
+ sldl %r10,0(cnt)
+ sldl %r8, 0(cnt)
+ sldl %r6, 0(cnt)
+ st %r10, 12(rp)
+ st %r8, 8(rp)
+ st %r6, 4(rp)
+ ahi rp, -12
+ ahi n, -1
+ je L(end)
+
+ ALIGN(8)
+L(top): l %r10, 16(up)
+ l %r8, 12(up)
+ l %r6, 8(up)
+ l %r0, 4(up)
+ l %r1, 0(up)
+ lr %r11, %r8
+ lr %r9, %r6
+ lr %r7, %r0
+ ahi up, -16
+ sldl %r10, 0(cnt)
+ sldl %r8, 0(cnt)
+ sldl %r6, 0(cnt)
+ sldl %r0, 0(cnt)
+ st %r10, 12(rp)
+ st %r8, 8(rp)
+ st %r6, 4(rp)
+ st %r0, 0(rp)
+ ahi rp, -16
+ brct n, L(top)
+
+L(end): l %r10, 16(up)
+ sll %r10, 0(cnt)
+ st %r10, 12(rp)
+
+ lr %r2, %r12
+ lm %r6, %r12, 24(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/lshiftc.asm b/gmp/mpn/s390_32/lshiftc.asm
new file mode 100644
index 0000000000..f601673249
--- /dev/null
+++ b/gmp/mpn/s390_32/lshiftc.asm
@@ -0,0 +1,156 @@
+dnl S/390-32 mpn_lshiftc.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 7
+C z990 3.375
+C z9 ?
+C z10 ?
+C z196 ?
+
+C TODO
+C *
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`cnt', `%r5')
+
+ASM_START()
+PROLOGUE(mpn_lshiftc)
+ lr %r1, n
+ sll %r1, 2
+ stm %r6, %r13, 24(%r15)
+ la up, 0(%r1,up) C put up near end of U
+ la rp, 0(%r1,rp) C put rp near end of R
+ ahi up, -20
+ ahi rp, -16
+ lhi %r8, 32
+ sr %r8, cnt
+ l %r12, 16(up)
+ srl %r12, 0(%r8) C return value
+ lhi %r13, -1
+ lhi %r7, 3
+ nr %r7, n
+ srl n, 2
+ je L(b0)
+ chi %r7, 2
+ jl L(b1)
+ je L(b2)
+
+L(b3): l %r10, 16(up)
+ l %r11, 12(up)
+ l %r9, 8(up)
+ ahi up, -8
+ lr %r8, %r11
+ sldl %r10, 0(cnt)
+ sldl %r8, 0(cnt)
+ xr %r10, %r13
+ xr %r8, %r13
+ st %r10, 12(rp)
+ st %r8, 8(rp)
+ ahi rp, -8
+ ltr n, n
+ je L(end)
+ j L(top)
+
+L(b2): l %r10, 16(up)
+ l %r11, 12(up)
+ ahi up, -4
+ sldl %r10, 0(cnt)
+ xr %r10, %r13
+ st %r10, 12(rp)
+ ahi rp, -4
+ ltr n, n
+ je L(end)
+ j L(top)
+
+L(b1): ltr n, n
+ je L(end)
+ j L(top)
+
+L(b0): l %r10,16(up)
+ l %r8, 12(up)
+ l %r6, 8(up)
+ l %r0, 4(up)
+ ahi up, -12
+ lr %r11, %r8
+ lr %r9, %r6
+ lr %r7, %r0
+ sldl %r10,0(cnt)
+ sldl %r8, 0(cnt)
+ sldl %r6, 0(cnt)
+ xr %r10, %r13
+ xr %r8, %r13
+ xr %r6, %r13
+ st %r10, 12(rp)
+ st %r8, 8(rp)
+ st %r6, 4(rp)
+ ahi rp, -12
+ ahi n, -1
+ je L(end)
+
+ ALIGN(8)
+L(top): l %r10, 16(up)
+ l %r8, 12(up)
+ l %r6, 8(up)
+ l %r0, 4(up)
+ l %r1, 0(up)
+ lr %r11, %r8
+ lr %r9, %r6
+ lr %r7, %r0
+ ahi up, -16
+ sldl %r10, 0(cnt)
+ sldl %r8, 0(cnt)
+ sldl %r6, 0(cnt)
+ sldl %r0, 0(cnt)
+ xr %r10, %r13
+ xr %r8, %r13
+ xr %r6, %r13
+ xr %r0, %r13
+ st %r10, 12(rp)
+ st %r8, 8(rp)
+ st %r6, 4(rp)
+ st %r0, 0(rp)
+ ahi rp, -16
+ brct n, L(top)
+
+L(end): l %r10, 16(up)
+ sll %r10, 0(cnt)
+ xr %r10, %r13
+ st %r10, 12(rp)
+
+ lr %r2, %r12
+ lm %r6, %r13, 24(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/mul_1.asm b/gmp/mpn/s390_32/mul_1.asm
new file mode 100644
index 0000000000..e3ad0c59d8
--- /dev/null
+++ b/gmp/mpn/s390_32/mul_1.asm
@@ -0,0 +1,85 @@
+dnl S/390 mpn_mul_1 -- Multiply a limb vector with a limb and store the
+dnl result in a second limb vector.
+
+dnl Copyright 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(`rp',2)
+define(`up',3)
+define(`n',4)
+define(`vlimb',5)
+define(`cylimb',7)
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ stm 6,7,24(15)
+ slr cylimb,cylimb # clear cylimb
+ ltr vlimb,vlimb
+ jnl .Loopp
+
+.Loopn: l 1,0(up) # load from u
+ lr 6,1 #
+ mr 0,vlimb # multiply signed
+ alr 0,6 # add vlimb to phi
+ sra 6,31 # make mask
+ nr 6,vlimb # 0 or vlimb
+ alr 0,6 # conditionally add vlimb to phi
+ alr 1,cylimb # add carry limb to plo
+ brc 8+4,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ lr cylimb,0 # new cylimb
+ st 1,0(rp) # store
+ la up,4(,up)
+ la rp,4(,rp)
+ brct n,.Loopn
+
+ lr 2,cylimb
+ lm 6,7,24(15)
+ br 14
+
+.Loopp: l 1,0(up) # load from u
+ lr 6,1 #
+ mr 0,vlimb # multiply signed
+ sra 6,31 # make mask
+ nr 6,vlimb # 0 or vlimb
+ alr 0,6 # conditionally add vlimb to phi
+ alr 1,cylimb # add carry limb to plo
+ brc 8+4,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ lr cylimb,0 # new cylimb
+ st 1,0(rp) # store
+ la up,4(,up)
+ la rp,4(,rp)
+ brct n,.Loopp
+
+ lr 2,cylimb
+ lm 6,7,24(15)
+ br 14
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/s390_32/rshift.asm b/gmp/mpn/s390_32/rshift.asm
new file mode 100644
index 0000000000..5f2cf37ca0
--- /dev/null
+++ b/gmp/mpn/s390_32/rshift.asm
@@ -0,0 +1,138 @@
+dnl S/390-32 mpn_rshift.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 6
+C z990 3
+C z9 ?
+C z10 ?
+C z196 ?
+
+C TODO
+C *
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`cnt', `%r5')
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ stm %r6, %r12, 24(%r15)
+ lhi %r8, 32
+ sr %r8, cnt
+ l %r12, 0(up)
+ sll %r12, 0(%r8) C return value
+ lhi %r7, 3
+ nr %r7, n
+ srl n, 2
+ je L(b0)
+ chi %r7, 2
+ jl L(b1)
+ je L(b2)
+
+L(b3): l %r11, 0(up)
+ l %r10, 4(up)
+ l %r8, 8(up)
+ ahi up, 8
+ lr %r9, %r10
+ srdl %r10, 0(cnt)
+ srdl %r8, 0(cnt)
+ st %r11, 0(rp)
+ st %r9, 4(rp)
+ ahi rp, 8
+ ltr n, n
+ je L(end)
+ j L(top)
+
+L(b2): l %r11, 0(up)
+ l %r10, 4(up)
+ ahi up, 4
+ srdl %r10, 0(cnt)
+ st %r11, 0(rp)
+ ahi rp, 4
+ ltr n, n
+ je L(end)
+ j L(top)
+
+L(b1): ltr n, n
+ je L(end)
+ j L(top)
+
+L(b0): l %r11, 0(up)
+ l %r9, 4(up)
+ l %r7, 8(up)
+ l %r1, 12(up)
+ ahi up, 12
+ lr %r10, %r9
+ lr %r8, %r7
+ lr %r6, %r1
+ srdl %r10, 0(cnt)
+ srdl %r8, 0(cnt)
+ srdl %r6, 0(cnt)
+ st %r11, 0(rp)
+ st %r9, 4(rp)
+ st %r7, 8(rp)
+ ahi rp, 12
+ ahi n, -1
+ je L(end)
+
+ ALIGN(8)
+L(top): l %r11, 0(up)
+ l %r9, 4(up)
+ l %r7, 8(up)
+ l %r1, 12(up)
+ l %r0, 16(up)
+ lr %r10, %r9
+ lr %r8, %r7
+ lr %r6, %r1
+ ahi up, 16
+ srdl %r10, 0(cnt)
+ srdl %r8, 0(cnt)
+ srdl %r6, 0(cnt)
+ srdl %r0, 0(cnt)
+ st %r11, 0(rp)
+ st %r9, 4(rp)
+ st %r7, 8(rp)
+ st %r1, 12(rp)
+ ahi rp, 16
+ brct n, L(top)
+
+L(end): l %r11, 0(up)
+ srl %r11, 0(cnt)
+ st %r11, 0(rp)
+
+ lr %r2, %r12
+ lm %r6, %r12, 24(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_32/submul_1.asm b/gmp/mpn/s390_32/submul_1.asm
new file mode 100644
index 0000000000..da7d849d5d
--- /dev/null
+++ b/gmp/mpn/s390_32/submul_1.asm
@@ -0,0 +1,93 @@
+dnl S/390 mpn_submul_1 -- Multiply a limb vector with a limb and subtract the
+dnl result from a second limb vector.
+
+dnl Copyright 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(`rp',2)
+define(`up',3)
+define(`n',4)
+define(`vlimb',5)
+define(`cylimb',7)
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ stm 6,7,24(15)
+ slr cylimb,cylimb # clear cylimb
+ ltr vlimb,vlimb
+ jnl .Loopp
+
+.Loopn: l 1,0(up) # load from u
+ lr 6,1 #
+ mr 0,vlimb # multiply signed
+ alr 0,6 # add vlimb to phi
+ sra 6,31 # make mask
+ nr 6,vlimb # 0 or vlimb
+ alr 0,6 # conditionally add vlimb to phi
+ alr 1,cylimb # add carry limb to plo
+ brc 8+4,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ l 6,0(rp) # load r limb
+ slr 6,1 # add u limb to plo
+ brc 2+1,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ lr cylimb,0 # new cylimb
+ st 6,0(rp) # store
+ la up,4(,up)
+ la rp,4(,rp)
+ brct n,.Loopn
+
+ lr 2,cylimb
+ lm 6,7,24(15)
+ br 14
+
+.Loopp: l 1,0(up) # load from u
+ lr 6,1 #
+ mr 0,vlimb # multiply signed
+ sra 6,31 # make mask
+ nr 6,vlimb # 0 or vlimb
+ alr 0,6 # conditionally add vlimb to phi
+ alr 1,cylimb # add carry limb to plo
+ brc 8+4,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ l 6,0(rp) # load r limb
+ slr 6,1 # add u limb to plo
+ brc 2+1,+8 # branch if not carry
+ ahi 0,1 # increment phi
+ lr cylimb,0 # new cylimb
+ st 6,0(rp) # store
+ la up,4(,up)
+ la rp,4(,rp)
+ brct n,.Loopp
+
+ lr 2,cylimb
+ lm 6,7,24(15)
+ br 14
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/s390_64/README b/gmp/mpn/s390_64/README
new file mode 100644
index 0000000000..8f482a9cd2
--- /dev/null
+++ b/gmp/mpn/s390_64/README
@@ -0,0 +1,88 @@
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+There are 5 generations of 64-but s390 processors, z900, z990, z9,
+z10, and z196. The current GMP code was optimised for the two oldest,
+z900 and z990.
+
+
+mpn_copyi
+
+This code makes use of a loop around MVC. It almost surely runs very
+close to optimally. A small improvement could be done by using one
+MVC for size 256 bytes, now we use two (we use an extra MVC when
+copying any multiple of 256 bytes).
+
+
+mpn_copyd
+
+We have tried several feed-in variants here, branch tree, jump table
+and computed goto. The fastest (on z990) turned out to be computed
+goto.
+
+An approach not tried is EX of LMG and STMG, modifying the register set
+on-the-fly. Using that trick, we could completely avoid using
+separate feed-in paths.
+
+
+mpn_lshift, mpn_rshift
+
+The current code runs at pipeline decode bandwith on z990.
+
+
+mpn_add_n, mpn_sub_n
+
+The current code is 4-way unrolled. It should be unrolled more, at
+least 8x, in order to reach 2.5 c/l.
+
+
+mpn_mul_1, mpn_addmul_1, mpn_submul_1
+
+The current code is very naive, but due to the non-pipelined nature of
+MLGR on z900 and z990, more sophisticated code would not gain much.
+
+On z10 one would need to cluster at least 4 MLGR together, in order to
+reduce stalling.
+
+On z196, one surely want to use unrolling and pipelining, to perhaps
+reach around 12 c/l. A major issue here and on z10 is ALCGR's 3 cycle
+stalling.
+
+
+mpn_mul_2, mpn_addmul_2
+
+At least for older machines (z900, z990) with very slow MLGR, we
+should use Karatsuba's algorithm on 2-limb units, making mul_2 and
+addmul_2 the main multiplication primitives. The newer machines might
+benefit less from this approach, perhaps in particular z10, where MLGR
+clustering is more important.
+
+With Karatsuba, one could hope for around 16 cycles per accumulated
+128 cross product, on z990.
diff --git a/gmp/mpn/s390_64/addmul_1.asm b/gmp/mpn/s390_64/addmul_1.asm
new file mode 100644
index 0000000000..84cca12361
--- /dev/null
+++ b/gmp/mpn/s390_64/addmul_1.asm
@@ -0,0 +1,72 @@
+dnl S/390-64 mpn_addmul_1
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 34
+C z990 23
+C z9 ?
+C z10 28
+C z196 ?
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`v0', `%r5')
+
+define(`z', `%r9')
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ stmg %r9, %r12, 72(%r15)
+ lghi %r12, 0 C zero index register
+ aghi %r12, 0 C clear carry flag
+ lghi %r11, 0 C clear carry limb
+ lghi z, 0 C keep register zero
+
+L(top): lg %r1, 0(%r12,up)
+ lg %r10, 0(%r12,rp)
+ mlgr %r0, v0
+ alcgr %r1, %r10
+ alcgr %r0, z
+ algr %r1, %r11
+ lgr %r11, %r0
+ stg %r1, 0(%r12,rp)
+ la %r12, 8(%r12)
+ brctg n, L(top)
+
+ lghi %r2, 0
+ alcgr %r2, %r11
+
+ lmg %r9, %r12, 72(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/aorrlsh1_n.asm b/gmp/mpn/s390_64/aorrlsh1_n.asm
new file mode 100644
index 0000000000..697259efef
--- /dev/null
+++ b/gmp/mpn/s390_64/aorrlsh1_n.asm
@@ -0,0 +1,168 @@
+dnl S/390-64 mpn_addlsh1_n and mpn_rsblsh1_n.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 9
+C z990 4.75
+C z9 ?
+C z10 11
+C z196 ?
+
+C TODO
+C * Optimise for small n, avoid 'la' like in aors_n.asm.
+C * Tune to reach 3.5 c/l. For addlsh1, we could let the main alcgr propagate
+C carry to the lsh1 alcgr.
+C * Compute RETVAL for sublsh1_n less stupidly.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`vp', `%r4')
+define(`n', `%r5')
+
+ifdef(`OPERATION_addlsh1_n',`
+ define(ADSB, alg)
+ define(ADSBC, alcg)
+ define(INITCY, `lghi %r9, -1')
+ define(RETVAL, `la %r2, 2(%r1,%r9)')
+ define(func, mpn_addlsh1_n)
+')
+ifdef(`OPERATION_rsblsh1_n',`
+ define(ADSB, slg)
+ define(ADSBC, slbg)
+ define(INITCY, `lghi %r9, 0')
+ define(RETVAL,`dnl
+ algr %r1, %r9
+ lghi %r2, 1
+ algr %r2, %r1')
+ define(func, mpn_rsblsh1_n)
+')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_rsblsh1_n)
+
+ASM_START()
+PROLOGUE(func)
+ stmg %r6, %r9, 48(%r15)
+
+ aghi n, 3
+ lghi %r7, 3
+ srlg %r0, n, 2
+ ngr %r7, n C n mod 4
+ je L(b1)
+ cghi %r7, 2
+ jl L(b2)
+ jne L(b0)
+
+L(b3): lmg %r5, %r7, 0(vp)
+ la vp, 24(vp)
+
+ algr %r5, %r5
+ alcgr %r6, %r6
+ alcgr %r7, %r7
+ slbgr %r1, %r1
+
+ ADSB %r5, 0(up)
+ ADSBC %r6, 8(up)
+ ADSBC %r7, 16(up)
+ la up, 24(up)
+ slbgr %r9, %r9
+
+ stmg %r5, %r7, 0(rp)
+ la rp, 24(rp)
+ brctg %r0, L(top)
+ j L(end)
+
+L(b0): lghi %r1, -1
+ INITCY
+ j L(top)
+
+L(b1): lg %r5, 0(vp)
+ la vp, 8(vp)
+
+ algr %r5, %r5
+ slbgr %r1, %r1
+ ADSB %r5, 0(up)
+ la up, 8(up)
+ slbgr %r9, %r9
+
+ stg %r5, 0(rp)
+ la rp, 8(rp)
+ brctg %r0, L(top)
+ j L(end)
+
+L(b2): lmg %r5, %r6, 0(vp)
+ la vp, 16(vp)
+
+ algr %r5, %r5
+ alcgr %r6, %r6
+ slbgr %r1, %r1
+
+ ADSB %r5, 0(up)
+ ADSBC %r6, 8(up)
+ la up, 16(up)
+ slbgr %r9, %r9
+
+ stmg %r5, %r6, 0(rp)
+ la rp, 16(rp)
+ brctg %r0, L(top)
+ j L(end)
+
+L(top): lmg %r5, %r8, 0(vp)
+ la vp, 32(vp)
+
+ aghi %r1, 1 C restore carry
+
+ alcgr %r5, %r5
+ alcgr %r6, %r6
+ alcgr %r7, %r7
+ alcgr %r8, %r8
+
+ slbgr %r1, %r1 C save carry
+
+ aghi %r9, 1 C restore carry
+
+ ADSBC %r5, 0(up)
+ ADSBC %r6, 8(up)
+ ADSBC %r7, 16(up)
+ ADSBC %r8, 24(up)
+ la up, 32(up)
+
+ slbgr %r9, %r9 C save carry
+
+ stmg %r5, %r8, 0(rp)
+ la rp, 32(rp)
+ brctg %r0, L(top)
+
+L(end): RETVAL
+ lmg %r6, %r9, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/aors_n.asm b/gmp/mpn/s390_64/aors_n.asm
new file mode 100644
index 0000000000..a3c3ca791c
--- /dev/null
+++ b/gmp/mpn/s390_64/aors_n.asm
@@ -0,0 +1,136 @@
+dnl S/390-64 mpn_add_n and mpn_sub_n.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 5.5
+C z990 3
+C z9 ?
+C z10 6
+C z196 ?
+
+C TODO
+C * Optimise for small n
+C * Use r0 and save/restore one less register
+C * Using logops_n's v1 inner loop operand order make the loop about 20%
+C faster, at the expense of highly alignment-dependent performance.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`vp', `%r4')
+define(`n', `%r5')
+
+ifdef(`OPERATION_add_n', `
+ define(ADSB, alg)
+ define(ADSBCR, alcgr)
+ define(ADSBC, alcg)
+ define(RETVAL,`dnl
+ lghi %r2, 0
+ alcgr %r2, %r2')
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(ADSB, slg)
+ define(ADSBCR, slbgr)
+ define(ADSBC, slbg)
+ define(RETVAL,`dnl
+ slbgr %r2, %r2
+ lcgr %r2, %r2')
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_sub_n)
+
+ASM_START()
+PROLOGUE(func)
+ stmg %r6, %r8, 48(%r15)
+
+ aghi n, 3
+ lghi %r7, 3
+ srlg %r1, n, 2
+ ngr %r7, n C n mod 4
+ je L(b1)
+ cghi %r7, 2
+ jl L(b2)
+ jne L(b0)
+
+L(b3): lmg %r5, %r7, 0(up)
+ la up, 24(up)
+ ADSB %r5, 0(vp)
+ ADSBC %r6, 8(vp)
+ ADSBC %r7, 16(vp)
+ la vp, 24(vp)
+ stmg %r5, %r7, 0(rp)
+ la rp, 24(rp)
+ brctg %r1, L(top)
+ j L(end)
+
+L(b0): lmg %r5, %r8, 0(up) C This redundant insns is no mistake,
+ la up, 32(up) C it is needed to make main loop run
+ ADSB %r5, 0(vp) C fast for n = 0 (mod 4).
+ ADSBC %r6, 8(vp)
+ j L(m0)
+
+L(b1): lg %r5, 0(up)
+ la up, 8(up)
+ ADSB %r5, 0(vp)
+ la vp, 8(vp)
+ stg %r5, 0(rp)
+ la rp, 8(rp)
+ brctg %r1, L(top)
+ j L(end)
+
+L(b2): lmg %r5, %r6, 0(up)
+ la up, 16(up)
+ ADSB %r5, 0(vp)
+ ADSBC %r6, 8(vp)
+ la vp, 16(vp)
+ stmg %r5, %r6, 0(rp)
+ la rp, 16(rp)
+ brctg %r1, L(top)
+ j L(end)
+
+L(top): lmg %r5, %r8, 0(up)
+ la up, 32(up)
+ ADSBC %r5, 0(vp)
+ ADSBC %r6, 8(vp)
+L(m0): ADSBC %r7, 16(vp)
+ ADSBC %r8, 24(vp)
+ la vp, 32(vp)
+ stmg %r5, %r8, 0(rp)
+ la rp, 32(rp)
+ brctg %r1, L(top)
+
+L(end): RETVAL
+ lmg %r6, %r8, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/bdiv_dbm1c.asm b/gmp/mpn/s390_64/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..35e900a279
--- /dev/null
+++ b/gmp/mpn/s390_64/bdiv_dbm1c.asm
@@ -0,0 +1,65 @@
+dnl S/390-64 mpn_bdiv_dbm1c
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 29
+C z990 22
+C z9 ?
+C z10 19
+C z196 ?
+
+C INPUT PARAMETERS
+define(`qp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`bd', `%r5')
+define(`cy', `%r6')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_bdiv_dbm1c)
+ stmg %r6, %r7, 48(%r15)
+ lghi %r7, 0 C zero index register
+
+L(top): lg %r1, 0(%r7,up)
+ mlgr %r0, bd
+ slgr %r6, %r1
+ stg %r6, 0(%r7,qp)
+ la %r7, 8(%r7)
+ slbgr %r6, %r0
+ brctg n, L(top)
+
+ lgr %r2, %r6
+ lmg %r6, %r7, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/copyd.asm b/gmp/mpn/s390_64/copyd.asm
new file mode 100644
index 0000000000..8631e19f00
--- /dev/null
+++ b/gmp/mpn/s390_64/copyd.asm
@@ -0,0 +1,144 @@
+dnl S/390-64 mpn_copyd
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 2.67
+C z990 1.5
+C z9 ?
+C z10 1.8
+C z196 ?
+
+C FIXME:
+C * Avoid saving/restoring callee-saves registers for n < 3. This could be
+C done by setting rp=r1, up=r2, i=r0 and r3,r4,r5 for clock regs.
+C We could then use r3...r10 in main loop.
+C * Could we use some EX trick, modifying lmg/stmg, for the feed-in code?
+
+C INPUT PARAMETERS
+define(`rp_param', `%r2')
+define(`up_param', `%r3')
+define(`n', `%r4')
+
+define(`rp', `%r8')
+define(`up', `%r9')
+
+ASM_START()
+PROLOGUE(mpn_copyd)
+ stmg %r6, %r11, 48(%r15)
+
+ sllg %r1, n, 3
+ la %r10, 8(n)
+ aghi %r1, -64
+ srlg %r10, %r10, 3
+ lghi %r11, -64
+
+ la rp, 0(%r1,rp_param) C FIXME use lay on z990 and later
+ la up, 0(%r1,up_param) C FIXME use lay on z990 and later
+
+ lghi %r7, 7
+ ngr %r7, n C n mod 8
+ cghi %r7, 2
+ jh L(b34567)
+ cghi %r7, 1
+ je L(b1)
+ jh L(b2)
+
+L(b0): brctg %r10, L(top)
+ j L(end)
+
+L(b1): lg %r0, 56(up)
+ aghi up, -8
+ stg %r0, 56(rp)
+ aghi rp, -8
+ brctg %r10, L(top)
+ j L(end)
+
+L(b2): lmg %r0, %r1, 48(up)
+ aghi up, -16
+ stmg %r0, %r1, 48(rp)
+ aghi rp, -16
+ brctg %r10, L(top)
+ j L(end)
+
+L(b34567):
+ cghi %r7, 4
+ jl L(b3)
+ je L(b4)
+ cghi %r7, 6
+ je L(b6)
+ jh L(b7)
+
+L(b5): lmg %r0, %r4, 24(up)
+ aghi up, -40
+ stmg %r0, %r4, 24(rp)
+ aghi rp, -40
+ brctg %r10, L(top)
+ j L(end)
+
+L(b3): lmg %r0, %r2, 40(up)
+ aghi up, -24
+ stmg %r0, %r2, 40(rp)
+ aghi rp, -24
+ brctg %r10, L(top)
+ j L(end)
+
+L(b4): lmg %r0, %r3, 32(up)
+ aghi up, -32
+ stmg %r0, %r3, 32(rp)
+ aghi rp, -32
+ brctg %r10, L(top)
+ j L(end)
+
+L(b6): lmg %r0, %r5, 16(up)
+ aghi up, -48
+ stmg %r0, %r5, 16(rp)
+ aghi rp, -48
+ brctg %r10, L(top)
+ j L(end)
+
+L(b7): lmg %r0, %r6, 8(up)
+ aghi up, -56
+ stmg %r0, %r6, 8(rp)
+ aghi rp, -56
+ brctg %r10, L(top)
+ j L(end)
+
+L(top): lmg %r0, %r7, 0(up)
+ la up, 0(%r11,up)
+ stmg %r0, %r7, 0(rp)
+ la rp, 0(%r11,rp)
+ brctg %r10, L(top)
+
+L(end): lmg %r6, %r11, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/copyi.asm b/gmp/mpn/s390_64/copyi.asm
new file mode 100644
index 0000000000..bfb88814ea
--- /dev/null
+++ b/gmp/mpn/s390_64/copyi.asm
@@ -0,0 +1,68 @@
+dnl S/390-64 mpn_copyi
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 1.25
+C z990 0.75
+C z9 ?
+C z10 1
+C z196 ?
+
+C NOTE
+C * This is based on GNU libc memcpy which was written by Martin Schwidefsky.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+
+ASM_START()
+PROLOGUE(mpn_copyi)
+ ltgr %r4, %r4
+ sllg %r4, %r4, 3
+ je L(rtn)
+ aghi %r4, -1
+ srlg %r5, %r4, 8
+ ltgr %r5, %r5 C < 256 bytes to copy?
+ je L(1)
+
+L(top): mvc 0(256, rp), 0(up)
+ la rp, 256(rp)
+ la up, 256(up)
+ brctg %r5, L(top)
+
+L(1): bras %r5, L(2) C make r5 point to mvc insn
+ mvc 0(1, rp), 0(up)
+L(2): ex %r4, 0(%r5) C execute mvc with length ((n-1) mod 256)+1
+L(rtn): br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/gmp-mparam.h b/gmp/mpn/s390_64/gmp-mparam.h
new file mode 100644
index 0000000000..dacd9966a4
--- /dev/null
+++ b/gmp/mpn/s390_64/gmp-mparam.h
@@ -0,0 +1,175 @@
+/* S/390-64 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 1200 MHz z990 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 9
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 62
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 17
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 98
+
+#define MUL_TOOM22_THRESHOLD 10
+#define MUL_TOOM33_THRESHOLD 41
+#define MUL_TOOM44_THRESHOLD 105
+#define MUL_TOOM6H_THRESHOLD 149
+#define MUL_TOOM8H_THRESHOLD 212
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 65
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 69
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 72
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 64
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 55
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 16
+#define SQR_TOOM3_THRESHOLD 57
+#define SQR_TOOM4_THRESHOLD 153
+#define SQR_TOOM6_THRESHOLD 204
+#define SQR_TOOM8_THRESHOLD 309
+
+#define MULMID_TOOM42_THRESHOLD 20
+
+#define MULMOD_BNM1_THRESHOLD 10
+#define SQRMOD_BNM1_THRESHOLD 11
+
+#define MUL_FFT_MODF_THRESHOLD 220 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 220, 5}, { 11, 6}, { 6, 5}, { 13, 6}, \
+ { 7, 5}, { 15, 6}, { 13, 7}, { 7, 6}, \
+ { 15, 7}, { 8, 6}, { 17, 7}, { 9, 6}, \
+ { 19, 7}, { 13, 8}, { 7, 7}, { 17, 8}, \
+ { 9, 7}, { 19, 8}, { 13, 9}, { 7, 8}, \
+ { 19, 9}, { 11, 8}, { 23,10}, { 7, 9}, \
+ { 15, 8}, { 33, 9}, { 19, 8}, { 39, 9}, \
+ { 23,10}, { 15, 9}, { 39,10}, { 23,11}, \
+ { 15,10}, { 31, 9}, { 63,10}, { 39, 9}, \
+ { 79,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255,10}, { 71, 9}, { 143, 8}, \
+ { 287,10}, { 79,11}, { 47,12}, { 31,11}, \
+ { 63,10}, { 127, 9}, { 255, 8}, { 511,10}, \
+ { 143, 9}, { 287,11}, { 79,10}, { 159, 9}, \
+ { 319,10}, { 175, 9}, { 351, 8}, { 703, 7}, \
+ { 1407,11}, { 95,10}, { 191, 9}, { 383,10}, \
+ { 207,11}, { 111,10}, { 223,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,11}, { 143,10}, \
+ { 287, 9}, { 575, 8}, { 1151,10}, { 319,11}, \
+ { 175,10}, { 351, 9}, { 703,12}, { 95,11}, \
+ { 191,10}, { 383, 9}, { 767,11}, { 207,10}, \
+ { 415,11}, { 223,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 97
+#define MUL_FFT_THRESHOLD 1728
+
+#define SQR_FFT_MODF_THRESHOLD 212 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 212, 5}, { 7, 4}, { 15, 5}, { 13, 6}, \
+ { 7, 5}, { 15, 6}, { 15, 7}, { 8, 6}, \
+ { 17, 7}, { 13, 8}, { 7, 7}, { 17, 8}, \
+ { 9, 7}, { 19, 8}, { 11, 7}, { 23, 8}, \
+ { 13, 9}, { 7, 8}, { 19, 9}, { 11, 8}, \
+ { 25,10}, { 7, 9}, { 15, 8}, { 31, 9}, \
+ { 19, 8}, { 39, 9}, { 23,10}, { 15, 9}, \
+ { 39,10}, { 23,11}, { 15,10}, { 31, 9}, \
+ { 63,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255,10}, { 71, 9}, { 143, 8}, \
+ { 287,10}, { 79,11}, { 47,12}, { 31,11}, \
+ { 63,10}, { 127, 9}, { 255, 8}, { 511,10}, \
+ { 143, 9}, { 287,11}, { 79,10}, { 159, 9}, \
+ { 319, 8}, { 639,10}, { 175, 9}, { 351, 8}, \
+ { 703,10}, { 191, 9}, { 383, 8}, { 767,10}, \
+ { 207, 9}, { 415,11}, { 111,10}, { 223,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,11}, \
+ { 143,10}, { 287, 9}, { 575, 8}, { 1151,11}, \
+ { 159,10}, { 319,11}, { 175,10}, { 351, 9}, \
+ { 703,11}, { 191,10}, { 383,11}, { 207,10}, \
+ { 415,11}, { 223,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 93
+#define SQR_FFT_THRESHOLD 1600
+
+#define MULLO_BASECASE_THRESHOLD 2
+#define MULLO_DC_THRESHOLD 33
+#define MULLO_MUL_N_THRESHOLD 3176
+
+#define DC_DIV_QR_THRESHOLD 28
+#define DC_DIVAPPR_Q_THRESHOLD 107
+#define DC_BDIV_QR_THRESHOLD 31
+#define DC_BDIV_Q_THRESHOLD 78
+
+#define INV_MULMOD_BNM1_THRESHOLD 43
+#define INV_NEWTON_THRESHOLD 129
+#define INV_APPR_THRESHOLD 117
+
+#define BINV_NEWTON_THRESHOLD 149
+#define REDC_1_TO_REDC_N_THRESHOLD 38
+
+#define MU_DIV_QR_THRESHOLD 748
+#define MU_DIVAPPR_Q_THRESHOLD 748
+#define MUPI_DIV_QR_THRESHOLD 65
+#define MU_BDIV_QR_THRESHOLD 562
+#define MU_BDIV_Q_THRESHOLD 734
+
+#define POWM_SEC_TABLE 4,23,274,961,2783
+
+#define MATRIX22_STRASSEN_THRESHOLD 11
+#define HGCD_THRESHOLD 79
+#define HGCD_APPR_THRESHOLD 70
+#define HGCD_REDUCE_THRESHOLD 1094
+#define GCD_DC_THRESHOLD 183
+#define GCDEXT_DC_THRESHOLD 148
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 30
+#define GET_STR_PRECOMPUTE_THRESHOLD 41
+#define SET_STR_DC_THRESHOLD 402
+#define SET_STR_PRECOMPUTE_THRESHOLD 1104
+
+#define FAC_DSC_THRESHOLD 842
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/s390_64/invert_limb.asm b/gmp/mpn/s390_64/invert_limb.asm
new file mode 100644
index 0000000000..edcebddf1c
--- /dev/null
+++ b/gmp/mpn/s390_64/invert_limb.asm
@@ -0,0 +1,94 @@
+dnl S/390-64 mpn_invert_limb
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 142
+C z990 86
+C z9 ?
+C z10 120
+C z196 ?
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_invert_limb)
+ stg %r9, 72(%r15)
+ srlg %r9, %r2, 55
+ agr %r9, %r9
+ larl %r4, approx_tab-512
+ srlg %r3, %r2, 24
+ aghi %r3, 1
+ lghi %r5, 1
+ llgh %r4, 0(%r9, %r4)
+ sllg %r9, %r4, 11
+ msgr %r4, %r4
+ msgr %r4, %r3
+ srlg %r4, %r4, 40
+ aghi %r9, -1
+ sgr %r9, %r4
+ sllg %r0, %r9, 60
+ sllg %r1, %r9, 13
+ msgr %r9, %r9
+ msgr %r9, %r3
+ sgr %r0, %r9
+ ngr %r5, %r2
+ srlg %r4, %r2, 1
+ srlg %r3, %r0, 47
+ agr %r3, %r1
+ agr %r4, %r5
+ msgr %r4, %r3
+ srlg %r1, %r3, 1
+ lcgr %r5, %r5
+ ngr %r1, %r5
+ sgr %r1, %r4
+ mlgr %r0, %r3
+ srlg %r9, %r0, 1
+ sllg %r4, %r3, 31
+ agr %r4, %r9
+ lgr %r1, %r4
+ mlgr %r0, %r2
+ algr %r1, %r2
+ alcgr %r0, %r2
+ lgr %r2, %r4
+ sgr %r2, %r0
+ lg %r9, 72(%r15)
+ br %r14
+EPILOGUE()
+ RODATA
+ ALIGN(2)
+approx_tab:
+forloop(i,256,512-1,dnl
+` .word eval(0x7fd00/i)
+')dnl
+ASM_END()
diff --git a/gmp/mpn/s390_64/logops_n.asm b/gmp/mpn/s390_64/logops_n.asm
new file mode 100644
index 0000000000..914cfb6a41
--- /dev/null
+++ b/gmp/mpn/s390_64/logops_n.asm
@@ -0,0 +1,291 @@
+dnl S/390-64 logops.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb variant 1 variant 2 variant 3
+C rp!=up rp=up
+C z900 4.5 2.25 5.5 5.5
+C z990 2.75 2 3.25 3.25
+C z9 ? ? ?
+C z10 3.25 3.75 3.75
+C z196 ? ? ?
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`vp', `%r4')
+define(`n', `%r5')
+
+ifdef(`OPERATION_and_n',`
+ define(`func',`mpn_and_n')
+ define(`VARIANT_1')
+ define(`LOGOPC',`nc')
+ define(`LOGOP',`ng')')
+ifdef(`OPERATION_andn_n',`
+ define(`func',`mpn_andn_n')
+ define(`VARIANT_2')
+ define(`LOGOP',`ng')')
+ifdef(`OPERATION_nand_n',`
+ define(`func',`mpn_nand_n')
+ define(`VARIANT_3')
+ define(`LOGOP',`ng')')
+ifdef(`OPERATION_ior_n',`
+ define(`func',`mpn_ior_n')
+ define(`VARIANT_1')
+ define(`LOGOPC',`oc')
+ define(`LOGOP',`og')')
+ifdef(`OPERATION_iorn_n',`
+ define(`func',`mpn_iorn_n')
+ define(`VARIANT_2')
+ define(`LOGOP',`og')')
+ifdef(`OPERATION_nior_n',`
+ define(`func',`mpn_nior_n')
+ define(`VARIANT_3')
+ define(`LOGOP',`og')')
+ifdef(`OPERATION_xor_n',`
+ define(`func',`mpn_xor_n')
+ define(`VARIANT_1')
+ define(`LOGOPC',`xc')
+ define(`LOGOP',`xg')')
+ifdef(`OPERATION_xnor_n',`
+ define(`func',`mpn_xnor_n')
+ define(`VARIANT_2')
+ define(`LOGOP',`xg')')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+ASM_START()
+PROLOGUE(func)
+ifdef(`VARIANT_1',`
+ cgr rp, up
+ jne L(normal)
+
+ sllg n, n, 3
+ aghi n, -1
+ srlg %r1, n, 8
+ ltgr %r1, %r1 C < 256 bytes to copy?
+ je L(1)
+
+L(tp): LOGOPC 0(256, rp), 0(vp)
+ la rp, 256(rp)
+ la vp, 256(vp)
+ brctg %r1, L(tp)
+
+L(1): bras %r1, L(2) C make r1 point to mvc insn
+ LOGOPC 0(1, rp), 0(vp)
+L(2): ex n, 0(%r1) C execute mvc with length ((n-1) mod 256)+1
+L(rtn): br %r14
+
+
+L(normal):
+ stmg %r6, %r8, 48(%r15)
+ aghi n, 3
+ lghi %r7, 3
+ srlg %r0, n, 2
+ ngr %r7, n C n mod 4
+ je L(b1)
+ cghi %r7, 2
+ jl L(b2)
+ jne L(top)
+
+L(b3): lmg %r5, %r7, 0(up)
+ la up, 24(up)
+ LOGOP %r5, 0(vp)
+ LOGOP %r6, 8(vp)
+ LOGOP %r7, 16(vp)
+ stmg %r5, %r7, 0(rp)
+ la rp, 24(rp)
+ la vp, 24(vp)
+ j L(mid)
+
+L(b1): lg %r5, 0(up)
+ la up, 8(up)
+ LOGOP %r5, 0(vp)
+ stg %r5, 0(rp)
+ la rp, 8(rp)
+ la vp, 8(vp)
+ j L(mid)
+
+L(b2): lmg %r5, %r6, 0(up)
+ la up, 16(up)
+ LOGOP %r5, 0(vp)
+ LOGOP %r6, 8(vp)
+ stmg %r5, %r6, 0(rp)
+ la rp, 16(rp)
+ la vp, 16(vp)
+ j L(mid)
+
+L(top): lmg %r5, %r8, 0(up)
+ la up, 32(up)
+ LOGOP %r5, 0(vp)
+ LOGOP %r6, 8(vp)
+ LOGOP %r7, 16(vp)
+ LOGOP %r8, 24(vp)
+ stmg %r5, %r8, 0(rp)
+ la rp, 32(rp)
+ la vp, 32(vp)
+L(mid): brctg %r0, L(top)
+
+ lmg %r6, %r8, 48(%r15)
+ br %r14
+')
+
+ifdef(`VARIANT_2',`
+ stmg %r6, %r8, 48(%r15)
+ lghi %r1, -1
+
+ aghi n, 3
+ lghi %r7, 3
+ srlg %r0, n, 2
+ ngr %r7, n C n mod 4
+ je L(b1)
+ cghi %r7, 2
+ jl L(b2)
+ jne L(top)
+
+L(b3): lmg %r5, %r7, 0(vp)
+ la vp, 24(vp)
+ xgr %r5, %r1
+ xgr %r6, %r1
+ xgr %r7, %r1
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 8(up)
+ LOGOP %r7, 16(up)
+ stmg %r5, %r7, 0(rp)
+ la rp, 24(rp)
+ la up, 24(up)
+ j L(mid)
+
+L(b1): lg %r5, 0(vp)
+ la vp, 8(vp)
+ xgr %r5, %r1
+ LOGOP %r5, 0(up)
+ stg %r5, 0(rp)
+ la rp, 8(rp)
+ la up, 8(up)
+ j L(mid)
+
+L(b2): lmg %r5, %r6, 0(vp)
+ la vp, 16(vp)
+ xgr %r5, %r1
+ xgr %r6, %r1
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 8(up)
+ stmg %r5, %r6, 0(rp)
+ la rp, 16(rp)
+ la up, 16(up)
+ j L(mid)
+
+L(top): lmg %r5, %r8, 0(vp)
+ la vp, 32(vp)
+ xgr %r5, %r1
+ xgr %r6, %r1
+ xgr %r7, %r1
+ xgr %r8, %r1
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 8(up)
+ LOGOP %r7, 16(up)
+ LOGOP %r8, 24(up)
+ la up, 32(up)
+ stmg %r5, %r8, 0(rp)
+ la rp, 32(rp)
+L(mid): brctg %r0, L(top)
+
+ lmg %r6, %r8, 48(%r15)
+ br %r14
+')
+
+ifdef(`VARIANT_3',`
+ stmg %r6, %r8, 48(%r15)
+ lghi %r1, -1
+
+ aghi n, 3
+ lghi %r7, 3
+ srlg %r0, n, 2
+ ngr %r7, n C n mod 4
+ je L(b1)
+ cghi %r7, 2
+ jl L(b2)
+ jne L(top)
+
+L(b3): lmg %r5, %r7, 0(vp)
+ la vp, 24(vp)
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 8(up)
+ xgr %r5, %r1
+ xgr %r6, %r1
+ LOGOP %r7, 16(up)
+ xgr %r7, %r1
+ stmg %r5, %r7, 0(rp)
+ la rp, 24(rp)
+ la up, 24(up)
+ j L(mid)
+
+L(b1): lg %r5, 0(vp)
+ la vp, 8(vp)
+ LOGOP %r5, 0(up)
+ xgr %r5, %r1
+ stg %r5, 0(rp)
+ la rp, 8(rp)
+ la up, 8(up)
+ j L(mid)
+
+L(b2): lmg %r5, %r6, 0(vp)
+ la vp, 16(vp)
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 8(up)
+ xgr %r5, %r1
+ xgr %r6, %r1
+ stmg %r5, %r6, 0(rp)
+ la rp, 16(rp)
+ la up, 16(up)
+ j L(mid)
+
+L(top): lmg %r5, %r8, 0(vp)
+ la vp, 32(vp)
+ LOGOP %r5, 0(up)
+ LOGOP %r6, 8(up)
+ xgr %r5, %r1
+ xgr %r6, %r1
+ LOGOP %r7, 16(up)
+ LOGOP %r8, 24(up)
+ xgr %r7, %r1
+ xgr %r8, %r1
+ stmg %r5, %r8, 0(rp)
+ la up, 32(up)
+ la rp, 32(rp)
+L(mid): brctg %r0, L(top)
+
+ lmg %r6, %r8, 48(%r15)
+ br %r14
+')
+
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/lshift.asm b/gmp/mpn/s390_64/lshift.asm
new file mode 100644
index 0000000000..4dae035a62
--- /dev/null
+++ b/gmp/mpn/s390_64/lshift.asm
@@ -0,0 +1,196 @@
+dnl S/390-64 mpn_lshift.
+
+dnl Copyright 2011, 2012, 2014 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 7
+C z990 3
+C z9 ?
+C z10 6
+C z196 ?
+
+C NOTES
+C * This uses discrete loads and stores in a software pipeline. Using lmg and
+C stmg is not faster.
+C * One could assume more pipelining could approach 2.5 c/l, but we have not
+C found any 8-way loop that runs better than the current 4-way loop.
+C * Consider using the same feed-in code for 1 <= n <= 3 as for n mod 4,
+C similarly to the x86_64 sqr_basecase feed-in.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`cnt', `%r5')
+
+define(`tnc', `%r6')
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ cghi n, 3
+ jh L(gt1)
+
+ stmg %r6, %r7, 48(%r15)
+ larl %r1, L(tab)-4
+ lcgr tnc, cnt
+ sllg n, n, 2
+ b 0(n,%r1)
+L(tab): j L(n1)
+ j L(n2)
+ j L(n3)
+
+L(n1): lg %r1, 0(up)
+ sllg %r0, %r1, 0(cnt)
+ stg %r0, 0(rp)
+ srlg %r2, %r1, 0(tnc)
+ lg %r6, 48(%r15) C restoring r7 not needed
+ br %r14
+
+L(n2): lg %r1, 8(up)
+ srlg %r4, %r1, 0(tnc)
+ sllg %r0, %r1, 0(cnt)
+ j L(cj)
+
+L(n3): lg %r1, 16(up)
+ srlg %r4, %r1, 0(tnc)
+ sllg %r0, %r1, 0(cnt)
+ lg %r1, 8(up)
+ srlg %r7, %r1, 0(tnc)
+ ogr %r7, %r0
+ sllg %r0, %r1, 0(cnt)
+ stg %r7, 16(rp)
+L(cj): lg %r1, 0(up)
+ srlg %r7, %r1, 0(tnc)
+ ogr %r7, %r0
+ sllg %r0, %r1, 0(cnt)
+ stg %r7, 8(rp)
+ stg %r0, 0(rp)
+ lgr %r2, %r4
+ lmg %r6, %r7, 48(%r15)
+ br %r14
+
+L(gt1): stmg %r6, %r13, 48(%r15)
+ lcgr tnc, cnt C tnc = -cnt
+
+ sllg %r1, n, 3
+ srlg %r0, n, 2 C loop count
+
+ agr up, %r1 C point up at end of U
+ agr rp, %r1 C point rp at end of R
+ aghi up, -56
+ aghi rp, -40
+
+ lghi %r7, 3
+ ngr %r7, n
+ je L(b0)
+ cghi %r7, 2
+ jl L(b1)
+ je L(b2)
+
+L(b3): lg %r7, 48(up)
+ srlg %r9, %r7, 0(tnc)
+ sllg %r11, %r7, 0(cnt)
+ lg %r8, 40(up)
+ lg %r7, 32(up)
+ srlg %r4, %r8, 0(tnc)
+ sllg %r13, %r8, 0(cnt)
+ ogr %r11, %r4
+ la rp, 16(rp)
+ j L(lm3)
+
+L(b2): lg %r8, 48(up)
+ lg %r7, 40(up)
+ srlg %r9, %r8, 0(tnc)
+ sllg %r13, %r8, 0(cnt)
+ la rp, 24(rp)
+ la up, 8(up)
+ j L(lm2)
+
+L(b1): lg %r7, 48(up)
+ srlg %r9, %r7, 0(tnc)
+ sllg %r11, %r7, 0(cnt)
+ lg %r8, 40(up)
+ lg %r7, 32(up)
+ srlg %r4, %r8, 0(tnc)
+ sllg %r10, %r8, 0(cnt)
+ ogr %r11, %r4
+ la rp, 32(rp)
+ la up, 16(up)
+ j L(lm1)
+
+L(b0): lg %r8, 48(up)
+ lg %r7, 40(up)
+ srlg %r9, %r8, 0(tnc)
+ sllg %r10, %r8, 0(cnt)
+ la rp, 40(rp)
+ la up, 24(up)
+ j L(lm0)
+
+ ALIGN(8)
+L(top): srlg %r4, %r8, 0(tnc)
+ sllg %r13, %r8, 0(cnt)
+ ogr %r11, %r4
+ stg %r10, 24(rp)
+L(lm3): stg %r11, 16(rp)
+L(lm2): srlg %r12, %r7, 0(tnc)
+ sllg %r11, %r7, 0(cnt)
+ lg %r8, 24(up)
+ lg %r7, 16(up)
+ ogr %r13, %r12
+ srlg %r4, %r8, 0(tnc)
+ sllg %r10, %r8, 0(cnt)
+ ogr %r11, %r4
+ stg %r13, 8(rp)
+L(lm1): stg %r11, 0(rp)
+L(lm0): srlg %r12, %r7, 0(tnc)
+ aghi rp, -32
+ sllg %r11, %r7, 0(cnt)
+ lg %r8, 8(up)
+ lg %r7, 0(up)
+ aghi up, -32
+ ogr %r10, %r12
+ brctg %r0, L(top)
+
+L(end): srlg %r4, %r8, 0(tnc)
+ sllg %r13, %r8, 0(cnt)
+ ogr %r11, %r4
+ stg %r10, 24(rp)
+ stg %r11, 16(rp)
+ srlg %r12, %r7, 0(tnc)
+ sllg %r11, %r7, 0(cnt)
+ ogr %r13, %r12
+ stg %r13, 8(rp)
+ stg %r11, 0(rp)
+ lgr %r2, %r9
+
+ lmg %r6, %r13, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/lshiftc.asm b/gmp/mpn/s390_64/lshiftc.asm
new file mode 100644
index 0000000000..92552d529a
--- /dev/null
+++ b/gmp/mpn/s390_64/lshiftc.asm
@@ -0,0 +1,207 @@
+dnl S/390-64 mpn_lshiftc.
+
+dnl Copyright 2011, 2014 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 9
+C z990 3.5
+C z9 ?
+C z10 7
+C z196 ?
+
+C NOTES
+C * See notes in lshift.asm.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`cnt', `%r5')
+
+define(`tnc', `%r6')
+
+ASM_START()
+PROLOGUE(mpn_lshiftc)
+ cghi n, 3
+ jh L(gt1)
+
+ stmg %r6, %r8, 48(%r15)
+ larl %r1, L(tab)-4
+ lcgr tnc, cnt
+ sllg n, n, 2
+ lghi %r8, -1
+ b 0(n,%r1)
+L(tab): j L(n1)
+ j L(n2)
+ j L(n3)
+
+L(n1): lg %r1, 0(up)
+ sllg %r0, %r1, 0(cnt)
+ xgr %r0, %r8
+ stg %r0, 0(rp)
+ srlg %r2, %r1, 0(tnc)
+ lmg %r6, %r8, 48(%r15)
+ br %r14
+
+L(n2): lg %r1, 8(up)
+ srlg %r4, %r1, 0(tnc)
+ sllg %r0, %r1, 0(cnt)
+ j L(cj)
+
+L(n3): lg %r1, 16(up)
+ srlg %r4, %r1, 0(tnc)
+ sllg %r0, %r1, 0(cnt)
+ lg %r1, 8(up)
+ srlg %r7, %r1, 0(tnc)
+ ogr %r7, %r0
+ sllg %r0, %r1, 0(cnt)
+ xgr %r7, %r8
+ stg %r7, 16(rp)
+L(cj): lg %r1, 0(up)
+ srlg %r7, %r1, 0(tnc)
+ ogr %r7, %r0
+ sllg %r0, %r1, 0(cnt)
+ xgr %r7, %r8
+ xgr %r0, %r8
+ stg %r7, 8(rp)
+ stg %r0, 0(rp)
+ lgr %r2, %r4
+ lmg %r6, %r8, 48(%r15)
+ br %r14
+
+L(gt1): stmg %r6, %r14, 48(%r15)
+ lcgr tnc, cnt C tnc = -cnt
+
+ sllg %r1, n, 3
+ srlg %r0, n, 2 C loop count
+
+ agr up, %r1 C point up at end of U
+ agr rp, %r1 C point rp at end of R
+ aghi up, -56
+ aghi rp, -40
+
+ lghi %r7, 3
+ lghi %r14, -1
+ ngr %r7, n
+ je L(b0)
+ cghi %r7, 2
+ jl L(b1)
+ je L(b2)
+
+L(b3): lg %r7, 48(up)
+ srlg %r9, %r7, 0(tnc)
+ sllg %r11, %r7, 0(cnt)
+ lg %r8, 40(up)
+ lg %r7, 32(up)
+ srlg %r4, %r8, 0(tnc)
+ sllg %r13, %r8, 0(cnt)
+ ogr %r11, %r4
+ la rp, 16(rp)
+ xgr %r11, %r14
+ j L(lm3)
+
+L(b2): lg %r8, 48(up)
+ lg %r7, 40(up)
+ srlg %r9, %r8, 0(tnc)
+ sllg %r13, %r8, 0(cnt)
+ la rp, 24(rp)
+ la up, 8(up)
+ j L(lm2)
+
+L(b1): lg %r7, 48(up)
+ srlg %r9, %r7, 0(tnc)
+ sllg %r11, %r7, 0(cnt)
+ lg %r8, 40(up)
+ lg %r7, 32(up)
+ srlg %r4, %r8, 0(tnc)
+ sllg %r10, %r8, 0(cnt)
+ ogr %r11, %r4
+ la rp, 32(rp)
+ la up, 16(up)
+ xgr %r11, %r14
+ j L(lm1)
+
+L(b0): lg %r8, 48(up)
+ lg %r7, 40(up)
+ srlg %r9, %r8, 0(tnc)
+ sllg %r10, %r8, 0(cnt)
+ la rp, 40(rp)
+ la up, 24(up)
+ j L(lm0)
+
+ ALIGN(8)
+L(top): srlg %r4, %r8, 0(tnc)
+ sllg %r13, %r8, 0(cnt)
+ ogr %r11, %r4
+ xgr %r10, %r14
+ xgr %r11, %r14
+ stg %r10, 24(rp)
+L(lm3): stg %r11, 16(rp)
+L(lm2): srlg %r12, %r7, 0(tnc)
+ sllg %r11, %r7, 0(cnt)
+ lg %r8, 24(up)
+ lg %r7, 16(up)
+ ogr %r13, %r12
+ srlg %r4, %r8, 0(tnc)
+ sllg %r10, %r8, 0(cnt)
+ ogr %r11, %r4
+ xgr %r13, %r14
+ xgr %r11, %r14
+ stg %r13, 8(rp)
+L(lm1): stg %r11, 0(rp)
+L(lm0): srlg %r12, %r7, 0(tnc)
+ aghi rp, -32
+ sllg %r11, %r7, 0(cnt)
+ lg %r8, 8(up)
+ lg %r7, 0(up)
+ aghi up, -32
+ ogr %r10, %r12
+ brctg %r0, L(top)
+
+L(end): srlg %r4, %r8, 0(tnc)
+ sllg %r13, %r8, 0(cnt)
+ ogr %r11, %r4
+ xgr %r10, %r14
+ xgr %r11, %r14
+ stg %r10, 24(rp)
+ stg %r11, 16(rp)
+ srlg %r12, %r7, 0(tnc)
+ sllg %r11, %r7, 0(cnt)
+ ogr %r13, %r12
+ xgr %r13, %r14
+ xgr %r11, %r14
+ stg %r13, 8(rp)
+ stg %r11, 0(rp)
+ lgr %r2, %r9
+
+ lmg %r6, %r14, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/mod_34lsub1.asm b/gmp/mpn/s390_64/mod_34lsub1.asm
new file mode 100644
index 0000000000..fd40011a8c
--- /dev/null
+++ b/gmp/mpn/s390_64/mod_34lsub1.asm
@@ -0,0 +1,109 @@
+dnl S/390-64 mpn_mod_34lsub1
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 5.8
+C z990 2
+C z9 ?
+C z10 4.5
+C z196 ?
+
+C TODO
+C * Optimise summation code, see x86_64.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`n', `%r3')
+
+ASM_START()
+PROLOGUE(mpn_mod_34lsub1)
+ stmg %r7, %r12, 56(%r15)
+ lghi %r11, 0
+ lghi %r12, 0
+ lghi %r0, 0
+ lghi %r8, 0
+ lghi %r9, 0
+ lghi %r10, 0
+ lghi %r7, 0
+ aghi %r3, -3
+ jl .L3
+
+L(top): alg %r0, 0(%r2)
+ alcg %r12, 8(%r2)
+ alcg %r11, 16(%r2)
+ alcgr %r8, %r7
+ la %r2, 24(%r2)
+ aghi %r3, -3
+ jnl L(top)
+
+ lgr %r7, %r8
+ srlg %r1, %r11, 16
+ nihh %r7, 0 C 0xffffffffffff
+ agr %r7, %r1
+ srlg %r8, %r8, 48
+ agr %r7, %r8
+ sllg %r11, %r11, 32
+ nihh %r11, 0
+ agr %r7, %r11
+.L3:
+ cghi %r3, -3
+ je .L6
+ alg %r0, 0(%r2)
+ alcgr %r10, %r10
+ cghi %r3, -2
+ je .L6
+ alg %r12, 8(%r2)
+ alcgr %r9, %r9
+.L6:
+ srlg %r1, %r0, 48
+ nihh %r0, 0 C 0xffffffffffff
+ agr %r0, %r1
+ agr %r0, %r7
+ srlg %r1, %r12, 32
+ agr %r0, %r1
+ srlg %r1, %r10, 32
+ agr %r0, %r1
+ llgfr %r12, %r12
+ srlg %r1, %r9, 16
+ sllg %r12, %r12, 16
+ llgfr %r10, %r10
+ agr %r0, %r1
+ llill %r2, 65535
+ agr %r0, %r12
+ sllg %r10, %r10, 16
+ ngr %r2, %r9
+ agr %r0, %r10
+ sllg %r2, %r2, 32
+ agr %r2, %r0
+ lmg %r7, %r12, 56(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/mul_1.asm b/gmp/mpn/s390_64/mul_1.asm
new file mode 100644
index 0000000000..a8f6da9a0f
--- /dev/null
+++ b/gmp/mpn/s390_64/mul_1.asm
@@ -0,0 +1,66 @@
+dnl S/390-64 mpn_mul_1
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 29
+C z990 22
+C z9 ?
+C z10 20
+C z196 ?
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`v0', `%r5')
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ stmg %r11, %r12, 88(%r15)
+ lghi %r12, 0 C zero index register
+ aghi %r12, 0 C clear carry flag
+ lghi %r11, 0 C clear carry limb
+
+L(top): lg %r1, 0(%r12,up)
+ mlgr %r0, v0
+ alcgr %r1, %r11
+ lgr %r11, %r0 C copy high part to carry limb
+ stg %r1, 0(%r12,rp)
+ la %r12, 8(%r12)
+ brctg n, L(top)
+
+ lghi %r2, 0
+ alcgr %r2, %r11
+
+ lmg %r11, %r12, 88(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/mul_basecase.asm b/gmp/mpn/s390_64/mul_basecase.asm
new file mode 100644
index 0000000000..7d14ea98d2
--- /dev/null
+++ b/gmp/mpn/s390_64/mul_basecase.asm
@@ -0,0 +1,130 @@
+dnl S/390-64 mpn_mul_basecase.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 ?
+C z990 23
+C z9 ?
+C z10 28
+C z196 ?
+
+C TODO
+C * Perhaps add special case for un <= 2.
+C * Replace loops by faster code. The mul_1 and addmul_1 loops could be sped
+C up by about 10%.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`un', `%r4')
+define(`vp', `%r5')
+define(`vn', `%r6')
+
+define(`zero', `%r8')
+
+ASM_START()
+PROLOGUE(mpn_mul_basecase)
+ cghi un, 2
+ jhe L(ge2)
+
+C un = vn = 1
+ lg %r1, 0(vp)
+ mlg %r0, 0(up)
+ stg %r1, 0(rp)
+ stg %r0, 8(rp)
+ br %r14
+
+L(ge2): C jne L(gen)
+
+
+L(gen):
+C mul_1 =======================================================================
+
+ stmg %r6, %r12, 48(%r15)
+ lghi zero, 0
+ aghi un, -1
+
+ lg %r7, 0(vp)
+ lg %r11, 0(up)
+ lghi %r12, 8 C init index register
+ mlgr %r10, %r7
+ lgr %r9, un
+ stg %r11, 0(rp)
+ cr %r15, %r15 C clear carry flag
+
+L(tm): lg %r1, 0(%r12,up)
+ mlgr %r0, %r7
+ alcgr %r1, %r10
+ lgr %r10, %r0 C copy high part to carry limb
+ stg %r1, 0(%r12,rp)
+ la %r12, 8(%r12)
+ brctg %r9, L(tm)
+
+ alcgr %r0, zero
+ stg %r0, 0(%r12,rp)
+
+C addmul_1 loop ===============================================================
+
+ aghi vn, -1
+ je L(outer_end)
+L(outer_loop):
+
+ la rp, 8(rp) C rp += 1
+ la vp, 8(vp) C up += 1
+ lg %r7, 0(vp)
+ lg %r11, 0(up)
+ lghi %r12, 8 C init index register
+ mlgr %r10, %r7
+ lgr %r9, un
+ alg %r11, 0(rp)
+ stg %r11, 0(rp)
+
+L(tam): lg %r1, 0(%r12,up)
+ lg %r11, 0(%r12,rp)
+ mlgr %r0, %r7
+ alcgr %r1, %r11
+ alcgr %r0, zero
+ algr %r1, %r10
+ lgr %r10, %r0
+ stg %r1, 0(%r12,rp)
+ la %r12, 8(%r12)
+ brctg %r9, L(tam)
+
+ alcgr %r0, zero
+ stg %r0, 0(%r12,rp)
+
+ brctg vn, L(outer_loop)
+L(outer_end):
+
+ lmg %r6, %r12, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/rshift.asm b/gmp/mpn/s390_64/rshift.asm
new file mode 100644
index 0000000000..e870971650
--- /dev/null
+++ b/gmp/mpn/s390_64/rshift.asm
@@ -0,0 +1,195 @@
+dnl S/390-64 mpn_rshift.
+
+dnl Copyright 2011, 2014 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 7
+C z990 3
+C z9 ?
+C z10 6
+C z196 ?
+
+C NOTES
+C * See notes in lshift.asm.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`cnt', `%r5')
+
+define(`tnc', `%r6')
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ cghi n, 3
+ jh L(gt1)
+
+ stmg %r6, %r7, 48(%r15)
+ larl %r1, L(tab)-4
+ lcgr tnc, cnt
+ sllg n, n, 2
+ b 0(n,%r1)
+L(tab): j L(n1)
+ j L(n2)
+ j L(n3)
+
+L(n1): lg %r1, 0(up)
+ srlg %r0, %r1, 0(cnt)
+ stg %r0, 0(rp)
+ sllg %r2, %r1, 0(tnc)
+ lg %r6, 48(%r15) C restoring r7 not needed
+ br %r14
+
+L(n2): lg %r1, 0(up)
+ sllg %r4, %r1, 0(tnc)
+ srlg %r0, %r1, 0(cnt)
+ lg %r1, 8(up)
+ sllg %r7, %r1, 0(tnc)
+ ogr %r7, %r0
+ srlg %r0, %r1, 0(cnt)
+ stg %r7, 0(rp)
+ stg %r0, 8(rp)
+ lgr %r2, %r4
+ lmg %r6, %r7, 48(%r15)
+ br %r14
+
+
+L(n3): lg %r1, 0(up)
+ sllg %r4, %r1, 0(tnc)
+ srlg %r0, %r1, 0(cnt)
+ lg %r1, 8(up)
+ sllg %r7, %r1, 0(tnc)
+ ogr %r7, %r0
+ srlg %r0, %r1, 0(cnt)
+ stg %r7, 0(rp)
+ lg %r1, 16(up)
+ sllg %r7, %r1, 0(tnc)
+ ogr %r7, %r0
+ srlg %r0, %r1, 0(cnt)
+ stg %r7, 8(rp)
+ stg %r0, 16(rp)
+ lgr %r2, %r4
+ lmg %r6, %r7, 48(%r15)
+ br %r14
+
+L(gt1): stmg %r6, %r13, 48(%r15)
+ lcgr tnc, cnt C tnc = -cnt
+
+ sllg %r1, n, 3
+ srlg %r0, n, 2 C loop count
+
+ lghi %r7, 3
+ ngr %r7, n
+ je L(b0)
+ cghi %r7, 2
+ jl L(b1)
+ je L(b2)
+
+L(b3): aghi rp, -8
+ lg %r7, 0(up)
+ sllg %r9, %r7, 0(tnc)
+ srlg %r11, %r7, 0(cnt)
+ lg %r8, 8(up)
+ lg %r7, 16(up)
+ sllg %r4, %r8, 0(tnc)
+ srlg %r13, %r8, 0(cnt)
+ ogr %r11, %r4
+ la up, 24(up)
+ j L(lm3)
+
+L(b2): aghi rp, -16
+ lg %r8, 0(up)
+ lg %r7, 8(up)
+ sllg %r9, %r8, 0(tnc)
+ srlg %r13, %r8, 0(cnt)
+ la up, 16(up)
+ j L(lm2)
+
+L(b1): aghi rp, -24
+ lg %r7, 0(up)
+ sllg %r9, %r7, 0(tnc)
+ srlg %r11, %r7, 0(cnt)
+ lg %r8, 8(up)
+ lg %r7, 16(up)
+ sllg %r4, %r8, 0(tnc)
+ srlg %r10, %r8, 0(cnt)
+ ogr %r11, %r4
+ la up, 8(up)
+ j L(lm1)
+
+L(b0): aghi rp, -32
+ lg %r8, 0(up)
+ lg %r7, 8(up)
+ sllg %r9, %r8, 0(tnc)
+ srlg %r10, %r8, 0(cnt)
+ j L(lm0)
+
+ ALIGN(8)
+L(top): sllg %r4, %r8, 0(tnc)
+ srlg %r13, %r8, 0(cnt)
+ ogr %r11, %r4
+ stg %r10, 0(rp)
+L(lm3): stg %r11, 8(rp)
+L(lm2): sllg %r12, %r7, 0(tnc)
+ srlg %r11, %r7, 0(cnt)
+ lg %r8, 0(up)
+ lg %r7, 8(up)
+ ogr %r13, %r12
+ sllg %r4, %r8, 0(tnc)
+ srlg %r10, %r8, 0(cnt)
+ ogr %r11, %r4
+ stg %r13, 16(rp)
+L(lm1): stg %r11, 24(rp)
+L(lm0): sllg %r12, %r7, 0(tnc)
+ aghi rp, 32
+ srlg %r11, %r7, 0(cnt)
+ lg %r8, 16(up)
+ lg %r7, 24(up)
+ aghi up, 32
+ ogr %r10, %r12
+ brctg %r0, L(top)
+
+L(end): sllg %r4, %r8, 0(tnc)
+ srlg %r13, %r8, 0(cnt)
+ ogr %r11, %r4
+ stg %r10, 0(rp)
+ stg %r11, 8(rp)
+ sllg %r12, %r7, 0(tnc)
+ srlg %r11, %r7, 0(cnt)
+ ogr %r13, %r12
+ stg %r13, 16(rp)
+ stg %r11, 24(rp)
+ lgr %r2, %r9
+
+ lmg %r6, %r13, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/sqr_basecase.asm b/gmp/mpn/s390_64/sqr_basecase.asm
new file mode 100644
index 0000000000..bf31bd5546
--- /dev/null
+++ b/gmp/mpn/s390_64/sqr_basecase.asm
@@ -0,0 +1,203 @@
+dnl S/390-64 mpn_sqr_basecase.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 ?
+C z990 23
+C z9 ?
+C z10 28
+C z196 ?
+
+C TODO
+C * Clean up.
+C * Stop iterating addmul_1 loop at latest for n = 2, implement longer tail.
+C This will ask for basecase handling of n = 3.
+C * Update counters and pointers more straightforwardly, possibly lowering
+C register usage.
+C * Should we use this allocation-free style for more sqr_basecase asm
+C implementations? The only disadvantage is that it requires R != U.
+C * Replace loops by faster code. The mul_1 and addmul_1 loops could be sped
+C up by about 10%. The sqr_diag_addlsh1 loop could probably be sped up even
+C more.
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+
+define(`zero', `%r8')
+define(`rp_saved', `%r9')
+define(`up_saved', `%r13')
+define(`n_saved', `%r14')
+
+ASM_START()
+PROLOGUE(mpn_sqr_basecase)
+ aghi n, -2
+ jhe L(ge2)
+
+C n = 1
+ lg %r5, 0(up)
+ mlgr %r4, %r5
+ stg %r5, 0(rp)
+ stg %r4, 8(rp)
+ br %r14
+
+L(ge2): jne L(gen)
+
+C n = 2
+ stmg %r6, %r8, 48(%r15)
+ lghi zero, 0
+
+ lg %r5, 0(up)
+ mlgr %r4, %r5 C u0 * u0
+ lg %r1, 8(up)
+ mlgr %r0, %r1 C u1 * u1
+ stg %r5, 0(rp)
+
+ lg %r7, 0(up)
+ mlg %r6, 8(up) C u0 * u1
+ algr %r7, %r7
+ alcgr %r6, %r6
+ alcgr %r0, zero
+
+ algr %r4, %r7
+ alcgr %r1, %r6
+ alcgr %r0, zero
+ stg %r4, 8(rp)
+ stg %r1, 16(rp)
+ stg %r0, 24(rp)
+
+ lmg %r6, %r8, 48(%r15)
+ br %r14
+
+L(gen):
+C mul_1 =======================================================================
+
+ stmg %r6, %r14, 48(%r15)
+ lghi zero, 0
+ lgr up_saved, up
+ lgr rp_saved, rp
+ lgr n_saved, n
+
+ lg %r6, 0(up)
+ lg %r11, 8(up)
+ lghi %r12, 16 C init index register
+ mlgr %r10, %r6
+ lgr %r5, n
+ stg %r11, 8(rp)
+ cr %r15, %r15 C clear carry flag
+
+L(tm): lg %r1, 0(%r12,up)
+ mlgr %r0, %r6
+ alcgr %r1, %r10
+ lgr %r10, %r0 C copy high part to carry limb
+ stg %r1, 0(%r12,rp)
+ la %r12, 8(%r12)
+ brctg %r5, L(tm)
+
+ alcgr %r0, zero
+ stg %r0, 0(%r12,rp)
+
+C addmul_1 loop ===============================================================
+
+ aghi n, -1
+ je L(outer_end)
+L(outer_loop):
+
+ la rp, 16(rp) C rp += 2
+ la up, 8(up) C up += 1
+ lg %r6, 0(up)
+ lg %r11, 8(up)
+ lghi %r12, 16 C init index register
+ mlgr %r10, %r6
+ lgr %r5, n
+ alg %r11, 8(rp)
+ stg %r11, 8(rp)
+
+L(tam): lg %r1, 0(%r12,up)
+ lg %r7, 0(%r12,rp)
+ mlgr %r0, %r6
+ alcgr %r1, %r7
+ alcgr %r0, zero
+ algr %r1, %r10
+ lgr %r10, %r0
+ stg %r1, 0(%r12,rp)
+ la %r12, 8(%r12)
+ brctg %r5, L(tam)
+
+ alcgr %r0, zero
+ stg %r0, 0(%r12,rp)
+
+ brctg n, L(outer_loop)
+L(outer_end):
+
+ lg %r6, 8(up)
+ lg %r1, 16(up)
+ lgr %r7, %r0 C Same as: lg %r7, 24(,rp)
+ mlgr %r0, %r6
+ algr %r1, %r7
+ alcgr %r0, zero
+ stg %r1, 24(rp)
+ stg %r0, 32(rp)
+
+C sqr_diag_addlsh1 ============================================================
+
+define(`up', `up_saved')
+define(`rp', `rp_saved')
+ la n, 1(n_saved)
+
+ lg %r1, 0(up)
+ mlgr %r0, %r1
+ stg %r1, 0(rp)
+C clr %r15, %r15 C clear carry (already clear per above)
+
+L(top): lg %r11, 8(up)
+ la up, 8(up)
+ lg %r6, 8(rp)
+ lg %r7, 16(rp)
+ mlgr %r10, %r11
+ alcgr %r6, %r6
+ alcgr %r7, %r7
+ alcgr %r10, zero C propagate carry to high product limb
+ algr %r6, %r0
+ alcgr %r7, %r11
+ stmg %r6, %r7, 8(rp)
+ la rp, 16(rp)
+ lgr %r0, %r10 C copy carry limb
+ brctg n, L(top)
+
+ alcgr %r0, zero
+ stg %r0, 8(rp)
+
+ lmg %r6, %r14, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/sublsh1_n.asm b/gmp/mpn/s390_64/sublsh1_n.asm
new file mode 100644
index 0000000000..50f127acef
--- /dev/null
+++ b/gmp/mpn/s390_64/sublsh1_n.asm
@@ -0,0 +1,169 @@
+dnl S/390-64 mpn_sublsh1_n
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 10
+C z990 5
+C z9 ?
+C z10 12
+C z196 ?
+
+C TODO
+C * Optimise for small n
+C * Compute RETVAL for sublsh1_n less stupidly
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`vp', `%r4')
+define(`n', `%r5')
+
+ifdef(`OPERATION_addlsh1_n',`
+ define(ADSBR, algr)
+ define(ADSBCR, alcgr)
+ define(INITCY, `lghi %r13, -1')
+ define(RETVAL, `la %r2, 2(%r1,%r13)')
+ define(func, mpn_addlsh1_n)
+')
+ifdef(`OPERATION_sublsh1_n',`
+ define(ADSBR, slgr)
+ define(ADSBCR, slbgr)
+ define(INITCY, `lghi %r13, 0')
+ define(RETVAL,`dnl
+ slgr %r1, %r13
+ lghi %r2, 1
+ algr %r2, %r1')
+ define(func, mpn_sublsh1_n)
+')
+
+ASM_START()
+PROLOGUE(mpn_sublsh1_n)
+ stmg %r6, %r13, 48(%r15)
+
+ aghi n, 3
+ lghi %r7, 3
+ srlg %r0, n, 2
+ ngr %r7, n C n mod 4
+ je L(b1)
+ cghi %r7, 2
+ jl L(b2)
+ jne L(b0)
+
+L(b3): lmg %r5, %r7, 0(up)
+ la up, 24(up)
+ lmg %r9, %r11, 0(vp)
+ la vp, 24(vp)
+
+ algr %r9, %r9
+ alcgr %r10, %r10
+ alcgr %r11, %r11
+ slbgr %r1, %r1
+
+ ADSBR %r5, %r9
+ ADSBCR %r6, %r10
+ ADSBCR %r7, %r11
+ slbgr %r13, %r13
+
+ stmg %r5, %r7, 0(rp)
+ la rp, 24(rp)
+ brctg %r0, L(top)
+ j L(end)
+
+L(b0): lghi %r1, -1
+ INITCY
+ j L(top)
+
+L(b1): lg %r5, 0(up)
+ la up, 8(up)
+ lg %r9, 0(vp)
+ la vp, 8(vp)
+
+ algr %r9, %r9
+ slbgr %r1, %r1
+ ADSBR %r5, %r9
+ slbgr %r13, %r13
+
+ stg %r5, 0(rp)
+ la rp, 8(rp)
+ brctg %r0, L(top)
+ j L(end)
+
+L(b2): lmg %r5, %r6, 0(up)
+ la up, 16(up)
+ lmg %r9, %r10, 0(vp)
+ la vp, 16(vp)
+
+ algr %r9, %r9
+ alcgr %r10, %r10
+ slbgr %r1, %r1
+
+ ADSBR %r5, %r9
+ ADSBCR %r6, %r10
+ slbgr %r13, %r13
+
+ stmg %r5, %r6, 0(rp)
+ la rp, 16(rp)
+ brctg %r0, L(top)
+ j L(end)
+
+L(top): lmg %r9, %r12, 0(vp)
+ la vp, 32(vp)
+
+ aghi %r1, 1 C restore carry
+
+ alcgr %r9, %r9
+ alcgr %r10, %r10
+ alcgr %r11, %r11
+ alcgr %r12, %r12
+
+ slbgr %r1, %r1 C save carry
+
+ lmg %r5, %r8, 0(up)
+ la up, 32(up)
+
+ aghi %r13, 1 C restore carry
+
+ ADSBCR %r5, %r9
+ ADSBCR %r6, %r10
+ ADSBCR %r7, %r11
+ ADSBCR %r8, %r12
+
+ slbgr %r13, %r13 C save carry
+
+ stmg %r5, %r8, 0(rp)
+ la rp, 32(rp)
+ brctg %r0, L(top)
+
+L(end): RETVAL
+ lmg %r6, %r13, 48(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/submul_1.asm b/gmp/mpn/s390_64/submul_1.asm
new file mode 100644
index 0000000000..91c4b06631
--- /dev/null
+++ b/gmp/mpn/s390_64/submul_1.asm
@@ -0,0 +1,70 @@
+dnl S/390-64 mpn_submul_1
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C z900 35
+C z990 24
+C z9 ?
+C z10 28
+C z196 ?
+
+C INPUT PARAMETERS
+define(`rp', `%r2')
+define(`up', `%r3')
+define(`n', `%r4')
+define(`v0', `%r5')
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ stmg %r9, %r12, 72(%r15)
+ lghi %r12, 0
+ slgr %r11, %r11
+
+L(top): lg %r1, 0(%r12, up)
+ lg %r10, 0(%r12, rp)
+ mlgr %r0, v0
+ slbgr %r10, %r1
+ slbgr %r9, %r9
+ slgr %r0, %r9 C conditional incr
+ slgr %r10, %r11
+ lgr %r11, %r0
+ stg %r10, 0(%r12, rp)
+ la %r12, 8(%r12)
+ brctg %r4, L(top)
+
+ lgr %r2, %r11
+ slbgr %r9, %r9
+ slgr %r2, %r9
+
+ lmg %r9, %r12, 72(%r15)
+ br %r14
+EPILOGUE()
diff --git a/gmp/mpn/s390_64/z10/gmp-mparam.h b/gmp/mpn/s390_64/z10/gmp-mparam.h
new file mode 100644
index 0000000000..c034f9b3b6
--- /dev/null
+++ b/gmp/mpn/s390_64/z10/gmp-mparam.h
@@ -0,0 +1,231 @@
+/* S/390-64 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 4400 MHz IBM z10 */
+/* FFT tuning limit = 15000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.7 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 4
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 8
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 14
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 23
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 29
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 2
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 56
+
+#define MUL_TOOM22_THRESHOLD 8
+#define MUL_TOOM33_THRESHOLD 65
+#define MUL_TOOM44_THRESHOLD 88
+#define MUL_TOOM6H_THRESHOLD 125
+#define MUL_TOOM8H_THRESHOLD 163
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 58
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 61
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 57
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 62
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 82
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 12
+#define SQR_TOOM3_THRESHOLD 89
+#define SQR_TOOM4_THRESHOLD 130
+#define SQR_TOOM6_THRESHOLD 189
+#define SQR_TOOM8_THRESHOLD 260
+
+#define MULMID_TOOM42_THRESHOLD 24
+
+#define MULMOD_BNM1_THRESHOLD 9
+#define SQRMOD_BNM1_THRESHOLD 9
+
+#define MUL_FFT_MODF_THRESHOLD 220 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 220, 5}, { 7, 4}, { 15, 5}, { 9, 6}, \
+ { 5, 5}, { 11, 6}, { 6, 5}, { 13, 6}, \
+ { 11, 7}, { 6, 6}, { 13, 7}, { 7, 6}, \
+ { 15, 7}, { 13, 8}, { 7, 7}, { 16, 8}, \
+ { 9, 7}, { 19, 8}, { 11, 7}, { 23, 8}, \
+ { 13, 9}, { 7, 8}, { 15, 7}, { 31, 8}, \
+ { 19, 9}, { 11, 8}, { 23,10}, { 7, 9}, \
+ { 15, 8}, { 33, 9}, { 19, 8}, { 39, 9}, \
+ { 27,10}, { 15, 9}, { 39,10}, { 23,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 83,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255, 7}, { 511,10}, { 71, 9}, \
+ { 143, 8}, { 287, 7}, { 575,10}, { 79,11}, \
+ { 47,12}, { 31,11}, { 63,10}, { 127, 9}, \
+ { 255, 8}, { 511,10}, { 143, 9}, { 287, 8}, \
+ { 575,11}, { 79,10}, { 159, 9}, { 319, 8}, \
+ { 639,10}, { 175, 9}, { 351, 8}, { 703, 7}, \
+ { 1407, 6}, { 2815,10}, { 191, 9}, { 383, 8}, \
+ { 767, 9}, { 415,11}, { 111,10}, { 223, 9}, \
+ { 447, 8}, { 895,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,11}, { 143,10}, { 287, 9}, \
+ { 575, 8}, { 1151,10}, { 319, 9}, { 639,11}, \
+ { 175, 9}, { 703, 8}, { 1407, 7}, { 2815,11}, \
+ { 191,10}, { 415, 9}, { 831,11}, { 223,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 287,10}, { 575, 9}, { 1151,12}, { 159,11}, \
+ { 319,10}, { 639,11}, { 351,10}, { 703, 9}, \
+ { 1407, 8}, { 2815,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 415,10}, { 831,12}, { 223,10}, \
+ { 895, 9}, { 1791,11}, { 479,13}, { 127,12}, \
+ { 255,11}, { 511,10}, { 1023,12}, { 287,11}, \
+ { 575,10}, { 1151,12}, { 319,11}, { 639,12}, \
+ { 351,11}, { 703,10}, { 1407, 9}, { 2815,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,10}, { 1663,12}, { 447,11}, { 895,10}, \
+ { 1791, 9}, { 3583,12}, { 479,14}, { 127,13}, \
+ { 255,12}, { 511,11}, { 1023,12}, { 575,11}, \
+ { 1151,13}, { 319,12}, { 703,11}, { 1407,10}, \
+ { 2815,13}, { 383,12}, { 767,11}, { 1535,12}, \
+ { 831,11}, { 1663,13}, { 447,12}, { 895,11}, \
+ { 1791,10}, { 3583,14}, { 255,13}, { 511,12}, \
+ { 1023,13}, { 575,12}, { 1151,13}, { 639,12}, \
+ { 1279,13}, { 703,12}, { 1407,11}, { 2815,14}, \
+ { 383,13}, { 767,12}, { 1535,13}, { 831,12}, \
+ { 1663,13}, { 895,12}, { 1791,11}, { 3583,15}, \
+ { 255,14}, { 511,13}, { 1151,14}, { 639,13}, \
+ { 1279,12}, { 2559,13}, { 1407,12}, { 2815,13}, \
+ { 1471,14}, { 767,13}, { 1663,14}, { 895,13}, \
+ { 1791,12}, { 3583,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 205
+#define MUL_FFT_THRESHOLD 1728
+
+#define SQR_FFT_MODF_THRESHOLD 212 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 212, 5}, { 7, 4}, { 15, 5}, { 11, 6}, \
+ { 6, 5}, { 13, 6}, { 7, 5}, { 15, 6}, \
+ { 13, 7}, { 7, 6}, { 15, 7}, { 13, 8}, \
+ { 7, 7}, { 16, 8}, { 9, 7}, { 19, 8}, \
+ { 11, 7}, { 23, 8}, { 13, 9}, { 7, 8}, \
+ { 19, 9}, { 11, 8}, { 23,10}, { 7, 9}, \
+ { 15, 8}, { 31, 9}, { 19, 8}, { 39, 9}, \
+ { 23,10}, { 15, 9}, { 39,10}, { 23,11}, \
+ { 15,10}, { 31, 9}, { 63,10}, { 39, 9}, \
+ { 79,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255,10}, { 71, 9}, { 143, 8}, \
+ { 287, 7}, { 575,10}, { 79,11}, { 47,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511,10}, { 143, 9}, { 287, 8}, { 575,11}, \
+ { 79,10}, { 159, 9}, { 319, 8}, { 639,10}, \
+ { 175, 9}, { 351, 8}, { 703,10}, { 191, 9}, \
+ { 383, 8}, { 767,10}, { 207,11}, { 111,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,11}, \
+ { 143,10}, { 287, 9}, { 575, 8}, { 1151,11}, \
+ { 159,10}, { 319, 9}, { 639,11}, { 175,10}, \
+ { 351, 9}, { 703,12}, { 95,11}, { 191,10}, \
+ { 383, 9}, { 767,11}, { 207,10}, { 415,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 287,10}, { 575, 9}, { 1151,12}, { 159,11}, \
+ { 319,10}, { 639,11}, { 351,10}, { 703, 9}, \
+ { 1407,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,12}, { 223,11}, { 447,10}, { 895, 9}, \
+ { 1791,13}, { 127,12}, { 255,11}, { 511,12}, \
+ { 287,11}, { 575,10}, { 1151,12}, { 319,11}, \
+ { 639,12}, { 351,11}, { 703,10}, { 1407,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,10}, { 1663,12}, { 447,11}, { 895,10}, \
+ { 1791, 9}, { 3583,12}, { 479,11}, { 959,10}, \
+ { 1919,14}, { 127,13}, { 255,12}, { 511,11}, \
+ { 1023,12}, { 575,11}, { 1151,13}, { 319,12}, \
+ { 639,11}, { 1279,12}, { 703,11}, { 1407,10}, \
+ { 2815,13}, { 383,12}, { 767,11}, { 1535,12}, \
+ { 831,11}, { 1663,13}, { 447,12}, { 895,11}, \
+ { 1791,12}, { 959,11}, { 1919,14}, { 255,13}, \
+ { 511,12}, { 1023,13}, { 575,12}, { 1151,13}, \
+ { 639,12}, { 1279,13}, { 703,12}, { 1407,11}, \
+ { 2815,14}, { 383,13}, { 767,12}, { 1535,13}, \
+ { 831,12}, { 1663,13}, { 895,12}, { 1791,11}, \
+ { 3583,13}, { 959,12}, { 1919,15}, { 255,14}, \
+ { 511,13}, { 1023,12}, { 2047,13}, { 1151,14}, \
+ { 639,13}, { 1279,12}, { 2559,13}, { 1407,12}, \
+ { 2815,14}, { 767,13}, { 1663,14}, { 895,13}, \
+ { 1791,12}, { 3583,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 201
+#define SQR_FFT_THRESHOLD 1728
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 34
+#define MULLO_MUL_N_THRESHOLD 3176
+
+#define DC_DIV_QR_THRESHOLD 39
+#define DC_DIVAPPR_Q_THRESHOLD 151
+#define DC_BDIV_QR_THRESHOLD 44
+#define DC_BDIV_Q_THRESHOLD 107
+
+#define INV_MULMOD_BNM1_THRESHOLD 14
+#define INV_NEWTON_THRESHOLD 163
+#define INV_APPR_THRESHOLD 154
+
+#define BINV_NEWTON_THRESHOLD 171
+#define REDC_1_TO_REDC_N_THRESHOLD 46
+
+#define MU_DIV_QR_THRESHOLD 792
+#define MU_DIVAPPR_Q_THRESHOLD 807
+#define MUPI_DIV_QR_THRESHOLD 81
+#define MU_BDIV_QR_THRESHOLD 654
+#define MU_BDIV_Q_THRESHOLD 792
+
+#define POWM_SEC_TABLE 3,19,194,946,2424
+
+#define MATRIX22_STRASSEN_THRESHOLD 17
+#define HGCD_THRESHOLD 117
+#define HGCD_APPR_THRESHOLD 145
+#define HGCD_REDUCE_THRESHOLD 1329
+#define GCD_DC_THRESHOLD 318
+#define GCDEXT_DC_THRESHOLD 265
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 17
+#define GET_STR_PRECOMPUTE_THRESHOLD 35
+#define SET_STR_DC_THRESHOLD 1015
+#define SET_STR_PRECOMPUTE_THRESHOLD 2047
+
+#define FAC_DSC_THRESHOLD 330
+#define FAC_ODD_THRESHOLD 23
diff --git a/gmp/mpn/sh/add_n.asm b/gmp/mpn/sh/add_n.asm
new file mode 100644
index 0000000000..79d17d0129
--- /dev/null
+++ b/gmp/mpn/sh/add_n.asm
@@ -0,0 +1,59 @@
+dnl SH mpn_add_n -- Add two limb vectors of the same length > 0 and store sum
+dnl in a third limb vector.
+
+dnl Copyright 1995, 1997, 2000, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rp r4
+C up r5
+C vp r6
+C n r7
+
+changecom(blah) C disable # to make all C comments below work
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+ mov #0,r3 C clear cy save reg
+
+L(top): mov.l @r5+,r1
+ mov.l @r6+,r2
+ shlr r3 C restore cy
+ addc r2,r1
+ movt r3 C save cy
+ mov.l r1,@r4
+ dt r7
+ bf.s L(top)
+ add #4,r4
+
+ rts
+ mov r3,r0 C return carry-out from most significant limb
+EPILOGUE()
diff --git a/gmp/mpn/sh/sh2/addmul_1.asm b/gmp/mpn/sh/sh2/addmul_1.asm
new file mode 100644
index 0000000000..c914b29541
--- /dev/null
+++ b/gmp/mpn/sh/sh2/addmul_1.asm
@@ -0,0 +1,65 @@
+dnl SH2 mpn_addmul_1 -- Multiply a limb vector with a limb and add the result
+dnl to a second limb vector.
+
+dnl Copyright 1995, 2000, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r4
+C s1_ptr r5
+C size r6
+C s2_limb r7
+
+changecom(blah) C disable # to make all C comments below work
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ mov #0,r2 C cy_limb = 0
+ mov #0,r0 C Keep r0 = 0 for entire loop
+ clrt
+
+L(top): mov.l @r5+,r3
+ dmulu.l r3,r7
+ sts macl,r1
+ addc r2,r1 C lo_prod += old cy_limb
+ sts mach,r2 C new cy_limb = hi_prod
+ mov.l @r4,r3
+ addc r0,r2 C cy_limb += T, T = 0
+ addc r3,r1
+ addc r0,r2 C cy_limb += T, T = 0
+ dt r6
+ mov.l r1,@r4
+ bf.s L(top)
+ add #4,r4
+
+ rts
+ mov r2,r0
+EPILOGUE()
diff --git a/gmp/mpn/sh/sh2/mul_1.asm b/gmp/mpn/sh/sh2/mul_1.asm
new file mode 100644
index 0000000000..83548a6953
--- /dev/null
+++ b/gmp/mpn/sh/sh2/mul_1.asm
@@ -0,0 +1,62 @@
+dnl SH2 mpn_mul_1 -- Multiply a limb vector with a limb and store the result
+dnl in a second limb vector.
+
+dnl Copyright 1995, 2000, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r4
+C s1_ptr r5
+C size r6
+C s2_limb r7
+
+changecom(blah) C disable # to make all C comments below work
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ mov #0,r2 C cy_limb = 0
+ mov #0,r0 C Keep r0 = 0 for entire loop
+ clrt
+
+L(top): mov.l @r5+,r3
+ dmulu.l r3,r7
+ sts macl,r1
+ addc r2,r1
+ sts mach,r2
+ addc r0,r2 C propagate carry to cy_limb (dt clobbers T)
+ dt r6
+ mov.l r1,@r4
+ bf.s L(top)
+ add #4,r4
+
+ rts
+ mov r2,r0
+EPILOGUE()
diff --git a/gmp/mpn/sh/sh2/submul_1.asm b/gmp/mpn/sh/sh2/submul_1.asm
new file mode 100644
index 0000000000..bef2abd9b2
--- /dev/null
+++ b/gmp/mpn/sh/sh2/submul_1.asm
@@ -0,0 +1,65 @@
+dnl SH2 mpn_submul_1 -- Multiply a limb vector with a limb and subtract the
+dnl result from a second limb vector.
+
+dnl Copyright 1995, 2000, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr r4
+C s1_ptr r5
+C size r6
+C s2_limb r7
+
+changecom(blah) C disable # to make all C comments below work
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ mov #0,r2 C cy_limb = 0
+ mov #0,r0 C Keep r0 = 0 for entire loop
+ clrt
+
+L(top): mov.l @r5+,r3
+ dmulu.l r3,r7
+ sts macl,r1
+ addc r2,r1 C lo_prod += old cy_limb
+ sts mach,r2 C new cy_limb = hi_prod
+ mov.l @r4,r3
+ addc r0,r2 C cy_limb += T, T = 0
+ subc r1,r3
+ addc r0,r2 C cy_limb += T, T = 0
+ dt r6
+ mov.l r3,@r4
+ bf.s L(top)
+ add #4,r4
+
+ rts
+ mov r2,r0
+EPILOGUE()
diff --git a/gmp/mpn/sh/sub_n.asm b/gmp/mpn/sh/sub_n.asm
new file mode 100644
index 0000000000..465bc806fa
--- /dev/null
+++ b/gmp/mpn/sh/sub_n.asm
@@ -0,0 +1,59 @@
+dnl SH mpn_sub_n -- Subtract two limb vectors of the same length > 0 and store
+dnl difference in a third limb vector.
+
+dnl Copyright 1995, 1997, 2000, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rp r4
+C up r5
+C vp r6
+C n r7
+
+changecom(blah) C disable # to make all C comments below work
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ mov #0,r3 C clear cy save reg
+
+L(top): mov.l @r5+,r1
+ mov.l @r6+,r2
+ shlr r3 C restore cy
+ subc r2,r1
+ movt r3 C save cy
+ mov.l r1,@r4
+ dt r7
+ bf.s L(top)
+ add #4,r4
+
+ rts
+ mov r3,r0 C return carry-out from most significant limb
+EPILOGUE()
diff --git a/gmp/mpn/sparc32/README b/gmp/mpn/sparc32/README
new file mode 100644
index 0000000000..f2dd1160f7
--- /dev/null
+++ b/gmp/mpn/sparc32/README
@@ -0,0 +1,71 @@
+Copyright 1996, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+This directory contains mpn functions for various SPARC chips. Code that
+runs only on version 8 SPARC implementations, is in the v8 subdirectory.
+
+RELEVANT OPTIMIZATION ISSUES
+
+ Load and Store timing
+
+On most early SPARC implementations, the ST instructions takes multiple
+cycles, while a STD takes just a single cycle more than an ST. For the CPUs
+in SPARCstation I and II, the times are 3 and 4 cycles, respectively.
+Therefore, combining two ST instructions into a STD when possible is a
+significant optimization.
+
+Later SPARC implementations have single cycle ST.
+
+For SuperSPARC, we can perform just one memory instruction per cycle, even
+if up to two integer instructions can be executed in its pipeline. For
+programs that perform so many memory operations that there are not enough
+non-memory operations to issue in parallel with all memory operations, using
+LDD and STD when possible helps.
+
+UltraSPARC-1/2 has very slow integer multiplication. In the v9 subdirectory,
+we therefore use floating-point multiplication.
+
+STATUS
+
+1. On a SuperSPARC, mpn_lshift and mpn_rshift run at 3 cycles/limb, or 2.5
+ cycles/limb asymptotically. We could optimize speed for special counts
+ by using ADDXCC.
+
+2. On a SuperSPARC, mpn_add_n and mpn_sub_n runs at 2.5 cycles/limb, or 2
+ cycles/limb asymptotically.
+
+3. mpn_mul_1 runs at what is believed to be optimal speed.
+
+4. On SuperSPARC, mpn_addmul_1 and mpn_submul_1 could both be improved by a
+ cycle by avoiding one of the add instructions. See a29k/addmul_1.
+
+The speed of the code for other SPARC implementations is uncertain.
diff --git a/gmp/mpn/sparc32/add_n.asm b/gmp/mpn/sparc32/add_n.asm
new file mode 100644
index 0000000000..8549195d92
--- /dev/null
+++ b/gmp/mpn/sparc32/add_n.asm
@@ -0,0 +1,245 @@
+dnl SPARC mpn_add_n -- Add two limb vectors of the same length > 0 and store
+dnl sum in a third limb vector.
+
+dnl Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(res_ptr,%o0)
+define(s1_ptr,%o1)
+define(s2_ptr,%o2)
+define(n,%o3)
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+ xor s2_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L(1) C branch if alignment differs
+ nop
+C ** V1a **
+L(0): andcc res_ptr,4,%g0 C res_ptr unaligned? Side effect: cy=0
+ be L(v1) C if no, branch
+ nop
+C Add least significant limb separately to align res_ptr and s2_ptr
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add n,-1,n
+ addcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+L(v1): addx %g0,%g0,%o4 C save cy in register
+ cmp n,2 C if n < 2 ...
+ bl L(end2) C ... branch to tail code
+ subcc %g0,%o4,%g0 C restore cy
+
+ ld [s1_ptr+0],%g4
+ addcc n,-10,n
+ ld [s1_ptr+4],%g1
+ ldd [s2_ptr+0],%g2
+ blt L(fin1)
+ subcc %g0,%o4,%g0 C restore cy
+C Add blocks of 8 limbs until less than 8 limbs remain
+L(loop1):
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+16],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+20],%g1
+ ldd [s2_ptr+16],%g2
+ std %o4,[res_ptr+8]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+24],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+28],%g1
+ ldd [s2_ptr+24],%g2
+ std %o4,[res_ptr+16]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+32],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+36],%g1
+ ldd [s2_ptr+32],%g2
+ std %o4,[res_ptr+24]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-8,n
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge L(loop1)
+ subcc %g0,%o4,%g0 C restore cy
+
+L(fin1):
+ addcc n,8-2,n
+ blt L(end1)
+ subcc %g0,%o4,%g0 C restore cy
+C Add blocks of 2 limbs until less than 2 limbs remain
+L(loope1):
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-2,n
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge L(loope1)
+ subcc %g0,%o4,%g0 C restore cy
+L(end1):
+ addxcc %g4,%g2,%o4
+ addxcc %g1,%g3,%o5
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 C save cy in register
+
+ andcc n,1,%g0
+ be L(ret1)
+ subcc %g0,%o4,%g0 C restore cy
+C Add last limb
+ ld [s1_ptr+8],%g4
+ ld [s2_ptr+8],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[res_ptr+8]
+
+L(ret1):
+ retl
+ addx %g0,%g0,%o0 C return carry-out from most sign. limb
+
+L(1): xor s1_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L(2)
+ nop
+C ** V1b **
+ mov s2_ptr,%g1
+ mov s1_ptr,s2_ptr
+ b L(0)
+ mov %g1,s1_ptr
+
+C ** V2 **
+C If we come here, the alignment of s1_ptr and res_ptr as well as the
+C alignment of s2_ptr and res_ptr differ. Since there are only two ways
+C things can be aligned (that we care about) we now know that the alignment
+C of s1_ptr and s2_ptr are the same.
+
+L(2): cmp n,1
+ be L(jone)
+ nop
+ andcc s1_ptr,4,%g0 C s1_ptr unaligned? Side effect: cy=0
+ be L(v2) C if no, branch
+ nop
+C Add least significant limb separately to align s1_ptr and s2_ptr
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add n,-1,n
+ addcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+
+L(v2): addx %g0,%g0,%o4 C save cy in register
+ addcc n,-8,n
+ blt L(fin2)
+ subcc %g0,%o4,%g0 C restore cy
+C Add blocks of 8 limbs until less than 8 limbs remain
+L(loop2):
+ ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ ldd [s1_ptr+8],%g2
+ ldd [s2_ptr+8],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+8]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+12]
+ ldd [s1_ptr+16],%g2
+ ldd [s2_ptr+16],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+16]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+20]
+ ldd [s1_ptr+24],%g2
+ ldd [s2_ptr+24],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+24]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+28]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-8,n
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge L(loop2)
+ subcc %g0,%o4,%g0 C restore cy
+
+L(fin2):
+ addcc n,8-2,n
+ blt L(end2)
+ subcc %g0,%o4,%g0 C restore cy
+L(loope2):
+ ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-2,n
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge L(loope2)
+ subcc %g0,%o4,%g0 C restore cy
+L(end2):
+ andcc n,1,%g0
+ be L(ret2)
+ subcc %g0,%o4,%g0 C restore cy
+C Add last limb
+L(jone):
+ ld [s1_ptr],%g4
+ ld [s2_ptr],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+
+L(ret2):
+ retl
+ addx %g0,%g0,%o0 C return carry-out from most sign. limb
+EPILOGUE(mpn_add_n)
diff --git a/gmp/mpn/sparc32/addmul_1.asm b/gmp/mpn/sparc32/addmul_1.asm
new file mode 100644
index 0000000000..92d5d78d51
--- /dev/null
+++ b/gmp/mpn/sparc32/addmul_1.asm
@@ -0,0 +1,155 @@
+dnl SPARC mpn_addmul_1 -- Multiply a limb vector with a limb and add the
+dnl result to a second limb vector.
+
+dnl Copyright 1992-1994, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr o0
+C s1_ptr o1
+C size o2
+C s2_limb o3
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ C Make S1_PTR and RES_PTR point at the end of their blocks
+ C and put (- 4 x SIZE) in index/loop counter.
+ sll %o2,2,%o2
+ add %o0,%o2,%o4 C RES_PTR in o4 since o0 is retval
+ add %o1,%o2,%o1
+ sub %g0,%o2,%o2
+
+ cmp %o3,0xfff
+ bgu L(large)
+ nop
+
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ b L(0)
+ add %o4,-4,%o4
+L(loop0):
+ addcc %o5,%g1,%g1
+ ld [%o1+%o2],%o5
+ addx %o0,%g0,%o0
+ st %g1,[%o4+%o2]
+L(0): wr %g0,%o3,%y
+ sra %o5,31,%g2
+ and %o3,%g2,%g2
+ andcc %g1,0,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,0,%g1
+ sra %g1,20,%g4
+ sll %g1,12,%g1
+ rd %y,%g3
+ srl %g3,20,%g3
+ or %g1,%g3,%g1
+
+ addcc %g1,%o0,%g1
+ addx %g2,%g4,%o0 C add sign-compensation and cy to hi limb
+ addcc %o2,4,%o2 C loop counter
+ bne L(loop0)
+ ld [%o4+%o2],%o5
+
+ addcc %o5,%g1,%g1
+ addx %o0,%g0,%o0
+ retl
+ st %g1,[%o4+%o2]
+
+L(large):
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ sra %o3,31,%g4 C g4 = mask of ones iff S2_LIMB < 0
+ b L(1)
+ add %o4,-4,%o4
+L(loop):
+ addcc %o5,%g3,%g3
+ ld [%o1+%o2],%o5
+ addx %o0,%g0,%o0
+ st %g3,[%o4+%o2]
+L(1): wr %g0,%o5,%y
+ and %o5,%g4,%g2
+ andcc %g0,%g0,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%g0,%g1
+ rd %y,%g3
+ addcc %g3,%o0,%g3
+ addx %g2,%g1,%o0
+ addcc %o2,4,%o2
+ bne L(loop)
+ ld [%o4+%o2],%o5
+
+ addcc %o5,%g3,%g3
+ addx %o0,%g0,%o0
+ retl
+ st %g3,[%o4+%o2]
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/sparc32/gmp-mparam.h b/gmp/mpn/sparc32/gmp-mparam.h
new file mode 100644
index 0000000000..a3bc612543
--- /dev/null
+++ b/gmp/mpn/sparc32/gmp-mparam.h
@@ -0,0 +1,67 @@
+/* SPARC v7 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* Generated by tuneup.c, 2002-03-13, gcc 2.95, Weitek 8701 */
+
+#define MUL_TOOM22_THRESHOLD 8
+#define MUL_TOOM33_THRESHOLD 466
+
+#define SQR_BASECASE_THRESHOLD 4
+#define SQR_TOOM2_THRESHOLD 16
+#define SQR_TOOM3_THRESHOLD 258
+
+#define DIV_SB_PREINV_THRESHOLD 4
+#define DIV_DC_THRESHOLD 28
+#define POWM_THRESHOLD 28
+
+#define GCD_ACCEL_THRESHOLD 3
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD 3
+#define DIVREM_1_UNNORM_THRESHOLD 4
+#define MOD_1_NORM_THRESHOLD 3
+#define MOD_1_UNNORM_THRESHOLD 4
+#define USE_PREINV_DIVREM_1 1
+#define USE_PREINV_MOD_1 1
+#define DIVREM_2_THRESHOLD 0 /* always */
+#define DIVEXACT_1_THRESHOLD 120
+#define MODEXACT_1_ODD_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define GET_STR_DC_THRESHOLD 21
+#define GET_STR_PRECOMPUTE_THRESHOLD 25
+#define SET_STR_THRESHOLD 1012
+
+#define MUL_FFT_TABLE { 272, 672, 1152, 3584, 10240, 24576, 0 }
+#define MUL_FFT_MODF_THRESHOLD 264
+#define MUL_FFT_THRESHOLD 2304
+
+#define SQR_FFT_TABLE { 304, 736, 1152, 3584, 10240, 24576, 0 }
+#define SQR_FFT_MODF_THRESHOLD 248
+#define SQR_FFT_THRESHOLD 2304
diff --git a/gmp/mpn/sparc32/lshift.asm b/gmp/mpn/sparc32/lshift.asm
new file mode 100644
index 0000000000..8321343d6b
--- /dev/null
+++ b/gmp/mpn/sparc32/lshift.asm
@@ -0,0 +1,105 @@
+dnl SPARC mpn_lshift -- Shift a number left.
+
+dnl Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr %o0
+C src_ptr %o1
+C size %o2
+C cnt %o3
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ sll %o2,2,%g1
+ add %o1,%g1,%o1 C make %o1 point at end of src
+ ld [%o1-4],%g2 C load first limb
+ sub %g0,%o3,%o5 C negate shift count
+ add %o0,%g1,%o0 C make %o0 point at end of res
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 C number of limbs in first loop
+ srl %g2,%o5,%g1 C compute function result
+ be L(0) C if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 C adjust count for main loop
+
+L(loop0):
+ ld [%o1-8],%g3
+ add %o0,-4,%o0
+ add %o1,-4,%o1
+ addcc %g4,-1,%g4
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne L(loop0)
+ st %o4,[%o0+0]
+
+L(0): tst %o2
+ be L(end)
+ nop
+
+L(loop):
+ ld [%o1-8],%g3
+ add %o0,-16,%o0
+ addcc %o2,-4,%o2
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+
+ ld [%o1-12],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+12]
+ srl %g2,%o5,%g1
+
+ ld [%o1-16],%g3
+ sll %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0+8]
+ srl %g3,%o5,%g1
+
+ ld [%o1-20],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+4]
+ srl %g2,%o5,%g1
+
+ add %o1,-16,%o1
+ or %g4,%g1,%g4
+ bne L(loop)
+ st %g4,[%o0+0]
+
+L(end): sll %g2,%o3,%g2
+ st %g2,[%o0-4]
+ retl
+ ld [%sp+80],%o0
+EPILOGUE(mpn_lshift)
diff --git a/gmp/mpn/sparc32/mul_1.asm b/gmp/mpn/sparc32/mul_1.asm
new file mode 100644
index 0000000000..42b4168be1
--- /dev/null
+++ b/gmp/mpn/sparc32/mul_1.asm
@@ -0,0 +1,146 @@
+dnl SPARC mpn_mul_1 -- Multiply a limb vector with a limb and store
+dnl the result in a second limb vector.
+
+dnl Copyright 1992-1994, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr o0
+C s1_ptr o1
+C size o2
+C s2_limb o3
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ C Make S1_PTR and RES_PTR point at the end of their blocks
+ C and put (- 4 x SIZE) in index/loop counter.
+ sll %o2,2,%o2
+ add %o0,%o2,%o4 C RES_PTR in o4 since o0 is retval
+ add %o1,%o2,%o1
+ sub %g0,%o2,%o2
+
+ cmp %o3,0xfff
+ bgu L(large)
+ nop
+
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ b L(0)
+ add %o4,-4,%o4
+L(loop0):
+ st %g1,[%o4+%o2]
+L(0): wr %g0,%o3,%y
+ sra %o5,31,%g2
+ and %o3,%g2,%g2
+ andcc %g1,0,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,0,%g1
+ sra %g1,20,%g4
+ sll %g1,12,%g1
+ rd %y,%g3
+ srl %g3,20,%g3
+ or %g1,%g3,%g1
+
+ addcc %g1,%o0,%g1
+ addx %g2,%g4,%o0 C add sign-compensation and cy to hi limb
+ addcc %o2,4,%o2 C loop counter
+ bne,a L(loop0)
+ ld [%o1+%o2],%o5
+
+ retl
+ st %g1,[%o4+%o2]
+
+
+L(large):
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ sra %o3,31,%g4 C g4 = mask of ones iff S2_LIMB < 0
+ b L(1)
+ add %o4,-4,%o4
+L(loop):
+ st %g3,[%o4+%o2]
+L(1): wr %g0,%o5,%y
+ and %o5,%g4,%g2 C g2 = S1_LIMB iff S2_LIMB < 0, else 0
+ andcc %g0,%g0,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%g0,%g1
+ rd %y,%g3
+ addcc %g3,%o0,%g3
+ addx %g2,%g1,%o0 C add sign-compensation and cy to hi limb
+ addcc %o2,4,%o2 C loop counter
+ bne,a L(loop)
+ ld [%o1+%o2],%o5
+
+ retl
+ st %g3,[%o4+%o2]
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/sparc32/rshift.asm b/gmp/mpn/sparc32/rshift.asm
new file mode 100644
index 0000000000..e1554766fe
--- /dev/null
+++ b/gmp/mpn/sparc32/rshift.asm
@@ -0,0 +1,102 @@
+dnl SPARC mpn_rshift -- Shift a number right.
+
+dnl Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr %o0
+C src_ptr %o1
+C size %o2
+C cnt %o3
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ ld [%o1],%g2 C load first limb
+ sub %g0,%o3,%o5 C negate shift count
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 C number of limbs in first loop
+ sll %g2,%o5,%g1 C compute function result
+ be L(0) C if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 C adjust count for main loop
+
+L(loop0):
+ ld [%o1+4],%g3
+ add %o0,4,%o0
+ add %o1,4,%o1
+ addcc %g4,-1,%g4
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne L(loop0)
+ st %o4,[%o0-4]
+
+L(0): tst %o2
+ be L(end)
+ nop
+
+L(loop):
+ ld [%o1+4],%g3
+ add %o0,16,%o0
+ addcc %o2,-4,%o2
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+
+ ld [%o1+8],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-16]
+ sll %g2,%o5,%g1
+
+ ld [%o1+12],%g3
+ srl %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0-12]
+ sll %g3,%o5,%g1
+
+ ld [%o1+16],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-8]
+ sll %g2,%o5,%g1
+
+ add %o1,16,%o1
+ or %g4,%g1,%g4
+ bne L(loop)
+ st %g4,[%o0-4]
+
+L(end): srl %g2,%o3,%g2
+ st %g2,[%o0-0]
+ retl
+ ld [%sp+80],%o0
+EPILOGUE(mpn_rshift)
diff --git a/gmp/mpn/sparc32/sparc-defs.m4 b/gmp/mpn/sparc32/sparc-defs.m4
new file mode 100644
index 0000000000..5a0d425204
--- /dev/null
+++ b/gmp/mpn/sparc32/sparc-defs.m4
@@ -0,0 +1,79 @@
+divert(-1)
+
+dnl m4 macros for SPARC assembler (32 and 64 bit).
+
+
+dnl Copyright 2002, 2011, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+changecom(;) dnl cannot use default # since that's used in REGISTER decls
+
+
+dnl Usage: REGISTER(reg,attr)
+dnl
+dnl Give a ".register reg,attr" directive, if the assembler supports it.
+dnl HAVE_REGISTER comes from the GMP_ASM_SPARC_REGISTER configure test.
+
+define(REGISTER,
+m4_assert_numargs(2)
+m4_assert_defined(`HAVE_REGISTER')
+`ifelse(HAVE_REGISTER,yes,
+`.register `$1',`$2'')')
+
+
+C Testing mechanism for running newer code on older processors
+ifdef(`FAKE_T3',`
+ include_mpn(`sparc64/ultrasparct3/missing.m4')
+',`
+ define(`addxccc', ``addxccc' $1, $2, $3')
+ define(`addxc', ``addxc' $1, $2, $3')
+ define(`umulxhi', ``umulxhi' $1, $2, $3')
+ define(`lzcnt', ``lzd' $1, $2')
+')
+
+dnl Usage: LEA64(symbol,reg,pic_reg)
+dnl
+dnl Use whatever 64-bit code sequence is appropriate to load "symbol" into
+dnl register "reg", potentially using register "pic_reg" to perform the
+dnl calculations.
+
+define(LEA64,
+m4_assert_numargs(3)
+m4_assert_defined(`HAVE_GOTDATA')
+`ifdef(`PIC',`
+ rd %pc, %`$2'
+ sethi %hi(_GLOBAL_OFFSET_TABLE_+4), %`$3'
+ add %`$3', %lo(_GLOBAL_OFFSET_TABLE_+8), %`$3'
+ add %`$2', %`$3', %`$3'
+ sethi %hi(`$1'), %`$2'
+ or %`$2', %lo(`$1'), %`$2'
+ ldx [%`$3' + %`$2'], %`$2'',`
+ setx `$1', %`$3', %`$2'')')
+
+divert
diff --git a/gmp/mpn/sparc32/sub_n.asm b/gmp/mpn/sparc32/sub_n.asm
new file mode 100644
index 0000000000..24a576d82b
--- /dev/null
+++ b/gmp/mpn/sparc32/sub_n.asm
@@ -0,0 +1,335 @@
+dnl SPARC mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+dnl store difference in a third limb vector.
+
+dnl Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(res_ptr,%o0)
+define(s1_ptr,%o1)
+define(s2_ptr,%o2)
+define(n,%o3)
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ xor s2_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L(1) C branch if alignment differs
+ nop
+C ** V1a **
+ andcc res_ptr,4,%g0 C res_ptr unaligned? Side effect: cy=0
+ be L(v1) C if no, branch
+ nop
+C Add least significant limb separately to align res_ptr and s2_ptr
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add n,-1,n
+ subcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+L(v1): addx %g0,%g0,%o4 C save cy in register
+ cmp n,2 C if n < 2 ...
+ bl L(end2) C ... branch to tail code
+ subcc %g0,%o4,%g0 C restore cy
+
+ ld [s1_ptr+0],%g4
+ addcc n,-10,n
+ ld [s1_ptr+4],%g1
+ ldd [s2_ptr+0],%g2
+ blt L(fin1)
+ subcc %g0,%o4,%g0 C restore cy
+C Add blocks of 8 limbs until less than 8 limbs remain
+L(loop1):
+ subxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ subxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ subxcc %g4,%g2,%o4
+ ld [s1_ptr+16],%g4
+ subxcc %g1,%g3,%o5
+ ld [s1_ptr+20],%g1
+ ldd [s2_ptr+16],%g2
+ std %o4,[res_ptr+8]
+ subxcc %g4,%g2,%o4
+ ld [s1_ptr+24],%g4
+ subxcc %g1,%g3,%o5
+ ld [s1_ptr+28],%g1
+ ldd [s2_ptr+24],%g2
+ std %o4,[res_ptr+16]
+ subxcc %g4,%g2,%o4
+ ld [s1_ptr+32],%g4
+ subxcc %g1,%g3,%o5
+ ld [s1_ptr+36],%g1
+ ldd [s2_ptr+32],%g2
+ std %o4,[res_ptr+24]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-8,n
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge L(loop1)
+ subcc %g0,%o4,%g0 C restore cy
+
+L(fin1):
+ addcc n,8-2,n
+ blt L(end1)
+ subcc %g0,%o4,%g0 C restore cy
+C Add blocks of 2 limbs until less than 2 limbs remain
+L(loope1):
+ subxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ subxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-2,n
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge L(loope1)
+ subcc %g0,%o4,%g0 C restore cy
+L(end1):
+ subxcc %g4,%g2,%o4
+ subxcc %g1,%g3,%o5
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 C save cy in register
+
+ andcc n,1,%g0
+ be L(ret1)
+ subcc %g0,%o4,%g0 C restore cy
+C Add last limb
+ ld [s1_ptr+8],%g4
+ ld [s2_ptr+8],%g2
+ subxcc %g4,%g2,%o4
+ st %o4,[res_ptr+8]
+
+L(ret1):
+ retl
+ addx %g0,%g0,%o0 C return carry-out from most sign. limb
+
+L(1): xor s1_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L(2)
+ nop
+C ** V1b **
+ andcc res_ptr,4,%g0 C res_ptr unaligned? Side effect: cy=0
+ be L(v1b) C if no, branch
+ nop
+C Add least significant limb separately to align res_ptr and s1_ptr
+ ld [s2_ptr],%g4
+ add s2_ptr,4,s2_ptr
+ ld [s1_ptr],%g2
+ add s1_ptr,4,s1_ptr
+ add n,-1,n
+ subcc %g2,%g4,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+L(v1b): addx %g0,%g0,%o4 C save cy in register
+ cmp n,2 C if n < 2 ...
+ bl L(end2) C ... branch to tail code
+ subcc %g0,%o4,%g0 C restore cy
+
+ ld [s2_ptr+0],%g4
+ addcc n,-10,n
+ ld [s2_ptr+4],%g1
+ ldd [s1_ptr+0],%g2
+ blt L(fin1b)
+ subcc %g0,%o4,%g0 C restore cy
+C Add blocks of 8 limbs until less than 8 limbs remain
+L(loop1b):
+ subxcc %g2,%g4,%o4
+ ld [s2_ptr+8],%g4
+ subxcc %g3,%g1,%o5
+ ld [s2_ptr+12],%g1
+ ldd [s1_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ subxcc %g2,%g4,%o4
+ ld [s2_ptr+16],%g4
+ subxcc %g3,%g1,%o5
+ ld [s2_ptr+20],%g1
+ ldd [s1_ptr+16],%g2
+ std %o4,[res_ptr+8]
+ subxcc %g2,%g4,%o4
+ ld [s2_ptr+24],%g4
+ subxcc %g3,%g1,%o5
+ ld [s2_ptr+28],%g1
+ ldd [s1_ptr+24],%g2
+ std %o4,[res_ptr+16]
+ subxcc %g2,%g4,%o4
+ ld [s2_ptr+32],%g4
+ subxcc %g3,%g1,%o5
+ ld [s2_ptr+36],%g1
+ ldd [s1_ptr+32],%g2
+ std %o4,[res_ptr+24]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-8,n
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge L(loop1b)
+ subcc %g0,%o4,%g0 C restore cy
+
+L(fin1b):
+ addcc n,8-2,n
+ blt L(end1b)
+ subcc %g0,%o4,%g0 C restore cy
+C Add blocks of 2 limbs until less than 2 limbs remain
+L(loope1b):
+ subxcc %g2,%g4,%o4
+ ld [s2_ptr+8],%g4
+ subxcc %g3,%g1,%o5
+ ld [s2_ptr+12],%g1
+ ldd [s1_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-2,n
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge L(loope1b)
+ subcc %g0,%o4,%g0 C restore cy
+L(end1b):
+ subxcc %g2,%g4,%o4
+ subxcc %g3,%g1,%o5
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 C save cy in register
+
+ andcc n,1,%g0
+ be L(ret1b)
+ subcc %g0,%o4,%g0 C restore cy
+C Add last limb
+ ld [s2_ptr+8],%g4
+ ld [s1_ptr+8],%g2
+ subxcc %g2,%g4,%o4
+ st %o4,[res_ptr+8]
+
+L(ret1b):
+ retl
+ addx %g0,%g0,%o0 C return carry-out from most sign. limb
+
+C ** V2 **
+C If we come here, the alignment of s1_ptr and res_ptr as well as the
+C alignment of s2_ptr and res_ptr differ. Since there are only two ways
+C things can be aligned (that we care about) we now know that the alignment
+C of s1_ptr and s2_ptr are the same.
+
+L(2): cmp n,1
+ be L(jone)
+ nop
+ andcc s1_ptr,4,%g0 C s1_ptr unaligned? Side effect: cy=0
+ be L(v2) C if no, branch
+ nop
+C Add least significant limb separately to align s1_ptr and s2_ptr
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add n,-1,n
+ subcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+
+L(v2): addx %g0,%g0,%o4 C save cy in register
+ addcc n,-8,n
+ blt L(fin2)
+ subcc %g0,%o4,%g0 C restore cy
+C Add blocks of 8 limbs until less than 8 limbs remain
+L(loop2):
+ ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ subxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ ldd [s1_ptr+8],%g2
+ ldd [s2_ptr+8],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[res_ptr+8]
+ subxcc %g3,%o5,%g3
+ st %g3,[res_ptr+12]
+ ldd [s1_ptr+16],%g2
+ ldd [s2_ptr+16],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[res_ptr+16]
+ subxcc %g3,%o5,%g3
+ st %g3,[res_ptr+20]
+ ldd [s1_ptr+24],%g2
+ ldd [s2_ptr+24],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[res_ptr+24]
+ subxcc %g3,%o5,%g3
+ st %g3,[res_ptr+28]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-8,n
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge L(loop2)
+ subcc %g0,%o4,%g0 C restore cy
+
+L(fin2):
+ addcc n,8-2,n
+ blt L(end2)
+ subcc %g0,%o4,%g0 C restore cy
+L(loope2):
+ ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ subxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ subxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ addx %g0,%g0,%o4 C save cy in register
+ addcc n,-2,n
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge L(loope2)
+ subcc %g0,%o4,%g0 C restore cy
+L(end2):
+ andcc n,1,%g0
+ be L(ret2)
+ subcc %g0,%o4,%g0 C restore cy
+C Add last limb
+L(jone):
+ ld [s1_ptr],%g4
+ ld [s2_ptr],%g2
+ subxcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+
+L(ret2):
+ retl
+ addx %g0,%g0,%o0 C return carry-out from most sign. limb
+EPILOGUE(mpn_sub_n)
diff --git a/gmp/mpn/sparc32/submul_1.asm b/gmp/mpn/sparc32/submul_1.asm
new file mode 100644
index 0000000000..73f9377006
--- /dev/null
+++ b/gmp/mpn/sparc32/submul_1.asm
@@ -0,0 +1,155 @@
+dnl SPARC mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+dnl the result from a second limb vector.
+
+dnl Copyright 1992-1994, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr o0
+C s1_ptr o1
+C size o2
+C s2_limb o3
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ C Make S1_PTR and RES_PTR point at the end of their blocks
+ C and put (- 4 x SIZE) in index/loop counter.
+ sll %o2,2,%o2
+ add %o0,%o2,%o4 C RES_PTR in o4 since o0 is retval
+ add %o1,%o2,%o1
+ sub %g0,%o2,%o2
+
+ cmp %o3,0xfff
+ bgu L(large)
+ nop
+
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ b L(0)
+ add %o4,-4,%o4
+L(loop0):
+ subcc %o5,%g1,%g1
+ ld [%o1+%o2],%o5
+ addx %o0,%g0,%o0
+ st %g1,[%o4+%o2]
+L(0): wr %g0,%o3,%y
+ sra %o5,31,%g2
+ and %o3,%g2,%g2
+ andcc %g1,0,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,%o5,%g1
+ mulscc %g1,0,%g1
+ sra %g1,20,%g4
+ sll %g1,12,%g1
+ rd %y,%g3
+ srl %g3,20,%g3
+ or %g1,%g3,%g1
+
+ addcc %g1,%o0,%g1
+ addx %g2,%g4,%o0 C add sign-compensation and cy to hi limb
+ addcc %o2,4,%o2 C loop counter
+ bne L(loop0)
+ ld [%o4+%o2],%o5
+
+ subcc %o5,%g1,%g1
+ addx %o0,%g0,%o0
+ retl
+ st %g1,[%o4+%o2]
+
+L(large):
+ ld [%o1+%o2],%o5
+ mov 0,%o0
+ sra %o3,31,%g4 C g4 = mask of ones iff S2_LIMB < 0
+ b L(1)
+ add %o4,-4,%o4
+L(loop):
+ subcc %o5,%g3,%g3
+ ld [%o1+%o2],%o5
+ addx %o0,%g0,%o0
+ st %g3,[%o4+%o2]
+L(1): wr %g0,%o5,%y
+ and %o5,%g4,%g2
+ andcc %g0,%g0,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%o3,%g1
+ mulscc %g1,%g0,%g1
+ rd %y,%g3
+ addcc %g3,%o0,%g3
+ addx %g2,%g1,%o0
+ addcc %o2,4,%o2
+ bne L(loop)
+ ld [%o4+%o2],%o5
+
+ subcc %o5,%g3,%g3
+ addx %o0,%g0,%o0
+ retl
+ st %g3,[%o4+%o2]
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/sparc32/udiv.asm b/gmp/mpn/sparc32/udiv.asm
new file mode 100644
index 0000000000..23ab3de1db
--- /dev/null
+++ b/gmp/mpn/sparc32/udiv.asm
@@ -0,0 +1,167 @@
+dnl SPARC v7 __udiv_qrnnd division support, used from longlong.h.
+dnl This is for v7 CPUs with a floating-point unit.
+
+dnl Copyright 1993, 1994, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rem_ptr i0
+C n1 i1
+C n0 i2
+C d i3
+
+ASM_START()
+
+ifdef(`PIC',
+` TEXT
+L(getpc):
+ retl
+ nop')
+
+ TEXT
+ ALIGN(8)
+L(C0): .double 0r4294967296
+L(C1): .double 0r2147483648
+
+PROLOGUE(mpn_udiv_qrnnd)
+ save %sp,-104,%sp
+ st %i1,[%fp-8]
+ ld [%fp-8],%f10
+
+ifdef(`PIC',
+`L(pc): call L(getpc) C put address of this insn in %o7
+ ldd [%o7+L(C0)-L(pc)],%f8',
+` sethi %hi(L(C0)),%o7
+ ldd [%o7+%lo(L(C0))],%f8')
+
+ fitod %f10,%f4
+ cmp %i1,0
+ bge L(248)
+ mov %i0,%i5
+ faddd %f4,%f8,%f4
+L(248):
+ st %i2,[%fp-8]
+ ld [%fp-8],%f10
+ fmuld %f4,%f8,%f6
+ cmp %i2,0
+ bge L(249)
+ fitod %f10,%f2
+ faddd %f2,%f8,%f2
+L(249):
+ st %i3,[%fp-8]
+ faddd %f6,%f2,%f2
+ ld [%fp-8],%f10
+ cmp %i3,0
+ bge L(250)
+ fitod %f10,%f4
+ faddd %f4,%f8,%f4
+L(250):
+ fdivd %f2,%f4,%f2
+
+ifdef(`PIC',
+` ldd [%o7+L(C1)-L(pc)],%f4',
+` sethi %hi(L(C1)),%o7
+ ldd [%o7+%lo(L(C1))],%f4')
+
+ fcmped %f2,%f4
+ nop
+ fbge,a L(251)
+ fsubd %f2,%f4,%f2
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ b L(252)
+ ld [%fp-8],%i4
+L(251):
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ ld [%fp-8],%i4
+ sethi %hi(-2147483648),%g2
+ xor %i4,%g2,%i4
+L(252):
+ wr %g0,%i4,%y
+ sra %i3,31,%g2
+ and %i4,%g2,%g2
+ andcc %g0,0,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,%i3,%g1
+ mulscc %g1,0,%g1
+ add %g1,%g2,%i0
+ rd %y,%g3
+ subcc %i2,%g3,%o7
+ subxcc %i1,%i0,%g0
+ be L(253)
+ cmp %o7,%i3
+
+ add %i4,-1,%i0
+ add %o7,%i3,%o7
+ st %o7,[%i5]
+ ret
+ restore
+L(253):
+ blu L(246)
+ mov %i4,%i0
+ add %i4,1,%i0
+ sub %o7,%i3,%o7
+L(246):
+ st %o7,[%i5]
+ ret
+ restore
+EPILOGUE(mpn_udiv_qrnnd)
diff --git a/gmp/mpn/sparc32/udiv_nfp.asm b/gmp/mpn/sparc32/udiv_nfp.asm
new file mode 100644
index 0000000000..ebbb820639
--- /dev/null
+++ b/gmp/mpn/sparc32/udiv_nfp.asm
@@ -0,0 +1,202 @@
+dnl SPARC v7 __udiv_qrnnd division support, used from longlong.h.
+dnl This is for v7 CPUs without a floating-point unit.
+
+dnl Copyright 1993, 1994, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rem_ptr o0
+C n1 o1
+C n0 o2
+C d o3
+
+ASM_START()
+PROLOGUE(mpn_udiv_qrnnd)
+ tst %o3
+ bneg L(largedivisor)
+ mov 8,%g1
+
+ b L(p1)
+ addxcc %o2,%o2,%o2
+
+L(plop):
+ bcc L(n1)
+ addxcc %o2,%o2,%o2
+L(p1): addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc L(n2)
+ addxcc %o2,%o2,%o2
+L(p2): addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc L(n3)
+ addxcc %o2,%o2,%o2
+L(p3): addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc L(n4)
+ addxcc %o2,%o2,%o2
+L(p4): addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne L(plop)
+ subcc %o1,%o3,%o4
+ bcc L(n5)
+ addxcc %o2,%o2,%o2
+L(p5): st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+L(nlop):
+ bcc L(p1)
+ addxcc %o2,%o2,%o2
+L(n1): addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc L(p2)
+ addxcc %o2,%o2,%o2
+L(n2): addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc L(p3)
+ addxcc %o2,%o2,%o2
+L(n3): addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc L(p4)
+ addxcc %o2,%o2,%o2
+L(n4): addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne L(nlop)
+ subcc %o4,%o3,%o1
+ bcc L(p5)
+ addxcc %o2,%o2,%o2
+L(n5): st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+L(largedivisor):
+ and %o2,1,%o5 C %o5 = n0 & 1
+
+ srl %o2,1,%o2
+ sll %o1,31,%g2
+ or %g2,%o2,%o2 C %o2 = lo(n1n0 >> 1)
+ srl %o1,1,%o1 C %o1 = hi(n1n0 >> 1)
+
+ and %o3,1,%g2
+ srl %o3,1,%g3 C %g3 = floor(d / 2)
+ add %g3,%g2,%g3 C %g3 = ceil(d / 2)
+
+ b L(Lp1)
+ addxcc %o2,%o2,%o2
+
+L(Lplop):
+ bcc L(Ln1)
+ addxcc %o2,%o2,%o2
+L(Lp1): addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc L(Ln2)
+ addxcc %o2,%o2,%o2
+L(Lp2): addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc L(Ln3)
+ addxcc %o2,%o2,%o2
+L(Lp3): addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc L(Ln4)
+ addxcc %o2,%o2,%o2
+L(Lp4): addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne L(Lplop)
+ subcc %o1,%g3,%o4
+ bcc L(Ln5)
+ addxcc %o2,%o2,%o2
+L(Lp5): add %o1,%o1,%o1 C << 1
+ tst %g2
+ bne L(oddp)
+ add %o5,%o1,%o1
+ st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+L(Lnlop):
+ bcc L(Lp1)
+ addxcc %o2,%o2,%o2
+L(Ln1): addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc L(Lp2)
+ addxcc %o2,%o2,%o2
+L(Ln2): addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc L(Lp3)
+ addxcc %o2,%o2,%o2
+L(Ln3): addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc L(Lp4)
+ addxcc %o2,%o2,%o2
+L(Ln4): addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne L(Lnlop)
+ subcc %o4,%g3,%o1
+ bcc L(Lp5)
+ addxcc %o2,%o2,%o2
+L(Ln5): add %o4,%o4,%o4 C << 1
+ tst %g2
+ bne L(oddn)
+ add %o5,%o4,%o4
+ st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+L(oddp):
+ xnor %g0,%o2,%o2
+ C q' in %o2. r' in %o1
+ addcc %o1,%o2,%o1
+ bcc L(Lp6)
+ addx %o2,0,%o2
+ sub %o1,%o3,%o1
+L(Lp6): subcc %o1,%o3,%g0
+ bcs L(Lp7)
+ subx %o2,-1,%o2
+ sub %o1,%o3,%o1
+L(Lp7): st %o1,[%o0]
+ retl
+ mov %o2,%o0
+
+L(oddn):
+ xnor %g0,%o2,%o2
+ C q' in %o2. r' in %o4
+ addcc %o4,%o2,%o4
+ bcc L(Ln6)
+ addx %o2,0,%o2
+ sub %o4,%o3,%o4
+L(Ln6): subcc %o4,%o3,%g0
+ bcs L(Ln7)
+ subx %o2,-1,%o2
+ sub %o4,%o3,%o4
+L(Ln7): st %o4,[%o0]
+ retl
+ mov %o2,%o0
+EPILOGUE(mpn_udiv_qrnnd)
diff --git a/gmp/mpn/sparc32/ultrasparct1/add_n.asm b/gmp/mpn/sparc32/ultrasparct1/add_n.asm
new file mode 100644
index 0000000000..c781596dad
--- /dev/null
+++ b/gmp/mpn/sparc32/ultrasparct1/add_n.asm
@@ -0,0 +1,70 @@
+dnl SPARC T1 32-bit mpn_add_n.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(`rp', %o0)
+define(`ap', %o1)
+define(`bp', %o2)
+define(`n', %o3)
+define(`cy', %o4)
+
+define(`i', %o3)
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc)
+
+ASM_START()
+PROLOGUE(mpn_add_nc)
+ b L(ent)
+ srl cy, 0, cy C strip any bogus high bits
+EPILOGUE()
+
+PROLOGUE(mpn_add_n)
+ mov 0, cy
+L(ent): srl n, 0, n C strip any bogus high bits
+ sll n, 2, n
+ add ap, n, ap
+ add bp, n, bp
+ add rp, n, rp
+ neg n, i
+
+L(top): lduw [ap+i], %g1
+ lduw [bp+i], %g2
+ add %g1, %g2, %g3
+ add %g3, cy, %g3
+ stw %g3, [rp+i]
+ add i, 4, i
+ brnz i, L(top)
+ srlx %g3, 32, cy
+
+ retl
+ mov cy, %o0 C return value
+EPILOGUE()
diff --git a/gmp/mpn/sparc32/ultrasparct1/addmul_1.asm b/gmp/mpn/sparc32/ultrasparct1/addmul_1.asm
new file mode 100644
index 0000000000..89da186457
--- /dev/null
+++ b/gmp/mpn/sparc32/ultrasparct1/addmul_1.asm
@@ -0,0 +1,90 @@
+dnl SPARC T1 32-bit mpn_addmul_1.
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T1: 24
+C UltraSPARC T2: 19
+C UltraSPARC T3: 19
+C UltraSPARC T4: 5
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`v0', `%i3')
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ save %sp, -96, %sp
+ srl n, 0, %o4
+ srl v0, 0, %g1
+ subcc %o4, 1, %o4
+ be L(final_one)
+ clr %o5
+
+L(top): lduw [up+0], %l0
+ lduw [rp+0], %l2
+ lduw [up+4], %l1
+ lduw [rp+4], %l3
+ mulx %l0, %g1, %g3
+ add up, 8, up
+ mulx %l1, %g1, %o3
+ sub %o4, 2, %o4
+ add rp, 8, rp
+ add %l2, %g3, %g3
+ add %o5, %g3, %g3
+ stw %g3, [rp-8]
+ srlx %g3, 32, %o5
+ add %l3, %o3, %o3
+ add %o5, %o3, %o3
+ stw %o3, [rp-4]
+ brgz %o4, L(top)
+ srlx %o3, 32, %o5
+
+ brlz,pt %o4, L(done)
+ nop
+
+L(final_one):
+ lduw [up+0], %l0
+ lduw [rp+0], %l2
+ mulx %l0, %g1, %g3
+ add %l2, %g3, %g3
+ add %o5, %g3, %g3
+ stw %g3, [rp+0]
+ srlx %g3, 32, %o5
+
+L(done):
+ ret
+ restore %o5, 0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc32/ultrasparct1/gmp-mparam.h b/gmp/mpn/sparc32/ultrasparct1/gmp-mparam.h
new file mode 100644
index 0000000000..6f9d5a44ca
--- /dev/null
+++ b/gmp/mpn/sparc32/ultrasparct1/gmp-mparam.h
@@ -0,0 +1,153 @@
+/* UltraSPARC T 32-bit gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 3
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 9
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 10
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 21
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 22
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD 35
+
+#define MUL_TOOM22_THRESHOLD 14
+#define MUL_TOOM33_THRESHOLD 98
+#define MUL_TOOM44_THRESHOLD 166
+#define MUL_TOOM6H_THRESHOLD 226
+#define MUL_TOOM8H_THRESHOLD 333
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 139
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 97
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 98
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 120
+
+#define SQR_BASECASE_THRESHOLD 6
+#define SQR_TOOM2_THRESHOLD 34
+#define SQR_TOOM3_THRESHOLD 110
+#define SQR_TOOM4_THRESHOLD 178
+#define SQR_TOOM6_THRESHOLD 240
+#define SQR_TOOM8_THRESHOLD 333
+
+#define MULMID_TOOM42_THRESHOLD 22
+
+#define MULMOD_BNM1_THRESHOLD 9
+#define SQRMOD_BNM1_THRESHOLD 13
+
+#define MUL_FFT_MODF_THRESHOLD 280 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 280, 5}, { 15, 6}, { 8, 5}, { 17, 6}, \
+ { 9, 5}, { 19, 6}, { 13, 7}, { 7, 6}, \
+ { 17, 7}, { 9, 6}, { 20, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 21, 8}, \
+ { 11, 7}, { 25, 9}, { 7, 8}, { 15, 7}, \
+ { 33, 8}, { 19, 7}, { 41, 8}, { 23, 7}, \
+ { 49, 8}, { 27, 9}, { 15, 8}, { 31, 7}, \
+ { 63, 8}, { 39, 9}, { 23, 8}, { 47,10}, \
+ { 15, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47,10}, { 31, 9}, { 79,10}, \
+ { 47,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255,10}, { 79, 9}, { 159, 8}, { 319,10}, \
+ { 95, 9}, { 191, 8}, { 383,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 143, 9}, { 287,10}, \
+ { 159, 9}, { 319,10}, { 175,11}, { 95,10}, \
+ { 191, 9}, { 383,12}, { 4096,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 66
+#define MUL_FFT_THRESHOLD 3712
+
+#define SQR_FFT_MODF_THRESHOLD 240 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 240, 5}, { 15, 6}, { 8, 5}, { 17, 6}, \
+ { 13, 7}, { 7, 6}, { 17, 7}, { 9, 6}, \
+ { 20, 7}, { 11, 6}, { 23, 7}, { 13, 8}, \
+ { 7, 7}, { 19, 8}, { 11, 7}, { 25, 9}, \
+ { 7, 8}, { 15, 7}, { 33, 8}, { 19, 7}, \
+ { 39, 8}, { 23, 7}, { 47, 8}, { 27, 9}, \
+ { 15, 8}, { 39, 9}, { 23, 8}, { 47,10}, \
+ { 15, 9}, { 31, 8}, { 63, 9}, { 39, 8}, \
+ { 79, 9}, { 47,10}, { 31, 9}, { 63, 8}, \
+ { 127, 9}, { 71, 8}, { 143, 9}, { 79,10}, \
+ { 47,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 9}, { 143,10}, { 79, 9}, { 159, 8}, \
+ { 319, 9}, { 175,10}, { 95, 9}, { 191, 8}, \
+ { 383, 9}, { 207,11}, { 63,10}, { 127, 9}, \
+ { 255,10}, { 143, 9}, { 287,10}, { 159, 9}, \
+ { 319,10}, { 175,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207,12}, { 4096,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 70
+#define SQR_FFT_THRESHOLD 2624
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 51
+#define MULLO_MUL_N_THRESHOLD 6633
+
+#define DC_DIV_QR_THRESHOLD 51
+#define DC_DIVAPPR_Q_THRESHOLD 202
+#define DC_BDIV_QR_THRESHOLD 47
+#define DC_BDIV_Q_THRESHOLD 124
+
+#define INV_MULMOD_BNM1_THRESHOLD 26
+#define INV_NEWTON_THRESHOLD 266
+#define INV_APPR_THRESHOLD 222
+
+#define BINV_NEWTON_THRESHOLD 296
+#define REDC_1_TO_REDC_N_THRESHOLD 59
+
+#define MU_DIV_QR_THRESHOLD 1334
+#define MU_DIVAPPR_Q_THRESHOLD 1499
+#define MUPI_DIV_QR_THRESHOLD 116
+#define MU_BDIV_QR_THRESHOLD 1057
+#define MU_BDIV_Q_THRESHOLD 1334
+
+#define POWM_SEC_TABLE 6,35,213,724,2618
+
+#define MATRIX22_STRASSEN_THRESHOLD 15
+#define HGCD_THRESHOLD 84
+#define HGCD_APPR_THRESHOLD 101
+#define HGCD_REDUCE_THRESHOLD 1437
+#define GCD_DC_THRESHOLD 372
+#define GCDEXT_DC_THRESHOLD 253
+#define JACOBI_BASE_METHOD 2
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 27
+#define SET_STR_DC_THRESHOLD 399
+#define SET_STR_PRECOMPUTE_THRESHOLD 885
+
+#define FAC_DSC_THRESHOLD 179
+#define FAC_ODD_THRESHOLD 29
diff --git a/gmp/mpn/sparc32/ultrasparct1/mul_1.asm b/gmp/mpn/sparc32/ultrasparct1/mul_1.asm
new file mode 100644
index 0000000000..0239cd28cd
--- /dev/null
+++ b/gmp/mpn/sparc32/ultrasparct1/mul_1.asm
@@ -0,0 +1,83 @@
+dnl SPARC T1 32-bit mpn_mul_1.
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T1: 20
+C UltraSPARC T2: 18
+C UltraSPARC T3: 18
+C UltraSPARC T4: 4
+
+C INPUT PARAMETERS
+define(`rp', `%o0')
+define(`up', `%o1')
+define(`n', `%o2')
+define(`v0', `%o3')
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ srl n, 0, n
+ srl v0, 0, v0
+ subcc n, 1, n
+ be L(final_one)
+ clr %o5
+
+L(top): lduw [up+0], %g1
+ lduw [up+4], %g2
+ mulx %g1, v0, %g3
+ add up, 8, up
+ mulx %g2, v0, %o4
+ sub n, 2, n
+ add rp, 8, rp
+ add %o5, %g3, %g3
+ stw %g3, [rp-8]
+ srlx %g3, 32, %o5
+ add %o5, %o4, %o4
+ stw %o4, [rp-4]
+ brgz n, L(top)
+ srlx %o4, 32, %o5
+
+ brlz,pt n, L(done)
+ nop
+
+L(final_one):
+ lduw [up+0], %g1
+ mulx %g1, v0, %g3
+ add %o5, %g3, %g3
+ stw %g3, [rp+0]
+ srlx %g3, 32, %o5
+
+L(done):
+ retl
+ mov %o5, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc32/ultrasparct1/sqr_diagonal.asm b/gmp/mpn/sparc32/ultrasparct1/sqr_diagonal.asm
new file mode 100644
index 0000000000..3b906ef202
--- /dev/null
+++ b/gmp/mpn/sparc32/ultrasparct1/sqr_diagonal.asm
@@ -0,0 +1,55 @@
+dnl SPARC T1 32-bit mpn_sqr_diagonal.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(`rp', `%o0')
+define(`up', `%o1')
+define(`n', `%o2')
+
+ASM_START()
+PROLOGUE(mpn_sqr_diagonal)
+ deccc n C n--
+ nop
+
+L(top): lduw [up+0], %g1
+ add up, 4, up C up++
+ mulx %g1, %g1, %g3
+ stw %g3, [rp+0]
+ srlx %g3, 32, %g4
+ stw %g4, [rp+4]
+ add rp, 8, rp C rp += 2
+ bnz %icc, L(top)
+ deccc n C n--
+
+ retl
+ nop
+EPILOGUE()
diff --git a/gmp/mpn/sparc32/ultrasparct1/sub_n.asm b/gmp/mpn/sparc32/ultrasparct1/sub_n.asm
new file mode 100644
index 0000000000..946bc3ff8e
--- /dev/null
+++ b/gmp/mpn/sparc32/ultrasparct1/sub_n.asm
@@ -0,0 +1,70 @@
+dnl SPARC T1 32-bit mpn_sub_n.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(`rp', %o0)
+define(`ap', %o1)
+define(`bp', %o2)
+define(`n', %o3)
+define(`cy', %o4)
+
+define(`i', %o3)
+
+MULFUNC_PROLOGUE(mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+PROLOGUE(mpn_sub_nc)
+ b L(ent)
+ srl cy, 0, cy C strip any bogus high bits
+EPILOGUE()
+
+PROLOGUE(mpn_sub_n)
+ mov 0, cy
+L(ent): srl n, 0, n C strip any bogus high bits
+ sll n, 2, n
+ add ap, n, ap
+ add bp, n, bp
+ add rp, n, rp
+ neg n, i
+
+L(top): lduw [ap+i], %g1
+ lduw [bp+i], %g2
+ sub %g1, %g2, %g3
+ sub %g3, cy, %g3
+ stw %g3, [rp+i]
+ add i, 4, i
+ brnz i, L(top)
+ srlx %g3, 63, cy
+
+ retl
+ mov cy, %o0 C return value
+EPILOGUE()
diff --git a/gmp/mpn/sparc32/ultrasparct1/submul_1.asm b/gmp/mpn/sparc32/ultrasparct1/submul_1.asm
new file mode 100644
index 0000000000..89200709c4
--- /dev/null
+++ b/gmp/mpn/sparc32/ultrasparct1/submul_1.asm
@@ -0,0 +1,91 @@
+dnl SPARC T1 32-bit mpn_submul_1.
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T1: 24
+C UltraSPARC T2: 19
+C UltraSPARC T3: 19
+C UltraSPARC T4: 5
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`v0', `%i3')
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ save %sp, -96, %sp
+ srl n, 0, %o4
+ srl v0, 0, %g1
+ subcc %o4, 1, %o4
+ be L(final_one)
+ subcc %g0, 0, %o5
+
+L(top): lduw [up+0], %l0
+ lduw [rp+0], %l2
+ lduw [up+4], %l1
+ lduw [rp+4], %l3
+ mulx %l0, %g1, %g3
+ add up, 8, up
+ mulx %l1, %g1, %o3
+ sub %o4, 2, %o4
+ add rp, 8, rp
+ addx %o5, %g3, %g3
+ srlx %g3, 32, %o5
+ subcc %l2, %g3, %g3
+ stw %g3, [rp-8]
+ addx %o5, %o3, %o3
+ srlx %o3, 32, %o5
+ subcc %l3, %o3, %o3
+ brgz %o4, L(top)
+ stw %o3, [rp-4]
+
+ brlz,pt %o4, L(done)
+ nop
+
+L(final_one):
+ lduw [up+0], %l0
+ lduw [rp+0], %l2
+ mulx %l0, %g1, %g3
+ addx %o5, %g3, %g3
+ srlx %g3, 32, %o5
+ subcc %l2, %g3, %g3
+ stw %g3, [rp+0]
+
+L(done):
+ addx %o5, 0, %o5
+ ret
+ restore %o5, 0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc32/umul.asm b/gmp/mpn/sparc32/umul.asm
new file mode 100644
index 0000000000..3a20b95cb5
--- /dev/null
+++ b/gmp/mpn/sparc32/umul.asm
@@ -0,0 +1,77 @@
+dnl SPARC mpn_umul_ppmm -- support for longlong.h for non-gcc.
+
+dnl Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_umul_ppmm)
+ wr %g0,%o1,%y
+ sra %o2,31,%g2 C Don't move this insn
+ and %o1,%g2,%g2 C Don't move this insn
+ andcc %g0,0,%g1 C Don't move this insn
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,%o2,%g1
+ mulscc %g1,0,%g1
+ rd %y,%g3
+ st %g3,[%o0]
+ retl
+ add %g1,%g2,%o0
+EPILOGUE(mpn_umul_ppmm)
diff --git a/gmp/mpn/sparc32/v8/addmul_1.asm b/gmp/mpn/sparc32/v8/addmul_1.asm
new file mode 100644
index 0000000000..0052092784
--- /dev/null
+++ b/gmp/mpn/sparc32/v8/addmul_1.asm
@@ -0,0 +1,131 @@
+dnl SPARC v8 mpn_addmul_1 -- Multiply a limb vector with a limb and
+dnl add the result to a second limb vector.
+
+dnl Copyright 1992-1995, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr o0
+C s1_ptr o1
+C size o2
+C s2_limb o3
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ orcc %g0,%g0,%g2
+ ld [%o1+0],%o4 C 1
+
+ sll %o2,4,%g1
+ and %g1,(4-1)<<4,%g1
+ifdef(`PIC',
+` mov %o7,%g4 C Save return address register
+0: call 1f
+ add %o7,L(1)-0b,%g3
+1: mov %g4,%o7 C Restore return address register
+',
+` sethi %hi(L(1)),%g3
+ or %g3,%lo(L(1)),%g3
+')
+ jmp %g3+%g1
+ nop
+L(1):
+L(L00): add %o0,-4,%o0
+ b L(loop00) C 4, 8, 12, ...
+ add %o1,-4,%o1
+ nop
+L(L01): b L(loop01) C 1, 5, 9, ...
+ nop
+ nop
+ nop
+L(L10): add %o0,-12,%o0 C 2, 6, 10, ...
+ b L(loop10)
+ add %o1,4,%o1
+ nop
+L(L11): add %o0,-8,%o0 C 3, 7, 11, ...
+ b L(loop11)
+ add %o1,-8,%o1
+ nop
+
+L(loop):
+ addcc %g3,%g2,%g3 C 1
+ ld [%o1+4],%o4 C 2
+ rd %y,%g2 C 1
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 C 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] C 1
+L(loop00):
+ umul %o4,%o3,%g3 C 2
+ ld [%o0+4],%g1 C 2
+ addxcc %g3,%g2,%g3 C 2
+ ld [%o1+8],%o4 C 3
+ rd %y,%g2 C 2
+ addx %g0,%g2,%g2
+ nop
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+4] C 2
+L(loop11):
+ umul %o4,%o3,%g3 C 3
+ addxcc %g3,%g2,%g3 C 3
+ ld [%o1+12],%o4 C 4
+ rd %y,%g2 C 3
+ add %o1,16,%o1
+ addx %g0,%g2,%g2
+ ld [%o0+8],%g1 C 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+8] C 3
+L(loop10):
+ umul %o4,%o3,%g3 C 4
+ addxcc %g3,%g2,%g3 C 4
+ ld [%o1+0],%o4 C 1
+ rd %y,%g2 C 4
+ addx %g0,%g2,%g2
+ ld [%o0+12],%g1 C 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+12] C 4
+ add %o0,16,%o0
+ addx %g0,%g2,%g2
+L(loop01):
+ addcc %o2,-4,%o2
+ bg L(loop)
+ umul %o4,%o3,%g3 C 1
+
+ addcc %g3,%g2,%g3 C 4
+ rd %y,%g2 C 4
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 C 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] C 4
+ addx %g0,%g2,%o0
+
+ retl
+ nop
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/sparc32/v8/gmp-mparam.h b/gmp/mpn/sparc32/v8/gmp-mparam.h
new file mode 100644
index 0000000000..e57897b439
--- /dev/null
+++ b/gmp/mpn/sparc32/v8/gmp-mparam.h
@@ -0,0 +1,73 @@
+/* SPARC v8 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* Generated by tuneup.c, 2004-02-07, gcc 2.95 */
+
+#define MUL_TOOM22_THRESHOLD 10
+#define MUL_TOOM33_THRESHOLD 65
+
+#define SQR_BASECASE_THRESHOLD 4
+#define SQR_TOOM2_THRESHOLD 18
+#define SQR_TOOM3_THRESHOLD 65
+
+#define DIV_SB_PREINV_THRESHOLD 5
+#define DIV_DC_THRESHOLD 24
+#define POWM_THRESHOLD 38
+
+#define HGCD_THRESHOLD 69
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 498
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD 6
+#define DIVREM_1_UNNORM_THRESHOLD 11
+#define MOD_1_NORM_THRESHOLD 5
+#define MOD_1_UNNORM_THRESHOLD 9
+#define USE_PREINV_DIVREM_1 1
+#define USE_PREINV_MOD_1 1
+#define DIVREM_2_THRESHOLD 0 /* always */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 4
+
+#define GET_STR_DC_THRESHOLD 14
+#define GET_STR_PRECOMPUTE_THRESHOLD 23
+#define SET_STR_THRESHOLD 1679
+
+#define MUL_FFT_TABLE { 272, 672, 1152, 2560, 10240, 24576, 0 }
+#define MUL_FFT_MODF_THRESHOLD 264
+#define MUL_FFT_THRESHOLD 1792
+
+#define SQR_FFT_TABLE { 304, 672, 1152, 3584, 10240, 24576, 0 }
+#define SQR_FFT_MODF_THRESHOLD 264
+#define SQR_FFT_THRESHOLD 1728
diff --git a/gmp/mpn/sparc32/v8/mul_1.asm b/gmp/mpn/sparc32/v8/mul_1.asm
new file mode 100644
index 0000000000..e26c853aed
--- /dev/null
+++ b/gmp/mpn/sparc32/v8/mul_1.asm
@@ -0,0 +1,112 @@
+dnl SPARC v8 mpn_mul_1 -- Multiply a limb vector with a single limb and
+dnl store the product in a second limb vector.
+
+dnl Copyright 1992, 1994, 1995, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr o0
+C s1_ptr o1
+C size o2
+C s2_limb o3
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ sll %o2,4,%g1
+ and %g1,(4-1)<<4,%g1
+ifdef(`PIC',
+` mov %o7,%g4 C Save return address register
+0: call 1f
+ add %o7,L(1)-0b,%g3
+1: mov %g4,%o7 C Restore return address register
+',
+` sethi %hi(L(1)),%g3
+ or %g3,%lo(L(1)),%g3
+')
+ jmp %g3+%g1
+ ld [%o1+0],%o4 C 1
+L(1):
+L(L00): add %o0,-4,%o0
+ add %o1,-4,%o1
+ b L(loop00) C 4, 8, 12, ...
+ orcc %g0,%g0,%g2
+L(L01): b L(loop01) C 1, 5, 9, ...
+ orcc %g0,%g0,%g2
+ nop
+ nop
+L(L10): add %o0,-12,%o0 C 2, 6, 10, ...
+ add %o1,4,%o1
+ b L(loop10)
+ orcc %g0,%g0,%g2
+ nop
+L(L11): add %o0,-8,%o0 C 3, 7, 11, ...
+ add %o1,-8,%o1
+ b L(loop11)
+ orcc %g0,%g0,%g2
+
+L(loop):
+ addcc %g3,%g2,%g3 C 1
+ ld [%o1+4],%o4 C 2
+ st %g3,[%o0+0] C 1
+ rd %y,%g2 C 1
+L(loop00):
+ umul %o4,%o3,%g3 C 2
+ addxcc %g3,%g2,%g3 C 2
+ ld [%o1+8],%o4 C 3
+ st %g3,[%o0+4] C 2
+ rd %y,%g2 C 2
+L(loop11):
+ umul %o4,%o3,%g3 C 3
+ addxcc %g3,%g2,%g3 C 3
+ ld [%o1+12],%o4 C 4
+ add %o1,16,%o1
+ st %g3,[%o0+8] C 3
+ rd %y,%g2 C 3
+L(loop10):
+ umul %o4,%o3,%g3 C 4
+ addxcc %g3,%g2,%g3 C 4
+ ld [%o1+0],%o4 C 1
+ st %g3,[%o0+12] C 4
+ add %o0,16,%o0
+ rd %y,%g2 C 4
+ addx %g0,%g2,%g2
+L(loop01):
+ addcc %o2,-4,%o2
+ bg L(loop)
+ umul %o4,%o3,%g3 C 1
+
+ addcc %g3,%g2,%g3 C 4
+ st %g3,[%o0+0] C 4
+ rd %y,%g2 C 4
+
+ retl
+ addx %g0,%g2,%o0
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/sparc32/v8/submul_1.asm b/gmp/mpn/sparc32/v8/submul_1.asm
new file mode 100644
index 0000000000..187314ecef
--- /dev/null
+++ b/gmp/mpn/sparc32/v8/submul_1.asm
@@ -0,0 +1,67 @@
+dnl SPARC v8 mpn_submul_1 -- Multiply a limb vector with a limb and
+dnl subtract the result from a second limb vector.
+
+dnl Copyright 1992-1994, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C res_ptr o0
+C s1_ptr o1
+C size o2
+C s2_limb o3
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ sub %g0,%o2,%o2 C negate ...
+ sll %o2,2,%o2 C ... and scale size
+ sub %o1,%o2,%o1 C o1 is offset s1_ptr
+ sub %o0,%o2,%g1 C g1 is offset res_ptr
+
+ mov 0,%o0 C clear cy_limb
+
+L(loop):
+ ld [%o1+%o2],%o4
+ ld [%g1+%o2],%g2
+ umul %o4,%o3,%o5
+ rd %y,%g3
+ addcc %o5,%o0,%o5
+ addx %g3,0,%o0
+ subcc %g2,%o5,%g2
+ addx %o0,0,%o0
+ st %g2,[%g1+%o2]
+
+ addcc %o2,4,%o2
+ bne L(loop)
+ nop
+
+ retl
+ nop
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/sparc32/v8/supersparc/gmp-mparam.h b/gmp/mpn/sparc32/v8/supersparc/gmp-mparam.h
new file mode 100644
index 0000000000..1ac9239e3c
--- /dev/null
+++ b/gmp/mpn/sparc32/v8/supersparc/gmp-mparam.h
@@ -0,0 +1,73 @@
+/* SuperSPARC gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* Generated by tuneup.c, 2004-02-10, gcc 3.3 */
+
+#define MUL_TOOM22_THRESHOLD 14
+#define MUL_TOOM33_THRESHOLD 81
+
+#define SQR_BASECASE_THRESHOLD 5
+#define SQR_TOOM2_THRESHOLD 28
+#define SQR_TOOM3_THRESHOLD 86
+
+#define DIV_SB_PREINV_THRESHOLD 0 /* always */
+#define DIV_DC_THRESHOLD 26
+#define POWM_THRESHOLD 79
+
+#define HGCD_THRESHOLD 97
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 470
+#define JACOBI_BASE_METHOD 2
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 3
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 3
+#define USE_PREINV_DIVREM_1 1
+#define USE_PREINV_MOD_1 1
+#define DIVREM_2_THRESHOLD 0 /* always */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always */
+
+#define GET_STR_DC_THRESHOLD 19
+#define GET_STR_PRECOMPUTE_THRESHOLD 34
+#define SET_STR_THRESHOLD 3524
+
+#define MUL_FFT_TABLE { 304, 800, 1408, 3584, 10240, 24576, 0 }
+#define MUL_FFT_MODF_THRESHOLD 264
+#define MUL_FFT_THRESHOLD 2304
+
+#define SQR_FFT_TABLE { 336, 800, 1408, 3584, 10240, 24576, 0 }
+#define SQR_FFT_MODF_THRESHOLD 280
+#define SQR_FFT_THRESHOLD 2304
diff --git a/gmp/mpn/sparc32/v8/supersparc/udiv.asm b/gmp/mpn/sparc32/v8/supersparc/udiv.asm
new file mode 100644
index 0000000000..12f66ce6a2
--- /dev/null
+++ b/gmp/mpn/sparc32/v8/supersparc/udiv.asm
@@ -0,0 +1,131 @@
+dnl SuperSPARC mpn_udiv_qrnnd division support, used from longlong.h.
+dnl This is for SuperSPARC only, to compensate for its semi-functional
+dnl udiv instruction.
+
+dnl Copyright 1993, 1994, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rem_ptr i0
+C n1 i1
+C n0 i2
+C d i3
+
+ASM_START()
+
+ifdef(`PIC',
+` TEXT
+L(getpc):
+ retl
+ nop')
+
+ TEXT
+ ALIGN(8)
+L(C0): .double 0r4294967296
+L(C1): .double 0r2147483648
+
+PROLOGUE(mpn_udiv_qrnnd)
+ save %sp,-104,%sp
+ st %i1,[%fp-8]
+ ld [%fp-8],%f10
+
+ifdef(`PIC',
+`L(pc): call L(getpc) C put address of this insn in %o7
+ ldd [%o7+L(C0)-L(pc)],%f8',
+` sethi %hi(L(C0)),%o7
+ ldd [%o7+%lo(L(C0))],%f8')
+
+ fitod %f10,%f4
+ cmp %i1,0
+ bge L(248)
+ mov %i0,%i5
+ faddd %f4,%f8,%f4
+L(248):
+ st %i2,[%fp-8]
+ ld [%fp-8],%f10
+ fmuld %f4,%f8,%f6
+ cmp %i2,0
+ bge L(249)
+ fitod %f10,%f2
+ faddd %f2,%f8,%f2
+L(249):
+ st %i3,[%fp-8]
+ faddd %f6,%f2,%f2
+ ld [%fp-8],%f10
+ cmp %i3,0
+ bge L(250)
+ fitod %f10,%f4
+ faddd %f4,%f8,%f4
+L(250):
+ fdivd %f2,%f4,%f2
+
+ifdef(`PIC',
+` ldd [%o7+L(C1)-L(pc)],%f4',
+` sethi %hi(L(C1)),%o7
+ ldd [%o7+%lo(L(C1))],%f4')
+
+ fcmped %f2,%f4
+ nop
+ fbge,a L(251)
+ fsubd %f2,%f4,%f2
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ b L(252)
+ ld [%fp-8],%i4
+L(251):
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ ld [%fp-8],%i4
+ sethi %hi(-2147483648),%g2
+ xor %i4,%g2,%i4
+L(252):
+ umul %i3,%i4,%g3
+ rd %y,%i0
+ subcc %i2,%g3,%o7
+ subxcc %i1,%i0,%g0
+ be L(253)
+ cmp %o7,%i3
+
+ add %i4,-1,%i0
+ add %o7,%i3,%o7
+ st %o7,[%i5]
+ ret
+ restore
+L(253):
+ blu L(246)
+ mov %i4,%i0
+ add %i4,1,%i0
+ sub %o7,%i3,%o7
+L(246):
+ st %o7,[%i5]
+ ret
+ restore
+EPILOGUE(mpn_udiv_qrnnd)
diff --git a/gmp/mpn/sparc32/v8/udiv.asm b/gmp/mpn/sparc32/v8/udiv.asm
new file mode 100644
index 0000000000..12f66ce6a2
--- /dev/null
+++ b/gmp/mpn/sparc32/v8/udiv.asm
@@ -0,0 +1,131 @@
+dnl SuperSPARC mpn_udiv_qrnnd division support, used from longlong.h.
+dnl This is for SuperSPARC only, to compensate for its semi-functional
+dnl udiv instruction.
+
+dnl Copyright 1993, 1994, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rem_ptr i0
+C n1 i1
+C n0 i2
+C d i3
+
+ASM_START()
+
+ifdef(`PIC',
+` TEXT
+L(getpc):
+ retl
+ nop')
+
+ TEXT
+ ALIGN(8)
+L(C0): .double 0r4294967296
+L(C1): .double 0r2147483648
+
+PROLOGUE(mpn_udiv_qrnnd)
+ save %sp,-104,%sp
+ st %i1,[%fp-8]
+ ld [%fp-8],%f10
+
+ifdef(`PIC',
+`L(pc): call L(getpc) C put address of this insn in %o7
+ ldd [%o7+L(C0)-L(pc)],%f8',
+` sethi %hi(L(C0)),%o7
+ ldd [%o7+%lo(L(C0))],%f8')
+
+ fitod %f10,%f4
+ cmp %i1,0
+ bge L(248)
+ mov %i0,%i5
+ faddd %f4,%f8,%f4
+L(248):
+ st %i2,[%fp-8]
+ ld [%fp-8],%f10
+ fmuld %f4,%f8,%f6
+ cmp %i2,0
+ bge L(249)
+ fitod %f10,%f2
+ faddd %f2,%f8,%f2
+L(249):
+ st %i3,[%fp-8]
+ faddd %f6,%f2,%f2
+ ld [%fp-8],%f10
+ cmp %i3,0
+ bge L(250)
+ fitod %f10,%f4
+ faddd %f4,%f8,%f4
+L(250):
+ fdivd %f2,%f4,%f2
+
+ifdef(`PIC',
+` ldd [%o7+L(C1)-L(pc)],%f4',
+` sethi %hi(L(C1)),%o7
+ ldd [%o7+%lo(L(C1))],%f4')
+
+ fcmped %f2,%f4
+ nop
+ fbge,a L(251)
+ fsubd %f2,%f4,%f2
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ b L(252)
+ ld [%fp-8],%i4
+L(251):
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ ld [%fp-8],%i4
+ sethi %hi(-2147483648),%g2
+ xor %i4,%g2,%i4
+L(252):
+ umul %i3,%i4,%g3
+ rd %y,%i0
+ subcc %i2,%g3,%o7
+ subxcc %i1,%i0,%g0
+ be L(253)
+ cmp %o7,%i3
+
+ add %i4,-1,%i0
+ add %o7,%i3,%o7
+ st %o7,[%i5]
+ ret
+ restore
+L(253):
+ blu L(246)
+ mov %i4,%i0
+ add %i4,1,%i0
+ sub %o7,%i3,%o7
+L(246):
+ st %o7,[%i5]
+ ret
+ restore
+EPILOGUE(mpn_udiv_qrnnd)
diff --git a/gmp/mpn/sparc32/v8/umul.asm b/gmp/mpn/sparc32/v8/umul.asm
new file mode 100644
index 0000000000..1a2e84b1f6
--- /dev/null
+++ b/gmp/mpn/sparc32/v8/umul.asm
@@ -0,0 +1,40 @@
+dnl SPARC v8 mpn_umul_ppmm -- support for longlong.h for non-gcc.
+
+dnl Copyright 1995, 1996, 2000 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_umul_ppmm)
+ umul %o1,%o2,%g2
+ st %g2,[%o0]
+ retl
+ rd %y,%o0
+EPILOGUE(mpn_umul_ppmm)
diff --git a/gmp/mpn/sparc32/v9/README b/gmp/mpn/sparc32/v9/README
new file mode 100644
index 0000000000..9b39713271
--- /dev/null
+++ b/gmp/mpn/sparc32/v9/README
@@ -0,0 +1,4 @@
+Code for SPARC processors implementing version 9 of the SPARC architecture.
+This code is for systems that doesn't preserve the full 64-bit contents of
+integer register at context switch. For other systems (such as Solaris 7 or
+later) use the code in ../../sparc64.
diff --git a/gmp/mpn/sparc32/v9/add_n.asm b/gmp/mpn/sparc32/v9/add_n.asm
new file mode 100644
index 0000000000..7bd5974fd3
--- /dev/null
+++ b/gmp/mpn/sparc32/v9/add_n.asm
@@ -0,0 +1,129 @@
+dnl SPARC mpn_add_n -- Add two limb vectors of the same length > 0 and store
+dnl sum in a third limb vector.
+
+dnl Copyright 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(rp,%o0)
+define(s1p,%o1)
+define(s2p,%o2)
+define(n,%o3)
+define(cy,%g1)
+
+C This code uses 64-bit operations on `o' and `g' registers. It doesn't
+C require that `o' registers' upper 32 bits are preserved by the operating
+C system, but if they are not, they must be zeroed. That is indeed what
+C happens at least on Slowaris 2.5 and 2.6.
+
+C On UltraSPARC 1 and 2, this code runs at 3 cycles/limb from the Dcache and at
+C about 10 cycles/limb from the Ecache.
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+ lduw [s1p+0],%o4
+ lduw [s2p+0],%o5
+ addcc n,-2,n
+ bl,pn %icc,L(end1)
+ lduw [s1p+4],%g2
+ lduw [s2p+4],%g3
+ be,pn %icc,L(end2)
+ mov 0,cy
+
+ .align 16
+L(loop):
+ add %o4,%o5,%g4
+ add rp,8,rp
+ lduw [s1p+8],%o4
+ fitod %f0,%f2
+C ---
+ add cy,%g4,%g4
+ addcc n,-1,n
+ lduw [s2p+8],%o5
+ fitod %f0,%f2
+C ---
+ srlx %g4,32,cy
+ add s2p,8,s2p
+ stw %g4,[rp-8]
+ be,pn %icc,L(exito)+4
+C ---
+ add %g2,%g3,%g4
+ addcc n,-1,n
+ lduw [s1p+12],%g2
+ fitod %f0,%f2
+C ---
+ add cy,%g4,%g4
+ add s1p,8,s1p
+ lduw [s2p+4],%g3
+ fitod %f0,%f2
+C ---
+ srlx %g4,32,cy
+ bne,pt %icc,L(loop)
+ stw %g4,[rp-4]
+C ---
+L(exite):
+ add %o4,%o5,%g4
+ add cy,%g4,%g4
+ srlx %g4,32,cy
+ stw %g4,[rp+0]
+ add %g2,%g3,%g4
+ add cy,%g4,%g4
+ stw %g4,[rp+4]
+ retl
+ srlx %g4,32,%o0
+
+L(exito):
+ add %g2,%g3,%g4
+ add cy,%g4,%g4
+ srlx %g4,32,cy
+ stw %g4,[rp-4]
+ add %o4,%o5,%g4
+ add cy,%g4,%g4
+ stw %g4,[rp+0]
+ retl
+ srlx %g4,32,%o0
+
+L(end1):
+ add %o4,%o5,%g4
+ stw %g4,[rp+0]
+ retl
+ srlx %g4,32,%o0
+
+L(end2):
+ add %o4,%o5,%g4
+ srlx %g4,32,cy
+ stw %g4,[rp+0]
+ add %g2,%g3,%g4
+ add cy,%g4,%g4
+ stw %g4,[rp+4]
+ retl
+ srlx %g4,32,%o0
+EPILOGUE(mpn_add_n)
diff --git a/gmp/mpn/sparc32/v9/addmul_1.asm b/gmp/mpn/sparc32/v9/addmul_1.asm
new file mode 100644
index 0000000000..2adf7a8a2f
--- /dev/null
+++ b/gmp/mpn/sparc32/v9/addmul_1.asm
@@ -0,0 +1,306 @@
+dnl SPARC v9 32-bit mpn_addmul_1 -- Multiply a limb vector with a limb and add
+dnl the result to a second limb vector.
+
+dnl Copyright 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C Algorithm: We use two floating-point multiplies per limb product, with the
+C invariant v operand split into two 16-bit pieces, and the u operand split
+C into 32-bit pieces. We convert the two 48-bit products and transfer them to
+C the integer unit.
+
+C cycles/limb
+C UltraSPARC 1&2: 6.5
+C UltraSPARC 3: ?
+
+C Possible optimizations:
+C 1. Combine 32-bit memory operations into 64-bit operations. Since we're
+C memory bandwidth limited, this could save 1.5 cycles/limb.
+C 2. Unroll the inner loop. Since we already use alternate temporary areas,
+C it is very straightforward to unroll, using an exit branch midways.
+C Unrolling would allow deeper scheduling which could improve speed for L2
+C cache case.
+C 3. For mpn_mul_1: Use more alternating temp areas. The std'es and ldx'es
+C aren't sufficiently apart-scheduled with just two temp areas.
+C 4. Specialize for particular v values. If its upper 16 bits are zero, we
+C could save many operations.
+
+C INPUT PARAMETERS
+C rp i0
+C up i1
+C n i2
+C v i3
+
+define(`FSIZE',224)
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ add %sp, -FSIZE, %sp
+ sethi %hi(0xffff), %g1
+ srl %o3, 16, %g2
+ or %g1, %lo(0xffff), %g1
+ and %o3, %g1, %g1
+ stx %g1, [%sp+104]
+ stx %g2, [%sp+112]
+ ldd [%sp+104], %f6
+ ldd [%sp+112], %f8
+ fxtod %f6, %f6
+ fxtod %f8, %f8
+ ld [%sp+104], %f10 C zero f10
+
+ mov 0, %g3 C cy = 0
+
+define(`fanop', `fitod %f18, %f0') C A quasi nop running in the FA pipe
+
+ add %sp, 160, %o5 C point in scratch area
+ and %o5, -32, %o5 C align at 0 (mod 32) in scratch area
+
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_two_or_more
+ fxtod %f10, %f2
+
+ fmuld %f2, %f8, %f16
+ fmuld %f2, %f6, %f4
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+16]
+ std %f12, [%o5+24]
+ ldx [%o5+16], %g2 C p16
+ ldx [%o5+24], %g1 C p0
+ lduw [%o0], %g5 C read rp[i]
+ b .L1
+ add %o0, -16, %o0
+
+ .align 16
+.L_two_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fmuld %f2, %f8, %f16
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_three_or_more
+ fxtod %f10, %f2
+
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+0]
+ std %f12, [%o5+8]
+ lduw [%o0], %g5 C read rp[i]
+ ldx [%o5+16], %g2 C p16
+ ldx [%o5+24], %g1 C p0
+ b .L2
+ add %o0, -12, %o0
+
+ .align 16
+.L_three_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_four_or_more
+ fxtod %f10, %f2
+
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+ fdtox %f16, %f14
+ ldx [%o5+16], %g2 C p16
+ fdtox %f4, %f12
+ ldx [%o5+24], %g1 C p0
+ std %f14, [%o5+16]
+ std %f12, [%o5+24]
+ lduw [%o0], %g5 C read rp[i]
+ b .L3
+ add %o0, -8, %o0
+
+ .align 16
+.L_four_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_five_or_more
+ fxtod %f10, %f2
+
+ fdtox %f16, %f14
+ ldx [%o5+16], %g2 C p16
+ fdtox %f4, %f12
+ ldx [%o5+24], %g1 C p0
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ lduw [%o0], %g5 C read rp[i]
+ b .L4
+ add %o0, -4, %o0
+
+ .align 16
+.L_five_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+ ldx [%o5+16], %g2 C p16
+ fdtox %f4, %f12
+ ldx [%o5+24], %g1 C p0
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ lduw [%o0], %g5 C read rp[i]
+ bne,pt %icc, .Loop
+ fxtod %f10, %f2
+ b,a .L5
+
+C BEGIN MAIN LOOP
+ .align 16
+C -- 0
+.Loop: nop
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+C -- 1
+ sllx %g2, 16, %g4 C (p16 << 16)
+ add %o0, 4, %o0 C rp++
+ ldx [%o5+0], %g2 C p16
+ fdtox %f4, %f12
+C -- 2
+ nop
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ fanop
+C -- 3
+ nop
+ add %g3, %g4, %g4 C p += cy
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+C -- 4
+ nop
+ add %g5, %g4, %g4 C p += rp[i]
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+C -- 5
+ xor %o5, 16, %o5 C alternate scratch variables
+ add %o1, 4, %o1 C up++
+ stw %g4, [%o0-4]
+ fanop
+C -- 6
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0], %g5 C read rp[i]
+ bne,pt %icc, .Loop
+ fxtod %f10, %f2
+C END MAIN LOOP
+
+.L5: fdtox %f16, %f14
+ sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ fdtox %f4, %f12
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g4, %g3, %g4 C p += cy
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+ add %g5, %g4, %g4 C p += rp[i]
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+ xor %o5, 16, %o5
+ stw %g4, [%o0+0]
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0+4], %g5 C read rp[i]
+
+.L4: fdtox %f16, %f14
+ sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ fdtox %f4, %f12
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g3, %g4, %g4 C p += cy
+ std %f14, [%o5+0]
+ add %g5, %g4, %g4 C p += rp[i]
+ std %f12, [%o5+8]
+ xor %o5, 16, %o5
+ stw %g4, [%o0+4]
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0+8], %g5 C read rp[i]
+
+.L3: sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g3, %g4, %g4 C p += cy
+ add %g5, %g4, %g4 C p += rp[i]
+ xor %o5, 16, %o5
+ stw %g4, [%o0+8]
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0+12], %g5 C read rp[i]
+
+.L2: sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g3, %g4, %g4 C p += cy
+ add %g5, %g4, %g4 C p += rp[i]
+ stw %g4, [%o0+12]
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0+16], %g5 C read rp[i]
+
+.L1: sllx %g2, 16, %g4 C (p16 << 16)
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ add %g3, %g4, %g4 C p += cy
+ add %g5, %g4, %g4 C p += rp[i]
+ stw %g4, [%o0+16]
+ srlx %g4, 32, %g3 C new cy
+
+ mov %g3, %o0
+ retl
+ sub %sp, -FSIZE, %sp
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/sparc32/v9/gmp-mparam.h b/gmp/mpn/sparc32/v9/gmp-mparam.h
new file mode 100644
index 0000000000..f909e2cf18
--- /dev/null
+++ b/gmp/mpn/sparc32/v9/gmp-mparam.h
@@ -0,0 +1,204 @@
+/* SPARC v9 32-bit gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004, 2009-2011, 2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 1593 MHz ultrasparc3 running Solaris 10 (swift.nada.kth.se) */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-16, gcc 3.4 */
+
+#define DIVREM_1_NORM_THRESHOLD 3
+#define DIVREM_1_UNNORM_THRESHOLD 4
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 3
+#define MOD_1_UNNORM_THRESHOLD 4
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 13
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 12
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 22
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 32
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 4
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 28
+#define MUL_TOOM33_THRESHOLD 43
+#define MUL_TOOM44_THRESHOLD 126
+#define MUL_TOOM6H_THRESHOLD 161
+#define MUL_TOOM8H_THRESHOLD 208
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 80
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 85
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 55
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 72
+
+#define SQR_BASECASE_THRESHOLD 4
+#define SQR_TOOM2_THRESHOLD 64
+#define SQR_TOOM3_THRESHOLD 85
+#define SQR_TOOM4_THRESHOLD 152
+#define SQR_TOOM6_THRESHOLD 185
+#define SQR_TOOM8_THRESHOLD 324
+
+#define MULMID_TOOM42_THRESHOLD 64
+
+#define MULMOD_BNM1_THRESHOLD 12
+#define SQRMOD_BNM1_THRESHOLD 16
+
+#define MUL_FFT_MODF_THRESHOLD 288 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 288, 5}, { 9, 4}, { 19, 5}, { 11, 6}, \
+ { 6, 5}, { 14, 6}, { 8, 5}, { 17, 6}, \
+ { 9, 5}, { 20, 6}, { 13, 7}, { 7, 6}, \
+ { 16, 7}, { 9, 6}, { 19, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 8}, { 7, 7}, { 15, 6}, \
+ { 31, 7}, { 19, 8}, { 11, 7}, { 23, 9}, \
+ { 7, 8}, { 15, 7}, { 31, 8}, { 19, 7}, \
+ { 39, 8}, { 27, 9}, { 15, 8}, { 31, 7}, \
+ { 63, 8}, { 39, 9}, { 23, 8}, { 47,10}, \
+ { 15, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47,10}, { 31, 9}, { 71, 8}, \
+ { 143, 9}, { 79,10}, { 47, 9}, { 95,11}, \
+ { 31,10}, { 63, 9}, { 135, 8}, { 271, 9}, \
+ { 143, 8}, { 287,10}, { 79, 9}, { 175,10}, \
+ { 95, 9}, { 191, 8}, { 383,10}, { 111,11}, \
+ { 63,10}, { 143, 9}, { 287, 8}, { 575,10}, \
+ { 175,11}, { 95,10}, { 191, 9}, { 415, 8}, \
+ { 831,12}, { 63,11}, { 127,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 351, 9}, { 703,11}, \
+ { 191,10}, { 415, 9}, { 831,11}, { 223,10}, \
+ { 447, 9}, { 895, 8}, { 1791,12}, { 127,11}, \
+ { 287,10}, { 607, 9}, { 1215, 8}, { 2431,11}, \
+ { 319, 9}, { 1279,11}, { 351,12}, { 191,11}, \
+ { 415,10}, { 831,11}, { 447,10}, { 895, 9}, \
+ { 1791,11}, { 479,13}, { 127,12}, { 255,11}, \
+ { 575,10}, { 1151,11}, { 607,12}, { 319,11}, \
+ { 703,12}, { 383,11}, { 831,12}, { 447,11}, \
+ { 895,10}, { 1791,11}, { 959,13}, { 255,12}, \
+ { 575,11}, { 1215,10}, { 2431,12}, { 703,13}, \
+ { 383,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1087,11}, { 2175,12}, { 1215,11}, { 2431,13}, \
+ { 639,12}, { 1407,11}, { 2943,13}, { 895,12}, \
+ { 1919,14}, { 511,13}, { 1151,12}, { 2431,13}, \
+ { 1407,14}, { 767,13}, { 1791,15}, { 511,14}, \
+ { 1023,13}, { 2431,14}, { 1279,13}, { 2943,12}, \
+ { 5887,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 143
+#define MUL_FFT_THRESHOLD 2240
+
+#define SQR_FFT_MODF_THRESHOLD 244 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 244, 5}, { 8, 4}, { 17, 5}, { 17, 6}, \
+ { 9, 5}, { 19, 6}, { 17, 7}, { 9, 6}, \
+ { 20, 7}, { 11, 6}, { 23, 7}, { 13, 8}, \
+ { 7, 7}, { 19, 8}, { 11, 7}, { 25, 9}, \
+ { 7, 8}, { 15, 7}, { 33, 8}, { 19, 7}, \
+ { 39, 8}, { 23, 9}, { 15, 8}, { 39, 9}, \
+ { 23,10}, { 15, 9}, { 31, 8}, { 63, 9}, \
+ { 47,10}, { 31, 9}, { 63, 8}, { 127, 9}, \
+ { 71, 8}, { 143, 7}, { 287, 9}, { 79,10}, \
+ { 47,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 9}, { 143, 8}, { 287,10}, { 79, 9}, \
+ { 159, 8}, { 319, 9}, { 175, 8}, { 351, 7}, \
+ { 703,10}, { 95, 9}, { 191, 8}, { 383, 9}, \
+ { 207, 8}, { 415, 9}, { 223,11}, { 63,10}, \
+ { 127, 9}, { 271,10}, { 143, 9}, { 287, 8}, \
+ { 575,10}, { 159, 9}, { 319,10}, { 175, 9}, \
+ { 351, 8}, { 703,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207, 9}, { 415, 8}, { 831,10}, \
+ { 223,12}, { 63,11}, { 127,10}, { 271, 9}, \
+ { 543,10}, { 287, 9}, { 575,11}, { 159,10}, \
+ { 319, 9}, { 639,10}, { 351, 9}, { 703, 8}, \
+ { 1407,11}, { 191,10}, { 415, 9}, { 831,11}, \
+ { 223,10}, { 447, 9}, { 895,10}, { 479,12}, \
+ { 127,11}, { 255,10}, { 543,11}, { 287,10}, \
+ { 575,11}, { 319,10}, { 639,11}, { 351,10}, \
+ { 703,12}, { 191,11}, { 415,10}, { 831,11}, \
+ { 447,10}, { 895, 9}, { 1791,13}, { 127,12}, \
+ { 255,11}, { 575,12}, { 319,11}, { 703,10}, \
+ { 1407,12}, { 383,11}, { 831,12}, { 447,11}, \
+ { 959,10}, { 1919, 9}, { 3839,13}, { 255,12}, \
+ { 575,11}, { 1151,12}, { 703,11}, { 1407,13}, \
+ { 383,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1215,11}, { 2431,13}, { 639,12}, { 1407,13}, \
+ { 767,12}, { 1599,13}, { 895,12}, { 1919,14}, \
+ { 511,13}, { 1151,12}, { 2431,13}, { 1407,12}, \
+ { 2815,14}, { 767,13}, { 1535,12}, { 3071,13}, \
+ { 1919,15}, { 511,14}, { 1023,13}, { 2431,14}, \
+ { 1279,13}, { 2943,12}, { 5887,14}, { 16384,15}, \
+ { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 153
+#define SQR_FFT_THRESHOLD 2112
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 144
+#define MULLO_MUL_N_THRESHOLD 4292
+
+#define DC_DIV_QR_THRESHOLD 74
+#define DC_DIVAPPR_Q_THRESHOLD 406
+#define DC_BDIV_QR_THRESHOLD 63
+#define DC_BDIV_Q_THRESHOLD 363
+
+#define INV_MULMOD_BNM1_THRESHOLD 108
+#define INV_NEWTON_THRESHOLD 351
+#define INV_APPR_THRESHOLD 303
+
+#define BINV_NEWTON_THRESHOLD 354
+#define REDC_1_TO_REDC_N_THRESHOLD 61
+
+#define MU_DIV_QR_THRESHOLD 998
+#define MU_DIVAPPR_Q_THRESHOLD 1099
+#define MUPI_DIV_QR_THRESHOLD 118
+#define MU_BDIV_QR_THRESHOLD 807
+#define MU_BDIV_Q_THRESHOLD 979
+
+#define POWM_SEC_TABLE 3,22,127,624,779,2351
+
+#define MATRIX22_STRASSEN_THRESHOLD 7
+#define HGCD_THRESHOLD 90
+#define HGCD_APPR_THRESHOLD 123
+#define HGCD_REDUCE_THRESHOLD 1494
+#define GCD_DC_THRESHOLD 283
+#define GCDEXT_DC_THRESHOLD 192
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 27
+#define SET_STR_DC_THRESHOLD 290
+#define SET_STR_PRECOMPUTE_THRESHOLD 634
+
+#define FAC_DSC_THRESHOLD 156
+#define FAC_ODD_THRESHOLD 25
diff --git a/gmp/mpn/sparc32/v9/mul_1.asm b/gmp/mpn/sparc32/v9/mul_1.asm
new file mode 100644
index 0000000000..40aeffad4f
--- /dev/null
+++ b/gmp/mpn/sparc32/v9/mul_1.asm
@@ -0,0 +1,287 @@
+dnl SPARC v9 32-bit mpn_mul_1 -- Multiply a limb vector with a limb and store
+dnl the result in a second limb vector.
+
+dnl Copyright 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C Algorithm: We use two floating-point multiplies per limb product, with the
+C invariant v operand split into two 16-bit pieces, and the u operand split
+C into 32-bit pieces. We convert the two 48-bit products and transfer them to
+C the integer unit.
+
+C cycles/limb
+C UltraSPARC 1&2: 6.5
+C UltraSPARC 3: ?
+
+C Possible optimizations:
+C 1. Combine 32-bit memory operations into 64-bit operations. Since we're
+C memory bandwidth limited, this could save 1.5 cycles/limb.
+C 2. Unroll the inner loop. Since we already use alternate temporary areas,
+C it is very straightforward to unroll, using an exit branch midways.
+C Unrolling would allow deeper scheduling which could improve speed for L2
+C cache case.
+C 3. For mpn_mul_1: Use more alternating temp areas. The std'es and ldx'es
+C aren't sufficiently apart-scheduled with just two temp areas.
+C 4. Specialize for particular v values. If its upper 16 bits are zero, we
+C could save many operations.
+
+C INPUT PARAMETERS
+C rp i0
+C up i1
+C n i2
+C v i3
+
+define(`FSIZE',224)
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ add %sp, -FSIZE, %sp
+ sethi %hi(0xffff), %g1
+ srl %o3, 16, %g2
+ or %g1, %lo(0xffff), %g1
+ and %o3, %g1, %g1
+ stx %g1, [%sp+104]
+ stx %g2, [%sp+112]
+ ldd [%sp+104], %f6
+ ldd [%sp+112], %f8
+ fxtod %f6, %f6
+ fxtod %f8, %f8
+ ld [%sp+104], %f10 C zero f10
+
+ mov 0, %g3 C cy = 0
+
+define(`fanop', `fitod %f18, %f0') C A quasi nop running in the FA pipe
+
+ add %sp, 160, %o5 C point in scratch area
+ and %o5, -32, %o5 C align at 0 (mod 32) in scratch area
+
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_two_or_more
+ fxtod %f10, %f2
+
+ fmuld %f2, %f8, %f16
+ fmuld %f2, %f6, %f4
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+16]
+ std %f12, [%o5+24]
+ ldx [%o5+16], %g2 C p16
+ ldx [%o5+24], %g1 C p0
+ b .L1
+ add %o0, -16, %o0
+
+ .align 16
+.L_two_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fmuld %f2, %f8, %f16
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_three_or_more
+ fxtod %f10, %f2
+
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+0]
+ std %f12, [%o5+8]
+ ldx [%o5+16], %g2 C p16
+ ldx [%o5+24], %g1 C p0
+ b .L2
+ add %o0, -12, %o0
+
+ .align 16
+.L_three_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_four_or_more
+ fxtod %f10, %f2
+
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+ fdtox %f16, %f14
+ ldx [%o5+16], %g2 C p16
+ fdtox %f4, %f12
+ ldx [%o5+24], %g1 C p0
+ std %f14, [%o5+16]
+ std %f12, [%o5+24]
+ b .L3
+ add %o0, -8, %o0
+
+ .align 16
+.L_four_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_five_or_more
+ fxtod %f10, %f2
+
+ fdtox %f16, %f14
+ ldx [%o5+16], %g2 C p16
+ fdtox %f4, %f12
+ ldx [%o5+24], %g1 C p0
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ b .L4
+ add %o0, -4, %o0
+
+ .align 16
+.L_five_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+ ldx [%o5+16], %g2 C p16
+ fdtox %f4, %f12
+ ldx [%o5+24], %g1 C p0
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .Loop
+ fxtod %f10, %f2
+ b,a .L5
+
+C BEGIN MAIN LOOP
+ .align 16
+C -- 0
+.Loop: nop
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+C -- 1
+ sllx %g2, 16, %g4 C (p16 << 16)
+ add %o0, 4, %o0 C rp++
+ ldx [%o5+0], %g2 C p16
+ fdtox %f4, %f12
+C -- 2
+ nop
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ fanop
+C -- 3
+ nop
+ add %g3, %g4, %g4 C p += cy
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+C -- 4
+ srlx %g4, 32, %g3 C new cy
+ add %o1, 4, %o1 C up++
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+C -- 5
+ xor %o5, 16, %o5 C alternate scratch variables
+ stw %g4, [%o0-4]
+ bne,pt %icc, .Loop
+ fxtod %f10, %f2
+C END MAIN LOOP
+
+.L5: fdtox %f16, %f14
+ sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ fdtox %f4, %f12
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g4, %g3, %g4 C p += cy
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+ xor %o5, 16, %o5
+ stw %g4, [%o0+0]
+ srlx %g4, 32, %g3 C new cy
+
+.L4: fdtox %f16, %f14
+ sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ fdtox %f4, %f12
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g3, %g4, %g4 C p += cy
+ std %f14, [%o5+0]
+ std %f12, [%o5+8]
+ xor %o5, 16, %o5
+ stw %g4, [%o0+4]
+ srlx %g4, 32, %g3 C new cy
+
+.L3: sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g3, %g4, %g4 C p += cy
+ xor %o5, 16, %o5
+ stw %g4, [%o0+8]
+ srlx %g4, 32, %g3 C new cy
+
+.L2: sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g3, %g4, %g4 C p += cy
+ stw %g4, [%o0+12]
+ srlx %g4, 32, %g3 C new cy
+
+.L1: sllx %g2, 16, %g4 C (p16 << 16)
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ add %g3, %g4, %g4 C p += cy
+ stw %g4, [%o0+16]
+ srlx %g4, 32, %g3 C new cy
+
+ mov %g3, %o0
+ retl
+ sub %sp, -FSIZE, %sp
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/sparc32/v9/sqr_diagonal.asm b/gmp/mpn/sparc32/v9/sqr_diagonal.asm
new file mode 100644
index 0000000000..e024279849
--- /dev/null
+++ b/gmp/mpn/sparc32/v9/sqr_diagonal.asm
@@ -0,0 +1,462 @@
+dnl SPARC v9 32-bit mpn_sqr_diagonal.
+
+dnl Copyright 2001, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rp i0
+C up i1
+C n i2
+
+C This code uses a very deep software pipeline, due to the need for moving data
+C forth and back between the integer registers and floating-point registers.
+C
+C A VIS variant of this code would make the pipeline less deep, since the
+C masking now done in the integer unit could take place in the floating-point
+C unit using the FAND instruction. It would be possible to save several cycles
+C too.
+C
+C On UltraSPARC 1 and 2, this code runs at 11 cycles/limb from the Dcache and
+C not much slower from the Ecache. It would perhaps be possible to shave off
+C one cycle, but not easily. We cannot do better than 10 cycles/limb with the
+C used instructions, since we have 10 memory operations per limb. But a VIS
+C variant could run three cycles faster than the corresponding non-VIS code.
+
+C This is non-pipelined code showing the algorithm:
+C
+C .Loop:
+C lduw [up+0],%g4 C 00000000hhhhllll
+C sllx %g4,16,%g3 C 0000hhhhllll0000
+C or %g3,%g4,%g2 C 0000hhhhXXXXllll
+C andn %g2,%g5,%g2 C 0000hhhh0000llll
+C stx %g2,[%fp+80]
+C ldd [%fp+80],%f0
+C fitod %f0,%f4 C hi16
+C fitod %f1,%f6 C lo16
+C ld [up+0],%f9
+C fxtod %f8,%f2
+C fmuld %f2,%f4,%f4
+C fmuld %f2,%f6,%f6
+C fdtox %f4,%f4
+C fdtox %f6,%f6
+C std %f4,[%fp-24]
+C std %f6,[%fp-16]
+C ldx [%fp-24],%g2
+C ldx [%fp-16],%g1
+C sllx %g2,16,%g2
+C add %g2,%g1,%g1
+C stw %g1,[rp+0]
+C srlx %g1,32,%l0
+C stw %l0,[rp+4]
+C add up,4,up
+C subcc n,1,n
+C bne,pt %icc,.Loop
+C add rp,8,rp
+
+define(`fanop',`fitod %f12,%f10') dnl A quasi nop running in the FA pipe
+
+ASM_START()
+
+ TEXT
+ ALIGN(4)
+.Lnoll:
+ .word 0
+
+PROLOGUE(mpn_sqr_diagonal)
+ save %sp,-256,%sp
+
+ifdef(`PIC',
+`.Lpc: rd %pc,%o7
+ ld [%o7+.Lnoll-.Lpc],%f8',
+` sethi %hi(.Lnoll),%g1
+ ld [%g1+%lo(.Lnoll)],%f8')
+
+ sethi %hi(0xffff0000),%g5
+ add %i1,-8,%i1
+
+ lduw [%i1+8],%g4
+ add %i1,4,%i1 C s1_ptr++
+ sllx %g4,16,%g3 C 0000hhhhllll0000
+ or %g3,%g4,%g2 C 0000hhhhXXXXllll
+ subcc %i2,1,%i2
+ bne,pt %icc,.L_grt_1
+ andn %g2,%g5,%g2 C 0000hhhh0000llll
+
+ add %i1,4,%i1 C s1_ptr++
+ stx %g2,[%fp+80]
+ ld [%i1],%f9
+ ldd [%fp+80],%f0
+ fxtod %f8,%f2
+ fitod %f0,%f4
+ fitod %f1,%f6
+ fmuld %f2,%f4,%f4
+ fmuld %f2,%f6,%f6
+ fdtox %f4,%f4
+ fdtox %f6,%f6
+ std %f4,[%fp-24]
+ std %f6,[%fp-16]
+
+ add %fp, 80, %l3
+ add %fp, -24, %l4
+ add %fp, 72, %l5
+ b .L1
+ add %fp, -40, %l6
+
+.L_grt_1:
+ stx %g2,[%fp+80]
+ lduw [%i1+8],%g4
+ add %i1,4,%i1 C s1_ptr++
+ sllx %g4,16,%g3 C 0000hhhhllll0000
+ or %g3,%g4,%g2 C 0000hhhhXXXXllll
+ subcc %i2,1,%i2
+ bne,pt %icc,.L_grt_2
+ andn %g2,%g5,%g2 C 0000hhhh0000llll
+
+ stx %g2,[%fp+72]
+ ld [%i1],%f9
+ add %i1,4,%i1 C s1_ptr++
+ ldd [%fp+80],%f0
+ fxtod %f8,%f2
+ fitod %f0,%f4
+ fitod %f1,%f6
+ fmuld %f2,%f4,%f4
+ ld [%i1],%f9
+ fmuld %f2,%f6,%f6
+ ldd [%fp+72],%f0
+ fdtox %f4,%f4
+ fdtox %f6,%f6
+ std %f4,[%fp-24]
+ fxtod %f8,%f2
+ std %f6,[%fp-16]
+ fitod %f0,%f4
+ fitod %f1,%f6
+ fmuld %f2,%f4,%f4
+ fmuld %f2,%f6,%f6
+ fdtox %f4,%f4
+
+ add %fp, 72, %l3
+ add %fp, -40, %l4
+ add %fp, 80, %l5
+ b .L2
+ add %fp, -24, %l6
+
+.L_grt_2:
+ stx %g2,[%fp+72]
+ lduw [%i1+8],%g4
+ ld [%i1],%f9
+ add %i1,4,%i1 C s1_ptr++
+ ldd [%fp+80],%f0
+ sllx %g4,16,%g3 C 0000hhhhllll0000
+ or %g3,%g4,%g2 C 0000hhhhXXXXllll
+ subcc %i2,1,%i2
+ fxtod %f8,%f2
+ bne,pt %icc,.L_grt_3
+ andn %g2,%g5,%g2 C 0000hhhh0000llll
+
+ stx %g2,[%fp+80]
+ fitod %f0,%f4
+ fitod %f1,%f6
+ fmuld %f2,%f4,%f4
+ ld [%i1],%f9
+ fmuld %f2,%f6,%f6
+ add %i1,4,%i1 C s1_ptr++
+ ldd [%fp+72],%f0
+ fdtox %f4,%f4
+ fdtox %f6,%f6
+ std %f4,[%fp-24]
+ fxtod %f8,%f2
+ std %f6,[%fp-16]
+ fitod %f0,%f4
+ fitod %f1,%f6
+ fmuld %f2,%f4,%f4
+ ld [%i1],%f9
+ add %fp, 80, %l3
+ fmuld %f2,%f6,%f6
+ add %fp, -24, %l4
+ ldd [%fp+80],%f0
+ add %fp, 72, %l5
+ fdtox %f4,%f4
+ b .L3
+ add %fp, -40, %l6
+
+.L_grt_3:
+ stx %g2,[%fp+80]
+ fitod %f0,%f4
+ lduw [%i1+8],%g4
+ fitod %f1,%f6
+ fmuld %f2,%f4,%f4
+ ld [%i1],%f9
+ fmuld %f2,%f6,%f6
+ add %i1,4,%i1 C s1_ptr++
+ ldd [%fp+72],%f0
+ fdtox %f4,%f4
+ sllx %g4,16,%g3 C 0000hhhhllll0000
+ fdtox %f6,%f6
+ or %g3,%g4,%g2 C 0000hhhhXXXXllll
+ subcc %i2,1,%i2
+ std %f4,[%fp-24]
+ fxtod %f8,%f2
+ std %f6,[%fp-16]
+ bne,pt %icc,.L_grt_4
+ andn %g2,%g5,%g2 C 0000hhhh0000llll
+
+ stx %g2,[%fp+72]
+ fitod %f0,%f4
+ fitod %f1,%f6
+ add %fp, 72, %l3
+ fmuld %f2,%f4,%f4
+ add %fp, -40, %l4
+ ld [%i1],%f9
+ fmuld %f2,%f6,%f6
+ add %i1,4,%i1 C s1_ptr++
+ ldd [%fp+80],%f0
+ add %fp, 80, %l5
+ fdtox %f4,%f4
+ b .L4
+ add %fp, -24, %l6
+
+.L_grt_4:
+ stx %g2,[%fp+72]
+ fitod %f0,%f4
+ lduw [%i1+8],%g4
+ fitod %f1,%f6
+ fmuld %f2,%f4,%f4
+ ld [%i1],%f9
+ fmuld %f2,%f6,%f6
+ add %i1,4,%i1 C s1_ptr++
+ ldd [%fp+80],%f0
+ fdtox %f4,%f4
+ sllx %g4,16,%g3 C 0000hhhhllll0000
+ fdtox %f6,%f6
+ or %g3,%g4,%g2 C 0000hhhhXXXXllll
+ subcc %i2,1,%i2
+ std %f4,[%fp-40]
+ fxtod %f8,%f2
+ std %f6,[%fp-32]
+ be,pn %icc,.L5
+ andn %g2,%g5,%g2 C 0000hhhh0000llll
+
+ b,a .Loop
+
+ .align 16
+C --- LOOP BEGIN
+.Loop: nop
+ nop
+ stx %g2,[%fp+80]
+ fitod %f0,%f4
+C ---
+ nop
+ nop
+ lduw [%i1+8],%g4
+ fitod %f1,%f6
+C ---
+ nop
+ nop
+ ldx [%fp-24],%g2 C p16
+ fanop
+C ---
+ nop
+ nop
+ ldx [%fp-16],%g1 C p0
+ fmuld %f2,%f4,%f4
+C ---
+ sllx %g2,16,%g2 C align p16
+ add %i0,8,%i0 C res_ptr++
+ ld [%i1],%f9
+ fmuld %f2,%f6,%f6
+C ---
+ add %g2,%g1,%g1 C add p16 to p0 (ADD1)
+ add %i1,4,%i1 C s1_ptr++
+ ldd [%fp+72],%f0
+ fanop
+C ---
+ srlx %g1,32,%l0
+ nop
+ stw %g1,[%i0-8]
+ fdtox %f4,%f4
+C ---
+ sllx %g4,16,%g3 C 0000hhhhllll0000
+ nop
+ stw %l0,[%i0-4]
+ fdtox %f6,%f6
+C ---
+ or %g3,%g4,%g2 C 0000hhhhXXXXllll
+ subcc %i2,1,%i2
+ std %f4,[%fp-24]
+ fxtod %f8,%f2
+C ---
+ std %f6,[%fp-16]
+ andn %g2,%g5,%g2 C 0000hhhh0000llll
+ be,pn %icc,.Lend
+ fanop
+C --- LOOP MIDDLE
+ nop
+ nop
+ stx %g2,[%fp+72]
+ fitod %f0,%f4
+C ---
+ nop
+ nop
+ lduw [%i1+8],%g4
+ fitod %f1,%f6
+C ---
+ nop
+ nop
+ ldx [%fp-40],%g2 C p16
+ fanop
+C ---
+ nop
+ nop
+ ldx [%fp-32],%g1 C p0
+ fmuld %f2,%f4,%f4
+C ---
+ sllx %g2,16,%g2 C align p16
+ add %i0,8,%i0 C res_ptr++
+ ld [%i1],%f9
+ fmuld %f2,%f6,%f6
+C ---
+ add %g2,%g1,%g1 C add p16 to p0 (ADD1)
+ add %i1,4,%i1 C s1_ptr++
+ ldd [%fp+80],%f0
+ fanop
+C ---
+ srlx %g1,32,%l0
+ nop
+ stw %g1,[%i0-8]
+ fdtox %f4,%f4
+C ---
+ sllx %g4,16,%g3 C 0000hhhhllll0000
+ nop
+ stw %l0,[%i0-4]
+ fdtox %f6,%f6
+C ---
+ or %g3,%g4,%g2 C 0000hhhhXXXXllll
+ subcc %i2,1,%i2
+ std %f4,[%fp-40]
+ fxtod %f8,%f2
+C ---
+ std %f6,[%fp-32]
+ andn %g2,%g5,%g2 C 0000hhhh0000llll
+ bne,pt %icc,.Loop
+ fanop
+C --- LOOP END
+
+.L5: add %fp, 80, %l3
+ add %fp, -24, %l4
+ add %fp, 72, %l5
+ b .Ltail
+ add %fp, -40, %l6
+
+.Lend: add %fp, 72, %l3
+ add %fp, -40, %l4
+ add %fp, 80, %l5
+ add %fp, -24, %l6
+.Ltail: stx %g2,[%l3]
+ fitod %f0,%f4
+ fitod %f1,%f6
+ ldx [%l4],%g2 C p16
+ ldx [%l4+8],%g1 C p0
+ fmuld %f2,%f4,%f4
+ sllx %g2,16,%g2 C align p16
+ add %i0,8,%i0 C res_ptr++
+ ld [%i1],%f9
+ fmuld %f2,%f6,%f6
+ add %g2,%g1,%g1 C add p16 to p0 (ADD1)
+ add %i1,4,%i1 C s1_ptr++
+ ldd [%l5],%f0
+ srlx %g1,32,%l0
+ stw %g1,[%i0-8]
+ fdtox %f4,%f4
+ stw %l0,[%i0-4]
+.L4: fdtox %f6,%f6
+ std %f4,[%l4]
+ fxtod %f8,%f2
+ std %f6,[%l4+8]
+
+ fitod %f0,%f4
+ fitod %f1,%f6
+ ldx [%l6],%g2 C p16
+ ldx [%l6+8],%g1 C p0
+ fmuld %f2,%f4,%f4
+ sllx %g2,16,%g2 C align p16
+ add %i0,8,%i0 C res_ptr++
+ ld [%i1],%f9
+ fmuld %f2,%f6,%f6
+ add %g2,%g1,%g1 C add p16 to p0 (ADD1)
+ ldd [%l3],%f0
+ srlx %g1,32,%l0
+ stw %g1,[%i0-8]
+ fdtox %f4,%f4
+ stw %l0,[%i0-4]
+.L3: fdtox %f6,%f6
+ std %f4,[%l6]
+ fxtod %f8,%f2
+ std %f6,[%l6+8]
+
+ fitod %f0,%f4
+ fitod %f1,%f6
+ ldx [%l4],%g2 C p16
+ ldx [%l4+8],%g1 C p0
+ fmuld %f2,%f4,%f4
+ sllx %g2,16,%g2 C align p16
+ add %i0,8,%i0 C res_ptr++
+ fmuld %f2,%f6,%f6
+ add %g2,%g1,%g1 C add p16 to p0 (ADD1)
+ srlx %g1,32,%l0
+ stw %g1,[%i0-8]
+ fdtox %f4,%f4
+ stw %l0,[%i0-4]
+.L2: fdtox %f6,%f6
+ std %f4,[%l4]
+ std %f6,[%l4+8]
+
+ ldx [%l6],%g2 C p16
+ ldx [%l6+8],%g1 C p0
+ sllx %g2,16,%g2 C align p16
+ add %i0,8,%i0 C res_ptr++
+ add %g2,%g1,%g1 C add p16 to p0 (ADD1)
+ srlx %g1,32,%l0
+ stw %g1,[%i0-8]
+ stw %l0,[%i0-4]
+
+.L1: ldx [%l4],%g2 C p16
+ ldx [%l4+8],%g1 C p0
+ sllx %g2,16,%g2 C align p16
+ add %i0,8,%i0 C res_ptr++
+ add %g2,%g1,%g1 C add p16 to p0 (ADD1)
+ srlx %g1,32,%l0
+ stw %g1,[%i0-8]
+ stw %l0,[%i0-4]
+
+ ret
+ restore %g0,%g0,%o0
+
+EPILOGUE(mpn_sqr_diagonal)
diff --git a/gmp/mpn/sparc32/v9/sub_n.asm b/gmp/mpn/sparc32/v9/sub_n.asm
new file mode 100644
index 0000000000..636c73bf35
--- /dev/null
+++ b/gmp/mpn/sparc32/v9/sub_n.asm
@@ -0,0 +1,129 @@
+dnl SPARC mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+dnl store difference in a third limb vector.
+
+dnl Copyright 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(rp,%o0)
+define(s1p,%o1)
+define(s2p,%o2)
+define(n,%o3)
+define(cy,%g1)
+
+C This code uses 64-bit operations on `o' and `g' registers. It doesn't
+C require that `o' registers' upper 32 bits are preserved by the operating
+C system, but if they are not, they must be zeroed. That is indeed what
+C happens at least on Slowaris 2.5 and 2.6.
+
+C On UltraSPARC 1 and 2, this code runs at 3 cycles/limb from the Dcache and at
+C about 10 cycles/limb from the Ecache.
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ lduw [s1p+0],%o4
+ lduw [s2p+0],%o5
+ addcc n,-2,n
+ bl,pn %icc,L(end1)
+ lduw [s1p+4],%g2
+ lduw [s2p+4],%g3
+ be,pn %icc,L(end2)
+ mov 0,cy
+
+ .align 16
+L(loop):
+ sub %o4,%o5,%g4
+ add rp,8,rp
+ lduw [s1p+8],%o4
+ fitod %f0,%f2
+C ---
+ sub %g4,cy,%g4
+ addcc n,-1,n
+ lduw [s2p+8],%o5
+ fitod %f0,%f2
+C ---
+ srlx %g4,63,cy
+ add s2p,8,s2p
+ stw %g4,[rp-8]
+ be,pn %icc,L(exito)+4
+C ---
+ sub %g2,%g3,%g4
+ addcc n,-1,n
+ lduw [s1p+12],%g2
+ fitod %f0,%f2
+C ---
+ sub %g4,cy,%g4
+ add s1p,8,s1p
+ lduw [s2p+4],%g3
+ fitod %f0,%f2
+C ---
+ srlx %g4,63,cy
+ bne,pt %icc,L(loop)
+ stw %g4,[rp-4]
+C ---
+L(exite):
+ sub %o4,%o5,%g4
+ sub %g4,cy,%g4
+ srlx %g4,63,cy
+ stw %g4,[rp+0]
+ sub %g2,%g3,%g4
+ sub %g4,cy,%g4
+ stw %g4,[rp+4]
+ retl
+ srlx %g4,63,%o0
+
+L(exito):
+ sub %g2,%g3,%g4
+ sub %g4,cy,%g4
+ srlx %g4,63,cy
+ stw %g4,[rp-4]
+ sub %o4,%o5,%g4
+ sub %g4,cy,%g4
+ stw %g4,[rp+0]
+ retl
+ srlx %g4,63,%o0
+
+L(end1):
+ sub %o4,%o5,%g4
+ stw %g4,[rp+0]
+ retl
+ srlx %g4,63,%o0
+
+L(end2):
+ sub %o4,%o5,%g4
+ srlx %g4,63,cy
+ stw %g4,[rp+0]
+ sub %g2,%g3,%g4
+ sub %g4,cy,%g4
+ stw %g4,[rp+4]
+ retl
+ srlx %g4,63,%o0
+EPILOGUE(mpn_sub_n)
diff --git a/gmp/mpn/sparc32/v9/submul_1.asm b/gmp/mpn/sparc32/v9/submul_1.asm
new file mode 100644
index 0000000000..92d0ce7db9
--- /dev/null
+++ b/gmp/mpn/sparc32/v9/submul_1.asm
@@ -0,0 +1,316 @@
+dnl SPARC v9 32-bit mpn_submul_1 -- Multiply a limb vector with a limb and
+dnl subtract the result from a second limb vector.
+
+dnl Copyright 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C Algorithm: We use two floating-point multiplies per limb product, with the
+C invariant v operand split into two 16-bit pieces, and the u operand split
+C into 32-bit pieces. We convert the two 48-bit products and transfer them to
+C the integer unit.
+
+C cycles/limb
+C UltraSPARC 1&2: 6.5
+C UltraSPARC 3: ?
+
+C Possible optimizations:
+C 1. Combine 32-bit memory operations into 64-bit operations. Since we're
+C memory bandwidth limited, this could save 1.5 cycles/limb.
+C 2. Unroll the inner loop. Since we already use alternate temporary areas,
+C it is very straightforward to unroll, using an exit branch midways.
+C Unrolling would allow deeper scheduling which could improve speed for L2
+C cache case.
+C 3. For mpn_mul_1: Use more alternating temp areas. The std'es and ldx'es
+C aren't sufficiently apart-scheduled with just two temp areas.
+C 4. Specialize for particular v values. If its upper 16 bits are zero, we
+C could save many operations.
+
+C INPUT PARAMETERS
+C rp i0
+C up i1
+C n i2
+C v i3
+
+define(`FSIZE',224)
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ add %sp, -FSIZE, %sp
+ sethi %hi(0xffff), %g1
+ srl %o3, 16, %g2
+ or %g1, %lo(0xffff), %g1
+ and %o3, %g1, %g1
+ stx %g1, [%sp+104]
+ stx %g2, [%sp+112]
+ ldd [%sp+104], %f6
+ ldd [%sp+112], %f8
+ fxtod %f6, %f6
+ fxtod %f8, %f8
+ ld [%sp+104], %f10 C zero f10
+
+ mov 0, %g3 C cy = 0
+
+define(`fanop', `fitod %f18, %f0') C A quasi nop running in the FA pipe
+
+ add %sp, 160, %o5 C point in scratch area
+ and %o5, -32, %o5 C align at 0 (mod 32) in scratch area
+
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_two_or_more
+ fxtod %f10, %f2
+
+ fmuld %f2, %f8, %f16
+ fmuld %f2, %f6, %f4
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+16]
+ std %f12, [%o5+24]
+ ldx [%o5+16], %g2 C p16
+ ldx [%o5+24], %g1 C p0
+ lduw [%o0], %g5 C read rp[i]
+ b .L1
+ add %o0, -16, %o0
+
+ .align 16
+.L_two_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fmuld %f2, %f8, %f16
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_three_or_more
+ fxtod %f10, %f2
+
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+0]
+ std %f12, [%o5+8]
+ lduw [%o0], %g5 C read rp[i]
+ ldx [%o5+16], %g2 C p16
+ ldx [%o5+24], %g1 C p0
+ b .L2
+ add %o0, -12, %o0
+
+ .align 16
+.L_three_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_four_or_more
+ fxtod %f10, %f2
+
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+ fdtox %f16, %f14
+ ldx [%o5+16], %g2 C p16
+ fdtox %f4, %f12
+ ldx [%o5+24], %g1 C p0
+ std %f14, [%o5+16]
+ std %f12, [%o5+24]
+ lduw [%o0], %g5 C read rp[i]
+ b .L3
+ add %o0, -8, %o0
+
+ .align 16
+.L_four_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+ fdtox %f4, %f12
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ bne,pt %icc, .L_five_or_more
+ fxtod %f10, %f2
+
+ fdtox %f16, %f14
+ ldx [%o5+16], %g2 C p16
+ fdtox %f4, %f12
+ ldx [%o5+24], %g1 C p0
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ lduw [%o0], %g5 C read rp[i]
+ b .L4
+ add %o0, -4, %o0
+
+ .align 16
+.L_five_or_more:
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+ ldx [%o5+16], %g2 C p16
+ fdtox %f4, %f12
+ ldx [%o5+24], %g1 C p0
+ std %f14, [%o5+16]
+ fmuld %f2, %f8, %f16
+ std %f12, [%o5+24]
+ fmuld %f2, %f6, %f4
+ add %o1, 4, %o1 C up++
+ lduw [%o0], %g5 C read rp[i]
+ bne,pt %icc, .Loop
+ fxtod %f10, %f2
+ b,a .L5
+
+C BEGIN MAIN LOOP
+ .align 16
+C -- 0
+.Loop: sub %g0, %g3, %g3
+ subcc %o2, 1, %o2
+ ld [%o1], %f11 C read up[i]
+ fdtox %f16, %f14
+C -- 1
+ sllx %g2, 16, %g4 C (p16 << 16)
+ add %o0, 4, %o0 C rp++
+ ldx [%o5+0], %g2 C p16
+ fdtox %f4, %f12
+C -- 2
+ srl %g3, 0, %g3 C zero most significant 32 bits
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ fanop
+C -- 3
+ nop
+ add %g3, %g4, %g4 C p += cy
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+C -- 4
+ nop
+ sub %g5, %g4, %g4 C p += rp[i]
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+C -- 5
+ xor %o5, 16, %o5 C alternate scratch variables
+ add %o1, 4, %o1 C up++
+ stw %g4, [%o0-4]
+ fanop
+C -- 6
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0], %g5 C read rp[i]
+ bne,pt %icc, .Loop
+ fxtod %f10, %f2
+C END MAIN LOOP
+
+.L5: sub %g0, %g3, %g3
+ fdtox %f16, %f14
+ sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ fdtox %f4, %f12
+ srl %g3, 0, %g3 C zero most significant 32 bits
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g4, %g3, %g4 C p += cy
+ std %f14, [%o5+0]
+ fmuld %f2, %f8, %f16
+ sub %g5, %g4, %g4 C p += rp[i]
+ std %f12, [%o5+8]
+ fmuld %f2, %f6, %f4
+ xor %o5, 16, %o5
+ stw %g4, [%o0+0]
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0+4], %g5 C read rp[i]
+
+ sub %g0, %g3, %g3
+.L4: fdtox %f16, %f14
+ sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ fdtox %f4, %f12
+ srl %g3, 0, %g3 C zero most significant 32 bits
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g3, %g4, %g4 C p += cy
+ std %f14, [%o5+0]
+ sub %g5, %g4, %g4 C p += rp[i]
+ std %f12, [%o5+8]
+ xor %o5, 16, %o5
+ stw %g4, [%o0+4]
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0+8], %g5 C read rp[i]
+
+ sub %g0, %g3, %g3
+.L3: sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ srl %g3, 0, %g3 C zero most significant 32 bits
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g3, %g4, %g4 C p += cy
+ sub %g5, %g4, %g4 C p += rp[i]
+ xor %o5, 16, %o5
+ stw %g4, [%o0+8]
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0+12], %g5 C read rp[i]
+
+ sub %g0, %g3, %g3
+.L2: sllx %g2, 16, %g4 C (p16 << 16)
+ ldx [%o5+0], %g2 C p16
+ srl %g3, 0, %g3 C zero most significant 32 bits
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ ldx [%o5+8], %g1 C p0
+ add %g3, %g4, %g4 C p += cy
+ sub %g5, %g4, %g4 C p += rp[i]
+ stw %g4, [%o0+12]
+ srlx %g4, 32, %g3 C new cy
+ lduw [%o0+16], %g5 C read rp[i]
+
+ sub %g0, %g3, %g3
+.L1: sllx %g2, 16, %g4 C (p16 << 16)
+ srl %g3, 0, %g3 C zero most significant 32 bits
+ add %g1, %g4, %g4 C p = p0 + (p16 << 16)
+ add %g3, %g4, %g4 C p += cy
+ sub %g5, %g4, %g4 C p += rp[i]
+ stw %g4, [%o0+16]
+ srlx %g4, 32, %g3 C new cy
+
+ sub %g0, %g3, %o0
+ retl
+ sub %sp, -FSIZE, %sp
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/sparc32/v9/udiv.asm b/gmp/mpn/sparc32/v9/udiv.asm
new file mode 100644
index 0000000000..61dde97a66
--- /dev/null
+++ b/gmp/mpn/sparc32/v9/udiv.asm
@@ -0,0 +1,52 @@
+dnl SPARC v9 32-bit mpn_udiv_qrnnd - division support for longlong.h.
+
+dnl Copyright 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+C rem_ptr o0
+C n1 o1
+C n0 o2
+C d o3
+
+ASM_START()
+PROLOGUE(mpn_udiv_qrnnd)
+ sllx %o1, 32, %g1 C shift upper dividend limb
+ srl %o2, 0, %g2 C zero extend lower dividend limb
+ srl %o3, 0, %g3 C zero extend divisor
+ or %g2, %g1, %g1 C assemble 64-bit dividend
+ udivx %g1, %g3, %g1
+ mulx %g1, %g3, %g4
+ sub %g2, %g4, %g2
+ st %g2, [%o0] C store remainder
+ retl
+ mov %g1, %o0 C return quotient
+EPILOGUE(mpn_udiv_qrnnd)
diff --git a/gmp/mpn/sparc64/README b/gmp/mpn/sparc64/README
new file mode 100644
index 0000000000..e2c051a02b
--- /dev/null
+++ b/gmp/mpn/sparc64/README
@@ -0,0 +1,125 @@
+Copyright 1997, 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+This directory contains mpn functions for 64-bit V9 SPARC
+
+RELEVANT OPTIMIZATION ISSUES
+
+Notation:
+ IANY = shift/add/sub/logical/sethi
+ IADDLOG = add/sub/logical/sethi
+ MEM = ld*/st*
+ FA = fadd*/fsub*/f*to*/fmov*
+ FM = fmul*
+
+UltraSPARC can issue four instructions per cycle, with these restrictions:
+* Two IANY instructions, but only one of these may be a shift. If there is a
+ shift and an IANY instruction, the shift must precede the IANY instruction.
+* One FA.
+* One FM.
+* One branch.
+* One MEM.
+* IANY/IADDLOG/MEM must be insn 1, 2, or 3 in an issue bundle. Taken branches
+ should not be in slot 4, since that makes the delay insn come from separate
+ bundle.
+* If two IANY/IADDLOG instructions are to be executed in the same cycle and one
+ of these is setting the condition codes, that instruction must be the second
+ one.
+
+To summarize, ignoring branches, these are the bundles that can reach the peak
+execution speed:
+
+insn1 iany iany mem iany iany mem iany iany mem
+insn2 iaddlog mem iany mem iaddlog iany mem iaddlog iany
+insn3 mem iaddlog iaddlog fa fa fa fm fm fm
+insn4 fa/fm fa/fm fa/fm fm fm fm fa fa fa
+
+The 64-bit integer multiply instruction mulx takes from 5 cycles to 35 cycles,
+depending on the position of the most significant bit of the first source
+operand. When used for 32x32->64 multiplication, it needs 20 cycles.
+Furthermore, it stalls the processor while executing. We stay away from that
+instruction, and instead use floating-point operations.
+
+Floating-point add and multiply units are fully pipelined. The latency for
+UltraSPARC-1/2 is 3 cycles and for UltraSPARC-3 it is 4 cycles.
+
+Integer conditional move instructions cannot dual-issue with other integer
+instructions. No conditional move can issue 1-5 cycles after a load. (This
+might have been fixed for UltraSPARC-3.)
+
+The UltraSPARC-3 pipeline is very simular to the one of UltraSPARC-1/2 , but is
+somewhat slower. Branches execute slower, and there may be other new stalls.
+But integer multiply doesn't stall the entire CPU and also has a much lower
+latency. But it's still not pipelined, and thus useless for our needs.
+
+STATUS
+
+* mpn_lshift, mpn_rshift: The current code runs at 2.0 cycles/limb on
+ UltraSPARC-1/2 and 2.65 on UltraSPARC-3. For UltraSPARC-1/2, the IEU0
+ functional unit is saturated with shifts.
+
+* mpn_add_n, mpn_sub_n: The current code runs at 4 cycles/limb on
+ UltraSPARC-1/2 and 4.5 cycles/limb on UltraSPARC-3. The 4 instruction
+ recurrency is the speed limiter.
+
+* mpn_addmul_1: The current code runs at 14 cycles/limb asymptotically on
+ UltraSPARC-1/2 and 17.5 cycles/limb on UltraSPARC-3. On UltraSPARC-1/2, the
+ code sustains 4 instructions/cycle. It might be possible to invent a better
+ way of summing the intermediate 49-bit operands, but it is unlikely that it
+ will save enough instructions to save an entire cycle.
+
+ The load-use of the u operand is not enough scheduled for good L2 cache
+ performance. The UltraSPARC-1/2 L1 cache is direct mapped, and since we use
+ temporary stack slots that will conflict with the u and r operands, we miss
+ to L2 very often. The load-use of the std/ldx pairs via the stack are
+ perhaps over-scheduled.
+
+ It would be possible to save two instructions: (1) The mov could be avoided
+ if the std/ldx were less scheduled. (2) The ldx of the r operand could be
+ split into two ld instructions, saving the shifts/masks.
+
+ It should be possible to reach 14 cycles/limb for UltraSPARC-3 if the fp
+ operations where rescheduled for this processor's 4-cycle latency.
+
+* mpn_mul_1: The current code is a straightforward edit of the mpn_addmul_1
+ code. It would be possible to shave one or two cycles from it, with some
+ labour.
+
+* mpn_submul_1: Simpleminded code just calling mpn_mul_1 + mpn_sub_n. This
+ means that it runs at 18 cycles/limb on UltraSPARC-1/2 and 23 cycles/limb on
+ UltraSPARC-3. It would be possible to either match the mpn_addmul_1
+ performance, or in the worst case use one more instruction group.
+
+* US1/US2 cache conflict resolving. The direct mapped L1 date cache of US1/US2
+ is a problem for mul_1, addmul_1 (and a prospective submul_1). We should
+ allocate a larger cache area, and put the stack temp area in a place that
+ doesn't cause cache conflicts.
diff --git a/gmp/mpn/sparc64/copyd.asm b/gmp/mpn/sparc64/copyd.asm
new file mode 100644
index 0000000000..ab105d39c7
--- /dev/null
+++ b/gmp/mpn/sparc64/copyd.asm
@@ -0,0 +1,89 @@
+dnl SPARC v9 mpn_copyd -- Copy a limb vector, decrementing.
+
+dnl Copyright 1999-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 2
+C UltraSPARC 3: 2.5
+C UltraSPARC T1: 17
+C UltraSPARC T3: 6
+C UltraSPARC T4/T5: 2
+
+C INPUT PARAMETERS
+C rptr %o0
+C sptr %o1
+C n %o2
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_copyd)
+ sllx %o2,3,%g1
+ add %g1,%o0,%o0
+ add %g1,%o1,%o1
+ addcc %o2,-8,%o2
+ bl,pt %xcc,L(end01234567)
+ nop
+L(loop1):
+ ldx [%o1-8],%g1
+ ldx [%o1-16],%g2
+ ldx [%o1-24],%g3
+ ldx [%o1-32],%g4
+ ldx [%o1-40],%g5
+ ldx [%o1-48],%o3
+ ldx [%o1-56],%o4
+ ldx [%o1-64],%o5
+ add %o1,-64,%o1
+ stx %g1,[%o0-8]
+ stx %g2,[%o0-16]
+ stx %g3,[%o0-24]
+ stx %g4,[%o0-32]
+ stx %g5,[%o0-40]
+ stx %o3,[%o0-48]
+ stx %o4,[%o0-56]
+ stx %o5,[%o0-64]
+ addcc %o2,-8,%o2
+ bge,pt %xcc,L(loop1)
+ add %o0,-64,%o0
+L(end01234567):
+ addcc %o2,8,%o2
+ bz,pn %xcc,L(end)
+ nop
+L(loop2):
+ ldx [%o1-8],%g1
+ add %o1,-8,%o1
+ addcc %o2,-1,%o2
+ stx %g1,[%o0-8]
+ bg,pt %xcc,L(loop2)
+ add %o0,-8,%o0
+L(end): retl
+ nop
+EPILOGUE(mpn_copyd)
diff --git a/gmp/mpn/sparc64/copyi.asm b/gmp/mpn/sparc64/copyi.asm
new file mode 100644
index 0000000000..45663dc2a3
--- /dev/null
+++ b/gmp/mpn/sparc64/copyi.asm
@@ -0,0 +1,86 @@
+dnl SPARC v9 mpn_copyi -- Copy a limb vector, incrementing.
+
+dnl Copyright 1999-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 2
+C UltraSPARC 3: 2.5
+C UltraSPARC T1: 17
+C UltraSPARC T3: 6
+C UltraSPARC T4/T5: 2
+
+C INPUT PARAMETERS
+C rptr %o0
+C sptr %o1
+C n %o2
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_copyi)
+ addcc %o2,-8,%o2
+ bl,pt %xcc,L(end01234567)
+ nop
+L(loop1):
+ ldx [%o1+0],%g1
+ ldx [%o1+8],%g2
+ ldx [%o1+16],%g3
+ ldx [%o1+24],%g4
+ ldx [%o1+32],%g5
+ ldx [%o1+40],%o3
+ ldx [%o1+48],%o4
+ ldx [%o1+56],%o5
+ add %o1,64,%o1
+ stx %g1,[%o0+0]
+ stx %g2,[%o0+8]
+ stx %g3,[%o0+16]
+ stx %g4,[%o0+24]
+ stx %g5,[%o0+32]
+ stx %o3,[%o0+40]
+ stx %o4,[%o0+48]
+ stx %o5,[%o0+56]
+ addcc %o2,-8,%o2
+ bge,pt %xcc,L(loop1)
+ add %o0,64,%o0
+L(end01234567):
+ addcc %o2,8,%o2
+ bz,pn %xcc,L(end)
+ nop
+L(loop2):
+ ldx [%o1+0],%g1
+ add %o1,8,%o1
+ addcc %o2,-1,%o2
+ stx %g1,[%o0+0]
+ bg,pt %xcc,L(loop2)
+ add %o0,8,%o0
+L(end): retl
+ nop
+EPILOGUE(mpn_copyi)
diff --git a/gmp/mpn/sparc64/dive_1.c b/gmp/mpn/sparc64/dive_1.c
new file mode 100644
index 0000000000..c3fbf01b14
--- /dev/null
+++ b/gmp/mpn/sparc64/dive_1.c
@@ -0,0 +1,158 @@
+/* UltraSPARC 64 mpn_divexact_1 -- mpn by limb exact division.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2000, 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#include "mpn/sparc64/sparc64.h"
+
+
+/* 64-bit divisor 32-bit divisor
+ cycles/limb cycles/limb
+ (approx) (approx)
+ Ultrasparc 2i: 110 70
+*/
+
+
+/* There are two key ideas here to reduce mulx's. Firstly when the divisor
+ is 32-bits the high of q*d can be calculated without the two 32x32->64
+ cross-products involving the high 32-bits of the divisor, that being zero
+ of course. Secondly umul_ppmm_lowequal and umul_ppmm_half_lowequal save
+ one mulx (each) knowing the low of q*d is equal to the input limb l.
+
+ For size==1, a simple udivx is used. This is faster than calculating an
+ inverse.
+
+ For a 32-bit divisor and small sizes, an attempt was made at a simple
+ udivx loop (two per 64-bit limb), but it turned out to be slower than
+ mul-by-inverse. At size==2 the inverse is about 260 cycles total
+ compared to a udivx at 291. Perhaps the latter would suit when size==2
+ but the high 32-bits of the second limb is zero (saving one udivx), but
+ it doesn't seem worth a special case just for that. */
+
+void
+mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor)
+{
+ mp_limb_t inverse, s, s_next, c, l, ls, q;
+ unsigned rshift, lshift;
+ mp_limb_t lshift_mask;
+ mp_limb_t divisor_h;
+
+ ASSERT (size >= 1);
+ ASSERT (divisor != 0);
+ ASSERT (MPN_SAME_OR_SEPARATE_P (dst, src, size));
+ ASSERT_MPN (src, size);
+ ASSERT_LIMB (divisor);
+
+ s = *src++; /* src low limb */
+ size--;
+ if (size == 0)
+ {
+ *dst = s / divisor;
+ return;
+ }
+
+ if ((divisor & 1) == 0)
+ {
+ count_trailing_zeros (rshift, divisor);
+ divisor >>= rshift;
+ }
+ else
+ rshift = 0;
+
+ binvert_limb (inverse, divisor);
+
+ lshift = 64 - rshift;
+
+ /* lshift==64 means no shift, so must mask out other part in this case */
+ lshift_mask = (rshift == 0 ? 0 : MP_LIMB_T_MAX);
+
+ c = 0;
+ divisor_h = HIGH32 (divisor);
+
+ if (divisor_h == 0)
+ {
+ /* 32-bit divisor */
+ do
+ {
+ s_next = *src++;
+ ls = (s >> rshift) | ((s_next << lshift) & lshift_mask);
+ s = s_next;
+
+ SUBC_LIMB (c, l, ls, c);
+
+ q = l * inverse;
+ *dst++ = q;
+
+ umul_ppmm_half_lowequal (l, q, divisor, l);
+ c += l;
+
+ size--;
+ }
+ while (size != 0);
+
+ ls = s >> rshift;
+ l = ls - c;
+ q = l * inverse;
+ *dst = q;
+ }
+ else
+ {
+ /* 64-bit divisor */
+ mp_limb_t divisor_l = LOW32 (divisor);
+ do
+ {
+ s_next = *src++;
+ ls = (s >> rshift) | ((s_next << lshift) & lshift_mask);
+ s = s_next;
+
+ SUBC_LIMB (c, l, ls, c);
+
+ q = l * inverse;
+ *dst++ = q;
+
+ umul_ppmm_lowequal (l, q, divisor, divisor_h, divisor_l, l);
+ c += l;
+
+ size--;
+ }
+ while (size != 0);
+
+ ls = s >> rshift;
+ l = ls - c;
+ q = l * inverse;
+ *dst = q;
+ }
+}
diff --git a/gmp/mpn/sparc64/divrem_1.c b/gmp/mpn/sparc64/divrem_1.c
new file mode 100644
index 0000000000..531494a94f
--- /dev/null
+++ b/gmp/mpn/sparc64/divrem_1.c
@@ -0,0 +1,243 @@
+/* UltraSparc 64 mpn_divrem_1 -- mpn by limb division.
+
+Copyright 1991, 1993, 1994, 1996, 1998-2001, 2003 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#include "mpn/sparc64/sparc64.h"
+
+
+/* 64-bit divisor 32-bit divisor
+ cycles/limb cycles/limb
+ (approx) (approx)
+ integer fraction integer fraction
+ Ultrasparc 2i: 160 160 122 96
+*/
+
+
+/* 32-bit divisors are treated in special case code. This requires 4 mulx
+ per limb instead of 8 in the general case.
+
+ For big endian systems we need HALF_ENDIAN_ADJ included in the src[i]
+ addressing, to get the two halves of each limb read in the correct order.
+ This is kept in an adj variable. Doing that measures about 4 c/l faster
+ than just writing HALF_ENDIAN_ADJ(i) in the integer loop. The latter
+ shouldn't be 6 cycles worth of work, but perhaps it doesn't schedule well
+ (on gcc 3.2.1 at least). The fraction loop doesn't seem affected, but we
+ still use a variable since that ought to work out best. */
+
+mp_limb_t
+mpn_divrem_1 (mp_ptr qp_limbptr, mp_size_t xsize_limbs,
+ mp_srcptr ap_limbptr, mp_size_t size_limbs, mp_limb_t d_limb)
+{
+ mp_size_t total_size_limbs;
+ mp_size_t i;
+
+ ASSERT (xsize_limbs >= 0);
+ ASSERT (size_limbs >= 0);
+ ASSERT (d_limb != 0);
+ /* FIXME: What's the correct overlap rule when xsize!=0? */
+ ASSERT (MPN_SAME_OR_SEPARATE_P (qp_limbptr + xsize_limbs,
+ ap_limbptr, size_limbs));
+
+ total_size_limbs = size_limbs + xsize_limbs;
+ if (UNLIKELY (total_size_limbs == 0))
+ return 0;
+
+ /* udivx is good for total_size==1, and no need to bother checking
+ limb<divisor, since if that's likely the caller should check */
+ if (UNLIKELY (total_size_limbs == 1))
+ {
+ mp_limb_t a, q;
+ a = (LIKELY (size_limbs != 0) ? ap_limbptr[0] : 0);
+ q = a / d_limb;
+ qp_limbptr[0] = q;
+ return a - q*d_limb;
+ }
+
+ if (d_limb <= CNST_LIMB(0xFFFFFFFF))
+ {
+ mp_size_t size, xsize, total_size, adj;
+ unsigned *qp, n1, n0, q, r, nshift, norm_rmask;
+ mp_limb_t dinv_limb;
+ const unsigned *ap;
+ int norm, norm_rshift;
+
+ size = 2 * size_limbs;
+ xsize = 2 * xsize_limbs;
+ total_size = size + xsize;
+
+ ap = (unsigned *) ap_limbptr;
+ qp = (unsigned *) qp_limbptr;
+
+ qp += xsize;
+ r = 0; /* initial remainder */
+
+ if (LIKELY (size != 0))
+ {
+ n1 = ap[size-1 + HALF_ENDIAN_ADJ(1)];
+
+ /* If the length of the source is uniformly distributed, then
+ there's a 50% chance of the high 32-bits being zero, which we
+ can skip. */
+ if (n1 == 0)
+ {
+ n1 = ap[size-2 + HALF_ENDIAN_ADJ(0)];
+ total_size--;
+ size--;
+ ASSERT (size > 0); /* because always even */
+ qp[size + HALF_ENDIAN_ADJ(1)] = 0;
+ }
+
+ /* Skip a division if high < divisor (high quotient 0). Testing
+ here before before normalizing will still skip as often as
+ possible. */
+ if (n1 < d_limb)
+ {
+ r = n1;
+ size--;
+ qp[size + HALF_ENDIAN_ADJ(size)] = 0;
+ total_size--;
+ if (total_size == 0)
+ return r;
+ }
+ }
+
+ count_leading_zeros_32 (norm, d_limb);
+ norm -= 32;
+ d_limb <<= norm;
+ r <<= norm;
+
+ norm_rshift = 32 - norm;
+ norm_rmask = (norm == 0 ? 0 : 0xFFFFFFFF);
+
+ invert_half_limb (dinv_limb, d_limb);
+
+ if (LIKELY (size != 0))
+ {
+ i = size - 1;
+ adj = HALF_ENDIAN_ADJ (i);
+ n1 = ap[i + adj];
+ adj = -adj;
+ r |= ((n1 >> norm_rshift) & norm_rmask);
+ for ( ; i > 0; i--)
+ {
+ n0 = ap[i-1 + adj];
+ adj = -adj;
+ nshift = (n1 << norm) | ((n0 >> norm_rshift) & norm_rmask);
+ udiv_qrnnd_half_preinv (q, r, r, nshift, d_limb, dinv_limb);
+ qp[i + adj] = q;
+ n1 = n0;
+ }
+ nshift = n1 << norm;
+ udiv_qrnnd_half_preinv (q, r, r, nshift, d_limb, dinv_limb);
+ qp[0 + HALF_ENDIAN_ADJ(0)] = q;
+ }
+ qp -= xsize;
+ adj = HALF_ENDIAN_ADJ (0);
+ for (i = xsize-1; i >= 0; i--)
+ {
+ udiv_qrnnd_half_preinv (q, r, r, 0, d_limb, dinv_limb);
+ adj = -adj;
+ qp[i + adj] = q;
+ }
+
+ return r >> norm;
+ }
+ else
+ {
+ mp_srcptr ap;
+ mp_ptr qp;
+ mp_size_t size, xsize, total_size;
+ mp_limb_t d, n1, n0, q, r, dinv, nshift, norm_rmask;
+ int norm, norm_rshift;
+
+ ap = ap_limbptr;
+ qp = qp_limbptr;
+ size = size_limbs;
+ xsize = xsize_limbs;
+ total_size = total_size_limbs;
+ d = d_limb;
+
+ qp += total_size; /* above high limb */
+ r = 0; /* initial remainder */
+
+ if (LIKELY (size != 0))
+ {
+ /* Skip a division if high < divisor (high quotient 0). Testing
+ here before before normalizing will still skip as often as
+ possible. */
+ n1 = ap[size-1];
+ if (n1 < d)
+ {
+ r = n1;
+ *--qp = 0;
+ total_size--;
+ if (total_size == 0)
+ return r;
+ size--;
+ }
+ }
+
+ count_leading_zeros (norm, d);
+ d <<= norm;
+ r <<= norm;
+
+ norm_rshift = GMP_LIMB_BITS - norm;
+ norm_rmask = (norm == 0 ? 0 : ~CNST_LIMB(0));
+
+ invert_limb (dinv, d);
+
+ if (LIKELY (size != 0))
+ {
+ n1 = ap[size-1];
+ r |= ((n1 >> norm_rshift) & norm_rmask);
+ for (i = size-2; i >= 0; i--)
+ {
+ n0 = ap[i];
+ nshift = (n1 << norm) | ((n0 >> norm_rshift) & norm_rmask);
+ udiv_qrnnd_preinv (q, r, r, nshift, d, dinv);
+ *--qp = q;
+ n1 = n0;
+ }
+ nshift = n1 << norm;
+ udiv_qrnnd_preinv (q, r, r, nshift, d, dinv);
+ *--qp = q;
+ }
+ for (i = 0; i < xsize; i++)
+ {
+ udiv_qrnnd_preinv (q, r, r, CNST_LIMB(0), d, dinv);
+ *--qp = q;
+ }
+ return r >> norm;
+ }
+}
diff --git a/gmp/mpn/sparc64/gcd_1.asm b/gmp/mpn/sparc64/gcd_1.asm
new file mode 100644
index 0000000000..e4d8de6a28
--- /dev/null
+++ b/gmp/mpn/sparc64/gcd_1.asm
@@ -0,0 +1,135 @@
+dnl SPARC64 mpn_gcd_1.
+
+dnl Based on the K7 gcd_1.asm, by Kevin Ryde. Rehacked for SPARC by Torbjörn
+dnl Granlund.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/bit (approx)
+C UltraSPARC 1&2: 5.1
+C UltraSPARC 3: 5.0
+C UltraSPARC T1: 11.4
+C UltraSPARC T3: 10
+C UltraSPARC T4: 6
+C Numbers measured with: speed -CD -s32-64 -t32 mpn_gcd_1
+
+C ctz_table[n] is the number of trailing zeros on n, or MAXSHIFT if n==0.
+
+deflit(MAXSHIFT, 7)
+deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))
+
+ RODATA
+ TYPE(ctz_table,object)
+ctz_table:
+ .byte MAXSHIFT
+forloop(i,1,MASK,
+` .byte m4_count_trailing_zeros(i)
+')
+ SIZE(ctz_table,.-ctz_table)
+
+C Threshold of when to call bmod when U is one limb. Should be about
+C (time_in_cycles(bmod_1,1) + call_overhead) / (cycles/bit).
+define(`BMOD_THRES_LOG2', 14)
+
+C INPUT PARAMETERS
+define(`up', `%i0')
+define(`n', `%i1')
+define(`v0', `%i2')
+
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_gcd_1)
+ save %sp, -192, %sp
+ ldx [up+0], %g1 C U low limb
+ mov -1, %i4
+ or v0, %g1, %g2 C x | y
+
+L(twos):
+ inc %i4
+ andcc %g2, 1, %g0
+ bz,a %xcc, L(twos)
+ srlx %g2, 1, %g2
+
+L(divide_strip_y):
+ andcc v0, 1, %g0
+ bz,a %xcc, L(divide_strip_y)
+ srlx v0, 1, v0
+
+ cmp n, 1 C if n > 1 we need
+ bnz %xcc, L(bmod) C to call bmod_1
+ nop
+
+C Both U and V are single limbs, reduce with bmod if u0 >> v0.
+ srlx %g1, BMOD_THRES_LOG2, %g2
+ cmp %g2, v0
+ bleu %xcc, L(noreduce)
+ mov %g1, %o0
+
+L(bmod):
+ mov up, %o0
+ mov n, %o1
+ mov v0, %o2
+ call mpn_modexact_1c_odd
+ mov 0, %o3
+
+L(noreduce):
+
+ LEA64(ctz_table, i5, g4)
+
+ cmp %o0, 0
+ bnz %xcc, L(mid)
+ and %o0, MASK, %g3 C
+
+ return %i7+8
+ sllx %o2, %o4, %o0 C CAUTION: v0 alias for o2
+
+ ALIGN(16)
+L(top): movcc %xcc, %l4, v0 C v = min(u,v)
+ movcc %xcc, %l2, %o0 C u = |v - u]
+L(mid): ldub [%i5+%g3], %g5 C
+ brz,a,pn %g3, L(shift_alot) C
+ srlx %o0, MAXSHIFT, %o0
+ srlx %o0, %g5, %l4 C new u, odd
+ subcc v0, %l4, %l2 C v - u, set flags for branch and movcc
+ sub %l4, v0, %o0 C u - v
+ bnz,pt %xcc, L(top) C
+ and %l2, MASK, %g3 C extract low MAXSHIFT bits from (v-u)
+
+ return %i7+8
+ sllx %o2, %o4, %o0 C CAUTION: v0 alias for o2
+
+L(shift_alot):
+ b L(mid)
+ and %o0, MASK, %g3 C
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/gmp-mparam.h b/gmp/mpn/sparc64/gmp-mparam.h
new file mode 100644
index 0000000000..5ac2c461c5
--- /dev/null
+++ b/gmp/mpn/sparc64/gmp-mparam.h
@@ -0,0 +1,139 @@
+/* Sparc64 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004, 2006, 2008-2010 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 500 MHz ultrasparc2 running GNU/Linux */
+
+#define DIVREM_1_NORM_THRESHOLD 3
+#define DIVREM_1_UNNORM_THRESHOLD 4
+#define MOD_1_NORM_THRESHOLD 3
+#define MOD_1_UNNORM_THRESHOLD 3
+#define MOD_1N_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 22
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 27
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+#define USE_PREINV_DIVREM_1 1
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 30
+#define MUL_TOOM33_THRESHOLD 187
+#define MUL_TOOM44_THRESHOLD 278
+#define MUL_TOOM6H_THRESHOLD 278
+#define MUL_TOOM8H_THRESHOLD 357
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 201
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 199
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 154
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 107
+
+#define SQR_BASECASE_THRESHOLD 13
+#define SQR_TOOM2_THRESHOLD 69
+#define SQR_TOOM3_THRESHOLD 116
+#define SQR_TOOM4_THRESHOLD 336
+#define SQR_TOOM6_THRESHOLD 336
+#define SQR_TOOM8_THRESHOLD 454
+
+#define MULMOD_BNM1_THRESHOLD 17
+#define SQRMOD_BNM1_THRESHOLD 23
+
+#define MUL_FFT_MODF_THRESHOLD 248 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 248, 5}, { 9, 4}, { 19, 6}, { 5, 5}, \
+ { 15, 6}, { 8, 5}, { 17, 6}, { 21, 7}, \
+ { 19, 8}, { 11, 7}, { 25, 8}, { 15, 7}, \
+ { 31, 8}, { 27, 9}, { 15, 8}, { 33, 9}, \
+ { 19, 8}, { 39, 9}, { 27,10}, { 15, 9}, \
+ { 39,10}, { 23, 9}, { 47,11}, { 15,10}, \
+ { 31, 9}, { 67,10}, { 39, 9}, { 79,10}, \
+ { 47,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255,10}, { 71, 9}, { 143, 8}, { 287,10}, \
+ { 79,11}, { 47,12}, { 4096,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 50
+#define MUL_FFT_THRESHOLD 1984
+
+#define SQR_FFT_MODF_THRESHOLD 236 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 236, 5}, { 8, 4}, { 17, 5}, { 19, 6}, \
+ { 10, 5}, { 21, 6}, { 19, 7}, { 10, 6}, \
+ { 21, 7}, { 21, 8}, { 21, 9}, { 11, 8}, \
+ { 23, 9}, { 19, 8}, { 43, 9}, { 23,10}, \
+ { 15, 9}, { 43,10}, { 23,11}, { 15,10}, \
+ { 31, 9}, { 63,10}, { 47, 8}, { 191,11}, \
+ { 31,10}, { 63, 8}, { 255, 7}, { 511, 9}, \
+ { 135, 8}, { 271,10}, { 71, 9}, { 143, 8}, \
+ { 287, 7}, { 575,11}, { 47, 9}, { 191, 8}, \
+ { 383,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 49
+#define SQR_FFT_THRESHOLD 1120
+
+#define MULLO_BASECASE_THRESHOLD 16
+#define MULLO_DC_THRESHOLD 41
+#define MULLO_MUL_N_THRESHOLD 3791
+
+#define DC_DIV_QR_THRESHOLD 27
+#define DC_DIVAPPR_Q_THRESHOLD 100
+#define DC_BDIV_QR_THRESHOLD 47
+#define DC_BDIV_Q_THRESHOLD 174
+
+#define INV_MULMOD_BNM1_THRESHOLD 58
+#define INV_NEWTON_THRESHOLD 13
+#define INV_APPR_THRESHOLD 9
+
+#define BINV_NEWTON_THRESHOLD 187
+#define REDC_1_TO_REDC_2_THRESHOLD 10
+#define REDC_2_TO_REDC_N_THRESHOLD 115
+
+#define MU_DIV_QR_THRESHOLD 680
+#define MU_DIVAPPR_Q_THRESHOLD 618
+#define MUPI_DIV_QR_THRESHOLD 0 /* always */
+#define MU_BDIV_QR_THRESHOLD 748
+#define MU_BDIV_Q_THRESHOLD 889
+
+#define MATRIX22_STRASSEN_THRESHOLD 13
+#define HGCD_THRESHOLD 53
+#define GCD_DC_THRESHOLD 283
+#define GCDEXT_DC_THRESHOLD 186
+#define JACOBI_BASE_METHOD 2
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 16
+#define SET_STR_DC_THRESHOLD 390
+#define SET_STR_PRECOMPUTE_THRESHOLD 1665
diff --git a/gmp/mpn/sparc64/lshift.asm b/gmp/mpn/sparc64/lshift.asm
new file mode 100644
index 0000000000..90bbb454f0
--- /dev/null
+++ b/gmp/mpn/sparc64/lshift.asm
@@ -0,0 +1,140 @@
+dnl SPARC v9 mpn_lshift
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 2
+C UltraSPARC 3: 2.5
+C UltraSPARC T1: 17.5
+C UltraSPARC T3: 8
+C UltraSPARC T4: 3
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`cnt', `%i3')
+
+define(`tcnt', `%i4')
+define(`retval', `%i5')
+define(`u0', `%l0')
+define(`u1', `%l1')
+define(`r0', `%l6')
+define(`r1', `%l7')
+define(`u0_off', `%o0')
+define(`u1_off', `%o1')
+define(`r0_off', `%o2')
+define(`r1_off', `%o3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_lshift)
+ save %sp, -176, %sp
+
+ sllx n, 3, n
+ sub %g0, cnt, tcnt
+
+ sub up, 8, u1_off
+ add rp, (5 * 8), r1_off
+
+ ldx [n + u1_off], u1 C WAS: up - 8
+ add u1_off, (3 * 8), u1_off
+
+ sub r1_off, 8, r0_off
+ sub u1_off, 8, u0_off
+
+ subcc n, (3 * 8), n
+ srlx u1, tcnt, retval
+
+ bl,pn %xcc, L(end12)
+ sllx u1, cnt, %l3
+
+ ldx [n + u0_off], u0 C WAS: up - 16
+ subcc n, (2 * 8), n
+
+ ldx [n + u1_off], u1 C WAS: up - 24
+
+ bl,pn %xcc, L(end34)
+ srlx u0, tcnt, %l4
+
+ b,a L(top)
+ ALIGN(16)
+L(top):
+ sllx u0, cnt, %l2
+ or %l4, %l3, r0
+
+ ldx [n + u0_off], u0 C WAS: up - 16
+ srlx u1, tcnt, %l5
+
+ stx r0, [n + r0_off] C WAS: rp - 8
+ subcc n, (2 * 8), n
+
+ sllx u1, cnt, %l3
+ or %l2, %l5, r1
+
+ ldx [n + u1_off], u1 C WAS: up - 24
+ srlx u0, tcnt, %l4
+
+ bge,pt %xcc, L(top)
+ stx r1, [n + r1_off] C WAS: rp - 16
+
+L(end34):
+ sllx u0, cnt, %l2
+ or %l4, %l3, r0
+
+ srlx u1, tcnt, %l5
+ stx r0, [n + r0_off] C WAS: rp - 8
+
+ or %l2, %l5, r1
+ sub n, (2 * 8), %o5
+
+ sllx u1, cnt, %l3
+ stx r1, [%o5 + r1_off] C WAS: rp - 16
+
+L(end12):
+ andcc n, 8, %g0
+ bz,pn %xcc, L(done)
+ nop
+
+ ldx [n + u0_off], u1
+ srlx u1, tcnt, %l4
+ or %l4, %l3, r0
+ stx r0, [r0_off - 24]
+ sllx u1, cnt, %l3
+L(done):
+ stx %l3, [r0_off - 32]
+
+ ret
+ restore retval, 0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/lshiftc.asm b/gmp/mpn/sparc64/lshiftc.asm
new file mode 100644
index 0000000000..4a0f0a3e40
--- /dev/null
+++ b/gmp/mpn/sparc64/lshiftc.asm
@@ -0,0 +1,147 @@
+dnl SPARC v9 mpn_lshiftc
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 3
+C UltraSPARC 3: 3
+C UltraSPARC T1: 17
+C UltraSPARC T3: 10
+C UltraSPARC T4: 3.5
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`cnt', `%i3')
+
+define(`tcnt', `%i4')
+define(`retval', `%i5')
+define(`u0', `%l0')
+define(`u1', `%l1')
+define(`r0', `%l6')
+define(`r1', `%l7')
+define(`u0_off', `%o0')
+define(`u1_off', `%o1')
+define(`r0_off', `%o2')
+define(`r1_off', `%o3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_lshiftc)
+ save %sp, -176, %sp
+
+ sllx n, 3, n
+ sub %g0, cnt, tcnt
+
+ sub up, 8, u1_off
+ add rp, (5 * 8), r1_off
+
+ ldx [n + u1_off], u1 C WAS: up - 8
+ add u1_off, (3 * 8), u1_off
+
+ sub r1_off, 8, r0_off
+ sub u1_off, 8, u0_off
+
+ subcc n, (3 * 8), n
+ srlx u1, tcnt, retval
+
+ bl,pn %xcc, L(end12)
+ sllx u1, cnt, %l3
+
+ ldx [n + u0_off], u0 C WAS: up - 16
+ subcc n, (2 * 8), n
+
+ ldx [n + u1_off], u1 C WAS: up - 24
+
+ bl,pn %xcc, L(end34)
+ srlx u0, tcnt, %l4
+
+ b,a L(top)
+ ALIGN(16)
+L(top):
+ not %l3, %l3
+ sllx u0, cnt, %l2
+
+ andn %l3, %l4, r0
+ ldx [n + u0_off], u0 C WAS: up - 16
+
+ srlx u1, tcnt, %l5
+ stx r0, [n + r0_off] C WAS: rp - 8
+
+ subcc n, (2 * 8), n
+ not %l2, %l2
+
+ sllx u1, cnt, %l3
+ andn %l2, %l5, r1
+
+ ldx [n + u1_off], u1 C WAS: up - 24
+ srlx u0, tcnt, %l4
+
+ bge,pt %xcc, L(top)
+ stx r1, [n + r1_off] C WAS: rp - 16
+
+L(end34):
+ not %l3, %l3
+ sllx u0, cnt, %l2
+
+ andn %l3, %l4, r0
+ srlx u1, tcnt, %l5
+
+ stx r0, [n + r0_off] C WAS: rp - 8
+ not %l2, %l2
+
+ andn %l2, %l5, r1
+ sub n, (2 * 8), %o5
+
+ sllx u1, cnt, %l3
+ stx r1, [%o5 + r1_off] C WAS: rp - 16
+
+L(end12):
+ andcc n, 8, %g0
+ bz %xcc, L(done)+4
+ not %l3, %l3
+
+ ldx [n + u0_off], u1
+ srlx u1, tcnt, %l4
+ andn %l3, %l4, r0
+ stx r0, [r0_off - 24]
+ sllx u1, cnt, %l3
+L(done):
+ not %l3, %l3
+ stx %l3, [r0_off - 32]
+
+ ret
+ restore retval, 0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/mod_1.c b/gmp/mpn/sparc64/mod_1.c
new file mode 100644
index 0000000000..f1c51970d9
--- /dev/null
+++ b/gmp/mpn/sparc64/mod_1.c
@@ -0,0 +1,239 @@
+/* UltraSPARC 64 mpn_mod_1 -- mpn by limb remainder.
+
+Copyright 1991, 1993, 1994, 1999-2001, 2003, 2010 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#include "mpn/sparc64/sparc64.h"
+
+
+/* 64-bit divisor 32-bit divisor
+ cycles/limb cycles/limb
+ (approx) (approx)
+ Ultrasparc 2i: 160 120
+*/
+
+
+/* 32-bit divisors are treated in special case code. This requires 4 mulx
+ per limb instead of 8 in the general case.
+
+ For big endian systems we need HALF_ENDIAN_ADJ included in the src[i]
+ addressing, to get the two halves of each limb read in the correct order.
+ This is kept in an adj variable. Doing that measures about 6 c/l faster
+ than just writing HALF_ENDIAN_ADJ(i) in the loop. The latter shouldn't
+ be 6 cycles worth of work, but perhaps it doesn't schedule well (on gcc
+ 3.2.1 at least).
+
+ A simple udivx/umulx loop for the 32-bit case was attempted for small
+ sizes, but at size==2 it was only about the same speed and at size==3 was
+ slower. */
+
+static mp_limb_t
+mpn_mod_1_anynorm (mp_srcptr src_limbptr, mp_size_t size_limbs, mp_limb_t d_limb)
+{
+ int norm, norm_rshift;
+ mp_limb_t src_high_limb;
+ mp_size_t i;
+
+ ASSERT (size_limbs >= 0);
+ ASSERT (d_limb != 0);
+
+ if (UNLIKELY (size_limbs == 0))
+ return 0;
+
+ src_high_limb = src_limbptr[size_limbs-1];
+
+ /* udivx is good for size==1, and no need to bother checking limb<divisor,
+ since if that's likely the caller should check */
+ if (UNLIKELY (size_limbs == 1))
+ return src_high_limb % d_limb;
+
+ if (d_limb <= CNST_LIMB(0xFFFFFFFF))
+ {
+ unsigned *src, n1, n0, r, dummy_q, nshift, norm_rmask;
+ mp_size_t size, adj;
+ mp_limb_t dinv_limb;
+
+ size = 2 * size_limbs; /* halfwords */
+ src = (unsigned *) src_limbptr;
+
+ /* prospective initial remainder, if < d */
+ r = src_high_limb >> 32;
+
+ /* If the length of the source is uniformly distributed, then there's
+ a 50% chance of the high 32-bits being zero, which we can skip. */
+ if (r == 0)
+ {
+ r = (unsigned) src_high_limb;
+ size--;
+ ASSERT (size > 0); /* because always even */
+ }
+
+ /* Skip a division if high < divisor. Having the test here before
+ normalizing will still skip as often as possible. */
+ if (r < d_limb)
+ {
+ size--;
+ ASSERT (size > 0); /* because size==1 handled above */
+ }
+ else
+ r = 0;
+
+ count_leading_zeros_32 (norm, d_limb);
+ norm -= 32;
+ d_limb <<= norm;
+
+ norm_rshift = 32 - norm;
+ norm_rmask = (norm == 0 ? 0 : 0xFFFFFFFF);
+ i = size-1;
+ adj = HALF_ENDIAN_ADJ (i);
+ n1 = src [i + adj];
+ r = (r << norm) | ((n1 >> norm_rshift) & norm_rmask);
+
+ invert_half_limb (dinv_limb, d_limb);
+ adj = -adj;
+
+ for (i--; i >= 0; i--)
+ {
+ n0 = src [i + adj];
+ adj = -adj;
+ nshift = (n1 << norm) | ((n0 >> norm_rshift) & norm_rmask);
+ udiv_qrnnd_half_preinv (dummy_q, r, r, nshift, d_limb, dinv_limb);
+ n1 = n0;
+ }
+
+ /* same as loop, but without n0 */
+ nshift = n1 << norm;
+ udiv_qrnnd_half_preinv (dummy_q, r, r, nshift, d_limb, dinv_limb);
+
+ ASSERT ((r & ((1 << norm) - 1)) == 0);
+ return r >> norm;
+ }
+ else
+ {
+ mp_srcptr src;
+ mp_size_t size;
+ mp_limb_t n1, n0, r, dinv, dummy_q, nshift, norm_rmask;
+
+ src = src_limbptr;
+ size = size_limbs;
+ r = src_high_limb; /* initial remainder */
+
+ /* Skip a division if high < divisor. Having the test here before
+ normalizing will still skip as often as possible. */
+ if (r < d_limb)
+ {
+ size--;
+ ASSERT (size > 0); /* because size==1 handled above */
+ }
+ else
+ r = 0;
+
+ count_leading_zeros (norm, d_limb);
+ d_limb <<= norm;
+
+ norm_rshift = GMP_LIMB_BITS - norm;
+ norm_rmask = (norm == 0 ? 0 : 0xFFFFFFFF);
+
+ src += size;
+ n1 = *--src;
+ r = (r << norm) | ((n1 >> norm_rshift) & norm_rmask);
+
+ invert_limb (dinv, d_limb);
+
+ for (i = size-2; i >= 0; i--)
+ {
+ n0 = *--src;
+ nshift = (n1 << norm) | ((n0 >> norm_rshift) & norm_rmask);
+ udiv_qrnnd_preinv (dummy_q, r, r, nshift, d_limb, dinv);
+ n1 = n0;
+ }
+
+ /* same as loop, but without n0 */
+ nshift = n1 << norm;
+ udiv_qrnnd_preinv (dummy_q, r, r, nshift, d_limb, dinv);
+
+ ASSERT ((r & ((CNST_LIMB(1) << norm) - 1)) == 0);
+ return r >> norm;
+ }
+}
+
+mp_limb_t
+mpn_mod_1 (mp_srcptr ap, mp_size_t n, mp_limb_t b)
+{
+ ASSERT (n >= 0);
+ ASSERT (b != 0);
+
+ /* Should this be handled at all? Rely on callers? Note un==0 is currently
+ required by mpz/fdiv_r_ui.c and possibly other places. */
+ if (n == 0)
+ return 0;
+
+ if (UNLIKELY ((b & GMP_NUMB_HIGHBIT) != 0))
+ {
+ if (BELOW_THRESHOLD (n, MOD_1N_TO_MOD_1_1_THRESHOLD))
+ {
+ return mpn_mod_1_anynorm (ap, n, b);
+ }
+ else
+ {
+ mp_limb_t pre[4];
+ mpn_mod_1_1p_cps (pre, b);
+ return mpn_mod_1_1p (ap, n, b, pre);
+ }
+ }
+ else
+ {
+ if (BELOW_THRESHOLD (n, MOD_1U_TO_MOD_1_1_THRESHOLD))
+ {
+ return mpn_mod_1_anynorm (ap, n, b);
+ }
+ else if (BELOW_THRESHOLD (n, MOD_1_1_TO_MOD_1_2_THRESHOLD))
+ {
+ mp_limb_t pre[4];
+ mpn_mod_1_1p_cps (pre, b);
+ return mpn_mod_1_1p (ap, n, b << pre[1], pre);
+ }
+ else if (BELOW_THRESHOLD (n, MOD_1_2_TO_MOD_1_4_THRESHOLD) || UNLIKELY (b > GMP_NUMB_MASK / 4))
+ {
+ mp_limb_t pre[5];
+ mpn_mod_1s_2p_cps (pre, b);
+ return mpn_mod_1s_2p (ap, n, b << pre[1], pre);
+ }
+ else
+ {
+ mp_limb_t pre[7];
+ mpn_mod_1s_4p_cps (pre, b);
+ return mpn_mod_1s_4p (ap, n, b << pre[1], pre);
+ }
+ }
+}
diff --git a/gmp/mpn/sparc64/mod_1_4.c b/gmp/mpn/sparc64/mod_1_4.c
new file mode 100644
index 0000000000..cc1b9484bc
--- /dev/null
+++ b/gmp/mpn/sparc64/mod_1_4.c
@@ -0,0 +1,236 @@
+/* mpn_mod_1s_4p (ap, n, b, cps)
+ Divide (ap,,n) by b. Return the single-limb remainder.
+ Requires that d < B / 4.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+ Based on a suggestion by Peter L. Montgomery.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2008-2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#include "mpn/sparc64/sparc64.h"
+
+void
+mpn_mod_1s_4p_cps (mp_limb_t cps[7], mp_limb_t b)
+{
+ mp_limb_t bi;
+ mp_limb_t B1modb, B2modb, B3modb, B4modb, B5modb;
+ int cnt;
+
+ ASSERT (b <= (~(mp_limb_t) 0) / 4);
+
+ count_leading_zeros (cnt, b);
+
+ b <<= cnt;
+ invert_limb (bi, b);
+
+ cps[0] = bi;
+ cps[1] = cnt;
+
+ B1modb = -b * ((bi >> (GMP_LIMB_BITS-cnt)) | (CNST_LIMB(1) << cnt));
+ ASSERT (B1modb <= b); /* NB: not fully reduced mod b */
+ cps[2] = B1modb >> cnt;
+
+ udiv_rnnd_preinv (B2modb, B1modb, CNST_LIMB(0), b, bi);
+ cps[3] = B2modb >> cnt;
+
+ udiv_rnnd_preinv (B3modb, B2modb, CNST_LIMB(0), b, bi);
+ cps[4] = B3modb >> cnt;
+
+ udiv_rnnd_preinv (B4modb, B3modb, CNST_LIMB(0), b, bi);
+ cps[5] = B4modb >> cnt;
+
+ udiv_rnnd_preinv (B5modb, B4modb, CNST_LIMB(0), b, bi);
+ cps[6] = B5modb >> cnt;
+
+#if WANT_ASSERT
+ {
+ int i;
+ b = cps[2];
+ for (i = 3; i <= 6; i++)
+ {
+ b += cps[i];
+ ASSERT (b >= cps[i]);
+ }
+ }
+#endif
+}
+
+mp_limb_t
+mpn_mod_1s_4p (mp_srcptr ap, mp_size_t n, mp_limb_t b, const mp_limb_t cps[7])
+{
+ mp_limb_t rh, rl, bi, ph, pl, ch, cl, r;
+ mp_limb_t B1modb, B2modb, B3modb, B4modb, B5modb;
+ mp_size_t i;
+ int cnt;
+
+ ASSERT (n >= 1);
+
+ B1modb = cps[2];
+ B2modb = cps[3];
+ B3modb = cps[4];
+ B4modb = cps[5];
+ B5modb = cps[6];
+
+ if ((b >> 32) == 0)
+ {
+ switch (n & 3)
+ {
+ case 0:
+ umul_ppmm_s (ph, pl, ap[n - 3], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[n - 4]);
+ umul_ppmm_s (ch, cl, ap[n - 2], B2modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+ umul_ppmm_s (rh, rl, ap[n - 1], B3modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ n -= 4;
+ break;
+ case 1:
+ rh = 0;
+ rl = ap[n - 1];
+ n -= 1;
+ break;
+ case 2:
+ rh = ap[n - 1];
+ rl = ap[n - 2];
+ n -= 2;
+ break;
+ case 3:
+ umul_ppmm_s (ph, pl, ap[n - 2], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[n - 3]);
+ umul_ppmm_s (rh, rl, ap[n - 1], B2modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ n -= 3;
+ break;
+ }
+
+ for (i = n - 4; i >= 0; i -= 4)
+ {
+ /* rr = ap[i] < B
+ + ap[i+1] * (B mod b) <= (B-1)(b-1)
+ + ap[i+2] * (B^2 mod b) <= (B-1)(b-1)
+ + ap[i+3] * (B^3 mod b) <= (B-1)(b-1)
+ + LO(rr) * (B^4 mod b) <= (B-1)(b-1)
+ + HI(rr) * (B^5 mod b) <= (B-1)(b-1)
+ */
+ umul_ppmm_s (ph, pl, ap[i + 1], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, CNST_LIMB(0), ap[i + 0]);
+
+ umul_ppmm_s (ch, cl, ap[i + 2], B2modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm_s (ch, cl, ap[i + 3], B3modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm_s (ch, cl, rl, B4modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm_s (rh, rl, rh, B5modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ }
+
+ umul_ppmm_s (rh, cl, rh, B1modb);
+ add_ssaaaa (rh, rl, rh, rl, CNST_LIMB(0), cl);
+ }
+ else
+ {
+ switch (n & 3)
+ {
+ case 0:
+ umul_ppmm (ph, pl, ap[n - 3], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, 0, ap[n - 4]);
+ umul_ppmm (ch, cl, ap[n - 2], B2modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+ umul_ppmm (rh, rl, ap[n - 1], B3modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ n -= 4;
+ break;
+ case 1:
+ rh = 0;
+ rl = ap[n - 1];
+ n -= 1;
+ break;
+ case 2:
+ rh = ap[n - 1];
+ rl = ap[n - 2];
+ n -= 2;
+ break;
+ case 3:
+ umul_ppmm (ph, pl, ap[n - 2], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, 0, ap[n - 3]);
+ umul_ppmm (rh, rl, ap[n - 1], B2modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ n -= 3;
+ break;
+ }
+
+ for (i = n - 4; i >= 0; i -= 4)
+ {
+ /* rr = ap[i] < B
+ + ap[i+1] * (B mod b) <= (B-1)(b-1)
+ + ap[i+2] * (B^2 mod b) <= (B-1)(b-1)
+ + ap[i+3] * (B^3 mod b) <= (B-1)(b-1)
+ + LO(rr) * (B^4 mod b) <= (B-1)(b-1)
+ + HI(rr) * (B^5 mod b) <= (B-1)(b-1)
+ */
+ umul_ppmm (ph, pl, ap[i + 1], B1modb);
+ add_ssaaaa (ph, pl, ph, pl, 0, ap[i + 0]);
+
+ umul_ppmm (ch, cl, ap[i + 2], B2modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm (ch, cl, ap[i + 3], B3modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm (ch, cl, rl, B4modb);
+ add_ssaaaa (ph, pl, ph, pl, ch, cl);
+
+ umul_ppmm (rh, rl, rh, B5modb);
+ add_ssaaaa (rh, rl, rh, rl, ph, pl);
+ }
+
+ umul_ppmm (rh, cl, rh, B1modb);
+ add_ssaaaa (rh, rl, rh, rl, 0, cl);
+ }
+
+ bi = cps[0];
+ cnt = cps[1];
+
+ r = (rh << cnt) | (rl >> (GMP_LIMB_BITS - cnt));
+ udiv_rnnd_preinv (r, r, rl << cnt, b, bi);
+
+ return r >> cnt;
+}
diff --git a/gmp/mpn/sparc64/mode1o.c b/gmp/mpn/sparc64/mode1o.c
new file mode 100644
index 0000000000..7c8fc1cf3d
--- /dev/null
+++ b/gmp/mpn/sparc64/mode1o.c
@@ -0,0 +1,197 @@
+/* UltraSPARC 64 mpn_modexact_1c_odd -- mpn by limb exact style remainder.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2000-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#include "mpn/sparc64/sparc64.h"
+
+
+/* 64-bit divisor 32-bit divisor
+ cycles/limb cycles/limb
+ (approx) (approx)
+ Ultrasparc 2i: ? ?
+*/
+
+
+/* This implementation reduces the number of multiplies done, knowing that
+ on ultrasparc 1 and 2 the mulx instruction stalls the whole chip.
+
+ The key idea is to use the fact that the low limb of q*d equals l, this
+ being the whole purpose of the q calculated. It means there's no need to
+ calculate the lowest 32x32->64 part of the q*d, instead it can be
+ inferred from l and the other three 32x32->64 parts. See sparc64.h for
+ details.
+
+ When d is 32-bits, the same applies, but in this case there's only one
+ other 32x32->64 part (ie. HIGH(q)*d).
+
+ The net effect is that for 64-bit divisor each limb is 4 mulx, or for
+ 32-bit divisor each is 2 mulx.
+
+ Enhancements:
+
+ No doubt this could be done in assembler, if that helped the scheduling,
+ or perhaps guaranteed good code irrespective of the compiler.
+
+ Alternatives:
+
+ It might be possibly to use floating point. The loop is dominated by
+ multiply latency, so not sure if floats would improve that. One
+ possibility would be to take two limbs at a time, with a 128 bit inverse,
+ if there's enough registers, which could effectively use float throughput
+ to reduce total latency across two limbs. */
+
+#define ASSERT_RETVAL(r) \
+ ASSERT (orig_c < d ? r < d : r <= d)
+
+mp_limb_t
+mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size, mp_limb_t d, mp_limb_t orig_c)
+{
+ mp_limb_t c = orig_c;
+ mp_limb_t s, l, q, h, inverse;
+
+ ASSERT (size >= 1);
+ ASSERT (d & 1);
+ ASSERT_MPN (src, size);
+ ASSERT_LIMB (d);
+ ASSERT_LIMB (c);
+
+ /* udivx is faster than 10 or 12 mulx's for one limb via an inverse */
+ if (size == 1)
+ {
+ s = src[0];
+ if (s > c)
+ {
+ l = s-c;
+ h = l % d;
+ if (h != 0)
+ h = d - h;
+ }
+ else
+ {
+ l = c-s;
+ h = l % d;
+ }
+ return h;
+ }
+
+ binvert_limb (inverse, d);
+
+ if (d <= 0xFFFFFFFF)
+ {
+ s = *src++;
+ size--;
+ do
+ {
+ SUBC_LIMB (c, l, s, c);
+ s = *src++;
+ q = l * inverse;
+ umul_ppmm_half_lowequal (h, q, d, l);
+ c += h;
+ size--;
+ }
+ while (size != 0);
+
+ if (s <= d)
+ {
+ /* With high s <= d the final step can be a subtract and addback.
+ If c==0 then the addback will restore to l>=0. If c==d then
+ will get l==d if s==0, but that's ok per the function
+ definition. */
+
+ l = c - s;
+ l += (l > c ? d : 0);
+
+ ASSERT_RETVAL (l);
+ return l;
+ }
+ else
+ {
+ /* Can't skip a divide, just do the loop code once more. */
+ SUBC_LIMB (c, l, s, c);
+ q = l * inverse;
+ umul_ppmm_half_lowequal (h, q, d, l);
+ c += h;
+
+ ASSERT_RETVAL (c);
+ return c;
+ }
+ }
+ else
+ {
+ mp_limb_t dl = LOW32 (d);
+ mp_limb_t dh = HIGH32 (d);
+ long i;
+
+ s = *src++;
+ size--;
+ do
+ {
+ SUBC_LIMB (c, l, s, c);
+ s = *src++;
+ q = l * inverse;
+ umul_ppmm_lowequal (h, q, d, dh, dl, l);
+ c += h;
+ size--;
+ }
+ while (size != 0);
+
+ if (s <= d)
+ {
+ /* With high s <= d the final step can be a subtract and addback.
+ If c==0 then the addback will restore to l>=0. If c==d then
+ will get l==d if s==0, but that's ok per the function
+ definition. */
+
+ l = c - s;
+ l += (l > c ? d : 0);
+
+ ASSERT_RETVAL (l);
+ return l;
+ }
+ else
+ {
+ /* Can't skip a divide, just do the loop code once more. */
+ SUBC_LIMB (c, l, s, c);
+ q = l * inverse;
+ umul_ppmm_lowequal (h, q, d, dh, dl, l);
+ c += h;
+
+ ASSERT_RETVAL (c);
+ return c;
+ }
+ }
+}
diff --git a/gmp/mpn/sparc64/rshift.asm b/gmp/mpn/sparc64/rshift.asm
new file mode 100644
index 0000000000..3f8e11fee7
--- /dev/null
+++ b/gmp/mpn/sparc64/rshift.asm
@@ -0,0 +1,142 @@
+dnl SPARC v9 mpn_rshift
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 2
+C UltraSPARC 3: 2.5
+C UltraSPARC T1: 17.5
+C UltraSPARC T3: 8
+C UltraSPARC T4: 3
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`cnt', `%i3')
+
+define(`tcnt', `%i4')
+define(`retval', `%i5')
+define(`u0', `%l0')
+define(`u1', `%l1')
+define(`r0', `%l6')
+define(`r1', `%l7')
+define(`u0_off', `%o0')
+define(`u1_off', `%o1')
+define(`r0_off', `%o2')
+define(`r1_off', `%o3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_rshift)
+ save %sp, -176, %sp
+
+ sllx n, 3, n
+ sub %g0, cnt, tcnt
+
+ add up, n, up
+ add rp, n, rp
+
+ neg n, n
+ sub up, (2 * 8), u0_off
+ sub rp, (5 * 8), r0_off
+
+ ldx [n + up], u1 C WAS: up + 0
+ sub u0_off, (1 * 8), u1_off
+ sub r0_off, (1 * 8), r1_off
+
+ subcc n, -(3 * 8), n
+ sllx u1, tcnt, retval
+
+ bg,pn %xcc, L(end12)
+ srlx u1, cnt, %l3
+
+ ldx [n + u0_off], u0 C WAS: up + 0
+ subcc n, -(2 * 8), n
+
+ ldx [n + u1_off], u1 C WAS: up + 8
+
+ bg,pn %xcc, L(end34)
+ sllx u0, tcnt, %l4
+
+ b,a L(top)
+ ALIGN(16)
+L(top):
+ srlx u0, cnt, %l2
+ or %l3, %l4, r0
+
+ ldx [n + u0_off], u0 C WAS: up + 0
+ sllx u1, tcnt, %l5
+
+ stx r0, [n + r0_off] C WAS: rp + 0
+ subcc n, -(2 * 8), n
+
+ srlx u1, cnt, %l3
+ or %l2, %l5, r1
+
+ ldx [n + u1_off], u1 C WAS: up + 8
+ sllx u0, tcnt, %l4
+
+ ble,pt %xcc, L(top)
+ stx r1, [n + r1_off] C WAS: rp + 8
+
+L(end34):
+ srlx u0, cnt, %l2
+ or %l3, %l4, r0
+
+ sllx u1, tcnt, %l5
+ stx r0, [n + r0_off] C WAS: rp + 0
+
+ or %l2, %l5, r1
+ sub n, -(2 * 8), %o5
+
+ srlx u1, cnt, %l3
+ stx r1, [%o5 + r1_off] C WAS: rp + 8
+
+L(end12):
+ andcc n, 8, %g0
+ bz,pn %xcc, L(done)
+ nop
+
+ ldx [n + u0_off], u1
+ sllx u1, tcnt, %l4
+ or %l3, %l4, r0
+ stx r0, [r0_off + 24]
+ srlx u1, cnt, %l3
+L(done):
+ stx %l3, [r0_off + 32]
+
+ ret
+ restore retval, 0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/sec_tabselect.asm b/gmp/mpn/sparc64/sec_tabselect.asm
new file mode 100644
index 0000000000..22e0dc5ef1
--- /dev/null
+++ b/gmp/mpn/sparc64/sec_tabselect.asm
@@ -0,0 +1,162 @@
+dnl SPARC v9 mpn_sec_tabselect.
+
+dnl Contributed to the GNU project by Torbjörn Granlund and David Miller.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 2 hopefully
+C UltraSPARC 3: 3
+C UltraSPARC T1: 17
+C UltraSPARC T3: ?
+C UltraSPARC T4/T5: 2.25 hopefully
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`tp', `%i1')
+define(`n', `%i2')
+define(`nents', `%i3')
+define(`which', `%i4')
+
+define(`i', `%g1')
+define(`j', `%g3')
+define(`stride', `%g4')
+define(`tporig', `%g5')
+define(`mask', `%o0')
+
+define(`data0', `%l0')
+define(`data1', `%l1')
+define(`data2', `%l2')
+define(`data3', `%l3')
+define(`t0', `%l4')
+define(`t1', `%l5')
+define(`t2', `%l6')
+define(`t3', `%l7')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_sec_tabselect)
+ save %sp, -176, %sp
+
+ sllx n, 3, stride
+ sub n, 4, j
+ brlz j, L(outer_end)
+ mov tp, tporig
+
+L(outer_loop):
+ clr data0
+ clr data1
+ clr data2
+ clr data3
+ mov tporig, tp
+ mov nents, i
+ mov which, %o1
+
+L(top): subcc %o1, 1, %o1 C set carry iff o1 = 0
+ ldx [tp + 0], t0
+ subc %g0, %g0, mask
+ ldx [tp + 8], t1
+ sub i, 1, i
+ ldx [tp + 16], t2
+ ldx [tp + 24], t3
+ add tp, stride, tp
+ and t0, mask, t0
+ and t1, mask, t1
+ or t0, data0, data0
+ and t2, mask, t2
+ or t1, data1, data1
+ and t3, mask, t3
+ or t2, data2, data2
+ brnz i, L(top)
+ or t3, data3, data3
+
+ stx data0, [rp + 0]
+ subcc j, 4, j
+ stx data1, [rp + 8]
+ stx data2, [rp + 16]
+ stx data3, [rp + 24]
+ add tporig, (4 * 8), tporig
+
+ brgez j, L(outer_loop)
+ add rp, (4 * 8), rp
+L(outer_end):
+
+
+ andcc n, 2, %g0
+ be L(b0x)
+ nop
+L(b1x): clr data0
+ clr data1
+ mov tporig, tp
+ mov nents, i
+ mov which, %o1
+
+L(tp2): subcc %o1, 1, %o1
+ ldx [tp + 0], t0
+ subc %g0, %g0, mask
+ ldx [tp + 8], t1
+ sub i, 1, i
+ add tp, stride, tp
+ and t0, mask, t0
+ and t1, mask, t1
+ or t0, data0, data0
+ brnz i, L(tp2)
+ or t1, data1, data1
+
+ stx data0, [rp + 0]
+ stx data1, [rp + 8]
+ add tporig, (2 * 8), tporig
+ add rp, (2 * 8), rp
+
+
+L(b0x): andcc n, 1, %g0
+ be L(b00)
+ nop
+L(b01): clr data0
+ mov tporig, tp
+ mov nents, i
+ mov which, %o1
+
+L(tp1): subcc %o1, 1, %o1
+ ldx [tp + 0], t0
+ subc %g0, %g0, mask
+ sub i, 1, i
+ add tp, stride, tp
+ and t0, mask, t0
+ brnz i, L(tp1)
+ or t0, data0, data0
+
+ stx data0, [rp + 0]
+
+L(b00): ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/sparc64.h b/gmp/mpn/sparc64/sparc64.h
new file mode 100644
index 0000000000..09fc16d46a
--- /dev/null
+++ b/gmp/mpn/sparc64/sparc64.h
@@ -0,0 +1,219 @@
+/* UltraSPARC 64 support macros.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define LOW32(x) ((x) & 0xFFFFFFFF)
+#define HIGH32(x) ((x) >> 32)
+
+
+/* Halfword number i in src is accessed as src[i+HALF_ENDIAN_ADJ(i)].
+ Plain src[i] would be incorrect in big endian, HALF_ENDIAN_ADJ has the
+ effect of swapping the two halves in this case. */
+#if HAVE_LIMB_BIG_ENDIAN
+#define HALF_ENDIAN_ADJ(i) (1 - (((i) & 1) << 1)) /* +1 even, -1 odd */
+#endif
+#if HAVE_LIMB_LITTLE_ENDIAN
+#define HALF_ENDIAN_ADJ(i) 0 /* no adjust */
+#endif
+#ifndef HALF_ENDIAN_ADJ
+Error, error, unknown limb endianness;
+#endif
+
+
+/* umul_ppmm_lowequal sets h to the high limb of q*d, assuming the low limb
+ of that product is equal to l. dh and dl are the 32-bit halves of d.
+
+ |-----high----||----low-----|
+ +------+------+
+ | | ph = qh * dh
+ +------+------+
+ +------+------+
+ | | pm1 = ql * dh
+ +------+------+
+ +------+------+
+ | | pm2 = qh * dl
+ +------+------+
+ +------+------+
+ | | pl = ql * dl (not calculated)
+ +------+------+
+
+ Knowing that the low 64 bits is equal to l means that LOW(pm1) + LOW(pm2)
+ + HIGH(pl) == HIGH(l). The only thing we need from those product parts
+ is whether they produce a carry into the high.
+
+ pm_l = LOW(pm1)+LOW(pm2) is done to contribute its carry, then the only
+ time there's a further carry from LOW(pm_l)+HIGH(pl) is if LOW(pm_l) >
+ HIGH(l). pl is never actually calculated. */
+
+#define umul_ppmm_lowequal(h, q, d, dh, dl, l) \
+ do { \
+ mp_limb_t ql, qh, ph, pm1, pm2, pm_l; \
+ ASSERT (dh == HIGH32(d)); \
+ ASSERT (dl == LOW32(d)); \
+ ASSERT (q*d == l); \
+ \
+ ql = LOW32 (q); \
+ qh = HIGH32 (q); \
+ \
+ pm1 = ql * dh; \
+ pm2 = qh * dl; \
+ ph = qh * dh; \
+ \
+ pm_l = LOW32 (pm1) + LOW32 (pm2); \
+ \
+ (h) = ph + HIGH32 (pm1) + HIGH32 (pm2) \
+ + HIGH32 (pm_l) + ((pm_l << 32) > l); \
+ \
+ ASSERT_HIGH_PRODUCT (h, q, d); \
+ } while (0)
+
+
+/* Set h to the high of q*d, assuming the low limb of that product is equal
+ to l, and that d fits in 32-bits.
+
+ |-----high----||----low-----|
+ +------+------+
+ | | pm = qh * dl
+ +------+------+
+ +------+------+
+ | | pl = ql * dl (not calculated)
+ +------+------+
+
+ Knowing that LOW(pm) + HIGH(pl) == HIGH(l) (mod 2^32) means that the only
+ time there's a carry from that sum is when LOW(pm) > HIGH(l). There's no
+ need to calculate pl to determine this. */
+
+#define umul_ppmm_half_lowequal(h, q, d, l) \
+ do { \
+ mp_limb_t pm; \
+ ASSERT (q*d == l); \
+ ASSERT (HIGH32(d) == 0); \
+ \
+ pm = HIGH32(q) * d; \
+ (h) = HIGH32(pm) + ((pm << 32) > l); \
+ ASSERT_HIGH_PRODUCT (h, q, d); \
+ } while (0)
+
+
+/* check that h is the high limb of x*y */
+#if WANT_ASSERT
+#define ASSERT_HIGH_PRODUCT(h, x, y) \
+ do { \
+ mp_limb_t want_h, dummy; \
+ umul_ppmm (want_h, dummy, x, y); \
+ ASSERT (h == want_h); \
+ } while (0)
+#else
+#define ASSERT_HIGH_PRODUCT(h, q, d) \
+ do { } while (0)
+#endif
+
+
+/* Multiply u anv v, where v < 2^32. */
+#define umul_ppmm_s(w1, w0, u, v) \
+ do { \
+ UWtype __x0, __x2; \
+ UWtype __ul, __vl, __uh; \
+ UWtype __u = (u), __v = (v); \
+ \
+ __ul = __ll_lowpart (__u); \
+ __uh = __ll_highpart (__u); \
+ __vl = __ll_lowpart (__v); \
+ \
+ __x0 = (UWtype) __ul * __vl; \
+ __x2 = (UWtype) __uh * __vl; \
+ \
+ (w1) = (__x2 + (__x0 >> W_TYPE_SIZE/2)) >> W_TYPE_SIZE/2; \
+ (w0) = (__x2 << W_TYPE_SIZE/2) + __x0; \
+ } while (0)
+
+/* Count the leading zeros on a limb, but assuming it fits in 32 bits.
+ The count returned will be in the range 32 to 63.
+ This is the 32-bit generic C count_leading_zeros from longlong.h. */
+#define count_leading_zeros_32(count, x) \
+ do { \
+ mp_limb_t __xr = (x); \
+ unsigned __a; \
+ ASSERT ((x) != 0); \
+ ASSERT ((x) <= CNST_LIMB(0xFFFFFFFF)); \
+ __a = __xr < ((UWtype) 1 << 16) ? (__xr < ((UWtype) 1 << 8) ? 1 : 8 + 1) \
+ : (__xr < ((UWtype) 1 << 24) ? 16 + 1 : 24 + 1); \
+ \
+ (count) = W_TYPE_SIZE + 1 - __a - __clz_tab[__xr >> __a]; \
+ } while (0)
+
+
+/* Set inv to a 32-bit inverse floor((b*(b-d)-1) / d), knowing that d fits
+ 32 bits and is normalized (high bit set). */
+#define invert_half_limb(inv, d) \
+ do { \
+ mp_limb_t _n; \
+ ASSERT ((d) <= 0xFFFFFFFF); \
+ ASSERT ((d) & 0x80000000); \
+ _n = (((mp_limb_t) -(d)) << 32) - 1; \
+ (inv) = (mp_limb_t) (unsigned) (_n / (d)); \
+ } while (0)
+
+
+/* Divide nh:nl by d, setting q to the quotient and r to the remainder.
+ q, r, nh and nl are 32-bits each, d_limb is 32-bits but in an mp_limb_t,
+ dinv_limb is similarly a 32-bit inverse but in an mp_limb_t. */
+
+#define udiv_qrnnd_half_preinv(q, r, nh, nl, d_limb, dinv_limb) \
+ do { \
+ unsigned _n2, _n10, _n1, _nadj, _q11n, _xh, _r, _q; \
+ mp_limb_t _n, _x; \
+ ASSERT (d_limb <= 0xFFFFFFFF); \
+ ASSERT (dinv_limb <= 0xFFFFFFFF); \
+ ASSERT (d_limb & 0x80000000); \
+ ASSERT (nh < d_limb); \
+ _n10 = (nl); \
+ _n2 = (nh); \
+ _n1 = (int) _n10 >> 31; \
+ _nadj = _n10 + (_n1 & d_limb); \
+ _x = dinv_limb * (_n2 - _n1) + _nadj; \
+ _q11n = ~(_n2 + HIGH32 (_x)); /* -q1-1 */ \
+ _n = ((mp_limb_t) _n2 << 32) + _n10; \
+ _x = _n + d_limb * _q11n; /* n-q1*d-d */ \
+ _xh = HIGH32 (_x) - d_limb; /* high(n-q1*d-d) */ \
+ ASSERT (_xh == 0 || _xh == ~0); \
+ _r = _x + (d_limb & _xh); /* addback */ \
+ _q = _xh - _q11n; /* q1+1-addback */ \
+ ASSERT (_r < d_limb); \
+ ASSERT (d_limb * _q + _r == _n); \
+ (r) = _r; \
+ (q) = _q; \
+ } while (0)
+
+
diff --git a/gmp/mpn/sparc64/ultrasparc1234/add_n.asm b/gmp/mpn/sparc64/ultrasparc1234/add_n.asm
new file mode 100644
index 0000000000..92374d2552
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparc1234/add_n.asm
@@ -0,0 +1,241 @@
+dnl SPARC v9 mpn_add_n -- Add two limb vectors of the same length > 0 and
+dnl store sum in a third limb vector.
+
+dnl Copyright 2001-2003, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 4
+C UltraSPARC 3: 4.5
+
+C Compute carry-out from the most significant bits of u,v, and r, where
+C r=u+v+carry_in, using logic operations.
+
+C This code runs at 4 cycles/limb on UltraSPARC 1 and 2. It has a 4 insn
+C recurrency, and the UltraSPARC 1 and 2 the IE units are 100% saturated.
+C Therefore, it seems futile to try to optimize this any further...
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`vp', `%i2')
+define(`n', `%i3')
+
+define(`u0', `%l0')
+define(`u1', `%l2')
+define(`u2', `%l4')
+define(`u3', `%l6')
+define(`v0', `%l1')
+define(`v1', `%l3')
+define(`v2', `%l5')
+define(`v3', `%l7')
+
+define(`cy',`%i4')
+
+define(`fanop',`fitod %f0,%f2') dnl A quasi nop running in the FA pipe
+define(`fmnop',`fmuld %f0,%f0,%f4') dnl A quasi nop running in the FM pipe
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_add_nc)
+ save %sp,-160,%sp
+
+ fitod %f0,%f0 C make sure f0 contains small, quiet number
+ subcc n,4,%g0
+ bl,pn %xcc,.Loop0
+ nop
+ b,a L(com)
+EPILOGUE()
+
+PROLOGUE(mpn_add_n)
+ save %sp,-160,%sp
+
+ fitod %f0,%f0 C make sure f0 contains small, quiet number
+ subcc n,4,%g0
+ bl,pn %xcc,.Loop0
+ mov 0,cy
+L(com):
+ ldx [up+0],u0
+ ldx [vp+0],v0
+ add up,32,up
+ ldx [up-24],u1
+ ldx [vp+8],v1
+ add vp,32,vp
+ ldx [up-16],u2
+ ldx [vp-16],v2
+ ldx [up-8],u3
+ ldx [vp-8],v3
+ subcc n,8,n
+ add u0,v0,%g1 C main add
+ add %g1,cy,%g5 C carry add
+ or u0,v0,%g2
+ bl,pn %xcc,.Lend4567
+ fanop
+ b,a .Loop
+
+ .align 16
+C START MAIN LOOP
+.Loop: andn %g2,%g5,%g2
+ and u0,v0,%g3
+ ldx [up+0],u0
+ fanop
+C --
+ or %g3,%g2,%g2
+ ldx [vp+0],v0
+ add up,32,up
+ fanop
+C --
+ srlx %g2,63,cy
+ add u1,v1,%g1
+ stx %g5,[rp+0]
+ fanop
+C --
+ add %g1,cy,%g5
+ or u1,v1,%g2
+ fmnop
+ fanop
+C --
+ andn %g2,%g5,%g2
+ and u1,v1,%g3
+ ldx [up-24],u1
+ fanop
+C --
+ or %g3,%g2,%g2
+ ldx [vp+8],v1
+ add vp,32,vp
+ fanop
+C --
+ srlx %g2,63,cy
+ add u2,v2,%g1
+ stx %g5,[rp+8]
+ fanop
+C --
+ add %g1,cy,%g5
+ or u2,v2,%g2
+ fmnop
+ fanop
+C --
+ andn %g2,%g5,%g2
+ and u2,v2,%g3
+ ldx [up-16],u2
+ fanop
+C --
+ or %g3,%g2,%g2
+ ldx [vp-16],v2
+ add rp,32,rp
+ fanop
+C --
+ srlx %g2,63,cy
+ add u3,v3,%g1
+ stx %g5,[rp-16]
+ fanop
+C --
+ add %g1,cy,%g5
+ or u3,v3,%g2
+ fmnop
+ fanop
+C --
+ andn %g2,%g5,%g2
+ and u3,v3,%g3
+ ldx [up-8],u3
+ fanop
+C --
+ or %g3,%g2,%g2
+ subcc n,4,n
+ ldx [vp-8],v3
+ fanop
+C --
+ srlx %g2,63,cy
+ add u0,v0,%g1
+ stx %g5,[rp-8]
+ fanop
+C --
+ add %g1,cy,%g5
+ or u0,v0,%g2
+ bge,pt %xcc,.Loop
+ fanop
+C END MAIN LOOP
+.Lend4567:
+ andn %g2,%g5,%g2
+ and u0,v0,%g3
+ or %g3,%g2,%g2
+ srlx %g2,63,cy
+ add u1,v1,%g1
+ stx %g5,[rp+0]
+ add %g1,cy,%g5
+ or u1,v1,%g2
+ andn %g2,%g5,%g2
+ and u1,v1,%g3
+ or %g3,%g2,%g2
+ srlx %g2,63,cy
+ add u2,v2,%g1
+ stx %g5,[rp+8]
+ add %g1,cy,%g5
+ or u2,v2,%g2
+ andn %g2,%g5,%g2
+ and u2,v2,%g3
+ or %g3,%g2,%g2
+ add rp,32,rp
+ srlx %g2,63,cy
+ add u3,v3,%g1
+ stx %g5,[rp-16]
+ add %g1,cy,%g5
+ or u3,v3,%g2
+ andn %g2,%g5,%g2
+ and u3,v3,%g3
+ or %g3,%g2,%g2
+ srlx %g2,63,cy
+ stx %g5,[rp-8]
+
+ addcc n,4,n
+ bz,pn %xcc,.Lret
+ fanop
+
+.Loop0: ldx [up],u0
+ add up,8,up
+ ldx [vp],v0
+ add vp,8,vp
+ add rp,8,rp
+ subcc n,1,n
+ add u0,v0,%g1
+ or u0,v0,%g2
+ add %g1,cy,%g5
+ and u0,v0,%g3
+ andn %g2,%g5,%g2
+ stx %g5,[rp-8]
+ or %g3,%g2,%g2
+ bnz,pt %xcc,.Loop0
+ srlx %g2,63,cy
+
+.Lret: mov cy,%i0
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparc1234/addmul_1.asm b/gmp/mpn/sparc64/ultrasparc1234/addmul_1.asm
new file mode 100644
index 0000000000..48a94146ff
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparc1234/addmul_1.asm
@@ -0,0 +1,606 @@
+dnl SPARC v9 64-bit mpn_addmul_1 -- Multiply a limb vector with a limb and add
+dnl the result to a second limb vector.
+
+dnl Copyright 1998, 2000-2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 14
+C UltraSPARC 3: 17.5
+
+C Algorithm: We use eight floating-point multiplies per limb product, with the
+C invariant v operand split into four 16-bit pieces, and the up operand split
+C into 32-bit pieces. We sum pairs of 48-bit partial products using
+C floating-point add, then convert the four 49-bit product-sums and transfer
+C them to the integer unit.
+
+C Possible optimizations:
+C 0. Rewrite to use algorithm of mpn_addmul_2.
+C 1. Align the stack area where we transfer the four 49-bit product-sums
+C to a 32-byte boundary. That would minimize the cache collision.
+C (UltraSPARC-1/2 use a direct-mapped cache.) (Perhaps even better would
+C be to align the area to map to the area immediately before up?)
+C 2. Sum the 4 49-bit quantities using 32-bit operations, as in the
+C develop mpn_addmul_2. This would save many integer instructions.
+C 3. Unrolling. Questionable if it is worth the code expansion, given that
+C it could only save 1 cycle/limb.
+C 4. Specialize for particular v values. If its upper 32 bits are zero, we
+C could save many operations, in the FPU (fmuld), but more so in the IEU
+C since we'll be summing 48-bit quantities, which might be simpler.
+C 5. Ideally, we should schedule the f2/f3 and f4/f5 RAW further apart, and
+C the i00,i16,i32,i48 RAW less apart. The latter apart-scheduling should
+C not be greater than needed for L2 cache latency, and also not so great
+C that i16 needs to be copied.
+C 6. Avoid performing mem+fa+fm in the same cycle, at least not when we want
+C to get high IEU bandwidth. (12 of the 14 cycles will be free for 2 IEU
+C ops.)
+
+C Instruction classification (as per UltraSPARC-1/2 functional units):
+C 8 FM
+C 10 FA
+C 12 MEM
+C 10 ISHIFT + 14 IADDLOG
+C 1 BRANCH
+C 55 insns totally (plus one mov insn that should be optimized out)
+
+C The loop executes 56 instructions in 14 cycles on UltraSPARC-1/2, i.e we
+C sustain the peak execution rate of 4 instructions/cycle.
+
+C INPUT PARAMETERS
+C rp i0
+C up i1
+C n i2
+C v i3
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+
+define(`p00', `%f8') define(`p16',`%f10') define(`p32',`%f12') define(`p48',`%f14')
+define(`r32',`%f16') define(`r48',`%f18') define(`r64',`%f20') define(`r80',`%f22')
+define(`v00',`%f24') define(`v16',`%f26') define(`v32',`%f28') define(`v48',`%f30')
+define(`u00',`%f32') define(`u32', `%f34')
+define(`a00',`%f36') define(`a16',`%f38') define(`a32',`%f40') define(`a48',`%f42')
+define(`cy',`%g1')
+define(`rlimb',`%g3')
+define(`i00',`%l0') define(`i16',`%l1') define(`i32',`%l2') define(`i48',`%l3')
+define(`xffffffff',`%l7')
+define(`xffff',`%o0')
+
+PROLOGUE(mpn_addmul_1)
+
+C Initialization. (1) Split v operand into four 16-bit chunks and store them
+C as IEEE double in fp registers. (2) Clear upper 32 bits of fp register pairs
+C f2 and f4. (3) Store masks in registers aliased to `xffff' and `xffffffff'.
+
+ save %sp, -256, %sp
+ mov -1, %g4
+ srlx %g4, 48, xffff C store mask in register `xffff'
+ and %i3, xffff, %g2
+ stx %g2, [%sp+2223+0]
+ srlx %i3, 16, %g3
+ and %g3, xffff, %g3
+ stx %g3, [%sp+2223+8]
+ srlx %i3, 32, %g2
+ and %g2, xffff, %g2
+ stx %g2, [%sp+2223+16]
+ srlx %i3, 48, %g3
+ stx %g3, [%sp+2223+24]
+ srlx %g4, 32, xffffffff C store mask in register `xffffffff'
+
+ sllx %i2, 3, %i2
+ mov 0, cy C clear cy
+ add %i0, %i2, %i0
+ add %i1, %i2, %i1
+ neg %i2
+ add %i1, 4, %i5
+ add %i0, -32, %i4
+ add %i0, -16, %i0
+
+ ldd [%sp+2223+0], v00
+ ldd [%sp+2223+8], v16
+ ldd [%sp+2223+16], v32
+ ldd [%sp+2223+24], v48
+ ld [%sp+2223+0],%f2 C zero f2
+ ld [%sp+2223+0],%f4 C zero f4
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fxtod v00, v00
+ fxtod v16, v16
+ fxtod v32, v32
+ fxtod v48, v48
+
+C Start real work. (We sneakingly read f3 and f5 above...)
+C The software pipeline is very deep, requiring 4 feed-in stages.
+
+ fxtod %f2, u00
+ fxtod %f4, u32
+ fmuld u00, v00, a00
+ fmuld u00, v16, a16
+ fmuld u00, v32, p32
+ fmuld u32, v00, r32
+ fmuld u00, v48, p48
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .L_two_or_more
+ fmuld u32, v16, r48
+
+.L_one:
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ fdtox a00, a00
+ faddd p48, r48, a48
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ fdtox a32, a32
+ fdtox a48, a48
+ std a00, [%sp+2223+0]
+ std a16, [%sp+2223+8]
+ std a32, [%sp+2223+16]
+ std a48, [%sp+2223+24]
+ add %i2, 8, %i2
+
+ fdtox r64, a00
+ ldx [%i0+%i2], rlimb C read rp[i]
+ fdtox r80, a16
+ ldx [%sp+2223+0], i00
+ ldx [%sp+2223+8], i16
+ ldx [%sp+2223+16], i32
+ ldx [%sp+2223+24], i48
+ std a00, [%sp+2223+0]
+ std a16, [%sp+2223+8]
+ add %i2, 8, %i2
+
+ srlx rlimb, 32, %g4 C HI(rlimb)
+ and rlimb, xffffffff, %g5 C LO(rlimb)
+ add i00, %g5, %g5 C i00+ now in g5
+ ldx [%sp+2223+0], i00
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ add i32, %g4, %g4 C i32+ now in g4
+ sllx i48, 32, %l6 C (i48 << 32)
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ add %l6, %o2, %o2 C mi64- in %o2
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ b .L_out_1
+ add %i2, 8, %i2
+
+.L_two_or_more:
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fdtox a00, a00
+ faddd p48, r48, a48
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ fdtox a32, a32
+ fxtod %f2, u00
+ fxtod %f4, u32
+ fdtox a48, a48
+ std a00, [%sp+2223+0]
+ fmuld u00, v00, p00
+ std a16, [%sp+2223+8]
+ fmuld u00, v16, p16
+ std a32, [%sp+2223+16]
+ fmuld u00, v32, p32
+ std a48, [%sp+2223+24]
+ faddd p00, r64, a00
+ fmuld u32, v00, r32
+ faddd p16, r80, a16
+ fmuld u00, v48, p48
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .L_three_or_more
+ fmuld u32, v16, r48
+
+.L_two:
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ fdtox a00, a00
+ ldx [%i0+%i2], rlimb C read rp[i]
+ faddd p48, r48, a48
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ ldx [%sp+2223+8], i16
+ ldx [%sp+2223+16], i32
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ std a00, [%sp+2223+0]
+ std a16, [%sp+2223+8]
+ std a32, [%sp+2223+16]
+ std a48, [%sp+2223+24]
+ add %i2, 8, %i2
+
+ fdtox r64, a00
+ srlx rlimb, 32, %g4 C HI(rlimb)
+ and rlimb, xffffffff, %g5 C LO(rlimb)
+ ldx [%i0+%i2], rlimb C read rp[i]
+ add i00, %g5, %g5 C i00+ now in g5
+ fdtox r80, a16
+ ldx [%sp+2223+0], i00
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ add i32, %g4, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ sllx i48, 32, %l6 C (i48 << 32)
+ ldx [%sp+2223+24], i48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ add %l6, %o2, %o2 C mi64- in %o2
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ b .L_out_2
+ add %i2, 8, %i2
+
+.L_three_or_more:
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fdtox a00, a00
+ ldx [%i0+%i2], rlimb C read rp[i]
+ faddd p48, r48, a48
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ ldx [%sp+2223+8], i16
+ fxtod %f2, u00
+ ldx [%sp+2223+16], i32
+ fxtod %f4, u32
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ std a00, [%sp+2223+0]
+ fmuld u00, v00, p00
+ std a16, [%sp+2223+8]
+ fmuld u00, v16, p16
+ std a32, [%sp+2223+16]
+ fmuld u00, v32, p32
+ std a48, [%sp+2223+24]
+ faddd p00, r64, a00
+ fmuld u32, v00, r32
+ faddd p16, r80, a16
+ fmuld u00, v48, p48
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .L_four_or_more
+ fmuld u32, v16, r48
+
+.L_three:
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ fdtox a00, a00
+ srlx rlimb, 32, %g4 C HI(rlimb)
+ and rlimb, xffffffff, %g5 C LO(rlimb)
+ ldx [%i0+%i2], rlimb C read rp[i]
+ faddd p48, r48, a48
+ add i00, %g5, %g5 C i00+ now in g5
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ add i32, %g4, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ sllx i48, 32, %l6 C (i48 << 32)
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ std a32, [%sp+2223+16]
+ add %l6, %o2, %o2 C mi64- in %o2
+ std a48, [%sp+2223+24]
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ b .L_out_3
+ add %i2, 8, %i2
+
+.L_four_or_more:
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fdtox a00, a00
+ srlx rlimb, 32, %g4 C HI(rlimb)
+ and rlimb, xffffffff, %g5 C LO(rlimb)
+ ldx [%i0+%i2], rlimb C read rp[i]
+ faddd p48, r48, a48
+ add i00, %g5, %g5 C i00+ now in g5
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ fxtod %f2, u00
+ srlx i48, 16, %l5 C (i48 >> 16)
+ add i32, %g4, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ fxtod %f4, u32
+ sllx i48, 32, %l6 C (i48 << 32)
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ fmuld u00, v00, p00
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ fmuld u00, v16, p16
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ std a32, [%sp+2223+16]
+ fmuld u00, v32, p32
+ add %l6, %o2, %o2 C mi64- in %o2
+ std a48, [%sp+2223+24]
+ faddd p00, r64, a00
+ fmuld u32, v00, r32
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ faddd p16, r80, a16
+ fmuld u00, v48, p48
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .Loop
+ fmuld u32, v16, r48
+
+.L_four:
+ b,a .L_out_4
+
+C BEGIN MAIN LOOP
+ .align 16
+.Loop:
+C 00
+ srlx %o4, 16, %o5 C (x >> 16)
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+C 01
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fdtox a00, a00
+C 02
+ srlx rlimb, 32, %g4 C HI(rlimb)
+ and rlimb, xffffffff, %g5 C LO(rlimb)
+ ldx [%i0+%i2], rlimb C read rp[i]
+ faddd p48, r48, a48
+C 03
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ add i00, %g5, %g5 C i00+ now in g5
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+C 04
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+C 05
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ fxtod %f2, u00
+C 06
+ srlx i48, 16, %l5 C (i48 >> 16)
+ add i32, %g4, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ fxtod %f4, u32
+C 07
+ sllx i48, 32, %l6 C (i48 << 32)
+ or %i3, %o5, %o5
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+C 08
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ fmuld u00, v00, p00
+C 09
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ fmuld u00, v16, p16
+C 10
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ std a32, [%sp+2223+16]
+ fmuld u00, v32, p32
+C 11
+ add %l6, %o2, %o2 C mi64- in %o2
+ std a48, [%sp+2223+24]
+ faddd p00, r64, a00
+ fmuld u32, v00, r32
+C 12
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ stx %o5, [%i4+%i2]
+ faddd p16, r80, a16
+ fmuld u00, v48, p48
+C 13
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .Loop
+ fmuld u32, v16, r48
+C END MAIN LOOP
+
+.L_out_4:
+ srlx %o4, 16, %o5 C (x >> 16)
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ fdtox a00, a00
+ srlx rlimb, 32, %g4 C HI(rlimb)
+ and rlimb, xffffffff, %g5 C LO(rlimb)
+ ldx [%i0+%i2], rlimb C read rp[i]
+ faddd p48, r48, a48
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ add i00, %g5, %g5 C i00+ now in g5
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ add i32, %g4, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ sllx i48, 32, %l6 C (i48 << 32)
+ or %i3, %o5, %o5
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ std a32, [%sp+2223+16]
+ add %l6, %o2, %o2 C mi64- in %o2
+ std a48, [%sp+2223+24]
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ stx %o5, [%i4+%i2]
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ add %i2, 8, %i2
+.L_out_3:
+ srlx %o4, 16, %o5 C (x >> 16)
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ fdtox r64, a00
+ srlx rlimb, 32, %g4 C HI(rlimb)
+ and rlimb, xffffffff, %g5 C LO(rlimb)
+ ldx [%i0+%i2], rlimb C read rp[i]
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ add i00, %g5, %g5 C i00+ now in g5
+ fdtox r80, a16
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ ldx [%sp+2223+0], i00
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ add i32, %g4, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ sllx i48, 32, %l6 C (i48 << 32)
+ or %i3, %o5, %o5
+ ldx [%sp+2223+24], i48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ add %l6, %o2, %o2 C mi64- in %o2
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ stx %o5, [%i4+%i2]
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ add %i2, 8, %i2
+.L_out_2:
+ srlx %o4, 16, %o5 C (x >> 16)
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ srlx rlimb, 32, %g4 C HI(rlimb)
+ and rlimb, xffffffff, %g5 C LO(rlimb)
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ add i00, %g5, %g5 C i00+ now in g5
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ ldx [%sp+2223+0], i00
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ add i32, %g4, %g4 C i32+ now in g4
+ sllx i48, 32, %l6 C (i48 << 32)
+ or %i3, %o5, %o5
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ add %l6, %o2, %o2 C mi64- in %o2
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ stx %o5, [%i4+%i2]
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ add %i2, 8, %i2
+.L_out_1:
+ srlx %o4, 16, %o5 C (x >> 16)
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ or %i3, %o5, %o5
+ stx %o5, [%i4+%i2]
+
+ sllx i00, 0, %g2
+ add %g2, cy, cy
+ sllx i16, 16, %g3
+ add %g3, cy, cy
+
+ return %i7+8
+ mov cy, %o0
+EPILOGUE(mpn_addmul_1)
diff --git a/gmp/mpn/sparc64/ultrasparc1234/addmul_2.asm b/gmp/mpn/sparc64/ultrasparc1234/addmul_2.asm
new file mode 100644
index 0000000000..37674d7423
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparc1234/addmul_2.asm
@@ -0,0 +1,551 @@
+dnl SPARC v9 64-bit mpn_addmul_2 -- Multiply an n limb number with 2-limb
+dnl number and add the result to a n limb vector.
+
+dnl Copyright 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 9
+C UltraSPARC 3: 10
+
+C Algorithm: We use 16 floating-point multiplies per limb product, with the
+C 2-limb v operand split into eight 16-bit pieces, and the n-limb u operand
+C split into 32-bit pieces. We sum four 48-bit partial products using
+C floating-point add, then convert the resulting four 50-bit quantities and
+C transfer them to the integer unit.
+
+C Possible optimizations:
+C 1. Align the stack area where we transfer the four 50-bit product-sums
+C to a 32-byte boundary. That would minimize the cache collision.
+C (UltraSPARC-1/2 use a direct-mapped cache.) (Perhaps even better would
+C be to align the area to map to the area immediately before up?)
+C 2. Perform two of the fp->int conversions with integer instructions. We
+C can get almost ten free IEU slots, if we clean up bookkeeping and the
+C silly carry-limb code.
+C 3. For an mpn_addmul_1 based on this, we need to fix the silly carry-limb
+C code.
+
+C OSP (Overlapping software pipeline) version of mpn_mul_basecase:
+C Operand swap will require 8 LDDA and 8 FXTOD, which will mean 8 cycles.
+C FI = 20
+C L = 9 x un * vn
+C WDFI = 10 x vn / 2
+C WD = 4
+
+C Instruction classification (as per UltraSPARC functional units).
+C Assuming silly carry code is fixed. Includes bookkeeping.
+C
+C mpn_addmul_X mpn_mul_X
+C 1 2 1 2
+C ========== ==========
+C FM 8 16 8 16
+C FA 10 18 10 18
+C MEM 12 12 10 10
+C ISHIFT 6 6 6 6
+C IADDLOG 11 11 10 10
+C BRANCH 1 1 1 1
+C
+C TOTAL IEU 17 17 16 16
+C TOTAL 48 64 45 61
+C
+C IEU cycles 8.5 8.5 8 8
+C MEM cycles 12 12 10 10
+C ISSUE cycles 12 16 11.25 15.25
+C FPU cycles 10 18 10 18
+C cycles/loop 12 18 12 18
+C cycles/limb 12 9 12 9
+
+
+C INPUT PARAMETERS
+C rp[n + 1] i0
+C up[n] i1
+C n i2
+C vp[2] i3
+
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+
+C Combine registers:
+C u00_hi= u32_hi
+C u00_lo= u32_lo
+C a000 = out000
+C a016 = out016
+C Free: f52 f54
+
+
+define(`p000', `%f8') define(`p016',`%f10')
+define(`p032',`%f12') define(`p048',`%f14')
+define(`p064',`%f16') define(`p080',`%f18')
+define(`p096a',`%f20') define(`p112a',`%f22')
+define(`p096b',`%f56') define(`p112b',`%f58')
+
+define(`out000',`%f0') define(`out016',`%f6')
+
+define(`v000',`%f24') define(`v016',`%f26')
+define(`v032',`%f28') define(`v048',`%f30')
+define(`v064',`%f44') define(`v080',`%f46')
+define(`v096',`%f48') define(`v112',`%f50')
+
+define(`u00',`%f32') define(`u32', `%f34')
+
+define(`a000',`%f36') define(`a016',`%f38')
+define(`a032',`%f40') define(`a048',`%f42')
+define(`a064',`%f60') define(`a080',`%f62')
+
+define(`u00_hi',`%f2') define(`u32_hi',`%f4')
+define(`u00_lo',`%f3') define(`u32_lo',`%f5')
+
+define(`cy',`%g1')
+define(`rlimb',`%g3')
+define(`i00',`%l0') define(`i16',`%l1')
+define(`r00',`%l2') define(`r32',`%l3')
+define(`xffffffff',`%l7')
+define(`xffff',`%o0')
+
+
+PROLOGUE(mpn_addmul_2)
+
+C Initialization. (1) Split v operand into eight 16-bit chunks and store them
+C as IEEE double in fp registers. (2) Clear upper 32 bits of fp register pairs
+C f2 and f4. (3) Store masks in registers aliased to `xffff' and `xffffffff'.
+C This code could be better scheduled.
+
+ save %sp, -256, %sp
+
+ifdef(`HAVE_VIS',
+` mov -1, %g4
+ wr %g0, 0xD2, %asi
+ srlx %g4, 32, xffffffff C store mask in register `xffffffff'
+ ldda [%i3+6] %asi, v000
+ ldda [%i3+4] %asi, v016
+ ldda [%i3+2] %asi, v032
+ ldda [%i3+0] %asi, v048
+ fxtod v000, v000
+ ldda [%i3+14] %asi, v064
+ fxtod v016, v016
+ ldda [%i3+12] %asi, v080
+ fxtod v032, v032
+ ldda [%i3+10] %asi, v096
+ fxtod v048, v048
+ ldda [%i3+8] %asi, v112
+ fxtod v064, v064
+ fxtod v080, v080
+ fxtod v096, v096
+ fxtod v112, v112
+ fzero u00_hi
+ fzero u32_hi
+',
+` mov -1, %g4
+ ldx [%i3+0], %l0 C vp[0]
+ srlx %g4, 48, xffff C store mask in register `xffff'
+ ldx [%i3+8], %l1 C vp[1]
+
+ and %l0, xffff, %g2
+ stx %g2, [%sp+2223+0]
+ srlx %l0, 16, %g3
+ and %g3, xffff, %g3
+ stx %g3, [%sp+2223+8]
+ srlx %l0, 32, %g2
+ and %g2, xffff, %g2
+ stx %g2, [%sp+2223+16]
+ srlx %l0, 48, %g3
+ stx %g3, [%sp+2223+24]
+ and %l1, xffff, %g2
+ stx %g2, [%sp+2223+32]
+ srlx %l1, 16, %g3
+ and %g3, xffff, %g3
+ stx %g3, [%sp+2223+40]
+ srlx %l1, 32, %g2
+ and %g2, xffff, %g2
+ stx %g2, [%sp+2223+48]
+ srlx %l1, 48, %g3
+ stx %g3, [%sp+2223+56]
+
+ srlx %g4, 32, xffffffff C store mask in register `xffffffff'
+
+ ldd [%sp+2223+0], v000
+ ldd [%sp+2223+8], v016
+ ldd [%sp+2223+16], v032
+ ldd [%sp+2223+24], v048
+ fxtod v000, v000
+ ldd [%sp+2223+32], v064
+ fxtod v016, v016
+ ldd [%sp+2223+40], v080
+ fxtod v032, v032
+ ldd [%sp+2223+48], v096
+ fxtod v048, v048
+ ldd [%sp+2223+56], v112
+ fxtod v064, v064
+ ld [%sp+2223+0], u00_hi C zero u00_hi
+ fxtod v080, v080
+ ld [%sp+2223+0], u32_hi C zero u32_hi
+ fxtod v096, v096
+ fxtod v112, v112
+')
+C Initialization done.
+ mov 0, %g2
+ mov 0, rlimb
+ mov 0, %g4
+ add %i0, -8, %i0 C BOOKKEEPING
+
+C Start software pipeline.
+
+ ld [%i1+4], u00_lo C read low 32 bits of up[i]
+ fxtod u00_hi, u00
+C mid
+ ld [%i1+0], u32_lo C read high 32 bits of up[i]
+ fmuld u00, v000, a000
+ fmuld u00, v016, a016
+ fmuld u00, v032, a032
+ fmuld u00, v048, a048
+ add %i2, -1, %i2 C BOOKKEEPING
+ fmuld u00, v064, p064
+ add %i1, 8, %i1 C BOOKKEEPING
+ fxtod u32_hi, u32
+ fmuld u00, v080, p080
+ fmuld u00, v096, p096a
+ brnz,pt %i2, .L_2_or_more
+ fmuld u00, v112, p112a
+
+.L1: fdtox a000, out000
+ fmuld u32, v000, p000
+ fdtox a016, out016
+ fmuld u32, v016, p016
+ fmovd p064, a064
+ fmuld u32, v032, p032
+ fmovd p080, a080
+ fmuld u32, v048, p048
+ std out000, [%sp+2223+16]
+ faddd p000, a032, a000
+ fmuld u32, v064, p064
+ std out016, [%sp+2223+24]
+ fxtod u00_hi, u00
+ faddd p016, a048, a016
+ fmuld u32, v080, p080
+ faddd p032, a064, a032
+ fmuld u32, v096, p096b
+ faddd p048, a080, a048
+ fmuld u32, v112, p112b
+C mid
+ fdtox a000, out000
+ fdtox a016, out016
+ faddd p064, p096a, a064
+ faddd p080, p112a, a080
+ std out000, [%sp+2223+0]
+ b .L_wd2
+ std out016, [%sp+2223+8]
+
+.L_2_or_more:
+ ld [%i1+4], u00_lo C read low 32 bits of up[i]
+ fdtox a000, out000
+ fmuld u32, v000, p000
+ fdtox a016, out016
+ fmuld u32, v016, p016
+ fmovd p064, a064
+ fmuld u32, v032, p032
+ fmovd p080, a080
+ fmuld u32, v048, p048
+ std out000, [%sp+2223+16]
+ faddd p000, a032, a000
+ fmuld u32, v064, p064
+ std out016, [%sp+2223+24]
+ fxtod u00_hi, u00
+ faddd p016, a048, a016
+ fmuld u32, v080, p080
+ faddd p032, a064, a032
+ fmuld u32, v096, p096b
+ faddd p048, a080, a048
+ fmuld u32, v112, p112b
+C mid
+ ld [%i1+0], u32_lo C read high 32 bits of up[i]
+ fdtox a000, out000
+ fmuld u00, v000, p000
+ fdtox a016, out016
+ fmuld u00, v016, p016
+ faddd p064, p096a, a064
+ fmuld u00, v032, p032
+ faddd p080, p112a, a080
+ fmuld u00, v048, p048
+ add %i2, -1, %i2 C BOOKKEEPING
+ std out000, [%sp+2223+0]
+ faddd p000, a032, a000
+ fmuld u00, v064, p064
+ add %i1, 8, %i1 C BOOKKEEPING
+ std out016, [%sp+2223+8]
+ fxtod u32_hi, u32
+ faddd p016, a048, a016
+ fmuld u00, v080, p080
+ faddd p032, a064, a032
+ fmuld u00, v096, p096a
+ faddd p048, a080, a048
+ brnz,pt %i2, .L_3_or_more
+ fmuld u00, v112, p112a
+
+ b .Lend
+ nop
+
+C 64 32 0
+C . . .
+C . |__rXXX_| 32
+C . |___cy___| 34
+C . |_______i00__| 50
+C |_______i16__| . 50
+
+
+C BEGIN MAIN LOOP
+ .align 16
+.L_3_or_more:
+.Loop: ld [%i1+4], u00_lo C read low 32 bits of up[i]
+ and %g2, xffffffff, %g2
+ fdtox a000, out000
+ fmuld u32, v000, p000
+C
+ lduw [%i0+4+8], r00 C read low 32 bits of rp[i]
+ add %g2, rlimb, %l5
+ fdtox a016, out016
+ fmuld u32, v016, p016
+C
+ srlx %l5, 32, cy
+ ldx [%sp+2223+16], i00
+ faddd p064, p096b, a064
+ fmuld u32, v032, p032
+C
+ add %g4, cy, cy C new cy
+ ldx [%sp+2223+24], i16
+ faddd p080, p112b, a080
+ fmuld u32, v048, p048
+C
+ nop
+ std out000, [%sp+2223+16]
+ faddd p000, a032, a000
+ fmuld u32, v064, p064
+C
+ add i00, r00, rlimb
+ add %i0, 8, %i0 C BOOKKEEPING
+ std out016, [%sp+2223+24]
+ fxtod u00_hi, u00
+C
+ sllx i16, 16, %g2
+ add cy, rlimb, rlimb
+ faddd p016, a048, a016
+ fmuld u32, v080, p080
+C
+ srlx i16, 16, %g4
+ add %g2, rlimb, %l5
+ faddd p032, a064, a032
+ fmuld u32, v096, p096b
+C
+ stw %l5, [%i0+4]
+ nop
+ faddd p048, a080, a048
+ fmuld u32, v112, p112b
+C midloop
+ ld [%i1+0], u32_lo C read high 32 bits of up[i]
+ and %g2, xffffffff, %g2
+ fdtox a000, out000
+ fmuld u00, v000, p000
+C
+ lduw [%i0+0], r32 C read high 32 bits of rp[i]
+ add %g2, rlimb, %l5
+ fdtox a016, out016
+ fmuld u00, v016, p016
+C
+ srlx %l5, 32, cy
+ ldx [%sp+2223+0], i00
+ faddd p064, p096a, a064
+ fmuld u00, v032, p032
+C
+ add %g4, cy, cy C new cy
+ ldx [%sp+2223+8], i16
+ faddd p080, p112a, a080
+ fmuld u00, v048, p048
+C
+ add %i2, -1, %i2 C BOOKKEEPING
+ std out000, [%sp+2223+0]
+ faddd p000, a032, a000
+ fmuld u00, v064, p064
+C
+ add i00, r32, rlimb
+ add %i1, 8, %i1 C BOOKKEEPING
+ std out016, [%sp+2223+8]
+ fxtod u32_hi, u32
+C
+ sllx i16, 16, %g2
+ add cy, rlimb, rlimb
+ faddd p016, a048, a016
+ fmuld u00, v080, p080
+C
+ srlx i16, 16, %g4
+ add %g2, rlimb, %l5
+ faddd p032, a064, a032
+ fmuld u00, v096, p096a
+C
+ stw %l5, [%i0+0]
+ faddd p048, a080, a048
+ brnz,pt %i2, .Loop
+ fmuld u00, v112, p112a
+C END MAIN LOOP
+
+C WIND-DOWN PHASE 1
+.Lend: and %g2, xffffffff, %g2
+ fdtox a000, out000
+ fmuld u32, v000, p000
+ lduw [%i0+4+8], r00 C read low 32 bits of rp[i]
+ add %g2, rlimb, %l5
+ fdtox a016, out016
+ fmuld u32, v016, p016
+ srlx %l5, 32, cy
+ ldx [%sp+2223+16], i00
+ faddd p064, p096b, a064
+ fmuld u32, v032, p032
+ add %g4, cy, cy C new cy
+ ldx [%sp+2223+24], i16
+ faddd p080, p112b, a080
+ fmuld u32, v048, p048
+ std out000, [%sp+2223+16]
+ faddd p000, a032, a000
+ fmuld u32, v064, p064
+ add i00, r00, rlimb
+ add %i0, 8, %i0 C BOOKKEEPING
+ std out016, [%sp+2223+24]
+ sllx i16, 16, %g2
+ add cy, rlimb, rlimb
+ faddd p016, a048, a016
+ fmuld u32, v080, p080
+ srlx i16, 16, %g4
+ add %g2, rlimb, %l5
+ faddd p032, a064, a032
+ fmuld u32, v096, p096b
+ stw %l5, [%i0+4]
+ faddd p048, a080, a048
+ fmuld u32, v112, p112b
+C mid
+ and %g2, xffffffff, %g2
+ fdtox a000, out000
+ lduw [%i0+0], r32 C read high 32 bits of rp[i]
+ add %g2, rlimb, %l5
+ fdtox a016, out016
+ srlx %l5, 32, cy
+ ldx [%sp+2223+0], i00
+ faddd p064, p096a, a064
+ add %g4, cy, cy C new cy
+ ldx [%sp+2223+8], i16
+ faddd p080, p112a, a080
+ std out000, [%sp+2223+0]
+ add i00, r32, rlimb
+ std out016, [%sp+2223+8]
+ sllx i16, 16, %g2
+ add cy, rlimb, rlimb
+ srlx i16, 16, %g4
+ add %g2, rlimb, %l5
+ stw %l5, [%i0+0]
+
+C WIND-DOWN PHASE 2
+.L_wd2: and %g2, xffffffff, %g2
+ fdtox a032, out000
+ lduw [%i0+4+8], r00 C read low 32 bits of rp[i]
+ add %g2, rlimb, %l5
+ fdtox a048, out016
+ srlx %l5, 32, cy
+ ldx [%sp+2223+16], i00
+ add %g4, cy, cy C new cy
+ ldx [%sp+2223+24], i16
+ std out000, [%sp+2223+16]
+ add i00, r00, rlimb
+ add %i0, 8, %i0 C BOOKKEEPING
+ std out016, [%sp+2223+24]
+ sllx i16, 16, %g2
+ add cy, rlimb, rlimb
+ srlx i16, 16, %g4
+ add %g2, rlimb, %l5
+ stw %l5, [%i0+4]
+C mid
+ and %g2, xffffffff, %g2
+ fdtox a064, out000
+ lduw [%i0+0], r32 C read high 32 bits of rp[i]
+ add %g2, rlimb, %l5
+ fdtox a080, out016
+ srlx %l5, 32, cy
+ ldx [%sp+2223+0], i00
+ add %g4, cy, cy C new cy
+ ldx [%sp+2223+8], i16
+ std out000, [%sp+2223+0]
+ add i00, r32, rlimb
+ std out016, [%sp+2223+8]
+ sllx i16, 16, %g2
+ add cy, rlimb, rlimb
+ srlx i16, 16, %g4
+ add %g2, rlimb, %l5
+ stw %l5, [%i0+0]
+
+C WIND-DOWN PHASE 3
+.L_wd3: and %g2, xffffffff, %g2
+ fdtox p096b, out000
+ add %g2, rlimb, %l5
+ fdtox p112b, out016
+ srlx %l5, 32, cy
+ ldx [%sp+2223+16], rlimb
+ add %g4, cy, cy C new cy
+ ldx [%sp+2223+24], i16
+ std out000, [%sp+2223+16]
+ add %i0, 8, %i0 C BOOKKEEPING
+ std out016, [%sp+2223+24]
+ sllx i16, 16, %g2
+ add cy, rlimb, rlimb
+ srlx i16, 16, %g4
+ add %g2, rlimb, %l5
+ stw %l5, [%i0+4]
+C mid
+ and %g2, xffffffff, %g2
+ add %g2, rlimb, %l5
+ srlx %l5, 32, cy
+ ldx [%sp+2223+0], rlimb
+ add %g4, cy, cy C new cy
+ ldx [%sp+2223+8], i16
+ sllx i16, 16, %g2
+ add cy, rlimb, rlimb
+ srlx i16, 16, %g4
+ add %g2, rlimb, %l5
+ stw %l5, [%i0+0]
+
+ and %g2, xffffffff, %g2
+ add %g2, rlimb, %l5
+ srlx %l5, 32, cy
+ ldx [%sp+2223+16], i00
+ add %g4, cy, cy C new cy
+ ldx [%sp+2223+24], i16
+
+ sllx i16, 16, %g2
+ add i00, cy, cy
+ return %i7+8
+ add %g2, cy, %o0
+EPILOGUE(mpn_addmul_2)
diff --git a/gmp/mpn/sparc64/ultrasparc1234/lshiftc.asm b/gmp/mpn/sparc64/ultrasparc1234/lshiftc.asm
new file mode 100644
index 0000000000..47286d569e
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparc1234/lshiftc.asm
@@ -0,0 +1,165 @@
+dnl SPARC v9 mpn_lshiftc
+
+dnl Copyright 1996, 2000-2003, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 3
+C UltraSPARC 3: 2.67
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`cnt',`%i3')
+
+define(`u0', `%l0')
+define(`u1', `%l2')
+define(`u2', `%l4')
+define(`u3', `%l6')
+
+define(`tnc',`%i4')
+
+define(`fanop',`fitod %f0,%f2') dnl A quasi nop running in the FA pipe
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_lshiftc)
+ save %sp,-160,%sp
+
+ sllx n,3,%g1
+ sub %g0,cnt,tnc C negate shift count
+ add up,%g1,up C make %o1 point at end of src
+ add rp,%g1,rp C make %o0 point at end of res
+ ldx [up-8],u3 C load first limb
+ subcc n,5,n
+ srlx u3,tnc,%i5 C compute function result
+ bl,pn %xcc,.Lend1234
+ sllx u3,cnt,%g3
+
+ subcc n,4,n
+ ldx [up-16],u0
+ ldx [up-24],u1
+ add up,-32,up
+ ldx [up-0],u2
+ ldx [up-8],u3
+ srlx u0,tnc,%g2
+ bl,pn %xcc,.Lend5678
+ not %g3, %g3
+
+ b,a .Loop
+ ALIGN(16)
+.Loop:
+ sllx u0,cnt,%g1
+ andn %g3,%g2,%g3
+ ldx [up-16],u0
+ fanop
+C --
+ srlx u1,tnc,%g2
+ subcc n,4,n
+ stx %g3,[rp-8]
+ not %g1, %g1
+C --
+ sllx u1,cnt,%g3
+ andn %g1,%g2,%g1
+ ldx [up-24],u1
+ fanop
+C --
+ srlx u2,tnc,%g2
+ stx %g1,[rp-16]
+ add up,-32,up
+ not %g3, %g3
+C --
+ sllx u2,cnt,%g1
+ andn %g3,%g2,%g3
+ ldx [up-0],u2
+ fanop
+C --
+ srlx u3,tnc,%g2
+ stx %g3,[rp-24]
+ add rp,-32,rp
+ not %g1, %g1
+C --
+ sllx u3,cnt,%g3
+ andn %g1,%g2,%g1
+ ldx [up-8],u3
+ fanop
+C --
+ srlx u0,tnc,%g2
+ stx %g1,[rp-0]
+ bge,pt %xcc,.Loop
+ not %g3, %g3
+C --
+.Lend5678:
+ sllx u0,cnt,%g1
+ andn %g3,%g2,%g3
+ srlx u1,tnc,%g2
+ stx %g3,[rp-8]
+ not %g1, %g1
+ sllx u1,cnt,%g3
+ andn %g1,%g2,%g1
+ srlx u2,tnc,%g2
+ stx %g1,[rp-16]
+ not %g3, %g3
+ sllx u2,cnt,%g1
+ andn %g3,%g2,%g3
+ srlx u3,tnc,%g2
+ stx %g3,[rp-24]
+ add rp,-32,rp
+ not %g1, %g1
+ sllx u3,cnt,%g3 C carry...
+ andn %g1,%g2,%g1
+ stx %g1,[rp-0]
+
+.Lend1234:
+ addcc n,4,n
+ bz,pn %xcc,.Lret
+ fanop
+.Loop0:
+ add rp,-8,rp
+ subcc n,1,n
+ ldx [up-16],u3
+ add up,-8,up
+ srlx u3,tnc,%g2
+ not %g3, %g3
+ andn %g3,%g2,%g3
+ stx %g3,[rp]
+ sllx u3,cnt,%g3
+ bnz,pt %xcc,.Loop0
+ fanop
+.Lret:
+ not %g3, %g3
+ stx %g3,[rp-8]
+ mov %i5,%i0
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparc1234/mul_1.asm b/gmp/mpn/sparc64/ultrasparc1234/mul_1.asm
new file mode 100644
index 0000000000..871d562fcb
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparc1234/mul_1.asm
@@ -0,0 +1,580 @@
+dnl SPARC v9 64-bit mpn_mul_1 -- Multiply a limb vector with a limb and store
+dnl the result in a second limb vector.
+
+dnl Copyright 1998, 2000-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 14
+C UltraSPARC 3: 18.5
+
+C Algorithm: We use eight floating-point multiplies per limb product, with the
+C invariant v operand split into four 16-bit pieces, and the s1 operand split
+C into 32-bit pieces. We sum pairs of 48-bit partial products using
+C floating-point add, then convert the four 49-bit product-sums and transfer
+C them to the integer unit.
+
+C Possible optimizations:
+C 1. Align the stack area where we transfer the four 49-bit product-sums
+C to a 32-byte boundary. That would minimize the cache collision.
+C (UltraSPARC-1/2 use a direct-mapped cache.) (Perhaps even better would
+C be to align the area to map to the area immediately before s1?)
+C 2. Sum the 4 49-bit quantities using 32-bit operations, as in the
+C develop mpn_addmul_2. This would save many integer instructions.
+C 3. Unrolling. Questionable if it is worth the code expansion, given that
+C it could only save 1 cycle/limb.
+C 4. Specialize for particular v values. If its upper 32 bits are zero, we
+C could save many operations, in the FPU (fmuld), but more so in the IEU
+C since we'll be summing 48-bit quantities, which might be simpler.
+C 5. Ideally, we should schedule the f2/f3 and f4/f5 RAW further apart, and
+C the i00,i16,i32,i48 RAW less apart. The latter apart-scheduling should
+C not be greater than needed for L2 cache latency, and also not so great
+C that i16 needs to be copied.
+C 6. Avoid performing mem+fa+fm in the same cycle, at least not when we want
+C to get high IEU bandwidth. (12 of the 14 cycles will be free for 2 IEU
+C ops.)
+
+C Instruction classification (as per UltraSPARC-1/2 functional units):
+C 8 FM
+C 10 FA
+C 11 MEM
+C 9 ISHIFT + 10? IADDLOG
+C 1 BRANCH
+C 49 insns totally (plus three mov insns that should be optimized out)
+
+C The loop executes 53 instructions in 14 cycles on UltraSPARC-1/2, i.e we
+C sustain 3.79 instructions/cycle.
+
+C INPUT PARAMETERS
+C rp i0
+C up i1
+C n i2
+C v i3
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+
+define(`p00', `%f8') define(`p16',`%f10') define(`p32',`%f12') define(`p48',`%f14')
+define(`r32',`%f16') define(`r48',`%f18') define(`r64',`%f20') define(`r80',`%f22')
+define(`v00',`%f24') define(`v16',`%f26') define(`v32',`%f28') define(`v48',`%f30')
+define(`u00',`%f32') define(`u32', `%f34')
+define(`a00',`%f36') define(`a16',`%f38') define(`a32',`%f40') define(`a48',`%f42')
+define(`cy',`%g1')
+define(`rlimb',`%g3')
+define(`i00',`%l0') define(`i16',`%l1') define(`i32',`%l2') define(`i48',`%l3')
+define(`xffffffff',`%l7')
+define(`xffff',`%o0')
+
+PROLOGUE(mpn_mul_1)
+
+C Initialization. (1) Split v operand into four 16-bit chunks and store them
+C as IEEE double in fp registers. (2) Clear upper 32 bits of fp register pairs
+C f2 and f4. (3) Store masks in registers aliased to `xffff' and `xffffffff'.
+
+ save %sp, -256, %sp
+ mov -1, %g4
+ srlx %g4, 48, xffff C store mask in register `xffff'
+ and %i3, xffff, %g2
+ stx %g2, [%sp+2223+0]
+ srlx %i3, 16, %g3
+ and %g3, xffff, %g3
+ stx %g3, [%sp+2223+8]
+ srlx %i3, 32, %g2
+ and %g2, xffff, %g2
+ stx %g2, [%sp+2223+16]
+ srlx %i3, 48, %g3
+ stx %g3, [%sp+2223+24]
+ srlx %g4, 32, xffffffff C store mask in register `xffffffff'
+
+ sllx %i2, 3, %i2
+ mov 0, cy C clear cy
+ add %i0, %i2, %i0
+ add %i1, %i2, %i1
+ neg %i2
+ add %i1, 4, %i5
+ add %i0, -32, %i4
+ add %i0, -16, %i0
+
+ ldd [%sp+2223+0], v00
+ ldd [%sp+2223+8], v16
+ ldd [%sp+2223+16], v32
+ ldd [%sp+2223+24], v48
+ ld [%sp+2223+0],%f2 C zero f2
+ ld [%sp+2223+0],%f4 C zero f4
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fxtod v00, v00
+ fxtod v16, v16
+ fxtod v32, v32
+ fxtod v48, v48
+
+C Start real work. (We sneakingly read f3 and f5 above...)
+C The software pipeline is very deep, requiring 4 feed-in stages.
+
+ fxtod %f2, u00
+ fxtod %f4, u32
+ fmuld u00, v00, a00
+ fmuld u00, v16, a16
+ fmuld u00, v32, p32
+ fmuld u32, v00, r32
+ fmuld u00, v48, p48
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .L_two_or_more
+ fmuld u32, v16, r48
+
+.L_one:
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ fdtox a00, a00
+ faddd p48, r48, a48
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ fdtox a32, a32
+ fdtox a48, a48
+ std a00, [%sp+2223+0]
+ std a16, [%sp+2223+8]
+ std a32, [%sp+2223+16]
+ std a48, [%sp+2223+24]
+ add %i2, 8, %i2
+
+ fdtox r64, a00
+ fdtox r80, a16
+ ldx [%sp+2223+0], i00
+ ldx [%sp+2223+8], i16
+ ldx [%sp+2223+16], i32
+ ldx [%sp+2223+24], i48
+ std a00, [%sp+2223+0]
+ std a16, [%sp+2223+8]
+ add %i2, 8, %i2
+
+ mov i00, %g5 C i00+ now in g5
+ ldx [%sp+2223+0], i00
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ mov i32, %g4 C i32+ now in g4
+ sllx i48, 32, %l6 C (i48 << 32)
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ add %l6, %o2, %o2 C mi64- in %o2
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ b .L_out_1
+ add %i2, 8, %i2
+
+.L_two_or_more:
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fdtox a00, a00
+ faddd p48, r48, a48
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ fdtox a32, a32
+ fxtod %f2, u00
+ fxtod %f4, u32
+ fdtox a48, a48
+ std a00, [%sp+2223+0]
+ fmuld u00, v00, p00
+ std a16, [%sp+2223+8]
+ fmuld u00, v16, p16
+ std a32, [%sp+2223+16]
+ fmuld u00, v32, p32
+ std a48, [%sp+2223+24]
+ faddd p00, r64, a00
+ fmuld u32, v00, r32
+ faddd p16, r80, a16
+ fmuld u00, v48, p48
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .L_three_or_more
+ fmuld u32, v16, r48
+
+.L_two:
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ fdtox a00, a00
+ faddd p48, r48, a48
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ ldx [%sp+2223+8], i16
+ ldx [%sp+2223+16], i32
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ std a00, [%sp+2223+0]
+ std a16, [%sp+2223+8]
+ std a32, [%sp+2223+16]
+ std a48, [%sp+2223+24]
+ add %i2, 8, %i2
+
+ fdtox r64, a00
+ mov i00, %g5 C i00+ now in g5
+ fdtox r80, a16
+ ldx [%sp+2223+0], i00
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ mov i32, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ sllx i48, 32, %l6 C (i48 << 32)
+ ldx [%sp+2223+24], i48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ add %l6, %o2, %o2 C mi64- in %o2
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ b .L_out_2
+ add %i2, 8, %i2
+
+.L_three_or_more:
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fdtox a00, a00
+ faddd p48, r48, a48
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ ldx [%sp+2223+8], i16
+ fxtod %f2, u00
+ ldx [%sp+2223+16], i32
+ fxtod %f4, u32
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ std a00, [%sp+2223+0]
+ fmuld u00, v00, p00
+ std a16, [%sp+2223+8]
+ fmuld u00, v16, p16
+ std a32, [%sp+2223+16]
+ fmuld u00, v32, p32
+ std a48, [%sp+2223+24]
+ faddd p00, r64, a00
+ fmuld u32, v00, r32
+ faddd p16, r80, a16
+ fmuld u00, v48, p48
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .L_four_or_more
+ fmuld u32, v16, r48
+
+.L_three:
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ fdtox a00, a00
+ faddd p48, r48, a48
+ mov i00, %g5 C i00+ now in g5
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ mov i32, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ sllx i48, 32, %l6 C (i48 << 32)
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ std a32, [%sp+2223+16]
+ add %l6, %o2, %o2 C mi64- in %o2
+ std a48, [%sp+2223+24]
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ b .L_out_3
+ add %i2, 8, %i2
+
+.L_four_or_more:
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fdtox a00, a00
+ faddd p48, r48, a48
+ mov i00, %g5 C i00+ now in g5
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ fxtod %f2, u00
+ srlx i48, 16, %l5 C (i48 >> 16)
+ mov i32, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ fxtod %f4, u32
+ sllx i48, 32, %l6 C (i48 << 32)
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ fmuld u00, v00, p00
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ fmuld u00, v16, p16
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ std a32, [%sp+2223+16]
+ fmuld u00, v32, p32
+ add %l6, %o2, %o2 C mi64- in %o2
+ std a48, [%sp+2223+24]
+ faddd p00, r64, a00
+ fmuld u32, v00, r32
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ faddd p16, r80, a16
+ fmuld u00, v48, p48
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .Loop
+ fmuld u32, v16, r48
+
+.L_four:
+ b,a .L_out_4
+
+C BEGIN MAIN LOOP
+ .align 16
+.Loop:
+C 00
+ srlx %o4, 16, %o5 C (x >> 16)
+ ld [%i5+%i2], %f3 C read low 32 bits of up[i]
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+C 01
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ ld [%i1+%i2], %f5 C read high 32 bits of up[i]
+ fdtox a00, a00
+C 02
+ faddd p48, r48, a48
+C 03
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ mov i00, %g5 C i00+ now in g5
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+C 04
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+C 05
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ fxtod %f2, u00
+C 06
+ srlx i48, 16, %l5 C (i48 >> 16)
+ mov i32, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ fxtod %f4, u32
+C 07
+ sllx i48, 32, %l6 C (i48 << 32)
+ or %i3, %o5, %o5
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+C 08
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ fmuld u00, v00, p00
+C 09
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ fmuld u00, v16, p16
+C 10
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ std a32, [%sp+2223+16]
+ fmuld u00, v32, p32
+C 11
+ add %l6, %o2, %o2 C mi64- in %o2
+ std a48, [%sp+2223+24]
+ faddd p00, r64, a00
+ fmuld u32, v00, r32
+C 12
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ stx %o5, [%i4+%i2]
+ faddd p16, r80, a16
+ fmuld u00, v48, p48
+C 13
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ addcc %i2, 8, %i2
+ bnz,pt %xcc, .Loop
+ fmuld u32, v16, r48
+C END MAIN LOOP
+
+.L_out_4:
+ srlx %o4, 16, %o5 C (x >> 16)
+ fmuld u32, v32, r64 C FIXME not urgent
+ faddd p32, r32, a32
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ fdtox a00, a00
+ faddd p48, r48, a48
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ mov i00, %g5 C i00+ now in g5
+ fmuld u32, v48, r80 C FIXME not urgent
+ fdtox a16, a16
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ ldx [%sp+2223+0], i00
+ fdtox a32, a32
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ mov i32, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ sllx i48, 32, %l6 C (i48 << 32)
+ or %i3, %o5, %o5
+ ldx [%sp+2223+24], i48
+ fdtox a48, a48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ std a32, [%sp+2223+16]
+ add %l6, %o2, %o2 C mi64- in %o2
+ std a48, [%sp+2223+24]
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ stx %o5, [%i4+%i2]
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ add %i2, 8, %i2
+.L_out_3:
+ srlx %o4, 16, %o5 C (x >> 16)
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ fdtox r64, a00
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ mov i00, %g5 C i00+ now in g5
+ fdtox r80, a16
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ ldx [%sp+2223+0], i00
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ mov i32, %g4 C i32+ now in g4
+ ldx [%sp+2223+16], i32
+ sllx i48, 32, %l6 C (i48 << 32)
+ or %i3, %o5, %o5
+ ldx [%sp+2223+24], i48
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ std a00, [%sp+2223+0]
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ std a16, [%sp+2223+8]
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ add %l6, %o2, %o2 C mi64- in %o2
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ stx %o5, [%i4+%i2]
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ add %i2, 8, %i2
+.L_out_2:
+ srlx %o4, 16, %o5 C (x >> 16)
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ mov i00, %g5 C i00+ now in g5
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ ldx [%sp+2223+0], i00
+ srlx i16, 48, %l4 C (i16 >> 48)
+ mov i16, %g2
+ ldx [%sp+2223+8], i16
+ srlx i48, 16, %l5 C (i48 >> 16)
+ mov i32, %g4 C i32+ now in g4
+ sllx i48, 32, %l6 C (i48 << 32)
+ or %i3, %o5, %o5
+ srlx %g4, 32, %o3 C (i32 >> 32)
+ add %l5, %l4, %o1 C hi64- in %o1
+ sllx %g4, 16, %o2 C (i32 << 16)
+ add %o3, %o1, %o1 C hi64 in %o1 1st ASSIGNMENT
+ sllx %o1, 48, %o3 C (hi64 << 48)
+ add %g2, %o2, %o2 C mi64- in %o2
+ add %l6, %o2, %o2 C mi64- in %o2
+ sub %o2, %o3, %o2 C mi64 in %o2 1st ASSIGNMENT
+ stx %o5, [%i4+%i2]
+ add cy, %g5, %o4 C x = prev(i00) + cy
+ add %i2, 8, %i2
+.L_out_1:
+ srlx %o4, 16, %o5 C (x >> 16)
+ add %o5, %o2, %o2 C mi64 in %o2 2nd ASSIGNMENT
+ and %o4, xffff, %o5 C (x & 0xffff)
+ srlx %o2, 48, %o7 C (mi64 >> 48)
+ sllx %o2, 16, %i3 C (mi64 << 16)
+ add %o7, %o1, cy C new cy
+ or %i3, %o5, %o5
+ stx %o5, [%i4+%i2]
+
+ sllx i00, 0, %g2
+ add %g2, cy, cy
+ sllx i16, 16, %g3
+ add %g3, cy, cy
+
+ return %i7+8
+ mov cy, %o0
+EPILOGUE(mpn_mul_1)
diff --git a/gmp/mpn/sparc64/ultrasparc1234/sqr_diagonal.asm b/gmp/mpn/sparc64/ultrasparc1234/sqr_diagonal.asm
new file mode 100644
index 0000000000..43c69d31d1
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparc1234/sqr_diagonal.asm
@@ -0,0 +1,342 @@
+dnl SPARC v9 64-bit mpn_sqr_diagonal.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 22
+C UltraSPARC 3: 36
+
+C This was generated by the Sun C compiler. It runs at 22 cycles/limb on the
+C UltraSPARC-1/2, three cycles slower than theoretically possible for optimal
+C code using the same algorithm. For 1-3 limbs, a special loop was generated,
+C which causes performance problems in particular for 2 and 3 limbs.
+C Ultimately, this should be replaced by hand-written code in the same software
+C pipeline style as e.g., addmul_1.asm.
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_sqr_diagonal)
+ save %sp, -240, %sp
+
+ sethi %hi(0x1ffc00), %o0
+ sethi %hi(0x3ffc00), %o1
+ add %o0, 1023, %o7
+ cmp %i2, 4
+ add %o1, 1023, %o4
+ or %g0, %i1, %g1
+ or %g0, %i0, %o0
+ bl,pn %xcc, .Lsmall
+ or %g0, 0, %g2
+
+ ldx [%i1], %o1
+ add %i1, 24, %g1
+ or %g0, 3, %g2
+ srlx %o1, 42, %g3
+ stx %g3, [%sp+2279]
+ and %o1, %o7, %o2
+ stx %o2, [%sp+2263]
+ srlx %o1, 21, %o1
+ ldd [%sp+2279], %f0
+ and %o1, %o7, %o1
+ stx %o1, [%sp+2271]
+ ldx [%i1+8], %o2
+ fxtod %f0, %f12
+ srlx %o2, 21, %o1
+ and %o2, %o7, %g3
+ ldd [%sp+2263], %f2
+ fmuld %f12, %f12, %f10
+ srlx %o2, 42, %o2
+ ldd [%sp+2271], %f0
+ and %o1, %o7, %o1
+ fxtod %f2, %f8
+ stx %o2, [%sp+2279]
+ stx %o1, [%sp+2271]
+ fxtod %f0, %f0
+ stx %g3, [%sp+2263]
+ fdtox %f10, %f14
+ fmuld %f12, %f8, %f6
+ ldx [%i1+16], %o2
+ std %f14, [%sp+2255]
+ fmuld %f0, %f0, %f2
+ fmuld %f8, %f8, %f10
+ srlx %o2, 42, %o1
+ faddd %f6, %f6, %f6
+ fmuld %f12, %f0, %f12
+ fmuld %f0, %f8, %f8
+ ldd [%sp+2279], %f0
+ ldd [%sp+2263], %f4
+ fdtox %f10, %f10
+ std %f10, [%sp+2239]
+ faddd %f2, %f6, %f6
+ ldd [%sp+2271], %f2
+ fdtox %f12, %f12
+ std %f12, [%sp+2247]
+ fdtox %f8, %f8
+ std %f8, [%sp+2231]
+ fdtox %f6, %f6
+ std %f6, [%sp+2223]
+
+.Loop: srlx %o2, 21, %g3
+ stx %o1, [%sp+2279]
+ add %g2, 1, %g2
+ and %g3, %o7, %o1
+ ldx [%sp+2255], %g4
+ cmp %g2, %i2
+ stx %o1, [%sp+2271]
+ add %g1, 8, %g1
+ add %o0, 16, %o0
+ ldx [%sp+2239], %o1
+ fxtod %f0, %f10
+ fxtod %f4, %f14
+ ldx [%sp+2231], %i0
+ ldx [%sp+2223], %g5
+ ldx [%sp+2247], %g3
+ and %o2, %o7, %o2
+ fxtod %f2, %f8
+ fmuld %f10, %f10, %f0
+ stx %o2, [%sp+2263]
+ fmuld %f10, %f14, %f6
+ ldx [%g1-8], %o2
+ fmuld %f10, %f8, %f12
+ fdtox %f0, %f2
+ ldd [%sp+2279], %f0
+ fmuld %f8, %f8, %f4
+ faddd %f6, %f6, %f6
+ fmuld %f14, %f14, %f10
+ std %f2, [%sp+2255]
+ sllx %g4, 20, %g4
+ ldd [%sp+2271], %f2
+ fmuld %f8, %f14, %f8
+ sllx %i0, 22, %i1
+ fdtox %f12, %f12
+ std %f12, [%sp+2247]
+ sllx %g5, 42, %i0
+ add %o1, %i1, %o1
+ faddd %f4, %f6, %f6
+ ldd [%sp+2263], %f4
+ add %o1, %i0, %o1
+ add %g3, %g4, %g3
+ fdtox %f10, %f10
+ std %f10, [%sp+2239]
+ srlx %o1, 42, %g4
+ and %g5, %o4, %i0
+ fdtox %f8, %f8
+ std %f8, [%sp+2231]
+ srlx %g5, 22, %g5
+ sub %g4, %i0, %g4
+ fdtox %f6, %f6
+ std %f6, [%sp+2223]
+ srlx %g4, 63, %g4
+ add %g3, %g5, %g3
+ add %g3, %g4, %g3
+ stx %o1, [%o0-16]
+ srlx %o2, 42, %o1
+ bl,pt %xcc, .Loop
+ stx %g3, [%o0-8]
+
+ stx %o1, [%sp+2279]
+ srlx %o2, 21, %o1
+ fxtod %f0, %f16
+ ldx [%sp+2223], %g3
+ fxtod %f4, %f6
+ and %o2, %o7, %o3
+ stx %o3, [%sp+2263]
+ fxtod %f2, %f4
+ and %o1, %o7, %o1
+ ldx [%sp+2231], %o2
+ sllx %g3, 42, %g4
+ fmuld %f16, %f16, %f14
+ stx %o1, [%sp+2271]
+ fmuld %f16, %f6, %f8
+ add %o0, 48, %o0
+ ldx [%sp+2239], %o1
+ sllx %o2, 22, %o2
+ fmuld %f4, %f4, %f10
+ ldx [%sp+2255], %o3
+ fdtox %f14, %f14
+ fmuld %f4, %f6, %f2
+ std %f14, [%sp+2255]
+ faddd %f8, %f8, %f12
+ add %o1, %o2, %o2
+ fmuld %f16, %f4, %f4
+ ldd [%sp+2279], %f0
+ sllx %o3, 20, %g5
+ add %o2, %g4, %o2
+ fmuld %f6, %f6, %f6
+ srlx %o2, 42, %o3
+ and %g3, %o4, %g4
+ srlx %g3, 22, %g3
+ faddd %f10, %f12, %f16
+ ldd [%sp+2271], %f12
+ ldd [%sp+2263], %f8
+ fxtod %f0, %f0
+ sub %o3, %g4, %o3
+ ldx [%sp+2247], %o1
+ srlx %o3, 63, %o3
+ fdtox %f2, %f10
+ fxtod %f8, %f8
+ std %f10, [%sp+2231]
+ fdtox %f6, %f6
+ std %f6, [%sp+2239]
+ add %o1, %g5, %o1
+ fmuld %f0, %f0, %f2
+ fdtox %f16, %f16
+ std %f16, [%sp+2223]
+ add %o1, %g3, %o1
+ fdtox %f4, %f4
+ std %f4, [%sp+2247]
+ fmuld %f0, %f8, %f10
+ fxtod %f12, %f12
+ add %o1, %o3, %o1
+ stx %o2, [%o0-48]
+ fmuld %f8, %f8, %f6
+ stx %o1, [%o0-40]
+ fdtox %f2, %f2
+ ldx [%sp+2231], %o2
+ faddd %f10, %f10, %f10
+ ldx [%sp+2223], %g3
+ fmuld %f12, %f12, %f4
+ fdtox %f6, %f6
+ ldx [%sp+2239], %o1
+ sllx %o2, 22, %o2
+ fmuld %f12, %f8, %f8
+ sllx %g3, 42, %g5
+ ldx [%sp+2255], %o3
+ fmuld %f0, %f12, %f0
+ add %o1, %o2, %o2
+ faddd %f4, %f10, %f4
+ ldx [%sp+2247], %o1
+ add %o2, %g5, %o2
+ and %g3, %o4, %g4
+ fdtox %f8, %f8
+ sllx %o3, 20, %g5
+ std %f8, [%sp+2231]
+ fdtox %f0, %f0
+ srlx %o2, 42, %o3
+ add %o1, %g5, %o1
+ fdtox %f4, %f4
+ srlx %g3, 22, %g3
+ sub %o3, %g4, %o3
+ std %f6, [%sp+2239]
+ std %f4, [%sp+2223]
+ srlx %o3, 63, %o3
+ add %o1, %g3, %o1
+ std %f2, [%sp+2255]
+ add %o1, %o3, %o1
+ std %f0, [%sp+2247]
+ stx %o2, [%o0-32]
+ stx %o1, [%o0-24]
+ ldx [%sp+2231], %o2
+ ldx [%sp+2223], %o3
+ ldx [%sp+2239], %o1
+ sllx %o2, 22, %o2
+ sllx %o3, 42, %g5
+ ldx [%sp+2255], %g4
+ and %o3, %o4, %g3
+ add %o1, %o2, %o2
+ ldx [%sp+2247], %o1
+ add %o2, %g5, %o2
+ stx %o2, [%o0-16]
+ sllx %g4, 20, %g4
+ srlx %o2, 42, %o2
+ add %o1, %g4, %o1
+ srlx %o3, 22, %o3
+ sub %o2, %g3, %o2
+ srlx %o2, 63, %o2
+ add %o1, %o3, %o1
+ add %o1, %o2, %o1
+ stx %o1, [%o0-8]
+ ret
+ restore %g0, %g0, %g0
+.Lsmall:
+ ldx [%g1], %o2
+.Loop0:
+ and %o2, %o7, %o1
+ stx %o1, [%sp+2263]
+ add %g2, 1, %g2
+ srlx %o2, 21, %o1
+ add %g1, 8, %g1
+ srlx %o2, 42, %o2
+ stx %o2, [%sp+2279]
+ and %o1, %o7, %o1
+ ldd [%sp+2263], %f0
+ cmp %g2, %i2
+ stx %o1, [%sp+2271]
+ fxtod %f0, %f6
+ ldd [%sp+2279], %f0
+ ldd [%sp+2271], %f4
+ fxtod %f0, %f2
+ fmuld %f6, %f6, %f0
+ fxtod %f4, %f10
+ fmuld %f2, %f6, %f4
+ fdtox %f0, %f0
+ std %f0, [%sp+2239]
+ fmuld %f10, %f6, %f8
+ fmuld %f10, %f10, %f0
+ faddd %f4, %f4, %f6
+ fmuld %f2, %f2, %f4
+ fdtox %f8, %f8
+ std %f8, [%sp+2231]
+ fmuld %f2, %f10, %f2
+ faddd %f0, %f6, %f0
+ fdtox %f4, %f4
+ std %f4, [%sp+2255]
+ fdtox %f2, %f2
+ std %f2, [%sp+2247]
+ fdtox %f0, %f0
+ std %f0, [%sp+2223]
+ ldx [%sp+2239], %o1
+ ldx [%sp+2255], %g4
+ ldx [%sp+2231], %o2
+ sllx %g4, 20, %g4
+ ldx [%sp+2223], %o3
+ sllx %o2, 22, %o2
+ sllx %o3, 42, %g5
+ add %o1, %o2, %o2
+ ldx [%sp+2247], %o1
+ add %o2, %g5, %o2
+ stx %o2, [%o0]
+ and %o3, %o4, %g3
+ srlx %o2, 42, %o2
+ add %o1, %g4, %o1
+ srlx %o3, 22, %o3
+ sub %o2, %g3, %o2
+ srlx %o2, 63, %o2
+ add %o1, %o3, %o1
+ add %o1, %o2, %o1
+ stx %o1, [%o0+8]
+ add %o0, 16, %o0
+ bl,a,pt %xcc, .Loop0
+ ldx [%g1], %o2
+ ret
+ restore %g0, %g0, %g0
+EPILOGUE(mpn_sqr_diagonal)
diff --git a/gmp/mpn/sparc64/ultrasparc1234/sub_n.asm b/gmp/mpn/sparc64/ultrasparc1234/sub_n.asm
new file mode 100644
index 0000000000..9fb7f70747
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparc1234/sub_n.asm
@@ -0,0 +1,241 @@
+dnl SPARC v9 mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+dnl store difference in a third limb vector.
+
+dnl Copyright 2001-2003, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 4
+C UltraSPARC 3: 4.5
+
+C Compute carry-out from the most significant bits of u,v, and r, where
+C r=u-v-carry_in, using logic operations.
+
+C This code runs at 4 cycles/limb on UltraSPARC 1 and 2. It has a 4 insn
+C recurrency, and the UltraSPARC 1 and 2 the IE units are 100% saturated.
+C Therefore, it seems futile to try to optimize this any further...
+
+C INPUT PARAMETERS
+define(`rp',`%i0')
+define(`up',`%i1')
+define(`vp',`%i2')
+define(`n',`%i3')
+
+define(`u0',`%l0')
+define(`u1',`%l2')
+define(`u2',`%l4')
+define(`u3',`%l6')
+define(`v0',`%l1')
+define(`v1',`%l3')
+define(`v2',`%l5')
+define(`v3',`%l7')
+
+define(`cy',`%i4')
+
+define(`fanop',`fitod %f0,%f2') dnl A quasi nop running in the FA pipe
+define(`fmnop',`fmuld %f0,%f0,%f4') dnl A quasi nop running in the FM pipe
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_sub_nc)
+ save %sp,-160,%sp
+
+ fitod %f0,%f0 C make sure f0 contains small, quiet number
+ subcc n,4,%g0
+ bl,pn %xcc,.Loop0
+ nop
+ b,a L(com)
+EPILOGUE()
+
+PROLOGUE(mpn_sub_n)
+ save %sp,-160,%sp
+
+ fitod %f0,%f0 C make sure f0 contains small, quiet number
+ subcc n,4,%g0
+ bl,pn %xcc,.Loop0
+ mov 0,cy
+L(com):
+ ldx [up+0],u0
+ ldx [vp+0],v0
+ add up,32,up
+ ldx [up-24],u1
+ ldx [vp+8],v1
+ add vp,32,vp
+ ldx [up-16],u2
+ ldx [vp-16],v2
+ ldx [up-8],u3
+ ldx [vp-8],v3
+ subcc n,8,n
+ sub u0,v0,%g1 C main sub
+ sub %g1,cy,%g5 C carry sub
+ orn u0,v0,%g2
+ bl,pn %xcc,.Lend4567
+ fanop
+ b,a .Loop
+
+ .align 16
+C START MAIN LOOP
+.Loop: orn %g5,%g2,%g2
+ andn u0,v0,%g3
+ ldx [up+0],u0
+ fanop
+C --
+ andn %g2,%g3,%g2
+ ldx [vp+0],v0
+ add up,32,up
+ fanop
+C --
+ srlx %g2,63,cy
+ sub u1,v1,%g1
+ stx %g5,[rp+0]
+ fanop
+C --
+ sub %g1,cy,%g5
+ orn u1,v1,%g2
+ fmnop
+ fanop
+C --
+ orn %g5,%g2,%g2
+ andn u1,v1,%g3
+ ldx [up-24],u1
+ fanop
+C --
+ andn %g2,%g3,%g2
+ ldx [vp+8],v1
+ add vp,32,vp
+ fanop
+C --
+ srlx %g2,63,cy
+ sub u2,v2,%g1
+ stx %g5,[rp+8]
+ fanop
+C --
+ sub %g1,cy,%g5
+ orn u2,v2,%g2
+ fmnop
+ fanop
+C --
+ orn %g5,%g2,%g2
+ andn u2,v2,%g3
+ ldx [up-16],u2
+ fanop
+C --
+ andn %g2,%g3,%g2
+ ldx [vp-16],v2
+ add rp,32,rp
+ fanop
+C --
+ srlx %g2,63,cy
+ sub u3,v3,%g1
+ stx %g5,[rp-16]
+ fanop
+C --
+ sub %g1,cy,%g5
+ orn u3,v3,%g2
+ fmnop
+ fanop
+C --
+ orn %g5,%g2,%g2
+ andn u3,v3,%g3
+ ldx [up-8],u3
+ fanop
+C --
+ andn %g2,%g3,%g2
+ subcc n,4,n
+ ldx [vp-8],v3
+ fanop
+C --
+ srlx %g2,63,cy
+ sub u0,v0,%g1
+ stx %g5,[rp-8]
+ fanop
+C --
+ sub %g1,cy,%g5
+ orn u0,v0,%g2
+ bge,pt %xcc,.Loop
+ fanop
+C END MAIN LOOP
+.Lend4567:
+ orn %g5,%g2,%g2
+ andn u0,v0,%g3
+ andn %g2,%g3,%g2
+ srlx %g2,63,cy
+ sub u1,v1,%g1
+ stx %g5,[rp+0]
+ sub %g1,cy,%g5
+ orn u1,v1,%g2
+ orn %g5,%g2,%g2
+ andn u1,v1,%g3
+ andn %g2,%g3,%g2
+ srlx %g2,63,cy
+ sub u2,v2,%g1
+ stx %g5,[rp+8]
+ sub %g1,cy,%g5
+ orn u2,v2,%g2
+ orn %g5,%g2,%g2
+ andn u2,v2,%g3
+ andn %g2,%g3,%g2
+ add rp,32,rp
+ srlx %g2,63,cy
+ sub u3,v3,%g1
+ stx %g5,[rp-16]
+ sub %g1,cy,%g5
+ orn u3,v3,%g2
+ orn %g5,%g2,%g2
+ andn u3,v3,%g3
+ andn %g2,%g3,%g2
+ srlx %g2,63,cy
+ stx %g5,[rp-8]
+
+ addcc n,4,n
+ bz,pn %xcc,.Lret
+ fanop
+
+.Loop0: ldx [up],u0
+ add up,8,up
+ ldx [vp],v0
+ add vp,8,vp
+ add rp,8,rp
+ subcc n,1,n
+ sub u0,v0,%g1
+ orn u0,v0,%g2
+ sub %g1,cy,%g5
+ andn u0,v0,%g3
+ orn %g5,%g2,%g2
+ stx %g5,[rp-8]
+ andn %g2,%g3,%g2
+ bnz,pt %xcc,.Loop0
+ srlx %g2,63,cy
+
+.Lret: mov cy,%i0
+ ret
+ restore
+EPILOGUE(mpn_sub_n)
diff --git a/gmp/mpn/sparc64/ultrasparc1234/submul_1.asm b/gmp/mpn/sparc64/ultrasparc1234/submul_1.asm
new file mode 100644
index 0000000000..0bdb566b9f
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparc1234/submul_1.asm
@@ -0,0 +1,68 @@
+dnl SPARC v9 64-bit mpn_submul_1 -- Multiply a limb vector with a limb and
+dnl subtract the result from a second limb vector.
+
+dnl Copyright 2001-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC 1&2: 18
+C UltraSPARC 3: 23
+
+C INPUT PARAMETERS
+C rp i0
+C up i1
+C n i2
+C v i3
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+
+PROLOGUE(mpn_submul_1)
+ save %sp,-176,%sp
+
+ sllx %i2, 3, %g2
+ or %g0, %i1, %o1
+ add %g2, 15, %o0
+ or %g0, %i2, %o2
+ and %o0, -16, %o0
+ sub %sp, %o0, %sp
+ add %sp, 2223, %o0
+ or %g0, %o0, %l0
+ call mpn_mul_1
+ or %g0, %i3, %o3
+ or %g0, %o0, %l1 C preserve carry value from mpn_mul_1
+ or %g0, %i0, %o0
+ or %g0, %i0, %o1
+ or %g0, %l0, %o2
+ call mpn_sub_n
+ or %g0, %i2, %o3
+ ret
+ restore %l1, %o0, %o0 C sum carry values
+EPILOGUE(mpn_submul_1)
diff --git a/gmp/mpn/sparc64/ultrasparc34/gmp-mparam.h b/gmp/mpn/sparc64/ultrasparc34/gmp-mparam.h
new file mode 100644
index 0000000000..0c525bbdcf
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparc34/gmp-mparam.h
@@ -0,0 +1,219 @@
+/* ultrasparc3/4 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004, 2006, 2008-2010, 2014 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 1593 MHz ultrasparc3 running Solaris 10 (swift.nada.kth.se) */
+/* FFT tuning limit = 60000000 */
+/* Generated by tuneup.c, 2014-03-14, gcc 3.4 */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 20
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 25
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 2
+#define DIV_QR_1_UNNORM_THRESHOLD 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 28
+#define MUL_TOOM33_THRESHOLD 93
+#define MUL_TOOM44_THRESHOLD 139
+#define MUL_TOOM6H_THRESHOLD 165
+#define MUL_TOOM8H_THRESHOLD 278
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 93
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 104
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 85
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 51
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 67
+
+#define SQR_BASECASE_THRESHOLD 7
+#define SQR_TOOM2_THRESHOLD 71
+#define SQR_TOOM3_THRESHOLD 98
+#define SQR_TOOM4_THRESHOLD 175
+#define SQR_TOOM6_THRESHOLD 190
+#define SQR_TOOM8_THRESHOLD 339
+
+#define MULMID_TOOM42_THRESHOLD 40
+
+#define MULMOD_BNM1_THRESHOLD 15
+#define SQRMOD_BNM1_THRESHOLD 9
+
+#define MUL_FFT_MODF_THRESHOLD 220 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 220, 5}, { 13, 6}, { 17, 7}, { 9, 6}, \
+ { 19, 7}, { 17, 8}, { 9, 7}, { 20, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 9}, { 7, 8}, \
+ { 19, 9}, { 11, 8}, { 25,10}, { 7, 9}, \
+ { 15, 8}, { 33, 9}, { 19, 8}, { 39, 9}, \
+ { 23, 8}, { 47, 9}, { 27,10}, { 15, 9}, \
+ { 39,10}, { 23, 9}, { 47,11}, { 15,10}, \
+ { 31, 9}, { 63, 8}, { 127, 7}, { 255, 9}, \
+ { 67,10}, { 39, 9}, { 79, 8}, { 159, 9}, \
+ { 83,10}, { 47, 9}, { 95, 8}, { 191, 7}, \
+ { 383,10}, { 55,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255, 7}, { 511,10}, { 71, 9}, \
+ { 143, 8}, { 287, 7}, { 575,10}, { 79, 9}, \
+ { 159, 8}, { 319,11}, { 47,10}, { 95, 9}, \
+ { 191, 8}, { 383,10}, { 103, 9}, { 207, 8}, \
+ { 415,10}, { 111,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 143, 9}, { 287, 8}, \
+ { 575,11}, { 79,10}, { 175, 9}, { 351,11}, \
+ { 95,10}, { 191, 9}, { 383,10}, { 207, 9}, \
+ { 415,11}, { 111,10}, { 223,12}, { 63,11}, \
+ { 127,10}, { 255,11}, { 143,10}, { 287, 9}, \
+ { 575, 8}, { 1151,11}, { 159,10}, { 319, 9}, \
+ { 639,11}, { 175,10}, { 351, 9}, { 703,12}, \
+ { 95,11}, { 191,10}, { 383,11}, { 207,10}, \
+ { 415,11}, { 223,10}, { 447,13}, { 63,12}, \
+ { 127,11}, { 287,10}, { 575,12}, { 159,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 415,12}, \
+ { 223,11}, { 479,13}, { 127,12}, { 287,11}, \
+ { 575,12}, { 351,13}, { 191,12}, { 415,11}, \
+ { 831,12}, { 479,14}, { 127,13}, { 255,12}, \
+ { 575,13}, { 319,12}, { 703,11}, { 1407,13}, \
+ { 383,12}, { 831,13}, { 447,12}, { 895,14}, \
+ { 255,13}, { 511,12}, { 1023,13}, { 575,12}, \
+ { 1215,13}, { 703,14}, { 383,13}, { 831,12}, \
+ { 1663,13}, { 895,15}, { 255,14}, { 511,13}, \
+ { 1151,14}, { 639,13}, { 1407,14}, { 767,13}, \
+ { 1663,14}, { 895,13}, { 1791,15}, { 511,14}, \
+ { 1023,13}, { 2047,14}, { 1151,13}, { 2303,14}, \
+ { 1407,15}, { 767,14}, { 1791,16}, { 511,15}, \
+ { 1023,14}, { 2303,15}, { 1279,14}, { 2815,15}, \
+ { 1535,14}, { 3199,15}, { 1791,14}, { 3583,16}, \
+ { 65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+ {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 172
+#define MUL_FFT_THRESHOLD 2240
+
+#define SQR_FFT_MODF_THRESHOLD 244 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 244, 5}, { 8, 4}, { 17, 5}, { 15, 6}, \
+ { 8, 5}, { 17, 6}, { 17, 7}, { 9, 6}, \
+ { 19, 7}, { 10, 6}, { 21, 7}, { 17, 8}, \
+ { 9, 7}, { 20, 8}, { 11, 7}, { 23, 8}, \
+ { 21, 9}, { 11, 8}, { 25, 9}, { 15, 8}, \
+ { 31, 9}, { 19, 8}, { 39, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 47,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 63, 9}, { 127, 8}, { 255,10}, \
+ { 71, 9}, { 143, 8}, { 287, 7}, { 575,10}, \
+ { 79, 9}, { 159, 8}, { 319,11}, { 47, 9}, \
+ { 191, 8}, { 383, 7}, { 767, 9}, { 207,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511, 9}, { 271,10}, { 143, 9}, { 287, 8}, \
+ { 575,11}, { 79,10}, { 159, 9}, { 319, 8}, \
+ { 639,10}, { 175, 9}, { 351, 8}, { 703,10}, \
+ { 191, 9}, { 383, 8}, { 767,10}, { 207, 9}, \
+ { 415, 8}, { 831,10}, { 223, 9}, { 447, 8}, \
+ { 895,12}, { 63,11}, { 127,10}, { 271,11}, \
+ { 143,10}, { 287, 9}, { 575, 8}, { 1215,11}, \
+ { 159,10}, { 319, 9}, { 639,11}, { 175,10}, \
+ { 351, 9}, { 703,11}, { 191,10}, { 383,11}, \
+ { 207,10}, { 415, 9}, { 831, 8}, { 1663,10}, \
+ { 447,13}, { 63,12}, { 127,11}, { 271,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 575, 9}, \
+ { 1151,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 415,10}, \
+ { 831,12}, { 223,11}, { 447,13}, { 127,12}, \
+ { 255,11}, { 543,12}, { 287,11}, { 607,12}, \
+ { 319,11}, { 639,12}, { 351,11}, { 703,13}, \
+ { 191,12}, { 415,11}, { 831,12}, { 479,14}, \
+ { 127,13}, { 255,12}, { 607,13}, { 319,12}, \
+ { 703,11}, { 1407,13}, { 383,12}, { 831,13}, \
+ { 447,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1023,13}, { 575,12}, { 1151,13}, { 639,12}, \
+ { 1279,13}, { 703,14}, { 383,13}, { 831,12}, \
+ { 1663,13}, { 895,15}, { 255,14}, { 511,13}, \
+ { 1151,14}, { 639,13}, { 1407,14}, { 767,13}, \
+ { 1663,14}, { 895,13}, { 1791,15}, { 511,14}, \
+ { 1023,13}, { 2047,14}, { 1151,13}, { 2303,14}, \
+ { 1407,15}, { 767,14}, { 1791,16}, { 511,15}, \
+ { 1023,14}, { 2303,15}, { 1279,14}, { 2815,15}, \
+ { 1535,14}, { 3199,15}, { 1791,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 183
+#define SQR_FFT_THRESHOLD 1728
+
+#define MULLO_BASECASE_THRESHOLD 19
+#define MULLO_DC_THRESHOLD 0 /* never mpn_mullo_basecase */
+#define MULLO_MUL_N_THRESHOLD 4392
+
+#define DC_DIV_QR_THRESHOLD 15
+#define DC_DIVAPPR_Q_THRESHOLD 64
+#define DC_BDIV_QR_THRESHOLD 29
+#define DC_BDIV_Q_THRESHOLD 86
+
+#define INV_MULMOD_BNM1_THRESHOLD 54
+#define INV_NEWTON_THRESHOLD 17
+#define INV_APPR_THRESHOLD 17
+
+#define BINV_NEWTON_THRESHOLD 111
+#define REDC_1_TO_REDC_2_THRESHOLD 0 /* always */
+#define REDC_2_TO_REDC_N_THRESHOLD 115
+
+#define MU_DIV_QR_THRESHOLD 680
+#define MU_DIVAPPR_Q_THRESHOLD 618
+#define MUPI_DIV_QR_THRESHOLD 0 /* always */
+#define MU_BDIV_QR_THRESHOLD 680
+#define MU_BDIV_Q_THRESHOLD 807
+
+#define POWM_SEC_TABLE 1,16,102,386,1985,2079
+
+#define MATRIX22_STRASSEN_THRESHOLD 12
+#define HGCD_THRESHOLD 46
+#define HGCD_APPR_THRESHOLD 50
+#define HGCD_REDUCE_THRESHOLD 1012
+#define GCD_DC_THRESHOLD 124
+#define GCDEXT_DC_THRESHOLD 138
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 20
+#define GET_STR_PRECOMPUTE_THRESHOLD 28
+#define SET_STR_DC_THRESHOLD 324
+#define SET_STR_PRECOMPUTE_THRESHOLD 1043
+
+#define FAC_DSC_THRESHOLD 422
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/sparc64/ultrasparct1/add_n.asm b/gmp/mpn/sparc64/ultrasparct1/add_n.asm
new file mode 100644
index 0000000000..954c7f6d35
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/add_n.asm
@@ -0,0 +1,68 @@
+dnl SPARC v9 mpn_add_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T1: ?
+C UltraSPARC T2: ?
+
+C INPUT PARAMETERS
+define(`rp', `%o0')
+define(`up', `%o1')
+define(`vp', `%o2')
+define(`n', `%o3')
+define(`cy', `%o4')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_add_nc)
+ b,a L(ent)
+EPILOGUE()
+PROLOGUE(mpn_add_n)
+ mov 0, cy
+L(ent): cmp %g0, cy
+L(top): ldx [up+0], %o4
+ add up, 8, up
+ ldx [vp+0], %o5
+ add vp, 8, vp
+ add rp, 8, rp
+ add n, -1, n
+ srlx %o4, 32, %g1
+ srlx %o5, 32, %g2
+ addccc %o4, %o5, %g3
+ addccc %g1, %g2, %g0
+ brgz n, L(top)
+ stx %g3, [rp-8]
+
+ retl
+ addc %g0, %g0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct1/addlsh1_n.asm b/gmp/mpn/sparc64/ultrasparct1/addlsh1_n.asm
new file mode 100644
index 0000000000..313479773f
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/addlsh1_n.asm
@@ -0,0 +1,41 @@
+dnl SPARC v9 mpn_addlsh1_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 1)
+define(RSH, 63)
+
+define(func, mpn_addlsh1_n)
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n)
+
+include_mpn(`sparc64/ultrasparct1/addlshC_n.asm')
diff --git a/gmp/mpn/sparc64/ultrasparct1/addlsh2_n.asm b/gmp/mpn/sparc64/ultrasparct1/addlsh2_n.asm
new file mode 100644
index 0000000000..ee1afd0116
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/addlsh2_n.asm
@@ -0,0 +1,41 @@
+dnl SPARC v9 mpn_addlsh2_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 2)
+define(RSH, 62)
+
+define(func, mpn_addlsh2_n)
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n)
+
+include_mpn(`sparc64/ultrasparct1/addlshC_n.asm')
diff --git a/gmp/mpn/sparc64/ultrasparct1/addlshC_n.asm b/gmp/mpn/sparc64/ultrasparct1/addlshC_n.asm
new file mode 100644
index 0000000000..5be9a0d30a
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/addlshC_n.asm
@@ -0,0 +1,69 @@
+dnl SPARC v9 mpn_addlshC_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+C cycles/limb
+C UltraSPARC T1: 21
+C UltraSPARC T2: ?
+
+C INPUT PARAMETERS
+define(`rp', `%o0')
+define(`up', `%o1')
+define(`vp', `%o2')
+define(`n', `%o3')
+define(`cy', `%o4')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(func)
+ mov 0, cy
+ mov 0, %g5
+ cmp %g0, cy
+L(top): ldx [up+0], %o4
+ add up, 8, up
+ ldx [vp+0], %o5
+ add vp, 8, vp
+ add rp, 8, rp
+
+ sllx %o5, LSH, %g4
+ add n, -1, n
+ or %g5, %g4, %g4
+ srlx %o5, RSH, %g5
+
+ srlx %o4, 32, %g1
+ srlx %g4, 32, %g2
+ addccc %o4, %g4, %g3
+ addccc %g1, %g2, %g0
+ brgz n, L(top)
+ stx %g3, [rp-8]
+
+ retl
+ addc %g5, %g0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct1/addmul_1.asm b/gmp/mpn/sparc64/ultrasparct1/addmul_1.asm
new file mode 100644
index 0000000000..29dba966f3
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/addmul_1.asm
@@ -0,0 +1,86 @@
+dnl SPARC v9 mpn_addmul_1 for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T1: 74
+C UltraSPARC T2: ?
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`v0', `%i3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_addmul_1)
+ save %sp, -176, %sp
+ mov 1, %o2
+ mov %i0, %g2
+ srlx %i3, 32, %o4
+ sllx %o2, 32, %o2
+ srl %i3, 0, %i3
+ mov 0, %g3
+ mov 0, %i0
+
+L(top): ldx [%i1+%g3], %g1
+ srl %g1, 0, %g4
+ mulx %g4, %i3, %o5
+ srlx %g1, 32, %g1
+ mulx %g1, %i3, %g5
+ mulx %g4, %o4, %g4
+ mulx %g1, %o4, %g1
+ srlx %o5, 32, %o1
+ add %g5, %o1, %o1
+ addcc %o1, %g4, %g4
+ srl %o5, 0, %o0
+ ldx [%g2+%g3], %o5
+ sllx %g4, 32, %o1
+ add %g1, %o2, %l1
+ movlu %xcc, %l1, %g1
+ add %o1, %o0, %l0
+ addcc %l0, %i0, %g5
+ srlx %g4, 32, %i0
+ add %i0, 1, %g4
+ movlu %xcc, %g4, %i0
+ addcc %o5, %g5, %g5
+ stx %g5, [%g2+%g3]
+ add %i0, 1, %g4
+ movlu %xcc, %g4, %i0
+ add %i2, -1, %i2
+ add %i0, %g1, %i0
+ brnz,pt %i2, L(top)
+ add %g3, 8, %g3
+ return %i7+8
+ nop
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct1/gmp-mparam.h b/gmp/mpn/sparc64/ultrasparct1/gmp-mparam.h
new file mode 100644
index 0000000000..99db78ac0f
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/gmp-mparam.h
@@ -0,0 +1,154 @@
+/* Sparc64 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004, 2006, 2008-2010 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 1000 MHz ultrasparc t1 running GNU/Linux */
+
+#define DIVREM_1_NORM_THRESHOLD 0 /* always */
+#define DIVREM_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1_1P_METHOD 2
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 13
+#define MOD_1U_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 34
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 8
+#define MUL_TOOM33_THRESHOLD 50
+#define MUL_TOOM44_THRESHOLD 99
+#define MUL_TOOM6H_THRESHOLD 125
+#define MUL_TOOM8H_THRESHOLD 187
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 65
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 77
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 65
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 50
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 34
+
+#define SQR_BASECASE_THRESHOLD 0 /* always */
+#define SQR_TOOM2_THRESHOLD 14
+#define SQR_TOOM3_THRESHOLD 57
+#define SQR_TOOM4_THRESHOLD 133
+#define SQR_TOOM6_THRESHOLD 156
+#define SQR_TOOM8_THRESHOLD 260
+
+#define MULMID_TOOM42_THRESHOLD 12
+
+#define MULMOD_BNM1_THRESHOLD 7
+#define SQRMOD_BNM1_THRESHOLD 7
+
+#define MUL_FFT_MODF_THRESHOLD 176 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 176, 5}, { 7, 6}, { 4, 5}, { 9, 6}, \
+ { 5, 5}, { 11, 6}, { 11, 7}, { 6, 6}, \
+ { 13, 7}, { 7, 6}, { 15, 7}, { 9, 8}, \
+ { 5, 7}, { 13, 8}, { 7, 7}, { 15, 6}, \
+ { 32, 7}, { 24, 8}, { 21, 9}, { 11, 8}, \
+ { 23,10}, { 7, 9}, { 15, 8}, { 33, 9}, \
+ { 19, 8}, { 39, 9}, { 23,10}, { 15, 9}, \
+ { 43,10}, { 23,11}, { 15,10}, { 31, 9}, \
+ { 63, 8}, { 127, 9}, { 67,10}, { 39, 9}, \
+ { 79, 8}, { 159,10}, { 47, 9}, { 95,11}, \
+ { 2048,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 53
+#define MUL_FFT_THRESHOLD 1728
+
+
+#define SQR_FFT_MODF_THRESHOLD 148 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 148, 5}, { 7, 6}, { 4, 5}, { 9, 6}, \
+ { 5, 5}, { 11, 6}, { 11, 7}, { 6, 6}, \
+ { 13, 7}, { 7, 6}, { 15, 7}, { 13, 8}, \
+ { 7, 7}, { 16, 8}, { 9, 6}, { 38, 7}, \
+ { 20, 8}, { 11, 7}, { 24, 8}, { 13, 9}, \
+ { 7, 7}, { 30, 8}, { 19, 9}, { 11, 8}, \
+ { 25,10}, { 7, 9}, { 15, 8}, { 31, 9}, \
+ { 19, 8}, { 39, 9}, { 27,10}, { 15, 9}, \
+ { 39,10}, { 23, 9}, { 47, 8}, { 95, 9}, \
+ { 51,11}, { 15,10}, { 31, 8}, { 127,10}, \
+ { 39, 9}, { 79, 8}, { 159,10}, { 47, 9}, \
+ { 95,11}, { 2048,12}, { 4096,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 58
+#define SQR_FFT_THRESHOLD 1344
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 28
+#define MULLO_MUL_N_THRESHOLD 3176
+
+#define DC_DIV_QR_THRESHOLD 27
+#define DC_DIVAPPR_Q_THRESHOLD 106
+#define DC_BDIV_QR_THRESHOLD 27
+#define DC_BDIV_Q_THRESHOLD 62
+
+#define INV_MULMOD_BNM1_THRESHOLD 14
+#define INV_NEWTON_THRESHOLD 163
+#define INV_APPR_THRESHOLD 117
+
+#define BINV_NEWTON_THRESHOLD 166
+#define REDC_1_TO_REDC_N_THRESHOLD 31
+
+#define MU_DIV_QR_THRESHOLD 734
+#define MU_DIVAPPR_Q_THRESHOLD 748
+#define MUPI_DIV_QR_THRESHOLD 67
+#define MU_BDIV_QR_THRESHOLD 562
+#define MU_BDIV_Q_THRESHOLD 734
+
+#define POWM_SEC_TABLE 4,29,188,643,2741
+
+#define MATRIX22_STRASSEN_THRESHOLD 11
+#define HGCD_THRESHOLD 58
+#define HGCD_APPR_THRESHOLD 55
+#define HGCD_REDUCE_THRESHOLD 637
+#define GCD_DC_THRESHOLD 186
+#define GCDEXT_DC_THRESHOLD 140
+#define JACOBI_BASE_METHOD 3
+
+#define GET_STR_DC_THRESHOLD 20
+#define GET_STR_PRECOMPUTE_THRESHOLD 33
+#define SET_STR_DC_THRESHOLD 268
+#define SET_STR_PRECOMPUTE_THRESHOLD 960
+
+#define FAC_DSC_THRESHOLD 268
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/sparc64/ultrasparct1/mul_1.asm b/gmp/mpn/sparc64/ultrasparct1/mul_1.asm
new file mode 100644
index 0000000000..1fea2a19ef
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/mul_1.asm
@@ -0,0 +1,82 @@
+dnl SPARC v9 mpn_mul_1 for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T1: 68
+C UltraSPARC T2: ?
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`v0', `%i3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_mul_1)
+ save %sp, -176, %sp
+ mov 1, %o2
+ mov %i0, %g2
+ srlx %i3, 32, %o4
+ sllx %o2, 32, %o2
+ srl %i3, 0, %i3
+ mov 0, %g3
+ mov 0, %i0
+
+L(top): ldx [%i1+%g3], %g1
+ srl %g1, 0, %g4
+ mulx %g4, %i3, %o5
+ srlx %g1, 32, %g1
+ mulx %g1, %i3, %g5
+ mulx %g4, %o4, %g4
+ mulx %g1, %o4, %g1
+ srlx %o5, 32, %o1
+ add %g5, %o1, %o1
+ addcc %o1, %g4, %g4
+ srl %o5, 0, %o0
+ sllx %g4, 32, %o1
+ add %g1, %o2, %l1
+ movlu %xcc, %l1, %g1
+ add %o1, %o0, %l0
+ addcc %l0, %i0, %g5
+ srlx %g4, 32, %i0
+ add %i0, 1, %g4
+ movlu %xcc, %g4, %i0
+ stx %g5, [%g2+%g3]
+ add %i2, -1, %i2
+ add %i0, %g1, %i0
+ brnz,pt %i2, L(top)
+ add %g3, 8, %g3
+ return %i7+8
+ nop
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct1/rsblsh1_n.asm b/gmp/mpn/sparc64/ultrasparct1/rsblsh1_n.asm
new file mode 100644
index 0000000000..51bd4ab45b
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/rsblsh1_n.asm
@@ -0,0 +1,41 @@
+dnl SPARC v9 mpn_rsblsh1_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 1)
+define(RSH, 63)
+
+define(func, mpn_rsblsh1_n)
+
+MULFUNC_PROLOGUE(mpn_rsblsh1_n)
+
+include_mpn(`sparc64/ultrasparct1/rsblshC_n.asm')
diff --git a/gmp/mpn/sparc64/ultrasparct1/rsblsh2_n.asm b/gmp/mpn/sparc64/ultrasparct1/rsblsh2_n.asm
new file mode 100644
index 0000000000..f0d208e198
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/rsblsh2_n.asm
@@ -0,0 +1,41 @@
+dnl SPARC v9 mpn_rsblsh2_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 2)
+define(RSH, 62)
+
+define(func, mpn_rsblsh2_n)
+
+MULFUNC_PROLOGUE(mpn_rsblsh2_n)
+
+include_mpn(`sparc64/ultrasparct1/rsblshC_n.asm')
diff --git a/gmp/mpn/sparc64/ultrasparct1/rsblshC_n.asm b/gmp/mpn/sparc64/ultrasparct1/rsblshC_n.asm
new file mode 100644
index 0000000000..7c03e9f97f
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/rsblshC_n.asm
@@ -0,0 +1,69 @@
+dnl SPARC v9 mpn_rsblshC_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+C cycles/limb
+C UltraSPARC T1: 21
+C UltraSPARC T2: ?
+
+C INPUT PARAMETERS
+define(`rp', `%o0')
+define(`up', `%o1')
+define(`vp', `%o2')
+define(`n', `%o3')
+define(`cy', `%o4')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(func)
+ mov 0, cy
+ mov 0, %g5
+ cmp %g0, cy
+L(top): ldx [up+0], %o4
+ add up, 8, up
+ ldx [vp+0], %o5
+ add vp, 8, vp
+ add rp, 8, rp
+
+ sllx %o5, LSH, %g4
+ add n, -1, n
+ or %g5, %g4, %g4
+ srlx %o5, RSH, %g5
+
+ srlx %o4, 32, %g1
+ srlx %g4, 32, %g2
+ subccc %g4, %o4, %g3
+ subccc %g2, %g1, %g0
+ brgz n, L(top)
+ stx %g3, [rp-8]
+
+ retl
+ subc %g5, %g0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct1/sub_n.asm b/gmp/mpn/sparc64/ultrasparct1/sub_n.asm
new file mode 100644
index 0000000000..c2af89f08f
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/sub_n.asm
@@ -0,0 +1,68 @@
+dnl SPARC v9 mpn_sub_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T1: ?
+C UltraSPARC T2: ?
+
+C INPUT PARAMETERS
+define(`rp', `%o0')
+define(`up', `%o1')
+define(`vp', `%o2')
+define(`n', `%o3')
+define(`cy', `%o4')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_sub_nc)
+ b,a L(ent)
+EPILOGUE()
+PROLOGUE(mpn_sub_n)
+ mov 0, cy
+L(ent): cmp %g0, cy
+L(top): ldx [up+0], %o4
+ add up, 8, up
+ ldx [vp+0], %o5
+ add vp, 8, vp
+ add rp, 8, rp
+ add n, -1, n
+ srlx %o4, 32, %g1
+ srlx %o5, 32, %g2
+ subccc %o4, %o5, %g3
+ subccc %g1, %g2, %g0
+ brgz n, L(top)
+ stx %g3, [rp-8]
+
+ retl
+ addc %g0, %g0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct1/sublsh1_n.asm b/gmp/mpn/sparc64/ultrasparct1/sublsh1_n.asm
new file mode 100644
index 0000000000..8c8fa80401
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/sublsh1_n.asm
@@ -0,0 +1,41 @@
+dnl SPARC v9 mpn_sublsh1_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 1)
+define(RSH, 63)
+
+define(func, mpn_sublsh1_n)
+
+MULFUNC_PROLOGUE(mpn_sublsh1_n)
+
+include_mpn(`sparc64/ultrasparct1/sublshC_n.asm')
diff --git a/gmp/mpn/sparc64/ultrasparct1/sublsh2_n.asm b/gmp/mpn/sparc64/ultrasparct1/sublsh2_n.asm
new file mode 100644
index 0000000000..2fd5eee71a
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/sublsh2_n.asm
@@ -0,0 +1,41 @@
+dnl SPARC v9 mpn_sublsh2_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+define(LSH, 2)
+define(RSH, 62)
+
+define(func, mpn_sublsh2_n)
+
+MULFUNC_PROLOGUE(mpn_sublsh2_n)
+
+include_mpn(`sparc64/ultrasparct1/sublshC_n.asm')
diff --git a/gmp/mpn/sparc64/ultrasparct1/sublshC_n.asm b/gmp/mpn/sparc64/ultrasparct1/sublshC_n.asm
new file mode 100644
index 0000000000..01eafef1bc
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/sublshC_n.asm
@@ -0,0 +1,69 @@
+dnl SPARC v9 mpn_sublshC_n for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+C cycles/limb
+C UltraSPARC T1: 21
+C UltraSPARC T2: ?
+
+C INPUT PARAMETERS
+define(`rp', `%o0')
+define(`up', `%o1')
+define(`vp', `%o2')
+define(`n', `%o3')
+define(`cy', `%o4')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(func)
+ mov 0, cy
+ mov 0, %g5
+ cmp %g0, cy
+L(top): ldx [up+0], %o4
+ add up, 8, up
+ ldx [vp+0], %o5
+ add vp, 8, vp
+ add rp, 8, rp
+
+ sllx %o5, LSH, %g4
+ add n, -1, n
+ or %g5, %g4, %g4
+ srlx %o5, RSH, %g5
+
+ srlx %o4, 32, %g1
+ srlx %g4, 32, %g2
+ subccc %o4, %g4, %g3
+ subccc %g1, %g2, %g0
+ brgz n, L(top)
+ stx %g3, [rp-8]
+
+ retl
+ addc %g5, %g0, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct1/submul_1.asm b/gmp/mpn/sparc64/ultrasparct1/submul_1.asm
new file mode 100644
index 0000000000..4f553a8063
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct1/submul_1.asm
@@ -0,0 +1,86 @@
+dnl SPARC v9 mpn_submul_1 for T1/T2.
+
+dnl Copyright 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T1: 74
+C UltraSPARC T2: ?
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`v0', `%i3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_submul_1)
+ save %sp, -176, %sp
+ mov 1, %o2
+ mov %i0, %g2
+ srlx %i3, 32, %o4
+ sllx %o2, 32, %o2
+ srl %i3, 0, %i3
+ mov 0, %g3
+ mov 0, %i0
+
+L(top): ldx [%i1+%g3], %g1
+ srl %g1, 0, %g4
+ mulx %g4, %i3, %o5
+ srlx %g1, 32, %g1
+ mulx %g1, %i3, %g5
+ mulx %g4, %o4, %g4
+ mulx %g1, %o4, %g1
+ srlx %o5, 32, %o1
+ add %g5, %o1, %o1
+ addcc %o1, %g4, %g4
+ srl %o5, 0, %o0
+ ldx [%g2+%g3], %o5
+ sllx %g4, 32, %o1
+ add %g1, %o2, %l1
+ movlu %xcc, %l1, %g1
+ add %o1, %o0, %l0
+ addcc %l0, %i0, %g5
+ srlx %g4, 32, %i0
+ add %i0, 1, %g4
+ movlu %xcc, %g4, %i0
+ subcc %o5, %g5, %g5
+ stx %g5, [%g2+%g3]
+ add %i0, 1, %g4
+ movlu %xcc, %g4, %i0
+ add %i2, -1, %i2
+ add %i0, %g1, %i0
+ brnz,pt %i2, L(top)
+ add %g3, 8, %g3
+ return %i7+8
+ nop
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/add_n.asm b/gmp/mpn/sparc64/ultrasparct3/add_n.asm
new file mode 100644
index 0000000000..0170746895
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/add_n.asm
@@ -0,0 +1,126 @@
+dnl SPARC v9 mpn_add_n for T3/T4.
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 8
+C UltraSPARC T4: 3
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`vp', `%i2')
+define(`n', `%i3')
+define(`cy', `%i4')
+
+define(`u0_off', `%l2')
+define(`u1_off', `%l3')
+define(`loop_n', `%l6')
+define(`tmp', `%l7')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_add_nc)
+ save %sp, -176, %sp
+ b,a L(ent)
+EPILOGUE()
+PROLOGUE(mpn_add_n)
+ save %sp, -176, %sp
+
+ mov 0, cy
+L(ent):
+ subcc n, 1, n
+ be L(final_one)
+ cmp %g0, cy
+
+ ldx [up + 0], %o4
+ sllx n, 3, tmp
+
+ ldx [vp + 0], %o5
+ add up, tmp, u0_off
+
+ ldx [up + 8], %g5
+ neg tmp, loop_n
+
+ ldx [vp + 8], %g1
+ add u0_off, 8, u1_off
+
+ sub loop_n, -(2 * 8), loop_n
+
+ brgez,pn loop_n, L(loop_tail)
+ add vp, (2 * 8), vp
+
+ b,a L(top)
+ ALIGN(16)
+L(top):
+ addxccc(%o4, %o5, tmp)
+ ldx [vp + 0], %o5
+
+ add rp, (2 * 8), rp
+ ldx [loop_n + u0_off], %o4
+
+ add vp, (2 * 8), vp
+ stx tmp, [rp - 16]
+
+ addxccc(%g1, %g5, tmp)
+ ldx [vp - 8], %g1
+
+ ldx [loop_n + u1_off], %g5
+ sub loop_n, -(2 * 8), loop_n
+
+ brlz loop_n, L(top)
+ stx tmp, [rp - 8]
+
+L(loop_tail):
+ addxccc(%o4, %o5, %g3)
+ add loop_n, u0_off, up
+
+ addxccc(%g1, %g5, %g5)
+ stx %g3, [rp + 0]
+
+ brgz,pt loop_n, L(done)
+ stx %g5, [rp + 8]
+
+ add rp, (2 * 8), rp
+L(final_one):
+ ldx [up+0], %o4
+ ldx [vp+0], %o5
+ addxccc(%o4, %o5, %g3)
+ stx %g3, [rp+0]
+
+L(done):
+ addxc(%g0, %g0, %i0)
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/addmul_1.asm b/gmp/mpn/sparc64/ultrasparct3/addmul_1.asm
new file mode 100644
index 0000000000..939811e1ce
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/addmul_1.asm
@@ -0,0 +1,182 @@
+dnl SPARC v9 mpn_addmul_1 for T3/T4/T5.
+
+dnl Contributed to the GNU project by David Miller and Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 26
+C UltraSPARC T4: 4.5
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`v0', `%i3')
+
+define(`u0', `%l0')
+define(`u1', `%l1')
+define(`u2', `%l2')
+define(`u3', `%l3')
+define(`r0', `%l4')
+define(`r1', `%l5')
+define(`r2', `%l6')
+define(`r3', `%l7')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_addmul_1)
+ save %sp, -176, %sp
+ ldx [up+0], %g1
+
+ and n, 3, %g3
+ brz %g3, L(b0)
+ addcc %g0, %g0, %g5 C clear carry limb, flag
+ cmp %g3, 2
+ bcs %xcc, L(b01)
+ nop
+ be %xcc, L(b10)
+ ldx [up+8], %g5
+
+L(b11): ldx [up+16], u3
+ mulx %g1, v0, %o2
+ umulxhi(%g1, v0, %o3)
+ ldx [rp+0], r1
+ mulx %g5, v0, %o4
+ ldx [rp+8], r2
+ umulxhi(%g5, v0, %o5)
+ ldx [rp+16], r3
+ mulx u3, v0, %g4
+ umulxhi(u3, v0, %g5)
+ addcc %o3, %o4, %o4
+ addxccc(%o5, %g4, %g4)
+ addxc( %g0, %g5, %g5)
+ addcc r1, %o2, r1
+ stx r1, [rp+0]
+ addxccc(r2, %o4, r2)
+ stx r2, [rp+8]
+ addxccc(r3, %g4, r3)
+ stx r3, [rp+16]
+ add n, -3, n
+ add up, 24, up
+ brz n, L(xit)
+ add rp, 24, rp
+ b L(com)
+ nop
+
+L(b10): mulx %g1, v0, %o4
+ ldx [rp+0], r2
+ umulxhi(%g1, v0, %o5)
+ ldx [rp+8], r3
+ mulx %g5, v0, %g4
+ umulxhi(%g5, v0, %g5)
+ addcc %o5, %g4, %g4
+ addxc( %g0, %g5, %g5)
+ addcc r2, %o4, r2
+ stx r2, [rp+0]
+ addxccc(r3, %g4, r3)
+ stx r3, [rp+8]
+ add n, -2, n
+ add up, 16, up
+ brz n, L(xit)
+ add rp, 16, rp
+ b L(com)
+ nop
+
+L(b01): ldx [rp+0], r3
+ mulx %g1, v0, %g4
+ umulxhi(%g1, v0, %g5)
+ addcc r3, %g4, r3
+ stx r3, [rp+0]
+ add n, -1, n
+ add up, 8, up
+ brz n, L(xit)
+ add rp, 8, rp
+
+L(com): ldx [up+0], %g1
+L(b0): ldx [up+8], u1
+ ldx [up+16], u2
+ ldx [up+24], u3
+ mulx %g1, v0, %o0
+ umulxhi(%g1, v0, %o1)
+ b L(lo0)
+ nop
+
+ ALIGN(16)
+L(top): ldx [up+0], u0
+ addxc( %g0, %g5, %g5) C propagate carry into carry limb
+ ldx [up+8], u1
+ addcc r0, %o0, r0
+ ldx [up+16], u2
+ addxccc(r1, %o2, r1)
+ ldx [up+24], u3
+ addxccc(r2, %o4, r2)
+ stx r0, [rp-32]
+ addxccc(r3, %g4, r3)
+ stx r1, [rp-24]
+ mulx u0, v0, %o0
+ stx r2, [rp-16]
+ umulxhi(u0, v0, %o1)
+ stx r3, [rp-8]
+L(lo0): mulx u1, v0, %o2
+ ldx [rp+0], r0
+ umulxhi(u1, v0, %o3)
+ ldx [rp+8], r1
+ mulx u2, v0, %o4
+ ldx [rp+16], r2
+ umulxhi(u2, v0, %o5)
+ ldx [rp+24], r3
+ mulx u3, v0, %g4
+ addxccc(%g5, %o0, %o0)
+ umulxhi(u3, v0, %g5)
+ add up, 32, up
+ addxccc(%o1, %o2, %o2)
+ add rp, 32, rp
+ addxccc(%o3, %o4, %o4)
+ add n, -4, n
+ addxccc(%o5, %g4, %g4)
+ brgz n, L(top)
+ nop
+
+ addxc( %g0, %g5, %g5)
+ addcc r0, %o0, r0
+ stx r0, [rp-32]
+ addxccc(r1, %o2, r1)
+ stx r1, [rp-24]
+ addxccc(r2, %o4, r2)
+ stx r2, [rp-16]
+ addxccc(r3, %g4, r3)
+ stx r3, [rp-8]
+L(xit): addxc( %g0, %g5, %i0)
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/aormul_2.asm b/gmp/mpn/sparc64/ultrasparct3/aormul_2.asm
new file mode 100644
index 0000000000..ccc6a4408d
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/aormul_2.asm
@@ -0,0 +1,228 @@
+dnl SPARC v9 mpn_mul_2 and mpn_addmul_2 for T3/T4/T5.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb cycles/limb
+C mul_2 addmul_2
+C UltraSPARC T3: 22.5 23.5
+C UltraSPARC T4: 3.25 3.75
+
+
+C The code is reasonably scheduled but also relies on OoO. There was hope that
+C this could run at around 3.0 and 3.5 c/l respectively, on T4. Two cycles per
+C iteration needs to be removed.
+C
+C We could almost use 2-way unrolling, but currently the wN registers live too
+C long. By changing add x,w1,w1 to add x,w1,w0, i.e. migrate the values down-
+C wards, 2-way unrolling should become possible. With n-indexed addressing it
+C should run no slower.
+C
+C The rp loads to g1/g3 are very much over-scheduled. Presumably, they could
+C be postponed a full way, and then just one register could be used.
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`vp', `%i3')
+
+define(`v0', `%o0')
+define(`v1', `%o1')
+
+define(`w0', `%o2')
+define(`w1', `%o3')
+define(`w2', `%o4')
+define(`w3', `%o5')
+
+ifdef(`OPERATION_mul_2',`
+ define(`AM2', `')
+ define(`ADDX', `addcc`'$1')
+ define(`func', `mpn_mul_2')
+')
+ifdef(`OPERATION_addmul_2',`
+ define(`AM2', `$1')
+ define(`ADDX', `addxccc($1,$2,$3)')
+ define(`func', `mpn_addmul_2')
+')
+
+
+MULFUNC_PROLOGUE(mpn_mul_2 mpn_addmul_2)
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(func)
+ save %sp, -176, %sp
+
+ ldx [vp+0], v0 C load v0
+ and n, 3, %g5
+ ldx [vp+8], v1 C load v1
+ add n, -6, n
+ ldx [up+0], %g4
+ brz %g5, L(b0)
+ cmp %g5, 2
+ bcs L(b1)
+ nop
+ be L(b2)
+ nop
+
+L(b3):
+AM2(` ldx [rp+0], %g1')
+ mulx %g4, v0, w2
+ umulxhi(%g4, v0, w3)
+ ldx [up+8], %i5
+ mulx %g4, v1, %l3
+ umulxhi(%g4, v1, %l7)
+AM2(` ldx [rp+8], %g3')
+ add up, -8, up
+ add rp, -8, rp
+ b L(lo3)
+ mov 0, w0
+
+L(b2):
+AM2(` ldx [rp+0], %g3')
+ mulx %g4, v0, w3
+ umulxhi(%g4, v0, w0)
+ ldx [up+8], %i4
+ mulx %g4, v1, %l1
+ umulxhi(%g4, v1, %l5)
+AM2(` ldx [rp+8], %g1')
+ add rp, 16, rp
+ brlz n, L(end)
+ mov 0, w1
+ ba L(top)
+ add up, 16, up
+
+L(b1):
+AM2(` ldx [rp+0], %g1')
+ mulx %g4, v0, w0
+ umulxhi(%g4, v0, w1)
+ ldx [up+8], %i5
+ mulx %g4, v1, %l3
+ umulxhi(%g4, v1, %l7)
+AM2(` ldx [rp+8], %g3')
+ add up, 8, up
+ add rp, 8, rp
+ b L(lo1)
+ mov 0, w2
+
+L(b0):
+AM2(` ldx [rp+0], %g3')
+ mulx %g4, v0, w1
+ umulxhi(%g4, v0, w2)
+ ldx [up+8], %i4
+ mulx %g4, v1, %l1
+ umulxhi(%g4, v1, %l5)
+AM2(` ldx [rp+8], %g1')
+ b L(lo0)
+ mov 0, w3
+
+ ALIGN(16) C cycle
+L(top): mulx %i4, v0, %l2 C 0->5
+ umulxhi(%i4, v0, %l6) C 0->5
+ ldx [up+0], %i5 C 1->6
+AM2(` addcc w3, %g3, w3') C 1
+ stx w3, [rp-16] C 2
+ ADDX(` %l1, w0, w0') C 2
+ addxccc(%l5, w1, w1) C 3
+ mulx %i4, v1, %l3 C 3->9
+ umulxhi(%i4, v1, %l7) C 4->9
+AM2(` ldx [rp+0], %g3') C 4
+ addcc %l2, w0, w0 C 5
+ addxccc(%l6, w1, w1) C 5
+ addxc( %g0, %g0, w2) C 6
+L(lo1): mulx %i5, v0, %l0 C 6
+ umulxhi(%i5, v0, %l4) C 7
+ ldx [up+8], %i4 C 7
+AM2(` addcc w0, %g1, w0') C 8
+ stx w0, [rp-8] C 8
+ ADDX(` %l3, w1, w1') C 9
+ addxccc(%l7, w2, w2) C 9
+ mulx %i5, v1, %l1 C 10
+ umulxhi(%i5, v1, %l5) C 10
+AM2(` ldx [rp+8], %g1') C 11
+ addcc %l0, w1, w1 C 11
+ addxccc(%l4, w2, w2) C 12
+ addxc( %g0, %g0, w3) C 12
+L(lo0): mulx %i4, v0, %l2 C 13
+ umulxhi(%i4, v0, %l6) C 13
+ ldx [up+16], %i5 C 14
+AM2(` addcc w1, %g3, w1') C 14
+ stx w1, [rp+0] C 15
+ ADDX(` %l1, w2, w2') C 15
+ addxccc(%l5, w3, w3) C 16
+ mulx %i4, v1, %l3 C 16
+ umulxhi(%i4, v1, %l7) C 17
+AM2(` ldx [rp+16], %g3') C 17
+ addcc %l2, w2, w2 C 18
+ addxccc(%l6, w3, w3) C 18
+ addxc( %g0, %g0, w0) C 19
+L(lo3): mulx %i5, v0, %l0 C 19
+ umulxhi(%i5, v0, %l4) C 20
+ ldx [up+24], %i4 C 20
+AM2(` addcc w2, %g1, w2') C 21
+ stx w2, [rp+8] C 21
+ ADDX(` %l3, w3, w3') C 22
+ addxccc(%l7, w0, w0) C 22
+ mulx %i5, v1, %l1 C 23
+ umulxhi(%i5, v1, %l5) C 23
+AM2(` ldx [rp+24], %g1') C 24
+ addcc %l0, w3, w3 C 24
+ addxccc(%l4, w0, w0) C 25
+ addxc( %g0, %g0, w1) C 25
+ add up, 32, up
+ add rp, 32, rp
+ brgz n, L(top)
+ add n, -4, n
+
+L(end): mulx %i4, v0, %l2
+ umulxhi(%i4, v0, %l6)
+AM2(` addcc w3, %g3, w3')
+ stx w3, [rp-16]
+ ADDX(` %l1, w0, w0')
+ addxccc(%l5, w1, w1)
+ mulx %i4, v1, %l3
+ umulxhi(%i4, v1, %l7)
+ addcc %l2, w0, w0
+ addxccc(%l6, w1, w1)
+ addxc( %g0, %g0, w2)
+AM2(` addcc w0, %g1, w0')
+ stx w0, [rp-8]
+ ADDX(` %l3, w1, w1')
+ stx w1, [rp+0]
+ addxc(%l7, w2, %i0)
+
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/aormul_4.asm b/gmp/mpn/sparc64/ultrasparct3/aormul_4.asm
new file mode 100644
index 0000000000..845f6d6d69
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/aormul_4.asm
@@ -0,0 +1,219 @@
+dnl SPARC v9 mpn_mul_4 and mpn_addmul_4 for T3/T4/T5.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb cycles/limb
+C mul_4 addmul_4
+C UltraSPARC T3: 21.5 22.0
+C UltraSPARC T4: 2.625 2.75
+
+
+C The code is well-scheduled and relies on OoO very little. There is hope that
+C this will run at around 2.5 and 2.75 c/l respectively, on T4.
+
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`vp', `%i3')
+
+define(`v0', `%g1')
+define(`v1', `%o7')
+define(`v2', `%g2')
+define(`v3', `%i3')
+
+define(`w0', `%o0')
+define(`w1', `%o1')
+define(`w2', `%o2')
+define(`w3', `%o3')
+define(`w4', `%o4')
+
+define(`r0', `%o5')
+
+define(`u0', `%i4')
+define(`u1', `%i5')
+
+define(`rp0', `rp')
+define(`rp1', `%g3')
+define(`rp2', `%g4')
+define(`up0', `up')
+define(`up1', `%g5')
+
+ifdef(`OPERATION_mul_4',`
+ define(`AM4', `')
+ define(`ADDX', `addcc`'$1')
+ define(`func', `mpn_mul_4')
+')
+ifdef(`OPERATION_addmul_4',`
+ define(`AM4', `$1')
+ define(`ADDX', `addxccc($1,$2,$3)')
+ define(`func', `mpn_addmul_4')
+')
+
+
+MULFUNC_PROLOGUE(mpn_mul_4 mpn_addmul_4)
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(func)
+ save %sp, -176, %sp
+
+ ldx [up + 0], u1 C load up[0] early
+ andcc n, 1, %g0 C is n odd?
+ ldx [vp + 0], v0
+ sllx n, 3, n
+ ldx [vp + 8], v1
+ add n, -28, n
+ ldx [vp + 16], v2
+ add rp, -16, rp
+ ldx [vp + 24], v3
+ add up, n, up0
+ add rp, n, rp0
+ add up0, 8, up1
+ add rp0, 8, rp1
+ add rp0, 16, rp2
+ mulx u1, v0, %l0
+ mov 0, w0
+ mulx u1, v1, %l1
+ mov 0, w1
+ mulx u1, v2, %l2
+ mov 0, w2
+ mulx u1, v3, %l3
+ mov 0, w3
+
+ be L(evn)
+ neg n, n
+
+L(odd): mov u1, u0
+ ldx [up1 + n], u1
+AM4(` ldx [rp2 + n], r0')
+ umulxhi(u0, v0, %l4)
+ umulxhi(u0, v1, %l5)
+ umulxhi(u0, v2, %l6)
+ umulxhi(u0, v3, %l7)
+ b L(mid)
+ add n, 8, n
+
+L(evn): ldx [up1 + n], u0
+AM4(` ldx [rp2 + n], r0')
+ umulxhi(u1, v0, %l4)
+ umulxhi(u1, v1, %l5)
+ umulxhi(u1, v2, %l6)
+ umulxhi(u1, v3, %l7)
+ add n, 16, n
+
+ ALIGN(16)
+L(top): addcc %l0, w0, w0
+ mulx u0, v0, %l0 C w 0
+ addxccc(%l1, w1, w1)
+ mulx u0, v1, %l1 C w 1
+ addxccc(%l2, w2, w2)
+ mulx u0, v2, %l2 C w 2
+ addxccc(%l3, w3, w3)
+ mulx u0, v3, %l3 C w 3
+ ldx [up0 + n], u1
+ addxc( %g0, %g0, w4)
+AM4(` addcc r0, w0, w0')
+ stx w0, [rp0 + n]
+ ADDX(` %l4, w1, w0')
+ umulxhi(u0, v0, %l4) C w 1
+AM4(` ldx [rp1 + n], r0')
+ addxccc(%l5, w2, w1)
+ umulxhi(u0, v1, %l5) C w 2
+ addxccc(%l6, w3, w2)
+ umulxhi(u0, v2, %l6) C w 3
+ addxc( %l7, w4, w3)
+ umulxhi(u0, v3, %l7) C w 4
+L(mid): addcc %l0, w0, w0
+ mulx u1, v0, %l0 C w 1
+ addxccc(%l1, w1, w1)
+ mulx u1, v1, %l1 C w 2
+ addxccc(%l2, w2, w2)
+ mulx u1, v2, %l2 C w 3
+ addxccc(%l3, w3, w3)
+ mulx u1, v3, %l3 C w 4
+ ldx [up1 + n], u0
+ addxc( %g0, %g0, w4)
+AM4(` addcc r0, w0, w0')
+ stx w0, [rp1 + n]
+ ADDX(` %l4, w1, w0')
+ umulxhi(u1, v0, %l4) C w 2
+AM4(` ldx [rp2 + n], r0')
+ addxccc(%l5, w2, w1)
+ umulxhi(u1, v1, %l5) C w 3
+ addxccc(%l6, w3, w2)
+ umulxhi(u1, v2, %l6) C w 4
+ addxc( %l7, w4, w3)
+ umulxhi(u1, v3, %l7) C w 5
+ brlz n, L(top)
+ add n, 16, n
+
+L(end): addcc %l0, w0, w0
+ mulx u0, v0, %l0
+ addxccc(%l1, w1, w1)
+ mulx u0, v1, %l1
+ addxccc(%l2, w2, w2)
+ mulx u0, v2, %l2
+ addxccc(%l3, w3, w3)
+ mulx u0, v3, %l3
+ addxc( %g0, %g0, w4)
+AM4(` addcc r0, w0, w0')
+ stx w0, [rp0 + n]
+ ADDX(` %l4, w1, w0')
+ umulxhi(u0, v0, %l4)
+AM4(` ldx [rp1 + n], r0')
+ addxccc(%l5, w2, w1)
+ umulxhi(u0, v1, %l5)
+ addxccc(%l6, w3, w2)
+ umulxhi(u0, v2, %l6)
+ addxc( %l7, w4, w3)
+ umulxhi(u0, v3, %l7)
+ addcc %l0, w0, w0
+ addxccc(%l1, w1, w1)
+ addxccc(%l2, w2, w2)
+ addxccc(%l3, w3, w3)
+ addxc( %g0, %g0, w4)
+AM4(` addcc r0, w0, w0')
+ stx w0, [rp1 + n]
+ ADDX(` %l4, w1, w0')
+ addxccc(%l5, w2, w1)
+ addxccc(%l6, w3, w2)
+ stx w0, [rp2 + n]
+ add n, 16, n
+ stx w1, [rp1 + n]
+ stx w2, [rp2 + n]
+ addxc( %l7, w4, %i0)
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/aorslsh_n.asm b/gmp/mpn/sparc64/ultrasparct3/aorslsh_n.asm
new file mode 100644
index 0000000000..1014b1ba23
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/aorslsh_n.asm
@@ -0,0 +1,147 @@
+dnl SPARC v9 mpn_addlsh_n and mpn_sublsh_n for T3/T4/T5.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 11
+C UltraSPARC T4: 4
+
+C For sublsh_n we combine the two shifted limbs using xnor, using the identity
+C (a xor not b) = (not (a xor b)) which equals (not (a or b)) when (a and b) =
+C 0 as it is in our usage. This gives us the ones complement for free.
+C Unfortunately, the same trick will not work for rsblsh_n, which will instead
+C require a separate negation.
+C
+C FIXME: Add rsblsh_n to this file.
+
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`vp', `%i2')
+define(`n', `%i3')
+define(`cnt',`%i4')
+
+define(`tnc',`%o5')
+
+ifdef(`OPERATION_addlsh_n',`
+ define(`INITCY', `subcc %g0, 0, %g0')
+ define(`MERGE', `or')
+ define(`func', `mpn_addlsh_n')
+')
+ifdef(`OPERATION_sublsh_n',`
+ define(`INITCY', `subcc %g0, 1, %g0')
+ define(`MERGE', `xnor')
+ define(`func', `mpn_sublsh_n')
+')
+
+define(`rp0', `rp')
+define(`rp1', `%o2')
+define(`up0', `up')
+define(`up1', `%o3')
+define(`vp0', `vp')
+define(`vp1', `%o4')
+
+MULFUNC_PROLOGUE(mpn_addlsh_n mpn_sublsh_n)
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(func)
+ save %sp, -176, %sp
+ mov 64, tnc
+ sub tnc, cnt, tnc
+
+ andcc n, 1, %g0
+ sllx n, 3, n
+ add n, -16, n
+ add up, n, up0
+ add vp, n, vp0
+ add rp, n, rp0
+ add up0, 8, up1
+ add vp0, 8, vp1
+ add rp0, -8, rp1
+ add rp0, -16, rp0
+ neg n, n
+ be L(evn)
+ INITCY
+
+L(odd): ldx [vp0 + n], %l1
+ mov 0, %l2
+ ldx [up0 + n], %l5
+ sllx %l1, cnt, %g3
+ brgez n, L(wd1)
+ add n, 8, n
+ ldx [vp0 + n], %l0
+ b L(lo1)
+ sllx %l1, cnt, %g3
+
+L(evn): ldx [vp0 + n], %l0
+ mov 0, %l3
+ ldx [up0 + n], %l4
+ ldx [vp1 + n], %l1
+ b L(lo0)
+ sllx %l0, cnt, %g1
+
+L(top): addxccc(%l6, %l4, %o0)
+ ldx [vp0 + n], %l0
+ sllx %l1, cnt, %g3
+ stx %o0, [rp0 + n]
+L(lo1): srlx %l1, tnc, %l3
+ MERGE %l2, %g3, %l7
+ ldx [up0 + n], %l4
+ addxccc(%l7, %l5, %o1)
+ ldx [vp1 + n], %l1
+ sllx %l0, cnt, %g1
+ stx %o1, [rp1 + n]
+L(lo0): srlx %l0, tnc, %l2
+ MERGE %l3, %g1, %l6
+ ldx [up1 + n], %l5
+ brlz,pt n, L(top)
+ add n, 16, n
+
+ addxccc(%l6, %l4, %o0)
+ sllx %l1, cnt, %g3
+ stx %o0, [rp0 + n]
+L(wd1): srlx %l1, tnc, %l3
+ MERGE %l2, %g3, %l7
+ addxccc(%l7, %l5, %o1)
+ stx %o1, [rp1 + n]
+
+ifdef(`OPERATION_addlsh_n',
+` addxc( %l3, %g0, %i0)')
+ifdef(`OPERATION_sublsh_n',
+` addxc( %g0, %g0, %g1)
+ add %g1, -1, %g1
+ sub %l3, %g1, %i0')
+
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/bdiv_dbm1c.asm b/gmp/mpn/sparc64/ultrasparct3/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..550860d368
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/bdiv_dbm1c.asm
@@ -0,0 +1,147 @@
+dnl SPARC T3/T4/T5 mpn_bdiv_dbm1c.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 25
+C UltraSPARC T4/T5: 4
+
+C INPUT PARAMETERS
+define(`qp', `%i0')
+define(`ap', `%i1')
+define(`n', `%i2')
+define(`bd', `%i3')
+define(`h', `%i4')
+
+define(`plo0',`%g4') define(`plo1',`%g5')
+define(`phi0',`%l0') define(`phi1',`%l1')
+define(`a0', `%g1') define(`a1', `%g3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_bdiv_dbm1c)
+ save %sp, -176, %sp
+
+ and n, 3, %g5
+ ldx [ap + 0], %g2
+ add n, -5, n
+ brz %g5, L(b0)
+ cmp %g5, 2
+ bcs %xcc, L(b1)
+ nop
+ be %xcc, L(b2)
+ nop
+
+L(b3): ldx [ap + 8], a0
+ mulx bd, %g2, plo1
+ umulxhi(bd, %g2, phi1)
+ ldx [ap + 16], a1
+ add qp, -24, qp
+ b L(lo3)
+ add ap, -8, ap
+
+L(b2): ldx [ap + 8], a1
+ mulx bd, %g2, plo0
+ umulxhi(bd, %g2, phi0)
+ brlz,pt n, L(wd2)
+ nop
+L(gt2): ldx [ap + 16], a0
+ add ap, 16, ap
+ b L(lo2)
+ add n, -1, n
+
+L(b1): mulx bd, %g2, plo1
+ umulxhi(bd, %g2, phi1)
+ brlz,pn n, L(wd1)
+ add qp, -8, qp
+L(gt1): ldx [ap + 8], a0
+ ldx [ap + 16], a1
+ b L(lo1)
+ add ap, 8, ap
+
+L(b0): ldx [ap + 8], a1
+ mulx bd, %g2, plo0
+ umulxhi(bd, %g2, phi0)
+ ldx [ap + 16], a0
+ b L(lo0)
+ add qp, -16, qp
+
+L(top): ldx [ap + 0], a0
+ sub h, phi1, h
+L(lo2): mulx bd, a1, plo1
+ umulxhi(bd, a1, phi1)
+ subcc h, plo0, h
+ addxc( phi0, %g0, phi0)
+ stx h, [qp + 0]
+ ldx [ap + 8], a1
+ sub h, phi0, h
+L(lo1): mulx bd, a0, plo0
+ umulxhi(bd, a0, phi0)
+ subcc h, plo1, h
+ addxc( phi1, %g0, phi1)
+ stx h, [qp + 8]
+ ldx [ap + 16], a0
+ sub h, phi1, h
+L(lo0): mulx bd, a1, plo1
+ umulxhi(bd, a1, phi1)
+ subcc h, plo0, h
+ addxc( phi0, %g0, phi0)
+ stx h, [qp + 16]
+ ldx [ap + 24], a1
+ sub h, phi0, h
+L(lo3): mulx bd, a0, plo0
+ umulxhi(bd, a0, phi0)
+ subcc h, plo1, h
+ addxc( phi1, %g0, phi1)
+ stx h, [qp + 24]
+ add ap, 32, ap
+ add qp, 32, qp
+ brgz,pt n, L(top)
+ add n, -4, n
+
+L(end): sub h, phi1, h
+L(wd2): mulx bd, a1, plo1
+ umulxhi(bd, a1, phi1)
+ subcc h, plo0, h
+ addxc( phi0, %g0, phi0)
+ stx h, [qp + 0]
+ sub h, phi0, h
+L(wd1): subcc h, plo1, h
+ addxc( phi1, %g0, phi1)
+ stx h, [qp + 8]
+ sub h, phi1, %i0
+
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/cnd_aors_n.asm b/gmp/mpn/sparc64/ultrasparct3/cnd_aors_n.asm
new file mode 100644
index 0000000000..f10ee72c1f
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/cnd_aors_n.asm
@@ -0,0 +1,143 @@
+dnl SPARC v9 mpn_cnd_add_n and mpn_cnd_sub_n for T3/T4/T5.
+
+dnl Contributed to the GNU project by David Miller and Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 8.5
+C UltraSPARC T4: 3
+
+C We use a double-pointer trick to allow indexed addressing. Its setup
+C cost might be a problem in these functions, since we don't expect huge n
+C arguments.
+C
+C For sub we need ~(a & mask) = (~a | ~mask) but by complementing mask we can
+C instead do ~(a & ~mask) = (~a | mask), allowing us to use the orn insn.
+
+C INPUT PARAMETERS
+define(`cnd', `%i0')
+define(`rp', `%i1')
+define(`up', `%i2')
+define(`vp', `%i3')
+define(`n', `%i4')
+
+define(`mask', `cnd')
+define(`up0', `%l0') define(`up1', `%l1')
+define(`vp0', `%l2') define(`vp1', `%l3')
+define(`rp0', `%g4') define(`rp1', `%g5')
+define(`u0', `%l4') define(`u1', `%l5')
+define(`v0', `%l6') define(`v1', `%l7')
+define(`x0', `%g1') define(`x1', `%g3')
+define(`w0', `%g1') define(`w1', `%g3')
+
+ifdef(`OPERATION_cnd_add_n',`
+ define(`LOGOP', `and $1, $2, $3')
+ define(`MAKEMASK',`cmp %g0, $1
+ subc %g0, %g0, $2')
+ define(`INITCY', `addcc %g0, 0, %g0')
+ define(`RETVAL', `addxc( %g0, %g0, %i0)')
+ define(`func', `mpn_cnd_add_n')
+')
+ifdef(`OPERATION_cnd_sub_n',`
+ define(`LOGOP', `orn $2, $1, $3')
+ define(`MAKEMASK',`cmp $1, 1
+ subc %g0, %g0, $2')
+ define(`INITCY', `subcc %g0, 1, %g0')
+ define(`RETVAL', `addxc( %g0, %g0, %i0)
+ xor %i0, 1, %i0')
+ define(`func', `mpn_cnd_sub_n')
+')
+
+MULFUNC_PROLOGUE(mpn_cnd_add_n mpn_cnd_sub_n)
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(func)
+ save %sp, -176, %sp
+
+ MAKEMASK(cnd,mask)
+
+ andcc n, 1, %g0
+ sllx n, 3, n
+ add n, -16, n
+ add vp, n, vp0
+ add up, n, up0
+ add rp, n, rp0
+ neg n, n
+ be L(evn)
+ INITCY
+
+L(odd): ldx [vp0 + n], v1
+ ldx [up0 + n], u1
+ LOGOP( v1, mask, x1)
+ addxccc(u1, x1, w1)
+ stx w1, [rp0 + n]
+ add n, 8, n
+ brgz n, L(rtn)
+ nop
+
+L(evn): add vp0, 8, vp1
+ add up0, 8, up1
+ add rp0, -24, rp1
+ ldx [vp0 + n], v0
+ ldx [vp1 + n], v1
+ ldx [up0 + n], u0
+ ldx [up1 + n], u1
+ add n, 16, n
+ brgz n, L(end)
+ add rp0, -16, rp0
+
+L(top): LOGOP( v0, mask, x0)
+ ldx [vp0 + n], v0
+ LOGOP( v1, mask, x1)
+ ldx [vp1 + n], v1
+ addxccc(u0, x0, w0)
+ ldx [up0 + n], u0
+ addxccc(u1, x1, w1)
+ ldx [up1 + n], u1
+ stx w0, [rp0 + n]
+ add n, 16, n
+ brlez n, L(top)
+ stx w1, [rp1 + n]
+
+L(end): LOGOP( v0, mask, x0)
+ LOGOP( v1, mask, x1)
+ addxccc(u0, x0, w0)
+ addxccc(u1, x1, w1)
+ stx w0, [rp0 + n]
+ stx w1, [rp1 + 32]
+
+L(rtn): RETVAL
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/dive_1.asm b/gmp/mpn/sparc64/ultrasparct3/dive_1.asm
new file mode 100644
index 0000000000..d7dbdf953c
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/dive_1.asm
@@ -0,0 +1,129 @@
+dnl SPARC T3/T4/T5 mpn_divexact_1.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 31
+C UltraSPARC T4/T5: 20-26 hits 20 early, then sharply drops
+
+C INPUT PARAMETERS
+define(`qp', `%i0')
+define(`ap', `%i1')
+define(`n', `%i2')
+define(`d', `%i3')
+
+define(`dinv',`%o4')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_divexact_1)
+ save %sp, -176, %sp
+ cmp n, 1
+ bne,pt %xcc, L(gt1)
+ ldx [ap], %o5
+ udivx %o5, d, %g1
+ stx %g1, [qp]
+ return %i7+8
+ nop
+
+L(gt1): add d, -1, %g1
+ andn %g1, d, %g1
+ popc %g1, %i4 C i4 = count_trailing_zeros(d)
+
+ srlx d, %i4, d
+ srlx d, 1, %g1
+ and %g1, 127, %g1
+
+ LEA64(binvert_limb_table, g2, g4)
+ ldub [%g2+%g1], %g1
+ add %g1, %g1, %g2
+ mulx %g1, %g1, %g1
+ mulx %g1, d, %g1
+ sub %g2, %g1, %g2
+ add %g2, %g2, %g1
+ mulx %g2, %g2, %g2
+ mulx %g2, d, %g2
+ sub %g1, %g2, %g1
+ add %g1, %g1, %o7
+ mulx %g1, %g1, %g1
+ mulx %g1, d, %g1
+ add n, -2, n
+ brz,pt %i4, L(norm)
+ sub %o7, %g1, dinv
+
+L(unnorm):
+ mov 0, %g4
+ sub %g0, %i4, %o2
+ srlx %o5, %i4, %o5
+L(top_unnorm):
+ ldx [ap+8], %g3
+ add ap, 8, ap
+ sllx %g3, %o2, %g5
+ or %g5, %o5, %g5
+ srlx %g3, %i4, %o5
+ subcc %g5, %g4, %g4
+ mulx %g4, dinv, %g1
+ stx %g1, [qp]
+ add qp, 8, qp
+ umulxhi(d, %g1, %g1)
+ addxc( %g1, %g0, %g4)
+ brgz,pt n, L(top_unnorm)
+ add n, -1, n
+
+ sub %o5, %g4, %g4
+ mulx %g4, dinv, %g1
+ stx %g1, [qp]
+ return %i7+8
+ nop
+
+L(norm):
+ mulx dinv, %o5, %g1
+ stx %g1, [qp]
+ add qp, 8, qp
+ addcc %g0, 0, %g4
+L(top_norm):
+ umulxhi(d, %g1, %g1)
+ ldx [ap+8], %g5
+ add ap, 8, ap
+ addxc( %g1, %g0, %g1)
+ subcc %g5, %g1, %g1
+ mulx %g1, dinv, %g1
+ stx %g1, [qp]
+ add qp, 8, qp
+ brgz,pt n, L(top_norm)
+ add n, -1, n
+
+ return %i7+8
+ nop
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/hamdist.asm b/gmp/mpn/sparc64/ultrasparct3/hamdist.asm
new file mode 100644
index 0000000000..20ed8bf15b
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/hamdist.asm
@@ -0,0 +1,78 @@
+dnl SPARC v9 mpn_hamdist for T3/T4.
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 18
+C UltraSPARC T4: 3.5
+
+C INPUT PARAMETERS
+define(`up', `%o0')
+define(`vp', `%o1')
+define(`n', `%o2')
+define(`pcnt', `%o5')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_hamdist)
+ subcc n, 1, n
+ be L(final_one)
+ clr pcnt
+L(top):
+ ldx [up + 0], %g1
+ ldx [vp + 0], %g2
+ ldx [up + 8], %o4
+ ldx [vp + 8], %g3
+ sub n, 2, n
+ xor %g1, %g2, %g1
+ add up, 16, up
+ popc %g1, %g2
+ add vp, 16, vp
+ xor %o4, %g3, %o4
+ add pcnt, %g2, pcnt
+ popc %o4, %g3
+ brgz n, L(top)
+ add pcnt, %g3, pcnt
+ brlz,pt n, L(done)
+ nop
+L(final_one):
+ ldx [up + 0], %g1
+ ldx [vp + 0], %g2
+ xor %g1,%g2, %g1
+ popc %g1, %g2
+ add pcnt, %g2, pcnt
+L(done):
+ retl
+ mov pcnt, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/invert_limb.asm b/gmp/mpn/sparc64/ultrasparct3/invert_limb.asm
new file mode 100644
index 0000000000..4da49cf030
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/invert_limb.asm
@@ -0,0 +1,92 @@
+dnl SPARC T3/T4/T5 mpn_invert_limb.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: ?
+C UltraSPARC T4/T5: ?
+
+C INPUT PARAMETERS
+define(`d', `%o0')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_invert_limb)
+ srlx d, 54, %g1
+ LEA64(approx_tab, g2, g3)
+ and %g1, 0x1fe, %g1
+ srlx d, 24, %g4
+ lduh [%g2+%g1], %g3
+ add %g4, 1, %g4
+ sllx %g3, 11, %g2
+ add %g2, -1, %g2
+ mulx %g3, %g3, %g3
+ mulx %g3, %g4, %g3
+ srlx %g3, 40, %g3
+ sub %g2, %g3, %g2
+ sllx %g2, 60, %g1
+ mulx %g2, %g2, %g3
+ mulx %g3, %g4, %g4
+ sub %g1, %g4, %g1
+ srlx %g1, 47, %g1
+ sllx %g2, 13, %g2
+ add %g1, %g2, %g1
+ and d, 1, %g2
+ srlx %g1, 1, %g4
+ sub %g0, %g2, %g3
+ and %g4, %g3, %g3
+ srlx d, 1, %g4
+ add %g4, %g2, %g2
+ mulx %g1, %g2, %g2
+ sub %g3, %g2, %g2
+ umulxhi(%g1, %g2, %g2)
+ srlx %g2, 1, %g2
+ sllx %g1, 31, %g1
+ add %g2, %g1, %g1
+ mulx %g1, d, %g3
+ umulxhi(d, %g1, %g4)
+ addcc %g3, d, %g0
+ addxc( %g4, d, %o0)
+ jmp %o7+8
+ sub %g1, %o0, %o0
+EPILOGUE()
+
+ RODATA
+ ALIGN(2)
+ TYPE( approx_tab, object)
+ SIZE( approx_tab, 512)
+approx_tab:
+forloop(i,256,512-1,dnl
+` .half eval(0x7fd00/i)
+')dnl
diff --git a/gmp/mpn/sparc64/ultrasparct3/missing.asm b/gmp/mpn/sparc64/ultrasparct3/missing.asm
new file mode 100644
index 0000000000..c79032dd38
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/missing.asm
@@ -0,0 +1,77 @@
+dnl SPARC v9-2011 simulation support.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(__gmpn_umulh)
+ save %sp, -176, %sp
+ ldx [%sp+2047+176+256], %o0
+ ldx [%sp+2047+176+256+8], %o1
+ rd %ccr, %o4
+ srl %o0, 0, %l4
+ srl %o1, 0, %l1
+ srlx %o1, 32, %o1
+ mulx %o1, %l4, %l2
+ srlx %o0, 32, %o0
+ mulx %o0, %l1, %l3
+ mulx %l1, %l4, %l1
+ srlx %l1, 32, %l1
+ add %l2, %l1, %l2
+ addcc %l2, %l3, %l2
+ mulx %o1, %o0, %o1
+ mov 0, %l1
+ movcs %xcc, 1, %l1
+ sllx %l1, 32, %l1
+ add %o1, %l1, %o1
+ srlx %l2, 32, %o0
+ add %o1, %o0, %o0
+ stx %o0, [%sp+2047+176+256]
+ wr %o4, 0, %ccr
+ ret
+ restore
+EPILOGUE()
+
+PROLOGUE(__gmpn_lzcnt)
+ save %sp, -176, %sp
+ ldx [%sp+2047+176+256], %o0
+ brz,a %o0, 2f
+ mov 64, %o1
+ brlz %o0, 2f
+ mov 0, %o1
+1: sllx %o0, 1, %o0
+ brgz %o0, 1b
+ add %o1, 1, %o1
+ stx %o1, [%sp+2047+176+256]
+2: ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/missing.m4 b/gmp/mpn/sparc64/ultrasparct3/missing.m4
new file mode 100644
index 0000000000..e5d6d8e98e
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/missing.m4
@@ -0,0 +1,88 @@
+dnl SPARC v9-2011 simulation support.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Usage addxccc(r1,r2,r3, t1)
+dnl 64-bit add with carry-in and carry-out
+dnl FIXME: Register g2 must not be destination
+
+define(`addxccc',`dnl
+ add %sp, -512, %sp
+ stx %g2, [%sp+2047+256+16]
+ mov 0, %g2
+ movcs %xcc, -1, %g2
+ addcc %g2, 1, %g0
+ addccc $1, $2, $3
+ ldx [%sp+2047+256+16], %g2
+ sub %sp, -512, %sp
+')
+
+
+dnl Usage addxc(r1,r2,r3, t1,t2)
+dnl 64-bit add with carry-in
+
+define(`addxc',`dnl
+ bcc %xcc, 1f
+ add $1, $2, $3
+ add $3, 1, $3
+1:
+')
+
+
+dnl Usage umulxhi(r1,r2,r3)
+dnl 64-bit multiply returning upper 64 bits
+dnl Calls __gmpn_umulh using a non-standard calling convention
+
+define(`umulxhi',`dnl
+ add %sp, -512, %sp
+ stx $1, [%sp+2047+256]
+ stx $2, [%sp+2047+256+8]
+ stx %o7, [%sp+2047+256+16]
+ call __gmpn_umulh
+ nop
+ ldx [%sp+2047+256+16], %o7
+ ldx [%sp+2047+256], $3
+ sub %sp, -512, %sp
+')
+dnl Usage lzcnt(r1,r2)
+dnl Plain count leading zeros
+dnl Calls __gmpn_lzcnt using a non-standard calling convention
+
+define(`lzcnt',`dnl
+ add %sp, -512, %sp
+ stx %o7, [%sp+2047+256+16]
+ call __gmpn_lzcnt
+ stx $1, [%sp+2047+256]
+ ldx [%sp+2047+256+16], %o7
+ ldx [%sp+2047+256], $2
+ sub %sp, -512, %sp
+')
diff --git a/gmp/mpn/sparc64/ultrasparct3/mod_1_4.asm b/gmp/mpn/sparc64/ultrasparct3/mod_1_4.asm
new file mode 100644
index 0000000000..08facbd1cc
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/mod_1_4.asm
@@ -0,0 +1,233 @@
+dnl SPARC T3/T4/T5 mpn_mod_1s_4p.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 30
+C UltraSPARC T4/T5: 4
+
+C INPUT PARAMETERS
+define(`ap', `%o0')
+define(`n', `%o1')
+define(`d', `%o2')
+define(`cps', `%o3')
+
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_mod_1s_4p)
+ save %sp, -176, %sp
+ ldx [%i3+16], %o4
+ ldx [%i3+24], %o3
+ ldx [%i3+32], %o2
+ ldx [%i3+40], %o1
+ ldx [%i3+48], %o0
+
+ and %i1, 3, %g3
+ sllx %i1, 3, %g1
+ add %i0, %g1, %i0
+ brz %g3, L(b00)
+ cmp %g3, 2
+ bcs %xcc, L(b01)
+ nop
+ be %xcc, L(b10)
+ nop
+
+L(b11): ldx [%i0-16], %g2
+ mulx %g2, %o4, %g5
+ umulxhi(%g2, %o4, %g3)
+ ldx [%i0-24], %g4
+ addcc %g5, %g4, %g5
+ addxc( %g3, %g0, %g4)
+ ldx [%i0-8], %g2
+ mulx %g2, %o3, %g1
+ umulxhi(%g2, %o3, %g3)
+ addcc %g1, %g5, %g1
+ addxc( %g3, %g4, %g2)
+ ba,pt %xcc, .L8
+ add %i0, -32, %i0
+
+L(b00): ldx [%i0-24], %g3
+ mulx %g3, %o4, %g2
+ umulxhi(%g3, %o4, %g5)
+ ldx [%i0-32], %g4
+ addcc %g2, %g4, %g2
+ addxc( %g5, %g0, %g3)
+ ldx [%i0-16], %g4
+ mulx %g4, %o3, %g5
+ umulxhi(%g4, %o3, %i5)
+ addcc %g2, %g5, %g5
+ addxc( %g3, %i5, %g4)
+ ldx [%i0-8], %g2
+ mulx %g2, %o2, %g1
+ umulxhi(%g2, %o2, %g3)
+ addcc %g1, %g5, %g1
+ addxc( %g3, %g4, %g2)
+ ba,pt %xcc, .L8
+ add %i0, -40, %i0
+
+L(b01): ldx [%i0-8], %g1
+ mov 0, %g2
+ ba,pt %xcc, .L8
+ add %i0, -16, %i0
+
+L(b10): ldx [%i0-8], %g2
+ ldx [%i0-16], %g1
+ add %i0, -24, %i0
+
+.L8: add %i1, -5, %g3
+ brlz,pn %g3, L(end)
+ nop
+
+L(top): ldx [%i0-16], %i4
+ mulx %i4, %o4, %o5
+ umulxhi(%i4, %o4, %i1)
+ ldx [%i0-24], %i5
+ addcc %o5, %i5, %o5
+ addxc( %i1, %g0, %i4)
+ ldx [%i0-8], %i5
+ mulx %i5, %o3, %o7
+ umulxhi(%i5, %o3, %i1)
+ addcc %o5, %o7, %o7
+ addxc( %i4, %i1, %i5)
+ ldx [%i0+0], %g4
+ mulx %g4, %o2, %i1
+ umulxhi(%g4, %o2, %i4)
+ addcc %o7, %i1, %i1
+ addxc( %i5, %i4, %g4)
+ mulx %g1, %o1, %i5
+ umulxhi(%g1, %o1, %i4)
+ addcc %i1, %i5, %i5
+ addxc( %g4, %i4, %g5)
+ mulx %g2, %o0, %g1
+ umulxhi(%g2, %o0, %g4)
+ addcc %g1, %i5, %g1
+ addxc( %g4, %g5, %g2)
+ add %g3, -4, %g3
+ brgez,pt %g3, L(top)
+ add %i0, -32, %i0
+
+L(end): mulx %g2, %o4, %g5
+ umulxhi(%g2, %o4, %g3)
+ addcc %g1, %g5, %g5
+ addxc( %g3, %g0, %g2)
+ ldx [%i3+8], %i0
+ ldx [%i3], %g4
+ sub %g0, %i0, %i5
+ srlx %g5, %i5, %i5
+ sllx %g2, %i0, %g2
+ or %i5, %g2, %g1
+ mulx %g1, %g4, %l7
+ umulxhi(%g1, %g4, %g3)
+ sllx %g5, %i0, %g2
+ add %g1, 1, %g1
+ addcc %l7, %g2, %g5
+ addxc( %g3, %g1, %g1)
+ mulx %g1, %i2, %g1
+ sub %g2, %g1, %g2
+ cmp %g2, %g5
+ add %i2, %g2, %g1
+ movlu %xcc, %g2, %g1
+ subcc %g1, %i2, %g2
+ movgeu %xcc, %g2, %g1
+ return %i7+8
+ srlx %g1, %o0, %o0
+EPILOGUE()
+
+PROLOGUE(mpn_mod_1s_4p_cps)
+ save %sp, -176, %sp
+ lzcnt( %i1, %i5)
+ sllx %i1, %i5, %i1
+ call mpn_invert_limb, 0
+ mov %i1, %o0
+ stx %o0, [%i0]
+ sra %i5, 0, %g1
+ stx %g1, [%i0+8]
+ sub %g0, %i5, %g2
+ srlx %o0, %g2, %g2
+ mov 1, %g1
+ sllx %g1, %i5, %g1
+ or %g2, %g1, %g2
+ sub %g0, %i1, %g1
+ mulx %g2, %g1, %g2
+ srlx %g2, %i5, %g1
+ stx %g1, [%i0+16]
+
+ umulxhi(%o0, %g2, %g3)
+ add %g2, %g3, %g3
+ xnor %g0, %g3, %g3
+ mulx %g3, %i1, %g3
+ mulx %g2, %o0, %g2
+ cmp %g2, %g3
+ add %i1, %g3, %g1
+ movgeu %xcc, %g3, %g1
+ srlx %g1, %i5, %g2
+ stx %g2, [%i0+24]
+
+ umulxhi(%o0, %g1, %g3)
+ add %g1, %g3, %g3
+ xnor %g0, %g3, %g3
+ mulx %g3, %i1, %g3
+ mulx %g1, %o0, %g1
+ cmp %g1, %g3
+ add %i1, %g3, %g2
+ movgeu %xcc, %g3, %g2
+ srlx %g2, %i5, %g1
+ stx %g1, [%i0+32]
+
+ umulxhi(%o0, %g2, %g3)
+ add %g2, %g3, %g3
+ xnor %g0, %g3, %g3
+ mulx %g3, %i1, %g3
+ mulx %g2, %o0, %g2
+ cmp %g2, %g3
+ add %i1, %g3, %g1
+ movgeu %xcc, %g3, %g1
+ srlx %g1, %i5, %g2
+ stx %g2, [%i0+40]
+
+ umulxhi(%o0, %g1, %g2)
+ add %g1, %g2, %g2
+ xnor %g0, %g2, %g2
+ mulx %g2, %i1, %g2
+ mulx %g1, %o0, %o0
+ cmp %o0, %g2
+ add %i1, %g2, %g3
+ movgeu %xcc, %g2, %g3
+ srlx %g3, %i5, %i5
+ stx %i5, [%i0+48]
+
+ return %i7+8
+ nop
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/mod_34lsub1.asm b/gmp/mpn/sparc64/ultrasparct3/mod_34lsub1.asm
new file mode 100644
index 0000000000..874428069e
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/mod_34lsub1.asm
@@ -0,0 +1,117 @@
+dnl SPARC v9 mpn_mod_34lsub1 for T3/T4/T5.
+
+dnl Copyright 2005, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T1: -
+C UltraSPARC T3: 5
+C UltraSPARC T4: 1.57
+
+C This is based on the powerpc64/mode64 code.
+
+C INPUT PARAMETERS
+define(`up', `%i0')
+define(`n', `%i1')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_mod_34lsub1)
+ save %sp, -176, %sp
+
+ mov 0, %g1
+ mov 0, %g3
+ mov 0, %g4
+ addcc %g0, 0, %g5
+
+ add n, -3, n
+ brlz n, L(lt3)
+ nop
+
+ add n, -3, n
+ ldx [up+0], %l5
+ ldx [up+8], %l6
+ ldx [up+16], %l7
+ brlz n, L(end)
+ add up, 24, up
+
+ ALIGN(16)
+L(top): addxccc(%g1, %l5, %g1)
+ ldx [up+0], %l5
+ addxccc(%g3, %l6, %g3)
+ ldx [up+8], %l6
+ addxccc(%g4, %l7, %g4)
+ ldx [up+16], %l7
+ add n, -3, n
+ brgez n, L(top)
+ add up, 24, up
+
+L(end): addxccc( %g1, %l5, %g1)
+ addxccc(%g3, %l6, %g3)
+ addxccc(%g4, %l7, %g4)
+ addxc( %g5, %g0, %g5)
+
+L(lt3): cmp n, -2
+ blt L(2)
+ nop
+
+ ldx [up+0], %l5
+ mov 0, %l6
+ beq L(1)
+ addcc %g1, %l5, %g1
+
+ ldx [up+8], %l6
+L(1): addxccc(%g3, %l6, %g3)
+ addxccc(%g4, %g0, %g4)
+ addxc( %g5, %g0, %g5)
+
+L(2): sllx %g1, 16, %l0
+ srlx %l0, 16, %l0 C %l0 = %g1 mod 2^48
+ srlx %g1, 48, %l3 C %l3 = %g1 div 2^48
+ srl %g3, 0, %g1
+ sllx %g1, 16, %l4 C %l4 = (%g3 mod 2^32) << 16
+ srlx %g3, 32, %l5 C %l5 = %g3 div 2^32
+ sethi %hi(0xffff0000), %g1
+ andn %g4, %g1, %g1
+ sllx %g1, 32, %l6 C %l6 = (%g4 mod 2^16) << 32
+ srlx %g4, 16, %l7 C %l7 = %g4 div 2^16
+
+ add %l0, %l3, %l0
+ add %l4, %l5, %l4
+ add %l6, %l7, %l6
+
+ add %l0, %l4, %l0
+ add %l6, %g5, %l6
+
+ add %l0, %l6, %i0
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/mode1o.asm b/gmp/mpn/sparc64/ultrasparct3/mode1o.asm
new file mode 100644
index 0000000000..494e1d3f4f
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/mode1o.asm
@@ -0,0 +1,82 @@
+dnl SPARC T3/T4/T5 mpn_modexact_1c_odd.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 30
+C UltraSPARC T4/T5: 26
+
+C INPUT PARAMETERS
+define(`ap', `%o0')
+define(`n', `%o1')
+define(`d', `%o2')
+define(`cy', `%o3')
+
+define(`dinv',`%o5')
+define(`a0', `%g1')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_modexact_1c_odd)
+ srlx d, 1, %g1
+ and %g1, 127, %g1
+
+ LEA64(binvert_limb_table, g2, g4)
+ ldub [%g2+%g1], %g1
+ add %g1, %g1, %g2
+ mulx %g1, %g1, %g1
+ mulx %g1, d, %g1
+ sub %g2, %g1, %g2
+ add %g2, %g2, %g1
+ mulx %g2, %g2, %g2
+ mulx %g2, d, %g2
+ sub %g1, %g2, %g1
+ add %g1, %g1, %o5
+ mulx %g1, %g1, %g1
+ mulx %g1, d, %g1
+ sub %o5, %g1, dinv
+ add n, -1, n
+
+L(top): ldx [ap], a0
+ add ap, 8, ap
+ subcc a0, cy, %g3
+ mulx %g3, dinv, %g5
+ umulxhi(d, %g5, %g5)
+ addxc( %g5, %g0, cy)
+ brnz,pt n, L(top)
+ add n, -1, n
+
+ retl
+ mov cy, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/mul_1.asm b/gmp/mpn/sparc64/ultrasparct3/mul_1.asm
new file mode 100644
index 0000000000..af05d627bc
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/mul_1.asm
@@ -0,0 +1,174 @@
+dnl SPARC v9 mpn_mul_1 for T3/T4/T5.
+
+dnl Contributed to the GNU project by David Miller and Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 23
+C UltraSPARC T4: 3
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`v0', `%i3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_mul_1)
+ save %sp, -176, %sp
+
+ and n, 3, %g5
+ add n, -4, n
+ brz %g5, L(b0)
+ cmp %g5, 2
+ bcs %xcc, L(b1)
+ nop
+ be %xcc, L(b2)
+ nop
+
+L(b3): addcc %g0, %g0, %i5
+ ldx [up+0], %l0
+ ldx [up+8], %l1
+ ldx [up+16], %l2
+ mulx %l0, v0, %o0
+ umulxhi(%l0, v0, %o1)
+ brgz n, L(gt3)
+ add rp, -8, rp
+ mulx %l1, v0, %o2
+ umulxhi(%l1, v0, %o3)
+ b L(wd3)
+ nop
+L(gt3): ldx [up+24], %l3
+ mulx %l1, v0, %o2
+ umulxhi(%l1, v0, %o3)
+ add up, 24, up
+ b L(lo3)
+ add n, -3, n
+
+L(b2): addcc %g0, %g0, %o1
+ ldx [up+0], %l1
+ ldx [up+8], %l2
+ brgz n, L(gt2)
+ add rp, -16, rp
+ mulx %l1, v0, %o2
+ umulxhi(%l1, v0, %o3)
+ mulx %l2, v0, %o4
+ umulxhi(%l2, v0, %o5)
+ b L(wd2)
+ nop
+L(gt2): ldx [up+16], %l3
+ mulx %l1, v0, %o2
+ umulxhi(%l1, v0, %o3)
+ ldx [up+24], %l0
+ mulx %l2, v0, %o4
+ umulxhi(%l2, v0, %o5)
+ add up, 16, up
+ b L(lo2)
+ add n, -2, n
+
+L(b1): addcc %g0, %g0, %o3
+ ldx [up+0], %l2
+ brgz n, L(gt1)
+ nop
+ mulx %l2, v0, %o4
+ stx %o4, [rp+0]
+ umulxhi(%l2, v0, %i0)
+ ret
+ restore
+L(gt1): ldx [up+8], %l3
+ ldx [up+16], %l0
+ mulx %l2, v0, %o4
+ umulxhi(%l2, v0, %o5)
+ ldx [up+24], %l1
+ mulx %l3, v0, %i4
+ umulxhi(%l3, v0, %i5)
+ add rp, -24, rp
+ add up, 8, up
+ b L(lo1)
+ add n, -1, n
+
+L(b0): addcc %g0, %g0, %o5
+ ldx [up+0], %l3
+ ldx [up+8], %l0
+ ldx [up+16], %l1
+ mulx %l3, v0, %i4
+ umulxhi(%l3, v0, %i5)
+ ldx [up+24], %l2
+ mulx %l0, v0, %o0
+ umulxhi(%l0, v0, %o1)
+ b L(lo0)
+ nop
+
+ ALIGN(16)
+L(top): ldx [up+0], %l3 C 0
+ addxccc(%i4, %o5, %i4) C 0
+ mulx %l1, v0, %o2 C 1
+ stx %i4, [rp+0] C 1
+ umulxhi(%l1, v0, %o3) C 2
+L(lo3): ldx [up+8], %l0 C 2
+ addxccc(%o0, %i5, %o0) C 3
+ mulx %l2, v0, %o4 C 3
+ stx %o0, [rp+8] C 4
+ umulxhi(%l2, v0, %o5) C 4
+L(lo2): ldx [up+16], %l1 C 5
+ addxccc(%o2, %o1, %o2) C 5
+ mulx %l3, v0, %i4 C 6
+ stx %o2, [rp+16] C 6
+ umulxhi(%l3, v0, %i5) C 7
+L(lo1): ldx [up+24], %l2 C 7
+ addxccc(%o4, %o3, %o4) C 8
+ mulx %l0, v0, %o0 C 8
+ stx %o4, [rp+24] C 9
+ umulxhi(%l0, v0, %o1) C 9
+ add rp, 32, rp C 10
+L(lo0): add up, 32, up C 10
+ brgz n, L(top) C 11
+ add n, -4, n C 11
+
+L(end): addxccc(%i4, %o5, %i4)
+ mulx %l1, v0, %o2
+ stx %i4, [rp+0]
+ umulxhi(%l1, v0, %o3)
+ addxccc(%o0, %i5, %o0)
+L(wd3): mulx %l2, v0, %o4
+ stx %o0, [rp+8]
+ umulxhi(%l2, v0, %o5)
+ addxccc(%o2, %o1, %o2)
+L(wd2): stx %o2, [rp+16]
+ addxccc(%o4, %o3, %o4)
+ stx %o4, [rp+24]
+ addxc( %g0, %o5, %i0)
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/popcount.asm b/gmp/mpn/sparc64/ultrasparct3/popcount.asm
new file mode 100644
index 0000000000..de80f3c809
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/popcount.asm
@@ -0,0 +1,70 @@
+dnl SPARC v9 mpn_popcount for T3/T4.
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 15
+C UltraSPARC T4: 2.5
+
+C INPUT PARAMETERS
+define(`up', `%o0')
+define(`n', `%o1')
+define(`pcnt', `%o5')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_popcount)
+ subcc n, 1, n
+ be L(final_one)
+ clr pcnt
+L(top):
+ ldx [up + 0], %g1
+ sub n, 2, n
+ ldx [up + 8], %o4
+ add up, 16, up
+ popc %g1, %g2
+ popc %o4, %g3
+ add pcnt, %g2, pcnt
+ brgz n, L(top)
+ add pcnt, %g3, pcnt
+ brlz,pt n, L(done)
+ nop
+L(final_one):
+ ldx [up + 0], %g1
+ popc %g1, %g2
+ add pcnt, %g2, pcnt
+L(done):
+ retl
+ mov pcnt, %o0
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/sqr_diag_addlsh1.asm b/gmp/mpn/sparc64/ultrasparct3/sqr_diag_addlsh1.asm
new file mode 100644
index 0000000000..216ddc0ba1
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/sqr_diag_addlsh1.asm
@@ -0,0 +1,93 @@
+dnl SPARC v9 mpn_sqr_dial_addlsh1 for T3/T4/T5.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: ?
+C UltraSPARC T4: >= 4.5
+
+
+define(`rp', `%i0')
+define(`tp', `%i1')
+define(`up', `%i2')
+define(`n', `%i3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_sqr_diag_addlsh1)
+ save %sp, -176, %sp
+
+ ldx [up+0], %g1
+ mulx %g1, %g1, %o0
+ umulxhi(%g1, %g1, %g2)
+ stx %o0, [rp+0]
+
+ ldx [up+8], %g1
+ ldx [tp+0], %g4
+ ldx [tp+8], %g5
+ mulx %g1, %g1, %o0
+ orcc %g0, %g0, %o5
+ b L(dm)
+ add n, -2, n
+
+ ALIGN(16)
+L(top): ldx [up+8], %g1
+ addcc %g4, %o2, %o2
+ addxccc(%g5, %o0, %g3)
+ ldx [tp+16], %g4
+ ldx [tp+24], %g5
+ mulx %g1, %g1, %o0
+ stx %o2, [rp+8]
+ stx %g3, [rp+16]
+ add rp, 16, rp
+ add tp, 16, tp
+L(dm): add %g2, %o5, %o2
+ umulxhi(%g1, %g1, %g2)
+ addxccc(%g4, %g4, %g4)
+ addxccc(%g5, %g5, %g5)
+ add up, 8, up
+ addxc( %g0, %g0, %o5)
+ brnz n, L(top)
+ add n, -1, n
+
+ addcc %o2, %g4, %g4
+ addxccc(%o0, %g5, %g5)
+ stx %g4, [rp+8]
+ stx %g5, [rp+16]
+ addxc( %o5, %g2, %g2)
+ stx %g2, [rp+24]
+
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/sub_n.asm b/gmp/mpn/sparc64/ultrasparct3/sub_n.asm
new file mode 100644
index 0000000000..0e4bc939e3
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/sub_n.asm
@@ -0,0 +1,144 @@
+dnl SPARC v9 mpn_sub_n for T3/T4.
+
+dnl Contributed to the GNU project by David Miller.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 8
+C UltraSPARC T4: 3
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`vp', `%i2')
+define(`n', `%i3')
+define(`cy', `%i4')
+
+define(`u0_off', `%l0')
+define(`u1_off', `%l1')
+define(`v0_off', `%l2')
+define(`v1_off', `%l3')
+define(`r0_off', `%l4')
+define(`r1_off', `%l5')
+define(`loop_n', `%l6')
+define(`tmp', `%l7')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_sub_nc)
+ save %sp, -176, %sp
+ ba,pt %xcc, L(ent)
+ xor cy, 1, cy
+EPILOGUE()
+PROLOGUE(mpn_sub_n)
+ save %sp, -176, %sp
+ mov 1, cy
+L(ent):
+ subcc n, 1, n
+ be L(final_one)
+ cmp %g0, cy
+
+ ldx [up + 0], %o4
+ sllx n, 3, tmp
+
+ ldx [vp + 0], %o5
+ add up, tmp, u0_off
+
+ ldx [up + 8], %g5
+ add vp, tmp, v0_off
+
+ ldx [vp + 8], %g1
+ add rp, tmp, r0_off
+
+ neg tmp, loop_n
+ add u0_off, 8, u1_off
+
+ add v0_off, 8, v1_off
+ sub loop_n, -(2 * 8), loop_n
+
+ sub r0_off, 16, r0_off
+ brgez,pn loop_n, L(loop_tail)
+ sub r0_off, 8, r1_off
+
+ b,a L(top)
+ ALIGN(16)
+L(top):
+ xnor %o5, 0, tmp
+ ldx [loop_n + v0_off], %o5
+
+ addxccc(%o4, tmp, %g3)
+ ldx [loop_n + u0_off], %o4
+
+ xnor %g1, 0, %g1
+ stx %g3, [loop_n + r0_off]
+
+ addxccc(%g5, %g1, tmp)
+ ldx [loop_n + v1_off], %g1
+
+ ldx [loop_n + u1_off], %g5
+ sub loop_n, -(2 * 8), loop_n
+
+ brlz loop_n, L(top)
+ stx tmp, [loop_n + r1_off]
+
+L(loop_tail):
+ xnor %o5, 0, tmp
+ xnor %g1, 0, %g1
+
+ addxccc(%o4, tmp, %g3)
+ add loop_n, u0_off, up
+
+ addxccc(%g5, %g1, %g5)
+ add loop_n, r0_off, rp
+
+ stx %g3, [rp + 0]
+ add loop_n, v0_off, vp
+
+ brgz,pt loop_n, L(done)
+ stx %g5, [rp + 8]
+
+ add rp, (2 * 8), rp
+
+L(final_one):
+ ldx [up+0], %o4
+ ldx [vp+0], %o5
+ xnor %o5, %g0, %o5
+ addxccc(%o4, %o5, %g3)
+ stx %g3, [rp+0]
+
+L(done):
+ clr %i0
+ movcc %xcc, 1, %i0
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/sparc64/ultrasparct3/submul_1.asm b/gmp/mpn/sparc64/ultrasparct3/submul_1.asm
new file mode 100644
index 0000000000..5635d1bdbd
--- /dev/null
+++ b/gmp/mpn/sparc64/ultrasparct3/submul_1.asm
@@ -0,0 +1,170 @@
+dnl SPARC v9 mpn_submul_1 for T3/T4/T5.
+
+dnl Contributed to the GNU project by David Miller and Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C UltraSPARC T3: 26
+C UltraSPARC T4: 4.5
+
+C INPUT PARAMETERS
+define(`rp', `%i0')
+define(`up', `%i1')
+define(`n', `%i2')
+define(`v0', `%i3')
+
+ASM_START()
+ REGISTER(%g2,#scratch)
+ REGISTER(%g3,#scratch)
+PROLOGUE(mpn_submul_1)
+ save %sp, -176, %sp
+ ldx [up+0], %g1
+
+ and n, 3, %g5
+ add n, -4, n
+ brz %g5, L(b00)
+ cmp %g5, 2
+ bcs %xcc, L(b01)
+ nop
+ bne %xcc, L(b11)
+ ldx [up+8], %g4
+
+L(b10): add up, 16, up
+ addcc %g0, 0, %g3
+ mulx %g1, v0, %l4
+ umulxhi(%g1, v0, %l5)
+ ldx [rp+0], %o2
+ mulx %g4, v0, %l6
+ umulxhi(%g4, v0, %l7)
+ brlz n, L(wd2)
+ nop
+L(gt2): ldx [up+0], %o0
+ b L(lo2)
+ nop
+
+L(b00): add rp, -16, rp
+ addcc %g0, 0, %g3
+ ldx [up+8], %o1
+ mulx %g1, v0, %l0
+ umulxhi(%g1, v0, %l1)
+ ldx [up+16], %o0
+ ldx [rp+16], %o2
+ mulx %o1, v0, %l2
+ umulxhi(%o1, v0, %l3)
+ b L(lo0)
+ nop
+
+L(b01): add up, 8, up
+ add rp, -8, rp
+ addcc %g0, 0, %g3
+ ldx [rp+8], %o3
+ mulx %g1, v0, %l6
+ umulxhi(%g1, v0, %l7)
+ brlz n, L(wd1)
+ nop
+ ldx [up+0], %o0
+ ldx [up+8], %o1
+ mulx %o0, v0, %l0
+ umulxhi(%o0, v0, %l1)
+ b L(lo1)
+ nop
+
+L(b11): add up, 24, up
+ add rp, 8, rp
+ addcc %g0, 0, %g3
+ mulx %g1, v0, %l2
+ umulxhi(%g1, v0, %l3)
+ ldx [up-8], %o1
+ ldx [rp-8], %o3
+ mulx %g4, v0, %l4
+ umulxhi(%g4, v0, %l5)
+ brlz n, L(end)
+ nop
+
+ ALIGN(16)
+L(top): ldx [up+0], %o0
+ addxccc(%g3, %l2, %g1)
+ ldx [rp+0], %o2
+ addxc( %g0, %l3, %g3)
+ mulx %o1, v0, %l6
+ subcc %o3, %g1, %g4
+ umulxhi(%o1, v0, %l7)
+ stx %g4, [rp-8]
+L(lo2): ldx [up+8], %o1
+ addxccc(%g3, %l4, %g1)
+ ldx [rp+8], %o3
+ addxc( %g0, %l5, %g3)
+ mulx %o0, v0, %l0
+ subcc %o2, %g1, %g4
+ umulxhi(%o0, v0, %l1)
+ stx %g4, [rp+0]
+L(lo1): ldx [up+16], %o0
+ addxccc(%g3, %l6, %g1)
+ ldx [rp+16], %o2
+ addxc( %g0, %l7, %g3)
+ mulx %o1, v0, %l2
+ subcc %o3, %g1, %g4
+ umulxhi(%o1, v0, %l3)
+ stx %g4, [rp+8]
+L(lo0): ldx [up+24], %o1
+ addxccc(%g3, %l0, %g1)
+ ldx [rp+24], %o3
+ addxc( %g0, %l1, %g3)
+ mulx %o0, v0, %l4
+ subcc %o2, %g1, %g4
+ umulxhi(%o0, v0, %l5)
+ stx %g4, [rp+16]
+ add n, -4, n
+ add up, 32, up
+ brgez n, L(top)
+ add rp, 32, rp
+
+L(end): addxccc(%g3, %l2, %g1)
+ ldx [rp+0], %o2
+ addxc( %g0, %l3, %g3)
+ mulx %o1, v0, %l6
+ subcc %o3, %g1, %g4
+ umulxhi(%o1, v0, %l7)
+ stx %g4, [rp-8]
+L(wd2): addxccc(%g3, %l4, %g1)
+ ldx [rp+8], %o3
+ addxc( %g0, %l5, %g3)
+ subcc %o2, %g1, %g4
+ stx %g4, [rp+0]
+L(wd1): addxccc(%g3, %l6, %g1)
+ addxc( %g0, %l7, %g3)
+ subcc %o3, %g1, %g4
+ stx %g4, [rp+8]
+ addxc( %g0, %g3, %i0)
+ ret
+ restore
+EPILOGUE()
diff --git a/gmp/mpn/thumb/add_n.asm b/gmp/mpn/thumb/add_n.asm
new file mode 100644
index 0000000000..08ed60b9be
--- /dev/null
+++ b/gmp/mpn/thumb/add_n.asm
@@ -0,0 +1,63 @@
+dnl ARM/Thumb mpn_add_n.
+
+dnl Copyright 1997, 2000, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(`rp', r0)
+define(`up', r1)
+define(`vp', r2)
+define(`n', r3)
+
+ASM_START()
+ .thumb
+PROLOGUE(mpn_add_nc)
+ push {r4, r5, r6}
+ ldr r6, [sp, #12] C init carry save register
+ sub r6, #1
+ b L(top)
+EPILOGUE()
+PROLOGUE(mpn_add_n)
+ push {r4, r5, r6}
+ neg r6, n C init carry save register
+
+L(top): ldmia up!, {r4} C load next limb from S1
+ cmp n, r6 C tricky carry restore
+ ldmia vp!, {r5} C load next limb from S2
+ adc r4, r5
+ stmia rp!, {r4} C store result limb to RES
+ sbc r6, r6 C save negated carry
+ sub n, #1
+ bne L(top)
+
+ add r0, r6, #1
+ pop {r4, r5, r6}
+ bx lr
+EPILOGUE()
diff --git a/gmp/mpn/thumb/sub_n.asm b/gmp/mpn/thumb/sub_n.asm
new file mode 100644
index 0000000000..a38572048e
--- /dev/null
+++ b/gmp/mpn/thumb/sub_n.asm
@@ -0,0 +1,63 @@
+dnl ARM/Thumb mpn_sub_n.
+
+dnl Copyright 1997, 2000, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C INPUT PARAMETERS
+define(`rp', r0)
+define(`up', r1)
+define(`vp', r2)
+define(`n', r3)
+
+ASM_START()
+ .thumb
+PROLOGUE(mpn_sub_nc)
+ push {r4, r5, r6}
+ ldr r6, [sp, #12] C init carry save register
+ neg r6, r6
+ b L(top)
+EPILOGUE()
+PROLOGUE(mpn_sub_n)
+ push {r4, r5, r6}
+ mov r6, n C init carry save register
+
+L(top): ldmia up!, {r4} C load next limb from S1
+ cmp n, r6 C tricky carry restore
+ ldmia vp!, {r5} C load next limb from S2
+ sbc r4, r5
+ stmia rp!, {r4} C store result limb to RES
+ sbc r6, r6 C save negated carry
+ sub n, #1
+ bne L(top)
+
+ neg r0, r6
+ pop {r4, r5, r6}
+ bx lr
+EPILOGUE()
diff --git a/gmp/mpn/vax/add_n.asm b/gmp/mpn/vax/add_n.asm
new file mode 100644
index 0000000000..0a0bf78ab3
--- /dev/null
+++ b/gmp/mpn/vax/add_n.asm
@@ -0,0 +1,64 @@
+dnl VAX mpn_add_n -- Add two limb vectors of the same length > 0 and store sum
+dnl in a third limb vector.
+
+dnl Copyright 1999, 2000, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_add_n)
+ .word 0x0
+ movl 16(ap), r0
+ movl 12(ap), r1
+ movl 8(ap), r2
+ movl 4(ap), r3
+ mnegl r0, r5
+ addl2 $3, r0
+ ashl $-2, r0, r0 C unroll loop count
+ bicl2 $-4, r5 C mask out low 2 bits
+ movaq (r5)[r5], r5 C 9x
+ jmp L(top)[r5]
+
+L(top): movl (r2)+, r4
+ adwc (r1)+, r4
+ movl r4, (r3)+
+ movl (r2)+, r4
+ adwc (r1)+, r4
+ movl r4, (r3)+
+ movl (r2)+, r4
+ adwc (r1)+, r4
+ movl r4, (r3)+
+ movl (r2)+, r4
+ adwc (r1)+, r4
+ movl r4, (r3)+
+ sobgtr r0, L(top)
+
+ adwc r0, r0
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/vax/addmul_1.asm b/gmp/mpn/vax/addmul_1.asm
new file mode 100644
index 0000000000..8a6f636bdf
--- /dev/null
+++ b/gmp/mpn/vax/addmul_1.asm
@@ -0,0 +1,124 @@
+dnl VAX mpn_addmul_1 -- Multiply a limb vector with a limb and add the result
+dnl to a second limb vector.
+
+dnl Copyright 1992, 1994, 1996, 2000, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_addmul_1)
+ .word 0xfc0
+ movl 12(ap), r4
+ movl 8(ap), r8
+ movl 4(ap), r9
+ clrl r3
+ incl r4
+ ashl $-1, r4, r7
+ clrl r11
+ movl 16(ap), r6
+ jlss L(v0_big)
+ jlbc r4, L(1)
+
+C Loop for v0 < 0x80000000
+L(tp1): movl (r8)+, r1
+ jlss L(1n0)
+ emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc $0, r3
+ addl2 r2, (r9)+
+ adwc $0, r3
+L(1): movl (r8)+, r1
+ jlss L(1n1)
+L(1p1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc $0, r11
+ addl2 r10, (r9)+
+ adwc $0, r11
+
+ sobgtr r7, L(tp1)
+ movl r11, r0
+ ret
+
+L(1n0): emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc r6, r3
+ addl2 r2, (r9)+
+ adwc $0, r3
+ movl (r8)+, r1
+ jgeq L(1p1)
+L(1n1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc r6, r11
+ addl2 r10, (r9)+
+ adwc $0, r11
+
+ sobgtr r7, L(tp1)
+ movl r11, r0
+ ret
+
+L(v0_big):
+ jlbc r4, L(2)
+
+C Loop for v0 >= 0x80000000
+L(tp2): movl (r8)+, r1
+ jlss L(2n0)
+ emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc r1, r3
+ addl2 r2, (r9)+
+ adwc $0, r3
+L(2): movl (r8)+, r1
+ jlss L(2n1)
+L(2p1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc r1, r11
+ addl2 r10, (r9)+
+ adwc $0, r11
+
+ sobgtr r7, L(tp2)
+ movl r11, r0
+ ret
+
+L(2n0): emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc r6, r3
+ addl2 r2, (r9)+
+ adwc r1, r3
+ movl (r8)+, r1
+ jgeq L(2p1)
+L(2n1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc r6, r11
+ addl2 r10, (r9)+
+ adwc r1, r11
+
+ sobgtr r7, L(tp2)
+ movl r11, r0
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/vax/elf.m4 b/gmp/mpn/vax/elf.m4
new file mode 100644
index 0000000000..e04f0bafc9
--- /dev/null
+++ b/gmp/mpn/vax/elf.m4
@@ -0,0 +1,54 @@
+divert(-1)
+
+dnl m4 macros for VAX assembler.
+
+dnl Copyright 2001, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+defreg(r0,`%r``''0')
+defreg(r1,`%r``''1')
+defreg(r2,`%r``''2')
+defreg(r3,`%r``''3')
+defreg(r4,`%r``''4')
+defreg(r5,`%r``''5')
+defreg(r6,`%r``''6')
+defreg(r7,`%r``''7')
+defreg(r8,`%r``''8')
+defreg(r9,`%r``''9')
+defreg(r10,`%r``''10')
+defreg(r11,`%r``''11')
+defreg(r12,`%r``''12')
+defreg(r13,`%r``''13')
+defreg(r14,`%r``''14')
+defreg(r15,`%r``''15')
+defreg(ap,`%a``''p')
+
+define(`foo', blablabla)
+
+divert
diff --git a/gmp/mpn/vax/gmp-mparam.h b/gmp/mpn/vax/gmp-mparam.h
new file mode 100644
index 0000000000..9f20b9b783
--- /dev/null
+++ b/gmp/mpn/vax/gmp-mparam.h
@@ -0,0 +1,60 @@
+/* VAX gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* These numbers were measured manually using the tune/speed program.
+ The standard tune/tuneup takes too long. (VAX 8800) */
+
+#define MUL_TOOM22_THRESHOLD 14
+#define MUL_TOOM33_THRESHOLD 110
+
+#define SQR_BASECASE_THRESHOLD 6
+#define SQR_TOOM2_THRESHOLD 42
+#define SQR_TOOM3_THRESHOLD 250
+
+/* #define DIV_SB_PREINV_THRESHOLD */
+/* #define DIV_DC_THRESHOLD */
+/* #define POWM_THRESHOLD */
+
+/* #define GCD_ACCEL_THRESHOLD */
+/* #define JACOBI_BASE_METHOD */
+
+/* #define DIVREM_1_NORM_THRESHOLD */
+/* #define DIVREM_1_UNNORM_THRESHOLD */
+/* #define MOD_1_NORM_THRESHOLD */
+/* #define MOD_1_UNNORM_THRESHOLD */
+/* #define USE_PREINV_DIVREM_1 */
+/* #define USE_PREINV_MOD_1 */
+/* #define DIVREM_2_THRESHOLD */
+/* #define DIVEXACT_1_THRESHOLD */
+/* #define MODEXACT_1_ODD_THRESHOLD */
+
+/* #define GET_STR_DC_THRESHOLD */
+/* #define GET_STR_PRECOMPUTE_THRESHOLD */
+#define SET_STR_THRESHOLD 3400
diff --git a/gmp/mpn/vax/lshift.asm b/gmp/mpn/vax/lshift.asm
new file mode 100644
index 0000000000..941e9994b8
--- /dev/null
+++ b/gmp/mpn/vax/lshift.asm
@@ -0,0 +1,59 @@
+dnl VAX mpn_lshift -- left shift.
+
+dnl Copyright 1999-2001, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_lshift)
+ .word 0x1c0
+ movl 4(ap), r7
+ movl 8(ap), r6
+ movl 12(ap), r1
+ movl 16(ap), r8
+
+ moval (r6)[r1], r6
+ moval (r7)[r1], r7
+ clrl r3
+ movl -(r6), r2
+ ashq r8, r2, r4
+ movl r5, r0
+ movl r2, r3
+ decl r1
+ jeql L(end)
+
+L(top): movl -(r6), r2
+ ashq r8, r2, r4
+ movl r5, -(r7)
+ movl r2, r3
+ sobgtr r1, L(top)
+
+L(end): movl r4, -4(r7)
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/vax/mul_1.asm b/gmp/mpn/vax/mul_1.asm
new file mode 100644
index 0000000000..8e4dcd2177
--- /dev/null
+++ b/gmp/mpn/vax/mul_1.asm
@@ -0,0 +1,118 @@
+dnl VAX mpn_mul_1 -- Multiply a limb vector with a limb and store the result
+dnl in a second limb vector.
+
+dnl Copyright 1992, 1994, 1996, 2000, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_mul_1)
+ .word 0xfc0
+ movl 12(ap), r4
+ movl 8(ap), r8
+ movl 4(ap), r9
+ clrl r3
+ incl r4
+ ashl $-1, r4, r7
+ clrl r11
+ movl 16(ap), r6
+ jlss L(v0_big)
+ jlbc r4, L(1)
+
+C Loop for v0 < 0x80000000
+L(tp1): movl (r8)+, r1
+ jlss L(1n0)
+ emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc $0, r3
+ movl r2, (r9)+
+L(1): movl (r8)+, r1
+ jlss L(1n1)
+L(1p1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc $0, r11
+ movl r10, (r9)+
+
+ sobgtr r7, L(tp1)
+ movl r11, r0
+ ret
+
+L(1n0): emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc r6, r3
+ movl r2, (r9)+
+ movl (r8)+, r1
+ jgeq L(1p1)
+L(1n1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc r6, r11
+ movl r10, (r9)+
+
+ sobgtr r7, L(tp1)
+ movl r11, r0
+ ret
+
+L(v0_big):
+ jlbc r4, L(2)
+
+C Loop for v0 >= 0x80000000
+L(tp2): movl (r8)+, r1
+ jlss L(2n0)
+ emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc r1, r3
+ movl r2, (r9)+
+L(2): movl (r8)+, r1
+ jlss L(2n1)
+L(2p1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc r1, r11
+ movl r10, (r9)+
+
+ sobgtr r7, L(tp2)
+ movl r11, r0
+ ret
+
+L(2n0): emul r1, r6, $0, r2
+ addl2 r1, r3
+ addl2 r11, r2
+ adwc r6, r3
+ movl r2, (r9)+
+ movl (r8)+, r1
+ jgeq L(2p1)
+L(2n1): emul r1, r6, $0, r10
+ addl2 r1, r11
+ addl2 r3, r10
+ adwc r6, r11
+ movl r10, (r9)+
+
+ sobgtr r7, L(tp2)
+ movl r11, r0
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/vax/rshift.asm b/gmp/mpn/vax/rshift.asm
new file mode 100644
index 0000000000..00b2daac01
--- /dev/null
+++ b/gmp/mpn/vax/rshift.asm
@@ -0,0 +1,57 @@
+dnl VAX mpn_rshift -- right shift.
+
+dnl Copyright 1999-2001, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_rshift)
+ .word 0x1c0
+ movl 4(ap), r7
+ movl 8(ap), r6
+ movl 12(ap), r1
+ movl 16(ap), r8
+
+ movl (r6)+, r2
+ subl3 r8, $32, r8
+ ashl r8, r2, r0
+ decl r1
+ jeql L(end)
+
+L(top): movl (r6)+, r3
+ ashq r8, r2, r4
+ movl r5, (r7)+
+ movl r3, r2
+ sobgtr r1, L(top)
+
+L(end): clrl r3
+ ashq r8, r2, r4
+ movl r5, (r7)
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/vax/sub_n.asm b/gmp/mpn/vax/sub_n.asm
new file mode 100644
index 0000000000..2844ef2cc1
--- /dev/null
+++ b/gmp/mpn/vax/sub_n.asm
@@ -0,0 +1,64 @@
+dnl VAX mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+dnl store difference in a third limb vector.
+
+dnl Copyright 1999, 2000, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_sub_n)
+ .word 0x0
+ movl 16(ap), r0
+ movl 12(ap), r1
+ movl 8(ap), r2
+ movl 4(ap), r3
+ mnegl r0, r5
+ addl2 $3, r0
+ ashl $-2, r0, r0 C unroll loop count
+ bicl2 $-4, r5 C mask out low 2 bits
+ movaq (r5)[r5], r5 C 9x
+ jmp L(top)[r5]
+
+L(top): movl (r2)+, r4
+ sbwc (r1)+, r4
+ movl r4, (r3)+
+ movl (r2)+, r4
+ sbwc (r1)+, r4
+ movl r4, (r3)+
+ movl (r2)+, r4
+ sbwc (r1)+, r4
+ movl r4, (r3)+
+ movl (r2)+, r4
+ sbwc (r1)+, r4
+ movl r4, (r3)+
+ sobgtr r0, L(top)
+
+ adwc r0, r0
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/vax/submul_1.asm b/gmp/mpn/vax/submul_1.asm
new file mode 100644
index 0000000000..60d47fcd6f
--- /dev/null
+++ b/gmp/mpn/vax/submul_1.asm
@@ -0,0 +1,124 @@
+dnl VAX mpn_submul_1 -- Multiply a limb vector with a limb and subtract the
+dnl result from a second limb vector.
+
+dnl Copyright 1992, 1994, 1996, 2000, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ASM_START()
+PROLOGUE(mpn_submul_1)
+ .word 0xfc0
+ movl 12(ap), r4
+ movl 8(ap), r8
+ movl 4(ap), r9
+ clrl r3
+ incl r4
+ ashl $-1, r4, r7
+ clrl r11
+ movl 16(ap), r6
+ jlss L(v0_big)
+ jlbc r4, L(1)
+
+C Loop for v0 < 0x80000000
+L(tp1): movl (r8)+, r1
+ jlss L(1n0)
+ emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc $0, r3
+ subl2 r2, (r9)+
+ adwc $0, r3
+L(1): movl (r8)+, r1
+ jlss L(1n1)
+L(1p1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc $0, r11
+ subl2 r10, (r9)+
+ adwc $0, r11
+
+ sobgtr r7, L(tp1)
+ movl r11, r0
+ ret
+
+L(1n0): emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc r6, r3
+ subl2 r2, (r9)+
+ adwc $0, r3
+ movl (r8)+, r1
+ jgeq L(1p1)
+L(1n1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc r6, r11
+ subl2 r10, (r9)+
+ adwc $0, r11
+
+ sobgtr r7, L(tp1)
+ movl r11, r0
+ ret
+
+L(v0_big):
+ jlbc r4, L(2)
+
+C Loop for v0 >= 0x80000000
+L(tp2): movl (r8)+, r1
+ jlss L(2n0)
+ emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc r1, r3
+ subl2 r2, (r9)+
+ adwc $0, r3
+L(2): movl (r8)+, r1
+ jlss L(2n1)
+L(2p1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc r1, r11
+ subl2 r10, (r9)+
+ adwc $0, r11
+
+ sobgtr r7, L(tp2)
+ movl r11, r0
+ ret
+
+L(2n0): emul r1, r6, $0, r2
+ addl2 r11, r2
+ adwc r6, r3
+ subl2 r2, (r9)+
+ adwc r1, r3
+ movl (r8)+, r1
+ jgeq L(2p1)
+L(2n1): emul r1, r6, $0, r10
+ addl2 r3, r10
+ adwc r6, r11
+ subl2 r10, (r9)+
+ adwc r1, r11
+
+ sobgtr r7, L(tp2)
+ movl r11, r0
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/README b/gmp/mpn/x86/README
new file mode 100644
index 0000000000..8d7ac9080d
--- /dev/null
+++ b/gmp/mpn/x86/README
@@ -0,0 +1,525 @@
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ X86 MPN SUBROUTINES
+
+
+This directory contains mpn functions for various 80x86 chips.
+
+
+CODE ORGANIZATION
+
+ x86 i386, generic
+ x86/i486 i486
+ x86/pentium Intel Pentium (P5, P54)
+ x86/pentium/mmx Intel Pentium with MMX (P55)
+ x86/p6 Intel Pentium Pro
+ x86/p6/mmx Intel Pentium II, III
+ x86/p6/p3mmx Intel Pentium III
+ x86/k6 \ AMD K6
+ x86/k6/mmx /
+ x86/k6/k62mmx AMD K6-2
+ x86/k7 \ AMD Athlon
+ x86/k7/mmx /
+ x86/pentium4 \
+ x86/pentium4/mmx | Intel Pentium 4
+ x86/pentium4/sse2 /
+
+
+The top-level x86 directory contains blended style code, meant to be
+reasonable on all x86s.
+
+
+
+STATUS
+
+The code is well-optimized for AMD and Intel chips, but there's nothing
+specific for Cyrix chips, nor for actual 80386 and 80486 chips.
+
+
+
+ASM FILES
+
+The x86 .asm files are BSD style assembler code, first put through m4 for
+macro processing. The generic mpn/asm-defs.m4 is used, together with
+mpn/x86/x86-defs.m4. See comments in those files.
+
+The code is meant for use with GNU "gas" or a system "as". There's no
+support for assemblers that demand Intel style code.
+
+
+
+STACK FRAME
+
+m4 macros are used to define the parameters passed on the stack, and these
+act like comments on what the stack frame looks like too. For example,
+mpn_mul_1() has the following.
+
+ defframe(PARAM_MULTIPLIER, 16)
+ defframe(PARAM_SIZE, 12)
+ defframe(PARAM_SRC, 8)
+ defframe(PARAM_DST, 4)
+
+PARAM_MULTIPLIER becomes `FRAME+16(%esp)', and the others similarly. The
+return address is at offset 0, but there's not normally any need to access
+that.
+
+FRAME is redefined as necessary through the code so it's the number of bytes
+pushed on the stack, and hence the offsets in the parameter macros stay
+correct. At the start of a routine FRAME should be zero.
+
+ deflit(`FRAME',0)
+ ...
+ deflit(`FRAME',4)
+ ...
+ deflit(`FRAME',8)
+ ...
+
+Helper macros FRAME_pushl(), FRAME_popl(), FRAME_addl_esp() and
+FRAME_subl_esp() exist to adjust FRAME for the effect of those instructions,
+and can be used instead of explicit definitions if preferred.
+defframe_pushl() is a combination FRAME_pushl() and defframe().
+
+There's generally some slackness in redefining FRAME. If new values aren't
+going to get used then the redefinitions are omitted to keep from cluttering
+up the code. This happens for instance at the end of a routine, where there
+might be just four pops and then a ret, so FRAME isn't getting used.
+
+Local variables and saved registers can be similarly defined, with negative
+offsets representing stack space below the initial stack pointer. For
+example,
+
+ defframe(SAVE_ESI, -4)
+ defframe(SAVE_EDI, -8)
+ defframe(VAR_COUNTER,-12)
+
+ deflit(STACK_SPACE, 12)
+
+Here STACK_SPACE gets used in a "subl $STACK_SPACE, %esp" to allocate the
+space, and that instruction must be followed by a redefinition of FRAME
+(setting it equal to STACK_SPACE) to reflect the change in %esp.
+
+Definitions for pushed registers are only put in when they're going to be
+used. If registers are just saved and restored with pushes and pops then
+definitions aren't made.
+
+
+
+ASSEMBLER EXPRESSIONS
+
+Only addition and subtraction seem to be universally available, certainly
+that's all the Solaris 8 "as" seems to accept. If expressions are wanted
+then m4 eval() should be used.
+
+In particular note that a "/" anywhere in a line starts a comment in Solaris
+"as", and in some configurations of gas too.
+
+ addl $32/2, %eax <-- wrong
+
+ addl $eval(32/2), %eax <-- right
+
+Binutils gas/config/tc-i386.c has a choice between "/" being a comment
+anywhere in a line, or only at the start. FreeBSD patches 2.9.1 to select
+the latter, and from 2.9.5 it's the default for GNU/Linux too.
+
+
+
+ASSEMBLER COMMENTS
+
+Solaris "as" doesn't support "#" commenting, using /* */ instead. For that
+reason "C" commenting is used (see asm-defs.m4) and the intermediate ".s"
+files have no comments.
+
+Any comments before include(`../config.m4') must use m4 "dnl", since it's
+only after the include that "C" is available. By convention "dnl" is also
+used for comments about m4 macros.
+
+
+
+TEMPORARY LABELS
+
+Temporary numbered labels like "1:" used as "1f" or "1b" are available in
+"gas" and Solaris "as", but not in SCO "as". Normal L() labels should be
+used instead, possibly with a counter to make them unique, see jadcl0() in
+x86-defs.m4 for instance. A separate counter for each macro makes it
+possible to nest them, for instance movl_text_address() can be used within
+an ASSERT().
+
+"1:" etc must be avoided in gcc __asm__ blocks too. "%=" for generating a
+unique number looks like a good alternative, but is that actually a
+documented feature? In any case this problem doesn't currently arise.
+
+
+
+ZERO DISPLACEMENTS
+
+In a couple of places addressing modes like 0(%ebx) with a byte-sized zero
+displacement are wanted, rather than (%ebx) with no displacement. These are
+either for computed jumps or to get desirable code alignment. Explicit
+.byte sequences are used to ensure the assembler doesn't turn 0(%ebx) into
+(%ebx). The Zdisp() macro in x86-defs.m4 is used for this.
+
+Current gas 2.9.5 or recent 2.9.1 leave 0(%ebx) as written, but old gas
+1.92.3 changes it. In general changing would be the sort of "optimization"
+an assembler might perform, hence explicit ".byte"s are used where
+necessary.
+
+
+
+SHLD/SHRD INSTRUCTIONS
+
+The %cl count forms of double shift instructions like "shldl %cl,%eax,%ebx"
+must be written "shldl %eax,%ebx" for some assemblers. gas takes either,
+Solaris "as" doesn't allow %cl, gcc generates %cl for gas and NeXT (which is
+gas), and omits %cl elsewhere.
+
+For GMP an autoconf test GMP_ASM_X86_SHLDL_CL is used to determine whether
+%cl should be used, and the macros shldl, shrdl, shldw and shrdw in
+mpn/x86/x86-defs.m4 pass through or omit %cl as necessary. See the comments
+with those macros for usage.
+
+
+
+IMUL INSTRUCTION
+
+GCC config/i386/i386.md (cvs rev 1.187, 21 Oct 00) under *mulsi3_1 notes
+that the following two forms produce identical object code
+
+ imul $12, %eax
+ imul $12, %eax, %eax
+
+but that the former isn't accepted by some assemblers, in particular the SCO
+OSR5 COFF assembler. GMP follows GCC and uses only the latter form.
+
+(This applies only to immediate operands, the three operand form is only
+valid with an immediate.)
+
+
+
+DIRECTION FLAG
+
+The x86 calling conventions say that the direction flag should be clear at
+function entry and exit. (See iBCS2 and SVR4 ABI books, references below.)
+Although this has been so since the year dot, it's not absolutely clear
+whether it's universally respected. Since it's better to be safe than
+sorry, GMP follows glibc and does a "cld" if it depends on the direction
+flag being clear. This happens only in a few places.
+
+
+
+POSITION INDEPENDENT CODE
+
+ Coding Style
+
+ Defining the symbol PIC in m4 processing selects SVR4 / ELF style
+ position independent code. This is necessary for shared libraries
+ because they can be mapped into different processes at different virtual
+ addresses. Actually, relocations are allowed but text pages with
+ relocations aren't shared, defeating the purpose of a shared library.
+
+ The GOT is used to access global data, and the PLT is used for
+ functions. The use of the PLT adds a fixed cost to every function call,
+ and the GOT adds a cost to any function accessing global variables.
+ These are small but might be noticeable when working with small
+ operands.
+
+ Scope
+
+ It's intended, as a matter of policy, that references within libgmp are
+ resolved within libgmp. Certainly there's no need for an application to
+ replace any internals, and we take the view that there's no value in an
+ application subverting anything documented either.
+
+ Resolving references within libgmp in theory means calls can be made with a
+ plain PC-relative call instruction, which is faster and smaller than going
+ through the PLT, and data references can be similarly PC-relative, saving a
+ GOT entry and fetch from there. Unfortunately the normal linker behaviour
+ doesn't allow us to do this.
+
+ By default an R_386_PC32 PC-relative reference, either for a call or for
+ data, is left in libgmp.so by the linker so that it can be resolved at
+ runtime to a location in the application or another shared library. This
+ means a text segment relocation which we don't want.
+
+ -Bsymbolic
+
+ Under the "-Bsymbolic" option, the linker resolves references to symbols
+ within libgmp.so. This gives us the desired effect for R_386_PC32,
+ ie. it's resolved at link time. It also resolves R_386_PLT32 calls
+ directly to their target without creating a PLT entry (though if this is
+ done to normal compiler-generated code it still leaves a setup of %ebx
+ to _GLOBAL_OFFSET_TABLE_ which may then be unnecessary).
+
+ Unfortunately -Bsymbolic does bad things to global variables defined in
+ a shared library but accessed by non-PIC code from the mainline (or a
+ static library).
+
+ The problem is that the mainline needs a fixed data address to avoid
+ text segment relocations, so space is allocated in its data segment and
+ the value from the variable is copied from the shared library's data
+ segment when the library is loaded. Under -Bsymbolic, however,
+ references in the shared library are then resolved still to the shared
+ library data area. Not surprisingly it bombs badly to have mainline
+ code and library code accessing different locations for what should be
+ one variable.
+
+ Note that this -Bsymbolic effect for the shared library is not just for
+ R_386_PC32 offsets which might have been cooked up in assembler, but is
+ done also for the contents of GOT entries. -Bsymbolic simply applies a
+ general rule that symbols are resolved first from the local module.
+
+ Visibility Attributes
+
+ GCC __attribute__ ((visibility ("protected"))), which is available in
+ recent versions, eg. 3.3, is probably what we'd like to use. It makes
+ gcc generate plain PC-relative calls to indicated functions, and directs
+ the linker to resolve references to the given function within the link
+ module.
+
+ Unfortunately, as of debian binutils 2.13.90.0.16 at least, the
+ resulting libgmp.so comes out with text segment relocations, references
+ are not resolved at link time. If the gcc description is to be believed
+ this is this not how it should work. If a symbol cannot be overridden
+ by another module then surely references within that module can be
+ resolved immediately (ie. at link time).
+
+ Present
+
+ In any case, all this means that we have no optimizations we can
+ usefully make to function or variable usages, neither for assembler nor
+ C code. Perhaps in the future the visibility attribute will work as
+ we'd like.
+
+
+
+
+GLOBAL OFFSET TABLE
+
+The magic _GLOBAL_OFFSET_TABLE_ used by code establishing the address of the
+GOT sometimes requires an extra underscore prefix. SVR4 systems and NetBSD
+don't need a prefix, OpenBSD does need one. Note that NetBSD and OpenBSD
+are both a.out underscore systems, so the prefix for _GLOBAL_OFFSET_TABLE_
+is not simply the same as the prefix for ordinary globals.
+
+In any case in the asm code we write _GLOBAL_OFFSET_TABLE_ and let a macro
+in x86-defs.m4 add an extra underscore if required (according to a configure
+test).
+
+Old gas 1.92.3 which comes with FreeBSD 2.2.8 gets a segmentation fault when
+asked to assemble the following,
+
+ L1:
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L1], %ebx
+
+It seems that using the label in the same instruction it refers to is the
+problem, since a nop in between works. But the simplest workaround is to
+follow gcc and omit the +[.-L1] since it does nothing,
+
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+
+Current gas 2.10 generates incorrect object code when %eax is used in such a
+construction (with or without +[.-L1]),
+
+ addl $_GLOBAL_OFFSET_TABLE_, %eax
+
+The R_386_GOTPC gets a displacement of 2 rather than the 1 appropriate for
+the 1 byte opcode of "addl $n,%eax". The best workaround is just to use any
+other register, since then it's a two byte opcode+mod/rm. GCC for example
+always uses %ebx (which is needed for calls through the PLT).
+
+A similar problem occurs in an leal (again with or without a +[.-L1]),
+
+ leal _GLOBAL_OFFSET_TABLE_(%edi), %ebx
+
+This time the R_386_GOTPC gets a displacement of 0 rather than the 2
+appropriate for the opcode and mod/rm, making this form unusable.
+
+
+
+
+SIMPLE LOOPS
+
+The overheads in setting up for an unrolled loop can mean that at small
+sizes a simple loop is faster. Making small sizes go fast is important,
+even if it adds a cycle or two to bigger sizes. To this end various
+routines choose between a simple loop and an unrolled loop according to
+operand size. The path to the simple loop, or to special case code for
+small sizes, is always as fast as possible.
+
+Adding a simple loop requires a conditional jump to choose between the
+simple and unrolled code. The size of a branch misprediction penalty
+affects whether a simple loop is worthwhile.
+
+The convention is for an m4 definition UNROLL_THRESHOLD to set the crossover
+point, with sizes < UNROLL_THRESHOLD using the simple loop, sizes >=
+UNROLL_THRESHOLD using the unrolled loop. If position independent code adds
+a couple of cycles to an unrolled loop setup, the threshold will vary with
+PIC or non-PIC. Something like the following is typical.
+
+ deflit(UNROLL_THRESHOLD, ifdef(`PIC',10,8))
+
+There's no automated way to determine the threshold. Setting it to a small
+value and then to a big value makes it possible to measure the simple and
+unrolled loops each over a range of sizes, from which the crossover point
+can be determined. Alternately, just adjust the threshold up or down until
+there's no more speedups.
+
+
+
+UNROLLED LOOP CODING
+
+The x86 addressing modes allow a byte displacement of -128 to +127, making
+it possible to access 256 bytes, which is 64 limbs, without adjusting
+pointer registers within the loop. Dword sized displacements can be used
+too, but they increase code size, and unrolling to 64 ought to be enough.
+
+When unrolling to the full 64 limbs/loop, the limb at the top of the loop
+will have a displacement of -128, so pointers have to have a corresponding
++128 added before entering the loop. When unrolling to 32 limbs/loop
+displacements 0 to 127 can be used with 0 at the top of the loop and no
+adjustment needed to the pointers.
+
+Where 64 limbs/loop is supported, the +128 adjustment is done only when 64
+limbs/loop is selected. Usually the gain in speed using 64 instead of 32 or
+16 is small, so support for 64 limbs/loop is generally only for comparison.
+
+
+
+COMPUTED JUMPS
+
+When working from least significant limb to most significant limb (most
+routines) the computed jump and pointer calculations in preparation for an
+unrolled loop are as follows.
+
+ S = operand size in limbs
+ N = number of limbs per loop (UNROLL_COUNT)
+ L = log2 of unrolling (UNROLL_LOG2)
+ M = mask for unrolling (UNROLL_MASK)
+ C = code bytes per limb in the loop
+ B = bytes per limb (4 for x86)
+
+ computed jump (-S & M) * C + entrypoint
+ subtract from pointers (-S & M) * B
+ initial loop counter (S-1) >> L
+ displacements 0 to B*(N-1)
+
+The loop counter is decremented at the end of each loop, and the looping
+stops when the decrement takes the counter to -1. The displacements are for
+the addressing accessing each limb, eg. a load with "movl disp(%ebx), %eax".
+
+Usually the multiply by "C" can be handled without an imul, using instead an
+leal, or a shift and subtract.
+
+When working from most significant to least significant limb (eg. mpn_lshift
+and mpn_copyd), the calculations change as follows.
+
+ add to pointers (-S & M) * B
+ displacements 0 to -B*(N-1)
+
+
+
+OLD GAS 1.92.3
+
+This version comes with FreeBSD 2.2.8 and has a couple of gremlins that
+affect GMP code.
+
+Firstly, an expression involving two forward references to labels comes out
+as zero. For example,
+
+ addl $bar-foo, %eax
+ foo:
+ nop
+ bar:
+
+This should lead to "addl $1, %eax", but it comes out as "addl $0, %eax".
+When only one forward reference is involved, it works correctly, as for
+example,
+
+ foo:
+ addl $bar-foo, %eax
+ nop
+ bar:
+
+Secondly, an expression involving two labels can't be used as the
+displacement for an leal. For example,
+
+ foo:
+ nop
+ bar:
+ leal bar-foo(%eax,%ebx,8), %ecx
+
+A slightly cryptic error is given, "Unimplemented segment type 0 in
+parse_operand". When only one label is used it's ok, and the label can be a
+forward reference too, as for example,
+
+ leal foo(%eax,%ebx,8), %ecx
+ nop
+ foo:
+
+These problems only affect PIC computed jump calculations. The workarounds
+are just to do an leal without a displacement and then an addl, and to make
+sure the code is placed so that there's at most one forward reference in the
+addl.
+
+
+
+REFERENCES
+
+"Intel Architecture Software Developer's Manual", volumes 1, 2a, 2b, 3a, 3b,
+2006, order numbers 253665 through 253669. Available on-line,
+
+ ftp://download.intel.com/design/Pentium4/manuals/25366518.pdf
+ ftp://download.intel.com/design/Pentium4/manuals/25366618.pdf
+ ftp://download.intel.com/design/Pentium4/manuals/25366718.pdf
+ ftp://download.intel.com/design/Pentium4/manuals/25366818.pdf
+ ftp://download.intel.com/design/Pentium4/manuals/25366918.pdf
+
+
+"System V Application Binary Interface", Unix System Laboratories Inc, 1992,
+published by Prentice Hall, ISBN 0-13-880410-9. And the "Intel386 Processor
+Supplement", AT&T, 1991, ISBN 0-13-877689-X. These have details of calling
+conventions and ELF shared library PIC coding. Versions of both available
+on-line,
+
+ http://www.sco.com/developer/devspecs
+
+"Intel386 Family Binary Compatibility Specification 2", Intel Corporation,
+published by McGraw-Hill, 1991, ISBN 0-07-031219-2. (Same as the above 386
+ABI supplement.)
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/x86/aors_n.asm b/gmp/mpn/x86/aors_n.asm
new file mode 100644
index 0000000000..5d359f59b6
--- /dev/null
+++ b/gmp/mpn/x86/aors_n.asm
@@ -0,0 +1,202 @@
+dnl x86 mpn_add_n/mpn_sub_n -- mpn addition and subtraction.
+
+dnl Copyright 1992, 1994-1996, 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5 3.375
+C P6 3.125
+C K6 3.5
+C K7 2.25
+C P4 8.75
+
+
+ifdef(`OPERATION_add_n',`
+ define(M4_inst, adcl)
+ define(M4_function_n, mpn_add_n)
+ define(M4_function_nc, mpn_add_nc)
+
+',`ifdef(`OPERATION_sub_n',`
+ define(M4_inst, sbbl)
+ define(M4_function_n, mpn_sub_n)
+ define(M4_function_nc, mpn_sub_nc)
+
+',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
+')')')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+
+C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size);
+C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size, mp_limb_t carry);
+
+defframe(PARAM_CARRY,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC2, 12)
+defframe(PARAM_SRC1, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(M4_function_nc)
+deflit(`FRAME',0)
+
+ pushl %edi FRAME_pushl()
+ pushl %esi FRAME_pushl()
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC1,%esi
+ movl PARAM_SRC2,%edx
+ movl PARAM_SIZE,%ecx
+
+ movl %ecx,%eax
+ shrl $3,%ecx C compute count for unrolled loop
+ negl %eax
+ andl $7,%eax C get index where to start loop
+ jz L(oopgo) C necessary special case for 0
+ incl %ecx C adjust loop count
+ shll $2,%eax C adjustment for pointers...
+ subl %eax,%edi C ... since they are offset ...
+ subl %eax,%esi C ... by a constant when we ...
+ subl %eax,%edx C ... enter the loop
+ shrl $2,%eax C restore previous value
+
+ifdef(`PIC',`
+ C Calculate start address in loop for PIC. Due to limitations in
+ C old gas, LF(M4_function_n,oop)-L(0a)-3 cannot be put into the leal
+ call L(0a)
+L(0a): leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $L(oop)-L(0a)-3,%eax
+ addl $4,%esp
+',`
+ C Calculate start address in loop for non-PIC.
+ leal L(oop)-3(%eax,%eax,8),%eax
+')
+
+ C These lines initialize carry from the 5th parameter. Should be
+ C possible to simplify.
+ pushl %ebp FRAME_pushl()
+ movl PARAM_CARRY,%ebp
+ shrl %ebp C shift bit 0 into carry
+ popl %ebp FRAME_popl()
+
+ jmp *%eax C jump into loop
+
+EPILOGUE()
+
+
+ ALIGN(16)
+PROLOGUE(M4_function_n)
+deflit(`FRAME',0)
+
+ pushl %edi FRAME_pushl()
+ pushl %esi FRAME_pushl()
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC1,%esi
+ movl PARAM_SRC2,%edx
+ movl PARAM_SIZE,%ecx
+
+ movl %ecx,%eax
+ shrl $3,%ecx C compute count for unrolled loop
+ negl %eax
+ andl $7,%eax C get index where to start loop
+ jz L(oop) C necessary special case for 0
+ incl %ecx C adjust loop count
+ shll $2,%eax C adjustment for pointers...
+ subl %eax,%edi C ... since they are offset ...
+ subl %eax,%esi C ... by a constant when we ...
+ subl %eax,%edx C ... enter the loop
+ shrl $2,%eax C restore previous value
+
+ifdef(`PIC',`
+ C Calculate start address in loop for PIC. Due to limitations in
+ C some assemblers, L(oop)-L(0b)-3 cannot be put into the leal
+ call L(0b)
+L(0b): leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $L(oop)-L(0b)-3,%eax
+ addl $4,%esp
+',`
+ C Calculate start address in loop for non-PIC.
+ leal L(oop)-3(%eax,%eax,8),%eax
+')
+ jmp *%eax C jump into loop
+
+L(oopgo):
+ pushl %ebp FRAME_pushl()
+ movl PARAM_CARRY,%ebp
+ shrl %ebp C shift bit 0 into carry
+ popl %ebp FRAME_popl()
+
+ ALIGN(16)
+L(oop): movl (%esi),%eax
+ M4_inst (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ M4_inst 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ M4_inst 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ M4_inst 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ M4_inst 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ M4_inst 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ M4_inst 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ M4_inst 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz L(oop)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ popl %edi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/aorsmul_1.asm b/gmp/mpn/x86/aorsmul_1.asm
new file mode 100644
index 0000000000..54a8905441
--- /dev/null
+++ b/gmp/mpn/x86/aorsmul_1.asm
@@ -0,0 +1,156 @@
+dnl x86 __gmpn_addmul_1 (for 386 and 486) -- Multiply a limb vector with a
+dnl limb and add the result to a second limb vector.
+
+dnl Copyright 1992, 1994, 1997, 1999-2002, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C P5 14.75
+C P6 model 0-8,10-12 7.5
+C P6 model 9 (Banias) 6.7
+C P6 model 13 (Dothan) 6.75
+C P4 model 0 (Willamette) 24.0
+C P4 model 1 (?) 24.0
+C P4 model 2 (Northwood) 24.0
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom
+C AMD K6 12.5
+C AMD K7 5.25
+C AMD K8
+C AMD K10
+
+
+ifdef(`OPERATION_addmul_1',`
+ define(M4_inst, addl)
+ define(M4_function_1, mpn_addmul_1)
+
+',`ifdef(`OPERATION_submul_1',`
+ define(M4_inst, subl)
+ define(M4_function_1, mpn_submul_1)
+
+',`m4_error(`Need OPERATION_addmul_1 or OPERATION_submul_1
+')')')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+
+C mp_limb_t M4_function_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult);
+
+define(PARAM_MULTIPLIER, `FRAME+16(%esp)')
+define(PARAM_SIZE, `FRAME+12(%esp)')
+define(PARAM_SRC, `FRAME+8(%esp)')
+define(PARAM_DST, `FRAME+4(%esp)')
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(M4_function_1)
+deflit(`FRAME',0)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+deflit(`FRAME',16)
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC,%esi
+ movl PARAM_SIZE,%ecx
+
+ xorl %ebx,%ebx
+ andl $3,%ecx
+ jz L(end0)
+
+L(oop0):
+ movl (%esi),%eax
+ mull PARAM_MULTIPLIER
+ leal 4(%esi),%esi
+ addl %ebx,%eax
+ movl $0,%ebx
+ adcl %ebx,%edx
+ M4_inst %eax,(%edi)
+ adcl %edx,%ebx C propagate carry into cylimb
+
+ leal 4(%edi),%edi
+ decl %ecx
+ jnz L(oop0)
+
+L(end0):
+ movl PARAM_SIZE,%ecx
+ shrl $2,%ecx
+ jz L(end)
+
+ ALIGN(8)
+L(oop): movl (%esi),%eax
+ mull PARAM_MULTIPLIER
+ addl %eax,%ebx
+ movl $0,%ebp
+ adcl %edx,%ebp
+
+ movl 4(%esi),%eax
+ mull PARAM_MULTIPLIER
+ M4_inst %ebx,(%edi)
+ adcl %eax,%ebp C new lo + cylimb
+ movl $0,%ebx
+ adcl %edx,%ebx
+
+ movl 8(%esi),%eax
+ mull PARAM_MULTIPLIER
+ M4_inst %ebp,4(%edi)
+ adcl %eax,%ebx C new lo + cylimb
+ movl $0,%ebp
+ adcl %edx,%ebp
+
+ movl 12(%esi),%eax
+ mull PARAM_MULTIPLIER
+ M4_inst %ebx,8(%edi)
+ adcl %eax,%ebp C new lo + cylimb
+ movl $0,%ebx
+ adcl %edx,%ebx
+
+ M4_inst %ebp,12(%edi)
+ adcl $0,%ebx C propagate carry into cylimb
+
+ leal 16(%esi),%esi
+ leal 16(%edi),%edi
+ decl %ecx
+ jnz L(oop)
+
+L(end): movl %ebx,%eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/atom/aorrlsh1_n.asm b/gmp/mpn/x86/atom/aorrlsh1_n.asm
new file mode 100644
index 0000000000..cd1a650022
--- /dev/null
+++ b/gmp/mpn/x86/atom/aorrlsh1_n.asm
@@ -0,0 +1,53 @@
+dnl Intel Atom mpn_rsblsh1_n -- rp[] = (vp[] << 1) - up[]
+
+dnl Contributed to the GNU project by Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 1)
+define(RSH, 31)
+
+ifdef(`OPERATION_addlsh1_n', `
+ define(M4_inst, adc)
+ define(M4_opp, sub)
+ define(M4_function, mpn_addlsh1_n)
+ define(M4_function_c, mpn_addlsh1_nc)
+',`ifdef(`OPERATION_rsblsh1_n', `
+ define(M4_inst, sbb)
+ define(M4_opp, add)
+ define(M4_function, mpn_rsblsh1_n)
+ define(M4_function_c, mpn_rsblsh1_nc)
+',`m4_error(`Need OPERATION_addlsh1_n or OPERATION_rsblsh1_n
+')')')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_addlsh1_nc mpn_rsblsh1_n mpn_rsblsh1_nc)
+
+include_mpn(`x86/atom/aorrlshC_n.asm')
diff --git a/gmp/mpn/x86/atom/aorrlsh2_n.asm b/gmp/mpn/x86/atom/aorrlsh2_n.asm
new file mode 100644
index 0000000000..10f4419de9
--- /dev/null
+++ b/gmp/mpn/x86/atom/aorrlsh2_n.asm
@@ -0,0 +1,53 @@
+dnl Intel Atom mpn_addlsh2_n/mpn_rsblsh2_n -- rp[] = (vp[] << 2) +- up[]
+
+dnl Contributed to the GNU project by Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 2)
+define(RSH, 30)
+
+ifdef(`OPERATION_addlsh2_n', `
+ define(M4_inst, adcl)
+ define(M4_opp, subl)
+ define(M4_function, mpn_addlsh2_n)
+ define(M4_function_c, mpn_addlsh2_nc)
+',`ifdef(`OPERATION_rsblsh2_n', `
+ define(M4_inst, sbbl)
+ define(M4_opp, addl)
+ define(M4_function, mpn_rsblsh2_n)
+ define(M4_function_c, mpn_rsblsh2_nc)
+',`m4_error(`Need OPERATION_addlsh2_n or OPERATION_rsblsh2_n
+')')')
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_addlsh2_nc mpn_rsblsh2_n mpn_rsblsh2_nc)
+
+include_mpn(`x86/atom/aorrlshC_n.asm')
diff --git a/gmp/mpn/x86/atom/aorrlshC_n.asm b/gmp/mpn/x86/atom/aorrlshC_n.asm
new file mode 100644
index 0000000000..71cfe490d6
--- /dev/null
+++ b/gmp/mpn/x86/atom/aorrlshC_n.asm
@@ -0,0 +1,156 @@
+dnl Intel Atom mpn_addlshC_n/mpn_rsblshC_n -- rp[] = (vp[] << C) +- up[]
+
+dnl Contributed to the GNU project by Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C mp_limb_t mpn_addlshC_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size);
+C mp_limb_t mpn_addlshC_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size, mp_limb_t carry);
+C mp_limb_t mpn_rsblshC_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size);
+C mp_limb_t mpn_rsblshC_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size, mp_signed_limb_t carry);
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 6
+C AMD K6
+C AMD K7
+C AMD K8
+C AMD K10
+
+defframe(PARAM_CORB, 20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_DBLD, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(VAR_COUNT,`PARAM_SIZE')
+define(SAVE_EBP,`PARAM_DBLD')
+define(SAVE_VP,`PARAM_SRC')
+define(SAVE_UP,`PARAM_DST')
+
+define(M, eval(m4_lshift(1,LSH)))
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`vp', `%ebx')
+
+ASM_START()
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(M4_function_c)
+deflit(`FRAME',0)
+ movl PARAM_CORB, %eax
+ movl %eax, %edx
+ shr $LSH, %edx
+ andl $1, %edx
+ M4_opp %edx, %eax
+ jmp L(start_nc)
+EPILOGUE()
+
+PROLOGUE(M4_function)
+deflit(`FRAME',0)
+
+ xor %eax, %eax
+ xor %edx, %edx
+L(start_nc):
+ push rp FRAME_pushl()
+
+ mov PARAM_SIZE, %ecx C size
+ mov PARAM_DST, rp
+ mov up, SAVE_UP
+ incl %ecx C size + 1
+ mov PARAM_SRC, up
+ mov vp, SAVE_VP
+ shr %ecx C (size+1)\2
+ mov PARAM_DBLD, vp
+ mov %ebp, SAVE_EBP
+ mov %ecx, VAR_COUNT
+ jnc L(entry) C size odd
+
+ shr %edx C size even
+ mov (vp), %ecx
+ lea 4(vp), vp
+ lea (%eax,%ecx,M), %edx
+ mov %ecx, %eax
+ lea -4(up), up
+ lea -4(rp), rp
+ jmp L(enteven)
+
+ ALIGN(16)
+L(oop):
+ lea (%eax,%ecx,M), %ebp
+ shr $RSH, %ecx
+ mov 4(vp), %eax
+ shr %edx
+ lea 8(vp), vp
+ M4_inst (up), %ebp
+ lea (%ecx,%eax,M), %edx
+ mov %ebp, (rp)
+L(enteven):
+ M4_inst 4(up), %edx
+ lea 8(up), up
+ mov %edx, 4(rp)
+ adc %edx, %edx
+ shr $RSH, %eax
+ lea 8(rp), rp
+L(entry):
+ mov (vp), %ecx
+ decl VAR_COUNT
+ jnz L(oop)
+
+ lea (%eax,%ecx,M), %ebp
+ shr $RSH, %ecx
+ shr %edx
+ mov SAVE_VP, vp
+ M4_inst (up), %ebp
+ mov %ecx, %eax
+ mov SAVE_UP, up
+ M4_inst $0, %eax
+ mov %ebp, (rp)
+ mov SAVE_EBP, %ebp
+ pop rp FRAME_popl()
+ ret
+EPILOGUE()
+
+ASM_END()
diff --git a/gmp/mpn/x86/atom/aors_n.asm b/gmp/mpn/x86/atom/aors_n.asm
new file mode 100644
index 0000000000..45ec287c3a
--- /dev/null
+++ b/gmp/mpn/x86/atom/aors_n.asm
@@ -0,0 +1,159 @@
+dnl Intel Atom mpn_add_n/mpn_sub_n -- rp[] = up[] +- vp[].
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Marco Bodrato.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 3
+C AMD K6
+C AMD K7
+C AMD K8
+C AMD K10
+
+ifdef(`OPERATION_add_n', `
+ define(M4_inst, adcl)
+ define(M4_function_n, mpn_add_n)
+ define(M4_function_nc, mpn_add_nc)
+ define(M4_description, add)
+',`ifdef(`OPERATION_sub_n', `
+ define(M4_inst, sbbl)
+ define(M4_function_n, mpn_sub_n)
+ define(M4_function_nc, mpn_sub_nc)
+ define(M4_description, subtract)
+',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
+')')')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size);
+C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size, mp_limb_t carry);
+C
+C Calculate src1,size M4_description src2,size, and store the result in
+C dst,size. The return value is the carry bit from the top of the result (1
+C or 0).
+C
+C The _nc version accepts 1 or 0 for an initial carry into the low limb of
+C the calculation. Note values other than 1 or 0 here will lead to garbage
+C results.
+
+defframe(PARAM_CARRY,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC2, 12)
+defframe(PARAM_SRC1, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_RP,`PARAM_SIZE')
+define(SAVE_VP,`PARAM_SRC1')
+define(SAVE_UP,`PARAM_DST')
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`vp', `%ebx')
+define(`cy', `%ecx')
+define(`r1', `%ecx')
+define(`r2', `%edx')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+deflit(`FRAME',0)
+
+PROLOGUE(M4_function_n)
+ xor cy, cy C carry
+L(start):
+ mov PARAM_SIZE, %eax C size
+ mov rp, SAVE_RP
+ mov PARAM_DST, rp
+ mov up, SAVE_UP
+ mov PARAM_SRC1, up
+ shr %eax C size >> 1
+ mov vp, SAVE_VP
+ mov PARAM_SRC2, vp
+ jz L(one) C size == 1
+ jc L(three) C size % 2 == 1
+
+ shr cy
+ mov (up), r2
+ lea 4(up), up
+ lea 4(vp), vp
+ lea -4(rp), rp
+ jmp L(entry)
+L(one):
+ shr cy
+ mov (up), r1
+ jmp L(end)
+L(three):
+ shr cy
+ mov (up), r1
+
+ ALIGN(16)
+L(oop):
+ M4_inst (vp), r1
+ lea 8(up), up
+ mov -4(up), r2
+ lea 8(vp), vp
+ mov r1, (rp)
+L(entry):
+ M4_inst -4(vp), r2
+ lea 8(rp), rp
+ dec %eax
+ mov (up), r1
+ mov r2, -4(rp)
+ jnz L(oop)
+
+L(end): C %eax is zero here
+ mov SAVE_UP, up
+ M4_inst (vp), r1
+ mov SAVE_VP, vp
+ mov r1, (rp)
+ adc %eax, %eax
+ mov SAVE_RP, rp
+ ret
+EPILOGUE()
+
+PROLOGUE(M4_function_nc)
+ mov PARAM_CARRY, cy C carry
+ jmp L(start)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/atom/aorslshC_n.asm b/gmp/mpn/x86/atom/aorslshC_n.asm
new file mode 100644
index 0000000000..75ace65e51
--- /dev/null
+++ b/gmp/mpn/x86/atom/aorslshC_n.asm
@@ -0,0 +1,247 @@
+dnl Intel Atom mpn_addlshC_n/mpn_sublshC_n -- rp[] = up[] +- (vp[] << C)
+
+dnl Contributed to the GNU project by Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C mp_limb_t mpn_addlshC_n_ip1 (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C mp_limb_t mpn_addlshC_nc_ip1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t carry);
+C mp_limb_t mpn_sublshC_n_ip1 (mp_ptr dst, mp_srcptr src, mp_size_t size,);
+C mp_limb_t mpn_sublshC_nc_ip1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_signed_limb_t borrow);
+
+defframe(PARAM_CORB, 16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+C mp_limb_t mpn_addlshC_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size,);
+C mp_limb_t mpn_addlshC_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size, mp_limb_t carry);
+C mp_limb_t mpn_sublshC_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size,);
+C mp_limb_t mpn_sublshC_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size, mp_limb_t borrow);
+
+C if src1 == dst, _ip1 is used
+
+C cycles/limb
+C dst!=src1,src2 dst==src1
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 7 6
+C AMD K6
+C AMD K7
+C AMD K8
+C AMD K10
+
+defframe(GPARAM_CORB, 20)
+defframe(GPARAM_SIZE, 16)
+defframe(GPARAM_SRC2, 12)
+
+dnl re-use parameter space
+define(SAVE_EBP,`PARAM_SIZE')
+define(SAVE_EBX,`PARAM_SRC')
+define(SAVE_UP,`PARAM_DST')
+
+define(M, eval(m4_lshift(1,LSH)))
+define(`rp', `%edi')
+define(`up', `%esi')
+
+ASM_START()
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(M4_ip_function_c)
+deflit(`FRAME',0)
+ movl PARAM_CORB, %ecx
+ movl %ecx, %edx
+ shr $LSH, %edx
+ andl $1, %edx
+ M4_opp %edx, %ecx
+ jmp L(start_nc)
+EPILOGUE()
+
+PROLOGUE(M4_ip_function)
+deflit(`FRAME',0)
+
+ xor %ecx, %ecx
+ xor %edx, %edx
+L(start_nc):
+ push rp FRAME_pushl()
+ mov PARAM_DST, rp
+ mov up, SAVE_UP
+ mov PARAM_SRC, up
+ mov %ebx, SAVE_EBX
+ mov PARAM_SIZE, %ebx C size
+L(inplace):
+ incl %ebx C size + 1
+ shr %ebx C (size+1)\2
+ mov %ebp, SAVE_EBP
+ jnc L(entry) C size odd
+
+ add %edx, %edx C size even
+ mov %ecx, %ebp
+ mov (up), %ecx
+ lea -4(rp), rp
+ lea (%ebp,%ecx,M), %eax
+ lea 4(up), up
+ jmp L(enteven)
+
+ ALIGN(16)
+L(oop):
+ lea (%ecx,%eax,M), %ebp
+ shr $RSH, %eax
+ mov 4(up), %ecx
+ add %edx, %edx
+ lea 8(up), up
+ M4_inst %ebp, (rp)
+ lea (%eax,%ecx,M), %eax
+
+L(enteven):
+ M4_inst %eax, 4(rp)
+ lea 8(rp), rp
+
+ sbb %edx, %edx
+ shr $RSH, %ecx
+
+L(entry):
+ mov (up), %eax
+ decl %ebx
+ jnz L(oop)
+
+ lea (%ecx,%eax,M), %ebp
+ shr $RSH, %eax
+ shr %edx
+ M4_inst %ebp, (rp)
+ mov SAVE_UP, up
+ adc $0, %eax
+ mov SAVE_EBP, %ebp
+ mov SAVE_EBX, %ebx
+ pop rp FRAME_popl()
+ ret
+EPILOGUE()
+
+PROLOGUE(M4_function_c)
+deflit(`FRAME',0)
+ movl GPARAM_CORB, %ecx
+ movl %ecx, %edx
+ shr $LSH, %edx
+ andl $1, %edx
+ M4_opp %edx, %ecx
+ jmp L(generic_nc)
+EPILOGUE()
+
+PROLOGUE(M4_function)
+deflit(`FRAME',0)
+
+ xor %ecx, %ecx
+ xor %edx, %edx
+L(generic_nc):
+ push rp FRAME_pushl()
+ mov PARAM_DST, rp
+ mov up, SAVE_UP
+ mov PARAM_SRC, up
+ cmp rp, up
+ mov %ebx, SAVE_EBX
+ jne L(general)
+ mov GPARAM_SIZE, %ebx C size
+ mov GPARAM_SRC2, up
+ jmp L(inplace)
+
+L(general):
+ mov GPARAM_SIZE, %eax C size
+ mov %ebx, SAVE_EBX
+ incl %eax C size + 1
+ mov up, %ebx C vp
+ mov GPARAM_SRC2, up C up
+ shr %eax C (size+1)\2
+ mov %ebp, SAVE_EBP
+ mov %eax, GPARAM_SIZE
+ jnc L(entry2) C size odd
+
+ add %edx, %edx C size even
+ mov %ecx, %ebp
+ mov (up), %ecx
+ lea -4(rp), rp
+ lea -4(%ebx), %ebx
+ lea (%ebp,%ecx,M), %eax
+ lea 4(up), up
+ jmp L(enteven2)
+
+ ALIGN(16)
+L(oop2):
+ lea (%ecx,%eax,M), %ebp
+ shr $RSH, %eax
+ mov 4(up), %ecx
+ add %edx, %edx
+ lea 8(up), up
+ mov (%ebx), %edx
+ M4_inst %ebp, %edx
+ lea (%eax,%ecx,M), %eax
+ mov %edx, (rp)
+L(enteven2):
+ mov 4(%ebx), %edx
+ lea 8(%ebx), %ebx
+ M4_inst %eax, %edx
+ mov %edx, 4(rp)
+ sbb %edx, %edx
+ shr $RSH, %ecx
+ lea 8(rp), rp
+L(entry2):
+ mov (up), %eax
+ decl GPARAM_SIZE
+ jnz L(oop2)
+
+ lea (%ecx,%eax,M), %ebp
+ shr $RSH, %eax
+ shr %edx
+ mov (%ebx), %edx
+ M4_inst %ebp, %edx
+ mov %edx, (rp)
+ mov SAVE_UP, up
+ adc $0, %eax
+ mov SAVE_EBP, %ebp
+ mov SAVE_EBX, %ebx
+ pop rp FRAME_popl()
+ ret
+EPILOGUE()
+
+ASM_END()
diff --git a/gmp/mpn/x86/atom/bdiv_q_1.asm b/gmp/mpn/x86/atom/bdiv_q_1.asm
new file mode 100644
index 0000000000..31e908ec44
--- /dev/null
+++ b/gmp/mpn/x86/atom/bdiv_q_1.asm
@@ -0,0 +1,35 @@
+dnl Intel Atom mpn_bdiv_q_1, mpn_pi1_bdiv_q_1 -- schoolbook Hensel
+dnl division by 1-limb divisor, returning quotient only.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_bdiv_q_1 mpn_pi1_bdiv_q_1)
+include_mpn(`x86/pentium/bdiv_q_1.asm')
diff --git a/gmp/mpn/x86/atom/cnd_add_n.asm b/gmp/mpn/x86/atom/cnd_add_n.asm
new file mode 100644
index 0000000000..50bf2ad64b
--- /dev/null
+++ b/gmp/mpn/x86/atom/cnd_add_n.asm
@@ -0,0 +1,113 @@
+dnl X86 mpn_cnd_add_n optimised for Intel Atom.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C P5 ?
+C P6 model 0-8,10-12 ?
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) ?
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) ?
+C P4 model 3-4 (Prescott) ?
+C Intel atom 4.67
+C AMD K6 ?
+C AMD K7 ?
+C AMD K8 ?
+
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`vp', `%ebp')
+define(`n', `%ecx')
+define(`cnd', `20(%esp)')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_cnd_add_n)
+ push %edi
+ push %esi
+ push %ebx
+ push %ebp
+
+ mov cnd, %eax C make cnd into a mask (1)
+ mov 24(%esp), rp
+ neg %eax C make cnd into a mask (1)
+ mov 28(%esp), up
+ sbb %eax, %eax C make cnd into a mask (1)
+ mov 32(%esp), vp
+ mov %eax, cnd C make cnd into a mask (1)
+ mov 36(%esp), n
+
+ xor %edx, %edx
+
+ shr $1, n
+ jnc L(top)
+
+ mov 0(vp), %eax
+ and cnd, %eax
+ lea 4(vp), vp
+ add 0(up), %eax
+ lea 4(rp), rp
+ lea 4(up), up
+ sbb %edx, %edx
+ mov %eax, -4(rp)
+ inc n
+ dec n
+ je L(end)
+
+L(top): sbb %edx, %edx
+ mov 0(vp), %eax
+ and cnd, %eax
+ lea 8(vp), vp
+ lea 8(rp), rp
+ mov -4(vp), %ebx
+ and cnd, %ebx
+ add %edx, %edx
+ adc 0(up), %eax
+ lea 8(up), up
+ mov %eax, -8(rp)
+ adc -4(up), %ebx
+ dec n
+ mov %ebx, -4(rp)
+ jne L(top)
+
+L(end): mov $0, %eax
+ adc %eax, %eax
+
+ pop %ebp
+ pop %ebx
+ pop %esi
+ pop %edi
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/atom/cnd_sub_n.asm b/gmp/mpn/x86/atom/cnd_sub_n.asm
new file mode 100644
index 0000000000..221bedca37
--- /dev/null
+++ b/gmp/mpn/x86/atom/cnd_sub_n.asm
@@ -0,0 +1,124 @@
+dnl X86 mpn_cnd_sub_n optimised for Intel Atom.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C P5 ?
+C P6 model 0-8,10-12 ?
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) ?
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) ?
+C P4 model 3-4 (Prescott) ?
+C Intel atom 5.67
+C AMD K6 ?
+C AMD K7 ?
+C AMD K8 ?
+
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`vp', `%ebp')
+define(`n', `%ecx')
+define(`cnd', `20(%esp)')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_cnd_sub_n)
+ push %edi
+ push %esi
+ push %ebx
+ push %ebp
+
+ mov cnd, %eax C make cnd into a mask (1)
+ mov 24(%esp), rp
+ neg %eax C make cnd into a mask (1)
+ mov 28(%esp), up
+ sbb %eax, %eax C make cnd into a mask (1)
+ mov 32(%esp), vp
+ mov %eax, cnd C make cnd into a mask (1)
+ mov 36(%esp), n
+
+ xor %edx, %edx
+
+ inc n
+ shr n
+ jnc L(ent)
+
+ mov 0(vp), %eax
+ and cnd, %eax
+ lea 4(vp), vp
+ mov 0(up), %edx
+ sub %eax, %edx
+ lea 4(rp), rp
+ lea 4(up), up
+ mov %edx, -4(rp)
+ sbb %edx, %edx C save cy
+
+L(ent): mov 0(vp), %ebx
+ and cnd, %ebx
+ add %edx, %edx C restore cy
+ mov 0(up), %edx
+ dec n
+ je L(end)
+
+L(top): sbb %ebx, %edx
+ mov 4(vp), %eax
+ mov %edx, 0(rp)
+ sbb %edx, %edx C save cy
+ mov 8(vp), %ebx
+ lea 8(up), up
+ and cnd, %ebx
+ and cnd, %eax
+ add %edx, %edx C restore cy
+ mov -4(up), %edx
+ lea 8(rp), rp
+ sbb %eax, %edx
+ mov %edx, -4(rp)
+ dec n
+ mov 0(up), %edx
+ lea 8(vp), vp
+ jne L(top)
+
+L(end): sbb %ebx, %edx
+ mov %edx, 0(rp)
+
+ mov $0, %eax
+ adc %eax, %eax
+
+ pop %ebp
+ pop %ebx
+ pop %esi
+ pop %edi
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/atom/dive_1.asm b/gmp/mpn/x86/atom/dive_1.asm
new file mode 100644
index 0000000000..71036a15a4
--- /dev/null
+++ b/gmp/mpn/x86/atom/dive_1.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_divexact_1)
+include_mpn(`x86/pentium/dive_1.asm')
diff --git a/gmp/mpn/x86/atom/gmp-mparam.h b/gmp/mpn/x86/atom/gmp-mparam.h
new file mode 100644
index 0000000000..45df12806c
--- /dev/null
+++ b/gmp/mpn/x86/atom/gmp-mparam.h
@@ -0,0 +1,201 @@
+/* Intel Atom/32 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 1667 MHz Pineview (Atom D510) */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-14, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 3
+#define MOD_1_UNNORM_THRESHOLD 5
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 11
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 10
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 13
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 4
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 31
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 74
+#define MUL_TOOM44_THRESHOLD 178
+#define MUL_TOOM6H_THRESHOLD 270
+#define MUL_TOOM8H_THRESHOLD 399
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 122
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 115
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 127
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 106
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 105
+#define SQR_TOOM4_THRESHOLD 178
+#define SQR_TOOM6_THRESHOLD 303
+#define SQR_TOOM8_THRESHOLD 527
+
+#define MULMID_TOOM42_THRESHOLD 54
+
+#define MULMOD_BNM1_THRESHOLD 13
+#define SQRMOD_BNM1_THRESHOLD 18
+
+#define MUL_FFT_MODF_THRESHOLD 380 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 380, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 39, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
+ { 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
+ { 47, 8}, { 95,10}, { 31, 9}, { 79,10}, \
+ { 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255, 9}, { 135,10}, { 79, 9}, \
+ { 159,10}, { 95, 9}, { 191,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511, 9}, { 271,10}, \
+ { 143, 9}, { 287, 8}, { 575,10}, { 159,11}, \
+ { 95,10}, { 191, 9}, { 383,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
+ { 543,10}, { 287, 9}, { 575,10}, { 303,11}, \
+ { 159,10}, { 319, 9}, { 639,10}, { 335, 9}, \
+ { 671,10}, { 351, 9}, { 703,11}, { 191,10}, \
+ { 383, 9}, { 767,10}, { 415, 9}, { 831,11}, \
+ { 223,10}, { 447,12}, { 127,11}, { 255,10}, \
+ { 543,11}, { 287,10}, { 607, 9}, { 1215,11}, \
+ { 319,10}, { 671,11}, { 351,10}, { 703,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,10}, \
+ { 831,11}, { 447,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
+ { 319,11}, { 735,12}, { 383,11}, { 831,12}, \
+ { 447,11}, { 959,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1151,12}, { 703,11}, \
+ { 1471,13}, { 383,12}, { 831,11}, { 1663,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1215,13}, \
+ { 639,12}, { 1471,11}, { 2943,13}, { 767,12}, \
+ { 1663,13}, { 895,12}, { 1919,14}, { 511,13}, \
+ { 1023,12}, { 2111,13}, { 1151,12}, { 2431,13}, \
+ { 1407,12}, { 2943,14}, { 767,13}, { 1663,12}, \
+ { 3455,13}, { 1919,15}, { 511,14}, { 1023,13}, \
+ { 2431,14}, { 1279,13}, { 2943,12}, { 5887,14}, \
+ { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 150
+#define MUL_FFT_THRESHOLD 4544
+
+#define SQR_FFT_MODF_THRESHOLD 340 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 340, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 12, 5}, { 25, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
+ { 31, 8}, { 63, 9}, { 39, 8}, { 79, 9}, \
+ { 47,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255,10}, { 79, 9}, { 159, 8}, { 319,10}, \
+ { 95, 9}, { 191,11}, { 63,10}, { 127, 9}, \
+ { 255, 8}, { 511, 9}, { 271,10}, { 143, 9}, \
+ { 287, 8}, { 575, 9}, { 303, 8}, { 607,10}, \
+ { 159, 9}, { 319,11}, { 95,10}, { 191, 9}, \
+ { 383,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,10}, { 287, 9}, \
+ { 575,10}, { 303, 9}, { 607,10}, { 319, 9}, \
+ { 639,10}, { 335, 9}, { 671,10}, { 351, 9}, \
+ { 703,11}, { 191,10}, { 383, 9}, { 767,10}, \
+ { 415,11}, { 223,10}, { 447,12}, { 127,11}, \
+ { 255,10}, { 543,11}, { 287,10}, { 607,11}, \
+ { 319,10}, { 671,11}, { 351,10}, { 703,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,10}, \
+ { 831,11}, { 479,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,11}, { 607,12}, { 319,11}, \
+ { 671,10}, { 1343,11}, { 735,12}, { 383,11}, \
+ { 831,12}, { 447,11}, { 959,13}, { 255,12}, \
+ { 511,11}, { 1087,12}, { 575,11}, { 1215,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1407,13}, \
+ { 383,12}, { 831,11}, { 1663,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1215,13}, { 639,12}, \
+ { 1471,13}, { 767,12}, { 1663,13}, { 895,12}, \
+ { 1791,14}, { 511,13}, { 1023,12}, { 2111,13}, \
+ { 1151,12}, { 2431,13}, { 1407,14}, { 767,13}, \
+ { 1663,12}, { 3455,13}, { 1791,15}, { 511,14}, \
+ { 1023,13}, { 2431,14}, { 1279,13}, { 2943,12}, \
+ { 5887,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 151
+#define SQR_FFT_THRESHOLD 2880
+
+#define MULLO_BASECASE_THRESHOLD 6
+#define MULLO_DC_THRESHOLD 48
+#define MULLO_MUL_N_THRESHOLD 8907
+
+#define DC_DIV_QR_THRESHOLD 59
+#define DC_DIVAPPR_Q_THRESHOLD 250
+#define DC_BDIV_QR_THRESHOLD 59
+#define DC_BDIV_Q_THRESHOLD 169
+
+#define INV_MULMOD_BNM1_THRESHOLD 38
+#define INV_NEWTON_THRESHOLD 246
+#define INV_APPR_THRESHOLD 246
+
+#define BINV_NEWTON_THRESHOLD 276
+#define REDC_1_TO_REDC_N_THRESHOLD 67
+
+#define MU_DIV_QR_THRESHOLD 1334
+#define MU_DIVAPPR_Q_THRESHOLD 1442
+#define MUPI_DIV_QR_THRESHOLD 114
+#define MU_BDIV_QR_THRESHOLD 1142
+#define MU_BDIV_Q_THRESHOLD 1334
+
+#define POWM_SEC_TABLE 1,22,98,416,1378
+
+#define MATRIX22_STRASSEN_THRESHOLD 13
+#define HGCD_THRESHOLD 133
+#define HGCD_APPR_THRESHOLD 169
+#define HGCD_REDUCE_THRESHOLD 2479
+#define GCD_DC_THRESHOLD 460
+#define GCDEXT_DC_THRESHOLD 342
+#define JACOBI_BASE_METHOD 3
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 23
+#define SET_STR_DC_THRESHOLD 321
+#define SET_STR_PRECOMPUTE_THRESHOLD 1099
+
+#define FAC_DSC_THRESHOLD 198
+#define FAC_ODD_THRESHOLD 34
diff --git a/gmp/mpn/x86/atom/logops_n.asm b/gmp/mpn/x86/atom/logops_n.asm
new file mode 100644
index 0000000000..3cb6d7310c
--- /dev/null
+++ b/gmp/mpn/x86/atom/logops_n.asm
@@ -0,0 +1,151 @@
+dnl Intel Atom mpn_and_n,...,mpn_xnor_n -- bitwise logical operations.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Marco Bodrato.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C op nop opn
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 3 3.5 3.5
+C AMD K6
+C AMD K7
+C AMD K8
+C AMD K10
+
+define(M4_choose_op,
+`ifdef(`OPERATION_$1',`
+define(`M4_function', `mpn_$1')
+define(`M4_want_pre', `$4')
+define(`M4_inst', `$3')
+define(`M4_want_post',`$2')
+')')
+define(M4pre, `ifelse(M4_want_pre, yes,`$1')')
+define(M4post,`ifelse(M4_want_post,yes,`$1')')
+
+M4_choose_op( and_n, , andl, )
+M4_choose_op( andn_n, , andl, yes)
+M4_choose_op( nand_n, yes, andl, )
+M4_choose_op( ior_n, , orl, )
+M4_choose_op( iorn_n, , orl, yes)
+M4_choose_op( nior_n, yes, orl, )
+M4_choose_op( xor_n, , xorl, )
+M4_choose_op( xnor_n, yes, xorl, )
+
+ifdef(`M4_function',,
+`m4_error(`Unrecognised or undefined OPERATION symbol
+')')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+C void M4_function (mp_ptr dst, mp_srcptr src2, mp_srcptr src1, mp_size_t size);
+C
+
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC1, 12)
+defframe(PARAM_SRC2, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_RP,`PARAM_SIZE')
+define(SAVE_VP,`PARAM_SRC1')
+define(SAVE_UP,`PARAM_DST')
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`vp', `%ebx')
+define(`cnt', `%eax')
+define(`r1', `%ecx')
+define(`r2', `%edx')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+deflit(`FRAME',0)
+
+PROLOGUE(M4_function)
+ mov PARAM_SIZE, cnt C size
+ mov rp, SAVE_RP
+ mov PARAM_DST, rp
+ mov up, SAVE_UP
+ mov PARAM_SRC1, up
+ shr cnt C size >> 1
+ mov vp, SAVE_VP
+ mov PARAM_SRC2, vp
+ mov (up), r1
+ jz L(end) C size == 1
+ jnc L(even) C size % 2 == 0
+
+ ALIGN(16)
+L(oop):
+M4pre(` notl_or_xorl_GMP_NUMB_MASK(r1)')
+ M4_inst (vp), r1
+ lea 8(up), up
+ mov -4(up), r2
+M4post(` notl_or_xorl_GMP_NUMB_MASK(r1)')
+ lea 8(vp), vp
+ mov r1, (rp)
+L(entry):
+M4pre(` notl_or_xorl_GMP_NUMB_MASK(r2)')
+ M4_inst -4(vp), r2
+ lea 8(rp), rp
+M4post(` notl_or_xorl_GMP_NUMB_MASK(r2)')
+ dec cnt
+ mov (up), r1
+ mov r2, -4(rp)
+ jnz L(oop)
+
+L(end):
+M4pre(` notl_or_xorl_GMP_NUMB_MASK(r1)')
+ mov SAVE_UP, up
+ M4_inst (vp), r1
+M4post(`notl_or_xorl_GMP_NUMB_MASK(r1)')
+ mov SAVE_VP, vp
+ mov r1, (rp)
+ mov SAVE_RP, rp
+ ret
+
+L(even):
+ mov r1, r2
+ lea 4(up), up
+ lea 4(vp), vp
+ lea -4(rp), rp
+ jmp L(entry)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/atom/lshift.asm b/gmp/mpn/x86/atom/lshift.asm
new file mode 100644
index 0000000000..f2c70dd3e8
--- /dev/null
+++ b/gmp/mpn/x86/atom/lshift.asm
@@ -0,0 +1,218 @@
+dnl Intel Atom mpn_lshift -- mpn left shift.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned cnt);
+
+C cycles/limb
+C cnt!=1 cnt==1
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 5 2.5
+C AMD K6
+C AMD K7
+C AMD K8
+C AMD K10
+
+defframe(PARAM_CNT, 16)
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_UP,`PARAM_CNT')
+define(VAR_COUNT,`PARAM_SIZE')
+define(SAVE_EBX,`PARAM_SRC')
+define(SAVE_EBP,`PARAM_DST')
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`cnt', `%ecx')
+
+ASM_START()
+ TEXT
+ ALIGN(8)
+deflit(`FRAME',0)
+PROLOGUE(mpn_lshift)
+ mov PARAM_CNT, cnt
+ mov PARAM_SIZE, %edx
+ mov up, SAVE_UP
+ mov PARAM_SRC, up
+ push rp FRAME_pushl()
+ mov PARAM_DST, rp
+
+C We can use faster code for shift-by-1 under certain conditions.
+ cmp $1,cnt
+ jne L(normal)
+ cmpl rp, up
+ jnc L(special) C jump if s_ptr + 1 >= res_ptr
+ leal (up,%edx,4),%eax
+ cmpl %eax,rp
+ jnc L(special) C jump if res_ptr >= s_ptr + size
+
+L(normal):
+ lea -4(up,%edx,4), up
+ mov %ebx, SAVE_EBX
+ lea -4(rp,%edx,4), rp
+
+ shr %edx
+ mov (up), %eax
+ mov %edx, VAR_COUNT
+ jnc L(evn)
+
+ mov %eax, %ebx
+ shl %cl, %ebx
+ neg cnt
+ shr %cl, %eax
+ test %edx, %edx
+ jnz L(gt1)
+ mov %ebx, (rp)
+ jmp L(quit)
+
+L(gt1): mov %ebp, SAVE_EBP
+ push %eax
+ mov -4(up), %eax
+ mov %eax, %ebp
+ shr %cl, %eax
+ jmp L(lo1)
+
+L(evn): mov %ebp, SAVE_EBP
+ neg cnt
+ mov %eax, %ebp
+ mov -4(up), %edx
+ shr %cl, %eax
+ mov %edx, %ebx
+ shr %cl, %edx
+ neg cnt
+ decl VAR_COUNT
+ lea 4(rp), rp
+ lea -4(up), up
+ jz L(end)
+ push %eax FRAME_pushl()
+
+ ALIGN(8)
+L(top): shl %cl, %ebp
+ or %ebp, %edx
+ shl %cl, %ebx
+ neg cnt
+ mov -4(up), %eax
+ mov %eax, %ebp
+ mov %edx, -4(rp)
+ shr %cl, %eax
+ lea -8(rp), rp
+L(lo1): mov -8(up), %edx
+ or %ebx, %eax
+ mov %edx, %ebx
+ shr %cl, %edx
+ lea -8(up), up
+ neg cnt
+ mov %eax, (rp)
+ decl VAR_COUNT
+ jg L(top)
+
+ pop %eax FRAME_popl()
+L(end):
+ shl %cl, %ebp
+ shl %cl, %ebx
+ or %ebp, %edx
+ mov SAVE_EBP, %ebp
+ mov %edx, -4(rp)
+ mov %ebx, -8(rp)
+
+L(quit):
+ mov SAVE_UP, up
+ mov SAVE_EBX, %ebx
+ pop rp FRAME_popl()
+ ret
+
+L(special):
+deflit(`FRAME',4)
+ lea 3(%edx), %eax C size + 3
+ dec %edx C size - 1
+ mov (up), %ecx
+ shr $2, %eax C (size + 3) / 4
+ and $3, %edx C (size - 1) % 4
+ jz L(goloop) C jmp if size == 1 (mod 4)
+ shr %edx
+ jnc L(odd) C jum if size == 3 (mod 4)
+
+ add %ecx, %ecx
+ lea 4(up), up
+ mov %ecx, (rp)
+ mov (up), %ecx
+ lea 4(rp), rp
+
+ dec %edx
+ jnz L(goloop) C jump if size == 0 (mod 4)
+L(odd): lea -8(up), up
+ lea -8(rp), rp
+ jmp L(sentry) C reached if size == 2 or 3 (mod 4)
+
+L(sloop):
+ adc %ecx, %ecx
+ mov 4(up), %edx
+ mov %ecx, (rp)
+ adc %edx, %edx
+ mov 8(up), %ecx
+ mov %edx, 4(rp)
+L(sentry):
+ adc %ecx, %ecx
+ mov 12(up), %edx
+ mov %ecx, 8(rp)
+ adc %edx, %edx
+ lea 16(up), up
+ mov %edx, 12(rp)
+ lea 16(rp), rp
+ mov (up), %ecx
+L(goloop):
+ decl %eax
+ jnz L(sloop)
+
+L(squit):
+ adc %ecx, %ecx
+ mov %ecx, (rp)
+ adc %eax, %eax
+
+ mov SAVE_UP, up
+ pop rp FRAME_popl()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/atom/lshiftc.asm b/gmp/mpn/x86/atom/lshiftc.asm
new file mode 100644
index 0000000000..5be53ed19d
--- /dev/null
+++ b/gmp/mpn/x86/atom/lshiftc.asm
@@ -0,0 +1,159 @@
+dnl Intel Atom mpn_lshiftc -- mpn left shift with complement.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C mp_limb_t mpn_lshiftc (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned cnt);
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 5.5
+C AMD K6
+C AMD K7
+C AMD K8
+C AMD K10
+
+defframe(PARAM_CNT, 16)
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_UP,`PARAM_CNT')
+define(VAR_COUNT,`PARAM_SIZE')
+define(SAVE_EBX,`PARAM_SRC')
+define(SAVE_EBP,`PARAM_DST')
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`cnt', `%ecx')
+
+ASM_START()
+ TEXT
+
+PROLOGUE(mpn_lshiftc)
+deflit(`FRAME',0)
+ mov PARAM_CNT, cnt
+ mov PARAM_SIZE, %edx
+ mov up, SAVE_UP
+ mov PARAM_SRC, up
+ push rp FRAME_pushl()
+ mov PARAM_DST, rp
+
+ lea -4(up,%edx,4), up
+ mov %ebx, SAVE_EBX
+ lea -4(rp,%edx,4), rp
+
+ shr %edx
+ mov (up), %eax
+ mov %edx, VAR_COUNT
+ jnc L(evn)
+
+ mov %eax, %ebx
+ shl %cl, %ebx
+ neg cnt
+ shr %cl, %eax
+ test %edx, %edx
+ jnz L(gt1)
+ not %ebx
+ mov %ebx, (rp)
+ jmp L(quit)
+
+L(gt1): mov %ebp, SAVE_EBP
+ push %eax
+ mov -4(up), %eax
+ mov %eax, %ebp
+ shr %cl, %eax
+ jmp L(lo1)
+
+L(evn): mov %ebp, SAVE_EBP
+ neg cnt
+ mov %eax, %ebp
+ mov -4(up), %edx
+ shr %cl, %eax
+ mov %edx, %ebx
+ shr %cl, %edx
+ neg cnt
+ decl VAR_COUNT
+ lea 4(rp), rp
+ lea -4(up), up
+ jz L(end)
+ push %eax FRAME_pushl()
+
+L(top): shl %cl, %ebp
+ or %ebp, %edx
+ shl %cl, %ebx
+ neg cnt
+ not %edx
+ mov -4(up), %eax
+ mov %eax, %ebp
+ mov %edx, -4(rp)
+ shr %cl, %eax
+ lea -8(rp), rp
+L(lo1): mov -8(up), %edx
+ or %ebx, %eax
+ mov %edx, %ebx
+ shr %cl, %edx
+ not %eax
+ lea -8(up), up
+ neg cnt
+ mov %eax, (rp)
+ decl VAR_COUNT
+ jg L(top)
+
+ pop %eax FRAME_popl()
+L(end):
+ shl %cl, %ebp
+ shl %cl, %ebx
+ or %ebp, %edx
+ mov SAVE_EBP, %ebp
+ not %edx
+ not %ebx
+ mov %edx, -4(rp)
+ mov %ebx, -8(rp)
+
+L(quit):
+ mov SAVE_UP, up
+ mov SAVE_EBX, %ebx
+ pop rp FRAME_popl()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/atom/mmx/copyd.asm b/gmp/mpn/x86/atom/mmx/copyd.asm
new file mode 100644
index 0000000000..b80fb033fe
--- /dev/null
+++ b/gmp/mpn/x86/atom/mmx/copyd.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom mpn_copyd -- copy limb vector, decrementing.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_copyd)
+include_mpn(`x86/k7/mmx/copyd.asm')
diff --git a/gmp/mpn/x86/atom/mmx/copyi.asm b/gmp/mpn/x86/atom/mmx/copyi.asm
new file mode 100644
index 0000000000..49b6b8d662
--- /dev/null
+++ b/gmp/mpn/x86/atom/mmx/copyi.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom mpn_copyi -- copy limb vector, incrementing.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_copyi)
+include_mpn(`x86/k7/mmx/copyi.asm')
diff --git a/gmp/mpn/x86/atom/mmx/hamdist.asm b/gmp/mpn/x86/atom/mmx/hamdist.asm
new file mode 100644
index 0000000000..3fe8253240
--- /dev/null
+++ b/gmp/mpn/x86/atom/mmx/hamdist.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom mpn_hamdist -- hamming distance.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_hamdist)
+include_mpn(`x86/k7/mmx/popham.asm')
diff --git a/gmp/mpn/x86/atom/mod_34lsub1.asm b/gmp/mpn/x86/atom/mod_34lsub1.asm
new file mode 100644
index 0000000000..6d57ba385d
--- /dev/null
+++ b/gmp/mpn/x86/atom/mod_34lsub1.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom mpn_mod_34lsub1 -- remainder modulo 2^24-1.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_mod_34lsub1)
+include_mpn(`x86/p6/mod_34lsub1.asm')
diff --git a/gmp/mpn/x86/atom/mode1o.asm b/gmp/mpn/x86/atom/mode1o.asm
new file mode 100644
index 0000000000..c9ee6bd2db
--- /dev/null
+++ b/gmp/mpn/x86/atom/mode1o.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom mpn_modexact_1_odd -- exact division style remainder.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_modexact_1_odd mpn_modexact_1c_odd)
+include_mpn(`x86/pentium/mode1o.asm')
diff --git a/gmp/mpn/x86/atom/rshift.asm b/gmp/mpn/x86/atom/rshift.asm
new file mode 100644
index 0000000000..1cb5dbefe9
--- /dev/null
+++ b/gmp/mpn/x86/atom/rshift.asm
@@ -0,0 +1,152 @@
+dnl Intel Atom mpn_rshift -- mpn right shift.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl Converted from AMD64 by Marco Bodrato.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned cnt);
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 5
+C AMD K6
+C AMD K7
+C AMD K8
+C AMD K10
+
+defframe(PARAM_CNT, 16)
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_UP,`PARAM_CNT')
+define(VAR_COUNT,`PARAM_SIZE')
+define(SAVE_EBX,`PARAM_SRC')
+define(SAVE_EBP,`PARAM_DST')
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`cnt', `%ecx')
+
+ASM_START()
+ TEXT
+ ALIGN(8)
+deflit(`FRAME',0)
+PROLOGUE(mpn_rshift)
+ mov PARAM_CNT, cnt
+ mov PARAM_SIZE, %edx
+ mov up, SAVE_UP
+ mov PARAM_SRC, up
+ push rp FRAME_pushl()
+ mov PARAM_DST, rp
+ mov %ebx, SAVE_EBX
+
+ shr %edx
+ mov (up), %eax
+ mov %edx, VAR_COUNT
+ jnc L(evn)
+
+ mov %eax, %ebx
+ shr %cl, %ebx
+ neg cnt
+ shl %cl, %eax
+ test %edx, %edx
+ jnz L(gt1)
+ mov %ebx, (rp)
+ jmp L(quit)
+
+L(gt1): mov %ebp, SAVE_EBP
+ push %eax
+ mov 4(up), %eax
+ mov %eax, %ebp
+ shl %cl, %eax
+ jmp L(lo1)
+
+L(evn): mov %ebp, SAVE_EBP
+ neg cnt
+ mov %eax, %ebp
+ mov 4(up), %edx
+ shl %cl, %eax
+ mov %edx, %ebx
+ shl %cl, %edx
+ neg cnt
+ decl VAR_COUNT
+ lea -4(rp), rp
+ lea 4(up), up
+ jz L(end)
+ push %eax FRAME_pushl()
+
+ ALIGN(8)
+L(top): shr %cl, %ebp
+ or %ebp, %edx
+ shr %cl, %ebx
+ neg cnt
+ mov 4(up), %eax
+ mov %eax, %ebp
+ mov %edx, 4(rp)
+ shl %cl, %eax
+ lea 8(rp), rp
+L(lo1): mov 8(up), %edx
+ or %ebx, %eax
+ mov %edx, %ebx
+ shl %cl, %edx
+ lea 8(up), up
+ neg cnt
+ mov %eax, (rp)
+ decl VAR_COUNT
+ jg L(top)
+
+ pop %eax FRAME_popl()
+L(end):
+ shr %cl, %ebp
+ shr %cl, %ebx
+ or %ebp, %edx
+ mov SAVE_EBP, %ebp
+ mov %edx, 4(rp)
+ mov %ebx, 8(rp)
+
+L(quit):
+ mov SAVE_UP, up
+ mov SAVE_EBX, %ebx
+ pop rp FRAME_popl()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/atom/sse2/aorsmul_1.asm b/gmp/mpn/x86/atom/sse2/aorsmul_1.asm
new file mode 100644
index 0000000000..969a14a919
--- /dev/null
+++ b/gmp/mpn/x86/atom/sse2/aorsmul_1.asm
@@ -0,0 +1,174 @@
+dnl x86-32 mpn_addmul_1 and mpn_submul_1 optimised for Intel Atom.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C cycles/limb
+C P5 -
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 8
+C AMD K6
+C AMD K7 -
+C AMD K8
+C AMD K10
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`n', `%ecx')
+
+ifdef(`OPERATION_addmul_1',`
+ define(ADDSUB, add)
+ define(func_1, mpn_addmul_1)
+ define(func_1c, mpn_addmul_1c)')
+ifdef(`OPERATION_submul_1',`
+ define(ADDSUB, sub)
+ define(func_1, mpn_submul_1)
+ define(func_1c, mpn_submul_1c)')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_addmul_1c mpn_submul_1 mpn_submul_1c)
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(func_1)
+ xor %edx, %edx
+L(ent): push %edi
+ push %esi
+ push %ebx
+ mov 16(%esp), rp
+ mov 20(%esp), up
+ mov 24(%esp), n
+ movd 28(%esp), %mm7
+ test $1, n
+ jz L(fi0or2)
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ shr $2, n
+ jnc L(fi1)
+
+L(fi3): lea -8(up), up
+ lea -8(rp), rp
+ movd 12(up), %mm1
+ movd %mm0, %ebx
+ pmuludq %mm7, %mm1
+ add $1, n C increment and clear carry
+ jmp L(lo3)
+
+L(fi1): movd %mm0, %ebx
+ jz L(wd1)
+ movd 4(up), %mm1
+ pmuludq %mm7, %mm1
+ jmp L(lo1)
+
+L(fi0or2):
+ movd (up), %mm1
+ pmuludq %mm7, %mm1
+ shr $2, n
+ movd 4(up), %mm0
+ jc L(fi2)
+ lea -4(up), up
+ lea -4(rp), rp
+ movd %mm1, %eax
+ pmuludq %mm7, %mm0
+ jmp L(lo0)
+
+L(fi2): lea 4(up), up
+ add $1, n C increment and clear carry
+ movd %mm1, %eax
+ lea -12(rp), rp
+ jmp L(lo2)
+
+C ALIGN(16) C alignment seems irrelevant
+L(top): movd 4(up), %mm1
+ adc $0, %edx
+ ADDSUB %eax, 12(rp)
+ movd %mm0, %ebx
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+L(lo1): psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ adc $0, %edx
+ ADDSUB %ebx, (rp)
+L(lo0): psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ movd %mm0, %ebx
+ movd 12(up), %mm1
+ pmuludq %mm7, %mm1
+ adc $0, %edx
+ ADDSUB %eax, 4(rp)
+L(lo3): psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ lea 16(up), up
+ movd (up), %mm0
+ adc $0, %edx
+ ADDSUB %ebx, 8(rp)
+L(lo2): psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ pmuludq %mm7, %mm0
+ dec n
+ jnz L(top)
+
+L(end): adc n, %edx C n is zero here
+ ADDSUB %eax, 12(rp)
+ movd %mm0, %ebx
+ lea 16(rp), rp
+L(wd1): psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %eax
+ adc n, %eax
+ ADDSUB %ebx, (rp)
+ emms
+ adc n, %eax
+ pop %ebx
+ pop %esi
+ pop %edi
+ ret
+EPILOGUE()
+PROLOGUE(func_1c)
+ mov 20(%esp), %edx C carry
+ jmp L(ent)
+EPILOGUE()
diff --git a/gmp/mpn/x86/atom/sse2/bdiv_dbm1c.asm b/gmp/mpn/x86/atom/sse2/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..782e914019
--- /dev/null
+++ b/gmp/mpn/x86/atom/sse2/bdiv_dbm1c.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom mpn_bdiv_dbm1.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_bdiv_dbm1c)
+include_mpn(`x86/pentium4/sse2/bdiv_dbm1c.asm')
diff --git a/gmp/mpn/x86/atom/sse2/divrem_1.asm b/gmp/mpn/x86/atom/sse2/divrem_1.asm
new file mode 100644
index 0000000000..f84709a22e
--- /dev/null
+++ b/gmp/mpn/x86/atom/sse2/divrem_1.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom mpn_divrem_1 -- mpn by limb division.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_preinv_divrem_1 mpn_divrem_1c mpn_divrem_1)
+include_mpn(`x86/pentium4/sse2/divrem_1.asm')
diff --git a/gmp/mpn/x86/atom/sse2/mod_1_1.asm b/gmp/mpn/x86/atom/sse2/mod_1_1.asm
new file mode 100644
index 0000000000..ae6581d9b6
--- /dev/null
+++ b/gmp/mpn/x86/atom/sse2/mod_1_1.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom/SSE2 mpn_mod_1_1.
+
+dnl Copyright 2009, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_mod_1_1p)
+include_mpn(`x86/pentium4/sse2/mod_1_1.asm')
diff --git a/gmp/mpn/x86/atom/sse2/mod_1_4.asm b/gmp/mpn/x86/atom/sse2/mod_1_4.asm
new file mode 100644
index 0000000000..31faa3f0a3
--- /dev/null
+++ b/gmp/mpn/x86/atom/sse2/mod_1_4.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom/SSE2 mpn_mod_1_4.
+
+dnl Copyright 2009, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_mod_1s_4p)
+include_mpn(`x86/pentium4/sse2/mod_1_4.asm')
diff --git a/gmp/mpn/x86/atom/sse2/mul_1.asm b/gmp/mpn/x86/atom/sse2/mul_1.asm
new file mode 100644
index 0000000000..aa3bb974bb
--- /dev/null
+++ b/gmp/mpn/x86/atom/sse2/mul_1.asm
@@ -0,0 +1,124 @@
+dnl Intel Atom mpn_mul_1.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C cycles/limb
+C P5 -
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 7.5
+C AMD K6 -
+C AMD K7 -
+C AMD K8
+C AMD K10
+
+defframe(PARAM_CARRY,20)
+defframe(PARAM_MUL, 16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+define(`rp', `%edx')
+define(`up', `%esi')
+define(`n', `%ecx')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+deflit(`FRAME',0)
+
+PROLOGUE(mpn_mul_1c)
+ movd PARAM_CARRY, %mm6 C carry
+ jmp L(ent)
+EPILOGUE()
+
+ ALIGN(8) C for compact code
+PROLOGUE(mpn_mul_1)
+ pxor %mm6, %mm6
+L(ent): push %esi FRAME_pushl()
+ mov PARAM_SRC, up
+ mov PARAM_SIZE, %eax C size
+ movd PARAM_MUL, %mm7
+ movd (up), %mm0
+ mov %eax, n
+ and $3, %eax
+ pmuludq %mm7, %mm0
+ mov PARAM_DST, rp
+ jz L(lo0)
+ cmp $2, %eax
+ lea -16(up,%eax,4),up
+ lea -16(rp,%eax,4),rp
+ jc L(lo1)
+ jz L(lo2)
+ jmp L(lo3)
+
+ ALIGN(16)
+L(top): movd (up), %mm0
+ pmuludq %mm7, %mm0
+ psrlq $32, %mm6
+ lea 16(rp), rp
+L(lo0): paddq %mm0, %mm6
+ movd 4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, (rp)
+ psrlq $32, %mm6
+L(lo3): paddq %mm0, %mm6
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, 4(rp)
+ psrlq $32, %mm6
+L(lo2): paddq %mm0, %mm6
+ movd 12(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, 8(rp)
+ psrlq $32, %mm6
+L(lo1): paddq %mm0, %mm6
+ sub $4, n
+ movd %mm6, 12(rp)
+ lea 16(up), up
+ ja L(top)
+
+ psrlq $32, %mm6
+ movd %mm6, %eax
+ emms
+ pop %esi FRAME_popl()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/atom/sse2/mul_basecase.asm b/gmp/mpn/x86/atom/sse2/mul_basecase.asm
new file mode 100644
index 0000000000..97d3aeb5ad
--- /dev/null
+++ b/gmp/mpn/x86/atom/sse2/mul_basecase.asm
@@ -0,0 +1,501 @@
+dnl x86 mpn_mul_basecase -- Multiply two limb vectors and store the result in
+dnl a third limb vector.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO
+C * Check if 'jmp N(%esp)' is well-predicted enough to allow us to combine the
+C 4 large loops into one; we could use it for the outer loop branch.
+C * Optimise code outside of inner loops.
+C * Write combined addmul_1 feed-in a wind-down code, and use when iterating
+C outer each loop. ("Overlapping software pipelining")
+C * Postpone push of ebx until we know vn > 1. Perhaps use caller-saves regs
+C for inlined mul_1, allowing us to postpone all pushes.
+C * Perhaps write special code for vn <= un < M, for some small M.
+
+C void mpn_mul_basecase (mp_ptr wp,
+C mp_srcptr xp, mp_size_t xn,
+C mp_srcptr yp, mp_size_t yn);
+C
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`un', `%ecx')
+define(`vp', `%ebp')
+define(`vn', `36(%esp)')
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_basecase)
+ push %edi
+ push %esi
+ push %ebx
+ push %ebp
+ mov 20(%esp), rp
+ mov 24(%esp), up
+ mov 28(%esp), un
+ mov 32(%esp), vp
+
+ movd (up), %mm0
+ movd (vp), %mm7
+ pmuludq %mm7, %mm0
+ pxor %mm6, %mm6
+
+ mov un, %eax
+ and $3, %eax
+ jz L(of0)
+ cmp $2, %eax
+ jc L(of1)
+ jz L(of2)
+
+C ================================================================
+ jmp L(m3)
+ ALIGN(16)
+L(lm3): movd -4(up), %mm0
+ pmuludq %mm7, %mm0
+ psrlq $32, %mm6
+ lea 16(rp), rp
+ paddq %mm0, %mm6
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -4(rp)
+ psrlq $32, %mm6
+L(m3): paddq %mm0, %mm6
+ movd 4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, (rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, 4(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ sub $4, un
+ movd %mm6, 8(rp)
+ lea 16(up), up
+ ja L(lm3)
+
+ psrlq $32, %mm6
+ movd %mm6, 12(rp)
+
+ decl vn
+ jz L(done)
+ lea -8(rp), rp
+
+L(ol3): mov 28(%esp), un
+ neg un
+ lea 4(vp), vp
+ movd (vp), %mm7 C read next V limb
+ mov 24(%esp), up
+ lea 16(rp,un,4), rp
+
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ sar $2, un
+ movd 4(up), %mm1
+ movd %mm0, %ebx
+ pmuludq %mm7, %mm1
+ lea -8(up), up
+ xor %edx, %edx C zero edx and CF
+ jmp L(a3)
+
+L(la3): movd 4(up), %mm1
+ adc $0, %edx
+ add %eax, 12(rp)
+ movd %mm0, %ebx
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ adc $0, %edx
+ add %ebx, (rp)
+ psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ movd %mm0, %ebx
+ movd 12(up), %mm1
+ pmuludq %mm7, %mm1
+ adc $0, %edx
+ add %eax, 4(rp)
+L(a3): psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ lea 16(up), up
+ movd (up), %mm0
+ adc $0, %edx
+ add %ebx, 8(rp)
+ psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ pmuludq %mm7, %mm0
+ inc un
+ jnz L(la3)
+
+ adc un, %edx C un is zero here
+ add %eax, 12(rp)
+ movd %mm0, %ebx
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %eax
+ adc un, %eax
+ add %ebx, 16(rp)
+ adc un, %eax
+ mov %eax, 20(rp)
+
+ decl vn
+ jnz L(ol3)
+ jmp L(done)
+
+C ================================================================
+ ALIGN(16)
+L(lm0): movd (up), %mm0
+ pmuludq %mm7, %mm0
+ psrlq $32, %mm6
+ lea 16(rp), rp
+L(of0): paddq %mm0, %mm6
+ movd 4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, (rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, 4(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd 12(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, 8(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ sub $4, un
+ movd %mm6, 12(rp)
+ lea 16(up), up
+ ja L(lm0)
+
+ psrlq $32, %mm6
+ movd %mm6, 16(rp)
+
+ decl vn
+ jz L(done)
+ lea -4(rp), rp
+
+L(ol0): mov 28(%esp), un
+ neg un
+ lea 4(vp), vp
+ movd (vp), %mm7 C read next V limb
+ mov 24(%esp), up
+ lea 20(rp,un,4), rp
+
+ movd (up), %mm1
+ pmuludq %mm7, %mm1
+ sar $2, un
+ movd 4(up), %mm0
+ lea -4(up), up
+ movd %mm1, %eax
+ pmuludq %mm7, %mm0
+ xor %edx, %edx C zero edx and CF
+ jmp L(a0)
+
+L(la0): movd 4(up), %mm1
+ adc $0, %edx
+ add %eax, 12(rp)
+ movd %mm0, %ebx
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ adc $0, %edx
+ add %ebx, (rp)
+L(a0): psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ movd %mm0, %ebx
+ movd 12(up), %mm1
+ pmuludq %mm7, %mm1
+ adc $0, %edx
+ add %eax, 4(rp)
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ lea 16(up), up
+ movd (up), %mm0
+ adc $0, %edx
+ add %ebx, 8(rp)
+ psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ pmuludq %mm7, %mm0
+ inc un
+ jnz L(la0)
+
+ adc un, %edx C un is zero here
+ add %eax, 12(rp)
+ movd %mm0, %ebx
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %eax
+ adc un, %eax
+ add %ebx, 16(rp)
+ adc un, %eax
+ mov %eax, 20(rp)
+
+ decl vn
+ jnz L(ol0)
+ jmp L(done)
+
+C ================================================================
+ ALIGN(16)
+L(lm1): movd -12(up), %mm0
+ pmuludq %mm7, %mm0
+ psrlq $32, %mm6
+ lea 16(rp), rp
+ paddq %mm0, %mm6
+ movd -8(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -12(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd -4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -8(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -4(rp)
+ psrlq $32, %mm6
+L(of1): paddq %mm0, %mm6
+ sub $4, un
+ movd %mm6, (rp)
+ lea 16(up), up
+ ja L(lm1)
+
+ psrlq $32, %mm6
+ movd %mm6, 4(rp)
+
+ decl vn
+ jz L(done)
+ lea -16(rp), rp
+
+L(ol1): mov 28(%esp), un
+ neg un
+ lea 4(vp), vp
+ movd (vp), %mm7 C read next V limb
+ mov 24(%esp), up
+ lea 24(rp,un,4), rp
+
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ sar $2, un
+ movd %mm0, %ebx
+ movd 4(up), %mm1
+ pmuludq %mm7, %mm1
+ xor %edx, %edx C zero edx and CF
+ inc un
+ jmp L(a1)
+
+L(la1): movd 4(up), %mm1
+ adc $0, %edx
+ add %eax, 12(rp)
+ movd %mm0, %ebx
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+L(a1): psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ adc $0, %edx
+ add %ebx, (rp)
+ psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ movd %mm0, %ebx
+ movd 12(up), %mm1
+ pmuludq %mm7, %mm1
+ adc $0, %edx
+ add %eax, 4(rp)
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ lea 16(up), up
+ movd (up), %mm0
+ adc $0, %edx
+ add %ebx, 8(rp)
+ psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ pmuludq %mm7, %mm0
+ inc un
+ jnz L(la1)
+
+ adc un, %edx C un is zero here
+ add %eax, 12(rp)
+ movd %mm0, %ebx
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %eax
+ adc un, %eax
+ add %ebx, 16(rp)
+ adc un, %eax
+ mov %eax, 20(rp)
+
+ decl vn
+ jnz L(ol1)
+ jmp L(done)
+
+C ================================================================
+ ALIGN(16)
+L(lm2): movd -8(up), %mm0
+ pmuludq %mm7, %mm0
+ psrlq $32, %mm6
+ lea 16(rp), rp
+ paddq %mm0, %mm6
+ movd -4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -8(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -4(rp)
+ psrlq $32, %mm6
+L(of2): paddq %mm0, %mm6
+ movd 4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, (rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ sub $4, un
+ movd %mm6, 4(rp)
+ lea 16(up), up
+ ja L(lm2)
+
+ psrlq $32, %mm6
+ movd %mm6, 8(rp)
+
+ decl vn
+ jz L(done)
+ lea -12(rp), rp
+
+L(ol2): mov 28(%esp), un
+ neg un
+ lea 4(vp), vp
+ movd (vp), %mm7 C read next V limb
+ mov 24(%esp), up
+ lea 12(rp,un,4), rp
+
+ movd (up), %mm1
+ pmuludq %mm7, %mm1
+ sar $2, un
+ movd 4(up), %mm0
+ lea 4(up), up
+ movd %mm1, %eax
+ xor %edx, %edx C zero edx and CF
+ jmp L(lo2)
+
+L(la2): movd 4(up), %mm1
+ adc $0, %edx
+ add %eax, 12(rp)
+ movd %mm0, %ebx
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ adc $0, %edx
+ add %ebx, (rp)
+ psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ movd %mm0, %ebx
+ movd 12(up), %mm1
+ pmuludq %mm7, %mm1
+ adc $0, %edx
+ add %eax, 4(rp)
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %edx
+ movd %mm1, %eax
+ lea 16(up), up
+ movd (up), %mm0
+ adc $0, %edx
+ add %ebx, 8(rp)
+L(lo2): psrlq $32, %mm1
+ adc %edx, %eax
+ movd %mm1, %edx
+ pmuludq %mm7, %mm0
+ inc un
+ jnz L(la2)
+
+ adc un, %edx C un is zero here
+ add %eax, 12(rp)
+ movd %mm0, %ebx
+ psrlq $32, %mm0
+ adc %edx, %ebx
+ movd %mm0, %eax
+ adc un, %eax
+ add %ebx, 16(rp)
+ adc un, %eax
+ mov %eax, 20(rp)
+
+ decl vn
+ jnz L(ol2)
+C jmp L(done)
+
+C ================================================================
+L(done):
+ emms
+ pop %ebp
+ pop %ebx
+ pop %esi
+ pop %edi
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/atom/sse2/popcount.asm b/gmp/mpn/x86/atom/sse2/popcount.asm
new file mode 100644
index 0000000000..7847aec8e6
--- /dev/null
+++ b/gmp/mpn/x86/atom/sse2/popcount.asm
@@ -0,0 +1,35 @@
+dnl Intel Atom mpn_popcount -- population count.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+MULFUNC_PROLOGUE(mpn_popcount)
+include_mpn(`x86/pentium4/sse2/popcount.asm')
diff --git a/gmp/mpn/x86/atom/sse2/sqr_basecase.asm b/gmp/mpn/x86/atom/sse2/sqr_basecase.asm
new file mode 100644
index 0000000000..af19ed854d
--- /dev/null
+++ b/gmp/mpn/x86/atom/sse2/sqr_basecase.asm
@@ -0,0 +1,634 @@
+dnl x86 mpn_sqr_basecase -- square an mpn number, optimised for atom.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO
+C * Check if 'jmp N(%esp)' is well-predicted enough to allow us to combine the
+C 4 large loops into one; we could use it for the outer loop branch.
+C * Optimise code outside of inner loops.
+C * Write combined addmul_1 feed-in a wind-down code, and use when iterating
+C outer each loop. ("Overlapping software pipelining")
+C * Perhaps use caller-saves regs for inlined mul_1, allowing us to postpone
+C all pushes.
+C * Perhaps write special code for n < M, for some small M.
+C * Replace inlined addmul_1 with smaller code from aorsmul_1.asm, or perhaps
+C with even less pipelined code.
+C * We run the outer loop until we have a 2-limb by 1-limb addmul_1 left.
+C Consider breaking out earlier, saving high the cost of short loops.
+
+C void mpn_sqr_basecase (mp_ptr wp,
+C mp_srcptr xp, mp_size_t xn);
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`n', `%ecx')
+
+define(`un', `%ebp')
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sqr_basecase)
+ push %edi
+ push %esi
+ mov 12(%esp), rp
+ mov 16(%esp), up
+ mov 20(%esp), n
+
+ lea 4(rp), rp C write triangular product starting at rp[1]
+ dec n
+ movd (up), %mm7
+
+ jz L(one)
+ lea 4(up), up
+ push %ebx
+ push %ebp
+ mov n, %eax
+
+ movd (up), %mm0
+ neg n
+ pmuludq %mm7, %mm0
+ pxor %mm6, %mm6
+ mov n, un
+
+ and $3, %eax
+ jz L(of0)
+ cmp $2, %eax
+ jc L(of1)
+ jz L(of2)
+
+C ================================================================
+ jmp L(m3)
+ ALIGN(16)
+L(lm3): movd -4(up), %mm0
+ pmuludq %mm7, %mm0
+ psrlq $32, %mm6
+ lea 16(rp), rp
+ paddq %mm0, %mm6
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -4(rp)
+ psrlq $32, %mm6
+L(m3): paddq %mm0, %mm6
+ movd 4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, (rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, 4(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ add $4, un
+ movd %mm6, 8(rp)
+ lea 16(up), up
+ js L(lm3)
+
+ psrlq $32, %mm6
+ movd %mm6, 12(rp)
+
+ inc n
+C jz L(done)
+ lea -12(up), up
+ lea 4(rp), rp
+ jmp L(ol2)
+
+C ================================================================
+ ALIGN(16)
+L(lm0): movd (up), %mm0
+ pmuludq %mm7, %mm0
+ psrlq $32, %mm6
+ lea 16(rp), rp
+L(of0): paddq %mm0, %mm6
+ movd 4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, (rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, 4(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd 12(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, 8(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ add $4, un
+ movd %mm6, 12(rp)
+ lea 16(up), up
+ js L(lm0)
+
+ psrlq $32, %mm6
+ movd %mm6, 16(rp)
+
+ inc n
+C jz L(done)
+ lea -8(up), up
+ lea 8(rp), rp
+ jmp L(ol3)
+
+C ================================================================
+ ALIGN(16)
+L(lm1): movd -12(up), %mm0
+ pmuludq %mm7, %mm0
+ psrlq $32, %mm6
+ lea 16(rp), rp
+ paddq %mm0, %mm6
+ movd -8(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -12(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd -4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -8(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -4(rp)
+ psrlq $32, %mm6
+L(of1): paddq %mm0, %mm6
+ add $4, un
+ movd %mm6, (rp)
+ lea 16(up), up
+ js L(lm1)
+
+ psrlq $32, %mm6
+ movd %mm6, 4(rp)
+
+ inc n
+ jz L(done) C goes away when we add special n=2 code
+ lea -20(up), up
+ lea -4(rp), rp
+ jmp L(ol0)
+
+C ================================================================
+ ALIGN(16)
+L(lm2): movd -8(up), %mm0
+ pmuludq %mm7, %mm0
+ psrlq $32, %mm6
+ lea 16(rp), rp
+ paddq %mm0, %mm6
+ movd -4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -8(rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, -4(rp)
+ psrlq $32, %mm6
+L(of2): paddq %mm0, %mm6
+ movd 4(up), %mm0
+ pmuludq %mm7, %mm0
+ movd %mm6, (rp)
+ psrlq $32, %mm6
+ paddq %mm0, %mm6
+ add $4, un
+ movd %mm6, 4(rp)
+ lea 16(up), up
+ js L(lm2)
+
+ psrlq $32, %mm6
+ movd %mm6, 8(rp)
+
+ inc n
+C jz L(done)
+ lea -16(up), up
+C lea (rp), rp
+C jmp L(ol1)
+
+C ================================================================
+
+L(ol1): lea 4(up,n,4), up
+ movd (up), %mm7 C read next U invariant limb
+ lea 8(rp,n,4), rp
+ mov n, un
+
+ movd 4(up), %mm1
+ pmuludq %mm7, %mm1
+ sar $2, un
+ movd %mm1, %ebx
+ inc un
+ jz L(re1)
+
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ xor %edx, %edx C zero edx and CF
+ jmp L(a1)
+
+L(la1): adc $0, %edx
+ add %ebx, 12(rp)
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ adc $0, %edx
+ add %eax, (rp)
+L(a1): psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %edx
+ movd %mm0, %eax
+ movd 12(up), %mm1
+ pmuludq %mm7, %mm1
+ adc $0, %edx
+ add %ebx, 4(rp)
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ lea 16(up), up
+ movd (up), %mm0
+ adc $0, %edx
+ add %eax, 8(rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %edx
+ pmuludq %mm7, %mm0
+ inc un
+ movd 4(up), %mm1
+ jnz L(la1)
+
+ adc un, %edx C un is zero here
+ add %ebx, 12(rp)
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ adc un, %edx
+ add %eax, (rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %eax
+ adc un, %eax
+ add %ebx, 4(rp)
+ adc un, %eax
+ mov %eax, 8(rp)
+
+ inc n
+
+C ================================================================
+
+L(ol0): lea (up,n,4), up
+ movd 4(up), %mm7 C read next U invariant limb
+ lea 4(rp,n,4), rp
+ mov n, un
+
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ sar $2, un
+ movd 12(up), %mm1
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ xor %edx, %edx C zero edx and CF
+ jmp L(a0)
+
+L(la0): adc $0, %edx
+ add %ebx, 12(rp)
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ adc $0, %edx
+ add %eax, (rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %edx
+ movd %mm0, %eax
+ movd 12(up), %mm1
+ pmuludq %mm7, %mm1
+ adc $0, %edx
+ add %ebx, 4(rp)
+L(a0): psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ lea 16(up), up
+ movd (up), %mm0
+ adc $0, %edx
+ add %eax, 8(rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %edx
+ pmuludq %mm7, %mm0
+ inc un
+ movd 4(up), %mm1
+ jnz L(la0)
+
+ adc un, %edx C un is zero here
+ add %ebx, 12(rp)
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ adc un, %edx
+ add %eax, (rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %eax
+ adc un, %eax
+ add %ebx, 4(rp)
+ adc un, %eax
+ mov %eax, 8(rp)
+
+ inc n
+
+C ================================================================
+
+L(ol3): lea 12(up,n,4), up
+ movd -8(up), %mm7 C read next U invariant limb
+ lea (rp,n,4), rp C put rp back
+ mov n, un
+
+ movd -4(up), %mm1
+ pmuludq %mm7, %mm1
+ sar $2, un
+ movd %mm1, %ebx
+ movd (up), %mm0
+ xor %edx, %edx C zero edx and CF
+ jmp L(a3)
+
+L(la3): adc $0, %edx
+ add %ebx, 12(rp)
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ adc $0, %edx
+ add %eax, (rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %edx
+ movd %mm0, %eax
+ movd 12(up), %mm1
+ pmuludq %mm7, %mm1
+ adc $0, %edx
+ add %ebx, 4(rp)
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ lea 16(up), up
+ movd (up), %mm0
+ adc $0, %edx
+ add %eax, 8(rp)
+L(a3): psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %edx
+ pmuludq %mm7, %mm0
+ inc un
+ movd 4(up), %mm1
+ jnz L(la3)
+
+ adc un, %edx C un is zero here
+ add %ebx, 12(rp)
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ adc un, %edx
+ add %eax, (rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %eax
+ adc un, %eax
+ add %ebx, 4(rp)
+ adc un, %eax
+ mov %eax, 8(rp)
+
+ inc n
+
+C ================================================================
+
+L(ol2): lea 8(up,n,4), up
+ movd -4(up), %mm7 C read next U invariant limb
+ lea 12(rp,n,4), rp
+ mov n, un
+
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ xor %edx, %edx
+ sar $2, un
+ movd 4(up), %mm1
+ test un, un C clear carry
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ inc un
+ jnz L(a2)
+ jmp L(re2)
+
+L(la2): adc $0, %edx
+ add %ebx, 12(rp)
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+L(a2): psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ movd 8(up), %mm0
+ pmuludq %mm7, %mm0
+ adc $0, %edx
+ add %eax, (rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %edx
+ movd %mm0, %eax
+ movd 12(up), %mm1
+ pmuludq %mm7, %mm1
+ adc $0, %edx
+ add %ebx, 4(rp)
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ lea 16(up), up
+ movd (up), %mm0
+ adc $0, %edx
+ add %eax, 8(rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %edx
+ pmuludq %mm7, %mm0
+ inc un
+ movd 4(up), %mm1
+ jnz L(la2)
+
+ adc un, %edx C un is zero here
+ add %ebx, 12(rp)
+ movd %mm0, %eax
+ pmuludq %mm7, %mm1
+ lea 16(rp), rp
+ psrlq $32, %mm0
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ adc un, %edx
+ add %eax, (rp)
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %eax
+ adc un, %eax
+ add %ebx, 4(rp)
+ adc un, %eax
+ mov %eax, 8(rp)
+
+ inc n
+ jmp L(ol1)
+
+C ================================================================
+L(re2): psrlq $32, %mm0
+ movd (up), %mm7 C read next U invariant limb
+ adc %edx, %eax
+ movd %mm0, %edx
+ movd %mm1, %ebx
+ adc un, %edx
+ add %eax, (rp)
+ lea 4(rp), rp
+ psrlq $32, %mm1
+ adc %edx, %ebx
+ movd %mm1, %eax
+ movd 4(up), %mm1
+ adc un, %eax
+ add %ebx, (rp)
+ pmuludq %mm7, %mm1
+ adc un, %eax
+ mov %eax, 4(rp)
+ movd %mm1, %ebx
+
+L(re1): psrlq $32, %mm1
+ add %ebx, 4(rp)
+ movd %mm1, %eax
+ adc un, %eax
+ xor n, n C make n zeroness assumption below true
+ mov %eax, 8(rp)
+
+L(done): C n is zero here
+ mov 24(%esp), up
+ mov 28(%esp), %eax
+
+ movd (up), %mm0
+ inc %eax
+ pmuludq %mm0, %mm0
+ lea 4(up), up
+ mov 20(%esp), rp
+ shr %eax
+ movd %mm0, (rp)
+ psrlq $32, %mm0
+ lea -12(rp), rp
+ mov %eax, 28(%esp)
+ jnc L(odd)
+
+ movd %mm0, %ebp
+ movd (up), %mm0
+ lea 8(rp), rp
+ pmuludq %mm0, %mm0
+ lea -4(up), up
+ add 8(rp), %ebp
+ movd %mm0, %edx
+ adc 12(rp), %edx
+ rcr n
+ jmp L(ent)
+
+C ALIGN(16) C alignment seems irrelevant
+L(top): movd (up), %mm1
+ adc n, n
+ movd %mm0, %eax
+ pmuludq %mm1, %mm1
+ movd 4(up), %mm0
+ adc (rp), %eax
+ movd %mm1, %ebx
+ pmuludq %mm0, %mm0
+ psrlq $32, %mm1
+ adc 4(rp), %ebx
+ movd %mm1, %ebp
+ movd %mm0, %edx
+ adc 8(rp), %ebp
+ adc 12(rp), %edx
+ rcr n C FIXME: isn't this awfully slow on atom???
+ adc %eax, (rp)
+ adc %ebx, 4(rp)
+L(ent): lea 8(up), up
+ adc %ebp, 8(rp)
+ psrlq $32, %mm0
+ adc %edx, 12(rp)
+L(odd): decl 28(%esp)
+ lea 16(rp), rp
+ jnz L(top)
+
+L(end): adc n, n
+ movd %mm0, %eax
+ adc n, %eax
+ mov %eax, (rp)
+
+L(rtn): emms
+ pop %ebp
+ pop %ebx
+ pop %esi
+ pop %edi
+ ret
+
+L(one): pmuludq %mm7, %mm7
+ movq %mm7, -4(rp)
+ emms
+ pop %esi
+ pop %edi
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/atom/sublsh1_n.asm b/gmp/mpn/x86/atom/sublsh1_n.asm
new file mode 100644
index 0000000000..d3e7e5b5cb
--- /dev/null
+++ b/gmp/mpn/x86/atom/sublsh1_n.asm
@@ -0,0 +1,34 @@
+dnl Intel Atom mpn_sublsh1_n -- rp[] = up[] - (vp[] << 1)
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_sublsh1_n_ip1)
+include_mpn(`x86/k7/sublsh1_n.asm')
diff --git a/gmp/mpn/x86/atom/sublsh2_n.asm b/gmp/mpn/x86/atom/sublsh2_n.asm
new file mode 100644
index 0000000000..79405cf9f4
--- /dev/null
+++ b/gmp/mpn/x86/atom/sublsh2_n.asm
@@ -0,0 +1,57 @@
+dnl Intel Atom mpn_addlsh2_n/mpn_sublsh2_n -- rp[] = up[] +- (vp[] << 2).
+
+dnl Contributed to the GNU project by Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 2)
+define(RSH, 30)
+
+ifdef(`OPERATION_addlsh2_n', `
+ define(M4_inst, adcl)
+ define(M4_opp, subl)
+ define(M4_function, mpn_addlsh2_n)
+ define(M4_function_c, mpn_addlsh2_nc)
+ define(M4_ip_function_c, mpn_addlsh2_nc_ip1)
+ define(M4_ip_function, mpn_addlsh2_n_ip1)
+',`ifdef(`OPERATION_sublsh2_n', `
+ define(M4_inst, sbbl)
+ define(M4_opp, addl)
+ define(M4_function, mpn_sublsh2_n)
+ define(M4_function_c, mpn_sublsh2_nc)
+ define(M4_ip_function_c, mpn_sublsh2_nc_ip1)
+ define(M4_ip_function, mpn_sublsh2_n_ip1)
+',`m4_error(`Need OPERATION_addlsh2_n or OPERATION_sublsh2_n
+')')')
+
+MULFUNC_PROLOGUE(mpn_sublsh2_n mpn_sublsh2_nc mpn_sublsh2_n_ip1 mpn_sublsh2_nc_ip1)
+
+include_mpn(`x86/atom/aorslshC_n.asm')
diff --git a/gmp/mpn/x86/bd1/gmp-mparam.h b/gmp/mpn/x86/bd1/gmp-mparam.h
new file mode 100644
index 0000000000..7d80a1cb4c
--- /dev/null
+++ b/gmp/mpn/x86/bd1/gmp-mparam.h
@@ -0,0 +1,208 @@
+/* AMD bd2 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2005, 2008-2010, 2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 3600 MHz Bulldozer Zambezi */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-13, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 3
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 16
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 11
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 3
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 27
+
+#define MUL_TOOM22_THRESHOLD 32
+#define MUL_TOOM33_THRESHOLD 65
+#define MUL_TOOM44_THRESHOLD 154
+#define MUL_TOOM6H_THRESHOLD 230
+#define MUL_TOOM8H_THRESHOLD 354
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 89
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 110
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 93
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 102
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 130
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 48
+#define SQR_TOOM3_THRESHOLD 87
+#define SQR_TOOM4_THRESHOLD 204
+#define SQR_TOOM6_THRESHOLD 315
+#define SQR_TOOM8_THRESHOLD 430
+
+#define MULMID_TOOM42_THRESHOLD 48
+
+#define MULMOD_BNM1_THRESHOLD 21
+#define SQRMOD_BNM1_THRESHOLD 23
+
+#define MUL_FFT_MODF_THRESHOLD 840 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 840, 5}, { 28, 6}, { 15, 5}, { 33, 6}, \
+ { 28, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 29, 8}, { 15, 7}, { 31, 6}, \
+ { 63, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 51, 8}, { 27, 7}, { 55, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 7}, { 79, 9}, \
+ { 23, 8}, { 55, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 63, 8}, { 127, 9}, \
+ { 79,10}, { 47, 9}, { 103,11}, { 31,10}, \
+ { 63, 9}, { 135,10}, { 79, 9}, { 159,10}, \
+ { 95, 9}, { 191,10}, { 111,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 159,11}, { 95,10}, \
+ { 191,12}, { 63,11}, { 127,10}, { 271,11}, \
+ { 159,10}, { 319, 9}, { 639,11}, { 191,10}, \
+ { 383, 9}, { 767,11}, { 223,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 287,10}, { 607,11}, \
+ { 319,10}, { 639,12}, { 191,11}, { 383,10}, \
+ { 799,13}, { 127,12}, { 255,11}, { 543,10}, \
+ { 1087,11}, { 607,12}, { 319,11}, { 671,10}, \
+ { 1343,11}, { 735,10}, { 1471, 9}, { 2943,12}, \
+ { 383,11}, { 799,10}, { 1599,11}, { 863,10}, \
+ { 1727,12}, { 447,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1215,10}, { 2431,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1471,10}, \
+ { 2943,13}, { 383,12}, { 767,11}, { 1599,12}, \
+ { 831,11}, { 1727,10}, { 3455,14}, { 255,13}, \
+ { 511,12}, { 1087,11}, { 2239,12}, { 1215,11}, \
+ { 2431,13}, { 639,12}, { 1471,11}, { 2943,13}, \
+ { 767,12}, { 1727,11}, { 3455,13}, { 895,12}, \
+ { 1919,11}, { 3839,12}, { 1983,11}, { 3967,10}, \
+ { 7935,14}, { 511,13}, { 1023,12}, { 2239,13}, \
+ { 1151,12}, { 2495,11}, { 4991,13}, { 1279,12}, \
+ { 2623,13}, { 1407,12}, { 2943,14}, { 767,13}, \
+ { 1535,12}, { 3071,13}, { 1663,12}, { 3455,13}, \
+ { 1791,12}, { 3583,13}, { 1919,12}, { 3967,11}, \
+ { 7935,15}, { 511,14}, { 1023,13}, { 2175,12}, \
+ { 4479,13}, { 2431,12}, { 4991,14}, { 1279,13}, \
+ { 2943,12}, { 6015,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 160
+#define MUL_FFT_THRESHOLD 7808
+
+#define SQR_FFT_MODF_THRESHOLD 690 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 690, 5}, { 28, 6}, { 15, 5}, { 32, 6}, \
+ { 29, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 40, 7}, { 21, 6}, \
+ { 43, 7}, { 23, 6}, { 47, 7}, { 35, 8}, \
+ { 19, 7}, { 43, 8}, { 23, 7}, { 49, 8}, \
+ { 27, 7}, { 55, 8}, { 31, 7}, { 63, 8}, \
+ { 39, 7}, { 79, 8}, { 43, 9}, { 23, 8}, \
+ { 55, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
+ { 31, 9}, { 63, 8}, { 127, 9}, { 79,10}, \
+ { 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
+ { 127,10}, { 79, 9}, { 167,10}, { 95, 9}, \
+ { 191,10}, { 111,11}, { 63,10}, { 159,11}, \
+ { 95,10}, { 191,12}, { 63,11}, { 127,10}, \
+ { 271,11}, { 159,10}, { 319, 9}, { 639,11}, \
+ { 191,10}, { 383,11}, { 223,12}, { 127,11}, \
+ { 255,10}, { 511, 9}, { 1023,10}, { 543,11}, \
+ { 287,10}, { 607, 9}, { 1215,11}, { 319,10}, \
+ { 639,12}, { 191,11}, { 383,10}, { 799,11}, \
+ { 415,13}, { 127,12}, { 255,11}, { 511,10}, \
+ { 1023,11}, { 543,10}, { 1087,11}, { 607,10}, \
+ { 1215,12}, { 319,11}, { 671,10}, { 1343,11}, \
+ { 735,10}, { 1471,12}, { 383,11}, { 799,10}, \
+ { 1599,11}, { 863,12}, { 447,11}, { 927,13}, \
+ { 255,12}, { 511,11}, { 1055,10}, { 2111,11}, \
+ { 1087,12}, { 575,11}, { 1215,10}, { 2431,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1471,13}, \
+ { 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
+ { 1727,10}, { 3455,12}, { 895,14}, { 255,13}, \
+ { 511,12}, { 1023,11}, { 2111,12}, { 1087,11}, \
+ { 2239,10}, { 4479,12}, { 1215,11}, { 2431,13}, \
+ { 639,12}, { 1471,11}, { 2943,13}, { 767,12}, \
+ { 1727,11}, { 3455,13}, { 895,12}, { 1983,11}, \
+ { 3967,14}, { 511,13}, { 1023,12}, { 2239,11}, \
+ { 4479,13}, { 1151,12}, { 2495,11}, { 4991,10}, \
+ { 9983,13}, { 1279,12}, { 2623,13}, { 1407,12}, \
+ { 2943,14}, { 767,13}, { 1663,12}, { 3455,13}, \
+ { 1791,12}, { 3583,13}, { 1919,12}, { 3967,15}, \
+ { 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
+ { 2431,12}, { 4991,11}, { 9983,14}, { 1279,13}, \
+ { 2687,12}, { 5375,13}, { 2943,12}, { 5887,14}, \
+ { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 166
+#define SQR_FFT_THRESHOLD 6784
+
+#define MULLO_BASECASE_THRESHOLD 5
+#define MULLO_DC_THRESHOLD 31
+#define MULLO_MUL_N_THRESHOLD 14709
+
+#define DC_DIV_QR_THRESHOLD 53
+#define DC_DIVAPPR_Q_THRESHOLD 230
+#define DC_BDIV_QR_THRESHOLD 50
+#define DC_BDIV_Q_THRESHOLD 136
+
+#define INV_MULMOD_BNM1_THRESHOLD 78
+#define INV_NEWTON_THRESHOLD 202
+#define INV_APPR_THRESHOLD 202
+
+#define BINV_NEWTON_THRESHOLD 236
+#define REDC_1_TO_REDC_N_THRESHOLD 55
+
+#define MU_DIV_QR_THRESHOLD 1442
+#define MU_DIVAPPR_Q_THRESHOLD 1652
+#define MUPI_DIV_QR_THRESHOLD 81
+#define MU_BDIV_QR_THRESHOLD 1787
+#define MU_BDIV_Q_THRESHOLD 1685
+
+#define POWM_SEC_TABLE 1,22,194,376,692,2657
+
+#define MATRIX22_STRASSEN_THRESHOLD 21
+#define HGCD_THRESHOLD 85
+#define HGCD_APPR_THRESHOLD 50
+#define HGCD_REDUCE_THRESHOLD 4455
+#define GCD_DC_THRESHOLD 456
+#define GCDEXT_DC_THRESHOLD 345
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 17
+#define GET_STR_PRECOMPUTE_THRESHOLD 27
+#define SET_STR_DC_THRESHOLD 100
+#define SET_STR_PRECOMPUTE_THRESHOLD 960
+
+#define FAC_DSC_THRESHOLD 208
+#define FAC_ODD_THRESHOLD 26
diff --git a/gmp/mpn/x86/bd2/gmp-mparam.h b/gmp/mpn/x86/bd2/gmp-mparam.h
new file mode 100644
index 0000000000..c5a53f2f9f
--- /dev/null
+++ b/gmp/mpn/x86/bd2/gmp-mparam.h
@@ -0,0 +1,209 @@
+/* AMD bd2 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2005, 2008-2010, 2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 4000 MHz Piledriver Vishera */
+/* FFT tuning limit = 40000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.8 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 3
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 19
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 10
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 3
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 24
+
+#define MUL_TOOM22_THRESHOLD 30
+#define MUL_TOOM33_THRESHOLD 81
+#define MUL_TOOM44_THRESHOLD 153
+#define MUL_TOOM6H_THRESHOLD 222
+#define MUL_TOOM8H_THRESHOLD 357
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 89
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 114
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 99
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 96
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 130
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 38
+#define SQR_TOOM3_THRESHOLD 89
+#define SQR_TOOM4_THRESHOLD 196
+#define SQR_TOOM6_THRESHOLD 290
+#define SQR_TOOM8_THRESHOLD 454
+
+#define MULMID_TOOM42_THRESHOLD 68
+
+#define MULMOD_BNM1_THRESHOLD 19
+#define SQRMOD_BNM1_THRESHOLD 22
+
+#define MUL_FFT_MODF_THRESHOLD 636 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 636, 5}, { 27, 6}, { 27, 7}, { 15, 6}, \
+ { 33, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
+ { 39, 7}, { 23, 6}, { 47, 7}, { 29, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 49, 8}, { 27, 7}, { 55, 9}, \
+ { 15, 8}, { 31, 7}, { 63, 8}, { 43, 9}, \
+ { 23, 8}, { 55, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 63, 8}, { 127, 9}, \
+ { 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
+ { 63, 9}, { 135,10}, { 79, 9}, { 159,10}, \
+ { 95, 9}, { 191,11}, { 63,10}, { 127, 6}, \
+ { 2111, 5}, { 4351, 6}, { 2239, 7}, { 1215, 9}, \
+ { 311, 8}, { 639,10}, { 175, 8}, { 703,10}, \
+ { 191,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,10}, { 287,11}, \
+ { 159, 9}, { 671,11}, { 191,10}, { 383, 9}, \
+ { 799,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607,11}, \
+ { 319,10}, { 671,12}, { 191,11}, { 383,10}, \
+ { 799,11}, { 415,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
+ { 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
+ { 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 863,12}, { 447,11}, { 895,13}, { 255,12}, \
+ { 511,11}, { 1087,12}, { 575,11}, { 1215,10}, \
+ { 2431,12}, { 639,11}, { 1343,12}, { 703,11}, \
+ { 1471,13}, { 383,12}, { 767,11}, { 1599,12}, \
+ { 831,11}, { 1727,10}, { 3455,12}, { 895,14}, \
+ { 255,13}, { 511,12}, { 1023,11}, { 2047,12}, \
+ { 1087,11}, { 2239,10}, { 4479,12}, { 1215,11}, \
+ { 2431,13}, { 639,12}, { 1471,11}, { 2943,13}, \
+ { 767,12}, { 1727,11}, { 3455,13}, { 895,12}, \
+ { 1919,14}, { 511,13}, { 1023,12}, { 2239,11}, \
+ { 4479,13}, { 1151,12}, { 2495,11}, { 4991,13}, \
+ { 1279,12}, { 2623,13}, { 1407,12}, { 2943,14}, \
+ { 767,13}, { 1535,12}, { 3071,13}, { 1663,12}, \
+ { 3455,13}, { 1919,15}, { 511,14}, { 1023,13}, \
+ { 2175,12}, { 4479,13}, { 2431,12}, { 4991,14}, \
+ { 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
+ { 3455,14}, { 1791,13}, { 3967,12}, { 7935,11}, \
+ { 15871,15}, { 1023,14}, { 2047,13}, { 4479,14}, \
+ { 2303,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 172
+#define MUL_FFT_THRESHOLD 6784
+
+#define SQR_FFT_MODF_THRESHOLD 606 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 606, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
+ { 29, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 49, 8}, \
+ { 31, 7}, { 63, 8}, { 43, 9}, { 23, 8}, \
+ { 51, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95,10}, { 31, 9}, \
+ { 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
+ { 63, 9}, { 135,10}, { 79, 9}, { 159,10}, \
+ { 95, 9}, { 191,11}, { 63,10}, { 159,11}, \
+ { 95,10}, { 191, 6}, { 3135, 5}, { 6399, 6}, \
+ { 3455, 8}, { 895, 9}, { 479, 8}, { 991,10}, \
+ { 255, 9}, { 575,11}, { 159, 9}, { 639,10}, \
+ { 335, 8}, { 1343,10}, { 351,11}, { 191, 9}, \
+ { 799,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543,11}, { 287,10}, { 607, 9}, { 1215,10}, \
+ { 671,12}, { 191,11}, { 383,10}, { 767, 9}, \
+ { 1535,10}, { 799,11}, { 415,10}, { 863,13}, \
+ { 127,12}, { 255,11}, { 511,10}, { 1023,11}, \
+ { 543,10}, { 1087,11}, { 607,12}, { 319,11}, \
+ { 671,10}, { 1343,11}, { 735,12}, { 383,11}, \
+ { 799,10}, { 1599,11}, { 863,12}, { 447,11}, \
+ { 927,13}, { 255,12}, { 511,11}, { 1087,12}, \
+ { 575,11}, { 1215,12}, { 639,11}, { 1343,12}, \
+ { 703,11}, { 1471,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1727,12}, { 895,11}, \
+ { 1791,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1087,11}, { 2239,10}, { 4479,12}, { 1215,13}, \
+ { 639,12}, { 1471,11}, { 2943,13}, { 767,12}, \
+ { 1727,13}, { 895,12}, { 1919,14}, { 511,13}, \
+ { 1023,12}, { 2239,11}, { 4479,13}, { 1151,12}, \
+ { 2495,11}, { 4991,13}, { 1279,12}, { 2623,13}, \
+ { 1407,12}, { 2943,14}, { 767,13}, { 1663,12}, \
+ { 3455,13}, { 1791,12}, { 3583,13}, { 1919,15}, \
+ { 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
+ { 2431,12}, { 4991,14}, { 1279,13}, { 2943,12}, \
+ { 5887,14}, { 1535,13}, { 3455,14}, { 1791,13}, \
+ { 3967,15}, { 1023,14}, { 2047,13}, { 4479,14}, \
+ { 2303,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 160
+#define SQR_FFT_THRESHOLD 5760
+
+#define MULLO_BASECASE_THRESHOLD 3
+#define MULLO_DC_THRESHOLD 34
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 67
+#define DC_DIVAPPR_Q_THRESHOLD 196
+#define DC_BDIV_QR_THRESHOLD 67
+#define DC_BDIV_Q_THRESHOLD 112
+
+#define INV_MULMOD_BNM1_THRESHOLD 70
+#define INV_NEWTON_THRESHOLD 262
+#define INV_APPR_THRESHOLD 222
+
+#define BINV_NEWTON_THRESHOLD 288
+#define REDC_1_TO_REDC_N_THRESHOLD 67
+
+#define MU_DIV_QR_THRESHOLD 1718
+#define MU_DIVAPPR_Q_THRESHOLD 1652
+#define MUPI_DIV_QR_THRESHOLD 122
+#define MU_BDIV_QR_THRESHOLD 1387
+#define MU_BDIV_Q_THRESHOLD 1528
+
+#define POWM_SEC_TABLE 1,16,69,508,1378,2657,2825
+
+#define MATRIX22_STRASSEN_THRESHOLD 19
+#define HGCD_THRESHOLD 61
+#define HGCD_APPR_THRESHOLD 50
+#define HGCD_REDUCE_THRESHOLD 3389
+#define GCD_DC_THRESHOLD 492
+#define GCDEXT_DC_THRESHOLD 345
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 9
+#define GET_STR_PRECOMPUTE_THRESHOLD 21
+#define SET_STR_DC_THRESHOLD 189
+#define SET_STR_PRECOMPUTE_THRESHOLD 541
+
+#define FAC_DSC_THRESHOLD 141
+#define FAC_ODD_THRESHOLD 29
diff --git a/gmp/mpn/x86/bdiv_dbm1c.asm b/gmp/mpn/x86/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..0288c475cd
--- /dev/null
+++ b/gmp/mpn/x86/bdiv_dbm1c.asm
@@ -0,0 +1,129 @@
+dnl x86 mpn_bdiv_dbm1.
+
+dnl Copyright 2008, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12)
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan) 5.1
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood) 13.67
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom
+C AMD K6
+C AMD K7 3.5
+C AMD K8
+C AMD K10
+
+
+C TODO
+C * Optimize for more x86 processors
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_bdiv_dbm1c)
+ mov 16(%esp), %ecx C d
+ push %esi
+ mov 12(%esp), %esi C ap
+ push %edi
+ mov 12(%esp), %edi C qp
+ push %ebp
+ mov 24(%esp), %ebp C n
+ push %ebx
+
+ mov (%esi), %eax
+ mul %ecx
+ mov 36(%esp), %ebx
+ sub %eax, %ebx
+ mov %ebx, (%edi)
+ sbb %edx, %ebx
+
+ mov %ebp, %eax
+ and $3, %eax
+ jz L(b0)
+ cmp $2, %eax
+ jc L(b1)
+ jz L(b2)
+
+L(b3): lea -8(%esi), %esi
+ lea 8(%edi), %edi
+ add $-3, %ebp
+ jmp L(3)
+
+L(b0): mov 4(%esi), %eax
+ lea -4(%esi), %esi
+ lea 12(%edi), %edi
+ add $-4, %ebp
+ jmp L(0)
+
+L(b2): mov 4(%esi), %eax
+ lea 4(%esi), %esi
+ lea 4(%edi), %edi
+ add $-2, %ebp
+ jmp L(2)
+
+ ALIGN(8)
+L(top): mov 4(%esi), %eax
+ mul %ecx
+ lea 16(%edi), %edi
+ sub %eax, %ebx
+ mov 8(%esi), %eax
+ mov %ebx, -12(%edi)
+ sbb %edx, %ebx
+L(0): mul %ecx
+ sub %eax, %ebx
+ mov %ebx, -8(%edi)
+ sbb %edx, %ebx
+L(3): mov 12(%esi), %eax
+ mul %ecx
+ sub %eax, %ebx
+ mov %ebx, -4(%edi)
+ mov 16(%esi), %eax
+ lea 16(%esi), %esi
+ sbb %edx, %ebx
+L(2): mul %ecx
+ sub %eax, %ebx
+ mov %ebx, 0(%edi)
+ sbb %edx, %ebx
+L(b1): add $-4, %ebp
+ jns L(top)
+
+ mov %ebx, %eax
+ pop %ebx
+ pop %ebp
+ pop %edi
+ pop %esi
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/bdiv_q_1.asm b/gmp/mpn/x86/bdiv_q_1.asm
new file mode 100644
index 0000000000..825cd296a1
--- /dev/null
+++ b/gmp/mpn/x86/bdiv_q_1.asm
@@ -0,0 +1,208 @@
+dnl x86 mpn_bdiv_q_1 -- mpn by limb exact division.
+
+dnl Rearranged from mpn/x86/dive_1.asm by Marco Bodrato.
+
+dnl Copyright 2001, 2002, 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P54 30.0
+C P55 29.0
+C P6 13.0 odd divisor, 12.0 even (strangely)
+C K6 14.0
+C K7 12.0
+C P4 42.0
+
+MULFUNC_PROLOGUE(mpn_bdiv_q_1 mpn_pi1_bdiv_q_1)
+
+defframe(PARAM_SHIFT, 24)
+defframe(PARAM_INVERSE,20)
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(VAR_INVERSE,`PARAM_SRC')
+
+ TEXT
+
+C mp_limb_t
+C mpn_pi1_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor,
+C mp_limb_t inverse, int shift)
+
+ ALIGN(16)
+PROLOGUE(mpn_pi1_bdiv_q_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SHIFT, %ecx
+ pushl %ebp FRAME_pushl()
+
+ movl PARAM_INVERSE, %eax
+ movl PARAM_SIZE, %ebp
+ pushl %ebx FRAME_pushl()
+L(common):
+ pushl %edi FRAME_pushl()
+ pushl %esi FRAME_pushl()
+
+ movl PARAM_SRC, %esi
+ movl PARAM_DST, %edi
+
+ leal (%esi,%ebp,4), %esi C src end
+ leal (%edi,%ebp,4), %edi C dst end
+ negl %ebp C -size
+
+ movl %eax, VAR_INVERSE
+ movl (%esi,%ebp,4), %eax C src[0]
+
+ xorl %ebx, %ebx
+ xorl %edx, %edx
+
+ incl %ebp
+ jz L(one)
+
+ movl (%esi,%ebp,4), %edx C src[1]
+
+ shrdl( %cl, %edx, %eax)
+
+ movl VAR_INVERSE, %edx
+ jmp L(entry)
+
+
+ ALIGN(8)
+ nop C k6 code alignment
+ nop
+L(top):
+ C eax q
+ C ebx carry bit, 0 or -1
+ C ecx shift
+ C edx carry limb
+ C esi src end
+ C edi dst end
+ C ebp counter, limbs, negative
+
+ movl -4(%esi,%ebp,4), %eax
+ subl %ebx, %edx C accumulate carry bit
+
+ movl (%esi,%ebp,4), %ebx
+
+ shrdl( %cl, %ebx, %eax)
+
+ subl %edx, %eax C apply carry limb
+ movl VAR_INVERSE, %edx
+
+ sbbl %ebx, %ebx
+
+L(entry):
+ imull %edx, %eax
+
+ movl %eax, -4(%edi,%ebp,4)
+ movl PARAM_DIVISOR, %edx
+
+ mull %edx
+
+ incl %ebp
+ jnz L(top)
+
+
+ movl -4(%esi), %eax C src high limb
+L(one):
+ shrl %cl, %eax
+ popl %esi FRAME_popl()
+
+ addl %ebx, %eax C apply carry bit
+
+ subl %edx, %eax C apply carry limb
+
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi)
+
+ popl %edi
+ popl %ebx
+ popl %ebp
+
+ ret
+
+EPILOGUE()
+
+C mp_limb_t mpn_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+
+ ALIGN(16)
+PROLOGUE(mpn_bdiv_q_1)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %eax
+ pushl %ebp FRAME_pushl()
+
+ movl $-1, %ecx C shift count
+ movl PARAM_SIZE, %ebp
+
+ pushl %ebx FRAME_pushl()
+
+L(strip_twos):
+ incl %ecx
+
+ shrl %eax
+ jnc L(strip_twos)
+
+ leal 1(%eax,%eax), %ebx C d without twos
+ andl $127, %eax C d/2, 7 bits
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %edx)
+ movzbl (%eax,%edx), %eax C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+
+ leal (%eax,%eax), %edx C 2*inv
+ movl %ebx, PARAM_DIVISOR C d without twos
+ imull %eax, %eax C inv*inv
+ imull %ebx, %eax C inv*inv*d
+ subl %eax, %edx C inv = 2*inv - inv*inv*d
+
+ leal (%edx,%edx), %eax C 2*inv
+ imull %edx, %edx C inv*inv
+ imull %ebx, %edx C inv*inv*d
+ subl %edx, %eax C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ imull PARAM_DIVISOR, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ jmp L(common)
+EPILOGUE()
+
diff --git a/gmp/mpn/x86/bobcat/gmp-mparam.h b/gmp/mpn/x86/bobcat/gmp-mparam.h
new file mode 100644
index 0000000000..198081f9fd
--- /dev/null
+++ b/gmp/mpn/x86/bobcat/gmp-mparam.h
@@ -0,0 +1,197 @@
+/* x86/bobcat gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 1600 MHz AMD Bobcat Zacate E-350 */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 12
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 16
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 16
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 2
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 40
+
+#define MUL_TOOM22_THRESHOLD 28
+#define MUL_TOOM33_THRESHOLD 90
+#define MUL_TOOM44_THRESHOLD 154
+#define MUL_TOOM6H_THRESHOLD 270
+#define MUL_TOOM8H_THRESHOLD 490
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 89
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 107
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 95
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 110
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 130
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 38
+#define SQR_TOOM3_THRESHOLD 121
+#define SQR_TOOM4_THRESHOLD 212
+#define SQR_TOOM6_THRESHOLD 303
+#define SQR_TOOM8_THRESHOLD 454
+
+#define MULMID_TOOM42_THRESHOLD 74
+
+#define MULMOD_BNM1_THRESHOLD 18
+#define SQRMOD_BNM1_THRESHOLD 23
+
+#define MUL_FFT_MODF_THRESHOLD 660 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 660, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 27, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 49, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
+ { 55, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
+ { 31, 9}, { 63, 8}, { 127, 9}, { 79,10}, \
+ { 47, 9}, { 103,11}, { 31,10}, { 63, 9}, \
+ { 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
+ { 191,10}, { 111,11}, { 63,10}, { 159,11}, \
+ { 95,10}, { 191,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271, 9}, { 543,11}, \
+ { 159, 9}, { 639,10}, { 335, 9}, { 671,11}, \
+ { 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
+ { 799,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607, 9}, \
+ { 1215,10}, { 671,12}, { 191,11}, { 383,10}, \
+ { 799, 9}, { 1599,11}, { 415,13}, { 127,12}, \
+ { 255,11}, { 543,10}, { 1087,11}, { 607,10}, \
+ { 1215,11}, { 671,10}, { 1343,11}, { 735,10}, \
+ { 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 863,12}, { 447,11}, { 991,13}, { 255,12}, \
+ { 511,11}, { 1087,12}, { 575,11}, { 1215,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1471,13}, \
+ { 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
+ { 1727,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1215,13}, { 639,12}, { 1471,13}, { 767,12}, \
+ { 1727,13}, { 895,12}, { 1919,14}, { 511,13}, \
+ { 1023,12}, { 2111,13}, { 1151,12}, { 2431,13}, \
+ { 1407,14}, { 767,13}, { 1663,12}, { 3455,13}, \
+ { 1919,15}, { 511,14}, { 1023,13}, { 2175,12}, \
+ { 4479,13}, { 2431,14}, { 1279,13}, { 2943,12}, \
+ { 5887,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 139
+#define MUL_FFT_THRESHOLD 7552
+
+#define SQR_FFT_MODF_THRESHOLD 606 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 606, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
+ { 28, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 49, 8}, \
+ { 31, 7}, { 63, 8}, { 43, 9}, { 23, 8}, \
+ { 55, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
+ { 31, 9}, { 79,10}, { 47, 9}, { 103,11}, \
+ { 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
+ { 159,10}, { 95, 9}, { 191,11}, { 63,10}, \
+ { 159,11}, { 95,10}, { 191,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
+ { 543, 8}, { 1087,11}, { 159,10}, { 319, 9}, \
+ { 639,10}, { 335, 9}, { 671, 8}, { 1343,10}, \
+ { 351,11}, { 191,10}, { 383, 9}, { 767,10}, \
+ { 399, 9}, { 799,10}, { 415, 9}, { 831,12}, \
+ { 127,11}, { 255,10}, { 511, 9}, { 1023,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607, 9}, \
+ { 1215,11}, { 319,10}, { 671, 9}, { 1343,12}, \
+ { 191,11}, { 383,10}, { 799,11}, { 415,10}, \
+ { 831,13}, { 127,12}, { 255,11}, { 511,10}, \
+ { 1023,11}, { 543,10}, { 1087,11}, { 607,10}, \
+ { 1215,12}, { 319,11}, { 671,10}, { 1343,11}, \
+ { 735,10}, { 1471,12}, { 383,11}, { 799,10}, \
+ { 1599,11}, { 863,12}, { 447,11}, { 991,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1215,12}, { 639,11}, { 1343,12}, { 703,11}, \
+ { 1471,13}, { 383,12}, { 767,11}, { 1599,12}, \
+ { 831,11}, { 1727,12}, { 959,14}, { 255,13}, \
+ { 511,12}, { 1215,13}, { 639,12}, { 1471,13}, \
+ { 767,12}, { 1727,13}, { 895,12}, { 1983,14}, \
+ { 511,13}, { 1023,12}, { 2111,13}, { 1151,12}, \
+ { 2431,13}, { 1407,14}, { 767,13}, { 1663,12}, \
+ { 3455,13}, { 1919,15}, { 511,14}, { 1023,13}, \
+ { 2175,12}, { 4479,13}, { 2431,14}, { 1279,13}, \
+ { 2943,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 147
+#define SQR_FFT_THRESHOLD 5760
+
+#define MULLO_BASECASE_THRESHOLD 5
+#define MULLO_DC_THRESHOLD 45
+#define MULLO_MUL_N_THRESHOLD 14281
+
+#define DC_DIV_QR_THRESHOLD 71
+#define DC_DIVAPPR_Q_THRESHOLD 238
+#define DC_BDIV_QR_THRESHOLD 67
+#define DC_BDIV_Q_THRESHOLD 151
+
+#define INV_MULMOD_BNM1_THRESHOLD 66
+#define INV_NEWTON_THRESHOLD 228
+#define INV_APPR_THRESHOLD 222
+
+#define BINV_NEWTON_THRESHOLD 270
+#define REDC_1_TO_REDC_N_THRESHOLD 71
+
+#define MU_DIV_QR_THRESHOLD 1718
+#define MU_DIVAPPR_Q_THRESHOLD 1718
+#define MUPI_DIV_QR_THRESHOLD 91
+#define MU_BDIV_QR_THRESHOLD 1589
+#define MU_BDIV_Q_THRESHOLD 1718
+
+#define POWM_SEC_TABLE 1,16,96,416,1185
+
+#define MATRIX22_STRASSEN_THRESHOLD 17
+#define HGCD_THRESHOLD 88
+#define HGCD_APPR_THRESHOLD 137
+#define HGCD_REDUCE_THRESHOLD 3664
+#define GCD_DC_THRESHOLD 465
+#define GCDEXT_DC_THRESHOLD 345
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 18
+#define GET_STR_PRECOMPUTE_THRESHOLD 34
+#define SET_STR_DC_THRESHOLD 270
+#define SET_STR_PRECOMPUTE_THRESHOLD 828
+
+#define FAC_DSC_THRESHOLD 256
+#define FAC_ODD_THRESHOLD 34
diff --git a/gmp/mpn/x86/cnd_aors_n.asm b/gmp/mpn/x86/cnd_aors_n.asm
new file mode 100644
index 0000000000..74f4917ecc
--- /dev/null
+++ b/gmp/mpn/x86/cnd_aors_n.asm
@@ -0,0 +1,124 @@
+dnl X86 mpn_cnd_add_n, mpn_cnd_sub_n
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C P5 ?
+C P6 model 0-8,10-12 ?
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) 5.4
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) 14.5
+C P4 model 3-4 (Prescott) 21
+C Intel atom 11
+C AMD K6 ?
+C AMD K7 3.4
+C AMD K8 ?
+
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`vp', `%ebp')
+define(`n', `%ecx')
+define(`cnd', `20(%esp)')
+define(`cy', `%edx')
+
+ifdef(`OPERATION_cnd_add_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func, mpn_cnd_add_n)')
+ifdef(`OPERATION_cnd_sub_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func, mpn_cnd_sub_n)')
+
+MULFUNC_PROLOGUE(mpn_cnd_add_n mpn_cnd_sub_n)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ add $-16, %esp
+ mov %ebp, (%esp)
+ mov %ebx, 4(%esp)
+ mov %esi, 8(%esp)
+ mov %edi, 12(%esp)
+
+ C make cnd into a full mask
+ mov cnd, %eax
+ neg %eax
+ sbb %eax, %eax
+ mov %eax, cnd
+
+ C load parameters into registers
+ mov 24(%esp), rp
+ mov 28(%esp), up
+ mov 32(%esp), vp
+ mov 36(%esp), n
+
+ mov (vp), %eax
+ mov (up), %ebx
+
+ C put operand pointers just beyond their last limb
+ lea (vp,n,4), vp
+ lea (up,n,4), up
+ lea -4(rp,n,4), rp
+ neg n
+
+ and cnd, %eax
+ ADDSUB %eax, %ebx
+ sbb cy, cy
+ inc n
+ je L(end)
+
+ ALIGN(16)
+L(top): mov (vp,n,4), %eax
+ and cnd, %eax
+ mov %ebx, (rp,n,4)
+ mov (up,n,4), %ebx
+ add cy, cy
+ ADCSBB %eax, %ebx
+ sbb cy, cy
+ inc n
+ jne L(top)
+
+L(end): mov %ebx, (rp)
+ xor %eax, %eax
+ sub cy, %eax
+
+ mov (%esp), %ebp
+ mov 4(%esp), %ebx
+ mov 8(%esp), %esi
+ mov 12(%esp), %edi
+ add $16, %esp
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/copyd.asm b/gmp/mpn/x86/copyd.asm
new file mode 100644
index 0000000000..51fa19568b
--- /dev/null
+++ b/gmp/mpn/x86/copyd.asm
@@ -0,0 +1,91 @@
+dnl x86 mpn_copyd -- copy limb vector, decrementing.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb startup (approx)
+C P5 1.0 40
+C P6 2.4 70
+C K6 1.0 55
+C K7 1.3 75
+C P4 2.6 175
+C
+C (Startup time includes some function call overheads.)
+
+
+C void mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C Copy src,size to dst,size, working from high to low addresses.
+C
+C The code here is very generic and can be expected to be reasonable on all
+C the x86 family.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(mpn_copyd)
+ C eax saved esi
+ C ebx
+ C ecx counter
+ C edx saved edi
+ C esi src
+ C edi dst
+ C ebp
+
+ movl PARAM_SIZE, %ecx
+ movl %esi, %eax
+
+ movl PARAM_SRC, %esi
+ movl %edi, %edx
+
+ movl PARAM_DST, %edi
+ leal -4(%esi,%ecx,4), %esi
+
+ leal -4(%edi,%ecx,4), %edi
+
+ std
+
+ rep
+ movsl
+
+ cld
+
+ movl %eax, %esi
+ movl %edx, %edi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/copyi.asm b/gmp/mpn/x86/copyi.asm
new file mode 100644
index 0000000000..f6b0354b4f
--- /dev/null
+++ b/gmp/mpn/x86/copyi.asm
@@ -0,0 +1,99 @@
+dnl x86 mpn_copyi -- copy limb vector, incrementing.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb startup (approx)
+C P5 1.0 35
+C P6 0.75 45
+C K6 1.0 30
+C K7 1.3 65
+C P4 1.0 120
+C
+C (Startup time includes some function call overheads.)
+
+
+C void mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C Copy src,size to dst,size, working from low to high addresses.
+C
+C The code here is very generic and can be expected to be reasonable on all
+C the x86 family.
+C
+C P6 - An MMX based copy was tried, but was found to be slower than a rep
+C movs in all cases. The fastest MMX found was 0.8 cycles/limb (when
+C fully aligned). A rep movs seems to have a startup time of about 15
+C cycles, but doing something special for small sizes could lead to a
+C branch misprediction that would destroy any saving. For now a plain
+C rep movs seems ok.
+C
+C K62 - We used to have a big chunk of code doing an MMX copy at 0.56 c/l if
+C aligned or a 1.0 rep movs if not. But that seemed excessive since
+C it only got an advantage half the time, and even then only showed it
+C above 50 limbs or so.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+ TEXT
+ ALIGN(32)
+
+ C eax saved esi
+ C ebx
+ C ecx counter
+ C edx saved edi
+ C esi src
+ C edi dst
+ C ebp
+
+PROLOGUE(mpn_copyi)
+
+ movl PARAM_SIZE, %ecx
+ movl %esi, %eax
+
+ movl PARAM_SRC, %esi
+ movl %edi, %edx
+
+ movl PARAM_DST, %edi
+
+ cld C better safe than sorry, see mpn/x86/README
+
+ rep
+ movsl
+
+ movl %eax, %esi
+ movl %edx, %edi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/core2/gmp-mparam.h b/gmp/mpn/x86/core2/gmp-mparam.h
new file mode 100644
index 0000000000..b370eb5877
--- /dev/null
+++ b/gmp/mpn/x86/core2/gmp-mparam.h
@@ -0,0 +1,200 @@
+/* x86/core2 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 2133 MHz Core 2 (65nm) */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-14, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 4
+#define MOD_1_UNNORM_THRESHOLD 4
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 10
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 10
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 3
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 19
+
+#define MUL_TOOM22_THRESHOLD 26
+#define MUL_TOOM33_THRESHOLD 90
+#define MUL_TOOM44_THRESHOLD 144
+#define MUL_TOOM6H_THRESHOLD 286
+#define MUL_TOOM8H_THRESHOLD 430
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 93
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 140
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 89
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 102
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 136
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 34
+#define SQR_TOOM3_THRESHOLD 114
+#define SQR_TOOM4_THRESHOLD 178
+#define SQR_TOOM6_THRESHOLD 262
+#define SQR_TOOM8_THRESHOLD 357
+
+#define MULMID_TOOM42_THRESHOLD 66
+
+#define MULMOD_BNM1_THRESHOLD 15
+#define SQRMOD_BNM1_THRESHOLD 21
+
+#define MUL_FFT_MODF_THRESHOLD 600 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 600, 5}, { 25, 6}, { 13, 5}, { 28, 6}, \
+ { 25, 7}, { 13, 6}, { 29, 7}, { 15, 6}, \
+ { 33, 7}, { 17, 6}, { 36, 7}, { 19, 6}, \
+ { 39, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 43, 8}, { 23, 7}, { 47, 8}, \
+ { 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
+ { 43, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
+ { 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
+ { 47, 8}, { 95, 9}, { 55,10}, { 31, 9}, \
+ { 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
+ { 63, 9}, { 135,10}, { 79, 9}, { 159,10}, \
+ { 95, 9}, { 191,11}, { 63,10}, { 159,11}, \
+ { 95,10}, { 191,12}, { 63,11}, { 127,10}, \
+ { 271, 9}, { 543, 8}, { 1087,11}, { 159,10}, \
+ { 319, 9}, { 639,10}, { 335, 9}, { 671,10}, \
+ { 351,11}, { 191,10}, { 383, 9}, { 767,10}, \
+ { 399, 9}, { 799,11}, { 223,12}, { 127,11}, \
+ { 255,10}, { 543, 9}, { 1087,11}, { 287,10}, \
+ { 607, 9}, { 1215,11}, { 319,10}, { 671,11}, \
+ { 351,12}, { 191,11}, { 383,10}, { 799, 9}, \
+ { 1599,13}, { 127,12}, { 255,11}, { 543,10}, \
+ { 1087,11}, { 607,10}, { 1215,12}, { 319,11}, \
+ { 671,10}, { 1343,11}, { 735,12}, { 383,11}, \
+ { 799,10}, { 1599,11}, { 863,10}, { 1727,12}, \
+ { 447,11}, { 959,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
+ { 1343,12}, { 703,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1727,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1087,11}, { 2239,10}, \
+ { 4479,12}, { 1215,13}, { 639,12}, { 1471,11}, \
+ { 2943,13}, { 767,12}, { 1727,13}, { 895,12}, \
+ { 1983,14}, { 511,13}, { 1023,12}, { 2239,11}, \
+ { 4479,13}, { 1151,12}, { 2495,13}, { 1279,12}, \
+ { 2623,13}, { 1407,12}, { 2815,14}, { 767,13}, \
+ { 1663,12}, { 3455,13}, { 1919,15}, { 511,14}, \
+ { 1023,13}, { 2175,12}, { 4479,13}, { 2431,14}, \
+ { 1279,13}, { 2943,12}, { 5887,14}, { 16384,15}, \
+ { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 149
+#define MUL_FFT_THRESHOLD 6784
+
+#define SQR_FFT_MODF_THRESHOLD 500 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 500, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
+ { 28, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 39, 7}, { 29, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
+ { 51,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 55,10}, { 31, 9}, \
+ { 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
+ { 63, 9}, { 127,10}, { 79, 9}, { 159,10}, \
+ { 95,11}, { 63,10}, { 143, 9}, { 287,10}, \
+ { 159,11}, { 95,12}, { 63,11}, { 127,10}, \
+ { 271, 9}, { 543,10}, { 287,11}, { 159,10}, \
+ { 319, 9}, { 639,10}, { 335, 9}, { 671,10}, \
+ { 351, 9}, { 703,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 399, 9}, { 799,10}, { 415, 9}, \
+ { 831,10}, { 431,11}, { 223,12}, { 127,11}, \
+ { 255,10}, { 543, 9}, { 1087,11}, { 287,10}, \
+ { 607,11}, { 319,10}, { 671,11}, { 351,10}, \
+ { 703,12}, { 191,11}, { 383,10}, { 799,11}, \
+ { 415,10}, { 863,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
+ { 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
+ { 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 863,12}, { 447,11}, { 959,13}, { 255,12}, \
+ { 511,11}, { 1087,12}, { 575,11}, { 1215,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1471,13}, \
+ { 383,12}, { 831,11}, { 1727,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1087,11}, { 2239,12}, \
+ { 1215,13}, { 639,12}, { 1471,11}, { 2943,13}, \
+ { 767,12}, { 1727,13}, { 895,12}, { 1983,14}, \
+ { 511,13}, { 1023,12}, { 2239,13}, { 1151,12}, \
+ { 2495,13}, { 1407,12}, { 2943,14}, { 767,13}, \
+ { 1663,12}, { 3455,13}, { 1919,15}, { 511,14}, \
+ { 1023,13}, { 2175,12}, { 4479,13}, { 2431,14}, \
+ { 1279,13}, { 2943,12}, { 5887,14}, { 16384,15}, \
+ { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 145
+#define SQR_FFT_THRESHOLD 5312
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 29
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 21
+#define DC_DIVAPPR_Q_THRESHOLD 50
+#define DC_BDIV_QR_THRESHOLD 79
+#define DC_BDIV_Q_THRESHOLD 174
+
+#define INV_MULMOD_BNM1_THRESHOLD 50
+#define INV_NEWTON_THRESHOLD 39
+#define INV_APPR_THRESHOLD 37
+
+#define BINV_NEWTON_THRESHOLD 318
+#define REDC_1_TO_REDC_N_THRESHOLD 87
+
+#define MU_DIV_QR_THRESHOLD 1099
+#define MU_DIVAPPR_Q_THRESHOLD 792
+#define MUPI_DIV_QR_THRESHOLD 0 /* always */
+#define MU_BDIV_QR_THRESHOLD 1442
+#define MU_BDIV_Q_THRESHOLD 1589
+
+#define POWM_SEC_TABLE 3,32,95,480,597,2657
+
+#define MATRIX22_STRASSEN_THRESHOLD 21
+#define HGCD_THRESHOLD 83
+#define HGCD_APPR_THRESHOLD 159
+#define HGCD_REDUCE_THRESHOLD 3389
+#define GCD_DC_THRESHOLD 379
+#define GCDEXT_DC_THRESHOLD 309
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 10
+#define GET_STR_PRECOMPUTE_THRESHOLD 25
+#define SET_STR_DC_THRESHOLD 442
+#define SET_STR_PRECOMPUTE_THRESHOLD 1104
+
+#define FAC_DSC_THRESHOLD 155
+#define FAC_ODD_THRESHOLD 34
diff --git a/gmp/mpn/x86/coreihwl/gmp-mparam.h b/gmp/mpn/x86/coreihwl/gmp-mparam.h
new file mode 100644
index 0000000000..e2b289cc3c
--- /dev/null
+++ b/gmp/mpn/x86/coreihwl/gmp-mparam.h
@@ -0,0 +1,210 @@
+/* x86/coreihwl gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 2900 MHz Core i5 Haswell */
+/* FFT tuning limit = 40000000 */
+/* Generated by tuneup.c, 2014-03-13, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 16
+#define MOD_1_UNNORM_THRESHOLD 13
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 11
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 9
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 10
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 5
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 15
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 19
+
+#define MUL_TOOM22_THRESHOLD 27
+#define MUL_TOOM33_THRESHOLD 90
+#define MUL_TOOM44_THRESHOLD 218
+#define MUL_TOOM6H_THRESHOLD 318
+#define MUL_TOOM8H_THRESHOLD 490
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 89
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 153
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 105
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 101
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 130
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 44
+#define SQR_TOOM3_THRESHOLD 137
+#define SQR_TOOM4_THRESHOLD 242
+#define SQR_TOOM6_THRESHOLD 351
+#define SQR_TOOM8_THRESHOLD 597
+
+#define MULMID_TOOM42_THRESHOLD 98
+
+#define MULMOD_BNM1_THRESHOLD 17
+#define SQRMOD_BNM1_THRESHOLD 21
+
+#define MUL_FFT_MODF_THRESHOLD 630 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 630, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 15, 5}, { 31, 6}, { 28, 7}, { 15, 6}, \
+ { 33, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
+ { 39, 7}, { 23, 6}, { 47, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
+ { 55,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 103,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 159,10}, { 95, 9}, { 191,10}, \
+ { 111,11}, { 63,10}, { 159,11}, { 95,10}, \
+ { 191,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,11}, { 159,10}, \
+ { 319, 9}, { 639,10}, { 335, 9}, { 671,11}, \
+ { 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
+ { 799,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543,11}, { 287,10}, { 607, 9}, { 1215,11}, \
+ { 319,10}, { 671,12}, { 191,11}, { 383,10}, \
+ { 799,11}, { 415,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
+ { 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
+ { 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 863,10}, { 1727,12}, { 447,11}, { 959,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1215,10}, { 2431,12}, { 639,11}, { 1343,12}, \
+ { 703,11}, { 1471,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1727,10}, { 3455,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1087,11}, \
+ { 2239,12}, { 1215,11}, { 2431,13}, { 639,12}, \
+ { 1471,11}, { 2943,10}, { 5887,13}, { 767,12}, \
+ { 1727,11}, { 3455,13}, { 895,12}, { 1983,14}, \
+ { 511,13}, { 1023,12}, { 2239,13}, { 1151,12}, \
+ { 2495,13}, { 1279,12}, { 2559,13}, { 1407,12}, \
+ { 2943,11}, { 5887,14}, { 767,13}, { 1535,12}, \
+ { 3071,13}, { 1663,12}, { 3455,13}, { 1919,15}, \
+ { 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
+ { 2431,14}, { 1279,13}, { 2943,12}, { 5887,14}, \
+ { 1535,13}, { 3455,14}, { 1791,13}, { 3967,12}, \
+ { 7935,15}, { 1023,14}, { 2047,13}, { 4479,14}, \
+ { 2303,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 168
+#define MUL_FFT_THRESHOLD 7424
+
+#define SQR_FFT_MODF_THRESHOLD 530 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 530, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
+ { 28, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
+ { 36, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 49, 8}, \
+ { 27, 7}, { 55, 9}, { 15, 8}, { 31, 7}, \
+ { 63, 8}, { 39, 9}, { 23, 8}, { 55,10}, \
+ { 15, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
+ { 31, 9}, { 79,10}, { 47, 9}, { 95,11}, \
+ { 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
+ { 159,10}, { 95, 9}, { 191,10}, { 111,11}, \
+ { 63,10}, { 159,11}, { 95,10}, { 191,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
+ { 271, 9}, { 543,11}, { 159,10}, { 319, 9}, \
+ { 639,10}, { 335, 9}, { 671,10}, { 351,11}, \
+ { 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
+ { 799,12}, { 127,11}, { 255,10}, { 511, 9}, \
+ { 1023,10}, { 543,11}, { 287,10}, { 607,11}, \
+ { 319,10}, { 671,11}, { 351,12}, { 191,11}, \
+ { 383,10}, { 799,11}, { 415,10}, { 831,13}, \
+ { 127,12}, { 255,11}, { 511,10}, { 1023,11}, \
+ { 543,10}, { 1087,11}, { 607,12}, { 319,11}, \
+ { 671,10}, { 1343,11}, { 735,10}, { 1471,12}, \
+ { 383,11}, { 799,10}, { 1599,11}, { 863,10}, \
+ { 1727,12}, { 447,11}, { 991,13}, { 255,12}, \
+ { 511,11}, { 1087,12}, { 575,11}, { 1215,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1471,13}, \
+ { 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
+ { 1727,12}, { 959,11}, { 1983,14}, { 255,13}, \
+ { 511,12}, { 1023,11}, { 2047,12}, { 1087,11}, \
+ { 2239,12}, { 1215,11}, { 2431,13}, { 639,12}, \
+ { 1471,11}, { 2943,13}, { 767,12}, { 1727,13}, \
+ { 895,12}, { 1983,14}, { 511,13}, { 1023,12}, \
+ { 2239,13}, { 1151,12}, { 2495,13}, { 1279,12}, \
+ { 2623,13}, { 1407,12}, { 2943,14}, { 767,13}, \
+ { 1535,12}, { 3071,13}, { 1663,12}, { 3455,13}, \
+ { 1919,12}, { 3839,15}, { 511,14}, { 1023,13}, \
+ { 2175,12}, { 4479,13}, { 2431,12}, { 4863,14}, \
+ { 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
+ { 3455,14}, { 1791,13}, { 3967,15}, { 1023,14}, \
+ { 2047,13}, { 4479,14}, { 2303,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 170
+#define SQR_FFT_THRESHOLD 5760
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 57
+#define MULLO_MUL_N_THRESHOLD 14281
+
+#define DC_DIV_QR_THRESHOLD 23
+#define DC_DIVAPPR_Q_THRESHOLD 63
+#define DC_BDIV_QR_THRESHOLD 87
+#define DC_BDIV_Q_THRESHOLD 204
+
+#define INV_MULMOD_BNM1_THRESHOLD 54
+#define INV_NEWTON_THRESHOLD 75
+#define INV_APPR_THRESHOLD 67
+
+#define BINV_NEWTON_THRESHOLD 296
+#define REDC_1_TO_REDC_N_THRESHOLD 79
+
+#define MU_DIV_QR_THRESHOLD 872
+#define MU_DIVAPPR_Q_THRESHOLD 654
+#define MUPI_DIV_QR_THRESHOLD 0 /* always */
+#define MU_BDIV_QR_THRESHOLD 1858
+#define MU_BDIV_Q_THRESHOLD 2089
+
+#define POWM_SEC_TABLE 1,17,127,508,1603
+
+#define MATRIX22_STRASSEN_THRESHOLD 19
+#define HGCD_THRESHOLD 61
+#define HGCD_APPR_THRESHOLD 60
+#define HGCD_REDUCE_THRESHOLD 3810
+#define GCD_DC_THRESHOLD 263
+#define GCDEXT_DC_THRESHOLD 278
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 11
+#define GET_STR_PRECOMPUTE_THRESHOLD 21
+#define SET_STR_DC_THRESHOLD 527
+#define SET_STR_PRECOMPUTE_THRESHOLD 1178
+
+#define FAC_DSC_THRESHOLD 187
+#define FAC_ODD_THRESHOLD 34
diff --git a/gmp/mpn/x86/coreinhm/gmp-mparam.h b/gmp/mpn/x86/coreinhm/gmp-mparam.h
new file mode 100644
index 0000000000..13289c0c23
--- /dev/null
+++ b/gmp/mpn/x86/coreinhm/gmp-mparam.h
@@ -0,0 +1,224 @@
+/* x86/coreinhm gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 2667 MHz Core i7 Nehalem */
+/* FFT tuning limit = 100000000 */
+/* Generated by tuneup.c, 2014-03-19, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 25
+#define MOD_1_UNNORM_THRESHOLD 15
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 8
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 11
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 3
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 18
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 15
+
+#define MUL_TOOM22_THRESHOLD 26
+#define MUL_TOOM33_THRESHOLD 89
+#define MUL_TOOM44_THRESHOLD 214
+#define MUL_TOOM6H_THRESHOLD 327
+#define MUL_TOOM8H_THRESHOLD 466
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 159
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 95
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 101
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 142
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 44
+#define SQR_TOOM3_THRESHOLD 145
+#define SQR_TOOM4_THRESHOLD 232
+#define SQR_TOOM6_THRESHOLD 342
+#define SQR_TOOM8_THRESHOLD 502
+
+#define MULMID_TOOM42_THRESHOLD 78
+
+#define MULMOD_BNM1_THRESHOLD 17
+#define SQRMOD_BNM1_THRESHOLD 21
+
+#define MUL_FFT_MODF_THRESHOLD 606 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 606, 5}, { 25, 6}, { 13, 5}, { 28, 6}, \
+ { 15, 5}, { 33, 6}, { 29, 7}, { 15, 6}, \
+ { 33, 7}, { 17, 6}, { 36, 7}, { 19, 6}, \
+ { 39, 7}, { 23, 6}, { 47, 7}, { 35, 8}, \
+ { 19, 7}, { 43, 8}, { 23, 7}, { 49, 8}, \
+ { 31, 7}, { 63, 8}, { 43, 9}, { 23, 8}, \
+ { 51, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
+ { 31, 9}, { 79,10}, { 47, 9}, { 95,11}, \
+ { 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
+ { 159,10}, { 95, 9}, { 191,10}, { 111,11}, \
+ { 63,10}, { 159,11}, { 95,10}, { 191,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
+ { 271, 9}, { 543,11}, { 159,10}, { 319, 9}, \
+ { 639,10}, { 335,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 399,12}, { 127,11}, { 255,10}, \
+ { 511, 9}, { 1023,10}, { 543,11}, { 287,10}, \
+ { 607,11}, { 319,10}, { 639,12}, { 191,11}, \
+ { 383,10}, { 767,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087,11}, \
+ { 607,12}, { 319,11}, { 671,10}, { 1343,11}, \
+ { 735,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 863,10}, { 1727,12}, { 447,11}, { 927,10}, \
+ { 1855,11}, { 991,13}, { 255,12}, { 511,11}, \
+ { 1119,12}, { 575,11}, { 1215,10}, { 2431,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1471,13}, \
+ { 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
+ { 1727,12}, { 895,11}, { 1855,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1023,11}, { 2111,12}, \
+ { 1087,11}, { 2239,10}, { 4479,12}, { 1215,11}, \
+ { 2431,13}, { 639,12}, { 1471,13}, { 767,12}, \
+ { 1727,11}, { 3455,13}, { 895,12}, { 1983,11}, \
+ { 3967,14}, { 511,13}, { 1023,12}, { 2239,11}, \
+ { 4479,13}, { 1151,12}, { 2495,11}, { 4991,13}, \
+ { 1279,12}, { 2623,13}, { 1407,12}, { 2943,14}, \
+ { 767,13}, { 1535,12}, { 3071,13}, { 1663,12}, \
+ { 3455,13}, { 1919,12}, { 3967,15}, { 511,14}, \
+ { 1023,13}, { 2175,12}, { 4479,13}, { 2431,12}, \
+ { 4991,14}, { 1279,13}, { 2687,12}, { 5503,13}, \
+ { 2943,12}, { 6015,14}, { 1535,13}, { 3455,14}, \
+ { 1791,13}, { 3967,12}, { 7935,15}, { 1023,14}, \
+ { 2047,13}, { 4479,14}, { 2303,13}, { 4991,12}, \
+ { 9983,14}, { 2559,13}, { 5503,14}, { 2815,13}, \
+ { 6015,15}, { 1535,14}, { 3839,13}, { 7935,16}, \
+ { 1023,15}, { 2047,14}, { 4095,13}, { 8191,12}, \
+ { 16383,11}, { 32767,10}, { 65535, 9}, { 131071, 8}, \
+ { 256, 9}, { 512,10}, { 1024,11}, { 2048,12}, \
+ { 4096,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 192
+#define MUL_FFT_THRESHOLD 6784
+
+#define SQR_FFT_MODF_THRESHOLD 555 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 555, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
+ { 16, 5}, { 33, 6}, { 29, 7}, { 15, 6}, \
+ { 32, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
+ { 39, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 49, 8}, \
+ { 27, 7}, { 55, 8}, { 31, 7}, { 63, 8}, \
+ { 43, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
+ { 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
+ { 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
+ { 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
+ { 135,10}, { 79, 9}, { 159,10}, { 95,11}, \
+ { 63,10}, { 143, 9}, { 287,10}, { 159,11}, \
+ { 95,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511, 8}, { 1023,10}, { 271, 9}, { 543,10}, \
+ { 287,11}, { 159,10}, { 319, 9}, { 639,10}, \
+ { 335, 9}, { 671,10}, { 351,11}, { 191,10}, \
+ { 383, 9}, { 767,10}, { 399, 9}, { 799,10}, \
+ { 415,12}, { 127,11}, { 255,10}, { 511, 9}, \
+ { 1023,10}, { 543,11}, { 287,10}, { 607,11}, \
+ { 319,10}, { 671,11}, { 351,12}, { 191,11}, \
+ { 383,10}, { 799,11}, { 415,13}, { 127,12}, \
+ { 255,11}, { 511,10}, { 1023,11}, { 543,10}, \
+ { 1087,11}, { 607,12}, { 319,11}, { 671,10}, \
+ { 1343,11}, { 735,10}, { 1471,12}, { 383,11}, \
+ { 799,10}, { 1599,11}, { 863,10}, { 1727,12}, \
+ { 447,11}, { 991,10}, { 1983,13}, { 255,12}, \
+ { 511,11}, { 1023,10}, { 2047,11}, { 1087,12}, \
+ { 575,11}, { 1215,10}, { 2431,12}, { 639,11}, \
+ { 1343,12}, { 703,11}, { 1471,13}, { 383,12}, \
+ { 767,11}, { 1599,12}, { 831,11}, { 1727,10}, \
+ { 3455,12}, { 895,11}, { 1791,12}, { 959,11}, \
+ { 1983,14}, { 255,13}, { 511,12}, { 1023,11}, \
+ { 2111,12}, { 1087,11}, { 2239,10}, { 4479,12}, \
+ { 1215,11}, { 2431,13}, { 639,12}, { 1471,11}, \
+ { 2943,13}, { 767,12}, { 1727,11}, { 3455,13}, \
+ { 895,12}, { 1983,11}, { 3967,14}, { 511,13}, \
+ { 1023,12}, { 2239,11}, { 4479,13}, { 1151,12}, \
+ { 2495,13}, { 1279,12}, { 2623,13}, { 1407,12}, \
+ { 2943,14}, { 767,13}, { 1663,12}, { 3455,13}, \
+ { 1919,12}, { 3967,15}, { 511,14}, { 1023,13}, \
+ { 2175,12}, { 4479,13}, { 2431,12}, { 4863,14}, \
+ { 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
+ { 3455,14}, { 1791,13}, { 3967,12}, { 7935,15}, \
+ { 1023,14}, { 2047,13}, { 4479,14}, { 2303,13}, \
+ { 4991,12}, { 9983,14}, { 2815,13}, { 5887,15}, \
+ { 1535,14}, { 3327,13}, { 6655,14}, { 3839,13}, \
+ { 7935,16}, { 1023,15}, { 2047,14}, { 4095,13}, \
+ { 8191,12}, { 16383,11}, { 32767,10}, { 65535, 9}, \
+ { 131071, 8}, { 256, 9}, { 512,10}, { 1024,11}, \
+ { 2048,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 201
+#define SQR_FFT_THRESHOLD 5312
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 38
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 22
+#define DC_DIVAPPR_Q_THRESHOLD 43
+#define DC_BDIV_QR_THRESHOLD 78
+#define DC_BDIV_Q_THRESHOLD 157
+
+#define INV_MULMOD_BNM1_THRESHOLD 50
+#define INV_NEWTON_THRESHOLD 15
+#define INV_APPR_THRESHOLD 18
+
+#define BINV_NEWTON_THRESHOLD 351
+#define REDC_1_TO_REDC_N_THRESHOLD 84
+
+#define MU_DIV_QR_THRESHOLD 889
+#define MU_DIVAPPR_Q_THRESHOLD 483
+#define MUPI_DIV_QR_THRESHOLD 0 /* always */
+#define MU_BDIV_QR_THRESHOLD 1589
+#define MU_BDIV_Q_THRESHOLD 1787
+
+#define POWM_SEC_TABLE 2,25,95,473,1357
+
+#define MATRIX22_STRASSEN_THRESHOLD 20
+#define HGCD_THRESHOLD 52
+#define HGCD_APPR_THRESHOLD 51
+#define HGCD_REDUCE_THRESHOLD 3524
+#define GCD_DC_THRESHOLD 213
+#define GCDEXT_DC_THRESHOLD 249
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 24
+#define SET_STR_DC_THRESHOLD 145
+#define SET_STR_PRECOMPUTE_THRESHOLD 545
+
+#define FAC_DSC_THRESHOLD 91
+#define FAC_ODD_THRESHOLD 29
diff --git a/gmp/mpn/x86/coreisbr/gmp-mparam.h b/gmp/mpn/x86/coreisbr/gmp-mparam.h
new file mode 100644
index 0000000000..9b227a71ba
--- /dev/null
+++ b/gmp/mpn/x86/coreisbr/gmp-mparam.h
@@ -0,0 +1,203 @@
+/* x86/coreisbr gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 3300 MHz Core i5 Sandy Bridge */
+/* FFT tuning limit = 40000000 */
+/* Generated by tuneup.c, 2014-03-13, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 18
+#define MOD_1_UNNORM_THRESHOLD 11
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 9
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 11
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 9
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 16
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 19
+
+#define MUL_TOOM22_THRESHOLD 28
+#define MUL_TOOM33_THRESHOLD 99
+#define MUL_TOOM44_THRESHOLD 160
+#define MUL_TOOM6H_THRESHOLD 268
+#define MUL_TOOM8H_THRESHOLD 490
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 106
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 140
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 109
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 108
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 137
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 48
+#define SQR_TOOM3_THRESHOLD 105
+#define SQR_TOOM4_THRESHOLD 256
+#define SQR_TOOM6_THRESHOLD 366
+#define SQR_TOOM8_THRESHOLD 562
+
+#define MULMID_TOOM42_THRESHOLD 98
+
+#define MULMOD_BNM1_THRESHOLD 19
+#define SQRMOD_BNM1_THRESHOLD 23
+
+#define MUL_FFT_MODF_THRESHOLD 636 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 636, 5}, { 27, 6}, { 28, 7}, { 15, 6}, \
+ { 32, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
+ { 39, 7}, { 23, 6}, { 47, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
+ { 55,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 103,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 159,10}, { 95, 9}, { 191,11}, \
+ { 63,10}, { 159,11}, { 95,10}, { 191,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
+ { 271, 9}, { 543,11}, { 159,10}, { 319, 9}, \
+ { 639,10}, { 335, 9}, { 671,11}, { 191,10}, \
+ { 383, 9}, { 767,10}, { 399, 9}, { 799,11}, \
+ { 223,12}, { 127,11}, { 255,10}, { 543, 9}, \
+ { 1087,11}, { 287,10}, { 607, 9}, { 1215,11}, \
+ { 319,10}, { 671,12}, { 191,11}, { 383,10}, \
+ { 799,11}, { 415,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
+ { 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
+ { 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 863,12}, { 447,11}, { 959,13}, { 255,12}, \
+ { 511,11}, { 1087,12}, { 575,11}, { 1215,10}, \
+ { 2431,12}, { 639,11}, { 1343,12}, { 703,11}, \
+ { 1471,13}, { 383,12}, { 767,11}, { 1599,12}, \
+ { 831,11}, { 1727,12}, { 959,14}, { 255,13}, \
+ { 511,12}, { 1087,11}, { 2239,12}, { 1215,11}, \
+ { 2431,13}, { 639,12}, { 1471,11}, { 2943,13}, \
+ { 767,12}, { 1727,13}, { 895,12}, { 1983,14}, \
+ { 511,13}, { 1023,12}, { 2239,13}, { 1151,12}, \
+ { 2431,13}, { 1279,12}, { 2559,13}, { 1407,12}, \
+ { 2943,14}, { 767,13}, { 1535,12}, { 3071,13}, \
+ { 1663,12}, { 3455,13}, { 1919,15}, { 511,14}, \
+ { 1023,13}, { 2175,12}, { 4479,13}, { 2431,14}, \
+ { 1279,13}, { 2943,12}, { 5887,14}, { 16384,15}, \
+ { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 149
+#define MUL_FFT_THRESHOLD 7424
+
+#define SQR_FFT_MODF_THRESHOLD 555 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 555, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
+ { 29, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
+ { 36, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 43, 8}, { 23, 7}, { 47, 8}, \
+ { 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
+ { 43, 9}, { 23, 8}, { 51, 9}, { 31, 8}, \
+ { 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
+ { 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
+ { 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
+ { 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
+ { 191,10}, { 111,11}, { 63,10}, { 159,11}, \
+ { 95,10}, { 191,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 543,11}, { 159,10}, { 319, 9}, \
+ { 639,10}, { 335, 9}, { 671,10}, { 351,11}, \
+ { 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
+ { 799,10}, { 415,12}, { 127,11}, { 255,10}, \
+ { 511, 9}, { 1023,10}, { 543,11}, { 287,10}, \
+ { 607,11}, { 319,10}, { 671,11}, { 351,12}, \
+ { 191,11}, { 383,10}, { 799,11}, { 415,13}, \
+ { 127,12}, { 255,11}, { 511,10}, { 1023,11}, \
+ { 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
+ { 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
+ { 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 863,10}, { 1727,12}, { 447,11}, { 959,10}, \
+ { 1919,11}, { 991,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1215,10}, { 2431,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1471,13}, \
+ { 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
+ { 1727,12}, { 959,11}, { 1919,14}, { 255,13}, \
+ { 511,12}, { 1023,11}, { 2047,12}, { 1087,11}, \
+ { 2239,12}, { 1215,11}, { 2431,13}, { 639,12}, \
+ { 1471,11}, { 2943,13}, { 767,12}, { 1727,13}, \
+ { 895,12}, { 1983,14}, { 511,13}, { 1023,12}, \
+ { 2239,13}, { 1151,12}, { 2495,13}, { 1279,12}, \
+ { 2623,13}, { 1407,12}, { 2943,14}, { 767,13}, \
+ { 1663,12}, { 3455,13}, { 1919,12}, { 3839,15}, \
+ { 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
+ { 2431,12}, { 4863,14}, { 1279,13}, { 2943,12}, \
+ { 5887,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 159
+#define SQR_FFT_THRESHOLD 5760
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 62
+#define MULLO_MUL_N_THRESHOLD 14281
+
+#define DC_DIV_QR_THRESHOLD 25
+#define DC_DIVAPPR_Q_THRESHOLD 43
+#define DC_BDIV_QR_THRESHOLD 99
+#define DC_BDIV_Q_THRESHOLD 240
+
+#define INV_MULMOD_BNM1_THRESHOLD 54
+#define INV_NEWTON_THRESHOLD 14
+#define INV_APPR_THRESHOLD 13
+
+#define BINV_NEWTON_THRESHOLD 363
+#define REDC_1_TO_REDC_N_THRESHOLD 90
+
+#define MU_DIV_QR_THRESHOLD 998
+#define MU_DIVAPPR_Q_THRESHOLD 667
+#define MUPI_DIV_QR_THRESHOLD 0 /* always */
+#define MU_BDIV_QR_THRESHOLD 1787
+#define MU_BDIV_Q_THRESHOLD 2130
+
+#define POWM_SEC_TABLE 1,16,126,480,1317
+
+#define MATRIX22_STRASSEN_THRESHOLD 21
+#define HGCD_THRESHOLD 61
+#define HGCD_APPR_THRESHOLD 56
+#define HGCD_REDUCE_THRESHOLD 3810
+#define GCD_DC_THRESHOLD 283
+#define GCDEXT_DC_THRESHOLD 309
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 21
+#define SET_STR_DC_THRESHOLD 399
+#define SET_STR_PRECOMPUTE_THRESHOLD 1183
+
+#define FAC_DSC_THRESHOLD 194
+#define FAC_ODD_THRESHOLD 34
diff --git a/gmp/mpn/x86/darwin.m4 b/gmp/mpn/x86/darwin.m4
new file mode 100644
index 0000000000..f8363db3f7
--- /dev/null
+++ b/gmp/mpn/x86/darwin.m4
@@ -0,0 +1,82 @@
+divert(-1)
+dnl Copyright 2007, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`DARWIN')
+
+
+dnl Usage LEA(symbol,reg)
+dnl
+dnl We maintain lists of stuff to append in load_eip and darwin_bd. The
+dnl `index' stuff is needed to suppress repeated definitions. To avoid
+dnl getting fooled by "var" and "var1", we add 'bol ' (the end of
+dnl 'indirect_symbol') at the beginning and and a newline at the end. This
+dnl might be a bit fragile.
+
+define(`LEA',
+m4_assert_numargs(2)
+`ifdef(`PIC',`
+ifelse(index(defn(`load_eip'), `$2'),-1,
+`m4append(`load_eip',
+`L(movl_eip_`'substr($2,1)):
+ movl (%esp), $2
+ ret_internal
+')')
+ifelse(index(defn(`darwin_bd'), `bol $1
+'),-1,
+`m4append(`darwin_bd',
+` .section __IMPORT,__pointers,non_lazy_symbol_pointers
+L($1`'$non_lazy_ptr):
+ .indirect_symbol $1
+ .long 0
+')')
+ call L(movl_eip_`'substr($2,1))
+ movl L($1`'$non_lazy_ptr)-.($2), $2
+',`
+ movl `$'$1, $2
+')')
+
+
+dnl EPILOGUE_cpu
+
+define(`EPILOGUE_cpu',`load_eip`'darwin_bd')
+
+define(`load_eip', `') dnl updated in LEA
+define(`darwin_bd', `') dnl updated in LEA
+
+
+dnl Usage: CALL(funcname)
+dnl
+
+define(`CALL',
+m4_assert_numargs(1)
+`call GSYM_PREFIX`'$1')
+
+undefine(`PIC_WITH_EBX')
+
+divert`'dnl
diff --git a/gmp/mpn/x86/dive_1.asm b/gmp/mpn/x86/dive_1.asm
new file mode 100644
index 0000000000..9a6cbb7931
--- /dev/null
+++ b/gmp/mpn/x86/dive_1.asm
@@ -0,0 +1,189 @@
+dnl x86 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2001, 2002, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P54 30.0
+C P55 29.0
+C P6 13.0 odd divisor, 12.0 even (strangely)
+C K6 14.0
+C K7 12.0
+C P4 42.0
+
+
+C mp_limb_t mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(VAR_INVERSE,`PARAM_SRC')
+
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(mpn_divexact_1)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %eax
+ pushl %ebp FRAME_pushl()
+
+ movl PARAM_SIZE, %ebp
+ pushl %edi FRAME_pushl()
+
+ pushl %ebx FRAME_pushl()
+ movl $-1, %ecx C shift count
+
+ pushl %esi FRAME_pushl()
+
+L(strip_twos):
+ incl %ecx
+
+ shrl %eax
+ jnc L(strip_twos)
+
+ leal 1(%eax,%eax), %ebx C d without twos
+ andl $127, %eax C d/2, 7 bits
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %edx)
+ movzbl (%eax,%edx), %eax C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+
+ leal (%eax,%eax), %edx C 2*inv
+ movl %ebx, PARAM_DIVISOR C d without twos
+
+ imull %eax, %eax C inv*inv
+
+ movl PARAM_SRC, %esi
+ movl PARAM_DST, %edi
+
+ imull %ebx, %eax C inv*inv*d
+
+ subl %eax, %edx C inv = 2*inv - inv*inv*d
+ leal (%edx,%edx), %eax C 2*inv
+
+ imull %edx, %edx C inv*inv
+
+ leal (%esi,%ebp,4), %esi C src end
+ leal (%edi,%ebp,4), %edi C dst end
+ negl %ebp C -size
+
+ imull %ebx, %edx C inv*inv*d
+
+ subl %edx, %eax C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ imull PARAM_DIVISOR, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ movl %eax, VAR_INVERSE
+ movl (%esi,%ebp,4), %eax C src[0]
+
+ xorl %ebx, %ebx
+ xorl %edx, %edx
+
+ incl %ebp
+ jz L(one)
+
+ movl (%esi,%ebp,4), %edx C src[1]
+
+ shrdl( %cl, %edx, %eax)
+
+ movl VAR_INVERSE, %edx
+ jmp L(entry)
+
+
+ ALIGN(8)
+ nop C k6 code alignment
+ nop
+L(top):
+ C eax q
+ C ebx carry bit, 0 or -1
+ C ecx shift
+ C edx carry limb
+ C esi src end
+ C edi dst end
+ C ebp counter, limbs, negative
+
+ movl -4(%esi,%ebp,4), %eax
+ subl %ebx, %edx C accumulate carry bit
+
+ movl (%esi,%ebp,4), %ebx
+
+ shrdl( %cl, %ebx, %eax)
+
+ subl %edx, %eax C apply carry limb
+ movl VAR_INVERSE, %edx
+
+ sbbl %ebx, %ebx
+
+L(entry):
+ imull %edx, %eax
+
+ movl %eax, -4(%edi,%ebp,4)
+ movl PARAM_DIVISOR, %edx
+
+ mull %edx
+
+ incl %ebp
+ jnz L(top)
+
+
+ movl -4(%esi), %eax C src high limb
+L(one):
+ shrl %cl, %eax
+ popl %esi FRAME_popl()
+
+ addl %ebx, %eax C apply carry bit
+ popl %ebx FRAME_popl()
+
+ subl %edx, %eax C apply carry limb
+
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi)
+
+ popl %edi
+ popl %ebp
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/divrem_1.asm b/gmp/mpn/x86/divrem_1.asm
new file mode 100644
index 0000000000..255d4935c3
--- /dev/null
+++ b/gmp/mpn/x86/divrem_1.asm
@@ -0,0 +1,233 @@
+dnl x86 mpn_divrem_1 -- mpn by limb division extending to fractional quotient.
+
+dnl Copyright 1999-2003, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C 486 approx 43 maybe
+C P5 44
+C P6 39
+C P6MMX 39
+C K6 22
+C K7 42
+C P4 58
+
+
+C mp_limb_t mpn_divrem_1 (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size, mp_limb_t divisor);
+C mp_limb_t mpn_divrem_1c (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size, mp_limb_t divisor,
+C mp_limb_t carry);
+C
+C Divide src,size by divisor and store the quotient in dst+xsize,size.
+C Extend the division to fractional quotient limbs in dst,xsize. Return the
+C remainder. Either or both xsize and size can be 0.
+C
+C mpn_divrem_1c takes a carry parameter which is an initial high limb,
+C effectively one extra limb at the top of src,size. Must have
+C carry<divisor.
+C
+C
+C Essentially the code is the same as the division based part of
+C mpn/generic/divrem_1.c, but has the advantage that we get the desired divl
+C instruction even when gcc is not being used (when longlong.h only has the
+C rather slow generic C udiv_qrnnd().
+C
+C A test is done to see if the high limb is less than the divisor, and if so
+C one less div is done. A div is between 20 and 40 cycles on the various
+C x86s, so assuming high<divisor about half the time, then this test saves
+C half that amount. The branch misprediction penalty on each chip is less
+C than half a div.
+C
+C
+C Notes for P5:
+C
+C It might be thought that moving the load down to pair with the store would
+C save 1 cycle, but that doesn't seem to happen in practice, and in any case
+C would be a mere 2.2% saving, so it's hardly worth bothering about.
+C
+C A mul-by-inverse might be a possibility for P5, as done in
+C mpn/x86/pentium/mod_1.asm. The number of auxiliary instructions required
+C is a hinderance, but there could be a 10-15% speedup available.
+C
+C
+C Notes for K6:
+C
+C K6 has its own version of this code, using loop and paying attention to
+C cache line boundary crossings. The target 20 c/l can be had with the
+C decl+jnz of the present code by pairing up the load and store in the
+C loops. But it's considered easier not to introduce complexity just for
+C that, but instead let k6 have its own code.
+C
+
+defframe(PARAM_CARRY, 24)
+defframe(PARAM_DIVISOR,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC, 12)
+defframe(PARAM_XSIZE, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(mpn_divrem_1c)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ pushl %edi FRAME_pushl()
+
+ movl PARAM_SRC, %edi
+ pushl %esi FRAME_pushl()
+
+ movl PARAM_DIVISOR, %esi
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_DST, %ebx
+ pushl %ebp FRAME_pushl()
+
+ movl PARAM_XSIZE, %ebp
+ orl %ecx, %ecx
+
+ movl PARAM_CARRY, %edx
+ jz L(fraction)
+
+ leal -4(%ebx,%ebp,4), %ebx C dst one limb below integer part
+ jmp L(integer_top)
+
+EPILOGUE()
+
+
+PROLOGUE(mpn_divrem_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ pushl %edi FRAME_pushl()
+
+ movl PARAM_SRC, %edi
+ pushl %esi FRAME_pushl()
+
+ movl PARAM_DIVISOR, %esi
+ orl %ecx,%ecx
+
+ jz L(size_zero)
+ pushl %ebx FRAME_pushl()
+
+ movl -4(%edi,%ecx,4), %eax C src high limb
+ xorl %edx, %edx
+
+ movl PARAM_DST, %ebx
+ pushl %ebp FRAME_pushl()
+
+ movl PARAM_XSIZE, %ebp
+ cmpl %esi, %eax
+
+ leal -4(%ebx,%ebp,4), %ebx C dst one limb below integer part
+ jae L(integer_entry)
+
+
+ C high<divisor, so high of dst is zero, and avoid one div
+
+ movl %edx, (%ebx,%ecx,4)
+ decl %ecx
+
+ movl %eax, %edx
+ jz L(fraction)
+
+
+L(integer_top):
+ C eax scratch (quotient)
+ C ebx dst+4*xsize-4
+ C ecx counter
+ C edx scratch (remainder)
+ C esi divisor
+ C edi src
+ C ebp xsize
+
+ movl -4(%edi,%ecx,4), %eax
+L(integer_entry):
+
+ divl %esi
+
+ movl %eax, (%ebx,%ecx,4)
+ decl %ecx
+ jnz L(integer_top)
+
+
+L(fraction):
+ orl %ebp, %ecx
+ jz L(done)
+
+ movl PARAM_DST, %ebx
+
+
+L(fraction_top):
+ C eax scratch (quotient)
+ C ebx dst
+ C ecx counter
+ C edx scratch (remainder)
+ C esi divisor
+ C edi
+ C ebp
+
+ xorl %eax, %eax
+
+ divl %esi
+
+ movl %eax, -4(%ebx,%ecx,4)
+ decl %ecx
+ jnz L(fraction_top)
+
+
+L(done):
+ popl %ebp
+ movl %edx, %eax
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
+L(size_zero):
+deflit(`FRAME',8)
+ movl PARAM_XSIZE, %ecx
+ xorl %eax, %eax
+
+ movl PARAM_DST, %edi
+
+ cld C better safe than sorry, see mpn/x86/README
+
+ rep
+ stosl
+
+ popl %esi
+ popl %edi
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/divrem_2.asm b/gmp/mpn/x86/divrem_2.asm
new file mode 100644
index 0000000000..4c38ad0acb
--- /dev/null
+++ b/gmp/mpn/x86/divrem_2.asm
@@ -0,0 +1,199 @@
+dnl x86 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number.
+
+dnl Copyright 2007, 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C norm frac
+C 486
+C P5
+C P6-13 29.2
+C P6-15 *26
+C K6
+C K7 22
+C K8 *19
+C P4-f1
+C P4-f2 *65
+C P4-f3
+C P4-f4 *72
+
+C A star means numbers not updated for the latest version of the code.
+
+
+C TODO
+C * Perhaps keep ecx or esi in stack slot, freeing up a reg for q0.
+C * The loop has not been carefully tuned. We should at the very least do
+C some local insn swapping.
+C * The code outside the main loop is what gcc generated. Clean up!
+C * Clean up stack slot usage.
+
+C INPUT PARAMETERS
+C qp
+C fn
+C up_param
+C un_param
+C dp
+
+
+C eax ebx ecx edx esi edi ebp
+C cnt qp
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_divrem_2)
+ push %ebp
+ push %edi
+ push %esi
+ push %ebx
+ sub $36, %esp
+ mov 68(%esp), %ecx C un
+ mov 72(%esp), %esi C dp
+ movl $0, 32(%esp)
+ lea 0(,%ecx,4), %edi
+ add 64(%esp), %edi C up
+ mov (%esi), %ebx
+ mov 4(%esi), %eax
+ mov %ebx, 20(%esp)
+ sub $12, %edi
+ mov %eax, 24(%esp)
+ mov %edi, 12(%esp)
+ mov 8(%edi), %ebx
+ mov 4(%edi), %ebp
+ cmp %eax, %ebx
+ jb L(8)
+ seta %dl
+ cmp 20(%esp), %ebp
+ setae %al
+ orb %dl, %al C "orb" form to placate Sun tools
+ jne L(35)
+L(8):
+ mov 60(%esp), %esi C fn
+ lea -3(%esi,%ecx), %edi
+ test %edi, %edi
+ js L(9)
+ mov 24(%esp), %edx
+ mov $-1, %esi
+ mov %esi, %eax
+ mov %esi, %ecx
+ not %edx
+ divl 24(%esp)
+ mov %eax, %esi
+ imul 24(%esp), %eax
+ mov %eax, (%esp)
+ mov %esi, %eax
+ mull 20(%esp)
+ mov (%esp), %eax
+ add 20(%esp), %eax
+ adc $0, %ecx
+ add %eax, %edx
+ adc $0, %ecx
+ mov %ecx, %eax
+ js L(32)
+L(36): dec %esi
+ sub 24(%esp), %edx
+ sbb $0, %eax
+ jns L(36)
+L(32):
+ mov %esi, 16(%esp) C di
+ mov %edi, %ecx C un
+ mov 12(%esp), %esi C up
+ mov 24(%esp), %eax
+ neg %eax
+ mov %eax, 4(%esp) C -d1
+ ALIGN(16)
+ nop
+
+C eax ebx ecx edx esi edi ebp 0 4 8 12 16 20 24 28 32 56 60
+C n2 un up n1 q0 -d1 di d0 d1 msl qp fn
+
+L(loop):
+ mov 16(%esp), %eax C di
+ mul %ebx
+ add %ebp, %eax
+ mov %eax, (%esp) C q0
+ adc %ebx, %edx
+ mov %edx, %edi C q
+ imul 4(%esp), %edx
+ mov 20(%esp), %eax
+ lea (%edx, %ebp), %ebx C n1 -= ...
+ mul %edi
+ xor %ebp, %ebp
+ cmp 60(%esp), %ecx
+ jl L(19)
+ mov (%esi), %ebp
+ sub $4, %esi
+L(19): sub 20(%esp), %ebp
+ sbb 24(%esp), %ebx
+ sub %eax, %ebp
+ sbb %edx, %ebx
+ mov 20(%esp), %eax C d1
+ inc %edi
+ xor %edx, %edx
+ cmp (%esp), %ebx
+ adc $-1, %edx C mask
+ add %edx, %edi C q--
+ and %edx, %eax C d0 or 0
+ and 24(%esp), %edx C d1 or 0
+ add %eax, %ebp
+ adc %edx, %ebx
+ cmp 24(%esp), %ebx
+ jae L(fix)
+L(bck): mov 56(%esp), %edx
+ mov %edi, (%edx, %ecx, 4)
+ dec %ecx
+ jns L(loop)
+
+L(9): mov 64(%esp), %esi C up
+ mov %ebp, (%esi)
+ mov %ebx, 4(%esi)
+ mov 32(%esp), %eax
+ add $36, %esp
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+ ret
+
+L(fix): seta %dl
+ cmp 20(%esp), %ebp
+ setae %al
+ orb %dl, %al C "orb" form to placate Sun tools
+ je L(bck)
+ inc %edi
+ sub 20(%esp), %ebp
+ sbb 24(%esp), %ebx
+ jmp L(bck)
+
+L(35): sub 20(%esp), %ebp
+ sbb 24(%esp), %ebx
+ movl $1, 32(%esp)
+ jmp L(8)
+EPILOGUE()
diff --git a/gmp/mpn/x86/fat/com.c b/gmp/mpn/x86/fat/com.c
new file mode 100644
index 0000000000..d359d4ce73
--- /dev/null
+++ b/gmp/mpn/x86/fat/com.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_com.
+
+Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/com.c"
diff --git a/gmp/mpn/x86/fat/fat.c b/gmp/mpn/x86/fat/fat.c
new file mode 100644
index 0000000000..1740813886
--- /dev/null
+++ b/gmp/mpn/x86/fat/fat.c
@@ -0,0 +1,473 @@
+/* x86 fat binary initializers.
+
+ THE FUNCTIONS AND VARIABLES IN THIS FILE ARE FOR INTERNAL USE ONLY.
+ THEY'RE ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR
+ COMPLETELY IN FUTURE GNU MP RELEASES.
+
+Copyright 2003, 2004, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for printf */
+#include <stdlib.h> /* for getenv */
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Change this to "#define TRACE(x) x" for some traces. */
+#define TRACE(x)
+
+
+/* fat_entry.asm */
+long __gmpn_cpuid (char [12], int);
+int __gmpn_cpuid_available (void);
+
+
+#if WANT_FAKE_CPUID
+/* The "name"s in the table are values for the GMP_CPU_TYPE environment
+ variable. Anything can be used, but for now it's the canonical cpu types
+ as per config.guess/config.sub. */
+
+#define __gmpn_cpuid fake_cpuid
+#define __gmpn_cpuid_available fake_cpuid_available
+
+#define MAKE_FMS(family, model) \
+ ((((family) & 0xf) << 8) + (((family) & 0xff0) << 20) \
+ + (((model) & 0xf) << 4) + (((model) & 0xf0) << 12))
+
+static struct {
+ const char *name;
+ const char vendor[13];
+ unsigned fms;
+} fake_cpuid_table[] = {
+ { "i386", "" },
+ { "i486", "GenuineIntel", MAKE_FMS (4, 0) },
+ { "pentium", "GenuineIntel", MAKE_FMS (5, 0) },
+ { "pentiummmx", "GenuineIntel", MAKE_FMS (5, 4) },
+ { "pentiumpro", "GenuineIntel", MAKE_FMS (6, 0) },
+ { "pentium2", "GenuineIntel", MAKE_FMS (6, 2) },
+ { "pentium3", "GenuineIntel", MAKE_FMS (6, 7) },
+ { "pentium4", "GenuineIntel", MAKE_FMS (15, 2) },
+ { "prescott", "GenuineIntel", MAKE_FMS (15, 3) },
+ { "nocona", "GenuineIntel", MAKE_FMS (15, 4) },
+ { "core2", "GenuineIntel", MAKE_FMS (6, 0xf) },
+ { "coreinhm", "GenuineIntel", MAKE_FMS (6, 0x1a) },
+ { "coreiwsm", "GenuineIntel", MAKE_FMS (6, 0x25) },
+ { "coreisbr", "GenuineIntel", MAKE_FMS (6, 0x2a) },
+ { "coreihwl", "GenuineIntel", MAKE_FMS (6, 0x3c) },
+ { "atom", "GenuineIntel", MAKE_FMS (6, 0x1c) },
+
+ { "k5", "AuthenticAMD", MAKE_FMS (5, 0) },
+ { "k6", "AuthenticAMD", MAKE_FMS (5, 3) },
+ { "k62", "AuthenticAMD", MAKE_FMS (5, 8) },
+ { "k63", "AuthenticAMD", MAKE_FMS (5, 9) },
+ { "athlon", "AuthenticAMD", MAKE_FMS (6, 0) },
+ { "k8", "AuthenticAMD", MAKE_FMS (15, 0) },
+ { "k10", "AuthenticAMD", MAKE_FMS (16, 0) },
+ { "bobcat", "AuthenticAMD", MAKE_FMS (20, 1) },
+ { "bulldozer", "AuthenticAMD", MAKE_FMS (21, 1) },
+
+ { "viac3", "CentaurHauls", MAKE_FMS (6, 0) },
+ { "viac32", "CentaurHauls", MAKE_FMS (6, 9) },
+ { "nano", "CentaurHauls", MAKE_FMS (6, 15) },
+};
+
+static int
+fake_cpuid_lookup (void)
+{
+ char *s;
+ int i;
+
+ s = getenv ("GMP_CPU_TYPE");
+ if (s == NULL)
+ {
+ printf ("Need GMP_CPU_TYPE environment variable for fake cpuid\n");
+ abort ();
+ }
+
+ for (i = 0; i < numberof (fake_cpuid_table); i++)
+ if (strcmp (s, fake_cpuid_table[i].name) == 0)
+ return i;
+
+ printf ("GMP_CPU_TYPE=%s unknown\n", s);
+ abort ();
+}
+
+static int
+fake_cpuid_available (void)
+{
+ return fake_cpuid_table[fake_cpuid_lookup()].vendor[0] != '\0';
+}
+
+static long
+fake_cpuid (char dst[12], int id)
+{
+ int i = fake_cpuid_lookup();
+
+ switch (id) {
+ case 0:
+ memcpy (dst, fake_cpuid_table[i].vendor, 12);
+ return 0;
+ case 1:
+ return fake_cpuid_table[i].fms;
+ default:
+ printf ("fake_cpuid(): oops, unknown id %d\n", id);
+ abort ();
+ }
+}
+#endif
+
+
+typedef DECL_preinv_divrem_1 ((*preinv_divrem_1_t));
+typedef DECL_preinv_mod_1 ((*preinv_mod_1_t));
+
+struct cpuvec_t __gmpn_cpuvec = {
+ __MPN(add_n_init),
+ 0,
+ 0,
+ __MPN(addmul_1_init),
+ 0,
+ __MPN(bdiv_dbm1c_init),
+ __MPN(cnd_add_n_init),
+ __MPN(cnd_sub_n_init),
+ __MPN(com_init),
+ __MPN(copyd_init),
+ __MPN(copyi_init),
+ __MPN(divexact_1_init),
+ __MPN(divrem_1_init),
+ __MPN(gcd_1_init),
+ __MPN(lshift_init),
+ __MPN(lshiftc_init),
+ __MPN(mod_1_init),
+ __MPN(mod_1_1p_init),
+ __MPN(mod_1_1p_cps_init),
+ __MPN(mod_1s_2p_init),
+ __MPN(mod_1s_2p_cps_init),
+ __MPN(mod_1s_4p_init),
+ __MPN(mod_1s_4p_cps_init),
+ __MPN(mod_34lsub1_init),
+ __MPN(modexact_1c_odd_init),
+ __MPN(mul_1_init),
+ __MPN(mul_basecase_init),
+ __MPN(mullo_basecase_init),
+ __MPN(preinv_divrem_1_init),
+ __MPN(preinv_mod_1_init),
+ __MPN(redc_1_init),
+ __MPN(redc_2_init),
+ __MPN(rshift_init),
+ __MPN(sqr_basecase_init),
+ __MPN(sub_n_init),
+ 0,
+ __MPN(submul_1_init),
+ 0
+};
+
+int __gmpn_cpuvec_initialized = 0;
+
+/* The following setups start with generic x86, then overwrite with
+ specifics for a chip, and higher versions of that chip.
+
+ The arrangement of the setups here will normally be the same as the $path
+ selections in configure.in for the respective chips.
+
+ This code is reentrant and thread safe. We always calculate the same
+ decided_cpuvec, so if two copies of the code are running it doesn't
+ matter which completes first, both write the same to __gmpn_cpuvec.
+
+ We need to go via decided_cpuvec because if one thread has completed
+ __gmpn_cpuvec then it may be making use of the threshold values in that
+ vector. If another thread is still running __gmpn_cpuvec_init then we
+ don't want it to write different values to those fields since some of the
+ asm routines only operate correctly up to their own defined threshold,
+ not an arbitrary value. */
+
+void
+__gmpn_cpuvec_init (void)
+{
+ struct cpuvec_t decided_cpuvec;
+
+ TRACE (printf ("__gmpn_cpuvec_init:\n"));
+
+ memset (&decided_cpuvec, '\0', sizeof (decided_cpuvec));
+
+ CPUVEC_SETUP_x86;
+ CPUVEC_SETUP_fat;
+
+ if (! __gmpn_cpuid_available ())
+ {
+ TRACE (printf (" 80386, or early 80486 without cpuid\n"));
+ }
+ else
+ {
+ char vendor_string[13];
+ char dummy_string[12];
+ long fms;
+ int family, model;
+
+ __gmpn_cpuid (vendor_string, 0);
+ vendor_string[12] = 0;
+
+ fms = __gmpn_cpuid (dummy_string, 1);
+ family = ((fms >> 8) & 0xf) + ((fms >> 20) & 0xff);
+ model = ((fms >> 4) & 0xf) + ((fms >> 12) & 0xf0);
+
+ if (strcmp (vendor_string, "GenuineIntel") == 0)
+ {
+ switch (family)
+ {
+ case 4:
+ TRACE (printf (" 80486 with cpuid\n"));
+ break;
+
+ case 5:
+ TRACE (printf (" pentium\n"));
+ CPUVEC_SETUP_pentium;
+ if (model >= 4)
+ {
+ TRACE (printf (" pentiummmx\n"));
+ CPUVEC_SETUP_pentium_mmx;
+ }
+ break;
+
+ case 6:
+ TRACE (printf (" p6\n"));
+ CPUVEC_SETUP_p6;
+ switch (model)
+ {
+ case 0x00:
+ case 0x01:
+ TRACE (printf (" pentiumpro\n"));
+ break;
+
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ TRACE (printf (" pentium2\n"));
+ CPUVEC_SETUP_p6_mmx;
+ break;
+
+ case 0x07:
+ case 0x08:
+ case 0x0a:
+ case 0x0b:
+ case 0x0c:
+ TRACE (printf (" pentium3\n"));
+ CPUVEC_SETUP_p6_mmx;
+ CPUVEC_SETUP_p6_p3mmx;
+ break;
+
+ case 0x09: /* Banias */
+ case 0x0d: /* Dothan */
+ case 0x0e: /* Yonah */
+ TRACE (printf (" Banias/Dothan/Yonah\n"));
+ CPUVEC_SETUP_p6_mmx;
+ CPUVEC_SETUP_p6_p3mmx;
+ CPUVEC_SETUP_p6_sse2;
+ break;
+
+ case 0x0f: /* Conroe Merom Kentsfield Allendale */
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17: /* PNR Wolfdale Yorkfield */
+ case 0x18:
+ case 0x19:
+ case 0x1d: /* PNR Dunnington */
+ TRACE (printf (" Conroe\n"));
+ CPUVEC_SETUP_p6_mmx;
+ CPUVEC_SETUP_p6_p3mmx;
+ CPUVEC_SETUP_p6_sse2;
+ CPUVEC_SETUP_core2;
+ break;
+
+ case 0x1c: /* Atom Silverthorne */
+ case 0x26: /* Atom Lincroft */
+ case 0x27: /* Atom Saltwell */
+ case 0x36: /* Atom Cedarview/Saltwell */
+ TRACE (printf (" atom\n"));
+ CPUVEC_SETUP_atom;
+ CPUVEC_SETUP_atom_mmx;
+ CPUVEC_SETUP_atom_sse2;
+ break;
+
+ case 0x1a: /* NHM Gainestown */
+ case 0x1b:
+ case 0x1e: /* NHM Lynnfield/Jasper */
+ case 0x1f:
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25: /* WSM Clarkdale/Arrandale */
+ case 0x28:
+ case 0x29:
+ case 0x2b:
+ case 0x2c: /* WSM Gulftown */
+ case 0x2e: /* NHM Beckton */
+ case 0x2f: /* WSM Eagleton */
+ TRACE (printf (" nehalem/westmere\n"));
+ CPUVEC_SETUP_p6_mmx;
+ CPUVEC_SETUP_p6_p3mmx;
+ CPUVEC_SETUP_p6_sse2;
+ CPUVEC_SETUP_core2;
+ CPUVEC_SETUP_coreinhm;
+ break;
+
+ case 0x2a: /* SBR */
+ case 0x2d: /* SBR-EP */
+ case 0x3a: /* IBR */
+ case 0x3c: /* Haswell */
+ TRACE (printf (" sandybridge\n"));
+ CPUVEC_SETUP_p6_mmx;
+ CPUVEC_SETUP_p6_p3mmx;
+ CPUVEC_SETUP_p6_sse2;
+ CPUVEC_SETUP_core2;
+ CPUVEC_SETUP_coreinhm;
+ CPUVEC_SETUP_coreisbr;
+ break;
+ }
+ break;
+
+ case 15:
+ TRACE (printf (" pentium4\n"));
+ CPUVEC_SETUP_pentium4;
+ CPUVEC_SETUP_pentium4_mmx;
+ CPUVEC_SETUP_pentium4_sse2;
+ break;
+ }
+ }
+ else if (strcmp (vendor_string, "AuthenticAMD") == 0)
+ {
+ switch (family)
+ {
+ case 5:
+ if (model <= 3)
+ {
+ TRACE (printf (" k5\n"));
+ }
+ else
+ {
+ TRACE (printf (" k6\n"));
+ CPUVEC_SETUP_k6;
+ CPUVEC_SETUP_k6_mmx;
+ if (model >= 8)
+ {
+ TRACE (printf (" k62\n"));
+ CPUVEC_SETUP_k6_k62mmx;
+ }
+ if (model >= 9)
+ {
+ TRACE (printf (" k63\n"));
+ }
+ }
+ break;
+ case 6:
+ TRACE (printf (" athlon\n"));
+ CPUVEC_SETUP_k7;
+ CPUVEC_SETUP_k7_mmx;
+ break;
+
+ case 0x0f: /* k8 */
+ case 0x11: /* "fam 11h", mix of k8 and k10 */
+ case 0x13: /* unknown, conservatively assume k8 */
+ case 0x16: /* unknown, conservatively assume k8 */
+ case 0x17: /* unknown, conservatively assume k8 */
+ TRACE (printf (" k8\n"));
+ CPUVEC_SETUP_k7;
+ CPUVEC_SETUP_k7_mmx;
+ CPUVEC_SETUP_k8;
+ break;
+
+ case 0x10: /* k10 */
+ case 0x12: /* k10 (llano) */
+ TRACE (printf (" k10\n"));
+ CPUVEC_SETUP_k7;
+ CPUVEC_SETUP_k7_mmx;
+ break;
+
+ case 0x14: /* bobcat */
+ TRACE (printf (" bobcat\n"));
+ CPUVEC_SETUP_k7;
+ CPUVEC_SETUP_k7_mmx;
+ CPUVEC_SETUP_bobcat;
+ break;
+
+ case 0x15: /* bulldozer */
+ TRACE (printf (" bulldozer\n"));
+ CPUVEC_SETUP_k7;
+ CPUVEC_SETUP_k7_mmx;
+ break;
+ }
+ }
+ else if (strcmp (vendor_string, "CentaurHauls") == 0)
+ {
+ switch (family)
+ {
+ case 6:
+ TRACE (printf (" viac3\n"));
+ if (model >= 9)
+ {
+ TRACE (printf (" viac32\n"));
+ }
+ if (model >= 15)
+ {
+ TRACE (printf (" nano\n"));
+ CPUVEC_SETUP_nano;
+ }
+ break;
+ }
+ }
+ else if (strcmp (vendor_string, "CyrixInstead") == 0)
+ {
+ /* Should recognize Cyrix' processors too. */
+ TRACE (printf (" cyrix something\n"));
+ }
+ }
+
+ /* There's no x86 generic mpn_preinv_divrem_1 or mpn_preinv_mod_1.
+ Instead default to the plain versions from whichever CPU we detected.
+ The function arguments are compatible, no need for any glue code. */
+ if (decided_cpuvec.preinv_divrem_1 == NULL)
+ decided_cpuvec.preinv_divrem_1 =(preinv_divrem_1_t)decided_cpuvec.divrem_1;
+ if (decided_cpuvec.preinv_mod_1 == NULL)
+ decided_cpuvec.preinv_mod_1 =(preinv_mod_1_t) decided_cpuvec.mod_1;
+
+ ASSERT_CPUVEC (decided_cpuvec);
+ CPUVEC_INSTALL (decided_cpuvec);
+
+ /* Set this once the threshold fields are ready.
+ Use volatile to prevent it getting moved. */
+ *((volatile int *) &__gmpn_cpuvec_initialized) = 1;
+}
diff --git a/gmp/mpn/x86/fat/fat_entry.asm b/gmp/mpn/x86/fat/fat_entry.asm
new file mode 100644
index 0000000000..6e3cb44dd5
--- /dev/null
+++ b/gmp/mpn/x86/fat/fat_entry.asm
@@ -0,0 +1,220 @@
+dnl x86 fat binary entrypoints.
+
+dnl Copyright 2003, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+dnl Forcibly disable profiling.
+dnl
+dnl The entrypoints and inits are small enough not to worry about, the real
+dnl routines arrived at will have any profiling. Also, the way the code
+dnl here ends with a jump means we won't work properly with the
+dnl "instrument" profiling scheme anyway.
+
+define(`WANT_PROFILING',no)
+
+
+ TEXT
+
+
+dnl Usage: FAT_ENTRY(name, offset)
+dnl
+dnl Emit a fat binary entrypoint function of the given name. This is the
+dnl normal entry for applications, eg. __gmpn_add_n.
+dnl
+dnl The code simply jumps through the function pointer in __gmpn_cpuvec at
+dnl the given "offset" (in bytes).
+dnl
+dnl For non-PIC, the jumps are 5 bytes each, aligning them to 8 should be
+dnl fine for all x86s.
+dnl
+dnl For PIC, the jumps are 20 bytes each, and are best aligned to 16 to
+dnl ensure at least the first two instructions don't cross a cache line
+dnl boundary.
+dnl
+dnl Note the extra `' ahead of PROLOGUE obscures it from the HAVE_NATIVE
+dnl grepping in configure, stopping that code trying to eval something with
+dnl $1 in it.
+
+define(FAT_ENTRY,
+m4_assert_numargs(2)
+` ALIGN(ifdef(`PIC',16,8))
+`'PROLOGUE($1)
+ifdef(`PIC',
+` call L(movl_eip_edx)
+L(entry_here$2):
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(entry_here$2)], %edx
+ movl GSYM_PREFIX`'__gmpn_cpuvec@GOT(%edx), %edx
+ jmp *m4_empty_if_zero($2)(%edx)
+',`dnl non-PIC
+ jmp *GSYM_PREFIX`'__gmpn_cpuvec+$2
+')
+EPILOGUE()
+')
+
+
+dnl FAT_ENTRY for each CPUVEC_FUNCS_LIST
+dnl
+
+define(`CPUVEC_offset',0)
+foreach(i,
+`FAT_ENTRY(MPN(i),CPUVEC_offset)
+define(`CPUVEC_offset',eval(CPUVEC_offset + 4))',
+CPUVEC_FUNCS_LIST)
+
+ifdef(`PIC',`
+ ALIGN(8)
+L(movl_eip_edx):
+ movl (%esp), %edx
+ ret_internal
+')
+
+
+dnl Usage: FAT_INIT(name, offset)
+dnl
+dnl Emit a fat binary initializer function of the given name. These
+dnl functions are the initial values for the pointers in __gmpn_cpuvec.
+dnl
+dnl The code simply calls __gmpn_cpuvec_init, and then jumps back through
+dnl the __gmpn_cpuvec pointer, at the given "offset" (in bytes).
+dnl __gmpn_cpuvec_init will have stored the address of the selected
+dnl implementation there.
+dnl
+dnl Only one of these routines will be executed, and only once, since after
+dnl that all the __gmpn_cpuvec pointers go to real routines. So there's no
+dnl need for anything special here, just something small and simple. To
+dnl keep code size down, "fat_init" is a shared bit of code, arrived at
+dnl with the offset in %al. %al is used since the movb instruction is 2
+dnl bytes where %eax would be 4.
+dnl
+dnl Note having `PROLOGUE in FAT_INIT obscures that PROLOGUE from the
+dnl HAVE_NATIVE grepping in configure, preventing that code trying to eval
+dnl something with $1 in it.
+
+define(FAT_INIT,
+m4_assert_numargs(2)
+`PROLOGUE($1)
+ movb $`'$2, %al
+ jmp L(fat_init)
+EPILOGUE()
+')
+
+L(fat_init):
+ C al __gmpn_cpuvec byte offset
+
+ movzbl %al, %eax
+ pushl %eax
+
+ifdef(`PIC',`
+ pushl %ebx
+ call L(movl_eip_ebx)
+L(init_here):
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(init_here)], %ebx
+ call GSYM_PREFIX`'__gmpn_cpuvec_init@PLT
+ movl GSYM_PREFIX`'__gmpn_cpuvec@GOT(%ebx), %edx
+ popl %ebx
+ popl %eax
+ jmp *(%edx,%eax)
+
+L(movl_eip_ebx):
+ movl (%esp), %ebx
+ ret_internal
+
+',`dnl non-PIC
+ call GSYM_PREFIX`'__gmpn_cpuvec_init
+ popl %eax
+ jmp *GSYM_PREFIX`'__gmpn_cpuvec(%eax)
+')
+
+dnl FAT_INIT for each CPUVEC_FUNCS_LIST
+dnl
+
+define(`CPUVEC_offset',0)
+foreach(i,
+`FAT_INIT(MPN(i`'_init),CPUVEC_offset)
+define(`CPUVEC_offset',eval(CPUVEC_offset + 4))',
+CPUVEC_FUNCS_LIST)
+
+
+
+C long __gmpn_cpuid (char dst[12], int id);
+C
+C This is called only once, so just something simple and compact is fine.
+
+defframe(PARAM_ID, 8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+PROLOGUE(__gmpn_cpuid)
+ pushl %esi FRAME_pushl()
+ pushl %ebx FRAME_pushl()
+ movl PARAM_ID, %eax
+ cpuid
+ movl PARAM_DST, %esi
+ movl %ebx, (%esi)
+ movl %edx, 4(%esi)
+ movl %ecx, 8(%esi)
+ popl %ebx
+ popl %esi
+ ret
+EPILOGUE()
+
+
+C int __gmpn_cpuid_available (void);
+C
+C Return non-zero if the cpuid instruction is available, which means late
+C model 80486 and higher. 80386 and early 80486 don't have cpuid.
+C
+C The test follows Intel AP-485 application note, namely that if bit 21 is
+C modifiable then cpuid is supported. This test is reentrant and thread
+C safe, since of course any interrupt or context switch will preserve the
+C flags while we're tinkering with them.
+C
+C This is called only once, so just something simple and compact is fine.
+
+PROLOGUE(__gmpn_cpuid_available)
+ pushf
+ popl %ecx C old flags
+
+ movl %ecx, %edx
+ xorl $0x200000, %edx
+ pushl %edx
+ popf
+ pushf
+ popl %edx C tweaked flags
+
+ movl $1, %eax
+ cmpl %ecx, %edx
+ jne L(available)
+ xorl %eax, %eax C not changed, so cpuid not available
+
+L(available):
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/fat/gcd_1.c b/gmp/mpn/x86/fat/gcd_1.c
new file mode 100644
index 0000000000..f809bd8092
--- /dev/null
+++ b/gmp/mpn/x86/fat/gcd_1.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_gcd_1.
+
+Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/gcd_1.c"
diff --git a/gmp/mpn/x86/fat/gmp-mparam.h b/gmp/mpn/x86/fat/gmp-mparam.h
new file mode 100644
index 0000000000..3641a6bafa
--- /dev/null
+++ b/gmp/mpn/x86/fat/gmp-mparam.h
@@ -0,0 +1,71 @@
+/* Fat binary x86 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2003, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* mpn_divexact_1 is faster than mpn_divrem_1 at all sizes. The only time
+ this might not be true currently is for actual 80386 and 80486 chips,
+ where mpn/x86/dive_1.asm might be slower than mpn/x86/divrem_1.asm, but
+ that's not worth worrying about. */
+#define DIVEXACT_1_THRESHOLD 0
+
+/* Only some of the x86s have an mpn_preinv_divrem_1, but we set
+ USE_PREINV_DIVREM_1 so that all callers use it, and then let the
+ __gmpn_cpuvec pointer go to plain mpn_divrem_1 if there's not an actual
+ preinv. */
+#define USE_PREINV_DIVREM_1 1
+
+#define BMOD_1_TO_MOD_1_THRESHOLD 20
+
+/* mpn_sqr_basecase is faster than mpn_mul_basecase at all sizes, no need
+ for mpn_sqr to call the latter. */
+#define SQR_BASECASE_THRESHOLD 0
+
+/* Sensible fallbacks for these, when not taken from a cpu-specific
+ gmp-mparam.h. */
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 130
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 200
+
+/* These are values more or less in the middle of what the typical x86 chips
+ come out as. For a fat binary it's necessary to have values for these,
+ since the defaults for MUL_FFT_TABLE and SQR_FFT_TABLE otherwise come out
+ as non-constant array initializers. FIXME: Perhaps these should be done
+ in the cpuvec structure like other thresholds. */
+#define MUL_FFT_TABLE { 464, 928, 1920, 3584, 10240, 40960, 0 }
+#define MUL_FFT_MODF_THRESHOLD 400
+#define MUL_FFT_THRESHOLD 2000
+
+#define SQR_FFT_TABLE { 528, 1184, 1920, 4608, 14336, 40960, 0 }
+#define SQR_FFT_MODF_THRESHOLD 500
+#define SQR_FFT_THRESHOLD 3000
diff --git a/gmp/mpn/x86/fat/lshiftc.c b/gmp/mpn/x86/fat/lshiftc.c
new file mode 100644
index 0000000000..9ecf48978f
--- /dev/null
+++ b/gmp/mpn/x86/fat/lshiftc.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_lshiftc.
+
+Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/lshiftc.c"
diff --git a/gmp/mpn/x86/fat/mod_1.c b/gmp/mpn/x86/fat/mod_1.c
new file mode 100644
index 0000000000..4f149cc353
--- /dev/null
+++ b/gmp/mpn/x86/fat/mod_1.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_mod_1.
+
+Copyright 2003, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/mod_1.c"
diff --git a/gmp/mpn/x86/fat/mod_1_1.c b/gmp/mpn/x86/fat/mod_1_1.c
new file mode 100644
index 0000000000..92eaa7a87f
--- /dev/null
+++ b/gmp/mpn/x86/fat/mod_1_1.c
@@ -0,0 +1,36 @@
+/* Fat binary fallback mpn_mod_1_1p.
+
+Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/*
+PROLOGUE(mpn_mod_1_1p_cps)
+*/
+
+#define OPERATION_mod_1_1_cps 1
+#include "mpn/generic/mod_1_1.c"
diff --git a/gmp/mpn/x86/fat/mod_1_2.c b/gmp/mpn/x86/fat/mod_1_2.c
new file mode 100644
index 0000000000..9095a61c93
--- /dev/null
+++ b/gmp/mpn/x86/fat/mod_1_2.c
@@ -0,0 +1,36 @@
+/* Fat binary fallback mpn_mod_1s_2p.
+
+Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/*
+PROLOGUE(mpn_mod_1s_2p_cps)
+*/
+
+#define OPERATION_mod_1_2_cps 1
+#include "mpn/generic/mod_1_2.c"
diff --git a/gmp/mpn/x86/fat/mod_1_4.c b/gmp/mpn/x86/fat/mod_1_4.c
new file mode 100644
index 0000000000..51c0def443
--- /dev/null
+++ b/gmp/mpn/x86/fat/mod_1_4.c
@@ -0,0 +1,36 @@
+/* Fat binary fallback mpn_mod_1s_4p.
+
+Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/*
+PROLOGUE(mpn_mod_1s_4p_cps)
+*/
+
+#define OPERATION_mod_1_4_cps 1
+#include "mpn/generic/mod_1_4.c"
diff --git a/gmp/mpn/x86/fat/mode1o.c b/gmp/mpn/x86/fat/mode1o.c
new file mode 100644
index 0000000000..870ddb899b
--- /dev/null
+++ b/gmp/mpn/x86/fat/mode1o.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_modexact_1c_odd.
+
+Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/mode1o.c"
diff --git a/gmp/mpn/x86/fat/mullo_basecase.c b/gmp/mpn/x86/fat/mullo_basecase.c
new file mode 100644
index 0000000000..7f86be64c5
--- /dev/null
+++ b/gmp/mpn/x86/fat/mullo_basecase.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_mullo_basecase.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/mullo_basecase.c"
diff --git a/gmp/mpn/x86/fat/redc_1.c b/gmp/mpn/x86/fat/redc_1.c
new file mode 100644
index 0000000000..0025403353
--- /dev/null
+++ b/gmp/mpn/x86/fat/redc_1.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_redc_1.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/redc_1.c"
diff --git a/gmp/mpn/x86/fat/redc_2.c b/gmp/mpn/x86/fat/redc_2.c
new file mode 100644
index 0000000000..1932d58323
--- /dev/null
+++ b/gmp/mpn/x86/fat/redc_2.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_redc_2.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/redc_2.c"
diff --git a/gmp/mpn/x86/geode/gmp-mparam.h b/gmp/mpn/x86/geode/gmp-mparam.h
new file mode 100644
index 0000000000..cc9c9f1789
--- /dev/null
+++ b/gmp/mpn/x86/geode/gmp-mparam.h
@@ -0,0 +1,141 @@
+/* Generic x86 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2002, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* Generated by tuneup.c, 2011-01-30, gcc 3.4 */
+
+#define MOD_1_NORM_THRESHOLD 6
+#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 17
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 9
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 14
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+#define USE_PREINV_DIVREM_1 0
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 42
+
+#define MUL_TOOM22_THRESHOLD 18
+#define MUL_TOOM33_THRESHOLD 66
+#define MUL_TOOM44_THRESHOLD 105
+#define MUL_TOOM6H_THRESHOLD 141
+#define MUL_TOOM8H_THRESHOLD 212
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 62
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 69
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 65
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 67
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 33
+#define SQR_TOOM3_THRESHOLD 60
+#define SQR_TOOM4_THRESHOLD 136
+#define SQR_TOOM6_THRESHOLD 196
+#define SQR_TOOM8_THRESHOLD 292
+
+#define MULMOD_BNM1_THRESHOLD 14
+#define SQRMOD_BNM1_THRESHOLD 16
+
+#define MUL_FFT_MODF_THRESHOLD 468 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 468, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
+ { 15, 7}, { 33, 8}, { 19, 7}, { 39, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 8}, { 47,10}, { 15, 9}, \
+ { 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
+ { 47, 8}, { 95, 9}, { 55,10}, { 31, 9}, \
+ { 63, 8}, { 127, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 159,10}, { 95, 9}, { 191,11}, \
+ { 63,10}, { 127, 9}, { 255,10}, { 143, 9}, \
+ { 287,10}, { 159,11}, { 95,10}, { 191, 9}, \
+ { 383,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 61
+#define MUL_FFT_THRESHOLD 5504
+
+#define SQR_FFT_MODF_THRESHOLD 396 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 396, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 21, 7}, { 11, 6}, { 24, 7}, { 13, 6}, \
+ { 27, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
+ { 11, 7}, { 27, 8}, { 15, 7}, { 33, 8}, \
+ { 19, 7}, { 39, 8}, { 23, 7}, { 47, 8}, \
+ { 27, 9}, { 15, 8}, { 39, 9}, { 23, 8}, \
+ { 51,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 9}, { 135,10}, { 79, 9}, { 159, 8}, \
+ { 319,10}, { 95, 9}, { 191,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511,10}, { 143, 9}, \
+ { 287, 8}, { 575,10}, { 159,11}, { 95,10}, \
+ { 191,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 61
+#define SQR_FFT_THRESHOLD 3712
+
+#define MULLO_BASECASE_THRESHOLD 3
+#define MULLO_DC_THRESHOLD 37
+#define MULLO_MUL_N_THRESHOLD 10950
+
+#define DC_DIV_QR_THRESHOLD 59
+#define DC_DIVAPPR_Q_THRESHOLD 189
+#define DC_BDIV_QR_THRESHOLD 55
+#define DC_BDIV_Q_THRESHOLD 136
+
+#define INV_MULMOD_BNM1_THRESHOLD 50
+#define INV_NEWTON_THRESHOLD 183
+#define INV_APPR_THRESHOLD 181
+
+#define BINV_NEWTON_THRESHOLD 204
+#define REDC_1_TO_REDC_N_THRESHOLD 54
+
+#define MU_DIV_QR_THRESHOLD 1142
+#define MU_DIVAPPR_Q_THRESHOLD 1142
+#define MUPI_DIV_QR_THRESHOLD 81
+#define MU_BDIV_QR_THRESHOLD 889
+#define MU_BDIV_Q_THRESHOLD 998
+
+#define MATRIX22_STRASSEN_THRESHOLD 13
+#define HGCD_THRESHOLD 133
+#define GCD_DC_THRESHOLD 451
+#define GCDEXT_DC_THRESHOLD 318
+#define JACOBI_BASE_METHOD 1
+
+#define GET_STR_DC_THRESHOLD 15
+#define GET_STR_PRECOMPUTE_THRESHOLD 30
+#define SET_STR_DC_THRESHOLD 547
+#define SET_STR_PRECOMPUTE_THRESHOLD 1049
diff --git a/gmp/mpn/x86/gmp-mparam.h b/gmp/mpn/x86/gmp-mparam.h
new file mode 100644
index 0000000000..2cb1984889
--- /dev/null
+++ b/gmp/mpn/x86/gmp-mparam.h
@@ -0,0 +1,38 @@
+/* Generic x86 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* Generic x86 mpn_divexact_1 is faster than generic x86 mpn_divrem_1 on all
+ of p5, p6, k6 and k7, so use it always. It's probably slower on 386 and
+ 486, but that's too bad. */
+#define DIVEXACT_1_THRESHOLD 0
diff --git a/gmp/mpn/x86/i486/gmp-mparam.h b/gmp/mpn/x86/i486/gmp-mparam.h
new file mode 100644
index 0000000000..aa7dbad45b
--- /dev/null
+++ b/gmp/mpn/x86/i486/gmp-mparam.h
@@ -0,0 +1,69 @@
+/* 80486 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* 100MHz DX4 */
+
+/* Generated by tuneup.c, 2003-02-13, gcc 2.95 */
+
+#define MUL_TOOM22_THRESHOLD 18
+#define MUL_TOOM33_THRESHOLD 228
+
+#define SQR_BASECASE_THRESHOLD 13
+#define SQR_TOOM2_THRESHOLD 49
+#define SQR_TOOM3_THRESHOLD 238
+
+#define DIV_SB_PREINV_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_DC_THRESHOLD 72
+#define POWM_THRESHOLD 38
+
+#define GCD_ACCEL_THRESHOLD 3
+#define JACOBI_BASE_METHOD 2
+
+#define USE_PREINV_DIVREM_1 0
+#define USE_PREINV_MOD_1 0
+#define DIVREM_2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define MODEXACT_1_ODD_THRESHOLD 17
+
+#define GET_STR_DC_THRESHOLD 32
+#define GET_STR_PRECOMPUTE_THRESHOLD 82
+#define SET_STR_THRESHOLD 3524
+
+#define MUL_FFT_TABLE { 464, 928, 1920, 4608, 10240, 40960, 0 }
+#define MUL_FFT_MODF_THRESHOLD 392
+#define MUL_FFT_THRESHOLD 2816
+
+#define SQR_FFT_TABLE { 432, 928, 1920, 4608, 14336, 40960, 0 }
+#define SQR_FFT_MODF_THRESHOLD 392
+#define SQR_FFT_THRESHOLD 2816
diff --git a/gmp/mpn/x86/k10/gmp-mparam.h b/gmp/mpn/x86/k10/gmp-mparam.h
new file mode 100644
index 0000000000..2a1ae5a6bb
--- /dev/null
+++ b/gmp/mpn/x86/k10/gmp-mparam.h
@@ -0,0 +1,211 @@
+/* x86/k10 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 2400 MHz K10 Barcelona */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-13, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 12
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 9
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 12
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 15
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 32
+
+#define MUL_TOOM22_THRESHOLD 24
+#define MUL_TOOM33_THRESHOLD 81
+#define MUL_TOOM44_THRESHOLD 130
+#define MUL_TOOM6H_THRESHOLD 189
+#define MUL_TOOM8H_THRESHOLD 430
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 81
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 91
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 82
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 90
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 112
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 38
+#define SQR_TOOM3_THRESHOLD 77
+#define SQR_TOOM4_THRESHOLD 184
+#define SQR_TOOM6_THRESHOLD 262
+#define SQR_TOOM8_THRESHOLD 369
+
+#define MULMID_TOOM42_THRESHOLD 56
+
+#define MULMOD_BNM1_THRESHOLD 17
+#define SQRMOD_BNM1_THRESHOLD 18
+
+#define MUL_FFT_MODF_THRESHOLD 765 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 765, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
+ { 39, 7}, { 23, 6}, { 47, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
+ { 51, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95,10}, { 31, 9}, \
+ { 63, 8}, { 127, 9}, { 79,10}, { 47, 9}, \
+ { 103,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 159,10}, { 95, 9}, { 199,10}, \
+ { 111,11}, { 63,10}, { 127, 9}, { 263,10}, \
+ { 175,11}, { 95,10}, { 207,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 543, 8}, { 1087, 9}, \
+ { 575,11}, { 159,10}, { 319, 9}, { 671, 8}, \
+ { 1343, 9}, { 735,11}, { 191, 9}, { 799, 8}, \
+ { 1599,10}, { 415, 9}, { 863,11}, { 223,12}, \
+ { 127,11}, { 255,10}, { 543, 9}, { 1087,10}, \
+ { 607, 9}, { 1215, 8}, { 2431,11}, { 319,10}, \
+ { 671, 9}, { 1343,10}, { 735,12}, { 191,11}, \
+ { 383,10}, { 799, 9}, { 1599,11}, { 415,10}, \
+ { 863, 9}, { 1727,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,11}, { 607,10}, { 1215, 9}, \
+ { 2431,12}, { 319,11}, { 671,10}, { 1343,11}, \
+ { 735,10}, { 1471, 9}, { 2943, 8}, { 5887,12}, \
+ { 383,11}, { 799,10}, { 1599,11}, { 863,10}, \
+ { 1727,12}, { 447,11}, { 959,10}, { 1919,11}, \
+ { 991,10}, { 1983,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1215,10}, { 2431,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1471,10}, \
+ { 2943, 9}, { 5887,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1727,10}, { 3455,12}, \
+ { 959,11}, { 1983,14}, { 255,13}, { 511,12}, \
+ { 1087,11}, { 2239,12}, { 1215,11}, { 2431,13}, \
+ { 639,12}, { 1471,11}, { 2943,10}, { 5887,13}, \
+ { 767,12}, { 1727,11}, { 3455,13}, { 895,12}, \
+ { 1983,14}, { 511,13}, { 1023,12}, { 2239,13}, \
+ { 1151,12}, { 2495,13}, { 1407,12}, { 2943,11}, \
+ { 5887,14}, { 767,13}, { 1663,12}, { 3455,13}, \
+ { 1919,12}, { 3839,15}, { 511,14}, { 1023,13}, \
+ { 2175,12}, { 4351,13}, { 2431,14}, { 1279,13}, \
+ { 2943,12}, { 5887,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 172
+#define MUL_FFT_THRESHOLD 6784
+
+#define SQR_FFT_MODF_THRESHOLD 555 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 555, 5}, { 21, 6}, { 11, 5}, { 25, 6}, \
+ { 13, 5}, { 27, 6}, { 27, 7}, { 15, 6}, \
+ { 32, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
+ { 39, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 39, 8}, { 23, 7}, { 47, 8}, \
+ { 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
+ { 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
+ { 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
+ { 47,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 127,10}, \
+ { 79, 9}, { 167,10}, { 95, 9}, { 191,10}, \
+ { 111,11}, { 63,10}, { 143, 9}, { 287, 8}, \
+ { 575,10}, { 159,11}, { 95,10}, { 191,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 543, 8}, \
+ { 1087,10}, { 287, 9}, { 607,11}, { 159,10}, \
+ { 319, 9}, { 671, 8}, { 1343,10}, { 351, 9}, \
+ { 735, 8}, { 1471,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 399, 9}, { 799, 8}, { 1599,10}, \
+ { 415, 9}, { 863,11}, { 223,10}, { 479,12}, \
+ { 127,11}, { 255,10}, { 543, 9}, { 1087,11}, \
+ { 287,10}, { 607, 9}, { 1215, 8}, { 2431,11}, \
+ { 319,10}, { 671, 9}, { 1343,11}, { 351,10}, \
+ { 735, 9}, { 1471,12}, { 191,11}, { 383,10}, \
+ { 799, 9}, { 1599,11}, { 415,10}, { 863, 9}, \
+ { 1727,11}, { 479,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087,11}, \
+ { 607,10}, { 1215, 9}, { 2431,12}, { 319,11}, \
+ { 671,10}, { 1343,11}, { 735,10}, { 1471, 9}, \
+ { 2943,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 863,10}, { 1727,12}, { 447,11}, { 959,10}, \
+ { 1919,11}, { 991,10}, { 1983,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1215,10}, { 2431,12}, \
+ { 639,11}, { 1343,12}, { 703,11}, { 1471,10}, \
+ { 2943,13}, { 383,12}, { 767,11}, { 1599,12}, \
+ { 831,11}, { 1727,10}, { 3455,12}, { 959,11}, \
+ { 1983,13}, { 511,12}, { 1215,11}, { 2431,13}, \
+ { 639,12}, { 1471,11}, { 2943,13}, { 767,12}, \
+ { 1727,11}, { 3455,13}, { 895,12}, { 1983,14}, \
+ { 511,13}, { 1023,12}, { 2111,13}, { 1151,12}, \
+ { 2431,13}, { 1407,12}, { 2943,14}, { 767,13}, \
+ { 1663,12}, { 3455,13}, { 1919,12}, { 3839,15}, \
+ { 511,14}, { 1023,13}, { 2431,14}, { 1279,13}, \
+ { 2943,12}, { 5887,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 172
+#define SQR_FFT_THRESHOLD 5504
+
+#define MULLO_BASECASE_THRESHOLD 7
+#define MULLO_DC_THRESHOLD 40
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 59
+#define DC_DIVAPPR_Q_THRESHOLD 270
+#define DC_BDIV_QR_THRESHOLD 55
+#define DC_BDIV_Q_THRESHOLD 206
+
+#define INV_MULMOD_BNM1_THRESHOLD 62
+#define INV_NEWTON_THRESHOLD 254
+#define INV_APPR_THRESHOLD 252
+
+#define BINV_NEWTON_THRESHOLD 274
+#define REDC_1_TO_REDC_N_THRESHOLD 74
+
+#define MU_DIV_QR_THRESHOLD 1589
+#define MU_DIVAPPR_Q_THRESHOLD 1589
+#define MUPI_DIV_QR_THRESHOLD 106
+#define MU_BDIV_QR_THRESHOLD 1470
+#define MU_BDIV_Q_THRESHOLD 1558
+
+#define POWM_SEC_TABLE 1,16,114,428,1240
+
+#define MATRIX22_STRASSEN_THRESHOLD 19
+#define HGCD_THRESHOLD 136
+#define HGCD_APPR_THRESHOLD 175
+#define HGCD_REDUCE_THRESHOLD 3389
+#define GCD_DC_THRESHOLD 595
+#define GCDEXT_DC_THRESHOLD 424
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 15
+#define GET_STR_PRECOMPUTE_THRESHOLD 28
+#define SET_STR_DC_THRESHOLD 100
+#define SET_STR_PRECOMPUTE_THRESHOLD 1360
+
+#define FAC_DSC_THRESHOLD 224
+#define FAC_ODD_THRESHOLD 29
diff --git a/gmp/mpn/x86/k6/README b/gmp/mpn/x86/k6/README
new file mode 100644
index 0000000000..1d65af3851
--- /dev/null
+++ b/gmp/mpn/x86/k6/README
@@ -0,0 +1,251 @@
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+ AMD K6 MPN SUBROUTINES
+
+
+
+This directory contains code optimized for AMD K6 CPUs, meaning K6, K6-2 and
+K6-3.
+
+The mmx subdirectory has MMX code suiting plain K6, the k62mmx subdirectory
+has MMX code suiting K6-2 and K6-3. All chips in the K6 family have MMX,
+the separate directories are just so that ./configure can omit them if the
+assembler doesn't support MMX.
+
+
+
+
+STATUS
+
+Times for the loops, with all code and data in L1 cache, are as follows.
+
+ cycles/limb
+
+ mpn_add_n/sub_n 3.25 normal, 2.75 in-place
+
+ mpn_mul_1 6.25
+ mpn_add/submul_1 7.65-8.4 (varying with data values)
+
+ mpn_mul_basecase 9.25 cycles/crossproduct (approx)
+ mpn_sqr_basecase 4.7 cycles/crossproduct (approx)
+ or 9.2 cycles/triangleproduct (approx)
+
+ mpn_l/rshift 3.0
+
+ mpn_divrem_1 20.0
+ mpn_mod_1 20.0
+ mpn_divexact_by3 11.0
+
+ mpn_copyi 1.0
+ mpn_copyd 1.0
+
+
+K6-2 and K6-3 have dual-issue MMX and get the following improvements.
+
+ mpn_l/rshift 1.75
+
+
+Prefetching of sources hasn't yet given any joy. With the 3DNow "prefetch"
+instruction, code seems to run slower, and with just "mov" loads it doesn't
+seem faster. Results so far are inconsistent. The K6 does a hardware
+prefetch of the second cache line in a sector, so the penalty for not
+prefetching in software is reduced.
+
+
+
+
+NOTES
+
+All K6 family chips have MMX, but only K6-2 and K6-3 have 3DNow.
+
+Plain K6 executes MMX instructions only in the X pipe, but K6-2 and K6-3 can
+execute them in both X and Y (and in both together).
+
+Branch misprediction penalty is 1 to 4 cycles (Optimization Manual
+chapter 6 table 12).
+
+Write-allocate L1 data cache means prefetching of destinations is unnecessary.
+Store queue is 7 entries of 64 bits each.
+
+Floating point multiplications can be done in parallel with integer
+multiplications, but there doesn't seem to be any way to make use of this.
+
+
+
+OPTIMIZATIONS
+
+Unrolled loops are used to reduce looping overhead. The unrolling is
+configurable up to 32 limbs/loop for most routines, up to 64 for some.
+
+Sometimes computed jumps into the unrolling are used to handle sizes not a
+multiple of the unrolling. An attractive feature of this is that times
+smoothly increase with operand size, but an indirect jump is about 6 cycles
+and the setups about another 6, so it depends on how much the unrolled code
+is faster than a simple loop as to whether a computed jump ought to be used.
+
+Position independent code is implemented using a call to get eip for
+computed jumps and a ret is always done, rather than an addl $4,%esp or a
+popl, so the CPU return address branch prediction stack stays synchronised
+with the actual stack in memory. Such a call however still costs 4 to 7
+cycles.
+
+Branch prediction, in absence of any history, will guess forward jumps are
+not taken and backward jumps are taken. Where possible it's arranged that
+the less likely or less important case is under a taken forward jump.
+
+
+
+MMX
+
+Putting emms or femms as late as possible in a routine seems to be fastest.
+Perhaps an emms or femms stalls until all outstanding MMX instructions have
+completed, so putting it later gives them a chance to complete on their own,
+in parallel with other operations (like register popping).
+
+The Optimization Manual chapter 5 recommends using a femms on K6-2 and K6-3
+at the start of a routine, in case it's been preceded by x87 floating point
+operations. This isn't done because in gmp programs it's expected that x87
+floating point won't be much used and that chances are an mpn routine won't
+have been preceded by any x87 code.
+
+
+
+CODING
+
+Instructions in general code are shown paired if they can decode and execute
+together, meaning two short decode instructions with the second not
+depending on the first, only the first using the shifter, no more than one
+load, and no more than one store.
+
+K6 does some out of order execution so the pairings aren't essential, they
+just show what slots might be available. When decoding is the limiting
+factor things can be scheduled that might not execute until later.
+
+
+
+NOTES
+
+Code alignment
+
+- if an opcode/modrm or 0Fh/opcode/modrm crosses a cache line boundary,
+ short decode is inhibited. The cross.pl script detects this.
+
+- loops and branch targets should be aligned to 16 bytes, or ensure at least
+ 2 instructions before a 32 byte boundary. This makes use of the 16 byte
+ cache in the BTB.
+
+Addressing modes
+
+- (%esi) degrades decoding from short to vector. 0(%esi) doesn't have this
+ problem, and can be used as an equivalent, or easier is just to use a
+ different register, like %ebx.
+
+- K6 and pre-CXT core K6-2 have the following problem. (K6-2 CXT and K6-3
+ have it fixed, these being cpuid function 1 signatures 0x588 to 0x58F).
+
+ If more than 3 bytes are needed to determine instruction length then
+ decoding degrades from direct to long, or from long to vector. This
+ happens with forms like "0F opcode mod/rm" with mod/rm=00-xxx-100 since
+ with mod=00 the sib determines whether there's a displacement.
+
+ This affects all MMX and 3DNow instructions, and others with an 0F prefix,
+ like movzbl. The modes affected are anything with an index and no
+ displacement, or an index but no base, and this includes (%esp) which is
+ really (,%esp,1).
+
+ The cross.pl script detects problem cases. The workaround is to always
+ use a displacement, and to do this with Zdisp if it's zero so the
+ assembler doesn't discard it.
+
+ See Optimization Manual rev D page 67 and 3DNow Porting Guide rev B pages
+ 13-14 and 36-37.
+
+Calls
+
+- indirect jumps and calls are not branch predicted, they measure about 6
+ cycles.
+
+Various
+
+- adcl 2 cycles of decode, maybe 2 cycles executing in the X pipe
+- bsf 12-27 cycles
+- emms 5 cycles
+- femms 3 cycles
+- jecxz 2 cycles taken, 13 not taken (optimization manual says 7 not taken)
+- divl 20 cycles back-to-back
+- imull 2 decode, 3 execute
+- mull 2 decode, 3 execute (optimization manual decoding sample)
+- prefetch 2 cycles
+- rcll/rcrl implicit by one bit: 2 cycles
+ immediate or %cl count: 11 + 2 per bit for dword
+ 13 + 4 per bit for byte
+- setCC 2 cycles
+- xchgl %eax,reg 1.5 cycles, back-to-back (strange)
+ reg,reg 2 cycles, back-to-back
+
+
+
+
+REFERENCES
+
+"AMD-K6 Processor Code Optimization Application Note", AMD publication
+number 21924, revision D amendment 0, January 2000. This describes K6-2 and
+K6-3. Available on-line,
+
+http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21924.pdf
+
+"AMD-K6 MMX Enhanced Processor x86 Code Optimization Application Note", AMD
+publication number 21828, revision A amendment 0, August 1997. This is an
+older edition of the above document, describing plain K6. Available
+on-line,
+
+http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21828.pdf
+
+"3DNow Technology Manual", AMD publication number 21928G/0-March 2000.
+This describes the femms and prefetch instructions, but nothing else from
+3DNow has been used. Available on-line,
+
+http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21928.pdf
+
+"3DNow Instruction Porting Guide", AMD publication number 22621, revision B,
+August 1999. This has some notes on general K6 optimizations as well as
+3DNow. Available on-line,
+
+http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22621.pdf
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/x86/k6/aors_n.asm b/gmp/mpn/x86/k6/aors_n.asm
new file mode 100644
index 0000000000..168f9b4ae4
--- /dev/null
+++ b/gmp/mpn/x86/k6/aors_n.asm
@@ -0,0 +1,337 @@
+dnl AMD K6 mpn_add/sub_n -- mpn addition or subtraction.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: normal 3.25 cycles/limb, in-place 2.75 cycles/limb.
+
+
+ifdef(`OPERATION_add_n', `
+ define(M4_inst, adcl)
+ define(M4_function_n, mpn_add_n)
+ define(M4_function_nc, mpn_add_nc)
+ define(M4_description, add)
+',`ifdef(`OPERATION_sub_n', `
+ define(M4_inst, sbbl)
+ define(M4_function_n, mpn_sub_n)
+ define(M4_function_nc, mpn_sub_nc)
+ define(M4_description, subtract)
+',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
+')')')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+
+C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size);
+C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size, mp_limb_t carry);
+C
+C Calculate src1,size M4_description src2,size, and store the result in
+C dst,size. The return value is the carry bit from the top of the result
+C (1 or 0).
+C
+C The _nc version accepts 1 or 0 for an initial carry into the low limb of
+C the calculation. Note values other than 1 or 0 here will lead to garbage
+C results.
+C
+C Instruction decoding limits a normal dst=src1+src2 operation to 3 c/l, and
+C an in-place dst+=src to 2.5 c/l. The unrolled loops have 1 cycle/loop of
+C loop control, which with 4 limbs/loop means an extra 0.25 c/l.
+
+define(PARAM_CARRY, `FRAME+20(%esp)')
+define(PARAM_SIZE, `FRAME+16(%esp)')
+define(PARAM_SRC2, `FRAME+12(%esp)')
+define(PARAM_SRC1, `FRAME+8(%esp)')
+define(PARAM_DST, `FRAME+4(%esp)')
+deflit(`FRAME',0)
+
+dnl minimum 5 because the unrolled code can't handle less
+deflit(UNROLL_THRESHOLD, 5)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(M4_function_nc)
+ movl PARAM_CARRY, %eax
+ jmp L(start)
+EPILOGUE()
+
+
+PROLOGUE(M4_function_n)
+ xorl %eax, %eax
+L(start):
+ movl PARAM_SIZE, %ecx
+ pushl %ebx
+FRAME_pushl()
+
+ movl PARAM_SRC1, %ebx
+ pushl %edi
+FRAME_pushl()
+
+ movl PARAM_SRC2, %edx
+ cmpl $UNROLL_THRESHOLD, %ecx
+
+ movl PARAM_DST, %edi
+ jae L(unroll)
+
+
+ shrl %eax C initial carry flag
+
+ C offset 0x21 here, close enough to aligned
+L(simple):
+ C eax scratch
+ C ebx src1
+ C ecx counter
+ C edx src2
+ C esi
+ C edi dst
+ C ebp
+ C
+ C The store to (%edi) could be done with a stosl; it'd be smaller
+ C code, but there's no speed gain and a cld would have to be added
+ C (per mpn/x86/README).
+
+ movl (%ebx), %eax
+ leal 4(%ebx), %ebx
+
+ M4_inst (%edx), %eax
+
+ movl %eax, (%edi)
+ leal 4(%edi), %edi
+
+ leal 4(%edx), %edx
+ loop L(simple)
+
+
+ movl $0, %eax
+ popl %edi
+
+ setc %al
+
+ popl %ebx
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(unroll):
+ C eax carry
+ C ebx src1
+ C ecx counter
+ C edx src2
+ C esi
+ C edi dst
+ C ebp
+
+ cmpl %edi, %ebx
+ pushl %esi
+
+ je L(inplace)
+
+ifdef(`OPERATION_add_n',`
+ cmpl %edi, %edx
+
+ je L(inplace_reverse)
+')
+
+ movl %ecx, %esi
+
+ andl $-4, %ecx
+ andl $3, %esi
+
+ leal (%ebx,%ecx,4), %ebx
+ leal (%edx,%ecx,4), %edx
+ leal (%edi,%ecx,4), %edi
+
+ negl %ecx
+ shrl %eax
+
+ ALIGN(32)
+L(normal_top):
+ C eax counter, qwords, negative
+ C ebx src1
+ C ecx scratch
+ C edx src2
+ C esi
+ C edi dst
+ C ebp
+
+ movl (%ebx,%ecx,4), %eax
+ leal 5(%ecx), %ecx
+ M4_inst -20(%edx,%ecx,4), %eax
+ movl %eax, -20(%edi,%ecx,4)
+
+ movl 4-20(%ebx,%ecx,4), %eax
+ M4_inst 4-20(%edx,%ecx,4), %eax
+ movl %eax, 4-20(%edi,%ecx,4)
+
+ movl 8-20(%ebx,%ecx,4), %eax
+ M4_inst 8-20(%edx,%ecx,4), %eax
+ movl %eax, 8-20(%edi,%ecx,4)
+
+ movl 12-20(%ebx,%ecx,4), %eax
+ M4_inst 12-20(%edx,%ecx,4), %eax
+ movl %eax, 12-20(%edi,%ecx,4)
+
+ loop L(normal_top)
+
+
+ decl %esi
+ jz L(normal_finish_one)
+ js L(normal_done)
+
+ C two or three more limbs
+
+ movl (%ebx), %eax
+ M4_inst (%edx), %eax
+ movl %eax, (%edi)
+
+ movl 4(%ebx), %eax
+ M4_inst 4(%edx), %eax
+ decl %esi
+ movl %eax, 4(%edi)
+
+ jz L(normal_done)
+ movl $2, %ecx
+
+L(normal_finish_one):
+ movl (%ebx,%ecx,4), %eax
+ M4_inst (%edx,%ecx,4), %eax
+ movl %eax, (%edi,%ecx,4)
+
+L(normal_done):
+ popl %esi
+ popl %edi
+
+ movl $0, %eax
+ popl %ebx
+
+ setc %al
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+
+ifdef(`OPERATION_add_n',`
+L(inplace_reverse):
+ C dst==src2
+
+ movl %ebx, %edx
+')
+
+L(inplace):
+ C eax initial carry
+ C ebx
+ C ecx size
+ C edx src
+ C esi
+ C edi dst
+ C ebp
+
+ leal -1(%ecx), %esi
+ decl %ecx
+
+ andl $-4, %ecx
+ andl $3, %esi
+
+ movl (%edx), %ebx C src low limb
+ leal (%edx,%ecx,4), %edx
+
+ leal (%edi,%ecx,4), %edi
+ negl %ecx
+
+ shrl %eax
+
+
+ ALIGN(32)
+L(inplace_top):
+ C eax
+ C ebx next src limb
+ C ecx size
+ C edx src
+ C esi
+ C edi dst
+ C ebp
+
+ M4_inst %ebx, (%edi,%ecx,4)
+
+ movl 4(%edx,%ecx,4), %eax
+ leal 5(%ecx), %ecx
+
+ M4_inst %eax, 4-20(%edi,%ecx,4)
+
+ movl 8-20(%edx,%ecx,4), %eax
+ movl 12-20(%edx,%ecx,4), %ebx
+
+ M4_inst %eax, 8-20(%edi,%ecx,4)
+ M4_inst %ebx, 12-20(%edi,%ecx,4)
+
+ movl 16-20(%edx,%ecx,4), %ebx
+ loop L(inplace_top)
+
+
+ C now %esi is 0 to 3 representing respectively 1 to 4 limbs more
+
+ M4_inst %ebx, (%edi)
+
+ decl %esi
+ jz L(inplace_finish_one)
+ js L(inplace_done)
+
+ C two or three more limbs
+
+ movl 4(%edx), %eax
+ movl 8(%edx), %ebx
+ M4_inst %eax, 4(%edi)
+ M4_inst %ebx, 8(%edi)
+
+ decl %esi
+ movl $2, %ecx
+
+ jz L(normal_done)
+
+L(inplace_finish_one):
+ movl 4(%edx,%ecx,4), %eax
+ M4_inst %eax, 4(%edi,%ecx,4)
+
+L(inplace_done):
+ popl %esi
+ popl %edi
+
+ movl $0, %eax
+ popl %ebx
+
+ setc %al
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/aorsmul_1.asm b/gmp/mpn/x86/k6/aorsmul_1.asm
new file mode 100644
index 0000000000..eaa92ebb24
--- /dev/null
+++ b/gmp/mpn/x86/k6/aorsmul_1.asm
@@ -0,0 +1,391 @@
+dnl AMD K6 mpn_addmul_1/mpn_submul_1 -- add or subtract mpn multiple.
+
+dnl Copyright 1999-2003, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12 5.94
+C P6 model 9 (Banias) 5.51
+C P6 model 13 (Dothan) 5.57
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C AMD K6 7.65-8.5 (data dependent)
+C AMD K7
+C AMD K8
+
+
+dnl K6: large multipliers small multipliers
+dnl UNROLL_COUNT cycles/limb cycles/limb
+dnl 4 9.5 7.78
+dnl 8 9.0 7.78
+dnl 16 8.4 7.65
+dnl 32 8.4 8.2
+dnl
+dnl Maximum possible unrolling with the current code is 32.
+dnl
+dnl Unrolling to 16 limbs/loop makes the unrolled loop fit exactly in a 256
+dnl byte block, which might explain the good speed at that unrolling.
+
+deflit(UNROLL_COUNT, 16)
+
+
+ifdef(`OPERATION_addmul_1', `
+ define(M4_inst, addl)
+ define(M4_function_1, mpn_addmul_1)
+ define(M4_function_1c, mpn_addmul_1c)
+',`ifdef(`OPERATION_submul_1', `
+ define(M4_inst, subl)
+ define(M4_function_1, mpn_submul_1)
+ define(M4_function_1c, mpn_submul_1c)
+',`m4_error(`Need OPERATION_addmul_1 or OPERATION_submul_1
+')')')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_addmul_1c mpn_submul_1 mpn_submul_1c)
+
+
+C mp_limb_t mpn_addmul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult);
+C mp_limb_t mpn_addmul_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult, mp_limb_t carry);
+C mp_limb_t mpn_submul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult);
+C mp_limb_t mpn_submul_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult, mp_limb_t carry);
+C
+C The jadcl0()s in the unrolled loop makes the speed data dependent. Small
+C multipliers (most significant few bits clear) result in few carry bits and
+C speeds up to 7.65 cycles/limb are attained. Large multipliers (most
+C significant few bits set) make the carry bits 50/50 and lead to something
+C more like 8.4 c/l. With adcl's both of these would be 9.3 c/l.
+C
+C It's important that the gains for jadcl0 on small multipliers don't come
+C at the cost of slowing down other data. Tests on uniformly distributed
+C random data, designed to confound branch prediction, show about a 7%
+C speed-up using jadcl0 over adcl (8.93 versus 9.57 cycles/limb, with all
+C overheads included).
+C
+C In the simple loop, jadcl0() measures slower than adcl (11.9-14.7 versus
+C 11.0 cycles/limb), and hence isn't used.
+C
+C In the simple loop, note that running ecx from negative to zero and using
+C it as an index in the two movs wouldn't help. It would save one
+C instruction (2*addl+loop becoming incl+jnz), but there's nothing unpaired
+C that would be collapsed by this.
+C
+C Attempts at a simpler main loop, with less unrolling, haven't yielded much
+C success, generally running over 9 c/l.
+C
+C
+C jadcl0
+C ------
+C
+C jadcl0() being faster than adcl $0 seems to be an artifact of two things,
+C firstly the instruction decoding and secondly the fact that there's a
+C carry bit for the jadcl0 only on average about 1/4 of the time.
+C
+C The code in the unrolled loop decodes something like the following.
+C
+C decode cycles
+C mull %ebp 2
+C M4_inst %esi, disp(%edi) 1
+C adcl %eax, %ecx 2
+C movl %edx, %esi \ 1
+C jnc 1f /
+C incl %esi \ 1
+C 1: movl disp(%ebx), %eax /
+C ---
+C 7
+C
+C In a back-to-back style test this measures 7 with the jnc not taken, or 8
+C with it taken (both when correctly predicted). This is opposite to the
+C measurements showing small multipliers running faster than large ones.
+C Don't really know why.
+C
+C It's not clear how much branch misprediction might be costing. The K6
+C doco says it will be 1 to 4 cycles, but presumably it's near the low end
+C of that range to get the measured results.
+C
+C
+C In the code the two carries are more or less the preceding mul product and
+C the calculation is roughly
+C
+C x*y + u*b+v
+C
+C where b=2^32 is the size of a limb, x*y is the two carry limbs, and u and
+C v are the two limbs it's added to (being the low of the next mul, and a
+C limb from the destination).
+C
+C To get a carry requires x*y+u*b+v >= b^2, which is u*b+v >= b^2-x*y, and
+C there are b^2-(b^2-x*y) = x*y many such values, giving a probability of
+C x*y/b^2. If x, y, u and v are random and uniformly distributed between 0
+C and b-1, then the total probability can be summed over x and y,
+C
+C 1 b-1 b-1 x*y 1 b*(b-1) b*(b-1)
+C --- * sum sum --- = --- * ------- * ------- = 1/4
+C b^2 x=0 y=1 b^2 b^4 2 2
+C
+C Actually it's a very tiny bit less than 1/4 of course. If y is fixed,
+C then the probability is 1/2*y/b thus varying linearly between 0 and 1/2.
+
+
+ifdef(`PIC',`
+deflit(UNROLL_THRESHOLD, 9)
+',`
+deflit(UNROLL_THRESHOLD, 6)
+')
+
+defframe(PARAM_CARRY, 20)
+defframe(PARAM_MULTIPLIER,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(M4_function_1c)
+ pushl %esi
+deflit(`FRAME',4)
+ movl PARAM_CARRY, %esi
+ jmp L(start_nc)
+EPILOGUE()
+
+PROLOGUE(M4_function_1)
+ push %esi
+deflit(`FRAME',4)
+ xorl %esi, %esi C initial carry
+
+L(start_nc):
+ movl PARAM_SIZE, %ecx
+ pushl %ebx
+deflit(`FRAME',8)
+
+ movl PARAM_SRC, %ebx
+ pushl %edi
+deflit(`FRAME',12)
+
+ cmpl $UNROLL_THRESHOLD, %ecx
+ movl PARAM_DST, %edi
+
+ pushl %ebp
+deflit(`FRAME',16)
+ jae L(unroll)
+
+
+ C simple loop
+
+ movl PARAM_MULTIPLIER, %ebp
+
+L(simple):
+ C eax scratch
+ C ebx src
+ C ecx counter
+ C edx scratch
+ C esi carry
+ C edi dst
+ C ebp multiplier
+
+ movl (%ebx), %eax
+ addl $4, %ebx
+
+ mull %ebp
+
+ addl $4, %edi
+ addl %esi, %eax
+
+ adcl $0, %edx
+
+ M4_inst %eax, -4(%edi)
+
+ adcl $0, %edx
+
+ movl %edx, %esi
+ loop L(simple)
+
+
+ popl %ebp
+ popl %edi
+
+ popl %ebx
+ movl %esi, %eax
+
+ popl %esi
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+C The unrolled loop uses a "two carry limbs" scheme. At the top of the loop
+C the carries are ecx=lo, esi=hi, then they swap for each limb processed.
+C For the computed jump an odd size means they start one way around, an even
+C size the other.
+C
+C VAR_JUMP holds the computed jump temporarily because there's not enough
+C registers at the point of doing the mul for the initial two carry limbs.
+C
+C The add/adc for the initial carry in %esi is necessary only for the
+C mpn_addmul/submul_1c entry points. Duplicating the startup code to
+C eliminate this for the plain mpn_add/submul_1 doesn't seem like a good
+C idea.
+
+dnl overlapping with parameters already fetched
+define(VAR_COUNTER, `PARAM_SIZE')
+define(VAR_JUMP, `PARAM_DST')
+
+L(unroll):
+ C eax
+ C ebx src
+ C ecx size
+ C edx
+ C esi initial carry
+ C edi dst
+ C ebp
+
+ movl %ecx, %edx
+ decl %ecx
+
+ subl $2, %edx
+ negl %ecx
+
+ shrl $UNROLL_LOG2, %edx
+ andl $UNROLL_MASK, %ecx
+
+ movl %edx, VAR_COUNTER
+ movl %ecx, %edx
+
+ shll $4, %edx
+ negl %ecx
+
+ C 15 code bytes per limb
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ leal L(entry) (%edx,%ecx,1), %edx
+')
+ movl (%ebx), %eax C src low limb
+
+ movl PARAM_MULTIPLIER, %ebp
+ movl %edx, VAR_JUMP
+
+ mull %ebp
+
+ addl %esi, %eax C initial carry (from _1c)
+ jadcl0( %edx)
+
+
+ leal 4(%ebx,%ecx,4), %ebx
+ movl %edx, %esi C high carry
+
+ movl VAR_JUMP, %edx
+ leal (%edi,%ecx,4), %edi
+
+ testl $1, %ecx
+ movl %eax, %ecx C low carry
+
+ jz L(noswap)
+ movl %esi, %ecx C high,low carry other way around
+
+ movl %eax, %esi
+L(noswap):
+
+ jmp *%edx
+
+
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ leal (%edx,%ecx,1), %edx
+ addl $L(entry)-L(here), %edx
+ addl (%esp), %edx
+ ret_internal
+')
+
+
+C -----------------------------------------------------------
+ ALIGN(32)
+L(top):
+deflit(`FRAME',16)
+ C eax scratch
+ C ebx src
+ C ecx carry lo
+ C edx scratch
+ C esi carry hi
+ C edi dst
+ C ebp multiplier
+ C
+ C 15 code bytes per limb
+
+ leal UNROLL_BYTES(%edi), %edi
+
+L(entry):
+forloop(`i', 0, UNROLL_COUNT/2-1, `
+ deflit(`disp0', eval(2*i*4))
+ deflit(`disp1', eval(disp0 + 4))
+
+Zdisp( movl, disp0,(%ebx), %eax)
+ mull %ebp
+Zdisp( M4_inst,%ecx, disp0,(%edi))
+ adcl %eax, %esi
+ movl %edx, %ecx
+ jadcl0( %ecx)
+
+ movl disp1(%ebx), %eax
+ mull %ebp
+ M4_inst %esi, disp1(%edi)
+ adcl %eax, %ecx
+ movl %edx, %esi
+ jadcl0( %esi)
+')
+
+ decl VAR_COUNTER
+
+ leal UNROLL_BYTES(%ebx), %ebx
+ jns L(top)
+
+
+ popl %ebp
+ M4_inst %ecx, UNROLL_BYTES(%edi)
+
+ popl %edi
+ movl %esi, %eax
+
+ popl %ebx
+ jadcl0( %eax)
+
+ popl %esi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/cross.pl b/gmp/mpn/x86/k6/cross.pl
new file mode 100755
index 0000000000..fc921a56b7
--- /dev/null
+++ b/gmp/mpn/x86/k6/cross.pl
@@ -0,0 +1,182 @@
+#! /usr/bin/perl
+
+# Copyright 2000, 2001 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: cross.pl [filename.o]...
+#
+# Produce an annotated disassembly of the given object files, indicating
+# certain code alignment and addressing mode problems afflicting K6 chips.
+# "ZZ" is used on all annotations, so this can be searched for.
+#
+# With no arguments, all .o files corresponding to .asm files are processed.
+# This is good in the mpn object directory of a k6*-*-* build.
+#
+# Code alignments of 8 bytes or more are handled. When 32 is used, cache
+# line boundaries will fall in at offsets 0x20,0x40,etc and problems are
+# flagged at those locations. When 16 is used, the line boundaries can also
+# fall at offsets 0x10,0x30,0x50,etc, depending where the file is loaded, so
+# problems are identified there too. Likewise when 8 byte alignment is used
+# problems are flagged additionally at 0x08,0x18,0x28,etc.
+#
+# Usually 32 byte alignment is used for k6 routines, but less is certainly
+# possible if through good luck, or a little tweaking, cache line crossing
+# problems can be avoided at the extra locations.
+#
+# Bugs:
+#
+# Instructions without mod/rm bytes or which are already vector decoded are
+# unaffected by cache line boundary crossing, but not all of these have yet
+# been put in as exceptions. All that occur in practice in GMP are present
+# though.
+#
+# There's no messages for using the vector decoded addressing mode (%esi),
+# but that's easy to avoid when coding.
+#
+# Future:
+#
+# Warn about jump targets that are poorly aligned (less than 2 instructions
+# before a cache line boundary).
+
+use strict;
+
+sub disassemble {
+ my ($file) = @_;
+ my ($addr,$b1,$b2,$b3, $prefix,$opcode,$modrm);
+ my $align;
+
+ open (IN, "objdump -Srfh $file |")
+ || die "Cannot open pipe from objdump\n";
+ while (<IN>) {
+ print;
+
+ if (/^[ \t]*[0-9]+[ \t]+\.text[ \t]/ && /2\*\*([0-9]+)$/) {
+ $align = 1 << $1;
+ if ($align < 8) {
+ print "ZZ cross.pl cannot handle alignment < 2**3\n";
+ $align = 8
+ }
+ }
+
+ if (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)[ \t]+([0-9a-f]+)[ \t]+([0-9a-f]+)/) {
+ ($addr,$b1,$b2,$b3) = ($1,$2,$3,$4);
+
+ } elsif (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)[ \t]+([0-9a-f]+)/) {
+ ($addr,$b1,$b2,$b3) = ($1,$2,$3,'');
+
+ } elsif (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)/) {
+ ($addr,$b1,$b2,$b3) = ($1,$2,'','');
+
+ } else {
+ next;
+ }
+
+ if ($b1 =~ /0f/) {
+ $prefix = $b1;
+ $opcode = $b2;
+ $modrm = $b3;
+ } else {
+ $prefix = '';
+ $opcode = $b1;
+ $modrm = $b2;
+ }
+
+ # modrm of the form 00-xxx-100 with an 0F prefix is the problem case
+ # for K6 and pre-CXT K6-2
+ if ($prefix =~ /0f/
+ && $opcode !~ /^8/ # jcond disp32
+ && $modrm =~ /^[0-3][4c]/) {
+ print "ZZ ($file) >3 bytes to determine instruction length [K6]\n";
+ }
+
+ # with just an opcode, starting 1f mod 20h
+ if (($align==32 && $addr =~ /[13579bdf]f$/
+ || $align==16 && $addr =~ /f$/
+ || $align==8 && $addr =~ /[7f]$/)
+ && $prefix !~ /0f/
+ && $opcode !~ /1[012345]/ # adc
+ && $opcode !~ /1[89abcd]/ # sbb
+ && $opcode !~ /^4/ # inc/dec reg
+ && $opcode !~ /^5/ # push/pop reg
+ && $opcode !~ /68/ # push $imm32
+ && $opcode !~ /^7/ # jcond disp8
+ && $opcode !~ /a[89]/ # test+imm
+ && $opcode !~ /a[a-f]/ # stos/lods/scas
+ && $opcode !~ /b8/ # movl $imm32,%eax
+ && $opcode !~ /d[0123]/ # rcl
+ && $opcode !~ /e[0123]/ # loop/loopz/loopnz/jcxz
+ && $opcode !~ /e8/ # call disp32
+ && $opcode !~ /e[9b]/ # jmp disp32/disp8
+ && $opcode !~ /f[89abcd]/ # clc,stc,cli,sti,cld,std
+ && !($opcode =~ /f[67]/ # grp 1
+ && $modrm =~ /^[2367abef]/) # mul, imul, div, idiv
+ && $modrm !~ /^$/) {
+ print "ZZ ($file) opcode/modrm cross 32-byte boundary\n";
+ }
+
+ # with an 0F prefix, anything starting at 1f mod 20h
+ if (($align==32 && $addr =~ /[13579bdf][f]$/
+ || $align==16 && $addr =~ /f$/
+ || $align==8 && $addr =~ /[7f]$/)
+ && $prefix =~ /0f/
+ && $opcode !~ /af/ # imul
+ && $opcode !~ /a[45]/ # shldl
+ && $opcode !~ /a[cd]/ # shrdl
+ ) {
+ print "ZZ ($file) prefix/opcode cross 32-byte boundary\n";
+ }
+
+ # with an 0F prefix, anything with mod/rm starting at 1e mod 20h
+ if (($align==32 && $addr =~ /[13579bdf][e]$/
+ || $align==16 && $addr =~ /[e]$/
+ || $align==8 && $addr =~ /[6e]$/)
+ && $prefix =~ /0f/
+ && $opcode !~ /^8/ # jcond disp32
+ && $opcode !~ /af/ # imull reg,reg
+ && $opcode !~ /a[45]/ # shldl
+ && $opcode !~ /a[cd]/ # shrdl
+ && $modrm !~ /^$/) {
+ print "ZZ ($file) prefix/opcode/modrm cross 32-byte boundary\n";
+ }
+ }
+ close IN || die "Error from objdump (or objdump not available)\n";
+}
+
+
+my @files;
+if ($#ARGV >= 0) {
+ @files = @ARGV;
+} else {
+ @files = glob "*.asm";
+ map {s/.asm/.o/} @files;
+}
+
+foreach (@files) {
+ disassemble($_);
+}
diff --git a/gmp/mpn/x86/k6/divrem_1.asm b/gmp/mpn/x86/k6/divrem_1.asm
new file mode 100644
index 0000000000..b4cea4fa2a
--- /dev/null
+++ b/gmp/mpn/x86/k6/divrem_1.asm
@@ -0,0 +1,203 @@
+dnl AMD K6 mpn_divrem_1 -- mpn by limb division.
+
+dnl Copyright 1999-2003, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: 20 cycles/limb
+
+
+C mp_limb_t mpn_divrem_1 (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size, mp_limb_t divisor);
+C mp_limb_t mpn_divrem_1c (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size, mp_limb_t divisor,
+C mp_limb_t carry);
+C
+C The code here is basically the same as mpn/x86/divrem_1.asm, but uses loop
+C instead of decl+jnz, since it comes out 2 cycles/limb faster.
+C
+C A test is done to see if the high limb is less than the divisor, and if so
+C one less div is done. A div is 20 cycles, so assuming high<divisor about
+C half the time, then this test saves half that amount. The branch
+C misprediction penalty is less than that.
+C
+C Back-to-back div instructions run at 20 cycles, the same as the loop here,
+C so it seems there's nothing to gain by rearranging the loop. Pairing the
+C mov and loop instructions was found to gain nothing.
+C
+C Enhancements:
+C
+C The low-latency K6 multiply might be thought to suit a mul-by-inverse, but
+C that algorithm has been found to suffer from the relatively poor carry
+C handling on K6 and too many auxiliary instructions. The fractional part
+C however could be done at about 13 c/l, if it mattered enough.
+
+defframe(PARAM_CARRY, 24)
+defframe(PARAM_DIVISOR,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC, 12)
+defframe(PARAM_XSIZE, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+
+ ALIGN(32)
+PROLOGUE(mpn_divrem_1c)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ pushl %edi FRAME_pushl()
+
+ movl PARAM_SRC, %edi
+ pushl %esi FRAME_pushl()
+
+ movl PARAM_DIVISOR, %esi
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_DST, %ebx
+ pushl %ebp FRAME_pushl()
+
+ movl PARAM_XSIZE, %ebp
+ orl %ecx, %ecx C size
+
+ movl PARAM_CARRY, %edx
+ jz L(fraction) C if size==0
+
+ leal -4(%ebx,%ebp,4), %ebx C dst one limb below integer part
+ jmp L(integer_top)
+
+EPILOGUE()
+
+
+ ALIGN(16)
+PROLOGUE(mpn_divrem_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ pushl %edi FRAME_pushl()
+
+ movl PARAM_SRC, %edi
+ pushl %esi FRAME_pushl()
+
+ movl PARAM_DIVISOR, %esi
+ orl %ecx,%ecx C size
+
+ jz L(size_zero)
+ pushl %ebx FRAME_pushl()
+
+ movl -4(%edi,%ecx,4), %eax C src high limb
+ xorl %edx, %edx
+
+ movl PARAM_DST, %ebx
+ pushl %ebp FRAME_pushl()
+
+ movl PARAM_XSIZE, %ebp
+ cmpl %esi, %eax
+
+ leal -4(%ebx,%ebp,4), %ebx C dst one limb below integer part
+ jae L(integer_entry)
+
+
+ C high<divisor, so high of dst is zero, and avoid one div
+
+ movl %edx, (%ebx,%ecx,4)
+ decl %ecx
+
+ movl %eax, %edx
+ jz L(fraction)
+
+
+L(integer_top):
+ C eax scratch (quotient)
+ C ebx dst+4*xsize-4
+ C ecx counter
+ C edx scratch (remainder)
+ C esi divisor
+ C edi src
+ C ebp xsize
+
+ movl -4(%edi,%ecx,4), %eax
+L(integer_entry):
+
+ divl %esi
+
+ movl %eax, (%ebx,%ecx,4)
+ loop L(integer_top)
+
+
+L(fraction):
+ orl %ebp, %ecx
+ jz L(done)
+
+ movl PARAM_DST, %ebx
+
+
+L(fraction_top):
+ C eax scratch (quotient)
+ C ebx dst
+ C ecx counter
+ C edx scratch (remainder)
+ C esi divisor
+ C edi
+ C ebp
+
+ xorl %eax, %eax
+
+ divl %esi
+
+ movl %eax, -4(%ebx,%ecx,4)
+ loop L(fraction_top)
+
+
+L(done):
+ popl %ebp
+ movl %edx, %eax
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
+L(size_zero):
+deflit(`FRAME',8)
+ movl PARAM_XSIZE, %ecx
+ xorl %eax, %eax
+
+ movl PARAM_DST, %edi
+
+ cld C better safe than sorry, see mpn/x86/README
+
+ rep
+ stosl
+
+ popl %esi
+ popl %edi
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/gcd_1.asm b/gmp/mpn/x86/k6/gcd_1.asm
new file mode 100644
index 0000000000..0c233ff362
--- /dev/null
+++ b/gmp/mpn/x86/k6/gcd_1.asm
@@ -0,0 +1,362 @@
+dnl AMD K6 mpn_gcd_1 -- mpn by 1 gcd.
+
+dnl Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: 9.5 cycles/bit (approx) 1x1 gcd
+C 11.0 cycles/limb Nx1 reduction (modexact_1_odd)
+
+
+C mp_limb_t mpn_gcd_1 (mp_srcptr src, mp_size_t size, mp_limb_t y);
+C
+C This code is nothing very special, but offers a speedup over what gcc 2.95
+C can do with mpn/generic/gcd_1.c.
+C
+C Future:
+C
+C Using a lookup table to count trailing zeros seems a touch quicker, but
+C after a slightly longer startup. Might be worthwhile if an mpn_gcd_2 used
+C it too.
+
+
+dnl If size==1 and x (the larger operand) is more than DIV_THRESHOLD bits
+dnl bigger than y, then a division x%y is done to reduce it.
+dnl
+dnl A divl is 20 cycles and the loop runs at about 9.5 cycles/bitpair so
+dnl there should be an advantage in the divl at about 4 or 5 bits, which is
+dnl what's found.
+
+deflit(DIV_THRESHOLD, 5)
+
+
+defframe(PARAM_LIMB, 12)
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(mpn_gcd_1)
+deflit(`FRAME',0)
+
+ ASSERT(ne, `cmpl $0, PARAM_LIMB')
+ ASSERT(ae, `cmpl $1, PARAM_SIZE')
+
+
+ movl PARAM_SRC, %eax
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_LIMB, %edx
+ movl $-1, %ecx
+
+ movl (%eax), %ebx C src low limb
+
+ movl %ebx, %eax C src low limb
+ orl %edx, %ebx
+
+L(common_twos):
+ shrl %ebx
+ incl %ecx
+
+ jnc L(common_twos) C 1/4 chance on random data
+ shrl %cl, %edx C y
+
+ cmpl $1, PARAM_SIZE
+ ja L(size_two_or_more)
+
+
+ ASSERT(nz, `orl %eax, %eax') C should have src limb != 0
+
+ shrl %cl, %eax C x
+
+
+ C Swap if necessary to make x>=y. Measures a touch quicker as a
+ C jump than a branch free calculation.
+ C
+ C eax x
+ C ebx
+ C ecx common twos
+ C edx y
+
+ movl %eax, %ebx
+ cmpl %eax, %edx
+
+ jb L(noswap)
+ movl %edx, %eax
+
+ movl %ebx, %edx
+ movl %eax, %ebx
+L(noswap):
+
+
+ C See if it's worth reducing x with a divl.
+ C
+ C eax x
+ C ebx x
+ C ecx common twos
+ C edx y
+
+ shrl $DIV_THRESHOLD, %ebx
+
+ cmpl %ebx, %edx
+ ja L(nodiv)
+
+
+ C Reduce x to x%y.
+ C
+ C eax x
+ C ebx
+ C ecx common twos
+ C edx y
+
+ movl %edx, %ebx
+ xorl %edx, %edx
+
+ divl %ebx
+
+ orl %edx, %edx C y
+ nop C code alignment
+
+ movl %ebx, %eax C x
+ jz L(done_shll)
+L(nodiv):
+
+
+ C eax x
+ C ebx
+ C ecx common twos
+ C edx y
+ C esi
+ C edi
+ C ebp
+
+L(strip_y):
+ shrl %edx
+ jnc L(strip_y)
+
+ leal 1(%edx,%edx), %edx
+ movl %ecx, %ebx C common twos
+
+ leal 1(%eax), %ecx
+ jmp L(strip_x_and)
+
+
+C Calculating a %cl shift based on the low bit 0 or 1 avoids doing a branch
+C on a 50/50 chance of 0 or 1. The chance of the next bit also being 0 is
+C only 1/4.
+C
+C A second computed %cl shift was tried, but that measured a touch slower
+C than branching back.
+C
+C A branch-free abs(x-y) and min(x,y) calculation was tried, but that
+C measured about 1 cycle/bit slower.
+
+ C eax x
+ C ebx common twos
+ C ecx scratch
+ C edx y
+
+ ALIGN(4)
+L(swap):
+ addl %eax, %edx C x-y+y = x
+ negl %eax C -(x-y) = y-x
+
+L(strip_x):
+ shrl %eax C odd-odd = even, so always one to strip
+ ASSERT(nz)
+
+L(strip_x_leal):
+ leal 1(%eax), %ecx
+
+L(strip_x_and):
+ andl $1, %ecx C (x^1)&1
+
+ shrl %cl, %eax C shift if x even
+
+ testb $1, %al
+ jz L(strip_x)
+
+ ASSERT(nz,`testl $1, %eax') C x, y odd
+ ASSERT(nz,`testl $1, %edx')
+
+ subl %edx, %eax
+ jb L(swap)
+ ja L(strip_x)
+
+
+ movl %edx, %eax
+ movl %ebx, %ecx
+
+L(done_shll):
+ shll %cl, %eax
+ popl %ebx
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+C Two or more limbs.
+C
+C x={src,size} is reduced modulo y using either a plain mod_1 style
+C remainder, or a modexact_1 style exact division.
+
+deflit(MODEXACT_THRESHOLD, ifdef(`PIC', 4, 4))
+
+ ALIGN(8)
+L(size_two_or_more):
+ C eax
+ C ebx
+ C ecx common twos
+ C edx y, without common twos
+ C esi
+ C edi
+ C ebp
+
+deflit(FRAME_TWO_OR_MORE, FRAME)
+
+ pushl %edi defframe_pushl(SAVE_EDI)
+ movl PARAM_SRC, %ebx
+
+L(y_twos):
+ shrl %edx
+ jnc L(y_twos)
+
+ movl %ecx, %edi C common twos
+ movl PARAM_SIZE, %ecx
+
+ pushl %esi defframe_pushl(SAVE_ESI)
+ leal 1(%edx,%edx), %esi C y (odd)
+
+ movl -4(%ebx,%ecx,4), %eax C src high limb
+
+ cmpl %edx, %eax C carry if high<divisor
+
+ sbbl %edx, %edx C -1 if high<divisor
+
+ addl %edx, %ecx C skip one limb if high<divisor
+ andl %eax, %edx
+
+ cmpl $MODEXACT_THRESHOLD, %ecx
+ jae L(modexact)
+
+
+L(divide_top):
+ C eax scratch (quotient)
+ C ebx src
+ C ecx counter, size-1 to 1
+ C edx carry (remainder)
+ C esi divisor (odd)
+ C edi
+ C ebp
+
+ movl -4(%ebx,%ecx,4), %eax
+ divl %esi
+ loop L(divide_top)
+
+
+ movl %edx, %eax C x
+ movl %esi, %edx C y (odd)
+
+ movl %edi, %ebx C common twos
+ popl %esi
+
+ popl %edi
+ leal 1(%eax), %ecx
+
+ orl %eax, %eax
+ jnz L(strip_x_and)
+
+
+ movl %ebx, %ecx
+ movl %edx, %eax
+
+ shll %cl, %eax
+ popl %ebx
+
+ ret
+
+
+ ALIGN(8)
+L(modexact):
+ C eax
+ C ebx src ptr
+ C ecx size or size-1
+ C edx
+ C esi y odd
+ C edi common twos
+ C ebp
+
+ movl PARAM_SIZE, %eax
+ pushl %esi FRAME_pushl()
+
+ pushl %eax FRAME_pushl()
+
+ pushl %ebx FRAME_pushl()
+
+ifdef(`PIC',`
+ nop C code alignment
+ call L(movl_eip_ebx)
+L(here):
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ call GSYM_PREFIX`'mpn_modexact_1_odd@PLT
+',`
+ call GSYM_PREFIX`'mpn_modexact_1_odd
+')
+
+ movl %esi, %edx C y odd
+ movl SAVE_ESI, %esi
+
+ movl %edi, %ebx C common twos
+ movl SAVE_EDI, %edi
+
+ addl $eval(FRAME - FRAME_TWO_OR_MORE), %esp
+ orl %eax, %eax
+
+ leal 1(%eax), %ecx
+ jnz L(strip_x_and)
+
+
+ movl %ebx, %ecx
+ movl %edx, %eax
+
+ shll %cl, %eax
+ popl %ebx
+
+ ret
+
+
+ifdef(`PIC',`
+L(movl_eip_ebx):
+ movl (%esp), %ebx
+ ret_internal
+')
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/gmp-mparam.h b/gmp/mpn/x86/k6/gmp-mparam.h
new file mode 100644
index 0000000000..f03f1b2d91
--- /dev/null
+++ b/gmp/mpn/x86/k6/gmp-mparam.h
@@ -0,0 +1,166 @@
+/* AMD K6 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2004, 2009, 2010 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* 450MHz K6-2 */
+
+#define MOD_1_NORM_THRESHOLD 12
+#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 41
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 32
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 3
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 128
+#define USE_PREINV_DIVREM_1 0
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 69
+#define MUL_TOOM44_THRESHOLD 106
+#define MUL_TOOM6H_THRESHOLD 157
+#define MUL_TOOM8H_THRESHOLD 199
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 69
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 65
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 64
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 32
+#define SQR_TOOM3_THRESHOLD 97
+#define SQR_TOOM4_THRESHOLD 143
+#define SQR_TOOM6_THRESHOLD 222
+#define SQR_TOOM8_THRESHOLD 272
+
+#define MULMOD_BNM1_THRESHOLD 13
+#define SQRMOD_BNM1_THRESHOLD 17
+
+#define MUL_FFT_MODF_THRESHOLD 476 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 476, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 11, 5}, { 23, 6}, { 17, 7}, { 9, 6}, \
+ { 19, 7}, { 11, 6}, { 23, 7}, { 13, 6}, \
+ { 27, 7}, { 15, 6}, { 31, 7}, { 17, 6}, \
+ { 35, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 39, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
+ { 51,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 47,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 167,10}, { 95, 9}, { 191,10}, \
+ { 111,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 143, 9}, { 287,10}, { 159,11}, { 95,10}, \
+ { 191, 9}, { 383,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271, 9}, { 543,10}, \
+ { 287,11}, { 159,10}, { 351,11}, { 191,10}, \
+ { 415, 9}, { 831,11}, { 223,12}, { 127,11}, \
+ { 255,10}, { 543,11}, { 287,10}, { 575,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 415,10}, \
+ { 831,13}, { 127,12}, { 255,11}, { 543,10}, \
+ { 1087,11}, { 575,12}, { 319,11}, { 703,12}, \
+ { 383,11}, { 831,12}, { 447,11}, { 895,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1151,12}, { 703,13}, { 383,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1215,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 106
+#define MUL_FFT_THRESHOLD 7424
+
+#define SQR_FFT_MODF_THRESHOLD 432 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 432, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 24, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 21, 8}, { 11, 7}, { 29, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 39, 8}, \
+ { 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 7}, { 93, 8}, { 47, 7}, \
+ { 95, 8}, { 51,10}, { 15, 9}, { 31, 8}, \
+ { 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
+ { 95, 9}, { 55,10}, { 31, 9}, { 71, 8}, \
+ { 143, 9}, { 79,10}, { 47, 9}, { 95,11}, \
+ { 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
+ { 167,10}, { 95, 9}, { 191,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 143, 9}, { 287, 8}, \
+ { 575,10}, { 159, 9}, { 319,11}, { 95,10}, \
+ { 191,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,10}, { 287,11}, \
+ { 159,10}, { 319, 9}, { 639,10}, { 351, 9}, \
+ { 703,11}, { 191,10}, { 415,11}, { 223,12}, \
+ { 127,11}, { 255,10}, { 543,11}, { 287,10}, \
+ { 607,11}, { 319,10}, { 639,11}, { 351,10}, \
+ { 703,12}, { 191,11}, { 415,10}, { 831,13}, \
+ { 127,12}, { 255,11}, { 543,10}, { 1087,11}, \
+ { 607,12}, { 319,11}, { 703,12}, { 383,11}, \
+ { 831,12}, { 447,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1215,12}, { 703,13}, \
+ { 383,12}, { 895,14}, { 255,13}, { 511,12}, \
+ { 1215,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 112
+#define SQR_FFT_THRESHOLD 7040
+
+#define MULLO_BASECASE_THRESHOLD 3
+#define MULLO_DC_THRESHOLD 60
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 78
+#define DC_DIVAPPR_Q_THRESHOLD 252
+#define DC_BDIV_QR_THRESHOLD 84
+#define DC_BDIV_Q_THRESHOLD 171
+
+#define INV_MULMOD_BNM1_THRESHOLD 55
+#define INV_NEWTON_THRESHOLD 234
+#define INV_APPR_THRESHOLD 236
+
+#define BINV_NEWTON_THRESHOLD 268
+#define REDC_1_TO_REDC_N_THRESHOLD 67
+
+#define MU_DIV_QR_THRESHOLD 1308
+#define MU_DIVAPPR_Q_THRESHOLD 1142
+#define MUPI_DIV_QR_THRESHOLD 134
+#define MU_BDIV_QR_THRESHOLD 1164
+#define MU_BDIV_Q_THRESHOLD 1164
+
+#define MATRIX22_STRASSEN_THRESHOLD 15
+#define HGCD_THRESHOLD 182
+#define GCD_DC_THRESHOLD 591
+#define GCDEXT_DC_THRESHOLD 472
+#define JACOBI_BASE_METHOD 2
+
+#define GET_STR_DC_THRESHOLD 24
+#define GET_STR_PRECOMPUTE_THRESHOLD 40
+#define SET_STR_DC_THRESHOLD 834
+#define SET_STR_PRECOMPUTE_THRESHOLD 2042
diff --git a/gmp/mpn/x86/k6/k62mmx/copyd.asm b/gmp/mpn/x86/k6/k62mmx/copyd.asm
new file mode 100644
index 0000000000..f80a5a1cdb
--- /dev/null
+++ b/gmp/mpn/x86/k6/k62mmx/copyd.asm
@@ -0,0 +1,118 @@
+dnl AMD K6-2 mpn_copyd -- copy limb vector, decrementing.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6-2: 1.0 cycles/limb
+
+
+C void mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C The loop here is no faster than a rep movsl at 1.0 c/l, but it avoids a 30
+C cycle startup time, which amounts for instance to a 2x speedup at 15
+C limbs.
+C
+C If dst is 4mod8 the loop would be 1.17 c/l, but that's avoided by
+C processing one limb separately to make it aligned. This and a final odd
+C limb are handled in a branch-free fashion, ending up re-copying if the
+C special case isn't needed.
+C
+C Alternatives:
+C
+C There used to be a big unrolled version of this, running at 0.56 c/l if
+C the destination was aligned, but that seemed rather excessive for the
+C relative importance of copyd.
+C
+C If the destination alignment is ignored and just left to run at 1.17 c/l
+C some code size and a fixed few cycles can be saved. Considering how few
+C uses copyd finds perhaps that should be favoured. The current code has
+C the attraction of being no slower than a basic rep movsl though.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-using parameter space
+define(SAVE_EBX,`PARAM_SIZE')
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(mpn_copyd)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl %ebx, SAVE_EBX
+
+ movl PARAM_SRC, %eax
+ movl PARAM_DST, %edx
+
+ subl $1, %ecx C better code alignment than decl
+ jb L(zero)
+
+ jz L(one_more)
+ leal 4(%edx,%ecx,4), %ebx
+
+Zdisp( movd, 0,(%eax,%ecx,4), %mm0) C high limb
+Zdisp( movd, %mm0, 0,(%edx,%ecx,4)) C Zdisp for good code alignment
+
+ cmpl $1, %ecx
+ je L(one_more)
+
+ shrl $2, %ebx
+ andl $1, %ebx C 1 if dst[size-2] unaligned
+
+ subl %ebx, %ecx
+ nop C code alignment
+
+L(top):
+ C eax src
+ C ebx
+ C ecx counter
+ C edx dst
+
+ movq -4(%eax,%ecx,4), %mm0
+ subl $2, %ecx
+
+ movq %mm0, 4(%edx,%ecx,4)
+ ja L(top)
+
+
+L(one_more):
+ movd (%eax), %mm0
+ movd %mm0, (%edx)
+
+ movl SAVE_EBX, %ebx
+ emms_or_femms
+L(zero):
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/k62mmx/lshift.asm b/gmp/mpn/x86/k6/k62mmx/lshift.asm
new file mode 100644
index 0000000000..c86575feed
--- /dev/null
+++ b/gmp/mpn/x86/k6/k62mmx/lshift.asm
@@ -0,0 +1,294 @@
+dnl AMD K6-2 mpn_lshift -- mpn left shift.
+
+dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6-2: 1.75 cycles/limb
+
+
+C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+dnl used after src has been fetched
+define(VAR_RETVAL,`PARAM_SRC')
+
+dnl minimum 9, because unrolled loop can't handle less
+deflit(UNROLL_THRESHOLD, 9)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(mpn_lshift)
+deflit(`FRAME',0)
+
+ C The 1 limb case can be done without the push %ebx, but it's then
+ C still the same speed. The push is left as a free helping hand for
+ C the two_or_more code.
+
+ movl PARAM_SIZE, %eax
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_SRC, %ebx
+ decl %eax
+
+ movl PARAM_SHIFT, %ecx
+ jnz L(two_or_more)
+
+ movl (%ebx), %edx C src limb
+ movl PARAM_DST, %ebx
+
+ shldl( %cl, %edx, %eax) C return value
+
+ shll %cl, %edx
+
+ movl %edx, (%ebx) C dst limb
+ popl %ebx
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16) C avoid offset 0x1f
+L(two_or_more):
+ C eax size-1
+ C ebx src
+ C ecx shift
+ C edx
+
+ movl (%ebx,%eax,4), %edx C src high limb
+ negl %ecx
+
+ movd PARAM_SHIFT, %mm6
+ addl $32, %ecx C 32-shift
+
+ shrl %cl, %edx
+ cmpl $UNROLL_THRESHOLD-1, %eax
+
+ movl %edx, VAR_RETVAL
+ jae L(unroll)
+
+
+ movd %ecx, %mm7
+ movl %eax, %ecx
+
+ movl PARAM_DST, %eax
+
+L(simple):
+ C eax dst
+ C ebx src
+ C ecx counter, size-1 to 1
+ C edx retval
+ C
+ C mm0 scratch
+ C mm6 shift
+ C mm7 32-shift
+
+ movq -4(%ebx,%ecx,4), %mm0
+
+ psrlq %mm7, %mm0
+
+Zdisp( movd, %mm0, 0,(%eax,%ecx,4))
+ loop L(simple)
+
+
+ movd (%ebx), %mm0
+ popl %ebx
+
+ psllq %mm6, %mm0
+
+ movd %mm0, (%eax)
+ movl %edx, %eax
+
+ femms
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(unroll):
+ C eax size-1
+ C ebx src
+ C ecx 32-shift
+ C edx retval (but instead VAR_RETVAL is used)
+ C
+ C mm6 shift
+
+ addl $32, %ecx
+ movl PARAM_DST, %edx
+
+ movd %ecx, %mm7
+ subl $7, %eax C size-8
+
+ leal (%edx,%eax,4), %ecx C alignment of dst
+
+ movq 32-8(%ebx,%eax,4), %mm2 C src high qword
+ testb $4, %cl
+
+ jz L(dst_aligned)
+ psllq %mm6, %mm2
+
+ psrlq $32, %mm2
+ decl %eax
+
+ movd %mm2, 32(%edx,%eax,4) C dst high limb
+ movq 32-8(%ebx,%eax,4), %mm2 C new src high qword
+L(dst_aligned):
+
+ movq 32-16(%ebx,%eax,4), %mm0 C src second highest qword
+
+
+ C This loop is the important bit, the rest is just support for it.
+ C Four src limbs are held at the start, and four more will be read.
+ C Four dst limbs will be written. This schedule seems necessary for
+ C full speed.
+ C
+ C The use of size-8 lets the loop stop when %eax goes negative and
+ C leaves -4 to -1 which can be tested with test $1 and $2.
+
+L(top):
+ C eax counter, size-8 step by -4 until <0
+ C ebx src
+ C ecx
+ C edx dst
+ C
+ C mm0 src next qword
+ C mm1 scratch
+ C mm2 src prev qword
+ C mm6 shift
+ C mm7 64-shift
+
+ psllq %mm6, %mm2
+ subl $4, %eax
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ por %mm0, %mm2
+ movq 24(%ebx,%eax,4), %mm0
+
+ psllq %mm6, %mm1
+ movq %mm2, 40(%edx,%eax,4)
+
+ movq %mm0, %mm2
+ psrlq %mm7, %mm0
+
+ por %mm0, %mm1
+ movq 16(%ebx,%eax,4), %mm0
+
+ movq %mm1, 32(%edx,%eax,4)
+ jnc L(top)
+
+
+ C Now have four limbs in mm2 (prev) and mm0 (next), plus eax mod 4.
+ C
+ C 8(%ebx) is the next source, and 24(%edx) is the next destination.
+ C %eax is between -4 and -1, representing respectively 0 to 3 extra
+ C limbs that must be read.
+
+
+ testl $2, %eax C testl to avoid bad cache line crossing
+ jz L(finish_nottwo)
+
+ C Two more limbs: lshift mm2, OR it with rshifted mm0, mm0 becomes
+ C new mm2 and a new mm0 is loaded.
+
+ psllq %mm6, %mm2
+ movq %mm0, %mm1
+
+ psrlq %mm7, %mm0
+ subl $2, %eax
+
+ por %mm0, %mm2
+ movq 16(%ebx,%eax,4), %mm0
+
+ movq %mm2, 32(%edx,%eax,4)
+ movq %mm1, %mm2
+L(finish_nottwo):
+
+
+ C lshift mm2, OR with rshifted mm0, mm1 becomes lshifted mm0
+
+ testb $1, %al
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ por %mm0, %mm2
+ psllq %mm6, %mm1
+
+ movq %mm2, 24(%edx,%eax,4)
+ jz L(finish_even)
+
+
+ C Size is odd, so mm1 and one extra limb to process.
+
+ movd (%ebx), %mm0 C src[0]
+ popl %ebx
+deflit(`FRAME',0)
+
+ movq %mm0, %mm2
+ psllq $32, %mm0
+
+ psrlq %mm7, %mm0
+
+ psllq %mm6, %mm2
+ por %mm0, %mm1
+
+ movq %mm1, 4(%edx) C dst[1,2]
+ movd %mm2, (%edx) C dst[0]
+
+ movl VAR_RETVAL, %eax
+
+ femms
+ ret
+
+
+ nop C avoid bad cache line crossing
+L(finish_even):
+deflit(`FRAME',4)
+ C Size is even, so only mm1 left to process.
+
+ movq %mm1, (%edx) C dst[0,1]
+ movl VAR_RETVAL, %eax
+
+ popl %ebx
+ femms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/k62mmx/rshift.asm b/gmp/mpn/x86/k6/k62mmx/rshift.asm
new file mode 100644
index 0000000000..f604a7bd52
--- /dev/null
+++ b/gmp/mpn/x86/k6/k62mmx/rshift.asm
@@ -0,0 +1,293 @@
+dnl AMD K6-2 mpn_rshift -- mpn right shift.
+
+dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6-2: 1.75 cycles/limb
+
+
+C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+dnl Minimum 9, because the unrolled loop can't handle less.
+dnl
+deflit(UNROLL_THRESHOLD, 9)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(mpn_rshift)
+deflit(`FRAME',0)
+
+ C The 1 limb case can be done without the push %ebx, but it's then
+ C still the same speed. The push is left as a free helping hand for
+ C the two_or_more code.
+
+ movl PARAM_SIZE, %eax
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_SRC, %ebx
+ decl %eax
+
+ movl PARAM_SHIFT, %ecx
+ jnz L(two_or_more)
+
+ movl (%ebx), %edx C src limb
+ movl PARAM_DST, %ebx
+
+ shrdl( %cl, %edx, %eax) C return value
+
+ shrl %cl, %edx
+
+ movl %edx, (%ebx) C dst limb
+ popl %ebx
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16) C avoid offset 0x1f
+L(two_or_more):
+ C eax size-1
+ C ebx src
+ C ecx shift
+ C edx
+
+ movl (%ebx), %edx C src low limb
+ negl %ecx
+
+ addl $32, %ecx
+ movd PARAM_SHIFT, %mm6
+
+ shll %cl, %edx
+ cmpl $UNROLL_THRESHOLD-1, %eax
+
+ jae L(unroll)
+
+
+ C eax size-1
+ C ebx src
+ C ecx 32-shift
+ C edx retval
+ C
+ C mm6 shift
+
+ movl PARAM_DST, %ecx
+ leal (%ebx,%eax,4), %ebx
+
+ leal -4(%ecx,%eax,4), %ecx
+ negl %eax
+
+ C This loop runs at about 3 cycles/limb, which is the amount of
+ C decoding, and this is despite every second access being unaligned.
+
+L(simple):
+ C eax counter, -(size-1) to -1
+ C ebx &src[size-1]
+ C ecx &dst[size-1]
+ C edx retval
+ C
+ C mm0 scratch
+ C mm6 shift
+
+Zdisp( movq, 0,(%ebx,%eax,4), %mm0)
+ incl %eax
+
+ psrlq %mm6, %mm0
+
+Zdisp( movd, %mm0, 0,(%ecx,%eax,4))
+ jnz L(simple)
+
+
+ movq %mm0, (%ecx)
+ movl %edx, %eax
+
+ popl %ebx
+
+ femms
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(unroll):
+ C eax size-1
+ C ebx src
+ C ecx 32-shift
+ C edx retval
+ C
+ C mm6 shift
+
+ addl $32, %ecx
+ subl $7, %eax C size-8
+
+ movd %ecx, %mm7
+ movl PARAM_DST, %ecx
+
+ movq (%ebx), %mm2 C src low qword
+ leal (%ebx,%eax,4), %ebx C src end - 32
+
+ testb $4, %cl
+ leal (%ecx,%eax,4), %ecx C dst end - 32
+
+ notl %eax C -(size-7)
+ jz L(dst_aligned)
+
+ psrlq %mm6, %mm2
+ incl %eax
+
+Zdisp( movd, %mm2, 0,(%ecx,%eax,4)) C dst low limb
+ movq 4(%ebx,%eax,4), %mm2 C new src low qword
+L(dst_aligned):
+
+ movq 12(%ebx,%eax,4), %mm0 C src second lowest qword
+ nop C avoid bad cache line crossing
+
+
+ C This loop is the important bit, the rest is just support for it.
+ C Four src limbs are held at the start, and four more will be read.
+ C Four dst limbs will be written. This schedule seems necessary for
+ C full speed.
+ C
+ C The use of -(size-7) lets the loop stop when %eax becomes >= 0 and
+ C and leaves 0 to 3 which can be tested with test $1 and $2.
+
+L(top):
+ C eax counter, -(size-7) step by +4 until >=0
+ C ebx src end - 32
+ C ecx dst end - 32
+ C edx retval
+ C
+ C mm0 src next qword
+ C mm1 scratch
+ C mm2 src prev qword
+ C mm6 shift
+ C mm7 64-shift
+
+ psrlq %mm6, %mm2
+ addl $4, %eax
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ por %mm0, %mm2
+ movq 4(%ebx,%eax,4), %mm0
+
+ psrlq %mm6, %mm1
+ movq %mm2, -12(%ecx,%eax,4)
+
+ movq %mm0, %mm2
+ psllq %mm7, %mm0
+
+ por %mm0, %mm1
+ movq 12(%ebx,%eax,4), %mm0
+
+ movq %mm1, -4(%ecx,%eax,4)
+ ja L(top) C jump if no carry and not zero
+
+
+
+ C Now have the four limbs in mm2 (low) and mm0 (high), and %eax is 0
+ C to 3 representing respectively 3 to 0 further limbs.
+
+ testl $2, %eax C testl to avoid bad cache line crossings
+ jnz L(finish_nottwo)
+
+ C Two or three extra limbs: rshift mm2, OR it with lshifted mm0, mm0
+ C becomes new mm2 and a new mm0 is loaded.
+
+ psrlq %mm6, %mm2
+ movq %mm0, %mm1
+
+ psllq %mm7, %mm0
+ addl $2, %eax
+
+ por %mm0, %mm2
+ movq 12(%ebx,%eax,4), %mm0
+
+ movq %mm2, -4(%ecx,%eax,4)
+ movq %mm1, %mm2
+L(finish_nottwo):
+
+
+ testb $1, %al
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ por %mm0, %mm2
+ psrlq %mm6, %mm1
+
+ movq %mm2, 4(%ecx,%eax,4)
+ jnz L(finish_even)
+
+
+ C one further extra limb to process
+
+ movd 32-4(%ebx), %mm0 C src[size-1], most significant limb
+ popl %ebx
+
+ movq %mm0, %mm2
+ psllq %mm7, %mm0
+
+ por %mm0, %mm1
+ psrlq %mm6, %mm2
+
+ movq %mm1, 32-12(%ecx) C dst[size-3,size-2]
+ movd %mm2, 32-4(%ecx) C dst[size-1]
+
+ movl %edx, %eax C retval
+
+ femms
+ ret
+
+
+ nop C avoid bad cache line crossing
+L(finish_even):
+ C no further extra limbs
+
+ movq %mm1, 32-8(%ecx) C dst[size-2,size-1]
+ movl %edx, %eax C retval
+
+ popl %ebx
+
+ femms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mmx/com.asm b/gmp/mpn/x86/k6/mmx/com.asm
new file mode 100644
index 0000000000..b747454627
--- /dev/null
+++ b/gmp/mpn/x86/k6/mmx/com.asm
@@ -0,0 +1,103 @@
+dnl AMD K6-2 mpn_com -- mpn bitwise one's complement.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+NAILS_SUPPORT(0-31)
+
+
+C alignment dst/src, A=0mod8 N=4mod8
+C A/A A/N N/A N/N
+C K6-2 1.0 1.18 1.18 1.18 cycles/limb
+C K6 1.5 1.85 1.75 1.85
+
+
+C void mpn_com (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C Take the bitwise ones-complement of src,size and write it to dst,size.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_com)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %eax
+ movl PARAM_DST, %edx
+ shrl %ecx
+ jnz L(two_or_more)
+
+ movl (%eax), %eax
+ notl_or_xorl_GMP_NUMB_MASK( %eax)
+ movl %eax, (%edx)
+ ret
+
+
+L(two_or_more):
+ pushl %ebx FRAME_pushl()
+ pcmpeqd %mm7, %mm7 C all ones
+
+ movl %ecx, %ebx
+ifelse(GMP_NAIL_BITS,0,,
+` psrld $GMP_NAIL_BITS, %mm7') C clear nails
+
+
+
+ ALIGN(8)
+L(top):
+ C eax src
+ C ebx floor(size/2)
+ C ecx counter
+ C edx dst
+ C
+ C mm0 scratch
+ C mm7 mask
+
+ movq -8(%eax,%ecx,8), %mm0
+ pxor %mm7, %mm0
+ movq %mm0, -8(%edx,%ecx,8)
+ loop L(top)
+
+
+ jnc L(no_extra)
+ movl (%eax,%ebx,8), %eax
+ notl_or_xorl_GMP_NUMB_MASK( %eax)
+ movl %eax, (%edx,%ebx,8)
+L(no_extra):
+
+ popl %ebx
+ emms_or_femms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mmx/dive_1.asm b/gmp/mpn/x86/k6/mmx/dive_1.asm
new file mode 100644
index 0000000000..b644dca8cd
--- /dev/null
+++ b/gmp/mpn/x86/k6/mmx/dive_1.asm
@@ -0,0 +1,281 @@
+dnl AMD K6 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2000-2002, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C divisor
+C odd even
+C K6: 10.0 12.0 cycles/limb
+C K6-2: 10.0 11.5
+
+
+C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+C A simple divl is used for size==1. This is about 10 cycles faster for an
+C odd divisor or 20 cycles for an even divisor.
+C
+C The loops are quite sensitive to code alignment, speeds should be
+C rechecked (odd and even divisor, pic and non-pic) if contemplating
+C changing anything.
+
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(VAR_INVERSE,`PARAM_DST')
+
+ TEXT
+
+ ALIGN(32)
+PROLOGUE(mpn_divexact_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+
+ movl PARAM_SRC, %eax
+ xorl %edx, %edx
+
+ cmpl $1, %ecx
+ jnz L(two_or_more)
+
+ movl (%eax), %eax
+
+ divl PARAM_DIVISOR
+
+ movl PARAM_DST, %ecx
+ movl %eax, (%ecx)
+
+ ret
+
+
+L(two_or_more):
+ movl PARAM_DIVISOR, %eax
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_SRC, %ebx
+ pushl %ebp FRAME_pushl()
+
+L(strip_twos):
+ shrl %eax
+ incl %edx C will get shift+1
+
+ jnc L(strip_twos)
+ pushl %esi FRAME_pushl()
+
+ leal 1(%eax,%eax), %esi C d without twos
+ andl $127, %eax C d/2, 7 bits
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %ebp)
+Zdisp( movzbl, 0,(%eax,%ebp), %eax)
+',`
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+ pushl %edi FRAME_pushl()
+
+ leal (%eax,%eax), %ebp C 2*inv
+
+ imull %eax, %eax C inv*inv
+
+ movl PARAM_DST, %edi
+
+ imull %esi, %eax C inv*inv*d
+
+ subl %eax, %ebp C inv = 2*inv - inv*inv*d
+ leal (%ebp,%ebp), %eax C 2*inv
+
+ imull %ebp, %ebp C inv*inv
+
+ movl %esi, PARAM_DIVISOR C d without twos
+ leal (%ebx,%ecx,4), %ebx C src end
+
+ imull %esi, %ebp C inv*inv*d
+
+ leal (%edi,%ecx,4), %edi C dst end
+ negl %ecx C -size
+
+ subl %ebp, %eax C inv = 2*inv - inv*inv*d
+ subl $1, %edx C shift amount, and clear carry
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ imull PARAM_DIVISOR, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ movl %eax, VAR_INVERSE
+ jnz L(even)
+
+ movl (%ebx,%ecx,4), %esi C src low limb
+ jmp L(odd_entry)
+
+
+ ALIGN(16)
+ nop C code alignment
+L(odd_top):
+ C eax scratch
+ C ebx src end
+ C ecx counter, limbs, negative
+ C edx inverse
+ C esi next limb, adjusted for carry
+ C edi dst end
+ C ebp carry bit, 0 or -1
+
+ imull %edx, %esi
+
+ movl PARAM_DIVISOR, %eax
+ movl %esi, -4(%edi,%ecx,4)
+
+ mull %esi C carry limb in edx
+
+ subl %ebp, %edx C apply carry bit
+ movl (%ebx,%ecx,4), %esi
+
+L(odd_entry):
+ subl %edx, %esi C apply carry limb
+ movl VAR_INVERSE, %edx
+
+ sbbl %ebp, %ebp C 0 or -1
+
+ incl %ecx
+ jnz L(odd_top)
+
+
+ imull %edx, %esi
+
+ movl %esi, -4(%edi,%ecx,4)
+
+ popl %edi
+ popl %esi
+
+ popl %ebp
+ popl %ebx
+
+ ret
+
+
+L(even):
+ C eax
+ C ebx src end
+ C ecx -size
+ C edx twos
+ C esi
+ C edi dst end
+ C ebp
+
+ xorl %ebp, %ebp
+Zdisp( movq, 0,(%ebx,%ecx,4), %mm0) C src[0,1]
+
+ movd %edx, %mm7
+ movl VAR_INVERSE, %edx
+
+ addl $2, %ecx
+ psrlq %mm7, %mm0
+
+ movd %mm0, %esi
+ jz L(even_two) C if only two limbs
+
+
+C Out-of-order execution is good enough to hide the load/rshift/movd
+C latency. Having imul at the top of the loop gives 11.5 c/l instead of 12,
+C on K6-2. In fact there's only 11 of decode, but nothing running at 11 has
+C been found. Maybe the fact every second movq is unaligned costs the extra
+C 0.5.
+
+L(even_top):
+ C eax scratch
+ C ebx src end
+ C ecx counter, limbs, negative
+ C edx inverse
+ C esi next limb, adjusted for carry
+ C edi dst end
+ C ebp carry bit, 0 or -1
+ C
+ C mm0 scratch, source limbs
+ C mm7 twos
+
+ imull %edx, %esi
+
+ movl %esi, -8(%edi,%ecx,4)
+ movl PARAM_DIVISOR, %eax
+
+ mull %esi C carry limb in edx
+
+ movq -4(%ebx,%ecx,4), %mm0
+ psrlq %mm7, %mm0
+
+ movd %mm0, %esi
+ subl %ebp, %edx C apply carry bit
+
+ subl %edx, %esi C apply carry limb
+ movl VAR_INVERSE, %edx
+
+ sbbl %ebp, %ebp C 0 or -1
+
+ incl %ecx
+ jnz L(even_top)
+
+
+L(even_two):
+ movd -4(%ebx), %mm0 C src high limb
+ psrlq %mm7, %mm0
+
+ imull %edx, %esi
+
+ movl %esi, -8(%edi)
+ movl PARAM_DIVISOR, %eax
+
+ mull %esi C carry limb in edx
+
+ movd %mm0, %esi
+ subl %ebp, %edx C apply carry bit
+
+ movl VAR_INVERSE, %eax
+ subl %edx, %esi C apply carry limb
+
+ imull %eax, %esi
+
+ movl %esi, -4(%edi)
+
+ popl %edi
+ popl %esi
+
+ popl %ebp
+ popl %ebx
+
+ emms_or_femms
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mmx/logops_n.asm b/gmp/mpn/x86/k6/mmx/logops_n.asm
new file mode 100644
index 0000000000..e17930bb2d
--- /dev/null
+++ b/gmp/mpn/x86/k6/mmx/logops_n.asm
@@ -0,0 +1,226 @@
+dnl AMD K6-2 mpn_and_n, mpn_andn_n, mpn_nand_n, mpn_ior_n, mpn_iorn_n,
+dnl mpn_nior_n, mpn_xor_n, mpn_xnor_n -- mpn bitwise logical operations.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+NAILS_SUPPORT(0-31)
+
+
+C alignment dst/src1/src2, A=0mod8, N=4mod8
+C A/A/A A/A/N A/N/A A/N/N N/A/A N/A/N N/N/A N/N/N
+C
+C K6-2 1.2 1.5 1.5 1.2 1.2 1.5 1.5 1.2 and,andn,ior,xor
+C K6-2 1.5 1.75 2.0 1.75 1.75 2.0 1.75 1.5 iorn,xnor
+C K6-2 1.75 2.0 2.0 2.0 2.0 2.0 2.0 1.75 nand,nior
+C
+C K6 1.5 1.68 1.75 1.2 1.75 1.75 1.68 1.5 and,andn,ior,xor
+C K6 2.0 2.0 2.25 2.25 2.25 2.25 2.0 2.0 iorn,xnor
+C K6 2.0 2.25 2.25 2.25 2.25 2.25 2.25 2.0 nand,nior
+
+
+dnl M4_p and M4_i are the MMX and integer instructions
+dnl M4_*_neg_dst means whether to negate the final result before writing
+dnl M4_*_neg_src2 means whether to negate the src2 values before using them
+
+define(M4_choose_op,
+m4_assert_numargs(7)
+`ifdef(`OPERATION_$1',`
+define(`M4_function', `mpn_$1')
+define(`M4_operation', `$1')
+define(`M4_p', `$2')
+define(`M4_p_neg_dst', `$3')
+define(`M4_p_neg_src2',`$4')
+define(`M4_i', `$5')
+define(`M4_i_neg_dst', `$6')
+define(`M4_i_neg_src2',`$7')
+')')
+
+dnl xnor is done in "iorn" style because it's a touch faster than "nior"
+dnl style (the two are equivalent for xor).
+dnl
+dnl pandn can't be used with nails.
+
+M4_choose_op( and_n, pand,0,0, andl,0,0)
+ifelse(GMP_NAIL_BITS,0,
+`M4_choose_op(andn_n, pandn,0,0, andl,0,1)',
+`M4_choose_op(andn_n, pand,0,1, andl,0,1)')
+M4_choose_op( nand_n, pand,1,0, andl,1,0)
+M4_choose_op( ior_n, por,0,0, orl,0,0)
+M4_choose_op( iorn_n, por,0,1, orl,0,1)
+M4_choose_op( nior_n, por,1,0, orl,1,0)
+M4_choose_op( xor_n, pxor,0,0, xorl,0,0)
+M4_choose_op( xnor_n, pxor,0,1, xorl,0,1)
+
+ifdef(`M4_function',,
+`m4_error(`Unrecognised or undefined OPERATION symbol
+')')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+
+C void M4_function (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size);
+C
+C Do src1,size M4_operation src2,size, storing the result in dst,size.
+C
+C Unaligned movq loads and stores are a bit slower than aligned ones. The
+C test at the start of the routine checks the alignment of src1 and if
+C necessary processes one limb separately at the low end to make it aligned.
+C
+C The raw speeds without this alignment switch are as follows.
+C
+C alignment dst/src1/src2, A=0mod8, N=4mod8
+C A/A/A A/A/N A/N/A A/N/N N/A/A N/A/N N/N/A N/N/N
+C
+C K6 1.5 2.0 1.5 2.0 and,andn,ior,xor
+C K6 1.75 2.2 2.0 2.28 iorn,xnor
+C K6 2.0 2.25 2.35 2.28 nand,nior
+C
+C
+C Future:
+C
+C K6 can do one 64-bit load per cycle so each of these routines should be
+C able to approach 1.0 c/l, if aligned. The basic and/andn/ior/xor might be
+C able to get 1.0 with just a 4 limb loop, being 3 instructions per 2 limbs.
+C The others are 4 instructions per 2 limbs, and so can only approach 1.0
+C because there's nowhere to hide some loop control.
+
+defframe(PARAM_SIZE,16)
+defframe(PARAM_SRC2,12)
+defframe(PARAM_SRC1,8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(M4_function)
+ movl PARAM_SIZE, %ecx
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_SRC1, %eax
+
+ movl PARAM_SRC2, %ebx
+ cmpl $1, %ecx
+
+ movl PARAM_DST, %edx
+ ja L(two_or_more)
+
+
+ movl (%ebx), %ecx
+ popl %ebx
+ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %ecx)')
+ M4_i (%eax), %ecx
+ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %ecx)')
+ movl %ecx, (%edx)
+
+ ret
+
+
+L(two_or_more):
+ C eax src1
+ C ebx src2
+ C ecx size
+ C edx dst
+ C esi
+ C edi
+ C ebp
+
+ pushl %esi FRAME_pushl()
+ testl $4, %eax
+ jz L(alignment_ok)
+
+ movl (%ebx), %esi
+ addl $4, %ebx
+ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %esi)')
+ M4_i (%eax), %esi
+ addl $4, %eax
+ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %esi)')
+ movl %esi, (%edx)
+ addl $4, %edx
+ decl %ecx
+
+L(alignment_ok):
+ movl %ecx, %esi
+ shrl %ecx
+ jnz L(still_two_or_more)
+
+ movl (%ebx), %ecx
+ popl %esi
+ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %ecx)')
+ M4_i (%eax), %ecx
+ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %ecx)')
+ popl %ebx
+ movl %ecx, (%edx)
+ ret
+
+
+L(still_two_or_more):
+ifelse(eval(M4_p_neg_src2 || M4_p_neg_dst),1,`
+ pcmpeqd %mm7, %mm7 C all ones
+ifelse(GMP_NAIL_BITS,0,,`psrld $GMP_NAIL_BITS, %mm7') C clear nails
+')
+
+ ALIGN(16)
+L(top):
+ C eax src1
+ C ebx src2
+ C ecx counter
+ C edx dst
+ C esi
+ C edi
+ C ebp
+ C
+ C carry bit is low of size
+
+ movq -8(%ebx,%ecx,8), %mm0
+ifelse(M4_p_neg_src2,1,`pxor %mm7, %mm0')
+ M4_p -8(%eax,%ecx,8), %mm0
+ifelse(M4_p_neg_dst,1,` pxor %mm7, %mm0')
+ movq %mm0, -8(%edx,%ecx,8)
+
+ loop L(top)
+
+
+ jnc L(no_extra)
+
+ movl -4(%ebx,%esi,4), %ebx
+ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %ebx)')
+ M4_i -4(%eax,%esi,4), %ebx
+ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %ebx)')
+ movl %ebx, -4(%edx,%esi,4)
+L(no_extra):
+
+ popl %esi
+ popl %ebx
+ emms_or_femms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mmx/lshift.asm b/gmp/mpn/x86/k6/mmx/lshift.asm
new file mode 100644
index 0000000000..45be582633
--- /dev/null
+++ b/gmp/mpn/x86/k6/mmx/lshift.asm
@@ -0,0 +1,130 @@
+dnl AMD K6 mpn_lshift -- mpn left shift.
+
+dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: 3.0 cycles/limb
+
+
+C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C The loop runs at 3 cycles/limb, limited by decoding and by having 3 mmx
+C instructions. This is despite every second fetch being unaligned.
+
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(mpn_lshift)
+deflit(`FRAME',0)
+
+ C The 1 limb case can be done without the push %ebx, but it's then
+ C still the same speed. The push is left as a free helping hand for
+ C the two_or_more code.
+
+ movl PARAM_SIZE, %eax
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_SRC, %ebx
+ decl %eax
+
+ movl PARAM_SHIFT, %ecx
+ jnz L(two_or_more)
+
+ movl (%ebx), %edx C src limb
+ movl PARAM_DST, %ebx
+
+ shldl( %cl, %edx, %eax) C return value
+
+ shll %cl, %edx
+
+ movl %edx, (%ebx) C dst limb
+ popl %ebx
+
+ ret
+
+
+ ALIGN(16) C avoid offset 0x1f
+ nop C avoid bad cache line crossing
+L(two_or_more):
+ C eax size-1
+ C ebx src
+ C ecx shift
+ C edx
+
+ movl (%ebx,%eax,4), %edx C src high limb
+ negl %ecx
+
+ movd PARAM_SHIFT, %mm6
+ addl $32, %ecx C 32-shift
+
+ shrl %cl, %edx
+
+ movd %ecx, %mm7
+ movl PARAM_DST, %ecx
+
+L(top):
+ C eax counter, size-1 to 1
+ C ebx src
+ C ecx dst
+ C edx retval
+ C
+ C mm0 scratch
+ C mm6 shift
+ C mm7 32-shift
+
+ movq -4(%ebx,%eax,4), %mm0
+ decl %eax
+
+ psrlq %mm7, %mm0
+
+ movd %mm0, 4(%ecx,%eax,4)
+ jnz L(top)
+
+
+ movd (%ebx), %mm0
+ popl %ebx
+
+ psllq %mm6, %mm0
+ movl %edx, %eax
+
+ movd %mm0, (%ecx)
+
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mmx/popham.asm b/gmp/mpn/x86/k6/mmx/popham.asm
new file mode 100644
index 0000000000..2b19d0b5ee
--- /dev/null
+++ b/gmp/mpn/x86/k6/mmx/popham.asm
@@ -0,0 +1,236 @@
+dnl AMD K6-2 mpn_popcount, mpn_hamdist -- mpn bit population count and
+dnl hamming distance.
+
+dnl Copyright 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C popcount hamdist
+C K6-2: 9.0 11.5 cycles/limb
+C K6: 12.5 13.0
+
+
+C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
+C unsigned long mpn_hamdist (mp_srcptr src, mp_srcptr src2, mp_size_t size);
+C
+C The code here isn't optimal, but it's already a 2x speedup over the plain
+C integer mpn/generic/popcount.c,hamdist.c.
+
+
+ifdef(`OPERATION_popcount',,
+`ifdef(`OPERATION_hamdist',,
+`m4_error(`Need OPERATION_popcount or OPERATION_hamdist
+')m4exit(1)')')
+
+define(HAM,
+m4_assert_numargs(1)
+`ifdef(`OPERATION_hamdist',`$1')')
+
+define(POP,
+m4_assert_numargs(1)
+`ifdef(`OPERATION_popcount',`$1')')
+
+HAM(`
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC2, 8)
+defframe(PARAM_SRC, 4)
+define(M4_function,mpn_hamdist)
+')
+POP(`
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+define(M4_function,mpn_popcount)
+')
+
+MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
+
+
+ifdef(`PIC',,`
+ dnl non-PIC
+
+ RODATA
+ ALIGN(8)
+
+L(rodata_AAAAAAAAAAAAAAAA):
+ .long 0xAAAAAAAA
+ .long 0xAAAAAAAA
+
+L(rodata_3333333333333333):
+ .long 0x33333333
+ .long 0x33333333
+
+L(rodata_0F0F0F0F0F0F0F0F):
+ .long 0x0F0F0F0F
+ .long 0x0F0F0F0F
+
+L(rodata_000000FF000000FF):
+ .long 0x000000FF
+ .long 0x000000FF
+')
+
+ TEXT
+ ALIGN(32)
+
+POP(`ifdef(`PIC', `
+ C avoid shrl crossing a 32-byte boundary
+ nop')')
+
+PROLOGUE(M4_function)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+
+ifdef(`PIC',`
+ movl $0xAAAAAAAA, %eax
+ movl $0x33333333, %edx
+
+ movd %eax, %mm7
+ movd %edx, %mm6
+
+ movl $0x0F0F0F0F, %eax
+ movl $0x000000FF, %edx
+
+ punpckldq %mm7, %mm7
+ punpckldq %mm6, %mm6
+
+ movd %eax, %mm5
+ movd %edx, %mm4
+
+ punpckldq %mm5, %mm5
+ punpckldq %mm4, %mm4
+',`
+
+ movq L(rodata_AAAAAAAAAAAAAAAA), %mm7
+ movq L(rodata_3333333333333333), %mm6
+ movq L(rodata_0F0F0F0F0F0F0F0F), %mm5
+ movq L(rodata_000000FF000000FF), %mm4
+')
+
+define(REG_AAAAAAAAAAAAAAAA, %mm7)
+define(REG_3333333333333333, %mm6)
+define(REG_0F0F0F0F0F0F0F0F, %mm5)
+define(REG_000000FF000000FF, %mm4)
+
+
+ movl PARAM_SRC, %eax
+HAM(` movl PARAM_SRC2, %edx')
+
+ pxor %mm2, %mm2 C total
+
+ shrl %ecx
+ jnc L(top)
+
+Zdisp( movd, 0,(%eax,%ecx,8), %mm1)
+
+HAM(`
+Zdisp( movd, 0,(%edx,%ecx,8), %mm0)
+ pxor %mm0, %mm1
+')
+
+ incl %ecx
+ jmp L(loaded)
+
+
+ ALIGN(16)
+POP(` nop C alignment to avoid crossing 32-byte boundaries')
+
+L(top):
+ C eax src
+ C ebx
+ C ecx counter, qwords, decrementing
+ C edx [hamdist] src2
+ C
+ C mm0 (scratch)
+ C mm1 (scratch)
+ C mm2 total (low dword)
+ C mm3
+ C mm4 \
+ C mm5 | special constants
+ C mm6 |
+ C mm7 /
+
+ movq -8(%eax,%ecx,8), %mm1
+HAM(` pxor -8(%edx,%ecx,8), %mm1')
+
+L(loaded):
+ movq %mm1, %mm0
+ pand REG_AAAAAAAAAAAAAAAA, %mm1
+
+ psrlq $1, %mm1
+HAM(` nop C code alignment')
+
+ psubd %mm1, %mm0 C bit pairs
+HAM(` nop C code alignment')
+
+
+ movq %mm0, %mm1
+ psrlq $2, %mm0
+
+ pand REG_3333333333333333, %mm0
+ pand REG_3333333333333333, %mm1
+
+ paddd %mm1, %mm0 C nibbles
+
+
+ movq %mm0, %mm1
+ psrlq $4, %mm0
+
+ pand REG_0F0F0F0F0F0F0F0F, %mm0
+ pand REG_0F0F0F0F0F0F0F0F, %mm1
+
+ paddd %mm1, %mm0 C bytes
+
+ movq %mm0, %mm1
+ psrlq $8, %mm0
+
+
+ paddb %mm1, %mm0 C words
+
+
+ movq %mm0, %mm1
+ psrlq $16, %mm0
+
+ paddd %mm1, %mm0 C dwords
+
+ pand REG_000000FF000000FF, %mm0
+
+ paddd %mm0, %mm2 C low to total
+ psrlq $32, %mm0
+
+ paddd %mm0, %mm2 C high to total
+ loop L(top)
+
+
+
+ movd %mm2, %eax
+ emms_or_femms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mmx/rshift.asm b/gmp/mpn/x86/k6/mmx/rshift.asm
new file mode 100644
index 0000000000..cd0382f322
--- /dev/null
+++ b/gmp/mpn/x86/k6/mmx/rshift.asm
@@ -0,0 +1,130 @@
+dnl AMD K6 mpn_rshift -- mpn right shift.
+
+dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: 3.0 cycles/limb
+
+
+C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C The loop runs at 3 cycles/limb, limited by decoding and by having 3 mmx
+C instructions. This is despite every second fetch being unaligned.
+
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(mpn_rshift)
+deflit(`FRAME',0)
+
+ C The 1 limb case can be done without the push %ebx, but it's then
+ C still the same speed. The push is left as a free helping hand for
+ C the two_or_more code.
+
+ movl PARAM_SIZE, %eax
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_SRC, %ebx
+ decl %eax
+
+ movl PARAM_SHIFT, %ecx
+ jnz L(two_or_more)
+
+ movl (%ebx), %edx C src limb
+ movl PARAM_DST, %ebx
+
+ shrdl( %cl, %edx, %eax) C return value
+
+ shrl %cl, %edx
+
+ movl %edx, (%ebx) C dst limb
+ popl %ebx
+
+ ret
+
+
+ ALIGN(16) C avoid offset 0x1f
+L(two_or_more):
+ C eax size-1
+ C ebx src
+ C ecx shift
+ C edx
+
+ movl (%ebx), %edx C src low limb
+ negl %ecx
+
+ addl $32, %ecx C 32-shift
+ movd PARAM_SHIFT, %mm6
+
+ shll %cl, %edx C retval
+ movl PARAM_DST, %ecx
+
+ leal (%ebx,%eax,4), %ebx
+
+ leal -4(%ecx,%eax,4), %ecx
+ negl %eax
+
+
+L(simple):
+ C eax counter (negative)
+ C ebx &src[size-1]
+ C ecx &dst[size-1]
+ C edx retval
+ C
+ C mm0 scratch
+ C mm6 shift
+
+Zdisp( movq, 0,(%ebx,%eax,4), %mm0)
+ incl %eax
+
+ psrlq %mm6, %mm0
+
+Zdisp( movd, %mm0, 0,(%ecx,%eax,4))
+ jnz L(simple)
+
+
+ movq %mm0, (%ecx)
+ movl %edx, %eax
+
+ popl %ebx
+
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mod_34lsub1.asm b/gmp/mpn/x86/k6/mod_34lsub1.asm
new file mode 100644
index 0000000000..7e30503e54
--- /dev/null
+++ b/gmp/mpn/x86/k6/mod_34lsub1.asm
@@ -0,0 +1,190 @@
+dnl AMD K6 mpn_mod_34lsub1 -- mpn remainder modulo 2**24-1.
+
+dnl Copyright 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: 2.66 cycles/limb
+
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr src, mp_size_t size)
+C
+C An attempt was made to use a loop like
+C
+C L(top):
+C adcl (%edx), %eax
+C adcl 4(%edx), %ebx
+C adcl 8(%edx), %esi
+C leal 12(%edx), %edx
+C loop L(top)
+C
+C with %ecx starting from floor(size/3), but it still measured 2.66 c/l.
+C The form used instead can save about 6 cycles by not dividing by 3.
+C
+C In the code used, putting the "leal"s at the top of the loop is necessary
+C for the claimed speed, anywhere else costs an extra cycle per loop.
+C Perhaps a tight loop like this needs short decode instructions at the
+C branch target, which would explain the leal/loop form above taking 8
+C cycles instead of 7 too.
+
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX, `PARAM_SIZE')
+define(SAVE_ESI, `PARAM_SRC')
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_34lsub1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %eax
+ movl PARAM_SRC, %edx
+
+ subl $2, %eax
+ ja L(three_or_more)
+
+Zdisp( movl, 0,(%edx), %eax) C avoid code cache line boundary
+ jne L(one)
+
+ movl %eax, %ecx
+ movl 4(%edx), %edx
+
+ shrl $24, %eax C src[0] high
+ andl $0x00FFFFFF, %ecx C src[0] low
+
+ addl %ecx, %eax
+ movl %edx, %ecx
+
+ shll $8, %edx
+ andl $0x00FFFF00, %edx C src[1] high
+
+ shrl $16, %ecx C src[1] low
+ addl %ecx, %eax
+
+ addl %edx, %eax
+
+L(one):
+ ret
+
+
+L(three_or_more):
+ C eax size-2
+ C ebx
+ C ecx
+ C edx src
+
+ movl %ebx, SAVE_EBX
+ xorl %ebx, %ebx
+
+ movl %esi, SAVE_ESI
+ pushl %edi FRAME_pushl()
+
+ xorl %esi, %esi
+ xorl %edi, %edi C and clear carry flag
+
+L(top):
+ C eax counter, limbs
+ C ebx acc 0mod3
+ C ecx
+ C edx src, incrementing
+ C esi acc 1mod3
+ C edi acc 2mod3
+ C ebp
+
+ leal -2(%eax), %eax
+ leal 12(%edx), %edx
+
+ adcl -12(%edx), %ebx
+ adcl -8(%edx), %esi
+ adcl -4(%edx), %edi
+
+ decl %eax
+ jg L(top)
+
+
+ C ecx is -3, -2 or -1 representing 0, 1 or 2 more limbs, respectively
+
+ movb $0, %cl
+ incl %eax
+
+ js L(combine) C 0 more
+
+Zdisp( adcl, 0,(%edx), %ebx) C avoid code cache line crossings
+
+ movb $8, %cl
+ decl %eax
+
+ js L(combine) C 1 more
+
+ adcl 4(%edx), %esi
+
+ movb $16, %cl
+
+
+L(combine):
+ sbbl %edx, %edx
+
+ shll %cl, %edx C carry
+ movl %ebx, %eax C 0mod3
+
+ shrl $24, %eax C 0mod3 high
+ andl $0x00FFFFFF, %ebx C 0mod3 low
+
+ subl %edx, %eax C apply carry
+ movl %esi, %ecx C 1mod3
+
+ shrl $16, %esi C 1mod3 high
+ addl %ebx, %eax C apply 0mod3 low
+
+ andl $0x0000FFFF, %ecx
+ addl %esi, %eax C apply 1mod3 high
+
+ shll $8, %ecx C 1mod3 low
+ movl %edi, %edx C 2mod3
+
+ shrl $8, %edx C 2mod3 high
+ addl %ecx, %eax C apply 1mod3 low
+
+ addl %edx, %eax C apply 2mod3 high
+ andl $0x000000FF, %edi
+
+ shll $16, %edi C 2mod3 low
+ movl SAVE_EBX, %ebx
+
+ addl %edi, %eax C apply 2mod3 low
+ movl SAVE_ESI, %esi
+
+ popl %edi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mode1o.asm b/gmp/mpn/x86/k6/mode1o.asm
new file mode 100644
index 0000000000..a13f647b81
--- /dev/null
+++ b/gmp/mpn/x86/k6/mode1o.asm
@@ -0,0 +1,175 @@
+dnl AMD K6 mpn_modexact_1_odd -- exact division style remainder.
+
+dnl Copyright 2000-2003, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: 10.0 cycles/limb
+
+
+C mp_limb_t mpn_modexact_1_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C
+C A special case for high<divisor at the end measured only about 4 cycles
+C faster, and so isn't used.
+C
+C A special case for size==1 using a divl rather than the inverse measured
+C only about 5 cycles faster, and so isn't used. When size==1 and
+C high<divisor it can skip a division and be a full 24 cycles faster, but
+C this isn't an important case.
+
+defframe(PARAM_CARRY, 16)
+defframe(PARAM_DIVISOR,12)
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+ TEXT
+
+ ALIGN(32)
+PROLOGUE(mpn_modexact_1c_odd)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %ecx
+ pushl %esi FRAME_pushl()
+
+ movl PARAM_CARRY, %edx
+ jmp L(start_1c)
+
+EPILOGUE()
+
+
+ ALIGN(16)
+PROLOGUE(mpn_modexact_1_odd)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %ecx
+ pushl %esi FRAME_pushl()
+
+ xorl %edx, %edx
+L(start_1c):
+ pushl %edi FRAME_pushl()
+
+ shrl %ecx C d/2
+ movl PARAM_DIVISOR, %esi
+
+ andl $127, %ecx C d/2, 7 bits
+ pushl %ebp FRAME_pushl()
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %edi)
+Zdisp( movzbl, 0,(%ecx,%edi), %edi) C inv 8 bits
+',`
+ movzbl binvert_limb_table(%ecx), %edi C inv 8 bits
+')
+ leal (%edi,%edi), %ecx C 2*inv
+
+ imull %edi, %edi C inv*inv
+
+ movl PARAM_SRC, %eax
+ movl PARAM_SIZE, %ebp
+
+ imull %esi, %edi C inv*inv*d
+
+ pushl %ebx FRAME_pushl()
+ leal (%eax,%ebp,4), %ebx C src end
+
+ subl %edi, %ecx C inv = 2*inv - inv*inv*d
+ leal (%ecx,%ecx), %edi C 2*inv
+
+ imull %ecx, %ecx C inv*inv
+
+ movl (%eax), %eax C src low limb
+ negl %ebp C -size
+
+ imull %esi, %ecx C inv*inv*d
+
+ subl %ecx, %edi C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax
+ movl %esi, %eax
+ imull %edi, %eax
+ cmpl $1, %eax
+ popl %eax')
+
+ jmp L(entry)
+
+
+C Rotating the mul to the top of the loop saves 1 cycle, presumably by
+C hiding the loop control under the imul latency.
+C
+C The run time is 10 cycles, but decoding is only 9 (and the dependent chain
+C only 8). It's not clear how to get down to 9 cycles.
+C
+C The xor and rcl to handle the carry bit could be an sbb instead, with the
+C the carry bit add becoming a sub, but that doesn't save anything.
+
+L(top):
+ C eax (low product)
+ C ebx src end
+ C ecx carry bit, 0 or 1
+ C edx (high product, being carry limb)
+ C esi divisor
+ C edi inverse
+ C ebp counter, limbs, negative
+
+ mull %esi
+
+ movl (%ebx,%ebp,4), %eax
+ addl %ecx, %edx C apply carry bit to carry limb
+
+L(entry):
+ xorl %ecx, %ecx
+ subl %edx, %eax C apply carry limb
+
+ rcll %ecx
+
+ imull %edi, %eax
+
+ incl %ebp
+ jnz L(top)
+
+
+
+ popl %ebx
+ popl %ebp
+
+ mull %esi
+
+ popl %edi
+ popl %esi
+
+ leal (%ecx,%edx), %eax
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mul_1.asm b/gmp/mpn/x86/k6/mul_1.asm
new file mode 100644
index 0000000000..3ef7ec24fe
--- /dev/null
+++ b/gmp/mpn/x86/k6/mul_1.asm
@@ -0,0 +1,292 @@
+dnl AMD K6 mpn_mul_1 -- mpn by limb multiply.
+
+dnl Copyright 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12 5.5
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan) 4.87
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C AMD K6 6.25
+C AMD K7
+C AMD K8
+
+
+C mp_limb_t mpn_mul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t multiplier);
+C mp_limb_t mpn_mul_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t multiplier, mp_limb_t carry);
+C
+C Multiply src,size by mult and store the result in dst,size.
+C Return the carry limb from the top of the result.
+C
+C mpn_mul_1c() accepts an initial carry for the calculation, it's added into
+C the low limb of the result.
+
+defframe(PARAM_CARRY, 20)
+defframe(PARAM_MULTIPLIER,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl minimum 5 because the unrolled code can't handle less
+deflit(UNROLL_THRESHOLD, 5)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(mpn_mul_1c)
+ pushl %esi
+deflit(`FRAME',4)
+ movl PARAM_CARRY, %esi
+ jmp L(start_nc)
+EPILOGUE()
+
+
+PROLOGUE(mpn_mul_1)
+ push %esi
+deflit(`FRAME',4)
+ xorl %esi, %esi C initial carry
+
+L(start_nc):
+ mov PARAM_SIZE, %ecx
+ push %ebx
+FRAME_pushl()
+
+ movl PARAM_SRC, %ebx
+ push %edi
+FRAME_pushl()
+
+ movl PARAM_DST, %edi
+ pushl %ebp
+FRAME_pushl()
+
+ cmpl $UNROLL_THRESHOLD, %ecx
+ movl PARAM_MULTIPLIER, %ebp
+
+ jae L(unroll)
+
+
+ C code offset 0x22 here, close enough to aligned
+L(simple):
+ C eax scratch
+ C ebx src
+ C ecx counter
+ C edx scratch
+ C esi carry
+ C edi dst
+ C ebp multiplier
+ C
+ C this loop 8 cycles/limb
+
+ movl (%ebx), %eax
+ addl $4, %ebx
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, (%edi)
+ addl $4, %edi
+
+ loop L(simple)
+
+
+ popl %ebp
+
+ popl %edi
+ popl %ebx
+
+ movl %esi, %eax
+ popl %esi
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+C The code for each limb is 6 cycles, with instruction decoding being the
+C limiting factor. At 4 limbs/loop and 1 cycle/loop of overhead it's 6.25
+C cycles/limb in total.
+C
+C The secret ingredient to get 6.25 is to start the loop with the mul and
+C have the load/store pair at the end. Rotating the load/store to the top
+C is an 0.5 c/l slowdown. (Some address generation effect probably.)
+C
+C The whole unrolled loop fits nicely in exactly 80 bytes.
+
+
+ ALIGN(16) C already aligned to 16 here actually
+L(unroll):
+ movl (%ebx), %eax
+ leal -16(%ebx,%ecx,4), %ebx
+
+ leal -16(%edi,%ecx,4), %edi
+ subl $4, %ecx
+
+ negl %ecx
+
+
+ ALIGN(16) C one byte nop for this alignment
+L(top):
+ C eax scratch
+ C ebx &src[size-4]
+ C ecx counter
+ C edx scratch
+ C esi carry
+ C edi &dst[size-4]
+ C ebp multiplier
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, (%edi,%ecx,4)
+ movl 4(%ebx,%ecx,4), %eax
+
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, 4(%edi,%ecx,4)
+ movl 8(%ebx,%ecx,4), %eax
+
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, 8(%edi,%ecx,4)
+ movl 12(%ebx,%ecx,4), %eax
+
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, 12(%edi,%ecx,4)
+ movl 16(%ebx,%ecx,4), %eax
+
+
+ addl $4, %ecx
+ js L(top)
+
+
+
+ C eax next src limb
+ C ebx &src[size-4]
+ C ecx 0 to 3 representing respectively 4 to 1 further limbs
+ C edx
+ C esi carry
+ C edi &dst[size-4]
+
+ testb $2, %cl
+ jnz L(finish_not_two)
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, (%edi,%ecx,4)
+ movl 4(%ebx,%ecx,4), %eax
+
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, 4(%edi,%ecx,4)
+ movl 8(%ebx,%ecx,4), %eax
+
+ addl $2, %ecx
+L(finish_not_two):
+
+
+ testb $1, %cl
+ jnz L(finish_not_one)
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, 8(%edi)
+ movl 12(%ebx), %eax
+L(finish_not_one):
+
+
+ mull %ebp
+
+ addl %esi, %eax
+ popl %ebp
+
+ adcl $0, %edx
+
+ movl %eax, 12(%edi)
+ popl %edi
+
+ popl %ebx
+ movl %edx, %eax
+
+ popl %esi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/mul_basecase.asm b/gmp/mpn/x86/k6/mul_basecase.asm
new file mode 100644
index 0000000000..7030001c3f
--- /dev/null
+++ b/gmp/mpn/x86/k6/mul_basecase.asm
@@ -0,0 +1,612 @@
+dnl AMD K6 mpn_mul_basecase -- multiply two mpn numbers.
+
+dnl Copyright 1999-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: approx 9.0 cycles per cross product on 30x30 limbs (with 16 limbs/loop
+C unrolling).
+
+
+
+dnl K6: UNROLL_COUNT cycles/product (approx)
+dnl 8 9.75
+dnl 16 9.3
+dnl 32 9.3
+dnl Maximum possible with the current code is 32.
+dnl
+dnl With 16 the inner unrolled loop fits exactly in a 256 byte block, which
+dnl might explain it's good performance.
+
+deflit(UNROLL_COUNT, 16)
+
+
+C void mpn_mul_basecase (mp_ptr wp,
+C mp_srcptr xp, mp_size_t xsize,
+C mp_srcptr yp, mp_size_t ysize);
+C
+C Calculate xp,xsize multiplied by yp,ysize, storing the result in
+C wp,xsize+ysize.
+C
+C This routine is essentially the same as mpn/generic/mul_basecase.c, but
+C it's faster because it does most of the mpn_addmul_1() entry code only
+C once. The saving is about 10-20% on typical sizes coming from the
+C Karatsuba multiply code.
+C
+C Enhancements:
+C
+C The mul_1 loop is about 8.5 c/l, which is slower than mpn_mul_1 at 6.25
+C c/l. Could call mpn_mul_1 when ysize is big enough to make it worthwhile.
+C
+C The main unrolled addmul loop could be shared by mpn_addmul_1, using some
+C extra stack setups and maybe 2 or 3 wasted cycles at the end. Code saving
+C would be 256 bytes.
+
+ifdef(`PIC',`
+deflit(UNROLL_THRESHOLD, 8)
+',`
+deflit(UNROLL_THRESHOLD, 8)
+')
+
+defframe(PARAM_YSIZE,20)
+defframe(PARAM_YP, 16)
+defframe(PARAM_XSIZE,12)
+defframe(PARAM_XP, 8)
+defframe(PARAM_WP, 4)
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mul_basecase)
+deflit(`FRAME',0)
+
+ movl PARAM_XSIZE, %ecx
+ movl PARAM_YP, %eax
+
+ movl PARAM_XP, %edx
+ movl (%eax), %eax C yp low limb
+
+ cmpl $2, %ecx
+ ja L(xsize_more_than_two_limbs)
+ je L(two_by_something)
+
+
+ C one limb by one limb
+
+ movl (%edx), %edx C xp low limb
+ movl PARAM_WP, %ecx
+
+ mull %edx
+
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(two_by_something):
+ decl PARAM_YSIZE
+ pushl %ebx
+deflit(`FRAME',4)
+
+ movl PARAM_WP, %ebx
+ pushl %esi
+deflit(`FRAME',8)
+
+ movl %eax, %ecx C yp low limb
+ movl (%edx), %eax C xp low limb
+
+ movl %edx, %esi C xp
+ jnz L(two_by_two)
+
+
+ C two limbs by one limb
+
+ mull %ecx
+
+ movl %eax, (%ebx)
+ movl 4(%esi), %eax
+
+ movl %edx, %esi C carry
+
+ mull %ecx
+
+ addl %eax, %esi
+ movl %esi, 4(%ebx)
+
+ adcl $0, %edx
+
+ movl %edx, 8(%ebx)
+ popl %esi
+
+ popl %ebx
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(two_by_two):
+ C eax xp low limb
+ C ebx wp
+ C ecx yp low limb
+ C edx
+ C esi xp
+ C edi
+ C ebp
+deflit(`FRAME',8)
+
+ mull %ecx C xp[0] * yp[0]
+
+ push %edi
+deflit(`FRAME',12)
+ movl %eax, (%ebx)
+
+ movl 4(%esi), %eax
+ movl %edx, %edi C carry, for wp[1]
+
+ mull %ecx C xp[1] * yp[0]
+
+ addl %eax, %edi
+ movl PARAM_YP, %ecx
+
+ adcl $0, %edx
+
+ movl %edi, 4(%ebx)
+ movl 4(%ecx), %ecx C yp[1]
+
+ movl 4(%esi), %eax C xp[1]
+ movl %edx, %edi C carry, for wp[2]
+
+ mull %ecx C xp[1] * yp[1]
+
+ addl %eax, %edi
+
+ adcl $0, %edx
+
+ movl (%esi), %eax C xp[0]
+ movl %edx, %esi C carry, for wp[3]
+
+ mull %ecx C xp[0] * yp[1]
+
+ addl %eax, 4(%ebx)
+ adcl %edx, %edi
+ adcl $0, %esi
+
+ movl %edi, 8(%ebx)
+ popl %edi
+
+ movl %esi, 12(%ebx)
+ popl %esi
+
+ popl %ebx
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(xsize_more_than_two_limbs):
+
+C The first limb of yp is processed with a simple mpn_mul_1 style loop
+C inline. Unrolling this doesn't seem worthwhile since it's only run once
+C (whereas the addmul below is run ysize-1 many times). A call to the
+C actual mpn_mul_1 will be slowed down by the call and parameter pushing and
+C popping, and doesn't seem likely to be worthwhile on the typical 10-20
+C limb operations the Karatsuba code calls here with.
+
+ C eax yp[0]
+ C ebx
+ C ecx xsize
+ C edx xp
+ C esi
+ C edi
+ C ebp
+deflit(`FRAME',0)
+
+ pushl %edi defframe_pushl(SAVE_EDI)
+ pushl %ebp defframe_pushl(SAVE_EBP)
+
+ movl PARAM_WP, %edi
+ pushl %esi defframe_pushl(SAVE_ESI)
+
+ movl %eax, %ebp
+ pushl %ebx defframe_pushl(SAVE_EBX)
+
+ leal (%edx,%ecx,4), %ebx C xp end
+ xorl %esi, %esi
+
+ leal (%edi,%ecx,4), %edi C wp end of mul1
+ negl %ecx
+
+
+L(mul1):
+ C eax scratch
+ C ebx xp end
+ C ecx counter, negative
+ C edx scratch
+ C esi carry
+ C edi wp end of mul1
+ C ebp multiplier
+
+ movl (%ebx,%ecx,4), %eax
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, (%edi,%ecx,4)
+ incl %ecx
+
+ jnz L(mul1)
+
+
+ movl PARAM_YSIZE, %edx
+ movl %esi, (%edi) C final carry
+
+ movl PARAM_XSIZE, %ecx
+ decl %edx
+
+ jnz L(ysize_more_than_one_limb)
+
+ popl %ebx
+ popl %esi
+ popl %ebp
+ popl %edi
+ ret
+
+
+L(ysize_more_than_one_limb):
+ cmpl $UNROLL_THRESHOLD, %ecx
+ movl PARAM_YP, %eax
+
+ jae L(unroll)
+
+
+C -----------------------------------------------------------------------------
+C Simple addmul loop.
+C
+C Using ebx and edi pointing at the ends of their respective locations saves
+C a couple of instructions in the outer loop. The inner loop is still 11
+C cycles, the same as the simple loop in aorsmul_1.asm.
+
+ C eax yp
+ C ebx xp end
+ C ecx xsize
+ C edx ysize-1
+ C esi
+ C edi wp end of mul1
+ C ebp
+
+ movl 4(%eax), %ebp C multiplier
+ negl %ecx
+
+ movl %ecx, PARAM_XSIZE C -xsize
+ xorl %esi, %esi C initial carry
+
+ leal 4(%eax,%edx,4), %eax C yp end
+ negl %edx
+
+ movl %eax, PARAM_YP
+ movl %edx, PARAM_YSIZE
+
+ jmp L(simple_outer_entry)
+
+
+ C aligning here saves a couple of cycles
+ ALIGN(16)
+L(simple_outer_top):
+ C edx ysize counter, negative
+
+ movl PARAM_YP, %eax C yp end
+ xorl %esi, %esi C carry
+
+ movl PARAM_XSIZE, %ecx C -xsize
+ movl %edx, PARAM_YSIZE
+
+ movl (%eax,%edx,4), %ebp C yp limb multiplier
+L(simple_outer_entry):
+ addl $4, %edi
+
+
+L(simple_inner):
+ C eax scratch
+ C ebx xp end
+ C ecx counter, negative
+ C edx scratch
+ C esi carry
+ C edi wp end of this addmul
+ C ebp multiplier
+
+ movl (%ebx,%ecx,4), %eax
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl $0, %edx
+ addl %eax, (%edi,%ecx,4)
+ adcl %edx, %esi
+
+ incl %ecx
+ jnz L(simple_inner)
+
+
+ movl PARAM_YSIZE, %edx
+ movl %esi, (%edi)
+
+ incl %edx
+ jnz L(simple_outer_top)
+
+
+ popl %ebx
+ popl %esi
+ popl %ebp
+ popl %edi
+ ret
+
+
+C -----------------------------------------------------------------------------
+C Unrolled loop.
+C
+C The unrolled inner loop is the same as in aorsmul_1.asm, see that code for
+C some comments.
+C
+C VAR_COUNTER is for the inner loop, running from VAR_COUNTER_INIT down to
+C 0, inclusive.
+C
+C VAR_JMP is the computed jump into the unrolled loop.
+C
+C PARAM_XP and PARAM_WP get offset appropriately for where the unrolled loop
+C is entered.
+C
+C VAR_XP_LOW is the least significant limb of xp, which is needed at the
+C start of the unrolled loop. This can't just be fetched through the xp
+C pointer because of the offset applied to it.
+C
+C PARAM_YSIZE is the outer loop counter, going from -(ysize-1) up to -1,
+C inclusive.
+C
+C PARAM_YP is offset appropriately so that the PARAM_YSIZE counter can be
+C added to give the location of the next limb of yp, which is the multiplier
+C in the unrolled loop.
+C
+C PARAM_WP is similarly offset so that the PARAM_YSIZE counter can be added
+C to give the starting point in the destination for each unrolled loop (this
+C point is one limb upwards for each limb of yp processed).
+C
+C Having PARAM_YSIZE count negative to zero means it's not necessary to
+C store new values of PARAM_YP and PARAM_WP on each loop. Those values on
+C the stack remain constant and on each loop an leal adjusts them with the
+C PARAM_YSIZE counter value.
+
+
+defframe(VAR_COUNTER, -20)
+defframe(VAR_COUNTER_INIT, -24)
+defframe(VAR_JMP, -28)
+defframe(VAR_XP_LOW, -32)
+deflit(VAR_STACK_SPACE, 16)
+
+dnl For some strange reason using (%esp) instead of 0(%esp) is a touch
+dnl slower in this code, hence the defframe empty-if-zero feature is
+dnl disabled.
+dnl
+dnl If VAR_COUNTER is at (%esp), the effect is worse. In this case the
+dnl unrolled loop is 255 instead of 256 bytes, but quite how this affects
+dnl anything isn't clear.
+dnl
+define(`defframe_empty_if_zero_disabled',1)
+
+L(unroll):
+ C eax yp (not used)
+ C ebx xp end (not used)
+ C ecx xsize
+ C edx ysize-1
+ C esi
+ C edi wp end of mul1 (not used)
+ C ebp
+deflit(`FRAME', 16)
+
+ leal -2(%ecx), %ebp C one limb processed at start,
+ decl %ecx C and ebp is one less
+
+ shrl $UNROLL_LOG2, %ebp
+ negl %ecx
+
+ subl $VAR_STACK_SPACE, %esp
+deflit(`FRAME', 16+VAR_STACK_SPACE)
+ andl $UNROLL_MASK, %ecx
+
+ movl %ecx, %esi
+ shll $4, %ecx
+
+ movl %ebp, VAR_COUNTER_INIT
+ negl %esi
+
+ C 15 code bytes per limb
+ifdef(`PIC',`
+ call L(pic_calc)
+L(unroll_here):
+',`
+ leal L(unroll_entry) (%ecx,%esi,1), %ecx
+')
+
+ movl PARAM_XP, %ebx
+ movl %ebp, VAR_COUNTER
+
+ movl PARAM_WP, %edi
+ movl %ecx, VAR_JMP
+
+ movl (%ebx), %eax
+ leal 4(%edi,%esi,4), %edi C wp adjust for unrolling and mul1
+
+ leal (%ebx,%esi,4), %ebx C xp adjust for unrolling
+
+ movl %eax, VAR_XP_LOW
+
+ movl %ebx, PARAM_XP
+ movl PARAM_YP, %ebx
+
+ leal (%edi,%edx,4), %ecx C wp adjust for ysize indexing
+ movl 4(%ebx), %ebp C multiplier (yp second limb)
+
+ leal 4(%ebx,%edx,4), %ebx C yp adjust for ysize indexing
+
+ movl %ecx, PARAM_WP
+
+ leal 1(%esi), %ecx C adjust parity for decl %ecx above
+
+ movl %ebx, PARAM_YP
+ negl %edx
+
+ movl %edx, PARAM_YSIZE
+ jmp L(unroll_outer_entry)
+
+
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ leal (%ecx,%esi,1), %ecx
+ addl $L(unroll_entry)-L(unroll_here), %ecx
+ addl (%esp), %ecx
+ ret_internal
+')
+
+
+C -----------------------------------------------------------------------------
+ C Aligning here saves a couple of cycles per loop. Using 32 doesn't
+ C cost any extra space, since the inner unrolled loop below is
+ C aligned to 32.
+ ALIGN(32)
+L(unroll_outer_top):
+ C edx ysize
+
+ movl PARAM_YP, %eax
+ movl %edx, PARAM_YSIZE C incremented ysize counter
+
+ movl PARAM_WP, %edi
+
+ movl VAR_COUNTER_INIT, %ebx
+ movl (%eax,%edx,4), %ebp C next multiplier
+
+ movl PARAM_XSIZE, %ecx
+ leal (%edi,%edx,4), %edi C adjust wp for where we are in yp
+
+ movl VAR_XP_LOW, %eax
+ movl %ebx, VAR_COUNTER
+
+L(unroll_outer_entry):
+ mull %ebp
+
+ C using testb is a tiny bit faster than testl
+ testb $1, %cl
+
+ movl %eax, %ecx C low carry
+ movl VAR_JMP, %eax
+
+ movl %edx, %esi C high carry
+ movl PARAM_XP, %ebx
+
+ jnz L(unroll_noswap)
+ movl %ecx, %esi C high,low carry other way around
+
+ movl %edx, %ecx
+L(unroll_noswap):
+
+ jmp *%eax
+
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(32)
+L(unroll_top):
+ C eax scratch
+ C ebx xp
+ C ecx carry low
+ C edx scratch
+ C esi carry high
+ C edi wp
+ C ebp multiplier
+ C VAR_COUNTER loop counter
+ C
+ C 15 code bytes each limb
+
+ leal UNROLL_BYTES(%edi), %edi
+
+L(unroll_entry):
+deflit(CHUNK_COUNT,2)
+forloop(`i', 0, UNROLL_COUNT/CHUNK_COUNT-1, `
+ deflit(`disp0', eval(i*CHUNK_COUNT*4))
+ deflit(`disp1', eval(disp0 + 4))
+ deflit(`disp2', eval(disp1 + 4))
+
+ movl disp1(%ebx), %eax
+ mull %ebp
+Zdisp( addl, %ecx, disp0,(%edi))
+ adcl %eax, %esi
+ movl %edx, %ecx
+ jadcl0( %ecx)
+
+ movl disp2(%ebx), %eax
+ mull %ebp
+ addl %esi, disp1(%edi)
+ adcl %eax, %ecx
+ movl %edx, %esi
+ jadcl0( %esi)
+')
+
+ decl VAR_COUNTER
+ leal UNROLL_BYTES(%ebx), %ebx
+
+ jns L(unroll_top)
+
+
+ movl PARAM_YSIZE, %edx
+ addl %ecx, UNROLL_BYTES(%edi)
+
+ adcl $0, %esi
+
+ incl %edx
+ movl %esi, UNROLL_BYTES+4(%edi)
+
+ jnz L(unroll_outer_top)
+
+
+ movl SAVE_ESI, %esi
+ movl SAVE_EBP, %ebp
+ movl SAVE_EDI, %edi
+ movl SAVE_EBX, %ebx
+
+ addl $FRAME, %esp
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/pre_mod_1.asm b/gmp/mpn/x86/k6/pre_mod_1.asm
new file mode 100644
index 0000000000..34db20d386
--- /dev/null
+++ b/gmp/mpn/x86/k6/pre_mod_1.asm
@@ -0,0 +1,146 @@
+dnl AMD K6 mpn_preinv_mod_1 -- mpn by 1 remainder, with pre-inverted divisor.
+
+dnl Copyright 2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: 18.0 cycles/limb
+
+
+C mp_limb_t mpn_preinv_mod_1 (mp_srcptr src, mp_size_t size, mp_limb_t divisor,
+C mp_limb_t inverse);
+C
+C This code is only 2 c/l faster than a simple divl, but that's 10% so it's
+C considered worthwhile (just).
+
+defframe(PARAM_INVERSE,16)
+defframe(PARAM_DIVISOR,12)
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_preinv_mod_1)
+deflit(`FRAME',0)
+
+ ASSERT(ae,`cmpl $1, PARAM_SIZE')
+ ASSERT(nz,`testl $0x80000000, PARAM_DIVISOR')
+
+ movl PARAM_SIZE, %ecx
+ pushl %ebp FRAME_pushl()
+
+ movl PARAM_SRC, %ebp
+ pushl %edi FRAME_pushl()
+
+ movl PARAM_DIVISOR, %eax
+ pushl %esi FRAME_pushl()
+
+ movl -4(%ebp,%ecx,4), %esi C src high limb
+ pushl %ebx FRAME_pushl()
+
+ movl %edx, %edi C first n2 to cancel
+ subl %eax, %esi C first n1 = high-divisor
+
+ decl %ecx
+ jz L(done_sbbl)
+
+L(top):
+ C eax scratch
+ C ebx n10, nadj, q1
+ C ecx counter, size to 1
+ C edx scratch
+ C esi n2
+ C edi old high, for underflow test
+ C ebp src
+
+ sbbl %edx, %edi C high n-(q1+1)*d, 0 or -1
+
+L(entry):
+ andl PARAM_DIVISOR, %edi
+L(q1_ff_top):
+ movl -4(%ebp,%ecx,4), %ebx
+
+ addl %esi, %edi C possible addback
+ movl %ebx, %esi C n10
+
+ sarl $31, %ebx C -n1 = 0 or -1
+ movl %edi, %eax C n2
+
+ movl PARAM_INVERSE, %edx
+ subl %ebx, %eax C n2+n1
+
+ mull %edx C m*(n2+n1)
+
+ andl PARAM_DIVISOR, %ebx C -n1 & d
+ addl %esi, %ebx C nadj = n10 + (-n1&d), ignoring overflow
+
+ addl %ebx, %eax C low m*(n2+n1) + nadj, giving carry flag
+ leal 1(%edi), %ebx C n2+1
+
+ adcl %ebx, %edx C 1+high(n2<<32+m*(n2+n1)+nadj) = q1+1
+
+ movl PARAM_DIVISOR, %eax C d
+ jz L(q1_ff)
+
+ mull %edx C (q1+1)*d
+
+ subl %eax, %esi C low n-(q1+1)*d
+ loop L(top)
+
+
+
+L(done_sbbl):
+ sbbl %edx, %edi C high n-(q1+1)*d, 0 or -1
+
+ andl PARAM_DIVISOR, %edi
+L(done_esi_edi):
+ popl %ebx
+
+ leal (%esi,%edi), %eax
+ popl %esi
+
+ popl %edi
+ popl %ebp
+
+ ret
+
+
+C Special case for q1=0xFFFFFFFF, giving q=0xFFFFFFFF meaning the low dword
+C of q*d is simply -d and the remainder n-q*d = n10+d. This is rarely
+C reached.
+
+L(q1_ff):
+ movl PARAM_DIVISOR, %edi
+ loop L(q1_ff_top)
+
+ jmp L(done_esi_edi)
+
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k6/sqr_basecase.asm b/gmp/mpn/x86/k6/sqr_basecase.asm
new file mode 100644
index 0000000000..b7ecb5cc8a
--- /dev/null
+++ b/gmp/mpn/x86/k6/sqr_basecase.asm
@@ -0,0 +1,680 @@
+dnl AMD K6 mpn_sqr_basecase -- square an mpn number.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K6: approx 4.7 cycles per cross product, or 9.2 cycles per triangular
+C product (measured on the speed difference between 17 and 33 limbs,
+C which is roughly the Karatsuba recursing range).
+
+
+dnl SQR_TOOM2_THRESHOLD_MAX is the maximum SQR_TOOM2_THRESHOLD this
+dnl code supports. This value is used only by the tune program to know
+dnl what it can go up to. (An attempt to compile with a bigger value will
+dnl trigger some m4_assert()s in the code, making the build fail.)
+dnl
+dnl The value is determined by requiring the displacements in the unrolled
+dnl addmul to fit in single bytes. This means a maximum UNROLL_COUNT of
+dnl 63, giving a maximum SQR_TOOM2_THRESHOLD of 66.
+
+deflit(SQR_TOOM2_THRESHOLD_MAX, 66)
+
+
+dnl Allow a value from the tune program to override config.m4.
+
+ifdef(`SQR_TOOM2_THRESHOLD_OVERRIDE',
+`define(`SQR_TOOM2_THRESHOLD',SQR_TOOM2_THRESHOLD_OVERRIDE)')
+
+
+dnl UNROLL_COUNT is the number of code chunks in the unrolled addmul. The
+dnl number required is determined by SQR_TOOM2_THRESHOLD, since
+dnl mpn_sqr_basecase only needs to handle sizes < SQR_TOOM2_THRESHOLD.
+dnl
+dnl The first addmul is the biggest, and this takes the second least
+dnl significant limb and multiplies it by the third least significant and
+dnl up. Hence for a maximum operand size of SQR_TOOM2_THRESHOLD-1
+dnl limbs, UNROLL_COUNT needs to be SQR_TOOM2_THRESHOLD-3.
+
+m4_config_gmp_mparam(`SQR_TOOM2_THRESHOLD')
+deflit(UNROLL_COUNT, eval(SQR_TOOM2_THRESHOLD-3))
+
+
+C void mpn_sqr_basecase (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C The algorithm is essentially the same as mpn/generic/sqr_basecase.c, but a
+C lot of function call overheads are avoided, especially when the given size
+C is small.
+C
+C The code size might look a bit excessive, but not all of it is executed
+C and so won't fill up the code cache. The 1x1, 2x2 and 3x3 special cases
+C clearly apply only to those sizes; mid sizes like 10x10 only need part of
+C the unrolled addmul; and big sizes like 35x35 that do need all of it will
+C at least be getting value for money, because 35x35 spends something like
+C 5780 cycles here.
+C
+C Different values of UNROLL_COUNT give slightly different speeds, between
+C 9.0 and 9.2 c/tri-prod measured on the difference between 17 and 33 limbs.
+C This isn't a big difference, but it's presumably some alignment effect
+C which if understood could give a simple speedup.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_sqr_basecase)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %eax
+
+ cmpl $2, %ecx
+ je L(two_limbs)
+
+ movl PARAM_DST, %edx
+ ja L(three_or_more)
+
+
+C -----------------------------------------------------------------------------
+C one limb only
+ C eax src
+ C ebx
+ C ecx size
+ C edx dst
+
+ movl (%eax), %eax
+ movl %edx, %ecx
+
+ mull %eax
+
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(two_limbs):
+ C eax src
+ C ebx
+ C ecx size
+ C edx dst
+
+ pushl %ebx
+ movl %eax, %ebx C src
+deflit(`FRAME',4)
+
+ movl (%ebx), %eax
+ movl PARAM_DST, %ecx
+
+ mull %eax C src[0]^2
+
+ movl %eax, (%ecx)
+ movl 4(%ebx), %eax
+
+ movl %edx, 4(%ecx)
+
+ mull %eax C src[1]^2
+
+ movl %eax, 8(%ecx)
+ movl (%ebx), %eax
+
+ movl %edx, 12(%ecx)
+ movl 4(%ebx), %edx
+
+ mull %edx C src[0]*src[1]
+
+ addl %eax, 4(%ecx)
+
+ adcl %edx, 8(%ecx)
+ adcl $0, 12(%ecx)
+
+ popl %ebx
+ addl %eax, 4(%ecx)
+
+ adcl %edx, 8(%ecx)
+ adcl $0, 12(%ecx)
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(three_or_more):
+deflit(`FRAME',0)
+ cmpl $4, %ecx
+ jae L(four_or_more)
+
+
+C -----------------------------------------------------------------------------
+C three limbs
+ C eax src
+ C ecx size
+ C edx dst
+
+ pushl %ebx
+ movl %eax, %ebx C src
+
+ movl (%ebx), %eax
+ movl %edx, %ecx C dst
+
+ mull %eax C src[0] ^ 2
+
+ movl %eax, (%ecx)
+ movl 4(%ebx), %eax
+
+ movl %edx, 4(%ecx)
+ pushl %esi
+
+ mull %eax C src[1] ^ 2
+
+ movl %eax, 8(%ecx)
+ movl 8(%ebx), %eax
+
+ movl %edx, 12(%ecx)
+ pushl %edi
+
+ mull %eax C src[2] ^ 2
+
+ movl %eax, 16(%ecx)
+ movl (%ebx), %eax
+
+ movl %edx, 20(%ecx)
+ movl 4(%ebx), %edx
+
+ mull %edx C src[0] * src[1]
+
+ movl %eax, %esi
+ movl (%ebx), %eax
+
+ movl %edx, %edi
+ movl 8(%ebx), %edx
+
+ pushl %ebp
+ xorl %ebp, %ebp
+
+ mull %edx C src[0] * src[2]
+
+ addl %eax, %edi
+ movl 4(%ebx), %eax
+
+ adcl %edx, %ebp
+
+ movl 8(%ebx), %edx
+
+ mull %edx C src[1] * src[2]
+
+ addl %eax, %ebp
+
+ adcl $0, %edx
+
+
+ C eax will be dst[5]
+ C ebx
+ C ecx dst
+ C edx dst[4]
+ C esi dst[1]
+ C edi dst[2]
+ C ebp dst[3]
+
+ xorl %eax, %eax
+ addl %esi, %esi
+ adcl %edi, %edi
+ adcl %ebp, %ebp
+ adcl %edx, %edx
+ adcl $0, %eax
+
+ addl %esi, 4(%ecx)
+ adcl %edi, 8(%ecx)
+ adcl %ebp, 12(%ecx)
+
+ popl %ebp
+ popl %edi
+
+ adcl %edx, 16(%ecx)
+
+ popl %esi
+ popl %ebx
+
+ adcl %eax, 20(%ecx)
+ ASSERT(nc)
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+defframe(VAR_COUNTER,-20)
+defframe(VAR_JMP, -24)
+deflit(STACK_SPACE, 24)
+
+ ALIGN(16)
+L(four_or_more):
+
+ C eax src
+ C ebx
+ C ecx size
+ C edx dst
+ C esi
+ C edi
+ C ebp
+
+C First multiply src[0]*src[1..size-1] and store at dst[1..size].
+C
+C A test was done calling mpn_mul_1 here to get the benefit of its unrolled
+C loop, but this was only a tiny speedup; at 35 limbs it took 24 cycles off
+C a 5780 cycle operation, which is not surprising since the loop here is 8
+C c/l and mpn_mul_1 is 6.25 c/l.
+
+ subl $STACK_SPACE, %esp deflit(`FRAME',STACK_SPACE)
+
+ movl %edi, SAVE_EDI
+ leal 4(%edx), %edi
+
+ movl %ebx, SAVE_EBX
+ leal 4(%eax), %ebx
+
+ movl %esi, SAVE_ESI
+ xorl %esi, %esi
+
+ movl %ebp, SAVE_EBP
+
+ C eax
+ C ebx src+4
+ C ecx size
+ C edx
+ C esi
+ C edi dst+4
+ C ebp
+
+ movl (%eax), %ebp C multiplier
+ leal -1(%ecx), %ecx C size-1, and pad to a 16 byte boundary
+
+
+ ALIGN(16)
+L(mul_1):
+ C eax scratch
+ C ebx src ptr
+ C ecx counter
+ C edx scratch
+ C esi carry
+ C edi dst ptr
+ C ebp multiplier
+
+ movl (%ebx), %eax
+ addl $4, %ebx
+
+ mull %ebp
+
+ addl %esi, %eax
+ movl $0, %esi
+
+ adcl %edx, %esi
+
+ movl %eax, (%edi)
+ addl $4, %edi
+
+ loop L(mul_1)
+
+
+C Addmul src[n]*src[n+1..size-1] at dst[2*n-1...], for each n=1..size-2.
+C
+C The last two addmuls, which are the bottom right corner of the product
+C triangle, are left to the end. These are src[size-3]*src[size-2,size-1]
+C and src[size-2]*src[size-1]. If size is 4 then it's only these corner
+C cases that need to be done.
+C
+C The unrolled code is the same as mpn_addmul_1(), see that routine for some
+C comments.
+C
+C VAR_COUNTER is the outer loop, running from -(size-4) to -1, inclusive.
+C
+C VAR_JMP is the computed jump into the unrolled code, stepped by one code
+C chunk each outer loop.
+C
+C K6 doesn't do any branch prediction on indirect jumps, which is good
+C actually because it's a different target each time. The unrolled addmul
+C is about 3 cycles/limb faster than a simple loop, so the 6 cycle cost of
+C the indirect jump is quickly recovered.
+
+
+dnl This value is also implicitly encoded in a shift and add.
+dnl
+deflit(CODE_BYTES_PER_LIMB, 15)
+
+dnl With the unmodified &src[size] and &dst[size] pointers, the
+dnl displacements in the unrolled code fit in a byte for UNROLL_COUNT
+dnl values up to 31. Above that an offset must be added to them.
+dnl
+deflit(OFFSET,
+ifelse(eval(UNROLL_COUNT>31),1,
+eval((UNROLL_COUNT-31)*4),
+0))
+
+ C eax
+ C ebx &src[size]
+ C ecx
+ C edx
+ C esi carry
+ C edi &dst[size]
+ C ebp
+
+ movl PARAM_SIZE, %ecx
+ movl %esi, (%edi)
+
+ subl $4, %ecx
+ jz L(corner)
+
+ movl %ecx, %edx
+ifelse(OFFSET,0,,
+` subl $OFFSET, %ebx')
+
+ shll $4, %ecx
+ifelse(OFFSET,0,,
+` subl $OFFSET, %edi')
+
+ negl %ecx
+
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ leal L(unroll_inner_end)-eval(2*CODE_BYTES_PER_LIMB)(%ecx,%edx), %ecx
+')
+ negl %edx
+
+
+ C The calculated jump mustn't be before the start of the available
+ C code. This is the limitation UNROLL_COUNT puts on the src operand
+ C size, but checked here using the jump address directly.
+ C
+ ASSERT(ae,`
+ movl_text_address( L(unroll_inner_start), %eax)
+ cmpl %eax, %ecx
+ ')
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(unroll_outer_top):
+ C eax
+ C ebx &src[size], constant
+ C ecx VAR_JMP
+ C edx VAR_COUNTER, limbs, negative
+ C esi high limb to store
+ C edi dst ptr, high of last addmul
+ C ebp
+
+ movl -12+OFFSET(%ebx,%edx,4), %ebp C multiplier
+ movl %edx, VAR_COUNTER
+
+ movl -8+OFFSET(%ebx,%edx,4), %eax C first limb of multiplicand
+
+ mull %ebp
+
+ testb $1, %cl
+
+ movl %edx, %esi C high carry
+ movl %ecx, %edx C jump
+
+ movl %eax, %ecx C low carry
+ leal CODE_BYTES_PER_LIMB(%edx), %edx
+
+ movl %edx, VAR_JMP
+ leal 4(%edi), %edi
+
+ C A branch-free version of this using some xors was found to be a
+ C touch slower than just a conditional jump, despite the jump
+ C switching between taken and not taken on every loop.
+
+ifelse(eval(UNROLL_COUNT%2),0,
+ jz,jnz) L(unroll_noswap)
+ movl %esi, %eax C high,low carry other way around
+
+ movl %ecx, %esi
+ movl %eax, %ecx
+L(unroll_noswap):
+
+ jmp *%edx
+
+
+ C Must be on an even address here so the low bit of the jump address
+ C will indicate which way around ecx/esi should start.
+ C
+ C An attempt was made at padding here to get the end of the unrolled
+ C code to come out on a good alignment, to save padding before
+ C L(corner). This worked, but turned out to run slower than just an
+ C ALIGN(2). The reason for this is not clear, it might be related
+ C to the different speeds on different UNROLL_COUNTs noted above.
+
+ ALIGN(2)
+
+L(unroll_inner_start):
+ C eax scratch
+ C ebx src
+ C ecx carry low
+ C edx scratch
+ C esi carry high
+ C edi dst
+ C ebp multiplier
+ C
+ C 15 code bytes each limb
+ C ecx/esi swapped on each chunk
+
+forloop(`i', UNROLL_COUNT, 1, `
+ deflit(`disp_src', eval(-i*4 + OFFSET))
+ deflit(`disp_dst', eval(disp_src - 4))
+
+ m4_assert(`disp_src>=-128 && disp_src<128')
+ m4_assert(`disp_dst>=-128 && disp_dst<128')
+
+ifelse(eval(i%2),0,`
+Zdisp( movl, disp_src,(%ebx), %eax)
+ mull %ebp
+Zdisp( addl, %esi, disp_dst,(%edi))
+ adcl %eax, %ecx
+ movl %edx, %esi
+ jadcl0( %esi)
+',`
+ dnl this one comes out last
+Zdisp( movl, disp_src,(%ebx), %eax)
+ mull %ebp
+Zdisp( addl, %ecx, disp_dst,(%edi))
+ adcl %eax, %esi
+ movl %edx, %ecx
+ jadcl0( %ecx)
+')
+')
+L(unroll_inner_end):
+
+ addl %esi, -4+OFFSET(%edi)
+
+ movl VAR_COUNTER, %edx
+ jadcl0( %ecx)
+
+ movl %ecx, m4_empty_if_zero(OFFSET)(%edi)
+ movl VAR_JMP, %ecx
+
+ incl %edx
+ jnz L(unroll_outer_top)
+
+
+ifelse(OFFSET,0,,`
+ addl $OFFSET, %ebx
+ addl $OFFSET, %edi
+')
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(corner):
+ C ebx &src[size]
+ C edi &dst[2*size-5]
+
+ movl -12(%ebx), %ebp
+
+ movl -8(%ebx), %eax
+ movl %eax, %ecx
+
+ mull %ebp
+
+ addl %eax, -4(%edi)
+ adcl $0, %edx
+
+ movl -4(%ebx), %eax
+ movl %edx, %esi
+ movl %eax, %ebx
+
+ mull %ebp
+
+ addl %esi, %eax
+ adcl $0, %edx
+
+ addl %eax, (%edi)
+ adcl $0, %edx
+
+ movl %edx, %esi
+ movl %ebx, %eax
+
+ mull %ecx
+
+ addl %esi, %eax
+ movl %eax, 4(%edi)
+
+ adcl $0, %edx
+
+ movl %edx, 8(%edi)
+
+
+C -----------------------------------------------------------------------------
+C Left shift of dst[1..2*size-2], the bit shifted out becomes dst[2*size-1].
+C The loop measures about 6 cycles/iteration, though it looks like it should
+C decode in 5.
+
+L(lshift_start):
+ movl PARAM_SIZE, %ecx
+
+ movl PARAM_DST, %edi
+ subl $1, %ecx C size-1 and clear carry
+
+ movl PARAM_SRC, %ebx
+ movl %ecx, %edx
+
+ xorl %eax, %eax C ready for adcl
+
+
+ ALIGN(16)
+L(lshift):
+ C eax
+ C ebx src (for later use)
+ C ecx counter, decrementing
+ C edx size-1 (for later use)
+ C esi
+ C edi dst, incrementing
+ C ebp
+
+ rcll 4(%edi)
+ rcll 8(%edi)
+ leal 8(%edi), %edi
+ loop L(lshift)
+
+
+ adcl %eax, %eax
+
+ movl %eax, 4(%edi) C dst most significant limb
+ movl (%ebx), %eax C src[0]
+
+ leal 4(%ebx,%edx,4), %ebx C &src[size]
+ subl %edx, %ecx C -(size-1)
+
+
+C -----------------------------------------------------------------------------
+C Now add in the squares on the diagonal, src[0]^2, src[1]^2, ...,
+C src[size-1]^2. dst[0] hasn't yet been set at all yet, and just gets the
+C low limb of src[0]^2.
+
+
+ mull %eax
+
+ movl %eax, (%edi,%ecx,8) C dst[0]
+
+
+ ALIGN(16)
+L(diag):
+ C eax scratch
+ C ebx &src[size]
+ C ecx counter, negative
+ C edx carry
+ C esi scratch
+ C edi dst[2*size-2]
+ C ebp
+
+ movl (%ebx,%ecx,4), %eax
+ movl %edx, %esi
+
+ mull %eax
+
+ addl %esi, 4(%edi,%ecx,8)
+ adcl %eax, 8(%edi,%ecx,8)
+ adcl $0, %edx
+
+ incl %ecx
+ jnz L(diag)
+
+
+ movl SAVE_EBX, %ebx
+ movl SAVE_ESI, %esi
+
+ addl %edx, 4(%edi) C dst most significant limb
+
+ movl SAVE_EDI, %edi
+ movl SAVE_EBP, %ebp
+ addl $FRAME, %esp
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ addl (%esp), %ecx
+ addl $L(unroll_inner_end)-L(here)-eval(2*CODE_BYTES_PER_LIMB), %ecx
+ addl %edx, %ecx
+ ret_internal
+')
+
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/README b/gmp/mpn/x86/k7/README
new file mode 100644
index 0000000000..5711b612c5
--- /dev/null
+++ b/gmp/mpn/x86/k7/README
@@ -0,0 +1,174 @@
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+ AMD K7 MPN SUBROUTINES
+
+
+This directory contains code optimized for the AMD Athlon CPU.
+
+The mmx subdirectory has routines using MMX instructions. All Athlons have
+MMX, the separate directory is just so that configure can omit it if the
+assembler doesn't support MMX.
+
+
+
+STATUS
+
+Times for the loops, with all code and data in L1 cache.
+
+ cycles/limb
+ mpn_add/sub_n 1.6
+
+ mpn_copyi 0.75 or 1.0 \ varying with data alignment
+ mpn_copyd 0.75 or 1.0 /
+
+ mpn_divrem_1 17.0 integer part, 15.0 fractional part
+ mpn_mod_1 17.0
+ mpn_divexact_by3 8.0
+
+ mpn_l/rshift 1.2
+
+ mpn_mul_1 3.4
+ mpn_addmul/submul_1 3.9
+
+ mpn_mul_basecase 4.42 cycles/crossproduct (approx)
+ mpn_sqr_basecase 2.3 cycles/crossproduct (approx)
+ or 4.55 cycles/triangleproduct (approx)
+
+Prefetching of sources hasn't yet been tried.
+
+
+
+NOTES
+
+cmov, MMX, 3DNow and some extensions to MMX and 3DNow are available.
+
+Write-allocate L1 data cache means prefetching of destinations is unnecessary.
+
+Floating point multiplications can be done in parallel with integer
+multiplications, but there doesn't seem to be any way to make use of this.
+
+Unsigned "mul"s can be issued every 3 cycles. This suggests 3 is a limit on
+the speed of the multiplication routines. The documentation shows mul
+executing in IEU0 (or maybe in IEU0 and IEU1 together), so it might be that,
+to get near 3 cycles code has to be arranged so that nothing else is issued
+to IEU0. A busy IEU0 could explain why some code takes 4 cycles and other
+apparently equivalent code takes 5.
+
+
+
+OPTIMIZATIONS
+
+Unrolled loops are used to reduce looping overhead. The unrolling is
+configurable up to 32 limbs/loop for most routines and up to 64 for some.
+The K7 has 64k L1 code cache so quite big unrolling is allowable.
+
+Computed jumps into the unrolling are used to handle sizes not a multiple of
+the unrolling. An attractive feature of this is that times increase
+smoothly with operand size, but it may be that some routines should just
+have simple loops to finish up, especially when PIC adds between 2 and 16
+cycles to get %eip.
+
+Position independent code is implemented using a call to get %eip for the
+computed jumps and a ret is always done, rather than an addl $4,%esp or a
+popl, so the CPU return address branch prediction stack stays synchronised
+with the actual stack in memory.
+
+Branch prediction, in absence of any history, will guess forward jumps are
+not taken and backward jumps are taken. Where possible it's arranged that
+the less likely or less important case is under a taken forward jump.
+
+
+
+CODING
+
+Instructions in general code have been shown grouped if they can execute
+together, which means up to three direct-path instructions which have no
+successive dependencies. K7 always decodes three and has out-of-order
+execution, but the groupings show what slots might be available and what
+dependency chains exist.
+
+When there's vector-path instructions an effort is made to get triplets of
+direct-path instructions in between them, even if there's dependencies,
+since this maximizes decoding throughput and might save a cycle or two if
+decoding is the limiting factor.
+
+
+
+INSTRUCTIONS
+
+adcl direct
+divl 39 cycles back-to-back
+lodsl,etc vector
+loop 1 cycle vector (decl/jnz opens up one decode slot)
+movd reg vector
+movd mem direct
+mull issue every 3 cycles, latency 4 cycles low word, 6 cycles high word
+popl vector (use movl for more than one pop)
+pushl direct, will pair with a load
+shrdl %cl vector, 3 cycles, seems to be 3 decode too
+xorl r,r false read dependency recognised
+
+
+
+REFERENCES
+
+"AMD Athlon Processor X86 Code Optimization Guide", AMD publication number
+22007, revision K, February 2002. Available on-line,
+
+http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22007.pdf
+
+"3DNow Technology Manual", AMD publication number 21928G/0-March 2000.
+This describes the femms and prefetch instructions. Available on-line,
+
+http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21928.pdf
+
+"AMD Extensions to the 3DNow and MMX Instruction Sets Manual", AMD
+publication number 22466, revision D, March 2000. This describes
+instructions added in the Athlon processor, such as pswapd and the extra
+prefetch forms. Available on-line,
+
+http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22466.pdf
+
+"3DNow Instruction Porting Guide", AMD publication number 22621, revision B,
+August 1999. This has some notes on general Athlon optimizations as well as
+3DNow. Available on-line,
+
+http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22621.pdf
+
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/x86/k7/addlsh1_n.asm b/gmp/mpn/x86/k7/addlsh1_n.asm
new file mode 100644
index 0000000000..a957b6f78e
--- /dev/null
+++ b/gmp/mpn/x86/k7/addlsh1_n.asm
@@ -0,0 +1,196 @@
+dnl AMD K7 mpn_addlsh1_n -- rp[] = up[] + (vp[] << 1)
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C This is an attempt at an addlsh1_n for x86-32, not relying on sse2 insns.
+C The innerloop is 2*3-way unrolled, which is best we can do with the available
+C registers. It seems tricky to use the same structure for rsblsh1_n, since we
+C cannot feed carry between operations there.
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan) 5.4 (worse than add_n + lshift)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 6
+C AMD K6 ?
+C AMD K7 2.5
+C AMD K8
+
+C This is a basic addlsh1_n for k7, atom, and perhaps some other x86-32
+C processors. It uses 2*3-way unrolling, for good reasons. Unfortunately,
+C that means we need an initial magic multiply.
+C
+C It is not clear how to do sublsh1_n or rsblsh1_n using the same pattern. We
+C cannot do rsblsh1_n since we feed carry from the shift blocks to the
+C add/subtract blocks, which is right for addition but reversed for
+C subtraction. We could perhaps do sublsh1_n, with some extra move insns,
+C without losing any time, since we're not issue limited but carry recurrency
+C latency.
+C
+C Breaking carry recurrency might be a good idea. We would then need separate
+C registers for the shift carry and add/subtract carry, which in turn would
+C force is to 2*2-way unrolling.
+
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_DBLD, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(VAR_COUNT,`PARAM_DST')
+define(VAR_TMP,`PARAM_DBLD')
+
+ASM_START()
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_addlsh1_n)
+deflit(`FRAME',0)
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`vp', `%ebp')
+
+ mov $0x2aaaaaab, %eax
+
+ push %ebx FRAME_pushl()
+ mov PARAM_SIZE, %ebx C size
+
+ push rp FRAME_pushl()
+ mov PARAM_DST, rp
+
+ mul %ebx
+
+ push up FRAME_pushl()
+ mov PARAM_SRC, up
+
+ not %edx C count = -(size\8)-1
+ mov %edx, VAR_COUNT
+
+ push vp FRAME_pushl()
+ mov PARAM_DBLD, vp
+
+ lea 3(%edx,%edx,2), %ecx C count*3+3 = -(size\6)*3
+ xor %edx, %edx
+ lea (%ebx,%ecx,2), %ebx C size + (count*3+3)*2 = size % 6
+ or %ebx, %ebx
+ jz L(exact)
+
+L(oop):
+ifdef(`CPU_P6',`
+ shr %edx ') C restore 2nd saved carry bit
+ mov (vp), %eax
+ adc %eax, %eax
+ rcr %edx C restore 1st saved carry bit
+ lea 4(vp), vp
+ adc (up), %eax
+ lea 4(up), up
+ adc %edx, %edx C save a carry bit in edx
+ifdef(`CPU_P6',`
+ adc %edx, %edx ') C save another carry bit in edx
+ dec %ebx
+ mov %eax, (rp)
+ lea 4(rp), rp
+ jnz L(oop)
+ mov vp, VAR_TMP
+L(exact):
+ incl VAR_COUNT
+ jz L(end)
+
+ ALIGN(16)
+L(top):
+ifdef(`CPU_P6',`
+ shr %edx ') C restore 2nd saved carry bit
+ mov (vp), %eax
+ adc %eax, %eax
+ mov 4(vp), %ebx
+ adc %ebx, %ebx
+ mov 8(vp), %ecx
+ adc %ecx, %ecx
+
+ rcr %edx C restore 1st saved carry bit
+
+ adc (up), %eax
+ mov %eax, (rp)
+ adc 4(up), %ebx
+ mov %ebx, 4(rp)
+ adc 8(up), %ecx
+ mov %ecx, 8(rp)
+
+ mov 12(vp), %eax
+ adc %eax, %eax
+ mov 16(vp), %ebx
+ adc %ebx, %ebx
+ mov 20(vp), %ecx
+ adc %ecx, %ecx
+
+ lea 24(vp), vp
+ adc %edx, %edx C save a carry bit in edx
+
+ adc 12(up), %eax
+ mov %eax, 12(rp)
+ adc 16(up), %ebx
+ mov %ebx, 16(rp)
+ adc 20(up), %ecx
+
+ lea 24(up), up
+
+ifdef(`CPU_P6',`
+ adc %edx, %edx ') C save another carry bit in edx
+ mov %ecx, 20(rp)
+ incl VAR_COUNT
+ lea 24(rp), rp
+ jne L(top)
+
+L(end):
+ pop vp FRAME_popl()
+ pop up FRAME_popl()
+
+ifdef(`CPU_P6',`
+ xor %eax, %eax
+ shr $1, %edx
+ adc %edx, %eax
+',`
+ adc $0, %edx
+ mov %edx, %eax
+')
+ pop rp FRAME_popl()
+ pop %ebx FRAME_popl()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/k7/aors_n.asm b/gmp/mpn/x86/k7/aors_n.asm
new file mode 100644
index 0000000000..1a08072029
--- /dev/null
+++ b/gmp/mpn/x86/k7/aors_n.asm
@@ -0,0 +1,258 @@
+dnl AMD K7 mpn_add_n/mpn_sub_n -- mpn add or subtract.
+
+dnl Copyright 1999-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K7: 1.64 cycles/limb (at 16 limbs/loop).
+
+
+
+dnl K7: UNROLL_COUNT cycles/limb
+dnl 8 1.9
+dnl 16 1.64
+dnl 32 1.7
+dnl 64 2.0
+dnl Maximum possible with the current code is 64.
+
+deflit(UNROLL_COUNT, 16)
+
+
+ifdef(`OPERATION_add_n', `
+ define(M4_inst, adcl)
+ define(M4_function_n, mpn_add_n)
+ define(M4_function_nc, mpn_add_nc)
+ define(M4_description, add)
+',`ifdef(`OPERATION_sub_n', `
+ define(M4_inst, sbbl)
+ define(M4_function_n, mpn_sub_n)
+ define(M4_function_nc, mpn_sub_nc)
+ define(M4_description, subtract)
+',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
+')')')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+
+C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size);
+C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size, mp_limb_t carry);
+C
+C Calculate src1,size M4_description src2,size, and store the result in
+C dst,size. The return value is the carry bit from the top of the result (1
+C or 0).
+C
+C The _nc version accepts 1 or 0 for an initial carry into the low limb of
+C the calculation. Note values other than 1 or 0 here will lead to garbage
+C results.
+C
+C This code runs at 1.64 cycles/limb, which might be the best possible with
+C plain integer operations. Each limb is 2 loads and 1 store, any 2 of
+C which can be done each cycle, leading to 1.5 c/l.
+
+dnl Must have UNROLL_THRESHOLD >= 2, since the unrolled loop can't handle 1.
+ifdef(`PIC',`
+deflit(UNROLL_THRESHOLD, 8)
+',`
+deflit(UNROLL_THRESHOLD, 8)
+')
+
+defframe(PARAM_CARRY,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC2, 12)
+defframe(PARAM_SRC1, 8)
+defframe(PARAM_DST, 4)
+
+defframe(SAVE_EBP, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EBX, -12)
+defframe(SAVE_EDI, -16)
+deflit(STACK_SPACE, 16)
+
+ TEXT
+ ALIGN(32)
+deflit(`FRAME',0)
+
+PROLOGUE(M4_function_nc)
+ movl PARAM_CARRY, %eax
+ jmp L(start)
+EPILOGUE()
+
+PROLOGUE(M4_function_n)
+
+ xorl %eax, %eax C carry
+L(start):
+ movl PARAM_SIZE, %ecx
+ subl $STACK_SPACE, %esp
+deflit(`FRAME',STACK_SPACE)
+
+ movl %edi, SAVE_EDI
+ movl %ebx, SAVE_EBX
+ cmpl $UNROLL_THRESHOLD, %ecx
+
+ movl PARAM_SRC2, %edx
+ movl PARAM_SRC1, %ebx
+ jae L(unroll)
+
+ movl PARAM_DST, %edi
+ leal (%ebx,%ecx,4), %ebx
+ leal (%edx,%ecx,4), %edx
+
+ leal (%edi,%ecx,4), %edi
+ negl %ecx
+ shrl %eax
+
+ C This loop in in a single 16 byte code block already, so no
+ C alignment necessary.
+L(simple):
+ C eax scratch
+ C ebx src1
+ C ecx counter
+ C edx src2
+ C esi
+ C edi dst
+ C ebp
+
+ movl (%ebx,%ecx,4), %eax
+ M4_inst (%edx,%ecx,4), %eax
+ movl %eax, (%edi,%ecx,4)
+ incl %ecx
+ jnz L(simple)
+
+ movl $0, %eax
+ movl SAVE_EDI, %edi
+
+ movl SAVE_EBX, %ebx
+ setc %al
+ addl $STACK_SPACE, %esp
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ C This is at 0x55, close enough to aligned.
+L(unroll):
+deflit(`FRAME',STACK_SPACE)
+ movl %ebp, SAVE_EBP
+ andl $-2, %ecx C size low bit masked out
+ andl $1, PARAM_SIZE C size low bit kept
+
+ movl %ecx, %edi
+ decl %ecx
+ movl PARAM_DST, %ebp
+
+ shrl $UNROLL_LOG2, %ecx
+ negl %edi
+ movl %esi, SAVE_ESI
+
+ andl $UNROLL_MASK, %edi
+
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ leal L(entry) (%edi,%edi,8), %esi C 9 bytes per
+')
+ negl %edi
+ shrl %eax
+
+ leal ifelse(UNROLL_BYTES,256,128) (%ebx,%edi,4), %ebx
+ leal ifelse(UNROLL_BYTES,256,128) (%edx,%edi,4), %edx
+ leal ifelse(UNROLL_BYTES,256,128) (%ebp,%edi,4), %edi
+
+ jmp *%esi
+
+
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ leal (%edi,%edi,8), %esi
+ addl $L(entry)-L(here), %esi
+ addl (%esp), %esi
+ ret_internal
+')
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(32)
+L(top):
+ C eax zero
+ C ebx src1
+ C ecx counter
+ C edx src2
+ C esi scratch (was computed jump)
+ C edi dst
+ C ebp scratch
+
+ leal UNROLL_BYTES(%edx), %edx
+
+L(entry):
+deflit(CHUNK_COUNT, 2)
+forloop(i, 0, UNROLL_COUNT/CHUNK_COUNT-1, `
+ deflit(`disp0', eval(i*CHUNK_COUNT*4 ifelse(UNROLL_BYTES,256,-128)))
+ deflit(`disp1', eval(disp0 + 4))
+
+Zdisp( movl, disp0,(%ebx), %esi)
+ movl disp1(%ebx), %ebp
+Zdisp( M4_inst,disp0,(%edx), %esi)
+Zdisp( movl, %esi, disp0,(%edi))
+ M4_inst disp1(%edx), %ebp
+ movl %ebp, disp1(%edi)
+')
+
+ decl %ecx
+ leal UNROLL_BYTES(%ebx), %ebx
+ leal UNROLL_BYTES(%edi), %edi
+ jns L(top)
+
+
+ mov PARAM_SIZE, %esi
+ movl SAVE_EBP, %ebp
+ movl $0, %eax
+
+ decl %esi
+ js L(even)
+
+ movl (%ebx), %ecx
+ M4_inst UNROLL_BYTES(%edx), %ecx
+ movl %ecx, (%edi)
+L(even):
+
+ movl SAVE_EDI, %edi
+ movl SAVE_EBX, %ebx
+ setc %al
+
+ movl SAVE_ESI, %esi
+ addl $STACK_SPACE, %esp
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/aorsmul_1.asm b/gmp/mpn/x86/k7/aorsmul_1.asm
new file mode 100644
index 0000000000..eec8df6de2
--- /dev/null
+++ b/gmp/mpn/x86/k7/aorsmul_1.asm
@@ -0,0 +1,167 @@
+dnl AMD K7 mpn_addmul_1/mpn_submul_1 -- add or subtract mpn multiple.
+
+dnl Copyright 1999-2002, 2005, 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias) 6.5
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C AMD K6
+C AMD K7 3.75
+C AMD K8
+
+C TODO
+C * Improve feed-in and wind-down code. We beat the old code for all n != 1,
+C but lose by 2x for n == 1.
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`func', `mpn_submul_1')
+')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ add $-16, %esp
+ mov %ebp, (%esp)
+ mov %ebx, 4(%esp)
+ mov %esi, 8(%esp)
+ mov %edi, 12(%esp)
+
+ mov 20(%esp), %edi
+ mov 24(%esp), %esi
+ mov 28(%esp), %eax
+ mov 32(%esp), %ecx
+ mov %eax, %ebx
+ shr $2, %eax
+ mov %eax, 28(%esp)
+ mov (%esi), %eax
+ and $3, %ebx
+ jz L(b0)
+ cmp $2, %ebx
+ jz L(b2)
+ jg L(b3)
+
+L(b1): lea -4(%esi), %esi
+ lea -4(%edi), %edi
+ mul %ecx
+ mov %eax, %ebx
+ mov %edx, %ebp
+ cmpl $0, 28(%esp)
+ jz L(cj1)
+ mov 8(%esi), %eax
+ jmp L(1)
+
+L(b2): mul %ecx
+ mov %eax, %ebp
+ mov 4(%esi), %eax
+ mov %edx, %ebx
+ cmpl $0, 28(%esp)
+ jne L(2)
+ jmp L(cj2)
+
+L(b3): lea -12(%esi), %esi
+ lea -12(%edi), %edi
+ mul %ecx
+ mov %eax, %ebx
+ mov %edx, %ebp
+ mov 16(%esi), %eax
+ incl 28(%esp)
+ jmp L(3)
+
+L(b0): lea -8(%esi), %esi
+ lea -8(%edi), %edi
+ mul %ecx
+ mov %eax, %ebp
+ mov 12(%esi), %eax
+ mov %edx, %ebx
+ jmp L(0)
+
+ ALIGN(16)
+L(top): lea 16(%edi), %edi
+L(2): mul %ecx
+ ADDSUB %ebp, 0(%edi)
+ mov $0, %ebp
+ adc %eax, %ebx
+ mov 8(%esi), %eax
+ adc %edx, %ebp
+L(1): mul %ecx
+ ADDSUB %ebx, 4(%edi)
+ mov $0, %ebx
+ adc %eax, %ebp
+ mov 12(%esi), %eax
+ adc %edx, %ebx
+L(0): mul %ecx
+ ADDSUB %ebp, 8(%edi)
+ mov $0, %ebp
+ adc %eax, %ebx
+ adc %edx, %ebp
+ mov 16(%esi), %eax
+L(3): mul %ecx
+ ADDSUB %ebx, 12(%edi)
+ adc %eax, %ebp
+ mov 20(%esi), %eax
+ lea 16(%esi), %esi
+ mov $0, %ebx
+ adc %edx, %ebx
+ decl 28(%esp)
+ jnz L(top)
+
+L(end): lea 16(%edi), %edi
+L(cj2): mul %ecx
+ ADDSUB %ebp, (%edi)
+ adc %eax, %ebx
+ adc $0, %edx
+L(cj1): ADDSUB %ebx, 4(%edi)
+ adc $0, %edx
+ mov %edx, %eax
+ mov (%esp), %ebp
+ mov 4(%esp), %ebx
+ mov 8(%esp), %esi
+ mov 12(%esp), %edi
+ add $16, %esp
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/k7/bdiv_q_1.asm b/gmp/mpn/x86/k7/bdiv_q_1.asm
new file mode 100644
index 0000000000..df3477f539
--- /dev/null
+++ b/gmp/mpn/x86/k7/bdiv_q_1.asm
@@ -0,0 +1,244 @@
+dnl AMD K7 mpn_bdiv_q_1 -- mpn by limb exact division.
+
+dnl Rearranged from mpn/x86/k7/dive_1.asm by Marco Bodrato.
+
+dnl Copyright 2001, 2002, 2004, 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C Athlon: 11.0
+C Hammer: 9.0
+
+
+C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+C The dependent chain is mul+imul+sub for 11 cycles and that speed is
+C achieved with no special effort. The load and shrld latencies are hidden
+C by out of order execution.
+C
+C It's a touch faster on size==1 to use the mul-by-inverse than divl.
+
+defframe(PARAM_SHIFT, 24)
+defframe(PARAM_INVERSE,20)
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+defframe(VAR_INVERSE, -20)
+defframe(VAR_DST_END, -24)
+
+deflit(STACK_SPACE, 24)
+
+ TEXT
+
+C mp_limb_t
+C mpn_pi1_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor,
+C mp_limb_t inverse, int shift)
+ ALIGN(16)
+PROLOGUE(mpn_pi1_bdiv_q_1)
+deflit(`FRAME',0)
+
+ subl $STACK_SPACE, %esp deflit(`FRAME',STACK_SPACE)
+ movl PARAM_SHIFT, %ecx C shift count
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_SIZE, %ebp
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ movl %ebx, SAVE_EBX
+
+ leal (%esi,%ebp,4), %esi C src end
+ leal (%edi,%ebp,4), %edi C dst end
+ negl %ebp C -size
+
+ movl PARAM_INVERSE, %eax C inv
+
+L(common):
+ movl %eax, VAR_INVERSE
+ movl (%esi,%ebp,4), %eax C src[0]
+
+ incl %ebp
+ jz L(one)
+
+ movl (%esi,%ebp,4), %edx C src[1]
+
+ shrdl( %cl, %edx, %eax)
+
+ movl %edi, VAR_DST_END
+ xorl %ebx, %ebx
+ jmp L(entry)
+
+ ALIGN(8)
+L(top):
+ C eax q
+ C ebx carry bit, 0 or 1
+ C ecx shift
+ C edx
+ C esi src end
+ C edi dst end
+ C ebp counter, limbs, negative
+
+ mull PARAM_DIVISOR C carry limb in edx
+
+ movl -4(%esi,%ebp,4), %eax
+ movl (%esi,%ebp,4), %edi
+
+ shrdl( %cl, %edi, %eax)
+
+ subl %ebx, %eax C apply carry bit
+ setc %bl
+ movl VAR_DST_END, %edi
+
+ subl %edx, %eax C apply carry limb
+ adcl $0, %ebx
+
+L(entry):
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi,%ebp,4)
+ incl %ebp
+ jnz L(top)
+
+
+ mull PARAM_DIVISOR C carry limb in edx
+
+ movl -4(%esi), %eax C src high limb
+ shrl %cl, %eax
+ movl SAVE_ESI, %esi
+
+ subl %ebx, %eax C apply carry bit
+ movl SAVE_EBX, %ebx
+ movl SAVE_EBP, %ebp
+
+ subl %edx, %eax C apply carry limb
+
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi)
+ movl SAVE_EDI, %edi
+ addl $STACK_SPACE, %esp
+
+ ret
+
+L(one):
+ shrl %cl, %eax
+ movl SAVE_ESI, %esi
+ movl SAVE_EBX, %ebx
+
+ imull VAR_INVERSE, %eax
+
+ movl SAVE_EBP, %ebp
+
+ movl %eax, -4(%edi)
+ movl SAVE_EDI, %edi
+ addl $STACK_SPACE, %esp
+
+ ret
+EPILOGUE()
+
+C mp_limb_t mpn_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+
+ ALIGN(16)
+PROLOGUE(mpn_bdiv_q_1)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %eax
+ subl $STACK_SPACE, %esp deflit(`FRAME',STACK_SPACE)
+ movl $-1, %ecx C shift count
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_SIZE, %ebp
+
+ movl %esi, SAVE_ESI
+ movl %edi, SAVE_EDI
+
+ C If there's usually only one or two trailing zero bits then this
+ C should be faster than bsfl.
+L(strip_twos):
+ incl %ecx
+ shrl %eax
+ jnc L(strip_twos)
+
+ movl %ebx, SAVE_EBX
+ leal 1(%eax,%eax), %ebx C d without twos
+ andl $127, %eax C d/2, 7 bits
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %edx)
+ movzbl (%eax,%edx), %eax C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+
+ leal (%eax,%eax), %edx C 2*inv
+ movl %ebx, PARAM_DIVISOR C d without twos
+
+ imull %eax, %eax C inv*inv
+
+ movl PARAM_SRC, %esi
+ movl PARAM_DST, %edi
+
+ imull %ebx, %eax C inv*inv*d
+
+ subl %eax, %edx C inv = 2*inv - inv*inv*d
+ leal (%edx,%edx), %eax C 2*inv
+
+ imull %edx, %edx C inv*inv
+
+ leal (%esi,%ebp,4), %esi C src end
+ leal (%edi,%ebp,4), %edi C dst end
+ negl %ebp C -size
+
+ imull %ebx, %edx C inv*inv*d
+
+ subl %edx, %eax C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ imull PARAM_DIVISOR, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ jmp L(common)
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/dive_1.asm b/gmp/mpn/x86/k7/dive_1.asm
new file mode 100644
index 0000000000..8eb4f45ac0
--- /dev/null
+++ b/gmp/mpn/x86/k7/dive_1.asm
@@ -0,0 +1,207 @@
+dnl AMD K7 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2001, 2002, 2004, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C Athlon: 11.0
+C Hammer: 9.0
+
+
+C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+C The dependent chain is mul+imul+sub for 11 cycles and that speed is
+C achieved with no special effort. The load and shrld latencies are hidden
+C by out of order execution.
+C
+C It's a touch faster on size==1 to use the mul-by-inverse than divl.
+
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+defframe(VAR_INVERSE, -20)
+defframe(VAR_DST_END, -24)
+
+deflit(STACK_SPACE, 24)
+
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(mpn_divexact_1)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %eax
+ subl $STACK_SPACE, %esp deflit(`FRAME',STACK_SPACE)
+ movl $-1, %ecx C shift count
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_SIZE, %ebp
+
+ movl %esi, SAVE_ESI
+ movl %edi, SAVE_EDI
+
+ C If there's usually only one or two trailing zero bits then this
+ C should be faster than bsfl.
+L(strip_twos):
+ incl %ecx
+ shrl %eax
+ jnc L(strip_twos)
+
+ movl %ebx, SAVE_EBX
+ leal 1(%eax,%eax), %ebx C d without twos
+ andl $127, %eax C d/2, 7 bits
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %edx)
+ movzbl (%eax,%edx), %eax C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+
+ leal (%eax,%eax), %edx C 2*inv
+ movl %ebx, PARAM_DIVISOR C d without twos
+
+ imull %eax, %eax C inv*inv
+
+ movl PARAM_SRC, %esi
+ movl PARAM_DST, %edi
+
+ imull %ebx, %eax C inv*inv*d
+
+ subl %eax, %edx C inv = 2*inv - inv*inv*d
+ leal (%edx,%edx), %eax C 2*inv
+
+ imull %edx, %edx C inv*inv
+
+ leal (%esi,%ebp,4), %esi C src end
+ leal (%edi,%ebp,4), %edi C dst end
+ negl %ebp C -size
+
+ imull %ebx, %edx C inv*inv*d
+
+ subl %edx, %eax C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ imull PARAM_DIVISOR, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ movl %eax, VAR_INVERSE
+ movl (%esi,%ebp,4), %eax C src[0]
+
+ incl %ebp
+ jz L(one)
+
+ movl (%esi,%ebp,4), %edx C src[1]
+
+ shrdl( %cl, %edx, %eax)
+
+ movl %edi, VAR_DST_END
+ xorl %ebx, %ebx
+ jmp L(entry)
+
+ ALIGN(8)
+L(top):
+ C eax q
+ C ebx carry bit, 0 or 1
+ C ecx shift
+ C edx
+ C esi src end
+ C edi dst end
+ C ebp counter, limbs, negative
+
+ mull PARAM_DIVISOR C carry limb in edx
+
+ movl -4(%esi,%ebp,4), %eax
+ movl (%esi,%ebp,4), %edi
+
+ shrdl( %cl, %edi, %eax)
+
+ subl %ebx, %eax C apply carry bit
+ setc %bl
+ movl VAR_DST_END, %edi
+
+ subl %edx, %eax C apply carry limb
+ adcl $0, %ebx
+
+L(entry):
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi,%ebp,4)
+ incl %ebp
+ jnz L(top)
+
+
+ mull PARAM_DIVISOR C carry limb in edx
+
+ movl -4(%esi), %eax C src high limb
+ shrl %cl, %eax
+ movl SAVE_ESI, %esi
+
+ subl %ebx, %eax C apply carry bit
+ movl SAVE_EBX, %ebx
+ movl SAVE_EBP, %ebp
+
+ subl %edx, %eax C apply carry limb
+
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi)
+ movl SAVE_EDI, %edi
+ addl $STACK_SPACE, %esp
+
+ ret
+
+
+L(one):
+ shrl %cl, %eax
+ movl SAVE_ESI, %esi
+ movl SAVE_EBX, %ebx
+
+ imull VAR_INVERSE, %eax
+
+ movl SAVE_EBP, %ebp
+ movl %eax, -4(%edi)
+
+ movl SAVE_EDI, %edi
+ addl $STACK_SPACE, %esp
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/gcd_1.asm b/gmp/mpn/x86/k7/gcd_1.asm
new file mode 100644
index 0000000000..c7d12c83c0
--- /dev/null
+++ b/gmp/mpn/x86/k7/gcd_1.asm
@@ -0,0 +1,186 @@
+dnl x86 mpn_gcd_1 optimised for AMD K7.
+
+dnl Contributed to the GNU project by by Kevin Ryde. Rehacked by Torbjorn
+dnl Granlund.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/bit (approx)
+C AMD K7 5.31
+C AMD K8,K9 5.33
+C AMD K10 5.30
+C AMD bd1 ?
+C AMD bobcat 7.02
+C Intel P4-2 10.1
+C Intel P4-3/4 10.0
+C Intel P6/13 5.88
+C Intel core2 6.26
+C Intel NHM 6.83
+C Intel SBR 8.50
+C Intel atom 8.90
+C VIA nano ?
+C Numbers measured with: speed -CD -s16-32 -t16 mpn_gcd_1
+
+C TODO
+C * Tune overhead, this takes 2-3 cycles more than old code when v0 is tiny.
+C * Stream things better through registers, avoiding some copying.
+
+C ctz_table[n] is the number of trailing zeros on n, or MAXSHIFT if n==0.
+
+deflit(MAXSHIFT, 6)
+deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))
+
+DEF_OBJECT(ctz_table,64)
+ .byte MAXSHIFT
+forloop(i,1,MASK,
+` .byte m4_count_trailing_zeros(i)
+')
+END_OBJECT(ctz_table)
+
+C Threshold of when to call bmod when U is one limb. Should be about
+C (time_in_cycles(bmod_1,1) + call_overhead) / (cycles/bit).
+define(`DIV_THRES_LOG2', 7)
+
+
+define(`up', `%edi')
+define(`n', `%esi')
+define(`v0', `%edx')
+
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_gcd_1)
+ push %edi
+ push %esi
+
+ mov 12(%esp), up
+ mov 16(%esp), n
+ mov 20(%esp), v0
+
+ mov (up), %eax C U low limb
+ or v0, %eax C x | y
+ mov $-1, %ecx
+
+L(twos):
+ inc %ecx
+ shr %eax
+ jnc L(twos)
+
+ shr %cl, v0
+ mov %ecx, %eax C common twos
+
+L(divide_strip_y):
+ shr v0
+ jnc L(divide_strip_y)
+ adc v0, v0
+
+ push %eax
+ push v0
+
+ cmp $1, n
+ jnz L(reduce_nby1)
+
+C Both U and V are single limbs, reduce with bmod if u0 >> v0.
+ mov (up), %ecx
+ mov %ecx, %eax
+ shr $DIV_THRES_LOG2, %ecx
+ cmp %ecx, v0
+ ja L(reduced)
+
+ mov v0, %esi
+ xor %edx, %edx
+ div %esi
+ mov %edx, %eax
+ jmp L(reduced)
+
+L(reduce_nby1):
+ifdef(`PIC_WITH_EBX',`
+ push %ebx
+ call L(movl_eip_to_ebx)
+ add $_GLOBAL_OFFSET_TABLE_, %ebx
+')
+ push v0 C param 3
+ push n C param 2
+ push up C param 1
+ cmp $BMOD_1_TO_MOD_1_THRESHOLD, n
+ jl L(bmod)
+ CALL( mpn_mod_1)
+ jmp L(called)
+L(bmod):
+ CALL( mpn_modexact_1_odd)
+
+L(called):
+ add $12, %esp C deallocate params
+ifdef(`PIC_WITH_EBX',`
+ pop %ebx
+')
+L(reduced):
+ pop %edx
+
+ LEA( ctz_table, %esi)
+ test %eax, %eax
+ mov %eax, %ecx
+ jnz L(mid)
+ jmp L(end)
+
+ ALIGN(16) C K8 BC P4 NHM SBR
+L(top): cmovc( %ecx, %eax) C if x-y < 0 0
+ cmovc( %edi, %edx) C use x,y-x 0
+L(mid): and $MASK, %ecx C 0
+ movzbl (%esi,%ecx), %ecx C 1
+ jz L(shift_alot) C 1
+ shr %cl, %eax C 3
+ mov %eax, %edi C 4
+ mov %edx, %ecx C 3
+ sub %eax, %ecx C 4
+ sub %edx, %eax C 4
+ jnz L(top) C 5
+
+L(end): pop %ecx
+ mov %edx, %eax
+ shl %cl, %eax
+ pop %esi
+ pop %edi
+ ret
+
+L(shift_alot):
+ shr $MAXSHIFT, %eax
+ mov %eax, %ecx
+ jmp L(mid)
+
+ifdef(`PIC_WITH_EBX',`
+L(movl_eip_to_ebx):
+ mov (%esp), %ebx
+ ret
+')
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/gmp-mparam.h b/gmp/mpn/x86/k7/gmp-mparam.h
new file mode 100644
index 0000000000..9977a113e2
--- /dev/null
+++ b/gmp/mpn/x86/k7/gmp-mparam.h
@@ -0,0 +1,241 @@
+/* AMD K7 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2005, 2008-2010, 2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 2083 MHz K7 Barton */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-13, gcc 4.2 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 3
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 24
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 10
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 3
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 24
+
+#define MUL_TOOM22_THRESHOLD 28
+#define MUL_TOOM33_THRESHOLD 85
+#define MUL_TOOM44_THRESHOLD 147
+#define MUL_TOOM6H_THRESHOLD 216
+#define MUL_TOOM8H_THRESHOLD 309
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 85
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 99
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 98
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 102
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 124
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 50
+#define SQR_TOOM3_THRESHOLD 81
+#define SQR_TOOM4_THRESHOLD 216
+#define SQR_TOOM6_THRESHOLD 306
+#define SQR_TOOM8_THRESHOLD 446
+
+#define MULMID_TOOM42_THRESHOLD 56
+
+#define MULMOD_BNM1_THRESHOLD 17
+#define SQRMOD_BNM1_THRESHOLD 17
+
+#define MUL_FFT_MODF_THRESHOLD 904 /* k = 6 */
+#define MUL_FFT_TABLE3 \
+ { { 904, 6}, { 21, 7}, { 11, 6}, { 25, 7}, \
+ { 13, 6}, { 27, 7}, { 15, 6}, { 31, 7}, \
+ { 17, 6}, { 35, 7}, { 19, 6}, { 39, 7}, \
+ { 23, 6}, { 47, 7}, { 27, 8}, { 15, 7}, \
+ { 31, 6}, { 63, 7}, { 35, 8}, { 19, 7}, \
+ { 39, 8}, { 23, 7}, { 47, 8}, { 31, 7}, \
+ { 63, 8}, { 39, 7}, { 79, 9}, { 23, 8}, \
+ { 47, 7}, { 95, 8}, { 51, 9}, { 31, 8}, \
+ { 71, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
+ { 95, 9}, { 55,10}, { 31, 9}, { 63, 8}, \
+ { 127, 9}, { 71, 8}, { 143, 9}, { 79, 8}, \
+ { 159,10}, { 47, 9}, { 95, 8}, { 191, 9}, \
+ { 103,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 9}, { 143,10}, { 79, 9}, { 167,10}, \
+ { 95, 9}, { 199,10}, { 111,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 143, 9}, { 287,10}, \
+ { 159, 9}, { 319,11}, { 95,10}, { 191, 9}, \
+ { 383,10}, { 207,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271, 8}, { 1087,10}, \
+ { 287,11}, { 159,10}, { 319, 9}, { 639,11}, \
+ { 191,10}, { 383, 9}, { 767, 8}, { 1535, 9}, \
+ { 799, 8}, { 1599,11}, { 223,12}, { 127,11}, \
+ { 255,10}, { 511, 9}, { 1023,10}, { 543, 9}, \
+ { 1087,11}, { 287,10}, { 575, 9}, { 1151,10}, \
+ { 607, 9}, { 1215, 8}, { 2431,11}, { 319,10}, \
+ { 639, 9}, { 1279,10}, { 671, 9}, { 1343,12}, \
+ { 191,11}, { 383,10}, { 767, 9}, { 1535,10}, \
+ { 799, 9}, { 1599,10}, { 831, 9}, { 1663,10}, \
+ { 863,13}, { 127,12}, { 255,11}, { 511,10}, \
+ { 1023,11}, { 543,10}, { 1087,11}, { 575,10}, \
+ { 1151,11}, { 607,10}, { 1215, 9}, { 2431,12}, \
+ { 319,11}, { 639,10}, { 1407,11}, { 735,10}, \
+ { 1471, 9}, { 2943,12}, { 383,11}, { 767,10}, \
+ { 1535,11}, { 799,10}, { 1599,11}, { 831,10}, \
+ { 1663,11}, { 895,10}, { 1791,11}, { 959,10}, \
+ { 1919,13}, { 255,12}, { 511,11}, { 1023,10}, \
+ { 2047,11}, { 1087,12}, { 575,11}, { 1151,10}, \
+ { 2303,11}, { 1215,10}, { 2431,12}, { 639,11}, \
+ { 1279,10}, { 2559,11}, { 1407,10}, { 2815,11}, \
+ { 1471,10}, { 2943,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1663,12}, { 895,11}, \
+ { 1791,10}, { 3583,12}, { 959,11}, { 1919,10}, \
+ { 3839,14}, { 255,13}, { 511,12}, { 1023,11}, \
+ { 2047,12}, { 1087,11}, { 2175,12}, { 1151,11}, \
+ { 2303,12}, { 1215,11}, { 2431,13}, { 639,12}, \
+ { 1407,11}, { 2815,12}, { 1471,11}, { 2943,13}, \
+ { 767,12}, { 1663,11}, { 3327,13}, { 895,12}, \
+ { 1791,11}, { 3583,12}, { 1919,11}, { 3839,12}, \
+ { 1983,11}, { 3967,14}, { 511,13}, { 1023,12}, \
+ { 2239,13}, { 1151,12}, { 2495,13}, { 1279,12}, \
+ { 2559,13}, { 1407,12}, { 2943,11}, { 5887,14}, \
+ { 767,13}, { 1535,12}, { 3071,13}, { 1663,12}, \
+ { 3327,13}, { 1791,12}, { 3583,13}, { 1919,12}, \
+ { 3967,15}, { 511,14}, { 1023,13}, { 2047,12}, \
+ { 4095,13}, { 2175,12}, { 4351,13}, { 2431,12}, \
+ { 4863,14}, { 1279,13}, { 2559,12}, { 5119,13}, \
+ { 2943,12}, { 5887,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 228
+#define MUL_FFT_THRESHOLD 7808
+
+#define SQR_FFT_MODF_THRESHOLD 888 /* k = 6 */
+#define SQR_FFT_TABLE3 \
+ { { 888, 6}, { 21, 7}, { 11, 6}, { 25, 7}, \
+ { 13, 6}, { 27, 7}, { 15, 6}, { 31, 7}, \
+ { 17, 6}, { 35, 7}, { 19, 6}, { 39, 7}, \
+ { 23, 6}, { 47, 7}, { 27, 8}, { 15, 7}, \
+ { 31, 6}, { 63, 7}, { 35, 8}, { 19, 7}, \
+ { 39, 8}, { 23, 7}, { 47, 8}, { 31, 7}, \
+ { 63, 8}, { 39, 9}, { 23, 8}, { 47, 7}, \
+ { 95, 8}, { 51, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 63, 8}, { 127, 9}, \
+ { 79,10}, { 47, 9}, { 95, 8}, { 191,11}, \
+ { 31,10}, { 63, 9}, { 127, 8}, { 255, 9}, \
+ { 143,10}, { 79, 9}, { 167,10}, { 95, 9}, \
+ { 191,10}, { 111,11}, { 63,10}, { 127, 9}, \
+ { 255, 8}, { 511,10}, { 143, 9}, { 287, 8}, \
+ { 575,10}, { 159,11}, { 95,10}, { 191, 9}, \
+ { 383,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543, 8}, { 1087,10}, \
+ { 287, 9}, { 575,11}, { 159,10}, { 319, 9}, \
+ { 639, 8}, { 1279, 9}, { 671,11}, { 191,10}, \
+ { 383, 9}, { 799, 8}, { 1599, 9}, { 831,11}, \
+ { 223,12}, { 127,11}, { 255,10}, { 543, 9}, \
+ { 1087,11}, { 287,10}, { 575, 9}, { 1215, 8}, \
+ { 2431,11}, { 319,10}, { 639, 9}, { 1279,10}, \
+ { 671, 9}, { 1407,12}, { 191,10}, { 799, 9}, \
+ { 1599,10}, { 831, 9}, { 1663,10}, { 863, 9}, \
+ { 1727,11}, { 447,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087, 9}, \
+ { 2175,10}, { 1119,11}, { 575,10}, { 1151,11}, \
+ { 607,10}, { 1215, 9}, { 2431,12}, { 319,11}, \
+ { 639,10}, { 1279,11}, { 671,10}, { 1343, 9}, \
+ { 2687,11}, { 703,10}, { 1407,11}, { 735,10}, \
+ { 1471, 9}, { 2943,10}, { 1503,12}, { 383,11}, \
+ { 767,10}, { 1535,11}, { 799,10}, { 1599,11}, \
+ { 863,10}, { 1727,12}, { 447,11}, { 895,10}, \
+ { 1791,11}, { 959,10}, { 1919,13}, { 255,12}, \
+ { 511,11}, { 1023,10}, { 2047,11}, { 1087,10}, \
+ { 2175,11}, { 1119,12}, { 575,11}, { 1151,10}, \
+ { 2303,11}, { 1215,10}, { 2431,12}, { 639,11}, \
+ { 1407,10}, { 2815,11}, { 1471,10}, { 2943,12}, \
+ { 767,11}, { 1599,12}, { 831,11}, { 1663,10}, \
+ { 3327,12}, { 895,11}, { 1791,10}, { 3583,12}, \
+ { 959,11}, { 1919,10}, { 3839,11}, { 1983,14}, \
+ { 255,13}, { 511,12}, { 1023,11}, { 2047,12}, \
+ { 1087,11}, { 2175,12}, { 1151,11}, { 2303,12}, \
+ { 1215,11}, { 2431,13}, { 639,12}, { 1407,11}, \
+ { 2815,12}, { 1471,11}, { 2943,13}, { 767,12}, \
+ { 1663,11}, { 3327,12}, { 1727,13}, { 895,12}, \
+ { 1791,11}, { 3583,12}, { 1919,11}, { 3839,12}, \
+ { 1983,11}, { 3967,14}, { 511,13}, { 1023,12}, \
+ { 2175,13}, { 1151,12}, { 2495,13}, { 1279,12}, \
+ { 2559,13}, { 1407,12}, { 2943,11}, { 5887,14}, \
+ { 767,13}, { 1535,12}, { 3071,13}, { 1663,12}, \
+ { 3327,13}, { 1791,12}, { 3583,13}, { 1919,12}, \
+ { 3967,15}, { 511,14}, { 1023,13}, { 2047,12}, \
+ { 4095,13}, { 2175,12}, { 4351,13}, { 2431,14}, \
+ { 1279,13}, { 2943,12}, { 5887,14}, { 16384,15}, \
+ { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 229
+#define SQR_FFT_THRESHOLD 7552
+
+#define MULLO_BASECASE_THRESHOLD 8
+#define MULLO_DC_THRESHOLD 36
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 45
+#define DC_DIVAPPR_Q_THRESHOLD 208
+#define DC_BDIV_QR_THRESHOLD 43
+#define DC_BDIV_Q_THRESHOLD 140
+
+#define INV_MULMOD_BNM1_THRESHOLD 62
+#define INV_NEWTON_THRESHOLD 204
+#define INV_APPR_THRESHOLD 204
+
+#define BINV_NEWTON_THRESHOLD 230
+#define REDC_1_TO_REDC_N_THRESHOLD 59
+
+#define MU_DIV_QR_THRESHOLD 1752
+#define MU_DIVAPPR_Q_THRESHOLD 1528
+#define MUPI_DIV_QR_THRESHOLD 82
+#define MU_BDIV_QR_THRESHOLD 1360
+#define MU_BDIV_Q_THRESHOLD 1470
+
+#define POWM_SEC_TABLE 1,16,102,336,1221
+
+#define MATRIX22_STRASSEN_THRESHOLD 16
+#define HGCD_THRESHOLD 120
+#define HGCD_APPR_THRESHOLD 143
+#define HGCD_REDUCE_THRESHOLD 4818
+#define GCD_DC_THRESHOLD 474
+#define GCDEXT_DC_THRESHOLD 345
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 15
+#define GET_STR_PRECOMPUTE_THRESHOLD 33
+#define SET_STR_DC_THRESHOLD 298
+#define SET_STR_PRECOMPUTE_THRESHOLD 1187
+
+#define FAC_DSC_THRESHOLD 602
+#define FAC_ODD_THRESHOLD 29
diff --git a/gmp/mpn/x86/k7/invert_limb.asm b/gmp/mpn/x86/k7/invert_limb.asm
new file mode 100644
index 0000000000..6cce455a9d
--- /dev/null
+++ b/gmp/mpn/x86/k7/invert_limb.asm
@@ -0,0 +1,193 @@
+dnl x86 mpn_invert_limb
+
+dnl Contributed to the GNU project by Niels Möller
+
+dnl Copyright 2009, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles (approx) div
+C P5 ?
+C P6 model 0-8,10-12 ?
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) ?
+C P4 model 0 (Willamette) ?
+C P4 model 1 (?) ?
+C P4 model 2 (Northwood) ?
+C P4 model 3 (Prescott) ?
+C P4 model 4 (Nocona) ?
+C AMD K6 ?
+C AMD K7 41 53
+C AMD K8 ?
+
+C TODO
+C * These c/l numbers are for a non-PIC build. Consider falling back to using
+C the 'div' instruction for PIC builds.
+C * Perhaps use this file--or at least the algorithm--for more machines than k7.
+
+C Register usage:
+C Input D in %edi
+C Current approximation is in %eax and/or %ecx
+C %ebx and %edx are temporaries
+C %esi and %ebp are unused
+
+defframe(PARAM_DIVISOR,4)
+
+ASM_START()
+
+C Make approx_tab global to work around Apple relocation bug.
+ifdef(`DARWIN',`
+ deflit(`approx_tab', MPN(invert_limb_tab))
+ GLOBL approx_tab')
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_invert_limb)
+deflit(`FRAME', 0)
+ mov PARAM_DIVISOR, %eax
+ C Avoid push/pop on k7.
+ sub $8, %esp FRAME_subl_esp(8)
+ mov %ebx, (%esp)
+ mov %edi, 4(%esp)
+
+ mov %eax, %edi
+ shr $22, %eax
+ifdef(`PIC',`
+ LEA( approx_tab, %ebx)
+ movzwl -1024(%ebx, %eax, 2), %eax
+',`
+ movzwl -1024+approx_tab(%eax, %eax), %eax C %eax = v0
+')
+
+ C v1 = (v0 << 4) - ((v0*v0*d_21) >> 32) - 1
+ mov %eax, %ecx
+ imul %eax, %eax
+ mov %edi, %ebx
+ shr $11, %ebx
+ inc %ebx
+ mul %ebx
+ mov %edi, %ebx C Prepare
+ shr %ebx
+ sbb %eax, %eax
+ sub %eax, %ebx C %ebx = d_31, %eax = mask
+ shl $4, %ecx
+ dec %ecx
+ sub %edx, %ecx C %ecx = v1
+
+ C v_2 = (v1 << 15) + ((v1 *(2^48 - v1 * d31 + (v1 >> 1) & mask)) >> 33)
+ imul %ecx, %ebx
+ and %ecx, %eax
+ shr %eax
+ sub %ebx, %eax
+ mul %ecx
+ mov %edi, %eax C Prepare for next mul
+ shl $15, %ecx
+ shr %edx
+ add %edx, %ecx C %ecx = v2
+
+ mul %ecx
+ add %edi, %eax
+ mov %ecx, %eax
+ adc %edi, %edx
+ sub %edx, %eax C %eax = v3
+
+ mov (%esp), %ebx
+ mov 4(%esp), %edi
+ add $8, %esp
+
+ ret
+
+EPILOGUE()
+
+DEF_OBJECT(approx_tab,2)
+ .value 0x7fe1,0x7fa1,0x7f61,0x7f22,0x7ee3,0x7ea4,0x7e65,0x7e27
+ .value 0x7de9,0x7dab,0x7d6d,0x7d30,0x7cf3,0x7cb6,0x7c79,0x7c3d
+ .value 0x7c00,0x7bc4,0x7b89,0x7b4d,0x7b12,0x7ad7,0x7a9c,0x7a61
+ .value 0x7a27,0x79ec,0x79b2,0x7979,0x793f,0x7906,0x78cc,0x7894
+ .value 0x785b,0x7822,0x77ea,0x77b2,0x777a,0x7742,0x770b,0x76d3
+ .value 0x769c,0x7665,0x762f,0x75f8,0x75c2,0x758c,0x7556,0x7520
+ .value 0x74ea,0x74b5,0x7480,0x744b,0x7416,0x73e2,0x73ad,0x7379
+ .value 0x7345,0x7311,0x72dd,0x72aa,0x7277,0x7243,0x7210,0x71de
+ .value 0x71ab,0x7179,0x7146,0x7114,0x70e2,0x70b1,0x707f,0x704e
+ .value 0x701c,0x6feb,0x6fba,0x6f8a,0x6f59,0x6f29,0x6ef9,0x6ec8
+ .value 0x6e99,0x6e69,0x6e39,0x6e0a,0x6ddb,0x6dab,0x6d7d,0x6d4e
+ .value 0x6d1f,0x6cf1,0x6cc2,0x6c94,0x6c66,0x6c38,0x6c0a,0x6bdd
+ .value 0x6bb0,0x6b82,0x6b55,0x6b28,0x6afb,0x6acf,0x6aa2,0x6a76
+ .value 0x6a49,0x6a1d,0x69f1,0x69c6,0x699a,0x696e,0x6943,0x6918
+ .value 0x68ed,0x68c2,0x6897,0x686c,0x6842,0x6817,0x67ed,0x67c3
+ .value 0x6799,0x676f,0x6745,0x671b,0x66f2,0x66c8,0x669f,0x6676
+ .value 0x664d,0x6624,0x65fc,0x65d3,0x65aa,0x6582,0x655a,0x6532
+ .value 0x650a,0x64e2,0x64ba,0x6493,0x646b,0x6444,0x641c,0x63f5
+ .value 0x63ce,0x63a7,0x6381,0x635a,0x6333,0x630d,0x62e7,0x62c1
+ .value 0x629a,0x6275,0x624f,0x6229,0x6203,0x61de,0x61b8,0x6193
+ .value 0x616e,0x6149,0x6124,0x60ff,0x60da,0x60b6,0x6091,0x606d
+ .value 0x6049,0x6024,0x6000,0x5fdc,0x5fb8,0x5f95,0x5f71,0x5f4d
+ .value 0x5f2a,0x5f07,0x5ee3,0x5ec0,0x5e9d,0x5e7a,0x5e57,0x5e35
+ .value 0x5e12,0x5def,0x5dcd,0x5dab,0x5d88,0x5d66,0x5d44,0x5d22
+ .value 0x5d00,0x5cde,0x5cbd,0x5c9b,0x5c7a,0x5c58,0x5c37,0x5c16
+ .value 0x5bf5,0x5bd4,0x5bb3,0x5b92,0x5b71,0x5b51,0x5b30,0x5b10
+ .value 0x5aef,0x5acf,0x5aaf,0x5a8f,0x5a6f,0x5a4f,0x5a2f,0x5a0f
+ .value 0x59ef,0x59d0,0x59b0,0x5991,0x5972,0x5952,0x5933,0x5914
+ .value 0x58f5,0x58d6,0x58b7,0x5899,0x587a,0x585b,0x583d,0x581f
+ .value 0x5800,0x57e2,0x57c4,0x57a6,0x5788,0x576a,0x574c,0x572e
+ .value 0x5711,0x56f3,0x56d5,0x56b8,0x569b,0x567d,0x5660,0x5643
+ .value 0x5626,0x5609,0x55ec,0x55cf,0x55b2,0x5596,0x5579,0x555d
+ .value 0x5540,0x5524,0x5507,0x54eb,0x54cf,0x54b3,0x5497,0x547b
+ .value 0x545f,0x5443,0x5428,0x540c,0x53f0,0x53d5,0x53b9,0x539e
+ .value 0x5383,0x5368,0x534c,0x5331,0x5316,0x52fb,0x52e0,0x52c6
+ .value 0x52ab,0x5290,0x5276,0x525b,0x5240,0x5226,0x520c,0x51f1
+ .value 0x51d7,0x51bd,0x51a3,0x5189,0x516f,0x5155,0x513b,0x5121
+ .value 0x5108,0x50ee,0x50d5,0x50bb,0x50a2,0x5088,0x506f,0x5056
+ .value 0x503c,0x5023,0x500a,0x4ff1,0x4fd8,0x4fbf,0x4fa6,0x4f8e
+ .value 0x4f75,0x4f5c,0x4f44,0x4f2b,0x4f13,0x4efa,0x4ee2,0x4eca
+ .value 0x4eb1,0x4e99,0x4e81,0x4e69,0x4e51,0x4e39,0x4e21,0x4e09
+ .value 0x4df1,0x4dda,0x4dc2,0x4daa,0x4d93,0x4d7b,0x4d64,0x4d4d
+ .value 0x4d35,0x4d1e,0x4d07,0x4cf0,0x4cd8,0x4cc1,0x4caa,0x4c93
+ .value 0x4c7d,0x4c66,0x4c4f,0x4c38,0x4c21,0x4c0b,0x4bf4,0x4bde
+ .value 0x4bc7,0x4bb1,0x4b9a,0x4b84,0x4b6e,0x4b58,0x4b41,0x4b2b
+ .value 0x4b15,0x4aff,0x4ae9,0x4ad3,0x4abd,0x4aa8,0x4a92,0x4a7c
+ .value 0x4a66,0x4a51,0x4a3b,0x4a26,0x4a10,0x49fb,0x49e5,0x49d0
+ .value 0x49bb,0x49a6,0x4990,0x497b,0x4966,0x4951,0x493c,0x4927
+ .value 0x4912,0x48fe,0x48e9,0x48d4,0x48bf,0x48ab,0x4896,0x4881
+ .value 0x486d,0x4858,0x4844,0x482f,0x481b,0x4807,0x47f3,0x47de
+ .value 0x47ca,0x47b6,0x47a2,0x478e,0x477a,0x4766,0x4752,0x473e
+ .value 0x472a,0x4717,0x4703,0x46ef,0x46db,0x46c8,0x46b4,0x46a1
+ .value 0x468d,0x467a,0x4666,0x4653,0x4640,0x462c,0x4619,0x4606
+ .value 0x45f3,0x45e0,0x45cd,0x45ba,0x45a7,0x4594,0x4581,0x456e
+ .value 0x455b,0x4548,0x4536,0x4523,0x4510,0x44fe,0x44eb,0x44d8
+ .value 0x44c6,0x44b3,0x44a1,0x448f,0x447c,0x446a,0x4458,0x4445
+ .value 0x4433,0x4421,0x440f,0x43fd,0x43eb,0x43d9,0x43c7,0x43b5
+ .value 0x43a3,0x4391,0x437f,0x436d,0x435c,0x434a,0x4338,0x4327
+ .value 0x4315,0x4303,0x42f2,0x42e0,0x42cf,0x42bd,0x42ac,0x429b
+ .value 0x4289,0x4278,0x4267,0x4256,0x4244,0x4233,0x4222,0x4211
+ .value 0x4200,0x41ef,0x41de,0x41cd,0x41bc,0x41ab,0x419a,0x418a
+ .value 0x4179,0x4168,0x4157,0x4147,0x4136,0x4125,0x4115,0x4104
+ .value 0x40f4,0x40e3,0x40d3,0x40c2,0x40b2,0x40a2,0x4091,0x4081
+ .value 0x4071,0x4061,0x4050,0x4040,0x4030,0x4020,0x4010,0x4000
+END_OBJECT(approx_tab)
diff --git a/gmp/mpn/x86/k7/mmx/com.asm b/gmp/mpn/x86/k7/mmx/com.asm
new file mode 100644
index 0000000000..a258c224f1
--- /dev/null
+++ b/gmp/mpn/x86/k7/mmx/com.asm
@@ -0,0 +1,125 @@
+dnl AMD Athlon mpn_com -- mpn bitwise one's complement.
+
+dnl Copyright 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K7: 1.0 cycles/limb
+
+
+C void mpn_com (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C The loop form below is necessary for the claimed speed. It needs to be
+C aligned to a 16 byte boundary and only 16 bytes long. Maybe that's so it
+C fits in a BTB entry. The adjustments to %eax and %edx avoid offsets on
+C the movq's and achieve the necessary size.
+C
+C If both src and dst are 4mod8, the loop runs at 1.5 c/l. So long as one
+C of the two is 0mod8, it runs at 1.0 c/l. On that basis dst is checked
+C (offset by the size, as per the loop addressing) and one high limb
+C processed separately to get alignment.
+C
+C The padding for the nails case is unattractive, but shouldn't cost any
+C cycles. Explicit .byte's guarantee the desired instructions, at a point
+C where we're probably stalled waiting for loads anyway.
+C
+C Enhancements:
+C
+C The combination load/pxor/store might be able to be unrolled to approach
+C 0.5 c/l if desired.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(mpn_com)
+deflit(`FRAME',0)
+
+ movl PARAM_DST, %edx
+ movl PARAM_SIZE, %ecx
+ pcmpeqd %mm7, %mm7
+
+ leal (%edx,%ecx,4), %eax
+ andl $4, %eax
+ifelse(GMP_NAIL_BITS,0,,
+` psrld $GMP_NAIL_BITS, %mm7') C GMP_NUMB_MASK
+
+ movl PARAM_SRC, %eax
+ movd -4(%eax,%ecx,4), %mm0 C src high limb
+
+ifelse(GMP_NAIL_BITS,0,,
+` C padding for alignment below
+ .byte 0x8d, 0xb6, 0x00, 0x00, 0x00, 0x00 C lea 0(%esi),%esi
+ .byte 0x8d, 0xbf, 0x00, 0x00, 0x00, 0x00 C lea 0(%edi),%edi
+')
+
+ jz L(aligned)
+
+ pxor %mm7, %mm0
+ movd %mm0, -4(%edx,%ecx,4) C dst high limb
+ decl %ecx
+ jz L(done)
+L(aligned):
+
+ addl $4, %eax
+ addl $4, %edx
+ decl %ecx
+ jz L(one)
+
+ C offset 0x30 for no nails, or 0x40 for nails
+ ALIGN(16)
+L(top):
+ C eax src
+ C ebx
+ C ecx counter
+ C edx dst
+
+ subl $2, %ecx
+ movq (%eax,%ecx,4), %mm0
+ pxor %mm7, %mm0
+ movq %mm0, (%edx,%ecx,4)
+ jg L(top)
+
+ jnz L(done) C if size even
+
+L(one):
+ movd -4(%eax), %mm0 C src low limb
+ pxor %mm7, %mm0
+ movd %mm0, -4(%edx) C dst low limb
+
+L(done):
+ emms
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mmx/copyd.asm b/gmp/mpn/x86/k7/mmx/copyd.asm
new file mode 100644
index 0000000000..59ece40920
--- /dev/null
+++ b/gmp/mpn/x86/k7/mmx/copyd.asm
@@ -0,0 +1,144 @@
+dnl AMD K7 mpn_copyd -- copy limb vector, decrementing.
+
+dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C alignment dst/src, A=0mod8 N=4mod8
+C A/A A/N N/A N/N
+C K7 0.75 1.0 1.0 0.75
+
+
+C void mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C The various comments in mpn/x86/k7/copyi.asm apply here too.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+dnl parameter space reused
+define(SAVE_EBX,`PARAM_SIZE')
+define(SAVE_ESI,`PARAM_SRC')
+
+dnl minimum 5 since the unrolled code can't handle less than 5
+deflit(UNROLL_THRESHOLD, 5)
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_copyd)
+
+ movl PARAM_SIZE, %ecx
+ movl %ebx, SAVE_EBX
+
+ movl PARAM_SRC, %eax
+ movl PARAM_DST, %edx
+
+ cmpl $UNROLL_THRESHOLD, %ecx
+ jae L(unroll)
+
+ orl %ecx, %ecx
+ jz L(simple_done)
+
+L(simple):
+ C eax src
+ C ebx scratch
+ C ecx counter
+ C edx dst
+ C
+ C this loop is 2 cycles/limb
+
+ movl -4(%eax,%ecx,4), %ebx
+ movl %ebx, -4(%edx,%ecx,4)
+ decl %ecx
+ jnz L(simple)
+
+L(simple_done):
+ movl SAVE_EBX, %ebx
+ ret
+
+
+L(unroll):
+ movl %esi, SAVE_ESI
+ leal (%eax,%ecx,4), %ebx
+ leal (%edx,%ecx,4), %esi
+
+ andl %esi, %ebx
+ movl SAVE_ESI, %esi
+ subl $4, %ecx C size-4
+
+ testl $4, %ebx C testl to pad code closer to 16 bytes for L(top)
+ jz L(aligned)
+
+ C both src and dst unaligned, process one limb to align them
+ movl 12(%eax,%ecx,4), %ebx
+ movl %ebx, 12(%edx,%ecx,4)
+ decl %ecx
+L(aligned):
+
+
+ ALIGN(16)
+L(top):
+ C eax src
+ C ebx
+ C ecx counter, limbs
+ C edx dst
+
+ movq 8(%eax,%ecx,4), %mm0
+ movq (%eax,%ecx,4), %mm1
+ subl $4, %ecx
+ movq %mm0, 16+8(%edx,%ecx,4)
+ movq %mm1, 16(%edx,%ecx,4)
+ jns L(top)
+
+
+ C now %ecx is -4 to -1 representing respectively 0 to 3 limbs remaining
+
+ testb $2, %cl
+ jz L(finish_not_two)
+
+ movq 8(%eax,%ecx,4), %mm0
+ movq %mm0, 8(%edx,%ecx,4)
+L(finish_not_two):
+
+ testb $1, %cl
+ jz L(done)
+
+ movl (%eax), %ebx
+ movl %ebx, (%edx)
+
+L(done):
+ movl SAVE_EBX, %ebx
+ emms
+ ret
+
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mmx/copyi.asm b/gmp/mpn/x86/k7/mmx/copyi.asm
new file mode 100644
index 0000000000..9a28f927ec
--- /dev/null
+++ b/gmp/mpn/x86/k7/mmx/copyi.asm
@@ -0,0 +1,157 @@
+dnl AMD K7 mpn_copyi -- copy limb vector, incrementing.
+
+dnl Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C alignment dst/src, A=0mod8 N=4mod8
+C A/A A/N N/A N/N
+C K7 0.75 1.0 1.0 0.75
+
+
+C void mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C Copy src,size to dst,size.
+C
+C This code at 0.75 or 1.0 c/l is always faster than a plain rep movsl at
+C 1.33 c/l.
+C
+C The K7 can do a 64-bit load and 64-bit store in one cycle (optimization
+C guile 22007 appendix B), so 0.5 c/l should be possible, however nothing
+C under 0.7 c/l is known. Apparently only two 32-bit stores can be done in
+C one cycle, so perhaps some scheduling is needed to ensure it's a
+C load+store in each cycle, not store+store.
+C
+C If both source and destination are unaligned then one limb is processed at
+C the start to make them aligned and so get 0.75 c/l, whereas if they'd been
+C used unaligned it would be 1.5 c/l.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl parameter space reused
+define(SAVE_EBX,`PARAM_SIZE')
+
+dnl minimum 5 since the unrolled code can't handle less than 5
+deflit(UNROLL_THRESHOLD, 5)
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_copyi)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl %ebx, SAVE_EBX
+
+ movl PARAM_SRC, %eax
+ movl PARAM_DST, %edx
+
+ cmpl $UNROLL_THRESHOLD, %ecx
+ jae L(unroll)
+
+ orl %ecx, %ecx
+ jz L(simple_done)
+
+L(simple):
+ C eax src, incrementing
+ C ebx scratch
+ C ecx counter
+ C edx dst, incrementing
+ C
+ C this loop is 2 cycles/limb
+
+ movl (%eax), %ebx
+ movl %ebx, (%edx)
+ decl %ecx
+ leal 4(%eax), %eax
+ leal 4(%edx), %edx
+ jnz L(simple)
+
+L(simple_done):
+ movl SAVE_EBX, %ebx
+ ret
+
+
+L(unroll):
+ movl %eax, %ebx
+ leal -12(%eax,%ecx,4), %eax C src end - 12
+ subl $3, %ecx C size-3
+
+ andl %edx, %ebx
+ leal (%edx,%ecx,4), %edx C dst end - 12
+ negl %ecx
+
+ testl $4, %ebx C testl to pad code closer to 16 bytes for L(top)
+ jz L(aligned)
+
+ C both src and dst unaligned, process one limb to align them
+ movl (%eax,%ecx,4), %ebx
+ movl %ebx, (%edx,%ecx,4)
+ incl %ecx
+L(aligned):
+
+
+ ALIGN(16)
+L(top):
+ C eax src end - 12
+ C ebx
+ C ecx counter, negative, limbs
+ C edx dst end - 12
+
+ movq (%eax,%ecx,4), %mm0
+ movq 8(%eax,%ecx,4), %mm1
+ addl $4, %ecx
+ movq %mm0, -16(%edx,%ecx,4)
+ movq %mm1, -16+8(%edx,%ecx,4)
+ ja L(top) C jump no carry and not zero
+
+
+ C now %ecx is 0 to 3 representing respectively 3 to 0 limbs remaining
+
+ testb $2, %cl
+ jnz L(finish_not_two)
+
+ movq (%eax,%ecx,4), %mm0
+ movq %mm0, (%edx,%ecx,4)
+L(finish_not_two):
+
+ testb $1, %cl
+ jnz L(done)
+
+ movl 8(%eax), %ebx
+ movl %ebx, 8(%edx)
+
+L(done):
+ movl SAVE_EBX, %ebx
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mmx/divrem_1.asm b/gmp/mpn/x86/k7/mmx/divrem_1.asm
new file mode 100644
index 0000000000..cf343280bb
--- /dev/null
+++ b/gmp/mpn/x86/k7/mmx/divrem_1.asm
@@ -0,0 +1,832 @@
+dnl AMD K7 mpn_divrem_1, mpn_divrem_1c, mpn_preinv_divrem_1 -- mpn by limb
+dnl division.
+
+dnl Copyright 1999-2002, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K7: 17.0 cycles/limb integer part, 15.0 cycles/limb fraction part.
+
+
+C mp_limb_t mpn_divrem_1 (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C mp_limb_t mpn_divrem_1c (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C mp_limb_t mpn_preinv_divrem_1 (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t inverse,
+C unsigned shift);
+C
+C Algorithm:
+C
+C The method and nomenclature follow part 8 of "Division by Invariant
+C Integers using Multiplication" by Granlund and Montgomery, reference in
+C gmp.texi.
+C
+C The "and"s shown in the paper are done here with "cmov"s. "m" is written
+C for m', and "d" for d_norm, which won't cause any confusion since it's
+C only the normalized divisor that's of any use in the code. "b" is written
+C for 2^N, the size of a limb, N being 32 here.
+C
+C The step "sdword dr = n - 2^N*d + (2^N-1-q1) * d" is instead done as
+C "n-(q1+1)*d"; this rearrangement gives the same two-limb answer. If
+C q1==0xFFFFFFFF, then q1+1 would overflow. We branch to a special case
+C "q1_ff" if this occurs. Since the true quotient is either q1 or q1+1 then
+C if q1==0xFFFFFFFF that must be the right value.
+C
+C For the last and second last steps q1==0xFFFFFFFF is instead handled by an
+C sbbl to go back to 0xFFFFFFFF if an overflow occurs when adding 1. This
+C then goes through as normal, and finding no addback required. sbbl costs
+C an extra cycle over what the main loop code does, but it keeps code size
+C and complexity down.
+C
+C Notes:
+C
+C mpn_divrem_1 and mpn_preinv_divrem_1 avoid one division if the src high
+C limb is less than the divisor. mpn_divrem_1c doesn't check for a zero
+C carry, since in normal circumstances that will be a very rare event.
+C
+C The test for skipping a division is branch free (once size>=1 is tested).
+C The store to the destination high limb is 0 when a divide is skipped, or
+C if it's not skipped then a copy of the src high limb is used. The latter
+C is in case src==dst.
+C
+C There's a small bias towards expecting xsize==0, by having code for
+C xsize==0 in a straight line and xsize!=0 under forward jumps.
+C
+C Alternatives:
+C
+C If the divisor is normalized (high bit set) then a division step can
+C always be skipped, since the high destination limb is always 0 or 1 in
+C that case. It doesn't seem worth checking for this though, since it
+C probably occurs infrequently, in particular note that big_base for a
+C decimal mpn_get_str is not normalized in a 32-bit limb.
+
+
+dnl MUL_THRESHOLD is the value of xsize+size at which the multiply by
+dnl inverse method is used, rather than plain "divl"s. Minimum value 1.
+dnl
+dnl The inverse takes about 50 cycles to calculate, but after that the
+dnl multiply is 17 c/l versus division at 42 c/l.
+dnl
+dnl At 3 limbs the mul is a touch faster than div on the integer part, and
+dnl even more so on the fractional part.
+
+deflit(MUL_THRESHOLD, 3)
+
+
+defframe(PARAM_PREINV_SHIFT, 28) dnl mpn_preinv_divrem_1
+defframe(PARAM_PREINV_INVERSE, 24) dnl mpn_preinv_divrem_1
+defframe(PARAM_CARRY, 24) dnl mpn_divrem_1c
+defframe(PARAM_DIVISOR,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC, 12)
+defframe(PARAM_XSIZE, 8)
+defframe(PARAM_DST, 4)
+
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+
+defframe(VAR_NORM, -20)
+defframe(VAR_INVERSE, -24)
+defframe(VAR_SRC, -28)
+defframe(VAR_DST, -32)
+defframe(VAR_DST_STOP,-36)
+
+deflit(STACK_SPACE, 36)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(mpn_preinv_divrem_1)
+deflit(`FRAME',0)
+ movl PARAM_XSIZE, %ecx
+ movl PARAM_DST, %edx
+ subl $STACK_SPACE, %esp FRAME_subl_esp(STACK_SPACE)
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_SIZE, %ebx
+
+ leal 8(%edx,%ecx,4), %edx C &dst[xsize+2]
+ movl %ebp, SAVE_EBP
+ movl PARAM_DIVISOR, %ebp
+
+ movl %edx, VAR_DST_STOP C &dst[xsize+2]
+ movl %edi, SAVE_EDI
+ xorl %edi, %edi C carry
+
+ movl -4(%esi,%ebx,4), %eax C src high limb
+ xor %ecx, %ecx
+
+ C
+
+ C
+
+ cmpl %ebp, %eax C high cmp divisor
+
+ cmovc( %eax, %edi) C high is carry if high<divisor
+ cmovnc( %eax, %ecx) C 0 if skip div, src high if not
+ C (the latter in case src==dst)
+
+ movl %ecx, -12(%edx,%ebx,4) C dst high limb
+ sbbl $0, %ebx C skip one division if high<divisor
+ movl PARAM_PREINV_SHIFT, %ecx
+
+ leal -8(%edx,%ebx,4), %edx C &dst[xsize+size]
+ movl $32, %eax
+
+ movl %edx, VAR_DST C &dst[xsize+size]
+
+ shll %cl, %ebp C d normalized
+ subl %ecx, %eax
+ movl %ecx, VAR_NORM
+
+ movd %eax, %mm7 C rshift
+ movl PARAM_PREINV_INVERSE, %eax
+ jmp L(start_preinv)
+
+EPILOGUE()
+
+
+ ALIGN(16)
+
+PROLOGUE(mpn_divrem_1c)
+deflit(`FRAME',0)
+ movl PARAM_CARRY, %edx
+ movl PARAM_SIZE, %ecx
+ subl $STACK_SPACE, %esp
+deflit(`FRAME',STACK_SPACE)
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_XSIZE, %ebx
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_DIVISOR, %ebp
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ leal -4(%edi,%ebx,4), %edi C &dst[xsize-1]
+ jmp L(start_1c)
+
+EPILOGUE()
+
+
+ C offset 0xa1, close enough to aligned
+PROLOGUE(mpn_divrem_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl $0, %edx C initial carry (if can't skip a div)
+ subl $STACK_SPACE, %esp
+deflit(`FRAME',STACK_SPACE)
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_XSIZE, %ebx
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_DIVISOR, %ebp
+ orl %ecx, %ecx C size
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+ leal -4(%edi,%ebx,4), %edi C &dst[xsize-1]
+
+ jz L(no_skip_div) C if size==0
+ movl -4(%esi,%ecx,4), %eax C src high limb
+ xorl %esi, %esi
+
+ cmpl %ebp, %eax C high cmp divisor
+
+ cmovc( %eax, %edx) C high is carry if high<divisor
+ cmovnc( %eax, %esi) C 0 if skip div, src high if not
+
+ movl %esi, (%edi,%ecx,4) C dst high limb
+ sbbl $0, %ecx C size-1 if high<divisor
+ movl PARAM_SRC, %esi C reload
+L(no_skip_div):
+
+
+L(start_1c):
+ C eax
+ C ebx xsize
+ C ecx size
+ C edx carry
+ C esi src
+ C edi &dst[xsize-1]
+ C ebp divisor
+
+ leal (%ebx,%ecx), %eax C size+xsize
+ cmpl $MUL_THRESHOLD, %eax
+ jae L(mul_by_inverse)
+
+
+C With MUL_THRESHOLD set to 3, the simple loops here only do 0 to 2 limbs.
+C It'd be possible to write them out without the looping, but no speedup
+C would be expected.
+C
+C Using PARAM_DIVISOR instead of %ebp measures 1 cycle/loop faster on the
+C integer part, but curiously not on the fractional part, where %ebp is a
+C (fixed) couple of cycles faster.
+
+ orl %ecx, %ecx
+ jz L(divide_no_integer)
+
+L(divide_integer):
+ C eax scratch (quotient)
+ C ebx xsize
+ C ecx counter
+ C edx scratch (remainder)
+ C esi src
+ C edi &dst[xsize-1]
+ C ebp divisor
+
+ movl -4(%esi,%ecx,4), %eax
+
+ divl PARAM_DIVISOR
+
+ movl %eax, (%edi,%ecx,4)
+ decl %ecx
+ jnz L(divide_integer)
+
+
+L(divide_no_integer):
+ movl PARAM_DST, %edi
+ orl %ebx, %ebx
+ jnz L(divide_fraction)
+
+L(divide_done):
+ movl SAVE_ESI, %esi
+ movl SAVE_EDI, %edi
+ movl %edx, %eax
+
+ movl SAVE_EBX, %ebx
+ movl SAVE_EBP, %ebp
+ addl $STACK_SPACE, %esp
+
+ ret
+
+
+L(divide_fraction):
+ C eax scratch (quotient)
+ C ebx counter
+ C ecx
+ C edx scratch (remainder)
+ C esi
+ C edi dst
+ C ebp divisor
+
+ movl $0, %eax
+
+ divl %ebp
+
+ movl %eax, -4(%edi,%ebx,4)
+ decl %ebx
+ jnz L(divide_fraction)
+
+ jmp L(divide_done)
+
+
+
+C -----------------------------------------------------------------------------
+
+L(mul_by_inverse):
+ C eax
+ C ebx xsize
+ C ecx size
+ C edx carry
+ C esi src
+ C edi &dst[xsize-1]
+ C ebp divisor
+
+ bsrl %ebp, %eax C 31-l
+
+ leal 12(%edi), %ebx C &dst[xsize+2], loop dst stop
+ leal 4(%edi,%ecx,4), %edi C &dst[xsize+size]
+
+ movl %edi, VAR_DST
+ movl %ebx, VAR_DST_STOP
+
+ movl %ecx, %ebx C size
+ movl $31, %ecx
+
+ movl %edx, %edi C carry
+ movl $-1, %edx
+
+ C
+
+ xorl %eax, %ecx C l
+ incl %eax C 32-l
+
+ shll %cl, %ebp C d normalized
+ movl %ecx, VAR_NORM
+
+ movd %eax, %mm7
+
+ movl $-1, %eax
+ subl %ebp, %edx C (b-d)-1 giving edx:eax = b*(b-d)-1
+
+ divl %ebp C floor (b*(b-d)-1) / d
+
+L(start_preinv):
+ C eax inverse
+ C ebx size
+ C ecx shift
+ C edx
+ C esi src
+ C edi carry
+ C ebp divisor
+ C
+ C mm7 rshift
+
+ orl %ebx, %ebx C size
+ movl %eax, VAR_INVERSE
+ leal -12(%esi,%ebx,4), %eax C &src[size-3]
+
+ jz L(start_zero)
+ movl %eax, VAR_SRC
+ cmpl $1, %ebx
+
+ movl 8(%eax), %esi C src high limb
+ jz L(start_one)
+
+L(start_two_or_more):
+ movl 4(%eax), %edx C src second highest limb
+
+ shldl( %cl, %esi, %edi) C n2 = carry,high << l
+
+ shldl( %cl, %edx, %esi) C n10 = high,second << l
+
+ cmpl $2, %ebx
+ je L(integer_two_left)
+ jmp L(integer_top)
+
+
+L(start_one):
+ shldl( %cl, %esi, %edi) C n2 = carry,high << l
+
+ shll %cl, %esi C n10 = high << l
+ movl %eax, VAR_SRC
+ jmp L(integer_one_left)
+
+
+L(start_zero):
+ C Can be here with xsize==0 if mpn_preinv_divrem_1 had size==1 and
+ C skipped a division.
+
+ shll %cl, %edi C n2 = carry << l
+ movl %edi, %eax C return value for zero_done
+ cmpl $0, PARAM_XSIZE
+
+ je L(zero_done)
+ jmp L(fraction_some)
+
+
+
+C -----------------------------------------------------------------------------
+C
+C The multiply by inverse loop is 17 cycles, and relies on some out-of-order
+C execution. The instruction scheduling is important, with various
+C apparently equivalent forms running 1 to 5 cycles slower.
+C
+C A lower bound for the time would seem to be 16 cycles, based on the
+C following successive dependencies.
+C
+C cycles
+C n2+n1 1
+C mul 6
+C q1+1 1
+C mul 6
+C sub 1
+C addback 1
+C ---
+C 16
+C
+C This chain is what the loop has already, but 16 cycles isn't achieved.
+C K7 has enough decode, and probably enough execute (depending maybe on what
+C a mul actually consumes), but nothing running under 17 has been found.
+C
+C In theory n2+n1 could be done in the sub and addback stages (by
+C calculating both n2 and n2+n1 there), but lack of registers makes this an
+C unlikely proposition.
+C
+C The jz in the loop keeps the q1+1 stage to 1 cycle. Handling an overflow
+C from q1+1 with an "sbbl $0, %ebx" would add a cycle to the dependent
+C chain, and nothing better than 18 cycles has been found when using it.
+C The jump is taken only when q1 is 0xFFFFFFFF, and on random data this will
+C be an extremely rare event.
+C
+C Branch mispredictions will hit random occurrences of q1==0xFFFFFFFF, but
+C if some special data is coming out with this always, the q1_ff special
+C case actually runs at 15 c/l. 0x2FFF...FFFD divided by 3 is a good way to
+C induce the q1_ff case, for speed measurements or testing. Note that
+C 0xFFF...FFF divided by 1 or 2 doesn't induce it.
+C
+C The instruction groupings and empty comments show the cycles for a naive
+C in-order view of the code (conveniently ignoring the load latency on
+C VAR_INVERSE). This shows some of where the time is going, but is nonsense
+C to the extent that out-of-order execution rearranges it. In this case
+C there's 19 cycles shown, but it executes at 17.
+
+ ALIGN(16)
+L(integer_top):
+ C eax scratch
+ C ebx scratch (nadj, q1)
+ C ecx scratch (src, dst)
+ C edx scratch
+ C esi n10
+ C edi n2
+ C ebp divisor
+ C
+ C mm0 scratch (src qword)
+ C mm7 rshift for normalization
+
+ cmpl $0x80000000, %esi C n1 as 0=c, 1=nc
+ movl %edi, %eax C n2
+ movl VAR_SRC, %ecx
+
+ leal (%ebp,%esi), %ebx
+ cmovc( %esi, %ebx) C nadj = n10 + (-n1 & d), ignoring overflow
+ sbbl $-1, %eax C n2+n1
+
+ mull VAR_INVERSE C m*(n2+n1)
+
+ movq (%ecx), %mm0 C next limb and the one below it
+ subl $4, %ecx
+
+ movl %ecx, VAR_SRC
+
+ C
+
+ addl %ebx, %eax C m*(n2+n1) + nadj, low giving carry flag
+ leal 1(%edi), %ebx C n2+1
+ movl %ebp, %eax C d
+
+ C
+
+ adcl %edx, %ebx C 1 + high(n2<<32 + m*(n2+n1) + nadj) = q1+1
+ jz L(q1_ff)
+ movl VAR_DST, %ecx
+
+ mull %ebx C (q1+1)*d
+
+ psrlq %mm7, %mm0
+
+ leal -4(%ecx), %ecx
+
+ C
+
+ subl %eax, %esi
+ movl VAR_DST_STOP, %eax
+
+ C
+
+ sbbl %edx, %edi C n - (q1+1)*d
+ movl %esi, %edi C remainder -> n2
+ leal (%ebp,%esi), %edx
+
+ movd %mm0, %esi
+
+ cmovc( %edx, %edi) C n - q1*d if underflow from using q1+1
+ sbbl $0, %ebx C q
+ cmpl %eax, %ecx
+
+ movl %ebx, (%ecx)
+ movl %ecx, VAR_DST
+ jne L(integer_top)
+
+
+L(integer_loop_done):
+
+
+C -----------------------------------------------------------------------------
+C
+C Here, and in integer_one_left below, an sbbl $0 is used rather than a jz
+C q1_ff special case. This make the code a bit smaller and simpler, and
+C costs only 1 cycle (each).
+
+L(integer_two_left):
+ C eax scratch
+ C ebx scratch (nadj, q1)
+ C ecx scratch (src, dst)
+ C edx scratch
+ C esi n10
+ C edi n2
+ C ebp divisor
+ C
+ C mm7 rshift
+
+ cmpl $0x80000000, %esi C n1 as 0=c, 1=nc
+ movl %edi, %eax C n2
+ movl PARAM_SRC, %ecx
+
+ leal (%ebp,%esi), %ebx
+ cmovc( %esi, %ebx) C nadj = n10 + (-n1 & d), ignoring overflow
+ sbbl $-1, %eax C n2+n1
+
+ mull VAR_INVERSE C m*(n2+n1)
+
+ movd (%ecx), %mm0 C src low limb
+
+ movl VAR_DST_STOP, %ecx
+
+ C
+
+ addl %ebx, %eax C m*(n2+n1) + nadj, low giving carry flag
+ leal 1(%edi), %ebx C n2+1
+ movl %ebp, %eax C d
+
+ adcl %edx, %ebx C 1 + high(n2<<32 + m*(n2+n1) + nadj) = q1+1
+
+ sbbl $0, %ebx
+
+ mull %ebx C (q1+1)*d
+
+ psllq $32, %mm0
+
+ psrlq %mm7, %mm0
+
+ C
+
+ subl %eax, %esi
+
+ C
+
+ sbbl %edx, %edi C n - (q1+1)*d
+ movl %esi, %edi C remainder -> n2
+ leal (%ebp,%esi), %edx
+
+ movd %mm0, %esi
+
+ cmovc( %edx, %edi) C n - q1*d if underflow from using q1+1
+ sbbl $0, %ebx C q
+
+ movl %ebx, -4(%ecx)
+
+
+C -----------------------------------------------------------------------------
+L(integer_one_left):
+ C eax scratch
+ C ebx scratch (nadj, q1)
+ C ecx dst
+ C edx scratch
+ C esi n10
+ C edi n2
+ C ebp divisor
+ C
+ C mm7 rshift
+
+ movl VAR_DST_STOP, %ecx
+ cmpl $0x80000000, %esi C n1 as 0=c, 1=nc
+ movl %edi, %eax C n2
+
+ leal (%ebp,%esi), %ebx
+ cmovc( %esi, %ebx) C nadj = n10 + (-n1 & d), ignoring overflow
+ sbbl $-1, %eax C n2+n1
+
+ mull VAR_INVERSE C m*(n2+n1)
+
+ C
+
+ C
+
+ C
+
+ addl %ebx, %eax C m*(n2+n1) + nadj, low giving carry flag
+ leal 1(%edi), %ebx C n2+1
+ movl %ebp, %eax C d
+
+ C
+
+ adcl %edx, %ebx C 1 + high(n2<<32 + m*(n2+n1) + nadj) = q1+1
+
+ sbbl $0, %ebx C q1 if q1+1 overflowed
+
+ mull %ebx
+
+ C
+
+ C
+
+ C
+
+ subl %eax, %esi
+
+ C
+
+ sbbl %edx, %edi C n - (q1+1)*d
+ movl %esi, %edi C remainder -> n2
+ leal (%ebp,%esi), %edx
+
+ cmovc( %edx, %edi) C n - q1*d if underflow from using q1+1
+ sbbl $0, %ebx C q
+
+ movl %ebx, -8(%ecx)
+ subl $8, %ecx
+
+
+
+L(integer_none):
+ cmpl $0, PARAM_XSIZE
+ jne L(fraction_some)
+
+ movl %edi, %eax
+L(fraction_done):
+ movl VAR_NORM, %ecx
+L(zero_done):
+ movl SAVE_EBP, %ebp
+
+ movl SAVE_EDI, %edi
+ movl SAVE_ESI, %esi
+
+ movl SAVE_EBX, %ebx
+ addl $STACK_SPACE, %esp
+
+ shrl %cl, %eax
+ emms
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+C
+C Special case for q1=0xFFFFFFFF, giving q=0xFFFFFFFF meaning the low dword
+C of q*d is simply -d and the remainder n-q*d = n10+d
+
+L(q1_ff):
+ C eax (divisor)
+ C ebx (q1+1 == 0)
+ C ecx
+ C edx
+ C esi n10
+ C edi n2
+ C ebp divisor
+
+ movl VAR_DST, %ecx
+ movl VAR_DST_STOP, %edx
+ subl $4, %ecx
+
+ psrlq %mm7, %mm0
+ leal (%ebp,%esi), %edi C n-q*d remainder -> next n2
+ movl %ecx, VAR_DST
+
+ movd %mm0, %esi C next n10
+
+ movl $-1, (%ecx)
+ cmpl %ecx, %edx
+ jne L(integer_top)
+
+ jmp L(integer_loop_done)
+
+
+
+C -----------------------------------------------------------------------------
+C
+C Being the fractional part, the "source" limbs are all zero, meaning
+C n10=0, n1=0, and hence nadj=0, leading to many instructions eliminated.
+C
+C The loop runs at 15 cycles. The dependent chain is the same as the
+C general case above, but without the n2+n1 stage (due to n1==0), so 15
+C would seem to be the lower bound.
+C
+C A not entirely obvious simplification is that q1+1 never overflows a limb,
+C and so there's no need for the sbbl $0 or jz q1_ff from the general case.
+C q1 is the high word of m*n2+b*n2 and the following shows q1<=b-2 always.
+C rnd() means rounding down to a multiple of d.
+C
+C m*n2 + b*n2 <= m*(d-1) + b*(d-1)
+C = m*d + b*d - m - b
+C = floor((b(b-d)-1)/d)*d + b*d - m - b
+C = rnd(b(b-d)-1) + b*d - m - b
+C = rnd(b(b-d)-1 + b*d) - m - b
+C = rnd(b*b-1) - m - b
+C <= (b-2)*b
+C
+C Unchanged from the general case is that the final quotient limb q can be
+C either q1 or q1+1, and the q1+1 case occurs often. This can be seen from
+C equation 8.4 of the paper which simplifies as follows when n1==0 and
+C n0==0.
+C
+C n-q1*d = (n2*k+q0*d)/b <= d + (d*d-2d)/b
+C
+C As before, the instruction groupings and empty comments show a naive
+C in-order view of the code, which is made a nonsense by out of order
+C execution. There's 17 cycles shown, but it executes at 15.
+C
+C Rotating the store q and remainder->n2 instructions up to the top of the
+C loop gets the run time down from 16 to 15.
+
+ ALIGN(16)
+L(fraction_some):
+ C eax
+ C ebx
+ C ecx
+ C edx
+ C esi
+ C edi carry
+ C ebp divisor
+
+ movl PARAM_DST, %esi
+ movl VAR_DST_STOP, %ecx C &dst[xsize+2]
+ movl %edi, %eax
+
+ subl $8, %ecx C &dst[xsize]
+ jmp L(fraction_entry)
+
+
+ ALIGN(16)
+L(fraction_top):
+ C eax n2 carry, then scratch
+ C ebx scratch (nadj, q1)
+ C ecx dst, decrementing
+ C edx scratch
+ C esi dst stop point
+ C edi (will be n2)
+ C ebp divisor
+
+ movl %ebx, (%ecx) C previous q
+ movl %eax, %edi C remainder->n2
+
+L(fraction_entry):
+ mull VAR_INVERSE C m*n2
+
+ movl %ebp, %eax C d
+ subl $4, %ecx C dst
+ leal 1(%edi), %ebx
+
+ C
+
+ C
+
+ C
+
+ C
+
+ addl %edx, %ebx C 1 + high(n2<<32 + m*n2) = q1+1
+
+ mull %ebx C (q1+1)*d
+
+ C
+
+ C
+
+ C
+
+ negl %eax C low of n - (q1+1)*d
+
+ C
+
+ sbbl %edx, %edi C high of n - (q1+1)*d, caring only about carry
+ leal (%ebp,%eax), %edx
+
+ cmovc( %edx, %eax) C n - q1*d if underflow from using q1+1
+ sbbl $0, %ebx C q
+ cmpl %esi, %ecx
+
+ jne L(fraction_top)
+
+
+ movl %ebx, (%ecx)
+ jmp L(fraction_done)
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mmx/lshift.asm b/gmp/mpn/x86/k7/mmx/lshift.asm
new file mode 100644
index 0000000000..b3383cf2c3
--- /dev/null
+++ b/gmp/mpn/x86/k7/mmx/lshift.asm
@@ -0,0 +1,481 @@
+dnl AMD K7 mpn_lshift -- mpn left shift.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K7: 1.21 cycles/limb (at 16 limbs/loop).
+
+
+
+dnl K7: UNROLL_COUNT cycles/limb
+dnl 4 1.51
+dnl 8 1.26
+dnl 16 1.21
+dnl 32 1.2
+dnl Maximum possible with the current code is 64.
+
+deflit(UNROLL_COUNT, 16)
+
+
+C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C Shift src,size left by shift many bits and store the result in dst,size.
+C Zeros are shifted in at the right. The bits shifted out at the left are
+C the return value.
+C
+C The comments in mpn_rshift apply here too.
+
+ifdef(`PIC',`
+deflit(UNROLL_THRESHOLD, 10)
+',`
+deflit(UNROLL_THRESHOLD, 10)
+')
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+defframe(SAVE_EDI, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EBX, -12)
+deflit(SAVE_SIZE, 12)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(mpn_lshift)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %eax
+ movl PARAM_SRC, %edx
+ subl $SAVE_SIZE, %esp
+deflit(`FRAME',SAVE_SIZE)
+
+ movl PARAM_SHIFT, %ecx
+ movl %edi, SAVE_EDI
+
+ movl PARAM_DST, %edi
+ decl %eax
+ jnz L(more_than_one_limb)
+
+ movl (%edx), %edx
+
+ shldl( %cl, %edx, %eax) C eax was decremented to zero
+
+ shll %cl, %edx
+
+ movl %edx, (%edi)
+ movl SAVE_EDI, %edi
+ addl $SAVE_SIZE, %esp
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(more_than_one_limb):
+ C eax size-1
+ C ebx
+ C ecx shift
+ C edx src
+ C esi
+ C edi dst
+ C ebp
+
+ movd PARAM_SHIFT, %mm6
+ movd (%edx,%eax,4), %mm5 C src high limb
+ cmp $UNROLL_THRESHOLD-1, %eax
+
+ jae L(unroll)
+ negl %ecx
+ movd (%edx), %mm4 C src low limb
+
+ addl $32, %ecx
+
+ movd %ecx, %mm7
+
+L(simple_top):
+ C eax loop counter, limbs
+ C ebx
+ C ecx
+ C edx src
+ C esi
+ C edi dst
+ C ebp
+ C
+ C mm0 scratch
+ C mm4 src low limb
+ C mm5 src high limb
+ C mm6 shift
+ C mm7 32-shift
+
+ movq -4(%edx,%eax,4), %mm0
+ decl %eax
+
+ psrlq %mm7, %mm0
+
+ movd %mm0, 4(%edi,%eax,4)
+ jnz L(simple_top)
+
+
+ psllq %mm6, %mm5
+ psllq %mm6, %mm4
+
+ psrlq $32, %mm5
+ movd %mm4, (%edi) C dst low limb
+
+ movd %mm5, %eax C return value
+
+ movl SAVE_EDI, %edi
+ addl $SAVE_SIZE, %esp
+ emms
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(unroll):
+ C eax size-1
+ C ebx (saved)
+ C ecx shift
+ C edx src
+ C esi
+ C edi dst
+ C ebp
+ C
+ C mm5 src high limb, for return value
+ C mm6 lshift
+
+ movl %esi, SAVE_ESI
+ movl %ebx, SAVE_EBX
+ leal -4(%edx,%eax,4), %edx C &src[size-2]
+
+ testb $4, %dl
+ movq (%edx), %mm1 C src high qword
+
+ jz L(start_src_aligned)
+
+
+ C src isn't aligned, process high limb (marked xxx) separately to
+ C make it so
+ C
+ C source -4(edx,%eax,4)
+ C |
+ C +-------+-------+-------+--
+ C | xxx |
+ C +-------+-------+-------+--
+ C 0mod8 4mod8 0mod8
+ C
+ C dest -4(edi,%eax,4)
+ C |
+ C +-------+-------+--
+ C | xxx | |
+ C +-------+-------+--
+
+ psllq %mm6, %mm1
+ subl $4, %edx
+ movl %eax, PARAM_SIZE C size-1
+
+ psrlq $32, %mm1
+ decl %eax C size-2 is new size-1
+
+ movd %mm1, 4(%edi,%eax,4)
+ movq (%edx), %mm1 C new src high qword
+L(start_src_aligned):
+
+
+ leal -4(%edi,%eax,4), %edi C &dst[size-2]
+ psllq %mm6, %mm5
+
+ testl $4, %edi
+ psrlq $32, %mm5 C return value
+
+ jz L(start_dst_aligned)
+
+
+ C dst isn't aligned, subtract 4 bytes to make it so, and pretend the
+ C shift is 32 bits extra. High limb of dst (marked xxx) handled
+ C here separately.
+ C
+ C source %edx
+ C +-------+-------+--
+ C | mm1 |
+ C +-------+-------+--
+ C 0mod8 4mod8
+ C
+ C dest %edi
+ C +-------+-------+-------+--
+ C | xxx |
+ C +-------+-------+-------+--
+ C 0mod8 4mod8 0mod8
+
+ movq %mm1, %mm0
+ psllq %mm6, %mm1
+ addl $32, %ecx C shift+32
+
+ psrlq $32, %mm1
+
+ movd %mm1, 4(%edi)
+ movq %mm0, %mm1
+ subl $4, %edi
+
+ movd %ecx, %mm6 C new lshift
+L(start_dst_aligned):
+
+ decl %eax C size-2, two last limbs handled at end
+ movq %mm1, %mm2 C copy of src high qword
+ negl %ecx
+
+ andl $-2, %eax C round size down to even
+ addl $64, %ecx
+
+ movl %eax, %ebx
+ negl %eax
+
+ andl $UNROLL_MASK, %eax
+ decl %ebx
+
+ shll %eax
+
+ movd %ecx, %mm7 C rshift = 64-lshift
+
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ leal L(entry) (%eax,%eax,4), %esi
+')
+ shrl $UNROLL_LOG2, %ebx C loop counter
+
+ leal ifelse(UNROLL_BYTES,256,128) -8(%edx,%eax,2), %edx
+ leal ifelse(UNROLL_BYTES,256,128) (%edi,%eax,2), %edi
+ movl PARAM_SIZE, %eax C for use at end
+ jmp *%esi
+
+
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ leal (%eax,%eax,4), %esi
+ addl $L(entry)-L(here), %esi
+ addl (%esp), %esi
+
+ ret_internal
+')
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(32)
+L(top):
+ C eax size (for use at end)
+ C ebx loop counter
+ C ecx rshift
+ C edx src
+ C esi computed jump
+ C edi dst
+ C ebp
+ C
+ C mm0 scratch
+ C mm1 \ carry (alternating, mm2 first)
+ C mm2 /
+ C mm6 lshift
+ C mm7 rshift
+ C
+ C 10 code bytes/limb
+ C
+ C The two chunks differ in whether mm1 or mm2 hold the carry.
+ C The computed jump puts the initial carry in both mm1 and mm2.
+
+L(entry):
+deflit(CHUNK_COUNT, 4)
+forloop(i, 0, UNROLL_COUNT/CHUNK_COUNT-1, `
+ deflit(`disp0', eval(-i*CHUNK_COUNT*4 ifelse(UNROLL_BYTES,256,-128)))
+ deflit(`disp1', eval(disp0 - 8))
+
+Zdisp( movq, disp0,(%edx), %mm0)
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ por %mm2, %mm0
+Zdisp( movq, %mm0, disp0,(%edi))
+
+
+Zdisp( movq, disp1,(%edx), %mm0)
+ psllq %mm6, %mm1
+
+ movq %mm0, %mm2
+ psrlq %mm7, %mm0
+
+ por %mm1, %mm0
+Zdisp( movq, %mm0, disp1,(%edi))
+')
+
+ subl $UNROLL_BYTES, %edx
+ subl $UNROLL_BYTES, %edi
+ decl %ebx
+
+ jns L(top)
+
+
+
+define(`disp', `m4_empty_if_zero(eval($1 ifelse(UNROLL_BYTES,256,-128)))')
+
+L(end):
+ testb $1, %al
+ movl SAVE_EBX, %ebx
+ psllq %mm6, %mm2 C wanted left shifted in all cases below
+
+ movd %mm5, %eax
+
+ movl SAVE_ESI, %esi
+ jz L(end_even)
+
+
+L(end_odd):
+
+ C Size odd, destination was aligned.
+ C
+ C source edx+8 edx+4
+ C --+---------------+-------+
+ C | mm2 | |
+ C --+---------------+-------+
+ C
+ C dest edi
+ C --+---------------+---------------+-------+
+ C | written | | |
+ C --+---------------+---------------+-------+
+ C
+ C mm6 = shift
+ C mm7 = ecx = 64-shift
+
+
+ C Size odd, destination was unaligned.
+ C
+ C source edx+8 edx+4
+ C --+---------------+-------+
+ C | mm2 | |
+ C --+---------------+-------+
+ C
+ C dest edi
+ C --+---------------+---------------+
+ C | written | |
+ C --+---------------+---------------+
+ C
+ C mm6 = shift+32
+ C mm7 = ecx = 64-(shift+32)
+
+
+ C In both cases there's one extra limb of src to fetch and combine
+ C with mm2 to make a qword at (%edi), and in the aligned case
+ C there's an extra limb of dst to be formed from that extra src limb
+ C left shifted.
+
+ movd disp(4) (%edx), %mm0
+ testb $32, %cl
+
+ movq %mm0, %mm1
+ psllq $32, %mm0
+
+ psrlq %mm7, %mm0
+ psllq %mm6, %mm1
+
+ por %mm2, %mm0
+
+ movq %mm0, disp(0) (%edi)
+ jz L(end_odd_unaligned)
+ movd %mm1, disp(-4) (%edi)
+L(end_odd_unaligned):
+
+ movl SAVE_EDI, %edi
+ addl $SAVE_SIZE, %esp
+ emms
+
+ ret
+
+
+L(end_even):
+
+ C Size even, destination was aligned.
+ C
+ C source edx+8
+ C --+---------------+
+ C | mm2 |
+ C --+---------------+
+ C
+ C dest edi
+ C --+---------------+---------------+
+ C | written | |
+ C --+---------------+---------------+
+ C
+ C mm6 = shift
+ C mm7 = ecx = 64-shift
+
+
+ C Size even, destination was unaligned.
+ C
+ C source edx+8
+ C --+---------------+
+ C | mm2 |
+ C --+---------------+
+ C
+ C dest edi+4
+ C --+---------------+-------+
+ C | written | |
+ C --+---------------+-------+
+ C
+ C mm6 = shift+32
+ C mm7 = ecx = 64-(shift+32)
+
+
+ C The movq for the aligned case overwrites the movd for the
+ C unaligned case.
+
+ movq %mm2, %mm0
+ psrlq $32, %mm2
+
+ testb $32, %cl
+ movd %mm2, disp(4) (%edi)
+
+ jz L(end_even_unaligned)
+ movq %mm0, disp(0) (%edi)
+L(end_even_unaligned):
+
+ movl SAVE_EDI, %edi
+ addl $SAVE_SIZE, %esp
+ emms
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mmx/popham.asm b/gmp/mpn/x86/k7/mmx/popham.asm
new file mode 100644
index 0000000000..95965b74d4
--- /dev/null
+++ b/gmp/mpn/x86/k7/mmx/popham.asm
@@ -0,0 +1,213 @@
+dnl AMD K7 mpn_popcount, mpn_hamdist -- population count and hamming
+dnl distance.
+
+dnl Copyright 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C popcount hamdist
+C P3 generic 6.5 7
+C P3 model 9 (Banias) 5.7 6.1
+C P3 model 13 (Dothan) 5.75 6
+C K7 5 6
+
+C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
+C unsigned long mpn_hamdist (mp_srcptr src, mp_srcptr src2, mp_size_t size);
+C
+C The code here is almost certainly not optimal, but is already a 3x speedup
+C over the generic C code. The main improvement would be to interleave
+C processing of two qwords in the loop so as to fully exploit the available
+C execution units, possibly leading to 3.25 c/l (13 cycles for 4 limbs).
+C
+C The loop is based on the example "Efficient 64-bit population count using
+C MMX instructions" in the Athlon Optimization Guide, AMD document 22007,
+C page 158 of rev E (reference in mpn/x86/k7/README).
+
+ifdef(`OPERATION_popcount',,
+`ifdef(`OPERATION_hamdist',,
+`m4_error(`Need OPERATION_popcount or OPERATION_hamdist defined
+')')')
+
+define(HAM,
+m4_assert_numargs(1)
+`ifdef(`OPERATION_hamdist',`$1')')
+
+define(POP,
+m4_assert_numargs(1)
+`ifdef(`OPERATION_popcount',`$1')')
+
+HAM(`
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC2, 8)
+defframe(PARAM_SRC, 4)
+define(M4_function,mpn_hamdist)
+')
+POP(`
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+define(M4_function,mpn_popcount)
+')
+
+MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
+
+
+ifdef(`PIC',,`
+ dnl non-PIC
+
+ RODATA
+ ALIGN(8)
+
+L(rodata_AAAAAAAAAAAAAAAA):
+ .long 0xAAAAAAAA
+ .long 0xAAAAAAAA
+
+L(rodata_3333333333333333):
+ .long 0x33333333
+ .long 0x33333333
+
+L(rodata_0F0F0F0F0F0F0F0F):
+ .long 0x0F0F0F0F
+ .long 0x0F0F0F0F
+')
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(M4_function)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+
+ifdef(`PIC',`
+ movl $0xAAAAAAAA, %eax
+ movl $0x33333333, %edx
+
+ movd %eax, %mm7
+ movd %edx, %mm6
+
+ movl $0x0F0F0F0F, %eax
+
+ punpckldq %mm7, %mm7
+ punpckldq %mm6, %mm6
+
+ movd %eax, %mm5
+ movd %edx, %mm4
+
+ punpckldq %mm5, %mm5
+
+',`
+ movq L(rodata_AAAAAAAAAAAAAAAA), %mm7
+ movq L(rodata_3333333333333333), %mm6
+ movq L(rodata_0F0F0F0F0F0F0F0F), %mm5
+')
+ pxor %mm4, %mm4
+
+define(REG_AAAAAAAAAAAAAAAA,%mm7)
+define(REG_3333333333333333,%mm6)
+define(REG_0F0F0F0F0F0F0F0F,%mm5)
+define(REG_0000000000000000,%mm4)
+
+
+ movl PARAM_SRC, %eax
+HAM(` movl PARAM_SRC2, %edx')
+
+ pxor %mm2, %mm2 C total
+
+ shrl %ecx
+ jnc L(top)
+
+ movd (%eax,%ecx,8), %mm1
+
+HAM(` movd (%edx,%ecx,8), %mm0
+ pxor %mm0, %mm1
+')
+ orl %ecx, %ecx
+ jmp L(loaded)
+
+
+ ALIGN(16)
+L(top):
+ C eax src
+ C ebx
+ C ecx counter, qwords, decrementing
+ C edx [hamdist] src2
+ C
+ C mm0 (scratch)
+ C mm1 (scratch)
+ C mm2 total (low dword)
+ C mm3
+ C mm4 \
+ C mm5 | special constants
+ C mm6 |
+ C mm7 /
+
+ movq -8(%eax,%ecx,8), %mm1
+
+HAM(` pxor -8(%edx,%ecx,8), %mm1')
+ decl %ecx
+
+L(loaded):
+ movq %mm1, %mm0
+ pand REG_AAAAAAAAAAAAAAAA, %mm1
+
+ psrlq $1, %mm1
+
+ psubd %mm1, %mm0 C bit pairs
+
+
+ movq %mm0, %mm1
+ psrlq $2, %mm0
+
+ pand REG_3333333333333333, %mm0
+ pand REG_3333333333333333, %mm1
+
+ paddd %mm1, %mm0 C nibbles
+
+
+ movq %mm0, %mm1
+ psrlq $4, %mm0
+
+ pand REG_0F0F0F0F0F0F0F0F, %mm0
+ pand REG_0F0F0F0F0F0F0F0F, %mm1
+
+ paddd %mm1, %mm0 C bytes
+
+
+ psadbw( %mm4, %mm0)
+
+ paddd %mm0, %mm2 C add to total
+ jnz L(top)
+
+
+ movd %mm2, %eax
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mmx/rshift.asm b/gmp/mpn/x86/k7/mmx/rshift.asm
new file mode 100644
index 0000000000..345d23a25e
--- /dev/null
+++ b/gmp/mpn/x86/k7/mmx/rshift.asm
@@ -0,0 +1,480 @@
+dnl AMD K7 mpn_rshift -- mpn right shift.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K7: 1.21 cycles/limb (at 16 limbs/loop).
+
+
+
+dnl K7: UNROLL_COUNT cycles/limb
+dnl 4 1.51
+dnl 8 1.26
+dnl 16 1.21
+dnl 32 1.2
+dnl Maximum possible with the current code is 64.
+
+deflit(UNROLL_COUNT, 16)
+
+
+C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C Shift src,size right by shift many bits and store the result in dst,size.
+C Zeros are shifted in at the left. The bits shifted out at the right are
+C the return value.
+C
+C This code uses 64-bit MMX operations, which makes it possible to handle
+C two limbs at a time, for a theoretical 1.0 cycles/limb. Plain integer
+C code, on the other hand, suffers from shrd being a vector path decode and
+C running at 3 cycles back-to-back.
+C
+C Full speed depends on source and destination being aligned, and some hairy
+C setups and finish-ups are done to arrange this for the loop.
+
+ifdef(`PIC',`
+deflit(UNROLL_THRESHOLD, 10)
+',`
+deflit(UNROLL_THRESHOLD, 10)
+')
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+defframe(SAVE_EDI, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EBX, -12)
+deflit(SAVE_SIZE, 12)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(mpn_rshift)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %eax
+ movl PARAM_SRC, %edx
+ subl $SAVE_SIZE, %esp
+deflit(`FRAME',SAVE_SIZE)
+
+ movl PARAM_SHIFT, %ecx
+ movl %edi, SAVE_EDI
+
+ movl PARAM_DST, %edi
+ decl %eax
+ jnz L(more_than_one_limb)
+
+ movl (%edx), %edx C src limb
+
+ shrdl( %cl, %edx, %eax) C eax was decremented to zero
+
+ shrl %cl, %edx
+
+ movl %edx, (%edi) C dst limb
+ movl SAVE_EDI, %edi
+ addl $SAVE_SIZE, %esp
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(more_than_one_limb):
+ C eax size-1
+ C ebx
+ C ecx shift
+ C edx src
+ C esi
+ C edi dst
+ C ebp
+
+ movd PARAM_SHIFT, %mm6 C rshift
+ movd (%edx), %mm5 C src low limb
+ cmp $UNROLL_THRESHOLD-1, %eax
+
+ jae L(unroll)
+ leal (%edx,%eax,4), %edx C &src[size-1]
+ leal -4(%edi,%eax,4), %edi C &dst[size-2]
+
+ movd (%edx), %mm4 C src high limb
+ negl %eax
+
+
+L(simple_top):
+ C eax loop counter, limbs, negative
+ C ebx
+ C ecx shift
+ C edx carry
+ C edx &src[size-1]
+ C edi &dst[size-2]
+ C ebp
+ C
+ C mm0 scratch
+ C mm4 src high limb
+ C mm5 src low limb
+ C mm6 shift
+
+ movq (%edx,%eax,4), %mm0
+ incl %eax
+
+ psrlq %mm6, %mm0
+
+ movd %mm0, (%edi,%eax,4)
+ jnz L(simple_top)
+
+
+ psllq $32, %mm5
+ psrlq %mm6, %mm4
+
+ psrlq %mm6, %mm5
+ movd %mm4, 4(%edi) C dst high limb
+
+ movd %mm5, %eax C return value
+
+ movl SAVE_EDI, %edi
+ addl $SAVE_SIZE, %esp
+ emms
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(unroll):
+ C eax size-1
+ C ebx
+ C ecx shift
+ C edx src
+ C esi
+ C edi dst
+ C ebp
+ C
+ C mm5 src low limb
+ C mm6 rshift
+
+ testb $4, %dl
+ movl %esi, SAVE_ESI
+ movl %ebx, SAVE_EBX
+
+ psllq $32, %mm5
+ jz L(start_src_aligned)
+
+
+ C src isn't aligned, process low limb separately (marked xxx) and
+ C step src and dst by one limb, making src aligned.
+ C
+ C source edx
+ C --+-------+-------+-------+
+ C | xxx |
+ C --+-------+-------+-------+
+ C 4mod8 0mod8 4mod8
+ C
+ C dest edi
+ C --+-------+-------+
+ C | | xxx |
+ C --+-------+-------+
+
+ movq (%edx), %mm0 C src low two limbs
+ addl $4, %edx
+ movl %eax, PARAM_SIZE C size-1
+
+ addl $4, %edi
+ decl %eax C size-2 is new size-1
+
+ psrlq %mm6, %mm0
+ movl %edi, PARAM_DST C new dst
+
+ movd %mm0, -4(%edi)
+L(start_src_aligned):
+
+
+ movq (%edx), %mm1 C src low two limbs
+ decl %eax C size-2, two last limbs handled at end
+ testl $4, %edi
+
+ psrlq %mm6, %mm5
+ jz L(start_dst_aligned)
+
+
+ C dst isn't aligned, add 4 to make it so, and pretend the shift is
+ C 32 bits extra. Low limb of dst (marked xxx) handled here separately.
+ C
+ C source edx
+ C --+-------+-------+
+ C | mm1 |
+ C --+-------+-------+
+ C 4mod8 0mod8
+ C
+ C dest edi
+ C --+-------+-------+-------+
+ C | xxx |
+ C --+-------+-------+-------+
+ C 4mod8 0mod8 4mod8
+
+ movq %mm1, %mm0
+ psrlq %mm6, %mm1
+ addl $32, %ecx C shift+32
+
+ movd %mm1, (%edi)
+ movq %mm0, %mm1
+ addl $4, %edi C new dst
+
+ movd %ecx, %mm6
+L(start_dst_aligned):
+
+
+ movq %mm1, %mm2 C copy of src low two limbs
+ negl %ecx
+ andl $-2, %eax C round size down to even
+
+ movl %eax, %ebx
+ negl %eax
+ addl $64, %ecx
+
+ andl $UNROLL_MASK, %eax
+ decl %ebx
+
+ shll %eax
+
+ movd %ecx, %mm7 C lshift = 64-rshift
+
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ leal L(entry) (%eax,%eax,4), %esi
+ negl %eax
+')
+ shrl $UNROLL_LOG2, %ebx C loop counter
+
+ leal ifelse(UNROLL_BYTES,256,128+) 8(%edx,%eax,2), %edx
+ leal ifelse(UNROLL_BYTES,256,128) (%edi,%eax,2), %edi
+ movl PARAM_SIZE, %eax C for use at end
+
+ jmp *%esi
+
+
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ leal (%eax,%eax,4), %esi
+ addl $L(entry)-L(here), %esi
+ addl (%esp), %esi
+ negl %eax
+
+ ret_internal
+')
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(64)
+L(top):
+ C eax size, for use at end
+ C ebx loop counter
+ C ecx lshift
+ C edx src
+ C esi was computed jump
+ C edi dst
+ C ebp
+ C
+ C mm0 scratch
+ C mm1 \ carry (alternating)
+ C mm2 /
+ C mm6 rshift
+ C mm7 lshift
+ C
+ C 10 code bytes/limb
+ C
+ C The two chunks differ in whether mm1 or mm2 hold the carry.
+ C The computed jump puts the initial carry in both mm1 and mm2.
+
+L(entry):
+deflit(CHUNK_COUNT, 4)
+forloop(i, 0, UNROLL_COUNT/CHUNK_COUNT-1, `
+ deflit(`disp0', eval(i*CHUNK_COUNT*4 ifelse(UNROLL_BYTES,256,-128)))
+ deflit(`disp1', eval(disp0 + 8))
+
+Zdisp( movq, disp0,(%edx), %mm0)
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ por %mm2, %mm0
+Zdisp( movq, %mm0, disp0,(%edi))
+
+
+Zdisp( movq, disp1,(%edx), %mm0)
+ psrlq %mm6, %mm1
+
+ movq %mm0, %mm2
+ psllq %mm7, %mm0
+
+ por %mm1, %mm0
+Zdisp( movq, %mm0, disp1,(%edi))
+')
+
+ addl $UNROLL_BYTES, %edx
+ addl $UNROLL_BYTES, %edi
+ decl %ebx
+
+ jns L(top)
+
+
+deflit(`disp0', ifelse(UNROLL_BYTES,256,-128))
+deflit(`disp1', eval(disp0-0 + 8))
+
+ testb $1, %al
+ psrlq %mm6, %mm2 C wanted rshifted in all cases below
+ movl SAVE_ESI, %esi
+
+ movd %mm5, %eax C return value
+
+ movl SAVE_EBX, %ebx
+ jz L(end_even)
+
+
+ C Size odd, destination was aligned.
+ C
+ C source
+ C edx
+ C +-------+---------------+--
+ C | | mm2 |
+ C +-------+---------------+--
+ C
+ C dest edi
+ C +-------+---------------+---------------+--
+ C | | | written |
+ C +-------+---------------+---------------+--
+ C
+ C mm6 = shift
+ C mm7 = ecx = 64-shift
+
+
+ C Size odd, destination was unaligned.
+ C
+ C source
+ C edx
+ C +-------+---------------+--
+ C | | mm2 |
+ C +-------+---------------+--
+ C
+ C dest edi
+ C +---------------+---------------+--
+ C | | written |
+ C +---------------+---------------+--
+ C
+ C mm6 = shift+32
+ C mm7 = ecx = 64-(shift+32)
+
+
+ C In both cases there's one extra limb of src to fetch and combine
+ C with mm2 to make a qword to store, and in the aligned case there's
+ C a further extra limb of dst to be formed.
+
+
+ movd disp0(%edx), %mm0
+ movq %mm0, %mm1
+
+ psllq %mm7, %mm0
+ testb $32, %cl
+
+ por %mm2, %mm0
+ psrlq %mm6, %mm1
+
+ movq %mm0, disp0(%edi)
+ jz L(finish_odd_unaligned)
+
+ movd %mm1, disp1(%edi)
+L(finish_odd_unaligned):
+
+ movl SAVE_EDI, %edi
+ addl $SAVE_SIZE, %esp
+ emms
+
+ ret
+
+
+L(end_even):
+
+ C Size even, destination was aligned.
+ C
+ C source
+ C +---------------+--
+ C | mm2 |
+ C +---------------+--
+ C
+ C dest edi
+ C +---------------+---------------+--
+ C | | mm3 |
+ C +---------------+---------------+--
+ C
+ C mm6 = shift
+ C mm7 = ecx = 64-shift
+
+
+ C Size even, destination was unaligned.
+ C
+ C source
+ C +---------------+--
+ C | mm2 |
+ C +---------------+--
+ C
+ C dest edi
+ C +-------+---------------+--
+ C | | mm3 |
+ C +-------+---------------+--
+ C
+ C mm6 = shift+32
+ C mm7 = 64-(shift+32)
+
+
+ C The movd for the unaligned case is the same data as the movq for
+ C the aligned case, it's just a choice between whether one or two
+ C limbs should be written.
+
+
+ testb $32, %cl
+ movd %mm2, disp0(%edi)
+
+ jz L(end_even_unaligned)
+
+ movq %mm2, disp0(%edi)
+L(end_even_unaligned):
+
+ movl SAVE_EDI, %edi
+ addl $SAVE_SIZE, %esp
+ emms
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mod_1_1.asm b/gmp/mpn/x86/k7/mod_1_1.asm
new file mode 100644
index 0000000000..1bbe6f92d7
--- /dev/null
+++ b/gmp/mpn/x86/k7/mod_1_1.asm
@@ -0,0 +1,221 @@
+dnl x86-32 mpn_mod_1_1p, requiring cmov.
+
+dnl Contributed to the GNU project by Niels Möller and Torbjorn Granlund.
+
+dnl Copyright 2010, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C P5 ?
+C P6 model 0-8,10-12 ?
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) ?
+C P4 model 0 (Willamette) ?
+C P4 model 1 (?) ?
+C P4 model 2 (Northwood) ?
+C P4 model 3 (Prescott) ?
+C P4 model 4 (Nocona) ?
+C AMD K6 ?
+C AMD K7 7
+C AMD K8 ?
+
+define(`B2mb', `%ebx')
+define(`r0', `%esi')
+define(`r2', `%ebp')
+define(`t0', `%edi')
+define(`ap', `%ecx') C Also shift count
+
+C Stack frame
+C pre 36(%esp)
+C b 32(%esp)
+C n 28(%esp)
+C ap 24(%esp)
+C return 20(%esp)
+C %ebp 16(%esp)
+C %edi 12(%esp)
+C %esi 8(%esp)
+C %ebx 4(%esp)
+C B2mod (%esp)
+
+define(`B2modb', `(%esp)')
+define(`n', `28(%esp)')
+define(`b', `32(%esp)')
+define(`pre', `36(%esp)')
+
+C mp_limb_t
+C mpn_mod_1_1p (mp_srcptr ap, mp_size_t n, mp_limb_t b, mp_limb_t pre[4])
+C
+C The pre array contains bi, cnt, B1modb, B2modb
+C Note: This implementation needs B1modb only when cnt > 0
+
+ASM_START()
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_mod_1_1p)
+ push %ebp
+ push %edi
+ push %esi
+ push %ebx
+ mov 32(%esp), %ebp C pre[]
+
+ mov 12(%ebp), %eax C B2modb
+ push %eax C Put it on stack
+
+ mov n, %edx
+ mov 24(%esp), ap
+
+ lea (ap, %edx, 4), ap
+ mov -4(ap), %eax
+ cmp $3, %edx
+ jnc L(first)
+ mov -8(ap), r0
+ jmp L(reduce_two)
+
+L(first):
+ C First iteration, no r2
+ mull B2modb
+ mov -12(ap), r0
+ add %eax, r0
+ mov -8(ap), %eax
+ adc %edx, %eax
+ sbb r2, r2
+ subl $3, n
+ lea -16(ap), ap
+ jz L(reduce_three)
+
+ mov B2modb, B2mb
+ sub b, B2mb
+ lea (B2mb, r0), t0
+ jmp L(mid)
+
+ ALIGN(16)
+L(top): C Loopmixed to 7 c/l on k7
+ add %eax, r0
+ lea (B2mb, r0), t0
+ mov r2, %eax
+ adc %edx, %eax
+ sbb r2, r2
+L(mid): mull B2modb
+ and B2modb, r2
+ add r0, r2
+ decl n
+ mov (ap), r0
+ cmovc( t0, r2)
+ lea -4(ap), ap
+ jnz L(top)
+
+ add %eax, r0
+ mov r2, %eax
+ adc %edx, %eax
+ sbb r2, r2
+
+L(reduce_three):
+ C Eliminate r2
+ and b, r2
+ sub r2, %eax
+
+L(reduce_two):
+ mov pre, %ebp
+ movb 4(%ebp), %cl
+ test %cl, %cl
+ jz L(normalized)
+
+ C Unnormalized, use B1modb to reduce to size < B b
+ mull 8(%ebp)
+ xor t0, t0
+ add %eax, r0
+ adc %edx, t0
+ mov t0, %eax
+
+ C Left-shift to normalize
+ shld %cl, r0, %eax C Always use shld?
+
+ shl %cl, r0
+ jmp L(udiv)
+
+L(normalized):
+ mov %eax, t0
+ sub b, t0
+ cmovnc( t0, %eax)
+
+L(udiv):
+ lea 1(%eax), t0
+ mull (%ebp)
+ mov b, %ebx C Needed in register for lea
+ add r0, %eax
+ adc t0, %edx
+ imul %ebx, %edx
+ sub %edx, r0
+ cmp r0, %eax
+ lea (%ebx, r0), %eax
+ cmovnc( r0, %eax)
+ cmp %ebx, %eax
+ jnc L(fix)
+L(ok): shr %cl, %eax
+
+ add $4, %esp
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+
+ ret
+L(fix): sub %ebx, %eax
+ jmp L(ok)
+EPILOGUE()
+
+PROLOGUE(mpn_mod_1_1p_cps)
+ push %ebp
+ mov 12(%esp), %ebp
+ push %esi
+ bsr %ebp, %ecx
+ push %ebx
+ xor $31, %ecx
+ mov 16(%esp), %esi
+ sal %cl, %ebp
+ mov %ebp, %edx
+ not %edx
+ mov $-1, %eax
+ div %ebp C On K7, invert_limb would be a few cycles faster.
+ mov %eax, (%esi) C store bi
+ mov %ecx, 4(%esi) C store cnt
+ neg %ebp
+ mov $1, %edx
+ shld %cl, %eax, %edx
+ imul %ebp, %edx
+ shr %cl, %edx
+ imul %ebp, %eax
+ mov %edx, 8(%esi) C store B1modb
+ mov %eax, 12(%esi) C store B2modb
+ pop %ebx
+ pop %esi
+ pop %ebp
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mod_1_4.asm b/gmp/mpn/x86/k7/mod_1_4.asm
new file mode 100644
index 0000000000..bb7597edd2
--- /dev/null
+++ b/gmp/mpn/x86/k7/mod_1_4.asm
@@ -0,0 +1,260 @@
+dnl x86-32 mpn_mod_1s_4p, requiring cmov.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2009, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C P5 ?
+C P6 model 0-8,10-12 ?
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) 6
+C P4 model 0 (Willamette) ?
+C P4 model 1 (?) ?
+C P4 model 2 (Northwood) 15.5
+C P4 model 3 (Prescott) ?
+C P4 model 4 (Nocona) ?
+C AMD K6 ?
+C AMD K7 4.75
+C AMD K8 ?
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_1s_4p)
+ push %ebp
+ push %edi
+ push %esi
+ push %ebx
+ sub $28, %esp
+ mov 60(%esp), %edi C cps[]
+ mov 8(%edi), %eax
+ mov 12(%edi), %edx
+ mov 16(%edi), %ecx
+ mov 20(%edi), %esi
+ mov 24(%edi), %edi
+ mov %eax, 4(%esp)
+ mov %edx, 8(%esp)
+ mov %ecx, 12(%esp)
+ mov %esi, 16(%esp)
+ mov %edi, 20(%esp)
+ mov 52(%esp), %eax C n
+ xor %edi, %edi
+ mov 48(%esp), %esi C up
+ lea -12(%esi,%eax,4), %esi
+ and $3, %eax
+ je L(b0)
+ cmp $2, %eax
+ jc L(b1)
+ je L(b2)
+
+L(b3): mov 4(%esi), %eax
+ mull 4(%esp)
+ mov (%esi), %ebp
+ add %eax, %ebp
+ adc %edx, %edi
+ mov 8(%esi), %eax
+ mull 8(%esp)
+ lea -12(%esi), %esi
+ jmp L(m0)
+
+L(b0): mov (%esi), %eax
+ mull 4(%esp)
+ mov -4(%esi), %ebp
+ add %eax, %ebp
+ adc %edx, %edi
+ mov 4(%esi), %eax
+ mull 8(%esp)
+ add %eax, %ebp
+ adc %edx, %edi
+ mov 8(%esi), %eax
+ mull 12(%esp)
+ lea -16(%esi), %esi
+ jmp L(m0)
+
+L(b1): mov 8(%esi), %ebp
+ lea -4(%esi), %esi
+ jmp L(m1)
+
+L(b2): mov 8(%esi), %edi
+ mov 4(%esi), %ebp
+ lea -8(%esi), %esi
+ jmp L(m1)
+
+ ALIGN(16)
+L(top): mov (%esi), %eax
+ mull 4(%esp)
+ mov -4(%esi), %ebx
+ xor %ecx, %ecx
+ add %eax, %ebx
+ adc %edx, %ecx
+ mov 4(%esi), %eax
+ mull 8(%esp)
+ add %eax, %ebx
+ adc %edx, %ecx
+ mov 8(%esi), %eax
+ mull 12(%esp)
+ add %eax, %ebx
+ adc %edx, %ecx
+ lea -16(%esi), %esi
+ mov 16(%esp), %eax
+ mul %ebp
+ add %eax, %ebx
+ adc %edx, %ecx
+ mov 20(%esp), %eax
+ mul %edi
+ mov %ebx, %ebp
+ mov %ecx, %edi
+L(m0): add %eax, %ebp
+ adc %edx, %edi
+L(m1): subl $4, 52(%esp)
+ ja L(top)
+
+L(end): mov 4(%esp), %eax
+ mul %edi
+ mov 60(%esp), %edi
+ add %eax, %ebp
+ adc $0, %edx
+ mov 4(%edi), %ecx
+ mov %edx, %esi
+ mov %ebp, %eax
+ sal %cl, %esi
+ mov %ecx, %ebx
+ neg %ecx
+ shr %cl, %eax
+ or %esi, %eax
+ lea 1(%eax), %esi
+ mull (%edi)
+ mov %ebx, %ecx
+ mov %eax, %ebx
+ mov %ebp, %eax
+ mov 56(%esp), %ebp
+ sal %cl, %eax
+ add %eax, %ebx
+ adc %esi, %edx
+ imul %ebp, %edx
+ sub %edx, %eax
+ lea (%eax,%ebp), %edx
+ cmp %eax, %ebx
+ cmovc( %edx, %eax)
+ mov %eax, %edx
+ sub %ebp, %eax
+ cmovc( %edx, %eax)
+ add $28, %esp
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+ shr %cl, %eax
+ ret
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_mod_1s_4p_cps)
+C CAUTION: This is the same code as in pentium4/sse2/mod_1_4.asm
+ push %ebp
+ push %edi
+ push %esi
+ push %ebx
+ mov 20(%esp), %ebp C FIXME: avoid bp for 0-idx
+ mov 24(%esp), %ebx
+ bsr %ebx, %ecx
+ xor $31, %ecx
+ sal %cl, %ebx C b << cnt
+ mov %ebx, %edx
+ not %edx
+ mov $-1, %eax
+ div %ebx
+ xor %edi, %edi
+ sub %ebx, %edi
+ mov $1, %esi
+ mov %eax, (%ebp) C store bi
+ mov %ecx, 4(%ebp) C store cnt
+ shld %cl, %eax, %esi
+ imul %edi, %esi
+ mov %eax, %edi
+ mul %esi
+
+ add %esi, %edx
+ shr %cl, %esi
+ mov %esi, 8(%ebp) C store B1modb
+
+ not %edx
+ imul %ebx, %edx
+ lea (%edx,%ebx), %esi
+ cmp %edx, %eax
+ cmovnc( %edx, %esi)
+ mov %edi, %eax
+ mul %esi
+
+ add %esi, %edx
+ shr %cl, %esi
+ mov %esi, 12(%ebp) C store B2modb
+
+ not %edx
+ imul %ebx, %edx
+ lea (%edx,%ebx), %esi
+ cmp %edx, %eax
+ cmovnc( %edx, %esi)
+ mov %edi, %eax
+ mul %esi
+
+ add %esi, %edx
+ shr %cl, %esi
+ mov %esi, 16(%ebp) C store B3modb
+
+ not %edx
+ imul %ebx, %edx
+ lea (%edx,%ebx), %esi
+ cmp %edx, %eax
+ cmovnc( %edx, %esi)
+ mov %edi, %eax
+ mul %esi
+
+ add %esi, %edx
+ shr %cl, %esi
+ mov %esi, 20(%ebp) C store B4modb
+
+ not %edx
+ imul %ebx, %edx
+ add %edx, %ebx
+ cmp %edx, %eax
+ cmovnc( %edx, %ebx)
+
+ shr %cl, %ebx
+ mov %ebx, 24(%ebp) C store B5modb
+
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mod_34lsub1.asm b/gmp/mpn/x86/k7/mod_34lsub1.asm
new file mode 100644
index 0000000000..ee3ad04099
--- /dev/null
+++ b/gmp/mpn/x86/k7/mod_34lsub1.asm
@@ -0,0 +1,188 @@
+dnl AMD K7 mpn_mod_34lsub1 -- remainder modulo 2^24-1.
+
+dnl Copyright 2000-2002, 2004, 2005, 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C Athlon: 1
+C Hammer: 1
+
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr src, mp_size_t size)
+C
+C The loop form below and the 64 byte code alignment seem necessary for the
+C claimed speed. This is a bit strange, since normally k7 isn't very
+C sensitive to such things. Perhaps there has to be 6 instructions in the
+C first 16 bytes for the BTB entry or something.
+
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+dnl re-use parameter space
+define(SAVE_EDI, `PARAM_SIZE')
+
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_mod_34lsub1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %edx
+
+ subl $2, %ecx
+ ja L(three_or_more)
+
+ movl (%edx), %eax
+ jb L(one)
+
+ movl 4(%edx), %ecx
+ movl %eax, %edx
+ shrl $24, %eax C src[0] low
+
+ andl $0xFFFFFF, %edx C src[0] high
+ addl %edx, %eax
+ movl %ecx, %edx
+
+ andl $0xFFFF, %ecx
+ shrl $16, %edx C src[1] high
+ addl %edx, %eax
+
+ shll $8, %ecx C src[1] low
+ addl %ecx, %eax
+
+L(one):
+ ret
+
+
+L(three_or_more):
+ C eax
+ C ebx
+ C ecx size-2
+ C edx src
+ C esi
+ C edi
+
+ pushl %ebx FRAME_pushl()
+ xorl %eax, %eax
+ xorl %ebx, %ebx
+
+ movl %edi, SAVE_EDI
+ pushl %esi FRAME_pushl()
+ xorl %esi, %esi C and clear carry flag
+
+
+ C code offset 0x40 at this point
+L(top):
+ C eax acc 0mod3
+ C ebx acc 1mod3
+ C ecx counter, limbs
+ C edx src
+ C esi acc 2mod3
+ C edi
+
+ leal 24(%edx), %edx
+ leal -2(%ecx), %ecx
+ adcl -24(%edx), %eax
+ adcl -20(%edx), %ebx
+ adcl -16(%edx), %esi
+
+ decl %ecx
+ jng L(done_loop)
+
+ leal -2(%ecx), %ecx
+ adcl -12(%edx), %eax
+ adcl -8(%edx), %ebx
+ adcl -4(%edx), %esi
+
+ decl %ecx
+ jg L(top)
+
+
+ leal 12(%edx), %edx
+
+
+L(done_loop):
+ C ecx is -2, -1 or 0 representing 0, 1 or 2 more limbs, respectively
+
+ incl %ecx
+ movl $0xFFFFFFFF, %edi
+ js L(combine)
+
+ adcl -12(%edx), %eax
+ decl %ecx
+ movl $0xFFFFFF00, %edi
+ js L(combine)
+
+ adcl -8(%edx), %ebx
+ movl $0xFFFF0000, %edi
+
+
+L(combine):
+ C eax acc 0mod3
+ C ebx acc 1mod3
+ C ecx
+ C edx
+ C esi acc 2mod3
+ C edi mask
+
+ sbbl %ecx, %ecx C carry
+ movl %eax, %edx C 0mod3
+ shrl $24, %eax C 0mod3 high
+
+ andl %edi, %ecx C carry masked
+ andl $0x00FFFFFF, %edx C 0mod3 low
+ movl %ebx, %edi C 1mod3
+
+ subl %ecx, %eax C apply carry
+ shrl $16, %ebx C 1mod3 high
+ andl $0xFFFF, %edi
+
+ addl %edx, %eax C apply 0mod3 low
+ movl %esi, %edx C 2mod3
+ shll $8, %edi C 1mod3 low
+
+ addl %ebx, %eax C apply 1mod3 high
+ shrl $8, %esi C 2mod3 high
+ movzbl %dl, %edx C 2mod3 low
+
+ addl %edi, %eax C apply 1mod3 low
+ shll $16, %edx C 2mod3 low
+
+ addl %esi, %eax C apply 2mod3 high
+ popl %esi FRAME_popl()
+
+ movl SAVE_EDI, %edi
+ addl %edx, %eax C apply 2mod3 low
+ popl %ebx FRAME_popl()
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mode1o.asm b/gmp/mpn/x86/k7/mode1o.asm
new file mode 100644
index 0000000000..6472ec5949
--- /dev/null
+++ b/gmp/mpn/x86/k7/mode1o.asm
@@ -0,0 +1,180 @@
+dnl AMD K7 mpn_modexact_1_odd -- exact division style remainder.
+
+dnl Copyright 2000-2002, 2004, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C Athlon: 11.0
+C Hammer: 7.0
+
+
+C mp_limb_t mpn_modexact_1_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C
+C With the loop running at just 11 cycles it doesn't seem worth bothering to
+C check for high<divisor to save one step.
+C
+C Using a divl for size==1 measures slower than the modexact method, which
+C is not too surprising since for the latter it's only about 24 cycles to
+C calculate the modular inverse.
+
+defframe(PARAM_CARRY, 16)
+defframe(PARAM_DIVISOR,12)
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+
+deflit(STACK_SPACE, 16)
+
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(mpn_modexact_1c_odd)
+deflit(`FRAME',0)
+
+ movl PARAM_CARRY, %ecx
+ jmp L(start_1c)
+
+EPILOGUE()
+
+
+ ALIGN(16)
+PROLOGUE(mpn_modexact_1_odd)
+deflit(`FRAME',0)
+
+ xorl %ecx, %ecx
+L(start_1c):
+ movl PARAM_DIVISOR, %eax
+ subl $STACK_SPACE, %esp FRAME_subl_esp(STACK_SPACE)
+
+ movl %esi, SAVE_ESI
+ movl PARAM_DIVISOR, %esi
+
+ movl %edi, SAVE_EDI
+
+ shrl %eax C d/2
+
+ andl $127, %eax
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %edi)
+ movzbl (%eax,%edi), %edi C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %edi C inv 8 bits
+')
+
+ xorl %edx, %edx C initial extra carry
+ leal (%edi,%edi), %eax C 2*inv
+
+ imull %edi, %edi C inv*inv
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_SIZE, %ebp
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_SRC, %ebx
+
+ imull %esi, %edi C inv*inv*d
+
+ subl %edi, %eax C inv = 2*inv - inv*inv*d
+ leal (%eax,%eax), %edi C 2*inv
+
+ imull %eax, %eax C inv*inv
+
+ imull %esi, %eax C inv*inv*d
+
+ leal (%ebx,%ebp,4), %ebx C src end
+ negl %ebp C -size
+
+ subl %eax, %edi C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C d*inv == 1 mod 2^GMP_LIMB_BITS
+ movl %esi, %eax
+ imull %edi, %eax
+ cmpl $1, %eax')
+
+
+C The dependent chain here is
+C
+C cycles
+C subl %edx, %eax 1
+C imull %edi, %eax 4
+C mull %esi 6 (high limb)
+C ----
+C total 11
+C
+C Out of order execution hides the load latency for the source data, so no
+C special scheduling is required.
+
+L(top):
+ C eax src limb
+ C ebx src end ptr
+ C ecx next carry bit, 0 or 1 (or initial carry param)
+ C edx carry limb, high of last product
+ C esi divisor
+ C edi inverse
+ C ebp counter, limbs, negative
+
+ movl (%ebx,%ebp,4), %eax
+
+ subl %ecx, %eax C apply carry bit
+ movl $0, %ecx
+
+ setc %cl C new carry bit
+
+ subl %edx, %eax C apply carry limb
+ adcl $0, %ecx
+
+ imull %edi, %eax
+
+ mull %esi
+
+ incl %ebp
+ jnz L(top)
+
+
+ movl SAVE_ESI, %esi
+ movl SAVE_EDI, %edi
+ leal (%ecx,%edx), %eax
+
+ movl SAVE_EBX, %ebx
+ movl SAVE_EBP, %ebp
+ addl $STACK_SPACE, %esp
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/mul_1.asm b/gmp/mpn/x86/k7/mul_1.asm
new file mode 100644
index 0000000000..755cd2ed50
--- /dev/null
+++ b/gmp/mpn/x86/k7/mul_1.asm
@@ -0,0 +1,237 @@
+dnl AMD K7 mpn_mul_1.
+
+dnl Copyright 1999-2002, 2005, 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12)
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C AMD K6
+C AMD K7 3.25
+C AMD K8
+
+C TODO
+C * Improve feed-in and wind-down code. We beat the old code for all n != 1,
+C but we might be able to do even better.
+C * The feed-in code for mul_1c is crude.
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_1c)
+ add $-16, %esp
+ mov %ebp, (%esp)
+ mov %ebx, 4(%esp)
+ mov %esi, 8(%esp)
+ mov %edi, 12(%esp)
+
+ mov 20(%esp), %edi
+ mov 24(%esp), %esi
+ mov 28(%esp), %ebp
+ mov 32(%esp), %ecx
+ mov %ebp, %ebx
+ shr $2, %ebp
+ mov %ebp, 28(%esp)
+ mov (%esi), %eax
+ and $3, %ebx
+ jz L(c0)
+ cmp $2, %ebx
+ mov 36(%esp), %ebx
+ jz L(c2)
+ jg L(c3)
+
+L(c1): lea -4(%edi), %edi
+ mul %ecx
+ test %ebp, %ebp
+ jnz 1f
+ add %ebx, %eax
+ mov %eax, 4(%edi)
+ mov %edx, %eax
+ adc %ebp, %eax
+ jmp L(rt)
+1: add %eax, %ebx
+ mov $0, %ebp
+ adc %edx, %ebp
+ mov 4(%esi), %eax
+ jmp L(1)
+
+L(c2): lea 4(%esi), %esi
+ mul %ecx
+ test %ebp, %ebp
+ mov %ebx, %ebp
+ jnz 2f
+ add %eax, %ebp
+ mov $0, %ebx
+ adc %edx, %ebx
+ mov (%esi), %eax
+ jmp L(cj2)
+2: add %eax, %ebp
+ mov $0, %ebx
+ adc %edx, %ebx
+ mov (%esi), %eax
+ jmp L(2)
+
+L(c3): lea 8(%esi), %esi
+ lea -12(%edi), %edi
+ mul %ecx
+ add %eax, %ebx
+ mov $0, %ebp
+ adc %edx, %ebp
+ mov -4(%esi), %eax
+ incl 28(%esp)
+ jmp L(3)
+
+L(c0): mov 36(%esp), %ebx
+ lea -4(%esi), %esi
+ lea -8(%edi), %edi
+ mul %ecx
+ mov %ebx, %ebp
+ add %eax, %ebp
+ mov $0, %ebx
+ adc %edx, %ebx
+ mov 8(%esi), %eax
+ jmp L(0)
+
+EPILOGUE()
+ ALIGN(16)
+PROLOGUE(mpn_mul_1)
+ add $-16, %esp
+ mov %ebp, (%esp)
+ mov %ebx, 4(%esp)
+ mov %esi, 8(%esp)
+ mov %edi, 12(%esp)
+
+ mov 20(%esp), %edi
+ mov 24(%esp), %esi
+ mov 28(%esp), %ebp
+ mov 32(%esp), %ecx
+ mov %ebp, %ebx
+ shr $2, %ebp
+ mov %ebp, 28(%esp)
+ mov (%esi), %eax
+ and $3, %ebx
+ jz L(b0)
+ cmp $2, %ebx
+ jz L(b2)
+ jg L(b3)
+
+L(b1): lea -4(%edi), %edi
+ mul %ecx
+ test %ebp, %ebp
+ jnz L(gt1)
+ mov %eax, 4(%edi)
+ mov %edx, %eax
+ jmp L(rt)
+L(gt1): mov %eax, %ebx
+ mov %edx, %ebp
+ mov 4(%esi), %eax
+ jmp L(1)
+
+L(b2): lea 4(%esi), %esi
+ mul %ecx
+ test %ebp, %ebp
+ mov %eax, %ebp
+ mov %edx, %ebx
+ mov (%esi), %eax
+ jnz L(2)
+ jmp L(cj2)
+
+L(b3): lea 8(%esi), %esi
+ lea -12(%edi), %edi
+ mul %ecx
+ mov %eax, %ebx
+ mov %edx, %ebp
+ mov -4(%esi), %eax
+ incl 28(%esp)
+ jmp L(3)
+
+L(b0): lea -4(%esi), %esi
+ lea -8(%edi), %edi
+ mul %ecx
+ mov %eax, %ebp
+ mov %edx, %ebx
+ mov 8(%esi), %eax
+ jmp L(0)
+
+ ALIGN(16)
+L(top): mov $0, %ebx
+ adc %edx, %ebx
+L(2): mul %ecx
+ add %eax, %ebx
+ mov %ebp, 0(%edi)
+ mov 4(%esi), %eax
+ mov $0, %ebp
+ adc %edx, %ebp
+L(1): mul %ecx
+ add %eax, %ebp
+ mov 8(%esi), %eax
+ mov %ebx, 4(%edi)
+ mov $0, %ebx
+ adc %edx, %ebx
+L(0): mov %ebp, 8(%edi)
+ mul %ecx
+ add %eax, %ebx
+ mov 12(%esi), %eax
+ lea 16(%esi), %esi
+ mov $0, %ebp
+ adc %edx, %ebp
+L(3): mov %ebx, 12(%edi)
+ mul %ecx
+ lea 16(%edi), %edi
+ add %eax, %ebp
+ decl 28(%esp)
+ mov 0(%esi), %eax
+ jnz L(top)
+
+L(end): mov $0, %ebx
+ adc %edx, %ebx
+L(cj2): mul %ecx
+ add %eax, %ebx
+ mov %ebp, (%edi)
+L(cj1): mov %ebx, 4(%edi)
+ adc $0, %edx
+ mov %edx, %eax
+
+L(rt): mov (%esp), %ebp
+ mov 4(%esp), %ebx
+ mov 8(%esp), %esi
+ mov 12(%esp), %edi
+ add $16, %esp
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/k7/mul_basecase.asm b/gmp/mpn/x86/k7/mul_basecase.asm
new file mode 100644
index 0000000000..4dfb500885
--- /dev/null
+++ b/gmp/mpn/x86/k7/mul_basecase.asm
@@ -0,0 +1,602 @@
+dnl AMD K7 mpn_mul_basecase -- multiply two mpn numbers.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K7: approx 4.42 cycles per cross product at around 20x20 limbs (16
+C limbs/loop unrolling).
+
+
+
+dnl K7 UNROLL_COUNT cycles/product (at around 20x20)
+dnl 8 4.67
+dnl 16 4.59
+dnl 32 4.42
+dnl Maximum possible with the current code is 32.
+dnl
+dnl At 32 the typical 13-26 limb sizes from the karatsuba code will get
+dnl done with a straight run through a block of code, no inner loop. Using
+dnl 32 gives 1k of code, but the k7 has a 64k L1 code cache.
+
+deflit(UNROLL_COUNT, 32)
+
+
+C void mpn_mul_basecase (mp_ptr wp,
+C mp_srcptr xp, mp_size_t xsize,
+C mp_srcptr yp, mp_size_t ysize);
+C
+C Calculate xp,xsize multiplied by yp,ysize, storing the result in
+C wp,xsize+ysize.
+C
+C This routine is essentially the same as mpn/generic/mul_basecase.c, but
+C it's faster because it does most of the mpn_addmul_1() startup
+C calculations only once. The saving is 15-25% on typical sizes coming from
+C the Karatsuba multiply code.
+
+ifdef(`PIC',`
+deflit(UNROLL_THRESHOLD, 5)
+',`
+deflit(UNROLL_THRESHOLD, 5)
+')
+
+defframe(PARAM_YSIZE,20)
+defframe(PARAM_YP, 16)
+defframe(PARAM_XSIZE,12)
+defframe(PARAM_XP, 8)
+defframe(PARAM_WP, 4)
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mul_basecase)
+deflit(`FRAME',0)
+
+ movl PARAM_XSIZE, %ecx
+ movl PARAM_YP, %eax
+
+ movl PARAM_XP, %edx
+ movl (%eax), %eax C yp low limb
+
+ cmpl $2, %ecx
+ ja L(xsize_more_than_two)
+ je L(two_by_something)
+
+
+ C one limb by one limb
+
+ mull (%edx)
+
+ movl PARAM_WP, %ecx
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(two_by_something):
+deflit(`FRAME',0)
+ decl PARAM_YSIZE
+ pushl %ebx defframe_pushl(`SAVE_EBX')
+ movl %eax, %ecx C yp low limb
+
+ movl PARAM_WP, %ebx
+ pushl %esi defframe_pushl(`SAVE_ESI')
+ movl %edx, %esi C xp
+
+ movl (%edx), %eax C xp low limb
+ jnz L(two_by_two)
+
+
+ C two limbs by one limb
+
+ mull %ecx
+
+ movl %eax, (%ebx)
+ movl 4(%esi), %eax
+ movl %edx, %esi C carry
+
+ mull %ecx
+
+ addl %eax, %esi
+
+ movl %esi, 4(%ebx)
+ movl SAVE_ESI, %esi
+
+ adcl $0, %edx
+
+ movl %edx, 8(%ebx)
+ movl SAVE_EBX, %ebx
+ addl $FRAME, %esp
+
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+C Could load yp earlier into another register.
+
+ ALIGN(16)
+L(two_by_two):
+ C eax xp low limb
+ C ebx wp
+ C ecx yp low limb
+ C edx
+ C esi xp
+ C edi
+ C ebp
+
+dnl FRAME carries on from previous
+
+ mull %ecx C xp[0] * yp[0]
+
+ push %edi defframe_pushl(`SAVE_EDI')
+ movl %edx, %edi C carry, for wp[1]
+
+ movl %eax, (%ebx)
+ movl 4(%esi), %eax
+
+ mull %ecx C xp[1] * yp[0]
+
+ addl %eax, %edi
+ movl PARAM_YP, %ecx
+
+ adcl $0, %edx
+ movl 4(%ecx), %ecx C yp[1]
+ movl %edi, 4(%ebx)
+
+ movl 4(%esi), %eax C xp[1]
+ movl %edx, %edi C carry, for wp[2]
+
+ mull %ecx C xp[1] * yp[1]
+
+ addl %eax, %edi
+
+ adcl $0, %edx
+ movl (%esi), %eax C xp[0]
+
+ movl %edx, %esi C carry, for wp[3]
+
+ mull %ecx C xp[0] * yp[1]
+
+ addl %eax, 4(%ebx)
+ adcl %edx, %edi
+ movl %edi, 8(%ebx)
+
+ adcl $0, %esi
+ movl SAVE_EDI, %edi
+ movl %esi, 12(%ebx)
+
+ movl SAVE_ESI, %esi
+ movl SAVE_EBX, %ebx
+ addl $FRAME, %esp
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(xsize_more_than_two):
+
+C The first limb of yp is processed with a simple mpn_mul_1 style loop
+C inline. Unrolling this doesn't seem worthwhile since it's only run once
+C (whereas the addmul below is run ysize-1 many times). A call to the
+C actual mpn_mul_1 will be slowed down by the call and parameter pushing and
+C popping, and doesn't seem likely to be worthwhile on the typical 13-26
+C limb operations the Karatsuba code calls here with.
+
+ C eax yp[0]
+ C ebx
+ C ecx xsize
+ C edx xp
+ C esi
+ C edi
+ C ebp
+
+dnl FRAME doesn't carry on from previous, no pushes yet here
+defframe(`SAVE_EBX',-4)
+defframe(`SAVE_ESI',-8)
+defframe(`SAVE_EDI',-12)
+defframe(`SAVE_EBP',-16)
+deflit(`FRAME',0)
+
+ subl $16, %esp
+deflit(`FRAME',16)
+
+ movl %edi, SAVE_EDI
+ movl PARAM_WP, %edi
+
+ movl %ebx, SAVE_EBX
+ movl %ebp, SAVE_EBP
+ movl %eax, %ebp
+
+ movl %esi, SAVE_ESI
+ xorl %ebx, %ebx
+ leal (%edx,%ecx,4), %esi C xp end
+
+ leal (%edi,%ecx,4), %edi C wp end of mul1
+ negl %ecx
+
+
+L(mul1):
+ C eax scratch
+ C ebx carry
+ C ecx counter, negative
+ C edx scratch
+ C esi xp end
+ C edi wp end of mul1
+ C ebp multiplier
+
+ movl (%esi,%ecx,4), %eax
+
+ mull %ebp
+
+ addl %ebx, %eax
+ movl %eax, (%edi,%ecx,4)
+ movl $0, %ebx
+
+ adcl %edx, %ebx
+ incl %ecx
+ jnz L(mul1)
+
+
+ movl PARAM_YSIZE, %edx
+ movl PARAM_XSIZE, %ecx
+
+ movl %ebx, (%edi) C final carry
+ decl %edx
+
+ jnz L(ysize_more_than_one)
+
+
+ movl SAVE_EDI, %edi
+ movl SAVE_EBX, %ebx
+
+ movl SAVE_EBP, %ebp
+ movl SAVE_ESI, %esi
+ addl $FRAME, %esp
+
+ ret
+
+
+L(ysize_more_than_one):
+ cmpl $UNROLL_THRESHOLD, %ecx
+ movl PARAM_YP, %eax
+
+ jae L(unroll)
+
+
+C -----------------------------------------------------------------------------
+ C simple addmul looping
+ C
+ C eax yp
+ C ebx
+ C ecx xsize
+ C edx ysize-1
+ C esi xp end
+ C edi wp end of mul1
+ C ebp
+
+ leal 4(%eax,%edx,4), %ebp C yp end
+ negl %ecx
+ negl %edx
+
+ movl (%esi,%ecx,4), %eax C xp low limb
+ movl %edx, PARAM_YSIZE C -(ysize-1)
+ incl %ecx
+
+ xorl %ebx, %ebx C initial carry
+ movl %ecx, PARAM_XSIZE C -(xsize-1)
+ movl %ebp, PARAM_YP
+
+ movl (%ebp,%edx,4), %ebp C yp second lowest limb - multiplier
+ jmp L(simple_outer_entry)
+
+
+ C this is offset 0x121 so close enough to aligned
+L(simple_outer_top):
+ C ebp ysize counter, negative
+
+ movl PARAM_YP, %edx
+ movl PARAM_XSIZE, %ecx C -(xsize-1)
+ xorl %ebx, %ebx C carry
+
+ movl %ebp, PARAM_YSIZE
+ addl $4, %edi C next position in wp
+
+ movl (%edx,%ebp,4), %ebp C yp limb - multiplier
+ movl -4(%esi,%ecx,4), %eax C xp low limb
+
+
+L(simple_outer_entry):
+
+L(simple_inner):
+ C eax xp limb
+ C ebx carry limb
+ C ecx loop counter (negative)
+ C edx scratch
+ C esi xp end
+ C edi wp end
+ C ebp multiplier
+
+ mull %ebp
+
+ addl %eax, %ebx
+ adcl $0, %edx
+
+ addl %ebx, (%edi,%ecx,4)
+ movl (%esi,%ecx,4), %eax
+ adcl $0, %edx
+
+ incl %ecx
+ movl %edx, %ebx
+ jnz L(simple_inner)
+
+
+ mull %ebp
+
+ movl PARAM_YSIZE, %ebp
+ addl %eax, %ebx
+
+ adcl $0, %edx
+ addl %ebx, (%edi)
+
+ adcl $0, %edx
+ incl %ebp
+
+ movl %edx, 4(%edi)
+ jnz L(simple_outer_top)
+
+
+ movl SAVE_EBX, %ebx
+ movl SAVE_ESI, %esi
+
+ movl SAVE_EDI, %edi
+ movl SAVE_EBP, %ebp
+ addl $FRAME, %esp
+
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+C
+C The unrolled loop is the same as in mpn_addmul_1(), see that code for some
+C comments.
+C
+C VAR_ADJUST is the negative of how many limbs the leals in the inner loop
+C increment xp and wp. This is used to adjust back xp and wp, and rshifted
+C to given an initial VAR_COUNTER at the top of the outer loop.
+C
+C VAR_COUNTER is for the unrolled loop, running from VAR_ADJUST/UNROLL_COUNT
+C up to -1, inclusive.
+C
+C VAR_JMP is the computed jump into the unrolled loop.
+C
+C VAR_XP_LOW is the least significant limb of xp, which is needed at the
+C start of the unrolled loop.
+C
+C PARAM_YSIZE is the outer loop counter, going from -(ysize-1) up to -1,
+C inclusive.
+C
+C PARAM_YP is offset appropriately so that the PARAM_YSIZE counter can be
+C added to give the location of the next limb of yp, which is the multiplier
+C in the unrolled loop.
+C
+C The trick with VAR_ADJUST means it's only necessary to do one fetch in the
+C outer loop to take care of xp, wp and the inner loop counter.
+
+defframe(VAR_COUNTER, -20)
+defframe(VAR_ADJUST, -24)
+defframe(VAR_JMP, -28)
+defframe(VAR_XP_LOW, -32)
+deflit(VAR_EXTRA_SPACE, 16)
+
+
+L(unroll):
+ C eax yp
+ C ebx
+ C ecx xsize
+ C edx ysize-1
+ C esi xp end
+ C edi wp end of mul1
+ C ebp
+
+ movl PARAM_XP, %esi
+ movl 4(%eax), %ebp C multiplier (yp second limb)
+ leal 4(%eax,%edx,4), %eax C yp adjust for ysize indexing
+
+ movl PARAM_WP, %edi
+ movl %eax, PARAM_YP
+ negl %edx
+
+ movl %edx, PARAM_YSIZE
+ leal UNROLL_COUNT-2(%ecx), %ebx C (xsize-1)+UNROLL_COUNT-1
+ decl %ecx C xsize-1
+
+ movl (%esi), %eax C xp low limb
+ andl $-UNROLL_MASK-1, %ebx
+ negl %ecx
+
+ subl $VAR_EXTRA_SPACE, %esp
+deflit(`FRAME',16+VAR_EXTRA_SPACE)
+ negl %ebx
+ andl $UNROLL_MASK, %ecx
+
+ movl %ebx, VAR_ADJUST
+ movl %ecx, %edx
+ shll $4, %ecx
+
+ sarl $UNROLL_LOG2, %ebx
+
+ C 17 code bytes per limb
+ifdef(`PIC',`
+ call L(pic_calc)
+L(unroll_here):
+',`
+ leal L(unroll_entry) (%ecx,%edx,1), %ecx
+')
+ negl %edx
+
+ movl %eax, VAR_XP_LOW
+ movl %ecx, VAR_JMP
+ leal 4(%edi,%edx,4), %edi C wp and xp, adjust for unrolling,
+ leal 4(%esi,%edx,4), %esi C and start at second limb
+ jmp L(unroll_outer_entry)
+
+
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ leal (%ecx,%edx,1), %ecx
+ addl $L(unroll_entry)-L(unroll_here), %ecx
+ addl (%esp), %ecx
+ ret_internal
+')
+
+
+C --------------------------------------------------------------------------
+ ALIGN(32)
+L(unroll_outer_top):
+ C ebp ysize counter, negative
+
+ movl VAR_ADJUST, %ebx
+ movl PARAM_YP, %edx
+
+ movl VAR_XP_LOW, %eax
+ movl %ebp, PARAM_YSIZE C store incremented ysize counter
+
+ leal 4(%edi,%ebx,4), %edi
+ leal (%esi,%ebx,4), %esi
+ sarl $UNROLL_LOG2, %ebx
+
+ movl (%edx,%ebp,4), %ebp C yp next multiplier
+ movl VAR_JMP, %ecx
+
+L(unroll_outer_entry):
+ mull %ebp
+
+ testb $1, %cl C and clear carry bit
+ movl %ebx, VAR_COUNTER
+ movl $0, %ebx
+
+ movl $0, %ecx
+ cmovz( %eax, %ecx) C eax into low carry, zero into high carry limb
+ cmovnz( %eax, %ebx)
+
+ C Extra fetch of VAR_JMP is bad, but registers are tight
+ jmp *VAR_JMP
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(32)
+L(unroll_top):
+ C eax xp limb
+ C ebx carry high
+ C ecx carry low
+ C edx scratch
+ C esi xp+8
+ C edi wp
+ C ebp yp multiplier limb
+ C
+ C VAR_COUNTER loop counter, negative
+ C
+ C 17 bytes each limb
+
+L(unroll_entry):
+
+deflit(CHUNK_COUNT,2)
+forloop(`i', 0, UNROLL_COUNT/CHUNK_COUNT-1, `
+ deflit(`disp0', eval(i*CHUNK_COUNT*4 ifelse(UNROLL_BYTES,256,-128)))
+ deflit(`disp1', eval(disp0 + 4))
+
+Zdisp( movl, disp0,(%esi), %eax)
+ adcl %edx, %ebx
+
+ mull %ebp
+
+Zdisp( addl, %ecx, disp0,(%edi))
+ movl $0, %ecx
+
+ adcl %eax, %ebx
+
+
+ movl disp1(%esi), %eax
+ adcl %edx, %ecx
+
+ mull %ebp
+
+ addl %ebx, disp1(%edi)
+ movl $0, %ebx
+
+ adcl %eax, %ecx
+')
+
+
+ incl VAR_COUNTER
+ leal UNROLL_BYTES(%esi), %esi
+ leal UNROLL_BYTES(%edi), %edi
+
+ jnz L(unroll_top)
+
+
+ C eax
+ C ebx zero
+ C ecx low
+ C edx high
+ C esi
+ C edi wp, pointing at second last limb)
+ C ebp
+ C
+ C carry flag to be added to high
+
+deflit(`disp0', ifelse(UNROLL_BYTES,256,-128))
+deflit(`disp1', eval(disp0-0 + 4))
+
+ movl PARAM_YSIZE, %ebp
+ adcl $0, %edx
+ addl %ecx, disp0(%edi)
+
+ adcl $0, %edx
+ incl %ebp
+
+ movl %edx, disp1(%edi)
+ jnz L(unroll_outer_top)
+
+
+ movl SAVE_ESI, %esi
+ movl SAVE_EBP, %ebp
+
+ movl SAVE_EDI, %edi
+ movl SAVE_EBX, %ebx
+ addl $FRAME, %esp
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/sqr_basecase.asm b/gmp/mpn/x86/k7/sqr_basecase.asm
new file mode 100644
index 0000000000..7b6a97e0df
--- /dev/null
+++ b/gmp/mpn/x86/k7/sqr_basecase.asm
@@ -0,0 +1,635 @@
+dnl AMD K7 mpn_sqr_basecase -- square an mpn number.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C K7: approx 2.3 cycles/crossproduct, or 4.55 cycles/triangular product
+C (measured on the speed difference between 25 and 50 limbs, which is
+C roughly the Karatsuba recursing range).
+
+
+dnl These are the same as mpn/x86/k6/sqr_basecase.asm, see that code for
+dnl some comments.
+
+deflit(SQR_TOOM2_THRESHOLD_MAX, 66)
+
+ifdef(`SQR_TOOM2_THRESHOLD_OVERRIDE',
+`define(`SQR_TOOM2_THRESHOLD',SQR_TOOM2_THRESHOLD_OVERRIDE)')
+
+m4_config_gmp_mparam(`SQR_TOOM2_THRESHOLD')
+deflit(UNROLL_COUNT, eval(SQR_TOOM2_THRESHOLD-3))
+
+
+C void mpn_sqr_basecase (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C With a SQR_TOOM2_THRESHOLD around 50 this code is about 1500 bytes,
+C which is quite a bit, but is considered good value since squares big
+C enough to use most of the code will be spending quite a few cycles in it.
+
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_sqr_basecase)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %eax
+ cmpl $2, %ecx
+
+ movl PARAM_DST, %edx
+ je L(two_limbs)
+ ja L(three_or_more)
+
+
+C------------------------------------------------------------------------------
+C one limb only
+ C eax src
+ C ecx size
+ C edx dst
+
+ movl (%eax), %eax
+ movl %edx, %ecx
+
+ mull %eax
+
+ movl %edx, 4(%ecx)
+ movl %eax, (%ecx)
+ ret
+
+
+C------------------------------------------------------------------------------
+C
+C Using the read/modify/write "add"s seems to be faster than saving and
+C restoring registers. Perhaps the loads for the first set hide under the
+C mul latency and the second gets store to load forwarding.
+
+ ALIGN(16)
+L(two_limbs):
+ C eax src
+ C ebx
+ C ecx size
+ C edx dst
+deflit(`FRAME',0)
+
+ pushl %ebx FRAME_pushl()
+ movl %eax, %ebx C src
+ movl (%eax), %eax
+
+ movl %edx, %ecx C dst
+
+ mull %eax C src[0]^2
+
+ movl %eax, (%ecx) C dst[0]
+ movl 4(%ebx), %eax
+
+ movl %edx, 4(%ecx) C dst[1]
+
+ mull %eax C src[1]^2
+
+ movl %eax, 8(%ecx) C dst[2]
+ movl (%ebx), %eax
+
+ movl %edx, 12(%ecx) C dst[3]
+
+ mull 4(%ebx) C src[0]*src[1]
+
+ popl %ebx
+
+ addl %eax, 4(%ecx)
+ adcl %edx, 8(%ecx)
+ adcl $0, 12(%ecx)
+ ASSERT(nc)
+
+ addl %eax, 4(%ecx)
+ adcl %edx, 8(%ecx)
+ adcl $0, 12(%ecx)
+ ASSERT(nc)
+
+ ret
+
+
+C------------------------------------------------------------------------------
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+deflit(STACK_SPACE, 16)
+
+L(three_or_more):
+ subl $STACK_SPACE, %esp
+ cmpl $4, %ecx
+ jae L(four_or_more)
+deflit(`FRAME',STACK_SPACE)
+
+
+C------------------------------------------------------------------------------
+C Three limbs
+C
+C Writing out the loads and stores separately at the end of this code comes
+C out about 10 cycles faster than using adcls to memory.
+
+ C eax src
+ C ecx size
+ C edx dst
+
+ movl %ebx, SAVE_EBX
+ movl %eax, %ebx C src
+ movl (%eax), %eax
+
+ movl %edx, %ecx C dst
+ movl %esi, SAVE_ESI
+ movl %edi, SAVE_EDI
+
+ mull %eax C src[0] ^ 2
+
+ movl %eax, (%ecx)
+ movl 4(%ebx), %eax
+ movl %edx, 4(%ecx)
+
+ mull %eax C src[1] ^ 2
+
+ movl %eax, 8(%ecx)
+ movl 8(%ebx), %eax
+ movl %edx, 12(%ecx)
+
+ mull %eax C src[2] ^ 2
+
+ movl %eax, 16(%ecx)
+ movl (%ebx), %eax
+ movl %edx, 20(%ecx)
+
+ mull 4(%ebx) C src[0] * src[1]
+
+ movl %eax, %esi
+ movl (%ebx), %eax
+ movl %edx, %edi
+
+ mull 8(%ebx) C src[0] * src[2]
+
+ addl %eax, %edi
+ movl %ebp, SAVE_EBP
+ movl $0, %ebp
+
+ movl 4(%ebx), %eax
+ adcl %edx, %ebp
+
+ mull 8(%ebx) C src[1] * src[2]
+
+ xorl %ebx, %ebx
+ addl %eax, %ebp
+
+ adcl $0, %edx
+
+ C eax
+ C ebx zero, will be dst[5]
+ C ecx dst
+ C edx dst[4]
+ C esi dst[1]
+ C edi dst[2]
+ C ebp dst[3]
+
+ adcl $0, %edx
+ addl %esi, %esi
+
+ adcl %edi, %edi
+ movl 4(%ecx), %eax
+
+ adcl %ebp, %ebp
+
+ adcl %edx, %edx
+
+ adcl $0, %ebx
+ addl %eax, %esi
+ movl 8(%ecx), %eax
+
+ adcl %eax, %edi
+ movl 12(%ecx), %eax
+ movl %esi, 4(%ecx)
+
+ adcl %eax, %ebp
+ movl 16(%ecx), %eax
+ movl %edi, 8(%ecx)
+
+ movl SAVE_ESI, %esi
+ movl SAVE_EDI, %edi
+
+ adcl %eax, %edx
+ movl 20(%ecx), %eax
+ movl %ebp, 12(%ecx)
+
+ adcl %ebx, %eax
+ ASSERT(nc)
+ movl SAVE_EBX, %ebx
+ movl SAVE_EBP, %ebp
+
+ movl %edx, 16(%ecx)
+ movl %eax, 20(%ecx)
+ addl $FRAME, %esp
+
+ ret
+
+
+C------------------------------------------------------------------------------
+L(four_or_more):
+
+C First multiply src[0]*src[1..size-1] and store at dst[1..size].
+C Further products are added in rather than stored.
+
+ C eax src
+ C ebx
+ C ecx size
+ C edx dst
+ C esi
+ C edi
+ C ebp
+
+defframe(`VAR_COUNTER',-20)
+defframe(`VAR_JMP', -24)
+deflit(EXTRA_STACK_SPACE, 8)
+
+ movl %ebx, SAVE_EBX
+ movl %edi, SAVE_EDI
+ leal (%edx,%ecx,4), %edi C &dst[size]
+
+ movl %esi, SAVE_ESI
+ movl %ebp, SAVE_EBP
+ leal (%eax,%ecx,4), %esi C &src[size]
+
+ movl (%eax), %ebp C multiplier
+ movl $0, %ebx
+ decl %ecx
+
+ negl %ecx
+ subl $EXTRA_STACK_SPACE, %esp
+FRAME_subl_esp(EXTRA_STACK_SPACE)
+
+L(mul_1):
+ C eax scratch
+ C ebx carry
+ C ecx counter
+ C edx scratch
+ C esi &src[size]
+ C edi &dst[size]
+ C ebp multiplier
+
+ movl (%esi,%ecx,4), %eax
+
+ mull %ebp
+
+ addl %ebx, %eax
+ movl %eax, (%edi,%ecx,4)
+ movl $0, %ebx
+
+ adcl %edx, %ebx
+ incl %ecx
+ jnz L(mul_1)
+
+
+C Add products src[n]*src[n+1..size-1] at dst[2*n-1...], for each n=1..size-2.
+C
+C The last two products, which are the bottom right corner of the product
+C triangle, are left to the end. These are src[size-3]*src[size-2,size-1]
+C and src[size-2]*src[size-1]. If size is 4 then it's only these corner
+C cases that need to be done.
+C
+C The unrolled code is the same as in mpn_addmul_1, see that routine for
+C some comments.
+C
+C VAR_COUNTER is the outer loop, running from -size+4 to -1, inclusive.
+C
+C VAR_JMP is the computed jump into the unrolled code, stepped by one code
+C chunk each outer loop.
+C
+C K7 does branch prediction on indirect jumps, which is bad since it's a
+C different target each time. There seems no way to avoid this.
+
+dnl This value also hard coded in some shifts and adds
+deflit(CODE_BYTES_PER_LIMB, 17)
+
+dnl With the unmodified &src[size] and &dst[size] pointers, the
+dnl displacements in the unrolled code fit in a byte for UNROLL_COUNT
+dnl values up to 31, but above that an offset must be added to them.
+
+deflit(OFFSET,
+ifelse(eval(UNROLL_COUNT>31),1,
+eval((UNROLL_COUNT-31)*4),
+0))
+
+dnl Because the last chunk of code is generated differently, a label placed
+dnl at the end doesn't work. Instead calculate the implied end using the
+dnl start and how many chunks of code there are.
+
+deflit(UNROLL_INNER_END,
+`L(unroll_inner_start)+eval(UNROLL_COUNT*CODE_BYTES_PER_LIMB)')
+
+ C eax
+ C ebx carry
+ C ecx
+ C edx
+ C esi &src[size]
+ C edi &dst[size]
+ C ebp
+
+ movl PARAM_SIZE, %ecx
+ movl %ebx, (%edi)
+
+ subl $4, %ecx
+ jz L(corner)
+
+ negl %ecx
+ifelse(OFFSET,0,,`subl $OFFSET, %edi')
+ifelse(OFFSET,0,,`subl $OFFSET, %esi')
+
+ movl %ecx, %edx
+ shll $4, %ecx
+
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ leal UNROLL_INNER_END-eval(2*CODE_BYTES_PER_LIMB)(%ecx,%edx), %ecx
+')
+
+
+ C The calculated jump mustn't come out to before the start of the
+ C code available. This is the limit UNROLL_COUNT puts on the src
+ C operand size, but checked here directly using the jump address.
+ ASSERT(ae,
+ `movl_text_address(L(unroll_inner_start), %eax)
+ cmpl %eax, %ecx')
+
+
+C------------------------------------------------------------------------------
+ ALIGN(16)
+L(unroll_outer_top):
+ C eax
+ C ebx high limb to store
+ C ecx VAR_JMP
+ C edx VAR_COUNTER, limbs, negative
+ C esi &src[size], constant
+ C edi dst ptr, high of last addmul
+ C ebp
+
+ movl -12+OFFSET(%esi,%edx,4), %ebp C next multiplier
+ movl -8+OFFSET(%esi,%edx,4), %eax C first of multiplicand
+
+ movl %edx, VAR_COUNTER
+
+ mull %ebp
+
+define(cmovX,`ifelse(eval(UNROLL_COUNT%2),0,`cmovz($@)',`cmovnz($@)')')
+
+ testb $1, %cl
+ movl %edx, %ebx C high carry
+ movl %ecx, %edx C jump
+
+ movl %eax, %ecx C low carry
+ cmovX( %ebx, %ecx) C high carry reverse
+ cmovX( %eax, %ebx) C low carry reverse
+
+ leal CODE_BYTES_PER_LIMB(%edx), %eax
+ xorl %edx, %edx
+ leal 4(%edi), %edi
+
+ movl %eax, VAR_JMP
+
+ jmp *%eax
+
+
+ifdef(`PIC',`
+L(pic_calc):
+ addl (%esp), %ecx
+ addl $UNROLL_INNER_END-eval(2*CODE_BYTES_PER_LIMB)-L(here), %ecx
+ addl %edx, %ecx
+ ret_internal
+')
+
+
+ C Must be an even address to preserve the significance of the low
+ C bit of the jump address indicating which way around ecx/ebx should
+ C start.
+ ALIGN(2)
+
+L(unroll_inner_start):
+ C eax next limb
+ C ebx carry high
+ C ecx carry low
+ C edx scratch
+ C esi src
+ C edi dst
+ C ebp multiplier
+
+forloop(`i', UNROLL_COUNT, 1, `
+ deflit(`disp_src', eval(-i*4 + OFFSET))
+ deflit(`disp_dst', eval(disp_src - 4))
+
+ m4_assert(`disp_src>=-128 && disp_src<128')
+ m4_assert(`disp_dst>=-128 && disp_dst<128')
+
+ifelse(eval(i%2),0,`
+Zdisp( movl, disp_src,(%esi), %eax)
+ adcl %edx, %ebx
+
+ mull %ebp
+
+Zdisp( addl, %ecx, disp_dst,(%edi))
+ movl $0, %ecx
+
+ adcl %eax, %ebx
+
+',`
+ dnl this bit comes out last
+Zdisp( movl, disp_src,(%esi), %eax)
+ adcl %edx, %ecx
+
+ mull %ebp
+
+Zdisp( addl, %ebx, disp_dst,(%edi))
+
+ifelse(forloop_last,0,
+` movl $0, %ebx')
+
+ adcl %eax, %ecx
+')
+')
+
+ C eax next limb
+ C ebx carry high
+ C ecx carry low
+ C edx scratch
+ C esi src
+ C edi dst
+ C ebp multiplier
+
+ adcl $0, %edx
+ addl %ecx, -4+OFFSET(%edi)
+ movl VAR_JMP, %ecx
+
+ adcl $0, %edx
+
+ movl %edx, m4_empty_if_zero(OFFSET) (%edi)
+ movl VAR_COUNTER, %edx
+
+ incl %edx
+ jnz L(unroll_outer_top)
+
+
+ifelse(OFFSET,0,,`
+ addl $OFFSET, %esi
+ addl $OFFSET, %edi
+')
+
+
+C------------------------------------------------------------------------------
+L(corner):
+ C esi &src[size]
+ C edi &dst[2*size-5]
+
+ movl -12(%esi), %ebp
+ movl -8(%esi), %eax
+ movl %eax, %ecx
+
+ mull %ebp
+
+ addl %eax, -4(%edi)
+ movl -4(%esi), %eax
+
+ adcl $0, %edx
+ movl %edx, %ebx
+ movl %eax, %esi
+
+ mull %ebp
+
+ addl %ebx, %eax
+
+ adcl $0, %edx
+ addl %eax, (%edi)
+ movl %esi, %eax
+
+ adcl $0, %edx
+ movl %edx, %ebx
+
+ mull %ecx
+
+ addl %ebx, %eax
+ movl %eax, 4(%edi)
+
+ adcl $0, %edx
+ movl %edx, 8(%edi)
+
+
+
+C Left shift of dst[1..2*size-2], high bit shifted out becomes dst[2*size-1].
+
+L(lshift_start):
+ movl PARAM_SIZE, %eax
+ movl PARAM_DST, %edi
+ xorl %ecx, %ecx C clear carry
+
+ leal (%edi,%eax,8), %edi
+ notl %eax C -size-1, preserve carry
+
+ leal 2(%eax), %eax C -(size-1)
+
+L(lshift):
+ C eax counter, negative
+ C ebx
+ C ecx
+ C edx
+ C esi
+ C edi dst, pointing just after last limb
+ C ebp
+
+ rcll -4(%edi,%eax,8)
+ rcll (%edi,%eax,8)
+ incl %eax
+ jnz L(lshift)
+
+ setc %al
+
+ movl PARAM_SRC, %esi
+ movl %eax, -4(%edi) C dst most significant limb
+
+ movl PARAM_SIZE, %ecx
+
+
+C Now add in the squares on the diagonal, src[0]^2, src[1]^2, ...,
+C src[size-1]^2. dst[0] hasn't yet been set at all yet, and just gets the
+C low limb of src[0]^2.
+
+ movl (%esi), %eax C src[0]
+
+ mull %eax
+
+ leal (%esi,%ecx,4), %esi C src point just after last limb
+ negl %ecx
+
+ movl %eax, (%edi,%ecx,8) C dst[0]
+ incl %ecx
+
+L(diag):
+ C eax scratch
+ C ebx scratch
+ C ecx counter, negative
+ C edx carry
+ C esi src just after last limb
+ C edi dst just after last limb
+ C ebp
+
+ movl (%esi,%ecx,4), %eax
+ movl %edx, %ebx
+
+ mull %eax
+
+ addl %ebx, -4(%edi,%ecx,8)
+ adcl %eax, (%edi,%ecx,8)
+ adcl $0, %edx
+
+ incl %ecx
+ jnz L(diag)
+
+
+ movl SAVE_ESI, %esi
+ movl SAVE_EBX, %ebx
+
+ addl %edx, -4(%edi) C dst most significant limb
+ movl SAVE_EDI, %edi
+
+ movl SAVE_EBP, %ebp
+ addl $FRAME, %esp
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/k7/sublsh1_n.asm b/gmp/mpn/x86/k7/sublsh1_n.asm
new file mode 100644
index 0000000000..523b01218d
--- /dev/null
+++ b/gmp/mpn/x86/k7/sublsh1_n.asm
@@ -0,0 +1,173 @@
+dnl AMD K7 mpn_sublsh1_n_ip1 -- rp[] = rp[] - (up[] << 1)
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C This is an attempt at a sublsh1_n for x86-32, not relying on sse2 insns. The
+C innerloop is 2*3-way unrolled, which is best we can do with the available
+C registers. It seems tricky to use the same structure for rsblsh1_n, since we
+C cannot feed carry between operations there.
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 6.75
+C AMD K6
+C AMD K7
+C AMD K8
+
+C This is a basic sublsh1_n for k7, atom, and perhaps some other x86-32
+C processors. It uses 2*4-way unrolling, for good reasons.
+C
+C Breaking carry recurrency might be a good idea. We would then need separate
+C registers for the shift carry and add/subtract carry, which in turn would
+C force is to 2*2-way unrolling.
+
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(VAR_COUNT,`PARAM_SIZE')
+define(SAVE_EBX,`PARAM_SRC')
+define(SAVE_EBP,`PARAM_DST')
+
+ASM_START()
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_sublsh1_n_ip1)
+deflit(`FRAME',0)
+
+define(`rp', `%edi')
+define(`up', `%esi')
+
+ mov PARAM_SIZE, %eax C size
+ push up FRAME_pushl()
+ push rp FRAME_pushl()
+ xor %edx, %edx
+ mov PARAM_SRC, up
+ mov PARAM_DST, rp
+ mov %ebx, SAVE_EBX
+ mov %eax, %ebx
+ shr $3, %eax
+
+ not %eax C count = -(size\8)-i
+ and $7, %ebx C size % 8
+ jz L(exact)
+
+L(oop):
+ifdef(`CPU_P6',`
+ shr %edx ') C restore 2nd saved carry bit
+ mov (up), %ecx
+ adc %ecx, %ecx
+ rcr %edx C restore 1st saved carry bit
+ lea 4(up), up
+ sbb %ecx, (rp)
+ lea 4(rp), rp
+ adc %edx, %edx C save a carry bit in edx
+ifdef(`CPU_P6',`
+ adc %edx, %edx ') C save another carry bit in edx
+ dec %ebx
+ jnz L(oop)
+L(exact):
+ inc %eax
+ jz L(end)
+ mov %eax, VAR_COUNT
+ mov %ebp, SAVE_EBP
+
+ ALIGN(16)
+L(top):
+ifdef(`CPU_P6',`
+ shr %edx ') C restore 2nd saved carry bit
+ mov (up), %eax
+ adc %eax, %eax
+ mov 4(up), %ebx
+ adc %ebx, %ebx
+ mov 8(up), %ecx
+ adc %ecx, %ecx
+ mov 12(up), %ebp
+ adc %ebp, %ebp
+
+ rcr %edx C restore 1st saved carry bit
+
+ sbb %eax, (rp)
+ sbb %ebx, 4(rp)
+ sbb %ecx, 8(rp)
+ sbb %ebp, 12(rp)
+
+ mov 16(up), %eax
+ adc %eax, %eax
+ mov 20(up), %ebx
+ adc %ebx, %ebx
+ mov 24(up), %ecx
+ adc %ecx, %ecx
+ mov 28(up), %ebp
+ adc %ebp, %ebp
+
+ lea 32(up), up
+ adc %edx, %edx C save a carry bit in edx
+
+ sbb %eax, 16(rp)
+ sbb %ebx, 20(rp)
+ sbb %ecx, 24(rp)
+ sbb %ebp, 28(rp)
+
+ifdef(`CPU_P6',`
+ adc %edx, %edx ') C save another carry bit in edx
+ incl VAR_COUNT
+ lea 32(rp), rp
+ jne L(top)
+
+ mov SAVE_EBP, %ebp
+L(end):
+ mov SAVE_EBX, %ebx
+
+ifdef(`CPU_P6',`
+ xor %eax, %eax
+ shr $1, %edx
+ adc %edx, %eax
+',`
+ adc $0, %edx
+ mov %edx, %eax
+')
+ pop rp FRAME_popl()
+ pop up FRAME_popl()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/k8/gmp-mparam.h b/gmp/mpn/x86/k8/gmp-mparam.h
new file mode 100644
index 0000000000..8d95fef80b
--- /dev/null
+++ b/gmp/mpn/x86/k8/gmp-mparam.h
@@ -0,0 +1,198 @@
+/* x86/k8 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 2500 MHz K8 Brisbane */
+/* FFT tuning limit = 10000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 11
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 12
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 16
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 1
+#define DIV_QR_1_NORM_THRESHOLD 2
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 40
+
+#define MUL_TOOM22_THRESHOLD 24
+#define MUL_TOOM33_THRESHOLD 81
+#define MUL_TOOM44_THRESHOLD 130
+#define MUL_TOOM6H_THRESHOLD 303
+#define MUL_TOOM8H_THRESHOLD 430
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 81
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 91
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 93
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 92
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 122
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 46
+#define SQR_TOOM3_THRESHOLD 78
+#define SQR_TOOM4_THRESHOLD 202
+#define SQR_TOOM6_THRESHOLD 286
+#define SQR_TOOM8_THRESHOLD 422
+
+#define MULMID_TOOM42_THRESHOLD 56
+
+#define MULMOD_BNM1_THRESHOLD 17
+#define SQRMOD_BNM1_THRESHOLD 18
+
+#define MUL_FFT_MODF_THRESHOLD 848 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 848, 5}, { 27, 6}, { 25, 7}, { 13, 6}, \
+ { 27, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
+ { 55, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
+ { 31, 9}, { 79,10}, { 47, 9}, { 103,11}, \
+ { 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
+ { 167,10}, { 95, 9}, { 199,10}, { 111,11}, \
+ { 63,10}, { 127, 9}, { 255,10}, { 143, 9}, \
+ { 287,10}, { 159,11}, { 95,10}, { 207,12}, \
+ { 63,11}, { 127,10}, { 271, 9}, { 543,10}, \
+ { 287,11}, { 159,10}, { 319, 9}, { 639,10}, \
+ { 335, 9}, { 671,11}, { 191,10}, { 383, 9}, \
+ { 799,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543,11}, { 287,10}, { 607, 9}, { 1215,11}, \
+ { 319,10}, { 671, 9}, { 1343,12}, { 191,11}, \
+ { 383,10}, { 799, 9}, { 1599,11}, { 415,10}, \
+ { 863, 9}, { 1727,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1119,11}, { 607,10}, { 1215,12}, \
+ { 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
+ { 1471, 9}, { 2943,12}, { 383,11}, { 799,10}, \
+ { 1599,11}, { 863,10}, { 1727,12}, { 447,11}, \
+ { 991,13}, { 255,12}, { 511,11}, { 1023,10}, \
+ { 2111,11}, { 1119,12}, { 575,11}, { 1215,10}, \
+ { 2431,12}, { 639,11}, { 1343,12}, { 703,11}, \
+ { 1471,10}, { 2943,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1727,12}, { 959,11}, \
+ { 1919,14}, { 255,13}, { 511,12}, { 1023,11}, \
+ { 2047,12}, { 1087,11}, { 2239,12}, { 1215,11}, \
+ { 2431,13}, { 639,12}, { 1471,11}, { 2943,13}, \
+ { 767,12}, { 1727,13}, { 895,12}, { 1983,14}, \
+ { 511,13}, { 1023,12}, { 2239,13}, { 1151,12}, \
+ { 4096,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 144
+#define MUL_FFT_THRESHOLD 7552
+
+#define SQR_FFT_MODF_THRESHOLD 618 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 618, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 28, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
+ { 51, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
+ { 31, 9}, { 79,10}, { 47, 9}, { 95,11}, \
+ { 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
+ { 167,10}, { 95, 9}, { 191,10}, { 111,11}, \
+ { 63,10}, { 159,11}, { 95,10}, { 191,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
+ { 271, 9}, { 543, 8}, { 1087,10}, { 287,11}, \
+ { 159,10}, { 319, 9}, { 639,10}, { 335, 9}, \
+ { 671, 8}, { 1343,10}, { 351,11}, { 191,10}, \
+ { 383, 9}, { 767,10}, { 399, 9}, { 799,10}, \
+ { 415,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607, 9}, \
+ { 1215,11}, { 319,10}, { 671, 9}, { 1343,11}, \
+ { 351,12}, { 191,11}, { 383,10}, { 799, 9}, \
+ { 1599,11}, { 415,10}, { 863, 9}, { 1727,13}, \
+ { 127,12}, { 255,11}, { 543,10}, { 1087,11}, \
+ { 607,10}, { 1215,12}, { 319,11}, { 671,10}, \
+ { 1343,11}, { 735,10}, { 1471,12}, { 383,11}, \
+ { 799,10}, { 1599,11}, { 863,10}, { 1727,12}, \
+ { 447,11}, { 959,10}, { 1919,11}, { 991,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1215,10}, { 2431,12}, { 639,11}, { 1343,12}, \
+ { 703,11}, { 1471,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1727,12}, { 959,11}, \
+ { 1919,14}, { 255,13}, { 511,12}, { 1087,11}, \
+ { 2239,12}, { 1215,11}, { 2431,13}, { 639,12}, \
+ { 1471,11}, { 2943,13}, { 767,12}, { 1727,11}, \
+ { 3455,13}, { 895,12}, { 1983,14}, { 511,13}, \
+ { 1023,12}, { 2239,13}, { 1151,12}, { 4096,13}, \
+ { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 147
+#define SQR_FFT_THRESHOLD 5760
+
+#define MULLO_BASECASE_THRESHOLD 8
+#define MULLO_DC_THRESHOLD 31
+#define MULLO_MUL_N_THRESHOLD 14281
+
+#define DC_DIV_QR_THRESHOLD 91
+#define DC_DIVAPPR_Q_THRESHOLD 280
+#define DC_BDIV_QR_THRESHOLD 87
+#define DC_BDIV_Q_THRESHOLD 222
+
+#define INV_MULMOD_BNM1_THRESHOLD 62
+#define INV_NEWTON_THRESHOLD 268
+#define INV_APPR_THRESHOLD 270
+
+#define BINV_NEWTON_THRESHOLD 260
+#define REDC_1_TO_REDC_N_THRESHOLD 79
+
+#define MU_DIV_QR_THRESHOLD 1718
+#define MU_DIVAPPR_Q_THRESHOLD 1528
+#define MUPI_DIV_QR_THRESHOLD 97
+#define MU_BDIV_QR_THRESHOLD 1470
+#define MU_BDIV_Q_THRESHOLD 1470
+
+#define POWM_SEC_TABLE 1,22,114,416,1464
+
+#define MATRIX22_STRASSEN_THRESHOLD 16
+#define HGCD_THRESHOLD 149
+#define HGCD_APPR_THRESHOLD 204
+#define HGCD_REDUCE_THRESHOLD 4455
+#define GCD_DC_THRESHOLD 599
+#define GCDEXT_DC_THRESHOLD 403
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 28
+#define SET_STR_DC_THRESHOLD 270
+#define SET_STR_PRECOMPUTE_THRESHOLD 1367
+
+#define FAC_DSC_THRESHOLD 348
+#define FAC_ODD_THRESHOLD 24
diff --git a/gmp/mpn/x86/lshift.asm b/gmp/mpn/x86/lshift.asm
new file mode 100644
index 0000000000..6ee6153cc2
--- /dev/null
+++ b/gmp/mpn/x86/lshift.asm
@@ -0,0 +1,106 @@
+dnl x86 mpn_lshift -- mpn left shift.
+
+dnl Copyright 1992, 1994, 1996, 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P54 7.5
+C P55 7.0
+C P6 2.5
+C K6 4.5
+C K7 5.0
+C P4 14.5
+
+
+C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_lshift)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+deflit(`FRAME',12)
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC,%esi
+ movl PARAM_SIZE,%edx
+ movl PARAM_SHIFT,%ecx
+
+ subl $4,%esi C adjust src
+
+ movl (%esi,%edx,4),%ebx C read most significant limb
+ xorl %eax,%eax
+ shldl( %cl, %ebx, %eax) C compute carry limb
+ decl %edx
+ jz L(end)
+ pushl %eax C push carry limb onto stack
+ testb $1,%dl
+ jnz L(1) C enter loop in the middle
+ movl %ebx,%eax
+
+ ALIGN(8)
+L(oop): movl (%esi,%edx,4),%ebx C load next lower limb
+ shldl( %cl, %ebx, %eax) C compute result limb
+ movl %eax,(%edi,%edx,4) C store it
+ decl %edx
+L(1): movl (%esi,%edx,4),%eax
+ shldl( %cl, %eax, %ebx)
+ movl %ebx,(%edi,%edx,4)
+ decl %edx
+ jnz L(oop)
+
+ shll %cl,%eax C compute least significant limb
+ movl %eax,(%edi) C store it
+
+ popl %eax C pop carry limb
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+L(end): shll %cl,%ebx C compute least significant limb
+ movl %ebx,(%edi) C store it
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/mmx/sec_tabselect.asm b/gmp/mpn/x86/mmx/sec_tabselect.asm
new file mode 100644
index 0000000000..aae158abf7
--- /dev/null
+++ b/gmp/mpn/x86/mmx/sec_tabselect.asm
@@ -0,0 +1,163 @@
+dnl X86 MMX mpn_sec_tabselect.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb
+C ali,evn n unal,evn n
+C P5
+C P6 model 0-8,10-12
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan) 1.33 1.87
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood) 2.1 2.63
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona) 1.7 2.57
+C Intel Atom 1.85 2.7
+C AMD K6
+C AMD K7 1.33 1.33
+C AMD K8
+C AMD K10
+
+define(`rp', `%edi')
+define(`tp', `%esi')
+define(`n', `%edx')
+define(`nents', `%ecx')
+define(`which', `')
+
+define(`i', `%ebp')
+define(`j', `%ebx')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sec_tabselect)
+ push %ebx
+ push %esi
+ push %edi
+ push %ebp
+
+ mov 20(%esp), rp
+ mov 24(%esp), tp
+ mov 28(%esp), n
+ mov 32(%esp), nents
+
+ movd 36(%esp), %mm6
+ punpckldq %mm6, %mm6 C 2 copies of `which'
+
+ mov $1, %ebx
+ movd %ebx, %mm7
+ punpckldq %mm7, %mm7 C 2 copies of 1
+
+ mov n, j
+ add $-4, j
+ js L(outer_end)
+
+L(outer_top):
+ mov nents, i
+ mov tp, %eax
+ pxor %mm1, %mm1
+ pxor %mm4, %mm4
+ pxor %mm5, %mm5
+ ALIGN(16)
+L(top): movq %mm6, %mm0
+ pcmpeqd %mm1, %mm0
+ paddd %mm7, %mm1
+ movq (tp), %mm2
+ movq 8(tp), %mm3
+ pand %mm0, %mm2
+ pand %mm0, %mm3
+ por %mm2, %mm4
+ por %mm3, %mm5
+ lea (tp,n,4), tp
+ add $-1, i
+ jne L(top)
+
+ movq %mm4, (rp)
+ movq %mm5, 8(rp)
+
+ lea 16(%eax), tp
+ lea 16(rp), rp
+ add $-4, j
+ jns L(outer_top)
+L(outer_end):
+
+ test $2, %dl
+ jz L(b0x)
+
+L(b1x): mov nents, i
+ mov tp, %eax
+ pxor %mm1, %mm1
+ pxor %mm4, %mm4
+ ALIGN(16)
+L(tp2): movq %mm6, %mm0
+ pcmpeqd %mm1, %mm0
+ paddd %mm7, %mm1
+ movq (tp), %mm2
+ pand %mm0, %mm2
+ por %mm2, %mm4
+ lea (tp,n,4), tp
+ add $-1, i
+ jne L(tp2)
+
+ movq %mm4, (rp)
+
+ lea 8(%eax), tp
+ lea 8(rp), rp
+
+L(b0x): test $1, %dl
+ jz L(b00)
+
+L(b01): mov nents, i
+ pxor %mm1, %mm1
+ pxor %mm4, %mm4
+ ALIGN(16)
+L(tp1): movq %mm6, %mm0
+ pcmpeqd %mm1, %mm0
+ paddd %mm7, %mm1
+ movd (tp), %mm2
+ pand %mm0, %mm2
+ por %mm2, %mm4
+ lea (tp,n,4), tp
+ add $-1, i
+ jne L(tp1)
+
+ movd %mm4, (rp)
+
+L(b00): pop %ebp
+ pop %edi
+ pop %esi
+ pop %ebx
+ emms
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/mod_34lsub1.asm b/gmp/mpn/x86/mod_34lsub1.asm
new file mode 100644
index 0000000000..e09e702c6f
--- /dev/null
+++ b/gmp/mpn/x86/mod_34lsub1.asm
@@ -0,0 +1,183 @@
+dnl Generic x86 mpn_mod_34lsub1 -- mpn remainder modulo 2^24-1.
+
+dnl Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5 3.0
+C P6 3.66
+C K6 3.0
+C K7 1.3
+C P4 9
+
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr src, mp_size_t size)
+C
+
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX, `PARAM_SRC')
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_34lsub1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %edx
+
+ subl $2, %ecx
+ ja L(three_or_more)
+
+ movl (%edx), %eax
+ jb L(one)
+
+ movl 4(%edx), %ecx
+ movl %eax, %edx
+ shrl $24, %eax C src[0] low
+
+ andl $0xFFFFFF, %edx C src[0] high
+ addl %edx, %eax
+ movl %ecx, %edx
+
+ andl $0xFFFF, %ecx
+ shrl $16, %edx C src[1] high
+ addl %edx, %eax
+
+ shll $8, %ecx C src[1] low
+ addl %ecx, %eax
+
+L(one):
+ ret
+
+
+L(three_or_more):
+ C eax
+ C ebx
+ C ecx size-2
+ C edx src
+ C esi
+ C edi
+ C ebp
+
+ movl %ebx, SAVE_EBX C and arrange 16-byte loop alignment
+ xorl %ebx, %ebx
+
+ pushl %esi FRAME_pushl()
+ xorl %esi, %esi
+
+ pushl %edi FRAME_pushl()
+ xorl %eax, %eax C and clear carry flag
+
+
+ C offset 0x40 here
+L(top):
+ C eax acc 0mod3
+ C ebx acc 1mod3
+ C ecx counter, limbs
+ C edx src
+ C esi acc 2mod3
+ C edi
+ C ebp
+
+ leal 12(%edx), %edx
+ leal -2(%ecx), %ecx
+
+ adcl -12(%edx), %eax
+ adcl -8(%edx), %ebx
+ adcl -4(%edx), %esi
+
+ decl %ecx
+ jg L(top)
+
+
+ C ecx is -2, -1 or 0 representing 0, 1 or 2 more limbs, respectively
+
+ movl $0xFFFFFFFF, %edi
+ incl %ecx
+ js L(combine)
+
+ adcl (%edx), %eax
+ movl $0xFFFFFF00, %edi
+ decl %ecx
+ js L(combine)
+
+ adcl 4(%edx), %ebx
+ movl $0xFFFF0000, %edi
+
+
+L(combine):
+ C eax acc 0mod3
+ C ebx acc 1mod3
+ C ecx
+ C edx
+ C esi acc 2mod3
+ C edi mask
+ C ebp
+
+ sbbl %ecx, %ecx C carry
+ movl %eax, %edx C 0mod3
+
+ shrl $24, %eax C 0mod3 high
+ andl %edi, %ecx C carry masked
+
+ subl %ecx, %eax C apply carry
+ movl %ebx, %edi C 1mod3
+
+ shrl $16, %ebx C 1mod3 high
+ andl $0x00FFFFFF, %edx C 0mod3 low
+
+ addl %edx, %eax C apply 0mod3 low
+ andl $0xFFFF, %edi
+
+ shll $8, %edi C 1mod3 low
+ addl %ebx, %eax C apply 1mod3 high
+
+ addl %edi, %eax C apply 1mod3 low
+ movl %esi, %edx C 2mod3
+
+ shrl $8, %esi C 2mod3 high
+ andl $0xFF, %edx C 2mod3 low
+
+ shll $16, %edx C 2mod3 low
+ addl %esi, %eax C apply 2mod3 high
+
+ addl %edx, %eax C apply 2mod3 low
+ popl %edi FRAME_popl()
+
+ movl SAVE_EBX, %ebx
+ popl %esi FRAME_popl()
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/mul_1.asm b/gmp/mpn/x86/mul_1.asm
new file mode 100644
index 0000000000..421de62225
--- /dev/null
+++ b/gmp/mpn/x86/mul_1.asm
@@ -0,0 +1,140 @@
+dnl x86 mpn_mul_1 (for 386, 486, and Pentium Pro) -- Multiply a limb vector
+dnl with a limb and store the result in a second limb vector.
+
+dnl Copyright 1992, 1994, 1997-2002, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5 12.5
+C P6 model 0-8,10-12 5.5
+C P6 model 9 (Banias)
+C P6 model 13 (Dothan) 5.25
+C P4 model 0 (Willamette) 19.0
+C P4 model 1 (?) 19.0
+C P4 model 2 (Northwood) 19.0
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C AMD K6 10.5
+C AMD K7 4.5
+C AMD K8
+
+
+C mp_limb_t mpn_mul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t multiplier);
+
+defframe(PARAM_MULTIPLIER,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_mul_1)
+deflit(`FRAME',0)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+deflit(`FRAME',16)
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC,%esi
+ movl PARAM_SIZE,%ecx
+
+ xorl %ebx,%ebx
+ andl $3,%ecx
+ jz L(end0)
+
+L(oop0):
+ movl (%esi),%eax
+ mull PARAM_MULTIPLIER
+ leal 4(%esi),%esi
+ addl %ebx,%eax
+ movl $0,%ebx
+ adcl %ebx,%edx
+ movl %eax,(%edi)
+ movl %edx,%ebx C propagate carry into cylimb
+
+ leal 4(%edi),%edi
+ decl %ecx
+ jnz L(oop0)
+
+L(end0):
+ movl PARAM_SIZE,%ecx
+ shrl $2,%ecx
+ jz L(end)
+
+
+ ALIGN(8)
+L(oop): movl (%esi),%eax
+ mull PARAM_MULTIPLIER
+ addl %eax,%ebx
+ movl $0,%ebp
+ adcl %edx,%ebp
+
+ movl 4(%esi),%eax
+ mull PARAM_MULTIPLIER
+ movl %ebx,(%edi)
+ addl %eax,%ebp C new lo + cylimb
+ movl $0,%ebx
+ adcl %edx,%ebx
+
+ movl 8(%esi),%eax
+ mull PARAM_MULTIPLIER
+ movl %ebp,4(%edi)
+ addl %eax,%ebx C new lo + cylimb
+ movl $0,%ebp
+ adcl %edx,%ebp
+
+ movl 12(%esi),%eax
+ mull PARAM_MULTIPLIER
+ movl %ebx,8(%edi)
+ addl %eax,%ebp C new lo + cylimb
+ movl $0,%ebx
+ adcl %edx,%ebx
+
+ movl %ebp,12(%edi)
+
+ leal 16(%esi),%esi
+ leal 16(%edi),%edi
+ decl %ecx
+ jnz L(oop)
+
+L(end): movl %ebx,%eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/mul_basecase.asm b/gmp/mpn/x86/mul_basecase.asm
new file mode 100644
index 0000000000..8339732a80
--- /dev/null
+++ b/gmp/mpn/x86/mul_basecase.asm
@@ -0,0 +1,223 @@
+dnl x86 mpn_mul_basecase -- Multiply two limb vectors and store the result
+dnl in a third limb vector.
+
+dnl Copyright 1996-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/crossproduct
+C P5 15
+C P6 7.5
+C K6 12.5
+C K7 5.5
+C P4 24
+
+
+C void mpn_mul_basecase (mp_ptr wp,
+C mp_srcptr xp, mp_size_t xsize,
+C mp_srcptr yp, mp_size_t ysize);
+C
+C This was written in a haste since the Pentium optimized code that was used
+C for all x86 machines was slow for the Pentium II. This code would benefit
+C from some cleanup.
+C
+C To shave off some percentage of the run-time, one should make 4 variants
+C of the Louter loop, for the four different outcomes of un mod 4. That
+C would avoid Loop0 altogether. Code expansion would be > 4-fold for that
+C part of the function, but since it is not very large, that would be
+C acceptable.
+C
+C The mul loop (at L(oopM)) might need some tweaking. It's current speed is
+C unknown.
+
+defframe(PARAM_YSIZE,20)
+defframe(PARAM_YP, 16)
+defframe(PARAM_XSIZE,12)
+defframe(PARAM_XP, 8)
+defframe(PARAM_WP, 4)
+
+defframe(VAR_MULTIPLIER, -4)
+defframe(VAR_COUNTER, -8)
+deflit(VAR_STACK_SPACE, 8)
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_mul_basecase)
+deflit(`FRAME',0)
+
+ subl $VAR_STACK_SPACE,%esp
+ pushl %esi
+ pushl %ebp
+ pushl %edi
+deflit(`FRAME',eval(VAR_STACK_SPACE+12))
+
+ movl PARAM_XP,%esi
+ movl PARAM_WP,%edi
+ movl PARAM_YP,%ebp
+
+ movl (%esi),%eax C load xp[0]
+ mull (%ebp) C multiply by yp[0]
+ movl %eax,(%edi) C store to wp[0]
+ movl PARAM_XSIZE,%ecx C xsize
+ decl %ecx C If xsize = 1, ysize = 1 too
+ jz L(done)
+
+ pushl %ebx
+FRAME_pushl()
+ movl %edx,%ebx
+
+ leal 4(%esi),%esi
+ leal 4(%edi),%edi
+
+L(oopM):
+ movl (%esi),%eax C load next limb at xp[j]
+ leal 4(%esi),%esi
+ mull (%ebp)
+ addl %ebx,%eax
+ movl %edx,%ebx
+ adcl $0,%ebx
+ movl %eax,(%edi)
+ leal 4(%edi),%edi
+ decl %ecx
+ jnz L(oopM)
+
+ movl %ebx,(%edi) C most significant limb of product
+ addl $4,%edi C increment wp
+ movl PARAM_XSIZE,%eax
+ shll $2,%eax
+ subl %eax,%edi
+ subl %eax,%esi
+
+ movl PARAM_YSIZE,%eax C ysize
+ decl %eax
+ jz L(skip)
+ movl %eax,VAR_COUNTER C set index i to ysize
+
+L(outer):
+ movl PARAM_YP,%ebp C yp
+ addl $4,%ebp C make ebp point to next v limb
+ movl %ebp,PARAM_YP
+ movl (%ebp),%eax C copy y limb ...
+ movl %eax,VAR_MULTIPLIER C ... to stack slot
+ movl PARAM_XSIZE,%ecx
+
+ xorl %ebx,%ebx
+ andl $3,%ecx
+ jz L(end0)
+
+L(oop0):
+ movl (%esi),%eax
+ mull VAR_MULTIPLIER
+ leal 4(%esi),%esi
+ addl %ebx,%eax
+ movl $0,%ebx
+ adcl %ebx,%edx
+ addl %eax,(%edi)
+ adcl %edx,%ebx C propagate carry into cylimb
+
+ leal 4(%edi),%edi
+ decl %ecx
+ jnz L(oop0)
+
+L(end0):
+ movl PARAM_XSIZE,%ecx
+ shrl $2,%ecx
+ jz L(endX)
+
+ ALIGN(8)
+L(oopX):
+ movl (%esi),%eax
+ mull VAR_MULTIPLIER
+ addl %eax,%ebx
+ movl $0,%ebp
+ adcl %edx,%ebp
+
+ movl 4(%esi),%eax
+ mull VAR_MULTIPLIER
+ addl %ebx,(%edi)
+ adcl %eax,%ebp C new lo + cylimb
+ movl $0,%ebx
+ adcl %edx,%ebx
+
+ movl 8(%esi),%eax
+ mull VAR_MULTIPLIER
+ addl %ebp,4(%edi)
+ adcl %eax,%ebx C new lo + cylimb
+ movl $0,%ebp
+ adcl %edx,%ebp
+
+ movl 12(%esi),%eax
+ mull VAR_MULTIPLIER
+ addl %ebx,8(%edi)
+ adcl %eax,%ebp C new lo + cylimb
+ movl $0,%ebx
+ adcl %edx,%ebx
+
+ addl %ebp,12(%edi)
+ adcl $0,%ebx C propagate carry into cylimb
+
+ leal 16(%esi),%esi
+ leal 16(%edi),%edi
+ decl %ecx
+ jnz L(oopX)
+
+L(endX):
+ movl %ebx,(%edi)
+ addl $4,%edi
+
+ C we incremented wp and xp in the loop above; compensate
+ movl PARAM_XSIZE,%eax
+ shll $2,%eax
+ subl %eax,%edi
+ subl %eax,%esi
+
+ movl VAR_COUNTER,%eax
+ decl %eax
+ movl %eax,VAR_COUNTER
+ jnz L(outer)
+
+L(skip):
+ popl %ebx
+ popl %edi
+ popl %ebp
+ popl %esi
+ addl $8,%esp
+ ret
+
+L(done):
+ movl %edx,4(%edi) C store to wp[1]
+ popl %edi
+ popl %ebp
+ popl %esi
+ addl $8,%esp
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/nano/gmp-mparam.h b/gmp/mpn/x86/nano/gmp-mparam.h
new file mode 100644
index 0000000000..cd8ac4e1d6
--- /dev/null
+++ b/gmp/mpn/x86/nano/gmp-mparam.h
@@ -0,0 +1,162 @@
+/* x86/nano gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* Generated by tuneup.c, 2011-11-25, gcc 4.2 */
+
+#define MOD_1_1P_METHOD 1
+#define MOD_1_NORM_THRESHOLD 3
+#define MOD_1_UNNORM_THRESHOLD 3
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 10
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 9
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 53
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 12
+#define USE_PREINV_DIVREM_1 1
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 32
+
+#define MUL_TOOM22_THRESHOLD 16
+#define MUL_TOOM33_THRESHOLD 132
+#define MUL_TOOM44_THRESHOLD 195
+#define MUL_TOOM6H_THRESHOLD 270
+#define MUL_TOOM8H_THRESHOLD 478
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 129
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 138
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 130
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 135
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 28
+#define SQR_TOOM3_THRESHOLD 194
+#define SQR_TOOM4_THRESHOLD 502
+#define SQR_TOOM6_THRESHOLD 746
+#define SQR_TOOM8_THRESHOLD 1005
+
+#define MULMID_TOOM42_THRESHOLD 40
+
+#define MULMOD_BNM1_THRESHOLD 14
+#define SQRMOD_BNM1_THRESHOLD 19
+
+#define POWM_SEC_TABLE 4,23,258,828,2246
+
+#define MUL_FFT_MODF_THRESHOLD 308 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 308, 5}, { 13, 6}, { 7, 5}, { 17, 6}, \
+ { 9, 5}, { 19, 6}, { 11, 5}, { 23, 6}, \
+ { 13, 7}, { 7, 6}, { 17, 7}, { 9, 6}, \
+ { 19, 7}, { 11, 6}, { 24, 7}, { 15, 6}, \
+ { 31, 7}, { 19, 8}, { 11, 7}, { 25, 8}, \
+ { 15, 7}, { 33, 8}, { 19, 7}, { 39, 8}, \
+ { 23, 7}, { 47, 9}, { 15, 8}, { 31, 7}, \
+ { 63, 8}, { 39, 9}, { 23, 8}, { 47,10}, \
+ { 15, 9}, { 31, 8}, { 63, 9}, { 47,10}, \
+ { 31, 9}, { 71,10}, { 47, 9}, { 95,11}, \
+ { 31,10}, { 63, 9}, { 127, 8}, { 255,10}, \
+ { 79, 9}, { 159,10}, { 95, 9}, { 191,11}, \
+ { 63,10}, { 127, 9}, { 255, 8}, { 543, 9}, \
+ { 287, 8}, { 575, 7}, { 1215,10}, { 159,11}, \
+ { 95,10}, { 191,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 543, 8}, { 1087,10}, { 287, 9}, \
+ { 607, 8}, { 1215,11}, { 159,10}, { 319, 9}, \
+ { 639,10}, { 351, 9}, { 703, 8}, { 1407, 9}, \
+ { 735, 8}, { 1471,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 415, 9}, { 831,11}, { 223,10}, \
+ { 447, 9}, { 895,10}, { 479, 9}, { 959, 8}, \
+ { 1919,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
+ { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 89
+#define MUL_FFT_THRESHOLD 1856
+
+#define SQR_FFT_MODF_THRESHOLD 396 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 396, 5}, { 13, 6}, { 7, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 15, 6}, { 31, 7}, { 19, 6}, \
+ { 39, 7}, { 21, 8}, { 11, 7}, { 23, 6}, \
+ { 47, 7}, { 27, 8}, { 15, 7}, { 33, 8}, \
+ { 19, 7}, { 39, 8}, { 23, 7}, { 47, 8}, \
+ { 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
+ { 39, 9}, { 23, 8}, { 47,10}, { 15, 9}, \
+ { 31, 8}, { 63, 9}, { 39, 8}, { 79, 9}, \
+ { 47,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 127,10}, \
+ { 79, 9}, { 159,10}, { 95,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 543,10}, { 143, 9}, \
+ { 287, 8}, { 607, 7}, { 1215, 6}, { 2431,10}, \
+ { 159, 8}, { 639,11}, { 95,10}, { 191,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 543, 8}, \
+ { 1087,10}, { 287, 9}, { 607, 8}, { 1215,11}, \
+ { 159,10}, { 319, 9}, { 671,10}, { 351, 9}, \
+ { 703, 8}, { 1407, 9}, { 735, 8}, { 1471, 7}, \
+ { 2943,11}, { 191,10}, { 383, 9}, { 799,10}, \
+ { 415, 9}, { 895,10}, { 479,12}, { 4096,13}, \
+ { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 87
+#define SQR_FFT_THRESHOLD 2368
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 51
+#define MULLO_MUL_N_THRESHOLD 3369
+
+#define DC_DIV_QR_THRESHOLD 56
+#define DC_DIVAPPR_Q_THRESHOLD 183
+#define DC_BDIV_QR_THRESHOLD 55
+#define DC_BDIV_Q_THRESHOLD 118
+
+#define INV_MULMOD_BNM1_THRESHOLD 30
+#define INV_NEWTON_THRESHOLD 266
+#define INV_APPR_THRESHOLD 218
+
+#define BINV_NEWTON_THRESHOLD 268
+#define REDC_1_TO_REDC_N_THRESHOLD 56
+
+#define MU_DIV_QR_THRESHOLD 1308
+#define MU_DIVAPPR_Q_THRESHOLD 1528
+#define MUPI_DIV_QR_THRESHOLD 124
+#define MU_BDIV_QR_THRESHOLD 855
+#define MU_BDIV_Q_THRESHOLD 1334
+
+#define MATRIX22_STRASSEN_THRESHOLD 14
+#define HGCD_THRESHOLD 104
+#define HGCD_APPR_THRESHOLD 139
+#define HGCD_REDUCE_THRESHOLD 2121
+#define GCD_DC_THRESHOLD 456
+#define GCDEXT_DC_THRESHOLD 321
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 11
+#define GET_STR_PRECOMPUTE_THRESHOLD 25
+#define SET_STR_DC_THRESHOLD 542
+#define SET_STR_PRECOMPUTE_THRESHOLD 840
diff --git a/gmp/mpn/x86/p6/README b/gmp/mpn/x86/p6/README
new file mode 100644
index 0000000000..f19d47b94f
--- /dev/null
+++ b/gmp/mpn/x86/p6/README
@@ -0,0 +1,125 @@
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ INTEL P6 MPN SUBROUTINES
+
+
+
+This directory contains code optimized for Intel P6 class CPUs, meaning
+PentiumPro, Pentium II and Pentium III. The mmx and p3mmx subdirectories
+have routines using MMX instructions.
+
+
+
+STATUS
+
+Times for the loops, with all code and data in L1 cache, are as follows.
+Some of these might be able to be improved.
+
+ cycles/limb
+
+ mpn_add_n/sub_n 3.7
+
+ mpn_copyi 0.75
+ mpn_copyd 1.75 (or 0.75 if no overlap)
+
+ mpn_divrem_1 39.0
+ mpn_mod_1 21.5
+ mpn_divexact_by3 8.5
+
+ mpn_mul_1 5.5
+ mpn_addmul/submul_1 6.35
+
+ mpn_l/rshift 2.5
+
+ mpn_mul_basecase 8.2 cycles/crossproduct (approx)
+ mpn_sqr_basecase 4.0 cycles/crossproduct (approx)
+ or 7.75 cycles/triangleproduct (approx)
+
+Pentium II and III have MMX and get the following improvements.
+
+ mpn_divrem_1 25.0 integer part, 17.5 fractional part
+
+ mpn_l/rshift 1.75
+
+
+
+
+NOTES
+
+Write-allocate L1 data cache means prefetching of destinations is unnecessary.
+
+Mispredicted branches have a penalty of between 9 and 15 cycles, and even up
+to 26 cycles depending how far speculative execution has gone. The 9 cycle
+minimum penalty comes from the issue pipeline being 9 stages.
+
+A copy with rep movs seems to copy 16 bytes at a time, since speeds for 4,
+5, 6 or 7 limb operations are all the same. The 0.75 cycles/limb would be 3
+cycles per 16 byte block.
+
+
+
+
+CODING
+
+Instructions in general code have been shown grouped if they can execute
+together, which means up to three instructions with no successive
+dependencies, and with only the first being a multiple micro-op.
+
+P6 has out-of-order execution, so the groupings are really only showing
+dependent paths where some shuffling might allow some latencies to be
+hidden.
+
+
+
+
+REFERENCES
+
+"Intel Architecture Optimization Reference Manual", 1999, revision 001 dated
+02/99, order number 245127 (order number 730795-001 is in the document too).
+Available on-line:
+
+ http://download.intel.com/design/PentiumII/manuals/245127.htm
+
+"Intel Architecture Optimization Manual", 1997, order number 242816. This
+is an older document mostly about P5 and not as good as the above.
+Available on-line:
+
+ http://download.intel.com/design/PentiumII/manuals/242816.htm
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/x86/p6/aors_n.asm b/gmp/mpn/x86/p6/aors_n.asm
new file mode 100644
index 0000000000..df51c2e6f7
--- /dev/null
+++ b/gmp/mpn/x86/p6/aors_n.asm
@@ -0,0 +1,156 @@
+dnl Intel P6 mpn_add_n/mpn_sub_n -- mpn add or subtract.
+
+dnl Copyright 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO:
+C * Avoid indexed addressing, it makes us stall on the two-ported register
+C file.
+
+C cycles/limb
+C P6 model 0-8,10-12 3.17
+C P6 model 9 (Banias) 2.15
+C P6 model 13 (Dothan) 2.25
+
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`vp', `%ebx')
+define(`n', `%ecx')
+
+ifdef(`OPERATION_add_n', `
+ define(ADCSBB, adc)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(ADCSBB, sbb)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ASM_START()
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(func)
+ xor %edx, %edx
+L(start):
+ push %edi
+ push %esi
+ push %ebx
+
+ mov 16(%esp), rp
+ mov 20(%esp), up
+ mov 24(%esp), vp
+ mov 28(%esp), n
+
+ lea (up,n,4), up
+ lea (vp,n,4), vp
+ lea (rp,n,4), rp
+
+ neg n
+ mov n, %eax
+ and $-8, n
+ and $7, %eax
+ shl $2, %eax C 4x
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ lea L(ent) (%eax,%eax,2), %eax C 12x
+')
+
+ shr %edx C set cy flag
+ jmp *%eax
+
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ lea (%eax,%eax,2), %eax
+ add $L(ent)-L(here), %eax
+ add (%esp), %eax
+ ret_internal
+')
+
+L(end):
+ sbb %eax, %eax
+ neg %eax
+ pop %ebx
+ pop %esi
+ pop %edi
+ ret
+
+ ALIGN(16)
+L(top):
+ jecxz L(end)
+L(ent):
+Zdisp( mov, 0,(up,n,4), %eax)
+Zdisp( ADCSBB, 0,(vp,n,4), %eax)
+Zdisp( mov, %eax, 0,(rp,n,4))
+
+ mov 4(up,n,4), %edx
+ ADCSBB 4(vp,n,4), %edx
+ mov %edx, 4(rp,n,4)
+
+ mov 8(up,n,4), %eax
+ ADCSBB 8(vp,n,4), %eax
+ mov %eax, 8(rp,n,4)
+
+ mov 12(up,n,4), %edx
+ ADCSBB 12(vp,n,4), %edx
+ mov %edx, 12(rp,n,4)
+
+ mov 16(up,n,4), %eax
+ ADCSBB 16(vp,n,4), %eax
+ mov %eax, 16(rp,n,4)
+
+ mov 20(up,n,4), %edx
+ ADCSBB 20(vp,n,4), %edx
+ mov %edx, 20(rp,n,4)
+
+ mov 24(up,n,4), %eax
+ ADCSBB 24(vp,n,4), %eax
+ mov %eax, 24(rp,n,4)
+
+ mov 28(up,n,4), %edx
+ ADCSBB 28(vp,n,4), %edx
+ mov %edx, 28(rp,n,4)
+
+ lea 8(n), n
+ jmp L(top)
+
+EPILOGUE()
+
+PROLOGUE(func_nc)
+ movl 20(%esp), %edx
+ jmp L(start)
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/aorsmul_1.asm b/gmp/mpn/x86/p6/aorsmul_1.asm
new file mode 100644
index 0000000000..bc8c49c62e
--- /dev/null
+++ b/gmp/mpn/x86/p6/aorsmul_1.asm
@@ -0,0 +1,320 @@
+dnl Intel P6 mpn_addmul_1/mpn_submul_1 -- add or subtract mpn multiple.
+
+dnl Copyright 1999-2002, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5
+C P6 model 0-8,10-12 6.44
+C P6 model 9 (Banias) 6.15
+C P6 model 13 (Dothan) 6.11
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood)
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C AMD K6
+C AMD K7
+C AMD K8
+
+
+dnl P6 UNROLL_COUNT cycles/limb
+dnl 8 6.7
+dnl 16 6.35
+dnl 32 6.3
+dnl 64 6.3
+dnl Maximum possible with the current code is 64.
+
+deflit(UNROLL_COUNT, 16)
+
+
+ifdef(`OPERATION_addmul_1', `
+ define(M4_inst, addl)
+ define(M4_function_1, mpn_addmul_1)
+ define(M4_function_1c, mpn_addmul_1c)
+ define(M4_description, add it to)
+ define(M4_desc_retval, carry)
+',`ifdef(`OPERATION_submul_1', `
+ define(M4_inst, subl)
+ define(M4_function_1, mpn_submul_1)
+ define(M4_function_1c, mpn_submul_1c)
+ define(M4_description, subtract it from)
+ define(M4_desc_retval, borrow)
+',`m4_error(`Need OPERATION_addmul_1 or OPERATION_submul_1
+')')')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_addmul_1c mpn_submul_1 mpn_submul_1c)
+
+
+C mp_limb_t M4_function_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult);
+C mp_limb_t M4_function_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult, mp_limb_t carry);
+C
+C Calculate src,size multiplied by mult and M4_description dst,size.
+C Return the M4_desc_retval limb from the top of the result.
+C
+C This code is pretty much the same as the K6 code. The unrolled loop is
+C the same, but there's just a few scheduling tweaks in the setups and the
+C simple loop.
+C
+C A number of variations have been tried for the unrolled loop, with one or
+C two carries, and with loads scheduled earlier, but nothing faster than 6
+C cycles/limb has been found.
+
+ifdef(`PIC',`
+deflit(UNROLL_THRESHOLD, 5)
+',`
+deflit(UNROLL_THRESHOLD, 5)
+')
+
+defframe(PARAM_CARRY, 20)
+defframe(PARAM_MULTIPLIER,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(32)
+
+PROLOGUE(M4_function_1c)
+ pushl %ebx
+deflit(`FRAME',4)
+ movl PARAM_CARRY, %ebx
+ jmp L(start_nc)
+EPILOGUE()
+
+PROLOGUE(M4_function_1)
+ push %ebx
+deflit(`FRAME',4)
+ xorl %ebx, %ebx C initial carry
+
+L(start_nc):
+ movl PARAM_SIZE, %ecx
+ pushl %esi
+deflit(`FRAME',8)
+
+ movl PARAM_SRC, %esi
+ pushl %edi
+deflit(`FRAME',12)
+
+ movl PARAM_DST, %edi
+ pushl %ebp
+deflit(`FRAME',16)
+ cmpl $UNROLL_THRESHOLD, %ecx
+
+ movl PARAM_MULTIPLIER, %ebp
+ jae L(unroll)
+
+
+ C simple loop
+ C this is offset 0x22, so close enough to aligned
+L(simple):
+ C eax scratch
+ C ebx carry
+ C ecx counter
+ C edx scratch
+ C esi src
+ C edi dst
+ C ebp multiplier
+
+ movl (%esi), %eax
+ addl $4, %edi
+
+ mull %ebp
+
+ addl %ebx, %eax
+ adcl $0, %edx
+
+ M4_inst %eax, -4(%edi)
+ movl %edx, %ebx
+
+ adcl $0, %ebx
+ decl %ecx
+
+ leal 4(%esi), %esi
+ jnz L(simple)
+
+
+ popl %ebp
+ popl %edi
+
+ popl %esi
+ movl %ebx, %eax
+
+ popl %ebx
+ ret
+
+
+
+C------------------------------------------------------------------------------
+C VAR_JUMP holds the computed jump temporarily because there's not enough
+C registers when doing the mul for the initial two carry limbs.
+C
+C The add/adc for the initial carry in %ebx is necessary only for the
+C mpn_add/submul_1c entry points. Duplicating the startup code to
+C eliminate this for the plain mpn_add/submul_1 doesn't seem like a good
+C idea.
+
+dnl overlapping with parameters already fetched
+define(VAR_COUNTER,`PARAM_SIZE')
+define(VAR_JUMP, `PARAM_DST')
+
+ C this is offset 0x43, so close enough to aligned
+L(unroll):
+ C eax
+ C ebx initial carry
+ C ecx size
+ C edx
+ C esi src
+ C edi dst
+ C ebp
+
+ movl %ecx, %edx
+ decl %ecx
+
+ subl $2, %edx
+ negl %ecx
+
+ shrl $UNROLL_LOG2, %edx
+ andl $UNROLL_MASK, %ecx
+
+ movl %edx, VAR_COUNTER
+ movl %ecx, %edx
+
+ C 15 code bytes per limb
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ shll $4, %edx
+ negl %ecx
+
+ leal L(entry) (%edx,%ecx,1), %edx
+')
+ movl (%esi), %eax C src low limb
+
+ movl %edx, VAR_JUMP
+ leal ifelse(UNROLL_BYTES,256,128+) 4(%esi,%ecx,4), %esi
+
+ mull %ebp
+
+ addl %ebx, %eax C initial carry (from _1c)
+ adcl $0, %edx
+
+ movl %edx, %ebx C high carry
+ leal ifelse(UNROLL_BYTES,256,128) (%edi,%ecx,4), %edi
+
+ movl VAR_JUMP, %edx
+ testl $1, %ecx
+ movl %eax, %ecx C low carry
+
+ cmovnz( %ebx, %ecx) C high,low carry other way around
+ cmovnz( %eax, %ebx)
+
+ jmp *%edx
+
+
+ifdef(`PIC',`
+L(pic_calc):
+ shll $4, %edx
+ negl %ecx
+
+ C See mpn/x86/README about old gas bugs
+ leal (%edx,%ecx,1), %edx
+ addl $L(entry)-L(here), %edx
+
+ addl (%esp), %edx
+
+ ret_internal
+')
+
+
+C -----------------------------------------------------------
+ ALIGN(32)
+L(top):
+deflit(`FRAME',16)
+ C eax scratch
+ C ebx carry hi
+ C ecx carry lo
+ C edx scratch
+ C esi src
+ C edi dst
+ C ebp multiplier
+ C
+ C VAR_COUNTER loop counter
+ C
+ C 15 code bytes per limb
+
+ addl $UNROLL_BYTES, %edi
+
+L(entry):
+deflit(CHUNK_COUNT,2)
+forloop(`i', 0, UNROLL_COUNT/CHUNK_COUNT-1, `
+ deflit(`disp0', eval(i*4*CHUNK_COUNT ifelse(UNROLL_BYTES,256,-128)))
+ deflit(`disp1', eval(disp0 + 4))
+
+Zdisp( movl, disp0,(%esi), %eax)
+ mull %ebp
+Zdisp( M4_inst,%ecx, disp0,(%edi))
+ adcl %eax, %ebx
+ movl %edx, %ecx
+ adcl $0, %ecx
+
+ movl disp1(%esi), %eax
+ mull %ebp
+ M4_inst %ebx, disp1(%edi)
+ adcl %eax, %ecx
+ movl %edx, %ebx
+ adcl $0, %ebx
+')
+
+ decl VAR_COUNTER
+ leal UNROLL_BYTES(%esi), %esi
+
+ jns L(top)
+
+
+deflit(`disp0', eval(UNROLL_BYTES ifelse(UNROLL_BYTES,256,-128)))
+
+ M4_inst %ecx, disp0(%edi)
+ movl %ebx, %eax
+
+ popl %ebp
+ popl %edi
+
+ popl %esi
+ popl %ebx
+ adcl $0, %eax
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/bdiv_q_1.asm b/gmp/mpn/x86/p6/bdiv_q_1.asm
new file mode 100644
index 0000000000..2cc179c238
--- /dev/null
+++ b/gmp/mpn/x86/p6/bdiv_q_1.asm
@@ -0,0 +1,286 @@
+dnl Intel P6 mpn_modexact_1_odd -- exact division style remainder.
+
+dnl Rearranged from mpn/x86/p6/dive_1.asm by Marco Bodrato.
+
+dnl Copyright 2001, 2002, 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C odd even divisor
+C P6: 10.0 12.0 cycles/limb
+
+C MULFUNC_PROLOGUE(mpn_bdiv_q_1 mpn_pi1_bdiv_q_1)
+
+C The odd case is basically the same as mpn_modexact_1_odd, just with an
+C extra store, and it runs at the same 10 cycles which is the dependent
+C chain.
+C
+C The shifts for the even case aren't on the dependent chain so in principle
+C it could run the same too, but nothing running at 10 has been found.
+C Perhaps there's too many uops (an extra 4 over the odd case).
+
+defframe(PARAM_SHIFT, 24)
+defframe(PARAM_INVERSE,20)
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+deflit(STACK_SPACE, 16)
+
+dnl re-use parameter space
+define(VAR_INVERSE,`PARAM_SRC')
+
+ TEXT
+
+C mp_limb_t
+C mpn_pi1_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor,
+C mp_limb_t inverse, int shift)
+
+ ALIGN(16)
+PROLOGUE(mpn_pi1_bdiv_q_1)
+deflit(`FRAME',0)
+
+ subl $STACK_SPACE, %esp FRAME_subl_esp(STACK_SPACE)
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_SIZE, %ebx
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_INVERSE, %ebp
+
+ movl PARAM_SHIFT, %ecx C trailing twos
+
+L(common):
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ leal (%esi,%ebx,4), %esi C src end
+
+ leal (%edi,%ebx,4), %edi C dst end
+ negl %ebx C -size
+
+ movl (%esi,%ebx,4), %eax C src[0]
+
+ orl %ecx, %ecx
+ jz L(odd_entry)
+
+ movl %edi, PARAM_DST
+ movl %ebp, VAR_INVERSE
+
+L(even):
+ C eax src[0]
+ C ebx counter, limbs, negative
+ C ecx shift
+ C edx
+ C esi
+ C edi
+ C ebp
+
+ xorl %ebp, %ebp C initial carry bit
+ xorl %edx, %edx C initial carry limb (for size==1)
+
+ incl %ebx
+ jz L(even_one)
+
+ movl (%esi,%ebx,4), %edi C src[1]
+
+ shrdl( %cl, %edi, %eax)
+
+ jmp L(even_entry)
+
+
+L(even_top):
+ C eax scratch
+ C ebx counter, limbs, negative
+ C ecx shift
+ C edx scratch
+ C esi &src[size]
+ C edi &dst[size] and scratch
+ C ebp carry bit
+
+ movl (%esi,%ebx,4), %edi
+
+ mull PARAM_DIVISOR
+
+ movl -4(%esi,%ebx,4), %eax
+ shrdl( %cl, %edi, %eax)
+
+ subl %ebp, %eax
+
+ sbbl %ebp, %ebp
+ subl %edx, %eax
+
+ sbbl $0, %ebp
+
+L(even_entry):
+ imull VAR_INVERSE, %eax
+
+ movl PARAM_DST, %edi
+ negl %ebp
+
+ movl %eax, -4(%edi,%ebx,4)
+ incl %ebx
+ jnz L(even_top)
+
+ mull PARAM_DIVISOR
+
+ movl -4(%esi), %eax
+
+L(even_one):
+ shrl %cl, %eax
+ movl SAVE_ESI, %esi
+
+ subl %ebp, %eax
+ movl SAVE_EBP, %ebp
+
+ subl %edx, %eax
+ movl SAVE_EBX, %ebx
+
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi)
+ movl SAVE_EDI, %edi
+ addl $STACK_SPACE, %esp
+
+ ret
+
+C The dependent chain here is
+C
+C subl %edx, %eax 1
+C imull %ebp, %eax 4
+C mull PARAM_DIVISOR 5
+C ----
+C total 10
+C
+C and this is the measured speed. No special scheduling is necessary, out
+C of order execution hides the load latency.
+
+L(odd_top):
+ C eax scratch (src limb)
+ C ebx counter, limbs, negative
+ C ecx carry bit
+ C edx carry limb, high of last product
+ C esi &src[size]
+ C edi &dst[size]
+ C ebp inverse
+
+ mull PARAM_DIVISOR
+
+ movl (%esi,%ebx,4), %eax
+ subl %ecx, %eax
+
+ sbbl %ecx, %ecx
+ subl %edx, %eax
+
+ sbbl $0, %ecx
+
+L(odd_entry):
+ imull %ebp, %eax
+
+ movl %eax, (%edi,%ebx,4)
+ negl %ecx
+
+ incl %ebx
+ jnz L(odd_top)
+
+
+ movl SAVE_ESI, %esi
+
+ movl SAVE_EDI, %edi
+
+ movl SAVE_EBP, %ebp
+
+ movl SAVE_EBX, %ebx
+ addl $STACK_SPACE, %esp
+
+ ret
+
+EPILOGUE()
+
+C mp_limb_t mpn_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+
+ ALIGN(16)
+PROLOGUE(mpn_bdiv_q_1)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %eax
+ subl $STACK_SPACE, %esp FRAME_subl_esp(STACK_SPACE)
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_SIZE, %ebx
+
+ bsfl %eax, %ecx C trailing twos
+
+ movl %ebp, SAVE_EBP
+
+ shrl %cl, %eax C d without twos
+
+ movl %eax, %edx
+ shrl %eax C d/2 without twos
+
+ movl %edx, PARAM_DIVISOR
+ andl $127, %eax
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %ebp)
+ movzbl (%eax,%ebp), %ebp C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %ebp C inv 8 bits
+')
+
+ leal (%ebp,%ebp), %eax C 2*inv
+
+ imull %ebp, %ebp C inv*inv
+ imull %edx, %ebp C inv*inv*d
+
+ subl %ebp, %eax C inv = 2*inv - inv*inv*d
+ leal (%eax,%eax), %ebp C 2*inv
+
+ imull %eax, %eax C inv*inv
+ imull %edx, %eax C inv*inv*d
+
+ subl %eax, %ebp C inv = 2*inv - inv*inv*d
+
+ jmp L(common)
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/copyd.asm b/gmp/mpn/x86/p6/copyd.asm
new file mode 100644
index 0000000000..1be7636835
--- /dev/null
+++ b/gmp/mpn/x86/p6/copyd.asm
@@ -0,0 +1,178 @@
+dnl Intel P6 mpn_copyd -- copy limb vector backwards.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P6: 1.75 cycles/limb, or 0.75 if no overlap
+
+
+C void mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C An explicit loop is used because a decrementing rep movsl is a bit slow at
+C 2.4 c/l. That rep movsl also has about a 40 cycle startup time, and the
+C code here stands a chance of being faster if the branches predict well.
+C
+C The slightly strange loop form seems necessary for the claimed speed.
+C Maybe load/store ordering affects it.
+C
+C The source and destination are checked to see if they're actually
+C overlapping, since it might be possible to use an incrementing rep movsl
+C at 0.75 c/l. (It doesn't suffer the bad startup time of the decrementing
+C version.)
+C
+C Enhancements:
+C
+C Top speed for an all-integer copy is probably 1.0 c/l, being one load and
+C one store each cycle. Unrolling the loop below would approach 1.0, but
+C it'd be good to know why something like store/load/subl + store/load/jnz
+C doesn't already run at 1.0 c/l. It looks like it should decode in 2
+C cycles, but doesn't run that way.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-using parameter space
+define(SAVE_ESI,`PARAM_SIZE')
+define(SAVE_EDI,`PARAM_SRC')
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(mpn_copyd)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ subl $1, %ecx
+ jb L(zero)
+
+ movl (%esi,%ecx,4), %eax C src[size-1]
+ jz L(one)
+
+ movl -4(%esi,%ecx,4), %edx C src[size-2]
+ subl $2, %ecx
+ jbe L(done_loop) C 2 or 3 limbs only
+
+
+ C The usual overlap is
+ C
+ C high low
+ C +------------------+
+ C | dst|
+ C +------------------+
+ C +------------------+
+ C | src|
+ C +------------------+
+ C
+ C We can use an incrementing copy in the following circumstances.
+ C
+ C src+4*size<=dst, since then the regions are disjoint
+ C
+ C src==dst, clearly (though this shouldn't occur normally)
+ C
+ C src>dst, since in that case it's a requirement of the
+ C parameters that src>=dst+size*4, and hence the
+ C regions are disjoint
+ C
+
+ leal (%edi,%ecx,4), %edx
+ cmpl %edi, %esi
+ jae L(use_movsl) C src >= dst
+
+ cmpl %edi, %edx
+ movl 4(%esi,%ecx,4), %edx C src[size-2] again
+ jbe L(use_movsl) C src+4*size <= dst
+
+
+L(top):
+ C eax prev high limb
+ C ebx
+ C ecx counter, size-3 down to 0 or -1, inclusive, by 2s
+ C edx prev low limb
+ C esi src
+ C edi dst
+ C ebp
+
+ movl %eax, 8(%edi,%ecx,4)
+ movl (%esi,%ecx,4), %eax
+
+ movl %edx, 4(%edi,%ecx,4)
+ movl -4(%esi,%ecx,4), %edx
+
+ subl $2, %ecx
+ jnbe L(top)
+
+
+L(done_loop):
+ movl %eax, 8(%edi,%ecx,4)
+ movl %edx, 4(%edi,%ecx,4)
+
+ C copy low limb (needed if size was odd, but will already have been
+ C done in the loop if size was even)
+ movl (%esi), %eax
+L(one):
+ movl %eax, (%edi)
+ movl SAVE_EDI, %edi
+ movl SAVE_ESI, %esi
+
+ ret
+
+
+L(use_movsl):
+ C eax
+ C ebx
+ C ecx size-3
+ C edx
+ C esi src
+ C edi dst
+ C ebp
+
+ addl $3, %ecx
+
+ cld C better safe than sorry, see mpn/x86/README
+
+ rep
+ movsl
+
+L(zero):
+ movl SAVE_ESI, %esi
+ movl SAVE_EDI, %edi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/dive_1.asm b/gmp/mpn/x86/p6/dive_1.asm
new file mode 100644
index 0000000000..aa7ba880c9
--- /dev/null
+++ b/gmp/mpn/x86/p6/dive_1.asm
@@ -0,0 +1,266 @@
+dnl Intel P6 mpn_modexact_1_odd -- exact division style remainder.
+
+dnl Copyright 2001, 2002, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C odd even divisor
+C P6: 10.0 12.0 cycles/limb
+
+
+C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+C The odd case is basically the same as mpn_modexact_1_odd, just with an
+C extra store, and it runs at the same 10 cycles which is the dependent
+C chain.
+C
+C The shifts for the even case aren't on the dependent chain so in principle
+C it could run the same too, but nothing running at 10 has been found.
+C Perhaps there's too many uops (an extra 4 over the odd case).
+
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+defframe(VAR_INVERSE, -20)
+deflit(STACK_SPACE, 20)
+
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(mpn_divexact_1)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %eax
+ subl $STACK_SPACE, %esp FRAME_subl_esp(STACK_SPACE)
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_SIZE, %ebx
+
+ bsfl %eax, %ecx C trailing twos
+
+ movl %ebp, SAVE_EBP
+
+ shrl %cl, %eax C d without twos
+
+ movl %eax, %edx
+ shrl %eax C d/2 without twos
+
+ movl %edx, PARAM_DIVISOR
+ andl $127, %eax
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %ebp)
+ movzbl (%eax,%ebp), %ebp C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %ebp C inv 8 bits
+')
+
+ leal (%ebp,%ebp), %eax C 2*inv
+
+ imull %ebp, %ebp C inv*inv
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ leal (%esi,%ebx,4), %esi C src end
+
+ imull PARAM_DIVISOR, %ebp C inv*inv*d
+
+ subl %ebp, %eax C inv = 2*inv - inv*inv*d
+ leal (%eax,%eax), %ebp C 2*inv
+
+ imull %eax, %eax C inv*inv
+
+ leal (%edi,%ebx,4), %edi C dst end
+ negl %ebx C -size
+
+ movl %edi, PARAM_DST
+
+ imull PARAM_DIVISOR, %eax C inv*inv*d
+
+ subl %eax, %ebp C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C d*inv == 1 mod 2^GMP_LIMB_BITS
+ movl PARAM_DIVISOR, %eax
+ imull %ebp, %eax
+ cmpl $1, %eax')
+
+ movl %ebp, VAR_INVERSE
+ movl (%esi,%ebx,4), %eax C src[0]
+
+ orl %ecx, %ecx
+ jnz L(even)
+
+ C ecx initial carry is zero
+ jmp L(odd_entry)
+
+
+C The dependent chain here is
+C
+C subl %edx, %eax 1
+C imull %ebp, %eax 4
+C mull PARAM_DIVISOR 5
+C ----
+C total 10
+C
+C and this is the measured speed. No special scheduling is necessary, out
+C of order execution hides the load latency.
+
+L(odd_top):
+ C eax scratch (src limb)
+ C ebx counter, limbs, negative
+ C ecx carry bit
+ C edx carry limb, high of last product
+ C esi &src[size]
+ C edi &dst[size]
+ C ebp
+
+ mull PARAM_DIVISOR
+
+ movl (%esi,%ebx,4), %eax
+ subl %ecx, %eax
+
+ sbbl %ecx, %ecx
+ subl %edx, %eax
+
+ sbbl $0, %ecx
+
+L(odd_entry):
+ imull VAR_INVERSE, %eax
+
+ movl %eax, (%edi,%ebx,4)
+ negl %ecx
+
+ incl %ebx
+ jnz L(odd_top)
+
+
+ movl SAVE_ESI, %esi
+
+ movl SAVE_EDI, %edi
+
+ movl SAVE_EBP, %ebp
+
+ movl SAVE_EBX, %ebx
+ addl $STACK_SPACE, %esp
+
+ ret
+
+
+L(even):
+ C eax src[0]
+ C ebx counter, limbs, negative
+ C ecx shift
+ C edx
+ C esi
+ C edi
+ C ebp
+
+ xorl %ebp, %ebp C initial carry bit
+ xorl %edx, %edx C initial carry limb (for size==1)
+
+ incl %ebx
+ jz L(even_one)
+
+ movl (%esi,%ebx,4), %edi C src[1]
+
+ shrdl( %cl, %edi, %eax)
+
+ jmp L(even_entry)
+
+
+L(even_top):
+ C eax scratch
+ C ebx counter, limbs, negative
+ C ecx shift
+ C edx scratch
+ C esi &src[size]
+ C edi &dst[size] and scratch
+ C ebp carry bit
+
+ movl (%esi,%ebx,4), %edi
+
+ mull PARAM_DIVISOR
+
+ movl -4(%esi,%ebx,4), %eax
+ shrdl( %cl, %edi, %eax)
+
+ subl %ebp, %eax
+
+ sbbl %ebp, %ebp
+ subl %edx, %eax
+
+ sbbl $0, %ebp
+
+L(even_entry):
+ imull VAR_INVERSE, %eax
+
+ movl PARAM_DST, %edi
+ negl %ebp
+
+ movl %eax, -4(%edi,%ebx,4)
+ incl %ebx
+ jnz L(even_top)
+
+
+
+ mull PARAM_DIVISOR
+
+ movl -4(%esi), %eax
+
+L(even_one):
+ shrl %cl, %eax
+ movl SAVE_ESI, %esi
+
+ subl %ebp, %eax
+ movl SAVE_EBP, %ebp
+
+ subl %edx, %eax
+ movl SAVE_EBX, %ebx
+
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi)
+ movl SAVE_EDI, %edi
+ addl $STACK_SPACE, %esp
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/gcd_1.asm b/gmp/mpn/x86/p6/gcd_1.asm
new file mode 100644
index 0000000000..f6518f6e19
--- /dev/null
+++ b/gmp/mpn/x86/p6/gcd_1.asm
@@ -0,0 +1,156 @@
+dnl x86 mpn_gcd_1 optimised for processors with fast BSF.
+
+dnl Based on the K7 gcd_1.asm, by Kevin Ryde. Rehacked by Torbjorn Granlund.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/bit (approx)
+C AMD K7 7.80
+C AMD K8,K9 7.79
+C AMD K10 4.08
+C AMD bd1 ?
+C AMD bobcat 7.82
+C Intel P4-2 14.9
+C Intel P4-3/4 14.0
+C Intel P6/13 5.09
+C Intel core2 4.22
+C Intel NHM 5.00
+C Intel SBR 5.00
+C Intel atom 17.1
+C VIA nano ?
+C Numbers measured with: speed -CD -s16-32 -t16 mpn_gcd_1
+
+C Threshold of when to call bmod when U is one limb. Should be about
+C (time_in_cycles(bmod_1,1) + call_overhead) / (cycles/bit).
+define(`BMOD_THRES_LOG2', 6)
+
+
+define(`up', `%edi')
+define(`n', `%esi')
+define(`v0', `%edx')
+
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_gcd_1)
+ push %edi
+ push %esi
+
+ mov 12(%esp), up
+ mov 16(%esp), n
+ mov 20(%esp), v0
+
+ mov (up), %eax C U low limb
+ or v0, %eax
+ bsf %eax, %eax C min(ctz(u0),ctz(v0))
+
+ bsf v0, %ecx
+ shr %cl, v0
+
+ push %eax C preserve common twos over call
+ push v0 C preserve v0 argument over call
+
+ cmp $1, n
+ jnz L(reduce_nby1)
+
+C Both U and V are single limbs, reduce with bmod if u0 >> v0.
+ mov (up), %ecx
+ mov %ecx, %eax
+ shr $BMOD_THRES_LOG2, %ecx
+ cmp %ecx, v0
+ ja L(reduced)
+ jmp L(bmod)
+
+L(reduce_nby1):
+ cmp $BMOD_1_TO_MOD_1_THRESHOLD, n
+ jl L(bmod)
+ifdef(`PIC_WITH_EBX',`
+ push %ebx
+ call L(movl_eip_to_ebx)
+ add $_GLOBAL_OFFSET_TABLE_, %ebx
+')
+ push v0 C param 3
+ push n C param 2
+ push up C param 1
+ CALL( mpn_mod_1)
+ jmp L(called)
+
+L(bmod):
+ifdef(`PIC_WITH_EBX',`dnl
+ push %ebx
+ call L(movl_eip_to_ebx)
+ add $_GLOBAL_OFFSET_TABLE_, %ebx
+')
+ push v0 C param 3
+ push n C param 2
+ push up C param 1
+ CALL( mpn_modexact_1_odd)
+
+L(called):
+ add $12, %esp C deallocate params
+ifdef(`PIC_WITH_EBX',`dnl
+ pop %ebx
+')
+L(reduced):
+ pop %edx
+
+ bsf %eax, %ecx
+C test %eax, %eax C FIXME: does this lower latency?
+ jnz L(mid)
+ jmp L(end)
+
+ ALIGN(16) C K10 BD C2 NHM SBR
+L(top): cmovc( %esi, %eax) C if x-y < 0 0,3 0,3 0,6 0,5 0,5
+ cmovc( %edi, %edx) C use x,y-x 0,3 0,3 2,8 1,7 1,7
+L(mid): shr %cl, %eax C 1,7 1,6 2,8 2,8 2,8
+ mov %edx, %esi C 1 1 4 3 3
+ sub %eax, %esi C 2 2 5 4 4
+ bsf %esi, %ecx C 3 3 6 5 5
+ mov %eax, %edi C 2 2 3 3 4
+ sub %edx, %eax C 2 2 4 3 4
+ jnz L(top) C
+
+L(end): pop %ecx
+ mov %edx, %eax
+ shl %cl, %eax
+
+ pop %esi
+ pop %edi
+ ret
+
+ifdef(`PIC_WITH_EBX',`dnl
+L(movl_eip_to_ebx):
+ mov (%esp), %ebx
+ ret
+')
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/gmp-mparam.h b/gmp/mpn/x86/p6/gmp-mparam.h
new file mode 100644
index 0000000000..96c96fd558
--- /dev/null
+++ b/gmp/mpn/x86/p6/gmp-mparam.h
@@ -0,0 +1,194 @@
+/* Intel P6 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2003, 2008-2010, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* NOTE: In a fat binary build SQR_TOOM2_THRESHOLD here cannot be more than the
+ value in mpn/x86/p6/gmp-mparam.h. The latter is used as a hard limit in
+ mpn/x86/p6/sqr_basecase.asm. */
+
+
+/* 1867 MHz P6 model 13 */
+
+#define MOD_1_NORM_THRESHOLD 4
+#define MOD_1_UNNORM_THRESHOLD 4
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 11
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 8
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 21
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 74
+#define MUL_TOOM44_THRESHOLD 181
+#define MUL_TOOM6H_THRESHOLD 252
+#define MUL_TOOM8H_THRESHOLD 363
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 114
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 115
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 80
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 101
+#define SQR_TOOM4_THRESHOLD 154
+#define SQR_TOOM6_THRESHOLD 222
+#define SQR_TOOM8_THRESHOLD 527
+
+#define MULMID_TOOM42_THRESHOLD 58
+
+#define MULMOD_BNM1_THRESHOLD 13
+#define SQRMOD_BNM1_THRESHOLD 17
+
+#define POWM_SEC_TABLE 4,23,258,768,2388
+
+#define MUL_FFT_MODF_THRESHOLD 565 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 565, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 25, 7}, { 13, 6}, { 28, 7}, { 15, 6}, \
+ { 31, 7}, { 17, 6}, { 35, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 5}, \
+ { 383, 4}, { 991, 5}, { 511, 6}, { 267, 7}, \
+ { 157, 8}, { 91, 9}, { 47, 8}, { 111, 9}, \
+ { 63, 8}, { 127, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 159,10}, { 95,11}, { 63,10}, \
+ { 143, 9}, { 287,10}, { 159,11}, { 95,10}, \
+ { 191,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,10}, { 287,11}, \
+ { 159,10}, { 335, 9}, { 671,11}, { 191,10}, \
+ { 383, 9}, { 767,10}, { 399, 9}, { 799,10}, \
+ { 415,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607,11}, \
+ { 319,10}, { 671,12}, { 191,11}, { 383,10}, \
+ { 799,11}, { 415,10}, { 831,13}, { 127,12}, \
+ { 255,11}, { 543,10}, { 1087,11}, { 607,10}, \
+ { 1215,12}, { 319,11}, { 671,10}, { 1343,11}, \
+ { 735,10}, { 1471,12}, { 383,11}, { 799,10}, \
+ { 1599,11}, { 863,12}, { 447,11}, { 959,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1215,12}, { 639,11}, { 1343,12}, { 703,11}, \
+ { 1471,13}, { 383,12}, { 831,11}, { 1727,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1215,13}, \
+ { 639,12}, { 1471,11}, { 2943,13}, { 767,12}, \
+ { 1727,13}, { 895,12}, { 1919,14}, { 511,13}, \
+ { 1023,12}, { 2111,13}, { 1151,12}, { 2431,13}, \
+ { 1407,12}, { 2815,14}, { 767,13}, { 1663,12}, \
+ { 3455,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 132
+#define MUL_FFT_THRESHOLD 6784
+
+#define SQR_FFT_MODF_THRESHOLD 472 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 472, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 17, 6}, { 35, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
+ { 31, 8}, { 63, 4}, { 1023, 8}, { 67, 9}, \
+ { 39, 5}, { 639, 4}, { 1471, 6}, { 383, 7}, \
+ { 209, 8}, { 119, 9}, { 63, 7}, { 255, 8}, \
+ { 139, 9}, { 71, 8}, { 143, 9}, { 79,10}, \
+ { 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
+ { 135,10}, { 79, 9}, { 159, 8}, { 319, 9}, \
+ { 167,10}, { 95,11}, { 63,10}, { 143, 9}, \
+ { 287,10}, { 159,11}, { 95,10}, { 191,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 543, 8}, \
+ { 1087,10}, { 287, 9}, { 575,11}, { 159,10}, \
+ { 319, 9}, { 639,10}, { 335, 9}, { 671,10}, \
+ { 351, 9}, { 703,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 399, 9}, { 799,10}, { 415, 9}, \
+ { 831,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607, 9}, \
+ { 1215,11}, { 319,10}, { 671, 9}, { 1343,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 383,10}, \
+ { 799,11}, { 415,10}, { 831,13}, { 127,12}, \
+ { 255,11}, { 543,10}, { 1087,11}, { 607,12}, \
+ { 319,11}, { 671,10}, { 1343,11}, { 735,12}, \
+ { 383,11}, { 799,10}, { 1599,11}, { 863,12}, \
+ { 447,11}, { 959,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
+ { 1343,12}, { 703,11}, { 1471,13}, { 383,12}, \
+ { 767,11}, { 1599,12}, { 831,11}, { 1727,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1215,13}, \
+ { 639,12}, { 1471,13}, { 767,12}, { 1727,13}, \
+ { 895,12}, { 1919,14}, { 511,13}, { 1023,12}, \
+ { 2111,13}, { 1151,12}, { 2431,13}, { 1407,14}, \
+ { 767,13}, { 1663,12}, { 3455,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 146
+#define SQR_FFT_THRESHOLD 5760
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 33
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 20
+#define DC_DIVAPPR_Q_THRESHOLD 56
+#define DC_BDIV_QR_THRESHOLD 60
+#define DC_BDIV_Q_THRESHOLD 134
+
+#define INV_MULMOD_BNM1_THRESHOLD 38
+#define INV_NEWTON_THRESHOLD 66
+#define INV_APPR_THRESHOLD 63
+
+#define BINV_NEWTON_THRESHOLD 250
+#define REDC_1_TO_REDC_N_THRESHOLD 63
+
+#define MU_DIV_QR_THRESHOLD 1164
+#define MU_DIVAPPR_Q_THRESHOLD 979
+#define MUPI_DIV_QR_THRESHOLD 38
+#define MU_BDIV_QR_THRESHOLD 1442
+#define MU_BDIV_Q_THRESHOLD 1470
+
+#define MATRIX22_STRASSEN_THRESHOLD 17
+#define HGCD_THRESHOLD 64
+#define HGCD_APPR_THRESHOLD 105
+#define HGCD_REDUCE_THRESHOLD 3524
+#define GCD_DC_THRESHOLD 386
+#define GCDEXT_DC_THRESHOLD 309
+#define JACOBI_BASE_METHOD 1
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 26
+#define SET_STR_DC_THRESHOLD 587
+#define SET_STR_PRECOMPUTE_THRESHOLD 1104
diff --git a/gmp/mpn/x86/p6/lshsub_n.asm b/gmp/mpn/x86/p6/lshsub_n.asm
new file mode 100644
index 0000000000..7ada213644
--- /dev/null
+++ b/gmp/mpn/x86/p6/lshsub_n.asm
@@ -0,0 +1,169 @@
+dnl Intel P6 mpn_lshsub_n -- mpn papillion support.
+
+dnl Copyright 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C P6/13: 3.35 cycles/limb (separate mpn_sub_n + mpn_lshift needs 4.12)
+
+C (1) The loop is not scheduled in any way, and scheduling attempts have not
+C improved speed on P6/13. Presumably, the K7 will want scheduling, if it
+C at all wants to use MMX.
+C (2) We could save a register by not alternatingly using eax and edx in the
+C loop.
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`vp', `%ebx')
+define(`n', `%ecx')
+define(`cnt', `%mm7')
+
+ASM_START()
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(mpn_lshsub_n)
+ push %edi
+ push %esi
+ push %ebx
+
+ mov 16(%esp), rp
+ mov 20(%esp), up
+ mov 24(%esp), vp
+ mov 28(%esp), n
+ mov $32, %eax
+ sub 32(%esp), %eax
+ movd %eax, cnt
+
+ lea (up,n,4), up
+ lea (vp,n,4), vp
+ lea (rp,n,4), rp
+
+ neg n
+ mov n, %eax
+ and $-8, n
+ and $7, %eax
+ shl %eax C eax = 2x
+ lea (%eax,%eax,4), %edx C edx = 10x
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ lea L(ent)(%eax,%edx,2), %eax C eax = 22x
+')
+
+ pxor %mm1, %mm1
+ pxor %mm0, %mm0
+
+ jmp *%eax
+
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ lea (%eax,%edx,2), %eax
+ add $L(ent)-L(here), %eax
+ add (%esp), %eax
+ ret_internal
+')
+
+L(end): C compute (cy<<cnt) | (edx>>(32-cnt))
+ sbb %eax, %eax
+ neg %eax
+ mov 32(%esp), %ecx
+ shld %cl, %edx, %eax
+
+ emms
+
+ pop %ebx
+ pop %esi
+ pop %edi
+ ret
+ ALIGN(16)
+L(top): jecxz L(end)
+L(ent): mov 0(up,n,4), %eax
+ sbb 0(vp,n,4), %eax
+ movd %eax, %mm0
+ punpckldq %mm0, %mm1
+ psrlq %mm7, %mm1
+ movd %mm1, 0(rp,n,4)
+
+ mov 4(up,n,4), %edx
+ sbb 4(vp,n,4), %edx
+ movd %edx, %mm1
+ punpckldq %mm1, %mm0
+ psrlq %mm7, %mm0
+ movd %mm0, 4(rp,n,4)
+
+ mov 8(up,n,4), %eax
+ sbb 8(vp,n,4), %eax
+ movd %eax, %mm0
+ punpckldq %mm0, %mm1
+ psrlq %mm7, %mm1
+ movd %mm1, 8(rp,n,4)
+
+ mov 12(up,n,4), %edx
+ sbb 12(vp,n,4), %edx
+ movd %edx, %mm1
+ punpckldq %mm1, %mm0
+ psrlq %mm7, %mm0
+ movd %mm0, 12(rp,n,4)
+
+ mov 16(up,n,4), %eax
+ sbb 16(vp,n,4), %eax
+ movd %eax, %mm0
+ punpckldq %mm0, %mm1
+ psrlq %mm7, %mm1
+ movd %mm1, 16(rp,n,4)
+
+ mov 20(up,n,4), %edx
+ sbb 20(vp,n,4), %edx
+ movd %edx, %mm1
+ punpckldq %mm1, %mm0
+ psrlq %mm7, %mm0
+ movd %mm0, 20(rp,n,4)
+
+ mov 24(up,n,4), %eax
+ sbb 24(vp,n,4), %eax
+ movd %eax, %mm0
+ punpckldq %mm0, %mm1
+ psrlq %mm7, %mm1
+ movd %mm1, 24(rp,n,4)
+
+ mov 28(up,n,4), %edx
+ sbb 28(vp,n,4), %edx
+ movd %edx, %mm1
+ punpckldq %mm1, %mm0
+ psrlq %mm7, %mm0
+ movd %mm0, 28(rp,n,4)
+
+ lea 8(n), n
+ jmp L(top)
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/mmx/divrem_1.asm b/gmp/mpn/x86/p6/mmx/divrem_1.asm
new file mode 100644
index 0000000000..5300616c14
--- /dev/null
+++ b/gmp/mpn/x86/p6/mmx/divrem_1.asm
@@ -0,0 +1,767 @@
+dnl Intel Pentium-II mpn_divrem_1 -- mpn by limb division.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P6MMX: 25.0 cycles/limb integer part, 17.5 cycles/limb fraction part.
+
+
+C mp_limb_t mpn_divrem_1 (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C mp_limb_t mpn_divrem_1c (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C mp_limb_t mpn_preinv_divrem_1 (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t inverse,
+C unsigned shift);
+C
+C This code is a lightly reworked version of mpn/x86/k7/mmx/divrem_1.asm,
+C see that file for some comments. It's possible what's here can be improved.
+
+
+dnl MUL_THRESHOLD is the value of xsize+size at which the multiply by
+dnl inverse method is used, rather than plain "divl"s. Minimum value 1.
+dnl
+dnl The different speeds of the integer and fraction parts means that using
+dnl xsize+size isn't quite right. The threshold wants to be a bit higher
+dnl for the integer part and a bit lower for the fraction part. (Or what's
+dnl really wanted is to speed up the integer part!)
+dnl
+dnl The threshold is set to make the integer part right. At 4 limbs the
+dnl div and mul are about the same there, but on the fractional part the
+dnl mul is much faster.
+
+deflit(MUL_THRESHOLD, 4)
+
+
+defframe(PARAM_PREINV_SHIFT, 28) dnl mpn_preinv_divrem_1
+defframe(PARAM_PREINV_INVERSE, 24) dnl mpn_preinv_divrem_1
+defframe(PARAM_CARRY, 24) dnl mpn_divrem_1c
+defframe(PARAM_DIVISOR,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC, 12)
+defframe(PARAM_XSIZE, 8)
+defframe(PARAM_DST, 4)
+
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+
+defframe(VAR_NORM, -20)
+defframe(VAR_INVERSE, -24)
+defframe(VAR_SRC, -28)
+defframe(VAR_DST, -32)
+defframe(VAR_DST_STOP,-36)
+
+deflit(STACK_SPACE, 36)
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(mpn_preinv_divrem_1)
+deflit(`FRAME',0)
+ movl PARAM_XSIZE, %ecx
+ subl $STACK_SPACE, %esp FRAME_subl_esp(STACK_SPACE)
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_SIZE, %ebx
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_DIVISOR, %ebp
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edx
+
+ movl -4(%esi,%ebx,4), %eax C src high limb
+ xorl %edi, %edi C initial carry (if can't skip a div)
+
+ C
+
+ leal 8(%edx,%ecx,4), %edx C &dst[xsize+2]
+ xor %ecx, %ecx
+
+ movl %edx, VAR_DST_STOP C &dst[xsize+2]
+ cmpl %ebp, %eax C high cmp divisor
+
+ cmovc( %eax, %edi) C high is carry if high<divisor
+
+ cmovnc( %eax, %ecx) C 0 if skip div, src high if not
+ C (the latter in case src==dst)
+
+ movl %ecx, -12(%edx,%ebx,4) C dst high limb
+
+ sbbl $0, %ebx C skip one division if high<divisor
+ movl PARAM_PREINV_SHIFT, %ecx
+
+ leal -8(%edx,%ebx,4), %edx C &dst[xsize+size]
+ movl $32, %eax
+
+ movl %edx, VAR_DST C &dst[xsize+size]
+
+ shll %cl, %ebp C d normalized
+ subl %ecx, %eax
+ movl %ecx, VAR_NORM
+
+ movd %eax, %mm7 C rshift
+ movl PARAM_PREINV_INVERSE, %eax
+ jmp L(start_preinv)
+
+EPILOGUE()
+
+
+
+ ALIGN(16)
+
+PROLOGUE(mpn_divrem_1c)
+deflit(`FRAME',0)
+ movl PARAM_CARRY, %edx
+
+ movl PARAM_SIZE, %ecx
+ subl $STACK_SPACE, %esp
+deflit(`FRAME',STACK_SPACE)
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_XSIZE, %ebx
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_DIVISOR, %ebp
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ leal -4(%edi,%ebx,4), %edi
+ jmp L(start_1c)
+
+EPILOGUE()
+
+
+ C offset 0x31, close enough to aligned
+PROLOGUE(mpn_divrem_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl $0, %edx C initial carry (if can't skip a div)
+ subl $STACK_SPACE, %esp
+deflit(`FRAME',STACK_SPACE)
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_DIVISOR, %ebp
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_XSIZE, %ebx
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+ orl %ecx, %ecx C size
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ leal -4(%edi,%ebx,4), %edi C &dst[xsize-1]
+ jz L(no_skip_div) C if size==0
+
+ movl -4(%esi,%ecx,4), %eax C src high limb
+ xorl %esi, %esi
+ cmpl %ebp, %eax C high cmp divisor
+
+ cmovc( %eax, %edx) C high is carry if high<divisor
+
+ cmovnc( %eax, %esi) C 0 if skip div, src high if not
+ C (the latter in case src==dst)
+
+ movl %esi, (%edi,%ecx,4) C dst high limb
+
+ sbbl $0, %ecx C size-1 if high<divisor
+ movl PARAM_SRC, %esi C reload
+L(no_skip_div):
+
+
+L(start_1c):
+ C eax
+ C ebx xsize
+ C ecx size
+ C edx carry
+ C esi src
+ C edi &dst[xsize-1]
+ C ebp divisor
+
+ leal (%ebx,%ecx), %eax C size+xsize
+ cmpl $MUL_THRESHOLD, %eax
+ jae L(mul_by_inverse)
+
+ orl %ecx, %ecx
+ jz L(divide_no_integer)
+
+L(divide_integer):
+ C eax scratch (quotient)
+ C ebx xsize
+ C ecx counter
+ C edx scratch (remainder)
+ C esi src
+ C edi &dst[xsize-1]
+ C ebp divisor
+
+ movl -4(%esi,%ecx,4), %eax
+
+ divl %ebp
+
+ movl %eax, (%edi,%ecx,4)
+ decl %ecx
+ jnz L(divide_integer)
+
+
+L(divide_no_integer):
+ movl PARAM_DST, %edi
+ orl %ebx, %ebx
+ jnz L(divide_fraction)
+
+L(divide_done):
+ movl SAVE_ESI, %esi
+
+ movl SAVE_EDI, %edi
+
+ movl SAVE_EBX, %ebx
+ movl %edx, %eax
+
+ movl SAVE_EBP, %ebp
+ addl $STACK_SPACE, %esp
+
+ ret
+
+
+L(divide_fraction):
+ C eax scratch (quotient)
+ C ebx counter
+ C ecx
+ C edx scratch (remainder)
+ C esi
+ C edi dst
+ C ebp divisor
+
+ movl $0, %eax
+
+ divl %ebp
+
+ movl %eax, -4(%edi,%ebx,4)
+ decl %ebx
+ jnz L(divide_fraction)
+
+ jmp L(divide_done)
+
+
+
+C -----------------------------------------------------------------------------
+
+L(mul_by_inverse):
+ C eax
+ C ebx xsize
+ C ecx size
+ C edx carry
+ C esi src
+ C edi &dst[xsize-1]
+ C ebp divisor
+
+ leal 12(%edi), %ebx C &dst[xsize+2], loop dst stop
+
+ movl %ebx, VAR_DST_STOP
+ leal 4(%edi,%ecx,4), %edi C &dst[xsize+size]
+
+ movl %edi, VAR_DST
+ movl %ecx, %ebx C size
+
+ bsrl %ebp, %ecx C 31-l
+ movl %edx, %edi C carry
+
+ leal 1(%ecx), %eax C 32-l
+ xorl $31, %ecx C l
+
+ movl %ecx, VAR_NORM
+ movl $-1, %edx
+
+ shll %cl, %ebp C d normalized
+ movd %eax, %mm7
+
+ movl $-1, %eax
+ subl %ebp, %edx C (b-d)-1 giving edx:eax = b*(b-d)-1
+
+ divl %ebp C floor (b*(b-d)-1) / d
+
+L(start_preinv):
+ C eax inverse
+ C ebx size
+ C ecx shift
+ C edx
+ C esi src
+ C edi carry
+ C ebp divisor
+ C
+ C mm7 rshift
+
+ movl %eax, VAR_INVERSE
+ orl %ebx, %ebx C size
+ leal -12(%esi,%ebx,4), %eax C &src[size-3]
+
+ movl %eax, VAR_SRC
+ jz L(start_zero)
+
+ movl 8(%eax), %esi C src high limb
+ cmpl $1, %ebx
+ jz L(start_one)
+
+L(start_two_or_more):
+ movl 4(%eax), %edx C src second highest limb
+
+ shldl( %cl, %esi, %edi) C n2 = carry,high << l
+
+ shldl( %cl, %edx, %esi) C n10 = high,second << l
+
+ cmpl $2, %ebx
+ je L(integer_two_left)
+ jmp L(integer_top)
+
+
+L(start_one):
+ shldl( %cl, %esi, %edi) C n2 = carry,high << l
+
+ shll %cl, %esi C n10 = high << l
+ jmp L(integer_one_left)
+
+
+L(start_zero):
+ C Can be here with xsize==0 if mpn_preinv_divrem_1 had size==1 and
+ C skipped a division.
+
+ shll %cl, %edi C n2 = carry << l
+ movl %edi, %eax C return value for zero_done
+ cmpl $0, PARAM_XSIZE
+
+ je L(zero_done)
+ jmp L(fraction_some)
+
+
+
+C -----------------------------------------------------------------------------
+C
+C This loop runs at about 25 cycles, which is probably sub-optimal, and
+C certainly more than the dependent chain would suggest. A better loop, or
+C a better rough analysis of what's possible, would be welcomed.
+C
+C In the current implementation, the following successively dependent
+C micro-ops seem to exist.
+C
+C uops
+C n2+n1 1 (addl)
+C mul 5
+C q1+1 3 (addl/adcl)
+C mul 5
+C sub 3 (subl/sbbl)
+C addback 2 (cmov)
+C ---
+C 19
+C
+C Lack of registers hinders explicit scheduling and it might be that the
+C normal out of order execution isn't able to hide enough under the mul
+C latencies.
+C
+C Using sarl/negl to pick out n1 for the n2+n1 stage is a touch faster than
+C cmov (and takes one uop off the dependent chain). A sarl/andl/addl
+C combination was tried for the addback (despite the fact it would lengthen
+C the dependent chain) but found to be no faster.
+
+
+ ALIGN(16)
+L(integer_top):
+ C eax scratch
+ C ebx scratch (nadj, q1)
+ C ecx scratch (src, dst)
+ C edx scratch
+ C esi n10
+ C edi n2
+ C ebp d
+ C
+ C mm0 scratch (src qword)
+ C mm7 rshift for normalization
+
+ movl %esi, %eax
+ movl %ebp, %ebx
+
+ sarl $31, %eax C -n1
+ movl VAR_SRC, %ecx
+
+ andl %eax, %ebx C -n1 & d
+ negl %eax C n1
+
+ addl %esi, %ebx C nadj = n10 + (-n1 & d), ignoring overflow
+ addl %edi, %eax C n2+n1
+ movq (%ecx), %mm0 C next src limb and the one below it
+
+ mull VAR_INVERSE C m*(n2+n1)
+
+ subl $4, %ecx
+
+ movl %ecx, VAR_SRC
+
+ C
+
+ C
+
+ addl %ebx, %eax C m*(n2+n1) + nadj, low giving carry flag
+ movl %ebp, %eax C d
+ leal 1(%edi), %ebx C n2+1
+
+ adcl %edx, %ebx C 1 + high(n2<<32 + m*(n2+n1) + nadj) = q1+1
+ jz L(q1_ff)
+
+ mull %ebx C (q1+1)*d
+
+ movl VAR_DST, %ecx
+ psrlq %mm7, %mm0
+
+ C
+
+ C
+
+ C
+
+ subl %eax, %esi
+ movl VAR_DST_STOP, %eax
+
+ sbbl %edx, %edi C n - (q1+1)*d
+ movl %esi, %edi C remainder -> n2
+ leal (%ebp,%esi), %edx
+
+ cmovc( %edx, %edi) C n - q1*d if underflow from using q1+1
+ movd %mm0, %esi
+
+ sbbl $0, %ebx C q
+ subl $4, %ecx
+
+ movl %ebx, (%ecx)
+ cmpl %eax, %ecx
+
+ movl %ecx, VAR_DST
+ jne L(integer_top)
+
+
+L(integer_loop_done):
+
+
+C -----------------------------------------------------------------------------
+C
+C Here, and in integer_one_left below, an sbbl $0 is used rather than a jz
+C q1_ff special case. This make the code a bit smaller and simpler, and
+C costs only 2 cycles (each).
+
+L(integer_two_left):
+ C eax scratch
+ C ebx scratch (nadj, q1)
+ C ecx scratch (src, dst)
+ C edx scratch
+ C esi n10
+ C edi n2
+ C ebp divisor
+ C
+ C mm7 rshift
+
+
+ movl %esi, %eax
+ movl %ebp, %ebx
+
+ sarl $31, %eax C -n1
+ movl PARAM_SRC, %ecx
+
+ andl %eax, %ebx C -n1 & d
+ negl %eax C n1
+
+ addl %esi, %ebx C nadj = n10 + (-n1 & d), ignoring overflow
+ addl %edi, %eax C n2+n1
+
+ mull VAR_INVERSE C m*(n2+n1)
+
+ movd (%ecx), %mm0 C src low limb
+
+ movl VAR_DST_STOP, %ecx
+
+ C
+
+ C
+
+ addl %ebx, %eax C m*(n2+n1) + nadj, low giving carry flag
+ leal 1(%edi), %ebx C n2+1
+ movl %ebp, %eax C d
+
+ adcl %edx, %ebx C 1 + high(n2<<32 + m*(n2+n1) + nadj) = q1+1
+
+ sbbl $0, %ebx
+
+ mull %ebx C (q1+1)*d
+
+ psllq $32, %mm0
+
+ psrlq %mm7, %mm0
+
+ C
+
+ C
+
+ subl %eax, %esi
+
+ sbbl %edx, %edi C n - (q1+1)*d
+ movl %esi, %edi C remainder -> n2
+ leal (%ebp,%esi), %edx
+
+ cmovc( %edx, %edi) C n - q1*d if underflow from using q1+1
+ movd %mm0, %esi
+
+ sbbl $0, %ebx C q
+
+ movl %ebx, -4(%ecx)
+
+
+C -----------------------------------------------------------------------------
+L(integer_one_left):
+ C eax scratch
+ C ebx scratch (nadj, q1)
+ C ecx scratch (dst)
+ C edx scratch
+ C esi n10
+ C edi n2
+ C ebp divisor
+ C
+ C mm7 rshift
+
+
+ movl %esi, %eax
+ movl %ebp, %ebx
+
+ sarl $31, %eax C -n1
+ movl VAR_DST_STOP, %ecx
+
+ andl %eax, %ebx C -n1 & d
+ negl %eax C n1
+
+ addl %esi, %ebx C nadj = n10 + (-n1 & d), ignoring overflow
+ addl %edi, %eax C n2+n1
+
+ mull VAR_INVERSE C m*(n2+n1)
+
+ C
+
+ C
+
+ C
+
+ addl %ebx, %eax C m*(n2+n1) + nadj, low giving carry flag
+ leal 1(%edi), %ebx C n2+1
+ movl %ebp, %eax C d
+
+ C
+
+ adcl %edx, %ebx C 1 + high(n2<<32 + m*(n2+n1) + nadj) = q1+1
+
+ sbbl $0, %ebx C q1 if q1+1 overflowed
+
+ mull %ebx
+
+ C
+
+ C
+
+ C
+
+ C
+
+ subl %eax, %esi
+ movl PARAM_XSIZE, %eax
+
+ sbbl %edx, %edi C n - (q1+1)*d
+ movl %esi, %edi C remainder -> n2
+ leal (%ebp,%esi), %edx
+
+ cmovc( %edx, %edi) C n - q1*d if underflow from using q1+1
+
+ sbbl $0, %ebx C q
+
+ movl %ebx, -8(%ecx)
+ subl $8, %ecx
+
+
+
+ orl %eax, %eax C xsize
+ jnz L(fraction_some)
+
+ movl %edi, %eax
+L(fraction_done):
+ movl VAR_NORM, %ecx
+L(zero_done):
+ movl SAVE_EBP, %ebp
+
+ movl SAVE_EDI, %edi
+
+ movl SAVE_ESI, %esi
+
+ movl SAVE_EBX, %ebx
+ addl $STACK_SPACE, %esp
+
+ shrl %cl, %eax
+ emms
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+C
+C Special case for q1=0xFFFFFFFF, giving q=0xFFFFFFFF meaning the low dword
+C of q*d is simply -d and the remainder n-q*d = n10+d
+
+L(q1_ff):
+ C eax (divisor)
+ C ebx (q1+1 == 0)
+ C ecx
+ C edx
+ C esi n10
+ C edi n2
+ C ebp divisor
+
+ movl VAR_DST, %ecx
+ movl VAR_DST_STOP, %edx
+ subl $4, %ecx
+
+ movl %ecx, VAR_DST
+ psrlq %mm7, %mm0
+ leal (%ebp,%esi), %edi C n-q*d remainder -> next n2
+
+ movl $-1, (%ecx)
+ movd %mm0, %esi C next n10
+
+ cmpl %ecx, %edx
+ jne L(integer_top)
+
+ jmp L(integer_loop_done)
+
+
+
+C -----------------------------------------------------------------------------
+C
+C In the current implementation, the following successively dependent
+C micro-ops seem to exist.
+C
+C uops
+C mul 5
+C q1+1 1 (addl)
+C mul 5
+C sub 3 (negl/sbbl)
+C addback 2 (cmov)
+C ---
+C 16
+C
+C The loop in fact runs at about 17.5 cycles. Using a sarl/andl/addl for
+C the addback was found to be a touch slower.
+
+
+ ALIGN(16)
+L(fraction_some):
+ C eax
+ C ebx
+ C ecx
+ C edx
+ C esi
+ C edi carry
+ C ebp divisor
+
+ movl PARAM_DST, %esi
+ movl VAR_DST_STOP, %ecx C &dst[xsize+2]
+ movl %edi, %eax
+
+ subl $8, %ecx C &dst[xsize]
+
+
+ ALIGN(16)
+L(fraction_top):
+ C eax n2, then scratch
+ C ebx scratch (nadj, q1)
+ C ecx dst, decrementing
+ C edx scratch
+ C esi dst stop point
+ C edi n2
+ C ebp divisor
+
+ mull VAR_INVERSE C m*n2
+
+ movl %ebp, %eax C d
+ subl $4, %ecx C dst
+ leal 1(%edi), %ebx
+
+ C
+
+ C
+
+ C
+
+ addl %edx, %ebx C 1 + high(n2<<32 + m*n2) = q1+1
+
+ mull %ebx C (q1+1)*d
+
+ C
+
+ C
+
+ C
+
+ C
+
+ negl %eax C low of n - (q1+1)*d
+
+ sbbl %edx, %edi C high of n - (q1+1)*d, caring only about carry
+ leal (%ebp,%eax), %edx
+
+ cmovc( %edx, %eax) C n - q1*d if underflow from using q1+1
+
+ sbbl $0, %ebx C q
+ movl %eax, %edi C remainder->n2
+ cmpl %esi, %ecx
+
+ movl %ebx, (%ecx) C previous q
+ jne L(fraction_top)
+
+
+ jmp L(fraction_done)
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/mmx/gmp-mparam.h b/gmp/mpn/x86/p6/mmx/gmp-mparam.h
new file mode 100644
index 0000000000..35c3aadfc1
--- /dev/null
+++ b/gmp/mpn/x86/p6/mmx/gmp-mparam.h
@@ -0,0 +1,198 @@
+/* Intel P6/mmx gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2005, 2009, 2010 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* NOTE: In a fat binary build SQR_TOOM2_THRESHOLD here cannot be more than the
+ value in mpn/x86/p6/gmp-mparam.h. The latter is used as a hard limit in
+ mpn/x86/p6/sqr_basecase.asm. */
+
+
+/* 800 MHz P6 model 8 */
+
+#define MOD_1_NORM_THRESHOLD 4
+#define MOD_1_UNNORM_THRESHOLD 4
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 9
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 8
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 10
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 17
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 49
+
+#define MUL_TOOM22_THRESHOLD 22
+#define MUL_TOOM33_THRESHOLD 73
+#define MUL_TOOM44_THRESHOLD 193
+#define MUL_TOOM6H_THRESHOLD 254
+#define MUL_TOOM8H_THRESHOLD 381
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 122
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 73
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 80
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 81
+#define SQR_TOOM4_THRESHOLD 142
+#define SQR_TOOM6_THRESHOLD 258
+#define SQR_TOOM8_THRESHOLD 399
+
+#define MULMOD_BNM1_THRESHOLD 15
+#define SQRMOD_BNM1_THRESHOLD 18
+
+#define MUL_FFT_MODF_THRESHOLD 476 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 476, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 21, 7}, { 11, 6}, { 25, 7}, { 13, 6}, \
+ { 27, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
+ { 11, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
+ { 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
+ { 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
+ { 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
+ { 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
+ { 47, 8}, { 95, 9}, { 55,10}, { 31, 9}, \
+ { 63, 8}, { 127, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 167,10}, { 95, 9}, { 199,10}, \
+ { 111,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511,10}, { 143, 9}, { 287, 8}, { 575,10}, \
+ { 159,11}, { 95,10}, { 191, 9}, { 383,10}, \
+ { 207,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543, 8}, { 1087,10}, \
+ { 287, 9}, { 575,11}, { 159,10}, { 319, 9}, \
+ { 639,10}, { 351, 9}, { 703,11}, { 191,10}, \
+ { 383, 9}, { 767,10}, { 415, 9}, { 831,11}, \
+ { 223,10}, { 447,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607, 9}, \
+ { 1215,11}, { 319,10}, { 671,11}, { 351,10}, \
+ { 703,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,10}, { 831,11}, { 447,13}, { 127,12}, \
+ { 255,11}, { 543,10}, { 1087,11}, { 607,10}, \
+ { 1215,12}, { 319,11}, { 671,10}, { 1343,11}, \
+ { 703,10}, { 1407,11}, { 735,12}, { 383,11}, \
+ { 831,12}, { 447,11}, { 959,10}, { 1919,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1215,10}, { 2431,12}, { 639,11}, { 1343,12}, \
+ { 703,11}, { 1471,13}, { 383,12}, { 767,11}, \
+ { 1535,12}, { 831,11}, { 1727,12}, { 959,11}, \
+ { 1919,14}, { 255,13}, { 511,12}, { 1215,11}, \
+ { 2431,13}, { 639,12}, { 1471,11}, { 2943,13}, \
+ { 767,12}, { 1727,13}, { 895,12}, { 1919,11}, \
+ { 3839,14}, { 511,13}, { 1023,12}, { 2111,13}, \
+ { 1151,12}, { 2431,13}, { 1279,12}, { 2559,13}, \
+ { 1407,12}, { 2943,14}, { 767,13}, { 1663,12}, \
+ { 3327,13}, { 1919,12}, { 3839,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 160
+#define MUL_FFT_THRESHOLD 7040
+
+#define SQR_FFT_MODF_THRESHOLD 376 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 376, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 21, 7}, { 11, 6}, { 24, 7}, { 13, 6}, \
+ { 27, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
+ { 11, 7}, { 27, 8}, { 15, 7}, { 33, 8}, \
+ { 19, 7}, { 39, 8}, { 23, 7}, { 47, 8}, \
+ { 27, 9}, { 15, 8}, { 39, 9}, { 23, 8}, \
+ { 51,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 127, 8}, \
+ { 255, 9}, { 135,10}, { 79, 9}, { 167,10}, \
+ { 95, 9}, { 191, 8}, { 383,10}, { 111,11}, \
+ { 63,10}, { 127, 9}, { 255, 8}, { 511, 9}, \
+ { 271,10}, { 143, 9}, { 287, 8}, { 575, 9}, \
+ { 303, 8}, { 607,10}, { 159, 9}, { 319,11}, \
+ { 95,10}, { 191, 9}, { 383,10}, { 207,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
+ { 271, 9}, { 543,10}, { 287, 9}, { 575,10}, \
+ { 303,11}, { 159,10}, { 319, 9}, { 639,10}, \
+ { 351, 9}, { 703,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 415, 9}, { 831,11}, { 223,10}, \
+ { 479,12}, { 127,11}, { 255,10}, { 543, 9}, \
+ { 1087,11}, { 287,10}, { 607, 9}, { 1215,11}, \
+ { 319,10}, { 671,11}, { 351,10}, { 703,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,10}, \
+ { 831,11}, { 479,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
+ { 319,11}, { 671,10}, { 1343,11}, { 703,10}, \
+ { 1407,11}, { 735,12}, { 383,11}, { 831,12}, \
+ { 447,11}, { 959,10}, { 1919,13}, { 255,12}, \
+ { 511,11}, { 1087,12}, { 575,11}, { 1215,10}, \
+ { 2431,12}, { 639,11}, { 1343,12}, { 703,11}, \
+ { 1407,13}, { 383,12}, { 831,11}, { 1727,12}, \
+ { 959,11}, { 1919,14}, { 255,13}, { 511,12}, \
+ { 1215,11}, { 2431,13}, { 639,12}, { 1471,11}, \
+ { 2943,13}, { 767,12}, { 1727,13}, { 895,12}, \
+ { 1919,11}, { 3839,14}, { 511,13}, { 1023,12}, \
+ { 2111,13}, { 1151,12}, { 2431,13}, { 1407,12}, \
+ { 2943,14}, { 767,13}, { 1535,12}, { 3071,13}, \
+ { 1663,12}, { 3455,13}, { 1919,12}, { 3839,15}, \
+ { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 161
+#define SQR_FFT_THRESHOLD 3712
+
+#define MULLO_BASECASE_THRESHOLD 8
+#define MULLO_DC_THRESHOLD 60
+#define MULLO_MUL_N_THRESHOLD 13765
+
+#define DC_DIV_QR_THRESHOLD 83
+#define DC_DIVAPPR_Q_THRESHOLD 246
+#define DC_BDIV_QR_THRESHOLD 76
+#define DC_BDIV_Q_THRESHOLD 175
+
+#define INV_MULMOD_BNM1_THRESHOLD 42
+#define INV_NEWTON_THRESHOLD 268
+#define INV_APPR_THRESHOLD 250
+
+#define BINV_NEWTON_THRESHOLD 276
+#define REDC_1_TO_REDC_N_THRESHOLD 74
+
+#define MU_DIV_QR_THRESHOLD 1442
+#define MU_DIVAPPR_Q_THRESHOLD 1442
+#define MUPI_DIV_QR_THRESHOLD 132
+#define MU_BDIV_QR_THRESHOLD 1142
+#define MU_BDIV_Q_THRESHOLD 1334
+
+#define MATRIX22_STRASSEN_THRESHOLD 18
+#define HGCD_THRESHOLD 121
+#define GCD_DC_THRESHOLD 478
+#define GCDEXT_DC_THRESHOLD 361
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 26
+#define SET_STR_DC_THRESHOLD 272
+#define SET_STR_PRECOMPUTE_THRESHOLD 1074
diff --git a/gmp/mpn/x86/p6/mmx/lshift.asm b/gmp/mpn/x86/p6/mmx/lshift.asm
new file mode 100644
index 0000000000..febd1c0e6c
--- /dev/null
+++ b/gmp/mpn/x86/p6/mmx/lshift.asm
@@ -0,0 +1,38 @@
+dnl Intel Pentium-II mpn_lshift -- mpn left shift.
+
+dnl Copyright 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl The P55 code runs well on P-II/III, but could stand some minor tweaks
+dnl at some stage probably.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_lshift)
+include_mpn(`x86/pentium/mmx/lshift.asm')
diff --git a/gmp/mpn/x86/p6/mmx/popham.asm b/gmp/mpn/x86/p6/mmx/popham.asm
new file mode 100644
index 0000000000..fd340e4b45
--- /dev/null
+++ b/gmp/mpn/x86/p6/mmx/popham.asm
@@ -0,0 +1,39 @@
+dnl Intel Pentium-II mpn_popcount, mpn_hamdist -- population count and
+dnl hamming distance.
+
+dnl Copyright 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P6MMX: popcount 11 cycles/limb (approx), hamdist 11.5 cycles/limb (approx)
+
+
+MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
+include_mpn(`x86/k6/mmx/popham.asm')
diff --git a/gmp/mpn/x86/p6/mmx/rshift.asm b/gmp/mpn/x86/p6/mmx/rshift.asm
new file mode 100644
index 0000000000..77aa1909fa
--- /dev/null
+++ b/gmp/mpn/x86/p6/mmx/rshift.asm
@@ -0,0 +1,38 @@
+dnl Intel Pentium-II mpn_rshift -- mpn left shift.
+
+dnl Copyright 2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl The P55 code runs well on P-II/III, but could stand some minor tweaks
+dnl at some stage probably.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_rshift)
+include_mpn(`x86/pentium/mmx/rshift.asm')
diff --git a/gmp/mpn/x86/p6/mod_34lsub1.asm b/gmp/mpn/x86/p6/mod_34lsub1.asm
new file mode 100644
index 0000000000..b88ab5d17c
--- /dev/null
+++ b/gmp/mpn/x86/p6/mod_34lsub1.asm
@@ -0,0 +1,190 @@
+dnl Intel P6 mpn_mod_34lsub1 -- remainder modulo 2^24-1.
+
+dnl Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P6: 2.0 cycles/limb
+
+C TODO
+C Experiments with more unrolling indicate that 1.5 c/l is possible on P6-13
+C with the current carry handling scheme.
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr src, mp_size_t size)
+C
+C Groups of three limbs are handled, with carry bits from 0mod3 into 1mod3
+C into 2mod3, but at that point going into a separate carries total so we
+C don't keep the carry flag live across the loop control. Avoiding decl
+C lets us get to 2.0 c/l, as compared to the generic x86 code at 3.66.
+C
+
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX, `PARAM_SIZE')
+define(SAVE_ESI, `PARAM_SRC')
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_34lsub1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %edx
+
+ subl $2, %ecx C size-2
+ movl (%edx), %eax C src[0]
+ ja L(three_or_more)
+ jb L(one)
+
+ C size==2
+
+ movl 4(%edx), %ecx C src[1]
+
+ movl %eax, %edx C src[0]
+ shrl $24, %eax C src[0] high
+
+ andl $0xFFFFFF, %edx C src[0] low
+
+ addl %edx, %eax
+ movl %ecx, %edx C src[1]
+ shrl $16, %ecx C src[1] high
+
+ andl $0xFFFF, %edx
+ addl %ecx, %eax
+
+ shll $8, %edx C src[1] low
+
+ addl %edx, %eax
+L(one):
+ ret
+
+
+L(three_or_more):
+ C eax src[0], initial acc 0mod3
+ C ebx
+ C ecx size-2
+ C edx src
+ C esi
+ C edi
+ C ebp
+
+ movl %ebx, SAVE_EBX
+ movl 4(%edx), %ebx C src[1], initial 1mod3
+ subl $3, %ecx C size-5
+
+ movl %esi, SAVE_ESI
+ movl 8(%edx), %esi C src[2], initial 2mod3
+
+ pushl %edi FRAME_pushl()
+ movl $0, %edi C initial carries 0mod3
+ jng L(done) C if size < 6
+
+
+L(top):
+ C eax acc 0mod3
+ C ebx acc 1mod3
+ C ecx counter, limbs
+ C edx src
+ C esi acc 2mod3
+ C edi carrys into 0mod3
+ C ebp
+
+ addl 12(%edx), %eax
+ adcl 16(%edx), %ebx
+ adcl 20(%edx), %esi
+ leal 12(%edx), %edx
+ adcl $0, %edi
+
+ subl $3, %ecx
+ jg L(top) C at least 3 more to process
+
+
+L(done):
+ C ecx is -2, -1 or 0 representing 0, 1 or 2 more limbs respectively
+ cmpl $-1, %ecx
+ jl L(done_0) C if -2, meaning 0 more limbs
+
+ C 1 or 2 more limbs
+ movl $0, %ecx
+ je L(done_1) C if -1, meaning 1 more limb only
+ movl 16(%edx), %ecx
+L(done_1):
+ addl 12(%edx), %eax C 0mod3
+ adcl %ecx, %ebx C 1mod3
+ adcl $0, %esi C 2mod3
+ adcl $0, %edi C carries 0mod3
+
+L(done_0):
+ C eax acc 0mod3
+ C ebx acc 1mod3
+ C ecx
+ C edx
+ C esi acc 2mod3
+ C edi carries 0mod3
+ C ebp
+
+ movl %eax, %ecx C 0mod3
+ shrl $24, %eax C 0mod3 high initial total
+
+ andl $0xFFFFFF, %ecx C 0mod3 low
+ movl %edi, %edx C carries
+ shrl $24, %edi C carries high
+
+ addl %ecx, %eax C add 0mod3 low
+ andl $0xFFFFFF, %edx C carries 0mod3 low
+ movl %ebx, %ecx C 1mod3
+
+ shrl $16, %ebx C 1mod3 high
+ addl %edi, %eax C add carries high
+ addl %edx, %eax C add carries 0mod3 low
+
+ andl $0xFFFF, %ecx C 1mod3 low mask
+ addl %ebx, %eax C add 1mod3 high
+ movl SAVE_EBX, %ebx
+
+ shll $8, %ecx C 1mod3 low
+ movl %esi, %edx C 2mod3
+ popl %edi FRAME_popl()
+
+ shrl $8, %esi C 2mod3 high
+ andl $0xFF, %edx C 2mod3 low mask
+ addl %ecx, %eax C add 1mod3 low
+
+ shll $16, %edx C 2mod3 low
+ addl %esi, %eax C add 2mod3 high
+ movl SAVE_ESI, %esi
+
+ addl %edx, %eax C add 2mod3 low
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/mode1o.asm b/gmp/mpn/x86/p6/mode1o.asm
new file mode 100644
index 0000000000..c62b676e5a
--- /dev/null
+++ b/gmp/mpn/x86/p6/mode1o.asm
@@ -0,0 +1,169 @@
+dnl Intel P6 mpn_modexact_1_odd -- exact division style remainder.
+
+dnl Copyright 2000-2002, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P6: 10.0 cycles/limb
+
+
+C mp_limb_t mpn_modexact_1_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C
+C It's not worth skipping a step at the end when high<divisor since the main
+C loop is only 10 cycles.
+
+defframe(PARAM_CARRY, 16)
+defframe(PARAM_DIVISOR,12)
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+dnl Not enough room under modexact_1 to make these re-use the parameter
+dnl space, unfortunately.
+defframe(SAVE_EBX, -4)
+defframe(SAVE_ESI, -8)
+defframe(SAVE_EDI, -12)
+deflit(STACK_SPACE, 12)
+
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(mpn_modexact_1c_odd)
+deflit(`FRAME',0)
+
+ movl PARAM_CARRY, %ecx
+ jmp L(start_1c)
+
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_modexact_1_odd)
+deflit(`FRAME',0)
+
+ xorl %ecx, %ecx
+L(start_1c):
+ movl PARAM_DIVISOR, %eax
+
+ subl $STACK_SPACE, %esp FRAME_subl_esp(STACK_SPACE)
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ shrl %eax C d/2
+ movl %edi, SAVE_EDI
+
+ andl $127, %eax
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %edi)
+ movzbl (%eax,%edi), %edi C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %edi C inv 8 bits
+')
+
+ xorl %edx, %edx C initial extra carry
+ leal (%edi,%edi), %eax C 2*inv
+
+ imull %edi, %edi C inv*inv
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_SIZE, %ebx
+
+ imull PARAM_DIVISOR, %edi C inv*inv*d
+
+ subl %edi, %eax C inv = 2*inv - inv*inv*d
+ leal (%eax,%eax), %edi C 2*inv
+
+ imull %eax, %eax C inv*inv
+
+ imull PARAM_DIVISOR, %eax C inv*inv*d
+
+ leal (%esi,%ebx,4), %esi C src end
+ negl %ebx C -size
+
+ subl %eax, %edi C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C d*inv == 1 mod 2^GMP_LIMB_BITS
+ movl PARAM_DIVISOR, %eax
+ imull %edi, %eax
+ cmpl $1, %eax')
+
+
+C The dependent chain here is
+C
+C subl %edx, %eax 1
+C imull %edi, %eax 4
+C mull PARAM_DIVISOR 5
+C ----
+C total 10
+C
+C and this is the measured speed. No special scheduling is necessary, out
+C of order execution hides the load latency.
+
+L(top):
+ C eax scratch (src limb)
+ C ebx counter, limbs, negative
+ C ecx carry bit, 0 or 1
+ C edx carry limb, high of last product
+ C esi &src[size]
+ C edi inverse
+ C ebp
+
+ movl (%esi,%ebx,4), %eax
+ subl %ecx, %eax
+
+ sbbl %ecx, %ecx
+ subl %edx, %eax
+
+ sbbl $0, %ecx
+
+ imull %edi, %eax
+
+ negl %ecx
+
+ mull PARAM_DIVISOR
+
+ incl %ebx
+ jnz L(top)
+
+
+ movl SAVE_ESI, %esi
+ leal (%ecx,%edx), %eax
+
+ movl SAVE_EDI, %edi
+
+ movl SAVE_EBX, %ebx
+ addl $STACK_SPACE, %esp
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/mul_basecase.asm b/gmp/mpn/x86/p6/mul_basecase.asm
new file mode 100644
index 0000000000..d87bc12b60
--- /dev/null
+++ b/gmp/mpn/x86/p6/mul_basecase.asm
@@ -0,0 +1,607 @@
+dnl Intel P6 mpn_mul_basecase -- multiply two mpn numbers.
+
+dnl Copyright 1999-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P6: approx 6.5 cycles per cross product (16 limbs/loop unrolling).
+
+
+dnl P6 UNROLL_COUNT cycles/product (approx)
+dnl 8 7
+dnl 16 6.5
+dnl 32 6.4
+dnl Maximum possible with the current code is 32.
+
+deflit(UNROLL_COUNT, 16)
+
+
+C void mpn_mul_basecase (mp_ptr wp,
+C mp_srcptr xp, mp_size_t xsize,
+C mp_srcptr yp, mp_size_t ysize);
+C
+C This routine is essentially the same as mpn/generic/mul_basecase.c, but
+C it's faster because it does most of the mpn_addmul_1() startup
+C calculations only once.
+
+ifdef(`PIC',`
+deflit(UNROLL_THRESHOLD, 5)
+',`
+deflit(UNROLL_THRESHOLD, 5)
+')
+
+defframe(PARAM_YSIZE,20)
+defframe(PARAM_YP, 16)
+defframe(PARAM_XSIZE,12)
+defframe(PARAM_XP, 8)
+defframe(PARAM_WP, 4)
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(mpn_mul_basecase)
+deflit(`FRAME',0)
+
+ movl PARAM_XSIZE, %ecx
+
+ movl PARAM_YP, %eax
+
+ movl PARAM_XP, %edx
+
+ movl (%eax), %eax C yp[0]
+ cmpl $2, %ecx
+ ja L(xsize_more_than_two)
+ je L(two_by_something)
+
+
+ C one limb by one limb
+
+ mull (%edx)
+
+ movl PARAM_WP, %ecx
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(two_by_something):
+deflit(`FRAME',0)
+
+dnl re-use parameter space
+define(SAVE_EBX, `PARAM_XSIZE')
+define(SAVE_ESI, `PARAM_YSIZE')
+
+ movl %ebx, SAVE_EBX
+ cmpl $1, PARAM_YSIZE
+ movl %eax, %ecx C yp[0]
+
+ movl %esi, SAVE_ESI C save esi
+ movl PARAM_WP, %ebx
+ movl %edx, %esi C xp
+
+ movl (%edx), %eax C xp[0]
+ jne L(two_by_two)
+
+
+ C two limbs by one limb
+ C
+ C eax xp[0]
+ C ebx wp
+ C ecx yp[0]
+ C edx
+ C esi xp
+
+ mull %ecx
+
+ movl %eax, (%ebx)
+ movl 4(%esi), %eax
+ movl %edx, %esi C carry
+
+ mull %ecx
+
+ addl %eax, %esi
+
+ movl %esi, 4(%ebx)
+ movl SAVE_ESI, %esi
+
+ adcl $0, %edx
+
+ movl %edx, 8(%ebx)
+ movl SAVE_EBX, %ebx
+
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+
+ ALIGN(16)
+L(two_by_two):
+ C eax xp[0]
+ C ebx wp
+ C ecx yp[0]
+ C edx
+ C esi xp
+ C edi
+ C ebp
+
+dnl more parameter space re-use
+define(SAVE_EDI, `PARAM_WP')
+
+ mull %ecx C xp[0] * yp[0]
+
+ movl %edi, SAVE_EDI
+ movl %edx, %edi C carry, for wp[1]
+
+ movl %eax, (%ebx)
+ movl 4(%esi), %eax
+
+ mull %ecx C xp[1] * yp[0]
+
+ addl %eax, %edi
+ movl PARAM_YP, %ecx
+
+ adcl $0, %edx
+ movl 4(%ecx), %ecx C yp[1]
+
+ movl %edi, 4(%ebx)
+ movl 4(%esi), %eax C xp[1]
+ movl %edx, %edi C carry, for wp[2]
+
+ mull %ecx C xp[1] * yp[1]
+
+ addl %eax, %edi
+ movl (%esi), %eax C xp[0]
+
+ adcl $0, %edx
+ movl %edx, %esi C carry, for wp[3]
+
+ mull %ecx C xp[0] * yp[1]
+
+ addl %eax, 4(%ebx)
+ movl %esi, %eax
+
+ adcl %edx, %edi
+ movl SAVE_ESI, %esi
+
+ movl %edi, 8(%ebx)
+
+ adcl $0, %eax
+ movl SAVE_EDI, %edi
+
+ movl %eax, 12(%ebx)
+ movl SAVE_EBX, %ebx
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(xsize_more_than_two):
+
+C The first limb of yp is processed with a simple mpn_mul_1 loop running at
+C about 6.2 c/l. Unrolling this doesn't seem worthwhile since it's only run
+C once (whereas the addmul_1 below is run ysize-1 many times). A call to
+C mpn_mul_1 would be slowed down by the parameter pushing and popping etc,
+C and doesn't seem likely to be worthwhile on the typical sizes reaching
+C here from the Karatsuba code.
+
+ C eax yp[0]
+ C ebx
+ C ecx xsize
+ C edx xp
+ C esi
+ C edi
+ C ebp
+
+defframe(`SAVE_EBX', -4)
+defframe(`SAVE_ESI', -8)
+defframe(`SAVE_EDI', -12)
+defframe(`SAVE_EBP', -16)
+defframe(VAR_COUNTER, -20) dnl for use in the unroll case
+defframe(VAR_ADJUST, -24)
+defframe(VAR_JMP, -28)
+defframe(VAR_SWAP, -32)
+defframe(VAR_XP_LOW, -36)
+deflit(STACK_SPACE, 36)
+
+ subl $STACK_SPACE, %esp
+deflit(`FRAME',STACK_SPACE)
+
+ movl %edi, SAVE_EDI
+ movl PARAM_WP, %edi
+
+ movl %ebx, SAVE_EBX
+
+ movl %ebp, SAVE_EBP
+ movl %eax, %ebp
+
+ movl %esi, SAVE_ESI
+ xorl %ebx, %ebx
+ leal (%edx,%ecx,4), %esi C xp end
+
+ leal (%edi,%ecx,4), %edi C wp end of mul1
+ negl %ecx
+
+
+L(mul1):
+ C eax scratch
+ C ebx carry
+ C ecx counter, negative
+ C edx scratch
+ C esi xp end
+ C edi wp end of mul1
+ C ebp multiplier
+
+ movl (%esi,%ecx,4), %eax
+
+ mull %ebp
+
+ addl %ebx, %eax
+ movl %eax, (%edi,%ecx,4)
+ movl $0, %ebx
+
+ adcl %edx, %ebx
+ incl %ecx
+ jnz L(mul1)
+
+
+ movl PARAM_YSIZE, %edx
+
+ movl %ebx, (%edi) C final carry
+ movl PARAM_XSIZE, %ecx
+ decl %edx
+
+ jz L(done) C if ysize==1
+
+ cmpl $UNROLL_THRESHOLD, %ecx
+ movl PARAM_YP, %eax
+ jae L(unroll)
+
+
+C -----------------------------------------------------------------------------
+ C simple addmul looping
+ C
+ C eax yp
+ C ebx
+ C ecx xsize
+ C edx ysize-1
+ C esi xp end
+ C edi wp end of mul1
+ C ebp
+
+ leal 4(%eax,%edx,4), %ebp C yp end
+ negl %ecx
+ negl %edx
+
+ movl %edx, PARAM_YSIZE C -(ysize-1)
+ movl (%esi,%ecx,4), %eax C xp low limb
+ incl %ecx
+
+ movl %ecx, PARAM_XSIZE C -(xsize-1)
+ xorl %ebx, %ebx C initial carry
+
+ movl %ebp, PARAM_YP
+ movl (%ebp,%edx,4), %ebp C yp second lowest limb - multiplier
+ jmp L(simple_outer_entry)
+
+
+L(simple_outer_top):
+ C ebp ysize counter, negative
+
+ movl PARAM_YP, %edx
+
+ movl PARAM_XSIZE, %ecx C -(xsize-1)
+ xorl %ebx, %ebx C carry
+
+ movl %ebp, PARAM_YSIZE
+ addl $4, %edi C next position in wp
+
+ movl (%edx,%ebp,4), %ebp C yp limb - multiplier
+
+ movl -4(%esi,%ecx,4), %eax C xp low limb
+
+
+L(simple_outer_entry):
+
+L(simple_inner_top):
+ C eax xp limb
+ C ebx carry limb
+ C ecx loop counter (negative)
+ C edx scratch
+ C esi xp end
+ C edi wp end
+ C ebp multiplier
+
+ mull %ebp
+
+ addl %eax, %ebx
+ adcl $0, %edx
+
+ addl %ebx, (%edi,%ecx,4)
+ movl (%esi,%ecx,4), %eax
+ adcl $0, %edx
+
+ incl %ecx
+ movl %edx, %ebx
+ jnz L(simple_inner_top)
+
+
+ C separate code for last limb so outer loop counter handling can be
+ C interleaved
+
+ mull %ebp
+
+ movl PARAM_YSIZE, %ebp
+ addl %eax, %ebx
+
+ adcl $0, %edx
+
+ addl %ebx, (%edi)
+
+ adcl $0, %edx
+ incl %ebp
+
+ movl %edx, 4(%edi)
+ jnz L(simple_outer_top)
+
+
+L(done):
+ movl SAVE_EBX, %ebx
+
+ movl SAVE_ESI, %esi
+
+ movl SAVE_EDI, %edi
+
+ movl SAVE_EBP, %ebp
+ addl $FRAME, %esp
+
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+C
+C The unrolled loop is the same as in mpn_addmul_1, see that code for some
+C comments.
+C
+C VAR_ADJUST is the negative of how many limbs the leals in the inner loop
+C increment xp and wp. This is used to adjust xp and wp, and is rshifted to
+C given an initial VAR_COUNTER at the top of the outer loop.
+C
+C VAR_COUNTER is for the unrolled loop, running from VAR_ADJUST/UNROLL_COUNT
+C up to -1, inclusive.
+C
+C VAR_JMP is the computed jump into the unrolled loop.
+C
+C VAR_SWAP is 0 if xsize odd or 0xFFFFFFFF if xsize even, used to swap the
+C initial ebx and ecx on entry to the unrolling.
+C
+C VAR_XP_LOW is the least significant limb of xp, which is needed at the
+C start of the unrolled loop.
+C
+C PARAM_YSIZE is the outer loop counter, going from -(ysize-1) up to -1,
+C inclusive.
+C
+C PARAM_YP is offset appropriately so that the PARAM_YSIZE counter can be
+C added to give the location of the next limb of yp, which is the multiplier
+C in the unrolled loop.
+C
+C The trick with the VAR_ADJUST value means it's only necessary to do one
+C fetch in the outer loop to take care of xp, wp and the inner loop counter.
+
+
+L(unroll):
+ C eax yp
+ C ebx
+ C ecx xsize
+ C edx ysize-1
+ C esi xp end
+ C edi wp end of mul1
+ C ebp
+
+ movl PARAM_XP, %esi
+
+ movl 4(%eax), %ebp C multiplier (yp second limb)
+ leal 4(%eax,%edx,4), %eax C yp adjust for ysize indexing
+
+ movl %eax, PARAM_YP
+ movl PARAM_WP, %edi
+ negl %edx
+
+ movl %edx, PARAM_YSIZE
+ leal UNROLL_COUNT-2(%ecx), %ebx C (xsize-1)+UNROLL_COUNT-1
+ decl %ecx C xsize-1
+
+ movl (%esi), %eax C xp low limb
+ andl $-UNROLL_MASK-1, %ebx
+ negl %ecx C -(xsize-1)
+
+ negl %ebx
+ andl $UNROLL_MASK, %ecx
+
+ movl %ebx, VAR_ADJUST
+ movl %ecx, %edx
+ shll $4, %ecx
+
+ movl %eax, VAR_XP_LOW
+ sarl $UNROLL_LOG2, %ebx
+ negl %edx
+
+ C 15 code bytes per limb
+ifdef(`PIC',`
+ call L(pic_calc)
+L(unroll_here):
+',`
+ leal L(unroll_inner_entry) (%ecx,%edx,1), %ecx
+')
+
+ movl %ecx, VAR_JMP
+ movl %edx, %ecx
+ shll $31, %edx
+
+ sarl $31, %edx C 0 or -1 as xsize odd or even
+ leal 4(%edi,%ecx,4), %edi C wp and xp, adjust for unrolling,
+ leal 4(%esi,%ecx,4), %esi C and start at second limb
+
+ movl %edx, VAR_SWAP
+ jmp L(unroll_outer_entry)
+
+
+ifdef(`PIC',`
+L(pic_calc):
+ C See mpn/x86/README about old gas bugs
+ leal (%ecx,%edx,1), %ecx
+ addl $L(unroll_inner_entry)-L(unroll_here), %ecx
+ addl (%esp), %ecx
+ ret_internal
+')
+
+
+C --------------------------------------------------------------------------
+ ALIGN(16)
+L(unroll_outer_top):
+ C eax
+ C ebx
+ C ecx
+ C edx
+ C esi xp + offset
+ C edi wp + offset
+ C ebp ysize counter, negative
+
+ movl VAR_ADJUST, %ebx
+ movl PARAM_YP, %edx
+
+ movl VAR_XP_LOW, %eax
+ movl %ebp, PARAM_YSIZE C store incremented ysize counter
+
+ leal eval(UNROLL_BYTES + 4) (%edi,%ebx,4), %edi
+ leal (%esi,%ebx,4), %esi
+ sarl $UNROLL_LOG2, %ebx
+
+ movl (%edx,%ebp,4), %ebp C yp next multiplier
+
+L(unroll_outer_entry):
+ mull %ebp
+
+ movl %ebx, VAR_COUNTER
+ movl %edx, %ebx C carry high
+ movl %eax, %ecx C carry low
+
+ xorl %edx, %eax
+ movl VAR_JMP, %edx
+
+ andl VAR_SWAP, %eax
+
+ xorl %eax, %ebx C carries other way for odd index
+ xorl %eax, %ecx
+
+ jmp *%edx
+
+
+C -----------------------------------------------------------------------------
+
+L(unroll_inner_top):
+ C eax xp limb
+ C ebx carry high
+ C ecx carry low
+ C edx scratch
+ C esi xp+8
+ C edi wp
+ C ebp yp multiplier limb
+ C
+ C VAR_COUNTER loop counter, negative
+ C
+ C 15 bytes each limb
+
+ addl $UNROLL_BYTES, %edi
+
+L(unroll_inner_entry):
+
+deflit(CHUNK_COUNT,2)
+forloop(`i', 0, UNROLL_COUNT/CHUNK_COUNT-1, `
+ deflit(`disp0', eval(i*CHUNK_COUNT*4 ifelse(UNROLL_BYTES,256,-128)))
+ deflit(`disp1', eval(disp0 + 4))
+
+Zdisp( movl, disp0,(%esi), %eax)
+ mull %ebp
+Zdisp( addl, %ecx, disp0,(%edi))
+ adcl %eax, %ebx C new carry low
+ movl %edx, %ecx
+ adcl $0, %ecx C new carry high
+
+ movl disp1(%esi), %eax
+ mull %ebp
+ addl %ebx, disp1(%edi)
+ adcl %eax, %ecx C new carry low
+ movl %edx, %ebx
+ adcl $0, %ebx C new carry high
+')
+
+
+ incl VAR_COUNTER
+ leal UNROLL_BYTES(%esi), %esi
+ jnz L(unroll_inner_top)
+
+
+ C eax
+ C ebx carry high
+ C ecx carry low
+ C edx
+ C esi
+ C edi wp, pointing at second last limb)
+ C ebp
+
+deflit(`disp0', eval(UNROLL_BYTES ifelse(UNROLL_BYTES,256,-128)))
+deflit(`disp1', eval(disp0 + 4))
+
+ movl PARAM_YSIZE, %ebp
+ addl %ecx, disp0(%edi) C carry low
+
+ adcl $0, %ebx
+ incl %ebp
+
+ movl %ebx, disp1(%edi) C carry high
+ jnz L(unroll_outer_top)
+
+
+ movl SAVE_ESI, %esi
+
+ movl SAVE_EBP, %ebp
+
+ movl SAVE_EDI, %edi
+
+ movl SAVE_EBX, %ebx
+ addl $FRAME, %esp
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/p3mmx/popham.asm b/gmp/mpn/x86/p6/p3mmx/popham.asm
new file mode 100644
index 0000000000..db2f2601c9
--- /dev/null
+++ b/gmp/mpn/x86/p6/p3mmx/popham.asm
@@ -0,0 +1,42 @@
+dnl Intel Pentium-III mpn_popcount, mpn_hamdist -- population count and
+dnl hamming distance.
+
+dnl Copyright 2000, 2002, 2004, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C popcount hamdist
+C P3 generic 6.5 7
+C P3 model 9 (Banias) ? ?
+C P3 model 13 (Dothan) 5.75 6
+
+
+MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
+include_mpn(`x86/k7/mmx/popham.asm')
diff --git a/gmp/mpn/x86/p6/sqr_basecase.asm b/gmp/mpn/x86/p6/sqr_basecase.asm
new file mode 100644
index 0000000000..8fc7fdf375
--- /dev/null
+++ b/gmp/mpn/x86/p6/sqr_basecase.asm
@@ -0,0 +1,649 @@
+dnl Intel P6 mpn_sqr_basecase -- square an mpn number.
+
+dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P6: approx 4.0 cycles per cross product, or 7.75 cycles per triangular
+C product (measured on the speed difference between 20 and 40 limbs,
+C which is the Karatsuba recursing range).
+
+
+dnl These are the same as in mpn/x86/k6/sqr_basecase.asm, see that file for
+dnl a description. The only difference here is that UNROLL_COUNT can go up
+dnl to 64 (not 63) making SQR_TOOM2_THRESHOLD_MAX 67.
+
+deflit(SQR_TOOM2_THRESHOLD_MAX, 67)
+
+ifdef(`SQR_TOOM2_THRESHOLD_OVERRIDE',
+`define(`SQR_TOOM2_THRESHOLD',SQR_TOOM2_THRESHOLD_OVERRIDE)')
+
+m4_config_gmp_mparam(`SQR_TOOM2_THRESHOLD')
+deflit(UNROLL_COUNT, eval(SQR_TOOM2_THRESHOLD-3))
+
+
+C void mpn_sqr_basecase (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C The algorithm is basically the same as mpn/generic/sqr_basecase.c, but a
+C lot of function call overheads are avoided, especially when the given size
+C is small.
+C
+C The code size might look a bit excessive, but not all of it is executed so
+C it won't all get into the code cache. The 1x1, 2x2 and 3x3 special cases
+C clearly apply only to those sizes; mid sizes like 10x10 only need part of
+C the unrolled addmul; and big sizes like 40x40 that do use the full
+C unrolling will least be making good use of it, because 40x40 will take
+C something like 7000 cycles.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_sqr_basecase)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %edx
+
+ movl PARAM_SRC, %eax
+
+ cmpl $2, %edx
+ movl PARAM_DST, %ecx
+ je L(two_limbs)
+
+ movl (%eax), %eax
+ ja L(three_or_more)
+
+
+C -----------------------------------------------------------------------------
+C one limb only
+ C eax src limb
+ C ebx
+ C ecx dst
+ C edx
+
+ mull %eax
+
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(two_limbs):
+ C eax src
+ C ebx
+ C ecx dst
+ C edx
+
+defframe(SAVE_ESI, -4)
+defframe(SAVE_EBX, -8)
+defframe(SAVE_EDI, -12)
+defframe(SAVE_EBP, -16)
+deflit(`STACK_SPACE',16)
+
+ subl $STACK_SPACE, %esp
+deflit(`FRAME',STACK_SPACE)
+
+ movl %esi, SAVE_ESI
+ movl %eax, %esi
+ movl (%eax), %eax
+
+ mull %eax C src[0]^2
+
+ movl %eax, (%ecx) C dst[0]
+ movl 4(%esi), %eax
+
+ movl %ebx, SAVE_EBX
+ movl %edx, %ebx C dst[1]
+
+ mull %eax C src[1]^2
+
+ movl %edi, SAVE_EDI
+ movl %eax, %edi C dst[2]
+ movl (%esi), %eax
+
+ movl %ebp, SAVE_EBP
+ movl %edx, %ebp C dst[3]
+
+ mull 4(%esi) C src[0]*src[1]
+
+ addl %eax, %ebx
+ movl SAVE_ESI, %esi
+
+ adcl %edx, %edi
+
+ adcl $0, %ebp
+ addl %ebx, %eax
+ movl SAVE_EBX, %ebx
+
+ adcl %edi, %edx
+ movl SAVE_EDI, %edi
+
+ adcl $0, %ebp
+
+ movl %eax, 4(%ecx)
+
+ movl %ebp, 12(%ecx)
+ movl SAVE_EBP, %ebp
+
+ movl %edx, 8(%ecx)
+ addl $FRAME, %esp
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(three_or_more):
+ C eax src low limb
+ C ebx
+ C ecx dst
+ C edx size
+deflit(`FRAME',0)
+
+ pushl %esi defframe_pushl(`SAVE_ESI')
+ cmpl $4, %edx
+
+ movl PARAM_SRC, %esi
+ jae L(four_or_more)
+
+
+C -----------------------------------------------------------------------------
+C three limbs
+
+ C eax src low limb
+ C ebx
+ C ecx dst
+ C edx
+ C esi src
+ C edi
+ C ebp
+
+ pushl %ebp defframe_pushl(`SAVE_EBP')
+ pushl %edi defframe_pushl(`SAVE_EDI')
+
+ mull %eax C src[0] ^ 2
+
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+
+ movl 4(%esi), %eax
+ xorl %ebp, %ebp
+
+ mull %eax C src[1] ^ 2
+
+ movl %eax, 8(%ecx)
+ movl %edx, 12(%ecx)
+ movl 8(%esi), %eax
+
+ pushl %ebx defframe_pushl(`SAVE_EBX')
+
+ mull %eax C src[2] ^ 2
+
+ movl %eax, 16(%ecx)
+ movl %edx, 20(%ecx)
+
+ movl (%esi), %eax
+
+ mull 4(%esi) C src[0] * src[1]
+
+ movl %eax, %ebx
+ movl %edx, %edi
+
+ movl (%esi), %eax
+
+ mull 8(%esi) C src[0] * src[2]
+
+ addl %eax, %edi
+ movl %edx, %ebp
+
+ adcl $0, %ebp
+ movl 4(%esi), %eax
+
+ mull 8(%esi) C src[1] * src[2]
+
+ xorl %esi, %esi
+ addl %eax, %ebp
+
+ C eax
+ C ebx dst[1]
+ C ecx dst
+ C edx dst[4]
+ C esi zero, will be dst[5]
+ C edi dst[2]
+ C ebp dst[3]
+
+ adcl $0, %edx
+ addl %ebx, %ebx
+
+ adcl %edi, %edi
+
+ adcl %ebp, %ebp
+
+ adcl %edx, %edx
+ movl 4(%ecx), %eax
+
+ adcl $0, %esi
+ addl %ebx, %eax
+
+ movl %eax, 4(%ecx)
+ movl 8(%ecx), %eax
+
+ adcl %edi, %eax
+ movl 12(%ecx), %ebx
+
+ adcl %ebp, %ebx
+ movl 16(%ecx), %edi
+
+ movl %eax, 8(%ecx)
+ movl SAVE_EBP, %ebp
+
+ movl %ebx, 12(%ecx)
+ movl SAVE_EBX, %ebx
+
+ adcl %edx, %edi
+ movl 20(%ecx), %eax
+
+ movl %edi, 16(%ecx)
+ movl SAVE_EDI, %edi
+
+ adcl %esi, %eax C no carry out of this
+ movl SAVE_ESI, %esi
+
+ movl %eax, 20(%ecx)
+ addl $FRAME, %esp
+
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+defframe(VAR_COUNTER,-20)
+defframe(VAR_JMP, -24)
+deflit(`STACK_SPACE',24)
+
+L(four_or_more):
+ C eax src low limb
+ C ebx
+ C ecx
+ C edx size
+ C esi src
+ C edi
+ C ebp
+deflit(`FRAME',4) dnl %esi already pushed
+
+C First multiply src[0]*src[1..size-1] and store at dst[1..size].
+
+ subl $STACK_SPACE-FRAME, %esp
+deflit(`FRAME',STACK_SPACE)
+ movl $1, %ecx
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ movl %ebx, SAVE_EBX
+ subl %edx, %ecx C -(size-1)
+
+ movl %ebp, SAVE_EBP
+ movl $0, %ebx C initial carry
+
+ leal (%esi,%edx,4), %esi C &src[size]
+ movl %eax, %ebp C multiplier
+
+ leal -4(%edi,%edx,4), %edi C &dst[size-1]
+
+
+C This loop runs at just over 6 c/l.
+
+L(mul_1):
+ C eax scratch
+ C ebx carry
+ C ecx counter, limbs, negative, -(size-1) to -1
+ C edx scratch
+ C esi &src[size]
+ C edi &dst[size-1]
+ C ebp multiplier
+
+ movl %ebp, %eax
+
+ mull (%esi,%ecx,4)
+
+ addl %ebx, %eax
+ movl $0, %ebx
+
+ adcl %edx, %ebx
+ movl %eax, 4(%edi,%ecx,4)
+
+ incl %ecx
+ jnz L(mul_1)
+
+
+ movl %ebx, 4(%edi)
+
+
+C Addmul src[n]*src[n+1..size-1] at dst[2*n-1...], for each n=1..size-2.
+C
+C The last two addmuls, which are the bottom right corner of the product
+C triangle, are left to the end. These are src[size-3]*src[size-2,size-1]
+C and src[size-2]*src[size-1]. If size is 4 then it's only these corner
+C cases that need to be done.
+C
+C The unrolled code is the same as mpn_addmul_1(), see that routine for some
+C comments.
+C
+C VAR_COUNTER is the outer loop, running from -(size-4) to -1, inclusive.
+C
+C VAR_JMP is the computed jump into the unrolled code, stepped by one code
+C chunk each outer loop.
+
+dnl This is also hard-coded in the address calculation below.
+deflit(CODE_BYTES_PER_LIMB, 15)
+
+dnl With &src[size] and &dst[size-1] pointers, the displacements in the
+dnl unrolled code fit in a byte for UNROLL_COUNT values up to 32, but above
+dnl that an offset must be added to them.
+deflit(OFFSET,
+ifelse(eval(UNROLL_COUNT>32),1,
+eval((UNROLL_COUNT-32)*4),
+0))
+
+ C eax
+ C ebx carry
+ C ecx
+ C edx
+ C esi &src[size]
+ C edi &dst[size-1]
+ C ebp
+
+ movl PARAM_SIZE, %ecx
+
+ subl $4, %ecx
+ jz L(corner)
+
+ movl %ecx, %edx
+ negl %ecx
+
+ shll $4, %ecx
+ifelse(OFFSET,0,,`subl $OFFSET, %esi')
+
+ifdef(`PIC',`
+ call L(pic_calc)
+L(here):
+',`
+ leal L(unroll_inner_end)-eval(2*CODE_BYTES_PER_LIMB)(%ecx,%edx), %ecx
+')
+ negl %edx
+
+ifelse(OFFSET,0,,`subl $OFFSET, %edi')
+
+ C The calculated jump mustn't be before the start of the available
+ C code. This is the limit that UNROLL_COUNT puts on the src operand
+ C size, but checked here using the jump address directly.
+
+ ASSERT(ae,
+ `movl_text_address( L(unroll_inner_start), %eax)
+ cmpl %eax, %ecx')
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(unroll_outer_top):
+ C eax
+ C ebx high limb to store
+ C ecx VAR_JMP
+ C edx VAR_COUNTER, limbs, negative
+ C esi &src[size], constant
+ C edi dst ptr, second highest limb of last addmul
+ C ebp
+
+ movl -12+OFFSET(%esi,%edx,4), %ebp C multiplier
+ movl %edx, VAR_COUNTER
+
+ movl -8+OFFSET(%esi,%edx,4), %eax C first limb of multiplicand
+
+ mull %ebp
+
+define(cmovX,`ifelse(eval(UNROLL_COUNT%2),1,`cmovz($@)',`cmovnz($@)')')
+
+ testb $1, %cl
+
+ movl %edx, %ebx C high carry
+ leal 4(%edi), %edi
+
+ movl %ecx, %edx C jump
+
+ movl %eax, %ecx C low carry
+ leal CODE_BYTES_PER_LIMB(%edx), %edx
+
+ cmovX( %ebx, %ecx) C high carry reverse
+ cmovX( %eax, %ebx) C low carry reverse
+ movl %edx, VAR_JMP
+ jmp *%edx
+
+
+ C Must be on an even address here so the low bit of the jump address
+ C will indicate which way around ecx/ebx should start.
+
+ ALIGN(2)
+
+L(unroll_inner_start):
+ C eax scratch
+ C ebx carry high
+ C ecx carry low
+ C edx scratch
+ C esi src pointer
+ C edi dst pointer
+ C ebp multiplier
+ C
+ C 15 code bytes each limb
+ C ecx/ebx reversed on each chunk
+
+forloop(`i', UNROLL_COUNT, 1, `
+ deflit(`disp_src', eval(-i*4 + OFFSET))
+ deflit(`disp_dst', eval(disp_src))
+
+ m4_assert(`disp_src>=-128 && disp_src<128')
+ m4_assert(`disp_dst>=-128 && disp_dst<128')
+
+ifelse(eval(i%2),0,`
+Zdisp( movl, disp_src,(%esi), %eax)
+ mull %ebp
+Zdisp( addl, %ebx, disp_dst,(%edi))
+ adcl %eax, %ecx
+ movl %edx, %ebx
+ adcl $0, %ebx
+',`
+ dnl this one comes out last
+Zdisp( movl, disp_src,(%esi), %eax)
+ mull %ebp
+Zdisp( addl, %ecx, disp_dst,(%edi))
+ adcl %eax, %ebx
+ movl %edx, %ecx
+ adcl $0, %ecx
+')
+')
+L(unroll_inner_end):
+
+ addl %ebx, m4_empty_if_zero(OFFSET)(%edi)
+
+ movl VAR_COUNTER, %edx
+ adcl $0, %ecx
+
+ movl %ecx, m4_empty_if_zero(OFFSET+4)(%edi)
+ movl VAR_JMP, %ecx
+
+ incl %edx
+ jnz L(unroll_outer_top)
+
+
+ifelse(OFFSET,0,,`
+ addl $OFFSET, %esi
+ addl $OFFSET, %edi
+')
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(16)
+L(corner):
+ C eax
+ C ebx
+ C ecx
+ C edx
+ C esi &src[size]
+ C edi &dst[2*size-5]
+ C ebp
+
+ movl -12(%esi), %eax
+
+ mull -8(%esi)
+
+ addl %eax, (%edi)
+ movl -12(%esi), %eax
+ movl $0, %ebx
+
+ adcl %edx, %ebx
+
+ mull -4(%esi)
+
+ addl %eax, %ebx
+ movl -8(%esi), %eax
+
+ adcl $0, %edx
+
+ addl %ebx, 4(%edi)
+ movl $0, %ebx
+
+ adcl %edx, %ebx
+
+ mull -4(%esi)
+
+ movl PARAM_SIZE, %ecx
+ addl %ebx, %eax
+
+ adcl $0, %edx
+
+ movl %eax, 8(%edi)
+
+ movl %edx, 12(%edi)
+ movl PARAM_DST, %edi
+
+
+C Left shift of dst[1..2*size-2], the bit shifted out becomes dst[2*size-1].
+
+ subl $1, %ecx C size-1
+ xorl %eax, %eax C ready for final adcl, and clear carry
+
+ movl %ecx, %edx
+ movl PARAM_SRC, %esi
+
+
+L(lshift):
+ C eax
+ C ebx
+ C ecx counter, size-1 to 1
+ C edx size-1 (for later use)
+ C esi src (for later use)
+ C edi dst, incrementing
+ C ebp
+
+ rcll 4(%edi)
+ rcll 8(%edi)
+
+ leal 8(%edi), %edi
+ decl %ecx
+ jnz L(lshift)
+
+
+ adcl %eax, %eax
+
+ movl %eax, 4(%edi) C dst most significant limb
+ movl (%esi), %eax C src[0]
+
+ leal 4(%esi,%edx,4), %esi C &src[size]
+ subl %edx, %ecx C -(size-1)
+
+
+C Now add in the squares on the diagonal, src[0]^2, src[1]^2, ...,
+C src[size-1]^2. dst[0] hasn't yet been set at all yet, and just gets the
+C low limb of src[0]^2.
+
+
+ mull %eax
+
+ movl %eax, (%edi,%ecx,8) C dst[0]
+
+
+L(diag):
+ C eax scratch
+ C ebx scratch
+ C ecx counter, negative
+ C edx carry
+ C esi &src[size]
+ C edi dst[2*size-2]
+ C ebp
+
+ movl (%esi,%ecx,4), %eax
+ movl %edx, %ebx
+
+ mull %eax
+
+ addl %ebx, 4(%edi,%ecx,8)
+ adcl %eax, 8(%edi,%ecx,8)
+ adcl $0, %edx
+
+ incl %ecx
+ jnz L(diag)
+
+
+ movl SAVE_ESI, %esi
+ movl SAVE_EBX, %ebx
+
+ addl %edx, 4(%edi) C dst most significant limb
+
+ movl SAVE_EDI, %edi
+ movl SAVE_EBP, %ebp
+ addl $FRAME, %esp
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+ifdef(`PIC',`
+L(pic_calc):
+ addl (%esp), %ecx
+ addl $L(unroll_inner_end)-L(here)-eval(2*CODE_BYTES_PER_LIMB), %ecx
+ addl %edx, %ecx
+ ret_internal
+')
+
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/p6/sse2/addmul_1.asm b/gmp/mpn/x86/p6/sse2/addmul_1.asm
new file mode 100644
index 0000000000..144b627aa3
--- /dev/null
+++ b/gmp/mpn/x86/p6/sse2/addmul_1.asm
@@ -0,0 +1,37 @@
+dnl Intel P6/SSE2 mpn_addmul_1.
+
+dnl Copyright 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO
+C * Write P6 specific SSE2 code.
+
+MULFUNC_PROLOGUE(mpn_addmul_1)
+include_mpn(`x86/pentium4/sse2/addmul_1.asm')
diff --git a/gmp/mpn/x86/p6/sse2/gmp-mparam.h b/gmp/mpn/x86/p6/sse2/gmp-mparam.h
new file mode 100644
index 0000000000..69226289a7
--- /dev/null
+++ b/gmp/mpn/x86/p6/sse2/gmp-mparam.h
@@ -0,0 +1,197 @@
+/* Intel P6/sse2 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2003, 2008-2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* NOTE: In a fat binary build SQR_TOOM2_THRESHOLD here cannot be more than the
+ value in mpn/x86/p6/gmp-mparam.h. The latter is used as a hard limit in
+ mpn/x86/p6/sqr_basecase.asm. */
+
+
+/* 1867 MHz P6 model 13 */
+
+#define MOD_1_NORM_THRESHOLD 4
+#define MOD_1_UNNORM_THRESHOLD 4
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 11
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 8
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 21
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 77
+#define MUL_TOOM44_THRESHOLD 169
+#define MUL_TOOM6H_THRESHOLD 246
+#define MUL_TOOM8H_THRESHOLD 381
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 114
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 97
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 80
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 106
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 101
+#define SQR_TOOM4_THRESHOLD 154
+#define SQR_TOOM6_THRESHOLD 222
+#define SQR_TOOM8_THRESHOLD 527
+
+#define MULMID_TOOM42_THRESHOLD 58
+
+#define MULMOD_BNM1_THRESHOLD 13
+#define SQRMOD_BNM1_THRESHOLD 17
+
+#define MUL_FFT_MODF_THRESHOLD 690 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 565, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 25, 7}, { 13, 6}, { 28, 7}, { 15, 6}, \
+ { 31, 7}, { 17, 6}, { 35, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 5}, \
+ { 383, 4}, { 991, 5}, { 511, 6}, { 267, 7}, \
+ { 157, 8}, { 91, 9}, { 47, 8}, { 111, 9}, \
+ { 63, 8}, { 127, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 159,10}, { 95,11}, { 63,10}, \
+ { 143, 9}, { 287,10}, { 159,11}, { 95,10}, \
+ { 191,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,10}, { 287,11}, \
+ { 159,10}, { 335, 9}, { 671,11}, { 191,10}, \
+ { 383, 9}, { 767,10}, { 399, 9}, { 799,10}, \
+ { 415,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607,11}, \
+ { 319,10}, { 671,12}, { 191,11}, { 383,10}, \
+ { 799,11}, { 415,10}, { 831,13}, { 127,12}, \
+ { 255,11}, { 543,10}, { 1087,11}, { 607,10}, \
+ { 1215,12}, { 319,11}, { 671,10}, { 1343,11}, \
+ { 735,10}, { 1471,12}, { 383,11}, { 799,10}, \
+ { 1599,11}, { 863,12}, { 447,11}, { 959,13}, \
+ { 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
+ { 1215,12}, { 639,11}, { 1343,12}, { 703,11}, \
+ { 1471,13}, { 383,12}, { 831,11}, { 1727,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1215,13}, \
+ { 639,12}, { 1471,11}, { 2943,13}, { 767,12}, \
+ { 1727,13}, { 895,12}, { 1919,14}, { 511,13}, \
+ { 1023,12}, { 2111,13}, { 1151,12}, { 2431,13}, \
+ { 1407,12}, { 2815,14}, { 767,13}, { 1663,12}, \
+ { 3455,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 132
+#define MUL_FFT_THRESHOLD 7424
+
+#define SQR_FFT_MODF_THRESHOLD 565 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 472, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 17, 6}, { 35, 7}, { 27, 8}, \
+ { 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
+ { 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
+ { 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
+ { 31, 8}, { 63, 4}, { 1023, 8}, { 67, 9}, \
+ { 39, 5}, { 639, 4}, { 1471, 6}, { 383, 7}, \
+ { 209, 8}, { 119, 9}, { 63, 7}, { 255, 8}, \
+ { 139, 9}, { 71, 8}, { 143, 9}, { 79,10}, \
+ { 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
+ { 135,10}, { 79, 9}, { 159, 8}, { 319, 9}, \
+ { 167,10}, { 95,11}, { 63,10}, { 143, 9}, \
+ { 287,10}, { 159,11}, { 95,10}, { 191,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 543, 8}, \
+ { 1087,10}, { 287, 9}, { 575,11}, { 159,10}, \
+ { 319, 9}, { 639,10}, { 335, 9}, { 671,10}, \
+ { 351, 9}, { 703,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 399, 9}, { 799,10}, { 415, 9}, \
+ { 831,11}, { 223,12}, { 127,11}, { 255,10}, \
+ { 543, 9}, { 1087,11}, { 287,10}, { 607, 9}, \
+ { 1215,11}, { 319,10}, { 671, 9}, { 1343,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 383,10}, \
+ { 799,11}, { 415,10}, { 831,13}, { 127,12}, \
+ { 255,11}, { 543,10}, { 1087,11}, { 607,12}, \
+ { 319,11}, { 671,10}, { 1343,11}, { 735,12}, \
+ { 383,11}, { 799,10}, { 1599,11}, { 863,12}, \
+ { 447,11}, { 959,13}, { 255,12}, { 511,11}, \
+ { 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
+ { 1343,12}, { 703,11}, { 1471,13}, { 383,12}, \
+ { 767,11}, { 1599,12}, { 831,11}, { 1727,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1215,13}, \
+ { 639,12}, { 1471,13}, { 767,12}, { 1727,13}, \
+ { 895,12}, { 1919,14}, { 511,13}, { 1023,12}, \
+ { 2111,13}, { 1151,12}, { 2431,13}, { 1407,14}, \
+ { 767,13}, { 1663,12}, { 3455,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 146
+#define SQR_FFT_THRESHOLD 5760
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 31
+#define MULLO_MUL_N_THRESHOLD 13463
+
+#define DC_DIV_QR_THRESHOLD 25
+#define DC_DIVAPPR_Q_THRESHOLD 55
+#define DC_BDIV_QR_THRESHOLD 60
+#define DC_BDIV_Q_THRESHOLD 132
+
+#define INV_MULMOD_BNM1_THRESHOLD 38
+#define INV_NEWTON_THRESHOLD 65
+#define INV_APPR_THRESHOLD 65
+
+#define BINV_NEWTON_THRESHOLD 252
+#define REDC_1_TO_REDC_N_THRESHOLD 62
+
+#define MU_DIV_QR_THRESHOLD 1164
+#define MU_DIVAPPR_Q_THRESHOLD 748
+#define MUPI_DIV_QR_THRESHOLD 38
+#define MU_BDIV_QR_THRESHOLD 1360
+#define MU_BDIV_Q_THRESHOLD 1470
+
+#define POWM_SEC_TABLE 2,23,258,879,2246
+
+#define MATRIX22_STRASSEN_THRESHOLD 17
+#define HGCD_THRESHOLD 69
+#define HGCD_APPR_THRESHOLD 112
+#define HGCD_REDUCE_THRESHOLD 3389
+#define GCD_DC_THRESHOLD 386
+#define GCDEXT_DC_THRESHOLD 303
+#define JACOBI_BASE_METHOD 1
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 25
+#define SET_STR_DC_THRESHOLD 582
+#define SET_STR_PRECOMPUTE_THRESHOLD 1118
+
+#define FAC_DSC_THRESHOLD 178
+#define FAC_ODD_THRESHOLD 34
diff --git a/gmp/mpn/x86/p6/sse2/mod_1_1.asm b/gmp/mpn/x86/p6/sse2/mod_1_1.asm
new file mode 100644
index 0000000000..8b7b7adaa5
--- /dev/null
+++ b/gmp/mpn/x86/p6/sse2/mod_1_1.asm
@@ -0,0 +1,34 @@
+dnl Intel P6/SSE2 mpn_mod_1_1.
+
+dnl Copyright 2009, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_mod_1_1p)
+include_mpn(`x86/pentium4/sse2/mod_1_1.asm')
diff --git a/gmp/mpn/x86/p6/sse2/mod_1_4.asm b/gmp/mpn/x86/p6/sse2/mod_1_4.asm
new file mode 100644
index 0000000000..49c96c60b9
--- /dev/null
+++ b/gmp/mpn/x86/p6/sse2/mod_1_4.asm
@@ -0,0 +1,34 @@
+dnl Intel P6/SSE2 mpn_mod_1_4.
+
+dnl Copyright 2009, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_mod_1s_4p)
+include_mpn(`x86/pentium4/sse2/mod_1_4.asm')
diff --git a/gmp/mpn/x86/p6/sse2/mul_1.asm b/gmp/mpn/x86/p6/sse2/mul_1.asm
new file mode 100644
index 0000000000..50e5b6983a
--- /dev/null
+++ b/gmp/mpn/x86/p6/sse2/mul_1.asm
@@ -0,0 +1,38 @@
+dnl Intel P6/SSE2 mpn_mul_1.
+
+dnl Copyright 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO
+C * Write P6 specific SSE2 code. It should reach 3 c/l.
+C The Pentium4 code runs at 4.2 c/l.
+
+MULFUNC_PROLOGUE(mpn_mul_1)
+include_mpn(`x86/pentium4/sse2/mul_1.asm')
diff --git a/gmp/mpn/x86/p6/sse2/mul_basecase.asm b/gmp/mpn/x86/p6/sse2/mul_basecase.asm
new file mode 100644
index 0000000000..4687625790
--- /dev/null
+++ b/gmp/mpn/x86/p6/sse2/mul_basecase.asm
@@ -0,0 +1,35 @@
+dnl Intel P6/SSE2 mpn_mul_basecase.
+
+dnl Copyright 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+MULFUNC_PROLOGUE(mpn_mul_basecase)
+include_mpn(`x86/pentium4/sse2/mul_basecase.asm')
diff --git a/gmp/mpn/x86/p6/sse2/popcount.asm b/gmp/mpn/x86/p6/sse2/popcount.asm
new file mode 100644
index 0000000000..4c02b93be2
--- /dev/null
+++ b/gmp/mpn/x86/p6/sse2/popcount.asm
@@ -0,0 +1,35 @@
+dnl Intel P6/SSE2 mpn_popcount -- population count.
+
+dnl Copyright 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+MULFUNC_PROLOGUE(mpn_popcount)
+include_mpn(`x86/pentium4/sse2/popcount.asm')
diff --git a/gmp/mpn/x86/p6/sse2/sqr_basecase.asm b/gmp/mpn/x86/p6/sse2/sqr_basecase.asm
new file mode 100644
index 0000000000..76b574b6c7
--- /dev/null
+++ b/gmp/mpn/x86/p6/sse2/sqr_basecase.asm
@@ -0,0 +1,35 @@
+dnl Intel P6/SSE2 mpn_sqr_basecase.
+
+dnl Copyright 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+MULFUNC_PROLOGUE(mpn_sqr_basecase)
+include_mpn(`x86/pentium4/sse2/sqr_basecase.asm')
diff --git a/gmp/mpn/x86/p6/sse2/submul_1.asm b/gmp/mpn/x86/p6/sse2/submul_1.asm
new file mode 100644
index 0000000000..98a603ce93
--- /dev/null
+++ b/gmp/mpn/x86/p6/sse2/submul_1.asm
@@ -0,0 +1,35 @@
+dnl Intel P6/SSE2 mpn_submul_1.
+
+dnl Copyright 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+MULFUNC_PROLOGUE(mpn_submul_1)
+include_mpn(`x86/k6/aorsmul_1.asm')
diff --git a/gmp/mpn/x86/pentium/README b/gmp/mpn/x86/pentium/README
new file mode 100644
index 0000000000..305936bbd9
--- /dev/null
+++ b/gmp/mpn/x86/pentium/README
@@ -0,0 +1,181 @@
+Copyright 1996, 1999-2001, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ INTEL PENTIUM P5 MPN SUBROUTINES
+
+
+This directory contains mpn functions optimized for Intel Pentium (P5,P54)
+processors. The mmx subdirectory has additional code for Pentium with MMX
+(P55).
+
+
+STATUS
+
+ cycles/limb
+
+ mpn_add_n/sub_n 2.375
+
+ mpn_mul_1 12.0
+ mpn_add/submul_1 14.0
+
+ mpn_mul_basecase 14.2 cycles/crossproduct (approx)
+
+ mpn_sqr_basecase 8 cycles/crossproduct (approx)
+ or 15.5 cycles/triangleproduct (approx)
+
+ mpn_l/rshift 5.375 normal (6.0 on P54)
+ 1.875 special shift by 1 bit
+
+ mpn_divrem_1 44.0
+ mpn_mod_1 28.0
+ mpn_divexact_by3 15.0
+
+ mpn_copyi/copyd 1.0
+
+Pentium MMX gets the following improvements
+
+ mpn_l/rshift 1.75
+
+ mpn_mul_1 12.0 normal, 7.0 for 16-bit multiplier
+
+
+mpn_add_n and mpn_sub_n run at asymptotically 2 cycles/limb. Due to loop
+overhead and other delays (cache refill?), they run at or near 2.5
+cycles/limb.
+
+mpn_mul_1, mpn_addmul_1, mpn_submul_1 all run 1 cycle faster than they
+should. Intel documentation says a mul instruction is 10 cycles, but it
+measures 9 and the routines using it run as 9.
+
+
+
+P55 MMX AND X87
+
+The cost of switching between MMX and x87 floating point on P55 is about 100
+cycles (fld1/por/emms for instance). In order to avoid that the two aren't
+mixed and currently that means using MMX and not x87.
+
+MMX offers a big speedup for lshift and rshift, and a nice speedup for
+16-bit multipliers in mpn_mul_1. If fast code using x87 is found then
+perhaps the preference for MMX will be reversed.
+
+
+
+
+P54 SHLDL
+
+mpn_lshift and mpn_rshift run at about 6 cycles/limb on P5 and P54, but the
+documentation indicates that they should take only 43/8 = 5.375 cycles/limb,
+or 5 cycles/limb asymptotically. The P55 runs them at the expected speed.
+
+It seems that on P54 a shldl or shrdl allows pairing in one following cycle,
+but not two. For example, back to back repetitions of the following
+
+ shldl( %cl, %eax, %ebx)
+ xorl %edx, %edx
+ xorl %esi, %esi
+
+run at 5 cycles, as expected, but repetitions of the following run at 7
+cycles, whereas 6 would be expected (and is achieved on P55),
+
+ shldl( %cl, %eax, %ebx)
+ xorl %edx, %edx
+ xorl %esi, %esi
+ xorl %edi, %edi
+ xorl %ebp, %ebp
+
+Three xorls run at 7 cycles too, so it doesn't seem to be just that pairing
+inhibited is only in the second following cycle (or something like that).
+
+Avoiding this problem would bring P54 shifts down from 6.0 c/l to 5.5 with a
+pattern of shift, 2 loads, shift, 2 stores, shift, etc. A start has been
+made on something like that, but it's not yet complete.
+
+
+
+
+OTHER NOTES
+
+Prefetching Destinations
+
+ Pentium doesn't allocate cache lines on writes, unlike most other modern
+ processors. Since the functions in the mpn class do array writes, we
+ have to handle allocating the destination cache lines by reading a word
+ from it in the loops, to achieve the best performance.
+
+Prefetching Sources
+
+ Prefetching of sources is pointless since there's no out-of-order loads.
+ Any load instruction blocks until the line is brought to L1, so it may
+ as well be the load that wants the data which blocks.
+
+Data Cache Bank Clashes
+
+ Pairing of memory operations requires that the two issued operations
+ refer to different cache banks (ie. different addresses modulo 32
+ bytes). The simplest way to ensure this is to read/write two words from
+ the same object. If we make operations on different objects, they might
+ or might not be to the same cache bank.
+
+PIC %eip Fetching
+
+ A simple call $+5 and popl can be used to get %eip, there's no need to
+ balance calls and returns since P5 doesn't have any return stack branch
+ prediction.
+
+Float Multiplies
+
+ fmul is pairable and can be issued every 2 cycles (with a 4 cycle
+ latency for data ready to use). This is a lot better than integer mull
+ or imull at 9 cycles non-pairing. Unfortunately the advantage is
+ quickly eaten away by needing to throw data through memory back to the
+ integer registers to adjust for fild and fist being signed, and to do
+ things like propagating carry bits.
+
+
+
+
+
+REFERENCES
+
+"Intel Architecture Optimization Manual", 1997, order number 242816. This
+is mostly about P5, the parts about P6 aren't relevant. Available on-line:
+
+ http://download.intel.com/design/PentiumII/manuals/242816.htm
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/x86/pentium/aors_n.asm b/gmp/mpn/x86/pentium/aors_n.asm
new file mode 100644
index 0000000000..01ebfb96ae
--- /dev/null
+++ b/gmp/mpn/x86/pentium/aors_n.asm
@@ -0,0 +1,203 @@
+dnl Intel Pentium mpn_add_n/mpn_sub_n -- mpn addition and subtraction.
+
+dnl Copyright 1992, 1994-1996, 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 2.375 cycles/limb
+
+
+ifdef(`OPERATION_add_n',`
+ define(M4_inst, adcl)
+ define(M4_function_n, mpn_add_n)
+ define(M4_function_nc, mpn_add_nc)
+
+',`ifdef(`OPERATION_sub_n',`
+ define(M4_inst, sbbl)
+ define(M4_function_n, mpn_sub_n)
+ define(M4_function_nc, mpn_sub_nc)
+
+',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
+')')')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+
+C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size);
+C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+C mp_size_t size, mp_limb_t carry);
+
+defframe(PARAM_CARRY,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC2, 12)
+defframe(PARAM_SRC1, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(M4_function_nc)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+deflit(`FRAME',16)
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC1,%esi
+ movl PARAM_SRC2,%ebp
+ movl PARAM_SIZE,%ecx
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx C zero carry flag
+ jz L(endgo)
+
+ pushl %edx
+FRAME_pushl()
+ movl PARAM_CARRY,%eax
+ shrl %eax C shift bit 0 into carry
+ jmp L(oop)
+
+L(endgo):
+deflit(`FRAME',16)
+ movl PARAM_CARRY,%eax
+ shrl %eax C shift bit 0 into carry
+ jmp L(end)
+
+EPILOGUE()
+
+
+ ALIGN(8)
+PROLOGUE(M4_function_n)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+deflit(`FRAME',16)
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC1,%esi
+ movl PARAM_SRC2,%ebp
+ movl PARAM_SIZE,%ecx
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx C zero carry flag
+ jz L(end)
+ pushl %edx
+FRAME_pushl()
+
+ ALIGN(8)
+L(oop): movl 28(%edi),%eax C fetch destination cache line
+ leal 32(%edi),%edi
+
+L(1): movl (%esi),%eax
+ movl 4(%esi),%edx
+ M4_inst %ebx,%eax
+ movl 4(%ebp),%ebx
+ M4_inst %ebx,%edx
+ movl 8(%ebp),%ebx
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L(2): movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ M4_inst %ebx,%eax
+ movl 12(%ebp),%ebx
+ M4_inst %ebx,%edx
+ movl 16(%ebp),%ebx
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L(3): movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ M4_inst %ebx,%eax
+ movl 20(%ebp),%ebx
+ M4_inst %ebx,%edx
+ movl 24(%ebp),%ebx
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L(4): movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ M4_inst %ebx,%eax
+ movl 28(%ebp),%ebx
+ M4_inst %ebx,%edx
+ movl 32(%ebp),%ebx
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebp),%ebp
+ decl %ecx
+ jnz L(oop)
+
+ popl %edx
+FRAME_popl()
+L(end):
+ decl %edx C test %edx w/o clobbering carry
+ js L(end2)
+ incl %edx
+L(oop2):
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ M4_inst %ebx,%eax
+ movl 4(%ebp),%ebx
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebp),%ebp
+ decl %edx
+ jnz L(oop2)
+L(end2):
+ movl (%esi),%eax
+ M4_inst %ebx,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/aorsmul_1.asm b/gmp/mpn/x86/pentium/aorsmul_1.asm
new file mode 100644
index 0000000000..d83cc4513b
--- /dev/null
+++ b/gmp/mpn/x86/pentium/aorsmul_1.asm
@@ -0,0 +1,144 @@
+dnl Intel Pentium mpn_addmul_1 -- mpn by limb multiplication.
+
+dnl Copyright 1992, 1994, 1996, 1999, 2000, 2002 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 14.0 cycles/limb
+
+
+ifdef(`OPERATION_addmul_1', `
+ define(M4_inst, addl)
+ define(M4_function_1, mpn_addmul_1)
+ define(M4_function_1c, mpn_addmul_1c)
+
+',`ifdef(`OPERATION_submul_1', `
+ define(M4_inst, subl)
+ define(M4_function_1, mpn_submul_1)
+ define(M4_function_1c, mpn_submul_1c)
+
+',`m4_error(`Need OPERATION_addmul_1 or OPERATION_submul_1
+')')')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_addmul_1c mpn_submul_1 mpn_submul_1c)
+
+
+C mp_limb_t mpn_addmul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult);
+C mp_limb_t mpn_addmul_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult, mp_limb_t carry);
+C
+C mp_limb_t mpn_submul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult);
+C mp_limb_t mpn_submul_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t mult, mp_limb_t carry);
+C
+
+defframe(PARAM_CARRY, 20)
+defframe(PARAM_MULTIPLIER,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+
+ ALIGN(8)
+PROLOGUE(M4_function_1c)
+deflit(`FRAME',0)
+
+ movl PARAM_CARRY, %ecx
+ pushl %esi FRAME_pushl()
+
+ jmp L(start_1c)
+
+EPILOGUE()
+
+
+ ALIGN(8)
+PROLOGUE(M4_function_1)
+deflit(`FRAME',0)
+
+ xorl %ecx, %ecx
+ pushl %esi FRAME_pushl()
+
+L(start_1c):
+ movl PARAM_SRC, %esi
+ movl PARAM_SIZE, %eax
+
+ pushl %edi FRAME_pushl()
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_DST, %edi
+ leal -1(%eax), %ebx C size-1
+
+ leal (%esi,%eax,4), %esi
+ xorl $-1, %ebx C -size, and clear carry
+
+ leal (%edi,%eax,4), %edi
+
+L(top):
+ C eax
+ C ebx counter, negative
+ C ecx carry
+ C edx
+ C esi src end
+ C edi dst end
+ C ebp
+
+ adcl $0, %ecx
+ movl (%esi,%ebx,4), %eax
+
+ mull PARAM_MULTIPLIER
+
+ addl %ecx, %eax
+ movl (%edi,%ebx,4), %ecx
+
+ adcl $0, %edx
+ M4_inst %eax, %ecx
+
+ movl %ecx, (%edi,%ebx,4)
+ incl %ebx
+
+ movl %edx, %ecx
+ jnz L(top)
+
+
+ adcl $0, %ecx
+ popl %ebx
+
+ movl %ecx, %eax
+ popl %edi
+
+ popl %esi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/bdiv_q_1.asm b/gmp/mpn/x86/pentium/bdiv_q_1.asm
new file mode 100644
index 0000000000..9fee3cb87a
--- /dev/null
+++ b/gmp/mpn/x86/pentium/bdiv_q_1.asm
@@ -0,0 +1,260 @@
+dnl Intel Pentium mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Rearranged from mpn/x86/pentium/dive_1.asm by Marco Bodrato.
+
+dnl Copyright 2001, 2002, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C divisor
+C odd even
+C P54: 24.5 30.5 cycles/limb
+C P55: 23.0 28.0
+
+MULFUNC_PROLOGUE(mpn_bdiv_q_1 mpn_pi1_bdiv_q_1)
+
+C The P55 speeds noted above, 23 cycles odd or 28 cycles even, are as
+C expected. On P54 in the even case the shrdl pairing nonsense (see
+C mpn/x86/pentium/README) costs 1 cycle, but it's not clear why there's a
+C further 1.5 slowdown for both odd and even.
+
+defframe(PARAM_SHIFT, 24)
+defframe(PARAM_INVERSE,20)
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(VAR_INVERSE,`PARAM_DST')
+
+ TEXT
+
+ ALIGN(32)
+C mp_limb_t mpn_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+PROLOGUE(mpn_bdiv_q_1)
+deflit(`FRAME',0)
+
+ movl $-1, %ecx
+ movl PARAM_DIVISOR, %eax
+
+L(strip_twos):
+ ASSERT(nz, `orl %eax, %eax')
+ shrl %eax
+ incl %ecx C shift count
+
+ jnc L(strip_twos)
+
+ leal 1(%eax,%eax), %edx C d
+ andl $127, %eax C d/2, 7 bits
+
+ pushl %ebx FRAME_pushl()
+ pushl %ebp FRAME_pushl()
+
+ifdef(`PIC',`
+ call L(here)
+L(here):
+ popl %ebp C eip
+
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebp
+ C AGI
+ movl binvert_limb_table@GOT(%ebp), %ebp
+ C AGI
+ movzbl (%eax,%ebp), %eax
+',`
+
+dnl non-PIC
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+
+ movl %eax, %ebp C inv
+ addl %eax, %eax C 2*inv
+
+ imull %ebp, %ebp C inv*inv
+
+ imull %edx, %ebp C inv*inv*d
+
+ subl %ebp, %eax C inv = 2*inv - inv*inv*d
+ movl PARAM_SIZE, %ebx
+
+ movl %eax, %ebp
+ addl %eax, %eax C 2*inv
+
+ imull %ebp, %ebp C inv*inv
+
+ imull %edx, %ebp C inv*inv*d
+
+ subl %ebp, %eax C inv = 2*inv - inv*inv*d
+ movl %edx, PARAM_DIVISOR C d without twos
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ imull PARAM_DIVISOR, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ jmp L(common)
+EPILOGUE()
+
+C mp_limb_t
+C mpn_pi1_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor,
+C mp_limb_t inverse, int shift)
+ ALIGN(32)
+PROLOGUE(mpn_pi1_bdiv_q_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SHIFT, %ecx
+
+ pushl %ebx FRAME_pushl()
+ pushl %ebp FRAME_pushl()
+
+ movl PARAM_SIZE, %ebx
+ movl PARAM_INVERSE, %eax
+
+L(common):
+ pushl %esi FRAME_pushl()
+ push %edi FRAME_pushl()
+
+ movl PARAM_SRC, %esi
+ movl PARAM_DST, %edi
+ movl %eax, VAR_INVERSE
+
+ leal (%esi,%ebx,4), %esi C src end
+ leal (%edi,%ebx,4), %edi C dst end
+
+ negl %ebx C -size
+
+ xorl %ebp, %ebp C initial carry bit
+
+ orl %ecx, %ecx C shift
+ movl (%esi,%ebx,4), %eax C src low limb
+ jz L(odd_entry)
+
+ xorl %edx, %edx C initial carry limb (for even, if one)
+ incl %ebx
+ jz L(one)
+
+ movl (%esi,%ebx,4), %edx C src second limb (for even)
+ shrdl( %cl, %edx, %eax)
+
+ jmp L(even_entry)
+
+
+ ALIGN(8)
+L(odd_top):
+ C eax scratch
+ C ebx counter, limbs, negative
+ C ecx
+ C edx
+ C esi src end
+ C edi dst end
+ C ebp carry bit, 0 or -1
+
+ mull PARAM_DIVISOR
+
+ movl (%esi,%ebx,4), %eax
+ subl %ebp, %edx
+
+ subl %edx, %eax
+
+ sbbl %ebp, %ebp
+
+L(odd_entry):
+ imull VAR_INVERSE, %eax
+
+ movl %eax, (%edi,%ebx,4)
+
+ incl %ebx
+ jnz L(odd_top)
+
+ popl %edi
+ popl %esi
+
+ popl %ebp
+ popl %ebx
+
+ ret
+
+L(even_top):
+ C eax scratch
+ C ebx counter, limbs, negative
+ C ecx twos
+ C edx
+ C esi src end
+ C edi dst end
+ C ebp carry bit, 0 or -1
+
+ mull PARAM_DIVISOR
+
+ subl %ebp, %edx C carry bit
+ movl -4(%esi,%ebx,4), %eax C src limb
+
+ movl (%esi,%ebx,4), %ebp C and one above it
+
+ shrdl( %cl, %ebp, %eax)
+
+ subl %edx, %eax C carry limb
+
+ sbbl %ebp, %ebp
+
+L(even_entry):
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi,%ebx,4)
+ incl %ebx
+
+ jnz L(even_top)
+
+ mull PARAM_DIVISOR
+
+ movl -4(%esi), %eax C src high limb
+ subl %ebp, %edx
+
+L(one):
+ shrl %cl, %eax
+
+ subl %edx, %eax C no carry if division is exact
+
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi) C dst high limb
+ nop C protect against cache bank clash
+
+ popl %edi
+ popl %esi
+
+ popl %ebp
+ popl %ebx
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/com.asm b/gmp/mpn/x86/pentium/com.asm
new file mode 100644
index 0000000000..b0805452a6
--- /dev/null
+++ b/gmp/mpn/x86/pentium/com.asm
@@ -0,0 +1,181 @@
+dnl Intel Pentium mpn_com -- mpn ones complement.
+
+dnl Copyright 1996, 2001, 2002, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 1.75 cycles/limb
+
+
+NAILS_SUPPORT(0-31)
+
+
+C void mpn_com (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C This code is similar to mpn_copyi, basically there's just some "xorl
+C $GMP_NUMB_MASK"s inserted.
+C
+C Alternatives:
+C
+C On P55 some MMX code could be 1.25 c/l (8 limb unrolled) if src and dst
+C are the same alignment mod 8, but it doesn't seem worth the trouble for
+C just that case (there'd need to be some plain integer available too for
+C the unaligned case).
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_com)
+deflit(`FRAME',0)
+
+ movl PARAM_SRC, %eax
+ movl PARAM_SIZE, %ecx
+
+ pushl %esi FRAME_pushl()
+ pushl %edi FRAME_pushl()
+
+ leal (%eax,%ecx,4), %eax
+ xorl $-1, %ecx C -size-1
+
+ movl PARAM_DST, %edx
+ addl $8, %ecx C -size+7
+
+ jns L(end)
+
+ movl (%edx), %esi C fetch destination cache line
+ nop
+
+L(top):
+ C eax &src[size]
+ C ebx
+ C ecx counter, limbs, negative
+ C edx dst, incrementing
+ C esi scratch
+ C edi scratch
+ C ebp
+
+ movl 28(%edx), %esi C destination prefetch
+ addl $32, %edx
+
+ movl -28(%eax,%ecx,4), %esi
+ movl -24(%eax,%ecx,4), %edi
+ xorl $GMP_NUMB_MASK, %esi
+ xorl $GMP_NUMB_MASK, %edi
+ movl %esi, -32(%edx)
+ movl %edi, -28(%edx)
+
+ movl -20(%eax,%ecx,4), %esi
+ movl -16(%eax,%ecx,4), %edi
+ xorl $GMP_NUMB_MASK, %esi
+ xorl $GMP_NUMB_MASK, %edi
+ movl %esi, -24(%edx)
+ movl %edi, -20(%edx)
+
+ movl -12(%eax,%ecx,4), %esi
+ movl -8(%eax,%ecx,4), %edi
+ xorl $GMP_NUMB_MASK, %esi
+ xorl $GMP_NUMB_MASK, %edi
+ movl %esi, -16(%edx)
+ movl %edi, -12(%edx)
+
+ movl -4(%eax,%ecx,4), %esi
+ movl (%eax,%ecx,4), %edi
+ xorl $GMP_NUMB_MASK, %esi
+ xorl $GMP_NUMB_MASK, %edi
+ movl %esi, -8(%edx)
+ movl %edi, -4(%edx)
+
+ addl $8, %ecx
+ js L(top)
+
+
+L(end):
+ C eax &src[size]
+ C ecx 0 to 7, representing respectively 7 to 0 limbs remaining
+ C edx dst, next location to store
+
+ subl $4, %ecx
+ nop
+
+ jns L(no4)
+
+ movl -12(%eax,%ecx,4), %esi
+ movl -8(%eax,%ecx,4), %edi
+ xorl $GMP_NUMB_MASK, %esi
+ xorl $GMP_NUMB_MASK, %edi
+ movl %esi, (%edx)
+ movl %edi, 4(%edx)
+
+ movl -4(%eax,%ecx,4), %esi
+ movl (%eax,%ecx,4), %edi
+ xorl $GMP_NUMB_MASK, %esi
+ xorl $GMP_NUMB_MASK, %edi
+ movl %esi, 8(%edx)
+ movl %edi, 12(%edx)
+
+ addl $16, %edx
+ addl $4, %ecx
+L(no4):
+
+ subl $2, %ecx
+ nop
+
+ jns L(no2)
+
+ movl -4(%eax,%ecx,4), %esi
+ movl (%eax,%ecx,4), %edi
+ xorl $GMP_NUMB_MASK, %esi
+ xorl $GMP_NUMB_MASK, %edi
+ movl %esi, (%edx)
+ movl %edi, 4(%edx)
+
+ addl $8, %edx
+ addl $2, %ecx
+L(no2):
+
+ popl %edi
+ jnz L(done)
+
+ movl -4(%eax), %ecx
+
+ xorl $GMP_NUMB_MASK, %ecx
+ popl %esi
+
+ movl %ecx, (%edx)
+ ret
+
+L(done):
+ popl %esi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/copyd.asm b/gmp/mpn/x86/pentium/copyd.asm
new file mode 100644
index 0000000000..72a543b2a3
--- /dev/null
+++ b/gmp/mpn/x86/pentium/copyd.asm
@@ -0,0 +1,146 @@
+dnl Intel Pentium mpn_copyd -- copy limb vector, decrementing.
+
+dnl Copyright 1996, 2001, 2002, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 1.25 cycles/limb
+
+
+C void mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C See comments in copyi.asm.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_copyd)
+deflit(`FRAME',0)
+
+ movl PARAM_SRC, %eax
+ movl PARAM_SIZE, %ecx
+
+ pushl %esi FRAME_pushl()
+ pushl %edi FRAME_pushl()
+
+ leal -4(%eax,%ecx,4), %eax C &src[size-1]
+ movl PARAM_DST, %edx
+
+ subl $7, %ecx C size-7
+ jle L(end)
+
+ movl 28-4(%edx,%ecx,4), %esi C prefetch cache, dst[size-1]
+ nop
+
+L(top):
+ C eax src, decrementing
+ C ebx
+ C ecx counter, limbs
+ C edx dst
+ C esi scratch
+ C edi scratch
+ C ebp
+
+ movl 28-32(%edx,%ecx,4), %esi C prefetch dst cache line
+ subl $8, %ecx
+
+ movl (%eax), %esi C read words pairwise
+ movl -4(%eax), %edi
+ movl %esi, 56(%edx,%ecx,4) C store words pairwise
+ movl %edi, 52(%edx,%ecx,4)
+
+ movl -8(%eax), %esi
+ movl -12(%eax), %edi
+ movl %esi, 48(%edx,%ecx,4)
+ movl %edi, 44(%edx,%ecx,4)
+
+ movl -16(%eax), %esi
+ movl -20(%eax), %edi
+ movl %esi, 40(%edx,%ecx,4)
+ movl %edi, 36(%edx,%ecx,4)
+
+ movl -24(%eax), %esi
+ movl -28(%eax), %edi
+ movl %esi, 32(%edx,%ecx,4)
+ movl %edi, 28(%edx,%ecx,4)
+
+ leal -32(%eax), %eax
+ jg L(top)
+
+
+L(end):
+ C ecx -7 to 0, representing respectively 0 to 7 limbs remaining
+ C eax src end
+ C edx dst, next location to store
+
+ addl $4, %ecx
+ jle L(no4)
+
+ movl (%eax), %esi
+ movl -4(%eax), %edi
+ movl %esi, 8(%edx,%ecx,4)
+ movl %edi, 4(%edx,%ecx,4)
+
+ movl -8(%eax), %esi
+ movl -12(%eax), %edi
+ movl %esi, (%edx,%ecx,4)
+ movl %edi, -4(%edx,%ecx,4)
+
+ subl $16, %eax
+ subl $4, %ecx
+L(no4):
+
+ addl $2, %ecx
+ jle L(no2)
+
+ movl (%eax), %esi
+ movl -4(%eax), %edi
+ movl %esi, (%edx,%ecx,4)
+ movl %edi, -4(%edx,%ecx,4)
+
+ subl $8, %eax
+ subl $2, %ecx
+L(no2):
+
+ jnz L(done)
+
+ movl (%eax), %ecx
+ movl %ecx, (%edx) C risk of cache bank clash here
+
+L(done):
+ popl %edi
+ popl %esi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/copyi.asm b/gmp/mpn/x86/pentium/copyi.asm
new file mode 100644
index 0000000000..d983d6b46e
--- /dev/null
+++ b/gmp/mpn/x86/pentium/copyi.asm
@@ -0,0 +1,164 @@
+dnl Intel Pentium mpn_copyi -- copy limb vector, incrementing.
+
+dnl Copyright 1996, 2001, 2002, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 1.25 cycles/limb
+
+
+C void mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C Destination prefetching is done to avoid repeated write-throughs on lines
+C not already in L1.
+C
+C At least one of the src or dst pointer needs to be incremented rather than
+C using indexing, so that there's somewhere to put the loop control without
+C an AGI. Incrementing one and not two lets us keep loop overhead to 2
+C cycles. Making it the src pointer incremented avoids an AGI on the %ecx
+C subtracts in the finishup code.
+C
+C The block of finishup code is almost as big as the main loop itself, which
+C is unfortunate, but it's faster that way than with say rep movsl, by about
+C 10 cycles for instance on P55.
+C
+C There's nothing to be gained from MMX on P55, since it can do only one
+C movq load (or store) per cycle, so the throughput would be the same as the
+C code here (and even then only if src and dst have the same alignment mod
+C 8).
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_copyi)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_DST, %edx
+
+ pushl %ebx FRAME_pushl()
+ pushl %esi FRAME_pushl()
+
+ leal (%edx,%ecx,4), %edx C &dst[size-1]
+ xorl $-1, %ecx C -size-1
+
+ movl PARAM_SRC, %esi
+ addl $8, %ecx C -size+7
+
+ jns L(end)
+
+ movl -28(%edx,%ecx,4), %eax C fetch destination cache line, dst[0]
+ nop
+
+L(top):
+ C eax scratch
+ C ebx scratch
+ C ecx counter, limbs, negative
+ C edx &dst[size-1]
+ C esi src, incrementing
+ C edi
+ C ebp
+
+ movl (%edx,%ecx,4), %eax C fetch destination cache line
+ addl $8, %ecx
+
+ movl (%esi), %eax C read words pairwise
+ movl 4(%esi), %ebx
+ movl %eax, -60(%edx,%ecx,4) C store words pairwise
+ movl %ebx, -56(%edx,%ecx,4)
+
+ movl 8(%esi), %eax
+ movl 12(%esi), %ebx
+ movl %eax, -52(%edx,%ecx,4)
+ movl %ebx, -48(%edx,%ecx,4)
+
+ movl 16(%esi), %eax
+ movl 20(%esi), %ebx
+ movl %eax, -44(%edx,%ecx,4)
+ movl %ebx, -40(%edx,%ecx,4)
+
+ movl 24(%esi), %eax
+ movl 28(%esi), %ebx
+ movl %eax, -36(%edx,%ecx,4)
+ movl %ebx, -32(%edx,%ecx,4)
+
+ leal 32(%esi), %esi
+ js L(top)
+
+
+L(end):
+ C ecx 0 to 7, representing respectively 7 to 0 limbs remaining
+ C esi src end
+ C edx dst, next location to store
+
+ subl $4, %ecx
+ jns L(no4)
+
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+ movl %eax, -12(%edx,%ecx,4)
+ movl %ebx, -8(%edx,%ecx,4)
+
+ movl 8(%esi), %eax
+ movl 12(%esi), %ebx
+ movl %eax, -4(%edx,%ecx,4)
+ movl %ebx, (%edx,%ecx,4)
+
+ addl $16, %esi
+ addl $4, %ecx
+L(no4):
+
+ subl $2, %ecx
+ jns L(no2)
+
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+ movl %eax, -4(%edx,%ecx,4)
+ movl %ebx, (%edx,%ecx,4)
+
+ addl $8, %esi
+ addl $2, %ecx
+L(no2):
+
+ jnz L(done)
+
+ movl (%esi), %eax
+ movl %eax, -4(%edx,%ecx,4) C risk of cache bank clash here
+
+L(done):
+ popl %esi
+ popl %ebx
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/dive_1.asm b/gmp/mpn/x86/pentium/dive_1.asm
new file mode 100644
index 0000000000..f80632f479
--- /dev/null
+++ b/gmp/mpn/x86/pentium/dive_1.asm
@@ -0,0 +1,272 @@
+dnl Intel Pentium mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C divisor
+C odd even
+C P54: 24.5 30.5 cycles/limb
+C P55: 23.0 28.0
+
+
+C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+C Plain divl is used for small sizes, since the inverse takes a while to
+C setup. Multiplying works out faster for size>=3 when the divisor is odd,
+C or size>=4 when the divisor is even. Actually on P55 size==2 for odd or
+C size==3 for even are about the same speed for both divl or mul, but the
+C former is used since it will use up less code cache.
+C
+C The P55 speeds noted above, 23 cycles odd or 28 cycles even, are as
+C expected. On P54 in the even case the shrdl pairing nonsense (see
+C mpn/x86/pentium/README) costs 1 cycle, but it's not clear why there's a
+C further 1.5 slowdown for both odd and even.
+
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(VAR_INVERSE,`PARAM_DST')
+
+ TEXT
+
+ ALIGN(32)
+PROLOGUE(mpn_divexact_1)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %eax
+ movl PARAM_SIZE, %ecx
+
+ pushl %esi FRAME_pushl()
+ push %edi FRAME_pushl()
+
+ movl PARAM_SRC, %esi
+ andl $1, %eax
+
+ movl PARAM_DST, %edi
+ addl %ecx, %eax C size if even, size+1 if odd
+
+ cmpl $4, %eax
+ jae L(mul_by_inverse)
+
+
+ xorl %edx, %edx
+L(div_top):
+ movl -4(%esi,%ecx,4), %eax
+
+ divl PARAM_DIVISOR
+
+ movl %eax, -4(%edi,%ecx,4)
+ decl %ecx
+
+ jnz L(div_top)
+
+ popl %edi
+ popl %esi
+
+ ret
+
+
+
+L(mul_by_inverse):
+ movl PARAM_DIVISOR, %eax
+ movl $-1, %ecx
+
+L(strip_twos):
+ ASSERT(nz, `orl %eax, %eax')
+ shrl %eax
+ incl %ecx C shift count
+
+ jnc L(strip_twos)
+
+ leal 1(%eax,%eax), %edx C d
+ andl $127, %eax C d/2, 7 bits
+
+ pushl %ebx FRAME_pushl()
+ pushl %ebp FRAME_pushl()
+
+ifdef(`PIC',`
+ call L(here)
+L(here):
+ popl %ebp C eip
+
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebp
+ C AGI
+ movl binvert_limb_table@GOT(%ebp), %ebp
+ C AGI
+ movzbl (%eax,%ebp), %eax
+',`
+
+dnl non-PIC
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+
+ movl %eax, %ebp C inv
+ addl %eax, %eax C 2*inv
+
+ imull %ebp, %ebp C inv*inv
+
+ imull %edx, %ebp C inv*inv*d
+
+ subl %ebp, %eax C inv = 2*inv - inv*inv*d
+ movl PARAM_SIZE, %ebx
+
+ movl %eax, %ebp
+ addl %eax, %eax C 2*inv
+
+ imull %ebp, %ebp C inv*inv
+
+ imull %edx, %ebp C inv*inv*d
+
+ subl %ebp, %eax C inv = 2*inv - inv*inv*d
+ movl %edx, PARAM_DIVISOR C d without twos
+
+ leal (%esi,%ebx,4), %esi C src end
+ leal (%edi,%ebx,4), %edi C dst end
+
+ negl %ebx C -size
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ imull PARAM_DIVISOR, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ movl %eax, VAR_INVERSE
+ xorl %ebp, %ebp C initial carry bit
+
+ movl (%esi,%ebx,4), %eax C src low limb
+ orl %ecx, %ecx C shift
+
+ movl 4(%esi,%ebx,4), %edx C src second limb (for even)
+ jz L(odd_entry)
+
+ shrdl( %cl, %edx, %eax)
+
+ incl %ebx
+ jmp L(even_entry)
+
+
+ ALIGN(8)
+L(odd_top):
+ C eax scratch
+ C ebx counter, limbs, negative
+ C ecx
+ C edx
+ C esi src end
+ C edi dst end
+ C ebp carry bit, 0 or -1
+
+ mull PARAM_DIVISOR
+
+ movl (%esi,%ebx,4), %eax
+ subl %ebp, %edx
+
+ subl %edx, %eax
+
+ sbbl %ebp, %ebp
+
+L(odd_entry):
+ imull VAR_INVERSE, %eax
+
+ movl %eax, (%edi,%ebx,4)
+
+ incl %ebx
+ jnz L(odd_top)
+
+
+ popl %ebp
+ popl %ebx
+
+ popl %edi
+ popl %esi
+
+ ret
+
+
+L(even_top):
+ C eax scratch
+ C ebx counter, limbs, negative
+ C ecx twos
+ C edx
+ C esi src end
+ C edi dst end
+ C ebp carry bit, 0 or -1
+
+ mull PARAM_DIVISOR
+
+ subl %ebp, %edx C carry bit
+ movl -4(%esi,%ebx,4), %eax C src limb
+
+ movl (%esi,%ebx,4), %ebp C and one above it
+
+ shrdl( %cl, %ebp, %eax)
+
+ subl %edx, %eax C carry limb
+
+ sbbl %ebp, %ebp
+
+L(even_entry):
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi,%ebx,4)
+ incl %ebx
+
+ jnz L(even_top)
+
+
+
+ mull PARAM_DIVISOR
+
+ movl -4(%esi), %eax C src high limb
+ subl %ebp, %edx
+
+ shrl %cl, %eax
+
+ subl %edx, %eax C no carry if division is exact
+
+ imull VAR_INVERSE, %eax
+
+ movl %eax, -4(%edi) C dst high limb
+ nop C protect against cache bank clash
+
+ popl %ebp
+ popl %ebx
+
+ popl %edi
+ popl %esi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/gmp-mparam.h b/gmp/mpn/x86/pentium/gmp-mparam.h
new file mode 100644
index 0000000000..befa6e27a9
--- /dev/null
+++ b/gmp/mpn/x86/pentium/gmp-mparam.h
@@ -0,0 +1,76 @@
+/* Intel P54 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* For mpn/x86/pentium/mod_1.asm */
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+
+
+/* 166MHz P54 */
+
+/* Generated by tuneup.c, 2004-02-10, gcc 2.95 */
+
+#define MUL_TOOM22_THRESHOLD 16
+#define MUL_TOOM33_THRESHOLD 90
+
+#define SQR_BASECASE_THRESHOLD 0 /* always */
+#define SQR_TOOM2_THRESHOLD 22
+#define SQR_TOOM3_THRESHOLD 122
+
+#define DIV_SB_PREINV_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_DC_THRESHOLD 52
+#define POWM_THRESHOLD 77
+
+#define HGCD_THRESHOLD 121
+#define GCD_ACCEL_THRESHOLD 3
+#define GCD_DC_THRESHOLD 615
+#define JACOBI_BASE_METHOD 2
+
+#define USE_PREINV_DIVREM_1 0
+#define USE_PREINV_MOD_1 1 /* native */
+#define DIVREM_2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define MODEXACT_1_ODD_THRESHOLD 0 /* always (native) */
+
+#define GET_STR_DC_THRESHOLD 23
+#define GET_STR_PRECOMPUTE_THRESHOLD 33
+#define SET_STR_THRESHOLD 2788
+
+#define MUL_FFT_TABLE { 432, 928, 1664, 3584, 10240, 40960, 0 }
+#define MUL_FFT_MODF_THRESHOLD 448
+#define MUL_FFT_THRESHOLD 3328
+
+#define SQR_FFT_TABLE { 496, 928, 1920, 4608, 10240, 40960, 0 }
+#define SQR_FFT_MODF_THRESHOLD 512
+#define SQR_FFT_THRESHOLD 3328
diff --git a/gmp/mpn/x86/pentium/hamdist.asm b/gmp/mpn/x86/pentium/hamdist.asm
new file mode 100644
index 0000000000..2d7bc99b12
--- /dev/null
+++ b/gmp/mpn/x86/pentium/hamdist.asm
@@ -0,0 +1,143 @@
+dnl Intel P5 mpn_hamdist -- mpn hamming distance.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 14.0 cycles/limb
+
+
+C unsigned long mpn_hamdist (mp_srcptr src1, mp_srcptr src2, mp_size_t size);
+C
+C It might be possible to shave 1 cycle from the loop, and hence 2
+C cycles/limb. The xorb is taking 2 cycles, but a separate load and xor
+C would be 1, if the right schedule could be found (not found so far).
+C Wanting to avoid potential cache bank clashes makes it tricky.
+
+C The slightly strange quoting here helps the renaming done by tune/many.pl.
+deflit(TABLE_NAME,
+m4_assert_defined(`GSYM_PREFIX')
+GSYM_PREFIX`'mpn_popcount``'_table')
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC2, 8)
+defframe(PARAM_SRC1, 4)
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_hamdist)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ pushl %esi FRAME_pushl()
+
+ shll %ecx C size in byte pairs
+ pushl %edi FRAME_pushl()
+
+ifdef(`PIC',`
+ pushl %ebx FRAME_pushl()
+ pushl %ebp FRAME_pushl()
+
+ call L(here) FRAME_pushl()
+L(here):
+ movl PARAM_SRC1, %esi
+ popl %ebp FRAME_popl()
+
+ movl PARAM_SRC2, %edi
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebp
+
+ xorl %ebx, %ebx C byte
+ xorl %edx, %edx C byte
+
+ movl TABLE_NAME@GOT(%ebp), %ebp
+ xorl %eax, %eax C total
+define(TABLE,`(%ebp,$1)')
+
+',`
+dnl non-PIC
+ movl PARAM_SRC1, %esi
+ movl PARAM_SRC2, %edi
+
+ xorl %eax, %eax C total
+ pushl %ebx FRAME_pushl()
+
+ xorl %edx, %edx C byte
+ xorl %ebx, %ebx C byte
+
+define(TABLE,`TABLE_NAME($1)')
+')
+
+
+ C The nop after the xorb seems necessary. Although a movb might be
+ C expected to go down the V pipe in the second cycle of the xorb, it
+ C doesn't and costs an extra 2 cycles.
+L(top):
+ C eax total
+ C ebx byte
+ C ecx counter, 2*size to 2
+ C edx byte
+ C esi src1
+ C edi src2
+ C ebp [PIC] table
+
+ addl %ebx, %eax
+ movb -1(%esi,%ecx,2), %bl
+
+ addl %edx, %eax
+ movb -1(%edi,%ecx,2), %dl
+
+ xorb %dl, %bl
+ movb -2(%esi,%ecx,2), %dl
+
+ xorb -2(%edi,%ecx,2), %dl
+ nop
+
+ movb TABLE(%ebx), %bl
+ decl %ecx
+
+ movb TABLE(%edx), %dl
+ jnz L(top)
+
+
+ifdef(`PIC',`
+ popl %ebp
+')
+ addl %ebx, %eax
+ popl %ebx
+
+ addl %edx, %eax
+ popl %edi
+
+ popl %esi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/logops_n.asm b/gmp/mpn/x86/pentium/logops_n.asm
new file mode 100644
index 0000000000..18773172e9
--- /dev/null
+++ b/gmp/mpn/x86/pentium/logops_n.asm
@@ -0,0 +1,176 @@
+dnl Intel Pentium mpn_and_n,...,mpn_xnor_n -- bitwise logical operations.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 3.0 c/l and, ior, xor
+C 3.5 c/l andn, iorn, nand, nior, xnor
+
+
+define(M4_choose_op,
+`ifdef(`OPERATION_$1',`
+define(`M4_function', `mpn_$1')
+define(`M4_want_pre', `$4')
+define(`M4op', `$3')
+define(`M4_want_post',`$2')
+')')
+define(M4pre, `ifelse(M4_want_pre, yes,`$1')')
+define(M4post,`ifelse(M4_want_post,yes,`$1')')
+
+M4_choose_op( and_n, , andl, )
+M4_choose_op( andn_n, , andl, yes)
+M4_choose_op( nand_n, yes, andl, )
+M4_choose_op( ior_n, , orl, )
+M4_choose_op( iorn_n, , orl, yes)
+M4_choose_op( nior_n, yes, orl, )
+M4_choose_op( xor_n, , xorl, )
+M4_choose_op( xnor_n, yes, xorl, )
+
+ifdef(`M4_function',,
+`m4_error(`Unrecognised or undefined OPERATION symbol
+')')
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+NAILS_SUPPORT(0-31)
+
+
+C void M4_function (mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size);
+C
+C Nothing complicated here, just some care to avoid data cache bank clashes
+C and AGIs.
+C
+C We're one register short of being able to do a simple 4 loads, 2 ops, 2
+C stores. Instead %ebp is juggled a bit and nops are introduced to keep the
+C pairings as intended. An in-place operation would free up a register, for
+C an 0.5 c/l speedup, if that's worth bothering with.
+C
+C This code seems best for P55 too. Data alignment is a big problem for MMX
+C and the pairing restrictions on movq and integer instructions make life
+C difficult.
+
+defframe(PARAM_SIZE,16)
+defframe(PARAM_YP, 12)
+defframe(PARAM_XP, 8)
+defframe(PARAM_WP, 4)
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(M4_function)
+deflit(`FRAME',0)
+
+ pushl %ebx FRAME_pushl()
+ pushl %esi FRAME_pushl()
+
+ pushl %edi FRAME_pushl()
+ pushl %ebp FRAME_pushl()
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_XP, %ebx
+
+ movl PARAM_YP, %esi
+ movl PARAM_WP, %edi
+
+ shrl %ecx
+ jnc L(entry)
+
+ movl (%ebx,%ecx,8), %eax C risk of data cache bank clash here
+ movl (%esi,%ecx,8), %edx
+
+M4pre(` notl_or_xorl_GMP_NUMB_MASK(%edx)')
+
+ M4op %edx, %eax
+
+M4post(`xorl $GMP_NUMB_MASK, %eax')
+ orl %ecx, %ecx
+
+ movl %eax, (%edi,%ecx,8)
+ jz L(done)
+
+ jmp L(entry)
+
+
+L(top):
+ C eax
+ C ebx xp
+ C ecx counter, limb pairs, decrementing
+ C edx
+ C esi yp
+ C edi wp
+ C ebp
+
+ M4op %ebp, %edx
+ nop
+
+M4post(`xorl $GMP_NUMB_MASK, %eax')
+M4post(`xorl $GMP_NUMB_MASK, %edx')
+
+ movl %eax, 4(%edi,%ecx,8)
+ movl %edx, (%edi,%ecx,8)
+
+L(entry):
+ movl -4(%ebx,%ecx,8), %ebp
+ nop
+
+ movl -4(%esi,%ecx,8), %eax
+ movl -8(%esi,%ecx,8), %edx
+
+M4pre(` xorl $GMP_NUMB_MASK, %eax')
+M4pre(` xorl $GMP_NUMB_MASK, %edx')
+
+ M4op %ebp, %eax
+ movl -8(%ebx,%ecx,8), %ebp
+
+ decl %ecx
+ jnz L(top)
+
+
+ M4op %ebp, %edx
+ nop
+
+M4post(`xorl $GMP_NUMB_MASK, %eax')
+M4post(`xorl $GMP_NUMB_MASK, %edx')
+
+ movl %eax, 4(%edi,%ecx,8)
+ movl %edx, (%edi,%ecx,8)
+
+
+L(done):
+ popl %ebp
+ popl %edi
+
+ popl %esi
+ popl %ebx
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/lshift.asm b/gmp/mpn/x86/pentium/lshift.asm
new file mode 100644
index 0000000000..2a31f36c6e
--- /dev/null
+++ b/gmp/mpn/x86/pentium/lshift.asm
@@ -0,0 +1,243 @@
+dnl Intel Pentium mpn_lshift -- mpn left shift.
+
+dnl Copyright 1992, 1994-1996, 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5,P54: 6.0
+C P55: 5.375
+
+
+C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C The main shift-by-N loop should run at 5.375 c/l and that's what P55 does,
+C but P5 and P54 run only at 6.0 c/l, which is 4 cycles lost somewhere.
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_lshift)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+deflit(`FRAME',16)
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC,%esi
+ movl PARAM_SIZE,%ebp
+ movl PARAM_SHIFT,%ecx
+
+C We can use faster code for shift-by-1 under certain conditions.
+ cmp $1,%ecx
+ jne L(normal)
+ leal 4(%esi),%eax
+ cmpl %edi,%eax
+ jnc L(special) C jump if s_ptr + 1 >= res_ptr
+ leal (%esi,%ebp,4),%eax
+ cmpl %eax,%edi
+ jnc L(special) C jump if res_ptr >= s_ptr + size
+
+L(normal):
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+ xorl %eax,%eax
+ shldl( %cl, %edx, %eax) C compute carry limb
+ pushl %eax C push carry limb onto stack
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz L(end)
+
+ movl (%edi),%eax C fetch destination cache line
+
+ ALIGN(4)
+L(oop): movl -28(%edi),%eax C fetch destination cache line
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ shldl( %cl, %eax, %ebx)
+ shldl( %cl, %edx, %eax)
+ movl %ebx,(%edi)
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ shldl( %cl, %ebx, %edx)
+ shldl( %cl, %eax, %ebx)
+ movl %edx,-8(%edi)
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ shldl( %cl, %edx, %eax)
+ shldl( %cl, %ebx, %edx)
+ movl %eax,-16(%edi)
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ shldl( %cl, %eax, %ebx)
+ shldl( %cl, %edx, %eax)
+ movl %ebx,-24(%edi)
+ movl %eax,-28(%edi)
+
+ subl $32,%esi
+ subl $32,%edi
+ decl %ebp
+ jnz L(oop)
+
+L(end): popl %ebp
+ andl $7,%ebp
+ jz L(end2)
+L(oop2):
+ movl (%esi),%eax
+ shldl( %cl,%eax,%edx)
+ movl %edx,(%edi)
+ movl %eax,%edx
+ subl $4,%esi
+ subl $4,%edi
+ decl %ebp
+ jnz L(oop2)
+
+L(end2):
+ shll %cl,%edx C compute least significant limb
+ movl %edx,(%edi) C store it
+
+ popl %eax C pop carry limb
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
+C We loop from least significant end of the arrays, which is only
+C permissable if the source and destination don't overlap, since the
+C function is documented to work for overlapping source and destination.
+
+L(special):
+ movl (%esi),%edx
+ addl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ addl %edx,%edx
+ incl %ebp
+ decl %ebp
+ jz L(Lend)
+
+ movl (%edi),%eax C fetch destination cache line
+
+ ALIGN(4)
+L(Loop):
+ movl 28(%edi),%eax C fetch destination cache line
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,(%edi)
+ adcl %edx,%edx
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ adcl %ebx,%ebx
+ movl %edx,8(%edi)
+ adcl %eax,%eax
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ adcl %edx,%edx
+ movl %eax,16(%edi)
+ adcl %ebx,%ebx
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,24(%edi)
+ adcl %edx,%edx
+ movl %eax,28(%edi)
+
+ leal 32(%esi),%esi C use leal not to clobber carry
+ leal 32(%edi),%edi
+ decl %ebp
+ jnz L(Loop)
+
+L(Lend):
+ popl %ebp
+ sbbl %eax,%eax C save carry in %eax
+ andl $7,%ebp
+ jz L(Lend2)
+ addl %eax,%eax C restore carry from eax
+L(Loop2):
+ movl %edx,%ebx
+ movl (%esi),%edx
+ adcl %edx,%edx
+ movl %ebx,(%edi)
+
+ leal 4(%esi),%esi C use leal not to clobber carry
+ leal 4(%edi),%edi
+ decl %ebp
+ jnz L(Loop2)
+
+ jmp L(L1)
+L(Lend2):
+ addl %eax,%eax C restore carry from eax
+L(L1): movl %edx,(%edi) C store last limb
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/mmx/gmp-mparam.h b/gmp/mpn/x86/pentium/mmx/gmp-mparam.h
new file mode 100644
index 0000000000..02a0def127
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mmx/gmp-mparam.h
@@ -0,0 +1,163 @@
+/* Intel P55 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 1999-2002, 2004, 2009, 2010 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+
+/* For mpn/x86/pentium/mod_1.asm */
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+
+
+/* 233MHz P55 */
+
+#define MOD_1_NORM_THRESHOLD 5
+#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 12
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 11
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 63
+#define USE_PREINV_DIVREM_1 0
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 51
+
+#define MUL_TOOM22_THRESHOLD 16
+#define MUL_TOOM33_THRESHOLD 53
+#define MUL_TOOM44_THRESHOLD 128
+#define MUL_TOOM6H_THRESHOLD 189
+#define MUL_TOOM8H_THRESHOLD 260
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 89
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 91
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 90
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 88
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 20
+#define SQR_TOOM3_THRESHOLD 73
+#define SQR_TOOM4_THRESHOLD 178
+#define SQR_TOOM6_THRESHOLD 210
+#define SQR_TOOM8_THRESHOLD 375
+
+#define MULMOD_BNM1_THRESHOLD 11
+#define SQRMOD_BNM1_THRESHOLD 12
+
+#define MUL_FFT_MODF_THRESHOLD 364 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 364, 5}, { 15, 6}, { 8, 5}, { 17, 6}, \
+ { 9, 5}, { 19, 6}, { 17, 7}, { 9, 6}, \
+ { 21, 7}, { 11, 6}, { 23, 7}, { 15, 6}, \
+ { 31, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
+ { 15, 7}, { 33, 8}, { 19, 7}, { 39, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
+ { 47,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
+ { 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
+ { 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
+ { 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
+ { 79, 9}, { 159, 8}, { 319, 9}, { 167,10}, \
+ { 95, 9}, { 191, 8}, { 383,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 143, 9}, { 287,10}, \
+ { 159, 9}, { 319,11}, { 95,10}, { 191, 9}, \
+ { 383,12}, { 63,11}, { 127,10}, { 271, 9}, \
+ { 543,10}, { 287,11}, { 159,10}, { 351,11}, \
+ { 191,10}, { 415,11}, { 223,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 287,10}, { 575,11}, \
+ { 351,12}, { 191,11}, { 415,13}, { 127,12}, \
+ { 255,11}, { 575,12}, { 319,11}, { 703,12}, \
+ { 383,11}, { 831,12}, { 447,13}, { 8192,14}, \
+ { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 90
+#define MUL_FFT_THRESHOLD 3520
+
+#define SQR_FFT_MODF_THRESHOLD 340 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 340, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 17, 7}, { 9, 6}, { 21, 7}, { 11, 6}, \
+ { 23, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
+ { 11, 7}, { 29, 8}, { 15, 7}, { 33, 8}, \
+ { 19, 7}, { 39, 8}, { 27, 7}, { 55, 9}, \
+ { 15, 8}, { 31, 7}, { 65, 8}, { 43, 9}, \
+ { 23, 8}, { 47,10}, { 15, 9}, { 31, 8}, \
+ { 67, 9}, { 39, 8}, { 83, 9}, { 47, 8}, \
+ { 95,10}, { 31, 9}, { 63, 8}, { 127, 9}, \
+ { 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
+ { 63, 9}, { 127, 8}, { 255, 9}, { 135,10}, \
+ { 79, 9}, { 159, 8}, { 319,10}, { 95, 9}, \
+ { 191,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511, 9}, { 271,10}, { 143, 9}, { 287, 8}, \
+ { 575, 9}, { 303,10}, { 159, 9}, { 319,11}, \
+ { 95,10}, { 191, 9}, { 383,10}, { 207,12}, \
+ { 63,11}, { 127,10}, { 271, 9}, { 543,10}, \
+ { 287, 9}, { 575,10}, { 303,11}, { 159,10}, \
+ { 351,11}, { 191,10}, { 415,11}, { 223,10}, \
+ { 447,12}, { 127,11}, { 255,10}, { 543,11}, \
+ { 287,10}, { 607,11}, { 351,12}, { 191,11}, \
+ { 479,13}, { 127,12}, { 255,11}, { 575,12}, \
+ { 319,11}, { 703,12}, { 383,11}, { 767,12}, \
+ { 447,13}, { 8192,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 96
+#define SQR_FFT_THRESHOLD 5504
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 48
+#define MULLO_MUL_N_THRESHOLD 6633
+
+#define DC_DIV_QR_THRESHOLD 43
+#define DC_DIVAPPR_Q_THRESHOLD 170
+#define DC_BDIV_QR_THRESHOLD 43
+#define DC_BDIV_Q_THRESHOLD 110
+
+#define INV_MULMOD_BNM1_THRESHOLD 30
+#define INV_NEWTON_THRESHOLD 177
+#define INV_APPR_THRESHOLD 171
+
+#define BINV_NEWTON_THRESHOLD 194
+#define REDC_1_TO_REDC_N_THRESHOLD 50
+
+#define MU_DIV_QR_THRESHOLD 1142
+#define MU_DIVAPPR_Q_THRESHOLD 1142
+#define MUPI_DIV_QR_THRESHOLD 90
+#define MU_BDIV_QR_THRESHOLD 942
+#define MU_BDIV_Q_THRESHOLD 1017
+
+#define MATRIX22_STRASSEN_THRESHOLD 13
+#define HGCD_THRESHOLD 92
+#define GCD_DC_THRESHOLD 283
+#define GCDEXT_DC_THRESHOLD 221
+#define JACOBI_BASE_METHOD 2
+
+#define GET_STR_DC_THRESHOLD 18
+#define GET_STR_PRECOMPUTE_THRESHOLD 31
+#define SET_STR_DC_THRESHOLD 490
+#define SET_STR_PRECOMPUTE_THRESHOLD 994
diff --git a/gmp/mpn/x86/pentium/mmx/hamdist.asm b/gmp/mpn/x86/pentium/mmx/hamdist.asm
new file mode 100644
index 0000000000..72e3196697
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mmx/hamdist.asm
@@ -0,0 +1,40 @@
+dnl Intel P55 mpn_hamdist -- mpn hamming distance.
+
+dnl Copyright 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P55: hamdist 12.0 cycles/limb
+
+C For reference, this code runs at 11.5 cycles/limb for popcount, which is
+C slower than the plain integer mpn/x86/pentium/popcount.asm.
+
+MULFUNC_PROLOGUE(mpn_hamdist)
+include_mpn(`x86/k6/mmx/popham.asm')
diff --git a/gmp/mpn/x86/pentium/mmx/lshift.asm b/gmp/mpn/x86/pentium/mmx/lshift.asm
new file mode 100644
index 0000000000..04b0ddcc8f
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mmx/lshift.asm
@@ -0,0 +1,463 @@
+dnl Intel P5 mpn_lshift -- mpn left shift.
+
+dnl Copyright 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 1.75 cycles/limb.
+
+
+C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C Shift src,size left by shift many bits and store the result in dst,size.
+C Zeros are shifted in at the right. Return the bits shifted out at the
+C left.
+C
+C The comments in mpn_rshift apply here too.
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+dnl minimum 5, because the unrolled loop can't handle less
+deflit(UNROLL_THRESHOLD, 5)
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_lshift)
+
+ pushl %ebx
+ pushl %edi
+deflit(`FRAME',8)
+
+ movl PARAM_SIZE, %eax
+ movl PARAM_DST, %edx
+
+ movl PARAM_SRC, %ebx
+ movl PARAM_SHIFT, %ecx
+
+ cmp $UNROLL_THRESHOLD, %eax
+ jae L(unroll)
+
+ movl -4(%ebx,%eax,4), %edi C src high limb
+ decl %eax
+
+ jnz L(simple)
+
+ shldl( %cl, %edi, %eax) C eax was decremented to zero
+
+ shll %cl, %edi
+
+ movl %edi, (%edx) C dst low limb
+ popl %edi C risk of data cache bank clash
+
+ popl %ebx
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+L(simple):
+ C eax size-1
+ C ebx src
+ C ecx shift
+ C edx dst
+ C esi
+ C edi
+ C ebp
+deflit(`FRAME',8)
+
+ movd (%ebx,%eax,4), %mm5 C src high limb
+
+ movd %ecx, %mm6 C lshift
+ negl %ecx
+
+ psllq %mm6, %mm5
+ addl $32, %ecx
+
+ movd %ecx, %mm7
+ psrlq $32, %mm5 C retval
+
+
+L(simple_top):
+ C eax counter, limbs, negative
+ C ebx src
+ C ecx
+ C edx dst
+ C esi
+ C edi
+ C
+ C mm0 scratch
+ C mm5 return value
+ C mm6 shift
+ C mm7 32-shift
+
+ movq -4(%ebx,%eax,4), %mm0
+ decl %eax
+
+ psrlq %mm7, %mm0
+
+ C
+
+ movd %mm0, 4(%edx,%eax,4)
+ jnz L(simple_top)
+
+
+ movd (%ebx), %mm0
+
+ movd %mm5, %eax
+ psllq %mm6, %mm0
+
+ popl %edi
+ popl %ebx
+
+ movd %mm0, (%edx)
+
+ emms
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(8)
+L(unroll):
+ C eax size
+ C ebx src
+ C ecx shift
+ C edx dst
+ C esi
+ C edi
+ C ebp
+deflit(`FRAME',8)
+
+ movd -4(%ebx,%eax,4), %mm5 C src high limb
+ leal (%ebx,%eax,4), %edi
+
+ movd %ecx, %mm6 C lshift
+ andl $4, %edi
+
+ psllq %mm6, %mm5
+ jz L(start_src_aligned)
+
+
+ C src isn't aligned, process high limb separately (marked xxx) to
+ C make it so.
+ C
+ C source -8(ebx,%eax,4)
+ C |
+ C +-------+-------+-------+--
+ C | |
+ C +-------+-------+-------+--
+ C 0mod8 4mod8 0mod8
+ C
+ C dest
+ C -4(edx,%eax,4)
+ C |
+ C +-------+-------+--
+ C | xxx | |
+ C +-------+-------+--
+
+ movq -8(%ebx,%eax,4), %mm0 C unaligned load
+
+ psllq %mm6, %mm0
+ decl %eax
+
+ psrlq $32, %mm0
+
+ C
+
+ movd %mm0, (%edx,%eax,4)
+L(start_src_aligned):
+
+ movq -8(%ebx,%eax,4), %mm1 C src high qword
+ leal (%edx,%eax,4), %edi
+
+ andl $4, %edi
+ psrlq $32, %mm5 C return value
+
+ movq -16(%ebx,%eax,4), %mm3 C src second highest qword
+ jz L(start_dst_aligned)
+
+ C dst isn't aligned, subtract 4 to make it so, and pretend the shift
+ C is 32 bits extra. High limb of dst (marked xxx) handled here
+ C separately.
+ C
+ C source -8(ebx,%eax,4)
+ C |
+ C +-------+-------+--
+ C | mm1 |
+ C +-------+-------+--
+ C 0mod8 4mod8
+ C
+ C dest
+ C -4(edx,%eax,4)
+ C |
+ C +-------+-------+-------+--
+ C | xxx | |
+ C +-------+-------+-------+--
+ C 0mod8 4mod8 0mod8
+
+ movq %mm1, %mm0
+ addl $32, %ecx C new shift
+
+ psllq %mm6, %mm0
+
+ movd %ecx, %mm6
+ psrlq $32, %mm0
+
+ C wasted cycle here waiting for %mm0
+
+ movd %mm0, -4(%edx,%eax,4)
+ subl $4, %edx
+L(start_dst_aligned):
+
+
+ psllq %mm6, %mm1
+ negl %ecx C -shift
+
+ addl $64, %ecx C 64-shift
+ movq %mm3, %mm2
+
+ movd %ecx, %mm7
+ subl $8, %eax C size-8
+
+ psrlq %mm7, %mm3
+
+ por %mm1, %mm3 C mm3 ready to store
+ jc L(finish)
+
+
+ C The comments in mpn_rshift apply here too.
+
+ ALIGN(8)
+L(unroll_loop):
+ C eax counter, limbs
+ C ebx src
+ C ecx
+ C edx dst
+ C esi
+ C edi
+ C
+ C mm0
+ C mm1
+ C mm2 src qword from 16(%ebx,%eax,4)
+ C mm3 dst qword ready to store to 24(%edx,%eax,4)
+ C
+ C mm5 return value
+ C mm6 lshift
+ C mm7 rshift
+
+ movq 8(%ebx,%eax,4), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ movq %mm3, 24(%edx,%eax,4) C prev
+ por %mm2, %mm0
+
+ movq (%ebx,%eax,4), %mm3 C
+ psllq %mm6, %mm1 C
+
+ movq %mm0, 16(%edx,%eax,4)
+ movq %mm3, %mm2 C
+
+ psrlq %mm7, %mm3 C
+ subl $4, %eax
+
+ por %mm1, %mm3 C
+ jnc L(unroll_loop)
+
+
+
+L(finish):
+ C eax -4 to -1 representing respectively 0 to 3 limbs remaining
+
+ testb $2, %al
+
+ jz L(finish_no_two)
+
+ movq 8(%ebx,%eax,4), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ movq %mm3, 24(%edx,%eax,4) C prev
+ por %mm2, %mm0
+
+ movq %mm1, %mm2
+ movq %mm0, %mm3
+
+ subl $2, %eax
+L(finish_no_two):
+
+
+ C eax -4 or -3 representing respectively 0 or 1 limbs remaining
+ C
+ C mm2 src prev qword, from 16(%ebx,%eax,4)
+ C mm3 dst qword, for 24(%edx,%eax,4)
+
+ testb $1, %al
+ movd %mm5, %eax C retval
+
+ popl %edi
+ jz L(finish_zero)
+
+
+ C One extra src limb, destination was aligned.
+ C
+ C source ebx
+ C --+---------------+-------+
+ C | mm2 | |
+ C --+---------------+-------+
+ C
+ C dest edx+12 edx+4 edx
+ C --+---------------+---------------+-------+
+ C | mm3 | | |
+ C --+---------------+---------------+-------+
+ C
+ C mm6 = shift
+ C mm7 = ecx = 64-shift
+
+
+ C One extra src limb, destination was unaligned.
+ C
+ C source ebx
+ C --+---------------+-------+
+ C | mm2 | |
+ C --+---------------+-------+
+ C
+ C dest edx+12 edx+4
+ C --+---------------+---------------+
+ C | mm3 | |
+ C --+---------------+---------------+
+ C
+ C mm6 = shift+32
+ C mm7 = ecx = 64-(shift+32)
+
+
+ C In both cases there's one extra limb of src to fetch and combine
+ C with mm2 to make a qword at 4(%edx), and in the aligned case
+ C there's an extra limb of dst to be formed from that extra src limb
+ C left shifted.
+
+
+ movd (%ebx), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm3, 12(%edx)
+ psllq $32, %mm0
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ por %mm2, %mm0
+ psllq %mm6, %mm1
+
+ movq %mm0, 4(%edx)
+ psrlq $32, %mm1
+
+ andl $32, %ecx
+ popl %ebx
+
+ jz L(finish_one_unaligned)
+
+ movd %mm1, (%edx)
+L(finish_one_unaligned):
+
+ emms
+
+ ret
+
+
+L(finish_zero):
+
+ C No extra src limbs, destination was aligned.
+ C
+ C source ebx
+ C --+---------------+
+ C | mm2 |
+ C --+---------------+
+ C
+ C dest edx+8 edx
+ C --+---------------+---------------+
+ C | mm3 | |
+ C --+---------------+---------------+
+ C
+ C mm6 = shift
+ C mm7 = ecx = 64-shift
+
+
+ C No extra src limbs, destination was unaligned.
+ C
+ C source ebx
+ C --+---------------+
+ C | mm2 |
+ C --+---------------+
+ C
+ C dest edx+8 edx+4
+ C --+---------------+-------+
+ C | mm3 | |
+ C --+---------------+-------+
+ C
+ C mm6 = shift+32
+ C mm7 = ecx = 64-(shift+32)
+
+
+ C The movd for the unaligned case writes the same data to 4(%edx)
+ C that the movq does for the aligned case.
+
+
+ movq %mm3, 8(%edx)
+ andl $32, %ecx
+
+ psllq %mm6, %mm2
+ jz L(finish_zero_unaligned)
+
+ movq %mm2, (%edx)
+L(finish_zero_unaligned):
+
+ psrlq $32, %mm2
+ popl %ebx
+
+ movd %mm5, %eax C retval
+
+ movd %mm2, 4(%edx)
+
+ emms
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/mmx/mul_1.asm b/gmp/mpn/x86/pentium/mmx/mul_1.asm
new file mode 100644
index 0000000000..4ced577b13
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mmx/mul_1.asm
@@ -0,0 +1,371 @@
+dnl Intel Pentium MMX mpn_mul_1 -- mpn by limb multiplication.
+
+dnl Copyright 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5: 12.0 for 32-bit multiplier
+C 7.0 for 16-bit multiplier
+
+
+C mp_limb_t mpn_mul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t multiplier);
+C
+C When the multiplier is 16 bits some special case MMX code is used. Small
+C multipliers might arise reasonably often from mpz_mul_ui etc. If the size
+C is odd there's roughly a 5 cycle penalty, so times for say size==7 and
+C size==8 end up being quite close. If src isn't aligned to an 8 byte
+C boundary then one limb is processed separately with roughly a 5 cycle
+C penalty, so in that case it's say size==8 and size==9 which are close.
+C
+C Alternatives:
+C
+C MMX is not believed to be of any use for 32-bit multipliers, since for
+C instance the current method would just have to be more or less duplicated
+C for the high and low halves of the multiplier, and would probably
+C therefore run at about 14 cycles, which is slower than the plain integer
+C at 12.
+C
+C Adding the high and low MMX products using integer code seems best. An
+C attempt at using paddd and carry bit propagation with pcmpgtd didn't give
+C any joy. Perhaps something could be done keeping the values signed and
+C thereby avoiding adjustments to make pcmpgtd into an unsigned compare, or
+C perhaps not.
+C
+C Future:
+C
+C An mpn_mul_1c entrypoint would need a double carry out of the low result
+C limb in the 16-bit code, unless it could be assumed the carry fits in 16
+C bits, possibly as carry<multiplier, this being true of a big calculation
+C done piece by piece. But let's worry about that if/when mul_1c is
+C actually used.
+
+defframe(PARAM_MULTIPLIER,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+
+ ALIGN(8)
+PROLOGUE(mpn_mul_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %edx
+
+ cmpl $1, %ecx
+ jne L(two_or_more)
+
+ C one limb only
+
+ movl PARAM_MULTIPLIER, %eax
+ movl PARAM_DST, %ecx
+
+ mull (%edx)
+
+ movl %eax, (%ecx)
+ movl %edx, %eax
+
+ ret
+
+
+L(two_or_more):
+ C eax size
+ C ebx
+ C ecx carry
+ C edx
+ C esi src
+ C edi
+ C ebp
+
+ pushl %esi FRAME_pushl()
+ pushl %edi FRAME_pushl()
+
+ movl %edx, %esi C src
+ movl PARAM_DST, %edi
+
+ movl PARAM_MULTIPLIER, %eax
+ pushl %ebx FRAME_pushl()
+
+ leal (%esi,%ecx,4), %esi C src end
+ leal (%edi,%ecx,4), %edi C dst end
+
+ negl %ecx C -size
+
+ pushl %ebp FRAME_pushl()
+ cmpl $65536, %eax
+
+ jb L(small)
+
+
+L(big):
+ xorl %ebx, %ebx C carry limb
+ sarl %ecx C -size/2
+
+ jnc L(top) C with carry flag clear
+
+
+ C size was odd, process one limb separately
+
+ mull 4(%esi,%ecx,8) C m * src[0]
+
+ movl %eax, 4(%edi,%ecx,8)
+ incl %ecx
+
+ orl %edx, %ebx C carry limb, and clear carry flag
+
+
+L(top):
+ C eax
+ C ebx carry
+ C ecx counter, negative
+ C edx
+ C esi src end
+ C edi dst end
+ C ebp (scratch carry)
+
+ adcl $0, %ebx
+ movl (%esi,%ecx,8), %eax
+
+ mull PARAM_MULTIPLIER
+
+ movl %edx, %ebp
+ addl %eax, %ebx
+
+ adcl $0, %ebp
+ movl 4(%esi,%ecx,8), %eax
+
+ mull PARAM_MULTIPLIER
+
+ movl %ebx, (%edi,%ecx,8)
+ addl %ebp, %eax
+
+ movl %eax, 4(%edi,%ecx,8)
+ incl %ecx
+
+ movl %edx, %ebx
+ jnz L(top)
+
+
+ adcl $0, %ebx
+ popl %ebp
+
+ movl %ebx, %eax
+ popl %ebx
+
+ popl %edi
+ popl %esi
+
+ ret
+
+
+L(small):
+ C Special case for 16-bit multiplier.
+ C
+ C eax multiplier
+ C ebx
+ C ecx -size
+ C edx src
+ C esi src end
+ C edi dst end
+ C ebp multiplier
+
+ C size<3 not supported here. At size==3 we're already a couple of
+ C cycles faster, so there's no threshold as such, just use the MMX
+ C as soon as possible.
+
+ cmpl $-3, %ecx
+ ja L(big)
+
+ movd %eax, %mm7 C m
+ pxor %mm6, %mm6 C initial carry word
+
+ punpcklwd %mm7, %mm7 C m replicated 2 times
+ addl $2, %ecx C -size+2
+
+ punpckldq %mm7, %mm7 C m replicated 4 times
+ andl $4, %edx C test alignment, clear carry flag
+
+ movq %mm7, %mm0 C m
+ jz L(small_entry)
+
+
+ C Source is unaligned, process one limb separately.
+ C
+ C Plain integer code is used here, since it's smaller and is about
+ C the same 13 cycles as an mmx block would be.
+ C
+ C An "addl $1,%ecx" doesn't clear the carry flag when size==3, hence
+ C the use of separate incl and orl.
+
+ mull -8(%esi,%ecx,4) C m * src[0]
+
+ movl %eax, -8(%edi,%ecx,4) C dst[0]
+ incl %ecx C one limb processed
+
+ movd %edx, %mm6 C initial carry
+
+ orl %eax, %eax C clear carry flag
+ jmp L(small_entry)
+
+
+C The scheduling here is quite tricky, since so many instructions have
+C pairing restrictions. In particular the js won't pair with a movd, and
+C can't be paired with an adc since it wants flags from the inc, so
+C instructions are rotated to the top of the loop to find somewhere useful
+C for it.
+C
+C Trouble has been taken to avoid overlapping successive loop iterations,
+C since that would greatly increase the size of the startup and finishup
+C code. Actually there's probably not much advantage to be had from
+C overlapping anyway, since the difficulties are mostly with pairing, not
+C with latencies as such.
+C
+C In the comments x represents the src data and m the multiplier (16
+C bits, but replicated 4 times).
+C
+C The m signs calculated in %mm3 are a loop invariant and could be held in
+C say %mm5, but that would save only one instruction and hence be no faster.
+
+L(small_top):
+ C eax l.low, then l.high
+ C ebx (h.low)
+ C ecx counter, -size+2 to 0 or 1
+ C edx (h.high)
+ C esi &src[size]
+ C edi &dst[size]
+ C ebp
+ C
+ C %mm0 (high products)
+ C %mm1 (low products)
+ C %mm2 (adjust for m using x signs)
+ C %mm3 (adjust for x using m signs)
+ C %mm4
+ C %mm5
+ C %mm6 h.low, then carry
+ C %mm7 m replicated 4 times
+
+ movd %mm6, %ebx C h.low
+ psrlq $32, %mm1 C l.high
+
+ movd %mm0, %edx C h.high
+ movq %mm0, %mm6 C new c
+
+ adcl %eax, %ebx
+ incl %ecx
+
+ movd %mm1, %eax C l.high
+ movq %mm7, %mm0
+
+ adcl %eax, %edx
+ movl %ebx, -16(%edi,%ecx,4)
+
+ movl %edx, -12(%edi,%ecx,4)
+ psrlq $32, %mm6 C c
+
+L(small_entry):
+ pmulhw -8(%esi,%ecx,4), %mm0 C h = (x*m).high
+ movq %mm7, %mm1
+
+ pmullw -8(%esi,%ecx,4), %mm1 C l = (x*m).low
+ movq %mm7, %mm3
+
+ movq -8(%esi,%ecx,4), %mm2 C x
+ psraw $15, %mm3 C m signs
+
+ pand -8(%esi,%ecx,4), %mm3 C x selected by m signs
+ psraw $15, %mm2 C x signs
+
+ paddw %mm3, %mm0 C add x to h if m neg
+ pand %mm7, %mm2 C m selected by x signs
+
+ paddw %mm2, %mm0 C add m to h if x neg
+ incl %ecx
+
+ movd %mm1, %eax C l.low
+ punpcklwd %mm0, %mm6 C c + h.low << 16
+
+ psrlq $16, %mm0 C h.high
+ js L(small_top)
+
+
+
+
+ movd %mm6, %ebx C h.low
+ psrlq $32, %mm1 C l.high
+
+ adcl %eax, %ebx
+ popl %ebp FRAME_popl()
+
+ movd %mm0, %edx C h.high
+ psrlq $32, %mm0 C l.high
+
+ movd %mm1, %eax C l.high
+
+ adcl %eax, %edx
+ movl %ebx, -12(%edi,%ecx,4)
+
+ movd %mm0, %eax C c
+
+ adcl $0, %eax
+ movl %edx, -8(%edi,%ecx,4)
+
+ orl %ecx, %ecx
+ jnz L(small_done) C final %ecx==1 means even, ==0 odd
+
+
+ C Size odd, one extra limb to process.
+ C Plain integer code is used here, since it's smaller and is about
+ C the same speed as another mmx block would be.
+
+ movl %eax, %ecx
+ movl PARAM_MULTIPLIER, %eax
+
+ mull -4(%esi)
+
+ addl %ecx, %eax
+
+ adcl $0, %edx
+ movl %eax, -4(%edi)
+
+ movl %edx, %eax
+L(small_done):
+ popl %ebx
+
+ popl %edi
+ popl %esi
+
+ emms
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/mmx/rshift.asm b/gmp/mpn/x86/pentium/mmx/rshift.asm
new file mode 100644
index 0000000000..e3b274bb63
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mmx/rshift.asm
@@ -0,0 +1,468 @@
+dnl Intel P5 mpn_rshift -- mpn right shift.
+
+dnl Copyright 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 1.75 cycles/limb.
+
+
+C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C Shift src,size right by shift many bits and store the result in dst,size.
+C Zeros are shifted in at the left. Return the bits shifted out at the
+C right.
+C
+C It takes 6 mmx instructions to process 2 limbs, making 1.5 cycles/limb,
+C and with a 4 limb loop and 1 cycle of loop overhead the total is 1.75 c/l.
+C
+C Full speed depends on source and destination being aligned. Unaligned mmx
+C loads and stores on P5 don't pair and have a 2 cycle penalty. Some hairy
+C setups and finish-ups are done to ensure alignment for the loop.
+C
+C MMX shifts work out a bit faster even for the simple loop.
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+deflit(`FRAME',0)
+
+dnl Minimum 5, because the unrolled loop can't handle less.
+deflit(UNROLL_THRESHOLD, 5)
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_rshift)
+
+ pushl %ebx
+ pushl %edi
+deflit(`FRAME',8)
+
+ movl PARAM_SIZE, %eax
+ movl PARAM_DST, %edx
+
+ movl PARAM_SRC, %ebx
+ movl PARAM_SHIFT, %ecx
+
+ cmp $UNROLL_THRESHOLD, %eax
+ jae L(unroll)
+
+ decl %eax
+ movl (%ebx), %edi C src low limb
+
+ jnz L(simple)
+
+ shrdl( %cl, %edi, %eax) C eax was decremented to zero
+
+ shrl %cl, %edi
+
+ movl %edi, (%edx) C dst low limb
+ popl %edi C risk of data cache bank clash
+
+ popl %ebx
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(8)
+L(simple):
+ C eax size-1
+ C ebx src
+ C ecx shift
+ C edx dst
+ C esi
+ C edi
+ C ebp
+deflit(`FRAME',8)
+
+ movd (%ebx), %mm5 C src[0]
+ leal (%ebx,%eax,4), %ebx C &src[size-1]
+
+ movd %ecx, %mm6 C rshift
+ leal -4(%edx,%eax,4), %edx C &dst[size-2]
+
+ psllq $32, %mm5
+ negl %eax
+
+
+C This loop is 5 or 8 cycles, with every second load unaligned and a wasted
+C cycle waiting for the mm0 result to be ready. For comparison a shrdl is 4
+C cycles and would be 8 in a simple loop. Using mmx helps the return value
+C and last limb calculations too.
+
+L(simple_top):
+ C eax counter, limbs, negative
+ C ebx &src[size-1]
+ C ecx return value
+ C edx &dst[size-2]
+ C
+ C mm0 scratch
+ C mm5 return value
+ C mm6 shift
+
+ movq (%ebx,%eax,4), %mm0
+ incl %eax
+
+ psrlq %mm6, %mm0
+
+ movd %mm0, (%edx,%eax,4)
+ jnz L(simple_top)
+
+
+ movd (%ebx), %mm0
+ psrlq %mm6, %mm5 C return value
+
+ psrlq %mm6, %mm0
+ popl %edi
+
+ movd %mm5, %eax
+ popl %ebx
+
+ movd %mm0, 4(%edx)
+
+ emms
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(8)
+L(unroll):
+ C eax size
+ C ebx src
+ C ecx shift
+ C edx dst
+ C esi
+ C edi
+ C ebp
+deflit(`FRAME',8)
+
+ movd (%ebx), %mm5 C src[0]
+ movl $4, %edi
+
+ movd %ecx, %mm6 C rshift
+ testl %edi, %ebx
+
+ psllq $32, %mm5
+ jz L(start_src_aligned)
+
+
+ C src isn't aligned, process low limb separately (marked xxx) and
+ C step src and dst by one limb, making src aligned.
+ C
+ C source ebx
+ C --+-------+-------+-------+
+ C | xxx |
+ C --+-------+-------+-------+
+ C 4mod8 0mod8 4mod8
+ C
+ C dest edx
+ C --+-------+-------+
+ C | | xxx |
+ C --+-------+-------+
+
+ movq (%ebx), %mm0 C unaligned load
+
+ psrlq %mm6, %mm0
+ addl $4, %ebx
+
+ decl %eax
+
+ movd %mm0, (%edx)
+ addl $4, %edx
+L(start_src_aligned):
+
+
+ movq (%ebx), %mm1
+ testl %edi, %edx
+
+ psrlq %mm6, %mm5 C retval
+ jz L(start_dst_aligned)
+
+ C dst isn't aligned, add 4 to make it so, and pretend the shift is
+ C 32 bits extra. Low limb of dst (marked xxx) handled here
+ C separately.
+ C
+ C source ebx
+ C --+-------+-------+
+ C | mm1 |
+ C --+-------+-------+
+ C 4mod8 0mod8
+ C
+ C dest edx
+ C --+-------+-------+-------+
+ C | xxx |
+ C --+-------+-------+-------+
+ C 4mod8 0mod8 4mod8
+
+ movq %mm1, %mm0
+ addl $32, %ecx C new shift
+
+ psrlq %mm6, %mm0
+
+ movd %ecx, %mm6
+
+ movd %mm0, (%edx)
+ addl $4, %edx
+L(start_dst_aligned):
+
+
+ movq 8(%ebx), %mm3
+ negl %ecx
+
+ movq %mm3, %mm2 C mm2 src qword
+ addl $64, %ecx
+
+ movd %ecx, %mm7
+ psrlq %mm6, %mm1
+
+ leal -12(%ebx,%eax,4), %ebx
+ leal -20(%edx,%eax,4), %edx
+
+ psllq %mm7, %mm3
+ subl $7, %eax C size-7
+
+ por %mm1, %mm3 C mm3 ready to store
+ negl %eax C -(size-7)
+
+ jns L(finish)
+
+
+ C This loop is the important bit, the rest is just support. Careful
+ C instruction scheduling achieves the claimed 1.75 c/l. The
+ C relevant parts of the pairing rules are:
+ C
+ C - mmx loads and stores execute only in the U pipe
+ C - only one mmx shift in a pair
+ C - wait one cycle before storing an mmx register result
+ C - the usual address generation interlock
+ C
+ C Two qword calculations are slightly interleaved. The instructions
+ C marked "C" belong to the second qword, and the "C prev" one is for
+ C the second qword from the previous iteration.
+
+ ALIGN(8)
+L(unroll_loop):
+ C eax counter, limbs, negative
+ C ebx &src[size-12]
+ C ecx
+ C edx &dst[size-12]
+ C esi
+ C edi
+ C
+ C mm0
+ C mm1
+ C mm2 src qword from -8(%ebx,%eax,4)
+ C mm3 dst qword ready to store to -8(%edx,%eax,4)
+ C
+ C mm5 return value
+ C mm6 rshift
+ C mm7 lshift
+
+ movq (%ebx,%eax,4), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, -8(%edx,%eax,4) C prev
+ por %mm2, %mm0
+
+ movq 8(%ebx,%eax,4), %mm3 C
+ psrlq %mm6, %mm1 C
+
+ movq %mm0, (%edx,%eax,4)
+ movq %mm3, %mm2 C
+
+ psllq %mm7, %mm3 C
+ addl $4, %eax
+
+ por %mm1, %mm3 C
+ js L(unroll_loop)
+
+
+L(finish):
+ C eax 0 to 3 representing respectively 3 to 0 limbs remaining
+
+ testb $2, %al
+
+ jnz L(finish_no_two)
+
+ movq (%ebx,%eax,4), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, -8(%edx,%eax,4) C prev
+ por %mm2, %mm0
+
+ movq %mm1, %mm2
+ movq %mm0, %mm3
+
+ addl $2, %eax
+L(finish_no_two):
+
+
+ C eax 2 or 3 representing respectively 1 or 0 limbs remaining
+ C
+ C mm2 src prev qword, from -8(%ebx,%eax,4)
+ C mm3 dst qword, for -8(%edx,%eax,4)
+
+ testb $1, %al
+ popl %edi
+
+ movd %mm5, %eax C retval
+ jnz L(finish_zero)
+
+
+ C One extra limb, destination was aligned.
+ C
+ C source ebx
+ C +-------+---------------+--
+ C | | mm2 |
+ C +-------+---------------+--
+ C
+ C dest edx
+ C +-------+---------------+---------------+--
+ C | | | mm3 |
+ C +-------+---------------+---------------+--
+ C
+ C mm6 = shift
+ C mm7 = ecx = 64-shift
+
+
+ C One extra limb, destination was unaligned.
+ C
+ C source ebx
+ C +-------+---------------+--
+ C | | mm2 |
+ C +-------+---------------+--
+ C
+ C dest edx
+ C +---------------+---------------+--
+ C | | mm3 |
+ C +---------------+---------------+--
+ C
+ C mm6 = shift+32
+ C mm7 = ecx = 64-(shift+32)
+
+
+ C In both cases there's one extra limb of src to fetch and combine
+ C with mm2 to make a qword at 8(%edx), and in the aligned case
+ C there's a further extra limb of dst to be formed.
+
+
+ movd 8(%ebx), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, (%edx)
+ por %mm2, %mm0
+
+ psrlq %mm6, %mm1
+ andl $32, %ecx
+
+ popl %ebx
+ jz L(finish_one_unaligned)
+
+ C dst was aligned, must store one extra limb
+ movd %mm1, 16(%edx)
+L(finish_one_unaligned):
+
+ movq %mm0, 8(%edx)
+
+ emms
+
+ ret
+
+
+L(finish_zero):
+
+ C No extra limbs, destination was aligned.
+ C
+ C source ebx
+ C +---------------+--
+ C | mm2 |
+ C +---------------+--
+ C
+ C dest edx+4
+ C +---------------+---------------+--
+ C | | mm3 |
+ C +---------------+---------------+--
+ C
+ C mm6 = shift
+ C mm7 = ecx = 64-shift
+
+
+ C No extra limbs, destination was unaligned.
+ C
+ C source ebx
+ C +---------------+--
+ C | mm2 |
+ C +---------------+--
+ C
+ C dest edx+4
+ C +-------+---------------+--
+ C | | mm3 |
+ C +-------+---------------+--
+ C
+ C mm6 = shift+32
+ C mm7 = 64-(shift+32)
+
+
+ C The movd for the unaligned case is clearly the same data as the
+ C movq for the aligned case, it's just a choice between whether one
+ C or two limbs should be written.
+
+
+ movq %mm3, 4(%edx)
+ psrlq %mm6, %mm2
+
+ movd %mm2, 12(%edx)
+ andl $32, %ecx
+
+ popl %ebx
+ jz L(finish_zero_unaligned)
+
+ movq %mm2, 12(%edx)
+L(finish_zero_unaligned):
+
+ emms
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/mod_34lsub1.asm b/gmp/mpn/x86/pentium/mod_34lsub1.asm
new file mode 100644
index 0000000000..2d88223b84
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mod_34lsub1.asm
@@ -0,0 +1,192 @@
+dnl Intel P5 mpn_mod_34lsub1 -- mpn remainder modulo 2**24-1.
+
+dnl Copyright 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 1.66 cycles/limb
+
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr src, mp_size_t size)
+C
+
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_34lsub1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %edx
+
+ subl $2, %ecx
+ ja L(three_or_more)
+
+ movl (%edx), %eax
+ jne L(one)
+
+
+ movl 4(%edx), %ecx
+ movl %eax, %edx
+
+ shrl $24, %edx
+ andl $0xFFFFFF, %eax
+
+ addl %edx, %eax
+ movl %ecx, %edx
+
+ shrl $16, %ecx
+ andl $0xFFFF, %edx
+
+ shll $8, %edx
+ addl %ecx, %eax
+
+ addl %edx, %eax
+
+L(one):
+ ret
+
+
+L(three_or_more):
+ C eax
+ C ebx
+ C ecx size-2
+ C edx src
+ C esi
+ C edi
+ C ebp
+
+ pushl %ebx FRAME_pushl()
+ pushl %esi FRAME_pushl()
+
+ pushl %edi FRAME_pushl()
+ pushl %ebp FRAME_pushl()
+
+ xorl %esi, %esi C 0mod3
+ xorl %edi, %edi C 1mod3
+
+ xorl %ebp, %ebp C 2mod3, and clear carry
+
+L(top):
+ C eax scratch
+ C ebx scratch
+ C ecx counter, limbs
+ C edx src
+ C esi 0mod3
+ C edi 1mod3
+ C ebp 2mod3
+
+ movl (%edx), %eax
+ movl 4(%edx), %ebx
+
+ adcl %eax, %esi
+ movl 8(%edx), %eax
+
+ adcl %ebx, %edi
+ leal 12(%edx), %edx
+
+ adcl %eax, %ebp
+ leal -2(%ecx), %ecx
+
+ decl %ecx
+ jg L(top)
+
+
+ C ecx is -2, -1 or 0, representing 0, 1 or 2 more limbs, respectively
+
+ movl $0xFFFFFFFF, %ebx C mask
+ incl %ecx
+
+ js L(combine) C 0 more
+
+ movl (%edx), %eax
+ movl $0xFFFFFF00, %ebx
+
+ adcl %eax, %esi
+ decl %ecx
+
+ js L(combine) C 1 more
+
+ movl 4(%edx), %eax
+ movl $0xFFFF0000, %ebx
+
+ adcl %eax, %edi
+
+
+
+L(combine):
+ C eax
+ C ebx mask
+ C ecx
+ C edx
+ C esi 0mod3
+ C edi 1mod3
+ C ebp 2mod3
+
+ sbbl %ecx, %ecx C carry
+ movl %esi, %eax C 0mod3
+
+ andl %ebx, %ecx C masked for position
+ andl $0xFFFFFF, %eax C 0mod3 low
+
+ shrl $24, %esi C 0mod3 high
+ subl %ecx, %eax C apply carry
+
+ addl %esi, %eax C apply 0mod3
+ movl %edi, %ebx C 1mod3
+
+ shrl $16, %edi C 1mod3 high
+ andl $0x0000FFFF, %ebx
+
+ shll $8, %ebx C 1mod3 low
+ addl %edi, %eax C apply 1mod3 high
+
+ addl %ebx, %eax C apply 1mod3 low
+ movl %ebp, %ebx C 2mod3
+
+ shrl $8, %ebp C 2mod3 high
+ andl $0xFF, %ebx
+
+ shll $16, %ebx C 2mod3 low
+ addl %ebp, %eax C apply 2mod3 high
+
+ addl %ebx, %eax C apply 2mod3 low
+
+ popl %ebp
+ popl %edi
+
+ popl %esi
+ popl %ebx
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/mode1o.asm b/gmp/mpn/x86/pentium/mode1o.asm
new file mode 100644
index 0000000000..eb2790e1a0
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mode1o.asm
@@ -0,0 +1,266 @@
+dnl Intel Pentium mpn_modexact_1_odd -- exact division style remainder.
+
+dnl Copyright 2000-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 23.0 cycles/limb
+
+
+C mp_limb_t mpn_modexact_1_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C
+C There seems no way to pair up the two lone instructions in the main loop.
+C
+C The special case for size==1 saves about 20 cycles (non-PIC), making it
+C the same as mpn_mod_1, and in fact making modexact faster than mod_1 at
+C all sizes.
+C
+C Alternatives:
+C
+C Using mmx for the multiplies might be possible, with pmullw and pmulhw
+C having just 3 cycle latencies, but carry bit handling would probably be
+C complicated.
+
+defframe(PARAM_CARRY, 16)
+defframe(PARAM_DIVISOR,12)
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+dnl re-using parameter space
+define(VAR_INVERSE,`PARAM_SIZE')
+
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(mpn_modexact_1c_odd)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %eax
+ movl PARAM_CARRY, %edx
+
+ jmp L(start_1c)
+
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_modexact_1_odd)
+deflit(`FRAME',0)
+
+ movl PARAM_DIVISOR, %eax
+ xorl %edx, %edx C carry
+
+L(start_1c):
+
+ifdef(`PIC',`
+ call L(here) FRAME_pushl()
+L(here):
+
+ shrl %eax C d/2
+ movl (%esp), %ecx C eip
+
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ecx
+ movl %ebx, (%esp) C push ebx
+
+ andl $127, %eax
+ movl PARAM_SIZE, %ebx
+
+ movl binvert_limb_table@GOT(%ecx), %ecx
+ subl $2, %ebx
+
+ movb (%eax,%ecx), %cl C inv 8 bits
+ jc L(one_limb)
+
+',`
+dnl non-PIC
+ shrl %eax C d/2
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_SIZE, %ebx
+ andl $127, %eax
+
+ subl $2, %ebx
+ jc L(one_limb)
+
+ movb binvert_limb_table(%eax), %cl C inv 8 bits
+')
+
+ movl %ecx, %eax
+ addl %ecx, %ecx C 2*inv
+
+ imull %eax, %eax C inv*inv
+
+ imull PARAM_DIVISOR, %eax C inv*inv*d
+
+ subl %eax, %ecx C inv = 2*inv - inv*inv*d
+
+ movl %ecx, %eax
+ addl %ecx, %ecx C 2*inv
+
+ imull %eax, %eax C inv*inv
+
+ imull PARAM_DIVISOR, %eax C inv*inv*d
+
+ subl %eax, %ecx C inv = 2*inv - inv*inv*d
+ pushl %esi FRAME_pushl()
+
+ ASSERT(e,` C d*inv == 1 mod 2^GMP_LIMB_BITS
+ movl %ecx, %eax
+ imull PARAM_DIVISOR, %eax
+ cmpl $1, %eax')
+
+ movl PARAM_SRC, %esi
+ movl %ecx, VAR_INVERSE
+
+ movl (%esi), %eax C src[0]
+ leal 4(%esi,%ebx,4), %esi C &src[size-1]
+
+ xorl $-1, %ebx C -(size-1)
+ ASSERT(nz)
+ jmp L(entry)
+
+
+C The use of VAR_INVERSE means only a store is needed for that value, rather
+C than a push and pop of say %edi.
+
+ ALIGN(16)
+L(top):
+ C eax scratch, low product
+ C ebx counter, limbs, negative
+ C ecx carry bit
+ C edx scratch, high product
+ C esi &src[size-1]
+ C edi
+ C ebp
+
+ mull PARAM_DIVISOR C h:dummy = q*d
+
+ movl (%esi,%ebx,4), %eax C src[i]
+ subl %ecx, %edx C h -= -c
+
+L(entry):
+ subl %edx, %eax C s = src[i] - h
+
+ sbbl %ecx, %ecx C new -c (0 or -1)
+
+ imull VAR_INVERSE, %eax C q = s*i
+
+ incl %ebx
+ jnz L(top)
+
+
+ mull PARAM_DIVISOR
+
+ movl (%esi), %eax C src high
+ subl %ecx, %edx C h -= -c
+
+ cmpl PARAM_DIVISOR, %eax
+
+ jbe L(skip_last)
+deflit(FRAME_LAST,FRAME)
+
+
+ subl %edx, %eax C s = src[i] - h
+ popl %esi FRAME_popl()
+
+ sbbl %ecx, %ecx C c (0 or -1)
+ popl %ebx FRAME_popl()
+
+ imull VAR_INVERSE, %eax C q = s*i
+
+ mull PARAM_DIVISOR C h:dummy = q*d
+
+ movl %edx, %eax
+
+ subl %ecx, %eax
+
+ ret
+
+
+C When high<divisor can skip last step.
+
+L(skip_last):
+deflit(`FRAME',FRAME_LAST)
+ C eax src high
+ C ebx
+ C ecx
+ C edx r
+ C esi
+
+ subl %eax, %edx C r-s
+ popl %esi FRAME_popl()
+
+ sbbl %eax, %eax C -1 if underflow
+ movl PARAM_DIVISOR, %ebx
+
+ andl %ebx, %eax C divisor if underflow
+ popl %ebx FRAME_popl()
+
+ addl %edx, %eax C addback if underflow
+
+ ret
+
+
+C Special case for size==1 using a division for r = c-a mod d.
+C Could look for a-c<d and save a division sometimes, but that doesn't seem
+C worth bothering about.
+
+L(one_limb):
+deflit(`FRAME',4)
+ C eax
+ C ebx size-2 (==-1)
+ C ecx
+ C edx carry
+ C esi src end
+ C edi
+ C ebp
+
+ movl %edx, %eax
+ movl PARAM_SRC, %edx
+
+ movl PARAM_DIVISOR, %ecx
+ popl %ebx FRAME_popl()
+
+ subl (%edx), %eax C c-a
+
+ sbbl %edx, %edx
+ decl %ecx C d-1
+
+ andl %ecx, %edx C b*d+c-a if c<a, or c-a if c>=a
+
+ divl PARAM_DIVISOR
+
+ movl %edx, %eax
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/mul_1.asm b/gmp/mpn/x86/pentium/mul_1.asm
new file mode 100644
index 0000000000..a0858af2b4
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mul_1.asm
@@ -0,0 +1,177 @@
+dnl Intel Pentium mpn_mul_1 -- mpn by limb multiplication.
+
+dnl Copyright 1992, 1994, 1996, 1999, 2000, 2002 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 12.0 cycles/limb
+
+
+C mp_limb_t mpn_mul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t multiplier);
+C mp_limb_t mpn_mul_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t multiplier, mp_limb_t carry);
+C
+
+defframe(PARAM_CARRY, 20)
+defframe(PARAM_MULTIPLIER,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_mul_1c)
+deflit(`FRAME',0)
+
+ movl PARAM_CARRY, %ecx
+ pushl %esi FRAME_pushl()
+
+ jmp L(start_1c)
+
+EPILOGUE()
+
+
+ ALIGN(8)
+PROLOGUE(mpn_mul_1)
+deflit(`FRAME',0)
+
+ xorl %ecx, %ecx
+ pushl %esi FRAME_pushl()
+
+L(start_1c):
+ movl PARAM_SRC, %esi
+ movl PARAM_SIZE, %eax
+
+ shrl %eax
+ jnz L(two_or_more)
+
+
+ C one limb only
+
+ movl (%esi), %eax
+
+ mull PARAM_MULTIPLIER
+
+ addl %eax, %ecx
+ movl PARAM_DST, %eax
+
+ adcl $0, %edx
+ popl %esi
+
+ movl %ecx, (%eax)
+ movl %edx, %eax
+
+ ret
+
+
+L(two_or_more):
+ C eax size/2
+ C ebx
+ C ecx carry
+ C edx
+ C esi src
+ C edi
+ C ebp
+
+ pushl %edi FRAME_pushl()
+ pushl %ebx FRAME_pushl()
+
+ movl PARAM_DST, %edi
+ leal -1(%eax), %ebx C size/2-1
+
+ notl %ebx C -size, preserve carry
+
+ leal (%esi,%eax,8), %esi C src end
+ leal (%edi,%eax,8), %edi C dst end
+
+ pushl %ebp FRAME_pushl()
+ jnc L(top)
+
+
+ C size was odd, process one limb separately
+
+ movl (%esi,%ebx,8), %eax
+ addl $4, %esi
+
+ mull PARAM_MULTIPLIER
+
+ addl %ecx, %eax
+ movl %edx, %ecx
+
+ movl %eax, (%edi,%ebx,8)
+ leal 4(%edi), %edi
+
+
+L(top):
+ C eax
+ C ebx counter, negative
+ C ecx carry
+ C edx
+ C esi src end
+ C edi dst end
+ C ebp
+
+ adcl $0, %ecx
+ movl (%esi,%ebx,8), %eax
+
+ mull PARAM_MULTIPLIER
+
+ movl %edx, %ebp
+ addl %eax, %ecx
+
+ adcl $0, %ebp
+ movl 4(%esi,%ebx,8), %eax
+
+ mull PARAM_MULTIPLIER
+
+ movl %ecx, (%edi,%ebx,8)
+ addl %ebp, %eax
+
+ movl %eax, 4(%edi,%ebx,8)
+ incl %ebx
+
+ movl %edx, %ecx
+ jnz L(top)
+
+
+ adcl $0, %ecx
+ popl %ebp
+
+ movl %ecx, %eax
+ popl %ebx
+
+ popl %edi
+ popl %esi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/mul_2.asm b/gmp/mpn/x86/pentium/mul_2.asm
new file mode 100644
index 0000000000..4c7beb5df2
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mul_2.asm
@@ -0,0 +1,150 @@
+dnl Intel Pentium mpn_mul_2 -- mpn by 2-limb multiplication.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 24.0 cycles/limb
+
+
+C mp_limb_t mpn_mul_2 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_srcptr mult);
+C
+C At 24 c/l this is only 2 cycles faster than a separate mul_1 and addmul_1,
+C but has the advantage of making just one pass over the operands.
+C
+C There's not enough registers to use PARAM_MULT directly, so the multiplier
+C limbs are transferred to local variables on the stack.
+
+defframe(PARAM_MULT, 16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(VAR_MULT_LOW, `PARAM_SRC')
+define(VAR_MULT_HIGH,`PARAM_DST')
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_mul_2)
+deflit(`FRAME',0)
+
+ pushl %esi FRAME_pushl()
+ pushl %edi FRAME_pushl()
+
+ movl PARAM_SRC, %esi
+ movl PARAM_DST, %edi
+
+ movl PARAM_MULT, %eax
+ movl PARAM_SIZE, %ecx
+
+ movl 4(%eax), %edx C mult high
+ movl (%eax), %eax C mult low
+
+ movl %eax, VAR_MULT_LOW
+ movl %edx, VAR_MULT_HIGH
+
+ pushl %ebx FRAME_pushl()
+ pushl %ebp FRAME_pushl()
+
+ mull (%esi) C src[0] * mult[0]
+
+ movl %eax, %ebp C in case src==dst
+ movl (%esi), %eax C src[0]
+
+ movl %ebp, (%edi) C dst[0]
+ movl %edx, %ebx C initial low carry
+
+ xorl %ebp, %ebp C initial high carry
+ leal (%edi,%ecx,4), %edi C dst end
+
+ mull VAR_MULT_HIGH C src[0] * mult[1]
+
+ subl $2, %ecx C size-2
+ js L(done)
+
+ leal 8(%esi,%ecx,4), %esi C &src[size]
+ xorl $-1, %ecx C -(size-1)
+
+
+
+L(top):
+ C eax low prod
+ C ebx low carry
+ C ecx counter, negative
+ C edx high prod
+ C esi src end
+ C edi dst end
+ C ebp high carry (0 or -1)
+
+ andl $1, %ebp C 1 or 0
+ addl %eax, %ebx
+
+ adcl %edx, %ebp
+ ASSERT(nc)
+ movl (%esi,%ecx,4), %eax
+
+ mull VAR_MULT_LOW
+
+ addl %eax, %ebx C low carry
+ movl (%esi,%ecx,4), %eax
+
+ adcl %ebp, %edx C high carry
+ movl %ebx, (%edi,%ecx,4)
+
+ sbbl %ebp, %ebp C new high carry, -1 or 0
+ movl %edx, %ebx C new low carry
+
+ mull VAR_MULT_HIGH
+
+ incl %ecx
+ jnz L(top)
+
+
+L(done):
+ andl $1, %ebp C 1 or 0
+ addl %ebx, %eax
+
+ adcl %ebp, %edx
+ ASSERT(nc)
+ movl %eax, (%edi) C store carry low
+
+ movl %edx, %eax C return carry high
+
+ popl %ebp
+ popl %ebx
+
+ popl %edi
+ popl %esi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/mul_basecase.asm b/gmp/mpn/x86/pentium/mul_basecase.asm
new file mode 100644
index 0000000000..50e15d3567
--- /dev/null
+++ b/gmp/mpn/x86/pentium/mul_basecase.asm
@@ -0,0 +1,143 @@
+dnl Intel Pentium mpn_mul_basecase -- mpn by mpn multiplication.
+
+dnl Copyright 1996, 1998-2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 14.2 cycles/crossproduct (approx)
+
+
+C void mpn_mul_basecase (mp_ptr wp,
+C mp_srcptr xp, mp_size_t xsize,
+C mp_srcptr yp, mp_size_t ysize);
+
+defframe(PARAM_YSIZE, 20)
+defframe(PARAM_YP, 16)
+defframe(PARAM_XSIZE, 12)
+defframe(PARAM_XP, 8)
+defframe(PARAM_WP, 4)
+
+defframe(VAR_COUNTER, -4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_mul_basecase)
+
+ pushl %eax C dummy push for allocating stack slot
+ pushl %esi
+ pushl %ebp
+ pushl %edi
+deflit(`FRAME',16)
+
+ movl PARAM_XP,%esi
+ movl PARAM_WP,%edi
+ movl PARAM_YP,%ebp
+
+ movl (%esi),%eax C load xp[0]
+ mull (%ebp) C multiply by yp[0]
+ movl %eax,(%edi) C store to wp[0]
+ movl PARAM_XSIZE,%ecx C xsize
+ decl %ecx C If xsize = 1, ysize = 1 too
+ jz L(done)
+
+ movl PARAM_XSIZE,%eax
+ pushl %ebx
+FRAME_pushl()
+ movl %edx,%ebx
+ leal (%esi,%eax,4),%esi C make xp point at end
+ leal (%edi,%eax,4),%edi C offset wp by xsize
+ negl %ecx C negate j size/index for inner loop
+ xorl %eax,%eax C clear carry
+
+ ALIGN(8)
+L(oop1): adcl $0,%ebx
+ movl (%esi,%ecx,4),%eax C load next limb at xp[j]
+ mull (%ebp)
+ addl %ebx,%eax
+ movl %eax,(%edi,%ecx,4)
+ incl %ecx
+ movl %edx,%ebx
+ jnz L(oop1)
+
+ adcl $0,%ebx
+ movl PARAM_YSIZE,%eax
+ movl %ebx,(%edi) C most significant limb of product
+ addl $4,%edi C increment wp
+ decl %eax
+ jz L(skip)
+ movl %eax,VAR_COUNTER C set index i to ysize
+
+L(outer):
+ addl $4,%ebp C make ebp point to next y limb
+ movl PARAM_XSIZE,%ecx
+ negl %ecx
+ xorl %ebx,%ebx
+
+ C code at 0x61 here, close enough to aligned
+L(oop2):
+ adcl $0,%ebx
+ movl (%esi,%ecx,4),%eax
+ mull (%ebp)
+ addl %ebx,%eax
+ movl (%edi,%ecx,4),%ebx
+ adcl $0,%edx
+ addl %eax,%ebx
+ movl %ebx,(%edi,%ecx,4)
+ incl %ecx
+ movl %edx,%ebx
+ jnz L(oop2)
+
+ adcl $0,%ebx
+
+ movl %ebx,(%edi)
+ addl $4,%edi
+ movl VAR_COUNTER,%eax
+ decl %eax
+ movl %eax,VAR_COUNTER
+ jnz L(outer)
+
+L(skip):
+ popl %ebx
+ popl %edi
+ popl %ebp
+ popl %esi
+ addl $4,%esp
+ ret
+
+L(done):
+ movl %edx,4(%edi) C store to wp[1]
+ popl %edi
+ popl %ebp
+ popl %esi
+ popl %eax C dummy pop for deallocating stack slot
+ ret
+
+EPILOGUE()
+
diff --git a/gmp/mpn/x86/pentium/popcount.asm b/gmp/mpn/x86/pentium/popcount.asm
new file mode 100644
index 0000000000..b8d84ad2e2
--- /dev/null
+++ b/gmp/mpn/x86/pentium/popcount.asm
@@ -0,0 +1,134 @@
+dnl Intel P5 mpn_popcount -- mpn bit population count.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: 8.0 cycles/limb
+
+
+C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
+C
+C An arithmetic approach has been found to be slower than the table lookup,
+C due to needing too many instructions.
+
+C The slightly strange quoting here helps the renaming done by tune/many.pl.
+deflit(TABLE_NAME,
+m4_assert_defined(`GSYM_PREFIX')
+GSYM_PREFIX`'mpn_popcount``'_table')
+
+ RODATA
+ ALIGN(8)
+ GLOBL TABLE_NAME
+TABLE_NAME:
+forloop(i,0,255,
+` .byte m4_popcount(i)
+')
+
+defframe(PARAM_SIZE,8)
+defframe(PARAM_SRC, 4)
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_popcount)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ pushl %esi FRAME_pushl()
+
+ifdef(`PIC',`
+ pushl %ebx FRAME_pushl()
+ pushl %ebp FRAME_pushl()
+
+ call L(here)
+L(here):
+ popl %ebp
+ shll %ecx C size in byte pairs
+
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebp
+ movl PARAM_SRC, %esi
+
+ xorl %eax, %eax C total
+ xorl %ebx, %ebx C byte
+
+ movl TABLE_NAME@GOT(%ebp), %ebp
+ xorl %edx, %edx C byte
+define(TABLE,`(%ebp,$1)')
+',`
+dnl non-PIC
+ shll %ecx C size in byte pairs
+ movl PARAM_SRC, %esi
+
+ pushl %ebx FRAME_pushl()
+ xorl %eax, %eax C total
+
+ xorl %ebx, %ebx C byte
+ xorl %edx, %edx C byte
+
+define(TABLE,`TABLE_NAME`'($1)')
+')
+
+
+ ALIGN(8) C necessary on P55 for claimed speed
+L(top):
+ C eax total
+ C ebx byte
+ C ecx counter, 2*size to 2
+ C edx byte
+ C esi src
+ C edi
+ C ebp [PIC] table
+
+ addl %ebx, %eax
+ movb -1(%esi,%ecx,2), %bl
+
+ addl %edx, %eax
+ movb -2(%esi,%ecx,2), %dl
+
+ movb TABLE(%ebx), %bl
+ decl %ecx
+
+ movb TABLE(%edx), %dl
+ jnz L(top)
+
+
+ifdef(`PIC',`
+ popl %ebp
+')
+ addl %ebx, %eax
+ popl %ebx
+
+ addl %edx, %eax
+ popl %esi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/rshift.asm b/gmp/mpn/x86/pentium/rshift.asm
new file mode 100644
index 0000000000..2105c4c935
--- /dev/null
+++ b/gmp/mpn/x86/pentium/rshift.asm
@@ -0,0 +1,243 @@
+dnl Intel Pentium mpn_rshift -- mpn right shift.
+
+dnl Copyright 1992, 1994-1996, 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5,P54: 6.0
+C P55: 5.375
+
+
+C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+C
+C The main shift-by-N loop should run at 5.375 c/l and that's what P55 does,
+C but P5 and P54 run only at 6.0 c/l, which is 4 cycles lost somewhere.
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_rshift)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+deflit(`FRAME',16)
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC,%esi
+ movl PARAM_SIZE,%ebp
+ movl PARAM_SHIFT,%ecx
+
+C We can use faster code for shift-by-1 under certain conditions.
+ cmp $1,%ecx
+ jne L(normal)
+ leal 4(%edi),%eax
+ cmpl %esi,%eax
+ jnc L(special) C jump if res_ptr + 1 >= s_ptr
+ leal (%edi,%ebp,4),%eax
+ cmpl %eax,%esi
+ jnc L(special) C jump if s_ptr >= res_ptr + size
+
+L(normal):
+ movl (%esi),%edx
+ addl $4,%esi
+ xorl %eax,%eax
+ shrdl( %cl, %edx, %eax) C compute carry limb
+ pushl %eax C push carry limb onto stack
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz L(end)
+
+ movl (%edi),%eax C fetch destination cache line
+
+ ALIGN(4)
+L(oop): movl 28(%edi),%eax C fetch destination cache line
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ shrdl( %cl, %eax, %ebx)
+ shrdl( %cl, %edx, %eax)
+ movl %ebx,(%edi)
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ shrdl( %cl, %ebx, %edx)
+ shrdl( %cl, %eax, %ebx)
+ movl %edx,8(%edi)
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ shrdl( %cl, %edx, %eax)
+ shrdl( %cl, %ebx, %edx)
+ movl %eax,16(%edi)
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ shrdl( %cl, %eax, %ebx)
+ shrdl( %cl, %edx, %eax)
+ movl %ebx,24(%edi)
+ movl %eax,28(%edi)
+
+ addl $32,%esi
+ addl $32,%edi
+ decl %ebp
+ jnz L(oop)
+
+L(end): popl %ebp
+ andl $7,%ebp
+ jz L(end2)
+L(oop2):
+ movl (%esi),%eax
+ shrdl( %cl,%eax,%edx) C compute result limb
+ movl %edx,(%edi)
+ movl %eax,%edx
+ addl $4,%esi
+ addl $4,%edi
+ decl %ebp
+ jnz L(oop2)
+
+L(end2):
+ shrl %cl,%edx C compute most significant limb
+ movl %edx,(%edi) C store it
+
+ popl %eax C pop carry limb
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
+C We loop from least significant end of the arrays, which is only
+C permissable if the source and destination don't overlap, since the
+C function is documented to work for overlapping source and destination.
+
+L(special):
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ shrl %edx
+ incl %ebp
+ decl %ebp
+ jz L(Lend)
+
+ movl (%edi),%eax C fetch destination cache line
+
+ ALIGN(4)
+L(Loop):
+ movl -28(%edi),%eax C fetch destination cache line
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ rcrl %eax
+ movl %ebx,(%edi)
+ rcrl %edx
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ rcrl %ebx
+ movl %edx,-8(%edi)
+ rcrl %eax
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ rcrl %edx
+ movl %eax,-16(%edi)
+ rcrl %ebx
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ rcrl %eax
+ movl %ebx,-24(%edi)
+ rcrl %edx
+ movl %eax,-28(%edi)
+
+ leal -32(%esi),%esi C use leal not to clobber carry
+ leal -32(%edi),%edi
+ decl %ebp
+ jnz L(Loop)
+
+L(Lend):
+ popl %ebp
+ sbbl %eax,%eax C save carry in %eax
+ andl $7,%ebp
+ jz L(Lend2)
+ addl %eax,%eax C restore carry from eax
+L(Loop2):
+ movl %edx,%ebx
+ movl (%esi),%edx
+ rcrl %edx
+ movl %ebx,(%edi)
+
+ leal -4(%esi),%esi C use leal not to clobber carry
+ leal -4(%edi),%edi
+ decl %ebp
+ jnz L(Loop2)
+
+ jmp L(L1)
+L(Lend2):
+ addl %eax,%eax C restore carry from eax
+L(L1): movl %edx,(%edi) C store last limb
+
+ movl $0,%eax
+ rcrl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium/sqr_basecase.asm b/gmp/mpn/x86/pentium/sqr_basecase.asm
new file mode 100644
index 0000000000..b11d767da2
--- /dev/null
+++ b/gmp/mpn/x86/pentium/sqr_basecase.asm
@@ -0,0 +1,528 @@
+dnl Intel P5 mpn_sqr_basecase -- square an mpn number.
+
+dnl Copyright 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P5: approx 8 cycles per crossproduct, or 15.5 cycles per triangular
+C product at around 20x20 limbs.
+
+
+C void mpn_sqr_basecase (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C Calculate src,size squared, storing the result in dst,2*size.
+C
+C The algorithm is basically the same as mpn/generic/sqr_basecase.c, but a
+C lot of function call overheads are avoided, especially when the size is
+C small.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_sqr_basecase)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %edx
+ movl PARAM_SRC, %eax
+
+ cmpl $2, %edx
+ movl PARAM_DST, %ecx
+
+ je L(two_limbs)
+
+ movl (%eax), %eax
+ ja L(three_or_more)
+
+C -----------------------------------------------------------------------------
+C one limb only
+ C eax src
+ C ebx
+ C ecx dst
+ C edx
+
+ mull %eax
+
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+
+ ret
+
+C -----------------------------------------------------------------------------
+ ALIGN(8)
+L(two_limbs):
+ C eax src
+ C ebx
+ C ecx dst
+ C edx size
+
+ pushl %ebp
+ pushl %edi
+
+ pushl %esi
+ pushl %ebx
+
+ movl %eax, %ebx
+ movl (%eax), %eax
+
+ mull %eax C src[0]^2
+
+ movl %eax, (%ecx) C dst[0]
+ movl %edx, %esi C dst[1]
+
+ movl 4(%ebx), %eax
+
+ mull %eax C src[1]^2
+
+ movl %eax, %edi C dst[2]
+ movl %edx, %ebp C dst[3]
+
+ movl (%ebx), %eax
+
+ mull 4(%ebx) C src[0]*src[1]
+
+ addl %eax, %esi
+ popl %ebx
+
+ adcl %edx, %edi
+
+ adcl $0, %ebp
+ addl %esi, %eax
+
+ adcl %edi, %edx
+ movl %eax, 4(%ecx)
+
+ adcl $0, %ebp
+ popl %esi
+
+ movl %edx, 8(%ecx)
+ movl %ebp, 12(%ecx)
+
+ popl %edi
+ popl %ebp
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(8)
+L(three_or_more):
+ C eax src low limb
+ C ebx
+ C ecx dst
+ C edx size
+
+ cmpl $4, %edx
+ pushl %ebx
+deflit(`FRAME',4)
+
+ movl PARAM_SRC, %ebx
+ jae L(four_or_more)
+
+
+C -----------------------------------------------------------------------------
+C three limbs
+ C eax src low limb
+ C ebx src
+ C ecx dst
+ C edx size
+
+ pushl %ebp
+ pushl %edi
+
+ mull %eax C src[0] ^ 2
+
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+
+ movl 4(%ebx), %eax
+ xorl %ebp, %ebp
+
+ mull %eax C src[1] ^ 2
+
+ movl %eax, 8(%ecx)
+ movl %edx, 12(%ecx)
+
+ movl 8(%ebx), %eax
+ pushl %esi C risk of cache bank clash
+
+ mull %eax C src[2] ^ 2
+
+ movl %eax, 16(%ecx)
+ movl %edx, 20(%ecx)
+
+ movl (%ebx), %eax
+
+ mull 4(%ebx) C src[0] * src[1]
+
+ movl %eax, %esi
+ movl %edx, %edi
+
+ movl (%ebx), %eax
+
+ mull 8(%ebx) C src[0] * src[2]
+
+ addl %eax, %edi
+ movl %edx, %ebp
+
+ adcl $0, %ebp
+ movl 4(%ebx), %eax
+
+ mull 8(%ebx) C src[1] * src[2]
+
+ xorl %ebx, %ebx
+ addl %eax, %ebp
+
+ C eax
+ C ebx zero, will be dst[5]
+ C ecx dst
+ C edx dst[4]
+ C esi dst[1]
+ C edi dst[2]
+ C ebp dst[3]
+
+ adcl $0, %edx
+ addl %esi, %esi
+
+ adcl %edi, %edi
+
+ adcl %ebp, %ebp
+
+ adcl %edx, %edx
+ movl 4(%ecx), %eax
+
+ adcl $0, %ebx
+ addl %esi, %eax
+
+ movl %eax, 4(%ecx)
+ movl 8(%ecx), %eax
+
+ adcl %edi, %eax
+ movl 12(%ecx), %esi
+
+ adcl %ebp, %esi
+ movl 16(%ecx), %edi
+
+ movl %eax, 8(%ecx)
+ movl %esi, 12(%ecx)
+
+ adcl %edx, %edi
+ popl %esi
+
+ movl 20(%ecx), %eax
+ movl %edi, 16(%ecx)
+
+ popl %edi
+ popl %ebp
+
+ adcl %ebx, %eax C no carry out of this
+ popl %ebx
+
+ movl %eax, 20(%ecx)
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(8)
+L(four_or_more):
+ C eax src low limb
+ C ebx src
+ C ecx dst
+ C edx size
+ C esi
+ C edi
+ C ebp
+ C
+ C First multiply src[0]*src[1..size-1] and store at dst[1..size].
+
+deflit(`FRAME',4)
+
+ pushl %edi
+FRAME_pushl()
+ pushl %esi
+FRAME_pushl()
+
+ pushl %ebp
+FRAME_pushl()
+ leal (%ecx,%edx,4), %edi C dst end of this mul1
+
+ leal (%ebx,%edx,4), %esi C src end
+ movl %ebx, %ebp C src
+
+ negl %edx C -size
+ xorl %ebx, %ebx C clear carry limb and carry flag
+
+ leal 1(%edx), %ecx C -(size-1)
+
+L(mul1):
+ C eax scratch
+ C ebx carry
+ C ecx counter, negative
+ C edx scratch
+ C esi &src[size]
+ C edi &dst[size]
+ C ebp src
+
+ adcl $0, %ebx
+ movl (%esi,%ecx,4), %eax
+
+ mull (%ebp)
+
+ addl %eax, %ebx
+
+ movl %ebx, (%edi,%ecx,4)
+ incl %ecx
+
+ movl %edx, %ebx
+ jnz L(mul1)
+
+
+ C Add products src[n]*src[n+1..size-1] at dst[2*n-1...], for
+ C n=1..size-2.
+ C
+ C The last two products, which are the end corner of the product
+ C triangle, are handled separately to save looping overhead. These
+ C are src[size-3]*src[size-2,size-1] and src[size-2]*src[size-1].
+ C If size is 4 then it's only these that need to be done.
+ C
+ C In the outer loop %esi is a constant, and %edi just advances by 1
+ C limb each time. The size of the operation decreases by 1 limb
+ C each time.
+
+ C eax
+ C ebx carry (needing carry flag added)
+ C ecx
+ C edx
+ C esi &src[size]
+ C edi &dst[size]
+ C ebp
+
+ adcl $0, %ebx
+ movl PARAM_SIZE, %edx
+
+ movl %ebx, (%edi)
+ subl $4, %edx
+
+ negl %edx
+ jz L(corner)
+
+
+L(outer):
+ C ebx previous carry limb to store
+ C edx outer loop counter (negative)
+ C esi &src[size]
+ C edi dst, pointing at stored carry limb of previous loop
+
+ pushl %edx C new outer loop counter
+ leal -2(%edx), %ecx
+
+ movl %ebx, (%edi)
+ addl $4, %edi
+
+ addl $4, %ebp
+ xorl %ebx, %ebx C initial carry limb, clear carry flag
+
+L(inner):
+ C eax scratch
+ C ebx carry (needing carry flag added)
+ C ecx counter, negative
+ C edx scratch
+ C esi &src[size]
+ C edi dst end of this addmul
+ C ebp &src[j]
+
+ adcl $0, %ebx
+ movl (%esi,%ecx,4), %eax
+
+ mull (%ebp)
+
+ addl %ebx, %eax
+ movl (%edi,%ecx,4), %ebx
+
+ adcl $0, %edx
+ addl %eax, %ebx
+
+ movl %ebx, (%edi,%ecx,4)
+ incl %ecx
+
+ movl %edx, %ebx
+ jnz L(inner)
+
+
+ adcl $0, %ebx
+ popl %edx C outer loop counter
+
+ incl %edx
+ jnz L(outer)
+
+
+ movl %ebx, (%edi)
+
+L(corner):
+ C esi &src[size]
+ C edi &dst[2*size-4]
+
+ movl -8(%esi), %eax
+ movl -4(%edi), %ebx C risk of data cache bank clash here
+
+ mull -12(%esi) C src[size-2]*src[size-3]
+
+ addl %eax, %ebx
+ movl %edx, %ecx
+
+ adcl $0, %ecx
+ movl -4(%esi), %eax
+
+ mull -12(%esi) C src[size-1]*src[size-3]
+
+ addl %ecx, %eax
+ movl (%edi), %ecx
+
+ adcl $0, %edx
+ movl %ebx, -4(%edi)
+
+ addl %eax, %ecx
+ movl %edx, %ebx
+
+ adcl $0, %ebx
+ movl -4(%esi), %eax
+
+ mull -8(%esi) C src[size-1]*src[size-2]
+
+ movl %ecx, (%edi)
+ addl %eax, %ebx
+
+ adcl $0, %edx
+ movl PARAM_SIZE, %eax
+
+ negl %eax
+ movl %ebx, 4(%edi)
+
+ addl $1, %eax C -(size-1) and clear carry
+ movl %edx, 8(%edi)
+
+
+C -----------------------------------------------------------------------------
+C Left shift of dst[1..2*size-2], high bit shifted out becomes dst[2*size-1].
+
+L(lshift):
+ C eax counter, negative
+ C ebx next limb
+ C ecx
+ C edx
+ C esi
+ C edi &dst[2*size-4]
+ C ebp
+
+ movl 12(%edi,%eax,8), %ebx
+
+ rcll %ebx
+ movl 16(%edi,%eax,8), %ecx
+
+ rcll %ecx
+ movl %ebx, 12(%edi,%eax,8)
+
+ movl %ecx, 16(%edi,%eax,8)
+ incl %eax
+
+ jnz L(lshift)
+
+
+ adcl %eax, %eax C high bit out
+ movl PARAM_SRC, %esi
+
+ movl PARAM_SIZE, %ecx C risk of cache bank clash
+ movl %eax, 12(%edi) C dst most significant limb
+
+
+C -----------------------------------------------------------------------------
+C Now add in the squares on the diagonal, namely src[0]^2, src[1]^2, ...,
+C src[size-1]^2. dst[0] hasn't yet been set at all yet, and just gets the
+C low limb of src[0]^2.
+
+ movl (%esi), %eax C src[0]
+ leal (%esi,%ecx,4), %esi C src end
+
+ negl %ecx
+
+ mull %eax
+
+ movl %eax, 16(%edi,%ecx,8) C dst[0]
+ movl %edx, %ebx
+
+ addl $1, %ecx C size-1 and clear carry
+
+L(diag):
+ C eax scratch (low product)
+ C ebx carry limb
+ C ecx counter, negative
+ C edx scratch (high product)
+ C esi &src[size]
+ C edi &dst[2*size-4]
+ C ebp scratch (fetched dst limbs)
+
+ movl (%esi,%ecx,4), %eax
+ adcl $0, %ebx
+
+ mull %eax
+
+ movl 16-4(%edi,%ecx,8), %ebp
+
+ addl %ebp, %ebx
+ movl 16(%edi,%ecx,8), %ebp
+
+ adcl %eax, %ebp
+ movl %ebx, 16-4(%edi,%ecx,8)
+
+ movl %ebp, 16(%edi,%ecx,8)
+ incl %ecx
+
+ movl %edx, %ebx
+ jnz L(diag)
+
+
+ adcl $0, %edx
+ movl 16-4(%edi), %eax C dst most significant limb
+
+ addl %eax, %edx
+ popl %ebp
+
+ movl %edx, 16-4(%edi)
+ popl %esi C risk of cache bank clash
+
+ popl %edi
+ popl %ebx
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/README b/gmp/mpn/x86/pentium4/README
new file mode 100644
index 0000000000..90f752e5d5
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/README
@@ -0,0 +1,124 @@
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+ INTEL PENTIUM-4 MPN SUBROUTINES
+
+
+This directory contains mpn functions optimized for Intel Pentium-4.
+
+The mmx subdirectory has routines using MMX instructions, the sse2
+subdirectory has routines using SSE2 instructions. All P4s have these, the
+separate directories are just so configure can omit that code if the
+assembler doesn't support it.
+
+
+STATUS
+
+ cycles/limb
+
+ mpn_add_n/sub_n 4 normal, 6 in-place
+
+ mpn_mul_1 4 normal, 6 in-place
+ mpn_addmul_1 6
+ mpn_submul_1 7
+
+ mpn_mul_basecase 6 cycles/crossproduct (approx)
+
+ mpn_sqr_basecase 3.5 cycles/crossproduct (approx)
+ or 7.0 cycles/triangleproduct (approx)
+
+ mpn_l/rshift 1.75
+
+
+
+The shifts ought to be able to go at 1.5 c/l, but not much effort has been
+applied to them yet.
+
+In-place operations, and all addmul, submul, mul_basecase and sqr_basecase
+calls, suffer from pipeline anomalies associated with write combining and
+movd reads and writes to the same or nearby locations. The movq
+instructions do not trigger the same hardware problems. Unfortunately,
+using movq and splitting/combining seems to require too many extra
+instructions to help. Perhaps future chip steppings will be better.
+
+
+
+NOTES
+
+The Pentium-4 pipeline "Netburst", provides for quite a number of surprises.
+Many traditional x86 instructions run very slowly, requiring use of
+alterative instructions for acceptable performance.
+
+adcl and sbbl are quite slow at 8 cycles for reg->reg. paddq of 32-bits
+within a 64-bit mmx register seems better, though the combination
+paddq/psrlq when propagating a carry is still a 4 cycle latency.
+
+incl and decl should be avoided, instead use add $1 and sub $1. Apparently
+the carry flag is not separately renamed, so incl and decl depend on all
+previous flags-setting instructions.
+
+shll and shrl have a 4 cycle latency, or 8 times the latency of the fastest
+integer instructions (addl, subl, orl, andl, and some more). shldl and
+shrdl seem to have 13 and 15 cycles latency, respectively. Bizarre.
+
+movq mmx -> mmx does have 6 cycle latency, as noted in the documentation.
+pxor/por or similar combination at 2 cycles latency can be used instead.
+The movq however executes in the float unit, thereby saving MMX execution
+resources. With the right juggling, data moves shouldn't be on a dependent
+chain.
+
+L1 is write-through, but the write-combining sounds like it does enough to
+not require explicit destination prefetching.
+
+xmm registers so far haven't found a use, but not much effort has been
+expended. A configure test for whether the operating system knows
+fxsave/fxrestor will be needed if they're used.
+
+
+
+REFERENCES
+
+Intel Pentium-4 processor manuals,
+
+ http://developer.intel.com/design/pentium4/manuals
+
+"Intel Pentium 4 Processor Optimization Reference Manual", Intel, 2001,
+order number 248966. Available on-line:
+
+ http://developer.intel.com/design/pentium4/manuals/248966.htm
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/mpn/x86/pentium4/copyd.asm b/gmp/mpn/x86/pentium4/copyd.asm
new file mode 100644
index 0000000000..82af81c522
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/copyd.asm
@@ -0,0 +1,71 @@
+dnl Pentium-4 mpn_copyd -- copy limb vector, decrementing.
+
+dnl Copyright 1999-2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl The std/rep/movsl/cld is very slow for small blocks on pentium4. Its
+dnl startup time seems to be about 165 cycles. It then needs 2.6 c/l.
+dnl We therefore use an open-coded 2 c/l copying loop.
+
+dnl Ultimately, we may want to use 64-bit movq or 128-bit movdqu in some
+dnl nifty unrolled arrangement. Clearly, that could reach much higher
+dnl speeds, at least for large blocks.
+
+include(`../config.m4')
+
+
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_copyd)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+
+ movl PARAM_SRC, %eax
+ movl PARAM_DST, %edx
+ movl %ebx, PARAM_SIZE
+ addl $-1, %ecx
+ js L(end)
+
+L(loop):
+ movl (%eax,%ecx,4), %ebx
+ movl %ebx, (%edx,%ecx,4)
+ addl $-1, %ecx
+
+ jns L(loop)
+L(end):
+ movl PARAM_SIZE, %ebx
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/copyi.asm b/gmp/mpn/x86/pentium4/copyi.asm
new file mode 100644
index 0000000000..b6148879fa
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/copyi.asm
@@ -0,0 +1,93 @@
+dnl Pentium-4 mpn_copyi -- copy limb vector, incrementing.
+
+dnl Copyright 1999-2001 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl The rep/movsl is very slow for small blocks on pentium4. Its startup
+dnl time seems to be about 110 cycles. It then copies at a rate of one
+dnl limb per cycle. We therefore fall back to an open-coded 2 c/l copying
+dnl loop for smaller sizes.
+
+dnl Ultimately, we may want to use 64-bit movd or 128-bit movdqu in some
+dnl nifty unrolled arrangement. Clearly, that could reach much higher
+dnl speeds, at least for large blocks.
+
+include(`../config.m4')
+
+
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_copyi)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ cmpl $150, %ecx
+ jg L(replmovs)
+
+ movl PARAM_SRC, %eax
+ movl PARAM_DST, %edx
+ movl %ebx, PARAM_SIZE
+ testl %ecx, %ecx
+ jz L(end)
+
+L(loop):
+ movl (%eax), %ebx
+ leal 4(%eax), %eax
+ addl $-1, %ecx
+ movl %ebx, (%edx)
+ leal 4(%edx), %edx
+
+ jnz L(loop)
+
+L(end):
+ movl PARAM_SIZE, %ebx
+ ret
+
+L(replmovs):
+ cld C better safe than sorry, see mpn/x86/README
+
+ movl %esi, %eax
+ movl PARAM_SRC, %esi
+ movl %edi, %edx
+ movl PARAM_DST, %edi
+
+ rep
+ movsl
+
+ movl %eax, %esi
+ movl %edx, %edi
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/mmx/lshift.asm b/gmp/mpn/x86/pentium4/mmx/lshift.asm
new file mode 100644
index 0000000000..b5eca66698
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/mmx/lshift.asm
@@ -0,0 +1,39 @@
+dnl Intel Pentium-4 mpn_lshift -- left shift.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P4 Willamette, Northwood: 1.75 cycles/limb
+C P4 Prescott: 2.0 cycles/limb
+
+
+MULFUNC_PROLOGUE(mpn_lshift)
+include_mpn(`x86/pentium/mmx/lshift.asm')
diff --git a/gmp/mpn/x86/pentium4/mmx/popham.asm b/gmp/mpn/x86/pentium4/mmx/popham.asm
new file mode 100644
index 0000000000..9563cb57e4
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/mmx/popham.asm
@@ -0,0 +1,203 @@
+dnl Intel Pentium 4 mpn_popcount, mpn_hamdist -- population count and
+dnl hamming distance.
+
+dnl Copyright 2000-2002, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C popcount hamdist
+C P3 model 9 (Banias) ? ?
+C P3 model 13 (Dothan) 6 6
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood) 8 9
+C P4 model 3 (Prescott) 8 9
+C P4 model 4 (Nocona)
+
+C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
+C unsigned long mpn_hamdist (mp_srcptr src, mp_srcptr src2, mp_size_t size);
+C
+C Loading with unaligned movq's costs an extra 1 c/l and hence is avoided.
+C Two movd's and a punpckldq seems to be the same speed as an aligned movq,
+C and using them saves fiddling about with alignment testing on entry.
+C
+C For popcount there's 13 mmx instructions in the loop, so perhaps 6.5 c/l
+C might be possible, but 8 c/l relying on out-of-order execution is already
+C quite reasonable.
+
+ifdef(`OPERATION_popcount',,
+`ifdef(`OPERATION_hamdist',,
+`m4_error(`Need OPERATION_popcount or OPERATION_hamdist defined
+')')')
+
+define(HAM,
+m4_assert_numargs(1)
+`ifdef(`OPERATION_hamdist',`$1')')
+
+define(POP,
+m4_assert_numargs(1)
+`ifdef(`OPERATION_popcount',`$1')')
+
+HAM(`
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC2, 8)
+defframe(PARAM_SRC, 4)
+define(M4_function,mpn_hamdist)
+')
+POP(`
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+define(M4_function,mpn_popcount)
+')
+
+MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
+
+
+ifdef(`PIC',,`
+ dnl non-PIC
+ RODATA
+ ALIGN(8)
+L(rodata_AAAAAAAAAAAAAAAA):
+ .long 0xAAAAAAAA
+ .long 0xAAAAAAAA
+L(rodata_3333333333333333):
+ .long 0x33333333
+ .long 0x33333333
+L(rodata_0F0F0F0F0F0F0F0F):
+ .long 0x0F0F0F0F
+ .long 0x0F0F0F0F
+')
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(M4_function)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %eax
+
+ifdef(`PIC',`
+ movl $0xAAAAAAAA, %edx
+ movd %edx, %mm7
+ punpckldq %mm7, %mm7
+
+ movl $0x33333333, %edx
+ movd %edx, %mm6
+ punpckldq %mm6, %mm6
+
+ movl $0x0F0F0F0F, %edx
+ movd %edx, %mm5
+ punpckldq %mm5, %mm5
+
+HAM(` movl PARAM_SRC2, %edx')
+
+',`
+ dnl non-PIC
+HAM(` movl PARAM_SRC2, %edx')
+ movq L(rodata_AAAAAAAAAAAAAAAA), %mm7
+ movq L(rodata_3333333333333333), %mm6
+ movq L(rodata_0F0F0F0F0F0F0F0F), %mm5
+')
+
+ pxor %mm4, %mm4 C zero
+ pxor %mm0, %mm0 C total
+
+ subl $1, %ecx
+ ja L(top)
+
+L(last):
+ movd (%eax,%ecx,4), %mm1 C src high limb
+HAM(` movd (%edx,%ecx,4), %mm2
+ pxor %mm2, %mm1
+')
+ jmp L(loaded)
+
+
+L(top):
+ C eax src
+ C ebx
+ C ecx counter, size-1 to 2 or 1, inclusive
+ C edx [hamdist] src2
+ C
+ C mm0 total (low dword)
+ C mm1 (scratch)
+ C mm2 (scratch)
+ C mm3
+ C mm4 0x0000000000000000
+ C mm5 0x0F0F0F0F0F0F0F0F
+ C mm6 0x3333333333333333
+ C mm7 0xAAAAAAAAAAAAAAAA
+
+ movd (%eax), %mm1
+ movd 4(%eax), %mm2
+ punpckldq %mm2, %mm1
+ addl $8, %eax
+
+HAM(` movd (%edx), %mm2
+ movd 4(%edx), %mm3
+ punpckldq %mm3, %mm2
+ pxor %mm2, %mm1
+ addl $8, %edx
+')
+
+L(loaded):
+ movq %mm7, %mm2
+ pand %mm1, %mm2
+ psrlq $1, %mm2
+ psubd %mm2, %mm1 C bit pairs
+
+ movq %mm6, %mm2
+ pand %mm1, %mm2
+ psrlq $2, %mm1
+ pand %mm6, %mm1
+ paddd %mm2, %mm1 C nibbles
+
+ movq %mm5, %mm2
+ pand %mm1, %mm2
+ psrlq $4, %mm1
+ pand %mm5, %mm1
+ paddd %mm2, %mm1 C bytes
+
+ psadbw( %mm4, %mm1)
+ paddd %mm1, %mm0 C to total
+
+ subl $2, %ecx
+ jg L(top)
+
+ C ecx is 0 or -1 representing respectively 1 or 0 further limbs
+ jz L(last)
+
+
+ movd %mm0, %eax
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/mmx/rshift.asm b/gmp/mpn/x86/pentium4/mmx/rshift.asm
new file mode 100644
index 0000000000..3ac0094a5a
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/mmx/rshift.asm
@@ -0,0 +1,39 @@
+dnl Intel Pentium-4 mpn_rshift -- right shift.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P4 Willamette, Northwood: 1.75 cycles/limb
+C P4 Prescott: 2.0 cycles/limb
+
+
+MULFUNC_PROLOGUE(mpn_rshift)
+include_mpn(`x86/pentium/mmx/rshift.asm')
diff --git a/gmp/mpn/x86/pentium4/sse2/add_n.asm b/gmp/mpn/x86/pentium4/sse2/add_n.asm
new file mode 100644
index 0000000000..8e2380e493
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/add_n.asm
@@ -0,0 +1,101 @@
+dnl Intel Pentium-4 mpn_add_n -- mpn addition.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C dst!=src1,2 dst==src1 dst==src2
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) ?
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) 4 6 6
+C P4 model 3-4 (Prescott) 4.25 7.5 7.5
+
+defframe(PARAM_CARRY,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC2, 12)
+defframe(PARAM_SRC1, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX,`PARAM_SRC1')
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_add_nc)
+deflit(`FRAME',0)
+ movd PARAM_CARRY, %mm0
+ jmp L(start_nc)
+EPILOGUE()
+
+ ALIGN(8)
+PROLOGUE(mpn_add_n)
+deflit(`FRAME',0)
+ pxor %mm0, %mm0
+L(start_nc):
+ mov PARAM_SRC1, %eax
+ mov %ebx, SAVE_EBX
+ mov PARAM_SRC2, %ebx
+ mov PARAM_DST, %edx
+ mov PARAM_SIZE, %ecx
+
+ lea (%eax,%ecx,4), %eax C src1 end
+ lea (%ebx,%ecx,4), %ebx C src2 end
+ lea (%edx,%ecx,4), %edx C dst end
+ neg %ecx C -size
+
+L(top):
+ C eax src1 end
+ C ebx src2 end
+ C ecx counter, limbs, negative
+ C edx dst end
+ C mm0 carry bit
+
+ movd (%eax,%ecx,4), %mm1
+ movd (%ebx,%ecx,4), %mm2
+ paddq %mm2, %mm1
+
+ paddq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $32, %mm0
+
+ add $1, %ecx
+ jnz L(top)
+
+ movd %mm0, %eax
+ mov SAVE_EBX, %ebx
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/addlsh1_n.asm b/gmp/mpn/x86/pentium4/sse2/addlsh1_n.asm
new file mode 100644
index 0000000000..93b63b2018
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/addlsh1_n.asm
@@ -0,0 +1,108 @@
+dnl Intel Pentium-4 mpn_addlsh1_n -- mpn x+2*y.
+
+dnl Copyright 2001-2004, 2006 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C dst!=src1,2 dst==src1 dst==src2
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) ?
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) 4.25 6 6
+C P4 model 3-4 (Prescott) 5 8.5 8.5
+
+C The slightly strange combination of indexing and pointer incrementing
+C that's used seems to work best. Not sure why, but %ecx,4 with src1 and/or
+C src2 is a slowdown.
+C
+C The dependent chain is simply the paddq of x+2*y to the previous carry,
+C then psrlq to get the new carry. That makes 4 c/l the target speed, which
+C is almost achieved for separate src/dst but when src==dst the write
+C combining anomalies slow it down.
+
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC2, 12)
+defframe(PARAM_SRC1, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX,`PARAM_SRC1')
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_addlsh1_n)
+deflit(`FRAME',0)
+
+ mov PARAM_SRC1, %eax
+ mov %ebx, SAVE_EBX
+
+ mov PARAM_SRC2, %ebx
+ pxor %mm0, %mm0 C initial carry
+
+ mov PARAM_DST, %edx
+
+ mov PARAM_SIZE, %ecx
+
+ lea (%edx,%ecx,4), %edx C dst end
+ neg %ecx C -size
+
+L(top):
+ C eax src1 end
+ C ebx src2 end
+ C ecx counter, limbs, negative
+ C edx dst end
+ C mm0 carry
+
+ movd (%ebx), %mm2
+ movd (%eax), %mm1
+ psrlq $32, %mm0
+ lea 4(%eax), %eax
+ lea 4(%ebx), %ebx
+
+ psllq $1, %mm2
+ paddq %mm2, %mm1
+
+ paddq %mm1, %mm0
+
+ movd %mm0, (%edx,%ecx,4)
+ add $1, %ecx
+ jnz L(top)
+
+
+ psrlq $32, %mm0
+ mov SAVE_EBX, %ebx
+ movd %mm0, %eax
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/addmul_1.asm b/gmp/mpn/x86/pentium4/sse2/addmul_1.asm
new file mode 100644
index 0000000000..78102072bf
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/addmul_1.asm
@@ -0,0 +1,189 @@
+dnl mpn_addmul_1 for Pentium 4 and P6 models with SSE2 (i.e., 9,D,E,F).
+
+dnl Copyright 2005, 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C cycles/limb
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) 5.24
+C P6 model 13 (Dothan) 5.24
+C P4 model 0-1 (Willamette) 5
+C P4 model 2 (Northwood) 5
+C P4 model 3-4 (Prescott) 5
+
+C TODO:
+C * Tweak eax/edx offsets in loop as to save some lea's
+C * Perhaps software pipeline small-case code
+
+C INPUT PARAMETERS
+C rp sp + 4
+C up sp + 8
+C n sp + 12
+C v0 sp + 16
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_addmul_1)
+ pxor %mm6, %mm6
+L(ent): mov 4(%esp), %edx
+ mov 8(%esp), %eax
+ mov 12(%esp), %ecx
+ movd 16(%esp), %mm7
+ cmp $4, %ecx
+ jnc L(big)
+
+L(lp0): movd (%eax), %mm0
+ lea 4(%eax), %eax
+ movd (%edx), %mm4
+ lea 4(%edx), %edx
+ pmuludq %mm7, %mm0
+ paddq %mm0, %mm4
+ paddq %mm4, %mm6
+ movd %mm6, -4(%edx)
+ psrlq $32, %mm6
+ dec %ecx
+ jnz L(lp0)
+ movd %mm6, %eax
+ emms
+ ret
+
+L(big): and $3, %ecx
+ je L(0)
+ cmp $2, %ecx
+ jc L(1)
+ je L(2)
+ jmp L(3) C FIXME: one case should fall through
+
+L(0): movd (%eax), %mm3
+ sub 12(%esp), %ecx C loop count
+ lea -16(%eax), %eax
+ lea -12(%edx), %edx
+ pmuludq %mm7, %mm3
+ movd 20(%eax), %mm0
+ movd 12(%edx), %mm5
+ pmuludq %mm7, %mm0
+ movd 24(%eax), %mm1
+ paddq %mm3, %mm5
+ movd 16(%edx), %mm4
+ jmp L(00)
+
+L(1): movd (%eax), %mm2
+ sub 12(%esp), %ecx
+ lea -12(%eax), %eax
+ lea -8(%edx), %edx
+ movd 8(%edx), %mm4
+ pmuludq %mm7, %mm2
+ movd 16(%eax), %mm3
+ pmuludq %mm7, %mm3
+ movd 20(%eax), %mm0
+ paddq %mm2, %mm4
+ movd 12(%edx), %mm5
+ jmp L(01)
+
+L(2): movd (%eax), %mm1
+ sub 12(%esp), %ecx
+ lea -8(%eax), %eax
+ lea -4(%edx), %edx
+ pmuludq %mm7, %mm1
+ movd 12(%eax), %mm2
+ movd 4(%edx), %mm5
+ pmuludq %mm7, %mm2
+ movd 16(%eax), %mm3
+ paddq %mm1, %mm5
+ movd 8(%edx), %mm4
+ jmp L(10)
+
+L(3): movd (%eax), %mm0
+ sub 12(%esp), %ecx
+ lea -4(%eax), %eax
+ pmuludq %mm7, %mm0
+ movd 8(%eax), %mm1
+ movd (%edx), %mm4
+ pmuludq %mm7, %mm1
+ movd 12(%eax), %mm2
+ paddq %mm0, %mm4
+ movd 4(%edx), %mm5
+
+ ALIGN(16)
+L(top): pmuludq %mm7, %mm2
+ paddq %mm4, %mm6
+ movd 16(%eax), %mm3
+ paddq %mm1, %mm5
+ movd 8(%edx), %mm4
+ movd %mm6, 0(%edx)
+ psrlq $32, %mm6
+L(10): pmuludq %mm7, %mm3
+ paddq %mm5, %mm6
+ movd 20(%eax), %mm0
+ paddq %mm2, %mm4
+ movd 12(%edx), %mm5
+ movd %mm6, 4(%edx)
+ psrlq $32, %mm6
+L(01): pmuludq %mm7, %mm0
+ paddq %mm4, %mm6
+ movd 24(%eax), %mm1
+ paddq %mm3, %mm5
+ movd 16(%edx), %mm4
+ movd %mm6, 8(%edx)
+ psrlq $32, %mm6
+L(00): pmuludq %mm7, %mm1
+ paddq %mm5, %mm6
+ movd 28(%eax), %mm2
+ paddq %mm0, %mm4
+ movd 20(%edx), %mm5
+ movd %mm6, 12(%edx)
+ psrlq $32, %mm6
+ lea 16(%eax), %eax
+ lea 16(%edx), %edx
+ add $4, %ecx
+ jnz L(top)
+
+L(end): pmuludq %mm7, %mm2
+ paddq %mm4, %mm6
+ paddq %mm1, %mm5
+ movd 8(%edx), %mm4
+ movd %mm6, 0(%edx)
+ psrlq $32, %mm6
+ paddq %mm5, %mm6
+ paddq %mm2, %mm4
+ movd %mm6, 4(%edx)
+ psrlq $32, %mm6
+ paddq %mm4, %mm6
+ movd %mm6, 8(%edx)
+ psrlq $32, %mm6
+ movd %mm6, %eax
+ emms
+ ret
+EPILOGUE()
+PROLOGUE(mpn_addmul_1c)
+ movd 20(%esp), %mm6
+ jmp L(ent)
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/bdiv_dbm1c.asm b/gmp/mpn/x86/pentium4/sse2/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..354300e4de
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/bdiv_dbm1c.asm
@@ -0,0 +1,141 @@
+dnl Intel Atom mpn_bdiv_dbm1.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C cycles/limb
+C P5 -
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) 9.75
+C P6 model 13 (Dothan)
+C P4 model 0 (Willamette)
+C P4 model 1 (?)
+C P4 model 2 (Northwood) 8.25
+C P4 model 3 (Prescott)
+C P4 model 4 (Nocona)
+C Intel Atom 8
+C AMD K6 -
+C AMD K7 -
+C AMD K8
+C AMD K10
+
+C TODO: This code was optimised for atom-32, consider moving it back to atom
+C dir(atom currently grabs this code), and write a 4-way version(7c/l).
+
+defframe(PARAM_CARRY,20)
+defframe(PARAM_MUL, 16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_RP,`PARAM_MUL')
+define(SAVE_UP,`PARAM_SIZE')
+
+define(`rp', `%edi')
+define(`up', `%esi')
+define(`n', `%ecx')
+define(`reg', `%edx')
+define(`cy', `%eax') C contains the return value
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+deflit(`FRAME',0)
+
+PROLOGUE(mpn_bdiv_dbm1c)
+ mov PARAM_SIZE, n C size
+ mov up, SAVE_UP
+ mov PARAM_SRC, up
+ movd PARAM_MUL, %mm7
+ mov rp, SAVE_RP
+ mov PARAM_DST, rp
+
+ movd (up), %mm0
+ pmuludq %mm7, %mm0
+ shr n
+ mov PARAM_CARRY, cy
+ jz L(eq1)
+
+ movd 4(up), %mm1
+ jc L(odd)
+
+ lea 4(up), up
+ pmuludq %mm7, %mm1
+ movd %mm0, reg
+ psrlq $32, %mm0
+ sub reg, cy
+ movd %mm0, reg
+ movq %mm1, %mm0
+ dec n
+ mov cy, (rp)
+ lea 4(rp), rp
+ jz L(end)
+
+C ALIGN(16)
+L(top): movd 4(up), %mm1
+ sbb reg, cy
+L(odd): movd %mm0, reg
+ psrlq $32, %mm0
+ pmuludq %mm7, %mm1
+ sub reg, cy
+ lea 8(up), up
+ movd %mm0, reg
+ movd (up), %mm0
+ mov cy, (rp)
+ sbb reg, cy
+ movd %mm1, reg
+ psrlq $32, %mm1
+ sub reg, cy
+ movd %mm1, reg
+ pmuludq %mm7, %mm0
+ dec n
+ mov cy, 4(rp)
+ lea 8(rp), rp
+ jnz L(top)
+
+L(end): sbb reg, cy
+
+L(eq1): movd %mm0, reg
+ psrlq $32, %mm0
+ mov SAVE_UP, up
+ sub reg, cy
+ movd %mm0, reg
+ emms
+ mov cy, (rp)
+ sbb reg, cy
+
+ mov SAVE_RP, rp
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86/pentium4/sse2/bdiv_q_1.asm b/gmp/mpn/x86/pentium4/sse2/bdiv_q_1.asm
new file mode 100644
index 0000000000..f7f461d56f
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/bdiv_q_1.asm
@@ -0,0 +1,233 @@
+dnl Intel Pentium-4 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Rearranged from mpn/x86/pentium4/sse2/dive_1.asm by Marco Bodrato.
+
+dnl Copyright 2001, 2002, 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P4: 19.0 cycles/limb
+
+C Pairs of movd's are used to avoid unaligned loads. Despite the loads not
+C being on the dependent chain and there being plenty of cycles available,
+C using an unaligned movq on every second iteration measured about 23 c/l.
+C
+
+defframe(PARAM_SHIFT, 24)
+defframe(PARAM_INVERSE,20)
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+
+C mp_limb_t
+C mpn_pi1_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor,
+C mp_limb_t inverse, int shift)
+ ALIGN(32)
+PROLOGUE(mpn_pi1_bdiv_q_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %edx
+
+ movl PARAM_SRC, %eax
+
+ movl PARAM_DIVISOR, %ecx
+
+ movd %ecx, %mm6
+ movl PARAM_SHIFT, %ecx
+
+ movd %ecx, %mm7 C shift
+
+ C
+
+ movl PARAM_INVERSE, %ecx
+ movd %ecx, %mm5 C inv
+
+ movl PARAM_DST, %ecx
+ pxor %mm1, %mm1 C initial carry limb
+ pxor %mm0, %mm0 C initial carry bit
+
+ subl $1, %edx
+ jz L(done)
+
+ pcmpeqd %mm4, %mm4
+ psrlq $32, %mm4 C 0x00000000FFFFFFFF
+
+C The dependent chain here is as follows.
+C
+C latency
+C psubq s = (src-cbit) - climb 2
+C pmuludq q = s*inverse 8
+C pmuludq prod = q*divisor 8
+C psrlq climb = high(prod) 2
+C --
+C 20
+C
+C Yet the loop measures 19.0 c/l, so obviously there's something gained
+C there over a straight reading of the chip documentation.
+
+L(top):
+ C eax src, incrementing
+ C ebx
+ C ecx dst, incrementing
+ C edx counter, size-1 iterations
+ C
+ C mm0 carry bit
+ C mm1 carry limb
+ C mm4 0x00000000FFFFFFFF
+ C mm5 inverse
+ C mm6 divisor
+ C mm7 shift
+
+ movd (%eax), %mm2
+ movd 4(%eax), %mm3
+ addl $4, %eax
+ punpckldq %mm3, %mm2
+
+ psrlq %mm7, %mm2
+ pand %mm4, %mm2 C src
+ psubq %mm0, %mm2 C src - cbit
+
+ psubq %mm1, %mm2 C src - cbit - climb
+ movq %mm2, %mm0
+ psrlq $63, %mm0 C new cbit
+
+ pmuludq %mm5, %mm2 C s*inverse
+ movd %mm2, (%ecx) C q
+ addl $4, %ecx
+
+ movq %mm6, %mm1
+ pmuludq %mm2, %mm1 C q*divisor
+ psrlq $32, %mm1 C new climb
+
+L(entry):
+ subl $1, %edx
+ jnz L(top)
+
+L(done):
+ movd (%eax), %mm2
+ psrlq %mm7, %mm2 C src
+ psubq %mm0, %mm2 C src - cbit
+
+ psubq %mm1, %mm2 C src - cbit - climb
+
+ pmuludq %mm5, %mm2 C s*inverse
+ movd %mm2, (%ecx) C q
+
+ emms
+ ret
+
+EPILOGUE()
+
+ ALIGN(16)
+C mp_limb_t mpn_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+PROLOGUE(mpn_bdiv_q_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %edx
+
+ movl PARAM_DIVISOR, %ecx
+
+ C eax src
+ C ebx
+ C ecx divisor
+ C edx size-1
+
+ movl %ecx, %eax
+ bsfl %ecx, %ecx C trailing twos
+
+ shrl %cl, %eax C d = divisor without twos
+ movd %eax, %mm6
+ movd %ecx, %mm7 C shift
+
+ shrl %eax C d/2
+
+ andl $127, %eax C d/2, 7 bits
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %ecx)
+ movzbl (%eax,%ecx), %eax C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+
+ C
+
+ movd %eax, %mm5 C inv
+
+ movd %eax, %mm0 C inv
+
+ pmuludq %mm5, %mm5 C inv*inv
+
+ C
+
+ pmuludq %mm6, %mm5 C inv*inv*d
+ paddd %mm0, %mm0 C 2*inv
+
+ C
+
+ psubd %mm5, %mm0 C inv = 2*inv - inv*inv*d
+ pxor %mm5, %mm5
+
+ paddd %mm0, %mm5
+ pmuludq %mm0, %mm0 C inv*inv
+
+ pcmpeqd %mm4, %mm4
+ psrlq $32, %mm4 C 0x00000000FFFFFFFF
+
+ C
+
+ pmuludq %mm6, %mm0 C inv*inv*d
+ paddd %mm5, %mm5 C 2*inv
+
+ movl PARAM_SRC, %eax
+ movl PARAM_DST, %ecx
+ pxor %mm1, %mm1 C initial carry limb
+
+ C
+
+ psubd %mm0, %mm5 C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ movq %mm6, %mm0
+ pmuludq %mm5, %mm0
+ movd %mm0, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ pxor %mm0, %mm0 C initial carry bit
+ jmp L(entry)
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/cnd_add_n.asm b/gmp/mpn/x86/pentium4/sse2/cnd_add_n.asm
new file mode 100644
index 0000000000..b3f3474e67
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/cnd_add_n.asm
@@ -0,0 +1,95 @@
+dnl Intel Pentium-4 mpn_cnd_add_n -- mpn addition.
+
+dnl Copyright 2001, 2002, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) 4.67
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) 5
+C P4 model 3-4 (Prescott) 5.25
+
+defframe(PARAM_SIZE, 20)
+defframe(PARAM_SRC2, 16)
+defframe(PARAM_SRC1, 12)
+defframe(PARAM_DST, 8)
+defframe(PARAM_CND, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX,`PARAM_SRC1')
+
+define(`cnd', `%mm3')
+
+ TEXT
+ ALIGN(8)
+
+ ALIGN(8)
+PROLOGUE(mpn_cnd_add_n)
+deflit(`FRAME',0)
+ pxor %mm0, %mm0
+
+ mov PARAM_CND, %eax
+ neg %eax
+ sbb %eax, %eax
+ movd %eax, cnd
+
+ mov PARAM_SRC1, %eax
+ mov %ebx, SAVE_EBX
+ mov PARAM_SRC2, %ebx
+ mov PARAM_DST, %edx
+ mov PARAM_SIZE, %ecx
+
+ lea (%eax,%ecx,4), %eax C src1 end
+ lea (%ebx,%ecx,4), %ebx C src2 end
+ lea (%edx,%ecx,4), %edx C dst end
+ neg %ecx C -size
+
+L(top): movd (%ebx,%ecx,4), %mm2
+ movd (%eax,%ecx,4), %mm1
+ pand cnd, %mm2
+ paddq %mm2, %mm1
+
+ paddq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $32, %mm0
+
+ add $1, %ecx
+ jnz L(top)
+
+ movd %mm0, %eax
+ mov SAVE_EBX, %ebx
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/cnd_sub_n.asm b/gmp/mpn/x86/pentium4/sse2/cnd_sub_n.asm
new file mode 100644
index 0000000000..339a23e0b6
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/cnd_sub_n.asm
@@ -0,0 +1,114 @@
+dnl Intel Pentium-4 mpn_cnd_sub_n -- mpn subtraction.
+
+dnl Copyright 2001, 2002, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) 4.67
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) 5
+C P4 model 3-4 (Prescott) 5.25
+
+defframe(PARAM_SIZE, 20)
+defframe(PARAM_SRC2, 16)
+defframe(PARAM_SRC1, 12)
+defframe(PARAM_DST, 8)
+defframe(PARAM_CND, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX,`PARAM_SRC1')
+
+define(`cnd', `%mm3')
+
+ TEXT
+ ALIGN(8)
+
+ ALIGN(8)
+PROLOGUE(mpn_cnd_sub_n)
+deflit(`FRAME',0)
+ pxor %mm0, %mm0
+
+ mov PARAM_CND, %eax
+ neg %eax
+ sbb %eax, %eax
+ movd %eax, cnd
+
+ mov PARAM_SRC1, %eax
+ mov %ebx, SAVE_EBX
+ mov PARAM_SRC2, %ebx
+ mov PARAM_DST, %edx
+ mov PARAM_SIZE, %ecx
+
+ lea (%eax,%ecx,4), %eax C src1 end
+ lea (%ebx,%ecx,4), %ebx C src2 end
+ lea (%edx,%ecx,4), %edx C dst end
+ neg %ecx C -size
+
+L(top): movd (%ebx,%ecx,4), %mm2
+ movd (%eax,%ecx,4), %mm1
+ pand cnd, %mm2
+ psubq %mm2, %mm1
+
+ psubq %mm0, %mm1
+ movd %mm1, (%edx,%ecx,4)
+
+ psrlq $63, %mm1
+
+ add $1, %ecx
+ jz L(done_mm1)
+
+ movd (%ebx,%ecx,4), %mm2
+ movd (%eax,%ecx,4), %mm0
+ pand cnd, %mm2
+ psubq %mm2, %mm0
+
+ psubq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $63, %mm0
+
+ add $1, %ecx
+ jnz L(top)
+
+ movd %mm0, %eax
+ mov SAVE_EBX, %ebx
+ emms
+ ret
+
+L(done_mm1):
+ movd %mm1, %eax
+ mov SAVE_EBX, %ebx
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/dive_1.asm b/gmp/mpn/x86/pentium4/sse2/dive_1.asm
new file mode 100644
index 0000000000..238f0dd8a5
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/dive_1.asm
@@ -0,0 +1,215 @@
+dnl Intel Pentium-4 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2001, 2002, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P4: 19.0 cycles/limb
+
+
+C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C
+C Pairs of movd's are used to avoid unaligned loads. Despite the loads not
+C being on the dependent chain and there being plenty of cycles available,
+C using an unaligned movq on every second iteration measured about 23 c/l.
+C
+C Using divl for size==1 seems a touch quicker than mul-by-inverse. The mul
+C will be about 9+2*4+2*2+10*4+19+12 = 92 cycles latency, though some of
+C that might be hidden by out-of-order execution, whereas divl is around 60.
+C At size==2 an extra 19 for the mul versus 60 for the divl will see the mul
+C faster.
+
+defframe(PARAM_DIVISOR,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(mpn_divexact_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %edx
+
+ movl PARAM_SRC, %eax
+
+ movl PARAM_DIVISOR, %ecx
+ subl $1, %edx
+ jnz L(two_or_more)
+
+ movl (%eax), %eax
+ xorl %edx, %edx
+
+ divl %ecx
+ movl PARAM_DST, %ecx
+
+ movl %eax, (%ecx)
+ ret
+
+
+L(two_or_more):
+ C eax src
+ C ebx
+ C ecx divisor
+ C edx size-1
+
+ movl %ecx, %eax
+ bsfl %ecx, %ecx C trailing twos
+
+ shrl %cl, %eax C d = divisor without twos
+ movd %eax, %mm6
+ movd %ecx, %mm7 C shift
+
+ shrl %eax C d/2
+
+ andl $127, %eax C d/2, 7 bits
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %ecx)
+ movzbl (%eax,%ecx), %eax C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+
+ C
+
+ movd %eax, %mm5 C inv
+
+ movd %eax, %mm0 C inv
+
+ pmuludq %mm5, %mm5 C inv*inv
+
+ C
+
+ pmuludq %mm6, %mm5 C inv*inv*d
+ paddd %mm0, %mm0 C 2*inv
+
+ C
+
+ psubd %mm5, %mm0 C inv = 2*inv - inv*inv*d
+ pxor %mm5, %mm5
+
+ paddd %mm0, %mm5
+ pmuludq %mm0, %mm0 C inv*inv
+
+ pcmpeqd %mm4, %mm4
+ psrlq $32, %mm4 C 0x00000000FFFFFFFF
+
+ C
+
+ pmuludq %mm6, %mm0 C inv*inv*d
+ paddd %mm5, %mm5 C 2*inv
+
+ movl PARAM_SRC, %eax
+ movl PARAM_DST, %ecx
+ pxor %mm1, %mm1 C initial carry limb
+
+ C
+
+ psubd %mm0, %mm5 C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ movq %mm6, %mm0
+ pmuludq %mm5, %mm0
+ movd %mm0, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ pxor %mm0, %mm0 C initial carry bit
+
+
+C The dependent chain here is as follows.
+C
+C latency
+C psubq s = (src-cbit) - climb 2
+C pmuludq q = s*inverse 8
+C pmuludq prod = q*divisor 8
+C psrlq climb = high(prod) 2
+C --
+C 20
+C
+C Yet the loop measures 19.0 c/l, so obviously there's something gained
+C there over a straight reading of the chip documentation.
+
+L(top):
+ C eax src, incrementing
+ C ebx
+ C ecx dst, incrementing
+ C edx counter, size-1 iterations
+ C
+ C mm0 carry bit
+ C mm1 carry limb
+ C mm4 0x00000000FFFFFFFF
+ C mm5 inverse
+ C mm6 divisor
+ C mm7 shift
+
+ movd (%eax), %mm2
+ movd 4(%eax), %mm3
+ addl $4, %eax
+ punpckldq %mm3, %mm2
+
+ psrlq %mm7, %mm2
+ pand %mm4, %mm2 C src
+ psubq %mm0, %mm2 C src - cbit
+
+ psubq %mm1, %mm2 C src - cbit - climb
+ movq %mm2, %mm0
+ psrlq $63, %mm0 C new cbit
+
+ pmuludq %mm5, %mm2 C s*inverse
+ movd %mm2, (%ecx) C q
+ addl $4, %ecx
+
+ movq %mm6, %mm1
+ pmuludq %mm2, %mm1 C q*divisor
+ psrlq $32, %mm1 C new climb
+
+ subl $1, %edx
+ jnz L(top)
+
+
+L(done):
+ movd (%eax), %mm2
+ psrlq %mm7, %mm2 C src
+ psubq %mm0, %mm2 C src - cbit
+
+ psubq %mm1, %mm2 C src - cbit - climb
+
+ pmuludq %mm5, %mm2 C s*inverse
+ movd %mm2, (%ecx) C q
+
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/divrem_1.asm b/gmp/mpn/x86/pentium4/sse2/divrem_1.asm
new file mode 100644
index 0000000000..0146fab117
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/divrem_1.asm
@@ -0,0 +1,645 @@
+dnl Intel Pentium-4 mpn_divrem_1 -- mpn by limb division.
+
+dnl Copyright 1999-2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P4: 32 cycles/limb integer part, 30 cycles/limb fraction part.
+
+
+C mp_limb_t mpn_divrem_1 (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C mp_limb_t mpn_divrem_1c (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C mp_limb_t mpn_preinv_divrem_1 (mp_ptr dst, mp_size_t xsize,
+C mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t inverse,
+C unsigned shift);
+C
+C Algorithm:
+C
+C The method and nomenclature follow part 8 of "Division by Invariant
+C Integers using Multiplication" by Granlund and Montgomery, reference in
+C gmp.texi.
+C
+C "m" is written for what is m' in the paper, and "d" for d_norm, which
+C won't cause any confusion since it's only the normalized divisor that's of
+C any use in the code. "b" is written for 2^N, the size of a limb, N being
+C 32 here.
+C
+C The step "sdword dr = n - 2^N*d + (2^N-1-q1) * d" is instead done as
+C "n-d - q1*d". This rearrangement gives the same two-limb answer but lets
+C us have just a psubq on the dependent chain.
+C
+C For reference, the way the k7 code uses "n-(q1+1)*d" would not suit here,
+C detecting an overflow of q1+1 when q1=0xFFFFFFFF would cost too much.
+C
+C Notes:
+C
+C mpn_divrem_1 and mpn_preinv_divrem_1 avoid one division if the src high
+C limb is less than the divisor. mpn_divrem_1c doesn't check for a zero
+C carry, since in normal circumstances that will be a very rare event.
+C
+C The test for skipping a division is branch free (once size>=1 is tested).
+C The store to the destination high limb is 0 when a divide is skipped, or
+C if it's not skipped then a copy of the src high limb is stored. The
+C latter is in case src==dst.
+C
+C There's a small bias towards expecting xsize==0, by having code for
+C xsize==0 in a straight line and xsize!=0 under forward jumps.
+C
+C Enhancements:
+C
+C The loop measures 32 cycles, but the dependent chain would suggest it
+C could be done with 30. Not sure where to start looking for the extras.
+C
+C Alternatives:
+C
+C If the divisor is normalized (high bit set) then a division step can
+C always be skipped, since the high destination limb is always 0 or 1 in
+C that case. It doesn't seem worth checking for this though, since it
+C probably occurs infrequently.
+
+
+dnl MUL_THRESHOLD is the value of xsize+size at which the multiply by
+dnl inverse method is used, rather than plain "divl"s. Minimum value 1.
+dnl
+dnl The inverse takes about 80-90 cycles to calculate, but after that the
+dnl multiply is 32 c/l versus division at about 58 c/l.
+dnl
+dnl At 4 limbs the div is a touch faster than the mul (and of course
+dnl simpler), so start the mul from 5 limbs.
+
+deflit(MUL_THRESHOLD, 5)
+
+
+defframe(PARAM_PREINV_SHIFT, 28) dnl mpn_preinv_divrem_1
+defframe(PARAM_PREINV_INVERSE, 24) dnl mpn_preinv_divrem_1
+defframe(PARAM_CARRY, 24) dnl mpn_divrem_1c
+defframe(PARAM_DIVISOR,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC, 12)
+defframe(PARAM_XSIZE, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_ESI,`PARAM_SIZE')
+define(SAVE_EBP,`PARAM_SRC')
+define(SAVE_EDI,`PARAM_DIVISOR')
+define(SAVE_EBX,`PARAM_DST')
+
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(mpn_preinv_divrem_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ xorl %edx, %edx C carry if can't skip a div
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_DIVISOR, %ebp
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ movl -4(%esi,%ecx,4), %eax C src high limb
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_XSIZE, %ebx
+
+ movd PARAM_PREINV_INVERSE, %mm4
+
+ movd PARAM_PREINV_SHIFT, %mm7 C l
+ cmpl %ebp, %eax C high cmp divisor
+
+ cmovc( %eax, %edx) C high is carry if high<divisor
+ movd %edx, %mm0 C carry
+
+ movd %edx, %mm1 C carry
+ movl $0, %edx
+
+ movd %ebp, %mm5 C d
+ cmovnc( %eax, %edx) C 0 if skip div, src high if not
+ C (the latter in case src==dst)
+ leal -4(%edi,%ebx,4), %edi C &dst[xsize-1]
+
+ movl %edx, (%edi,%ecx,4) C dst high limb
+ sbbl $0, %ecx C skip one division if high<divisor
+ movl $32, %eax
+
+ subl PARAM_PREINV_SHIFT, %eax
+ psllq %mm7, %mm5 C d normalized
+ leal (%edi,%ecx,4), %edi C &dst[xsize+size-1]
+ leal -4(%esi,%ecx,4), %esi C &src[size-1]
+
+ movd %eax, %mm6 C 32-l
+ jmp L(start_preinv)
+
+EPILOGUE()
+
+
+ ALIGN(16)
+PROLOGUE(mpn_divrem_1c)
+deflit(`FRAME',0)
+
+ movl PARAM_CARRY, %edx
+
+ movl PARAM_SIZE, %ecx
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_DIVISOR, %ebp
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_XSIZE, %ebx
+
+ leal -4(%edi,%ebx,4), %edi C &dst[xsize-1]
+ jmp L(start_1c)
+
+EPILOGUE()
+
+
+ ALIGN(16)
+PROLOGUE(mpn_divrem_1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ xorl %edx, %edx C initial carry (if can't skip a div)
+
+ movl %esi, SAVE_ESI
+ movl PARAM_SRC, %esi
+
+ movl %ebp, SAVE_EBP
+ movl PARAM_DIVISOR, %ebp
+
+ movl %edi, SAVE_EDI
+ movl PARAM_DST, %edi
+
+ movl %ebx, SAVE_EBX
+ movl PARAM_XSIZE, %ebx
+ leal -4(%edi,%ebx,4), %edi C &dst[xsize-1]
+
+ orl %ecx, %ecx C size
+ jz L(no_skip_div) C if size==0
+ movl -4(%esi,%ecx,4), %eax C src high limb
+
+ cmpl %ebp, %eax C high cmp divisor
+
+ cmovnc( %eax, %edx) C 0 if skip div, src high if not
+ movl %edx, (%edi,%ecx,4) C dst high limb
+
+ movl $0, %edx
+ cmovc( %eax, %edx) C high is carry if high<divisor
+
+ sbbl $0, %ecx C size-1 if high<divisor
+L(no_skip_div):
+
+
+L(start_1c):
+ C eax
+ C ebx xsize
+ C ecx size
+ C edx carry
+ C esi src
+ C edi &dst[xsize-1]
+ C ebp divisor
+
+ leal (%ebx,%ecx), %eax C size+xsize
+ leal -4(%esi,%ecx,4), %esi C &src[size-1]
+ leal (%edi,%ecx,4), %edi C &dst[size+xsize-1]
+
+ cmpl $MUL_THRESHOLD, %eax
+ jae L(mul_by_inverse)
+
+
+ orl %ecx, %ecx
+ jz L(divide_no_integer) C if size==0
+
+L(divide_integer):
+ C eax scratch (quotient)
+ C ebx xsize
+ C ecx counter
+ C edx carry
+ C esi src, decrementing
+ C edi dst, decrementing
+ C ebp divisor
+
+ movl (%esi), %eax
+ subl $4, %esi
+
+ divl %ebp
+
+ movl %eax, (%edi)
+ subl $4, %edi
+
+ subl $1, %ecx
+ jnz L(divide_integer)
+
+
+L(divide_no_integer):
+ orl %ebx, %ebx
+ jnz L(divide_fraction) C if xsize!=0
+
+L(divide_done):
+ movl SAVE_ESI, %esi
+ movl SAVE_EDI, %edi
+ movl SAVE_EBX, %ebx
+ movl SAVE_EBP, %ebp
+ movl %edx, %eax
+ ret
+
+
+L(divide_fraction):
+ C eax scratch (quotient)
+ C ebx counter
+ C ecx
+ C edx carry
+ C esi
+ C edi dst, decrementing
+ C ebp divisor
+
+ movl $0, %eax
+
+ divl %ebp
+
+ movl %eax, (%edi)
+ subl $4, %edi
+
+ subl $1, %ebx
+ jnz L(divide_fraction)
+
+ jmp L(divide_done)
+
+
+
+C -----------------------------------------------------------------------------
+
+L(mul_by_inverse):
+ C eax
+ C ebx xsize
+ C ecx size
+ C edx carry
+ C esi &src[size-1]
+ C edi &dst[size+xsize-1]
+ C ebp divisor
+
+ bsrl %ebp, %eax C 31-l
+ movd %edx, %mm0 C carry
+ movd %edx, %mm1 C carry
+ movl %ecx, %edx C size
+ movl $31, %ecx
+
+ C
+
+ xorl %eax, %ecx C l = leading zeros on d
+ addl $1, %eax
+
+ shll %cl, %ebp C d normalized
+ movd %ecx, %mm7 C l
+ movl %edx, %ecx C size
+
+ movd %eax, %mm6 C 32-l
+ movl $-1, %edx
+ movl $-1, %eax
+
+ C
+
+ subl %ebp, %edx C (b-d)-1 so edx:eax = b*(b-d)-1
+
+ divl %ebp C floor (b*(b-d)-1 / d)
+ movd %ebp, %mm5 C d
+
+ C
+
+ movd %eax, %mm4 C m
+
+
+L(start_preinv):
+ C eax inverse
+ C ebx xsize
+ C ecx size
+ C edx
+ C esi &src[size-1]
+ C edi &dst[size+xsize-1]
+ C ebp
+ C
+ C mm0 carry
+ C mm1 carry
+ C mm2
+ C mm4 m
+ C mm5 d
+ C mm6 31-l
+ C mm7 l
+
+ psllq %mm7, %mm0 C n2 = carry << l, for size==0
+
+ subl $1, %ecx
+ jb L(integer_none)
+
+ movd (%esi), %mm0 C src high limb
+ punpckldq %mm1, %mm0
+ psrlq %mm6, %mm0 C n2 = high (carry:srchigh << l)
+ jz L(integer_last)
+
+
+C The dependent chain here consists of
+C
+C 2 paddd n1+n2
+C 8 pmuludq m*(n1+n2)
+C 2 paddq n2:nadj + m*(n1+n2)
+C 2 psrlq q1
+C 8 pmuludq d*q1
+C 2 psubq (n-d)-q1*d
+C 2 psrlq high n-(q1+1)*d mask
+C 2 pand d masked
+C 2 paddd n2+d addback
+C --
+C 30
+C
+C But it seems to run at 32 cycles, so presumably there's something else
+C going on.
+
+ ALIGN(16)
+L(integer_top):
+ C eax
+ C ebx
+ C ecx counter, size-1 to 0
+ C edx
+ C esi src, decrementing
+ C edi dst, decrementing
+ C
+ C mm0 n2
+ C mm4 m
+ C mm5 d
+ C mm6 32-l
+ C mm7 l
+
+ ASSERT(b,`C n2<d
+ movd %mm0, %eax
+ movd %mm5, %edx
+ cmpl %edx, %eax')
+
+ movd -4(%esi), %mm1 C next src limbs
+ movd (%esi), %mm2
+ leal -4(%esi), %esi
+
+ punpckldq %mm2, %mm1
+ psrlq %mm6, %mm1 C n10
+
+ movq %mm1, %mm2 C n10
+ movq %mm1, %mm3 C n10
+ psrad $31, %mm1 C -n1
+ pand %mm5, %mm1 C -n1 & d
+ paddd %mm2, %mm1 C nadj = n10+(-n1&d), ignore overflow
+
+ psrld $31, %mm2 C n1
+ paddd %mm0, %mm2 C n2+n1
+ punpckldq %mm0, %mm1 C n2:nadj
+
+ pmuludq %mm4, %mm2 C m*(n2+n1)
+
+ C
+
+ paddq %mm2, %mm1 C n2:nadj + m*(n2+n1)
+ pxor %mm2, %mm2 C break dependency, saves 4 cycles
+ pcmpeqd %mm2, %mm2 C FF...FF
+ psrlq $63, %mm2 C 1
+
+ psrlq $32, %mm1 C q1 = high(n2:nadj + m*(n2+n1))
+
+ paddd %mm1, %mm2 C q1+1
+ pmuludq %mm5, %mm1 C q1*d
+
+ punpckldq %mm0, %mm3 C n = n2:n10
+ pxor %mm0, %mm0
+
+ psubq %mm5, %mm3 C n - d
+
+ C
+
+ psubq %mm1, %mm3 C n - (q1+1)*d
+
+ por %mm3, %mm0 C copy remainder -> new n2
+ psrlq $32, %mm3 C high n - (q1+1)*d, 0 or -1
+
+ ASSERT(be,`C 0 or -1
+ movd %mm3, %eax
+ addl $1, %eax
+ cmpl $1, %eax')
+
+ paddd %mm3, %mm2 C q
+ pand %mm5, %mm3 C mask & d
+
+ paddd %mm3, %mm0 C addback if necessary
+ movd %mm2, (%edi)
+ leal -4(%edi), %edi
+
+ subl $1, %ecx
+ ja L(integer_top)
+
+
+L(integer_last):
+ C eax
+ C ebx xsize
+ C ecx
+ C edx
+ C esi &src[0]
+ C edi &dst[xsize]
+ C
+ C mm0 n2
+ C mm4 m
+ C mm5 d
+ C mm6
+ C mm7 l
+
+ ASSERT(b,`C n2<d
+ movd %mm0, %eax
+ movd %mm5, %edx
+ cmpl %edx, %eax')
+
+ movd (%esi), %mm1 C src[0]
+ psllq %mm7, %mm1 C n10
+
+ movq %mm1, %mm2 C n10
+ movq %mm1, %mm3 C n10
+ psrad $31, %mm1 C -n1
+ pand %mm5, %mm1 C -n1 & d
+ paddd %mm2, %mm1 C nadj = n10+(-n1&d), ignore overflow
+
+ psrld $31, %mm2 C n1
+ paddd %mm0, %mm2 C n2+n1
+ punpckldq %mm0, %mm1 C n2:nadj
+
+ pmuludq %mm4, %mm2 C m*(n2+n1)
+
+ C
+
+ paddq %mm2, %mm1 C n2:nadj + m*(n2+n1)
+ pcmpeqd %mm2, %mm2 C FF...FF
+ psrlq $63, %mm2 C 1
+
+ psrlq $32, %mm1 C q1 = high(n2:nadj + m*(n2+n1))
+ paddd %mm1, %mm2 C q1
+
+ pmuludq %mm5, %mm1 C q1*d
+ punpckldq %mm0, %mm3 C n
+ psubq %mm5, %mm3 C n - d
+ pxor %mm0, %mm0
+
+ C
+
+ psubq %mm1, %mm3 C n - (q1+1)*d
+
+ por %mm3, %mm0 C remainder -> n2
+ psrlq $32, %mm3 C high n - (q1+1)*d, 0 or -1
+
+ ASSERT(be,`C 0 or -1
+ movd %mm3, %eax
+ addl $1, %eax
+ cmpl $1, %eax')
+
+ paddd %mm3, %mm2 C q
+ pand %mm5, %mm3 C mask & d
+
+ paddd %mm3, %mm0 C addback if necessary
+ movd %mm2, (%edi)
+ leal -4(%edi), %edi
+
+
+L(integer_none):
+ C eax
+ C ebx xsize
+
+ orl %ebx, %ebx
+ jnz L(fraction_some) C if xsize!=0
+
+
+L(fraction_done):
+ movl SAVE_EBP, %ebp
+ psrld %mm7, %mm0 C remainder
+
+ movl SAVE_EDI, %edi
+ movd %mm0, %eax
+
+ movl SAVE_ESI, %esi
+ movl SAVE_EBX, %ebx
+ emms
+ ret
+
+
+
+C -----------------------------------------------------------------------------
+C
+
+L(fraction_some):
+ C eax
+ C ebx xsize
+ C ecx
+ C edx
+ C esi
+ C edi &dst[xsize-1]
+ C ebp
+
+
+L(fraction_top):
+ C eax
+ C ebx counter, xsize iterations
+ C ecx
+ C edx
+ C esi src, decrementing
+ C edi dst, decrementing
+ C
+ C mm0 n2
+ C mm4 m
+ C mm5 d
+ C mm6 32-l
+ C mm7 l
+
+ ASSERT(b,`C n2<d
+ movd %mm0, %eax
+ movd %mm5, %edx
+ cmpl %edx, %eax')
+
+ movq %mm0, %mm1 C n2
+ pmuludq %mm4, %mm0 C m*n2
+
+ pcmpeqd %mm2, %mm2
+ psrlq $63, %mm2
+
+ C
+
+ psrlq $32, %mm0 C high(m*n2)
+
+ paddd %mm1, %mm0 C q1 = high(n2:0 + m*n2)
+
+ paddd %mm0, %mm2 C q1+1
+ pmuludq %mm5, %mm0 C q1*d
+
+ psllq $32, %mm1 C n = n2:0
+ psubq %mm5, %mm1 C n - d
+
+ C
+
+ psubq %mm0, %mm1 C r = n - (q1+1)*d
+ pxor %mm0, %mm0
+
+ por %mm1, %mm0 C r -> n2
+ psrlq $32, %mm1 C high n - (q1+1)*d, 0 or -1
+
+ ASSERT(be,`C 0 or -1
+ movd %mm1, %eax
+ addl $1, %eax
+ cmpl $1, %eax')
+
+ paddd %mm1, %mm2 C q
+ pand %mm5, %mm1 C mask & d
+
+ paddd %mm1, %mm0 C addback if necessary
+ movd %mm2, (%edi)
+ leal -4(%edi), %edi
+
+ subl $1, %ebx
+ jne L(fraction_top)
+
+
+ jmp L(fraction_done)
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/gmp-mparam.h b/gmp/mpn/x86/pentium4/sse2/gmp-mparam.h
new file mode 100644
index 0000000000..a94ae868b3
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/gmp-mparam.h
@@ -0,0 +1,206 @@
+/* Intel Pentium-4 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2005, 2007-2010, 2014 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 32
+#define GMP_LIMB_BYTES 4
+
+/* 2600 MHz P4 Northwood */
+/* FFT tuning limit = 12500000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.2 */
+
+#define MOD_1_NORM_THRESHOLD 24
+#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 6
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 13
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 2
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1N_PI1_METHOD 2
+#define DIV_QR_1_NORM_THRESHOLD 19
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 20
+
+#define MUL_TOOM22_THRESHOLD 29
+#define MUL_TOOM33_THRESHOLD 113
+#define MUL_TOOM44_THRESHOLD 288
+#define MUL_TOOM6H_THRESHOLD 454
+#define MUL_TOOM8H_THRESHOLD 592
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 118
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 214
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 193
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 186
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 287
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 44
+#define SQR_TOOM3_THRESHOLD 173
+#define SQR_TOOM4_THRESHOLD 390
+#define SQR_TOOM6_THRESHOLD 0 /* always */
+#define SQR_TOOM8_THRESHOLD 915
+
+#define MULMID_TOOM42_THRESHOLD 66
+
+#define MULMOD_BNM1_THRESHOLD 19
+#define SQRMOD_BNM1_THRESHOLD 23
+
+#define MUL_FFT_MODF_THRESHOLD 1147 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 1147, 5}, { 36, 6}, { 19, 5}, { 39, 6}, \
+ { 27, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
+ { 35, 7}, { 19, 6}, { 40, 7}, { 21, 6}, \
+ { 43, 7}, { 23, 6}, { 49, 7}, { 27, 6}, \
+ { 55, 7}, { 31, 6}, { 63, 7}, { 35, 8}, \
+ { 19, 7}, { 43, 8}, { 23, 7}, { 51, 8}, \
+ { 27, 7}, { 55, 8}, { 31, 7}, { 63, 8}, \
+ { 39, 7}, { 79, 8}, { 43, 9}, { 23, 8}, \
+ { 55, 9}, { 31, 8}, { 71, 9}, { 39, 8}, \
+ { 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
+ { 31, 9}, { 63, 8}, { 127, 9}, { 79,10}, \
+ { 47, 9}, { 111,11}, { 31,10}, { 63, 9}, \
+ { 143,10}, { 79, 9}, { 159,10}, { 111,11}, \
+ { 63,10}, { 127, 9}, { 255,10}, { 159, 9}, \
+ { 319,11}, { 95,10}, { 207,12}, { 63,11}, \
+ { 127,10}, { 287,11}, { 159,10}, { 335,11}, \
+ { 191,10}, { 383,11}, { 223,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 319,10}, { 671,11}, \
+ { 351,12}, { 191,11}, { 383,10}, { 799,13}, \
+ { 127,12}, { 255,11}, { 511,10}, { 1055, 9}, \
+ { 2111,10}, { 1119, 9}, { 2239,11}, { 607,12}, \
+ { 319,11}, { 671,10}, { 1407,11}, { 735,10}, \
+ { 1471, 9}, { 2943,12}, { 383,11}, { 799,10}, \
+ { 1599,11}, { 863,10}, { 1727, 9}, { 3455,12}, \
+ { 447,11}, { 895,13}, { 255,12}, { 511,11}, \
+ { 1055,10}, { 2111,11}, { 1119,10}, { 2239, 9}, \
+ { 4479,12}, { 575,11}, { 1247,10}, { 2495, 9}, \
+ { 4991,12}, { 639,11}, { 1471,10}, { 2943,13}, \
+ { 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
+ { 1727,10}, { 3455,12}, { 895,14}, { 255,13}, \
+ { 511,12}, { 1023,11}, { 2047,12}, { 1087,11}, \
+ { 2239,10}, { 4479,12}, { 1215,11}, { 2495,10}, \
+ { 4991,13}, { 639,12}, { 1471,11}, { 2943,10}, \
+ { 5887,11}, { 3007,13}, { 767,12}, { 1727,11}, \
+ { 3455,13}, { 895,12}, { 1791,11}, { 3711,12}, \
+ { 1983,11}, { 3967,10}, { 7935,14}, { 511,13}, \
+ { 1023,12}, { 2239,11}, { 4479,13}, { 1151,12}, \
+ { 2495,11}, { 4991,13}, { 1279,12}, { 2623,13}, \
+ { 1407,12}, { 2943,11}, { 5887,12}, { 3007,14}, \
+ { 16384,15}, { 32768,16} }
+#define MUL_FFT_TABLE3_SIZE 158
+#define MUL_FFT_THRESHOLD 7808
+
+#define SQR_FFT_MODF_THRESHOLD 896 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 896, 5}, { 28, 6}, { 15, 5}, { 33, 6}, \
+ { 17, 5}, { 35, 6}, { 19, 5}, { 39, 6}, \
+ { 27, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
+ { 36, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
+ { 47, 7}, { 27, 6}, { 55, 7}, { 31, 6}, \
+ { 63, 7}, { 37, 8}, { 19, 7}, { 43, 8}, \
+ { 23, 7}, { 51, 8}, { 27, 7}, { 55, 8}, \
+ { 31, 7}, { 63, 8}, { 39, 7}, { 79, 8}, \
+ { 43, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
+ { 71, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
+ { 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
+ { 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
+ { 127,10}, { 79, 9}, { 159,10}, { 95, 9}, \
+ { 191,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 159,11}, { 95,10}, { 191,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
+ { 543,11}, { 159,10}, { 319, 9}, { 639,11}, \
+ { 191,10}, { 383, 9}, { 767,11}, { 223,12}, \
+ { 127,11}, { 255,10}, { 511, 9}, { 1055,10}, \
+ { 543,11}, { 287,10}, { 607,11}, { 319,12}, \
+ { 191,11}, { 383,10}, { 767,13}, { 127,12}, \
+ { 255,11}, { 511,10}, { 1055,11}, { 543,10}, \
+ { 1119, 9}, { 2239,11}, { 607,12}, { 319,11}, \
+ { 671,10}, { 1407,11}, { 735,10}, { 1471, 9}, \
+ { 2943,12}, { 383,11}, { 799,10}, { 1599,11}, \
+ { 863,10}, { 1727,12}, { 447,11}, { 991,13}, \
+ { 255,12}, { 511,11}, { 1055,10}, { 2111,11}, \
+ { 1119,10}, { 2239,12}, { 575,11}, { 1247,10}, \
+ { 2495,12}, { 639,11}, { 1471,10}, { 2943,13}, \
+ { 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
+ { 1727,10}, { 3455,12}, { 959,14}, { 255,13}, \
+ { 511,12}, { 1023,11}, { 2111,12}, { 1087,11}, \
+ { 2239,10}, { 4479,12}, { 1215,11}, { 2495,13}, \
+ { 639,12}, { 1471,11}, { 2943,10}, { 5887,13}, \
+ { 767,12}, { 1727,11}, { 3455,13}, { 895,12}, \
+ { 1791,11}, { 3711,12}, { 1983,11}, { 3967,10}, \
+ { 7935,14}, { 511,13}, { 1023,12}, { 2239,11}, \
+ { 4479,13}, { 1151,12}, { 2495,11}, { 4991,13}, \
+ { 1279,12}, { 2623,13}, { 1407,12}, { 2943,11}, \
+ { 5887,14}, { 16384,15}, { 32768,16} }
+#define SQR_FFT_TABLE3_SIZE 159
+#define SQR_FFT_THRESHOLD 7296
+
+#define MULLO_BASECASE_THRESHOLD 12
+#define MULLO_DC_THRESHOLD 55
+#define MULLO_MUL_N_THRESHOLD 14709
+
+#define DC_DIV_QR_THRESHOLD 38
+#define DC_DIVAPPR_Q_THRESHOLD 77
+#define DC_BDIV_QR_THRESHOLD 51
+#define DC_BDIV_Q_THRESHOLD 85
+
+#define INV_MULMOD_BNM1_THRESHOLD 56
+#define INV_NEWTON_THRESHOLD 121
+#define INV_APPR_THRESHOLD 93
+
+#define BINV_NEWTON_THRESHOLD 366
+#define REDC_1_TO_REDC_N_THRESHOLD 64
+
+#define MU_DIV_QR_THRESHOLD 2350
+#define MU_DIVAPPR_Q_THRESHOLD 2172
+#define MUPI_DIV_QR_THRESHOLD 62
+#define MU_BDIV_QR_THRESHOLD 2172
+#define MU_BDIV_Q_THRESHOLD 2304
+
+#define POWM_SEC_TABLE 1,19,102,615,2111
+
+#define MATRIX22_STRASSEN_THRESHOLD 23
+#define HGCD_THRESHOLD 88
+#define HGCD_APPR_THRESHOLD 93
+#define HGCD_REDUCE_THRESHOLD 5010
+#define GCD_DC_THRESHOLD 379
+#define GCDEXT_DC_THRESHOLD 258
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 26
+#define SET_STR_DC_THRESHOLD 147
+#define SET_STR_PRECOMPUTE_THRESHOLD 894
+
+#define FAC_DSC_THRESHOLD 906
+#define FAC_ODD_THRESHOLD 28
diff --git a/gmp/mpn/x86/pentium4/sse2/mod_1_1.asm b/gmp/mpn/x86/pentium4/sse2/mod_1_1.asm
new file mode 100644
index 0000000000..ee88babeee
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/mod_1_1.asm
@@ -0,0 +1,166 @@
+dnl x86-32 mpn_mod_1_1p for Pentium 4 and P6 models with SSE2 (i.e., 9,D,E,F).
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2009, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO:
+C * Optimize. The present code was written quite straightforwardly.
+C * Optimize post-loop reduction code; it is from mod_1s_4p, thus overkill.
+C * Write a cps function that uses sse2 insns.
+
+C cycles/limb
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) ?
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) 16
+C P4 model 3-4 (Prescott) 18
+
+C INPUT PARAMETERS
+C ap sp + 4
+C n sp + 8
+C b sp + 12
+C cps sp + 16
+
+define(`B1modb', `%mm1')
+define(`B2modb', `%mm2')
+define(`ap', `%edx')
+define(`n', `%eax')
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_1_1p)
+ push %ebx
+ mov 8(%esp), ap
+ mov 12(%esp), n
+ mov 20(%esp), %ecx
+ movd 8(%ecx), B1modb
+ movd 12(%ecx), B2modb
+
+ lea -4(ap,n,4), ap
+
+C FIXME: See comment in generic/mod_1_1.c.
+ movd (ap), %mm7
+ movd -4(ap), %mm4
+ pmuludq B1modb, %mm7
+ paddq %mm4, %mm7
+ add $-2, n
+ jz L(end)
+
+ ALIGN(8)
+L(top): movq %mm7, %mm6
+ psrlq $32, %mm7 C rh
+ movd -8(ap), %mm0
+ add $-4, ap
+ pmuludq B2modb, %mm7
+ pmuludq B1modb, %mm6
+ add $-1, n
+ paddq %mm0, %mm7
+ paddq %mm6, %mm7
+ jnz L(top)
+
+L(end): pcmpeqd %mm4, %mm4
+ psrlq $32, %mm4 C 0x00000000FFFFFFFF
+ pand %mm7, %mm4 C rl
+ psrlq $32, %mm7 C rh
+ pmuludq B1modb, %mm7 C rh,cl
+ paddq %mm4, %mm7 C rh,rl
+ movd 4(%ecx), %mm4 C cnt
+ psllq %mm4, %mm7 C rh,rl normalized
+ movq %mm7, %mm2 C rl in low half
+ psrlq $32, %mm7 C rh
+ movd (%ecx), %mm1 C bi
+ pmuludq %mm7, %mm1 C qh,ql
+ paddq %mm2, %mm1 C qh-1,ql
+ movd %mm1, %ecx C ql
+ psrlq $32, %mm1 C qh-1
+ movd 16(%esp), %mm3 C b
+ pmuludq %mm1, %mm3 C (qh-1) * b
+ psubq %mm3, %mm2 C r in low half (could use psubd)
+ movd %mm2, %eax C r
+ mov 16(%esp), %ebx
+ sub %ebx, %eax C r
+ cmp %eax, %ecx
+ lea (%eax,%ebx), %edx
+ cmovc( %edx, %eax)
+ movd %mm4, %ecx C cnt
+ cmp %ebx, %eax
+ jae L(fix)
+ emms
+ pop %ebx
+ shr %cl, %eax
+ ret
+
+L(fix): sub %ebx, %eax
+ emms
+ pop %ebx
+ shr %cl, %eax
+ ret
+EPILOGUE()
+
+PROLOGUE(mpn_mod_1_1p_cps)
+C CAUTION: This is the same code as in k7/mod_1_1.asm
+ push %ebp
+ mov 12(%esp), %ebp
+ push %esi
+ bsr %ebp, %ecx
+ push %ebx
+ xor $31, %ecx
+ mov 16(%esp), %esi
+ sal %cl, %ebp
+ mov %ebp, %edx
+ not %edx
+ mov $-1, %eax
+ div %ebp
+ mov %eax, (%esi) C store bi
+ mov %ecx, 4(%esi) C store cnt
+ xor %ebx, %ebx
+ sub %ebp, %ebx
+ mov $1, %edx
+ shld %cl, %eax, %edx
+ imul %edx, %ebx
+ mul %ebx
+ add %ebx, %edx
+ not %edx
+ imul %ebp, %edx
+ add %edx, %ebp
+ cmp %edx, %eax
+ cmovc( %ebp, %edx)
+ shr %cl, %ebx
+ mov %ebx, 8(%esi) C store B1modb
+ shr %cl, %edx
+ mov %edx, 12(%esi) C store B2modb
+ pop %ebx
+ pop %esi
+ pop %ebp
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/mod_1_4.asm b/gmp/mpn/x86/pentium4/sse2/mod_1_4.asm
new file mode 100644
index 0000000000..eb2edb6297
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/mod_1_4.asm
@@ -0,0 +1,269 @@
+dnl x86-32 mpn_mod_1s_4p for Pentium 4 and P6 models with SSE2 (i.e. 9,D,E,F).
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2009, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO:
+C * Optimize. The present code was written quite straightforwardly.
+C * Optimize post-loop reduction code.
+C * Write a cps function that uses sse2 insns.
+
+C cycles/limb
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) 3.4
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) 4
+C P4 model 3-4 (Prescott) 4.5
+
+C INPUT PARAMETERS
+C ap sp + 4
+C n sp + 8
+C b sp + 12
+C cps sp + 16
+
+define(`B1modb', `%mm1')
+define(`B2modb', `%mm2')
+define(`B3modb', `%mm3')
+define(`B4modb', `%mm4')
+define(`B5modb', `%mm5')
+define(`ap', `%edx')
+define(`n', `%eax')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_1s_4p)
+ push %ebx
+ mov 8(%esp), ap
+ mov 12(%esp), n
+ mov 20(%esp), %ecx
+
+ movd 8(%ecx), B1modb
+ movd 12(%ecx), B2modb
+ movd 16(%ecx), B3modb
+ movd 20(%ecx), B4modb
+ movd 24(%ecx), B5modb
+
+ mov n, %ebx
+ lea -4(ap,n,4), ap
+ and $3, %ebx
+ je L(b0)
+ cmp $2, %ebx
+ jc L(b1)
+ je L(b2)
+
+L(b3): movd -4(ap), %mm7
+ pmuludq B1modb, %mm7
+ movd -8(ap), %mm6
+ paddq %mm6, %mm7
+ movd (ap), %mm6
+ pmuludq B2modb, %mm6
+ paddq %mm6, %mm7
+ lea -24(ap), ap
+ add $-3, n
+ jz L(end)
+ jmp L(top)
+
+L(b0): movd -8(ap), %mm7
+ pmuludq B1modb, %mm7
+ movd -12(ap), %mm6
+ paddq %mm6, %mm7
+ movd -4(ap), %mm6
+ pmuludq B2modb, %mm6
+ paddq %mm6, %mm7
+ movd (ap), %mm6
+ pmuludq B3modb, %mm6
+ paddq %mm6, %mm7
+ lea -28(ap), ap
+ add $-4, n
+ jz L(end)
+ jmp L(top)
+
+L(b1): movd (ap), %mm7
+ lea -16(ap), ap
+ dec n
+ jz L(x)
+ jmp L(top)
+
+L(b2): movd -4(ap), %mm7 C rl
+ punpckldq (ap), %mm7 C rh
+ lea -20(ap), ap
+ add $-2, n
+ jz L(end)
+
+ ALIGN(8)
+L(top): movd 4(ap), %mm0
+ pmuludq B1modb, %mm0
+ movd 0(ap), %mm6
+ paddq %mm6, %mm0
+
+ movd 8(ap), %mm6
+ pmuludq B2modb, %mm6
+ paddq %mm6, %mm0
+
+ movd 12(ap), %mm6
+ pmuludq B3modb, %mm6
+ paddq %mm6, %mm0
+
+ movq %mm7, %mm6
+ psrlq $32, %mm7 C rh
+ pmuludq B5modb, %mm7
+ pmuludq B4modb, %mm6
+
+ paddq %mm0, %mm7
+ paddq %mm6, %mm7
+
+ add $-16, ap
+ add $-4, n
+ jnz L(top)
+
+L(end): pcmpeqd %mm4, %mm4
+ psrlq $32, %mm4 C 0x00000000FFFFFFFF
+ pand %mm7, %mm4 C rl
+ psrlq $32, %mm7 C rh
+ pmuludq B1modb, %mm7 C rh,cl
+ paddq %mm4, %mm7 C rh,rl
+L(x): movd 4(%ecx), %mm4 C cnt
+ psllq %mm4, %mm7 C rh,rl normalized
+ movq %mm7, %mm2 C rl in low half
+ psrlq $32, %mm7 C rh
+ movd (%ecx), %mm1 C bi
+ pmuludq %mm7, %mm1 C qh,ql
+ paddq %mm2, %mm1 C qh-1,ql
+ movd %mm1, %ecx C ql
+ psrlq $32, %mm1 C qh-1
+ movd 16(%esp), %mm3 C b
+ pmuludq %mm1, %mm3 C (qh-1) * b
+ psubq %mm3, %mm2 C r in low half (could use psubd)
+ movd %mm2, %eax C r
+ mov 16(%esp), %ebx
+ sub %ebx, %eax C r
+ cmp %eax, %ecx
+ lea (%eax,%ebx), %edx
+ cmovc( %edx, %eax)
+ movd %mm4, %ecx C cnt
+ cmp %ebx, %eax
+ jae L(fix)
+ emms
+ pop %ebx
+ shr %cl, %eax
+ ret
+
+L(fix): sub %ebx, %eax
+ emms
+ pop %ebx
+ shr %cl, %eax
+ ret
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_mod_1s_4p_cps)
+C CAUTION: This is the same code as in k7/mod_1_4.asm
+ push %ebp
+ push %edi
+ push %esi
+ push %ebx
+ mov 20(%esp), %ebp C FIXME: avoid bp for 0-idx
+ mov 24(%esp), %ebx
+ bsr %ebx, %ecx
+ xor $31, %ecx
+ sal %cl, %ebx C b << cnt
+ mov %ebx, %edx
+ not %edx
+ mov $-1, %eax
+ div %ebx
+ xor %edi, %edi
+ sub %ebx, %edi
+ mov $1, %esi
+ mov %eax, (%ebp) C store bi
+ mov %ecx, 4(%ebp) C store cnt
+ shld %cl, %eax, %esi
+ imul %edi, %esi
+ mov %eax, %edi
+ mul %esi
+
+ add %esi, %edx
+ shr %cl, %esi
+ mov %esi, 8(%ebp) C store B1modb
+
+ not %edx
+ imul %ebx, %edx
+ lea (%edx,%ebx), %esi
+ cmp %edx, %eax
+ cmovnc( %edx, %esi)
+ mov %edi, %eax
+ mul %esi
+
+ add %esi, %edx
+ shr %cl, %esi
+ mov %esi, 12(%ebp) C store B2modb
+
+ not %edx
+ imul %ebx, %edx
+ lea (%edx,%ebx), %esi
+ cmp %edx, %eax
+ cmovnc( %edx, %esi)
+ mov %edi, %eax
+ mul %esi
+
+ add %esi, %edx
+ shr %cl, %esi
+ mov %esi, 16(%ebp) C store B3modb
+
+ not %edx
+ imul %ebx, %edx
+ lea (%edx,%ebx), %esi
+ cmp %edx, %eax
+ cmovnc( %edx, %esi)
+ mov %edi, %eax
+ mul %esi
+
+ add %esi, %edx
+ shr %cl, %esi
+ mov %esi, 20(%ebp) C store B4modb
+
+ not %edx
+ imul %ebx, %edx
+ add %edx, %ebx
+ cmp %edx, %eax
+ cmovnc( %edx, %ebx)
+
+ shr %cl, %ebx
+ mov %ebx, 24(%ebp) C store B5modb
+
+ pop %ebx
+ pop %esi
+ pop %edi
+ pop %ebp
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/mod_34lsub1.asm b/gmp/mpn/x86/pentium4/sse2/mod_34lsub1.asm
new file mode 100644
index 0000000000..31e25b79bc
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/mod_34lsub1.asm
@@ -0,0 +1,175 @@
+dnl Intel Pentium 4 mpn_mod_34lsub1 -- remainder modulo 2^24-1.
+
+dnl Copyright 2000-2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C Pentium4: 1.0 cycles/limb
+
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr src, mp_size_t size)
+C
+C Enhancements:
+C
+C There might a couple of cycles to save by using plain integer code for
+C more small sizes. 2 limbs measures about 20 cycles, but 3 limbs jumps to
+C about 46 (inclusive of some function call overheads).
+
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX, `PARAM_SRC')
+define(SAVE_ESI, `PARAM_SIZE')
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_34lsub1)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %ecx
+ movl PARAM_SRC, %edx
+ movl (%edx), %eax
+
+ subl $2, %ecx
+ ja L(three_or_more)
+ jne L(one)
+
+ movl 4(%edx), %edx
+ movl %eax, %ecx
+ shrl $24, %eax C src[0] high
+
+ andl $0x00FFFFFF, %ecx C src[0] low
+ addl %ecx, %eax
+
+ movl %edx, %ecx
+ shll $8, %edx
+
+ shrl $16, %ecx C src[1] low
+ addl %ecx, %eax
+
+ andl $0x00FFFF00, %edx C src[1] high
+ addl %edx, %eax
+
+L(one):
+ ret
+
+
+L(three_or_more):
+ pxor %mm0, %mm0
+ pxor %mm1, %mm1
+ pxor %mm2, %mm2
+
+ pcmpeqd %mm7, %mm7
+ psrlq $32, %mm7 C 0x00000000FFFFFFFF, low 32 bits
+
+ pcmpeqd %mm6, %mm6
+ psrlq $40, %mm6 C 0x0000000000FFFFFF, low 24 bits
+
+L(top):
+ C eax
+ C ebx
+ C ecx counter, size-2 to 0, -1 or -2
+ C edx src, incrementing
+ C
+ C mm0 sum 0mod3
+ C mm1 sum 1mod3
+ C mm2 sum 2mod3
+ C mm3
+ C mm4
+ C mm5
+ C mm6 0x0000000000FFFFFF
+ C mm7 0x00000000FFFFFFFF
+
+ movd (%edx), %mm3
+ paddq %mm3, %mm0
+
+ movd 4(%edx), %mm3
+ paddq %mm3, %mm1
+
+ movd 8(%edx), %mm3
+ paddq %mm3, %mm2
+
+ addl $12, %edx
+ subl $3, %ecx
+ ja L(top)
+
+
+ C ecx is -2, -1 or 0 representing 0, 1 or 2 more limbs, respectively
+
+ addl $1, %ecx
+ js L(combine) C 0 more
+
+ movd (%edx), %mm3
+ paddq %mm3, %mm0
+
+ jz L(combine) C 1 more
+
+ movd 4(%edx), %mm3
+ paddq %mm3, %mm1
+
+L(combine):
+ movq %mm7, %mm3 C low halves
+ pand %mm0, %mm3
+
+ movq %mm7, %mm4
+ pand %mm1, %mm4
+
+ movq %mm7, %mm5
+ pand %mm2, %mm5
+
+ psrlq $32, %mm0 C high halves
+ psrlq $32, %mm1
+ psrlq $32, %mm2
+
+ paddq %mm0, %mm4 C fold high halves to give 33 bits each
+ paddq %mm1, %mm5
+ paddq %mm2, %mm3
+
+ psllq $8, %mm4 C combine at respective offsets
+ psllq $16, %mm5
+ paddq %mm4, %mm3
+ paddq %mm5, %mm3 C 0x000cxxxxxxxxxxxx, 50 bits
+
+ pand %mm3, %mm6 C fold at 24 bits
+ psrlq $24, %mm3
+
+ paddq %mm6, %mm3
+ movd %mm3, %eax
+
+ ASSERT(z, C nothing left in high dword
+ `psrlq $32, %mm3
+ movd %mm3, %ecx
+ orl %ecx, %ecx')
+
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/mode1o.asm b/gmp/mpn/x86/pentium4/sse2/mode1o.asm
new file mode 100644
index 0000000000..778c478169
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/mode1o.asm
@@ -0,0 +1,174 @@
+dnl Intel Pentium-4 mpn_modexact_1_odd -- mpn by limb exact remainder.
+
+dnl Copyright 2001, 2002, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C P4: 19.0 cycles/limb
+
+
+C mp_limb_t mpn_modexact_1_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor);
+C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
+C mp_limb_t divisor, mp_limb_t carry);
+C
+
+defframe(PARAM_CARRY, 16)
+defframe(PARAM_DIVISOR,12)
+defframe(PARAM_SIZE, 8)
+defframe(PARAM_SRC, 4)
+
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(mpn_modexact_1c_odd)
+deflit(`FRAME',0)
+
+ movd PARAM_CARRY, %mm1
+ jmp L(start_1c)
+
+EPILOGUE()
+
+
+ ALIGN(16)
+PROLOGUE(mpn_modexact_1_odd)
+deflit(`FRAME',0)
+
+ pxor %mm1, %mm1 C carry limb
+L(start_1c):
+ movl PARAM_DIVISOR, %eax
+
+ movd PARAM_DIVISOR, %mm7
+
+ shrl %eax
+
+ andl $127, %eax C d/2, 7 bits
+
+ifdef(`PIC',`
+ LEA( binvert_limb_table, %edx)
+ movzbl (%eax,%edx), %eax C inv 8 bits
+',`
+ movzbl binvert_limb_table(%eax), %eax C inv 8 bits
+')
+
+ C
+
+ movd %eax, %mm6 C inv
+
+ movd %eax, %mm0 C inv
+
+ pmuludq %mm6, %mm6 C inv*inv
+
+ C
+
+ pmuludq %mm7, %mm6 C inv*inv*d
+ paddd %mm0, %mm0 C 2*inv
+
+ C
+
+ psubd %mm6, %mm0 C inv = 2*inv - inv*inv*d
+ pxor %mm6, %mm6
+
+ paddd %mm0, %mm6
+ pmuludq %mm0, %mm0 C inv*inv
+
+ C
+
+ pmuludq %mm7, %mm0 C inv*inv*d
+ paddd %mm6, %mm6 C 2*inv
+
+
+ movl PARAM_SRC, %eax
+ movl PARAM_SIZE, %ecx
+
+ C
+
+ psubd %mm0, %mm6 C inv = 2*inv - inv*inv*d
+
+ ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
+ pushl %eax FRAME_pushl()
+ movd %mm6, %eax
+ imul PARAM_DIVISOR, %eax
+ cmpl $1, %eax
+ popl %eax FRAME_popl()')
+
+ pxor %mm0, %mm0 C carry bit
+
+
+C The dependent chain here is as follows.
+C
+C latency
+C psubq s = (src-cbit) - climb 2
+C pmuludq q = s*inverse 8
+C pmuludq prod = q*divisor 8
+C psrlq climb = high(prod) 2
+C --
+C 20
+C
+C Yet the loop measures 19.0 c/l, so obviously there's something gained
+C there over a straight reading of the chip documentation.
+
+L(top):
+ C eax src, incrementing
+ C ebx
+ C ecx counter, limbs
+ C edx
+ C
+ C mm0 carry bit
+ C mm1 carry limb
+ C mm6 inverse
+ C mm7 divisor
+
+ movd (%eax), %mm2
+ addl $4, %eax
+
+ psubq %mm0, %mm2 C src - cbit
+
+ psubq %mm1, %mm2 C src - cbit - climb
+ movq %mm2, %mm0
+ psrlq $63, %mm0 C new cbit
+
+ pmuludq %mm6, %mm2 C s*inverse
+
+ movq %mm7, %mm1
+ pmuludq %mm2, %mm1 C q*divisor
+ psrlq $32, %mm1 C new climb
+
+ subl $1, %ecx
+ jnz L(top)
+
+
+L(done):
+ paddq %mm1, %mm0
+ movd %mm0, %eax
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/mul_1.asm b/gmp/mpn/x86/pentium4/sse2/mul_1.asm
new file mode 100644
index 0000000000..6347b8bf62
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/mul_1.asm
@@ -0,0 +1,164 @@
+dnl mpn_mul_1 for Pentium 4 and P6 models with SSE2 (i.e., 9,D,E,F).
+
+dnl Copyright 2005, 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C cycles/limb
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) 4.17
+C P6 model 13 (Dothan) 4.17
+C P4 model 0-1 (Willamette) 4
+C P4 model 2 (Northwood) 4
+C P4 model 3-4 (Prescott) 4.55
+
+C TODO:
+C * Tweak eax/edx offsets in loop as to save some lea's
+C * Perhaps software pipeline small-case code
+
+C INPUT PARAMETERS
+C rp sp + 4
+C up sp + 8
+C n sp + 12
+C v0 sp + 16
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_1)
+ pxor %mm6, %mm6
+L(ent): mov 4(%esp), %edx
+ mov 8(%esp), %eax
+ mov 12(%esp), %ecx
+ movd 16(%esp), %mm7
+ cmp $4, %ecx
+ jnc L(big)
+
+L(lp0): movd (%eax), %mm0
+ lea 4(%eax), %eax
+ lea 4(%edx), %edx
+ pmuludq %mm7, %mm0
+ paddq %mm0, %mm6
+ movd %mm6, -4(%edx)
+ psrlq $32, %mm6
+ dec %ecx
+ jnz L(lp0)
+ movd %mm6, %eax
+ emms
+ ret
+
+L(big): and $3, %ecx
+ je L(0)
+ cmp $2, %ecx
+ jc L(1)
+ je L(2)
+ jmp L(3) C FIXME: one case should fall through
+
+L(0): movd (%eax), %mm3
+ sub 12(%esp), %ecx C loop count
+ lea -16(%eax), %eax
+ lea -12(%edx), %edx
+ pmuludq %mm7, %mm3
+ movd 20(%eax), %mm0
+ pmuludq %mm7, %mm0
+ movd 24(%eax), %mm1
+ jmp L(00)
+
+L(1): movd (%eax), %mm2
+ sub 12(%esp), %ecx
+ lea -12(%eax), %eax
+ lea -8(%edx), %edx
+ pmuludq %mm7, %mm2
+ movd 16(%eax), %mm3
+ pmuludq %mm7, %mm3
+ movd 20(%eax), %mm0
+ jmp L(01)
+
+L(2): movd (%eax), %mm1
+ sub 12(%esp), %ecx
+ lea -8(%eax), %eax
+ lea -4(%edx), %edx
+ pmuludq %mm7, %mm1
+ movd 12(%eax), %mm2
+ pmuludq %mm7, %mm2
+ movd 16(%eax), %mm3
+ jmp L(10)
+
+L(3): movd (%eax), %mm0
+ sub 12(%esp), %ecx
+ lea -4(%eax), %eax
+ pmuludq %mm7, %mm0
+ movd 8(%eax), %mm1
+ pmuludq %mm7, %mm1
+ movd 12(%eax), %mm2
+
+ ALIGN(16)
+L(top): pmuludq %mm7, %mm2
+ paddq %mm0, %mm6
+ movd 16(%eax), %mm3
+ movd %mm6, 0(%edx)
+ psrlq $32, %mm6
+L(10): pmuludq %mm7, %mm3
+ paddq %mm1, %mm6
+ movd 20(%eax), %mm0
+ movd %mm6, 4(%edx)
+ psrlq $32, %mm6
+L(01): pmuludq %mm7, %mm0
+ paddq %mm2, %mm6
+ movd 24(%eax), %mm1
+ movd %mm6, 8(%edx)
+ psrlq $32, %mm6
+L(00): pmuludq %mm7, %mm1
+ paddq %mm3, %mm6
+ movd 28(%eax), %mm2
+ movd %mm6, 12(%edx)
+ psrlq $32, %mm6
+ lea 16(%eax), %eax
+ lea 16(%edx), %edx
+ add $4, %ecx
+ ja L(top)
+
+L(end): pmuludq %mm7, %mm2
+ paddq %mm0, %mm6
+ movd %mm6, 0(%edx)
+ psrlq $32, %mm6
+ paddq %mm1, %mm6
+ movd %mm6, 4(%edx)
+ psrlq $32, %mm6
+ paddq %mm2, %mm6
+ movd %mm6, 8(%edx)
+ psrlq $32, %mm6
+ movd %mm6, %eax
+ emms
+ ret
+EPILOGUE()
+PROLOGUE(mpn_mul_1c)
+ movd 20(%esp), %mm6
+ jmp L(ent)
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/mul_basecase.asm b/gmp/mpn/x86/pentium4/sse2/mul_basecase.asm
new file mode 100644
index 0000000000..6e3775ae09
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/mul_basecase.asm
@@ -0,0 +1,662 @@
+dnl mpn_mul_basecase for Pentium 4 and P6 models with SSE2 (i.e., 9,D,E,F).
+
+dnl Copyright 2001, 2002, 2005, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO:
+C * Improve ad-hoc outer loop code and register handling. Some feed-in
+C scheduling could improve things by several cycles per outer iteration.
+C * In code for un <= 3, try keeping accumulation operands in registers,
+C without storing intermediates to rp.
+C * We might want to keep 32 in a free mm register, since the register form is
+C 3 bytes and the immediate form is 4 bytes. About 70 bytes to save.
+C * Look into different loop alignment, we now expand the code about 50 bytes
+C with possibly needless alignment.
+C * Perhaps rewrap loops 00,01,02 (6 loops) to allow fall-through entry.
+C * Use OSP, should solve feed-in latency problems.
+C * Save a few tens of bytes by doing cross-jumping for Loel0, etc.
+C * Save around 120 bytes by remapping "m 0", "m 1", "m 2" and "m 3" registers
+C so that they can share feed-in code, and changing the branch targets from
+C L<n> to Lm<nn>.
+
+C cycles/limb
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) 5.24
+C P6 model 14 (Yonah) ?
+C P4 model 0-1 (Willamette): 5
+C P4 model 2 (Northwood): 4.60 at 32 limbs
+C P4 model 3-4 (Prescott): 4.94 at 32 limbs
+
+C INPUT PARAMETERS
+C rp sp + 4
+C up sp + 8
+C un sp + 12
+C vp sp + 16
+C vn sp + 20
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_basecase)
+ push %esi
+ push %ebx
+ mov 12(%esp), %edx C rp
+ mov 16(%esp), %eax C up
+ mov 20(%esp), %ecx C un
+ mov 24(%esp), %esi C vp
+ mov 28(%esp), %ebx C vn
+ movd (%esi), %mm7 C
+L(ent): cmp $3, %ecx
+ ja L(big)
+ movd (%eax), %mm6
+ pmuludq %mm7, %mm6
+ jz L(un3)
+ cmp $2, %ecx
+ jz L(un2)
+
+L(un1): movd %mm6, (%edx) C un=1
+ psrlq $32, %mm6 C un=1
+ movd %mm6, 4(%edx) C un=1
+ jmp L(rtr) C un=1
+
+L(un2): movd 4(%eax), %mm1 C un=2
+ pmuludq %mm7, %mm1 C un=2
+ movd %mm6, (%edx) C un=2
+ psrlq $32, %mm6 C un=2
+ paddq %mm1, %mm6 C un=2
+ movd %mm6, 4(%edx) C un=2
+ psrlq $32, %mm6 C un=2
+ movd %mm6, 8(%edx) C un=2
+ dec %ebx C un=2
+ jz L(rtr) C un=2
+ movd 4(%esi), %mm7 C un=2
+ movd (%eax), %mm6 C un=2
+ pmuludq %mm7, %mm6 C un=2
+ movd 4(%eax), %mm1 C un=2
+ movd 4(%edx), %mm4 C un=2
+ pmuludq %mm7, %mm1 C un=2
+ movd 8(%edx), %mm5 C un=2
+ paddq %mm4, %mm6 C un=2
+ paddq %mm1, %mm5 C un=2
+ movd %mm6, 4(%edx) C un=2
+ psrlq $32, %mm6 C un=2
+ paddq %mm5, %mm6 C un=2
+ movd %mm6, 8(%edx) C un=2
+ psrlq $32, %mm6 C un=2
+ movd %mm6, 12(%edx) C un=2
+L(rtr): emms
+ pop %ebx
+ pop %esi
+ ret
+
+L(un3): movd 4(%eax), %mm1 C un=3
+ pmuludq %mm7, %mm1 C un=3
+ movd 8(%eax), %mm2 C un=3
+ pmuludq %mm7, %mm2 C un=3
+ movd %mm6, (%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ paddq %mm1, %mm6 C un=3
+ movd %mm6, 4(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ paddq %mm2, %mm6 C un=3
+ movd %mm6, 8(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ movd %mm6, 12(%edx) C un=3
+ dec %ebx C un=3
+ jz L(rtr) C un=3
+ movd 4(%esi), %mm7 C un=3
+ movd (%eax), %mm6 C un=3
+ pmuludq %mm7, %mm6 C un=3
+ movd 4(%eax), %mm1 C un=3
+ movd 4(%edx), %mm4 C un=3
+ pmuludq %mm7, %mm1 C un=3
+ movd 8(%eax), %mm2 C un=3
+ movd 8(%edx), %mm5 C un=3
+ pmuludq %mm7, %mm2 C un=3
+ paddq %mm4, %mm6 C un=3
+ paddq %mm1, %mm5 C un=3
+ movd 12(%edx), %mm4 C un=3
+ movd %mm6, 4(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ paddq %mm5, %mm6 C un=3
+ paddq %mm2, %mm4 C un=3
+ movd %mm6, 8(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ paddq %mm4, %mm6 C un=3
+ movd %mm6, 12(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ movd %mm6, 16(%edx) C un=3
+ dec %ebx C un=3
+ jz L(rtr) C un=3
+ movd 8(%esi), %mm7 C un=3
+ movd (%eax), %mm6 C un=3
+ pmuludq %mm7, %mm6 C un=3
+ movd 4(%eax), %mm1 C un=3
+ movd 8(%edx), %mm4 C un=3
+ pmuludq %mm7, %mm1 C un=3
+ movd 8(%eax), %mm2 C un=3
+ movd 12(%edx), %mm5 C un=3
+ pmuludq %mm7, %mm2 C un=3
+ paddq %mm4, %mm6 C un=3
+ paddq %mm1, %mm5 C un=3
+ movd 16(%edx), %mm4 C un=3
+ movd %mm6, 8(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ paddq %mm5, %mm6 C un=3
+ paddq %mm2, %mm4 C un=3
+ movd %mm6, 12(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ paddq %mm4, %mm6 C un=3
+ movd %mm6, 16(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ movd %mm6, 20(%edx) C un=3
+ jmp L(rtr)
+
+
+L(big): push %edi
+ pxor %mm6, %mm6
+ lea 4(%esi), %esi
+ and $3, %ecx
+ jz L(0)
+ cmp $2, %ecx
+ jc L(1)
+ jz L(2)
+ jmp L(3) C FIXME: one case should fall through
+
+
+L(0): movd (%eax), %mm3 C m 0
+ sub 24(%esp), %ecx C inner loop count m 0
+ mov %ecx, 24(%esp) C update loop count for later m 0
+ pmuludq %mm7, %mm3 C m 0
+ movd 4(%eax), %mm0 C m 0
+ pmuludq %mm7, %mm0 C m 0
+ movd 8(%eax), %mm1 C m 0
+ jmp L(m00) C m 0
+ ALIGN(16) C m 0
+L(lpm0):
+ pmuludq %mm7, %mm4 C m 0
+ paddq %mm0, %mm6 C m 0
+ movd (%eax), %mm3 C m 0
+ movd %mm6, -12(%edx) C m 0
+ psrlq $32, %mm6 C m 0
+ pmuludq %mm7, %mm3 C m 0
+ paddq %mm1, %mm6 C m 0
+ movd 4(%eax), %mm0 C m 0
+ movd %mm6, -8(%edx) C m 0
+ psrlq $32, %mm6 C m 0
+ pmuludq %mm7, %mm0 C m 0
+ paddq %mm4, %mm6 C m 0
+ movd 8(%eax), %mm1 C m 0
+ movd %mm6, -4(%edx) C m 0
+ psrlq $32, %mm6 C m 0
+L(m00): pmuludq %mm7, %mm1 C m 0
+ paddq %mm3, %mm6 C m 0
+ movd 12(%eax), %mm4 C m 0
+ movd %mm6, (%edx) C m 0
+ psrlq $32, %mm6 C m 0
+ lea 16(%eax), %eax C m 0
+ lea 16(%edx), %edx C m 0
+ add $4, %ecx C m 0
+ ja L(lpm0) C m 0
+ pmuludq %mm7, %mm4 C m 0
+ paddq %mm0, %mm6 C m 0
+ movd %mm6, -12(%edx) C m 0
+ psrlq $32, %mm6 C m 0
+ paddq %mm1, %mm6 C m 0
+ mov 16(%esp), %edi C rp 0
+ jmp L(x0)
+
+L(olp0):
+ lea 4(%edi), %edi C am 0
+ movd (%esi), %mm7 C am 0
+ lea 4(%esi), %esi C am 0
+ mov %edi, %edx C rp am 0
+ mov 20(%esp), %eax C up am 0
+ movd (%eax), %mm3 C am 0
+ mov 24(%esp), %ecx C inner loop count am 0
+ pxor %mm6, %mm6 C am 0
+ pmuludq %mm7, %mm3 C am 0
+ movd 4(%eax), %mm0 C am 0
+ movd (%edx), %mm5 C am 0
+ pmuludq %mm7, %mm0 C am 0
+ movd 8(%eax), %mm1 C am 0
+ paddq %mm3, %mm5 C am 0
+ movd 4(%edx), %mm4 C am 0
+ jmp L(am00) C am 0
+ ALIGN(16) C mm 0
+L(lam0):
+ pmuludq %mm7, %mm2 C am 0
+ paddq %mm4, %mm6 C am 0
+ movd (%eax), %mm3 C am 0
+ paddq %mm1, %mm5 C am 0
+ movd -4(%edx), %mm4 C am 0
+ movd %mm6, -12(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ pmuludq %mm7, %mm3 C am 0
+ paddq %mm5, %mm6 C am 0
+ movd 4(%eax), %mm0 C am 0
+ paddq %mm2, %mm4 C am 0
+ movd (%edx), %mm5 C am 0
+ movd %mm6, -8(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ pmuludq %mm7, %mm0 C am 0
+ paddq %mm4, %mm6 C am 0
+ movd 8(%eax), %mm1 C am 0
+ paddq %mm3, %mm5 C am 0
+ movd 4(%edx), %mm4 C am 0
+ movd %mm6, -4(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+L(am00):
+ pmuludq %mm7, %mm1 C am 0
+ paddq %mm5, %mm6 C am 0
+ movd 12(%eax), %mm2 C am 0
+ paddq %mm0, %mm4 C am 0
+ movd 8(%edx), %mm5 C am 0
+ movd %mm6, (%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ lea 16(%eax), %eax C am 0
+ lea 16(%edx), %edx C am 0
+ add $4, %ecx C am 0
+ jnz L(lam0) C am 0
+ pmuludq %mm7, %mm2 C am 0
+ paddq %mm4, %mm6 C am 0
+ paddq %mm1, %mm5 C am 0
+ movd -4(%edx), %mm4 C am 0
+ movd %mm6, -12(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ paddq %mm5, %mm6 C am 0
+ paddq %mm2, %mm4 C am 0
+L(x0): movd %mm6, -8(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ paddq %mm4, %mm6 C am 0
+ movd %mm6, -4(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ movd %mm6, (%edx) C am 0
+ dec %ebx C am 0
+ jnz L(olp0) C am 0
+L(oel0):
+ emms C 0
+ pop %edi C 0
+ pop %ebx C 0
+ pop %esi C 0
+ ret C 0
+
+
+L(1): movd (%eax), %mm4 C m 1
+ sub 24(%esp), %ecx C m 1
+ mov %ecx, 24(%esp) C update loop count for later m 1
+ pmuludq %mm7, %mm4 C m 1
+ movd 4(%eax), %mm3 C m 1
+ pmuludq %mm7, %mm3 C m 1
+ movd 8(%eax), %mm0 C m 1
+ jmp L(m01) C m 1
+ ALIGN(16) C m 1
+L(lpm1):
+ pmuludq %mm7, %mm4 C m 1
+ paddq %mm0, %mm6 C m 1
+ movd 4(%eax), %mm3 C m 1
+ movd %mm6, -8(%edx) C m 1
+ psrlq $32, %mm6 C m 1
+ pmuludq %mm7, %mm3 C m 1
+ paddq %mm1, %mm6 C m 1
+ movd 8(%eax), %mm0 C m 1
+ movd %mm6, -4(%edx) C m 1
+ psrlq $32, %mm6 C m 1
+L(m01): pmuludq %mm7, %mm0 C m 1
+ paddq %mm4, %mm6 C m 1
+ movd 12(%eax), %mm1 C m 1
+ movd %mm6, (%edx) C m 1
+ psrlq $32, %mm6 C m 1
+ pmuludq %mm7, %mm1 C m 1
+ paddq %mm3, %mm6 C m 1
+ movd 16(%eax), %mm4 C m 1
+ movd %mm6, 4(%edx) C m 1
+ psrlq $32, %mm6 C m 1
+ lea 16(%eax), %eax C m 1
+ lea 16(%edx), %edx C m 1
+ add $4, %ecx C m 1
+ ja L(lpm1) C m 1
+ pmuludq %mm7, %mm4 C m 1
+ paddq %mm0, %mm6 C m 1
+ movd %mm6, -8(%edx) C m 1
+ psrlq $32, %mm6 C m 1
+ paddq %mm1, %mm6 C m 1
+ mov 16(%esp), %edi C rp 1
+ jmp L(x1)
+
+L(olp1):
+ lea 4(%edi), %edi C am 1
+ movd (%esi), %mm7 C am 1
+ lea 4(%esi), %esi C am 1
+ mov %edi, %edx C rp am 1
+ mov 20(%esp), %eax C up am 1
+ movd (%eax), %mm2 C am 1
+ mov 24(%esp), %ecx C inner loop count am 1
+ pxor %mm6, %mm6 C am 1
+ pmuludq %mm7, %mm2 C am 1
+ movd 4(%eax), %mm3 C am 1
+ movd (%edx), %mm4 C am 1
+ pmuludq %mm7, %mm3 C am 1
+ movd 8(%eax), %mm0 C am 1
+ paddq %mm2, %mm4 C am 1
+ movd 4(%edx), %mm5 C am 1
+ jmp L(am01) C am 1
+ ALIGN(16) C am 1
+L(lam1):
+ pmuludq %mm7, %mm2 C am 1
+ paddq %mm4, %mm6 C am 1
+ movd 4(%eax), %mm3 C am 1
+ paddq %mm1, %mm5 C am 1
+ movd (%edx), %mm4 C am 1
+ movd %mm6, -8(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ pmuludq %mm7, %mm3 C am 1
+ paddq %mm5, %mm6 C am 1
+ movd 8(%eax), %mm0 C am 1
+ paddq %mm2, %mm4 C am 1
+ movd 4(%edx), %mm5 C am 1
+ movd %mm6, -4(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+L(am01):
+ pmuludq %mm7, %mm0 C am 1
+ paddq %mm4, %mm6 C am 1
+ movd 12(%eax), %mm1 C am 1
+ paddq %mm3, %mm5 C am 1
+ movd 8(%edx), %mm4 C am 1
+ movd %mm6, (%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ pmuludq %mm7, %mm1 C am 1
+ paddq %mm5, %mm6 C am 1
+ movd 16(%eax), %mm2 C am 1
+ paddq %mm0, %mm4 C am 1
+ movd 12(%edx), %mm5 C am 1
+ movd %mm6, 4(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ lea 16(%eax), %eax C am 1
+ lea 16(%edx), %edx C am 1
+ add $4, %ecx C am 1
+ jnz L(lam1) C am 1
+ pmuludq %mm7, %mm2 C am 1
+ paddq %mm4, %mm6 C am 1
+ paddq %mm1, %mm5 C am 1
+ movd (%edx), %mm4 C am 1
+ movd %mm6, -8(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ paddq %mm5, %mm6 C am 1
+ paddq %mm2, %mm4 C am 1
+L(x1): movd %mm6, -4(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ paddq %mm4, %mm6 C am 1
+ movd %mm6, (%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ movd %mm6, 4(%edx) C am 1
+ dec %ebx C am 1
+ jnz L(olp1) C am 1
+L(oel1):
+ emms C 1
+ pop %edi C 1
+ pop %ebx C 1
+ pop %esi C 1
+ ret C 1
+
+
+L(2): movd (%eax), %mm1 C m 2
+ sub 24(%esp), %ecx C m 2
+ mov %ecx, 24(%esp) C update loop count for later m 2
+ pmuludq %mm7, %mm1 C m 2
+ movd 4(%eax), %mm4 C m 2
+ pmuludq %mm7, %mm4 C m 2
+ movd 8(%eax), %mm3 C m 2
+ jmp L(m10) C m 2
+ ALIGN(16) C m 2
+L(lpm2):
+ pmuludq %mm7, %mm4 C m 2
+ paddq %mm0, %mm6 C m 2
+ movd 8(%eax), %mm3 C m 2
+ movd %mm6, -4(%edx) C m 2
+ psrlq $32, %mm6 C m 2
+L(m10): pmuludq %mm7, %mm3 C m 2
+ paddq %mm1, %mm6 C m 2
+ movd 12(%eax), %mm0 C m 2
+ movd %mm6, (%edx) C m 2
+ psrlq $32, %mm6 C m 2
+ pmuludq %mm7, %mm0 C m 2
+ paddq %mm4, %mm6 C m 2
+ movd 16(%eax), %mm1 C m 2
+ movd %mm6, 4(%edx) C m 2
+ psrlq $32, %mm6 C m 2
+ pmuludq %mm7, %mm1 C m 2
+ paddq %mm3, %mm6 C m 2
+ movd 20(%eax), %mm4 C m 2
+ movd %mm6, 8(%edx) C m 2
+ psrlq $32, %mm6 C m 2
+ lea 16(%eax), %eax C m 2
+ lea 16(%edx), %edx C m 2
+ add $4, %ecx C m 2
+ ja L(lpm2) C m 2
+ pmuludq %mm7, %mm4 C m 2
+ paddq %mm0, %mm6 C m 2
+ movd %mm6, -4(%edx) C m 2
+ psrlq $32, %mm6 C m 2
+ paddq %mm1, %mm6 C m 2
+ mov 16(%esp), %edi C rp 2
+ jmp L(x2)
+
+L(olp2):
+ lea 4(%edi), %edi C am 2
+ movd (%esi), %mm7 C am 2
+ lea 4(%esi), %esi C am 2
+ mov %edi, %edx C rp am 2
+ mov 20(%esp), %eax C up am 2
+ movd (%eax), %mm1 C am 2
+ mov 24(%esp), %ecx C inner loop count am 2
+ pxor %mm6, %mm6 C am 2
+ pmuludq %mm7, %mm1 C am 2
+ movd 4(%eax), %mm2 C am 2
+ movd (%edx), %mm5 C am 2
+ pmuludq %mm7, %mm2 C am 2
+ movd 8(%eax), %mm3 C am 2
+ paddq %mm1, %mm5 C am 2
+ movd 4(%edx), %mm4 C am 2
+ jmp L(am10) C am 2
+ ALIGN(16) C am 2
+L(lam2):
+ pmuludq %mm7, %mm2 C am 2
+ paddq %mm4, %mm6 C am 2
+ movd 8(%eax), %mm3 C am 2
+ paddq %mm1, %mm5 C am 2
+ movd 4(%edx), %mm4 C am 2
+ movd %mm6, -4(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+L(am10):
+ pmuludq %mm7, %mm3 C am 2
+ paddq %mm5, %mm6 C am 2
+ movd 12(%eax), %mm0 C am 2
+ paddq %mm2, %mm4 C am 2
+ movd 8(%edx), %mm5 C am 2
+ movd %mm6, (%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ pmuludq %mm7, %mm0 C am 2
+ paddq %mm4, %mm6 C am 2
+ movd 16(%eax), %mm1 C am 2
+ paddq %mm3, %mm5 C am 2
+ movd 12(%edx), %mm4 C am 2
+ movd %mm6, 4(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ pmuludq %mm7, %mm1 C am 2
+ paddq %mm5, %mm6 C am 2
+ movd 20(%eax), %mm2 C am 2
+ paddq %mm0, %mm4 C am 2
+ movd 16(%edx), %mm5 C am 2
+ movd %mm6, 8(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ lea 16(%eax), %eax C am 2
+ lea 16(%edx), %edx C am 2
+ add $4, %ecx C am 2
+ jnz L(lam2) C am 2
+ pmuludq %mm7, %mm2 C am 2
+ paddq %mm4, %mm6 C am 2
+ paddq %mm1, %mm5 C am 2
+ movd 4(%edx), %mm4 C am 2
+ movd %mm6, -4(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ paddq %mm5, %mm6 C am 2
+ paddq %mm2, %mm4 C am 2
+L(x2): movd %mm6, (%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ paddq %mm4, %mm6 C am 2
+ movd %mm6, 4(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ movd %mm6, 8(%edx) C am 2
+ dec %ebx C am 2
+ jnz L(olp2) C am 2
+L(oel2):
+ emms C 2
+ pop %edi C 2
+ pop %ebx C 2
+ pop %esi C 2
+ ret C 2
+
+
+L(3): movd (%eax), %mm0 C m 3
+ sub 24(%esp), %ecx C m 3
+ mov %ecx, 24(%esp) C update loop count for later m 3
+ pmuludq %mm7, %mm0 C m 3
+ movd 4(%eax), %mm1 C m 3
+ pmuludq %mm7, %mm1 C m 3
+ movd 8(%eax), %mm4 C m 3
+ jmp L(lpm3) C m 3
+ ALIGN(16) C m 3
+L(lpm3):
+ pmuludq %mm7, %mm4 C m 3
+ paddq %mm0, %mm6 C m 3
+ movd 12(%eax), %mm3 C m 3
+ movd %mm6, (%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ pmuludq %mm7, %mm3 C m 3
+ paddq %mm1, %mm6 C m 3
+ movd 16(%eax), %mm0 C m 3
+ movd %mm6, 4(%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ pmuludq %mm7, %mm0 C m 3
+ paddq %mm4, %mm6 C m 3
+ movd 20(%eax), %mm1 C m 3
+ movd %mm6, 8(%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ pmuludq %mm7, %mm1 C m 3
+ paddq %mm3, %mm6 C m 3
+ movd 24(%eax), %mm4 C m 3
+ movd %mm6, 12(%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ lea 16(%eax), %eax C m 3
+ lea 16(%edx), %edx C m 3
+ add $4, %ecx C m 3
+ ja L(lpm3) C m 3
+ pmuludq %mm7, %mm4 C m 3
+ paddq %mm0, %mm6 C m 3
+ movd %mm6, (%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ paddq %mm1, %mm6 C m 3
+ mov 16(%esp), %edi C rp 3
+ jmp L(x3)
+
+L(olp3):
+ lea 4(%edi), %edi C am 3
+ movd (%esi), %mm7 C am 3
+ lea 4(%esi), %esi C am 3
+ mov %edi, %edx C rp am 3
+ mov 20(%esp), %eax C up am 3
+ movd (%eax), %mm0 C am 3
+ mov 24(%esp), %ecx C inner loop count am 3
+ pxor %mm6, %mm6 C am 3
+ pmuludq %mm7, %mm0 C am 3
+ movd 4(%eax), %mm1 C am 3
+ movd (%edx), %mm4 C am 3
+ pmuludq %mm7, %mm1 C am 3
+ movd 8(%eax), %mm2 C am 3
+ paddq %mm0, %mm4 C am 3
+ movd 4(%edx), %mm5 C am 3
+ jmp L(lam3) C am 3
+ ALIGN(16) C am 3
+L(lam3):
+ pmuludq %mm7, %mm2 C am 3
+ paddq %mm4, %mm6 C am 3
+ movd 12(%eax), %mm3 C am 3
+ paddq %mm1, %mm5 C am 3
+ movd 8(%edx), %mm4 C am 3
+ movd %mm6, (%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ pmuludq %mm7, %mm3 C am 3
+ paddq %mm5, %mm6 C am 3
+ movd 16(%eax), %mm0 C am 3
+ paddq %mm2, %mm4 C am 3
+ movd 12(%edx), %mm5 C am 3
+ movd %mm6, 4(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ pmuludq %mm7, %mm0 C am 3
+ paddq %mm4, %mm6 C am 3
+ movd 20(%eax), %mm1 C am 3
+ paddq %mm3, %mm5 C am 3
+ movd 16(%edx), %mm4 C am 3
+ movd %mm6, 8(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ pmuludq %mm7, %mm1 C am 3
+ paddq %mm5, %mm6 C am 3
+ movd 24(%eax), %mm2 C am 3
+ paddq %mm0, %mm4 C am 3
+ movd 20(%edx), %mm5 C am 3
+ movd %mm6, 12(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ lea 16(%eax), %eax C am 3
+ lea 16(%edx), %edx C am 3
+ add $4, %ecx C am 3
+ jnz L(lam3) C am 3
+ pmuludq %mm7, %mm2 C am 3
+ paddq %mm4, %mm6 C am 3
+ paddq %mm1, %mm5 C am 3
+ movd 8(%edx), %mm4 C am 3
+ movd %mm6, (%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ paddq %mm5, %mm6 C am 3
+ paddq %mm2, %mm4 C am 3
+L(x3): movd %mm6, 4(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ paddq %mm4, %mm6 C am 3
+ movd %mm6, 8(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ movd %mm6, 12(%edx) C am 3
+ dec %ebx C am 3
+ jnz L(olp3) C am 3
+L(oel3):
+ emms C 3
+ pop %edi C 3
+ pop %ebx C 3
+ pop %esi C 3
+ ret C 3
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/popcount.asm b/gmp/mpn/x86/pentium4/sse2/popcount.asm
new file mode 100644
index 0000000000..b8238b9b66
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/popcount.asm
@@ -0,0 +1,280 @@
+dnl X86-32 and X86-64 mpn_popcount using SSE2.
+
+dnl Copyright 2006, 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+
+C 32-bit popcount hamdist
+C cycles/limb cycles/limb
+C P5 -
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) 4
+C P4 model 0 (Willamette) ?
+C P4 model 1 (?) ?
+C P4 model 2 (Northwood) 3.9
+C P4 model 3 (Prescott) ?
+C P4 model 4 (Nocona) ?
+C AMD K6 -
+C AMD K7 -
+C AMD K8 ?
+
+C 64-bit popcount hamdist
+C cycles/limb cycles/limb
+C P4 model 4 (Nocona): 8
+C AMD K8,K9 7.5
+C AMD K10 3.5
+C Intel core2 3.68
+C Intel corei 3.15
+C Intel atom 10.8
+C VIA nano 6.5
+
+C TODO
+C * Make a mpn_hamdist based on this. Alignment could either be handled by
+C using movdqu for one operand and movdqa for the other, or by painfully
+C shifting as we go. Unfortunately, there seem to be no usable shift
+C instruction, except for one that takes an immediate count.
+C * It would probably be possible to cut a few cycles/limb using software
+C pipelining.
+C * There are 35 decode slots unused by the SSE2 instructions. Loop control
+C needs just 2 or 3 slots, leaving around 32 slots. This allows a parallel
+C integer based popcount. Such a combined loop would handle 6 limbs in
+C about 30 cycles on K8.
+C * We could save a byte or two by using 32-bit operations on areg.
+C * Check if using movdqa to a temp of and then register-based pand is faster.
+
+ifelse(GMP_LIMB_BITS,`32',
+` define(`up', `%edx')
+ define(`n', `%ecx')
+ define(`areg',`%eax')
+ define(`breg',`%ebx')
+ define(`zero',`%xmm4')
+ define(`LIMB32',` $1')
+ define(`LIMB64',`dnl')
+',`
+ define(`up', `%rdi')
+ define(`n', `%rsi')
+ define(`areg',`%rax')
+ define(`breg',`%rdx')
+ define(`zero',`%xmm8')
+ define(`LIMB32',`dnl')
+ define(`LIMB64',` $1')
+')
+
+define(`mm01010101',`%xmm6')
+define(`mm00110011',`%xmm7')
+define(`mm00001111',`%xmm2')
+
+define(`GMP_LIMB_BYTES', eval(GMP_LIMB_BITS/8))
+define(`LIMBS_PER_XMM', eval(16/GMP_LIMB_BYTES))
+define(`LIMBS_PER_2XMM', eval(32/GMP_LIMB_BYTES))
+
+undefine(`psadbw') C override inherited m4 version
+
+ASM_START()
+
+C Make cnsts global to work around Apple relocation bug.
+ifdef(`DARWIN',`
+ define(`cnsts', MPN(popccnsts))
+ GLOBL cnsts')
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_popcount)
+
+LIMB32(`mov 4(%esp), up ')
+LIMB32(`mov 8(%esp), n ')
+LIMB32(`push %ebx ')
+
+ pxor %xmm3, %xmm3 C zero grand total count
+LIMB64(`pxor zero, zero ')
+ifdef(`PIC',`
+ LEA( cnsts, breg)
+',`
+LIMB32(`mov $cnsts, breg ')
+LIMB64(`movabs $cnsts, breg ')
+')
+
+ movdqa -48(breg), mm01010101
+ movdqa -32(breg), mm00110011
+ movdqa -16(breg), mm00001111
+
+ mov up, areg
+ and $-16, up C round `up' down to 128-bit boundary
+ and $12, areg C 32:areg = 0, 4, 8, 12
+ C 64:areg = 0, 8
+ movdqa (up), %xmm0
+ pand 64(breg,areg,4), %xmm0
+ shr $m4_log2(GMP_LIMB_BYTES), %eax
+ add areg, n C compensate n for rounded down `up'
+
+ pxor %xmm4, %xmm4
+ sub $LIMBS_PER_XMM, n
+ jbe L(sum)
+
+ sub $LIMBS_PER_XMM, n
+ ja L(ent)
+ jmp L(lsum)
+
+ ALIGN(16)
+L(top): movdqa (up), %xmm0
+L(ent): movdqa 16(up), %xmm4
+
+ movdqa %xmm0, %xmm1
+ movdqa %xmm4, %xmm5
+ psrld $1, %xmm0
+ psrld $1, %xmm4
+ pand mm01010101, %xmm0
+ pand mm01010101, %xmm4
+ psubd %xmm0, %xmm1
+ psubd %xmm4, %xmm5
+
+ movdqa %xmm1, %xmm0
+ movdqa %xmm5, %xmm4
+ psrlq $2, %xmm1
+ psrlq $2, %xmm5
+ pand mm00110011, %xmm0
+ pand mm00110011, %xmm4
+ pand mm00110011, %xmm1
+ pand mm00110011, %xmm5
+ paddq %xmm0, %xmm1
+ paddq %xmm4, %xmm5
+
+LIMB32(`pxor zero, zero ')
+
+ add $32, up
+ sub $LIMBS_PER_2XMM, n
+
+ paddq %xmm5, %xmm1
+ movdqa %xmm1, %xmm0
+ psrlq $4, %xmm1
+ pand mm00001111, %xmm0
+ pand mm00001111, %xmm1
+ paddq %xmm0, %xmm1
+
+ psadbw zero, %xmm1
+ paddq %xmm1, %xmm3 C add to grand total
+
+ jnc L(top)
+L(end):
+ add $LIMBS_PER_2XMM, n
+ jz L(rt)
+ movdqa (up), %xmm0
+ pxor %xmm4, %xmm4
+ sub $LIMBS_PER_XMM, n
+ jbe L(sum)
+L(lsum):
+ movdqa %xmm0, %xmm4
+ movdqa 16(up), %xmm0
+L(sum):
+ shl $m4_log2(GMP_LIMB_BYTES), n
+ and $12, n
+ pand (breg,n,4), %xmm0
+
+ movdqa %xmm0, %xmm1
+ movdqa %xmm4, %xmm5
+ psrld $1, %xmm0
+ psrld $1, %xmm4
+ pand mm01010101, %xmm0
+ pand mm01010101, %xmm4
+ psubd %xmm0, %xmm1
+ psubd %xmm4, %xmm5
+
+ movdqa %xmm1, %xmm0
+ movdqa %xmm5, %xmm4
+ psrlq $2, %xmm1
+ psrlq $2, %xmm5
+ pand mm00110011, %xmm0
+ pand mm00110011, %xmm4
+ pand mm00110011, %xmm1
+ pand mm00110011, %xmm5
+ paddq %xmm0, %xmm1
+ paddq %xmm4, %xmm5
+
+LIMB32(`pxor zero, zero ')
+
+ paddq %xmm5, %xmm1
+ movdqa %xmm1, %xmm0
+ psrlq $4, %xmm1
+ pand mm00001111, %xmm0
+ pand mm00001111, %xmm1
+ paddq %xmm0, %xmm1
+
+ psadbw zero, %xmm1
+ paddq %xmm1, %xmm3 C add to grand total
+
+
+C Add the two 64-bit halves of the grand total counter
+L(rt): movdqa %xmm3, %xmm0
+ psrldq $8, %xmm3
+ paddq %xmm3, %xmm0
+ movd %xmm0, areg C movq avoided due to gas bug
+
+LIMB32(`pop %ebx ')
+ ret
+
+EPILOGUE()
+DEF_OBJECT(dummy,16)
+C Three magic constants used for masking out bits
+ .byte 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
+ .byte 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
+
+ .byte 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33
+ .byte 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33
+
+ .byte 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f
+ .byte 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f
+cnsts:
+C Masks for high end of number
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+
+ .byte 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00
+ .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ .byte 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00
+C Masks for low end of number
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+
+ .byte 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+
+ .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ .byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+
+ .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ .byte 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
+END_OBJECT(dummy)
diff --git a/gmp/mpn/x86/pentium4/sse2/rsh1add_n.asm b/gmp/mpn/x86/pentium4/sse2/rsh1add_n.asm
new file mode 100644
index 0000000000..f421d1323e
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/rsh1add_n.asm
@@ -0,0 +1,126 @@
+dnl Intel Pentium-4 mpn_rsh1add_n -- mpn (x+y)/2
+
+dnl Copyright 2001-2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb (approx)
+C dst!=src1,2 dst==src1 dst==src2
+C P4: 4.5 6.5 6.5
+
+
+C mp_limb_t mpn_rsh1add_n (mp_ptr wp, mp_srcptr xp, mp_srcptr yp,
+C mp_size_t size);
+C
+C The slightly strange combination of indexing and pointer incrementing
+C that's used seems to work best. Not sure why, but for instance leal
+C incrementing on %esi is a 1 or 2 cycle slowdown.
+C
+C The dependent chain is paddq combining the carry and next (shifted) part,
+C plus psrlq to move the new carry down. That, and just 4 mmx instructions
+C in total, makes 4 c/l the target speed, which is almost achieved for
+C separate src/dst but when src==dst the write combining anomalies slow it
+C down.
+
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_YP, 12)
+defframe(PARAM_XP, 8)
+defframe(PARAM_WP, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX,`PARAM_XP')
+define(SAVE_ESI,`PARAM_YP')
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_rsh1add_n)
+deflit(`FRAME',0)
+
+ movl PARAM_XP, %edx
+ movl %ebx, SAVE_EBX
+
+ movl PARAM_YP, %ebx
+ movl %esi, SAVE_ESI
+
+ movl PARAM_WP, %esi
+
+ movd (%edx), %mm0 C xp[0]
+
+ movd (%ebx), %mm1 C yp[0]
+ movl PARAM_SIZE, %ecx
+
+ movl (%edx), %eax C xp[0]
+
+ addl (%ebx), %eax C xp[0]+yp[0]
+
+ paddq %mm1, %mm0 C xp[0]+yp[0]
+ leal (%esi,%ecx,4), %esi C wp end
+ negl %ecx C -size
+
+ psrlq $1, %mm0 C (xp[0]+yp[0])/2
+ and $1, %eax C return value, rsh1 bit of xp[0]+yp[0]
+ addl $1, %ecx C -(size-1)
+ jz L(done)
+
+
+L(top):
+ C eax return value
+ C ebx yp end
+ C ecx counter, limbs, -(size-1) to -1 inclusive
+ C edx xp end
+ C esi wp end
+ C mm0 carry (32 bits)
+
+ movd 4(%edx), %mm1 C xp[i+1]
+ movd 4(%ebx), %mm2 C yp[i+1]
+ leal 4(%edx), %edx
+ leal 4(%ebx), %ebx
+ paddq %mm2, %mm1 C xp[i+1]+yp[i+1]
+ psllq $31, %mm1 C low bit at 31, further 32 above
+
+ paddq %mm1, %mm0 C 31 and carry from prev add
+ movd %mm0, -4(%esi,%ecx,4) C low ready to store dst[i]
+
+ psrlq $32, %mm0 C high becomes new carry
+
+ addl $1, %ecx
+ jnz L(top)
+
+
+L(done):
+ movd %mm0, -4(%esi) C dst[size-1]
+ movl SAVE_EBX, %ebx
+
+ movl SAVE_ESI, %esi
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/sqr_basecase.asm b/gmp/mpn/x86/pentium4/sse2/sqr_basecase.asm
new file mode 100644
index 0000000000..2dd57d25d9
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/sqr_basecase.asm
@@ -0,0 +1,705 @@
+dnl mpn_sqr_basecase for Pentium 4 and P6 models with SSE2 (i.e., 9,D,E,F).
+
+dnl Copyright 2001, 2002, 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO:
+C * Improve ad-hoc outer loop code and register handling. Some feed-in
+C scheduling could improve things by several cycles per outer iteration.
+C * In Lam3...Lam1 code for, keep accumulation operands in registers, without
+C storing intermediates to rp.
+C * We might want to keep 32 in a free mm register, since the register form is
+C 3 bytes and the immediate form is 4 bytes. About 80 bytes to save.
+C * Look into different loop alignment, we now expand the code about 50 bytes
+C with possibly needless alignment.
+C * Use OSP, should solve feed-in latency problems.
+C * Address relative slowness for un<=3 for Pentium M. The old code is there
+C considerably faster. (1:20/14, 2:34:32, 3:66/57)
+
+C INPUT PARAMETERS
+C rp sp + 4
+C up sp + 8
+C un sp + 12
+
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sqr_basecase)
+ mov 4(%esp), %edx C rp
+ mov 8(%esp), %eax C up
+ mov 12(%esp), %ecx C un
+
+ cmp $2, %ecx
+ jc L(un1)
+ jz L(un2)
+ cmp $4, %ecx
+ jc L(un3)
+ jz L(un4)
+ jmp L(big)
+
+L(un1): mov (%eax), %eax
+ mov %edx, %ecx
+ mul %eax
+ mov %eax, (%ecx)
+ mov %edx, 4(%ecx)
+ ret
+L(un2): movd (%eax), %mm0 C un=2
+ movd (%eax), %mm2 C un=2
+ movd 4(%eax), %mm1 C un=2
+ pmuludq %mm0, %mm0 C 64b weight 0 un=2
+ pmuludq %mm1, %mm2 C 64b weight 32 un=2
+ pmuludq %mm1, %mm1 C 64b weight 64 un=2
+ movd %mm0, (%edx) C un=2
+ psrlq $32, %mm0 C 32b weight 32 un=2
+ pcmpeqd %mm7, %mm7 C un=2
+ psrlq $33, %mm7 C 0x000000007FFFFFFF un=2
+ pand %mm2, %mm7 C 31b weight 32 un=2
+ psrlq $31, %mm2 C 33b weight 65 un=2
+ psllq $1, %mm7 C 31b weight 33 un=2
+ paddq %mm7, %mm0 C un=2
+ movd %mm0, 4(%edx) C un=2
+ psrlq $32, %mm0 C un=2
+ paddq %mm2, %mm1 C un=2
+ paddq %mm0, %mm1 C un=2
+ movd %mm1, 8(%edx) C un=2
+ psrlq $32, %mm1 C un=2
+ movd %mm1, 12(%edx) C un=2
+ emms
+ ret
+L(un3): movd (%eax), %mm7 C un=3
+ movd 4(%eax), %mm6 C un=3
+ pmuludq %mm7, %mm6 C un=3
+ movd 8(%eax), %mm2 C un=3
+ pmuludq %mm7, %mm2 C un=3
+ movd %mm6, 4(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ paddq %mm2, %mm6 C un=3
+ movd %mm6, 8(%edx) C un=3
+ psrlq $32, %mm6 C un=3
+ movd %mm6, 12(%edx) C un=3
+ lea 4(%edx), %edx C un=3
+ lea 4(%eax), %eax C un=3
+ jmp L(am1)
+L(un4): movd (%eax), %mm7 C un=4
+ movd 4(%eax), %mm6 C un=4
+ pmuludq %mm7, %mm6 C un=4
+ movd 8(%eax), %mm0 C un=4
+ pmuludq %mm7, %mm0 C un=4
+ movd 12(%eax), %mm1 C un=4
+ pmuludq %mm7, %mm1 C un=4
+ movd %mm6, 4(%edx) C un=4
+ psrlq $32, %mm6 C un=4
+ paddq %mm0, %mm6 C un=4
+ movd %mm6, 8(%edx) C un=4
+ psrlq $32, %mm6 C un=4
+ paddq %mm1, %mm6 C un=4
+ movd %mm6, 12(%edx) C un=4
+ psrlq $32, %mm6 C un=4
+ movd %mm6, 16(%edx) C un=4
+ lea 4(%edx), %edx C un=4
+ lea 4(%eax), %eax C un=4
+ jmp L(am2)
+
+L(big): push %esi
+ push %ebx
+ push %edi
+ pxor %mm6, %mm6
+ movd (%eax), %mm7 C
+ lea 4(%eax), %esi C init up, up++
+ lea 4(%eax), %eax C up2++ FIXME: should fix offsets
+ lea 4(%edx), %edi C init rp, rp++
+ lea 4(%edx), %edx C rp2++
+ lea -4(%ecx), %ebx C loop count
+ and $3, %ecx
+ jz L(3m)
+ cmp $2, %ecx
+ ja L(2m)
+ jb L(0m)
+
+L(1m):
+ movd (%eax), %mm4 C m 1
+ lea (%ebx), %ecx C inner loop count m 1
+ pmuludq %mm7, %mm4 C m 1
+ movd 4(%eax), %mm3 C m 1
+ pmuludq %mm7, %mm3 C m 1
+ movd 8(%eax), %mm0 C m 1
+ jmp L(m01) C m 1
+ ALIGN(16) C m 1
+L(lpm1):
+ pmuludq %mm7, %mm4 C m 1
+ paddq %mm0, %mm6 C m 1
+ movd 4(%eax), %mm3 C m 1
+ movd %mm6, -8(%edx) C m 1
+ psrlq $32, %mm6 C m 1
+ pmuludq %mm7, %mm3 C m 1
+ paddq %mm1, %mm6 C m 1
+ movd 8(%eax), %mm0 C m 1
+ movd %mm6, -4(%edx) C m 1
+ psrlq $32, %mm6 C m 1
+L(m01): pmuludq %mm7, %mm0 C m 1
+ paddq %mm4, %mm6 C m 1
+ movd 12(%eax), %mm1 C m 1
+ movd %mm6, (%edx) C m 1
+ psrlq $32, %mm6 C m 1
+ pmuludq %mm7, %mm1 C m 1
+ paddq %mm3, %mm6 C m 1
+ movd 16(%eax), %mm4 C m 1
+ movd %mm6, 4(%edx) C m 1
+ psrlq $32, %mm6 C m 1
+ lea 16(%eax), %eax C m 1
+ lea 16(%edx), %edx C m 1
+ sub $4, %ecx C m 1
+ ja L(lpm1) C m 1
+ pmuludq %mm7, %mm4 C m 1
+ paddq %mm0, %mm6 C m 1
+ movd %mm6, -8(%edx) C m 1
+ psrlq $32, %mm6 C m 1
+ paddq %mm1, %mm6 C m 1
+ jmp L(0)
+
+L(2m):
+ movd (%eax), %mm1 C m 2
+ lea (%ebx), %ecx C inner loop count m 2
+ pmuludq %mm7, %mm1 C m 2
+ movd 4(%eax), %mm4 C m 2
+ pmuludq %mm7, %mm4 C m 2
+ movd 8(%eax), %mm3 C m 2
+ jmp L(m10) C m 2
+ ALIGN(16) C m 2
+L(lpm2):
+ pmuludq %mm7, %mm4 C m 2
+ paddq %mm0, %mm6 C m 2
+ movd 8(%eax), %mm3 C m 2
+ movd %mm6, -4(%edx) C m 2
+ psrlq $32, %mm6 C m 2
+L(m10): pmuludq %mm7, %mm3 C m 2
+ paddq %mm1, %mm6 C m 2
+ movd 12(%eax), %mm0 C m 2
+ movd %mm6, (%edx) C m 2
+ psrlq $32, %mm6 C m 2
+ pmuludq %mm7, %mm0 C m 2
+ paddq %mm4, %mm6 C m 2
+ movd 16(%eax), %mm1 C m 2
+ movd %mm6, 4(%edx) C m 2
+ psrlq $32, %mm6 C m 2
+ pmuludq %mm7, %mm1 C m 2
+ paddq %mm3, %mm6 C m 2
+ movd 20(%eax), %mm4 C m 2
+ movd %mm6, 8(%edx) C m 2
+ psrlq $32, %mm6 C m 2
+ lea 16(%eax), %eax C m 2
+ lea 16(%edx), %edx C m 2
+ sub $4, %ecx C m 2
+ ja L(lpm2) C m 2
+ pmuludq %mm7, %mm4 C m 2
+ paddq %mm0, %mm6 C m 2
+ movd %mm6, -4(%edx) C m 2
+ psrlq $32, %mm6 C m 2
+ paddq %mm1, %mm6 C m 2
+ jmp L(1)
+
+L(3m):
+ movd (%eax), %mm0 C m 3
+ lea (%ebx), %ecx C inner loop count m 3
+ pmuludq %mm7, %mm0 C m 3
+ movd 4(%eax), %mm1 C m 3
+ pmuludq %mm7, %mm1 C m 3
+ movd 8(%eax), %mm4 C m 3
+ jmp L(lpm3) C m 3
+ ALIGN(16) C m 3
+L(lpm3):
+ pmuludq %mm7, %mm4 C m 3
+ paddq %mm0, %mm6 C m 3
+ movd 12(%eax), %mm3 C m 3
+ movd %mm6, (%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ pmuludq %mm7, %mm3 C m 3
+ paddq %mm1, %mm6 C m 3
+ movd 16(%eax), %mm0 C m 3
+ movd %mm6, 4(%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ pmuludq %mm7, %mm0 C m 3
+ paddq %mm4, %mm6 C m 3
+ movd 20(%eax), %mm1 C m 3
+ movd %mm6, 8(%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ pmuludq %mm7, %mm1 C m 3
+ paddq %mm3, %mm6 C m 3
+ movd 24(%eax), %mm4 C m 3
+ movd %mm6, 12(%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ lea 16(%eax), %eax C m 3
+ lea 16(%edx), %edx C m 3
+ sub $4, %ecx C m 3
+ ja L(lpm3) C m 3
+ pmuludq %mm7, %mm4 C m 3
+ paddq %mm0, %mm6 C m 3
+ movd %mm6, (%edx) C m 3
+ psrlq $32, %mm6 C m 3
+ paddq %mm1, %mm6 C m 3
+ jmp L(2)
+
+L(0m):
+ movd (%eax), %mm3 C m 0
+ lea (%ebx), %ecx C inner loop count m 0
+ pmuludq %mm7, %mm3 C m 0
+ movd 4(%eax), %mm0 C m 0
+ pmuludq %mm7, %mm0 C m 0
+ movd 8(%eax), %mm1 C m 0
+ jmp L(m00) C m 0
+ ALIGN(16) C m 0
+L(lpm0):
+ pmuludq %mm7, %mm4 C m 0
+ paddq %mm0, %mm6 C m 0
+ movd (%eax), %mm3 C m 0
+ movd %mm6, -12(%edx) C m 0
+ psrlq $32, %mm6 C m 0
+ pmuludq %mm7, %mm3 C m 0
+ paddq %mm1, %mm6 C m 0
+ movd 4(%eax), %mm0 C m 0
+ movd %mm6, -8(%edx) C m 0
+ psrlq $32, %mm6 C m 0
+ pmuludq %mm7, %mm0 C m 0
+ paddq %mm4, %mm6 C m 0
+ movd 8(%eax), %mm1 C m 0
+ movd %mm6, -4(%edx) C m 0
+ psrlq $32, %mm6 C m 0
+L(m00): pmuludq %mm7, %mm1 C m 0
+ paddq %mm3, %mm6 C m 0
+ movd 12(%eax), %mm4 C m 0
+ movd %mm6, (%edx) C m 0
+ psrlq $32, %mm6 C m 0
+ lea 16(%eax), %eax C m 0
+ lea 16(%edx), %edx C m 0
+ sub $4, %ecx C m 0
+ ja L(lpm0) C m 0
+ pmuludq %mm7, %mm4 C m 0
+ paddq %mm0, %mm6 C m 0
+ movd %mm6, -12(%edx) C m 0
+ psrlq $32, %mm6 C m 0
+ paddq %mm1, %mm6 C m 0
+ jmp L(3)
+
+L(outer):
+ lea 8(%edi), %edi C rp += 2
+ movd (%esi), %mm7 C am 3
+ mov %edi, %edx C rp2 = rp am 3
+ lea 4(%esi), %esi C up++ am 3
+ lea (%esi), %eax C up2 = up am 3
+ movd (%eax), %mm0 C am 3
+ lea (%ebx), %ecx C inner loop count am 3
+ pxor %mm6, %mm6 C am 3
+ pmuludq %mm7, %mm0 C am 3
+ movd 4(%eax), %mm1 C am 3
+ movd (%edx), %mm4 C am 3
+ pmuludq %mm7, %mm1 C am 3
+ movd 8(%eax), %mm2 C am 3
+ paddq %mm0, %mm4 C am 3
+ movd 4(%edx), %mm5 C am 3
+ jmp L(lam3) C am 3
+ ALIGN(16) C am 3
+L(lam3):
+ pmuludq %mm7, %mm2 C am 3
+ paddq %mm4, %mm6 C am 3
+ movd 12(%eax), %mm3 C am 3
+ paddq %mm1, %mm5 C am 3
+ movd 8(%edx), %mm4 C am 3
+ movd %mm6, (%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ pmuludq %mm7, %mm3 C am 3
+ paddq %mm5, %mm6 C am 3
+ movd 16(%eax), %mm0 C am 3
+ paddq %mm2, %mm4 C am 3
+ movd 12(%edx), %mm5 C am 3
+ movd %mm6, 4(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ pmuludq %mm7, %mm0 C am 3
+ paddq %mm4, %mm6 C am 3
+ movd 20(%eax), %mm1 C am 3
+ paddq %mm3, %mm5 C am 3
+ movd 16(%edx), %mm4 C am 3
+ movd %mm6, 8(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ pmuludq %mm7, %mm1 C am 3
+ paddq %mm5, %mm6 C am 3
+ movd 24(%eax), %mm2 C am 3
+ paddq %mm0, %mm4 C am 3
+ movd 20(%edx), %mm5 C am 3
+ movd %mm6, 12(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ lea 16(%eax), %eax C am 3
+ lea 16(%edx), %edx C am 3
+ sub $4, %ecx C am 3
+ ja L(lam3) C am 3
+ pmuludq %mm7, %mm2 C am 3
+ paddq %mm4, %mm6 C am 3
+ paddq %mm1, %mm5 C am 3
+ movd 8(%edx), %mm4 C am 3
+ movd %mm6, (%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ paddq %mm5, %mm6 C am 3
+ paddq %mm2, %mm4 C am 3
+L(2): movd %mm6, 4(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ paddq %mm4, %mm6 C am 3
+ movd %mm6, 8(%edx) C am 3
+ psrlq $32, %mm6 C am 3
+ movd %mm6, 12(%edx) C am 3
+
+ lea 8(%edi), %edi C rp += 2
+ movd (%esi), %mm7 C am 2
+ mov %edi, %edx C rp2 = rp am 2
+ lea 4(%esi), %esi C up++ am 2
+ lea (%esi), %eax C up2 = up am 2
+ movd (%eax), %mm1 C am 2
+ lea (%ebx), %ecx C inner loop count am 2
+ pxor %mm6, %mm6 C am 2
+ pmuludq %mm7, %mm1 C am 2
+ movd 4(%eax), %mm2 C am 2
+ movd (%edx), %mm5 C am 2
+ pmuludq %mm7, %mm2 C am 2
+ movd 8(%eax), %mm3 C am 2
+ paddq %mm1, %mm5 C am 2
+ movd 4(%edx), %mm4 C am 2
+ jmp L(am10) C am 2
+ ALIGN(16) C am 2
+L(lam2):
+ pmuludq %mm7, %mm2 C am 2
+ paddq %mm4, %mm6 C am 2
+ movd 8(%eax), %mm3 C am 2
+ paddq %mm1, %mm5 C am 2
+ movd 4(%edx), %mm4 C am 2
+ movd %mm6, -4(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+L(am10):
+ pmuludq %mm7, %mm3 C am 2
+ paddq %mm5, %mm6 C am 2
+ movd 12(%eax), %mm0 C am 2
+ paddq %mm2, %mm4 C am 2
+ movd 8(%edx), %mm5 C am 2
+ movd %mm6, (%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ pmuludq %mm7, %mm0 C am 2
+ paddq %mm4, %mm6 C am 2
+ movd 16(%eax), %mm1 C am 2
+ paddq %mm3, %mm5 C am 2
+ movd 12(%edx), %mm4 C am 2
+ movd %mm6, 4(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ pmuludq %mm7, %mm1 C am 2
+ paddq %mm5, %mm6 C am 2
+ movd 20(%eax), %mm2 C am 2
+ paddq %mm0, %mm4 C am 2
+ movd 16(%edx), %mm5 C am 2
+ movd %mm6, 8(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ lea 16(%eax), %eax C am 2
+ lea 16(%edx), %edx C am 2
+ sub $4, %ecx C am 2
+ ja L(lam2) C am 2
+ pmuludq %mm7, %mm2 C am 2
+ paddq %mm4, %mm6 C am 2
+ paddq %mm1, %mm5 C am 2
+ movd 4(%edx), %mm4 C am 2
+ movd %mm6, -4(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ paddq %mm5, %mm6 C am 2
+ paddq %mm2, %mm4 C am 2
+L(1): movd %mm6, (%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ paddq %mm4, %mm6 C am 2
+ movd %mm6, 4(%edx) C am 2
+ psrlq $32, %mm6 C am 2
+ movd %mm6, 8(%edx) C am 2
+
+ lea 8(%edi), %edi C rp += 2
+ movd (%esi), %mm7 C am 1
+ mov %edi, %edx C rp2 = rp am 1
+ lea 4(%esi), %esi C up++ am 1
+ lea (%esi), %eax C up2 = up am 1
+ movd (%eax), %mm2 C am 1
+ lea (%ebx), %ecx C inner loop count am 1
+ pxor %mm6, %mm6 C am 1
+ pmuludq %mm7, %mm2 C am 1
+ movd 4(%eax), %mm3 C am 1
+ movd (%edx), %mm4 C am 1
+ pmuludq %mm7, %mm3 C am 1
+ movd 8(%eax), %mm0 C am 1
+ paddq %mm2, %mm4 C am 1
+ movd 4(%edx), %mm5 C am 1
+ jmp L(am01) C am 1
+ ALIGN(16) C am 1
+L(lam1):
+ pmuludq %mm7, %mm2 C am 1
+ paddq %mm4, %mm6 C am 1
+ movd 4(%eax), %mm3 C am 1
+ paddq %mm1, %mm5 C am 1
+ movd (%edx), %mm4 C am 1
+ movd %mm6, -8(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ pmuludq %mm7, %mm3 C am 1
+ paddq %mm5, %mm6 C am 1
+ movd 8(%eax), %mm0 C am 1
+ paddq %mm2, %mm4 C am 1
+ movd 4(%edx), %mm5 C am 1
+ movd %mm6, -4(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+L(am01):
+ pmuludq %mm7, %mm0 C am 1
+ paddq %mm4, %mm6 C am 1
+ movd 12(%eax), %mm1 C am 1
+ paddq %mm3, %mm5 C am 1
+ movd 8(%edx), %mm4 C am 1
+ movd %mm6, (%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ pmuludq %mm7, %mm1 C am 1
+ paddq %mm5, %mm6 C am 1
+ movd 16(%eax), %mm2 C am 1
+ paddq %mm0, %mm4 C am 1
+ movd 12(%edx), %mm5 C am 1
+ movd %mm6, 4(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ lea 16(%eax), %eax C am 1
+ lea 16(%edx), %edx C am 1
+ sub $4, %ecx C am 1
+ ja L(lam1) C am 1
+ pmuludq %mm7, %mm2 C am 1
+ paddq %mm4, %mm6 C am 1
+ paddq %mm1, %mm5 C am 1
+ movd (%edx), %mm4 C am 1
+ movd %mm6, -8(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ paddq %mm5, %mm6 C am 1
+ paddq %mm2, %mm4 C am 1
+L(0): movd %mm6, -4(%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ paddq %mm4, %mm6 C am 1
+ movd %mm6, (%edx) C am 1
+ psrlq $32, %mm6 C am 1
+ movd %mm6, 4(%edx) C am 1
+
+ lea 8(%edi), %edi C rp += 2
+ movd (%esi), %mm7 C am 0
+ mov %edi, %edx C rp2 = rp am 0
+ lea 4(%esi), %esi C up++ am 0
+ lea (%esi), %eax C up2 = up am 0
+ movd (%eax), %mm3 C am 0
+ lea (%ebx), %ecx C inner loop count am 0
+ pxor %mm6, %mm6 C am 0
+ pmuludq %mm7, %mm3 C am 0
+ movd 4(%eax), %mm0 C am 0
+ movd (%edx), %mm5 C am 0
+ pmuludq %mm7, %mm0 C am 0
+ movd 8(%eax), %mm1 C am 0
+ paddq %mm3, %mm5 C am 0
+ movd 4(%edx), %mm4 C am 0
+ jmp L(am00) C am 0
+ ALIGN(16) C am 0
+L(lam0):
+ pmuludq %mm7, %mm2 C am 0
+ paddq %mm4, %mm6 C am 0
+ movd (%eax), %mm3 C am 0
+ paddq %mm1, %mm5 C am 0
+ movd -4(%edx), %mm4 C am 0
+ movd %mm6, -12(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ pmuludq %mm7, %mm3 C am 0
+ paddq %mm5, %mm6 C am 0
+ movd 4(%eax), %mm0 C am 0
+ paddq %mm2, %mm4 C am 0
+ movd (%edx), %mm5 C am 0
+ movd %mm6, -8(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ pmuludq %mm7, %mm0 C am 0
+ paddq %mm4, %mm6 C am 0
+ movd 8(%eax), %mm1 C am 0
+ paddq %mm3, %mm5 C am 0
+ movd 4(%edx), %mm4 C am 0
+ movd %mm6, -4(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+L(am00):
+ pmuludq %mm7, %mm1 C am 0
+ paddq %mm5, %mm6 C am 0
+ movd 12(%eax), %mm2 C am 0
+ paddq %mm0, %mm4 C am 0
+ movd 8(%edx), %mm5 C am 0
+ movd %mm6, (%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ lea 16(%eax), %eax C am 0
+ lea 16(%edx), %edx C am 0
+ sub $4, %ecx C am 0
+ ja L(lam0) C am 0
+ pmuludq %mm7, %mm2 C am 0
+ paddq %mm4, %mm6 C am 0
+ paddq %mm1, %mm5 C am 0
+ movd -4(%edx), %mm4 C am 0
+ movd %mm6, -12(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ paddq %mm5, %mm6 C am 0
+ paddq %mm2, %mm4 C am 0
+L(3): movd %mm6, -8(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ paddq %mm4, %mm6 C am 0
+ movd %mm6, -4(%edx) C am 0
+ psrlq $32, %mm6 C am 0
+ movd %mm6, (%edx) C am 0
+ sub $4, %ebx C am 0
+ ja L(outer) C am 0
+
+ mov %edi, %edx
+ mov %esi, %eax
+ pop %edi
+ pop %ebx
+ pop %esi
+
+L(am3): C up[un-1..un-3] x up[un-4]
+ lea 8(%edx), %edx C rp2 += 2
+ movd (%eax), %mm7
+ movd 4(%eax), %mm1
+ movd 8(%eax), %mm2
+ movd 12(%eax), %mm3
+ movd (%edx), %mm4
+ pmuludq %mm7, %mm1
+ movd 4(%edx), %mm5
+ pmuludq %mm7, %mm2
+ movd 8(%edx), %mm6
+ pmuludq %mm7, %mm3
+ paddq %mm1, %mm4
+ paddq %mm2, %mm5
+ paddq %mm3, %mm6
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+ paddq %mm5, %mm4
+ movd %mm4, 4(%edx)
+ psrlq $32, %mm4
+ paddq %mm6, %mm4
+ movd %mm4, 8(%edx)
+ psrlq $32, %mm4
+ movd %mm4, 12(%edx) C FIXME feed through!
+ lea 4(%eax), %eax
+
+L(am2): C up[un-1..un-2] x up[un-3]
+ lea 8(%edx), %edx C rp2 += 2
+ movd (%eax), %mm7
+ movd 4(%eax), %mm1
+ movd 8(%eax), %mm2
+ movd (%edx), %mm4
+ movd 4(%edx), %mm5
+ pmuludq %mm7, %mm1
+ pmuludq %mm7, %mm2
+ paddq %mm1, %mm4
+ paddq %mm2, %mm5
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+ paddq %mm5, %mm4
+ movd %mm4, 4(%edx)
+ psrlq $32, %mm4
+ movd %mm4, 8(%edx) C FIXME feed through!
+ lea 4(%eax), %eax
+
+L(am1): C up[un-1] x up[un-2]
+ lea 8(%edx), %edx C rp2 += 2
+ movd (%eax), %mm7
+ movd 4(%eax), %mm2
+ movd (%edx), %mm4
+ pmuludq %mm7, %mm2
+ paddq %mm2, %mm4
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+ movd %mm4, 4(%edx)
+
+C *** diag stuff, use elementary code for now
+
+ mov 4(%esp), %edx C rp
+ mov 8(%esp), %eax C up
+ mov 12(%esp), %ecx C un
+
+ movd (%eax), %mm2
+ pmuludq %mm2, %mm2 C src[0]^2
+
+ pcmpeqd %mm7, %mm7
+ psrlq $32, %mm7
+
+ movd 4(%edx), %mm3 C dst[1]
+
+ movd %mm2, (%edx)
+ psrlq $32, %mm2
+
+ psllq $1, %mm3 C 2*dst[1]
+ paddq %mm3, %mm2
+ movd %mm2, 4(%edx)
+ psrlq $32, %mm2
+
+ sub $2, %ecx
+
+L(diag):
+ movd 4(%eax), %mm0 C src limb
+ add $4, %eax
+ pmuludq %mm0, %mm0
+ movq %mm7, %mm1
+ pand %mm0, %mm1 C diagonal low
+ psrlq $32, %mm0 C diagonal high
+
+ movd 8(%edx), %mm3
+ psllq $1, %mm3 C 2*dst[i]
+ paddq %mm3, %mm1
+ paddq %mm1, %mm2
+ movd %mm2, 8(%edx)
+ psrlq $32, %mm2
+
+ movd 12(%edx), %mm3
+ psllq $1, %mm3 C 2*dst[i+1]
+ paddq %mm3, %mm0
+ paddq %mm0, %mm2
+ movd %mm2, 12(%edx)
+ add $8, %edx
+ psrlq $32, %mm2
+
+ sub $1, %ecx
+ jnz L(diag)
+
+ movd 4(%eax), %mm0 C src[size-1]
+ pmuludq %mm0, %mm0
+ pand %mm0, %mm7 C diagonal low
+ psrlq $32, %mm0 C diagonal high
+
+ movd 8(%edx), %mm3 C dst[2*size-2]
+ psllq $1, %mm3
+ paddq %mm3, %mm7
+ paddq %mm7, %mm2
+ movd %mm2, 8(%edx)
+ psrlq $32, %mm2
+
+ paddq %mm0, %mm2
+ movd %mm2, 12(%edx) C dst[2*size-1]
+
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/sub_n.asm b/gmp/mpn/x86/pentium4/sse2/sub_n.asm
new file mode 100644
index 0000000000..5ba1c018ec
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/sub_n.asm
@@ -0,0 +1,119 @@
+dnl Intel Pentium-4 mpn_sub_n -- mpn subtraction.
+
+dnl Copyright 2001, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C dst!=src1,2 dst==src1 dst==src2
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) ?
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) 4 6 6
+C P4 model 3-4 (Prescott) 4.25 7.5 7.5
+
+defframe(PARAM_CARRY,20)
+defframe(PARAM_SIZE, 16)
+defframe(PARAM_SRC2, 12)
+defframe(PARAM_SRC1, 8)
+defframe(PARAM_DST, 4)
+
+dnl re-use parameter space
+define(SAVE_EBX,`PARAM_SRC1')
+
+ TEXT
+ ALIGN(8)
+
+PROLOGUE(mpn_sub_nc)
+deflit(`FRAME',0)
+ movd PARAM_CARRY, %mm0
+ jmp L(start_nc)
+EPILOGUE()
+
+ ALIGN(8)
+PROLOGUE(mpn_sub_n)
+deflit(`FRAME',0)
+ pxor %mm0, %mm0
+L(start_nc):
+ mov PARAM_SRC1, %eax
+ mov %ebx, SAVE_EBX
+ mov PARAM_SRC2, %ebx
+ mov PARAM_DST, %edx
+ mov PARAM_SIZE, %ecx
+
+ lea (%eax,%ecx,4), %eax C src1 end
+ lea (%ebx,%ecx,4), %ebx C src2 end
+ lea (%edx,%ecx,4), %edx C dst end
+ neg %ecx C -size
+
+L(top):
+ C eax src1 end
+ C ebx src2 end
+ C ecx counter, limbs, negative
+ C edx dst end
+ C mm0 carry bit
+
+ movd (%eax,%ecx,4), %mm1
+ movd (%ebx,%ecx,4), %mm2
+ psubq %mm2, %mm1
+
+ psubq %mm0, %mm1
+ movd %mm1, (%edx,%ecx,4)
+
+ psrlq $63, %mm1
+
+ add $1, %ecx
+ jz L(done_mm1)
+
+ movd (%eax,%ecx,4), %mm0
+ movd (%ebx,%ecx,4), %mm2
+ psubq %mm2, %mm0
+
+ psubq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $63, %mm0
+
+ add $1, %ecx
+ jnz L(top)
+
+ movd %mm0, %eax
+ mov SAVE_EBX, %ebx
+ emms
+ ret
+
+L(done_mm1):
+ movd %mm1, %eax
+ mov SAVE_EBX, %ebx
+ emms
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/pentium4/sse2/submul_1.asm b/gmp/mpn/x86/pentium4/sse2/submul_1.asm
new file mode 100644
index 0000000000..020675bd7b
--- /dev/null
+++ b/gmp/mpn/x86/pentium4/sse2/submul_1.asm
@@ -0,0 +1,182 @@
+dnl Intel Pentium-4 mpn_submul_1 -- Multiply a limb vector with a limb and
+dnl subtract the result from a second limb vector.
+
+dnl Copyright 2001, 2002, 2008, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P6 model 0-8,10-12 -
+C P6 model 9 (Banias) 6.8
+C P6 model 13 (Dothan) 6.9
+C P4 model 0-1 (Willamette) ?
+C P4 model 2 (Northwood) 5.87
+C P4 model 3-4 (Prescott) 6.5
+
+C This code represents a step forwards compared to the code available before
+C GMP 5.1, but it is not carefully tuned for either P6 or P4. In fact, it is
+C not good for P6. For P4 it saved a bit over 1 c/l for both Northwood and
+C Prescott compared to the old code.
+C
+C The arrangements made here to get a two instruction dependent chain are
+C slightly subtle. In the loop the carry (or borrow rather) is a negative so
+C that a paddq can be used to give a low limb ready to store, and a high limb
+C ready to become the new carry after a psrlq.
+C
+C If the carry was a simple twos complement negative then the psrlq shift would
+C need to bring in 0 bits or 1 bits according to whether the high was zero or
+C non-zero, since a non-zero value would represent a negative needing sign
+C extension. That wouldn't be particularly easy to arrange and certainly would
+C add an instruction to the dependent chain, so instead an offset is applied so
+C that the high limb will be 0xFFFFFFFF+c. With c in the range -0xFFFFFFFF to
+C 0, the value 0xFFFFFFFF+c is in the range 0 to 0xFFFFFFFF and is therefore
+C always positive and can always have 0 bits shifted in, which is what psrlq
+C does.
+C
+C The extra 0xFFFFFFFF must be subtracted before c is used, but that can be
+C done off the dependent chain. The total adjustment then is to add
+C 0xFFFFFFFF00000000 to offset the new carry, and subtract 0x00000000FFFFFFFF
+C to remove the offset from the current carry, for a net add of
+C 0xFFFFFFFE00000001. In the code this is applied to the destination limb when
+C fetched.
+C
+C It's also possible to view the 0xFFFFFFFF adjustment as a ones-complement
+C negative, which is how it's undone for the return value, but that doesn't
+C seem as clear.
+
+defframe(PARAM_CARRY, 20)
+defframe(PARAM_MULTIPLIER,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(16)
+
+PROLOGUE(mpn_submul_1c)
+deflit(`FRAME',0)
+ movd PARAM_CARRY, %mm1
+ jmp L(start_1c)
+EPILOGUE()
+
+PROLOGUE(mpn_submul_1)
+deflit(`FRAME',0)
+ pxor %mm1, %mm1 C initial borrow
+
+L(start_1c):
+ mov PARAM_SRC, %eax
+ pcmpeqd %mm0, %mm0
+
+ movd PARAM_MULTIPLIER, %mm7
+ pcmpeqd %mm6, %mm6
+
+ mov PARAM_DST, %edx
+ psrlq $32, %mm0 C 0x00000000FFFFFFFF
+
+ mov PARAM_SIZE, %ecx
+ psllq $32, %mm6 C 0xFFFFFFFF00000000
+
+ psubq %mm0, %mm6 C 0xFFFFFFFE00000001
+
+ psubq %mm1, %mm0 C 0xFFFFFFFF - borrow
+
+
+ movd (%eax), %mm3 C up
+ movd (%edx), %mm4 C rp
+
+ add $-1, %ecx
+ paddq %mm6, %mm4 C add 0xFFFFFFFE00000001
+ pmuludq %mm7, %mm3
+ jnz L(gt1)
+ psubq %mm3, %mm4 C prod
+ paddq %mm4, %mm0 C borrow
+ movd %mm0, (%edx) C result
+ jmp L(rt)
+
+L(gt1): movd 4(%eax), %mm1 C up
+ movd 4(%edx), %mm2 C rp
+
+ add $-1, %ecx
+ jz L(eev)
+
+ ALIGN(16)
+L(top): paddq %mm6, %mm2 C add 0xFFFFFFFE00000001
+ pmuludq %mm7, %mm1
+ psubq %mm3, %mm4 C prod
+ movd 8(%eax), %mm3 C up
+ paddq %mm4, %mm0 C borrow
+ movd 8(%edx), %mm4 C rp
+ movd %mm0, (%edx) C result
+ psrlq $32, %mm0
+
+ add $-1, %ecx
+ jz L(eod)
+
+ paddq %mm6, %mm4 C add 0xFFFFFFFE00000001
+ pmuludq %mm7, %mm3
+ psubq %mm1, %mm2 C prod
+ movd 12(%eax), %mm1 C up
+ paddq %mm2, %mm0 C borrow
+ movd 12(%edx), %mm2 C rp
+ movd %mm0, 4(%edx) C result
+ psrlq $32, %mm0
+
+ lea 8(%eax), %eax
+ lea 8(%edx), %edx
+ add $-1, %ecx
+ jnz L(top)
+
+
+L(eev): paddq %mm6, %mm2 C add 0xFFFFFFFE00000001
+ pmuludq %mm7, %mm1
+ psubq %mm3, %mm4 C prod
+ paddq %mm4, %mm0 C borrow
+ movd %mm0, (%edx) C result
+ psrlq $32, %mm0
+ psubq %mm1, %mm2 C prod
+ paddq %mm2, %mm0 C borrow
+ movd %mm0, 4(%edx) C result
+L(rt): psrlq $32, %mm0
+ movd %mm0, %eax
+ not %eax
+ emms
+ ret
+
+L(eod): paddq %mm6, %mm4 C add 0xFFFFFFFE00000001
+ pmuludq %mm7, %mm3
+ psubq %mm1, %mm2 C prod
+ paddq %mm2, %mm0 C borrow
+ movd %mm0, 4(%edx) C result
+ psrlq $32, %mm0
+ psubq %mm3, %mm4 C prod
+ paddq %mm4, %mm0 C borrow
+ movd %mm0, 8(%edx) C result
+ jmp L(rt)
+EPILOGUE()
diff --git a/gmp/mpn/x86/rshift.asm b/gmp/mpn/x86/rshift.asm
new file mode 100644
index 0000000000..a60dcaa4b2
--- /dev/null
+++ b/gmp/mpn/x86/rshift.asm
@@ -0,0 +1,108 @@
+dnl x86 mpn_rshift -- mpn right shift.
+
+dnl Copyright 1992, 1994, 1996, 1999-2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P54 7.5
+C P55 7.0
+C P6 2.5
+C K6 4.5
+C K7 5.0
+C P4 16.5
+
+
+C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
+C unsigned shift);
+
+defframe(PARAM_SHIFT,16)
+defframe(PARAM_SIZE, 12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_rshift)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+deflit(`FRAME',12)
+
+ movl PARAM_DST,%edi
+ movl PARAM_SRC,%esi
+ movl PARAM_SIZE,%edx
+ movl PARAM_SHIFT,%ecx
+
+ leal -4(%edi,%edx,4),%edi
+ leal (%esi,%edx,4),%esi
+ negl %edx
+
+ movl (%esi,%edx,4),%ebx C read least significant limb
+ xorl %eax,%eax
+ shrdl( %cl, %ebx, %eax) C compute carry limb
+ incl %edx
+ jz L(end)
+ pushl %eax C push carry limb onto stack
+ testb $1,%dl
+ jnz L(1) C enter loop in the middle
+ movl %ebx,%eax
+
+ ALIGN(8)
+L(oop): movl (%esi,%edx,4),%ebx C load next higher limb
+ shrdl( %cl, %ebx, %eax) C compute result limb
+ movl %eax,(%edi,%edx,4) C store it
+ incl %edx
+L(1): movl (%esi,%edx,4),%eax
+ shrdl( %cl, %eax, %ebx)
+ movl %ebx,(%edi,%edx,4)
+ incl %edx
+ jnz L(oop)
+
+ shrl %cl,%eax C compute most significant limb
+ movl %eax,(%edi) C store it
+
+ popl %eax C pop carry limb
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+L(end): shrl %cl,%ebx C compute most significant limb
+ movl %ebx,(%edi) C store it
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/sec_tabselect.asm b/gmp/mpn/x86/sec_tabselect.asm
new file mode 100644
index 0000000000..c7c2e059f1
--- /dev/null
+++ b/gmp/mpn/x86/sec_tabselect.asm
@@ -0,0 +1,115 @@
+dnl x86 mpn_sec_tabselect.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C P5 ?
+C P6 model 0-8,10-12 ?
+C P6 model 9 (Banias) ?
+C P6 model 13 (Dothan) ?
+C P4 model 0 (Willamette) ?
+C P4 model 1 (?) ?
+C P4 model 2 (Northwood) 4.5
+C P4 model 3 (Prescott) ?
+C P4 model 4 (Nocona) ?
+C Intel Atom ?
+C AMD K6 ?
+C AMD K7 3.4
+C AMD K8 ?
+C AMD K10 ?
+
+C NOTES
+C * This has not been tuned for any specific processor. Its speed should not
+C be too bad, though.
+C * Using SSE2 could result in many-fold speedup.
+
+C mpn_sec_tabselect (mp_limb_t *rp, mp_limb_t *tp, mp_size_t n, mp_size_t nents, mp_size_t which)
+define(`rp', `%edi')
+define(`tp', `%esi')
+define(`n', `%ebx')
+define(`nents', `%ecx')
+define(`which', `36(%esp)')
+
+define(`i', `%ebp')
+define(`maskp', `20(%esp)')
+define(`maskn', `32(%esp)')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sec_tabselect)
+ push %edi
+ push %esi
+ push %ebx
+ push %ebp
+ mov 20(%esp), rp
+ mov 24(%esp), tp
+ mov 28(%esp), n
+ mov 32(%esp), nents
+
+ lea (rp,n,4), rp
+ lea (tp,n,4), tp
+ sub nents, which
+L(outer):
+ mov which, %eax
+ add nents, %eax
+ neg %eax C set CF iff 'which' != k
+ sbb %eax, %eax
+ mov %eax, maskn
+ not %eax
+ mov %eax, maskp
+
+ mov n, i
+ neg i
+
+ ALIGN(16)
+L(top): mov (tp,i,4), %eax
+ and maskp, %eax
+ mov (rp,i,4), %edx
+ and maskn, %edx
+ or %edx, %eax
+ mov %eax, (rp,i,4)
+ inc i
+ js L(top)
+
+L(end): mov n, %eax
+ lea (tp,%eax,4), tp
+ dec nents
+ jne L(outer)
+
+L(outer_end):
+ pop %ebp
+ pop %ebx
+ pop %esi
+ pop %edi
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/sqr_basecase.asm b/gmp/mpn/x86/sqr_basecase.asm
new file mode 100644
index 0000000000..39f8a89805
--- /dev/null
+++ b/gmp/mpn/x86/sqr_basecase.asm
@@ -0,0 +1,359 @@
+dnl x86 generic mpn_sqr_basecase -- square an mpn number.
+
+dnl Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+
+C cycles/crossproduct cycles/triangleproduct
+C P5
+C P6
+C K6
+C K7
+C P4
+
+
+C void mpn_sqr_basecase (mp_ptr dst, mp_srcptr src, mp_size_t size);
+C
+C The algorithm is basically the same as mpn/generic/sqr_basecase.c, but a
+C lot of function call overheads are avoided, especially when the size is
+C small.
+C
+C The mul1 loop is not unrolled like mul_1.asm, it doesn't seem worth the
+C code size to do so here.
+C
+C Enhancements:
+C
+C The addmul loop here is also not unrolled like aorsmul_1.asm and
+C mul_basecase.asm are. Perhaps it should be done. It'd add to the
+C complexity, but if it's worth doing in the other places then it should be
+C worthwhile here.
+C
+C A fully-unrolled style like other sqr_basecase.asm versions (k6, k7, p6)
+C might be worth considering. That'd add quite a bit to the code size, but
+C only as much as is used would be dragged into L1 cache.
+
+defframe(PARAM_SIZE,12)
+defframe(PARAM_SRC, 8)
+defframe(PARAM_DST, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_sqr_basecase)
+deflit(`FRAME',0)
+
+ movl PARAM_SIZE, %edx
+
+ movl PARAM_SRC, %eax
+
+ cmpl $2, %edx
+ movl PARAM_DST, %ecx
+
+ je L(two_limbs)
+ ja L(three_or_more)
+
+
+C -----------------------------------------------------------------------------
+C one limb only
+ C eax src
+ C ebx
+ C ecx dst
+ C edx
+
+ movl (%eax), %eax
+ mull %eax
+ movl %eax, (%ecx)
+ movl %edx, 4(%ecx)
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(8)
+L(two_limbs):
+ C eax src
+ C ebx
+ C ecx dst
+ C edx
+
+ pushl %ebx
+ pushl %ebp
+
+ movl %eax, %ebx
+ movl (%eax), %eax
+
+ mull %eax C src[0]^2
+
+ pushl %esi
+ pushl %edi
+
+ movl %edx, %esi C dst[1]
+ movl %eax, (%ecx) C dst[0]
+
+ movl 4(%ebx), %eax
+ mull %eax C src[1]^2
+
+ movl %eax, %edi C dst[2]
+ movl %edx, %ebp C dst[3]
+
+ movl (%ebx), %eax
+ mull 4(%ebx) C src[0]*src[1]
+
+ addl %eax, %esi
+
+ adcl %edx, %edi
+
+ adcl $0, %ebp
+ addl %esi, %eax
+
+ adcl %edi, %edx
+ movl %eax, 4(%ecx)
+
+ adcl $0, %ebp
+
+ movl %edx, 8(%ecx)
+ movl %ebp, 12(%ecx)
+
+ popl %edi
+ popl %esi
+
+ popl %ebp
+ popl %ebx
+
+ ret
+
+
+C -----------------------------------------------------------------------------
+ ALIGN(8)
+L(three_or_more):
+deflit(`FRAME',0)
+ C eax src
+ C ebx
+ C ecx dst
+ C edx size
+
+ pushl %ebx FRAME_pushl()
+ pushl %edi FRAME_pushl()
+
+ pushl %esi FRAME_pushl()
+ pushl %ebp FRAME_pushl()
+
+ leal (%ecx,%edx,4), %edi C &dst[size], end of this mul1
+ leal (%eax,%edx,4), %esi C &src[size]
+
+C First multiply src[0]*src[1..size-1] and store at dst[1..size].
+
+ movl (%eax), %ebp C src[0], multiplier
+ movl %edx, %ecx
+
+ negl %ecx C -size
+ xorl %ebx, %ebx C clear carry limb
+
+ incl %ecx C -(size-1)
+
+L(mul1):
+ C eax scratch
+ C ebx carry
+ C ecx counter, limbs, negative
+ C edx scratch
+ C esi &src[size]
+ C edi &dst[size]
+ C ebp multiplier
+
+ movl (%esi,%ecx,4), %eax
+ mull %ebp
+ addl %eax, %ebx
+ adcl $0, %edx
+ movl %ebx, (%edi,%ecx,4)
+ movl %edx, %ebx
+ incl %ecx
+ jnz L(mul1)
+
+ movl %ebx, (%edi)
+
+
+ C Add products src[n]*src[n+1..size-1] at dst[2*n-1...], for
+ C n=1..size-2.
+ C
+ C The last products src[size-2]*src[size-1], which is the end corner
+ C of the product triangle, is handled separately at the end to save
+ C looping overhead. If size is 3 then it's only this that needs to
+ C be done.
+ C
+ C In the outer loop %esi is a constant, and %edi just advances by 1
+ C limb each time. The size of the operation decreases by 1 limb
+ C each time.
+
+ C eax
+ C ebx carry (needing carry flag added)
+ C ecx
+ C edx
+ C esi &src[size]
+ C edi &dst[size]
+ C ebp
+
+ movl PARAM_SIZE, %ecx
+ subl $3, %ecx
+ jz L(corner)
+
+ negl %ecx
+
+dnl re-use parameter space
+define(VAR_OUTER,`PARAM_DST')
+
+L(outer):
+ C eax
+ C ebx
+ C ecx
+ C edx outer loop counter, -(size-3) to -1
+ C esi &src[size]
+ C edi dst, pointing at stored carry limb of previous loop
+ C ebp
+
+ movl %ecx, VAR_OUTER
+ addl $4, %edi C advance dst end
+
+ movl -8(%esi,%ecx,4), %ebp C next multiplier
+ subl $1, %ecx
+
+ xorl %ebx, %ebx C initial carry limb
+
+L(inner):
+ C eax scratch
+ C ebx carry (needing carry flag added)
+ C ecx counter, -n-1 to -1
+ C edx scratch
+ C esi &src[size]
+ C edi dst end of this addmul
+ C ebp multiplier
+
+ movl (%esi,%ecx,4), %eax
+ mull %ebp
+ addl %ebx, %eax
+ adcl $0, %edx
+ addl %eax, (%edi,%ecx,4)
+ adcl $0, %edx
+ movl %edx, %ebx
+ addl $1, %ecx
+ jl L(inner)
+
+
+ movl %ebx, (%edi)
+ movl VAR_OUTER, %ecx
+ incl %ecx
+ jnz L(outer)
+
+
+L(corner):
+ C esi &src[size]
+ C edi &dst[2*size-3]
+
+ movl -4(%esi), %eax
+ mull -8(%esi) C src[size-1]*src[size-2]
+ addl %eax, 0(%edi)
+ adcl $0, %edx
+ movl %edx, 4(%edi) C dst high limb
+
+
+C -----------------------------------------------------------------------------
+C Left shift of dst[1..2*size-2], high bit shifted out becomes dst[2*size-1].
+
+ movl PARAM_SIZE, %eax
+ negl %eax
+ addl $1, %eax C -(size-1) and clear carry
+
+L(lshift):
+ C eax counter, negative
+ C ebx next limb
+ C ecx
+ C edx
+ C esi
+ C edi &dst[2*size-4]
+ C ebp
+
+ rcll 8(%edi,%eax,8)
+ rcll 12(%edi,%eax,8)
+ incl %eax
+ jnz L(lshift)
+
+
+ adcl %eax, %eax C high bit out
+ movl %eax, 8(%edi) C dst most significant limb
+
+
+C Now add in the squares on the diagonal, namely src[0]^2, src[1]^2, ...,
+C src[size-1]^2. dst[0] hasn't yet been set at all yet, and just gets the
+C low limb of src[0]^2.
+
+ movl PARAM_SRC, %esi
+ movl (%esi), %eax C src[0]
+ mull %eax C src[0]^2
+
+ movl PARAM_SIZE, %ecx
+ leal (%esi,%ecx,4), %esi C src end
+
+ negl %ecx C -size
+ movl %edx, %ebx C initial carry
+
+ movl %eax, 12(%edi,%ecx,8) C dst[0]
+ incl %ecx C -(size-1)
+
+L(diag):
+ C eax scratch (low product)
+ C ebx carry limb
+ C ecx counter, -(size-1) to -1
+ C edx scratch (high product)
+ C esi &src[size]
+ C edi &dst[2*size-3]
+ C ebp scratch (fetched dst limbs)
+
+ movl (%esi,%ecx,4), %eax
+ mull %eax
+
+ addl %ebx, 8(%edi,%ecx,8)
+ movl %edx, %ebx
+
+ adcl %eax, 12(%edi,%ecx,8)
+ adcl $0, %ebx
+
+ incl %ecx
+ jnz L(diag)
+
+
+ addl %ebx, 8(%edi) C dst most significant limb
+
+ popl %ebp
+ popl %esi
+
+ popl %edi
+ popl %ebx
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86/t-zdisp.sh b/gmp/mpn/x86/t-zdisp.sh
new file mode 100755
index 0000000000..61efdd6c4f
--- /dev/null
+++ b/gmp/mpn/x86/t-zdisp.sh
@@ -0,0 +1,71 @@
+#! /bin/sh
+#
+# Copyright 2000 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: cd $(builddir)/mpn
+# $(srcdir)/x86/t-zdisp.sh
+#
+# Run the Zdisp() macro instructions through the assembler to check
+# the encodings used. Mismatches are printed, no output means all ok.
+#
+# This program is only meant for use during development. It can be
+# run in the mpn build directory of any x86 configuration.
+#
+# For this test the assembler needs to generate byte sized 0
+# displacements when given something like 0(%eax). Recent versions of
+# gas are suitable (eg. 2.9.x or 2.10.x).
+
+set -e
+
+cat >tmp-zdisptest.asm <<\EOF
+
+include(`../config.m4')
+
+dnl Redefine Zdisp_match to output its pattern and encoding.
+define(`Zdisp_match',
+`define(`Zdisp_found',1)dnl
+ifelse(`$2',0,` $1 $2$3, $4')`'dnl
+ifelse(`$3',0,` $1 $2, $3$4')`'dnl
+
+ .byte $5
+')
+ .text
+ Zdisp()
+EOF
+
+m4 tmp-zdisptest.asm >tmp-zdisptest.s
+as -o tmp-zdisptest.o tmp-zdisptest.s
+
+# Demand duplicates from the instruction patterns and byte encodings.
+objdump -d tmp-zdisptest.o | awk '
+/^ *[a-z0-9]+:/ {
+ sub(/^ *[a-z0-9]+:/,"")
+ print
+}' | sort | uniq -u
diff --git a/gmp/mpn/x86/t-zdisp2.pl b/gmp/mpn/x86/t-zdisp2.pl
new file mode 100755
index 0000000000..b441b6579a
--- /dev/null
+++ b/gmp/mpn/x86/t-zdisp2.pl
@@ -0,0 +1,147 @@
+#!/usr/bin/perl -w
+#
+# Copyright 2001, 2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: cd $(builddir)/mpn
+# $(srcdir)/x86/t-zdisp2.pl
+#
+# Grep for any "0(reg...)" addressing modes coming out of the x86 .asm
+# files. Additive expressions like "12+4-16" are recognised too.
+#
+# Old gas doesn't preserve the "0" displacement, so if it's wanted then
+# Zdisp ought to be used to give explicit .byte sequences. See
+# mpn/x86/README.
+#
+# No output means everything is ok. All the asm files are put through m4 in
+# PIC and non-PIC modes, and in each multi-function form, all of which can
+# take a while to run.
+#
+# This program is only meant for use during development.
+
+use strict;
+use File::Find;
+use File::Basename;
+use Getopt::Std;
+
+my %opt;
+getopts('t', \%opt);
+
+
+my $srcdir;
+open IN, '<Makefile' or die;
+while (<IN>) {
+ if (/^srcdir[ \t]*=[ \t]*(.*)/) {
+ $srcdir = $1;
+ last;
+ }
+}
+close IN or die;
+defined $srcdir or die "Cannot find \$srcdir in Makefile\n";
+
+my $filecount = 0;
+
+my $tempfile = 't-zdisp2.tmp';
+open KARA, ">$tempfile" or die;
+close KARA or die;
+
+find({ wanted => \&process, preprocess => \&process_mparam, no_chdir => 1 },
+ "$srcdir/x86");
+
+sub process {
+ if (/gmp-mparam.h$/) {
+ process_mparam($_);
+ } elsif (/\.asm$/) {
+ process_asm($_);
+ }
+}
+
+# Ensure we're using the right SQR_TOOM2_THRESHOLD for the part of the
+# tree being processed.
+sub process_mparam {
+ my $file = "$File::Find::dir/gmp-mparam.h";
+ if (-f $file) {
+ print "$file\n" if $opt{'t'};
+ open MPARAM, "<$file" or die;
+ while (<MPARAM>) {
+ if (/^#define SQR_TOOM2_THRESHOLD[ \t]*([0-9][0-9]*)/) {
+ open KARA, ">$tempfile" or die;
+ print KARA "define(\`SQR_TOOM2_THRESHOLD',$1)\n\n";
+ print "define(\`SQR_TOOM2_THRESHOLD',$1)\n" if $opt{'t'};
+ close KARA or die;
+ last;
+ }
+ }
+ close MPARAM or die;
+ }
+ return @_;
+}
+
+sub process_asm {
+ my ($file) = @_;
+ my $base = basename ($file, '.asm');
+
+ my @funs;
+ if ($base eq 'aors_n') { @funs = qw(add_n sub_n); }
+ elsif ($base eq 'aorsmul_1') { @funs = qw(addmul_1 submul_1); }
+ elsif ($base eq 'popham') { @funs = qw(popcount hamdist); }
+ elsif ($base eq 'logops_n') { @funs = qw(and_n andn_n nand_n ior_n iorn_n nior_n xor_n xnor_n); }
+ elsif ($base eq 'lorrshift') { @funs = qw(lshift rshift); }
+ else { @funs = ($base); }
+
+ foreach my $fun (@funs) {
+ foreach my $pic ('', ' -DPIC') {
+ my $header = "$file: 0: $pic\n";
+ $filecount++;
+
+ my $m4 = "m4 -DHAVE_HOST_CPU_athlon -DOPERATION_$fun $pic ../config.m4 $tempfile $file";
+ print "$m4\n" if $opt{'t'};
+
+ open IN, "$m4 |" or die;
+ while (<IN>) {
+ next unless /([0-9+-][0-9 \t+-]*)\(%/;
+ my $pat=$1;
+ $pat = eval($pat);
+ next if ($pat != 0);
+ print "$header$_";
+ $header='';
+ }
+ close IN or die;
+ }
+ }
+}
+
+unlink($tempfile);
+print "total $filecount processed\n";
+exit 0;
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/gmp/mpn/x86/udiv.asm b/gmp/mpn/x86/udiv.asm
new file mode 100644
index 0000000000..a3ee08860f
--- /dev/null
+++ b/gmp/mpn/x86/udiv.asm
@@ -0,0 +1,52 @@
+dnl x86 mpn_udiv_qrnnd -- 2 by 1 limb division
+
+dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C mp_limb_t mpn_udiv_qrnnd (mp_limb_t *remptr, mp_limb_t high, mp_limb_t low,
+C mp_limb_t divisor);
+
+defframe(PARAM_DIVISOR, 16)
+defframe(PARAM_LOW, 12)
+defframe(PARAM_HIGH, 8)
+defframe(PARAM_REMPTR, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_udiv_qrnnd)
+deflit(`FRAME',0)
+ movl PARAM_LOW, %eax
+ movl PARAM_HIGH, %edx
+ divl PARAM_DIVISOR
+ movl PARAM_REMPTR, %ecx
+ movl %edx, (%ecx)
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/umul.asm b/gmp/mpn/x86/umul.asm
new file mode 100644
index 0000000000..34fe434400
--- /dev/null
+++ b/gmp/mpn/x86/umul.asm
@@ -0,0 +1,51 @@
+dnl mpn_umul_ppmm -- 1x1->2 limb multiplication
+
+dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C mp_limb_t mpn_umul_ppmm (mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2);
+C
+
+defframe(PARAM_M2, 12)
+defframe(PARAM_M1, 8)
+defframe(PARAM_LOWPTR, 4)
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(mpn_umul_ppmm)
+deflit(`FRAME',0)
+ movl PARAM_LOWPTR, %ecx
+ movl PARAM_M1, %eax
+ mull PARAM_M2
+ movl %eax, (%ecx)
+ movl %edx, %eax
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86/x86-defs.m4 b/gmp/mpn/x86/x86-defs.m4
new file mode 100644
index 0000000000..1538b6820c
--- /dev/null
+++ b/gmp/mpn/x86/x86-defs.m4
@@ -0,0 +1,999 @@
+divert(-1)
+
+
+dnl m4 macros for x86 assembler.
+
+
+dnl Copyright 1999-2003, 2007, 2010, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Notes:
+dnl
+dnl m4 isn't perfect for processing BSD style x86 assembler code, the main
+dnl problems are,
+dnl
+dnl 1. Doing define(foo,123) and then using foo in an addressing mode like
+dnl foo(%ebx) expands as a macro rather than a constant. This is worked
+dnl around by using deflit() from asm-defs.m4, instead of define().
+dnl
+dnl 2. Immediates in macro definitions need a space or `' to stop the $
+dnl looking like a macro parameter. For example,
+dnl
+dnl define(foo, `mov $ 123, %eax')
+dnl
+dnl This is only a problem in macro definitions, not in ordinary text,
+dnl and not in macro parameters like text passed to forloop() or ifdef().
+
+
+deflit(GMP_LIMB_BYTES, 4)
+
+
+dnl Libtool gives -DPIC -DDLL_EXPORT to indicate a cygwin or mingw DLL. We
+dnl undefine PIC since we don't need to be position independent in this
+dnl case and definitely don't want the ELF style _GLOBAL_OFFSET_TABLE_ etc.
+
+ifdef(`DLL_EXPORT',`undefine(`PIC')')
+
+
+dnl Usage: CPUVEC_FUNCS_LIST
+dnl
+dnl A list of the functions from gmp-impl.h x86 struct cpuvec_t, in the
+dnl order they appear in that structure.
+
+define(CPUVEC_FUNCS_LIST,
+``add_n',
+`addlsh1_n',
+`addlsh2_n',
+`addmul_1',
+`addmul_2',
+`bdiv_dbm1c',
+`cnd_add_n',
+`cnd_sub_n',
+`com',
+`copyd',
+`copyi',
+`divexact_1',
+`divrem_1',
+`gcd_1',
+`lshift',
+`lshiftc',
+`mod_1',
+`mod_1_1p',
+`mod_1_1p_cps',
+`mod_1s_2p',
+`mod_1s_2p_cps',
+`mod_1s_4p',
+`mod_1s_4p_cps',
+`mod_34lsub1',
+`modexact_1c_odd',
+`mul_1',
+`mul_basecase',
+`mullo_basecase',
+`preinv_divrem_1',
+`preinv_mod_1',
+`redc_1',
+`redc_2',
+`rshift',
+`sqr_basecase',
+`sub_n',
+`sublsh1_n',
+`submul_1'')
+
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+dnl In the x86 code we use explicit TEXT and ALIGN() calls in the code,
+dnl since different alignments are wanted in various circumstances. So for
+dnl instance,
+dnl
+dnl TEXT
+dnl ALIGN(16)
+dnl PROLOGUE(mpn_add_n)
+dnl ...
+dnl EPILOGUE()
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+m4_assert_defined(`WANT_PROFILING')
+ `GLOBL $1
+ TYPE($1,`function')
+ COFF_TYPE($1)
+$1:
+ifelse(WANT_PROFILING,`prof', ` call_mcount')
+ifelse(WANT_PROFILING,`gprof', ` call_mcount')
+ifelse(WANT_PROFILING,`instrument',` call_instrument(enter)')
+')
+
+
+dnl Usage: COFF_TYPE(GSYM_PREFIX`'foo)
+dnl
+dnl Emit COFF style ".def ... .endef" type information for a function, when
+dnl supported. The argument should include any GSYM_PREFIX.
+dnl
+dnl See autoconf macro GMP_ASM_COFF_TYPE for HAVE_COFF_TYPE.
+
+define(COFF_TYPE,
+m4_assert_numargs(1)
+m4_assert_defined(`HAVE_COFF_TYPE')
+`ifelse(HAVE_COFF_TYPE,yes,
+ `.def $1
+ .scl 2
+ .type 32
+ .endef')')
+
+
+dnl Usage: call_mcount
+dnl
+dnl For `gprof' style profiling, %ebp is setup as a frame pointer. None of
+dnl the assembler routines use %ebp this way, so it's done only for the
+dnl benefit of mcount. glibc sysdeps/i386/i386-mcount.S shows how mcount
+dnl gets the current function from (%esp) and the parent from 4(%ebp).
+dnl
+dnl For `prof' style profiling gcc generates mcount calls without setting
+dnl up %ebp, and the same is done here.
+
+define(`call_mcount',
+m4_assert_numargs(-1)
+m4_assert_defined(`WANT_PROFILING')
+m4_assert_defined(`MCOUNT_PIC_REG')
+m4_assert_defined(`MCOUNT_NONPIC_REG')
+m4_assert_defined(`MCOUNT_PIC_CALL')
+m4_assert_defined(`MCOUNT_NONPIC_CALL')
+`ifelse(ifdef(`PIC',`MCOUNT_PIC_REG',`MCOUNT_NONPIC_REG'),,,
+` DATA
+ ALIGN(4)
+L(mcount_data_`'mcount_counter):
+ W32 0
+ TEXT
+')dnl
+ifelse(WANT_PROFILING,`gprof',
+` pushl %ebp
+ movl %esp, %ebp
+')dnl
+ifdef(`PIC',
+` pushl %ebx
+ call_movl_eip_to_ebx
+L(mcount_here_`'mcount_counter):
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(mcount_here_`'mcount_counter)], %ebx
+ifelse(MCOUNT_PIC_REG,,,
+` leal L(mcount_data_`'mcount_counter)@GOTOFF(%ebx), MCOUNT_PIC_REG')
+MCOUNT_PIC_CALL
+ popl %ebx
+',`dnl non-PIC
+ifelse(MCOUNT_NONPIC_REG,,,
+` movl `$'L(mcount_data_`'mcount_counter), MCOUNT_NONPIC_REG
+')dnl
+MCOUNT_NONPIC_CALL
+')dnl
+ifelse(WANT_PROFILING,`gprof',
+` popl %ebp
+')
+define(`mcount_counter',incr(mcount_counter))
+')
+
+define(mcount_counter,1)
+
+
+dnl Usage: call_instrument(enter|exit)
+dnl
+dnl Call __cyg_profile_func_enter or __cyg_profile_func_exit.
+dnl
+dnl For PIC, most routines don't require _GLOBAL_OFFSET_TABLE_ themselves
+dnl so %ebx is just setup for these calls. It's a bit wasteful to repeat
+dnl the setup for the exit call having done it earlier for the enter, but
+dnl there's nowhere very convenient to hold %ebx through the length of a
+dnl routine, in general.
+dnl
+dnl For PIC, because instrument_current_function will be within the current
+dnl object file we can get it just as an offset from %eip, there's no need
+dnl to use the GOT.
+dnl
+dnl No attempt is made to maintain the stack alignment gcc generates with
+dnl -mpreferred-stack-boundary. This wouldn't be hard, but it seems highly
+dnl unlikely the instrumenting functions would be doing anything that'd
+dnl benefit from alignment, in particular they're unlikely to be using
+dnl doubles or long doubles on the stack.
+dnl
+dnl The FRAME scheme is used to conveniently account for the register saves
+dnl before accessing the return address. Any previous value is saved and
+dnl restored, since plenty of code keeps a value across a "ret" in the
+dnl middle of a routine.
+
+define(call_instrument,
+m4_assert_numargs(1)
+` pushdef(`FRAME',0)
+ifelse($1,exit,
+` pushl %eax FRAME_pushl() C return value
+')
+ifdef(`PIC',
+` pushl %ebx FRAME_pushl()
+ call_movl_eip_to_ebx
+L(instrument_here_`'instrument_count):
+ movl %ebx, %ecx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-L(instrument_here_`'instrument_count)], %ebx
+ C use addl rather than leal to avoid old gas bugs, see mpn/x86/README
+ addl $instrument_current_function-L(instrument_here_`'instrument_count), %ecx
+ pushl m4_empty_if_zero(FRAME)(%esp) FRAME_pushl() C return addr
+ pushl %ecx FRAME_pushl() C this function
+ call GSYM_PREFIX`'__cyg_profile_func_$1@PLT
+ addl $`'8, %esp
+ popl %ebx
+',
+` C non-PIC
+ pushl m4_empty_if_zero(FRAME)(%esp) FRAME_pushl() C return addr
+ pushl $instrument_current_function FRAME_pushl() C this function
+ call GSYM_PREFIX`'__cyg_profile_func_$1
+ addl $`'8, %esp
+')
+ifelse($1,exit,
+` popl %eax C return value
+')
+ popdef(`FRAME')
+define(`instrument_count',incr(instrument_count))
+')
+define(instrument_count,1)
+
+
+dnl Usage: instrument_current_function
+dnl
+dnl Return the current function name for instrumenting purposes. This is
+dnl PROLOGUE_current_function, but it sticks at the first such name seen.
+dnl
+dnl Sticking to the first name seen ensures that multiple-entrypoint
+dnl functions like mpn_add_nc and mpn_add_n will make enter and exit calls
+dnl giving the same function address.
+
+define(instrument_current_function,
+m4_assert_numargs(-1)
+`ifdef(`instrument_current_function_seen',
+`instrument_current_function_seen',
+`define(`instrument_current_function_seen',PROLOGUE_current_function)dnl
+PROLOGUE_current_function')')
+
+
+dnl Usage: call_movl_eip_to_ebx
+dnl
+dnl Generate a call to L(movl_eip_to_ebx), and record the need for that
+dnl routine.
+
+define(call_movl_eip_to_ebx,
+m4_assert_numargs(-1)
+`call L(movl_eip_to_ebx)
+define(`movl_eip_to_ebx_needed',1)')
+
+dnl Usage: generate_movl_eip_to_ebx
+dnl
+dnl Emit a L(movl_eip_to_ebx) routine, if needed and not already generated.
+
+define(generate_movl_eip_to_ebx,
+m4_assert_numargs(-1)
+`ifelse(movl_eip_to_ebx_needed,1,
+`ifelse(movl_eip_to_ebx_done,1,,
+`L(movl_eip_to_ebx):
+ movl (%esp), %ebx
+ ret_internal
+define(`movl_eip_to_ebx_done',1)
+')')')
+
+
+dnl Usage: ret
+dnl
+dnl Generate a "ret", but if doing instrumented profiling then call
+dnl __cyg_profile_func_exit first.
+
+define(ret,
+m4_assert_numargs(-1)
+m4_assert_defined(`WANT_PROFILING')
+`ifelse(WANT_PROFILING,instrument,
+`ret_instrument',
+`ret_internal')
+generate_movl_eip_to_ebx
+')
+
+
+dnl Usage: ret_internal
+dnl
+dnl A plain "ret", without any __cyg_profile_func_exit call. This can be
+dnl used for a return which is internal to some function, such as when
+dnl getting %eip for PIC.
+
+define(ret_internal,
+m4_assert_numargs(-1)
+``ret'')
+
+
+dnl Usage: ret_instrument
+dnl
+dnl Generate call to __cyg_profile_func_exit and then a ret. If a ret has
+dnl already been seen from this function then jump to that chunk of code,
+dnl rather than emitting it again.
+
+define(ret_instrument,
+m4_assert_numargs(-1)
+`ifelse(m4_unquote(ret_instrument_seen_`'instrument_current_function),1,
+`jmp L(instrument_exit_`'instrument_current_function)',
+`define(ret_instrument_seen_`'instrument_current_function,1)
+L(instrument_exit_`'instrument_current_function):
+call_instrument(exit)
+ ret_internal')')
+
+
+dnl Usage: _GLOBAL_OFFSET_TABLE_
+dnl
+dnl Expand to _GLOBAL_OFFSET_TABLE_ plus any necessary underscore prefix.
+dnl This lets us write plain _GLOBAL_OFFSET_TABLE_ in SVR4 style, but still
+dnl work with systems requiring an extra underscore such as OpenBSD.
+dnl
+dnl deflit is used so "leal _GLOBAL_OFFSET_TABLE_(%eax), %ebx" will come
+dnl out right, though that form doesn't work properly in gas (see
+dnl mpn/x86/README).
+
+deflit(_GLOBAL_OFFSET_TABLE_,
+m4_assert_defined(`GOT_GSYM_PREFIX')
+`GOT_GSYM_PREFIX`_GLOBAL_OFFSET_TABLE_'')
+
+
+dnl --------------------------------------------------------------------------
+dnl Various x86 macros.
+dnl
+
+
+dnl Usage: ALIGN_OFFSET(bytes,offset)
+dnl
+dnl Align to `offset' away from a multiple of `bytes'.
+dnl
+dnl This is useful for testing, for example align to something very strict
+dnl and see what effect offsets from it have, "ALIGN_OFFSET(256,32)".
+dnl
+dnl Generally you wouldn't execute across the padding, but it's done with
+dnl nop's so it'll work.
+
+define(ALIGN_OFFSET,
+m4_assert_numargs(2)
+`ALIGN($1)
+forloop(`i',1,$2,` nop
+')')
+
+
+dnl Usage: defframe(name,offset)
+dnl
+dnl Make a definition like the following with which to access a parameter
+dnl or variable on the stack.
+dnl
+dnl define(name,`FRAME+offset(%esp)')
+dnl
+dnl Actually m4_empty_if_zero(FRAME+offset) is used, which will save one
+dnl byte if FRAME+offset is zero, by putting (%esp) rather than 0(%esp).
+dnl Use define(`defframe_empty_if_zero_disabled',1) if for some reason the
+dnl zero offset is wanted.
+dnl
+dnl The new macro also gets a check that when it's used FRAME is actually
+dnl defined, and that the final %esp offset isn't negative, which would
+dnl mean an attempt to access something below the current %esp.
+dnl
+dnl deflit() is used rather than a plain define(), so the new macro won't
+dnl delete any following parenthesized expression. name(%edi) will come
+dnl out say as 16(%esp)(%edi). This isn't valid assembler and should
+dnl provoke an error, which is better than silently giving just 16(%esp).
+dnl
+dnl See README for more on the suggested way to access the stack frame.
+
+define(defframe,
+m4_assert_numargs(2)
+`deflit(`$1',
+m4_assert_defined(`FRAME')
+`defframe_check_notbelow(`$1',$2,FRAME)dnl
+defframe_empty_if_zero(FRAME+($2))(%esp)')')
+
+dnl Called: defframe_empty_if_zero(expression)
+define(defframe_empty_if_zero,
+m4_assert_numargs(1)
+`ifelse(defframe_empty_if_zero_disabled,1,
+`eval($1)',
+`m4_empty_if_zero($1)')')
+
+dnl Called: defframe_check_notbelow(`name',offset,FRAME)
+define(defframe_check_notbelow,
+m4_assert_numargs(3)
+`ifelse(eval(($3)+($2)<0),1,
+`m4_error(`$1 at frame offset $2 used when FRAME is only $3 bytes
+')')')
+
+
+dnl Usage: FRAME_pushl()
+dnl FRAME_popl()
+dnl FRAME_addl_esp(n)
+dnl FRAME_subl_esp(n)
+dnl
+dnl Adjust FRAME appropriately for a pushl or popl, or for an addl or subl
+dnl %esp of n bytes.
+dnl
+dnl Using these macros is completely optional. Sometimes it makes more
+dnl sense to put explicit deflit(`FRAME',N) forms, especially when there's
+dnl jumps and different sequences of FRAME values need to be used in
+dnl different places.
+
+define(FRAME_pushl,
+m4_assert_numargs(0)
+m4_assert_defined(`FRAME')
+`deflit(`FRAME',eval(FRAME+4))')
+
+define(FRAME_popl,
+m4_assert_numargs(0)
+m4_assert_defined(`FRAME')
+`deflit(`FRAME',eval(FRAME-4))')
+
+define(FRAME_addl_esp,
+m4_assert_numargs(1)
+m4_assert_defined(`FRAME')
+`deflit(`FRAME',eval(FRAME-($1)))')
+
+define(FRAME_subl_esp,
+m4_assert_numargs(1)
+m4_assert_defined(`FRAME')
+`deflit(`FRAME',eval(FRAME+($1)))')
+
+
+dnl Usage: defframe_pushl(name)
+dnl
+dnl Do a combination FRAME_pushl() and a defframe() to name the stack
+dnl location just pushed. This should come after a pushl instruction.
+dnl Putting it on the same line works and avoids lengthening the code. For
+dnl example,
+dnl
+dnl pushl %eax defframe_pushl(VAR_COUNTER)
+dnl
+dnl Notice the defframe() is done with an unquoted -FRAME thus giving its
+dnl current value without tracking future changes.
+
+define(defframe_pushl,
+m4_assert_numargs(1)
+`FRAME_pushl()defframe(`$1',-FRAME)')
+
+
+dnl --------------------------------------------------------------------------
+dnl Assembler instruction macros.
+dnl
+
+
+dnl Usage: emms_or_femms
+dnl femms_available_p
+dnl
+dnl femms_available_p expands to 1 or 0 according to whether the AMD 3DNow
+dnl femms instruction is available. emms_or_femms expands to femms if
+dnl available, or emms if not.
+dnl
+dnl emms_or_femms is meant for use in the K6 directory where plain K6
+dnl (without femms) and K6-2 and K6-3 (with a slightly faster femms) are
+dnl supported together.
+dnl
+dnl On K7 femms is no longer faster and is just an alias for emms, so plain
+dnl emms may as well be used.
+
+define(femms_available_p,
+m4_assert_numargs(-1)
+`m4_ifdef_anyof_p(
+ `HAVE_HOST_CPU_k62',
+ `HAVE_HOST_CPU_k63',
+ `HAVE_HOST_CPU_athlon')')
+
+define(emms_or_femms,
+m4_assert_numargs(-1)
+`ifelse(femms_available_p,1,`femms',`emms')')
+
+
+dnl Usage: femms
+dnl
+dnl Gas 2.9.1 which comes with FreeBSD 3.4 doesn't support femms, so the
+dnl following is a replacement using .byte.
+
+define(femms,
+m4_assert_numargs(-1)
+`.byte 15,14 C AMD 3DNow femms')
+
+
+dnl Usage: jadcl0(op)
+dnl
+dnl Generate a jnc/incl as a substitute for adcl $0,op. Note this isn't an
+dnl exact replacement, since it doesn't set the flags like adcl does.
+dnl
+dnl This finds a use in K6 mpn_addmul_1, mpn_submul_1, mpn_mul_basecase and
+dnl mpn_sqr_basecase because on K6 an adcl is slow, the branch
+dnl misprediction penalty is small, and the multiply algorithm used leads
+dnl to a carry bit on average only 1/4 of the time.
+dnl
+dnl jadcl0_disabled can be set to 1 to instead generate an ordinary adcl
+dnl for comparison. For example,
+dnl
+dnl define(`jadcl0_disabled',1)
+dnl
+dnl When using a register operand, eg. "jadcl0(%edx)", the jnc/incl code is
+dnl the same size as an adcl. This makes it possible to use the exact same
+dnl computed jump code when testing the relative speed of the two.
+
+define(jadcl0,
+m4_assert_numargs(1)
+`ifelse(jadcl0_disabled,1,
+ `adcl $`'0, $1',
+ `jnc L(jadcl0_`'jadcl0_counter)
+ incl $1
+L(jadcl0_`'jadcl0_counter):
+define(`jadcl0_counter',incr(jadcl0_counter))')')
+
+define(jadcl0_counter,1)
+
+
+dnl Usage: x86_lookup(target, key,value, key,value, ...)
+dnl x86_lookup_p(target, key,value, key,value, ...)
+dnl
+dnl Look for `target' among the `key' parameters.
+dnl
+dnl x86_lookup expands to the corresponding `value', or generates an error
+dnl if `target' isn't found.
+dnl
+dnl x86_lookup_p expands to 1 if `target' is found, or 0 if not.
+
+define(x86_lookup,
+m4_assert_numargs_range(1,999)
+`ifelse(eval($#<3),1,
+`m4_error(`unrecognised part of x86 instruction: $1
+')',
+`ifelse(`$1',`$2', `$3',
+`x86_lookup(`$1',shift(shift(shift($@))))')')')
+
+define(x86_lookup_p,
+m4_assert_numargs_range(1,999)
+`ifelse(eval($#<3),1, `0',
+`ifelse(`$1',`$2', `1',
+`x86_lookup_p(`$1',shift(shift(shift($@))))')')')
+
+
+dnl Usage: x86_opcode_reg32(reg)
+dnl x86_opcode_reg32_p(reg)
+dnl
+dnl x86_opcode_reg32 expands to the standard 3 bit encoding for the given
+dnl 32-bit register, eg. `%ebp' turns into 5.
+dnl
+dnl x86_opcode_reg32_p expands to 1 if reg is a valid 32-bit register, or 0
+dnl if not.
+
+define(x86_opcode_reg32,
+m4_assert_numargs(1)
+`x86_lookup(`$1',x86_opcode_reg32_list)')
+
+define(x86_opcode_reg32_p,
+m4_assert_onearg()
+`x86_lookup_p(`$1',x86_opcode_reg32_list)')
+
+define(x86_opcode_reg32_list,
+``%eax',0,
+`%ecx',1,
+`%edx',2,
+`%ebx',3,
+`%esp',4,
+`%ebp',5,
+`%esi',6,
+`%edi',7')
+
+
+dnl Usage: x86_opcode_tttn(cond)
+dnl
+dnl Expand to the 4-bit "tttn" field value for the given x86 branch
+dnl condition (like `c', `ae', etc).
+
+define(x86_opcode_tttn,
+m4_assert_numargs(1)
+`x86_lookup(`$1',x86_opcode_ttn_list)')
+
+define(x86_opcode_tttn_list,
+``o', 0,
+`no', 1,
+`b', 2, `c', 2, `nae',2,
+`nb', 3, `nc', 3, `ae', 3,
+`e', 4, `z', 4,
+`ne', 5, `nz', 5,
+`be', 6, `na', 6,
+`nbe', 7, `a', 7,
+`s', 8,
+`ns', 9,
+`p', 10, `pe', 10, `npo',10,
+`np', 11, `npe',11, `po', 11,
+`l', 12, `nge',12,
+`nl', 13, `ge', 13,
+`le', 14, `ng', 14,
+`nle',15, `g', 15')
+
+
+dnl Usage: cmovCC(%srcreg,%dstreg)
+dnl
+dnl Emit a cmov instruction, using a .byte sequence, since various past
+dnl versions of gas don't know cmov. For example,
+dnl
+dnl cmovz( %eax, %ebx)
+dnl
+dnl The source operand can only be a plain register. (m4 code implementing
+dnl full memory addressing modes exists, believe it or not, but isn't
+dnl currently needed and isn't included.)
+dnl
+dnl All the standard conditions are defined. Attempting to use one without
+dnl the macro parentheses, such as just "cmovbe %eax, %ebx", will provoke
+dnl an error. This protects against writing something old gas wouldn't
+dnl understand.
+
+dnl Called: define_cmov_many(cond,tttn,cond,tttn,...)
+define(define_cmov_many,
+`ifelse(m4_length(`$1'),0,,
+`define_cmov(`$1',`$2')define_cmov_many(shift(shift($@)))')')
+
+dnl Called: define_cmov(cond,tttn)
+dnl Emit basically define(cmov<cond>,`cmov_internal(<cond>,<ttn>,`$1',`$2')')
+define(define_cmov,
+m4_assert_numargs(2)
+`define(`cmov$1',
+m4_instruction_wrapper()
+m4_assert_numargs(2)
+`cmov_internal'(m4_doublequote($`'0),``$2'',dnl
+m4_doublequote($`'1),m4_doublequote($`'2)))')
+
+define_cmov_many(x86_opcode_tttn_list)
+
+dnl Called: cmov_internal(name,tttn,src,dst)
+define(cmov_internal,
+m4_assert_numargs(4)
+`.byte dnl
+15, dnl
+eval(64+$2), dnl
+eval(192+8*x86_opcode_reg32(`$4')+x86_opcode_reg32(`$3')) dnl
+ C `$1 $3, $4'')
+
+
+dnl Usage: x86_opcode_regmmx(reg)
+dnl
+dnl Validate the given mmx register, and return its number, 0 to 7.
+
+define(x86_opcode_regmmx,
+m4_assert_numargs(1)
+`x86_lookup(`$1',x86_opcode_regmmx_list)')
+
+define(x86_opcode_regmmx_list,
+``%mm0',0,
+`%mm1',1,
+`%mm2',2,
+`%mm3',3,
+`%mm4',4,
+`%mm5',5,
+`%mm6',6,
+`%mm7',7')
+
+
+dnl Usage: psadbw(%srcreg,%dstreg)
+dnl
+dnl Oldish versions of gas don't know psadbw, in particular gas 2.9.1 on
+dnl FreeBSD 3.3 and 3.4 doesn't, so instead emit .byte sequences. For
+dnl example,
+dnl
+dnl psadbw( %mm1, %mm2)
+dnl
+dnl Only register->register forms are supported here, which suffices for
+dnl the current code.
+
+define(psadbw,
+m4_instruction_wrapper()
+m4_assert_numargs(2)
+`.byte 0x0f,0xf6,dnl
+eval(192+x86_opcode_regmmx(`$2')*8+x86_opcode_regmmx(`$1')) dnl
+ C `psadbw $1, $2'')
+
+
+dnl Usage: Zdisp(inst,op,op,op)
+dnl
+dnl Generate explicit .byte sequences if necessary to force a byte-sized
+dnl zero displacement on an instruction. For example,
+dnl
+dnl Zdisp( movl, 0,(%esi), %eax)
+dnl
+dnl expands to
+dnl
+dnl .byte 139,70,0 C movl 0(%esi), %eax
+dnl
+dnl If the displacement given isn't 0, then normal assembler code is
+dnl generated. For example,
+dnl
+dnl Zdisp( movl, 4,(%esi), %eax)
+dnl
+dnl expands to
+dnl
+dnl movl 4(%esi), %eax
+dnl
+dnl This means a single Zdisp() form can be used with an expression for the
+dnl displacement, and .byte will be used only if necessary. The
+dnl displacement argument is eval()ed.
+dnl
+dnl Because there aren't many places a 0(reg) form is wanted, Zdisp is
+dnl implemented with a table of instructions and encodings. A new entry is
+dnl needed for any different operation or registers. The table is split
+dnl into separate macros to avoid overflowing BSD m4 macro expansion space.
+
+define(Zdisp,
+m4_assert_numargs(4)
+`define(`Zdisp_found',0)dnl
+Zdisp_1($@)dnl
+Zdisp_2($@)dnl
+Zdisp_3($@)dnl
+Zdisp_4($@)dnl
+ifelse(Zdisp_found,0,
+`m4_error(`unrecognised instruction in Zdisp: $1 $2 $3 $4
+')')')
+
+define(Zdisp_1,`dnl
+Zdisp_match( adcl, 0,(%edx), %eax, `0x13,0x42,0x00', $@)`'dnl
+Zdisp_match( adcl, 0,(%edx), %ebx, `0x13,0x5a,0x00', $@)`'dnl
+Zdisp_match( adcl, 0,(%edx), %esi, `0x13,0x72,0x00', $@)`'dnl
+Zdisp_match( addl, %ebx, 0,(%edi), `0x01,0x5f,0x00', $@)`'dnl
+Zdisp_match( addl, %ecx, 0,(%edi), `0x01,0x4f,0x00', $@)`'dnl
+Zdisp_match( addl, %esi, 0,(%edi), `0x01,0x77,0x00', $@)`'dnl
+Zdisp_match( sbbl, 0,(%edx), %eax, `0x1b,0x42,0x00', $@)`'dnl
+Zdisp_match( sbbl, 0,(%edx), %esi, `0x1b,0x72,0x00', $@)`'dnl
+Zdisp_match( subl, %ecx, 0,(%edi), `0x29,0x4f,0x00', $@)`'dnl
+Zdisp_match( movzbl, 0,(%eax,%ebp), %eax, `0x0f,0xb6,0x44,0x28,0x00', $@)`'dnl
+Zdisp_match( movzbl, 0,(%ecx,%edi), %edi, `0x0f,0xb6,0x7c,0x39,0x00', $@)`'dnl
+Zdisp_match( adc, 0,(%ebx,%ecx,4), %eax, `0x13,0x44,0x8b,0x00', $@)`'dnl
+Zdisp_match( sbb, 0,(%ebx,%ecx,4), %eax, `0x1b,0x44,0x8b,0x00', $@)`'dnl
+')
+define(Zdisp_2,`dnl
+Zdisp_match( movl, %eax, 0,(%edi), `0x89,0x47,0x00', $@)`'dnl
+Zdisp_match( movl, %ebx, 0,(%edi), `0x89,0x5f,0x00', $@)`'dnl
+Zdisp_match( movl, %esi, 0,(%edi), `0x89,0x77,0x00', $@)`'dnl
+Zdisp_match( movl, 0,(%ebx), %eax, `0x8b,0x43,0x00', $@)`'dnl
+Zdisp_match( movl, 0,(%ebx), %esi, `0x8b,0x73,0x00', $@)`'dnl
+Zdisp_match( movl, 0,(%edx), %eax, `0x8b,0x42,0x00', $@)`'dnl
+Zdisp_match( movl, 0,(%esi), %eax, `0x8b,0x46,0x00', $@)`'dnl
+Zdisp_match( movl, 0,(%esi,%ecx,4), %eax, `0x8b,0x44,0x8e,0x00', $@)`'dnl
+Zdisp_match( mov, 0,(%esi,%ecx,4), %eax, `0x8b,0x44,0x8e,0x00', $@)`'dnl
+Zdisp_match( mov, %eax, 0,(%edi,%ecx,4), `0x89,0x44,0x8f,0x00', $@)`'dnl
+')
+define(Zdisp_3,`dnl
+Zdisp_match( movq, 0,(%eax,%ecx,8), %mm0, `0x0f,0x6f,0x44,0xc8,0x00', $@)`'dnl
+Zdisp_match( movq, 0,(%ebx,%eax,4), %mm0, `0x0f,0x6f,0x44,0x83,0x00', $@)`'dnl
+Zdisp_match( movq, 0,(%ebx,%eax,4), %mm2, `0x0f,0x6f,0x54,0x83,0x00', $@)`'dnl
+Zdisp_match( movq, 0,(%ebx,%ecx,4), %mm0, `0x0f,0x6f,0x44,0x8b,0x00', $@)`'dnl
+Zdisp_match( movq, 0,(%edx), %mm0, `0x0f,0x6f,0x42,0x00', $@)`'dnl
+Zdisp_match( movq, 0,(%esi), %mm0, `0x0f,0x6f,0x46,0x00', $@)`'dnl
+Zdisp_match( movq, %mm0, 0,(%edi), `0x0f,0x7f,0x47,0x00', $@)`'dnl
+Zdisp_match( movq, %mm2, 0,(%ecx,%eax,4), `0x0f,0x7f,0x54,0x81,0x00', $@)`'dnl
+Zdisp_match( movq, %mm2, 0,(%edx,%eax,4), `0x0f,0x7f,0x54,0x82,0x00', $@)`'dnl
+Zdisp_match( movq, %mm0, 0,(%edx,%ecx,8), `0x0f,0x7f,0x44,0xca,0x00', $@)`'dnl
+')
+define(Zdisp_4,`dnl
+Zdisp_match( movd, 0,(%eax,%ecx,4), %mm0, `0x0f,0x6e,0x44,0x88,0x00', $@)`'dnl
+Zdisp_match( movd, 0,(%eax,%ecx,8), %mm1, `0x0f,0x6e,0x4c,0xc8,0x00', $@)`'dnl
+Zdisp_match( movd, 0,(%edx,%ecx,8), %mm0, `0x0f,0x6e,0x44,0xca,0x00', $@)`'dnl
+Zdisp_match( movd, %mm0, 0,(%eax,%ecx,4), `0x0f,0x7e,0x44,0x88,0x00', $@)`'dnl
+Zdisp_match( movd, %mm0, 0,(%ecx,%eax,4), `0x0f,0x7e,0x44,0x81,0x00', $@)`'dnl
+Zdisp_match( movd, %mm2, 0,(%ecx,%eax,4), `0x0f,0x7e,0x54,0x81,0x00', $@)`'dnl
+Zdisp_match( movd, %mm0, 0,(%edx,%ecx,4), `0x0f,0x7e,0x44,0x8a,0x00', $@)`'dnl
+')
+
+define(Zdisp_match,
+m4_assert_numargs(9)
+`ifelse(eval(m4_stringequal_p(`$1',`$6')
+ && m4_stringequal_p(`$2',0)
+ && m4_stringequal_p(`$3',`$8')
+ && m4_stringequal_p(`$4',`$9')),1,
+`define(`Zdisp_found',1)dnl
+ifelse(eval(`$7'),0,
+` .byte $5 C `$1 0$3, $4'',
+` $6 $7$8, $9')',
+
+`ifelse(eval(m4_stringequal_p(`$1',`$6')
+ && m4_stringequal_p(`$2',`$7')
+ && m4_stringequal_p(`$3',0)
+ && m4_stringequal_p(`$4',`$9')),1,
+`define(`Zdisp_found',1)dnl
+ifelse(eval(`$8'),0,
+` .byte $5 C `$1 $2, 0$4'',
+` $6 $7, $8$9')')')')
+
+
+dnl Usage: shldl(count,src,dst)
+dnl shrdl(count,src,dst)
+dnl shldw(count,src,dst)
+dnl shrdw(count,src,dst)
+dnl
+dnl Generate a double-shift instruction, possibly omitting a %cl count
+dnl parameter if that's what the assembler requires, as indicated by
+dnl WANT_SHLDL_CL in config.m4. For example,
+dnl
+dnl shldl( %cl, %eax, %ebx)
+dnl
+dnl turns into either
+dnl
+dnl shldl %cl, %eax, %ebx
+dnl or
+dnl shldl %eax, %ebx
+dnl
+dnl Immediate counts are always passed through unchanged. For example,
+dnl
+dnl shrdl( $2, %esi, %edi)
+dnl becomes
+dnl shrdl $2, %esi, %edi
+dnl
+dnl
+dnl If you forget to use the macro form "shldl( ...)" and instead write
+dnl just a plain "shldl ...", an error results. This ensures the necessary
+dnl variant treatment of %cl isn't accidentally bypassed.
+
+define(define_shd_instruction,
+m4_assert_numargs(1)
+`define($1,
+m4_instruction_wrapper()
+m4_assert_numargs(3)
+`shd_instruction'(m4_doublequote($`'0),m4_doublequote($`'1),dnl
+m4_doublequote($`'2),m4_doublequote($`'3)))')
+
+dnl Effectively: define(shldl,`shd_instruction(`$0',`$1',`$2',`$3')') etc
+define_shd_instruction(shldl)
+define_shd_instruction(shrdl)
+define_shd_instruction(shldw)
+define_shd_instruction(shrdw)
+
+dnl Called: shd_instruction(op,count,src,dst)
+define(shd_instruction,
+m4_assert_numargs(4)
+m4_assert_defined(`WANT_SHLDL_CL')
+`ifelse(eval(m4_stringequal_p(`$2',`%cl') && !WANT_SHLDL_CL),1,
+``$1' `$3', `$4'',
+``$1' `$2', `$3', `$4'')')
+
+
+dnl Usage: ASSERT([cond][,instructions])
+dnl
+dnl If WANT_ASSERT is 1, output the given instructions and expect the given
+dnl flags condition to then be satisfied. For example,
+dnl
+dnl ASSERT(ne, `cmpl %eax, %ebx')
+dnl
+dnl The instructions can be omitted to just assert a flags condition with
+dnl no extra calculation. For example,
+dnl
+dnl ASSERT(nc)
+dnl
+dnl When `instructions' is not empty, a pushf/popf is added to preserve the
+dnl flags, but the instructions themselves must preserve any registers that
+dnl matter. FRAME is adjusted for the push and pop, so the instructions
+dnl given can use defframe() stack variables.
+dnl
+dnl The condition can be omitted to just output the given instructions when
+dnl assertion checking is wanted. In this case the pushf/popf is omitted.
+dnl For example,
+dnl
+dnl ASSERT(, `movl %eax, VAR_KEEPVAL')
+
+define(ASSERT,
+m4_assert_numargs_range(1,2)
+m4_assert_defined(`WANT_ASSERT')
+`ifelse(WANT_ASSERT,1,
+`ifelse(`$1',,
+ `$2',
+ `C ASSERT
+ifelse(`$2',,,` pushf ifdef(`FRAME',`FRAME_pushl()')')
+ $2
+ j`$1' L(ASSERT_ok`'ASSERT_counter)
+ ud2 C assertion failed
+L(ASSERT_ok`'ASSERT_counter):
+ifelse(`$2',,,` popf ifdef(`FRAME',`FRAME_popl()')')
+define(`ASSERT_counter',incr(ASSERT_counter))')')')
+
+define(ASSERT_counter,1)
+
+
+dnl Usage: movl_text_address(label,register)
+dnl
+dnl Get the address of a text segment label, using either a plain movl or a
+dnl position-independent calculation, as necessary. For example,
+dnl
+dnl movl_code_address(L(foo),%eax)
+dnl
+dnl This macro is only meant for use in ASSERT()s or when testing, since
+dnl the PIC sequence it generates will want to be done with a ret balancing
+dnl the call on CPUs with return address branch prediction.
+dnl
+dnl The addl generated here has a backward reference to the label, and so
+dnl won't suffer from the two forwards references bug in old gas (described
+dnl in mpn/x86/README).
+
+define(movl_text_address,
+m4_assert_numargs(2)
+`ifdef(`PIC',
+ `call L(movl_text_address_`'movl_text_address_counter)
+L(movl_text_address_`'movl_text_address_counter):
+ popl $2 C %eip
+ addl `$'$1-L(movl_text_address_`'movl_text_address_counter), $2
+define(`movl_text_address_counter',incr(movl_text_address_counter))',
+ `movl `$'$1, $2')')
+
+define(movl_text_address_counter,1)
+
+
+dnl Usage: notl_or_xorl_GMP_NUMB_MASK(reg)
+dnl
+dnl Expand to either "notl `reg'" or "xorl $GMP_NUMB_BITS,`reg'" as
+dnl appropriate for nails in use or not.
+
+define(notl_or_xorl_GMP_NUMB_MASK,
+m4_assert_numargs(1)
+`ifelse(GMP_NAIL_BITS,0,
+`notl `$1'',
+`xorl $GMP_NUMB_MASK, `$1'')')
+
+
+dnl Usage LEA(symbol,reg)
+
+define(`LEA',
+m4_assert_numargs(2)
+`ifdef(`PIC',`
+define(`EPILOGUE_cpu',
+`
+L(movl_eip_`'substr($2,1)):
+ movl (%esp), $2
+ ret_internal
+ SIZE($'`1, .-$'`1)')
+
+ call L(movl_eip_`'substr($2,1))
+ addl $_GLOBAL_OFFSET_TABLE_, $2
+ movl $1@GOT($2), $2
+',`
+ movl `$'$1, $2
+')')
+
+define(`DEF_OBJECT',
+m4_assert_numargs_range(1,2)
+ `RODATA
+ ALIGN(ifelse($#,1,2,$2))
+$1:
+')
+
+define(`END_OBJECT',
+m4_assert_numargs(1)
+` SIZE(`$1',.-`$1')')
+
+dnl Usage: CALL(funcname)
+dnl
+
+define(`CALL',
+m4_assert_numargs(1)
+`ifdef(`PIC',
+ `call GSYM_PREFIX`'$1@PLT',
+ `call GSYM_PREFIX`'$1')')
+
+ifdef(`PIC',
+`define(`PIC_WITH_EBX')',
+`undefine(`PIC_WITH_EBX')')
+
+divert`'dnl
diff --git a/gmp/mpn/x86_64/README b/gmp/mpn/x86_64/README
new file mode 100644
index 0000000000..9c8a586622
--- /dev/null
+++ b/gmp/mpn/x86_64/README
@@ -0,0 +1,74 @@
+Copyright 2003, 2004, 2006, 2008 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ AMD64 MPN SUBROUTINES
+
+
+This directory contains mpn functions for AMD64 chips. It is also useful
+for 64-bit Pentiums, and "Core 2".
+
+
+ RELEVANT OPTIMIZATION ISSUES
+
+The Opteron and Athlon64 can sustain up to 3 instructions per cycle, but in
+practice that is only possible for integer instructions. But almost any
+three integer instructions can issue simultaneously, including any 3 ALU
+operations, including shifts. Up to two memory operations can issue each
+cycle.
+
+Scheduling typically requires that load-use instructions are split into
+separate load and use instructions. That requires more decode resources,
+and it is rarely a win. Opteron/Athlon64 have deep out-of-order core.
+
+
+Optimizing for 64-bit Pentium4 is probably a waste of time, as the most
+critical instructions are very poorly implemented here. Perhaps we could
+save a cycle or two, but the most common loops now run at between 10 and 22
+cycles, so a saved cycle isn't too exciting.
+
+
+The new spin of the venerable P6 core, the "Core 2" is much better than the
+Pentium4 for the GMP loops. Its integer pipeline is somewhat similar to to
+the Opteron/Athlon64 pipeline, except that the GMP favourites ADC/SBB and
+MUL are slower. Furthermore, an INC/DEC followed by ADC/SBB incur a
+pipeline stall of around 10 cycles. The default mpn_add_n and mpn_sub_n
+code suffers badly from the stall. The code in the core2 subdirectory uses
+the almost forgotten instruction JRCXZ for loop control, and updates the
+induction variable using LEA.
+
+
+
+REFERENCES
+
+"System V Application Binary Interface AMD64 Architecture Processor
+Supplement", draft version 0.99, December 2007.
+http://www.x86-64.org/documentation/abi.pdf
diff --git a/gmp/mpn/x86_64/addaddmul_1msb0.asm b/gmp/mpn/x86_64/addaddmul_1msb0.asm
new file mode 100644
index 0000000000..87c21b4aca
--- /dev/null
+++ b/gmp/mpn/x86_64/addaddmul_1msb0.asm
@@ -0,0 +1,170 @@
+dnl AMD64 mpn_addaddmul_1msb0, R = Au + Bv, u,v < 2^63.
+
+dnl Copyright 2008 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.167
+C AMD K10 2.167
+C Intel P4 12.0
+C Intel core2 4.0
+C Intel corei ?
+C Intel atom ?
+C VIA nano ?
+
+C TODO
+C * Perhaps handle various n mod 3 sizes better. The code now is too large.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`ap', `%rsi')
+define(`bp_param', `%rdx')
+define(`n', `%rcx')
+define(`u0', `%r8')
+define(`v0', `%r9')
+
+
+define(`bp', `%rbp')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_addaddmul_1msb0)
+ push %r12
+ push %rbp
+
+ lea (ap,n,8), ap
+ lea (bp_param,n,8), bp
+ lea (rp,n,8), rp
+ neg n
+
+ mov (ap,n,8), %rax
+ mul %r8
+ mov %rax, %r12
+ mov (bp,n,8), %rax
+ mov %rdx, %r10
+ add $3, n
+ jns L(end)
+
+ ALIGN(16)
+L(top): mul %r9
+ add %rax, %r12
+ mov -16(ap,n,8), %rax
+ adc %rdx, %r10
+ mov %r12, -24(rp,n,8)
+ mul %r8
+ add %rax, %r10
+ mov -16(bp,n,8), %rax
+ mov $0, R32(%r11)
+ adc %rdx, %r11
+ mul %r9
+ add %rax, %r10
+ mov -8(ap,n,8), %rax
+ adc %rdx, %r11
+ mov %r10, -16(rp,n,8)
+ mul %r8
+ add %rax, %r11
+ mov -8(bp,n,8), %rax
+ mov $0, R32(%r12)
+ adc %rdx, %r12
+ mul %r9
+ add %rax, %r11
+ adc %rdx, %r12
+ mov (ap,n,8), %rax
+ mul %r8
+ add %rax, %r12
+ mov %r11, -8(rp,n,8)
+ mov (bp,n,8), %rax
+ mov $0, R32(%r10)
+ adc %rdx, %r10
+ add $3, n
+ js L(top)
+
+L(end): cmp $1, R32(n)
+ ja 2f
+ jz 1f
+
+ mul %r9
+ add %rax, %r12
+ mov -16(ap), %rax
+ adc %rdx, %r10
+ mov %r12, -24(rp)
+ mul %r8
+ add %rax, %r10
+ mov -16(bp), %rax
+ mov $0, R32(%r11)
+ adc %rdx, %r11
+ mul %r9
+ add %rax, %r10
+ mov -8(ap), %rax
+ adc %rdx, %r11
+ mov %r10, -16(rp)
+ mul %r8
+ add %rax, %r11
+ mov -8(bp), %rax
+ mov $0, R32(%r12)
+ adc %rdx, %r12
+ mul %r9
+ add %rax, %r11
+ adc %rdx, %r12
+ mov %r11, -8(rp)
+ mov %r12, %rax
+ pop %rbp
+ pop %r12
+ ret
+
+1: mul %r9
+ add %rax, %r12
+ mov -8(ap), %rax
+ adc %rdx, %r10
+ mov %r12, -16(rp)
+ mul %r8
+ add %rax, %r10
+ mov -8(bp), %rax
+ mov $0, R32(%r11)
+ adc %rdx, %r11
+ mul %r9
+ add %rax, %r10
+ adc %rdx, %r11
+ mov %r10, -8(rp)
+ mov %r11, %rax
+ pop %rbp
+ pop %r12
+ ret
+
+2: mul %r9
+ add %rax, %r12
+ mov %r12, -8(rp)
+ adc %rdx, %r10
+ mov %r10, %rax
+ pop %rbp
+ pop %r12
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/addmul_2.asm b/gmp/mpn/x86_64/addmul_2.asm
new file mode 100644
index 0000000000..18307d719f
--- /dev/null
+++ b/gmp/mpn/x86_64/addmul_2.asm
@@ -0,0 +1,184 @@
+dnl AMD64 mpn_addmul_2 -- Multiply an n-limb vector with a 2-limb vector and
+dnl add the result to a third limb vector.
+
+dnl Copyright 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.375
+C AMD K10 2.375
+C Intel P4 15-16
+C Intel core2 4.45
+C Intel NHM 4.32
+C Intel SBR 3.4
+C Intel atom ?
+C VIA nano 4.4
+
+C This code is the result of running a code generation and optimization tool
+C suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * Tune feed-in and wind-down code.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n_param',`%rdx')
+define(`vp', `%rcx')
+
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+define(`n', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_addmul_2)
+ FUNC_ENTRY(4)
+ mov n_param, n
+ push %rbx
+ push %rbp
+
+ mov 0(vp), v0
+ mov 8(vp), v1
+
+ mov R32(n_param), R32(%rbx)
+ mov (up), %rax
+ lea -8(up,n_param,8), up
+ lea -8(rp,n_param,8), rp
+ mul v0
+ neg n
+ and $3, R32(%rbx)
+ jz L(b0)
+ cmp $2, R32(%rbx)
+ jc L(b1)
+ jz L(b2)
+
+L(b3): mov %rax, w1
+ mov %rdx, w2
+ xor R32(w3), R32(w3)
+ mov 8(up,n,8), %rax
+ dec n
+ jmp L(lo3)
+
+L(b2): mov %rax, w2
+ mov 8(up,n,8), %rax
+ mov %rdx, w3
+ xor R32(w0), R32(w0)
+ add $-2, n
+ jmp L(lo2)
+
+L(b1): mov %rax, w3
+ mov 8(up,n,8), %rax
+ mov %rdx, w0
+ xor R32(w1), R32(w1)
+ inc n
+ jmp L(lo1)
+
+L(b0): mov $0, R32(w3)
+ mov %rax, w0
+ mov 8(up,n,8), %rax
+ mov %rdx, w1
+ xor R32(w2), R32(w2)
+ jmp L(lo0)
+
+ ALIGN(32)
+L(top): mov $0, R32(w1)
+ mul v0
+ add %rax, w3
+ mov (up,n,8), %rax
+ adc %rdx, w0
+ adc $0, R32(w1)
+L(lo1): mul v1
+ add w3, (rp,n,8)
+ mov $0, R32(w3)
+ adc %rax, w0
+ mov $0, R32(w2)
+ mov 8(up,n,8), %rax
+ adc %rdx, w1
+ mul v0
+ add %rax, w0
+ mov 8(up,n,8), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+L(lo0): mul v1
+ add w0, 8(rp,n,8)
+ adc %rax, w1
+ adc %rdx, w2
+ mov 16(up,n,8), %rax
+ mul v0
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 16(up,n,8), %rax
+L(lo3): mul v1
+ add w1, 16(rp,n,8)
+ adc %rax, w2
+ adc %rdx, w3
+ xor R32(w0), R32(w0)
+ mov 24(up,n,8), %rax
+ mul v0
+ add %rax, w2
+ mov 24(up,n,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+L(lo2): mul v1
+ add w2, 24(rp,n,8)
+ adc %rax, w3
+ adc %rdx, w0
+ mov 32(up,n,8), %rax
+ add $4, n
+ js L(top)
+
+L(end): xor R32(w1), R32(w1)
+ mul v0
+ add %rax, w3
+ mov (up), %rax
+ adc %rdx, w0
+ adc R32(w1), R32(w1)
+ mul v1
+ add w3, (rp)
+ adc %rax, w0
+ adc %rdx, w1
+ mov w0, 8(rp)
+ mov w1, %rax
+
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/aorrlsh1_n.asm b/gmp/mpn/x86_64/aorrlsh1_n.asm
new file mode 100644
index 0000000000..6ee0872823
--- /dev/null
+++ b/gmp/mpn/x86_64/aorrlsh1_n.asm
@@ -0,0 +1,170 @@
+dnl AMD64 mpn_addlsh1_n -- rp[] = up[] + (vp[] << 1)
+dnl AMD64 mpn_rsblsh1_n -- rp[] = (vp[] << 1) - up[]
+
+dnl Copyright 2003, 2005-2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 2
+C AMD K10 2
+C AMD bd1 ?
+C AMD bobcat ?
+C Intel P4 13
+C Intel core2 3.45
+C Intel NHM ?
+C Intel SBR ?
+C Intel atom ?
+C VIA nano ?
+
+
+C Sometimes speed degenerates, supposedly related to that some operand
+C alignments cause cache conflicts.
+
+C The speed is limited by decoding/issue bandwidth. There are 22 instructions
+C in the loop, which corresponds to ceil(22/3)/4 = 1.83 c/l.
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`vp',`%rdx')
+define(`n', `%rcx')
+
+ifdef(`OPERATION_addlsh1_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func, mpn_addlsh1_n)')
+ifdef(`OPERATION_rsblsh1_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func, mpn_rsblsh1_n)')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_rsblsh1_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ push %rbp
+
+ mov (vp), %r8
+ mov R32(n), R32(%rax)
+ lea (rp,n,8), rp
+ lea (up,n,8), up
+ lea (vp,n,8), vp
+ neg n
+ xor R32(%rbp), R32(%rbp)
+ and $3, R32(%rax)
+ je L(b00)
+ cmp $2, R32(%rax)
+ jc L(b01)
+ je L(b10)
+
+L(b11): add %r8, %r8
+ mov 8(vp,n,8), %r9
+ adc %r9, %r9
+ mov 16(vp,n,8), %r10
+ adc %r10, %r10
+ sbb R32(%rax), R32(%rax) C save scy
+ ADDSUB (up,n,8), %r8
+ ADCSBB 8(up,n,8), %r9
+ mov %r8, (rp,n,8)
+ mov %r9, 8(rp,n,8)
+ ADCSBB 16(up,n,8), %r10
+ mov %r10, 16(rp,n,8)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ add $3, n
+ jmp L(ent)
+
+L(b10): add %r8, %r8
+ mov 8(vp,n,8), %r9
+ adc %r9, %r9
+ sbb R32(%rax), R32(%rax) C save scy
+ ADDSUB (up,n,8), %r8
+ ADCSBB 8(up,n,8), %r9
+ mov %r8, (rp,n,8)
+ mov %r9, 8(rp,n,8)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ add $2, n
+ jmp L(ent)
+
+L(b01): add %r8, %r8
+ sbb R32(%rax), R32(%rax) C save scy
+ ADDSUB (up,n,8), %r8
+ mov %r8, (rp,n,8)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ inc n
+L(ent): jns L(end)
+
+ ALIGN(16)
+L(top): add R32(%rax), R32(%rax) C restore scy
+
+ mov (vp,n,8), %r8
+L(b00): adc %r8, %r8
+ mov 8(vp,n,8), %r9
+ adc %r9, %r9
+ mov 16(vp,n,8), %r10
+ adc %r10, %r10
+ mov 24(vp,n,8), %r11
+ adc %r11, %r11
+
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+
+ ADCSBB (up,n,8), %r8
+ nop C Hammer speedup!
+ ADCSBB 8(up,n,8), %r9
+ mov %r8, (rp,n,8)
+ mov %r9, 8(rp,n,8)
+ ADCSBB 16(up,n,8), %r10
+ ADCSBB 24(up,n,8), %r11
+ mov %r10, 16(rp,n,8)
+ mov %r11, 24(rp,n,8)
+
+ sbb R32(%rbp), R32(%rbp) C save acy
+ add $4, n
+ js L(top)
+
+L(end):
+ifdef(`OPERATION_addlsh1_n',`
+ add R32(%rbp), R32(%rax)
+ neg R32(%rax)')
+ifdef(`OPERATION_rsblsh1_n',`
+ sub R32(%rax), R32(%rbp)
+ movslq R32(%rbp), %rax')
+
+ pop %rbp
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/aorrlsh2_n.asm b/gmp/mpn/x86_64/aorrlsh2_n.asm
new file mode 100644
index 0000000000..999e972fb4
--- /dev/null
+++ b/gmp/mpn/x86_64/aorrlsh2_n.asm
@@ -0,0 +1,53 @@
+dnl AMD64 mpn_addlsh2_n -- rp[] = up[] + (vp[] << 2)
+dnl AMD64 mpn_rsblsh2_n -- rp[] = (vp[] << 2) - up[]
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2009-2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 2)
+define(RSH, 62)
+
+ifdef(`OPERATION_addlsh2_n',`
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func, mpn_addlsh2_n)')
+ifdef(`OPERATION_rsblsh2_n',`
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func, mpn_rsblsh2_n)')
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_rsblsh2_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+include_mpn(`x86_64/aorrlshC_n.asm')
diff --git a/gmp/mpn/x86_64/aorrlshC_n.asm b/gmp/mpn/x86_64/aorrlshC_n.asm
new file mode 100644
index 0000000000..5a9fd4dfb9
--- /dev/null
+++ b/gmp/mpn/x86_64/aorrlshC_n.asm
@@ -0,0 +1,160 @@
+dnl AMD64 mpn_addlshC_n -- rp[] = up[] + (vp[] << C)
+dnl AMD64 mpn_rsblshC_n -- rp[] = (vp[] << C) - up[]
+
+dnl Copyright 2009-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+C cycles/limb
+C AMD K8,K9 2
+C AMD K10 2
+C Intel P4 ?
+C Intel core2 3
+C Intel NHM 2.75
+C Intel SBR 2.55
+C Intel atom ?
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+
+define(M, eval(m4_lshift(1,LSH)))
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov (vp), %r8
+ lea (,%r8,M), %r12
+ shr $RSH, %r8
+
+ mov R32(n), R32(%rax)
+ lea (rp,n,8), rp
+ lea (up,n,8), up
+ lea (vp,n,8), vp
+ neg n
+ and $3, R8(%rax)
+ je L(b00)
+ cmp $2, R8(%rax)
+ jc L(b01)
+ je L(b10)
+
+L(b11): mov 8(vp,n,8), %r10
+ lea (%r8,%r10,M), %r14
+ shr $RSH, %r10
+ mov 16(vp,n,8), %r11
+ lea (%r10,%r11,M), %r15
+ shr $RSH, %r11
+ ADDSUB (up,n,8), %r12
+ ADCSBB 8(up,n,8), %r14
+ ADCSBB 16(up,n,8), %r15
+ sbb R32(%rax), R32(%rax) C save carry for next
+ mov %r12, (rp,n,8)
+ mov %r14, 8(rp,n,8)
+ mov %r15, 16(rp,n,8)
+ add $3, n
+ js L(top)
+ jmp L(end)
+
+L(b01): mov %r8, %r11
+ ADDSUB (up,n,8), %r12
+ sbb R32(%rax), R32(%rax) C save carry for next
+ mov %r12, (rp,n,8)
+ add $1, n
+ js L(top)
+ jmp L(end)
+
+L(b10): mov 8(vp,n,8), %r11
+ lea (%r8,%r11,M), %r15
+ shr $RSH, %r11
+ ADDSUB (up,n,8), %r12
+ ADCSBB 8(up,n,8), %r15
+ sbb R32(%rax), R32(%rax) C save carry for next
+ mov %r12, (rp,n,8)
+ mov %r15, 8(rp,n,8)
+ add $2, n
+ js L(top)
+ jmp L(end)
+
+L(b00): mov 8(vp,n,8), %r9
+ mov 16(vp,n,8), %r10
+ jmp L(e00)
+
+ ALIGN(16)
+L(top): mov 16(vp,n,8), %r10
+ mov (vp,n,8), %r8
+ mov 8(vp,n,8), %r9
+ lea (%r11,%r8,M), %r12
+ shr $RSH, %r8
+L(e00): lea (%r8,%r9,M), %r13
+ shr $RSH, %r9
+ mov 24(vp,n,8), %r11
+ lea (%r9,%r10,M), %r14
+ shr $RSH, %r10
+ lea (%r10,%r11,M), %r15
+ shr $RSH, %r11
+ add R32(%rax), R32(%rax) C restore carry
+ ADCSBB (up,n,8), %r12
+ ADCSBB 8(up,n,8), %r13
+ ADCSBB 16(up,n,8), %r14
+ ADCSBB 24(up,n,8), %r15
+ mov %r12, (rp,n,8)
+ mov %r13, 8(rp,n,8)
+ mov %r14, 16(rp,n,8)
+ sbb R32(%rax), R32(%rax) C save carry for next
+ mov %r15, 24(rp,n,8)
+ add $4, n
+ js L(top)
+L(end):
+
+ifelse(ADDSUB,add,`
+ sub R32(%r11), R32(%rax)
+ neg R32(%rax)
+',`
+ add R32(%r11), R32(%rax)
+ movslq R32(%rax), %rax
+')
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/aorrlsh_n.asm b/gmp/mpn/x86_64/aorrlsh_n.asm
new file mode 100644
index 0000000000..5ca128fbf3
--- /dev/null
+++ b/gmp/mpn/x86_64/aorrlsh_n.asm
@@ -0,0 +1,176 @@
+dnl AMD64 mpn_addlsh_n and mpn_rsblsh_n. R = V2^k +- U.
+
+dnl Copyright 2006, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 3.1 < 3.85 for lshift + add_n
+C AMD K10 3.1 < 3.85 for lshift + add_n
+C Intel P4 14.6 > 7.33 for lshift + add_n
+C Intel core2 3.87 > 3.27 for lshift + add_n
+C Intel NHM 4 > 3.75 for lshift + add_n
+C Intel SBR (5.8) > 3.46 for lshift + add_n
+C Intel atom (7.75) < 8.75 for lshift + add_n
+C VIA nano 4.7 < 6.25 for lshift + add_n
+
+C This was written quickly and not optimized at all. Surely one could get
+C closer to 3 c/l or perhaps even under 3 c/l. Ideas:
+C 1) Use indexing to save the 3 LEA
+C 2) Write reasonable feed-in code
+C 3) Be more clever about register usage
+C 4) Unroll more, handling CL negation, carry save/restore cost much now
+C 5) Reschedule
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cnt', `%r8')
+
+ifdef(`OPERATION_addlsh_n',`
+ define(ADCSBB, `adc')
+ define(func, mpn_addlsh_n)
+')
+ifdef(`OPERATION_rsblsh_n',`
+ define(ADCSBB, `sbb')
+ define(func, mpn_rsblsh_n)
+')
+
+MULFUNC_PROLOGUE(mpn_addlsh_n mpn_rsblsh_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+ push %r12
+ push %r13
+ push %r14
+ push %rbp
+ push %rbx
+
+ mov n, %rax
+ xor R32(%rbx), R32(%rbx) C clear carry save register
+ mov R32(%r8), R32(%rcx) C shift count
+ xor R32(%rbp), R32(%rbp) C limb carry
+
+ mov R32(%rax), R32(%r11)
+ and $3, R32(%r11)
+ je L(4)
+ sub $1, R32(%r11)
+
+L(012): mov (vp), %r8
+ mov %r8, %r12
+ shl R8(%rcx), %r8
+ or %rbp, %r8
+ neg R8(%rcx)
+ mov %r12, %rbp
+ shr R8(%rcx), %rbp
+ neg R8(%rcx)
+ add R32(%rbx), R32(%rbx)
+ ADCSBB (up), %r8
+ mov %r8, (rp)
+ sbb R32(%rbx), R32(%rbx)
+ lea 8(up), up
+ lea 8(vp), vp
+ lea 8(rp), rp
+ sub $1, R32(%r11)
+ jnc L(012)
+
+L(4): sub $4, %rax
+ jc L(end)
+
+ ALIGN(16)
+L(top): mov (vp), %r8
+ mov %r8, %r12
+ mov 8(vp), %r9
+ mov %r9, %r13
+ mov 16(vp), %r10
+ mov %r10, %r14
+ mov 24(vp), %r11
+
+ shl R8(%rcx), %r8
+ shl R8(%rcx), %r9
+ shl R8(%rcx), %r10
+ or %rbp, %r8
+ mov %r11, %rbp
+ shl R8(%rcx), %r11
+
+ neg R8(%rcx)
+
+ shr R8(%rcx), %r12
+ shr R8(%rcx), %r13
+ shr R8(%rcx), %r14
+ shr R8(%rcx), %rbp C used next iteration
+
+ or %r12, %r9
+ or %r13, %r10
+ or %r14, %r11
+
+ neg R8(%rcx)
+
+ add R32(%rbx), R32(%rbx) C restore carry flag
+
+ ADCSBB (up), %r8
+ ADCSBB 8(up), %r9
+ ADCSBB 16(up), %r10
+ ADCSBB 24(up), %r11
+
+ mov %r8, (rp)
+ mov %r9, 8(rp)
+ mov %r10, 16(rp)
+ mov %r11, 24(rp)
+
+ sbb R32(%rbx), R32(%rbx) C save carry flag
+
+ lea 32(up), up
+ lea 32(vp), vp
+ lea 32(rp), rp
+
+ sub $4, %rax
+ jnc L(top)
+
+L(end): add R32(%rbx), R32(%rbx)
+ ADCSBB $0, %rbp
+ mov %rbp, %rax
+ pop %rbx
+ pop %rbp
+ pop %r14
+ pop %r13
+ pop %r12
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/aors_err1_n.asm b/gmp/mpn/x86_64/aors_err1_n.asm
new file mode 100644
index 0000000000..54d0b3f9b7
--- /dev/null
+++ b/gmp/mpn/x86_64/aors_err1_n.asm
@@ -0,0 +1,225 @@
+dnl AMD64 mpn_add_err1_n, mpn_sub_err1_n
+
+dnl Contributed by David Harvey.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.75 (degenerates to 3 c/l for some alignments)
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 ?
+C Intel corei ?
+C Intel atom ?
+C VIA nano ?
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`ep', `%rcx')
+define(`yp', `%r8')
+define(`n', `%r9')
+define(`cy_param', `8(%rsp)')
+
+define(`el', `%rbx')
+define(`eh', `%rbp')
+define(`t0', `%r10')
+define(`t1', `%r11')
+define(`t2', `%r12')
+define(`t3', `%r13')
+define(`w0', `%r14')
+define(`w1', `%r15')
+
+ifdef(`OPERATION_add_err1_n', `
+ define(ADCSBB, adc)
+ define(func, mpn_add_err1_n)')
+ifdef(`OPERATION_sub_err1_n', `
+ define(ADCSBB, sbb)
+ define(func, mpn_sub_err1_n)')
+
+MULFUNC_PROLOGUE(mpn_add_err1_n mpn_sub_err1_n)
+
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ mov cy_param, %rax
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ lea (up,n,8), up
+ lea (vp,n,8), vp
+ lea (rp,n,8), rp
+
+ mov R32(n), R32(%r10)
+ and $3, R32(%r10)
+ jz L(0mod4)
+ cmp $2, R32(%r10)
+ jc L(1mod4)
+ jz L(2mod4)
+L(3mod4):
+ xor R32(el), R32(el)
+ xor R32(eh), R32(eh)
+ xor R32(t0), R32(t0)
+ xor R32(t1), R32(t1)
+ lea -24(yp,n,8), yp
+ neg n
+
+ shr $1, %al C restore carry
+ mov (up,n,8), w0
+ mov 8(up,n,8), w1
+ ADCSBB (vp,n,8), w0
+ mov w0, (rp,n,8)
+ cmovc 16(yp), el
+ ADCSBB 8(vp,n,8), w1
+ mov w1, 8(rp,n,8)
+ cmovc 8(yp), t0
+ mov 16(up,n,8), w0
+ ADCSBB 16(vp,n,8), w0
+ mov w0, 16(rp,n,8)
+ cmovc (yp), t1
+ setc %al C save carry
+ add t0, el
+ adc $0, eh
+ add t1, el
+ adc $0, eh
+
+ add $3, n
+ jnz L(loop)
+ jmp L(end)
+
+ ALIGN(16)
+L(0mod4):
+ xor R32(el), R32(el)
+ xor R32(eh), R32(eh)
+ lea (yp,n,8), yp
+ neg n
+ jmp L(loop)
+
+ ALIGN(16)
+L(1mod4):
+ xor R32(el), R32(el)
+ xor R32(eh), R32(eh)
+ lea -8(yp,n,8), yp
+ neg n
+
+ shr $1, %al C restore carry
+ mov (up,n,8), w0
+ ADCSBB (vp,n,8), w0
+ mov w0, (rp,n,8)
+ cmovc (yp), el
+ setc %al C save carry
+
+ add $1, n
+ jnz L(loop)
+ jmp L(end)
+
+ ALIGN(16)
+L(2mod4):
+ xor R32(el), R32(el)
+ xor R32(eh), R32(eh)
+ xor R32(t0), R32(t0)
+ lea -16(yp,n,8), yp
+ neg n
+
+ shr $1, %al C restore carry
+ mov (up,n,8), w0
+ mov 8(up,n,8), w1
+ ADCSBB (vp,n,8), w0
+ mov w0, (rp,n,8)
+ cmovc 8(yp), el
+ ADCSBB 8(vp,n,8), w1
+ mov w1, 8(rp,n,8)
+ cmovc (yp), t0
+ setc %al C save carry
+ add t0, el
+ adc $0, eh
+
+ add $2, n
+ jnz L(loop)
+ jmp L(end)
+
+ ALIGN(32)
+L(loop):
+ shr $1, %al C restore carry
+ mov -8(yp), t0
+ mov $0, R32(t3)
+ mov (up,n,8), w0
+ mov 8(up,n,8), w1
+ ADCSBB (vp,n,8), w0
+ cmovnc t3, t0
+ ADCSBB 8(vp,n,8), w1
+ mov -16(yp), t1
+ mov w0, (rp,n,8)
+ mov 16(up,n,8), w0
+ mov w1, 8(rp,n,8)
+ cmovnc t3, t1
+ mov -24(yp), t2
+ ADCSBB 16(vp,n,8), w0
+ cmovnc t3, t2
+ mov 24(up,n,8), w1
+ ADCSBB 24(vp,n,8), w1
+ cmovc -32(yp), t3
+ setc %al C save carry
+ add t0, el
+ adc $0, eh
+ add t1, el
+ adc $0, eh
+ add t2, el
+ adc $0, eh
+ mov w0, 16(rp,n,8)
+ add t3, el
+ lea -32(yp), yp
+ adc $0, eh
+ mov w1, 24(rp,n,8)
+ add $4, n
+ jnz L(loop)
+
+L(end):
+ mov el, (ep)
+ mov eh, 8(ep)
+
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/aors_err2_n.asm b/gmp/mpn/x86_64/aors_err2_n.asm
new file mode 100644
index 0000000000..ce5c2a49b6
--- /dev/null
+++ b/gmp/mpn/x86_64/aors_err2_n.asm
@@ -0,0 +1,172 @@
+dnl AMD64 mpn_add_err2_n, mpn_sub_err2_n
+
+dnl Contributed by David Harvey.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 4.5
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 6.9
+C Intel corei ?
+C Intel atom ?
+C VIA nano ?
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`ep', `%rcx')
+define(`yp1', `%r8')
+define(`yp2', `%r9')
+define(`n_param', `8(%rsp)')
+define(`cy_param', `16(%rsp)')
+
+define(`cy1', `%r14')
+define(`cy2', `%rax')
+
+define(`n', `%r10')
+
+define(`w', `%rbx')
+define(`e1l', `%rbp')
+define(`e1h', `%r11')
+define(`e2l', `%r12')
+define(`e2h', `%r13')
+
+
+ifdef(`OPERATION_add_err2_n', `
+ define(ADCSBB, adc)
+ define(func, mpn_add_err2_n)')
+ifdef(`OPERATION_sub_err2_n', `
+ define(ADCSBB, sbb)
+ define(func, mpn_sub_err2_n)')
+
+MULFUNC_PROLOGUE(mpn_add_err2_n mpn_sub_err2_n)
+
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ mov cy_param, cy2
+ mov n_param, n
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+
+ xor R32(e1l), R32(e1l)
+ xor R32(e1h), R32(e1h)
+ xor R32(e2l), R32(e2l)
+ xor R32(e2h), R32(e2h)
+
+ sub yp1, yp2
+
+ lea (rp,n,8), rp
+ lea (up,n,8), up
+ lea (vp,n,8), vp
+
+ test $1, n
+ jnz L(odd)
+
+ lea -8(yp1,n,8), yp1
+ neg n
+ jmp L(top)
+
+ ALIGN(16)
+L(odd):
+ lea -16(yp1,n,8), yp1
+ neg n
+ shr $1, cy2
+ mov (up,n,8), w
+ ADCSBB (vp,n,8), w
+ cmovc 8(yp1), e1l
+ cmovc 8(yp1,yp2), e2l
+ mov w, (rp,n,8)
+ sbb cy2, cy2
+ inc n
+ jz L(end)
+
+ ALIGN(16)
+L(top):
+ mov (up,n,8), w
+ shr $1, cy2 C restore carry
+ ADCSBB (vp,n,8), w
+ mov w, (rp,n,8)
+ sbb cy1, cy1 C generate mask, preserve CF
+
+ mov 8(up,n,8), w
+ ADCSBB 8(vp,n,8), w
+ mov w, 8(rp,n,8)
+ sbb cy2, cy2 C generate mask, preserve CF
+
+ mov (yp1), w C (e1h:e1l) += cy1 * yp1 limb
+ and cy1, w
+ add w, e1l
+ adc $0, e1h
+
+ and (yp1,yp2), cy1 C (e2h:e2l) += cy1 * yp2 limb
+ add cy1, e2l
+ adc $0, e2h
+
+ mov -8(yp1), w C (e1h:e1l) += cy2 * next yp1 limb
+ and cy2, w
+ add w, e1l
+ adc $0, e1h
+
+ mov -8(yp1,yp2), w C (e2h:e2l) += cy2 * next yp2 limb
+ and cy2, w
+ add w, e2l
+ adc $0, e2h
+
+ add $2, n
+ lea -16(yp1), yp1
+ jnz L(top)
+L(end):
+
+ mov e1l, (ep)
+ mov e1h, 8(ep)
+ mov e2l, 16(ep)
+ mov e2h, 24(ep)
+
+ and $1, %eax C return carry
+
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/aors_err3_n.asm b/gmp/mpn/x86_64/aors_err3_n.asm
new file mode 100644
index 0000000000..bb6d0c5366
--- /dev/null
+++ b/gmp/mpn/x86_64/aors_err3_n.asm
@@ -0,0 +1,156 @@
+dnl AMD64 mpn_add_err3_n, mpn_sub_err3_n
+
+dnl Contributed by David Harvey.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 7.0
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 ?
+C Intel corei ?
+C Intel atom ?
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`ep', `%rcx')
+define(`yp1', `%r8')
+define(`yp2', `%r9')
+define(`yp3_param', `8(%rsp)')
+define(`n_param', `16(%rsp)')
+define(`cy_param', `24(%rsp)')
+
+define(`n', `%r10')
+define(`yp3', `%rcx')
+define(`t', `%rbx')
+
+define(`e1l', `%rbp')
+define(`e1h', `%r11')
+define(`e2l', `%r12')
+define(`e2h', `%r13')
+define(`e3l', `%r14')
+define(`e3h', `%r15')
+
+
+
+ifdef(`OPERATION_add_err3_n', `
+ define(ADCSBB, adc)
+ define(func, mpn_add_err3_n)')
+ifdef(`OPERATION_sub_err3_n', `
+ define(ADCSBB, sbb)
+ define(func, mpn_sub_err3_n)')
+
+MULFUNC_PROLOGUE(mpn_add_err3_n mpn_sub_err3_n)
+
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ mov cy_param, %rax
+ mov n_param, n
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ push ep
+ mov 64(%rsp), yp3 C load from yp3_param
+
+ xor R32(e1l), R32(e1l)
+ xor R32(e1h), R32(e1h)
+ xor R32(e2l), R32(e2l)
+ xor R32(e2h), R32(e2h)
+ xor R32(e3l), R32(e3l)
+ xor R32(e3h), R32(e3h)
+
+ sub yp1, yp2
+ sub yp1, yp3
+
+ lea -8(yp1,n,8), yp1
+ lea (rp,n,8), rp
+ lea (up,n,8), up
+ lea (vp,n,8), vp
+ neg n
+
+ ALIGN(16)
+L(top):
+ shr $1, %rax C restore carry
+ mov (up,n,8), %rax
+ ADCSBB (vp,n,8), %rax
+ mov %rax, (rp,n,8)
+ sbb %rax, %rax C save carry and generate mask
+
+ mov (yp1), t
+ and %rax, t
+ add t, e1l
+ adc $0, e1h
+
+ mov (yp1,yp2), t
+ and %rax, t
+ add t, e2l
+ adc $0, e2h
+
+ mov (yp1,yp3), t
+ and %rax, t
+ add t, e3l
+ adc $0, e3h
+
+ lea -8(yp1), yp1
+ inc n
+ jnz L(top)
+
+L(end):
+ and $1, %eax
+ pop ep
+
+ mov e1l, (ep)
+ mov e1h, 8(ep)
+ mov e2l, 16(ep)
+ mov e2h, 24(ep)
+ mov e3l, 32(ep)
+ mov e3h, 40(ep)
+
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/aors_n.asm b/gmp/mpn/x86_64/aors_n.asm
new file mode 100644
index 0000000000..8941f7a17b
--- /dev/null
+++ b/gmp/mpn/x86_64/aors_n.asm
@@ -0,0 +1,169 @@
+dnl AMD64 mpn_add_n, mpn_sub_n
+
+dnl Copyright 2003-2005, 2007, 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 1.5
+C AMD K10 1.5
+C AMD bd1 1.8
+C AMD bobcat 2.5
+C Intel P4
+C Intel core2 4.9
+C Intel NHM 5.5
+C Intel SBR 1.61
+C Intel IBR 1.61
+C Intel atom 4
+C VIA nano 3.25
+
+C The loop of this code is the result of running a code generation and
+C optimization tool suite written by David Harvey and Torbjorn Granlund.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`vp', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`cy', `%r8') C rsp+40 (mpn_add_nc and mpn_sub_nc)
+
+ifdef(`OPERATION_add_n', `
+ define(ADCSBB, adc)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(ADCSBB, sbb)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ mov R32(n), R32(%rax)
+ shr $2, n
+ and $3, R32(%rax)
+ bt $0, %r8 C cy flag <- carry parameter
+ jrcxz L(lt4)
+
+ mov (up), %r8
+ mov 8(up), %r9
+ dec n
+ jmp L(mid)
+
+EPILOGUE()
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ mov R32(n), R32(%rax)
+ shr $2, n
+ and $3, R32(%rax)
+ jrcxz L(lt4)
+
+ mov (up), %r8
+ mov 8(up), %r9
+ dec n
+ jmp L(mid)
+
+L(lt4): dec R32(%rax)
+ mov (up), %r8
+ jnz L(2)
+ ADCSBB (vp), %r8
+ mov %r8, (rp)
+ adc R32(%rax), R32(%rax)
+ FUNC_EXIT()
+ ret
+
+L(2): dec R32(%rax)
+ mov 8(up), %r9
+ jnz L(3)
+ ADCSBB (vp), %r8
+ ADCSBB 8(vp), %r9
+ mov %r8, (rp)
+ mov %r9, 8(rp)
+ adc R32(%rax), R32(%rax)
+ FUNC_EXIT()
+ ret
+
+L(3): mov 16(up), %r10
+ ADCSBB (vp), %r8
+ ADCSBB 8(vp), %r9
+ ADCSBB 16(vp), %r10
+ mov %r8, (rp)
+ mov %r9, 8(rp)
+ mov %r10, 16(rp)
+ setc R8(%rax)
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(top): ADCSBB (vp), %r8
+ ADCSBB 8(vp), %r9
+ ADCSBB 16(vp), %r10
+ ADCSBB 24(vp), %r11
+ mov %r8, (rp)
+ lea 32(up), up
+ mov %r9, 8(rp)
+ mov %r10, 16(rp)
+ dec n
+ mov %r11, 24(rp)
+ lea 32(vp), vp
+ mov (up), %r8
+ mov 8(up), %r9
+ lea 32(rp), rp
+L(mid): mov 16(up), %r10
+ mov 24(up), %r11
+ jnz L(top)
+
+L(end): lea 32(up), up
+ ADCSBB (vp), %r8
+ ADCSBB 8(vp), %r9
+ ADCSBB 16(vp), %r10
+ ADCSBB 24(vp), %r11
+ lea 32(vp), vp
+ mov %r8, (rp)
+ mov %r9, 8(rp)
+ mov %r10, 16(rp)
+ mov %r11, 24(rp)
+ lea 32(rp), rp
+
+ inc R32(%rax)
+ dec R32(%rax)
+ jnz L(lt4)
+ adc R32(%rax), R32(%rax)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/aorsmul_1.asm b/gmp/mpn/x86_64/aorsmul_1.asm
new file mode 100644
index 0000000000..e3fc005757
--- /dev/null
+++ b/gmp/mpn/x86_64/aorsmul_1.asm
@@ -0,0 +1,180 @@
+dnl AMD64 mpn_addmul_1 and mpn_submul_1.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.5
+C AMD K10 2.5
+C AMD bd1 5.0
+C AMD bobcat 6.17
+C Intel P4 14.9
+C Intel core2 5.09
+C Intel NHM 4.9
+C Intel SBR 4.0
+C Intel atom 21.3
+C VIA nano 5.0
+
+C The loop of this code is the result of running a code generation and
+C optimization tool suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * The loop is great, but the prologue and epilogue code was quickly written.
+C Tune it!
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`vl', `%rcx') C r9
+
+define(`n', `%r11')
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`func', `mpn_submul_1')
+')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+IFDOS(` define(`up', ``%rsi'') ') dnl
+IFDOS(` define(`rp', ``%rcx'') ') dnl
+IFDOS(` define(`vl', ``%r9'') ') dnl
+IFDOS(` define(`r9', ``rdi'') ') dnl
+IFDOS(` define(`n', ``%r8'') ') dnl
+IFDOS(` define(`r8', ``r11'') ') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+
+IFDOS(``push %rsi '')
+IFDOS(``push %rdi '')
+IFDOS(``mov %rdx, %rsi '')
+
+ mov (up), %rax C read first u limb early
+ push %rbx
+IFSTD(` mov n_param, %rbx ') C move away n from rdx, mul uses it
+IFDOS(` mov n, %rbx ')
+ mul vl
+IFSTD(` mov %rbx, n ')
+
+ and $3, R32(%rbx)
+ jz L(b0)
+ cmp $2, R32(%rbx)
+ jz L(b2)
+ jg L(b3)
+
+L(b1): dec n
+ jne L(gt1)
+ ADDSUB %rax, (rp)
+ jmp L(ret)
+L(gt1): lea 8(up,n,8), up
+ lea -8(rp,n,8), rp
+ neg n
+ xor %r10, %r10
+ xor R32(%rbx), R32(%rbx)
+ mov %rax, %r9
+ mov (up,n,8), %rax
+ mov %rdx, %r8
+ jmp L(L1)
+
+L(b0): lea (up,n,8), up
+ lea -16(rp,n,8), rp
+ neg n
+ xor %r10, %r10
+ mov %rax, %r8
+ mov %rdx, %rbx
+ jmp L(L0)
+
+L(b3): lea -8(up,n,8), up
+ lea -24(rp,n,8), rp
+ neg n
+ mov %rax, %rbx
+ mov %rdx, %r10
+ jmp L(L3)
+
+L(b2): lea -16(up,n,8), up
+ lea -32(rp,n,8), rp
+ neg n
+ xor %r8, %r8
+ xor R32(%rbx), R32(%rbx)
+ mov %rax, %r10
+ mov 24(up,n,8), %rax
+ mov %rdx, %r9
+ jmp L(L2)
+
+ ALIGN(16)
+L(top): ADDSUB %r10, (rp,n,8)
+ adc %rax, %r9
+ mov (up,n,8), %rax
+ adc %rdx, %r8
+ mov $0, R32(%r10)
+L(L1): mul vl
+ ADDSUB %r9, 8(rp,n,8)
+ adc %rax, %r8
+ adc %rdx, %rbx
+L(L0): mov 8(up,n,8), %rax
+ mul vl
+ ADDSUB %r8, 16(rp,n,8)
+ adc %rax, %rbx
+ adc %rdx, %r10
+L(L3): mov 16(up,n,8), %rax
+ mul vl
+ ADDSUB %rbx, 24(rp,n,8)
+ mov $0, R32(%r8) C zero
+ mov %r8, %rbx C zero
+ adc %rax, %r10
+ mov 24(up,n,8), %rax
+ mov %r8, %r9 C zero
+ adc %rdx, %r9
+L(L2): mul vl
+ add $4, n
+ js L(top)
+
+ ADDSUB %r10, (rp,n,8)
+ adc %rax, %r9
+ adc %r8, %rdx
+ ADDSUB %r9, 8(rp,n,8)
+L(ret): adc $0, %rdx
+ mov %rdx, %rax
+
+ pop %rbx
+IFDOS(``pop %rdi '')
+IFDOS(``pop %rsi '')
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/atom/addmul_2.asm b/gmp/mpn/x86_64/atom/addmul_2.asm
new file mode 100644
index 0000000000..c1dcdc44aa
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/addmul_2.asm
@@ -0,0 +1,186 @@
+dnl AMD64 mpn_addmul_2 optimised for Intel Atom.
+
+dnl Copyright 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C AMD K8,K9
+C AMD K10
+C AMD bd1
+C AMD bd2
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel PNR
+C Intel NHM
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom 18.8 this
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`vp', `%rcx') C r9
+
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+define(`n', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_addmul_2)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov (up), %rax
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ mov n_param, n
+ mul v0
+
+ test $1, R8(n)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n)
+ jnz L(b10)
+
+L(b00): mov %rax, w0
+ mov (up), %rax
+ mov %rdx, w1
+ xor R32(w2), R32(w2)
+ lea -8(rp), rp
+ jmp L(lo0)
+
+L(b10): mov %rax, w2
+ mov (up), %rax
+ mov %rdx, w3
+ xor R32(w0), R32(w0)
+ lea -16(up), up
+ lea -24(rp), rp
+ jmp L(lo2)
+
+L(bx1): test $2, R8(n)
+ jnz L(b11)
+
+L(b01): mov %rax, w3
+ mov %rdx, w0
+ mov (up), %rax
+ xor R32(w1), R32(w1)
+ lea 8(up), up
+ dec n
+ jmp L(lo1)
+
+L(b11): mov %rax, w1
+ mov (up), %rax
+ mov %rdx, w2
+ xor R32(w3), R32(w3)
+ lea -8(up), up
+ lea -16(rp), rp
+ jmp L(lo3)
+
+ ALIGN(16)
+L(top):
+L(lo1): mul v1
+ add w3, (rp)
+ mov $0, R32(w2)
+ adc %rax, w0
+ mov (up), %rax
+ adc %rdx, w1
+ mul v0
+ add %rax, w0
+ mov (up), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+L(lo0): mul v1
+ add w0, 8(rp)
+ adc %rax, w1
+ mov 8(up), %rax
+ mov $0, R32(w3)
+ adc %rdx, w2
+ mul v0
+ add %rax, w1
+ mov 8(up), %rax
+ adc %rdx, w2
+ adc $0, R32(w3)
+L(lo3): mul v1
+ add w1, 16(rp)
+ adc %rax, w2
+ mov 16(up), %rax
+ mov $0, R32(w0)
+ adc %rdx, w3
+ mul v0
+ add %rax, w2
+ mov 16(up), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+L(lo2): mul v1
+ add w2, 24(rp)
+ adc %rax, w3
+ mov 24(up), %rax
+ adc %rdx, w0
+ mov $0, R32(w1)
+ lea 32(rp), rp
+ mul v0
+ lea 32(up), up
+ add %rax, w3
+ adc %rdx, w0
+ mov -8(up), %rax
+ adc $0, R32(w1)
+ sub $4, n
+ ja L(top)
+
+L(end): mul v1
+ add w3, (rp)
+ adc %rax, w0
+ adc %rdx, w1
+ mov w0, 8(rp)
+ mov w1, %rax
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/atom/aorrlsh1_n.asm b/gmp/mpn/x86_64/atom/aorrlsh1_n.asm
new file mode 100644
index 0000000000..f44de19fef
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/aorrlsh1_n.asm
@@ -0,0 +1,238 @@
+dnl AMD64 mpn_addlsh1_n, mpn_rsblsh1_n optimised for Intel Atom.
+dnl Used also for AMD bd1.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO
+C * This code is slightly large at 433 bytes.
+C * sublsh1_n.asm and this file use the same basic pattern.
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C AMD bd1 2.3
+C AMD bobcat ?
+C Intel P4 ?
+C Intel core2 ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel atom 4.875 (4.75 is probably possible)
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cy', `%r8')
+
+ifdef(`OPERATION_addlsh1_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func_n, mpn_addlsh1_n)
+ define(func_nc, mpn_addlsh1_nc)')
+ifdef(`OPERATION_rsblsh1_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func_n, mpn_rsblsh1_n)
+ define(func_nc, mpn_rsblsh1_nc)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_addlsh1_nc mpn_rsblsh1_n mpn_rsblsh1_nc)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func_n)
+ FUNC_ENTRY(4)
+ push %rbp
+ xor R32(%rbp), R32(%rbp)
+L(ent): mov R32(n), R32(%rax)
+ and $3, R32(%rax)
+ jz L(b0)
+ cmp $2, R32(%rax)
+ jz L(b2)
+ jg L(b3)
+
+L(b1): mov (vp), %r8
+ add %r8, %r8
+ lea 8(vp), vp
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+ ADCSBB (up), %r8
+ mov %r8, (rp)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ lea 8(up), up
+ lea 8(rp), rp
+ jmp L(b0)
+
+L(b2): mov (vp), %r8
+ add %r8, %r8
+ mov 8(vp), %r9
+ adc %r9, %r9
+ lea 16(vp), vp
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+ ADCSBB (up), %r8
+ mov %r8, (rp)
+ ADCSBB 8(up), %r9
+ mov %r9, 8(rp)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ lea 16(up), up
+ lea 16(rp), rp
+ jmp L(b0)
+
+L(b3): mov (vp), %r8
+ add %r8, %r8
+ mov 8(vp), %r9
+ adc %r9, %r9
+ mov 16(vp), %r10
+ adc %r10, %r10
+ lea 24(vp), vp
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+ ADCSBB (up), %r8
+ mov %r8, (rp)
+ ADCSBB 8(up), %r9
+ mov %r9, 8(rp)
+ ADCSBB 16(up), %r10
+ mov %r10, 16(rp)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ lea 24(up), up
+ lea 24(rp), rp
+
+L(b0): test $4, R8(n)
+ jz L(skp)
+ add R32(%rax), R32(%rax) C restore scy
+ mov (vp), %r8
+ adc %r8, %r8
+ mov 8(vp), %r9
+ adc %r9, %r9
+ mov 16(vp), %r10
+ adc %r10, %r10
+ mov 24(vp), %r11
+ adc %r11, %r11
+ lea 32(vp), vp
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+ ADCSBB (up), %r8
+ mov %r8, (rp)
+ ADCSBB 8(up), %r9
+ mov %r9, 8(rp)
+ ADCSBB 16(up), %r10
+ mov %r10, 16(rp)
+ ADCSBB 24(up), %r11
+ mov %r11, 24(rp)
+ lea 32(up), up
+ lea 32(rp), rp
+ sbb R32(%rbp), R32(%rbp) C save acy
+
+L(skp): cmp $8, n
+ jl L(rtn)
+
+ push %r12
+ push %r13
+ push %r14
+ push %rbx
+ lea -64(rp), rp
+ jmp L(x)
+
+ ALIGN(16)
+L(top): add R32(%rax), R32(%rax) C restore scy
+ lea 64(rp), rp
+ mov (vp), %r8
+ adc %r8, %r8
+ mov 8(vp), %r9
+ adc %r9, %r9
+ mov 16(vp), %r10
+ adc %r10, %r10
+ mov 24(vp), %r11
+ adc %r11, %r11
+ mov 32(vp), %r12
+ adc %r12, %r12
+ mov 40(vp), %r13
+ adc %r13, %r13
+ mov 48(vp), %r14
+ adc %r14, %r14
+ mov 56(vp), %rbx
+ adc %rbx, %rbx
+ lea 64(vp), vp
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+ ADCSBB (up), %r8
+ mov %r8, (rp)
+ ADCSBB 8(up), %r9
+ mov %r9, 8(rp)
+ ADCSBB 16(up), %r10
+ mov %r10, 16(rp)
+ ADCSBB 24(up), %r11
+ mov %r11, 24(rp)
+ ADCSBB 32(up), %r12
+ mov %r12, 32(rp)
+ ADCSBB 40(up), %r13
+ mov %r13, 40(rp)
+ ADCSBB 48(up), %r14
+ mov %r14, 48(rp)
+ ADCSBB 56(up), %rbx
+ mov %rbx, 56(rp)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ lea 64(up), up
+L(x): sub $8, n
+ jge L(top)
+
+L(end): pop %rbx
+ pop %r14
+ pop %r13
+ pop %r12
+L(rtn):
+ifdef(`OPERATION_addlsh1_n',`
+ add R32(%rbp), R32(%rax)
+ neg R32(%rax)')
+ifdef(`OPERATION_rsblsh1_n',`
+ sub R32(%rax), R32(%rbp)
+ movslq R32(%rbp), %rax')
+
+ pop %rbp
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbp
+ neg %r8 C set CF
+ sbb R32(%rbp), R32(%rbp) C save acy
+ jmp L(ent)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/atom/aorrlsh2_n.asm b/gmp/mpn/x86_64/atom/aorrlsh2_n.asm
new file mode 100644
index 0000000000..02fb29dd74
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/aorrlsh2_n.asm
@@ -0,0 +1,191 @@
+dnl AMD64 mpn_addlsh2_n -- rp[] = up[] + (vp[] << 2)
+dnl AMD64 mpn_rsblsh2_n -- rp[] = (vp[] << 2) - up[]
+dnl Optimised for Intel Atom.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel atom 5.75
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+
+define(`LSH', 2)
+define(`RSH', 62)
+define(M, eval(m4_lshift(1,LSH)))
+
+ifdef(`OPERATION_addlsh2_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func_n, mpn_addlsh2_n)
+ define(func_nc, mpn_addlsh2_nc)')
+ifdef(`OPERATION_rsblsh2_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func_n, mpn_rsblsh2_n)
+ define(func_nc, mpn_rsblsh2_nc)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_rsblsh2_n)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func_n)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov R32(n), R32(%rax)
+ and $3, R32(%rax)
+ jz L(b0) C we rely on rax = 0 at target
+ cmp $2, R32(%rax)
+ mov $0, R32(%rax)
+ jz L(b2)
+ jg L(b3)
+
+L(b1): mov (vp), %r9
+ lea (%rax,%r9,M), %rbp
+ shr $RSH, %r9
+ sub $1, n
+ lea -8(up), up
+ lea -8(rp), rp
+ jz L(cj1)
+ mov 8(vp), %r10
+ lea (%r9,%r10,M), %r9
+ shr $RSH, %r10
+ mov 16(vp), %r11
+ lea 24(vp), vp
+ mov (vp), %r8
+ lea (%r10,%r11,M), %r10
+ shr $RSH, %r11
+ add R32(%rax), R32(%rax)
+ jmp L(L1)
+
+L(b2): lea -32(rp), rp
+ mov (vp), %r8
+ lea -32(up), up
+ lea (%rax,%r8,M), %rbx
+ shr $RSH, %r8
+ mov 8(vp), %r9
+ sub $2, n
+ jle L(end)
+ jmp L(top)
+
+L(b3): lea -24(up), up
+ mov (vp), %r11
+ lea -24(rp), rp
+ mov 8(vp), %r8
+ lea (%rax,%r11,M), %r10
+ shr $RSH, %r11
+ lea 8(vp), vp
+ lea (%r11,%r8,M), %rbx
+ add $1, n
+ jmp L(L3)
+
+L(b0): lea -16(up), up
+ mov (vp), %r10
+ lea (%rax,%r10,M), %r9
+ shr $RSH, %r10
+ mov 8(vp), %r11
+ lea -16(rp), rp
+ mov 16(vp), %r8
+ lea (%r10,%r11,M), %r10
+ shr $RSH, %r11
+ add R32(%rax), R32(%rax)
+ lea 16(vp), vp
+ jmp L(L0)
+
+ ALIGN(16)
+L(top): lea (%r8,%r9,M), %rbp
+ shr $RSH, %r9
+ lea 32(up), up
+ mov 16(vp), %r10
+ lea (%r9,%r10,M), %r9
+ shr $RSH, %r10
+ mov 24(vp), %r11
+ lea 32(rp), rp
+ lea 32(vp), vp
+ mov (vp), %r8
+ lea (%r10,%r11,M), %r10
+ shr $RSH, %r11
+ add R32(%rax), R32(%rax)
+ ADCSBB (up), %rbx
+ mov %rbx, (rp)
+L(L1): ADCSBB 8(up), %rbp
+ mov %rbp, 8(rp)
+L(L0): ADCSBB 16(up), %r9
+ lea (%r11,%r8,M), %rbx
+ mov %r9, 16(rp)
+L(L3): ADCSBB 24(up), %r10
+ sbb R32(%rax), R32(%rax)
+L(L2): shr $RSH, %r8
+ mov 8(vp), %r9
+ mov %r10, 24(rp)
+ sub $4, n
+ jg L(top)
+
+L(end): lea (%r8,%r9,M), %rbp
+ shr $RSH, %r9
+ lea 32(up), up
+ lea 32(rp), rp
+ add R32(%rax), R32(%rax)
+ ADCSBB (up), %rbx
+ mov %rbx, (rp)
+L(cj1): ADCSBB 8(up), %rbp
+ mov %rbp, 8(rp)
+
+ifdef(`OPERATION_addlsh2_n',`
+ mov R32(n), R32(%rax) C zero rax
+ adc %r9, %rax')
+ifdef(`OPERATION_rsblsh2_n',`
+ sbb n, %r9 C subtract 0
+ mov %r9, %rax')
+
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/atom/aors_n.asm b/gmp/mpn/x86_64/atom/aors_n.asm
new file mode 100644
index 0000000000..2c0b7b31a8
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/aors_n.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_add_n, mpn_sub_n, optimized for Intel Atom.
+
+dnl Copyright 2003-2005, 2007, 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+include_mpn(`x86_64/coreisbr/aors_n.asm')
diff --git a/gmp/mpn/x86_64/atom/aorsmul_1.asm b/gmp/mpn/x86_64/atom/aorsmul_1.asm
new file mode 100644
index 0000000000..e95315347c
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/aorsmul_1.asm
@@ -0,0 +1,190 @@
+dnl AMD64 mpn_addmul_1/mpn_submul_1 optimised for Intel Atom.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C AMD K8,K9
+C AMD K10
+C AMD bd1
+C AMD bd2
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel PNR
+C Intel NHM
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom 19.37 this
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0', `%rcx') C r9
+
+define(`n', `%rbx')
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`func', `mpn_submul_1')
+')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ push %rbx
+
+ mov (up), %rax
+ lea -8(up,n_param,8), up
+ lea -16(rp,n_param,8), rp
+
+ test $1, R8(n_param)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n_param)
+ jnz L(b10)
+
+L(b00): mov $1, R32(n)
+ sub n_param, n
+ mul v0
+ mov %rax, %r11
+ mov 8(up,n,8), %rax
+ mov %rdx, %r10
+ mul v0
+ mov %rax, %r8
+ mov 16(up,n,8), %rax
+ jmp L(lo0)
+
+L(b10): mov $3, R32(n)
+ sub n_param, n
+ mul v0
+ mov %rax, %r11
+ mov -8(up,n,8), %rax
+ mov %rdx, %r10
+ mul v0
+ test n, n
+ jns L(cj2)
+ mov %rax, %r8
+ mov (up,n,8), %rax
+ mov %rdx, %r9
+ jmp L(lo2)
+
+L(bx1): test $2, R8(n_param)
+ jnz L(b11)
+
+L(b01): mov $2, R32(n)
+ sub n_param, n
+ mul v0
+ test n, n
+ jns L(cj1)
+ mov %rax, %r8
+ mov (up,n,8), %rax
+ mov %rdx, %r9
+ mul v0
+ mov %rax, %r11
+ mov 8(up,n,8), %rax
+ mov %rdx, %r10
+ jmp L(lo1)
+
+L(b11): xor R32(n), R32(n)
+ sub n_param, n
+ mul v0
+ mov %rax, %r8
+ mov 16(up,n,8), %rax
+ mov %rdx, %r9
+ mul v0
+ mov %rax, %r11
+ mov 24(up,n,8), %rax
+ jmp L(lo3)
+
+ ALIGN(16)
+L(top): mul v0
+ ADDSUB %r8, -16(rp,n,8)
+ mov %rax, %r8
+ mov (up,n,8), %rax
+ adc %r9, %r11
+ mov %rdx, %r9
+ adc $0, %r10
+L(lo2): mul v0
+ ADDSUB %r11, -8(rp,n,8)
+ mov %rax, %r11
+ mov 8(up,n,8), %rax
+ adc %r10, %r8
+ mov %rdx, %r10
+ adc $0, %r9
+L(lo1): mul v0
+ ADDSUB %r8, (rp,n,8)
+ mov %rax, %r8
+ adc %r9, %r11
+ mov 16(up,n,8), %rax
+ adc $0, %r10
+L(lo0): mov %rdx, %r9
+ mul v0
+ ADDSUB %r11, 8(rp,n,8)
+ mov %rax, %r11
+ adc %r10, %r8
+ mov 24(up,n,8), %rax
+ adc $0, %r9
+L(lo3): add $4, n
+ mov %rdx, %r10
+ js L(top)
+
+L(end): mul v0
+ ADDSUB %r8, -16(rp,n,8)
+ adc %r9, %r11
+ adc $0, %r10
+L(cj2): ADDSUB %r11, -8(rp,n,8)
+ adc %r10, %rax
+ adc $0, %rdx
+L(cj1): ADDSUB %rax, (rp,n,8)
+ mov $0, R32(%rax)
+ adc %rdx, %rax
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/atom/com.asm b/gmp/mpn/x86_64/atom/com.asm
new file mode 100644
index 0000000000..6b6460fffe
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/com.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_com optimised for Intel Atom.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_com)
+include_mpn(`x86_64/fastsse/com-palignr.asm')
diff --git a/gmp/mpn/x86_64/atom/copyd.asm b/gmp/mpn/x86_64/atom/copyd.asm
new file mode 100644
index 0000000000..e3092794c0
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/copyd.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_copyd optimised for Intel Atom.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_copyd)
+include_mpn(`x86_64/fastsse/copyd-palignr.asm')
diff --git a/gmp/mpn/x86_64/atom/copyi.asm b/gmp/mpn/x86_64/atom/copyi.asm
new file mode 100644
index 0000000000..00ec3c23c6
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/copyi.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_copyi optimised for Intel Atom.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_copyi)
+include_mpn(`x86_64/fastsse/copyi-palignr.asm')
diff --git a/gmp/mpn/x86_64/atom/dive_1.asm b/gmp/mpn/x86_64/atom/dive_1.asm
new file mode 100644
index 0000000000..d9ba5fe6f0
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/dive_1.asm
@@ -0,0 +1,37 @@
+dnl AMD64 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_divexact_1)
+include_mpn(`x86_64/nano/dive_1.asm')
diff --git a/gmp/mpn/x86_64/atom/gmp-mparam.h b/gmp/mpn/x86_64/atom/gmp-mparam.h
new file mode 100644
index 0000000000..6816dfc362
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/gmp-mparam.h
@@ -0,0 +1,220 @@
+/* Intel Atom/64 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2010, 2012, 2014 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+#define SHLD_SLOW 1
+#define SHRD_SLOW 1
+
+/* 1667 MHz Pineview (Atom D510) */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-13, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD MP_SIZE_T_MAX
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 12
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 15
+
+#define MUL_TOOM22_THRESHOLD 12
+#define MUL_TOOM33_THRESHOLD 74
+#define MUL_TOOM44_THRESHOLD 118
+#define MUL_TOOM6H_THRESHOLD 157
+#define MUL_TOOM8H_THRESHOLD 212
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 84
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 81
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 80
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 58
+
+#define SQR_BASECASE_THRESHOLD 6
+#define SQR_TOOM2_THRESHOLD 23
+#define SQR_TOOM3_THRESHOLD 49
+#define SQR_TOOM4_THRESHOLD 130
+#define SQR_TOOM6_THRESHOLD 173
+#define SQR_TOOM8_THRESHOLD 238
+
+#define MULMID_TOOM42_THRESHOLD 16
+
+#define MULMOD_BNM1_THRESHOLD 10
+#define SQRMOD_BNM1_THRESHOLD 12
+
+#define MUL_FFT_MODF_THRESHOLD 252 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 252, 5}, { 11, 6}, { 6, 5}, { 13, 6}, \
+ { 7, 5}, { 15, 6}, { 13, 7}, { 7, 6}, \
+ { 15, 7}, { 8, 6}, { 17, 7}, { 9, 6}, \
+ { 19, 7}, { 13, 8}, { 7, 7}, { 17, 8}, \
+ { 9, 7}, { 19, 8}, { 11, 7}, { 23, 8}, \
+ { 13, 9}, { 7, 8}, { 15, 7}, { 31, 8}, \
+ { 19, 9}, { 11, 8}, { 25, 9}, { 15, 8}, \
+ { 33, 9}, { 19, 8}, { 39, 9}, { 23,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 47,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79,10}, { 47,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255,10}, { 71, 9}, { 143, 8}, \
+ { 287,10}, { 79,11}, { 47,10}, { 95,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511, 9}, { 287, 8}, { 575,11}, { 79,10}, \
+ { 159, 9}, { 319,10}, { 175, 9}, { 351, 8}, \
+ { 703,11}, { 95,10}, { 191, 9}, { 383, 8}, \
+ { 767,10}, { 207, 9}, { 415,10}, { 223,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,11}, \
+ { 143,10}, { 287, 9}, { 575, 8}, { 1151,10}, \
+ { 319, 9}, { 639,11}, { 175,10}, { 351, 9}, \
+ { 703, 8}, { 1407, 7}, { 2815,10}, { 383,11}, \
+ { 207,10}, { 415,11}, { 223,10}, { 447,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 287,10}, { 575, 9}, { 1151,12}, { 159,11}, \
+ { 319,10}, { 639,11}, { 351,10}, { 703, 9}, \
+ { 1407,12}, { 191,11}, { 415,12}, { 223,11}, \
+ { 447,10}, { 895,11}, { 479,13}, { 127,12}, \
+ { 255,11}, { 511,12}, { 287,11}, { 575,10}, \
+ { 1151,12}, { 319,11}, { 639,12}, { 351,11}, \
+ { 703,10}, { 1407,13}, { 191,12}, { 383,11}, \
+ { 767,12}, { 415,11}, { 831,12}, { 447,11}, \
+ { 895,12}, { 479,14}, { 127,13}, { 255,12}, \
+ { 511,11}, { 1023,12}, { 575,11}, { 1151,13}, \
+ { 319,12}, { 703,11}, { 1407,13}, { 383,12}, \
+ { 831,13}, { 447,12}, { 895,11}, { 1791,14}, \
+ { 255,13}, { 511,12}, { 1023,13}, { 575,12}, \
+ { 1151,13}, { 703,12}, { 1407,14}, { 383,13}, \
+ { 831,12}, { 1663,13}, { 895,12}, { 1791,15}, \
+ { 255,14}, { 511,13}, { 1087,12}, { 2175,13}, \
+ { 1151,14}, { 639,13}, { 1407,12}, { 2815,14}, \
+ { 767,13}, { 1663,14}, { 895,13}, { 1919,12}, \
+ { 3839,15}, { 511,14}, { 1023,13}, { 2175,14}, \
+ { 1151,13}, { 2431,14}, { 1407,13}, { 2815,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 185
+#define MUL_FFT_THRESHOLD 2240
+
+#define SQR_FFT_MODF_THRESHOLD 208 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 208, 5}, { 11, 6}, { 6, 5}, { 13, 6}, \
+ { 13, 7}, { 7, 6}, { 15, 7}, { 13, 8}, \
+ { 7, 7}, { 17, 8}, { 9, 7}, { 19, 8}, \
+ { 11, 7}, { 23, 8}, { 13, 9}, { 7, 8}, \
+ { 19, 9}, { 11, 8}, { 23,10}, { 7, 9}, \
+ { 15, 8}, { 31, 9}, { 23,10}, { 15, 9}, \
+ { 39,10}, { 23,11}, { 15,10}, { 31, 9}, \
+ { 63, 8}, { 127,10}, { 39, 9}, { 79, 8}, \
+ { 159,10}, { 47, 8}, { 191,10}, { 55,11}, \
+ { 31,10}, { 63, 9}, { 127, 8}, { 255,10}, \
+ { 71, 9}, { 143, 8}, { 287, 7}, { 575,10}, \
+ { 79, 9}, { 159,11}, { 47, 9}, { 191,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511,10}, { 143, 9}, { 287, 8}, { 575,10}, \
+ { 159, 9}, { 319, 8}, { 639,10}, { 175, 9}, \
+ { 351, 8}, { 703,10}, { 191, 9}, { 383,10}, \
+ { 207,11}, { 111,10}, { 223, 9}, { 447,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,11}, \
+ { 143,10}, { 287, 9}, { 575,11}, { 159,10}, \
+ { 319, 9}, { 639,11}, { 175,10}, { 351, 9}, \
+ { 703,11}, { 191,10}, { 383,11}, { 207,10}, \
+ { 415,11}, { 223,10}, { 447,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 511,11}, { 287,10}, \
+ { 575,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 415,12}, { 223,11}, { 447,10}, \
+ { 895,13}, { 127,12}, { 255,11}, { 511,12}, \
+ { 287,11}, { 575,12}, { 319,11}, { 639,12}, \
+ { 351,11}, { 703,13}, { 191,12}, { 383,11}, \
+ { 767,12}, { 415,11}, { 831,12}, { 447,11}, \
+ { 895,14}, { 127,13}, { 255,12}, { 511,11}, \
+ { 1023,12}, { 575,11}, { 1151,13}, { 319,12}, \
+ { 703,11}, { 1407,13}, { 383,12}, { 831,13}, \
+ { 447,12}, { 895,14}, { 255,13}, { 511,12}, \
+ { 1023,13}, { 575,12}, { 1151,13}, { 703,12}, \
+ { 1407,14}, { 383,13}, { 831,12}, { 1663,13}, \
+ { 895,15}, { 255,14}, { 511,13}, { 1087,12}, \
+ { 2175,13}, { 1151,14}, { 639,13}, { 1407,12}, \
+ { 2815,14}, { 767,13}, { 1663,14}, { 895,13}, \
+ { 1791,12}, { 3583,15}, { 511,14}, { 1023,13}, \
+ { 2047,14}, { 1151,13}, { 2431,12}, { 4863,14}, \
+ { 1407,13}, { 2815,15}, { 32768,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 175
+#define SQR_FFT_THRESHOLD 1600
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 34
+#define MULLO_MUL_N_THRESHOLD 4392
+
+#define DC_DIV_QR_THRESHOLD 32
+#define DC_DIVAPPR_Q_THRESHOLD 122
+#define DC_BDIV_QR_THRESHOLD 35
+#define DC_BDIV_Q_THRESHOLD 76
+
+#define INV_MULMOD_BNM1_THRESHOLD 22
+#define INV_NEWTON_THRESHOLD 163
+#define INV_APPR_THRESHOLD 134
+
+#define BINV_NEWTON_THRESHOLD 179
+#define REDC_1_TO_REDC_2_THRESHOLD 17
+#define REDC_2_TO_REDC_N_THRESHOLD 43
+
+#define MU_DIV_QR_THRESHOLD 855
+#define MU_DIVAPPR_Q_THRESHOLD 872
+#define MUPI_DIV_QR_THRESHOLD 83
+#define MU_BDIV_QR_THRESHOLD 748
+#define MU_BDIV_Q_THRESHOLD 807
+
+#define POWM_SEC_TABLE 1,16,114,452,1603
+
+#define MATRIX22_STRASSEN_THRESHOLD 13
+#define HGCD_THRESHOLD 102
+#define HGCD_APPR_THRESHOLD 95
+#define HGCD_REDUCE_THRESHOLD 1329
+#define GCD_DC_THRESHOLD 268
+#define GCDEXT_DC_THRESHOLD 221
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 14
+#define GET_STR_PRECOMPUTE_THRESHOLD 26
+#define SET_STR_DC_THRESHOLD 418
+#define SET_STR_PRECOMPUTE_THRESHOLD 1420
+
+#define FAC_DSC_THRESHOLD 1065
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/x86_64/atom/lshift.asm b/gmp/mpn/x86_64/atom/lshift.asm
new file mode 100644
index 0000000000..1b37d5dccf
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/lshift.asm
@@ -0,0 +1,123 @@
+dnl AMD64 mpn_lshift -- mpn left shift, optimised for Atom.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel atom 4.5
+C VIA nano ?
+
+C TODO
+C * Consider using 4-way unrolling. We reach 4 c/l, but the code is 2.5 times
+C larger.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_lshift)
+ FUNC_ENTRY(4)
+ lea -8(up,n,8), up
+ lea -8(rp,n,8), rp
+ shr R32(n)
+ mov (up), %rax
+ jnc L(evn)
+
+ mov %rax, %r11
+ shl R8(%rcx), %r11
+ neg R8(%rcx)
+ shr R8(%rcx), %rax
+ test n, n
+ jnz L(gt1)
+ mov %r11, (rp)
+ FUNC_EXIT()
+ ret
+
+L(gt1): mov -8(up), %r8
+ mov %r8, %r10
+ shr R8(%rcx), %r8
+ jmp L(lo1)
+
+L(evn): mov %rax, %r10
+ neg R8(%rcx)
+ shr R8(%rcx), %rax
+ mov -8(up), %r9
+ mov %r9, %r11
+ shr R8(%rcx), %r9
+ neg R8(%rcx)
+ dec n
+ lea 8(rp), rp
+ lea -8(up), up
+ jz L(end)
+
+ ALIGN(8)
+L(top): shl R8(%rcx), %r10
+ or %r10, %r9
+ shl R8(%rcx), %r11
+ neg R8(%rcx)
+ mov -8(up), %r8
+ mov %r8, %r10
+ mov %r9, -8(rp)
+ shr R8(%rcx), %r8
+ lea -16(rp), rp
+L(lo1): mov -16(up), %r9
+ or %r11, %r8
+ mov %r9, %r11
+ shr R8(%rcx), %r9
+ lea -16(up), up
+ neg R8(%rcx)
+ mov %r8, (rp)
+ dec n
+ jg L(top)
+
+L(end): shl R8(%rcx), %r10
+ or %r10, %r9
+ shl R8(%rcx), %r11
+ mov %r9, -8(rp)
+ mov %r11, -16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/atom/lshiftc.asm b/gmp/mpn/x86_64/atom/lshiftc.asm
new file mode 100644
index 0000000000..7385f8fd44
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/lshiftc.asm
@@ -0,0 +1,127 @@
+dnl AMD64 mpn_lshiftc -- mpn left shift with complement, optimised for Atom.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel atom 5
+C VIA nano ?
+
+C TODO
+C * Consider using 4-way unrolling. We reach 4.5 c/l, but the code is 2.5
+C times larger.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_lshiftc)
+ FUNC_ENTRY(4)
+ lea -8(up,n,8), up
+ lea -8(rp,n,8), rp
+ shr R32(n)
+ mov (up), %rax
+ jnc L(evn)
+
+ mov %rax, %r11
+ shl R8(%rcx), %r11
+ neg R8(%rcx)
+ shr R8(%rcx), %rax
+ test n, n
+ jnz L(gt1)
+ not %r11
+ mov %r11, (rp)
+ FUNC_EXIT()
+ ret
+
+L(gt1): mov -8(up), %r8
+ mov %r8, %r10
+ shr R8(%rcx), %r8
+ jmp L(lo1)
+
+L(evn): mov %rax, %r10
+ neg R8(%rcx)
+ shr R8(%rcx), %rax
+ mov -8(up), %r9
+ mov %r9, %r11
+ shr R8(%rcx), %r9
+ neg R8(%rcx)
+ lea 8(rp), rp
+ lea -8(up), up
+ jmp L(lo0)
+
+C ALIGN(16)
+L(top): shl R8(%rcx), %r10
+ or %r10, %r9
+ shl R8(%rcx), %r11
+ not %r9
+ neg R8(%rcx)
+ mov -8(up), %r8
+ lea -16(rp), rp
+ mov %r8, %r10
+ shr R8(%rcx), %r8
+ mov %r9, 8(rp)
+L(lo1): or %r11, %r8
+ mov -16(up), %r9
+ mov %r9, %r11
+ shr R8(%rcx), %r9
+ lea -16(up), up
+ neg R8(%rcx)
+ not %r8
+ mov %r8, (rp)
+L(lo0): dec n
+ jg L(top)
+
+L(end): shl R8(%rcx), %r10
+ or %r10, %r9
+ not %r9
+ shl R8(%rcx), %r11
+ not %r11
+ mov %r9, -8(rp)
+ mov %r11, -16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/atom/mul_1.asm b/gmp/mpn/x86_64/atom/mul_1.asm
new file mode 100644
index 0000000000..d76a3d3b8c
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/mul_1.asm
@@ -0,0 +1,143 @@
+dnl AMD64 mpn_mul_1 optimised for Intel Atom.
+
+dnl Copyright 2003-2005, 2007, 2008, 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C AMD K8,K9
+C AMD K10
+C AMD bd1
+C AMD bd2
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel PNR
+C Intel NHM
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom 17.3 this
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0', `%rcx') C r9
+
+define(`n', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_1)
+ FUNC_ENTRY(4)
+ xor %r8, %r8
+L(com): mov (up), %rax
+ lea -16(up,n_param,8), up
+ lea -8(rp,n_param,8), rp
+ test $1, R8(n_param)
+ jnz L(bx1)
+
+L(bx0): mov %r8, %r9
+ test $2, R8(n_param)
+ jnz L(b10)
+
+L(b00): mov $2, R32(n)
+ sub n_param, n
+ jmp L(lo0)
+
+L(bx1): test $2, R8(n_param)
+ jnz L(b11)
+
+L(b01): mov $3, R32(n)
+ sub n_param, n
+ mul v0
+ cmp $2, n
+ jnz L(lo1)
+ jmp L(cj1)
+
+L(b11): mov $1, R32(n)
+ sub n_param, n
+ jmp L(lo3)
+
+L(b10): xor R32(n), R32(n)
+ sub n_param, n
+ jmp L(lo2)
+
+L(top): mul v0
+ mov %r9, -24(rp,n,8)
+L(lo1): xor %r9d, %r9d
+ add %rax, %r8
+ mov (up,n,8), %rax
+ adc %rdx, %r9
+ mov %r8, -16(rp,n,8)
+L(lo0): xor %r8d, %r8d
+ mul v0
+ add %rax, %r9
+ mov 8(up,n,8), %rax
+ adc %rdx, %r8
+ mov %r9, -8(rp,n,8)
+L(lo3): xor %r9d, %r9d
+ mul v0
+ add %rax, %r8
+ mov 16(up,n,8), %rax
+ adc %rdx, %r9
+ mov %r8, (rp,n,8)
+L(lo2): xor %r8d, %r8d
+ mul v0
+ add %rax, %r9
+ mov 24(up,n,8), %rax
+ adc %rdx, %r8
+ add $4, n
+ js L(top)
+
+L(end): mul v0
+ mov %r9, -8(rp)
+L(cj1): add %rax, %r8
+ mov $0, R32(%rax)
+ adc %rdx, %rax
+ mov %r8, (rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+
+PROLOGUE(mpn_mul_1c)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ jmp L(com)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/atom/mul_2.asm b/gmp/mpn/x86_64/atom/mul_2.asm
new file mode 100644
index 0000000000..f3fc3afdd1
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/mul_2.asm
@@ -0,0 +1,186 @@
+dnl AMD64 mpn_mul_2 optimised for Intel Atom.
+
+dnl Copyright 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C AMD K8,K9
+C AMD K10
+C AMD bd1
+C AMD bd2
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel PNR
+C Intel NHM
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom 17.75 this
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`vp', `%rcx') C r9
+
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+define(`n', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_2)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov (up), %rax
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ mov n_param, n
+ mul v0
+
+ test $1, R8(n)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n)
+ jnz L(b10)
+
+L(b00): mov %rax, w0
+ mov (up), %rax
+ mov %rdx, w1
+ xor R32(w2), R32(w2)
+ lea -8(rp), rp
+ jmp L(lo0)
+
+L(b10): mov %rax, w2
+ mov (up), %rax
+ mov %rdx, w3
+ xor R32(w0), R32(w0)
+ lea -16(up), up
+ lea -24(rp), rp
+ jmp L(lo2)
+
+L(bx1): test $2, R8(n)
+ jnz L(b11)
+
+L(b01): mov %rax, w3
+ mov %rdx, w0
+ mov (up), %rax
+ xor R32(w1), R32(w1)
+ lea 8(up), up
+ dec n
+ jmp L(lo1)
+
+L(b11): mov %rax, w1
+ mov (up), %rax
+ mov %rdx, w2
+ xor R32(w3), R32(w3)
+ lea -8(up), up
+ lea -16(rp), rp
+ jmp L(lo3)
+
+ ALIGN(16)
+L(top):
+L(lo1): mul v1
+ add %rax, w0
+ mov (up), %rax
+ mov $0, R32(w2)
+ mov w3, (rp)
+ adc %rdx, w1
+ mul v0
+ add %rax, w0
+ mov (up), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+L(lo0): mul v1
+ add %rax, w1
+ mov 8(up), %rax
+ mov w0, 8(rp)
+ adc %rdx, w2
+ mul v0
+ add %rax, w1
+ mov 8(up), %rax
+ adc %rdx, w2
+ mov $0, R32(w3)
+ adc $0, R32(w3)
+L(lo3): mul v1
+ add %rax, w2
+ mov 16(up), %rax
+ mov w1, 16(rp)
+ mov $0, R32(w0)
+ adc %rdx, w3
+ mul v0
+ add %rax, w2
+ mov 16(up), %rax
+ adc %rdx, w3
+L(lo2): mov $0, R32(w1)
+ mov w2, 24(rp)
+ adc $0, R32(w0)
+ mul v1
+ add %rax, w3
+ mov 24(up), %rax
+ lea 32(up), up
+ adc %rdx, w0
+ mul v0
+ lea 32(rp), rp
+ add %rax, w3
+ adc %rdx, w0
+ mov -8(up), %rax
+ adc $0, R32(w1)
+ sub $4, n
+ ja L(top)
+
+L(end): mul v1
+ mov w3, (rp)
+ add %rax, w0
+ adc %rdx, w1
+ mov w0, 8(rp)
+ mov w1, %rax
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/atom/popcount.asm b/gmp/mpn/x86_64/atom/popcount.asm
new file mode 100644
index 0000000000..fb14dd3d31
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/popcount.asm
@@ -0,0 +1,35 @@
+dnl x86-64 mpn_popcount.
+
+dnl Copyright 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_popcount)
+include_mpn(`x86/pentium4/sse2/popcount.asm')
diff --git a/gmp/mpn/x86_64/atom/redc_1.asm b/gmp/mpn/x86_64/atom/redc_1.asm
new file mode 100644
index 0000000000..d93c19fdc0
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/redc_1.asm
@@ -0,0 +1,574 @@
+dnl X86-64 mpn_redc_1 optimised for Intel Atom.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C AMD bull ?
+C AMD pile ?
+C AMD steam ?
+C AMD bobcat 5.0
+C AMD jaguar ?
+C Intel P4 ?
+C Intel core ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel IBR ?
+C Intel HWL ?
+C Intel BWL ?
+C Intel atom ?
+C VIA nano ?
+
+C TODO
+C * Micro-optimise, none performed thus far.
+C * Consider inlining mpn_add_n.
+C * Single basecases out before the pushes.
+C * Make lead-in code for the inner loops be more similar.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`mp_param', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`u0inv', `%r8') C stack
+
+define(`i', `%r14')
+define(`j', `%r15')
+define(`mp', `%r12')
+define(`q0', `%r13')
+define(`w0', `%rbp')
+define(`w1', `%r9')
+define(`w2', `%r10')
+define(`w3', `%r11')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+define(`ALIGNx', `ALIGN(16)')
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_redc_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov (up), q0
+ mov n, j C outer loop induction var
+ lea (mp_param,n,8), mp
+ lea (up,n,8), up
+ neg n
+ imul u0inv, q0 C first iteration q0
+
+ test $1, R8(n)
+ jz L(bx0)
+
+L(bx1): test $2, R8(n)
+ jz L(b3)
+
+L(b1): cmp $-1, R32(n)
+ jz L(n1)
+
+L(otp1):lea 1(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov %rax, %rbp
+ mov 8(mp,n,8), %rax
+ mov %rdx, %r9
+ mul q0
+ mov %rax, %rbx
+ mov 16(mp,n,8), %rax
+ mov %rdx, %r10
+ mul q0
+ add (up,n,8), %rbp
+ mov %rax, %rbp
+ adc %r9, %rbx
+ mov 24(mp,n,8), %rax
+ adc $0, %r10
+ mov %rdx, %r9
+ mul q0
+ add 8(up,n,8), %rbx
+ mov %rbx, 8(up,n,8)
+ mov %rax, %r11
+ adc %r10, %rbp
+ mov 32(mp,n,8), %rax
+ adc $0, %r9
+ imul u0inv, %rbx C next q limb
+ jmp L(e1)
+
+ ALIGNx
+L(tp1): mul q0
+ add %rbp, -24(up,i,8)
+ mov %rax, %rbp
+ mov (mp,i,8), %rax
+ adc %r9, %r11
+ mov %rdx, %r9
+ adc $0, %r10
+ mul q0
+ add %r11, -16(up,i,8)
+ mov %rax, %r11
+ mov 8(mp,i,8), %rax
+ adc %r10, %rbp
+ mov %rdx, %r10
+ adc $0, %r9
+ mul q0
+ add %rbp, -8(up,i,8)
+ mov %rax, %rbp
+ adc %r9, %r11
+ mov 16(mp,i,8), %rax
+ adc $0, %r10
+ mov %rdx, %r9
+ mul q0
+ add %r11, (up,i,8)
+ mov %rax, %r11
+ adc %r10, %rbp
+ mov 24(mp,i,8), %rax
+ adc $0, %r9
+L(e1): add $4, i
+ mov %rdx, %r10
+ js L(tp1)
+
+L(ed1): mul q0
+ add %rbp, I(-24(up),-24(up,i,8))
+ adc %r9, %r11
+ adc $0, %r10
+ add %r11, I(-16(up),-16(up,i,8))
+ adc %r10, %rax
+ adc $0, %rdx
+ add %rax, I(-8(up),-8(up,i,8))
+ adc $0, %rdx
+ mov %rdx, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp1)
+ jmp L(cj)
+
+L(b3): cmp $-3, R32(n)
+ jz L(n3)
+
+L(otp3):lea 3(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov %rax, %rbp
+ mov 8(mp,n,8), %rax
+ mov %rdx, %r9
+ mul q0
+ mov %rax, %rbx
+ mov 16(mp,n,8), %rax
+ mov %rdx, %r10
+ mul q0
+ add (up,n,8), %rbp
+ mov %rax, %rbp
+ mov 24(mp,n,8), %rax
+ adc %r9, %rbx
+ mov %rdx, %r9
+ adc $0, %r10
+ mul q0
+ add 8(up,n,8), %rbx
+ mov %rbx, 8(up,n,8)
+ mov %rax, %r11
+ mov 32(mp,n,8), %rax
+ adc %r10, %rbp
+ mov %rdx, %r10
+ adc $0, %r9
+ imul u0inv, %rbx C next q limb
+ jmp L(e3)
+
+ ALIGNx
+L(tp3): mul q0
+ add %rbp, -24(up,i,8)
+ mov %rax, %rbp
+ mov (mp,i,8), %rax
+ adc %r9, %r11
+ mov %rdx, %r9
+ adc $0, %r10
+ mul q0
+ add %r11, -16(up,i,8)
+ mov %rax, %r11
+ mov 8(mp,i,8), %rax
+ adc %r10, %rbp
+ mov %rdx, %r10
+ adc $0, %r9
+L(e3): mul q0
+ add %rbp, -8(up,i,8)
+ mov %rax, %rbp
+ adc %r9, %r11
+ mov 16(mp,i,8), %rax
+ adc $0, %r10
+ mov %rdx, %r9
+ mul q0
+ add %r11, (up,i,8)
+ mov %rax, %r11
+ adc %r10, %rbp
+ mov 24(mp,i,8), %rax
+ adc $0, %r9
+ add $4, i
+ mov %rdx, %r10
+ js L(tp3)
+
+L(ed3): mul q0
+ add %rbp, I(-24(up),-24(up,i,8))
+ adc %r9, %r11
+ adc $0, %r10
+ add %r11, I(-16(up),-16(up,i,8))
+ adc %r10, %rax
+ adc $0, %rdx
+ add %rax, I(-8(up),-8(up,i,8))
+ adc $0, %rdx
+ mov %rdx, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp3)
+C jmp L(cj)
+
+L(cj):
+IFSTD(` lea (up,n,8), up C param 2: up
+ lea (up,n,8), %rdx C param 3: up - n
+ neg R32(n) ') C param 4: n
+
+IFDOS(` lea (up,n,8), %rdx C param 2: up
+ lea (%rdx,n,8), %r8 C param 3: up - n
+ neg R32(n)
+ mov n, %r9 C param 4: n
+ mov rp, %rcx ') C param 1: rp
+
+ CALL( mpn_add_n)
+
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(bx0): test $2, R8(n)
+ jnz L(b2)
+
+L(b0): cmp $-4, R32(n)
+ jz L(n4)
+
+L(otp0):lea 4(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov %rax, %r11
+ mov 8(mp,n,8), %rax
+ mov %rdx, %r10
+ mul q0
+ mov %rax, %rbx
+ mov 16(mp,n,8), %rax
+ mov %rdx, %r9
+ mul q0
+ add (up,n,8), %r11
+ mov %rax, %r11
+ adc %r10, %rbx
+ mov 24(mp,n,8), %rax
+ adc $0, %r9
+ mov %rdx, %r10
+ mul q0
+ add 8(up,n,8), %rbx
+ mov %rbx, 8(up,n,8)
+ mov %rax, %rbp
+ mov 32(mp,n,8), %rax
+ adc %r9, %r11
+ mov %rdx, %r9
+ adc $0, %r10
+ imul u0inv, %rbx C next q limb
+ jmp L(e0)
+
+ ALIGNx
+L(tp0): mul q0
+ add %rbp, -24(up,i,8)
+ mov %rax, %rbp
+ mov (mp,i,8), %rax
+ adc %r9, %r11
+ mov %rdx, %r9
+ adc $0, %r10
+L(e0): mul q0
+ add %r11, -16(up,i,8)
+ mov %rax, %r11
+ mov 8(mp,i,8), %rax
+ adc %r10, %rbp
+ mov %rdx, %r10
+ adc $0, %r9
+ mul q0
+ add %rbp, -8(up,i,8)
+ mov %rax, %rbp
+ adc %r9, %r11
+ mov 16(mp,i,8), %rax
+ adc $0, %r10
+ mov %rdx, %r9
+ mul q0
+ add %r11, (up,i,8)
+ mov %rax, %r11
+ adc %r10, %rbp
+ mov 24(mp,i,8), %rax
+ adc $0, %r9
+ add $4, i
+ mov %rdx, %r10
+ js L(tp0)
+
+L(ed0): mul q0
+ add %rbp, I(-24(up),-24(up,i,8))
+ adc %r9, %r11
+ adc $0, %r10
+ add %r11, I(-16(up),-16(up,i,8))
+ adc %r10, %rax
+ adc $0, %rdx
+ add %rax, I(-8(up),-8(up,i,8))
+ adc $0, %rdx
+ mov %rdx, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp0)
+ jmp L(cj)
+
+L(b2): cmp $-2, R32(n)
+ jz L(n2)
+
+L(otp2):lea 2(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov %rax, %r11
+ mov 8(mp,n,8), %rax
+ mov %rdx, %r10
+ mul q0
+ mov %rax, %rbx
+ mov 16(mp,n,8), %rax
+ mov %rdx, %r9
+ mul q0
+ add (up,n,8), %r11
+ mov %rax, %r11
+ adc %r10, %rbx
+ mov 24(mp,n,8), %rax
+ adc $0, %r9
+ mov %rdx, %r10
+ mul q0
+ add 8(up,n,8), %rbx
+ mov %rbx, 8(up,n,8)
+ mov %rax, %rbp
+ mov 32(mp,n,8), %rax
+ adc %r9, %r11
+ mov %rdx, %r9
+ adc $0, %r10
+ imul u0inv, %rbx C next q limb
+ jmp L(e2)
+
+ ALIGNx
+L(tp2): mul q0
+ add %rbp, -24(up,i,8)
+ mov %rax, %rbp
+ mov (mp,i,8), %rax
+ adc %r9, %r11
+ mov %rdx, %r9
+ adc $0, %r10
+ mul q0
+ add %r11, -16(up,i,8)
+ mov %rax, %r11
+ mov 8(mp,i,8), %rax
+ adc %r10, %rbp
+ mov %rdx, %r10
+ adc $0, %r9
+ mul q0
+ add %rbp, -8(up,i,8)
+ mov %rax, %rbp
+ adc %r9, %r11
+ mov 16(mp,i,8), %rax
+ adc $0, %r10
+ mov %rdx, %r9
+L(e2): mul q0
+ add %r11, (up,i,8)
+ mov %rax, %r11
+ adc %r10, %rbp
+ mov 24(mp,i,8), %rax
+ adc $0, %r9
+ add $4, i
+ mov %rdx, %r10
+ js L(tp2)
+
+L(ed2): mul q0
+ add %rbp, I(-24(up),-24(up,i,8))
+ adc %r9, %r11
+ adc $0, %r10
+ add %r11, I(-16(up),-16(up,i,8))
+ adc %r10, %rax
+ adc $0, %rdx
+ add %rax, I(-8(up),-8(up,i,8))
+ adc $0, %rdx
+ mov %rdx, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp2)
+ jmp L(cj)
+
+L(n1): mov (mp_param), %rax
+ mul q0
+ add -8(up), %rax
+ adc (up), %rdx
+ mov %rdx, (rp)
+ mov $0, R32(%rax)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+L(n2): mov (mp_param), %rax
+ mov -16(up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ mov -8(up), %r10
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, q0
+ imul u0inv, q0 C next q0
+ mov -16(mp), %rax
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ mov (up), %r14
+ mul q0
+ add %rax, %r14
+ adc $0, %rdx
+ add %r9, %r14
+ adc $0, %rdx
+ xor R32(%rax), R32(%rax)
+ add %r11, %r14
+ adc 8(up), %rdx
+ mov %r14, (rp)
+ mov %rdx, 8(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+ ALIGNx
+L(n3): mov -24(mp), %rax
+ mov -24(up), %r10
+ mul q0
+ add %rax, %r10
+ mov -16(mp), %rax
+ mov %rdx, %r11
+ adc $0, %r11
+ mov -16(up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ add %r11, %rbp
+ mov -8(up), %r10
+ adc $0, %r9
+ mul q0
+ mov %rbp, q0
+ imul u0inv, q0 C next q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ mov %rbp, -16(up)
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, -8(up)
+ mov %r11, -24(up) C up[0]
+ lea 8(up), up C up++
+ dec j
+ jnz L(n3)
+
+ mov -48(up), %rdx
+ mov -40(up), %rbx
+ xor R32(%rax), R32(%rax)
+ add %rbp, %rdx
+ adc %r10, %rbx
+ adc -8(up), %r11
+ mov %rdx, (rp)
+ mov %rbx, 8(rp)
+ mov %r11, 16(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+L(n4): mov -32(mp), %rax
+ mul q0
+ mov %rax, %r11
+ mov -24(mp), %rax
+ mov %rdx, %r10
+ mul q0
+ mov %rax, %rbx
+ mov -16(mp), %rax
+ mov %rdx, %r9
+ mul q0
+ add -32(up), %r11
+ mov %rax, %r11
+ adc %r10, %rbx
+ mov -8(mp), %rax
+ adc $0, %r9
+ mov %rdx, %r10
+ mul q0
+ add -24(up), %rbx
+ mov %rbx, -24(up)
+ adc %r9, %r11
+ adc $0, %r10
+ imul u0inv, %rbx C next q limb
+ add %r11, -16(up)
+ adc %r10, %rax
+ adc $0, %rdx
+ add %rax, -8(up)
+ adc $0, %rdx
+ mov %rdx, -32(up) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ dec j
+ lea 8(up), up C up++
+ jnz L(n4)
+ jmp L(cj)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/atom/rsh1aors_n.asm b/gmp/mpn/x86_64/atom/rsh1aors_n.asm
new file mode 100644
index 0000000000..6f5f6384a7
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/rsh1aors_n.asm
@@ -0,0 +1,287 @@
+dnl x86-64 mpn_rsh1add_n/mpn_rsh1sub_n.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO
+C * Schedule loop less. It is now almost surely overscheduled, resulting in
+C large feed-in and wind-down code.
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 ?
+C Intel NMH ?
+C Intel SBR ?
+C Intel atom 5.25
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`vp',`%rdx')
+define(`n',`%rcx')
+
+ifdef(`OPERATION_rsh1add_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func_n, mpn_rsh1add_n)
+ define(func_nc, mpn_rsh1add_nc)')
+ifdef(`OPERATION_rsh1sub_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func_n, mpn_rsh1sub_n)
+ define(func_nc, mpn_rsh1sub_nc)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_rsh1add_n mpn_rsh1sub_n)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func_n)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov (up), %r15
+ ADDSUB (vp), %r15
+ sbb R32(%rbx), R32(%rbx)
+ xor R32(%rax), R32(%rax)
+ shr %r15
+ adc R32(%rax), R32(%rax) C return value
+
+ mov R32(n), R32(%rbp)
+ and $3, R32(%rbp)
+ jz L(b0)
+ cmp $2, R32(%rbp)
+ jae L(b23)
+
+L(b1): dec n
+ jnz L(gt1)
+ shl $63, %rbx
+ add %rbx, %r15
+ mov %r15, (rp)
+ jmp L(cj1)
+L(gt1): lea 24(up), up
+ lea 24(vp), vp
+ mov -16(up), %r9
+ add R32(%rbx), R32(%rbx)
+ mov -8(up), %r10
+ lea 24(rp), rp
+ mov (up), %r11
+ ADCSBB -16(vp), %r9
+ ADCSBB -8(vp), %r10
+ mov %r15, %r12
+ ADCSBB (vp), %r11
+ mov %r9, %r13
+ sbb R32(%rbx), R32(%rbx)
+ mov %r11, %r15
+ mov %r10, %r14
+ shl $63, %r11
+ shl $63, %r10
+ shl $63, %r9
+ or %r9, %r12
+ shr %r13
+ mov 8(up), %r8
+ shr %r14
+ or %r10, %r13
+ shr %r15
+ or %r11, %r14
+ sub $4, n
+ jz L(cj5)
+L(gt5): mov 16(up), %r9
+ add R32(%rbx), R32(%rbx)
+ mov 24(up), %r10
+ ADCSBB 8(vp), %r8
+ mov %r15, %rbp
+ mov 32(up), %r11
+ jmp L(lo1)
+
+L(b23): jnz L(b3)
+ mov 8(up), %r8
+ sub $2, n
+ jnz L(gt2)
+ add R32(%rbx), R32(%rbx)
+ ADCSBB 8(vp), %r8
+ mov %r8, %r12
+ jmp L(cj2)
+L(gt2): mov 16(up), %r9
+ add R32(%rbx), R32(%rbx)
+ mov 24(up), %r10
+ ADCSBB 8(vp), %r8
+ mov %r15, %rbp
+ mov 32(up), %r11
+ ADCSBB 16(vp), %r9
+ lea 32(up), up
+ ADCSBB 24(vp), %r10
+ mov %r9, %r13
+ ADCSBB 32(vp), %r11
+ mov %r8, %r12
+ jmp L(lo2)
+
+L(b3): lea 40(up), up
+ lea 8(vp), vp
+ mov %r15, %r14
+ add R32(%rbx), R32(%rbx)
+ mov -32(up), %r11
+ ADCSBB 0(vp), %r11
+ lea 8(rp), rp
+ sbb R32(%rbx), R32(%rbx)
+ mov %r11, %r15
+ shl $63, %r11
+ mov -24(up), %r8
+ shr %r15
+ or %r11, %r14
+ sub $3, n
+ jnz L(gt3)
+ add R32(%rbx), R32(%rbx)
+ ADCSBB 8(vp), %r8
+ jmp L(cj3)
+L(gt3): mov -16(up), %r9
+ add R32(%rbx), R32(%rbx)
+ mov -8(up), %r10
+ ADCSBB 8(vp), %r8
+ mov %r15, %rbp
+ mov (up), %r11
+ ADCSBB 16(vp), %r9
+ ADCSBB 24(vp), %r10
+ mov %r8, %r12
+ jmp L(lo3)
+
+L(b0): lea 48(up), up
+ lea 16(vp), vp
+ add R32(%rbx), R32(%rbx)
+ mov -40(up), %r10
+ lea 16(rp), rp
+ mov -32(up), %r11
+ ADCSBB -8(vp), %r10
+ mov %r15, %r13
+ ADCSBB (vp), %r11
+ sbb R32(%rbx), R32(%rbx)
+ mov %r11, %r15
+ mov %r10, %r14
+ shl $63, %r11
+ shl $63, %r10
+ mov -24(up), %r8
+ shr %r14
+ or %r10, %r13
+ shr %r15
+ or %r11, %r14
+ sub $4, n
+ jnz L(gt4)
+ add R32(%rbx), R32(%rbx)
+ ADCSBB 8(vp), %r8
+ jmp L(cj4)
+L(gt4): mov -16(up), %r9
+ add R32(%rbx), R32(%rbx)
+ mov -8(up), %r10
+ ADCSBB 8(vp), %r8
+ mov %r15, %rbp
+ mov (up), %r11
+ ADCSBB 16(vp), %r9
+ jmp L(lo0)
+
+ ALIGN(8)
+L(top): mov 16(up), %r9
+ shr %r14
+ or %r10, %r13
+ shr %r15
+ or %r11, %r14
+ add R32(%rbx), R32(%rbx)
+ mov 24(up), %r10
+ mov %rbp, (rp)
+ ADCSBB 8(vp), %r8
+ mov %r15, %rbp
+ lea 32(rp), rp
+ mov 32(up), %r11
+L(lo1): ADCSBB 16(vp), %r9
+ lea 32(up), up
+ mov %r12, -24(rp)
+L(lo0): ADCSBB 24(vp), %r10
+ mov %r8, %r12
+ mov %r13, -16(rp)
+L(lo3): ADCSBB 32(vp), %r11
+ mov %r9, %r13
+ mov %r14, -8(rp)
+L(lo2): sbb R32(%rbx), R32(%rbx)
+ shl $63, %r8
+ mov %r11, %r15
+ shr %r12
+ mov %r10, %r14
+ shl $63, %r9
+ lea 32(vp), vp
+ shl $63, %r10
+ or %r8, %rbp
+ shl $63, %r11
+ or %r9, %r12
+ shr %r13
+ mov 8(up), %r8
+ sub $4, n
+ jg L(top)
+
+L(end): shr %r14
+ or %r10, %r13
+ shr %r15
+ or %r11, %r14
+ mov %rbp, (rp)
+ lea 32(rp), rp
+L(cj5): add R32(%rbx), R32(%rbx)
+ ADCSBB 8(vp), %r8
+ mov %r12, -24(rp)
+L(cj4): mov %r13, -16(rp)
+L(cj3): mov %r8, %r12
+ mov %r14, -8(rp)
+L(cj2): sbb R32(%rbx), R32(%rbx)
+ shl $63, %r8
+ shr %r12
+ or %r8, %r15
+ shl $63, %rbx
+ add %rbx, %r12
+ mov %r15, (rp)
+ mov %r12, 8(rp)
+L(cj1): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/atom/rshift.asm b/gmp/mpn/x86_64/atom/rshift.asm
new file mode 100644
index 0000000000..29c027de49
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/rshift.asm
@@ -0,0 +1,121 @@
+dnl AMD64 mpn_rshift -- mpn right shift, optimised for Atom.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel atom 4.5
+C VIA nano ?
+
+C TODO
+C * Consider using 4-way unrolling. We reach 4 c/l, but the code is 2.5 times
+C larger.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_rshift)
+ FUNC_ENTRY(4)
+ shr R32(n)
+ mov (up), %rax
+ jnc L(evn)
+
+ mov %rax, %r11
+ shr R8(cnt), %r11
+ neg R8(cnt)
+ shl R8(cnt), %rax
+ test n, n
+ jnz L(gt1)
+ mov %r11, (rp)
+ FUNC_EXIT()
+ ret
+
+L(gt1): mov 8(up), %r8
+ mov %r8, %r10
+ shl R8(cnt), %r8
+ jmp L(lo1)
+
+L(evn): mov %rax, %r10
+ neg R8(cnt)
+ shl R8(cnt), %rax
+ mov 8(up), %r9
+ mov %r9, %r11
+ shl R8(cnt), %r9
+ neg R8(cnt)
+ dec n
+ lea -8(rp), rp
+ lea 8(up), up
+ jz L(end)
+
+ ALIGN(8)
+L(top): shr R8(cnt), %r10
+ or %r10, %r9
+ shr R8(cnt), %r11
+ neg R8(cnt)
+ mov 8(up), %r8
+ mov %r8, %r10
+ mov %r9, 8(rp)
+ shl R8(cnt), %r8
+ lea 16(rp), rp
+L(lo1): mov 16(up), %r9
+ or %r11, %r8
+ mov %r9, %r11
+ shl R8(cnt), %r9
+ lea 16(up), up
+ neg R8(cnt)
+ mov %r8, (rp)
+ dec n
+ jg L(top)
+
+L(end): shr R8(cnt), %r10
+ or %r10, %r9
+ shr R8(cnt), %r11
+ mov %r9, 8(rp)
+ mov %r11, 16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/atom/sublsh1_n.asm b/gmp/mpn/x86_64/atom/sublsh1_n.asm
new file mode 100644
index 0000000000..1306acde2b
--- /dev/null
+++ b/gmp/mpn/x86_64/atom/sublsh1_n.asm
@@ -0,0 +1,242 @@
+dnl AMD64 mpn_sublsh1_n optimised for Intel Atom.
+dnl Used also for AMD bd1.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C TODO
+C * This code is slightly large at 501 bytes.
+C * aorrlsh1_n.asm and this file use the same basic pattern.
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C AMD bd1 2.3
+C AMD bobcat ?
+C Intel P4 ?
+C Intel core2 ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel atom 5 (4.875 is probably possible)
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cy', `%r8')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sublsh1_n)
+ FUNC_ENTRY(4)
+ push %rbp
+ push %r15
+ xor R32(%rbp), R32(%rbp)
+L(ent): mov R32(n), R32(%rax)
+ and $3, R32(%rax)
+ jz L(b0)
+ cmp $2, R32(%rax)
+ jz L(b2)
+ jg L(b3)
+
+L(b1): mov (vp), %r8
+ add %r8, %r8
+ lea 8(vp), vp
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+ mov (up), %r15
+ sbb %r8, %r15
+ mov %r15, (rp)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ lea 8(up), up
+ lea 8(rp), rp
+ jmp L(b0)
+
+L(b2): mov (vp), %r8
+ add %r8, %r8
+ mov 8(vp), %r9
+ adc %r9, %r9
+ lea 16(vp), vp
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+ mov (up), %r15
+ sbb %r8, %r15
+ mov %r15, (rp)
+ mov 8(up), %r15
+ sbb %r9, %r15
+ mov %r15, 8(rp)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ lea 16(up), up
+ lea 16(rp), rp
+ jmp L(b0)
+
+L(b3): mov (vp), %r8
+ add %r8, %r8
+ mov 8(vp), %r9
+ adc %r9, %r9
+ mov 16(vp), %r10
+ adc %r10, %r10
+ lea 24(vp), vp
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+ mov (up), %r15
+ sbb %r8, %r15
+ mov %r15, (rp)
+ mov 8(up), %r15
+ sbb %r9, %r15
+ mov %r15, 8(rp)
+ mov 16(up), %r15
+ sbb %r10, %r15
+ mov %r15, 16(rp)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ lea 24(up), up
+ lea 24(rp), rp
+
+L(b0): test $4, R8(n)
+ jz L(skp)
+ add R32(%rax), R32(%rax) C restore scy
+ mov (vp), %r8
+ adc %r8, %r8
+ mov 8(vp), %r9
+ adc %r9, %r9
+ mov 16(vp), %r10
+ adc %r10, %r10
+ mov 24(vp), %r11
+ adc %r11, %r11
+ lea 32(vp), vp
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+ mov (up), %r15
+ sbb %r8, %r15
+ mov %r15, (rp)
+ mov 8(up), %r15
+ sbb %r9, %r15
+ mov %r15, 8(rp)
+ mov 16(up), %r15
+ sbb %r10, %r15
+ mov %r15, 16(rp)
+ mov 24(up), %r15
+ sbb %r11, %r15
+ mov %r15, 24(rp)
+ lea 32(up), up
+ lea 32(rp), rp
+ sbb R32(%rbp), R32(%rbp) C save acy
+
+L(skp): cmp $8, n
+ jl L(rtn)
+
+ push %r12
+ push %r13
+ push %r14
+ push %rbx
+ lea -64(rp), rp
+ jmp L(x)
+
+ ALIGN(16)
+L(top): mov (vp), %r8
+ add R32(%rax), R32(%rax)
+ lea 64(vp), vp
+ adc %r8, %r8
+ mov -56(vp), %r9
+ adc %r9, %r9
+ mov -48(vp), %r10
+ adc %r10, %r10
+ mov -40(vp), %r11
+ adc %r11, %r11
+ mov -32(vp), %r12
+ adc %r12, %r12
+ mov -24(vp), %r13
+ adc %r13, %r13
+ mov -16(vp), %r14
+ adc %r14, %r14
+ mov -8(vp), %r15
+ adc %r15, %r15
+ sbb R32(%rax), R32(%rax)
+ add R32(%rbp), R32(%rbp)
+ mov (up), %rbp
+ lea 64(rp), rp
+ mov 8(up), %rbx
+ sbb %r8, %rbp
+ mov 32(up), %r8
+ mov %rbp, (rp)
+ sbb %r9, %rbx
+ mov 16(up), %rbp
+ mov %rbx, 8(rp)
+ sbb %r10, %rbp
+ mov 24(up), %rbx
+ mov %rbp, 16(rp)
+ sbb %r11, %rbx
+ mov %rbx, 24(rp)
+ sbb %r12, %r8
+ mov 40(up), %r9
+ mov %r8, 32(rp)
+ sbb %r13, %r9
+ mov 48(up), %rbp
+ mov %r9, 40(rp)
+ sbb %r14, %rbp
+ mov 56(up), %rbx
+ mov %rbp, 48(rp)
+ sbb %r15, %rbx
+ lea 64(up), up
+ mov %rbx, 56(rp)
+ sbb R32(%rbp), R32(%rbp)
+L(x): sub $8, n
+ jge L(top)
+
+L(end): pop %rbx
+ pop %r14
+ pop %r13
+ pop %r12
+L(rtn):
+ add R32(%rbp), R32(%rax)
+ neg R32(%rax)
+
+ pop %r15
+ pop %rbp
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+PROLOGUE(mpn_sublsh1_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbp
+ push %r15
+ neg %r8 C set CF
+ sbb R32(%rbp), R32(%rbp) C save acy
+ jmp L(ent)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bd1/README b/gmp/mpn/x86_64/bd1/README
new file mode 100644
index 0000000000..ccd210e0d6
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/README
@@ -0,0 +1,11 @@
+This directory contains code for AMD bulldozer including its piledriver update.
+
+We currently make limited use of SIMD instructions, both via the MPN_PATH and
+via inclusion of x86_64/fastsse files.
+
+The bd1 cores share one SIMD/FPU pipeline for two integer units. This probably
+means that an all-core GMP load (such as a HPC load) might run slower if there
+is significant SIMD dependency.
+
+We should perhaps allow a special 'bd1nosimd' pseudo cpu-name excluding any
+SIMD code.
diff --git a/gmp/mpn/x86_64/bd1/aorrlsh1_n.asm b/gmp/mpn/x86_64/bd1/aorrlsh1_n.asm
new file mode 100644
index 0000000000..c34a5fa134
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/aorrlsh1_n.asm
@@ -0,0 +1,37 @@
+dnl AMD64 mpn_addlsh1_n and mpn_rsblsh1_n
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_addlsh1_nc mpn_rsblsh1_n mpn_rsblsh1_nc)
+include_mpn(`x86_64/atom/aorrlsh1_n.asm')
diff --git a/gmp/mpn/x86_64/bd1/aorsmul_1.asm b/gmp/mpn/x86_64/bd1/aorsmul_1.asm
new file mode 100644
index 0000000000..96fec9f5ac
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/aorsmul_1.asm
@@ -0,0 +1,181 @@
+dnl AMD64 mpn_addmul_1 and mpn_submul_1 optimised for AMD Bulldozer.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9
+C AMD K10
+C AMD bd1 4.5-4.7
+C AMD bobcat
+C Intel P4
+C Intel core2
+C Intel NHM
+C Intel SBR
+C Intel atom
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * Try to make loop run closer to 4 c/l.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0', `%rcx') C r9
+
+define(`n', `%r11')
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`func', `mpn_submul_1')
+')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+IFDOS(` define(`up', ``%rsi'') ') dnl
+IFDOS(` define(`rp', ``%rcx'') ') dnl
+IFDOS(` define(`v0', ``%r9'') ') dnl
+IFDOS(` define(`r9', ``rdi'') ') dnl
+IFDOS(` define(`n', ``%r8'') ') dnl
+IFDOS(` define(`r8', ``r11'') ') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+IFDOS(``push %rsi '')
+IFDOS(``push %rdi '')
+IFDOS(``mov %rdx, %rsi '')
+
+ mov (up), %rax C read first u limb early
+ push %rbx
+IFSTD(` mov n_param, %rbx ') C move away n from rdx, mul uses it
+IFDOS(` mov n, %rbx ')
+ mul v0
+
+IFSTD(` mov %rbx, n ')
+
+ and $3, R32(%rbx)
+ lea -16(rp,n,8), rp
+ jz L(b0)
+ cmp $2, R32(%rbx)
+ jb L(b1)
+ jz L(b2)
+
+L(b3): mov $0, R32(%r8)
+ mov %rax, %rbx
+ mov $0, R32(%r9)
+ mov 8(up), %rax
+ mov %rdx, %r10
+ lea (up,n,8), up
+ not n
+ jmp L(L3)
+
+L(b0): mov $0, R32(%r10)
+ mov %rax, %r8
+ mov %rdx, %rbx
+ mov 8(up), %rax
+ lea (up,n,8), up
+ neg n
+ jmp L(L0)
+
+L(b1): cmp $1, n
+ jz L(n1)
+ mov %rax, %r9
+ mov 8(up), %rax
+ mov %rdx, %r8
+ mov $0, R32(%rbx)
+ lea (up,n,8), up
+ neg n
+ inc n
+ jmp L(L1)
+
+L(b2): mov $0, R32(%rbx)
+ mov %rax, %r10
+ mov %rdx, %r9
+ mov 8(up), %rax
+ mov $0, R32(%r8)
+ lea (up,n,8), up
+ neg n
+ add $2, n
+ jns L(end)
+
+ ALIGN(32)
+L(top): mul v0
+ ADDSUB %r10, (rp,n,8)
+ adc %rax, %r9
+ mov (up,n,8), %rax
+ adc %rdx, %r8
+L(L1): mul v0
+ mov $0, R32(%r10)
+ ADDSUB %r9, 8(rp,n,8)
+ adc %rax, %r8
+ adc %rdx, %rbx
+ mov 8(up,n,8), %rax
+L(L0): mul v0
+ ADDSUB %r8, 16(rp,n,8)
+ mov $0, R32(%r8)
+ adc %rax, %rbx
+ mov $0, R32(%r9)
+ mov 16(up,n,8), %rax
+ adc %rdx, %r10
+L(L3): mul v0
+ ADDSUB %rbx, 24(rp,n,8)
+ mov $0, R32(%rbx)
+ adc %rax, %r10
+ adc %rdx, %r9
+ mov 24(up,n,8), %rax
+ add $4, n
+ js L(top)
+
+L(end): mul v0
+ ADDSUB %r10, (rp)
+ adc %r9, %rax
+ adc %r8, %rdx
+L(n1): ADDSUB %rax, 8(rp)
+ adc $0, %rdx
+ mov %rdx, %rax
+
+ pop %rbx
+IFDOS(``pop %rdi '')
+IFDOS(``pop %rsi '')
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/bd1/com.asm b/gmp/mpn/x86_64/bd1/com.asm
new file mode 100644
index 0000000000..43f356117a
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/com.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_com optimised for AMD bd1.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_com)
+include_mpn(`x86_64/fastsse/com-palignr.asm')
diff --git a/gmp/mpn/x86_64/bd1/copyd.asm b/gmp/mpn/x86_64/bd1/copyd.asm
new file mode 100644
index 0000000000..675cdc3f6b
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/copyd.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_copyd optimised for AMD bd1.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_copyd)
+include_mpn(`x86_64/fastsse/copyd-palignr.asm')
diff --git a/gmp/mpn/x86_64/bd1/copyi.asm b/gmp/mpn/x86_64/bd1/copyi.asm
new file mode 100644
index 0000000000..ceef036585
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/copyi.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_copyi optimised for AMD bd1.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_copyi)
+include_mpn(`x86_64/fastsse/copyi-palignr.asm')
diff --git a/gmp/mpn/x86_64/bd1/gcd_1.asm b/gmp/mpn/x86_64/bd1/gcd_1.asm
new file mode 100644
index 0000000000..3d8e5c7ab1
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/gcd_1.asm
@@ -0,0 +1,37 @@
+dnl AMD64 mpn_gcd_1.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_gcd_1)
+include_mpn(`x86_64/core2/gcd_1.asm')
diff --git a/gmp/mpn/x86_64/bd1/gmp-mparam.h b/gmp/mpn/x86_64/bd1/gmp-mparam.h
new file mode 100644
index 0000000000..5014f9f469
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/gmp-mparam.h
@@ -0,0 +1,236 @@
+/* AMD bd1 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2010, 2012, 2014 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 3600 MHz Bulldozer Zambezi */
+/* FFT tuning limit = 40000000 */
+/* Generated by tuneup.c, 2014-03-13, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 5
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 13
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 28
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 11
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 22
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 59
+#define MUL_TOOM44_THRESHOLD 166
+#define MUL_TOOM6H_THRESHOLD 274
+#define MUL_TOOM8H_THRESHOLD 333
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 107
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 105
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 115
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 150
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 22
+#define SQR_TOOM3_THRESHOLD 85
+#define SQR_TOOM4_THRESHOLD 242
+#define SQR_TOOM6_THRESHOLD 318
+#define SQR_TOOM8_THRESHOLD 478
+
+#define MULMID_TOOM42_THRESHOLD 22
+
+#define MULMOD_BNM1_THRESHOLD 11
+#define SQRMOD_BNM1_THRESHOLD 14
+
+#define MUL_FFT_MODF_THRESHOLD 404 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 404, 5}, { 19, 6}, { 11, 5}, { 23, 6}, \
+ { 19, 7}, { 10, 6}, { 25, 7}, { 15, 6}, \
+ { 31, 7}, { 25, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 17, 7}, { 35, 8}, \
+ { 19, 7}, { 39, 8}, { 27, 9}, { 15, 8}, \
+ { 35, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 47, 9}, { 27,10}, { 15, 9}, { 39,10}, \
+ { 23, 9}, { 55,11}, { 15,10}, { 31, 9}, \
+ { 67,10}, { 39, 9}, { 83,10}, { 47, 9}, \
+ { 95,10}, { 55,11}, { 31,10}, { 79,11}, \
+ { 47,10}, { 103,12}, { 31,11}, { 63,10}, \
+ { 135,11}, { 79,10}, { 167,11}, { 95,10}, \
+ { 191,11}, { 111,12}, { 63,11}, { 127,10}, \
+ { 255,11}, { 143,10}, { 287, 9}, { 575,10}, \
+ { 303,11}, { 159,12}, { 95,11}, { 191,10}, \
+ { 383,11}, { 207,13}, { 63,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 271,10}, { 543,11}, \
+ { 287,10}, { 575,11}, { 303,12}, { 159,11}, \
+ { 319, 9}, { 1279,11}, { 367,12}, { 191,11}, \
+ { 383,10}, { 767,11}, { 415,12}, { 223,11}, \
+ { 447,10}, { 895,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,12}, { 287,11}, \
+ { 575,10}, { 1151,11}, { 607,10}, { 1215,12}, \
+ { 319,10}, { 1279,11}, { 671,12}, { 351,11}, \
+ { 703,13}, { 191,12}, { 383,11}, { 767,12}, \
+ { 415,11}, { 831,10}, { 1663,12}, { 447,11}, \
+ { 895,14}, { 127,13}, { 255,12}, { 511,11}, \
+ { 1023,12}, { 543,11}, { 1087,10}, { 2175,12}, \
+ { 575,11}, { 1151,12}, { 607,11}, { 1215,13}, \
+ { 319,11}, { 1279,12}, { 671,11}, { 1343,10}, \
+ { 2687,12}, { 703,11}, { 1407,13}, { 383,12}, \
+ { 767,11}, { 1535,12}, { 799,11}, { 1599,12}, \
+ { 831,11}, { 1663,13}, { 447,12}, { 895,11}, \
+ { 1791,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1087,11}, { 2175,13}, { 575,12}, { 1215,11}, \
+ { 2431,10}, { 4863,12}, { 1343,13}, { 703,12}, \
+ { 1407,14}, { 383,13}, { 767,12}, { 1599,13}, \
+ { 831,12}, { 1727,11}, { 3455,13}, { 895,12}, \
+ { 1791,13}, { 959,15}, { 255,14}, { 511,13}, \
+ { 1087,12}, { 2175,13}, { 1151,12}, { 2303,13}, \
+ { 1215,12}, { 2431,11}, { 4863,13}, { 1343,12}, \
+ { 2687,13}, { 1471,12}, { 2943,11}, { 5887,14}, \
+ { 767,13}, { 1599,12}, { 3199,13}, { 1727,14}, \
+ { 895,13}, { 1791,12}, { 3583,13}, { 1919,12}, \
+ { 3839,15}, { 511,14}, { 1023,13}, { 2175,14}, \
+ { 1151,13}, { 2303,12}, { 4607,13}, { 2431,12}, \
+ { 4863,14}, { 1279,13}, { 2687,14}, { 1407,13}, \
+ { 2943,12}, { 5887,15}, { 767,14}, { 1535,13}, \
+ { 3199,14}, { 1663,13}, { 3455,12}, { 6911,14}, \
+ { 1791,13}, { 3583,14}, { 1919,13}, { 3839,16}, \
+ { 511,15}, { 1023,14}, { 2175,13}, { 4351,14}, \
+ { 2303,13}, { 4607,14}, { 2431,13}, { 4863,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 217
+#define MUL_FFT_THRESHOLD 3712
+
+#define SQR_FFT_MODF_THRESHOLD 380 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 380, 5}, { 17, 6}, { 9, 5}, { 23, 6}, \
+ { 21, 7}, { 11, 6}, { 25, 7}, { 13, 6}, \
+ { 27, 7}, { 15, 6}, { 31, 7}, { 25, 8}, \
+ { 13, 7}, { 27, 8}, { 15, 7}, { 31, 8}, \
+ { 19, 7}, { 39, 8}, { 21, 9}, { 11, 8}, \
+ { 27, 9}, { 15, 8}, { 35, 9}, { 19, 8}, \
+ { 41, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 51,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 83,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 79,11}, { 47,10}, { 95,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 135,11}, { 79,10}, { 159,11}, { 95,10}, \
+ { 191,11}, { 111,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271,11}, { 143,10}, \
+ { 287, 9}, { 575,10}, { 303,11}, { 159,10}, \
+ { 319,12}, { 95,11}, { 191,10}, { 383,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 271,10}, { 543, 9}, { 1087,11}, { 303,10}, \
+ { 607,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 335,10}, { 671, 9}, { 1343,11}, { 351,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,12}, \
+ { 223,11}, { 447,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087,12}, \
+ { 287,11}, { 575,10}, { 1151,11}, { 607,12}, \
+ { 319,11}, { 639,10}, { 1279,11}, { 671,12}, \
+ { 351,13}, { 191,12}, { 383,11}, { 767,12}, \
+ { 415,11}, { 831,12}, { 447,14}, { 127,13}, \
+ { 255,12}, { 511,11}, { 1023,12}, { 543,11}, \
+ { 1087,10}, { 2175,12}, { 575,11}, { 1151,12}, \
+ { 607,13}, { 319,12}, { 639,11}, { 1279,12}, \
+ { 671,11}, { 1343,10}, { 2687,12}, { 703,11}, \
+ { 1407,13}, { 383,12}, { 767,11}, { 1599,10}, \
+ { 3199,12}, { 831,13}, { 447,12}, { 895,14}, \
+ { 255,13}, { 511,12}, { 1087,11}, { 2175,13}, \
+ { 575,12}, { 1215,11}, { 2431,10}, { 4863,13}, \
+ { 639,12}, { 1343,11}, { 2687,13}, { 703,12}, \
+ { 1407,14}, { 383,13}, { 767,12}, { 1599,11}, \
+ { 3199,13}, { 831,12}, { 1727,13}, { 895,15}, \
+ { 255,14}, { 511,13}, { 1087,12}, { 2175,13}, \
+ { 1215,12}, { 2431,11}, { 4863,14}, { 639,13}, \
+ { 1343,12}, { 2687,13}, { 1471,12}, { 2943,11}, \
+ { 5887,14}, { 767,13}, { 1599,12}, { 3199,13}, \
+ { 1727,14}, { 895,13}, { 1791,12}, { 3583,13}, \
+ { 1919,12}, { 3839,15}, { 511,14}, { 1023,13}, \
+ { 2175,14}, { 1151,13}, { 2303,12}, { 4607,13}, \
+ { 2431,12}, { 4863,14}, { 1279,13}, { 2687,14}, \
+ { 1407,13}, { 2943,12}, { 5887,15}, { 767,14}, \
+ { 1535,13}, { 3199,14}, { 1663,13}, { 3327,12}, \
+ { 6655,13}, { 3455,12}, { 6911,14}, { 1791,13}, \
+ { 3583,14}, { 1919,13}, { 3839,16}, { 511,15}, \
+ { 1023,14}, { 2175,13}, { 4351,14}, { 2303,13}, \
+ { 4607,14}, { 2431,13}, { 4863,15}, { 32768,16}, \
+ { 65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+ {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 220
+#define SQR_FFT_THRESHOLD 3264
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 39
+#define MULLO_MUL_N_THRESHOLD 7246
+
+#define DC_DIV_QR_THRESHOLD 54
+#define DC_DIVAPPR_Q_THRESHOLD 180
+#define DC_BDIV_QR_THRESHOLD 47
+#define DC_BDIV_Q_THRESHOLD 80
+
+#define INV_MULMOD_BNM1_THRESHOLD 38
+#define INV_NEWTON_THRESHOLD 226
+#define INV_APPR_THRESHOLD 188
+
+#define BINV_NEWTON_THRESHOLD 248
+#define REDC_1_TO_REDC_2_THRESHOLD 52
+#define REDC_2_TO_REDC_N_THRESHOLD 0 /* always */
+
+#define MU_DIV_QR_THRESHOLD 1334
+#define MU_DIVAPPR_Q_THRESHOLD 1360
+#define MUPI_DIV_QR_THRESHOLD 108
+#define MU_BDIV_QR_THRESHOLD 1142
+#define MU_BDIV_Q_THRESHOLD 1360
+
+#define POWM_SEC_TABLE 1,16,194,386,452,2245
+
+#define MATRIX22_STRASSEN_THRESHOLD 15
+#define HGCD_THRESHOLD 108
+#define HGCD_APPR_THRESHOLD 51
+#define HGCD_REDUCE_THRESHOLD 2681
+#define GCD_DC_THRESHOLD 474
+#define GCDEXT_DC_THRESHOLD 298
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 13
+#define GET_STR_PRECOMPUTE_THRESHOLD 21
+#define SET_STR_DC_THRESHOLD 418
+#define SET_STR_PRECOMPUTE_THRESHOLD 1289
+
+#define FAC_DSC_THRESHOLD 252
+#define FAC_ODD_THRESHOLD 23
diff --git a/gmp/mpn/x86_64/bd1/hamdist.asm b/gmp/mpn/x86_64/bd1/hamdist.asm
new file mode 100644
index 0000000000..93e1e5632b
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/hamdist.asm
@@ -0,0 +1,38 @@
+dnl AMD64 mpn_hamdist -- hamming distance.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_hamdist)
+include_mpn(`x86_64/k10/hamdist.asm')
diff --git a/gmp/mpn/x86_64/bd1/mul_1.asm b/gmp/mpn/x86_64/bd1/mul_1.asm
new file mode 100644
index 0000000000..e59667c085
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/mul_1.asm
@@ -0,0 +1,184 @@
+dnl AMD64 mpn_mul_1 optimised for AMD Bulldozer.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9
+C AMD K10
+C AMD bd1 4
+C AMD bobcat
+C Intel P4
+C Intel core2
+C Intel NHM
+C Intel SBR
+C Intel atom
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * Move loop code into feed-in blocks, to save insn for zeroing regs.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0', `%rcx') C r9
+
+define(`n', `%rbx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+IFDOS(` define(`up', ``%rsi'') ') dnl
+IFDOS(` define(`rp', ``%rcx'') ') dnl
+IFDOS(` define(`v0', ``%r9'') ') dnl
+IFDOS(` define(`r9', ``rdi'') ') dnl
+IFDOS(` define(`n', ``%r8'') ') dnl
+IFDOS(` define(`r8', ``rbx'') ') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_1c)
+IFDOS(``push %rsi '')
+IFDOS(``push %rdi '')
+IFDOS(``mov %rdx, %rsi '')
+
+ mov (up), %rax C read first u limb early
+ push %rbx
+IFSTD(` mov n_param, %r11 ') C move away n from rdx, mul uses it
+IFDOS(` mov n, %r11 ')
+ mul v0
+
+IFSTD(` add %r8, %rax ')
+IFDOS(` add 64(%rsp), %rax ') C 40 + 3*8 (3 push insns)
+ adc $0, %rdx
+ jmp L(common)
+
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_mul_1)
+IFDOS(``push %rsi '')
+IFDOS(``push %rdi '')
+IFDOS(``mov %rdx, %rsi '')
+
+ mov (up), %rax C read first u limb early
+ push %rbx
+IFSTD(` mov n_param, %r11 ') C move away n from rdx, mul uses it
+IFDOS(` mov n, %r11 ')
+ mul v0
+
+L(common):
+IFSTD(` mov %r11, n ')
+
+ and $3, R32(%r11)
+ lea -16(rp,n,8), rp
+ jz L(b0)
+ cmp $2, R32(%r11)
+ jb L(b1)
+ jz L(b2)
+
+L(b3): mov %rax, %r10
+ mov %rdx, %r11
+ mov 8(up), %rax
+ mul v0
+ lea (up,n,8), up
+ not n
+ jmp L(L3)
+
+L(b0): mov %rax, %r9
+ mov %rdx, %r10
+ mov 8(up), %rax
+ lea (up,n,8), up
+ neg n
+ jmp L(L0)
+
+L(b1): mov %rax, %r8
+ cmp $1, n
+ jz L(n1)
+ mov %rdx, %r9
+ lea (up,n,8), up
+ neg n
+ mov %r8, 16(rp,n,8)
+ inc n
+ jmp L(L1)
+
+L(b2): mov %rax, %r11
+ mov %rdx, %r8
+ mov 8(up), %rax
+ lea (up,n,8), up
+ neg n
+ add $2, n
+ jns L(end)
+
+ ALIGN(16)
+L(top): mul v0
+ mov %rdx, %r9
+ add %rax, %r8
+ adc $0, %r9
+ mov %r8, 8(rp,n,8)
+ mov %r11, (rp,n,8)
+L(L1): mov (up,n,8), %rax
+ mul v0
+ add %rax, %r9
+ mov %rdx, %r10
+ mov 8(up,n,8), %rax
+ adc $0, %r10
+L(L0): mul v0
+ add %rax, %r10
+ mov %rdx, %r11
+ mov 16(up,n,8), %rax
+ adc $0, %r11
+ mul v0
+ mov %r9, 16(rp,n,8)
+L(L3): add %rax, %r11
+ mov %r10, 24(rp,n,8)
+ mov %rdx, %r8
+ adc $0, %r8
+ add $4, n
+ mov -8(up,n,8), %rax
+ js L(top)
+
+L(end): mul v0
+ add %rax, %r8
+ adc $0, %rdx
+ mov %r11, (rp)
+L(n1): mov %r8, 8(rp)
+ mov %rdx, %rax
+
+ pop %rbx
+IFDOS(``pop %rdi '')
+IFDOS(``pop %rsi '')
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/bd1/mul_2.asm b/gmp/mpn/x86_64/bd1/mul_2.asm
new file mode 100644
index 0000000000..4ed5f30561
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/mul_2.asm
@@ -0,0 +1,192 @@
+dnl AMD64 mpn_mul_2 optimised for AMD Bulldozer.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9
+C AMD K10
+C AMD bull 4.36 average, quite fluctuating
+C AMD pile 4.38 slighty fluctuating
+C AMD steam
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core
+C Intel NHM
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+C Scheme: genxmul --mul
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`vp', `%rcx') C r9
+
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+define(`n', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mul_2)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov (up), %rax
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ lea (up,n_param,8), up
+ lea (rp,n_param,8), rp
+
+ mov n_param, n
+ mul v0
+ neg n
+
+ test $1, R8(n)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n)
+ jnz L(b10)
+
+L(b00): mov %rax, w0
+ mov %rdx, w1
+ xor R32(w2), R32(w2)
+ mov (up,n,8), %rax
+ jmp L(lo0)
+
+L(b10): mov %rax, w2
+ mov %rdx, w3
+ mov (up,n,8), %rax
+ xor R32(w0), R32(w0)
+ mul v1
+ add $-2, n
+ jmp L(lo2)
+
+L(bx1): test $2, R8(n)
+ jz L(b11)
+
+L(b01): mov %rax, w3
+ mov %rdx, w0
+ mov (up,n,8), %rax
+ mul v1
+ xor R32(w1), R32(w1)
+ inc n
+ jmp L(lo1)
+
+L(b11): mov %rax, w1
+ mov %rdx, w2
+ mov (up,n,8), %rax
+ xor R32(w3), R32(w3)
+ dec n
+ jmp L(lo3)
+
+ ALIGN(32)
+L(top): mov -8(up,n,8), %rax
+ mul v1
+ mov w2, -16(rp,n,8)
+L(lo1): add %rax, w0
+ mov w3, -8(rp,n,8)
+ adc %rdx, w1
+ mov (up,n,8), %rax
+ mul v0
+ mov $0, R32(w2)
+ add %rax, w0
+ adc %rdx, w1
+ adc $0, R32(w2)
+ mov (up,n,8), %rax
+L(lo0): mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 8(up,n,8), %rax
+ mul v0
+ add %rax, w1
+ mov w0, (rp,n,8)
+ mov $0, R32(w3)
+ mov 8(up,n,8), %rax
+ adc %rdx, w2
+ adc $0, R32(w3)
+L(lo3): mul v1
+ add %rax, w2
+ mov 16(up,n,8), %rax
+ adc %rdx, w3
+ mul v0
+ add %rax, w2
+ mov 16(up,n,8), %rax
+ mov $0, R32(w0)
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ mov w1, 8(rp,n,8)
+L(lo2): add %rax, w3
+ adc %rdx, w0
+ mov 24(up,n,8), %rax
+ mul v0
+ add %rax, w3
+ adc %rdx, w0
+ mov $0, R32(w1)
+ adc $0, R32(w1)
+ add $4, n
+ jnc L(top)
+
+L(end): mov -8(up,n,8), %rax
+ mul v1
+ mov w2, -16(rp,n,8)
+ add %rax, w0
+ mov w3, -8(rp,n,8)
+ adc %rdx, w1
+ mov w0, (rp,n,8)
+ mov w1, %rax
+
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bd1/mul_basecase.asm b/gmp/mpn/x86_64/bd1/mul_basecase.asm
new file mode 100644
index 0000000000..e47ba587cd
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/mul_basecase.asm
@@ -0,0 +1,416 @@
+dnl AMD64 mpn_mul_basecase optimised for AMD Bulldozer and Piledriver.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_1 mul_2 mul_3 addmul_2
+C AMD K8,K9
+C AMD K10
+C AMD bull ~4.8 ~4.55 - ~4.3
+C AMD pile ~4.6 ~4.55 - ~4.55
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core
+C Intel NHM
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * Merge bull-specific mul_1, if it is not slower the TOOM22 range.
+C Alternatively, we could tweak the present code (which was loopmixed for a
+C different CPU).
+C * Merge faster mul_2, such as the one in the same directory as this file.
+C * Further micro-optimise.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param',`%rdx')
+define(`vp', `%rcx')
+define(`vn', `%r8')
+
+define(`un', `%rbx')
+
+define(`w0', `%r10')
+define(`w1', `%r11')
+define(`w2', `%r12')
+define(`w3', `%r13')
+define(`n', `%rbp')
+define(`v0', `%r9')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_basecase)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+ push %rbx
+ push %rbp
+ mov un_param, un C free up rdx
+ neg un
+
+ mov (up), %rax C shared for mul_1 and mul_2
+ lea (up,un_param,8), up C point at operand end
+ lea (rp,un_param,8), rp C point at rp[un-1]
+
+ mov (vp), v0 C shared for mul_1 and mul_2
+ mul v0 C shared for mul_1 and mul_2
+
+ test $1, R8(vn)
+ jz L(do_mul_2)
+
+L(do_mul_1):
+ test $1, R8(un)
+ jnz L(m1x1)
+
+L(m1x0):mov %rax, w0 C un = 2, 4, 6, 8, ...
+ mov %rdx, w1
+ mov 8(up,un,8), %rax
+ test $2, R8(un)
+ jnz L(m110)
+
+L(m100):lea 2(un), n C un = 4, 8, 12, ...
+ jmp L(m1l0)
+
+L(m110):lea (un), n C un = 2, 6, 10, ...
+ jmp L(m1l2)
+
+L(m1x1):mov %rax, w1 C un = 1, 3, 5, 7, ...
+ mov %rdx, w0
+ test $2, R8(un)
+ jz L(m111)
+
+L(m101):lea 3(un), n C un = 1, 5, 9, ...
+ test n, n
+ js L(m1l1)
+ mov %rax, -8(rp)
+ mov %rdx, (rp)
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(m111):lea 1(un), n C un = 3, 7, 11, ...
+ mov 8(up,un,8), %rax
+ jmp L(m1l3)
+
+ ALIGN(16)
+L(m1tp):mov %rdx, w0
+ add %rax, w1
+L(m1l1):mov -16(up,n,8), %rax
+ adc $0, w0
+ mul v0
+ add %rax, w0
+ mov w1, -24(rp,n,8)
+ mov -8(up,n,8), %rax
+ mov %rdx, w1
+ adc $0, w1
+L(m1l0):mul v0
+ mov w0, -16(rp,n,8)
+ add %rax, w1
+ mov %rdx, w0
+ mov (up,n,8), %rax
+ adc $0, w0
+L(m1l3):mul v0
+ mov w1, -8(rp,n,8)
+ mov %rdx, w1
+ add %rax, w0
+ mov 8(up,n,8), %rax
+ adc $0, w1
+L(m1l2):mul v0
+ mov w0, (rp,n,8)
+ add $4, n
+ jnc L(m1tp)
+
+L(m1ed):add %rax, w1
+ adc $0, %rdx
+ mov w1, I(-8(rp),-24(rp,n,8))
+ mov %rdx, I((rp),-16(rp,n,8))
+
+ dec R32(vn)
+ jz L(ret2)
+
+ lea 8(vp), vp
+ lea 8(rp), rp
+ push %r12
+ push %r13
+ push %r14
+ jmp L(do_addmul)
+
+L(do_mul_2):
+define(`v1', `%r14')
+ push %r12
+ push %r13
+ push %r14
+
+ mov 8(vp), v1
+
+ test $1, R8(un)
+ jnz L(m2b1)
+
+L(m2b0):lea (un), n
+ mov %rax, w2 C 0
+ mov (up,un,8), %rax
+ mov %rdx, w1 C 1
+ mul v1
+ mov %rax, w0 C 1
+ mov w2, (rp,un,8) C 0
+ mov 8(up,un,8), %rax
+ mov %rdx, w2 C 2
+ jmp L(m2l0)
+
+L(m2b1):lea 1(un), n
+ mov %rax, w0 C 1
+ mov %rdx, w3 C 2
+ mov (up,un,8), %rax
+ mul v1
+ mov w0, (rp,un,8) C 1
+ mov %rdx, w0 C 3
+ mov %rax, w2 C 0
+ mov 8(up,un,8), %rax
+ jmp L(m2l1)
+
+ ALIGN(32)
+L(m2tp):add %rax, w2 C 0
+ mov (up,n,8), %rax
+ adc $0, w0 C 1
+L(m2l1):mul v0
+ add %rax, w2 C 0
+ mov (up,n,8), %rax
+ mov %rdx, w1 C 1
+ adc $0, w1 C 1
+ mul v1
+ add w3, w2 C 0
+ adc $0, w1 C 1
+ add %rax, w0 C 1
+ mov w2, (rp,n,8) C 0
+ mov 8(up,n,8), %rax
+ mov %rdx, w2 C 2
+ adc $0, w2 C 2
+L(m2l0):mul v0
+ add %rax, w0 C 1
+ mov %rdx, w3 C 2
+ adc $0, w3 C 2
+ add w1, w0 C 1
+ adc $0, w3 C 2
+ mov 8(up,n,8), %rax
+ mul v1
+ add $2, n
+ mov w0, -8(rp,n,8) C 1
+ mov %rdx, w0 C 3
+ jnc L(m2tp)
+
+L(m2ed):add %rax, w2
+ adc $0, %rdx
+ add w3, w2
+ adc $0, %rdx
+ mov w2, I((rp),(rp,n,8))
+ mov %rdx, I(8(rp),8(rp,n,8))
+
+ add $-2, R32(vn)
+ jz L(ret5)
+
+ lea 16(vp), vp
+ lea 16(rp), rp
+
+
+L(do_addmul):
+ push %r15
+ push vn C save vn in new stack slot
+define(`vn', `(%rsp)')
+define(`X0', `%r14')
+define(`X1', `%r15')
+define(`v1', `%r8')
+
+L(outer):
+ mov (vp), v0
+ mov 8(vp), v1
+
+ mov (up,un,8), %rax
+ mul v0
+
+ test $1, R8(un)
+ jnz L(bx1)
+
+L(bx0): mov %rax, X1
+ mov (up,un,8), %rax
+ mov %rdx, X0
+ mul v1
+ test $2, R8(un)
+ jnz L(b10)
+
+L(b00): lea (un), n C un = 4, 8, 12, ...
+ mov (rp,un,8), w3
+ mov %rax, w0
+ mov 8(up,un,8), %rax
+ mov %rdx, w1
+ jmp L(lo0)
+
+L(b10): lea 2(un), n C un = 2, 6, 10, ...
+ mov (rp,un,8), w1
+ mov %rdx, w3
+ mov %rax, w2
+ mov 8(up,un,8), %rax
+ jmp L(lo2)
+
+L(bx1): mov %rax, X0
+ mov (up,un,8), %rax
+ mov %rdx, X1
+ mul v1
+ test $2, R8(un)
+ jz L(b11)
+
+L(b01): lea 1(un), n C un = 1, 5, 9, ...
+ mov (rp,un,8), w2
+ mov %rdx, w0
+ mov %rax, w3
+ jmp L(lo1)
+
+L(b11): lea -1(un), n C un = 3, 7, 11, ...
+ mov (rp,un,8), w0
+ mov %rax, w1
+ mov 8(up,un,8), %rax
+ mov %rdx, w2
+ jmp L(lo3)
+
+ ALIGN(32)
+L(top):
+L(lo2): mul v0
+ add w1, X1
+ mov X1, -16(rp,n,8)
+ mov %rdx, X1
+ adc %rax, X0
+ adc $0, X1
+ mov -8(up,n,8), %rax
+ mul v1
+ mov -8(rp,n,8), w1
+ mov %rdx, w0
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+L(lo1): mov (up,n,8), %rax
+ mul v0
+ add w2, X0
+ mov X0, -8(rp,n,8)
+ mov %rdx, X0
+ adc %rax, X1
+ mov (up,n,8), %rax
+ adc $0, X0
+ mov (rp,n,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ mov 8(up,n,8), %rax
+ mov %rdx, w1
+ adc $0, w1
+L(lo0): mul v0
+ add w3, X1
+ mov X1, (rp,n,8)
+ adc %rax, X0
+ mov 8(up,n,8), %rax
+ mov %rdx, X1
+ adc $0, X1
+ mov 8(rp,n,8), w3
+ mul v1
+ add w3, w0
+ adc %rax, w1
+ mov 16(up,n,8), %rax
+ mov %rdx, w2
+ adc $0, w2
+L(lo3): mul v0
+ add w0, X0
+ mov X0, 8(rp,n,8)
+ mov %rdx, X0
+ adc %rax, X1
+ adc $0, X0
+ mov 16(up,n,8), %rax
+ mov 16(rp,n,8), w0
+ mul v1
+ mov %rdx, w3
+ add w0, w1
+ adc %rax, w2
+ adc $0, w3
+ mov 24(up,n,8), %rax
+ add $4, n
+ jnc L(top)
+
+L(end): mul v0
+ add w1, X1
+ mov X1, I(-16(rp),-16(rp,n,8))
+ mov %rdx, X1
+ adc %rax, X0
+ adc $0, X1
+ mov I(-8(up),-8(up,n,8)), %rax
+ mul v1
+ mov I(-8(rp),-8(rp,n,8)), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, %rdx
+ add w2, X0
+ adc $0, X1
+ mov X0, I(-8(rp),-8(rp,n,8))
+ add w3, X1
+ mov X1, I((rp),(rp,n,8))
+ adc $0, %rdx
+ mov %rdx, I(8(rp),8(rp,n,8))
+
+
+ addl $-2, vn
+ lea 16(vp), vp
+ lea 16(rp), rp
+ jnz L(outer)
+
+ pop %rax C deallocate vn slot
+ pop %r15
+L(ret5):pop %r14
+ pop %r13
+ pop %r12
+L(ret2):pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bd1/popcount.asm b/gmp/mpn/x86_64/bd1/popcount.asm
new file mode 100644
index 0000000000..8f22a715b6
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/popcount.asm
@@ -0,0 +1,38 @@
+dnl AMD64 mpn_popcount -- population count.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_popcount)
+include_mpn(`x86_64/k10/popcount.asm')
diff --git a/gmp/mpn/x86_64/bd1/sec_tabselect.asm b/gmp/mpn/x86_64/bd1/sec_tabselect.asm
new file mode 100644
index 0000000000..e4360341d9
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/sec_tabselect.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_sec_tabselect.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_sec_tabselect)
+include_mpn(`x86_64/fastsse/sec_tabselect.asm')
diff --git a/gmp/mpn/x86_64/bd1/sublsh1_n.asm b/gmp/mpn/x86_64/bd1/sublsh1_n.asm
new file mode 100644
index 0000000000..4ba673d15a
--- /dev/null
+++ b/gmp/mpn/x86_64/bd1/sublsh1_n.asm
@@ -0,0 +1,37 @@
+dnl AMD64 mpn_sublsh1_n
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_sublsh1_n mpn_sublsh1_nc)
+include_mpn(`x86_64/atom/sublsh1_n.asm')
diff --git a/gmp/mpn/x86_64/bd2/gmp-mparam.h b/gmp/mpn/x86_64/bd2/gmp-mparam.h
new file mode 100644
index 0000000000..16f25c4c7b
--- /dev/null
+++ b/gmp/mpn/x86_64/bd2/gmp-mparam.h
@@ -0,0 +1,237 @@
+/* AMD bd2 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2010, 2012, 2014 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 3200 MHz Piledriver Vishera */
+/* FFT tuning limit = 40000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.8 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 17
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 34
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 10
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 2
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 21
+
+#define MUL_TOOM22_THRESHOLD 16
+#define MUL_TOOM33_THRESHOLD 54
+#define MUL_TOOM44_THRESHOLD 154
+#define MUL_TOOM6H_THRESHOLD 274
+#define MUL_TOOM8H_THRESHOLD 454
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 114
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 105
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 105
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 147
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 22
+#define SQR_TOOM3_THRESHOLD 81
+#define SQR_TOOM4_THRESHOLD 218
+#define SQR_TOOM6_THRESHOLD 303
+#define SQR_TOOM8_THRESHOLD 430
+
+#define MULMID_TOOM42_THRESHOLD 20
+
+#define MULMOD_BNM1_THRESHOLD 12
+#define SQRMOD_BNM1_THRESHOLD 13
+
+#define MUL_FFT_MODF_THRESHOLD 376 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 376, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 23, 7}, { 13, 6}, { 27, 7}, { 21, 8}, \
+ { 11, 7}, { 25, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 32, 8}, { 17, 7}, { 35, 8}, \
+ { 21, 9}, { 11, 8}, { 27, 9}, { 15, 8}, \
+ { 35, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 49, 9}, { 27,10}, { 15, 9}, { 39,10}, \
+ { 23, 9}, { 51,11}, { 15,10}, { 31, 9}, \
+ { 71,10}, { 39, 9}, { 83,10}, { 47, 9}, \
+ { 99,10}, { 55,11}, { 31,10}, { 79,11}, \
+ { 47,10}, { 95,12}, { 31,11}, { 63,10}, \
+ { 135, 6}, { 2175, 7}, { 1151, 9}, { 303,10}, \
+ { 159, 9}, { 319, 8}, { 639, 9}, { 335,11}, \
+ { 95,10}, { 191,11}, { 111,12}, { 63,11}, \
+ { 127,10}, { 255,11}, { 143,10}, { 303,11}, \
+ { 159,12}, { 95,11}, { 191,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 511,11}, { 271,10}, \
+ { 543,11}, { 287,10}, { 575,11}, { 303,12}, \
+ { 159,11}, { 319,10}, { 639,11}, { 351,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,12}, \
+ { 223,11}, { 447,13}, { 127,12}, { 255,11}, \
+ { 511,12}, { 287,11}, { 575,10}, { 1151,12}, \
+ { 319,11}, { 639,10}, { 1279,12}, { 351,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,10}, \
+ { 1663,12}, { 447,14}, { 127,13}, { 255,12}, \
+ { 511,11}, { 1023,12}, { 543,11}, { 1087,10}, \
+ { 2175,12}, { 575,11}, { 1151,12}, { 607,13}, \
+ { 319,12}, { 639,11}, { 1279,12}, { 671,11}, \
+ { 1343,10}, { 2687,12}, { 703,11}, { 1407,10}, \
+ { 2815,12}, { 735,13}, { 383,12}, { 767,11}, \
+ { 1599,12}, { 831,11}, { 1663,13}, { 447,12}, \
+ { 895,11}, { 1791,14}, { 255,13}, { 511,12}, \
+ { 1023,11}, { 2047,12}, { 1087,11}, { 2175,13}, \
+ { 575,12}, { 1151,11}, { 2303,12}, { 1215,11}, \
+ { 2431,10}, { 4863,13}, { 639,12}, { 1279,11}, \
+ { 2559,12}, { 1343,11}, { 2687,13}, { 703,12}, \
+ { 1407,11}, { 2815,14}, { 383,13}, { 767,12}, \
+ { 1599,13}, { 831,12}, { 1663,13}, { 895,12}, \
+ { 1791,15}, { 255,14}, { 511,13}, { 1023,12}, \
+ { 2047,13}, { 1087,12}, { 2175,13}, { 1151,12}, \
+ { 2303,13}, { 1215,12}, { 2431,11}, { 4863,14}, \
+ { 639,13}, { 1343,12}, { 2687,13}, { 1407,12}, \
+ { 2815,13}, { 1471,12}, { 2943,11}, { 5887,14}, \
+ { 767,13}, { 1599,12}, { 3199,13}, { 1727,14}, \
+ { 895,13}, { 1791,12}, { 3583,13}, { 1919,12}, \
+ { 3839,11}, { 7679,15}, { 511,14}, { 1023,13}, \
+ { 2175,14}, { 1151,13}, { 2431,12}, { 4863,14}, \
+ { 1279,13}, { 2687,14}, { 1407,13}, { 2943,12}, \
+ { 5887,15}, { 767,14}, { 1535,13}, { 3199,14}, \
+ { 1663,13}, { 3455,12}, { 6911,14}, { 1791,13}, \
+ { 3583,14}, { 1919,13}, { 3839,12}, { 7679,16}, \
+ { 511,15}, { 1023,14}, { 2175,13}, { 4479,14}, \
+ { 2303,13}, { 4607,14}, { 2431,13}, { 4863,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 225
+#define MUL_FFT_THRESHOLD 3712
+
+#define SQR_FFT_MODF_THRESHOLD 344 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 344, 5}, { 11, 4}, { 23, 5}, { 19, 6}, \
+ { 10, 5}, { 21, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 17, 6}, \
+ { 35, 8}, { 9, 7}, { 21, 8}, { 11, 7}, \
+ { 25, 8}, { 13, 7}, { 27, 8}, { 15, 7}, \
+ { 31, 8}, { 17, 7}, { 35, 8}, { 21, 9}, \
+ { 11, 8}, { 27, 9}, { 15, 8}, { 35, 9}, \
+ { 19, 8}, { 39, 9}, { 23, 8}, { 47, 9}, \
+ { 27,10}, { 15, 9}, { 39,10}, { 23, 9}, \
+ { 51,11}, { 15,10}, { 31, 9}, { 63,10}, \
+ { 39, 9}, { 79,10}, { 47, 9}, { 95,11}, \
+ { 31,10}, { 79,11}, { 47,10}, { 95,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 135,11}, { 95,10}, { 191, 6}, { 3199, 7}, \
+ { 1727, 9}, { 447,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271,11}, { 143,10}, { 287, 9}, \
+ { 575,10}, { 303, 9}, { 607,10}, { 319,12}, \
+ { 95,11}, { 191,10}, { 383,11}, { 207,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 271,10}, { 543,11}, { 287,10}, { 575,11}, \
+ { 351,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,12}, { 223,11}, { 447,10}, { 895,13}, \
+ { 127,12}, { 255,11}, { 511,10}, { 1023,11}, \
+ { 543,12}, { 287,11}, { 575,12}, { 319,10}, \
+ { 1279,12}, { 351,13}, { 191,12}, { 383,11}, \
+ { 767,12}, { 415,11}, { 831,12}, { 447,11}, \
+ { 895,14}, { 127,13}, { 255,12}, { 511,11}, \
+ { 1023,12}, { 543,11}, { 1087,10}, { 2175,12}, \
+ { 575,13}, { 319,11}, { 1279,12}, { 671,11}, \
+ { 1343,12}, { 703,11}, { 1407,13}, { 383,12}, \
+ { 767,11}, { 1535,12}, { 799,11}, { 1599,12}, \
+ { 831,11}, { 1663,13}, { 447,12}, { 895,14}, \
+ { 255,13}, { 511,12}, { 1087,11}, { 2175,13}, \
+ { 575,11}, { 2303,12}, { 1215,11}, { 2431,10}, \
+ { 4863,13}, { 639,12}, { 1343,11}, { 2687,13}, \
+ { 703,12}, { 1407,14}, { 383,13}, { 767,12}, \
+ { 1599,13}, { 831,12}, { 1727,11}, { 3455,13}, \
+ { 895,15}, { 255,14}, { 511,13}, { 1087,12}, \
+ { 2239,11}, { 4479,12}, { 2303,13}, { 1215,12}, \
+ { 2431,11}, { 4863,14}, { 639,13}, { 1279,12}, \
+ { 2559,13}, { 1343,12}, { 2687,13}, { 1407,12}, \
+ { 2815,13}, { 1471,12}, { 2943,11}, { 5887,14}, \
+ { 767,13}, { 1599,12}, { 3199,13}, { 1727,14}, \
+ { 895,13}, { 1791,12}, { 3583,13}, { 1919,12}, \
+ { 3839,15}, { 511,14}, { 1023,13}, { 2431,12}, \
+ { 4863,14}, { 1279,13}, { 2687,14}, { 1407,13}, \
+ { 2943,12}, { 5887,11}, { 11775,15}, { 767,14}, \
+ { 1535,13}, { 3199,14}, { 1663,13}, { 3455,12}, \
+ { 6911,14}, { 1791,13}, { 3583,14}, { 1919,13}, \
+ { 3839,16}, { 511,15}, { 1023,14}, { 2175,13}, \
+ { 4479,14}, { 2303,13}, { 4607,14}, { 2431,13}, \
+ { 4863,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 214
+#define SQR_FFT_THRESHOLD 3264
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 37
+#define MULLO_MUL_N_THRESHOLD 8397
+
+#define DC_DIV_QR_THRESHOLD 42
+#define DC_DIVAPPR_Q_THRESHOLD 173
+#define DC_BDIV_QR_THRESHOLD 42
+#define DC_BDIV_Q_THRESHOLD 77
+
+#define INV_MULMOD_BNM1_THRESHOLD 30
+#define INV_NEWTON_THRESHOLD 202
+#define INV_APPR_THRESHOLD 172
+
+#define BINV_NEWTON_THRESHOLD 238
+#define REDC_1_TO_REDC_2_THRESHOLD 44
+#define REDC_2_TO_REDC_N_THRESHOLD 0 /* always */
+
+#define MU_DIV_QR_THRESHOLD 1308
+#define MU_DIVAPPR_Q_THRESHOLD 1334
+#define MUPI_DIV_QR_THRESHOLD 85
+#define MU_BDIV_QR_THRESHOLD 1142
+#define MU_BDIV_Q_THRESHOLD 1308
+
+#define POWM_SEC_TABLE 1,16,257,452,1099,2079
+
+#define MATRIX22_STRASSEN_THRESHOLD 14
+#define HGCD_THRESHOLD 110
+#define HGCD_APPR_THRESHOLD 96
+#define HGCD_REDUCE_THRESHOLD 2479
+#define GCD_DC_THRESHOLD 372
+#define GCDEXT_DC_THRESHOLD 293
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 20
+#define SET_STR_DC_THRESHOLD 204
+#define SET_STR_PRECOMPUTE_THRESHOLD 1160
+
+#define FAC_DSC_THRESHOLD 166
+#define FAC_ODD_THRESHOLD 24
diff --git a/gmp/mpn/x86_64/bdiv_dbm1c.asm b/gmp/mpn/x86_64/bdiv_dbm1c.asm
new file mode 100644
index 0000000000..a53bd52beb
--- /dev/null
+++ b/gmp/mpn/x86_64/bdiv_dbm1c.asm
@@ -0,0 +1,106 @@
+dnl x86_64 mpn_bdiv_dbm1.
+
+dnl Copyright 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.25
+C AMD K10 2.25
+C Intel P4 12.5
+C Intel core2 4
+C Intel NHM 3.75
+C Intel SBR 3.6
+C Intel atom 20
+C VIA nano 4
+
+C TODO
+C * Optimise feed-in code.
+
+C INPUT PARAMETERS
+define(`qp', `%rdi')
+define(`up', `%rsi')
+define(`n_param', `%rdx')
+define(`bd', `%rcx')
+define(`cy', `%r8')
+
+define(`n', `%r9')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_bdiv_dbm1c)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ mov (up), %rax
+ mov n_param, n
+ mov R32(n_param), R32(%r11)
+ mul bd
+ lea (up,n,8), up
+ lea (qp,n,8), qp
+ neg n
+ and $3, R32(%r11)
+ jz L(lo0)
+ lea -4(n,%r11), n
+ cmp $2, R32(%r11)
+ jc L(lo1)
+ jz L(lo2)
+ jmp L(lo3)
+
+ ALIGN(16)
+L(top): mov (up,n,8), %rax
+ mul bd
+L(lo0): sub %rax, %r8
+ mov %r8, (qp,n,8)
+ sbb %rdx, %r8
+ mov 8(up,n,8), %rax
+ mul bd
+L(lo3): sub %rax, %r8
+ mov %r8, 8(qp,n,8)
+ sbb %rdx, %r8
+ mov 16(up,n,8), %rax
+ mul bd
+L(lo2): sub %rax, %r8
+ mov %r8, 16(qp,n,8)
+ sbb %rdx, %r8
+ mov 24(up,n,8), %rax
+ mul bd
+L(lo1): sub %rax, %r8
+ mov %r8, 24(qp,n,8)
+ sbb %rdx, %r8
+ add $4, n
+ jnz L(top)
+
+ mov %r8, %rax
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bdiv_q_1.asm b/gmp/mpn/x86_64/bdiv_q_1.asm
new file mode 100644
index 0000000000..02eacbe6a8
--- /dev/null
+++ b/gmp/mpn/x86_64/bdiv_q_1.asm
@@ -0,0 +1,167 @@
+dnl AMD64 mpn_bdiv_q_1, mpn_pi1_bdiv_q_1 -- schoolbook Hensel division by
+dnl 1-limb divisor, returning quotient only.
+
+dnl Copyright 2001, 2002, 2004-2006, 2009, 2011, 2012 Free Software
+dnl Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 10
+C AMD K10 10
+C Intel P4 33
+C Intel core2 13.25
+C Intel corei 14
+C Intel atom 42
+C VIA nano ?
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`d', `%rcx')
+define(`di', `%r8') C just mpn_pi1_bdiv_q_1
+define(`ncnt', `%r9') C just mpn_pi1_bdiv_q_1
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_bdiv_q_1)
+ FUNC_ENTRY(4)
+ push %rbx
+
+ mov %rcx, %rax
+ xor R32(%rcx), R32(%rcx) C ncnt count
+ mov %rdx, %r10
+
+ bt $0, R32(%rax)
+ jnc L(evn) C skip bsfq unless divisor is even
+
+L(odd): mov %rax, %rbx
+ shr R32(%rax)
+ and $127, R32(%rax) C d/2, 7 bits
+
+ LEA( binvert_limb_table, %rdx)
+
+ movzbl (%rdx,%rax), R32(%rax) C inv 8 bits
+
+ mov %rbx, %r11 C d without twos
+
+ lea (%rax,%rax), R32(%rdx) C 2*inv
+ imul R32(%rax), R32(%rax) C inv*inv
+ imul R32(%rbx), R32(%rax) C inv*inv*d
+ sub R32(%rax), R32(%rdx) C inv = 2*inv - inv*inv*d, 16 bits
+
+ lea (%rdx,%rdx), R32(%rax) C 2*inv
+ imul R32(%rdx), R32(%rdx) C inv*inv
+ imul R32(%rbx), R32(%rdx) C inv*inv*d
+ sub R32(%rdx), R32(%rax) C inv = 2*inv - inv*inv*d, 32 bits
+
+ lea (%rax,%rax), %r8 C 2*inv
+ imul %rax, %rax C inv*inv
+ imul %rbx, %rax C inv*inv*d
+ sub %rax, %r8 C inv = 2*inv - inv*inv*d, 64 bits
+
+ jmp L(com)
+
+L(evn): bsf %rax, %rcx
+ shr R8(%rcx), %rax
+ jmp L(odd)
+EPILOGUE()
+
+PROLOGUE(mpn_pi1_bdiv_q_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+IFDOS(` mov 64(%rsp), %r9 ')
+ push %rbx
+
+ mov %rcx, %r11 C d
+ mov %rdx, %r10 C n
+ mov %r9, %rcx C ncnt
+
+L(com): mov (up), %rax C up[0]
+
+ dec %r10
+ jz L(one)
+
+ mov 8(up), %rdx C up[1]
+ lea (up,%r10,8), up C up end
+ lea (rp,%r10,8), rp C rp end
+ neg %r10 C -n
+
+ shrd R8(%rcx), %rdx, %rax
+
+ xor R32(%rbx), R32(%rbx)
+ jmp L(ent)
+
+ ALIGN(8)
+L(top):
+ C rax q
+ C rbx carry bit, 0 or 1
+ C rcx ncnt
+ C rdx
+ C r10 counter, limbs, negative
+
+ mul %r11 C carry limb in rdx
+ mov (up,%r10,8), %rax
+ mov 8(up,%r10,8), %r9
+ shrd R8(%rcx), %r9, %rax
+ nop
+ sub %rbx, %rax C apply carry bit
+ setc R8(%rbx)
+ sub %rdx, %rax C apply carry limb
+ adc $0, %rbx
+L(ent): imul %r8, %rax
+ mov %rax, (rp,%r10,8)
+ inc %r10
+ jnz L(top)
+
+ mul %r11 C carry limb in rdx
+ mov (up), %rax C up high limb
+ shr R8(%rcx), %rax
+ sub %rbx, %rax C apply carry bit
+ sub %rdx, %rax C apply carry limb
+ imul %r8, %rax
+ mov %rax, (rp)
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(one): shr R8(%rcx), %rax
+ imul %r8, %rax
+ mov %rax, (rp)
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bobcat/aors_n.asm b/gmp/mpn/x86_64/bobcat/aors_n.asm
new file mode 100644
index 0000000000..22287b8558
--- /dev/null
+++ b/gmp/mpn/x86_64/bobcat/aors_n.asm
@@ -0,0 +1,150 @@
+dnl AMD64 mpn_add_n, mpn_sub_n optimised for bobcat.
+
+dnl Copyright 2003-2005, 2007, 2008, 2010-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9
+C AMD K10
+C AMD bd1
+C AMD bobcat 2.28
+C Intel P4
+C Intel core2
+C Intel NHM
+C Intel SBR
+C Intel IBR
+C Intel atom
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimization tool suite written by David Harvey and Torbjorn Granlund.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`vp', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`cy', `%r8') C rsp+40 (mpn_add_nc and mpn_sub_nc)
+
+ifdef(`OPERATION_add_n', `
+ define(ADCSBB, adc)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(ADCSBB, sbb)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ xor %r8, %r8
+L(ent): test $1, R8(n)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n)
+ jnz L(b10)
+
+L(b00): shr $2, n
+ neg %r8
+ mov $3, R32(%rax)
+ mov (up), %r10
+ mov 8(up), %r11
+ jmp L(lo0)
+
+L(b10): shr $2, n
+ neg %r8
+ mov $1, R32(%rax)
+ mov (up), %r8
+ mov 8(up), %r9
+ jrcxz L(cj2)
+ jmp L(top)
+
+L(bx1): test $2, R8(n)
+ jnz L(b11)
+
+L(b01): shr $2, n
+ neg %r8
+ mov $0, R32(%rax)
+ mov (up), %r9
+ jrcxz L(cj1)
+ mov 8(up), %r10
+ jmp L(lo1)
+
+ ALIGN(8)
+L(b11): inc n
+ shr $2, n
+ neg %r8
+ mov $2, R32(%rax)
+ mov (up), %r11
+ jmp L(lo3)
+
+ ALIGN(4)
+L(top): mov 8(up,%rax,8), %r10
+ ADCSBB -8(vp,%rax,8), %r8
+ mov %r8, -8(rp,%rax,8)
+L(lo1): mov 16(up,%rax,8), %r11
+ ADCSBB (vp,%rax,8), %r9
+ lea 4(%rax), %rax
+ mov %r9, -32(rp,%rax,8)
+L(lo0): ADCSBB -24(vp,%rax,8), %r10
+ mov %r10, -24(rp,%rax,8)
+L(lo3): ADCSBB -16(vp,%rax,8), %r11
+ dec n
+ mov -8(up,%rax,8), %r8
+ mov %r11, -16(rp,%rax,8)
+L(lo2): mov (up,%rax,8), %r9
+ jnz L(top)
+
+L(cj2): ADCSBB -8(vp,%rax,8), %r8
+ mov %r8, -8(rp,%rax,8)
+L(cj1): ADCSBB (vp,%rax,8), %r9
+ mov %r9, (rp,%rax,8)
+
+ mov $0, R32(%rax)
+ adc $0, R32(%rax)
+
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ jmp L(ent)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bobcat/aorsmul_1.asm b/gmp/mpn/x86_64/bobcat/aorsmul_1.asm
new file mode 100644
index 0000000000..415a17cb7f
--- /dev/null
+++ b/gmp/mpn/x86_64/bobcat/aorsmul_1.asm
@@ -0,0 +1,183 @@
+dnl AMD64 mpn_addmul_1 and mpn_submul_1 optimised for AMD bobcat.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 4.5
+C AMD K10 4.5
+C AMD bd1 4.75
+C AMD bobcat 5
+C Intel P4 17.7
+C Intel core2 5.5
+C Intel NHM 5.43
+C Intel SBR 3.92
+C Intel atom 23
+C VIA nano 5.63
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`func', `mpn_submul_1')
+')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+C Standard parameters
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n_param', `%rdx')
+define(`v0', `%rcx')
+C Standard allocations
+define(`n', `%rbx')
+define(`w0', `%r8')
+define(`w1', `%r9')
+define(`w2', `%r10')
+define(`w3', `%r11')
+
+C DOS64 parameters
+IFDOS(` define(`rp', `%rcx') ') dnl
+IFDOS(` define(`up', `%rsi') ') dnl
+IFDOS(` define(`n_param', `%r8') ') dnl
+IFDOS(` define(`v0', `%r9') ') dnl
+C DOS64 allocations
+IFDOS(` define(`n', `%rbx') ') dnl
+IFDOS(` define(`w0', `%r8') ') dnl
+IFDOS(` define(`w1', `%rdi') ') dnl
+IFDOS(` define(`w2', `%r10') ') dnl
+IFDOS(` define(`w3', `%r11') ') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+IFDOS(` push %rsi ')
+IFDOS(` push %rdi ')
+IFDOS(` mov %rdx, %rsi ')
+
+ push %rbx
+ mov (up), %rax
+
+ lea -16(rp,n_param,8), rp
+ lea -16(up,n_param,8), up
+
+ mov n_param, n
+ and $3, R32(n_param)
+ jz L(b0)
+ cmp $2, R32(n_param)
+ ja L(b3)
+ jz L(b2)
+
+L(b1): mul v0
+ cmp $1, n
+ jz L(n1)
+ mov %rax, w2
+ mov %rdx, w3
+ neg n
+ add $3, n
+ jmp L(L1)
+L(n1): ADDSUB %rax, 8(rp)
+ adc $0, %rdx
+ mov %rdx, %rax
+ pop %rbx
+IFDOS(` pop %rdi ')
+IFDOS(` pop %rsi ')
+ ret
+
+L(b3): mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ neg n
+ inc n
+ jmp L(L3)
+
+L(b0): mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ neg n
+ add $2, n
+ jmp L(L0)
+
+L(b2): mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ neg n
+ jmp L(L2)
+
+ ALIGN(16)
+L(top): ADDSUB w0, -16(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+L(L1): mov 0(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ ADDSUB w2, -8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+L(L0): mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ ADDSUB w0, 0(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+L(L3): mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ ADDSUB w2, 8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+L(L2): mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(top)
+
+L(end): ADDSUB w0, (rp)
+ adc w1, w2
+ adc $0, w3
+ ADDSUB w2, 8(rp)
+ adc $0, w3
+ mov w3, %rax
+
+ pop %rbx
+IFDOS(` pop %rdi ')
+IFDOS(` pop %rsi ')
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bobcat/copyd.asm b/gmp/mpn/x86_64/bobcat/copyd.asm
new file mode 100644
index 0000000000..877714e903
--- /dev/null
+++ b/gmp/mpn/x86_64/bobcat/copyd.asm
@@ -0,0 +1,91 @@
+dnl AMD64 mpn_copyd optimised for AMD bobcat.
+
+dnl Copyright 2003, 2005, 2007, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 1
+C AMD K10 1-2 (alignment fluctuations)
+C AMD bd1 ?
+C AMD bobcat 1.5
+C Intel P4 2.8
+C Intel core2 1
+C Intel NHM 1-1.25
+C Intel SBR 1
+C Intel atom 2.87
+C VIA nano 2
+
+C INPUT PARAMETERS
+C rp rdi
+C up rsi
+C n rdx
+
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`n',`%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_copyd)
+ FUNC_ENTRY(3)
+ sub $4, n
+ jl L(end)
+ ALIGN(16)
+L(top): mov 24(up,n,8), %r8
+ mov %r8, 24(rp,n,8)
+ mov 16(up,n,8), %r8
+ mov %r8, 16(rp,n,8)
+ mov 8(up,n,8), %r8
+ mov %r8, 8(rp,n,8)
+ mov (up,n,8), %r8
+ mov %r8, (rp,n,8)
+L(ent): sub $4, n
+ jge L(top)
+
+L(end): cmp $-4, R32(n)
+ jz L(ret)
+ mov 24(up,n,8), %r8
+ mov %r8, 24(rp,n,8)
+ cmp $-3, R32(n)
+ jz L(ret)
+ mov 16(up,n,8), %r8
+ mov %r8, 16(rp,n,8)
+ cmp $-2, R32(n)
+ jz L(ret)
+ mov 8(up,n,8), %r8
+ mov %r8, 8(rp,n,8)
+
+L(ret): FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bobcat/copyi.asm b/gmp/mpn/x86_64/bobcat/copyi.asm
new file mode 100644
index 0000000000..ee0f578652
--- /dev/null
+++ b/gmp/mpn/x86_64/bobcat/copyi.asm
@@ -0,0 +1,94 @@
+dnl AMD64 mpn_copyi optimised for AMD bobcat.
+
+dnl Copyright 2003, 2005, 2007, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 1
+C AMD K10 1-2 (alignment fluctuations)
+C AMD bd1 ?
+C AMD bobcat 1.5
+C Intel P4 2.8
+C Intel core2 1
+C Intel NHM 1-1.25
+C Intel SBR 1
+C Intel atom 2.87
+C VIA nano 2
+
+C INPUT PARAMETERS
+C rp rdi
+C up rsi
+C n rdx
+
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`n',`%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_copyi)
+ FUNC_ENTRY(3)
+ lea -32(up,n,8), up
+ lea -32(rp,n,8), rp
+ neg n
+ add $4, n
+ jg L(end)
+ ALIGN(16)
+L(top): mov (up,n,8), %r8
+ mov %r8, (rp,n,8)
+ mov 8(up,n,8), %r8
+ mov %r8, 8(rp,n,8)
+ mov 16(up,n,8), %r8
+ mov %r8, 16(rp,n,8)
+ mov 24(up,n,8), %r8
+ mov %r8, 24(rp,n,8)
+L(ent): add $4, n
+ jle L(top)
+
+L(end): cmp $4, R32(n)
+ jz L(ret)
+ mov (up,n,8), %r8
+ mov %r8, (rp,n,8)
+ cmp $3, R32(n)
+ jz L(ret)
+ mov 8(up,n,8), %r8
+ mov %r8, 8(rp,n,8)
+ cmp $2, R32(n)
+ jz L(ret)
+ mov 16(up,n,8), %r8
+ mov %r8, 16(rp,n,8)
+
+L(ret): FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bobcat/gmp-mparam.h b/gmp/mpn/x86_64/bobcat/gmp-mparam.h
new file mode 100644
index 0000000000..de4c4e4528
--- /dev/null
+++ b/gmp/mpn/x86_64/bobcat/gmp-mparam.h
@@ -0,0 +1,208 @@
+/* AMD Bobcat gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2012, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+#undef HAVE_NATIVE_mpn_mul_2
+#undef HAVE_NATIVE_mpn_addmul_2
+
+/* 1600 MHz AMD Bobcat Zacate E-350 */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 32
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 43
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 10
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 17
+
+#define MUL_TOOM22_THRESHOLD 24
+#define MUL_TOOM33_THRESHOLD 36
+#define MUL_TOOM44_THRESHOLD 268
+#define MUL_TOOM6H_THRESHOLD 396
+#define MUL_TOOM8H_THRESHOLD 517
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 69
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 195
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 181
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 72
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 103
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 26
+#define SQR_TOOM3_THRESHOLD 93
+#define SQR_TOOM4_THRESHOLD 375
+#define SQR_TOOM6_THRESHOLD 0 /* always */
+#define SQR_TOOM8_THRESHOLD 478
+
+#define MULMID_TOOM42_THRESHOLD 22
+
+#define MULMOD_BNM1_THRESHOLD 11
+#define SQRMOD_BNM1_THRESHOLD 13
+
+#define MUL_FFT_MODF_THRESHOLD 400 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 400, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 10, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 20, 7}, { 11, 6}, { 23, 7}, { 21, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 17, 7}, { 36, 8}, \
+ { 19, 7}, { 39, 8}, { 21, 9}, { 11, 8}, \
+ { 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
+ { 37, 9}, { 19, 8}, { 43, 9}, { 23, 8}, \
+ { 49, 9}, { 27,10}, { 15, 9}, { 43,10}, \
+ { 23, 9}, { 55,11}, { 15,10}, { 31, 9}, \
+ { 67,10}, { 39, 9}, { 83,10}, { 47, 9}, \
+ { 99,10}, { 55,11}, { 31,10}, { 63, 9}, \
+ { 127,10}, { 71, 9}, { 143,10}, { 79,11}, \
+ { 47,10}, { 103,12}, { 31,11}, { 63,10}, \
+ { 143,11}, { 79,10}, { 167,11}, { 95,10}, \
+ { 191, 9}, { 383,11}, { 111,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,11}, { 143,10}, \
+ { 287,11}, { 159,10}, { 319,12}, { 95,11}, \
+ { 191,10}, { 383,11}, { 207,10}, { 415,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 271,10}, { 543,11}, { 287,12}, { 159,11}, \
+ { 319,10}, { 639,11}, { 351,10}, { 703,11}, \
+ { 367,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,12}, { 223,11}, { 447,13}, { 127,12}, \
+ { 255,11}, { 543,12}, { 287,11}, { 607,12}, \
+ { 319,11}, { 639,12}, { 351,11}, { 703,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,12}, { 447,14}, { 127,13}, { 255,12}, \
+ { 607,13}, { 319,12}, { 703,13}, { 383,12}, \
+ { 831,13}, { 447,12}, { 895,14}, { 255,13}, \
+ { 511,12}, { 1023,13}, { 575,12}, { 1151,13}, \
+ { 703,14}, { 383,13}, { 831,12}, { 1663,13}, \
+ { 895,15}, { 255,14}, { 511,13}, { 1087,12}, \
+ { 2175,13}, { 1151,14}, { 639,13}, { 1407,14}, \
+ { 767,13}, { 1663,14}, { 895,15}, { 511,14}, \
+ { 1023,13}, { 2175,14}, { 1151,13}, { 2431,14}, \
+ { 1279,13}, { 2559,14}, { 1407,15}, { 32768,16}, \
+ { 65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+ {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 156
+#define MUL_FFT_THRESHOLD 5504
+
+#define SQR_FFT_MODF_THRESHOLD 380 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 380, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 10, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 12, 5}, { 25, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 25, 8}, \
+ { 13, 7}, { 27, 8}, { 15, 7}, { 31, 8}, \
+ { 17, 7}, { 35, 8}, { 19, 7}, { 39, 8}, \
+ { 27, 9}, { 15, 8}, { 35, 9}, { 19, 8}, \
+ { 41, 9}, { 23, 8}, { 49, 9}, { 27,10}, \
+ { 15, 9}, { 31, 8}, { 63, 9}, { 43,10}, \
+ { 23, 9}, { 55,10}, { 31, 9}, { 71,10}, \
+ { 39, 9}, { 83,10}, { 47, 9}, { 99,10}, \
+ { 55,11}, { 31,10}, { 79,11}, { 47,10}, \
+ { 103,12}, { 31,11}, { 63,10}, { 127, 9}, \
+ { 255,10}, { 135, 9}, { 271,11}, { 79,10}, \
+ { 159, 9}, { 319,11}, { 95,10}, { 191, 9}, \
+ { 383,11}, { 111,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,10}, { 271,11}, { 143,10}, \
+ { 287, 9}, { 575,10}, { 303,11}, { 159,10}, \
+ { 319,12}, { 95,11}, { 191,10}, { 383,11}, \
+ { 207,10}, { 415,13}, { 63,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 271,10}, { 575,11}, \
+ { 303,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 335,10}, { 671,11}, { 351,10}, { 703,11}, \
+ { 367,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,12}, { 223,11}, { 447,13}, { 127,12}, \
+ { 255,11}, { 543,12}, { 287,11}, { 607,12}, \
+ { 319,11}, { 671,12}, { 351,11}, { 703,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,12}, { 479,14}, { 127,13}, { 255,12}, \
+ { 607,13}, { 319,12}, { 703,13}, { 383,12}, \
+ { 831,13}, { 447,12}, { 895,14}, { 255,13}, \
+ { 511,12}, { 1023,13}, { 575,12}, { 1151,13}, \
+ { 703,14}, { 383,13}, { 831,12}, { 1663,13}, \
+ { 895,15}, { 255,14}, { 511,13}, { 1087,12}, \
+ { 2175,13}, { 1151,14}, { 639,13}, { 1343,12}, \
+ { 2687,14}, { 767,13}, { 1599,12}, { 3199,13}, \
+ { 1663,14}, { 895,15}, { 511,14}, { 1023,13}, \
+ { 2175,14}, { 1151,13}, { 2431,14}, { 1279,13}, \
+ { 2687,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 162
+#define SQR_FFT_THRESHOLD 3712
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 26
+#define MULLO_MUL_N_THRESHOLD 10950
+
+#define DC_DIV_QR_THRESHOLD 63
+#define DC_DIVAPPR_Q_THRESHOLD 198
+#define DC_BDIV_QR_THRESHOLD 56
+#define DC_BDIV_Q_THRESHOLD 127
+
+#define INV_MULMOD_BNM1_THRESHOLD 46
+#define INV_NEWTON_THRESHOLD 236
+#define INV_APPR_THRESHOLD 204
+
+#define BINV_NEWTON_THRESHOLD 286
+#define REDC_1_TO_REDC_2_THRESHOLD 63
+#define REDC_2_TO_REDC_N_THRESHOLD 0 /* always */
+
+#define MU_DIV_QR_THRESHOLD 1499
+#define MU_DIVAPPR_Q_THRESHOLD 1499
+#define MUPI_DIV_QR_THRESHOLD 84
+#define MU_BDIV_QR_THRESHOLD 1334
+#define MU_BDIV_Q_THRESHOLD 1470
+
+#define POWM_SEC_TABLE 1,16,194,904,1167
+
+#define MATRIX22_STRASSEN_THRESHOLD 15
+#define HGCD_THRESHOLD 102
+#define HGCD_APPR_THRESHOLD 50
+#define HGCD_REDUCE_THRESHOLD 2681
+#define GCD_DC_THRESHOLD 416
+#define GCDEXT_DC_THRESHOLD 293
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 15
+#define GET_STR_PRECOMPUTE_THRESHOLD 26
+#define SET_STR_DC_THRESHOLD 248
+#define SET_STR_PRECOMPUTE_THRESHOLD 1160
+
+#define FAC_DSC_THRESHOLD 746
+#define FAC_ODD_THRESHOLD 44
diff --git a/gmp/mpn/x86_64/bobcat/mul_1.asm b/gmp/mpn/x86_64/bobcat/mul_1.asm
new file mode 100644
index 0000000000..cb58bef0b3
--- /dev/null
+++ b/gmp/mpn/x86_64/bobcat/mul_1.asm
@@ -0,0 +1,187 @@
+dnl AMD64 mpn_mul_1 optimised for AMD bobcat.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 4.5
+C AMD K10 4.5
+C AMD bd1 4.62
+C AMD bobcat 5
+C Intel P4 14
+C Intel core2 4.5
+C Intel NHM 4.23
+C Intel SBR 3.0
+C Intel atom 21
+C VIA nano 4.94
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+C Standard parameters
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n_param', `%rdx')
+define(`v0', `%rcx')
+define(`cy', `%r8')
+C Standard allocations
+define(`n', `%rbx')
+define(`w0', `%r8')
+define(`w1', `%r9')
+define(`w2', `%r10')
+define(`w3', `%r11')
+
+C DOS64 parameters
+IFDOS(` define(`rp', `%rcx') ') dnl
+IFDOS(` define(`up', `%rsi') ') dnl
+IFDOS(` define(`n_param', `%r8') ') dnl
+IFDOS(` define(`v0', `%r9') ') dnl
+IFDOS(` define(`cy', `64(%rsp)')') dnl
+C DOS64 allocations
+IFDOS(` define(`n', `%rbx') ') dnl
+IFDOS(` define(`w0', `%r8') ') dnl
+IFDOS(` define(`w1', `%rdi') ') dnl
+IFDOS(` define(`w2', `%r10') ') dnl
+IFDOS(` define(`w3', `%r11') ') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_1c)
+IFDOS(` push %rsi ')
+IFDOS(` push %rdi ')
+IFDOS(` mov %rdx, %rsi ')
+ mov cy, w2
+ jmp L(com)
+EPILOGUE()
+
+PROLOGUE(mpn_mul_1)
+IFDOS(` push %rsi ')
+IFDOS(` push %rdi ')
+IFDOS(` mov %rdx, %rsi ')
+ xor w2, w2
+L(com): push %rbx
+ mov (up), %rax
+
+ lea -16(rp,n_param,8), rp
+ lea -16(up,n_param,8), up
+
+ mov n_param, n
+ and $3, R32(n_param)
+ jz L(b0)
+ cmp $2, R32(n_param)
+ ja L(b3)
+ jz L(b2)
+
+L(b1): mul v0
+ cmp $1, n
+ jz L(n1)
+ neg n
+ add $3, n
+ add %rax, w2
+ mov %rdx, w3
+ jmp L(L1)
+L(n1): add %rax, w2
+ mov %rdx, %rax
+ mov w2, 8(rp)
+ adc $0, %rax
+ pop %rbx
+IFDOS(` pop %rdi ')
+IFDOS(` pop %rsi ')
+ ret
+
+L(b3): mul v0
+ neg n
+ inc n
+ add %rax, w2
+ mov %rdx, w3
+ jmp L(L3)
+
+L(b0): mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ neg n
+ add $2, n
+ add w2, w0
+ jmp L(L0)
+
+L(b2): mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ neg n
+ add w2, w0
+ jmp L(L2)
+
+ ALIGN(16)
+L(top): mov w0, -16(rp,n,8)
+ add w1, w2
+L(L1): adc $0, w3
+ mov 0(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, -8(rp,n,8)
+ add w3, w0
+L(L0): adc $0, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ mov w0, 0(rp,n,8)
+ add w1, w2
+L(L3): adc $0, w3
+ mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, 8(rp,n,8)
+ add w3, w0
+L(L2): adc $0, w1
+ mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(top)
+
+L(end): mov w0, (rp)
+ add w1, w2
+ adc $0, w3
+ mov w2, 8(rp)
+ mov w3, %rax
+
+ pop %rbx
+IFDOS(` pop %rdi ')
+IFDOS(` pop %rsi ')
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bobcat/mul_basecase.asm b/gmp/mpn/x86_64/bobcat/mul_basecase.asm
new file mode 100644
index 0000000000..e7d46bfcff
--- /dev/null
+++ b/gmp/mpn/x86_64/bobcat/mul_basecase.asm
@@ -0,0 +1,486 @@
+dnl AMD64 mpn_mul_basecase optimised for AMD bobcat.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 4.5
+C AMD K10 4.5
+C AMD bd1 4.75
+C AMD bobcat 5
+C Intel P4 17.7
+C Intel core2 5.5
+C Intel NHM 5.43
+C Intel SBR 3.92
+C Intel atom 23
+C VIA nano 5.63
+
+C This mul_basecase is based on mul_1 and addmul_1, since these both run at the
+C multiply insn bandwidth, without any apparent loop branch exit pipeline
+C replays experienced on K8. The structure is unusual: it falls into mul_1 in
+C the same way for all n, then it splits into 4 different wind-down blocks and
+C 4 separate addmul_1 loops.
+C
+C We have not tried using the same addmul_1 loops with a switch into feed-in
+C code, as we do in other basecase implementations. Doing that could save
+C substantial code volume, but would also probably add some overhead.
+
+C TODO
+C * Tune un < 3 code.
+C * Fix slowdown for un=vn=3 (67->71) compared to default code.
+C * This is 1263 bytes, compared to 1099 bytes for default code. Consider
+C combining addmul loops like that code. Tolerable slowdown?
+C * Lots of space could be saved by replacing the "switch" code by gradual
+C jumps out from mul_1 winddown code, perhaps with no added overhead.
+C * Are the ALIGN(16) really necessary? They add about 25 bytes of padding.
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+C Standard parameters
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param', `%rdx')
+define(`vp', `%rcx')
+define(`vn', `%r8')
+C Standard allocations
+define(`un', `%rbx')
+define(`w0', `%r10')
+define(`w1', `%r11')
+define(`w2', `%r12')
+define(`w3', `%r13')
+define(`n', `%rbp')
+define(`v0', `%r9')
+
+C Temp macro for allowing control over indexing.
+C Define to return $1 for more conservative ptr handling.
+define(`X',`$2')
+
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_basecase)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+
+ mov (up), %rax
+ mov (vp), v0
+
+ cmp $2, un_param
+ ja L(ge3)
+ jz L(u2)
+
+ mul v0 C u0 x v0
+ mov %rax, (rp)
+ mov %rdx, 8(rp)
+ FUNC_EXIT()
+ ret
+
+L(u2): mul v0 C u0 x v0
+ mov %rax, (rp)
+ mov 8(up), %rax
+ mov %rdx, w0
+ mul v0
+ add %rax, w0
+ mov %rdx, w1
+ adc $0, w1
+ cmp $1, R32(vn)
+ jnz L(u2v2)
+ mov w0, 8(rp)
+ mov w1, 16(rp)
+ FUNC_EXIT()
+ ret
+
+L(u2v2):mov 8(vp), v0
+ mov (up), %rax
+ mul v0
+ add %rax, w0
+ mov w0, 8(rp)
+ mov %rdx, %r8 C CAUTION: r8 realloc
+ adc $0, %r8
+ mov 8(up), %rax
+ mul v0
+ add w1, %r8
+ adc $0, %rdx
+ add %r8, %rax
+ adc $0, %rdx
+ mov %rax, 16(rp)
+ mov %rdx, 24(rp)
+ FUNC_EXIT()
+ ret
+
+
+L(ge3): push %rbx
+ push %rbp
+ push %r12
+ push %r13
+
+ lea 8(vp), vp
+
+ lea -24(rp,un_param,8), rp
+ lea -24(up,un_param,8), up
+ xor R32(un), R32(un)
+ mov $2, R32(n)
+ sub un_param, un
+ sub un_param, n
+
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ jmp L(L3)
+
+ ALIGN(16)
+L(top): mov w0, -16(rp,n,8)
+ add w1, w2
+ adc $0, w3
+ mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, -8(rp,n,8)
+ add w3, w0
+ adc $0, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ mov w0, (rp,n,8)
+ add w1, w2
+ adc $0, w3
+L(L3): mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, 8(rp,n,8)
+ add w3, w0
+ adc $0, w1
+ mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(top)
+
+ mov w0, -16(rp,n,8)
+ add w1, w2
+ adc $0, w3
+
+C Switch on n into right addmul_l loop
+ test n, n
+ jz L(r2)
+ cmp $2, R32(n)
+ ja L(r3)
+ jz L(r0)
+ jmp L(r1)
+
+
+L(r3): mov w2, X(-8(rp,n,8),16(rp))
+ mov w3, X((rp,n,8),24(rp))
+ add $2, un
+
+C outer loop(3)
+L(to3): dec vn
+ jz L(ret)
+ mov (vp), v0
+ mov 8(up,un,8), %rax
+ lea 8(vp), vp
+ lea 8(rp), rp
+ mov un, n
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ jmp L(al3)
+
+ ALIGN(16)
+L(ta3): add w0, -16(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (rp,n,8)
+ adc w1, w2
+ adc $0, w3
+L(al3): mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(ta3)
+
+ add w0, X(-16(rp,n,8),8(rp))
+ adc w1, w2
+ adc $0, w3
+ add w2, X(-8(rp,n,8),16(rp))
+ adc $0, w3
+ mov w3, X((rp,n,8),24(rp))
+ jmp L(to3)
+
+
+L(r2): mov X(0(up,n,8),(up)), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, X(-8(rp,n,8),-8(rp))
+ add w3, w0
+ adc $0, w1
+ mov X(8(up,n,8),8(up)), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ mov w0, X((rp,n,8),(rp))
+ add w1, w2
+ adc $0, w3
+ mov X(16(up,n,8),16(up)), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, X(8(rp,n,8),8(rp))
+ add w3, w0
+ adc $0, w1
+ mov w0, X(16(rp,n,8),16(rp))
+ adc $0, w3
+ mov w1, X(24(rp,n,8),24(rp))
+ inc un
+
+C outer loop(2)
+L(to2): dec vn
+ jz L(ret)
+ mov (vp), v0
+ mov 16(up,un,8), %rax
+ lea 8(vp), vp
+ lea 8(rp), rp
+ mov un, n
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ jmp L(al2)
+
+ ALIGN(16)
+L(ta2): add w0, -16(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+L(al2): mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(ta2)
+
+ add w0, X(-16(rp,n,8),8(rp))
+ adc w1, w2
+ adc $0, w3
+ add w2, X(-8(rp,n,8),16(rp))
+ adc $0, w3
+ mov w3, X((rp,n,8),24(rp))
+ jmp L(to2)
+
+
+L(r1): mov X(0(up,n,8),8(up)), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, X(-8(rp,n,8),(rp))
+ add w3, w0
+ adc $0, w1
+ mov X(8(up,n,8),16(up)), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ mov w0, X((rp,n,8),8(rp))
+ add w1, w2
+ adc $0, w3
+ mov w2, X(8(rp,n,8),16(rp))
+ mov w3, X(16(rp,n,8),24(rp))
+ add $4, un
+
+C outer loop(1)
+L(to1): dec vn
+ jz L(ret)
+ mov (vp), v0
+ mov -8(up,un,8), %rax
+ lea 8(vp), vp
+ lea 8(rp), rp
+ mov un, n
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ jmp L(al1)
+
+ ALIGN(16)
+L(ta1): add w0, -16(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+L(al1): mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(ta1)
+
+ add w0, X(-16(rp,n,8),8(rp))
+ adc w1, w2
+ adc $0, w3
+ add w2, X(-8(rp,n,8),16(rp))
+ adc $0, w3
+ mov w3, X((rp,n,8),24(rp))
+ jmp L(to1)
+
+
+L(r0): mov X((up,n,8),16(up)), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, X(-8(rp,n,8),8(rp))
+ add w3, w0
+ adc $0, w1
+ mov w0, X((rp,n,8),16(rp))
+ mov w1, X(8(rp,n,8),24(rp))
+ add $3, un
+
+C outer loop(0)
+L(to0): dec vn
+ jz L(ret)
+ mov (vp), v0
+ mov (up,un,8), %rax
+ lea 8(vp), vp
+ lea 8(rp), rp
+ mov un, n
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ jmp L(al0)
+
+ ALIGN(16)
+L(ta0): add w0, -16(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+L(al0): mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(ta0)
+
+ add w0, X(-16(rp,n,8),8(rp))
+ adc w1, w2
+ adc $0, w3
+ add w2, X(-8(rp,n,8),16(rp))
+ adc $0, w3
+ mov w3, X((rp,n,8),24(rp))
+ jmp L(to0)
+
+
+L(ret): pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/bobcat/redc_1.asm b/gmp/mpn/x86_64/bobcat/redc_1.asm
new file mode 100644
index 0000000000..c3798021f7
--- /dev/null
+++ b/gmp/mpn/x86_64/bobcat/redc_1.asm
@@ -0,0 +1,502 @@
+dnl X86-64 mpn_redc_1 optimised for AMD bobcat.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C AMD bull ?
+C AMD pile ?
+C AMD steam ?
+C AMD bobcat 5.0
+C AMD jaguar ?
+C Intel P4 ?
+C Intel core ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel IBR ?
+C Intel HWL ?
+C Intel BWL ?
+C Intel atom ?
+C VIA nano ?
+
+C TODO
+C * Micro-optimise, none performed thus far.
+C * Consider inlining mpn_add_n.
+C * Single basecases out before the pushes.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`mp_param', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`u0inv', `%r8') C stack
+
+define(`i', `%r14')
+define(`j', `%r15')
+define(`mp', `%r12')
+define(`q0', `%r13')
+define(`w0', `%rbp')
+define(`w1', `%r9')
+define(`w2', `%r10')
+define(`w3', `%r11')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+define(`ALIGNx', `ALIGN(16)')
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_redc_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov (up), q0
+ mov n, j C outer loop induction var
+ lea (mp_param,n,8), mp
+ lea (up,n,8), up
+ neg n
+ imul u0inv, q0 C first iteration q0
+
+ test $1, R8(n)
+ jz L(bx0)
+
+L(bx1): test $2, R8(n)
+ jz L(b3)
+
+L(b1): cmp $-1, R32(n)
+ jz L(n1)
+
+L(otp1):lea 1(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ mov 8(mp,n,8), %rax
+ mul q0
+ mov %rax, %rbx
+ mov %rdx, w1
+ add (up,n,8), w2
+ adc w3, %rbx
+ adc $0, w1
+ mov 16(mp,n,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add 8(up,n,8), %rbx
+ mov %rbx, 8(up,n,8)
+ adc w1, w2
+ adc $0, w3
+ imul u0inv, %rbx C next q limb
+ jmp L(e1)
+
+ ALIGNx
+L(tp1): add w0, -16(up,i,8)
+ adc w1, w2
+ adc $0, w3
+ mov (mp,i,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(up,i,8)
+ adc w3, w0
+ adc $0, w1
+ mov 8(mp,i,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (up,i,8)
+ adc w1, w2
+ adc $0, w3
+L(e1): mov 16(mp,i,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(up,i,8)
+ adc w3, w0
+ adc $0, w1
+ mov 24(mp,i,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, i
+ js L(tp1)
+
+L(ed1): add w0, I(-16(up),-16(up,i,8))
+ adc w1, w2
+ adc $0, w3
+ add w2, I(-8(up),-8(up,i,8))
+ adc $0, w3
+ mov w3, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp1)
+ jmp L(cj)
+
+L(b3): cmp $-3, R32(n)
+ jz L(n3)
+
+L(otp3):lea 3(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ mov 8(mp,n,8), %rax
+ mul q0
+ mov %rax, %rbx
+ mov %rdx, w1
+ add (up,n,8), w2
+ adc w3, %rbx
+ adc $0, w1
+ mov 16(mp,n,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add 8(up,n,8), %rbx
+ mov %rbx, 8(up,n,8)
+ adc w1, w2
+ adc $0, w3
+ imul u0inv, %rbx C next q limb
+ jmp L(e3)
+
+ ALIGNx
+L(tp3): add w0, -16(up,i,8)
+ adc w1, w2
+ adc $0, w3
+L(e3): mov (mp,i,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(up,i,8)
+ adc w3, w0
+ adc $0, w1
+ mov 8(mp,i,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (up,i,8)
+ adc w1, w2
+ adc $0, w3
+ mov 16(mp,i,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(up,i,8)
+ adc w3, w0
+ adc $0, w1
+ mov 24(mp,i,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, i
+ js L(tp3)
+
+L(ed3): add w0, I(-16(up),-16(up,i,8))
+ adc w1, w2
+ adc $0, w3
+ add w2, I(-8(up),-8(up,i,8))
+ adc $0, w3
+ mov w3, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp3)
+C jmp L(cj)
+
+L(cj):
+IFSTD(` lea (up,n,8), up C param 2: up
+ lea (up,n,8), %rdx C param 3: up - n
+ neg R32(n) ') C param 4: n
+
+IFDOS(` lea (up,n,8), %rdx C param 2: up
+ lea (%rdx,n,8), %r8 C param 3: up - n
+ neg R32(n)
+ mov n, %r9 C param 4: n
+ mov rp, %rcx ') C param 1: rp
+
+ CALL( mpn_add_n)
+
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(bx0): test $2, R8(n)
+ jnz L(b2)
+
+L(b0):
+L(otp0):lea (n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ mov 8(mp,n,8), %rax
+ mul q0
+ mov %rax, %rbx
+ mov %rdx, w3
+ add (up,n,8), w0
+ adc w1, %rbx
+ adc $0, w3
+ mov 16(mp,n,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add 8(up,n,8), %rbx
+ mov %rbx, 8(up,n,8)
+ adc w3, w0
+ adc $0, w1
+ imul u0inv, %rbx C next q limb
+ jmp L(e0)
+
+ ALIGNx
+L(tp0): add w0, -16(up,i,8)
+ adc w1, w2
+ adc $0, w3
+ mov (mp,i,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(up,i,8)
+ adc w3, w0
+ adc $0, w1
+ mov 8(mp,i,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (up,i,8)
+ adc w1, w2
+ adc $0, w3
+ mov 16(mp,i,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(up,i,8)
+ adc w3, w0
+ adc $0, w1
+L(e0): mov 24(mp,i,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, i
+ js L(tp0)
+
+L(ed0): add w0, I(-16(up),-16(up,i,8))
+ adc w1, w2
+ adc $0, w3
+ add w2, I(-8(up),-8(up,i,8))
+ adc $0, w3
+ mov w3, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp0)
+ jmp L(cj)
+
+L(b2): cmp $-2, R32(n)
+ jz L(n2)
+
+L(otp2):lea 2(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ mov 8(mp,n,8), %rax
+ mul q0
+ mov %rax, %rbx
+ mov %rdx, w3
+ add (up,n,8), w0
+ adc w1, %rbx
+ adc $0, w3
+ mov 16(mp,n,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add 8(up,n,8), %rbx
+ mov %rbx, 8(up,n,8)
+ adc w3, w0
+ adc $0, w1
+ imul u0inv, %rbx C next q limb
+ jmp L(e2)
+
+ ALIGNx
+L(tp2): add w0, -16(up,i,8)
+ adc w1, w2
+ adc $0, w3
+ mov (mp,i,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(up,i,8)
+ adc w3, w0
+ adc $0, w1
+L(e2): mov 8(mp,i,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (up,i,8)
+ adc w1, w2
+ adc $0, w3
+ mov 16(mp,i,8), %rax
+ mul q0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(up,i,8)
+ adc w3, w0
+ adc $0, w1
+ mov 24(mp,i,8), %rax
+ mul q0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, i
+ js L(tp2)
+
+L(ed2): add w0, I(-16(up),-16(up,i,8))
+ adc w1, w2
+ adc $0, w3
+ add w2, I(-8(up),-8(up,i,8))
+ adc $0, w3
+ mov w3, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp2)
+ jmp L(cj)
+
+L(n1): mov (mp_param), %rax
+ mul q0
+ add -8(up), %rax
+ adc (up), %rdx
+ mov %rdx, (rp)
+ mov $0, R32(%rax)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+L(n2): mov (mp_param), %rax
+ mov -16(up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ mov -8(up), %r10
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, q0
+ imul u0inv, q0 C next q0
+ mov -16(mp), %rax
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ mov (up), %r14
+ mul q0
+ add %rax, %r14
+ adc $0, %rdx
+ add %r9, %r14
+ adc $0, %rdx
+ xor R32(%rax), R32(%rax)
+ add %r11, %r14
+ adc 8(up), %rdx
+ mov %r14, (rp)
+ mov %rdx, 8(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+ ALIGNx
+L(n3): mov -24(mp), %rax
+ mov -24(up), %r10
+ mul q0
+ add %rax, %r10
+ mov -16(mp), %rax
+ mov %rdx, %r11
+ adc $0, %r11
+ mov -16(up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ add %r11, %rbp
+ mov -8(up), %r10
+ adc $0, %r9
+ mul q0
+ mov %rbp, q0
+ imul u0inv, q0 C next q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ mov %rbp, -16(up)
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, -8(up)
+ mov %r11, -24(up) C up[0]
+ lea 8(up), up C up++
+ dec j
+ jnz L(n3)
+
+ mov -48(up), %rdx
+ mov -40(up), %rbx
+ xor R32(%rax), R32(%rax)
+ add %rbp, %rdx
+ adc %r10, %rbx
+ adc -8(up), %r11
+ mov %rdx, (rp)
+ mov %rbx, 8(rp)
+ mov %r11, 16(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/bobcat/sqr_basecase.asm b/gmp/mpn/x86_64/bobcat/sqr_basecase.asm
new file mode 100644
index 0000000000..0e417a1ebe
--- /dev/null
+++ b/gmp/mpn/x86_64/bobcat/sqr_basecase.asm
@@ -0,0 +1,565 @@
+dnl AMD64 mpn_sqr_basecase optimised for AMD bobcat.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 4.5
+C AMD K10 4.5
+C AMD bd1 4.75
+C AMD bobcat 5
+C Intel P4 17.7
+C Intel core2 5.5
+C Intel NHM 5.43
+C Intel SBR 3.92
+C Intel atom 23
+C VIA nano 5.63
+
+C This sqr_basecase is based on mul_1 and addmul_1, since these both run at the
+C multiply insn bandwidth, without any apparent loop branch exit pipeline
+C replays experienced on K8. The structure is unusual: it falls into mul_1 in
+C the same way for all n, then it splits into 4 different wind-down blocks and
+C 4 separate addmul_1 loops.
+C
+C We have not tried using the same addmul_1 loops with a switch into feed-in
+C code, as we do in other basecase implementations. Doing that could save
+C substantial code volume, but would also probably add some overhead.
+
+C TODO
+C * Tune un < 4 code.
+C * Perhaps implement a larger final corner (it is now 2 x 1).
+C * Lots of space could be saved by replacing the "switch" code by gradual
+C jumps out from mul_1 winddown code, perhaps with no added overhead.
+C * Are the ALIGN(16) really necessary? They add about 25 bytes of padding.
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+C Standard parameters
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param', `%rdx')
+C Standard allocations
+define(`un', `%rbx')
+define(`w0', `%r8')
+define(`w1', `%r9')
+define(`w2', `%r10')
+define(`w3', `%r11')
+define(`n', `%rbp')
+define(`v0', `%rcx')
+
+C Temp macro for allowing control over indexing.
+C Define to return $1 for more conservative ptr handling.
+define(`X',`$2')
+dnl define(`X',`$1')
+
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_sqr_basecase)
+ FUNC_ENTRY(3)
+
+ mov (up), %rax
+
+ cmp $2, R32(un_param)
+ jae L(ge2)
+
+ mul %rax
+ mov %rax, (rp)
+ mov %rdx, 8(rp)
+ FUNC_EXIT()
+ ret
+
+L(ge2): mov (up), v0
+ jnz L(g2)
+
+ mul %rax
+ mov %rax, (rp)
+ mov 8(up), %rax
+ mov %rdx, w0
+ mul v0
+ add %rax, w0
+ mov %rdx, w1
+ adc $0, w1
+ mov 8(up), v0
+ mov (up), %rax
+ mul v0
+ add %rax, w0
+ mov w0, 8(rp)
+ mov %rdx, w0 C CAUTION: r8 realloc
+ adc $0, w0
+ mov 8(up), %rax
+ mul v0
+ add w1, w0
+ adc $0, %rdx
+ add w0, %rax
+ adc $0, %rdx
+ mov %rax, 16(rp)
+ mov %rdx, 24(rp)
+ FUNC_EXIT()
+ ret
+
+L(g2): cmp $3, R32(un_param)
+ ja L(g3)
+ mul %rax
+ mov %rax, (rp)
+ mov %rdx, 8(rp)
+ mov 8(up), %rax
+ mul %rax
+ mov %rax, 16(rp)
+ mov %rdx, 24(rp)
+ mov 16(up), %rax
+ mul %rax
+ mov %rax, 32(rp)
+ mov %rdx, 40(rp)
+
+ mov (up), v0
+ mov 8(up), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov 16(up), %rax
+ mul v0
+ xor R32(w2), R32(w2)
+ add %rax, w1
+ adc %rdx, w2
+
+ mov 8(up), v0
+ mov 16(up), %rax
+ mul v0
+ xor R32(w3), R32(w3)
+ add %rax, w2
+ adc %rdx, w3
+ add w0, w0
+ adc w1, w1
+ adc w2, w2
+ adc w3, w3
+ mov $0, R32(v0)
+ adc v0, v0
+ add w0, 8(rp)
+ adc w1, 16(rp)
+ adc w2, 24(rp)
+ adc w3, 32(rp)
+ adc v0, 40(rp)
+ FUNC_EXIT()
+ ret
+
+L(g3): push %rbx
+ push %rbp
+
+ mov 8(up), %rax
+ lea -24(rp,un_param,8), rp
+ lea -24(up,un_param,8), up
+ neg un_param
+ push un_param C for sqr_diag_addlsh1
+ lea (un_param), un
+ lea 3(un_param), n
+
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ jmp L(L3)
+
+ ALIGN(16)
+L(top): mov w0, -16(rp,n,8)
+ add w1, w2
+ adc $0, w3
+ mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, -8(rp,n,8)
+ add w3, w0
+ adc $0, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ mov w0, (rp,n,8)
+ add w1, w2
+ adc $0, w3
+L(L3): mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, 8(rp,n,8)
+ add w3, w0
+ adc $0, w1
+ mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(top)
+
+ mov w0, -16(rp,n,8)
+ add w1, w2
+ adc $0, w3
+
+ test n, n
+ jz L(r2)
+ cmp $2, R32(n)
+ ja L(r3)
+ jz L(r0)
+
+
+L(r1): mov X((up,n,8),8(up)), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, X(-8(rp,n,8),(rp))
+ add w3, w0
+ adc $0, w1
+ mov X(8(up,n,8),16(up)), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ mov w0, X((rp,n,8),8(rp))
+ add w1, w2
+ adc $0, w3
+ mov w2, X(8(rp,n,8),16(rp))
+ mov w3, X(16(rp,n,8),24(rp))
+ add $5, un
+ jmp L(to0)
+
+L(r2): mov X((up,n,8),(up)), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, X(-8(rp,n,8),-8(rp))
+ add w3, w0
+ adc $0, w1
+ mov X(8(up,n,8),8(up)), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ mov w0, X((rp,n,8),(rp))
+ add w1, w2
+ adc $0, w3
+ mov X(16(up,n,8),16(up)), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, X(8(rp,n,8),8(rp))
+ add w3, w0
+ adc $0, w1
+ mov w0, X(16(rp,n,8),16(rp))
+ adc $0, w3
+ mov w1, X(24(rp,n,8),24(rp))
+ add $6, un
+ jmp L(to1)
+
+L(r3): mov w2, X(-8(rp,n,8),16(rp))
+ mov w3, X((rp,n,8),24(rp))
+ add $3, un
+ jmp L(to2)
+
+L(r0): mov X((up,n,8),16(up)), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov w2, X(-8(rp,n,8),8(rp))
+ add w3, w0
+ adc $0, w1
+ mov w0, X((rp,n,8),16(rp))
+ mov w1, X(8(rp,n,8),24(rp))
+ add $4, un
+C jmp L(to3)
+C fall through into main loop
+
+
+L(outer):
+ mov un, n
+ mov (up,un,8), v0
+ mov 8(up,un,8), %rax
+ lea 8(rp), rp
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ jmp L(al3)
+
+ ALIGN(16)
+L(ta3): add w0, -16(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (rp,n,8)
+ adc w1, w2
+ adc $0, w3
+L(al3): mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(ta3)
+
+ add w0, X(-16(rp,n,8),8(rp))
+ adc w1, w2
+ adc $0, w3
+ add w2, X(-8(rp,n,8),16(rp))
+ adc $0, w3
+ mov w3, X((rp,n,8),24(rp))
+
+
+L(to2): mov un, n
+ cmp $-4, R32(un)
+ jnc L(end)
+ add $4, un
+ mov 8(up,n,8), v0
+ mov 16(up,n,8), %rax
+ lea 8(rp), rp
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ jmp L(al2)
+
+ ALIGN(16)
+L(ta2): add w0, -16(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+L(al2): mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(ta2)
+
+ add w0, X(-16(rp,n,8),8(rp))
+ adc w1, w2
+ adc $0, w3
+ add w2, X(-8(rp,n,8),16(rp))
+ adc $0, w3
+ mov w3, X((rp,n,8),24(rp))
+
+
+L(to1): mov un, n
+ mov -16(up,un,8), v0
+ mov -8(up,un,8), %rax
+ lea 8(rp), rp
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ jmp L(al1)
+
+ ALIGN(16)
+L(ta1): add w0, -16(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+L(al1): mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(ta1)
+
+ add w0, X(-16(rp,n,8),8(rp))
+ adc w1, w2
+ adc $0, w3
+ add w2, X(-8(rp,n,8),16(rp))
+ adc $0, w3
+ mov w3, X((rp,n,8),24(rp))
+
+
+L(to0): mov un, n
+ mov -8(up,un,8), v0
+ mov (up,un,8), %rax
+ lea 8(rp), rp
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ jmp L(al0)
+
+ ALIGN(16)
+L(ta0): add w0, -16(rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov (up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, -8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+L(al0): mov 8(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, (rp,n,8)
+ adc w1, w2
+ adc $0, w3
+ mov 16(up,n,8), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ add w2, 8(rp,n,8)
+ adc w3, w0
+ adc $0, w1
+ mov 24(up,n,8), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add $4, n
+ js L(ta0)
+
+ add w0, X(-16(rp,n,8),8(rp))
+ adc w1, w2
+ adc $0, w3
+ add w2, X(-8(rp,n,8),16(rp))
+ adc $0, w3
+ mov w3, X((rp,n,8),24(rp))
+ jmp L(outer)
+
+
+L(end): mov X(8(up,un,8),(up)), v0
+ mov X(16(up,un,8),8(up)), %rax
+ mul v0
+ mov %rax, w0
+ mov %rdx, w1
+ mov X(24(up,un,8),16(up)), %rax
+ mul v0
+ mov %rax, w2
+ mov %rdx, w3
+ add w0, X(24(rp,un,8),16(rp))
+ adc w1, w2
+ adc $0, w3
+ add w2, X(32(rp,un,8),24(rp))
+ adc $0, w3
+ mov X(16(up,un,8),8(up)), v0
+ mov X(24(up,un,8),16(up)), %rax
+ mul v0
+ add %rax, w3
+ mov w3, X(40(rp,un,8),32(rp))
+ adc $0, %rdx
+ mov %rdx, X(48(rp,un,8),40(rp))
+
+
+C sqr_diag_addlsh1
+
+ lea 16(up), up
+ lea 40(rp), rp
+ pop n
+ lea 2(n,n), n
+
+ mov (up,n,4), %rax
+ mul %rax
+ xor R32(w2), R32(w2)
+
+ mov 8(rp,n,8), w0
+ mov %rax, (rp,n,8)
+ jmp L(lm)
+
+ ALIGN(8)
+L(tsd): add %rbx, w0
+ adc %rax, w1
+ mov w0, -8(rp,n,8)
+ mov 8(rp,n,8), w0
+ mov w1, (rp,n,8)
+L(lm): mov 16(rp,n,8), w1
+ adc w0, w0
+ adc w1, w1
+ lea (%rdx,w2), %rbx
+ mov 8(up,n,4), %rax
+ setc R8(w2)
+ mul %rax
+ add $2, n
+ js L(tsd)
+
+L(esd): add %rbx, w0
+ adc %rax, w1
+ mov w0, X(-8(rp,n,8),-8(rp))
+ mov w1, X((rp,n,8),(rp))
+ adc w2, %rdx
+ mov %rdx, X(8(rp,n,8),8(rp))
+
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/cnd_aors_n.asm b/gmp/mpn/x86_64/cnd_aors_n.asm
new file mode 100644
index 0000000000..13a2ab3be9
--- /dev/null
+++ b/gmp/mpn/x86_64/cnd_aors_n.asm
@@ -0,0 +1,183 @@
+dnl AMD64 mpn_cnd_add_n, mpn_cnd_sub_n
+
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2
+C AMD K10 2
+C AMD bd1 2.32
+C AMD bobcat 3
+C Intel P4 13
+C Intel core2 2.9
+C Intel NHM 2.8
+C Intel SBR 2.4
+C Intel atom 5.33
+C VIA nano 3
+
+C NOTES
+C * It might seem natural to use the cmov insn here, but since this function
+C is supposed to have the exact same execution pattern for cnd true and
+C false, and since cmov's documentation is not clear about whether it
+C actually reads both source operands and writes the register for a false
+C condition, we cannot use it.
+C * Two cases could be optimised: (1) cnd_add_n could use ADCSBB-from-memory
+C to save one insn/limb, and (2) when up=rp cnd_add_n and cnd_sub_n could use
+C ADCSBB-to-memory, again saving 1 insn/limb.
+C * This runs optimally at decoder bandwidth on K10. It has not been tuned
+C for any other processor.
+
+C INPUT PARAMETERS
+define(`cnd', `%rdi') dnl rcx
+define(`rp', `%rsi') dnl rdx
+define(`up', `%rdx') dnl r8
+define(`vp', `%rcx') dnl r9
+define(`n', `%r8') dnl rsp+40
+
+ifdef(`OPERATION_cnd_add_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func, mpn_cnd_add_n)')
+ifdef(`OPERATION_cnd_sub_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func, mpn_cnd_sub_n)')
+
+MULFUNC_PROLOGUE(mpn_cnd_add_n mpn_cnd_sub_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), R32(%r8)')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+
+ neg cnd
+ sbb cnd, cnd C make cnd mask
+
+ lea (vp,n,8), vp
+ lea (up,n,8), up
+ lea (rp,n,8), rp
+
+ mov R32(n), R32(%rax)
+ neg n
+ and $3, R32(%rax)
+ jz L(top) C carry-save reg rax = 0 in this arc
+ cmp $2, R32(%rax)
+ jc L(b1)
+ jz L(b2)
+
+L(b3): mov (vp,n,8), %r12
+ mov 8(vp,n,8), %r13
+ mov 16(vp,n,8), %r14
+ and cnd, %r12
+ mov (up,n,8), %r10
+ and cnd, %r13
+ mov 8(up,n,8), %rbx
+ and cnd, %r14
+ mov 16(up,n,8), %rbp
+ ADDSUB %r12, %r10
+ mov %r10, (rp,n,8)
+ ADCSBB %r13, %rbx
+ mov %rbx, 8(rp,n,8)
+ ADCSBB %r14, %rbp
+ mov %rbp, 16(rp,n,8)
+ sbb R32(%rax), R32(%rax) C save carry
+ add $3, n
+ js L(top)
+ jmp L(end)
+
+L(b2): mov (vp,n,8), %r12
+ mov 8(vp,n,8), %r13
+ mov (up,n,8), %r10
+ and cnd, %r12
+ mov 8(up,n,8), %rbx
+ and cnd, %r13
+ ADDSUB %r12, %r10
+ mov %r10, (rp,n,8)
+ ADCSBB %r13, %rbx
+ mov %rbx, 8(rp,n,8)
+ sbb R32(%rax), R32(%rax) C save carry
+ add $2, n
+ js L(top)
+ jmp L(end)
+
+L(b1): mov (vp,n,8), %r12
+ mov (up,n,8), %r10
+ and cnd, %r12
+ ADDSUB %r12, %r10
+ mov %r10, (rp,n,8)
+ sbb R32(%rax), R32(%rax) C save carry
+ add $1, n
+ jns L(end)
+
+ ALIGN(16)
+L(top): mov (vp,n,8), %r12
+ mov 8(vp,n,8), %r13
+ mov 16(vp,n,8), %r14
+ mov 24(vp,n,8), %r11
+ and cnd, %r12
+ mov (up,n,8), %r10
+ and cnd, %r13
+ mov 8(up,n,8), %rbx
+ and cnd, %r14
+ mov 16(up,n,8), %rbp
+ and cnd, %r11
+ mov 24(up,n,8), %r9
+ add R32(%rax), R32(%rax) C restore carry
+ ADCSBB %r12, %r10
+ mov %r10, (rp,n,8)
+ ADCSBB %r13, %rbx
+ mov %rbx, 8(rp,n,8)
+ ADCSBB %r14, %rbp
+ mov %rbp, 16(rp,n,8)
+ ADCSBB %r11, %r9
+ mov %r9, 24(rp,n,8)
+ sbb R32(%rax), R32(%rax) C save carry
+ add $4, n
+ js L(top)
+
+L(end): neg R32(%rax)
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/com.asm b/gmp/mpn/x86_64/com.asm
new file mode 100644
index 0000000000..006acaf648
--- /dev/null
+++ b/gmp/mpn/x86_64/com.asm
@@ -0,0 +1,95 @@
+dnl AMD64 mpn_com.
+
+dnl Copyright 2004-2006, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 1.25
+C AMD K10 1.25
+C Intel P4 2.78
+C Intel core2 1.1
+C Intel corei 1.5
+C Intel atom ?
+C VIA nano 2
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`n',`%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_com)
+ FUNC_ENTRY(3)
+ movq (up), %r8
+ movl R32(%rdx), R32(%rax)
+ leaq (up,n,8), up
+ leaq (rp,n,8), rp
+ negq n
+ andl $3, R32(%rax)
+ je L(b00)
+ cmpl $2, R32(%rax)
+ jc L(b01)
+ je L(b10)
+
+L(b11): notq %r8
+ movq %r8, (rp,n,8)
+ decq n
+ jmp L(e11)
+L(b10): addq $-2, n
+ jmp L(e10)
+ .byte 0x90,0x90,0x90,0x90,0x90,0x90
+L(b01): notq %r8
+ movq %r8, (rp,n,8)
+ incq n
+ jz L(ret)
+
+L(oop): movq (up,n,8), %r8
+L(b00): movq 8(up,n,8), %r9
+ notq %r8
+ notq %r9
+ movq %r8, (rp,n,8)
+ movq %r9, 8(rp,n,8)
+L(e11): movq 16(up,n,8), %r8
+L(e10): movq 24(up,n,8), %r9
+ notq %r8
+ notq %r9
+ movq %r8, 16(rp,n,8)
+ movq %r9, 24(rp,n,8)
+ addq $4, n
+ jnc L(oop)
+L(ret): FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/copyd.asm b/gmp/mpn/x86_64/copyd.asm
new file mode 100644
index 0000000000..a5e6e595e7
--- /dev/null
+++ b/gmp/mpn/x86_64/copyd.asm
@@ -0,0 +1,93 @@
+dnl AMD64 mpn_copyd -- copy limb vector, decrementing.
+
+dnl Copyright 2003, 2005, 2007, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 1
+C AMD K10 1
+C AMD bd1 1.36
+C AMD bobcat 1.71
+C Intel P4 2-3
+C Intel core2 1
+C Intel NHM 1
+C Intel SBR 1
+C Intel atom 2
+C VIA nano 2
+
+
+IFSTD(`define(`rp',`%rdi')')
+IFSTD(`define(`up',`%rsi')')
+IFSTD(`define(`n', `%rdx')')
+
+IFDOS(`define(`rp',`%rcx')')
+IFDOS(`define(`up',`%rdx')')
+IFDOS(`define(`n', `%r8')')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_copyd)
+ lea -8(up,n,8), up
+ lea (rp,n,8), rp
+ sub $4, n
+ jc L(end)
+ nop
+
+L(top): mov (up), %rax
+ mov -8(up), %r9
+ lea -32(rp), rp
+ mov -16(up), %r10
+ mov -24(up), %r11
+ lea -32(up), up
+ mov %rax, 24(rp)
+ mov %r9, 16(rp)
+ sub $4, n
+ mov %r10, 8(rp)
+ mov %r11, (rp)
+ jnc L(top)
+
+L(end): shr R32(n)
+ jnc 1f
+ mov (up), %rax
+ mov %rax, -8(rp)
+ lea -8(rp), rp
+ lea -8(up), up
+1: shr R32(n)
+ jnc 1f
+ mov (up), %rax
+ mov -8(up), %r9
+ mov %rax, -8(rp)
+ mov %r9, -16(rp)
+1: ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/copyi.asm b/gmp/mpn/x86_64/copyi.asm
new file mode 100644
index 0000000000..bafce7a09e
--- /dev/null
+++ b/gmp/mpn/x86_64/copyi.asm
@@ -0,0 +1,92 @@
+dnl AMD64 mpn_copyi -- copy limb vector, incrementing.
+
+dnl Copyright 2003, 2005, 2007, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 1
+C AMD K10 1
+C AMD bd1 1.36
+C AMD bobcat 1.71
+C Intel P4 2-3
+C Intel core2 1
+C Intel NHM 1
+C Intel SBR 1
+C Intel atom 2
+C VIA nano 2
+
+
+IFSTD(`define(`rp',`%rdi')')
+IFSTD(`define(`up',`%rsi')')
+IFSTD(`define(`n', `%rdx')')
+
+IFDOS(`define(`rp',`%rcx')')
+IFDOS(`define(`up',`%rdx')')
+IFDOS(`define(`n', `%r8')')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+ .byte 0,0,0,0,0,0
+PROLOGUE(mpn_copyi)
+ lea -8(rp), rp
+ sub $4, n
+ jc L(end)
+
+L(top): mov (up), %rax
+ mov 8(up), %r9
+ lea 32(rp), rp
+ mov 16(up), %r10
+ mov 24(up), %r11
+ lea 32(up), up
+ mov %rax, -24(rp)
+ mov %r9, -16(rp)
+ sub $4, n
+ mov %r10, -8(rp)
+ mov %r11, (rp)
+ jnc L(top)
+
+L(end): shr R32(n)
+ jnc 1f
+ mov (up), %rax
+ mov %rax, 8(rp)
+ lea 8(rp), rp
+ lea 8(up), up
+1: shr R32(n)
+ jnc 1f
+ mov (up), %rax
+ mov 8(up), %r9
+ mov %rax, 8(rp)
+ mov %r9, 16(rp)
+1: ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/aorrlsh1_n.asm b/gmp/mpn/x86_64/core2/aorrlsh1_n.asm
new file mode 100644
index 0000000000..7066bb4372
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/aorrlsh1_n.asm
@@ -0,0 +1,53 @@
+dnl AMD64 mpn_addlsh1_n -- rp[] = up[] + (vp[] << 1)
+dnl AMD64 mpn_rsblsh1_n -- rp[] = (vp[] << 1) - up[]
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 1)
+define(RSH, 63)
+
+ifdef(`OPERATION_addlsh1_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func, mpn_addlsh1_n)')
+ifdef(`OPERATION_rsblsh1_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func, mpn_rsblsh1_n)')
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_rsblsh1_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+include_mpn(`x86_64/aorrlshC_n.asm')
diff --git a/gmp/mpn/x86_64/core2/aorrlsh2_n.asm b/gmp/mpn/x86_64/core2/aorrlsh2_n.asm
new file mode 100644
index 0000000000..5065120857
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/aorrlsh2_n.asm
@@ -0,0 +1,53 @@
+dnl AMD64 mpn_addlsh2_n -- rp[] = up[] + (vp[] << 2)
+dnl AMD64 mpn_rsblsh2_n -- rp[] = (vp[] << 2) - up[]
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 2)
+define(RSH, 62)
+
+ifdef(`OPERATION_addlsh2_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func, mpn_addlsh2_n)')
+ifdef(`OPERATION_rsblsh2_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func, mpn_rsblsh2_n)')
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_rsblsh2_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+include_mpn(`x86_64/aorrlshC_n.asm')
diff --git a/gmp/mpn/x86_64/core2/aorrlsh_n.asm b/gmp/mpn/x86_64/core2/aorrlsh_n.asm
new file mode 100644
index 0000000000..57abf31579
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/aorrlsh_n.asm
@@ -0,0 +1,38 @@
+dnl AMD64 mpn_addlsh_n and mpn_rsblsh_n. R = V2^k +- U.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_addlsh_n mpn_addlsh_nc mpn_rsblsh_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+include_mpn(`x86_64/coreinhm/aorrlsh_n.asm')
diff --git a/gmp/mpn/x86_64/core2/aors_err1_n.asm b/gmp/mpn/x86_64/core2/aors_err1_n.asm
new file mode 100644
index 0000000000..3f875aefa4
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/aors_err1_n.asm
@@ -0,0 +1,225 @@
+dnl Core 2 mpn_add_err1_n, mpn_sub_err1_n
+
+dnl Contributed by David Harvey.
+
+dnl Copyright 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 4.14
+C Intel corei ?
+C Intel atom ?
+C VIA nano ?
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`ep', `%rcx')
+define(`yp', `%r8')
+define(`n', `%r9')
+define(`cy_param', `8(%rsp)')
+
+define(`el', `%rbx')
+define(`eh', `%rbp')
+define(`t0', `%r10')
+define(`t1', `%r11')
+define(`t2', `%r12')
+define(`t3', `%r13')
+define(`w0', `%r14')
+define(`w1', `%r15')
+
+ifdef(`OPERATION_add_err1_n', `
+ define(ADCSBB, adc)
+ define(func, mpn_add_err1_n)')
+ifdef(`OPERATION_sub_err1_n', `
+ define(ADCSBB, sbb)
+ define(func, mpn_sub_err1_n)')
+
+MULFUNC_PROLOGUE(mpn_add_err1_n mpn_sub_err1_n)
+
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ mov cy_param, %rax
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ lea (up,n,8), up
+ lea (vp,n,8), vp
+ lea (rp,n,8), rp
+
+ mov R32(n), R32(%r10)
+ and $3, R32(%r10)
+ jz L(0mod4)
+ cmp $2, R32(%r10)
+ jc L(1mod4)
+ jz L(2mod4)
+L(3mod4):
+ xor R32(el), R32(el)
+ xor R32(eh), R32(eh)
+ xor R32(t0), R32(t0)
+ xor R32(t1), R32(t1)
+ lea -24(yp,n,8), yp
+ neg n
+
+ shr $1, %al C restore carry
+ mov (up,n,8), w0
+ mov 8(up,n,8), w1
+ ADCSBB (vp,n,8), w0
+ mov w0, (rp,n,8)
+ cmovc 16(yp), el
+ ADCSBB 8(vp,n,8), w1
+ mov w1, 8(rp,n,8)
+ cmovc 8(yp), t0
+ mov 16(up,n,8), w0
+ ADCSBB 16(vp,n,8), w0
+ mov w0, 16(rp,n,8)
+ cmovc (yp), t1
+ setc %al C save carry
+ add t0, el
+ adc $0, eh
+ add t1, el
+ adc $0, eh
+
+ add $3, n
+ jnz L(loop)
+ jmp L(end)
+
+ ALIGN(16)
+L(0mod4):
+ xor R32(el), R32(el)
+ xor R32(eh), R32(eh)
+ lea (yp,n,8), yp
+ neg n
+ jmp L(loop)
+
+ ALIGN(16)
+L(1mod4):
+ xor R32(el), R32(el)
+ xor R32(eh), R32(eh)
+ lea -8(yp,n,8), yp
+ neg n
+
+ shr $1, %al C restore carry
+ mov (up,n,8), w0
+ ADCSBB (vp,n,8), w0
+ mov w0, (rp,n,8)
+ cmovc (yp), el
+ setc %al C save carry
+
+ add $1, n
+ jnz L(loop)
+ jmp L(end)
+
+ ALIGN(16)
+L(2mod4):
+ xor R32(el), R32(el)
+ xor R32(eh), R32(eh)
+ xor R32(t0), R32(t0)
+ lea -16(yp,n,8), yp
+ neg n
+
+ shr $1, %al C restore carry
+ mov (up,n,8), w0
+ mov 8(up,n,8), w1
+ ADCSBB (vp,n,8), w0
+ mov w0, (rp,n,8)
+ cmovc 8(yp), el
+ ADCSBB 8(vp,n,8), w1
+ mov w1, 8(rp,n,8)
+ cmovc (yp), t0
+ setc %al C save carry
+ add t0, el
+ adc $0, eh
+
+ add $2, n
+ jnz L(loop)
+ jmp L(end)
+
+ ALIGN(32)
+L(loop):
+ mov (up,n,8), w0
+ shr $1, %al C restore carry
+ mov -8(yp), t0
+ mov $0, R32(t3)
+ ADCSBB (vp,n,8), w0
+ cmovnc t3, t0
+ mov w0, (rp,n,8)
+ mov 8(up,n,8), w1
+ mov 16(up,n,8), w0
+ ADCSBB 8(vp,n,8), w1
+ mov -16(yp), t1
+ cmovnc t3, t1
+ mov -24(yp), t2
+ mov w1, 8(rp,n,8)
+ ADCSBB 16(vp,n,8), w0
+ cmovnc t3, t2
+ mov 24(up,n,8), w1
+ ADCSBB 24(vp,n,8), w1
+ cmovc -32(yp), t3
+ setc %al C save carry
+ add t0, el
+ adc $0, eh
+ add t1, el
+ adc $0, eh
+ add t2, el
+ adc $0, eh
+ lea -32(yp), yp
+ mov w0, 16(rp,n,8)
+ add t3, el
+ adc $0, eh
+ add $4, n
+ mov w1, -8(rp,n,8)
+ jnz L(loop)
+
+L(end):
+ mov el, (ep)
+ mov eh, 8(ep)
+
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/aors_n.asm b/gmp/mpn/x86_64/core2/aors_n.asm
new file mode 100644
index 0000000000..74a1bce48a
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/aors_n.asm
@@ -0,0 +1,141 @@
+dnl Intel mpn_add_n/mpn_sub_n optimised for Conroe, Nehalem.
+
+dnl Copyright 2006, 2007, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 2
+C AMD K10 2
+C Intel P4 10
+C Intel core2 2
+C Intel NHM 2
+C Intel SBR 2
+C Intel atom 9
+C VIA nano 3
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cy', `%r8')
+
+ifdef(`OPERATION_add_n', `
+ define(ADCSBB, adc)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(ADCSBB, sbb)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ xor %r8, %r8
+L(start):
+ mov (up), %r10
+ mov (vp), %r11
+
+ lea (up,n,8), up
+ lea (vp,n,8), vp
+ lea (rp,n,8), rp
+ mov R32(n), R32(%rax)
+ neg n
+ and $3, R32(%rax)
+ je L(b00)
+ add %rax, n C clear low rcx bits for jrcxz
+ cmp $2, R32(%rax)
+ jl L(b01)
+ je L(b10)
+
+L(b11): neg %r8 C set cy
+ jmp L(e11)
+
+L(b00): neg %r8 C set cy
+ mov %r10, %r8
+ mov %r11, %r9
+ lea 4(n), n
+ jmp L(e00)
+
+ nop
+ nop
+ nop
+L(b01): neg %r8 C set cy
+ jmp L(top)
+
+L(b10): neg %r8 C set cy
+ mov %r10, %r8
+ mov %r11, %r9
+ jmp L(e10)
+
+L(end): ADCSBB %r11, %r10
+ mov %r10, -8(rp)
+ mov R32(%rcx), R32(%rax) C clear eax, ecx contains 0
+ adc R32(%rax), R32(%rax)
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(top): jrcxz L(end)
+ mov (up,n,8), %r8
+ mov (vp,n,8), %r9
+ lea 4(n), n
+ ADCSBB %r11, %r10
+ mov %r10, -40(rp,n,8)
+L(e00): mov -24(up,n,8), %r10
+ mov -24(vp,n,8), %r11
+ ADCSBB %r9, %r8
+ mov %r8, -32(rp,n,8)
+L(e11): mov -16(up,n,8), %r8
+ mov -16(vp,n,8), %r9
+ ADCSBB %r11, %r10
+ mov %r10, -24(rp,n,8)
+L(e10): mov -8(up,n,8), %r10
+ mov -8(vp,n,8), %r11
+ ADCSBB %r9, %r8
+ mov %r8, -16(rp,n,8)
+ jmp L(top)
+EPILOGUE()
+
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ jmp L(start)
+EPILOGUE()
+
diff --git a/gmp/mpn/x86_64/core2/aorsmul_1.asm b/gmp/mpn/x86_64/core2/aorsmul_1.asm
new file mode 100644
index 0000000000..6b313dd836
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/aorsmul_1.asm
@@ -0,0 +1,178 @@
+dnl x86-64 mpn_addmul_1 and mpn_submul_1, optimized for "Core 2".
+
+dnl Copyright 2003-2005, 2007-2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 4
+C AMD K10 4
+C AMD bd1 5.1
+C AMD bobcat
+C Intel P4 ?
+C Intel core2 4.3-4.5 (fluctuating)
+C Intel NHM 5.0
+C Intel SBR 4.1
+C Intel atom ?
+C VIA nano 5.25
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`v0', `%rcx')
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`func', `mpn_addmul_1')
+ define(`func_1c', `mpn_addmul_1c')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`func', `mpn_submul_1')
+ define(`func_1c', `mpn_submul_1c')
+')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_addmul_1c mpn_submul_1 mpn_submul_1c)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ C For DOS, on the stack we have four saved registers, return address,
+ C space for four register arguments, and finally the carry input.
+
+IFDOS(` define(`carry_in', `72(%rsp)')') dnl
+IFSTD(` define(`carry_in', `%r8')') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func_1c)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+ lea (%rdx), %rbx
+ neg %rbx
+
+ mov (up), %rax
+ mov (rp), %r10
+
+ lea -16(rp,%rdx,8), rp
+ lea (up,%rdx,8), up
+ mul %rcx
+ add carry_in, %rax
+ adc $0, %rdx
+ jmp L(start_nc)
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+ lea (%rdx), %rbx
+ neg %rbx
+
+ mov (up), %rax
+ mov (rp), %r10
+
+ lea -16(rp,%rdx,8), rp
+ lea (up,%rdx,8), up
+ mul %rcx
+
+L(start_nc):
+ bt $0, R32(%rbx)
+ jc L(odd)
+
+ lea (%rax), %r11
+ mov 8(up,%rbx,8), %rax
+ lea (%rdx), %rbp
+ mul %rcx
+ add $2, %rbx
+ jns L(n2)
+
+ lea (%rax), %r8
+ mov (up,%rbx,8), %rax
+ lea (%rdx), %r9
+ jmp L(mid)
+
+L(odd): add $1, %rbx
+ jns L(n1)
+
+ lea (%rax), %r8
+ mov (up,%rbx,8), %rax
+ lea (%rdx), %r9
+ mul %rcx
+ lea (%rax), %r11
+ mov 8(up,%rbx,8), %rax
+ lea (%rdx), %rbp
+ jmp L(e)
+
+ ALIGN(16)
+L(top): mul %rcx
+ ADDSUB %r8, %r10
+ lea (%rax), %r8
+ mov (up,%rbx,8), %rax
+ adc %r9, %r11
+ mov %r10, -8(rp,%rbx,8)
+ mov (rp,%rbx,8), %r10
+ lea (%rdx), %r9
+ adc $0, %rbp
+L(mid): mul %rcx
+ ADDSUB %r11, %r10
+ lea (%rax), %r11
+ mov 8(up,%rbx,8), %rax
+ adc %rbp, %r8
+ mov %r10, (rp,%rbx,8)
+ mov 8(rp,%rbx,8), %r10
+ lea (%rdx), %rbp
+ adc $0, %r9
+L(e): add $2, %rbx
+ js L(top)
+
+ mul %rcx
+ ADDSUB %r8, %r10
+ adc %r9, %r11
+ mov %r10, -8(rp)
+ adc $0, %rbp
+L(n2): mov (rp), %r10
+ ADDSUB %r11, %r10
+ adc %rbp, %rax
+ mov %r10, (rp)
+ adc $0, %rdx
+L(n1): mov 8(rp), %r10
+ ADDSUB %rax, %r10
+ mov %r10, 8(rp)
+ mov R32(%rbx), R32(%rax) C zero rax
+ adc %rdx, %rax
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/copyd.asm b/gmp/mpn/x86_64/core2/copyd.asm
new file mode 100644
index 0000000000..f0dc54a55e
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/copyd.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_copyd optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_copyd)
+include_mpn(`x86_64/fastsse/copyd-palignr.asm')
diff --git a/gmp/mpn/x86_64/core2/copyi.asm b/gmp/mpn/x86_64/core2/copyi.asm
new file mode 100644
index 0000000000..9c26e00c52
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/copyi.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_copyi optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_copyi)
+include_mpn(`x86_64/fastsse/copyi-palignr.asm')
diff --git a/gmp/mpn/x86_64/core2/divrem_1.asm b/gmp/mpn/x86_64/core2/divrem_1.asm
new file mode 100644
index 0000000000..623bea386c
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/divrem_1.asm
@@ -0,0 +1,237 @@
+dnl x86-64 mpn_divrem_1 -- mpn by limb division.
+
+dnl Copyright 2004, 2005, 2007-2010, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C norm unorm frac
+C AMD K8,K9 15 15 12
+C AMD K10 15 15 12
+C Intel P4 44 44 43
+C Intel core2 24 24 19.5
+C Intel corei 19 19 18
+C Intel atom 51 51 36
+C VIA nano 46 44 22.5
+
+C mp_limb_t
+C mpn_divrem_1 (mp_ptr qp, mp_size_t fn,
+C mp_srcptr np, mp_size_t nn, mp_limb_t d)
+
+C mp_limb_t
+C mpn_preinv_divrem_1 (mp_ptr qp, mp_size_t fn,
+C mp_srcptr np, mp_size_t nn, mp_limb_t d,
+C mp_limb_t dinv, int cnt)
+
+C INPUT PARAMETERS
+define(`qp', `%rdi')
+define(`fn_param', `%rsi')
+define(`up_param', `%rdx')
+define(`un_param', `%rcx')
+define(`d', `%r8')
+define(`dinv', `%r9') C only for mpn_preinv_divrem_1
+C shift passed on stack C only for mpn_preinv_divrem_1
+
+define(`cnt', `%rcx')
+define(`up', `%rsi')
+define(`fn', `%r12')
+define(`un', `%rbx')
+
+
+C rax rbx rcx rdx rsi rdi rbp r8 r9 r10 r11 r12 r13 r14 r15
+C cnt qp d dinv
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+IFSTD(`define(`CNTOFF', `40($1)')')
+IFDOS(`define(`CNTOFF', `104($1)')')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_preinv_divrem_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+IFDOS(` mov 64(%rsp), %r9 ')
+ xor R32(%rax), R32(%rax)
+ push %r13
+ push %r12
+ push %rbp
+ push %rbx
+
+ mov fn_param, fn
+ mov un_param, un
+ add fn_param, un_param
+ mov up_param, up
+
+ lea -8(qp,un_param,8), qp
+
+ mov CNTOFF(%rsp), R8(cnt)
+ shl R8(cnt), d
+ jmp L(ent)
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_divrem_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ xor R32(%rax), R32(%rax)
+ push %r13
+ push %r12
+ push %rbp
+ push %rbx
+
+ mov fn_param, fn
+ mov un_param, un
+ add fn_param, un_param
+ mov up_param, up
+ je L(ret)
+
+ lea -8(qp,un_param,8), qp
+ xor R32(%rbp), R32(%rbp)
+
+L(unnormalized):
+ test un, un
+ je L(44)
+ mov -8(up,un,8), %rax
+ cmp d, %rax
+ jae L(44)
+ mov %rbp, (qp)
+ mov %rax, %rbp
+ lea -8(qp), qp
+ je L(ret)
+ dec un
+L(44):
+ bsr d, %rcx
+ not R32(%rcx)
+ sal R8(%rcx), d
+ sal R8(%rcx), %rbp
+
+ push %rcx
+IFSTD(` push %rdi ')
+IFSTD(` push %rsi ')
+ push %r8
+IFSTD(` mov d, %rdi ')
+IFDOS(` mov d, %rcx ')
+ CALL( mpn_invert_limb)
+ pop %r8
+IFSTD(` pop %rsi ')
+IFSTD(` pop %rdi ')
+ pop %rcx
+
+ mov %rax, dinv
+ mov %rbp, %rax
+ test un, un
+ je L(frac)
+L(ent): mov -8(up,un,8), %rbp
+ shr R8(%rcx), %rax
+ shld R8(%rcx), %rbp, %rax
+ sub $2, un
+ js L(end)
+
+ ALIGN(16)
+L(top): lea 1(%rax), %r11
+ mul dinv
+ mov (up,un,8), %r10
+ shld R8(%rcx), %r10, %rbp
+ mov %rbp, %r13
+ add %rax, %r13
+ adc %r11, %rdx
+ mov %rdx, %r11
+ imul d, %rdx
+ sub %rdx, %rbp
+ lea (d,%rbp), %rax
+ sub $8, qp
+ cmp %r13, %rbp
+ cmovc %rbp, %rax
+ adc $-1, %r11
+ cmp d, %rax
+ jae L(ufx)
+L(uok): dec un
+ mov %r11, 8(qp)
+ mov %r10, %rbp
+ jns L(top)
+
+L(end): lea 1(%rax), %r11
+ sal R8(%rcx), %rbp
+ mul dinv
+ add %rbp, %rax
+ adc %r11, %rdx
+ mov %rax, %r11
+ mov %rdx, %r13
+ imul d, %rdx
+ sub %rdx, %rbp
+ mov d, %rax
+ add %rbp, %rax
+ cmp %r11, %rbp
+ cmovc %rbp, %rax
+ adc $-1, %r13
+ cmp d, %rax
+ jae L(efx)
+L(eok): mov %r13, (qp)
+ sub $8, qp
+ jmp L(frac)
+
+L(ufx): sub d, %rax
+ inc %r11
+ jmp L(uok)
+L(efx): sub d, %rax
+ inc %r13
+ jmp L(eok)
+
+L(frac):mov d, %rbp
+ neg %rbp
+ jmp L(fent)
+
+ ALIGN(16) C K8-K10 P6-CNR P6-NHM P4
+L(ftop):mul dinv C 0,12 0,17 0,17
+ add %r11, %rdx C 5 8 10
+ mov %rax, %r11 C 4 8 3
+ mov %rdx, %r13 C 6 9 11
+ imul %rbp, %rdx C 6 9 11
+ mov d, %rax C
+ add %rdx, %rax C 10 14 14
+ cmp %r11, %rdx C 10 14 14
+ cmovc %rdx, %rax C 11 15 15
+ adc $-1, %r13 C
+ mov %r13, (qp) C
+ sub $8, qp C
+L(fent):lea 1(%rax), %r11 C
+ dec fn C
+ jns L(ftop) C
+
+ shr R8(%rcx), %rax
+L(ret): pop %rbx
+ pop %rbp
+ pop %r12
+ pop %r13
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/gcd_1.asm b/gmp/mpn/x86_64/core2/gcd_1.asm
new file mode 100644
index 0000000000..e0cab9b4e4
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/gcd_1.asm
@@ -0,0 +1,144 @@
+dnl AMD64 mpn_gcd_1 optimised for Intel C2, NHM, SBR and AMD K10, BD.
+
+dnl Based on the K7 gcd_1.asm, by Kevin Ryde. Rehacked for AMD64 by Torbjorn
+dnl Granlund.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/bit (approx)
+C AMD K8,K9 8.50
+C AMD K10 4.30
+C AMD bd1 5.00
+C AMD bobcat 10.0
+C Intel P4 18.6
+C Intel core2 3.83
+C Intel NHM 5.17
+C Intel SBR 4.69
+C Intel atom 17.0
+C VIA nano 5.44
+C Numbers measured with: speed -CD -s16-64 -t48 mpn_gcd_1
+
+C TODO
+C * Optimise inner-loop for specific CPUs.
+C * Use DIV for 1-by-1 reductions, at least for some CPUs.
+
+C Threshold of when to call bmod when U is one limb. Should be about
+C (time_in_cycles(bmod_1,1) + call_overhead) / (cycles/bit).
+define(`BMOD_THRES_LOG2', 6)
+
+C INPUT PARAMETERS
+define(`up', `%rdi')
+define(`n', `%rsi')
+define(`v0', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+IFDOS(`define(`STACK_ALLOC', 40)')
+IFSTD(`define(`STACK_ALLOC', 8)')
+
+C Undo some configure cleverness.
+C The problem is that C only defines the '1c' variant, and that configure
+C therefore considers modexact_1c to be the base function. It then adds a
+C special fat rule for mpn_modexact_1_odd, messing up things when a cpudep
+C gcd_1 exists without a corresponding cpudep mode1o.
+ifdef(`WANT_FAT_BINARY', `
+ define(`mpn_modexact_1_odd', `MPN_PREFIX`modexact_1_odd_x86_64'')')
+
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_gcd_1)
+ FUNC_ENTRY(3)
+ mov (up), %rax C U low limb
+ or v0, %rax
+ bsf %rax, %rax C min(ctz(u0),ctz(v0))
+
+ bsf v0, %rcx
+ shr R8(%rcx), v0
+
+ push %rax C preserve common twos over call
+ push v0 C preserve v0 argument over call
+ sub $STACK_ALLOC, %rsp C maintain ABI required rsp alignment
+
+ cmp $1, n
+ jnz L(reduce_nby1)
+
+C Both U and V are single limbs, reduce with bmod if u0 >> v0.
+ mov (up), %r8
+ mov %r8, %rax
+ shr $BMOD_THRES_LOG2, %r8
+ cmp %r8, v0
+ ja L(reduced)
+ jmp L(bmod)
+
+L(reduce_nby1):
+ cmp $BMOD_1_TO_MOD_1_THRESHOLD, n
+ jl L(bmod)
+IFDOS(` mov %rdx, %r8 ')
+IFDOS(` mov %rsi, %rdx ')
+IFDOS(` mov %rdi, %rcx ')
+ CALL( mpn_mod_1)
+ jmp L(reduced)
+L(bmod):
+IFDOS(` mov %rdx, %r8 ')
+IFDOS(` mov %rsi, %rdx ')
+IFDOS(` mov %rdi, %rcx ')
+ CALL( mpn_modexact_1_odd)
+L(reduced):
+
+ add $STACK_ALLOC, %rsp
+ pop %rdx
+
+ bsf %rax, %rcx
+C test %rax, %rax C FIXME: does this lower latency?
+ jnz L(mid)
+ jmp L(end)
+
+ ALIGN(16) C K10 BD C2 NHM SBR
+L(top): cmovc %r10, %rax C if x-y < 0 0,3 0,3 0,6 0,5 0,5
+ cmovc %r9, %rdx C use x,y-x 0,3 0,3 2,8 1,7 1,7
+L(mid): shr R8(%rcx), %rax C 1,7 1,6 2,8 2,8 2,8
+ mov %rdx, %r10 C 1 1 4 3 3
+ sub %rax, %r10 C 2 2 5 4 4
+ bsf %r10, %rcx C 3 3 6 5 5
+ mov %rax, %r9 C 2 2 3 3 4
+ sub %rdx, %rax C 2 2 4 3 4
+ jnz L(top) C
+
+L(end): pop %rcx
+ mov %rdx, %rax
+ shl R8(%rcx), %rax
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/gmp-mparam.h b/gmp/mpn/x86_64/core2/gmp-mparam.h
new file mode 100644
index 0000000000..0f4f88f780
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/gmp-mparam.h
@@ -0,0 +1,217 @@
+/* Core 2 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2010, 2012, 2014 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 2133 MHz Core 2 (65nm) */
+/* FFT tuning limit = 60000000 */
+/* Generated by tuneup.c, 2014-03-13, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 11
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 16
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 9
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 24
+
+#define MUL_TOOM22_THRESHOLD 23
+#define MUL_TOOM33_THRESHOLD 65
+#define MUL_TOOM44_THRESHOLD 179
+#define MUL_TOOM6H_THRESHOLD 268
+#define MUL_TOOM8H_THRESHOLD 357
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 69
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 114
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 73
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 78
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 100
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 28
+#define SQR_TOOM3_THRESHOLD 102
+#define SQR_TOOM4_THRESHOLD 160
+#define SQR_TOOM6_THRESHOLD 222
+#define SQR_TOOM8_THRESHOLD 296
+
+#define MULMID_TOOM42_THRESHOLD 28
+
+#define MULMOD_BNM1_THRESHOLD 12
+#define SQRMOD_BNM1_THRESHOLD 13
+
+#define MUL_FFT_MODF_THRESHOLD 372 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 372, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 21, 7}, { 11, 6}, { 23, 7}, { 12, 6}, \
+ { 25, 7}, { 21, 8}, { 11, 7}, { 25, 8}, \
+ { 13, 7}, { 27, 8}, { 15, 7}, { 32, 8}, \
+ { 17, 7}, { 36, 8}, { 19, 7}, { 40, 8}, \
+ { 21, 9}, { 11, 8}, { 27, 9}, { 15, 8}, \
+ { 35, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 47, 9}, { 27,10}, { 15, 9}, { 43,10}, \
+ { 23, 9}, { 51,11}, { 15,10}, { 31, 9}, \
+ { 63,10}, { 39, 9}, { 83,10}, { 47, 9}, \
+ { 95,10}, { 55,11}, { 31,10}, { 79,11}, \
+ { 47,10}, { 95,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 135, 9}, { 271,11}, \
+ { 79,10}, { 159, 9}, { 319,10}, { 167,11}, \
+ { 95,10}, { 191, 9}, { 383,10}, { 207,11}, \
+ { 111,12}, { 63,11}, { 127,10}, { 271,11}, \
+ { 143,10}, { 287, 9}, { 575,10}, { 303,11}, \
+ { 159,10}, { 319,12}, { 95,11}, { 191,10}, \
+ { 383,11}, { 207,10}, { 415,11}, { 223,13}, \
+ { 63,12}, { 127,11}, { 271,10}, { 543,11}, \
+ { 287,10}, { 575,11}, { 303,10}, { 607,12}, \
+ { 159,11}, { 319,10}, { 639,11}, { 351,12}, \
+ { 191,11}, { 415,12}, { 223,11}, { 479,13}, \
+ { 127,12}, { 255,11}, { 543,12}, { 287,11}, \
+ { 607,12}, { 319,11}, { 639,12}, { 351,11}, \
+ { 703,13}, { 191,12}, { 415,11}, { 831,12}, \
+ { 479,14}, { 127,13}, { 255,12}, { 607,13}, \
+ { 319,12}, { 703,13}, { 383,12}, { 831,13}, \
+ { 447,12}, { 959,14}, { 255,13}, { 511,12}, \
+ { 1023,13}, { 575,12}, { 1215,13}, { 639,12}, \
+ { 1279,13}, { 703,14}, { 383,13}, { 831,12}, \
+ { 1663,13}, { 895,15}, { 255,14}, { 511,13}, \
+ { 1151,14}, { 639,13}, { 1343,14}, { 767,13}, \
+ { 1599,14}, { 895,15}, { 511,14}, { 1279,13}, \
+ { 2687,14}, { 1407,13}, { 2815,15}, { 767,14}, \
+ { 1535,13}, { 3199,14}, { 1663,13}, { 3455,16}, \
+ { 511,15}, { 1023,14}, { 2047,13}, { 4095,14}, \
+ { 2175,12}, { 8959,14}, { 2303,13}, { 4607,12}, \
+ { 9471,14}, { 2431,13}, { 4863,12}, { 9983,15}, \
+ { 1279,14}, { 2559,12}, { 10239,14}, { 2687,12}, \
+ { 11775,15}, { 1535,14}, { 3327,13}, { 6655,14}, \
+ { 3455,13}, { 6911,14}, { 3583,12}, { 14335,11}, \
+ { 28671,10}, { 57343,11}, { 2048,12}, { 4096,13}, \
+ { 8192,14}, { 16384,15}, { 32768,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 183
+#define MUL_FFT_THRESHOLD 4736
+
+#define SQR_FFT_MODF_THRESHOLD 340 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 340, 5}, { 15, 6}, { 8, 5}, { 17, 6}, \
+ { 9, 5}, { 19, 6}, { 23, 7}, { 12, 6}, \
+ { 25, 7}, { 21, 8}, { 11, 7}, { 25, 8}, \
+ { 13, 7}, { 27, 8}, { 15, 7}, { 31, 8}, \
+ { 21, 9}, { 11, 8}, { 27, 9}, { 15, 8}, \
+ { 33, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 47, 9}, { 27,10}, { 15, 9}, { 43,10}, \
+ { 23, 9}, { 55,10}, { 31, 9}, { 67,10}, \
+ { 39, 9}, { 79,10}, { 47,11}, { 31,10}, \
+ { 79,11}, { 47,10}, { 95,12}, { 31,11}, \
+ { 63,10}, { 127, 9}, { 255, 8}, { 511, 9}, \
+ { 271, 8}, { 543,11}, { 79, 9}, { 319, 8}, \
+ { 639,11}, { 95,10}, { 191, 9}, { 383,10}, \
+ { 207, 9}, { 415,12}, { 63,11}, { 127,10}, \
+ { 271, 9}, { 543,10}, { 287, 9}, { 575,10}, \
+ { 303, 9}, { 607,10}, { 319, 9}, { 639,11}, \
+ { 175,12}, { 95,11}, { 191,10}, { 383,11}, \
+ { 207,10}, { 415,13}, { 63,12}, { 127,11}, \
+ { 271,10}, { 543,11}, { 287,10}, { 575,11}, \
+ { 303,10}, { 607,11}, { 319,10}, { 639,11}, \
+ { 351,12}, { 191,11}, { 415,10}, { 831,12}, \
+ { 223,11}, { 447,10}, { 895,11}, { 479,13}, \
+ { 127,12}, { 255,11}, { 543,12}, { 287,11}, \
+ { 607,12}, { 319,11}, { 639,12}, { 351,13}, \
+ { 191,12}, { 415,11}, { 831,12}, { 479,14}, \
+ { 127,13}, { 255,12}, { 607,13}, { 319,12}, \
+ { 703,13}, { 383,12}, { 831,13}, { 447,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1023,13}, \
+ { 575,12}, { 1215,13}, { 639,12}, { 1279,13}, \
+ { 703,14}, { 383,13}, { 831,12}, { 1663,13}, \
+ { 959,15}, { 255,14}, { 511,13}, { 1087,12}, \
+ { 2175,13}, { 1215,14}, { 639,13}, { 1343,12}, \
+ { 2687,13}, { 1407,12}, { 2815,14}, { 767,13}, \
+ { 1663,14}, { 895,15}, { 511,14}, { 1023,13}, \
+ { 2175,14}, { 1151,13}, { 2303,12}, { 4607,13}, \
+ { 2431,12}, { 4863,14}, { 1279,13}, { 2687,14}, \
+ { 1407,15}, { 767,14}, { 1535,13}, { 3071,14}, \
+ { 1663,13}, { 3455,12}, { 6911,14}, { 1791,13}, \
+ { 3583,16}, { 511,15}, { 1023,14}, { 2175,13}, \
+ { 4351,14}, { 2303,13}, { 4607,14}, { 2431,13}, \
+ { 4863,15}, { 1279,14}, { 2815,13}, { 5631,14}, \
+ { 2943,13}, { 5887,15}, { 1535,14}, { 3455,13}, \
+ { 6911,14}, { 16384,15}, { 32768,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 179
+#define SQR_FFT_THRESHOLD 3008
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 62
+#define MULLO_MUL_N_THRESHOLD 9174
+
+#define DC_DIV_QR_THRESHOLD 46
+#define DC_DIVAPPR_Q_THRESHOLD 155
+#define DC_BDIV_QR_THRESHOLD 50
+#define DC_BDIV_Q_THRESHOLD 94
+
+#define INV_MULMOD_BNM1_THRESHOLD 48
+#define INV_NEWTON_THRESHOLD 156
+#define INV_APPR_THRESHOLD 155
+
+#define BINV_NEWTON_THRESHOLD 234
+#define REDC_1_TO_REDC_2_THRESHOLD 22
+#define REDC_2_TO_REDC_N_THRESHOLD 48
+
+#define MU_DIV_QR_THRESHOLD 1187
+#define MU_DIVAPPR_Q_THRESHOLD 1142
+#define MUPI_DIV_QR_THRESHOLD 74
+#define MU_BDIV_QR_THRESHOLD 1017
+#define MU_BDIV_Q_THRESHOLD 1187
+
+#define POWM_SEC_TABLE 1,64,131,269,466
+
+#define MATRIX22_STRASSEN_THRESHOLD 19
+#define HGCD_THRESHOLD 117
+#define HGCD_APPR_THRESHOLD 151
+#define HGCD_REDUCE_THRESHOLD 2121
+#define GCD_DC_THRESHOLD 427
+#define GCDEXT_DC_THRESHOLD 342
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 11
+#define GET_STR_PRECOMPUTE_THRESHOLD 18
+#define SET_STR_DC_THRESHOLD 552
+#define SET_STR_PRECOMPUTE_THRESHOLD 1561
+
+#define FAC_DSC_THRESHOLD 656
+#define FAC_ODD_THRESHOLD 23
diff --git a/gmp/mpn/x86_64/core2/lshift.asm b/gmp/mpn/x86_64/core2/lshift.asm
new file mode 100644
index 0000000000..8ccafeca6c
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/lshift.asm
@@ -0,0 +1,149 @@
+dnl x86-64 mpn_lshift optimized for "Core 2".
+
+dnl Copyright 2007, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 4.25
+C AMD K10 4.25
+C Intel P4 14.7
+C Intel core2 1.27
+C Intel NHM 1.375 (up to about n = 260, then 1.5)
+C Intel SBR 1.87
+C Intel atom ?
+C VIA nano ?
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_lshift)
+ FUNC_ENTRY(4)
+ lea -8(rp,n,8), rp
+ lea -8(up,n,8), up
+
+ mov R32(%rdx), R32(%rax)
+ and $3, R32(%rax)
+ jne L(nb00)
+L(b00): C n = 4, 8, 12, ...
+ mov (up), %r10
+ mov -8(up), %r11
+ xor R32(%rax), R32(%rax)
+ shld R8(cnt), %r10, %rax
+ mov -16(up), %r8
+ lea 24(rp), rp
+ sub $4, n
+ jmp L(00)
+
+L(nb00):C n = 1, 5, 9, ...
+ cmp $2, R32(%rax)
+ jae L(nb01)
+L(b01): mov (up), %r9
+ xor R32(%rax), R32(%rax)
+ shld R8(cnt), %r9, %rax
+ sub $2, n
+ jb L(le1)
+ mov -8(up), %r10
+ mov -16(up), %r11
+ lea -8(up), up
+ lea 16(rp), rp
+ jmp L(01)
+L(le1): shl R8(cnt), %r9
+ mov %r9, (rp)
+ FUNC_EXIT()
+ ret
+
+L(nb01):C n = 2, 6, 10, ...
+ jne L(b11)
+L(b10): mov (up), %r8
+ mov -8(up), %r9
+ xor R32(%rax), R32(%rax)
+ shld R8(cnt), %r8, %rax
+ sub $3, n
+ jb L(le2)
+ mov -16(up), %r10
+ lea -16(up), up
+ lea 8(rp), rp
+ jmp L(10)
+L(le2): shld R8(cnt), %r9, %r8
+ mov %r8, (rp)
+ shl R8(cnt), %r9
+ mov %r9, -8(rp)
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16) C performance critical!
+L(b11): C n = 3, 7, 11, ...
+ mov (up), %r11
+ mov -8(up), %r8
+ xor R32(%rax), R32(%rax)
+ shld R8(cnt), %r11, %rax
+ mov -16(up), %r9
+ lea -24(up), up
+ sub $4, n
+ jb L(end)
+
+ ALIGN(16)
+L(top): shld R8(cnt), %r8, %r11
+ mov (up), %r10
+ mov %r11, (rp)
+L(10): shld R8(cnt), %r9, %r8
+ mov -8(up), %r11
+ mov %r8, -8(rp)
+L(01): shld R8(cnt), %r10, %r9
+ mov -16(up), %r8
+ mov %r9, -16(rp)
+L(00): shld R8(cnt), %r11, %r10
+ mov -24(up), %r9
+ mov %r10, -24(rp)
+ add $-32, up
+ lea -32(rp), rp
+ sub $4, n
+ jnc L(top)
+
+L(end): shld R8(cnt), %r8, %r11
+ mov %r11, (rp)
+ shld R8(cnt), %r9, %r8
+ mov %r8, -8(rp)
+ shl R8(cnt), %r9
+ mov %r9, -16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/lshiftc.asm b/gmp/mpn/x86_64/core2/lshiftc.asm
new file mode 100644
index 0000000000..65c7b2f1b8
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/lshiftc.asm
@@ -0,0 +1,159 @@
+dnl x86-64 mpn_lshiftc optimized for "Core 2".
+
+dnl Copyright 2007, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 1.5
+C Intel NHM 2.25 (up to about n = 260, then 1.875)
+C Intel SBR 2.25
+C Intel atom ?
+C VIA nano ?
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_lshiftc)
+ FUNC_ENTRY(4)
+ lea -8(rp,n,8), rp
+ lea -8(up,n,8), up
+
+ mov R32(%rdx), R32(%rax)
+ and $3, R32(%rax)
+ jne L(nb00)
+L(b00): C n = 4, 8, 12, ...
+ mov (up), %r10
+ mov -8(up), %r11
+ xor R32(%rax), R32(%rax)
+ shld R8(cnt), %r10, %rax
+ mov -16(up), %r8
+ lea 24(rp), rp
+ sub $4, n
+ jmp L(00)
+
+L(nb00):C n = 1, 5, 9, ...
+ cmp $2, R32(%rax)
+ jae L(nb01)
+L(b01): mov (up), %r9
+ xor R32(%rax), R32(%rax)
+ shld R8(cnt), %r9, %rax
+ sub $2, n
+ jb L(le1)
+ mov -8(up), %r10
+ mov -16(up), %r11
+ lea -8(up), up
+ lea 16(rp), rp
+ jmp L(01)
+L(le1): shl R8(cnt), %r9
+ not %r9
+ mov %r9, (rp)
+ FUNC_EXIT()
+ ret
+
+L(nb01):C n = 2, 6, 10, ...
+ jne L(b11)
+L(b10): mov (up), %r8
+ mov -8(up), %r9
+ xor R32(%rax), R32(%rax)
+ shld R8(cnt), %r8, %rax
+ sub $3, n
+ jb L(le2)
+ mov -16(up), %r10
+ lea -16(up), up
+ lea 8(rp), rp
+ jmp L(10)
+L(le2): shld R8(cnt), %r9, %r8
+ not %r8
+ mov %r8, (rp)
+ shl R8(cnt), %r9
+ not %r9
+ mov %r9, -8(rp)
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16) C performance critical!
+L(b11): C n = 3, 7, 11, ...
+ mov (up), %r11
+ mov -8(up), %r8
+ xor R32(%rax), R32(%rax)
+ shld R8(cnt), %r11, %rax
+ mov -16(up), %r9
+ lea -24(up), up
+ sub $4, n
+ jb L(end)
+
+ ALIGN(16)
+L(top): shld R8(cnt), %r8, %r11
+ mov (up), %r10
+ not %r11
+ mov %r11, (rp)
+L(10): shld R8(cnt), %r9, %r8
+ mov -8(up), %r11
+ not %r8
+ mov %r8, -8(rp)
+L(01): shld R8(cnt), %r10, %r9
+ mov -16(up), %r8
+ not %r9
+ mov %r9, -16(rp)
+L(00): shld R8(cnt), %r11, %r10
+ mov -24(up), %r9
+ not %r10
+ mov %r10, -24(rp)
+ add $-32, up
+ lea -32(rp), rp
+ sub $4, n
+ jnc L(top)
+
+L(end): shld R8(cnt), %r8, %r11
+ not %r11
+ mov %r11, (rp)
+ shld R8(cnt), %r9, %r8
+ not %r8
+ mov %r8, -8(rp)
+ shl R8(cnt), %r9
+ not %r9
+ mov %r9, -16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/mul_basecase.asm b/gmp/mpn/x86_64/core2/mul_basecase.asm
new file mode 100644
index 0000000000..d16be852f7
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/mul_basecase.asm
@@ -0,0 +1,975 @@
+dnl X86-64 mpn_mul_basecase optimised for Intel Nehalem/Westmere.
+dnl It also seems good for Conroe/Wolfdale.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_1 mul_2 mul_3 addmul_2
+C AMD K8,K9
+C AMD K10
+C AMD bull
+C AMD pile
+C AMD steam
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core 4.0 4.0 - 4.18-4.25
+C Intel NHM 3.75 3.8 - 4.06-4.2
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C Code structure:
+C
+C
+C m_1(0m4) m_1(1m4) m_1(2m4) m_1(3m4)
+C | | | |
+C m_2(0m4) | m_2(1m4) | m_2(2m4) | m_2(3m4) |
+C | / | / | / | /
+C | / | / | / | /
+C | / | / | / | /
+C \|/ |/_ \|/ |/_ \|/ |/_ \|/ |/_
+C _____ _____ _____ _____
+C / \ / \ / \ / \
+C \|/ | \|/ | \|/ | \|/ |
+C am_2(0m4) | am_2(1m4) | am_2(2m4) | am_2(3m4) |
+C \ /|\ \ /|\ \ /|\ \ /|\
+C \_____/ \_____/ \_____/ \_____/
+
+C TODO
+C * Tune. None done so far.
+C * Currently 2687 bytes, making it smaller would be nice.
+C * Implement some basecases, say for un < 4.
+C * Try zeroing with xor in m2 loops.
+C * Try re-rolling the m2 loops to avoid the current 9 insn code duplication
+C between loop header and wind-down code.
+C * Consider adc reg,reg instead of adc $0,reg in m2 loops. This save a byte.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+C Define this to $1 to use late loop index variable as zero, $2 to use an
+C explicit $0.
+define(`Z',`$1')
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param', `%rdx')
+define(`vp_param', `%rcx') C FIXME reallocate vp to rcx but watch performance!
+define(`vn_param', `%r8')
+
+define(`un', `%r9')
+define(`vn', `(%rsp)')
+
+define(`v0', `%r10')
+define(`v1', `%r11')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r12')
+define(`i', `%r13')
+define(`vp', `%r14')
+
+define(`X0', `%r8')
+define(`X1', `%r15')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+define(`ALIGNx', `ALIGN(16)')
+
+define(`N', 85)
+ifdef(`N',,`define(`N',0)')
+define(`MOV', `ifelse(eval(N & $3),0,`mov $1, $2',`lea ($1), $2')')
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mul_basecase)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+ mov (up), %rax C shared for mul_1 and mul_2
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+
+ mov (vp_param), v0 C shared for mul_1 and mul_2
+
+ xor un, un
+ sub un_param, un C un = -un_param
+
+ lea (up,un_param,8), up
+ lea (rp,un_param,8), rp
+
+ mul v0 C shared for mul_1 and mul_2
+
+ test $1, R8(vn_param)
+ jz L(m2)
+
+ lea 8(vp_param), vp C FIXME: delay until known needed
+
+ test $1, R8(un)
+ jnz L(m1x1)
+
+L(m1x0):test $2, R8(un)
+ jnz L(m1s2)
+
+L(m1s0):
+ lea (un), i
+ mov %rax, (rp,un,8)
+ mov 8(up,un,8), %rax
+ mov %rdx, w0 C FIXME: Use lea?
+ lea L(do_am0)(%rip), %rbp
+ jmp L(m1e0)
+
+L(m1s2):
+ lea 2(un), i
+ mov %rax, (rp,un,8)
+ mov 8(up,un,8), %rax
+ mov %rdx, w0 C FIXME: Use lea?
+ mul v0
+ lea L(do_am2)(%rip), %rbp
+ test i, i
+ jnz L(m1e2)
+ add %rax, w0
+ adc $0, %rdx
+ mov w0, I(-8(rp),8(rp,un,8))
+ mov %rdx, I((rp),16(rp,un,8))
+ jmp L(ret2)
+
+L(m1x1):test $2, R8(un)
+ jz L(m1s3)
+
+L(m1s1):
+ lea 1(un), i
+ mov %rax, (rp,un,8)
+ test i, i
+ jz L(1)
+ mov 8(up,un,8), %rax
+ mov %rdx, w1 C FIXME: Use lea?
+ lea L(do_am1)(%rip), %rbp
+ jmp L(m1e1)
+L(1): mov %rdx, I((rp),8(rp,un,8))
+ jmp L(ret2)
+
+L(m1s3):
+ lea -1(un), i
+ mov %rax, (rp,un,8)
+ mov 8(up,un,8), %rax
+ mov %rdx, w1 C FIXME: Use lea?
+ lea L(do_am3)(%rip), %rbp
+ jmp L(m1e3)
+
+ ALIGNx
+L(m1top):
+ mul v0
+ mov w1, -16(rp,i,8)
+L(m1e2):xor R32(w1), R32(w1)
+ add %rax, w0
+ mov (up,i,8), %rax
+ adc %rdx, w1
+ mov w0, -8(rp,i,8)
+L(m1e1):xor R32(w0), R32(w0)
+ mul v0
+ add %rax, w1
+ mov 8(up,i,8), %rax
+ adc %rdx, w0
+ mov w1, (rp,i,8)
+L(m1e0):xor R32(w1), R32(w1)
+ mul v0
+ add %rax, w0
+ mov 16(up,i,8), %rax
+ adc %rdx, w1
+ mov w0, 8(rp,i,8)
+L(m1e3):xor R32(w0), R32(w0)
+ mul v0
+ add %rax, w1
+ mov 24(up,i,8), %rax
+ adc %rdx, w0
+ add $4, i
+ js L(m1top)
+
+ mul v0
+ mov w1, I(-16(rp),-16(rp,i,8))
+ add %rax, w0
+ adc $0, %rdx
+ mov w0, I(-8(rp),-8(rp,i,8))
+ mov %rdx, I((rp),(rp,i,8))
+
+ dec vn_param
+ jz L(ret2)
+ lea -8(rp), rp
+ jmp *%rbp
+
+L(m2):
+ mov 8(vp_param), v1
+ lea 16(vp_param), vp C FIXME: delay until known needed
+
+ test $1, R8(un)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(un)
+ jnz L(b10)
+
+L(b00): lea (un), i
+ mov %rax, (rp,un,8)
+ mov %rdx, w1 C FIXME: Use lea?
+ mov (up,un,8), %rax
+ mov $0, R32(w2)
+ jmp L(m2e0)
+
+L(b10): lea -2(un), i
+ mov %rax, w2 C FIXME: Use lea?
+ mov (up,un,8), %rax
+ mov %rdx, w3 C FIXME: Use lea?
+ mov $0, R32(w0)
+ jmp L(m2e2)
+
+L(bx1): test $2, R8(un)
+ jz L(b11)
+
+L(b01): lea 1(un), i
+ mov %rax, (rp,un,8)
+ mov (up,un,8), %rax
+ mov %rdx, w0 C FIXME: Use lea?
+ mov $0, R32(w1)
+ jmp L(m2e1)
+
+L(b11): lea -1(un), i
+ mov %rax, w1 C FIXME: Use lea?
+ mov (up,un,8), %rax
+ mov %rdx, w2 C FIXME: Use lea?
+ mov $0, R32(w3)
+ jmp L(m2e3)
+
+ ALIGNx
+L(m2top0):
+ mul v0
+ add %rax, w3
+ mov -8(up,i,8), %rax
+ mov w3, -8(rp,i,8)
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w0
+ mov w0, (rp,i,8)
+ adc %rdx, w1
+ mov (up,i,8), %rax
+ adc $0, R32(w2)
+L(m2e0):mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 8(up,i,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 8(up,i,8), %rax
+ mul v1
+ add %rax, w2
+ mov w1, 8(rp,i,8)
+ adc %rdx, w3
+ mov $0, R32(w0)
+ mov 16(up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov 16(up,i,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ mov $0, R32(w1)
+ add %rax, w3
+ mov 24(up,i,8), %rax
+ mov w2, 16(rp,i,8)
+ adc %rdx, w0
+ add $4, i
+ js L(m2top0)
+
+ mul v0
+ add %rax, w3
+ mov I(-8(up),-8(up,i,8)), %rax
+ mov w3, I(-8(rp),-8(rp,i,8))
+ adc %rdx, w0
+ adc R32(w1), R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov w0, I((rp),(rp,i,8))
+ mov w1, I(8(rp),8(rp,i,8))
+
+ add $-2, vn_param
+ jz L(ret2)
+
+L(do_am0):
+ push %r15
+ push vn_param
+
+L(olo0):
+ mov (vp), v0
+ mov 8(vp), v1
+ lea 16(vp), vp
+ lea 16(rp), rp
+ mov (up,un,8), %rax
+C lea 0(un), i
+ mov un, i
+ mul v0
+ mov %rax, X0
+ mov (up,un,8), %rax
+ MOV( %rdx, X1, 2)
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov (rp,un,8), w2
+ mov %rax, w3
+ jmp L(lo0)
+
+ ALIGNx
+L(am2top0):
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ mov (up,i,8), %rax
+ MOV( %rdx, w3, 1)
+ adc $0, w3
+ mul v0
+ add w1, X1
+ mov X1, -8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 2)
+ adc $0, X1
+ mov (up,i,8), %rax
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov (rp,i,8), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+L(lo0): mov 8(up,i,8), %rax
+ mul v0
+ add w2, X0
+ adc %rax, X1
+ mov X0, (rp,i,8)
+ MOV( %rdx, X0, 8)
+ adc $0, X0
+ mov 8(up,i,8), %rax
+ mov 8(rp,i,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ MOV( %rdx, w1, 16)
+ adc $0, w1
+ mov 16(up,i,8), %rax
+ mul v0
+ add w3, X1
+ mov X1, 8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 32)
+ mov 16(rp,i,8), w3
+ adc $0, X1
+ mov 16(up,i,8), %rax
+ mul v1
+ add w3, w0
+ MOV( %rdx, w2, 64)
+ adc %rax, w1
+ mov 24(up,i,8), %rax
+ adc $0, w2
+ mul v0
+ add w0, X0
+ mov X0, 16(rp,i,8)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov 24(up,i,8), %rax
+ mov 24(rp,i,8), w0
+ adc $0, X0
+ add $4, i
+ jnc L(am2top0)
+
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ adc Z(i,$0), %rdx
+ add w1, X1
+ adc Z(i,$0), X0
+ mov X1, I(-8(rp),-8(rp,i,8))
+ add w2, X0
+ mov X0, I((rp),(rp,i,8))
+ adc Z(i,$0), %rdx
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ addl $-2, vn
+ jnz L(olo0)
+
+L(ret): pop %rax
+ pop %r15
+L(ret2):pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+
+ ALIGNx
+L(m2top1):
+ mul v0
+ add %rax, w3
+ mov -8(up,i,8), %rax
+ mov w3, -8(rp,i,8)
+ adc %rdx, w0
+ adc $0, R32(w1)
+L(m2e1):mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w0
+ mov w0, (rp,i,8)
+ adc %rdx, w1
+ mov (up,i,8), %rax
+ adc $0, R32(w2)
+ mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 8(up,i,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 8(up,i,8), %rax
+ mul v1
+ add %rax, w2
+ mov w1, 8(rp,i,8)
+ adc %rdx, w3
+ mov $0, R32(w0)
+ mov 16(up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov 16(up,i,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ mov $0, R32(w1)
+ add %rax, w3
+ mov 24(up,i,8), %rax
+ mov w2, 16(rp,i,8)
+ adc %rdx, w0
+ add $4, i
+ js L(m2top1)
+
+ mul v0
+ add %rax, w3
+ mov I(-8(up),-8(up,i,8)), %rax
+ mov w3, I(-8(rp),-8(rp,i,8))
+ adc %rdx, w0
+ adc R32(w1), R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov w0, I((rp),(rp,i,8))
+ mov w1, I(8(rp),8(rp,i,8))
+
+ add $-2, vn_param
+ jz L(ret2)
+
+L(do_am1):
+ push %r15
+ push vn_param
+
+L(olo1):
+ mov (vp), v0
+ mov 8(vp), v1
+ lea 16(vp), vp
+ lea 16(rp), rp
+ mov (up,un,8), %rax
+ lea 1(un), i
+ mul v0
+ mov %rax, X1
+ MOV( %rdx, X0, 128)
+ mov (up,un,8), %rax
+ mov (rp,un,8), w1
+ mul v1
+ mov %rax, w2
+ mov 8(up,un,8), %rax
+ MOV( %rdx, w3, 1)
+ jmp L(lo1)
+
+ ALIGNx
+L(am2top1):
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ mov (up,i,8), %rax
+ MOV( %rdx, w3, 1)
+ adc $0, w3
+L(lo1): mul v0
+ add w1, X1
+ mov X1, -8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 2)
+ adc $0, X1
+ mov (up,i,8), %rax
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov (rp,i,8), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+ mov 8(up,i,8), %rax
+ mul v0
+ add w2, X0
+ adc %rax, X1
+ mov X0, (rp,i,8)
+ MOV( %rdx, X0, 8)
+ adc $0, X0
+ mov 8(up,i,8), %rax
+ mov 8(rp,i,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ MOV( %rdx, w1, 16)
+ adc $0, w1
+ mov 16(up,i,8), %rax
+ mul v0
+ add w3, X1
+ mov X1, 8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 32)
+ mov 16(rp,i,8), w3
+ adc $0, X1
+ mov 16(up,i,8), %rax
+ mul v1
+ add w3, w0
+ MOV( %rdx, w2, 64)
+ adc %rax, w1
+ mov 24(up,i,8), %rax
+ adc $0, w2
+ mul v0
+ add w0, X0
+ mov X0, 16(rp,i,8)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov 24(up,i,8), %rax
+ mov 24(rp,i,8), w0
+ adc $0, X0
+ add $4, i
+ jnc L(am2top1)
+
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ adc Z(i,$0), %rdx
+ add w1, X1
+ adc Z(i,$0), X0
+ mov X1, I(-8(rp),-8(rp,i,8))
+ add w2, X0
+ mov X0, I((rp),(rp,i,8))
+ adc Z(i,$0), %rdx
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ addl $-2, vn
+ jnz L(olo1)
+
+ pop %rax
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+
+ ALIGNx
+L(m2top2):
+ mul v0
+ add %rax, w3
+ mov -8(up,i,8), %rax
+ mov w3, -8(rp,i,8)
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w0
+ mov w0, (rp,i,8)
+ adc %rdx, w1
+ mov (up,i,8), %rax
+ adc $0, R32(w2)
+ mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 8(up,i,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 8(up,i,8), %rax
+ mul v1
+ add %rax, w2
+ mov w1, 8(rp,i,8)
+ adc %rdx, w3
+ mov $0, R32(w0)
+ mov 16(up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov 16(up,i,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+L(m2e2):mul v1
+ mov $0, R32(w1)
+ add %rax, w3
+ mov 24(up,i,8), %rax
+ mov w2, 16(rp,i,8)
+ adc %rdx, w0
+ add $4, i
+ js L(m2top2)
+
+ mul v0
+ add %rax, w3
+ mov I(-8(up),-8(up,i,8)), %rax
+ mov w3, I(-8(rp),-8(rp,i,8))
+ adc %rdx, w0
+ adc R32(w1), R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov w0, I((rp),(rp,i,8))
+ mov w1, I(8(rp),8(rp,i,8))
+
+ add $-2, vn_param
+ jz L(ret2)
+
+L(do_am2):
+ push %r15
+ push vn_param
+
+L(olo2):
+ mov (vp), v0
+ mov 8(vp), v1
+ lea 16(vp), vp
+ lea 16(rp), rp
+ mov (up,un,8), %rax
+ lea -2(un), i
+ mul v0
+ mov %rax, X0
+ MOV( %rdx, X1, 32)
+ mov (up,un,8), %rax
+ mov (rp,un,8), w0
+ mul v1
+ mov %rax, w1
+ lea (%rdx), w2
+ mov 8(up,un,8), %rax
+ jmp L(lo2)
+
+ ALIGNx
+L(am2top2):
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ mov (up,i,8), %rax
+ MOV( %rdx, w3, 1)
+ adc $0, w3
+ mul v0
+ add w1, X1
+ mov X1, -8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 2)
+ adc $0, X1
+ mov (up,i,8), %rax
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov (rp,i,8), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+ mov 8(up,i,8), %rax
+ mul v0
+ add w2, X0
+ adc %rax, X1
+ mov X0, (rp,i,8)
+ MOV( %rdx, X0, 8)
+ adc $0, X0
+ mov 8(up,i,8), %rax
+ mov 8(rp,i,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ MOV( %rdx, w1, 16)
+ adc $0, w1
+ mov 16(up,i,8), %rax
+ mul v0
+ add w3, X1
+ mov X1, 8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 32)
+ mov 16(rp,i,8), w3
+ adc $0, X1
+ mov 16(up,i,8), %rax
+ mul v1
+ add w3, w0
+ MOV( %rdx, w2, 64)
+ adc %rax, w1
+ mov 24(up,i,8), %rax
+ adc $0, w2
+L(lo2): mul v0
+ add w0, X0
+ mov X0, 16(rp,i,8)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov 24(up,i,8), %rax
+ mov 24(rp,i,8), w0
+ adc $0, X0
+ add $4, i
+ jnc L(am2top2)
+
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ adc Z(i,$0), %rdx
+ add w1, X1
+ adc Z(i,$0), X0
+ mov X1, I(-8(rp),-8(rp,i,8))
+ add w2, X0
+ mov X0, I((rp),(rp,i,8))
+ adc Z(i,$0), %rdx
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ addl $-2, vn
+ jnz L(olo2)
+
+ pop %rax
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+
+ ALIGNx
+L(m2top3):
+ mul v0
+ add %rax, w3
+ mov -8(up,i,8), %rax
+ mov w3, -8(rp,i,8)
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w0
+ mov w0, (rp,i,8)
+ adc %rdx, w1
+ mov (up,i,8), %rax
+ adc $0, R32(w2)
+ mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 8(up,i,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 8(up,i,8), %rax
+L(m2e3):mul v1
+ add %rax, w2
+ mov w1, 8(rp,i,8)
+ adc %rdx, w3
+ mov $0, R32(w0)
+ mov 16(up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov 16(up,i,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ mov $0, R32(w1)
+ add %rax, w3
+ mov 24(up,i,8), %rax
+ mov w2, 16(rp,i,8)
+ adc %rdx, w0
+ add $4, i
+ js L(m2top3)
+
+ mul v0
+ add %rax, w3
+ mov I(-8(up),-8(up,i,8)), %rax
+ mov w3, I(-8(rp),-8(rp,i,8))
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov w0, I((rp),(rp,i,8))
+ mov w1, I(8(rp),8(rp,i,8))
+
+ add $-2, vn_param
+ jz L(ret2)
+
+L(do_am3):
+ push %r15
+ push vn_param
+
+L(olo3):
+ mov (vp), v0
+ mov 8(vp), v1
+ lea 16(vp), vp
+ lea 16(rp), rp
+ mov (up,un,8), %rax
+ lea -1(un), i
+ mul v0
+ mov %rax, X1
+ MOV( %rdx, X0, 8)
+ mov (up,un,8), %rax
+ mov (rp,un,8), w3
+ mul v1
+ mov %rax, w0
+ MOV( %rdx, w1, 16)
+ mov 8(up,un,8), %rax
+ jmp L(lo3)
+
+ ALIGNx
+L(am2top3):
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ mov (up,i,8), %rax
+ MOV( %rdx, w3, 1)
+ adc $0, w3
+ mul v0
+ add w1, X1
+ mov X1, -8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 2)
+ adc $0, X1
+ mov (up,i,8), %rax
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov (rp,i,8), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+ mov 8(up,i,8), %rax
+ mul v0
+ add w2, X0
+ adc %rax, X1
+ mov X0, (rp,i,8)
+ MOV( %rdx, X0, 8)
+ adc $0, X0
+ mov 8(up,i,8), %rax
+ mov 8(rp,i,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ MOV( %rdx, w1, 16)
+ adc $0, w1
+ mov 16(up,i,8), %rax
+L(lo3): mul v0
+ add w3, X1
+ mov X1, 8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 32)
+ mov 16(rp,i,8), w3
+ adc $0, X1
+ mov 16(up,i,8), %rax
+ mul v1
+ add w3, w0
+ MOV( %rdx, w2, 64)
+ adc %rax, w1
+ mov 24(up,i,8), %rax
+ adc $0, w2
+ mul v0
+ add w0, X0
+ mov X0, 16(rp,i,8)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov 24(up,i,8), %rax
+ mov 24(rp,i,8), w0
+ adc $0, X0
+ add $4, i
+ jnc L(am2top3)
+
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ adc Z(i,$0), %rdx
+ add w1, X1
+ adc Z(i,$0), X0
+ mov X1, I(-8(rp),-8(rp,i,8))
+ add w2, X0
+ mov X0, I((rp),(rp,i,8))
+ adc Z(i,$0), %rdx
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ addl $-2, vn
+ jnz L(olo3)
+
+ pop %rax
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/mullo_basecase.asm b/gmp/mpn/x86_64/core2/mullo_basecase.asm
new file mode 100644
index 0000000000..0f03d867f6
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/mullo_basecase.asm
@@ -0,0 +1,427 @@
+dnl AMD64 mpn_mullo_basecase optimised for Conroe/Wolfdale/Nehalem/Westmere.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2008, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_2 addmul_2
+C AMD K8,K9
+C AMD K10
+C AMD bull
+C AMD pile
+C AMD steam
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core 4.0 4.18-4.25
+C Intel NHM 3.75 4.06-4.2
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Implement proper cor2, replacing current cor0.
+C * Offset n by 2 in order to avoid the outer loop cmp. (And sqr_basecase?)
+C * Micro-optimise.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp_param', `%rdx')
+define(`n_param', `%rcx')
+
+define(`v0', `%r10')
+define(`v1', `%r11')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r12')
+define(`n', `%r9')
+define(`i', `%r13')
+define(`vp', `%r8')
+
+define(`X0', `%r14')
+define(`X1', `%r15')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+define(`ALIGNx', `ALIGN(16)')
+
+define(`N', 85)
+ifdef(`N',,`define(`N',0)')
+define(`MOV', `ifelse(eval(N & $3),0,`mov $1, $2',`lea ($1), $2')')
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mullo_basecase)
+ FUNC_ENTRY(4)
+
+ mov (up), %rax
+ mov vp_param, vp
+
+ cmp $4, n_param
+ jb L(small)
+
+ mov (vp_param), v0
+ push %rbx
+ lea (rp,n_param,8), rp C point rp at R[un]
+ push %rbp
+ lea (up,n_param,8), up C point up right after U's end
+ push %r12
+ mov $0, R32(n) C FIXME
+ sub n_param, n
+ push %r13
+ mul v0
+ mov 8(vp), v1
+
+ test $1, R8(n_param)
+ jnz L(m2x1)
+
+L(m2x0):test $2, R8(n_param)
+ jnz L(m2b2)
+
+L(m2b0):lea (n), i
+ mov %rax, (rp,n,8)
+ mov %rdx, w1
+ mov (up,n,8), %rax
+ xor R32(w2), R32(w2)
+ jmp L(m2e0)
+
+L(m2b2):lea -2(n), i
+ mov %rax, w2
+ mov (up,n,8), %rax
+ mov %rdx, w3
+ xor R32(w0), R32(w0)
+ jmp L(m2e2)
+
+L(m2x1):test $2, R8(n_param)
+ jnz L(m2b3)
+
+L(m2b1):lea 1(n), i
+ mov %rax, (rp,n,8)
+ mov (up,n,8), %rax
+ mov %rdx, w0
+ xor R32(w1), R32(w1)
+ jmp L(m2e1)
+
+L(m2b3):lea -1(n), i
+ xor R32(w3), R32(w3)
+ mov %rax, w1
+ mov %rdx, w2
+ mov (up,n,8), %rax
+ jmp L(m2e3)
+
+ ALIGNx
+L(m2tp):mul v0
+ add %rax, w3
+ mov -8(up,i,8), %rax
+ mov w3, -8(rp,i,8)
+ adc %rdx, w0
+ adc $0, R32(w1)
+L(m2e1):mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w0
+ mov w0, (rp,i,8)
+ adc %rdx, w1
+ mov (up,i,8), %rax
+ adc $0, R32(w2)
+L(m2e0):mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 8(up,i,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 8(up,i,8), %rax
+L(m2e3):mul v1
+ add %rax, w2
+ mov w1, 8(rp,i,8)
+ adc %rdx, w3
+ mov $0, R32(w0)
+ mov 16(up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov 16(up,i,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+L(m2e2):mul v1
+ mov $0, R32(w1) C FIXME: dead in last iteration
+ add %rax, w3
+ mov 24(up,i,8), %rax
+ mov w2, 16(rp,i,8)
+ adc %rdx, w0 C FIXME: dead in last iteration
+ add $4, i
+ js L(m2tp)
+
+L(m2ed):imul v0, %rax
+ add w3, %rax
+ mov %rax, I(-8(rp),-8(rp,i,8))
+
+ add $2, n
+ lea 16(vp), vp
+ lea -16(up), up
+ cmp $-2, n
+ jge L(cor1)
+
+ push %r14
+ push %r15
+
+L(outer):
+ mov (vp), v0
+ mov 8(vp), v1
+ mov (up,n,8), %rax
+ mul v0
+ test $1, R8(n)
+ jnz L(a1x1)
+
+L(a1x0):mov %rax, X1
+ MOV( %rdx, X0, 8)
+ mov (up,n,8), %rax
+ mul v1
+ test $2, R8(n)
+ jnz L(a110)
+
+L(a100):lea (n), i
+ mov (rp,n,8), w3
+ mov %rax, w0
+ MOV( %rdx, w1, 16)
+ jmp L(lo0)
+
+L(a110):lea 2(n), i
+ mov (rp,n,8), w1
+ mov %rax, w2
+ mov 8(up,n,8), %rax
+ MOV( %rdx, w3, 1)
+ jmp L(lo2)
+
+L(a1x1):mov %rax, X0
+ MOV( %rdx, X1, 2)
+ mov (up,n,8), %rax
+ mul v1
+ test $2, R8(n)
+ jz L(a111)
+
+L(a101):lea 1(n), i
+ MOV( %rdx, w0, 4)
+ mov (rp,n,8), w2
+ mov %rax, w3
+ jmp L(lo1)
+
+L(a111):lea -1(n), i
+ MOV( %rdx, w2, 64)
+ mov %rax, w1
+ mov (rp,n,8), w0
+ mov 8(up,n,8), %rax
+ jmp L(lo3)
+
+ ALIGNx
+L(top): mul v1
+ add w0, w1
+ adc %rax, w2
+ mov -8(up,i,8), %rax
+ MOV( %rdx, w3, 1)
+ adc $0, w3
+L(lo2): mul v0
+ add w1, X1
+ mov X1, -16(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 2)
+ adc $0, X1
+ mov -8(up,i,8), %rax
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov -8(rp,i,8), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+L(lo1): mov (up,i,8), %rax
+ mul v0
+ add w2, X0
+ adc %rax, X1
+ mov X0, -8(rp,i,8)
+ MOV( %rdx, X0, 8)
+ adc $0, X0
+ mov (up,i,8), %rax
+ mov (rp,i,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ MOV( %rdx, w1, 16)
+ adc $0, w1
+L(lo0): mov 8(up,i,8), %rax
+ mul v0
+ add w3, X1
+ mov X1, (rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 32)
+ mov 8(rp,i,8), w3
+ adc $0, X1
+ mov 8(up,i,8), %rax
+ mul v1
+ add w3, w0
+ MOV( %rdx, w2, 64)
+ adc %rax, w1
+ mov 16(up,i,8), %rax
+ adc $0, w2
+L(lo3): mul v0
+ add w0, X0
+ mov X0, 8(rp,i,8)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov 16(up,i,8), %rax
+ mov 16(rp,i,8), w0
+ adc $0, X0
+ add $4, i
+ jnc L(top)
+
+L(end): imul v1, %rax
+ add w0, w1
+ adc %rax, w2
+ mov I(-8(up),-8(up,i,8)), %rax
+ imul v0, %rax
+ add w1, X1
+ mov X1, I(-16(rp),-16(rp,i,8))
+ adc X0, %rax
+ mov I(-8(rp),-8(rp,i,8)), w1
+ add w1, w2
+ add w2, %rax
+ mov %rax, I(-8(rp),-8(rp,i,8))
+
+ add $2, n
+ lea 16(vp), vp
+ lea -16(up), up
+ cmp $-2, n
+ jl L(outer)
+
+ pop %r15
+ pop %r14
+
+ jnz L(cor0)
+
+L(cor1):mov (vp), v0
+ mov 8(vp), v1
+ mov -16(up), %rax
+ mul v0 C u0 x v2
+ add -16(rp), %rax C FIXME: rp[0] still available in reg?
+ adc -8(rp), %rdx C FIXME: rp[1] still available in reg?
+ mov -8(up), %rbx
+ imul v0, %rbx
+ mov -16(up), %rcx
+ imul v1, %rcx
+ mov %rax, -16(rp)
+ add %rbx, %rcx
+ add %rdx, %rcx
+ mov %rcx, -8(rp)
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(cor0):mov (vp), %r11
+ imul -8(up), %r11
+ add %rax, %r11
+ mov %r11, -8(rp)
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(small):
+ cmp $2, n_param
+ jae L(gt1)
+L(n1): imul (vp_param), %rax
+ mov %rax, (rp)
+ FUNC_EXIT()
+ ret
+L(gt1): ja L(gt2)
+L(n2): mov (vp_param), %r9
+ mul %r9
+ mov %rax, (rp)
+ mov 8(up), %rax
+ imul %r9, %rax
+ add %rax, %rdx
+ mov 8(vp), %r9
+ mov (up), %rcx
+ imul %r9, %rcx
+ add %rcx, %rdx
+ mov %rdx, 8(rp)
+ FUNC_EXIT()
+ ret
+L(gt2):
+L(n3): mov (vp_param), %r9
+ mul %r9 C u0 x v0
+ mov %rax, (rp)
+ mov %rdx, %r10
+ mov 8(up), %rax
+ mul %r9 C u1 x v0
+ imul 16(up), %r9 C u2 x v0
+ add %rax, %r10
+ adc %rdx, %r9
+ mov 8(vp), %r11
+ mov (up), %rax
+ mul %r11 C u0 x v1
+ add %rax, %r10
+ adc %rdx, %r9
+ imul 8(up), %r11 C u1 x v1
+ add %r11, %r9
+ mov %r10, 8(rp)
+ mov 16(vp), %r10
+ mov (up), %rax
+ imul %rax, %r10 C u0 x v2
+ add %r10, %r9
+ mov %r9, 16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/popcount.asm b/gmp/mpn/x86_64/core2/popcount.asm
new file mode 100644
index 0000000000..e935cf1892
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/popcount.asm
@@ -0,0 +1,35 @@
+dnl x86-64 mpn_popcount optimized for "Core 2".
+
+dnl Copyright 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_popcount)
+include_mpn(`x86/pentium4/sse2/popcount.asm')
diff --git a/gmp/mpn/x86_64/core2/redc_1.asm b/gmp/mpn/x86_64/core2/redc_1.asm
new file mode 100644
index 0000000000..d0e96ef1cb
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/redc_1.asm
@@ -0,0 +1,425 @@
+dnl X86-64 mpn_redc_1 optimised for Intel Conroe and Wolfdale.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C AMD bull ?
+C AMD pile ?
+C AMD steam ?
+C AMD bobcat ?
+C AMD jaguar ?
+C Intel P4 ?
+C Intel core 4.5 (fluctuating)
+C Intel NHM ?
+C Intel SBR ?
+C Intel IBR ?
+C Intel HWL ?
+C Intel BWL ?
+C Intel atom ?
+C VIA nano ?
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Micro-optimise, none performed thus far.
+C * Consider inlining mpn_add_n.
+C * Single basecases out before the pushes.
+C * Keep up[i] in registers for basecases (might require pushes).
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`mp_param', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`u0inv', `%r8') C stack
+
+define(`i', `%r14')
+define(`j', `%r15')
+define(`mp', `%r12')
+define(`q0', `%r13')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+C X q0' n X rp up u0i mp q0 i j
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+define(`ALIGNx', `ALIGN(16)')
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_redc_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov (up), q0
+ mov n, j C outer loop induction var
+ lea (mp_param,n,8), mp
+ lea -16(up,n,8), up
+ neg n
+ imul u0inv, q0 C first iteration q0
+
+ test $1, R8(n)
+ jz L(b0)
+
+L(b1): cmp $-1, R32(n)
+ jz L(n1)
+ cmp $-3, R32(n)
+ jz L(n3)
+
+ push rp
+
+L(otp1):lea 3(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ lea (%rax), %rbp
+ mov 8(mp,n,8), %rax
+ lea (%rdx), %r9
+ mul q0
+ lea (%rax), %r11
+ mov 16(mp,n,8), %rax
+ mov 16(up,n,8), %r10
+ lea (%rdx), %rdi
+ mul q0
+ add %rbp, %r10
+ lea (%rax), %rbp
+ mov 24(mp,n,8), %rax
+ adc %r9, %r11
+ mov 24(up,n,8), %rbx
+ lea (%rdx), %r9
+ adc $0, %rdi
+ mul q0
+ add %r11, %rbx
+ lea (%rax), %r11
+ mov 32(mp,n,8), %rax
+ adc %rdi, %rbp
+ mov %rbx, 24(up,n,8)
+ mov 32(up,n,8), %r10
+ lea (%rdx), %rdi
+ adc $0, %r9
+ imul u0inv, %rbx C next q limb
+ add $2, i
+ jns L(ed1)
+
+ ALIGNx
+L(tp1): mul q0
+ add %rbp, %r10
+ lea (%rax), %rbp
+ mov (mp,i,8), %rax
+ adc %r9, %r11
+ mov %r10, -8(up,i,8)
+ mov (up,i,8), %r10
+ lea (%rdx), %r9
+ adc $0, %rdi
+ mul q0
+ add %r11, %r10
+ lea (%rax), %r11
+ mov 8(mp,i,8), %rax
+ adc %rdi, %rbp
+ mov %r10, (up,i,8)
+ mov 8(up,i,8), %r10
+ lea (%rdx), %rdi
+ adc $0, %r9
+ add $2, i
+ js L(tp1)
+
+L(ed1): mul q0
+ add %rbp, %r10
+ adc %r9, %r11
+ mov %r10, I(-8(up),-8(up,i,8))
+ mov I((up),(up,i,8)), %r10
+ adc $0, %rdi
+ add %r11, %r10
+ adc %rdi, %rax
+ mov %r10, I((up),(up,i,8))
+ mov I(8(up),8(up,i,8)), %r10
+ adc $0, %rdx
+ add %rax, %r10
+ mov %r10, I(8(up),8(up,i,8))
+ adc $0, %rdx
+ mov %rdx, 16(up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp1)
+ jmp L(cj)
+
+L(b0): cmp $-2, R32(n)
+ jz L(n2)
+ cmp $-4, R32(n)
+ jz L(n4)
+
+ push rp
+
+L(otp0):lea 4(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ lea (%rax), %r11
+ mov 8(mp,n,8), %rax
+ lea (%rdx), %rdi
+ mul q0
+ lea (%rax), %rbp
+ mov 16(mp,n,8), %rax
+ mov 16(up,n,8), %r10
+ lea (%rdx), %r9
+ mul q0
+ add %r11, %r10
+ lea (%rax), %r11
+ mov 24(mp,n,8), %rax
+ adc %rdi, %rbp
+ mov 24(up,n,8), %rbx
+ lea (%rdx), %rdi
+ adc $0, %r9
+ mul q0
+ add %rbp, %rbx
+ lea (%rax), %rbp
+ mov 32(mp,n,8), %rax
+ adc %r9, %r11
+ mov %rbx, 24(up,n,8)
+ mov 32(up,n,8), %r10
+ lea (%rdx), %r9
+ adc $0, %rdi
+ imul u0inv, %rbx C next q limb
+ jmp L(e0)
+
+ ALIGNx
+L(tp0): mul q0
+ add %rbp, %r10
+ lea (%rax), %rbp
+ mov (mp,i,8), %rax
+ adc %r9, %r11
+ mov %r10, -8(up,i,8)
+ mov (up,i,8), %r10
+ lea (%rdx), %r9
+ adc $0, %rdi
+L(e0): mul q0
+ add %r11, %r10
+ lea (%rax), %r11
+ mov 8(mp,i,8), %rax
+ adc %rdi, %rbp
+ mov %r10, (up,i,8)
+ mov 8(up,i,8), %r10
+ lea (%rdx), %rdi
+ adc $0, %r9
+ add $2, i
+ js L(tp0)
+
+L(ed0): mul q0
+ add %rbp, %r10
+ adc %r9, %r11
+ mov %r10, I(-8(up),-8(up,i,8))
+ mov I((up),(up,i,8)), %r10
+ adc $0, %rdi
+ add %r11, %r10
+ adc %rdi, %rax
+ mov %r10, I((up),(up,i,8))
+ mov I(8(up),8(up,i,8)), %r10
+ adc $0, %rdx
+ add %rax, %r10
+ mov %r10, I(8(up),8(up,i,8))
+ adc $0, %rdx
+ mov %rdx, 16(up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp0)
+
+L(cj): lea 16(up), up C FIXME
+ pop rp
+L(add_n):
+IFSTD(` lea (up,n,8), up C param 2: up
+ lea (up,n,8), %rdx C param 3: up - n
+ neg R32(n) ') C param 4: n
+
+IFDOS(` lea (up,n,8), %rdx C param 2: up
+ lea (%rdx,n,8), %r8 C param 3: up - n
+ neg R32(n)
+ mov n, %r9 C param 4: n
+ mov rp, %rcx ') C param 1: rp
+
+ CALL( mpn_add_n)
+
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(n1): mov (mp_param), %rax
+ mul q0
+ add 8(up), %rax
+ adc 16(up), %rdx
+ mov %rdx, (rp)
+ mov $0, R32(%rax)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+L(n2): mov (mp_param), %rax
+ mov (up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ mov 8(up), %r10
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, q0
+ imul u0inv, q0 C next q0
+ mov -16(mp), %rax
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ mov 16(up), %r14
+ mul q0
+ add %rax, %r14
+ adc $0, %rdx
+ add %r9, %r14
+ adc $0, %rdx
+ xor R32(%rax), R32(%rax)
+ add %r11, %r14
+ adc 24(up), %rdx
+ mov %r14, (rp)
+ mov %rdx, 8(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+ ALIGNx
+L(n3): mov -24(mp), %rax
+ mov -8(up), %r10
+ mul q0
+ add %rax, %r10
+ mov -16(mp), %rax
+ mov %rdx, %r11
+ adc $0, %r11
+ mov (up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ add %r11, %rbp
+ mov 8(up), %r10
+ adc $0, %r9
+ mul q0
+ mov %rbp, q0
+ imul u0inv, q0 C next q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ mov %rbp, (up)
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, 8(up)
+ mov %r11, -8(up) C up[0]
+ lea 8(up), up C up++
+ dec j
+ jnz L(n3)
+
+ mov -32(up), %rdx
+ mov -24(up), %rbx
+ xor R32(%rax), R32(%rax)
+ add %rbp, %rdx
+ adc %r10, %rbx
+ adc 8(up), %r11
+ mov %rdx, (rp)
+ mov %rbx, 8(rp)
+ mov %r11, 16(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+ ALIGNx
+L(n4): mov -32(mp), %rax
+ mul q0
+ lea (%rax), %r11
+ mov -24(mp), %rax
+ lea (%rdx), %r14
+ mul q0
+ lea (%rax), %rbp
+ mov -16(mp), %rax
+ mov -16(up), %r10
+ lea (%rdx), %r9
+ mul q0
+ add %r11, %r10
+ lea (%rax), %r11
+ mov -8(mp), %rax
+ adc %r14, %rbp
+ mov -8(up), %rbx
+ lea (%rdx), %r14
+ adc $0, %r9
+ mul q0
+ add %rbp, %rbx
+ adc %r9, %r11
+ mov %rbx, -8(up)
+ mov (up), %r10
+ adc $0, %r14
+ imul u0inv, %rbx C next q limb
+ add %r11, %r10
+ adc %r14, %rax
+ mov %r10, (up)
+ mov 8(up), %r10
+ adc $0, %rdx
+ add %rax, %r10
+ mov %r10, 8(up)
+ adc $0, %rdx
+ mov %rdx, -16(up) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(n4)
+ lea 16(up), up
+ jmp L(add_n)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/core2/rsh1aors_n.asm b/gmp/mpn/x86_64/core2/rsh1aors_n.asm
new file mode 100644
index 0000000000..27eed3712d
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/rsh1aors_n.asm
@@ -0,0 +1,169 @@
+dnl X86-64 mpn_rsh1add_n, mpn_rsh1sub_n optimised for Intel Conroe/Penryn.
+
+dnl Copyright 2003, 2005, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 3.05
+C Intel NHM 3.3
+C Intel SBR 2.5
+C Intel atom ?
+C VIA nano ?
+
+C TODO
+C * Loopmix to approach 2.5 c/l on NHM.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+
+ifdef(`OPERATION_rsh1add_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func_n, mpn_rsh1add_n)
+ define(func_nc, mpn_rsh1add_nc)')
+ifdef(`OPERATION_rsh1sub_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func_n, mpn_rsh1sub_n)
+ define(func_nc, mpn_rsh1sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_rsh1add_n mpn_rsh1add_nc mpn_rsh1sub_n mpn_rsh1sub_nc)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbx
+ push %rbp
+
+ neg %r8 C set C flag from parameter
+ mov (up), %r8
+ ADCSBB (vp), %r8
+ jmp L(ent)
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(func_n)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov (up), %r8
+ ADDSUB (vp), %r8
+L(ent): sbb R32(%rbx), R32(%rbx) C save cy
+ mov %r8, %rax
+ and $1, R32(%rax) C return value
+
+ lea (up,n,8), up
+ lea (vp,n,8), vp
+ lea (rp,n,8), rp
+ mov R32(n), R32(%rbp)
+ neg n
+ and $3, R32(%rbp)
+ jz L(b0)
+ cmp $2, R32(%rbp)
+ jae L(n1)
+
+L(b1): mov %r8, %rbp
+ inc n
+ js L(top)
+ jmp L(end)
+
+L(n1): jnz L(b3)
+ add R32(%rbx), R32(%rbx) C restore cy
+ mov 8(up,n,8), %r11
+ ADCSBB 8(vp,n,8), %r11
+ sbb R32(%rbx), R32(%rbx) C save cy
+ mov %r8, %r10
+ add $-2, n
+ jmp L(2)
+
+L(b3): add R32(%rbx), R32(%rbx) C restore cy
+ mov 8(up,n,8), %r10
+ mov 16(up,n,8), %r11
+ ADCSBB 8(vp,n,8), %r10
+ ADCSBB 16(vp,n,8), %r11
+ sbb R32(%rbx), R32(%rbx) C save cy
+ mov %r8, %r9
+ dec n
+ jmp L(3)
+
+L(b0): add R32(%rbx), R32(%rbx) C restore cy
+ mov 8(up,n,8), %r9
+ mov 16(up,n,8), %r10
+ mov 24(up,n,8), %r11
+ ADCSBB 8(vp,n,8), %r9
+ ADCSBB 16(vp,n,8), %r10
+ ADCSBB 24(vp,n,8), %r11
+ sbb R32(%rbx), R32(%rbx) C save cy
+ jmp L(4)
+
+ ALIGN(16)
+
+L(top): add R32(%rbx), R32(%rbx) C restore cy
+ mov (up,n,8), %r8
+ mov 8(up,n,8), %r9
+ mov 16(up,n,8), %r10
+ mov 24(up,n,8), %r11
+ ADCSBB (vp,n,8), %r8
+ ADCSBB 8(vp,n,8), %r9
+ ADCSBB 16(vp,n,8), %r10
+ ADCSBB 24(vp,n,8), %r11
+ sbb R32(%rbx), R32(%rbx) C save cy
+ shrd $1, %r8, %rbp
+ mov %rbp, -8(rp,n,8)
+L(4): shrd $1, %r9, %r8
+ mov %r8, (rp,n,8)
+L(3): shrd $1, %r10, %r9
+ mov %r9, 8(rp,n,8)
+L(2): shrd $1, %r11, %r10
+ mov %r10, 16(rp,n,8)
+L(1): add $4, n
+ mov %r11, %rbp
+ js L(top)
+
+L(end): shrd $1, %rbx, %rbp
+ mov %rbp, -8(rp)
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/rshift.asm b/gmp/mpn/x86_64/core2/rshift.asm
new file mode 100644
index 0000000000..ab32ec85df
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/rshift.asm
@@ -0,0 +1,147 @@
+dnl x86-64 mpn_rshift optimized for "Core 2".
+
+dnl Copyright 2007, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 4.25
+C AMD K10 4.25
+C Intel P4 14.7
+C Intel core2 1.27
+C Intel NHM 1.375 (up to about n = 260, then 1.5)
+C Intel SBR 1.77
+C Intel atom ?
+C VIA nano ?
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_rshift)
+ FUNC_ENTRY(4)
+ mov R32(%rdx), R32(%rax)
+ and $3, R32(%rax)
+ jne L(nb00)
+L(b00): C n = 4, 8, 12, ...
+ mov (up), %r10
+ mov 8(up), %r11
+ xor R32(%rax), R32(%rax)
+ shrd R8(cnt), %r10, %rax
+ mov 16(up), %r8
+ lea 8(up), up
+ lea -24(rp), rp
+ sub $4, n
+ jmp L(00)
+
+L(nb00):C n = 1, 5, 9, ...
+ cmp $2, R32(%rax)
+ jae L(nb01)
+L(b01): mov (up), %r9
+ xor R32(%rax), R32(%rax)
+ shrd R8(cnt), %r9, %rax
+ sub $2, n
+ jb L(le1)
+ mov 8(up), %r10
+ mov 16(up), %r11
+ lea 16(up), up
+ lea -16(rp), rp
+ jmp L(01)
+L(le1): shr R8(cnt), %r9
+ mov %r9, (rp)
+ FUNC_EXIT()
+ ret
+
+L(nb01):C n = 2, 6, 10, ...
+ jne L(b11)
+L(b10): mov (up), %r8
+ mov 8(up), %r9
+ xor R32(%rax), R32(%rax)
+ shrd R8(cnt), %r8, %rax
+ sub $3, n
+ jb L(le2)
+ mov 16(up), %r10
+ lea 24(up), up
+ lea -8(rp), rp
+ jmp L(10)
+L(le2): shrd R8(cnt), %r9, %r8
+ mov %r8, (rp)
+ shr R8(cnt), %r9
+ mov %r9, 8(rp)
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(b11): C n = 3, 7, 11, ...
+ mov (up), %r11
+ mov 8(up), %r8
+ xor R32(%rax), R32(%rax)
+ shrd R8(cnt), %r11, %rax
+ mov 16(up), %r9
+ lea 32(up), up
+ sub $4, n
+ jb L(end)
+
+ ALIGN(16)
+L(top): shrd R8(cnt), %r8, %r11
+ mov -8(up), %r10
+ mov %r11, (rp)
+L(10): shrd R8(cnt), %r9, %r8
+ mov (up), %r11
+ mov %r8, 8(rp)
+L(01): shrd R8(cnt), %r10, %r9
+ mov 8(up), %r8
+ mov %r9, 16(rp)
+L(00): shrd R8(cnt), %r11, %r10
+ mov 16(up), %r9
+ mov %r10, 24(rp)
+ add $32, up
+ lea 32(rp), rp
+ sub $4, n
+ jnc L(top)
+
+L(end): shrd R8(cnt), %r8, %r11
+ mov %r11, (rp)
+ shrd R8(cnt), %r9, %r8
+ mov %r8, 8(rp)
+ shr R8(cnt), %r9
+ mov %r9, 16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/sec_tabselect.asm b/gmp/mpn/x86_64/core2/sec_tabselect.asm
new file mode 100644
index 0000000000..e4360341d9
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/sec_tabselect.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_sec_tabselect.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_sec_tabselect)
+include_mpn(`x86_64/fastsse/sec_tabselect.asm')
diff --git a/gmp/mpn/x86_64/core2/sqr_basecase.asm b/gmp/mpn/x86_64/core2/sqr_basecase.asm
new file mode 100644
index 0000000000..a112c1b52e
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/sqr_basecase.asm
@@ -0,0 +1,984 @@
+dnl X86-64 mpn_sqr_basecase optimised for Intel Nehalem/Westmere.
+dnl It also seems good for Conroe/Wolfdale.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_2 addmul_2 sqr_diag_addlsh1
+C AMD K8,K9
+C AMD K10
+C AMD bull
+C AMD pile
+C AMD steam
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core 4.9 4.18-4.25 3.87
+C Intel NHM 3.8 4.06-4.2 3.5
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C Code structure:
+C
+C
+C m_2(0m4) m_2(2m4) m_2(1m4) m_2(3m4)
+C | | | |
+C | | | |
+C | | | |
+C \|/ \|/ \|/ \|/
+C ____________ ____________
+C / \ / \
+C \|/ \ \|/ \
+C am_2(3m4) am_2(1m4) am_2(0m4) am_2(2m4)
+C \ /|\ \ /|\
+C \____________/ \____________/
+C \ /
+C \ /
+C \ /
+C tail(0m2) tail(1m2)
+C \ /
+C \ /
+C sqr_diag_addlsh1
+
+C TODO
+C * Tune. None done so far.
+C * Currently 2761 bytes, making it smaller would be nice.
+C * Consider using a jumptab-based entry sequence. One might even use a mask-
+C less sequence, if the table is large enough to support tuneup's needs.
+C The code would be, using non-PIC code,
+C lea tab(%rip),%rax; jmp *(n,%rax)
+C or,
+C lea tab(%rip),%rax; lea (%rip),%rbx; add (n,%rax),%rbx; jmp *%rbx
+C using PIC code. The table entries would be Ln1,Ln2,Ln3,Lm0,Lm1,Lm2,Lm3,..
+C with the last four entries repeated a safe number of times.
+C * Consider expanding feed-in code in order to avoid zeroing registers.
+C * Zero consistently with xor.
+C * Check if using "lea (reg),reg" should be done in more places; we have some
+C explicit "mov %rax,reg" now.
+C * Try zeroing with xor in m2 loops.
+C * Try re-rolling the m2 loops to avoid the current 9 insn code duplication
+C between loop header and wind-down code.
+C * Consider adc reg,reg instead of adc $0,reg in m2 loops. This save a byte.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+C Define this to $1 to use late loop index variable as zero, $2 to use an
+C explicit $0.
+define(`Z',`$1')
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n_param', `%rdx')
+
+define(`n', `%r8')
+
+define(`v0', `%r10')
+define(`v1', `%r11')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r9')
+define(`i', `%r13')
+
+define(`X0', `%r12')
+define(`X1', `%r14')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+define(`ALIGNx', `ALIGN(16)')
+
+define(`N', 85)
+ifdef(`N',,`define(`N',0)')
+define(`MOV', `ifelse(eval(N & $3),0,`mov $1, $2',`lea ($1), $2')')
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_sqr_basecase)
+ FUNC_ENTRY(3)
+
+ cmp $4, n_param
+ jl L(small)
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+
+ mov (up), v0
+ mov 8(up), %rax
+ mov %rax, v1
+
+ mov $1, R32(n)
+ sub n_param, n C n = -n_param+1
+ push n
+
+ lea (up,n_param,8), up
+ lea (rp,n_param,8), rp
+
+ mul v0
+
+ test $1, R8(n)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n)
+ mov %rax, (rp,n,8)
+ jnz L(b10)
+
+L(b00): lea (n), i C n = 5, 9, ...
+ mov %rdx, w1 C FIXME: Use lea?
+ xor R32(w2), R32(w2)
+ jmp L(m2e0)
+
+L(b10): lea 2(n), i C n = 7, 11, ...
+ mov 8(up,n,8), %rax
+ mov %rdx, w3 C FIXME: Use lea?
+ xor R32(w0), R32(w0)
+ xor R32(w1), R32(w1)
+ jmp L(m2e2)
+
+L(bx1): test $2, R8(n)
+ mov %rax, (rp,n,8)
+ jz L(b11)
+
+L(b01): lea 1(n), i C n = 6, 10, ...
+ mov %rdx, w0 C FIXME: Use lea?
+ xor R32(w1), R32(w1)
+ jmp L(m2e1)
+
+L(b11): lea -1(n), i C n = 4, 8, 12, ...
+ mov %rdx, w2 C FIXME: Use lea?
+ xor R32(w3), R32(w3)
+ jmp L(m2e3)
+
+
+ ALIGNx
+L(m2top1):
+ mul v0
+ add %rax, w3
+ mov -8(up,i,8), %rax
+ mov w3, -8(rp,i,8)
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+L(m2e1):mov $0, R32(w2)
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w0
+ mov w0, (rp,i,8)
+ adc %rdx, w1
+ mov (up,i,8), %rax
+ adc $0, R32(w2)
+ mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 8(up,i,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 8(up,i,8), %rax
+ mul v1
+ add %rax, w2
+ mov w1, 8(rp,i,8)
+ adc %rdx, w3
+ mov $0, R32(w0)
+ mov 16(up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov 16(up,i,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ mov $0, R32(w1)
+ add %rax, w3
+ mov 24(up,i,8), %rax
+ mov w2, 16(rp,i,8)
+ adc %rdx, w0
+ add $4, i
+ js L(m2top1)
+
+ mul v0
+ add %rax, w3
+ mov I(-8(up),-8(up,i,8)), %rax
+ mov w3, I(-8(rp),-8(rp,i,8))
+ adc %rdx, w0
+ adc R32(w1), R32(w1)
+ mul v1
+ add w0, %rax
+ adc w1, %rdx
+ mov %rax, I((rp),(rp,i,8))
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ lea 16(rp), rp
+ add $2, n C decrease |n|
+ jmp L(am2o3)
+
+ ALIGNx
+L(m2top3):
+ mul v0
+ add %rax, w3
+ mov -8(up,i,8), %rax
+ mov w3, -8(rp,i,8)
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w0
+ mov w0, (rp,i,8)
+ adc %rdx, w1
+ mov (up,i,8), %rax
+ adc $0, R32(w2)
+ mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 8(up,i,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 8(up,i,8), %rax
+ mul v1
+ add %rax, w2
+ mov w1, 8(rp,i,8)
+ adc %rdx, w3
+L(m2e3):mov $0, R32(w0)
+ mov 16(up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov 16(up,i,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ mov $0, R32(w1)
+ add %rax, w3
+ mov 24(up,i,8), %rax
+ mov w2, 16(rp,i,8)
+ adc %rdx, w0
+ add $4, i
+ js L(m2top3)
+
+ mul v0
+ add %rax, w3
+ mov I(-8(up),-8(up,i,8)), %rax
+ mov w3, I(-8(rp),-8(rp,i,8))
+ adc %rdx, w0
+ adc R32(w1), R32(w1)
+ mul v1
+ add w0, %rax
+ adc w1, %rdx
+ mov %rax, I((rp),(rp,i,8))
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ lea 16(rp), rp
+ add $2, n C decrease |n|
+ cmp $-1, n
+ jz L(cor1) C jumps iff entry n = 4
+
+L(am2o1):
+ mov -8(up,n,8), v0
+ mov (up,n,8), %rax
+ mov %rax, v1
+ lea 1(n), i
+ mul v0
+ mov %rax, X1
+ MOV( %rdx, X0, 128)
+ mov (rp,n,8), w1
+ xor R32(w2), R32(w2)
+ mov 8(up,n,8), %rax
+ xor R32(w3), R32(w3)
+ jmp L(lo1)
+
+ ALIGNx
+L(am2top1):
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ mov (up,i,8), %rax
+ MOV( %rdx, w3, 1)
+ adc $0, w3
+L(lo1): mul v0
+ add w1, X1
+ mov X1, -8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 2)
+ adc $0, X1
+ mov (up,i,8), %rax
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov (rp,i,8), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+ mov 8(up,i,8), %rax
+ mul v0
+ add w2, X0
+ adc %rax, X1
+ mov X0, (rp,i,8)
+ MOV( %rdx, X0, 8)
+ adc $0, X0
+ mov 8(up,i,8), %rax
+ mov 8(rp,i,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ MOV( %rdx, w1, 16)
+ adc $0, w1
+ mov 16(up,i,8), %rax
+ mul v0
+ add w3, X1
+ mov X1, 8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 32)
+ mov 16(rp,i,8), w3
+ adc $0, X1
+ mov 16(up,i,8), %rax
+ mul v1
+ add w3, w0
+ MOV( %rdx, w2, 64)
+ adc %rax, w1
+ mov 24(up,i,8), %rax
+ adc $0, w2
+ mul v0
+ add w0, X0
+ mov X0, 16(rp,i,8)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov 24(up,i,8), %rax
+ mov 24(rp,i,8), w0
+ adc $0, X0
+ add $4, i
+ jnc L(am2top1)
+
+ mul v1
+ add w0, w1
+ adc w2, %rax
+ adc Z(i,$0), %rdx
+ add w1, X1
+ adc Z(i,$0), X0
+ mov X1, I(-8(rp),-8(rp,i,8))
+ add X0, %rax
+ mov %rax, I((rp),(rp,i,8))
+ adc Z(i,$0), %rdx
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ lea 16(rp), rp
+ add $2, n
+
+L(am2o3):
+ mov -8(up,n,8), v0
+ mov (up,n,8), %rax
+ mov %rax, v1
+ lea -1(n), i
+ mul v0
+ mov %rax, X1
+ MOV( %rdx, X0, 8)
+ mov (rp,n,8), w3
+ xor R32(w0), R32(w0)
+ xor R32(w1), R32(w1)
+ mov 8(up,n,8), %rax
+ jmp L(lo3)
+
+ ALIGNx
+L(am2top3):
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ mov (up,i,8), %rax
+ MOV( %rdx, w3, 1)
+ adc $0, w3
+ mul v0
+ add w1, X1
+ mov X1, -8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 2)
+ adc $0, X1
+ mov (up,i,8), %rax
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov (rp,i,8), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+ mov 8(up,i,8), %rax
+ mul v0
+ add w2, X0
+ adc %rax, X1
+ mov X0, (rp,i,8)
+ MOV( %rdx, X0, 8)
+ adc $0, X0
+ mov 8(up,i,8), %rax
+ mov 8(rp,i,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ MOV( %rdx, w1, 16)
+ adc $0, w1
+ mov 16(up,i,8), %rax
+L(lo3): mul v0
+ add w3, X1
+ mov X1, 8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 32)
+ mov 16(rp,i,8), w3
+ adc $0, X1
+ mov 16(up,i,8), %rax
+ mul v1
+ add w3, w0
+ MOV( %rdx, w2, 64)
+ adc %rax, w1
+ mov 24(up,i,8), %rax
+ adc $0, w2
+ mul v0
+ add w0, X0
+ mov X0, 16(rp,i,8)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov 24(up,i,8), %rax
+ mov 24(rp,i,8), w0
+ adc $0, X0
+ add $4, i
+ jnc L(am2top3)
+
+ mul v1
+ add w0, w1
+ adc w2, %rax
+ adc Z(i,$0), %rdx
+ add w1, X1
+ adc Z(i,$0), X0
+ mov X1, I(-8(rp),-8(rp,i,8))
+ add X0, %rax
+ mov %rax, I((rp),(rp,i,8))
+ adc Z(i,$0), %rdx
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ lea 16(rp), rp
+ add $2, n
+ cmp $-1, n
+ jnz L(am2o1)
+
+L(cor1):pop n
+ mov %rdx, w3
+ mov -16(up), v0
+ mov -8(up), %rax
+ mul v0
+ add w3, %rax
+ adc $0, %rdx
+ mov %rax, -8(rp)
+ mov %rdx, (rp)
+ jmp L(sqr_diag_addlsh1)
+
+ ALIGNx
+L(m2top2):
+L(m2e2):mul v0
+ add %rax, w3
+ mov -8(up,i,8), %rax
+ mov w3, -8(rp,i,8)
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w0
+ mov w0, (rp,i,8)
+ adc %rdx, w1
+ mov (up,i,8), %rax
+ adc $0, R32(w2)
+ mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 8(up,i,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 8(up,i,8), %rax
+ mul v1
+ add %rax, w2
+ mov w1, 8(rp,i,8)
+ adc %rdx, w3
+ mov $0, R32(w0)
+ mov 16(up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov 16(up,i,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ mov $0, R32(w1)
+ add %rax, w3
+ mov 24(up,i,8), %rax
+ mov w2, 16(rp,i,8)
+ adc %rdx, w0
+ add $4, i
+ js L(m2top2)
+
+ mul v0
+ add %rax, w3
+ mov I(-8(up),-8(up,i,8)), %rax
+ mov w3, I(-8(rp),-8(rp,i,8))
+ adc %rdx, w0
+ adc R32(w1), R32(w1)
+ mul v1
+ add w0, %rax
+ adc w1, %rdx
+ mov %rax, I((rp),(rp,i,8))
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ lea 16(rp), rp
+ add $2, n C decrease |n|
+ jmp L(am2o0)
+
+ ALIGNx
+L(m2top0):
+ mul v0
+ add %rax, w3
+ mov -8(up,i,8), %rax
+ mov w3, -8(rp,i,8)
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w0
+ mov w0, (rp,i,8)
+ adc %rdx, w1
+ mov (up,i,8), %rax
+ adc $0, R32(w2)
+ mul v1
+ add %rax, w1
+ adc %rdx, w2
+L(m2e0):mov 8(up,i,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mov 8(up,i,8), %rax
+ mul v1
+ add %rax, w2
+ mov w1, 8(rp,i,8)
+ adc %rdx, w3
+ mov $0, R32(w0)
+ mov 16(up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov 16(up,i,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ mov $0, R32(w1)
+ add %rax, w3
+ mov 24(up,i,8), %rax
+ mov w2, 16(rp,i,8)
+ adc %rdx, w0
+ add $4, i
+ js L(m2top0)
+
+ mul v0
+ add %rax, w3
+ mov I(-8(up),-8(up,i,8)), %rax
+ mov w3, I(-8(rp),-8(rp,i,8))
+ adc %rdx, w0
+ adc R32(w1), R32(w1)
+ mul v1
+ add w0, %rax
+ adc w1, %rdx
+ mov %rax, I((rp),(rp,i,8))
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ lea 16(rp), rp
+ add $2, n C decrease |n|
+ cmp $-2, n
+ jz L(cor2) C jumps iff entry n = 5
+
+L(am2o2):
+ mov -8(up,n,8), v0
+ mov (up,n,8), %rax
+ mov %rax, v1
+ lea -2(n), i
+ mul v0
+ mov %rax, X0
+ MOV( %rdx, X1, 32)
+ mov (rp,n,8), w0
+ xor R32(w1), R32(w1)
+ xor R32(w2), R32(w2)
+ mov 8(up,n,8), %rax
+ jmp L(lo2)
+
+ ALIGNx
+L(am2top2):
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ mov (up,i,8), %rax
+ MOV( %rdx, w3, 1)
+ adc $0, w3
+ mul v0
+ add w1, X1
+ mov X1, -8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 2)
+ adc $0, X1
+ mov (up,i,8), %rax
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov (rp,i,8), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+ mov 8(up,i,8), %rax
+ mul v0
+ add w2, X0
+ adc %rax, X1
+ mov X0, (rp,i,8)
+ MOV( %rdx, X0, 8)
+ adc $0, X0
+ mov 8(up,i,8), %rax
+ mov 8(rp,i,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ MOV( %rdx, w1, 16)
+ adc $0, w1
+ mov 16(up,i,8), %rax
+ mul v0
+ add w3, X1
+ mov X1, 8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 32)
+ mov 16(rp,i,8), w3
+ adc $0, X1
+ mov 16(up,i,8), %rax
+ mul v1
+ add w3, w0
+ MOV( %rdx, w2, 64)
+ adc %rax, w1
+ mov 24(up,i,8), %rax
+ adc $0, w2
+L(lo2): mul v0
+ add w0, X0
+ mov X0, 16(rp,i,8)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov 24(up,i,8), %rax
+ mov 24(rp,i,8), w0
+ adc $0, X0
+ add $4, i
+ jnc L(am2top2)
+
+ mul v1
+ add w0, w1
+ adc w2, %rax
+ adc Z(i,$0), %rdx
+ add w1, X1
+ adc Z(i,$0), X0
+ mov X1, I(-8(rp),-8(rp,i,8))
+ add X0, %rax
+ mov %rax, I((rp),(rp,i,8))
+ adc Z(i,$0), %rdx
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ lea 16(rp), rp
+ add $2, n
+
+L(am2o0):
+ mov -8(up,n,8), v0
+ mov (up,n,8), %rax
+ mov %rax, v1
+ lea 0(n), i
+ mul v0
+ mov %rax, X0
+ MOV( %rdx, X1, 2)
+ xor R32(w0), R32(w0)
+ mov (rp,n,8), w2
+ xor R32(w3), R32(w3)
+ jmp L(lo0)
+
+ ALIGNx
+L(am2top0):
+ mul v1
+ add w0, w1
+ adc %rax, w2
+ mov (up,i,8), %rax
+ MOV( %rdx, w3, 1)
+ adc $0, w3
+ mul v0
+ add w1, X1
+ mov X1, -8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 2)
+ adc $0, X1
+ mov (up,i,8), %rax
+ mul v1
+ MOV( %rdx, w0, 4)
+ mov (rp,i,8), w1
+ add w1, w2
+ adc %rax, w3
+ adc $0, w0
+L(lo0): mov 8(up,i,8), %rax
+ mul v0
+ add w2, X0
+ adc %rax, X1
+ mov X0, (rp,i,8)
+ MOV( %rdx, X0, 8)
+ adc $0, X0
+ mov 8(up,i,8), %rax
+ mov 8(rp,i,8), w2
+ mul v1
+ add w2, w3
+ adc %rax, w0
+ MOV( %rdx, w1, 16)
+ adc $0, w1
+ mov 16(up,i,8), %rax
+ mul v0
+ add w3, X1
+ mov X1, 8(rp,i,8)
+ adc %rax, X0
+ MOV( %rdx, X1, 32)
+ mov 16(rp,i,8), w3
+ adc $0, X1
+ mov 16(up,i,8), %rax
+ mul v1
+ add w3, w0
+ MOV( %rdx, w2, 64)
+ adc %rax, w1
+ mov 24(up,i,8), %rax
+ adc $0, w2
+ mul v0
+ add w0, X0
+ mov X0, 16(rp,i,8)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov 24(up,i,8), %rax
+ mov 24(rp,i,8), w0
+ adc $0, X0
+ add $4, i
+ jnc L(am2top0)
+
+ mul v1
+ add w0, w1
+ adc w2, %rax
+ adc Z(i,$0), %rdx
+ add w1, X1
+ adc Z(i,$0), X0
+ mov X1, I(-8(rp),-8(rp,i,8))
+ add X0, %rax
+ mov %rax, I((rp),(rp,i,8))
+ adc Z(i,$0), %rdx
+ mov %rdx, I(8(rp),8(rp,i,8))
+
+ lea 16(rp), rp
+ add $2, n
+ cmp $-2, n
+ jnz L(am2o2)
+
+L(cor2):pop n
+ mov -24(up), v0
+ mov %rax, w2
+ mov %rdx, w0
+ mov -16(up), %rax
+ mov %rax, v1
+ mul v0
+ mov %rax, X0
+ MOV( %rdx, X1, 32)
+ mov -8(up), %rax
+ mul v0
+ add w2, X0
+ mov X0, -16(rp)
+ MOV( %rdx, X0, 128)
+ adc %rax, X1
+ mov -8(up), %rax
+ adc $0, X0
+ mul v1
+ add w0, X1
+ adc $0, X0
+ mov X1, -8(rp)
+ add X0, %rax
+ mov %rax, (rp)
+ adc $0, %rdx
+ mov %rdx, 8(rp)
+ lea 8(rp), rp
+
+L(sqr_diag_addlsh1):
+ mov -8(up,n,8), %rax
+ shl n
+ xor R32(%rbx), R32(%rbx)
+ mul %rax
+ mov 8(rp,n,8), %r11
+ lea (%rdx), %r10
+ mov 16(rp,n,8), %r9
+ add %r11, %r11
+ jmp L(dm)
+
+ ALIGNx
+L(dtop):mul %rax
+ add %r11, %r10
+ mov 8(rp,n,8), %r11
+ mov %r10, -8(rp,n,8)
+ adc %r9, %rax
+ lea (%rdx,%rbx), %r10
+ mov 16(rp,n,8), %r9
+ adc %r11, %r11
+L(dm): mov %rax, (rp,n,8)
+ mov (up,n,4), %rax
+ adc %r9, %r9
+ setc R8(%rbx)
+ add $2, n
+ js L(dtop)
+
+ mul %rax
+ add %r11, %r10
+ mov %r10, -8(rp)
+ adc %r9, %rax
+ lea (%rdx,%rbx), %r10
+ mov %rax, (rp)
+ adc $0, %r10
+ mov %r10, 8(rp)
+
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(small):
+ mov (up), %rax
+ cmp $2, n_param
+ jae L(gt1)
+L(n1):
+ mul %rax
+ mov %rax, (rp)
+ mov %rdx, 8(rp)
+ FUNC_EXIT()
+ ret
+
+L(gt1): jne L(gt2)
+L(n2): mov %rax, %r8
+ mul %rax
+ mov 8(up), %r11
+ mov %rax, (rp)
+ mov %r11, %rax
+ mov %rdx, %r9
+ mul %rax
+ mov %rax, %r10
+ mov %r11, %rax
+ mov %rdx, %r11
+ mul %r8
+ xor %r8, %r8
+ add %rax, %r9
+ adc %rdx, %r10
+ adc %r8, %r11
+ add %rax, %r9
+ mov %r9, 8(rp)
+ adc %rdx, %r10
+ mov %r10, 16(rp)
+ adc %r8, %r11
+ mov %r11, 24(rp)
+ FUNC_EXIT()
+ ret
+
+L(gt2):
+L(n3): mov %rax, %r10
+ mul %rax
+ mov 8(up), %r11
+ mov %rax, (rp)
+ mov %r11, %rax
+ mov %rdx, 8(rp)
+ mul %rax
+ mov 16(up), %rcx
+ mov %rax, 16(rp)
+ mov %rcx, %rax
+ mov %rdx, 24(rp)
+ mul %rax
+ mov %rax, 32(rp)
+ mov %rdx, 40(rp)
+
+ mov %r11, %rax
+ mul %r10
+ mov %rax, %r8
+ mov %rcx, %rax
+ mov %rdx, %r9
+ mul %r10
+ xor %r10, %r10
+ add %rax, %r9
+ mov %r11, %rax
+ mov %r10, %r11
+ adc %rdx, %r10
+
+ mul %rcx
+ add %rax, %r10
+ adc %r11, %rdx
+ add %r8, %r8
+ adc %r9, %r9
+ adc %r10, %r10
+ adc %rdx, %rdx
+ adc %r11, %r11
+ add %r8, 8(rp)
+ adc %r9, 16(rp)
+ adc %r10, 24(rp)
+ adc %rdx, 32(rp)
+ adc %r11, 40(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/core2/sublsh1_n.asm b/gmp/mpn/x86_64/core2/sublsh1_n.asm
new file mode 100644
index 0000000000..46488fcafe
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/sublsh1_n.asm
@@ -0,0 +1,47 @@
+dnl AMD64 mpn_sublsh1_n optimised for Core 2 and Core iN.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 1)
+define(RSH, 63)
+
+define(ADDSUB, sub)
+define(ADCSBB, sbb)
+define(func, mpn_sublsh1_n)
+
+MULFUNC_PROLOGUE(mpn_sublsh1_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+include_mpn(`x86_64/core2/sublshC_n.asm')
diff --git a/gmp/mpn/x86_64/core2/sublsh2_n.asm b/gmp/mpn/x86_64/core2/sublsh2_n.asm
new file mode 100644
index 0000000000..f3b1e28464
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/sublsh2_n.asm
@@ -0,0 +1,47 @@
+dnl AMD64 mpn_sublsh2_n optimised for Core 2 and Core iN.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 2)
+define(RSH, 62)
+
+define(ADDSUB, sub)
+define(ADCSBB, sbb)
+define(func, mpn_sublsh2_n)
+
+MULFUNC_PROLOGUE(mpn_sublsh2_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+include_mpn(`x86_64/core2/sublshC_n.asm')
diff --git a/gmp/mpn/x86_64/core2/sublshC_n.asm b/gmp/mpn/x86_64/core2/sublshC_n.asm
new file mode 100644
index 0000000000..5acc46b032
--- /dev/null
+++ b/gmp/mpn/x86_64/core2/sublshC_n.asm
@@ -0,0 +1,158 @@
+dnl AMD64 mpn_sublshC_n -- rp[] = up[] - (vp[] << 1), optimised for Core 2 and
+dnl Core iN.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+C cycles/limb
+C AMD K8,K9 4.25
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 3
+C Intel NHM 3.1
+C Intel SBR 2.47
+C Intel atom ?
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`vp',`%rdx')
+define(`n', `%rcx')
+
+ASM_START()
+ TEXT
+ ALIGN(8)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %r12
+
+ mov R32(%rcx), R32(%rax)
+ lea 24(up,n,8), up
+ lea 24(vp,n,8), vp
+ lea 24(rp,n,8), rp
+ neg n
+
+ xor R32(%r11), R32(%r11)
+
+ mov -24(vp,n,8), %r8 C do first limb early
+ shrd $RSH, %r8, %r11
+
+ and $3, R32(%rax)
+ je L(b0)
+ cmp $2, R32(%rax)
+ jc L(b1)
+ je L(b2)
+
+L(b3): mov -16(vp,n,8), %r9
+ shrd $RSH, %r9, %r8
+ mov -8(vp,n,8), %r10
+ shrd $RSH, %r10, %r9
+ mov -24(up,n,8), %r12
+ ADDSUB %r11, %r12
+ mov %r12, -24(rp,n,8)
+ mov -16(up,n,8), %r12
+ ADCSBB %r8, %r12
+ mov %r12, -16(rp,n,8)
+ mov -8(up,n,8), %r12
+ ADCSBB %r9, %r12
+ mov %r12, -8(rp,n,8)
+ mov %r10, %r11
+ sbb R32(%rax), R32(%rax) C save cy
+ add $3, n
+ js L(top)
+ jmp L(end)
+
+L(b1): mov -24(up,n,8), %r12
+ ADDSUB %r11, %r12
+ mov %r12, -24(rp,n,8)
+ mov %r8, %r11
+ sbb R32(%rax), R32(%rax) C save cy
+ inc n
+ js L(top)
+ jmp L(end)
+
+L(b2): mov -16(vp,n,8), %r9
+ shrd $RSH, %r9, %r8
+ mov -24(up,n,8), %r12
+ ADDSUB %r11, %r12
+ mov %r12, -24(rp,n,8)
+ mov -16(up,n,8), %r12
+ ADCSBB %r8, %r12
+ mov %r12, -16(rp,n,8)
+ mov %r9, %r11
+ sbb R32(%rax), R32(%rax) C save cy
+ add $2, n
+ js L(top)
+ jmp L(end)
+
+ ALIGN(16)
+L(top): mov -24(vp,n,8), %r8
+ shrd $RSH, %r8, %r11
+L(b0): mov -16(vp,n,8), %r9
+ shrd $RSH, %r9, %r8
+ mov -8(vp,n,8), %r10
+ shrd $RSH, %r10, %r9
+ mov (vp,n,8), %rbx
+ shrd $RSH, %rbx, %r10
+
+ add R32(%rax), R32(%rax) C restore cy
+
+ mov -24(up,n,8), %r12
+ ADCSBB %r11, %r12
+ mov %r12, -24(rp,n,8)
+
+ mov -16(up,n,8), %r12
+ ADCSBB %r8, %r12
+ mov %r12, -16(rp,n,8)
+
+ mov -8(up,n,8), %r12
+ ADCSBB %r9, %r12
+ mov %r12, -8(rp,n,8)
+
+ mov (up,n,8), %r12
+ ADCSBB %r10, %r12
+ mov %r12, (rp,n,8)
+
+ mov %rbx, %r11
+ sbb R32(%rax), R32(%rax) C save cy
+
+ add $4, n
+ js L(top)
+
+L(end): shr $RSH, %r11
+ pop %r12
+ pop %rbx
+ sub R32(%r11), R32(%rax)
+ neg R32(%rax)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreihwl/addmul_2.asm b/gmp/mpn/x86_64/coreihwl/addmul_2.asm
new file mode 100644
index 0000000000..54aebc888d
--- /dev/null
+++ b/gmp/mpn/x86_64/coreihwl/addmul_2.asm
@@ -0,0 +1,238 @@
+dnl AMD64 mpn_addmul_2 optimised for Intel Haswell.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 n/a
+C AMD K10 n/a
+C AMD bull n/a
+C AMD pile n/a
+C AMD steam ?
+C AMD bobcat n/a
+C AMD jaguar ?
+C Intel P4 n/a
+C Intel core n/a
+C Intel NHM n/a
+C Intel SBR n/a
+C Intel IBR n/a
+C Intel HWL 2.15
+C Intel BWL ?
+C Intel atom n/a
+C VIA nano n/a
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n_param',`%rdx')
+define(`vp', `%rcx')
+
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+define(`n', `%r11')
+define(`X0', `%r12')
+define(`X1', `%r13')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_addmul_2)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ mov n_param, n
+ shr $2, n
+
+ test $1, R8(n_param)
+ jnz L(bx1)
+
+L(bx0): mov (rp), X0
+ mov 8(rp), X1
+ test $2, R8(n_param)
+ jnz L(b10)
+
+L(b00): mov (up), %rdx
+ lea 16(up), up
+ mulx( v0, %rax, w1)
+ add %rax, X0
+ mulx( v1, %rax, w2)
+ adc $0, w1
+ mov X0, (rp)
+ add %rax, X1
+ adc $0, w2
+ mov -8(up), %rdx
+ lea 16(rp), rp
+ jmp L(lo0)
+
+L(b10): mov (up), %rdx
+ inc n
+ mulx( v0, %rax, w1)
+ add %rax, X0
+ adc $0, w1
+ mulx( v1, %rax, w2)
+ mov X0, (rp)
+ mov 16(rp), X0
+ add %rax, X1
+ adc $0, w2
+ xor w0, w0
+ jmp L(lo2)
+
+L(bx1): mov (rp), X1
+ mov 8(rp), X0
+ test $2, R8(n_param)
+ jnz L(b11)
+
+L(b01): mov (up), %rdx
+ mulx( v0, %rax, w3)
+ add %rax, X1
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ mov 8(up), %rdx
+ mov X1, (rp)
+ mov 16(rp), X1
+ mulx( v0, %rax, w1)
+ lea 24(rp), rp
+ lea 24(up), up
+ jmp L(lo1)
+
+L(b11): mov (up), %rdx
+ inc n
+ mulx( v0, %rax, w3)
+ add %rax, X1
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ mov X1, (rp)
+ mov 8(up), %rdx
+ mulx( v0, %rax, w1)
+ lea 8(rp), rp
+ lea 8(up), up
+ jmp L(lo3)
+
+ ALIGN(16)
+L(top): mulx( v0, %rax, w3)
+ add w0, X1
+ adc $0, w2
+ add %rax, X1
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ lea 32(rp), rp
+ add w1, X1
+ mov -16(up), %rdx
+ mov X1, -24(rp)
+ adc $0, w3
+ add w2, X0
+ mov -8(rp), X1
+ mulx( v0, %rax, w1)
+ adc $0, w0
+L(lo1): add %rax, X0
+ mulx( v1, %rax, w2)
+ adc $0, w1
+ add w3, X0
+ mov X0, -16(rp)
+ adc $0, w1
+ add %rax, X1
+ adc $0, w2
+ add w0, X1
+ mov -8(up), %rdx
+ adc $0, w2
+L(lo0): mulx( v0, %rax, w3)
+ add %rax, X1
+ adc $0, w3
+ mov (rp), X0
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ add w1, X1
+ mov X1, -8(rp)
+ adc $0, w3
+ mov (up), %rdx
+ add w2, X0
+ mulx( v0, %rax, w1)
+ adc $0, w0
+L(lo3): add %rax, X0
+ adc $0, w1
+ mulx( v1, %rax, w2)
+ add w3, X0
+ mov 8(rp), X1
+ mov X0, (rp)
+ mov 16(rp), X0
+ adc $0, w1
+ add %rax, X1
+ adc $0, w2
+L(lo2): mov 8(up), %rdx
+ lea 32(up), up
+ dec n
+ jnz L(top)
+
+L(end): mulx( v0, %rax, w3)
+ add w0, X1
+ adc $0, w2
+ add %rax, X1
+ adc $0, w3
+ mulx( v1, %rdx, %rax)
+ add w1, X1
+ mov X1, 8(rp)
+ adc $0, w3
+ add w2, %rdx
+ adc $0, %rax
+ add w3, %rdx
+ mov %rdx, 16(rp)
+ adc $0, %rax
+
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreihwl/aorsmul_1.asm b/gmp/mpn/x86_64/coreihwl/aorsmul_1.asm
new file mode 100644
index 0000000000..fd5a26d00f
--- /dev/null
+++ b/gmp/mpn/x86_64/coreihwl/aorsmul_1.asm
@@ -0,0 +1,198 @@
+dnl AMD64 mpn_addmul_1 and mpn_submul_1 optimised for Intel Haswell.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 n/a
+C AMD K10 n/a
+C AMD bull n/a
+C AMD pile n/a
+C AMD steam ?
+C AMD bobcat n/a
+C AMD jaguar ?
+C Intel P4 n/a
+C Intel core n/a
+C Intel NHM n/a
+C Intel SBR n/a
+C Intel IBR n/a
+C Intel HWL 2.32
+C Intel BWL ?
+C Intel atom n/a
+C VIA nano n/a
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Handle small n separately, for lower overhead.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0_param',`%rcx') C r9
+
+define(`n', `%rbp')
+define(`v0', `%rdx')
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`ADCSBB', `adc')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`ADCSBB', `sbb')
+ define(`func', `mpn_submul_1')
+')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+
+ mov n_param, n
+ mov v0_param, v0
+
+ test $1, R8(n)
+ jnz L(bx1)
+
+L(bx0): shr $2, n
+ jc L(b10)
+
+L(b00): mulx( (up), %r13, %r12)
+ mulx( 8,(up), %rbx, %rax)
+ add %r12, %rbx
+ adc $0, %rax
+ mov (rp), %r12
+ mov 8(rp), %rcx
+ mulx( 16,(up), %r9, %r8)
+ lea -16(rp), rp
+ lea 16(up), up
+ ADDSUB %r13, %r12
+ jmp L(lo0)
+
+L(bx1): shr $2, n
+ jc L(b11)
+
+L(b01): mulx( (up), %r11, %r10)
+ jnz L(gt1)
+L(n1): ADDSUB %r11, (rp)
+ mov $0, R32(%rax)
+ adc %r10, %rax
+ jmp L(ret)
+
+L(gt1): mulx( 8,(up), %r13, %r12)
+ mulx( 16,(up), %rbx, %rax)
+ lea 24(up), up
+ add %r10, %r13
+ adc %r12, %rbx
+ adc $0, %rax
+ mov (rp), %r10
+ mov 8(rp), %r12
+ mov 16(rp), %rcx
+ lea -8(rp), rp
+ ADDSUB %r11, %r10
+ jmp L(lo1)
+
+L(b11): mulx( (up), %rbx, %rax)
+ mov (rp), %rcx
+ mulx( 8,(up), %r9, %r8)
+ lea 8(up), up
+ lea -24(rp), rp
+ inc n C adjust n
+ ADDSUB %rbx, %rcx
+ jmp L(lo3)
+
+L(b10): mulx( (up), %r9, %r8)
+ mulx( 8,(up), %r11, %r10)
+ lea -32(rp), rp
+ mov $0, R32(%rax)
+ clc C clear cf
+ jz L(end) C depends on old shift
+
+ ALIGN(16)
+L(top): adc %rax, %r9
+ lea 32(rp), rp
+ adc %r8, %r11
+ mulx( 16,(up), %r13, %r12)
+ mov (rp), %r8
+ mulx( 24,(up), %rbx, %rax)
+ lea 32(up), up
+ adc %r10, %r13
+ adc %r12, %rbx
+ adc $0, %rax
+ mov 8(rp), %r10
+ mov 16(rp), %r12
+ ADDSUB %r9, %r8
+ mov 24(rp), %rcx
+ mov %r8, (rp)
+ ADCSBB %r11, %r10
+L(lo1): mulx( (up), %r9, %r8)
+ mov %r10, 8(rp)
+ ADCSBB %r13, %r12
+L(lo0): mov %r12, 16(rp)
+ ADCSBB %rbx, %rcx
+L(lo3): mulx( 8,(up), %r11, %r10)
+ mov %rcx, 24(rp)
+ dec n
+ jnz L(top)
+
+L(end): adc %rax, %r9
+ adc %r8, %r11
+ mov 32(rp), %r8
+ mov %r10, %rax
+ adc $0, %rax
+ mov 40(rp), %r10
+ ADDSUB %r9, %r8
+ mov %r8, 32(rp)
+ ADCSBB %r11, %r10
+ mov %r10, 40(rp)
+ adc $0, %rax
+
+L(ret): pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreihwl/gmp-mparam.h b/gmp/mpn/x86_64/coreihwl/gmp-mparam.h
new file mode 100644
index 0000000000..eef44b3a81
--- /dev/null
+++ b/gmp/mpn/x86_64/coreihwl/gmp-mparam.h
@@ -0,0 +1,237 @@
+/* Haswell gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 2900 MHz Core i5 Haswell */
+/* FFT tuning limit = 75000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 10
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 26
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 10
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 25
+
+#define MUL_TOOM22_THRESHOLD 22
+#define MUL_TOOM33_THRESHOLD 74
+#define MUL_TOOM44_THRESHOLD 195
+#define MUL_TOOM6H_THRESHOLD 298
+#define MUL_TOOM8H_THRESHOLD 406
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 121
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 138
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 128
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 132
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 170
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 34
+#define SQR_TOOM3_THRESHOLD 117
+#define SQR_TOOM4_THRESHOLD 336
+#define SQR_TOOM6_THRESHOLD 426
+#define SQR_TOOM8_THRESHOLD 562
+
+#define MULMID_TOOM42_THRESHOLD 42
+
+#define MULMOD_BNM1_THRESHOLD 13
+#define SQRMOD_BNM1_THRESHOLD 17
+
+#define MUL_FFT_MODF_THRESHOLD 376 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 376, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 21, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 21, 9}, { 11, 8}, \
+ { 27, 9}, { 15, 8}, { 35, 9}, { 19, 8}, \
+ { 39, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 55,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 83,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 79,11}, { 47,10}, { 95,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255,10}, \
+ { 135,11}, { 79,10}, { 159, 9}, { 319,10}, \
+ { 167,11}, { 95,10}, { 191, 9}, { 383,11}, \
+ { 111,12}, { 63,11}, { 127,10}, { 255, 9}, \
+ { 511,10}, { 271, 9}, { 543,11}, { 143,10}, \
+ { 287, 9}, { 575,10}, { 303, 9}, { 607,11}, \
+ { 159,10}, { 319, 9}, { 639,12}, { 95,11}, \
+ { 191,10}, { 383,11}, { 207,10}, { 415,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 271,10}, { 543, 9}, { 1087,11}, { 287,10}, \
+ { 607,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 335,10}, { 671,11}, { 351,10}, { 703,11}, \
+ { 367,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,10}, { 831,12}, { 223,11}, { 447,10}, \
+ { 895,11}, { 479,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087,12}, \
+ { 287,11}, { 575,10}, { 1151,11}, { 607,12}, \
+ { 319,11}, { 639,10}, { 1279,11}, { 671,12}, \
+ { 351,11}, { 703,10}, { 1407,11}, { 735,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,10}, { 1663,12}, { 447,11}, { 895,12}, \
+ { 479,14}, { 127,12}, { 511,11}, { 1023,12}, \
+ { 543,11}, { 1087,12}, { 575,11}, { 1151,12}, \
+ { 607,11}, { 1215,13}, { 319,12}, { 671,11}, \
+ { 1343,12}, { 703,11}, { 1407,12}, { 735,13}, \
+ { 383,12}, { 767,11}, { 1535,12}, { 831,13}, \
+ { 447,12}, { 959,11}, { 1919,13}, { 511,12}, \
+ { 1087,13}, { 575,12}, { 1215,13}, { 639,12}, \
+ { 1343,13}, { 703,12}, { 1407,11}, { 2815,14}, \
+ { 383,13}, { 767,12}, { 1535,13}, { 831,12}, \
+ { 1727,13}, { 959,12}, { 1919,14}, { 511,13}, \
+ { 1023,12}, { 2047,13}, { 1087,12}, { 2175,13}, \
+ { 1215,12}, { 2431,14}, { 639,13}, { 1279,12}, \
+ { 2559,13}, { 1343,12}, { 2687,13}, { 1407,12}, \
+ { 2815,13}, { 1471,12}, { 2943,14}, { 767,13}, \
+ { 1535,12}, { 3071,13}, { 1727,14}, { 895,13}, \
+ { 1791,12}, { 3583,13}, { 1919,15}, { 511,14}, \
+ { 1023,13}, { 2175,14}, { 1151,13}, { 2431,12}, \
+ { 4863,14}, { 1279,13}, { 2687,14}, { 1407,13}, \
+ { 2943,15}, { 767,14}, { 1535,13}, { 3199,14}, \
+ { 1663,13}, { 3455,12}, { 6911,14}, { 1791,13}, \
+ { 3583,14}, { 1919,16}, { 511,15}, { 1023,14}, \
+ { 2175,13}, { 4351,14}, { 2431,13}, { 4863,15}, \
+ { 1279,14}, { 2943,13}, { 5887,15}, { 1535,14}, \
+ { 3455,13}, { 6911,15}, { 1791,14}, { 3839,13}, \
+ { 7679,16}, { 1023,15}, { 2047,14}, { 4351,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 237
+#define MUL_FFT_THRESHOLD 4224
+
+#define SQR_FFT_MODF_THRESHOLD 344 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 344, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 10, 5}, { 21, 6}, { 21, 7}, { 11, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 21, 8}, \
+ { 11, 7}, { 25, 8}, { 13, 7}, { 28, 8}, \
+ { 15, 7}, { 31, 8}, { 21, 9}, { 11, 8}, \
+ { 27, 9}, { 15, 8}, { 35, 9}, { 19, 8}, \
+ { 41, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 51,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79,10}, { 55,11}, { 31,10}, { 79,11}, \
+ { 47,10}, { 95,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255, 8}, { 511,10}, { 135,11}, \
+ { 79,10}, { 159, 9}, { 319,11}, { 95,10}, \
+ { 191, 9}, { 383,11}, { 111,12}, { 63,11}, \
+ { 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
+ { 543,11}, { 143,10}, { 287, 9}, { 575,10}, \
+ { 303, 9}, { 607,11}, { 159,10}, { 319, 9}, \
+ { 639,12}, { 95,11}, { 191,10}, { 383, 9}, \
+ { 767,11}, { 207,10}, { 415,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 511,11}, { 271,10}, \
+ { 543, 9}, { 1087,10}, { 575,11}, { 303,10}, \
+ { 607,11}, { 319,10}, { 671,11}, { 351,10}, \
+ { 735,11}, { 383,10}, { 767,11}, { 415,10}, \
+ { 831,11}, { 447,10}, { 895,11}, { 479,13}, \
+ { 127,12}, { 255,11}, { 543,10}, { 1087,11}, \
+ { 607,10}, { 1215,11}, { 671,12}, { 351,11}, \
+ { 735,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,10}, { 1663,12}, { 447,11}, { 895,12}, \
+ { 479,14}, { 127,12}, { 511,11}, { 1023,12}, \
+ { 543,11}, { 1087,12}, { 607,11}, { 1215,13}, \
+ { 319,12}, { 639,11}, { 1279,12}, { 671,11}, \
+ { 1343,12}, { 735,13}, { 383,12}, { 767,11}, \
+ { 1535,12}, { 831,13}, { 447,12}, { 959,13}, \
+ { 511,12}, { 1087,13}, { 575,12}, { 1215,13}, \
+ { 639,12}, { 1343,13}, { 703,12}, { 1407,14}, \
+ { 383,13}, { 767,12}, { 1535,13}, { 831,12}, \
+ { 1663,13}, { 959,14}, { 511,13}, { 1087,12}, \
+ { 2175,13}, { 1215,12}, { 2431,14}, { 639,13}, \
+ { 1343,12}, { 2687,13}, { 1407,12}, { 2815,13}, \
+ { 1471,14}, { 767,13}, { 1599,12}, { 3199,13}, \
+ { 1663,14}, { 895,13}, { 1791,12}, { 3583,15}, \
+ { 511,14}, { 1023,13}, { 2175,14}, { 1151,13}, \
+ { 2431,12}, { 4863,14}, { 1279,13}, { 2687,14}, \
+ { 1407,13}, { 2815,15}, { 767,14}, { 1535,13}, \
+ { 3199,14}, { 1663,13}, { 3455,12}, { 6911,14}, \
+ { 1791,13}, { 3583,16}, { 511,15}, { 1023,14}, \
+ { 2431,13}, { 4863,15}, { 1279,14}, { 2943,13}, \
+ { 5887,15}, { 1535,14}, { 3455,13}, { 6911,15}, \
+ { 1791,14}, { 3839,16}, { 1023,15}, { 2047,14}, \
+ { 4223,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 206
+#define SQR_FFT_THRESHOLD 3712
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 78
+#define MULLO_MUL_N_THRESHOLD 8207
+
+#define DC_DIV_QR_THRESHOLD 63
+#define DC_DIVAPPR_Q_THRESHOLD 195
+#define DC_BDIV_QR_THRESHOLD 56
+#define DC_BDIV_Q_THRESHOLD 128
+
+#define INV_MULMOD_BNM1_THRESHOLD 42
+#define INV_NEWTON_THRESHOLD 199
+#define INV_APPR_THRESHOLD 181
+
+#define BINV_NEWTON_THRESHOLD 236
+#define REDC_1_TO_REDC_2_THRESHOLD 47
+#define REDC_2_TO_REDC_N_THRESHOLD 62
+
+#define MU_DIV_QR_THRESHOLD 1470
+#define MU_DIVAPPR_Q_THRESHOLD 1589
+#define MUPI_DIV_QR_THRESHOLD 78
+#define MU_BDIV_QR_THRESHOLD 1442
+#define MU_BDIV_Q_THRESHOLD 1470
+
+#define POWM_SEC_TABLE 3,22,194,257,1099
+
+#define MATRIX22_STRASSEN_THRESHOLD 17
+#define HGCD_THRESHOLD 112
+#define HGCD_APPR_THRESHOLD 52
+#define HGCD_REDUCE_THRESHOLD 2681
+#define GCD_DC_THRESHOLD 807
+#define GCDEXT_DC_THRESHOLD 416
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 21
+#define SET_STR_DC_THRESHOLD 1326
+#define SET_STR_PRECOMPUTE_THRESHOLD 2627
+
+#define FAC_DSC_THRESHOLD 767
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/x86_64/coreihwl/mul_1.asm b/gmp/mpn/x86_64/coreihwl/mul_1.asm
new file mode 100644
index 0000000000..1e3c338f4e
--- /dev/null
+++ b/gmp/mpn/x86_64/coreihwl/mul_1.asm
@@ -0,0 +1,155 @@
+dnl AMD64 mpn_mul_1 using mulx optimised for Intel Haswell.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C AMD K8,K9 n/a
+C AMD K10 n/a
+C AMD bd1 n/a
+C AMD bd2 ?
+C AMD bobcat n/a
+C AMD jaguar ?
+C Intel P4 n/a
+C Intel PNR n/a
+C Intel NHM n/a
+C Intel SBR n/a
+C Intel IBR n/a
+C Intel HWL 1.57 this
+C Intel BWL ?
+C Intel atom n/a
+C VIA nano n/a
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0_param',`%rcx') C r9
+
+define(`n', `%rbp')
+define(`v0', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mul_1)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+ push %r12
+
+ mov n_param, n
+ shr $2, n
+
+ test $1, R8(n_param)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n_param)
+ mov v0_param, v0
+ jnz L(b10)
+
+L(b00): mulx( (up), %r9, %r8)
+ mulx( 8,(up), %r11, %r10)
+ mulx( 16,(up), %rcx, %r12)
+ lea -32(rp), rp
+ jmp L(lo0)
+
+L(b10): mulx( (up), %rcx, %r12)
+ mulx( 8,(up), %rbx, %rax)
+ lea -16(rp), rp
+ test n, n
+ jz L(cj2)
+ mulx( 16,(up), %r9, %r8)
+ lea 16(up), up
+ jmp L(lo2)
+
+L(bx1): test $2, R8(n_param)
+ mov v0_param, v0
+ jnz L(b11)
+
+L(b01): mulx( (up), %rbx, %rax)
+ lea -24(rp), rp
+ test n, n
+ jz L(cj1)
+ mulx( 8,(up), %r9, %r8)
+ lea 8(up), up
+ jmp L(lo1)
+
+L(b11): mulx( (up), %r11, %r10)
+ mulx( 8,(up), %rcx, %r12)
+ mulx( 16,(up), %rbx, %rax)
+ lea -8(rp), rp
+ test n, n
+ jz L(cj3)
+ lea 24(up), up
+ jmp L(lo3)
+
+ ALIGN(32)
+L(top): lea 32(rp), rp
+ mov %r9, (rp)
+ adc %r8, %r11
+L(lo3): mulx( (up), %r9, %r8)
+ mov %r11, 8(rp)
+ adc %r10, %rcx
+L(lo2): mov %rcx, 16(rp)
+ adc %r12, %rbx
+L(lo1): mulx( 8,(up), %r11, %r10)
+ adc %rax, %r9
+ mulx( 16,(up), %rcx, %r12)
+ mov %rbx, 24(rp)
+L(lo0): mulx( 24,(up), %rbx, %rax)
+ lea 32(up), up
+ dec n
+ jnz L(top)
+
+L(end): lea 32(rp), rp
+ mov %r9, (rp)
+ adc %r8, %r11
+L(cj3): mov %r11, 8(rp)
+ adc %r10, %rcx
+L(cj2): mov %rcx, 16(rp)
+ adc %r12, %rbx
+L(cj1): mov %rbx, 24(rp)
+ adc $0, %rax
+
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/coreihwl/mul_2.asm b/gmp/mpn/x86_64/coreihwl/mul_2.asm
new file mode 100644
index 0000000000..5bdb1aa645
--- /dev/null
+++ b/gmp/mpn/x86_64/coreihwl/mul_2.asm
@@ -0,0 +1,173 @@
+dnl AMD64 mpn_mul_2 optimised for Intel Haswell.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 n/a
+C AMD K10 n/a
+C AMD bull n/a
+C AMD pile n/a
+C AMD steam ?
+C AMD bobcat n/a
+C AMD jaguar ?
+C Intel P4 n/a
+C Intel core n/a
+C Intel NHM n/a
+C Intel SBR n/a
+C Intel IBR n/a
+C Intel HWL 1.86
+C Intel BWL ?
+C Intel atom n/a
+C VIA nano n/a
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Move test and jcc together, for insn fusion.
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n_param',`%rdx')
+define(`vp', `%rcx')
+
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+define(`n', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mul_2)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ lea 3(n_param), n
+ shr $2, n
+
+ test $1, R8(n_param)
+ jnz L(bx1)
+
+L(bx0): xor w0, w0
+ test $2, R8(n_param)
+ mov (up), %rdx
+ mulx( v0, w2, w1)
+ jz L(lo0)
+
+L(b10): lea -16(rp), rp
+ lea -16(up), up
+ jmp L(lo2)
+
+L(bx1): xor w2, w2
+ test $2, R8(n_param)
+ mov (up), %rdx
+ mulx( v0, w0, w3)
+ jnz L(b11)
+
+L(b01): lea -24(rp), rp
+ lea 8(up), up
+ jmp L(lo1)
+
+L(b11): lea -8(rp), rp
+ lea -8(up), up
+ jmp L(lo3)
+
+ ALIGN(16)
+L(top): mulx( v1, %rax, w0)
+ add %rax, w2 C 0
+ mov (up), %rdx
+ mulx( v0, %rax, w1)
+ adc $0, w0 C 1
+ add %rax, w2 C 0
+ adc $0, w1 C 1
+ add w3, w2 C 0
+L(lo0): mov w2, (rp) C 0
+ adc $0, w1 C 1
+ mulx( v1, %rax, w2)
+ add %rax, w0 C 1
+ mov 8(up), %rdx
+ adc $0, w2 C 2
+ mulx( v0, %rax, w3)
+ add %rax, w0 C 1
+ adc $0, w3 C 2
+ add w1, w0 C 1
+L(lo3): mov w0, 8(rp) C 1
+ adc $0, w3 C 2
+ mulx( v1, %rax, w0)
+ add %rax, w2 C 2
+ mov 16(up), %rdx
+ mulx( v0, %rax, w1)
+ adc $0, w0 C 3
+ add %rax, w2 C 2
+ adc $0, w1 C 3
+ add w3, w2 C 2
+L(lo2): mov w2, 16(rp) C 2
+ adc $0, w1 C 3
+ mulx( v1, %rax, w2)
+ add %rax, w0 C 3
+ mov 24(up), %rdx
+ adc $0, w2 C 4
+ mulx( v0, %rax, w3)
+ add %rax, w0 C 3
+ adc $0, w3 C 4
+ add w1, w0 C 3
+ lea 32(up), up
+L(lo1): mov w0, 24(rp) C 3
+ adc $0, w3 C 4
+ dec n
+ lea 32(rp), rp
+ jnz L(top)
+
+L(end): mulx( v1, %rdx, %rax)
+ add %rdx, w2
+ adc $0, %rax
+ add w3, w2
+ mov w2, (rp)
+ adc $0, %rax
+
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreihwl/mul_basecase.asm b/gmp/mpn/x86_64/coreihwl/mul_basecase.asm
new file mode 100644
index 0000000000..b2656c8e9b
--- /dev/null
+++ b/gmp/mpn/x86_64/coreihwl/mul_basecase.asm
@@ -0,0 +1,441 @@
+dnl AMD64 mpn_mul_basecase optimised for Intel Haswell.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_1 mul_2 mul_3 addmul_2
+C AMD K8,K9 n/a n/a - n/a
+C AMD K10 n/a n/a - n/a
+C AMD bull n/a n/a - n/a
+C AMD pile n/a n/a - n/a
+C AMD steam ? ? - ?
+C AMD bobcat n/a n/a - n/a
+C AMD jaguar ? ? - ?
+C Intel P4 n/a n/a - n/a
+C Intel core n/a n/a - n/a
+C Intel NHM n/a n/a - n/a
+C Intel SBR n/a n/a - n/a
+C Intel IBR n/a n/a - n/a
+C Intel HWL 1.77 1.86 - 2.15
+C Intel BWL ? ? - ?
+C Intel atom n/a n/a - n/a
+C VIA nano n/a n/a - n/a
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Adjoin a mul_3.
+C * Further micro-optimise.
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param',`%rdx')
+define(`vp', `%rcx')
+define(`vn', `%r8')
+
+define(`un', `%rbx')
+
+define(`w0', `%r10')
+define(`w1', `%r11')
+define(`w2', `%r12')
+define(`w3', `%r13')
+define(`n', `%rbp')
+define(`v0', `%r9')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_basecase)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ mov un_param, un C free up rdx
+ neg un
+
+ mov un_param, n C FIXME: share
+ sar $2, n C FIXME: share
+
+ test $1, R8(vn)
+ jz L(do_mul_2)
+
+define(`w4', `%r9')
+define(`w5', `%r14')
+
+ mov (vp), %rdx
+
+L(do_mul_1):
+ test $1, R8(un)
+ jnz L(m1x1)
+
+L(m1x0):test $2, R8(un)
+ jnz L(m110)
+
+L(m100):
+ mulx( (up), w5, w2)
+ mulx( 8,(up), w1, w3)
+ lea -24(rp), rp
+ jmp L(m1l0)
+
+L(m110):
+ mulx( (up), w3, w4)
+ mulx( 8,(up), w1, w5)
+ lea -8(rp), rp
+ test n, n
+ jz L(cj2)
+ mulx( 16,(up), w0, w2)
+ lea 16(up), up
+ jmp L(m1l2)
+
+L(m1x1):test $2, R8(un)
+ jz L(m111)
+
+L(m101):
+ mulx( (up), w4, w5)
+ lea -16(rp), rp
+ test n, n
+ jz L(cj1)
+ mulx( 8,(up), w0, w2)
+ lea 8(up), up
+ jmp L(m1l1)
+
+L(m111):
+ mulx( (up), w2, w3)
+ mulx( 8,(up), w0, w4)
+ mulx( 16,(up), w1, w5)
+ lea 24(up), up
+ test n, n
+ jnz L(gt3)
+ add w0, w3
+ jmp L(cj3)
+L(gt3): add w0, w3
+ jmp L(m1l3)
+
+ ALIGN(32)
+L(m1tp):lea 32(rp), rp
+L(m1l3):mov w2, (rp)
+ mulx( (up), w0, w2)
+L(m1l2):mov w3, 8(rp)
+ adc w1, w4
+L(m1l1):adc w0, w5
+ mov w4, 16(rp)
+ mulx( 8,(up), w1, w3)
+L(m1l0):mov w5, 24(rp)
+ mulx( 16,(up), w0, w4)
+ adc w1, w2
+ mulx( 24,(up), w1, w5)
+ adc w0, w3
+ lea 32(up), up
+ dec n
+ jnz L(m1tp)
+
+L(m1ed):lea 32(rp), rp
+L(cj3): mov w2, (rp)
+L(cj2): mov w3, 8(rp)
+ adc w1, w4
+L(cj1): mov w4, 16(rp)
+ adc $0, w5
+ mov w5, 24(rp)
+
+ dec R32(vn)
+ jz L(ret5)
+
+ lea 8(vp), vp
+ lea 32(rp), rp
+C push %r12
+C push %r13
+C push %r14
+ jmp L(do_addmul)
+
+L(do_mul_2):
+define(`v1', `%r14')
+C push %r12
+C push %r13
+C push %r14
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ lea (un), n
+ sar $2, n
+
+ test $1, R8(un)
+ jnz L(m2x1)
+
+L(m2x0):xor w0, w0
+ test $2, R8(un)
+ mov (up), %rdx
+ mulx( v0, w2, w1)
+ jz L(m2l0)
+
+L(m210):lea -16(rp), rp
+ lea -16(up), up
+ jmp L(m2l2)
+
+L(m2x1):xor w2, w2
+ test $2, R8(un)
+ mov (up), %rdx
+ mulx( v0, w0, w3)
+ jz L(m211)
+
+L(m201):lea -24(rp), rp
+ lea 8(up), up
+ jmp L(m2l1)
+
+L(m211):lea -8(rp), rp
+ lea -8(up), up
+ jmp L(m2l3)
+
+ ALIGN(16)
+L(m2tp):mulx( v1, %rax, w0)
+ add %rax, w2
+ mov (up), %rdx
+ mulx( v0, %rax, w1)
+ adc $0, w0
+ add %rax, w2
+ adc $0, w1
+ add w3, w2
+L(m2l0):mov w2, (rp)
+ adc $0, w1
+ mulx( v1, %rax, w2)
+ add %rax, w0
+ mov 8(up), %rdx
+ adc $0, w2
+ mulx( v0, %rax, w3)
+ add %rax, w0
+ adc $0, w3
+ add w1, w0
+L(m2l3):mov w0, 8(rp)
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, w2
+ mov 16(up), %rdx
+ mulx( v0, %rax, w1)
+ adc $0, w0
+ add %rax, w2
+ adc $0, w1
+ add w3, w2
+L(m2l2):mov w2, 16(rp)
+ adc $0, w1
+ mulx( v1, %rax, w2)
+ add %rax, w0
+ mov 24(up), %rdx
+ adc $0, w2
+ mulx( v0, %rax, w3)
+ add %rax, w0
+ adc $0, w3
+ add w1, w0
+ lea 32(up), up
+L(m2l1):mov w0, 24(rp)
+ adc $0, w3
+ inc n
+ lea 32(rp), rp
+ jnz L(m2tp)
+
+L(m2ed):mulx( v1, %rdx, %rax)
+ add %rdx, w2
+ adc $0, %rax
+ add w3, w2
+ mov w2, (rp)
+ adc $0, %rax
+ mov %rax, 8(rp)
+
+ add $-2, R32(vn)
+ jz L(ret5)
+ lea 16(vp), vp
+ lea 16(rp), rp
+
+
+L(do_addmul):
+ push %r15
+ push vn C save vn in new stack slot
+define(`vn', `(%rsp)')
+define(`X0', `%r14')
+define(`X1', `%r15')
+define(`v1', `%r8')
+
+ lea (rp,un,8), rp
+ lea (up,un,8), up
+
+L(outer):
+ mov (vp), v0
+ mov 8(vp), v1
+
+ lea 2(un), n
+ sar $2, n
+
+ mov (up), %rdx
+ test $1, R8(un)
+ jnz L(bx1)
+
+L(bx0): mov (rp), X0
+ mov 8(rp), X1
+ mulx( v0, %rax, w1)
+ add %rax, X0
+ mulx( v1, %rax, w2)
+ adc $0, w1
+ mov X0, (rp)
+ add %rax, X1
+ adc $0, w2
+ mov 8(up), %rdx
+ test $2, R8(un)
+ jnz L(b10)
+
+L(b00): lea 16(up), up
+ lea 16(rp), rp
+ jmp L(lo0)
+
+L(b10): mov 16(rp), X0
+ lea 32(up), up
+ mulx( v0, %rax, w3)
+ jmp L(lo2)
+
+L(bx1): mov (rp), X1
+ mov 8(rp), X0
+ mulx( v0, %rax, w3)
+ add %rax, X1
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ mov 8(up), %rdx
+ mov X1, (rp)
+ mulx( v0, %rax, w1)
+ test $2, R8(un)
+ jz L(b11)
+
+L(b01): mov 16(rp), X1
+ lea 24(rp), rp
+ lea 24(up), up
+ jmp L(lo1)
+
+L(b11): lea 8(rp), rp
+ lea 8(up), up
+ jmp L(lo3)
+
+ ALIGN(16)
+L(top): mulx( v0, %rax, w3)
+ add w0, X1
+ adc $0, w2
+L(lo2): add %rax, X1
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ lea 32(rp), rp
+ add w1, X1
+ mov -16(up), %rdx
+ mov X1, -24(rp)
+ adc $0, w3
+ add w2, X0
+ mov -8(rp), X1
+ mulx( v0, %rax, w1)
+ adc $0, w0
+L(lo1): add %rax, X0
+ mulx( v1, %rax, w2)
+ adc $0, w1
+ add w3, X0
+ mov X0, -16(rp)
+ adc $0, w1
+ add %rax, X1
+ adc $0, w2
+ add w0, X1
+ mov -8(up), %rdx
+ adc $0, w2
+L(lo0): mulx( v0, %rax, w3)
+ add %rax, X1
+ adc $0, w3
+ mov (rp), X0
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ add w1, X1
+ mov X1, -8(rp)
+ adc $0, w3
+ mov (up), %rdx
+ add w2, X0
+ mulx( v0, %rax, w1)
+ adc $0, w0
+L(lo3): add %rax, X0
+ adc $0, w1
+ mulx( v1, %rax, w2)
+ add w3, X0
+ mov 8(rp), X1
+ mov X0, (rp)
+ mov 16(rp), X0
+ adc $0, w1
+ add %rax, X1
+ adc $0, w2
+ mov 8(up), %rdx
+ lea 32(up), up
+ inc n
+ jnz L(top)
+
+L(end): mulx( v0, %rax, w3)
+ add w0, X1
+ adc $0, w2
+ add %rax, X1
+ adc $0, w3
+ mulx( v1, %rdx, %rax)
+ add w1, X1
+ mov X1, 8(rp)
+ adc $0, w3
+ add w2, %rdx
+ adc $0, %rax
+ add w3, %rdx
+ mov %rdx, 16(rp)
+ adc $0, %rax
+ mov %rax, 24(rp)
+
+ addl $-2, vn
+ lea 16(vp), vp
+ lea -16(up,un,8), up
+ lea 32(rp,un,8), rp
+ jnz L(outer)
+
+ pop %rax C deallocate vn slot
+ pop %r15
+L(ret5):pop %r14
+L(ret4):pop %r13
+L(ret3):pop %r12
+L(ret2):pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreihwl/mullo_basecase.asm b/gmp/mpn/x86_64/coreihwl/mullo_basecase.asm
new file mode 100644
index 0000000000..9986e8bcfa
--- /dev/null
+++ b/gmp/mpn/x86_64/coreihwl/mullo_basecase.asm
@@ -0,0 +1,426 @@
+dnl AMD64 mpn_mullo_basecase optimised for Intel Haswell.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2008, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_2 addmul_2
+C AMD K8,K9 n/a n/a
+C AMD K10 n/a n/a
+C AMD bull n/a n/a
+C AMD pile n/a n/a
+C AMD steam ? ?
+C AMD bobcat n/a n/a
+C AMD jaguar ? ?
+C Intel P4 n/a n/a
+C Intel core n/a n/a
+C Intel NHM n/a n/a
+C Intel SBR n/a n/a
+C Intel IBR n/a n/a
+C Intel HWL 1.86 2.15
+C Intel BWL ? ?
+C Intel atom n/a n/a
+C VIA nano n/a n/a
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Implement proper cor2, replacing current cor0.
+C * Micro-optimise.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp_param', `%rdx')
+define(`n', `%rcx')
+
+define(`vp', `%r8')
+define(`X0', `%r14')
+define(`X1', `%r15')
+
+define(`w0', `%r10')
+define(`w1', `%r11')
+define(`w2', `%r12')
+define(`w3', `%r13')
+define(`i', `%rbp')
+define(`v0', `%r9')
+define(`v1', `%rbx')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mullo_basecase)
+ FUNC_ENTRY(4)
+
+ mov vp_param, vp
+ mov (up), %rdx
+
+ cmp $4, n
+ jb L(small)
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ lea 2(n), i
+ shr $2, i
+ neg n
+ add $2, n
+
+ push up C put entry `up' on stack
+
+ test $1, R8(n)
+ jnz L(m2x1)
+
+L(m2x0):mulx( v0, w0, w3)
+ xor R32(w2), R32(w2)
+ test $2, R8(n)
+ jz L(m2b2)
+
+L(m2b0):lea -8(rp), rp
+ lea -8(up), up
+ jmp L(m2e0)
+
+L(m2b2):lea -24(rp), rp
+ lea 8(up), up
+ jmp L(m2e2)
+
+L(m2x1):mulx( v0, w2, w1)
+ xor R32(w0), R32(w0)
+ test $2, R8(n)
+ jnz L(m2b3)
+
+L(m2b1):jmp L(m2e1)
+
+L(m2b3):lea -16(rp), rp
+ lea -16(up), up
+ jmp L(m2e3)
+
+ ALIGN(16)
+L(m2tp):mulx( v1, %rax, w0)
+ add %rax, w2
+ mov (up), %rdx
+ mulx( v0, %rax, w1)
+ adc $0, w0
+ add %rax, w2
+ adc $0, w1
+ add w3, w2
+L(m2e1):mov w2, (rp)
+ adc $0, w1
+ mulx( v1, %rax, w2)
+ add %rax, w0
+ mov 8(up), %rdx
+ adc $0, w2
+ mulx( v0, %rax, w3)
+ add %rax, w0
+ adc $0, w3
+ add w1, w0
+L(m2e0):mov w0, 8(rp)
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, w2
+ mov 16(up), %rdx
+ mulx( v0, %rax, w1)
+ adc $0, w0
+ add %rax, w2
+ adc $0, w1
+ add w3, w2
+L(m2e3):mov w2, 16(rp)
+ adc $0, w1
+ mulx( v1, %rax, w2)
+ add %rax, w0
+ mov 24(up), %rdx
+ adc $0, w2
+ mulx( v0, %rax, w3)
+ add %rax, w0
+ adc $0, w3
+ add w1, w0
+ lea 32(up), up
+L(m2e2):mov w0, 24(rp)
+ adc $0, w3
+ dec i
+ lea 32(rp), rp
+ jnz L(m2tp)
+
+L(m2ed):mulx( v1, %rax, w0)
+ add %rax, w2
+ mov (up), %rdx
+ mulx( v0, %rax, w1)
+ add w2, %rax
+ add w3, %rax
+ mov %rax, (rp)
+
+ mov (%rsp), up C restore `up' to beginning
+ lea 16(vp), vp
+ lea 8(rp,n,8), rp C put back rp to old rp + 2
+ add $2, n
+ jge L(cor1)
+
+ push %r14
+ push %r15
+
+L(outer):
+ mov (vp), v0
+ mov 8(vp), v1
+
+ lea (n), i
+ sar $2, i
+
+ mov (up), %rdx
+ test $1, R8(n)
+ jnz L(bx1)
+
+L(bx0): mov (rp), X1
+ mov 8(rp), X0
+ mulx( v0, %rax, w3)
+ add %rax, X1
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ mov 8(up), %rdx
+ mov X1, (rp)
+ mulx( v0, %rax, w1)
+ test $2, R8(n)
+ jz L(b2)
+
+L(b0): lea 8(rp), rp
+ lea 8(up), up
+ jmp L(lo0)
+
+L(b2): mov 16(rp), X1
+ lea 24(rp), rp
+ lea 24(up), up
+ jmp L(lo2)
+
+L(bx1): mov (rp), X0
+ mov 8(rp), X1
+ mulx( v0, %rax, w1)
+ add %rax, X0
+ mulx( v1, %rax, w2)
+ adc $0, w1
+ mov X0, (rp)
+ add %rax, X1
+ adc $0, w2
+ mov 8(up), %rdx
+ test $2, R8(n)
+ jnz L(b3)
+
+L(b1): lea 16(up), up
+ lea 16(rp), rp
+ jmp L(lo1)
+
+L(b3): mov 16(rp), X0
+ lea 32(up), up
+ mulx( v0, %rax, w3)
+ inc i
+ jz L(cj3)
+ jmp L(lo3)
+
+ ALIGN(16)
+L(top): mulx( v0, %rax, w3)
+ add w0, X1
+ adc $0, w2
+L(lo3): add %rax, X1
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ lea 32(rp), rp
+ add w1, X1
+ mov -16(up), %rdx
+ mov X1, -24(rp)
+ adc $0, w3
+ add w2, X0
+ mov -8(rp), X1
+ mulx( v0, %rax, w1)
+ adc $0, w0
+L(lo2): add %rax, X0
+ mulx( v1, %rax, w2)
+ adc $0, w1
+ add w3, X0
+ mov X0, -16(rp)
+ adc $0, w1
+ add %rax, X1
+ adc $0, w2
+ add w0, X1
+ mov -8(up), %rdx
+ adc $0, w2
+L(lo1): mulx( v0, %rax, w3)
+ add %rax, X1
+ adc $0, w3
+ mov (rp), X0
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ add w1, X1
+ mov X1, -8(rp)
+ adc $0, w3
+ mov (up), %rdx
+ add w2, X0
+ mulx( v0, %rax, w1)
+ adc $0, w0
+L(lo0): add %rax, X0
+ adc $0, w1
+ mulx( v1, %rax, w2)
+ add w3, X0
+ mov 8(rp), X1
+ mov X0, (rp)
+ mov 16(rp), X0
+ adc $0, w1
+ add %rax, X1
+ adc $0, w2
+ mov 8(up), %rdx
+ lea 32(up), up
+ inc i
+ jnz L(top)
+
+L(end): mulx( v0, %rax, w3)
+ add w0, X1
+ adc $0, w2
+L(cj3): add %rax, X1
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ add w1, X1
+ mov -16(up), %rdx
+ mov X1, 8(rp)
+ adc $0, w3
+ add w2, X0
+ mulx( v0, %rax, w1)
+ add X0, %rax
+ add w3, %rax
+ mov %rax, 16(rp)
+
+ mov 16(%rsp), up C restore `up' to beginning
+ lea 16(vp), vp
+ lea 24(rp,n,8), rp C put back rp to old rp + 2
+ add $2, n
+ jl L(outer)
+
+ pop %r15
+ pop %r14
+
+ jnz L(cor0)
+
+L(cor1):mov (vp), v0
+ mov 8(vp), v1
+ mov (up), %rdx
+ mulx( v0, %r12, %rbp) C u0 x v2
+ add (rp), %r12 C FIXME: rp[0] still available in reg?
+ adc %rax, %rbp
+ mov 8(up), %r10
+ imul v0, %r10
+ imul v1, %rdx
+ mov %r12, (rp)
+ add %r10, %rdx
+ add %rbp, %rdx
+ mov %rdx, 8(rp)
+ pop %rax C deallocate `up' copy
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(cor0):mov (vp), %r11
+ imul (up), %r11
+ add %rax, %r11
+ mov %r11, (rp)
+ pop %rax C deallocate `up' copy
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(small):
+ cmp $2, n
+ jae L(gt1)
+L(n1): imul (vp), %rdx
+ mov %rdx, (rp)
+ FUNC_EXIT()
+ ret
+L(gt1): ja L(gt2)
+L(n2): mov (vp), %r9
+ mulx( %r9, %rax, %rdx)
+ mov %rax, (rp)
+ mov 8(up), %rax
+ imul %r9, %rax
+ add %rax, %rdx
+ mov 8(vp), %r9
+ mov (up), %rcx
+ imul %r9, %rcx
+ add %rcx, %rdx
+ mov %rdx, 8(rp)
+ FUNC_EXIT()
+ ret
+L(gt2):
+L(n3): mov (vp), %r9
+ mulx( %r9, %rax, %r10) C u0 x v0
+ mov %rax, (rp)
+ mov 8(up), %rdx
+ mulx( %r9, %rax, %rdx) C u1 x v0
+ imul 16(up), %r9 C u2 x v0
+ add %rax, %r10
+ adc %rdx, %r9
+ mov 8(vp), %r11
+ mov (up), %rdx
+ mulx( %r11, %rax, %rdx) C u0 x v1
+ add %rax, %r10
+ adc %rdx, %r9
+ imul 8(up), %r11 C u1 x v1
+ add %r11, %r9
+ mov %r10, 8(rp)
+ mov 16(vp), %r10
+ mov (up), %rax
+ imul %rax, %r10 C u0 x v2
+ add %r10, %r9
+ mov %r9, 16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreihwl/redc_1.asm b/gmp/mpn/x86_64/coreihwl/redc_1.asm
new file mode 100644
index 0000000000..f1a475e53c
--- /dev/null
+++ b/gmp/mpn/x86_64/coreihwl/redc_1.asm
@@ -0,0 +1,433 @@
+dnl AMD64 mpn_redc_1 optimised for Intel Haswell.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 n/a
+C AMD K10 n/a
+C AMD bull n/a
+C AMD pile n/a
+C AMD steam ?
+C AMD bobcat n/a
+C AMD jaguar ?
+C Intel P4 n/a
+C Intel core n/a
+C Intel NHM n/a
+C Intel SBR n/a
+C Intel IBR n/a
+C Intel HWL 2.32
+C Intel BWL ?
+C Intel atom n/a
+C VIA nano n/a
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Micro-optimise.
+C * Consider inlining mpn_add_n. Tests indicate that this saves just 1-2
+C cycles, though.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`mp_param', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`u0inv_param', `%r8') C stack
+
+define(`i', `%r14')
+define(`j', `%r15')
+define(`mp', `%rdi')
+define(`u0inv', `(%rsp)') C stack
+
+ABI_SUPPORT(DOS64) C FIXME: needs verification
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_redc_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ push rp
+ mov mp_param, mp C note that rp and mp shares register
+ mov (up), %rdx
+
+ neg n
+ push %r8 C put u0inv on stack
+ imul u0inv_param, %rdx C first iteration q0
+ mov n, j C outer loop induction var
+
+ test $1, R8(n)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n)
+ jz L(o0b)
+
+ cmp $-2, R32(n)
+ jnz L(o2)
+
+C Special code for n = 2 since general code cannot handle it
+ mov 8(%rsp), %rbx C rp
+ lea 16(%rsp), %rsp C deallocate two slots
+ mulx( (mp), %r9, %r12)
+ mulx( 8,(mp), %r11, %r10)
+ add %r12, %r11
+ adc $0, %r10
+ add (up), %r9 C = 0
+ adc 8(up), %r11 C r11 = up[1]
+ adc $0, %r10 C -> up[0]
+ mov %r11, %rdx
+ imul u0inv_param, %rdx
+ mulx( (mp), %r13, %r12)
+ mulx( 8,(mp), %r14, %r15)
+ xor R32(%rax), R32(%rax)
+ add %r12, %r14
+ adc $0, %r15
+ add %r11, %r13 C = 0
+ adc 16(up), %r14 C rp[2]
+ adc $0, %r15 C -> up[1]
+ add %r14, %r10
+ adc 24(up), %r15
+ mov %r10, (%rbx)
+ mov %r15, 8(%rbx)
+ setc R8(%rax)
+ jmp L(ret)
+
+L(o2): lea 2(n), i C inner loop induction var
+ mulx( (mp), %r9, %r8)
+ mulx( 8,(mp), %r11, %r10)
+ sar $2, i
+ add %r8, %r11
+ jmp L(lo2)
+
+ ALIGN(16)
+L(tp2): adc %rax, %r9
+ lea 32(up), up
+ adc %r8, %r11
+L(lo2): mulx( 16,(mp), %r13, %r12)
+ mov (up), %r8
+ mulx( 24,(mp), %rbx, %rax)
+ lea 32(mp), mp
+ adc %r10, %r13
+ adc %r12, %rbx
+ adc $0, %rax
+ mov 8(up), %r10
+ mov 16(up), %r12
+ add %r9, %r8
+ mov 24(up), %rbp
+ mov %r8, (up)
+ adc %r11, %r10
+ mulx( (mp), %r9, %r8)
+ mov %r10, 8(up)
+ adc %r13, %r12
+ mov %r12, 16(up)
+ adc %rbx, %rbp
+ mulx( 8,(mp), %r11, %r10)
+ mov %rbp, 24(up)
+ inc i
+ jnz L(tp2)
+
+L(ed2): mov 56(up,n,8), %rdx C next iteration up[0]
+ lea 16(mp,n,8), mp C mp = (last starting mp)
+ adc %rax, %r9
+ adc %r8, %r11
+ mov 32(up), %r8
+ adc $0, %r10
+ imul u0inv, %rdx C next iteration q0
+ mov 40(up), %rax
+ add %r9, %r8
+ mov %r8, 32(up)
+ adc %r11, %rax
+ mov %rax, 40(up)
+ lea 56(up,n,8), up C up = (last starting up) + 1
+ adc $0, %r10
+ mov %r10, -8(up)
+ inc j
+ jnz L(o2)
+
+ jmp L(cj)
+
+
+L(bx1): test $2, R8(n)
+ jz L(o3a)
+
+L(o1a): cmp $-1, R32(n)
+ jnz L(o1b)
+
+C Special code for n = 1 since general code cannot handle it
+ mov 8(%rsp), %rbx C rp
+ lea 16(%rsp), %rsp C deallocate two slots
+ mulx( (mp), %r11, %r10)
+ add (up), %r11
+ adc 8(up), %r10
+ mov %r10, (%rbx)
+ mov $0, R32(%rax)
+ setc R8(%rax)
+ jmp L(ret)
+
+L(o1b): lea 24(mp), mp
+L(o1): lea 1(n), i C inner loop induction var
+ mulx( -24,(mp), %r11, %r10)
+ mulx( -16,(mp), %r13, %r12)
+ mulx( -8,(mp), %rbx, %rax)
+ sar $2, i
+ add %r10, %r13
+ adc %r12, %rbx
+ adc $0, %rax
+ mov (up), %r10
+ mov 8(up), %r12
+ mov 16(up), %rbp
+ add %r11, %r10
+ jmp L(lo1)
+
+ ALIGN(16)
+L(tp1): adc %rax, %r9
+ lea 32(up), up
+ adc %r8, %r11
+ mulx( 16,(mp), %r13, %r12)
+ mov -8(up), %r8
+ mulx( 24,(mp), %rbx, %rax)
+ lea 32(mp), mp
+ adc %r10, %r13
+ adc %r12, %rbx
+ adc $0, %rax
+ mov (up), %r10
+ mov 8(up), %r12
+ add %r9, %r8
+ mov 16(up), %rbp
+ mov %r8, -8(up)
+ adc %r11, %r10
+L(lo1): mulx( (mp), %r9, %r8)
+ mov %r10, (up)
+ adc %r13, %r12
+ mov %r12, 8(up)
+ adc %rbx, %rbp
+ mulx( 8,(mp), %r11, %r10)
+ mov %rbp, 16(up)
+ inc i
+ jnz L(tp1)
+
+L(ed1): mov 48(up,n,8), %rdx C next iteration up[0]
+ lea 40(mp,n,8), mp C mp = (last starting mp)
+ adc %rax, %r9
+ adc %r8, %r11
+ mov 24(up), %r8
+ adc $0, %r10
+ imul u0inv, %rdx C next iteration q0
+ mov 32(up), %rax
+ add %r9, %r8
+ mov %r8, 24(up)
+ adc %r11, %rax
+ mov %rax, 32(up)
+ lea 48(up,n,8), up C up = (last starting up) + 1
+ adc $0, %r10
+ mov %r10, -8(up)
+ inc j
+ jnz L(o1)
+
+ jmp L(cj)
+
+L(o3a): cmp $-3, R32(n)
+ jnz L(o3b)
+
+C Special code for n = 3 since general code cannot handle it
+L(n3): mulx( (mp), %rbx, %rax)
+ mulx( 8,(mp), %r9, %r14)
+ add (up), %rbx
+ mulx( 16,(mp), %r11, %r10)
+ adc %rax, %r9 C W 1
+ adc %r14, %r11 C W 2
+ mov 8(up), %r14
+ mov u0inv_param, %rdx
+ adc $0, %r10 C W 3
+ mov 16(up), %rax
+ add %r9, %r14 C W 1
+ mov %r14, 8(up)
+ mulx( %r14, %rdx, %r13) C next iteration q0
+ adc %r11, %rax C W 2
+ mov %rax, 16(up)
+ adc $0, %r10 C W 3
+ mov %r10, (up)
+ lea 8(up), up C up = (last starting up) + 1
+ inc j
+ jnz L(n3)
+
+ jmp L(cj)
+
+L(o3b): lea 8(mp), mp
+L(o3): lea 4(n), i C inner loop induction var
+ mulx( -8,(mp), %rbx, %rax)
+ mulx( (mp), %r9, %r8)
+ mov (up), %rbp
+ mulx( 8,(mp), %r11, %r10)
+ sar $2, i
+ add %rbx, %rbp
+ nop
+ adc %rax, %r9
+ jmp L(lo3)
+
+ ALIGN(16)
+L(tp3): adc %rax, %r9
+ lea 32(up), up
+L(lo3): adc %r8, %r11
+ mulx( 16,(mp), %r13, %r12)
+ mov 8(up), %r8
+ mulx( 24,(mp), %rbx, %rax)
+ lea 32(mp), mp
+ adc %r10, %r13
+ adc %r12, %rbx
+ adc $0, %rax
+ mov 16(up), %r10
+ mov 24(up), %r12
+ add %r9, %r8
+ mov 32(up), %rbp
+ mov %r8, 8(up)
+ adc %r11, %r10
+ mulx( (mp), %r9, %r8)
+ mov %r10, 16(up)
+ adc %r13, %r12
+ mov %r12, 24(up)
+ adc %rbx, %rbp
+ mulx( 8,(mp), %r11, %r10)
+ mov %rbp, 32(up)
+ inc i
+ jnz L(tp3)
+
+L(ed3): mov 64(up,n,8), %rdx C next iteration up[0]
+ lea 24(mp,n,8), mp C mp = (last starting mp)
+ adc %rax, %r9
+ adc %r8, %r11
+ mov 40(up), %r8
+ adc $0, %r10
+ imul u0inv, %rdx C next iteration q0
+ mov 48(up), %rax
+ add %r9, %r8
+ mov %r8, 40(up)
+ adc %r11, %rax
+ mov %rax, 48(up)
+ lea 64(up,n,8), up C up = (last starting up) + 1
+ adc $0, %r10
+ mov %r10, -8(up)
+ inc j
+ jnz L(o3)
+
+ jmp L(cj)
+
+L(o0b): lea 16(mp), mp
+L(o0): mov n, i C inner loop induction var
+ mulx( -16,(mp), %r13, %r12)
+ mulx( -8,(mp), %rbx, %rax)
+ sar $2, i
+ add %r12, %rbx
+ adc $0, %rax
+ mov (up), %r12
+ mov 8(up), %rbp
+ mulx( (mp), %r9, %r8)
+ add %r13, %r12
+ jmp L(lo0)
+
+ ALIGN(16)
+L(tp0): adc %rax, %r9
+ lea 32(up), up
+ adc %r8, %r11
+ mulx( 16,(mp), %r13, %r12)
+ mov -16(up), %r8
+ mulx( 24,(mp), %rbx, %rax)
+ lea 32(mp), mp
+ adc %r10, %r13
+ adc %r12, %rbx
+ adc $0, %rax
+ mov -8(up), %r10
+ mov (up), %r12
+ add %r9, %r8
+ mov 8(up), %rbp
+ mov %r8, -16(up)
+ adc %r11, %r10
+ mulx( (mp), %r9, %r8)
+ mov %r10, -8(up)
+ adc %r13, %r12
+ mov %r12, (up)
+L(lo0): adc %rbx, %rbp
+ mulx( 8,(mp), %r11, %r10)
+ mov %rbp, 8(up)
+ inc i
+ jnz L(tp0)
+
+L(ed0): mov 40(up,n,8), %rdx C next iteration up[0]
+ lea 32(mp,n,8), mp C mp = (last starting mp)
+ adc %rax, %r9
+ adc %r8, %r11
+ mov 16(up), %r8
+ adc $0, %r10
+ imul u0inv, %rdx C next iteration q0
+ mov 24(up), %rax
+ add %r9, %r8
+ mov %r8, 16(up)
+ adc %r11, %rax
+ mov %rax, 24(up)
+ lea 40(up,n,8), up C up = (last starting up) + 1
+ adc $0, %r10
+ mov %r10, -8(up)
+ inc j
+ jnz L(o0)
+
+L(cj):
+IFSTD(` mov 8(%rsp), %rdi C param 1: rp
+ lea 16(%rsp), %rsp C deallocate two slots
+ lea (up,n,8), %rdx C param 3: up - n
+ neg R32(n) ') C param 4: n
+
+IFDOS(` mov up, %rdx C param 2: up
+ lea (up,n,8), %r8 C param 3: up - n
+ neg R32(n)
+ mov n, %r9 C param 4: n
+ mov 8(%rsp), %rcx C param 1: rp
+ lea 16(%rsp), %rsp ') C deallocate two slots
+
+ CALL( mpn_add_n)
+
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreihwl/sqr_basecase.asm b/gmp/mpn/x86_64/coreihwl/sqr_basecase.asm
new file mode 100644
index 0000000000..641cdf349a
--- /dev/null
+++ b/gmp/mpn/x86_64/coreihwl/sqr_basecase.asm
@@ -0,0 +1,506 @@
+dnl AMD64 mpn_sqr_basecase optimised for Intel Haswell.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2008, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_2 addmul_2 sqr_diag_addlsh1
+C AMD K8,K9 n/a n/a n/a
+C AMD K10 n/a n/a n/a
+C AMD bull n/a n/a n/a
+C AMD pile n/a n/a n/a
+C AMD steam ? ? ?
+C AMD bobcat n/a n/a n/a
+C AMD jaguar ? ? ?
+C Intel P4 n/a n/a n/a
+C Intel core n/a n/a n/a
+C Intel NHM n/a n/a n/a
+C Intel SBR n/a n/a n/a
+C Intel IBR n/a n/a n/a
+C Intel HWL 1.86 2.15 ~2.5
+C Intel BWL ? ? ?
+C Intel atom n/a n/a n/a
+C VIA nano n/a n/a n/a
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund, except
+C that the sqr_diag_addlsh1 loop was manually written.
+
+C TODO
+C * Replace current unoptimised sqr_diag_addlsh1 loop; 1.75 c/l might be
+C possible.
+C * Consider splitting outer loop into 2, one for n = 1 (mod 2) and one for
+C n = 0 (mod 2). These loops could fall into specific "corner" code.
+C * Consider splitting outer loop into 4.
+C * Streamline pointer updates.
+C * Perhaps suppress a few more xor insns in feed-in code.
+C * Make sure we write no dead registers in feed-in code.
+C * We might use 32-bit size ops, since n >= 2^32 is non-terminating. Watch
+C out for negative sizes being zero-extended, though.
+C * Provide straight-line code for n = 4; then look for simplifications in
+C main code.
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param',`%rdx')
+
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_sqr_basecase)
+ FUNC_ENTRY(3)
+
+ cmp $2, un_param
+ jae L(gt1)
+
+ mov (up), %rdx
+ mulx( %rdx, %rax, %rdx)
+ mov %rax, (rp)
+ mov %rdx, 8(rp)
+ FUNC_EXIT()
+ ret
+
+L(gt1): jne L(gt2)
+
+ mov (up), %rdx
+ mov 8(up), %rcx
+ mulx( %rcx, %r9, %r10) C v0 * v1 W 1 2
+ mulx( %rdx, %rax, %r8) C v0 * v0 W 0 1
+ mov %rcx, %rdx
+ mulx( %rdx, %r11, %rdx) C v1 * v1 W 2 3
+ add %r9, %r9 C W 1
+ adc %r10, %r10 C W 2
+ adc $0, %rdx C W 3
+ add %r9, %r8 C W 1
+ adc %r11, %r10 C W 2
+ adc $0, %rdx C W 3
+ mov %rax, (rp)
+ mov %r8, 8(rp)
+ mov %r10, 16(rp)
+ mov %rdx, 24(rp)
+ FUNC_EXIT()
+ ret
+
+L(gt2): cmp $4, un_param
+ jae L(gt3)
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%r10')
+define(`w2', `%r11')
+
+ mov (up), v0
+ mov 8(up), %rdx
+ mov %rdx, v1
+ mulx( v0, w2, %rax)
+ mov 16(up), %rdx
+ mulx( v0, w0, %rcx)
+ mov w2, %r8
+ add %rax, w0
+ adc $0, %rcx
+ mulx( v1, %rdx, %rax)
+ add %rcx, %rdx
+ mov %rdx, 24(rp)
+ adc $0, %rax
+ mov %rax, 32(rp)
+ xor R32(%rcx), R32(%rcx)
+ mov (up), %rdx
+ mulx( %rdx, %rax, w2)
+ mov %rax, (rp)
+ add %r8, %r8
+ adc w0, w0
+ setc R8(%rcx)
+ mov 8(up), %rdx
+ mulx( %rdx, %rax, %rdx)
+ add w2, %r8
+ adc %rax, w0
+ mov %r8, 8(rp)
+ mov w0, 16(rp)
+ mov 24(rp), %r8
+ mov 32(rp), w0
+ lea (%rdx,%rcx), w2
+ adc %r8, %r8
+ adc w0, w0
+ setc R8(%rcx)
+ mov 16(up), %rdx
+ mulx( %rdx, %rax, %rdx)
+ add w2, %r8
+ adc %rax, w0
+ mov %r8, 24(rp)
+ mov w0, 32(rp)
+ adc %rcx, %rdx
+ mov %rdx, 40(rp)
+ FUNC_EXIT()
+ ret
+
+L(gt3):
+
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%r10')
+define(`w1', `%r11')
+define(`w2', `%rbx')
+define(`w3', `%rbp')
+define(`un', `%r12')
+define(`n', `%rcx')
+
+define(`X0', `%r13')
+define(`X1', `%r14')
+
+L(do_mul_2):
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ mov $0, R32(un)
+ sub un_param, un C free up rdx
+ push un
+ mov (up), v0
+ mov 8(up), %rdx
+ lea 2(un), n
+ sar $2, n C FIXME: suppress, change loop?
+ inc un C decrement |un|
+ mov %rdx, v1
+
+ test $1, R8(un)
+ jnz L(mx1)
+
+L(mx0): mulx( v0, w2, w1)
+ mov 16(up), %rdx
+ mov w2, 8(rp)
+ xor w2, w2
+ mulx( v0, w0, w3)
+ test $2, R8(un)
+ jz L(m00)
+
+L(m10): lea -8(rp), rp
+ lea -8(up), up
+ jmp L(mlo2)
+
+L(m00): lea 8(up), up
+ lea 8(rp), rp
+ jmp L(mlo0)
+
+L(mx1): mulx( v0, w0, w3)
+ mov 16(up), %rdx
+ mov w0, 8(rp)
+ xor w0, w0
+ mulx( v0, w2, w1)
+ test $2, R8(un)
+ jz L(mlo3)
+
+L(m01): lea 16(rp), rp
+ lea 16(up), up
+ jmp L(mlo1)
+
+ ALIGN(32)
+L(mtop):mulx( v1, %rax, w0)
+ add %rax, w2 C 0
+ mov (up), %rdx
+ mulx( v0, %rax, w1)
+ adc $0, w0 C 1
+ add %rax, w2 C 0
+L(mlo1):adc $0, w1 C 1
+ add w3, w2 C 0
+ mov w2, (rp) C 0
+ adc $0, w1 C 1
+ mulx( v1, %rax, w2)
+ add %rax, w0 C 1
+ mov 8(up), %rdx
+ adc $0, w2 C 2
+ mulx( v0, %rax, w3)
+ add %rax, w0 C 1
+ adc $0, w3 C 2
+L(mlo0):add w1, w0 C 1
+ mov w0, 8(rp) C 1
+ adc $0, w3 C 2
+ mulx( v1, %rax, w0)
+ add %rax, w2 C 2
+ mov 16(up), %rdx
+ mulx( v0, %rax, w1)
+ adc $0, w0 C 3
+ add %rax, w2 C 2
+ adc $0, w1 C 3
+L(mlo3):add w3, w2 C 2
+ mov w2, 16(rp) C 2
+ adc $0, w1 C 3
+ mulx( v1, %rax, w2)
+ add %rax, w0 C 3
+ mov 24(up), %rdx
+ adc $0, w2 C 4
+ mulx( v0, %rax, w3)
+ add %rax, w0 C 3
+ adc $0, w3 C 4
+L(mlo2):add w1, w0 C 3
+ lea 32(up), up
+ mov w0, 24(rp) C 3
+ adc $0, w3 C 4
+ inc n
+ lea 32(rp), rp
+ jnz L(mtop)
+
+L(mend):mulx( v1, %rdx, %rax)
+ add %rdx, w2
+ adc $0, %rax
+ add w3, w2
+ mov w2, (rp)
+ adc $0, %rax
+ mov %rax, 8(rp)
+
+ lea 16(up), up
+ lea -16(rp), rp
+
+L(do_addmul_2):
+L(outer):
+ lea (up,un,8), up C put back up to 2 positions above last time
+ lea 48(rp,un,8), rp C put back rp to 4 positions above last time
+
+ mov -8(up), v0 C shared between addmul_2 and corner
+
+ add $2, un C decrease |un|
+ cmp $-2, un
+ jge L(corner)
+
+ mov (up), v1
+
+ lea 1(un), n
+ sar $2, n C FIXME: suppress, change loop?
+
+ mov v1, %rdx
+ test $1, R8(un)
+ jnz L(bx1)
+
+L(bx0): mov (rp), X0
+ mov 8(rp), X1
+ mulx( v0, %rax, w1)
+ add %rax, X0
+ adc $0, w1
+ mov X0, (rp)
+ xor w2, w2
+ test $2, R8(un)
+ jnz L(b10)
+
+L(b00): mov 8(up), %rdx
+ lea 16(rp), rp
+ lea 16(up), up
+ jmp L(lo0)
+
+L(b10): mov 8(up), %rdx
+ mov 16(rp), X0
+ lea 32(up), up
+ inc n
+ mulx( v0, %rax, w3)
+ jz L(ex)
+ jmp L(lo2)
+
+L(bx1): mov (rp), X1
+ mov 8(rp), X0
+ mulx( v0, %rax, w3)
+ mov 8(up), %rdx
+ add %rax, X1
+ adc $0, w3
+ xor w0, w0
+ mov X1, (rp)
+ mulx( v0, %rax, w1)
+ test $2, R8(un)
+ jz L(b11)
+
+L(b01): mov 16(rp), X1
+ lea 24(rp), rp
+ lea 24(up), up
+ jmp L(lo1)
+
+L(b11): lea 8(rp), rp
+ lea 8(up), up
+ jmp L(lo3)
+
+ ALIGN(32)
+L(top): mulx( v0, %rax, w3)
+ add w0, X1
+ adc $0, w2
+L(lo2): add %rax, X1
+ adc $0, w3
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ lea 32(rp), rp
+ add w1, X1
+ mov -16(up), %rdx
+ mov X1, -24(rp)
+ adc $0, w3
+ add w2, X0
+ mov -8(rp), X1
+ mulx( v0, %rax, w1)
+ adc $0, w0
+L(lo1): add %rax, X0
+ mulx( v1, %rax, w2)
+ adc $0, w1
+ add w3, X0
+ mov X0, -16(rp)
+ adc $0, w1
+ add %rax, X1
+ adc $0, w2
+ add w0, X1
+ mov -8(up), %rdx
+ adc $0, w2
+L(lo0): mulx( v0, %rax, w3)
+ add %rax, X1
+ adc $0, w3
+ mov (rp), X0
+ mulx( v1, %rax, w0)
+ add %rax, X0
+ adc $0, w0
+ add w1, X1
+ mov X1, -8(rp)
+ adc $0, w3
+ mov (up), %rdx
+ add w2, X0
+ mulx( v0, %rax, w1)
+ adc $0, w0
+L(lo3): add %rax, X0
+ adc $0, w1
+ mulx( v1, %rax, w2)
+ add w3, X0
+ mov 8(rp), X1
+ mov X0, (rp)
+ mov 16(rp), X0
+ adc $0, w1
+ add %rax, X1
+ adc $0, w2
+ mov 8(up), %rdx
+ lea 32(up), up
+ inc n
+ jnz L(top)
+
+L(end): mulx( v0, %rax, w3)
+ add w0, X1
+ adc $0, w2
+L(ex): add %rax, X1
+ adc $0, w3
+ mulx( v1, %rdx, %rax)
+ add w1, X1
+ mov X1, 8(rp)
+ adc $0, w3
+ add w2, %rdx
+ adc $0, %rax
+ add %rdx, w3
+ mov w3, 16(rp)
+ adc $0, %rax
+ mov %rax, 24(rp)
+
+ jmp L(outer) C loop until a small corner remains
+
+L(corner):
+ pop un
+ mov (up), %rdx
+ jg L(small_corner)
+
+ mov %rdx, v1
+ mov (rp), X0
+ mov %rax, X1 C Tricky rax reuse of last iteration
+ mulx( v0, %rax, w1)
+ add %rax, X0
+ adc $0, w1
+ mov X0, (rp)
+ mov 8(up), %rdx
+ mulx( v0, %rax, w3)
+ add %rax, X1
+ adc $0, w3
+ mulx( v1, %rdx, %rax)
+ add w1, X1
+ mov X1, 8(rp)
+ adc $0, w3
+ add w3, %rdx
+ mov %rdx, 16(rp)
+ adc $0, %rax
+ mov %rax, 24(rp)
+ lea 32(rp), rp
+ lea 16(up), up
+ jmp L(com)
+
+L(small_corner):
+ mulx( v0, X1, w3)
+ add %rax, X1 C Tricky rax reuse of last iteration
+ adc $0, w3
+ mov X1, (rp)
+ mov w3, 8(rp)
+ lea 16(rp), rp
+ lea 8(up), up
+
+L(com):
+
+L(sqr_diag_addlsh1):
+ lea 8(up,un,8), up C put back up at its very beginning
+ lea (rp,un,8), rp
+ lea (rp,un,8), rp C put back rp at its very beginning
+ inc un
+
+ mov -8(up), %rdx
+ xor R32(%rbx), R32(%rbx) C clear CF as side effect
+ mulx( %rdx, %rax, %r10)
+ mov %rax, 8(rp)
+ mov 16(rp), %r8
+ mov 24(rp), %r9
+ jmp L(dm)
+
+ ALIGN(16)
+L(dtop):mov 32(rp), %r8
+ mov 40(rp), %r9
+ lea 16(rp), rp
+ lea (%rdx,%rbx), %r10
+L(dm): adc %r8, %r8
+ adc %r9, %r9
+ setc R8(%rbx)
+ mov (up), %rdx
+ lea 8(up), up
+ mulx( %rdx, %rax, %rdx)
+ add %r10, %r8
+ adc %rax, %r9
+ mov %r8, 16(rp)
+ mov %r9, 24(rp)
+ inc un
+ jnz L(dtop)
+
+L(dend):adc %rbx, %rdx
+ mov %rdx, 32(rp)
+
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreinhm/aorrlsh_n.asm b/gmp/mpn/x86_64/coreinhm/aorrlsh_n.asm
new file mode 100644
index 0000000000..eed64e701e
--- /dev/null
+++ b/gmp/mpn/x86_64/coreinhm/aorrlsh_n.asm
@@ -0,0 +1,200 @@
+dnl AMD64 mpn_addlsh_n -- rp[] = up[] + (vp[] << k)
+dnl AMD64 mpn_rsblsh_n -- rp[] = (vp[] << k) - up[]
+dnl Optimised for Nehalem.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 4.75
+C Intel P4 ?
+C Intel core2 2.8-3
+C Intel NHM 2.8
+C Intel SBR 3.55
+C Intel atom ?
+C VIA nano ?
+
+C The inner-loop probably runs close to optimally on Nehalem (using 4-way
+C unrolling). The rest of the code is quite crude, and could perhaps be made
+C both smaller and faster.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cnt', `%r8')
+define(`cy', `%r9') C for _nc variant
+
+ifdef(`OPERATION_addlsh_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(IFRSB, )
+ define(func_n, mpn_addlsh_n)
+ define(func_nc, mpn_addlsh_nc)')
+ifdef(`OPERATION_rsblsh_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(IFRSB, `$1')
+ define(func_n, mpn_rsblsh_n)
+ define(func_nc, mpn_rsblsh_nc)')
+
+C mpn_rsblsh_nc removed below, its idea of carry-in is inconsistent with
+C refmpn_rsblsh_nc
+MULFUNC_PROLOGUE(mpn_addlsh_n mpn_addlsh_nc mpn_rsblsh_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(func_n)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ') C cnt
+ push %rbx
+ xor R32(%rbx), R32(%rbx) C clear CF save register
+L(ent): push %rbp
+ mov R32(n), R32(%rbp)
+ mov n, %rax
+
+ mov R32(cnt), R32(%rcx)
+ neg R32(%rcx)
+
+ lea -8(up,%rax,8), up
+ lea -8(vp,%rax,8), vp
+ lea -40(rp,%rax,8), rp
+ neg %rax
+
+ and $3, R32(%rbp)
+ jz L(b0)
+ cmp $2, R32(%rbp)
+ jc L(b1)
+ jz L(b2)
+
+L(b3): xor R32(%r9), R32(%r9)
+ mov 8(vp,%rax,8), %r10
+ mov 16(vp,%rax,8), %r11
+ shrd %cl, %r10, %r9
+ shrd %cl, %r11, %r10
+ add R32(%rbx), R32(%rbx)
+ ADCSBB 8(up,%rax,8), %r9
+ mov 24(vp,%rax,8), %r8
+ ADCSBB 16(up,%rax,8), %r10
+ sbb R32(%rbx), R32(%rbx)
+ add $3, %rax
+ jmp L(lo3)
+
+L(b0): mov 8(vp,%rax,8), %r9
+ xor R32(%r8), R32(%r8)
+ shrd %cl, %r9, %r8
+ mov 16(vp,%rax,8), %r10
+ mov 24(vp,%rax,8), %r11
+ shrd %cl, %r10, %r9
+ shrd %cl, %r11, %r10
+ add R32(%rbx), R32(%rbx)
+ ADCSBB 8(up,%rax,8), %r8
+ mov %r8, 40(rp,%rax,8) C offset 40
+ ADCSBB 16(up,%rax,8), %r9
+ mov 32(vp,%rax,8), %r8
+ ADCSBB 24(up,%rax,8), %r10
+ sbb R32(%rbx), R32(%rbx)
+ add $4, %rax
+ jmp L(lo0)
+
+L(b1): mov 8(vp,%rax,8), %r8
+ add $1, %rax
+ jz L(1)
+ mov 8(vp,%rax,8), %r9
+ xor R32(%rbp), R32(%rbp)
+ jmp L(lo1)
+L(1): xor R32(%r11), R32(%r11)
+ jmp L(wd1)
+
+L(b2): xor %r10, %r10
+ mov 8(vp,%rax,8), %r11
+ shrd %cl, %r11, %r10
+ add R32(%rbx), R32(%rbx)
+ mov 16(vp,%rax,8), %r8
+ ADCSBB 8(up,%rax,8), %r10
+ sbb R32(%rbx), R32(%rbx)
+ add $2, %rax
+ jz L(end)
+
+ ALIGN(16)
+L(top): mov 8(vp,%rax,8), %r9
+ mov %r11, %rbp
+L(lo2): mov %r10, 24(rp,%rax,8) C offset 24
+L(lo1): shrd %cl, %r8, %rbp
+ shrd %cl, %r9, %r8
+ mov 16(vp,%rax,8), %r10
+ mov 24(vp,%rax,8), %r11
+ shrd %cl, %r10, %r9
+ shrd %cl, %r11, %r10
+ add R32(%rbx), R32(%rbx)
+ ADCSBB (up,%rax,8), %rbp
+ ADCSBB 8(up,%rax,8), %r8
+ mov %r8, 40(rp,%rax,8) C offset 40
+ ADCSBB 16(up,%rax,8), %r9
+ mov 32(vp,%rax,8), %r8
+ ADCSBB 24(up,%rax,8), %r10
+ sbb R32(%rbx), R32(%rbx)
+ add $4, %rax
+ mov %rbp, (rp,%rax,8) C offset 32
+L(lo0):
+L(lo3): mov %r9, 16(rp,%rax,8) C offset 48
+ jnz L(top)
+
+L(end): mov %r10, 24(rp,%rax,8)
+L(wd1): shrd %cl, %r8, %r11
+ add R32(%rbx), R32(%rbx)
+ ADCSBB (up,%rax,8), %r11
+ mov %r11, 32(rp,%rax,8) C offset 32
+ adc R32(%rax), R32(%rax) C rax is zero after loop
+ shr R8(%rcx), %r8
+ ADDSUB %r8, %rax
+IFRSB( neg %rax)
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ') C cnt
+IFDOS(` mov 64(%rsp), %r9 ') C cy
+ push %rbx
+ neg cy
+ sbb R32(%rbx), R32(%rbx) C initialise CF save register
+ jmp L(ent)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreinhm/aorsmul_1.asm b/gmp/mpn/x86_64/coreinhm/aorsmul_1.asm
new file mode 100644
index 0000000000..b768905b93
--- /dev/null
+++ b/gmp/mpn/x86_64/coreinhm/aorsmul_1.asm
@@ -0,0 +1,187 @@
+dnl AMD64 mpn_addmul_1 and mpn_submul_1 optimised for Intel Nehalem.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9
+C AMD K10
+C AMD bull
+C AMD pile
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core
+C Intel NHM 4.55 with minor fluctuations
+C Intel SBR
+C Intel IBR
+C Intel HWL
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimization tool suite written by David Harvey and Torbjorn Granlund.
+
+C N.B.: Be careful if editing, making sure the loop alignment padding does not
+C become large, as we currently fall into it.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0', `%rcx') C r9
+
+define(`n', `%rbx')
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`func', `mpn_submul_1')
+')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ push %rbx
+
+ mov (up), %rax
+ lea -8(up,n_param,8), up
+ mov (rp), %r8
+ lea -8(rp,n_param,8), rp
+
+ test $1, R8(n_param)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n_param)
+ jnz L(b10)
+
+L(b00): mov $3, R32(n)
+ sub n_param, n
+ mul v0
+ mov $0, R32(%r11)
+ mov %r8, %r10
+ ADDSUB %rax, %r10
+ mov -8(up,n,8), %rax
+ adc %rdx, %r11
+ jmp L(lo0)
+
+L(b10): mov $1, R32(n)
+ sub n_param, n
+ mul v0
+ mov %r8, %r10
+ mov $0, R32(%r11)
+ ADDSUB %rax, %r10
+ mov 8(up,n,8), %rax
+ adc %rdx, %r11
+ jmp L(lo2)
+
+L(bx1): test $2, R8(n_param)
+ jz L(b01)
+
+L(b11): mov $2, R32(n)
+ sub n_param, n
+ mul v0
+ ADDSUB %rax, %r8
+ mov $0, R32(%r9)
+ mov (up,n,8), %rax
+ adc %rdx, %r9
+ jmp L(lo3)
+
+L(b01): mov $0, R32(n)
+ sub n_param, n
+ xor %r11, %r11
+ add $4, n
+ jc L(end)
+
+ ALIGN(32)
+L(top): mul v0
+ ADDSUB %rax, %r8
+ mov $0, R32(%r9)
+ mov -16(up,n,8), %rax
+ adc %rdx, %r9
+L(lo1): mul v0
+ ADDSUB %r11, %r8
+ mov $0, R32(%r11)
+ mov -16(rp,n,8), %r10
+ adc $0, %r9
+ ADDSUB %rax, %r10
+ mov -8(up,n,8), %rax
+ adc %rdx, %r11
+ mov %r8, -24(rp,n,8)
+ ADDSUB %r9, %r10
+ adc $0, %r11
+L(lo0): mov -8(rp,n,8), %r8
+ mul v0
+ ADDSUB %rax, %r8
+ mov $0, R32(%r9)
+ mov (up,n,8), %rax
+ adc %rdx, %r9
+ mov %r10, -16(rp,n,8)
+ ADDSUB %r11, %r8
+ adc $0, %r9
+L(lo3): mul v0
+ mov (rp,n,8), %r10
+ mov $0, R32(%r11)
+ ADDSUB %rax, %r10
+ mov 8(up,n,8), %rax
+ adc %rdx, %r11
+ mov %r8, -8(rp,n,8)
+ ADDSUB %r9, %r10
+ adc $0, %r11
+L(lo2): mov 8(rp,n,8), %r8
+ mov %r10, (rp,n,8)
+ add $4, n
+ jnc L(top)
+
+L(end): mul v0
+ ADDSUB %rax, %r8
+ mov $0, R32(%rax)
+ adc %rdx, %rax
+ ADDSUB %r11, %r8
+ adc $0, %rax
+ mov %r8, (rp)
+
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/coreinhm/gmp-mparam.h b/gmp/mpn/x86_64/coreinhm/gmp-mparam.h
new file mode 100644
index 0000000000..6a7c03639f
--- /dev/null
+++ b/gmp/mpn/x86_64/coreinhm/gmp-mparam.h
@@ -0,0 +1,231 @@
+/* Nehalem gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2012, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 2667 MHz Core i7 Nehalem */
+/* FFT tuning limit = 100000000 */
+/* Generated by tuneup.c, 2014-03-18, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 2
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 11
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 16
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 9
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 16
+
+#define MUL_TOOM22_THRESHOLD 18
+#define MUL_TOOM33_THRESHOLD 60
+#define MUL_TOOM44_THRESHOLD 166
+#define MUL_TOOM6H_THRESHOLD 228
+#define MUL_TOOM8H_THRESHOLD 309
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 63
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 114
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 104
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 113
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 147
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 28
+#define SQR_TOOM3_THRESHOLD 93
+#define SQR_TOOM4_THRESHOLD 250
+#define SQR_TOOM6_THRESHOLD 351
+#define SQR_TOOM8_THRESHOLD 454
+
+#define MULMID_TOOM42_THRESHOLD 28
+
+#define MULMOD_BNM1_THRESHOLD 12
+#define SQRMOD_BNM1_THRESHOLD 15
+
+#define MUL_FFT_MODF_THRESHOLD 380 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 380, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 10, 5}, { 21, 6}, { 21, 7}, { 11, 6}, \
+ { 23, 7}, { 21, 8}, { 11, 7}, { 24, 8}, \
+ { 13, 7}, { 27, 8}, { 15, 7}, { 31, 8}, \
+ { 21, 9}, { 11, 8}, { 27, 9}, { 15, 8}, \
+ { 33, 9}, { 19, 8}, { 39, 9}, { 23, 8}, \
+ { 47, 9}, { 27,10}, { 15, 9}, { 39,10}, \
+ { 23, 9}, { 51,11}, { 15,10}, { 31, 9}, \
+ { 67,10}, { 39, 9}, { 83,10}, { 47, 9}, \
+ { 95,10}, { 55,11}, { 31,10}, { 79,11}, \
+ { 47,10}, { 95,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 135,11}, { 79,10}, \
+ { 159, 9}, { 319,10}, { 167,11}, { 95,10}, \
+ { 191, 9}, { 383,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511,11}, { 143,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 319,12}, { 95,11}, \
+ { 191,10}, { 383, 9}, { 767,11}, { 207,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 271,10}, { 543,11}, { 287,10}, { 575,11}, \
+ { 303,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 415,10}, { 831,12}, { 223,11}, \
+ { 447,10}, { 895,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087,12}, \
+ { 287,11}, { 575,10}, { 1151,11}, { 607,12}, \
+ { 319,11}, { 671,12}, { 351,11}, { 703,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,12}, { 447,11}, { 895,12}, { 479,14}, \
+ { 127,13}, { 255,12}, { 511,11}, { 1023,12}, \
+ { 543,11}, { 1087,12}, { 575,11}, { 1151,12}, \
+ { 607,13}, { 319,12}, { 703,11}, { 1407,13}, \
+ { 383,12}, { 831,13}, { 447,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1087,11}, { 2175,13}, \
+ { 575,12}, { 1215,11}, { 2431,13}, { 639,12}, \
+ { 1279,13}, { 703,12}, { 1407,14}, { 383,13}, \
+ { 767,12}, { 1535,13}, { 831,12}, { 1663,13}, \
+ { 959,14}, { 511,13}, { 1087,12}, { 2175,13}, \
+ { 1215,12}, { 2431,14}, { 639,13}, { 1343,12}, \
+ { 2687,13}, { 1407,12}, { 2815,14}, { 767,13}, \
+ { 1663,14}, { 895,13}, { 1919,15}, { 511,14}, \
+ { 1023,13}, { 2175,14}, { 1151,13}, { 2431,12}, \
+ { 4863,14}, { 1279,13}, { 2687,14}, { 1407,13}, \
+ { 2815,15}, { 767,14}, { 1535,13}, { 3071,14}, \
+ { 1663,13}, { 3455,14}, { 1791,13}, { 3583,14}, \
+ { 1919,16}, { 511,15}, { 1023,14}, { 2431,13}, \
+ { 4863,15}, { 1279,14}, { 2943,13}, { 5887,15}, \
+ { 1535,14}, { 3455,15}, { 1791,14}, { 3839,16}, \
+ { 1023,15}, { 2047,14}, { 4223,15}, { 2303,14}, \
+ { 4863,15}, { 2815,14}, { 5887,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 203
+#define MUL_FFT_THRESHOLD 4032
+
+#define SQR_FFT_MODF_THRESHOLD 312 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 312, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
+ { 21, 7}, { 11, 6}, { 23, 7}, { 21, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 21, 9}, { 11, 8}, \
+ { 27, 9}, { 15, 8}, { 33, 9}, { 19, 8}, \
+ { 41, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 47,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 83,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 79,11}, { 47,10}, { 95,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511,10}, { 135,11}, { 79,10}, { 159, 9}, \
+ { 319,11}, { 95,10}, { 191, 9}, { 383,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
+ { 271, 9}, { 543,11}, { 143,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 319, 9}, { 639,12}, \
+ { 95,11}, { 191,10}, { 383, 9}, { 767,11}, \
+ { 207,13}, { 63,12}, { 127,11}, { 255,10}, \
+ { 511, 9}, { 1023,11}, { 271,10}, { 543,11}, \
+ { 287,10}, { 575,11}, { 303,12}, { 159,11}, \
+ { 319,10}, { 639, 9}, { 1279,11}, { 351,10}, \
+ { 703,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,10}, { 831,12}, { 223,11}, { 447,10}, \
+ { 895,11}, { 479,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087,12}, \
+ { 287,11}, { 575,10}, { 1151,11}, { 607,12}, \
+ { 319,11}, { 639,10}, { 1279,11}, { 671,12}, \
+ { 351,11}, { 703,13}, { 191,12}, { 383,11}, \
+ { 767,12}, { 415,11}, { 831,12}, { 447,11}, \
+ { 895,12}, { 479,11}, { 959,14}, { 127,13}, \
+ { 255,12}, { 511,11}, { 1023,12}, { 543,11}, \
+ { 1087,12}, { 575,11}, { 1151,12}, { 607,13}, \
+ { 319,12}, { 639,11}, { 1279,12}, { 671,11}, \
+ { 1343,12}, { 703,11}, { 1407,13}, { 383,12}, \
+ { 767,11}, { 1535,12}, { 831,13}, { 447,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1087,13}, \
+ { 575,12}, { 1215,13}, { 639,12}, { 1343,13}, \
+ { 703,12}, { 1407,14}, { 383,13}, { 767,12}, \
+ { 1535,13}, { 831,12}, { 1663,13}, { 959,14}, \
+ { 511,13}, { 1087,12}, { 2175,13}, { 1215,12}, \
+ { 2431,14}, { 639,13}, { 1279,12}, { 2559,13}, \
+ { 1343,12}, { 2687,13}, { 1407,12}, { 2815,14}, \
+ { 767,13}, { 1663,14}, { 895,13}, { 1791,12}, \
+ { 3583,13}, { 1919,15}, { 511,14}, { 1023,13}, \
+ { 2175,14}, { 1151,13}, { 2431,12}, { 4863,14}, \
+ { 1279,13}, { 2687,14}, { 1407,13}, { 2815,15}, \
+ { 767,14}, { 1663,13}, { 3455,14}, { 1791,13}, \
+ { 3583,16}, { 511,15}, { 1023,14}, { 2303,13}, \
+ { 4607,14}, { 2431,13}, { 4863,15}, { 1279,14}, \
+ { 2943,13}, { 5887,15}, { 1535,14}, { 3455,15}, \
+ { 1791,14}, { 3839,16}, { 1023,15}, { 2047,14}, \
+ { 4223,15}, { 2303,14}, { 4863,15}, { 2815,14}, \
+ { 5887,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 217
+#define SQR_FFT_THRESHOLD 2752
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 45
+#define MULLO_MUL_N_THRESHOLD 8397
+
+#define DC_DIV_QR_THRESHOLD 46
+#define DC_DIVAPPR_Q_THRESHOLD 135
+#define DC_BDIV_QR_THRESHOLD 38
+#define DC_BDIV_Q_THRESHOLD 31
+
+#define INV_MULMOD_BNM1_THRESHOLD 34
+#define INV_NEWTON_THRESHOLD 212
+#define INV_APPR_THRESHOLD 155
+
+#define BINV_NEWTON_THRESHOLD 254
+#define REDC_1_TO_REDC_2_THRESHOLD 32
+#define REDC_2_TO_REDC_N_THRESHOLD 50
+
+#define MU_DIV_QR_THRESHOLD 1334
+#define MU_DIVAPPR_Q_THRESHOLD 1360
+#define MUPI_DIV_QR_THRESHOLD 85
+#define MU_BDIV_QR_THRESHOLD 1142
+#define MU_BDIV_Q_THRESHOLD 1210
+
+#define POWM_SEC_TABLE 3,46,194,494,1678
+
+#define MATRIX22_STRASSEN_THRESHOLD 21
+#define HGCD_THRESHOLD 141
+#define HGCD_APPR_THRESHOLD 175
+#define HGCD_REDUCE_THRESHOLD 2205
+#define GCD_DC_THRESHOLD 330
+#define GCDEXT_DC_THRESHOLD 361
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 15
+#define GET_STR_PRECOMPUTE_THRESHOLD 21
+#define SET_STR_DC_THRESHOLD 517
+#define SET_STR_PRECOMPUTE_THRESHOLD 1430
+
+#define FAC_DSC_THRESHOLD 351
+#define FAC_ODD_THRESHOLD 43
diff --git a/gmp/mpn/x86_64/coreinhm/hamdist.asm b/gmp/mpn/x86_64/coreinhm/hamdist.asm
new file mode 100644
index 0000000000..93e1e5632b
--- /dev/null
+++ b/gmp/mpn/x86_64/coreinhm/hamdist.asm
@@ -0,0 +1,38 @@
+dnl AMD64 mpn_hamdist -- hamming distance.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_hamdist)
+include_mpn(`x86_64/k10/hamdist.asm')
diff --git a/gmp/mpn/x86_64/coreinhm/popcount.asm b/gmp/mpn/x86_64/coreinhm/popcount.asm
new file mode 100644
index 0000000000..8f22a715b6
--- /dev/null
+++ b/gmp/mpn/x86_64/coreinhm/popcount.asm
@@ -0,0 +1,38 @@
+dnl AMD64 mpn_popcount -- population count.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_popcount)
+include_mpn(`x86_64/k10/popcount.asm')
diff --git a/gmp/mpn/x86_64/coreinhm/redc_1.asm b/gmp/mpn/x86_64/coreinhm/redc_1.asm
new file mode 100644
index 0000000000..4d9261d8f9
--- /dev/null
+++ b/gmp/mpn/x86_64/coreinhm/redc_1.asm
@@ -0,0 +1,544 @@
+dnl X86-64 mpn_redc_1 optimised for Intel Nehalem and Westmere.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C AMD bull ?
+C AMD pile ?
+C AMD steam ?
+C AMD bobcat ?
+C AMD jaguar ?
+C Intel P4 ?
+C Intel core ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel IBR ?
+C Intel HWL ?
+C Intel BWL ?
+C Intel atom ?
+C VIA nano ?
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Micro-optimise, none performed thus far.
+C * Consider inlining mpn_add_n.
+C * Single basecases out before the pushes.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`mp_param', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`u0inv', `%r8') C stack
+
+define(`i', `%r14')
+define(`j', `%r15')
+define(`mp', `%r12')
+define(`q0', `%r13')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+define(`ALIGNx', `ALIGN(16)')
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_redc_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov (up), q0
+ mov n, j C outer loop induction var
+ lea (mp_param,n,8), mp
+ lea (up,n,8), up
+ neg n
+ imul u0inv, q0 C first iteration q0
+
+ test $1, R8(n)
+ jz L(bx0)
+
+L(bx1): test $2, R8(n)
+ jz L(b3)
+
+L(b1): cmp $-1, R32(n)
+ jz L(n1)
+
+L(otp1):lea 3(n), i
+ mov (mp,n,8), %rax
+ mov (up,n,8), %rbp
+ mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov 8(mp,n,8), %rax
+ adc %rdx, %r9
+ mul q0
+ mov $0, R32(%r11)
+ mov 8(up,n,8), %rbx
+ add %rax, %rbx
+ mov 16(mp,n,8), %rax
+ adc %rdx, %r11
+ add %r9, %rbx
+ adc $0, %r11
+ mov 16(up,n,8), %rbp
+ mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov 24(mp,n,8), %rax
+ adc %rdx, %r9
+ mov %rbx, 8(up,n,8)
+ imul u0inv, %rbx C next q limb
+ jmp L(e1)
+
+ ALIGNx
+L(tp1): mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov -16(mp,i,8), %rax
+ adc %rdx, %r9
+ mul q0
+ add %r11, %rbp
+ mov $0, R32(%r11)
+ mov -16(up,i,8), %r10
+ adc $0, %r9
+ add %rax, %r10
+ mov -8(mp,i,8), %rax
+ adc %rdx, %r11
+ mov %rbp, -24(up,i,8)
+ add %r9, %r10
+ adc $0, %r11
+ mov -8(up,i,8), %rbp
+ mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov (mp,i,8), %rax
+ adc %rdx, %r9
+ mov %r10, -16(up,i,8)
+L(e1): add %r11, %rbp
+ adc $0, %r9
+ mul q0
+ mov (up,i,8), %r10
+ mov $0, R32(%r11)
+ add %rax, %r10
+ mov 8(mp,i,8), %rax
+ adc %rdx, %r11
+ mov %rbp, -8(up,i,8)
+ add %r9, %r10
+ adc $0, %r11
+ mov 8(up,i,8), %rbp
+ mov %r10, (up,i,8)
+ add $4, i
+ jnc L(tp1)
+
+L(ed1): mul q0
+ add %rax, %rbp
+ adc $0, %rdx
+ add %r11, %rbp
+ adc $0, %rdx
+ mov %rbp, I(-8(up),-24(up,i,8))
+ mov %rdx, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp1)
+ jmp L(cj)
+
+L(b3): cmp $-3, R32(n)
+ jz L(n3)
+
+L(otp3):lea 5(n), i
+ mov (mp,n,8), %rax
+ mov (up,n,8), %rbp
+ mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov 8(mp,n,8), %rax
+ adc %rdx, %r9
+ mul q0
+ mov 8(up,n,8), %rbx
+ mov $0, R32(%r11)
+ add %rax, %rbx
+ mov 16(mp,n,8), %rax
+ adc %rdx, %r11
+ add %r9, %rbx
+ adc $0, %r11
+ mov 16(up,n,8), %rbp
+ mov %rbx, 8(up,n,8)
+ imul u0inv, %rbx C next q limb
+C jmp L(tp3)
+
+ ALIGNx
+L(tp3): mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov -16(mp,i,8), %rax
+ adc %rdx, %r9
+ mul q0
+ add %r11, %rbp
+ mov $0, R32(%r11)
+ mov -16(up,i,8), %r10
+ adc $0, %r9
+ add %rax, %r10
+ mov -8(mp,i,8), %rax
+ adc %rdx, %r11
+ mov %rbp, -24(up,i,8)
+ add %r9, %r10
+ adc $0, %r11
+ mov -8(up,i,8), %rbp
+ mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov (mp,i,8), %rax
+ adc %rdx, %r9
+ mov %r10, -16(up,i,8)
+ add %r11, %rbp
+ adc $0, %r9
+ mul q0
+ mov (up,i,8), %r10
+ mov $0, R32(%r11)
+ add %rax, %r10
+ mov 8(mp,i,8), %rax
+ adc %rdx, %r11
+ mov %rbp, -8(up,i,8)
+ add %r9, %r10
+ adc $0, %r11
+ mov 8(up,i,8), %rbp
+ mov %r10, (up,i,8)
+ add $4, i
+ jnc L(tp3)
+
+L(ed3): mul q0
+ add %rax, %rbp
+ adc $0, %rdx
+ add %r11, %rbp
+ adc $0, %rdx
+ mov %rbp, I(-8(up),-24(up,i,8))
+ mov %rdx, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp3)
+C jmp L(cj)
+
+L(cj):
+IFSTD(` lea (up,n,8), up C param 2: up
+ lea (up,n,8), %rdx C param 3: up - n
+ neg R32(n) ') C param 4: n
+
+IFDOS(` lea (up,n,8), %rdx C param 2: up
+ lea (%rdx,n,8), %r8 C param 3: up - n
+ neg R32(n)
+ mov n, %r9 C param 4: n
+ mov rp, %rcx ') C param 1: rp
+
+ CALL( mpn_add_n)
+
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(bx0): test $2, R8(n)
+ jnz L(b2)
+
+L(b0):
+L(otp0):lea 2(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov $0, R32(%r11)
+ mov (up,n,8), %r10
+ add %rax, %r10
+ mov 8(mp,n,8), %rax
+ adc %rdx, %r11
+ mov 8(up,n,8), %rbx
+ mul q0
+ add %rax, %rbx
+ mov $0, R32(%r9)
+ mov 16(mp,n,8), %rax
+ adc %rdx, %r9
+ add %r11, %rbx
+ adc $0, %r9
+ mul q0
+ mov 16(up,n,8), %r10
+ mov $0, R32(%r11)
+ add %rax, %r10
+ mov 24(mp,n,8), %rax
+ adc %rdx, %r11
+ mov %rbx, 8(up,n,8)
+ imul u0inv, %rbx C next q limb
+ jmp L(e0)
+
+ ALIGNx
+L(tp0): mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov -16(mp,i,8), %rax
+ adc %rdx, %r9
+ mul q0
+ add %r11, %rbp
+ mov $0, R32(%r11)
+ mov -16(up,i,8), %r10
+ adc $0, %r9
+ add %rax, %r10
+ mov -8(mp,i,8), %rax
+ adc %rdx, %r11
+ mov %rbp, -24(up,i,8)
+ add %r9, %r10
+ adc $0, %r11
+ mov -8(up,i,8), %rbp
+ mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov (mp,i,8), %rax
+ adc %rdx, %r9
+ mov %r10, -16(up,i,8)
+ add %r11, %rbp
+ adc $0, %r9
+ mul q0
+ mov (up,i,8), %r10
+ mov $0, R32(%r11)
+ add %rax, %r10
+ mov 8(mp,i,8), %rax
+ adc %rdx, %r11
+ mov %rbp, -8(up,i,8)
+L(e0): add %r9, %r10
+ adc $0, %r11
+ mov 8(up,i,8), %rbp
+ mov %r10, (up,i,8)
+ add $4, i
+ jnc L(tp0)
+
+L(ed0): mul q0
+ add %rax, %rbp
+ adc $0, %rdx
+ add %r11, %rbp
+ adc $0, %rdx
+ mov %rbp, I(-8(up),-24(up,i,8))
+ mov %rdx, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp0)
+ jmp L(cj)
+
+L(b2): cmp $-2, R32(n)
+ jz L(n2)
+
+L(otp2):lea 4(n), i
+ mov (mp,n,8), %rax
+ mul q0
+ mov (up,n,8), %r10
+ mov $0, R32(%r11)
+ add %rax, %r10
+ mov 8(mp,n,8), %rax
+ adc %rdx, %r11
+ mov 8(up,n,8), %rbx
+ mul q0
+ add %rax, %rbx
+ mov $0, R32(%r9)
+ mov 16(mp,n,8), %rax
+ adc %rdx, %r9
+ mul q0
+ add %r11, %rbx
+ mov $0, R32(%r11)
+ mov 16(up,n,8), %r10
+ adc $0, %r9
+ add %rax, %r10
+ mov 24(mp,n,8), %rax
+ adc %rdx, %r11
+ mov %rbx, 8(up,n,8)
+ imul u0inv, %rbx C next q limb
+ jmp L(e2)
+
+ ALIGNx
+L(tp2): mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov -16(mp,i,8), %rax
+ adc %rdx, %r9
+ mul q0
+ add %r11, %rbp
+ mov $0, R32(%r11)
+ mov -16(up,i,8), %r10
+ adc $0, %r9
+ add %rax, %r10
+ mov -8(mp,i,8), %rax
+ adc %rdx, %r11
+ mov %rbp, -24(up,i,8)
+L(e2): add %r9, %r10
+ adc $0, %r11
+ mov -8(up,i,8), %rbp
+ mul q0
+ add %rax, %rbp
+ mov $0, R32(%r9)
+ mov (mp,i,8), %rax
+ adc %rdx, %r9
+ mov %r10, -16(up,i,8)
+ add %r11, %rbp
+ adc $0, %r9
+ mul q0
+ mov (up,i,8), %r10
+ mov $0, R32(%r11)
+ add %rax, %r10
+ mov 8(mp,i,8), %rax
+ adc %rdx, %r11
+ mov %rbp, -8(up,i,8)
+ add %r9, %r10
+ adc $0, %r11
+ mov 8(up,i,8), %rbp
+ mov %r10, (up,i,8)
+ add $4, i
+ jnc L(tp2)
+
+L(ed2): mul q0
+ add %rax, %rbp
+ adc $0, %rdx
+ add %r11, %rbp
+ adc $0, %rdx
+ mov %rbp, I(-8(up),-24(up,i,8))
+ mov %rdx, (up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp2)
+ jmp L(cj)
+
+L(n1): mov (mp_param), %rax
+ mul q0
+ add -8(up), %rax
+ adc (up), %rdx
+ mov %rdx, (rp)
+ mov $0, R32(%rax)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+L(n2): mov (mp_param), %rax
+ mov -16(up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ mov -8(up), %r10
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, q0
+ imul u0inv, q0 C next q0
+ mov -16(mp), %rax
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ mov (up), %r14
+ mul q0
+ add %rax, %r14
+ adc $0, %rdx
+ add %r9, %r14
+ adc $0, %rdx
+ xor R32(%rax), R32(%rax)
+ add %r11, %r14
+ adc 8(up), %rdx
+ mov %r14, (rp)
+ mov %rdx, 8(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+ ALIGNx
+L(n3): mov -24(mp), %rax
+ mov -24(up), %r10
+ mul q0
+ add %rax, %r10
+ mov -16(mp), %rax
+ mov %rdx, %r11
+ adc $0, %r11
+ mov -16(up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -8(mp), %rax
+ add %r11, %rbp
+ mov -8(up), %r10
+ adc $0, %r9
+ mul q0
+ mov %rbp, q0
+ imul u0inv, q0 C next q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ mov %rbp, -16(up)
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, -8(up)
+ mov %r11, -24(up) C up[0]
+ lea 8(up), up C up++
+ dec j
+ jnz L(n3)
+
+ mov -48(up), %rdx
+ mov -40(up), %rbx
+ xor R32(%rax), R32(%rax)
+ add %rbp, %rdx
+ adc %r10, %rbx
+ adc -8(up), %r11
+ mov %rdx, (rp)
+ mov %rbx, 8(rp)
+ mov %r11, 16(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/coreinhm/sec_tabselect.asm b/gmp/mpn/x86_64/coreinhm/sec_tabselect.asm
new file mode 100644
index 0000000000..e4360341d9
--- /dev/null
+++ b/gmp/mpn/x86_64/coreinhm/sec_tabselect.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_sec_tabselect.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_sec_tabselect)
+include_mpn(`x86_64/fastsse/sec_tabselect.asm')
diff --git a/gmp/mpn/x86_64/coreisbr/addmul_2.asm b/gmp/mpn/x86_64/coreisbr/addmul_2.asm
new file mode 100644
index 0000000000..21f0bf465f
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/addmul_2.asm
@@ -0,0 +1,224 @@
+dnl AMD64 mpn_addmul_2 optimised for Intel Sandy Bridge.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C AMD K8,K9
+C AMD K10
+C AMD bull
+C AMD pile
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core
+C Intel NHM
+C Intel SBR 2.93 this
+C Intel IBR 2.66 this
+C Intel HWL 2.5 2.15
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C This code is the result of running a code generation and optimisation tool
+C suite written by David Harvey and Torbjorn Granlund.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`vp', `%rcx') C r9
+
+define(`n', `%rcx')
+define(`v0', `%rbx')
+define(`v1', `%rbp')
+define(`w0', `%r8')
+define(`w1', `%r9')
+define(`w2', `%r10')
+define(`w3', `%r11')
+define(`X0', `%r12')
+define(`X1', `%r13')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_addmul_2)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ mov (up), %rax
+
+ mov n_param, n
+ neg n
+
+ lea (up,n_param,8), up
+ lea 8(rp,n_param,8), rp
+ mul v0
+
+ test $1, R8(n)
+ jnz L(bx1)
+
+L(bx0): mov -8(rp,n,8), X0
+ mov %rdx, w1
+ add %rax, X0
+ adc $0, w1
+ mov (up,n,8), %rax
+ xor w0, w0
+ xor w3, w3
+ test $2, R8(n)
+ jnz L(b10)
+
+L(b00): nop C this nop make loop go faster on SBR!
+ mul v1
+ mov (rp,n,8), X1
+ jmp L(lo0)
+
+L(b10): lea -2(n), n
+ jmp L(lo2)
+
+L(bx1): mov -8(rp,n,8), X1
+ mov %rdx, w3
+ add %rax, X1
+ adc $0, w3
+ mov (up,n,8), %rax
+ xor w1, w1
+ xor w2, w2
+ test $2, R8(n)
+ jz L(b11)
+
+L(b01): mov (rp,n,8), X0
+ inc n
+ jmp L(lo1)
+
+L(b11): dec n
+ jmp L(lo3)
+
+ ALIGN(32)
+L(top):
+L(lo1): mul v1
+ mov %rdx, w0 C 1
+ add %rax, X0 C 0
+ adc $0, w0 C 1
+ add w1, X1 C 3
+ adc $0, w3 C 0
+ add w2, X0 C 0
+ adc $0, w0 C 1
+ mov (up,n,8), %rax
+ mul v0
+ add %rax, X0 C 0
+ mov %rdx, w1 C 1
+ adc $0, w1 C 1
+ mov (up,n,8), %rax
+ mul v1
+ mov X1, -16(rp,n,8) C 3
+ mov (rp,n,8), X1 C 1
+ add w3, X0 C 0
+ adc $0, w1 C 1
+L(lo0): mov %rdx, w2 C 2
+ mov X0, -8(rp,n,8) C 0
+ add %rax, X1 C 1
+ adc $0, w2 C 2
+ mov 8(up,n,8), %rax
+ add w0, X1 C 1
+ adc $0, w2 C 2
+ mul v0
+ add %rax, X1 C 1
+ mov %rdx, w3 C 2
+ adc $0, w3 C 2
+ mov 8(up,n,8), %rax
+L(lo3): mul v1
+ add w1, X1 C 1
+ mov 8(rp,n,8), X0 C 2
+ adc $0, w3 C 2
+ mov %rdx, w0 C 3
+ add %rax, X0 C 2
+ adc $0, w0 C 3
+ mov 16(up,n,8), %rax
+ mul v0
+ add w2, X0 C 2
+ mov X1, (rp,n,8) C 1
+ mov %rdx, w1 C 3
+ adc $0, w0 C 3
+ add %rax, X0 C 2
+ adc $0, w1 C 3
+ mov 16(up,n,8), %rax
+ add w3, X0 C 2
+ adc $0, w1 C 3
+L(lo2): mul v1
+ mov 16(rp,n,8), X1 C 3
+ add %rax, X1 C 3
+ mov %rdx, w2 C 4
+ adc $0, w2 C 4
+ mov 24(up,n,8), %rax
+ mov X0, 8(rp,n,8) C 2
+ mul v0
+ add w0, X1 C 3
+ mov %rdx, w3 C 4
+ adc $0, w2 C 4
+ add %rax, X1 C 3
+ mov 24(up,n,8), %rax
+ mov 24(rp,n,8), X0 C 0 useless but harmless final read
+ adc $0, w3 C 4
+ add $4, n
+ jnc L(top)
+
+L(end): mul v1
+ add w1, X1
+ adc $0, w3
+ add w2, %rax
+ adc $0, %rdx
+ mov X1, I(-16(rp),-16(rp,n,8))
+ add w3, %rax
+ adc $0, %rdx
+ mov %rax, I(-8(rp),-8(rp,n,8))
+ mov %rdx, %rax
+
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/aorrlsh1_n.asm b/gmp/mpn/x86_64/coreisbr/aorrlsh1_n.asm
new file mode 100644
index 0000000000..2319a80060
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/aorrlsh1_n.asm
@@ -0,0 +1,54 @@
+dnl AMD64 mpn_addlsh1_n -- rp[] = up[] + (vp[] << 1)
+dnl AMD64 mpn_rsblsh1_n -- rp[] = (vp[] << 1) - up[]
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 1)
+define(RSH, 63)
+
+ifdef(`OPERATION_addlsh1_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func_n, mpn_addlsh1_n)
+ define(func_nc, mpn_addlsh1_nc)')
+ifdef(`OPERATION_rsblsh1_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func_n, mpn_rsblsh1_n)
+ define(func_nc, mpn_rsblsh1_nc)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_addlsh1_nc mpn_rsblsh1_n mpn_rsblsh1_nc)
+include_mpn(`x86_64/coreisbr/aorrlshC_n.asm')
diff --git a/gmp/mpn/x86_64/coreisbr/aorrlsh2_n.asm b/gmp/mpn/x86_64/coreisbr/aorrlsh2_n.asm
new file mode 100644
index 0000000000..9416d5a164
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/aorrlsh2_n.asm
@@ -0,0 +1,56 @@
+dnl AMD64 mpn_addlsh2_n -- rp[] = up[] + (vp[] << 1)
+dnl AMD64 mpn_rsblsh2_n -- rp[] = (vp[] << 1) - up[]
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 2)
+define(RSH, 62)
+
+ifdef(`OPERATION_addlsh2_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func_n, mpn_addlsh2_n)
+ define(func_nc, mpn_addlsh2_nc)')
+ifdef(`OPERATION_rsblsh2_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func_n, mpn_rsblsh2_n)
+ define(func_nc, mpn_rsblsh2_nc)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+C mpn_rsblsh2_nc removed below, its idea of carry-in is inconsistent with
+C refmpn_rsblsh2_nc
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_addlsh2_nc mpn_rsblsh2_n)
+include_mpn(`x86_64/coreisbr/aorrlshC_n.asm')
diff --git a/gmp/mpn/x86_64/coreisbr/aorrlshC_n.asm b/gmp/mpn/x86_64/coreisbr/aorrlshC_n.asm
new file mode 100644
index 0000000000..23ace41889
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/aorrlshC_n.asm
@@ -0,0 +1,173 @@
+dnl AMD64 mpn_addlshC_n -- rp[] = up[] + (vp[] << C)
+dnl AMD64 mpn_rsblshC_n -- rp[] = (vp[] << C) - up[]
+
+dnl Copyright 2009-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 ?
+C Intel core2 3.25
+C Intel NHM 4
+C Intel SBR 2 C (or 1.95 when L(top)'s alignment = 16 (mod 32))
+C Intel atom ?
+C VIA nano ?
+
+C This code probably runs close to optimally on Sandy Bridge (using 4-way
+C unrolling). It also runs reasonably well on Core 2, but it runs poorly on
+C all other processors, including Nehalem.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cy', `%r8')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbp
+ mov cy, %rax
+ neg %rax C set msb on carry
+ xor R32(%rbp), R32(%rbp) C limb carry
+ mov (vp), %r8
+ shrd $RSH, %r8, %rbp
+ mov R32(n), R32(%r9)
+ and $3, R32(%r9)
+ je L(b00)
+ cmp $2, R32(%r9)
+ jc L(b01)
+ je L(b10)
+ jmp L(b11)
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(func_n)
+ FUNC_ENTRY(4)
+ push %rbp
+ xor R32(%rbp), R32(%rbp) C limb carry
+ mov (vp), %r8
+ shrd $RSH, %r8, %rbp
+ mov R32(n), R32(%rax)
+ and $3, R32(%rax)
+ je L(b00)
+ cmp $2, R32(%rax)
+ jc L(b01)
+ je L(b10)
+
+L(b11): mov 8(vp), %r9
+ shrd $RSH, %r9, %r8
+ mov 16(vp), %r10
+ shrd $RSH, %r10, %r9
+ add R32(%rax), R32(%rax) C init carry flag
+ ADCSBB (up), %rbp
+ ADCSBB 8(up), %r8
+ ADCSBB 16(up), %r9
+ mov %rbp, (rp)
+ mov %r8, 8(rp)
+ mov %r9, 16(rp)
+ mov %r10, %rbp
+ lea 24(up), up
+ lea 24(vp), vp
+ lea 24(rp), rp
+ sbb R32(%rax), R32(%rax) C save carry flag
+ sub $3, n
+ ja L(top)
+ jmp L(end)
+
+L(b01): add R32(%rax), R32(%rax) C init carry flag
+ ADCSBB (up), %rbp
+ mov %rbp, (rp)
+ mov %r8, %rbp
+ lea 8(up), up
+ lea 8(vp), vp
+ lea 8(rp), rp
+ sbb R32(%rax), R32(%rax) C save carry flag
+ sub $1, n
+ ja L(top)
+ jmp L(end)
+
+L(b10): mov 8(vp), %r9
+ shrd $RSH, %r9, %r8
+ add R32(%rax), R32(%rax) C init carry flag
+ ADCSBB (up), %rbp
+ ADCSBB 8(up), %r8
+ mov %rbp, (rp)
+ mov %r8, 8(rp)
+ mov %r9, %rbp
+ lea 16(up), up
+ lea 16(vp), vp
+ lea 16(rp), rp
+ sbb R32(%rax), R32(%rax) C save carry flag
+ sub $2, n
+ ja L(top)
+ jmp L(end)
+
+ ALIGN(16)
+L(top): mov (vp), %r8
+ shrd $RSH, %r8, %rbp
+L(b00): mov 8(vp), %r9
+ shrd $RSH, %r9, %r8
+ mov 16(vp), %r10
+ shrd $RSH, %r10, %r9
+ mov 24(vp), %r11
+ shrd $RSH, %r11, %r10
+ lea 32(vp), vp
+ add R32(%rax), R32(%rax) C restore carry flag
+ ADCSBB (up), %rbp
+ ADCSBB 8(up), %r8
+ ADCSBB 16(up), %r9
+ ADCSBB 24(up), %r10
+ lea 32(up), up
+ mov %rbp, (rp)
+ mov %r8, 8(rp)
+ mov %r9, 16(rp)
+ mov %r10, 24(rp)
+ mov %r11, %rbp
+ lea 32(rp), rp
+ sbb R32(%rax), R32(%rax) C save carry flag
+ sub $4, n
+ jnz L(top)
+
+L(end): shr $RSH, %rbp
+ add R32(%rax), R32(%rax) C restore carry flag
+ ADCSBB $0, %rbp
+ mov %rbp, %rax
+ pop %rbp
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/aorrlsh_n.asm b/gmp/mpn/x86_64/coreisbr/aorrlsh_n.asm
new file mode 100644
index 0000000000..db8ee68849
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/aorrlsh_n.asm
@@ -0,0 +1,215 @@
+dnl AMD64 mpn_addlsh_n -- rp[] = up[] + (vp[] << k)
+dnl AMD64 mpn_rsblsh_n -- rp[] = (vp[] << k) - up[]
+dnl Optimised for Sandy Bridge.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 5.25
+C Intel P4 ?
+C Intel core2 3.1
+C Intel NHM 3.95
+C Intel SBR 2.75
+C Intel atom ?
+C VIA nano ?
+
+C The inner-loop probably runs close to optimally on Sandy Bridge (using 4-way
+C unrolling). The rest of the code is quite crude, and could perhaps be made
+C both smaller and faster.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cnt', `%r8')
+define(`cy', `%r9') C for _nc variant
+
+ifdef(`OPERATION_addlsh_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(IFRSB, )
+ define(func_n, mpn_addlsh_n)
+ define(func_nc, mpn_addlsh_nc)')
+ifdef(`OPERATION_rsblsh_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(IFRSB, `$1')
+ define(func_n, mpn_rsblsh_n)
+ define(func_nc, mpn_rsblsh_nc)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+C mpn_rsblsh_nc removed below, its idea of carry-in is inconsistent with
+C refmpn_rsblsh_nc
+MULFUNC_PROLOGUE(mpn_addlsh_n mpn_addlsh_nc mpn_rsblsh_n)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(func_n)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ') C cnt
+ push %rbx
+ xor R32(%rbx), R32(%rbx) C clear CF save register
+L(ent): push %rbp
+ mov R32(n), R32(%rbp)
+ mov n, %rax
+ mov R32(cnt), R32(%rcx)
+ neg R32(%rcx)
+ and $3, R32(%rbp)
+ jz L(b0)
+ lea -32(vp,%rbp,8), vp
+ lea -32(up,%rbp,8), up
+ lea -32(rp,%rbp,8), rp
+ cmp $2, R32(%rbp)
+ jc L(b1)
+ jz L(b2)
+
+L(b3): xor %r8, %r8
+ mov 8(vp), %r9
+ mov 16(vp), %r10
+ shrd R8(%rcx), %r9, %r8
+ shrd R8(%rcx), %r10, %r9
+ mov 24(vp), %r11
+ shrd R8(%rcx), %r11, %r10
+ sub $3, %rax
+ jz L(3)
+ add R32(%rbx), R32(%rbx)
+ lea 32(vp), vp
+ ADCSBB 8(up), %r8
+ ADCSBB 16(up), %r9
+ ADCSBB 24(up), %r10
+ lea 32(up), up
+ jmp L(lo3)
+L(3): add R32(%rbx), R32(%rbx)
+ lea 32(vp), vp
+ ADCSBB 8(up), %r8
+ ADCSBB 16(up), %r9
+ ADCSBB 24(up), %r10
+ jmp L(wd3)
+
+L(b0): mov (vp), %r8
+ mov 8(vp), %r9
+ xor R32(%rbp), R32(%rbp)
+ jmp L(lo0)
+
+L(b1): xor %r10, %r10
+ mov 24(vp), %r11
+ shrd R8(%rcx), %r11, %r10
+ sub $1, %rax
+ jz L(1)
+ add R32(%rbx), R32(%rbx)
+ lea 32(vp), vp
+ ADCSBB 24(up), %r10
+ lea 32(up), up
+ mov (vp), %r8
+ jmp L(lo1)
+L(1): add R32(%rbx), R32(%rbx)
+ ADCSBB 24(up), %r10
+ jmp L(wd1)
+
+L(b2): xor %r9, %r9
+ mov 16(vp), %r10
+ shrd R8(%rcx), %r10, %r9
+ mov 24(vp), %r11
+ shrd R8(%rcx), %r11, %r10
+ sub $2, %rax
+ jz L(2)
+ add R32(%rbx), R32(%rbx)
+ lea 32(vp), vp
+ ADCSBB 16(up), %r9
+ ADCSBB 24(up), %r10
+ lea 32(up), up
+ jmp L(lo2)
+L(2): add R32(%rbx), R32(%rbx)
+ ADCSBB 16(up), %r9
+ ADCSBB 24(up), %r10
+ jmp L(wd2)
+
+ ALIGN(32) C 16-byte alignment is not enough!
+L(top): shrd R8(%rcx), %r11, %r10
+ add R32(%rbx), R32(%rbx)
+ lea 32(vp), vp
+ ADCSBB (up), %rbp
+ ADCSBB 8(up), %r8
+ ADCSBB 16(up), %r9
+ ADCSBB 24(up), %r10
+ mov %rbp, (rp)
+ lea 32(up), up
+L(lo3): mov %r8, 8(rp)
+L(lo2): mov %r9, 16(rp)
+ mov (vp), %r8
+L(lo1): mov %r10, 24(rp)
+ mov 8(vp), %r9
+ mov %r11, %rbp
+ lea 32(rp), rp
+ sbb R32(%rbx), R32(%rbx)
+L(lo0): shrd R8(%rcx), %r8, %rbp
+ mov 16(vp), %r10
+ shrd R8(%rcx), %r9, %r8
+ shrd R8(%rcx), %r10, %r9
+ mov 24(vp), %r11
+ sub $4, %rax
+ jg L(top)
+
+ shrd R8(%rcx), %r11, %r10
+ add R32(%rbx), R32(%rbx)
+ ADCSBB (up), %rbp
+ ADCSBB 8(up), %r8
+ ADCSBB 16(up), %r9
+ ADCSBB 24(up), %r10
+ mov %rbp, (rp)
+L(wd3): mov %r8, 8(rp)
+L(wd2): mov %r9, 16(rp)
+L(wd1): mov %r10, 24(rp)
+ adc R32(%rax), R32(%rax) C rax is zero after loop
+ shr R8(%rcx), %r11
+ ADDSUB %r11, %rax
+IFRSB( neg %rax)
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ') C cnt
+IFDOS(` mov 64(%rsp), %r9 ') C cy
+ push %rbx
+ neg cy
+ sbb R32(%rbx), R32(%rbx) C initialise CF save register
+ jmp L(ent)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/aors_n.asm b/gmp/mpn/x86_64/coreisbr/aors_n.asm
new file mode 100644
index 0000000000..01abf78a0d
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/aors_n.asm
@@ -0,0 +1,198 @@
+dnl AMD64 mpn_add_n, mpn_sub_n optimised for Sandy bridge, Ivy bridge, and
+dnl Haswell.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2010-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9
+C AMD K10
+C AMD bull 1.82 average over 400-600
+C AMD pile 1.83 average over 400-600
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core
+C Intel NHM
+C Intel SBR 1.55 fluctuates
+C Intel IBR 1.55 fluctuates
+C Intel HWL 1.33 fluctuates
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The loop of this code was manually written. It runs close to optimally on
+C Intel SBR, IBR, and HWL far as we know, except for the fluctuation problems.
+C It also runs slightly faster on average on AMD bull and pile.
+C
+C No micro-optimisation has been done.
+C
+C N.B.! The loop alignment padding insns are executed. If editing the code,
+C make sure the padding does not become excessive. It is now a 4-byte nop.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`vp', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`cy', `%r8') C rsp+40 (mpn_add_nc and mpn_sub_nc)
+
+ifdef(`OPERATION_add_n', `
+ define(ADCSBB, adc)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(ADCSBB, sbb)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ xor %r8, %r8
+
+L(ent): mov R32(n), R32(%rax)
+ shr $2, n
+
+ test $1, R8(%rax)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(%rax)
+ jnz L(b10)
+
+L(b00): neg %r8
+ mov (up), %r8
+ mov 8(up), %r9
+ ADCSBB (vp), %r8
+ ADCSBB 8(vp), %r9
+ mov 16(up), %r10
+ mov 24(up), %r11
+ lea 32(up), up
+ ADCSBB 16(vp), %r10
+ ADCSBB 24(vp), %r11
+ lea 32(vp), vp
+ lea -16(rp), rp
+ jmp L(lo0)
+
+L(b10): neg %r8
+ mov (up), %r10
+ mov 8(up), %r11
+ ADCSBB 0(vp), %r10
+ ADCSBB 8(vp), %r11
+ jrcxz L(e2)
+ mov 16(up), %r8
+ mov 24(up), %r9
+ lea 16(up), up
+ ADCSBB 16(vp), %r8
+ ADCSBB 24(vp), %r9
+ lea 16(vp), vp
+ lea (rp), rp
+ jmp L(lo2)
+
+L(e2): mov %r10, (rp)
+ mov %r11, 8(rp)
+ setc R8(%rax)
+ FUNC_EXIT()
+ ret
+
+L(bx1): test $2, R8(%rax)
+ jnz L(b11)
+
+L(b01): neg %r8
+ mov (up), %r11
+ ADCSBB (vp), %r11
+ jrcxz L(e1)
+ mov 8(up), %r8
+ mov 16(up), %r9
+ lea 8(up), up
+ lea -8(rp), rp
+ ADCSBB 8(vp), %r8
+ ADCSBB 16(vp), %r9
+ lea 8(vp), vp
+ jmp L(lo1)
+
+L(e1): mov %r11, (rp)
+ setc R8(%rax)
+ FUNC_EXIT()
+ ret
+
+L(b11): neg %r8
+ mov (up), %r9
+ ADCSBB (vp), %r9
+ mov 8(up), %r10
+ mov 16(up), %r11
+ lea 24(up), up
+ ADCSBB 8(vp), %r10
+ ADCSBB 16(vp), %r11
+ lea 24(vp), vp
+ mov %r9, (rp)
+ lea 8(rp), rp
+ jrcxz L(end)
+
+ ALIGN(32)
+L(top): mov (up), %r8
+ mov 8(up), %r9
+ ADCSBB (vp), %r8
+ ADCSBB 8(vp), %r9
+L(lo2): mov %r10, (rp)
+L(lo1): mov %r11, 8(rp)
+ mov 16(up), %r10
+ mov 24(up), %r11
+ lea 32(up), up
+ ADCSBB 16(vp), %r10
+ ADCSBB 24(vp), %r11
+ lea 32(vp), vp
+L(lo0): mov %r8, 16(rp)
+L(lo3): mov %r9, 24(rp)
+ lea 32(rp), rp
+ dec n
+ jnz L(top)
+
+L(end): mov R32(n), R32(%rax) C zero rax
+ mov %r10, (rp)
+ mov %r11, 8(rp)
+ setc R8(%rax)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+ ALIGN(16)
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ jmp L(ent)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/aorsmul_1.asm b/gmp/mpn/x86_64/coreisbr/aorsmul_1.asm
new file mode 100644
index 0000000000..9f01d9c061
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/aorsmul_1.asm
@@ -0,0 +1,209 @@
+dnl X86-64 mpn_addmul_1 and mpn_submul_1 optimised for Intel Sandy Bridge.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9
+C AMD K10
+C AMD bull
+C AMD pile
+C AMD steam
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core
+C Intel NHM
+C Intel SBR 3.24 (average, fluctuating in 3.20-3.57)
+C Intel IBR 3.04
+C Intel HWL
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimization tool suite written by David Harvey and Torbjörn Granlund.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0', `%rcx') C r9
+
+define(`n', `%rbx')
+
+define(`I',`$1')
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`func', `mpn_submul_1')
+')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+IFDOS(` define(`up', ``%rsi'')') dnl
+IFDOS(` define(`rp', ``%rcx'')') dnl
+IFDOS(` define(`v0', ``%r9'')') dnl
+IFDOS(` define(`r9', ``rdi'')') dnl
+IFDOS(` define(`n_param',``%r8'')') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(func)
+
+IFDOS(``push %rsi '')
+IFDOS(``push %rdi '')
+IFDOS(``mov %rdx, %rsi '')
+
+ mov (up), %rax
+ push %rbx
+ lea (up,n_param,8), up
+ lea (rp,n_param,8), rp
+
+ test $1, R8(n_param)
+ jnz L(b13)
+
+L(b02): xor R32(%r11), R32(%r11)
+ test $2, R8(n_param)
+ jnz L(b2)
+
+L(b0): mov $1, R32(n)
+ sub n_param, n
+ mul v0
+ mov %rdx, %r9
+ mov -8(rp,n,8), %r8
+ jmp L(e0)
+
+ ALIGN(16)
+L(b2): mov $-1, n
+ sub n_param, n
+ mul v0
+ mov 8(rp,n,8), %r8
+ mov %rdx, %r9
+ jmp L(e2)
+
+ ALIGN(16)
+L(b13): xor R32(%r9), R32(%r9)
+ test $2, R8(n_param)
+ jnz L(b3)
+
+L(b1): mov $2, R32(n)
+ sub n_param, n
+ jns L(1)
+ mul v0
+ mov -16(rp,n,8), %r10
+ mov %rdx, %r11
+ jmp L(e1)
+
+ ALIGN(16)
+L(b3): xor R32(n), R32(n)
+ sub n_param, n
+ mul v0
+ mov (rp,n,8), %r10
+ jmp L(e3)
+
+ ALIGN(32)
+L(top): mul v0
+ mov -16(rp,n,8), %r10
+ ADDSUB %r11, %r8
+ mov %rdx, %r11
+ adc $0, %r9
+ mov %r8, -24(rp,n,8)
+L(e1): ADDSUB %rax, %r10
+ mov -8(up,n,8), %rax
+ adc $0, %r11
+ mul v0
+ ADDSUB %r9, %r10
+ mov %rdx, %r9
+ mov -8(rp,n,8), %r8
+ adc $0, %r11
+ mov %r10, -16(rp,n,8)
+L(e0): ADDSUB %rax, %r8
+ adc $0, %r9
+ mov (up,n,8), %rax
+ mul v0
+ mov (rp,n,8), %r10
+ ADDSUB %r11, %r8
+ mov %r8, -8(rp,n,8)
+ adc $0, %r9
+L(e3): mov %rdx, %r11
+ ADDSUB %rax, %r10
+ mov 8(up,n,8), %rax
+ adc $0, %r11
+ mul v0
+ mov 8(rp,n,8), %r8
+ ADDSUB %r9, %r10
+ mov %rdx, %r9
+ mov %r10, (rp,n,8)
+ adc $0, %r11
+L(e2): ADDSUB %rax, %r8
+ adc $0, %r9
+ mov 16(up,n,8), %rax
+ add $4, n
+ jnc L(top)
+
+L(end): mul v0
+ mov I(-8(rp),-16(rp,n,8)), %r10
+ ADDSUB %r11, %r8
+ mov %rdx, %r11
+ adc $0, %r9
+ mov %r8, I(-16(rp),-24(rp,n,8))
+ ADDSUB %rax, %r10
+ adc $0, %r11
+ ADDSUB %r9, %r10
+ adc $0, %r11
+ mov %r10, I(-8(rp),-16(rp,n,8))
+ mov %r11, %rax
+
+ pop %rbx
+IFDOS(``pop %rdi '')
+IFDOS(``pop %rsi '')
+ ret
+
+ ALIGN(16)
+L(1): mul v0
+ ADDSUB %rax, -8(rp)
+ mov %rdx, %rax
+ adc $0, %rax
+ pop %rbx
+IFDOS(``pop %rdi '')
+IFDOS(``pop %rsi '')
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/coreisbr/divrem_1.asm b/gmp/mpn/x86_64/coreisbr/divrem_1.asm
new file mode 100644
index 0000000000..d9f371f785
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/divrem_1.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_divrem_1
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_divrem_1 mpn_preinv_divrem_1)
+include_mpn(`x86_64/divrem_1.asm')
diff --git a/gmp/mpn/x86_64/coreisbr/gmp-mparam.h b/gmp/mpn/x86_64/coreisbr/gmp-mparam.h
new file mode 100644
index 0000000000..3a91b4c30e
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/gmp-mparam.h
@@ -0,0 +1,224 @@
+/* Sandy Bridge gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* 3300 MHz Core i5 Sandy Bridge */
+/* FFT tuning limit = 100000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 9
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 20
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 10
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 30
+
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 65
+#define MUL_TOOM44_THRESHOLD 166
+#define MUL_TOOM6H_THRESHOLD 254
+#define MUL_TOOM8H_THRESHOLD 333
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 105
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 122
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 105
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 113
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 148
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 28
+#define SQR_TOOM3_THRESHOLD 93
+#define SQR_TOOM4_THRESHOLD 250
+#define SQR_TOOM6_THRESHOLD 348
+#define SQR_TOOM8_THRESHOLD 454
+
+#define MULMID_TOOM42_THRESHOLD 36
+
+#define MULMOD_BNM1_THRESHOLD 12
+#define SQRMOD_BNM1_THRESHOLD 15
+
+#define MUL_FFT_MODF_THRESHOLD 380 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 380, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
+ { 23, 7}, { 21, 8}, { 11, 7}, { 25, 8}, \
+ { 13, 7}, { 27, 8}, { 15, 7}, { 31, 8}, \
+ { 21, 9}, { 11, 8}, { 27, 9}, { 15, 8}, \
+ { 33, 9}, { 19, 8}, { 39, 9}, { 23, 8}, \
+ { 47, 9}, { 27,10}, { 15, 9}, { 39,10}, \
+ { 23, 9}, { 51,11}, { 15,10}, { 31, 9}, \
+ { 67,10}, { 39, 9}, { 83,10}, { 47, 9}, \
+ { 95,10}, { 55,11}, { 31,10}, { 79,11}, \
+ { 47,10}, { 95,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 135,11}, { 79,10}, \
+ { 159, 9}, { 319,10}, { 167,11}, { 95,10}, \
+ { 191, 9}, { 383, 8}, { 767, 7}, { 1599, 8}, \
+ { 831, 9}, { 447,10}, { 239,12}, { 63,11}, \
+ { 127,10}, { 255,11}, { 143,10}, { 287, 9}, \
+ { 575,12}, { 95,11}, { 191,10}, { 383,11}, \
+ { 207,10}, { 447,13}, { 63,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 271,10}, { 543, 8}, \
+ { 2175,11}, { 303,12}, { 159,11}, { 319,10}, \
+ { 671,11}, { 367,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 415,10}, { 831,12}, { 223,11}, \
+ { 447,10}, { 895,11}, { 479,13}, { 127,12}, \
+ { 255,11}, { 511,10}, { 1023,11}, { 543,12}, \
+ { 287,11}, { 575,10}, { 1151,11}, { 607,12}, \
+ { 319,11}, { 671,12}, { 351,11}, { 703,10}, \
+ { 1407,13}, { 191,12}, { 383,11}, { 767,12}, \
+ { 415,11}, { 831,12}, { 479,14}, { 127,13}, \
+ { 255,12}, { 511,11}, { 1023,12}, { 575,11}, \
+ { 1151,12}, { 607,13}, { 319,12}, { 671,11}, \
+ { 1343,12}, { 703,13}, { 383,12}, { 767,11}, \
+ { 1535,12}, { 831,13}, { 447,12}, { 959,11}, \
+ { 1919,14}, { 255,13}, { 511,12}, { 1087,13}, \
+ { 575,12}, { 1215,13}, { 639,12}, { 1279,13}, \
+ { 703,12}, { 1407,14}, { 383,13}, { 767,12}, \
+ { 1535,13}, { 831,12}, { 1663,13}, { 959,14}, \
+ { 511,13}, { 1087,12}, { 2175,13}, { 1215,12}, \
+ { 2431,14}, { 639,13}, { 1343,12}, { 2687,13}, \
+ { 1407,12}, { 2815,13}, { 1471,12}, { 2943,14}, \
+ { 767,13}, { 1663,14}, { 895,13}, { 1919,15}, \
+ { 511,14}, { 1023,13}, { 2175,14}, { 1151,13}, \
+ { 2431,12}, { 4863,14}, { 1279,13}, { 2687,14}, \
+ { 1407,13}, { 2943,15}, { 767,14}, { 1535,13}, \
+ { 3071,14}, { 1663,13}, { 3455,14}, { 1919,16}, \
+ { 511,15}, { 1023,14}, { 2431,13}, { 4863,15}, \
+ { 1279,14}, { 2943,13}, { 5887,15}, { 1535,14}, \
+ { 3455,15}, { 1791,14}, { 3839,13}, { 7679,16}, \
+ { 1023,15}, { 2047,14}, { 4223,15}, { 2303,14}, \
+ { 4863,15}, { 2815,14}, { 5887,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 203
+#define MUL_FFT_THRESHOLD 4736
+
+#define SQR_FFT_MODF_THRESHOLD 336 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 336, 5}, { 11, 4}, { 23, 5}, { 19, 6}, \
+ { 10, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 25, 8}, \
+ { 13, 7}, { 27, 8}, { 15, 7}, { 31, 8}, \
+ { 21, 9}, { 11, 8}, { 27, 9}, { 15, 8}, \
+ { 33, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 47, 9}, { 27,10}, { 15, 9}, { 39,10}, \
+ { 23, 9}, { 51,11}, { 15,10}, { 31, 9}, \
+ { 63,10}, { 39, 9}, { 79,10}, { 55,11}, \
+ { 31,10}, { 79,11}, { 47,10}, { 95,12}, \
+ { 31,11}, { 63,10}, { 127, 9}, { 255, 8}, \
+ { 511,10}, { 135,11}, { 79, 9}, { 319, 8}, \
+ { 639,11}, { 95,10}, { 191, 9}, { 383,12}, \
+ { 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
+ { 271, 9}, { 543,11}, { 143,10}, { 287, 8}, \
+ { 1151,10}, { 303, 6}, { 4863, 8}, { 1279, 9}, \
+ { 671,11}, { 175,10}, { 367,12}, { 95,11}, \
+ { 191,10}, { 383,11}, { 207, 9}, { 831,10}, \
+ { 447,13}, { 63,12}, { 127,11}, { 255,10}, \
+ { 511,11}, { 271, 9}, { 1087,10}, { 575,11}, \
+ { 303,10}, { 607,11}, { 319,10}, { 671,11}, \
+ { 367,12}, { 191,11}, { 383,10}, { 767,11}, \
+ { 415,12}, { 223,11}, { 447,10}, { 959,12}, \
+ { 255,11}, { 511,10}, { 1023,11}, { 575,10}, \
+ { 1151,11}, { 607,10}, { 1215,12}, { 319,11}, \
+ { 671, 9}, { 2687,12}, { 351,11}, { 703,13}, \
+ { 191,12}, { 415,11}, { 831,12}, { 479,14}, \
+ { 127,13}, { 255,12}, { 511,11}, { 1023,12}, \
+ { 607,13}, { 319,12}, { 671,11}, { 1343,12}, \
+ { 703,13}, { 383,12}, { 831,13}, { 447,12}, \
+ { 959,14}, { 255,13}, { 511,12}, { 1087,13}, \
+ { 575,12}, { 1215,13}, { 639,12}, { 1343,13}, \
+ { 703,14}, { 383,13}, { 767,12}, { 1535,13}, \
+ { 831,12}, { 1663,13}, { 959,14}, { 511,13}, \
+ { 1087,12}, { 2175,13}, { 1215,14}, { 639,13}, \
+ { 1343,12}, { 2687,13}, { 1407,12}, { 2815,14}, \
+ { 767,13}, { 1663,14}, { 895,13}, { 1791,15}, \
+ { 511,14}, { 1023,13}, { 2175,14}, { 1151,13}, \
+ { 2431,12}, { 4863,14}, { 1279,13}, { 2687,14}, \
+ { 1407,13}, { 2815,15}, { 767,14}, { 1535,13}, \
+ { 3071,14}, { 1663,13}, { 3455,14}, { 1791,16}, \
+ { 511,15}, { 1023,14}, { 2431,13}, { 4863,15}, \
+ { 1279,14}, { 2943,13}, { 5887,15}, { 1535,14}, \
+ { 3455,15}, { 1791,14}, { 3839,16}, { 1023,15}, \
+ { 2047,14}, { 4223,15}, { 2303,14}, { 4863,15}, \
+ { 2815,14}, { 5887,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 190
+#define SQR_FFT_THRESHOLD 3264
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 62
+#define MULLO_MUL_N_THRESHOLD 8907
+
+#define DC_DIV_QR_THRESHOLD 52
+#define DC_DIVAPPR_Q_THRESHOLD 166
+#define DC_BDIV_QR_THRESHOLD 46
+#define DC_BDIV_Q_THRESHOLD 104
+
+#define INV_MULMOD_BNM1_THRESHOLD 42
+#define INV_NEWTON_THRESHOLD 166
+#define INV_APPR_THRESHOLD 165
+
+#define BINV_NEWTON_THRESHOLD 228
+#define REDC_1_TO_REDC_2_THRESHOLD 32
+#define REDC_2_TO_REDC_N_THRESHOLD 52
+
+#define MU_DIV_QR_THRESHOLD 1334
+#define MU_DIVAPPR_Q_THRESHOLD 1387
+#define MUPI_DIV_QR_THRESHOLD 69
+#define MU_BDIV_QR_THRESHOLD 1187
+#define MU_BDIV_Q_THRESHOLD 1334
+
+#define POWM_SEC_TABLE 3,22,194,452,1167
+
+#define MATRIX22_STRASSEN_THRESHOLD 14
+#define HGCD_THRESHOLD 119
+#define HGCD_APPR_THRESHOLD 51
+#define HGCD_REDUCE_THRESHOLD 2479
+#define GCD_DC_THRESHOLD 478
+#define GCDEXT_DC_THRESHOLD 368
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 14
+#define GET_STR_PRECOMPUTE_THRESHOLD 22
+#define SET_STR_DC_THRESHOLD 802
+#define SET_STR_PRECOMPUTE_THRESHOLD 2042
+
+#define FAC_DSC_THRESHOLD 644
+#define FAC_ODD_THRESHOLD 24
diff --git a/gmp/mpn/x86_64/coreisbr/lshift.asm b/gmp/mpn/x86_64/coreisbr/lshift.asm
new file mode 100644
index 0000000000..a1cbc31f61
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/lshift.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_lshift optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_lshift)
+include_mpn(`x86_64/fastsse/lshift-movdqu2.asm')
diff --git a/gmp/mpn/x86_64/coreisbr/lshiftc.asm b/gmp/mpn/x86_64/coreisbr/lshiftc.asm
new file mode 100644
index 0000000000..ac90edb76b
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/lshiftc.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_lshiftc optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_lshiftc)
+include_mpn(`x86_64/fastsse/lshiftc-movdqu2.asm')
diff --git a/gmp/mpn/x86_64/coreisbr/mul_1.asm b/gmp/mpn/x86_64/coreisbr/mul_1.asm
new file mode 100644
index 0000000000..ded7d899c2
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/mul_1.asm
@@ -0,0 +1,161 @@
+dnl X86-64 mpn_mul_1 optimised for Intel Sandy Bridge.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9
+C AMD K10
+C AMD bd1
+C AMD bobcat
+C Intel P4
+C Intel core2
+C Intel NHM
+C Intel SBR 2.5
+C Intel IBR 2.4
+C Intel atom
+C VIA nano
+
+C The loop of this code is the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * The loop is great, but the prologue code was quickly written. Tune it!
+C * Add mul_1c entry point.
+C * We could preserve one less register under DOS64 calling conventions, using
+C r10 instead of rsi.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0', `%rcx') C r9
+
+define(`n', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+IFDOS(` define(`up', ``%rsi'')') dnl
+IFDOS(` define(`rp', ``%rcx'')') dnl
+IFDOS(` define(`v0', ``%r9'')') dnl
+IFDOS(` define(`r9', ``rdi'')') dnl
+IFDOS(` define(`n_param',``%r8'')') dnl
+IFDOS(` define(`n', ``%r8'')') dnl
+IFDOS(` define(`r8', ``r11'')') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_1)
+
+IFDOS(``push %rsi '')
+IFDOS(``push %rdi '')
+IFDOS(``mov %rdx, %rsi '')
+
+ mov (up), %rax
+ mov R32(`n_param'), R32(%r10)
+IFSTD(` mov n_param, n ')
+
+ lea (up,n_param,8), up
+ lea -8(rp,n_param,8), rp
+ neg n
+ mul v0
+ and $3, R32(%r10)
+ jz L(b0)
+ cmp $2, R32(%r10)
+ jb L(b1)
+ jz L(b2)
+
+L(b3): add $-1, n
+ mov %rax, %r9
+ mov %rdx, %r8
+ mov 16(up,n,8), %rax
+ jmp L(L3)
+
+L(b1): mov %rax, %r9
+ mov %rdx, %r8
+ add $1, n
+ jnc L(L1)
+ mov %rax, (rp)
+ mov %rdx, %rax
+IFDOS(``pop %rdi '')
+IFDOS(``pop %rsi '')
+ ret
+
+L(b2): add $-2, n
+ mov %rax, %r8
+ mov %rdx, %r9
+ mov 24(up,n,8), %rax
+ jmp L(L2)
+
+L(b0): mov %rax, %r8
+ mov %rdx, %r9
+ mov 8(up,n,8), %rax
+ jmp L(L0)
+
+ ALIGN(8)
+L(top): mov %rdx, %r8
+ add %rax, %r9
+L(L1): mov 0(up,n,8), %rax
+ adc $0, %r8
+ mul v0
+ add %rax, %r8
+ mov %r9, 0(rp,n,8)
+ mov 8(up,n,8), %rax
+ mov %rdx, %r9
+ adc $0, %r9
+L(L0): mul v0
+ mov %r8, 8(rp,n,8)
+ add %rax, %r9
+ mov %rdx, %r8
+ mov 16(up,n,8), %rax
+ adc $0, %r8
+L(L3): mul v0
+ mov %r9, 16(rp,n,8)
+ mov %rdx, %r9
+ add %rax, %r8
+ mov 24(up,n,8), %rax
+ adc $0, %r9
+L(L2): mul v0
+ mov %r8, 24(rp,n,8)
+ add $4, n
+ jnc L(top)
+
+L(end): add %rax, %r9
+ mov %rdx, %rax
+ adc $0, %rax
+ mov %r9, (rp)
+
+IFDOS(``pop %rdi '')
+IFDOS(``pop %rsi '')
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/mul_2.asm b/gmp/mpn/x86_64/coreisbr/mul_2.asm
new file mode 100644
index 0000000000..ffee78a385
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/mul_2.asm
@@ -0,0 +1,163 @@
+dnl AMD64 mpn_mul_2 optimised for Intel Sandy Bridge.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb best
+C AMD K8,K9
+C AMD K10
+C AMD bull
+C AMD pile
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core
+C Intel NHM
+C Intel SBR 2.57 2.52 using 4-way code
+C Intel IBR 2.35 2.32 using 4-way code
+C Intel HWL 2.02 1.86
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C This code is the result of running a code generation and optimisation tool
+C suite written by David Harvey and Torbjorn Granlund.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`vp', `%rcx') C r9
+
+define(`n', `%rcx')
+define(`v0', `%rbx')
+define(`v1', `%rbp')
+
+define(`w0', `%r8')
+define(`w1', `%r9')
+define(`w2', `%r10')
+define(`w3', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mul_2)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ mov (up), %rax
+ lea (up,n_param,8), up
+ lea (rp,n_param,8), rp
+
+ test $1, R8(n_param)
+ jnz L(b1)
+
+L(b0): mov $0, R32(n)
+ sub n_param, n
+ xor w0, w0
+ mul v0
+ mov %rax, w2
+ mov %rdx, w1
+ mov (up,n,8), %rax
+ jmp L(lo0)
+
+L(b1): mov $1, R32(n)
+ sub n_param, n
+ xor w2, w2
+ mul v0
+ mov %rax, w0
+ mov %rdx, w3
+ mov -8(up,n,8), %rax
+ mul v1
+ jmp L(lo1)
+
+ ALIGN(32)
+L(top): mul v0
+ add %rax, w0 C 1
+ mov %rdx, w3 C 2
+ adc $0, w3 C 2
+ mov -8(up,n,8), %rax
+ mul v1
+ add w1, w0 C 1
+ adc $0, w3 C 2
+L(lo1): add %rax, w2 C 2
+ mov w0, -8(rp,n,8) C 1
+ mov %rdx, w0 C 3
+ adc $0, w0 C 3
+ mov (up,n,8), %rax
+ mul v0
+ add %rax, w2 C 2
+ mov %rdx, w1 C 3
+ adc $0, w1 C 3
+ add w3, w2 C 2
+ mov (up,n,8), %rax
+ adc $0, w1 C 1
+L(lo0): mul v1
+ mov w2, (rp,n,8) C 2
+ add %rax, w0 C 3
+ mov %rdx, w2 C 4
+ mov 8(up,n,8), %rax
+ adc $0, w2 C 4
+ add $2, n
+ jnc L(top)
+
+L(end): mul v0
+ add %rax, w0
+ mov %rdx, w3
+ adc $0, w3
+ mov I(-8(up),-8(up,n,8)), %rax
+ mul v1
+ add w1, w0
+ adc $0, w3
+ add %rax, w2
+ mov w0, I(-8(rp),-8(rp,n,8))
+ adc $0, %rdx
+ add w3, w2
+ mov w2, I((rp),(rp,n,8))
+ adc $0, %rdx
+ mov %rdx, %rax
+
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/mul_basecase.asm b/gmp/mpn/x86_64/coreisbr/mul_basecase.asm
new file mode 100644
index 0000000000..f026136ea0
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/mul_basecase.asm
@@ -0,0 +1,407 @@
+dnl AMD64 mpn_mul_basecase optimised for Intel Sandy bridge and Ivy bridge.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_1 mul_2 mul_3 addmul_2
+C AMD K8,K9
+C AMD K10
+C AMD bull
+C AMD pile
+C AMD steam
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core
+C Intel NHM
+C Intel SBR 2.5 2.5 - 2.95
+C Intel IBR 2.4 2.3 - 2.68
+C Intel HWL 2.35 2.0 - 2.5
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * Fix the addmul_2 fluctuation affecting SBR.
+C * Improve feed-in code, avoiding zeroing of many registers and dummy adds in
+C the loops at the expense of code size.
+C * Adjoin a mul_3, avoiding slow mul_1 for odd vn.
+C * Consider replacing the 2-way mul_2 code with 4-way code, for a very slight
+C speedup.
+C * Further micro-optimise.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param',`%rdx')
+define(`vp', `%rcx')
+define(`vn', `%r8')
+
+define(`un', `%rbx')
+
+define(`w0', `%r10')
+define(`w1', `%r11')
+define(`w2', `%r12')
+define(`w3', `%r13')
+define(`n', `%rbp')
+define(`v0', `%r9')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_basecase)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+ push %rbx
+ push %rbp
+ mov un_param, un C free up rdx
+ neg un
+
+ mov (up), %rax C shared for mul_1 and mul_2
+ lea (up,un_param,8), up C point at operand end
+ lea (rp,un_param,8), rp C point at rp[un-1]
+
+ mov (vp), v0 C shared for mul_1 and mul_2
+ mul v0 C shared for mul_1 and mul_2
+
+ test $1, R8(vn)
+ jz L(do_mul_2)
+
+L(do_mul_1):
+ test $1, R8(un)
+ jnz L(m1x1)
+
+L(m1x0):mov %rax, w0 C un = 2, 4, 6, 8, ...
+ mov %rdx, w1
+ mov 8(up,un,8), %rax
+ test $2, R8(un)
+ jnz L(m110)
+
+L(m100):lea 2(un), n C un = 4, 8, 12, ...
+ jmp L(m1l0)
+
+L(m110):lea (un), n C un = 2, 6, 10, ...
+ jmp L(m1l2)
+
+L(m1x1):mov %rax, w1 C un = 1, 3, 5, 7, ...
+ mov %rdx, w0
+ test $2, R8(un)
+ jz L(m111)
+
+L(m101):lea 3(un), n C un = 1, 5, 9, ...
+ test n, n
+ js L(m1l1)
+ mov %rax, -8(rp)
+ mov %rdx, (rp)
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(m111):lea 1(un), n C un = 3, 7, 11, ...
+ mov 8(up,un,8), %rax
+ jmp L(m1l3)
+
+ ALIGN(16) C FIXME
+L(m1tp):mov %rdx, w0
+ add %rax, w1
+L(m1l1):mov -16(up,n,8), %rax
+ adc $0, w0
+ mul v0
+ add %rax, w0
+ mov w1, -24(rp,n,8)
+ mov -8(up,n,8), %rax
+ mov %rdx, w1
+ adc $0, w1
+L(m1l0):mul v0
+ mov w0, -16(rp,n,8)
+ add %rax, w1
+ mov %rdx, w0
+ mov (up,n,8), %rax
+ adc $0, w0
+L(m1l3):mul v0
+ mov w1, -8(rp,n,8)
+ mov %rdx, w1
+ add %rax, w0
+ mov 8(up,n,8), %rax
+ adc $0, w1
+L(m1l2):mul v0
+ mov w0, (rp,n,8)
+ add $4, n
+ jnc L(m1tp)
+
+L(m1ed):add %rax, w1
+ adc $0, %rdx
+ mov w1, I(-8(rp),-24(rp,n,8))
+ mov %rdx, I((rp),-16(rp,n,8))
+
+ dec R32(vn)
+ jz L(ret2)
+
+ lea 8(vp), vp
+ lea 8(rp), rp
+ push %r12
+ push %r13
+ push %r14
+ jmp L(do_addmul)
+
+L(do_mul_2):
+define(`v1', `%r14')
+ push %r12
+ push %r13
+ push %r14
+
+ mov 8(vp), v1
+
+ test $1, R8(un)
+ jnz L(m2b1)
+
+L(m2b0):lea (un), n
+ xor w0, w0
+ mov %rax, w2
+ mov %rdx, w1
+ jmp L(m2l0)
+
+L(m2b1):lea 1(un), n
+ xor w1, w1
+ xor w2, w2
+ mov %rax, w0
+ mov %rdx, w3
+ jmp L(m2l1)
+
+ ALIGN(32)
+L(m2tp):mul v0
+ add %rax, w0
+ mov %rdx, w3
+ adc $0, w3
+L(m2l1):mov -8(up,n,8), %rax
+ mul v1
+ add w1, w0
+ adc $0, w3
+ add %rax, w2
+ mov w0, -8(rp,n,8)
+ mov %rdx, w0
+ adc $0, w0
+ mov (up,n,8), %rax
+ mul v0
+ add %rax, w2
+ mov %rdx, w1
+ adc $0, w1
+ add w3, w2
+L(m2l0):mov (up,n,8), %rax
+ adc $0, w1
+ mul v1
+ mov w2, (rp,n,8)
+ add %rax, w0
+ mov %rdx, w2
+ mov 8(up,n,8), %rax
+ adc $0, w2
+ add $2, n
+ jnc L(m2tp)
+
+L(m2ed):mul v0
+ add %rax, w0
+ mov %rdx, w3
+ adc $0, w3
+ mov I(-8(up),-8(up,n,8)), %rax
+ mul v1
+ add w1, w0
+ adc $0, w3
+ add %rax, w2
+ mov w0, I(-8(rp),-8(rp,n,8))
+ adc $0, %rdx
+ add w3, w2
+ mov w2, I((rp),(rp,n,8))
+ adc $0, %rdx
+ mov %rdx, I(8(rp),8(rp,n,8))
+
+ add $-2, R32(vn)
+ jz L(ret5)
+ lea 16(vp), vp
+ lea 16(rp), rp
+
+
+L(do_addmul):
+ push %r15
+ push vn C save vn in new stack slot
+define(`vn', `(%rsp)')
+define(`X0', `%r14')
+define(`X1', `%r15')
+define(`v1', `%r8')
+
+L(outer):
+ mov (vp), v0
+ mov 8(vp), v1
+ mov (up,un,8), %rax
+ mul v0
+ test $1, R8(un)
+ jnz L(a1x1)
+
+L(a1x0):mov (rp,un,8), X0
+ xor w0, w0
+ mov %rdx, w1
+ test $2, R8(un)
+ jnz L(a110)
+
+L(a100):lea 2(un), n C un = 4, 8, 12, ...
+ add %rax, X0
+ adc $0, w1
+ mov (up,un,8), %rax
+ mul v1
+ mov 8(rp,un,8), X1 C FIXME: Use un
+ jmp L(lo0)
+
+L(a110):lea (un), n C un = 2, 6, 10, ...
+ xor w3, w3
+ jmp L(lo2)
+
+L(a1x1):mov (rp,un,8), X1
+ xor w2, w2
+ xor w1, w1
+ test $2, R8(un)
+ jz L(a111)
+
+L(a101):lea 3(un), n C un = 1, 5, 9, ...
+ mov %rdx, w3
+ add %rax, X1
+ mov (up,un,8), %rax
+ mov 8(rp,un,8), X0
+ adc $0, w3
+ jmp L(top)
+
+L(a111):lea 1(un), n C un = 3, 7, 11, ...
+ jmp L(lo3)
+
+ ALIGN(32)
+L(top): mul v1
+ mov %rdx, w0
+ add %rax, X0
+ adc $0, w0
+ add w1, X1
+ adc $0, w3
+ add w2, X0
+ adc $0, w0
+ mov -16(up,n,8), %rax
+ mul v0
+ add %rax, X0
+ mov %rdx, w1
+ adc $0, w1
+ mov -16(up,n,8), %rax
+ mul v1
+ mov X1, -24(rp,n,8)
+ mov -8(rp,n,8), X1
+ add w3, X0
+ adc $0, w1
+L(lo0): mov %rdx, w2
+ mov X0, -16(rp,n,8)
+ add %rax, X1
+ adc $0, w2
+ mov -8(up,n,8), %rax
+ add w0, X1
+ adc $0, w2
+ mul v0
+L(lo3): add %rax, X1
+ mov %rdx, w3
+ adc $0, w3
+ mov -8(up,n,8), %rax
+ mul v1
+ add w1, X1
+ mov (rp,n,8), X0
+ adc $0, w3
+ mov %rdx, w0
+ add %rax, X0
+ adc $0, w0
+ mov (up,n,8), %rax
+ mul v0
+ add w2, X0
+ mov X1, -8(rp,n,8)
+ mov %rdx, w1
+ adc $0, w0
+L(lo2): add %rax, X0
+ adc $0, w1
+ mov (up,n,8), %rax
+ add w3, X0
+ adc $0, w1
+ mul v1
+ mov 8(rp,n,8), X1
+ add %rax, X1
+ mov %rdx, w2
+ adc $0, w2
+ mov 8(up,n,8), %rax
+ mov X0, (rp,n,8)
+ mul v0
+ add w0, X1
+ mov %rdx, w3
+ adc $0, w2
+ add %rax, X1
+ mov 8(up,n,8), %rax
+ mov 16(rp,n,8), X0 C useless but harmless in final iter
+ adc $0, w3
+ add $4, n
+ jnc L(top)
+
+L(end): mul v1
+ add w1, X1
+ adc $0, w3
+ add w2, %rax
+ adc $0, %rdx
+ mov X1, I(-8(rp),-24(rp,n,8))
+ add w3, %rax
+ adc $0, %rdx
+ mov %rax, I((rp),-16(rp,n,8))
+ mov %rdx, I(8(rp),-8(rp,n,8))
+
+ addl $-2, vn
+ lea 16(vp), vp
+ lea 16(rp), rp
+ jnz L(outer)
+
+ pop %rax C deallocate vn slot
+ pop %r15
+L(ret5):pop %r14
+ pop %r13
+ pop %r12
+L(ret2):pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/mullo_basecase.asm b/gmp/mpn/x86_64/coreisbr/mullo_basecase.asm
new file mode 100644
index 0000000000..a41a8acee4
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/mullo_basecase.asm
@@ -0,0 +1,384 @@
+dnl AMD64 mpn_mullo_basecase optimised for Intel Sandy bridge and Ivy bridge.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2008, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_2 addmul_2
+C AMD K8,K9
+C AMD K10
+C AMD bull
+C AMD pile
+C AMD steam
+C AMD bobcat
+C AMD jaguar
+C Intel P4
+C Intel core
+C Intel NHM
+C Intel SBR 2.5 2.95
+C Intel IBR 2.3 2.68
+C Intel HWL 2.0 2.5
+C Intel BWL
+C Intel atom
+C VIA nano
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Implement proper cor2, replacing current cor0.
+C * Offset n by 2 in order to avoid the outer loop cmp. (And sqr_basecase?)
+C * Micro-optimise.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp_param', `%rdx')
+define(`n', `%rcx')
+
+define(`vp', `%r8')
+define(`X0', `%r14')
+define(`X1', `%r15')
+
+define(`w0', `%r10')
+define(`w1', `%r11')
+define(`w2', `%r12')
+define(`w3', `%r13')
+define(`i', `%rbp')
+define(`v0', `%r9')
+define(`v1', `%rbx')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mullo_basecase)
+ FUNC_ENTRY(4)
+
+ mov (up), %rax
+ mov vp_param, vp
+
+ cmp $4, n
+ jb L(small)
+
+ mov (vp_param), v0
+ push %rbx
+ lea (rp,n,8), rp C point rp at R[un]
+ push %rbp
+ lea (up,n,8), up C point up right after U's end
+ push %r12
+ neg n
+ push %r13
+ mul v0
+ mov 8(vp), v1
+
+ test $1, R8(n)
+ jnz L(m2b1)
+
+L(m2b0):lea (n), i
+ xor w0, w0
+ mov %rax, w2
+ mov %rdx, w1
+ jmp L(m2l0)
+
+L(m2b1):lea 1(n), i
+ xor w1, w1
+ xor w2, w2
+ mov %rax, w0
+ mov %rdx, w3
+ jmp L(m2l1)
+
+ ALIGN(32)
+L(m2tp):mul v0
+ add %rax, w0
+ mov %rdx, w3
+ adc $0, w3
+L(m2l1):mov -8(up,i,8), %rax
+ mul v1
+ add w1, w0
+ adc $0, w3
+ add %rax, w2
+ mov w0, -8(rp,i,8)
+ mov %rdx, w0
+ adc $0, w0
+ mov (up,i,8), %rax
+ mul v0
+ add %rax, w2
+ mov %rdx, w1
+ adc $0, w1
+ add w3, w2
+L(m2l0):mov (up,i,8), %rax
+ adc $0, w1
+ mul v1
+ mov w2, (rp,i,8)
+ add %rax, w0
+ mov %rdx, w2 C FIXME: dead in last iteration
+ mov 8(up,i,8), %rax
+ adc $0, w2 C FIXME: dead in last iteration
+ add $2, i
+ jnc L(m2tp)
+
+L(m2ed):imul v0, %rax
+ add w0, %rax
+ add w1, %rax
+ mov %rax, I(-8(rp),-8(rp,i,8))
+
+ add $2, n
+ lea 16(vp), vp
+ lea -16(up), up
+ cmp $-2, n
+ jge L(cor1)
+
+ push %r14
+ push %r15
+
+L(outer):
+ mov (vp), v0
+ mov 8(vp), v1
+ mov (up,n,8), %rax
+ mul v0
+ test $1, R8(n)
+ jnz L(a1x1)
+
+L(a1x0):mov (rp,n,8), X1
+ xor w2, w2
+ xor w1, w1
+ test $2, R8(n)
+ jnz L(a110)
+
+L(a100):lea 1(n), i
+ jmp L(lo0)
+
+L(a110):lea 3(n), i
+ mov %rdx, w3
+ add %rax, X1
+ mov (up,n,8), %rax
+ mov 8(rp,n,8), X0
+ adc $0, w3
+ jmp L(lo2)
+
+L(a1x1):mov (rp,n,8), X0
+ xor w0, w0
+ mov %rdx, w1
+ test $2, R8(n)
+ jz L(a111)
+
+L(a101):lea 2(n), i
+ add %rax, X0
+ adc $0, w1
+ mov (up,n,8), %rax
+ mul v1
+ mov 8(rp,n,8), X1
+ jmp L(lo1)
+
+L(a111):lea (n), i
+ xor w3, w3
+ jmp L(lo3)
+
+ ALIGN(32)
+L(top):
+L(lo2): mul v1
+ mov %rdx, w0
+ add %rax, X0
+ adc $0, w0
+ add w1, X1
+ adc $0, w3
+ add w2, X0
+ adc $0, w0
+ mov -16(up,i,8), %rax
+ mul v0
+ add %rax, X0
+ mov %rdx, w1
+ adc $0, w1
+ mov -16(up,i,8), %rax
+ mul v1
+ mov X1, -24(rp,i,8)
+ mov -8(rp,i,8), X1
+ add w3, X0
+ adc $0, w1
+L(lo1): mov %rdx, w2
+ mov X0, -16(rp,i,8)
+ add %rax, X1
+ adc $0, w2
+ mov -8(up,i,8), %rax
+ add w0, X1
+ adc $0, w2
+ mul v0
+L(lo0): add %rax, X1
+ mov %rdx, w3
+ adc $0, w3
+ mov -8(up,i,8), %rax
+ mul v1
+ add w1, X1
+ mov (rp,i,8), X0
+ adc $0, w3
+ mov %rdx, w0
+ add %rax, X0
+ adc $0, w0
+ mov (up,i,8), %rax
+ mul v0
+ add w2, X0
+ mov X1, -8(rp,i,8)
+ mov %rdx, w1
+ adc $0, w0
+L(lo3): add %rax, X0
+ adc $0, w1
+ mov (up,i,8), %rax
+ add w3, X0
+ adc $0, w1
+ mul v1
+ mov 8(rp,i,8), X1
+ add %rax, X1
+ mov %rdx, w2
+ adc $0, w2
+ mov 8(up,i,8), %rax
+ mov X0, (rp,i,8)
+ mul v0
+ add w0, X1
+ mov %rdx, w3
+ adc $0, w2
+ add %rax, X1
+ mov 8(up,i,8), %rax
+ mov 16(rp,i,8), X0
+ adc $0, w3
+ add $4, i
+ jnc L(top)
+
+L(end): imul v1, %rax
+ add %rax, X0
+ add w1, X1
+ adc $0, w3
+ add w2, X0
+ mov I(-8(up),-16(up,i,8)), %rax
+ imul v0, %rax
+ add X0, %rax
+ mov X1, I(-16(rp),-24(rp,i,8))
+ add w3, %rax
+ mov %rax, I(-8(rp),-16(rp,i,8))
+
+ add $2, n
+ lea 16(vp), vp
+ lea -16(up), up
+ cmp $-2, n
+ jl L(outer)
+
+ pop %r15
+ pop %r14
+
+ jnz L(cor0)
+
+L(cor1):mov (vp), v0
+ mov 8(vp), v1
+ mov -16(up), %rax
+ mul v0 C u0 x v2
+ add -16(rp), %rax C FIXME: rp[0] still available in reg?
+ adc -8(rp), %rdx C FIXME: rp[1] still available in reg?
+ mov -8(up), %r10
+ imul v0, %r10
+ mov -16(up), %r11
+ imul v1, %r11
+ mov %rax, -16(rp)
+ add %r10, %r11
+ add %rdx, %r11
+ mov %r11, -8(rp)
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(cor0):mov (vp), %r11
+ imul -8(up), %r11
+ add %rax, %r11
+ mov %r11, -8(rp)
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(small):
+ cmp $2, n
+ jae L(gt1)
+L(n1): imul (vp_param), %rax
+ mov %rax, (rp)
+ FUNC_EXIT()
+ ret
+L(gt1): ja L(gt2)
+L(n2): mov (vp_param), %r9
+ mul %r9
+ mov %rax, (rp)
+ mov 8(up), %rax
+ imul %r9, %rax
+ add %rax, %rdx
+ mov 8(vp), %r9
+ mov (up), %rcx
+ imul %r9, %rcx
+ add %rcx, %rdx
+ mov %rdx, 8(rp)
+ FUNC_EXIT()
+ ret
+L(gt2):
+L(n3): mov (vp_param), %r9
+ mul %r9 C u0 x v0
+ mov %rax, (rp)
+ mov %rdx, %r10
+ mov 8(up), %rax
+ mul %r9 C u1 x v0
+ imul 16(up), %r9 C u2 x v0
+ add %rax, %r10
+ adc %rdx, %r9
+ mov 8(vp), %r11
+ mov (up), %rax
+ mul %r11 C u0 x v1
+ add %rax, %r10
+ adc %rdx, %r9
+ imul 8(up), %r11 C u1 x v1
+ add %r11, %r9
+ mov %r10, 8(rp)
+ mov 16(vp), %r10
+ mov (up), %rax
+ imul %rax, %r10 C u0 x v2
+ add %r10, %r9
+ mov %r9, 16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/popcount.asm b/gmp/mpn/x86_64/coreisbr/popcount.asm
new file mode 100644
index 0000000000..a5be33e6a7
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/popcount.asm
@@ -0,0 +1,118 @@
+dnl AMD64 mpn_popcount -- population count.
+
+dnl Copyright 2008, 2010-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 n/a
+C AMD K10 1.5 slower than 8-way non-pipelined code
+C AMD bd1 4.2
+C AMD bobcat 6.28 slower than 8-way non-pipelined code
+C Intel P4 n/a
+C Intel core2 n/a
+C Intel NHM 1.32
+C Intel SBR 1.05 fluctuating
+C Intel IBR 1.05 fluctuating
+C Intel HSW 1
+C Intel atom n/a
+C VIA nano n/a
+
+define(`up', `%rdi')
+define(`n_param', `%rsi')
+
+define(`n', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_popcount)
+ FUNC_ENTRY(2)
+
+ lea (up,n_param,8), up
+ xor R32(%rax), R32(%rax)
+
+ test $1, R8(n_param)
+ jnz L(bx1)
+
+L(bx0): test $2, R8(n_param)
+ jnz L(b10)
+
+L(b00): mov $0, R32(n)
+ sub n_param, n
+ .byte 0xf3,0x4c,0x0f,0xb8,0x04,0xcf C popcnt (up,n,8), %r8
+ .byte 0xf3,0x4c,0x0f,0xb8,0x4c,0xcf,0x08 C popcnt 8(up,n,8), %r9
+ jmp L(lo0)
+
+L(b10): mov $2, R32(n)
+ sub n_param, n
+ .byte 0xf3,0x4c,0x0f,0xb8,0x54,0xcf,0xf0 C popcnt -16(up,n,8), %r10
+ .byte 0xf3,0x4c,0x0f,0xb8,0x5c,0xcf,0xf8 C popcnt -8(up,n,8), %r11
+ test n, n
+ jz L(cj2)
+ jmp L(lo2)
+
+L(bx1): test $2, R8(n_param)
+ jnz L(b11)
+
+L(b01): mov $1, R32(n)
+ sub n_param, n
+ .byte 0xf3,0x4c,0x0f,0xb8,0x5c,0xcf,0xf8 C popcnt -8(up,n,8), %r11
+ test n, n
+ jz L(cj1)
+ .byte 0xf3,0x4c,0x0f,0xb8,0x04,0xcf C popcnt 0(up,n,8), %r8
+ jmp L(lo1)
+
+L(b11): mov $-1, n
+ sub n_param, n
+ .byte 0xf3,0x4c,0x0f,0xb8,0x4c,0xcf,0x08 C popcnt 8(up,n,8), %r9
+ .byte 0xf3,0x4c,0x0f,0xb8,0x54,0xcf,0x10 C popcnt 16(up,n,8), %r10
+ jmp L(lo3)
+
+ ALIGN(32)
+L(top): add %r9, %rax
+L(lo2): .byte 0xf3,0x4c,0x0f,0xb8,0x04,0xcf C popcnt 0(up,n,8), %r8
+ add %r10, %rax
+L(lo1): .byte 0xf3,0x4c,0x0f,0xb8,0x4c,0xcf,0x08 C popcnt 8(up,n,8), %r9
+ add %r11, %rax
+L(lo0): .byte 0xf3,0x4c,0x0f,0xb8,0x54,0xcf,0x10 C popcnt 16(up,n,8), %r10
+ add %r8, %rax
+L(lo3): .byte 0xf3,0x4c,0x0f,0xb8,0x5c,0xcf,0x18 C popcnt 24(up,n,8), %r11
+ add $4, n
+ js L(top)
+
+L(end): add %r9, %rax
+L(cj2): add %r10, %rax
+L(cj1): add %r11, %rax
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/redc_1.asm b/gmp/mpn/x86_64/coreisbr/redc_1.asm
new file mode 100644
index 0000000000..8a5170e3fd
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/redc_1.asm
@@ -0,0 +1,541 @@
+dnl X86-64 mpn_redc_1 optimised for Intel Sandy Bridge and Ivy Bridge.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003-2005, 2007, 2008, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C AMD bull ?
+C AMD pile ?
+C AMD steam ?
+C AMD bobcat ?
+C AMD jaguar ?
+C Intel P4 ?
+C Intel core ?
+C Intel NHM ?
+C Intel SBR 3.24
+C Intel IBR 3.04
+C Intel HWL ?
+C Intel BWL ?
+C Intel atom ?
+C VIA nano ?
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Micro-optimise, none performed thus far.
+C * Consider inlining mpn_add_n.
+C * Single basecases out before the pushes.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`mp_param', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`u0inv', `%r8') C stack
+
+define(`i', `%r14')
+define(`j', `%r15')
+define(`mp', `%r12')
+define(`q0', `%r13')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+define(`ALIGNx', `ALIGN(16)')
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_redc_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov (up), q0
+ mov n, j C outer loop induction var
+ lea 8(mp_param,n,8), mp
+ lea 8(up,n,8), up
+ neg n
+ imul u0inv, q0 C first iteration q0
+
+ test $1, R8(n)
+ jz L(bx0)
+
+L(bx1): test $2, R8(n)
+ jz L(b3)
+
+L(b1): cmp $-1, R32(n)
+ jz L(n1)
+
+L(otp1):lea 1(n), i
+ mov -8(mp,n,8), %rax
+ mul q0
+ mov -8(up,n,8), %r10
+ mov %rdx, %r11
+ add %rax, %r10
+ mov (mp,n,8), %rax
+ adc $0, %r11
+ mul q0
+ mov %rdx, %r9
+ mov (up,n,8), %rbx
+ add %rax, %rbx
+ adc $0, %r9
+ mov (mp,i,8), %rax
+ mul q0
+ mov (up,i,8), %r10
+ add %r11, %rbx
+ mov %rbx, -8(up,i,8) C next low remainder limb
+ adc $0, %r9
+ imul u0inv, %rbx C next q limb
+ jmp L(e1)
+
+ ALIGNx
+L(tp1): mul q0
+ mov -16(up,i,8), %r10
+ add %r11, %rbp
+ mov %rdx, %r11
+ adc $0, %r9
+ mov %rbp, -24(up,i,8)
+ add %rax, %r10
+ mov -8(mp,i,8), %rax
+ adc $0, %r11
+ mul q0
+ add %r9, %r10
+ mov %rdx, %r9
+ mov -8(up,i,8), %rbp
+ adc $0, %r11
+ mov %r10, -16(up,i,8)
+ add %rax, %rbp
+ adc $0, %r9
+ mov (mp,i,8), %rax
+ mul q0
+ mov (up,i,8), %r10
+ add %r11, %rbp
+ mov %rbp, -8(up,i,8)
+ adc $0, %r9
+L(e1): mov %rdx, %r11
+ add %rax, %r10
+ mov 8(mp,i,8), %rax
+ adc $0, %r11
+ mul q0
+ mov 8(up,i,8), %rbp
+ add %r9, %r10
+ mov %rdx, %r9
+ mov %r10, (up,i,8)
+ adc $0, %r11
+ add %rax, %rbp
+ adc $0, %r9
+ mov 16(mp,i,8), %rax
+ add $4, i
+ jnc L(tp1)
+
+L(ed1): mul q0
+ mov I(-16(up),-16(up,i,8)), %r10
+ add %r11, %rbp
+ adc $0, %r9
+ mov %rbp, I(-24(up),-24(up,i,8))
+ add %rax, %r10
+ adc $0, %rdx
+ add %r9, %r10
+ adc $0, %rdx
+ mov %r10, I(-16(up),-16(up,i,8))
+ mov %rdx, -8(up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp1)
+ jmp L(cj)
+
+L(b3): cmp $-3, R32(n)
+ jz L(n3)
+
+L(otp3):lea 3(n), i
+ mov -8(mp,n,8), %rax
+ mul q0
+ mov -8(up,n,8), %r10
+ mov %rdx, %r11
+ add %rax, %r10
+ mov (mp,n,8), %rax
+ adc $0, %r11
+ mul q0
+ mov (up,n,8), %rbx
+ mov %rdx, %r9
+ add %rax, %rbx
+ adc $0, %r9
+ mov 8(mp,n,8), %rax
+ mul q0
+ mov 8(up,n,8), %r10
+ add %r11, %rbx
+ mov %rdx, %r11
+ adc $0, %r9
+ mov %rbx, (up,n,8)
+ imul u0inv, %rbx C next q limb
+ jmp L(e3)
+
+ ALIGNx
+L(tp3): mul q0
+ mov -16(up,i,8), %r10
+ add %r11, %rbp
+ mov %rdx, %r11
+ adc $0, %r9
+ mov %rbp, -24(up,i,8)
+L(e3): add %rax, %r10
+ mov -8(mp,i,8), %rax
+ adc $0, %r11
+ mul q0
+ add %r9, %r10
+ mov %rdx, %r9
+ mov -8(up,i,8), %rbp
+ adc $0, %r11
+ mov %r10, -16(up,i,8)
+ add %rax, %rbp
+ adc $0, %r9
+ mov (mp,i,8), %rax
+ mul q0
+ mov (up,i,8), %r10
+ add %r11, %rbp
+ mov %rbp, -8(up,i,8)
+ adc $0, %r9
+ mov %rdx, %r11
+ add %rax, %r10
+ mov 8(mp,i,8), %rax
+ adc $0, %r11
+ mul q0
+ mov 8(up,i,8), %rbp
+ add %r9, %r10
+ mov %rdx, %r9
+ mov %r10, (up,i,8)
+ adc $0, %r11
+ add %rax, %rbp
+ adc $0, %r9
+ mov 16(mp,i,8), %rax
+ add $4, i
+ jnc L(tp3)
+
+L(ed3): mul q0
+ mov I(-16(up),-16(up,i,8)), %r10
+ add %r11, %rbp
+ adc $0, %r9
+ mov %rbp, I(-24(up),-24(up,i,8))
+ add %rax, %r10
+ adc $0, %rdx
+ add %r9, %r10
+ adc $0, %rdx
+ mov %r10, I(-16(up),-16(up,i,8))
+ mov %rdx, -8(up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp3)
+C jmp L(cj)
+
+L(cj):
+IFSTD(` lea -8(up,n,8), up C param 2: up
+ lea (up,n,8), %rdx C param 3: up - n
+ neg R32(n) ') C param 4: n
+
+IFDOS(` lea -8(up,n,8), %rdx C param 2: up
+ lea (%rdx,n,8), %r8 C param 3: up - n
+ neg R32(n)
+ mov n, %r9 C param 4: n
+ mov rp, %rcx ') C param 1: rp
+
+ CALL( mpn_add_n)
+
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(bx0): test $2, R8(n)
+ jnz L(b2)
+
+L(b0):
+L(otp0):lea (n), i
+ mov -8(mp,n,8), %rax
+ mul q0
+ mov %rdx, %r9
+ mov -8(up,n,8), %rbp
+ add %rax, %rbp
+ adc $0, %r9
+ mov (mp,n,8), %rax
+ mul q0
+ mov (up,n,8), %rbx
+ mov %rdx, %r11
+ add %rax, %rbx
+ mov 8(mp,n,8), %rax
+ adc $0, %r11
+ mul q0
+ mov 8(up,n,8), %rbp
+ add %r9, %rbx
+ mov %rdx, %r9
+ mov %rbx, (up,n,8)
+ adc $0, %r11
+ imul u0inv, %rbx C next q limb
+ jmp L(e0)
+
+ ALIGNx
+L(tp0): mul q0
+ mov -16(up,i,8), %r10
+ add %r11, %rbp
+ mov %rdx, %r11
+ adc $0, %r9
+ mov %rbp, -24(up,i,8)
+ add %rax, %r10
+ mov -8(mp,i,8), %rax
+ adc $0, %r11
+ mul q0
+ add %r9, %r10
+ mov %rdx, %r9
+ mov -8(up,i,8), %rbp
+ adc $0, %r11
+ mov %r10, -16(up,i,8)
+ add %rax, %rbp
+ adc $0, %r9
+ mov (mp,i,8), %rax
+ mul q0
+ mov (up,i,8), %r10
+ add %r11, %rbp
+ mov %rbp, -8(up,i,8)
+ adc $0, %r9
+ mov %rdx, %r11
+ add %rax, %r10
+ mov 8(mp,i,8), %rax
+ adc $0, %r11
+ mul q0
+ mov 8(up,i,8), %rbp
+ add %r9, %r10
+ mov %rdx, %r9
+ mov %r10, (up,i,8)
+ adc $0, %r11
+L(e0): add %rax, %rbp
+ adc $0, %r9
+ mov 16(mp,i,8), %rax
+ add $4, i
+ jnc L(tp0)
+
+L(ed0): mul q0
+ mov I(-16(up),-16(up,i,8)), %r10
+ add %r11, %rbp
+ adc $0, %r9
+ mov %rbp, I(-24(up),-24(up,i,8))
+ add %rax, %r10
+ adc $0, %rdx
+ add %r9, %r10
+ adc $0, %rdx
+ mov %r10, I(-16(up),-16(up,i,8))
+ mov %rdx, -8(up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp0)
+ jmp L(cj)
+
+L(b2): cmp $-2, R32(n)
+ jz L(n2)
+
+L(otp2):lea 2(n), i
+ mov -8(mp,n,8), %rax
+ mul q0
+ mov -8(up,n,8), %rbp
+ mov %rdx, %r9
+ add %rax, %rbp
+ adc $0, %r9
+ mov (mp,n,8), %rax
+ mul q0
+ mov (up,n,8), %rbx
+ mov %rdx, %r11
+ add %rax, %rbx
+ mov 8(mp,n,8), %rax
+ adc $0, %r11
+ mul q0
+ add %r9, %rbx
+ mov %rdx, %r9
+ mov 8(up,n,8), %rbp
+ adc $0, %r11
+ mov %rbx, (up,n,8)
+ imul u0inv, %rbx C next q limb
+ jmp L(e2)
+
+ ALIGNx
+L(tp2): mul q0
+ mov -16(up,i,8), %r10
+ add %r11, %rbp
+ mov %rdx, %r11
+ adc $0, %r9
+ mov %rbp, -24(up,i,8)
+ add %rax, %r10
+ mov -8(mp,i,8), %rax
+ adc $0, %r11
+ mul q0
+ add %r9, %r10
+ mov %rdx, %r9
+ mov -8(up,i,8), %rbp
+ adc $0, %r11
+ mov %r10, -16(up,i,8)
+L(e2): add %rax, %rbp
+ adc $0, %r9
+ mov (mp,i,8), %rax
+ mul q0
+ mov (up,i,8), %r10
+ add %r11, %rbp
+ mov %rbp, -8(up,i,8)
+ adc $0, %r9
+ mov %rdx, %r11
+ add %rax, %r10
+ mov 8(mp,i,8), %rax
+ adc $0, %r11
+ mul q0
+ mov 8(up,i,8), %rbp
+ add %r9, %r10
+ mov %rdx, %r9
+ mov %r10, (up,i,8)
+ adc $0, %r11
+ add %rax, %rbp
+ adc $0, %r9
+ mov 16(mp,i,8), %rax
+ add $4, i
+ jnc L(tp2)
+
+L(ed2): mul q0
+ mov I(-16(up),-16(up,i,8)), %r10
+ add %r11, %rbp
+ adc $0, %r9
+ mov %rbp, I(-24(up),-24(up,i,8))
+ add %rax, %r10
+ adc $0, %rdx
+ add %r9, %r10
+ adc $0, %rdx
+ mov %r10, I(-16(up),-16(up,i,8))
+ mov %rdx, -8(up,n,8) C up[0]
+ mov %rbx, q0 C previously computed q limb -> q0
+ lea 8(up), up C up++
+ dec j
+ jnz L(otp2)
+ jmp L(cj)
+
+L(n1): mov (mp_param), %rax
+ mul q0
+ add -16(up), %rax
+ adc -8(up), %rdx
+ mov %rdx, (rp)
+ mov $0, R32(%rax)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+L(n2): mov (mp_param), %rax
+ mov -24(up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -16(mp), %rax
+ mov -16(up), %r10
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, q0
+ imul u0inv, q0 C next q0
+ mov -24(mp), %rax
+ mul q0
+ add %rax, %r10
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -16(mp), %rax
+ mov -8(up), %r14
+ mul q0
+ add %rax, %r14
+ adc $0, %rdx
+ add %r9, %r14
+ adc $0, %rdx
+ xor R32(%rax), R32(%rax)
+ add %r11, %r14
+ adc (up), %rdx
+ mov %r14, (rp)
+ mov %rdx, 8(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+ ALIGNx
+L(n3): mov -32(mp), %rax
+ mov -32(up), %r10
+ mul q0
+ add %rax, %r10
+ mov -24(mp), %rax
+ mov %rdx, %r11
+ adc $0, %r11
+ mov -24(up), %rbp
+ mul q0
+ add %rax, %rbp
+ mov %rdx, %r9
+ adc $0, %r9
+ mov -16(mp), %rax
+ add %r11, %rbp
+ mov -16(up), %r10
+ adc $0, %r9
+ mul q0
+ mov %rbp, q0
+ imul u0inv, q0 C next q0
+ add %rax, %r10
+ mov %rdx, %r11
+ adc $0, %r11
+ mov %rbp, -24(up)
+ add %r9, %r10
+ adc $0, %r11
+ mov %r10, -16(up)
+ mov %r11, -32(up) C up[0]
+ lea 8(up), up C up++
+ dec j
+ jnz L(n3)
+ jmp L(cj)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/coreisbr/rsh1aors_n.asm b/gmp/mpn/x86_64/coreisbr/rsh1aors_n.asm
new file mode 100644
index 0000000000..fd2eaea7bb
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/rsh1aors_n.asm
@@ -0,0 +1,193 @@
+dnl X86-64 mpn_rsh1add_n, mpn_rsh1sub_n optimised for Intel Sandy Bridge.
+
+dnl Copyright 2003, 2005, 2009-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 4.25
+C Intel P4 21.5
+C Intel core2 3.2
+C Intel NHM 3.87
+C Intel SBR 2.05
+C Intel atom ?
+C VIA nano 44.9
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+
+ifdef(`OPERATION_rsh1add_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func_n, mpn_rsh1add_n)
+ define(func_nc, mpn_rsh1add_nc)')
+ifdef(`OPERATION_rsh1sub_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func_n, mpn_rsh1sub_n)
+ define(func_nc, mpn_rsh1sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_rsh1add_n mpn_rsh1add_nc mpn_rsh1sub_n mpn_rsh1sub_nc)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+
+ ALIGN(16)
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbx
+ push %rbp
+
+ neg %r8 C set C flag from parameter
+ mov (up), %rbp
+ ADCSBB (vp), %rbp
+
+ jmp L(ent)
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(func_n)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov (up), %rbp
+ ADDSUB (vp), %rbp
+L(ent):
+ sbb R32(%rbx), R32(%rbx) C save cy
+ mov R32(%rbp), R32(%rax)
+ and $1, R32(%rax) C return value
+
+ mov R32(n), R32(%r11)
+ and $3, R32(%r11)
+
+ cmp $1, R32(%r11)
+ je L(do) C jump if n = 1 5 9 ...
+
+L(n1): cmp $2, R32(%r11)
+ jne L(n2) C jump unless n = 2 6 10 ...
+ add R32(%rbx), R32(%rbx) C restore cy
+ mov 8(up), %r10
+ ADCSBB 8(vp), %r10
+ lea 8(up), up
+ lea 8(vp), vp
+ lea 8(rp), rp
+ sbb R32(%rbx), R32(%rbx) C save cy
+
+ shrd $1, %r10, %rbp
+ mov %rbp, -8(rp)
+ jmp L(cj1)
+
+L(n2): cmp $3, R32(%r11)
+ jne L(n3) C jump unless n = 3 7 11 ...
+ add R32(%rbx), R32(%rbx) C restore cy
+ mov 8(up), %r9
+ mov 16(up), %r10
+ ADCSBB 8(vp), %r9
+ ADCSBB 16(vp), %r10
+ lea 16(up), up
+ lea 16(vp), vp
+ lea 16(rp), rp
+ sbb R32(%rbx), R32(%rbx) C save cy
+
+ shrd $1, %r9, %rbp
+ mov %rbp, -16(rp)
+ jmp L(cj2)
+
+L(n3): dec n C come here for n = 4 8 12 ...
+ add R32(%rbx), R32(%rbx) C restore cy
+ mov 8(up), %r8
+ mov 16(up), %r9
+ ADCSBB 8(vp), %r8
+ ADCSBB 16(vp), %r9
+ mov 24(up), %r10
+ ADCSBB 24(vp), %r10
+ lea 24(up), up
+ lea 24(vp), vp
+ lea 24(rp), rp
+ sbb R32(%rbx), R32(%rbx) C save cy
+
+ shrd $1, %r8, %rbp
+ mov %rbp, -24(rp)
+ shrd $1, %r9, %r8
+ mov %r8, -16(rp)
+L(cj2): shrd $1, %r10, %r9
+ mov %r9, -8(rp)
+L(cj1): mov %r10, %rbp
+
+L(do):
+ shr $2, n C 4
+ je L(end) C 2
+ ALIGN(16)
+L(top): add R32(%rbx), R32(%rbx) C restore cy
+
+ mov 8(up), %r8
+ mov 16(up), %r9
+ ADCSBB 8(vp), %r8
+ ADCSBB 16(vp), %r9
+ mov 24(up), %r10
+ mov 32(up), %r11
+ ADCSBB 24(vp), %r10
+ ADCSBB 32(vp), %r11
+
+ lea 32(up), up
+ lea 32(vp), vp
+
+ sbb R32(%rbx), R32(%rbx) C save cy
+
+ shrd $1, %r8, %rbp
+ mov %rbp, (rp)
+ shrd $1, %r9, %r8
+ mov %r8, 8(rp)
+ shrd $1, %r10, %r9
+ mov %r9, 16(rp)
+ shrd $1, %r11, %r10
+ mov %r10, 24(rp)
+
+ dec n
+ mov %r11, %rbp
+ lea 32(rp), rp
+ jne L(top)
+
+L(end): shrd $1, %rbx, %rbp
+ mov %rbp, (rp)
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/coreisbr/rshift.asm b/gmp/mpn/x86_64/coreisbr/rshift.asm
new file mode 100644
index 0000000000..4c1c0d4cde
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/rshift.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_rshift optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_rshift)
+include_mpn(`x86_64/fastsse/rshift-movdqu2.asm')
diff --git a/gmp/mpn/x86_64/coreisbr/sec_tabselect.asm b/gmp/mpn/x86_64/coreisbr/sec_tabselect.asm
new file mode 100644
index 0000000000..e4360341d9
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/sec_tabselect.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_sec_tabselect.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_sec_tabselect)
+include_mpn(`x86_64/fastsse/sec_tabselect.asm')
diff --git a/gmp/mpn/x86_64/coreisbr/sqr_basecase.asm b/gmp/mpn/x86_64/coreisbr/sqr_basecase.asm
new file mode 100644
index 0000000000..46a36121fe
--- /dev/null
+++ b/gmp/mpn/x86_64/coreisbr/sqr_basecase.asm
@@ -0,0 +1,484 @@
+dnl AMD64 mpn_sqr_basecase optimised for Intel Sandy bridge and Ivy bridge.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2008, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb mul_2 addmul_2 sqr_diag_addlsh1
+C AMD K8,K9 ? ? ?
+C AMD K10 ? ? ?
+C AMD bull ? ? ?
+C AMD pile ? ? ?
+C AMD steam ? ? ?
+C AMD bobcat ? ? ?
+C AMD jaguar ? ? ?
+C Intel P4 ? ? ?
+C Intel core ? ? ?
+C Intel NHM ? ? ?
+C Intel SBR 2.57 2.93 3.0
+C Intel IBR 2.35 2.66 3.0
+C Intel HWL 2.02 2.5 2.5
+C Intel BWL ? ? ?
+C Intel atom ? ? ?
+C VIA nano ? ? ?
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund, except
+C that the sqr_diag_addlsh1 loop was manually written.
+
+C TODO
+C * Replace current unoptimised sqr_diag_addlsh1 loop, 2.5 c/l should be easy.
+C * Streamline pointer updates.
+C * Perhaps suppress a few more xor insns in feed-in code.
+C * Make sure we write no dead registers in feed-in code.
+C * We might use 32-bit size ops, since n >= 2^32 is non-terminating. Watch
+C out for negative sizes being zero-extended, though.
+C * The straight-line code for n <= 3 comes from the K8 code, and might be
+C quite sub-optimal here. Write specific code, and add code for n = 4.
+C * The mul_2 loop has a 10 insn common sequence in the loop start and the
+C wind-down code. Try re-rolling it.
+C * This file has been the subject to just basic micro-optimisation.
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param',`%rdx')
+
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_sqr_basecase)
+ FUNC_ENTRY(3)
+
+ cmp $2, un_param
+ jae L(gt1)
+
+ mov (up), %rax
+ mul %rax
+ mov %rax, (rp)
+ mov %rdx, 8(rp)
+ FUNC_EXIT()
+ ret
+
+L(gt1): jne L(gt2)
+
+ mov (up), %rax
+ mov %rax, %r8
+ mul %rax
+ mov 8(up), %r11
+ mov %rax, (rp)
+ mov %r11, %rax
+ mov %rdx, %r9
+ mul %rax
+ mov %rax, %r10
+ mov %r11, %rax
+ mov %rdx, %r11
+ mul %r8
+ xor %r8, %r8
+ add %rax, %r9
+ adc %rdx, %r10
+ adc %r8, %r11
+ add %rax, %r9
+ mov %r9, 8(rp)
+ adc %rdx, %r10
+ mov %r10, 16(rp)
+ adc %r8, %r11
+ mov %r11, 24(rp)
+ FUNC_EXIT()
+ ret
+
+L(gt2): cmp $4, un_param
+ jae L(gt3)
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%r10')
+define(`w2', `%r11')
+
+ mov (up), %rax
+ mov %rax, %r10
+ mul %rax
+ mov 8(up), %r11
+ mov %rax, (rp)
+ mov %r11, %rax
+ mov %rdx, 8(rp)
+ mul %rax
+ mov 16(up), %rcx
+ mov %rax, 16(rp)
+ mov %rcx, %rax
+ mov %rdx, 24(rp)
+ mul %rax
+ mov %rax, 32(rp)
+ mov %rdx, 40(rp)
+
+ mov %r11, %rax
+ mul %r10
+ mov %rax, %r8
+ mov %rcx, %rax
+ mov %rdx, %r9
+ mul %r10
+ xor %r10, %r10
+ add %rax, %r9
+ mov %r11, %rax
+ mov %r10, %r11
+ adc %rdx, %r10
+
+ mul %rcx
+ add %rax, %r10
+ adc %r11, %rdx
+ add %r8, %r8
+ adc %r9, %r9
+ adc %r10, %r10
+ adc %rdx, %rdx
+ adc %r11, %r11
+ add %r8, 8(rp)
+ adc %r9, 16(rp)
+ adc %r10, 24(rp)
+ adc %rdx, 32(rp)
+ adc %r11, 40(rp)
+ FUNC_EXIT()
+ ret
+
+L(gt3):
+
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%r10')
+define(`w1', `%r11')
+define(`w2', `%rbx')
+define(`w3', `%rbp')
+define(`un', `%r12')
+define(`n', `%rcx')
+
+define(`X0', `%r13')
+define(`X1', `%r14')
+
+L(do_mul_2):
+ mov (up), v0
+ push %rbx
+ lea (rp,un_param,8), rp C point rp at R[un]
+ mov 8(up), %rax
+ push %rbp
+ lea (up,un_param,8), up C point up right after U's end
+ mov %rax, v1
+ push %r12
+ mov $1, R32(un) C free up rdx
+ push %r13
+ sub un_param, un
+ push %r14
+ push un
+ mul v0
+ mov %rax, (rp,un,8)
+ mov 8(up,un,8), %rax
+ test $1, R8(un)
+ jnz L(m2b1)
+
+L(m2b0):lea 2(un), n
+ xor R32(w1), R32(w1) C FIXME
+ xor R32(w2), R32(w2) C FIXME
+ mov %rdx, w0
+ jmp L(m2l0)
+
+L(m2b1):lea 1(un), n
+ xor R32(w3), R32(w3) C FIXME
+ xor R32(w0), R32(w0) C FIXME
+ mov %rdx, w2
+ jmp L(m2l1)
+
+ ALIGN(32)
+L(m2tp):
+L(m2l0):mul v0
+ add %rax, w0
+ mov %rdx, w3
+ adc $0, w3
+ mov -8(up,n,8), %rax
+ mul v1
+ add w1, w0
+ adc $0, w3
+ add %rax, w2
+ mov w0, -8(rp,n,8)
+ mov %rdx, w0
+ adc $0, w0
+ mov (up,n,8), %rax
+L(m2l1):mul v0
+ add %rax, w2
+ mov %rdx, w1
+ adc $0, w1
+ add w3, w2
+ mov (up,n,8), %rax
+ adc $0, w1
+ mul v1
+ mov w2, (rp,n,8)
+ add %rax, w0
+ mov %rdx, w2
+ mov 8(up,n,8), %rax
+ adc $0, w2
+ add $2, n
+ jnc L(m2tp)
+
+L(m2ed):mul v0
+ add %rax, w0
+ mov %rdx, w3
+ adc $0, w3
+ mov I(-8(up),-8(up,n,8)), %rax
+ mul v1
+ add w1, w0
+ adc $0, w3
+ add %rax, w2
+ mov w0, I(-8(rp),-8(rp,n,8))
+ adc $0, %rdx
+ add w3, w2
+ mov w2, I((rp),(rp,n,8))
+ adc $0, %rdx
+ mov %rdx, I(8(rp),8(rp,n,8))
+
+ add $2, un C decrease |un|
+
+L(do_addmul_2):
+L(outer):
+ lea 16(rp), rp
+ cmp $-2, R32(un) C jump if un C {-1,0} FIXME jump if un C {-2,1}
+ jge L(corner) C FIXME: move to before the lea above
+
+ mov -8(up,un,8), v0
+ mov (up,un,8), %rax
+ mov %rax, v1
+ mul v0
+ test $1, R8(un)
+ jnz L(a1x1)
+
+L(a1x0):mov (rp,un,8), X0
+ xor w0, w0
+ mov 8(rp,un,8), X1
+ add %rax, X0
+ mov %rdx, w1
+ adc $0, w1
+ xor w2, w2
+ mov X0, (rp,un,8)
+ mov 8(up,un,8), %rax
+ test $2, R8(un)
+ jnz L(a110)
+
+L(a100):lea 2(un), n C un = 4, 8, 12, ...
+ jmp L(lo0)
+
+L(a110):lea (un), n C un = 2, 6, 10, ...
+ jmp L(lo2)
+
+L(a1x1):mov (rp,un,8), X1
+ xor w2, w2
+ mov 8(rp,un,8), X0
+ add %rax, X1
+ mov %rdx, w3
+ adc $0, w3
+ xor w0, w0
+ mov 8(up,un,8), %rax
+ test $2, R8(un)
+ jz L(a111)
+
+L(a101):lea 3(un), n C un = 1, 5, 9, ...
+ jmp L(lo1)
+
+L(a111):lea 1(un), n C un = 3, 7, 11, ...
+ jmp L(lo3)
+
+ ALIGN(32)
+L(top): mul v1
+ mov %rdx, w0
+ add %rax, X0
+ adc $0, w0
+ add w1, X1
+ adc $0, w3
+ add w2, X0
+ adc $0, w0
+ mov -16(up,n,8), %rax
+L(lo1): mul v0
+ add %rax, X0
+ mov %rdx, w1
+ adc $0, w1
+ mov -16(up,n,8), %rax
+ mul v1
+ mov X1, -24(rp,n,8)
+ mov -8(rp,n,8), X1
+ add w3, X0
+ adc $0, w1
+ mov %rdx, w2
+ mov X0, -16(rp,n,8)
+ add %rax, X1
+ adc $0, w2
+ mov -8(up,n,8), %rax
+ add w0, X1
+ adc $0, w2
+L(lo0): mul v0
+ add %rax, X1
+ mov %rdx, w3
+ adc $0, w3
+ mov -8(up,n,8), %rax
+ mul v1
+ add w1, X1
+ mov (rp,n,8), X0
+ adc $0, w3
+ mov %rdx, w0
+ add %rax, X0
+ adc $0, w0
+ mov (up,n,8), %rax
+L(lo3): mul v0
+ add w2, X0
+ mov X1, -8(rp,n,8)
+ mov %rdx, w1
+ adc $0, w0
+ add %rax, X0
+ adc $0, w1
+ mov (up,n,8), %rax
+ add w3, X0
+ adc $0, w1
+ mul v1
+ mov 8(rp,n,8), X1
+ add %rax, X1
+ mov %rdx, w2
+ adc $0, w2
+ mov 8(up,n,8), %rax
+ mov X0, (rp,n,8)
+L(lo2): mul v0
+ add w0, X1
+ mov %rdx, w3
+ adc $0, w2
+ add %rax, X1
+ mov 8(up,n,8), %rax
+ mov 16(rp,n,8), X0
+ adc $0, w3
+ add $4, n
+ jnc L(top)
+
+L(end): mul v1
+ add w1, X1
+ adc $0, w3
+ add w2, %rax
+ adc $0, %rdx
+ mov X1, I(-8(rp),-24(rp,n,8))
+ add w3, %rax
+ adc $0, %rdx
+ mov %rax, I((rp),-16(rp,n,8))
+ mov %rdx, I(8(rp),-8(rp,n,8))
+
+ add $2, un C decrease |un|
+ jmp L(outer) C loop until a small corner remains
+
+L(corner):
+ pop n
+ jg L(small_corner)
+
+ lea 8(rp), rp
+ mov -24(up), v0
+ mov -16(up), %rax
+ mov %rax, v1
+ mul v0
+ mov -24(rp), X0
+ mov -16(rp), X1
+ add %rax, X0
+ mov %rdx, w1
+ adc $0, w1
+ xor w2, w2
+ mov X0, -24(rp)
+ mov -8(up), %rax
+ mul v0
+ add $0, X1
+ mov %rdx, w3
+ adc $0, w2
+ add %rax, X1
+ mov -8(up), %rax
+ adc $0, w3
+ mul v1
+ add w1, X1
+ adc $0, w3
+ add w2, %rax
+ adc $0, %rdx
+ mov X1, -16(rp)
+ jmp L(com)
+
+L(small_corner):
+ mov -8(rp), w3
+ mov -16(up), v0
+ mov -8(up), %rax
+ mul v0
+L(com): add w3, %rax
+ adc $0, %rdx
+ mov %rax, -8(rp)
+ mov %rdx, (rp)
+
+L(sqr_diag_addlsh1):
+ mov -8(up,n,8), %rax
+ shl n
+ mul %rax
+ mov %rax, (rp,n,8)
+
+ xor R32(%rbx), R32(%rbx)
+ mov 8(rp,n,8), %r8
+ mov 16(rp,n,8), %r9
+ jmp L(dm)
+
+ ALIGN(32)
+L(dtop):add %r8, %r10
+ adc %r9, %rax
+ mov 8(rp,n,8), %r8
+ mov 16(rp,n,8), %r9
+ mov %r10, -8(rp,n,8)
+ mov %rax, (rp,n,8)
+L(dm): adc %r8, %r8
+ adc %r9, %r9
+ mov (up,n,4), %rax
+ lea (%rdx,%rbx), %r10
+ setc R8(%rbx)
+ mul %rax
+ add $2, n
+ js L(dtop)
+
+L(dend):add %r8, %r10
+ adc %r9, %rax
+ mov %r10, I(-8(rp),-8(rp,n,8))
+ mov %rax, I((rp),(rp,n,8))
+ adc %rbx, %rdx
+ mov %rdx, I(8(rp),8(rp,n,8))
+
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/darwin.m4 b/gmp/mpn/x86_64/darwin.m4
new file mode 100644
index 0000000000..6f8ec7893d
--- /dev/null
+++ b/gmp/mpn/x86_64/darwin.m4
@@ -0,0 +1,81 @@
+divert(-1)
+dnl Copyright 2008, 2011, 2012 Free Software Foundation, Inc.
+dnl
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`DARWIN')
+
+define(`LEA',`dnl
+ifdef(`PIC',
+ `lea $1(%rip), $2'
+,
+ `movabs `$'$1, $2')
+')
+
+dnl Usage: CALL(funcname)
+dnl
+dnl Simply override the definition in x86_64-defs.m4.
+
+define(`CALL',`call GSYM_PREFIX`'$1')
+
+
+dnl Usage: JUMPTABSECT
+dnl
+dnl CAUTION: Do not put anything sensible here, like RODATA. That works with
+dnl some Darwin tool chains, but silently breaks with other. (Note that
+dnl putting jump tables in the text segment is a really poor idea for PC many
+dnl processors, since they cannot cache the same thing in both L1D and L2I.)
+
+define(`JUMPTABSECT', `.text')
+
+
+dnl Usage: JMPENT(targlabel,tablabel)
+
+define(`JMPENT',`dnl
+ifdef(`PIC',
+ `.set $1_tmp, $1-$2
+ .long $1_tmp'
+,
+ `.quad $1'
+)')
+
+dnl Target ABI macros. For Darwin we override IFELF (and leave default for
+dnl IFDOS and IFSTD).
+
+define(`IFELF', `')
+
+
+dnl Usage: PROTECT(symbol)
+dnl
+dnl Used for private GMP symbols that should never be overridden by users.
+dnl This can save reloc entries and improve shlib sharing as well as
+dnl application startup times
+
+define(`PROTECT', `.private_extern $1')
+
+
+divert`'dnl
diff --git a/gmp/mpn/x86_64/div_qr_1n_pi1.asm b/gmp/mpn/x86_64/div_qr_1n_pi1.asm
new file mode 100644
index 0000000000..cb072e979d
--- /dev/null
+++ b/gmp/mpn/x86_64/div_qr_1n_pi1.asm
@@ -0,0 +1,247 @@
+dnl x86-64 mpn_div_qr_1n_pi1
+dnl -- Divide an mpn number by a normalized single-limb number,
+dnl using a single-limb inverse.
+
+dnl Contributed to the GNU project by Niels Möller
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C c/l
+C AMD K8,K9 13
+C AMD K10 13
+C AMD bull 16.5
+C AMD pile 15
+C AMD steam ?
+C AMD bobcat 16
+C AMD jaguar ?
+C Intel P4 47 poor
+C Intel core 19.25
+C Intel NHM 18
+C Intel SBR 15 poor
+C Intel IBR 13
+C Intel HWL 11.7
+C Intel BWL ?
+C Intel atom 52 very poor
+C VIA nano 19
+
+
+C INPUT Parameters
+define(`QP', `%rdi')
+define(`UP', `%rsi')
+define(`UN_INPUT', `%rdx')
+define(`U1', `%rcx') C Also in %rax
+define(`D', `%r8')
+define(`DINV', `%r9')
+
+C Invariants
+define(`B2', `%rbp')
+define(`B2md', `%rbx')
+
+C Variables
+define(`UN', `%r8') C Overlaps D input
+define(`T', `%r10')
+define(`U0', `%r11')
+define(`U2', `%r12')
+define(`Q0', `%r13')
+define(`Q1', `%r14')
+define(`Q2', `%r15')
+
+ABI_SUPPORT(STD64)
+
+ ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_div_qr_1n_pi1)
+ FUNC_ENTRY(6)
+IFDOS(` mov 56(%rsp), %r8 ')
+IFDOS(` mov 64(%rsp), %r9 ')
+ dec UN_INPUT
+ jnz L(first)
+
+ C Just a single 2/1 division.
+ C T, U0 are allocated in scratch registers
+ lea 1(U1), T
+ mov U1, %rax
+ mul DINV
+ mov (UP), U0
+ add U0, %rax
+ adc T, %rdx
+ mov %rdx, T
+ imul D, %rdx
+ sub %rdx, U0
+ cmp U0, %rax
+ lea (U0, D), %rax
+ cmovnc U0, %rax
+ sbb $0, T
+ cmp D, %rax
+ jc L(single_div_done)
+ sub D, %rax
+ add $1, T
+L(single_div_done):
+ mov T, (QP)
+ FUNC_EXIT
+ ret
+L(first):
+ C FIXME: Could delay some of these until we enter the loop.
+ push %r15
+ push %r14
+ push %r13
+ push %r12
+ push %rbx
+ push %rbp
+
+ mov D, B2
+ imul DINV, B2
+ neg B2
+ mov B2, B2md
+ sub D, B2md
+
+ C D not needed until final reduction
+ push D
+ mov UN_INPUT, UN C Clobbers D
+
+ mov DINV, %rax
+ mul U1
+ mov %rax, Q0
+ add U1, %rdx
+ mov %rdx, T
+
+ mov B2, %rax
+ mul U1
+ mov -8(UP, UN, 8), U0
+ mov (UP, UN, 8), U1
+ mov T, (QP, UN, 8)
+ add %rax, U0
+ adc %rdx, U1
+ sbb U2, U2
+ dec UN
+ mov U1, %rax
+ jz L(final)
+
+ ALIGN(16)
+
+ C Loop is 28 instructions, 30 decoder slots, should run in 10 cycles.
+ C At entry, %rax holds an extra copy of U1
+L(loop):
+ C {Q2, Q1, Q0} <-- DINV * U1 + B (Q0 + U2 DINV) + B^2 U2
+ C Remains to add in B (U1 + c)
+ mov DINV, Q1
+ mov U2, Q2
+ and U2, Q1
+ neg Q2
+ mul DINV
+ add %rdx, Q1
+ adc $0, Q2
+ add Q0, Q1
+ mov %rax, Q0
+ mov B2, %rax
+ lea (B2md, U0), T
+ adc $0, Q2
+
+ C {U2, U1, U0} <-- (U0 + U2 B2 -c U) B + U1 B2 + u
+ mul U1
+ and B2, U2
+ add U2, U0
+ cmovnc U0, T
+
+ C {QP+UN, ...} <-- {QP+UN, ...} + {Q2, Q1} + U1 + c
+ adc U1, Q1
+ mov -8(UP, UN, 8), U0
+ adc Q2, 8(QP, UN, 8)
+ jc L(q_incr)
+L(q_incr_done):
+ add %rax, U0
+ mov T, %rax
+ adc %rdx, %rax
+ mov Q1, (QP, UN, 8)
+ sbb U2, U2
+ dec UN
+ mov %rax, U1
+ jnz L(loop)
+
+L(final):
+ pop D
+
+ mov U2, Q1
+ and D, U2
+ sub U2, %rax
+ neg Q1
+
+ mov %rax, U1
+ sub D, %rax
+ cmovc U1, %rax
+ sbb $-1, Q1
+
+ lea 1(%rax), T
+ mul DINV
+ add U0, %rax
+ adc T, %rdx
+ mov %rdx, T
+ imul D, %rdx
+ sub %rdx, U0
+ cmp U0, %rax
+ lea (U0, D), %rax
+ cmovnc U0, %rax
+ sbb $0, T
+ cmp D, %rax
+ jc L(div_done)
+ sub D, %rax
+ add $1, T
+L(div_done):
+ add T, Q0
+ mov Q0, (QP)
+ adc Q1, 8(QP)
+ jnc L(done)
+L(final_q_incr):
+ addq $1, 16(QP)
+ lea 8(QP), QP
+ jc L(final_q_incr)
+
+L(done):
+ pop %rbp
+ pop %rbx
+ pop %r12
+ pop %r13
+ pop %r14
+ pop %r15
+ FUNC_EXIT
+ ret
+
+L(q_incr):
+ C U1 is not live, so use it for indexing
+ lea 16(QP, UN, 8), U1
+L(q_incr_loop):
+ addq $1, (U1)
+ jnc L(q_incr_done)
+ lea 8(U1), U1
+ jmp L(q_incr_loop)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/div_qr_2n_pi1.asm b/gmp/mpn/x86_64/div_qr_2n_pi1.asm
new file mode 100644
index 0000000000..5e59a0ac5d
--- /dev/null
+++ b/gmp/mpn/x86_64/div_qr_2n_pi1.asm
@@ -0,0 +1,158 @@
+dnl x86-64 mpn_div_qr_2n_pi1
+dnl -- Divide an mpn number by a normalized 2-limb number,
+dnl using a single-limb inverse.
+
+dnl Copyright 2007, 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C c/l
+C INPUT PARAMETERS
+define(`qp', `%rdi')
+define(`rp', `%rsi')
+define(`up_param', `%rdx')
+define(`un', `%rcx')
+define(`d1', `%r8')
+define(`d0', `%r9')
+define(`di_param', `8(%rsp)')
+
+define(`di', `%r10')
+define(`up', `%r11')
+define(`u2', `%rbx')
+define(`u1', `%r12')
+define(`t1', `%r13')
+define(`t0', `%r14')
+define(`md1', `%r15')
+
+C TODO
+C * Store qh in the same stack slot as di_param, instead of pushing
+C it. (we could put it in register %rbp, but then we would need to
+C save and restore that instead, which doesn't seem like a win).
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_div_qr_2n_pi1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+IFDOS(` mov 64(%rsp), %r9 ')
+IFDOS(`define(`di_param', `72(%rsp)')')
+ mov di_param, di
+ mov up_param, up
+ push %r15
+ push %r14
+ push %r13
+ push %r12
+ push %rbx
+
+ mov -16(up, un, 8), u1
+ mov -8(up, un, 8), u2
+
+ mov u1, t0
+ mov u2, t1
+ sub d0, t0
+ sbb d1, t1
+ cmovnc t0, u1
+ cmovnc t1, u2
+ C push qh which is !carry
+ sbb %rax, %rax
+ inc %rax
+ push %rax
+ lea -2(un), un
+ mov d1, md1
+ neg md1
+
+ jmp L(next)
+
+ ALIGN(16)
+L(loop):
+ C udiv_qr_3by2 (q,u2,u1,u2,u1,n0, d1,d0,di)
+ C Based on the optimized divrem_2.asm code.
+
+ mov di, %rax
+ mul u2
+ mov u1, t0
+ add %rax, t0 C q0 in t0
+ adc u2, %rdx
+ mov %rdx, t1 C q in t1
+ imul md1, %rdx
+ mov d0, %rax
+ lea (%rdx, u1), u2
+ mul t1
+ mov (up, un, 8), u1
+ sub d0, u1
+ sbb d1, u2
+ sub %rax, u1
+ sbb %rdx, u2
+ xor R32(%rax), R32(%rax)
+ xor R32(%rdx), R32(%rdx)
+ cmp t0, u2
+ cmovnc d0, %rax
+ cmovnc d1, %rdx
+ adc $0, t1
+ nop
+ add %rax, u1
+ adc %rdx, u2
+ cmp d1, u2
+ jae L(fix)
+L(bck):
+ mov t1, (qp, un, 8)
+L(next):
+ sub $1, un
+ jnc L(loop)
+L(end):
+ mov u2, 8(rp)
+ mov u1, (rp)
+
+ C qh on stack
+ pop %rax
+
+ pop %rbx
+ pop %r12
+ pop %r13
+ pop %r14
+ pop %r15
+ FUNC_EXIT()
+ ret
+
+L(fix): C Unlikely update. u2 >= d1
+ seta %dl
+ cmp d0, u1
+ setae %al
+ orb %dl, %al C "orb" form to placate Sun tools
+ je L(bck)
+ inc t1
+ sub d0, u1
+ sbb d1, u2
+ jmp L(bck)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/div_qr_2u_pi1.asm b/gmp/mpn/x86_64/div_qr_2u_pi1.asm
new file mode 100644
index 0000000000..85af96fbf6
--- /dev/null
+++ b/gmp/mpn/x86_64/div_qr_2u_pi1.asm
@@ -0,0 +1,200 @@
+dnl x86-64 mpn_div_qr_2u_pi1
+dnl -- Divide an mpn number by an unnormalized 2-limb number,
+dnl using a single-limb inverse and shifting the dividend on the fly.
+
+dnl Copyright 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C c/l
+C INPUT PARAMETERS
+define(`qp', `%rdi')
+define(`rp', `%rsi')
+define(`up_param', `%rdx')
+define(`un_param', `%rcx') dnl %rcx needed for shift count
+define(`d1', `%r8')
+define(`d0', `%r9')
+define(`shift_param', `FRAME+8(%rsp)')
+define(`di_param', `FRAME+16(%rsp)')
+
+define(`di', `%r10')
+define(`up', `%r11')
+define(`un', `%rbp')
+define(`u2', `%rbx')
+define(`u1', `%r12')
+define(`u0', `%rsi') dnl Same as rp, which is saved and restored.
+define(`t1', `%r13')
+define(`t0', `%r14')
+define(`md1', `%r15')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+deflit(`FRAME', 0)
+PROLOGUE(mpn_div_qr_2u_pi1)
+ mov di_param, di
+ mov up_param, up
+ push %r15
+ push %r14
+ push %r13
+ push %r12
+ push %rbx
+ push %rbp
+ push rp
+deflit(`FRAME', 56)
+ lea -2(un_param), un
+ mov d1, md1
+ neg md1
+
+ C int parameter, 32 bits only
+ movl shift_param, R32(%rcx)
+
+ C FIXME: Different code for SHLD_SLOW
+
+ xor R32(u2), R32(u2)
+ mov 8(up, un, 8), u1
+ shld %cl, u1, u2
+ C Remains to read (up, un, 8) and shift u1, u0
+ C udiv_qr_3by2 (qh,u2,u1,u2,u1,n0, d1,d0,di)
+ mov di, %rax
+ mul u2
+ mov (up, un, 8), u0
+ shld %cl, u0, u1
+ mov u1, t0
+ add %rax, t0 C q0 in t0
+ adc u2, %rdx
+ mov %rdx, t1 C q in t1
+ imul md1, %rdx
+ mov d0, %rax
+ lea (%rdx, u1), u2
+ mul t1
+ mov u0, u1
+ shl %cl, u1
+ sub d0, u1
+ sbb d1, u2
+ sub %rax, u1
+ sbb %rdx, u2
+ xor R32(%rax), R32(%rax)
+ xor R32(%rdx), R32(%rdx)
+ cmp t0, u2
+ cmovnc d0, %rax
+ cmovnc d1, %rdx
+ adc $0, t1
+ nop
+ add %rax, u1
+ adc %rdx, u2
+ cmp d1, u2
+ jae L(fix_qh)
+L(bck_qh):
+ push t1 C push qh on stack
+
+ jmp L(next)
+
+ ALIGN(16)
+L(loop):
+ C udiv_qr_3by2 (q,u2,u1,u2,u1,n0, d1,d0,di)
+ C Based on the optimized divrem_2.asm code.
+
+ mov di, %rax
+ mul u2
+ mov (up, un, 8), u0
+ xor R32(t1), R32(t1)
+ shld %cl, u0, t1
+ or t1, u1
+ mov u1, t0
+ add %rax, t0 C q0 in t0
+ adc u2, %rdx
+ mov %rdx, t1 C q in t1
+ imul md1, %rdx
+ mov d0, %rax
+ lea (%rdx, u1), u2
+ mul t1
+ mov u0, u1
+ shl %cl, u1
+ sub d0, u1
+ sbb d1, u2
+ sub %rax, u1
+ sbb %rdx, u2
+ xor R32(%rax), R32(%rax)
+ xor R32(%rdx), R32(%rdx)
+ cmp t0, u2
+ cmovnc d0, %rax
+ cmovnc d1, %rdx
+ adc $0, t1
+ nop
+ add %rax, u1
+ adc %rdx, u2
+ cmp d1, u2
+ jae L(fix)
+L(bck):
+ mov t1, (qp, un, 8)
+L(next):
+ sub $1, un
+ jnc L(loop)
+L(end):
+ C qh on stack
+ pop %rax
+ pop rp
+ shrd %cl, u2, u1
+ shr %cl, u2
+ mov u2, 8(rp)
+ mov u1, (rp)
+
+ pop %rbp
+ pop %rbx
+ pop %r12
+ pop %r13
+ pop %r14
+ pop %r15
+ ret
+
+L(fix): C Unlikely update. u2 >= d1
+ seta %dl
+ cmp d0, u1
+ setae %al
+ orb %dl, %al C "orb" form to placate Sun tools
+ je L(bck)
+ inc t1
+ sub d0, u1
+ sbb d1, u2
+ jmp L(bck)
+
+C Duplicated, just jumping back to a different address.
+L(fix_qh): C Unlikely update. u2 >= d1
+ seta %dl
+ cmp d0, u1
+ setae %al
+ orb %dl, %al C "orb" form to placate Sun tools
+ je L(bck_qh)
+ inc t1
+ sub d0, u1
+ sbb d1, u2
+ jmp L(bck_qh)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/dive_1.asm b/gmp/mpn/x86_64/dive_1.asm
new file mode 100644
index 0000000000..988bdab632
--- /dev/null
+++ b/gmp/mpn/x86_64/dive_1.asm
@@ -0,0 +1,158 @@
+dnl AMD64 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2001, 2002, 2004-2006, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 10
+C AMD K10 10
+C Intel P4 33
+C Intel core2 13.25
+C Intel corei 14
+C Intel atom 42
+C VIA nano 43
+
+C A quick adoption of the 32-bit K7 code.
+
+
+C INPUT PARAMETERS
+C rp rdi
+C up rsi
+C n rdx
+C divisor rcx
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_divexact_1)
+ FUNC_ENTRY(4)
+ push %rbx
+
+ mov %rcx, %rax
+ xor R32(%rcx), R32(%rcx) C shift count
+ mov %rdx, %r8
+
+ bt $0, R32(%rax)
+ jnc L(evn) C skip bsfq unless divisor is even
+
+L(odd): mov %rax, %rbx
+ shr R32(%rax)
+ and $127, R32(%rax) C d/2, 7 bits
+
+ LEA( binvert_limb_table, %rdx)
+
+ movzbl (%rdx,%rax), R32(%rax) C inv 8 bits
+
+ mov %rbx, %r11 C d without twos
+
+ lea (%rax,%rax), R32(%rdx) C 2*inv
+ imul R32(%rax), R32(%rax) C inv*inv
+ imul R32(%rbx), R32(%rax) C inv*inv*d
+ sub R32(%rax), R32(%rdx) C inv = 2*inv - inv*inv*d, 16 bits
+
+ lea (%rdx,%rdx), R32(%rax) C 2*inv
+ imul R32(%rdx), R32(%rdx) C inv*inv
+ imul R32(%rbx), R32(%rdx) C inv*inv*d
+ sub R32(%rdx), R32(%rax) C inv = 2*inv - inv*inv*d, 32 bits
+
+ lea (%rax,%rax), %r10 C 2*inv
+ imul %rax, %rax C inv*inv
+ imul %rbx, %rax C inv*inv*d
+ sub %rax, %r10 C inv = 2*inv - inv*inv*d, 64 bits
+
+ lea (%rsi,%r8,8), %rsi C up end
+ lea -8(%rdi,%r8,8), %rdi C rp end
+ neg %r8 C -n
+
+ mov (%rsi,%r8,8), %rax C up[0]
+
+ inc %r8
+ jz L(one)
+
+ mov (%rsi,%r8,8), %rdx C up[1]
+
+ shrd R8(%rcx), %rdx, %rax
+
+ xor R32(%rbx), R32(%rbx)
+ jmp L(ent)
+
+L(evn): bsf %rax, %rcx
+ shr R8(%rcx), %rax
+ jmp L(odd)
+
+ ALIGN(8)
+L(top):
+ C rax q
+ C rbx carry bit, 0 or 1
+ C rcx shift
+ C rdx
+ C rsi up end
+ C rdi rp end
+ C r8 counter, limbs, negative
+ C r10 d^(-1) mod 2^64
+ C r11 d, shifted down
+
+ mul %r11 C carry limb in rdx 0 10
+ mov -8(%rsi,%r8,8), %rax C
+ mov (%rsi,%r8,8), %r9 C
+ shrd R8(%rcx), %r9, %rax C
+ nop C
+ sub %rbx, %rax C apply carry bit
+ setc %bl C
+ sub %rdx, %rax C apply carry limb 5
+ adc $0, %rbx C 6
+L(ent): imul %r10, %rax C 6
+ mov %rax, (%rdi,%r8,8) C
+ inc %r8 C
+ jnz L(top)
+
+ mul %r11 C carry limb in rdx
+ mov -8(%rsi), %rax C up high limb
+ shr R8(%rcx), %rax
+ sub %rbx, %rax C apply carry bit
+ sub %rdx, %rax C apply carry limb
+ imul %r10, %rax
+ mov %rax, (%rdi)
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(one): shr R8(%rcx), %rax
+ imul %r10, %rax
+ mov %rax, (%rdi)
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/divrem_1.asm b/gmp/mpn/x86_64/divrem_1.asm
new file mode 100644
index 0000000000..91928d9aa3
--- /dev/null
+++ b/gmp/mpn/x86_64/divrem_1.asm
@@ -0,0 +1,306 @@
+dnl x86-64 mpn_divrem_1 -- mpn by limb division.
+
+dnl Copyright 2004, 2005, 2007-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C norm unorm frac
+C AMD K8,K9 13 13 12
+C AMD K10 13 13 12
+C Intel P4 43 44 43
+C Intel core2 24.5 24.5 19.5
+C Intel corei 20.5 19.5 18
+C Intel atom 43 46 36
+C VIA nano 25.5 25.5 24
+
+C mp_limb_t
+C mpn_divrem_1 (mp_ptr qp, mp_size_t fn,
+C mp_srcptr np, mp_size_t nn, mp_limb_t d)
+
+C mp_limb_t
+C mpn_preinv_divrem_1 (mp_ptr qp, mp_size_t fn,
+C mp_srcptr np, mp_size_t nn, mp_limb_t d,
+C mp_limb_t dinv, int cnt)
+
+C INPUT PARAMETERS
+define(`qp', `%rdi')
+define(`fn_param', `%rsi')
+define(`up_param', `%rdx')
+define(`un_param', `%rcx')
+define(`d', `%r8')
+define(`dinv', `%r9') C only for mpn_preinv_divrem_1
+C shift passed on stack C only for mpn_preinv_divrem_1
+
+define(`cnt', `%rcx')
+define(`up', `%rsi')
+define(`fn', `%r12')
+define(`un', `%rbx')
+
+
+C rax rbx rcx rdx rsi rdi rbp r8 r9 r10 r11 r12 r13 r14 r15
+C cnt qp d dinv
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+IFSTD(`define(`CNTOFF', `40($1)')')
+IFDOS(`define(`CNTOFF', `104($1)')')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_preinv_divrem_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+IFDOS(` mov 64(%rsp), %r9 ')
+ xor R32(%rax), R32(%rax)
+ push %r13
+ push %r12
+ push %rbp
+ push %rbx
+
+ mov fn_param, fn
+ mov un_param, un
+ add fn_param, un_param
+ mov up_param, up
+
+ lea -8(qp,un_param,8), qp
+
+ test d, d
+ js L(nent)
+
+ mov CNTOFF(%rsp), R8(cnt)
+ shl R8(cnt), d
+ jmp L(uent)
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_divrem_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ xor R32(%rax), R32(%rax)
+ push %r13
+ push %r12
+ push %rbp
+ push %rbx
+
+ mov fn_param, fn
+ mov un_param, un
+ add fn_param, un_param
+ mov up_param, up
+ je L(ret)
+
+ lea -8(qp,un_param,8), qp
+ xor R32(%rbp), R32(%rbp)
+
+ test d, d
+ jns L(unnormalized)
+
+L(normalized):
+ test un, un
+ je L(8) C un == 0
+ mov -8(up,un,8), %rbp
+ dec un
+ mov %rbp, %rax
+ sub d, %rbp
+ cmovc %rax, %rbp
+ sbb R32(%rax), R32(%rax)
+ inc R32(%rax)
+ mov %rax, (qp)
+ lea -8(qp), qp
+L(8):
+IFSTD(` push %rdi ')
+IFSTD(` push %rsi ')
+ push %r8
+IFSTD(` mov d, %rdi ')
+IFDOS(` mov d, %rcx ')
+ CALL( mpn_invert_limb)
+ pop %r8
+IFSTD(` pop %rsi ')
+IFSTD(` pop %rdi ')
+
+ mov %rax, dinv
+ mov %rbp, %rax
+ jmp L(nent)
+
+ ALIGN(16)
+L(ntop):mov (up,un,8), %r10 C K8-K10 P6-CNR P6-NHM P4
+ mul dinv C 0,13 0,20 0,18 0,45
+ add %r10, %rax C 4 8 3 12
+ adc %rbp, %rdx C 5 9 10 13
+ mov %rax, %rbp C 5 9 4 13
+ mov %rdx, %r13 C 6 11 12 23
+ imul d, %rdx C 6 11 11 23
+ sub %rdx, %r10 C 10 16 14 33
+ mov d, %rax C
+ add %r10, %rax C 11 17 15 34
+ cmp %rbp, %r10 C 11 17 15 34
+ cmovc %r10, %rax C 12 18 16 35
+ adc $-1, %r13 C
+ cmp d, %rax C
+ jae L(nfx) C
+L(nok): mov %r13, (qp) C
+ sub $8, qp C
+L(nent):lea 1(%rax), %rbp C
+ dec un C
+ jns L(ntop) C
+
+ xor R32(%rcx), R32(%rcx)
+ jmp L(87)
+
+L(nfx): sub d, %rax
+ inc %r13
+ jmp L(nok)
+
+L(unnormalized):
+ test un, un
+ je L(44)
+ mov -8(up,un,8), %rax
+ cmp d, %rax
+ jae L(44)
+ mov %rbp, (qp)
+ mov %rax, %rbp
+ lea -8(qp), qp
+ je L(ret)
+ dec un
+L(44):
+ bsr d, %rcx
+ not R32(%rcx)
+ shl R8(%rcx), d
+ shl R8(%rcx), %rbp
+
+ push %rcx
+IFSTD(` push %rdi ')
+IFSTD(` push %rsi ')
+ push %r8
+IFSTD(` mov d, %rdi ')
+IFDOS(` mov d, %rcx ')
+ CALL( mpn_invert_limb)
+ pop %r8
+IFSTD(` pop %rsi ')
+IFSTD(` pop %rdi ')
+ pop %rcx
+
+ mov %rax, dinv
+ mov %rbp, %rax
+ test un, un
+ je L(87)
+
+L(uent):dec un
+ mov (up,un,8), %rbp
+ neg R32(%rcx)
+ shr R8(%rcx), %rbp
+ neg R32(%rcx)
+ or %rbp, %rax
+ jmp L(ent)
+
+ ALIGN(16)
+L(utop):mov (up,un,8), %r10
+ shl R8(%rcx), %rbp
+ neg R32(%rcx)
+ shr R8(%rcx), %r10
+ neg R32(%rcx)
+ or %r10, %rbp
+ mul dinv
+ add %rbp, %rax
+ adc %r11, %rdx
+ mov %rax, %r11
+ mov %rdx, %r13
+ imul d, %rdx
+ sub %rdx, %rbp
+ mov d, %rax
+ add %rbp, %rax
+ cmp %r11, %rbp
+ cmovc %rbp, %rax
+ adc $-1, %r13
+ cmp d, %rax
+ jae L(ufx)
+L(uok): mov %r13, (qp)
+ sub $8, qp
+L(ent): mov (up,un,8), %rbp
+ dec un
+ lea 1(%rax), %r11
+ jns L(utop)
+
+L(uend):shl R8(%rcx), %rbp
+ mul dinv
+ add %rbp, %rax
+ adc %r11, %rdx
+ mov %rax, %r11
+ mov %rdx, %r13
+ imul d, %rdx
+ sub %rdx, %rbp
+ mov d, %rax
+ add %rbp, %rax
+ cmp %r11, %rbp
+ cmovc %rbp, %rax
+ adc $-1, %r13
+ cmp d, %rax
+ jae L(efx)
+L(eok): mov %r13, (qp)
+ sub $8, qp
+ jmp L(87)
+
+L(ufx): sub d, %rax
+ inc %r13
+ jmp L(uok)
+L(efx): sub d, %rax
+ inc %r13
+ jmp L(eok)
+
+L(87): mov d, %rbp
+ neg %rbp
+ jmp L(fent)
+
+ ALIGN(16) C K8-K10 P6-CNR P6-NHM P4
+L(ftop):mul dinv C 0,12 0,17 0,17
+ add %r11, %rdx C 5 8 10
+ mov %rax, %r11 C 4 8 3
+ mov %rdx, %r13 C 6 9 11
+ imul %rbp, %rdx C 6 9 11
+ mov d, %rax C
+ add %rdx, %rax C 10 14 14
+ cmp %r11, %rdx C 10 14 14
+ cmovc %rdx, %rax C 11 15 15
+ adc $-1, %r13 C
+ mov %r13, (qp) C
+ sub $8, qp C
+L(fent):lea 1(%rax), %r11 C
+ dec fn C
+ jns L(ftop) C
+
+ shr R8(%rcx), %rax
+L(ret): pop %rbx
+ pop %rbp
+ pop %r12
+ pop %r13
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/divrem_2.asm b/gmp/mpn/x86_64/divrem_2.asm
new file mode 100644
index 0000000000..66c2da1a05
--- /dev/null
+++ b/gmp/mpn/x86_64/divrem_2.asm
@@ -0,0 +1,189 @@
+dnl x86-64 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number.
+
+dnl Copyright 2007, 2008, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb best
+C AMD K8,K9 18
+C AMD K10 18
+C AMD bull
+C AMD pile
+C AMD bobcat
+C AMD jaguar
+C Intel P4 68
+C Intel core 34
+C Intel NHM 30.25
+C Intel SBR 21.3
+C Intel IBR 21.4
+C Intel HWL 20.6
+C Intel BWL
+C Intel atom 73
+C VIA nano 33
+
+
+C INPUT PARAMETERS
+define(`qp', `%rdi')
+define(`fn', `%rsi')
+define(`up_param', `%rdx')
+define(`un_param', `%rcx')
+define(`dp', `%r8')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_divrem_2)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %r15
+ push %r14
+ push %r13
+ push %r12
+ lea -24(%rdx,%rcx,8), %r12 C r12 = &up[un-1]
+ mov %rsi, %r13
+ push %rbp
+ mov %rdi, %rbp
+ push %rbx
+ mov 8(%r8), %r11 C d1
+ mov 16(%r12), %rbx
+ mov (%r8), %r8 C d0
+ mov 8(%r12), %r10
+
+ xor R32(%r15), R32(%r15)
+ cmp %rbx, %r11
+ ja L(2)
+ setb %dl
+ cmp %r10, %r8
+ setbe %al
+ orb %al, %dl C "orb" form to placate Sun tools
+ je L(2)
+ inc R32(%r15)
+ sub %r8, %r10
+ sbb %r11, %rbx
+L(2):
+ lea -3(%rcx,%r13), %r14 C un + fn - 3
+ test %r14, %r14
+ js L(end)
+
+ push %r8
+ push %r10
+ push %r11
+IFSTD(` mov %r11, %rdi ')
+IFDOS(` mov %r11, %rcx ')
+ CALL( mpn_invert_limb)
+ pop %r11
+ pop %r10
+ pop %r8
+
+ mov %r11, %rdx
+ mov %rax, %rdi
+ imul %rax, %rdx
+ mov %rdx, %r9
+ mul %r8
+ xor R32(%rcx), R32(%rcx)
+ add %r8, %r9
+ adc $-1, %rcx
+ add %rdx, %r9
+ adc $0, %rcx
+ js 2f
+1: dec %rdi
+ sub %r11, %r9
+ sbb $0, %rcx
+ jns 1b
+2:
+
+ lea (%rbp,%r14,8), %rbp
+ mov %r11, %rsi
+ neg %rsi C -d1
+
+C rax rbx rcx rdx rsi rdi rbp r8 r9 r10 r11 r12 r13 r14 r15
+C n2 un -d1 dinv qp d0 q0 d1 up fn msl
+
+ ALIGN(16)
+L(top): mov %rdi, %rax C di ncp
+ mul %rbx C 0, 17
+ mov %r10, %rcx C
+ add %rax, %rcx C 4
+ adc %rbx, %rdx C 5
+ mov %rdx, %r9 C q 6
+ imul %rsi, %rdx C 6
+ mov %r8, %rax C ncp
+ lea (%rdx, %r10), %rbx C n1 -= ... 10
+ xor R32(%r10), R32(%r10) C
+ mul %r9 C 7
+ cmp %r14, %r13 C
+ jg L(19) C
+ mov (%r12), %r10 C
+ sub $8, %r12 C
+L(19): sub %r8, %r10 C ncp
+ sbb %r11, %rbx C 11
+ sub %rax, %r10 C 11
+ sbb %rdx, %rbx C 12
+ xor R32(%rax), R32(%rax) C
+ xor R32(%rdx), R32(%rdx) C
+ cmp %rcx, %rbx C 13
+ cmovnc %r8, %rax C 14
+ cmovnc %r11, %rdx C 14
+ adc $0, %r9 C adjust q 14
+ nop
+ add %rax, %r10 C 15
+ adc %rdx, %rbx C 16
+ cmp %r11, %rbx C
+ jae L(fix) C
+L(bck): mov %r9, (%rbp) C
+ sub $8, %rbp C
+ dec %r14
+ jns L(top)
+
+L(end): mov %r10, 8(%r12)
+ mov %rbx, 16(%r12)
+ pop %rbx
+ pop %rbp
+ pop %r12
+ pop %r13
+ pop %r14
+ mov %r15, %rax
+ pop %r15
+ FUNC_EXIT()
+ ret
+
+L(fix): seta %dl
+ cmp %r8, %r10
+ setae %al
+ orb %dl, %al C "orb" form to placate Sun tools
+ je L(bck)
+ inc %r9
+ sub %r8, %r10
+ sbb %r11, %rbx
+ jmp L(bck)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/dos64.m4 b/gmp/mpn/x86_64/dos64.m4
new file mode 100644
index 0000000000..9414623b56
--- /dev/null
+++ b/gmp/mpn/x86_64/dos64.m4
@@ -0,0 +1,100 @@
+divert(-1)
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+define(`HOST_DOS64')
+
+
+dnl On DOS64 we always generate position-independent-code
+dnl
+
+define(`PIC')
+
+
+define(`LEA',`
+ lea $1(%rip), $2
+')
+
+
+dnl Usage: CALL(funcname)
+dnl
+dnl Simply override the definition in x86_64-defs.m4.
+
+define(`CALL',`call GSYM_PREFIX`'$1')
+
+
+dnl Usage: JUMPTABSECT
+
+define(`JUMPTABSECT', `RODATA')
+
+
+dnl Usage: JMPENT(targlabel,tablabel)
+
+define(`JMPENT', `.long $1-$2')
+
+
+dnl Usage: FUNC_ENTRY(nregparmas)
+dnl Usage: FUNC_EXIT()
+
+dnl FUNC_ENTRY and FUNC_EXIT provide an easy path for adoption of standard
+dnl ABI assembly to the DOS64 ABI.
+
+define(`FUNC_ENTRY',
+ `push %rdi
+ push %rsi
+ mov %rcx, %rdi
+ifelse(eval($1>=2),1,`dnl
+ mov %rdx, %rsi
+ifelse(eval($1>=3),1,`dnl
+ mov %r8, %rdx
+ifelse(eval($1>=4),1,`dnl
+ mov %r9, %rcx
+')')')')
+
+define(`FUNC_EXIT',
+ `pop %rsi
+ pop %rdi')
+
+
+dnl Target ABI macros. For DOS64 we override the defaults.
+
+define(`IFDOS', `$1')
+define(`IFSTD', `')
+define(`IFELF', `')
+
+
+dnl Usage: PROTECT(symbol)
+dnl
+dnl Used for private GMP symbols that should never be overridden by users.
+dnl This can save reloc entries and improve shlib sharing as well as
+dnl application startup times
+
+define(`PROTECT', `')
+
+
+divert`'dnl
diff --git a/gmp/mpn/x86_64/fastavx/copyd.asm b/gmp/mpn/x86_64/fastavx/copyd.asm
new file mode 100644
index 0000000000..41c55de5ca
--- /dev/null
+++ b/gmp/mpn/x86_64/fastavx/copyd.asm
@@ -0,0 +1,171 @@
+dnl AMD64 mpn_copyd optimised for CPUs with fast AVX.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003, 2005, 2007, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb aligned unaligned best seen for cpu?
+C AMD K8,K9 n/a
+C AMD K10 n/a
+C AMD bull n/a
+C AMD pile 4.87 4.87 N
+C AMD steam ? ?
+C AMD bobcat n/a
+C AMD jaguar n/a
+C Intel P4 n/a
+C Intel core n/a
+C Intel NHM n/a
+C Intel SBR 0.50 0.91 N
+C Intel IBR ?
+C Intel HWL 0.25 0.30 Y
+C Intel BWL ?
+C Intel atom n/a
+C VIA nano n/a
+
+C We try to do as many 32-byte operations as possible. The top-most and
+C bottom-most writes might need 8-byte operations. For the bulk copying, we
+C write using aligned 32-byte operations, but we read with both aligned and
+C unaligned 32-byte operations.
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+dnl define(`vmovdqu', vlddqu)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_copyd)
+ FUNC_ENTRY(3)
+
+ lea -32(rp,n,8), rp
+ lea -32(up,n,8), up
+
+ cmp $7, n C basecase needed for correctness
+ jbe L(bc)
+
+ test $8, R8(rp) C is rp 16-byte aligned?
+ jz L(a2) C jump if rp aligned
+ mov 24(up), %rax
+ lea -8(up), up
+ mov %rax, 24(rp)
+ lea -8(rp), rp
+ dec n
+L(a2): test $16, R8(rp) C is rp 32-byte aligned?
+ jz L(a3) C jump if rp aligned
+ vmovdqu 16(up), %xmm0
+ lea -16(up), up
+ vmovdqa %xmm0, 16(rp)
+ lea -16(rp), rp
+ sub $2, n
+L(a3): sub $16, n
+ jc L(sma)
+
+ ALIGN(16)
+L(top): vmovdqu (up), %ymm0
+ vmovdqu -32(up), %ymm1
+ vmovdqu -64(up), %ymm2
+ vmovdqu -96(up), %ymm3
+ lea -128(up), up
+ vmovdqa %ymm0, (rp)
+ vmovdqa %ymm1, -32(rp)
+ vmovdqa %ymm2, -64(rp)
+ vmovdqa %ymm3, -96(rp)
+ lea -128(rp), rp
+L(ali): sub $16, n
+ jnc L(top)
+
+L(sma): test $8, R8(n)
+ jz 1f
+ vmovdqu (up), %ymm0
+ vmovdqu -32(up), %ymm1
+ lea -64(up), up
+ vmovdqa %ymm0, (rp)
+ vmovdqa %ymm1, -32(rp)
+ lea -64(rp), rp
+1:
+ test $4, R8(n)
+ jz 1f
+ vmovdqu (up), %ymm0
+ lea -32(up), up
+ vmovdqa %ymm0, (rp)
+ lea -32(rp), rp
+1:
+ test $2, R8(n)
+ jz 1f
+ vmovdqu 16(up), %xmm0
+ lea -16(up), up
+ vmovdqa %xmm0, 16(rp)
+ lea -16(rp), rp
+1:
+ test $1, R8(n)
+ jz 1f
+ mov 24(up), %r8
+ mov %r8, 24(rp)
+1:
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(bc): test $4, R8(n)
+ jz 1f
+ mov 24(up), %rax
+ mov 16(up), %rcx
+ mov 8(up), %r8
+ mov (up), %r9
+ lea -32(up), up
+ mov %rax, 24(rp)
+ mov %rcx, 16(rp)
+ mov %r8, 8(rp)
+ mov %r9, (rp)
+ lea -32(rp), rp
+1:
+ test $2, R8(n)
+ jz 1f
+ mov 24(up), %rax
+ mov 16(up), %rcx
+ lea -16(up), up
+ mov %rax, 24(rp)
+ mov %rcx, 16(rp)
+ lea -16(rp), rp
+1:
+ test $1, R8(n)
+ jz 1f
+ mov 24(up), %rax
+ mov %rax, 24(rp)
+1:
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastavx/copyi.asm b/gmp/mpn/x86_64/fastavx/copyi.asm
new file mode 100644
index 0000000000..97264ef837
--- /dev/null
+++ b/gmp/mpn/x86_64/fastavx/copyi.asm
@@ -0,0 +1,168 @@
+dnl AMD64 mpn_copyi optimised for CPUs with fast AVX.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003, 2005, 2007, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb aligned unaligned best seen for cpu?
+C AMD K8,K9 n/a
+C AMD K10 n/a
+C AMD bull n/a
+C AMD pile 4.87 4.87 N
+C AMD steam ? ?
+C AMD bobcat n/a
+C AMD jaguar n/a
+C Intel P4 n/a
+C Intel core n/a
+C Intel NHM n/a
+C Intel SBR 0.50 0.91 N
+C Intel IBR ?
+C Intel HWL 0.25 0.30 Y
+C Intel BWL ?
+C Intel atom n/a
+C VIA nano n/a
+
+C We try to do as many 32-byte operations as possible. The top-most and
+C bottom-most writes might need 8-byte operations. For the bulk copying, we
+C write using aligned 32-byte operations, but we read with both aligned and
+C unaligned 32-byte operations.
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+dnl define(`vmovdqu', vlddqu)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_copyi)
+ FUNC_ENTRY(3)
+
+ cmp $7, n
+ jbe L(bc)
+
+ test $8, R8(rp) C is rp 16-byte aligned?
+ jz L(a2) C jump if rp aligned
+ mov (up), %rax
+ lea 8(up), up
+ mov %rax, (rp)
+ lea 8(rp), rp
+ dec n
+L(a2): test $16, R8(rp) C is rp 32-byte aligned?
+ jz L(a3) C jump if rp aligned
+ vmovdqu (up), %xmm0
+ lea 16(up), up
+ vmovdqa %xmm0, (rp)
+ lea 16(rp), rp
+ sub $2, n
+L(a3): sub $16, n
+ jc L(sma)
+
+ ALIGN(16)
+L(top): vmovdqu (up), %ymm0
+ vmovdqu 32(up), %ymm1
+ vmovdqu 64(up), %ymm2
+ vmovdqu 96(up), %ymm3
+ lea 128(up), up
+ vmovdqa %ymm0, (rp)
+ vmovdqa %ymm1, 32(rp)
+ vmovdqa %ymm2, 64(rp)
+ vmovdqa %ymm3, 96(rp)
+ lea 128(rp), rp
+L(ali): sub $16, n
+ jnc L(top)
+
+L(sma): test $8, R8(n)
+ jz 1f
+ vmovdqu (up), %ymm0
+ vmovdqu 32(up), %ymm1
+ lea 64(up), up
+ vmovdqa %ymm0, (rp)
+ vmovdqa %ymm1, 32(rp)
+ lea 64(rp), rp
+1:
+ test $4, R8(n)
+ jz 1f
+ vmovdqu (up), %ymm0
+ lea 32(up), up
+ vmovdqa %ymm0, (rp)
+ lea 32(rp), rp
+1:
+ test $2, R8(n)
+ jz 1f
+ vmovdqu (up), %xmm0
+ lea 16(up), up
+ vmovdqa %xmm0, (rp)
+ lea 16(rp), rp
+1:
+L(end): test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov %r8, (rp)
+1:
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(bc): test $4, R8(n)
+ jz 1f
+ mov (up), %rax
+ mov 8(up), %rcx
+ mov 16(up), %r8
+ mov 24(up), %r9
+ lea 32(up), up
+ mov %rax, (rp)
+ mov %rcx, 8(rp)
+ mov %r8, 16(rp)
+ mov %r9, 24(rp)
+ lea 32(rp), rp
+1:
+ test $2, R8(n)
+ jz 1f
+ mov (up), %rax
+ mov 8(up), %rcx
+ lea 16(up), up
+ mov %rax, (rp)
+ mov %rcx, 8(rp)
+ lea 16(rp), rp
+1:
+ test $1, R8(n)
+ jz 1f
+ mov (up), %rax
+ mov %rax, (rp)
+1:
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/README b/gmp/mpn/x86_64/fastsse/README
new file mode 100644
index 0000000000..520551ed99
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/README
@@ -0,0 +1,21 @@
+This directory contains code for x86-64 processors with fast
+implementations of SSE operations, hence the name "fastsse".
+
+Current processors that might benefit from this code are:
+
+ AMD K10
+ AMD Bulldozer
+ Intel Nocona
+ Intel Nehalem/Westmere
+ Intel Sandybridge/Ivybridge
+ VIA Nano
+
+Current processors that do not benefit from this code are:
+
+ AMD K8
+ AMD Bobcat
+ Intel Atom
+
+Intel Conroe/Penryn is a border case; its handling of non-aligned
+128-bit memory operands is poor. VIA Nano also have poor handling of
+non-aligned operands.
diff --git a/gmp/mpn/x86_64/fastsse/com-palignr.asm b/gmp/mpn/x86_64/fastsse/com-palignr.asm
new file mode 100644
index 0000000000..d9641e890d
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/com-palignr.asm
@@ -0,0 +1,302 @@
+dnl AMD64 mpn_com optimised for CPUs with fast SSE copying and SSSE3.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb cycles/limb good
+C aligned unaligned best seen for cpu?
+C AMD K8,K9 2.0 illop 1.0/1.0 N
+C AMD K10 0.85 illop Y/N
+C AMD bd1 1.39 ? 1.45 Y/N
+C AMD bobcat 1.97 ? 8.17 1.5/1.5 N
+C Intel P4 2.26 illop Y/N
+C Intel core2 0.52 0.82 opt/0.74 Y
+C Intel NHM 0.52 0.65 opt/opt Y
+C Intel SBR 0.51 0.55 opt/0.51 Y
+C Intel atom 1.16 1.70 opt/opt Y
+C VIA nano 1.09 1.10 opt/opt Y
+
+C We use only 16-byte operations, except for unaligned top-most and bottom-most
+C limbs. We use the SSSE3 palignr instruction when rp - up = 8 (mod 16). That
+C instruction is better adapted to mpn_copyd's needs, we need to contort the
+C code to use it here.
+C
+C For operands of < COM_SSE_THRESHOLD limbs, we use a plain 64-bit loop, taken
+C from the x86_64 default code.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+
+C There are three instructions for loading an aligned 128-bit quantity. We use
+C movaps, since it has the shortest coding.
+define(`movdqa', ``movaps'')
+
+ifdef(`COM_SSE_THRESHOLD',`',`define(`COM_SSE_THRESHOLD', 7)')
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_com)
+ FUNC_ENTRY(3)
+
+ cmp $COM_SSE_THRESHOLD, n
+ jbe L(bc)
+
+ pcmpeqb %xmm7, %xmm7 C set to 111...111
+
+ test $8, R8(rp) C is rp 16-byte aligned?
+ jz L(rp_aligned) C jump if rp aligned
+
+ mov (up), %r8
+ lea 8(up), up
+ not %r8
+ mov %r8, (rp)
+ lea 8(rp), rp
+ dec n
+
+L(rp_aligned):
+ test $8, R8(up)
+ jnz L(uent)
+
+ifelse(eval(COM_SSE_THRESHOLD >= 8),1,
+` sub $8, n',
+` jmp L(am)')
+
+ ALIGN(16)
+L(atop):movdqa 0(up), %xmm0
+ movdqa 16(up), %xmm1
+ movdqa 32(up), %xmm2
+ movdqa 48(up), %xmm3
+ lea 64(up), up
+ pxor %xmm7, %xmm0
+ pxor %xmm7, %xmm1
+ pxor %xmm7, %xmm2
+ pxor %xmm7, %xmm3
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ movdqa %xmm2, 32(rp)
+ movdqa %xmm3, 48(rp)
+ lea 64(rp), rp
+L(am): sub $8, n
+ jnc L(atop)
+
+ test $4, R8(n)
+ jz 1f
+ movdqa (up), %xmm0
+ movdqa 16(up), %xmm1
+ lea 32(up), up
+ pxor %xmm7, %xmm0
+ pxor %xmm7, %xmm1
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ lea 32(rp), rp
+
+1: test $2, R8(n)
+ jz 1f
+ movdqa (up), %xmm0
+ lea 16(up), up
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, (rp)
+ lea 16(rp), rp
+
+1: test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ not %r8
+ mov %r8, (rp)
+
+1: FUNC_EXIT()
+ ret
+
+L(uent):
+C Code handling up - rp = 8 (mod 16)
+
+C FIXME: The code below only handles overlap if it is close to complete, or
+C quite separate: up-rp < 5 or up-up > 15 limbs
+ lea -40(up), %rax C 40 = 5 * GMP_LIMB_BYTES
+ sub rp, %rax
+ cmp $80, %rax C 80 = (15-5) * GMP_LIMB_BYTES
+ jbe L(bc) C deflect to plain loop
+
+ sub $16, n
+ jc L(uend)
+
+ movdqa 120(up), %xmm3
+
+ sub $16, n
+ jmp L(um)
+
+ ALIGN(16)
+L(utop):movdqa 120(up), %xmm3
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, -128(rp)
+ sub $16, n
+L(um): movdqa 104(up), %xmm2
+ palignr($8, %xmm2, %xmm3)
+ movdqa 88(up), %xmm1
+ pxor %xmm7, %xmm3
+ movdqa %xmm3, 112(rp)
+ palignr($8, %xmm1, %xmm2)
+ movdqa 72(up), %xmm0
+ pxor %xmm7, %xmm2
+ movdqa %xmm2, 96(rp)
+ palignr($8, %xmm0, %xmm1)
+ movdqa 56(up), %xmm3
+ pxor %xmm7, %xmm1
+ movdqa %xmm1, 80(rp)
+ palignr($8, %xmm3, %xmm0)
+ movdqa 40(up), %xmm2
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, 64(rp)
+ palignr($8, %xmm2, %xmm3)
+ movdqa 24(up), %xmm1
+ pxor %xmm7, %xmm3
+ movdqa %xmm3, 48(rp)
+ palignr($8, %xmm1, %xmm2)
+ movdqa 8(up), %xmm0
+ pxor %xmm7, %xmm2
+ movdqa %xmm2, 32(rp)
+ palignr($8, %xmm0, %xmm1)
+ movdqa -8(up), %xmm3
+ pxor %xmm7, %xmm1
+ movdqa %xmm1, 16(rp)
+ palignr($8, %xmm3, %xmm0)
+ lea 128(up), up
+ lea 128(rp), rp
+ jnc L(utop)
+
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, -128(rp)
+
+L(uend):test $8, R8(n)
+ jz 1f
+ movdqa 56(up), %xmm3
+ movdqa 40(up), %xmm2
+ palignr($8, %xmm2, %xmm3)
+ movdqa 24(up), %xmm1
+ pxor %xmm7, %xmm3
+ movdqa %xmm3, 48(rp)
+ palignr($8, %xmm1, %xmm2)
+ movdqa 8(up), %xmm0
+ pxor %xmm7, %xmm2
+ movdqa %xmm2, 32(rp)
+ palignr($8, %xmm0, %xmm1)
+ movdqa -8(up), %xmm3
+ pxor %xmm7, %xmm1
+ movdqa %xmm1, 16(rp)
+ palignr($8, %xmm3, %xmm0)
+ lea 64(up), up
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, (rp)
+ lea 64(rp), rp
+
+1: test $4, R8(n)
+ jz 1f
+ movdqa 24(up), %xmm1
+ movdqa 8(up), %xmm0
+ palignr($8, %xmm0, %xmm1)
+ movdqa -8(up), %xmm3
+ pxor %xmm7, %xmm1
+ movdqa %xmm1, 16(rp)
+ palignr($8, %xmm3, %xmm0)
+ lea 32(up), up
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, (rp)
+ lea 32(rp), rp
+
+1: test $2, R8(n)
+ jz 1f
+ movdqa 8(up), %xmm0
+ movdqa -8(up), %xmm3
+ palignr($8, %xmm3, %xmm0)
+ lea 16(up), up
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, (rp)
+ lea 16(rp), rp
+
+1: test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ not %r8
+ mov %r8, (rp)
+
+1: FUNC_EXIT()
+ ret
+
+C Basecase code. Needed for good small operands speed, not for
+C correctness as the above code is currently written.
+
+L(bc): lea -8(rp), rp
+ sub $4, R32(n)
+ jc L(end)
+
+ifelse(eval(1 || COM_SSE_THRESHOLD >= 8),1,
+` ALIGN(16)')
+L(top): mov (up), %r8
+ mov 8(up), %r9
+ lea 32(rp), rp
+ mov 16(up), %r10
+ mov 24(up), %r11
+ lea 32(up), up
+ not %r8
+ not %r9
+ not %r10
+ not %r11
+ mov %r8, -24(rp)
+ mov %r9, -16(rp)
+ifelse(eval(1 || COM_SSE_THRESHOLD >= 8),1,
+` sub $4, R32(n)')
+ mov %r10, -8(rp)
+ mov %r11, (rp)
+ifelse(eval(1 || COM_SSE_THRESHOLD >= 8),1,
+` jnc L(top)')
+
+L(end): test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ not %r8
+ mov %r8, 8(rp)
+ lea 8(rp), rp
+ lea 8(up), up
+1: test $2, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov 8(up), %r9
+ not %r8
+ not %r9
+ mov %r8, 8(rp)
+ mov %r9, 16(rp)
+1: FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/com.asm b/gmp/mpn/x86_64/fastsse/com.asm
new file mode 100644
index 0000000000..4abb076d3f
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/com.asm
@@ -0,0 +1,161 @@
+dnl AMD64 mpn_com optimised for CPUs with fast SSE.
+
+dnl Copyright 2003, 2005, 2007, 2011, 2012 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb cycles/limb good
+C aligned unaligned best seen for cpu?
+C AMD K8,K9 2.0 2.0 N
+C AMD K10 0.85 1.3 Y/N
+C AMD bd1 1.40 1.40 Y
+C AMD bobcat 3.1 3.1 N
+C Intel P4 2.28 illop Y
+C Intel core2 1.02 1.02 N
+C Intel NHM 0.53 0.68 Y
+C Intel SBR 0.51 0.75 Y
+C Intel atom 3.68 3.68 N
+C VIA nano 1.17 5.09 Y/N
+
+C We try to do as many 16-byte operations as possible. The top-most and
+C bottom-most writes might need 8-byte operations. We can always write using
+C aligned 16-byte operations, we read with both aligned and unaligned 16-byte
+C operations.
+
+C Instead of having separate loops for reading aligned and unaligned, we read
+C using MOVDQU. This seems to work great except for core2; there performance
+C doubles when reading using MOVDQA (for aligned source). It is unclear how to
+C best handle the unaligned case there.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_com)
+ FUNC_ENTRY(3)
+
+ test n, n
+ jz L(don)
+
+ pcmpeqb %xmm7, %xmm7 C set to 111...111
+
+ test $8, R8(rp) C is rp 16-byte aligned?
+ jz L(ali) C jump if rp aligned
+ mov (up), %rax
+ lea 8(up), up
+ not %rax
+ mov %rax, (rp)
+ lea 8(rp), rp
+ dec n
+
+ sub $14, n
+ jc L(sma)
+
+ ALIGN(16)
+L(top): movdqu (up), %xmm0
+ movdqu 16(up), %xmm1
+ movdqu 32(up), %xmm2
+ movdqu 48(up), %xmm3
+ movdqu 64(up), %xmm4
+ movdqu 80(up), %xmm5
+ movdqu 96(up), %xmm6
+ lea 112(up), up
+ pxor %xmm7, %xmm0
+ pxor %xmm7, %xmm1
+ pxor %xmm7, %xmm2
+ pxor %xmm7, %xmm3
+ pxor %xmm7, %xmm4
+ pxor %xmm7, %xmm5
+ pxor %xmm7, %xmm6
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ movdqa %xmm2, 32(rp)
+ movdqa %xmm3, 48(rp)
+ movdqa %xmm4, 64(rp)
+ movdqa %xmm5, 80(rp)
+ movdqa %xmm6, 96(rp)
+ lea 112(rp), rp
+L(ali): sub $14, n
+ jnc L(top)
+
+L(sma): add $14, n
+ test $8, R8(n)
+ jz 1f
+ movdqu (up), %xmm0
+ movdqu 16(up), %xmm1
+ movdqu 32(up), %xmm2
+ movdqu 48(up), %xmm3
+ lea 64(up), up
+ pxor %xmm7, %xmm0
+ pxor %xmm7, %xmm1
+ pxor %xmm7, %xmm2
+ pxor %xmm7, %xmm3
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ movdqa %xmm2, 32(rp)
+ movdqa %xmm3, 48(rp)
+ lea 64(rp), rp
+1:
+ test $4, R8(n)
+ jz 1f
+ movdqu (up), %xmm0
+ movdqu 16(up), %xmm1
+ lea 32(up), up
+ pxor %xmm7, %xmm0
+ pxor %xmm7, %xmm1
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ lea 32(rp), rp
+1:
+ test $2, R8(n)
+ jz 1f
+ movdqu (up), %xmm0
+ lea 16(up), up
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, (rp)
+ lea 16(rp), rp
+1:
+ test $1, R8(n)
+ jz 1f
+ mov (up), %rax
+ not %rax
+ mov %rax, (rp)
+1:
+L(don): FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/copyd-palignr.asm b/gmp/mpn/x86_64/fastsse/copyd-palignr.asm
new file mode 100644
index 0000000000..7430cadc09
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/copyd-palignr.asm
@@ -0,0 +1,251 @@
+dnl AMD64 mpn_copyd optimised for CPUs with fast SSE copying and SSSE3.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb cycles/limb good
+C aligned unaligned best seen for cpu?
+C AMD K8,K9 2.0 illop 1.0/1.0 N
+C AMD K10 0.85 illop Y/N
+C AMD bull 0.70 0.70 Y
+C AMD pile 0.68 0.68 Y
+C AMD steam ? ?
+C AMD bobcat 1.97 8.24 1.5/1.5 N
+C AMD jaguar ? ?
+C Intel P4 2.26 illop Y/N
+C Intel core 0.52 0.68-0.80 opt/0.64 Y
+C Intel NHM 0.52 0.64 opt/opt Y
+C Intel SBR 0.51 0.51 opt/0.51 Y
+C Intel IBR ? ? Y
+C Intel HWL 0.51 0.51 0.25/0.25 N
+C Intel atom 1.16 1.66 opt/opt Y
+C VIA nano 1.08 1.06 opt/opt Y
+
+C We use only 16-byte operations, except for unaligned top-most and bottom-most
+C limbs. We use the SSSE3 palignr instruction when rp - up = 8 (mod 16).
+C
+C For operands of < COPYD_SSE_THRESHOLD limbs, we use a plain 64-bit loop,
+C taken from the x86_64 default code.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+
+C There are three instructions for loading an aligned 128-bit quantity. We use
+C movaps, since it has the shortest coding.
+define(`movdqa', ``movaps'')
+
+ifdef(`COPYD_SSE_THRESHOLD',`',`define(`COPYD_SSE_THRESHOLD', 7)')
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_copyd)
+ FUNC_ENTRY(3)
+
+ lea -8(up,n,8), up
+ lea -8(rp,n,8), rp
+
+ cmp $COPYD_SSE_THRESHOLD, n
+ jbe L(bc)
+
+ test $8, R8(rp) C is rp 16-byte aligned?
+ jnz L(rp_aligned) C jump if rp aligned
+
+ mov (up), %rax C copy one limb
+ mov %rax, (rp)
+ lea -8(up), up
+ lea -8(rp), rp
+ dec n
+
+L(rp_aligned):
+ test $8, R8(up)
+ jz L(uent)
+
+ifelse(eval(COPYD_SSE_THRESHOLD >= 8),1,
+` sub $8, n',
+` jmp L(am)')
+
+ ALIGN(16)
+L(atop):movdqa -8(up), %xmm0
+ movdqa -24(up), %xmm1
+ movdqa -40(up), %xmm2
+ movdqa -56(up), %xmm3
+ lea -64(up), up
+ movdqa %xmm0, -8(rp)
+ movdqa %xmm1, -24(rp)
+ movdqa %xmm2, -40(rp)
+ movdqa %xmm3, -56(rp)
+ lea -64(rp), rp
+L(am): sub $8, n
+ jnc L(atop)
+
+ test $4, R8(n)
+ jz 1f
+ movdqa -8(up), %xmm0
+ movdqa -24(up), %xmm1
+ lea -32(up), up
+ movdqa %xmm0, -8(rp)
+ movdqa %xmm1, -24(rp)
+ lea -32(rp), rp
+
+1: test $2, R8(n)
+ jz 1f
+ movdqa -8(up), %xmm0
+ lea -16(up), up
+ movdqa %xmm0, -8(rp)
+ lea -16(rp), rp
+
+1: test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov %r8, (rp)
+
+1: FUNC_EXIT()
+ ret
+
+L(uent):sub $16, n
+ movdqa (up), %xmm0
+ jc L(uend)
+
+ ALIGN(16)
+L(utop):sub $16, n
+ movdqa -16(up), %xmm1
+ palignr($8, %xmm1, %xmm0)
+ movdqa %xmm0, -8(rp)
+ movdqa -32(up), %xmm2
+ palignr($8, %xmm2, %xmm1)
+ movdqa %xmm1, -24(rp)
+ movdqa -48(up), %xmm3
+ palignr($8, %xmm3, %xmm2)
+ movdqa %xmm2, -40(rp)
+ movdqa -64(up), %xmm0
+ palignr($8, %xmm0, %xmm3)
+ movdqa %xmm3, -56(rp)
+ movdqa -80(up), %xmm1
+ palignr($8, %xmm1, %xmm0)
+ movdqa %xmm0, -72(rp)
+ movdqa -96(up), %xmm2
+ palignr($8, %xmm2, %xmm1)
+ movdqa %xmm1, -88(rp)
+ movdqa -112(up), %xmm3
+ palignr($8, %xmm3, %xmm2)
+ movdqa %xmm2, -104(rp)
+ movdqa -128(up), %xmm0
+ palignr($8, %xmm0, %xmm3)
+ movdqa %xmm3, -120(rp)
+ lea -128(up), up
+ lea -128(rp), rp
+ jnc L(utop)
+
+L(uend):test $8, R8(n)
+ jz 1f
+ movdqa -16(up), %xmm1
+ palignr($8, %xmm1, %xmm0)
+ movdqa %xmm0, -8(rp)
+ movdqa -32(up), %xmm0
+ palignr($8, %xmm0, %xmm1)
+ movdqa %xmm1, -24(rp)
+ movdqa -48(up), %xmm1
+ palignr($8, %xmm1, %xmm0)
+ movdqa %xmm0, -40(rp)
+ movdqa -64(up), %xmm0
+ palignr($8, %xmm0, %xmm1)
+ movdqa %xmm1, -56(rp)
+ lea -64(up), up
+ lea -64(rp), rp
+
+1: test $4, R8(n)
+ jz 1f
+ movdqa -16(up), %xmm1
+ palignr($8, %xmm1, %xmm0)
+ movdqa %xmm0, -8(rp)
+ movdqa -32(up), %xmm0
+ palignr($8, %xmm0, %xmm1)
+ movdqa %xmm1, -24(rp)
+ lea -32(up), up
+ lea -32(rp), rp
+
+1: test $2, R8(n)
+ jz 1f
+ movdqa -16(up), %xmm1
+ palignr($8, %xmm1, %xmm0)
+ movdqa %xmm0, -8(rp)
+ lea -16(up), up
+ lea -16(rp), rp
+
+1: test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov %r8, (rp)
+
+1: FUNC_EXIT()
+ ret
+
+C Basecase code. Needed for good small operands speed, not for
+C correctness as the above code is currently written.
+
+L(bc): sub $4, R32(n)
+ jc L(end)
+
+ ALIGN(16)
+L(top): mov (up), %r8
+ mov -8(up), %r9
+ lea -32(rp), rp
+ mov -16(up), %r10
+ mov -24(up), %r11
+ lea -32(up), up
+ mov %r8, 32(rp)
+ mov %r9, 24(rp)
+ifelse(eval(COPYD_SSE_THRESHOLD >= 8),1,
+` sub $4, R32(n)')
+ mov %r10, 16(rp)
+ mov %r11, 8(rp)
+ifelse(eval(COPYD_SSE_THRESHOLD >= 8),1,
+` jnc L(top)')
+
+L(end): test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov %r8, (rp)
+ lea -8(rp), rp
+ lea -8(up), up
+1: test $2, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov -8(up), %r9
+ mov %r8, (rp)
+ mov %r9, -8(rp)
+1: FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/copyd.asm b/gmp/mpn/x86_64/fastsse/copyd.asm
new file mode 100644
index 0000000000..5c6094c7e2
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/copyd.asm
@@ -0,0 +1,145 @@
+dnl AMD64 mpn_copyd optimised for CPUs with fast SSE.
+
+dnl Copyright 2003, 2005, 2007, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb good for cpu?
+C AMD K8,K9
+C AMD K10 0.85 Y
+C AMD bd1 0.8 Y
+C AMD bobcat
+C Intel P4 2.28 Y
+C Intel core2 1
+C Intel NHM 0.5 Y
+C Intel SBR 0.5 Y
+C Intel atom
+C VIA nano 1.1 Y
+
+C We try to do as many 16-byte operations as possible. The top-most and
+C bottom-most writes might need 8-byte operations. We can always write using
+C aligned 16-byte operations, we read with both aligned and unaligned 16-byte
+C operations.
+
+C Instead of having separate loops for reading aligned and unaligned, we read
+C using MOVDQU. This seems to work great except for core2; there performance
+C doubles when reading using MOVDQA (for aligned source). It is unclear how to
+C best handle the unaligned case there.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_copyd)
+ FUNC_ENTRY(3)
+
+ test n, n
+ jz L(don)
+
+ lea -16(rp,n,8), rp
+ lea -16(up,n,8), up
+
+ test $8, R8(rp) C is rp 16-byte aligned?
+ jz L(ali) C jump if rp aligned
+ mov 8(up), %rax
+ lea -8(up), up
+ mov %rax, 8(rp)
+ lea -8(rp), rp
+ dec n
+
+ sub $16, n
+ jc L(sma)
+
+ ALIGN(16)
+L(top): movdqu (up), %xmm0
+ movdqu -16(up), %xmm1
+ movdqu -32(up), %xmm2
+ movdqu -48(up), %xmm3
+ movdqu -64(up), %xmm4
+ movdqu -80(up), %xmm5
+ movdqu -96(up), %xmm6
+ movdqu -112(up), %xmm7
+ lea -128(up), up
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, -16(rp)
+ movdqa %xmm2, -32(rp)
+ movdqa %xmm3, -48(rp)
+ movdqa %xmm4, -64(rp)
+ movdqa %xmm5, -80(rp)
+ movdqa %xmm6, -96(rp)
+ movdqa %xmm7, -112(rp)
+ lea -128(rp), rp
+L(ali): sub $16, n
+ jnc L(top)
+
+L(sma): test $8, R8(n)
+ jz 1f
+ movdqu (up), %xmm0
+ movdqu -16(up), %xmm1
+ movdqu -32(up), %xmm2
+ movdqu -48(up), %xmm3
+ lea -64(up), up
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, -16(rp)
+ movdqa %xmm2, -32(rp)
+ movdqa %xmm3, -48(rp)
+ lea -64(rp), rp
+1:
+ test $4, R8(n)
+ jz 1f
+ movdqu (up), %xmm0
+ movdqu -16(up), %xmm1
+ lea -32(up), up
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, -16(rp)
+ lea -32(rp), rp
+1:
+ test $2, R8(n)
+ jz 1f
+ movdqu (up), %xmm0
+ lea -16(up), up
+ movdqa %xmm0, (rp)
+ lea -16(rp), rp
+1:
+ test $1, R8(n)
+ jz 1f
+ mov 8(up), %r8
+ mov %r8, 8(rp)
+1:
+L(don): FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/copyi-palignr.asm b/gmp/mpn/x86_64/fastsse/copyi-palignr.asm
new file mode 100644
index 0000000000..fda3c3500f
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/copyi-palignr.asm
@@ -0,0 +1,295 @@
+dnl AMD64 mpn_copyi optimised for CPUs with fast SSE copying and SSSE3.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb cycles/limb cycles/limb good
+C aligned unaligned best seen for cpu?
+C AMD K8,K9 2.0 illop 1.0/1.0 N
+C AMD K10 0.85 illop Y/N
+C AMD bull 0.70 0.66 Y
+C AMD pile 0.68 0.66 Y
+C AMD steam ? ?
+C AMD bobcat 1.97 8.16 1.5/1.5 N
+C AMD jaguar ? ?
+C Intel P4 2.26 illop Y/N
+C Intel core 0.52 0.64 opt/opt Y
+C Intel NHM 0.52 0.71 opt/opt Y
+C Intel SBR 0.51 0.54 opt/0.51 Y
+C Intel IBR ? ? Y
+C Intel HWL 0.51 0.52 0.25/0.25 N
+C Intel atom 1.16 1.61 opt/opt Y
+C VIA nano 1.09 1.08 opt/opt Y
+
+C We use only 16-byte operations, except for unaligned top-most and bottom-most
+C limbs. We use the SSSE3 palignr instruction when rp - up = 8 (mod 16). That
+C instruction is better adapted to mpn_copyd's needs, we need to contort the
+C code to use it here.
+C
+C For operands of < COPYI_SSE_THRESHOLD limbs, we use a plain 64-bit loop,
+C taken from the x86_64 default code.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+
+C There are three instructions for loading an aligned 128-bit quantity. We use
+C movaps, since it has the shortest coding.
+dnl define(`movdqa', ``movaps'')
+
+ifdef(`COPYI_SSE_THRESHOLD',`',`define(`COPYI_SSE_THRESHOLD', 7)')
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_copyi)
+ FUNC_ENTRY(3)
+
+ cmp $COPYI_SSE_THRESHOLD, n
+ jbe L(bc)
+
+ test $8, R8(rp) C is rp 16-byte aligned?
+ jz L(rp_aligned) C jump if rp aligned
+
+ movsq C copy one limb
+ dec n
+
+L(rp_aligned):
+ test $8, R8(up)
+ jnz L(uent)
+
+ifelse(eval(COPYI_SSE_THRESHOLD >= 8),1,
+` sub $8, n',
+` jmp L(am)')
+
+ ALIGN(16)
+L(atop):movdqa 0(up), %xmm0
+ movdqa 16(up), %xmm1
+ movdqa 32(up), %xmm2
+ movdqa 48(up), %xmm3
+ lea 64(up), up
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ movdqa %xmm2, 32(rp)
+ movdqa %xmm3, 48(rp)
+ lea 64(rp), rp
+L(am): sub $8, n
+ jnc L(atop)
+
+ test $4, R8(n)
+ jz 1f
+ movdqa (up), %xmm0
+ movdqa 16(up), %xmm1
+ lea 32(up), up
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ lea 32(rp), rp
+
+1: test $2, R8(n)
+ jz 1f
+ movdqa (up), %xmm0
+ lea 16(up), up
+ movdqa %xmm0, (rp)
+ lea 16(rp), rp
+
+1: test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov %r8, (rp)
+
+1: FUNC_EXIT()
+ ret
+
+L(uent):
+C Code handling up - rp = 8 (mod 16)
+
+ cmp $16, n
+ jc L(ued0)
+
+IFDOS(` add $-56, %rsp ')
+IFDOS(` movdqa %xmm6, (%rsp) ')
+IFDOS(` movdqa %xmm7, 16(%rsp) ')
+IFDOS(` movdqa %xmm8, 32(%rsp) ')
+
+ movaps 120(up), %xmm7
+ movaps 104(up), %xmm6
+ movaps 88(up), %xmm5
+ movaps 72(up), %xmm4
+ movaps 56(up), %xmm3
+ movaps 40(up), %xmm2
+ lea 128(up), up
+ sub $32, n
+ jc L(ued1)
+
+ ALIGN(16)
+L(utop):movaps -104(up), %xmm1
+ sub $16, n
+ movaps -120(up), %xmm0
+ palignr($8, %xmm6, %xmm7)
+ movaps -136(up), %xmm8
+ movdqa %xmm7, 112(rp)
+ palignr($8, %xmm5, %xmm6)
+ movaps 120(up), %xmm7
+ movdqa %xmm6, 96(rp)
+ palignr($8, %xmm4, %xmm5)
+ movaps 104(up), %xmm6
+ movdqa %xmm5, 80(rp)
+ palignr($8, %xmm3, %xmm4)
+ movaps 88(up), %xmm5
+ movdqa %xmm4, 64(rp)
+ palignr($8, %xmm2, %xmm3)
+ movaps 72(up), %xmm4
+ movdqa %xmm3, 48(rp)
+ palignr($8, %xmm1, %xmm2)
+ movaps 56(up), %xmm3
+ movdqa %xmm2, 32(rp)
+ palignr($8, %xmm0, %xmm1)
+ movaps 40(up), %xmm2
+ movdqa %xmm1, 16(rp)
+ palignr($8, %xmm8, %xmm0)
+ lea 128(up), up
+ movdqa %xmm0, (rp)
+ lea 128(rp), rp
+ jnc L(utop)
+
+L(ued1):movaps -104(up), %xmm1
+ movaps -120(up), %xmm0
+ movaps -136(up), %xmm8
+ palignr($8, %xmm6, %xmm7)
+ movdqa %xmm7, 112(rp)
+ palignr($8, %xmm5, %xmm6)
+ movdqa %xmm6, 96(rp)
+ palignr($8, %xmm4, %xmm5)
+ movdqa %xmm5, 80(rp)
+ palignr($8, %xmm3, %xmm4)
+ movdqa %xmm4, 64(rp)
+ palignr($8, %xmm2, %xmm3)
+ movdqa %xmm3, 48(rp)
+ palignr($8, %xmm1, %xmm2)
+ movdqa %xmm2, 32(rp)
+ palignr($8, %xmm0, %xmm1)
+ movdqa %xmm1, 16(rp)
+ palignr($8, %xmm8, %xmm0)
+ movdqa %xmm0, (rp)
+ lea 128(rp), rp
+
+IFDOS(` movdqa (%rsp), %xmm6 ')
+IFDOS(` movdqa 16(%rsp), %xmm7 ')
+IFDOS(` movdqa 32(%rsp), %xmm8 ')
+IFDOS(` add $56, %rsp ')
+
+L(ued0):test $8, R8(n)
+ jz 1f
+ movaps 56(up), %xmm3
+ movaps 40(up), %xmm2
+ movaps 24(up), %xmm1
+ movaps 8(up), %xmm0
+ movaps -8(up), %xmm4
+ palignr($8, %xmm2, %xmm3)
+ movdqa %xmm3, 48(rp)
+ palignr($8, %xmm1, %xmm2)
+ movdqa %xmm2, 32(rp)
+ palignr($8, %xmm0, %xmm1)
+ movdqa %xmm1, 16(rp)
+ palignr($8, %xmm4, %xmm0)
+ lea 64(up), up
+ movdqa %xmm0, (rp)
+ lea 64(rp), rp
+
+1: test $4, R8(n)
+ jz 1f
+ movaps 24(up), %xmm1
+ movaps 8(up), %xmm0
+ palignr($8, %xmm0, %xmm1)
+ movaps -8(up), %xmm3
+ movdqa %xmm1, 16(rp)
+ palignr($8, %xmm3, %xmm0)
+ lea 32(up), up
+ movdqa %xmm0, (rp)
+ lea 32(rp), rp
+
+1: test $2, R8(n)
+ jz 1f
+ movdqa 8(up), %xmm0
+ movdqa -8(up), %xmm3
+ palignr($8, %xmm3, %xmm0)
+ lea 16(up), up
+ movdqa %xmm0, (rp)
+ lea 16(rp), rp
+
+1: test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov %r8, (rp)
+
+1: FUNC_EXIT()
+ ret
+
+C Basecase code. Needed for good small operands speed, not for
+C correctness as the above code is currently written.
+
+L(bc): lea -8(rp), rp
+ sub $4, R32(n)
+ jc L(end)
+
+ ALIGN(16)
+L(top): mov (up), %r8
+ mov 8(up), %r9
+ lea 32(rp), rp
+ mov 16(up), %r10
+ mov 24(up), %r11
+ lea 32(up), up
+ mov %r8, -24(rp)
+ mov %r9, -16(rp)
+ifelse(eval(COPYI_SSE_THRESHOLD >= 8),1,
+` sub $4, R32(n)')
+ mov %r10, -8(rp)
+ mov %r11, (rp)
+ifelse(eval(COPYI_SSE_THRESHOLD >= 8),1,
+` jnc L(top)')
+
+L(end): test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov %r8, 8(rp)
+ lea 8(rp), rp
+ lea 8(up), up
+1: test $2, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov 8(up), %r9
+ mov %r8, 8(rp)
+ mov %r9, 16(rp)
+1: FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/copyi.asm b/gmp/mpn/x86_64/fastsse/copyi.asm
new file mode 100644
index 0000000000..a1a1c231dc
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/copyi.asm
@@ -0,0 +1,166 @@
+dnl AMD64 mpn_copyi optimised for CPUs with fast SSE.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2003, 2005, 2007, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb good for cpu?
+C AMD K8,K9
+C AMD K10 0.85 1.64 Y/N
+C AMD bd1 1.4 1.4 Y
+C AMD bobcat
+C Intel P4 2.3 2.3 Y
+C Intel core2 1.0 1.0
+C Intel NHM 0.5 0.67 Y
+C Intel SBR 0.5 0.75 Y
+C Intel atom
+C VIA nano 1.16 5.16 Y/N
+
+C We try to do as many 16-byte operations as possible. The top-most and
+C bottom-most writes might need 8-byte operations. We can always write using
+C aligned 16-byte operations, we read with both aligned and unaligned 16-byte
+C operations.
+
+C Instead of having separate loops for reading aligned and unaligned, we read
+C using MOVDQU. This seems to work great except for core2; there performance
+C doubles when reading using MOVDQA (for aligned source). It is unclear how to
+C best handle the unaligned case there.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+dnl define(`movdqu', lddqu)
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_copyi)
+ FUNC_ENTRY(3)
+
+ cmp $3, n
+ jc L(bc)
+
+ test $8, R8(rp) C is rp 16-byte aligned?
+ jz L(ali) C jump if rp aligned
+ movsq C copy single limb
+ dec n
+
+ sub $16, n
+ jc L(sma)
+
+ ALIGN(16)
+L(top): movdqu (up), %xmm0
+ movdqu 16(up), %xmm1
+ movdqu 32(up), %xmm2
+ movdqu 48(up), %xmm3
+ movdqu 64(up), %xmm4
+ movdqu 80(up), %xmm5
+ movdqu 96(up), %xmm6
+ movdqu 112(up), %xmm7
+ lea 128(up), up
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ movdqa %xmm2, 32(rp)
+ movdqa %xmm3, 48(rp)
+ movdqa %xmm4, 64(rp)
+ movdqa %xmm5, 80(rp)
+ movdqa %xmm6, 96(rp)
+ movdqa %xmm7, 112(rp)
+ lea 128(rp), rp
+L(ali): sub $16, n
+ jnc L(top)
+
+L(sma): test $8, R8(n)
+ jz 1f
+ movdqu (up), %xmm0
+ movdqu 16(up), %xmm1
+ movdqu 32(up), %xmm2
+ movdqu 48(up), %xmm3
+ lea 64(up), up
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ movdqa %xmm2, 32(rp)
+ movdqa %xmm3, 48(rp)
+ lea 64(rp), rp
+1:
+ test $4, R8(n)
+ jz 1f
+ movdqu (up), %xmm0
+ movdqu 16(up), %xmm1
+ lea 32(up), up
+ movdqa %xmm0, (rp)
+ movdqa %xmm1, 16(rp)
+ lea 32(rp), rp
+1:
+ test $2, R8(n)
+ jz 1f
+ movdqu (up), %xmm0
+ lea 16(up), up
+ movdqa %xmm0, (rp)
+ lea 16(rp), rp
+ ALIGN(16)
+1:
+L(end): test $1, R8(n)
+ jz 1f
+ mov (up), %r8
+ mov %r8, (rp)
+1:
+ FUNC_EXIT()
+ ret
+
+C Basecase code. Needed for good small operands speed, not for
+C correctness as the above code is currently written.
+
+L(bc): sub $2, n
+ jc L(end)
+ ALIGN(16)
+1: mov (up), %rax
+ mov 8(up), %rcx
+ lea 16(up), up
+ mov %rax, (rp)
+ mov %rcx, 8(rp)
+ lea 16(rp), rp
+ sub $2, n
+ jnc 1b
+
+ test $1, R8(n)
+ jz L(ret)
+ mov (up), %rax
+ mov %rax, (rp)
+L(ret): FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/lshift-movdqu2.asm b/gmp/mpn/x86_64/fastsse/lshift-movdqu2.asm
new file mode 100644
index 0000000000..a05e850a1f
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/lshift-movdqu2.asm
@@ -0,0 +1,182 @@
+dnl AMD64 mpn_lshift optimised for CPUs with fast SSE including fast movdqu.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb cycles/limb cycles/limb good
+C aligned unaligned best seen for cpu?
+C AMD K8,K9 3 3 2.35 no, use shl/shr
+C AMD K10 1.5-1.8 1.5-1.8 1.33 yes
+C AMD bd1 1.7-1.9 1.7-1.9 1.33 yes
+C AMD bobcat 3.17 3.17 yes, bad for n < 20
+C Intel P4 4.67 4.67 2.7 no, slow movdqu
+C Intel core2 2.15 2.15 1.25 no, use shld/shrd
+C Intel NHM 1.66 1.66 1.25 no, use shld/shrd
+C Intel SBR 1.3 1.3 1.25 yes, bad for n = 4-6
+C Intel atom 11.7 11.7 4.5 no
+C VIA nano 5.7 5.95 2.0 no, slow movdqu
+
+C We try to do as many aligned 16-byte operations as possible. The top-most
+C and bottom-most writes might need 8-byte operations.
+C
+C This variant rely on fast load movdqu, and uses it even for aligned operands,
+C in order to avoid the need for two separate loops.
+C
+C TODO
+C * Could 2-limb wind-down code be simplified?
+C * Improve basecase code, using shld/shrd for SBR, discrete integer shifts
+C for other affected CPUs.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`ap', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_lshift)
+ FUNC_ENTRY(4)
+ movd R32(%rcx), %xmm4
+ mov $64, R32(%rax)
+ sub R32(%rcx), R32(%rax)
+ movd R32(%rax), %xmm5
+
+ neg R32(%rcx)
+ mov -8(ap,n,8), %rax
+ shr R8(%rcx), %rax
+
+ cmp $3, n
+ jle L(bc)
+
+ lea (rp,n,8), R32(%rcx)
+ test $8, R8(%rcx)
+ jz L(rp_aligned)
+
+C Do one initial limb in order to make rp aligned
+ movq -8(ap,n,8), %xmm0
+ movq -16(ap,n,8), %xmm1
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ movq %xmm0, -8(rp,n,8)
+ dec n
+
+L(rp_aligned):
+ lea 1(n), %r8d
+
+ and $6, R32(%r8)
+ jz L(ba0)
+ cmp $4, R32(%r8)
+ jz L(ba4)
+ jc L(ba2)
+L(ba6): add $-4, n
+ jmp L(i56)
+L(ba0): add $-6, n
+ jmp L(i70)
+L(ba4): add $-2, n
+ jmp L(i34)
+L(ba2): add $-8, n
+ jle L(end)
+
+ ALIGN(16)
+L(top): movdqu 40(ap,n,8), %xmm1
+ movdqu 48(ap,n,8), %xmm0
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ movdqa %xmm0, 48(rp,n,8)
+L(i70):
+ movdqu 24(ap,n,8), %xmm1
+ movdqu 32(ap,n,8), %xmm0
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ movdqa %xmm0, 32(rp,n,8)
+L(i56):
+ movdqu 8(ap,n,8), %xmm1
+ movdqu 16(ap,n,8), %xmm0
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ movdqa %xmm0, 16(rp,n,8)
+L(i34):
+ movdqu -8(ap,n,8), %xmm1
+ movdqu (ap,n,8), %xmm0
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ movdqa %xmm0, (rp,n,8)
+ sub $8, n
+ jg L(top)
+
+L(end): test $1, R8(n)
+ jnz L(end8)
+
+ movdqu (ap), %xmm1
+ pxor %xmm0, %xmm0
+ punpcklqdq %xmm1, %xmm0
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ movdqa %xmm0, (rp)
+ FUNC_EXIT()
+ ret
+
+C Basecase
+ ALIGN(16)
+L(bc): dec R32(n)
+ jz L(end8)
+
+ movq (ap,n,8), %xmm1
+ movq -8(ap,n,8), %xmm0
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ movq %xmm0, (rp,n,8)
+ sub $2, R32(n)
+ jl L(end8)
+ movq 8(ap), %xmm1
+ movq (ap), %xmm0
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ movq %xmm0, 8(rp)
+
+L(end8):movq (ap), %xmm0
+ psllq %xmm4, %xmm0
+ movq %xmm0, (rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/lshift.asm b/gmp/mpn/x86_64/fastsse/lshift.asm
new file mode 100644
index 0000000000..f76972a22f
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/lshift.asm
@@ -0,0 +1,169 @@
+dnl AMD64 mpn_lshift optimised for CPUs with fast SSE.
+
+dnl Contributed to the GNU project by David Harvey and Torbjorn Granlund.
+
+dnl Copyright 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb cycles/limb good
+C 16-byte aligned 16-byte unaligned for cpu?
+C AMD K8,K9 ? ?
+C AMD K10 1.68 (1.45) 1.75 (1.49) Y
+C AMD bd1 1.82 (1.75) 1.82 (1.75) Y
+C AMD bobcat 4 4
+C Intel P4 3 (2.7) 3 (2.7) Y
+C Intel core2 2.05 (1.67) 2.55 (1.75)
+C Intel NHM 2.05 (1.75) 2.09 (2)
+C Intel SBR 1.5 (1.3125) 1.5 (1.4375) Y
+C Intel atom ? ?
+C VIA nano 2.25 (2) 2.5 (2) Y
+
+C We try to do as many 16-byte operations as possible. The top-most and
+C bottom-most writes might need 8-byte operations.
+
+C There are two inner-loops, one for when rp = ap (mod 16) and one when this is
+C not true. The aligned case reads 16+8 bytes, the unaligned case reads
+C 16+8+X bytes, where X is 8 or 16 depending on how punpcklqdq is implemented.
+
+C This is not yet great code:
+C (1) The unaligned case makes many reads.
+C (2) We should do some unrolling, at least 2-way.
+C With 2-way unrolling but no scheduling we reach 1.5 c/l on K10 and 2 c/l on
+C Nano.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`ap', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_lshift)
+ movd R32(%rcx), %xmm4
+ mov $64, R32(%rax)
+ sub R32(%rcx), R32(%rax)
+ movd R32(%rax), %xmm5
+
+ neg R32(%rcx)
+ mov -8(ap,n,8), %rax
+ shr R8(%rcx), %rax
+
+ cmp $2, n
+ jle L(le2)
+
+ lea (rp,n,8), R32(%rcx)
+ test $8, R8(%rcx)
+ je L(rp_aligned)
+
+C Do one initial limb in order to make rp aligned
+ movq -8(ap,n,8), %xmm0
+ movq -16(ap,n,8), %xmm1
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ movq %xmm0, -8(rp,n,8)
+ dec n
+
+L(rp_aligned):
+ lea (ap,n,8), R32(%rcx)
+ test $8, R8(%rcx)
+ je L(aent)
+ jmp L(uent)
+C *****************************************************************************
+
+C Handle the case when ap != rp (mod 16).
+
+ ALIGN(16)
+L(utop):movdqa -8(ap,n,8), %xmm0
+ movq (ap,n,8), %xmm1
+ punpcklqdq 8(ap,n,8), %xmm1
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ movdqa %xmm0, (rp,n,8)
+L(uent):sub $2, n
+ ja L(utop)
+
+ jne L(end8)
+
+ movq (ap), %xmm1
+ pxor %xmm0, %xmm0
+ punpcklqdq %xmm1, %xmm0
+ punpcklqdq 8(ap), %xmm1
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ movdqa %xmm0, (rp)
+ ret
+C *****************************************************************************
+
+C Handle the case when ap = rp (mod 16).
+
+ ALIGN(16)
+L(atop):movdqa (ap,n,8), %xmm0 C xmm0 = B*ap[n-1] + ap[n-2]
+ movq -8(ap,n,8), %xmm1 C xmm1 = ap[n-3]
+ punpcklqdq %xmm0, %xmm1 C xmm1 = B*ap[n-2] + ap[n-3]
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ movdqa %xmm0, (rp,n,8)
+L(aent):
+ sub $2, n
+ ja L(atop)
+ jne L(end8)
+
+ movdqa (ap), %xmm1
+ pxor %xmm0, %xmm0
+ punpcklqdq %xmm1, %xmm0
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ movdqa %xmm0, (rp)
+ ret
+C *****************************************************************************
+
+ ALIGN(16)
+L(le2): jne L(end8)
+
+ movq 8(ap), %xmm0
+ movq (ap), %xmm1
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ movq %xmm0, 8(rp)
+
+L(end8):movq (ap), %xmm0
+ psllq %xmm4, %xmm0
+ movq %xmm0, (rp)
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/lshiftc-movdqu2.asm b/gmp/mpn/x86_64/fastsse/lshiftc-movdqu2.asm
new file mode 100644
index 0000000000..8250910c52
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/lshiftc-movdqu2.asm
@@ -0,0 +1,193 @@
+dnl AMD64 mpn_lshiftc optimised for CPUs with fast SSE including fast movdqu.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb cycles/limb cycles/limb good
+C aligned unaligned best seen for cpu?
+C AMD K8,K9 3 3 ? no, use shl/shr
+C AMD K10 1.8-2.0 1.8-2.0 ? yes
+C AMD bd1 1.9 1.9 ? yes
+C AMD bobcat 3.67 3.67 yes, bad for n < 20
+C Intel P4 4.75 4.75 ? no, slow movdqu
+C Intel core2 2.27 2.27 ? no, use shld/shrd
+C Intel NHM 2.15 2.15 ? no, use shld/shrd
+C Intel SBR 1.45 1.45 ? yes, bad for n = 4-6
+C Intel atom 12.9 12.9 ? no
+C VIA nano 6.18 6.44 ? no, slow movdqu
+
+C We try to do as many aligned 16-byte operations as possible. The top-most
+C and bottom-most writes might need 8-byte operations.
+C
+C This variant rely on fast load movdqu, and uses it even for aligned operands,
+C in order to avoid the need for two separate loops.
+C
+C TODO
+C * Could 2-limb wind-down code be simplified?
+C * Improve basecase code, using shld/shrd for SBR, discrete integer shifts
+C for other affected CPUs.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`ap', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_lshiftc)
+ FUNC_ENTRY(4)
+ movd R32(%rcx), %xmm4
+ mov $64, R32(%rax)
+ sub R32(%rcx), R32(%rax)
+ movd R32(%rax), %xmm5
+
+ neg R32(%rcx)
+ mov -8(ap,n,8), %rax
+ shr R8(%rcx), %rax
+
+ pcmpeqb %xmm3, %xmm3 C set to 111...111
+
+ cmp $3, n
+ jle L(bc)
+
+ lea (rp,n,8), R32(%rcx)
+ test $8, R8(%rcx)
+ jz L(rp_aligned)
+
+C Do one initial limb in order to make rp aligned
+ movq -8(ap,n,8), %xmm0
+ movq -16(ap,n,8), %xmm1
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ pxor %xmm3, %xmm0
+ movq %xmm0, -8(rp,n,8)
+ dec n
+
+L(rp_aligned):
+ lea 1(n), %r8d
+
+ and $6, R32(%r8)
+ jz L(ba0)
+ cmp $4, R32(%r8)
+ jz L(ba4)
+ jc L(ba2)
+L(ba6): add $-4, n
+ jmp L(i56)
+L(ba0): add $-6, n
+ jmp L(i70)
+L(ba4): add $-2, n
+ jmp L(i34)
+L(ba2): add $-8, n
+ jle L(end)
+
+ ALIGN(16)
+L(top): movdqu 40(ap,n,8), %xmm1
+ movdqu 48(ap,n,8), %xmm0
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ pxor %xmm3, %xmm0
+ movdqa %xmm0, 48(rp,n,8)
+L(i70):
+ movdqu 24(ap,n,8), %xmm1
+ movdqu 32(ap,n,8), %xmm0
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ pxor %xmm3, %xmm0
+ movdqa %xmm0, 32(rp,n,8)
+L(i56):
+ movdqu 8(ap,n,8), %xmm1
+ movdqu 16(ap,n,8), %xmm0
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ pxor %xmm3, %xmm0
+ movdqa %xmm0, 16(rp,n,8)
+L(i34):
+ movdqu -8(ap,n,8), %xmm1
+ movdqu (ap,n,8), %xmm0
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ pxor %xmm3, %xmm0
+ movdqa %xmm0, (rp,n,8)
+ sub $8, n
+ jg L(top)
+
+L(end): test $1, R8(n)
+ jnz L(end8)
+
+ movdqu (ap), %xmm1
+ pxor %xmm0, %xmm0
+ punpcklqdq %xmm1, %xmm0
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ pxor %xmm3, %xmm0
+ movdqa %xmm0, (rp)
+ FUNC_EXIT()
+ ret
+
+C Basecase
+ ALIGN(16)
+L(bc): dec R32(n)
+ jz L(end8)
+
+ movq (ap,n,8), %xmm1
+ movq -8(ap,n,8), %xmm0
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ pxor %xmm3, %xmm0
+ movq %xmm0, (rp,n,8)
+ sub $2, R32(n)
+ jl L(end8)
+ movq 8(ap), %xmm1
+ movq (ap), %xmm0
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ pxor %xmm3, %xmm0
+ movq %xmm0, 8(rp)
+
+L(end8):movq (ap), %xmm0
+ psllq %xmm4, %xmm0
+ pxor %xmm3, %xmm0
+ movq %xmm0, (rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/lshiftc.asm b/gmp/mpn/x86_64/fastsse/lshiftc.asm
new file mode 100644
index 0000000000..d2520690e2
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/lshiftc.asm
@@ -0,0 +1,179 @@
+dnl AMD64 mpn_lshiftc optimised for CPUs with fast SSE.
+
+dnl Contributed to the GNU project by David Harvey and Torbjorn Granlund.
+
+dnl Copyright 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb cycles/limb good
+C 16-byte aligned 16-byte unaligned for cpu?
+C AMD K8,K9 ? ?
+C AMD K10 1.85 (1.635) 1.9 (1.67) Y
+C AMD bd1 1.82 (1.75) 1.82 (1.75) Y
+C AMD bobcat 4.5 4.5
+C Intel P4 3.6 (3.125) 3.6 (3.125) Y
+C Intel core2 2.05 (1.67) 2.55 (1.75)
+C Intel NHM 2.05 (1.875) 2.6 (2.25)
+C Intel SBR 1.55 (1.44) 2 (1.57) Y
+C Intel atom ? ?
+C VIA nano 2.5 (2.5) 2.5 (2.5) Y
+
+C We try to do as many 16-byte operations as possible. The top-most and
+C bottom-most writes might need 8-byte operations. We always write using
+C 16-byte operations, we read with both 8-byte and 16-byte operations.
+
+C There are two inner-loops, one for when rp = ap (mod 16) and one when this is
+C not true. The aligned case reads 16+8 bytes, the unaligned case reads
+C 16+8+X bytes, where X is 8 or 16 depending on how punpcklqdq is implemented.
+
+C This is not yet great code:
+C (1) The unaligned case makes too many reads.
+C (2) We should do some unrolling, at least 2-way.
+C With 2-way unrolling but no scheduling we reach 1.5 c/l on K10 and 2 c/l on
+C Nano.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`ap', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_lshiftc)
+ movd R32(%rcx), %xmm4
+ mov $64, R32(%rax)
+ sub R32(%rcx), R32(%rax)
+ movd R32(%rax), %xmm5
+
+ neg R32(%rcx)
+ mov -8(ap,n,8), %rax
+ shr R8(%rcx), %rax
+
+ pcmpeqb %xmm7, %xmm7 C set to 111...111
+
+ cmp $2, n
+ jle L(le2)
+
+ lea (rp,n,8), R32(%rcx)
+ test $8, R8(%rcx)
+ je L(rp_aligned)
+
+C Do one initial limb in order to make rp aligned
+ movq -8(ap,n,8), %xmm0
+ movq -16(ap,n,8), %xmm1
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ pxor %xmm7, %xmm0
+ movq %xmm0, -8(rp,n,8)
+ dec n
+
+L(rp_aligned):
+ lea (ap,n,8), R32(%rcx)
+ test $8, R8(%rcx)
+ je L(aent)
+ jmp L(uent)
+C *****************************************************************************
+
+C Handle the case when ap != rp (mod 16).
+
+ ALIGN(16)
+L(utop):movq (ap,n,8), %xmm1
+ punpcklqdq 8(ap,n,8), %xmm1
+ movdqa -8(ap,n,8), %xmm0
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, (rp,n,8)
+L(uent):sub $2, n
+ ja L(utop)
+
+ jne L(end8)
+
+ movq (ap), %xmm1
+ pxor %xmm0, %xmm0
+ punpcklqdq %xmm1, %xmm0
+ punpcklqdq 8(ap), %xmm1
+ psllq %xmm4, %xmm1
+ psrlq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, (rp)
+ ret
+C *****************************************************************************
+
+C Handle the case when ap = rp (mod 16).
+
+ ALIGN(16)
+L(atop):movdqa (ap,n,8), %xmm0 C xmm0 = B*ap[n-1] + ap[n-2]
+ movq -8(ap,n,8), %xmm1 C xmm1 = ap[n-3]
+ punpcklqdq %xmm0, %xmm1 C xmm1 = B*ap[n-2] + ap[n-3]
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, (rp,n,8)
+L(aent):sub $2, n
+ ja L(atop)
+
+ jne L(end8)
+
+ movdqa (ap), %xmm0
+ pxor %xmm1, %xmm1
+ punpcklqdq %xmm0, %xmm1
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ pxor %xmm7, %xmm0
+ movdqa %xmm0, (rp)
+ ret
+C *****************************************************************************
+
+ ALIGN(16)
+L(le2): jne L(end8)
+
+ movq 8(ap), %xmm0
+ movq (ap), %xmm1
+ psllq %xmm4, %xmm0
+ psrlq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ pxor %xmm7, %xmm0
+ movq %xmm0, 8(rp)
+
+L(end8):movq (ap), %xmm0
+ psllq %xmm4, %xmm0
+ pxor %xmm7, %xmm0
+ movq %xmm0, (rp)
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/rshift-movdqu2.asm b/gmp/mpn/x86_64/fastsse/rshift-movdqu2.asm
new file mode 100644
index 0000000000..1e270b13c3
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/rshift-movdqu2.asm
@@ -0,0 +1,201 @@
+dnl AMD64 mpn_rshift optimised for CPUs with fast SSE including fast movdqu.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb cycles/limb cycles/limb good
+C aligned unaligned best seen for cpu?
+C AMD K8,K9 3 3 2.35 no, use shl/shr
+C AMD K10 1.5-1.8 1.5-1.8 1.33 yes
+C AMD bd1 1.7-1.9 1.7-1.9 1.33 yes
+C AMD bobcat 3.17 3.17 yes, bad for n < 20
+C Intel P4 4.67 4.67 2.7 no, slow movdqu
+C Intel core2 2.15 2.15 1.25 no, use shld/shrd
+C Intel NHM 1.66 1.66 1.25 no, use shld/shrd
+C Intel SBR 1.3 1.3 1.25 yes, bad for n = 4-6
+C Intel atom 11.7 11.7 4.5 no
+C VIA nano 5.7 5.95 2.0 no, slow movdqu
+
+C We try to do as many aligned 16-byte operations as possible. The top-most
+C and bottom-most writes might need 8-byte operations.
+C
+C This variant rely on fast load movdqu, and uses it even for aligned operands,
+C in order to avoid the need for two separate loops.
+C
+C TODO
+C * Could 2-limb wind-down code be simplified?
+C * Improve basecase code, using shld/shrd for SBR, discrete integer shifts
+C for other affected CPUs.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`ap', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ASM_START()
+ TEXT
+ ALIGN(64)
+PROLOGUE(mpn_rshift)
+ FUNC_ENTRY(4)
+ movd R32(%rcx), %xmm4
+ mov $64, R32(%rax)
+ sub R32(%rcx), R32(%rax)
+ movd R32(%rax), %xmm5
+
+ neg R32(%rcx)
+ mov (ap), %rax
+ shl R8(%rcx), %rax
+
+ cmp $3, n
+ jle L(bc)
+
+ test $8, R8(rp)
+ jz L(rp_aligned)
+
+C Do one initial limb in order to make rp aligned
+ movq (ap), %xmm0
+ movq 8(ap), %xmm1
+ psrlq %xmm4, %xmm0
+ psllq %xmm5, %xmm1
+ por %xmm1, %xmm0
+ movq %xmm0, (rp)
+ lea 8(ap), ap
+ lea 8(rp), rp
+ dec n
+
+L(rp_aligned):
+ lea 1(n), %r8d
+ lea (ap,n,8), ap
+ lea (rp,n,8), rp
+ neg n
+
+ and $6, R32(%r8)
+ jz L(bu0)
+ cmp $4, R32(%r8)
+ jz L(bu4)
+ jc L(bu2)
+L(bu6): add $4, n
+ jmp L(i56)
+L(bu0): add $6, n
+ jmp L(i70)
+L(bu4): add $2, n
+ jmp L(i34)
+L(bu2): add $8, n
+ jge L(end)
+
+ ALIGN(16)
+L(top): movdqu -64(ap,n,8), %xmm1
+ movdqu -56(ap,n,8), %xmm0
+ psllq %xmm5, %xmm0
+ psrlq %xmm4, %xmm1
+ por %xmm1, %xmm0
+ movdqa %xmm0, -64(rp,n,8)
+L(i70):
+ movdqu -48(ap,n,8), %xmm1
+ movdqu -40(ap,n,8), %xmm0
+ psllq %xmm5, %xmm0
+ psrlq %xmm4, %xmm1
+ por %xmm1, %xmm0
+ movdqa %xmm0, -48(rp,n,8)
+L(i56):
+ movdqu -32(ap,n,8), %xmm1
+ movdqu -24(ap,n,8), %xmm0
+ psllq %xmm5, %xmm0
+ psrlq %xmm4, %xmm1
+ por %xmm1, %xmm0
+ movdqa %xmm0, -32(rp,n,8)
+L(i34):
+ movdqu -16(ap,n,8), %xmm1
+ movdqu -8(ap,n,8), %xmm0
+ psllq %xmm5, %xmm0
+ psrlq %xmm4, %xmm1
+ por %xmm1, %xmm0
+ movdqa %xmm0, -16(rp,n,8)
+ add $8, n
+ jl L(top)
+
+L(end): test $1, R8(n)
+ jnz L(e1)
+
+ movdqu -16(ap), %xmm1
+ movq -8(ap), %xmm0
+ psrlq %xmm4, %xmm1
+ psllq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ movdqa %xmm0, -16(rp)
+ FUNC_EXIT()
+ ret
+
+L(e1): movq -8(ap), %xmm0
+ psrlq %xmm4, %xmm0
+ movq %xmm0, -8(rp)
+ FUNC_EXIT()
+ ret
+
+C Basecase
+ ALIGN(16)
+L(bc): dec R32(n)
+ jnz 1f
+ movq (ap), %xmm0
+ psrlq %xmm4, %xmm0
+ movq %xmm0, (rp)
+ FUNC_EXIT()
+ ret
+
+1: movq (ap), %xmm1
+ movq 8(ap), %xmm0
+ psrlq %xmm4, %xmm1
+ psllq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ movq %xmm0, (rp)
+ dec R32(n)
+ jnz 1f
+ movq 8(ap), %xmm0
+ psrlq %xmm4, %xmm0
+ movq %xmm0, 8(rp)
+ FUNC_EXIT()
+ ret
+
+1: movq 8(ap), %xmm1
+ movq 16(ap), %xmm0
+ psrlq %xmm4, %xmm1
+ psllq %xmm5, %xmm0
+ por %xmm1, %xmm0
+ movq %xmm0, 8(rp)
+ movq 16(ap), %xmm0
+ psrlq %xmm4, %xmm0
+ movq %xmm0, 16(rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fastsse/sec_tabselect.asm b/gmp/mpn/x86_64/fastsse/sec_tabselect.asm
new file mode 100644
index 0000000000..e3df110be4
--- /dev/null
+++ b/gmp/mpn/x86_64/fastsse/sec_tabselect.asm
@@ -0,0 +1,192 @@
+dnl AMD64 SSE mpn_sec_tabselect.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb cycles/limb cycles/limb
+C ali,evn n unal,evn n other cases
+C AMD K8,K9 1.65 1.65 1.8
+C AMD K10 0.78 0.78 0.85
+C AMD bd1 0.80 0.91 1.25
+C AMD bobcat 2.15 2.15 2.37
+C Intel P4 2.5 2.5 2.95
+C Intel core2 1.17 1.25 1.25
+C Intel NHM 0.87 0.90 0.90
+C Intel SBR 0.63 0.79 0.77
+C Intel atom 4.3 4.3 4.3 slower than plain code
+C VIA nano 1.4 5.1 3.14 too alignment dependent
+
+C NOTES
+C * We only honour the least significant 32 bits of the `which' and `nents'
+C arguments to allow efficient code using just SSE2. We would need to
+C either use the SSE4_1 pcmpeqq, or find some other SSE2 sequence.
+C * We use movd for copying between xmm and plain registers, since old gas
+C rejects movq. But gas assembles movd as movq when given a 64-bit greg.
+
+define(`rp', `%rdi')
+define(`tp', `%rsi')
+define(`n', `%rdx')
+define(`nents', `%rcx')
+define(`which', `%r8')
+
+define(`i', `%r10')
+define(`j', `%r9')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+C nents n rp tab which j i temp * * * *
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sec_tabselect)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+
+ movd which, %xmm8
+ pshufd $0, %xmm8, %xmm8 C 4 `which' copies
+ mov $1, R32(%rax)
+ movd %rax, %xmm9
+ pshufd $0, %xmm9, %xmm9 C 4 copies of 1
+
+ mov n, j
+ add $-8, j
+ js L(outer_end)
+
+L(outer_top):
+ mov nents, i
+ mov tp, %r11
+ pxor %xmm13, %xmm13
+ pxor %xmm4, %xmm4
+ pxor %xmm5, %xmm5
+ pxor %xmm6, %xmm6
+ pxor %xmm7, %xmm7
+ ALIGN(16)
+L(top): movdqa %xmm8, %xmm0
+ pcmpeqd %xmm13, %xmm0
+ paddd %xmm9, %xmm13
+ movdqu 0(tp), %xmm2
+ movdqu 16(tp), %xmm3
+ pand %xmm0, %xmm2
+ pand %xmm0, %xmm3
+ por %xmm2, %xmm4
+ por %xmm3, %xmm5
+ movdqu 32(tp), %xmm2
+ movdqu 48(tp), %xmm3
+ pand %xmm0, %xmm2
+ pand %xmm0, %xmm3
+ por %xmm2, %xmm6
+ por %xmm3, %xmm7
+ lea (tp,n,8), tp
+ add $-1, i
+ jne L(top)
+
+ movdqu %xmm4, 0(rp)
+ movdqu %xmm5, 16(rp)
+ movdqu %xmm6, 32(rp)
+ movdqu %xmm7, 48(rp)
+
+ lea 64(%r11), tp
+ lea 64(rp), rp
+ add $-8, j
+ jns L(outer_top)
+L(outer_end):
+
+ test $4, R8(n)
+ je L(b0xx)
+L(b1xx):mov nents, i
+ mov tp, %r11
+ pxor %xmm13, %xmm13
+ pxor %xmm4, %xmm4
+ pxor %xmm5, %xmm5
+ ALIGN(16)
+L(tp4): movdqa %xmm8, %xmm0
+ pcmpeqd %xmm13, %xmm0
+ paddd %xmm9, %xmm13
+ movdqu 0(tp), %xmm2
+ movdqu 16(tp), %xmm3
+ pand %xmm0, %xmm2
+ pand %xmm0, %xmm3
+ por %xmm2, %xmm4
+ por %xmm3, %xmm5
+ lea (tp,n,8), tp
+ add $-1, i
+ jne L(tp4)
+ movdqu %xmm4, 0(rp)
+ movdqu %xmm5, 16(rp)
+ lea 32(%r11), tp
+ lea 32(rp), rp
+
+L(b0xx):test $2, R8(n)
+ je L(b00x)
+L(b01x):mov nents, i
+ mov tp, %r11
+ pxor %xmm13, %xmm13
+ pxor %xmm4, %xmm4
+ ALIGN(16)
+L(tp2): movdqa %xmm8, %xmm0
+ pcmpeqd %xmm13, %xmm0
+ paddd %xmm9, %xmm13
+ movdqu 0(tp), %xmm2
+ pand %xmm0, %xmm2
+ por %xmm2, %xmm4
+ lea (tp,n,8), tp
+ add $-1, i
+ jne L(tp2)
+ movdqu %xmm4, 0(rp)
+ lea 16(%r11), tp
+ lea 16(rp), rp
+
+L(b00x):test $1, R8(n)
+ je L(b000)
+L(b001):mov nents, i
+ mov tp, %r11
+ pxor %xmm13, %xmm13
+ pxor %xmm4, %xmm4
+ ALIGN(16)
+L(tp1): movdqa %xmm8, %xmm0
+ pcmpeqd %xmm13, %xmm0
+ paddd %xmm9, %xmm13
+ movq 0(tp), %xmm2
+ pand %xmm0, %xmm2
+ por %xmm2, %xmm4
+ lea (tp,n,8), tp
+ add $-1, i
+ jne L(tp1)
+ movq %xmm4, 0(rp)
+
+L(b000):FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fat/fat.c b/gmp/mpn/x86_64/fat/fat.c
new file mode 100644
index 0000000000..1b3f4e48be
--- /dev/null
+++ b/gmp/mpn/x86_64/fat/fat.c
@@ -0,0 +1,368 @@
+/* x86_64 fat binary initializers.
+
+ Contributed to the GNU project by Kevin Ryde (original x86_32 code) and
+ Torbjorn Granlund (port to x86_64)
+
+ THE FUNCTIONS AND VARIABLES IN THIS FILE ARE FOR INTERNAL USE ONLY.
+ THEY'RE ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR
+ COMPLETELY IN FUTURE GNU MP RELEASES.
+
+Copyright 2003, 2004, 2009, 2011-2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for printf */
+#include <stdlib.h> /* for getenv */
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Change this to "#define TRACE(x) x" for some traces. */
+#define TRACE(x)
+
+
+/* fat_entry.asm */
+long __gmpn_cpuid (char [12], int);
+
+
+#if WANT_FAKE_CPUID
+/* The "name"s in the table are values for the GMP_CPU_TYPE environment
+ variable. Anything can be used, but for now it's the canonical cpu types
+ as per config.guess/config.sub. */
+
+#define __gmpn_cpuid fake_cpuid
+
+#define MAKE_FMS(family, model) \
+ ((((family) & 0xf) << 8) + (((family) & 0xff0) << 20) \
+ + (((model) & 0xf) << 4) + (((model) & 0xf0) << 12))
+
+static struct {
+ const char *name;
+ const char vendor[13];
+ unsigned fms;
+} fake_cpuid_table[] = {
+ { "core2", "GenuineIntel", MAKE_FMS (6, 0xf) },
+ { "coreinhm", "GenuineIntel", MAKE_FMS (6, 0x1a) },
+ { "coreiwsm", "GenuineIntel", MAKE_FMS (6, 0x25) },
+ { "coreisbr", "GenuineIntel", MAKE_FMS (6, 0x2a) },
+ { "coreihwl", "GenuineIntel", MAKE_FMS (6, 0x3c) },
+ { "atom", "GenuineIntel", MAKE_FMS (6, 0x1c) },
+ { "pentium4", "GenuineIntel", MAKE_FMS (15, 3) },
+
+ { "k8", "AuthenticAMD", MAKE_FMS (15, 0) },
+ { "k10", "AuthenticAMD", MAKE_FMS (16, 0) },
+ { "bobcat", "AuthenticAMD", MAKE_FMS (20, 1) },
+ { "bulldozer", "AuthenticAMD", MAKE_FMS (21, 1) },
+ { "piledriver", "AuthenticAMD", MAKE_FMS (21, 2) },
+ { "steamroller","AuthenticAMD", MAKE_FMS (21, 0x30) },
+ { "excavator", "AuthenticAMD", MAKE_FMS (21, 0x60) },
+ { "jaguar", "AuthenticAMD", MAKE_FMS (22, 1) },
+
+ { "nano", "CentaurHauls", MAKE_FMS (6, 15) },
+};
+
+static int
+fake_cpuid_lookup (void)
+{
+ char *s;
+ int i;
+
+ s = getenv ("GMP_CPU_TYPE");
+ if (s == NULL)
+ {
+ printf ("Need GMP_CPU_TYPE environment variable for fake cpuid\n");
+ abort ();
+ }
+
+ for (i = 0; i < numberof (fake_cpuid_table); i++)
+ if (strcmp (s, fake_cpuid_table[i].name) == 0)
+ return i;
+
+ printf ("GMP_CPU_TYPE=%s unknown\n", s);
+ abort ();
+}
+
+static long
+fake_cpuid (char dst[12], unsigned int id)
+{
+ int i = fake_cpuid_lookup();
+
+ switch (id) {
+ case 0:
+ memcpy (dst, fake_cpuid_table[i].vendor, 12);
+ return 0;
+ case 1:
+ return fake_cpuid_table[i].fms;
+ case 7:
+ dst[0] = 0xff; /* BMI1, AVX2, etc */
+ dst[1] = 0xff; /* BMI2, etc */
+ return 0;
+ case 0x80000001:
+ dst[4 + 29 / 8] = (1 << (29 % 8)); /* "long" mode */
+ return 0;
+ default:
+ printf ("fake_cpuid(): oops, unknown id %d\n", id);
+ abort ();
+ }
+}
+#endif
+
+
+typedef DECL_preinv_divrem_1 ((*preinv_divrem_1_t));
+typedef DECL_preinv_mod_1 ((*preinv_mod_1_t));
+
+struct cpuvec_t __gmpn_cpuvec = {
+ __MPN(add_n_init),
+ __MPN(addlsh1_n_init),
+ __MPN(addlsh2_n_init),
+ __MPN(addmul_1_init),
+ __MPN(addmul_2_init),
+ __MPN(bdiv_dbm1c_init),
+ __MPN(cnd_add_n_init),
+ __MPN(cnd_sub_n_init),
+ __MPN(com_init),
+ __MPN(copyd_init),
+ __MPN(copyi_init),
+ __MPN(divexact_1_init),
+ __MPN(divrem_1_init),
+ __MPN(gcd_1_init),
+ __MPN(lshift_init),
+ __MPN(lshiftc_init),
+ __MPN(mod_1_init),
+ __MPN(mod_1_1p_init),
+ __MPN(mod_1_1p_cps_init),
+ __MPN(mod_1s_2p_init),
+ __MPN(mod_1s_2p_cps_init),
+ __MPN(mod_1s_4p_init),
+ __MPN(mod_1s_4p_cps_init),
+ __MPN(mod_34lsub1_init),
+ __MPN(modexact_1c_odd_init),
+ __MPN(mul_1_init),
+ __MPN(mul_basecase_init),
+ __MPN(mullo_basecase_init),
+ __MPN(preinv_divrem_1_init),
+ __MPN(preinv_mod_1_init),
+ __MPN(redc_1_init),
+ __MPN(redc_2_init),
+ __MPN(rshift_init),
+ __MPN(sqr_basecase_init),
+ __MPN(sub_n_init),
+ __MPN(sublsh1_n_init),
+ __MPN(submul_1_init),
+ 0
+};
+
+int __gmpn_cpuvec_initialized = 0;
+
+/* The following setups start with generic x86, then overwrite with
+ specifics for a chip, and higher versions of that chip.
+
+ The arrangement of the setups here will normally be the same as the $path
+ selections in configure.in for the respective chips.
+
+ This code is reentrant and thread safe. We always calculate the same
+ decided_cpuvec, so if two copies of the code are running it doesn't
+ matter which completes first, both write the same to __gmpn_cpuvec.
+
+ We need to go via decided_cpuvec because if one thread has completed
+ __gmpn_cpuvec then it may be making use of the threshold values in that
+ vector. If another thread is still running __gmpn_cpuvec_init then we
+ don't want it to write different values to those fields since some of the
+ asm routines only operate correctly up to their own defined threshold,
+ not an arbitrary value. */
+
+void
+__gmpn_cpuvec_init (void)
+{
+ struct cpuvec_t decided_cpuvec;
+ char vendor_string[13];
+ char dummy_string[12];
+ long fms;
+ int family, model;
+
+ TRACE (printf ("__gmpn_cpuvec_init:\n"));
+
+ memset (&decided_cpuvec, '\0', sizeof (decided_cpuvec));
+
+ CPUVEC_SETUP_x86_64;
+ CPUVEC_SETUP_fat;
+
+ __gmpn_cpuid (vendor_string, 0);
+ vendor_string[12] = 0;
+
+ fms = __gmpn_cpuid (dummy_string, 1);
+ family = ((fms >> 8) & 0xf) + ((fms >> 20) & 0xff);
+ model = ((fms >> 4) & 0xf) + ((fms >> 12) & 0xf0);
+
+ /* Check extended feature flags */
+ __gmpn_cpuid (dummy_string, 0x80000001);
+ if ((dummy_string[4 + 29 / 8] & (1 << (29 % 8))) == 0)
+ abort (); /* longmode-capable-bit turned off! */
+
+ /*********************************************************/
+ /*** WARNING: keep this list in sync with config.guess ***/
+ /*********************************************************/
+ if (strcmp (vendor_string, "GenuineIntel") == 0)
+ {
+ switch (family)
+ {
+ case 6:
+ switch (model)
+ {
+ case 0x0f: /* Conroe Merom Kentsfield Allendale */
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17: /* PNR Wolfdale Yorkfield */
+ case 0x18:
+ case 0x19:
+ case 0x1d: /* PNR Dunnington */
+ CPUVEC_SETUP_core2;
+ break;
+
+ case 0x1c: /* Atom Silverthorne */
+ case 0x26: /* Atom Lincroft */
+ case 0x27: /* Atom Saltwell? */
+ case 0x36: /* Atom Cedarview/Saltwell */
+ CPUVEC_SETUP_atom;
+ break;
+
+ case 0x1a: /* NHM Gainestown */
+ case 0x1b:
+ case 0x1e: /* NHM Lynnfield/Jasper */
+ case 0x1f:
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25: /* WSM Clarkdale/Arrandale */
+ case 0x28:
+ case 0x29:
+ case 0x2b:
+ case 0x2c: /* WSM Gulftown */
+ case 0x2e: /* NHM Beckton */
+ case 0x2f: /* WSM Eagleton */
+ case 0x37: /* Atom Silvermont */
+ case 0x4d: /* Atom Silvermont/Avoton */
+ CPUVEC_SETUP_core2;
+ CPUVEC_SETUP_coreinhm;
+ break;
+
+ case 0x2a: /* SB */
+ case 0x2d: /* SBC-EP */
+ case 0x3a: /* IBR */
+ case 0x3e: /* IBR Ivytown */
+ CPUVEC_SETUP_core2;
+ CPUVEC_SETUP_coreinhm;
+ CPUVEC_SETUP_coreisbr;
+ break;
+ case 0x3c: /* Haswell client */
+ case 0x3d: /* Broadwell */
+ case 0x3f: /* Haswell server */
+ case 0x45: /* Haswell ULT */
+ case 0x46: /* Crystal Well */
+ case 0x4f: /* Broadwell server */
+ case 0x56: /* Broadwell microserver */
+ CPUVEC_SETUP_core2;
+ CPUVEC_SETUP_coreinhm;
+ CPUVEC_SETUP_coreisbr;
+ /* Some Haswells lack BMI2. Let them appear as Sandybridges for
+ now. */
+ __gmpn_cpuid (dummy_string, 7);
+ if ((dummy_string[0 + 8 / 8] & (1 << (8 % 8))) != 0)
+ CPUVEC_SETUP_coreihwl;
+ break;
+ }
+ break;
+
+ case 15:
+ CPUVEC_SETUP_pentium4;
+ break;
+ }
+ }
+ else if (strcmp (vendor_string, "AuthenticAMD") == 0)
+ {
+ switch (family)
+ {
+ case 0x0f: /* k8 */
+ case 0x11: /* "fam 11h", mix of k8 and k10 */
+ case 0x13:
+ case 0x17:
+ CPUVEC_SETUP_k8;
+ break;
+
+ case 0x10: /* k10 */
+ case 0x12: /* k10 (llano) */
+ CPUVEC_SETUP_k8;
+ CPUVEC_SETUP_k10;
+ break;
+
+ case 0x14: /* bobcat */
+ case 0x16: /* jaguar */
+ CPUVEC_SETUP_k8;
+ CPUVEC_SETUP_k10;
+ CPUVEC_SETUP_bobcat;
+ break;
+
+ case 0x15: /* bulldozer, piledriver, steamroller, excavator */
+ CPUVEC_SETUP_k8;
+ CPUVEC_SETUP_k10;
+ CPUVEC_SETUP_bd1;
+ }
+ }
+ else if (strcmp (vendor_string, "CentaurHauls") == 0)
+ {
+ switch (family)
+ {
+ case 6:
+ if (model >= 15)
+ CPUVEC_SETUP_nano;
+ break;
+ }
+ }
+
+ /* There's no x86 generic mpn_preinv_divrem_1 or mpn_preinv_mod_1.
+ Instead default to the plain versions from whichever CPU we detected.
+ The function arguments are compatible, no need for any glue code. */
+ if (decided_cpuvec.preinv_divrem_1 == NULL)
+ decided_cpuvec.preinv_divrem_1 =(preinv_divrem_1_t)decided_cpuvec.divrem_1;
+ if (decided_cpuvec.preinv_mod_1 == NULL)
+ decided_cpuvec.preinv_mod_1 =(preinv_mod_1_t) decided_cpuvec.mod_1;
+
+ ASSERT_CPUVEC (decided_cpuvec);
+ CPUVEC_INSTALL (decided_cpuvec);
+
+ /* Set this once the threshold fields are ready.
+ Use volatile to prevent it getting moved. */
+ *((volatile int *) &__gmpn_cpuvec_initialized) = 1;
+}
diff --git a/gmp/mpn/x86_64/fat/fat_entry.asm b/gmp/mpn/x86_64/fat/fat_entry.asm
new file mode 100644
index 0000000000..764e3d82f2
--- /dev/null
+++ b/gmp/mpn/x86_64/fat/fat_entry.asm
@@ -0,0 +1,204 @@
+dnl x86 fat binary entrypoints.
+
+dnl Contributed to the GNU project by Kevin Ryde (original x86_32 code) and
+dnl Torbjorn Granlund (port to x86_64)
+
+dnl Copyright 2003, 2009, 2011-2014 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+dnl Forcibly disable profiling.
+dnl
+dnl The entrypoints and inits are small enough not to worry about, the real
+dnl routines arrived at will have any profiling. Also, the way the code
+dnl here ends with a jump means we won't work properly with the
+dnl "instrument" profiling scheme anyway.
+
+define(`WANT_PROFILING',no)
+
+
+dnl We define PRETEND_PIC as a helper symbol, the use it for suppressing
+dnl normal, fast call code, since that triggers problems on Darwin and
+dnl OpenBSD.
+
+ifdef(`DARWIN',
+`define(`PRETEND_PIC')')
+ifdef(`OPENBSD',
+`define(`PRETEND_PIC')')
+ifdef(`PIC',
+`define(`PRETEND_PIC')')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ TEXT
+
+dnl Usage: FAT_ENTRY(name, offset)
+dnl
+dnl Emit a fat binary entrypoint function of the given name. This is the
+dnl normal entry for applications, eg. __gmpn_add_n.
+dnl
+dnl The code simply jumps through the function pointer in __gmpn_cpuvec at
+dnl the given "offset" (in bytes).
+dnl
+dnl For non-PIC, the jumps are 5 bytes each, aligning them to 8 should be
+dnl fine for all x86s.
+dnl
+dnl For ELF/DARWIN PIC, the jumps are 20 bytes each, and are best aligned to
+dnl 16 to ensure at least the first two instructions don't cross a cache line
+dnl boundary.
+dnl
+dnl For DOS64, the jumps are 6 bytes. The same form works also for GNU/Linux
+dnl (at least with certain assembler/linkers) but FreeBSD 8.2 crashes. Not
+dnl tested on Darwin, Slowaris, NetBSD, etc.
+dnl
+dnl Note the extra `' ahead of PROLOGUE obscures it from the HAVE_NATIVE
+dnl grepping in configure, stopping that code trying to eval something with
+dnl $1 in it.
+
+define(FAT_ENTRY,
+m4_assert_numargs(2)
+`ifdef(`HOST_DOS64',
+` ALIGN(8)
+`'PROLOGUE($1)
+ jmp *$2+GSYM_PREFIX`'__gmpn_cpuvec(%rip)
+EPILOGUE()
+',
+` ALIGN(ifdef(`PIC',16,8))
+`'PROLOGUE($1)
+ifdef(`PRETEND_PIC',
+` LEA( GSYM_PREFIX`'__gmpn_cpuvec, %rax)
+ jmp *$2(%rax)
+',`dnl non-PIC
+ jmp *GSYM_PREFIX`'__gmpn_cpuvec+$2
+')
+EPILOGUE()
+')')
+
+
+dnl FAT_ENTRY for each CPUVEC_FUNCS_LIST
+dnl
+
+define(`CPUVEC_offset',0)
+foreach(i,
+`FAT_ENTRY(MPN(i),CPUVEC_offset)
+define(`CPUVEC_offset',eval(CPUVEC_offset + 8))',
+CPUVEC_FUNCS_LIST)
+
+
+dnl Usage: FAT_INIT(name, offset)
+dnl
+dnl Emit a fat binary initializer function of the given name. These
+dnl functions are the initial values for the pointers in __gmpn_cpuvec.
+dnl
+dnl The code simply calls __gmpn_cpuvec_init, and then jumps back through
+dnl the __gmpn_cpuvec pointer, at the given "offset" (in bytes).
+dnl __gmpn_cpuvec_init will have stored the address of the selected
+dnl implementation there.
+dnl
+dnl Only one of these routines will be executed, and only once, since after
+dnl that all the __gmpn_cpuvec pointers go to real routines. So there's no
+dnl need for anything special here, just something small and simple. To
+dnl keep code size down, "fat_init" is a shared bit of code, arrived at
+dnl with the offset in %al. %al is used since the movb instruction is 2
+dnl bytes where %eax would be 4.
+dnl
+dnl Note having `PROLOGUE in FAT_INIT obscures that PROLOGUE from the
+dnl HAVE_NATIVE grepping in configure, preventing that code trying to eval
+dnl something with $1 in it.
+dnl
+dnl We need to preserve parameter registers over the __gmpn_cpuvec_init call
+
+define(FAT_INIT,
+m4_assert_numargs(2)
+`PROLOGUE($1)
+ mov $`'$2, %al
+ jmp L(fat_init)
+EPILOGUE()
+')
+
+dnl FAT_INIT for each CPUVEC_FUNCS_LIST
+dnl
+
+define(`CPUVEC_offset',0)
+foreach(i,
+`FAT_INIT(MPN(i`'_init),CPUVEC_offset)
+define(`CPUVEC_offset',eval(CPUVEC_offset + 1))',
+CPUVEC_FUNCS_LIST)
+
+L(fat_init):
+ C al __gmpn_cpuvec byte offset
+
+ movzbl %al, %eax
+IFSTD(` push %rdi ')
+IFSTD(` push %rsi ')
+ push %rdx
+ push %rcx
+ push %r8
+ push %r9
+ push %rax
+ CALL( __gmpn_cpuvec_init)
+ pop %rax
+ pop %r9
+ pop %r8
+ pop %rcx
+ pop %rdx
+IFSTD(` pop %rsi ')
+IFSTD(` pop %rdi ')
+ifdef(`PRETEND_PIC',`
+ LEA( GSYM_PREFIX`'__gmpn_cpuvec, %r10)
+ jmp *(%r10,%rax,8)
+',`dnl non-PIC
+ jmp *GSYM_PREFIX`'__gmpn_cpuvec(,%rax,8)
+')
+
+
+C long __gmpn_cpuid (char dst[12], int id);
+C
+C This is called only 3 times, so just something simple and compact is fine.
+C
+C The rcx/ecx zeroing here is needed for the BMI2 check.
+
+define(`rp', `%rdi')
+define(`idx', `%rsi')
+
+PROLOGUE(__gmpn_cpuid)
+ FUNC_ENTRY(2)
+ mov %rbx, %r8
+ mov R32(idx), R32(%rax)
+ xor %ecx, %ecx
+ cpuid
+ mov %ebx, (rp)
+ mov %edx, 4(rp)
+ mov %ecx, 8(rp)
+ mov %r8, %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/fat/gmp-mparam.h b/gmp/mpn/x86_64/fat/gmp-mparam.h
new file mode 100644
index 0000000000..005c893635
--- /dev/null
+++ b/gmp/mpn/x86_64/fat/gmp-mparam.h
@@ -0,0 +1,72 @@
+/* Fat binary x86_64 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2003, 2009, 2011 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+
+/* mpn_divexact_1 is faster than mpn_divrem_1 at all sizes. The only time
+ this might not be true currently is for actual 80386 and 80486 chips,
+ where mpn/x86/dive_1.asm might be slower than mpn/x86/divrem_1.asm, but
+ that's not worth worrying about. */
+#define DIVEXACT_1_THRESHOLD 0
+
+/* Only some of the x86s have an mpn_preinv_divrem_1, but we set
+ USE_PREINV_DIVREM_1 so that all callers use it, and then let the
+ __gmpn_cpuvec pointer go to plain mpn_divrem_1 if there's not an actual
+ preinv. */
+#define USE_PREINV_DIVREM_1 1
+
+#define BMOD_1_TO_MOD_1_THRESHOLD 20
+
+/* mpn_sqr_basecase is faster than mpn_mul_basecase at all sizes, no need
+ for mpn_sqr to call the latter. */
+#define SQR_BASECASE_THRESHOLD 0
+
+/* Sensible fallbacks for these, when not taken from a cpu-specific
+ gmp-mparam.h. */
+#define MUL_TOOM22_THRESHOLD 20
+#define MUL_TOOM33_THRESHOLD 130
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 200
+
+/* These are values more or less in the middle of what the typical x86 chips
+ come out as. For a fat binary it's necessary to have values for these,
+ since the defaults for MUL_FFT_TABLE and SQR_FFT_TABLE otherwise come out
+ as non-constant array initializers. FIXME: Perhaps these should be done
+ in the cpuvec structure like other thresholds. */
+#define MUL_FFT_TABLE { 464, 928, 1920, 3584, 10240, 40960, 0 }
+#define MUL_FFT_MODF_THRESHOLD 400
+#define MUL_FFT_THRESHOLD 2000
+
+#define SQR_FFT_TABLE { 528, 1184, 1920, 4608, 14336, 40960, 0 }
+#define SQR_FFT_MODF_THRESHOLD 500
+#define SQR_FFT_THRESHOLD 3000
diff --git a/gmp/mpn/x86_64/fat/mod_1.c b/gmp/mpn/x86_64/fat/mod_1.c
new file mode 100644
index 0000000000..4f149cc353
--- /dev/null
+++ b/gmp/mpn/x86_64/fat/mod_1.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_mod_1.
+
+Copyright 2003, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/mod_1.c"
diff --git a/gmp/mpn/x86_64/fat/mul_basecase.c b/gmp/mpn/x86_64/fat/mul_basecase.c
new file mode 100644
index 0000000000..d9eb4718c2
--- /dev/null
+++ b/gmp/mpn/x86_64/fat/mul_basecase.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_mul_basecase.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/mul_basecase.c"
diff --git a/gmp/mpn/x86_64/fat/mullo_basecase.c b/gmp/mpn/x86_64/fat/mullo_basecase.c
new file mode 100644
index 0000000000..7f86be64c5
--- /dev/null
+++ b/gmp/mpn/x86_64/fat/mullo_basecase.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_mullo_basecase.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/mullo_basecase.c"
diff --git a/gmp/mpn/x86_64/fat/redc_1.c b/gmp/mpn/x86_64/fat/redc_1.c
new file mode 100644
index 0000000000..0025403353
--- /dev/null
+++ b/gmp/mpn/x86_64/fat/redc_1.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_redc_1.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/redc_1.c"
diff --git a/gmp/mpn/x86_64/fat/redc_2.c b/gmp/mpn/x86_64/fat/redc_2.c
new file mode 100644
index 0000000000..1932d58323
--- /dev/null
+++ b/gmp/mpn/x86_64/fat/redc_2.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_redc_2.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/redc_2.c"
diff --git a/gmp/mpn/x86_64/fat/sqr_basecase.c b/gmp/mpn/x86_64/fat/sqr_basecase.c
new file mode 100644
index 0000000000..d1c5dcd2e0
--- /dev/null
+++ b/gmp/mpn/x86_64/fat/sqr_basecase.c
@@ -0,0 +1,32 @@
+/* Fat binary fallback mpn_sqr_basecase.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "mpn/generic/sqr_basecase.c"
diff --git a/gmp/mpn/x86_64/gcd_1.asm b/gmp/mpn/x86_64/gcd_1.asm
new file mode 100644
index 0000000000..252d4174eb
--- /dev/null
+++ b/gmp/mpn/x86_64/gcd_1.asm
@@ -0,0 +1,163 @@
+dnl AMD64 mpn_gcd_1 -- mpn by 1 gcd.
+
+dnl Based on the K7 gcd_1.asm, by Kevin Ryde. Rehacked for AMD64 by Torbjorn
+dnl Granlund.
+
+dnl Copyright 2000-2002, 2005, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/bit (approx)
+C AMD K8,K9 5.21 (4.95)
+C AMD K10 5.15 (5.00)
+C AMD bd1 5.42 (5.14)
+C AMD bobcat 6.71 (6.56)
+C Intel P4 13.5 (12.75)
+C Intel core2 6.20 (6.16)
+C Intel NHM 6.49 (6.25)
+C Intel SBR 7.75 (7.57)
+C Intel atom 8.77 (8.54)
+C VIA nano 6.60 (6.20)
+C Numbers measured with: speed -CD -s16-64 -t48 mpn_gcd_1
+
+C ctz_table[n] is the number of trailing zeros on n, or MAXSHIFT if n==0.
+
+deflit(MAXSHIFT, 7)
+deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))
+
+DEF_OBJECT(ctz_table,64)
+ .byte MAXSHIFT
+forloop(i,1,MASK,
+` .byte m4_count_trailing_zeros(i)
+')
+END_OBJECT(ctz_table)
+
+C Threshold of when to call bmod when U is one limb. Should be about
+C (time_in_cycles(bmod_1,1) + call_overhead) / (cycles/bit).
+define(`BMOD_THRES_LOG2', 8)
+
+C INPUT PARAMETERS
+define(`up', `%rdi')
+define(`n', `%rsi')
+define(`v0', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+IFDOS(`define(`STACK_ALLOC', 40)')
+IFSTD(`define(`STACK_ALLOC', 8)')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_gcd_1)
+ FUNC_ENTRY(3)
+ mov (up), %rax C U low limb
+ mov $-1, R32(%rcx)
+ or v0, %rax C x | y
+
+L(twos):
+ inc R32(%rcx)
+ shr %rax
+ jnc L(twos)
+
+ shr R8(%rcx), v0
+ push %rcx C common twos
+
+L(divide_strip_y):
+ shr v0
+ jnc L(divide_strip_y)
+ adc v0, v0
+
+ cmp $1, n
+ jnz L(reduce_nby1)
+
+C Both U and V are single limbs, reduce with bmod if u0 >> v0.
+ mov (up), %r8
+ mov %r8, %rax
+ shr $BMOD_THRES_LOG2, %r8
+ cmp %r8, v0
+ ja L(noreduce)
+ push v0
+ sub $STACK_ALLOC, %rsp C maintain ABI required rsp alignment
+
+L(bmod):
+IFDOS(` mov %rdx, %r8 ')
+IFDOS(` mov %rsi, %rdx ')
+IFDOS(` mov %rdi, %rcx ')
+ CALL( mpn_modexact_1_odd)
+
+L(reduced):
+ add $STACK_ALLOC, %rsp
+ pop %rdx
+
+L(noreduce):
+ LEA( ctz_table, %rsi)
+ test %rax, %rax
+ mov %rax, %rcx
+ jnz L(mid)
+ jmp L(end)
+
+L(reduce_nby1):
+ push v0
+ sub $STACK_ALLOC, %rsp C maintain ABI required rsp alignment
+
+ cmp $BMOD_1_TO_MOD_1_THRESHOLD, n
+ jl L(bmod)
+IFDOS(` mov %rdx, %r8 ')
+IFDOS(` mov %rsi, %rdx ')
+IFDOS(` mov %rdi, %rcx ')
+ CALL( mpn_mod_1)
+ jmp L(reduced)
+
+ ALIGN(16) C K8 BC P4 NHM SBR
+L(top): cmovc %rcx, %rax C if x-y < 0 0
+ cmovc %rdi, %rdx C use x,y-x 0
+L(mid): and $MASK, R32(%rcx) C 0
+ movzbl (%rsi,%rcx), R32(%rcx) C 1
+ jz L(shift_alot) C 1
+ shr R8(%rcx), %rax C 3
+ mov %rax, %rdi C 4
+ mov %rdx, %rcx C 3
+ sub %rax, %rcx C 4
+ sub %rdx, %rax C 4
+ jnz L(top) C 5
+
+L(end): pop %rcx
+ mov %rdx, %rax
+ shl R8(%rcx), %rax
+ FUNC_EXIT()
+ ret
+
+L(shift_alot):
+ shr $MAXSHIFT, %rax
+ mov %rax, %rcx
+ jmp L(mid)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/gmp-mparam.h b/gmp/mpn/x86_64/gmp-mparam.h
new file mode 100644
index 0000000000..0dea8c94cd
--- /dev/null
+++ b/gmp/mpn/x86_64/gmp-mparam.h
@@ -0,0 +1,218 @@
+/* AMD K8-K10 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 14
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 28
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 7
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 15
+
+#define MUL_TOOM22_THRESHOLD 27
+#define MUL_TOOM33_THRESHOLD 81
+#define MUL_TOOM44_THRESHOLD 234
+#define MUL_TOOM6H_THRESHOLD 418
+#define MUL_TOOM8H_THRESHOLD 466
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 160
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 145
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 175
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 36
+#define SQR_TOOM3_THRESHOLD 117
+#define SQR_TOOM4_THRESHOLD 327
+#define SQR_TOOM6_THRESHOLD 446
+#define SQR_TOOM8_THRESHOLD 547
+
+#define MULMID_TOOM42_THRESHOLD 36
+
+#define MULMOD_BNM1_THRESHOLD 17
+#define SQRMOD_BNM1_THRESHOLD 17
+
+#define POWM_SEC_TABLE 2,67,322,991
+
+#define MUL_FFT_MODF_THRESHOLD 570 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 570, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 25, 8}, { 13, 7}, { 29, 8}, \
+ { 15, 7}, { 31, 8}, { 17, 7}, { 35, 8}, \
+ { 19, 7}, { 39, 8}, { 21, 7}, { 43, 8}, \
+ { 23, 7}, { 47, 8}, { 25, 7}, { 51, 8}, \
+ { 29, 9}, { 15, 8}, { 37, 9}, { 19, 8}, \
+ { 43, 9}, { 23, 8}, { 51, 9}, { 27, 8}, \
+ { 55,10}, { 15, 9}, { 43,10}, { 23, 9}, \
+ { 55,10}, { 31, 9}, { 63, 5}, { 1023, 4}, \
+ { 2431, 5}, { 1279, 6}, { 671, 7}, { 367, 8}, \
+ { 189, 9}, { 95, 8}, { 195, 9}, { 111,11}, \
+ { 31, 9}, { 131,10}, { 71, 9}, { 155,10}, \
+ { 79, 9}, { 159,10}, { 87,11}, { 47,10}, \
+ { 111,11}, { 63,10}, { 135,11}, { 79,10}, \
+ { 167,11}, { 95,10}, { 191,11}, { 111,12}, \
+ { 63,11}, { 143,10}, { 287,11}, { 159,10}, \
+ { 319,11}, { 175,12}, { 95,11}, { 207,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 543,11}, \
+ { 287,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 335,10}, { 671,11}, { 351,10}, { 703,12}, \
+ { 191,11}, { 383,10}, { 767,11}, { 415,12}, \
+ { 223,13}, { 127,12}, { 255,11}, { 543,12}, \
+ { 287,11}, { 575,10}, { 1151,11}, { 607,12}, \
+ { 319,11}, { 639,10}, { 1279,11}, { 671,12}, \
+ { 351,11}, { 703,13}, { 191,12}, { 383,11}, \
+ { 767,12}, { 415,11}, { 831,12}, { 447,14}, \
+ { 127,13}, { 255,12}, { 543,11}, { 1087,12}, \
+ { 607,11}, { 1215,13}, { 319,12}, { 671,11}, \
+ { 1343,12}, { 735,13}, { 383,12}, { 767,11}, \
+ { 1535,12}, { 799,11}, { 1599,12}, { 831,13}, \
+ { 447,12}, { 895,11}, { 1791,12}, { 959,14}, \
+ { 255,13}, { 511,12}, { 1087,13}, { 575,12}, \
+ { 1215,13}, { 639,12}, { 1343,13}, { 703,12}, \
+ { 1407,14}, { 383,13}, { 767,12}, { 1599,13}, \
+ { 831,12}, { 1663,13}, { 895,12}, { 1791,13}, \
+ { 959,15}, { 255,14}, { 511,13}, { 1087,12}, \
+ { 2175,13}, { 1215,14}, { 639,13}, { 1471,14}, \
+ { 767,13}, { 1663,14}, { 895,13}, { 1855,15}, \
+ { 511,14}, { 1023,13}, { 2175,14}, { 1151,13}, \
+ { 2431,14}, { 1279,13}, { 2687,14}, { 1407,15}, \
+ { 767,14}, { 1535,13}, { 3071,14}, { 1791,16}, \
+ { 511,15}, { 1023,14}, { 2431,15}, { 1279,14}, \
+ { 2815,15}, { 1535,14}, { 3199,15}, { 1791,14}, \
+ { 3583,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 185
+#define MUL_FFT_THRESHOLD 7552
+
+#define SQR_FFT_MODF_THRESHOLD 460 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 460, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 12, 5}, { 25, 6}, { 27, 7}, { 14, 6}, \
+ { 29, 7}, { 15, 6}, { 31, 7}, { 29, 8}, \
+ { 15, 7}, { 32, 8}, { 17, 7}, { 35, 8}, \
+ { 19, 7}, { 39, 8}, { 21, 7}, { 43, 8}, \
+ { 25, 7}, { 51, 8}, { 29, 9}, { 15, 8}, \
+ { 35, 9}, { 19, 8}, { 43, 9}, { 23, 8}, \
+ { 51, 9}, { 27, 8}, { 55,10}, { 15, 9}, \
+ { 31, 8}, { 63, 9}, { 43,10}, { 23, 9}, \
+ { 55,11}, { 15,10}, { 31, 9}, { 71,10}, \
+ { 39, 9}, { 83,10}, { 47, 6}, { 767, 4}, \
+ { 3263, 5}, { 1727, 4}, { 3455, 5}, { 1791, 6}, \
+ { 927, 7}, { 479, 6}, { 959, 7}, { 511, 8}, \
+ { 271, 9}, { 147,10}, { 87,11}, { 47,10}, \
+ { 95,12}, { 31,11}, { 63,10}, { 135,11}, \
+ { 79,10}, { 167,11}, { 95,10}, { 191,11}, \
+ { 111,12}, { 63,11}, { 127,10}, { 255,11}, \
+ { 143,10}, { 287, 9}, { 575,10}, { 303,11}, \
+ { 159,12}, { 95,11}, { 191,10}, { 383, 9}, \
+ { 767,10}, { 399,11}, { 207,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 511,11}, { 271,10}, \
+ { 543,11}, { 287,10}, { 575,12}, { 159,11}, \
+ { 319,10}, { 639,11}, { 335,10}, { 671,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 415,10}, { 831,11}, { 447,13}, \
+ { 127,12}, { 255,11}, { 511,10}, { 1023,11}, \
+ { 543,12}, { 287,11}, { 575,10}, { 1151,11}, \
+ { 607,10}, { 1215,12}, { 319,11}, { 639,10}, \
+ { 1279,11}, { 671,12}, { 351,11}, { 703,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,12}, { 447,14}, { 127,13}, { 255,12}, \
+ { 511,11}, { 1023,12}, { 543,11}, { 1087,12}, \
+ { 575,11}, { 1151,12}, { 607,13}, { 319,12}, \
+ { 639,11}, { 1279,12}, { 671,11}, { 1343,12}, \
+ { 703,11}, { 1407,12}, { 735,13}, { 383,12}, \
+ { 767,11}, { 1535,12}, { 799,11}, { 1599,12}, \
+ { 831,13}, { 447,12}, { 959,14}, { 255,13}, \
+ { 511,12}, { 1087,13}, { 575,12}, { 1215,13}, \
+ { 639,12}, { 1343,13}, { 703,12}, { 1407,14}, \
+ { 383,13}, { 767,12}, { 1599,13}, { 831,12}, \
+ { 1663,13}, { 895,12}, { 1791,13}, { 959,15}, \
+ { 255,14}, { 511,13}, { 1087,12}, { 2175,13}, \
+ { 1215,14}, { 639,13}, { 1471,14}, { 767,13}, \
+ { 1663,14}, { 895,13}, { 1855,15}, { 511,14}, \
+ { 1023,13}, { 2175,14}, { 1151,13}, { 2303,14}, \
+ { 1279,13}, { 2559,14}, { 1407,15}, { 767,14}, \
+ { 1535,13}, { 3071,14}, { 1791,16}, { 511,15}, \
+ { 1023,14}, { 2303,15}, { 1279,14}, { 2687,15}, \
+ { 1535,14}, { 3199,15}, { 1791,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 203
+#define SQR_FFT_THRESHOLD 5248
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 35
+#define MULLO_MUL_N_THRESHOLD 15604
+
+#define DC_DIV_QR_THRESHOLD 56
+#define DC_DIVAPPR_Q_THRESHOLD 220
+#define DC_BDIV_QR_THRESHOLD 52
+#define DC_BDIV_Q_THRESHOLD 152
+
+#define INV_MULMOD_BNM1_THRESHOLD 54
+#define INV_NEWTON_THRESHOLD 226
+#define INV_APPR_THRESHOLD 214
+
+#define BINV_NEWTON_THRESHOLD 327
+#define REDC_1_TO_REDC_2_THRESHOLD 4
+#define REDC_2_TO_REDC_N_THRESHOLD 79
+
+#define MU_DIV_QR_THRESHOLD 1895
+#define MU_DIVAPPR_Q_THRESHOLD 1895
+#define MUPI_DIV_QR_THRESHOLD 106
+#define MU_BDIV_QR_THRESHOLD 1589
+#define MU_BDIV_Q_THRESHOLD 1718
+
+#define MATRIX22_STRASSEN_THRESHOLD 16
+#define HGCD_THRESHOLD 125
+#define HGCD_APPR_THRESHOLD 173
+#define HGCD_REDUCE_THRESHOLD 3524
+#define GCD_DC_THRESHOLD 555
+#define GCDEXT_DC_THRESHOLD 478
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 28
+#define SET_STR_DC_THRESHOLD 248
+#define SET_STR_PRECOMPUTE_THRESHOLD 1648
+
+#define FAC_DSC_THRESHOLD 1075
+#define FAC_ODD_THRESHOLD 0 /* always */
+
diff --git a/gmp/mpn/x86_64/invert_limb.asm b/gmp/mpn/x86_64/invert_limb.asm
new file mode 100644
index 0000000000..cc79b89a2b
--- /dev/null
+++ b/gmp/mpn/x86_64/invert_limb.asm
@@ -0,0 +1,115 @@
+dnl AMD64 mpn_invert_limb -- Invert a normalized limb.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Niels Möller.
+
+dnl Copyright 2004, 2007-2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb (approx) div
+C AMD K8,K9 48 71
+C AMD K10 48 77
+C Intel P4 135 161
+C Intel core2 69 116
+C Intel corei 55 89
+C Intel atom 129 191
+C VIA nano 79 157
+
+C rax rcx rdx rdi rsi r8
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+PROTECT(`mpn_invert_limb_table')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_invert_limb) C Kn C2 Ci
+ FUNC_ENTRY(1)
+ mov %rdi, %rax C 0 0 0
+ shr $55, %rax C 1 1 1
+ifdef(`PIC',`
+ifdef(`DARWIN',`
+ mov mpn_invert_limb_table@GOTPCREL(%rip), %r8
+ add $-512, %r8
+',`
+ lea -512+mpn_invert_limb_table(%rip), %r8
+')',`
+ movabs $-512+mpn_invert_limb_table, %r8
+')
+ movzwl (%r8,%rax,2), R32(%rcx) C %rcx = v0
+
+ C v1 = (v0 << 11) - (v0*v0*d40 >> 40) - 1
+ mov %rdi, %rsi C 0 0 0
+ mov R32(%rcx), R32(%rax) C 4 5 5
+ imul R32(%rcx), R32(%rcx) C 4 5 5
+ shr $24, %rsi C 1 1 1
+ inc %rsi C %rsi = d40
+ imul %rsi, %rcx C 8 10 8
+ shr $40, %rcx C 12 15 11
+ sal $11, R32(%rax) C 5 6 6
+ dec R32(%rax)
+ sub R32(%rcx), R32(%rax) C %rax = v1
+
+ C v2 = (v1 << 13) + (v1 * (2^60 - v1*d40) >> 47)
+ mov $0x1000000000000000, %rcx
+ imul %rax, %rsi C 14 17 13
+ sub %rsi, %rcx
+ imul %rax, %rcx
+ sal $13, %rax
+ shr $47, %rcx
+ add %rax, %rcx C %rcx = v2
+
+ C v3 = (v2 << 31) + (v2 * (2^96 - v2 * d63 + ((v2 >> 1) & mask)) >> 65
+ mov %rdi, %rsi C 0 0 0
+ shr %rsi C d/2
+ sbb %rax, %rax C -d0 = -(d mod 2)
+ sub %rax, %rsi C d63 = ceil(d/2)
+ imul %rcx, %rsi C v2 * d63
+ and %rcx, %rax C v2 * d0
+ shr %rax C (v2>>1) * d0
+ sub %rsi, %rax C (v2>>1) * d0 - v2 * d63
+ mul %rcx
+ sal $31, %rcx
+ shr %rdx
+ add %rdx, %rcx C %rcx = v3
+
+ mov %rdi, %rax
+ mul %rcx
+ add %rdi, %rax
+ mov %rcx, %rax
+ adc %rdi, %rdx
+ sub %rdx, %rax
+
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/invert_limb_table.asm b/gmp/mpn/x86_64/invert_limb_table.asm
new file mode 100644
index 0000000000..739d59e46c
--- /dev/null
+++ b/gmp/mpn/x86_64/invert_limb_table.asm
@@ -0,0 +1,50 @@
+dnl Table used for mpn_invert_limb
+
+dnl Contributed to the GNU project by Torbjorn Granlund and Niels Möller.
+
+dnl Copyright 2004, 2007-2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+PROTECT(`mpn_invert_limb_table')
+
+ASM_START()
+C Table entry X contains floor (0x7fd00 / (0x100 + X))
+
+ RODATA
+ ALIGN(2)
+ GLOBL mpn_invert_limb_table
+mpn_invert_limb_table:
+forloop(i,256,512-1,dnl
+` .value eval(0x7fd00/i)
+')dnl
+ASM_END()
diff --git a/gmp/mpn/x86_64/k10/gcd_1.asm b/gmp/mpn/x86_64/k10/gcd_1.asm
new file mode 100644
index 0000000000..3d8e5c7ab1
--- /dev/null
+++ b/gmp/mpn/x86_64/k10/gcd_1.asm
@@ -0,0 +1,37 @@
+dnl AMD64 mpn_gcd_1.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_gcd_1)
+include_mpn(`x86_64/core2/gcd_1.asm')
diff --git a/gmp/mpn/x86_64/k10/gmp-mparam.h b/gmp/mpn/x86_64/k10/gmp-mparam.h
new file mode 100644
index 0000000000..5881306a40
--- /dev/null
+++ b/gmp/mpn/x86_64/k10/gmp-mparam.h
@@ -0,0 +1,222 @@
+/* AMD K10 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2012, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+#if 0
+#undef mpn_sublsh_n
+#define mpn_sublsh_n(rp,up,vp,n,c) \
+ (((rp) == (up)) ? mpn_submul_1 (rp, vp, n, CNST_LIMB(1) << (c)) \
+ : MPN(mpn_sublsh_n)(rp,up,vp,n,c))
+#endif
+
+/* 3200 MHz K10 Thuban */
+/* FFT tuning limit = 100000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.2 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 2
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 17
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 28
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 7
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 15
+
+#define MUL_TOOM22_THRESHOLD 28
+#define MUL_TOOM33_THRESHOLD 81
+#define MUL_TOOM44_THRESHOLD 242
+#define MUL_TOOM6H_THRESHOLD 369
+#define MUL_TOOM8H_THRESHOLD 478
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 154
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 145
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 163
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 142
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 34
+#define SQR_TOOM3_THRESHOLD 114
+#define SQR_TOOM4_THRESHOLD 390
+#define SQR_TOOM6_THRESHOLD 446
+#define SQR_TOOM8_THRESHOLD 547
+
+#define MULMID_TOOM42_THRESHOLD 36
+
+#define MULMOD_BNM1_THRESHOLD 17
+#define SQRMOD_BNM1_THRESHOLD 17
+
+#define MUL_FFT_MODF_THRESHOLD 570 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 570, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 29, 7}, { 15, 6}, { 31, 7}, { 29, 8}, \
+ { 15, 7}, { 32, 8}, { 17, 7}, { 35, 8}, \
+ { 19, 7}, { 39, 8}, { 21, 7}, { 43, 8}, \
+ { 23, 7}, { 47, 8}, { 25, 7}, { 51, 8}, \
+ { 29, 9}, { 15, 8}, { 35, 9}, { 19, 8}, \
+ { 43, 9}, { 23, 8}, { 51, 9}, { 27, 8}, \
+ { 55,10}, { 15, 9}, { 31, 8}, { 63, 9}, \
+ { 43,10}, { 23, 9}, { 55,10}, { 31, 9}, \
+ { 67,10}, { 39, 9}, { 83,10}, { 47, 9}, \
+ { 95,10}, { 55,11}, { 31,10}, { 87,11}, \
+ { 47,10}, { 111,12}, { 31,11}, { 63,10}, \
+ { 135,11}, { 79,10}, { 167, 8}, { 671,11}, \
+ { 111,12}, { 63,11}, { 159,12}, { 95,11}, \
+ { 207,10}, { 415,13}, { 63,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 271,12}, { 159,11}, \
+ { 319,10}, { 639,11}, { 335,10}, { 671,11}, \
+ { 367,12}, { 191,11}, { 415,12}, { 223,13}, \
+ { 127,12}, { 255,11}, { 543,12}, { 287,11}, \
+ { 575,10}, { 1151,11}, { 607,10}, { 1215,12}, \
+ { 319,11}, { 671,12}, { 351,11}, { 703,13}, \
+ { 191,12}, { 383,11}, { 767,12}, { 415,11}, \
+ { 831,12}, { 447,14}, { 127,13}, { 255,12}, \
+ { 543,11}, { 1087,12}, { 607,13}, { 319,12}, \
+ { 671,11}, { 1343,12}, { 735,13}, { 383,12}, \
+ { 799,11}, { 1599,12}, { 831,13}, { 447,12}, \
+ { 959,13}, { 511,12}, { 1087,13}, { 575,12}, \
+ { 1215,13}, { 639,12}, { 1343,13}, { 703,12}, \
+ { 1407,14}, { 383,13}, { 767,12}, { 1599,13}, \
+ { 831,12}, { 1663,13}, { 895,12}, { 1791,13}, \
+ { 959,15}, { 255,14}, { 511,13}, { 1087,12}, \
+ { 2175,13}, { 1215,14}, { 639,13}, { 1471,14}, \
+ { 767,13}, { 1727,14}, { 895,13}, { 1855,15}, \
+ { 511,14}, { 1023,13}, { 2175,14}, { 1151,13}, \
+ { 2431,14}, { 1279,13}, { 2559,14}, { 1407,15}, \
+ { 767,14}, { 1535,13}, { 3071,14}, { 1791,16}, \
+ { 511,15}, { 1023,14}, { 2431,15}, { 1279,14}, \
+ { 2815,15}, { 1535,14}, { 3199,15}, { 1791,14}, \
+ { 3583,16}, { 1023,15}, { 2047,14}, { 4223,15}, \
+ { 2303,14}, { 4863,15}, { 2559,14}, { 5247,15}, \
+ { 2815,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 169
+#define MUL_FFT_THRESHOLD 7808
+
+#define SQR_FFT_MODF_THRESHOLD 448 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 448, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 12, 5}, { 25, 6}, { 29, 7}, { 15, 6}, \
+ { 31, 7}, { 29, 8}, { 15, 7}, { 32, 8}, \
+ { 17, 7}, { 35, 8}, { 19, 7}, { 39, 8}, \
+ { 21, 7}, { 43, 8}, { 25, 7}, { 51, 8}, \
+ { 29, 9}, { 15, 8}, { 35, 9}, { 19, 8}, \
+ { 43, 9}, { 23, 8}, { 51, 9}, { 27, 8}, \
+ { 55,10}, { 15, 9}, { 31, 8}, { 65, 9}, \
+ { 43,10}, { 23, 9}, { 55,11}, { 15,10}, \
+ { 31, 9}, { 67,10}, { 39, 9}, { 83,10}, \
+ { 47, 9}, { 95,10}, { 55,11}, { 31,10}, \
+ { 79,11}, { 47,10}, { 103,12}, { 31,11}, \
+ { 63,10}, { 135,11}, { 79,10}, { 159,11}, \
+ { 95,10}, { 191,11}, { 111,12}, { 63,11}, \
+ { 127,10}, { 255,11}, { 143, 9}, { 575,10}, \
+ { 303, 9}, { 607,12}, { 95,11}, { 191, 9}, \
+ { 767,10}, { 399,11}, { 207,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 543, 9}, { 1087,10}, \
+ { 575,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 335,10}, { 671,11}, { 351,10}, { 703, 9}, \
+ { 1407,12}, { 191,11}, { 415,10}, { 831,12}, \
+ { 223,11}, { 447,13}, { 127,12}, { 255,11}, \
+ { 543,10}, { 1087,12}, { 287,11}, { 607,12}, \
+ { 319,11}, { 671,12}, { 351,11}, { 703,13}, \
+ { 191,12}, { 383,11}, { 767,10}, { 1535,12}, \
+ { 415,11}, { 863,12}, { 447,14}, { 127,13}, \
+ { 255,12}, { 511,11}, { 1023,12}, { 543,11}, \
+ { 1087,12}, { 575,11}, { 1151,12}, { 607,13}, \
+ { 319,12}, { 639,11}, { 1279,12}, { 671,11}, \
+ { 1343,12}, { 703,11}, { 1407,12}, { 735,13}, \
+ { 383,12}, { 799,11}, { 1599,12}, { 863,13}, \
+ { 447,12}, { 927,14}, { 255,13}, { 511,12}, \
+ { 1087,13}, { 575,12}, { 1215,13}, { 639,12}, \
+ { 1343,13}, { 703,12}, { 1407,14}, { 383,13}, \
+ { 767,12}, { 1535,13}, { 831,12}, { 1727,13}, \
+ { 895,12}, { 1791,13}, { 959,15}, { 255,14}, \
+ { 511,13}, { 1087,12}, { 2175,13}, { 1215,14}, \
+ { 639,13}, { 1471,14}, { 767,13}, { 1663,14}, \
+ { 895,13}, { 1791,15}, { 511,14}, { 1023,13}, \
+ { 2175,14}, { 1151,13}, { 2303,14}, { 1407,15}, \
+ { 767,14}, { 1791,16}, { 511,15}, { 1023,14}, \
+ { 2303,15}, { 1279,14}, { 2687,15}, { 1535,14}, \
+ { 3199,15}, { 1791,16}, { 1023,15}, { 2047,14}, \
+ { 4223,15}, { 2303,14}, { 4863,15}, { 2559,14}, \
+ { 5247,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 185
+#define SQR_FFT_THRESHOLD 5568
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 61
+#define MULLO_MUL_N_THRESHOLD 15604
+
+#define DC_DIV_QR_THRESHOLD 56
+#define DC_DIVAPPR_Q_THRESHOLD 218
+#define DC_BDIV_QR_THRESHOLD 52
+#define DC_BDIV_Q_THRESHOLD 42
+
+#define INV_MULMOD_BNM1_THRESHOLD 62
+#define INV_NEWTON_THRESHOLD 226
+#define INV_APPR_THRESHOLD 220
+
+#define BINV_NEWTON_THRESHOLD 327
+#define REDC_1_TO_REDC_2_THRESHOLD 51
+#define REDC_2_TO_REDC_N_THRESHOLD 66
+
+#define MU_DIV_QR_THRESHOLD 1752
+#define MU_DIVAPPR_Q_THRESHOLD 1718
+#define MUPI_DIV_QR_THRESHOLD 102
+#define MU_BDIV_QR_THRESHOLD 1528
+#define MU_BDIV_Q_THRESHOLD 1718
+
+#define POWM_SEC_TABLE 1,22,110,624,1985
+
+#define MATRIX22_STRASSEN_THRESHOLD 17
+#define HGCD_THRESHOLD 147
+#define HGCD_APPR_THRESHOLD 181
+#define HGCD_REDUCE_THRESHOLD 3524
+#define GCD_DC_THRESHOLD 622
+#define GCDEXT_DC_THRESHOLD 487
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 14
+#define GET_STR_PRECOMPUTE_THRESHOLD 29
+#define SET_STR_DC_THRESHOLD 268
+#define SET_STR_PRECOMPUTE_THRESHOLD 1718
+
+#define FAC_DSC_THRESHOLD 1075
+#define FAC_ODD_THRESHOLD 23
diff --git a/gmp/mpn/x86_64/k10/hamdist.asm b/gmp/mpn/x86_64/k10/hamdist.asm
new file mode 100644
index 0000000000..44b67b5e4e
--- /dev/null
+++ b/gmp/mpn/x86_64/k10/hamdist.asm
@@ -0,0 +1,103 @@
+dnl AMD64 mpn_hamdist -- hamming distance.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 n/a
+C AMD K10 2
+C Intel P4 n/a
+C Intel core2 n/a
+C Intel corei 2.05
+C Intel atom n/a
+C VIA nano n/a
+
+C This is very straightforward 2-way unrolled code.
+
+C TODO
+C * Write something less basic. It should not be hard to reach 1.5 c/l with
+C 4-way unrolling.
+
+define(`ap', `%rdi')
+define(`bp', `%rsi')
+define(`n', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_hamdist)
+ FUNC_ENTRY(3)
+ mov (ap), %r8
+ xor (bp), %r8
+
+ lea (ap,n,8), ap C point at A operand end
+ lea (bp,n,8), bp C point at B operand end
+ neg n
+
+ bt $0, R32(n)
+ jnc L(2)
+
+L(1): .byte 0xf3,0x49,0x0f,0xb8,0xc0 C popcnt %r8, %rax
+ xor R32(%r10), R32(%r10)
+ add $1, n
+ js L(top)
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(2): mov 8(ap,n,8), %r9
+ .byte 0xf3,0x49,0x0f,0xb8,0xc0 C popcnt %r8, %rax
+ xor 8(bp,n,8), %r9
+ .byte 0xf3,0x4d,0x0f,0xb8,0xd1 C popcnt %r9, %r10
+ add $2, n
+ js L(top)
+ lea (%r10, %rax), %rax
+ FUNC_EXIT()
+ ret
+
+ ALIGN(16)
+L(top): mov (ap,n,8), %r8
+ lea (%r10, %rax), %rax
+ mov 8(ap,n,8), %r9
+ xor (bp,n,8), %r8
+ xor 8(bp,n,8), %r9
+ .byte 0xf3,0x49,0x0f,0xb8,0xc8 C popcnt %r8, %rcx
+ lea (%rcx, %rax), %rax
+ .byte 0xf3,0x4d,0x0f,0xb8,0xd1 C popcnt %r9, %r10
+ add $2, n
+ js L(top)
+
+ lea (%r10, %rax), %rax
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/k10/lshift.asm b/gmp/mpn/x86_64/k10/lshift.asm
new file mode 100644
index 0000000000..a1cbc31f61
--- /dev/null
+++ b/gmp/mpn/x86_64/k10/lshift.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_lshift optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_lshift)
+include_mpn(`x86_64/fastsse/lshift-movdqu2.asm')
diff --git a/gmp/mpn/x86_64/k10/lshiftc.asm b/gmp/mpn/x86_64/k10/lshiftc.asm
new file mode 100644
index 0000000000..ac90edb76b
--- /dev/null
+++ b/gmp/mpn/x86_64/k10/lshiftc.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_lshiftc optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_lshiftc)
+include_mpn(`x86_64/fastsse/lshiftc-movdqu2.asm')
diff --git a/gmp/mpn/x86_64/k10/popcount.asm b/gmp/mpn/x86_64/k10/popcount.asm
new file mode 100644
index 0000000000..3814aeabf4
--- /dev/null
+++ b/gmp/mpn/x86_64/k10/popcount.asm
@@ -0,0 +1,138 @@
+dnl AMD64 mpn_popcount -- population count.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 n/a
+C AMD K10 1.125
+C Intel P4 n/a
+C Intel core2 n/a
+C Intel corei 1.25
+C Intel atom n/a
+C VIA nano n/a
+
+C * The zero-offset of popcount is misassembled to the offset-less form, which
+C is one byte shorter and therefore will mess up the switching code.
+C * The outdated gas used in FreeBSD and NetBSD cannot handle the POPCNT insn,
+C which is the main reason for our usage of '.byte'.
+
+C TODO
+C * Improve switching code, the current code sucks.
+
+define(`up', `%rdi')
+define(`n', `%rsi')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_popcount)
+ FUNC_ENTRY(2)
+
+ifelse(1,1,`
+ lea (up,n,8), up
+
+C mov R32(n), R32(%rcx)
+C neg R32(%rcx)
+ imul $-1, R32(n), R32(%rcx)
+ and $8-1, R32(%rcx)
+
+ neg n
+
+ mov R32(%rcx), R32(%rax)
+ neg %rax
+ lea (up,%rax,8),up
+
+ xor R32(%rax), R32(%rax)
+
+ lea (%rcx,%rcx,4), %rcx
+
+ lea L(top)(%rip), %rdx
+ lea (%rdx,%rcx,2), %rdx
+ jmp *%rdx
+',`
+ lea (up,n,8), up
+
+ mov R32(n), R32(%rcx)
+ neg R32(%rcx)
+ and $8-1, R32(%rcx)
+
+ neg n
+
+ mov R32(%rcx), R32(%rax)
+ shl $3, R32(%rax)
+ sub %rax, up
+
+ xor R32(%rax), R32(%rax)
+
+C add R32(%rcx), R32(%rcx) C 2x
+C lea (%rcx,%rcx,4), %rcx C 10x
+ imul $10, R32(%rcx)
+
+ lea L(top)(%rip), %rdx
+ add %rcx, %rdx
+ jmp *%rdx
+')
+
+ ALIGN(32)
+L(top):
+C 0 = n mod 8
+ .byte 0xf3,0x4c,0x0f,0xb8,0x44,0xf7,0x00 C popcnt 0(up,n,8), %r8
+ add %r8, %rax
+C 7 = n mod 8
+ .byte 0xf3,0x4c,0x0f,0xb8,0x4c,0xf7,0x08 C popcnt 8(up,n,8), %r9
+ add %r9, %rax
+C 6 = n mod 8
+ .byte 0xf3,0x4c,0x0f,0xb8,0x44,0xf7,0x10 C popcnt 16(up,n,8), %r8
+ add %r8, %rax
+C 5 = n mod 8
+ .byte 0xf3,0x4c,0x0f,0xb8,0x4c,0xf7,0x18 C popcnt 24(up,n,8), %r9
+ add %r9, %rax
+C 4 = n mod 8
+ .byte 0xf3,0x4c,0x0f,0xb8,0x44,0xf7,0x20 C popcnt 32(up,n,8), %r8
+ add %r8, %rax
+C 3 = n mod 8
+ .byte 0xf3,0x4c,0x0f,0xb8,0x4c,0xf7,0x28 C popcnt 40(up,n,8), %r9
+ add %r9, %rax
+C 2 = n mod 8
+ .byte 0xf3,0x4c,0x0f,0xb8,0x44,0xf7,0x30 C popcnt 48(up,n,8), %r8
+ add %r8, %rax
+C 1 = n mod 8
+ .byte 0xf3,0x4c,0x0f,0xb8,0x4c,0xf7,0x38 C popcnt 56(up,n,8), %r9
+ add %r9, %rax
+
+ add $8, n
+ js L(top)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/k10/rshift.asm b/gmp/mpn/x86_64/k10/rshift.asm
new file mode 100644
index 0000000000..4c1c0d4cde
--- /dev/null
+++ b/gmp/mpn/x86_64/k10/rshift.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_rshift optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_rshift)
+include_mpn(`x86_64/fastsse/rshift-movdqu2.asm')
diff --git a/gmp/mpn/x86_64/k10/sec_tabselect.asm b/gmp/mpn/x86_64/k10/sec_tabselect.asm
new file mode 100644
index 0000000000..e4360341d9
--- /dev/null
+++ b/gmp/mpn/x86_64/k10/sec_tabselect.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_sec_tabselect.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_sec_tabselect)
+include_mpn(`x86_64/fastsse/sec_tabselect.asm')
diff --git a/gmp/mpn/x86_64/k8/aorrlsh_n.asm b/gmp/mpn/x86_64/k8/aorrlsh_n.asm
new file mode 100644
index 0000000000..ff3a1842fd
--- /dev/null
+++ b/gmp/mpn/x86_64/k8/aorrlsh_n.asm
@@ -0,0 +1,217 @@
+dnl AMD64 mpn_addlsh_n and mpn_rsblsh_n. R = V2^k +- U.
+
+dnl Copyright 2006, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.87 < 3.85 for lshift + add_n
+C AMD K10 2.75 < 3.85 for lshift + add_n
+C Intel P4 22 > 7.33 for lshift + add_n
+C Intel core2 4.1 > 3.27 for lshift + add_n
+C Intel NHM 4.4 > 3.75 for lshift + add_n
+C Intel SBR 3.17 < 3.46 for lshift + add_n
+C Intel atom ? ? 8.75 for lshift + add_n
+C VIA nano 4.7 < 6.25 for lshift + add_n
+
+C TODO
+C * Can we propagate carry into rdx instead of using a special carry register?
+C That could save enough insns to get to 10 cycles/iteration.
+
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp_param', `%rdx')
+define(`n_param', `%rcx')
+define(`cnt', `%r8')
+
+define(`vp', `%r12')
+define(`n', `%rbp')
+
+ifdef(`OPERATION_addlsh_n',`
+ define(ADDSUB, `add')
+ define(ADCSBB, `adc')
+ define(func, mpn_addlsh_n)
+')
+ifdef(`OPERATION_rsblsh_n',`
+ define(ADDSUB, `sub')
+ define(ADCSBB, `sbb')
+ define(func, mpn_rsblsh_n)
+')
+
+MULFUNC_PROLOGUE(mpn_addlsh_n mpn_rsblsh_n)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+ push %r12
+ push %rbp
+ push %rbx
+
+ mov (vp_param), %rax C load first V limb early
+
+ mov $0, R32(n)
+ sub n_param, n
+
+ lea -16(up,n_param,8), up
+ lea -16(rp,n_param,8), rp
+ lea 16(vp_param,n_param,8), vp
+
+ mov n_param, %r9
+
+ mov %r8, %rcx
+ mov $1, R32(%r8)
+ shl R8(%rcx), %r8
+
+ mul %r8 C initial multiply
+
+ and $3, R32(%r9)
+ jz L(b0)
+ cmp $2, R32(%r9)
+ jc L(b1)
+ jz L(b2)
+
+L(b3): mov %rax, %r11
+ ADDSUB 16(up,n,8), %r11
+ mov -8(vp,n,8), %rax
+ sbb R32(%rcx), R32(%rcx)
+ mov %rdx, %rbx
+ mul %r8
+ or %rax, %rbx
+ mov (vp,n,8), %rax
+ mov %rdx, %r9
+ mul %r8
+ or %rax, %r9
+ add $3, n
+ jnz L(lo3)
+ jmp L(cj3)
+
+L(b2): mov %rax, %rbx
+ mov -8(vp,n,8), %rax
+ mov %rdx, %r9
+ mul %r8
+ or %rax, %r9
+ add $2, n
+ jz L(cj2)
+ mov %rdx, %r10
+ mov -16(vp,n,8), %rax
+ mul %r8
+ or %rax, %r10
+ xor R32(%rcx), R32(%rcx) C clear carry register
+ jmp L(lo2)
+
+L(b1): mov %rax, %r9
+ mov %rdx, %r10
+ add $1, n
+ jnz L(gt1)
+ ADDSUB 8(up,n,8), %r9
+ jmp L(cj1)
+L(gt1): mov -16(vp,n,8), %rax
+ mul %r8
+ or %rax, %r10
+ mov %rdx, %r11
+ mov -8(vp,n,8), %rax
+ mul %r8
+ or %rax, %r11
+ ADDSUB 8(up,n,8), %r9
+ ADCSBB 16(up,n,8), %r10
+ ADCSBB 24(up,n,8), %r11
+ mov (vp,n,8), %rax
+ sbb R32(%rcx), R32(%rcx)
+ jmp L(lo1)
+
+L(b0): mov %rax, %r10
+ mov %rdx, %r11
+ mov -8(vp,n,8), %rax
+ mul %r8
+ or %rax, %r11
+ ADDSUB 16(up,n,8), %r10
+ ADCSBB 24(up,n,8), %r11
+ mov (vp,n,8), %rax
+ sbb R32(%rcx), R32(%rcx)
+ mov %rdx, %rbx
+ mul %r8
+ or %rax, %rbx
+ mov 8(vp,n,8), %rax
+ add $4, n
+ jz L(end)
+
+ ALIGN(8)
+L(top): mov %rdx, %r9
+ mul %r8
+ or %rax, %r9
+ mov %r10, -16(rp,n,8)
+L(lo3): mov %rdx, %r10
+ mov -16(vp,n,8), %rax
+ mul %r8
+ or %rax, %r10
+ mov %r11, -8(rp,n,8)
+L(lo2): mov %rdx, %r11
+ mov -8(vp,n,8), %rax
+ mul %r8
+ or %rax, %r11
+ add R32(%rcx), R32(%rcx)
+ ADCSBB (up,n,8), %rbx
+ ADCSBB 8(up,n,8), %r9
+ ADCSBB 16(up,n,8), %r10
+ ADCSBB 24(up,n,8), %r11
+ mov (vp,n,8), %rax
+ sbb R32(%rcx), R32(%rcx)
+ mov %rbx, (rp,n,8)
+L(lo1): mov %rdx, %rbx
+ mul %r8
+ or %rax, %rbx
+ mov %r9, 8(rp,n,8)
+L(lo0): mov 8(vp,n,8), %rax
+ add $4, n
+ jnz L(top)
+
+L(end): mov %rdx, %r9
+ mul %r8
+ or %rax, %r9
+ mov %r10, -16(rp,n,8)
+L(cj3): mov %r11, -8(rp,n,8)
+L(cj2): add R32(%rcx), R32(%rcx)
+ ADCSBB (up,n,8), %rbx
+ ADCSBB 8(up,n,8), %r9
+ mov %rbx, (rp,n,8)
+L(cj1): mov %r9, 8(rp,n,8)
+ mov %rdx, %rax
+ ADCSBB $0, %rax
+ pop %rbx
+ pop %rbp
+ pop %r12
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/k8/div_qr_1n_pi1.asm b/gmp/mpn/x86_64/k8/div_qr_1n_pi1.asm
new file mode 100644
index 0000000000..861402b222
--- /dev/null
+++ b/gmp/mpn/x86_64/k8/div_qr_1n_pi1.asm
@@ -0,0 +1,249 @@
+dnl x86-64 mpn_div_qr_1n_pi1
+dnl -- Divide an mpn number by a normalized single-limb number,
+dnl using a single-limb inverse.
+
+dnl Contributed to the GNU project by Niels Möller
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C c/l
+C AMD K8,K9 11
+C AMD K10 11
+C AMD bull 16
+C AMD pile 14.25
+C AMD steam ?
+C AMD bobcat 16
+C AMD jaguar ?
+C Intel P4 47.5 poor
+C Intel core 28.5 very poor
+C Intel NHM 29 very poor
+C Intel SBR 16 poor
+C Intel IBR 13.5
+C Intel HWL 12
+C Intel BWL ?
+C Intel atom 53 very poor
+C VIA nano 19
+
+
+C INPUT Parameters
+define(`QP', `%rdi')
+define(`UP', `%rsi')
+define(`UN_INPUT', `%rdx')
+define(`U1', `%rcx') C Also in %rax
+define(`D', `%r8')
+define(`DINV', `%r9')
+
+C Invariants
+define(`B2', `%rbp')
+define(`B2md', `%rbx')
+
+C Variables
+define(`UN', `%r8') C Overlaps D input
+define(`T', `%r10')
+define(`U0', `%r11')
+define(`U2', `%r12')
+define(`Q0', `%r13')
+define(`Q1', `%r14')
+define(`Q2', `%r15')
+
+ABI_SUPPORT(STD64)
+
+ ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_div_qr_1n_pi1)
+ FUNC_ENTRY(6)
+IFDOS(` mov 56(%rsp), %r8 ')
+IFDOS(` mov 64(%rsp), %r9 ')
+ dec UN_INPUT
+ jnz L(first)
+
+ C Just a single 2/1 division.
+ C T, U0 are allocated in scratch registers
+ lea 1(U1), T
+ mov U1, %rax
+ mul DINV
+ mov (UP), U0
+ add U0, %rax
+ adc T, %rdx
+ mov %rdx, T
+ imul D, %rdx
+ sub %rdx, U0
+ cmp U0, %rax
+ lea (U0, D), %rax
+ cmovnc U0, %rax
+ sbb $0, T
+ cmp D, %rax
+ jc L(single_div_done)
+ sub D, %rax
+ add $1, T
+L(single_div_done):
+ mov T, (QP)
+ FUNC_EXIT
+ ret
+L(first):
+ C FIXME: Could delay some of these until we enter the loop.
+ push %r15
+ push %r14
+ push %r13
+ push %r12
+ push %rbx
+ push %rbp
+
+ mov D, B2
+ imul DINV, B2
+ neg B2
+ mov B2, B2md
+ sub D, B2md
+
+ C D not needed until final reduction
+ push D
+ mov UN_INPUT, UN C Clobbers D
+
+ mov DINV, %rax
+ mul U1
+ mov %rax, Q0
+ add U1, %rdx
+ mov %rdx, T
+
+ mov B2, %rax
+ mul U1
+ mov -8(UP, UN, 8), U0
+ mov (UP, UN, 8), U1
+ mov T, (QP, UN, 8)
+ add %rax, U0
+ adc %rdx, U1
+ sbb U2, U2
+ dec UN
+ mov U1, %rax
+ jz L(final)
+ mov $0, R32(Q1)
+
+ ALIGN(16)
+
+ C Loop is 28 instructions, 30 K8/K10 decoder slots, should run
+ C in 10 cycles. At entry, %rax holds an extra copy of U1, Q1
+ C is zero, and carry holds an extra copy of U2.
+L(loop):
+ C {Q2, Q1, Q0} <-- DINV * U1 + B (Q0 + U2 DINV) + B^2 U2
+ C Remains to add in B (U1 + c)
+ cmovc DINV, Q1
+ mov U2, Q2
+ neg Q2
+ mul DINV
+ add %rdx, Q1
+ adc $0, Q2
+ add Q0, Q1
+ mov %rax, Q0
+ mov B2, %rax
+ lea (B2md, U0), T
+ adc $0, Q2
+
+ C {U2, U1, U0} <-- (U0 + U2 B2 -c U) B + U1 B2 + u
+ mul U1
+ and B2, U2
+ add U2, U0
+ cmovnc U0, T
+
+ C {QP+UN, ...} <-- {QP+UN, ...} + {Q2, Q1} + U1 + c
+ adc U1, Q1
+ mov -8(UP, UN, 8), U0
+ adc Q2, 8(QP, UN, 8)
+ jc L(q_incr)
+L(q_incr_done):
+ add %rax, U0
+ mov T, %rax
+ adc %rdx, %rax
+ mov Q1, (QP, UN, 8)
+ mov $0, R32(Q1)
+ sbb U2, U2
+ dec UN
+ mov %rax, U1
+ jnz L(loop)
+
+L(final):
+ pop D
+
+ mov U2, Q1
+ and D, U2
+ sub U2, %rax
+ neg Q1
+
+ mov %rax, U1
+ sub D, %rax
+ cmovc U1, %rax
+ sbb $-1, Q1
+
+ lea 1(%rax), T
+ mul DINV
+ add U0, %rax
+ adc T, %rdx
+ mov %rdx, T
+ imul D, %rdx
+ sub %rdx, U0
+ cmp U0, %rax
+ lea (U0, D), %rax
+ cmovnc U0, %rax
+ sbb $0, T
+ cmp D, %rax
+ jc L(div_done)
+ sub D, %rax
+ add $1, T
+L(div_done):
+ add T, Q0
+ mov Q0, (QP)
+ adc Q1, 8(QP)
+ jnc L(done)
+L(final_q_incr):
+ addq $1, 16(QP)
+ lea 8(QP), QP
+ jc L(final_q_incr)
+
+L(done):
+ pop %rbp
+ pop %rbx
+ pop %r12
+ pop %r13
+ pop %r14
+ pop %r15
+ FUNC_EXIT
+ ret
+
+L(q_incr):
+ C U1 is not live, so use it for indexing
+ lea 16(QP, UN, 8), U1
+L(q_incr_loop):
+ addq $1, (U1)
+ jnc L(q_incr_done)
+ lea 8(U1), U1
+ jmp L(q_incr_loop)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/k8/gmp-mparam.h b/gmp/mpn/x86_64/k8/gmp-mparam.h
new file mode 100644
index 0000000000..df78c38923
--- /dev/null
+++ b/gmp/mpn/x86_64/k8/gmp-mparam.h
@@ -0,0 +1,236 @@
+/* AMD K8 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2012, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+// #undef mpn_sublsh_n
+// #define mpn_sublsh_n(rp,up,vp,n,c) \
+// (((rp) == (up)) ? mpn_submul_1 (rp, vp, n, CNST_LIMB(1) << (c)) \
+// : MPN(mpn_sublsh_n)(rp,up,vp,n,c))
+
+/* 2500 MHz K8 Brisbane */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 13
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 35
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 9
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 16
+
+#define MUL_TOOM22_THRESHOLD 28
+#define MUL_TOOM33_THRESHOLD 81
+#define MUL_TOOM44_THRESHOLD 242
+#define MUL_TOOM6H_THRESHOLD 345
+#define MUL_TOOM8H_THRESHOLD 482
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 153
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 161
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 175
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 166
+
+#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
+#define SQR_TOOM2_THRESHOLD 34
+#define SQR_TOOM3_THRESHOLD 129
+#define SQR_TOOM4_THRESHOLD 527
+#define SQR_TOOM6_THRESHOLD 562
+#define SQR_TOOM8_THRESHOLD 0 /* always */
+
+#define MULMID_TOOM42_THRESHOLD 36
+
+#define MULMOD_BNM1_THRESHOLD 18
+#define SQRMOD_BNM1_THRESHOLD 22
+
+#define MUL_FFT_MODF_THRESHOLD 654 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 654, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 12, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 15, 5}, { 31, 6}, { 27, 7}, { 15, 6}, \
+ { 31, 7}, { 19, 6}, { 39, 7}, { 29, 8}, \
+ { 15, 7}, { 33, 8}, { 17, 7}, { 37, 8}, \
+ { 19, 7}, { 39, 8}, { 23, 7}, { 47, 8}, \
+ { 25, 7}, { 51, 8}, { 43, 9}, { 23, 8}, \
+ { 51, 9}, { 27, 8}, { 57, 9}, { 31, 8}, \
+ { 65, 9}, { 35, 8}, { 71, 9}, { 39, 8}, \
+ { 79, 9}, { 43,10}, { 23, 9}, { 59, 8}, \
+ { 119,10}, { 31, 8}, { 125, 9}, { 71,10}, \
+ { 39, 9}, { 87,10}, { 47, 9}, { 99,10}, \
+ { 55, 9}, { 123,11}, { 31,10}, { 63, 9}, \
+ { 131,10}, { 71, 9}, { 143,10}, { 79, 9}, \
+ { 159,10}, { 87,11}, { 47,10}, { 119,11}, \
+ { 63,10}, { 143,11}, { 79,10}, { 175,11}, \
+ { 95,10}, { 199,11}, { 111,10}, { 223,12}, \
+ { 63,11}, { 143,10}, { 287, 9}, { 575,10}, \
+ { 295,11}, { 159,10}, { 319,11}, { 175,12}, \
+ { 95,11}, { 191,10}, { 383,11}, { 207,10}, \
+ { 415, 9}, { 831,11}, { 223,10}, { 447,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 271,10}, { 543, 9}, { 1087,11}, { 287,10}, \
+ { 575, 9}, { 1151,12}, { 159,11}, { 319,10}, \
+ { 639,11}, { 335,10}, { 671,11}, { 351,10}, \
+ { 703,11}, { 367,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 399,10}, { 799,11}, { 415,10}, \
+ { 831,12}, { 223,11}, { 447,10}, { 895,11}, \
+ { 479,13}, { 127,12}, { 255,11}, { 511,10}, \
+ { 1023,11}, { 543,10}, { 1087,12}, { 287,11}, \
+ { 575,10}, { 1151,11}, { 607,12}, { 319,11}, \
+ { 639,10}, { 1279,11}, { 671,12}, { 351,11}, \
+ { 703,10}, { 1407,13}, { 191,12}, { 383,11}, \
+ { 767,12}, { 415,11}, { 831,12}, { 447,11}, \
+ { 895,12}, { 479,11}, { 959,14}, { 127,13}, \
+ { 255,12}, { 511,11}, { 1023,12}, { 543,11}, \
+ { 1087,12}, { 575,11}, { 1151,12}, { 607,11}, \
+ { 1215,13}, { 319,12}, { 671,11}, { 1343,12}, \
+ { 735,13}, { 383,12}, { 799,11}, { 1599,12}, \
+ { 863,13}, { 447,12}, { 895,11}, { 1791,12}, \
+ { 991,13}, { 511,12}, { 1087,13}, { 575,12}, \
+ { 1215,13}, { 639,12}, { 1343,13}, { 703,12}, \
+ { 1471,14}, { 383,13}, { 767,12}, { 1599,13}, \
+ { 831,12}, { 1663,13}, { 895,12}, { 1791,13}, \
+ { 959,12}, { 1919,14}, { 511,13}, { 1087,12}, \
+ { 2175,13}, { 1215,14}, { 639,13}, { 1471,14}, \
+ { 767,13}, { 1663,14}, { 895,13}, { 1919,15}, \
+ { 511,14}, { 1023,13}, { 2175,14}, { 1151,13}, \
+ { 2367,14}, { 1279,13}, { 2559,14}, { 1407,15}, \
+ { 32768,16}, { 65536,17}, { 131072,18}, { 262144,19}, \
+ { 524288,20}, {1048576,21}, {2097152,22}, {4194304,23}, \
+ {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 205
+#define MUL_FFT_THRESHOLD 11520
+
+#define SQR_FFT_MODF_THRESHOLD 570 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 570, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
+ { 12, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
+ { 14, 5}, { 29, 6}, { 16, 5}, { 33, 6}, \
+ { 29, 7}, { 15, 6}, { 31, 7}, { 16, 6}, \
+ { 33, 7}, { 17, 6}, { 35, 7}, { 33, 8}, \
+ { 17, 7}, { 37, 8}, { 19, 7}, { 40, 8}, \
+ { 21, 7}, { 43, 8}, { 23, 7}, { 47, 8}, \
+ { 25, 7}, { 51, 8}, { 29, 9}, { 15, 8}, \
+ { 37, 9}, { 19, 8}, { 43, 9}, { 23, 8}, \
+ { 51, 9}, { 27, 8}, { 55, 9}, { 31, 8}, \
+ { 63, 9}, { 35, 8}, { 71, 9}, { 39, 8}, \
+ { 79, 9}, { 43,10}, { 23, 9}, { 55,10}, \
+ { 31, 9}, { 71,10}, { 39, 9}, { 83,10}, \
+ { 47, 9}, { 99,10}, { 55, 9}, { 123,11}, \
+ { 31,10}, { 63, 9}, { 127,10}, { 71, 9}, \
+ { 143,10}, { 87,11}, { 47,10}, { 111,12}, \
+ { 31,11}, { 63,10}, { 143,11}, { 79,10}, \
+ { 167,11}, { 95,10}, { 199,11}, { 111,12}, \
+ { 63,11}, { 127, 9}, { 511,11}, { 143,10}, \
+ { 287, 9}, { 575, 8}, { 1151,11}, { 159,10}, \
+ { 319, 9}, { 639,11}, { 175,12}, { 95,11}, \
+ { 191,10}, { 383, 9}, { 767,11}, { 207,10}, \
+ { 415, 9}, { 831,10}, { 431,11}, { 223,10}, \
+ { 447,13}, { 63,12}, { 127,10}, { 511, 9}, \
+ { 1023,10}, { 543, 9}, { 1087,11}, { 287,10}, \
+ { 575, 9}, { 1151,12}, { 159,11}, { 319,10}, \
+ { 639, 9}, { 1279,11}, { 335,10}, { 671,11}, \
+ { 351,10}, { 703,11}, { 367,12}, { 191,11}, \
+ { 383,10}, { 767,11}, { 399,10}, { 799,11}, \
+ { 415,10}, { 831,11}, { 431,12}, { 223,11}, \
+ { 447,10}, { 895,11}, { 463,13}, { 127,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087,12}, \
+ { 287,11}, { 575,10}, { 1151,11}, { 607,10}, \
+ { 1215,12}, { 319,11}, { 639,10}, { 1279,11}, \
+ { 671,12}, { 351,11}, { 703,10}, { 1407,13}, \
+ { 191,12}, { 383,11}, { 767,10}, { 1535,11}, \
+ { 799,12}, { 415,11}, { 831,12}, { 447,11}, \
+ { 895,12}, { 479,14}, { 127,12}, { 511,11}, \
+ { 1023,12}, { 543,11}, { 1087,12}, { 575,11}, \
+ { 1151,12}, { 607,11}, { 1215,13}, { 319,12}, \
+ { 639,11}, { 1279,12}, { 671,11}, { 1343,12}, \
+ { 703,11}, { 1407,12}, { 735,13}, { 383,12}, \
+ { 799,11}, { 1599,12}, { 863,13}, { 447,12}, \
+ { 959,13}, { 511,12}, { 1087,13}, { 575,12}, \
+ { 1215,13}, { 639,12}, { 1343,13}, { 703,12}, \
+ { 1471,14}, { 383,13}, { 767,12}, { 1599,13}, \
+ { 831,12}, { 1663,13}, { 895,12}, { 1791,13}, \
+ { 959,14}, { 511,13}, { 1023,12}, { 2047,13}, \
+ { 1215,14}, { 639,13}, { 1471,14}, { 767,13}, \
+ { 1663,14}, { 895,13}, { 1855,15}, { 511,14}, \
+ { 1023,13}, { 2111,14}, { 1151,13}, { 2303,14}, \
+ { 1407,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 214
+#define SQR_FFT_THRESHOLD 5760
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 61
+#define MULLO_MUL_N_THRESHOLD 22906
+
+#define DC_DIV_QR_THRESHOLD 51
+#define DC_DIVAPPR_Q_THRESHOLD 264
+#define DC_BDIV_QR_THRESHOLD 38
+#define DC_BDIV_Q_THRESHOLD 170
+
+#define INV_MULMOD_BNM1_THRESHOLD 67
+#define INV_NEWTON_THRESHOLD 246
+#define INV_APPR_THRESHOLD 244
+
+#define BINV_NEWTON_THRESHOLD 252
+#define REDC_1_TO_REDC_2_THRESHOLD 35
+#define REDC_2_TO_REDC_N_THRESHOLD 84
+
+#define MU_DIV_QR_THRESHOLD 2089
+#define MU_DIVAPPR_Q_THRESHOLD 1752
+#define MUPI_DIV_QR_THRESHOLD 93
+#define MU_BDIV_QR_THRESHOLD 1718
+#define MU_BDIV_Q_THRESHOLD 1895
+
+#define POWM_SEC_TABLE 2,16,194,904,2177
+
+#define MATRIX22_STRASSEN_THRESHOLD 21
+#define HGCD_THRESHOLD 148
+#define HGCD_APPR_THRESHOLD 185
+#define HGCD_REDUCE_THRESHOLD 4120
+#define GCD_DC_THRESHOLD 562
+#define GCDEXT_DC_THRESHOLD 501
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 17
+#define GET_STR_PRECOMPUTE_THRESHOLD 29
+#define SET_STR_DC_THRESHOLD 268
+#define SET_STR_PRECOMPUTE_THRESHOLD 1787
+
+#define FAC_DSC_THRESHOLD 1240
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/x86_64/k8/mul_basecase.asm b/gmp/mpn/x86_64/k8/mul_basecase.asm
new file mode 100644
index 0000000000..ca2efb9b2f
--- /dev/null
+++ b/gmp/mpn/x86_64/k8/mul_basecase.asm
@@ -0,0 +1,469 @@
+dnl AMD64 mpn_mul_basecase.
+
+dnl Contributed to the GNU project by Torbjorn Granlund and David Harvey.
+
+dnl Copyright 2008, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.375
+C AMD K10 2.375
+C Intel P4 15-16
+C Intel core2 4.45
+C Intel corei 4.35
+C Intel atom ?
+C VIA nano 4.5
+
+C The inner loops of this code are the result of running a code generation and
+C optimization tool suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * Use fewer registers. (how??? I can't see it -- david)
+C * Avoid some "mov $0,r" and instead use "xor r,r".
+C * Can the top of each L(addmul_outer_n) prologue be folded into the
+C mul_1/mul_2 prologues, saving a LEA (%rip)? It would slow down the
+C case where vn = 1 or 2; is it worth it?
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param',`%rdx')
+define(`vp', `%rcx')
+define(`vn', `%r8')
+
+define(`v0', `%r12')
+define(`v1', `%r9')
+
+define(`w0', `%rbx')
+define(`w1', `%r15')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+
+define(`n', `%r11')
+define(`outer_addr', `%r14')
+define(`un', `%r13')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_basecase)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ xor R32(un), R32(un)
+ mov (up), %rax
+ mov (vp), v0
+
+ sub un_param, un C rdx used by mul
+ mov un, n
+ mov R32(un_param), R32(w0)
+
+ lea (rp,un_param,8), rp
+ lea (up,un_param,8), up
+
+ mul v0
+
+ test $1, R8(vn)
+ jz L(mul_2)
+
+C ===========================================================
+C mul_1 for vp[0] if vn is odd
+
+L(mul_1):
+ and $3, R32(w0)
+ jz L(mul_1_prologue_0)
+ cmp $2, R32(w0)
+ jc L(mul_1_prologue_1)
+ jz L(mul_1_prologue_2)
+
+L(mul_1_prologue_3):
+ add $-1, n
+ lea L(addmul_outer_3)(%rip), outer_addr
+ mov %rax, w3
+ mov %rdx, w0
+ jmp L(mul_1_entry_3)
+
+L(mul_1_prologue_0):
+ mov %rax, w2
+ mov %rdx, w3 C note: already w0 == 0
+ lea L(addmul_outer_0)(%rip), outer_addr
+ jmp L(mul_1_entry_0)
+
+L(mul_1_prologue_1):
+ cmp $-1, un
+ jne 2f
+ mov %rax, -8(rp)
+ mov %rdx, (rp)
+ jmp L(ret)
+2: add $1, n
+ lea L(addmul_outer_1)(%rip), outer_addr
+ mov %rax, w1
+ mov %rdx, w2
+ xor R32(w3), R32(w3)
+ mov (up,n,8), %rax
+ jmp L(mul_1_entry_1)
+
+L(mul_1_prologue_2):
+ add $-2, n
+ lea L(addmul_outer_2)(%rip), outer_addr
+ mov %rax, w0
+ mov %rdx, w1
+ mov 24(up,n,8), %rax
+ xor R32(w2), R32(w2)
+ xor R32(w3), R32(w3)
+ jmp L(mul_1_entry_2)
+
+
+ C this loop is 10 c/loop = 2.5 c/l on K8, for all up/rp alignments
+
+ ALIGN(16)
+L(mul_1_top):
+ mov w0, -16(rp,n,8)
+ add %rax, w1
+ mov (up,n,8), %rax
+ adc %rdx, w2
+L(mul_1_entry_1):
+ xor R32(w0), R32(w0)
+ mul v0
+ mov w1, -8(rp,n,8)
+ add %rax, w2
+ adc %rdx, w3
+L(mul_1_entry_0):
+ mov 8(up,n,8), %rax
+ mul v0
+ mov w2, (rp,n,8)
+ add %rax, w3
+ adc %rdx, w0
+L(mul_1_entry_3):
+ mov 16(up,n,8), %rax
+ mul v0
+ mov w3, 8(rp,n,8)
+ xor R32(w2), R32(w2) C zero
+ mov w2, w3 C zero
+ add %rax, w0
+ mov 24(up,n,8), %rax
+ mov w2, w1 C zero
+ adc %rdx, w1
+L(mul_1_entry_2):
+ mul v0
+ add $4, n
+ js L(mul_1_top)
+
+ mov w0, -16(rp)
+ add %rax, w1
+ mov w1, -8(rp)
+ adc %rdx, w2
+ mov w2, (rp)
+
+ add $-1, vn C vn -= 1
+ jz L(ret)
+
+ mov 8(vp), v0
+ mov 16(vp), v1
+
+ lea 8(vp), vp C vp += 1
+ lea 8(rp), rp C rp += 1
+
+ jmp *outer_addr
+
+C ===========================================================
+C mul_2 for vp[0], vp[1] if vn is even
+
+ ALIGN(16)
+L(mul_2):
+ mov 8(vp), v1
+
+ and $3, R32(w0)
+ jz L(mul_2_prologue_0)
+ cmp $2, R32(w0)
+ jz L(mul_2_prologue_2)
+ jc L(mul_2_prologue_1)
+
+L(mul_2_prologue_3):
+ lea L(addmul_outer_3)(%rip), outer_addr
+ add $2, n
+ mov %rax, -16(rp,n,8)
+ mov %rdx, w2
+ xor R32(w3), R32(w3)
+ xor R32(w0), R32(w0)
+ mov -16(up,n,8), %rax
+ jmp L(mul_2_entry_3)
+
+ ALIGN(16)
+L(mul_2_prologue_0):
+ add $3, n
+ mov %rax, w0
+ mov %rdx, w1
+ xor R32(w2), R32(w2)
+ mov -24(up,n,8), %rax
+ lea L(addmul_outer_0)(%rip), outer_addr
+ jmp L(mul_2_entry_0)
+
+ ALIGN(16)
+L(mul_2_prologue_1):
+ mov %rax, w3
+ mov %rdx, w0
+ xor R32(w1), R32(w1)
+ lea L(addmul_outer_1)(%rip), outer_addr
+ jmp L(mul_2_entry_1)
+
+ ALIGN(16)
+L(mul_2_prologue_2):
+ add $1, n
+ lea L(addmul_outer_2)(%rip), outer_addr
+ mov $0, R32(w0)
+ mov $0, R32(w1)
+ mov %rax, w2
+ mov -8(up,n,8), %rax
+ mov %rdx, w3
+ jmp L(mul_2_entry_2)
+
+ C this loop is 18 c/loop = 2.25 c/l on K8, for all up/rp alignments
+
+ ALIGN(16)
+L(mul_2_top):
+ mov -32(up,n,8), %rax
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov -24(up,n,8), %rax
+ xor R32(w2), R32(w2)
+ mul v0
+ add %rax, w0
+ mov -24(up,n,8), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+L(mul_2_entry_0):
+ mul v1
+ add %rax, w1
+ mov w0, -24(rp,n,8)
+ adc %rdx, w2
+ mov -16(up,n,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ mov -16(up,n,8), %rax
+ adc $0, R32(w3)
+ mov $0, R32(w0)
+ mov w1, -16(rp,n,8)
+L(mul_2_entry_3):
+ mul v1
+ add %rax, w2
+ mov -8(up,n,8), %rax
+ adc %rdx, w3
+ mov $0, R32(w1)
+ mul v0
+ add %rax, w2
+ mov -8(up,n,8), %rax
+ adc %rdx, w3
+ adc R32(w1), R32(w0) C adc $0, w0
+L(mul_2_entry_2):
+ mul v1
+ add %rax, w3
+ mov w2, -8(rp,n,8)
+ adc %rdx, w0
+ mov (up,n,8), %rax
+ mul v0
+ add %rax, w3
+ adc %rdx, w0
+ adc $0, R32(w1)
+L(mul_2_entry_1):
+ add $4, n
+ mov w3, -32(rp,n,8)
+ js L(mul_2_top)
+
+ mov -32(up,n,8), %rax C FIXME: n is constant
+ mul v1
+ add %rax, w0
+ mov w0, (rp)
+ adc %rdx, w1
+ mov w1, 8(rp)
+
+ add $-2, vn C vn -= 2
+ jz L(ret)
+
+ mov 16(vp), v0
+ mov 24(vp), v1
+
+ lea 16(vp), vp C vp += 2
+ lea 16(rp), rp C rp += 2
+
+ jmp *outer_addr
+
+
+C ===========================================================
+C addmul_2 for remaining vp's
+
+ C in the following prologues, we reuse un to store the
+ C adjusted value of n that is reloaded on each iteration
+
+L(addmul_outer_0):
+ add $3, un
+ lea 0(%rip), outer_addr
+
+ mov un, n
+ mov -24(up,un,8), %rax
+ mul v0
+ mov %rax, w0
+ mov -24(up,un,8), %rax
+ mov %rdx, w1
+ xor R32(w2), R32(w2)
+ jmp L(addmul_entry_0)
+
+L(addmul_outer_1):
+ mov un, n
+ mov (up,un,8), %rax
+ mul v0
+ mov %rax, w3
+ mov (up,un,8), %rax
+ mov %rdx, w0
+ xor R32(w1), R32(w1)
+ jmp L(addmul_entry_1)
+
+L(addmul_outer_2):
+ add $1, un
+ lea 0(%rip), outer_addr
+
+ mov un, n
+ mov -8(up,un,8), %rax
+ mul v0
+ xor R32(w0), R32(w0)
+ mov %rax, w2
+ xor R32(w1), R32(w1)
+ mov %rdx, w3
+ mov -8(up,un,8), %rax
+ jmp L(addmul_entry_2)
+
+L(addmul_outer_3):
+ add $2, un
+ lea 0(%rip), outer_addr
+
+ mov un, n
+ mov -16(up,un,8), %rax
+ xor R32(w3), R32(w3)
+ mul v0
+ mov %rax, w1
+ mov -16(up,un,8), %rax
+ mov %rdx, w2
+ jmp L(addmul_entry_3)
+
+ C this loop is 19 c/loop = 2.375 c/l on K8, for all up/rp alignments
+
+ ALIGN(16)
+L(addmul_top):
+ add w3, -32(rp,n,8)
+ adc %rax, w0
+ mov -24(up,n,8), %rax
+ adc %rdx, w1
+ xor R32(w2), R32(w2)
+ mul v0
+ add %rax, w0
+ mov -24(up,n,8), %rax
+ adc %rdx, w1
+ adc R32(w2), R32(w2) C adc $0, w2
+L(addmul_entry_0):
+ mul v1
+ xor R32(w3), R32(w3)
+ add w0, -24(rp,n,8)
+ adc %rax, w1
+ mov -16(up,n,8), %rax
+ adc %rdx, w2
+ mul v0
+ add %rax, w1
+ mov -16(up,n,8), %rax
+ adc %rdx, w2
+ adc $0, R32(w3)
+L(addmul_entry_3):
+ mul v1
+ add w1, -16(rp,n,8)
+ adc %rax, w2
+ mov -8(up,n,8), %rax
+ adc %rdx, w3
+ mul v0
+ xor R32(w0), R32(w0)
+ add %rax, w2
+ adc %rdx, w3
+ mov $0, R32(w1)
+ mov -8(up,n,8), %rax
+ adc R32(w1), R32(w0) C adc $0, w0
+L(addmul_entry_2):
+ mul v1
+ add w2, -8(rp,n,8)
+ adc %rax, w3
+ adc %rdx, w0
+ mov (up,n,8), %rax
+ mul v0
+ add %rax, w3
+ mov (up,n,8), %rax
+ adc %rdx, w0
+ adc $0, R32(w1)
+L(addmul_entry_1):
+ mul v1
+ add $4, n
+ js L(addmul_top)
+
+ add w3, -8(rp)
+ adc %rax, w0
+ mov w0, (rp)
+ adc %rdx, w1
+ mov w1, 8(rp)
+
+ add $-2, vn C vn -= 2
+ jz L(ret)
+
+ lea 16(rp), rp C rp += 2
+ lea 16(vp), vp C vp += 2
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ jmp *outer_addr
+
+ ALIGN(16)
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/k8/mullo_basecase.asm b/gmp/mpn/x86_64/k8/mullo_basecase.asm
new file mode 100644
index 0000000000..fa00f4234a
--- /dev/null
+++ b/gmp/mpn/x86_64/k8/mullo_basecase.asm
@@ -0,0 +1,436 @@
+dnl AMD64 mpn_mullo_basecase.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjorn Granlund.
+
+C NOTES
+C * There is a major stupidity in that we call mpn_mul_1 initially, for a
+C large trip count. Instead, we should start with mul_2 for any operand
+C size congruence class.
+C * Stop iterating addmul_2 earlier, falling into straight-line triangle code
+C for the last 2-3 iterations.
+C * Perhaps implement n=4 special code.
+C * The reload of the outer loop jump address hurts branch prediction.
+C * The addmul_2 loop ends with an MUL whose high part is not used upon loop
+C exit.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp_param', `%rdx')
+define(`n', `%rcx')
+
+define(`vp', `%r11')
+define(`outer_addr', `%r8')
+define(`j', `%r9')
+define(`v0', `%r13')
+define(`v1', `%r14')
+define(`w0', `%rbx')
+define(`w1', `%r15')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mullo_basecase)
+ FUNC_ENTRY(4)
+ cmp $4, n
+ jge L(gen)
+ mov (up), %rax C u0
+ mov (vp_param), %r8 C v0
+
+ lea L(tab)(%rip), %r9
+ifdef(`PIC',
+` movslq (%r9,%rcx,4), %r10
+ add %r10, %r9
+ jmp *%r9
+',`
+ jmp *(%r9,n,8)
+')
+ JUMPTABSECT
+ ALIGN(8)
+L(tab): JMPENT( L(tab), L(tab)) C not allowed
+ JMPENT( L(1), L(tab)) C 1
+ JMPENT( L(2), L(tab)) C 2
+ JMPENT( L(3), L(tab)) C 3
+dnl JMPENT( L(0m4), L(tab)) C 4
+dnl JMPENT( L(1m4), L(tab)) C 5
+dnl JMPENT( L(2m4), L(tab)) C 6
+dnl JMPENT( L(3m4), L(tab)) C 7
+dnl JMPENT( L(0m4), L(tab)) C 8
+dnl JMPENT( L(1m4), L(tab)) C 9
+dnl JMPENT( L(2m4), L(tab)) C 10
+dnl JMPENT( L(3m4), L(tab)) C 11
+ TEXT
+
+L(1): imul %r8, %rax
+ mov %rax, (rp)
+ FUNC_EXIT()
+ ret
+
+L(2): mov 8(vp_param), %r11
+ imul %rax, %r11 C u0 x v1
+ mul %r8 C u0 x v0
+ mov %rax, (rp)
+ imul 8(up), %r8 C u1 x v0
+ lea (%r11, %rdx), %rax
+ add %r8, %rax
+ mov %rax, 8(rp)
+ FUNC_EXIT()
+ ret
+
+L(3): mov 8(vp_param), %r9 C v1
+ mov 16(vp_param), %r11
+ mul %r8 C u0 x v0 -> <r1,r0>
+ mov %rax, (rp) C r0
+ mov (up), %rax C u0
+ mov %rdx, %rcx C r1
+ mul %r9 C u0 x v1 -> <r2,r1>
+ imul 8(up), %r9 C u1 x v1 -> r2
+ mov 16(up), %r10
+ imul %r8, %r10 C u2 x v0 -> r2
+ add %rax, %rcx
+ adc %rdx, %r9
+ add %r10, %r9
+ mov 8(up), %rax C u1
+ mul %r8 C u1 x v0 -> <r2,r1>
+ add %rax, %rcx
+ adc %rdx, %r9
+ mov %r11, %rax
+ imul (up), %rax C u0 x v2 -> r2
+ add %rax, %r9
+ mov %rcx, 8(rp)
+ mov %r9, 16(rp)
+ FUNC_EXIT()
+ ret
+
+L(0m4):
+L(1m4):
+L(2m4):
+L(3m4):
+L(gen): push %rbx
+ push %rbp
+ push %r13
+ push %r14
+ push %r15
+
+ mov (up), %rax
+ mov (vp_param), v0
+ mov vp_param, vp
+
+ lea (rp,n,8), rp
+ lea (up,n,8), up
+ neg n
+
+ mul v0
+
+ test $1, R8(n)
+ jz L(mul_2)
+
+L(mul_1):
+ lea -8(rp), rp
+ lea -8(up), up
+ test $2, R8(n)
+ jnz L(mul_1_prologue_3)
+
+L(mul_1_prologue_2): C n = 7, 11, 15, ...
+ lea -1(n), j
+ lea L(addmul_outer_1)(%rip), outer_addr
+ mov %rax, w0
+ mov %rdx, w1
+ xor R32(w2), R32(w2)
+ xor R32(w3), R32(w3)
+ mov 16(up,n,8), %rax
+ jmp L(mul_1_entry_2)
+
+L(mul_1_prologue_3): C n = 5, 9, 13, ...
+ lea 1(n), j
+ lea L(addmul_outer_3)(%rip), outer_addr
+ mov %rax, w2
+ mov %rdx, w3
+ xor R32(w0), R32(w0)
+ jmp L(mul_1_entry_0)
+
+ ALIGN(16)
+L(mul_1_top):
+ mov w0, -16(rp,j,8)
+ add %rax, w1
+ mov (up,j,8), %rax
+ adc %rdx, w2
+ xor R32(w0), R32(w0)
+ mul v0
+ mov w1, -8(rp,j,8)
+ add %rax, w2
+ adc %rdx, w3
+L(mul_1_entry_0):
+ mov 8(up,j,8), %rax
+ mul v0
+ mov w2, (rp,j,8)
+ add %rax, w3
+ adc %rdx, w0
+ mov 16(up,j,8), %rax
+ mul v0
+ mov w3, 8(rp,j,8)
+ xor R32(w2), R32(w2) C zero
+ mov w2, w3 C zero
+ add %rax, w0
+ mov 24(up,j,8), %rax
+ mov w2, w1 C zero
+ adc %rdx, w1
+L(mul_1_entry_2):
+ mul v0
+ add $4, j
+ js L(mul_1_top)
+
+ mov w0, -16(rp)
+ add %rax, w1
+ mov w1, -8(rp)
+ adc %rdx, w2
+
+ imul (up), v0
+ add v0, w2
+ mov w2, (rp)
+
+ add $1, n
+ jz L(ret)
+
+ mov 8(vp), v0
+ mov 16(vp), v1
+
+ lea 16(up), up
+ lea 8(vp), vp
+ lea 24(rp), rp
+
+ jmp *outer_addr
+
+
+L(mul_2):
+ mov 8(vp), v1
+ test $2, R8(n)
+ jz L(mul_2_prologue_3)
+
+ ALIGN(16)
+L(mul_2_prologue_1):
+ lea 0(n), j
+ mov %rax, w3
+ mov %rdx, w0
+ xor R32(w1), R32(w1)
+ mov (up,n,8), %rax
+ lea L(addmul_outer_3)(%rip), outer_addr
+ jmp L(mul_2_entry_1)
+
+ ALIGN(16)
+L(mul_2_prologue_3):
+ lea 2(n), j
+ mov $0, R32(w3)
+ mov %rax, w1
+ mov (up,n,8), %rax
+ mov %rdx, w2
+ lea L(addmul_outer_1)(%rip), outer_addr
+ jmp L(mul_2_entry_3)
+
+ ALIGN(16)
+L(mul_2_top):
+ mov -32(up,j,8), %rax
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov -24(up,j,8), %rax
+ xor R32(w2), R32(w2)
+ mul v0
+ add %rax, w0
+ mov -24(up,j,8), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+ mul v1
+ add %rax, w1
+ mov w0, -24(rp,j,8)
+ adc %rdx, w2
+ mov -16(up,j,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ mov -16(up,j,8), %rax
+ adc $0, R32(w3)
+L(mul_2_entry_3):
+ mov $0, R32(w0)
+ mov w1, -16(rp,j,8)
+ mul v1
+ add %rax, w2
+ mov -8(up,j,8), %rax
+ adc %rdx, w3
+ mov $0, R32(w1)
+ mul v0
+ add %rax, w2
+ mov -8(up,j,8), %rax
+ adc %rdx, w3
+ adc R32(w1), R32(w0)
+ mul v1
+ add %rax, w3
+ mov w2, -8(rp,j,8)
+ adc %rdx, w0
+ mov (up,j,8), %rax
+ mul v0
+ add %rax, w3
+ adc %rdx, w0
+ adc $0, R32(w1)
+L(mul_2_entry_1):
+ add $4, j
+ mov w3, -32(rp,j,8)
+ js L(mul_2_top)
+
+ imul -16(up), v1
+ add v1, w0
+ imul -8(up), v0
+ add v0, w0
+ mov w0, -8(rp)
+
+ add $2, n
+ jz L(ret)
+
+ mov 16(vp), v0
+ mov 24(vp), v1
+
+ lea 16(vp), vp
+ lea 16(rp), rp
+
+ jmp *outer_addr
+
+
+L(addmul_outer_1):
+ lea -2(n), j
+ mov -16(up,n,8), %rax
+ mul v0
+ mov %rax, w3
+ mov -16(up,n,8), %rax
+ mov %rdx, w0
+ xor R32(w1), R32(w1)
+ lea L(addmul_outer_3)(%rip), outer_addr
+ jmp L(addmul_entry_1)
+
+L(addmul_outer_3):
+ lea 0(n), j
+ mov -16(up,n,8), %rax
+ xor R32(w3), R32(w3)
+ mul v0
+ mov %rax, w1
+ mov -16(up,n,8), %rax
+ mov %rdx, w2
+ lea L(addmul_outer_1)(%rip), outer_addr
+ jmp L(addmul_entry_3)
+
+ ALIGN(16)
+L(addmul_top):
+ add w3, -32(rp,j,8)
+ adc %rax, w0
+ mov -24(up,j,8), %rax
+ adc %rdx, w1
+ xor R32(w2), R32(w2)
+ mul v0
+ add %rax, w0
+ mov -24(up,j,8), %rax
+ adc %rdx, w1
+ adc R32(w2), R32(w2)
+ mul v1
+ xor R32(w3), R32(w3)
+ add w0, -24(rp,j,8)
+ adc %rax, w1
+ mov -16(up,j,8), %rax
+ adc %rdx, w2
+ mul v0
+ add %rax, w1
+ mov -16(up,j,8), %rax
+ adc %rdx, w2
+ adc $0, R32(w3)
+L(addmul_entry_3):
+ mul v1
+ add w1, -16(rp,j,8)
+ adc %rax, w2
+ mov -8(up,j,8), %rax
+ adc %rdx, w3
+ mul v0
+ xor R32(w0), R32(w0)
+ add %rax, w2
+ adc %rdx, w3
+ mov $0, R32(w1)
+ mov -8(up,j,8), %rax
+ adc R32(w1), R32(w0)
+ mul v1
+ add w2, -8(rp,j,8)
+ adc %rax, w3
+ adc %rdx, w0
+ mov (up,j,8), %rax
+ mul v0
+ add %rax, w3
+ mov (up,j,8), %rax
+ adc %rdx, w0
+ adc $0, R32(w1)
+L(addmul_entry_1):
+ mul v1
+ add $4, j
+ js L(addmul_top)
+
+ add w3, -32(rp)
+ adc %rax, w0
+
+ imul -24(up), v0
+ add v0, w0
+ add w0, -24(rp)
+
+ add $2, n
+ jns L(ret)
+
+ lea 16(vp), vp
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ lea -16(up), up
+
+ jmp *outer_addr
+
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/k8/mulmid_basecase.asm b/gmp/mpn/x86_64/k8/mulmid_basecase.asm
new file mode 100644
index 0000000000..86f1414ed8
--- /dev/null
+++ b/gmp/mpn/x86_64/k8/mulmid_basecase.asm
@@ -0,0 +1,559 @@
+dnl AMD64 mpn_mulmid_basecase
+
+dnl Contributed by David Harvey.
+
+dnl Copyright 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+C cycles/limb
+C K8,K9: 2.375 (2.5 when un - vn is "small")
+C K10: ?
+C P4: ?
+C P6-15: ?
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`un_param',`%rdx')
+define(`vp_param',`%rcx')
+define(`vn', `%r8')
+
+define(`v0', `%r12')
+define(`v1', `%r9')
+
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+
+define(`n', `%r11')
+define(`outer_addr', `%r14')
+define(`un', `%r13')
+define(`vp', `%r15')
+
+define(`vp_inner', `%r10')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mulmid_basecase)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov vp_param, vp
+
+ C use un for row length (= un_param - vn + 1)
+ lea 1(un_param), un
+ sub vn, un
+
+ lea (rp,un,8), rp
+
+ cmp $4, un C TODO: needs tuning
+ jc L(diagonal)
+
+ lea (up,un_param,8), up
+
+ test $1, vn
+ jz L(mul_2)
+
+C ===========================================================
+C mul_1 for vp[0] if vn is odd
+
+L(mul_1):
+ mov R32(un), R32(w0)
+
+ neg un
+ mov (up,un,8), %rax
+ mov (vp), v0
+ mul v0
+
+ and $-4, un C round down to multiple of 4
+ mov un, n
+
+ and $3, R32(w0)
+ jz L(mul_1_prologue_0)
+ cmp $2, R32(w0)
+ jc L(mul_1_prologue_1)
+ jz L(mul_1_prologue_2)
+
+L(mul_1_prologue_3):
+ mov %rax, w3
+ mov %rdx, w0
+ lea L(addmul_prologue_3)(%rip), outer_addr
+ jmp L(mul_1_entry_3)
+
+ ALIGN(16)
+L(mul_1_prologue_0):
+ mov %rax, w2
+ mov %rdx, w3 C note already w0 == 0
+ lea L(addmul_prologue_0)(%rip), outer_addr
+ jmp L(mul_1_entry_0)
+
+ ALIGN(16)
+L(mul_1_prologue_1):
+ add $4, n
+ mov %rax, w1
+ mov %rdx, w2
+ mov $0, R32(w3)
+ mov (up,n,8), %rax
+ lea L(addmul_prologue_1)(%rip), outer_addr
+ jmp L(mul_1_entry_1)
+
+ ALIGN(16)
+L(mul_1_prologue_2):
+ mov %rax, w0
+ mov %rdx, w1
+ mov 24(up,n,8), %rax
+ mov $0, R32(w2)
+ mov $0, R32(w3)
+ lea L(addmul_prologue_2)(%rip), outer_addr
+ jmp L(mul_1_entry_2)
+
+
+ C this loop is 10 c/loop = 2.5 c/l on K8
+
+ ALIGN(16)
+L(mul_1_top):
+ mov w0, -16(rp,n,8)
+ add %rax, w1
+ mov (up,n,8), %rax
+ adc %rdx, w2
+L(mul_1_entry_1):
+ mov $0, R32(w0)
+ mul v0
+ mov w1, -8(rp,n,8)
+ add %rax, w2
+ adc %rdx, w3
+L(mul_1_entry_0):
+ mov 8(up,n,8), %rax
+ mul v0
+ mov w2, (rp,n,8)
+ add %rax, w3
+ adc %rdx, w0
+L(mul_1_entry_3):
+ mov 16(up,n,8), %rax
+ mul v0
+ mov w3, 8(rp,n,8)
+ mov $0, R32(w2) C zero
+ mov w2, w3 C zero
+ add %rax, w0
+ mov 24(up,n,8), %rax
+ mov w2, w1 C zero
+ adc %rdx, w1
+L(mul_1_entry_2):
+ mul v0
+ add $4, n
+ js L(mul_1_top)
+
+ mov w0, -16(rp)
+ add %rax, w1
+ mov w1, -8(rp)
+ mov w2, 8(rp) C zero last limb of output
+ adc %rdx, w2
+ mov w2, (rp)
+
+ dec vn
+ jz L(ret)
+
+ lea -8(up), up
+ lea 8(vp), vp
+
+ mov un, n
+ mov (vp), v0
+ mov 8(vp), v1
+
+ jmp *outer_addr
+
+C ===========================================================
+C mul_2 for vp[0], vp[1] if vn is even
+
+ ALIGN(16)
+L(mul_2):
+ mov R32(un), R32(w0)
+
+ neg un
+ mov -8(up,un,8), %rax
+ mov (vp), v0
+ mov 8(vp), v1
+ mul v1
+
+ and $-4, un C round down to multiple of 4
+ mov un, n
+
+ and $3, R32(w0)
+ jz L(mul_2_prologue_0)
+ cmp $2, R32(w0)
+ jc L(mul_2_prologue_1)
+ jz L(mul_2_prologue_2)
+
+L(mul_2_prologue_3):
+ mov %rax, w1
+ mov %rdx, w2
+ lea L(addmul_prologue_3)(%rip), outer_addr
+ jmp L(mul_2_entry_3)
+
+ ALIGN(16)
+L(mul_2_prologue_0):
+ mov %rax, w0
+ mov %rdx, w1
+ lea L(addmul_prologue_0)(%rip), outer_addr
+ jmp L(mul_2_entry_0)
+
+ ALIGN(16)
+L(mul_2_prologue_1):
+ mov %rax, w3
+ mov %rdx, w0
+ mov $0, R32(w1)
+ lea L(addmul_prologue_1)(%rip), outer_addr
+ jmp L(mul_2_entry_1)
+
+ ALIGN(16)
+L(mul_2_prologue_2):
+ mov %rax, w2
+ mov %rdx, w3
+ mov $0, R32(w0)
+ mov 16(up,n,8), %rax
+ lea L(addmul_prologue_2)(%rip), outer_addr
+ jmp L(mul_2_entry_2)
+
+
+ C this loop is 18 c/loop = 2.25 c/l on K8
+
+ ALIGN(16)
+L(mul_2_top):
+ mov -8(up,n,8), %rax
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+L(mul_2_entry_0):
+ mov $0, R32(w2)
+ mov (up,n,8), %rax
+ mul v0
+ add %rax, w0
+ mov (up,n,8), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+ mul v1
+ add %rax, w1
+ mov w0, (rp,n,8)
+ adc %rdx, w2
+L(mul_2_entry_3):
+ mov 8(up,n,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ mov $0, R32(w0)
+ adc $0, R32(w3)
+ mov 8(up,n,8), %rax
+ mov w1, 8(rp,n,8)
+ mul v1
+ add %rax, w2
+ mov 16(up,n,8), %rax
+ adc %rdx, w3
+L(mul_2_entry_2):
+ mov $0, R32(w1)
+ mul v0
+ add %rax, w2
+ mov 16(up,n,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ add %rax, w3
+ mov w2, 16(rp,n,8)
+ adc %rdx, w0
+L(mul_2_entry_1):
+ mov 24(up,n,8), %rax
+ mul v0
+ add %rax, w3
+ adc %rdx, w0
+ adc $0, R32(w1)
+ add $4, n
+ mov w3, -8(rp,n,8)
+ jnz L(mul_2_top)
+
+ mov w0, (rp)
+ mov w1, 8(rp)
+
+ sub $2, vn
+ jz L(ret)
+
+ lea 16(vp), vp
+ lea -16(up), up
+
+ mov un, n
+ mov (vp), v0
+ mov 8(vp), v1
+
+ jmp *outer_addr
+
+C ===========================================================
+C addmul_2 for remaining vp's
+
+ ALIGN(16)
+L(addmul_prologue_0):
+ mov -8(up,n,8), %rax
+ mul v1
+ mov %rax, w1
+ mov %rdx, w2
+ mov $0, R32(w3)
+ jmp L(addmul_entry_0)
+
+ ALIGN(16)
+L(addmul_prologue_1):
+ mov 16(up,n,8), %rax
+ mul v1
+ mov %rax, w0
+ mov %rdx, w1
+ mov $0, R32(w2)
+ mov 24(up,n,8), %rax
+ jmp L(addmul_entry_1)
+
+ ALIGN(16)
+L(addmul_prologue_2):
+ mov 8(up,n,8), %rax
+ mul v1
+ mov %rax, w3
+ mov %rdx, w0
+ mov $0, R32(w1)
+ jmp L(addmul_entry_2)
+
+ ALIGN(16)
+L(addmul_prologue_3):
+ mov (up,n,8), %rax
+ mul v1
+ mov %rax, w2
+ mov %rdx, w3
+ mov $0, R32(w0)
+ mov $0, R32(w1)
+ jmp L(addmul_entry_3)
+
+ C this loop is 19 c/loop = 2.375 c/l on K8
+
+ ALIGN(16)
+L(addmul_top):
+ mov $0, R32(w3)
+ add %rax, w0
+ mov -8(up,n,8), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+ mul v1
+ add w0, -8(rp,n,8)
+ adc %rax, w1
+ adc %rdx, w2
+L(addmul_entry_0):
+ mov (up,n,8), %rax
+ mul v0
+ add %rax, w1
+ mov (up,n,8), %rax
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mul v1
+ add w1, (rp,n,8)
+ mov $0, R32(w1)
+ adc %rax, w2
+ mov $0, R32(w0)
+ adc %rdx, w3
+L(addmul_entry_3):
+ mov 8(up,n,8), %rax
+ mul v0
+ add %rax, w2
+ mov 8(up,n,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ add w2, 8(rp,n,8)
+ adc %rax, w3
+ adc %rdx, w0
+L(addmul_entry_2):
+ mov 16(up,n,8), %rax
+ mul v0
+ add %rax, w3
+ mov 16(up,n,8), %rax
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add w3, 16(rp,n,8)
+ nop C don't ask...
+ adc %rax, w0
+ mov $0, R32(w2)
+ mov 24(up,n,8), %rax
+ adc %rdx, w1
+L(addmul_entry_1):
+ mul v0
+ add $4, n
+ jnz L(addmul_top)
+
+ add %rax, w0
+ adc %rdx, w1
+ adc $0, R32(w2)
+
+ add w0, -8(rp)
+ adc w1, (rp)
+ adc w2, 8(rp)
+
+ sub $2, vn
+ jz L(ret)
+
+ lea 16(vp), vp
+ lea -16(up), up
+
+ mov un, n
+ mov (vp), v0
+ mov 8(vp), v1
+
+ jmp *outer_addr
+
+C ===========================================================
+C accumulate along diagonals if un - vn is small
+
+ ALIGN(16)
+L(diagonal):
+ xor R32(w0), R32(w0)
+ xor R32(w1), R32(w1)
+ xor R32(w2), R32(w2)
+
+ neg un
+
+ mov R32(vn), %eax
+ and $3, %eax
+ jz L(diag_prologue_0)
+ cmp $2, %eax
+ jc L(diag_prologue_1)
+ jz L(diag_prologue_2)
+
+L(diag_prologue_3):
+ lea -8(vp), vp
+ mov vp, vp_inner
+ add $1, vn
+ mov vn, n
+ lea L(diag_entry_3)(%rip), outer_addr
+ jmp L(diag_entry_3)
+
+L(diag_prologue_0):
+ mov vp, vp_inner
+ mov vn, n
+ lea 0(%rip), outer_addr
+ mov -8(up,n,8), %rax
+ jmp L(diag_entry_0)
+
+L(diag_prologue_1):
+ lea 8(vp), vp
+ mov vp, vp_inner
+ add $3, vn
+ mov vn, n
+ lea 0(%rip), outer_addr
+ mov -8(vp_inner), %rax
+ jmp L(diag_entry_1)
+
+L(diag_prologue_2):
+ lea -16(vp), vp
+ mov vp, vp_inner
+ add $2, vn
+ mov vn, n
+ lea 0(%rip), outer_addr
+ mov 16(vp_inner), %rax
+ jmp L(diag_entry_2)
+
+
+ C this loop is 10 c/loop = 2.5 c/l on K8
+
+ ALIGN(16)
+L(diag_top):
+ add %rax, w0
+ adc %rdx, w1
+ mov -8(up,n,8), %rax
+ adc $0, w2
+L(diag_entry_0):
+ mulq (vp_inner)
+ add %rax, w0
+ adc %rdx, w1
+ adc $0, w2
+L(diag_entry_3):
+ mov -16(up,n,8), %rax
+ mulq 8(vp_inner)
+ add %rax, w0
+ mov 16(vp_inner), %rax
+ adc %rdx, w1
+ adc $0, w2
+L(diag_entry_2):
+ mulq -24(up,n,8)
+ add %rax, w0
+ mov 24(vp_inner), %rax
+ adc %rdx, w1
+ lea 32(vp_inner), vp_inner
+ adc $0, w2
+L(diag_entry_1):
+ mulq -32(up,n,8)
+ sub $4, n
+ jnz L(diag_top)
+
+ add %rax, w0
+ adc %rdx, w1
+ adc $0, w2
+
+ mov w0, (rp,un,8)
+
+ inc un
+ jz L(diag_end)
+
+ mov vn, n
+ mov vp, vp_inner
+
+ lea 8(up), up
+ mov w1, w0
+ mov w2, w1
+ xor R32(w2), R32(w2)
+
+ jmp *outer_addr
+
+L(diag_end):
+ mov w1, (rp)
+ mov w2, 8(rp)
+
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/k8/redc_1.asm b/gmp/mpn/x86_64/k8/redc_1.asm
new file mode 100644
index 0000000000..74538986f9
--- /dev/null
+++ b/gmp/mpn/x86_64/k8/redc_1.asm
@@ -0,0 +1,590 @@
+dnl X86-64 mpn_redc_1 optimised for AMD K8-K10.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2004, 2008, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C AMD bull ?
+C AMD pile ?
+C AMD steam ?
+C AMD bobcat ?
+C AMD jaguar ?
+C Intel P4 ?
+C Intel core ?
+C Intel NHM ?
+C Intel SBR ?
+C Intel IBR ?
+C Intel HWL ?
+C Intel BWL ?
+C Intel atom ?
+C VIA nano ?
+
+C The inner loops of this code are the result of running a code generation and
+C optimisation tool suite written by David Harvey and Torbjörn Granlund.
+
+C TODO
+C * Micro-optimise, none performed thus far.
+C * This looks different from other current redc_1.asm variants. Consider
+C adapting this to the mainstream style.
+C * Is this code really faster than more approaches which compute q0 later?
+C Is the use of a jump jump table faster? Or is the edge of this due to the
+C inlined add_n code?
+C * Put initial m[0] x q0 computation in header.
+C * Put basecases at the file's end, single them out before the pushes.
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`mp_param', `%rdx') C r8
+define(`n', `%rcx') C r9
+define(`u0inv', `%r8') C stack
+
+define(`i', `%r11')
+define(`nneg', `%r12')
+define(`mp', `%r13')
+define(`q0', `%rbp')
+define(`vp', `%rdx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_redc_1)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbp
+ mov (up), q0 C up[0]
+ push %rbx
+ imul u0inv, q0 C first q0, for all execution paths
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov n, nneg
+ neg nneg
+ lea (mp_param,n,8), mp C mp += n
+ lea -16(up,n,8), up C up += n
+
+ mov R32(n), R32(%rax)
+ and $3, R32(%rax)
+ lea 4(%rax), %r9
+ cmp $4, R32(n)
+ cmovg %r9, %rax
+ lea L(tab)(%rip), %r9
+ifdef(`PIC',`
+ movslq (%r9,%rax,4), %rax
+ add %r9, %rax
+ jmp *%rax
+',`
+ jmp *(%r9,%rax,8)
+')
+
+ JUMPTABSECT
+ ALIGN(8)
+L(tab): JMPENT( L(0m4), L(tab))
+ JMPENT( L(1), L(tab))
+ JMPENT( L(2), L(tab))
+ JMPENT( L(3), L(tab))
+ JMPENT( L(0m4), L(tab))
+ JMPENT( L(1m4), L(tab))
+ JMPENT( L(2m4), L(tab))
+ JMPENT( L(3m4), L(tab))
+ TEXT
+
+ ALIGN(16)
+L(1): mov (mp_param), %rax
+ mul q0
+ add 8(up), %rax
+ adc 16(up), %rdx
+ mov %rdx, (rp)
+ mov $0, R32(%rax)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+
+ ALIGN(16)
+L(2): mov (mp_param), %rax
+ mul q0
+ xor R32(%r14), R32(%r14)
+ mov %rax, %r10
+ mov -8(mp), %rax
+ mov %rdx, %r9
+ mul q0
+ add (up), %r10
+ adc %rax, %r9
+ adc %rdx, %r14
+ add 8(up), %r9
+ adc $0, %r14
+ mov %r9, q0
+ imul u0inv, q0
+ mov -16(mp), %rax
+ mul q0
+ xor R32(%rbx), R32(%rbx)
+ mov %rax, %r10
+ mov -8(mp), %rax
+ mov %rdx, %r11
+ mul q0
+ add %r9, %r10
+ adc %rax, %r11
+ adc %rdx, %rbx
+ add 16(up), %r11
+ adc $0, %rbx
+ xor R32(%rax), R32(%rax)
+ add %r11, %r14
+ adc 24(up), %rbx
+ mov %r14, (rp)
+ mov %rbx, 8(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+
+L(3): mov (mp_param), %rax
+ mul q0
+ mov %rax, %rbx
+ mov %rdx, %r10
+ mov -16(mp), %rax
+ mul q0
+ xor R32(%r9), R32(%r9)
+ xor R32(%r14), R32(%r14)
+ add -8(up), %rbx
+ adc %rax, %r10
+ mov -8(mp), %rax
+ adc %rdx, %r9
+ mul q0
+ add (up), %r10
+ mov %r10, (up)
+ adc %rax, %r9
+ adc %rdx, %r14
+ mov %r10, q0
+ imul u0inv, q0
+ add %r9, 8(up)
+ adc $0, %r14
+ mov %r14, -8(up)
+
+ mov -24(mp), %rax
+ mul q0
+ mov %rax, %rbx
+ mov %rdx, %r10
+ mov -16(mp), %rax
+ mul q0
+ xor R32(%r9), R32(%r9)
+ xor R32(%r14), R32(%r14)
+ add (up), %rbx
+ adc %rax, %r10
+ mov -8(mp), %rax
+ adc %rdx, %r9
+ mul q0
+ add 8(up), %r10
+ mov %r10, 8(up)
+ adc %rax, %r9
+ adc %rdx, %r14
+ mov %r10, q0
+ imul u0inv, q0
+ add %r9, 16(up)
+ adc $0, %r14
+ mov %r14, (up)
+
+ mov -24(mp), %rax
+ mul q0
+ mov %rax, %rbx
+ mov %rdx, %r10
+ mov -16(mp), %rax
+ mul q0
+ xor R32(%r9), R32(%r9)
+ xor R32(%r14), R32(%r14)
+ add 8(up), %rbx
+ adc %rax, %r10
+ mov -8(mp), %rax
+ adc %rdx, %r9
+ mul q0
+ add 16(up), %r10
+ adc %rax, %r9
+ adc %rdx, %r14
+ add 24(up), %r9
+ adc $0, %r14
+
+ xor R32(%rax), R32(%rax)
+ add -8(up), %r10
+ adc (up), %r9
+ adc 32(up), %r14
+ mov %r10, (rp)
+ mov %r9, 8(rp)
+ mov %r14, 16(rp)
+ adc R32(%rax), R32(%rax)
+ jmp L(ret)
+
+
+ ALIGN(16)
+L(2m4):
+L(lo2): mov (mp,nneg,8), %rax
+ mul q0
+ xor R32(%r14), R32(%r14)
+ xor R32(%rbx), R32(%rbx)
+ mov %rax, %r10
+ mov 8(mp,nneg,8), %rax
+ mov 24(up,nneg,8), %r15
+ mov %rdx, %r9
+ mul q0
+ add 16(up,nneg,8), %r10
+ adc %rax, %r9
+ mov 16(mp,nneg,8), %rax
+ adc %rdx, %r14
+ mul q0
+ mov $0, R32(%r10) C xor?
+ lea 2(nneg), i
+ add %r9, %r15
+ imul u0inv, %r15
+ jmp L(e2)
+
+ ALIGN(16)
+L(li2): add %r10, (up,i,8)
+ adc %rax, %r9
+ mov (mp,i,8), %rax
+ adc %rdx, %r14
+ xor R32(%r10), R32(%r10)
+ mul q0
+L(e2): add %r9, 8(up,i,8)
+ adc %rax, %r14
+ adc %rdx, %rbx
+ mov 8(mp,i,8), %rax
+ mul q0
+ add %r14, 16(up,i,8)
+ adc %rax, %rbx
+ adc %rdx, %r10
+ mov 16(mp,i,8), %rax
+ mul q0
+ add %rbx, 24(up,i,8)
+ mov $0, R32(%r14) C zero
+ mov %r14, %rbx C zero
+ adc %rax, %r10
+ mov 24(mp,i,8), %rax
+ mov %r14, %r9 C zero
+ adc %rdx, %r9
+ mul q0
+ add $4, i
+ js L(li2)
+
+L(le2): add %r10, (up)
+ adc %rax, %r9
+ adc %r14, %rdx
+ add %r9, 8(up)
+ adc $0, %rdx
+ mov %rdx, 16(up,nneg,8) C up[0]
+ add $8, up
+ mov %r15, q0
+ dec n
+ jnz L(lo2)
+
+ mov nneg, n
+ sar $2, n
+ lea 32(up,nneg,8), up
+ lea (up,nneg,8), vp
+
+ mov -16(up), %r8
+ mov -8(up), %r9
+ add -16(vp), %r8
+ adc -8(vp), %r9
+ mov %r8, (rp)
+ mov %r9, 8(rp)
+ lea 16(rp), rp
+ jmp L(addx)
+
+
+ ALIGN(16)
+L(1m4):
+L(lo1): mov (mp,nneg,8), %rax
+ xor %r9, %r9
+ xor R32(%rbx), R32(%rbx)
+ mul q0
+ mov %rax, %r9
+ mov 8(mp,nneg,8), %rax
+ mov 24(up,nneg,8), %r15
+ mov %rdx, %r14
+ mov $0, R32(%r10) C xor?
+ mul q0
+ add 16(up,nneg,8), %r9
+ adc %rax, %r14
+ adc %rdx, %rbx
+ mov 16(mp,nneg,8), %rax
+ mul q0
+ lea 1(nneg), i
+ add %r14, %r15
+ imul u0inv, %r15
+ jmp L(e1)
+
+ ALIGN(16)
+L(li1): add %r10, (up,i,8)
+ adc %rax, %r9
+ mov (mp,i,8), %rax
+ adc %rdx, %r14
+ xor R32(%r10), R32(%r10)
+ mul q0
+ add %r9, 8(up,i,8)
+ adc %rax, %r14
+ adc %rdx, %rbx
+ mov 8(mp,i,8), %rax
+ mul q0
+L(e1): add %r14, 16(up,i,8)
+ adc %rax, %rbx
+ adc %rdx, %r10
+ mov 16(mp,i,8), %rax
+ mul q0
+ add %rbx, 24(up,i,8)
+ mov $0, R32(%r14) C zero
+ mov %r14, %rbx C zero
+ adc %rax, %r10
+ mov 24(mp,i,8), %rax
+ mov %r14, %r9 C zero
+ adc %rdx, %r9
+ mul q0
+ add $4, i
+ js L(li1)
+
+L(le1): add %r10, (up)
+ adc %rax, %r9
+ adc %r14, %rdx
+ add %r9, 8(up)
+ adc $0, %rdx
+ mov %rdx, 16(up,nneg,8) C up[0]
+ add $8, up
+ mov %r15, q0
+ dec n
+ jnz L(lo1)
+
+ mov nneg, n
+ sar $2, n
+ lea 24(up,nneg,8), up
+ lea (up,nneg,8), vp
+
+ mov -8(up), %r8
+ add -8(vp), %r8
+ mov %r8, (rp)
+ lea 8(rp), rp
+ jmp L(addx)
+
+
+ ALIGN(16)
+L(0m4):
+L(lo0): mov (mp,nneg,8), %rax
+ mov nneg, i
+ mul q0
+ xor R32(%r10), R32(%r10)
+ mov %rax, %r14
+ mov %rdx, %rbx
+ mov 8(mp,nneg,8), %rax
+ mov 24(up,nneg,8), %r15
+ mul q0
+ add 16(up,nneg,8), %r14
+ adc %rax, %rbx
+ adc %rdx, %r10
+ add %rbx, %r15
+ imul u0inv, %r15
+ jmp L(e0)
+
+ ALIGN(16)
+L(li0): add %r10, (up,i,8)
+ adc %rax, %r9
+ mov (mp,i,8), %rax
+ adc %rdx, %r14
+ xor R32(%r10), R32(%r10)
+ mul q0
+ add %r9, 8(up,i,8)
+ adc %rax, %r14
+ adc %rdx, %rbx
+ mov 8(mp,i,8), %rax
+ mul q0
+ add %r14, 16(up,i,8)
+ adc %rax, %rbx
+ adc %rdx, %r10
+L(e0): mov 16(mp,i,8), %rax
+ mul q0
+ add %rbx, 24(up,i,8)
+ mov $0, R32(%r14) C zero
+ mov %r14, %rbx C zero
+ adc %rax, %r10
+ mov 24(mp,i,8), %rax
+ mov %r14, %r9 C zero
+ adc %rdx, %r9
+ mul q0
+ add $4, i
+ js L(li0)
+
+L(le0): add %r10, (up)
+ adc %rax, %r9
+ adc %r14, %rdx
+ add %r9, 8(up)
+ adc $0, %rdx
+ mov %rdx, 16(up,nneg,8) C up[0]
+ add $8, up
+ mov %r15, q0
+ dec n
+ jnz L(lo0)
+
+ mov nneg, n
+ sar $2, n
+ clc
+ lea 16(up,nneg,8), up
+ lea (up,nneg,8), vp
+ jmp L(addy)
+
+
+ ALIGN(16)
+L(3m4):
+L(lo3): mov (mp,nneg,8), %rax
+ mul q0
+ mov %rax, %rbx
+ mov %rdx, %r10
+ mov 8(mp,nneg,8), %rax
+ mov 24(up,nneg,8), %r15
+ mul q0
+ add 16(up,nneg,8), %rbx C result is zero, might carry
+ mov $0, R32(%rbx) C zero
+ mov %rbx, %r14 C zero
+ adc %rax, %r10
+ mov 16(mp,nneg,8), %rax
+ mov %r14, %r9 C zero
+ adc %rdx, %r9
+ add %r10, %r15
+ mul q0
+ lea 3(nneg), i
+ imul u0inv, %r15
+C jmp L(li3)
+
+ ALIGN(16)
+L(li3): add %r10, (up,i,8)
+ adc %rax, %r9
+ mov (mp,i,8), %rax
+ adc %rdx, %r14
+ xor R32(%r10), R32(%r10)
+ mul q0
+ add %r9, 8(up,i,8)
+ adc %rax, %r14
+ adc %rdx, %rbx
+ mov 8(mp,i,8), %rax
+ mul q0
+ add %r14, 16(up,i,8)
+ adc %rax, %rbx
+ adc %rdx, %r10
+ mov 16(mp,i,8), %rax
+ mul q0
+ add %rbx, 24(up,i,8)
+ mov $0, R32(%r14) C zero
+ mov %r14, %rbx C zero
+ adc %rax, %r10
+ mov 24(mp,i,8), %rax
+ mov %r14, %r9 C zero
+ adc %rdx, %r9
+ mul q0
+ add $4, i
+ js L(li3)
+
+L(le3): add %r10, (up)
+ adc %rax, %r9
+ adc %r14, %rdx
+ add %r9, 8(up)
+ adc $0, %rdx
+ mov %rdx, 16(up,nneg,8) C up[0]
+ mov %r15, q0
+ lea 8(up), up
+ dec n
+ jnz L(lo3)
+
+
+C ==== Addition code ====
+ mov nneg, n
+ sar $2, n
+ lea 40(up,nneg,8), up
+ lea (up,nneg,8), vp
+
+ mov -24(up), %r8
+ mov -16(up), %r9
+ mov -8(up), %r10
+ add -24(vp), %r8
+ adc -16(vp), %r9
+ adc -8(vp), %r10
+ mov %r8, (rp)
+ mov %r9, 8(rp)
+ mov %r10, 16(rp)
+ lea 24(rp), rp
+
+L(addx):inc n
+ jz L(ad3)
+
+L(addy):mov (up), %r8
+ mov 8(up), %r9
+ inc n
+ jmp L(mid)
+
+C ALIGN(16)
+L(al3): adc (vp), %r8
+ adc 8(vp), %r9
+ adc 16(vp), %r10
+ adc 24(vp), %r11
+ mov %r8, (rp)
+ lea 32(up), up
+ mov %r9, 8(rp)
+ mov %r10, 16(rp)
+ inc n
+ mov %r11, 24(rp)
+ lea 32(vp), vp
+ mov (up), %r8
+ mov 8(up), %r9
+ lea 32(rp), rp
+L(mid): mov 16(up), %r10
+ mov 24(up), %r11
+ jnz L(al3)
+
+L(ae3): adc (vp), %r8
+ adc 8(vp), %r9
+ adc 16(vp), %r10
+ adc 24(vp), %r11
+ mov %r8, (rp)
+ mov %r9, 8(rp)
+ mov %r10, 16(rp)
+ mov %r11, 24(rp)
+
+L(ad3): mov R32(n), R32(%rax) C zero
+ adc R32(%rax), R32(%rax)
+
+L(ret): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbx
+ pop %rbp
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/k8/sqr_basecase.asm b/gmp/mpn/x86_64/k8/sqr_basecase.asm
new file mode 100644
index 0000000000..60cf945a46
--- /dev/null
+++ b/gmp/mpn/x86_64/k8/sqr_basecase.asm
@@ -0,0 +1,807 @@
+dnl AMD64 mpn_sqr_basecase.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C The inner loops of this code are the result of running a code generation and
+C optimization tool suite written by David Harvey and Torbjorn Granlund.
+
+C NOTES
+C * There is a major stupidity in that we call mpn_mul_1 initially, for a
+C large trip count. Instead, we should follow the generic/sqr_basecase.c
+C code which uses addmul_2s from the start, conditionally leaving a 1x1
+C multiply to the end. (In assembly code, one would stop invoking
+C addmul_2s loops when perhaps 3x2s respectively a 2x2s remains.)
+C * Another stupidity is in the sqr_diag_addlsh1 code. It does not need to
+C save/restore carry, instead it can propagate into the high product word.
+C * Align more labels, should shave off a few cycles.
+C * We can safely use 32-bit size operations, since operands with (2^32)
+C limbs will lead to non-termination in practice.
+C * The jump table could probably be optimized, at least for non-pic.
+C * The special code for n <= 4 was quickly written. It is probably too
+C large and unnecessarily slow.
+C * Consider combining small cases code so that the n=k-1 code jumps into the
+C middle of the n=k code.
+C * Avoid saving registers for small cases code.
+C * Needed variables:
+C n r11 input size
+C i r8 work left, initially n
+C j r9 inner loop count
+C r15 unused
+C v0 r13
+C v1 r14
+C rp rdi
+C up rsi
+C w0 rbx
+C w1 rcx
+C w2 rbp
+C w3 r10
+C tp r12
+C lo rax
+C hi rdx
+C rsp
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n_param', `%rdx')
+
+define(`n', `%r11')
+define(`tp', `%r12')
+define(`i', `%r8')
+define(`j', `%r9')
+define(`v0', `%r13')
+define(`v1', `%r14')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sqr_basecase)
+ FUNC_ENTRY(3)
+ mov R32(n_param), R32(%rcx)
+ mov R32(n_param), R32(n) C free original n register (rdx)
+
+ add $-40, %rsp
+
+ and $3, R32(%rcx)
+ cmp $4, R32(n_param)
+ lea 4(%rcx), %r8
+
+ mov %rbx, 32(%rsp)
+ mov %rbp, 24(%rsp)
+ mov %r12, 16(%rsp)
+ mov %r13, 8(%rsp)
+ mov %r14, (%rsp)
+
+ cmovg %r8, %rcx
+
+ lea L(tab)(%rip), %rax
+ifdef(`PIC',
+` movslq (%rax,%rcx,4), %r10
+ add %r10, %rax
+ jmp *%rax
+',`
+ jmp *(%rax,%rcx,8)
+')
+ JUMPTABSECT
+ ALIGN(8)
+L(tab): JMPENT( L(4), L(tab))
+ JMPENT( L(1), L(tab))
+ JMPENT( L(2), L(tab))
+ JMPENT( L(3), L(tab))
+ JMPENT( L(0m4), L(tab))
+ JMPENT( L(1m4), L(tab))
+ JMPENT( L(2m4), L(tab))
+ JMPENT( L(3m4), L(tab))
+ TEXT
+
+L(1): mov (up), %rax
+ mul %rax
+ add $40, %rsp
+ mov %rax, (rp)
+ mov %rdx, 8(rp)
+ FUNC_EXIT()
+ ret
+
+L(2): mov (up), %rax
+ mov %rax, %r8
+ mul %rax
+ mov 8(up), %r11
+ mov %rax, (rp)
+ mov %r11, %rax
+ mov %rdx, %r9
+ mul %rax
+ add $40, %rsp
+ mov %rax, %r10
+ mov %r11, %rax
+ mov %rdx, %r11
+ mul %r8
+ xor %r8, %r8
+ add %rax, %r9
+ adc %rdx, %r10
+ adc %r8, %r11
+ add %rax, %r9
+ mov %r9, 8(rp)
+ adc %rdx, %r10
+ mov %r10, 16(rp)
+ adc %r8, %r11
+ mov %r11, 24(rp)
+ FUNC_EXIT()
+ ret
+
+L(3): mov (up), %rax
+ mov %rax, %r10
+ mul %rax
+ mov 8(up), %r11
+ mov %rax, (rp)
+ mov %r11, %rax
+ mov %rdx, 8(rp)
+ mul %rax
+ mov 16(up), %rcx
+ mov %rax, 16(rp)
+ mov %rcx, %rax
+ mov %rdx, 24(rp)
+ mul %rax
+ mov %rax, 32(rp)
+ mov %rdx, 40(rp)
+
+ mov %r11, %rax
+ mul %r10
+ mov %rax, %r8
+ mov %rcx, %rax
+ mov %rdx, %r9
+ mul %r10
+ xor %r10, %r10
+ add %rax, %r9
+ mov %r11, %rax
+ mov %r10, %r11
+ adc %rdx, %r10
+
+ mul %rcx
+ add $40, %rsp
+ add %rax, %r10
+ adc %r11, %rdx
+ add %r8, %r8
+ adc %r9, %r9
+ adc %r10, %r10
+ adc %rdx, %rdx
+ adc %r11, %r11
+ add %r8, 8(rp)
+ adc %r9, 16(rp)
+ adc %r10, 24(rp)
+ adc %rdx, 32(rp)
+ adc %r11, 40(rp)
+ FUNC_EXIT()
+ ret
+
+L(4): mov (up), %rax
+ mov %rax, %r11
+ mul %rax
+ mov 8(up), %rbx
+ mov %rax, (rp)
+ mov %rbx, %rax
+ mov %rdx, 8(rp)
+ mul %rax
+ mov %rax, 16(rp)
+ mov %rdx, 24(rp)
+ mov 16(up), %rax
+ mul %rax
+ mov %rax, 32(rp)
+ mov %rdx, 40(rp)
+ mov 24(up), %rax
+ mul %rax
+ mov %rax, 48(rp)
+ mov %rbx, %rax
+ mov %rdx, 56(rp)
+
+ mul %r11
+ add $32, %rsp
+ mov %rax, %r8
+ mov %rdx, %r9
+ mov 16(up), %rax
+ mul %r11
+ xor %r10, %r10
+ add %rax, %r9
+ adc %rdx, %r10
+ mov 24(up), %rax
+ mul %r11
+ xor %r11, %r11
+ add %rax, %r10
+ adc %rdx, %r11
+ mov 16(up), %rax
+ mul %rbx
+ xor %rcx, %rcx
+ add %rax, %r10
+ adc %rdx, %r11
+ adc $0, %rcx
+ mov 24(up), %rax
+ mul %rbx
+ pop %rbx
+ add %rax, %r11
+ adc %rdx, %rcx
+ mov 16(up), %rdx
+ mov 24(up), %rax
+ mul %rdx
+ add %rax, %rcx
+ adc $0, %rdx
+
+ add %r8, %r8
+ adc %r9, %r9
+ adc %r10, %r10
+ adc %r11, %r11
+ adc %rcx, %rcx
+ mov $0, R32(%rax)
+ adc %rdx, %rdx
+
+ adc %rax, %rax
+ add %r8, 8(rp)
+ adc %r9, 16(rp)
+ adc %r10, 24(rp)
+ adc %r11, 32(rp)
+ adc %rcx, 40(rp)
+ adc %rdx, 48(rp)
+ adc %rax, 56(rp)
+ FUNC_EXIT()
+ ret
+
+
+L(0m4):
+ lea -16(rp,n,8), tp C point tp in middle of result operand
+ mov (up), v0
+ mov 8(up), %rax
+ lea (up,n,8), up C point up at end of input operand
+
+ lea -4(n), i
+C Function mpn_mul_1_m3(tp, up - i, i, up[-i - 1])
+ xor R32(j), R32(j)
+ sub n, j
+
+ mul v0
+ xor R32(w2), R32(w2)
+ mov %rax, w0
+ mov 16(up,j,8), %rax
+ mov %rdx, w3
+ jmp L(L3)
+
+ ALIGN(16)
+L(mul_1_m3_top):
+ add %rax, w2
+ mov w3, (tp,j,8)
+ mov (up,j,8), %rax
+ adc %rdx, w1
+ xor R32(w0), R32(w0)
+ mul v0
+ xor R32(w3), R32(w3)
+ mov w2, 8(tp,j,8)
+ add %rax, w1
+ adc %rdx, w0
+ mov 8(up,j,8), %rax
+ mov w1, 16(tp,j,8)
+ xor R32(w2), R32(w2)
+ mul v0
+ add %rax, w0
+ mov 16(up,j,8), %rax
+ adc %rdx, w3
+L(L3): xor R32(w1), R32(w1)
+ mul v0
+ add %rax, w3
+ mov 24(up,j,8), %rax
+ adc %rdx, w2
+ mov w0, 24(tp,j,8)
+ mul v0
+ add $4, j
+ js L(mul_1_m3_top)
+
+ add %rax, w2
+ mov w3, (tp)
+ adc %rdx, w1
+ mov w2, 8(tp)
+ mov w1, 16(tp)
+
+ lea eval(2*8)(tp), tp C tp += 2
+ lea -8(up), up
+ jmp L(dowhile)
+
+
+L(1m4):
+ lea 8(rp,n,8), tp C point tp in middle of result operand
+ mov (up), v0 C u0
+ mov 8(up), %rax C u1
+ lea 8(up,n,8), up C point up at end of input operand
+
+ lea -3(n), i
+C Function mpn_mul_2s_m0(tp, up - i, i, up - i - 1)
+ lea -3(n), j
+ neg j
+
+ mov %rax, v1 C u1
+ mul v0 C u0 * u1
+ mov %rdx, w1
+ xor R32(w2), R32(w2)
+ mov %rax, 8(rp)
+ jmp L(m0)
+
+ ALIGN(16)
+L(mul_2_m0_top):
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov -24(up,j,8), %rax
+ mov $0, R32(w2)
+ mul v0
+ add %rax, w0
+ mov -24(up,j,8), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+ mul v1 C v1 * u0
+ add %rax, w1
+ mov w0, -24(tp,j,8)
+ adc %rdx, w2
+L(m0): mov -16(up,j,8), %rax C u2, u6 ...
+ mul v0 C u0 * u2
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ mov -16(up,j,8), %rax
+ adc $0, R32(w3)
+ mov $0, R32(w0)
+ mov w1, -16(tp,j,8)
+ mul v1
+ add %rax, w2
+ mov -8(up,j,8), %rax
+ adc %rdx, w3
+ mov $0, R32(w1)
+ mul v0
+ add %rax, w2
+ mov -8(up,j,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ add %rax, w3
+ mov w2, -8(tp,j,8)
+ adc %rdx, w0
+L(m2x): mov (up,j,8), %rax
+ mul v0
+ add %rax, w3
+ adc %rdx, w0
+ adc $0, R32(w1)
+ add $4, j
+ mov -32(up,j,8), %rax
+ mov w3, -32(tp,j,8)
+ js L(mul_2_m0_top)
+
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov w0, -8(tp)
+ mov w1, (tp)
+
+ lea -16(up), up
+ lea eval(3*8-24)(tp), tp C tp += 3
+ jmp L(dowhile_end)
+
+
+L(2m4):
+ lea -16(rp,n,8), tp C point tp in middle of result operand
+ mov (up), v0
+ mov 8(up), %rax
+ lea (up,n,8), up C point up at end of input operand
+
+ lea -4(n), i
+C Function mpn_mul_1_m1(tp, up - (i - 1), i - 1, up[-i])
+ lea -2(n), j
+ neg j
+
+ mul v0
+ mov %rax, w2
+ mov (up,j,8), %rax
+ mov %rdx, w1
+ jmp L(L1)
+
+ ALIGN(16)
+L(mul_1_m1_top):
+ add %rax, w2
+ mov w3, (tp,j,8)
+ mov (up,j,8), %rax
+ adc %rdx, w1
+L(L1): xor R32(w0), R32(w0)
+ mul v0
+ xor R32(w3), R32(w3)
+ mov w2, 8(tp,j,8)
+ add %rax, w1
+ adc %rdx, w0
+ mov 8(up,j,8), %rax
+ mov w1, 16(tp,j,8)
+ xor R32(w2), R32(w2)
+ mul v0
+ add %rax, w0
+ mov 16(up,j,8), %rax
+ adc %rdx, w3
+ xor R32(w1), R32(w1)
+ mul v0
+ add %rax, w3
+ mov 24(up,j,8), %rax
+ adc %rdx, w2
+ mov w0, 24(tp,j,8)
+ mul v0
+ add $4, j
+ js L(mul_1_m1_top)
+
+ add %rax, w2
+ mov w3, (tp)
+ adc %rdx, w1
+ mov w2, 8(tp)
+ mov w1, 16(tp)
+
+ lea eval(2*8)(tp), tp C tp += 2
+ lea -8(up), up
+ jmp L(dowhile_mid)
+
+
+L(3m4):
+ lea 8(rp,n,8), tp C point tp in middle of result operand
+ mov (up), v0 C u0
+ mov 8(up), %rax C u1
+ lea 8(up,n,8), up C point up at end of input operand
+
+ lea -5(n), i
+C Function mpn_mul_2s_m2(tp, up - i + 1, i - 1, up - i)
+ lea -1(n), j
+ neg j
+
+ mov %rax, v1 C u1
+ mul v0 C u0 * u1
+ mov %rdx, w3
+ xor R32(w0), R32(w0)
+ xor R32(w1), R32(w1)
+ mov %rax, 8(rp)
+ jmp L(m2)
+
+ ALIGN(16)
+L(mul_2_m2_top):
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov -24(up,j,8), %rax
+ mov $0, R32(w2)
+ mul v0
+ add %rax, w0
+ mov -24(up,j,8), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+ mul v1 C v1 * u0
+ add %rax, w1
+ mov w0, -24(tp,j,8)
+ adc %rdx, w2
+ mov -16(up,j,8), %rax
+ mul v0
+ mov $0, R32(w3)
+ add %rax, w1
+ adc %rdx, w2
+ mov -16(up,j,8), %rax
+ adc $0, R32(w3)
+ mov $0, R32(w0)
+ mov w1, -16(tp,j,8)
+ mul v1
+ add %rax, w2
+ mov -8(up,j,8), %rax
+ adc %rdx, w3
+ mov $0, R32(w1)
+ mul v0
+ add %rax, w2
+ mov -8(up,j,8), %rax
+ adc %rdx, w3
+ adc $0, R32(w0)
+ mul v1
+ add %rax, w3
+ mov w2, -8(tp,j,8)
+ adc %rdx, w0
+L(m2): mov (up,j,8), %rax
+ mul v0
+ add %rax, w3
+ adc %rdx, w0
+ adc $0, R32(w1)
+ add $4, j
+ mov -32(up,j,8), %rax
+ mov w3, -32(tp,j,8)
+ js L(mul_2_m2_top)
+
+ mul v1
+ add %rax, w0
+ adc %rdx, w1
+ mov w0, -8(tp)
+ mov w1, (tp)
+
+ lea -16(up), up
+ jmp L(dowhile_mid)
+
+L(dowhile):
+C Function mpn_addmul_2s_m2(tp, up - (i - 1), i - 1, up - i)
+ lea 4(i), j
+ neg j
+
+ mov 16(up,j,8), v0
+ mov 24(up,j,8), v1
+ mov 24(up,j,8), %rax
+ mul v0
+ xor R32(w3), R32(w3)
+ add %rax, 24(tp,j,8)
+ adc %rdx, w3
+ xor R32(w0), R32(w0)
+ xor R32(w1), R32(w1)
+ jmp L(am2)
+
+ ALIGN(16)
+L(addmul_2_m2_top):
+ add w3, (tp,j,8)
+ adc %rax, w0
+ mov 8(up,j,8), %rax
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mul v0
+ add %rax, w0
+ mov 8(up,j,8), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+ mul v1 C v1 * u0
+ add w0, 8(tp,j,8)
+ adc %rax, w1
+ adc %rdx, w2
+ mov 16(up,j,8), %rax
+ mov $0, R32(w3)
+ mul v0 C v0 * u1
+ add %rax, w1
+ mov 16(up,j,8), %rax
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mul v1 C v1 * u1
+ add w1, 16(tp,j,8)
+ adc %rax, w2
+ mov 24(up,j,8), %rax
+ adc %rdx, w3
+ mul v0
+ mov $0, R32(w0)
+ add %rax, w2
+ adc %rdx, w3
+ mov $0, R32(w1)
+ mov 24(up,j,8), %rax
+ adc $0, R32(w0)
+ mul v1
+ add w2, 24(tp,j,8)
+ adc %rax, w3
+ adc %rdx, w0
+L(am2): mov 32(up,j,8), %rax
+ mul v0
+ add %rax, w3
+ mov 32(up,j,8), %rax
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add $4, j
+ js L(addmul_2_m2_top)
+
+ add w3, (tp)
+ adc %rax, w0
+ adc %rdx, w1
+ mov w0, 8(tp)
+ mov w1, 16(tp)
+
+ lea eval(2*8)(tp), tp C tp += 2
+
+ add $-2, R32(i) C i -= 2
+
+L(dowhile_mid):
+C Function mpn_addmul_2s_m0(tp, up - (i - 1), i - 1, up - i)
+ lea 2(i), j
+ neg j
+
+ mov (up,j,8), v0
+ mov 8(up,j,8), v1
+ mov 8(up,j,8), %rax
+ mul v0
+ xor R32(w1), R32(w1)
+ add %rax, 8(tp,j,8)
+ adc %rdx, w1
+ xor R32(w2), R32(w2)
+ jmp L(20)
+
+ ALIGN(16)
+L(addmul_2_m0_top):
+ add w3, (tp,j,8)
+ adc %rax, w0
+ mov 8(up,j,8), %rax
+ adc %rdx, w1
+ mov $0, R32(w2)
+ mul v0
+ add %rax, w0
+ mov 8(up,j,8), %rax
+ adc %rdx, w1
+ adc $0, R32(w2)
+ mul v1 C v1 * u0
+ add w0, 8(tp,j,8)
+ adc %rax, w1
+ adc %rdx, w2
+L(20): mov 16(up,j,8), %rax
+ mov $0, R32(w3)
+ mul v0 C v0 * u1
+ add %rax, w1
+ mov 16(up,j,8), %rax
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mul v1 C v1 * u1
+ add w1, 16(tp,j,8)
+ adc %rax, w2
+ mov 24(up,j,8), %rax
+ adc %rdx, w3
+ mul v0
+ mov $0, R32(w0)
+ add %rax, w2
+ adc %rdx, w3
+ mov $0, R32(w1)
+ mov 24(up,j,8), %rax
+ adc $0, R32(w0)
+ mul v1
+ add w2, 24(tp,j,8)
+ adc %rax, w3
+ adc %rdx, w0
+ mov 32(up,j,8), %rax
+ mul v0
+ add %rax, w3
+ mov 32(up,j,8), %rax
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mul v1
+ add $4, j
+ js L(addmul_2_m0_top)
+
+ add w3, (tp)
+ adc %rax, w0
+ adc %rdx, w1
+ mov w0, 8(tp)
+ mov w1, 16(tp)
+
+ lea eval(2*8)(tp), tp C tp += 2
+L(dowhile_end):
+
+ add $-2, R32(i) C i -= 2
+ jne L(dowhile)
+
+C Function mpn_addmul_2s_2
+ mov -16(up), v0
+ mov -8(up), v1
+ mov -8(up), %rax
+ mul v0
+ xor R32(w3), R32(w3)
+ add %rax, -8(tp)
+ adc %rdx, w3
+ xor R32(w0), R32(w0)
+ xor R32(w1), R32(w1)
+ mov (up), %rax
+ mul v0
+ add %rax, w3
+ mov (up), %rax
+ adc %rdx, w0
+ mul v1
+ add w3, (tp)
+ adc %rax, w0
+ adc %rdx, w1
+ mov w0, 8(tp)
+ mov w1, 16(tp)
+
+C Function mpn_sqr_diag_addlsh1
+ lea -4(n,n), j
+
+ mov 8(rp), %r11
+ lea -8(up), up
+ lea (rp,j,8), rp
+ neg j
+ mov (up,j,4), %rax
+ mul %rax
+ test $2, R8(j)
+ jnz L(odd)
+
+L(evn): add %r11, %r11
+ sbb R32(%rbx), R32(%rbx) C save CF
+ add %rdx, %r11
+ mov %rax, (rp,j,8)
+ jmp L(d0)
+
+L(odd): add %r11, %r11
+ sbb R32(%rbp), R32(%rbp) C save CF
+ add %rdx, %r11
+ mov %rax, (rp,j,8)
+ lea -2(j), j
+ jmp L(d1)
+
+ ALIGN(16)
+L(top): mov (up,j,4), %rax
+ mul %rax
+ add R32(%rbp), R32(%rbp) C restore carry
+ adc %rax, %r10
+ adc %rdx, %r11
+ mov %r10, (rp,j,8)
+L(d0): mov %r11, 8(rp,j,8)
+ mov 16(rp,j,8), %r10
+ adc %r10, %r10
+ mov 24(rp,j,8), %r11
+ adc %r11, %r11
+ nop
+ sbb R32(%rbp), R32(%rbp) C save CF
+ mov 8(up,j,4), %rax
+ mul %rax
+ add R32(%rbx), R32(%rbx) C restore carry
+ adc %rax, %r10
+ adc %rdx, %r11
+ mov %r10, 16(rp,j,8)
+L(d1): mov %r11, 24(rp,j,8)
+ mov 32(rp,j,8), %r10
+ adc %r10, %r10
+ mov 40(rp,j,8), %r11
+ adc %r11, %r11
+ sbb R32(%rbx), R32(%rbx) C save CF
+ add $4, j
+ js L(top)
+
+ mov (up), %rax
+ mul %rax
+ add R32(%rbp), R32(%rbp) C restore carry
+ adc %rax, %r10
+ adc %rdx, %r11
+ mov %r10, (rp)
+ mov %r11, 8(rp)
+ mov 16(rp), %r10
+ adc %r10, %r10
+ sbb R32(%rbp), R32(%rbp) C save CF
+ neg R32(%rbp)
+ mov 8(up), %rax
+ mul %rax
+ add R32(%rbx), R32(%rbx) C restore carry
+ adc %rax, %r10
+ adc %rbp, %rdx
+ mov %r10, 16(rp)
+ mov %rdx, 24(rp)
+
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/logops_n.asm b/gmp/mpn/x86_64/logops_n.asm
new file mode 100644
index 0000000000..b277f58962
--- /dev/null
+++ b/gmp/mpn/x86_64/logops_n.asm
@@ -0,0 +1,244 @@
+dnl AMD64 logops.
+
+dnl Copyright 2004-2006, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 1.5 with fluctuations for variant 2 and 3
+C AMD K10 1.5 with fluctuations for all variants
+C Intel P4 2.8/3.35/3.60 (variant1/variant2/variant3)
+C Intel core2 2
+C Intel NHM 2
+C Intel SBR 1.5/1.75/1.75
+C Intel atom 3.75
+C VIA nano 3.25
+
+ifdef(`OPERATION_and_n',`
+ define(`func',`mpn_and_n')
+ define(`VARIANT_1')
+ define(`LOGOP',`andq')')
+ifdef(`OPERATION_andn_n',`
+ define(`func',`mpn_andn_n')
+ define(`VARIANT_2')
+ define(`LOGOP',`andq')')
+ifdef(`OPERATION_nand_n',`
+ define(`func',`mpn_nand_n')
+ define(`VARIANT_3')
+ define(`LOGOP',`andq')')
+ifdef(`OPERATION_ior_n',`
+ define(`func',`mpn_ior_n')
+ define(`VARIANT_1')
+ define(`LOGOP',`orq')')
+ifdef(`OPERATION_iorn_n',`
+ define(`func',`mpn_iorn_n')
+ define(`VARIANT_2')
+ define(`LOGOP',`orq')')
+ifdef(`OPERATION_nior_n',`
+ define(`func',`mpn_nior_n')
+ define(`VARIANT_3')
+ define(`LOGOP',`orq')')
+ifdef(`OPERATION_xor_n',`
+ define(`func',`mpn_xor_n')
+ define(`VARIANT_1')
+ define(`LOGOP',`xorq')')
+ifdef(`OPERATION_xnor_n',`
+ define(`func',`mpn_xnor_n')
+ define(`VARIANT_2')
+ define(`LOGOP',`xorq')')
+
+
+MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`vp',`%rdx')
+define(`n',`%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+
+ifdef(`VARIANT_1',`
+ TEXT
+ ALIGN(32)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ movq (vp), %r8
+ movl R32(%rcx), R32(%rax)
+ leaq (vp,n,8), vp
+ leaq (up,n,8), up
+ leaq (rp,n,8), rp
+ negq n
+ andl $3, R32(%rax)
+ je L(b00)
+ cmpl $2, R32(%rax)
+ jc L(b01)
+ je L(b10)
+
+L(b11): LOGOP (up,n,8), %r8
+ movq %r8, (rp,n,8)
+ decq n
+ jmp L(e11)
+L(b10): addq $-2, n
+ jmp L(e10)
+L(b01): LOGOP (up,n,8), %r8
+ movq %r8, (rp,n,8)
+ incq n
+ jz L(ret)
+
+L(oop): movq (vp,n,8), %r8
+L(b00): movq 8(vp,n,8), %r9
+ LOGOP (up,n,8), %r8
+ LOGOP 8(up,n,8), %r9
+ nop
+ movq %r8, (rp,n,8)
+ movq %r9, 8(rp,n,8)
+L(e11): movq 16(vp,n,8), %r8
+L(e10): movq 24(vp,n,8), %r9
+ LOGOP 16(up,n,8), %r8
+ LOGOP 24(up,n,8), %r9
+ movq %r8, 16(rp,n,8)
+ movq %r9, 24(rp,n,8)
+ addq $4, n
+ jnc L(oop)
+L(ret): FUNC_EXIT()
+ ret
+EPILOGUE()
+')
+
+ifdef(`VARIANT_2',`
+ TEXT
+ ALIGN(32)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ movq (vp), %r8
+ notq %r8
+ movl R32(%rcx), R32(%rax)
+ leaq (vp,n,8), vp
+ leaq (up,n,8), up
+ leaq (rp,n,8), rp
+ negq n
+ andl $3, R32(%rax)
+ je L(b00)
+ cmpl $2, R32(%rax)
+ jc L(b01)
+ je L(b10)
+
+L(b11): LOGOP (up,n,8), %r8
+ movq %r8, (rp,n,8)
+ decq n
+ jmp L(e11)
+L(b10): addq $-2, n
+ jmp L(e10)
+ .byte 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90
+L(b01): LOGOP (up,n,8), %r8
+ movq %r8, (rp,n,8)
+ incq n
+ jz L(ret)
+
+L(oop): movq (vp,n,8), %r8
+ notq %r8
+L(b00): movq 8(vp,n,8), %r9
+ notq %r9
+ LOGOP (up,n,8), %r8
+ LOGOP 8(up,n,8), %r9
+ movq %r8, (rp,n,8)
+ movq %r9, 8(rp,n,8)
+L(e11): movq 16(vp,n,8), %r8
+ notq %r8
+L(e10): movq 24(vp,n,8), %r9
+ notq %r9
+ LOGOP 16(up,n,8), %r8
+ LOGOP 24(up,n,8), %r9
+ movq %r8, 16(rp,n,8)
+ movq %r9, 24(rp,n,8)
+ addq $4, n
+ jnc L(oop)
+L(ret): FUNC_EXIT()
+ ret
+EPILOGUE()
+')
+
+ifdef(`VARIANT_3',`
+ TEXT
+ ALIGN(32)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ movq (vp), %r8
+ movl R32(%rcx), R32(%rax)
+ leaq (vp,n,8), vp
+ leaq (up,n,8), up
+ leaq (rp,n,8), rp
+ negq n
+ andl $3, R32(%rax)
+ je L(b00)
+ cmpl $2, R32(%rax)
+ jc L(b01)
+ je L(b10)
+
+L(b11): LOGOP (up,n,8), %r8
+ notq %r8
+ movq %r8, (rp,n,8)
+ decq n
+ jmp L(e11)
+L(b10): addq $-2, n
+ jmp L(e10)
+ .byte 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90
+L(b01): LOGOP (up,n,8), %r8
+ notq %r8
+ movq %r8, (rp,n,8)
+ incq n
+ jz L(ret)
+
+L(oop): movq (vp,n,8), %r8
+L(b00): movq 8(vp,n,8), %r9
+ LOGOP (up,n,8), %r8
+ notq %r8
+ LOGOP 8(up,n,8), %r9
+ notq %r9
+ movq %r8, (rp,n,8)
+ movq %r9, 8(rp,n,8)
+L(e11): movq 16(vp,n,8), %r8
+L(e10): movq 24(vp,n,8), %r9
+ LOGOP 16(up,n,8), %r8
+ notq %r8
+ LOGOP 24(up,n,8), %r9
+ notq %r9
+ movq %r8, 16(rp,n,8)
+ movq %r9, 24(rp,n,8)
+ addq $4, n
+ jnc L(oop)
+L(ret): FUNC_EXIT()
+ ret
+EPILOGUE()
+')
diff --git a/gmp/mpn/x86_64/lshift.asm b/gmp/mpn/x86_64/lshift.asm
new file mode 100644
index 0000000000..f368944b85
--- /dev/null
+++ b/gmp/mpn/x86_64/lshift.asm
@@ -0,0 +1,247 @@
+dnl AMD64 mpn_lshift -- mpn left shift.
+
+dnl Copyright 2003, 2005, 2007, 2009, 2011, 2012 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb cycles/limb cnt=1
+C AMD K8,K9 2.375 1.375
+C AMD K10 2.375 1.375
+C Intel P4 8 10.5
+C Intel core2 2.11 4.28
+C Intel corei ? ?
+C Intel atom 5.75 3.5
+C VIA nano 3.5 2.25
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_lshift)
+ FUNC_ENTRY(4)
+ cmp $1, R8(%rcx)
+ jne L(gen)
+
+C For cnt=1 we want to work from lowest limb towards higher limbs.
+C Check for bad overlap (up=rp is OK!) up=rp+1..rp+n-1 is bad.
+C FIXME: this could surely be done more cleverly.
+
+ mov rp, %rax
+ sub up, %rax
+ je L(fwd) C rp = up
+ shr $3, %rax
+ cmp n, %rax
+ jb L(gen)
+
+L(fwd): mov R32(n), R32(%rax)
+ shr $2, n
+ je L(e1)
+ and $3, R32(%rax)
+
+ ALIGN(8)
+ nop
+ nop
+L(t1): mov (up), %r8
+ mov 8(up), %r9
+ mov 16(up), %r10
+ mov 24(up), %r11
+ lea 32(up), up
+ adc %r8, %r8
+ mov %r8, (rp)
+ adc %r9, %r9
+ mov %r9, 8(rp)
+ adc %r10, %r10
+ mov %r10, 16(rp)
+ adc %r11, %r11
+ mov %r11, 24(rp)
+ lea 32(rp), rp
+ dec n
+ jne L(t1)
+
+ inc R32(%rax)
+ dec R32(%rax)
+ jne L(n00)
+ adc R32(%rax), R32(%rax)
+ FUNC_EXIT()
+ ret
+L(e1): test R32(%rax), R32(%rax) C clear cy
+L(n00): mov (up), %r8
+ dec R32(%rax)
+ jne L(n01)
+ adc %r8, %r8
+ mov %r8, (rp)
+L(ret): adc R32(%rax), R32(%rax)
+ FUNC_EXIT()
+ ret
+L(n01): dec R32(%rax)
+ mov 8(up), %r9
+ jne L(n10)
+ adc %r8, %r8
+ adc %r9, %r9
+ mov %r8, (rp)
+ mov %r9, 8(rp)
+ adc R32(%rax), R32(%rax)
+ FUNC_EXIT()
+ ret
+L(n10): mov 16(up), %r10
+ adc %r8, %r8
+ adc %r9, %r9
+ adc %r10, %r10
+ mov %r8, (rp)
+ mov %r9, 8(rp)
+ mov %r10, 16(rp)
+ adc $-1, R32(%rax)
+ FUNC_EXIT()
+ ret
+
+L(gen): neg R32(%rcx) C put rsh count in cl
+ mov -8(up,n,8), %rax
+ shr R8(%rcx), %rax C function return value
+
+ neg R32(%rcx) C put lsh count in cl
+ lea 1(n), R32(%r8)
+ and $3, R32(%r8)
+ je L(rlx) C jump for n = 3, 7, 11, ...
+
+ dec R32(%r8)
+ jne L(1)
+C n = 4, 8, 12, ...
+ mov -8(up,n,8), %r10
+ shl R8(%rcx), %r10
+ neg R32(%rcx) C put rsh count in cl
+ mov -16(up,n,8), %r8
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ mov %r10, -8(rp,n,8)
+ dec n
+ jmp L(rll)
+
+L(1): dec R32(%r8)
+ je L(1x) C jump for n = 1, 5, 9, 13, ...
+C n = 2, 6, 10, 16, ...
+ mov -8(up,n,8), %r10
+ shl R8(%rcx), %r10
+ neg R32(%rcx) C put rsh count in cl
+ mov -16(up,n,8), %r8
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ mov %r10, -8(rp,n,8)
+ dec n
+ neg R32(%rcx) C put lsh count in cl
+L(1x):
+ cmp $1, n
+ je L(ast)
+ mov -8(up,n,8), %r10
+ shl R8(%rcx), %r10
+ mov -16(up,n,8), %r11
+ shl R8(%rcx), %r11
+ neg R32(%rcx) C put rsh count in cl
+ mov -16(up,n,8), %r8
+ mov -24(up,n,8), %r9
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ shr R8(%rcx), %r9
+ or %r9, %r11
+ mov %r10, -8(rp,n,8)
+ mov %r11, -16(rp,n,8)
+ sub $2, n
+
+L(rll): neg R32(%rcx) C put lsh count in cl
+L(rlx): mov -8(up,n,8), %r10
+ shl R8(%rcx), %r10
+ mov -16(up,n,8), %r11
+ shl R8(%rcx), %r11
+
+ sub $4, n C 4
+ jb L(end) C 2
+ ALIGN(16)
+L(top):
+ C finish stuff from lsh block
+ neg R32(%rcx) C put rsh count in cl
+ mov 16(up,n,8), %r8
+ mov 8(up,n,8), %r9
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ shr R8(%rcx), %r9
+ or %r9, %r11
+ mov %r10, 24(rp,n,8)
+ mov %r11, 16(rp,n,8)
+ C start two new rsh
+ mov 0(up,n,8), %r8
+ mov -8(up,n,8), %r9
+ shr R8(%rcx), %r8
+ shr R8(%rcx), %r9
+
+ C finish stuff from rsh block
+ neg R32(%rcx) C put lsh count in cl
+ mov 8(up,n,8), %r10
+ mov 0(up,n,8), %r11
+ shl R8(%rcx), %r10
+ or %r10, %r8
+ shl R8(%rcx), %r11
+ or %r11, %r9
+ mov %r8, 8(rp,n,8)
+ mov %r9, 0(rp,n,8)
+ C start two new lsh
+ mov -8(up,n,8), %r10
+ mov -16(up,n,8), %r11
+ shl R8(%rcx), %r10
+ shl R8(%rcx), %r11
+
+ sub $4, n
+ jae L(top) C 2
+L(end):
+ neg R32(%rcx) C put rsh count in cl
+ mov 8(up), %r8
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ mov (up), %r9
+ shr R8(%rcx), %r9
+ or %r9, %r11
+ mov %r10, 16(rp)
+ mov %r11, 8(rp)
+
+ neg R32(%rcx) C put lsh count in cl
+L(ast): mov (up), %r10
+ shl R8(%rcx), %r10
+ mov %r10, (rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/lshiftc.asm b/gmp/mpn/x86_64/lshiftc.asm
new file mode 100644
index 0000000000..c4ba04a173
--- /dev/null
+++ b/gmp/mpn/x86_64/lshiftc.asm
@@ -0,0 +1,182 @@
+dnl AMD64 mpn_lshiftc -- mpn left shift with complement.
+
+dnl Copyright 2003, 2005, 2006, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 2.75
+C AMD K10 2.75
+C Intel P4 ?
+C Intel core2 ?
+C Intel corei ?
+C Intel atom ?
+C VIA nano 3.75
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_lshiftc)
+ FUNC_ENTRY(4)
+ neg R32(%rcx) C put rsh count in cl
+ mov -8(up,n,8), %rax
+ shr R8(%rcx), %rax C function return value
+
+ neg R32(%rcx) C put lsh count in cl
+ lea 1(n), R32(%r8)
+ and $3, R32(%r8)
+ je L(rlx) C jump for n = 3, 7, 11, ...
+
+ dec R32(%r8)
+ jne L(1)
+C n = 4, 8, 12, ...
+ mov -8(up,n,8), %r10
+ shl R8(%rcx), %r10
+ neg R32(%rcx) C put rsh count in cl
+ mov -16(up,n,8), %r8
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ not %r10
+ mov %r10, -8(rp,n,8)
+ dec n
+ jmp L(rll)
+
+L(1): dec R32(%r8)
+ je L(1x) C jump for n = 1, 5, 9, 13, ...
+C n = 2, 6, 10, 16, ...
+ mov -8(up,n,8), %r10
+ shl R8(%rcx), %r10
+ neg R32(%rcx) C put rsh count in cl
+ mov -16(up,n,8), %r8
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ not %r10
+ mov %r10, -8(rp,n,8)
+ dec n
+ neg R32(%rcx) C put lsh count in cl
+L(1x):
+ cmp $1, n
+ je L(ast)
+ mov -8(up,n,8), %r10
+ shl R8(%rcx), %r10
+ mov -16(up,n,8), %r11
+ shl R8(%rcx), %r11
+ neg R32(%rcx) C put rsh count in cl
+ mov -16(up,n,8), %r8
+ mov -24(up,n,8), %r9
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ shr R8(%rcx), %r9
+ or %r9, %r11
+ not %r10
+ not %r11
+ mov %r10, -8(rp,n,8)
+ mov %r11, -16(rp,n,8)
+ sub $2, n
+
+L(rll): neg R32(%rcx) C put lsh count in cl
+L(rlx): mov -8(up,n,8), %r10
+ shl R8(%rcx), %r10
+ mov -16(up,n,8), %r11
+ shl R8(%rcx), %r11
+
+ sub $4, n C 4
+ jb L(end) C 2
+ ALIGN(16)
+L(top):
+ C finish stuff from lsh block
+ neg R32(%rcx) C put rsh count in cl
+ mov 16(up,n,8), %r8
+ mov 8(up,n,8), %r9
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ shr R8(%rcx), %r9
+ or %r9, %r11
+ not %r10
+ not %r11
+ mov %r10, 24(rp,n,8)
+ mov %r11, 16(rp,n,8)
+ C start two new rsh
+ mov 0(up,n,8), %r8
+ mov -8(up,n,8), %r9
+ shr R8(%rcx), %r8
+ shr R8(%rcx), %r9
+
+ C finish stuff from rsh block
+ neg R32(%rcx) C put lsh count in cl
+ mov 8(up,n,8), %r10
+ mov 0(up,n,8), %r11
+ shl R8(%rcx), %r10
+ or %r10, %r8
+ shl R8(%rcx), %r11
+ or %r11, %r9
+ not %r8
+ not %r9
+ mov %r8, 8(rp,n,8)
+ mov %r9, 0(rp,n,8)
+ C start two new lsh
+ mov -8(up,n,8), %r10
+ mov -16(up,n,8), %r11
+ shl R8(%rcx), %r10
+ shl R8(%rcx), %r11
+
+ sub $4, n
+ jae L(top) C 2
+L(end):
+ neg R32(%rcx) C put rsh count in cl
+ mov 8(up), %r8
+ shr R8(%rcx), %r8
+ or %r8, %r10
+ mov (up), %r9
+ shr R8(%rcx), %r9
+ or %r9, %r11
+ not %r10
+ not %r11
+ mov %r10, 16(rp)
+ mov %r11, 8(rp)
+
+ neg R32(%rcx) C put lsh count in cl
+L(ast): mov (up), %r10
+ shl R8(%rcx), %r10
+ not %r10
+ mov %r10, (rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/lshsub_n.asm b/gmp/mpn/x86_64/lshsub_n.asm
new file mode 100644
index 0000000000..4d428c0bd2
--- /dev/null
+++ b/gmp/mpn/x86_64/lshsub_n.asm
@@ -0,0 +1,172 @@
+dnl AMD64 mpn_lshsub_n. R = 2^k(U - V).
+
+dnl Copyright 2006, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 3.15 (mpn_sub_n + mpn_lshift costs about 4 c/l)
+C AMD K10 3.15 (mpn_sub_n + mpn_lshift costs about 4 c/l)
+C Intel P4 16.5
+C Intel core2 4.35
+C Intel corei ?
+C Intel atom ?
+C VIA nano ?
+
+C This was written quickly and not optimized at all, but it runs very well on
+C K8. But perhaps one could get under 3 c/l. Ideas:
+C 1) Use indexing to save the 3 LEA
+C 2) Write reasonable feed-in code
+C 3) Be more clever about register usage
+C 4) Unroll more, handling CL negation, carry save/restore cost much now
+C 5) Reschedule
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cnt', `%r8')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_lshsub_n)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ push %rbx
+
+ mov n, %rax
+ xor R32(%rbx), R32(%rbx) C clear carry save register
+ mov R32(%r8), R32(%rcx) C shift count
+ xor R32(%r15), R32(%r15) C limb carry
+
+ mov R32(%rax), R32(%r11)
+ and $3, R32(%r11)
+ je L(4)
+ sub $1, R32(%r11)
+
+L(oopette):
+ add R32(%rbx), R32(%rbx) C restore carry flag
+ mov 0(up), %r8
+ lea 8(up), up
+ sbb 0(vp), %r8
+ mov %r8, %r12
+ sbb R32(%rbx), R32(%rbx) C save carry flag
+ shl R8(%rcx), %r8
+ or %r15, %r8
+ mov %r12, %r15
+ lea 8(vp), vp
+ neg R8(%rcx)
+ shr R8(%rcx), %r15
+ neg R8(%rcx)
+ mov %r8, 0(rp)
+ lea 8(rp), rp
+ sub $1, R32(%r11)
+ jnc L(oopette)
+
+L(4):
+ sub $4, %rax
+ jc L(end)
+
+ ALIGN(16)
+L(oop):
+ add R32(%rbx), R32(%rbx) C restore carry flag
+
+ mov 0(up), %r8
+ mov 8(up), %r9
+ mov 16(up), %r10
+ mov 24(up), %r11
+
+ lea 32(up), up
+
+ sbb 0(vp), %r8
+ mov %r8, %r12
+ sbb 8(vp), %r9
+ mov %r9, %r13
+ sbb 16(vp), %r10
+ mov %r10, %r14
+ sbb 24(vp), %r11
+
+ sbb R32(%rbx), R32(%rbx) C save carry flag
+
+ shl R8(%rcx), %r8
+ shl R8(%rcx), %r9
+ shl R8(%rcx), %r10
+ or %r15, %r8
+ mov %r11, %r15
+ shl R8(%rcx), %r11
+
+ lea 32(vp), vp
+
+ neg R8(%rcx)
+
+ shr R8(%rcx), %r12
+ shr R8(%rcx), %r13
+ shr R8(%rcx), %r14
+ shr R8(%rcx), %r15 C used next loop
+
+ or %r12, %r9
+ or %r13, %r10
+ or %r14, %r11
+
+ neg R8(%rcx)
+
+ mov %r8, 0(rp)
+ mov %r9, 8(rp)
+ mov %r10, 16(rp)
+ mov %r11, 24(rp)
+
+ lea 32(rp), rp
+
+ sub $4, %rax
+ jnc L(oop)
+L(end):
+ neg R32(%rbx)
+ shl R8(%rcx), %rbx
+ adc %r15, %rbx
+ mov %rbx, %rax
+ pop %rbx
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/missing-call.m4 b/gmp/mpn/x86_64/missing-call.m4
new file mode 100644
index 0000000000..c024f0ed77
--- /dev/null
+++ b/gmp/mpn/x86_64/missing-call.m4
@@ -0,0 +1,53 @@
+dnl AMD64 MULX/ADX simulation support, function call version.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+define(`adox',`
+ push $1
+ push $2
+ call __gmp_adox
+ pop $2
+')
+
+define(`adcx',`
+ push $1
+ push $2
+ call __gmp_adcx
+ pop $2
+')
+
+define(`mulx',`
+ push $1
+ call __gmp_mulx
+ pop $2
+ pop $3
+')
diff --git a/gmp/mpn/x86_64/missing-inline.m4 b/gmp/mpn/x86_64/missing-inline.m4
new file mode 100644
index 0000000000..bd1df1313f
--- /dev/null
+++ b/gmp/mpn/x86_64/missing-inline.m4
@@ -0,0 +1,100 @@
+dnl AMD64 MULX/ADX simulation support, inline version.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+define(`adox',`
+ push $2
+ push %rcx
+ push %rbx
+ push %rax
+ mov $1, %rcx
+ pushfq
+ pushfq
+C copy 0(%rsp):11 to 0(%rsp):0
+ mov (%rsp), %rbx
+ shr %rbx
+ bt $`'10, %rbx
+ adc %rbx, %rbx
+ mov %rbx, (%rsp)
+C put manipulated flags into eflags, execute a plain adc
+ popfq
+ adc %rcx, 32(%rsp)
+C copy CF to 0(%rsp):11
+ mov (%rsp), %rbx
+ sbb R32(%rax), R32(%rax)
+ and $`'0x800, R32(%rax)
+ and $`'0xfffffffffffff7ff, %rbx
+ or %rax, %rbx
+ mov %rbx, (%rsp)
+C put manipulated flags into eflags
+ popfq
+ pop %rax
+ pop %rbx
+ pop %rcx
+ pop $2
+')
+
+define(`adcx',`
+ push $2
+ push %rcx
+ push %rbx
+ push %rax
+ mov $1, %rcx
+ pushfq
+ adc %rcx, 32(%rsp)
+ mov (%rsp), %rbx
+ sbb R32(%rax), R32(%rax)
+ and $`'0xfffffffffffffffe, %rbx
+ sub %rax, %rbx
+ mov %rbx, (%rsp)
+ popfq
+ pop %rax
+ pop %rbx
+ pop %rcx
+ pop $2
+')
+
+define(`mulx',`
+ lea -16(%rsp), %rsp
+ push %rax
+ push %rdx
+ pushfq C preserve all flags
+ mov $1, %rax
+ mul %rdx
+ mov %rax, 24(%rsp)
+ mov %rdx, 32(%rsp)
+ popfq C restore eflags
+ pop %rdx
+ pop %rax
+ pop $2
+ pop $3
+')
diff --git a/gmp/mpn/x86_64/missing.asm b/gmp/mpn/x86_64/missing.asm
new file mode 100644
index 0000000000..9b65c89dd4
--- /dev/null
+++ b/gmp/mpn/x86_64/missing.asm
@@ -0,0 +1,130 @@
+
+ dnl AMD64 MULX/ADX simulation support.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+ASM_START()
+
+C Fake the MULX instruction
+C
+C Accept the single explicit parameter on the stack, return the two result
+C words on the stack. This calling convention means that we need to move the
+C return address up.
+C
+PROLOGUE(__gmp_mulx)
+ lea -8(%rsp), %rsp
+ push %rax
+ push %rdx
+ pushfq C preserve all flags
+ mov 32(%rsp), %rax C move retaddr...
+ mov %rax, 24(%rsp) C ...up the stack
+ mov 40(%rsp), %rax C input parameter
+ mul %rdx
+ mov %rax, 32(%rsp)
+ mov %rdx, 40(%rsp)
+ popfq C restore eflags
+ pop %rdx
+ pop %rax
+ ret
+EPILOGUE()
+PROTECT(__gmp_mulx)
+
+
+C Fake the ADOX instruction
+C
+C Accept the two parameters on the stack, return the result word on the stack.
+C This calling convention means that we need to move the return address down.
+C
+PROLOGUE(__gmp_adox)
+ push %rcx
+ push %rbx
+ push %rax
+ mov 32(%rsp), %rcx C src2
+ mov 24(%rsp), %rax C move retaddr...
+ mov %rax, 32(%rsp) C ...down the stack
+ pushfq
+C copy 0(%rsp):11 to 0(%rsp):0
+ mov (%rsp), %rbx
+ shr %rbx
+ bt $10, %rbx
+ adc %rbx, %rbx
+ push %rbx
+C put manipulated flags into eflags, execute a plain adc
+ popfq
+ adc %rcx, 48(%rsp)
+C copy CF to 0(%rsp):11
+ pop %rbx
+ sbb R32(%rax), R32(%rax)
+ and $0x800, R32(%rax)
+ and $0xfffffffffffff7ff, %rbx
+ or %rax, %rbx
+ push %rbx
+C put manipulated flags into eflags
+ popfq
+ pop %rax
+ pop %rbx
+ pop %rcx
+ lea 8(%rsp), %rsp
+ ret
+EPILOGUE()
+PROTECT(__gmp_adox)
+
+
+C Fake the ADCX instruction
+C
+C Accept the two parameters on the stack, return the result word on the stack.
+C This calling convention means that we need to move the return address down.
+C
+PROLOGUE(__gmp_adcx)
+ push %rcx
+ push %rbx
+ push %rax
+ mov 32(%rsp), %rcx C src2
+ mov 24(%rsp), %rax C move retaddr...
+ mov %rax, 32(%rsp) C ...down the stack
+ pushfq
+ adc %rcx, 48(%rsp)
+ pop %rbx
+ sbb R32(%rax), R32(%rax)
+ and $`'0xfffffffffffffffe, %rbx
+ sub %rax, %rbx
+ push %rbx
+ popfq
+ pop %rax
+ pop %rbx
+ pop %rcx
+ lea 8(%rsp), %rsp
+ ret
+EPILOGUE()
+PROTECT(__gmp_adcx)
diff --git a/gmp/mpn/x86_64/mod_1_1.asm b/gmp/mpn/x86_64/mod_1_1.asm
new file mode 100644
index 0000000000..4a7c45a58b
--- /dev/null
+++ b/gmp/mpn/x86_64/mod_1_1.asm
@@ -0,0 +1,235 @@
+dnl AMD64 mpn_mod_1_1p
+
+dnl Contributed to the GNU project by Torbjörn Granlund and Niels Möller.
+
+dnl Copyright 2009-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 6
+C AMD K10 6
+C Intel P4 26
+C Intel core2 12.5
+C Intel NHM 11.3
+C Intel SBR 8.4 (slowdown, old code took 8.0)
+C Intel atom 26
+C VIA nano 13
+
+define(`B2mb', `%r10')
+define(`B2modb', `%r11')
+define(`ap', `%rdi')
+define(`n', `%rsi')
+define(`pre', `%r8')
+define(`b', `%rbx')
+
+define(`r0', `%rbp') C r1 kept in %rax
+define(`r2', `%rcx') C kept negated. Also used as shift count
+define(`t0', `%r9')
+
+C mp_limb_t
+C mpn_mod_1_1p (mp_srcptr ap, mp_size_t n, mp_limb_t b, mp_limb_t bmodb[4])
+C %rdi %rsi %rdx %rcx
+C The pre array contains bi, cnt, B1modb, B2modb
+C Note: This implementation needs B1modb only when cnt > 0
+
+C The iteration is almost as follows,
+C
+C r_2 B^3 + r_1 B^2 + r_0 B + u = r_1 B2modb + (r_0 + r_2 B2mod) B + u
+C
+C where r2 is a single bit represented as a mask. But to make sure that the
+C result fits in two limbs and a bit, carry from the addition
+C
+C r_0 + r_2 B2mod
+C
+C is handled specially. On carry, we subtract b to cancel the carry,
+C and we use instead the value
+C
+C r_0 + B2mb (mod B)
+C
+C This addition can be issued early since it doesn't depend on r2, and it is
+C the source of the cmov in the loop.
+C
+C We have the invariant that r_2 B^2 + r_1 B + r_0 < B^2 + B b
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_1_1p)
+ FUNC_ENTRY(4)
+ push %rbp
+ push %rbx
+ mov %rdx, b
+ mov %rcx, pre
+
+ mov -8(ap, n, 8), %rax
+ cmp $3, n
+ jnc L(first)
+ mov -16(ap, n, 8), r0
+ jmp L(reduce_two)
+
+L(first):
+ C First iteration, no r2
+ mov 24(pre), B2modb
+ mul B2modb
+ mov -24(ap, n, 8), r0
+ add %rax, r0
+ mov -16(ap, n, 8), %rax
+ adc %rdx, %rax
+ sbb r2, r2
+ sub $4, n
+ jc L(reduce_three)
+
+ mov B2modb, B2mb
+ sub b, B2mb
+
+ ALIGN(16)
+L(top): and B2modb, r2
+ lea (B2mb, r0), t0
+ mul B2modb
+ add r0, r2
+ mov (ap, n, 8), r0
+ cmovc t0, r2
+ add %rax, r0
+ mov r2, %rax
+ adc %rdx, %rax
+ sbb r2, r2
+ sub $1, n
+ jnc L(top)
+
+L(reduce_three):
+ C Eliminate r2
+ and b, r2
+ sub r2, %rax
+
+L(reduce_two):
+ mov 8(pre), R32(%rcx)
+ test R32(%rcx), R32(%rcx)
+ jz L(normalized)
+
+ C Unnormalized, use B1modb to reduce to size < B (b+1)
+ mulq 16(pre)
+ xor t0, t0
+ add %rax, r0
+ adc %rdx, t0
+ mov t0, %rax
+
+ C Left-shift to normalize
+ifdef(`SHLD_SLOW',`
+ shl R8(%rcx), %rax
+ mov r0, t0
+ neg R32(%rcx)
+ shr R8(%rcx), t0
+ or t0, %rax
+ neg R32(%rcx)
+',`
+ shld R8(%rcx), r0, %rax
+')
+ shl R8(%rcx), r0
+ jmp L(udiv)
+
+L(normalized):
+ mov %rax, t0
+ sub b, t0
+ cmovnc t0, %rax
+
+L(udiv):
+ lea 1(%rax), t0
+ mulq (pre)
+ add r0, %rax
+ adc t0, %rdx
+ imul b, %rdx
+ sub %rdx, r0
+ cmp r0, %rax
+ lea (b, r0), %rax
+ cmovnc r0, %rax
+ cmp b, %rax
+ jnc L(fix)
+L(ok): shr R8(%rcx), %rax
+
+ pop %rbx
+ pop %rbp
+ FUNC_EXIT()
+ ret
+L(fix): sub b, %rax
+ jmp L(ok)
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_mod_1_1p_cps)
+ FUNC_ENTRY(2)
+ push %rbp
+ bsr %rsi, %rcx
+ push %rbx
+ mov %rdi, %rbx
+ push %r12
+ xor $63, R32(%rcx)
+ mov %rsi, %r12
+ mov R32(%rcx), R32(%rbp)
+ sal R8(%rcx), %r12
+IFSTD(` mov %r12, %rdi ') C pass parameter
+IFDOS(` mov %r12, %rcx ') C pass parameter
+ CALL( mpn_invert_limb)
+ neg %r12
+ mov %r12, %r8
+ mov %rax, (%rbx) C store bi
+ mov %rbp, 8(%rbx) C store cnt
+ imul %rax, %r12
+ mov %r12, 24(%rbx) C store B2modb
+ mov R32(%rbp), R32(%rcx)
+ test R32(%rcx), R32(%rcx)
+ jz L(z)
+
+ mov $1, R32(%rdx)
+ifdef(`SHLD_SLOW',`
+ C Destroys %rax, unlike shld. Otherwise, we could do B1modb
+ C before B2modb, and get rid of the move %r12, %r8 above.
+
+ shl R8(%rcx), %rdx
+ neg R32(%rcx)
+ shr R8(%rcx), %rax
+ or %rax, %rdx
+ neg R32(%rcx)
+',`
+ shld R8(%rcx), %rax, %rdx
+')
+ imul %rdx, %r8
+ shr R8(%rcx), %r8
+ mov %r8, 16(%rbx) C store B1modb
+L(z):
+ pop %r12
+ pop %rbx
+ pop %rbp
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/mod_1_2.asm b/gmp/mpn/x86_64/mod_1_2.asm
new file mode 100644
index 0000000000..02dd917791
--- /dev/null
+++ b/gmp/mpn/x86_64/mod_1_2.asm
@@ -0,0 +1,238 @@
+dnl AMD64 mpn_mod_1s_2p
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2009-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 4
+C AMD K10 4
+C Intel P4 19
+C Intel core2 8
+C Intel NHM 6.5
+C Intel SBR 4.5
+C Intel atom 28
+C VIA nano 8
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_1s_2p)
+ FUNC_ENTRY(4)
+ push %r14
+ test $1, R8(%rsi)
+ mov %rdx, %r14
+ push %r13
+ mov %rcx, %r13
+ push %r12
+ push %rbp
+ push %rbx
+ mov 16(%rcx), %r10
+ mov 24(%rcx), %rbx
+ mov 32(%rcx), %rbp
+ je L(b0)
+ dec %rsi
+ je L(one)
+ mov -8(%rdi,%rsi,8), %rax
+ mul %r10
+ mov %rax, %r9
+ mov %rdx, %r8
+ mov (%rdi,%rsi,8), %rax
+ add -16(%rdi,%rsi,8), %r9
+ adc $0, %r8
+ mul %rbx
+ add %rax, %r9
+ adc %rdx, %r8
+ jmp L(11)
+
+L(b0): mov -8(%rdi,%rsi,8), %r8
+ mov -16(%rdi,%rsi,8), %r9
+
+L(11): sub $4, %rsi
+ jb L(ed2)
+ lea 40(%rdi,%rsi,8), %rdi
+ mov -40(%rdi), %r11
+ mov -32(%rdi), %rax
+ jmp L(m0)
+
+ ALIGN(16)
+L(top): mov -24(%rdi), %r9
+ add %rax, %r11
+ mov -16(%rdi), %rax
+ adc %rdx, %r12
+ mul %r10
+ add %rax, %r9
+ mov %r11, %rax
+ mov %rdx, %r8
+ adc $0, %r8
+ mul %rbx
+ add %rax, %r9
+ mov %r12, %rax
+ adc %rdx, %r8
+ mul %rbp
+ sub $2, %rsi
+ jb L(ed1)
+ mov -40(%rdi), %r11
+ add %rax, %r9
+ mov -32(%rdi), %rax
+ adc %rdx, %r8
+L(m0): mul %r10
+ add %rax, %r11
+ mov %r9, %rax
+ mov %rdx, %r12
+ adc $0, %r12
+ mul %rbx
+ add %rax, %r11
+ lea -32(%rdi), %rdi C ap -= 4
+ mov %r8, %rax
+ adc %rdx, %r12
+ mul %rbp
+ sub $2, %rsi
+ jae L(top)
+
+L(ed0): mov %r11, %r9
+ mov %r12, %r8
+L(ed1): add %rax, %r9
+ adc %rdx, %r8
+L(ed2): mov 8(%r13), R32(%rdi) C cnt
+ mov %r8, %rax
+ mov %r9, %r8
+ mul %r10
+ add %rax, %r8
+ adc $0, %rdx
+L(1): xor R32(%rcx), R32(%rcx)
+ mov %r8, %r9
+ sub R32(%rdi), R32(%rcx)
+ shr R8(%rcx), %r9
+ mov R32(%rdi), R32(%rcx)
+ sal R8(%rcx), %rdx
+ or %rdx, %r9
+ sal R8(%rcx), %r8
+ mov %r9, %rax
+ mulq (%r13)
+ mov %rax, %rsi
+ inc %r9
+ add %r8, %rsi
+ adc %r9, %rdx
+ imul %r14, %rdx
+ sub %rdx, %r8
+ lea (%r8,%r14), %rax
+ cmp %r8, %rsi
+ cmovc %rax, %r8
+ mov %r8, %rax
+ sub %r14, %rax
+ cmovc %r8, %rax
+ mov R32(%rdi), R32(%rcx)
+ shr R8(%rcx), %rax
+ pop %rbx
+ pop %rbp
+ pop %r12
+ pop %r13
+ pop %r14
+ FUNC_EXIT()
+ ret
+L(one):
+ mov (%rdi), %r8
+ mov 8(%rcx), R32(%rdi)
+ xor %rdx, %rdx
+ jmp L(1)
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_mod_1s_2p_cps)
+ FUNC_ENTRY(2)
+ push %rbp
+ bsr %rsi, %rcx
+ push %rbx
+ mov %rdi, %rbx
+ push %r12
+ xor $63, R32(%rcx)
+ mov %rsi, %r12
+ mov R32(%rcx), R32(%rbp) C preserve cnt over call
+ sal R8(%rcx), %r12 C b << cnt
+IFSTD(` mov %r12, %rdi ') C pass parameter
+IFDOS(` mov %r12, %rcx ') C pass parameter
+ CALL( mpn_invert_limb)
+ mov %r12, %r8
+ mov %rax, %r11
+ mov %rax, (%rbx) C store bi
+ mov %rbp, 8(%rbx) C store cnt
+ neg %r8
+ mov R32(%rbp), R32(%rcx)
+ mov $1, R32(%rsi)
+ifdef(`SHLD_SLOW',`
+ shl R8(%rcx), %rsi
+ neg R32(%rcx)
+ mov %rax, %rbp
+ shr R8(%rcx), %rax
+ or %rax, %rsi
+ mov %rbp, %rax
+ neg R32(%rcx)
+',`
+ shld R8(%rcx), %rax, %rsi C FIXME: Slow on Atom and Nano
+')
+ imul %r8, %rsi
+ mul %rsi
+
+ add %rsi, %rdx
+ shr R8(%rcx), %rsi
+ mov %rsi, 16(%rbx) C store B1modb
+
+ not %rdx
+ imul %r12, %rdx
+ lea (%rdx,%r12), %rsi
+ cmp %rdx, %rax
+ cmovnc %rdx, %rsi
+ mov %r11, %rax
+ mul %rsi
+
+ add %rsi, %rdx
+ shr R8(%rcx), %rsi
+ mov %rsi, 24(%rbx) C store B2modb
+
+ not %rdx
+ imul %r12, %rdx
+ add %rdx, %r12
+ cmp %rdx, %rax
+ cmovnc %rdx, %r12
+
+ shr R8(%rcx), %r12
+ mov %r12, 32(%rbx) C store B3modb
+
+ pop %r12
+ pop %rbx
+ pop %rbp
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/mod_1_4.asm b/gmp/mpn/x86_64/mod_1_4.asm
new file mode 100644
index 0000000000..3ce83dc42e
--- /dev/null
+++ b/gmp/mpn/x86_64/mod_1_4.asm
@@ -0,0 +1,269 @@
+dnl AMD64 mpn_mod_1s_4p
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2009-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 3
+C AMD K10 3
+C Intel P4 15.5
+C Intel core2 5
+C Intel corei 4
+C Intel atom 23
+C VIA nano 4.75
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mod_1s_4p)
+ FUNC_ENTRY(4)
+ push %r15
+ push %r14
+ push %r13
+ push %r12
+ push %rbp
+ push %rbx
+
+ mov %rdx, %r15
+ mov %rcx, %r14
+ mov 16(%rcx), %r11 C B1modb
+ mov 24(%rcx), %rbx C B2modb
+ mov 32(%rcx), %rbp C B3modb
+ mov 40(%rcx), %r13 C B4modb
+ mov 48(%rcx), %r12 C B5modb
+ xor R32(%r8), R32(%r8)
+ mov R32(%rsi), R32(%rdx)
+ and $3, R32(%rdx)
+ je L(b0)
+ cmp $2, R32(%rdx)
+ jc L(b1)
+ je L(b2)
+
+L(b3): lea -24(%rdi,%rsi,8), %rdi
+ mov 8(%rdi), %rax
+ mul %r11
+ mov (%rdi), %r9
+ add %rax, %r9
+ adc %rdx, %r8
+ mov 16(%rdi), %rax
+ mul %rbx
+ jmp L(m0)
+
+ ALIGN(8)
+L(b0): lea -32(%rdi,%rsi,8), %rdi
+ mov 8(%rdi), %rax
+ mul %r11
+ mov (%rdi), %r9
+ add %rax, %r9
+ adc %rdx, %r8
+ mov 16(%rdi), %rax
+ mul %rbx
+ add %rax, %r9
+ adc %rdx, %r8
+ mov 24(%rdi), %rax
+ mul %rbp
+ jmp L(m0)
+
+ ALIGN(8)
+L(b1): lea -8(%rdi,%rsi,8), %rdi
+ mov (%rdi), %r9
+ jmp L(m1)
+
+ ALIGN(8)
+L(b2): lea -16(%rdi,%rsi,8), %rdi
+ mov 8(%rdi), %r8
+ mov (%rdi), %r9
+ jmp L(m1)
+
+ ALIGN(16)
+L(top): mov -24(%rdi), %rax
+ mov -32(%rdi), %r10
+ mul %r11 C up[1] * B1modb
+ add %rax, %r10
+ mov -16(%rdi), %rax
+ mov $0, R32(%rcx)
+ adc %rdx, %rcx
+ mul %rbx C up[2] * B2modb
+ add %rax, %r10
+ mov -8(%rdi), %rax
+ adc %rdx, %rcx
+ sub $32, %rdi
+ mul %rbp C up[3] * B3modb
+ add %rax, %r10
+ mov %r13, %rax
+ adc %rdx, %rcx
+ mul %r9 C rl * B4modb
+ add %rax, %r10
+ mov %r12, %rax
+ adc %rdx, %rcx
+ mul %r8 C rh * B5modb
+ mov %r10, %r9
+ mov %rcx, %r8
+L(m0): add %rax, %r9
+ adc %rdx, %r8
+L(m1): sub $4, %rsi
+ ja L(top)
+
+L(end): mov 8(%r14), R32(%rsi)
+ mov %r8, %rax
+ mul %r11
+ mov %rax, %r8
+ add %r9, %r8
+ adc $0, %rdx
+ xor R32(%rcx), R32(%rcx)
+ sub R32(%rsi), R32(%rcx)
+ mov %r8, %rdi
+ shr R8(%rcx), %rdi
+ mov R32(%rsi), R32(%rcx)
+ sal R8(%rcx), %rdx
+ or %rdx, %rdi
+ mov %rdi, %rax
+ mulq (%r14)
+ mov %r15, %rbx
+ mov %rax, %r9
+ sal R8(%rcx), %r8
+ inc %rdi
+ add %r8, %r9
+ adc %rdi, %rdx
+ imul %rbx, %rdx
+ sub %rdx, %r8
+ lea (%r8,%rbx), %rax
+ cmp %r8, %r9
+ cmovc %rax, %r8
+ mov %r8, %rax
+ sub %rbx, %rax
+ cmovc %r8, %rax
+ shr R8(%rcx), %rax
+ pop %rbx
+ pop %rbp
+ pop %r12
+ pop %r13
+ pop %r14
+ pop %r15
+ FUNC_EXIT()
+ ret
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(mpn_mod_1s_4p_cps)
+ FUNC_ENTRY(2)
+ push %rbp
+ bsr %rsi, %rcx
+ push %rbx
+ mov %rdi, %rbx
+ push %r12
+ xor $63, R32(%rcx)
+ mov %rsi, %r12
+ mov R32(%rcx), R32(%rbp) C preserve cnt over call
+ sal R8(%rcx), %r12 C b << cnt
+IFSTD(` mov %r12, %rdi ') C pass parameter
+IFDOS(` mov %r12, %rcx ') C pass parameter
+ CALL( mpn_invert_limb)
+ mov %r12, %r8
+ mov %rax, %r11
+ mov %rax, (%rbx) C store bi
+ mov %rbp, 8(%rbx) C store cnt
+ neg %r8
+ mov R32(%rbp), R32(%rcx)
+ mov $1, R32(%rsi)
+ifdef(`SHLD_SLOW',`
+ shl R8(%rcx), %rsi
+ neg R32(%rcx)
+ mov %rax, %rbp
+ shr R8(%rcx), %rax
+ or %rax, %rsi
+ mov %rbp, %rax
+ neg R32(%rcx)
+',`
+ shld R8(%rcx), %rax, %rsi C FIXME: Slow on Atom and Nano
+')
+ imul %r8, %rsi
+ mul %rsi
+
+ add %rsi, %rdx
+ shr R8(%rcx), %rsi
+ mov %rsi, 16(%rbx) C store B1modb
+
+ not %rdx
+ imul %r12, %rdx
+ lea (%rdx,%r12), %rsi
+ cmp %rdx, %rax
+ cmovnc %rdx, %rsi
+ mov %r11, %rax
+ mul %rsi
+
+ add %rsi, %rdx
+ shr R8(%rcx), %rsi
+ mov %rsi, 24(%rbx) C store B2modb
+
+ not %rdx
+ imul %r12, %rdx
+ lea (%rdx,%r12), %rsi
+ cmp %rdx, %rax
+ cmovnc %rdx, %rsi
+ mov %r11, %rax
+ mul %rsi
+
+ add %rsi, %rdx
+ shr R8(%rcx), %rsi
+ mov %rsi, 32(%rbx) C store B3modb
+
+ not %rdx
+ imul %r12, %rdx
+ lea (%rdx,%r12), %rsi
+ cmp %rdx, %rax
+ cmovnc %rdx, %rsi
+ mov %r11, %rax
+ mul %rsi
+
+ add %rsi, %rdx
+ shr R8(%rcx), %rsi
+ mov %rsi, 40(%rbx) C store B4modb
+
+ not %rdx
+ imul %r12, %rdx
+ add %rdx, %r12
+ cmp %rdx, %rax
+ cmovnc %rdx, %r12
+
+ shr R8(%rcx), %r12
+ mov %r12, 48(%rbx) C store B5modb
+
+ pop %r12
+ pop %rbx
+ pop %rbp
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/mod_34lsub1.asm b/gmp/mpn/x86_64/mod_34lsub1.asm
new file mode 100644
index 0000000000..62bdcfac69
--- /dev/null
+++ b/gmp/mpn/x86_64/mod_34lsub1.asm
@@ -0,0 +1,205 @@
+dnl AMD64 mpn_mod_34lsub1 -- remainder modulo 2^48-1.
+
+dnl Copyright 2000-2002, 2004, 2005, 2007, 2009-2012 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 0.67 0.583 is possible with zero-reg instead of $0, 4-way
+C AMD K10 0.67 this seems hard to beat
+C AMD bd1 1
+C AMD bobcat 1.07
+C Intel P4 7.35 terrible, use old code
+C Intel core2 1.25 1+epsilon with huge unrolling
+C Intel NHM 1.15 this seems hard to beat
+C Intel SBR 0.93
+C Intel atom 2.5
+C VIA nano 1.25 this seems hard to beat
+
+C INPUT PARAMETERS
+define(`ap', %rdi)
+define(`n', %rsi)
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr up, mp_size_t n)
+
+C TODO
+C * Review feed-in and wind-down code.
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mod_34lsub1)
+ FUNC_ENTRY(2)
+
+ mov $0x0000FFFFFFFFFFFF, %r11
+
+ mov (ap), %rax
+
+ cmp $2, %rsi
+ ja L(gt2)
+
+ jb L(one)
+
+ mov 8(ap), %rsi
+ mov %rax, %rdx
+ shr $48, %rax C src[0] low
+
+ and %r11, %rdx C src[0] high
+ add %rdx, %rax
+ mov R32(%rsi), R32(%rdx)
+
+ shr $32, %rsi C src[1] high
+ add %rsi, %rax
+
+ shl $16, %rdx C src[1] low
+ add %rdx, %rax
+L(one): FUNC_EXIT()
+ ret
+
+
+C Don't change this, the wind-down code is not able to handle greater values
+define(UNROLL,3)
+
+L(gt2): mov 8(ap), %rcx
+ mov 16(ap), %rdx
+ xor %r9, %r9
+ add $24, ap
+ sub $eval(UNROLL*3+3), %rsi
+ jc L(end)
+ ALIGN(16)
+L(top):
+ add (ap), %rax
+ adc 8(ap), %rcx
+ adc 16(ap), %rdx
+ adc $0, %r9
+forloop(i,1,UNROLL-1,`dnl
+ add eval(i*24)(ap), %rax
+ adc eval(i*24+8)(ap), %rcx
+ adc eval(i*24+16)(ap), %rdx
+ adc $0, %r9
+')dnl
+ add $eval(UNROLL*24), ap
+ sub $eval(UNROLL*3), %rsi
+ jnc L(top)
+
+L(end):
+ lea L(tab)(%rip), %r8
+ifdef(`PIC',
+` movslq 36(%r8,%rsi,4), %r10
+ add %r10, %r8
+ jmp *%r8
+',`
+ jmp *72(%r8,%rsi,8)
+')
+ JUMPTABSECT
+ ALIGN(8)
+L(tab): JMPENT( L(0), L(tab))
+ JMPENT( L(1), L(tab))
+ JMPENT( L(2), L(tab))
+ JMPENT( L(3), L(tab))
+ JMPENT( L(4), L(tab))
+ JMPENT( L(5), L(tab))
+ JMPENT( L(6), L(tab))
+ JMPENT( L(7), L(tab))
+ JMPENT( L(8), L(tab))
+ TEXT
+
+L(6): add (ap), %rax
+ adc 8(ap), %rcx
+ adc 16(ap), %rdx
+ adc $0, %r9
+ add $24, ap
+L(3): add (ap), %rax
+ adc 8(ap), %rcx
+ adc 16(ap), %rdx
+ jmp L(cj1)
+
+L(7): add (ap), %rax
+ adc 8(ap), %rcx
+ adc 16(ap), %rdx
+ adc $0, %r9
+ add $24, ap
+L(4): add (ap), %rax
+ adc 8(ap), %rcx
+ adc 16(ap), %rdx
+ adc $0, %r9
+ add $24, ap
+L(1): add (ap), %rax
+ adc $0, %rcx
+ jmp L(cj2)
+
+L(8): add (ap), %rax
+ adc 8(ap), %rcx
+ adc 16(ap), %rdx
+ adc $0, %r9
+ add $24, ap
+L(5): add (ap), %rax
+ adc 8(ap), %rcx
+ adc 16(ap), %rdx
+ adc $0, %r9
+ add $24, ap
+L(2): add (ap), %rax
+ adc 8(ap), %rcx
+
+L(cj2): adc $0, %rdx
+L(cj1): adc $0, %r9
+L(0): add %r9, %rax
+ adc $0, %rcx
+ adc $0, %rdx
+ adc $0, %rax
+
+ mov %rax, %rdi C 0mod3
+ shr $48, %rax C 0mod3 high
+
+ and %r11, %rdi C 0mod3 low
+ mov R32(%rcx), R32(%r10) C 1mod3
+
+ shr $32, %rcx C 1mod3 high
+
+ add %rdi, %rax C apply 0mod3 low
+ movzwl %dx, R32(%rdi) C 2mod3
+ shl $16, %r10 C 1mod3 low
+
+ add %rcx, %rax C apply 1mod3 high
+ shr $16, %rdx C 2mod3 high
+
+ add %r10, %rax C apply 1mod3 low
+ shl $32, %rdi C 2mod3 low
+
+ add %rdx, %rax C apply 2mod3 high
+ add %rdi, %rax C apply 2mod3 low
+
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/mode1o.asm b/gmp/mpn/x86_64/mode1o.asm
new file mode 100644
index 0000000000..2cd2b08848
--- /dev/null
+++ b/gmp/mpn/x86_64/mode1o.asm
@@ -0,0 +1,171 @@
+dnl AMD64 mpn_modexact_1_odd -- Hensel norm remainder.
+
+dnl Copyright 2000-2006, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 10
+C AMD K10 10
+C Intel P4 33
+C Intel core2 13
+C Intel corei 14.5
+C Intel atom 35
+C VIA nano ?
+
+
+C The dependent chain in the main loop is
+C
+C cycles
+C sub %rdx, %rax 1
+C imul %r9, %rax 4
+C mul %r8 5
+C ----
+C total 10
+C
+C The mov load from src seems to need to be scheduled back before the jz to
+C achieve this speed, out-of-order execution apparently can't completely hide
+C the latency otherwise.
+C
+C The l=src[i]-cbit step is rotated back too, since that allows us to avoid it
+C for the first iteration (where there's no cbit).
+C
+C The code alignment used (32-byte) for the loop also seems necessary. Without
+C that the non-PIC case has adc crossing the 0x60 offset, apparently making it
+C run at 11 cycles instead of 10.
+
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_modexact_1_odd)
+ FUNC_ENTRY(3)
+ mov $0, R32(%rcx)
+IFDOS(` jmp L(ent) ')
+
+PROLOGUE(mpn_modexact_1c_odd)
+ FUNC_ENTRY(4)
+L(ent):
+ C rdi src
+ C rsi size
+ C rdx divisor
+ C rcx carry
+
+ mov %rdx, %r8 C d
+ shr R32(%rdx) C d/2
+
+ LEA( binvert_limb_table, %r9)
+
+ and $127, R32(%rdx)
+ mov %rcx, %r10 C initial carry
+
+ movzbl (%r9,%rdx), R32(%rdx) C inv 8 bits
+
+ mov (%rdi), %rax C src[0]
+ lea (%rdi,%rsi,8), %r11 C src end
+ mov %r8, %rdi C d, made available to imull
+
+ lea (%rdx,%rdx), R32(%rcx) C 2*inv
+ imul R32(%rdx), R32(%rdx) C inv*inv
+
+ neg %rsi C -size
+
+ imul R32(%rdi), R32(%rdx) C inv*inv*d
+
+ sub R32(%rdx), R32(%rcx) C inv = 2*inv - inv*inv*d, 16 bits
+
+ lea (%rcx,%rcx), R32(%rdx) C 2*inv
+ imul R32(%rcx), R32(%rcx) C inv*inv
+
+ imul R32(%rdi), R32(%rcx) C inv*inv*d
+
+ sub R32(%rcx), R32(%rdx) C inv = 2*inv - inv*inv*d, 32 bits
+ xor R32(%rcx), R32(%rcx) C initial cbit
+
+ lea (%rdx,%rdx), %r9 C 2*inv
+ imul %rdx, %rdx C inv*inv
+
+ imul %r8, %rdx C inv*inv*d
+
+ sub %rdx, %r9 C inv = 2*inv - inv*inv*d, 64 bits
+ mov %r10, %rdx C initial climb
+
+ ASSERT(e,` C d*inv == 1 mod 2^64
+ mov %r8, %r10
+ imul %r9, %r10
+ cmp $1, %r10')
+
+ inc %rsi
+ jz L(one)
+
+
+ ALIGN(16)
+L(top):
+ C rax l = src[i]-cbit
+ C rcx new cbit, 0 or 1
+ C rdx climb, high of last product
+ C rsi counter, limbs, negative
+ C rdi
+ C r8 divisor
+ C r9 inverse
+ C r11 src end ptr
+
+ sub %rdx, %rax C l = src[i]-cbit - climb
+
+ adc $0, %rcx C more cbit
+ imul %r9, %rax C q = l * inverse
+
+ mul %r8 C climb = high (q * d)
+
+ mov (%r11,%rsi,8), %rax C src[i+1]
+ sub %rcx, %rax C next l = src[i+1] - cbit
+ setc R8(%rcx) C new cbit
+
+ inc %rsi
+ jnz L(top)
+
+
+L(one):
+ sub %rdx, %rax C l = src[i]-cbit - climb
+
+ adc $0, %rcx C more cbit
+ imul %r9, %rax C q = l * inverse
+
+ mul %r8 C climb = high (q * d)
+
+ lea (%rcx,%rdx), %rax C climb+cbit
+ FUNC_EXIT()
+ ret
+
+EPILOGUE(mpn_modexact_1c_odd)
+EPILOGUE(mpn_modexact_1_odd)
diff --git a/gmp/mpn/x86_64/mul_1.asm b/gmp/mpn/x86_64/mul_1.asm
new file mode 100644
index 0000000000..b032afc9dd
--- /dev/null
+++ b/gmp/mpn/x86_64/mul_1.asm
@@ -0,0 +1,183 @@
+dnl AMD64 mpn_mul_1.
+
+dnl Copyright 2003-2005, 2007, 2008, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.5
+C AMD K10 2.5
+C AMD bd1 5.0
+C AMD bobcat 5.5
+C Intel P4 12.3
+C Intel core2 4.0
+C Intel NHM 3.75
+C Intel SBR 2.95
+C Intel atom 19.8
+C VIA nano 4.25
+
+C The loop of this code is the result of running a code generation and
+C optimization tool suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * The loop is great, but the prologue and epilogue code was quickly written.
+C Tune it!
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`vl', `%rcx') C r9
+
+define(`n', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+IFDOS(` define(`up', ``%rsi'') ') dnl
+IFDOS(` define(`rp', ``%rcx'') ') dnl
+IFDOS(` define(`vl', ``%r9'') ') dnl
+IFDOS(` define(`r9', ``rdi'') ') dnl
+IFDOS(` define(`n', ``%r8'') ') dnl
+IFDOS(` define(`r8', ``r11'') ') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_1c)
+IFDOS(``push %rsi '')
+IFDOS(``push %rdi '')
+IFDOS(``mov %rdx, %rsi '')
+ push %rbx
+IFSTD(` mov %r8, %r10')
+IFDOS(` mov 64(%rsp), %r10') C 40 + 3*8 (3 push insns)
+ jmp L(common)
+EPILOGUE()
+
+PROLOGUE(mpn_mul_1)
+IFDOS(``push %rsi '')
+IFDOS(``push %rdi '')
+IFDOS(``mov %rdx, %rsi '')
+
+ push %rbx
+ xor %r10, %r10
+L(common):
+ mov (up), %rax C read first u limb early
+IFSTD(` mov n_param, %rbx ') C move away n from rdx, mul uses it
+IFDOS(` mov n, %rbx ')
+ mul vl
+IFSTD(` mov %rbx, n ')
+
+ add %r10, %rax
+ adc $0, %rdx
+
+ and $3, R32(%rbx)
+ jz L(b0)
+ cmp $2, R32(%rbx)
+ jz L(b2)
+ jg L(b3)
+
+L(b1): dec n
+ jne L(gt1)
+ mov %rax, (rp)
+ jmp L(ret)
+L(gt1): lea 8(up,n,8), up
+ lea -8(rp,n,8), rp
+ neg n
+ xor %r10, %r10
+ xor R32(%rbx), R32(%rbx)
+ mov %rax, %r9
+ mov (up,n,8), %rax
+ mov %rdx, %r8
+ jmp L(L1)
+
+L(b0): lea (up,n,8), up
+ lea -16(rp,n,8), rp
+ neg n
+ xor %r10, %r10
+ mov %rax, %r8
+ mov %rdx, %rbx
+ jmp L(L0)
+
+L(b3): lea -8(up,n,8), up
+ lea -24(rp,n,8), rp
+ neg n
+ mov %rax, %rbx
+ mov %rdx, %r10
+ jmp L(L3)
+
+L(b2): lea -16(up,n,8), up
+ lea -32(rp,n,8), rp
+ neg n
+ xor %r8, %r8
+ xor R32(%rbx), R32(%rbx)
+ mov %rax, %r10
+ mov 24(up,n,8), %rax
+ mov %rdx, %r9
+ jmp L(L2)
+
+ ALIGN(16)
+L(top): mov %r10, (rp,n,8)
+ add %rax, %r9
+ mov (up,n,8), %rax
+ adc %rdx, %r8
+ mov $0, R32(%r10)
+L(L1): mul vl
+ mov %r9, 8(rp,n,8)
+ add %rax, %r8
+ adc %rdx, %rbx
+L(L0): mov 8(up,n,8), %rax
+ mul vl
+ mov %r8, 16(rp,n,8)
+ add %rax, %rbx
+ adc %rdx, %r10
+L(L3): mov 16(up,n,8), %rax
+ mul vl
+ mov %rbx, 24(rp,n,8)
+ mov $0, R32(%r8) C zero
+ mov %r8, %rbx C zero
+ add %rax, %r10
+ mov 24(up,n,8), %rax
+ mov %r8, %r9 C zero
+ adc %rdx, %r9
+L(L2): mul vl
+ add $4, n
+ js L(top)
+
+ mov %r10, (rp,n,8)
+ add %rax, %r9
+ adc %r8, %rdx
+ mov %r9, 8(rp,n,8)
+ add %r8, %rdx
+L(ret): mov %rdx, %rax
+
+ pop %rbx
+IFDOS(``pop %rdi '')
+IFDOS(``pop %rsi '')
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/mul_2.asm b/gmp/mpn/x86_64/mul_2.asm
new file mode 100644
index 0000000000..f408c52250
--- /dev/null
+++ b/gmp/mpn/x86_64/mul_2.asm
@@ -0,0 +1,192 @@
+dnl AMD64 mpn_mul_2 -- Multiply an n-limb vector with a 2-limb vector and
+dnl store the result in a third limb vector.
+
+dnl Copyright 2008, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.275
+C AMD K10 2.275
+C Intel P4 13.5
+C Intel core2 4.0
+C Intel corei 3.8
+C Intel atom ?
+C VIA nano ?
+
+C This code is the result of running a code generation and optimization tool
+C suite written by David Harvey and Torbjorn Granlund.
+
+C TODO
+C * Work on feed-in and wind-down code.
+C * Convert "mov $0" to "xor".
+C * Adjust initial lea to save some bytes.
+C * Perhaps adjust n from n_param&3 value?
+C * Replace with 2.25 c/l sequence.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n_param',`%rdx')
+define(`vp', `%rcx')
+
+define(`v0', `%r8')
+define(`v1', `%r9')
+define(`w0', `%rbx')
+define(`w1', `%rcx')
+define(`w2', `%rbp')
+define(`w3', `%r10')
+define(`n', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_2)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov (vp), v0
+ mov 8(vp), v1
+
+ mov (up), %rax
+
+ mov n_param, n
+ neg n
+ lea -8(up,n_param,8), up
+ lea -8(rp,n_param,8), rp
+
+ and $3, R32(n_param)
+ jz L(m2p0)
+ cmp $2, R32(n_param)
+ jc L(m2p1)
+ jz L(m2p2)
+L(m2p3):
+ mul v0
+ xor R32(w3), R32(w3)
+ mov %rax, w1
+ mov %rdx, w2
+ mov 8(up,n,8), %rax
+ add $-1, n
+ mul v1
+ add %rax, w2
+ jmp L(m23)
+L(m2p0):
+ mul v0
+ xor R32(w2), R32(w2)
+ mov %rax, w0
+ mov %rdx, w1
+ jmp L(m20)
+L(m2p1):
+ mul v0
+ xor R32(w3), R32(w3)
+ xor R32(w0), R32(w0)
+ xor R32(w1), R32(w1)
+ add $1, n
+ jmp L(m2top)
+L(m2p2):
+ mul v0
+ xor R32(w0), R32(w0)
+ xor R32(w1), R32(w1)
+ mov %rax, w2
+ mov %rdx, w3
+ mov 8(up,n,8), %rax
+ add $-2, n
+ jmp L(m22)
+
+
+ ALIGN(32)
+L(m2top):
+ add %rax, w3
+ adc %rdx, w0
+ mov 0(up,n,8), %rax
+ adc $0, R32(w1)
+ mov $0, R32(w2)
+ mul v1
+ add %rax, w0
+ mov w3, 0(rp,n,8)
+ adc %rdx, w1
+ mov 8(up,n,8), %rax
+ mul v0
+ add %rax, w0
+ adc %rdx, w1
+ adc $0, R32(w2)
+L(m20): mov 8(up,n,8), %rax
+ mul v1
+ add %rax, w1
+ adc %rdx, w2
+ mov 16(up,n,8), %rax
+ mov $0, R32(w3)
+ mul v0
+ add %rax, w1
+ mov 16(up,n,8), %rax
+ adc %rdx, w2
+ adc $0, R32(w3)
+ mul v1
+ add %rax, w2
+ mov w0, 8(rp,n,8)
+L(m23): adc %rdx, w3
+ mov 24(up,n,8), %rax
+ mul v0
+ mov $0, R32(w0)
+ add %rax, w2
+ adc %rdx, w3
+ mov w1, 16(rp,n,8)
+ mov 24(up,n,8), %rax
+ mov $0, R32(w1)
+ adc $0, R32(w0)
+L(m22): mul v1
+ add %rax, w3
+ mov w2, 24(rp,n,8)
+ adc %rdx, w0
+ mov 32(up,n,8), %rax
+ mul v0
+ add $4, n
+ js L(m2top)
+
+
+ add %rax, w3
+ adc %rdx, w0
+ adc $0, R32(w1)
+ mov (up), %rax
+ mul v1
+ mov w3, (rp)
+ add %rax, w0
+ adc %rdx, w1
+ mov w0, 8(rp)
+ mov w1, %rax
+
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/mulx/adx/addmul_1.asm b/gmp/mpn/x86_64/mulx/adx/addmul_1.asm
new file mode 100644
index 0000000000..ea607899a4
--- /dev/null
+++ b/gmp/mpn/x86_64/mulx/adx/addmul_1.asm
@@ -0,0 +1,149 @@
+dnl AMD64 mpn_addmul_1 for CPUs with mulx and adx.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 -
+C AMD K10 -
+C AMD bd1 -
+C AMD bobcat -
+C Intel P4 -
+C Intel PNR -
+C Intel NHM -
+C Intel SBR -
+C Intel HWL -
+C Intel BWL ?
+C Intel atom -
+C VIA nano -
+
+define(`rp', `%rdi') dnl rcx
+define(`up', `%rsi') dnl rdx
+define(`n_param', `%rdx') dnl r8
+define(`v0_param',`%rcx') dnl r9
+
+define(`n', `%rcx') dnl
+define(`v0', `%rdx') dnl
+
+C Testing mechanism for running this on older AMD64 processors
+ifelse(FAKE_MULXADX,1,`
+ include(CONFIG_TOP_SRCDIR`/mpn/x86_64/missing-call.m4')
+',`
+ define(`adox', ``adox' $1, $2')
+ define(`adcx', ``adcx' $1, $2')
+ define(`mulx', ``mulx' $1, $2, $3')
+')
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_addmul_1)
+ mov (up), %r8
+
+ push %rbx
+ push %r12
+ push %r13
+
+ lea (up,n_param,8), up
+ lea -16(rp,n_param,8), rp
+ mov R32(n_param), R32(%rax)
+ xchg v0_param, v0 C FIXME: is this insn fast?
+
+ neg n
+
+ and $3, R8(%rax)
+ jz L(b0)
+ cmp $2, R8(%rax)
+ jl L(b1)
+ jz L(b2)
+
+L(b3): mulx( (up,n,8), %r11, %r10)
+ mulx( 8(up,n,8), %r13, %r12)
+ mulx( 16(up,n,8), %rbx, %rax)
+ dec n
+ jmp L(lo3)
+
+L(b0): mulx( (up,n,8), %r9, %r8)
+ mulx( 8(up,n,8), %r11, %r10)
+ mulx( 16(up,n,8), %r13, %r12)
+ jmp L(lo0)
+
+L(b2): mulx( (up,n,8), %r13, %r12)
+ mulx( 8(up,n,8), %rbx, %rax)
+ lea 2(n), n
+ jrcxz L(wd2)
+L(gt2): mulx( (up,n,8), %r9, %r8)
+ jmp L(lo2)
+
+L(b1): and R8(%rax), R8(%rax)
+ mulx( (up,n,8), %rbx, %rax)
+ lea 1(n), n
+ jrcxz L(wd1)
+ mulx( (up,n,8), %r9, %r8)
+ mulx( 8(up,n,8), %r11, %r10)
+ jmp L(lo1)
+
+L(end): adcx( %r10, %r13)
+ mov %r11, -8(rp)
+L(wd2): adox( (rp), %r13)
+ adcx( %r12, %rbx)
+ mov %r13, (rp)
+L(wd1): adox( 8(rp), %rbx)
+ adcx( %rcx, %rax)
+ adox( %rcx, %rax)
+ mov %rbx, 8(rp)
+ pop %r13
+ pop %r12
+ pop %rbx
+ ret
+
+L(top): jrcxz L(end)
+ mulx( (up,n,8), %r9, %r8)
+ adcx( %r10, %r13)
+ mov %r11, -8(rp,n,8)
+L(lo2): adox( (rp,n,8), %r13)
+ mulx( 8(up,n,8), %r11, %r10)
+ adcx( %r12, %rbx)
+ mov %r13, (rp,n,8)
+L(lo1): adox( 8(rp,n,8), %rbx)
+ mulx( 16(up,n,8), %r13, %r12)
+ adcx( %rax, %r9)
+ mov %rbx, 8(rp,n,8)
+L(lo0): adox( 16(rp,n,8), %r9)
+ mulx( 24(up,n,8), %rbx, %rax)
+ adcx( %r8, %r11)
+ mov %r9, 16(rp,n,8)
+L(lo3): adox( 24(rp,n,8), %r11)
+ lea 4(n), n
+ jmp L(top)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/mulx/aorsmul_1.asm b/gmp/mpn/x86_64/mulx/aorsmul_1.asm
new file mode 100644
index 0000000000..285c07335e
--- /dev/null
+++ b/gmp/mpn/x86_64/mulx/aorsmul_1.asm
@@ -0,0 +1,161 @@
+dnl AMD64 mpn_addmul_1 and mpn_submul_1 for CPUs with mulx.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 -
+C AMD K10 -
+C AMD bd1 -
+C AMD bd2 ?
+C AMD bobcat -
+C AMD jaguar ?
+C Intel P4 -
+C Intel PNR -
+C Intel NHM -
+C Intel SBR -
+C Intel HWL ?
+C Intel BWL ?
+C Intel atom -
+C VIA nano -
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0_param',`%rcx') C r9
+
+define(`n', `%rcx')
+define(`v0', `%rdx')
+
+ifdef(`OPERATION_addmul_1',`
+ define(`ADDSUB', `add')
+ define(`ADCSBB', `adc')
+ define(`func', `mpn_addmul_1')
+')
+ifdef(`OPERATION_submul_1',`
+ define(`ADDSUB', `sub')
+ define(`ADCSBB', `sbb')
+ define(`func', `mpn_submul_1')
+')
+
+MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
+
+IFDOS(` define(`up', ``%rsi'') ') dnl
+IFDOS(` define(`rp', ``%rcx'') ') dnl
+IFDOS(` define(`vl', ``%r9'') ') dnl
+IFDOS(` define(`r9', ``rdi'') ') dnl
+IFDOS(` define(`n', ``%r8'') ') dnl
+IFDOS(` define(`r8', ``r11'') ') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ mov (up), %r8
+
+ push %rbx
+ push %r12
+ push %r13
+
+ lea (up,n_param,8), up
+ lea -32(rp,n_param,8), rp
+ mov R32(n_param), R32(%rax)
+ xchg v0_param, v0 C FIXME: is this insn fast?
+
+ neg n
+
+ and $3, R8(%rax)
+ jz L(b0)
+ cmp $2, R8(%rax)
+ jz L(b2)
+ jg L(b3)
+
+L(b1): mulx %r8, %rbx, %rax
+ sub $-1, n
+ jz L(wd1)
+ mulx (up,n,8), %r9, %r8
+ mulx 8(up,n,8), %r11, %r10
+ test R32(%rax), R32(%rax) C clear cy
+ jmp L(lo1)
+
+L(b0): mulx %r8, %r9, %r8
+ mulx 8(up,n,8), %r11, %r10
+ mulx 16(up,n,8), %r13, %r12
+ xor R32(%rax), R32(%rax)
+ jmp L(lo0)
+
+L(b3): mulx %r8, %r11, %r10
+ mulx 8(up,n,8), %r13, %r12
+ mulx 16(up,n,8), %rbx, %rax
+ add %r10, %r13
+ adc %r12, %rbx
+ adc $0, %rax
+ sub $-3, n
+ jz L(wd3)
+ test R32(%rax), R32(%rax) C clear cy
+ jmp L(lo3)
+
+L(b2): mulx %r8, %r13, %r12
+ mulx 8(up,n,8), %rbx, %rax
+ add %r12, %rbx
+ adc $0, %rax
+ sub $-2, n
+ jz L(wd2)
+ mulx (up,n,8), %r9, %r8
+ test R32(%rax), R32(%rax) C clear cy
+ jmp L(lo2)
+
+L(top): ADDSUB %r9, (rp,n,8)
+L(lo3): mulx (up,n,8), %r9, %r8
+ ADCSBB %r11, 8(rp,n,8)
+L(lo2): mulx 8(up,n,8), %r11, %r10
+ ADCSBB %r13, 16(rp,n,8)
+L(lo1): mulx 16(up,n,8), %r13, %r12
+ ADCSBB %rbx, 24(rp,n,8)
+ adc %rax, %r9
+L(lo0): mulx 24(up,n,8), %rbx, %rax
+ adc %r8, %r11
+ adc %r10, %r13
+ adc %r12, %rbx
+ adc $0, %rax C rax = carry limb
+ add $4, n
+ js L(top)
+
+L(end): ADDSUB %r9, (rp)
+L(wd3): ADCSBB %r11, 8(rp)
+L(wd2): ADCSBB %r13, 16(rp)
+L(wd1): ADCSBB %rbx, 24(rp)
+ adc n, %rax
+ pop %r13
+ pop %r12
+ pop %rbx
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/mulx/mul_1.asm b/gmp/mpn/x86_64/mulx/mul_1.asm
new file mode 100644
index 0000000000..34a044dcdc
--- /dev/null
+++ b/gmp/mpn/x86_64/mulx/mul_1.asm
@@ -0,0 +1,154 @@
+dnl AMD64 mpn_mul_1 for CPUs with mulx.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 -
+C AMD K10 -
+C AMD bd1 -
+C AMD bd2 ?
+C AMD bobcat -
+C AMD jaguar ?
+C Intel P4 -
+C Intel PNR -
+C Intel NHM -
+C Intel SBR -
+C Intel HWL ?
+C Intel BWL ?
+C Intel atom -
+C VIA nano -
+
+define(`rp', `%rdi') C rcx
+define(`up', `%rsi') C rdx
+define(`n_param', `%rdx') C r8
+define(`v0_param',`%rcx') C r9
+
+define(`n', `%rcx')
+define(`v0', `%rdx')
+
+IFDOS(` define(`up', ``%rsi'') ') dnl
+IFDOS(` define(`rp', ``%rcx'') ') dnl
+IFDOS(` define(`v0', ``%r9'') ') dnl
+IFDOS(` define(`r9', ``rdi'') ') dnl
+IFDOS(` define(`n', ``%r8'') ') dnl
+IFDOS(` define(`r8', ``r11'') ') dnl
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_mul_1c)
+ jmp L(ent)
+EPILOGUE()
+PROLOGUE(mpn_mul_1)
+ xor R32(%r8), R32(%r8) C carry-in limb
+L(ent): mov (up), %r9
+
+ push %rbx
+ push %r12
+ push %r13
+
+ lea (up,n_param,8), up
+ lea -32(rp,n_param,8), rp
+ mov R32(n_param), R32(%rax)
+ xchg v0_param, v0 C FIXME: is this insn fast?
+
+ neg n
+
+ and $3, R8(%rax)
+ jz L(b0)
+ cmp $2, R8(%rax)
+ jz L(b2)
+ jg L(b3)
+
+L(b1): mov %r8, %r12
+ mulx %r9, %rbx, %rax
+ sub $-1, n
+ jz L(wd1)
+ mulx (up,n,8), %r9, %r8
+ mulx 8(up,n,8), %r11, %r10
+ add %r12, %rbx
+ jmp L(lo1)
+
+L(b3): mulx %r9, %r11, %r10
+ mulx 8(up,n,8), %r13, %r12
+ mulx 16(up,n,8), %rbx, %rax
+ sub $-3, n
+ jz L(wd3)
+ add %r8, %r11
+ jmp L(lo3)
+
+L(b2): mov %r8, %r10 C carry-in limb
+ mulx %r9, %r13, %r12
+ mulx 8(up,n,8), %rbx, %rax
+ sub $-2, n
+ jz L(wd2)
+ mulx (up,n,8), %r9, %r8
+ add %r10, %r13
+ jmp L(lo2)
+
+L(b0): mov %r8, %rax C carry-in limb
+ mulx %r9, %r9, %r8
+ mulx 8(up,n,8), %r11, %r10
+ mulx 16(up,n,8), %r13, %r12
+ add %rax, %r9
+ jmp L(lo0)
+
+L(top): jrcxz L(end)
+ adc %r8, %r11
+ mov %r9, (rp,n,8)
+L(lo3): mulx (up,n,8), %r9, %r8
+ adc %r10, %r13
+ mov %r11, 8(rp,n,8)
+L(lo2): mulx 8(up,n,8), %r11, %r10
+ adc %r12, %rbx
+ mov %r13, 16(rp,n,8)
+L(lo1): mulx 16(up,n,8), %r13, %r12
+ adc %rax, %r9
+ mov %rbx, 24(rp,n,8)
+L(lo0): mulx 24(up,n,8), %rbx, %rax
+ lea 4(n), n
+ jmp L(top)
+
+L(end): mov %r9, (rp)
+L(wd3): adc %r8, %r11
+ mov %r11, 8(rp)
+L(wd2): adc %r10, %r13
+ mov %r13, 16(rp)
+L(wd1): adc %r12, %rbx
+ adc n, %rax
+ mov %rbx, 24(rp)
+
+ pop %r13
+ pop %r12
+ pop %rbx
+ ret
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/nano/copyd.asm b/gmp/mpn/x86_64/nano/copyd.asm
new file mode 100644
index 0000000000..f0dc54a55e
--- /dev/null
+++ b/gmp/mpn/x86_64/nano/copyd.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_copyd optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_copyd)
+include_mpn(`x86_64/fastsse/copyd-palignr.asm')
diff --git a/gmp/mpn/x86_64/nano/copyi.asm b/gmp/mpn/x86_64/nano/copyi.asm
new file mode 100644
index 0000000000..9c26e00c52
--- /dev/null
+++ b/gmp/mpn/x86_64/nano/copyi.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_copyi optimised for Intel Sandy Bridge.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_copyi)
+include_mpn(`x86_64/fastsse/copyi-palignr.asm')
diff --git a/gmp/mpn/x86_64/nano/dive_1.asm b/gmp/mpn/x86_64/nano/dive_1.asm
new file mode 100644
index 0000000000..e9a07631c4
--- /dev/null
+++ b/gmp/mpn/x86_64/nano/dive_1.asm
@@ -0,0 +1,166 @@
+dnl AMD64 mpn_divexact_1 -- mpn by limb exact division.
+
+dnl Copyright 2001, 2002, 2004-2006, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C norm unorm
+C AMD K8,K9 11 11
+C AMD K10 11 11
+C Intel P4 ?
+C Intel core2 13.5 13.25
+C Intel corei 14.25
+C Intel atom 34 36
+C VIA nano 19.25 19.25
+
+
+C INPUT PARAMETERS
+C rp rdi
+C up rsi
+C n rdx
+C divisor rcx
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_divexact_1)
+ FUNC_ENTRY(4)
+ push %rbx
+
+ mov %rcx, %rax
+ xor R32(%rcx), R32(%rcx) C shift count
+ mov %rdx, %r8
+
+ bt $0, R32(%rax)
+ jc L(odd) C skip bsfq unless divisor is even
+ bsf %rax, %rcx
+ shr R8(%rcx), %rax
+L(odd): mov %rax, %rbx
+ shr R32(%rax)
+ and $127, R32(%rax) C d/2, 7 bits
+
+ LEA( binvert_limb_table, %rdx)
+
+ movzbl (%rdx,%rax), R32(%rax) C inv 8 bits
+
+ mov %rbx, %r11 C d without twos
+
+ lea (%rax,%rax), R32(%rdx) C 2*inv
+ imul R32(%rax), R32(%rax) C inv*inv
+ imul R32(%rbx), R32(%rax) C inv*inv*d
+ sub R32(%rax), R32(%rdx) C inv = 2*inv - inv*inv*d, 16 bits
+
+ lea (%rdx,%rdx), R32(%rax) C 2*inv
+ imul R32(%rdx), R32(%rdx) C inv*inv
+ imul R32(%rbx), R32(%rdx) C inv*inv*d
+ sub R32(%rdx), R32(%rax) C inv = 2*inv - inv*inv*d, 32 bits
+
+ lea (%rax,%rax), %r10 C 2*inv
+ imul %rax, %rax C inv*inv
+ imul %rbx, %rax C inv*inv*d
+ sub %rax, %r10 C inv = 2*inv - inv*inv*d, 64 bits
+
+ lea (%rsi,%r8,8), %rsi C up end
+ lea -8(%rdi,%r8,8), %rdi C rp end
+ neg %r8 C -n
+
+ mov (%rsi,%r8,8), %rax C up[0]
+
+ inc %r8
+ jz L(one)
+
+ test R32(%rcx), R32(%rcx)
+ jnz L(unorm) C branch if count != 0
+ xor R32(%rbx), R32(%rbx)
+ jmp L(nent)
+
+ ALIGN(8)
+L(ntop):mul %r11 C carry limb in rdx 0 10
+ mov -8(%rsi,%r8,8), %rax C
+ sub %rbx, %rax C apply carry bit
+ setc %bl C
+ sub %rdx, %rax C apply carry limb 5
+ adc $0, %rbx C 6
+L(nent):imul %r10, %rax C 6
+ mov %rax, (%rdi,%r8,8) C
+ inc %r8 C
+ jnz L(ntop)
+
+ mov -8(%rsi), %r9 C up high limb
+ jmp L(com)
+
+L(unorm):
+ mov (%rsi,%r8,8), %r9 C up[1]
+ shr R8(%rcx), %rax C
+ neg R32(%rcx)
+ shl R8(%rcx), %r9 C
+ neg R32(%rcx)
+ or %r9, %rax
+ xor R32(%rbx), R32(%rbx)
+ jmp L(uent)
+
+ ALIGN(8)
+L(utop):mul %r11 C carry limb in rdx 0 10
+ mov (%rsi,%r8,8), %rax C
+ shl R8(%rcx), %rax C
+ neg R32(%rcx)
+ or %r9, %rax
+ sub %rbx, %rax C apply carry bit
+ setc %bl C
+ sub %rdx, %rax C apply carry limb 5
+ adc $0, %rbx C 6
+L(uent):imul %r10, %rax C 6
+ mov (%rsi,%r8,8), %r9 C
+ shr R8(%rcx), %r9 C
+ neg R32(%rcx)
+ mov %rax, (%rdi,%r8,8) C
+ inc %r8 C
+ jnz L(utop)
+
+L(com): mul %r11 C carry limb in rdx
+ sub %rbx, %r9 C apply carry bit
+ sub %rdx, %r9 C apply carry limb
+ imul %r10, %r9
+ mov %r9, (%rdi)
+ pop %rbx
+ FUNC_EXIT()
+ ret
+
+L(one): shr R8(%rcx), %rax
+ imul %r10, %rax
+ mov %rax, (%rdi)
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/nano/gcd_1.asm b/gmp/mpn/x86_64/nano/gcd_1.asm
new file mode 100644
index 0000000000..3d8e5c7ab1
--- /dev/null
+++ b/gmp/mpn/x86_64/nano/gcd_1.asm
@@ -0,0 +1,37 @@
+dnl AMD64 mpn_gcd_1.
+
+dnl Copyright 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_gcd_1)
+include_mpn(`x86_64/core2/gcd_1.asm')
diff --git a/gmp/mpn/x86_64/nano/gmp-mparam.h b/gmp/mpn/x86_64/nano/gmp-mparam.h
new file mode 100644
index 0000000000..fde69dbb7f
--- /dev/null
+++ b/gmp/mpn/x86_64/nano/gmp-mparam.h
@@ -0,0 +1,243 @@
+/* VIA Nano gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2010, 2012, 2014 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+#define SHLD_SLOW 1
+#define SHRD_SLOW 1
+
+/* 1600 MHz Nano 2xxx */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.2 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 2
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 18
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 20
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 8
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 22
+
+#define MUL_TOOM22_THRESHOLD 27
+#define MUL_TOOM33_THRESHOLD 38
+#define MUL_TOOM44_THRESHOLD 324
+#define MUL_TOOM6H_THRESHOLD 450
+#define MUL_TOOM8H_THRESHOLD 632
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 207
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 211
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 219
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 315
+
+#define SQR_BASECASE_THRESHOLD 10
+#define SQR_TOOM2_THRESHOLD 52
+#define SQR_TOOM3_THRESHOLD 73
+#define SQR_TOOM4_THRESHOLD 387
+#define SQR_TOOM6_THRESHOLD 662
+#define SQR_TOOM8_THRESHOLD 781
+
+#define MULMID_TOOM42_THRESHOLD 32
+
+#define MULMOD_BNM1_THRESHOLD 14
+#define SQRMOD_BNM1_THRESHOLD 15
+
+#define MUL_FFT_MODF_THRESHOLD 376 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 376, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 23, 7}, { 12, 6}, { 25, 7}, { 21, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 19, 7}, { 39, 8}, \
+ { 21, 9}, { 11, 8}, { 27, 9}, { 15, 8}, \
+ { 35, 9}, { 19, 8}, { 41, 9}, { 23, 8}, \
+ { 49, 9}, { 27,10}, { 15, 9}, { 43,10}, \
+ { 23, 9}, { 55,11}, { 15,10}, { 31, 9}, \
+ { 67,10}, { 39, 9}, { 83,10}, { 47, 9}, \
+ { 95,10}, { 79,11}, { 47,10}, { 103,12}, \
+ { 31,11}, { 63,10}, { 143,11}, { 79,10}, \
+ { 159, 9}, { 319,10}, { 175,11}, { 95, 9}, \
+ { 383, 8}, { 767,10}, { 207,11}, { 111,12}, \
+ { 63,11}, { 127,10}, { 255,11}, { 143, 9}, \
+ { 575, 8}, { 1151,10}, { 303,11}, { 159,10}, \
+ { 319, 9}, { 639, 8}, { 1279,10}, { 335,12}, \
+ { 95,11}, { 191,10}, { 383, 9}, { 767,11}, \
+ { 207,10}, { 415, 9}, { 831, 8}, { 1663,10}, \
+ { 447,13}, { 63,12}, { 127,11}, { 255,10}, \
+ { 511, 9}, { 1023,11}, { 271,10}, { 543, 9}, \
+ { 1087,10}, { 575, 9}, { 1215,12}, { 159,11}, \
+ { 319,10}, { 639, 9}, { 1279,11}, { 335,10}, \
+ { 671, 9}, { 1343,11}, { 351,10}, { 703, 9}, \
+ { 1407,12}, { 191,11}, { 383,10}, { 767, 9}, \
+ { 1535,10}, { 831, 9}, { 1663,12}, { 223,11}, \
+ { 447,10}, { 895,13}, { 127,12}, { 255,11}, \
+ { 511,10}, { 1023,11}, { 543,10}, { 1087,12}, \
+ { 287,11}, { 575,10}, { 1151,11}, { 607,10}, \
+ { 1215,12}, { 319,11}, { 639,10}, { 1279,11}, \
+ { 671,10}, { 1343,12}, { 351,11}, { 703,10}, \
+ { 1407,13}, { 191,12}, { 383,11}, { 767,10}, \
+ { 1535,12}, { 415,11}, { 831,10}, { 1663,12}, \
+ { 447,11}, { 895,10}, { 1791,14}, { 127,13}, \
+ { 255,12}, { 511,11}, { 1023,12}, { 543,11}, \
+ { 1087,12}, { 575,11}, { 1151,12}, { 607,11}, \
+ { 1215,13}, { 319,12}, { 639,11}, { 1279,12}, \
+ { 671,11}, { 1343,12}, { 703,11}, { 1407,13}, \
+ { 383,12}, { 767,11}, { 1535,12}, { 831,11}, \
+ { 1663,13}, { 447,12}, { 895,11}, { 1791,13}, \
+ { 511,12}, { 1023,11}, { 2047,12}, { 1087,13}, \
+ { 575,12}, { 1151,11}, { 2303,12}, { 1215,13}, \
+ { 639,12}, { 1279,11}, { 2559,12}, { 1343,13}, \
+ { 703,12}, { 1407,14}, { 383,13}, { 767,12}, \
+ { 1535,13}, { 831,12}, { 1663,13}, { 895,12}, \
+ { 1791,13}, { 959,14}, { 511,13}, { 1023,12}, \
+ { 2047,13}, { 1087,12}, { 2175,13}, { 1151,12}, \
+ { 2303,13}, { 1215,14}, { 639,13}, { 1279,12}, \
+ { 2559,13}, { 1407,12}, { 2815,13}, { 1471,14}, \
+ { 767,13}, { 1535,12}, { 3071,13}, { 1663,14}, \
+ { 895,13}, { 1791,12}, { 3583,13}, { 1919,15}, \
+ { 511,14}, { 1023,13}, { 2047,12}, { 4095,13}, \
+ { 2175,14}, { 1151,13}, { 2303,12}, { 4607,13}, \
+ { 2431,14}, { 1279,13}, { 2559,12}, { 5119,14}, \
+ { 1407,13}, { 2815,12}, { 5631,15}, { 32768,16}, \
+ { 65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+ {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 224
+#define MUL_FFT_THRESHOLD 3520
+
+#define SQR_FFT_MODF_THRESHOLD 340 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 340, 5}, { 19, 6}, { 10, 5}, { 21, 6}, \
+ { 21, 7}, { 11, 6}, { 23, 7}, { 21, 8}, \
+ { 11, 7}, { 24, 8}, { 13, 7}, { 27, 8}, \
+ { 15, 7}, { 31, 8}, { 21, 9}, { 11, 8}, \
+ { 27, 9}, { 15, 8}, { 33, 9}, { 19, 8}, \
+ { 41, 9}, { 23, 8}, { 47, 9}, { 27,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 51,11}, \
+ { 15,10}, { 31, 9}, { 67,10}, { 39, 9}, \
+ { 79,10}, { 47, 9}, { 95,10}, { 55,11}, \
+ { 31,10}, { 63, 9}, { 127,10}, { 71, 9}, \
+ { 143,10}, { 79,11}, { 47,10}, { 95, 9}, \
+ { 191,10}, { 103,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 135, 7}, { 1087, 9}, \
+ { 287,11}, { 79, 9}, { 319, 8}, { 639,10}, \
+ { 167,11}, { 95,10}, { 191, 9}, { 383, 8}, \
+ { 767,11}, { 111,12}, { 63,11}, { 127,10}, \
+ { 255, 9}, { 511, 8}, { 1023,10}, { 271, 9}, \
+ { 543, 8}, { 1087,11}, { 143, 9}, { 575, 8}, \
+ { 1151,10}, { 303, 9}, { 639, 8}, { 1279,10}, \
+ { 335, 9}, { 671,10}, { 351, 9}, { 703,12}, \
+ { 95,11}, { 191,10}, { 383, 9}, { 767,11}, \
+ { 207,10}, { 415, 9}, { 831,13}, { 63,12}, \
+ { 127,11}, { 255,10}, { 511, 9}, { 1023,11}, \
+ { 271,10}, { 543, 9}, { 1087,10}, { 575, 9}, \
+ { 1151,11}, { 303,10}, { 607, 9}, { 1215,12}, \
+ { 159,11}, { 319,10}, { 639, 9}, { 1279,10}, \
+ { 671, 9}, { 1343,11}, { 351,10}, { 703, 9}, \
+ { 1407,12}, { 191,11}, { 383,10}, { 767, 9}, \
+ { 1535,11}, { 415,10}, { 831, 9}, { 1663,12}, \
+ { 223,11}, { 447,10}, { 959,13}, { 127,12}, \
+ { 255,11}, { 511,10}, { 1023,11}, { 543,10}, \
+ { 1087,11}, { 575,10}, { 1215,12}, { 319,11}, \
+ { 639,10}, { 1279,11}, { 671,10}, { 1343,12}, \
+ { 351,11}, { 703,10}, { 1407,13}, { 191,12}, \
+ { 383,11}, { 767,10}, { 1535,12}, { 415,11}, \
+ { 831,10}, { 1663,12}, { 447,11}, { 895,10}, \
+ { 1791,12}, { 479,11}, { 959,14}, { 127,12}, \
+ { 511,11}, { 1023,12}, { 543,11}, { 1087,12}, \
+ { 575,11}, { 1151,12}, { 607,11}, { 1215,13}, \
+ { 319,12}, { 639,11}, { 1279,12}, { 671,11}, \
+ { 1343,12}, { 703,11}, { 1407,13}, { 383,12}, \
+ { 767,11}, { 1535,12}, { 831,11}, { 1663,13}, \
+ { 447,12}, { 895,11}, { 1791,12}, { 959,13}, \
+ { 511,12}, { 1023,11}, { 2047,12}, { 1087,13}, \
+ { 575,12}, { 1215,13}, { 639,12}, { 1343,13}, \
+ { 703,12}, { 1407,11}, { 2815,13}, { 767,12}, \
+ { 1535,13}, { 831,12}, { 1663,13}, { 895,12}, \
+ { 1791,13}, { 959,14}, { 511,13}, { 1023,12}, \
+ { 2047,13}, { 1087,12}, { 2175,13}, { 1215,14}, \
+ { 639,13}, { 1279,12}, { 2559,13}, { 1407,12}, \
+ { 2815,14}, { 767,13}, { 1535,12}, { 3071,13}, \
+ { 1663,14}, { 895,13}, { 1791,12}, { 3583,13}, \
+ { 1919,15}, { 511,14}, { 1023,13}, { 2047,12}, \
+ { 4095,13}, { 2175,14}, { 1151,13}, { 2303,12}, \
+ { 4607,14}, { 1279,13}, { 2559,14}, { 1407,13}, \
+ { 2815,15}, { 32768,16}, { 65536,17}, { 131072,18}, \
+ { 262144,19}, { 524288,20}, {1048576,21}, {2097152,22}, \
+ {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 230
+#define SQR_FFT_THRESHOLD 2496
+
+#define MULLO_BASECASE_THRESHOLD 13
+#define MULLO_DC_THRESHOLD 38
+#define MULLO_MUL_N_THRESHOLD 6633
+
+#define DC_DIV_QR_THRESHOLD 56
+#define DC_DIVAPPR_Q_THRESHOLD 173
+#define DC_BDIV_QR_THRESHOLD 55
+#define DC_BDIV_Q_THRESHOLD 96
+
+#define INV_MULMOD_BNM1_THRESHOLD 54
+#define INV_NEWTON_THRESHOLD 202
+#define INV_APPR_THRESHOLD 166
+
+#define BINV_NEWTON_THRESHOLD 246
+#define REDC_1_TO_REDC_2_THRESHOLD 7
+#define REDC_2_TO_REDC_N_THRESHOLD 85
+
+#define MU_DIV_QR_THRESHOLD 1499
+#define MU_DIVAPPR_Q_THRESHOLD 1652
+#define MUPI_DIV_QR_THRESHOLD 83
+#define MU_BDIV_QR_THRESHOLD 1210
+#define MU_BDIV_Q_THRESHOLD 1499
+
+#define POWM_SEC_TABLE 1,28,129,642,2387
+
+#define MATRIX22_STRASSEN_THRESHOLD 15
+#define HGCD_THRESHOLD 127
+#define HGCD_APPR_THRESHOLD 214
+#define HGCD_REDUCE_THRESHOLD 2479
+#define GCD_DC_THRESHOLD 487
+#define GCDEXT_DC_THRESHOLD 505
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 24
+#define SET_STR_DC_THRESHOLD 802
+#define SET_STR_PRECOMPUTE_THRESHOLD 2042
+
+#define FAC_DSC_THRESHOLD 1737
+#define FAC_ODD_THRESHOLD 44
diff --git a/gmp/mpn/x86_64/nano/popcount.asm b/gmp/mpn/x86_64/nano/popcount.asm
new file mode 100644
index 0000000000..fb14dd3d31
--- /dev/null
+++ b/gmp/mpn/x86_64/nano/popcount.asm
@@ -0,0 +1,35 @@
+dnl x86-64 mpn_popcount.
+
+dnl Copyright 2007, 2011 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_popcount)
+include_mpn(`x86/pentium4/sse2/popcount.asm')
diff --git a/gmp/mpn/x86_64/pentium4/aors_n.asm b/gmp/mpn/x86_64/pentium4/aors_n.asm
new file mode 100644
index 0000000000..8e6ee1bae6
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/aors_n.asm
@@ -0,0 +1,196 @@
+dnl x86-64 mpn_add_n/mpn_sub_n optimized for Pentium 4.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2007, 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 2.8
+C AMD K10 2.8
+C Intel P4 4
+C Intel core2 3.6-5 (fluctuating)
+C Intel corei ?
+C Intel atom ?
+C VIA nano ?
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cy', `%r8')
+
+ifdef(`OPERATION_add_n', `
+ define(ADDSUB, add)
+ define(func, mpn_add_n)
+ define(func_nc, mpn_add_nc)')
+ifdef(`OPERATION_sub_n', `
+ define(ADDSUB, sub)
+ define(func, mpn_sub_n)
+ define(func_nc, mpn_sub_nc)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
+ASM_START()
+ TEXT
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ xor %r8, %r8
+IFDOS(` jmp L(ent) ')
+EPILOGUE()
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+L(ent): push %rbx
+ push %r12
+
+ mov (vp), %r9
+
+ mov R32(n), R32(%rax)
+ and $3, R32(%rax)
+ jne L(n00) C n = 0, 4, 8, ...
+ mov R32(%r8), R32(%rbx)
+ mov (up), %r8
+ mov 8(up), %r10
+ ADDSUB %r9, %r8
+ mov 8(vp), %r9
+ setc R8(%rax)
+ lea -16(rp), rp
+ jmp L(L00)
+
+L(n00): cmp $2, R32(%rax)
+ jnc L(n01) C n = 1, 5, 9, ...
+ mov (up), %r11
+ mov R32(%r8), R32(%rax)
+ xor R32(%rbx), R32(%rbx)
+ dec n
+ jnz L(gt1)
+ ADDSUB %r9, %r11
+ setc R8(%rbx)
+ ADDSUB %rax, %r11
+ adc $0, R32(%rbx)
+ mov %r11, (rp)
+ jmp L(ret)
+L(gt1): mov 8(up), %r8
+ ADDSUB %r9, %r11
+ mov 8(vp), %r9
+ setc R8(%rbx)
+ lea -8(rp), rp
+ lea 8(up), up
+ lea 8(vp), vp
+ jmp L(L01)
+
+L(n01): jne L(n10) C n = 2, 6, 10, ...
+ mov (up), %r12
+ mov R32(%r8), R32(%rbx)
+ mov 8(up), %r11
+ ADDSUB %r9, %r12
+ mov 8(vp), %r9
+ setc R8(%rax)
+ lea -32(rp), rp
+ lea 16(up), up
+ lea 16(vp), vp
+ jmp L(L10)
+
+L(n10): mov (up), %r10 C n = 3, 7, 11, ...
+ mov R32(%r8), R32(%rax)
+ xor R32(%rbx), R32(%rbx)
+ mov 8(up), %r12
+ ADDSUB %r9, %r10
+ mov 8(vp), %r9
+ setc R8(%rbx)
+ lea -24(rp), rp
+ lea -8(up), up
+ lea -8(vp), vp
+ jmp L(L11)
+
+L(c0): mov $1, R8(%rbx)
+ jmp L(rc0)
+L(c1): mov $1, R8(%rax)
+ jmp L(rc1)
+L(c2): mov $1, R8(%rbx)
+ jmp L(rc2)
+L(c3): mov $1, R8(%rax)
+ jmp L(rc3)
+
+ ALIGN(16)
+L(top): mov (up), %r8 C not on critical path
+ ADDSUB %r9, %r11 C not on critical path
+ mov (vp), %r9 C not on critical path
+ setc R8(%rbx) C save carry out
+ mov %r12, (rp)
+L(L01): ADDSUB %rax, %r11 C apply previous carry out
+ jc L(c0) C jump if ripple
+L(rc0): mov 8(up), %r10
+ ADDSUB %r9, %r8
+ mov 8(vp), %r9
+ setc R8(%rax)
+ mov %r11, 8(rp)
+L(L00): ADDSUB %rbx, %r8
+ jc L(c1)
+L(rc1): mov 16(up), %r12
+ ADDSUB %r9, %r10
+ mov 16(vp), %r9
+ setc R8(%rbx)
+ mov %r8, 16(rp)
+L(L11): ADDSUB %rax, %r10
+ jc L(c2)
+L(rc2): mov 24(up), %r11
+ ADDSUB %r9, %r12
+ lea 32(up), up
+ mov 24(vp), %r9
+ lea 32(vp), vp
+ setc R8(%rax)
+ mov %r10, 24(rp)
+L(L10): ADDSUB %rbx, %r12
+ jc L(c3)
+L(rc3): lea 32(rp), rp
+ sub $4, n
+ ja L(top)
+
+L(end): ADDSUB %r9, %r11
+ setc R8(%rbx)
+ mov %r12, (rp)
+ ADDSUB %rax, %r11
+ jnc L(1)
+ mov $1, R8(%rbx)
+L(1): mov %r11, 8(rp)
+
+L(ret): mov R32(%rbx), R32(%rax)
+ pop %r12
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/pentium4/aorslsh1_n.asm b/gmp/mpn/x86_64/pentium4/aorslsh1_n.asm
new file mode 100644
index 0000000000..66937d3267
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/aorslsh1_n.asm
@@ -0,0 +1,50 @@
+dnl AMD64 mpn_addlsh1_n, mpn_sublsh1_n -- rp[] = up[] +- (vp[] << 1),
+dnl optimised for Pentium 4.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 1)
+define(RSH, 31) C 31, not 63, since we use 32-bit ops
+
+ifdef(`OPERATION_addlsh1_n', `
+ define(ADDSUB, add)
+ define(func, mpn_addlsh1_n)')
+ifdef(`OPERATION_sublsh1_n', `
+ define(ADDSUB, sub)
+ define(func, mpn_sublsh1_n)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_sublsh1_n)
+include_mpn(`x86_64/pentium4/aorslshC_n.asm')
diff --git a/gmp/mpn/x86_64/pentium4/aorslsh2_n.asm b/gmp/mpn/x86_64/pentium4/aorslsh2_n.asm
new file mode 100644
index 0000000000..001f0ac5bf
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/aorslsh2_n.asm
@@ -0,0 +1,50 @@
+dnl AMD64 mpn_addlsh2_n, mpn_sublsh2_n -- rp[] = up[] +- (vp[] << 2),
+dnl optimised for Pentium 4.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+define(LSH, 2)
+define(RSH, 30) C 30, not 62, since we use 32-bit ops
+
+ifdef(`OPERATION_addlsh2_n', `
+ define(ADDSUB, add)
+ define(func, mpn_addlsh2_n)')
+ifdef(`OPERATION_sublsh2_n', `
+ define(ADDSUB, sub)
+ define(func, mpn_sublsh2_n)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_sublsh2_n)
+include_mpn(`x86_64/pentium4/aorslshC_n.asm')
diff --git a/gmp/mpn/x86_64/pentium4/aorslshC_n.asm b/gmp/mpn/x86_64/pentium4/aorslshC_n.asm
new file mode 100644
index 0000000000..d03c6a3f30
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/aorslshC_n.asm
@@ -0,0 +1,203 @@
+dnl AMD64 mpn_addlshC_n, mpn_sublshC_n -- rp[] = up[] +- (vp[] << C), where
+dnl C is 1, 2, 3. Optimized for Pentium 4.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+C cycles/limb
+C AMD K8,K9 3.8
+C AMD K10 3.8
+C Intel P4 5.8
+C Intel core2 4.75
+C Intel corei 4.75
+C Intel atom ?
+C VIA nano 4.75
+
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`vp',`%rdx')
+define(`n', `%rcx')
+
+define(M, eval(m4_lshift(1,LSH)))
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %r12
+ push %rbp
+
+ mov (vp), %r9
+ shl $LSH, %r9
+ mov 4(vp), R32(%rbp)
+
+ xor R32(%rbx), R32(%rbx)
+
+ mov R32(n), R32(%rax)
+ and $3, R32(%rax)
+ jne L(n00) C n = 0, 4, 8, ...
+
+ mov (up), %r8
+ mov 8(up), %r10
+ shr $RSH, R32(%rbp)
+ ADDSUB %r9, %r8
+ mov 8(vp), %r9
+ lea (%rbp,%r9,M), %r9
+ setc R8(%rax)
+ mov 12(vp), R32(%rbp)
+ lea -16(rp), rp
+ jmp L(L00)
+
+L(n00): cmp $2, R32(%rax)
+ jnc L(n01) C n = 1, 5, 9, ...
+ mov (up), %r11
+ lea -8(rp), rp
+ shr $RSH, R32(%rbp)
+ ADDSUB %r9, %r11
+ setc R8(%rbx)
+ dec n
+ jz L(1) C jump for n = 1
+ mov 8(up), %r8
+ mov 8(vp), %r9
+ lea (%rbp,%r9,M), %r9
+ mov 12(vp), R32(%rbp)
+ lea 8(up), up
+ lea 8(vp), vp
+ jmp L(L01)
+
+L(n01): jne L(n10) C n = 2, 6, 10, ...
+ mov (up), %r12
+ mov 8(up), %r11
+ shr $RSH, R32(%rbp)
+ ADDSUB %r9, %r12
+ mov 8(vp), %r9
+ lea (%rbp,%r9,M), %r9
+ setc R8(%rax)
+ mov 12(vp), R32(%rbp)
+ lea 16(up), up
+ lea 16(vp), vp
+ jmp L(L10)
+
+L(n10): mov (up), %r10
+ mov 8(up), %r12
+ shr $RSH, R32(%rbp)
+ ADDSUB %r9, %r10
+ mov 8(vp), %r9
+ lea (%rbp,%r9,M), %r9
+ setc R8(%rbx)
+ mov 12(vp), R32(%rbp)
+ lea -24(rp), rp
+ lea -8(up), up
+ lea -8(vp), vp
+ jmp L(L11)
+
+L(c0): mov $1, R8(%rbx)
+ jmp L(rc0)
+L(c1): mov $1, R8(%rax)
+ jmp L(rc1)
+L(c2): mov $1, R8(%rbx)
+ jmp L(rc2)
+
+ ALIGN(16)
+L(top): mov (up), %r8 C not on critical path
+ shr $RSH, R32(%rbp)
+ ADDSUB %r9, %r11 C not on critical path
+ mov (vp), %r9
+ lea (%rbp,%r9,M), %r9
+ setc R8(%rbx) C save carry out
+ mov 4(vp), R32(%rbp)
+ mov %r12, (rp)
+ ADDSUB %rax, %r11 C apply previous carry out
+ jc L(c0) C jump if ripple
+L(rc0):
+L(L01): mov 8(up), %r10
+ shr $RSH, R32(%rbp)
+ ADDSUB %r9, %r8
+ mov 8(vp), %r9
+ lea (%rbp,%r9,M), %r9
+ setc R8(%rax)
+ mov 12(vp), R32(%rbp)
+ mov %r11, 8(rp)
+ ADDSUB %rbx, %r8
+ jc L(c1)
+L(rc1):
+L(L00): mov 16(up), %r12
+ shr $RSH, R32(%rbp)
+ ADDSUB %r9, %r10
+ mov 16(vp), %r9
+ lea (%rbp,%r9,M), %r9
+ setc R8(%rbx)
+ mov 20(vp), R32(%rbp)
+ mov %r8, 16(rp)
+ ADDSUB %rax, %r10
+ jc L(c2)
+L(rc2):
+L(L11): mov 24(up), %r11
+ shr $RSH, R32(%rbp)
+ ADDSUB %r9, %r12
+ mov 24(vp), %r9
+ lea (%rbp,%r9,M), %r9
+ lea 32(up), up
+ lea 32(vp), vp
+ setc R8(%rax)
+ mov -4(vp), R32(%rbp)
+ mov %r10, 24(rp)
+ ADDSUB %rbx, %r12
+ jc L(c3)
+L(rc3): lea 32(rp), rp
+L(L10): sub $4, n
+ ja L(top)
+
+L(end):
+ shr $RSH, R32(%rbp)
+ ADDSUB %r9, %r11
+ setc R8(%rbx)
+ mov %r12, (rp)
+ ADDSUB %rax, %r11
+ jnc L(1)
+ mov $1, R8(%rbx)
+L(1): mov %r11, 8(rp)
+ lea (%rbx,%rbp), R32(%rax)
+ pop %rbp
+ pop %r12
+ pop %rbx
+ FUNC_EXIT()
+ ret
+L(c3): mov $1, R8(%rax)
+ jmp L(rc3)
+EPILOGUE()
+ASM_END()
diff --git a/gmp/mpn/x86_64/pentium4/gmp-mparam.h b/gmp/mpn/x86_64/pentium4/gmp-mparam.h
new file mode 100644
index 0000000000..2171e230a5
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/gmp-mparam.h
@@ -0,0 +1,231 @@
+/* Pentium 4-64 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000-2010, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define GMP_LIMB_BITS 64
+#define GMP_LIMB_BYTES 8
+
+/* These routines exists for all x86_64 chips, but they are slower on Pentium4
+ than separate add/sub and shift. Make sure they are not really used. */
+#undef HAVE_NATIVE_mpn_rsblsh1_n
+#undef HAVE_NATIVE_mpn_rsblsh2_n
+#undef HAVE_NATIVE_mpn_addlsh_n
+#undef HAVE_NATIVE_mpn_rsblsh_n
+
+/* 3400 MHz Pentium4 Nocona / 1024 Kibyte cache */
+/* FFT tuning limit = 25000000 */
+/* Generated by tuneup.c, 2014-03-12, gcc 4.5 */
+
+#define MOD_1_NORM_THRESHOLD 0 /* always */
+#define MOD_1_UNNORM_THRESHOLD 0 /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
+#define MOD_1U_TO_MOD_1_1_THRESHOLD 3
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD 16
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD 32
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 11
+#define USE_PREINV_DIVREM_1 1 /* native */
+#define DIV_QR_1_NORM_THRESHOLD 1
+#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
+#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD 20
+
+#define MUL_TOOM22_THRESHOLD 12
+#define MUL_TOOM33_THRESHOLD 41
+#define MUL_TOOM44_THRESHOLD 112
+#define MUL_TOOM6H_THRESHOLD 157
+#define MUL_TOOM8H_THRESHOLD 236
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD 91
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD 81
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD 78
+#define MUL_TOOM43_TO_TOOM54_THRESHOLD 106
+
+#define SQR_BASECASE_THRESHOLD 5
+#define SQR_TOOM2_THRESHOLD 30
+#define SQR_TOOM3_THRESHOLD 53
+#define SQR_TOOM4_THRESHOLD 154
+#define SQR_TOOM6_THRESHOLD 197
+#define SQR_TOOM8_THRESHOLD 296
+
+#define MULMID_TOOM42_THRESHOLD 22
+
+#define MULMOD_BNM1_THRESHOLD 9
+#define SQRMOD_BNM1_THRESHOLD 9
+
+#define MUL_FFT_MODF_THRESHOLD 252 /* k = 5 */
+#define MUL_FFT_TABLE3 \
+ { { 252, 5}, { 11, 6}, { 6, 5}, { 13, 6}, \
+ { 13, 7}, { 7, 6}, { 15, 7}, { 8, 6}, \
+ { 17, 7}, { 9, 6}, { 19, 7}, { 13, 8}, \
+ { 7, 7}, { 17, 8}, { 9, 7}, { 20, 8}, \
+ { 11, 7}, { 23, 8}, { 13, 9}, { 7, 8}, \
+ { 21, 9}, { 11, 8}, { 25,10}, { 7, 9}, \
+ { 15, 8}, { 33, 9}, { 19, 8}, { 39, 9}, \
+ { 23, 8}, { 47,10}, { 15, 9}, { 39,10}, \
+ { 23, 9}, { 51,11}, { 15,10}, { 31, 9}, \
+ { 67,10}, { 39, 9}, { 79,10}, { 47, 9}, \
+ { 95,10}, { 55,11}, { 31,10}, { 63, 9}, \
+ { 127, 8}, { 255,10}, { 71, 9}, { 143, 8}, \
+ { 287,10}, { 79,11}, { 47,10}, { 95, 9}, \
+ { 191,10}, { 103,12}, { 31,11}, { 63,10}, \
+ { 127, 9}, { 255,10}, { 143, 9}, { 287,11}, \
+ { 79,10}, { 159, 9}, { 319,10}, { 175, 9}, \
+ { 351,11}, { 95,10}, { 191, 9}, { 383,10}, \
+ { 223,12}, { 63,11}, { 127,10}, { 255,11}, \
+ { 143,10}, { 287, 9}, { 575, 8}, { 1151,11}, \
+ { 159,10}, { 319,11}, { 175,10}, { 351,12}, \
+ { 95,11}, { 191,10}, { 383,11}, { 207,10}, \
+ { 415,11}, { 223,13}, { 63,12}, { 127,11}, \
+ { 255,10}, { 511,11}, { 287,10}, { 575, 9}, \
+ { 1151,12}, { 159,11}, { 319,10}, { 639,11}, \
+ { 351,10}, { 703,12}, { 191,11}, { 383,10}, \
+ { 767,11}, { 415,12}, { 223,11}, { 447,13}, \
+ { 127,12}, { 255,11}, { 511,12}, { 287,11}, \
+ { 575,10}, { 1151,12}, { 319,11}, { 639,12}, \
+ { 351,11}, { 703,13}, { 191,12}, { 383,11}, \
+ { 767,12}, { 415,11}, { 831,12}, { 447,11}, \
+ { 895,14}, { 127,13}, { 255,12}, { 511,11}, \
+ { 1023,12}, { 543,11}, { 1087,10}, { 2175,12}, \
+ { 575,11}, { 1151,13}, { 319,12}, { 639,11}, \
+ { 1279,12}, { 703,11}, { 1407,10}, { 2815,13}, \
+ { 383,12}, { 767,11}, { 1535,12}, { 831,11}, \
+ { 1663,13}, { 447,12}, { 895,14}, { 255,13}, \
+ { 511,12}, { 1023,11}, { 2047,12}, { 1087,11}, \
+ { 2175,13}, { 575,12}, { 1151,11}, { 2303,12}, \
+ { 1215,11}, { 2431,10}, { 4863,13}, { 639,12}, \
+ { 1279,11}, { 2559,13}, { 703,12}, { 1407,11}, \
+ { 2815,14}, { 383,13}, { 767,12}, { 1535,13}, \
+ { 831,12}, { 1663,13}, { 895,15}, { 255,14}, \
+ { 511,13}, { 1023,12}, { 2047,13}, { 1087,12}, \
+ { 2175,13}, { 1151,12}, { 2303,13}, { 1215,12}, \
+ { 2431,11}, { 4863,14}, { 639,13}, { 1279,12}, \
+ { 2559,13}, { 1407,12}, { 2815,14}, { 767,13}, \
+ { 1663,14}, { 895,13}, { 1791,12}, { 3583,13}, \
+ { 1919,12}, { 3839,15}, { 511,14}, { 1023,13}, \
+ { 2175,14}, { 1151,13}, { 2303,12}, { 4607,13}, \
+ { 2431,12}, { 4863,14}, { 1279,13}, { 2559,14}, \
+ { 1407,13}, { 2815,15}, { 32768,16}, { 65536,17}, \
+ { 131072,18}, { 262144,19}, { 524288,20}, {1048576,21}, \
+ {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 211
+#define MUL_FFT_THRESHOLD 2240
+
+#define SQR_FFT_MODF_THRESHOLD 212 /* k = 5 */
+#define SQR_FFT_TABLE3 \
+ { { 212, 5}, { 11, 6}, { 6, 5}, { 13, 6}, \
+ { 13, 7}, { 7, 6}, { 15, 7}, { 9, 6}, \
+ { 19, 7}, { 13, 8}, { 7, 7}, { 17, 8}, \
+ { 9, 7}, { 20, 8}, { 11, 7}, { 24, 8}, \
+ { 13, 9}, { 7, 8}, { 21, 9}, { 11, 8}, \
+ { 25,10}, { 7, 9}, { 15, 8}, { 33, 9}, \
+ { 19, 8}, { 39, 9}, { 23, 8}, { 47,10}, \
+ { 15, 9}, { 39,10}, { 23, 9}, { 47,11}, \
+ { 15,10}, { 31, 9}, { 63, 8}, { 127, 9}, \
+ { 67,10}, { 39, 9}, { 79,10}, { 55,11}, \
+ { 31,10}, { 63, 9}, { 127, 8}, { 255,10}, \
+ { 71, 9}, { 143, 8}, { 287,10}, { 79, 9}, \
+ { 159,11}, { 47, 9}, { 191,12}, { 31,11}, \
+ { 63,10}, { 127, 9}, { 255,10}, { 143, 9}, \
+ { 287,11}, { 79,10}, { 159, 9}, { 319,10}, \
+ { 175, 9}, { 351,10}, { 191, 9}, { 383,10}, \
+ { 207,11}, { 111,10}, { 223,12}, { 63,11}, \
+ { 127,10}, { 255,11}, { 143,10}, { 287, 9}, \
+ { 575,11}, { 159,10}, { 319,11}, { 175,10}, \
+ { 351,11}, { 191,10}, { 383,11}, { 223,13}, \
+ { 63,12}, { 127,11}, { 255,10}, { 511,11}, \
+ { 287,10}, { 575,12}, { 159,11}, { 351,12}, \
+ { 191,11}, { 383,12}, { 223,11}, { 447,13}, \
+ { 127,12}, { 255,11}, { 511,12}, { 287,11}, \
+ { 575,10}, { 1151,12}, { 319,11}, { 639,12}, \
+ { 351,13}, { 191,12}, { 383,11}, { 767,12}, \
+ { 415,11}, { 831,12}, { 447,14}, { 127,13}, \
+ { 255,12}, { 511,11}, { 1023,10}, { 2047,11}, \
+ { 1087,12}, { 575,11}, { 1151,13}, { 319,12}, \
+ { 639,11}, { 1279,12}, { 703,11}, { 1407,13}, \
+ { 383,12}, { 767,11}, { 1535,12}, { 831,13}, \
+ { 447,14}, { 255,13}, { 511,12}, { 1023,11}, \
+ { 2047,13}, { 575,12}, { 1151,11}, { 2303,12}, \
+ { 1215,13}, { 639,12}, { 1279,11}, { 2559,13}, \
+ { 703,14}, { 383,13}, { 767,12}, { 1535,13}, \
+ { 831,12}, { 1663,13}, { 895,15}, { 255,14}, \
+ { 511,13}, { 1023,12}, { 2047,13}, { 1087,12}, \
+ { 2175,13}, { 1151,12}, { 2303,13}, { 1215,12}, \
+ { 2431,14}, { 639,13}, { 1279,12}, { 2687,13}, \
+ { 1407,12}, { 2815,14}, { 767,13}, { 1663,14}, \
+ { 895,13}, { 1791,12}, { 3583,15}, { 511,14}, \
+ { 1023,13}, { 2175,14}, { 1151,13}, { 2303,12}, \
+ { 4607,13}, { 2431,12}, { 4863,14}, { 1279,13}, \
+ { 2559,14}, { 1407,13}, { 2815,15}, { 32768,16}, \
+ { 65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+ {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 184
+#define SQR_FFT_THRESHOLD 1984
+
+#define MULLO_BASECASE_THRESHOLD 0 /* always */
+#define MULLO_DC_THRESHOLD 33
+#define MULLO_MUL_N_THRESHOLD 4392
+
+#define DC_DIV_QR_THRESHOLD 35
+#define DC_DIVAPPR_Q_THRESHOLD 68
+#define DC_BDIV_QR_THRESHOLD 32
+#define DC_BDIV_Q_THRESHOLD 56
+
+#define INV_MULMOD_BNM1_THRESHOLD 22
+#define INV_NEWTON_THRESHOLD 195
+#define INV_APPR_THRESHOLD 116
+
+#define BINV_NEWTON_THRESHOLD 199
+#define REDC_1_TO_REDC_2_THRESHOLD 4
+#define REDC_2_TO_REDC_N_THRESHOLD 42
+
+#define MU_DIV_QR_THRESHOLD 979
+#define MU_DIVAPPR_Q_THRESHOLD 979
+#define MUPI_DIV_QR_THRESHOLD 91
+#define MU_BDIV_QR_THRESHOLD 855
+#define MU_BDIV_Q_THRESHOLD 942
+
+#define POWM_SEC_TABLE 1,16,175,692,1603
+
+#define MATRIX22_STRASSEN_THRESHOLD 17
+#define HGCD_THRESHOLD 109
+#define HGCD_APPR_THRESHOLD 119
+#define HGCD_REDUCE_THRESHOLD 1679
+#define GCD_DC_THRESHOLD 222
+#define GCDEXT_DC_THRESHOLD 238
+#define JACOBI_BASE_METHOD 4
+
+#define GET_STR_DC_THRESHOLD 12
+#define GET_STR_PRECOMPUTE_THRESHOLD 24
+#define SET_STR_DC_THRESHOLD 537
+#define SET_STR_PRECOMPUTE_THRESHOLD 1430
+
+#define FAC_DSC_THRESHOLD 1127
+#define FAC_ODD_THRESHOLD 0 /* always */
diff --git a/gmp/mpn/x86_64/pentium4/lshift.asm b/gmp/mpn/x86_64/pentium4/lshift.asm
new file mode 100644
index 0000000000..d3b521364f
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/lshift.asm
@@ -0,0 +1,166 @@
+dnl x86-64 mpn_lshift optimized for Pentium 4.
+
+dnl Copyright 2003, 2005, 2007, 2008, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 2.5
+C AMD K10 ?
+C Intel P4 3.29
+C Intel core2 2.1 (fluctuates, presumably cache related)
+C Intel corei ?
+C Intel atom 14.3
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`n',`%rdx')
+define(`cnt',`%cl')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_lshift)
+ FUNC_ENTRY(4)
+ mov -8(up,n,8), %rax
+ movd R32(%rcx), %mm4
+ neg R32(%rcx) C put rsh count in cl
+ and $63, R32(%rcx)
+ movd R32(%rcx), %mm5
+
+ lea 1(n), R32(%r8)
+
+ shr R8(%rcx), %rax C function return value
+
+ and $3, R32(%r8)
+ je L(rol) C jump for n = 3, 7, 11, ...
+
+ dec R32(%r8)
+ jne L(1)
+C n = 4, 8, 12, ...
+ movq -8(up,n,8), %mm2
+ psllq %mm4, %mm2
+ movq -16(up,n,8), %mm0
+ psrlq %mm5, %mm0
+ por %mm0, %mm2
+ movq %mm2, -8(rp,n,8)
+ dec n
+ jmp L(rol)
+
+L(1): dec R32(%r8)
+ je L(1x) C jump for n = 1, 5, 9, 13, ...
+C n = 2, 6, 10, 16, ...
+ movq -8(up,n,8), %mm2
+ psllq %mm4, %mm2
+ movq -16(up,n,8), %mm0
+ psrlq %mm5, %mm0
+ por %mm0, %mm2
+ movq %mm2, -8(rp,n,8)
+ dec n
+L(1x):
+ cmp $1, n
+ je L(ast)
+ movq -8(up,n,8), %mm2
+ psllq %mm4, %mm2
+ movq -16(up,n,8), %mm3
+ psllq %mm4, %mm3
+ movq -16(up,n,8), %mm0
+ movq -24(up,n,8), %mm1
+ psrlq %mm5, %mm0
+ por %mm0, %mm2
+ psrlq %mm5, %mm1
+ por %mm1, %mm3
+ movq %mm2, -8(rp,n,8)
+ movq %mm3, -16(rp,n,8)
+ sub $2, n
+
+L(rol): movq -8(up,n,8), %mm2
+ psllq %mm4, %mm2
+ movq -16(up,n,8), %mm3
+ psllq %mm4, %mm3
+
+ sub $4, n C 4
+ jb L(end) C 2
+ ALIGN(32)
+L(top):
+ C finish stuff from lsh block
+ movq 16(up,n,8), %mm0
+ movq 8(up,n,8), %mm1
+ psrlq %mm5, %mm0
+ por %mm0, %mm2
+ psrlq %mm5, %mm1
+ movq (up,n,8), %mm0
+ por %mm1, %mm3
+ movq -8(up,n,8), %mm1
+ movq %mm2, 24(rp,n,8)
+ movq %mm3, 16(rp,n,8)
+ C start two new rsh
+ psrlq %mm5, %mm0
+ psrlq %mm5, %mm1
+
+ C finish stuff from rsh block
+ movq 8(up,n,8), %mm2
+ movq (up,n,8), %mm3
+ psllq %mm4, %mm2
+ por %mm2, %mm0
+ psllq %mm4, %mm3
+ movq -8(up,n,8), %mm2
+ por %mm3, %mm1
+ movq -16(up,n,8), %mm3
+ movq %mm0, 8(rp,n,8)
+ movq %mm1, (rp,n,8)
+ C start two new lsh
+ sub $4, n
+ psllq %mm4, %mm2
+ psllq %mm4, %mm3
+
+ jae L(top) C 2
+L(end):
+ movq 8(up), %mm0
+ psrlq %mm5, %mm0
+ por %mm0, %mm2
+ movq (up), %mm1
+ psrlq %mm5, %mm1
+ por %mm1, %mm3
+ movq %mm2, 16(rp)
+ movq %mm3, 8(rp)
+
+L(ast): movq (up), %mm2
+ psllq %mm4, %mm2
+ movq %mm2, (rp)
+ emms
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/pentium4/lshiftc.asm b/gmp/mpn/x86_64/pentium4/lshiftc.asm
new file mode 100644
index 0000000000..fc64676574
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/lshiftc.asm
@@ -0,0 +1,179 @@
+dnl x86-64 mpn_lshiftc optimized for Pentium 4.
+
+dnl Copyright 2003, 2005, 2007, 2008, 2010, 2012 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 ?
+C AMD K10 ?
+C Intel P4 4.15
+C Intel core2 ?
+C Intel corei ?
+C Intel atom ?
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`n',`%rdx')
+define(`cnt',`%cl')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_lshiftc)
+ FUNC_ENTRY(4)
+ mov -8(up,n,8), %rax
+ pcmpeqd %mm6, %mm6 C 0xffff...fff
+ movd R32(%rcx), %mm4
+ neg R32(%rcx) C put rsh count in cl
+ and $63, R32(%rcx)
+ movd R32(%rcx), %mm5
+
+ lea 1(n), R32(%r8)
+
+ shr R8(%rcx), %rax C function return value
+
+ and $3, R32(%r8)
+ je L(rol) C jump for n = 3, 7, 11, ...
+
+ dec R32(%r8)
+ jne L(1)
+C n = 4, 8, 12, ...
+ movq -8(up,n,8), %mm2
+ psllq %mm4, %mm2
+ movq -16(up,n,8), %mm0
+ pxor %mm6, %mm2
+ psrlq %mm5, %mm0
+ pandn %mm2, %mm0
+ movq %mm0, -8(rp,n,8)
+ dec n
+ jmp L(rol)
+
+L(1): dec R32(%r8)
+ je L(1x) C jump for n = 1, 5, 9, 13, ...
+C n = 2, 6, 10, 16, ...
+ movq -8(up,n,8), %mm2
+ psllq %mm4, %mm2
+ movq -16(up,n,8), %mm0
+ pxor %mm6, %mm2
+ psrlq %mm5, %mm0
+ pandn %mm2, %mm0
+ movq %mm0, -8(rp,n,8)
+ dec n
+L(1x):
+ cmp $1, n
+ je L(ast)
+ movq -8(up,n,8), %mm2
+ psllq %mm4, %mm2
+ movq -16(up,n,8), %mm3
+ psllq %mm4, %mm3
+ movq -16(up,n,8), %mm0
+ movq -24(up,n,8), %mm1
+ pxor %mm6, %mm2
+ psrlq %mm5, %mm0
+ pandn %mm2, %mm0
+ pxor %mm6, %mm3
+ psrlq %mm5, %mm1
+ pandn %mm3, %mm1
+ movq %mm0, -8(rp,n,8)
+ movq %mm1, -16(rp,n,8)
+ sub $2, n
+
+L(rol): movq -8(up,n,8), %mm2
+ psllq %mm4, %mm2
+ movq -16(up,n,8), %mm3
+ psllq %mm4, %mm3
+
+ sub $4, n
+ jb L(end)
+ ALIGN(32)
+L(top):
+ C finish stuff from lsh block
+ movq 16(up,n,8), %mm0
+ pxor %mm6, %mm2
+ movq 8(up,n,8), %mm1
+ psrlq %mm5, %mm0
+ psrlq %mm5, %mm1
+ pandn %mm2, %mm0
+ pxor %mm6, %mm3
+ movq %mm0, 24(rp,n,8)
+ movq (up,n,8), %mm0
+ pandn %mm3, %mm1
+ movq %mm1, 16(rp,n,8)
+ movq -8(up,n,8), %mm1
+ C start two new rsh
+ psrlq %mm5, %mm0
+ psrlq %mm5, %mm1
+
+ C finish stuff from rsh block
+ movq 8(up,n,8), %mm2
+ pxor %mm6, %mm0
+ movq (up,n,8), %mm3
+ psllq %mm4, %mm2
+ psllq %mm4, %mm3
+ pandn %mm0, %mm2
+ pxor %mm6, %mm1
+ movq %mm2, 8(rp,n,8)
+ movq -8(up,n,8), %mm2
+ pandn %mm1, %mm3
+ movq %mm3, (rp,n,8)
+ movq -16(up,n,8), %mm3
+ C start two new lsh
+ sub $4, n
+ psllq %mm4, %mm2
+ psllq %mm4, %mm3
+
+ jae L(top)
+
+L(end): pxor %mm6, %mm2
+ movq 8(up), %mm0
+ psrlq %mm5, %mm0
+ pandn %mm2, %mm0
+ pxor %mm6, %mm3
+ movq (up), %mm1
+ psrlq %mm5, %mm1
+ pandn %mm3, %mm1
+ movq %mm0, 16(rp)
+ movq %mm1, 8(rp)
+
+L(ast): movq (up), %mm2
+ psllq %mm4, %mm2
+ pxor %mm6, %mm2
+ movq %mm2, (rp)
+ emms
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/pentium4/mod_34lsub1.asm b/gmp/mpn/x86_64/pentium4/mod_34lsub1.asm
new file mode 100644
index 0000000000..f34b3f079a
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/mod_34lsub1.asm
@@ -0,0 +1,167 @@
+dnl AMD64 mpn_mod_34lsub1 -- remainder modulo 2^48-1.
+
+dnl Copyright 2000-2002, 2004, 2005, 2007, 2010-2012 Free Software Foundation,
+dnl Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 1.0
+C AMD K10 1.12
+C Intel P4 3.25
+C Intel core2 1.5
+C Intel corei 1.5
+C Intel atom 2.5
+C VIA nano 1.75
+
+
+C INPUT PARAMETERS
+define(`ap', %rdi)
+define(`n', %rsi)
+
+C mp_limb_t mpn_mod_34lsub1 (mp_srcptr up, mp_size_t n)
+
+C TODO
+C * Review feed-in and wind-down code. In particular, try to avoid adc and
+C sbb to placate Pentium4.
+C * It seems possible to reach 2.67 c/l by using a cleaner 6-way unrolling,
+C without the dual loop exits.
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_mod_34lsub1)
+ FUNC_ENTRY(2)
+
+ mov $0x0000FFFFFFFFFFFF, %r11
+
+ sub $2, %rsi
+ ja L(gt2)
+
+ mov (ap), %rax
+ nop
+ jb L(1)
+
+ mov 8(ap), %rsi
+ mov %rax, %rdx
+ shr $48, %rax C src[0] low
+
+ and %r11, %rdx C src[0] high
+ add %rdx, %rax
+ mov R32(%rsi), R32(%rdx)
+
+ shr $32, %rsi C src[1] high
+ add %rsi, %rax
+
+ shl $16, %rdx C src[1] low
+ add %rdx, %rax
+
+L(1): FUNC_EXIT()
+ ret
+
+
+ ALIGN(16)
+L(gt2): xor R32(%rax), R32(%rax)
+ xor R32(%rcx), R32(%rcx)
+ xor R32(%rdx), R32(%rdx)
+ xor %r8, %r8
+ xor %r9, %r9
+ xor %r10, %r10
+
+L(top): add (ap), %rax
+ adc $0, %r10
+ add 8(ap), %rcx
+ adc $0, %r8
+ add 16(ap), %rdx
+ adc $0, %r9
+
+ sub $3, %rsi
+ jng L(end)
+
+ add 24(ap), %rax
+ adc $0, %r10
+ add 32(ap), %rcx
+ adc $0, %r8
+ add 40(ap), %rdx
+ lea 48(ap), ap
+ adc $0, %r9
+
+ sub $3, %rsi
+ jg L(top)
+
+
+ add $-24, ap
+L(end): add %r9, %rax
+ adc %r10, %rcx
+ adc %r8, %rdx
+
+ inc %rsi
+ mov $0x1, R32(%r10)
+ js L(combine)
+
+ mov $0x10000, R32(%r10)
+ adc 24(ap), %rax
+ dec %rsi
+ js L(combine)
+
+ adc 32(ap), %rcx
+ mov $0x100000000, %r10
+
+L(combine):
+ sbb %rsi, %rsi C carry
+ mov %rax, %rdi C 0mod3
+ shr $48, %rax C 0mod3 high
+
+ and %r10, %rsi C carry masked
+ and %r11, %rdi C 0mod3 low
+ mov R32(%rcx), R32(%r10) C 1mod3
+
+ add %rsi, %rax C apply carry
+ shr $32, %rcx C 1mod3 high
+
+ add %rdi, %rax C apply 0mod3 low
+ movzwl %dx, R32(%rdi) C 2mod3
+ shl $16, %r10 C 1mod3 low
+
+ add %rcx, %rax C apply 1mod3 high
+ shr $16, %rdx C 2mod3 high
+
+ add %r10, %rax C apply 1mod3 low
+ shl $32, %rdi C 2mod3 low
+
+ add %rdx, %rax C apply 2mod3 high
+ add %rdi, %rax C apply 2mod3 low
+
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/pentium4/popcount.asm b/gmp/mpn/x86_64/pentium4/popcount.asm
new file mode 100644
index 0000000000..7014b39de5
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/popcount.asm
@@ -0,0 +1,35 @@
+dnl x86-64 mpn_popcount optimized for Pentium 4.
+
+dnl Copyright 2007 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+MULFUNC_PROLOGUE(mpn_popcount)
+include_mpn(`x86/pentium4/sse2/popcount.asm')
diff --git a/gmp/mpn/x86_64/pentium4/rsh1aors_n.asm b/gmp/mpn/x86_64/pentium4/rsh1aors_n.asm
new file mode 100644
index 0000000000..5528ce47da
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/rsh1aors_n.asm
@@ -0,0 +1,334 @@
+dnl x86-64 mpn_rsh1add_n/mpn_rsh1sub_n optimized for Pentium 4.
+
+dnl Contributed to the GNU project by Torbjorn Granlund.
+
+dnl Copyright 2007, 2008, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 4.13
+C AMD K10 4.13
+C Intel P4 5.70
+C Intel core2 4.75
+C Intel corei 5
+C Intel atom 8.75
+C VIA nano 5.25
+
+C TODO
+C * Try to make this smaller, 746 bytes seem excessive for this 2nd class
+C function. Less sw pipelining would help, and since we now probably
+C pipeline somewhat too deeply, it might not affect performance too much.
+C * A separate small-n loop might speed things as well as make things smaller.
+C That loop should be selected before pushing registers.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n', `%rcx')
+define(`cy', `%r8')
+
+ifdef(`OPERATION_rsh1add_n', `
+ define(ADDSUB, add)
+ define(func, mpn_rsh1add_n)
+ define(func_nc, mpn_rsh1add_nc)')
+ifdef(`OPERATION_rsh1sub_n', `
+ define(ADDSUB, sub)
+ define(func, mpn_rsh1sub_n)
+ define(func_nc, mpn_rsh1sub_nc)')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_rsh1add_n mpn_rsh1add_nc mpn_rsh1sub_n mpn_rsh1sub_nc)
+
+ASM_START()
+ TEXT
+PROLOGUE(func)
+ FUNC_ENTRY(4)
+ xor %r8, %r8
+IFDOS(` jmp L(ent) ')
+EPILOGUE()
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+L(ent): push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov (vp), %r9
+ mov (up), %r15
+
+ mov R32(n), R32(%rax)
+ and $3, R32(%rax)
+ jne L(n00)
+
+ mov R32(%r8), R32(%rbx) C n = 0, 4, 8, ...
+ mov 8(up), %r10
+ ADDSUB %r9, %r15
+ mov 8(vp), %r9
+ setc R8(%rax)
+ ADDSUB %rbx, %r15 C return bit
+ jnc 1f
+ mov $1, R8(%rax)
+1: mov 16(up), %r12
+ ADDSUB %r9, %r10
+ mov 16(vp), %r9
+ setc R8(%rbx)
+ mov %r15, %r13
+ ADDSUB %rax, %r10
+ jnc 1f
+ mov $1, R8(%rbx)
+1: mov 24(up), %r11
+ ADDSUB %r9, %r12
+ lea 32(up), up
+ mov 24(vp), %r9
+ lea 32(vp), vp
+ setc R8(%rax)
+ mov %r10, %r14
+ shl $63, %r10
+ shr %r13
+ jmp L(L00)
+
+L(n00): cmp $2, R32(%rax)
+ jnc L(n01)
+ xor R32(%rbx), R32(%rbx) C n = 1, 5, 9, ...
+ lea -24(rp), rp
+ mov R32(%r8), R32(%rax)
+ dec n
+ jnz L(gt1)
+ ADDSUB %r9, %r15
+ setc R8(%rbx)
+ ADDSUB %rax, %r15
+ jnc 1f
+ mov $1, R8(%rbx)
+1: mov %r15, %r14
+ shl $63, %rbx
+ shr %r14
+ jmp L(cj1)
+L(gt1): mov 8(up), %r8
+ ADDSUB %r9, %r15
+ mov 8(vp), %r9
+ setc R8(%rbx)
+ ADDSUB %rax, %r15
+ jnc 1f
+ mov $1, R8(%rbx)
+1: mov 16(up), %r10
+ ADDSUB %r9, %r8
+ mov 16(vp), %r9
+ setc R8(%rax)
+ mov %r15, %r14
+ ADDSUB %rbx, %r8
+ jnc 1f
+ mov $1, R8(%rax)
+1: mov 24(up), %r12
+ ADDSUB %r9, %r10
+ mov 24(vp), %r9
+ setc R8(%rbx)
+ mov %r8, %r13
+ shl $63, %r8
+ shr %r14
+ lea 8(up), up
+ lea 8(vp), vp
+ jmp L(L01)
+
+L(n01): jne L(n10)
+ lea -16(rp), rp C n = 2, 6, 10, ...
+ mov R32(%r8), R32(%rbx)
+ mov 8(up), %r11
+ ADDSUB %r9, %r15
+ mov 8(vp), %r9
+ setc R8(%rax)
+ ADDSUB %rbx, %r15
+ jnc 1f
+ mov $1, R8(%rax)
+1: sub $2, n
+ jnz L(gt2)
+ ADDSUB %r9, %r11
+ setc R8(%rbx)
+ mov %r15, %r13
+ ADDSUB %rax, %r11
+ jnc 1f
+ mov $1, R8(%rbx)
+1: mov %r11, %r14
+ shl $63, %r11
+ shr %r13
+ jmp L(cj2)
+L(gt2): mov 16(up), %r8
+ ADDSUB %r9, %r11
+ mov 16(vp), %r9
+ setc R8(%rbx)
+ mov %r15, %r13
+ ADDSUB %rax, %r11
+ jnc 1f
+ mov $1, R8(%rbx)
+1: mov 24(up), %r10
+ ADDSUB %r9, %r8
+ mov 24(vp), %r9
+ setc R8(%rax)
+ mov %r11, %r14
+ shl $63, %r11
+ shr %r13
+ lea 16(up), up
+ lea 16(vp), vp
+ jmp L(L10)
+
+L(n10): xor R32(%rbx), R32(%rbx) C n = 3, 7, 11, ...
+ lea -8(rp), rp
+ mov R32(%r8), R32(%rax)
+ mov 8(up), %r12
+ ADDSUB %r9, %r15
+ mov 8(vp), %r9
+ setc R8(%rbx)
+ ADDSUB %rax, %r15
+ jnc 1f
+ mov $1, R8(%rbx)
+1: mov 16(up), %r11
+ ADDSUB %r9, %r12
+ mov 16(vp), %r9
+ setc R8(%rax)
+ mov %r15, %r14
+ ADDSUB %rbx, %r12
+ jnc 1f
+ mov $1, R8(%rax)
+1: sub $3, n
+ jnz L(gt3)
+ ADDSUB %r9, %r11
+ setc R8(%rbx)
+ mov %r12, %r13
+ shl $63, %r12
+ shr %r14
+ jmp L(cj3)
+L(gt3): mov 24(up), %r8
+ ADDSUB %r9, %r11
+ mov 24(vp), %r9
+ setc R8(%rbx)
+ mov %r12, %r13
+ shl $63, %r12
+ shr %r14
+ lea 24(up), up
+ lea 24(vp), vp
+ jmp L(L11)
+
+L(c0): mov $1, R8(%rbx)
+ jmp L(rc0)
+L(c1): mov $1, R8(%rax)
+ jmp L(rc1)
+L(c2): mov $1, R8(%rbx)
+ jmp L(rc2)
+
+ ALIGN(16)
+L(top): mov (up), %r8 C not on critical path
+ or %r13, %r10
+ ADDSUB %r9, %r11 C not on critical path
+ mov (vp), %r9 C not on critical path
+ setc R8(%rbx) C save carry out
+ mov %r12, %r13 C new for later
+ shl $63, %r12 C shift new right
+ shr %r14 C shift old left
+ mov %r10, (rp)
+L(L11): ADDSUB %rax, %r11 C apply previous carry out
+ jc L(c0) C jump if ripple
+L(rc0): mov 8(up), %r10
+ or %r14, %r12
+ ADDSUB %r9, %r8
+ mov 8(vp), %r9
+ setc R8(%rax)
+ mov %r11, %r14
+ shl $63, %r11
+ shr %r13
+ mov %r12, 8(rp)
+L(L10): ADDSUB %rbx, %r8
+ jc L(c1)
+L(rc1): mov 16(up), %r12
+ or %r13, %r11
+ ADDSUB %r9, %r10
+ mov 16(vp), %r9
+ setc R8(%rbx)
+ mov %r8, %r13
+ shl $63, %r8
+ shr %r14
+ mov %r11, 16(rp)
+L(L01): ADDSUB %rax, %r10
+ jc L(c2)
+L(rc2): mov 24(up), %r11
+ or %r14, %r8
+ ADDSUB %r9, %r12
+ lea 32(up), up
+ mov 24(vp), %r9
+ lea 32(vp), vp
+ setc R8(%rax)
+ mov %r10, %r14
+ shl $63, %r10
+ shr %r13
+ mov %r8, 24(rp)
+ lea 32(rp), rp
+L(L00): ADDSUB %rbx, %r12
+ jc L(c3)
+L(rc3): sub $4, n
+ ja L(top)
+
+L(end): or %r13, %r10
+ ADDSUB %r9, %r11
+ setc R8(%rbx)
+ mov %r12, %r13
+ shl $63, %r12
+ shr %r14
+ mov %r10, (rp)
+L(cj3): ADDSUB %rax, %r11
+ jnc 1f
+ mov $1, R8(%rbx)
+1: or %r14, %r12
+ mov %r11, %r14
+ shl $63, %r11
+ shr %r13
+ mov %r12, 8(rp)
+L(cj2): or %r13, %r11
+ shl $63, %rbx
+ shr %r14
+ mov %r11, 16(rp)
+L(cj1): or %r14, %rbx
+ mov %rbx, 24(rp)
+
+ mov R32(%r15), R32(%rax)
+ and $1, R32(%rax)
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbx
+ FUNC_EXIT()
+ ret
+L(c3): mov $1, R8(%rax)
+ jmp L(rc3)
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/pentium4/rshift.asm b/gmp/mpn/x86_64/pentium4/rshift.asm
new file mode 100644
index 0000000000..b7c1ee2cdd
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/rshift.asm
@@ -0,0 +1,169 @@
+dnl x86-64 mpn_rshift optimized for Pentium 4.
+
+dnl Copyright 2003, 2005, 2007, 2008, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 2.5
+C AMD K10 ?
+C Intel P4 3.29
+C Intel core2 2.1 (fluctuates, presumably cache related)
+C Intel corei ?
+C Intel atom 14.3
+C VIA nano ?
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`n',`%rdx')
+define(`cnt',`%cl')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_rshift)
+ FUNC_ENTRY(4)
+ mov (up), %rax
+ movd R32(%rcx), %mm4
+ neg R32(%rcx) C put lsh count in cl
+ and $63, R32(%rcx)
+ movd R32(%rcx), %mm5
+
+ lea -8(up,n,8), up
+ lea -8(rp,n,8), rp
+ lea 1(n), R32(%r8)
+ neg n
+
+ shl R8(%rcx), %rax C function return value
+
+ and $3, R32(%r8)
+ je L(rol) C jump for n = 3, 7, 11, ...
+
+ dec R32(%r8)
+ jne L(1)
+C n = 4, 8, 12, ...
+ movq 8(up,n,8), %mm2
+ psrlq %mm4, %mm2
+ movq 16(up,n,8), %mm0
+ psllq %mm5, %mm0
+ por %mm0, %mm2
+ movq %mm2, 8(rp,n,8)
+ inc n
+ jmp L(rol)
+
+L(1): dec R32(%r8)
+ je L(1x) C jump for n = 1, 5, 9, 13, ...
+C n = 2, 6, 10, 16, ...
+ movq 8(up,n,8), %mm2
+ psrlq %mm4, %mm2
+ movq 16(up,n,8), %mm0
+ psllq %mm5, %mm0
+ por %mm0, %mm2
+ movq %mm2, 8(rp,n,8)
+ inc n
+L(1x):
+ cmp $-1, n
+ je L(ast)
+ movq 8(up,n,8), %mm2
+ psrlq %mm4, %mm2
+ movq 16(up,n,8), %mm3
+ psrlq %mm4, %mm3
+ movq 16(up,n,8), %mm0
+ movq 24(up,n,8), %mm1
+ psllq %mm5, %mm0
+ por %mm0, %mm2
+ psllq %mm5, %mm1
+ por %mm1, %mm3
+ movq %mm2, 8(rp,n,8)
+ movq %mm3, 16(rp,n,8)
+ add $2, n
+
+L(rol): movq 8(up,n,8), %mm2
+ psrlq %mm4, %mm2
+ movq 16(up,n,8), %mm3
+ psrlq %mm4, %mm3
+
+ add $4, n C 4
+ jb L(end) C 2
+ ALIGN(32)
+L(top):
+ C finish stuff from lsh block
+ movq -16(up,n,8), %mm0
+ movq -8(up,n,8), %mm1
+ psllq %mm5, %mm0
+ por %mm0, %mm2
+ psllq %mm5, %mm1
+ movq (up,n,8), %mm0
+ por %mm1, %mm3
+ movq 8(up,n,8), %mm1
+ movq %mm2, -24(rp,n,8)
+ movq %mm3, -16(rp,n,8)
+ C start two new rsh
+ psllq %mm5, %mm0
+ psllq %mm5, %mm1
+
+ C finish stuff from rsh block
+ movq -8(up,n,8), %mm2
+ movq (up,n,8), %mm3
+ psrlq %mm4, %mm2
+ por %mm2, %mm0
+ psrlq %mm4, %mm3
+ movq 8(up,n,8), %mm2
+ por %mm3, %mm1
+ movq 16(up,n,8), %mm3
+ movq %mm0, -8(rp,n,8)
+ movq %mm1, (rp,n,8)
+ C start two new lsh
+ add $4, n
+ psrlq %mm4, %mm2
+ psrlq %mm4, %mm3
+
+ jae L(top) C 2
+L(end):
+ movq -8(up), %mm0
+ psllq %mm5, %mm0
+ por %mm0, %mm2
+ movq (up), %mm1
+ psllq %mm5, %mm1
+ por %mm1, %mm3
+ movq %mm2, -16(rp)
+ movq %mm3, -8(rp)
+
+L(ast): movq (up), %mm2
+ psrlq %mm4, %mm2
+ movq %mm2, (rp)
+ emms
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/pentium4/sec_tabselect.asm b/gmp/mpn/x86_64/pentium4/sec_tabselect.asm
new file mode 100644
index 0000000000..e4360341d9
--- /dev/null
+++ b/gmp/mpn/x86_64/pentium4/sec_tabselect.asm
@@ -0,0 +1,37 @@
+dnl X86-64 mpn_sec_tabselect.
+
+dnl Copyright 2012, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+MULFUNC_PROLOGUE(mpn_sec_tabselect)
+include_mpn(`x86_64/fastsse/sec_tabselect.asm')
diff --git a/gmp/mpn/x86_64/popham.asm b/gmp/mpn/x86_64/popham.asm
new file mode 100644
index 0000000000..9005f81776
--- /dev/null
+++ b/gmp/mpn/x86_64/popham.asm
@@ -0,0 +1,177 @@
+dnl AMD64 mpn_popcount, mpn_hamdist -- population count and hamming distance.
+
+dnl Copyright 2004, 2005, 2007, 2010-2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+
+C popcount hamdist
+C cycles/limb cycles/limb
+C AMD K8,K9 6 7
+C AMD K10 6 7
+C Intel P4 12 14.3
+C Intel core2 7 8
+C Intel corei ? 7.3
+C Intel atom 16.5 17.5
+C VIA nano 8.75 10.4
+
+C TODO
+C * Tune. It should be possible to reach 5 c/l for popcount and 6 c/l for
+C hamdist for K8/K9.
+
+
+ifdef(`OPERATION_popcount',`
+ define(`func',`mpn_popcount')
+ define(`up', `%rdi')
+ define(`n', `%rsi')
+ define(`h55555555', `%r10')
+ define(`h33333333', `%r11')
+ define(`h0f0f0f0f', `%rcx')
+ define(`h01010101', `%rdx')
+ define(`POP', `$1')
+ define(`HAM', `dnl')
+')
+ifdef(`OPERATION_hamdist',`
+ define(`func',`mpn_hamdist')
+ define(`up', `%rdi')
+ define(`vp', `%rsi')
+ define(`n', `%rdx')
+ define(`h55555555', `%r10')
+ define(`h33333333', `%r11')
+ define(`h0f0f0f0f', `%rcx')
+ define(`h01010101', `%r14')
+ define(`POP', `dnl')
+ define(`HAM', `$1')
+')
+
+
+MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(func)
+ POP(` FUNC_ENTRY(2) ')
+ HAM(` FUNC_ENTRY(3) ')
+ push %r12
+ push %r13
+ HAM(` push %r14 ')
+
+ mov $0x5555555555555555, h55555555
+ mov $0x3333333333333333, h33333333
+ mov $0x0f0f0f0f0f0f0f0f, h0f0f0f0f
+ mov $0x0101010101010101, h01010101
+
+ lea (up,n,8), up
+ HAM(` lea (vp,n,8), vp ')
+ neg n
+
+ xor R32(%rax), R32(%rax)
+
+ bt $0, R32(n)
+ jnc L(top)
+
+ mov (up,n,8), %r8
+ HAM(` xor (vp,n,8), %r8 ')
+
+ mov %r8, %r9
+ shr %r8
+ and h55555555, %r8
+ sub %r8, %r9
+
+ mov %r9, %r8
+ shr $2, %r9
+ and h33333333, %r8
+ and h33333333, %r9
+ add %r8, %r9 C 16 4-bit fields (0..4)
+
+ mov %r9, %r8
+ shr $4, %r9
+ and h0f0f0f0f, %r8
+ and h0f0f0f0f, %r9
+ add %r8, %r9 C 8 8-bit fields (0..16)
+
+ imul h01010101, %r9 C sum the 8 fields in high 8 bits
+ shr $56, %r9
+
+ mov %r9, %rax C add to total
+ add $1, n
+ jz L(end)
+
+ ALIGN(16)
+L(top): mov (up,n,8), %r8
+ mov 8(up,n,8), %r12
+ HAM(` xor (vp,n,8), %r8 ')
+ HAM(` xor 8(vp,n,8), %r12 ')
+
+ mov %r8, %r9
+ mov %r12, %r13
+ shr %r8
+ shr %r12
+ and h55555555, %r8
+ and h55555555, %r12
+ sub %r8, %r9
+ sub %r12, %r13
+
+ mov %r9, %r8
+ mov %r13, %r12
+ shr $2, %r9
+ shr $2, %r13
+ and h33333333, %r8
+ and h33333333, %r9
+ and h33333333, %r12
+ and h33333333, %r13
+ add %r8, %r9 C 16 4-bit fields (0..4)
+ add %r12, %r13 C 16 4-bit fields (0..4)
+
+ add %r13, %r9 C 16 4-bit fields (0..8)
+ mov %r9, %r8
+ shr $4, %r9
+ and h0f0f0f0f, %r8
+ and h0f0f0f0f, %r9
+ add %r8, %r9 C 8 8-bit fields (0..16)
+
+ imul h01010101, %r9 C sum the 8 fields in high 8 bits
+ shr $56, %r9
+
+ add %r9, %rax C add to total
+ add $2, n
+ jnc L(top)
+
+L(end):
+ HAM(` pop %r14 ')
+ pop %r13
+ pop %r12
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/rsh1aors_n.asm b/gmp/mpn/x86_64/rsh1aors_n.asm
new file mode 100644
index 0000000000..a3e9cc5d23
--- /dev/null
+++ b/gmp/mpn/x86_64/rsh1aors_n.asm
@@ -0,0 +1,189 @@
+dnl AMD64 mpn_rsh1add_n -- rp[] = (up[] + vp[]) >> 1
+dnl AMD64 mpn_rsh1sub_n -- rp[] = (up[] - vp[]) >> 1
+
+dnl Copyright 2003, 2005, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.14 (mpn_add_n + mpn_rshift need 4.125)
+C AMD K10 2.14 (mpn_add_n + mpn_rshift need 4.125)
+C Intel P4 12.75
+C Intel core2 3.75
+C Intel NMH 4.4
+C Intel SBR ?
+C Intel atom ?
+C VIA nano 3.25
+
+C TODO
+C * Rewrite to use indexed addressing, like addlsh1.asm and sublsh1.asm.
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`vp', `%rdx')
+define(`n',` %rcx')
+
+ifdef(`OPERATION_rsh1add_n', `
+ define(ADDSUB, add)
+ define(ADCSBB, adc)
+ define(func_n, mpn_rsh1add_n)
+ define(func_nc, mpn_rsh1add_nc)')
+ifdef(`OPERATION_rsh1sub_n', `
+ define(ADDSUB, sub)
+ define(ADCSBB, sbb)
+ define(func_n, mpn_rsh1sub_n)
+ define(func_nc, mpn_rsh1sub_nc)')
+
+MULFUNC_PROLOGUE(mpn_rsh1add_n mpn_rsh1add_nc mpn_rsh1sub_n mpn_rsh1sub_nc)
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(func_nc)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8 ')
+ push %rbx
+
+ xor R32(%rax), R32(%rax)
+ neg %r8 C set C flag from parameter
+ mov (up), %rbx
+ ADCSBB (vp), %rbx
+ jmp L(ent)
+EPILOGUE()
+
+ ALIGN(16)
+PROLOGUE(func_n)
+ FUNC_ENTRY(4)
+ push %rbx
+
+ xor R32(%rax), R32(%rax)
+ mov (up), %rbx
+ ADDSUB (vp), %rbx
+L(ent):
+ rcr %rbx C rotate, save acy
+ adc R32(%rax), R32(%rax) C return value
+
+ mov R32(n), R32(%r11)
+ and $3, R32(%r11)
+
+ cmp $1, R32(%r11)
+ je L(do) C jump if n = 1 5 9 ...
+
+L(n1): cmp $2, R32(%r11)
+ jne L(n2) C jump unless n = 2 6 10 ...
+ add %rbx, %rbx C rotate carry limb, restore acy
+ mov 8(up), %r10
+ ADCSBB 8(vp), %r10
+ lea 8(up), up
+ lea 8(vp), vp
+ lea 8(rp), rp
+ rcr %r10
+ rcr %rbx
+ mov %rbx, -8(rp)
+ jmp L(cj1)
+
+L(n2): cmp $3, R32(%r11)
+ jne L(n3) C jump unless n = 3 7 11 ...
+ add %rbx, %rbx C rotate carry limb, restore acy
+ mov 8(up), %r9
+ mov 16(up), %r10
+ ADCSBB 8(vp), %r9
+ ADCSBB 16(vp), %r10
+ lea 16(up), up
+ lea 16(vp), vp
+ lea 16(rp), rp
+ rcr %r10
+ rcr %r9
+ rcr %rbx
+ mov %rbx, -16(rp)
+ jmp L(cj2)
+
+L(n3): dec n C come here for n = 4 8 12 ...
+ add %rbx, %rbx C rotate carry limb, restore acy
+ mov 8(up), %r8
+ mov 16(up), %r9
+ ADCSBB 8(vp), %r8
+ ADCSBB 16(vp), %r9
+ mov 24(up), %r10
+ ADCSBB 24(vp), %r10
+ lea 24(up), up
+ lea 24(vp), vp
+ lea 24(rp), rp
+ rcr %r10
+ rcr %r9
+ rcr %r8
+ rcr %rbx
+ mov %rbx, -24(rp)
+ mov %r8, -16(rp)
+L(cj2): mov %r9, -8(rp)
+L(cj1): mov %r10, %rbx
+
+L(do):
+ shr $2, n C 4
+ je L(end) C 2
+ ALIGN(16)
+L(top): add %rbx, %rbx C rotate carry limb, restore acy
+
+ mov 8(up), %r8
+ mov 16(up), %r9
+ ADCSBB 8(vp), %r8
+ ADCSBB 16(vp), %r9
+ mov 24(up), %r10
+ mov 32(up), %r11
+ ADCSBB 24(vp), %r10
+ ADCSBB 32(vp), %r11
+
+ lea 32(up), up
+ lea 32(vp), vp
+
+ rcr %r11 C rotate, save acy
+ rcr %r10
+ rcr %r9
+ rcr %r8
+
+ rcr %rbx
+ mov %rbx, (rp)
+ mov %r8, 8(rp)
+ mov %r9, 16(rp)
+ mov %r10, 24(rp)
+ mov %r11, %rbx
+
+ lea 32(rp), rp
+ dec n
+ jne L(top)
+
+L(end): mov %rbx, (rp)
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/rshift.asm b/gmp/mpn/x86_64/rshift.asm
new file mode 100644
index 0000000000..3f344f1dfc
--- /dev/null
+++ b/gmp/mpn/x86_64/rshift.asm
@@ -0,0 +1,176 @@
+dnl AMD64 mpn_rshift -- mpn right shift.
+
+dnl Copyright 2003, 2005, 2009, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 2.375
+C AMD K10 2.375
+C Intel P4 8
+C Intel core2 2.11
+C Intel corei ?
+C Intel atom 5.75
+C VIA nano 3.5
+
+
+C INPUT PARAMETERS
+define(`rp', `%rdi')
+define(`up', `%rsi')
+define(`n', `%rdx')
+define(`cnt', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_rshift)
+ FUNC_ENTRY(4)
+ neg R32(%rcx) C put rsh count in cl
+ mov (up), %rax
+ shl R8(%rcx), %rax C function return value
+ neg R32(%rcx) C put lsh count in cl
+
+ lea 1(n), R32(%r8)
+
+ lea -8(up,n,8), up
+ lea -8(rp,n,8), rp
+ neg n
+
+ and $3, R32(%r8)
+ je L(rlx) C jump for n = 3, 7, 11, ...
+
+ dec R32(%r8)
+ jne L(1)
+C n = 4, 8, 12, ...
+ mov 8(up,n,8), %r10
+ shr R8(%rcx), %r10
+ neg R32(%rcx) C put rsh count in cl
+ mov 16(up,n,8), %r8
+ shl R8(%rcx), %r8
+ or %r8, %r10
+ mov %r10, 8(rp,n,8)
+ inc n
+ jmp L(rll)
+
+L(1): dec R32(%r8)
+ je L(1x) C jump for n = 1, 5, 9, 13, ...
+C n = 2, 6, 10, 16, ...
+ mov 8(up,n,8), %r10
+ shr R8(%rcx), %r10
+ neg R32(%rcx) C put rsh count in cl
+ mov 16(up,n,8), %r8
+ shl R8(%rcx), %r8
+ or %r8, %r10
+ mov %r10, 8(rp,n,8)
+ inc n
+ neg R32(%rcx) C put lsh count in cl
+L(1x):
+ cmp $-1, n
+ je L(ast)
+ mov 8(up,n,8), %r10
+ shr R8(%rcx), %r10
+ mov 16(up,n,8), %r11
+ shr R8(%rcx), %r11
+ neg R32(%rcx) C put rsh count in cl
+ mov 16(up,n,8), %r8
+ mov 24(up,n,8), %r9
+ shl R8(%rcx), %r8
+ or %r8, %r10
+ shl R8(%rcx), %r9
+ or %r9, %r11
+ mov %r10, 8(rp,n,8)
+ mov %r11, 16(rp,n,8)
+ add $2, n
+
+L(rll): neg R32(%rcx) C put lsh count in cl
+L(rlx): mov 8(up,n,8), %r10
+ shr R8(%rcx), %r10
+ mov 16(up,n,8), %r11
+ shr R8(%rcx), %r11
+
+ add $4, n C 4
+ jb L(end) C 2
+ ALIGN(16)
+L(top):
+ C finish stuff from lsh block
+ neg R32(%rcx) C put rsh count in cl
+ mov -16(up,n,8), %r8
+ mov -8(up,n,8), %r9
+ shl R8(%rcx), %r8
+ or %r8, %r10
+ shl R8(%rcx), %r9
+ or %r9, %r11
+ mov %r10, -24(rp,n,8)
+ mov %r11, -16(rp,n,8)
+ C start two new rsh
+ mov (up,n,8), %r8
+ mov 8(up,n,8), %r9
+ shl R8(%rcx), %r8
+ shl R8(%rcx), %r9
+
+ C finish stuff from rsh block
+ neg R32(%rcx) C put lsh count in cl
+ mov -8(up,n,8), %r10
+ mov 0(up,n,8), %r11
+ shr R8(%rcx), %r10
+ or %r10, %r8
+ shr R8(%rcx), %r11
+ or %r11, %r9
+ mov %r8, -8(rp,n,8)
+ mov %r9, 0(rp,n,8)
+ C start two new lsh
+ mov 8(up,n,8), %r10
+ mov 16(up,n,8), %r11
+ shr R8(%rcx), %r10
+ shr R8(%rcx), %r11
+
+ add $4, n
+ jae L(top) C 2
+L(end):
+ neg R32(%rcx) C put rsh count in cl
+ mov -8(up), %r8
+ shl R8(%rcx), %r8
+ or %r8, %r10
+ mov (up), %r9
+ shl R8(%rcx), %r9
+ or %r9, %r11
+ mov %r10, -16(rp)
+ mov %r11, -8(rp)
+
+ neg R32(%rcx) C put lsh count in cl
+L(ast): mov (up), %r10
+ shr R8(%rcx), %r10
+ mov %r10, (rp)
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/sec_tabselect.asm b/gmp/mpn/x86_64/sec_tabselect.asm
new file mode 100644
index 0000000000..e8aed261ef
--- /dev/null
+++ b/gmp/mpn/x86_64/sec_tabselect.asm
@@ -0,0 +1,176 @@
+dnl AMD64 mpn_sec_tabselect.
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb good for cpu
+C AMD K8,K9 1.5 Y
+C AMD K10 1.4
+C AMD bd1 2.64
+C AMD bobcat 2.15 Y
+C Intel P4 4
+C Intel core2 1.38
+C Intel NHM 1.75
+C Intel SBR 1.25
+C Intel atom 2.5 Y
+C VIA nano 1.75 Y
+
+C NOTES
+C * This has not been tuned for any specific processor. Its speed should not
+C be too bad, though.
+C * Using SSE2/AVX2 could result in many-fold speedup.
+C * WORKS FOR n mod 4 = 0 ONLY!
+
+C mpn_sec_tabselect (mp_limb_t *rp, mp_limb_t *tp, mp_size_t n, mp_size_t nents, mp_size_t which)
+define(`rp', `%rdi')
+define(`tp', `%rsi')
+define(`n', `%rdx')
+define(`nents', `%rcx')
+define(`which', `%r8')
+
+define(`i', `%rbp')
+define(`j', `%r9')
+
+C rax rbx rcx rdx rdi rsi rbp r8 r9 r10 r11 r12 r13 r14 r15
+C nents n rp tab i which j * * * * * *
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sec_tabselect)
+ FUNC_ENTRY(4)
+IFDOS(` mov 56(%rsp), %r8d ')
+
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ mov n, j
+ add $-4, j
+ js L(outer_end)
+
+L(outer_top):
+ mov nents, i
+ push tp
+ xor R32(%r12), R32(%r12)
+ xor R32(%r13), R32(%r13)
+ xor R32(%r14), R32(%r14)
+ xor R32(%r15), R32(%r15)
+ mov which, %rbx
+
+ ALIGN(16)
+L(top): sub $1, %rbx
+ sbb %rax, %rax
+ mov 0(tp), %r10
+ mov 8(tp), %r11
+ and %rax, %r10
+ and %rax, %r11
+ or %r10, %r12
+ or %r11, %r13
+ mov 16(tp), %r10
+ mov 24(tp), %r11
+ and %rax, %r10
+ and %rax, %r11
+ or %r10, %r14
+ or %r11, %r15
+ lea (tp,n,8), tp
+ add $-1, i
+ jne L(top)
+
+ mov %r12, 0(rp)
+ mov %r13, 8(rp)
+ mov %r14, 16(rp)
+ mov %r15, 24(rp)
+ pop tp
+ lea 32(tp), tp
+ lea 32(rp), rp
+ add $-4, j
+ jns L(outer_top)
+L(outer_end):
+
+ test $2, R8(n)
+ jz L(b0x)
+L(b1x): mov nents, i
+ push tp
+ xor R32(%r12), R32(%r12)
+ xor R32(%r13), R32(%r13)
+ mov which, %rbx
+ ALIGN(16)
+L(tp2): sub $1, %rbx
+ sbb %rax, %rax
+ mov 0(tp), %r10
+ mov 8(tp), %r11
+ and %rax, %r10
+ and %rax, %r11
+ or %r10, %r12
+ or %r11, %r13
+ lea (tp,n,8), tp
+ add $-1, i
+ jne L(tp2)
+ mov %r12, 0(rp)
+ mov %r13, 8(rp)
+ pop tp
+ lea 16(tp), tp
+ lea 16(rp), rp
+
+L(b0x): test $1, R8(n)
+ jz L(b00)
+L(b01): mov nents, i
+ xor R32(%r12), R32(%r12)
+ mov which, %rbx
+ ALIGN(16)
+L(tp1): sub $1, %rbx
+ sbb %rax, %rax
+ mov 0(tp), %r10
+ and %rax, %r10
+ or %r10, %r12
+ lea (tp,n,8), tp
+ add $-1, i
+ jne L(tp1)
+ mov %r12, 0(rp)
+
+L(b00): pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/sqr_diag_addlsh1.asm b/gmp/mpn/x86_64/sqr_diag_addlsh1.asm
new file mode 100644
index 0000000000..4ad034c855
--- /dev/null
+++ b/gmp/mpn/x86_64/sqr_diag_addlsh1.asm
@@ -0,0 +1,116 @@
+dnl AMD64 mpn_sqr_diag_addlsh1
+
+dnl Contributed to the GNU project by Torbjörn Granlund.
+
+dnl Copyright 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+C cycles/limb
+C AMD K8,K9 2.5
+C AMD K10 2.5
+C AMD bull 3.6
+C AMD pile 3.6
+C AMD steam ?
+C AMD bobcat 4
+C AMD jaguar ?
+C Intel P4 ?
+C Intel core 4
+C Intel NHM 3.6
+C Intel SBR 3.15
+C Intel IBR 3.2
+C Intel HWL 2.6
+C Intel BWL ?
+C Intel atom 14
+C VIA nano 3.5
+
+C When playing with pointers, set this to $2 to fall back to conservative
+C indexing in wind-down code.
+define(`I',`$1')
+
+define(`rp', `%rdi')
+define(`tp', `%rsi')
+define(`up_arg', `%rdx')
+define(`n', `%rcx')
+
+define(`up', `%r11')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(32)
+PROLOGUE(mpn_sqr_diag_addlsh1)
+ FUNC_ENTRY(4)
+ push %rbx
+
+ dec n
+ shl n
+
+ mov (up_arg), %rax
+
+ lea (rp,n,8), rp
+ lea (tp,n,8), tp
+ lea (up_arg,n,4), up
+ neg n
+
+ mul %rax
+ mov %rax, (rp,n,8)
+
+ xor R32(%rbx), R32(%rbx)
+ jmp L(mid)
+
+ ALIGN(16)
+L(top): add %r10, %r8
+ adc %rax, %r9
+ mov %r8, -8(rp,n,8)
+ mov %r9, (rp,n,8)
+L(mid): mov 8(up,n,4), %rax
+ mov (tp,n,8), %r8
+ mov 8(tp,n,8), %r9
+ adc %r8, %r8
+ adc %r9, %r9
+ lea (%rdx,%rbx), %r10
+ setc R8(%rbx)
+ mul %rax
+ add $2, n
+ js L(top)
+
+L(end): add %r10, %r8
+ adc %rax, %r9
+ mov %r8, I(-8(rp),-8(rp,n,8))
+ mov %r9, I((rp),(rp,n,8))
+ adc %rbx, %rdx
+ mov %rdx, I(8(rp),8(rp,n,8))
+
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/sublsh1_n.asm b/gmp/mpn/x86_64/sublsh1_n.asm
new file mode 100644
index 0000000000..c6d829fcb2
--- /dev/null
+++ b/gmp/mpn/x86_64/sublsh1_n.asm
@@ -0,0 +1,160 @@
+dnl AMD64 mpn_sublsh1_n -- rp[] = up[] - (vp[] << 1)
+
+dnl Copyright 2003, 2005-2007, 2011, 2012 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C cycles/limb
+C AMD K8,K9 2.2
+C AMD K10 2.2
+C Intel P4 12.75
+C Intel core2 3.45
+C Intel corei ?
+C Intel atom ?
+C VIA nano 3.25
+
+C Sometimes speed degenerates, supposedly related to that some operand
+C alignments cause cache conflicts.
+
+C The speed is limited by decoding/issue bandwidth. There are 26 instructions
+C in the loop, which corresponds to 26/3/4 = 2.167 c/l.
+
+C INPUT PARAMETERS
+define(`rp',`%rdi')
+define(`up',`%rsi')
+define(`vp',`%rdx')
+define(`n', `%rcx')
+
+ABI_SUPPORT(DOS64)
+ABI_SUPPORT(STD64)
+
+ASM_START()
+ TEXT
+ ALIGN(16)
+PROLOGUE(mpn_sublsh1_n)
+ FUNC_ENTRY(4)
+ push %rbx
+ push %rbp
+
+ mov (vp), %r8
+ mov R32(n), R32(%rax)
+ lea (rp,n,8), rp
+ lea (up,n,8), up
+ lea (vp,n,8), vp
+ neg n
+ xor R32(%rbp), R32(%rbp)
+ and $3, R32(%rax)
+ je L(b00)
+ cmp $2, R32(%rax)
+ jc L(b01)
+ je L(b10)
+
+L(b11): add %r8, %r8
+ mov 8(vp,n,8), %r9
+ adc %r9, %r9
+ mov 16(vp,n,8), %r10
+ adc %r10, %r10
+ sbb R32(%rax), R32(%rax) C save scy
+ mov (up,n,8), %rbp
+ mov 8(up,n,8), %rbx
+ sub %r8, %rbp
+ sbb %r9, %rbx
+ mov %rbp, (rp,n,8)
+ mov %rbx, 8(rp,n,8)
+ mov 16(up,n,8), %rbp
+ sbb %r10, %rbp
+ mov %rbp, 16(rp,n,8)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ add $3, n
+ jmp L(ent)
+
+L(b10): add %r8, %r8
+ mov 8(vp,n,8), %r9
+ adc %r9, %r9
+ sbb R32(%rax), R32(%rax) C save scy
+ mov (up,n,8), %rbp
+ mov 8(up,n,8), %rbx
+ sub %r8, %rbp
+ sbb %r9, %rbx
+ mov %rbp, (rp,n,8)
+ mov %rbx, 8(rp,n,8)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ add $2, n
+ jmp L(ent)
+
+L(b01): add %r8, %r8
+ sbb R32(%rax), R32(%rax) C save scy
+ mov (up,n,8), %rbp
+ sub %r8, %rbp
+ mov %rbp, (rp,n,8)
+ sbb R32(%rbp), R32(%rbp) C save acy
+ inc n
+L(ent): jns L(end)
+
+ ALIGN(16)
+L(top): add R32(%rax), R32(%rax) C restore scy
+
+ mov (vp,n,8), %r8
+L(b00): adc %r8, %r8
+ mov 8(vp,n,8), %r9
+ adc %r9, %r9
+ mov 16(vp,n,8), %r10
+ adc %r10, %r10
+ mov 24(vp,n,8), %r11
+ adc %r11, %r11
+
+ sbb R32(%rax), R32(%rax) C save scy
+ add R32(%rbp), R32(%rbp) C restore acy
+
+ mov (up,n,8), %rbp
+ mov 8(up,n,8), %rbx
+ sbb %r8, %rbp
+ sbb %r9, %rbx
+ mov %rbp, (rp,n,8)
+ mov %rbx, 8(rp,n,8)
+ mov 16(up,n,8), %rbp
+ mov 24(up,n,8), %rbx
+ sbb %r10, %rbp
+ sbb %r11, %rbx
+ mov %rbp, 16(rp,n,8)
+ mov %rbx, 24(rp,n,8)
+
+ sbb R32(%rbp), R32(%rbp) C save acy
+ add $4, n
+ js L(top)
+
+L(end): add R32(%rbp), R32(%rax)
+ neg R32(%rax)
+
+ pop %rbp
+ pop %rbx
+ FUNC_EXIT()
+ ret
+EPILOGUE()
diff --git a/gmp/mpn/x86_64/x86_64-defs.m4 b/gmp/mpn/x86_64/x86_64-defs.m4
new file mode 100644
index 0000000000..366598b41d
--- /dev/null
+++ b/gmp/mpn/x86_64/x86_64-defs.m4
@@ -0,0 +1,354 @@
+divert(-1)
+
+dnl m4 macros for amd64 assembler.
+
+dnl Copyright 1999-2005, 2008, 2009, 2011-2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+dnl Usage: CPUVEC_FUNCS_LIST
+dnl
+dnl A list of the functions from gmp-impl.h x86 struct cpuvec_t, in the
+dnl order they appear in that structure.
+
+define(CPUVEC_FUNCS_LIST,
+``add_n',
+`addlsh1_n',
+`addlsh2_n',
+`addmul_1',
+`addmul_2',
+`bdiv_dbm1c',
+`cnd_add_n',
+`cnd_sub_n',
+`com',
+`copyd',
+`copyi',
+`divexact_1',
+`divrem_1',
+`gcd_1',
+`lshift',
+`lshiftc',
+`mod_1',
+`mod_1_1p',
+`mod_1_1p_cps',
+`mod_1s_2p',
+`mod_1s_2p_cps',
+`mod_1s_4p',
+`mod_1s_4p_cps',
+`mod_34lsub1',
+`modexact_1c_odd',
+`mul_1',
+`mul_basecase',
+`mullo_basecase',
+`preinv_divrem_1',
+`preinv_mod_1',
+`redc_1',
+`redc_2',
+`rshift',
+`sqr_basecase',
+`sub_n',
+`sublsh1_n',
+`submul_1'')
+
+
+dnl Called: PROLOGUE_cpu(GSYM_PREFIX`'foo)
+dnl
+dnl In the amd64 code we use explicit TEXT and ALIGN() calls in the code,
+dnl since different alignments are wanted in various circumstances. So for
+dnl instance,
+dnl
+dnl TEXT
+dnl ALIGN(16)
+dnl PROLOGUE(mpn_add_n)
+dnl ...
+dnl EPILOGUE()
+
+define(`PROLOGUE_cpu',
+m4_assert_numargs(1)
+` GLOBL $1
+ TYPE($1,`function')
+$1:
+')
+
+
+dnl Usage: ASSERT([cond][,instructions])
+dnl
+dnl If WANT_ASSERT is 1, output the given instructions and expect the given
+dnl flags condition to then be satisfied. For example,
+dnl
+dnl ASSERT(ne, `cmpq %rax, %rbx')
+dnl
+dnl The instructions can be omitted to just assert a flags condition with
+dnl no extra calculation. For example,
+dnl
+dnl ASSERT(nc)
+dnl
+dnl When `instructions' is not empty, a pushfq/popfq is added for
+dnl convenience to preserve the flags, but the instructions themselves must
+dnl preserve any registers that matter.
+dnl
+dnl The condition can be omitted to just output the given instructions when
+dnl assertion checking is wanted. In this case the pushf/popf is omitted.
+dnl For example,
+dnl
+dnl ASSERT(, `movq %rax, VAR_KEEPVAL')
+
+define(ASSERT,
+m4_assert_numargs_range(1,2)
+m4_assert_defined(`WANT_ASSERT')
+`ifelse(WANT_ASSERT,1,
+`ifelse(`$1',,
+` $2',
+`ifelse(`$2',,,
+` pushfq')
+ $2
+ j`$1' L(ASSERT_ok`'ASSERT_counter)
+ ud2 C assertion failed
+L(ASSERT_ok`'ASSERT_counter):
+ifelse(`$2',,,` popfq')
+define(`ASSERT_counter',incr(ASSERT_counter))')')')
+
+define(ASSERT_counter,1)
+
+define(`LEA',`dnl
+ifdef(`PIC',
+ `mov $1@GOTPCREL(%rip), $2'
+,
+ `movabs `$'$1, $2')
+')
+
+
+define(`DEF_OBJECT',
+m4_assert_numargs_range(1,2)
+` RODATA
+ ALIGN(ifelse($#,1,2,$2))
+$1:
+')
+
+define(`END_OBJECT',
+m4_assert_numargs(1)
+` SIZE(`$1',.-`$1')')
+
+
+define(`R32',
+ `ifelse($1,`%rax',`%eax',
+ $1,`%rbx',`%ebx',
+ $1,`%rcx',`%ecx',
+ $1,`%rdx',`%edx',
+ $1,`%rsi',`%esi',
+ $1,`%rdi',`%edi',
+ $1,`%rbp',`%ebp',
+ $1,`%r8',`%r8d',
+ $1,`%r9',`%r9d',
+ $1,`%r10',`%r10d',
+ $1,`%r11',`%r11d',
+ $1,`%r12',`%r12d',
+ $1,`%r13',`%r13d',
+ $1,`%r14',`%r14d',
+ $1,`%r15',`%r15d')')
+define(`R8',
+ `ifelse($1,`%rax',`%al',
+ $1,`%rbx',`%bl',
+ $1,`%rcx',`%cl',
+ $1,`%rdx',`%dl',
+ $1,`%rsi',`%sil',
+ $1,`%rdi',`%dil',
+ $1,`%rbp',`%bpl',
+ $1,`%r8',`%r8b',
+ $1,`%r9',`%r9b',
+ $1,`%r10',`%r10b',
+ $1,`%r11',`%r11b',
+ $1,`%r12',`%r12b',
+ $1,`%r13',`%r13b',
+ $1,`%r14',`%r14b',
+ $1,`%r15',`%r15b')')
+
+
+dnl Usage: CALL(funcname)
+dnl
+
+define(`CALL',`dnl
+ifdef(`PIC',
+ `call GSYM_PREFIX`'$1@PLT'
+,
+ `call GSYM_PREFIX`'$1'
+)')
+
+
+define(`JUMPTABSECT', `.section .data.rel.ro.local,"aw",@progbits')
+
+
+dnl Usage: JMPENT(targlabel,tablabel)
+
+define(`JMPENT',`dnl
+ifdef(`PIC',
+ `.long $1-$2'
+,
+ `.quad $1'
+)')
+
+
+dnl These macros are defined just for DOS64, where they provide calling
+dnl sequence glue code.
+
+define(`FUNC_ENTRY',`')
+define(`FUNC_EXIT',`')
+
+
+dnl Target ABI macros.
+
+define(`IFDOS', `')
+define(`IFSTD', `$1')
+define(`IFELF', `$1')
+
+
+dnl Usage: PROTECT(symbol)
+dnl
+dnl Used for private GMP symbols that should never be overridden by users.
+dnl This can save reloc entries and improve shlib sharing as well as
+dnl application startup times
+
+define(`PROTECT', `.hidden $1')
+
+
+dnl Usage: x86_lookup(target, key,value, key,value, ...)
+dnl
+dnl Look for `target' among the `key' parameters.
+dnl
+dnl x86_lookup expands to the corresponding `value', or generates an error
+dnl if `target' isn't found.
+
+define(x86_lookup,
+m4_assert_numargs_range(1,999)
+`ifelse(eval($#<3),1,
+`m4_error(`unrecognised part of x86 instruction: $1
+')',
+`ifelse(`$1',`$2', `$3',
+`x86_lookup(`$1',shift(shift(shift($@))))')')')
+
+
+dnl Usage: x86_opcode_regxmm(reg)
+dnl
+dnl Validate the given xmm register, and return its number, 0 to 7.
+
+define(x86_opcode_regxmm,
+m4_assert_numargs(1)
+`x86_lookup(`$1',x86_opcode_regxmm_list)')
+
+define(x86_opcode_regxmm_list,
+``%xmm0',0,
+`%xmm1',1,
+`%xmm2',2,
+`%xmm3',3,
+`%xmm4',4,
+`%xmm5',5,
+`%xmm6',6,
+`%xmm7',7,
+`%xmm8',8,
+`%xmm9',9,
+`%xmm10',10,
+`%xmm11',11,
+`%xmm12',12,
+`%xmm13',13,
+`%xmm14',14,
+`%xmm15',15')
+
+dnl Usage: palignr($imm,%srcreg,%dstreg)
+dnl
+dnl Emit a palignr instruction, using a .byte sequence, since obsolete but
+dnl still distributed versions of gas don't know SSSE3 instructions.
+
+define(`palignr',
+m4_assert_numargs(3)
+`.byte 0x66,dnl
+ifelse(eval(x86_opcode_regxmm($3) >= 8 || x86_opcode_regxmm($2) >= 8),1,
+ `eval(0x40+x86_opcode_regxmm($3)/8*4+x86_opcode_regxmm($2)/8),')dnl
+0x0f,0x3a,0x0f,dnl
+eval(0xc0+x86_opcode_regxmm($3)%8*8+x86_opcode_regxmm($2)%8),dnl
+substr($1,1)')
+
+
+dnl Usage
+dnl
+dnl regnum(op) raw operand index (so slightly misnamed)
+dnl regnumh(op) high bit of register operand nimber
+dnl ix(op) 0 for reg operand, 1 for plain pointer operand.
+dnl
+
+define(`regnum',`x86_lookup(`$1',oplist)')
+define(`regnumh',`eval(regnum($1)/8 & 1)')
+define(`ix',`eval(regnum($1)/16)')
+define(`oplist',
+``%rax', 0, `%rcx', 1, `%rdx', 2, `%rbx', 3,
+ `%rsp', 4, `%rbp', 5, `%rsi', 6, `%rdi', 7,
+ `%r8', 8, `%r9', 9, `%r10', 10, `%r11', 11,
+ `%r12', 12, `%r13', 13, `%r14', 14, `%r15', 15,
+ `(%rax)',16, `(%rcx)',17, `(%rdx)',18, `(%rbx)',19,
+ `(%rsp)',20, `(%rbp)',21, `(%rsi)',22, `(%rdi)',23,
+ `(%r8)', 24, `(%r9)', 25, `(%r10)',26, `(%r11)',27,
+ `(%r12)',28, `(%r13)',29, `(%r14)',30, `(%r15)' 31')
+
+
+dnl Usage
+dnl
+dnl mulx(reg1,reg2,reg3)
+dnl
+dnl or
+dnl
+dnl mulx((reg1),reg2,reg3)
+dnl
+dnl where reg1 is any register but rsp,rbp,r12,r13, or
+dnl
+dnl mulx(off,(reg1),reg2,reg3)
+dnl
+dnl where reg1 is any register but rsp,r12.
+dnl
+dnl The exceptions are due to special coding needed for some registers; rsp
+dnl and r12 need an extra byte 0x24 at the end while rbp and r13 lack the
+dnl offset-less form.
+dnl
+dnl Other addressing forms are not handled. Invalid forms are not properly
+dnl detected. Offsets that don't fit one byte are not handled correctly.
+
+define(`mulx',`dnl
+ifelse($#,3,
+`.byte 0xc4`'dnl
+,0x`'eval(0xe2^32*regnumh($1)^128*regnumh($3),16)`'dnl
+,0x`'eval(0xfb-8*regnum($2),16)`'dnl
+,0xf6`'dnl
+,0x`'eval(0xc0+(7 & regnum($1))+8*(7 & regnum($3))-0xc0*ix($1),16)`'dnl
+',$#,4,
+`.byte 0xc4`'dnl
+,0x`'eval(0xe2^32*regnumh($2)^128*regnumh($4),16)`'dnl
+,0x`'eval(0xfb-8*regnum($3),16)`'dnl
+,0xf6`'dnl
+,0x`'eval(0x40+(7 & regnum($2))+8*(7 & regnum($4)),16)`'dnl
+,0x`'eval(($1 + 256) % 256,16)`'dnl
+')')
+
+divert`'dnl
diff --git a/gmp/mpq/Makefile.am b/gmp/mpq/Makefile.am
new file mode 100644
index 0000000000..406aa9f8dc
--- /dev/null
+++ b/gmp/mpq/Makefile.am
@@ -0,0 +1,41 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 1996, 1998, 2000-2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+
+noinst_LTLIBRARIES = libmpq.la
+libmpq_la_SOURCES = \
+ abs.c aors.c canonicalize.c clear.c clears.c \
+ cmp.c cmp_si.c cmp_ui.c div.c equal.c \
+ get_d.c get_den.c get_num.c get_str.c \
+ init.c inits.c inp_str.c inv.c md_2exp.c mul.c neg.c out_str.c \
+ set.c set_den.c set_num.c set_si.c set_str.c set_ui.c set_z.c set_d.c \
+ set_f.c swap.c
diff --git a/gmp/mpq/Makefile.in b/gmp/mpq/Makefile.in
new file mode 100644
index 0000000000..8bc0a9984f
--- /dev/null
+++ b/gmp/mpq/Makefile.in
@@ -0,0 +1,563 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 1996, 1998, 2000-2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = mpq
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libmpq_la_LIBADD =
+am_libmpq_la_OBJECTS = abs.lo aors.lo canonicalize.lo clear.lo \
+ clears.lo cmp.lo cmp_si.lo cmp_ui.lo div.lo equal.lo get_d.lo \
+ get_den.lo get_num.lo get_str.lo init.lo inits.lo inp_str.lo \
+ inv.lo md_2exp.lo mul.lo neg.lo out_str.lo set.lo set_den.lo \
+ set_num.lo set_si.lo set_str.lo set_ui.lo set_z.lo set_d.lo \
+ set_f.lo swap.lo
+libmpq_la_OBJECTS = $(am_libmpq_la_OBJECTS)
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libmpq_la_SOURCES)
+DIST_SOURCES = $(libmpq_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+noinst_LTLIBRARIES = libmpq.la
+libmpq_la_SOURCES = \
+ abs.c aors.c canonicalize.c clear.c clears.c \
+ cmp.c cmp_si.c cmp_ui.c div.c equal.c \
+ get_d.c get_den.c get_num.c get_str.c \
+ init.c inits.c inp_str.c inv.c md_2exp.c mul.c neg.c out_str.c \
+ set.c set_den.c set_num.c set_si.c set_str.c set_ui.c set_z.c set_d.c \
+ set_f.c swap.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 mpq/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps mpq/Makefile
+.PRECIOUS: 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-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libmpq.la: $(libmpq_la_OBJECTS) $(libmpq_la_DEPENDENCIES) $(EXTRA_libmpq_la_DEPENDENCIES)
+ $(LINK) $(libmpq_la_OBJECTS) $(libmpq_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+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:
+
+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-generic clean-libtool clean-noinstLTLIBRARIES \
+ 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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags 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 tags uninstall uninstall-am
+
+
+# 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/gmp/mpq/abs.c b/gmp/mpq/abs.c
new file mode 100644
index 0000000000..7fe04a35bb
--- /dev/null
+++ b/gmp/mpq/abs.c
@@ -0,0 +1,56 @@
+/* mpq_abs -- absolute value of a rational.
+
+Copyright 2000, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpq_abs 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpq_abs (mpq_ptr dst, mpq_srcptr src)
+{
+ mp_size_t num_abs_size = ABSIZ(NUM(src));
+
+ if (dst != src)
+ {
+ mp_size_t den_size = SIZ(DEN(src));
+ mp_ptr dp;
+
+ dp = MPZ_NEWALLOC (NUM(dst), num_abs_size);
+ MPN_COPY (dp, PTR(NUM(src)), num_abs_size);
+
+ dp = MPZ_NEWALLOC (DEN(dst), den_size);
+ SIZ(DEN(dst)) = den_size;
+ MPN_COPY (dp, PTR(DEN(src)), den_size);
+ }
+
+ SIZ(NUM(dst)) = num_abs_size;
+}
diff --git a/gmp/mpq/aors.c b/gmp/mpq/aors.c
new file mode 100644
index 0000000000..81edc1fa39
--- /dev/null
+++ b/gmp/mpq/aors.c
@@ -0,0 +1,113 @@
+/* mpq_add, mpq_sub -- add or subtract rational numbers.
+
+Copyright 1991, 1994-1997, 2000, 2001, 2004, 2005 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+static void __gmpq_aors (REGPARM_3_1 (mpq_ptr, mpq_srcptr, mpq_srcptr, void (*) (mpz_ptr, mpz_srcptr, mpz_srcptr))) REGPARM_ATTR (1);
+#define mpq_aors(w,x,y,fun) __gmpq_aors (REGPARM_3_1 (w, x, y, fun))
+
+REGPARM_ATTR (1) static void
+mpq_aors (mpq_ptr rop, mpq_srcptr op1, mpq_srcptr op2,
+ void (*fun) (mpz_ptr, mpz_srcptr, mpz_srcptr))
+{
+ mpz_t gcd;
+ mpz_t tmp1, tmp2;
+ mp_size_t op1_num_size = ABSIZ(NUM(op1));
+ mp_size_t op1_den_size = SIZ(DEN(op1));
+ mp_size_t op2_num_size = ABSIZ(NUM(op2));
+ mp_size_t op2_den_size = SIZ(DEN(op2));
+ TMP_DECL;
+
+ TMP_MARK;
+ MPZ_TMP_INIT (gcd, MIN (op1_den_size, op2_den_size));
+ MPZ_TMP_INIT (tmp1, op1_num_size + op2_den_size);
+ MPZ_TMP_INIT (tmp2, op2_num_size + op1_den_size);
+
+ /* ROP might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of ROP when we are finished
+ with the numerators of OP1 and OP2. */
+
+ mpz_gcd (gcd, DEN(op1), DEN(op2));
+ if (! MPZ_EQUAL_1_P (gcd))
+ {
+ mpz_t t;
+
+ MPZ_TMP_INIT (t, MAX (op1_num_size + op2_den_size,
+ op2_num_size + op1_den_size) + 2 - SIZ(gcd));
+
+ mpz_divexact_gcd (t, DEN(op2), gcd);
+ mpz_divexact_gcd (tmp2, DEN(op1), gcd);
+
+ mpz_mul (tmp1, NUM(op1), t);
+ mpz_mul (t, NUM(op2), tmp2);
+
+ (*fun) (t, tmp1, t);
+
+ mpz_gcd (gcd, t, gcd);
+ if (MPZ_EQUAL_1_P (gcd))
+ {
+ mpz_set (NUM(rop), t);
+ mpz_mul (DEN(rop), DEN(op2), tmp2);
+ }
+ else
+ {
+ mpz_divexact_gcd (NUM(rop), t, gcd);
+ mpz_divexact_gcd (tmp1, DEN(op2), gcd);
+ mpz_mul (DEN(rop), tmp1, tmp2);
+ }
+ }
+ else
+ {
+ /* The common divisor is 1. This is the case (for random input) with
+ probability 6/(pi**2), which is about 60.8%. */
+ mpz_mul (tmp1, NUM(op1), DEN(op2));
+ mpz_mul (tmp2, NUM(op2), DEN(op1));
+ (*fun) (NUM(rop), tmp1, tmp2);
+ mpz_mul (DEN(rop), DEN(op1), DEN(op2));
+ }
+ TMP_FREE;
+}
+
+
+void
+mpq_add (mpq_ptr rop, mpq_srcptr op1, mpq_srcptr op2)
+{
+ mpq_aors (rop, op1, op2, mpz_add);
+}
+
+void
+mpq_sub (mpq_ptr rop, mpq_srcptr op1, mpq_srcptr op2)
+{
+ mpq_aors (rop, op1, op2, mpz_sub);
+}
diff --git a/gmp/mpq/canonicalize.c b/gmp/mpq/canonicalize.c
new file mode 100644
index 0000000000..882f408fb8
--- /dev/null
+++ b/gmp/mpq/canonicalize.c
@@ -0,0 +1,63 @@
+/* mpq_canonicalize(op) -- Remove common factors of the denominator and
+ numerator in OP.
+
+Copyright 1991, 1994-1996, 2000, 2001, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_canonicalize (mpq_t op)
+{
+ mpz_t gcd;
+ TMP_DECL;
+
+ if (UNLIKELY (SIZ(DEN(op)) == 0))
+ DIVIDE_BY_ZERO;
+
+ TMP_MARK;
+
+ /* ??? Dunno if the 1+ is needed. */
+ MPZ_TMP_INIT (gcd, 1 + MAX (ABSIZ(NUM(op)),
+ ABSIZ(DEN(op))));
+
+ mpz_gcd (gcd, NUM(op), DEN(op));
+ if (! MPZ_EQUAL_1_P (gcd))
+ {
+ mpz_divexact_gcd (NUM(op), NUM(op), gcd);
+ mpz_divexact_gcd (DEN(op), DEN(op), gcd);
+ }
+
+ if (SIZ(DEN(op)) < 0)
+ {
+ SIZ(NUM(op)) = -SIZ(NUM(op));
+ SIZ(DEN(op)) = -SIZ(DEN(op));
+ }
+ TMP_FREE;
+}
diff --git a/gmp/mpq/clear.c b/gmp/mpq/clear.c
new file mode 100644
index 0000000000..ce0b973f9f
--- /dev/null
+++ b/gmp/mpq/clear.c
@@ -0,0 +1,41 @@
+/* mpq_clear -- free the space occupied by a mpq_t.
+
+Copyright 1991, 1994, 1995, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_clear (mpq_t m)
+{
+ (*__gmp_free_func) (PTR(NUM(m)),
+ (size_t) ALLOC(NUM(m)) * GMP_LIMB_BYTES);
+ (*__gmp_free_func) (PTR(DEN(m)),
+ (size_t) ALLOC(DEN(m)) * GMP_LIMB_BYTES);
+}
diff --git a/gmp/mpq/clears.c b/gmp/mpq/clears.c
new file mode 100644
index 0000000000..f949fe36cd
--- /dev/null
+++ b/gmp/mpq/clears.c
@@ -0,0 +1,52 @@
+/* mpq_clears() -- Clear multiple mpq_t variables.
+
+Copyright 2009, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_clears (mpq_ptr x, ...)
+{
+ va_list ap;
+
+ va_start (ap, x);
+
+ while (x != NULL)
+ {
+ (*__gmp_free_func) (PTR(NUM(x)),
+ (size_t) ALLOC(NUM(x)) * GMP_LIMB_BYTES);
+ (*__gmp_free_func) (PTR(DEN(x)),
+ (size_t) ALLOC(DEN(x)) * GMP_LIMB_BYTES);
+ x = va_arg (ap, mpq_ptr);
+ }
+ va_end (ap);
+}
diff --git a/gmp/mpq/cmp.c b/gmp/mpq/cmp.c
new file mode 100644
index 0000000000..e633b6f42d
--- /dev/null
+++ b/gmp/mpq/cmp.c
@@ -0,0 +1,126 @@
+/* mpq_cmp(u,v) -- Compare U, V. Return positive, zero, or negative
+ based on if U > V, U == V, or U < V.
+
+Copyright 1991, 1994, 1996, 2001, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+int
+mpq_cmp (const mpq_t op1, const mpq_t op2)
+{
+ mp_size_t num1_size = SIZ(NUM(op1));
+ mp_size_t den1_size = SIZ(DEN(op1));
+ mp_size_t num2_size = SIZ(NUM(op2));
+ mp_size_t den2_size = SIZ(DEN(op2));
+ mp_size_t tmp1_size, tmp2_size;
+ mp_ptr tmp1_ptr, tmp2_ptr;
+ mp_size_t num1_sign;
+ int cc;
+ TMP_DECL;
+
+ /* need canonical signs to get right result */
+ ASSERT (den1_size > 0);
+ ASSERT (den2_size > 0);
+
+ if (num1_size == 0)
+ return -num2_size;
+ if (num2_size == 0)
+ return num1_size;
+ if ((num1_size ^ num2_size) < 0) /* I.e. are the signs different? */
+ return num1_size;
+
+ num1_sign = num1_size;
+ num1_size = ABS (num1_size);
+ num2_size = ABS (num2_size);
+
+ tmp1_size = num1_size + den2_size;
+ tmp2_size = num2_size + den1_size;
+
+ /* 1. Check to see if we can tell which operand is larger by just looking at
+ the number of limbs. */
+
+ /* NUM1 x DEN2 is either TMP1_SIZE limbs or TMP1_SIZE-1 limbs.
+ Same for NUM1 x DEN1 with respect to TMP2_SIZE. */
+ if (tmp1_size > tmp2_size + 1)
+ /* NUM1 x DEN2 is surely larger in magnitude than NUM2 x DEN1. */
+ return num1_sign;
+ if (tmp2_size > tmp1_size + 1)
+ /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1. */
+ return -num1_sign;
+
+ /* 2. Same, but compare the number of significant bits. */
+ {
+ int cnt1, cnt2;
+ mp_bitcnt_t bits1, bits2;
+
+ count_leading_zeros (cnt1, PTR(NUM(op1))[num1_size - 1]);
+ count_leading_zeros (cnt2, PTR(DEN(op2))[den2_size - 1]);
+ bits1 = tmp1_size * GMP_NUMB_BITS - cnt1 - cnt2 + 2 * GMP_NAIL_BITS;
+
+ count_leading_zeros (cnt1, PTR(NUM(op2))[num2_size - 1]);
+ count_leading_zeros (cnt2, PTR(DEN(op1))[den1_size - 1]);
+ bits2 = tmp2_size * GMP_NUMB_BITS - cnt1 - cnt2 + 2 * GMP_NAIL_BITS;
+
+ if (bits1 > bits2 + 1)
+ return num1_sign;
+ if (bits2 > bits1 + 1)
+ return -num1_sign;
+ }
+
+ /* 3. Finally, cross multiply and compare. */
+
+ TMP_MARK;
+ TMP_ALLOC_LIMBS_2 (tmp1_ptr,tmp1_size, tmp2_ptr,tmp2_size);
+
+ if (num1_size >= den2_size)
+ tmp1_size -= 0 == mpn_mul (tmp1_ptr,
+ PTR(NUM(op1)), num1_size,
+ PTR(DEN(op2)), den2_size);
+ else
+ tmp1_size -= 0 == mpn_mul (tmp1_ptr,
+ PTR(DEN(op2)), den2_size,
+ PTR(NUM(op1)), num1_size);
+
+ if (num2_size >= den1_size)
+ tmp2_size -= 0 == mpn_mul (tmp2_ptr,
+ PTR(NUM(op2)), num2_size,
+ PTR(DEN(op1)), den1_size);
+ else
+ tmp2_size -= 0 == mpn_mul (tmp2_ptr,
+ PTR(DEN(op1)), den1_size,
+ PTR(NUM(op2)), num2_size);
+
+
+ cc = tmp1_size - tmp2_size != 0
+ ? tmp1_size - tmp2_size : mpn_cmp (tmp1_ptr, tmp2_ptr, tmp1_size);
+ TMP_FREE;
+ return num1_sign < 0 ? -cc : cc;
+}
diff --git a/gmp/mpq/cmp_si.c b/gmp/mpq/cmp_si.c
new file mode 100644
index 0000000000..0a31fe8c9e
--- /dev/null
+++ b/gmp/mpq/cmp_si.c
@@ -0,0 +1,67 @@
+/* _mpq_cmp_si -- compare mpq and long/ulong fraction.
+
+Copyright 2001, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Something like mpq_cmpabs_ui would be more useful for the neg/neg case,
+ and perhaps a version accepting a parameter to reverse the test, to make
+ it a tail call here. */
+
+int
+_mpq_cmp_si (mpq_srcptr q, long n, unsigned long d)
+{
+ /* need canonical sign to get right result */
+ ASSERT (SIZ(DEN(q)) > 0);
+
+ if (SIZ(NUM(q)) >= 0)
+ {
+ if (n >= 0)
+ return _mpq_cmp_ui (q, n, d); /* >=0 cmp >=0 */
+ else
+ return 1; /* >=0 cmp <0 */
+ }
+ else
+ {
+ if (n >= 0)
+ return -1; /* <0 cmp >=0 */
+ else
+ {
+ mpq_t qabs;
+ SIZ(NUM(qabs)) = ABSIZ(NUM(q));
+ PTR(NUM(qabs)) = PTR(NUM(q));
+ SIZ(DEN(qabs)) = SIZ(DEN(q));
+ PTR(DEN(qabs)) = PTR(DEN(q));
+
+ return - _mpq_cmp_ui (qabs, NEG_CAST (unsigned long, n), d); /* <0 cmp <0 */
+ }
+ }
+}
diff --git a/gmp/mpq/cmp_ui.c b/gmp/mpq/cmp_ui.c
new file mode 100644
index 0000000000..a2e2d8ca81
--- /dev/null
+++ b/gmp/mpq/cmp_ui.c
@@ -0,0 +1,100 @@
+/* mpq_cmp_ui(u,vn,vd) -- Compare U with Vn/Vd. Return positive, zero, or
+ negative based on if U > V, U == V, or U < V. Vn and Vd may have
+ common factors.
+
+Copyright 1993, 1994, 1996, 2000-2003, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+_mpq_cmp_ui (const mpq_t op1, unsigned long int num2, unsigned long int den2)
+{
+ mp_size_t num1_size = SIZ(NUM(op1));
+ mp_size_t den1_size = SIZ(DEN(op1));
+ mp_size_t tmp1_size, tmp2_size;
+ mp_ptr tmp1_ptr, tmp2_ptr;
+ mp_limb_t cy_limb;
+ int cc;
+ TMP_DECL;
+
+#if GMP_NAIL_BITS != 0
+ if ((num2 | den2) > GMP_NUMB_MAX)
+ {
+ mpq_t op2;
+ mpq_init (op2);
+ mpz_set_ui (mpq_numref (op2), num2);
+ mpz_set_ui (mpq_denref (op2), den2);
+ cc = mpq_cmp (op1, op2);
+ mpq_clear (op2);
+ return cc;
+ }
+#endif
+
+ /* need canonical sign to get right result */
+ ASSERT (den1_size > 0);
+
+ if (UNLIKELY (den2 == 0))
+ DIVIDE_BY_ZERO;
+
+ if (num1_size == 0)
+ return -(num2 != 0);
+ if (num1_size < 0)
+ return num1_size;
+ if (num2 == 0)
+ return num1_size;
+
+ /* NUM1 x DEN2 is either TMP1_SIZE limbs or TMP1_SIZE-1 limbs.
+ Same for NUM1 x DEN1 with respect to TMP2_SIZE. */
+ if (num1_size > den1_size + 1)
+ /* NUM1 x DEN2 is surely larger in magnitude than NUM2 x DEN1. */
+ return num1_size;
+ if (den1_size > num1_size + 1)
+ /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1. */
+ return -num1_size;
+
+ TMP_MARK;
+ tmp1_ptr = TMP_ALLOC_LIMBS (num1_size + 1);
+ tmp2_ptr = TMP_ALLOC_LIMBS (den1_size + 1);
+
+ cy_limb = mpn_mul_1 (tmp1_ptr, PTR(NUM(op1)), num1_size,
+ (mp_limb_t) den2);
+ tmp1_ptr[num1_size] = cy_limb;
+ tmp1_size = num1_size + (cy_limb != 0);
+
+ cy_limb = mpn_mul_1 (tmp2_ptr, PTR(DEN(op1)), den1_size,
+ (mp_limb_t) num2);
+ tmp2_ptr[den1_size] = cy_limb;
+ tmp2_size = den1_size + (cy_limb != 0);
+
+ cc = tmp1_size - tmp2_size != 0
+ ? tmp1_size - tmp2_size : mpn_cmp (tmp1_ptr, tmp2_ptr, tmp1_size);
+ TMP_FREE;
+ return cc;
+}
diff --git a/gmp/mpq/div.c b/gmp/mpq/div.c
new file mode 100644
index 0000000000..7d91e0998a
--- /dev/null
+++ b/gmp/mpq/div.c
@@ -0,0 +1,115 @@
+/* mpq_div -- divide two rational numbers.
+
+Copyright 1991, 1994-1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpq_div (mpq_ptr quot, mpq_srcptr op1, mpq_srcptr op2)
+{
+ mpz_t gcd1, gcd2;
+ mpz_t tmp1, tmp2;
+ mpz_t numtmp;
+ mp_size_t op1_num_size;
+ mp_size_t op1_den_size;
+ mp_size_t op2_num_size;
+ mp_size_t op2_den_size;
+ mp_size_t alloc;
+ TMP_DECL;
+
+ op2_num_size = ABSIZ(NUM(op2));
+
+ if (UNLIKELY (op2_num_size == 0))
+ DIVIDE_BY_ZERO;
+
+ op1_num_size = ABSIZ(NUM(op1));
+
+ if (op1_num_size == 0)
+ {
+ /* We special case this to simplify allocation logic; gcd(0,x) = x
+ is a singular case for the allocations. */
+ SIZ(NUM(quot)) = 0;
+ PTR(DEN(quot))[0] = 1;
+ SIZ(DEN(quot)) = 1;
+ return;
+ }
+
+ op2_den_size = SIZ(DEN(op2));
+ op1_den_size = SIZ(DEN(op1));
+
+ TMP_MARK;
+
+ alloc = MIN (op1_num_size, op2_num_size);
+ MPZ_TMP_INIT (gcd1, alloc);
+
+ alloc = MIN (op1_den_size, op2_den_size);
+ MPZ_TMP_INIT (gcd2, alloc);
+
+ alloc = MAX (op1_num_size, op2_num_size);
+ MPZ_TMP_INIT (tmp1, alloc);
+
+ alloc = MAX (op1_den_size, op2_den_size);
+ MPZ_TMP_INIT (tmp2, alloc);
+
+ alloc = op1_num_size + op2_den_size;
+ MPZ_TMP_INIT (numtmp, alloc);
+
+ /* QUOT might be identical to either operand, so don't store the result there
+ until we are finished with the input operands. We can overwrite the
+ numerator of QUOT when we are finished with the numerators of OP1 and
+ OP2. */
+
+ mpz_gcd (gcd1, NUM(op1), NUM(op2));
+ mpz_gcd (gcd2, DEN(op2), DEN(op1));
+
+ mpz_divexact_gcd (tmp1, NUM(op1), gcd1);
+ mpz_divexact_gcd (tmp2, DEN(op2), gcd2);
+
+ mpz_mul (numtmp, tmp1, tmp2);
+
+ mpz_divexact_gcd (tmp1, NUM(op2), gcd1);
+ mpz_divexact_gcd (tmp2, DEN(op1), gcd2);
+
+ mpz_mul (DEN(quot), tmp1, tmp2);
+
+ /* We needed to go via NUMTMP to take care of QUOT being the same as OP2.
+ Now move NUMTMP to QUOT->_mp_num. */
+ mpz_set (NUM(quot), numtmp);
+
+ /* Keep the denominator positive. */
+ if (SIZ(DEN(quot)) < 0)
+ {
+ SIZ(DEN(quot)) = -SIZ(DEN(quot));
+ SIZ(NUM(quot)) = -SIZ(NUM(quot));
+ }
+
+ TMP_FREE;
+}
diff --git a/gmp/mpq/equal.c b/gmp/mpq/equal.c
new file mode 100644
index 0000000000..500c2d802e
--- /dev/null
+++ b/gmp/mpq/equal.c
@@ -0,0 +1,69 @@
+/* mpq_equal(u,v) -- Compare U, V. Return non-zero if they are equal, zero
+ if they are non-equal.
+
+Copyright 1996, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpq_equal (mpq_srcptr op1, mpq_srcptr op2) __GMP_NOTHROW
+{
+ mp_size_t num1_size, num2_size, den1_size, den2_size, i;
+ mp_srcptr num1_ptr, num2_ptr, den1_ptr, den2_ptr;
+
+ /* need fully canonical for correct results */
+ ASSERT_MPQ_CANONICAL (op1);
+ ASSERT_MPQ_CANONICAL (op2);
+
+ num1_size = SIZ(NUM(op1));
+ num2_size = SIZ(NUM(op2));
+ if (num1_size != num2_size)
+ return 0;
+
+ num1_ptr = PTR(NUM(op1));
+ num2_ptr = PTR(NUM(op2));
+ num1_size = ABS (num1_size);
+ for (i = 0; i < num1_size; i++)
+ if (num1_ptr[i] != num2_ptr[i])
+ return 0;
+
+ den1_size = SIZ(DEN(op1));
+ den2_size = SIZ(DEN(op2));
+ if (den1_size != den2_size)
+ return 0;
+
+ den1_ptr = PTR(DEN(op1));
+ den2_ptr = PTR(DEN(op2));
+ for (i = 0; i < den1_size; i++)
+ if (den1_ptr[i] != den2_ptr[i])
+ return 0;
+
+ return 1;
+}
diff --git a/gmp/mpq/get_d.c b/gmp/mpq/get_d.c
new file mode 100644
index 0000000000..6318e22293
--- /dev/null
+++ b/gmp/mpq/get_d.c
@@ -0,0 +1,175 @@
+/* double mpq_get_d (mpq_t src) -- mpq to double, rounding towards zero.
+
+Copyright 1995, 1996, 2001-2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* All that's needed is to get the high 53 bits of the quotient num/den,
+ rounded towards zero. More than 53 bits is fine, any excess is ignored
+ by mpn_get_d.
+
+ N_QLIMBS is how many quotient limbs we need to satisfy the mantissa of a
+ double, assuming the highest of those limbs is non-zero. The target
+ qsize for mpn_tdiv_qr is then 1 more than this, since that function may
+ give a zero in the high limb (and non-zero in the second highest).
+
+ The use of 8*sizeof(double) in N_QLIMBS is an overestimate of the
+ mantissa bits, but it gets the same result as the true value (53 or 48 or
+ whatever) when rounded up to a multiple of GMP_NUMB_BITS, for non-nails.
+
+ Enhancements:
+
+ Use the true mantissa size in the N_QLIMBS formula, to save a divide step
+ in nails.
+
+ Examine the high limbs of num and den to see if the highest 1 bit of the
+ quotient will fall high enough that just N_QLIMBS-1 limbs is enough to
+ get the necessary bits, thereby saving a division step.
+
+ Bit shift either num or den to arrange for the above condition on the
+ high 1 bit of the quotient, to save a division step always. A shift to
+ save a division step is definitely worthwhile with mpn_tdiv_qr, though we
+ may want to reassess this on big num/den when a quotient-only division
+ exists.
+
+ Maybe we could estimate the final exponent using nsize-dsize (and
+ possibly the high limbs of num and den), so as to detect overflow and
+ return infinity or zero quickly. Overflow is never very helpful to an
+ application, and can therefore probably be regarded as abnormal, but we
+ may still like to optimize it if the conditions are easy. (This would
+ only be for float formats we know, unknown formats are not important and
+ can be left to mpn_get_d.)
+
+ Future:
+
+ If/when mpn_tdiv_qr supports its qxn parameter we can use that instead of
+ padding n with zeros in temporary space.
+
+ If/when a quotient-only division exists it can be used here immediately.
+ remp is only to satisfy mpn_tdiv_qr, the remainder is not used.
+
+ Alternatives:
+
+ An alternative algorithm, that may be faster:
+ 0. Let n be somewhat larger than the number of significant bits in a double.
+ 1. Extract the most significant n bits of the denominator, and an equal
+ number of bits from the numerator.
+ 2. Interpret the extracted numbers as integers, call them a and b
+ respectively, and develop n bits of the fractions ((a + 1) / b) and
+ (a / (b + 1)) using mpn_divrem.
+ 3. If the computed values are identical UP TO THE POSITION WE CARE ABOUT,
+ we are done. If they are different, repeat the algorithm from step 1,
+ but first let n = n * 2.
+ 4. If we end up using all bits from the numerator and denominator, fall
+ back to a plain division.
+ 5. Just to make life harder, The computation of a + 1 and b + 1 above
+ might give carry-out... Needs special handling. It might work to
+ subtract 1 in both cases instead.
+
+ Not certain if this approach would be faster than a quotient-only
+ division. Presumably such optimizations are the sort of thing we would
+ like to have helping everywhere that uses a quotient-only division. */
+
+double
+mpq_get_d (const mpq_t src)
+{
+ double res;
+ mp_srcptr np, dp;
+ mp_ptr remp, tp;
+ mp_size_t nsize = SIZ(NUM(src));
+ mp_size_t dsize = SIZ(DEN(src));
+ mp_size_t qsize, prospective_qsize, zeros, chop, tsize;
+ mp_size_t sign_quotient = nsize;
+ long exp;
+#define N_QLIMBS (1 + (sizeof (double) + GMP_LIMB_BYTES-1) / GMP_LIMB_BYTES)
+ mp_limb_t qarr[N_QLIMBS + 1];
+ mp_ptr qp = qarr;
+ TMP_DECL;
+
+ ASSERT (dsize > 0); /* canonical src */
+
+ /* mpn_get_d below requires a non-zero operand */
+ if (UNLIKELY (nsize == 0))
+ return 0.0;
+
+ TMP_MARK;
+ nsize = ABS (nsize);
+ dsize = ABS (dsize);
+ np = PTR(NUM(src));
+ dp = PTR(DEN(src));
+
+ prospective_qsize = nsize - dsize + 1; /* from using given n,d */
+ qsize = N_QLIMBS + 1; /* desired qsize */
+
+ zeros = qsize - prospective_qsize; /* padding n to get qsize */
+ exp = (long) -zeros * GMP_NUMB_BITS; /* relative to low of qp */
+
+ chop = MAX (-zeros, 0); /* negative zeros means shorten n */
+ np += chop;
+ nsize -= chop;
+ zeros += chop; /* now zeros >= 0 */
+
+ tsize = nsize + zeros; /* size for possible copy of n */
+
+ if (WANT_TMP_DEBUG)
+ {
+ /* separate blocks, for malloc debugging */
+ remp = TMP_ALLOC_LIMBS (dsize);
+ tp = (zeros > 0 ? TMP_ALLOC_LIMBS (tsize) : NULL);
+ }
+ else
+ {
+ /* one block with conditionalized size, for efficiency */
+ remp = TMP_ALLOC_LIMBS (dsize + (zeros > 0 ? tsize : 0));
+ tp = remp + dsize;
+ }
+
+ /* zero extend n into temporary space, if necessary */
+ if (zeros > 0)
+ {
+ MPN_ZERO (tp, zeros);
+ MPN_COPY (tp+zeros, np, nsize);
+ np = tp;
+ nsize = tsize;
+ }
+
+ ASSERT (qsize == nsize - dsize + 1);
+ mpn_tdiv_qr (qp, remp, (mp_size_t) 0, np, nsize, dp, dsize);
+
+ /* strip possible zero high limb */
+ qsize -= (qp[qsize-1] == 0);
+
+ res = mpn_get_d (qp, qsize, sign_quotient, exp);
+ TMP_FREE;
+ return res;
+}
diff --git a/gmp/mpq/get_den.c b/gmp/mpq/get_den.c
new file mode 100644
index 0000000000..48a385c817
--- /dev/null
+++ b/gmp/mpq/get_den.c
@@ -0,0 +1,43 @@
+/* mpq_get_den(den,rat_src) -- Set DEN to the denominator of RAT_SRC.
+
+Copyright 1991, 1994, 1995, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_get_den (mpz_ptr den, mpq_srcptr src)
+{
+ mp_size_t size = SIZ(DEN(src));
+ mp_ptr dp;
+
+ dp = MPZ_NEWALLOC (den, size);
+ SIZ(den) = size;
+ MPN_COPY (dp, PTR(DEN(src)), size);
+}
diff --git a/gmp/mpq/get_num.c b/gmp/mpq/get_num.c
new file mode 100644
index 0000000000..cb464ccb94
--- /dev/null
+++ b/gmp/mpq/get_num.c
@@ -0,0 +1,45 @@
+ /* mpq_get_num(num,rat_src) -- Set NUM to the numerator of RAT_SRC.
+
+Copyright 1991, 1994, 1995, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_get_num (mpz_ptr num, mpq_srcptr src)
+{
+ mp_size_t size = SIZ(NUM(src));
+ mp_size_t abs_size = ABS (size);
+ mp_ptr dp;
+
+ dp = MPZ_NEWALLOC (num, abs_size);
+ SIZ(num) = size;
+
+ MPN_COPY (dp, PTR(NUM(src)), abs_size);
+}
diff --git a/gmp/mpq/get_str.c b/gmp/mpq/get_str.c
new file mode 100644
index 0000000000..8fa0de1cd7
--- /dev/null
+++ b/gmp/mpq/get_str.c
@@ -0,0 +1,76 @@
+/* mpq_get_str -- mpq to string conversion.
+
+Copyright 2001, 2002, 2006, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <string.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+char *
+mpq_get_str (char *str, int base, mpq_srcptr q)
+{
+ size_t str_alloc, len;
+
+ if (base > 62 || base < -36)
+ return NULL;
+
+ str_alloc = 0;
+ if (str == NULL)
+ {
+ /* This is an overestimate since we don't bother checking how much of
+ the high limbs of num and den are used. +2 for rounding up the
+ chars per bit of num and den. +3 for sign, slash and '\0'. */
+ DIGITS_IN_BASE_PER_LIMB (str_alloc, ABSIZ(NUM(q)) + SIZ(DEN(q)), ABS(base));
+ str_alloc += 6;
+
+ str = (char *) (*__gmp_allocate_func) (str_alloc);
+ }
+
+ mpz_get_str (str, base, mpq_numref(q));
+ len = strlen (str);
+ if (! MPZ_EQUAL_1_P (mpq_denref (q)))
+ {
+ str[len++] = '/';
+ mpz_get_str (str+len, base, mpq_denref(q));
+ len += strlen (str+len);
+ }
+
+ ASSERT (len == strlen(str));
+ ASSERT (str_alloc == 0 || len+1 <= str_alloc);
+ ASSERT (len+1 <= /* size recommended to applications */
+ mpz_sizeinbase (mpq_numref(q), ABS(base)) +
+ mpz_sizeinbase (mpq_denref(q), ABS(base)) + 3);
+
+ if (str_alloc != 0)
+ __GMP_REALLOCATE_FUNC_MAYBE_TYPE (str, str_alloc, len+1, char);
+
+ return str;
+}
diff --git a/gmp/mpq/init.c b/gmp/mpq/init.c
new file mode 100644
index 0000000000..0f526ef31d
--- /dev/null
+++ b/gmp/mpq/init.c
@@ -0,0 +1,49 @@
+/* mpq_init -- Make a new rational number with value 0/1.
+
+Copyright 1991, 1994, 1995, 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_init (mpq_t x)
+{
+ ALLOC(NUM(x)) = 1;
+ PTR(NUM(x)) = (mp_ptr) (*__gmp_allocate_func) (GMP_LIMB_BYTES);
+ SIZ(NUM(x)) = 0;
+ ALLOC(DEN(x)) = 1;
+ PTR(DEN(x)) = (mp_ptr) (*__gmp_allocate_func) (GMP_LIMB_BYTES);
+ PTR(DEN(x))[0] = 1;
+ SIZ(DEN(x)) = 1;
+
+#ifdef __CHECKER__
+ /* let the low limb look initialized, for the benefit of mpz_get_ui etc */
+ PTR(NUM(x))[0] = 0;
+#endif
+}
diff --git a/gmp/mpq/inits.c b/gmp/mpq/inits.c
new file mode 100644
index 0000000000..97c41656ff
--- /dev/null
+++ b/gmp/mpq/inits.c
@@ -0,0 +1,49 @@
+/* mpq_inits() -- Initialize multiple mpq_t variables and set them to 0.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_inits (mpq_ptr x, ...)
+{
+ va_list ap;
+
+ va_start (ap, x);
+
+ while (x != NULL)
+ {
+ mpq_init (x);
+ x = va_arg (ap, mpq_ptr);
+ }
+ va_end (ap);
+}
diff --git a/gmp/mpq/inp_str.c b/gmp/mpq/inp_str.c
new file mode 100644
index 0000000000..7ba95743f8
--- /dev/null
+++ b/gmp/mpq/inp_str.c
@@ -0,0 +1,76 @@
+/* mpq_inp_str -- read an mpq from a FILE.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+size_t
+mpq_inp_str (mpq_ptr q, FILE *fp, int base)
+{
+ size_t nread;
+ int c;
+
+ if (fp == NULL)
+ fp = stdin;
+
+ SIZ(DEN(q)) = 1;
+ PTR(DEN(q))[0] = 1;
+
+ nread = mpz_inp_str (mpq_numref(q), fp, base);
+ if (nread == 0)
+ return 0;
+
+ c = getc (fp);
+ nread++;
+
+ if (c == '/')
+ {
+ c = getc (fp);
+ nread++;
+
+ nread = mpz_inp_str_nowhite (mpq_denref(q), fp, base, c, nread);
+ if (nread == 0)
+ {
+ SIZ(NUM(q)) = 0;
+ SIZ(DEN(q)) = 1;
+ PTR(DEN(q))[0] = 1;
+ }
+ }
+ else
+ {
+ ungetc (c, fp);
+ nread--;
+ }
+
+ return nread;
+}
diff --git a/gmp/mpq/inv.c b/gmp/mpq/inv.c
new file mode 100644
index 0000000000..bd703d4860
--- /dev/null
+++ b/gmp/mpq/inv.c
@@ -0,0 +1,71 @@
+/* mpq_inv(dest,src) -- invert a rational number, i.e. set DEST to SRC
+ with the numerator and denominator swapped.
+
+Copyright 1991, 1994, 1995, 2000, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_inv (mpq_ptr dest, mpq_srcptr src)
+{
+ mp_size_t num_size = SIZ(NUM(src));
+ mp_size_t den_size = SIZ(DEN(src));
+
+ if (num_size < 0)
+ {
+ num_size = -num_size;
+ den_size = -den_size;
+ }
+ else if (UNLIKELY (num_size == 0))
+ DIVIDE_BY_ZERO;
+
+ SIZ(DEN(dest)) = num_size;
+ SIZ(NUM(dest)) = den_size;
+
+ /* If dest == src we may just swap the numerator and denominator;
+ we ensured that the new denominator is positive. */
+
+ if (dest == src)
+ {
+ MP_PTR_SWAP (PTR(NUM(dest)), PTR(DEN(dest)));
+ MP_SIZE_T_SWAP (ALLOC(NUM(dest)), ALLOC(DEN(dest)));
+ }
+ else
+ {
+ mp_ptr dp;
+
+ den_size = ABS (den_size);
+ dp = MPZ_NEWALLOC (NUM(dest), den_size);
+ MPN_COPY (dp, PTR(DEN(src)), den_size);
+
+ dp = MPZ_NEWALLOC (DEN(dest), num_size);
+ MPN_COPY (dp, PTR(NUM(src)), num_size);
+ }
+}
diff --git a/gmp/mpq/md_2exp.c b/gmp/mpq/md_2exp.c
new file mode 100644
index 0000000000..a2a7e1e2fb
--- /dev/null
+++ b/gmp/mpq/md_2exp.c
@@ -0,0 +1,111 @@
+/* mpq_mul_2exp, mpq_div_2exp - multiply or divide by 2^N */
+
+/*
+Copyright 2000, 2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* The multiplier/divisor "n", representing 2^n, is applied by right shifting
+ "r" until it's odd (if it isn't already), and left shifting "l" for the
+ rest. */
+
+static void
+mord_2exp (mpz_ptr ldst, mpz_ptr rdst, mpz_srcptr lsrc, mpz_srcptr rsrc,
+ mp_bitcnt_t n)
+{
+ mp_size_t rsrc_size = SIZ(rsrc);
+ mp_size_t len = ABS (rsrc_size);
+ mp_ptr rsrc_ptr = PTR(rsrc);
+ mp_ptr p, rdst_ptr;
+ mp_limb_t plow;
+
+ p = rsrc_ptr;
+ plow = *p;
+ while (n >= GMP_NUMB_BITS && plow == 0)
+ {
+ n -= GMP_NUMB_BITS;
+ p++;
+ plow = *p;
+ }
+
+ /* no realloc here if rsrc==rdst, so p and rsrc_ptr remain valid */
+ len -= (p - rsrc_ptr);
+ rdst_ptr = MPZ_REALLOC (rdst, len);
+
+ if ((plow & 1) || n == 0)
+ {
+ /* need INCR when src==dst */
+ if (p != rdst_ptr)
+ MPN_COPY_INCR (rdst_ptr, p, len);
+ }
+ else
+ {
+ unsigned long shift;
+ if (plow == 0)
+ shift = n;
+ else
+ {
+ count_trailing_zeros (shift, plow);
+ shift = MIN (shift, n);
+ }
+ mpn_rshift (rdst_ptr, p, len, shift);
+ len -= (rdst_ptr[len-1] == 0);
+ n -= shift;
+ }
+ SIZ(rdst) = (rsrc_size >= 0) ? len : -len;
+
+ if (n)
+ mpz_mul_2exp (ldst, lsrc, n);
+ else if (ldst != lsrc)
+ mpz_set (ldst, lsrc);
+}
+
+
+void
+mpq_mul_2exp (mpq_ptr dst, mpq_srcptr src, mp_bitcnt_t n)
+{
+ mord_2exp (NUM(dst), DEN(dst), NUM(src), DEN(src), n);
+}
+
+void
+mpq_div_2exp (mpq_ptr dst, mpq_srcptr src, mp_bitcnt_t n)
+{
+ if (SIZ(NUM(src)) == 0)
+ {
+ SIZ(NUM(dst)) = 0;
+ SIZ(DEN(dst)) = 1;
+ PTR(DEN(dst))[0] = 1;
+ return;
+ }
+
+ mord_2exp (DEN(dst), NUM(dst), DEN(src), NUM(src), n);
+}
diff --git a/gmp/mpq/mul.c b/gmp/mpq/mul.c
new file mode 100644
index 0000000000..49d618f3bc
--- /dev/null
+++ b/gmp/mpq/mul.c
@@ -0,0 +1,103 @@
+/* mpq_mul -- multiply two rational numbers.
+
+Copyright 1991, 1994-1996, 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpq_mul (mpq_ptr prod, mpq_srcptr op1, mpq_srcptr op2)
+{
+ mpz_t gcd1, gcd2;
+ mpz_t tmp1, tmp2;
+ mp_size_t op1_num_size;
+ mp_size_t op1_den_size;
+ mp_size_t op2_num_size;
+ mp_size_t op2_den_size;
+ mp_size_t alloc;
+ TMP_DECL;
+
+ if (op1 == op2)
+ {
+ /* No need for any GCDs when squaring. */
+ mpz_mul (mpq_numref (prod), mpq_numref (op1), mpq_numref (op1));
+ mpz_mul (mpq_denref (prod), mpq_denref (op1), mpq_denref (op1));
+ return;
+ }
+
+ op1_num_size = ABSIZ(NUM(op1));
+ op1_den_size = SIZ(DEN(op1));
+ op2_num_size = ABSIZ(NUM(op2));
+ op2_den_size = SIZ(DEN(op2));
+
+ if (op1_num_size == 0 || op2_num_size == 0)
+ {
+ /* We special case this to simplify allocation logic; gcd(0,x) = x
+ is a singular case for the allocations. */
+ SIZ(NUM(prod)) = 0;
+ PTR(DEN(prod))[0] = 1;
+ SIZ(DEN(prod)) = 1;
+ return;
+ }
+
+ TMP_MARK;
+
+ alloc = MIN (op1_num_size, op2_den_size);
+ MPZ_TMP_INIT (gcd1, alloc);
+
+ alloc = MIN (op2_num_size, op1_den_size);
+ MPZ_TMP_INIT (gcd2, alloc);
+
+ alloc = MAX (op1_num_size, op2_den_size);
+ MPZ_TMP_INIT (tmp1, alloc);
+
+ alloc = MAX (op2_num_size, op1_den_size);
+ MPZ_TMP_INIT (tmp2, alloc);
+
+ /* PROD might be identical to either operand, so don't store the result there
+ until we are finished with the input operands. We can overwrite the
+ numerator of PROD when we are finished with the numerators of OP1 and
+ OP2. */
+
+ mpz_gcd (gcd1, NUM(op1), DEN(op2));
+ mpz_gcd (gcd2, NUM(op2), DEN(op1));
+
+ mpz_divexact_gcd (tmp1, NUM(op1), gcd1);
+ mpz_divexact_gcd (tmp2, NUM(op2), gcd2);
+
+ mpz_mul (NUM(prod), tmp1, tmp2);
+
+ mpz_divexact_gcd (tmp1, DEN(op2), gcd1);
+ mpz_divexact_gcd (tmp2, DEN(op1), gcd2);
+
+ mpz_mul (DEN(prod), tmp1, tmp2);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpq/neg.c b/gmp/mpq/neg.c
new file mode 100644
index 0000000000..054e21ebe3
--- /dev/null
+++ b/gmp/mpq/neg.c
@@ -0,0 +1,58 @@
+/* mpq_neg -- negate a rational.
+
+Copyright 2000, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpq_neg 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpq_neg (mpq_ptr dst, mpq_srcptr src)
+{
+ mp_size_t num_size = SIZ(NUM(src));
+
+ if (src != dst)
+ {
+ mp_size_t size;
+ mp_ptr dp;
+
+ size = ABS(num_size);
+ dp = MPZ_NEWALLOC (NUM(dst), size);
+ MPN_COPY (dp, PTR(NUM(src)), size);
+
+ size = SIZ(DEN(src));
+ dp = MPZ_NEWALLOC (DEN(dst), size);
+ SIZ(DEN(dst)) = size;
+ MPN_COPY (dp, PTR(DEN(src)), size);
+ }
+
+ SIZ(NUM(dst)) = -num_size;
+}
diff --git a/gmp/mpq/out_str.c b/gmp/mpq/out_str.c
new file mode 100644
index 0000000000..c2bc053b21
--- /dev/null
+++ b/gmp/mpq/out_str.c
@@ -0,0 +1,54 @@
+/* mpq_out_str(stream,base,integer) */
+
+/*
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+size_t
+mpq_out_str (FILE *stream, int base, mpq_srcptr q)
+{
+ size_t written;
+
+ if (stream == NULL)
+ stream = stdout;
+
+ written = mpz_out_str (stream, base, mpq_numref (q));
+
+ if (mpz_cmp_ui (mpq_denref (q), 1) != 0)
+ {
+ putc ('/', stream);
+ written += 1 + mpz_out_str (stream, base, mpq_denref (q));
+ }
+
+ return ferror (stream) ? 0 : written;
+}
diff --git a/gmp/mpq/set.c b/gmp/mpq/set.c
new file mode 100644
index 0000000000..fb7bfad49c
--- /dev/null
+++ b/gmp/mpq/set.c
@@ -0,0 +1,51 @@
+/* mpq_set(dest,src) -- Set DEST to SRC.
+
+Copyright 1991, 1994, 1995, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_set (mpq_ptr dest, mpq_srcptr src)
+{
+ mp_size_t num_size, den_size;
+ mp_size_t abs_num_size;
+ mp_ptr dp;
+
+ num_size = SIZ(NUM(src));
+ abs_num_size = ABS (num_size);
+ dp = MPZ_NEWALLOC (NUM(dest), abs_num_size);
+ SIZ(NUM(dest)) = num_size;
+ MPN_COPY (dp, PTR(NUM(src)), abs_num_size);
+
+ den_size = SIZ(DEN(src));
+ dp = MPZ_NEWALLOC (DEN(dest), den_size);
+ SIZ(DEN(dest)) = den_size;
+ MPN_COPY (dp, PTR(DEN(src)), den_size);
+}
diff --git a/gmp/mpq/set_d.c b/gmp/mpq/set_d.c
new file mode 100644
index 0000000000..308677db40
--- /dev/null
+++ b/gmp/mpq/set_d.c
@@ -0,0 +1,166 @@
+/* mpq_set_d(mpq_t q, double d) -- Set q to d without rounding.
+
+Copyright 2000, 2002, 2003, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if HAVE_FLOAT_H
+#include <float.h> /* for DBL_MAX */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#if LIMBS_PER_DOUBLE > 4
+ choke me
+#endif
+
+void
+mpq_set_d (mpq_ptr dest, double d)
+{
+ int negative;
+ mp_exp_t exp;
+ mp_limb_t tp[LIMBS_PER_DOUBLE];
+ mp_ptr np, dp;
+ mp_size_t nn, dn;
+ int c;
+
+ DOUBLE_NAN_INF_ACTION (d,
+ __gmp_invalid_operation (),
+ __gmp_invalid_operation ());
+
+ negative = d < 0;
+ d = ABS (d);
+
+ exp = __gmp_extract_double (tp, d);
+
+ /* There are two main version of the conversion. The `then' arm handles
+ numbers with a fractional part, while the `else' arm handles integers. */
+#if LIMBS_PER_DOUBLE == 4
+ if (exp <= 1 || (exp == 2 && (tp[0] | tp[1]) != 0))
+#endif
+#if LIMBS_PER_DOUBLE == 3
+ if (exp <= 1 || (exp == 2 && tp[0] != 0))
+#endif
+#if LIMBS_PER_DOUBLE == 2
+ if (exp <= 1)
+#endif
+ {
+ if (d == 0.0)
+ {
+ SIZ(NUM(dest)) = 0;
+ SIZ(DEN(dest)) = 1;
+ PTR(DEN(dest))[0] = 1;
+ return;
+ }
+
+ dn = -exp;
+ np = MPZ_NEWALLOC (NUM(dest), 3);
+#if LIMBS_PER_DOUBLE == 4
+ if ((tp[0] | tp[1] | tp[2]) == 0)
+ np[0] = tp[3], nn = 1;
+ else if ((tp[0] | tp[1]) == 0)
+ np[1] = tp[3], np[0] = tp[2], nn = 2;
+ else if (tp[0] == 0)
+ np[2] = tp[3], np[1] = tp[2], np[0] = tp[1], nn = 3;
+ else
+ np[3] = tp[3], np[2] = tp[2], np[1] = tp[1], np[0] = tp[0], nn = 4;
+#endif
+#if LIMBS_PER_DOUBLE == 3
+ if ((tp[0] | tp[1]) == 0)
+ np[0] = tp[2], nn = 1;
+ else if (tp[0] == 0)
+ np[1] = tp[2], np[0] = tp[1], nn = 2;
+ else
+ np[2] = tp[2], np[1] = tp[1], np[0] = tp[0], nn = 3;
+#endif
+#if LIMBS_PER_DOUBLE == 2
+ if (tp[0] == 0)
+ np[0] = tp[1], nn = 1;
+ else
+ np[1] = tp[1], np[0] = tp[0], nn = 2;
+#endif
+ dn += nn + 1;
+ ASSERT_ALWAYS (dn > 0);
+ dp = MPZ_NEWALLOC (DEN(dest), dn);
+ MPN_ZERO (dp, dn - 1);
+ dp[dn - 1] = 1;
+ count_trailing_zeros (c, np[0] | dp[0]);
+ if (c != 0)
+ {
+ mpn_rshift (np, np, nn, c);
+ nn -= np[nn - 1] == 0;
+ mpn_rshift (dp, dp, dn, c);
+ dn -= dp[dn - 1] == 0;
+ }
+ SIZ(DEN(dest)) = dn;
+ SIZ(NUM(dest)) = negative ? -nn : nn;
+ }
+ else
+ {
+ nn = exp;
+ np = MPZ_NEWALLOC (NUM(dest), nn);
+ switch (nn)
+ {
+ default:
+ MPN_ZERO (np, nn - LIMBS_PER_DOUBLE);
+ np += nn - LIMBS_PER_DOUBLE;
+ /* fall through */
+#if LIMBS_PER_DOUBLE == 2
+ case 2:
+ np[1] = tp[1], np[0] = tp[0];
+ break;
+#endif
+#if LIMBS_PER_DOUBLE == 3
+ case 3:
+ np[2] = tp[2], np[1] = tp[1], np[0] = tp[0];
+ break;
+ case 2:
+ np[1] = tp[2], np[0] = tp[1];
+ break;
+#endif
+#if LIMBS_PER_DOUBLE == 4
+ case 4:
+ np[3] = tp[3], np[2] = tp[2], np[1] = tp[1], np[0] = tp[0];
+ break;
+ case 3:
+ np[2] = tp[3], np[1] = tp[2], np[0] = tp[1];
+ break;
+ case 2:
+ np[1] = tp[3], np[0] = tp[2];
+ break;
+#endif
+ }
+ dp = PTR(DEN(dest));
+ dp[0] = 1;
+ SIZ(DEN(dest)) = 1;
+ SIZ(NUM(dest)) = negative ? -nn : nn;
+ }
+}
diff --git a/gmp/mpq/set_den.c b/gmp/mpq/set_den.c
new file mode 100644
index 0000000000..4bcb86b097
--- /dev/null
+++ b/gmp/mpq/set_den.c
@@ -0,0 +1,45 @@
+/* mpq_set_den(dest,den) -- Set the denominator of DEST from DEN.
+
+Copyright 1991, 1994-1996, 2000, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_set_den (mpq_ptr dest, mpz_srcptr den)
+{
+ mp_size_t size = SIZ (den);
+ mp_size_t abs_size = ABS (size);
+ mp_ptr dp;
+
+ dp = MPZ_NEWALLOC (DEN(dest), abs_size);
+
+ SIZ(DEN(dest)) = size;
+ MPN_COPY (dp, PTR(den), abs_size);
+}
diff --git a/gmp/mpq/set_f.c b/gmp/mpq/set_f.c
new file mode 100644
index 0000000000..7764a17f05
--- /dev/null
+++ b/gmp/mpq/set_f.c
@@ -0,0 +1,107 @@
+/* mpq_set_f -- set an mpq from an mpf.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+void
+mpq_set_f (mpq_ptr q, mpf_srcptr f)
+{
+ mp_size_t fexp = EXP(f);
+ mp_ptr fptr = PTR(f);
+ mp_size_t fsize = SIZ(f);
+ mp_size_t abs_fsize = ABS(fsize);
+ mp_limb_t flow;
+
+ if (fsize == 0)
+ {
+ /* set q=0 */
+ SIZ(NUM(q)) = 0;
+ SIZ(DEN(q)) = 1;
+ PTR(DEN(q))[0] = 1;
+ return;
+ }
+
+ /* strip low zero limbs from f */
+ flow = *fptr;
+ MPN_STRIP_LOW_ZEROS_NOT_ZERO (fptr, abs_fsize, flow);
+
+ if (fexp >= abs_fsize)
+ {
+ /* radix point is to the right of the limbs, no denominator */
+ mp_ptr num_ptr;
+
+ num_ptr = MPZ_NEWALLOC (mpq_numref (q), fexp);
+ MPN_ZERO (num_ptr, fexp - abs_fsize);
+ MPN_COPY (num_ptr + fexp - abs_fsize, fptr, abs_fsize);
+
+ SIZ(NUM(q)) = fsize >= 0 ? fexp : -fexp;
+ SIZ(DEN(q)) = 1;
+ PTR(DEN(q))[0] = 1;
+ }
+ else
+ {
+ /* radix point is within or to the left of the limbs, use denominator */
+ mp_ptr num_ptr, den_ptr;
+ mp_size_t den_size;
+
+ den_size = abs_fsize - fexp;
+ num_ptr = MPZ_NEWALLOC (mpq_numref (q), abs_fsize);
+ den_ptr = MPZ_NEWALLOC (mpq_denref (q), den_size+1);
+
+ if (flow & 1)
+ {
+ /* no powers of two to strip from numerator */
+
+ MPN_COPY (num_ptr, fptr, abs_fsize);
+ MPN_ZERO (den_ptr, den_size);
+ den_ptr[den_size] = 1;
+ }
+ else
+ {
+ /* right shift numerator, adjust denominator accordingly */
+ int shift;
+
+ den_size--;
+ count_trailing_zeros (shift, flow);
+
+ mpn_rshift (num_ptr, fptr, abs_fsize, shift);
+ abs_fsize -= (num_ptr[abs_fsize-1] == 0);
+
+ MPN_ZERO (den_ptr, den_size);
+ den_ptr[den_size] = GMP_LIMB_HIGHBIT >> (shift-1);
+ }
+
+ SIZ(NUM(q)) = fsize >= 0 ? abs_fsize : -abs_fsize;
+ SIZ(DEN(q)) = den_size + 1;
+ }
+}
diff --git a/gmp/mpq/set_num.c b/gmp/mpq/set_num.c
new file mode 100644
index 0000000000..c6b52ccaa1
--- /dev/null
+++ b/gmp/mpq/set_num.c
@@ -0,0 +1,45 @@
+/* mpq_set_num(dest,num) -- Set the numerator of DEST from NUM.
+
+Copyright 1991, 1994, 1995, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_set_num (mpq_ptr dest, mpz_srcptr num)
+{
+ mp_size_t size = SIZ (num);
+ mp_size_t abs_size = ABS (size);
+ mp_ptr dp;
+
+ dp = MPZ_NEWALLOC (NUM(dest), abs_size);
+
+ SIZ(NUM(dest)) = size;
+ MPN_COPY (dp, PTR(num), abs_size);
+}
diff --git a/gmp/mpq/set_si.c b/gmp/mpq/set_si.c
new file mode 100644
index 0000000000..0a10b3048d
--- /dev/null
+++ b/gmp/mpq/set_si.c
@@ -0,0 +1,65 @@
+/* mpq_set_si(dest,ulong_num,ulong_den) -- Set DEST to the rational number
+ ULONG_NUM/ULONG_DEN.
+
+Copyright 1991, 1994, 1995, 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_set_si (mpq_t dest, signed long int num, unsigned long int den)
+{
+ unsigned long int abs_num;
+
+ if (GMP_NUMB_BITS < BITS_PER_ULONG)
+ {
+ if (num == 0) /* Canonicalize 0/d to 0/1. */
+ den = 1;
+ mpz_set_si (mpq_numref (dest), num);
+ mpz_set_ui (mpq_denref (dest), den);
+ return;
+ }
+
+ abs_num = ABS_CAST (unsigned long, num);
+
+ if (num == 0)
+ {
+ /* Canonicalize 0/d to 0/1. */
+ den = 1;
+ SIZ(NUM(dest)) = 0;
+ }
+ else
+ {
+ PTR(NUM(dest))[0] = abs_num;
+ SIZ(NUM(dest)) = num > 0 ? 1 : -1;
+ }
+
+ PTR(DEN(dest))[0] = den;
+ SIZ(DEN(dest)) = (den != 0);
+}
diff --git a/gmp/mpq/set_str.c b/gmp/mpq/set_str.c
new file mode 100644
index 0000000000..930fe5576c
--- /dev/null
+++ b/gmp/mpq/set_str.c
@@ -0,0 +1,69 @@
+/* mpq_set_str -- string to mpq conversion.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <string.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* FIXME: Would like an mpz_set_mem (or similar) accepting a pointer and
+ length so we wouldn't have to copy the numerator just to null-terminate
+ it. */
+
+int
+mpq_set_str (mpq_ptr q, const char *str, int base)
+{
+ const char *slash;
+ char *num;
+ size_t numlen;
+ int ret;
+
+ slash = strchr (str, '/');
+ if (slash == NULL)
+ {
+ SIZ(DEN(q)) = 1;
+ PTR(DEN(q))[0] = 1;
+
+ return mpz_set_str (mpq_numref(q), str, base);
+ }
+
+ numlen = slash - str;
+ num = __GMP_ALLOCATE_FUNC_TYPE (numlen+1, char);
+ memcpy (num, str, numlen);
+ num[numlen] = '\0';
+ ret = mpz_set_str (mpq_numref(q), num, base);
+ (*__gmp_free_func) (num, numlen+1);
+
+ if (ret != 0)
+ return ret;
+
+ return mpz_set_str (mpq_denref(q), slash+1, base);
+}
diff --git a/gmp/mpq/set_ui.c b/gmp/mpq/set_ui.c
new file mode 100644
index 0000000000..4473b30bb8
--- /dev/null
+++ b/gmp/mpq/set_ui.c
@@ -0,0 +1,61 @@
+/* mpq_set_ui(dest,ulong_num,ulong_den) -- Set DEST to the rational number
+ ULONG_NUM/ULONG_DEN.
+
+Copyright 1991, 1994, 1995, 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_set_ui (mpq_t dest, unsigned long int num, unsigned long int den)
+{
+ if (GMP_NUMB_BITS < BITS_PER_ULONG)
+ {
+ if (num == 0) /* Canonicalize 0/d to 0/1. */
+ den = 1;
+ mpz_set_ui (mpq_numref (dest), num);
+ mpz_set_ui (mpq_denref (dest), den);
+ return;
+ }
+
+ if (num == 0)
+ {
+ /* Canonicalize 0/n to 0/1. */
+ den = 1;
+ SIZ(NUM(dest)) = 0;
+ }
+ else
+ {
+ PTR(NUM(dest))[0] = num;
+ SIZ(NUM(dest)) = 1;
+ }
+
+ PTR(DEN(dest))[0] = den;
+ SIZ(DEN(dest)) = (den != 0);
+}
diff --git a/gmp/mpq/set_z.c b/gmp/mpq/set_z.c
new file mode 100644
index 0000000000..358d1ca899
--- /dev/null
+++ b/gmp/mpq/set_z.c
@@ -0,0 +1,49 @@
+/* mpq_set_z (dest,src) -- Set DEST to SRC.
+
+Copyright 1996, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_set_z (mpq_ptr dest, mpz_srcptr src)
+{
+ mp_size_t num_size;
+ mp_size_t abs_num_size;
+ mp_ptr dp;
+
+ num_size = SIZ (src);
+ abs_num_size = ABS (num_size);
+ dp = MPZ_NEWALLOC (NUM(dest), abs_num_size);
+ SIZ(NUM(dest)) = num_size;
+ MPN_COPY (dp, PTR(src), abs_num_size);
+
+ PTR(DEN(dest))[0] = 1;
+ SIZ(DEN(dest)) = 1;
+}
diff --git a/gmp/mpq/swap.c b/gmp/mpq/swap.c
new file mode 100644
index 0000000000..51fdcac7fd
--- /dev/null
+++ b/gmp/mpq/swap.c
@@ -0,0 +1,71 @@
+/* mpq_swap (U, V) -- Swap U and V.
+
+Copyright 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpq_swap (mpq_ptr u, mpq_ptr v) __GMP_NOTHROW
+{
+ mp_ptr up, vp;
+ mp_size_t usize, vsize;
+ mp_size_t ualloc, valloc;
+
+ ualloc = ALLOC(NUM(u));
+ valloc = ALLOC(NUM(v));
+ ALLOC(NUM(v)) = ualloc;
+ ALLOC(NUM(u)) = valloc;
+
+ usize = SIZ(NUM(u));
+ vsize = SIZ(NUM(v));
+ SIZ(NUM(v)) = usize;
+ SIZ(NUM(u)) = vsize;
+
+ up = PTR(NUM(u));
+ vp = PTR(NUM(v));
+ PTR(NUM(v)) = up;
+ PTR(NUM(u)) = vp;
+
+
+ ualloc = ALLOC(DEN(u));
+ valloc = ALLOC(DEN(v));
+ ALLOC(DEN(v)) = ualloc;
+ ALLOC(DEN(u)) = valloc;
+
+ usize = SIZ(DEN(u));
+ vsize = SIZ(DEN(v));
+ SIZ(DEN(v)) = usize;
+ SIZ(DEN(u)) = vsize;
+
+ up = PTR(DEN(u));
+ vp = PTR(DEN(v));
+ PTR(DEN(v)) = up;
+ PTR(DEN(u)) = vp;
+}
diff --git a/gmp/mpz/2fac_ui.c b/gmp/mpz/2fac_ui.c
new file mode 100644
index 0000000000..37e6c468bc
--- /dev/null
+++ b/gmp/mpz/2fac_ui.c
@@ -0,0 +1,100 @@
+/* mpz_2fac_ui(RESULT, N) -- Set RESULT to N!!.
+
+Contributed to the GNU project by Marco Bodrato.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \
+ do { \
+ if ((PR) > (MAX_PR)) { \
+ (VEC)[(I)++] = (PR); \
+ (PR) = (P); \
+ } else \
+ (PR) *= (P); \
+ } while (0)
+
+#define FAC_2DSC_THRESHOLD ((FAC_DSC_THRESHOLD << 1) | (FAC_DSC_THRESHOLD & 1))
+#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_2DSC_THRESHOLD-1)+1))
+
+/* Computes n!!, the 2-multi-factorial of n. (aka double-factorial or semi-factorial)
+ WARNING: it assumes that n fits in a limb!
+ */
+void
+mpz_2fac_ui (mpz_ptr x, unsigned long n)
+{
+ ASSERT (n <= GMP_NUMB_MAX);
+
+ if ((n & 1) == 0) { /* n is even, n = 2k, (2k)!! = k! 2^k */
+ mp_limb_t count;
+
+ if ((n <= TABLE_LIMIT_2N_MINUS_POPC_2N) & (n != 0))
+ count = __gmp_fac2cnt_table[n / 2 - 1];
+ else
+ {
+ popc_limb (count, n); /* popc(n) == popc(k) */
+ count = n - count; /* n - popc(n) == k + k - popc(k) */
+ }
+ mpz_oddfac_1 (x, n >> 1, 0);
+ mpz_mul_2exp (x, x, count);
+ } else { /* n is odd */
+ if (n <= ODD_DOUBLEFACTORIAL_TABLE_LIMIT) {
+ PTR (x)[0] = __gmp_odd2fac_table[n >> 1];
+ SIZ (x) = 1;
+ } else if (BELOW_THRESHOLD (n, FAC_2DSC_THRESHOLD)) { /* odd basecase, */
+ mp_limb_t *factors, prod, max_prod, j;
+ TMP_SDECL;
+
+ /* FIXME: we might alloc a fixed amount 1+FAC_2DSC_THRESHOLD/FACTORS_PER_LIMB */
+ TMP_SMARK;
+ factors = TMP_SALLOC_LIMBS (1 + n / (2 * FACTORS_PER_LIMB));
+
+ factors[0] = ODD_DOUBLEFACTORIAL_TABLE_MAX;
+ j = 1;
+ prod = n;
+
+ max_prod = GMP_NUMB_MAX / FAC_2DSC_THRESHOLD;
+ while ((n -= 2) > ODD_DOUBLEFACTORIAL_TABLE_LIMIT)
+ FACTOR_LIST_STORE (n, prod, max_prod, factors, j);
+
+ factors[j++] = prod;
+ mpz_prodlimbs (x, factors, j);
+
+ TMP_SFREE;
+ } else { /* for the asymptotically fast odd case, let oddfac do the job. */
+ mpz_oddfac_1 (x, n, 1);
+ }
+ }
+}
+
+#undef FACTORS_PER_LIMB
+#undef FACTOR_LIST_STORE
+#undef FAC_2DSC_THRESHOLD
diff --git a/gmp/mpz/Makefile.am b/gmp/mpz/Makefile.am
new file mode 100644
index 0000000000..1aac41b992
--- /dev/null
+++ b/gmp/mpz/Makefile.am
@@ -0,0 +1,67 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 1996, 1998-2003, 2012 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+
+noinst_LTLIBRARIES = libmpz.la
+libmpz_la_SOURCES = aors.h aors_ui.h fits_s.h mul_i.h \
+ 2fac_ui.c \
+ add.c add_ui.c abs.c aorsmul.c aorsmul_i.c and.c array_init.c \
+ bin_ui.c bin_uiui.c cdiv_q.c \
+ cdiv_q_ui.c cdiv_qr.c cdiv_qr_ui.c cdiv_r.c cdiv_r_ui.c cdiv_ui.c \
+ cfdiv_q_2exp.c cfdiv_r_2exp.c \
+ clear.c clears.c clrbit.c \
+ cmp.c cmp_d.c cmp_si.c cmp_ui.c cmpabs.c cmpabs_d.c cmpabs_ui.c \
+ com.c combit.c \
+ cong.c cong_2exp.c cong_ui.c \
+ divexact.c divegcd.c dive_ui.c divis.c divis_ui.c divis_2exp.c \
+ dump.c export.c fac_ui.c fdiv_q.c fdiv_q_ui.c \
+ fdiv_qr.c fdiv_qr_ui.c fdiv_r.c fdiv_r_ui.c fdiv_ui.c \
+ fib_ui.c fib2_ui.c \
+ fits_sint.c fits_slong.c fits_sshort.c \
+ fits_uint.c fits_ulong.c fits_ushort.c \
+ gcd.c gcd_ui.c gcdext.c get_d.c get_d_2exp.c get_si.c \
+ get_str.c get_ui.c getlimbn.c hamdist.c \
+ import.c init.c init2.c inits.c inp_raw.c inp_str.c \
+ invert.c ior.c iset.c iset_d.c iset_si.c iset_str.c iset_ui.c \
+ jacobi.c kronsz.c kronuz.c kronzs.c kronzu.c \
+ lcm.c lcm_ui.c limbs_read.c limbs_write.c limbs_modify.c limbs_finish.c \
+ lucnum_ui.c lucnum2_ui.c mfac_uiui.c millerrabin.c \
+ mod.c mul.c mul_2exp.c mul_si.c mul_ui.c n_pow_ui.c neg.c nextprime.c \
+ oddfac_1.c \
+ out_raw.c out_str.c perfpow.c perfsqr.c popcount.c pow_ui.c powm.c \
+ powm_sec.c powm_ui.c pprime_p.c prodlimbs.c primorial_ui.c random.c random2.c \
+ realloc.c realloc2.c remove.c roinit_n.c root.c rootrem.c rrandomb.c \
+ scan0.c scan1.c set.c set_d.c set_f.c set_q.c set_si.c set_str.c \
+ set_ui.c setbit.c size.c sizeinbase.c sqrt.c sqrtrem.c sub.c sub_ui.c \
+ swap.c tdiv_ui.c tdiv_q.c tdiv_q_2exp.c tdiv_q_ui.c tdiv_qr.c \
+ tdiv_qr_ui.c tdiv_r.c tdiv_r_2exp.c tdiv_r_ui.c tstbit.c ui_pow_ui.c \
+ ui_sub.c urandomb.c urandomm.c xor.c
diff --git a/gmp/mpz/Makefile.in b/gmp/mpz/Makefile.in
new file mode 100644
index 0000000000..fc2eb0fab7
--- /dev/null
+++ b/gmp/mpz/Makefile.in
@@ -0,0 +1,614 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 1996, 1998-2003, 2012 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = mpz
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libmpz_la_LIBADD =
+am_libmpz_la_OBJECTS = 2fac_ui.lo add.lo add_ui.lo abs.lo aorsmul.lo \
+ aorsmul_i.lo and.lo array_init.lo bin_ui.lo bin_uiui.lo \
+ cdiv_q.lo cdiv_q_ui.lo cdiv_qr.lo cdiv_qr_ui.lo cdiv_r.lo \
+ cdiv_r_ui.lo cdiv_ui.lo cfdiv_q_2exp.lo cfdiv_r_2exp.lo \
+ clear.lo clears.lo clrbit.lo cmp.lo cmp_d.lo cmp_si.lo \
+ cmp_ui.lo cmpabs.lo cmpabs_d.lo cmpabs_ui.lo com.lo combit.lo \
+ cong.lo cong_2exp.lo cong_ui.lo divexact.lo divegcd.lo \
+ dive_ui.lo divis.lo divis_ui.lo divis_2exp.lo dump.lo \
+ export.lo fac_ui.lo fdiv_q.lo fdiv_q_ui.lo fdiv_qr.lo \
+ fdiv_qr_ui.lo fdiv_r.lo fdiv_r_ui.lo fdiv_ui.lo fib_ui.lo \
+ fib2_ui.lo fits_sint.lo fits_slong.lo fits_sshort.lo \
+ fits_uint.lo fits_ulong.lo fits_ushort.lo gcd.lo gcd_ui.lo \
+ gcdext.lo get_d.lo get_d_2exp.lo get_si.lo get_str.lo \
+ get_ui.lo getlimbn.lo hamdist.lo import.lo init.lo init2.lo \
+ inits.lo inp_raw.lo inp_str.lo invert.lo ior.lo iset.lo \
+ iset_d.lo iset_si.lo iset_str.lo iset_ui.lo jacobi.lo \
+ kronsz.lo kronuz.lo kronzs.lo kronzu.lo lcm.lo lcm_ui.lo \
+ limbs_read.lo limbs_write.lo limbs_modify.lo limbs_finish.lo \
+ lucnum_ui.lo lucnum2_ui.lo mfac_uiui.lo millerrabin.lo mod.lo \
+ mul.lo mul_2exp.lo mul_si.lo mul_ui.lo n_pow_ui.lo neg.lo \
+ nextprime.lo oddfac_1.lo out_raw.lo out_str.lo perfpow.lo \
+ perfsqr.lo popcount.lo pow_ui.lo powm.lo powm_sec.lo \
+ powm_ui.lo pprime_p.lo prodlimbs.lo primorial_ui.lo random.lo \
+ random2.lo realloc.lo realloc2.lo remove.lo roinit_n.lo \
+ root.lo rootrem.lo rrandomb.lo scan0.lo scan1.lo set.lo \
+ set_d.lo set_f.lo set_q.lo set_si.lo set_str.lo set_ui.lo \
+ setbit.lo size.lo sizeinbase.lo sqrt.lo sqrtrem.lo sub.lo \
+ sub_ui.lo swap.lo tdiv_ui.lo tdiv_q.lo tdiv_q_2exp.lo \
+ tdiv_q_ui.lo tdiv_qr.lo tdiv_qr_ui.lo tdiv_r.lo tdiv_r_2exp.lo \
+ tdiv_r_ui.lo tstbit.lo ui_pow_ui.lo ui_sub.lo urandomb.lo \
+ urandomm.lo xor.lo
+libmpz_la_OBJECTS = $(am_libmpz_la_OBJECTS)
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libmpz_la_SOURCES)
+DIST_SOURCES = $(libmpz_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+noinst_LTLIBRARIES = libmpz.la
+libmpz_la_SOURCES = aors.h aors_ui.h fits_s.h mul_i.h \
+ 2fac_ui.c \
+ add.c add_ui.c abs.c aorsmul.c aorsmul_i.c and.c array_init.c \
+ bin_ui.c bin_uiui.c cdiv_q.c \
+ cdiv_q_ui.c cdiv_qr.c cdiv_qr_ui.c cdiv_r.c cdiv_r_ui.c cdiv_ui.c \
+ cfdiv_q_2exp.c cfdiv_r_2exp.c \
+ clear.c clears.c clrbit.c \
+ cmp.c cmp_d.c cmp_si.c cmp_ui.c cmpabs.c cmpabs_d.c cmpabs_ui.c \
+ com.c combit.c \
+ cong.c cong_2exp.c cong_ui.c \
+ divexact.c divegcd.c dive_ui.c divis.c divis_ui.c divis_2exp.c \
+ dump.c export.c fac_ui.c fdiv_q.c fdiv_q_ui.c \
+ fdiv_qr.c fdiv_qr_ui.c fdiv_r.c fdiv_r_ui.c fdiv_ui.c \
+ fib_ui.c fib2_ui.c \
+ fits_sint.c fits_slong.c fits_sshort.c \
+ fits_uint.c fits_ulong.c fits_ushort.c \
+ gcd.c gcd_ui.c gcdext.c get_d.c get_d_2exp.c get_si.c \
+ get_str.c get_ui.c getlimbn.c hamdist.c \
+ import.c init.c init2.c inits.c inp_raw.c inp_str.c \
+ invert.c ior.c iset.c iset_d.c iset_si.c iset_str.c iset_ui.c \
+ jacobi.c kronsz.c kronuz.c kronzs.c kronzu.c \
+ lcm.c lcm_ui.c limbs_read.c limbs_write.c limbs_modify.c limbs_finish.c \
+ lucnum_ui.c lucnum2_ui.c mfac_uiui.c millerrabin.c \
+ mod.c mul.c mul_2exp.c mul_si.c mul_ui.c n_pow_ui.c neg.c nextprime.c \
+ oddfac_1.c \
+ out_raw.c out_str.c perfpow.c perfsqr.c popcount.c pow_ui.c powm.c \
+ powm_sec.c powm_ui.c pprime_p.c prodlimbs.c primorial_ui.c random.c random2.c \
+ realloc.c realloc2.c remove.c roinit_n.c root.c rootrem.c rrandomb.c \
+ scan0.c scan1.c set.c set_d.c set_f.c set_q.c set_si.c set_str.c \
+ set_ui.c setbit.c size.c sizeinbase.c sqrt.c sqrtrem.c sub.c sub_ui.c \
+ swap.c tdiv_ui.c tdiv_q.c tdiv_q_2exp.c tdiv_q_ui.c tdiv_qr.c \
+ tdiv_qr_ui.c tdiv_r.c tdiv_r_2exp.c tdiv_r_ui.c tstbit.c ui_pow_ui.c \
+ ui_sub.c urandomb.c urandomm.c xor.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 mpz/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps mpz/Makefile
+.PRECIOUS: 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-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libmpz.la: $(libmpz_la_OBJECTS) $(libmpz_la_DEPENDENCIES) $(EXTRA_libmpz_la_DEPENDENCIES)
+ $(LINK) $(libmpz_la_OBJECTS) $(libmpz_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+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:
+
+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-generic clean-libtool clean-noinstLTLIBRARIES \
+ 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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags 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 tags uninstall uninstall-am
+
+
+# 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/gmp/mpz/abs.c b/gmp/mpz/abs.c
new file mode 100644
index 0000000000..81c6b63266
--- /dev/null
+++ b/gmp/mpz/abs.c
@@ -0,0 +1,55 @@
+/* mpz_abs(dst, src) -- Assign the absolute value of SRC to DST.
+
+Copyright 1991, 1993-1995, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_abs 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_abs (mpz_ptr w, mpz_srcptr u)
+{
+ mp_ptr wp;
+ mp_srcptr up;
+ mp_size_t size;
+
+ size = ABSIZ (u);
+
+ if (u != w)
+ {
+ wp = MPZ_NEWALLOC (w, size);
+
+ up = PTR (u);
+
+ MPN_COPY (wp, up, size);
+ }
+
+ SIZ (w) = size;
+}
diff --git a/gmp/mpz/add.c b/gmp/mpz/add.c
new file mode 100644
index 0000000000..f1f0ae8e16
--- /dev/null
+++ b/gmp/mpz/add.c
@@ -0,0 +1,33 @@
+/* mpz_add -- add integers.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define OPERATION_add
+#include "aors.h"
diff --git a/gmp/mpz/add_ui.c b/gmp/mpz/add_ui.c
new file mode 100644
index 0000000000..8fd15ad611
--- /dev/null
+++ b/gmp/mpz/add_ui.c
@@ -0,0 +1,33 @@
+/* mpz_add_ui -- Add an mpz_t and an unsigned one-word integer.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define OPERATION_add_ui
+#include "aors_ui.h"
diff --git a/gmp/mpz/and.c b/gmp/mpz/and.c
new file mode 100644
index 0000000000..5aa01a71da
--- /dev/null
+++ b/gmp/mpz/and.c
@@ -0,0 +1,244 @@
+/* mpz_and -- Logical and.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2003, 2005, 2012 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_and (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2)
+{
+ mp_srcptr op1_ptr, op2_ptr;
+ mp_size_t op1_size, op2_size;
+ mp_ptr res_ptr;
+ mp_size_t res_size;
+ mp_size_t i;
+ TMP_DECL;
+
+ TMP_MARK;
+ op1_size = SIZ(op1);
+ op2_size = SIZ(op2);
+
+ op1_ptr = PTR(op1);
+ op2_ptr = PTR(op2);
+
+ if (op1_size >= 0)
+ {
+ if (op2_size >= 0)
+ {
+ res_size = MIN (op1_size, op2_size);
+ /* First loop finds the size of the result. */
+ for (i = res_size - 1; i >= 0; i--)
+ if ((op1_ptr[i] & op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+
+ /* Handle allocation, now then we know exactly how much space is
+ needed for the result. */
+ res_ptr = MPZ_REALLOC (res, res_size);
+ /* Don't re-read op1_ptr and op2_ptr. Since res_size <=
+ MIN(op1_size, op2_size), res is not changed when op1
+ is identical to res or op2 is identical to res. */
+
+ SIZ(res) = res_size;
+ if (LIKELY (res_size != 0))
+ mpn_and_n (res_ptr, op1_ptr, op2_ptr, res_size);
+ return;
+ }
+ else /* op2_size < 0 */
+ {
+ /* Fall through to the code at the end of the function. */
+ }
+ }
+ else
+ {
+ if (op2_size < 0)
+ {
+ mp_ptr opx, opy;
+ mp_limb_t cy;
+
+ /* Both operands are negative, so will be the result.
+ -((-OP1) & (-OP2)) = -(~(OP1 - 1) & ~(OP2 - 1)) =
+ = ~(~(OP1 - 1) & ~(OP2 - 1)) + 1 =
+ = ((OP1 - 1) | (OP2 - 1)) + 1 */
+
+ /* It might seem as we could end up with an (invalid) result with
+ a leading zero-limb here when one of the operands is of the
+ type 1,,0,,..,,.0. But some analysis shows that we surely
+ would get carry into the zero-limb in this situation... */
+
+ op1_size = -op1_size;
+ op2_size = -op2_size;
+
+ if (op1_size > op2_size)
+ MPN_SRCPTR_SWAP (op1_ptr, op1_size, op2_ptr, op2_size);
+
+ TMP_ALLOC_LIMBS_2 (opx, op1_size, opy, op2_size);
+ mpn_sub_1 (opx, op1_ptr, op1_size, (mp_limb_t) 1);
+ op1_ptr = opx;
+
+ mpn_sub_1 (opy, op2_ptr, op2_size, (mp_limb_t) 1);
+ op2_ptr = opy;
+
+ res_ptr = MPZ_REALLOC (res, 1 + op2_size);
+ /* Don't re-read OP1_PTR and OP2_PTR. They point to temporary
+ space--never to the space PTR(res) used to point to before
+ reallocation. */
+
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size,
+ op2_size - op1_size);
+ mpn_ior_n (res_ptr, op1_ptr, op2_ptr, op1_size);
+ res_size = op2_size;
+
+ cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1);
+ res_ptr[res_size] = cy;
+ res_size += (cy != 0);
+
+ SIZ(res) = -res_size;
+ TMP_FREE;
+ return;
+ }
+ else
+ {
+ /* We should compute -OP1 & OP2. Swap OP1 and OP2 and fall
+ through to the code that handles OP1 & -OP2. */
+ MPN_SRCPTR_SWAP (op1_ptr, op1_size, op2_ptr, op2_size);
+ }
+
+ }
+
+ {
+#if ANDNEW
+ mp_size_t op2_lim;
+ mp_size_t count;
+
+ /* OP2 must be negated as with infinite precision.
+
+ Scan from the low end for a non-zero limb. The first non-zero
+ limb is simply negated (two's complement). Any subsequent
+ limbs are one's complemented. Of course, we don't need to
+ handle more limbs than there are limbs in the other, positive
+ operand as the result for those limbs is going to become zero
+ anyway. */
+
+ /* Scan for the least significant non-zero OP2 limb, and zero the
+ result meanwhile for those limb positions. (We will surely
+ find a non-zero limb, so we can write the loop with one
+ termination condition only.) */
+ for (i = 0; op2_ptr[i] == 0; i++)
+ res_ptr[i] = 0;
+ op2_lim = i;
+
+ op2_size = -op2_size;
+
+ if (op1_size <= op2_size)
+ {
+ /* The ones-extended OP2 is >= than the zero-extended OP1.
+ RES_SIZE <= OP1_SIZE. Find the exact size. */
+ for (i = op1_size - 1; i > op2_lim; i--)
+ if ((op1_ptr[i] & ~op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+ for (i = res_size - 1; i > op2_lim; i--)
+ res_ptr[i] = op1_ptr[i] & ~op2_ptr[i];
+ res_ptr[op2_lim] = op1_ptr[op2_lim] & -op2_ptr[op2_lim];
+ /* Yes, this *can* happen! */
+ MPN_NORMALIZE (res_ptr, res_size);
+ }
+ else
+ {
+ /* The ones-extended OP2 is < than the zero-extended OP1.
+ RES_SIZE == OP1_SIZE, since OP1 is normalized. */
+ res_size = op1_size;
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, op1_size - op2_size);
+ for (i = op2_size - 1; i > op2_lim; i--)
+ res_ptr[i] = op1_ptr[i] & ~op2_ptr[i];
+ res_ptr[op2_lim] = op1_ptr[op2_lim] & -op2_ptr[op2_lim];
+ }
+
+ SIZ(res) = res_size;
+#else
+
+ /* OP1 is positive and zero-extended,
+ OP2 is negative and ones-extended.
+ The result will be positive.
+ OP1 & -OP2 = OP1 & ~(OP2 - 1). */
+
+ mp_ptr opx;
+
+ op2_size = -op2_size;
+ opx = TMP_ALLOC_LIMBS (op2_size);
+ mpn_sub_1 (opx, op2_ptr, op2_size, (mp_limb_t) 1);
+ op2_ptr = opx;
+
+ if (op1_size > op2_size)
+ {
+ /* The result has the same size as OP1, since OP1 is normalized
+ and longer than the ones-extended OP2. */
+ res_size = op1_size;
+
+ /* Handle allocation, now then we know exactly how much space is
+ needed for the result. */
+ res_ptr = MPZ_REALLOC (res, res_size);
+ /* Don't re-read OP1_PTR or OP2_PTR. Since res_size = op1_size,
+ op1 is not changed if it is identical to res.
+ OP2_PTR points to temporary space. */
+
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, res_size - op2_size);
+ mpn_andn_n (res_ptr, op1_ptr, op2_ptr, op2_size);
+
+ SIZ(res) = res_size;
+ }
+ else
+ {
+ /* Find out the exact result size. Ignore the high limbs of OP2,
+ OP1 is zero-extended and would make the result zero. */
+ for (i = op1_size - 1; i >= 0; i--)
+ if ((op1_ptr[i] & ~op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+
+ /* Handle allocation, now then we know exactly how much space is
+ needed for the result. */
+ res_ptr = MPZ_REALLOC (res, res_size);
+ /* Don't re-read OP1_PTR. Since res_size <= op1_size,
+ op1 is not changed if it is identical to res.
+ Don't re-read OP2_PTR. It points to temporary space--never
+ to the space PTR(res) used to point to before reallocation. */
+
+ if (LIKELY (res_size != 0))
+ mpn_andn_n (res_ptr, op1_ptr, op2_ptr, res_size);
+
+ SIZ(res) = res_size;
+ }
+#endif
+ }
+ TMP_FREE;
+}
diff --git a/gmp/mpz/aors.h b/gmp/mpz/aors.h
new file mode 100644
index 0000000000..4d22754b23
--- /dev/null
+++ b/gmp/mpz/aors.h
@@ -0,0 +1,124 @@
+/* mpz_add, mpz_sub -- add or subtract integers.
+
+Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2011, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#ifdef OPERATION_add
+#define FUNCTION mpz_add
+#define VARIATION
+#endif
+#ifdef OPERATION_sub
+#define FUNCTION mpz_sub
+#define VARIATION -
+#endif
+
+#ifndef FUNCTION
+Error, need OPERATION_add or OPERATION_sub
+#endif
+
+
+void
+FUNCTION (mpz_ptr w, mpz_srcptr u, mpz_srcptr v)
+{
+ mp_srcptr up, vp;
+ mp_ptr wp;
+ mp_size_t usize, vsize, wsize;
+ mp_size_t abs_usize;
+ mp_size_t abs_vsize;
+
+ usize = SIZ(u);
+ vsize = VARIATION SIZ(v);
+ abs_usize = ABS (usize);
+ abs_vsize = ABS (vsize);
+
+ if (abs_usize < abs_vsize)
+ {
+ /* Swap U and V. */
+ MPZ_SRCPTR_SWAP (u, v);
+ MP_SIZE_T_SWAP (usize, vsize);
+ MP_SIZE_T_SWAP (abs_usize, abs_vsize);
+ }
+
+ /* True: ABS_USIZE >= ABS_VSIZE. */
+
+ /* If not space for w (and possible carry), increase space. */
+ wsize = abs_usize + 1;
+ wp = MPZ_REALLOC (w, wsize);
+
+ /* These must be after realloc (u or v may be the same as w). */
+ up = PTR(u);
+ vp = PTR(v);
+
+ if ((usize ^ vsize) < 0)
+ {
+ /* U and V have different sign. Need to compare them to determine
+ which operand to subtract from which. */
+
+ /* This test is right since ABS_USIZE >= ABS_VSIZE. */
+ if (abs_usize != abs_vsize)
+ {
+ mpn_sub (wp, up, abs_usize, vp, abs_vsize);
+ wsize = abs_usize;
+ MPN_NORMALIZE (wp, wsize);
+ if (usize < 0)
+ wsize = -wsize;
+ }
+ else if (mpn_cmp (up, vp, abs_usize) < 0)
+ {
+ mpn_sub_n (wp, vp, up, abs_usize);
+ wsize = abs_usize;
+ MPN_NORMALIZE (wp, wsize);
+ if (usize >= 0)
+ wsize = -wsize;
+ }
+ else
+ {
+ mpn_sub_n (wp, up, vp, abs_usize);
+ wsize = abs_usize;
+ MPN_NORMALIZE (wp, wsize);
+ if (usize < 0)
+ wsize = -wsize;
+ }
+ }
+ else
+ {
+ /* U and V have same sign. Add them. */
+ mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize);
+ wp[abs_usize] = cy_limb;
+ wsize = abs_usize + cy_limb;
+ if (usize < 0)
+ wsize = -wsize;
+ }
+
+ SIZ(w) = wsize;
+}
diff --git a/gmp/mpz/aors_ui.h b/gmp/mpz/aors_ui.h
new file mode 100644
index 0000000000..2e3c481ab7
--- /dev/null
+++ b/gmp/mpz/aors_ui.h
@@ -0,0 +1,121 @@
+/* mpz_add_ui, mpz_sub_ui -- Add or subtract an mpz_t and an unsigned
+ one-word integer.
+
+Copyright 1991, 1993, 1994, 1996, 1999-2002, 2004, 2012, 2013 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#ifdef OPERATION_add_ui
+#define FUNCTION mpz_add_ui
+#define FUNCTION2 mpz_add
+#define VARIATION_CMP >=
+#define VARIATION_NEG
+#define VARIATION_UNNEG -
+#endif
+
+#ifdef OPERATION_sub_ui
+#define FUNCTION mpz_sub_ui
+#define FUNCTION2 mpz_sub
+#define VARIATION_CMP <
+#define VARIATION_NEG -
+#define VARIATION_UNNEG
+#endif
+
+#ifndef FUNCTION
+Error, need OPERATION_add_ui or OPERATION_sub_ui
+#endif
+
+
+void
+FUNCTION (mpz_ptr w, mpz_srcptr u, unsigned long int vval)
+{
+ mp_srcptr up;
+ mp_ptr wp;
+ mp_size_t usize, wsize;
+ mp_size_t abs_usize;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (vval > GMP_NUMB_MAX)
+ {
+ mpz_t v;
+ mp_limb_t vl[2];
+ PTR(v) = vl;
+ vl[0] = vval & GMP_NUMB_MASK;
+ vl[1] = vval >> GMP_NUMB_BITS;
+ SIZ(v) = 2;
+ FUNCTION2 (w, u, v);
+ return;
+ }
+#endif
+
+ usize = SIZ (u);
+ if (usize == 0)
+ {
+ PTR (w)[0] = vval;
+ SIZ (w) = VARIATION_NEG (vval != 0);
+ return;
+ }
+
+ abs_usize = ABS (usize);
+
+ /* If not space for W (and possible carry), increase space. */
+ wp = MPZ_REALLOC (w, abs_usize + 1);
+
+ /* These must be after realloc (U may be the same as W). */
+ up = PTR (u);
+
+ if (usize VARIATION_CMP 0)
+ {
+ mp_limb_t cy;
+ cy = mpn_add_1 (wp, up, abs_usize, (mp_limb_t) vval);
+ wp[abs_usize] = cy;
+ wsize = VARIATION_NEG (abs_usize + cy);
+ }
+ else
+ {
+ /* The signs are different. Need exact comparison to determine
+ which operand to subtract from which. */
+ if (abs_usize == 1 && up[0] < vval)
+ {
+ wp[0] = vval - up[0];
+ wsize = VARIATION_NEG 1;
+ }
+ else
+ {
+ mpn_sub_1 (wp, up, abs_usize, (mp_limb_t) vval);
+ /* Size can decrease with at most one limb. */
+ wsize = VARIATION_UNNEG (abs_usize - (wp[abs_usize - 1] == 0));
+ }
+ }
+
+ SIZ (w) = wsize;
+}
diff --git a/gmp/mpz/aorsmul.c b/gmp/mpz/aorsmul.c
new file mode 100644
index 0000000000..bf012c965c
--- /dev/null
+++ b/gmp/mpz/aorsmul.c
@@ -0,0 +1,164 @@
+/* mpz_addmul, mpz_submul -- add or subtract multiple.
+
+Copyright 2001, 2004, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* expecting x and y both with non-zero high limbs */
+#define mpn_cmp_twosizes_lt(xp,xsize, yp,ysize) \
+ ((xsize) < (ysize) \
+ || ((xsize) == (ysize) && mpn_cmp (xp, yp, xsize) < 0))
+
+
+/* sub>=0 means an addmul w += x*y, sub<0 means a submul w -= x*y.
+
+ The signs of w, x and y are fully accounted for by each flipping "sub".
+
+ The sign of w is retained for the result, unless the absolute value
+ submul underflows, in which case it flips. */
+
+static void __gmpz_aorsmul (REGPARM_3_1 (mpz_ptr w, mpz_srcptr x, mpz_srcptr y, mp_size_t sub)) REGPARM_ATTR (1);
+#define mpz_aorsmul(w,x,y,sub) __gmpz_aorsmul (REGPARM_3_1 (w, x, y, sub))
+
+REGPARM_ATTR (1) static void
+mpz_aorsmul (mpz_ptr w, mpz_srcptr x, mpz_srcptr y, mp_size_t sub)
+{
+ mp_size_t xsize, ysize, tsize, wsize, wsize_signed;
+ mp_ptr wp, tp;
+ mp_limb_t c, high;
+ TMP_DECL;
+
+ /* w unaffected if x==0 or y==0 */
+ xsize = SIZ(x);
+ ysize = SIZ(y);
+ if (xsize == 0 || ysize == 0)
+ return;
+
+ /* make x the bigger of the two */
+ if (ABS(ysize) > ABS(xsize))
+ {
+ MPZ_SRCPTR_SWAP (x, y);
+ MP_SIZE_T_SWAP (xsize, ysize);
+ }
+
+ sub ^= ysize;
+ ysize = ABS(ysize);
+
+ /* use mpn_addmul_1/mpn_submul_1 if possible */
+ if (ysize == 1)
+ {
+ mpz_aorsmul_1 (w, x, PTR(y)[0], sub);
+ return;
+ }
+
+ sub ^= xsize;
+ xsize = ABS(xsize);
+
+ wsize_signed = SIZ(w);
+ sub ^= wsize_signed;
+ wsize = ABS(wsize_signed);
+
+ tsize = xsize + ysize;
+ wp = MPZ_REALLOC (w, MAX (wsize, tsize) + 1);
+
+ if (wsize_signed == 0)
+ {
+ /* Nothing to add to, just set w=x*y. No w==x or w==y overlap here,
+ since we know x,y!=0 but w==0. */
+ high = mpn_mul (wp, PTR(x),xsize, PTR(y),ysize);
+ tsize -= (high == 0);
+ SIZ(w) = (sub >= 0 ? tsize : -tsize);
+ return;
+ }
+
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS (tsize);
+
+ high = mpn_mul (tp, PTR(x),xsize, PTR(y),ysize);
+ tsize -= (high == 0);
+ ASSERT (tp[tsize-1] != 0);
+ if (sub >= 0)
+ {
+ mp_srcptr up = wp;
+ mp_size_t usize = wsize;
+
+ if (usize < tsize)
+ {
+ up = tp;
+ usize = tsize;
+ tp = wp;
+ tsize = wsize;
+
+ wsize = usize;
+ }
+
+ c = mpn_add (wp, up,usize, tp,tsize);
+ wp[wsize] = c;
+ wsize += (c != 0);
+ }
+ else
+ {
+ mp_srcptr up = wp;
+ mp_size_t usize = wsize;
+
+ if (mpn_cmp_twosizes_lt (up,usize, tp,tsize))
+ {
+ up = tp;
+ usize = tsize;
+ tp = wp;
+ tsize = wsize;
+
+ wsize = usize;
+ wsize_signed = -wsize_signed;
+ }
+
+ ASSERT_NOCARRY (mpn_sub (wp, up,usize, tp,tsize));
+ wsize = usize;
+ MPN_NORMALIZE (wp, wsize);
+ }
+
+ SIZ(w) = (wsize_signed >= 0 ? wsize : -wsize);
+
+ TMP_FREE;
+}
+
+
+void
+mpz_addmul (mpz_ptr w, mpz_srcptr u, mpz_srcptr v)
+{
+ mpz_aorsmul (w, u, v, (mp_size_t) 0);
+}
+
+void
+mpz_submul (mpz_ptr w, mpz_srcptr u, mpz_srcptr v)
+{
+ mpz_aorsmul (w, u, v, (mp_size_t) -1);
+}
diff --git a/gmp/mpz/aorsmul_i.c b/gmp/mpz/aorsmul_i.c
new file mode 100644
index 0000000000..eafd5f36de
--- /dev/null
+++ b/gmp/mpz/aorsmul_i.c
@@ -0,0 +1,255 @@
+/* mpz_addmul_ui, mpz_submul_ui - add or subtract small multiple.
+
+ THE mpz_aorsmul_1 FUNCTION IN THIS FILE IS FOR INTERNAL USE ONLY AND IS
+ ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR
+ COMPLETELY IN FUTURE GNU MP RELEASES.
+
+Copyright 2001, 2002, 2004, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#if HAVE_NATIVE_mpn_mul_1c
+#define MPN_MUL_1C(cout, dst, src, size, n, cin) \
+ do { \
+ (cout) = mpn_mul_1c (dst, src, size, n, cin); \
+ } while (0)
+#else
+#define MPN_MUL_1C(cout, dst, src, size, n, cin) \
+ do { \
+ mp_limb_t __cy; \
+ __cy = mpn_mul_1 (dst, src, size, n); \
+ (cout) = __cy + mpn_add_1 (dst, dst, size, cin); \
+ } while (0)
+#endif
+
+
+/* sub>=0 means an addmul w += x*y, sub<0 means a submul w -= x*y.
+
+ All that's needed to account for negative w or x is to flip "sub".
+
+ The final w will retain its sign, unless an underflow occurs in a submul
+ of absolute values, in which case it's flipped.
+
+ If x has more limbs than w, then mpn_submul_1 followed by mpn_com is
+ used. The alternative would be mpn_mul_1 into temporary space followed
+ by mpn_sub_n. Avoiding temporary space seem good, and submul+com stands
+ a chance of being faster since it involves only one set of carry
+ propagations, not two. Note that doing an addmul_1 with a
+ twos-complement negative y doesn't work, because it effectively adds an
+ extra x * 2^GMP_LIMB_BITS. */
+
+REGPARM_ATTR(1) void
+mpz_aorsmul_1 (mpz_ptr w, mpz_srcptr x, mp_limb_t y, mp_size_t sub)
+{
+ mp_size_t xsize, wsize, wsize_signed, new_wsize, min_size, dsize;
+ mp_srcptr xp;
+ mp_ptr wp;
+ mp_limb_t cy;
+
+ /* w unaffected if x==0 or y==0 */
+ xsize = SIZ (x);
+ if (xsize == 0 || y == 0)
+ return;
+
+ sub ^= xsize;
+ xsize = ABS (xsize);
+
+ wsize_signed = SIZ (w);
+ if (wsize_signed == 0)
+ {
+ /* nothing to add to, just set x*y, "sub" gives the sign */
+ wp = MPZ_REALLOC (w, xsize+1);
+ cy = mpn_mul_1 (wp, PTR(x), xsize, y);
+ wp[xsize] = cy;
+ xsize += (cy != 0);
+ SIZ (w) = (sub >= 0 ? xsize : -xsize);
+ return;
+ }
+
+ sub ^= wsize_signed;
+ wsize = ABS (wsize_signed);
+
+ new_wsize = MAX (wsize, xsize);
+ wp = MPZ_REALLOC (w, new_wsize+1);
+ xp = PTR (x);
+ min_size = MIN (wsize, xsize);
+
+ if (sub >= 0)
+ {
+ /* addmul of absolute values */
+
+ cy = mpn_addmul_1 (wp, xp, min_size, y);
+ wp += min_size;
+ xp += min_size;
+
+ dsize = xsize - wsize;
+#if HAVE_NATIVE_mpn_mul_1c
+ if (dsize > 0)
+ cy = mpn_mul_1c (wp, xp, dsize, y, cy);
+ else if (dsize < 0)
+ {
+ dsize = -dsize;
+ cy = mpn_add_1 (wp, wp, dsize, cy);
+ }
+#else
+ if (dsize != 0)
+ {
+ mp_limb_t cy2;
+ if (dsize > 0)
+ cy2 = mpn_mul_1 (wp, xp, dsize, y);
+ else
+ {
+ dsize = -dsize;
+ cy2 = 0;
+ }
+ cy = cy2 + mpn_add_1 (wp, wp, dsize, cy);
+ }
+#endif
+
+ wp[dsize] = cy;
+ new_wsize += (cy != 0);
+ }
+ else
+ {
+ /* submul of absolute values */
+
+ cy = mpn_submul_1 (wp, xp, min_size, y);
+ if (wsize >= xsize)
+ {
+ /* if w bigger than x, then propagate borrow through it */
+ if (wsize != xsize)
+ cy = mpn_sub_1 (wp+xsize, wp+xsize, wsize-xsize, cy);
+
+ if (cy != 0)
+ {
+ /* Borrow out of w, take twos complement negative to get
+ absolute value, flip sign of w. */
+ wp[new_wsize] = ~-cy; /* extra limb is 0-cy */
+ mpn_com (wp, wp, new_wsize);
+ new_wsize++;
+ MPN_INCR_U (wp, new_wsize, CNST_LIMB(1));
+ wsize_signed = -wsize_signed;
+ }
+ }
+ else /* wsize < xsize */
+ {
+ /* x bigger than w, so want x*y-w. Submul has given w-x*y, so
+ take twos complement and use an mpn_mul_1 for the rest. */
+
+ mp_limb_t cy2;
+
+ /* -(-cy*b^n + w-x*y) = (cy-1)*b^n + ~(w-x*y) + 1 */
+ mpn_com (wp, wp, wsize);
+ cy += mpn_add_1 (wp, wp, wsize, CNST_LIMB(1));
+ cy -= 1;
+
+ /* If cy-1 == -1 then hold that -1 for latter. mpn_submul_1 never
+ returns cy==MP_LIMB_T_MAX so that value always indicates a -1. */
+ cy2 = (cy == MP_LIMB_T_MAX);
+ cy += cy2;
+ MPN_MUL_1C (cy, wp+wsize, xp+wsize, xsize-wsize, y, cy);
+ wp[new_wsize] = cy;
+ new_wsize += (cy != 0);
+
+ /* Apply any -1 from above. The value at wp+wsize is non-zero
+ because y!=0 and the high limb of x will be non-zero. */
+ if (cy2)
+ MPN_DECR_U (wp+wsize, new_wsize-wsize, CNST_LIMB(1));
+
+ wsize_signed = -wsize_signed;
+ }
+
+ /* submul can produce high zero limbs due to cancellation, both when w
+ has more limbs or x has more */
+ MPN_NORMALIZE (wp, new_wsize);
+ }
+
+ SIZ (w) = (wsize_signed >= 0 ? new_wsize : -new_wsize);
+
+ ASSERT (new_wsize == 0 || PTR(w)[new_wsize-1] != 0);
+}
+
+
+void
+mpz_addmul_ui (mpz_ptr w, mpz_srcptr x, unsigned long y)
+{
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ if (UNLIKELY (y > GMP_NUMB_MAX && SIZ(x) != 0))
+ {
+ mpz_t t;
+ mp_ptr tp;
+ mp_size_t xn;
+ TMP_DECL;
+ TMP_MARK;
+ xn = SIZ (x);
+ MPZ_TMP_INIT (t, ABS (xn) + 1);
+ tp = PTR (t);
+ tp[0] = 0;
+ MPN_COPY (tp + 1, PTR(x), ABS (xn));
+ SIZ(t) = xn >= 0 ? xn + 1 : xn - 1;
+ mpz_aorsmul_1 (w, t, (mp_limb_t) y >> GMP_NUMB_BITS, (mp_size_t) 0);
+ PTR(t) = tp + 1;
+ SIZ(t) = xn;
+ mpz_aorsmul_1 (w, t, (mp_limb_t) y & GMP_NUMB_MASK, (mp_size_t) 0);
+ TMP_FREE;
+ return;
+ }
+#endif
+ mpz_aorsmul_1 (w, x, (mp_limb_t) y, (mp_size_t) 0);
+}
+
+void
+mpz_submul_ui (mpz_ptr w, mpz_srcptr x, unsigned long y)
+{
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ if (y > GMP_NUMB_MAX && SIZ(x) != 0)
+ {
+ mpz_t t;
+ mp_ptr tp;
+ mp_size_t xn;
+ TMP_DECL;
+ TMP_MARK;
+ xn = SIZ (x);
+ MPZ_TMP_INIT (t, ABS (xn) + 1);
+ tp = PTR (t);
+ tp[0] = 0;
+ MPN_COPY (tp + 1, PTR(x), ABS (xn));
+ SIZ(t) = xn >= 0 ? xn + 1 : xn - 1;
+ mpz_aorsmul_1 (w, t, (mp_limb_t) y >> GMP_NUMB_BITS, (mp_size_t) -1);
+ PTR(t) = tp + 1;
+ SIZ(t) = xn;
+ mpz_aorsmul_1 (w, t, (mp_limb_t) y & GMP_NUMB_MASK, (mp_size_t) -1);
+ TMP_FREE;
+ return;
+ }
+#endif
+ mpz_aorsmul_1 (w, x, (mp_limb_t) y & GMP_NUMB_MASK, (mp_size_t) -1);
+}
diff --git a/gmp/mpz/array_init.c b/gmp/mpz/array_init.c
new file mode 100644
index 0000000000..b967ddbeef
--- /dev/null
+++ b/gmp/mpz/array_init.c
@@ -0,0 +1,50 @@
+/* mpz_array_init (array, array_size, size_per_elem) --
+
+Copyright 1991, 1993-1995, 2000-2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_array_init (mpz_ptr arr, mp_size_t arr_size, mp_size_t nbits)
+{
+ mp_ptr p;
+ mp_size_t i;
+ mp_size_t nlimbs;
+
+ nlimbs = nbits / GMP_NUMB_BITS + 1;
+ p = (mp_ptr) (*__gmp_allocate_func) ((size_t) arr_size * nlimbs * GMP_LIMB_BYTES);
+
+ for (i = 0; i < arr_size; i++)
+ {
+ ALLOC (&arr[i]) = nlimbs + 1; /* Yes, lie a little... */
+ SIZ (&arr[i]) = 0;
+ PTR (&arr[i]) = p + i * nlimbs;
+ }
+}
diff --git a/gmp/mpz/bin_ui.c b/gmp/mpz/bin_ui.c
new file mode 100644
index 0000000000..c24b21724c
--- /dev/null
+++ b/gmp/mpz/bin_ui.c
@@ -0,0 +1,143 @@
+/* mpz_bin_ui - compute n over k.
+
+Copyright 1998-2002, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* This is a poor implementation. Look at bin_uiui.c for improvement ideas.
+ In fact consider calling mpz_bin_uiui() when the arguments fit, leaving
+ the code here only for big n.
+
+ The identity bin(n,k) = (-1)^k * bin(-n+k-1,k) can be found in Knuth vol
+ 1 section 1.2.6 part G. */
+
+
+#define DIVIDE() \
+ do { \
+ ASSERT (SIZ(r) > 0); \
+ MPN_DIVREM_OR_DIVEXACT_1 (PTR(r), PTR(r), (mp_size_t) SIZ(r), kacc); \
+ SIZ(r) -= (PTR(r)[SIZ(r)-1] == 0); \
+ } while (0)
+
+void
+mpz_bin_ui (mpz_ptr r, mpz_srcptr n, unsigned long int k)
+{
+ mpz_t ni;
+ mp_limb_t i;
+ mpz_t nacc;
+ mp_limb_t kacc;
+ mp_size_t negate;
+
+ if (SIZ (n) < 0)
+ {
+ /* bin(n,k) = (-1)^k * bin(-n+k-1,k), and set ni = -n+k-1 - k = -n-1 */
+ mpz_init (ni);
+ mpz_add_ui (ni, n, 1L);
+ mpz_neg (ni, ni);
+ negate = (k & 1); /* (-1)^k */
+ }
+ else
+ {
+ /* bin(n,k) == 0 if k>n
+ (no test for this under the n<0 case, since -n+k-1 >= k there) */
+ if (mpz_cmp_ui (n, k) < 0)
+ {
+ SIZ (r) = 0;
+ return;
+ }
+
+ /* set ni = n-k */
+ mpz_init (ni);
+ mpz_sub_ui (ni, n, k);
+ negate = 0;
+ }
+
+ /* Now wanting bin(ni+k,k), with ni positive, and "negate" is the sign (0
+ for positive, 1 for negative). */
+ SIZ (r) = 1; PTR (r)[0] = 1;
+
+ /* Rewrite bin(n,k) as bin(n,n-k) if that is smaller. In this case it's
+ whether ni+k-k < k meaning ni<k, and if so change to denominator ni+k-k
+ = ni, and new ni of ni+k-ni = k. */
+ if (mpz_cmp_ui (ni, k) < 0)
+ {
+ unsigned long tmp;
+ tmp = k;
+ k = mpz_get_ui (ni);
+ mpz_set_ui (ni, tmp);
+ }
+
+ kacc = 1;
+ mpz_init_set_ui (nacc, 1L);
+
+ for (i = 1; i <= k; i++)
+ {
+ mp_limb_t k1, k0;
+
+#if 0
+ mp_limb_t nacclow;
+ int c;
+
+ nacclow = PTR(nacc)[0];
+ for (c = 0; (((kacc | nacclow) & 1) == 0); c++)
+ {
+ kacc >>= 1;
+ nacclow >>= 1;
+ }
+ mpz_div_2exp (nacc, nacc, c);
+#endif
+
+ mpz_add_ui (ni, ni, 1L);
+ mpz_mul (nacc, nacc, ni);
+ umul_ppmm (k1, k0, kacc, i << GMP_NAIL_BITS);
+ if (k1 != 0)
+ {
+ /* Accumulator overflow. Perform bignum step. */
+ mpz_mul (r, r, nacc);
+ SIZ (nacc) = 1; PTR (nacc)[0] = 1;
+ DIVIDE ();
+ kacc = i;
+ }
+ else
+ {
+ /* Save new products in accumulators to keep accumulating. */
+ kacc = k0 >> GMP_NAIL_BITS;
+ }
+ }
+
+ mpz_mul (r, r, nacc);
+ DIVIDE ();
+ SIZ(r) = (SIZ(r) ^ -negate) + negate;
+
+ mpz_clear (nacc);
+ mpz_clear (ni);
+}
diff --git a/gmp/mpz/bin_uiui.c b/gmp/mpz/bin_uiui.c
new file mode 100644
index 0000000000..94a9dc5c75
--- /dev/null
+++ b/gmp/mpz/bin_uiui.c
@@ -0,0 +1,696 @@
+/* mpz_bin_uiui - compute n over k.
+
+Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
+
+Copyright 2010-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef BIN_GOETGHELUCK_THRESHOLD
+#define BIN_GOETGHELUCK_THRESHOLD 1000
+#endif
+#ifndef BIN_UIUI_ENABLE_SMALLDC
+#define BIN_UIUI_ENABLE_SMALLDC 1
+#endif
+#ifndef BIN_UIUI_RECURSIVE_SMALLDC
+#define BIN_UIUI_RECURSIVE_SMALLDC (GMP_NUMB_BITS > 32)
+#endif
+
+/* Algorithm:
+
+ Accumulate chunks of factors first limb-by-limb (using one of mul0-mul8)
+ which are then accumulated into mpn numbers. The first inner loop
+ accumulates divisor factors, the 2nd inner loop accumulates exactly the same
+ number of dividend factors. We avoid accumulating more for the divisor,
+ even with its smaller factors, since we else cannot guarantee divisibility.
+
+ Since we know each division will yield an integer, we compute the quotient
+ using Hensel norm: If the quotient is limited by 2^t, we compute A / B mod
+ 2^t.
+
+ Improvements:
+
+ (1) An obvious improvement to this code would be to compute mod 2^t
+ everywhere. Unfortunately, we cannot determine t beforehand, unless we
+ invoke some approximation, such as Stirling's formula. Of course, we don't
+ need t to be tight. However, it is not clear that this would help much,
+ our numbers are kept reasonably small already.
+
+ (2) Compute nmax/kmax semi-accurately, without scalar division or a loop.
+ Extracting the 3 msb, then doing a table lookup using cnt*8+msb as index,
+ would make it both reasonably accurate and fast. (We could use a table
+ stored into a limb, perhaps.) The table should take the removed factors of
+ 2 into account (those done on-the-fly in mulN).
+
+ (3) The first time in the loop we compute the odd part of a
+ factorial in kp, we might use oddfac_1 for this task.
+ */
+
+/* This threshold determines how large divisor to accumulate before we call
+ bdiv. Perhaps we should never call bdiv, and accumulate all we are told,
+ since we are just basecase code anyway? Presumably, this depends on the
+ relative speed of the asymptotically fast code and this code. */
+#define SOME_THRESHOLD 20
+
+/* Multiply-into-limb functions. These remove factors of 2 on-the-fly. FIXME:
+ All versions of MAXFACS don't take this 2 removal into account now, meaning
+ that then, shifting just adds some overhead. (We remove factors from the
+ completed limb anyway.) */
+
+static mp_limb_t
+mul1 (mp_limb_t m)
+{
+ return m;
+}
+
+static mp_limb_t
+mul2 (mp_limb_t m)
+{
+ /* We need to shift before multiplying, to avoid an overflow. */
+ mp_limb_t m01 = (m | 1) * ((m + 1) >> 1);
+ return m01;
+}
+
+static mp_limb_t
+mul3 (mp_limb_t m)
+{
+ mp_limb_t m01 = (m + 0) * (m + 1) >> 1;
+ mp_limb_t m2 = (m + 2);
+ return m01 * m2;
+}
+
+static mp_limb_t
+mul4 (mp_limb_t m)
+{
+ mp_limb_t m01 = (m + 0) * (m + 1) >> 1;
+ mp_limb_t m23 = (m + 2) * (m + 3) >> 1;
+ return m01 * m23;
+}
+
+static mp_limb_t
+mul5 (mp_limb_t m)
+{
+ mp_limb_t m012 = (m + 0) * (m + 1) * (m + 2) >> 1;
+ mp_limb_t m34 = (m + 3) * (m + 4) >> 1;
+ return m012 * m34;
+}
+
+static mp_limb_t
+mul6 (mp_limb_t m)
+{
+ mp_limb_t m01 = (m + 0) * (m + 1);
+ mp_limb_t m23 = (m + 2) * (m + 3);
+ mp_limb_t m45 = (m + 4) * (m + 5) >> 1;
+ mp_limb_t m0123 = m01 * m23 >> 3;
+ return m0123 * m45;
+}
+
+static mp_limb_t
+mul7 (mp_limb_t m)
+{
+ mp_limb_t m01 = (m + 0) * (m + 1);
+ mp_limb_t m23 = (m + 2) * (m + 3);
+ mp_limb_t m456 = (m + 4) * (m + 5) * (m + 6) >> 1;
+ mp_limb_t m0123 = m01 * m23 >> 3;
+ return m0123 * m456;
+}
+
+static mp_limb_t
+mul8 (mp_limb_t m)
+{
+ mp_limb_t m01 = (m + 0) * (m + 1);
+ mp_limb_t m23 = (m + 2) * (m + 3);
+ mp_limb_t m45 = (m + 4) * (m + 5);
+ mp_limb_t m67 = (m + 6) * (m + 7);
+ mp_limb_t m0123 = m01 * m23 >> 3;
+ mp_limb_t m4567 = m45 * m67 >> 3;
+ return m0123 * m4567;
+}
+
+typedef mp_limb_t (* mulfunc_t) (mp_limb_t);
+
+static const mulfunc_t mulfunc[] = {mul1,mul2,mul3,mul4,mul5,mul6,mul7,mul8};
+#define M (numberof(mulfunc))
+
+/* Number of factors-of-2 removed by the corresponding mulN function. */
+static const unsigned char tcnttab[] = {0, 1, 1, 2, 2, 4, 4, 6};
+
+#if 1
+/* This variant is inaccurate but share the code with other functions. */
+#define MAXFACS(max,l) \
+ do { \
+ (max) = log_n_max (l); \
+ } while (0)
+#else
+
+/* This variant is exact(?) but uses a loop. It takes the 2 removal
+ of mulN into account. */
+static const unsigned long ftab[] =
+#if GMP_NUMB_BITS == 64
+ /* 1 to 8 factors per iteration */
+ {CNST_LIMB(0xffffffffffffffff),CNST_LIMB(0x100000000),0x32cbfe,0x16a0b,0x24c4,0xa16,0x34b,0x1b2 /*,0xdf,0x8d */};
+#endif
+#if GMP_NUMB_BITS == 32
+ /* 1 to 7 factors per iteration */
+ {0xffffffff,0x10000,0x801,0x16b,0x71,0x42,0x26 /* ,0x1e */};
+#endif
+
+#define MAXFACS(max,l) \
+ do { \
+ int __i; \
+ for (__i = numberof (ftab) - 1; l > ftab[__i]; __i--) \
+ ; \
+ (max) = __i + 1; \
+ } while (0)
+#endif
+
+/* Entry i contains (i!/2^t)^(-1) where t is chosen such that the parenthesis
+ is an odd integer. */
+static const mp_limb_t facinv[] = { ONE_LIMB_ODD_FACTORIAL_INVERSES_TABLE };
+
+static void
+mpz_bdiv_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
+{
+ int nmax, kmax, nmaxnow, numfac;
+ mp_ptr np, kp;
+ mp_size_t nn, kn, alloc;
+ mp_limb_t i, j, t, iii, jjj, cy, dinv;
+ mp_bitcnt_t i2cnt, j2cnt;
+ int cnt;
+ mp_size_t maxn;
+ TMP_DECL;
+
+ ASSERT (k > ODD_FACTORIAL_TABLE_LIMIT);
+ TMP_MARK;
+
+ maxn = 1 + n / GMP_NUMB_BITS; /* absolutely largest result size (limbs) */
+
+ /* FIXME: This allocation might be insufficient, but is usually way too
+ large. */
+ alloc = SOME_THRESHOLD - 1 + MAX (3 * maxn / 2, SOME_THRESHOLD);
+ alloc = MIN (alloc, k) + 1;
+ np = TMP_ALLOC_LIMBS (alloc);
+ kp = TMP_ALLOC_LIMBS (SOME_THRESHOLD + 1);
+
+ MAXFACS (nmax, n);
+ ASSERT (nmax <= M);
+ MAXFACS (kmax, k);
+ ASSERT (kmax <= M);
+ ASSERT (k >= M);
+
+ i = n - k + 1;
+
+ np[0] = 1; nn = 1;
+
+ i2cnt = 0; /* total low zeros in dividend */
+ j2cnt = __gmp_fac2cnt_table[ODD_FACTORIAL_TABLE_LIMIT / 2 - 1];
+ /* total low zeros in divisor */
+
+ numfac = 1;
+ j = ODD_FACTORIAL_TABLE_LIMIT + 1;
+ jjj = ODD_FACTORIAL_TABLE_MAX;
+ ASSERT (__gmp_oddfac_table[ODD_FACTORIAL_TABLE_LIMIT] == ODD_FACTORIAL_TABLE_MAX);
+
+ while (1)
+ {
+ kp[0] = jjj; /* store new factors */
+ kn = 1;
+ t = k - j + 1;
+ kmax = MIN (kmax, t);
+
+ while (kmax != 0 && kn < SOME_THRESHOLD)
+ {
+ jjj = mulfunc[kmax - 1] (j);
+ j += kmax; /* number of factors used */
+ count_trailing_zeros (cnt, jjj); /* count low zeros */
+ jjj >>= cnt; /* remove remaining low zeros */
+ j2cnt += tcnttab[kmax - 1] + cnt; /* update low zeros count */
+ cy = mpn_mul_1 (kp, kp, kn, jjj); /* accumulate new factors */
+ kp[kn] = cy;
+ kn += cy != 0;
+ t = k - j + 1;
+ kmax = MIN (kmax, t);
+ }
+ numfac = j - numfac;
+
+ while (numfac != 0)
+ {
+ nmaxnow = MIN (nmax, numfac);
+ iii = mulfunc[nmaxnow - 1] (i);
+ i += nmaxnow; /* number of factors used */
+ count_trailing_zeros (cnt, iii); /* count low zeros */
+ iii >>= cnt; /* remove remaining low zeros */
+ i2cnt += tcnttab[nmaxnow - 1] + cnt; /* update low zeros count */
+ cy = mpn_mul_1 (np, np, nn, iii); /* accumulate new factors */
+ np[nn] = cy;
+ nn += cy != 0;
+ numfac -= nmaxnow;
+ }
+
+ ASSERT (nn < alloc);
+
+ binvert_limb (dinv, kp[0]);
+ nn += (np[nn - 1] >= kp[kn - 1]);
+ nn -= kn;
+ mpn_sbpi1_bdiv_q (np, np, nn, kp, MIN(kn,nn), -dinv);
+
+ if (kmax == 0)
+ break;
+ numfac = j;
+
+ jjj = mulfunc[kmax - 1] (j);
+ j += kmax; /* number of factors used */
+ count_trailing_zeros (cnt, jjj); /* count low zeros */
+ jjj >>= cnt; /* remove remaining low zeros */
+ j2cnt += tcnttab[kmax - 1] + cnt; /* update low zeros count */
+ }
+
+ /* Put back the right number of factors of 2. */
+ cnt = i2cnt - j2cnt;
+ if (cnt != 0)
+ {
+ ASSERT (cnt < GMP_NUMB_BITS); /* can happen, but not for intended use */
+ cy = mpn_lshift (np, np, nn, cnt);
+ np[nn] = cy;
+ nn += cy != 0;
+ }
+
+ nn -= np[nn - 1] == 0; /* normalisation */
+
+ kp = MPZ_NEWALLOC (r, nn);
+ SIZ(r) = nn;
+ MPN_COPY (kp, np, nn);
+ TMP_FREE;
+}
+
+static void
+mpz_smallk_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
+{
+ int nmax, numfac;
+ mp_ptr rp;
+ mp_size_t rn, alloc;
+ mp_limb_t i, iii, cy;
+ mp_bitcnt_t i2cnt, cnt;
+
+ count_leading_zeros (cnt, (mp_limb_t) n);
+ cnt = GMP_LIMB_BITS - cnt;
+ alloc = cnt * k / GMP_NUMB_BITS + 3; /* FIXME: ensure rounding is enough. */
+ rp = MPZ_NEWALLOC (r, alloc);
+
+ MAXFACS (nmax, n);
+ nmax = MIN (nmax, M);
+
+ i = n - k + 1;
+
+ nmax = MIN (nmax, k);
+ rp[0] = mulfunc[nmax - 1] (i);
+ rn = 1;
+ i += nmax; /* number of factors used */
+ i2cnt = tcnttab[nmax - 1]; /* low zeros count */
+ numfac = k - nmax;
+ while (numfac != 0)
+ {
+ nmax = MIN (nmax, numfac);
+ iii = mulfunc[nmax - 1] (i);
+ i += nmax; /* number of factors used */
+ i2cnt += tcnttab[nmax - 1]; /* update low zeros count */
+ cy = mpn_mul_1 (rp, rp, rn, iii); /* accumulate new factors */
+ rp[rn] = cy;
+ rn += cy != 0;
+ numfac -= nmax;
+ }
+
+ ASSERT (rn < alloc);
+
+ mpn_pi1_bdiv_q_1 (rp, rp, rn, __gmp_oddfac_table[k], facinv[k - 2],
+ __gmp_fac2cnt_table[k / 2 - 1] - i2cnt);
+ /* A two-fold, branch-free normalisation is possible :*/
+ /* rn -= rp[rn - 1] == 0; */
+ /* rn -= rp[rn - 1] == 0; */
+ MPN_NORMALIZE_NOT_ZERO (rp, rn);
+
+ SIZ(r) = rn;
+}
+
+/* Algorithm:
+
+ Plain and simply multiply things together.
+
+ We tabulate factorials (k!/2^t)^(-1) mod B (where t is chosen such
+ that k!/2^t is odd).
+
+*/
+
+static mp_limb_t
+bc_bin_uiui (unsigned int n, unsigned int k)
+{
+ return ((__gmp_oddfac_table[n] * facinv[k - 2] * facinv[n - k - 2])
+ << (__gmp_fac2cnt_table[n / 2 - 1] - __gmp_fac2cnt_table[k / 2 - 1] - __gmp_fac2cnt_table[(n-k) / 2 - 1]))
+ & GMP_NUMB_MASK;
+}
+
+/* Algorithm:
+
+ Recursively exploit the relation
+ bin(n,k) = bin(n,k>>1)*bin(n-k>>1,k-k>>1)/bin(k,k>>1) .
+
+ Values for binomial(k,k>>1) that fit in a limb are precomputed
+ (with inverses).
+*/
+
+/* bin2kk[i - ODD_CENTRAL_BINOMIAL_OFFSET] =
+ binomial(i*2,i)/2^t (where t is chosen so that it is odd). */
+static const mp_limb_t bin2kk[] = { ONE_LIMB_ODD_CENTRAL_BINOMIAL_TABLE };
+
+/* bin2kkinv[i] = bin2kk[i]^-1 mod B */
+static const mp_limb_t bin2kkinv[] = { ONE_LIMB_ODD_CENTRAL_BINOMIAL_INVERSE_TABLE };
+
+/* bin2kk[i] = binomial((i+MIN_S)*2,i+MIN_S)/2^t. This table contains the t values. */
+static const unsigned char fac2bin[] = { CENTRAL_BINOMIAL_2FAC_TABLE };
+
+static void
+mpz_smallkdc_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
+{
+ mp_ptr rp;
+ mp_size_t rn;
+ unsigned long int hk;
+
+ hk = k >> 1;
+
+ if ((! BIN_UIUI_RECURSIVE_SMALLDC) || hk <= ODD_FACTORIAL_TABLE_LIMIT)
+ mpz_smallk_bin_uiui (r, n, hk);
+ else
+ mpz_smallkdc_bin_uiui (r, n, hk);
+ k -= hk;
+ n -= hk;
+ if (n <= ODD_FACTORIAL_EXTTABLE_LIMIT) {
+ mp_limb_t cy;
+ rn = SIZ (r);
+ rp = MPZ_REALLOC (r, rn + 1);
+ cy = mpn_mul_1 (rp, rp, rn, bc_bin_uiui (n, k));
+ rp [rn] = cy;
+ rn += cy != 0;
+ } else {
+ mp_limb_t buffer[ODD_CENTRAL_BINOMIAL_TABLE_LIMIT + 3];
+ mpz_t t;
+
+ ALLOC (t) = ODD_CENTRAL_BINOMIAL_TABLE_LIMIT + 3;
+ PTR (t) = buffer;
+ if ((! BIN_UIUI_RECURSIVE_SMALLDC) || k <= ODD_FACTORIAL_TABLE_LIMIT)
+ mpz_smallk_bin_uiui (t, n, k);
+ else
+ mpz_smallkdc_bin_uiui (t, n, k);
+ mpz_mul (r, r, t);
+ rp = PTR (r);
+ rn = SIZ (r);
+ }
+
+ mpn_pi1_bdiv_q_1 (rp, rp, rn, bin2kk[k - ODD_CENTRAL_BINOMIAL_OFFSET],
+ bin2kkinv[k - ODD_CENTRAL_BINOMIAL_OFFSET],
+ fac2bin[k - ODD_CENTRAL_BINOMIAL_OFFSET] - (k != hk));
+ /* A two-fold, branch-free normalisation is possible :*/
+ /* rn -= rp[rn - 1] == 0; */
+ /* rn -= rp[rn - 1] == 0; */
+ MPN_NORMALIZE_NOT_ZERO (rp, rn);
+
+ SIZ(r) = rn;
+}
+
+/* mpz_goetgheluck_bin_uiui(RESULT, N, K) -- Set RESULT to binomial(N,K).
+ *
+ * Contributed to the GNU project by Marco Bodrato.
+ *
+ * Implementation of the algorithm by P. Goetgheluck, "Computing
+ * Binomial Coefficients", The American Mathematical Monthly, Vol. 94,
+ * No. 4 (April 1987), pp. 360-365.
+ *
+ * Acknowledgment: Peter Luschny did spot the slowness of the previous
+ * code and suggested the reference.
+ */
+
+/* TODO: Remove duplicated constants / macros / static functions...
+ */
+
+/*************************************************************/
+/* Section macros: common macros, for swing/fac/bin (&sieve) */
+/*************************************************************/
+
+#define FACTOR_LIST_APPEND(PR, MAX_PR, VEC, I) \
+ if ((PR) > (MAX_PR)) { \
+ (VEC)[(I)++] = (PR); \
+ (PR) = 1; \
+ }
+
+#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \
+ do { \
+ if ((PR) > (MAX_PR)) { \
+ (VEC)[(I)++] = (PR); \
+ (PR) = (P); \
+ } else \
+ (PR) *= (P); \
+ } while (0)
+
+#define LOOP_ON_SIEVE_CONTINUE(prime,end,sieve) \
+ __max_i = (end); \
+ \
+ do { \
+ ++__i; \
+ if (((sieve)[__index] & __mask) == 0) \
+ { \
+ (prime) = id_to_n(__i)
+
+#define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve) \
+ do { \
+ mp_limb_t __mask, __index, __max_i, __i; \
+ \
+ __i = (start)-(off); \
+ __index = __i / GMP_LIMB_BITS; \
+ __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS); \
+ __i += (off); \
+ \
+ LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)
+
+#define LOOP_ON_SIEVE_STOP \
+ } \
+ __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1); \
+ __index += __mask & 1; \
+ } while (__i <= __max_i) \
+
+#define LOOP_ON_SIEVE_END \
+ LOOP_ON_SIEVE_STOP; \
+ } while (0)
+
+/*********************************************************/
+/* Section sieve: sieving functions and tools for primes */
+/*********************************************************/
+
+#if WANT_ASSERT
+static mp_limb_t
+bit_to_n (mp_limb_t bit) { return (bit*3+4)|1; }
+#endif
+
+/* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/
+static mp_limb_t
+id_to_n (mp_limb_t id) { return id*3+1+(id&1); }
+
+/* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */
+static mp_limb_t
+n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; }
+
+static mp_size_t
+primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; }
+
+/*********************************************************/
+/* Section binomial: fast binomial implementation */
+/*********************************************************/
+
+#define COUNT_A_PRIME(P, N, K, PR, MAX_PR, VEC, I) \
+ do { \
+ mp_limb_t __a, __b, __prime, __ma,__mb; \
+ __prime = (P); \
+ __a = (N); __b = (K); __mb = 0; \
+ FACTOR_LIST_APPEND(PR, MAX_PR, VEC, I); \
+ do { \
+ __mb += __b % __prime; __b /= __prime; \
+ __ma = __a % __prime; __a /= __prime; \
+ if (__ma < __mb) { \
+ __mb = 1; (PR) *= __prime; \
+ } else __mb = 0; \
+ } while (__a >= __prime); \
+ } while (0)
+
+#define SH_COUNT_A_PRIME(P, N, K, PR, MAX_PR, VEC, I) \
+ do { \
+ mp_limb_t __prime; \
+ __prime = (P); \
+ if (((N) % __prime) < ((K) % __prime)) { \
+ FACTOR_LIST_STORE (__prime, PR, MAX_PR, VEC, I); \
+ } \
+ } while (0)
+
+/* Returns an approximation of the sqare root of x. *
+ * It gives: x <= limb_apprsqrt (x) ^ 2 < x * 9/4 */
+static mp_limb_t
+limb_apprsqrt (mp_limb_t x)
+{
+ int s;
+
+ ASSERT (x > 2);
+ count_leading_zeros (s, x - 1);
+ s = GMP_LIMB_BITS - 1 - s;
+ return (CNST_LIMB(1) << (s >> 1)) + (CNST_LIMB(1) << ((s - 1) >> 1));
+}
+
+static void
+mpz_goetgheluck_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
+{
+ mp_limb_t *sieve, *factors, count;
+ mp_limb_t prod, max_prod, j;
+ TMP_DECL;
+
+ ASSERT (BIN_GOETGHELUCK_THRESHOLD >= 13);
+ ASSERT (n >= 25);
+
+ TMP_MARK;
+ sieve = TMP_ALLOC_LIMBS (primesieve_size (n));
+
+ count = gmp_primesieve (sieve, n) + 1;
+ factors = TMP_ALLOC_LIMBS (count / log_n_max (n) + 1);
+
+ max_prod = GMP_NUMB_MAX / n;
+
+ /* Handle primes = 2, 3 separately. */
+ popc_limb (count, n - k);
+ popc_limb (j, k);
+ count += j;
+ popc_limb (j, n);
+ count -= j;
+ prod = CNST_LIMB(1) << count;
+
+ j = 0;
+ COUNT_A_PRIME (3, n, k, prod, max_prod, factors, j);
+
+ /* Accumulate prime factors from 5 to n/2 */
+ {
+ mp_limb_t s;
+
+ {
+ mp_limb_t prime;
+ s = limb_apprsqrt(n);
+ s = n_to_bit (s);
+ LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (5), s, 0,sieve);
+ COUNT_A_PRIME (prime, n, k, prod, max_prod, factors, j);
+ LOOP_ON_SIEVE_END;
+ s++;
+ }
+
+ ASSERT (max_prod <= GMP_NUMB_MAX / 2);
+ max_prod <<= 1;
+ ASSERT (bit_to_n (s) * bit_to_n (s) > n);
+ ASSERT (s <= n_to_bit (n >> 1));
+ {
+ mp_limb_t prime;
+
+ LOOP_ON_SIEVE_BEGIN (prime, s, n_to_bit (n >> 1), 0,sieve);
+ SH_COUNT_A_PRIME (prime, n, k, prod, max_prod, factors, j);
+ LOOP_ON_SIEVE_END;
+ }
+ max_prod >>= 1;
+ }
+
+ /* Store primes from (n-k)+1 to n */
+ ASSERT (n_to_bit (n - k) < n_to_bit (n));
+ {
+ mp_limb_t prime;
+ LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (n - k) + 1, n_to_bit (n), 0,sieve);
+ FACTOR_LIST_STORE (prime, prod, max_prod, factors, j);
+ LOOP_ON_SIEVE_END;
+ }
+
+ if (LIKELY (j != 0))
+ {
+ factors[j++] = prod;
+ mpz_prodlimbs (r, factors, j);
+ }
+ else
+ {
+ PTR (r)[0] = prod;
+ SIZ (r) = 1;
+ }
+ TMP_FREE;
+}
+
+#undef COUNT_A_PRIME
+#undef SH_COUNT_A_PRIME
+#undef LOOP_ON_SIEVE_END
+#undef LOOP_ON_SIEVE_STOP
+#undef LOOP_ON_SIEVE_BEGIN
+#undef LOOP_ON_SIEVE_CONTINUE
+
+/*********************************************************/
+/* End of implementation of Goetgheluck's algorithm */
+/*********************************************************/
+
+void
+mpz_bin_uiui (mpz_ptr r, unsigned long int n, unsigned long int k)
+{
+ if (UNLIKELY (n < k)) {
+ SIZ (r) = 0;
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ } else if (UNLIKELY (n > GMP_NUMB_MAX)) {
+ mpz_t tmp;
+
+ mpz_init_set_ui (tmp, n);
+ mpz_bin_ui (r, tmp, k);
+ mpz_clear (tmp);
+#endif
+ } else {
+ ASSERT (n <= GMP_NUMB_MAX);
+ /* Rewrite bin(n,k) as bin(n,n-k) if that is smaller. */
+ k = MIN (k, n - k);
+ if (k < 2) {
+ PTR(r)[0] = k ? n : 1; /* 1 + ((-k) & (n-1)); */
+ SIZ(r) = 1;
+ } else if (n <= ODD_FACTORIAL_EXTTABLE_LIMIT) { /* k >= 2, n >= 4 */
+ PTR(r)[0] = bc_bin_uiui (n, k);
+ SIZ(r) = 1;
+ } else if (k <= ODD_FACTORIAL_TABLE_LIMIT)
+ mpz_smallk_bin_uiui (r, n, k);
+ else if (BIN_UIUI_ENABLE_SMALLDC &&
+ k <= (BIN_UIUI_RECURSIVE_SMALLDC ? ODD_CENTRAL_BINOMIAL_TABLE_LIMIT : ODD_FACTORIAL_TABLE_LIMIT)* 2)
+ mpz_smallkdc_bin_uiui (r, n, k);
+ else if (ABOVE_THRESHOLD (k, BIN_GOETGHELUCK_THRESHOLD) &&
+ k > (n >> 4)) /* k > ODD_FACTORIAL_TABLE_LIMIT */
+ mpz_goetgheluck_bin_uiui (r, n, k);
+ else
+ mpz_bdiv_bin_uiui (r, n, k);
+ }
+}
diff --git a/gmp/mpz/cdiv_q.c b/gmp/mpz/cdiv_q.c
new file mode 100644
index 0000000000..32e3200a8d
--- /dev/null
+++ b/gmp/mpz/cdiv_q.c
@@ -0,0 +1,53 @@
+/* mpz_cdiv_q -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator.
+
+Copyright 1994-1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_cdiv_q (mpz_ptr quot, mpz_srcptr dividend, mpz_srcptr divisor)
+{
+ mp_size_t dividend_size = SIZ (dividend);
+ mp_size_t divisor_size = SIZ (divisor);
+ mpz_t rem;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ MPZ_TMP_INIT (rem, ABS (divisor_size));
+
+ mpz_tdiv_qr (quot, rem, dividend, divisor);
+
+ if ((divisor_size ^ dividend_size) >= 0 && SIZ (rem) != 0)
+ mpz_add_ui (quot, quot, 1L);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/cdiv_q_ui.c b/gmp/mpz/cdiv_q_ui.c
new file mode 100644
index 0000000000..63608c9043
--- /dev/null
+++ b/gmp/mpz/cdiv_q_ui.c
@@ -0,0 +1,103 @@
+/* mpz_cdiv_q_ui -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator. In order to make it
+ always fit into the return type, the negative of the true remainder is
+ returned.
+
+Copyright 1994, 1996, 1999, 2001, 2002, 2004, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_cdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn, qn;
+ mp_ptr np, qp;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(quot) = 0;
+ return 0;
+ }
+
+ nn = ABS(ns);
+ qp = MPZ_REALLOC (quot, nn);
+ np = PTR(dividend);
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2], rp[2];
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ qp[0] = 0;
+ rl = np[0];
+ qn = 1; /* a white lie, fixed below */
+ }
+ else
+ {
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ qn = nn - 2 + 1;
+ }
+
+ if (rl != 0 && ns >= 0)
+ {
+ mpn_incr_u (qp, (mp_limb_t) 1);
+ rl = divisor - rl;
+ }
+
+ qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0;
+ }
+ else
+#endif
+ {
+ rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor);
+
+ if (rl != 0 && ns >= 0)
+ {
+ mpn_incr_u (qp, (mp_limb_t) 1);
+ rl = divisor - rl;
+ }
+
+ qn = nn - (qp[nn - 1] == 0);
+ }
+
+ SIZ(quot) = ns >= 0 ? qn : -qn;
+ return rl;
+}
diff --git a/gmp/mpz/cdiv_qr.c b/gmp/mpz/cdiv_qr.c
new file mode 100644
index 0000000000..45e9a2774c
--- /dev/null
+++ b/gmp/mpz/cdiv_qr.c
@@ -0,0 +1,65 @@
+/* mpz_cdiv_qr -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator.
+
+Copyright 1994-1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_cdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+{
+ mp_size_t divisor_size = SIZ (divisor);
+ mp_size_t xsize;
+ mpz_t temp_divisor; /* N.B.: lives until function returns! */
+ TMP_DECL;
+
+ TMP_MARK;
+
+ /* We need the original value of the divisor after the quotient and
+ remainder have been preliminary calculated. We have to copy it to
+ temporary space if it's the same variable as either QUOT or REM. */
+ if (quot == divisor || rem == divisor)
+ {
+ MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
+ mpz_set (temp_divisor, divisor);
+ divisor = temp_divisor;
+ }
+
+ xsize = SIZ (dividend) ^ divisor_size;;
+ mpz_tdiv_qr (quot, rem, dividend, divisor);
+
+ if (xsize >= 0 && SIZ (rem) != 0)
+ {
+ mpz_add_ui (quot, quot, 1L);
+ mpz_sub (rem, rem, divisor);
+ }
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/cdiv_qr_ui.c b/gmp/mpz/cdiv_qr_ui.c
new file mode 100644
index 0000000000..1ccfbbe7fd
--- /dev/null
+++ b/gmp/mpz/cdiv_qr_ui.c
@@ -0,0 +1,119 @@
+/* mpz_cdiv_qr_ui -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator. In order to make it
+ always fit into the return type, the negative of the true remainder is
+ returned.
+
+Copyright 1994-1996, 1999, 2001, 2002, 2004, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_cdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn, qn;
+ mp_ptr np, qp;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(quot) = 0;
+ SIZ(rem) = 0;
+ return 0;
+ }
+
+ nn = ABS(ns);
+ qp = MPZ_REALLOC (quot, nn);
+ np = PTR(dividend);
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2];
+ mp_ptr rp;
+ mp_size_t rn;
+
+ rp = MPZ_REALLOC (rem, 2);
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ qp[0] = 0;
+ qn = 1; /* a white lie, fixed below */
+ rl = np[0];
+ rp[0] = rl;
+ }
+ else
+ {
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ qn = nn - 2 + 1;
+ }
+
+ if (rl != 0 && ns >= 0)
+ {
+ mpn_incr_u (qp, (mp_limb_t) 1);
+ rl = divisor - rl;
+ rp[0] = rl & GMP_NUMB_MASK;
+ rp[1] = rl >> GMP_NUMB_BITS;
+ }
+
+ qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0;
+ rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0);
+ SIZ(rem) = -rn;
+ }
+ else
+#endif
+ {
+ rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ SIZ(rem) = 0;
+ else
+ {
+ if (ns >= 0)
+ {
+ mpn_incr_u (qp, (mp_limb_t) 1);
+ rl = divisor - rl;
+ }
+
+ PTR(rem)[0] = rl;
+ SIZ(rem) = -(rl != 0);
+ }
+ qn = nn - (qp[nn - 1] == 0);
+ }
+
+ SIZ(quot) = ns >= 0 ? qn : -qn;
+ return rl;
+}
diff --git a/gmp/mpz/cdiv_r.c b/gmp/mpz/cdiv_r.c
new file mode 100644
index 0000000000..9cebab3e06
--- /dev/null
+++ b/gmp/mpz/cdiv_r.c
@@ -0,0 +1,61 @@
+/* mpz_cdiv_r -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator.
+
+Copyright 1994-1996, 2001, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_cdiv_r (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+{
+ mp_size_t divisor_size = SIZ (divisor);
+ mpz_t temp_divisor; /* N.B.: lives until function returns! */
+ TMP_DECL;
+
+ TMP_MARK;
+
+ /* We need the original value of the divisor after the remainder has been
+ preliminary calculated. We have to copy it to temporary space if it's
+ the same variable as REM. */
+ if (rem == divisor)
+ {
+
+ MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
+ mpz_set (temp_divisor, divisor);
+ divisor = temp_divisor;
+ }
+
+ mpz_tdiv_r (rem, dividend, divisor);
+
+ if ((divisor_size ^ SIZ (dividend)) >= 0 && SIZ (rem) != 0)
+ mpz_sub (rem, rem, divisor);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/cdiv_r_ui.c b/gmp/mpz/cdiv_r_ui.c
new file mode 100644
index 0000000000..68fb149c46
--- /dev/null
+++ b/gmp/mpz/cdiv_r_ui.c
@@ -0,0 +1,110 @@
+/* mpz_cdiv_r_ui -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator. In order to make it
+ always fit into the return type, the negative of the true remainder is
+ returned.
+
+Copyright 1994-1996, 2001, 2002, 2004, 2005, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_cdiv_r_ui (mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn;
+ mp_ptr np;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(rem) = 0;
+ return 0;
+ }
+
+ nn = ABS(ns);
+ np = PTR(dividend);
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2];
+ mp_ptr rp, qp;
+ mp_size_t rn;
+ TMP_DECL;
+
+ rp = MPZ_REALLOC (rem, 2);
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ rl = np[0];
+ rp[0] = rl;
+ }
+ else
+ {
+ TMP_MARK;
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ qp = TMP_ALLOC_LIMBS (nn - 2 + 1);
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ TMP_FREE;
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ }
+
+ if (rl != 0 && ns >= 0)
+ {
+ rl = divisor - rl;
+ rp[0] = rl & GMP_NUMB_MASK;
+ rp[1] = rl >> GMP_NUMB_BITS;
+ }
+
+ rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0);
+ SIZ(rem) = -rn;
+ }
+ else
+#endif
+ {
+ rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ SIZ(rem) = 0;
+ else
+ {
+ if (ns >= 0)
+ rl = divisor - rl;
+
+ PTR(rem)[0] = rl;
+ SIZ(rem) = -1;
+ }
+ }
+
+ return rl;
+}
diff --git a/gmp/mpz/cdiv_ui.c b/gmp/mpz/cdiv_ui.c
new file mode 100644
index 0000000000..1f7f6e3c1b
--- /dev/null
+++ b/gmp/mpz/cdiv_ui.c
@@ -0,0 +1,103 @@
+/* mpz_cdiv_ui -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator. In order to make it
+ always fit into the return type, the negative of the true remainder is
+ returned.
+
+Copyright 1994-1996, 2001, 2002, 2004, 2005, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_cdiv_ui (mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn;
+ mp_ptr np;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ return 0;
+ }
+
+ nn = ABS(ns);
+ np = PTR(dividend);
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2], rp[2];
+ mp_ptr qp;
+ mp_size_t rn;
+ TMP_DECL;
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ rl = np[0];
+ rp[0] = rl;
+ }
+ else
+ {
+ TMP_MARK;
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ qp = TMP_ALLOC_LIMBS (nn - 2 + 1);
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ TMP_FREE;
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ }
+
+ if (rl != 0 && ns >= 0)
+ {
+ rl = divisor - rl;
+ rp[0] = rl & GMP_NUMB_MASK;
+ rp[1] = rl >> GMP_NUMB_BITS;
+ }
+
+ rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0);
+ }
+ else
+#endif
+ {
+ rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ ;
+ else
+ {
+ if (ns >= 0)
+ rl = divisor - rl;
+ }
+ }
+
+ return rl;
+}
diff --git a/gmp/mpz/cfdiv_q_2exp.c b/gmp/mpz/cfdiv_q_2exp.c
new file mode 100644
index 0000000000..c69e37c605
--- /dev/null
+++ b/gmp/mpz/cfdiv_q_2exp.c
@@ -0,0 +1,113 @@
+/* mpz_cdiv_q_2exp, mpz_fdiv_q_2exp -- quotient from mpz divided by 2^n.
+
+Copyright 1991, 1993, 1994, 1996, 1998, 1999, 2001, 2002, 2004, 2012 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* dir==1 for ceil, dir==-1 for floor */
+
+static void __gmpz_cfdiv_q_2exp (REGPARM_3_1 (mpz_ptr, mpz_srcptr, mp_bitcnt_t, int)) REGPARM_ATTR (1);
+#define cfdiv_q_2exp(w,u,cnt,dir) __gmpz_cfdiv_q_2exp (REGPARM_3_1 (w,u,cnt,dir))
+
+REGPARM_ATTR (1) static void
+cfdiv_q_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt, int dir)
+{
+ mp_size_t wsize, usize, abs_usize, limb_cnt, i;
+ mp_srcptr up;
+ mp_ptr wp;
+ mp_limb_t round, rmask;
+
+ usize = SIZ (u);
+ abs_usize = ABS (usize);
+ limb_cnt = cnt / GMP_NUMB_BITS;
+ wsize = abs_usize - limb_cnt;
+ if (wsize <= 0)
+ {
+ /* u < 2**cnt, so result 1, 0 or -1 according to rounding */
+ PTR(w)[0] = 1;
+ SIZ(w) = (usize == 0 || (usize ^ dir) < 0 ? 0 : dir);
+ return;
+ }
+
+ /* +1 limb to allow for mpn_add_1 below */
+ MPZ_REALLOC (w, wsize+1);
+
+ /* Check for rounding if direction matches u sign.
+ Set round if we're skipping non-zero limbs. */
+ up = PTR(u);
+ round = 0;
+ rmask = ((usize ^ dir) >= 0 ? MP_LIMB_T_MAX : 0);
+ if (rmask != 0)
+ for (i = 0; i < limb_cnt && round == 0; i++)
+ round = up[i];
+
+ wp = PTR(w);
+ cnt %= GMP_NUMB_BITS;
+ if (cnt != 0)
+ {
+ round |= rmask & mpn_rshift (wp, up + limb_cnt, wsize, cnt);
+ wsize -= (wp[wsize - 1] == 0);
+ }
+ else
+ MPN_COPY_INCR (wp, up + limb_cnt, wsize);
+
+ if (round != 0)
+ {
+ if (wsize != 0)
+ {
+ mp_limb_t cy;
+ cy = mpn_add_1 (wp, wp, wsize, CNST_LIMB(1));
+ wp[wsize] = cy;
+ wsize += cy;
+ }
+ else
+ {
+ /* We shifted something to zero. */
+ wp[0] = 1;
+ wsize = 1;
+ }
+ }
+ SIZ(w) = (usize >= 0 ? wsize : -wsize);
+}
+
+
+void
+mpz_cdiv_q_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt)
+{
+ cfdiv_q_2exp (w, u, cnt, 1);
+}
+
+void
+mpz_fdiv_q_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt)
+{
+ cfdiv_q_2exp (w, u, cnt, -1);
+}
diff --git a/gmp/mpz/cfdiv_r_2exp.c b/gmp/mpz/cfdiv_r_2exp.c
new file mode 100644
index 0000000000..5466691f29
--- /dev/null
+++ b/gmp/mpz/cfdiv_r_2exp.c
@@ -0,0 +1,164 @@
+/* mpz_cdiv_r_2exp, mpz_fdiv_r_2exp -- remainder from mpz divided by 2^n.
+
+Copyright 2001, 2002, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Bit mask of "n" least significant bits of a limb. */
+#define LOW_MASK(n) ((CNST_LIMB(1) << (n)) - 1)
+
+
+/* dir==1 for ceil, dir==-1 for floor */
+
+static void __gmpz_cfdiv_r_2exp (REGPARM_3_1 (mpz_ptr, mpz_srcptr, mp_bitcnt_t, int)) REGPARM_ATTR (1);
+#define cfdiv_r_2exp(w,u,cnt,dir) __gmpz_cfdiv_r_2exp (REGPARM_3_1 (w, u, cnt, dir))
+
+REGPARM_ATTR (1) static void
+cfdiv_r_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt, int dir)
+{
+ mp_size_t usize, abs_usize, limb_cnt, i;
+ mp_srcptr up;
+ mp_ptr wp;
+ mp_limb_t high;
+
+ usize = SIZ(u);
+ if (usize == 0)
+ {
+ SIZ(w) = 0;
+ return;
+ }
+
+ limb_cnt = cnt / GMP_NUMB_BITS;
+ cnt %= GMP_NUMB_BITS;
+ abs_usize = ABS (usize);
+
+ /* MPZ_REALLOC(w) below is only when w!=u, so we can fetch PTR(u) here
+ nice and early */
+ up = PTR(u);
+
+ if ((usize ^ dir) < 0)
+ {
+ /* Round towards zero, means just truncate */
+
+ if (w == u)
+ {
+ /* if already smaller than limb_cnt then do nothing */
+ if (abs_usize <= limb_cnt)
+ return;
+ wp = PTR(w);
+ }
+ else
+ {
+ i = MIN (abs_usize, limb_cnt+1);
+ wp = MPZ_REALLOC (w, i);
+ MPN_COPY (wp, up, i);
+
+ /* if smaller than limb_cnt then only the copy is needed */
+ if (abs_usize <= limb_cnt)
+ {
+ SIZ(w) = usize;
+ return;
+ }
+ }
+ }
+ else
+ {
+ /* Round away from zero, means twos complement if non-zero */
+
+ /* if u!=0 and smaller than divisor, then must negate */
+ if (abs_usize <= limb_cnt)
+ goto negate;
+
+ /* if non-zero low limb, then must negate */
+ for (i = 0; i < limb_cnt; i++)
+ if (up[i] != 0)
+ goto negate;
+
+ /* if non-zero partial limb, then must negate */
+ if ((up[limb_cnt] & LOW_MASK (cnt)) != 0)
+ goto negate;
+
+ /* otherwise low bits of u are zero, so that's the result */
+ SIZ(w) = 0;
+ return;
+
+ negate:
+ /* twos complement negation to get 2**cnt-u */
+
+ wp = MPZ_REALLOC (w, limb_cnt+1);
+ up = PTR(u);
+
+ /* Ones complement */
+ i = MIN (abs_usize, limb_cnt+1);
+ mpn_com (wp, up, i);
+ for ( ; i <= limb_cnt; i++)
+ wp[i] = GMP_NUMB_MAX;
+
+ /* Twos complement. Since u!=0 in the relevant part, the twos
+ complement never gives 0 and a carry, so can use MPN_INCR_U. */
+ MPN_INCR_U (wp, limb_cnt+1, CNST_LIMB(1));
+
+ usize = -usize;
+ }
+
+ /* Mask the high limb */
+ high = wp[limb_cnt];
+ high &= LOW_MASK (cnt);
+ wp[limb_cnt] = high;
+
+ /* Strip any consequent high zeros */
+ while (high == 0)
+ {
+ limb_cnt--;
+ if (limb_cnt < 0)
+ {
+ SIZ(w) = 0;
+ return;
+ }
+ high = wp[limb_cnt];
+ }
+
+ limb_cnt++;
+ SIZ(w) = (usize >= 0 ? limb_cnt : -limb_cnt);
+}
+
+
+void
+mpz_cdiv_r_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt)
+{
+ cfdiv_r_2exp (w, u, cnt, 1);
+}
+
+void
+mpz_fdiv_r_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt)
+{
+ cfdiv_r_2exp (w, u, cnt, -1);
+}
diff --git a/gmp/mpz/clear.c b/gmp/mpz/clear.c
new file mode 100644
index 0000000000..30f626c505
--- /dev/null
+++ b/gmp/mpz/clear.c
@@ -0,0 +1,40 @@
+/* mpz_clear -- de-allocate the space occupied by the dynamic digit space of
+ an integer.
+
+Copyright 1991, 1993-1995, 2000, 2001, 2012, 2014 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_clear (mpz_ptr m)
+{
+ (*__gmp_free_func) (PTR (m), (size_t) ALLOC (m) * GMP_LIMB_BYTES);
+}
diff --git a/gmp/mpz/clears.c b/gmp/mpz/clears.c
new file mode 100644
index 0000000000..193c5ade77
--- /dev/null
+++ b/gmp/mpz/clears.c
@@ -0,0 +1,49 @@
+/* mpz_clears() -- Clear multiple mpz_t variables.
+
+Copyright 2009, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_clears (mpz_ptr x, ...)
+{
+ va_list ap;
+
+ va_start (ap, x);
+
+ while (x != NULL)
+ {
+ (*__gmp_free_func) (PTR (x), (size_t) ALLOC (x) * GMP_LIMB_BYTES);
+ x = va_arg (ap, mpz_ptr);
+ }
+ va_end (ap);
+}
diff --git a/gmp/mpz/clrbit.c b/gmp/mpz/clrbit.c
new file mode 100644
index 0000000000..2475efe1e5
--- /dev/null
+++ b/gmp/mpz/clrbit.c
@@ -0,0 +1,116 @@
+/* mpz_clrbit -- clear a specified bit.
+
+Copyright 1991, 1993-1995, 2001, 2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_clrbit (mpz_ptr d, mp_bitcnt_t bit_idx)
+{
+ mp_size_t dsize = SIZ (d);
+ mp_ptr dp = PTR (d);
+ mp_size_t limb_idx;
+ mp_limb_t mask;
+
+ limb_idx = bit_idx / GMP_NUMB_BITS;
+ mask = CNST_LIMB(1) << (bit_idx % GMP_NUMB_BITS);
+ if (dsize >= 0)
+ {
+ if (limb_idx < dsize)
+ {
+ mp_limb_t dlimb;
+ dlimb = dp[limb_idx] & ~mask;
+ dp[limb_idx] = dlimb;
+
+ if (UNLIKELY ((dlimb == 0) + limb_idx == dsize)) /* dsize == limb_idx + 1 */
+ {
+ /* high limb became zero, must normalize */
+ MPN_NORMALIZE (dp, limb_idx);
+ SIZ (d) = limb_idx;
+ }
+ }
+ else
+ ;
+ }
+ else
+ {
+ /* Simulate two's complement arithmetic, i.e. simulate
+ 1. Set OP = ~(OP - 1) [with infinitely many leading ones].
+ 2. clear the bit.
+ 3. Set OP = ~OP + 1. */
+
+ dsize = -dsize;
+
+ if (limb_idx < dsize)
+ {
+ mp_size_t zero_bound;
+
+ /* No index upper bound on this loop, we're sure there's a non-zero limb
+ sooner or later. */
+ zero_bound = 0;
+ while (dp[zero_bound] == 0)
+ zero_bound++;
+
+ if (limb_idx > zero_bound)
+ {
+ dp[limb_idx] |= mask;
+ }
+ else if (limb_idx == zero_bound)
+ {
+ mp_limb_t dlimb;
+ dlimb = (((dp[limb_idx] - 1) | mask) + 1) & GMP_NUMB_MASK;
+ dp[limb_idx] = dlimb;
+
+ if (dlimb == 0)
+ {
+ /* Increment at limb_idx + 1. Extend the number with a zero limb
+ for simplicity. */
+ dp = MPZ_REALLOC (d, dsize + 1);
+ dp[dsize] = 0;
+ MPN_INCR_U (dp + limb_idx + 1, dsize - limb_idx, 1);
+ dsize += dp[dsize];
+
+ SIZ (d) = -dsize;
+ }
+ }
+ else
+ ;
+ }
+ else
+ {
+ /* Ugh. The bit should be cleared outside of the end of the
+ number. We have to increase the size of the number. */
+ dp = MPZ_REALLOC (d, limb_idx + 1);
+ SIZ (d) = -(limb_idx + 1);
+ MPN_ZERO (dp + dsize, limb_idx - dsize);
+ dp[limb_idx] = mask;
+ }
+ }
+}
diff --git a/gmp/mpz/cmp.c b/gmp/mpz/cmp.c
new file mode 100644
index 0000000000..b8a5eaa765
--- /dev/null
+++ b/gmp/mpz/cmp.c
@@ -0,0 +1,54 @@
+/* mpz_cmp(u,v) -- Compare U, V. Return positive, zero, or negative
+ based on if U > V, U == V, or U < V.
+
+Copyright 1991, 1993, 1994, 1996, 2001, 2002, 2011 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpz_cmp (mpz_srcptr u, mpz_srcptr v) __GMP_NOTHROW
+{
+ mp_size_t usize, vsize, dsize, asize;
+ mp_srcptr up, vp;
+ int cmp;
+
+ usize = SIZ(u);
+ vsize = SIZ(v);
+ dsize = usize - vsize;
+ if (dsize != 0)
+ return dsize;
+
+ asize = ABS (usize);
+ up = PTR(u);
+ vp = PTR(v);
+ MPN_CMP (cmp, up, vp, asize);
+ return (usize >= 0 ? cmp : -cmp);
+}
diff --git a/gmp/mpz/cmp_d.c b/gmp/mpz/cmp_d.c
new file mode 100644
index 0000000000..45926d6d54
--- /dev/null
+++ b/gmp/mpz/cmp_d.c
@@ -0,0 +1,145 @@
+/* mpz_cmp_d -- compare absolute values of mpz and double.
+
+Copyright 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if HAVE_FLOAT_H
+#include <float.h> /* for DBL_MAX */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#define RETURN_CMP(zl, dl) \
+ do { \
+ zlimb = (zl); \
+ dlimb = (dl); \
+ if (zlimb != dlimb) \
+ return (zlimb >= dlimb ? ret : -ret); \
+ } while (0)
+
+#define RETURN_NONZERO(ptr, size, val) \
+ do { \
+ mp_size_t __i; \
+ for (__i = (size)-1; __i >= 0; __i--) \
+ if ((ptr)[__i] != 0) \
+ return val; \
+ return 0; \
+ } while (0)
+
+
+int
+mpz_cmp_d (mpz_srcptr z, double d)
+{
+ mp_limb_t darray[LIMBS_PER_DOUBLE], zlimb, dlimb;
+ mp_srcptr zp;
+ mp_size_t zsize;
+ int dexp, ret;
+
+ /* d=NaN is an invalid operation, there's no sensible return value.
+ d=Inf or -Inf is always bigger than z. */
+ DOUBLE_NAN_INF_ACTION (d, __gmp_invalid_operation (), goto z_zero);
+
+ /* 1. Either operand zero. */
+ zsize = SIZ(z);
+ if (d == 0.0)
+ return zsize;
+ if (zsize == 0)
+ {
+ z_zero:
+ return (d < 0.0 ? 1 : -1);
+ }
+
+ /* 2. Opposite signs. */
+ if (zsize >= 0)
+ {
+ if (d < 0.0)
+ return 1; /* >=0 cmp <0 */
+ ret = 1;
+ }
+ else
+ {
+ if (d >= 0.0)
+ return -1; /* <0 cmp >=0 */
+ ret = -1;
+ d = -d;
+ zsize = -zsize;
+ }
+
+ /* 3. Small d, knowing abs(z) >= 1. */
+ if (d < 1.0)
+ return ret;
+
+ dexp = __gmp_extract_double (darray, d);
+ ASSERT (dexp >= 1);
+
+ /* 4. Check for different high limb positions. */
+ if (zsize != dexp)
+ return (zsize >= dexp ? ret : -ret);
+
+ /* 5. Limb data. */
+ zp = PTR(z);
+
+#if LIMBS_PER_DOUBLE == 2
+ RETURN_CMP (zp[zsize-1], darray[1]);
+ if (zsize == 1)
+ return (darray[0] != 0 ? -ret : 0);
+
+ RETURN_CMP (zp[zsize-2], darray[0]);
+ RETURN_NONZERO (zp, zsize-2, ret);
+#endif
+
+#if LIMBS_PER_DOUBLE == 3
+ RETURN_CMP (zp[zsize-1], darray[2]);
+ if (zsize == 1)
+ return ((darray[0] | darray[1]) != 0 ? -ret : 0);
+
+ RETURN_CMP (zp[zsize-2], darray[1]);
+ if (zsize == 2)
+ return (darray[0] != 0 ? -ret : 0);
+
+ RETURN_CMP (zp[zsize-3], darray[0]);
+ RETURN_NONZERO (zp, zsize-3, ret);
+#endif
+
+#if LIMBS_PER_DOUBLE >= 4
+ {
+ int i;
+ for (i = 1; i <= LIMBS_PER_DOUBLE; i++)
+ {
+ RETURN_CMP (zp[zsize-i], darray[LIMBS_PER_DOUBLE-i]);
+ if (i >= zsize)
+ RETURN_NONZERO (darray, LIMBS_PER_DOUBLE-i, -ret);
+ }
+ RETURN_NONZERO (zp, zsize-LIMBS_PER_DOUBLE, ret);
+ }
+#endif
+}
diff --git a/gmp/mpz/cmp_si.c b/gmp/mpz/cmp_si.c
new file mode 100644
index 0000000000..86251f436a
--- /dev/null
+++ b/gmp/mpz/cmp_si.c
@@ -0,0 +1,70 @@
+/* mpz_cmp_si(u,v) -- Compare an integer U with a single-word int V.
+ Return positive, zero, or negative based on if U > V, U == V, or U < V.
+
+Copyright 1991, 1993-1996, 2000-2002, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+_mpz_cmp_si (mpz_srcptr u, signed long int v_digit) __GMP_NOTHROW
+{
+#if GMP_NAIL_BITS != 0
+ /* FIXME. This isn't very pretty. */
+ mpz_t tmp;
+ mp_limb_t tt[2];
+ PTR(tmp) = tt;
+ ALLOC(tmp) = 2;
+ mpz_set_si (tmp, v_digit);
+ return mpz_cmp (u, tmp);
+#else
+
+ mp_size_t vsize, usize;
+
+ usize = SIZ (u);
+ vsize = (v_digit > 0) - (v_digit < 0);
+
+ if ((usize == 0) | (usize != vsize))
+ return usize - vsize;
+ else {
+ mp_limb_t u_digit, absv_digit;
+
+ u_digit = PTR (u)[0];
+ absv_digit = ABS_CAST (unsigned long, v_digit);
+
+ if (u_digit == absv_digit)
+ return 0;
+
+ if (u_digit > absv_digit)
+ return usize;
+ else
+ return -usize;
+ }
+#endif
+}
diff --git a/gmp/mpz/cmp_ui.c b/gmp/mpz/cmp_ui.c
new file mode 100644
index 0000000000..790d8241d6
--- /dev/null
+++ b/gmp/mpz/cmp_ui.c
@@ -0,0 +1,78 @@
+/* mpz_cmp_ui.c -- Compare a mpz_t a with an mp_limb_t b. Return positive,
+ zero, or negative based on if a > b, a == b, or a < b.
+
+Copyright 1991, 1993-1996, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+_mpz_cmp_ui (mpz_srcptr u, unsigned long int v_digit) __GMP_NOTHROW
+{
+ mp_ptr up;
+ mp_size_t un;
+ mp_limb_t ul;
+
+ up = PTR(u);
+ un = SIZ(u);
+
+ if (un == 0)
+ return -(v_digit != 0);
+
+ if (un == 1)
+ {
+ ul = up[0];
+ if (ul > v_digit)
+ return 1;
+ if (ul < v_digit)
+ return -1;
+ return 0;
+ }
+
+#if GMP_NAIL_BITS != 0
+ if (v_digit > GMP_NUMB_MAX)
+ {
+ if (un == 2)
+ {
+ ul = up[0] + (up[1] << GMP_NUMB_BITS);
+
+ if ((up[1] >> GMP_NAIL_BITS) != 0)
+ return 1;
+
+ if (ul > v_digit)
+ return 1;
+ if (ul < v_digit)
+ return -1;
+ return 0;
+ }
+ }
+#endif
+
+ return un > 0 ? 1 : -1;
+}
diff --git a/gmp/mpz/cmpabs.c b/gmp/mpz/cmpabs.c
new file mode 100644
index 0000000000..5685776abe
--- /dev/null
+++ b/gmp/mpz/cmpabs.c
@@ -0,0 +1,54 @@
+/* mpz_cmpabs(u,v) -- Compare U, V. Return positive, zero, or negative
+ based on if U > V, U == V, or U < V.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+mpz_cmpabs (mpz_srcptr u, mpz_srcptr v) __GMP_NOTHROW
+{
+ mp_size_t usize, vsize, dsize;
+ mp_srcptr up, vp;
+ int cmp;
+
+ usize = ABSIZ (u);
+ vsize = ABSIZ (v);
+ dsize = usize - vsize;
+ if (dsize != 0)
+ return dsize;
+
+ up = PTR(u);
+ vp = PTR(v);
+ MPN_CMP (cmp, up, vp, usize);
+ return cmp;
+}
diff --git a/gmp/mpz/cmpabs_d.c b/gmp/mpz/cmpabs_d.c
new file mode 100644
index 0000000000..a4b95d26aa
--- /dev/null
+++ b/gmp/mpz/cmpabs_d.c
@@ -0,0 +1,130 @@
+/* mpz_cmpabs_d -- compare absolute values of mpz and double.
+
+Copyright 2001-2003, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if HAVE_FLOAT_H
+#include <float.h> /* for DBL_MAX */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#define RETURN_CMP(zl, dl) \
+ do { \
+ zlimb = (zl); \
+ dlimb = (dl); \
+ if (zlimb != dlimb) \
+ return (zlimb >= dlimb ? 1 : -1); \
+ } while (0)
+
+#define RETURN_NONZERO(ptr, size, val) \
+ do { \
+ mp_size_t __i; \
+ for (__i = (size)-1; __i >= 0; __i--) \
+ if ((ptr)[__i] != 0) \
+ return val; \
+ return 0; \
+ } while (0)
+
+
+int
+mpz_cmpabs_d (mpz_srcptr z, double d)
+{
+ mp_limb_t darray[LIMBS_PER_DOUBLE], zlimb, dlimb;
+ mp_srcptr zp;
+ mp_size_t zsize;
+ int dexp;
+
+ /* d=NaN is an invalid operation, there's no sensible return value.
+ d=Inf or -Inf is always bigger than z. */
+ DOUBLE_NAN_INF_ACTION (d, __gmp_invalid_operation (), return -1);
+
+ /* 1. Check for either operand zero. */
+ zsize = SIZ(z);
+ if (d == 0.0)
+ return (zsize != 0);
+ if (zsize == 0)
+ return -1; /* d != 0 */
+
+ /* 2. Ignore signs. */
+ zsize = ABS(zsize);
+ d = ABS(d);
+
+ /* 3. Small d, knowing abs(z) >= 1. */
+ if (d < 1.0)
+ return 1;
+
+ dexp = __gmp_extract_double (darray, d);
+ ASSERT (dexp >= 1);
+
+ /* 4. Check for different high limb positions. */
+ if (zsize != dexp)
+ return (zsize >= dexp ? 1 : -1);
+
+ /* 5. Limb data. */
+ zp = PTR(z);
+
+#if LIMBS_PER_DOUBLE == 2
+ RETURN_CMP (zp[zsize-1], darray[1]);
+ if (zsize == 1)
+ return (darray[0] != 0 ? -1 : 0);
+
+ RETURN_CMP (zp[zsize-2], darray[0]);
+ RETURN_NONZERO (zp, zsize-2, 1);
+#endif
+
+#if LIMBS_PER_DOUBLE == 3
+ RETURN_CMP (zp[zsize-1], darray[2]);
+ if (zsize == 1)
+ return ((darray[0] | darray[1]) != 0 ? -1 : 0);
+
+ RETURN_CMP (zp[zsize-2], darray[1]);
+ if (zsize == 2)
+ return (darray[0] != 0 ? -1 : 0);
+
+ RETURN_CMP (zp[zsize-3], darray[0]);
+ RETURN_NONZERO (zp, zsize-3, 1);
+#endif
+
+#if LIMBS_PER_DOUBLE >= 4
+ {
+ int i;
+ for (i = 1; i <= LIMBS_PER_DOUBLE; i++)
+ {
+ RETURN_CMP (zp[zsize-i], darray[LIMBS_PER_DOUBLE-i]);
+ if (i >= zsize)
+ RETURN_NONZERO (darray, LIMBS_PER_DOUBLE-i, -1);
+ }
+ RETURN_NONZERO (zp, zsize-LIMBS_PER_DOUBLE, 1);
+ }
+#endif
+}
diff --git a/gmp/mpz/cmpabs_ui.c b/gmp/mpz/cmpabs_ui.c
new file mode 100644
index 0000000000..fdeb061945
--- /dev/null
+++ b/gmp/mpz/cmpabs_ui.c
@@ -0,0 +1,77 @@
+/* mpz_cmpabs_ui.c -- Compare a mpz_t a with an mp_limb_t b. Return positive,
+ zero, or negative based on if a > b, a == b, or a < b.
+
+Copyright 1991, 1993-1995, 1997, 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpz_cmpabs_ui (mpz_srcptr u, unsigned long int v_digit) __GMP_NOTHROW
+{
+ mp_ptr up;
+ mp_size_t un;
+ mp_limb_t ul;
+
+ up = PTR(u);
+ un = SIZ(u);
+
+ if (un == 0)
+ return -(v_digit != 0);
+
+ un = ABS (un);
+
+ if (un == 1)
+ {
+ ul = up[0];
+ if (ul > v_digit)
+ return 1;
+ if (ul < v_digit)
+ return -1;
+ return 0;
+ }
+
+#if GMP_NAIL_BITS != 0
+ if (v_digit > GMP_NUMB_MAX)
+ {
+ if (un == 2)
+ {
+ ul = up[0] + (up[1] << GMP_NUMB_BITS);
+
+ if (ul > v_digit)
+ return 1;
+ if (ul < v_digit)
+ return -1;
+ return 0;
+ }
+ }
+#endif
+
+ return 1;
+}
diff --git a/gmp/mpz/com.c b/gmp/mpz/com.c
new file mode 100644
index 0000000000..66d69ce8b2
--- /dev/null
+++ b/gmp/mpz/com.c
@@ -0,0 +1,88 @@
+/* mpz_com(mpz_ptr dst, mpz_ptr src) -- Assign the bit-complemented value of
+ SRC to DST.
+
+Copyright 1991, 1993, 1994, 1996, 2001, 2003, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_com (mpz_ptr dst, mpz_srcptr src)
+{
+ mp_size_t size = SIZ (src);
+ mp_srcptr src_ptr;
+ mp_ptr dst_ptr;
+
+ if (size >= 0)
+ {
+ /* As with infinite precision: one's complement, two's complement.
+ But this can be simplified using the identity -x = ~x + 1.
+ So we're going to compute (~~x) + 1 = x + 1! */
+
+ if (UNLIKELY (size == 0))
+ {
+ /* special case, as mpn_add_1 wants size!=0 */
+ PTR (dst)[0] = 1;
+ SIZ (dst) = -1;
+ }
+ else
+ {
+ mp_limb_t cy;
+
+ dst_ptr = MPZ_REALLOC (dst, size + 1);
+
+ src_ptr = PTR (src);
+
+ cy = mpn_add_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1);
+ dst_ptr[size] = cy;
+ size += cy;
+
+ /* Store a negative size, to indicate ones-extension. */
+ SIZ (dst) = -size;
+ }
+ }
+ else
+ {
+ /* As with infinite precision: two's complement, then one's complement.
+ But that can be simplified using the identity -x = ~(x - 1).
+ So we're going to compute ~~(x - 1) = x - 1! */
+ size = -size;
+
+ dst_ptr = MPZ_REALLOC (dst, size);
+
+ src_ptr = PTR (src);
+
+ mpn_sub_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1);
+ size -= dst_ptr[size - 1] == 0;
+
+ /* Store a positive size, to indicate zero-extension. */
+ SIZ (dst) = size;
+ }
+}
diff --git a/gmp/mpz/combit.c b/gmp/mpz/combit.c
new file mode 100644
index 0000000000..85ea4c8b26
--- /dev/null
+++ b/gmp/mpz/combit.c
@@ -0,0 +1,103 @@
+/* mpz_combit -- complement a specified bit.
+
+Copyright 2002, 2003, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_combit (mpz_ptr d, mp_bitcnt_t bit_index)
+{
+ mp_size_t dsize = SIZ(d);
+ mp_ptr dp = PTR(d);
+
+ mp_size_t limb_index = bit_index / GMP_NUMB_BITS;
+ mp_limb_t bit = (CNST_LIMB (1) << (bit_index % GMP_NUMB_BITS));
+
+ /* Check for the most common case: Positive input, no realloc or
+ normalization needed. */
+ if (limb_index + 1 < dsize)
+ dp[limb_index] ^= bit;
+
+ /* Check for the hairy case. d < 0, and we have all zero bits to the
+ right of the bit to toggle. */
+ else if (limb_index < -dsize && mpn_zero_p (dp, limb_index)
+ && (dp[limb_index] & (bit - 1)) == 0)
+ {
+ ASSERT (dsize < 0);
+ dsize = -dsize;
+
+ if (dp[limb_index] & bit)
+ {
+ /* We toggle the least significant one bit. Corresponds to
+ an add, with potential carry propagation, on the absolute
+ value. */
+ dp = MPZ_REALLOC (d, 1 + dsize);
+ dp[dsize] = 0;
+ MPN_INCR_U (dp + limb_index, 1 + dsize - limb_index, bit);
+ SIZ(d) = - dsize - dp[dsize];
+ }
+ else
+ {
+ /* We toggle a zero bit, subtract from the absolute value. */
+ MPN_DECR_U (dp + limb_index, dsize - limb_index, bit);
+ /* The absolute value shrinked by at most one bit. */
+ dsize -= dp[dsize - 1] == 0;
+ ASSERT (dsize > 0 && dp[dsize - 1] != 0);
+ SIZ (d) = -dsize;
+ }
+ }
+ else
+ {
+ /* Simple case: Toggle the bit in the absolute value. */
+ dsize = ABS(dsize);
+ if (limb_index < dsize)
+ {
+ mp_limb_t dlimb;
+ dlimb = dp[limb_index] ^ bit;
+ dp[limb_index] = dlimb;
+
+ /* Can happen only when limb_index = dsize - 1. Avoid SIZ(d)
+ bookkeeping in the common case. */
+ if (UNLIKELY ((dlimb == 0) + limb_index == dsize)) /* dsize == limb_index + 1 */
+ {
+ /* high limb became zero, must normalize */
+ MPN_NORMALIZE (dp, limb_index);
+ SIZ (d) = SIZ (d) >= 0 ? limb_index : -limb_index;
+ }
+ }
+ else
+ {
+ dp = MPZ_REALLOC (d, limb_index + 1);
+ MPN_ZERO(dp + dsize, limb_index - dsize);
+ dp[limb_index++] = bit;
+ SIZ(d) = SIZ(d) >= 0 ? limb_index : -limb_index;
+ }
+ }
+}
diff --git a/gmp/mpz/cong.c b/gmp/mpz/cong.c
new file mode 100644
index 0000000000..1855b5052a
--- /dev/null
+++ b/gmp/mpz/cong.c
@@ -0,0 +1,183 @@
+/* mpz_congruent_p -- test congruence of two mpz's.
+
+Copyright 2001, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* For big divisors this code is only very slightly better than the user
+ doing a combination of mpz_sub and mpz_tdiv_r, but it's quite convenient,
+ and perhaps in the future can be improved, in similar ways to
+ mpn_divisible_p perhaps.
+
+ The csize==1 / dsize==1 special case makes mpz_congruent_p as good as
+ mpz_congruent_ui_p on relevant operands, though such a combination
+ probably doesn't occur often.
+
+ Alternatives:
+
+ If c<d then it'd work to just form a%d and compare a and c (either as
+ a==c or a+c==d depending on the signs), but the saving from avoiding the
+ abs(a-c) calculation would be small compared to the division.
+
+ Similarly if both a<d and c<d then it would work to just compare a and c
+ (a==c or a+c==d), but this isn't considered a particularly important case
+ and so isn't done for the moment.
+
+ Low zero limbs on d could be stripped and the corresponding limbs of a
+ and c tested and skipped, but doing so would introduce a borrow when a
+ and c differ in sign and have non-zero skipped limbs. It doesn't seem
+ worth the complications to do this, since low zero limbs on d should
+ occur only rarely. */
+
+int
+mpz_congruent_p (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d)
+{
+ mp_size_t asize, csize, dsize, sign;
+ mp_srcptr ap, cp, dp;
+ mp_ptr xp;
+ mp_limb_t alow, clow, dlow, dmask, r;
+ int result;
+ TMP_DECL;
+
+ dsize = SIZ(d);
+ if (UNLIKELY (dsize == 0))
+ return (mpz_cmp (a, c) == 0);
+
+ dsize = ABS(dsize);
+ dp = PTR(d);
+
+ if (ABSIZ(a) < ABSIZ(c))
+ MPZ_SRCPTR_SWAP (a, c);
+
+ asize = SIZ(a);
+ csize = SIZ(c);
+ sign = (asize ^ csize);
+
+ asize = ABS(asize);
+ ap = PTR(a);
+
+ if (csize == 0)
+ return mpn_divisible_p (ap, asize, dp, dsize);
+
+ csize = ABS(csize);
+ cp = PTR(c);
+
+ alow = ap[0];
+ clow = cp[0];
+ dlow = dp[0];
+
+ /* Check a==c mod low zero bits of dlow. This might catch a few cases of
+ a!=c quickly, and it helps the csize==1 special cases below. */
+ dmask = LOW_ZEROS_MASK (dlow) & GMP_NUMB_MASK;
+ alow = (sign >= 0 ? alow : -alow);
+ if (((alow-clow) & dmask) != 0)
+ return 0;
+
+ if (csize == 1)
+ {
+ if (dsize == 1)
+ {
+ cong_1:
+ if (sign < 0)
+ NEG_MOD (clow, clow, dlow);
+
+ if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD))
+ {
+ r = mpn_mod_1 (ap, asize, dlow);
+ if (clow < dlow)
+ return r == clow;
+ else
+ return r == (clow % dlow);
+ }
+
+ if ((dlow & 1) == 0)
+ {
+ /* Strip low zero bits to get odd d required by modexact. If
+ d==e*2^n then a==c mod d if and only if both a==c mod e and
+ a==c mod 2^n, the latter having been done above. */
+ unsigned twos;
+ count_trailing_zeros (twos, dlow);
+ dlow >>= twos;
+ }
+
+ r = mpn_modexact_1c_odd (ap, asize, dlow, clow);
+ return r == 0 || r == dlow;
+ }
+
+ /* dlow==0 is avoided since we don't want to bother handling extra low
+ zero bits if dsecond is even (would involve borrow if a,c differ in
+ sign and alow,clow!=0). */
+ if (dsize == 2 && dlow != 0)
+ {
+ mp_limb_t dsecond = dp[1];
+
+ if (dsecond <= dmask)
+ {
+ unsigned twos;
+ count_trailing_zeros (twos, dlow);
+ dlow = (dlow >> twos) | (dsecond << (GMP_NUMB_BITS-twos));
+ ASSERT_LIMB (dlow);
+
+ /* dlow will be odd here, so the test for it even under cong_1
+ is unnecessary, but the rest of that code is wanted. */
+ goto cong_1;
+ }
+ }
+ }
+
+ TMP_MARK;
+ xp = TMP_ALLOC_LIMBS (asize+1);
+
+ /* calculate abs(a-c) */
+ if (sign >= 0)
+ {
+ /* same signs, subtract */
+ if (asize > csize || mpn_cmp (ap, cp, asize) >= 0)
+ ASSERT_NOCARRY (mpn_sub (xp, ap, asize, cp, csize));
+ else
+ ASSERT_NOCARRY (mpn_sub_n (xp, cp, ap, asize));
+ MPN_NORMALIZE (xp, asize);
+ }
+ else
+ {
+ /* different signs, add */
+ mp_limb_t carry;
+ carry = mpn_add (xp, ap, asize, cp, csize);
+ xp[asize] = carry;
+ asize += (carry != 0);
+ }
+
+ result = mpn_divisible_p (xp, asize, dp, dsize);
+
+ TMP_FREE;
+ return result;
+}
diff --git a/gmp/mpz/cong_2exp.c b/gmp/mpz/cong_2exp.c
new file mode 100644
index 0000000000..8e78b17378
--- /dev/null
+++ b/gmp/mpz/cong_2exp.c
@@ -0,0 +1,150 @@
+/* mpz_congruent_2exp_p -- test congruence of mpz mod 2^n.
+
+Copyright 2001, 2002, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+mpz_congruent_2exp_p (mpz_srcptr a, mpz_srcptr c, mp_bitcnt_t d) __GMP_NOTHROW
+{
+ mp_size_t i, dlimbs;
+ unsigned dbits;
+ mp_ptr ap, cp;
+ mp_limb_t dmask, alimb, climb, sum;
+ mp_size_t as, cs, asize, csize;
+
+ as = SIZ(a);
+ asize = ABS(as);
+
+ cs = SIZ(c);
+ csize = ABS(cs);
+
+ if (asize < csize)
+ {
+ MPZ_SRCPTR_SWAP (a, c);
+ MP_SIZE_T_SWAP (asize, csize);
+ }
+
+ dlimbs = d / GMP_NUMB_BITS;
+ dbits = d % GMP_NUMB_BITS;
+ dmask = (CNST_LIMB(1) << dbits) - 1;
+
+ ap = PTR(a);
+ cp = PTR(c);
+
+ if (csize == 0)
+ goto a_zeros;
+
+ if ((cs ^ as) >= 0)
+ {
+ /* same signs, direct comparison */
+
+ /* a==c for limbs in common */
+ if (mpn_cmp (ap, cp, MIN (csize, dlimbs)) != 0)
+ return 0;
+
+ /* if that's all of dlimbs, then a==c for remaining bits */
+ if (csize > dlimbs)
+ return ((ap[dlimbs]-cp[dlimbs]) & dmask) == 0;
+
+ a_zeros:
+ /* a remains, need all zero bits */
+
+ /* if d covers all of a and c, then must be exactly equal */
+ if (asize <= dlimbs)
+ return asize == csize;
+
+ /* whole limbs zero */
+ for (i = csize; i < dlimbs; i++)
+ if (ap[i] != 0)
+ return 0;
+
+ /* partial limb zero */
+ return (ap[dlimbs] & dmask) == 0;
+ }
+ else
+ {
+ /* different signs, negated comparison */
+
+ /* common low zero limbs, stopping at first non-zeros, which must
+ match twos complement */
+ i = 0;
+ do
+ {
+ ASSERT (i < csize); /* always have a non-zero limb on c */
+ alimb = ap[i];
+ climb = cp[i];
+ sum = (alimb + climb) & GMP_NUMB_MASK;
+
+ if (i >= dlimbs)
+ return (sum & dmask) == 0;
+ ++i;
+
+ /* require both zero, or first non-zeros as twos-complements */
+ if (sum != 0)
+ return 0;
+ } while (alimb == 0);
+
+ /* further limbs matching as ones-complement */
+ for (; i < csize; ++i)
+ {
+ alimb = ap[i];
+ climb = cp[i];
+ sum = alimb ^ climb ^ GMP_NUMB_MASK;
+
+ if (i >= dlimbs)
+ return (sum & dmask) == 0;
+
+ if (sum != 0)
+ return 0;
+ }
+
+ /* no more c, so require all 1 bits in a */
+
+ if (asize < dlimbs)
+ return 0; /* not enough a */
+
+ /* whole limbs */
+ for ( ; i < dlimbs; i++)
+ if (ap[i] != GMP_NUMB_MAX)
+ return 0;
+
+ /* if only whole limbs, no further fetches from a */
+ if (dbits == 0)
+ return 1;
+
+ /* need enough a */
+ if (asize == dlimbs)
+ return 0;
+
+ return ((ap[dlimbs]+1) & dmask) == 0;
+ }
+}
diff --git a/gmp/mpz/cong_ui.c b/gmp/mpz/cong_ui.c
new file mode 100644
index 0000000000..a9729d9a85
--- /dev/null
+++ b/gmp/mpz/cong_ui.c
@@ -0,0 +1,116 @@
+/* mpz_congruent_ui_p -- test congruence of mpz and ulong.
+
+Copyright 2000-2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* There's some explicit checks for c<d since it seems reasonably likely an
+ application might use that in a test.
+
+ Hopefully the compiler can generate something good for r==(c%d), though
+ if modexact is being used exclusively then that's not reached. */
+
+int
+mpz_congruent_ui_p (mpz_srcptr a, unsigned long cu, unsigned long du)
+{
+ mp_srcptr ap;
+ mp_size_t asize;
+ mp_limb_t c, d, r;
+
+ if (UNLIKELY (du == 0))
+ return (mpz_cmp_ui (a, cu) == 0);
+
+ asize = SIZ(a);
+ if (asize == 0)
+ {
+ if (cu < du)
+ return cu == 0;
+ else
+ return (cu % du) == 0;
+ }
+
+ /* For nails don't try to be clever if c or d is bigger than a limb, just
+ fake up some mpz_t's and go to the main mpz_congruent_p. */
+ if (du > GMP_NUMB_MAX || cu > GMP_NUMB_MAX)
+ {
+ mp_limb_t climbs[2], dlimbs[2];
+ mpz_t cz, dz;
+
+ ALLOC(cz) = 2;
+ PTR(cz) = climbs;
+ ALLOC(dz) = 2;
+ PTR(dz) = dlimbs;
+
+ mpz_set_ui (cz, cu);
+ mpz_set_ui (dz, du);
+ return mpz_congruent_p (a, cz, dz);
+ }
+
+ /* NEG_MOD works on limbs, so convert ulong to limb */
+ c = cu;
+ d = du;
+
+ if (asize < 0)
+ {
+ asize = -asize;
+ NEG_MOD (c, c, d);
+ }
+
+ ap = PTR (a);
+
+ if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD))
+ {
+ r = mpn_mod_1 (ap, asize, d);
+ if (c < d)
+ return r == c;
+ else
+ return r == (c % d);
+ }
+
+ if ((d & 1) == 0)
+ {
+ /* Strip low zero bits to get odd d required by modexact. If
+ d==e*2^n then a==c mod d if and only if both a==c mod 2^n
+ and a==c mod e. */
+
+ unsigned twos;
+
+ if ((ap[0]-c) & LOW_ZEROS_MASK (d))
+ return 0;
+
+ count_trailing_zeros (twos, d);
+ d >>= twos;
+ }
+
+ r = mpn_modexact_1c_odd (ap, asize, d, c);
+ return r == 0 || r == d;
+}
diff --git a/gmp/mpz/dive_ui.c b/gmp/mpz/dive_ui.c
new file mode 100644
index 0000000000..8a1b5a31ff
--- /dev/null
+++ b/gmp/mpz/dive_ui.c
@@ -0,0 +1,69 @@
+/* mpz_divexact_ui -- exact division mpz by ulong.
+
+Copyright 2001, 2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_divexact_ui (mpz_ptr dst, mpz_srcptr src, unsigned long divisor)
+{
+ mp_size_t size, abs_size;
+ mp_ptr dst_ptr;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ /* For nails don't try to be clever if d is bigger than a limb, just fake
+ up an mpz_t and go to the main mpz_divexact. */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dlimbs[2];
+ mpz_t dz;
+ ALLOC(dz) = 2;
+ PTR(dz) = dlimbs;
+ mpz_set_ui (dz, divisor);
+ mpz_divexact (dst, src, dz);
+ return;
+ }
+
+ size = SIZ(src);
+ if (size == 0)
+ {
+ SIZ(dst) = 0;
+ return;
+ }
+ abs_size = ABS (size);
+
+ dst_ptr = MPZ_REALLOC (dst, abs_size);
+
+ MPN_DIVREM_OR_DIVEXACT_1 (dst_ptr, PTR(src), abs_size, (mp_limb_t) divisor);
+ abs_size -= (dst_ptr[abs_size-1] == 0);
+ SIZ(dst) = (size >= 0 ? abs_size : -abs_size);
+}
diff --git a/gmp/mpz/divegcd.c b/gmp/mpz/divegcd.c
new file mode 100644
index 0000000000..3cb181c319
--- /dev/null
+++ b/gmp/mpz/divegcd.c
@@ -0,0 +1,157 @@
+/* mpz_divexact_gcd -- exact division optimized for GCDs.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE AND ARE ALMOST CERTAIN TO
+ BE SUBJECT TO INCOMPATIBLE CHANGES IN FUTURE GNU MP RELEASES.
+
+Copyright 2000, 2005, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Set q to a/d, expecting d to be from a GCD and therefore usually small.
+
+ The distribution of GCDs of random numbers can be found in Knuth volume 2
+ section 4.5.2 theorem D.
+
+ GCD chance
+ 1 60.8%
+ 2^k 20.2% (1<=k<32)
+ 3*2^k 9.0% (1<=k<32)
+ other 10.1%
+
+ Only the low limb is examined for optimizations, since GCDs bigger than
+ 2^32 (or 2^64) will occur very infrequently.
+
+ Future: This could change to an mpn_divexact_gcd, possibly partly
+ inlined, if/when the relevant mpq functions change to an mpn based
+ implementation. */
+
+
+#if GMP_NUMB_BITS % 2 == 0
+static void
+mpz_divexact_by3 (mpz_ptr q, mpz_srcptr a)
+{
+ mp_size_t size = SIZ(a);
+ mp_size_t abs_size = ABS(size);
+ mp_ptr qp;
+
+ qp = MPZ_REALLOC (q, abs_size);
+
+ mpn_bdiv_dbm1 (qp, PTR(a), abs_size, GMP_NUMB_MASK / 3);
+
+ abs_size -= (qp[abs_size-1] == 0);
+ SIZ(q) = (size>0 ? abs_size : -abs_size);
+}
+#endif
+
+#if GMP_NUMB_BITS % 4 == 0
+static void
+mpz_divexact_by5 (mpz_ptr q, mpz_srcptr a)
+{
+ mp_size_t size = SIZ(a);
+ mp_size_t abs_size = ABS(size);
+ mp_ptr qp;
+
+ qp = MPZ_REALLOC (q, abs_size);
+
+ mpn_bdiv_dbm1 (qp, PTR(a), abs_size, GMP_NUMB_MASK / 5);
+
+ abs_size -= (qp[abs_size-1] == 0);
+ SIZ(q) = (size>0 ? abs_size : -abs_size);
+}
+#endif
+
+static void
+mpz_divexact_limb (mpz_ptr q, mpz_srcptr a, mp_limb_t d)
+{
+ mp_size_t size = SIZ(a);
+ mp_size_t abs_size = ABS(size);
+ mp_ptr qp;
+
+ qp = MPZ_REALLOC (q, abs_size);
+
+ mpn_divexact_1 (qp, PTR(a), abs_size, d);
+
+ abs_size -= (qp[abs_size-1] == 0);
+ SIZ(q) = (size>0 ? abs_size : -abs_size);
+}
+
+void
+mpz_divexact_gcd (mpz_ptr q, mpz_srcptr a, mpz_srcptr d)
+{
+ ASSERT (mpz_sgn (d) > 0);
+
+ if (SIZ(a) == 0)
+ {
+ SIZ(q) = 0;
+ return;
+ }
+
+ if (SIZ(d) == 1)
+ {
+ mp_limb_t dl = PTR(d)[0];
+ int twos;
+
+ if ((dl & 1) == 0)
+ {
+ count_trailing_zeros (twos, dl);
+ dl >>= twos;
+ mpz_tdiv_q_2exp (q, a, twos);
+ a = q;
+ }
+
+ if (dl == 1)
+ {
+ if (q != a)
+ mpz_set (q, a);
+ return;
+ }
+#if GMP_NUMB_BITS % 2 == 0
+ if (dl == 3)
+ {
+ mpz_divexact_by3 (q, a);
+ return;
+ }
+#endif
+#if GMP_NUMB_BITS % 4 == 0
+ if (dl == 5)
+ {
+ mpz_divexact_by5 (q, a);
+ return;
+ }
+#endif
+
+ mpz_divexact_limb (q, a, dl);
+ return;
+ }
+
+ mpz_divexact (q, a, d);
+}
diff --git a/gmp/mpz/divexact.c b/gmp/mpz/divexact.c
new file mode 100644
index 0000000000..e935471529
--- /dev/null
+++ b/gmp/mpz/divexact.c
@@ -0,0 +1,91 @@
+/* mpz_divexact -- finds quotient when known that quot * den == num && den != 0.
+
+Contributed to the GNU project by Niels Möller.
+
+Copyright 1991, 1993-1998, 2000-2002, 2005-2007, 2009, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpz_divexact (mpz_ptr quot, mpz_srcptr num, mpz_srcptr den)
+{
+ mp_ptr qp;
+ mp_size_t qn;
+ mp_srcptr np, dp;
+ mp_size_t nn, dn;
+ TMP_DECL;
+
+#if WANT_ASSERT
+ {
+ mpz_t rem;
+ mpz_init (rem);
+ mpz_tdiv_r (rem, num, den);
+ ASSERT (SIZ(rem) == 0);
+ mpz_clear (rem);
+ }
+#endif
+
+ nn = ABSIZ (num);
+ dn = ABSIZ (den);
+
+ if (nn < dn)
+ {
+ /* This special case avoids segfaults below when the function is
+ incorrectly called with |N| < |D|, N != 0. It also handles the
+ well-defined case N = 0. */
+ SIZ(quot) = 0;
+ return;
+ }
+
+ qn = nn - dn + 1;
+
+ TMP_MARK;
+
+ if (quot == num || quot == den)
+ qp = TMP_ALLOC_LIMBS (qn);
+ else
+ qp = MPZ_REALLOC (quot, qn);
+
+ np = PTR(num);
+ dp = PTR(den);
+
+ mpn_divexact (qp, np, nn, dp, dn);
+ MPN_NORMALIZE (qp, qn);
+
+ if (qp != PTR(quot))
+ MPN_COPY (MPZ_REALLOC (quot, qn), qp, qn);
+
+ SIZ(quot) = (SIZ(num) ^ SIZ(den)) >= 0 ? qn : -qn;
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/divis.c b/gmp/mpz/divis.c
new file mode 100644
index 0000000000..cd9d406846
--- /dev/null
+++ b/gmp/mpz/divis.c
@@ -0,0 +1,44 @@
+/* mpz_divisible_p -- mpz by mpz divisibility test
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpz_divisible_p (mpz_srcptr a, mpz_srcptr d)
+{
+ mp_size_t dsize = SIZ(d);
+ mp_size_t asize = SIZ(a);
+
+ if (UNLIKELY (dsize == 0))
+ return (asize == 0);
+
+ return mpn_divisible_p (PTR(a), ABS(asize), PTR(d), ABS(dsize));
+}
diff --git a/gmp/mpz/divis_2exp.c b/gmp/mpz/divis_2exp.c
new file mode 100644
index 0000000000..db6cfa4433
--- /dev/null
+++ b/gmp/mpz/divis_2exp.c
@@ -0,0 +1,61 @@
+/* mpz_divisible_2exp_p -- mpz by 2^n divisibility test
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+mpz_divisible_2exp_p (mpz_srcptr a, mp_bitcnt_t d) __GMP_NOTHROW
+{
+ mp_size_t i, dlimbs;
+ unsigned dbits;
+ mp_ptr ap;
+ mp_limb_t dmask;
+ mp_size_t asize;
+
+ asize = ABSIZ(a);
+ dlimbs = d / GMP_NUMB_BITS;
+
+ /* if d covers the whole of a, then only a==0 is divisible */
+ if (asize <= dlimbs)
+ return asize == 0;
+
+ /* whole limbs must be zero */
+ ap = PTR(a);
+ for (i = 0; i < dlimbs; i++)
+ if (ap[i] != 0)
+ return 0;
+
+ /* left over bits must be zero */
+ dbits = d % GMP_NUMB_BITS;
+ dmask = (CNST_LIMB(1) << dbits) - 1;
+ return (ap[dlimbs] & dmask) == 0;
+}
diff --git a/gmp/mpz/divis_ui.c b/gmp/mpz/divis_ui.c
new file mode 100644
index 0000000000..41ff5f0b84
--- /dev/null
+++ b/gmp/mpz/divis_ui.c
@@ -0,0 +1,81 @@
+/* mpz_divisible_ui_p -- mpz by ulong divisibility test.
+
+Copyright 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+int
+mpz_divisible_ui_p (mpz_srcptr a, unsigned long d)
+{
+ mp_size_t asize;
+ mp_ptr ap;
+ unsigned twos;
+
+ asize = SIZ(a);
+ if (UNLIKELY (d == 0))
+ return (asize == 0);
+
+ if (asize == 0) /* 0 divisible by any d */
+ return 1;
+
+ /* For nails don't try to be clever if d is bigger than a limb, just fake
+ up an mpz_t and go to the main mpz_divisible_p. */
+ if (d > GMP_NUMB_MAX)
+ {
+ mp_limb_t dlimbs[2];
+ mpz_t dz;
+ ALLOC(dz) = 2;
+ PTR(dz) = dlimbs;
+ mpz_set_ui (dz, d);
+ return mpz_divisible_p (a, dz);
+ }
+
+ ap = PTR(a);
+ asize = ABS(asize); /* ignore sign of a */
+
+ if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD))
+ return mpn_mod_1 (ap, asize, (mp_limb_t) d) == 0;
+
+ if (! (d & 1))
+ {
+ /* Strip low zero bits to get odd d required by modexact. If d==e*2^n
+ and a is divisible by 2^n and by e, then it's divisible by d. */
+
+ if ((ap[0] & LOW_ZEROS_MASK (d)) != 0)
+ return 0;
+
+ count_trailing_zeros (twos, (mp_limb_t) d);
+ d >>= twos;
+ }
+
+ return mpn_modexact_1_odd (ap, asize, (mp_limb_t) d) == 0;
+}
diff --git a/gmp/mpz/dump.c b/gmp/mpz/dump.c
new file mode 100644
index 0000000000..282be34db7
--- /dev/null
+++ b/gmp/mpz/dump.c
@@ -0,0 +1,49 @@
+/* mpz_dump - Dump an integer to stdout.
+
+ THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE. IT IS NOT SAFE TO
+ CALL THIS FUNCTION DIRECTLY. IN FACT, IT IS ALMOST GUARANTEED THAT THIS
+ FUNCTION WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+
+Copyright 1999-2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <string.h> /* for strlen */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_dump (mpz_srcptr u)
+{
+ char *str;
+
+ str = mpz_get_str (0, 10, u);
+ printf ("%s\n", str);
+ (*__gmp_free_func) (str, strlen (str) + 1);
+}
diff --git a/gmp/mpz/export.c b/gmp/mpz/export.c
new file mode 100644
index 0000000000..bc4c4df976
--- /dev/null
+++ b/gmp/mpz/export.c
@@ -0,0 +1,190 @@
+/* mpz_export -- create word data from mpz.
+
+Copyright 2002, 2003, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#if HAVE_LIMB_BIG_ENDIAN
+#define HOST_ENDIAN 1
+#endif
+#if HAVE_LIMB_LITTLE_ENDIAN
+#define HOST_ENDIAN (-1)
+#endif
+#ifndef HOST_ENDIAN
+static const mp_limb_t endian_test = (CNST_LIMB(1) << (GMP_LIMB_BITS-7)) - 1;
+#define HOST_ENDIAN (* (signed char *) &endian_test)
+#endif
+
+void *
+mpz_export (void *data, size_t *countp, int order,
+ size_t size, int endian, size_t nail, mpz_srcptr z)
+{
+ mp_size_t zsize;
+ mp_srcptr zp;
+ size_t count, dummy;
+ unsigned long numb;
+ unsigned align;
+
+ ASSERT (order == 1 || order == -1);
+ ASSERT (endian == 1 || endian == 0 || endian == -1);
+ ASSERT (nail <= 8*size);
+ ASSERT (nail < 8*size || SIZ(z) == 0); /* nail < 8*size+(SIZ(z)==0) */
+
+ if (countp == NULL)
+ countp = &dummy;
+
+ zsize = SIZ(z);
+ if (zsize == 0)
+ {
+ *countp = 0;
+ return data;
+ }
+
+ zsize = ABS (zsize);
+ zp = PTR(z);
+ numb = 8*size - nail;
+ MPN_SIZEINBASE_2EXP (count, zp, zsize, numb);
+ *countp = count;
+
+ if (data == NULL)
+ data = (*__gmp_allocate_func) (count*size);
+
+ if (endian == 0)
+ endian = HOST_ENDIAN;
+
+ align = ((char *) data - (char *) NULL) % sizeof (mp_limb_t);
+
+ if (nail == GMP_NAIL_BITS)
+ {
+ if (size == sizeof (mp_limb_t) && align == 0)
+ {
+ if (order == -1 && endian == HOST_ENDIAN)
+ {
+ MPN_COPY ((mp_ptr) data, zp, (mp_size_t) count);
+ return data;
+ }
+ if (order == 1 && endian == HOST_ENDIAN)
+ {
+ MPN_REVERSE ((mp_ptr) data, zp, (mp_size_t) count);
+ return data;
+ }
+
+ if (order == -1 && endian == -HOST_ENDIAN)
+ {
+ MPN_BSWAP ((mp_ptr) data, zp, (mp_size_t) count);
+ return data;
+ }
+ if (order == 1 && endian == -HOST_ENDIAN)
+ {
+ MPN_BSWAP_REVERSE ((mp_ptr) data, zp, (mp_size_t) count);
+ return data;
+ }
+ }
+ }
+
+ {
+ mp_limb_t limb, wbitsmask;
+ size_t i, numb;
+ mp_size_t j, wbytes, woffset;
+ unsigned char *dp;
+ int lbits, wbits;
+ mp_srcptr zend;
+
+ numb = size * 8 - nail;
+
+ /* whole bytes per word */
+ wbytes = numb / 8;
+
+ /* possible partial byte */
+ wbits = numb % 8;
+ wbitsmask = (CNST_LIMB(1) << wbits) - 1;
+
+ /* offset to get to the next word */
+ woffset = (endian >= 0 ? size : - (mp_size_t) size)
+ + (order < 0 ? size : - (mp_size_t) size);
+
+ /* least significant byte */
+ dp = (unsigned char *) data
+ + (order >= 0 ? (count-1)*size : 0) + (endian >= 0 ? size-1 : 0);
+
+#define EXTRACT(N, MASK) \
+ do { \
+ if (lbits >= (N)) \
+ { \
+ *dp = limb MASK; \
+ limb >>= (N); \
+ lbits -= (N); \
+ } \
+ else \
+ { \
+ mp_limb_t newlimb; \
+ newlimb = (zp == zend ? 0 : *zp++); \
+ *dp = (limb | (newlimb << lbits)) MASK; \
+ limb = newlimb >> ((N)-lbits); \
+ lbits += GMP_NUMB_BITS - (N); \
+ } \
+ } while (0)
+
+ zend = zp + zsize;
+ lbits = 0;
+ limb = 0;
+ for (i = 0; i < count; i++)
+ {
+ for (j = 0; j < wbytes; j++)
+ {
+ EXTRACT (8, + 0);
+ dp -= endian;
+ }
+ if (wbits != 0)
+ {
+ EXTRACT (wbits, & wbitsmask);
+ dp -= endian;
+ j++;
+ }
+ for ( ; j < size; j++)
+ {
+ *dp = '\0';
+ dp -= endian;
+ }
+ dp += woffset;
+ }
+
+ ASSERT (zp == PTR(z) + ABSIZ(z));
+
+ /* low byte of word after most significant */
+ ASSERT (dp == (unsigned char *) data
+ + (order < 0 ? count*size : - (mp_size_t) size)
+ + (endian >= 0 ? (mp_size_t) size - 1 : 0));
+ }
+ return data;
+}
diff --git a/gmp/mpz/fac_ui.c b/gmp/mpz/fac_ui.c
new file mode 100644
index 0000000000..e0932272ff
--- /dev/null
+++ b/gmp/mpz/fac_ui.c
@@ -0,0 +1,108 @@
+/* mpz_fac_ui(RESULT, N) -- Set RESULT to N!.
+
+Contributed to the GNU project by Marco Bodrato.
+
+Copyright 1991, 1993-1995, 2000-2003, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \
+ do { \
+ if ((PR) > (MAX_PR)) { \
+ (VEC)[(I)++] = (PR); \
+ (PR) = (P); \
+ } else \
+ (PR) *= (P); \
+ } while (0)
+
+#if TUNE_PROGRAM_BUILD
+#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_DSC_THRESHOLD_LIMIT-1)+1))
+#else
+#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_ODD_THRESHOLD)+1))
+#endif
+
+/* Computes n!, the factorial of n.
+ WARNING: it assumes that n fits in a limb!
+ */
+void
+mpz_fac_ui (mpz_ptr x, unsigned long n)
+{
+ static const mp_limb_t table[] = { ONE_LIMB_FACTORIAL_TABLE };
+
+ ASSERT (n <= GMP_NUMB_MAX);
+
+ if (n < numberof (table))
+ {
+ PTR (x)[0] = table[n];
+ SIZ (x) = 1;
+ }
+ else if (BELOW_THRESHOLD (n, FAC_ODD_THRESHOLD))
+ {
+ mp_limb_t prod, max_prod;
+ mp_size_t j;
+ mp_ptr factors;
+ TMP_SDECL;
+
+ TMP_SMARK;
+ factors = TMP_SALLOC_LIMBS (2 + (n - numberof (table)) / FACTORS_PER_LIMB);
+
+ factors[0] = table[numberof (table)-1];
+ j = 1;
+ prod = n;
+#if TUNE_PROGRAM_BUILD
+ max_prod = GMP_NUMB_MAX / FAC_DSC_THRESHOLD_LIMIT;
+#else
+ max_prod = GMP_NUMB_MAX / (FAC_ODD_THRESHOLD | 1);
+#endif
+ while (--n >= numberof (table))
+ FACTOR_LIST_STORE (n, prod, max_prod, factors, j);
+
+ factors[j++] = prod;
+ mpz_prodlimbs (x, factors, j);
+
+ TMP_SFREE;
+ }
+ else
+ {
+ mp_limb_t count;
+ mpz_oddfac_1 (x, n, 0);
+ if (n <= TABLE_LIMIT_2N_MINUS_POPC_2N)
+ count = __gmp_fac2cnt_table[n / 2 - 1];
+ else
+ {
+ popc_limb (count, n);
+ count = n - count;
+ }
+ mpz_mul_2exp (x, x, count);
+ }
+}
+
+#undef FACTORS_PER_LIMB
+#undef FACTOR_LIST_STORE
diff --git a/gmp/mpz/fdiv_q.c b/gmp/mpz/fdiv_q.c
new file mode 100644
index 0000000000..5713b905b2
--- /dev/null
+++ b/gmp/mpz/fdiv_q.c
@@ -0,0 +1,53 @@
+/* mpz_fdiv_q -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright 1994-1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_fdiv_q (mpz_ptr quot, mpz_srcptr dividend, mpz_srcptr divisor)
+{
+ mp_size_t dividend_size = SIZ (dividend);
+ mp_size_t divisor_size = SIZ (divisor);
+ mpz_t rem;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ MPZ_TMP_INIT (rem, ABS (divisor_size));
+
+ mpz_tdiv_qr (quot, rem, dividend, divisor);
+
+ if ((divisor_size ^ dividend_size) < 0 && SIZ (rem) != 0)
+ mpz_sub_ui (quot, quot, 1L);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/fdiv_q_ui.c b/gmp/mpz/fdiv_q_ui.c
new file mode 100644
index 0000000000..7899992d04
--- /dev/null
+++ b/gmp/mpz/fdiv_q_ui.c
@@ -0,0 +1,101 @@
+/* mpz_fdiv_q_ui -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright 1994-1996, 1999, 2001, 2002, 2004, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_fdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn, qn;
+ mp_ptr np, qp;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(quot) = 0;
+ return 0;
+ }
+
+ nn = ABS(ns);
+ qp = MPZ_REALLOC (quot, nn);
+ np = PTR(dividend);
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2], rp[2];
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ qp[0] = 0;
+ rl = np[0];
+ qn = 1; /* a white lie, fixed below */
+ }
+ else
+ {
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ qn = nn - 2 + 1;
+ }
+
+ if (rl != 0 && ns < 0)
+ {
+ mpn_incr_u (qp, (mp_limb_t) 1);
+ rl = divisor - rl;
+ }
+
+ qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0;
+ }
+ else
+#endif
+ {
+ rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor);
+
+ if (rl != 0 && ns < 0)
+ {
+ mpn_incr_u (qp, (mp_limb_t) 1);
+ rl = divisor - rl;
+ }
+
+ qn = nn - (qp[nn - 1] == 0);
+ }
+
+ SIZ(quot) = ns >= 0 ? qn : -qn;
+ return rl;
+}
diff --git a/gmp/mpz/fdiv_qr.c b/gmp/mpz/fdiv_qr.c
new file mode 100644
index 0000000000..36cfd367ad
--- /dev/null
+++ b/gmp/mpz/fdiv_qr.c
@@ -0,0 +1,65 @@
+/* mpz_fdiv_qr -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright 1994-1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_fdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+{
+ mp_size_t divisor_size = SIZ (divisor);
+ mp_size_t xsize;
+ mpz_t temp_divisor; /* N.B.: lives until function returns! */
+ TMP_DECL;
+
+ TMP_MARK;
+
+ /* We need the original value of the divisor after the quotient and
+ remainder have been preliminary calculated. We have to copy it to
+ temporary space if it's the same variable as either QUOT or REM. */
+ if (quot == divisor || rem == divisor)
+ {
+ MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
+ mpz_set (temp_divisor, divisor);
+ divisor = temp_divisor;
+ }
+
+ xsize = SIZ (dividend) ^ divisor_size;;
+ mpz_tdiv_qr (quot, rem, dividend, divisor);
+
+ if (xsize < 0 && SIZ (rem) != 0)
+ {
+ mpz_sub_ui (quot, quot, 1L);
+ mpz_add (rem, rem, divisor);
+ }
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/fdiv_qr_ui.c b/gmp/mpz/fdiv_qr_ui.c
new file mode 100644
index 0000000000..c8435a423c
--- /dev/null
+++ b/gmp/mpz/fdiv_qr_ui.c
@@ -0,0 +1,118 @@
+/* mpz_fdiv_qr_ui -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright 1994-1996, 1999, 2001, 2002, 2004, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_fdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn, qn;
+ mp_ptr np, qp;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(quot) = 0;
+ SIZ(rem) = 0;
+ return 0;
+ }
+
+ nn = ABS(ns);
+ qp = MPZ_REALLOC (quot, nn);
+ np = PTR(dividend);
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2];
+ mp_ptr rp;
+ mp_size_t rn;
+
+ MPZ_REALLOC (rem, 2);
+ rp = PTR(rem);
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ qp[0] = 0;
+ qn = 1; /* a white lie, fixed below */
+ rl = np[0];
+ rp[0] = rl;
+ }
+ else
+ {
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ qn = nn - 2 + 1;
+ }
+
+ if (rl != 0 && ns < 0)
+ {
+ mpn_incr_u (qp, (mp_limb_t) 1);
+ rl = divisor - rl;
+ rp[0] = rl & GMP_NUMB_MASK;
+ rp[1] = rl >> GMP_NUMB_BITS;
+ }
+
+ qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0;
+ rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0);
+ SIZ(rem) = rn;
+ }
+ else
+#endif
+ {
+ rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ SIZ(rem) = 0;
+ else
+ {
+ if (ns < 0)
+ {
+ mpn_incr_u (qp, (mp_limb_t) 1);
+ rl = divisor - rl;
+ }
+
+ PTR(rem)[0] = rl;
+ SIZ(rem) = rl != 0;
+ }
+ qn = nn - (qp[nn - 1] == 0);
+ }
+
+ SIZ(quot) = ns >= 0 ? qn : -qn;
+ return rl;
+}
diff --git a/gmp/mpz/fdiv_r.c b/gmp/mpz/fdiv_r.c
new file mode 100644
index 0000000000..35f2789b14
--- /dev/null
+++ b/gmp/mpz/fdiv_r.c
@@ -0,0 +1,60 @@
+/* mpz_fdiv_r -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright 1994-1996, 2001, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_fdiv_r (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+{
+ mp_size_t divisor_size = SIZ (divisor);
+ mpz_t temp_divisor; /* N.B.: lives until function returns! */
+ TMP_DECL;
+
+ TMP_MARK;
+
+ /* We need the original value of the divisor after the remainder has been
+ preliminary calculated. We have to copy it to temporary space if it's
+ the same variable as REM. */
+ if (rem == divisor)
+ {
+ MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
+ mpz_set (temp_divisor, divisor);
+ divisor = temp_divisor;
+ }
+
+ mpz_tdiv_r (rem, dividend, divisor);
+
+ if ((divisor_size ^ SIZ (dividend)) < 0 && SIZ (rem) != 0)
+ mpz_add (rem, rem, divisor);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/fdiv_r_ui.c b/gmp/mpz/fdiv_r_ui.c
new file mode 100644
index 0000000000..98dd56c6f2
--- /dev/null
+++ b/gmp/mpz/fdiv_r_ui.c
@@ -0,0 +1,108 @@
+/* mpz_fdiv_r_ui -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright 1994-1996, 2001, 2002, 2004, 2005, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_fdiv_r_ui (mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn;
+ mp_ptr np;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(rem) = 0;
+ return 0;
+ }
+
+ nn = ABS(ns);
+ np = PTR(dividend);
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2];
+ mp_ptr rp, qp;
+ mp_size_t rn;
+ TMP_DECL;
+
+ rp = MPZ_REALLOC (rem, 2);
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ rl = np[0];
+ rp[0] = rl;
+ }
+ else
+ {
+ TMP_MARK;
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ qp = TMP_ALLOC_LIMBS (nn - 2 + 1);
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ TMP_FREE;
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ }
+
+ if (rl != 0 && ns < 0)
+ {
+ rl = divisor - rl;
+ rp[0] = rl & GMP_NUMB_MASK;
+ rp[1] = rl >> GMP_NUMB_BITS;
+ }
+
+ rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0);
+ SIZ(rem) = rn;
+ }
+ else
+#endif
+ {
+ rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ SIZ(rem) = 0;
+ else
+ {
+ if (ns < 0)
+ rl = divisor - rl;
+
+ PTR(rem)[0] = rl;
+ SIZ(rem) = 1;
+ }
+ }
+
+ return rl;
+}
diff --git a/gmp/mpz/fdiv_ui.c b/gmp/mpz/fdiv_ui.c
new file mode 100644
index 0000000000..532ee2cbec
--- /dev/null
+++ b/gmp/mpz/fdiv_ui.c
@@ -0,0 +1,101 @@
+/* mpz_fdiv_ui -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright 1994-1996, 2001, 2002, 2004, 2005, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_fdiv_ui (mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn;
+ mp_ptr np;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ return 0;
+ }
+
+ nn = ABS(ns);
+ np = PTR(dividend);
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2], rp[2];
+ mp_ptr qp;
+ mp_size_t rn;
+ TMP_DECL;
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ rl = np[0];
+ rp[0] = rl;
+ }
+ else
+ {
+ TMP_MARK;
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ qp = TMP_ALLOC_LIMBS (nn - 2 + 1);
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ TMP_FREE;
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ }
+
+ if (rl != 0 && ns < 0)
+ {
+ rl = divisor - rl;
+ rp[0] = rl & GMP_NUMB_MASK;
+ rp[1] = rl >> GMP_NUMB_BITS;
+ }
+
+ rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0);
+ }
+ else
+#endif
+ {
+ rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ ;
+ else
+ {
+ if (ns < 0)
+ rl = divisor - rl;
+ }
+ }
+
+ return rl;
+}
diff --git a/gmp/mpz/fib2_ui.c b/gmp/mpz/fib2_ui.c
new file mode 100644
index 0000000000..122db8dd51
--- /dev/null
+++ b/gmp/mpz/fib2_ui.c
@@ -0,0 +1,50 @@
+/* mpz_fib2_ui -- calculate Fibonacci numbers.
+
+Copyright 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpz_fib2_ui (mpz_ptr fn, mpz_ptr fnsub1, unsigned long n)
+{
+ mp_ptr fp, f1p;
+ mp_size_t size;
+
+ size = MPN_FIB2_SIZE (n);
+ fp = MPZ_REALLOC (fn, size);
+ f1p = MPZ_REALLOC (fnsub1, size);
+
+ size = mpn_fib2_ui (fp, f1p, n);
+
+ SIZ(fn) = size - (n == 0);
+ SIZ(fnsub1) = size - (f1p[size-1] == 0);
+}
diff --git a/gmp/mpz/fib_ui.c b/gmp/mpz/fib_ui.c
new file mode 100644
index 0000000000..c0f57a0dc9
--- /dev/null
+++ b/gmp/mpz/fib_ui.c
@@ -0,0 +1,152 @@
+/* mpz_fib_ui -- calculate Fibonacci numbers.
+
+Copyright 2000-2002, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* change to "#define TRACE(x) x" to get some traces */
+#define TRACE(x)
+
+
+/* In the F[2k+1] below for k odd, the -2 won't give a borrow from the low
+ limb because the result F[2k+1] is an F[4m+3] and such numbers are always
+ == 1, 2 or 5 mod 8, whereas an underflow would leave 6 or 7. (This is
+ the same as in mpn_fib2_ui.)
+
+ In the F[2k+1] for k even, the +2 won't give a carry out of the low limb
+ in normal circumstances. This is an F[4m+1] and we claim that F[3*2^b+1]
+ == 1 mod 2^b is the first F[4m+1] congruent to 0 or 1 mod 2^b, and hence
+ if n < 2^GMP_NUMB_BITS then F[n] cannot have a low limb of 0 or 1. No
+ proof for this claim, but it's been verified up to b==32 and has such a
+ nice pattern it must be true :-). Of interest is that F[3*2^b] == 0 mod
+ 2^(b+1) seems to hold too.
+
+ When n >= 2^GMP_NUMB_BITS, which can arise in a nails build, then the low
+ limb of F[4m+1] can certainly be 1, and an mpn_add_1 must be used. */
+
+void
+mpz_fib_ui (mpz_ptr fn, unsigned long n)
+{
+ mp_ptr fp, xp, yp;
+ mp_size_t size, xalloc;
+ unsigned long n2;
+ mp_limb_t c, c2;
+ TMP_DECL;
+
+ if (n <= FIB_TABLE_LIMIT)
+ {
+ PTR(fn)[0] = FIB_TABLE (n);
+ SIZ(fn) = (n != 0); /* F[0]==0, others are !=0 */
+ return;
+ }
+
+ n2 = n/2;
+ xalloc = MPN_FIB2_SIZE (n2) + 1;
+ fp = MPZ_REALLOC (fn, 2*xalloc+1);
+
+ TMP_MARK;
+ TMP_ALLOC_LIMBS_2 (xp,xalloc, yp,xalloc);
+ size = mpn_fib2_ui (xp, yp, n2);
+
+ TRACE (printf ("mpz_fib_ui last step n=%lu size=%ld bit=%lu\n",
+ n >> 1, size, n&1);
+ mpn_trace ("xp", xp, size);
+ mpn_trace ("yp", yp, size));
+
+ if (n & 1)
+ {
+ /* F[2k+1] = (2F[k]+F[k-1])*(2F[k]-F[k-1]) + 2*(-1)^k */
+ mp_size_t xsize, ysize;
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ xp[size] = mpn_lshift (xp, xp, size, 1);
+ yp[size] = 0;
+ ASSERT_NOCARRY (mpn_add_n_sub_n (xp, yp, xp, yp, size+1));
+ xsize = size + (xp[size] != 0);
+ ysize = size + (yp[size] != 0);
+#else
+ c2 = mpn_lshift (fp, xp, size, 1);
+ c = c2 + mpn_add_n (xp, fp, yp, size);
+ xp[size] = c;
+ xsize = size + (c != 0);
+ c2 -= mpn_sub_n (yp, fp, yp, size);
+ yp[size] = c2;
+ ASSERT (c2 <= 1);
+ ysize = size + c2;
+#endif
+
+ size = xsize + ysize;
+ c = mpn_mul (fp, xp, xsize, yp, ysize);
+
+#if GMP_NUMB_BITS >= BITS_PER_ULONG
+ /* no overflow, see comments above */
+ ASSERT (n & 2 ? fp[0] >= 2 : fp[0] <= GMP_NUMB_MAX-2);
+ fp[0] += (n & 2 ? -CNST_LIMB(2) : CNST_LIMB(2));
+#else
+ if (n & 2)
+ {
+ ASSERT (fp[0] >= 2);
+ fp[0] -= 2;
+ }
+ else
+ {
+ ASSERT (c != GMP_NUMB_MAX); /* because it's the high of a mul */
+ c += mpn_add_1 (fp, fp, size-1, CNST_LIMB(2));
+ fp[size-1] = c;
+ }
+#endif
+ }
+ else
+ {
+ /* F[2k] = F[k]*(F[k]+2F[k-1]) */
+
+ mp_size_t xsize, ysize;
+ c = mpn_lshift (yp, yp, size, 1);
+ c += mpn_add_n (yp, yp, xp, size);
+ yp[size] = c;
+ xsize = size;
+ ysize = size + (c != 0);
+ size += ysize;
+ c = mpn_mul (fp, yp, ysize, xp, xsize);
+ }
+
+ /* one or two high zeros */
+ size -= (c == 0);
+ size -= (fp[size-1] == 0);
+ SIZ(fn) = size;
+
+ TRACE (printf ("done special, size=%ld\n", size);
+ mpn_trace ("fp ", fp, size));
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/fits_s.h b/gmp/mpz/fits_s.h
new file mode 100644
index 0000000000..e7f21d1b2b
--- /dev/null
+++ b/gmp/mpz/fits_s.h
@@ -0,0 +1,61 @@
+/* int mpz_fits_X_p (mpz_t z) -- test whether z fits signed type X.
+
+Copyright 1997, 2000-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+FUNCTION (mpz_srcptr z) __GMP_NOTHROW
+{
+ mp_size_t n = SIZ(z);
+ mp_ptr p = PTR(z);
+ mp_limb_t limb = p[0];
+
+ if (n == 0)
+ return 1;
+ if (n == 1)
+ return limb <= MAXIMUM;
+ if (n == -1)
+ return limb <= NEG_CAST (mp_limb_t, MINIMUM);
+#if GMP_NAIL_BITS != 0
+ {
+ if ((p[1] >> GMP_NAIL_BITS) == 0)
+ {
+ limb += p[1] << GMP_NUMB_BITS;
+ if (n == 2)
+ return limb <= MAXIMUM;
+ if (n == -2)
+ return limb <= NEG_CAST (mp_limb_t, MINIMUM);
+ }
+ }
+#endif
+ return 0;
+}
diff --git a/gmp/mpz/fits_sint.c b/gmp/mpz/fits_sint.c
new file mode 100644
index 0000000000..d548c45b0d
--- /dev/null
+++ b/gmp/mpz/fits_sint.c
@@ -0,0 +1,36 @@
+/* int mpz_fits_sint_p (mpz_t z) -- test whether z fits an int.
+
+Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define FUNCTION mpz_fits_sint_p
+#define MAXIMUM INT_MAX
+#define MINIMUM INT_MIN
+
+#include "fits_s.h"
diff --git a/gmp/mpz/fits_slong.c b/gmp/mpz/fits_slong.c
new file mode 100644
index 0000000000..9306a00c0f
--- /dev/null
+++ b/gmp/mpz/fits_slong.c
@@ -0,0 +1,36 @@
+/* int mpz_fits_slong_p (mpz_t z) -- test whether z fits a long.
+
+Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define FUNCTION mpz_fits_slong_p
+#define MAXIMUM LONG_MAX
+#define MINIMUM LONG_MIN
+
+#include "fits_s.h"
diff --git a/gmp/mpz/fits_sshort.c b/gmp/mpz/fits_sshort.c
new file mode 100644
index 0000000000..431d6b06ce
--- /dev/null
+++ b/gmp/mpz/fits_sshort.c
@@ -0,0 +1,36 @@
+/* int mpz_fits_sshort_p (mpz_t z) -- test whether z fits a short.
+
+Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define FUNCTION mpz_fits_sshort_p
+#define MAXIMUM SHRT_MAX
+#define MINIMUM SHRT_MIN
+
+#include "fits_s.h"
diff --git a/gmp/mpz/fits_uint.c b/gmp/mpz/fits_uint.c
new file mode 100644
index 0000000000..a37e291b6e
--- /dev/null
+++ b/gmp/mpz/fits_uint.c
@@ -0,0 +1,34 @@
+/* mpz_fits_uint_p -- test whether z fits an unsigned int.
+
+Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_fits_uint_p 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpz/fits_ulong.c b/gmp/mpz/fits_ulong.c
new file mode 100644
index 0000000000..fa40eb5671
--- /dev/null
+++ b/gmp/mpz/fits_ulong.c
@@ -0,0 +1,34 @@
+/* mpz_fits_ulong_p -- test whether z fits an unsigned long.
+
+Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_fits_ulong_p 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpz/fits_ushort.c b/gmp/mpz/fits_ushort.c
new file mode 100644
index 0000000000..7f6f907821
--- /dev/null
+++ b/gmp/mpz/fits_ushort.c
@@ -0,0 +1,34 @@
+/* mpz_fits_ushort_p -- test whether z fits an unsigned short.
+
+Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_fits_ushort_p 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpz/gcd.c b/gmp/mpz/gcd.c
new file mode 100644
index 0000000000..87c6a8f17b
--- /dev/null
+++ b/gmp/mpz/gcd.c
@@ -0,0 +1,167 @@
+/* mpz/gcd.c: Calculate the greatest common divisor of two integers.
+
+Copyright 1991, 1993, 1994, 1996, 2000-2002, 2005, 2010 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+void
+mpz_gcd (mpz_ptr g, mpz_srcptr u, mpz_srcptr v)
+{
+ unsigned long int g_zero_bits, u_zero_bits, v_zero_bits;
+ mp_size_t g_zero_limbs, u_zero_limbs, v_zero_limbs;
+ mp_ptr tp;
+ mp_ptr up;
+ mp_size_t usize;
+ mp_ptr vp;
+ mp_size_t vsize;
+ mp_size_t gsize;
+ TMP_DECL;
+
+ up = PTR(u);
+ usize = ABSIZ (u);
+ vp = PTR(v);
+ vsize = ABSIZ (v);
+ /* GCD(0, V) == V. */
+ if (usize == 0)
+ {
+ SIZ (g) = vsize;
+ if (g == v)
+ return;
+ MPZ_REALLOC (g, vsize);
+ MPN_COPY (PTR (g), vp, vsize);
+ return;
+ }
+
+ /* GCD(U, 0) == U. */
+ if (vsize == 0)
+ {
+ SIZ (g) = usize;
+ if (g == u)
+ return;
+ MPZ_REALLOC (g, usize);
+ MPN_COPY (PTR (g), up, usize);
+ return;
+ }
+
+ if (usize == 1)
+ {
+ SIZ (g) = 1;
+ PTR (g)[0] = mpn_gcd_1 (vp, vsize, up[0]);
+ return;
+ }
+
+ if (vsize == 1)
+ {
+ SIZ(g) = 1;
+ PTR (g)[0] = mpn_gcd_1 (up, usize, vp[0]);
+ return;
+ }
+
+ TMP_MARK;
+
+ /* Eliminate low zero bits from U and V and move to temporary storage. */
+ while (*up == 0)
+ up++;
+ u_zero_limbs = up - PTR(u);
+ usize -= u_zero_limbs;
+ count_trailing_zeros (u_zero_bits, *up);
+ tp = up;
+ up = TMP_ALLOC_LIMBS (usize);
+ if (u_zero_bits != 0)
+ {
+ mpn_rshift (up, tp, usize, u_zero_bits);
+ usize -= up[usize - 1] == 0;
+ }
+ else
+ MPN_COPY (up, tp, usize);
+
+ while (*vp == 0)
+ vp++;
+ v_zero_limbs = vp - PTR (v);
+ vsize -= v_zero_limbs;
+ count_trailing_zeros (v_zero_bits, *vp);
+ tp = vp;
+ vp = TMP_ALLOC_LIMBS (vsize);
+ if (v_zero_bits != 0)
+ {
+ mpn_rshift (vp, tp, vsize, v_zero_bits);
+ vsize -= vp[vsize - 1] == 0;
+ }
+ else
+ MPN_COPY (vp, tp, vsize);
+
+ if (u_zero_limbs > v_zero_limbs)
+ {
+ g_zero_limbs = v_zero_limbs;
+ g_zero_bits = v_zero_bits;
+ }
+ else if (u_zero_limbs < v_zero_limbs)
+ {
+ g_zero_limbs = u_zero_limbs;
+ g_zero_bits = u_zero_bits;
+ }
+ else /* Equal. */
+ {
+ g_zero_limbs = u_zero_limbs;
+ g_zero_bits = MIN (u_zero_bits, v_zero_bits);
+ }
+
+ /* Call mpn_gcd. The 2nd argument must not have more bits than the 1st. */
+ vsize = (usize < vsize || (usize == vsize && up[usize-1] < vp[vsize-1]))
+ ? mpn_gcd (vp, vp, vsize, up, usize)
+ : mpn_gcd (vp, up, usize, vp, vsize);
+
+ /* Here G <-- V << (g_zero_limbs*GMP_LIMB_BITS + g_zero_bits). */
+ gsize = vsize + g_zero_limbs;
+ if (g_zero_bits != 0)
+ {
+ mp_limb_t cy_limb;
+ gsize += (vp[vsize - 1] >> (GMP_NUMB_BITS - g_zero_bits)) != 0;
+ MPZ_REALLOC (g, gsize);
+ MPN_ZERO (PTR (g), g_zero_limbs);
+
+ tp = PTR(g) + g_zero_limbs;
+ cy_limb = mpn_lshift (tp, vp, vsize, g_zero_bits);
+ if (cy_limb != 0)
+ tp[vsize] = cy_limb;
+ }
+ else
+ {
+ MPZ_REALLOC (g, gsize);
+ MPN_ZERO (PTR (g), g_zero_limbs);
+ MPN_COPY (PTR (g) + g_zero_limbs, vp, vsize);
+ }
+
+ SIZ (g) = gsize;
+ TMP_FREE;
+}
diff --git a/gmp/mpz/gcd_ui.c b/gmp/mpz/gcd_ui.c
new file mode 100644
index 0000000000..e26d03f64a
--- /dev/null
+++ b/gmp/mpz/gcd_ui.c
@@ -0,0 +1,85 @@
+/* mpz_gcd_ui -- Calculate the greatest common divisor of two integers.
+
+Copyright 1994, 1996, 1999-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_gcd_ui (mpz_ptr w, mpz_srcptr u, unsigned long int v)
+{
+ mp_size_t un;
+ mp_limb_t res;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (v > GMP_NUMB_MAX)
+ {
+ mpz_t vz;
+ mp_limb_t vlimbs[2];
+ vlimbs[0] = v & GMP_NUMB_MASK;
+ vlimbs[1] = v >> GMP_NUMB_BITS;
+ PTR(vz) = vlimbs;
+ SIZ(vz) = 2;
+ mpz_gcd (w, u, vz);
+ /* because v!=0 we will have w<=v hence fitting a ulong */
+ ASSERT (mpz_fits_ulong_p (w));
+ return mpz_get_ui (w);
+ }
+#endif
+
+ un = ABSIZ(u);
+
+ if (un == 0)
+ res = v;
+ else if (v == 0)
+ {
+ if (w != NULL)
+ {
+ if (u != w)
+ {
+ MPZ_REALLOC (w, un);
+ MPN_COPY (PTR(w), PTR(u), un);
+ }
+ SIZ(w) = un;
+ }
+ /* Return u if it fits a ulong, otherwise 0. */
+ res = PTR(u)[0];
+ return (un == 1 && res <= ULONG_MAX ? res : 0);
+ }
+ else
+ res = mpn_gcd_1 (PTR(u), un, (mp_limb_t) v);
+
+ if (w != NULL)
+ {
+ PTR(w)[0] = res;
+ SIZ(w) = res != 0;
+ }
+ return res;
+}
diff --git a/gmp/mpz/gcdext.c b/gmp/mpz/gcdext.c
new file mode 100644
index 0000000000..01b1f8379a
--- /dev/null
+++ b/gmp/mpz/gcdext.c
@@ -0,0 +1,124 @@
+/* mpz_gcdext(g, s, t, a, b) -- Set G to gcd(a, b), and S and T such that
+ g = as + bt.
+
+Copyright 1991, 1993-1997, 2000, 2001, 2005, 2011, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_gcdext (mpz_ptr g, mpz_ptr s, mpz_ptr t, mpz_srcptr a, mpz_srcptr b)
+{
+ mp_size_t asize, bsize;
+ mp_ptr tmp_ap, tmp_bp;
+ mp_size_t gsize, ssize, tmp_ssize;
+ mp_ptr gp, tmp_gp, tmp_sp;
+ TMP_DECL;
+
+ /* mpn_gcdext requires that Usize >= Vsize. Therefore, we often
+ have to swap U and V. The computed cofactor will be the
+ "smallest" one, which is faster to produce. The wanted one will
+ be computed here; this is needed anyway when both are requested. */
+
+ asize = ABSIZ (a);
+ bsize = ABSIZ (b);
+
+ if (asize < bsize)
+ {
+ MPZ_SRCPTR_SWAP (a, b);
+ MP_SIZE_T_SWAP (asize, bsize);
+ MPZ_PTR_SWAP (s, t);
+ }
+
+ if (bsize == 0)
+ {
+ /* g = |a|, s = sgn(a), t = 0. */
+ ssize = SIZ (a) >= 0 ? (asize != 0) : -1;
+
+ gp = MPZ_REALLOC (g, asize);
+ MPN_COPY (gp, PTR (a), asize);
+ SIZ (g) = asize;
+
+ if (t != NULL)
+ SIZ (t) = 0;
+ if (s != NULL)
+ {
+ SIZ (s) = ssize;
+ PTR (s)[0] = 1;
+ }
+ return;
+ }
+
+ TMP_MARK;
+
+ TMP_ALLOC_LIMBS_2 (tmp_ap, asize, tmp_bp, bsize);
+ MPN_COPY (tmp_ap, PTR (a), asize);
+ MPN_COPY (tmp_bp, PTR (b), bsize);
+
+ TMP_ALLOC_LIMBS_2 (tmp_gp, bsize, tmp_sp, bsize + 1);
+
+ gsize = mpn_gcdext (tmp_gp, tmp_sp, &tmp_ssize, tmp_ap, asize, tmp_bp, bsize);
+
+ ssize = ABS (tmp_ssize);
+ tmp_ssize = SIZ (a) >= 0 ? tmp_ssize : -tmp_ssize;
+
+ if (t != NULL)
+ {
+ mpz_t x;
+ __mpz_struct gtmp, stmp;
+
+ PTR (&gtmp) = tmp_gp;
+ SIZ (&gtmp) = gsize;
+
+ PTR (&stmp) = tmp_sp;
+ SIZ (&stmp) = tmp_ssize;
+
+ MPZ_TMP_INIT (x, ssize + asize + 1);
+ mpz_mul (x, &stmp, a);
+ mpz_sub (x, &gtmp, x);
+ mpz_divexact (t, x, b);
+ }
+
+ if (s != NULL)
+ {
+ mp_ptr sp;
+
+ sp = MPZ_REALLOC (s, ssize);
+ MPN_COPY (sp, tmp_sp, ssize);
+ SIZ (s) = tmp_ssize;
+ }
+
+ gp = MPZ_REALLOC (g, gsize);
+ MPN_COPY (gp, tmp_gp, gsize);
+ SIZ (g) = gsize;
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/get_d.c b/gmp/mpz/get_d.c
new file mode 100644
index 0000000000..ac653c5ba0
--- /dev/null
+++ b/gmp/mpz/get_d.c
@@ -0,0 +1,44 @@
+/* double mpz_get_d (mpz_t src) -- Return the double approximation to SRC.
+
+Copyright 1996, 1997, 2000-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+double
+mpz_get_d (mpz_srcptr z)
+{
+ mp_size_t size;
+
+ size = SIZ (z);
+ if (UNLIKELY (size == 0))
+ return 0.0;
+
+ return mpn_get_d (PTR (z), ABS (size), size, 0L);
+}
diff --git a/gmp/mpz/get_d_2exp.c b/gmp/mpz/get_d_2exp.c
new file mode 100644
index 0000000000..96314851bf
--- /dev/null
+++ b/gmp/mpz/get_d_2exp.c
@@ -0,0 +1,54 @@
+/* double mpz_get_d_2exp (signed long int *exp, mpz_t src).
+
+Copyright 2001, 2003, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+double
+mpz_get_d_2exp (signed long int *exp2, mpz_srcptr src)
+{
+ mp_size_t size, abs_size;
+ mp_srcptr ptr;
+ long exp;
+
+ size = SIZ(src);
+ if (UNLIKELY (size == 0))
+ {
+ *exp2 = 0;
+ return 0.0;
+ }
+
+ ptr = PTR(src);
+ abs_size = ABS(size);
+ MPN_SIZEINBASE_2EXP(exp, ptr, abs_size, 1);
+ *exp2 = exp;
+ return mpn_get_d (ptr, abs_size, size, -exp);
+}
diff --git a/gmp/mpz/get_si.c b/gmp/mpz/get_si.c
new file mode 100644
index 0000000000..6e9752636b
--- /dev/null
+++ b/gmp/mpz/get_si.c
@@ -0,0 +1,53 @@
+/* mpz_get_si(integer) -- Return the least significant digit from INTEGER.
+
+Copyright 1991, 1993-1995, 2000-2002, 2006, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+signed long int
+mpz_get_si (mpz_srcptr z) __GMP_NOTHROW
+{
+ mp_ptr zp = PTR (z);
+ mp_size_t size = SIZ (z);
+ mp_limb_t zl = zp[0];
+
+#if GMP_NAIL_BITS != 0
+ if (ULONG_MAX > GMP_NUMB_MAX && ABS (size) >= 2)
+ zl |= zp[1] << GMP_NUMB_BITS;
+#endif
+
+ if (size > 0)
+ return zl & LONG_MAX;
+ else if (size < 0)
+ /* This expression is necessary to properly handle 0x80000000 */
+ return -1 - (long) ((zl - 1) & LONG_MAX);
+ else
+ return 0;
+}
diff --git a/gmp/mpz/get_str.c b/gmp/mpz/get_str.c
new file mode 100644
index 0000000000..08c7cd7371
--- /dev/null
+++ b/gmp/mpz/get_str.c
@@ -0,0 +1,119 @@
+/* mpz_get_str (string, base, mp_src) -- Convert the multiple precision
+ number MP_SRC to a string STRING of base BASE. If STRING is NULL
+ allocate space for the result. In any case, return a pointer to the
+ result. If STRING is not NULL, the caller must ensure enough space is
+ available to store the result.
+
+Copyright 1991, 1993, 1994, 1996, 2000-2002, 2005, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <string.h> /* for strlen */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+char *
+mpz_get_str (char *res_str, int base, mpz_srcptr x)
+{
+ mp_ptr xp;
+ mp_size_t x_size = SIZ (x);
+ char *return_str;
+ size_t str_size;
+ size_t alloc_size = 0;
+ const char *num_to_text;
+ int i;
+ TMP_DECL;
+
+ if (base >= 0)
+ {
+ num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz";
+ if (base <= 1)
+ base = 10;
+ else if (base > 36)
+ {
+ num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ if (base > 62)
+ return NULL;
+ }
+ }
+ else
+ {
+ base = -base;
+ if (base <= 1)
+ base = 10;
+ else if (base > 36)
+ return NULL;
+ num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ }
+
+ /* allocate string for the user if necessary */
+ if (res_str == NULL)
+ {
+ /* digits, null terminator, possible minus sign */
+ MPN_SIZEINBASE (alloc_size, PTR(x), ABS(x_size), base);
+ alloc_size += 1 + (x_size<0);
+ res_str = (char *) (*__gmp_allocate_func) (alloc_size);
+ }
+ return_str = res_str;
+
+ if (x_size < 0)
+ {
+ *res_str++ = '-';
+ x_size = -x_size;
+ }
+
+ /* mpn_get_str clobbers its input on non power-of-2 bases */
+ TMP_MARK;
+ xp = PTR (x);
+ if (! POW2_P (base))
+ {
+ xp = TMP_ALLOC_LIMBS (x_size | 1); /* |1 in case x_size==0 */
+ MPN_COPY (xp, PTR (x), x_size);
+ }
+
+ str_size = mpn_get_str ((unsigned char *) res_str, base, xp, x_size);
+ ASSERT (alloc_size == 0 || str_size <= alloc_size - (SIZ(x) < 0));
+
+ /* Convert result to printable chars. */
+ for (i = 0; i < str_size; i++)
+ res_str[i] = num_to_text[(int) res_str[i]];
+ res_str[str_size] = 0;
+
+ TMP_FREE;
+
+ /* if allocated then resize down to the actual space required */
+ if (alloc_size != 0)
+ {
+ size_t actual_size = str_size + 1 + (res_str - return_str);
+ ASSERT (actual_size == strlen (return_str) + 1);
+ __GMP_REALLOCATE_FUNC_MAYBE_TYPE (return_str, alloc_size, actual_size,
+ char);
+ }
+ return return_str;
+}
diff --git a/gmp/mpz/get_ui.c b/gmp/mpz/get_ui.c
new file mode 100644
index 0000000000..ca97788b74
--- /dev/null
+++ b/gmp/mpz/get_ui.c
@@ -0,0 +1,34 @@
+/* mpz_get_ui(integer) -- Return the least significant digit from INTEGER.
+
+Copyright 1991, 1993-1995, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_get_ui 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpz/getlimbn.c b/gmp/mpz/getlimbn.c
new file mode 100644
index 0000000000..c531f7e61f
--- /dev/null
+++ b/gmp/mpz/getlimbn.c
@@ -0,0 +1,34 @@
+/* mpz_getlimbn(integer,n) -- Return the N:th limb from INTEGER.
+
+Copyright 1993-1996, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_getlimbn 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpz/hamdist.c b/gmp/mpz/hamdist.c
new file mode 100644
index 0000000000..146769c394
--- /dev/null
+++ b/gmp/mpz/hamdist.c
@@ -0,0 +1,175 @@
+/* mpz_hamdist -- calculate hamming distance.
+
+Copyright 1994, 1996, 2001, 2002, 2009-2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+mp_bitcnt_t
+mpz_hamdist (mpz_srcptr u, mpz_srcptr v) __GMP_NOTHROW
+{
+ mp_srcptr up, vp;
+ mp_size_t usize, vsize;
+ mp_bitcnt_t count;
+
+ usize = SIZ(u);
+ vsize = SIZ(v);
+
+ up = PTR(u);
+ vp = PTR(v);
+
+ if (usize >= 0)
+ {
+ if (vsize < 0)
+ return ~ (mp_bitcnt_t) 0;
+
+ /* positive/positive */
+
+ if (usize < vsize)
+ MPN_SRCPTR_SWAP (up,usize, vp,vsize);
+
+ count = 0;
+ if (vsize != 0)
+ count = mpn_hamdist (up, vp, vsize);
+
+ usize -= vsize;
+ if (usize != 0)
+ count += mpn_popcount (up + vsize, usize);
+
+ return count;
+ }
+ else
+ {
+ mp_limb_t ulimb, vlimb;
+ mp_size_t old_vsize, step;
+
+ if (vsize >= 0)
+ return ~ (mp_bitcnt_t) 0;
+
+ /* negative/negative */
+
+ usize = -usize;
+ vsize = -vsize;
+
+ /* skip common low zeros */
+ for (;;)
+ {
+ ASSERT (usize > 0);
+ ASSERT (vsize > 0);
+
+ usize--;
+ vsize--;
+
+ ulimb = *up++;
+ vlimb = *vp++;
+
+ if (ulimb != 0)
+ break;
+
+ if (vlimb != 0)
+ {
+ MPN_SRCPTR_SWAP (up,usize, vp,vsize);
+ ulimb = vlimb;
+ vlimb = 0;
+ break;
+ }
+ }
+
+ /* twos complement first non-zero limbs (ulimb is non-zero, but vlimb
+ might be zero) */
+ ulimb = -ulimb;
+ vlimb = -vlimb;
+ popc_limb (count, (ulimb ^ vlimb) & GMP_NUMB_MASK);
+
+ if (vlimb == 0)
+ {
+ mp_bitcnt_t twoscount;
+
+ /* first non-zero of v */
+ old_vsize = vsize;
+ do
+ {
+ ASSERT (vsize > 0);
+ vsize--;
+ vlimb = *vp++;
+ }
+ while (vlimb == 0);
+
+ /* part of u corresponding to skipped v zeros */
+ step = old_vsize - vsize - 1;
+ count += step * GMP_NUMB_BITS;
+ step = MIN (step, usize);
+ if (step != 0)
+ {
+ count -= mpn_popcount (up, step);
+ usize -= step;
+ up += step;
+ }
+
+ /* First non-zero vlimb as twos complement, xor with ones
+ complement ulimb. Note -v^(~0^u) == (v-1)^u. */
+ vlimb--;
+ if (usize != 0)
+ {
+ usize--;
+ vlimb ^= *up++;
+ }
+ popc_limb (twoscount, vlimb);
+ count += twoscount;
+ }
+
+ /* Overlapping part of u and v, if any. Ones complement both, so just
+ plain hamdist. */
+ step = MIN (usize, vsize);
+ if (step != 0)
+ {
+ count += mpn_hamdist (up, vp, step);
+ usize -= step;
+ vsize -= step;
+ up += step;
+ vp += step;
+ }
+
+ /* Remaining high part of u or v, if any, ones complement but xor
+ against all ones in the other, so plain popcount. */
+ if (usize != 0)
+ {
+ remaining:
+ count += mpn_popcount (up, usize);
+ }
+ else if (vsize != 0)
+ {
+ up = vp;
+ usize = vsize;
+ goto remaining;
+ }
+ return count;
+ }
+}
diff --git a/gmp/mpz/import.c b/gmp/mpz/import.c
new file mode 100644
index 0000000000..9072830afe
--- /dev/null
+++ b/gmp/mpz/import.c
@@ -0,0 +1,180 @@
+/* mpz_import -- set mpz from word data.
+
+Copyright 2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+
+#if HAVE_LIMB_BIG_ENDIAN
+#define HOST_ENDIAN 1
+#endif
+#if HAVE_LIMB_LITTLE_ENDIAN
+#define HOST_ENDIAN (-1)
+#endif
+#ifndef HOST_ENDIAN
+static const mp_limb_t endian_test = (CNST_LIMB(1) << (GMP_LIMB_BITS-7)) - 1;
+#define HOST_ENDIAN (* (signed char *) &endian_test)
+#endif
+
+
+void
+mpz_import (mpz_ptr z, size_t count, int order,
+ size_t size, int endian, size_t nail, const void *data)
+{
+ mp_size_t zsize;
+ mp_ptr zp;
+
+ ASSERT (order == 1 || order == -1);
+ ASSERT (endian == 1 || endian == 0 || endian == -1);
+ ASSERT (nail <= 8*size);
+
+ zsize = BITS_TO_LIMBS (count * (8*size - nail));
+ zp = MPZ_NEWALLOC (z, zsize);
+
+ if (endian == 0)
+ endian = HOST_ENDIAN;
+
+ /* Can't use these special cases with nails currently, since they don't
+ mask out the nail bits in the input data. */
+ if (nail == 0 && GMP_NAIL_BITS == 0)
+ {
+ unsigned align = ((char *) data - (char *) NULL) % sizeof (mp_limb_t);
+
+ if (order == -1
+ && size == sizeof (mp_limb_t)
+ && endian == HOST_ENDIAN
+ && align == 0)
+ {
+ MPN_COPY (zp, (mp_srcptr) data, (mp_size_t) count);
+ goto done;
+ }
+
+ if (order == -1
+ && size == sizeof (mp_limb_t)
+ && endian == - HOST_ENDIAN
+ && align == 0)
+ {
+ MPN_BSWAP (zp, (mp_srcptr) data, (mp_size_t) count);
+ goto done;
+ }
+
+ if (order == 1
+ && size == sizeof (mp_limb_t)
+ && endian == HOST_ENDIAN
+ && align == 0)
+ {
+ MPN_REVERSE (zp, (mp_srcptr) data, (mp_size_t) count);
+ goto done;
+ }
+ }
+
+ {
+ mp_limb_t limb, byte, wbitsmask;
+ size_t i, j, numb, wbytes;
+ mp_size_t woffset;
+ unsigned char *dp;
+ int lbits, wbits;
+
+ numb = size * 8 - nail;
+
+ /* whole bytes to process */
+ wbytes = numb / 8;
+
+ /* partial byte to process */
+ wbits = numb % 8;
+ wbitsmask = (CNST_LIMB(1) << wbits) - 1;
+
+ /* offset to get to the next word after processing wbytes and wbits */
+ woffset = (numb + 7) / 8;
+ woffset = (endian >= 0 ? woffset : -woffset)
+ + (order < 0 ? size : - (mp_size_t) size);
+
+ /* least significant byte */
+ dp = (unsigned char *) data
+ + (order >= 0 ? (count-1)*size : 0) + (endian >= 0 ? size-1 : 0);
+
+#define ACCUMULATE(N) \
+ do { \
+ ASSERT (lbits < GMP_NUMB_BITS); \
+ ASSERT (limb <= (CNST_LIMB(1) << lbits) - 1); \
+ \
+ limb |= (mp_limb_t) byte << lbits; \
+ lbits += (N); \
+ if (lbits >= GMP_NUMB_BITS) \
+ { \
+ *zp++ = limb & GMP_NUMB_MASK; \
+ lbits -= GMP_NUMB_BITS; \
+ ASSERT (lbits < (N)); \
+ limb = byte >> ((N) - lbits); \
+ } \
+ } while (0)
+
+ limb = 0;
+ lbits = 0;
+ for (i = 0; i < count; i++)
+ {
+ for (j = 0; j < wbytes; j++)
+ {
+ byte = *dp;
+ dp -= endian;
+ ACCUMULATE (8);
+ }
+ if (wbits != 0)
+ {
+ byte = *dp & wbitsmask;
+ dp -= endian;
+ ACCUMULATE (wbits);
+ }
+ dp += woffset;
+ }
+
+ if (lbits != 0)
+ {
+ ASSERT (lbits <= GMP_NUMB_BITS);
+ ASSERT_LIMB (limb);
+ *zp++ = limb;
+ }
+
+ ASSERT (zp == PTR(z) + zsize);
+
+ /* low byte of word after most significant */
+ ASSERT (dp == (unsigned char *) data
+ + (order < 0 ? count*size : - (mp_size_t) size)
+ + (endian >= 0 ? (mp_size_t) size - 1 : 0));
+
+ }
+
+ done:
+ zp = PTR(z);
+ MPN_NORMALIZE (zp, zsize);
+ SIZ(z) = zsize;
+}
diff --git a/gmp/mpz/init.c b/gmp/mpz/init.c
new file mode 100644
index 0000000000..09df9df5c8
--- /dev/null
+++ b/gmp/mpz/init.c
@@ -0,0 +1,45 @@
+/* mpz_init() -- Make a new multiple precision number with value 0.
+
+Copyright 1991, 1993-1995, 2000-2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_init (mpz_ptr x)
+{
+ ALLOC (x) = 1;
+ PTR (x) = (mp_ptr) (*__gmp_allocate_func) (GMP_LIMB_BYTES);
+ SIZ (x) = 0;
+
+#ifdef __CHECKER__
+ /* let the low limb look initialized, for the benefit of mpz_get_ui etc */
+ PTR (x) = 0;
+#endif
+}
diff --git a/gmp/mpz/init2.c b/gmp/mpz/init2.c
new file mode 100644
index 0000000000..b942e499d6
--- /dev/null
+++ b/gmp/mpz/init2.c
@@ -0,0 +1,61 @@
+/* mpz_init2 -- initialize mpz, with requested size in bits.
+
+Copyright 2001, 2002, 2008 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_init2 (mpz_ptr x, mp_bitcnt_t bits)
+{
+ mp_size_t new_alloc;
+
+ bits -= (bits != 0); /* Round down, except if 0 */
+ new_alloc = 1 + bits / GMP_NUMB_BITS;
+
+ if (sizeof (unsigned long) > sizeof (int)) /* param vs _mp_size field */
+ {
+ if (UNLIKELY (new_alloc > INT_MAX))
+ {
+ fprintf (stderr, "gmp: overflow in mpz type\n");
+ abort ();
+ }
+ }
+
+ PTR(x) = __GMP_ALLOCATE_FUNC_LIMBS (new_alloc);
+ ALLOC(x) = new_alloc;
+ SIZ(x) = 0;
+
+#ifdef __CHECKER__
+ /* let the low limb look initialized, for the benefit of mpz_get_ui etc */
+ PTR(x)[0] = 0;
+#endif
+}
diff --git a/gmp/mpz/inits.c b/gmp/mpz/inits.c
new file mode 100644
index 0000000000..0488edaa44
--- /dev/null
+++ b/gmp/mpz/inits.c
@@ -0,0 +1,49 @@
+/* mpz_inits() -- Initialize multiple mpz_t variables and set them to 0.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_inits (mpz_ptr x, ...)
+{
+ va_list ap;
+
+ va_start (ap, x);
+
+ while (x != NULL)
+ {
+ mpz_init (x);
+ x = va_arg (ap, mpz_ptr);
+ }
+ va_end (ap);
+}
diff --git a/gmp/mpz/inp_raw.c b/gmp/mpz/inp_raw.c
new file mode 100644
index 0000000000..d95c19ede7
--- /dev/null
+++ b/gmp/mpz/inp_raw.c
@@ -0,0 +1,173 @@
+/* mpz_inp_raw -- read an mpz_t in raw format.
+
+Copyright 2001, 2002, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* NTOH_LIMB_FETCH fetches a limb which is in network byte order (ie. big
+ endian) and produces a normal host byte order result. */
+
+#if HAVE_LIMB_BIG_ENDIAN
+#define NTOH_LIMB_FETCH(limb, src) do { (limb) = *(src); } while (0)
+#endif
+
+#if HAVE_LIMB_LITTLE_ENDIAN
+#define NTOH_LIMB_FETCH(limb, src) BSWAP_LIMB_FETCH (limb, src)
+#endif
+
+#ifndef NTOH_LIMB_FETCH
+#define NTOH_LIMB_FETCH(limb, src) \
+ do { \
+ const unsigned char *__p = (const unsigned char *) (src); \
+ mp_limb_t __limb; \
+ int __i; \
+ __limb = 0; \
+ for (__i = 0; __i < GMP_LIMB_BYTES; __i++) \
+ __limb = (__limb << 8) | __p[__i]; \
+ (limb) = __limb; \
+ } while (0)
+#endif
+
+
+/* Enhancement: The byte swap loop ought to be safe to vectorize on Cray
+ etc, but someone who knows what they're doing needs to check it. */
+
+size_t
+mpz_inp_raw (mpz_ptr x, FILE *fp)
+{
+ unsigned char csize_bytes[4];
+ mp_size_t csize, abs_xsize, i;
+ size_t abs_csize;
+ char *cp;
+ mp_ptr xp, sp, ep;
+ mp_limb_t slimb, elimb;
+
+ if (fp == 0)
+ fp = stdin;
+
+ /* 4 bytes for size */
+ if (fread (csize_bytes, sizeof (csize_bytes), 1, fp) != 1)
+ return 0;
+
+ csize =
+ ( (mp_size_t) csize_bytes[0] << 24)
+ + ((mp_size_t) csize_bytes[1] << 16)
+ + ((mp_size_t) csize_bytes[2] << 8)
+ + ((mp_size_t) csize_bytes[3]);
+
+ /* Sign extend if necessary.
+ Could write "csize -= ((csize & 0x80000000L) << 1)", but that tickles a
+ bug in gcc 3.0 for powerpc64 on AIX. */
+ if (sizeof (csize) > 4 && csize & 0x80000000L)
+ csize -= 0x80000000L << 1;
+
+ abs_csize = ABS (csize);
+
+ /* round up to a multiple of limbs */
+ abs_xsize = BITS_TO_LIMBS (abs_csize*8);
+
+ if (abs_xsize != 0)
+ {
+ xp = MPZ_NEWALLOC (x, abs_xsize);
+
+ /* Get limb boundaries right in the read, for the benefit of the
+ non-nails case. */
+ xp[0] = 0;
+ cp = (char *) (xp + abs_xsize) - abs_csize;
+ if (fread (cp, abs_csize, 1, fp) != 1)
+ return 0;
+
+ if (GMP_NAIL_BITS == 0)
+ {
+ /* Reverse limbs to least significant first, and byte swap. If
+ abs_xsize is odd then on the last iteration elimb and slimb are
+ the same. It doesn't seem extra code to handle that case
+ separately, to save an NTOH. */
+ sp = xp;
+ ep = xp + abs_xsize-1;
+ for (i = 0; i < (abs_xsize+1)/2; i++)
+ {
+ NTOH_LIMB_FETCH (elimb, ep);
+ NTOH_LIMB_FETCH (slimb, sp);
+ *sp++ = elimb;
+ *ep-- = slimb;
+ }
+ }
+ else
+ {
+ /* It ought to be possible to do the transformation in-place, but
+ for now it's easier to use an extra temporary area. */
+ mp_limb_t byte, limb;
+ int bits;
+ mp_size_t tpos;
+ mp_ptr tp;
+ TMP_DECL;
+
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS (abs_xsize);
+ limb = 0;
+ bits = 0;
+ tpos = 0;
+ for (i = abs_csize-1; i >= 0; i--)
+ {
+ byte = (unsigned char) cp[i];
+ limb |= (byte << bits);
+ bits += 8;
+ if (bits >= GMP_NUMB_BITS)
+ {
+ ASSERT (tpos < abs_xsize);
+ tp[tpos++] = limb & GMP_NUMB_MASK;
+ bits -= GMP_NUMB_BITS;
+ ASSERT (bits < 8);
+ limb = byte >> (8 - bits);
+ }
+ }
+ if (bits != 0)
+ {
+ ASSERT (tpos < abs_xsize);
+ tp[tpos++] = limb;
+ }
+ ASSERT (tpos == abs_xsize);
+
+ MPN_COPY (xp, tp, abs_xsize);
+ TMP_FREE;
+ }
+
+ /* GMP 1.x mpz_out_raw wrote high zero bytes, strip any high zero
+ limbs resulting from this. Should be a non-zero value here, but
+ for safety don't assume that. */
+ MPN_NORMALIZE (xp, abs_xsize);
+ }
+
+ SIZ(x) = (csize >= 0 ? abs_xsize : -abs_xsize);
+ return abs_csize + 4;
+}
diff --git a/gmp/mpz/inp_str.c b/gmp/mpz/inp_str.c
new file mode 100644
index 0000000000..474bc68435
--- /dev/null
+++ b/gmp/mpz/inp_str.c
@@ -0,0 +1,174 @@
+/* mpz_inp_str(dest_integer, stream, base) -- Input a number in base
+ BASE from stdio stream STREAM and store the result in DEST_INTEGER.
+
+ OF THE FUNCTIONS IN THIS FILE, ONLY mpz_inp_str IS FOR EXTERNAL USE, THE
+ REST ARE INTERNALS AND ARE ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE
+ CHANGES OR DISAPPEAR COMPLETELY IN FUTURE GNU MP RELEASES.
+
+Copyright 1991, 1993, 1994, 1996, 1998, 2000-2003, 2011-2013 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#define digit_value_tab __gmp_digit_value_tab
+
+size_t
+mpz_inp_str (mpz_ptr x, FILE *stream, int base)
+{
+ int c;
+ size_t nread;
+
+ if (stream == 0)
+ stream = stdin;
+
+ nread = 0;
+
+ /* Skip whitespace. */
+ do
+ {
+ c = getc (stream);
+ nread++;
+ }
+ while (isspace (c));
+
+ return mpz_inp_str_nowhite (x, stream, base, c, nread);
+}
+
+/* shared by mpq_inp_str */
+size_t
+mpz_inp_str_nowhite (mpz_ptr x, FILE *stream, int base, int c, size_t nread)
+{
+ char *str;
+ size_t alloc_size, str_size;
+ int negative;
+ mp_size_t xsize;
+ const unsigned char *digit_value;
+
+ ASSERT_ALWAYS (EOF == -1); /* FIXME: handle this by adding explicit */
+ /* comparisons of c and EOF before each */
+ /* read of digit_value[]. */
+
+ digit_value = digit_value_tab;
+ if (base > 36)
+ {
+ /* For bases > 36, use the collating sequence
+ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz. */
+ digit_value += 208;
+ if (base > 62)
+ return 0; /* too large base */
+ }
+
+ negative = 0;
+ if (c == '-')
+ {
+ negative = 1;
+ c = getc (stream);
+ nread++;
+ }
+
+ if (c == EOF || digit_value[c] >= (base == 0 ? 10 : base))
+ return 0; /* error if no digits */
+
+ /* If BASE is 0, try to find out the base by looking at the initial
+ characters. */
+ if (base == 0)
+ {
+ base = 10;
+ if (c == '0')
+ {
+ base = 8;
+ c = getc (stream);
+ nread++;
+ if (c == 'x' || c == 'X')
+ {
+ base = 16;
+ c = getc (stream);
+ nread++;
+ }
+ else if (c == 'b' || c == 'B')
+ {
+ base = 2;
+ c = getc (stream);
+ nread++;
+ }
+ }
+ }
+
+ /* Skip leading zeros. */
+ while (c == '0')
+ {
+ c = getc (stream);
+ nread++;
+ }
+
+ alloc_size = 100;
+ str = (char *) (*__gmp_allocate_func) (alloc_size);
+ str_size = 0;
+
+ while (c != EOF)
+ {
+ int dig;
+ dig = digit_value[c];
+ if (dig >= base)
+ break;
+ if (str_size >= alloc_size)
+ {
+ size_t old_alloc_size = alloc_size;
+ alloc_size = alloc_size * 3 / 2;
+ str = (char *) (*__gmp_reallocate_func) (str, old_alloc_size, alloc_size);
+ }
+ str[str_size++] = dig;
+ c = getc (stream);
+ }
+ nread += str_size;
+
+ ungetc (c, stream);
+ nread--;
+
+ /* Make sure the string is not empty, mpn_set_str would fail. */
+ if (str_size == 0)
+ {
+ SIZ (x) = 0;
+ }
+ else
+ {
+ LIMBS_PER_DIGIT_IN_BASE (xsize, str_size, base);
+ MPZ_REALLOC (x, xsize);
+
+ /* Convert the byte array in base BASE to our bignum format. */
+ xsize = mpn_set_str (PTR (x), (unsigned char *) str, str_size, base);
+ SIZ (x) = negative ? -xsize : xsize;
+ }
+ (*__gmp_free_func) (str, alloc_size);
+ return nread;
+}
diff --git a/gmp/mpz/invert.c b/gmp/mpz/invert.c
new file mode 100644
index 0000000000..09cdd9a121
--- /dev/null
+++ b/gmp/mpz/invert.c
@@ -0,0 +1,73 @@
+/* mpz_invert (inv, x, n). Find multiplicative inverse of X in Z(N).
+ If X has an inverse, return non-zero and store inverse in INVERSE,
+ otherwise, return 0 and put garbage in INVERSE.
+
+Copyright 1996-2001, 2005, 2012, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpz_invert (mpz_ptr inverse, mpz_srcptr x, mpz_srcptr n)
+{
+ mpz_t gcd, tmp;
+ mp_size_t xsize, nsize, size;
+ TMP_DECL;
+
+ xsize = ABSIZ (x);
+ nsize = ABSIZ (n);
+
+ size = MAX (xsize, nsize) + 1;
+ TMP_MARK;
+
+ MPZ_TMP_INIT (gcd, size);
+ MPZ_TMP_INIT (tmp, size);
+ mpz_gcdext (gcd, tmp, (mpz_ptr) 0, x, n);
+
+ /* If no inverse existed, return with an indication of that. */
+ if (!MPZ_EQUAL_1_P (gcd))
+ {
+ TMP_FREE;
+ return 0;
+ }
+
+ /* Make sure we return a positive inverse. */
+ if (SIZ (tmp) < 0)
+ {
+ if (SIZ (n) < 0)
+ mpz_sub (inverse, tmp, n);
+ else
+ mpz_add (inverse, tmp, n);
+ }
+ else
+ mpz_set (inverse, tmp);
+
+ TMP_FREE;
+ return 1;
+}
diff --git a/gmp/mpz/ior.c b/gmp/mpz/ior.c
new file mode 100644
index 0000000000..5c181f04c4
--- /dev/null
+++ b/gmp/mpz/ior.c
@@ -0,0 +1,230 @@
+/* mpz_ior -- Logical inclusive or.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2005, 2012, 2013 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_ior (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2)
+{
+ mp_srcptr op1_ptr, op2_ptr;
+ mp_size_t op1_size, op2_size;
+ mp_ptr res_ptr;
+ mp_size_t res_size;
+ mp_size_t i;
+ TMP_DECL;
+
+ TMP_MARK;
+ op1_size = SIZ(op1);
+ op2_size = SIZ(op2);
+
+ op1_ptr = PTR(op1);
+ op2_ptr = PTR(op2);
+ res_ptr = PTR(res);
+
+ if (op1_size >= 0)
+ {
+ if (op2_size >= 0)
+ {
+ if (op1_size >= op2_size)
+ {
+ if (ALLOC(res) < op1_size)
+ {
+ res_ptr = MPZ_REALLOC (res, op1_size);
+ /* No overlapping possible: op1_ptr = PTR(op1); */
+ op2_ptr = PTR(op2);
+ }
+
+ if (res_ptr != op1_ptr)
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size,
+ op1_size - op2_size);
+ if (LIKELY (op2_size != 0))
+ mpn_ior_n (res_ptr, op1_ptr, op2_ptr, op2_size);
+ res_size = op1_size;
+ }
+ else
+ {
+ if (ALLOC(res) < op2_size)
+ {
+ res_ptr = MPZ_REALLOC (res, op2_size);
+ op1_ptr = PTR(op1);
+ /* No overlapping possible: op2_ptr = PTR(op2); */
+ }
+
+ if (res_ptr != op2_ptr)
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size,
+ op2_size - op1_size);
+ if (LIKELY (op1_size != 0))
+ mpn_ior_n (res_ptr, op1_ptr, op2_ptr, op1_size);
+ res_size = op2_size;
+ }
+
+ SIZ(res) = res_size;
+ return;
+ }
+ else /* op2_size < 0 */
+ {
+ /* Fall through to the code at the end of the function. */
+ }
+ }
+ else
+ {
+ if (op2_size < 0)
+ {
+ mp_ptr opx, opy;
+
+ /* Both operands are negative, so will be the result.
+ -((-OP1) | (-OP2)) = -(~(OP1 - 1) | ~(OP2 - 1)) =
+ = ~(~(OP1 - 1) | ~(OP2 - 1)) + 1 =
+ = ((OP1 - 1) & (OP2 - 1)) + 1 */
+
+ op1_size = -op1_size;
+ op2_size = -op2_size;
+
+ res_size = MIN (op1_size, op2_size);
+
+ /* Possible optimization: Decrease mpn_sub precision,
+ as we won't use the entire res of both. */
+ TMP_ALLOC_LIMBS_2 (opx, res_size, opy, res_size);
+ mpn_sub_1 (opx, op1_ptr, res_size, (mp_limb_t) 1);
+ op1_ptr = opx;
+
+ mpn_sub_1 (opy, op2_ptr, res_size, (mp_limb_t) 1);
+ op2_ptr = opy;
+
+ /* First loop finds the size of the result. */
+ for (i = res_size - 1; i >= 0; i--)
+ if ((op1_ptr[i] & op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+
+ if (res_size != 0)
+ {
+ res_ptr = MPZ_NEWALLOC (res, res_size + 1);
+
+ /* Second loop computes the real result. */
+ mpn_and_n (res_ptr, op1_ptr, op2_ptr, res_size);
+
+ res_ptr[res_size] = 0;
+ MPN_INCR_U (res_ptr, res_size + 1, 1);
+ res_size += res_ptr[res_size];
+ }
+ else
+ {
+ res_ptr[0] = 1;
+ res_size = 1;
+ }
+
+ SIZ(res) = -res_size;
+ TMP_FREE;
+ return;
+ }
+ else
+ {
+ /* We should compute -OP1 | OP2. Swap OP1 and OP2 and fall
+ through to the code that handles OP1 | -OP2. */
+ MPZ_SRCPTR_SWAP (op1, op2);
+ MPN_SRCPTR_SWAP (op1_ptr,op1_size, op2_ptr,op2_size);
+ }
+ }
+
+ {
+ mp_ptr opx;
+ mp_limb_t cy;
+ mp_size_t res_alloc;
+ mp_size_t count;
+
+ /* Operand 2 negative, so will be the result.
+ -(OP1 | (-OP2)) = -(OP1 | ~(OP2 - 1)) =
+ = ~(OP1 | ~(OP2 - 1)) + 1 =
+ = (~OP1 & (OP2 - 1)) + 1 */
+
+ op2_size = -op2_size;
+
+ res_alloc = op2_size;
+
+ opx = TMP_ALLOC_LIMBS (op2_size);
+ mpn_sub_1 (opx, op2_ptr, op2_size, (mp_limb_t) 1);
+ op2_ptr = opx;
+ op2_size -= op2_ptr[op2_size - 1] == 0;
+
+ if (ALLOC(res) < res_alloc)
+ {
+ _mpz_realloc (res, res_alloc);
+ op1_ptr = PTR(op1);
+ /* op2_ptr points to temporary space. */
+ res_ptr = PTR(res);
+ }
+
+ if (op1_size >= op2_size)
+ {
+ /* We can just ignore the part of OP1 that stretches above OP2,
+ because the result limbs are zero there. */
+
+ /* First loop finds the size of the result. */
+ for (i = op2_size - 1; i >= 0; i--)
+ if ((~op1_ptr[i] & op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+ count = res_size;
+ }
+ else
+ {
+ res_size = op2_size;
+
+ /* Copy the part of OP2 that stretches above OP1, to RES. */
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size);
+ count = op1_size;
+ }
+
+ if (res_size != 0)
+ {
+ /* Second loop computes the real result. */
+ if (LIKELY (count != 0))
+ mpn_andn_n (res_ptr, op2_ptr, op1_ptr, count);
+
+ cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1);
+ if (cy)
+ {
+ res_ptr[res_size] = cy;
+ res_size++;
+ }
+ }
+ else
+ {
+ res_ptr[0] = 1;
+ res_size = 1;
+ }
+
+ SIZ(res) = -res_size;
+ }
+ TMP_FREE;
+}
diff --git a/gmp/mpz/iset.c b/gmp/mpz/iset.c
new file mode 100644
index 0000000000..b6fbf490fd
--- /dev/null
+++ b/gmp/mpz/iset.c
@@ -0,0 +1,59 @@
+/* mpz_init_set (src_integer) -- Make a new multiple precision number with
+ a value copied from SRC_INTEGER.
+
+Copyright 1991, 1993, 1994, 1996, 2000-2002, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_init_set (mpz_ptr w, mpz_srcptr u)
+{
+ mp_ptr wp, up;
+ mp_size_t usize, size;
+
+ usize = SIZ (u);
+ size = ABS (usize);
+
+ ALLOC (w) = MAX (size, 1);
+ PTR (w) = (mp_ptr) (*__gmp_allocate_func) ((size_t) ALLOC (w) * GMP_LIMB_BYTES);
+
+ wp = PTR (w);
+ up = PTR (u);
+
+ MPN_COPY (wp, up, size);
+ SIZ (w) = usize;
+
+#ifdef __CHECKER__
+ /* let the low limb look initialized, for the benefit of mpz_get_ui etc */
+ if (size == 0)
+ wp[0] = 0;
+#endif
+}
diff --git a/gmp/mpz/iset_d.c b/gmp/mpz/iset_d.c
new file mode 100644
index 0000000000..a450abcb3e
--- /dev/null
+++ b/gmp/mpz/iset_d.c
@@ -0,0 +1,42 @@
+/* mpz_init_set_d(integer, val) -- Initialize and assign INTEGER with a double
+ value VAL.
+
+Copyright 1996, 2000, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_init_set_d (mpz_ptr dest, double val)
+{
+ ALLOC (dest) = 1;
+ PTR (dest) = (mp_ptr) (*__gmp_allocate_func) (GMP_LIMB_BYTES);
+ SIZ (dest) = 0;
+ mpz_set_d (dest, val);
+}
diff --git a/gmp/mpz/iset_si.c b/gmp/mpz/iset_si.c
new file mode 100644
index 0000000000..107577795a
--- /dev/null
+++ b/gmp/mpz/iset_si.c
@@ -0,0 +1,59 @@
+/* mpz_init_set_si(dest,val) -- Make a new multiple precision in DEST and
+ assign VAL to the new number.
+
+Copyright 1991, 1993-1995, 2000-2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_init_set_si (mpz_ptr dest, signed long int val)
+{
+ mp_size_t size;
+ mp_limb_t vl;
+
+ ALLOC (dest) = 1;
+ PTR (dest) = (mp_ptr) (*__gmp_allocate_func) (GMP_LIMB_BYTES);
+
+ vl = (mp_limb_t) ABS_CAST (unsigned long int, val);
+
+ PTR (dest)[0] = vl & GMP_NUMB_MASK;
+ size = vl != 0;
+
+#if GMP_NAIL_BITS != 0
+ if (vl > GMP_NUMB_MAX)
+ {
+ MPZ_REALLOC (dest, 2);
+ PTR (dest)[1] = vl >> GMP_NUMB_BITS;
+ size = 2;
+ }
+#endif
+
+ SIZ (dest) = val >= 0 ? size : -size;
+}
diff --git a/gmp/mpz/iset_str.c b/gmp/mpz/iset_str.c
new file mode 100644
index 0000000000..e31742ce65
--- /dev/null
+++ b/gmp/mpz/iset_str.c
@@ -0,0 +1,52 @@
+/* mpz_init_set_str(string, base) -- Convert the \0-terminated string STRING in
+ base BASE to a multiple precision integer. Allow white space in the string.
+ If BASE == 0 determine the base in the C standard way, i.e. 0xhh...h means
+ base 16, 0oo...o means base 8, otherwise assume base 10.
+
+Copyright 1991, 1993-1995, 2000-2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpz_init_set_str (mpz_ptr x, const char *str, int base)
+{
+ ALLOC (x) = 1;
+ PTR (x) = (mp_ptr) (*__gmp_allocate_func) (GMP_LIMB_BYTES);
+
+ /* if str has no digits mpz_set_str leaves x->_mp_size unset */
+ SIZ (x) = 0;
+
+#ifdef __CHECKER__
+ /* let the low limb look initialized, for the benefit of mpz_get_ui etc */
+ PTR (x)[0] = 0;
+#endif
+
+ return mpz_set_str (x, str, base);
+}
diff --git a/gmp/mpz/iset_ui.c b/gmp/mpz/iset_ui.c
new file mode 100644
index 0000000000..0d43c68411
--- /dev/null
+++ b/gmp/mpz/iset_ui.c
@@ -0,0 +1,59 @@
+/* mpz_init_set_ui(dest,val) -- Make a new multiple precision in DEST and
+ assign VAL to the new number.
+
+Copyright 1991, 1993-1995, 2000-2002, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_init_set_ui (mpz_ptr dest, unsigned long int val)
+{
+ mp_size_t size;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (val > GMP_NUMB_MAX)
+ {
+ ALLOC (dest) = 2;
+ PTR (dest) = (mp_ptr) (*__gmp_allocate_func) (GMP_LIMB_BYTES*2);
+ PTR (dest)[1] = val >> GMP_NUMB_BITS;
+ size = 2;
+ }
+ else
+#endif
+ {
+ ALLOC (dest) = 1;
+ PTR (dest) = (mp_ptr) (*__gmp_allocate_func) (GMP_LIMB_BYTES);
+
+ size = val != 0;
+ }
+ PTR (dest)[0] = val & GMP_NUMB_MASK;
+
+ SIZ (dest) = size;
+}
diff --git a/gmp/mpz/jacobi.c b/gmp/mpz/jacobi.c
new file mode 100644
index 0000000000..397fe11c9b
--- /dev/null
+++ b/gmp/mpz/jacobi.c
@@ -0,0 +1,211 @@
+/* mpz_jacobi, mpz_legendre, mpz_kronecker -- mpz/mpz Jacobi symbols.
+
+Copyright 2000-2002, 2005, 2010-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* This code does triple duty as mpz_jacobi, mpz_legendre and
+ mpz_kronecker. For ABI compatibility, the link symbol is
+ __gmpz_jacobi, not __gmpz_kronecker, even though the latter would
+ be more logical.
+
+ mpz_jacobi could assume b is odd, but the improvements from that seem
+ small compared to other operations, and anything significant should be
+ checked at run-time since we'd like odd b to go fast in mpz_kronecker
+ too.
+
+ mpz_legendre could assume b is an odd prime, but knowing this doesn't
+ present any obvious benefits. Result 0 wouldn't arise (unless "a" is a
+ multiple of b), but the checking for that takes little time compared to
+ other operations.
+
+ Enhancements:
+
+ mpn_bdiv_qr should be used instead of mpn_tdiv_qr.
+
+*/
+
+int
+mpz_jacobi (mpz_srcptr a, mpz_srcptr b)
+{
+ mp_srcptr asrcp, bsrcp;
+ mp_size_t asize, bsize;
+ mp_limb_t alow, blow;
+ mp_ptr ap, bp;
+ unsigned btwos;
+ int result_bit1;
+ int res;
+ TMP_DECL;
+
+ asize = SIZ(a);
+ asrcp = PTR(a);
+ alow = asrcp[0];
+
+ bsize = SIZ(b);
+ bsrcp = PTR(b);
+ blow = bsrcp[0];
+
+ /* The MPN jacobi functions require positive a and b, and b odd. So
+ we must to handle the cases of a or b zero, then signs, and then
+ the case of even b.
+ */
+
+ if (bsize == 0)
+ /* (a/0) = [ a = 1 or a = -1 ] */
+ return JACOBI_LS0 (alow, asize);
+
+ if (asize == 0)
+ /* (0/b) = [ b = 1 or b = - 1 ] */
+ return JACOBI_0LS (blow, bsize);
+
+ if ( (((alow | blow) & 1) == 0))
+ /* Common factor of 2 ==> (a/b) = 0 */
+ return 0;
+
+ if (bsize < 0)
+ {
+ /* (a/-1) = -1 if a < 0, +1 if a >= 0 */
+ result_bit1 = (asize < 0) << 1;
+ bsize = -bsize;
+ }
+ else
+ result_bit1 = 0;
+
+ JACOBI_STRIP_LOW_ZEROS (result_bit1, alow, bsrcp, bsize, blow);
+
+ count_trailing_zeros (btwos, blow);
+ blow >>= btwos;
+
+ if (bsize > 1 && btwos > 0)
+ {
+ mp_limb_t b1 = bsrcp[1];
+ blow |= b1 << (GMP_NUMB_BITS - btwos);
+ if (bsize == 2 && (b1 >> btwos) == 0)
+ bsize = 1;
+ }
+
+ if (asize < 0)
+ {
+ /* (-1/b) = -1 iff b = 3 (mod 4) */
+ result_bit1 ^= JACOBI_N1B_BIT1(blow);
+ asize = -asize;
+ }
+
+ JACOBI_STRIP_LOW_ZEROS (result_bit1, blow, asrcp, asize, alow);
+
+ /* Ensure asize >= bsize. Take advantage of the generalized
+ reciprocity law (a/b*2^n) = (b*2^n / a) * RECIP(a,b) */
+
+ if (asize < bsize)
+ {
+ MPN_SRCPTR_SWAP (asrcp, asize, bsrcp, bsize);
+ MP_LIMB_T_SWAP (alow, blow);
+
+ /* NOTE: The value of alow (old blow) is a bit subtle. For this code
+ path, we get alow as the low, always odd, limb of shifted A. Which is
+ what we need for the reciprocity update below.
+
+ However, all other uses of alow assumes that it is *not*
+ shifted. Luckily, alow matters only when either
+
+ + btwos > 0, in which case A is always odd
+
+ + asize == bsize == 1, in which case this code path is never
+ taken. */
+
+ count_trailing_zeros (btwos, blow);
+ blow >>= btwos;
+
+ if (bsize > 1 && btwos > 0)
+ {
+ mp_limb_t b1 = bsrcp[1];
+ blow |= b1 << (GMP_NUMB_BITS - btwos);
+ if (bsize == 2 && (b1 >> btwos) == 0)
+ bsize = 1;
+ }
+
+ result_bit1 ^= JACOBI_RECIP_UU_BIT1 (alow, blow);
+ }
+
+ if (bsize == 1)
+ {
+ result_bit1 ^= JACOBI_TWOS_U_BIT1(btwos, alow);
+
+ if (blow == 1)
+ return JACOBI_BIT1_TO_PN (result_bit1);
+
+ if (asize > 1)
+ JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, alow, asrcp, asize, blow);
+
+ return mpn_jacobi_base (alow, blow, result_bit1);
+ }
+
+ /* Allocation strategy: For A, we allocate a working copy only for A % B, but
+ when A is much larger than B, we have to allocate space for the large
+ quotient. We use the same area, pointed to by bp, for both the quotient
+ A/B and the working copy of B. */
+
+ TMP_MARK;
+
+ if (asize >= 2*bsize)
+ TMP_ALLOC_LIMBS_2 (ap, bsize, bp, asize - bsize + 1);
+ else
+ TMP_ALLOC_LIMBS_2 (ap, bsize, bp, bsize);
+
+ /* In the case of even B, we conceptually shift out the powers of two first,
+ and then divide A mod B. Hence, when taking those powers of two into
+ account, we must use alow *before* the division. Doing the actual division
+ first is ok, because the point is to remove multiples of B from A, and
+ multiples of 2^k B are good enough. */
+ if (asize > bsize)
+ mpn_tdiv_qr (bp, ap, 0, asrcp, asize, bsrcp, bsize);
+ else
+ MPN_COPY (ap, asrcp, bsize);
+
+ if (btwos > 0)
+ {
+ result_bit1 ^= JACOBI_TWOS_U_BIT1(btwos, alow);
+
+ ASSERT_NOCARRY (mpn_rshift (bp, bsrcp, bsize, btwos));
+ bsize -= (ap[bsize-1] | bp[bsize-1]) == 0;
+ }
+ else
+ MPN_COPY (bp, bsrcp, bsize);
+
+ ASSERT (blow == bp[0]);
+ res = mpn_jacobi_n (ap, bp, bsize,
+ mpn_jacobi_init (ap[0], blow, (result_bit1>>1) & 1));
+
+ TMP_FREE;
+ return res;
+}
diff --git a/gmp/mpz/kronsz.c b/gmp/mpz/kronsz.c
new file mode 100644
index 0000000000..12c8fbd0aa
--- /dev/null
+++ b/gmp/mpz/kronsz.c
@@ -0,0 +1,138 @@
+/* mpz_si_kronecker -- long+mpz Kronecker/Jacobi symbol.
+
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+int
+mpz_si_kronecker (long a, mpz_srcptr b)
+{
+ mp_srcptr b_ptr;
+ mp_limb_t b_low;
+ mp_size_t b_size;
+ mp_size_t b_abs_size;
+ mp_limb_t a_limb, b_rem;
+ unsigned twos;
+ int result_bit1;
+
+#if GMP_NUMB_BITS < BITS_PER_ULONG
+ if (a > GMP_NUMB_MAX || a < -GMP_NUMB_MAX)
+ {
+ mp_limb_t alimbs[2];
+ mpz_t az;
+ ALLOC(az) = numberof (alimbs);
+ PTR(az) = alimbs;
+ mpz_set_si (az, a);
+ return mpz_kronecker (az, b);
+ }
+#endif
+
+ b_size = SIZ (b);
+ if (b_size == 0)
+ return JACOBI_S0 (a); /* (a/0) */
+
+ /* account for the effect of the sign of b, then ignore it */
+ result_bit1 = JACOBI_BSGN_SS_BIT1 (a, b_size);
+
+ b_ptr = PTR(b);
+ b_low = b_ptr[0];
+ b_abs_size = ABS (b_size);
+
+ if ((b_low & 1) != 0)
+ {
+ /* b odd */
+
+ result_bit1 ^= JACOBI_ASGN_SU_BIT1 (a, b_low);
+ a_limb = (unsigned long) ABS(a);
+
+ if ((a_limb & 1) == 0)
+ {
+ /* (0/b)=1 for b=+/-1, 0 otherwise */
+ if (a_limb == 0)
+ return (b_abs_size == 1 && b_low == 1);
+
+ /* a even, b odd */
+ count_trailing_zeros (twos, a_limb);
+ a_limb >>= twos;
+ /* (a*2^n/b) = (a/b) * twos(n,a) */
+ result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, b_low);
+ }
+ }
+ else
+ {
+ /* (even/even)=0, and (0/b)=0 for b!=+/-1 */
+ if ((a & 1) == 0)
+ return 0;
+
+ /* a odd, b even
+
+ Establish shifted b_low with valid bit1 for ASGN and RECIP below.
+ Zero limbs stripped are accounted for, but zero bits on b_low are
+ not because they remain in {b_ptr,b_abs_size} for the
+ JACOBI_MOD_OR_MODEXACT_1_ODD. */
+
+ JACOBI_STRIP_LOW_ZEROS (result_bit1, a, b_ptr, b_abs_size, b_low);
+ if ((b_low & 1) == 0)
+ {
+ if (UNLIKELY (b_low == GMP_NUMB_HIGHBIT))
+ {
+ /* need b_ptr[1] to get bit1 in b_low */
+ if (b_abs_size == 1)
+ {
+ /* (a/0x80000000) = (a/2)^(BPML-1) */
+ if ((GMP_NUMB_BITS % 2) == 0)
+ result_bit1 ^= JACOBI_TWO_U_BIT1 (a);
+ return JACOBI_BIT1_TO_PN (result_bit1);
+ }
+
+ /* b_abs_size > 1 */
+ b_low = b_ptr[1] << 1;
+ }
+ else
+ {
+ count_trailing_zeros (twos, b_low);
+ b_low >>= twos;
+ }
+ }
+
+ result_bit1 ^= JACOBI_ASGN_SU_BIT1 (a, b_low);
+ a_limb = (unsigned long) ABS(a);
+ }
+
+ if (a_limb == 1)
+ return JACOBI_BIT1_TO_PN (result_bit1); /* (1/b)=1 */
+
+ /* (a/b*2^n) = (b*2^n mod a / a) * recip(a,b) */
+ JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, b_rem, b_ptr, b_abs_size, a_limb);
+ result_bit1 ^= JACOBI_RECIP_UU_BIT1 (a_limb, b_low);
+ return mpn_jacobi_base (b_rem, a_limb, result_bit1);
+}
diff --git a/gmp/mpz/kronuz.c b/gmp/mpz/kronuz.c
new file mode 100644
index 0000000000..ca88250de5
--- /dev/null
+++ b/gmp/mpz/kronuz.c
@@ -0,0 +1,130 @@
+/* mpz_ui_kronecker -- ulong+mpz Kronecker/Jacobi symbol.
+
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+int
+mpz_ui_kronecker (unsigned long a, mpz_srcptr b)
+{
+ mp_srcptr b_ptr;
+ mp_limb_t b_low;
+ int b_abs_size;
+ mp_limb_t b_rem;
+ int twos;
+ int result_bit1;
+
+ /* (a/-1)=1 when a>=0, so the sign of b is ignored */
+ b_abs_size = ABSIZ (b);
+
+ if (b_abs_size == 0)
+ return JACOBI_U0 (a); /* (a/0) */
+
+ if (a > GMP_NUMB_MAX)
+ {
+ mp_limb_t alimbs[2];
+ mpz_t az;
+ ALLOC(az) = numberof (alimbs);
+ PTR(az) = alimbs;
+ mpz_set_ui (az, a);
+ return mpz_kronecker (az, b);
+ }
+
+ b_ptr = PTR(b);
+ b_low = b_ptr[0];
+ result_bit1 = 0;
+
+ if (! (b_low & 1))
+ {
+ /* (0/b)=0 for b!=+/-1; and (even/even)=0 */
+ if (! (a & 1))
+ return 0;
+
+ /* a odd, b even
+
+ Establish shifted b_low with valid bit1 for the RECIP below. Zero
+ limbs stripped are accounted for, but zero bits on b_low are not
+ because they remain in {b_ptr,b_abs_size} for
+ JACOBI_MOD_OR_MODEXACT_1_ODD. */
+
+ JACOBI_STRIP_LOW_ZEROS (result_bit1, a, b_ptr, b_abs_size, b_low);
+ if (! (b_low & 1))
+ {
+ if (UNLIKELY (b_low == GMP_NUMB_HIGHBIT))
+ {
+ /* need b_ptr[1] to get bit1 in b_low */
+ if (b_abs_size == 1)
+ {
+ /* (a/0x80...00) == (a/2)^(NUMB-1) */
+ if ((GMP_NUMB_BITS % 2) == 0)
+ {
+ /* JACOBI_STRIP_LOW_ZEROS does nothing to result_bit1
+ when GMP_NUMB_BITS is even, so it's still 0. */
+ ASSERT (result_bit1 == 0);
+ result_bit1 = JACOBI_TWO_U_BIT1 (a);
+ }
+ return JACOBI_BIT1_TO_PN (result_bit1);
+ }
+
+ /* b_abs_size > 1 */
+ b_low = b_ptr[1] << 1;
+ }
+ else
+ {
+ count_trailing_zeros (twos, b_low);
+ b_low >>= twos;
+ }
+ }
+ }
+ else
+ {
+ if (a == 0) /* (0/b)=1 for b=+/-1, 0 otherwise */
+ return (b_abs_size == 1 && b_low == 1);
+
+ if (! (a & 1))
+ {
+ /* a even, b odd */
+ count_trailing_zeros (twos, a);
+ a >>= twos;
+ /* (a*2^n/b) = (a/b) * (2/a)^n */
+ result_bit1 = JACOBI_TWOS_U_BIT1 (twos, b_low);
+ }
+ }
+
+ if (a == 1)
+ return JACOBI_BIT1_TO_PN (result_bit1); /* (1/b)=1 */
+
+ /* (a/b*2^n) = (b*2^n mod a / a) * RECIP(a,b) */
+ JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, b_rem, b_ptr, b_abs_size, a);
+ result_bit1 ^= JACOBI_RECIP_UU_BIT1 (a, b_low);
+ return mpn_jacobi_base (b_rem, (mp_limb_t) a, result_bit1);
+}
diff --git a/gmp/mpz/kronzs.c b/gmp/mpz/kronzs.c
new file mode 100644
index 0000000000..695cd0f283
--- /dev/null
+++ b/gmp/mpz/kronzs.c
@@ -0,0 +1,93 @@
+/* mpz_kronecker_si -- mpz+long Kronecker/Jacobi symbol.
+
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* After the absolute value of b is established it's treated as an unsigned
+ long, because 0x80..00 doesn't fit in a signed long. */
+
+int
+mpz_kronecker_si (mpz_srcptr a, long b)
+{
+ mp_srcptr a_ptr;
+ mp_size_t a_size;
+ mp_limb_t a_rem, b_limb;
+ int result_bit1;
+
+ a_size = SIZ(a);
+ if (a_size == 0)
+ return JACOBI_0S (b);
+
+#if GMP_NUMB_BITS < BITS_PER_ULONG
+ if (b > GMP_NUMB_MAX || b < -GMP_NUMB_MAX)
+ {
+ mp_limb_t blimbs[2];
+ mpz_t bz;
+ ALLOC(bz) = numberof (blimbs);
+ PTR(bz) = blimbs;
+ mpz_set_si (bz, b);
+ return mpz_kronecker (a, bz);
+ }
+#endif
+
+ result_bit1 = JACOBI_BSGN_SS_BIT1 (a_size, b);
+ b_limb = ABS_CAST (unsigned long, b);
+ a_ptr = PTR(a);
+
+ if ((b_limb & 1) == 0)
+ {
+ mp_limb_t a_low = a_ptr[0];
+ int twos;
+
+ if (b_limb == 0)
+ return JACOBI_LS0 (a_low, a_size); /* (a/0) */
+
+ if (! (a_low & 1))
+ return 0; /* (even/even)=0 */
+
+ /* (a/2)=(2/a) for a odd */
+ count_trailing_zeros (twos, b_limb);
+ b_limb >>= twos;
+ result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, a_low);
+ }
+
+ if (b_limb == 1)
+ return JACOBI_BIT1_TO_PN (result_bit1); /* (a/1)=1 for any a */
+
+ result_bit1 ^= JACOBI_ASGN_SU_BIT1 (a_size, b_limb);
+ a_size = ABS(a_size);
+
+ /* (a/b) = (a mod b / b) */
+ JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, a_rem, a_ptr, a_size, b_limb);
+ return mpn_jacobi_base (a_rem, b_limb, result_bit1);
+}
diff --git a/gmp/mpz/kronzu.c b/gmp/mpz/kronzu.c
new file mode 100644
index 0000000000..f57f92e8ba
--- /dev/null
+++ b/gmp/mpz/kronzu.c
@@ -0,0 +1,89 @@
+/* mpz_kronecker_ui -- mpz+ulong Kronecker/Jacobi symbol.
+
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+int
+mpz_kronecker_ui (mpz_srcptr a, unsigned long b)
+{
+ mp_srcptr a_ptr;
+ mp_size_t a_size;
+ mp_limb_t a_rem;
+ int result_bit1;
+
+ a_size = SIZ(a);
+ if (a_size == 0)
+ return JACOBI_0U (b);
+
+ if (b > GMP_NUMB_MAX)
+ {
+ mp_limb_t blimbs[2];
+ mpz_t bz;
+ ALLOC(bz) = numberof (blimbs);
+ PTR(bz) = blimbs;
+ mpz_set_ui (bz, b);
+ return mpz_kronecker (a, bz);
+ }
+
+ a_ptr = PTR(a);
+ if ((b & 1) != 0)
+ {
+ result_bit1 = JACOBI_ASGN_SU_BIT1 (a_size, b);
+ }
+ else
+ {
+ mp_limb_t a_low = a_ptr[0];
+ int twos;
+
+ if (b == 0)
+ return JACOBI_LS0 (a_low, a_size); /* (a/0) */
+
+ if (! (a_low & 1))
+ return 0; /* (even/even)=0 */
+
+ /* (a/2)=(2/a) for a odd */
+ count_trailing_zeros (twos, b);
+ b >>= twos;
+ result_bit1 = (JACOBI_TWOS_U_BIT1 (twos, a_low)
+ ^ JACOBI_ASGN_SU_BIT1 (a_size, b));
+ }
+
+ if (b == 1)
+ return JACOBI_BIT1_TO_PN (result_bit1); /* (a/1)=1 for any a */
+
+ a_size = ABS(a_size);
+
+ /* (a/b) = (a mod b / b) */
+ JACOBI_MOD_OR_MODEXACT_1_ODD (result_bit1, a_rem, a_ptr, a_size, b);
+ return mpn_jacobi_base (a_rem, (mp_limb_t) b, result_bit1);
+}
diff --git a/gmp/mpz/lcm.c b/gmp/mpz/lcm.c
new file mode 100644
index 0000000000..805f671077
--- /dev/null
+++ b/gmp/mpz/lcm.c
@@ -0,0 +1,88 @@
+/* mpz_lcm -- mpz/mpz least common multiple.
+
+Copyright 1996, 2000, 2001, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_lcm (mpz_ptr r, mpz_srcptr u, mpz_srcptr v)
+{
+ mpz_t g;
+ mp_size_t usize, vsize;
+ TMP_DECL;
+
+ usize = SIZ (u);
+ vsize = SIZ (v);
+ if (usize == 0 || vsize == 0)
+ {
+ SIZ (r) = 0;
+ return;
+ }
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ if (vsize == 1 || usize == 1)
+ {
+ mp_limb_t vl, gl, c;
+ mp_srcptr up;
+ mp_ptr rp;
+
+ if (usize == 1)
+ {
+ usize = vsize;
+ MPZ_SRCPTR_SWAP (u, v);
+ }
+
+ MPZ_REALLOC (r, usize+1);
+
+ up = PTR(u);
+ vl = PTR(v)[0];
+ gl = mpn_gcd_1 (up, usize, vl);
+ vl /= gl;
+
+ rp = PTR(r);
+ c = mpn_mul_1 (rp, up, usize, vl);
+ rp[usize] = c;
+ usize += (c != 0);
+ SIZ(r) = usize;
+ return;
+ }
+
+ TMP_MARK;
+ MPZ_TMP_INIT (g, usize); /* v != 0 implies |gcd(u,v)| <= |u| */
+
+ mpz_gcd (g, u, v);
+ mpz_divexact (g, u, g);
+ mpz_mul (r, g, v);
+
+ SIZ (r) = ABS (SIZ (r)); /* result always positive */
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/lcm_ui.c b/gmp/mpz/lcm_ui.c
new file mode 100644
index 0000000000..362d183b42
--- /dev/null
+++ b/gmp/mpz/lcm_ui.c
@@ -0,0 +1,79 @@
+/* mpz_lcm_ui -- least common multiple of mpz and ulong.
+
+Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+void
+mpz_lcm_ui (mpz_ptr r, mpz_srcptr u, unsigned long v)
+{
+ mp_size_t usize;
+ mp_srcptr up;
+ mp_ptr rp;
+ unsigned long g;
+ mp_limb_t c;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (v > GMP_NUMB_MAX)
+ {
+ mpz_t vz;
+ mp_limb_t vlimbs[2];
+ vlimbs[0] = v & GMP_NUMB_MASK;
+ vlimbs[1] = v >> GMP_NUMB_BITS;
+ PTR(vz) = vlimbs;
+ SIZ(vz) = 2;
+ mpz_lcm (r, u, vz);
+ return;
+ }
+#endif
+
+ /* result zero if either operand zero */
+ usize = SIZ(u);
+ if (usize == 0 || v == 0)
+ {
+ SIZ(r) = 0;
+ return;
+ }
+ usize = ABS(usize);
+
+ MPZ_REALLOC (r, usize+1);
+
+ up = PTR(u);
+ g = (unsigned long) mpn_gcd_1 (up, usize, (mp_limb_t) v);
+ v /= g;
+
+ rp = PTR(r);
+ c = mpn_mul_1 (rp, up, usize, (mp_limb_t) v);
+ rp[usize] = c;
+ usize += (c != 0);
+ SIZ(r) = usize;
+}
diff --git a/gmp/mpz/limbs_finish.c b/gmp/mpz/limbs_finish.c
new file mode 100644
index 0000000000..ebf6dea290
--- /dev/null
+++ b/gmp/mpz/limbs_finish.c
@@ -0,0 +1,40 @@
+/* mpz_finish_limbs -- Update mpz after writing to the limb array.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_limbs_finish (mpz_ptr x, mp_size_t xs)
+{
+ mp_size_t xn = ABS(xs);
+ MPN_NORMALIZE (PTR (x), xn);
+ SIZ (x) = xs < 0 ? -xn : xn;
+}
diff --git a/gmp/mpz/limbs_modify.c b/gmp/mpz/limbs_modify.c
new file mode 100644
index 0000000000..bafd7d88a0
--- /dev/null
+++ b/gmp/mpz/limbs_modify.c
@@ -0,0 +1,39 @@
+/* mpz_limbs_modify -- Read-and-modify access to the mpn-style limb array.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_ptr
+mpz_limbs_modify (mpz_ptr x, mp_size_t n)
+{
+ ASSERT (n > 0);
+ return MPZ_REALLOC (x, n);
+}
diff --git a/gmp/mpz/limbs_read.c b/gmp/mpz/limbs_read.c
new file mode 100644
index 0000000000..6c14f18d45
--- /dev/null
+++ b/gmp/mpz/limbs_read.c
@@ -0,0 +1,38 @@
+/* mpz_limbs_read -- Read access to the mpn-style limb array.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_srcptr
+mpz_limbs_read (mpz_srcptr x)
+{
+ return PTR(x);
+}
diff --git a/gmp/mpz/limbs_write.c b/gmp/mpz/limbs_write.c
new file mode 100644
index 0000000000..605cb5e3a3
--- /dev/null
+++ b/gmp/mpz/limbs_write.c
@@ -0,0 +1,39 @@
+/* mpz_limbs_write -- Write access to the mpn-style limb array.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_ptr
+mpz_limbs_write (mpz_ptr x, mp_size_t n)
+{
+ ASSERT (n > 0);
+ return MPZ_NEWALLOC (x, n);
+}
diff --git a/gmp/mpz/lucnum2_ui.c b/gmp/mpz/lucnum2_ui.c
new file mode 100644
index 0000000000..f8e4fb356f
--- /dev/null
+++ b/gmp/mpz/lucnum2_ui.c
@@ -0,0 +1,90 @@
+/* mpz_lucnum2_ui -- calculate Lucas numbers.
+
+Copyright 2001, 2003, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpz_lucnum2_ui (mpz_ptr ln, mpz_ptr lnsub1, unsigned long n)
+{
+ mp_ptr lp, l1p, f1p;
+ mp_size_t size;
+ mp_limb_t c;
+ TMP_DECL;
+
+ ASSERT (ln != lnsub1);
+
+ /* handle small n quickly, and hide the special case for L[-1]=-1 */
+ if (n <= FIB_TABLE_LUCNUM_LIMIT)
+ {
+ mp_limb_t f = FIB_TABLE (n);
+ mp_limb_t f1 = FIB_TABLE ((int) n - 1);
+
+ /* L[n] = F[n] + 2F[n-1] */
+ PTR(ln)[0] = f + 2*f1;
+ SIZ(ln) = 1;
+
+ /* L[n-1] = 2F[n] - F[n-1], but allow for L[-1]=-1 */
+ PTR(lnsub1)[0] = (n == 0 ? 1 : 2*f - f1);
+ SIZ(lnsub1) = (n == 0 ? -1 : 1);
+
+ return;
+ }
+
+ TMP_MARK;
+ size = MPN_FIB2_SIZE (n);
+ f1p = TMP_ALLOC_LIMBS (size);
+
+ lp = MPZ_REALLOC (ln, size+1);
+ l1p = MPZ_REALLOC (lnsub1, size+1);
+
+ size = mpn_fib2_ui (l1p, f1p, n);
+
+ /* L[n] = F[n] + 2F[n-1] */
+#if HAVE_NATIVE_mpn_addlsh1_n
+ c = mpn_addlsh1_n (lp, l1p, f1p, size);
+#else
+ c = mpn_lshift (lp, f1p, size, 1);
+ c += mpn_add_n (lp, lp, l1p, size);
+#endif
+ lp[size] = c;
+ SIZ(ln) = size + (c != 0);
+
+ /* L[n-1] = 2F[n] - F[n-1] */
+ c = mpn_lshift (l1p, l1p, size, 1);
+ c -= mpn_sub_n (l1p, l1p, f1p, size);
+ ASSERT ((mp_limb_signed_t) c >= 0);
+ l1p[size] = c;
+ SIZ(lnsub1) = size + (c != 0);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/lucnum_ui.c b/gmp/mpz/lucnum_ui.c
new file mode 100644
index 0000000000..d1fe6b54ce
--- /dev/null
+++ b/gmp/mpz/lucnum_ui.c
@@ -0,0 +1,209 @@
+/* mpz_lucnum_ui -- calculate Lucas number.
+
+Copyright 2001, 2003, 2005, 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* change this to "#define TRACE(x) x" for diagnostics */
+#define TRACE(x)
+
+
+/* Notes:
+
+ For the +4 in L[2k+1] when k is even, all L[4m+3] == 4, 5 or 7 mod 8, so
+ there can't be an overflow applying +4 to just the low limb (since that
+ would leave 0, 1, 2 or 3 mod 8).
+
+ For the -4 in L[2k+1] when k is even, it seems (no proof) that
+ L[3*2^(b-2)-3] == -4 mod 2^b, so for instance with a 32-bit limb
+ L[0xBFFFFFFD] == 0xFFFFFFFC mod 2^32, and this implies a borrow from the
+ low limb. Obviously L[0xBFFFFFFD] is a huge number, but it's at least
+ conceivable to calculate it, so it probably should be handled.
+
+ For the -2 in L[2k] with k even, it seems (no proof) L[2^(b-1)] == -1 mod
+ 2^b, so for instance in 32-bits L[0x80000000] has a low limb of
+ 0xFFFFFFFF so there would have been a borrow. Again L[0x80000000] is
+ obviously huge, but probably should be made to work. */
+
+void
+mpz_lucnum_ui (mpz_ptr ln, unsigned long n)
+{
+ mp_size_t lalloc, xalloc, lsize, xsize;
+ mp_ptr lp, xp;
+ mp_limb_t c;
+ int zeros;
+ TMP_DECL;
+
+ TRACE (printf ("mpn_lucnum_ui n=%lu\n", n));
+
+ if (n <= FIB_TABLE_LUCNUM_LIMIT)
+ {
+ /* L[n] = F[n] + 2F[n-1] */
+ PTR(ln)[0] = FIB_TABLE(n) + 2 * FIB_TABLE ((int) n - 1);
+ SIZ(ln) = 1;
+ return;
+ }
+
+ /* +1 since L[n]=F[n]+2F[n-1] might be 1 limb bigger than F[n], further +1
+ since square or mul used below might need an extra limb over the true
+ size */
+ lalloc = MPN_FIB2_SIZE (n) + 2;
+ lp = MPZ_REALLOC (ln, lalloc);
+
+ TMP_MARK;
+ xalloc = lalloc;
+ xp = TMP_ALLOC_LIMBS (xalloc);
+
+ /* Strip trailing zeros from n, until either an odd number is reached
+ where the L[2k+1] formula can be used, or until n fits within the
+ FIB_TABLE data. The table is preferred of course. */
+ zeros = 0;
+ for (;;)
+ {
+ if (n & 1)
+ {
+ /* L[2k+1] = 5*F[k-1]*(2*F[k]+F[k-1]) - 4*(-1)^k */
+
+ mp_size_t yalloc, ysize;
+ mp_ptr yp;
+
+ TRACE (printf (" initial odd n=%lu\n", n));
+
+ yalloc = MPN_FIB2_SIZE (n/2);
+ yp = TMP_ALLOC_LIMBS (yalloc);
+ ASSERT (xalloc >= yalloc);
+
+ xsize = mpn_fib2_ui (xp, yp, n/2);
+
+ /* possible high zero on F[k-1] */
+ ysize = xsize;
+ ysize -= (yp[ysize-1] == 0);
+ ASSERT (yp[ysize-1] != 0);
+
+ /* xp = 2*F[k] + F[k-1] */
+#if HAVE_NATIVE_mpn_addlsh1_n
+ c = mpn_addlsh1_n (xp, yp, xp, xsize);
+#else
+ c = mpn_lshift (xp, xp, xsize, 1);
+ c += mpn_add_n (xp, xp, yp, xsize);
+#endif
+ ASSERT (xalloc >= xsize+1);
+ xp[xsize] = c;
+ xsize += (c != 0);
+ ASSERT (xp[xsize-1] != 0);
+
+ ASSERT (lalloc >= xsize + ysize);
+ c = mpn_mul (lp, xp, xsize, yp, ysize);
+ lsize = xsize + ysize;
+ lsize -= (c == 0);
+
+ /* lp = 5*lp */
+#if HAVE_NATIVE_mpn_addlsh2_n
+ c = mpn_addlsh2_n (lp, lp, lp, lsize);
+#else
+ /* FIXME: Is this faster than mpn_mul_1 ? */
+ c = mpn_lshift (xp, lp, lsize, 2);
+ c += mpn_add_n (lp, lp, xp, lsize);
+#endif
+ ASSERT (lalloc >= lsize+1);
+ lp[lsize] = c;
+ lsize += (c != 0);
+
+ /* lp = lp - 4*(-1)^k */
+ if (n & 2)
+ {
+ /* no overflow, see comments above */
+ ASSERT (lp[0] <= MP_LIMB_T_MAX-4);
+ lp[0] += 4;
+ }
+ else
+ {
+ /* won't go negative */
+ MPN_DECR_U (lp, lsize, CNST_LIMB(4));
+ }
+
+ TRACE (mpn_trace (" l",lp, lsize));
+ break;
+ }
+
+ MP_PTR_SWAP (xp, lp); /* balance the swaps wanted in the L[2k] below */
+ zeros++;
+ n /= 2;
+
+ if (n <= FIB_TABLE_LUCNUM_LIMIT)
+ {
+ /* L[n] = F[n] + 2F[n-1] */
+ lp[0] = FIB_TABLE (n) + 2 * FIB_TABLE ((int) n - 1);
+ lsize = 1;
+
+ TRACE (printf (" initial small n=%lu\n", n);
+ mpn_trace (" l",lp, lsize));
+ break;
+ }
+ }
+
+ for ( ; zeros != 0; zeros--)
+ {
+ /* L[2k] = L[k]^2 + 2*(-1)^k */
+
+ TRACE (printf (" zeros=%d\n", zeros));
+
+ ASSERT (xalloc >= 2*lsize);
+ mpn_sqr (xp, lp, lsize);
+ lsize *= 2;
+ lsize -= (xp[lsize-1] == 0);
+
+ /* First time around the loop k==n determines (-1)^k, after that k is
+ always even and we set n=0 to indicate that. */
+ if (n & 1)
+ {
+ /* L[n]^2 == 0 or 1 mod 4, like all squares, so +2 gives no carry */
+ ASSERT (xp[0] <= MP_LIMB_T_MAX-2);
+ xp[0] += 2;
+ n = 0;
+ }
+ else
+ {
+ /* won't go negative */
+ MPN_DECR_U (xp, lsize, CNST_LIMB(2));
+ }
+
+ MP_PTR_SWAP (xp, lp);
+ ASSERT (lp[lsize-1] != 0);
+ }
+
+ /* should end up in the right spot after all the xp/lp swaps */
+ ASSERT (lp == PTR(ln));
+ SIZ(ln) = lsize;
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/mfac_uiui.c b/gmp/mpz/mfac_uiui.c
new file mode 100644
index 0000000000..3ea36bce9d
--- /dev/null
+++ b/gmp/mpz/mfac_uiui.c
@@ -0,0 +1,140 @@
+/* mpz_mfac_uiui(RESULT, N, M) -- Set RESULT to N!^(M) = N(N-M)(N-2M)...
+
+Contributed to the GNU project by Marco Bodrato.
+
+Copyright 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*************************************************************/
+/* Section macros: common macros, for swing/fac/bin (&sieve) */
+/*************************************************************/
+
+#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \
+ do { \
+ if ((PR) > (MAX_PR)) { \
+ (VEC)[(I)++] = (PR); \
+ (PR) = (P); \
+ } else \
+ (PR) *= (P); \
+ } while (0)
+
+/*********************************************************/
+/* Section oder factorials: */
+/*********************************************************/
+
+/* mpz_mfac_uiui (x, n, m) computes x = n!^(m) = n*(n-m)*(n-2m)*... */
+
+void
+mpz_mfac_uiui (mpz_ptr x, unsigned long n, unsigned long m)
+{
+ ASSERT (n <= GMP_NUMB_MAX);
+ ASSERT (m != 0);
+
+ if ((n < 3) | (n - 3 < m - 1)) { /* (n < 3 || n - 1 <= m || m == 0) */
+ PTR (x)[0] = n + (n == 0);
+ SIZ (x) = 1;
+ } else { /* m < n - 1 < GMP_NUMB_MAX */
+ mp_limb_t g, sn;
+ mpz_t t;
+
+ sn = n;
+ g = mpn_gcd_1 (&sn, 1, m);
+ if (g > 1) { n/=g; m/=g; }
+
+ if (m <= 2) { /* fac or 2fac */
+ if (m == 1) {
+ if (g > 2) {
+ mpz_init (t);
+ mpz_fac_ui (t, n);
+ sn = n;
+ } else {
+ if (g == 2)
+ mpz_2fac_ui (x, n << 1);
+ else
+ mpz_fac_ui (x, n);
+ return;
+ }
+ } else { /* m == 2 */
+ if (g > 1) {
+ mpz_init (t);
+ mpz_2fac_ui (t, n);
+ sn = n / 2 + 1;
+ } else {
+ mpz_2fac_ui (x, n);
+ return;
+ }
+ }
+ } else { /* m >= 3, gcd(n,m) = 1 */
+ mp_limb_t *factors;
+ mp_limb_t prod, max_prod, j;
+ TMP_DECL;
+
+ sn = n / m + 1;
+
+ j = 0;
+ prod = n;
+ n -= m;
+ max_prod = GMP_NUMB_MAX / n;
+
+ if (g > 1)
+ factors = MPZ_NEWALLOC (x, sn / log_n_max (n) + 2);
+ else {
+ TMP_MARK;
+ factors = TMP_ALLOC_LIMBS (sn / log_n_max (n) + 2);
+ }
+
+ for (; n > m; n -= m)
+ FACTOR_LIST_STORE (n, prod, max_prod, factors, j);
+
+ factors[j++] = n;
+ factors[j++] = prod;
+
+ if (g > 1) {
+ mpz_init (t);
+ mpz_prodlimbs (t, factors, j);
+ } else {
+ mpz_prodlimbs (x, factors, j);
+ TMP_FREE;
+ return;
+ }
+ }
+
+ {
+ mpz_t p;
+
+ mpz_init (p);
+ mpz_ui_pow_ui (p, g, sn); /* g^sn */
+ mpz_mul (x, p, t);
+ mpz_clear (p);
+ mpz_clear (t);
+ }
+ }
+}
diff --git a/gmp/mpz/millerrabin.c b/gmp/mpz/millerrabin.c
new file mode 100644
index 0000000000..e1ce32c893
--- /dev/null
+++ b/gmp/mpz/millerrabin.c
@@ -0,0 +1,124 @@
+/* mpz_millerrabin(n,reps) -- An implementation of the probabilistic primality
+ test found in Knuth's Seminumerical Algorithms book. If the function
+ mpz_millerrabin() returns 0 then n is not prime. If it returns 1, then n is
+ 'probably' prime. The probability of a false positive is (1/4)**reps, where
+ reps is the number of internal passes of the probabilistic algorithm. Knuth
+ indicates that 25 passes are reasonable.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 1991, 1993, 1994, 1996-2002, 2005 Free Software Foundation, Inc.
+
+Contributed by John Amanatides.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+static int millerrabin (mpz_srcptr, mpz_srcptr,
+ mpz_ptr, mpz_ptr,
+ mpz_srcptr, unsigned long int);
+
+int
+mpz_millerrabin (mpz_srcptr n, int reps)
+{
+ int r;
+ mpz_t nm1, nm3, x, y, q;
+ unsigned long int k;
+ gmp_randstate_t rstate;
+ int is_prime;
+ TMP_DECL;
+ TMP_MARK;
+
+ MPZ_TMP_INIT (nm1, SIZ (n) + 1);
+ mpz_sub_ui (nm1, n, 1L);
+
+ MPZ_TMP_INIT (x, SIZ (n) + 1);
+ MPZ_TMP_INIT (y, 2 * SIZ (n)); /* mpz_powm_ui needs excessive memory!!! */
+
+ /* Perform a Fermat test. */
+ mpz_set_ui (x, 210L);
+ mpz_powm (y, x, nm1, n);
+ if (mpz_cmp_ui (y, 1L) != 0)
+ {
+ TMP_FREE;
+ return 0;
+ }
+
+ MPZ_TMP_INIT (q, SIZ (n));
+
+ /* Find q and k, where q is odd and n = 1 + 2**k * q. */
+ k = mpz_scan1 (nm1, 0L);
+ mpz_tdiv_q_2exp (q, nm1, k);
+
+ /* n-3 */
+ MPZ_TMP_INIT (nm3, SIZ (n) + 1);
+ mpz_sub_ui (nm3, n, 3L);
+ ASSERT (mpz_cmp_ui (nm3, 1L) >= 0);
+
+ gmp_randinit_default (rstate);
+
+ is_prime = 1;
+ for (r = 0; r < reps && is_prime; r++)
+ {
+ /* 2 to n-2 inclusive, don't want 1, 0 or -1 */
+ mpz_urandomm (x, rstate, nm3);
+ mpz_add_ui (x, x, 2L);
+
+ is_prime = millerrabin (n, nm1, x, y, q, k);
+ }
+
+ gmp_randclear (rstate);
+
+ TMP_FREE;
+ return is_prime;
+}
+
+static int
+millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y,
+ mpz_srcptr q, unsigned long int k)
+{
+ unsigned long int i;
+
+ mpz_powm (y, x, q, n);
+
+ if (mpz_cmp_ui (y, 1L) == 0 || mpz_cmp (y, nm1) == 0)
+ return 1;
+
+ for (i = 1; i < k; i++)
+ {
+ mpz_powm_ui (y, y, 2L, n);
+ if (mpz_cmp (y, nm1) == 0)
+ return 1;
+ if (mpz_cmp_ui (y, 1L) == 0)
+ return 0;
+ }
+ return 0;
+}
diff --git a/gmp/mpz/mod.c b/gmp/mpz/mod.c
new file mode 100644
index 0000000000..f2de0f9783
--- /dev/null
+++ b/gmp/mpz/mod.c
@@ -0,0 +1,68 @@
+/* mpz_mod -- The mathematical mod function.
+
+Copyright 1991, 1993-1996, 2001, 2002, 2005, 2010, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_mod (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+{
+ mp_size_t rn, bn;
+ mpz_t temp_divisor;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ bn = ABSIZ(divisor);
+
+ /* We need the original value of the divisor after the remainder has been
+ preliminary calculated. We have to copy it to temporary space if it's
+ the same variable as REM. */
+ if (rem == divisor)
+ {
+ PTR(temp_divisor) = TMP_ALLOC_LIMBS (bn);
+ MPN_COPY (PTR(temp_divisor), PTR(divisor), bn);
+ }
+ else
+ {
+ PTR(temp_divisor) = PTR(divisor);
+ }
+ SIZ(temp_divisor) = bn;
+ divisor = temp_divisor;
+
+ mpz_tdiv_r (rem, dividend, divisor);
+
+ rn = SIZ (rem);
+ if (rn < 0)
+ mpz_add (rem, rem, divisor);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/mul.c b/gmp/mpz/mul.c
new file mode 100644
index 0000000000..59a279eca6
--- /dev/null
+++ b/gmp/mpz/mul.c
@@ -0,0 +1,157 @@
+/* mpz_mul -- Multiply two integers.
+
+Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2005, 2009, 2011, 2012 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpz_mul (mpz_ptr w, mpz_srcptr u, mpz_srcptr v)
+{
+ mp_size_t usize;
+ mp_size_t vsize;
+ mp_size_t wsize;
+ mp_size_t sign_product;
+ mp_ptr up, vp;
+ mp_ptr wp;
+ mp_ptr free_me;
+ size_t free_me_size;
+ mp_limb_t cy_limb;
+ TMP_DECL;
+
+ usize = SIZ (u);
+ vsize = SIZ (v);
+ sign_product = usize ^ vsize;
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ if (usize < vsize)
+ {
+ MPZ_SRCPTR_SWAP (u, v);
+ MP_SIZE_T_SWAP (usize, vsize);
+ }
+
+ if (vsize == 0)
+ {
+ SIZ (w) = 0;
+ return;
+ }
+
+#if HAVE_NATIVE_mpn_mul_2
+ if (vsize <= 2)
+ {
+ wp = MPZ_REALLOC (w, usize+vsize);
+ if (vsize == 1)
+ cy_limb = mpn_mul_1 (wp, PTR (u), usize, PTR (v)[0]);
+ else
+ {
+ cy_limb = mpn_mul_2 (wp, PTR (u), usize, PTR (v));
+ usize++;
+ }
+ wp[usize] = cy_limb;
+ usize += (cy_limb != 0);
+ SIZ (w) = (sign_product >= 0 ? usize : -usize);
+ return;
+ }
+#else
+ if (vsize == 1)
+ {
+ wp = MPZ_REALLOC (w, usize+1);
+ cy_limb = mpn_mul_1 (wp, PTR (u), usize, PTR (v)[0]);
+ wp[usize] = cy_limb;
+ usize += (cy_limb != 0);
+ SIZ (w) = (sign_product >= 0 ? usize : -usize);
+ return;
+ }
+#endif
+
+ TMP_MARK;
+ free_me = NULL;
+ up = PTR (u);
+ vp = PTR (v);
+ wp = PTR (w);
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if (ALLOC (w) < wsize)
+ {
+ if (wp == up || wp == vp)
+ {
+ free_me = wp;
+ free_me_size = ALLOC (w);
+ }
+ else
+ (*__gmp_free_func) (wp, (size_t) ALLOC (w) * GMP_LIMB_BYTES);
+
+ ALLOC (w) = wsize;
+ wp = (mp_ptr) (*__gmp_allocate_func) ((size_t) wsize * GMP_LIMB_BYTES);
+ PTR (w) = wp;
+ }
+ else
+ {
+ /* Make U and V not overlap with W. */
+ if (wp == up)
+ {
+ /* W and U are identical. Allocate temporary space for U. */
+ up = TMP_ALLOC_LIMBS (usize);
+ /* Is V identical too? Keep it identical with U. */
+ if (wp == vp)
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY (up, wp, usize);
+ }
+ else if (wp == vp)
+ {
+ /* W and V are identical. Allocate temporary space for V. */
+ vp = TMP_ALLOC_LIMBS (vsize);
+ /* Copy to the temporary space. */
+ MPN_COPY (vp, wp, vsize);
+ }
+ }
+
+ if (up == vp)
+ {
+ mpn_sqr (wp, up, usize);
+ cy_limb = wp[wsize - 1];
+ }
+ else
+ {
+ cy_limb = mpn_mul (wp, up, usize, vp, vsize);
+ }
+
+ wsize -= cy_limb == 0;
+
+ SIZ (w) = sign_product < 0 ? -wsize : wsize;
+ if (free_me != NULL)
+ (*__gmp_free_func) (free_me, free_me_size * GMP_LIMB_BYTES);
+ TMP_FREE;
+}
diff --git a/gmp/mpz/mul_2exp.c b/gmp/mpz/mul_2exp.c
new file mode 100644
index 0000000000..f02fef7ee2
--- /dev/null
+++ b/gmp/mpz/mul_2exp.c
@@ -0,0 +1,73 @@
+/* mpz_mul_2exp -- Multiply a bignum by 2**CNT
+
+Copyright 1991, 1993, 1994, 1996, 2001, 2002, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_mul_2exp (mpz_ptr r, mpz_srcptr u, mp_bitcnt_t cnt)
+{
+ mp_size_t un, rn;
+ mp_size_t limb_cnt;
+ mp_ptr rp;
+ mp_srcptr up;
+ mp_limb_t rlimb;
+
+ un = ABSIZ (u);
+ limb_cnt = cnt / GMP_NUMB_BITS;
+ rn = un + limb_cnt;
+
+ if (un == 0)
+ rn = 0;
+ else
+ {
+ rp = MPZ_REALLOC (r, rn + 1);
+ up = PTR(u);
+
+ cnt %= GMP_NUMB_BITS;
+ if (cnt != 0)
+ {
+ rlimb = mpn_lshift (rp + limb_cnt, up, un, cnt);
+ rp[rn] = rlimb;
+ rn += (rlimb != 0);
+ }
+ else
+ {
+ MPN_COPY_DECR (rp + limb_cnt, up, un);
+ }
+
+ /* Zero all whole limbs at low end. Do it here and not before calling
+ mpn_lshift, not to lose for U == R. */
+ MPN_ZERO (rp, limb_cnt);
+ }
+
+ SIZ(r) = SIZ(u) >= 0 ? rn : -rn;
+}
diff --git a/gmp/mpz/mul_i.h b/gmp/mpz/mul_i.h
new file mode 100644
index 0000000000..486a8fd63e
--- /dev/null
+++ b/gmp/mpz/mul_i.h
@@ -0,0 +1,107 @@
+/* mpz_mul_ui/si (product, multiplier, small_multiplicand) -- Set PRODUCT to
+ MULTIPLICATOR times SMALL_MULTIPLICAND.
+
+Copyright 1991, 1993, 1994, 1996, 2000-2002, 2005, 2008, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#ifdef OPERATION_mul_si
+#define FUNCTION mpz_mul_si
+#define MULTIPLICAND_UNSIGNED
+#define MULTIPLICAND_ABS(x) ABS_CAST(unsigned long, (x))
+#endif
+
+#ifdef OPERATION_mul_ui
+#define FUNCTION mpz_mul_ui
+#define MULTIPLICAND_UNSIGNED unsigned
+#define MULTIPLICAND_ABS(x) x
+#endif
+
+#ifndef FUNCTION
+Error, error, unrecognised OPERATION
+#endif
+
+
+void
+FUNCTION (mpz_ptr prod, mpz_srcptr mult,
+ MULTIPLICAND_UNSIGNED long int small_mult)
+{
+ mp_size_t size;
+ mp_size_t sign_product;
+ mp_limb_t sml;
+ mp_limb_t cy;
+ mp_ptr pp;
+
+ sign_product = SIZ(mult);
+ if (sign_product == 0 || small_mult == 0)
+ {
+ SIZ(prod) = 0;
+ return;
+ }
+
+ size = ABS (sign_product);
+
+ sml = MULTIPLICAND_ABS (small_mult);
+
+ if (sml <= GMP_NUMB_MAX)
+ {
+ pp = MPZ_REALLOC (prod, size + 1);
+ cy = mpn_mul_1 (pp, PTR(mult), size, sml);
+ pp[size] = cy;
+ size += cy != 0;
+ }
+#if GMP_NAIL_BITS != 0
+ else
+ {
+ /* Operand too large for the current nails size. Use temporary for
+ intermediate products, to allow prod and mult being identical. */
+ mp_ptr tp;
+ TMP_DECL;
+ TMP_MARK;
+
+ tp = TMP_ALLOC_LIMBS (size + 2);
+
+ /* Use, maybe, mpn_mul_2? */
+ cy = mpn_mul_1 (tp, PTR(mult), size, sml & GMP_NUMB_MASK);
+ tp[size] = cy;
+ cy = mpn_addmul_1 (tp + 1, PTR(mult), size, sml >> GMP_NUMB_BITS);
+ tp[size + 1] = cy;
+ size += 2;
+ MPN_NORMALIZE_NOT_ZERO (tp, size); /* too general, need to trim one or two limb */
+ pp = MPZ_REALLOC (prod, size);
+ MPN_COPY (pp, tp, size);
+ TMP_FREE;
+ }
+#endif
+
+ SIZ(prod) = ((sign_product < 0) ^ (small_mult < 0)) ? -size : size;
+}
diff --git a/gmp/mpz/mul_si.c b/gmp/mpz/mul_si.c
new file mode 100644
index 0000000000..9f29f601e2
--- /dev/null
+++ b/gmp/mpz/mul_si.c
@@ -0,0 +1,34 @@
+/* mpz_mul_si (product, multiplier, small_multiplicand) -- Set PRODUCT to
+ MULTIPLICATOR times SMALL_MULTIPLICAND.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define OPERATION_mul_si
+#include "mul_i.h"
diff --git a/gmp/mpz/mul_ui.c b/gmp/mpz/mul_ui.c
new file mode 100644
index 0000000000..d398c4f6f1
--- /dev/null
+++ b/gmp/mpz/mul_ui.c
@@ -0,0 +1,34 @@
+/* mpz_mul_ui (product, multiplier, small_multiplicand) -- Set PRODUCT to
+ MULTIPLICATOR times SMALL_MULTIPLICAND.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define OPERATION_mul_ui
+#include "mul_i.h"
diff --git a/gmp/mpz/n_pow_ui.c b/gmp/mpz/n_pow_ui.c
new file mode 100644
index 0000000000..6c3febe237
--- /dev/null
+++ b/gmp/mpz/n_pow_ui.c
@@ -0,0 +1,533 @@
+/* mpz_n_pow_ui -- mpn raised to ulong.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001, 2002, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* Change this to "#define TRACE(x) x" for some traces. */
+#define TRACE(x)
+
+
+/* Use this to test the mul_2 code on a CPU without a native version of that
+ routine. */
+#if 0
+#define mpn_mul_2 refmpn_mul_2
+#define HAVE_NATIVE_mpn_mul_2 1
+#endif
+
+
+/* mpz_pow_ui and mpz_ui_pow_ui want to share almost all of this code.
+ ui_pow_ui doesn't need the mpn_mul based powering loop or the tests on
+ bsize==2 or >2, but separating that isn't easy because there's shared
+ code both before and after (the size calculations and the powers of 2
+ handling).
+
+ Alternatives:
+
+ It would work to just use the mpn_mul powering loop for 1 and 2 limb
+ bases, but the current separate loop allows mul_1 and mul_2 to be done
+ in-place, which might help cache locality a bit. If mpn_mul was relaxed
+ to allow source==dest when vn==1 or 2 then some pointer twiddling might
+ let us get the same effect in one loop.
+
+ The initial powering for bsize==1 into blimb or blimb:blimb_low doesn't
+ form the biggest possible power of b that fits, only the biggest power of
+ 2 power, ie. b^(2^n). It'd be possible to choose a bigger power, perhaps
+ using mp_bases[b].big_base for small b, and thereby get better value
+ from mpn_mul_1 or mpn_mul_2 in the bignum powering. It's felt that doing
+ so would be more complicated than it's worth, and could well end up being
+ a slowdown for small e. For big e on the other hand the algorithm is
+ dominated by mpn_sqr so there wouldn't much of a saving. The current
+ code can be viewed as simply doing the first few steps of the powering in
+ a single or double limb where possible.
+
+ If r==b, and blow_twos==0, and r must be realloc'ed, then the temporary
+ copy made of b is unnecessary. We could just use the old alloc'ed block
+ and free it at the end. But arranging this seems like a lot more trouble
+ than it's worth. */
+
+
+/* floor(sqrt(GMP_NUMB_MAX)), ie. the biggest value that can be squared in
+ a limb without overflowing.
+ FIXME: This formula is an underestimate when GMP_NUMB_BITS is odd. */
+
+#define GMP_NUMB_HALFMAX (((mp_limb_t) 1 << GMP_NUMB_BITS/2) - 1)
+
+
+/* The following are for convenience, they update the size and check the
+ alloc. */
+
+#define MPN_SQR(dst, alloc, src, size) \
+ do { \
+ ASSERT (2*(size) <= (alloc)); \
+ mpn_sqr (dst, src, size); \
+ (size) *= 2; \
+ (size) -= ((dst)[(size)-1] == 0); \
+ } while (0)
+
+#define MPN_MUL(dst, alloc, src, size, src2, size2) \
+ do { \
+ mp_limb_t cy; \
+ ASSERT ((size) + (size2) <= (alloc)); \
+ cy = mpn_mul (dst, src, size, src2, size2); \
+ (size) += (size2) - (cy == 0); \
+ } while (0)
+
+#define MPN_MUL_2(ptr, size, alloc, mult) \
+ do { \
+ mp_limb_t cy; \
+ ASSERT ((size)+2 <= (alloc)); \
+ cy = mpn_mul_2 (ptr, ptr, size, mult); \
+ (size)++; \
+ (ptr)[(size)] = cy; \
+ (size) += (cy != 0); \
+ } while (0)
+
+#define MPN_MUL_1(ptr, size, alloc, limb) \
+ do { \
+ mp_limb_t cy; \
+ ASSERT ((size)+1 <= (alloc)); \
+ cy = mpn_mul_1 (ptr, ptr, size, limb); \
+ (ptr)[size] = cy; \
+ (size) += (cy != 0); \
+ } while (0)
+
+#define MPN_LSHIFT(ptr, size, alloc, shift) \
+ do { \
+ mp_limb_t cy; \
+ ASSERT ((size)+1 <= (alloc)); \
+ cy = mpn_lshift (ptr, ptr, size, shift); \
+ (ptr)[size] = cy; \
+ (size) += (cy != 0); \
+ } while (0)
+
+#define MPN_RSHIFT_OR_COPY(dst, src, size, shift) \
+ do { \
+ if ((shift) == 0) \
+ MPN_COPY (dst, src, size); \
+ else \
+ { \
+ mpn_rshift (dst, src, size, shift); \
+ (size) -= ((dst)[(size)-1] == 0); \
+ } \
+ } while (0)
+
+
+/* ralloc and talloc are only wanted for ASSERTs, after the initial space
+ allocations. Avoid writing values to them in a normal build, to ensure
+ the compiler lets them go dead. gcc already figures this out itself
+ actually. */
+
+#define SWAP_RP_TP \
+ do { \
+ MP_PTR_SWAP (rp, tp); \
+ ASSERT_CODE (MP_SIZE_T_SWAP (ralloc, talloc)); \
+ } while (0)
+
+
+void
+mpz_n_pow_ui (mpz_ptr r, mp_srcptr bp, mp_size_t bsize, unsigned long int e)
+{
+ mp_ptr rp;
+ mp_size_t rtwos_limbs, ralloc, rsize;
+ int rneg, i, cnt, btwos, r_bp_overlap;
+ mp_limb_t blimb, rl;
+ mp_bitcnt_t rtwos_bits;
+#if HAVE_NATIVE_mpn_mul_2
+ mp_limb_t blimb_low, rl_high;
+#else
+ mp_limb_t b_twolimbs[2];
+#endif
+ TMP_DECL;
+
+ TRACE (printf ("mpz_n_pow_ui rp=0x%lX bp=0x%lX bsize=%ld e=%lu (0x%lX)\n",
+ PTR(r), bp, bsize, e, e);
+ mpn_trace ("b", bp, bsize));
+
+ ASSERT (bsize == 0 || bp[ABS(bsize)-1] != 0);
+ ASSERT (MPN_SAME_OR_SEPARATE2_P (PTR(r), ALLOC(r), bp, ABS(bsize)));
+
+ /* b^0 == 1, including 0^0 == 1 */
+ if (e == 0)
+ {
+ PTR(r)[0] = 1;
+ SIZ(r) = 1;
+ return;
+ }
+
+ /* 0^e == 0 apart from 0^0 above */
+ if (bsize == 0)
+ {
+ SIZ(r) = 0;
+ return;
+ }
+
+ /* Sign of the final result. */
+ rneg = (bsize < 0 && (e & 1) != 0);
+ bsize = ABS (bsize);
+ TRACE (printf ("rneg %d\n", rneg));
+
+ r_bp_overlap = (PTR(r) == bp);
+
+ /* Strip low zero limbs from b. */
+ rtwos_limbs = 0;
+ for (blimb = *bp; blimb == 0; blimb = *++bp)
+ {
+ rtwos_limbs += e;
+ bsize--; ASSERT (bsize >= 1);
+ }
+ TRACE (printf ("trailing zero rtwos_limbs=%ld\n", rtwos_limbs));
+
+ /* Strip low zero bits from b. */
+ count_trailing_zeros (btwos, blimb);
+ blimb >>= btwos;
+ rtwos_bits = e * btwos;
+ rtwos_limbs += rtwos_bits / GMP_NUMB_BITS;
+ rtwos_bits %= GMP_NUMB_BITS;
+ TRACE (printf ("trailing zero btwos=%d rtwos_limbs=%ld rtwos_bits=%lu\n",
+ btwos, rtwos_limbs, rtwos_bits));
+
+ TMP_MARK;
+
+ rl = 1;
+#if HAVE_NATIVE_mpn_mul_2
+ rl_high = 0;
+#endif
+
+ if (bsize == 1)
+ {
+ bsize_1:
+ /* Power up as far as possible within blimb. We start here with e!=0,
+ but if e is small then we might reach e==0 and the whole b^e in rl.
+ Notice this code works when blimb==1 too, reaching e==0. */
+
+ while (blimb <= GMP_NUMB_HALFMAX)
+ {
+ TRACE (printf ("small e=0x%lX blimb=0x%lX rl=0x%lX\n",
+ e, blimb, rl));
+ ASSERT (e != 0);
+ if ((e & 1) != 0)
+ rl *= blimb;
+ e >>= 1;
+ if (e == 0)
+ goto got_rl;
+ blimb *= blimb;
+ }
+
+#if HAVE_NATIVE_mpn_mul_2
+ TRACE (printf ("single power, e=0x%lX b=0x%lX rl=0x%lX\n",
+ e, blimb, rl));
+
+ /* Can power b once more into blimb:blimb_low */
+ bsize = 2;
+ ASSERT (e != 0);
+ if ((e & 1) != 0)
+ {
+ umul_ppmm (rl_high, rl, rl, blimb << GMP_NAIL_BITS);
+ rl >>= GMP_NAIL_BITS;
+ }
+ e >>= 1;
+ umul_ppmm (blimb, blimb_low, blimb, blimb << GMP_NAIL_BITS);
+ blimb_low >>= GMP_NAIL_BITS;
+
+ got_rl:
+ TRACE (printf ("double power e=0x%lX blimb=0x%lX:0x%lX rl=0x%lX:%lX\n",
+ e, blimb, blimb_low, rl_high, rl));
+
+ /* Combine left-over rtwos_bits into rl_high:rl to be handled by the
+ final mul_1 or mul_2 rather than a separate lshift.
+ - rl_high:rl mustn't be 1 (since then there's no final mul)
+ - rl_high mustn't overflow
+ - rl_high mustn't change to non-zero, since mul_1+lshift is
+ probably faster than mul_2 (FIXME: is this true?) */
+
+ if (rtwos_bits != 0
+ && ! (rl_high == 0 && rl == 1)
+ && (rl_high >> (GMP_NUMB_BITS-rtwos_bits)) == 0)
+ {
+ mp_limb_t new_rl_high = (rl_high << rtwos_bits)
+ | (rl >> (GMP_NUMB_BITS-rtwos_bits));
+ if (! (rl_high == 0 && new_rl_high != 0))
+ {
+ rl_high = new_rl_high;
+ rl <<= rtwos_bits;
+ rtwos_bits = 0;
+ TRACE (printf ("merged rtwos_bits, rl=0x%lX:%lX\n",
+ rl_high, rl));
+ }
+ }
+#else
+ got_rl:
+ TRACE (printf ("small power e=0x%lX blimb=0x%lX rl=0x%lX\n",
+ e, blimb, rl));
+
+ /* Combine left-over rtwos_bits into rl to be handled by the final
+ mul_1 rather than a separate lshift.
+ - rl mustn't be 1 (since then there's no final mul)
+ - rl mustn't overflow */
+
+ if (rtwos_bits != 0
+ && rl != 1
+ && (rl >> (GMP_NUMB_BITS-rtwos_bits)) == 0)
+ {
+ rl <<= rtwos_bits;
+ rtwos_bits = 0;
+ TRACE (printf ("merged rtwos_bits, rl=0x%lX\n", rl));
+ }
+#endif
+ }
+ else if (bsize == 2)
+ {
+ mp_limb_t bsecond = bp[1];
+ if (btwos != 0)
+ blimb |= (bsecond << (GMP_NUMB_BITS - btwos)) & GMP_NUMB_MASK;
+ bsecond >>= btwos;
+ if (bsecond == 0)
+ {
+ /* Two limbs became one after rshift. */
+ bsize = 1;
+ goto bsize_1;
+ }
+
+ TRACE (printf ("bsize==2 using b=0x%lX:%lX", bsecond, blimb));
+#if HAVE_NATIVE_mpn_mul_2
+ blimb_low = blimb;
+#else
+ bp = b_twolimbs;
+ b_twolimbs[0] = blimb;
+ b_twolimbs[1] = bsecond;
+#endif
+ blimb = bsecond;
+ }
+ else
+ {
+ if (r_bp_overlap || btwos != 0)
+ {
+ mp_ptr tp = TMP_ALLOC_LIMBS (bsize);
+ MPN_RSHIFT_OR_COPY (tp, bp, bsize, btwos);
+ bp = tp;
+ TRACE (printf ("rshift or copy bp,bsize, new bsize=%ld\n", bsize));
+ }
+#if HAVE_NATIVE_mpn_mul_2
+ /* in case 3 limbs rshift to 2 and hence use the mul_2 loop below */
+ blimb_low = bp[0];
+#endif
+ blimb = bp[bsize-1];
+
+ TRACE (printf ("big bsize=%ld ", bsize);
+ mpn_trace ("b", bp, bsize));
+ }
+
+ /* At this point blimb is the most significant limb of the base to use.
+
+ Each factor of b takes (bsize*BPML-cnt) bits and there's e of them; +1
+ limb to round up the division; +1 for multiplies all using an extra
+ limb over the true size; +2 for rl at the end; +1 for lshift at the
+ end.
+
+ The size calculation here is reasonably accurate. The base is at least
+ half a limb, so in 32 bits the worst case is 2^16+1 treated as 17 bits
+ when it will power up as just over 16, an overestimate of 17/16 =
+ 6.25%. For a 64-bit limb it's half that.
+
+ If e==0 then blimb won't be anything useful (though it will be
+ non-zero), but that doesn't matter since we just end up with ralloc==5,
+ and that's fine for 2 limbs of rl and 1 of lshift. */
+
+ ASSERT (blimb != 0);
+ count_leading_zeros (cnt, blimb);
+ ralloc = (bsize*GMP_NUMB_BITS - cnt + GMP_NAIL_BITS) * e / GMP_NUMB_BITS + 5;
+ TRACE (printf ("ralloc %ld, from bsize=%ld blimb=0x%lX cnt=%d\n",
+ ralloc, bsize, blimb, cnt));
+ rp = MPZ_REALLOC (r, ralloc + rtwos_limbs);
+
+ /* Low zero limbs resulting from powers of 2. */
+ MPN_ZERO (rp, rtwos_limbs);
+ rp += rtwos_limbs;
+
+ if (e == 0)
+ {
+ /* Any e==0 other than via bsize==1 or bsize==2 is covered at the
+ start. */
+ rp[0] = rl;
+ rsize = 1;
+#if HAVE_NATIVE_mpn_mul_2
+ rp[1] = rl_high;
+ rsize += (rl_high != 0);
+#endif
+ ASSERT (rp[rsize-1] != 0);
+ }
+ else
+ {
+ mp_ptr tp;
+ mp_size_t talloc;
+
+ /* In the mpn_mul_1 or mpn_mul_2 loops or in the mpn_mul loop when the
+ low bit of e is zero, tp only has to hold the second last power
+ step, which is half the size of the final result. There's no need
+ to round up the divide by 2, since ralloc includes a +2 for rl
+ which not needed by tp. In the mpn_mul loop when the low bit of e
+ is 1, tp must hold nearly the full result, so just size it the same
+ as rp. */
+
+ talloc = ralloc;
+#if HAVE_NATIVE_mpn_mul_2
+ if (bsize <= 2 || (e & 1) == 0)
+ talloc /= 2;
+#else
+ if (bsize <= 1 || (e & 1) == 0)
+ talloc /= 2;
+#endif
+ TRACE (printf ("talloc %ld\n", talloc));
+ tp = TMP_ALLOC_LIMBS (talloc);
+
+ /* Go from high to low over the bits of e, starting with i pointing at
+ the bit below the highest 1 (which will mean i==-1 if e==1). */
+ count_leading_zeros (cnt, (mp_limb_t) e);
+ i = GMP_LIMB_BITS - cnt - 2;
+
+#if HAVE_NATIVE_mpn_mul_2
+ if (bsize <= 2)
+ {
+ mp_limb_t mult[2];
+
+ /* Any bsize==1 will have been powered above to be two limbs. */
+ ASSERT (bsize == 2);
+ ASSERT (blimb != 0);
+
+ /* Arrange the final result ends up in r, not in the temp space */
+ if ((i & 1) == 0)
+ SWAP_RP_TP;
+
+ rp[0] = blimb_low;
+ rp[1] = blimb;
+ rsize = 2;
+
+ mult[0] = blimb_low;
+ mult[1] = blimb;
+
+ for ( ; i >= 0; i--)
+ {
+ TRACE (printf ("mul_2 loop i=%d e=0x%lX, rsize=%ld ralloc=%ld talloc=%ld\n",
+ i, e, rsize, ralloc, talloc);
+ mpn_trace ("r", rp, rsize));
+
+ MPN_SQR (tp, talloc, rp, rsize);
+ SWAP_RP_TP;
+ if ((e & (1L << i)) != 0)
+ MPN_MUL_2 (rp, rsize, ralloc, mult);
+ }
+
+ TRACE (mpn_trace ("mul_2 before rl, r", rp, rsize));
+ if (rl_high != 0)
+ {
+ mult[0] = rl;
+ mult[1] = rl_high;
+ MPN_MUL_2 (rp, rsize, ralloc, mult);
+ }
+ else if (rl != 1)
+ MPN_MUL_1 (rp, rsize, ralloc, rl);
+ }
+#else
+ if (bsize == 1)
+ {
+ /* Arrange the final result ends up in r, not in the temp space */
+ if ((i & 1) == 0)
+ SWAP_RP_TP;
+
+ rp[0] = blimb;
+ rsize = 1;
+
+ for ( ; i >= 0; i--)
+ {
+ TRACE (printf ("mul_1 loop i=%d e=0x%lX, rsize=%ld ralloc=%ld talloc=%ld\n",
+ i, e, rsize, ralloc, talloc);
+ mpn_trace ("r", rp, rsize));
+
+ MPN_SQR (tp, talloc, rp, rsize);
+ SWAP_RP_TP;
+ if ((e & (1L << i)) != 0)
+ MPN_MUL_1 (rp, rsize, ralloc, blimb);
+ }
+
+ TRACE (mpn_trace ("mul_1 before rl, r", rp, rsize));
+ if (rl != 1)
+ MPN_MUL_1 (rp, rsize, ralloc, rl);
+ }
+#endif
+ else
+ {
+ int parity;
+
+ /* Arrange the final result ends up in r, not in the temp space */
+ ULONG_PARITY (parity, e);
+ if (((parity ^ i) & 1) != 0)
+ SWAP_RP_TP;
+
+ MPN_COPY (rp, bp, bsize);
+ rsize = bsize;
+
+ for ( ; i >= 0; i--)
+ {
+ TRACE (printf ("mul loop i=%d e=0x%lX, rsize=%ld ralloc=%ld talloc=%ld\n",
+ i, e, rsize, ralloc, talloc);
+ mpn_trace ("r", rp, rsize));
+
+ MPN_SQR (tp, talloc, rp, rsize);
+ SWAP_RP_TP;
+ if ((e & (1L << i)) != 0)
+ {
+ MPN_MUL (tp, talloc, rp, rsize, bp, bsize);
+ SWAP_RP_TP;
+ }
+ }
+ }
+ }
+
+ ASSERT (rp == PTR(r) + rtwos_limbs);
+ TRACE (mpn_trace ("end loop r", rp, rsize));
+ TMP_FREE;
+
+ /* Apply any partial limb factors of 2. */
+ if (rtwos_bits != 0)
+ {
+ MPN_LSHIFT (rp, rsize, ralloc, (unsigned) rtwos_bits);
+ TRACE (mpn_trace ("lshift r", rp, rsize));
+ }
+
+ rsize += rtwos_limbs;
+ SIZ(r) = (rneg ? -rsize : rsize);
+}
diff --git a/gmp/mpz/neg.c b/gmp/mpz/neg.c
new file mode 100644
index 0000000000..eb46ab7f78
--- /dev/null
+++ b/gmp/mpz/neg.c
@@ -0,0 +1,57 @@
+/* mpz_neg(mpz_ptr dst, mpz_ptr src) -- Assign the negated value of SRC to DST.
+
+Copyright 1991, 1993-1995, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_neg 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_neg (mpz_ptr w, mpz_srcptr u)
+{
+ mp_ptr wp;
+ mp_srcptr up;
+ mp_size_t usize, size;
+
+ usize = SIZ (u);
+
+ if (u != w)
+ {
+ size = ABS (usize);
+
+ wp = MPZ_NEWALLOC (w, size);
+
+ up = PTR (u);
+
+ MPN_COPY (wp, up, size);
+ }
+
+ SIZ (w) = -usize;
+}
diff --git a/gmp/mpz/nextprime.c b/gmp/mpz/nextprime.c
new file mode 100644
index 0000000000..1493054695
--- /dev/null
+++ b/gmp/mpz/nextprime.c
@@ -0,0 +1,129 @@
+/* mpz_nextprime(p,t) - compute the next prime > t and store that in p.
+
+Copyright 1999-2001, 2008, 2009, 2012 Free Software Foundation, Inc.
+
+Contributed to the GNU project by Niels Möller and Torbjorn Granlund.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+static const unsigned char primegap[] =
+{
+ 2,2,4,2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,14,4,6,
+ 2,10,2,6,6,4,6,6,2,10,2,4,2,12,12,4,2,4,6,2,10,6,6,6,2,6,4,2,10,14,4,2,
+ 4,14,6,10,2,4,6,8,6,6,4,6,8,4,8,10,2,10,2,6,4,6,8,4,2,4,12,8,4,8,4,6,
+ 12,2,18,6,10,6,6,2,6,10,6,6,2,6,6,4,2,12,10,2,4,6,6,2,12,4,6,8,10,8,10,8,
+ 6,6,4,8,6,4,8,4,14,10,12,2,10,2,4,2,10,14,4,2,4,14,4,2,4,20,4,8,10,8,4,6,
+ 6,14,4,6,6,8,6,12
+};
+
+#define NUMBER_OF_PRIMES 167
+
+void
+mpz_nextprime (mpz_ptr p, mpz_srcptr n)
+{
+ unsigned short *moduli;
+ unsigned long difference;
+ int i;
+ unsigned prime_limit;
+ unsigned long prime;
+ mp_size_t pn;
+ mp_bitcnt_t nbits;
+ unsigned incr;
+ TMP_SDECL;
+
+ /* First handle tiny numbers */
+ if (mpz_cmp_ui (n, 2) < 0)
+ {
+ mpz_set_ui (p, 2);
+ return;
+ }
+ mpz_add_ui (p, n, 1);
+ mpz_setbit (p, 0);
+
+ if (mpz_cmp_ui (p, 7) <= 0)
+ return;
+
+ pn = SIZ(p);
+ MPN_SIZEINBASE_2EXP(nbits, PTR(p), pn, 1);
+ if (nbits / 2 >= NUMBER_OF_PRIMES)
+ prime_limit = NUMBER_OF_PRIMES - 1;
+ else
+ prime_limit = nbits / 2;
+
+ TMP_SMARK;
+
+ /* Compute residues modulo small odd primes */
+ moduli = TMP_SALLOC_TYPE (prime_limit * sizeof moduli[0], unsigned short);
+
+ for (;;)
+ {
+ /* FIXME: Compute lazily? */
+ prime = 3;
+ for (i = 0; i < prime_limit; i++)
+ {
+ moduli[i] = mpz_fdiv_ui (p, prime);
+ prime += primegap[i];
+ }
+
+#define INCR_LIMIT 0x10000 /* deep science */
+
+ for (difference = incr = 0; incr < INCR_LIMIT; difference += 2)
+ {
+ /* First check residues */
+ prime = 3;
+ for (i = 0; i < prime_limit; i++)
+ {
+ unsigned r;
+ /* FIXME: Reduce moduli + incr and store back, to allow for
+ division-free reductions. Alternatively, table primes[]'s
+ inverses (mod 2^16). */
+ r = (moduli[i] + incr) % prime;
+ prime += primegap[i];
+
+ if (r == 0)
+ goto next;
+ }
+
+ mpz_add_ui (p, p, difference);
+ difference = 0;
+
+ /* Miller-Rabin test */
+ if (mpz_millerrabin (p, 25))
+ goto done;
+ next:;
+ incr += 2;
+ }
+ mpz_add_ui (p, p, difference);
+ difference = 0;
+ }
+ done:
+ TMP_SFREE;
+}
diff --git a/gmp/mpz/oddfac_1.c b/gmp/mpz/oddfac_1.c
new file mode 100644
index 0000000000..cf0bff0650
--- /dev/null
+++ b/gmp/mpz/oddfac_1.c
@@ -0,0 +1,427 @@
+/* mpz_oddfac_1(RESULT, N) -- Set RESULT to the odd factor of N!.
+
+Contributed to the GNU project by Marco Bodrato.
+
+THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE.
+IT IS ONLY SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES.
+IN FACT, IT IS ALMOST GUARANTEED THAT IT WILL CHANGE OR
+DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2010-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* TODO:
+ - split this file in smaller parts with functions that can be recycled for different computations.
+ */
+
+/**************************************************************/
+/* Section macros: common macros, for mswing/fac/bin (&sieve) */
+/**************************************************************/
+
+#define FACTOR_LIST_APPEND(PR, MAX_PR, VEC, I) \
+ if ((PR) > (MAX_PR)) { \
+ (VEC)[(I)++] = (PR); \
+ (PR) = 1; \
+ }
+
+#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \
+ do { \
+ if ((PR) > (MAX_PR)) { \
+ (VEC)[(I)++] = (PR); \
+ (PR) = (P); \
+ } else \
+ (PR) *= (P); \
+ } while (0)
+
+#define LOOP_ON_SIEVE_CONTINUE(prime,end,sieve) \
+ __max_i = (end); \
+ \
+ do { \
+ ++__i; \
+ if (((sieve)[__index] & __mask) == 0) \
+ { \
+ (prime) = id_to_n(__i)
+
+#define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve) \
+ do { \
+ mp_limb_t __mask, __index, __max_i, __i; \
+ \
+ __i = (start)-(off); \
+ __index = __i / GMP_LIMB_BITS; \
+ __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS); \
+ __i += (off); \
+ \
+ LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)
+
+#define LOOP_ON_SIEVE_STOP \
+ } \
+ __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1); \
+ __index += __mask & 1; \
+ } while (__i <= __max_i) \
+
+#define LOOP_ON_SIEVE_END \
+ LOOP_ON_SIEVE_STOP; \
+ } while (0)
+
+/*********************************************************/
+/* Section sieve: sieving functions and tools for primes */
+/*********************************************************/
+
+#if WANT_ASSERT
+static mp_limb_t
+bit_to_n (mp_limb_t bit) { return (bit*3+4)|1; }
+#endif
+
+/* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/
+static mp_limb_t
+id_to_n (mp_limb_t id) { return id*3+1+(id&1); }
+
+/* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */
+static mp_limb_t
+n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; }
+
+#if WANT_ASSERT
+static mp_size_t
+primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; }
+#endif
+
+/*********************************************************/
+/* Section mswing: 2-multiswing factorial */
+/*********************************************************/
+
+/* Returns an approximation of the sqare root of x. *
+ * It gives: x <= limb_apprsqrt (x) ^ 2 < x * 9/4 */
+static mp_limb_t
+limb_apprsqrt (mp_limb_t x)
+{
+ int s;
+
+ ASSERT (x > 2);
+ count_leading_zeros (s, x - 1);
+ s = GMP_LIMB_BITS - 1 - s;
+ return (CNST_LIMB(1) << (s >> 1)) + (CNST_LIMB(1) << ((s - 1) >> 1));
+}
+
+#if 0
+/* A count-then-exponentiate variant for SWING_A_PRIME */
+#define SWING_A_PRIME(P, N, PR, MAX_PR, VEC, I) \
+ do { \
+ mp_limb_t __q, __prime; \
+ int __exp; \
+ __prime = (P); \
+ __exp = 0; \
+ __q = (N); \
+ do { \
+ __q /= __prime; \
+ __exp += __q & 1; \
+ } while (__q >= __prime); \
+ if (__exp) { /* Store $prime^{exp}$ */ \
+ for (__q = __prime; --__exp; __q *= __prime); \
+ FACTOR_LIST_STORE(__q, PR, MAX_PR, VEC, I); \
+ }; \
+ } while (0)
+#else
+#define SWING_A_PRIME(P, N, PR, MAX_PR, VEC, I) \
+ do { \
+ mp_limb_t __q, __prime; \
+ __prime = (P); \
+ FACTOR_LIST_APPEND(PR, MAX_PR, VEC, I); \
+ __q = (N); \
+ do { \
+ __q /= __prime; \
+ if ((__q & 1) != 0) (PR) *= __prime; \
+ } while (__q >= __prime); \
+ } while (0)
+#endif
+
+#define SH_SWING_A_PRIME(P, N, PR, MAX_PR, VEC, I) \
+ do { \
+ mp_limb_t __prime; \
+ __prime = (P); \
+ if ((((N) / __prime) & 1) != 0) \
+ FACTOR_LIST_STORE(__prime, PR, MAX_PR, VEC, I); \
+ } while (0)
+
+/* mpz_2multiswing_1 computes the odd part of the 2-multiswing
+ factorial of the parameter n. The result x is an odd positive
+ integer so that multiswing(n,2) = x 2^a.
+
+ Uses the algorithm described by Peter Luschny in "Divide, Swing and
+ Conquer the Factorial!".
+
+ The pointer sieve points to primesieve_size(n) limbs containing a
+ bit-array where primes are marked as 0.
+ Enough (FIXME: explain :-) limbs must be pointed by factors.
+ */
+
+static void
+mpz_2multiswing_1 (mpz_ptr x, mp_limb_t n, mp_ptr sieve, mp_ptr factors)
+{
+ mp_limb_t prod, max_prod;
+ mp_size_t j;
+
+ ASSERT (n >= 26);
+
+ j = 0;
+ prod = -(n & 1);
+ n &= ~ CNST_LIMB(1); /* n-1, if n is odd */
+
+ prod = (prod & n) + 1; /* the original n, if it was odd, 1 otherwise */
+ max_prod = GMP_NUMB_MAX / (n-1);
+
+ /* Handle prime = 3 separately. */
+ SWING_A_PRIME (3, n, prod, max_prod, factors, j);
+
+ /* Swing primes from 5 to n/3 */
+ {
+ mp_limb_t s;
+
+ {
+ mp_limb_t prime;
+
+ s = limb_apprsqrt(n);
+ ASSERT (s >= 5);
+ s = n_to_bit (s);
+ LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (5), s, 0,sieve);
+ SWING_A_PRIME (prime, n, prod, max_prod, factors, j);
+ LOOP_ON_SIEVE_END;
+ s++;
+ }
+
+ ASSERT (max_prod <= GMP_NUMB_MAX / 3);
+ ASSERT (bit_to_n (s) * bit_to_n (s) > n);
+ ASSERT (s <= n_to_bit (n / 3));
+ {
+ mp_limb_t prime;
+ mp_limb_t l_max_prod = max_prod * 3;
+
+ LOOP_ON_SIEVE_BEGIN (prime, s, n_to_bit (n/3), 0, sieve);
+ SH_SWING_A_PRIME (prime, n, prod, l_max_prod, factors, j);
+ LOOP_ON_SIEVE_END;
+ }
+ }
+
+ /* Store primes from (n+1)/2 to n */
+ {
+ mp_limb_t prime;
+ LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (n >> 1) + 1, n_to_bit (n), 0,sieve);
+ FACTOR_LIST_STORE (prime, prod, max_prod, factors, j);
+ LOOP_ON_SIEVE_END;
+ }
+
+ if (LIKELY (j != 0))
+ {
+ factors[j++] = prod;
+ mpz_prodlimbs (x, factors, j);
+ }
+ else
+ {
+ PTR (x)[0] = prod;
+ SIZ (x) = 1;
+ }
+}
+
+#undef SWING_A_PRIME
+#undef SH_SWING_A_PRIME
+#undef LOOP_ON_SIEVE_END
+#undef LOOP_ON_SIEVE_STOP
+#undef LOOP_ON_SIEVE_BEGIN
+#undef LOOP_ON_SIEVE_CONTINUE
+#undef FACTOR_LIST_APPEND
+
+/*********************************************************/
+/* Section oddfac: odd factorial, needed also by binomial*/
+/*********************************************************/
+
+#if TUNE_PROGRAM_BUILD
+#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_DSC_THRESHOLD_LIMIT-1)+1))
+#else
+#define FACTORS_PER_LIMB (GMP_NUMB_BITS / (LOG2C(FAC_DSC_THRESHOLD-1)+1))
+#endif
+
+/* mpz_oddfac_1 computes the odd part of the factorial of the
+ parameter n. I.e. n! = x 2^a, where x is the returned value: an
+ odd positive integer.
+
+ If flag != 0 a square is skipped in the DSC part, e.g.
+ if n is odd, n > FAC_DSC_THRESHOLD and flag = 1, x is set to n!!.
+
+ If n is too small, flag is ignored, and an ASSERT can be triggered.
+
+ TODO: FAC_DSC_THRESHOLD is used here with two different roles:
+ - to decide when prime factorisation is needed,
+ - to stop the recursion, once sieving is done.
+ Maybe two thresholds can do a better job.
+ */
+void
+mpz_oddfac_1 (mpz_ptr x, mp_limb_t n, unsigned flag)
+{
+ ASSERT (n <= GMP_NUMB_MAX);
+ ASSERT (flag == 0 || (flag == 1 && n > ODD_FACTORIAL_TABLE_LIMIT && ABOVE_THRESHOLD (n, FAC_DSC_THRESHOLD)));
+
+ if (n <= ODD_FACTORIAL_TABLE_LIMIT)
+ {
+ PTR (x)[0] = __gmp_oddfac_table[n];
+ SIZ (x) = 1;
+ }
+ else if (n <= ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1)
+ {
+ mp_ptr px;
+
+ px = MPZ_NEWALLOC (x, 2);
+ umul_ppmm (px[1], px[0], __gmp_odd2fac_table[(n - 1) >> 1], __gmp_oddfac_table[n >> 1]);
+ SIZ (x) = 2;
+ }
+ else
+ {
+ unsigned s;
+ mp_ptr factors;
+
+ s = 0;
+ {
+ mp_limb_t tn;
+ mp_limb_t prod, max_prod, i;
+ mp_size_t j;
+ TMP_SDECL;
+
+#if TUNE_PROGRAM_BUILD
+ ASSERT (FAC_DSC_THRESHOLD_LIMIT >= FAC_DSC_THRESHOLD);
+ ASSERT (FAC_DSC_THRESHOLD >= 2 * (ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 2));
+#endif
+
+ /* Compute the number of recursive steps for the DSC algorithm. */
+ for (tn = n; ABOVE_THRESHOLD (tn, FAC_DSC_THRESHOLD); s++)
+ tn >>= 1;
+
+ j = 0;
+
+ TMP_SMARK;
+ factors = TMP_SALLOC_LIMBS (1 + tn / FACTORS_PER_LIMB);
+ ASSERT (tn >= FACTORS_PER_LIMB);
+
+ prod = 1;
+#if TUNE_PROGRAM_BUILD
+ max_prod = GMP_NUMB_MAX / FAC_DSC_THRESHOLD_LIMIT;
+#else
+ max_prod = GMP_NUMB_MAX / FAC_DSC_THRESHOLD;
+#endif
+
+ ASSERT (tn > ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1);
+ do {
+ i = ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 2;
+ factors[j++] = ODD_DOUBLEFACTORIAL_TABLE_MAX;
+ do {
+ FACTOR_LIST_STORE (i, prod, max_prod, factors, j);
+ i += 2;
+ } while (i <= tn);
+ max_prod <<= 1;
+ tn >>= 1;
+ } while (tn > ODD_DOUBLEFACTORIAL_TABLE_LIMIT + 1);
+
+ factors[j++] = prod;
+ factors[j++] = __gmp_odd2fac_table[(tn - 1) >> 1];
+ factors[j++] = __gmp_oddfac_table[tn >> 1];
+ mpz_prodlimbs (x, factors, j);
+
+ TMP_SFREE;
+ }
+
+ if (s != 0)
+ /* Use the algorithm described by Peter Luschny in "Divide,
+ Swing and Conquer the Factorial!".
+
+ Improvement: there are two temporary buffers, factors and
+ square, that are never used together; with a good estimate
+ of the maximal needed size, they could share a single
+ allocation.
+ */
+ {
+ mpz_t mswing;
+ mp_ptr sieve;
+ mp_size_t size;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ flag--;
+ size = n / GMP_NUMB_BITS + 4;
+ ASSERT (primesieve_size (n - 1) <= size - (size / 2 + 1));
+ /* 2-multiswing(n) < 2^(n-1)*sqrt(n/pi) < 2^(n+GMP_NUMB_BITS);
+ one more can be overwritten by mul, another for the sieve */
+ MPZ_TMP_INIT (mswing, size);
+ /* Initialize size, so that ASSERT can check it correctly. */
+ ASSERT_CODE (SIZ (mswing) = 0);
+
+ /* Put the sieve on the second half, it will be overwritten by the last mswing. */
+ sieve = PTR (mswing) + size / 2 + 1;
+
+ size = (gmp_primesieve (sieve, n - 1) + 1) / log_n_max (n) + 1;
+
+ factors = TMP_ALLOC_LIMBS (size);
+ do {
+ mp_ptr square, px;
+ mp_size_t nx, ns;
+ mp_limb_t cy;
+ TMP_DECL;
+
+ s--;
+ ASSERT (ABSIZ (mswing) < ALLOC (mswing) / 2); /* Check: sieve has not been overwritten */
+ mpz_2multiswing_1 (mswing, n >> s, sieve, factors);
+
+ TMP_MARK;
+ nx = SIZ (x);
+ if (s == flag) {
+ size = nx;
+ square = TMP_ALLOC_LIMBS (size);
+ MPN_COPY (square, PTR (x), nx);
+ } else {
+ size = nx << 1;
+ square = TMP_ALLOC_LIMBS (size);
+ mpn_sqr (square, PTR (x), nx);
+ size -= (square[size - 1] == 0);
+ }
+ ns = SIZ (mswing);
+ nx = size + ns;
+ px = MPZ_NEWALLOC (x, nx);
+ ASSERT (ns <= size);
+ cy = mpn_mul (px, square, size, PTR(mswing), ns); /* n!= n$ * floor(n/2)!^2 */
+
+ TMP_FREE;
+ SIZ(x) = nx - (cy == 0);
+ } while (s != 0);
+ TMP_FREE;
+ }
+ }
+}
+
+#undef FACTORS_PER_LIMB
+#undef FACTOR_LIST_STORE
diff --git a/gmp/mpz/out_raw.c b/gmp/mpz/out_raw.c
new file mode 100644
index 0000000000..3b6b0b7cb5
--- /dev/null
+++ b/gmp/mpz/out_raw.c
@@ -0,0 +1,173 @@
+/* mpz_out_raw -- write an mpz_t in raw format.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* HTON_LIMB_STORE takes a normal host byte order limb and stores it as
+ network byte order (ie. big endian). */
+
+#if HAVE_LIMB_BIG_ENDIAN
+#define HTON_LIMB_STORE(dst, limb) do { *(dst) = (limb); } while (0)
+#endif
+
+#if HAVE_LIMB_LITTLE_ENDIAN
+#define HTON_LIMB_STORE(dst, limb) BSWAP_LIMB_STORE (dst, limb)
+#endif
+
+#ifndef HTON_LIMB_STORE
+#define HTON_LIMB_STORE(dst, limb) \
+ do { \
+ mp_limb_t __limb = (limb); \
+ char *__p = (char *) (dst); \
+ int __i; \
+ for (__i = 0; __i < GMP_LIMB_BYTES; __i++) \
+ __p[__i] = (char) (__limb >> ((GMP_LIMB_BYTES-1 - __i) * 8)); \
+ } while (0)
+#endif
+
+
+size_t
+mpz_out_raw (FILE *fp, mpz_srcptr x)
+{
+ mp_size_t xsize, abs_xsize, bytes, i;
+ mp_srcptr xp;
+ char *tp, *bp;
+ mp_limb_t xlimb;
+ int zeros;
+ size_t tsize, ssize;
+
+ xsize = SIZ(x);
+ abs_xsize = ABS (xsize);
+ bytes = (abs_xsize * GMP_NUMB_BITS + 7) / 8;
+ tsize = ROUND_UP_MULTIPLE ((unsigned) 4, GMP_LIMB_BYTES) + bytes;
+
+ tp = __GMP_ALLOCATE_FUNC_TYPE (tsize, char);
+ bp = tp + ROUND_UP_MULTIPLE ((unsigned) 4, GMP_LIMB_BYTES);
+
+ if (bytes != 0)
+ {
+ bp += bytes;
+ xp = PTR (x);
+ i = abs_xsize;
+
+ if (GMP_NAIL_BITS == 0)
+ {
+ /* reverse limb order, and byte swap if necessary */
+#ifdef _CRAY
+ _Pragma ("_CRI ivdep");
+#endif
+ do
+ {
+ bp -= GMP_LIMB_BYTES;
+ xlimb = *xp;
+ HTON_LIMB_STORE ((mp_ptr) bp, xlimb);
+ xp++;
+ }
+ while (--i > 0);
+
+ /* strip high zero bytes (without fetching from bp) */
+ count_leading_zeros (zeros, xlimb);
+ zeros /= 8;
+ bp += zeros;
+ bytes -= zeros;
+ }
+ else
+ {
+ mp_limb_t new_xlimb;
+ int bits;
+ ASSERT_CODE (char *bp_orig = bp - bytes);
+
+ ASSERT_ALWAYS (GMP_NUMB_BITS >= 8);
+
+ bits = 0;
+ xlimb = 0;
+ for (;;)
+ {
+ while (bits >= 8)
+ {
+ ASSERT (bp > bp_orig);
+ *--bp = xlimb & 0xFF;
+ xlimb >>= 8;
+ bits -= 8;
+ }
+
+ if (i == 0)
+ break;
+
+ new_xlimb = *xp++;
+ i--;
+ ASSERT (bp > bp_orig);
+ *--bp = (xlimb | (new_xlimb << bits)) & 0xFF;
+ xlimb = new_xlimb >> (8 - bits);
+ bits += GMP_NUMB_BITS - 8;
+ }
+
+ if (bits != 0)
+ {
+ ASSERT (bp > bp_orig);
+ *--bp = xlimb;
+ }
+
+ ASSERT (bp == bp_orig);
+ while (*bp == 0)
+ {
+ bp++;
+ bytes--;
+ }
+ }
+ }
+
+ /* total bytes to be written */
+ ssize = 4 + bytes;
+
+ /* twos complement negative for the size value */
+ bytes = (xsize >= 0 ? bytes : -bytes);
+
+ /* so we don't rely on sign extension in ">>" */
+ ASSERT_ALWAYS (sizeof (bytes) >= 4);
+
+ bp[-4] = bytes >> 24;
+ bp[-3] = bytes >> 16;
+ bp[-2] = bytes >> 8;
+ bp[-1] = bytes;
+ bp -= 4;
+
+ if (fp == 0)
+ fp = stdout;
+ if (fwrite (bp, ssize, 1, fp) != 1)
+ ssize = 0;
+
+ (*__gmp_free_func) (tp, tsize);
+ return ssize;
+}
diff --git a/gmp/mpz/out_str.c b/gmp/mpz/out_str.c
new file mode 100644
index 0000000000..6c97039c64
--- /dev/null
+++ b/gmp/mpz/out_str.c
@@ -0,0 +1,112 @@
+/* mpz_out_str(stream, base, integer) -- Output to STREAM the multi prec.
+ integer INTEGER in base BASE.
+
+Copyright 1991, 1993, 1994, 1996, 2001, 2005, 2011, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+size_t
+mpz_out_str (FILE *stream, int base, mpz_srcptr x)
+{
+ mp_ptr xp;
+ mp_size_t x_size = SIZ (x);
+ unsigned char *str;
+ size_t str_size;
+ size_t i;
+ size_t written;
+ const char *num_to_text;
+ TMP_DECL;
+
+ if (stream == 0)
+ stream = stdout;
+
+ if (base >= 0)
+ {
+ num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz";
+ if (base <= 1)
+ base = 10;
+ else if (base > 36)
+ {
+ num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ if (base > 62)
+ return 0;
+ }
+ }
+ else
+ {
+ base = -base;
+ if (base <= 1)
+ base = 10;
+ else if (base > 36)
+ return 0;
+ num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ }
+
+ written = 0;
+
+ if (x_size < 0)
+ {
+ fputc ('-', stream);
+ x_size = -x_size;
+ written = 1;
+ }
+
+ TMP_MARK;
+
+ DIGITS_IN_BASE_PER_LIMB (str_size, x_size, base);
+ str_size += 3;
+ str = (unsigned char *) TMP_ALLOC (str_size);
+
+ xp = PTR (x);
+ if (! POW2_P (base))
+ {
+ xp = TMP_ALLOC_LIMBS (x_size | 1); /* |1 in case x_size==0 */
+ MPN_COPY (xp, PTR (x), x_size);
+ }
+
+ str_size = mpn_get_str (str, base, xp, x_size);
+
+ /* Convert result to printable chars. */
+ for (i = 0; i < str_size; i++)
+ str[i] = num_to_text[str[i]];
+ str[str_size] = 0;
+
+ {
+ size_t fwret;
+ fwret = fwrite ((char *) str, 1, str_size, stream);
+ written += fwret;
+ }
+
+ TMP_FREE;
+ return ferror (stream) ? 0 : written;
+}
diff --git a/gmp/mpz/perfpow.c b/gmp/mpz/perfpow.c
new file mode 100644
index 0000000000..72ff3c89ac
--- /dev/null
+++ b/gmp/mpz/perfpow.c
@@ -0,0 +1,39 @@
+/* mpz_perfect_power_p(arg) -- Return non-zero if ARG is a perfect power,
+ zero otherwise.
+
+Copyright 1998-2001, 2005, 2008, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpz_perfect_power_p (mpz_srcptr u)
+{
+ return mpn_perfect_power_p (PTR (u), SIZ (u));
+}
diff --git a/gmp/mpz/perfsqr.c b/gmp/mpz/perfsqr.c
new file mode 100644
index 0000000000..534f10ff56
--- /dev/null
+++ b/gmp/mpz/perfsqr.c
@@ -0,0 +1,35 @@
+/* mpz_perfect_square_p(arg) -- Return non-zero if ARG is a perfect square,
+ zero otherwise.
+
+Copyright 1991, 1993, 1994, 1996, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_perfect_square_p 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpz/popcount.c b/gmp/mpz/popcount.c
new file mode 100644
index 0000000000..06f0f0b3a2
--- /dev/null
+++ b/gmp/mpz/popcount.c
@@ -0,0 +1,35 @@
+/* mpz_popcount(mpz_ptr op) -- Population count of OP. If the operand is
+ negative, return ~0 (a novel representation of infinity).
+
+Copyright 1994, 1996, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_popcount 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpz/pow_ui.c b/gmp/mpz/pow_ui.c
new file mode 100644
index 0000000000..4891e97877
--- /dev/null
+++ b/gmp/mpz/pow_ui.c
@@ -0,0 +1,53 @@
+/* mpz_pow_ui -- mpz raised to ulong.
+
+Copyright 2001, 2008 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_pow_ui (mpz_ptr r, mpz_srcptr b, unsigned long int e)
+{
+ /* We test some small exponents here, mainly to avoid the overhead of
+ mpz_n_pow_ui for small bases and exponents. */
+ switch (e)
+ {
+ case 0:
+ mpz_set_ui (r, 1);
+ break;
+ case 1:
+ mpz_set (r, b);
+ break;
+ case 2:
+ mpz_mul (r, b, b);
+ break;
+ default:
+ mpz_n_pow_ui (r, PTR(b), (mp_size_t) SIZ(b), e);
+ }
+}
diff --git a/gmp/mpz/powm.c b/gmp/mpz/powm.c
new file mode 100644
index 0000000000..4d13da7396
--- /dev/null
+++ b/gmp/mpz/powm.c
@@ -0,0 +1,283 @@
+/* mpz_powm(res,base,exp,mod) -- Set R to (U^E) mod M.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2005, 2008, 2009, 2011, 2012
+Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* TODO
+
+ * Improve handling of buffers. It is pretty ugly now.
+
+ * For even moduli, we compute a binvert of its odd part both here and in
+ mpn_powm. How can we avoid this recomputation?
+*/
+
+/*
+ b ^ e mod m res
+ 0 0 0 ?
+ 0 e 0 ?
+ 0 0 m ?
+ 0 e m 0
+ b 0 0 ?
+ b e 0 ?
+ b 0 m 1 mod m
+ b e m b^e mod m
+*/
+
+#define HANDLE_NEGATIVE_EXPONENT 1
+
+void
+mpz_powm (mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m)
+{
+ mp_size_t n, nodd, ncnt;
+ int cnt;
+ mp_ptr rp, tp;
+ mp_srcptr bp, ep, mp;
+ mp_size_t rn, bn, es, en, itch;
+ mpz_t new_b; /* note: value lives long via 'b' */
+ TMP_DECL;
+
+ n = ABSIZ(m);
+ if (UNLIKELY (n == 0))
+ DIVIDE_BY_ZERO;
+
+ mp = PTR(m);
+
+ TMP_MARK;
+
+ es = SIZ(e);
+ if (UNLIKELY (es <= 0))
+ {
+ if (es == 0)
+ {
+ /* b^0 mod m, b is anything and m is non-zero.
+ Result is 1 mod m, i.e., 1 or 0 depending on if m = 1. */
+ SIZ(r) = n != 1 || mp[0] != 1;
+ PTR(r)[0] = 1;
+ TMP_FREE; /* we haven't really allocated anything here */
+ return;
+ }
+#if HANDLE_NEGATIVE_EXPONENT
+ MPZ_TMP_INIT (new_b, n + 1);
+
+ if (UNLIKELY (! mpz_invert (new_b, b, m)))
+ DIVIDE_BY_ZERO;
+ b = new_b;
+ es = -es;
+#else
+ DIVIDE_BY_ZERO;
+#endif
+ }
+ en = es;
+
+ bn = ABSIZ(b);
+
+ if (UNLIKELY (bn == 0))
+ {
+ SIZ(r) = 0;
+ TMP_FREE;
+ return;
+ }
+
+ ep = PTR(e);
+
+ /* Handle (b^1 mod m) early, since mpn_pow* do not handle that case. */
+ if (UNLIKELY (en == 1 && ep[0] == 1))
+ {
+ rp = TMP_ALLOC_LIMBS (n);
+ bp = PTR(b);
+ if (bn >= n)
+ {
+ mp_ptr qp = TMP_ALLOC_LIMBS (bn - n + 1);
+ mpn_tdiv_qr (qp, rp, 0L, bp, bn, mp, n);
+ rn = n;
+ MPN_NORMALIZE (rp, rn);
+
+ if (SIZ(b) < 0 && rn != 0)
+ {
+ mpn_sub (rp, mp, n, rp, rn);
+ rn = n;
+ MPN_NORMALIZE (rp, rn);
+ }
+ }
+ else
+ {
+ if (SIZ(b) < 0)
+ {
+ mpn_sub (rp, mp, n, bp, bn);
+ rn = n;
+ rn -= (rp[rn - 1] == 0);
+ }
+ else
+ {
+ MPN_COPY (rp, bp, bn);
+ rn = bn;
+ }
+ }
+ goto ret;
+ }
+
+ /* Remove low zero limbs from M. This loop will terminate for correctly
+ represented mpz numbers. */
+ ncnt = 0;
+ while (UNLIKELY (mp[0] == 0))
+ {
+ mp++;
+ ncnt++;
+ }
+ nodd = n - ncnt;
+ cnt = 0;
+ if (mp[0] % 2 == 0)
+ {
+ mp_ptr newmp = TMP_ALLOC_LIMBS (nodd);
+ count_trailing_zeros (cnt, mp[0]);
+ mpn_rshift (newmp, mp, nodd, cnt);
+ nodd -= newmp[nodd - 1] == 0;
+ mp = newmp;
+ ncnt++;
+ }
+
+ if (ncnt != 0)
+ {
+ /* We will call both mpn_powm and mpn_powlo. */
+ /* rp needs n, mpn_powlo needs 4n, the 2 mpn_binvert might need more */
+ mp_size_t n_largest_binvert = MAX (ncnt, nodd);
+ mp_size_t itch_binvert = mpn_binvert_itch (n_largest_binvert);
+ itch = 3 * n + MAX (itch_binvert, 2 * n);
+ }
+ else
+ {
+ /* We will call just mpn_powm. */
+ mp_size_t itch_binvert = mpn_binvert_itch (nodd);
+ itch = n + MAX (itch_binvert, 2 * n);
+ }
+ tp = TMP_ALLOC_LIMBS (itch);
+
+ rp = tp; tp += n;
+
+ bp = PTR(b);
+ mpn_powm (rp, bp, bn, ep, en, mp, nodd, tp);
+
+ rn = n;
+
+ if (ncnt != 0)
+ {
+ mp_ptr r2, xp, yp, odd_inv_2exp;
+ unsigned long t;
+ int bcnt;
+
+ if (bn < ncnt)
+ {
+ mp_ptr newbp = TMP_ALLOC_LIMBS (ncnt);
+ MPN_COPY (newbp, bp, bn);
+ MPN_ZERO (newbp + bn, ncnt - bn);
+ bp = newbp;
+ }
+
+ r2 = tp;
+
+ if (bp[0] % 2 == 0)
+ {
+ if (en > 1)
+ {
+ MPN_ZERO (r2, ncnt);
+ goto zero;
+ }
+
+ ASSERT (en == 1);
+ t = (ncnt - (cnt != 0)) * GMP_NUMB_BITS + cnt;
+
+ /* Count number of low zero bits in B, up to 3. */
+ bcnt = (0x1213 >> ((bp[0] & 7) << 1)) & 0x3;
+ /* Note that ep[0] * bcnt might overflow, but that just results
+ in a missed optimization. */
+ if (ep[0] * bcnt >= t)
+ {
+ MPN_ZERO (r2, ncnt);
+ goto zero;
+ }
+ }
+
+ mpn_powlo (r2, bp, ep, en, ncnt, tp + ncnt);
+
+ zero:
+ if (nodd < ncnt)
+ {
+ mp_ptr newmp = TMP_ALLOC_LIMBS (ncnt);
+ MPN_COPY (newmp, mp, nodd);
+ MPN_ZERO (newmp + nodd, ncnt - nodd);
+ mp = newmp;
+ }
+
+ odd_inv_2exp = tp + n;
+ mpn_binvert (odd_inv_2exp, mp, ncnt, tp + 2 * n);
+
+ mpn_sub (r2, r2, ncnt, rp, nodd > ncnt ? ncnt : nodd);
+
+ xp = tp + 2 * n;
+ mpn_mullo_n (xp, odd_inv_2exp, r2, ncnt);
+
+ if (cnt != 0)
+ xp[ncnt - 1] &= (CNST_LIMB(1) << cnt) - 1;
+
+ yp = tp;
+ if (ncnt > nodd)
+ mpn_mul (yp, xp, ncnt, mp, nodd);
+ else
+ mpn_mul (yp, mp, nodd, xp, ncnt);
+
+ mpn_add (rp, yp, n, rp, nodd);
+
+ ASSERT (nodd + ncnt >= n);
+ ASSERT (nodd + ncnt <= n + 1);
+ }
+
+ MPN_NORMALIZE (rp, rn);
+
+ if ((ep[0] & 1) && SIZ(b) < 0 && rn != 0)
+ {
+ mpn_sub (rp, PTR(m), n, rp, rn);
+ rn = n;
+ MPN_NORMALIZE (rp, rn);
+ }
+
+ ret:
+ MPZ_REALLOC (r, rn);
+ SIZ(r) = rn;
+ MPN_COPY (PTR(r), rp, rn);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/powm_sec.c b/gmp/mpz/powm_sec.c
new file mode 100644
index 0000000000..98644ca496
--- /dev/null
+++ b/gmp/mpz/powm_sec.c
@@ -0,0 +1,104 @@
+/* mpz_powm_sec(res,base,exp,mod) -- Set R to (U^E) mod M.
+
+ Contributed to the GNU project by Torbjorn Granlund.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2005, 2008, 2009, 2012 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpz_powm_sec (mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m)
+{
+ mp_size_t n;
+ mp_ptr rp, tp;
+ mp_srcptr bp, ep, mp;
+ mp_size_t rn, bn, es, en;
+ TMP_DECL;
+
+ n = ABSIZ(m);
+
+ mp = PTR(m);
+
+ if (UNLIKELY ((n == 0) || (mp[0] % 2 == 0)))
+ DIVIDE_BY_ZERO;
+
+ es = SIZ(e);
+ if (UNLIKELY (es <= 0))
+ {
+ if (es == 0)
+ {
+ /* b^0 mod m, b is anything and m is non-zero.
+ Result is 1 mod m, i.e., 1 or 0 depending on if m = 1. */
+ SIZ(r) = n != 1 || mp[0] != 1;
+ PTR(r)[0] = 1;
+ return;
+ }
+ DIVIDE_BY_ZERO;
+ }
+ en = es;
+
+ bn = ABSIZ(b);
+
+ if (UNLIKELY (bn == 0))
+ {
+ SIZ(r) = 0;
+ return;
+ }
+
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS (n + mpn_sec_powm_itch (bn, en * GMP_NUMB_BITS, n));
+
+ rp = tp; tp += n;
+
+ bp = PTR(b);
+ ep = PTR(e);
+
+ mpn_sec_powm (rp, bp, bn, ep, en * GMP_NUMB_BITS, mp, n, tp);
+
+ rn = n;
+
+ MPN_NORMALIZE (rp, rn);
+
+ if ((ep[0] & 1) && SIZ(b) < 0 && rn != 0)
+ {
+ mpn_sub (rp, PTR(m), n, rp, rn);
+ rn = n;
+ MPN_NORMALIZE (rp, rn);
+ }
+
+ MPZ_REALLOC (r, rn);
+ SIZ(r) = rn;
+ MPN_COPY (PTR(r), rp, rn);
+
+ TMP_FREE;
+}
diff --git a/gmp/mpz/powm_ui.c b/gmp/mpz/powm_ui.c
new file mode 100644
index 0000000000..46e770ce7e
--- /dev/null
+++ b/gmp/mpz/powm_ui.c
@@ -0,0 +1,292 @@
+/* mpz_powm_ui(res,base,exp,mod) -- Set R to (B^E) mod M.
+
+ Contributed to the GNU project by Torbjörn Granlund.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2005, 2008, 2009, 2011-2013
+Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* This code is very old, and should be rewritten to current GMP standard. It
+ is slower than mpz_powm for large exponents, but also for small exponents
+ when the mod argument is small.
+
+ As an intermediate solution, we now deflect to mpz_powm for exponents >= 20.
+*/
+
+/*
+ b ^ e mod m res
+ 0 0 0 ?
+ 0 e 0 ?
+ 0 0 m ?
+ 0 e m 0
+ b 0 0 ?
+ b e 0 ?
+ b 0 m 1 mod m
+ b e m b^e mod m
+*/
+
+static void
+mod (mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn, gmp_pi1_t *dinv, mp_ptr tp)
+{
+ mp_ptr qp;
+ TMP_DECL;
+ TMP_MARK;
+
+ qp = tp;
+
+ if (dn == 1)
+ {
+ np[0] = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, dp[0]);
+ }
+ else if (dn == 2)
+ {
+ mpn_div_qr_2n_pi1 (qp, np, np, nn, dp[1], dp[0], dinv->inv32);
+ }
+ else if (BELOW_THRESHOLD (dn, DC_DIV_QR_THRESHOLD) ||
+ BELOW_THRESHOLD (nn - dn, DC_DIV_QR_THRESHOLD))
+ {
+ mpn_sbpi1_div_qr (qp, np, nn, dp, dn, dinv->inv32);
+ }
+ else if (BELOW_THRESHOLD (dn, MUPI_DIV_QR_THRESHOLD) || /* fast condition */
+ BELOW_THRESHOLD (nn, 2 * MU_DIV_QR_THRESHOLD) || /* fast condition */
+ (double) (2 * (MU_DIV_QR_THRESHOLD - MUPI_DIV_QR_THRESHOLD)) * dn /* slow... */
+ + (double) MUPI_DIV_QR_THRESHOLD * nn > (double) dn * nn) /* ...condition */
+ {
+ mpn_dcpi1_div_qr (qp, np, nn, dp, dn, dinv);
+ }
+ else
+ {
+ /* We need to allocate separate remainder area, since mpn_mu_div_qr does
+ not handle overlap between the numerator and remainder areas.
+ FIXME: Make it handle such overlap. */
+ mp_ptr rp = TMP_BALLOC_LIMBS (dn);
+ mp_size_t itch = mpn_mu_div_qr_itch (nn, dn, 0);
+ mp_ptr scratch = TMP_BALLOC_LIMBS (itch);
+ mpn_mu_div_qr (qp, rp, np, nn, dp, dn, scratch);
+ MPN_COPY (np, rp, dn);
+ }
+
+ TMP_FREE;
+}
+
+/* Compute t = a mod m, a is defined by (ap,an), m is defined by (mp,mn), and
+ t is defined by (tp,mn). */
+static void
+reduce (mp_ptr tp, mp_srcptr ap, mp_size_t an, mp_srcptr mp, mp_size_t mn, gmp_pi1_t *dinv)
+{
+ mp_ptr rp, scratch;
+ TMP_DECL;
+ TMP_MARK;
+
+ rp = TMP_ALLOC_LIMBS (an);
+ scratch = TMP_ALLOC_LIMBS (an - mn + 1);
+ MPN_COPY (rp, ap, an);
+ mod (rp, an, mp, mn, dinv, scratch);
+ MPN_COPY (tp, rp, mn);
+
+ TMP_FREE;
+}
+
+void
+mpz_powm_ui (mpz_ptr r, mpz_srcptr b, unsigned long int el, mpz_srcptr m)
+{
+ if (el < 20)
+ {
+ mp_ptr xp, tp, mp, bp, scratch;
+ mp_size_t xn, tn, mn, bn;
+ int m_zero_cnt;
+ int c;
+ mp_limb_t e, m2;
+ gmp_pi1_t dinv;
+ TMP_DECL;
+
+ mp = PTR(m);
+ mn = ABSIZ(m);
+ if (UNLIKELY (mn == 0))
+ DIVIDE_BY_ZERO;
+
+ if (el == 0)
+ {
+ /* Exponent is zero, result is 1 mod M, i.e., 1 or 0 depending on if
+ M equals 1. */
+ SIZ(r) = (mn == 1 && mp[0] == 1) ? 0 : 1;
+ PTR(r)[0] = 1;
+ return;
+ }
+
+ TMP_MARK;
+
+ /* Normalize m (i.e. make its most significant bit set) as required by
+ division functions below. */
+ count_leading_zeros (m_zero_cnt, mp[mn - 1]);
+ m_zero_cnt -= GMP_NAIL_BITS;
+ if (m_zero_cnt != 0)
+ {
+ mp_ptr new_mp = TMP_ALLOC_LIMBS (mn);
+ mpn_lshift (new_mp, mp, mn, m_zero_cnt);
+ mp = new_mp;
+ }
+
+ m2 = mn == 1 ? 0 : mp[mn - 2];
+ invert_pi1 (dinv, mp[mn - 1], m2);
+
+ bn = ABSIZ(b);
+ bp = PTR(b);
+ if (bn > mn)
+ {
+ /* Reduce possibly huge base. Use a function call to reduce, since we
+ don't want the quotient allocation to live until function return. */
+ mp_ptr new_bp = TMP_ALLOC_LIMBS (mn);
+ reduce (new_bp, bp, bn, mp, mn, &dinv);
+ bp = new_bp;
+ bn = mn;
+ /* Canonicalize the base, since we are potentially going to multiply with
+ it quite a few times. */
+ MPN_NORMALIZE (bp, bn);
+ }
+
+ if (bn == 0)
+ {
+ SIZ(r) = 0;
+ TMP_FREE;
+ return;
+ }
+
+ tp = TMP_ALLOC_LIMBS (2 * mn + 1);
+ xp = TMP_ALLOC_LIMBS (mn);
+ scratch = TMP_ALLOC_LIMBS (mn + 1);
+
+ MPN_COPY (xp, bp, bn);
+ xn = bn;
+
+ e = el;
+ count_leading_zeros (c, e);
+ e = (e << c) << 1; /* shift the exp bits to the left, lose msb */
+ c = GMP_LIMB_BITS - 1 - c;
+
+ if (c == 0)
+ {
+ /* If m is already normalized (high bit of high limb set), and b is
+ the same size, but a bigger value, and e==1, then there's no
+ modular reductions done and we can end up with a result out of
+ range at the end. */
+ if (xn == mn && mpn_cmp (xp, mp, mn) >= 0)
+ mpn_sub_n (xp, xp, mp, mn);
+ }
+ else
+ {
+ /* Main loop. */
+ do
+ {
+ mpn_sqr (tp, xp, xn);
+ tn = 2 * xn; tn -= tp[tn - 1] == 0;
+ if (tn < mn)
+ {
+ MPN_COPY (xp, tp, tn);
+ xn = tn;
+ }
+ else
+ {
+ mod (tp, tn, mp, mn, &dinv, scratch);
+ MPN_COPY (xp, tp, mn);
+ xn = mn;
+ }
+
+ if ((mp_limb_signed_t) e < 0)
+ {
+ mpn_mul (tp, xp, xn, bp, bn);
+ tn = xn + bn; tn -= tp[tn - 1] == 0;
+ if (tn < mn)
+ {
+ MPN_COPY (xp, tp, tn);
+ xn = tn;
+ }
+ else
+ {
+ mod (tp, tn, mp, mn, &dinv, scratch);
+ MPN_COPY (xp, tp, mn);
+ xn = mn;
+ }
+ }
+ e <<= 1;
+ c--;
+ }
+ while (c != 0);
+ }
+
+ /* We shifted m left m_zero_cnt steps. Adjust the result by reducing it
+ with the original M. */
+ if (m_zero_cnt != 0)
+ {
+ mp_limb_t cy;
+ cy = mpn_lshift (tp, xp, xn, m_zero_cnt);
+ tp[xn] = cy; xn += cy != 0;
+
+ if (xn < mn)
+ {
+ MPN_COPY (xp, tp, xn);
+ }
+ else
+ {
+ mod (tp, xn, mp, mn, &dinv, scratch);
+ MPN_COPY (xp, tp, mn);
+ xn = mn;
+ }
+ mpn_rshift (xp, xp, xn, m_zero_cnt);
+ }
+ MPN_NORMALIZE (xp, xn);
+
+ if ((el & 1) != 0 && SIZ(b) < 0 && xn != 0)
+ {
+ mp = PTR(m); /* want original, unnormalized m */
+ mpn_sub (xp, mp, mn, xp, xn);
+ xn = mn;
+ MPN_NORMALIZE (xp, xn);
+ }
+ MPZ_REALLOC (r, xn);
+ SIZ (r) = xn;
+ MPN_COPY (PTR(r), xp, xn);
+
+ TMP_FREE;
+ }
+ else
+ {
+ /* For large exponents, fake a mpz_t exponent and deflect to the more
+ sophisticated mpz_powm. */
+ mpz_t e;
+ mp_limb_t ep[LIMBS_PER_ULONG];
+ MPZ_FAKE_UI (e, ep, el);
+ mpz_powm (r, b, e, m);
+ }
+}
diff --git a/gmp/mpz/pprime_p.c b/gmp/mpz/pprime_p.c
new file mode 100644
index 0000000000..f3d38a0821
--- /dev/null
+++ b/gmp/mpz/pprime_p.c
@@ -0,0 +1,164 @@
+/* mpz_probab_prime_p --
+ An implementation of the probabilistic primality test found in Knuth's
+ Seminumerical Algorithms book. If the function mpz_probab_prime_p()
+ returns 0 then n is not prime. If it returns 1, then n is 'probably'
+ prime. If it returns 2, n is surely prime. The probability of a false
+ positive is (1/4)**reps, where reps is the number of internal passes of the
+ probabilistic algorithm. Knuth indicates that 25 passes are reasonable.
+
+Copyright 1991, 1993, 1994, 1996-2002, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+static int isprime (unsigned long int);
+
+
+/* MPN_MOD_OR_MODEXACT_1_ODD can be used instead of mpn_mod_1 for the trial
+ division. It gives a result which is not the actual remainder r but a
+ value congruent to r*2^n mod d. Since all the primes being tested are
+ odd, r*2^n mod p will be 0 if and only if r mod p is 0. */
+
+int
+mpz_probab_prime_p (mpz_srcptr n, int reps)
+{
+ mp_limb_t r;
+ mpz_t n2;
+
+ /* Handle small and negative n. */
+ if (mpz_cmp_ui (n, 1000000L) <= 0)
+ {
+ int is_prime;
+ if (mpz_cmpabs_ui (n, 1000000L) <= 0)
+ {
+ is_prime = isprime (mpz_get_ui (n));
+ return is_prime ? 2 : 0;
+ }
+ /* Negative number. Negate and fall out. */
+ PTR(n2) = PTR(n);
+ SIZ(n2) = -SIZ(n);
+ n = n2;
+ }
+
+ /* If n is now even, it is not a prime. */
+ if ((mpz_get_ui (n) & 1) == 0)
+ return 0;
+
+#if defined (PP)
+ /* Check if n has small factors. */
+#if defined (PP_INVERTED)
+ r = MPN_MOD_OR_PREINV_MOD_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP,
+ (mp_limb_t) PP_INVERTED);
+#else
+ r = mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP);
+#endif
+ if (r % 3 == 0
+#if GMP_LIMB_BITS >= 4
+ || r % 5 == 0
+#endif
+#if GMP_LIMB_BITS >= 8
+ || r % 7 == 0
+#endif
+#if GMP_LIMB_BITS >= 16
+ || r % 11 == 0 || r % 13 == 0
+#endif
+#if GMP_LIMB_BITS >= 32
+ || r % 17 == 0 || r % 19 == 0 || r % 23 == 0 || r % 29 == 0
+#endif
+#if GMP_LIMB_BITS >= 64
+ || r % 31 == 0 || r % 37 == 0 || r % 41 == 0 || r % 43 == 0
+ || r % 47 == 0 || r % 53 == 0
+#endif
+ )
+ {
+ return 0;
+ }
+#endif /* PP */
+
+ /* Do more dividing. We collect small primes, using umul_ppmm, until we
+ overflow a single limb. We divide our number by the small primes product,
+ and look for factors in the remainder. */
+ {
+ unsigned long int ln2;
+ unsigned long int q;
+ mp_limb_t p1, p0, p;
+ unsigned int primes[15];
+ int nprimes;
+
+ nprimes = 0;
+ p = 1;
+ ln2 = mpz_sizeinbase (n, 2); /* FIXME: tune this limit */
+ for (q = PP_FIRST_OMITTED; q < ln2; q += 2)
+ {
+ if (isprime (q))
+ {
+ umul_ppmm (p1, p0, p, q);
+ if (p1 != 0)
+ {
+ r = MPN_MOD_OR_MODEXACT_1_ODD (PTR(n), (mp_size_t) SIZ(n), p);
+ while (--nprimes >= 0)
+ if (r % primes[nprimes] == 0)
+ {
+ ASSERT_ALWAYS (mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) primes[nprimes]) == 0);
+ return 0;
+ }
+ p = q;
+ nprimes = 0;
+ }
+ else
+ {
+ p = p0;
+ }
+ primes[nprimes++] = q;
+ }
+ }
+ }
+
+ /* Perform a number of Miller-Rabin tests. */
+ return mpz_millerrabin (n, reps);
+}
+
+static int
+isprime (unsigned long int t)
+{
+ unsigned long int q, r, d;
+
+ if (t < 3 || (t & 1) == 0)
+ return t == 2;
+
+ for (d = 3, r = 1; r != 0; d += 2)
+ {
+ q = t / d;
+ r = t - q * d;
+ if (q < d)
+ return 1;
+ }
+ return 0;
+}
diff --git a/gmp/mpz/primorial_ui.c b/gmp/mpz/primorial_ui.c
new file mode 100644
index 0000000000..f322edf549
--- /dev/null
+++ b/gmp/mpz/primorial_ui.c
@@ -0,0 +1,164 @@
+/* mpz_primorial_ui(RESULT, N) -- Set RESULT to N# the product of primes <= N.
+
+Contributed to the GNU project by Marco Bodrato.
+
+Copyright 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* TODO: Remove duplicated constants / macros / static functions...
+ */
+
+/*************************************************************/
+/* Section macros: common macros, for swing/fac/bin (&sieve) */
+/*************************************************************/
+
+#define FACTOR_LIST_STORE(P, PR, MAX_PR, VEC, I) \
+ do { \
+ if ((PR) > (MAX_PR)) { \
+ (VEC)[(I)++] = (PR); \
+ (PR) = (P); \
+ } else \
+ (PR) *= (P); \
+ } while (0)
+
+#define LOOP_ON_SIEVE_CONTINUE(prime,end,sieve) \
+ __max_i = (end); \
+ \
+ do { \
+ ++__i; \
+ if (((sieve)[__index] & __mask) == 0) \
+ { \
+ (prime) = id_to_n(__i)
+
+#define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve) \
+ do { \
+ mp_limb_t __mask, __index, __max_i, __i; \
+ \
+ __i = (start)-(off); \
+ __index = __i / GMP_LIMB_BITS; \
+ __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS); \
+ __i += (off); \
+ \
+ LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)
+
+#define LOOP_ON_SIEVE_STOP \
+ } \
+ __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1); \
+ __index += __mask & 1; \
+ } while (__i <= __max_i) \
+
+#define LOOP_ON_SIEVE_END \
+ LOOP_ON_SIEVE_STOP; \
+ } while (0)
+
+/*********************************************************/
+/* Section sieve: sieving functions and tools for primes */
+/*********************************************************/
+
+#if WANT_ASSERT
+static mp_limb_t
+bit_to_n (mp_limb_t bit) { return (bit*3+4)|1; }
+#endif
+
+/* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/
+static mp_limb_t
+id_to_n (mp_limb_t id) { return id*3+1+(id&1); }
+
+/* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */
+static mp_limb_t
+n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; }
+
+#if WANT_ASSERT
+static mp_size_t
+primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; }
+#endif
+
+/*********************************************************/
+/* Section primorial: implementation */
+/*********************************************************/
+
+void
+mpz_primorial_ui (mpz_ptr x, unsigned long n)
+{
+ static const mp_limb_t table[] = { 1, 1, 2, 6, 6 };
+
+ ASSERT (n <= GMP_NUMB_MAX);
+
+ if (n < numberof (table))
+ {
+ PTR (x)[0] = table[n];
+ SIZ (x) = 1;
+ }
+ else
+ {
+ mp_limb_t *sieve, *factors;
+ mp_size_t size;
+ mp_limb_t prod;
+ mp_limb_t j;
+ TMP_DECL;
+
+ size = 1 + n / GMP_NUMB_BITS + n / (2*GMP_NUMB_BITS);
+ ASSERT (size >= primesieve_size (n));
+ sieve = MPZ_NEWALLOC (x, size);
+ size = (gmp_primesieve (sieve, n) + 1) / log_n_max (n) + 1;
+
+ TMP_MARK;
+ factors = TMP_ALLOC_LIMBS (size);
+
+ j = 0;
+
+ prod = table[numberof (table)-1];
+
+ /* Store primes from 5 to n */
+ {
+ mp_limb_t prime, max_prod;
+
+ max_prod = GMP_NUMB_MAX / n;
+
+ LOOP_ON_SIEVE_BEGIN (prime, n_to_bit(numberof (table)), n_to_bit (n), 0, sieve);
+ FACTOR_LIST_STORE (prime, prod, max_prod, factors, j);
+ LOOP_ON_SIEVE_END;
+ }
+
+ if (LIKELY (j != 0))
+ {
+ factors[j++] = prod;
+ mpz_prodlimbs (x, factors, j);
+ }
+ else
+ {
+ PTR (x)[0] = prod;
+ SIZ (x) = 1;
+ }
+
+ TMP_FREE;
+ }
+}
diff --git a/gmp/mpz/prodlimbs.c b/gmp/mpz/prodlimbs.c
new file mode 100644
index 0000000000..8d84bcb435
--- /dev/null
+++ b/gmp/mpz/prodlimbs.c
@@ -0,0 +1,109 @@
+/* mpz_prodlimbs(RESULT, V, LEN) -- Set RESULT to V[0]*V[1]*...*V[LEN-1].
+
+Contributed to the GNU project by Marco Bodrato.
+
+THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE.
+IT IS ONLY SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES.
+IN FACT, IT IS ALMOST GUARANTEED THAT IT WILL CHANGE OR
+DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2010-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/*********************************************************/
+/* Section list-prod: product of a list -> mpz_t */
+/*********************************************************/
+
+/* FIXME: should be tuned */
+#ifndef RECURSIVE_PROD_THRESHOLD
+#define RECURSIVE_PROD_THRESHOLD (MUL_TOOM22_THRESHOLD)
+#endif
+
+/* Computes the product of the j>1 limbs pointed by factors, puts the
+ * result in x. It assumes that all limbs are non-zero. Above
+ * Karatsuba's threshold it uses a binary splitting strategy, to gain
+ * speed by the asymptotically fast multiplication algorithms.
+ *
+ * The list in {factors, j} is overwritten.
+ * Returns the size of the result
+ */
+
+mp_size_t
+mpz_prodlimbs (mpz_ptr x, mp_ptr factors, mp_size_t j)
+{
+ mp_limb_t cy;
+ mp_size_t size, i;
+ mp_ptr prod;
+
+ ASSERT (j > 1);
+ ASSERT (RECURSIVE_PROD_THRESHOLD > 3);
+
+ if (BELOW_THRESHOLD (j, RECURSIVE_PROD_THRESHOLD)) {
+ j--;
+ size = 1;
+
+ for (i = 1; i < j; i++)
+ {
+ cy = mpn_mul_1 (factors, factors, size, factors[i]);
+ factors[size] = cy;
+ size += cy != 0;
+ };
+
+ prod = MPZ_NEWALLOC (x, size + 1);
+
+ cy = mpn_mul_1 (prod, factors, size, factors[i]);
+ prod[size] = cy;
+ return SIZ (x) = size + (cy != 0);
+ } else {
+ mpz_t x1, x2;
+ TMP_DECL;
+
+ i = j >> 1;
+ j -= i;
+ TMP_MARK;
+
+ MPZ_TMP_INIT (x2, j);
+
+ PTR (x1) = factors + i;
+ ALLOC (x1) = j;
+ j = mpz_prodlimbs (x2, factors + i, j);
+ i = mpz_prodlimbs (x1, factors, i);
+ size = i + j;
+ prod = MPZ_NEWALLOC (x, size);
+ if (i >= j)
+ cy = mpn_mul (prod, PTR(x1), i, PTR(x2), j);
+ else
+ cy = mpn_mul (prod, PTR(x2), j, PTR(x1), i);
+ TMP_FREE;
+
+ return SIZ (x) = size - (cy == 0);
+ }
+}
diff --git a/gmp/mpz/random.c b/gmp/mpz/random.c
new file mode 100644
index 0000000000..1dca3a93cd
--- /dev/null
+++ b/gmp/mpz/random.c
@@ -0,0 +1,40 @@
+/* mpz_random -- Generate a random mpz_t of specified size in limbs.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_random (mpz_ptr x, mp_size_t size)
+{
+ mpz_urandomb (x, RANDS, (unsigned long) (ABS (size) * GMP_NUMB_BITS));
+ if (size < 0)
+ SIZ(x) = -SIZ(x);
+}
diff --git a/gmp/mpz/random2.c b/gmp/mpz/random2.c
new file mode 100644
index 0000000000..7f9e5f28e8
--- /dev/null
+++ b/gmp/mpz/random2.c
@@ -0,0 +1,51 @@
+/* mpz_random2 -- Generate a positive random mpz_t of specified size, with
+ long runs of consecutive ones and zeros in the binary representation.
+ Meant for testing of other MP routines.
+
+Copyright 1991, 1993, 1994, 1996, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_random2 (mpz_ptr x, mp_size_t size)
+{
+ mp_size_t abs_size;
+ mp_ptr xp;
+
+ abs_size = ABS (size);
+ if (abs_size != 0)
+ {
+ xp = MPZ_REALLOC (x, abs_size);
+
+ mpn_random2 (xp, abs_size);
+ }
+
+ SIZ (x) = size;
+}
diff --git a/gmp/mpz/realloc.c b/gmp/mpz/realloc.c
new file mode 100644
index 0000000000..3d2755ca0a
--- /dev/null
+++ b/gmp/mpz/realloc.c
@@ -0,0 +1,71 @@
+/* _mpz_realloc -- make the mpz_t have NEW_ALLOC digits allocated.
+
+Copyright 1991, 1993-1995, 2000, 2001, 2008 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void *
+_mpz_realloc (mpz_ptr m, mp_size_t new_alloc)
+{
+ mp_ptr mp;
+
+ /* Never allocate zero space. */
+ new_alloc = MAX (new_alloc, 1);
+
+ if (sizeof (mp_size_t) == sizeof (int))
+ {
+ if (UNLIKELY (new_alloc > ULONG_MAX / GMP_NUMB_BITS))
+ {
+ fprintf (stderr, "gmp: overflow in mpz type\n");
+ abort ();
+ }
+ }
+ else
+ {
+ if (UNLIKELY (new_alloc > INT_MAX))
+ {
+ fprintf (stderr, "gmp: overflow in mpz type\n");
+ abort ();
+ }
+ }
+
+ mp = __GMP_REALLOCATE_FUNC_LIMBS (PTR(m), ALLOC(m), new_alloc);
+ PTR(m) = mp;
+ ALLOC(m) = new_alloc;
+
+ /* Don't create an invalid number; if the current value doesn't fit after
+ reallocation, clear it to 0. */
+ if (ABSIZ(m) > new_alloc)
+ SIZ(m) = 0;
+
+ return (void *) mp;
+}
diff --git a/gmp/mpz/realloc2.c b/gmp/mpz/realloc2.c
new file mode 100644
index 0000000000..3ccfaab1f0
--- /dev/null
+++ b/gmp/mpz/realloc2.c
@@ -0,0 +1,60 @@
+/* mpz_realloc2 -- change allocated data size.
+
+Copyright 2001, 2002, 2008 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_realloc2 (mpz_ptr m, mp_bitcnt_t bits)
+{
+ mp_size_t new_alloc;
+
+ bits -= (bits != 0); /* Round down, except if 0 */
+ new_alloc = 1 + bits / GMP_NUMB_BITS;
+
+ if (sizeof (unsigned long) > sizeof (int)) /* param vs _mp_size field */
+ {
+ if (UNLIKELY (new_alloc > INT_MAX))
+ {
+ fprintf (stderr, "gmp: overflow in mpz type\n");
+ abort ();
+ }
+ }
+
+ PTR(m) = __GMP_REALLOCATE_FUNC_LIMBS (PTR(m), ALLOC(m), new_alloc);
+ ALLOC(m) = new_alloc;
+
+ /* Don't create an invalid number; if the current value doesn't fit after
+ reallocation, clear it to 0. */
+ if (ABSIZ(m) > new_alloc)
+ SIZ(m) = 0;
+}
diff --git a/gmp/mpz/remove.c b/gmp/mpz/remove.c
new file mode 100644
index 0000000000..3d29358738
--- /dev/null
+++ b/gmp/mpz/remove.c
@@ -0,0 +1,147 @@
+/* mpz_remove -- divide out a factor and return its multiplicity.
+
+Copyright 1998-2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_bitcnt_t
+mpz_remove (mpz_ptr dest, mpz_srcptr src, mpz_srcptr f)
+{
+ mp_bitcnt_t pwr;
+ mp_srcptr fp;
+ mp_size_t sn, fn, afn;
+ mp_limb_t fp0;
+
+ sn = SIZ (src);
+ fn = SIZ (f);
+ fp = PTR (f);
+ afn = ABS (fn);
+ fp0 = fp[0];
+
+ if (UNLIKELY ((afn <= (fp0 == 1)) /* mpz_cmpabs_ui (f, 1) <= 0 */
+ | (sn == 0)))
+ {
+ /* f = 0 or f = +- 1 or src = 0 */
+ if (afn == 0)
+ DIVIDE_BY_ZERO;
+ mpz_set (dest, src);
+ return 0;
+ }
+
+ if ((fp0 & 1) != 0)
+ { /* f is odd */
+ mp_ptr dp;
+ mp_size_t dn;
+
+ dn = ABS (sn);
+ dp = MPZ_REALLOC (dest, dn);
+
+ pwr = mpn_remove (dp, &dn, PTR(src), dn, PTR(f), afn, ~(mp_bitcnt_t) 0);
+
+ SIZ (dest) = ((pwr & (fn < 0)) ^ (sn < 0)) ? -dn : dn;
+ }
+ else if (afn == (fp0 == 2))
+ { /* mpz_cmpabs_ui (f, 2) == 0 */
+ pwr = mpz_scan1 (src, 0);
+ mpz_div_2exp (dest, src, pwr);
+ if (pwr & (fn < 0)) /*((pwr % 2 == 1) && (SIZ (f) < 0))*/
+ mpz_neg (dest, dest);
+ }
+ else
+ { /* f != +-2 */
+ mpz_t x, rem;
+
+ mpz_init (rem);
+ mpz_init (x);
+
+ pwr = 0;
+ mpz_tdiv_qr (x, rem, src, f);
+ if (SIZ (rem) == 0)
+ {
+ mpz_t fpow[GMP_LIMB_BITS]; /* Really MP_SIZE_T_BITS */
+ int p;
+
+#if WANT_ORIGINAL_DEST
+ mp_ptr dp;
+ dp = PTR (dest);
+#endif
+ /* We could perhaps compute mpz_scan1(src,0)/mpz_scan1(f,0). It is an
+ upper bound of the result we're seeking. We could also shift down the
+ operands so that they become odd, to make intermediate values
+ smaller. */
+ mpz_init_set (fpow[0], f);
+ mpz_swap (dest, x);
+
+ p = 1;
+ /* Divide by f, f^2 ... f^(2^k) until we get a remainder for f^(2^k). */
+ while (ABSIZ (dest) >= 2 * ABSIZ (fpow[p - 1]) - 1)
+ {
+ mpz_init (fpow[p]);
+ mpz_mul (fpow[p], fpow[p - 1], fpow[p - 1]);
+ mpz_tdiv_qr (x, rem, dest, fpow[p]);
+ if (SIZ (rem) != 0) {
+ mpz_clear (fpow[p]);
+ break;
+ }
+ mpz_swap (dest, x);
+ p++;
+ }
+
+ pwr = ((mp_bitcnt_t)1 << p) - 1;
+
+ /* Divide by f^(2^(k-1)), f^(2^(k-2)), ..., f for all divisors that give
+ a zero remainder. */
+ while (--p >= 0)
+ {
+ mpz_tdiv_qr (x, rem, dest, fpow[p]);
+ if (SIZ (rem) == 0)
+ {
+ pwr += (mp_bitcnt_t)1 << p;
+ mpz_swap (dest, x);
+ }
+ mpz_clear (fpow[p]);
+ }
+
+#if WANT_ORIGINAL_DEST
+ if (PTR (x) == dp) {
+ mpz_swap (dest, x);
+ mpz_set (dest, x);
+ }
+#endif
+ }
+ else
+ mpz_set (dest, src);
+
+ mpz_clear (x);
+ mpz_clear (rem);
+ }
+
+ return pwr;
+}
diff --git a/gmp/mpz/roinit_n.c b/gmp/mpz/roinit_n.c
new file mode 100644
index 0000000000..137dbda83c
--- /dev/null
+++ b/gmp/mpz/roinit_n.c
@@ -0,0 +1,44 @@
+/* mpz_roinit_n -- Initialize mpz with read-only limb array.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mpz_srcptr
+mpz_roinit_n (mpz_ptr x, mp_srcptr xp, mp_size_t xs)
+{
+ mp_size_t xn = ABS(xs);
+ MPN_NORMALIZE (xp, xn);
+
+ ALLOC (x) = 0;
+ SIZ (x) = xs < 0 ? -xn : xn;
+ PTR (x) = (mp_ptr) xp;
+ return x;
+}
diff --git a/gmp/mpz/root.c b/gmp/mpz/root.c
new file mode 100644
index 0000000000..31eb440b4f
--- /dev/null
+++ b/gmp/mpz/root.c
@@ -0,0 +1,93 @@
+/* mpz_root(root, u, nth) -- Set ROOT to floor(U^(1/nth)).
+ Return an indication if the result is exact.
+
+Copyright 1999-2003, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+mpz_root (mpz_ptr root, mpz_srcptr u, unsigned long int nth)
+{
+ mp_ptr rootp, up;
+ mp_size_t us, un, rootn, remn;
+ TMP_DECL;
+
+ us = SIZ(u);
+
+ /* even roots of negatives provoke an exception */
+ if (UNLIKELY (us < 0 && (nth & 1) == 0))
+ SQRT_OF_NEGATIVE;
+
+ /* root extraction interpreted as c^(1/nth) means a zeroth root should
+ provoke a divide by zero, do this even if c==0 */
+ if (UNLIKELY (nth == 0))
+ DIVIDE_BY_ZERO;
+
+ if (us == 0)
+ {
+ if (root != NULL)
+ SIZ(root) = 0;
+ return 1; /* exact result */
+ }
+
+ un = ABS (us);
+ rootn = (un - 1) / nth + 1;
+
+ TMP_MARK;
+
+ /* FIXME: Perhaps disallow root == NULL */
+ if (root != NULL && u != root)
+ rootp = MPZ_REALLOC (root, rootn);
+ else
+ rootp = TMP_ALLOC_LIMBS (rootn);
+
+ up = PTR(u);
+
+ if (nth == 1)
+ {
+ MPN_COPY (rootp, up, un);
+ remn = 0;
+ }
+ else
+ {
+ remn = mpn_rootrem (rootp, NULL, up, un, (mp_limb_t) nth);
+ }
+
+ if (root != NULL)
+ {
+ SIZ(root) = us >= 0 ? rootn : -rootn;
+ if (u == root)
+ MPN_COPY (up, rootp, rootn);
+ }
+
+ TMP_FREE;
+ return remn == 0;
+}
diff --git a/gmp/mpz/rootrem.c b/gmp/mpz/rootrem.c
new file mode 100644
index 0000000000..ac4a1e030a
--- /dev/null
+++ b/gmp/mpz/rootrem.c
@@ -0,0 +1,101 @@
+/* mpz_rootrem(root, rem, u, nth) -- Set ROOT to trunc(U^(1/nth)) and
+ set REM to the remainder.
+
+Copyright 1999-2003, 2005, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_rootrem (mpz_ptr root, mpz_ptr rem, mpz_srcptr u, unsigned long int nth)
+{
+ mp_ptr rootp, up, remp;
+ mp_size_t us, un, rootn, remn;
+ TMP_DECL;
+
+ us = SIZ(u);
+
+ /* even roots of negatives provoke an exception */
+ if (UNLIKELY (us < 0 && (nth & 1) == 0))
+ SQRT_OF_NEGATIVE;
+
+ /* root extraction interpreted as c^(1/nth) means a zeroth root should
+ provoke a divide by zero, do this even if c==0 */
+ if (UNLIKELY (nth == 0))
+ DIVIDE_BY_ZERO;
+
+ if (us == 0)
+ {
+ if (root != NULL)
+ SIZ(root) = 0;
+ SIZ(rem) = 0;
+ return;
+ }
+
+ un = ABS (us);
+ rootn = (un - 1) / nth + 1;
+
+ TMP_MARK;
+
+ /* FIXME: Perhaps disallow root == NULL */
+ if (root != NULL && u != root)
+ rootp = MPZ_REALLOC (root, rootn);
+ else
+ rootp = TMP_ALLOC_LIMBS (rootn);
+
+ if (u != rem)
+ remp = MPZ_REALLOC (rem, un);
+ else
+ remp = TMP_ALLOC_LIMBS (un);
+
+ up = PTR(u);
+
+ if (nth == 1)
+ {
+ MPN_COPY (rootp, up, un);
+ remn = 0;
+ }
+ else
+ {
+ remn = mpn_rootrem (rootp, remp, up, un, (mp_limb_t) nth);
+ }
+
+ if (root != NULL)
+ {
+ SIZ(root) = us >= 0 ? rootn : -rootn;
+ if (u == root)
+ MPN_COPY (up, rootp, rootn);
+ }
+
+ if (u == rem)
+ MPN_COPY (up, remp, remn);
+ SIZ(rem) = us >= 0 ? remn : -remn;
+ TMP_FREE;
+}
diff --git a/gmp/mpz/rrandomb.c b/gmp/mpz/rrandomb.c
new file mode 100644
index 0000000000..8b1803c6ba
--- /dev/null
+++ b/gmp/mpz/rrandomb.c
@@ -0,0 +1,103 @@
+/* mpz_rrandomb -- Generate a positive random mpz_t of specified bit size, with
+ long runs of consecutive ones and zeros in the binary representation.
+ Meant for testing of other MP routines.
+
+Copyright 2000-2002, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+static void gmp_rrandomb (mp_ptr, gmp_randstate_t, mp_bitcnt_t);
+
+void
+mpz_rrandomb (mpz_ptr x, gmp_randstate_t rstate, mp_bitcnt_t nbits)
+{
+ mp_size_t nl;
+ mp_ptr xp;
+
+ nl = BITS_TO_LIMBS (nbits);
+ if (nbits != 0)
+ {
+ xp = MPZ_NEWALLOC (x, nl);
+ gmp_rrandomb (xp, rstate, nbits);
+ }
+
+ SIZ(x) = nl;
+}
+
+/* Ask _gmp_rand for 32 bits per call unless that's more than a limb can hold.
+ Thus, we get the same random number sequence in the common cases.
+ FIXME: We should always generate the same random number sequence! */
+#if GMP_NUMB_BITS < 32
+#define BITS_PER_RANDCALL GMP_NUMB_BITS
+#else
+#define BITS_PER_RANDCALL 32
+#endif
+
+static void
+gmp_rrandomb (mp_ptr rp, gmp_randstate_t rstate, mp_bitcnt_t nbits)
+{
+ mp_bitcnt_t bi;
+ mp_limb_t ranm; /* buffer for random bits */
+ unsigned cap_chunksize, chunksize;
+ mp_size_t i;
+
+ /* Set entire result to 111..1 */
+ i = BITS_TO_LIMBS (nbits) - 1;
+ rp[i] = GMP_NUMB_MAX >> (GMP_NUMB_BITS - (nbits % GMP_NUMB_BITS)) % GMP_NUMB_BITS;
+ for (i = i - 1; i >= 0; i--)
+ rp[i] = GMP_NUMB_MAX;
+
+ _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL);
+ cap_chunksize = nbits / (ranm % 4 + 1);
+ cap_chunksize += cap_chunksize == 0; /* make it at least 1 */
+
+ bi = nbits;
+
+ for (;;)
+ {
+ _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL);
+ chunksize = 1 + ranm % cap_chunksize;
+ bi = (bi < chunksize) ? 0 : bi - chunksize;
+
+ if (bi == 0)
+ break; /* low chunk is ...1 */
+
+ rp[bi / GMP_NUMB_BITS] ^= CNST_LIMB (1) << bi % GMP_NUMB_BITS;
+
+ _gmp_rand (&ranm, rstate, BITS_PER_RANDCALL);
+ chunksize = 1 + ranm % cap_chunksize;
+ bi = (bi < chunksize) ? 0 : bi - chunksize;
+
+ mpn_incr_u (rp + bi / GMP_NUMB_BITS, CNST_LIMB (1) << bi % GMP_NUMB_BITS);
+
+ if (bi == 0)
+ break; /* low chunk is ...0 */
+ }
+}
diff --git a/gmp/mpz/scan0.c b/gmp/mpz/scan0.c
new file mode 100644
index 0000000000..de24595cfe
--- /dev/null
+++ b/gmp/mpz/scan0.c
@@ -0,0 +1,130 @@
+/* mpz_scan0 -- search for a 0 bit.
+
+Copyright 2000-2002, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* mpn_scan0 can't be used for the u>0 search since there might not be a 0
+ bit before the end of the data. mpn_scan1 could be used for the inverted
+ search under u<0, but usually the search won't go very far so it seems
+ reasonable to inline that code. */
+
+mp_bitcnt_t
+mpz_scan0 (mpz_srcptr u, mp_bitcnt_t starting_bit) __GMP_NOTHROW
+{
+ mp_srcptr u_ptr = PTR(u);
+ mp_size_t size = SIZ(u);
+ mp_size_t abs_size = ABS(size);
+ mp_srcptr u_end = u_ptr + abs_size;
+ mp_size_t starting_limb = starting_bit / GMP_NUMB_BITS;
+ mp_srcptr p = u_ptr + starting_limb;
+ mp_limb_t limb;
+ int cnt;
+
+ /* When past end, there's an immediate 0 bit for u>=0, or no 0 bits for
+ u<0. Notice this test picks up all cases of u==0 too. */
+ if (starting_limb >= abs_size)
+ return (size >= 0 ? starting_bit : ~(mp_bitcnt_t) 0);
+
+ limb = *p;
+
+ if (size >= 0)
+ {
+ /* Mask to 1 all bits before starting_bit, thus ignoring them. */
+ limb |= (CNST_LIMB(1) << (starting_bit % GMP_NUMB_BITS)) - 1;
+
+ /* Search for a limb which isn't all ones. If the end is reached then
+ the zero bit immediately past the end is returned. */
+ while (limb == GMP_NUMB_MAX)
+ {
+ p++;
+ if (p == u_end)
+ return (mp_bitcnt_t) abs_size * GMP_NUMB_BITS;
+ limb = *p;
+ }
+
+ /* Now seek low 1 bit. */
+ limb = ~limb;
+ }
+ else
+ {
+ mp_srcptr q;
+
+ /* If there's a non-zero limb before ours then we're in the ones
+ complement region. Search from *(p-1) downwards since that might
+ give better cache locality, and since a non-zero in the middle of a
+ number is perhaps a touch more likely than at the end. */
+ q = p;
+ while (q != u_ptr)
+ {
+ q--;
+ if (*q != 0)
+ goto inverted;
+ }
+
+ /* Adjust so ~limb implied by searching for 1 bit below becomes -limb.
+ If limb==0 here then this isn't the beginning of twos complement
+ inversion, but that doesn't matter because limb==0 is a zero bit
+ immediately (-1 is all ones for below). */
+ limb--;
+
+ inverted:
+ /* Now seeking a 1 bit. */
+
+ /* Mask to 0 all bits before starting_bit, thus ignoring them. */
+ limb &= (MP_LIMB_T_MAX << (starting_bit % GMP_NUMB_BITS));
+
+ if (limb == 0)
+ {
+ /* If the high limb is zero after masking, then no 1 bits past
+ starting_bit. */
+ p++;
+ if (p == u_end)
+ return ~(mp_bitcnt_t) 0;
+
+ /* Search further for a non-zero limb. The high limb is non-zero,
+ if nothing else. */
+ for (;;)
+ {
+ limb = *p;
+ if (limb != 0)
+ break;
+ p++;
+ ASSERT (p < u_end);
+ }
+ }
+ }
+
+ ASSERT (limb != 0);
+ count_trailing_zeros (cnt, limb);
+ return (mp_bitcnt_t) (p - u_ptr) * GMP_NUMB_BITS + cnt;
+}
diff --git a/gmp/mpz/scan1.c b/gmp/mpz/scan1.c
new file mode 100644
index 0000000000..c9309de691
--- /dev/null
+++ b/gmp/mpz/scan1.c
@@ -0,0 +1,124 @@
+/* mpz_scan1 -- search for a 1 bit.
+
+Copyright 2000-2002, 2004, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* mpn_scan0 can't be used for the inverted u<0 search since there might not
+ be a 0 bit before the end of the data. mpn_scan1 could be used under u>0
+ (except when in the high limb), but usually the search won't go very far
+ so it seems reasonable to inline that code. */
+
+mp_bitcnt_t
+mpz_scan1 (mpz_srcptr u, mp_bitcnt_t starting_bit) __GMP_NOTHROW
+{
+ mp_srcptr u_ptr = PTR(u);
+ mp_size_t size = SIZ(u);
+ mp_size_t abs_size = ABS(size);
+ mp_srcptr u_end = u_ptr + abs_size - 1;
+ mp_size_t starting_limb = starting_bit / GMP_NUMB_BITS;
+ mp_srcptr p = u_ptr + starting_limb;
+ mp_limb_t limb;
+ int cnt;
+
+ /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit for u<0.
+ Notice this test picks up any u==0 too. */
+ if (starting_limb >= abs_size)
+ return (size >= 0 ? ~(mp_bitcnt_t) 0 : starting_bit);
+
+ /* This is an important case, where sign is not relevant! */
+ if (starting_bit == 0)
+ goto short_cut;
+
+ limb = *p;
+
+ if (size >= 0)
+ {
+ /* Mask to 0 all bits before starting_bit, thus ignoring them. */
+ limb &= (MP_LIMB_T_MAX << (starting_bit % GMP_NUMB_BITS));
+
+ if (limb == 0)
+ {
+ /* If it's the high limb which is zero after masking, then there's
+ no 1 bits after starting_bit. */
+ if (p == u_end)
+ return ~(mp_bitcnt_t) 0;
+
+ /* Otherwise search further for a non-zero limb. The high limb is
+ non-zero, if nothing else. */
+ search_nonzero:
+ do
+ {
+ ASSERT (p != u_end);
+ p++;
+ short_cut:
+ limb = *p;
+ }
+ while (limb == 0);
+ }
+ }
+ else
+ {
+ /* If there's a non-zero limb before ours then we're in the ones
+ complement region. */
+ if (mpn_zero_p (u_ptr, starting_limb)) {
+ if (limb == 0)
+ /* Seeking for the first non-zero bit, it is the same for u and -u. */
+ goto search_nonzero;
+
+ /* Adjust so ~limb implied by searching for 0 bit becomes -limb. */
+ limb--;
+ }
+
+ /* Now seeking a 0 bit. */
+
+ /* Mask to 1 all bits before starting_bit, thus ignoring them. */
+ limb |= (CNST_LIMB(1) << (starting_bit % GMP_NUMB_BITS)) - 1;
+
+ /* Search for a limb which is not all ones. If the end is reached
+ then the zero immediately past the end is the result. */
+ while (limb == GMP_NUMB_MAX)
+ {
+ if (p == u_end)
+ return (mp_bitcnt_t) abs_size * GMP_NUMB_BITS;
+ p++;
+ limb = *p;
+ }
+
+ /* Now seeking low 1 bit. */
+ limb = ~limb;
+ }
+
+ ASSERT (limb != 0);
+ count_trailing_zeros (cnt, limb);
+ return (mp_bitcnt_t) (p - u_ptr) * GMP_NUMB_BITS + cnt;
+}
diff --git a/gmp/mpz/set.c b/gmp/mpz/set.c
new file mode 100644
index 0000000000..9d7d58c8d0
--- /dev/null
+++ b/gmp/mpz/set.c
@@ -0,0 +1,50 @@
+/* mpz_set (dest_integer, src_integer) -- Assign DEST_INTEGER from SRC_INTEGER.
+
+Copyright 1991, 1993-1995, 2000, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpz_set (mpz_ptr w, mpz_srcptr u)
+{
+ mp_ptr wp, up;
+ mp_size_t usize, size;
+
+ usize = SIZ(u);
+ size = ABS (usize);
+
+ wp = MPZ_REALLOC (w, size);
+
+ up = PTR(u);
+
+ MPN_COPY (wp, up, size);
+ SIZ(w) = usize;
+}
diff --git a/gmp/mpz/set_d.c b/gmp/mpz/set_d.c
new file mode 100644
index 0000000000..d40ee726d2
--- /dev/null
+++ b/gmp/mpz/set_d.c
@@ -0,0 +1,117 @@
+/* mpz_set_d(integer, val) -- Assign INTEGER with a double value VAL.
+
+Copyright 1995, 1996, 2000-2003, 2006 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if HAVE_FLOAT_H
+#include <float.h> /* for DBL_MAX */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* We used to have a special case for d < MP_BASE_AS_DOUBLE, just casting
+ double -> limb. Unfortunately gcc 3.3 on powerpc970-apple-darwin6.8.5
+ got this wrong. (It assumed __fixunsdfdi returned its result in a single
+ 64-bit register, where instead that function followed the calling
+ conventions and gave the result in two parts r3 and r4.) Hence the use
+ of __gmp_extract_double in all cases. */
+
+void
+mpz_set_d (mpz_ptr r, double d)
+{
+ int negative;
+ mp_limb_t tp[LIMBS_PER_DOUBLE];
+ mp_ptr rp;
+ mp_size_t rn;
+
+ DOUBLE_NAN_INF_ACTION (d,
+ __gmp_invalid_operation (),
+ __gmp_invalid_operation ());
+
+ negative = d < 0;
+ d = ABS (d);
+
+ rn = __gmp_extract_double (tp, d);
+
+ if (ALLOC(r) < rn)
+ _mpz_realloc (r, rn);
+
+ if (rn <= 0)
+ rn = 0;
+
+ rp = PTR (r);
+
+ switch (rn)
+ {
+ default:
+ MPN_ZERO (rp, rn - LIMBS_PER_DOUBLE);
+ rp += rn - LIMBS_PER_DOUBLE;
+ /* fall through */
+#if LIMBS_PER_DOUBLE == 2
+ case 2:
+ rp[1] = tp[1], rp[0] = tp[0];
+ break;
+ case 1:
+ rp[0] = tp[1];
+ break;
+#endif
+#if LIMBS_PER_DOUBLE == 3
+ case 3:
+ rp[2] = tp[2], rp[1] = tp[1], rp[0] = tp[0];
+ break;
+ case 2:
+ rp[1] = tp[2], rp[0] = tp[1];
+ break;
+ case 1:
+ rp[0] = tp[2];
+ break;
+#endif
+#if LIMBS_PER_DOUBLE == 4
+ case 4:
+ rp[3] = tp[3], rp[2] = tp[2], rp[1] = tp[1], rp[0] = tp[0];
+ break;
+ case 3:
+ rp[2] = tp[3], rp[1] = tp[2], rp[0] = tp[1];
+ break;
+ case 2:
+ rp[1] = tp[3], rp[0] = tp[2];
+ break;
+ case 1:
+ rp[0] = tp[3];
+ break;
+#endif
+ case 0:
+ break;
+ }
+
+ SIZ(r) = negative ? -rn : rn;
+}
diff --git a/gmp/mpz/set_f.c b/gmp/mpz/set_f.c
new file mode 100644
index 0000000000..4eb9819837
--- /dev/null
+++ b/gmp/mpz/set_f.c
@@ -0,0 +1,72 @@
+/* mpz_set_f (dest_integer, src_float) -- Assign DEST_INTEGER from SRC_FLOAT.
+
+Copyright 1996, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpz_set_f (mpz_ptr w, mpf_srcptr u)
+{
+ mp_ptr wp, up;
+ mp_size_t size;
+ mp_exp_t exp;
+
+ /* abs(u)<1 truncates to zero */
+ exp = EXP (u);
+ if (exp <= 0)
+ {
+ SIZ(w) = 0;
+ return;
+ }
+
+ wp = MPZ_REALLOC (w, exp);
+ up = PTR(u);
+
+ size = SIZ (u);
+ SIZ(w) = (size >= 0 ? exp : -exp);
+ size = ABS (size);
+
+ if (exp > size)
+ {
+ /* pad with low zeros to get a total "exp" many limbs */
+ mp_size_t zeros = exp - size;
+ MPN_ZERO (wp, zeros);
+ wp += zeros;
+ }
+ else
+ {
+ /* exp<=size, truncate to the high "exp" many limbs */
+ up += (size - exp);
+ size = exp;
+ }
+
+ MPN_COPY (wp, up, size);
+}
diff --git a/gmp/mpz/set_q.c b/gmp/mpz/set_q.c
new file mode 100644
index 0000000000..2627e82298
--- /dev/null
+++ b/gmp/mpz/set_q.c
@@ -0,0 +1,35 @@
+/* mpz_set_q (dest_integer, src_rational) -- Assign DEST_INTEGER from
+ SRC_rational.
+
+Copyright 1996, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_set_q 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpz/set_si.c b/gmp/mpz/set_si.c
new file mode 100644
index 0000000000..1370368332
--- /dev/null
+++ b/gmp/mpz/set_si.c
@@ -0,0 +1,55 @@
+/* mpz_set_si(dest,val) -- Assign DEST with a small value VAL.
+
+Copyright 1991, 1993-1995, 2000-2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_set_si (mpz_ptr dest, signed long int val)
+{
+ mp_size_t size;
+ mp_limb_t vl;
+
+ vl = (mp_limb_t) ABS_CAST (unsigned long int, val);
+
+ PTR (dest)[0] = vl & GMP_NUMB_MASK;
+ size = vl != 0;
+
+#if GMP_NAIL_BITS != 0
+ if (vl > GMP_NUMB_MAX)
+ {
+ MPZ_REALLOC (dest, 2);
+ PTR (dest)[1] = vl >> GMP_NUMB_BITS;
+ size = 2;
+ }
+#endif
+
+ SIZ (dest) = val >= 0 ? size : -size;
+}
diff --git a/gmp/mpz/set_str.c b/gmp/mpz/set_str.c
new file mode 100644
index 0000000000..848d2136a0
--- /dev/null
+++ b/gmp/mpz/set_str.c
@@ -0,0 +1,145 @@
+/* mpz_set_str(mp_dest, string, base) -- Convert the \0-terminated
+ string STRING in base BASE to multiple precision integer in
+ MP_DEST. Allow white space in the string. If BASE == 0 determine
+ the base in the C standard way, i.e. 0xhh...h means base 16,
+ 0oo...o means base 8, otherwise assume base 10.
+
+Copyright 1991, 1993, 1994, 1996-1998, 2000-2003, 2005, 2011-2013 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <string.h>
+#include <ctype.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#define digit_value_tab __gmp_digit_value_tab
+
+int
+mpz_set_str (mpz_ptr x, const char *str, int base)
+{
+ size_t str_size;
+ char *s, *begs;
+ size_t i;
+ mp_size_t xsize;
+ int c;
+ int negative;
+ const unsigned char *digit_value;
+ TMP_DECL;
+
+ digit_value = digit_value_tab;
+ if (base > 36)
+ {
+ /* For bases > 36, use the collating sequence
+ 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz. */
+ digit_value += 208;
+ if (base > 62)
+ return -1; /* too large base */
+ }
+
+ /* Skip whitespace. */
+ do
+ c = (unsigned char) *str++;
+ while (isspace (c));
+
+ negative = 0;
+ if (c == '-')
+ {
+ negative = 1;
+ c = (unsigned char) *str++;
+ }
+
+ if (digit_value[c] >= (base == 0 ? 10 : base))
+ return -1; /* error if no valid digits */
+
+ /* If BASE is 0, try to find out the base by looking at the initial
+ characters. */
+ if (base == 0)
+ {
+ base = 10;
+ if (c == '0')
+ {
+ base = 8;
+ c = (unsigned char) *str++;
+ if (c == 'x' || c == 'X')
+ {
+ base = 16;
+ c = (unsigned char) *str++;
+ }
+ else if (c == 'b' || c == 'B')
+ {
+ base = 2;
+ c = (unsigned char) *str++;
+ }
+ }
+ }
+
+ /* Skip leading zeros and white space. */
+ while (c == '0' || isspace (c))
+ c = (unsigned char) *str++;
+ /* Make sure the string does not become empty, mpn_set_str would fail. */
+ if (c == 0)
+ {
+ SIZ (x) = 0;
+ return 0;
+ }
+
+ TMP_MARK;
+ str_size = strlen (str - 1);
+ s = begs = (char *) TMP_ALLOC (str_size + 1);
+
+ /* Remove spaces from the string and convert the result from ASCII to a
+ byte array. */
+ for (i = 0; i < str_size; i++)
+ {
+ if (!isspace (c))
+ {
+ int dig = digit_value[c];
+ if (dig >= base)
+ {
+ TMP_FREE;
+ return -1;
+ }
+ *s++ = dig;
+ }
+ c = (unsigned char) *str++;
+ }
+
+ str_size = s - begs;
+
+ LIMBS_PER_DIGIT_IN_BASE (xsize, str_size, base);
+ MPZ_REALLOC (x, xsize);
+
+ /* Convert the byte array in base BASE to our bignum format. */
+ xsize = mpn_set_str (PTR (x), (unsigned char *) begs, str_size, base);
+ SIZ (x) = negative ? -xsize : xsize;
+
+ TMP_FREE;
+ return 0;
+}
diff --git a/gmp/mpz/set_ui.c b/gmp/mpz/set_ui.c
new file mode 100644
index 0000000000..f36754cd59
--- /dev/null
+++ b/gmp/mpz/set_ui.c
@@ -0,0 +1,53 @@
+/* mpz_set_ui(integer, val) -- Assign INTEGER with a small value VAL.
+
+Copyright 1991, 1993-1995, 2001, 2002, 2004, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_set_ui (mpz_ptr dest, unsigned long int val)
+{
+ mp_size_t size;
+
+ PTR (dest)[0] = val & GMP_NUMB_MASK;
+ size = val != 0;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (val > GMP_NUMB_MAX)
+ {
+ MPZ_REALLOC (dest, 2);
+ PTR (dest)[1] = val >> GMP_NUMB_BITS;
+ size = 2;
+ }
+#endif
+
+ SIZ (dest) = size;
+}
diff --git a/gmp/mpz/setbit.c b/gmp/mpz/setbit.c
new file mode 100644
index 0000000000..3c2c139f98
--- /dev/null
+++ b/gmp/mpz/setbit.c
@@ -0,0 +1,105 @@
+/* mpz_setbit -- set a specified bit.
+
+Copyright 1991, 1993-1995, 1997, 1999, 2001, 2002, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_setbit (mpz_ptr d, mp_bitcnt_t bit_idx)
+{
+ mp_size_t dsize = SIZ (d);
+ mp_ptr dp = PTR (d);
+ mp_size_t limb_idx;
+ mp_limb_t mask;
+
+ limb_idx = bit_idx / GMP_NUMB_BITS;
+ mask = CNST_LIMB(1) << (bit_idx % GMP_NUMB_BITS);
+ if (dsize >= 0)
+ {
+ if (limb_idx < dsize)
+ {
+ dp[limb_idx] |= mask;
+ }
+ else
+ {
+ /* Ugh. The bit should be set outside of the end of the
+ number. We have to increase the size of the number. */
+ dp = MPZ_REALLOC (d, limb_idx + 1);
+ SIZ (d) = limb_idx + 1;
+ MPN_ZERO (dp + dsize, limb_idx - dsize);
+ dp[limb_idx] = mask;
+ }
+ }
+ else
+ {
+ /* Simulate two's complement arithmetic, i.e. simulate
+ 1. Set OP = ~(OP - 1) [with infinitely many leading ones].
+ 2. Set the bit.
+ 3. Set OP = ~OP + 1. */
+
+ dsize = -dsize;
+
+ if (limb_idx < dsize)
+ {
+ mp_size_t zero_bound;
+ /* No index upper bound on this loop, we're sure there's a non-zero limb
+ sooner or later. */
+ zero_bound = 0;
+ while (dp[zero_bound] == 0)
+ zero_bound++;
+
+ if (limb_idx > zero_bound)
+ {
+ mp_limb_t dlimb;
+ dlimb = dp[limb_idx] & ~mask;
+ dp[limb_idx] = dlimb;
+
+ if (UNLIKELY ((dlimb == 0) + limb_idx == dsize)) /* dsize == limb_idx + 1 */
+ {
+ /* high limb became zero, must normalize */
+ MPN_NORMALIZE (dp, limb_idx);
+ SIZ (d) = -limb_idx;
+ }
+ }
+ else if (limb_idx == zero_bound)
+ {
+ dp[limb_idx] = ((dp[limb_idx] - 1) & ~mask) + 1;
+ ASSERT (dp[limb_idx] != 0);
+ }
+ else
+ {
+ MPN_DECR_U (dp + limb_idx, dsize - limb_idx, mask);
+ dsize -= dp[dsize - 1] == 0;
+ SIZ (d) = -dsize;
+ }
+ }
+ }
+}
diff --git a/gmp/mpz/size.c b/gmp/mpz/size.c
new file mode 100644
index 0000000000..2b324c3423
--- /dev/null
+++ b/gmp/mpz/size.c
@@ -0,0 +1,35 @@
+/* mpz_size(x) -- return the number of lims currently used by the
+ value of integer X.
+
+Copyright 1991, 1993-1995, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_FORCE_mpz_size 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
diff --git a/gmp/mpz/sizeinbase.c b/gmp/mpz/sizeinbase.c
new file mode 100644
index 0000000000..0f3851ea86
--- /dev/null
+++ b/gmp/mpz/sizeinbase.c
@@ -0,0 +1,43 @@
+/* mpz_sizeinbase(x, base) -- return an approximation to the number of
+ character the integer X would have printed in base BASE. The
+ approximation is never too small.
+
+Copyright 1991, 1993-1995, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+size_t
+mpz_sizeinbase (mpz_srcptr x, int base) __GMP_NOTHROW
+{
+ size_t result;
+ MPN_SIZEINBASE (result, PTR(x), ABSIZ(x), base);
+ return result;
+}
diff --git a/gmp/mpz/sqrt.c b/gmp/mpz/sqrt.c
new file mode 100644
index 0000000000..d906cfd59e
--- /dev/null
+++ b/gmp/mpz/sqrt.c
@@ -0,0 +1,77 @@
+/* mpz_sqrt(root, u) -- Set ROOT to floor(sqrt(U)).
+
+Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2005, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_sqrt (mpz_ptr root, mpz_srcptr op)
+{
+ mp_size_t op_size, root_size;
+ mp_ptr root_ptr, op_ptr;
+
+ op_size = SIZ (op);
+ if (UNLIKELY (op_size <= 0))
+ {
+ if (op_size < 0)
+ SQRT_OF_NEGATIVE;
+ SIZ(root) = 0;
+ return;
+ }
+
+ /* The size of the root is accurate after this simple calculation. */
+ root_size = (op_size + 1) / 2;
+ SIZ (root) = root_size;
+
+ op_ptr = PTR (op);
+
+ if (root == op)
+ {
+ /* Allocate temp space for the root, which we then copy to the
+ shared OP/ROOT variable. */
+ TMP_DECL;
+ TMP_MARK;
+
+ root_ptr = TMP_ALLOC_LIMBS (root_size);
+ mpn_sqrtrem (root_ptr, NULL, op_ptr, op_size);
+
+ MPN_COPY (op_ptr, root_ptr, root_size);
+
+ TMP_FREE;
+ }
+ else
+ {
+ root_ptr = MPZ_REALLOC (root, root_size);
+
+ mpn_sqrtrem (root_ptr, NULL, op_ptr, op_size);
+ }
+}
diff --git a/gmp/mpz/sqrtrem.c b/gmp/mpz/sqrtrem.c
new file mode 100644
index 0000000000..99685354d6
--- /dev/null
+++ b/gmp/mpz/sqrtrem.c
@@ -0,0 +1,85 @@
+/* mpz_sqrtrem(root,rem,x) -- Set ROOT to floor(sqrt(X)) and REM
+ to the remainder, i.e. X - ROOT**2.
+
+Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2005, 2011, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_sqrtrem (mpz_ptr root, mpz_ptr rem, mpz_srcptr op)
+{
+ mp_size_t op_size, root_size, rem_size;
+ mp_ptr root_ptr, op_ptr, rem_ptr;
+
+ op_size = SIZ (op);
+ if (UNLIKELY (op_size <= 0))
+ {
+ if (op_size < 0)
+ SQRT_OF_NEGATIVE;
+ SIZ(root) = 0;
+ SIZ(rem) = 0;
+ return;
+ }
+
+ rem_ptr = MPZ_REALLOC (rem, op_size);
+
+ /* The size of the root is accurate after this simple calculation. */
+ root_size = (op_size + 1) / 2;
+ SIZ (root) = root_size;
+
+ op_ptr = PTR (op);
+
+ if (root == op)
+ {
+ /* Allocate temp space for the root, which we then copy to the
+ shared OP/ROOT variable. */
+ TMP_DECL;
+ TMP_MARK;
+
+ root_ptr = TMP_ALLOC_LIMBS (root_size);
+ rem_size = mpn_sqrtrem (root_ptr, rem_ptr, op_ptr, op_size);
+
+ if (rem != root) /* Don't overwrite remainder */
+ MPN_COPY (op_ptr, root_ptr, root_size);
+
+ TMP_FREE;
+ }
+ else
+ {
+ root_ptr = MPZ_REALLOC (root, root_size);
+
+ rem_size = mpn_sqrtrem (root_ptr, rem_ptr, op_ptr, op_size);
+ }
+
+ /* Write remainder size last, to make this function give only the square root
+ remainder, when passed ROOT == REM. */
+ SIZ (rem) = rem_size;
+}
diff --git a/gmp/mpz/sub.c b/gmp/mpz/sub.c
new file mode 100644
index 0000000000..7cb022e069
--- /dev/null
+++ b/gmp/mpz/sub.c
@@ -0,0 +1,33 @@
+/* mpz_sub -- subtract integers.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define OPERATION_sub
+#include "aors.h"
diff --git a/gmp/mpz/sub_ui.c b/gmp/mpz/sub_ui.c
new file mode 100644
index 0000000000..3ce23d3555
--- /dev/null
+++ b/gmp/mpz/sub_ui.c
@@ -0,0 +1,33 @@
+/* mpz_sub_ui -- Subtract an mpz_t and an unsigned one-word integer.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+#define OPERATION_sub_ui
+#include "aors_ui.h"
diff --git a/gmp/mpz/swap.c b/gmp/mpz/swap.c
new file mode 100644
index 0000000000..0fc11fb9e1
--- /dev/null
+++ b/gmp/mpz/swap.c
@@ -0,0 +1,55 @@
+/* mpz_swap (dest_integer, src_integer) -- Swap U and V.
+
+Copyright 1997, 1998, 2001, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_swap (mpz_ptr u, mpz_ptr v) __GMP_NOTHROW
+{
+ mp_ptr up, vp;
+ mp_size_t usize, vsize;
+ mp_size_t ualloc, valloc;
+
+ ualloc = ALLOC (u);
+ valloc = ALLOC (v);
+ ALLOC (v) = ualloc;
+ ALLOC (u) = valloc;
+
+ usize = SIZ (u);
+ vsize = SIZ (v);
+ SIZ (v) = usize;
+ SIZ (u) = vsize;
+
+ up = PTR (u);
+ vp = PTR (v);
+ PTR (v) = up;
+ PTR (u) = vp;
+}
diff --git a/gmp/mpz/tdiv_q.c b/gmp/mpz/tdiv_q.c
new file mode 100644
index 0000000000..38528f35bf
--- /dev/null
+++ b/gmp/mpz/tdiv_q.c
@@ -0,0 +1,93 @@
+/* mpz_tdiv_q -- divide two integers and produce a quotient.
+
+Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2005, 2010, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpz_tdiv_q (mpz_ptr quot, mpz_srcptr num, mpz_srcptr den)
+{
+ mp_size_t ql;
+ mp_size_t ns, ds, nl, dl;
+ mp_ptr np, dp, qp;
+ TMP_DECL;
+
+ ns = SIZ (num);
+ ds = SIZ (den);
+ nl = ABS (ns);
+ dl = ABS (ds);
+ ql = nl - dl + 1;
+
+ if (UNLIKELY (dl == 0))
+ DIVIDE_BY_ZERO;
+
+ if (ql <= 0)
+ {
+ SIZ (quot) = 0;
+ return;
+ }
+
+ qp = MPZ_REALLOC (quot, ql);
+
+ TMP_MARK;
+ np = PTR (num);
+ dp = PTR (den);
+
+ /* Copy denominator to temporary space if it overlaps with the quotient. */
+ if (dp == qp)
+ {
+ mp_ptr tp;
+ tp = TMP_ALLOC_LIMBS (dl);
+ MPN_COPY (tp, dp, dl);
+ dp = tp;
+ }
+ /* Copy numerator to temporary space if it overlaps with the quotient. */
+ if (np == qp)
+ {
+ mp_ptr tp;
+ tp = TMP_ALLOC_LIMBS (nl + 1);
+ MPN_COPY (tp, np, nl);
+ /* Overlap dividend and scratch. */
+ mpn_div_q (qp, tp, nl, dp, dl, tp);
+ }
+ else
+ {
+ mp_ptr tp;
+ tp = TMP_ALLOC_LIMBS (nl + 1);
+ mpn_div_q (qp, np, nl, dp, dl, tp);
+ }
+
+ ql -= qp[ql - 1] == 0;
+
+ SIZ (quot) = (ns ^ ds) >= 0 ? ql : -ql;
+ TMP_FREE;
+}
diff --git a/gmp/mpz/tdiv_q_2exp.c b/gmp/mpz/tdiv_q_2exp.c
new file mode 100644
index 0000000000..9ffcaf2bbb
--- /dev/null
+++ b/gmp/mpz/tdiv_q_2exp.c
@@ -0,0 +1,68 @@
+/* mpz_tdiv_q_2exp -- Divide an integer by 2**CNT. Round the quotient
+ towards -infinity.
+
+Copyright 1991, 1993, 1994, 1996, 2001, 2002, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_tdiv_q_2exp (mpz_ptr r, mpz_srcptr u, mp_bitcnt_t cnt)
+{
+ mp_size_t un, rn;
+ mp_size_t limb_cnt;
+ mp_ptr rp;
+ mp_srcptr up;
+
+ un = SIZ(u);
+ limb_cnt = cnt / GMP_NUMB_BITS;
+ rn = ABS (un) - limb_cnt;
+
+ if (rn <= 0)
+ rn = 0;
+ else
+ {
+ rp = MPZ_REALLOC (r, rn);
+ up = PTR(u) + limb_cnt;
+
+ cnt %= GMP_NUMB_BITS;
+ if (cnt != 0)
+ {
+ mpn_rshift (rp, up, rn, cnt);
+ rn -= rp[rn - 1] == 0;
+ }
+ else
+ {
+ MPN_COPY_INCR (rp, up, rn);
+ }
+ }
+
+ SIZ(r) = un >= 0 ? rn : -rn;
+}
diff --git a/gmp/mpz/tdiv_q_ui.c b/gmp/mpz/tdiv_q_ui.c
new file mode 100644
index 0000000000..88e9082529
--- /dev/null
+++ b/gmp/mpz/tdiv_q_ui.c
@@ -0,0 +1,84 @@
+/* mpz_tdiv_q_ui(quot, dividend, divisor_limb)
+ -- Divide DIVIDEND by DIVISOR_LIMB and store the result in QUOT.
+
+Copyright 1991, 1993, 1994, 1996, 1998, 2001, 2002, 2004, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_tdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn, qn;
+ mp_ptr np, qp;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(quot) = 0;
+ return 0;
+ }
+
+ nn = ABS(ns);
+ qp = MPZ_REALLOC (quot, nn);
+ np = PTR(dividend);
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2], rp[2];
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ SIZ(quot) = 0;
+ rl = np[0];
+ return rl;
+ }
+
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ qn = nn - 2 + 1; qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0;
+ }
+ else
+#endif
+ {
+ rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor);
+ qn = nn - (qp[nn - 1] == 0);
+ }
+
+ SIZ(quot) = ns >= 0 ? qn : -qn;
+ return rl;
+}
diff --git a/gmp/mpz/tdiv_qr.c b/gmp/mpz/tdiv_qr.c
new file mode 100644
index 0000000000..ab9a37dae9
--- /dev/null
+++ b/gmp/mpz/tdiv_qr.c
@@ -0,0 +1,107 @@
+/* mpz_tdiv_qr(quot,rem,dividend,divisor) -- Set QUOT to DIVIDEND/DIVISOR,
+ and REM to DIVIDEND mod DIVISOR.
+
+Copyright 1991, 1993, 1994, 2000, 2001, 2005, 2011, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpz_tdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr num, mpz_srcptr den)
+{
+ mp_size_t ql;
+ mp_size_t ns, ds, nl, dl;
+ mp_ptr np, dp, qp, rp;
+ TMP_DECL;
+
+ ns = SIZ (num);
+ ds = SIZ (den);
+ nl = ABS (ns);
+ dl = ABS (ds);
+ ql = nl - dl + 1;
+
+ if (UNLIKELY (dl == 0))
+ DIVIDE_BY_ZERO;
+
+ rp = MPZ_REALLOC (rem, dl);
+
+ if (ql <= 0)
+ {
+ if (num != rem)
+ {
+ np = PTR (num);
+ MPN_COPY (rp, np, nl);
+ SIZ (rem) = SIZ (num);
+ }
+ /* This needs to follow the assignment to rem, in case the
+ numerator and quotient are the same. */
+ SIZ (quot) = 0;
+ return;
+ }
+
+ qp = MPZ_REALLOC (quot, ql);
+
+ TMP_MARK;
+ np = PTR (num);
+ dp = PTR (den);
+
+ /* FIXME: We should think about how to handle the temporary allocation.
+ Perhaps mpn_tdiv_qr should handle it, since it anyway often needs to
+ allocate temp space. */
+
+ /* Copy denominator to temporary space if it overlaps with the quotient
+ or remainder. */
+ if (dp == rp || dp == qp)
+ {
+ mp_ptr tp;
+ tp = TMP_ALLOC_LIMBS (dl);
+ MPN_COPY (tp, dp, dl);
+ dp = tp;
+ }
+ /* Copy numerator to temporary space if it overlaps with the quotient or
+ remainder. */
+ if (np == rp || np == qp)
+ {
+ mp_ptr tp;
+ tp = TMP_ALLOC_LIMBS (nl);
+ MPN_COPY (tp, np, nl);
+ np = tp;
+ }
+
+ mpn_tdiv_qr (qp, rp, 0L, np, nl, dp, dl);
+
+ ql -= qp[ql - 1] == 0;
+ MPN_NORMALIZE (rp, dl);
+
+ SIZ (quot) = (ns ^ ds) >= 0 ? ql : -ql;
+ SIZ (rem) = ns >= 0 ? dl : -dl;
+ TMP_FREE;
+}
diff --git a/gmp/mpz/tdiv_qr_ui.c b/gmp/mpz/tdiv_qr_ui.c
new file mode 100644
index 0000000000..4f667abe07
--- /dev/null
+++ b/gmp/mpz/tdiv_qr_ui.c
@@ -0,0 +1,103 @@
+/* mpz_tdiv_qr_ui(quot,rem,dividend,short_divisor) --
+ Set QUOT to DIVIDEND / SHORT_DIVISOR
+ and REM to DIVIDEND mod SHORT_DIVISOR.
+
+Copyright 1991, 1993, 1994, 1996, 1998, 2001, 2002, 2004, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_tdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn, qn;
+ mp_ptr np, qp;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(quot) = 0;
+ SIZ(rem) = 0;
+ return 0;
+ }
+
+ nn = ABS(ns);
+ qp = MPZ_REALLOC (quot, nn);
+ np = PTR(dividend);
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2];
+ mp_ptr rp;
+ mp_size_t rn;
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ SIZ(quot) = 0;
+ rl = np[0];
+ SIZ(rem) = ns >= 0 ? 1 : -1;
+ PTR(rem)[0] = rl;
+ return rl;
+ }
+
+ rp = MPZ_REALLOC (rem, 2);
+
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ qn = nn - 2 + 1; qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0;
+ rn = 2 - (rp[1] == 0); rn -= (rp[rn - 1] == 0);
+ SIZ(rem) = ns >= 0 ? rn : -rn;
+ }
+ else
+#endif
+ {
+ rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ SIZ(rem) = 0;
+ else
+ {
+ /* Store the single-limb remainder. We don't check if there's space
+ for just one limb, since no function ever makes zero space. */
+ SIZ(rem) = ns >= 0 ? 1 : -1;
+ PTR(rem)[0] = rl;
+ }
+ qn = nn - (qp[nn - 1] == 0);
+ }
+
+ SIZ(quot) = ns >= 0 ? qn : -qn;
+ return rl;
+}
diff --git a/gmp/mpz/tdiv_r.c b/gmp/mpz/tdiv_r.c
new file mode 100644
index 0000000000..d9cb38c323
--- /dev/null
+++ b/gmp/mpz/tdiv_r.c
@@ -0,0 +1,98 @@
+/* mpz_tdiv_r(rem, dividend, divisor) -- Set REM to DIVIDEND mod DIVISOR.
+
+Copyright 1991, 1993, 1994, 2000, 2001, 2005, 2012 Free Software Foundation,
+Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+mpz_tdiv_r (mpz_ptr rem, mpz_srcptr num, mpz_srcptr den)
+{
+ mp_size_t ql;
+ mp_size_t ns, ds, nl, dl;
+ mp_ptr np, dp, qp, rp;
+ TMP_DECL;
+
+ ns = SIZ (num);
+ ds = SIZ (den);
+ nl = ABS (ns);
+ dl = ABS (ds);
+ ql = nl - dl + 1;
+
+ if (UNLIKELY (dl == 0))
+ DIVIDE_BY_ZERO;
+
+ rp = MPZ_REALLOC (rem, dl);
+
+ if (ql <= 0)
+ {
+ if (num != rem)
+ {
+ np = PTR (num);
+ MPN_COPY (rp, np, nl);
+ SIZ (rem) = SIZ (num);
+ }
+ return;
+ }
+
+ TMP_MARK;
+ qp = TMP_ALLOC_LIMBS (ql);
+ np = PTR (num);
+ dp = PTR (den);
+
+ /* FIXME: We should think about how to handle the temporary allocation.
+ Perhaps mpn_tdiv_qr should handle it, since it anyway often needs to
+ allocate temp space. */
+
+ /* Copy denominator to temporary space if it overlaps with the remainder. */
+ if (dp == rp)
+ {
+ mp_ptr tp;
+ tp = TMP_ALLOC_LIMBS (dl);
+ MPN_COPY (tp, dp, dl);
+ dp = tp;
+ }
+ /* Copy numerator to temporary space if it overlaps with the remainder. */
+ if (np == rp)
+ {
+ mp_ptr tp;
+ tp = TMP_ALLOC_LIMBS (nl);
+ MPN_COPY (tp, np, nl);
+ np = tp;
+ }
+
+ mpn_tdiv_qr (qp, rp, 0L, np, nl, dp, dl);
+
+ MPN_NORMALIZE (rp, dl);
+
+ SIZ (rem) = ns >= 0 ? dl : -dl;
+ TMP_FREE;
+}
diff --git a/gmp/mpz/tdiv_r_2exp.c b/gmp/mpz/tdiv_r_2exp.c
new file mode 100644
index 0000000000..e21d90fecd
--- /dev/null
+++ b/gmp/mpz/tdiv_r_2exp.c
@@ -0,0 +1,78 @@
+/* mpz_tdiv_r_2exp -- Divide an integer by 2**CNT and produce a remainder.
+
+Copyright 1991, 1993-1995, 2001, 2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_tdiv_r_2exp (mpz_ptr res, mpz_srcptr in, mp_bitcnt_t cnt)
+{
+ mp_size_t in_size = ABSIZ (in);
+ mp_size_t res_size;
+ mp_size_t limb_cnt = cnt / GMP_NUMB_BITS;
+ mp_srcptr in_ptr = PTR (in);
+
+ if (in_size > limb_cnt)
+ {
+ /* The input operand is (probably) greater than 2**CNT. */
+ mp_limb_t x;
+
+ x = in_ptr[limb_cnt] & (((mp_limb_t) 1 << cnt % GMP_NUMB_BITS) - 1);
+ if (x != 0)
+ {
+ res_size = limb_cnt + 1;
+ MPZ_REALLOC (res, res_size);
+
+ PTR (res)[limb_cnt] = x;
+ }
+ else
+ {
+ res_size = limb_cnt;
+ MPN_NORMALIZE (in_ptr, res_size);
+
+ MPZ_REALLOC (res, res_size);
+
+ limb_cnt = res_size;
+ }
+ }
+ else
+ {
+ /* The input operand is smaller than 2**CNT. We perform a no-op,
+ apart from that we might need to copy IN to RES. */
+ res_size = in_size;
+ MPZ_REALLOC (res, res_size);
+
+ limb_cnt = res_size;
+ }
+
+ if (res != in)
+ MPN_COPY (PTR (res), PTR (in), limb_cnt);
+ SIZ (res) = SIZ (in) >= 0 ? res_size : -res_size;
+}
diff --git a/gmp/mpz/tdiv_r_ui.c b/gmp/mpz/tdiv_r_ui.c
new file mode 100644
index 0000000000..30addd6db7
--- /dev/null
+++ b/gmp/mpz/tdiv_r_ui.c
@@ -0,0 +1,99 @@
+/* mpz_tdiv_r_ui(rem, dividend, divisor_limb)
+ -- Set REM to DIVDEND mod DIVISOR_LIMB.
+
+Copyright 1991, 1993, 1994, 1996, 1998, 2001, 2002, 2004, 2005, 2012 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+mpz_tdiv_r_ui (mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn;
+ mp_ptr np;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(rem) = 0;
+ return 0;
+ }
+
+ nn = ABS(ns);
+ np = PTR(dividend);
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2];
+ mp_ptr rp, qp;
+ mp_size_t rn;
+ TMP_DECL;
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ rl = np[0];
+ SIZ(rem) = ns >= 0 ? 1 : -1;
+ PTR(rem)[0] = rl;
+ return rl;
+ }
+
+ rp = MPZ_REALLOC (rem, 2);
+
+ TMP_MARK;
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ qp = TMP_ALLOC_LIMBS (nn - 2 + 1);
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ TMP_FREE;
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ rn = 2 - (rp[1] == 0); rn -= (rp[rn - 1] == 0);
+ SIZ(rem) = ns >= 0 ? rn : -rn;
+ }
+ else
+#endif
+ {
+ rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ SIZ(rem) = 0;
+ else
+ {
+ /* Store the single-limb remainder. We don't check if there's space
+ for just one limb, since no function ever makes zero space. */
+ SIZ(rem) = ns >= 0 ? 1 : -1;
+ PTR(rem)[0] = rl;
+ }
+ }
+
+ return rl;
+}
diff --git a/gmp/mpz/tdiv_ui.c b/gmp/mpz/tdiv_ui.c
new file mode 100644
index 0000000000..328d67fdf8
--- /dev/null
+++ b/gmp/mpz/tdiv_ui.c
@@ -0,0 +1,85 @@
+/* mpz_tdiv_ui(dividend, divisor_limb) -- Return DIVDEND mod DIVISOR_LIMB.
+
+Copyright 1991, 1993, 1994, 1996-1998, 2001, 2002, 2004, 2005, 2012 Free
+Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+unsigned long int
+mpz_tdiv_ui (mpz_srcptr dividend, unsigned long int divisor)
+{
+ mp_size_t ns, nn;
+ mp_ptr np;
+ mp_limb_t rl;
+
+ if (UNLIKELY (divisor == 0))
+ DIVIDE_BY_ZERO;
+
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ return 0;
+ }
+
+ nn = ABS(ns);
+ np = PTR(dividend);
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2], rp[2];
+ mp_ptr qp;
+ mp_size_t rn;
+ TMP_DECL;
+
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ rl = np[0];
+ return rl;
+ }
+
+ TMP_MARK;
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ qp = TMP_ALLOC_LIMBS (nn - 2 + 1);
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ TMP_FREE;
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ rn = 2 - (rp[1] == 0); rn -= (rp[rn - 1] == 0);
+ }
+ else
+#endif
+ {
+ rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor);
+ }
+
+ return rl;
+}
diff --git a/gmp/mpz/tstbit.c b/gmp/mpz/tstbit.c
new file mode 100644
index 0000000000..db3d75a64f
--- /dev/null
+++ b/gmp/mpz/tstbit.c
@@ -0,0 +1,81 @@
+/* mpz_tstbit -- test a specified bit.
+
+Copyright 2000, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* For negatives the effective twos complement is achieved by negating the
+ limb tested, either with a ones or twos complement. Twos complement
+ ("-") is used if there's only zero limbs below the one being tested.
+ Ones complement ("~") is used if there's a non-zero below. Note that "-"
+ is correct even if the limb examined is 0 (and the true beginning of twos
+ complement is further up).
+
+ Testing the limbs below p is unavoidable on negatives, but will usually
+ need to examine only *(p-1). The search is done from *(p-1) down to
+ *u_ptr, since that might give better cache locality, and because a
+ non-zero limb is perhaps a touch more likely in the middle of a number
+ than at the low end.
+
+ Bits past the end of available data simply follow sign of u. Notice that
+ the limb_index >= abs_size test covers u=0 too. */
+
+int
+mpz_tstbit (mpz_srcptr u, mp_bitcnt_t bit_index) __GMP_NOTHROW
+{
+ mp_srcptr u_ptr = PTR(u);
+ mp_size_t size = SIZ(u);
+ unsigned abs_size = ABS(size);
+ mp_size_t limb_index = bit_index / GMP_NUMB_BITS;
+ mp_srcptr p = u_ptr + limb_index;
+ mp_limb_t limb;
+
+ if (limb_index >= abs_size)
+ return (size < 0);
+
+ limb = *p;
+ if (size < 0)
+ {
+ limb = -limb; /* twos complement */
+
+ while (p != u_ptr)
+ {
+ p--;
+ if (*p != 0)
+ {
+ limb--; /* make it a ones complement instead */
+ break;
+ }
+ }
+ }
+
+ return (limb >> (bit_index % GMP_NUMB_BITS)) & 1;
+}
diff --git a/gmp/mpz/ui_pow_ui.c b/gmp/mpz/ui_pow_ui.c
new file mode 100644
index 0000000000..a4f23c5655
--- /dev/null
+++ b/gmp/mpz/ui_pow_ui.c
@@ -0,0 +1,59 @@
+/* mpz_ui_pow_ui -- ulong raised to ulong.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+mpz_ui_pow_ui (mpz_ptr r, unsigned long b, unsigned long e)
+{
+#if GMP_NAIL_BITS != 0
+ if (b > GMP_NUMB_MAX)
+ {
+ mp_limb_t bb[2];
+ bb[0] = b & GMP_NUMB_MASK;
+ bb[1] = b >> GMP_NUMB_BITS;
+ mpz_n_pow_ui (r, bb, (mp_size_t) 2, e);
+ }
+ else
+#endif
+ {
+#ifdef _LONG_LONG_LIMB
+ /* i386 gcc 2.95.3 doesn't recognise blimb can be eliminated when
+ mp_limb_t is an unsigned long, so only use a separate blimb when
+ necessary. */
+ mp_limb_t blimb = b;
+ mpz_n_pow_ui (r, &blimb, (mp_size_t) (b != 0), e);
+#else
+ mpz_n_pow_ui (r, &b, (mp_size_t) (b != 0), e);
+#endif
+ }
+}
diff --git a/gmp/mpz/ui_sub.c b/gmp/mpz/ui_sub.c
new file mode 100644
index 0000000000..579a300795
--- /dev/null
+++ b/gmp/mpz/ui_sub.c
@@ -0,0 +1,96 @@
+/* mpz_ui_sub -- Subtract an unsigned one-word integer and an mpz_t.
+
+Copyright 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_ui_sub (mpz_ptr w, unsigned long int uval, mpz_srcptr v)
+{
+ mp_ptr vp, wp;
+ mp_size_t vn, wn;
+ mp_limb_t cy;
+
+#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
+ if (uval > GMP_NUMB_MAX)
+ {
+ mpz_t u;
+ mp_limb_t ul[2];
+ PTR(u) = ul;
+ ul[0] = uval & GMP_NUMB_MASK;
+ ul[1] = uval >> GMP_NUMB_BITS;
+ SIZ(u) = 2;
+ mpz_sub (w, u, v);
+ return;
+ }
+#endif
+
+ vp = PTR(v);
+ vn = SIZ(v);
+
+ wp = PTR(w);
+
+ if (vn > 1)
+ {
+ wp = MPZ_REALLOC (w, vn);
+ vp = PTR(v);
+ mpn_sub_1 (wp, vp, vn, (mp_limb_t) uval);
+ wn = -(vn - (wp[vn - 1] == 0));
+ }
+ else if (vn == 1)
+ {
+ if (uval >= vp[0])
+ {
+ wp[0] = uval - vp[0];
+ wn = wp[0] != 0;
+ }
+ else
+ {
+ wp[0] = vp[0] - uval;
+ wn = -1;
+ }
+ }
+ else if (vn == 0)
+ {
+ wp[0] = uval;
+ wn = uval != 0;
+ }
+ else /* (vn < 0) */
+ {
+ vn = -vn;
+ wp = MPZ_REALLOC (w, vn + 1);
+ vp = PTR(v);
+ cy = mpn_add_1 (wp, vp, vn, (mp_limb_t) uval);
+ wp[vn] = cy;
+ wn = vn + (cy != 0);
+ }
+
+ SIZ(w) = wn;
+}
diff --git a/gmp/mpz/urandomb.c b/gmp/mpz/urandomb.c
new file mode 100644
index 0000000000..f1295699b3
--- /dev/null
+++ b/gmp/mpz/urandomb.c
@@ -0,0 +1,48 @@
+/* mpz_urandomb (rop, state, n) -- Generate a uniform pseudorandom
+ integer in the range 0 to 2^N - 1, inclusive, using STATE as the
+ random state previously initialized by a call to gmp_randinit().
+
+Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_urandomb (mpz_ptr rop, gmp_randstate_t rstate, mp_bitcnt_t nbits)
+{
+ mp_ptr rp;
+ mp_size_t size;
+
+ size = BITS_TO_LIMBS (nbits);
+ rp = MPZ_NEWALLOC (rop, size);
+
+ _gmp_rand (rp, rstate, nbits);
+ MPN_NORMALIZE (rp, size);
+ SIZ (rop) = size;
+}
diff --git a/gmp/mpz/urandomm.c b/gmp/mpz/urandomm.c
new file mode 100644
index 0000000000..434359cdd7
--- /dev/null
+++ b/gmp/mpz/urandomm.c
@@ -0,0 +1,105 @@
+/* mpz_urandomm (rop, state, n) -- Generate a uniform pseudorandom
+ integer in the range 0 to N-1, using STATE as the random state
+ previously initialized by a call to gmp_randinit().
+
+Copyright 2000, 2002, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h" /* for count_leading_zeros */
+
+
+#define MAX_URANDOMM_ITER 80
+
+void
+mpz_urandomm (mpz_ptr rop, gmp_randstate_t rstate, mpz_srcptr n)
+{
+ mp_ptr rp, np, nlast;
+ mp_size_t nbits, size;
+ int count;
+ int pow2;
+ int cmp;
+ TMP_DECL;
+
+ size = ABSIZ (n);
+ if (UNLIKELY (size == 0))
+ DIVIDE_BY_ZERO;
+
+ nlast = &PTR (n)[size - 1];
+
+ /* Detect whether n is a power of 2. */
+ pow2 = POW2_P (*nlast);
+ if (pow2 != 0)
+ for (np = PTR (n); np < nlast; np++)
+ if (*np != 0)
+ {
+ pow2 = 0; /* Mark n as `not a power of two'. */
+ break;
+ }
+
+ count_leading_zeros (count, *nlast);
+ nbits = size * GMP_NUMB_BITS - (count - GMP_NAIL_BITS) - pow2;
+ if (nbits == 0) /* nbits == 0 means that n was == 1. */
+ {
+ SIZ (rop) = 0;
+ return;
+ }
+
+ TMP_MARK;
+ np = PTR (n);
+ if (rop == n)
+ {
+ mp_ptr tp;
+ tp = TMP_ALLOC_LIMBS (size);
+ MPN_COPY (tp, np, size);
+ np = tp;
+ }
+
+ /* Here the allocated size can be one too much if n is a power of
+ (2^GMP_NUMB_BITS) but it's convenient for using mpn_cmp below. */
+ rp = MPZ_REALLOC (rop, size);
+ /* Clear last limb to prevent the case in which size is one too much. */
+ rp[size - 1] = 0;
+
+ count = MAX_URANDOMM_ITER; /* Set iteration count limit. */
+ do
+ {
+ _gmp_rand (rp, rstate, nbits);
+ MPN_CMP (cmp, rp, np, size);
+ }
+ while (cmp >= 0 && --count != 0);
+
+ if (count == 0)
+ /* Too many iterations; return result mod n == result - n */
+ mpn_sub_n (rp, rp, np, size);
+
+ MPN_NORMALIZE (rp, size);
+ SIZ (rop) = size;
+ TMP_FREE;
+}
diff --git a/gmp/mpz/xor.c b/gmp/mpz/xor.c
new file mode 100644
index 0000000000..cd701000d5
--- /dev/null
+++ b/gmp/mpz/xor.c
@@ -0,0 +1,194 @@
+/* mpz_xor -- Logical xor.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2005, 2012 Free Software
+Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpz_xor (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2)
+{
+ mp_srcptr op1_ptr, op2_ptr;
+ mp_size_t op1_size, op2_size;
+ mp_ptr res_ptr;
+ mp_size_t res_size, res_alloc;
+ TMP_DECL;
+
+ TMP_MARK;
+ op1_size = SIZ(op1);
+ op2_size = SIZ(op2);
+
+ op1_ptr = PTR(op1);
+ op2_ptr = PTR(op2);
+ res_ptr = PTR(res);
+
+ if (op1_size >= 0)
+ {
+ if (op2_size >= 0)
+ {
+ if (op1_size >= op2_size)
+ {
+ if (ALLOC(res) < op1_size)
+ {
+ _mpz_realloc (res, op1_size);
+ /* No overlapping possible: op1_ptr = PTR(op1); */
+ op2_ptr = PTR(op2);
+ res_ptr = PTR(res);
+ }
+
+ if (res_ptr != op1_ptr)
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size,
+ op1_size - op2_size);
+ if (LIKELY (op2_size != 0))
+ mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op2_size);
+ res_size = op1_size;
+ }
+ else
+ {
+ if (ALLOC(res) < op2_size)
+ {
+ _mpz_realloc (res, op2_size);
+ op1_ptr = PTR(op1);
+ /* No overlapping possible: op2_ptr = PTR(op2); */
+ res_ptr = PTR(res);
+ }
+
+ if (res_ptr != op2_ptr)
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size,
+ op2_size - op1_size);
+ if (LIKELY (op1_size != 0))
+ mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op1_size);
+ res_size = op2_size;
+ }
+
+ MPN_NORMALIZE (res_ptr, res_size);
+ SIZ(res) = res_size;
+ return;
+ }
+ else /* op2_size < 0 */
+ {
+ /* Fall through to the code at the end of the function. */
+ }
+ }
+ else
+ {
+ if (op2_size < 0)
+ {
+ mp_ptr opx, opy;
+
+ /* Both operands are negative, the result will be positive.
+ (-OP1) ^ (-OP2) =
+ = ~(OP1 - 1) ^ ~(OP2 - 1) =
+ = (OP1 - 1) ^ (OP2 - 1) */
+
+ op1_size = -op1_size;
+ op2_size = -op2_size;
+
+ /* Possible optimization: Decrease mpn_sub precision,
+ as we won't use the entire res of both. */
+ TMP_ALLOC_LIMBS_2 (opx, op1_size, opy, op2_size);
+ mpn_sub_1 (opx, op1_ptr, op1_size, (mp_limb_t) 1);
+ op1_ptr = opx;
+
+ mpn_sub_1 (opy, op2_ptr, op2_size, (mp_limb_t) 1);
+ op2_ptr = opy;
+
+ if (op1_size > op2_size)
+ MPN_SRCPTR_SWAP (op1_ptr,op1_size, op2_ptr,op2_size);
+
+ res_alloc = op2_size;
+ res_ptr = MPZ_REALLOC (res, res_alloc);
+
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size,
+ op2_size - op1_size);
+ mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op1_size);
+ res_size = op2_size;
+
+ MPN_NORMALIZE (res_ptr, res_size);
+ SIZ(res) = res_size;
+ TMP_FREE;
+ return;
+ }
+ else
+ {
+ /* We should compute -OP1 ^ OP2. Swap OP1 and OP2 and fall
+ through to the code that handles OP1 ^ -OP2. */
+ MPZ_SRCPTR_SWAP (op1, op2);
+ MPN_SRCPTR_SWAP (op1_ptr,op1_size, op2_ptr,op2_size);
+ }
+ }
+
+ {
+ mp_ptr opx;
+ mp_limb_t cy;
+
+ /* Operand 2 negative, so will be the result.
+ -(OP1 ^ (-OP2)) = -(OP1 ^ ~(OP2 - 1)) =
+ = ~(OP1 ^ ~(OP2 - 1)) + 1 =
+ = (OP1 ^ (OP2 - 1)) + 1 */
+
+ op2_size = -op2_size;
+
+ opx = TMP_ALLOC_LIMBS (op2_size);
+ mpn_sub_1 (opx, op2_ptr, op2_size, (mp_limb_t) 1);
+ op2_ptr = opx;
+
+ res_alloc = MAX (op1_size, op2_size) + 1;
+ if (ALLOC(res) < res_alloc)
+ {
+ _mpz_realloc (res, res_alloc);
+ op1_ptr = PTR(op1);
+ /* op2_ptr points to temporary space. */
+ res_ptr = PTR(res);
+ }
+
+ if (op1_size > op2_size)
+ {
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, op1_size - op2_size);
+ mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op2_size);
+ res_size = op1_size;
+ }
+ else
+ {
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size);
+ if (LIKELY (op1_size != 0))
+ mpn_xor_n (res_ptr, op1_ptr, op2_ptr, op1_size);
+ res_size = op2_size;
+ }
+
+ cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1);
+ res_ptr[res_size] = cy;
+ res_size += (cy != 0);
+
+ MPN_NORMALIZE (res_ptr, res_size);
+ SIZ(res) = -res_size;
+ TMP_FREE;
+ }
+}
diff --git a/gmp/nextprime.c b/gmp/nextprime.c
new file mode 100644
index 0000000000..dd9ded5873
--- /dev/null
+++ b/gmp/nextprime.c
@@ -0,0 +1,167 @@
+/* gmp_nextprime -- generate small primes reasonably efficiently for internal
+ GMP needs.
+
+ Contributed to the GNU project by Torbjorn Granlund. Miscellaneous
+ improvements by Martin Boij.
+
+ THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY
+ SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
+ GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/*
+ Optimisation ideas:
+
+ 1. Unroll the sieving loops. Should reach 1 write/cycle. That would be a 2x
+ improvement.
+
+ 2. Separate sieving with primes p < SIEVESIZE and p >= SIEVESIZE. The latter
+ will need at most one write, and thus not need any inner loop.
+
+ 3. For primes p >= SIEVESIZE, i.e., typically the majority of primes, we
+ perform more than one division per sieving write. That might dominate the
+ entire run time for the nextprime function. A incrementally initialised
+ remainder table of Pi(65536) = 6542 16-bit entries could replace that
+ division.
+*/
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include <string.h> /* for memset */
+
+
+unsigned long int
+gmp_nextprime (gmp_primesieve_t *ps)
+{
+ unsigned long p, d, pi;
+ unsigned char *sp;
+ static unsigned char addtab[] =
+ { 2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,2,4,6,2,6,6,4,
+ 2,4,6,2,6,4,2,4,2,10,2,10 };
+ unsigned char *addp = addtab;
+ unsigned long ai;
+
+ /* Look for already sieved primes. A sentinel at the end of the sieving
+ area allows us to use a very simple loop here. */
+ d = ps->d;
+ sp = ps->s + d;
+ while (*sp != 0)
+ sp++;
+ if (sp != ps->s + SIEVESIZE)
+ {
+ d = sp - ps->s;
+ ps->d = d + 1;
+ return ps->s0 + 2 * d;
+ }
+
+ /* Handle the number 2 separately. */
+ if (ps->s0 < 3)
+ {
+ ps->s0 = 3 - 2 * SIEVESIZE; /* Tricky */
+ return 2;
+ }
+
+ /* Exhausted computed primes. Resieve, then call ourselves recursively. */
+
+#if 0
+ for (sp = ps->s; sp < ps->s + SIEVESIZE; sp++)
+ *sp = 0;
+#else
+ memset (ps->s, 0, SIEVESIZE);
+#endif
+
+ ps->s0 += 2 * SIEVESIZE;
+
+ /* Update sqrt_s0 as needed. */
+ while ((ps->sqrt_s0 + 1) * (ps->sqrt_s0 + 1) <= ps->s0 + 2 * SIEVESIZE - 1)
+ ps->sqrt_s0++;
+
+ pi = ((ps->s0 + 3) / 2) % 3;
+ if (pi > 0)
+ pi = 3 - pi;
+ if (ps->s0 + 2 * pi <= 3)
+ pi += 3;
+ sp = ps->s + pi;
+ while (sp < ps->s + SIEVESIZE)
+ {
+ *sp = 1, sp += 3;
+ }
+
+ pi = ((ps->s0 + 5) / 2) % 5;
+ if (pi > 0)
+ pi = 5 - pi;
+ if (ps->s0 + 2 * pi <= 5)
+ pi += 5;
+ sp = ps->s + pi;
+ while (sp < ps->s + SIEVESIZE)
+ {
+ *sp = 1, sp += 5;
+ }
+
+ pi = ((ps->s0 + 7) / 2) % 7;
+ if (pi > 0)
+ pi = 7 - pi;
+ if (ps->s0 + 2 * pi <= 7)
+ pi += 7;
+ sp = ps->s + pi;
+ while (sp < ps->s + SIEVESIZE)
+ {
+ *sp = 1, sp += 7;
+ }
+
+ p = 11;
+ ai = 0;
+ while (p <= ps->sqrt_s0)
+ {
+ pi = ((ps->s0 + p) / 2) % p;
+ if (pi > 0)
+ pi = p - pi;
+ if (ps->s0 + 2 * pi <= p)
+ pi += p;
+ sp = ps->s + pi;
+ while (sp < ps->s + SIEVESIZE)
+ {
+ *sp = 1, sp += p;
+ }
+ p += addp[ai];
+ ai = (ai + 1) % 48;
+ }
+ ps->d = 0;
+ return gmp_nextprime (ps);
+}
+
+void
+gmp_init_primesieve (gmp_primesieve_t *ps)
+{
+ ps->s0 = 0;
+ ps->sqrt_s0 = 0;
+ ps->d = SIEVESIZE;
+ ps->s[SIEVESIZE] = 0; /* sentinel */
+}
diff --git a/gmp/primesieve.c b/gmp/primesieve.c
new file mode 100644
index 0000000000..569e4cecea
--- /dev/null
+++ b/gmp/primesieve.c
@@ -0,0 +1,295 @@
+/* primesieve (BIT_ARRAY, N) -- Fills the BIT_ARRAY with a mask for primes up to N.
+
+Contributed to the GNU project by Marco Bodrato.
+
+THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE.
+IT IS ONLY SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES.
+IN FACT, IT IS ALMOST GUARANTEED THAT IT WILL CHANGE OR
+DISAPPEAR IN A FUTURE GNU MP RELEASE.
+
+Copyright 2010-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/**************************************************************/
+/* Section macros: common macros, for mswing/fac/bin (&sieve) */
+/**************************************************************/
+
+#define LOOP_ON_SIEVE_CONTINUE(prime,end,sieve) \
+ __max_i = (end); \
+ \
+ do { \
+ ++__i; \
+ if (((sieve)[__index] & __mask) == 0) \
+ { \
+ (prime) = id_to_n(__i)
+
+#define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve) \
+ do { \
+ mp_limb_t __mask, __index, __max_i, __i; \
+ \
+ __i = (start)-(off); \
+ __index = __i / GMP_LIMB_BITS; \
+ __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS); \
+ __i += (off); \
+ \
+ LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)
+
+#define LOOP_ON_SIEVE_STOP \
+ } \
+ __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1); \
+ __index += __mask & 1; \
+ } while (__i <= __max_i) \
+
+#define LOOP_ON_SIEVE_END \
+ LOOP_ON_SIEVE_STOP; \
+ } while (0)
+
+/*********************************************************/
+/* Section sieve: sieving functions and tools for primes */
+/*********************************************************/
+
+#if 0
+static mp_limb_t
+bit_to_n (mp_limb_t bit) { return (bit*3+4)|1; }
+#endif
+
+/* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/
+static mp_limb_t
+id_to_n (mp_limb_t id) { return id*3+1+(id&1); }
+
+/* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */
+static mp_limb_t
+n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; }
+
+#if 0
+static mp_size_t
+primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; }
+#endif
+
+#if GMP_LIMB_BITS > 61
+#define SIEVE_SEED CNST_LIMB(0x3294C9E069128480)
+#define SEED_LIMIT 202
+#else
+#if GMP_LIMB_BITS > 30
+#define SIEVE_SEED CNST_LIMB(0x69128480)
+#define SEED_LIMIT 114
+#else
+#if GMP_LIMB_BITS > 15
+#define SIEVE_SEED CNST_LIMB(0x8480)
+#define SEED_LIMIT 54
+#else
+#if GMP_LIMB_BITS > 7
+#define SIEVE_SEED CNST_LIMB(0x80)
+#define SEED_LIMIT 34
+#else
+#define SIEVE_SEED CNST_LIMB(0x0)
+#define SEED_LIMIT 24
+#endif /* 7 */
+#endif /* 15 */
+#endif /* 30 */
+#endif /* 61 */
+
+static void
+first_block_primesieve (mp_ptr bit_array, mp_limb_t n)
+{
+ mp_size_t bits, limbs;
+
+ ASSERT (n > 4);
+
+ bits = n_to_bit(n);
+ limbs = bits / GMP_LIMB_BITS + 1;
+
+ /* FIXME: We can skip 5 too, filling with a 5-part pattern. */
+ MPN_ZERO (bit_array, limbs);
+ bit_array[0] = SIEVE_SEED;
+
+ if ((bits + 1) % GMP_LIMB_BITS != 0)
+ bit_array[limbs-1] |= MP_LIMB_T_MAX << ((bits + 1) % GMP_LIMB_BITS);
+
+ if (n > SEED_LIMIT) {
+ mp_limb_t mask, index, i;
+
+ ASSERT (n > 49);
+
+ mask = 1;
+ index = 0;
+ i = 1;
+ do {
+ if ((bit_array[index] & mask) == 0)
+ {
+ mp_size_t step, lindex;
+ mp_limb_t lmask;
+ unsigned maskrot;
+
+ step = id_to_n(i);
+/* lindex = n_to_bit(id_to_n(i)*id_to_n(i)); */
+ lindex = i*(step+1)-1+(-(i&1)&(i+1));
+/* lindex = i*(step+1+(i&1))-1+(i&1); */
+ if (lindex > bits)
+ break;
+
+ step <<= 1;
+ maskrot = step % GMP_LIMB_BITS;
+
+ lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
+ do {
+ bit_array[lindex / GMP_LIMB_BITS] |= lmask;
+ lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
+ lindex += step;
+ } while (lindex <= bits);
+
+/* lindex = n_to_bit(id_to_n(i)*bit_to_n(i)); */
+ lindex = i*(i*3+6)+(i&1);
+
+ lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
+ for ( ; lindex <= bits; lindex += step) {
+ bit_array[lindex / GMP_LIMB_BITS] |= lmask;
+ lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
+ };
+ }
+ mask = mask << 1 | mask >> (GMP_LIMB_BITS-1);
+ index += mask & 1;
+ i++;
+ } while (1);
+ }
+}
+
+static void
+block_resieve (mp_ptr bit_array, mp_size_t limbs, mp_limb_t offset,
+ mp_srcptr sieve, mp_limb_t sieve_bits)
+{
+ mp_size_t bits, step;
+
+ ASSERT (limbs > 0);
+
+ bits = limbs * GMP_LIMB_BITS - 1;
+
+ /* FIXME: We can skip 5 too, filling with a 5-part pattern. */
+ MPN_ZERO (bit_array, limbs);
+
+ LOOP_ON_SIEVE_BEGIN(step,0,sieve_bits,0,sieve);
+ {
+ mp_size_t lindex;
+ mp_limb_t lmask;
+ unsigned maskrot;
+
+/* lindex = n_to_bit(id_to_n(i)*id_to_n(i)); */
+ lindex = __i*(step+1)-1+(-(__i&1)&(__i+1));
+/* lindex = __i*(step+1+(__i&1))-1+(__i&1); */
+ if (lindex > bits + offset)
+ break;
+
+ step <<= 1;
+ maskrot = step % GMP_LIMB_BITS;
+
+ if (lindex < offset)
+ lindex += step * ((offset - lindex - 1) / step + 1);
+
+ lindex -= offset;
+
+ lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
+ for ( ; lindex <= bits; lindex += step) {
+ bit_array[lindex / GMP_LIMB_BITS] |= lmask;
+ lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
+ };
+
+/* lindex = n_to_bit(id_to_n(i)*bit_to_n(i)); */
+ lindex = __i*(__i*3+6)+(__i&1);
+ if (lindex > bits + offset)
+ continue;
+
+ if (lindex < offset)
+ lindex += step * ((offset - lindex - 1) / step + 1);
+
+ lindex -= offset;
+
+ lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
+ for ( ; lindex <= bits; lindex += step) {
+ bit_array[lindex / GMP_LIMB_BITS] |= lmask;
+ lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
+ };
+ }
+ LOOP_ON_SIEVE_END;
+}
+
+#define BLOCK_SIZE 2048
+
+/* Fills bit_array with the characteristic function of composite
+ numbers up to the parameter n. I.e. a bit set to "1" represent a
+ composite, a "0" represent a prime.
+
+ The primesieve_size(n) limbs pointed to by bit_array are
+ overwritten. The returned value counts prime integers in the
+ interval [4, n]. Note that n > 4.
+
+ Even numbers and multiples of 3 are excluded "a priori", only
+ numbers equivalent to +/- 1 mod 6 have their bit in the array.
+
+ Once sieved, if the bit b is ZERO it represent a prime, the
+ represented prime is bit_to_n(b), if the LSbit is bit 0, or
+ id_to_n(b), if you call "1" the first bit.
+ */
+
+mp_limb_t
+gmp_primesieve (mp_ptr bit_array, mp_limb_t n)
+{
+ mp_size_t size;
+ mp_limb_t bits;
+
+ ASSERT (n > 4);
+
+ bits = n_to_bit(n);
+ size = bits / GMP_LIMB_BITS + 1;
+
+ if (size > BLOCK_SIZE * 2) {
+ mp_size_t off;
+ off = BLOCK_SIZE + (size % BLOCK_SIZE);
+ first_block_primesieve (bit_array, id_to_n (off * GMP_LIMB_BITS));
+ for ( ; off < size; off += BLOCK_SIZE)
+ block_resieve (bit_array + off, BLOCK_SIZE, off * GMP_LIMB_BITS, bit_array, off * GMP_LIMB_BITS - 1);
+ } else {
+ first_block_primesieve (bit_array, n);
+ }
+
+ if ((bits + 1) % GMP_LIMB_BITS != 0)
+ bit_array[size-1] |= MP_LIMB_T_MAX << ((bits + 1) % GMP_LIMB_BITS);
+
+
+ return size * GMP_LIMB_BITS - mpn_popcount (bit_array, size);
+}
+
+#undef BLOCK_SIZE
+#undef SEED_LIMIT
+#undef SIEVE_SEED
+#undef LOOP_ON_SIEVE_END
+#undef LOOP_ON_SIEVE_STOP
+#undef LOOP_ON_SIEVE_BEGIN
+#undef LOOP_ON_SIEVE_CONTINUE
diff --git a/gmp/printf/Makefile.am b/gmp/printf/Makefile.am
new file mode 100644
index 0000000000..c8e3c78c6c
--- /dev/null
+++ b/gmp/printf/Makefile.am
@@ -0,0 +1,41 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2001, 2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+
+noinst_LTLIBRARIES = libprintf.la
+
+libprintf_la_SOURCES = \
+ asprintf.c asprntffuns.c doprnt.c doprntf.c doprnti.c \
+ fprintf.c obprintf.c obvprintf.c obprntffuns.c \
+ printf.c printffuns.c snprintf.c snprntffuns.c sprintf.c sprintffuns.c \
+ vasprintf.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c \
+ repl-vsnprintf.c
diff --git a/gmp/printf/Makefile.in b/gmp/printf/Makefile.in
new file mode 100644
index 0000000000..ff4bdfb37c
--- /dev/null
+++ b/gmp/printf/Makefile.in
@@ -0,0 +1,562 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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, 2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = printf
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libprintf_la_LIBADD =
+am_libprintf_la_OBJECTS = asprintf.lo asprntffuns.lo doprnt.lo \
+ doprntf.lo doprnti.lo fprintf.lo obprintf.lo obvprintf.lo \
+ obprntffuns.lo printf.lo printffuns.lo snprintf.lo \
+ snprntffuns.lo sprintf.lo sprintffuns.lo vasprintf.lo \
+ vfprintf.lo vprintf.lo vsnprintf.lo vsprintf.lo \
+ repl-vsnprintf.lo
+libprintf_la_OBJECTS = $(am_libprintf_la_OBJECTS)
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libprintf_la_SOURCES)
+DIST_SOURCES = $(libprintf_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+noinst_LTLIBRARIES = libprintf.la
+libprintf_la_SOURCES = \
+ asprintf.c asprntffuns.c doprnt.c doprntf.c doprnti.c \
+ fprintf.c obprintf.c obvprintf.c obprntffuns.c \
+ printf.c printffuns.c snprintf.c snprntffuns.c sprintf.c sprintffuns.c \
+ vasprintf.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c \
+ repl-vsnprintf.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 printf/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps printf/Makefile
+.PRECIOUS: 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-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libprintf.la: $(libprintf_la_OBJECTS) $(libprintf_la_DEPENDENCIES) $(EXTRA_libprintf_la_DEPENDENCIES)
+ $(LINK) $(libprintf_la_OBJECTS) $(libprintf_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+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:
+
+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-generic clean-libtool clean-noinstLTLIBRARIES \
+ 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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags 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 tags uninstall uninstall-am
+
+
+# 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/gmp/printf/asprintf.c b/gmp/printf/asprintf.c
new file mode 100644
index 0000000000..b35d9b10c8
--- /dev/null
+++ b/gmp/printf/asprintf.c
@@ -0,0 +1,48 @@
+/* gmp_asprintf -- formatted output to an allocated space.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_asprintf (char **result, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start (ap, fmt);
+
+ ret = gmp_vasprintf (result, fmt, ap);
+ va_end (ap);
+ return ret;
+}
diff --git a/gmp/printf/asprntffuns.c b/gmp/printf/asprntffuns.c
new file mode 100644
index 0000000000..c141b7a99e
--- /dev/null
+++ b/gmp/printf/asprntffuns.c
@@ -0,0 +1,72 @@
+/* __gmp_asprintf_memory etc -- formatted output to allocated space.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* These routines are in a separate file so that the mpz_t, mpq_t and mpf_t
+ operator<< routines can avoid dragging vsnprintf into the link (via
+ __gmp_asprintf_format). */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+__gmp_asprintf_memory (struct gmp_asprintf_t *d, const char *str, size_t len)
+{
+ GMP_ASPRINTF_T_NEED (d, len);
+ memcpy (d->buf + d->size, str, len);
+ d->size += len;
+ return len;
+}
+
+int
+__gmp_asprintf_reps (struct gmp_asprintf_t *d, int c, int reps)
+{
+ GMP_ASPRINTF_T_NEED (d, reps);
+ memset (d->buf + d->size, c, reps);
+ d->size += reps;
+ return reps;
+}
+
+int
+__gmp_asprintf_final (struct gmp_asprintf_t *d)
+{
+ char *buf = d->buf;
+ ASSERT (d->alloc >= d->size + 1);
+ buf[d->size] = '\0';
+ __GMP_REALLOCATE_FUNC_MAYBE_TYPE (buf, d->alloc, d->size+1, char);
+ *d->result = buf;
+ return 0;
+}
diff --git a/gmp/printf/doprnt.c b/gmp/printf/doprnt.c
new file mode 100644
index 0000000000..5220feee20
--- /dev/null
+++ b/gmp/printf/doprnt.c
@@ -0,0 +1,627 @@
+/* __gmp_doprnt -- printf style formatted output.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define _GNU_SOURCE /* for DECIMAL_POINT in glibc langinfo.h */
+
+#include "config.h" /* needed for the HAVE_, could also move gmp incls */
+
+#include <stdarg.h>
+#include <ctype.h> /* for isdigit */
+#include <stddef.h> /* for ptrdiff_t */
+#include <string.h>
+#include <stdio.h> /* for NULL */
+#include <stdlib.h>
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h> /* for intmax_t */
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+
+#if HAVE_LANGINFO_H
+#include <langinfo.h> /* for nl_langinfo */
+#endif
+
+#if HAVE_LOCALE_H
+#include <locale.h> /* for localeconv */
+#endif
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h> /* for quad_t */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* change this to "#define TRACE(x) x" for diagnostics */
+#define TRACE(x)
+
+
+/* Should be portable, but in any case this is only used under some ASSERTs. */
+#define va_equal(x, y) \
+ (memcmp (&(x), &(y), sizeof(va_list)) == 0)
+
+
+/* printf is convenient because it allows various types to be printed in one
+ fairly compact call, so having gmp_printf support the standard types as
+ well as the gmp ones is important. This ends up meaning all the standard
+ parsing must be duplicated, to get a new routine recognising the gmp
+ extras.
+
+ With the currently favoured handling of mpz etc as Z, Q and F type
+ markers, it's not possible to use glibc register_printf_function since
+ that only accepts new conversion characters, not new types. If Z was a
+ conversion there'd be no way to specify hex, decimal or octal, or
+ similarly with F no way to specify fixed point or scientific format.
+
+ It seems wisest to pass conversions %f, %e and %g of float, double and
+ long double over to the standard printf. It'd be hard to be sure of
+ getting the right handling for NaNs, rounding, etc. Integer conversions
+ %d etc and string conversions %s on the other hand could be easily enough
+ handled within gmp_doprnt, but if floats are going to libc then it's just
+ as easy to send all non-gmp types there.
+
+ "Z" was a type marker for size_t in old glibc, but there seems no need to
+ provide access to that now "z" is standard.
+
+ In GMP 4.1.1 we documented "ll" and "L" as being equivalent, but in C99
+ in fact "ll" is just for long long and "L" just for long double.
+ Apparently GLIBC allows "L" for long long though. This doesn't affect
+ us as such, since both are passed through to the C library. To be
+ consistent with what we said before, the two are treated equivalently
+ here, and it's left to the C library to do what it thinks with them.
+
+ Possibilities:
+
+ "b" might be nice for binary output, and could even be supported for the
+ standard C types too if desired.
+
+ POSIX style "%n$" parameter numbering would be possible, but would need
+ to be handled completely within gmp_doprnt, since the numbering will be
+ all different once the format string it cut into pieces.
+
+ Some options for mpq formatting would be good. Perhaps a non-zero
+ precision field could give a width for the denominator and mean always
+ put a "/". A form "n+p/q" might interesting too, though perhaps that's
+ better left to applications.
+
+ Right now there's no way for an application to know whether types like
+ intmax_t are supported here. If configure is doing its job and the same
+ compiler is used for gmp as for the application then there shouldn't be
+ any problem, but perhaps gmp.h should have some preprocessor symbols to
+ say what libgmp can do. */
+
+
+
+/* If a gmp format is the very first thing or there are two gmp formats with
+ nothing in between then we'll reach here with this_fmt == last_fmt and we
+ can do nothing in that case.
+
+ last_ap is always replaced after a FLUSH, so it doesn't matter if va_list
+ is a call-by-reference and the funs->format routine modifies it. */
+
+#define FLUSH() \
+ do { \
+ if (this_fmt == last_fmt) \
+ { \
+ TRACE (printf ("nothing to flush\n")); \
+ ASSERT (va_equal (this_ap, last_ap)); \
+ } \
+ else \
+ { \
+ ASSERT (*this_fmt == '%'); \
+ *this_fmt = '\0'; \
+ TRACE (printf ("flush \"%s\"\n", last_fmt)); \
+ DOPRNT_FORMAT (last_fmt, last_ap); \
+ } \
+ } while (0)
+
+
+/* Parse up the given format string and do the appropriate output using the
+ given "funs" routines. The data parameter is passed through to those
+ routines. */
+
+int
+__gmp_doprnt (const struct doprnt_funs_t *funs, void *data,
+ const char *orig_fmt, va_list orig_ap)
+{
+ va_list ap, this_ap, last_ap;
+ size_t alloc_fmt_size;
+ char *fmt, *alloc_fmt, *last_fmt, *this_fmt, *gmp_str;
+ int retval = 0;
+ int type, fchar, *value, seen_precision;
+ struct doprnt_params_t param;
+
+ TRACE (printf ("gmp_doprnt \"%s\"\n", orig_fmt));
+
+ /* Don't modify orig_ap, if va_list is actually an array and hence call by
+ reference. It could be argued that it'd be more efficient to leave the
+ caller to make a copy if it cared, but doing so here is going to be a
+ very small part of the total work, and we may as well keep applications
+ out of trouble. */
+ va_copy (ap, orig_ap);
+
+ /* The format string is chopped up into pieces to be passed to
+ funs->format. Unfortunately that means it has to be copied so each
+ piece can be null-terminated. We're not going to be very fast here, so
+ use __gmp_allocate_func rather than TMP_ALLOC, to avoid overflowing the
+ stack if a long output string is given. */
+ alloc_fmt_size = strlen (orig_fmt) + 1;
+#if _LONG_LONG_LIMB
+ /* for a long long limb we change %Mx to %llx, so could need an extra 1
+ char for every 3 existing */
+ alloc_fmt_size += alloc_fmt_size / 3;
+#endif
+ alloc_fmt = __GMP_ALLOCATE_FUNC_TYPE (alloc_fmt_size, char);
+ fmt = alloc_fmt;
+ memcpy (fmt, orig_fmt, alloc_fmt_size);
+
+ /* last_fmt and last_ap are just after the last output, and hence where
+ the next output will begin, when that's done */
+ last_fmt = fmt;
+ va_copy (last_ap, ap);
+
+ for (;;)
+ {
+ TRACE (printf ("next: \"%s\"\n", fmt));
+
+ fmt = strchr (fmt, '%');
+ if (fmt == NULL)
+ break;
+
+ /* this_fmt and this_ap are the current '%' sequence being considered */
+ this_fmt = fmt;
+ va_copy (this_ap, ap);
+ fmt++; /* skip the '%' */
+
+ TRACE (printf ("considering\n");
+ printf (" last: \"%s\"\n", last_fmt);
+ printf (" this: \"%s\"\n", this_fmt));
+
+ type = '\0';
+ value = &param.width;
+
+ param.base = 10;
+ param.conv = 0;
+ param.expfmt = "e%c%02ld";
+ param.exptimes4 = 0;
+ param.fill = ' ';
+ param.justify = DOPRNT_JUSTIFY_RIGHT;
+ param.prec = 6;
+ param.showbase = DOPRNT_SHOWBASE_NO;
+ param.showpoint = 0;
+ param.showtrailing = 1;
+ param.sign = '\0';
+ param.width = 0;
+ seen_precision = 0;
+
+ /* This loop parses a single % sequence. "break" from the switch
+ means continue with this %, "goto next" means the conversion
+ character has been seen and a new % should be sought. */
+ for (;;)
+ {
+ fchar = *fmt++;
+ if (fchar == '\0')
+ break;
+
+ switch (fchar) {
+
+ case 'a':
+ /* %a behaves like %e, but defaults to all significant digits,
+ and there's no leading zeros on the exponent (which is in
+ fact bit-based) */
+ param.base = 16;
+ param.expfmt = "p%c%ld";
+ goto conv_a;
+ case 'A':
+ param.base = -16;
+ param.expfmt = "P%c%ld";
+ conv_a:
+ param.conv = DOPRNT_CONV_SCIENTIFIC;
+ param.exptimes4 = 1;
+ if (! seen_precision)
+ param.prec = -1; /* default to all digits */
+ param.showbase = DOPRNT_SHOWBASE_YES;
+ param.showtrailing = 1;
+ goto floating_a;
+
+ case 'c':
+ /* Let's assume wchar_t will be promoted to "int" in the call,
+ the same as char will be. */
+ (void) va_arg (ap, int);
+ goto next;
+
+ case 'd':
+ case 'i':
+ case 'u':
+ integer:
+ TRACE (printf ("integer, base=%d\n", param.base));
+ if (! seen_precision)
+ param.prec = -1;
+ switch (type) {
+ case 'j':
+ /* Let's assume uintmax_t is the same size as intmax_t. */
+#if HAVE_INTMAX_T
+ (void) va_arg (ap, intmax_t);
+#else
+ ASSERT_FAIL (intmax_t not available);
+#endif
+ break;
+ case 'l':
+ (void) va_arg (ap, long);
+ break;
+ case 'L':
+#if HAVE_LONG_LONG
+ (void) va_arg (ap, long long);
+#else
+ ASSERT_FAIL (long long not available);
+#endif
+ break;
+ case 'N':
+ {
+ mp_ptr xp;
+ mp_size_t xsize, abs_xsize;
+ mpz_t z;
+ FLUSH ();
+ xp = va_arg (ap, mp_ptr);
+ PTR(z) = xp;
+ xsize = (int) va_arg (ap, mp_size_t);
+ abs_xsize = ABS (xsize);
+ MPN_NORMALIZE (xp, abs_xsize);
+ SIZ(z) = (xsize >= 0 ? abs_xsize : -abs_xsize);
+ ASSERT_CODE (ALLOC(z) = abs_xsize);
+ gmp_str = mpz_get_str (NULL, param.base, z);
+ goto gmp_integer;
+ }
+ /* break; */
+ case 'q':
+ /* quad_t is probably the same as long long, but let's treat
+ it separately just to be sure. Also let's assume u_quad_t
+ will be the same size as quad_t. */
+#if HAVE_QUAD_T
+ (void) va_arg (ap, quad_t);
+#else
+ ASSERT_FAIL (quad_t not available);
+#endif
+ break;
+ case 'Q':
+ FLUSH ();
+ gmp_str = mpq_get_str (NULL, param.base, va_arg(ap, mpq_srcptr));
+ goto gmp_integer;
+ case 't':
+#if HAVE_PTRDIFF_T
+ (void) va_arg (ap, ptrdiff_t);
+#else
+ ASSERT_FAIL (ptrdiff_t not available);
+#endif
+ break;
+ case 'z':
+ (void) va_arg (ap, size_t);
+ break;
+ case 'Z':
+ {
+ int ret;
+ FLUSH ();
+ gmp_str = mpz_get_str (NULL, param.base,
+ va_arg (ap, mpz_srcptr));
+ gmp_integer:
+ ret = __gmp_doprnt_integer (funs, data, &param, gmp_str);
+ (*__gmp_free_func) (gmp_str, strlen(gmp_str)+1);
+ DOPRNT_ACCUMULATE (ret);
+ va_copy (last_ap, ap);
+ last_fmt = fmt;
+ }
+ break;
+ default:
+ /* default is an "int", and this includes h=short and hh=char
+ since they're promoted to int in a function call */
+ (void) va_arg (ap, int);
+ break;
+ }
+ goto next;
+
+ case 'E':
+ param.base = -10;
+ param.expfmt = "E%c%02ld";
+ /*FALLTHRU*/
+ case 'e':
+ param.conv = DOPRNT_CONV_SCIENTIFIC;
+ floating:
+ if (param.showbase == DOPRNT_SHOWBASE_NONZERO)
+ {
+ /* # in %e, %f and %g */
+ param.showpoint = 1;
+ param.showtrailing = 1;
+ }
+ floating_a:
+ switch (type) {
+ case 'F':
+ FLUSH ();
+ DOPRNT_ACCUMULATE (__gmp_doprnt_mpf (funs, data, &param,
+ GMP_DECIMAL_POINT,
+ va_arg (ap, mpf_srcptr)));
+ va_copy (last_ap, ap);
+ last_fmt = fmt;
+ break;
+ case 'L':
+#if HAVE_LONG_DOUBLE
+ (void) va_arg (ap, long double);
+#else
+ ASSERT_FAIL (long double not available);
+#endif
+ break;
+ default:
+ (void) va_arg (ap, double);
+ break;
+ }
+ goto next;
+
+ case 'f':
+ param.conv = DOPRNT_CONV_FIXED;
+ goto floating;
+
+ case 'F': /* mpf_t */
+ case 'j': /* intmax_t */
+ case 'L': /* long long */
+ case 'N': /* mpn */
+ case 'q': /* quad_t */
+ case 'Q': /* mpq_t */
+ case 't': /* ptrdiff_t */
+ case 'z': /* size_t */
+ case 'Z': /* mpz_t */
+ set_type:
+ type = fchar;
+ break;
+
+ case 'G':
+ param.base = -10;
+ param.expfmt = "E%c%02ld";
+ /*FALLTHRU*/
+ case 'g':
+ param.conv = DOPRNT_CONV_GENERAL;
+ param.showtrailing = 0;
+ goto floating;
+
+ case 'h':
+ if (type != 'h')
+ goto set_type;
+ type = 'H'; /* internal code for "hh" */
+ break;
+
+ case 'l':
+ if (type != 'l')
+ goto set_type;
+ type = 'L'; /* "ll" means "L" */
+ break;
+
+ case 'm':
+ /* glibc strerror(errno), no argument */
+ goto next;
+
+ case 'M': /* mp_limb_t */
+ /* mung format string to l or ll and let plain printf handle it */
+#if _LONG_LONG_LIMB
+ memmove (fmt+1, fmt, strlen (fmt)+1);
+ fmt[-1] = 'l';
+ fmt[0] = 'l';
+ fmt++;
+ type = 'L';
+#else
+ fmt[-1] = 'l';
+ type = 'l';
+#endif
+ break;
+
+ case 'n':
+ {
+ void *p;
+ FLUSH ();
+ p = va_arg (ap, void *);
+ switch (type) {
+ case '\0': * (int *) p = retval; break;
+ case 'F': mpf_set_si ((mpf_ptr) p, (long) retval); break;
+ case 'H': * (char *) p = retval; break;
+ case 'h': * (short *) p = retval; break;
+#if HAVE_INTMAX_T
+ case 'j': * (intmax_t *) p = retval; break;
+#else
+ case 'j': ASSERT_FAIL (intmax_t not available); break;
+#endif
+ case 'l': * (long *) p = retval; break;
+#if HAVE_QUAD_T && HAVE_LONG_LONG
+ case 'q':
+ ASSERT_ALWAYS (sizeof (quad_t) == sizeof (long long));
+ /*FALLTHRU*/
+#else
+ case 'q': ASSERT_FAIL (quad_t not available); break;
+#endif
+#if HAVE_LONG_LONG
+ case 'L': * (long long *) p = retval; break;
+#else
+ case 'L': ASSERT_FAIL (long long not available); break;
+#endif
+ case 'N':
+ {
+ mp_size_t n;
+ n = va_arg (ap, mp_size_t);
+ n = ABS (n);
+ if (n != 0)
+ {
+ * (mp_ptr) p = retval;
+ MPN_ZERO ((mp_ptr) p + 1, n - 1);
+ }
+ }
+ break;
+ case 'Q': mpq_set_si ((mpq_ptr) p, (long) retval, 1L); break;
+#if HAVE_PTRDIFF_T
+ case 't': * (ptrdiff_t *) p = retval; break;
+#else
+ case 't': ASSERT_FAIL (ptrdiff_t not available); break;
+#endif
+ case 'z': * (size_t *) p = retval; break;
+ case 'Z': mpz_set_si ((mpz_ptr) p, (long) retval); break;
+ }
+ }
+ va_copy (last_ap, ap);
+ last_fmt = fmt;
+ goto next;
+
+ case 'o':
+ param.base = 8;
+ goto integer;
+
+ case 'p':
+ case 's':
+ /* "void *" will be good enough for "char *" or "wchar_t *", no
+ need for separate code. */
+ (void) va_arg (ap, const void *);
+ goto next;
+
+ case 'x':
+ param.base = 16;
+ goto integer;
+ case 'X':
+ param.base = -16;
+ goto integer;
+
+ case '%':
+ goto next;
+
+ case '#':
+ param.showbase = DOPRNT_SHOWBASE_NONZERO;
+ break;
+
+ case '\'':
+ /* glibc digit grouping, just pass it through, no support for it
+ on gmp types */
+ break;
+
+ case '+':
+ case ' ':
+ param.sign = fchar;
+ break;
+
+ case '-':
+ param.justify = DOPRNT_JUSTIFY_LEFT;
+ break;
+ case '.':
+ seen_precision = 1;
+ param.prec = -1; /* "." alone means all necessary digits */
+ value = &param.prec;
+ break;
+
+ case '*':
+ {
+ int n = va_arg (ap, int);
+
+ if (value == &param.width)
+ {
+ /* negative width means left justify */
+ if (n < 0)
+ {
+ param.justify = DOPRNT_JUSTIFY_LEFT;
+ n = -n;
+ }
+ param.width = n;
+ }
+ else
+ {
+ /* don't allow negative precision */
+ param.prec = MAX (0, n);
+ }
+ }
+ break;
+
+ case '0':
+ if (value == &param.width)
+ {
+ /* in width field, set fill */
+ param.fill = '0';
+
+ /* for right justify, put the fill after any minus sign */
+ if (param.justify == DOPRNT_JUSTIFY_RIGHT)
+ param.justify = DOPRNT_JUSTIFY_INTERNAL;
+ }
+ else
+ {
+ /* in precision field, set value */
+ *value = 0;
+ }
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ /* process all digits to form a value */
+ {
+ int n = 0;
+ do {
+ n = n * 10 + (fchar-'0');
+ fchar = *fmt++;
+ } while (isascii (fchar) && isdigit (fchar));
+ fmt--; /* unget the non-digit */
+ *value = n;
+ }
+ break;
+
+ default:
+ /* something invalid */
+ ASSERT (0);
+ goto next;
+ }
+ }
+
+ next:
+ /* Stop parsing the current "%" format, look for a new one. */
+ ;
+ }
+
+ TRACE (printf ("remainder: \"%s\"\n", last_fmt));
+ if (*last_fmt != '\0')
+ DOPRNT_FORMAT (last_fmt, last_ap);
+
+ if (funs->final != NULL)
+ if ((*funs->final) (data) == -1)
+ goto error;
+
+ done:
+ (*__gmp_free_func) (alloc_fmt, alloc_fmt_size);
+ return retval;
+
+ error:
+ retval = -1;
+ goto done;
+}
diff --git a/gmp/printf/doprntf.c b/gmp/printf/doprntf.c
new file mode 100644
index 0000000000..c501e8d06b
--- /dev/null
+++ b/gmp/printf/doprntf.c
@@ -0,0 +1,390 @@
+/* __gmp_doprnt_mpf -- mpf formatted output.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001, 2002, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h> /* for va_list and hence doprnt_funs_t */
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* change this to "#define TRACE(x) x" for diagnostics */
+#define TRACE(x)
+
+
+/* The separate of __gmp_doprnt_float_digits and __gmp_doprnt_float is so
+ some C++ can do the mpf_get_str and release it in case of an exception */
+
+#define DIGIT_VALUE(c) \
+ (isdigit (c) ? (c) - '0' \
+ : islower (c) ? (c) - 'a' + 10 \
+ : (c) - 'A' + 10)
+
+int
+__gmp_doprnt_mpf (const struct doprnt_funs_t *funs,
+ void *data,
+ const struct doprnt_params_t *p,
+ const char *point,
+ mpf_srcptr f)
+{
+ int prec, ndigits, free_size, len, newlen, justify, justlen, explen;
+ int showbaselen, sign, signlen, intlen, intzeros, pointlen;
+ int fraczeros, fraclen, preczeros;
+ char *s, *free_ptr;
+ mp_exp_t exp;
+ char exponent[GMP_LIMB_BITS + 10];
+ const char *showbase;
+ int retval = 0;
+
+ TRACE (printf ("__gmp_doprnt_float\n");
+ printf (" conv=%d prec=%d\n", p->conv, p->prec));
+
+ prec = p->prec;
+ if (prec <= -1)
+ {
+ /* all digits */
+ ndigits = 0;
+
+ /* arrange the fixed/scientific decision on a "prec" implied by how
+ many significant digits there are */
+ if (p->conv == DOPRNT_CONV_GENERAL)
+ MPF_SIGNIFICANT_DIGITS (prec, PREC(f), ABS(p->base));
+ }
+ else
+ {
+ switch (p->conv) {
+ case DOPRNT_CONV_FIXED:
+ /* Precision is digits after the radix point. Try not to generate
+ too many more than will actually be required. If f>=1 then
+ overestimate the integer part, and add prec. If f<1 then
+ underestimate the zeros between the radix point and the first
+ digit and subtract that from prec. In either case add 2 so the
+ round to nearest can be applied accurately. Finally, we add 1 to
+ handle the case of 1-eps where EXP(f) = 0 but mpf_get_str returns
+ exp as 1. */
+ ndigits = prec + 2 + 1
+ + EXP(f) * (mp_bases[ABS(p->base)].chars_per_limb + (EXP(f)>=0));
+ ndigits = MAX (ndigits, 1);
+ break;
+
+ case DOPRNT_CONV_SCIENTIFIC:
+ /* precision is digits after the radix point, and there's one digit
+ before */
+ ndigits = prec + 1;
+ break;
+
+ default:
+ ASSERT (0);
+ /*FALLTHRU*/
+
+ case DOPRNT_CONV_GENERAL:
+ /* precision is total digits, but be sure to ask mpf_get_str for at
+ least 1, not 0 */
+ ndigits = MAX (prec, 1);
+ break;
+ }
+ }
+ TRACE (printf (" ndigits %d\n", ndigits));
+
+ s = mpf_get_str (NULL, &exp, p->base, ndigits, f);
+ len = strlen (s);
+ free_ptr = s;
+ free_size = len + 1;
+ TRACE (printf (" s %s\n", s);
+ printf (" exp %ld\n", exp);
+ printf (" len %d\n", len));
+
+ /* For fixed mode check the ndigits formed above was in fact enough for
+ the integer part plus p->prec after the radix point. */
+ ASSERT ((p->conv == DOPRNT_CONV_FIXED && p->prec > -1)
+ ? ndigits >= MAX (1, exp + p->prec + 2) : 1);
+
+ sign = p->sign;
+ if (s[0] == '-')
+ {
+ sign = s[0];
+ s++, len--;
+ }
+ signlen = (sign != '\0');
+ TRACE (printf (" sign %c signlen %d\n", sign, signlen));
+
+ switch (p->conv) {
+ case DOPRNT_CONV_FIXED:
+ if (prec <= -1)
+ prec = MAX (0, len-exp); /* retain all digits */
+
+ /* Truncate if necessary so fraction will be at most prec digits. */
+ ASSERT (prec >= 0);
+ newlen = exp + prec;
+ if (newlen < 0)
+ {
+ /* first non-zero digit is below target prec, and at least one zero
+ digit in between, so print zero */
+ len = 0;
+ exp = 0;
+ }
+ else if (len <= newlen)
+ {
+ /* already got few enough digits */
+ }
+ else
+ {
+ /* discard excess digits and round to nearest */
+
+ const char *num_to_text = (p->base >= 0
+ ? "0123456789abcdefghijklmnopqrstuvwxyz"
+ : "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ int base = ABS(p->base);
+ int n;
+
+ ASSERT (base <= 36);
+
+ len = newlen;
+ n = DIGIT_VALUE (s[len]);
+ TRACE (printf (" rounding with %d\n", n));
+ if (n >= (base + 1) / 2)
+ {
+ /* propagate a carry */
+ for (;;)
+ {
+ if (len == 0)
+ {
+ s[0] = '1';
+ len = 1;
+ exp++;
+ break;
+ }
+ n = DIGIT_VALUE (s[len-1]);
+ ASSERT (n >= 0 && n < base);
+ n++;
+ if (n != base)
+ {
+ TRACE (printf (" storing now %d\n", n));
+ s[len-1] = num_to_text[n];
+ break;
+ }
+ len--;
+ }
+ }
+ else
+ {
+ /* truncate only, strip any trailing zeros now exposed */
+ while (len > 0 && s[len-1] == '0')
+ len--;
+ }
+
+ /* Can have newlen==0, in which case the truncate was just to check
+ for a carry turning it into "1". If we're left with len==0 then
+ adjust exp to match. */
+ if (len == 0)
+ exp = 0;
+ }
+
+ fixed:
+ ASSERT (len == 0 ? exp == 0 : 1);
+ if (exp <= 0)
+ {
+ TRACE (printf (" fixed 0.000sss\n"));
+ intlen = 0;
+ intzeros = 1;
+ fraczeros = -exp;
+ fraclen = len;
+ }
+ else
+ {
+ TRACE (printf (" fixed sss.sss or sss000\n"));
+ intlen = MIN (len, exp);
+ intzeros = exp - intlen;
+ fraczeros = 0;
+ fraclen = len - intlen;
+ }
+ explen = 0;
+ break;
+
+ case DOPRNT_CONV_SCIENTIFIC:
+ {
+ long int expval;
+ char expsign;
+
+ if (prec <= -1)
+ prec = MAX (0, len-1); /* retain all digits */
+
+ scientific:
+ TRACE (printf (" scientific s.sss\n"));
+
+ intlen = MIN (1, len);
+ intzeros = (intlen == 0 ? 1 : 0);
+ fraczeros = 0;
+ fraclen = len - intlen;
+
+ expval = (exp-intlen);
+ if (p->exptimes4)
+ expval <<= 2;
+
+ /* Split out the sign since %o or %x in expfmt give negatives as twos
+ complement, not with a sign. */
+ expsign = (expval >= 0 ? '+' : '-');
+ expval = ABS (expval);
+
+#if HAVE_VSNPRINTF
+ explen = snprintf (exponent, sizeof(exponent),
+ p->expfmt, expsign, expval);
+ /* test for < sizeof-1 since a glibc 2.0.x return of sizeof-1 might
+ mean truncation */
+ ASSERT (explen >= 0 && explen < sizeof(exponent)-1);
+#else
+ sprintf (exponent, p->expfmt, expsign, expval);
+ explen = strlen (exponent);
+ ASSERT (explen < sizeof(exponent));
+#endif
+ TRACE (printf (" expfmt %s gives %s\n", p->expfmt, exponent));
+ }
+ break;
+
+ default:
+ ASSERT (0);
+ /*FALLTHRU*/ /* to stop variables looking uninitialized */
+
+ case DOPRNT_CONV_GENERAL:
+ /* The exponent for "scientific" will be exp-1, choose scientific if
+ this is < -4 or >= prec (and minimum 1 for prec). For f==0 will have
+ exp==0 and get the desired "fixed". This rule follows glibc. For
+ fixed there's no need to truncate, the desired ndigits will already
+ be as required. */
+ if (exp-1 < -4 || exp-1 >= MAX (1, prec))
+ goto scientific;
+ else
+ goto fixed;
+ }
+
+ TRACE (printf (" intlen %d intzeros %d fraczeros %d fraclen %d\n",
+ intlen, intzeros, fraczeros, fraclen));
+ ASSERT (p->prec <= -1
+ ? intlen + fraclen == strlen (s)
+ : intlen + fraclen <= strlen (s));
+
+ if (p->showtrailing)
+ {
+ /* Pad to requested precision with trailing zeros, for general this is
+ all digits, for fixed and scientific just the fraction. */
+ preczeros = prec - (fraczeros + fraclen
+ + (p->conv == DOPRNT_CONV_GENERAL
+ ? intlen + intzeros : 0));
+ preczeros = MAX (0, preczeros);
+ }
+ else
+ preczeros = 0;
+ TRACE (printf (" prec=%d showtrailing=%d, pad with preczeros %d\n",
+ prec, p->showtrailing, preczeros));
+
+ /* radix point if needed, or if forced */
+ pointlen = ((fraczeros + fraclen + preczeros) != 0 || p->showpoint != 0)
+ ? strlen (point) : 0;
+ TRACE (printf (" point |%s| pointlen %d\n", point, pointlen));
+
+ /* Notice the test for a non-zero value is done after any truncation for
+ DOPRNT_CONV_FIXED. */
+ showbase = NULL;
+ showbaselen = 0;
+ switch (p->showbase) {
+ default:
+ ASSERT (0);
+ /*FALLTHRU*/
+ case DOPRNT_SHOWBASE_NO:
+ break;
+ case DOPRNT_SHOWBASE_NONZERO:
+ if (intlen == 0 && fraclen == 0)
+ break;
+ /*FALLTHRU*/
+ case DOPRNT_SHOWBASE_YES:
+ switch (p->base) {
+ case 16: showbase = "0x"; showbaselen = 2; break;
+ case -16: showbase = "0X"; showbaselen = 2; break;
+ case 8: showbase = "0"; showbaselen = 1; break;
+ }
+ break;
+ }
+ TRACE (printf (" showbase %s showbaselen %d\n",
+ showbase == NULL ? "" : showbase, showbaselen));
+
+ /* left over field width */
+ justlen = p->width - (signlen + showbaselen + intlen + intzeros + pointlen
+ + fraczeros + fraclen + preczeros + explen);
+ TRACE (printf (" justlen %d fill 0x%X\n", justlen, p->fill));
+
+ justify = p->justify;
+ if (justlen <= 0) /* no justifying if exceed width */
+ justify = DOPRNT_JUSTIFY_NONE;
+
+ TRACE (printf (" justify type %d intlen %d pointlen %d fraclen %d\n",
+ justify, intlen, pointlen, fraclen));
+
+ if (justify == DOPRNT_JUSTIFY_RIGHT) /* pad for right */
+ DOPRNT_REPS (p->fill, justlen);
+
+ if (signlen) /* sign */
+ DOPRNT_REPS (sign, 1);
+
+ DOPRNT_MEMORY_MAYBE (showbase, showbaselen); /* base */
+
+ if (justify == DOPRNT_JUSTIFY_INTERNAL) /* pad for internal */
+ DOPRNT_REPS (p->fill, justlen);
+
+ DOPRNT_MEMORY (s, intlen); /* integer */
+ DOPRNT_REPS_MAYBE ('0', intzeros);
+
+ DOPRNT_MEMORY_MAYBE (point, pointlen); /* point */
+
+ DOPRNT_REPS_MAYBE ('0', fraczeros); /* frac */
+ DOPRNT_MEMORY_MAYBE (s+intlen, fraclen);
+
+ DOPRNT_REPS_MAYBE ('0', preczeros); /* prec */
+
+ DOPRNT_MEMORY_MAYBE (exponent, explen); /* exp */
+
+ if (justify == DOPRNT_JUSTIFY_LEFT) /* pad for left */
+ DOPRNT_REPS (p->fill, justlen);
+
+ done:
+ (*__gmp_free_func) (free_ptr, free_size);
+ return retval;
+
+ error:
+ retval = -1;
+ goto done;
+}
diff --git a/gmp/printf/doprnti.c b/gmp/printf/doprnti.c
new file mode 100644
index 0000000000..c4cb9c8da8
--- /dev/null
+++ b/gmp/printf/doprnti.c
@@ -0,0 +1,137 @@
+/* __gmp_doprnt_integer -- integer style formatted output.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h> /* for va_list and hence doprnt_funs_t */
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+__gmp_doprnt_integer (const struct doprnt_funs_t *funs,
+ void *data,
+ const struct doprnt_params_t *p,
+ const char *s)
+{
+ int retval = 0;
+ int slen, justlen, showbaselen, sign, signlen, slashlen, zeros;
+ int justify, den_showbaselen;
+ const char *slash, *showbase;
+
+ /* '+' or ' ' if wanted, and don't already have '-' */
+ sign = p->sign;
+ if (s[0] == '-')
+ {
+ sign = s[0];
+ s++;
+ }
+ signlen = (sign != '\0');
+
+ /* if the precision was explicitly 0, print nothing for a 0 value */
+ if (*s == '0' && p->prec == 0)
+ s++;
+
+ slen = strlen (s);
+ slash = strchr (s, '/');
+
+ showbase = NULL;
+ showbaselen = 0;
+
+ if (p->showbase != DOPRNT_SHOWBASE_NO)
+ {
+ switch (p->base) {
+ case 16: showbase = "0x"; showbaselen = 2; break;
+ case -16: showbase = "0X"; showbaselen = 2; break;
+ case 8: showbase = "0"; showbaselen = 1; break;
+ }
+ }
+
+ den_showbaselen = showbaselen;
+ if (slash == NULL
+ || (p->showbase == DOPRNT_SHOWBASE_NONZERO && slash[1] == '0'))
+ den_showbaselen = 0;
+
+ if (p->showbase == DOPRNT_SHOWBASE_NONZERO && s[0] == '0')
+ showbaselen = 0;
+
+ /* the influence of p->prec on mpq is currently undefined */
+ zeros = MAX (0, p->prec - slen);
+
+ /* space left over after actual output length */
+ justlen = p->width
+ - (strlen(s) + signlen + showbaselen + den_showbaselen + zeros);
+
+ justify = p->justify;
+ if (justlen <= 0) /* no justifying if exceed width */
+ justify = DOPRNT_JUSTIFY_NONE;
+
+ if (justify == DOPRNT_JUSTIFY_RIGHT) /* pad right */
+ DOPRNT_REPS (p->fill, justlen);
+
+ DOPRNT_REPS_MAYBE (sign, signlen); /* sign */
+
+ DOPRNT_MEMORY_MAYBE (showbase, showbaselen); /* base */
+
+ DOPRNT_REPS_MAYBE ('0', zeros); /* zeros */
+
+ if (justify == DOPRNT_JUSTIFY_INTERNAL) /* pad internal */
+ DOPRNT_REPS (p->fill, justlen);
+
+ /* if there's a showbase on the denominator, then print the numerator
+ separately so it can be inserted */
+ if (den_showbaselen != 0)
+ {
+ ASSERT (slash != NULL);
+ slashlen = slash+1 - s;
+ DOPRNT_MEMORY (s, slashlen); /* numerator and slash */
+ slen -= slashlen;
+ s += slashlen;
+ DOPRNT_MEMORY (showbase, den_showbaselen);
+ }
+
+ DOPRNT_MEMORY (s, slen); /* number, or denominator */
+
+ if (justify == DOPRNT_JUSTIFY_LEFT) /* pad left */
+ DOPRNT_REPS (p->fill, justlen);
+
+ done:
+ return retval;
+
+ error:
+ retval = -1;
+ goto done;
+}
diff --git a/gmp/printf/fprintf.c b/gmp/printf/fprintf.c
new file mode 100644
index 0000000000..2d8187d7cf
--- /dev/null
+++ b/gmp/printf/fprintf.c
@@ -0,0 +1,49 @@
+/* gmp_fprintf -- formatted output.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_fprintf (FILE *fp, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start (ap, fmt);
+
+ ret = __gmp_doprnt (&__gmp_fprintf_funs, fp, fmt, ap);
+ va_end (ap);
+ return ret;
+}
diff --git a/gmp/printf/obprintf.c b/gmp/printf/obprintf.c
new file mode 100644
index 0000000000..fbf3ea768f
--- /dev/null
+++ b/gmp/printf/obprintf.c
@@ -0,0 +1,59 @@
+/* gmp_obstack_printf -- formatted output to an obstack.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if HAVE_OBSTACK_VPRINTF
+
+#include <stdarg.h>
+#include <obstack.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_obstack_printf (struct obstack *ob, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start (ap, fmt);
+
+ ASSERT (! MEM_OVERLAP_P (obstack_base(ob), obstack_object_size(ob),
+ fmt, strlen(fmt)+1));
+
+ ret = __gmp_doprnt (&__gmp_obstack_printf_funs, ob, fmt, ap);
+ va_end (ap);
+ return ret;
+}
+
+#endif /* HAVE_OBSTACK_VPRINTF */
diff --git a/gmp/printf/obprntffuns.c b/gmp/printf/obprntffuns.c
new file mode 100644
index 0000000000..4cd1a91dec
--- /dev/null
+++ b/gmp/printf/obprntffuns.c
@@ -0,0 +1,72 @@
+/* __gmp_obstack_printf_funs -- support for gmp_obstack_printf and
+ gmp_obstack_vprintf.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if HAVE_OBSTACK_VPRINTF
+
+#define _GNU_SOURCE /* ask glibc <stdio.h> for obstack_vprintf */
+
+#include <stdarg.h>
+#include <stdio.h> /* for obstack_vprintf */
+#include <string.h>
+#include <obstack.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+static int
+gmp_obstack_memory (struct obstack *ob, const char *ptr, size_t len)
+{
+ obstack_grow (ob, ptr, len);
+ return len;
+}
+
+static int
+gmp_obstack_reps (struct obstack *ob, int c, int reps)
+{
+ obstack_blank (ob, reps);
+ memset ((char *) obstack_next_free(ob) - reps, c, reps);
+ return reps;
+}
+
+const struct doprnt_funs_t __gmp_obstack_printf_funs = {
+ (doprnt_format_t) obstack_vprintf,
+ (doprnt_memory_t) gmp_obstack_memory,
+ (doprnt_reps_t) gmp_obstack_reps
+};
+
+#endif /* HAVE_OBSTACK_VPRINTF */
diff --git a/gmp/printf/obvprintf.c b/gmp/printf/obvprintf.c
new file mode 100644
index 0000000000..31eddbdf2a
--- /dev/null
+++ b/gmp/printf/obvprintf.c
@@ -0,0 +1,52 @@
+/* gmp_obstack_vprintf -- formatted output to an obstack.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if HAVE_OBSTACK_VPRINTF
+
+#include <stdarg.h>
+#include <obstack.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_obstack_vprintf (struct obstack *ob, const char *fmt, va_list ap)
+{
+ ASSERT (! MEM_OVERLAP_P (obstack_base(ob), obstack_object_size(ob),
+ fmt, strlen(fmt)+1));
+
+ return __gmp_doprnt (&__gmp_obstack_printf_funs, ob, fmt, ap);
+}
+
+#endif /* HAVE_OBSTACK_VPRINTF */
diff --git a/gmp/printf/printf.c b/gmp/printf/printf.c
new file mode 100644
index 0000000000..7ac7b62fae
--- /dev/null
+++ b/gmp/printf/printf.c
@@ -0,0 +1,49 @@
+/* gmp_printf -- formatted output.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_printf (const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start (ap, fmt);
+
+ ret = __gmp_doprnt (&__gmp_fprintf_funs, stdout, fmt, ap);
+ va_end (ap);
+ return ret;
+}
diff --git a/gmp/printf/printffuns.c b/gmp/printf/printffuns.c
new file mode 100644
index 0000000000..058c6b9d8b
--- /dev/null
+++ b/gmp/printf/printffuns.c
@@ -0,0 +1,80 @@
+/* __gmp_fprintf_funs -- support for formatted output to FILEs.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* SunOS 4 stdio.h doesn't provide a prototype for this */
+#if ! HAVE_DECL_VFPRINTF
+int vfprintf (FILE *, const char *, va_list);
+#endif
+
+
+static int
+gmp_fprintf_memory (FILE *fp, const char *str, size_t len)
+{
+ return fwrite (str, 1, len, fp);
+}
+
+/* glibc putc is a function, at least when it's in multi-threaded mode or
+ some such, so fwrite chunks instead of making many calls. */
+static int
+gmp_fprintf_reps (FILE *fp, int c, int reps)
+{
+ char buf[256];
+ int i, piece, ret;
+ ASSERT (reps >= 0);
+
+ memset (buf, c, MIN (reps, sizeof (buf)));
+ for (i = reps; i > 0; i -= sizeof (buf))
+ {
+ piece = MIN (i, sizeof (buf));
+ ret = fwrite (buf, 1, piece, fp);
+ if (ret == -1)
+ return ret;
+ ASSERT (ret == piece);
+ }
+
+ return reps;
+}
+
+const struct doprnt_funs_t __gmp_fprintf_funs = {
+ (doprnt_format_t) vfprintf,
+ (doprnt_memory_t) gmp_fprintf_memory,
+ (doprnt_reps_t) gmp_fprintf_reps,
+};
diff --git a/gmp/printf/repl-vsnprintf.c b/gmp/printf/repl-vsnprintf.c
new file mode 100644
index 0000000000..a95003baa6
--- /dev/null
+++ b/gmp/printf/repl-vsnprintf.c
@@ -0,0 +1,396 @@
+/* __gmp_replacement_vsnprintf -- for systems which don't have vsnprintf, or
+ only have a broken one.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#if ! HAVE_VSNPRINTF /* only need this file if we don't have vsnprintf */
+
+
+#define _GNU_SOURCE /* for strnlen prototype */
+
+#include <stdarg.h>
+#include <ctype.h> /* for isdigit */
+#include <stddef.h> /* for ptrdiff_t */
+#include <string.h>
+#include <stdio.h> /* for NULL */
+#include <stdlib.h>
+
+#if HAVE_FLOAT_H
+#include <float.h> /* for DBL_MAX_10_EXP etc */
+#endif
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h> /* for intmax_t */
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h> /* for quad_t */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Autoconf notes that AIX 4.3 has a broken strnlen, but fortunately it
+ doesn't affect us since __gmp_replacement_vsnprintf is not required on
+ that system. */
+#if ! HAVE_STRNLEN
+static size_t
+strnlen (const char *s, size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++)
+ if (s[i] == '\0')
+ break;
+ return i;
+}
+#endif
+
+
+/* The approach here is to parse the fmt string, and decide how much space
+ it requires, then use vsprintf into a big enough buffer. The space
+ calculated isn't an exact amount, but it's certainly no less than
+ required.
+
+ This code was inspired by GNU libiberty/vasprintf.c but we support more
+ datatypes, when available.
+
+ mingw32 - doesn't have vsnprintf, it seems. Because gcc is used a full
+ set of types are available, but "long double" is just a plain IEEE
+ 64-bit "double" and LDBL_MAX_EXP_10 is correspondingly defined, so we
+ avoid the big 15-bit exponent estimate. */
+
+int
+__gmp_replacement_vsnprintf (char *buf, size_t buf_size,
+ const char *orig_fmt, va_list orig_ap)
+{
+ va_list ap;
+ const char *fmt;
+ size_t total_width, integer_sizeof, floating_sizeof, len;
+ char fchar, type;
+ int width, prec, seen_prec, double_digits, long_double_digits;
+ int *value;
+
+ /* preserve orig_ap for use after size estimation */
+ va_copy (ap, orig_ap);
+
+ fmt = orig_fmt;
+ total_width = strlen (fmt) + 1; /* 1 extra for the '\0' */
+
+ integer_sizeof = sizeof (long);
+#if HAVE_LONG_LONG
+ integer_sizeof = MAX (integer_sizeof, sizeof (long long));
+#endif
+#if HAVE_QUAD_T
+ integer_sizeof = MAX (integer_sizeof, sizeof (quad_t));
+#endif
+
+ floating_sizeof = sizeof (double);
+#if HAVE_LONG_DOUBLE
+ floating_sizeof = MAX (floating_sizeof, sizeof (long double));
+#endif
+
+ /* IEEE double or VAX G floats have an 11 bit exponent, so the default is
+ a maximum 308 decimal digits. VAX D floats have only an 8 bit
+ exponent, but we don't bother trying to detect that directly. */
+ double_digits = 308;
+#ifdef DBL_MAX_10_EXP
+ /* but in any case prefer a value the compiler says */
+ double_digits = DBL_MAX_10_EXP;
+#endif
+
+ /* IEEE 128-bit quad, Intel 80-bit temporary, or VAX H floats all have 15
+ bit exponents, so the default is a maximum 4932 decimal digits. */
+ long_double_digits = 4932;
+ /* but if double == long double, then go with that size */
+#if HAVE_LONG_DOUBLE
+ if (sizeof (double) == sizeof (long double))
+ long_double_digits = double_digits;
+#endif
+#ifdef LDBL_MAX_10_EXP
+ /* but in any case prefer a value the compiler says */
+ long_double_digits = LDBL_MAX_10_EXP;
+#endif
+
+ for (;;)
+ {
+ fmt = strchr (fmt, '%');
+ if (fmt == NULL)
+ break;
+ fmt++;
+
+ type = '\0';
+ width = 0;
+ prec = 6;
+ seen_prec = 0;
+ value = &width;
+
+ for (;;)
+ {
+ fchar = *fmt++;
+ switch (fchar) {
+
+ case 'c':
+ /* char, already accounted for by strlen(fmt) */
+ goto next;
+
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'x':
+ case 'X':
+ case 'u':
+ /* at most 3 digits per byte in hex, dec or octal, plus a sign */
+ total_width += 3 * integer_sizeof + 1;
+
+ switch (type) {
+ case 'j':
+ /* Let's assume uintmax_t is the same size as intmax_t. */
+#if HAVE_INTMAX_T
+ (void) va_arg (ap, intmax_t);
+#else
+ ASSERT_FAIL (intmax_t not available);
+#endif
+ break;
+ case 'l':
+ (void) va_arg (ap, long);
+ break;
+ case 'L':
+#if HAVE_LONG_LONG
+ (void) va_arg (ap, long long);
+#else
+ ASSERT_FAIL (long long not available);
+#endif
+ break;
+ case 'q':
+ /* quad_t is probably the same as long long, but let's treat
+ it separately just to be sure. Also let's assume u_quad_t
+ will be the same size as quad_t. */
+#if HAVE_QUAD_T
+ (void) va_arg (ap, quad_t);
+#else
+ ASSERT_FAIL (quad_t not available);
+#endif
+ break;
+ case 't':
+#if HAVE_PTRDIFF_T
+ (void) va_arg (ap, ptrdiff_t);
+#else
+ ASSERT_FAIL (ptrdiff_t not available);
+#endif
+ break;
+ case 'z':
+ (void) va_arg (ap, size_t);
+ break;
+ default:
+ /* default is an "int", and this includes h=short and hh=char
+ since they're promoted to int in a function call */
+ (void) va_arg (ap, int);
+ break;
+ }
+ goto next;
+
+ case 'E':
+ case 'e':
+ case 'G':
+ case 'g':
+ /* Requested decimals, sign, point and e, plus an overestimate
+ of exponent digits (the assumption is all the float is
+ exponent!). */
+ total_width += prec + 3 + floating_sizeof * 3;
+ if (type == 'L')
+ {
+#if HAVE_LONG_DOUBLE
+ (void) va_arg (ap, long double);
+#else
+ ASSERT_FAIL (long double not available);
+#endif
+ }
+ else
+ (void) va_arg (ap, double);
+ break;
+
+ case 'f':
+ /* Requested decimals, sign and point, and a margin for error,
+ then add the maximum digits that can be in the integer part,
+ based on the maximum exponent value. */
+ total_width += prec + 2 + 10;
+ if (type == 'L')
+ {
+#if HAVE_LONG_DOUBLE
+ (void) va_arg (ap, long double);
+ total_width += long_double_digits;
+#else
+ ASSERT_FAIL (long double not available);
+#endif
+ }
+ else
+ {
+ (void) va_arg (ap, double);
+ total_width += double_digits;
+ }
+ break;
+
+ case 'h': /* short or char */
+ case 'j': /* intmax_t */
+ case 'L': /* long long or long double */
+ case 'q': /* quad_t */
+ case 't': /* ptrdiff_t */
+ case 'z': /* size_t */
+ set_type:
+ type = fchar;
+ break;
+
+ case 'l':
+ /* long or long long */
+ if (type != 'l')
+ goto set_type;
+ type = 'L'; /* "ll" means "L" */
+ break;
+
+ case 'n':
+ /* bytes written, no output as such */
+ (void) va_arg (ap, void *);
+ goto next;
+
+ case 's':
+ /* If no precision was given, then determine the string length
+ and put it there, to be added to the total under "next". If
+ a precision was given then that's already the maximum from
+ this field, but see whether the string is shorter than that,
+ in case the limit was very big. */
+ {
+ const char *s = va_arg (ap, const char *);
+ prec = (seen_prec ? strnlen (s, prec) : strlen (s));
+ }
+ goto next;
+
+ case 'p':
+ /* pointer, let's assume at worst it's octal with some padding */
+ (void) va_arg (ap, const void *);
+ total_width += 3 * sizeof (void *) + 16;
+ goto next;
+
+ case '%':
+ /* literal %, already accounted for by strlen(fmt) */
+ goto next;
+
+ case '#':
+ /* showbase, at most 2 for "0x" */
+ total_width += 2;
+ break;
+
+ case '+':
+ case ' ':
+ /* sign, already accounted for under numerics */
+ break;
+
+ case '-':
+ /* left justify, no effect on total width */
+ break;
+
+ case '.':
+ seen_prec = 1;
+ value = &prec;
+ break;
+
+ case '*':
+ {
+ /* negative width means left justify which can be ignored,
+ negative prec would be invalid, just use absolute value */
+ int n = va_arg (ap, int);
+ *value = ABS (n);
+ }
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ /* process all digits to form a value */
+ {
+ int n = 0;
+ do {
+ n = n * 10 + (fchar-'0');
+ fchar = *fmt++;
+ } while (isascii (fchar) && isdigit (fchar));
+ fmt--; /* unget the non-digit */
+ *value = n;
+ }
+ break;
+
+ default:
+ /* incomplete or invalid % sequence */
+ ASSERT (0);
+ goto next;
+ }
+ }
+
+ next:
+ total_width += width;
+ total_width += prec;
+ }
+
+ if (total_width <= buf_size)
+ {
+ vsprintf (buf, orig_fmt, orig_ap);
+ len = strlen (buf);
+ }
+ else
+ {
+ char *s;
+
+ s = __GMP_ALLOCATE_FUNC_TYPE (total_width, char);
+ vsprintf (s, orig_fmt, orig_ap);
+ len = strlen (s);
+ if (buf_size != 0)
+ {
+ size_t copylen = MIN (len, buf_size-1);
+ memcpy (buf, s, copylen);
+ buf[copylen] = '\0';
+ }
+ (*__gmp_free_func) (s, total_width);
+ }
+
+ /* If total_width was somehow wrong then chances are we've already
+ clobbered memory, but maybe this check will still work. */
+ ASSERT_ALWAYS (len < total_width);
+
+ return len;
+}
+
+#endif /* ! HAVE_VSNPRINTF */
diff --git a/gmp/printf/snprintf.c b/gmp/printf/snprintf.c
new file mode 100644
index 0000000000..fde5c806eb
--- /dev/null
+++ b/gmp/printf/snprintf.c
@@ -0,0 +1,54 @@
+/* gmp_snprintf -- formatted output to an fixed size buffer.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <string.h> /* for strlen */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_snprintf (char *buf, size_t size, const char *fmt, ...)
+{
+ struct gmp_snprintf_t d;
+ va_list ap;
+ int ret;
+
+ va_start (ap, fmt);
+ d.buf = buf;
+ d.size = size;
+
+ ASSERT (! MEM_OVERLAP_P (buf, size, fmt, strlen(fmt)+1));
+
+ ret = __gmp_doprnt (&__gmp_snprintf_funs, &d, fmt, ap);
+ va_end (ap);
+ return ret;
+}
diff --git a/gmp/printf/snprntffuns.c b/gmp/printf/snprntffuns.c
new file mode 100644
index 0000000000..41a7670c6d
--- /dev/null
+++ b/gmp/printf/snprntffuns.c
@@ -0,0 +1,160 @@
+/* __gmp_snprintf_funs -- support for gmp_snprintf and gmp_vsnprintf.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#if ! HAVE_VSNPRINTF
+#define vsnprintf __gmp_replacement_vsnprintf
+#endif
+
+
+/* glibc 2.0.x vsnprintf returns either -1 or size-1 for an overflow, with
+ no indication how big the output would have been. It's necessary to
+ re-run to determine that size.
+
+ "size-1" would mean success from a C99 vsnprintf, and the re-run is
+ unnecessary in this case, but we don't bother to try to detect what sort
+ of vsnprintf we've got. size-1 should occur rarely in normal
+ circumstances.
+
+ vsnprintf might trash it's given ap (it does for instance in glibc 2.1.3
+ on powerpc), so copy it in case we need to use it to probe for the size
+ output that would have been produced. Note there's no need to preserve
+ it for our callers, just for ourselves. */
+
+static int
+gmp_snprintf_format (struct gmp_snprintf_t *d, const char *fmt,
+ va_list orig_ap)
+{
+ int ret, step, alloc, avail;
+ va_list ap;
+ char *p;
+
+ ASSERT (d->size >= 0);
+
+ avail = d->size;
+ if (avail > 1)
+ {
+ va_copy (ap, orig_ap);
+ ret = vsnprintf (d->buf, avail, fmt, ap);
+ if (ret == -1)
+ {
+ ASSERT (strlen (d->buf) == avail-1);
+ ret = avail-1;
+ }
+
+ step = MIN (ret, avail-1);
+ d->size -= step;
+ d->buf += step;
+
+ if (ret != avail-1)
+ return ret;
+
+ /* probably glibc 2.0.x truncated output, probe for actual size */
+ alloc = MAX (128, ret);
+ }
+ else
+ {
+ /* no space to write anything, just probe for size */
+ alloc = 128;
+ }
+
+ do
+ {
+ alloc *= 2;
+ p = __GMP_ALLOCATE_FUNC_TYPE (alloc, char);
+ va_copy (ap, orig_ap);
+ ret = vsnprintf (p, alloc, fmt, ap);
+ (*__gmp_free_func) (p, alloc);
+ }
+ while (ret == alloc-1 || ret == -1);
+
+ return ret;
+}
+
+static int
+gmp_snprintf_memory (struct gmp_snprintf_t *d, const char *str, size_t len)
+{
+ size_t n;
+
+ ASSERT (d->size >= 0);
+
+ if (d->size > 1)
+ {
+ n = MIN (d->size-1, len);
+ memcpy (d->buf, str, n);
+ d->buf += n;
+ d->size -= n;
+ }
+ return len;
+}
+
+static int
+gmp_snprintf_reps (struct gmp_snprintf_t *d, int c, int reps)
+{
+ size_t n;
+
+ ASSERT (reps >= 0);
+ ASSERT (d->size >= 0);
+
+ if (d->size > 1)
+ {
+ n = MIN (d->size-1, reps);
+ memset (d->buf, c, n);
+ d->buf += n;
+ d->size -= n;
+ }
+ return reps;
+}
+
+static int
+gmp_snprintf_final (struct gmp_snprintf_t *d)
+{
+ if (d->size >= 1)
+ d->buf[0] = '\0';
+ return 0;
+}
+
+const struct doprnt_funs_t __gmp_snprintf_funs = {
+ (doprnt_format_t) gmp_snprintf_format,
+ (doprnt_memory_t) gmp_snprintf_memory,
+ (doprnt_reps_t) gmp_snprintf_reps,
+ (doprnt_final_t) gmp_snprintf_final
+};
diff --git a/gmp/printf/sprintf.c b/gmp/printf/sprintf.c
new file mode 100644
index 0000000000..052a2655c9
--- /dev/null
+++ b/gmp/printf/sprintf.c
@@ -0,0 +1,55 @@
+/* gmp_sprintf -- formatted output to an unrestricted string.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <string.h> /* for strlen */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_sprintf (char *buf, const char *fmt, ...)
+{
+#if WANT_ASSERT
+ int fmtlen = strlen(fmt);
+#endif
+ va_list ap;
+ int ret;
+
+ va_start (ap, fmt);
+
+ ret = __gmp_doprnt (&__gmp_sprintf_funs, &buf, fmt, ap);
+ va_end (ap);
+
+ ASSERT (! MEM_OVERLAP_P (buf, strlen(buf)+1, fmt, fmtlen+1));
+
+ return ret;
+}
diff --git a/gmp/printf/sprintffuns.c b/gmp/printf/sprintffuns.c
new file mode 100644
index 0000000000..40374e1a07
--- /dev/null
+++ b/gmp/printf/sprintffuns.c
@@ -0,0 +1,95 @@
+/* __gmp_sprintf_funs -- support for gmp_sprintf and gmp_vsprintf.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* The data parameter "bufp" points to a "char *buf" which is the next
+ character to be written, having started as the destination from the
+ application. This is then increased each time output is produced. */
+
+
+/* If vsprintf returns -1 then pass it upwards. It doesn't matter that
+ "*bufp" is ruined in this case, since gmp_doprint will bail out
+ immediately anyway. */
+static int
+gmp_sprintf_format (char **bufp, const char *fmt, va_list ap)
+{
+ char *buf = *bufp;
+ int ret;
+ vsprintf (buf, fmt, ap);
+ ret = strlen (buf);
+ *bufp = buf + ret;
+ return ret;
+}
+
+static int
+gmp_sprintf_memory (char **bufp, const char *str, size_t len)
+{
+ char *buf = *bufp;
+ *bufp = buf + len;
+ memcpy (buf, str, len);
+ return len;
+}
+
+static int
+gmp_sprintf_reps (char **bufp, int c, int reps)
+{
+ char *buf = *bufp;
+ ASSERT (reps >= 0);
+ *bufp = buf + reps;
+ memset (buf, c, reps);
+ return reps;
+}
+
+static int
+gmp_sprintf_final (char **bufp, int c, int reps)
+{
+ char *buf = *bufp;
+ *buf = '\0';
+ return 0;
+}
+
+const struct doprnt_funs_t __gmp_sprintf_funs = {
+ (doprnt_format_t) gmp_sprintf_format,
+ (doprnt_memory_t) gmp_sprintf_memory,
+ (doprnt_reps_t) gmp_sprintf_reps,
+ (doprnt_final_t) gmp_sprintf_final
+};
diff --git a/gmp/printf/vasprintf.c b/gmp/printf/vasprintf.c
new file mode 100644
index 0000000000..44785dae2a
--- /dev/null
+++ b/gmp/printf/vasprintf.c
@@ -0,0 +1,117 @@
+/* gmp_vasprintf -- formatted output to an allocated space.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if ! HAVE_VSNPRINTF
+#define vsnprintf __gmp_replacement_vsnprintf
+#endif
+
+
+/* vasprintf isn't used since we prefer all GMP allocs to go through
+ __gmp_allocate_func, and in particular we don't want the -1 return from
+ vasprintf for out-of-memory, instead __gmp_allocate_func should handle
+ that. Using vsnprintf unfortunately means we might have to re-run it if
+ our current space is insufficient.
+
+ The initial guess for the needed space is an arbitrary 256 bytes. If
+ that (and any extra GMP_ASPRINTF_T_NEED might give) isn't enough then an
+ ISO C99 standard vsnprintf will tell us what we really need.
+
+ GLIBC 2.0.x vsnprintf returns either -1 or space-1 to indicate overflow,
+ without giving any indication how much is really needed. In this case
+ keep trying with double the space each time.
+
+ A return of space-1 is success on a C99 vsnprintf, but we're not
+ bothering to identify which style vsnprintf we've got, so just take the
+ pessimistic option and assume it's glibc 2.0.x.
+
+ Notice the use of ret+2 for the new space in the C99 case. This ensures
+ the next vsnprintf return value will be space-2, which is unambiguously
+ successful. But actually GMP_ASPRINTF_T_NEED() will realloc to even
+ bigger than that ret+2.
+
+ vsnprintf might trash it's given ap, so copy it in case we need to use it
+ more than once. See comments with gmp_snprintf_format. */
+
+static int
+gmp_asprintf_format (struct gmp_asprintf_t *d, const char *fmt,
+ va_list orig_ap)
+{
+ int ret;
+ va_list ap;
+ size_t space = 256;
+
+ for (;;)
+ {
+ GMP_ASPRINTF_T_NEED (d, space);
+ space = d->alloc - d->size;
+ va_copy (ap, orig_ap);
+ ret = vsnprintf (d->buf + d->size, space, fmt, ap);
+ if (ret == -1)
+ {
+ ASSERT (strlen (d->buf + d->size) == space-1);
+ ret = space-1;
+ }
+
+ /* done if output fits in our space */
+ if (ret < space-1)
+ break;
+
+ if (ret == space-1)
+ space *= 2; /* possible glibc 2.0.x, so double */
+ else
+ space = ret+2; /* C99, so now know space required */
+ }
+
+ d->size += ret;
+ return ret;
+}
+
+const struct doprnt_funs_t __gmp_asprintf_funs = {
+ (doprnt_format_t) gmp_asprintf_format,
+ (doprnt_memory_t) __gmp_asprintf_memory,
+ (doprnt_reps_t) __gmp_asprintf_reps,
+ (doprnt_final_t) __gmp_asprintf_final
+};
+
+int
+gmp_vasprintf (char **result, const char *fmt, va_list ap)
+{
+ struct gmp_asprintf_t d;
+ GMP_ASPRINTF_T_INIT (d, result);
+ return __gmp_doprnt (&__gmp_asprintf_funs, &d, fmt, ap);
+}
diff --git a/gmp/printf/vfprintf.c b/gmp/printf/vfprintf.c
new file mode 100644
index 0000000000..839f133d9d
--- /dev/null
+++ b/gmp/printf/vfprintf.c
@@ -0,0 +1,42 @@
+/* gmp_vfprintf -- formatted output.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_vfprintf (FILE *fp, const char *fmt, va_list ap)
+{
+ return __gmp_doprnt (&__gmp_fprintf_funs, fp, fmt, ap);
+}
diff --git a/gmp/printf/vprintf.c b/gmp/printf/vprintf.c
new file mode 100644
index 0000000000..8e768978f5
--- /dev/null
+++ b/gmp/printf/vprintf.c
@@ -0,0 +1,42 @@
+/* gmp_vprintf -- formatted output.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_vprintf (const char *fmt, va_list ap)
+{
+ return __gmp_doprnt (&__gmp_fprintf_funs, stdout, fmt, ap);
+}
diff --git a/gmp/printf/vsnprintf.c b/gmp/printf/vsnprintf.c
new file mode 100644
index 0000000000..ed6f99885d
--- /dev/null
+++ b/gmp/printf/vsnprintf.c
@@ -0,0 +1,48 @@
+/* gmp_vsnprintf -- formatted output to an fixed size buffer.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <string.h> /* for strlen */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
+{
+ struct gmp_snprintf_t d;
+
+ ASSERT (! MEM_OVERLAP_P (buf, size, fmt, strlen(fmt)+1));
+
+ d.buf = buf;
+ d.size = size;
+ return __gmp_doprnt (&__gmp_snprintf_funs, &d, fmt, ap);
+}
diff --git a/gmp/printf/vsprintf.c b/gmp/printf/vsprintf.c
new file mode 100644
index 0000000000..099455d325
--- /dev/null
+++ b/gmp/printf/vsprintf.c
@@ -0,0 +1,51 @@
+/* gmp_vsprintf -- formatted output to an unrestricted string.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <string.h> /* for strlen */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_vsprintf (char *buf, const char *fmt, va_list ap)
+{
+#if WANT_ASSERT
+ int fmtlen = strlen(fmt);
+#endif
+ int ret;
+
+ ret = __gmp_doprnt (&__gmp_sprintf_funs, &buf, fmt, ap);
+
+ ASSERT (! MEM_OVERLAP_P (buf, strlen(buf)+1, fmt, fmtlen+1));
+
+ return ret;
+}
diff --git a/gmp/rand/Makefile.am b/gmp/rand/Makefile.am
new file mode 100644
index 0000000000..0cee1a7623
--- /dev/null
+++ b/gmp/rand/Makefile.am
@@ -0,0 +1,38 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2001, 2002, 2010 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+
+noinst_LTLIBRARIES = librandom.la
+
+librandom_la_SOURCES = randmt.h \
+ rand.c randclr.c randdef.c randiset.c randlc2s.c randlc2x.c randmt.c \
+ randmts.c rands.c randsd.c randsdui.c randbui.c randmui.c
diff --git a/gmp/rand/Makefile.in b/gmp/rand/Makefile.in
new file mode 100644
index 0000000000..9d033e1259
--- /dev/null
+++ b/gmp/rand/Makefile.in
@@ -0,0 +1,556 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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, 2002, 2010 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = rand
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+librandom_la_LIBADD =
+am_librandom_la_OBJECTS = rand.lo randclr.lo randdef.lo randiset.lo \
+ randlc2s.lo randlc2x.lo randmt.lo randmts.lo rands.lo \
+ randsd.lo randsdui.lo randbui.lo randmui.lo
+librandom_la_OBJECTS = $(am_librandom_la_OBJECTS)
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(librandom_la_SOURCES)
+DIST_SOURCES = $(librandom_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+noinst_LTLIBRARIES = librandom.la
+librandom_la_SOURCES = randmt.h \
+ rand.c randclr.c randdef.c randiset.c randlc2s.c randlc2x.c randmt.c \
+ randmts.c rands.c randsd.c randsdui.c randbui.c randmui.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 rand/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps rand/Makefile
+.PRECIOUS: 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-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+librandom.la: $(librandom_la_OBJECTS) $(librandom_la_DEPENDENCIES) $(EXTRA_librandom_la_DEPENDENCIES)
+ $(LINK) $(librandom_la_OBJECTS) $(librandom_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+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:
+
+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-generic clean-libtool clean-noinstLTLIBRARIES \
+ 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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags 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 tags uninstall uninstall-am
+
+
+# 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/gmp/rand/rand.c b/gmp/rand/rand.c
new file mode 100644
index 0000000000..09e3b765bc
--- /dev/null
+++ b/gmp/rand/rand.c
@@ -0,0 +1,52 @@
+/* gmp_randinit (state, algorithm, ...) -- Initialize a random state.
+
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+gmp_randinit (gmp_randstate_t rstate, gmp_randalg_t alg, ...)
+{
+ va_list ap;
+ va_start (ap, alg);
+
+ switch (alg) {
+ case GMP_RAND_ALG_LC:
+ if (! gmp_randinit_lc_2exp_size (rstate, va_arg (ap, unsigned long)))
+ gmp_errno |= GMP_ERROR_INVALID_ARGUMENT;
+ break;
+ default:
+ gmp_errno |= GMP_ERROR_UNSUPPORTED_ARGUMENT;
+ break;
+ }
+ va_end (ap);
+}
diff --git a/gmp/rand/randbui.c b/gmp/rand/randbui.c
new file mode 100644
index 0000000000..619ab91bd1
--- /dev/null
+++ b/gmp/rand/randbui.c
@@ -0,0 +1,57 @@
+/* gmp_urandomb_ui -- random bits returned in a ulong.
+
+Copyright 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Currently bits>=BITS_PER_ULONG is quietly truncated to BITS_PER_ULONG,
+ maybe this should raise an exception or something. */
+
+unsigned long
+gmp_urandomb_ui (gmp_randstate_ptr rstate, unsigned long bits)
+{
+ mp_limb_t a[LIMBS_PER_ULONG];
+
+ /* start with zeros, since if bits==0 then _gmp_rand will store nothing at
+ all, or if bits <= GMP_NUMB_BITS then it will store only a[0] */
+ a[0] = 0;
+#if LIMBS_PER_ULONG > 1
+ a[1] = 0;
+#endif
+
+ _gmp_rand (a, rstate, MIN (bits, BITS_PER_ULONG));
+
+#if LIMBS_PER_ULONG == 1
+ return a[0];
+#else
+ return a[0] | (a[1] << GMP_NUMB_BITS);
+#endif
+}
diff --git a/gmp/rand/randclr.c b/gmp/rand/randclr.c
new file mode 100644
index 0000000000..fb3798b73d
--- /dev/null
+++ b/gmp/rand/randclr.c
@@ -0,0 +1,38 @@
+/* gmp_randclear (state) -- Clear and deallocate random state STATE.
+
+Copyright 1999-2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+gmp_randclear (gmp_randstate_t rstate)
+{
+ (*((gmp_randfnptr_t *) RNG_FNPTR (rstate))->randclear_fn) (rstate);
+}
diff --git a/gmp/rand/randdef.c b/gmp/rand/randdef.c
new file mode 100644
index 0000000000..7d173f9364
--- /dev/null
+++ b/gmp/rand/randdef.c
@@ -0,0 +1,38 @@
+/* gmp_randinit_default -- initialize a random state with a default algorithm.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+gmp_randinit_default (gmp_randstate_t rstate)
+{
+ gmp_randinit_mt (rstate);
+}
diff --git a/gmp/rand/randiset.c b/gmp/rand/randiset.c
new file mode 100644
index 0000000000..66f4bc4903
--- /dev/null
+++ b/gmp/rand/randiset.c
@@ -0,0 +1,39 @@
+/* gmp_randinit_set -- initialize with a copy of another gmp_randstate_t.
+
+Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+void
+gmp_randinit_set (gmp_randstate_ptr dst, gmp_randstate_srcptr src)
+{
+ (*((gmp_randfnptr_t *) RNG_FNPTR (src))->randiset_fn) (dst, src);
+}
diff --git a/gmp/rand/randlc2s.c b/gmp/rand/randlc2s.c
new file mode 100644
index 0000000000..013e877286
--- /dev/null
+++ b/gmp/rand/randlc2s.c
@@ -0,0 +1,93 @@
+/* gmp_randinit_lc_2exp_size -- initialize a random state with a linear
+ congruential generator of a requested size.
+
+Copyright 1999-2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Array of LC-schemes, ordered in increasing order of the first
+ member (the 'm2exp' value). The end of the array is indicated with
+ an entry containing all zeros. */
+
+/* All multipliers are in the range 0.01*m and 0.99*m, and are
+congruent to 5 (mod 8).
+They all pass the spectral test with Vt >= 2^(30/t) and merit >= 1.
+(Up to and including 196 bits, merit is >= 3.) */
+
+struct __gmp_rand_lc_scheme_struct
+{
+ unsigned long int m2exp; /* Modulus is 2 ^ m2exp. */
+ const char *astr; /* Multiplier in string form. */
+ unsigned long int c; /* Addend. */
+};
+
+static const struct __gmp_rand_lc_scheme_struct __gmp_rand_lc_scheme[] =
+{
+ {32, "29CF535", 1},
+ {33, "51F666D", 1},
+ {34, "A3D73AD", 1},
+ {35, "147E5B85", 1},
+ {36, "28F725C5", 1},
+ {37, "51EE3105", 1},
+ {38, "A3DD5CDD", 1},
+ {39, "147AF833D", 1},
+ {40, "28F5DA175", 1},
+ {56, "AA7D735234C0DD", 1},
+ {64, "BAECD515DAF0B49D", 1},
+ {100, "292787EBD3329AD7E7575E2FD", 1},
+ {128, "48A74F367FA7B5C8ACBB36901308FA85", 1},
+ {156, "78A7FDDDC43611B527C3F1D760F36E5D7FC7C45", 1},
+ {196, "41BA2E104EE34C66B3520CE706A56498DE6D44721E5E24F5", 1},
+ {200, "4E5A24C38B981EAFE84CD9D0BEC48E83911362C114F30072C5", 1},
+ {256, "AF66BA932AAF58A071FD8F0742A99A0C76982D648509973DB802303128A14CB5", 1},
+ {0, NULL, 0} /* End of array. */
+};
+
+int
+gmp_randinit_lc_2exp_size (gmp_randstate_t rstate, mp_bitcnt_t size)
+{
+ const struct __gmp_rand_lc_scheme_struct *sp;
+ mpz_t a;
+
+ /* Pick a scheme. */
+ for (sp = __gmp_rand_lc_scheme; sp->m2exp != 0; sp++)
+ if (sp->m2exp / 2 >= size)
+ goto found;
+ return 0;
+
+ found:
+ /* Install scheme. */
+ mpz_init_set_str (a, sp->astr, 16);
+ gmp_randinit_lc_2exp (rstate, a, sp->c, sp->m2exp);
+ mpz_clear (a);
+ return 1;
+}
diff --git a/gmp/rand/randlc2x.c b/gmp/rand/randlc2x.c
new file mode 100644
index 0000000000..195f759327
--- /dev/null
+++ b/gmp/rand/randlc2x.c
@@ -0,0 +1,333 @@
+/* Linear Congruential pseudo-random number generator functions.
+
+Copyright 1999-2003, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* State structure for LC, the RNG_STATE() pointer in a gmp_randstate_t.
+
+ _mp_seed holds the current seed value, in the range 0 to 2^m2exp-1.
+ SIZ(_mp_seed) is fixed at BITS_TO_LIMBS(_mp_m2exp) and the value is
+ padded with high zero limbs if necessary. ALLOC(_mp_seed) is the current
+ size of PTR(_mp_seed) in the usual way. There only needs to be
+ BITS_TO_LIMBS(_mp_m2exp) allocated, but the mpz functions in the
+ initialization and seeding end up making it a bit more than this.
+
+ _mp_a is the "a" multiplier, in the range 0 to 2^m2exp-1. SIZ(_mp_a) is
+ the size of the value in the normal way for an mpz_t, except that a value
+ of zero is held with SIZ(_mp_a)==1 and PTR(_mp_a)[0]==0. This makes it
+ easy to call mpn_mul, and the case of a==0 is highly un-random and not
+ worth any trouble to optimize.
+
+ {_cp,_cn} is the "c" addend. Normally _cn is 1, but when nails are in
+ use a ulong can be bigger than one limb, and in this case _cn is 2 if
+ necessary. c==0 is stored as _cp[0]==0 and _cn==1, which makes it easy
+ to call __GMPN_ADD. c==0 is fairly un-random so isn't worth optimizing.
+
+ _mp_m2exp gives the modulus, namely 2^m2exp. We demand m2exp>=1, since
+ m2exp==0 would mean no bits at all out of each iteration, which makes no
+ sense. */
+
+typedef struct {
+ mpz_t _mp_seed;
+ mpz_t _mp_a;
+ mp_size_t _cn;
+ mp_limb_t _cp[LIMBS_PER_ULONG];
+ unsigned long _mp_m2exp;
+} gmp_rand_lc_struct;
+
+
+/* lc (rp, state) -- Generate next number in LC sequence. Return the
+ number of valid bits in the result. Discards the lower half of the
+ result. */
+
+static unsigned long int
+lc (mp_ptr rp, gmp_randstate_t rstate)
+{
+ mp_ptr tp, seedp, ap;
+ mp_size_t ta;
+ mp_size_t tn, seedn, an;
+ unsigned long int m2exp;
+ unsigned long int bits;
+ int cy;
+ mp_size_t xn;
+ gmp_rand_lc_struct *p;
+ TMP_DECL;
+
+ p = (gmp_rand_lc_struct *) RNG_STATE (rstate);
+
+ m2exp = p->_mp_m2exp;
+
+ seedp = PTR (p->_mp_seed);
+ seedn = SIZ (p->_mp_seed);
+
+ ap = PTR (p->_mp_a);
+ an = SIZ (p->_mp_a);
+
+ /* Allocate temporary storage. Let there be room for calculation of
+ (A * seed + C) % M, or M if bigger than that. */
+
+ TMP_MARK;
+
+ ta = an + seedn + 1;
+ tn = BITS_TO_LIMBS (m2exp);
+ if (ta <= tn) /* that is, if (ta < tn + 1) */
+ {
+ mp_size_t tmp = an + seedn;
+ ta = tn + 1;
+ tp = TMP_ALLOC_LIMBS (ta);
+ MPN_ZERO (&tp[tmp], ta - tmp); /* mpn_mul won't zero it out. */
+ }
+ else
+ tp = TMP_ALLOC_LIMBS (ta);
+
+ /* t = a * seed. NOTE: an is always > 0; see initialization. */
+ ASSERT (seedn >= an && an > 0);
+ mpn_mul (tp, seedp, seedn, ap, an);
+
+ /* t = t + c. NOTE: tn is always >= p->_cn (precondition for __GMPN_ADD);
+ see initialization. */
+ ASSERT (tn >= p->_cn);
+ __GMPN_ADD (cy, tp, tp, tn, p->_cp, p->_cn);
+
+ /* t = t % m */
+ tp[m2exp / GMP_NUMB_BITS] &= (CNST_LIMB (1) << m2exp % GMP_NUMB_BITS) - 1;
+
+ /* Save result as next seed. */
+ MPN_COPY (PTR (p->_mp_seed), tp, tn);
+
+ /* Discard the lower m2exp/2 of the result. */
+ bits = m2exp / 2;
+ xn = bits / GMP_NUMB_BITS;
+
+ tn -= xn;
+ if (tn > 0)
+ {
+ unsigned int cnt = bits % GMP_NUMB_BITS;
+ if (cnt != 0)
+ {
+ mpn_rshift (tp, tp + xn, tn, cnt);
+ MPN_COPY_INCR (rp, tp, xn + 1);
+ }
+ else /* Even limb boundary. */
+ MPN_COPY_INCR (rp, tp + xn, tn);
+ }
+
+ TMP_FREE;
+
+ /* Return number of valid bits in the result. */
+ return (m2exp + 1) / 2;
+}
+
+
+/* Obtain a sequence of random numbers. */
+static void
+randget_lc (gmp_randstate_t rstate, mp_ptr rp, unsigned long int nbits)
+{
+ unsigned long int rbitpos;
+ int chunk_nbits;
+ mp_ptr tp;
+ mp_size_t tn;
+ gmp_rand_lc_struct *p;
+ TMP_DECL;
+
+ p = (gmp_rand_lc_struct *) RNG_STATE (rstate);
+
+ TMP_MARK;
+
+ chunk_nbits = p->_mp_m2exp / 2;
+ tn = BITS_TO_LIMBS (chunk_nbits);
+
+ tp = TMP_ALLOC_LIMBS (tn);
+
+ rbitpos = 0;
+ while (rbitpos + chunk_nbits <= nbits)
+ {
+ mp_ptr r2p = rp + rbitpos / GMP_NUMB_BITS;
+
+ if (rbitpos % GMP_NUMB_BITS != 0)
+ {
+ mp_limb_t savelimb, rcy;
+ /* Target of new chunk is not bit aligned. Use temp space
+ and align things by shifting it up. */
+ lc (tp, rstate);
+ savelimb = r2p[0];
+ rcy = mpn_lshift (r2p, tp, tn, rbitpos % GMP_NUMB_BITS);
+ r2p[0] |= savelimb;
+ /* bogus */
+ if ((chunk_nbits % GMP_NUMB_BITS + rbitpos % GMP_NUMB_BITS)
+ > GMP_NUMB_BITS)
+ r2p[tn] = rcy;
+ }
+ else
+ {
+ /* Target of new chunk is bit aligned. Let `lc' put bits
+ directly into our target variable. */
+ lc (r2p, rstate);
+ }
+ rbitpos += chunk_nbits;
+ }
+
+ /* Handle last [0..chunk_nbits) bits. */
+ if (rbitpos != nbits)
+ {
+ mp_ptr r2p = rp + rbitpos / GMP_NUMB_BITS;
+ int last_nbits = nbits - rbitpos;
+ tn = BITS_TO_LIMBS (last_nbits);
+ lc (tp, rstate);
+ if (rbitpos % GMP_NUMB_BITS != 0)
+ {
+ mp_limb_t savelimb, rcy;
+ /* Target of new chunk is not bit aligned. Use temp space
+ and align things by shifting it up. */
+ savelimb = r2p[0];
+ rcy = mpn_lshift (r2p, tp, tn, rbitpos % GMP_NUMB_BITS);
+ r2p[0] |= savelimb;
+ if (rbitpos + tn * GMP_NUMB_BITS - rbitpos % GMP_NUMB_BITS < nbits)
+ r2p[tn] = rcy;
+ }
+ else
+ {
+ MPN_COPY (r2p, tp, tn);
+ }
+ /* Mask off top bits if needed. */
+ if (nbits % GMP_NUMB_BITS != 0)
+ rp[nbits / GMP_NUMB_BITS]
+ &= ~(~CNST_LIMB (0) << nbits % GMP_NUMB_BITS);
+ }
+
+ TMP_FREE;
+}
+
+
+static void
+randseed_lc (gmp_randstate_t rstate, mpz_srcptr seed)
+{
+ gmp_rand_lc_struct *p = (gmp_rand_lc_struct *) RNG_STATE (rstate);
+ mpz_ptr seedz = p->_mp_seed;
+ mp_size_t seedn = BITS_TO_LIMBS (p->_mp_m2exp);
+
+ /* Store p->_mp_seed as an unnormalized integer with size enough
+ for numbers up to 2^m2exp-1. That size can't be zero. */
+ mpz_fdiv_r_2exp (seedz, seed, p->_mp_m2exp);
+ MPN_ZERO (&PTR (seedz)[SIZ (seedz)], seedn - SIZ (seedz));
+ SIZ (seedz) = seedn;
+}
+
+
+static void
+randclear_lc (gmp_randstate_t rstate)
+{
+ gmp_rand_lc_struct *p = (gmp_rand_lc_struct *) RNG_STATE (rstate);
+
+ mpz_clear (p->_mp_seed);
+ mpz_clear (p->_mp_a);
+ (*__gmp_free_func) (p, sizeof (gmp_rand_lc_struct));
+}
+
+static void randiset_lc (gmp_randstate_ptr, gmp_randstate_srcptr);
+
+static const gmp_randfnptr_t Linear_Congruential_Generator = {
+ randseed_lc,
+ randget_lc,
+ randclear_lc,
+ randiset_lc
+};
+
+static void
+randiset_lc (gmp_randstate_ptr dst, gmp_randstate_srcptr src)
+{
+ gmp_rand_lc_struct *dstp, *srcp;
+
+ srcp = (gmp_rand_lc_struct *) RNG_STATE (src);
+ dstp = (gmp_rand_lc_struct *) (*__gmp_allocate_func) (sizeof (gmp_rand_lc_struct));
+
+ RNG_STATE (dst) = (mp_limb_t *) (void *) dstp;
+ RNG_FNPTR (dst) = (void *) &Linear_Congruential_Generator;
+
+ /* _mp_seed and _mp_a might be unnormalized (high zero limbs), but
+ mpz_init_set won't worry about that */
+ mpz_init_set (dstp->_mp_seed, srcp->_mp_seed);
+ mpz_init_set (dstp->_mp_a, srcp->_mp_a);
+
+ dstp->_cn = srcp->_cn;
+
+ dstp->_cp[0] = srcp->_cp[0];
+ if (LIMBS_PER_ULONG > 1)
+ dstp->_cp[1] = srcp->_cp[1];
+ if (LIMBS_PER_ULONG > 2) /* usually there's only 1 or 2 */
+ MPN_COPY (dstp->_cp + 2, srcp->_cp + 2, LIMBS_PER_ULONG - 2);
+
+ dstp->_mp_m2exp = srcp->_mp_m2exp;
+}
+
+
+void
+gmp_randinit_lc_2exp (gmp_randstate_t rstate,
+ mpz_srcptr a,
+ unsigned long int c,
+ mp_bitcnt_t m2exp)
+{
+ gmp_rand_lc_struct *p;
+ mp_size_t seedn = BITS_TO_LIMBS (m2exp);
+
+ ASSERT_ALWAYS (m2exp != 0);
+
+ p = __GMP_ALLOCATE_FUNC_TYPE (1, gmp_rand_lc_struct);
+ RNG_STATE (rstate) = (mp_limb_t *) (void *) p;
+ RNG_FNPTR (rstate) = (void *) &Linear_Congruential_Generator;
+
+ /* allocate m2exp bits of space for p->_mp_seed, and initial seed "1" */
+ mpz_init2 (p->_mp_seed, m2exp);
+ MPN_ZERO (PTR (p->_mp_seed), seedn);
+ SIZ (p->_mp_seed) = seedn;
+ PTR (p->_mp_seed)[0] = 1;
+
+ /* "a", forced to 0 to 2^m2exp-1 */
+ mpz_init (p->_mp_a);
+ mpz_fdiv_r_2exp (p->_mp_a, a, m2exp);
+
+ /* Avoid SIZ(a) == 0 to avoid checking for special case in lc(). */
+ if (SIZ (p->_mp_a) == 0)
+ {
+ SIZ (p->_mp_a) = 1;
+ PTR (p->_mp_a)[0] = CNST_LIMB (0);
+ }
+
+ MPN_SET_UI (p->_cp, p->_cn, c);
+
+ /* Internally we may discard any bits of c above m2exp. The following
+ code ensures that __GMPN_ADD in lc() will always work. */
+ if (seedn < p->_cn)
+ p->_cn = (p->_cp[0] != 0);
+
+ p->_mp_m2exp = m2exp;
+}
diff --git a/gmp/rand/randmt.c b/gmp/rand/randmt.c
new file mode 100644
index 0000000000..f3cdc66662
--- /dev/null
+++ b/gmp/rand/randmt.c
@@ -0,0 +1,416 @@
+/* Mersenne Twister pseudo-random number generator functions.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2002, 2003, 2006 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h> /* for NULL */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "randmt.h"
+
+
+/* This code implements the Mersenne Twister pseudorandom number generator
+ by Takuji Nishimura and Makoto Matsumoto. The buffer initialization
+ function is different in order to permit seeds greater than 2^32-1.
+
+ This file contains a special __gmp_randinit_mt_noseed which excludes the
+ seeding function from the gmp_randfnptr_t routines. This is for use by
+ mpn_random and mpn_random2 on the global random generator. MT seeding
+ uses mpz functions, and we don't want mpn routines dragging mpz functions
+ into the link. */
+
+
+/* Default seed to use when the generator is not initialized. */
+#define DEFAULT_SEED 5489 /* was 4357 */
+
+/* Tempering masks. */
+#define MASK_1 0x9D2C5680
+#define MASK_2 0xEFC60000
+
+/* Initial state of buffer when initialized with default seed. */
+static const gmp_uint_least32_t default_state[N] =
+{
+ 0xD247B233,0x9E5AA8F1,0x0FFA981B,0x9DCB0980,0x74200F2B,0xA576D044,
+ 0xE9F05ADF,0x1538BFF5,0x59818BBF,0xCF9E58D8,0x09FCE032,0x6A1C663F,
+ 0x5116E78A,0x69B3E0FA,0x6D92D665,0xD0A8BE98,0xF669B734,0x41AC1B68,
+ 0x630423F1,0x4B8D6B8A,0xC2C46DD7,0x5680747D,0x43703E8F,0x3B6103D2,
+ 0x49E5EB3F,0xCBDAB4C1,0x9C988E23,0x747BEE0B,0x9111E329,0x9F031B5A,
+ 0xECCA71B9,0x2AFE4EF8,0x8421C7ED,0xAC89AFF1,0xAED90DF3,0x2DD74F01,
+ 0x14906A13,0x75873FA9,0xFF83F877,0x5028A0C9,0x11B4C41D,0x7CAEDBC4,
+ 0x8672D0A7,0x48A7C109,0x8320E59F,0xBC0B3D5F,0x75A30886,0xF9E0D128,
+ 0x41AF7580,0x239BB94D,0xC67A3C81,0x74EEBD6E,0xBC02B53C,0x727EA449,
+ 0x6B8A2806,0x5853B0DA,0xBDE032F4,0xCE234885,0x320D6145,0x48CC053F,
+ 0x00DBC4D2,0xD55A2397,0xE1059B6F,0x1C3E05D1,0x09657C64,0xD07CB661,
+ 0x6E982E34,0x6DD1D777,0xEDED1071,0xD79DFD65,0xF816DDCE,0xB6FAF1E4,
+ 0x1C771074,0x311835BD,0x18F952F7,0xF8F40350,0x4ECED354,0x7C8AC12B,
+ 0x31A9994D,0x4FD47747,0xDC227A23,0x6DFAFDDF,0x6796E748,0x0C6F634F,
+ 0xF992FA1D,0x4CF670C9,0x067DFD31,0xA7A3E1A5,0x8CD7D9DF,0x972CCB34,
+ 0x67C82156,0xD548F6A8,0x045CEC21,0xF3240BFB,0xDEF656A7,0x43DE08C5,
+ 0xDAD1F92F,0x3726C56B,0x1409F19A,0x942FD147,0xB926749C,0xADDC31B8,
+ 0x53D0D869,0xD1BA52FE,0x6722DF8C,0x22D95A74,0x7DC1B52A,0x1DEC6FD5,
+ 0x7262874D,0x0A725DC9,0xE6A8193D,0xA052835A,0xDC9AD928,0xE59EBB90,
+ 0x70DBA9FF,0xD612749D,0x5A5A638C,0x6086EC37,0x2A579709,0x1449EA3A,
+ 0xBC8E3C06,0x2F900666,0xFBE74FD1,0x6B35B911,0xF8335008,0xEF1E979D,
+ 0x738AB29D,0xA2DC0FDC,0x7696305D,0xF5429DAC,0x8C41813B,0x8073E02E,
+ 0xBEF83CCD,0x7B50A95A,0x05EE5862,0x00829ECE,0x8CA1958C,0xBE4EA2E2,
+ 0x4293BB73,0x656F7B23,0x417316D8,0x4467D7CF,0x2200E63B,0x109050C8,
+ 0x814CBE47,0x36B1D4A8,0x36AF9305,0x308327B3,0xEBCD7344,0xA738DE27,
+ 0x5A10C399,0x4142371D,0x64A18528,0x0B31E8B2,0x641057B9,0x6AFC363B,
+ 0x108AD953,0x9D4DA234,0x0C2D9159,0x1C8A1A1F,0x310C66BA,0x87AA1070,
+ 0xDAC832FF,0x0A433422,0x7AF15812,0x2D8D9BD0,0x995A25E9,0x25326CAC,
+ 0xA34384DB,0x4C8421CC,0x4F0315EC,0x29E8649E,0xA7732D6F,0x2E94D3E3,
+ 0x7D98A340,0x397C4D74,0x659DB4DE,0x747D4E9A,0xD9DB8435,0x4659DBE9,
+ 0x313E6DC5,0x29D104DC,0x9F226CBA,0x452F18B0,0xD0BC5068,0x844CA299,
+ 0x782B294E,0x4AE2EB7B,0xA4C475F8,0x70A81311,0x4B3E8BCC,0x7E20D4BA,
+ 0xABCA33C9,0x57BE2960,0x44F9B419,0x2E567746,0x72EB757A,0x102CC0E8,
+ 0xB07F32B9,0xD0DABD59,0xBA85AD6B,0xF3E20667,0x98D77D81,0x197AFA47,
+ 0x518EE9AC,0xE10CE5A2,0x01CF2C2A,0xD3A3AF3D,0x16DDFD65,0x669232F8,
+ 0x1C50A301,0xB93D9151,0x9354D3F4,0x847D79D0,0xD5FE2EC6,0x1F7B0610,
+ 0xFA6B90A5,0xC5879041,0x2E7DC05E,0x423F1F32,0xEF623DDB,0x49C13280,
+ 0x98714E92,0xC7B6E4AD,0xC4318466,0x0737F312,0x4D3C003F,0x9ACC1F1F,
+ 0x5F1C926D,0x085FA771,0x185A83A2,0xF9AA159D,0x0B0B0132,0xF98E7A43,
+ 0xCD9EBDBE,0x0190CB29,0x10D93FB6,0x3B8A4D97,0x66A65A41,0xE43E766F,
+ 0x77BE3C41,0xB9686364,0xCB36994D,0x6846A287,0x567E77F7,0x36178DD8,
+ 0xBDE6B1F2,0xB6EFDC64,0x82950324,0x42053F47,0xC09BE51C,0x0942D762,
+ 0x35F92C7F,0x367DEC61,0x6EE3D983,0xDBAAF78A,0x265D2C47,0x8EB4BF5C,
+ 0x33B232D7,0xB0137E77,0x373C39A7,0x8D2B2E76,0xC7510F01,0x50F9E032,
+ 0x7B1FDDDB,0x724C2AAE,0xB10ECB31,0xCCA3D1B8,0x7F0BCF10,0x4254BBBD,
+ 0xE3F93B97,0x2305039B,0x53120E22,0x1A2F3B9A,0x0FDDBD97,0x0118561E,
+ 0x0A798E13,0x9E0B3ACD,0xDB6C9F15,0xF512D0A2,0x9E8C3A28,0xEE2184AE,
+ 0x0051EC2F,0x2432F74F,0xB0AA66EA,0x55128D88,0xF7D83A38,0x4DAE8E82,
+ 0x3FDC98D6,0x5F0BD341,0x7244BE1D,0xC7B48E78,0x2D473053,0x43892E20,
+ 0xBA0F1F2A,0x524D4895,0x2E10BCB1,0x4C372D81,0x5C3E50CD,0xCF61CC2E,
+ 0x931709AB,0x81B3AEFC,0x39E9405E,0x7FFE108C,0x4FBB3FF8,0x06ABE450,
+ 0x7F5BF51E,0xA4E3CDFD,0xDB0F6C6F,0x159A1227,0x3B9FED55,0xD20B6F7F,
+ 0xFBE9CC83,0x64856619,0xBF52B8AF,0x9D7006B0,0x71165BC6,0xAE324AEE,
+ 0x29D27F2C,0x794C2086,0x74445CE2,0x782915CC,0xD4CE6886,0x3289AE7C,
+ 0x53DEF297,0x4185F7ED,0x88B72400,0x3C09DC11,0xBCE3AAB6,0x6A75934A,
+ 0xB267E399,0x000DF1BF,0x193BA5E2,0xFA3E1977,0x179E14F6,0x1EEDE298,
+ 0x691F0B06,0xB84F78AC,0xC1C15316,0xFFFF3AD6,0x0B457383,0x518CD612,
+ 0x05A00F3E,0xD5B7D275,0x4C5ECCD7,0xE02CD0BE,0x5558E9F2,0x0C89BBF0,
+ 0xA3D96227,0x2832D2B2,0xF667B897,0xD4556554,0xF9D2F01F,0xFA1E3FAE,
+ 0x52C2E1EE,0xE5451F31,0x7E849729,0xDABDB67A,0x54BF5E7E,0xF831C271,
+ 0x5F1A17E3,0x9D140AFE,0x92741C47,0x48CFABCE,0x9CBBE477,0x9C3EE57F,
+ 0xB07D4C39,0xCC21BCE2,0x697708B1,0x58DA2A6B,0x2370DB16,0x6E641948,
+ 0xACC5BD52,0x868F24CC,0xCA1DB0F5,0x4CADA492,0x3F443E54,0xC4A4D5E9,
+ 0xF00AD670,0xE93C86E0,0xFE90651A,0xDDE532A3,0xA66458DF,0xAB7D7151,
+ 0x0E2E775F,0xC9109F99,0x8D96D59F,0x73CEF14C,0xC74E88E9,0x02712DC0,
+ 0x04F41735,0x2E5914A2,0x59F4B2FB,0x0287FC83,0x80BC0343,0xF6B32559,
+ 0xC74178D4,0xF1D99123,0x383CCC07,0xACC0637D,0x0863A548,0xA6FCAC85,
+ 0x2A13EFF0,0xAF2EEDB1,0x41E72750,0xE0C6B342,0x5DA22B46,0x635559E0,
+ 0xD2EA40AC,0x10AA98C0,0x19096497,0x112C542B,0x2C85040C,0xA868E7D0,
+ 0x6E260188,0xF596D390,0xC3BB5D7A,0x7A2AA937,0xDFD15032,0x6780AE3B,
+ 0xDB5F9CD8,0x8BD266B0,0x7744AF12,0xB463B1B0,0x589629C9,0xE30DBC6E,
+ 0x880F5569,0x209E6E16,0x9DECA50C,0x02987A57,0xBED3EA57,0xD3A678AA,
+ 0x70DD030D,0x0CFD9C5D,0x92A18E99,0xF5740619,0x7F6F0A7D,0x134CAF9A,
+ 0x70F5BAE4,0x23DCA7B5,0x4D788FCD,0xC7F07847,0xBCF77DA1,0x9071D568,
+ 0xFC627EA1,0xAE004B77,0x66B54BCB,0x7EF2DAAC,0xDCD5AC30,0xB9BDF730,
+ 0x505A97A7,0x9D881FD3,0xADB796CC,0x94A1D202,0x97535D7F,0x31EC20C0,
+ 0xB1887A98,0xC1475069,0xA6F73AF3,0x71E4E067,0x46A569DE,0xD2ADE430,
+ 0x6F0762C7,0xF50876F4,0x53510542,0x03741C3E,0x53502224,0xD8E54D60,
+ 0x3C44AB1A,0x34972B46,0x74BFA89D,0xD7D768E0,0x37E605DC,0xE13D1BDF,
+ 0x5051C421,0xB9E057BE,0xB717A14C,0xA1730C43,0xB99638BE,0xB5D5F36D,
+ 0xE960D9EA,0x6B1388D3,0xECB6D3B6,0xBDBE8B83,0x2E29AFC5,0x764D71EC,
+ 0x4B8F4F43,0xC21DDC00,0xA63F657F,0x82678130,0xDBF535AC,0xA594FC58,
+ 0x942686BC,0xBD9B657B,0x4A0F9B61,0x44FF184F,0x38E10A2F,0x61910626,
+ 0x5E247636,0x7106D137,0xC62802F0,0xBD1D1F00,0x7CC0DCB2,0xED634909,
+ 0xDC13B24E,0x9799C499,0xD77E3D6A,0x14773B68,0x967A4FB7,0x35EECFB1,
+ 0x2A5110B8,0xE2F0AF94,0x9D09DEA5,0x20255D27,0x5771D34B,0xE1089EE4,
+ 0x246F330B,0x8F7CAEE5,0xD3064712,0x75CAFBEE,0xB94F7028,0xED953666,
+ 0x5D1975B4,0x5AF81271,0x13BE2025,0x85194659,0x30805331,0xEC9D46C0,
+ 0xBC027C36,0x2AF84188,0xC2141B80,0xC02B1E4A,0x04D36177,0xFC50E9D7,
+ 0x39CE79DA,0x917E0A00,0xEF7A0BF4,0xA98BD8D1,0x19424DD2,0x9439DF1F,
+ 0xC42AF746,0xADDBE83E,0x85221F0D,0x45563E90,0x9095EC52,0x77887B25,
+ 0x8AE46064,0xBD43B71A,0xBB541956,0x7366CF9D,0xEE8E1737,0xB5A727C9,
+ 0x5076B3E7,0xFC70BACA,0xCE135B75,0xC4E91AA3,0xF0341911,0x53430C3F,
+ 0x886B0824,0x6BB5B8B7,0x33E21254,0xF193B456,0x5B09617F,0x215FFF50,
+ 0x48D97EF1,0x356479AB,0x6EA9DDC4,0x0D352746,0xA2F5CE43,0xB226A1B3,
+ 0x1329EA3C,0x7A337CC2,0xB5CCE13D,0x563E3B5B,0x534E8E8F,0x561399C9,
+ 0xE1596392,0xB0F03125,0x4586645B,0x1F371847,0x94EAABD1,0x41F97EDD,
+ 0xE3E5A39B,0x71C774E2,0x507296F4,0x5960133B,0x7852C494,0x3F5B2691,
+ 0xA3F87774,0x5A7AF89E,0x17DA3F28,0xE9D9516D,0xFCC1C1D5,0xE4618628,
+ 0x04081047,0xD8E4DB5F,0xDC380416,0x8C4933E2,0x95074D53,0xB1B0032D,
+ 0xCC8102EA,0x71641243,0x98D6EB6A,0x90FEC945,0xA0914345,0x6FAB037D,
+ 0x70F49C4D,0x05BF5B0E,0x927AAF7F,0xA1940F61,0xFEE0756F,0xF815369F,
+ 0x5C00253B,0xF2B9762F,0x4AEB3CCC,0x1069F386,0xFBA4E7B9,0x70332665,
+ 0x6BCA810E,0x85AB8058,0xAE4B2B2F,0x9D120712,0xBEE8EACB,0x776A1112
+};
+
+void
+__gmp_mt_recalc_buffer (gmp_uint_least32_t mt[])
+{
+ gmp_uint_least32_t y;
+ int kk;
+
+ for (kk = 0; kk < N - M; kk++)
+ {
+ y = (mt[kk] & 0x80000000) | (mt[kk + 1] & 0x7FFFFFFF);
+ mt[kk] = mt[kk + M] ^ (y >> 1) ^ ((y & 0x01) != 0 ? MATRIX_A : 0);
+ }
+ for (; kk < N - 1; kk++)
+ {
+ y = (mt[kk] & 0x80000000) | (mt[kk + 1] & 0x7FFFFFFF);
+ mt[kk] = mt[kk - (N - M)] ^ (y >> 1) ^ ((y & 0x01) != 0 ? MATRIX_A : 0);
+ }
+
+ y = (mt[N - 1] & 0x80000000) | (mt[0] & 0x7FFFFFFF);
+ mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ ((y & 0x01) != 0 ? MATRIX_A : 0);
+}
+
+
+/* Get nbits bits of output from the generator into dest.
+ Note that Mersenne Twister is designed to produce outputs in
+ 32-bit words. */
+void
+__gmp_randget_mt (gmp_randstate_t rstate, mp_ptr dest, unsigned long int nbits)
+{
+ gmp_uint_least32_t y;
+ int rbits;
+ mp_size_t i;
+ mp_size_t nlimbs;
+ int *pmti;
+ gmp_uint_least32_t *mt;
+
+ pmti = &((gmp_rand_mt_struct *) RNG_STATE (rstate))->mti;
+ mt = ((gmp_rand_mt_struct *) RNG_STATE (rstate))->mt;
+
+ nlimbs = nbits / GMP_NUMB_BITS;
+ rbits = nbits % GMP_NUMB_BITS;
+
+#define NEXT_RANDOM \
+ do \
+ { \
+ if (*pmti >= N) \
+ { \
+ __gmp_mt_recalc_buffer (mt); \
+ *pmti = 0; \
+ } \
+ y = mt[(*pmti)++]; \
+ y ^= (y >> 11); \
+ y ^= (y << 7) & MASK_1; \
+ y ^= (y << 15) & MASK_2; \
+ y ^= (y >> 18); \
+ } \
+ while (0)
+
+
+ /* Handle the common cases of 32- or 64-bit limbs with fast,
+ optimized routines, and the rest of cases with a general
+ routine. In all cases, no more than 31 bits are rejected
+ for the last limb so that every version of the code is
+ consistent with the others. */
+
+#if (GMP_NUMB_BITS == 32)
+
+ for (i = 0; i < nlimbs; i++)
+ {
+ NEXT_RANDOM;
+ dest[i] = (mp_limb_t) y;
+ }
+ if (rbits)
+ {
+ NEXT_RANDOM;
+ dest[nlimbs] = (mp_limb_t) (y & ~(ULONG_MAX << rbits));
+ }
+
+#else /* GMP_NUMB_BITS != 32 */
+#if (GMP_NUMB_BITS == 64)
+
+ for (i = 0; i < nlimbs; i++)
+ {
+ NEXT_RANDOM;
+ dest[i] = (mp_limb_t) y;
+ NEXT_RANDOM;
+ dest[i] |= (mp_limb_t) y << 32;
+ }
+ if (rbits)
+ {
+ if (rbits < 32)
+ {
+ NEXT_RANDOM;
+ dest[nlimbs] = (mp_limb_t) (y & ~(ULONG_MAX << rbits));
+ }
+ else
+ {
+ NEXT_RANDOM;
+ dest[nlimbs] = (mp_limb_t) y;
+ if (rbits > 32)
+ {
+ NEXT_RANDOM;
+ dest[nlimbs] |=
+ ((mp_limb_t) (y & ~(ULONG_MAX << (rbits-32)))) << 32;
+ }
+ }
+ }
+
+#else /* GMP_NUMB_BITS != 64 */
+
+ {
+ /* Fall back to a general algorithm. This algorithm works by
+ keeping a pool of up to 64 bits (2 outputs from MT) acting
+ as a shift register from which bits are consumed as needed.
+ Bits are consumed using the LSB bits of bitpool_l, and
+ inserted via bitpool_h and shifted to the right place. */
+
+ gmp_uint_least32_t bitpool_h = 0;
+ gmp_uint_least32_t bitpool_l = 0;
+ int bits_in_pool = 0; /* Holds number of valid bits in the pool. */
+ int bits_to_fill; /* Holds total number of bits to put in
+ destination. */
+ int bitidx; /* Holds the destination bit position. */
+ mp_size_t nlimbs2; /* Number of whole+partial limbs to fill. */
+
+ nlimbs2 = nlimbs + (rbits != 0);
+
+ for (i = 0; i < nlimbs2; i++)
+ {
+ bitidx = 0;
+ if (i < nlimbs)
+ bits_to_fill = GMP_NUMB_BITS;
+ else
+ bits_to_fill = rbits;
+
+ dest[i] = CNST_LIMB (0);
+ while (bits_to_fill >= 32) /* Process whole 32-bit blocks first. */
+ {
+ if (bits_in_pool < 32) /* Need more bits. */
+ {
+ /* 64-bit right shift. */
+ NEXT_RANDOM;
+ bitpool_h = y;
+ bitpool_l |= (bitpool_h << bits_in_pool) & 0xFFFFFFFF;
+ if (bits_in_pool == 0)
+ bitpool_h = 0;
+ else
+ bitpool_h >>= 32 - bits_in_pool;
+ bits_in_pool += 32; /* We've got 32 more bits. */
+ }
+
+ /* Fill a 32-bit chunk. */
+ dest[i] |= ((mp_limb_t) bitpool_l) << bitidx;
+ bitpool_l = bitpool_h;
+ bits_in_pool -= 32;
+ bits_to_fill -= 32;
+ bitidx += 32;
+ }
+
+ /* Cover the case where GMP_NUMB_BITS is not a multiple of 32. */
+ if (bits_to_fill != 0)
+ {
+ if (bits_in_pool < bits_to_fill)
+ {
+ NEXT_RANDOM;
+ bitpool_h = y;
+ bitpool_l |= (bitpool_h << bits_in_pool) & 0xFFFFFFFF;
+ if (bits_in_pool == 0)
+ bitpool_h = 0;
+ else
+ bitpool_h >>= 32 - bits_in_pool;
+ bits_in_pool += 32;
+ }
+
+ dest[i] |= (((mp_limb_t) bitpool_l
+ & ~(~CNST_LIMB (0) << bits_to_fill))
+ << bitidx);
+ bitpool_l = ((bitpool_l >> bits_to_fill)
+ | (bitpool_h << (32 - bits_to_fill))) & 0xFFFFFFFF;
+ bitpool_h >>= bits_to_fill;
+ bits_in_pool -= bits_to_fill;
+ }
+ }
+ }
+
+#endif /* GMP_NUMB_BITS != 64 */
+#endif /* GMP_NUMB_BITS != 32 */
+}
+
+void
+__gmp_randclear_mt (gmp_randstate_t rstate)
+{
+ (*__gmp_free_func) ((void *) RNG_STATE (rstate),
+ ALLOC (rstate->_mp_seed) * GMP_LIMB_BYTES);
+}
+
+void __gmp_randiset_mt (gmp_randstate_ptr, gmp_randstate_srcptr);
+
+static const gmp_randfnptr_t Mersenne_Twister_Generator_Noseed = {
+ NULL,
+ __gmp_randget_mt,
+ __gmp_randclear_mt,
+ __gmp_randiset_mt
+};
+
+void
+__gmp_randiset_mt (gmp_randstate_ptr dst, gmp_randstate_srcptr src)
+{
+ const mp_size_t sz = ((sizeof (gmp_rand_mt_struct) - 1) / GMP_LIMB_BYTES) + 1;
+ gmp_rand_mt_struct *dstp, *srcp;
+ mp_size_t i;
+
+ /* Set the generator functions. */
+ RNG_FNPTR (dst) = (void *) &Mersenne_Twister_Generator_Noseed;
+
+ /* Allocate the MT-specific state. */
+ dstp = (gmp_rand_mt_struct *) __GMP_ALLOCATE_FUNC_LIMBS (sz);
+ RNG_STATE (dst) = (mp_ptr) dstp;
+ ALLOC (dst->_mp_seed) = sz; /* Initialize alloc field to placate Camm. */
+
+ /* Copy state. */
+ srcp = (gmp_rand_mt_struct *) RNG_STATE (src);
+ for (i = 0; i < N; i++)
+ dstp->mt[i] = srcp->mt[i];
+
+ dstp->mti = srcp->mti;
+}
+
+void
+__gmp_randinit_mt_noseed (gmp_randstate_ptr dst)
+{
+ const mp_size_t sz = ((sizeof (gmp_rand_mt_struct) - 1) / GMP_LIMB_BYTES) + 1;
+ gmp_rand_mt_struct *dstp;
+ mp_size_t i;
+
+ /* Set the generator functions. */
+ RNG_FNPTR (dst) = (void *) &Mersenne_Twister_Generator_Noseed;
+
+ /* Allocate the MT-specific state. */
+ dstp = (gmp_rand_mt_struct *) __GMP_ALLOCATE_FUNC_LIMBS (sz);
+ RNG_STATE (dst) = (mp_ptr) dstp;
+ ALLOC (dst->_mp_seed) = sz; /* Initialize alloc field to placate Camm. */
+
+ /* Set state for default seed. */
+ for (i = 0; i < N; i++)
+ dstp->mt[i] = default_state[i];
+
+ dstp->mti = WARM_UP % N;
+}
diff --git a/gmp/rand/randmt.h b/gmp/rand/randmt.h
new file mode 100644
index 0000000000..d64ff59548
--- /dev/null
+++ b/gmp/rand/randmt.h
@@ -0,0 +1,51 @@
+/* Mersenne Twister pseudo-random number generator defines.
+
+Copyright 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* Number of extractions used to warm the buffer up. */
+#define WARM_UP 2000
+
+/* Period parameters. */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908B0DF /* Constant vector a. */
+
+/* State structure for MT. */
+typedef struct
+{
+ gmp_uint_least32_t mt[N]; /* State array. */
+ int mti; /* Index of current value. */
+} gmp_rand_mt_struct;
+
+
+void __gmp_mt_recalc_buffer (gmp_uint_least32_t *);
+void __gmp_randget_mt (gmp_randstate_t, mp_ptr, unsigned long int);
+void __gmp_randclear_mt (gmp_randstate_t);
+void __gmp_randiset_mt (gmp_randstate_ptr, gmp_randstate_srcptr);
diff --git a/gmp/rand/randmts.c b/gmp/rand/randmts.c
new file mode 100644
index 0000000000..1db7855141
--- /dev/null
+++ b/gmp/rand/randmts.c
@@ -0,0 +1,165 @@
+/* Mersenne Twister pseudo-random number generator functions.
+
+Copyright 2002, 2003, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "randmt.h"
+
+
+/* Calculate (b^e) mod (2^n-k) for e=1074888996, n=19937 and k=20023,
+ needed by the seeding function below. */
+static void
+mangle_seed (mpz_ptr r)
+{
+ mpz_t t, b;
+ unsigned long e = 0x40118124;
+ unsigned long bit = 0x20000000;
+
+ mpz_init2 (t, 19937L);
+ mpz_init_set (b, r);
+
+ do
+ {
+ mpz_mul (r, r, r);
+
+ reduce:
+ for (;;)
+ {
+ mpz_tdiv_q_2exp (t, r, 19937L);
+ if (SIZ (t) == 0)
+ break;
+ mpz_tdiv_r_2exp (r, r, 19937L);
+ mpz_addmul_ui (r, t, 20023L);
+ }
+
+ if ((e & bit) != 0)
+ {
+ e ^= bit;
+ mpz_mul (r, r, b);
+ goto reduce;
+ }
+
+ bit >>= 1;
+ }
+ while (bit != 0);
+
+ mpz_clear (t);
+ mpz_clear (b);
+}
+
+
+/* Seeding function. Uses powering modulo a non-Mersenne prime to obtain
+ a permutation of the input seed space. The modulus is 2^19937-20023,
+ which is probably prime. The power is 1074888996. In order to avoid
+ seeds 0 and 1 generating invalid or strange output, the input seed is
+ first manipulated as follows:
+
+ seed1 = seed mod (2^19937-20027) + 2
+
+ so that seed1 lies between 2 and 2^19937-20026 inclusive. Then the
+ powering is performed as follows:
+
+ seed2 = (seed1^1074888996) mod (2^19937-20023)
+
+ and then seed2 is used to bootstrap the buffer.
+
+ This method aims to give guarantees that:
+ a) seed2 will never be zero,
+ b) seed2 will very seldom have a very low population of ones in its
+ binary representation, and
+ c) every seed between 0 and 2^19937-20028 (inclusive) will yield a
+ different sequence.
+
+ CAVEATS:
+
+ The period of the seeding function is 2^19937-20027. This means that
+ with seeds 2^19937-20027, 2^19937-20026, ... the exact same sequences
+ are obtained as with seeds 0, 1, etc.; it also means that seed -1
+ produces the same sequence as seed 2^19937-20028, etc.
+ */
+
+static void
+randseed_mt (gmp_randstate_t rstate, mpz_srcptr seed)
+{
+ int i;
+ size_t cnt;
+
+ gmp_rand_mt_struct *p;
+ mpz_t mod; /* Modulus. */
+ mpz_t seed1; /* Intermediate result. */
+
+ p = (gmp_rand_mt_struct *) RNG_STATE (rstate);
+
+ mpz_init2 (mod, 19937L);
+ mpz_init2 (seed1, 19937L);
+
+ mpz_setbit (mod, 19937L);
+ mpz_sub_ui (mod, mod, 20027L);
+ mpz_mod (seed1, seed, mod); /* Reduce `seed' modulo `mod'. */
+ mpz_clear (mod);
+ mpz_add_ui (seed1, seed1, 2L); /* seed1 is now ready. */
+ mangle_seed (seed1); /* Perform the mangling by powering. */
+
+ /* Copy the last bit into bit 31 of mt[0] and clear it. */
+ p->mt[0] = (mpz_tstbit (seed1, 19936L) != 0) ? 0x80000000 : 0;
+ mpz_clrbit (seed1, 19936L);
+
+ /* Split seed1 into N-1 32-bit chunks. */
+ mpz_export (&p->mt[1], &cnt, -1, sizeof (p->mt[1]), 0,
+ 8 * sizeof (p->mt[1]) - 32, seed1);
+ mpz_clear (seed1);
+ cnt++;
+ ASSERT (cnt <= N);
+ while (cnt < N)
+ p->mt[cnt++] = 0;
+
+ /* Warm the generator up if necessary. */
+ if (WARM_UP != 0)
+ for (i = 0; i < WARM_UP / N; i++)
+ __gmp_mt_recalc_buffer (p->mt);
+
+ p->mti = WARM_UP % N;
+}
+
+
+static const gmp_randfnptr_t Mersenne_Twister_Generator = {
+ randseed_mt,
+ __gmp_randget_mt,
+ __gmp_randclear_mt,
+ __gmp_randiset_mt
+};
+
+/* Initialize MT-specific data. */
+void
+gmp_randinit_mt (gmp_randstate_t rstate)
+{
+ __gmp_randinit_mt_noseed (rstate);
+ RNG_FNPTR (rstate) = (void *) &Mersenne_Twister_Generator;
+}
diff --git a/gmp/rand/randmui.c b/gmp/rand/randmui.c
new file mode 100644
index 0000000000..2d4ef86aa3
--- /dev/null
+++ b/gmp/rand/randmui.c
@@ -0,0 +1,86 @@
+/* gmp_urandomm_ui -- uniform random number 0 to N-1 for ulong N.
+
+Copyright 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+/* If n is a power of 2 then the test ret<n is always true and the loop is
+ unnecessary, but there's no need to add special code for this. Just get
+ the "bits" calculation correct and let it go through normally.
+
+ If n is 1 then will have bits==0 and _gmp_rand will produce no output and
+ we always return 0. Again there seems no need for a special case, just
+ initialize a[0]=0 and let it go through normally. */
+
+#define MAX_URANDOMM_ITER 80
+
+unsigned long
+gmp_urandomm_ui (gmp_randstate_ptr rstate, unsigned long n)
+{
+ mp_limb_t a[LIMBS_PER_ULONG];
+ unsigned long ret, bits, leading;
+ int i;
+
+ if (UNLIKELY (n == 0))
+ DIVIDE_BY_ZERO;
+
+ /* start with zeros, since if bits==0 then _gmp_rand will store nothing at
+ all (bits==0 arises when n==1), or if bits <= GMP_NUMB_BITS then it
+ will store only a[0]. */
+ a[0] = 0;
+#if LIMBS_PER_ULONG > 1
+ a[1] = 0;
+#endif
+
+ count_leading_zeros (leading, (mp_limb_t) n);
+ bits = GMP_LIMB_BITS - leading - (POW2_P(n) != 0);
+
+ for (i = 0; i < MAX_URANDOMM_ITER; i++)
+ {
+ _gmp_rand (a, rstate, bits);
+#if LIMBS_PER_ULONG == 1
+ ret = a[0];
+#else
+ ret = a[0] | (a[1] << GMP_NUMB_BITS);
+#endif
+ if (LIKELY (ret < n)) /* usually one iteration suffices */
+ goto done;
+ }
+
+ /* Too many iterations, there must be something degenerate about the
+ rstate algorithm. Return r%n. */
+ ret -= n;
+ ASSERT (ret < n);
+
+ done:
+ return ret;
+}
diff --git a/gmp/rand/rands.c b/gmp/rand/rands.c
new file mode 100644
index 0000000000..1701da7a2c
--- /dev/null
+++ b/gmp/rand/rands.c
@@ -0,0 +1,42 @@
+/* __gmp_rands -- global random state for old-style random functions.
+
+ EVERYTHING IN THIS FILE IS FOR INTERNAL USE ONLY. IT'S ALMOST CERTAIN TO
+ BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN FUTURE GNU
+ MP RELEASES. */
+
+/*
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Use this via the RANDS macro in gmp-impl.h */
+char __gmp_rands_initialized = 0;
+gmp_randstate_t __gmp_rands;
diff --git a/gmp/rand/randsd.c b/gmp/rand/randsd.c
new file mode 100644
index 0000000000..1214d000d5
--- /dev/null
+++ b/gmp/rand/randsd.c
@@ -0,0 +1,39 @@
+/* gmp_randseed (state, seed) -- Set initial seed SEED in random state STATE.
+
+Copyright 2000, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+gmp_randseed (gmp_randstate_t rstate,
+ mpz_srcptr seed)
+{
+ (*((gmp_randfnptr_t *) RNG_FNPTR (rstate))->randseed_fn) (rstate, seed);
+}
diff --git a/gmp/rand/randsdui.c b/gmp/rand/randsdui.c
new file mode 100644
index 0000000000..1c97232e30
--- /dev/null
+++ b/gmp/rand/randsdui.c
@@ -0,0 +1,44 @@
+/* gmp_randseed_ui (state, seed) -- Set initial seed SEED in random
+ state STATE.
+
+Copyright 2000, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+gmp_randseed_ui (gmp_randstate_t rstate,
+ unsigned long int seed)
+{
+ mpz_t zseed;
+ mp_limb_t zlimbs[LIMBS_PER_ULONG];
+
+ MPZ_FAKE_UI (zseed, zlimbs, seed);
+ gmp_randseed (rstate, zseed);
+}
diff --git a/gmp/scanf/Makefile.am b/gmp/scanf/Makefile.am
new file mode 100644
index 0000000000..b5e0148222
--- /dev/null
+++ b/gmp/scanf/Makefile.am
@@ -0,0 +1,38 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2001, 2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+
+noinst_LTLIBRARIES = libscanf.la
+
+libscanf_la_SOURCES = \
+ doscan.c fscanf.c fscanffuns.c scanf.c sscanf.c sscanffuns.c \
+ vfscanf.c vscanf.c vsscanf.c
diff --git a/gmp/scanf/Makefile.in b/gmp/scanf/Makefile.in
new file mode 100644
index 0000000000..718a2c5beb
--- /dev/null
+++ b/gmp/scanf/Makefile.in
@@ -0,0 +1,555 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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, 2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = scanf
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libscanf_la_LIBADD =
+am_libscanf_la_OBJECTS = doscan.lo fscanf.lo fscanffuns.lo scanf.lo \
+ sscanf.lo sscanffuns.lo vfscanf.lo vscanf.lo vsscanf.lo
+libscanf_la_OBJECTS = $(am_libscanf_la_OBJECTS)
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libscanf_la_SOURCES)
+DIST_SOURCES = $(libscanf_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -D__GMP_WITHIN_GMP -I$(top_srcdir)
+noinst_LTLIBRARIES = libscanf.la
+libscanf_la_SOURCES = \
+ doscan.c fscanf.c fscanffuns.c scanf.c sscanf.c sscanffuns.c \
+ vfscanf.c vscanf.c vsscanf.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 scanf/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps scanf/Makefile
+.PRECIOUS: 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-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libscanf.la: $(libscanf_la_OBJECTS) $(libscanf_la_DEPENDENCIES) $(EXTRA_libscanf_la_DEPENDENCIES)
+ $(LINK) $(libscanf_la_OBJECTS) $(libscanf_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+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:
+
+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-generic clean-libtool clean-noinstLTLIBRARIES \
+ 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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags 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 tags uninstall uninstall-am
+
+
+# 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/gmp/scanf/doscan.c b/gmp/scanf/doscan.c
new file mode 100644
index 0000000000..47b22706ce
--- /dev/null
+++ b/gmp/scanf/doscan.c
@@ -0,0 +1,768 @@
+/* __gmp_doscan -- formatted input internals.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define _GNU_SOURCE /* for DECIMAL_POINT in langinfo.h */
+
+#include "config.h" /* needed for the HAVE_, could also move gmp incls */
+
+#include <stdarg.h>
+#include <ctype.h>
+#include <stddef.h> /* for ptrdiff_t */
+#include <stdio.h>
+#include <stdlib.h> /* for strtol */
+#include <string.h>
+
+#if HAVE_LANGINFO_H
+#include <langinfo.h> /* for nl_langinfo */
+#endif
+
+#if HAVE_LOCALE_H
+#include <locale.h> /* for localeconv */
+#endif
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h> /* for intmax_t */
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h> /* for quad_t */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Change this to "#define TRACE(x) x" for some traces. */
+#define TRACE(x)
+
+
+/* General:
+
+ It's necessary to parse up the format string to recognise the GMP
+ extra types F, Q and Z. Other types and conversions are passed
+ across to the standard sscanf or fscanf via funs->scan, for ease of
+ implementation. This is essential in the case of something like glibc
+ %p where the pointer format isn't actually documented.
+
+ Because funs->scan doesn't get the whole input it can't put the right
+ values in for %n, so that's handled in __gmp_doscan. Neither sscanf
+ nor fscanf directly indicate how many characters were read, so an
+ extra %n is appended to each run for that. For fscanf this merely
+ supports our %n output, but for sscanf it lets funs->step move us
+ along the input string.
+
+ Whitespace and literal matches in the format string, including %%,
+ are handled directly within __gmp_doscan. This is reasonably
+ efficient, and avoids some suspicious behaviour observed in various
+ system libc's. GLIBC 2.2.4 for instance returns 0 on
+
+ sscanf(" ", " x")
+ or
+ sscanf(" ", " x%d",&n)
+
+ whereas we think they should return EOF, since end-of-string is
+ reached when a match of "x" is required.
+
+ For standard % conversions, funs->scan is called once for each
+ conversion. If we had vfscanf and vsscanf and could rely on their
+ fixed text matching behaviour then we could call them with multiple
+ consecutive standard conversions. But plain fscanf and sscanf work
+ fine, and parsing one field at a time shouldn't be too much of a
+ slowdown.
+
+ gmpscan:
+
+ gmpscan reads a gmp type. It's only used from one place, but is a
+ separate subroutine to avoid a big chunk of complicated code in the
+ middle of __gmp_doscan. Within gmpscan a couple of loopbacks make it
+ possible to share code for parsing integers, rationals and floats.
+
+ In gmpscan normally one char of lookahead is maintained, but when width
+ is reached that stops, on the principle that an fgetc/ungetc of a char
+ past where we're told to stop would be undesirable. "chars" is how many
+ characters have been read so far, including the current c. When
+ chars==width and another character is desired then a jump is done to the
+ "convert" stage. c is invalid and mustn't be unget'ed in this case;
+ chars is set to width+1 to indicate that.
+
+ gmpscan normally returns the number of characters read. -1 means an
+ invalid field, -2 means EOF reached before any matching characters
+ were read.
+
+ For hex floats, the mantissa part is passed to mpf_set_str, then the
+ exponent is applied with mpf_mul_exp or mpf_div_2exp. This is easier
+ than teaching mpf_set_str about an exponent factor (ie. 2) differing
+ from the mantissa radix point factor (ie. 16). mpf_mul_exp and
+ mpf_div_2exp will preserve the application requested precision, so
+ nothing in that respect is lost by making this a two-step process.
+
+ Matching and errors:
+
+ C99 7.19.6.2 paras 9 and 10 say an input item is read as the longest
+ string which is a match for the appropriate type, or a prefix of a
+ match. With that done, if it's only a prefix then the result is a
+ matching failure, ie. invalid input.
+
+ This rule seems fairly clear, but doesn't seem to be universally
+ applied in system C libraries. Even GLIBC doesn't seem to get it
+ right, insofar as it seems to accept some apparently invalid forms.
+ Eg. glibc 2.3.1 accepts "0x" for a "%i", where a reading of the
+ standard would suggest a non-empty sequence of digits should be
+ required after an "0x".
+
+ A footnote to 7.19.6.2 para 17 notes how this input item reading can
+ mean inputs acceptable to strtol are not acceptable to fscanf. We
+ think this confirms our reading of "0x" as invalid.
+
+ Clearly gmp_sscanf could backtrack to a longest input which was a
+ valid match for a given item, but this is not done, since C99 says
+ sscanf is identical to fscanf, so we make gmp_sscanf identical to
+ gmp_fscanf.
+
+ Types:
+
+ C99 says "ll" is for long long, and "L" is for long double floats.
+ Unfortunately in GMP 4.1.1 we documented the two as equivalent. This
+ doesn't affect us directly, since both are passed through to plain
+ scanf. It seems wisest not to try to enforce the C99 rule. This is
+ consistent with what we said before, though whether it actually
+ worked was always up to the C library.
+
+ Alternatives:
+
+ Consideration was given to using separate code for gmp_fscanf and
+ gmp_sscanf. The sscanf case could zip across a string doing literal
+ matches or recognising digits in gmpscan, rather than making a
+ function call fun->get per character. The fscanf could use getc
+ rather than fgetc too, which might help those systems where getc is a
+ macro or otherwise inlined. But none of this scanning and converting
+ will be particularly fast, so the two are done together to keep it a
+ little simpler for now.
+
+ Various multibyte string issues are not addressed, for a start C99
+ scanf says the format string is multibyte. Since we pass %c, %s and
+ %[ to the system scanf, they might do multibyte reads already, but
+ it's another matter whether or not that can be used, since our digit
+ and whitespace parsing is only unibyte. The plan is to quietly
+ ignore multibyte locales for now. This is not as bad as it sounds,
+ since GMP is presumably used mostly on numbers, which can be
+ perfectly adequately treated in plain ASCII.
+
+*/
+
+
+struct gmp_doscan_params_t {
+ int base;
+ int ignore;
+ char type;
+ int width;
+};
+
+
+#define GET(c) \
+ do { \
+ ASSERT (chars <= width); \
+ chars++; \
+ if (chars > width) \
+ goto convert; \
+ (c) = (*funs->get) (data); \
+ } while (0)
+
+/* store into "s", extending if necessary */
+#define STORE(c) \
+ do { \
+ ASSERT (s_upto <= s_alloc); \
+ if (s_upto >= s_alloc) \
+ { \
+ size_t s_alloc_new = s_alloc + S_ALLOC_STEP; \
+ s = __GMP_REALLOCATE_FUNC_TYPE (s, s_alloc, s_alloc_new, char); \
+ s_alloc = s_alloc_new; \
+ } \
+ s[s_upto++] = c; \
+ } while (0)
+
+#define S_ALLOC_STEP 512
+
+static int
+gmpscan (const struct gmp_doscan_funs_t *funs, void *data,
+ const struct gmp_doscan_params_t *p, void *dst)
+{
+ int chars, c, base, first, width, seen_point, seen_digit, hexfloat;
+ size_t s_upto, s_alloc, hexexp;
+ char *s;
+ int invalid = 0;
+
+ TRACE (printf ("gmpscan\n"));
+
+ ASSERT (p->type == 'F' || p->type == 'Q' || p->type == 'Z');
+
+ c = (*funs->get) (data);
+ if (c == EOF)
+ return -2;
+
+ chars = 1;
+ first = 1;
+ seen_point = 0;
+ width = (p->width == 0 ? INT_MAX-1 : p->width);
+ base = p->base;
+ s_alloc = S_ALLOC_STEP;
+ s = __GMP_ALLOCATE_FUNC_TYPE (s_alloc, char);
+ s_upto = 0;
+ hexfloat = 0;
+ hexexp = 0;
+
+ another:
+ seen_digit = 0;
+ if (c == '-')
+ {
+ STORE (c);
+ goto get_for_sign;
+ }
+ else if (c == '+')
+ {
+ /* don't store '+', it's not accepted by mpz_set_str etc */
+ get_for_sign:
+ GET (c);
+ }
+
+ if (base == 0)
+ {
+ base = 10; /* decimal if no base indicator */
+ if (c == '0')
+ {
+ seen_digit = 1; /* 0 alone is a valid number */
+ if (p->type != 'F')
+ base = 8; /* leading 0 is octal, for non-floats */
+ STORE (c);
+ GET (c);
+ if (c == 'x' || c == 'X')
+ {
+ base = 16;
+ seen_digit = 0; /* must have digits after an 0x */
+ if (p->type == 'F') /* don't pass 'x' to mpf_set_str_point */
+ hexfloat = 1;
+ else
+ STORE (c);
+ GET (c);
+ }
+ }
+ }
+
+ digits:
+ for (;;)
+ {
+ if (base == 16)
+ {
+ if (! isxdigit (c))
+ break;
+ }
+ else
+ {
+ if (! isdigit (c))
+ break;
+ if (base == 8 && (c == '8' || c == '9'))
+ break;
+ }
+
+ seen_digit = 1;
+ STORE (c);
+ GET (c);
+ }
+
+ if (first)
+ {
+ /* decimal point */
+ if (p->type == 'F' && ! seen_point)
+ {
+ /* For a multi-character decimal point, if the first character is
+ present then all of it must be, otherwise the input is
+ considered invalid. */
+ const char *point = GMP_DECIMAL_POINT;
+ int pc = (unsigned char) *point++;
+ if (c == pc)
+ {
+ for (;;)
+ {
+ STORE (c);
+ GET (c);
+ pc = (unsigned char) *point++;
+ if (pc == '\0')
+ break;
+ if (c != pc)
+ goto set_invalid;
+ }
+ seen_point = 1;
+ goto digits;
+ }
+ }
+
+ /* exponent */
+ if (p->type == 'F')
+ {
+ if (hexfloat && (c == 'p' || c == 'P'))
+ {
+ hexexp = s_upto; /* exponent location */
+ base = 10; /* exponent in decimal */
+ goto exponent;
+ }
+ else if (! hexfloat && (c == 'e' || c == 'E'))
+ {
+ exponent:
+ /* must have at least one digit in the mantissa, just an exponent
+ is not good enough */
+ if (! seen_digit)
+ goto set_invalid;
+
+ do_second:
+ first = 0;
+ STORE (c);
+ GET (c);
+ goto another;
+ }
+ }
+
+ /* denominator */
+ if (p->type == 'Q' && c == '/')
+ {
+ /* must have at least one digit in the numerator */
+ if (! seen_digit)
+ goto set_invalid;
+
+ /* now look for at least one digit in the denominator */
+ seen_digit = 0;
+
+ /* allow the base to be redetermined for "%i" */
+ base = p->base;
+ goto do_second;
+ }
+ }
+
+ convert:
+ if (! seen_digit)
+ {
+ set_invalid:
+ invalid = 1;
+ goto done;
+ }
+
+ if (! p->ignore)
+ {
+ STORE ('\0');
+ TRACE (printf (" convert \"%s\"\n", s));
+
+ /* We ought to have parsed out a valid string above, so just test
+ mpz_set_str etc with an ASSERT. */
+ switch (p->type) {
+ case 'F':
+ {
+ mpf_ptr f = (mpf_ptr) dst;
+ if (hexexp != 0)
+ s[hexexp] = '\0';
+ ASSERT_NOCARRY (mpf_set_str (f, s, hexfloat ? 16 : 10));
+ if (hexexp != 0)
+ {
+ char *dummy;
+ long exp;
+ exp = strtol (s + hexexp + 1, &dummy, 10);
+ if (exp >= 0)
+ mpf_mul_2exp (f, f, (unsigned long) exp);
+ else
+ mpf_div_2exp (f, f, - (unsigned long) exp);
+ }
+ }
+ break;
+ case 'Q':
+ ASSERT_NOCARRY (mpq_set_str ((mpq_ptr) dst, s, p->base));
+ break;
+ case 'Z':
+ ASSERT_NOCARRY (mpz_set_str ((mpz_ptr) dst, s, p->base));
+ break;
+ default:
+ ASSERT (0);
+ /*FALLTHRU*/
+ break;
+ }
+ }
+
+ done:
+ ASSERT (chars <= width+1);
+ if (chars != width+1)
+ {
+ (*funs->unget) (c, data);
+ TRACE (printf (" ungetc %d, to give %d chars\n", c, chars-1));
+ }
+ chars--;
+
+ (*__gmp_free_func) (s, s_alloc);
+
+ if (invalid)
+ {
+ TRACE (printf (" invalid\n"));
+ return -1;
+ }
+
+ TRACE (printf (" return %d chars (cf width %d)\n", chars, width));
+ return chars;
+}
+
+
+/* Read and discard whitespace, if any. Return number of chars skipped.
+ Whitespace skipping never provokes the EOF return from __gmp_doscan, so
+ it's not necessary to watch for EOF from funs->get, */
+static int
+skip_white (const struct gmp_doscan_funs_t *funs, void *data)
+{
+ int c;
+ int ret = 0;
+
+ do
+ {
+ c = (funs->get) (data);
+ ret++;
+ }
+ while (isspace (c));
+
+ (funs->unget) (c, data);
+ ret--;
+
+ TRACE (printf (" skip white %d\n", ret));
+ return ret;
+}
+
+
+int
+__gmp_doscan (const struct gmp_doscan_funs_t *funs, void *data,
+ const char *orig_fmt, va_list orig_ap)
+{
+ struct gmp_doscan_params_t param;
+ va_list ap;
+ char *alloc_fmt;
+ const char *fmt, *this_fmt, *end_fmt;
+ size_t orig_fmt_len, alloc_fmt_size, len;
+ int new_fields, new_chars;
+ char fchar;
+ int fields = 0;
+ int chars = 0;
+
+ TRACE (printf ("__gmp_doscan \"%s\"\n", orig_fmt);
+ if (funs->scan == (gmp_doscan_scan_t) sscanf)
+ printf (" s=\"%s\"\n", * (const char **) data));
+
+ /* Don't modify orig_ap, if va_list is actually an array and hence call by
+ reference. It could be argued that it'd be more efficient to leave
+ callers to make a copy if they care, but doing so here is going to be a
+ very small part of the total work, and we may as well keep applications
+ out of trouble. */
+ va_copy (ap, orig_ap);
+
+ /* Parts of the format string are going to be copied so that a " %n" can
+ be appended. alloc_fmt is some space for that. orig_fmt_len+4 will be
+ needed if fmt consists of a single "%" specifier, but otherwise is an
+ overestimate. We're not going to be very fast here, so use
+ __gmp_allocate_func rather than TMP_ALLOC. */
+ orig_fmt_len = strlen (orig_fmt);
+ alloc_fmt_size = orig_fmt_len + 4;
+ alloc_fmt = __GMP_ALLOCATE_FUNC_TYPE (alloc_fmt_size, char);
+
+ fmt = orig_fmt;
+ end_fmt = orig_fmt + orig_fmt_len;
+
+ for (;;)
+ {
+ next:
+ fchar = *fmt++;
+
+ if (fchar == '\0')
+ break;
+
+ if (isspace (fchar))
+ {
+ chars += skip_white (funs, data);
+ continue;
+ }
+
+ if (fchar != '%')
+ {
+ int c;
+ literal:
+ c = (funs->get) (data);
+ if (c != fchar)
+ {
+ (funs->unget) (c, data);
+ if (c == EOF)
+ {
+ eof_no_match:
+ if (fields == 0)
+ fields = EOF;
+ }
+ goto done;
+ }
+ chars++;
+ continue;
+ }
+
+ param.type = '\0';
+ param.base = 0; /* for e,f,g,i */
+ param.ignore = 0;
+ param.width = 0;
+
+ this_fmt = fmt-1;
+ TRACE (printf (" this_fmt \"%s\"\n", this_fmt));
+
+ for (;;)
+ {
+ ASSERT (fmt <= end_fmt);
+
+ fchar = *fmt++;
+ switch (fchar) {
+
+ case '\0': /* unterminated % sequence */
+ ASSERT (0);
+ goto done;
+
+ case '%': /* literal % */
+ goto literal;
+
+ case '[': /* character range */
+ fchar = *fmt++;
+ if (fchar == '^')
+ fchar = *fmt++;
+ /* ']' allowed as the first char (possibly after '^') */
+ if (fchar == ']')
+ fchar = *fmt++;
+ for (;;)
+ {
+ ASSERT (fmt <= end_fmt);
+ if (fchar == '\0')
+ {
+ /* unterminated % sequence */
+ ASSERT (0);
+ goto done;
+ }
+ if (fchar == ']')
+ break;
+ fchar = *fmt++;
+ }
+ /*FALLTHRU*/
+ case 'c': /* characters */
+ case 's': /* string of non-whitespace */
+ case 'p': /* pointer */
+ libc_type:
+ len = fmt - this_fmt;
+ memcpy (alloc_fmt, this_fmt, len);
+ alloc_fmt[len++] = '%';
+ alloc_fmt[len++] = 'n';
+ alloc_fmt[len] = '\0';
+
+ TRACE (printf (" scan \"%s\"\n", alloc_fmt);
+ if (funs->scan == (gmp_doscan_scan_t) sscanf)
+ printf (" s=\"%s\"\n", * (const char **) data));
+
+ new_chars = -1;
+ if (param.ignore)
+ {
+ new_fields = (*funs->scan) (data, alloc_fmt, &new_chars, NULL);
+ ASSERT (new_fields == 0 || new_fields == EOF);
+ }
+ else
+ {
+ void *arg = va_arg (ap, void *);
+ new_fields = (*funs->scan) (data, alloc_fmt, arg, &new_chars);
+ ASSERT (new_fields==0 || new_fields==1 || new_fields==EOF);
+
+ if (new_fields == 0)
+ goto done; /* invalid input */
+
+ if (new_fields == 1)
+ ASSERT (new_chars != -1);
+ }
+ TRACE (printf (" new_fields %d new_chars %d\n",
+ new_fields, new_chars));
+
+ if (new_fields == -1)
+ goto eof_no_match; /* EOF before anything matched */
+
+ /* Under param.ignore, when new_fields==0 we don't know if
+ it's a successful match or an invalid field. new_chars
+ won't have been assigned if it was an invalid field. */
+ if (new_chars == -1)
+ goto done; /* invalid input */
+
+ chars += new_chars;
+ (*funs->step) (data, new_chars);
+
+ increment_fields:
+ if (! param.ignore)
+ fields++;
+ goto next;
+
+ case 'd': /* decimal */
+ case 'u': /* decimal */
+ param.base = 10;
+ goto numeric;
+
+ case 'e': /* float */
+ case 'E': /* float */
+ case 'f': /* float */
+ case 'g': /* float */
+ case 'G': /* float */
+ case 'i': /* integer with base marker */
+ numeric:
+ if (param.type != 'F' && param.type != 'Q' && param.type != 'Z')
+ goto libc_type;
+
+ chars += skip_white (funs, data);
+
+ new_chars = gmpscan (funs, data, &param,
+ param.ignore ? NULL : va_arg (ap, void*));
+ if (new_chars == -2)
+ goto eof_no_match;
+ if (new_chars == -1)
+ goto done;
+
+ ASSERT (new_chars >= 0);
+ chars += new_chars;
+ goto increment_fields;
+
+ case 'a': /* glibc allocate string */
+ case '\'': /* glibc digit groupings */
+ break;
+
+ case 'F': /* mpf_t */
+ case 'j': /* intmax_t */
+ case 'L': /* long long */
+ case 'q': /* quad_t */
+ case 'Q': /* mpq_t */
+ case 't': /* ptrdiff_t */
+ case 'z': /* size_t */
+ case 'Z': /* mpz_t */
+ set_type:
+ param.type = fchar;
+ break;
+
+ case 'h': /* short or char */
+ if (param.type != 'h')
+ goto set_type;
+ param.type = 'H'; /* internal code for "hh" */
+ break;
+
+ goto numeric;
+
+ case 'l': /* long, long long, double or long double */
+ if (param.type != 'l')
+ goto set_type;
+ param.type = 'L'; /* "ll" means "L" */
+ break;
+
+ case 'n':
+ if (! param.ignore)
+ {
+ void *p;
+ p = va_arg (ap, void *);
+ TRACE (printf (" store %%n to %p\n", p));
+ switch (param.type) {
+ case '\0': * (int *) p = chars; break;
+ case 'F': mpf_set_si ((mpf_ptr) p, (long) chars); break;
+ case 'H': * (char *) p = chars; break;
+ case 'h': * (short *) p = chars; break;
+#if HAVE_INTMAX_T
+ case 'j': * (intmax_t *) p = chars; break;
+#else
+ case 'j': ASSERT_FAIL (intmax_t not available); break;
+#endif
+ case 'l': * (long *) p = chars; break;
+#if HAVE_QUAD_T && HAVE_LONG_LONG
+ case 'q':
+ ASSERT_ALWAYS (sizeof (quad_t) == sizeof (long long));
+ /*FALLTHRU*/
+#else
+ case 'q': ASSERT_FAIL (quad_t not available); break;
+#endif
+#if HAVE_LONG_LONG
+ case 'L': * (long long *) p = chars; break;
+#else
+ case 'L': ASSERT_FAIL (long long not available); break;
+#endif
+ case 'Q': mpq_set_si ((mpq_ptr) p, (long) chars, 1L); break;
+#if HAVE_PTRDIFF_T
+ case 't': * (ptrdiff_t *) p = chars; break;
+#else
+ case 't': ASSERT_FAIL (ptrdiff_t not available); break;
+#endif
+ case 'z': * (size_t *) p = chars; break;
+ case 'Z': mpz_set_si ((mpz_ptr) p, (long) chars); break;
+ default: ASSERT (0); break;
+ }
+ }
+ goto next;
+
+ case 'o':
+ param.base = 8;
+ goto numeric;
+
+ case 'x':
+ case 'X':
+ param.base = 16;
+ goto numeric;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ param.width = 0;
+ do {
+ param.width = param.width * 10 + (fchar-'0');
+ fchar = *fmt++;
+ } while (isdigit (fchar));
+ fmt--; /* unget the non-digit */
+ break;
+
+ case '*':
+ param.ignore = 1;
+ break;
+
+ default:
+ /* something invalid in a % sequence */
+ ASSERT (0);
+ goto next;
+ }
+ }
+ }
+
+ done:
+ (*__gmp_free_func) (alloc_fmt, alloc_fmt_size);
+ return fields;
+}
diff --git a/gmp/scanf/fscanf.c b/gmp/scanf/fscanf.c
new file mode 100644
index 0000000000..83f46169ed
--- /dev/null
+++ b/gmp/scanf/fscanf.c
@@ -0,0 +1,48 @@
+/* gmp_fscanf -- formatted input from a FILE.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_fscanf (FILE *fp, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+ va_start (ap, fmt);
+
+ ret = __gmp_doscan (&__gmp_fscanf_funs, fp, fmt, ap);
+ va_end (ap);
+ return ret;
+}
diff --git a/gmp/scanf/fscanffuns.c b/gmp/scanf/fscanffuns.c
new file mode 100644
index 0000000000..396e9a175f
--- /dev/null
+++ b/gmp/scanf/fscanffuns.c
@@ -0,0 +1,62 @@
+/* __gmp_fscanf_funs -- support for formatted input from a FILE.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* SunOS 4 stdio.h doesn't provide prototypes for these */
+#if ! HAVE_DECL_FGETC
+int fgetc (FILE *);
+#endif
+#if ! HAVE_DECL_FSCANF
+int fscanf (FILE *, const char *, ...);
+#endif
+#if ! HAVE_DECL_UNGETC
+int ungetc (int, FILE *);
+#endif
+
+
+static void
+step (FILE *fp, int n)
+{
+}
+
+const struct gmp_doscan_funs_t __gmp_fscanf_funs = {
+ (gmp_doscan_scan_t) fscanf,
+ (gmp_doscan_step_t) step,
+ (gmp_doscan_get_t) fgetc,
+ (gmp_doscan_unget_t) ungetc,
+};
diff --git a/gmp/scanf/scanf.c b/gmp/scanf/scanf.c
new file mode 100644
index 0000000000..a944a7c029
--- /dev/null
+++ b/gmp/scanf/scanf.c
@@ -0,0 +1,48 @@
+/* gmp_scanf -- formatted input from stdin.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_scanf (const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+ va_start (ap, fmt);
+
+ ret = __gmp_doscan (&__gmp_fscanf_funs, stdin, fmt, ap);
+ va_end (ap);
+ return ret;
+}
diff --git a/gmp/scanf/sscanf.c b/gmp/scanf/sscanf.c
new file mode 100644
index 0000000000..b3d12dcda6
--- /dev/null
+++ b/gmp/scanf/sscanf.c
@@ -0,0 +1,53 @@
+/* gmp_sscanf -- formatted input from a string.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_sscanf (const char *s, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+ va_start (ap, fmt);
+
+#if SSCANF_WRITABLE_INPUT
+ /* let gmp_vsscanf handle the copying */
+ ret = gmp_vsscanf (s, fmt, ap);
+#else
+ ret = __gmp_doscan (&__gmp_sscanf_funs, (void *) &s, fmt, ap);
+#endif
+ va_end (ap);
+ return ret;
+}
diff --git a/gmp/scanf/sscanffuns.c b/gmp/scanf/sscanffuns.c
new file mode 100644
index 0000000000..ed5bdf57d3
--- /dev/null
+++ b/gmp/scanf/sscanffuns.c
@@ -0,0 +1,124 @@
+/* __gmp_sscanf_funs -- support for formatted input from a string.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE GNU MP RELEASES.
+
+Copyright 2001-2003, 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+#if 0
+static int
+scan (const char **sp, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vsscanf(*sp, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+#else
+static int
+scan (const char **sp, const char *fmt, ...)
+{
+ va_list ap;
+ void *p1, *p2;
+ int ret;
+
+ va_start (ap, fmt);
+ p1 = va_arg (ap, void *);
+ p2 = va_arg (ap, void *);
+
+ ret = sscanf (*sp, fmt, p1, p2);
+
+ va_end (ap);
+
+ return ret;
+}
+#endif
+
+static void
+step (const char **sp, int n)
+{
+ ASSERT (n >= 0);
+
+ /* shouldn't push us past the end of the string */
+#if WANT_ASSERT
+ {
+ int i;
+ for (i = 0; i < n; i++)
+ ASSERT ((*sp)[i] != '\0');
+ }
+#endif
+
+ (*sp) += n;
+}
+
+static int
+get (const char **sp)
+{
+ const char *s;
+ int c;
+ s = *sp;
+ c = (unsigned char) *s++;
+ if (c == '\0')
+ return EOF;
+ *sp = s;
+ return c;
+}
+
+static void
+unget (int c, const char **sp)
+{
+ const char *s;
+ s = *sp;
+ if (c == EOF)
+ {
+ ASSERT (*s == '\0');
+ return;
+ }
+ s--;
+ ASSERT ((unsigned char) *s == c);
+ *sp = s;
+}
+
+const struct gmp_doscan_funs_t __gmp_sscanf_funs = {
+ (gmp_doscan_scan_t) scan,
+ (gmp_doscan_step_t) step,
+ (gmp_doscan_get_t) get,
+ (gmp_doscan_unget_t) unget,
+};
diff --git a/gmp/scanf/vfscanf.c b/gmp/scanf/vfscanf.c
new file mode 100644
index 0000000000..8011b55754
--- /dev/null
+++ b/gmp/scanf/vfscanf.c
@@ -0,0 +1,42 @@
+/* gmp_vfscanf -- formatted input from a FILE.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_vfscanf (FILE *fp, const char *fmt, va_list ap)
+{
+ return __gmp_doscan (&__gmp_fscanf_funs, fp, fmt, ap);
+}
diff --git a/gmp/scanf/vscanf.c b/gmp/scanf/vscanf.c
new file mode 100644
index 0000000000..51feebf72e
--- /dev/null
+++ b/gmp/scanf/vscanf.c
@@ -0,0 +1,43 @@
+/* gmp_vscanf -- formatted input from stdin.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_vscanf (const char *fmt, va_list ap)
+{
+ return __gmp_doscan (&__gmp_fscanf_funs, stdin, fmt, ap);
+}
diff --git a/gmp/scanf/vsscanf.c b/gmp/scanf/vsscanf.c
new file mode 100644
index 0000000000..6fb043dce2
--- /dev/null
+++ b/gmp/scanf/vsscanf.c
@@ -0,0 +1,61 @@
+/* gmp_vsscanf -- formatted input from a string.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdarg.h>
+
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+int
+gmp_vsscanf (const char *s, const char *fmt, va_list ap)
+{
+#if SSCANF_WRITABLE_INPUT
+ /* We only actually need this if there's standard C types in fmt, and if
+ "s" is not already writable, but it's too much trouble to check that,
+ and in any case this writable sscanf input business is only for a few
+ old systems. */
+ size_t size;
+ char *alloc;
+ int ret;
+ size = strlen (s) + 1;
+ alloc = (char *) (*__gmp_allocate_func) (size);
+ memcpy (alloc, s, size);
+ s = alloc;
+ ret = __gmp_doscan (&__gmp_sscanf_funs, (void *) &s, fmt, ap);
+ (*__gmp_free_func) (alloc, size);
+ return ret;
+
+#else
+ return __gmp_doscan (&__gmp_sscanf_funs, (void *) &s, fmt, ap);
+#endif
+}
diff --git a/gmp/tal-debug.c b/gmp/tal-debug.c
new file mode 100644
index 0000000000..35912af360
--- /dev/null
+++ b/gmp/tal-debug.c
@@ -0,0 +1,151 @@
+/* TMP_ALLOC routines for debugging.
+
+Copyright 2000, 2001, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* This method aims to help a malloc debugger find problems. A linked list
+ of allocated block is kept for TMP_FREE to release. This is reentrant
+ and thread safe.
+
+ Each TMP_ALLOC is a separate malloced block, so redzones or sentinels
+ applied by a malloc debugger either above or below can guard against
+ accesses outside the allocated area.
+
+ A marker is a "struct tmp_debug_t *" so that TMP_DECL can initialize it
+ to NULL and we can detect TMP_ALLOC without TMP_MARK.
+
+ It will work to realloc an MPZ_TMP_INIT variable, but when TMP_FREE comes
+ to release the memory it will have the old size, thereby triggering an
+ error from tests/memory.c.
+
+ Possibilities:
+
+ It'd be possible to keep a global list of active "struct tmp_debug_t"
+ records, so at the end of a program any TMP leaks could be printed. But
+ if only a couple of routines are under test at any one time then the
+ likely culprit should be easy enough to spot. */
+
+
+void
+__gmp_tmp_debug_mark (const char *file, int line,
+ struct tmp_debug_t **markp, struct tmp_debug_t *mark,
+ const char *decl_name, const char *mark_name)
+{
+ if (strcmp (mark_name, decl_name) != 0)
+ {
+ __gmp_assert_header (file, line);
+ fprintf (stderr, "GNU MP: TMP_MARK(%s) but TMP_DECL(%s) is in scope\n",
+ mark_name, decl_name);
+ abort ();
+ }
+
+ if (*markp != NULL)
+ {
+ __gmp_assert_header (file, line);
+ fprintf (stderr, "GNU MP: Repeat of TMP_MARK(%s)\n", mark_name);
+ if (mark->file != NULL && mark->file[0] != '\0' && mark->line != -1)
+ {
+ __gmp_assert_header (mark->file, mark->line);
+ fprintf (stderr, "previous was here\n");
+ }
+ abort ();
+ }
+
+ *markp = mark;
+ mark->file = file;
+ mark->line = line;
+ mark->list = NULL;
+}
+
+void *
+__gmp_tmp_debug_alloc (const char *file, int line, int dummy,
+ struct tmp_debug_t **markp,
+ const char *decl_name, size_t size)
+{
+ struct tmp_debug_t *mark = *markp;
+ struct tmp_debug_entry_t *p;
+
+ ASSERT_ALWAYS (size >= 1);
+
+ if (mark == NULL)
+ {
+ __gmp_assert_header (file, line);
+ fprintf (stderr, "GNU MP: TMP_ALLOC without TMP_MARK(%s)\n", decl_name);
+ abort ();
+ }
+
+ p = __GMP_ALLOCATE_FUNC_TYPE (1, struct tmp_debug_entry_t);
+ p->size = size;
+ p->block = (*__gmp_allocate_func) (size);
+ p->next = mark->list;
+ mark->list = p;
+ return p->block;
+}
+
+void
+__gmp_tmp_debug_free (const char *file, int line, int dummy,
+ struct tmp_debug_t **markp,
+ const char *decl_name, const char *free_name)
+{
+ struct tmp_debug_t *mark = *markp;
+ struct tmp_debug_entry_t *p, *next;
+
+ if (mark == NULL)
+ {
+ __gmp_assert_header (file, line);
+ fprintf (stderr, "GNU MP: TMP_FREE(%s) without TMP_MARK(%s)\n",
+ free_name, decl_name);
+ abort ();
+ }
+
+ if (strcmp (free_name, decl_name) != 0)
+ {
+ __gmp_assert_header (file, line);
+ fprintf (stderr, "GNU MP: TMP_FREE(%s) when TMP_DECL(%s) is in scope\n",
+ free_name, decl_name);
+ abort ();
+ }
+
+ p = mark->list;
+ while (p != NULL)
+ {
+ next = p->next;
+ (*__gmp_free_func) (p->block, p->size);
+ __GMP_FREE_FUNC_TYPE (p, 1, struct tmp_debug_entry_t);
+ p = next;
+ }
+
+ *markp = NULL;
+}
diff --git a/gmp/tal-notreent.c b/gmp/tal-notreent.c
new file mode 100644
index 0000000000..ed162e552b
--- /dev/null
+++ b/gmp/tal-notreent.c
@@ -0,0 +1,130 @@
+/* Stack allocation routines. This is intended for machines without support
+ for the `alloca' function.
+
+Copyright 1996, 1997, 1999-2001, 2006 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+struct tmp_stack
+{
+ void *end;
+ void *alloc_point;
+ struct tmp_stack *prev;
+};
+typedef struct tmp_stack tmp_stack;
+
+
+static unsigned long max_total_allocation = 0;
+static unsigned long current_total_allocation = 0;
+
+static tmp_stack xxx = {&xxx, &xxx, 0};
+static tmp_stack *current = &xxx;
+
+/* The rounded size of the header of each allocation block. */
+#define HSIZ ROUND_UP_MULTIPLE (sizeof (tmp_stack), __TMP_ALIGN)
+
+
+/* Allocate a block of exactly <size> bytes. This should only be called
+ through the TMP_ALLOC macro, which takes care of rounding/alignment. */
+void *
+__gmp_tmp_alloc (unsigned long size)
+{
+ void *that;
+
+ ASSERT ((size % __TMP_ALIGN) == 0);
+ ASSERT (((unsigned) current->alloc_point % __TMP_ALIGN) == 0);
+
+ if (size > (char *) current->end - (char *) current->alloc_point)
+ {
+ void *chunk;
+ tmp_stack *header;
+ unsigned long chunk_size;
+ unsigned long now;
+
+ /* Allocate a chunk that makes the total current allocation somewhat
+ larger than the maximum allocation ever. If size is very large, we
+ allocate that much. */
+
+ now = current_total_allocation + size;
+ if (now > max_total_allocation)
+ {
+ /* We need more temporary memory than ever before. Increase
+ for future needs. */
+ now = (now * 3 / 2 + __TMP_ALIGN - 1) & -__TMP_ALIGN;
+ chunk_size = now - current_total_allocation + HSIZ;
+ current_total_allocation = now;
+ max_total_allocation = current_total_allocation;
+ }
+ else
+ {
+ chunk_size = max_total_allocation - current_total_allocation + HSIZ;
+ current_total_allocation = max_total_allocation;
+ }
+
+ chunk = (*__gmp_allocate_func) (chunk_size);
+ header = (tmp_stack *) chunk;
+ header->end = (char *) chunk + chunk_size;
+ header->alloc_point = (char *) chunk + HSIZ;
+ header->prev = current;
+ current = header;
+ }
+
+ that = current->alloc_point;
+ current->alloc_point = (char *) that + size;
+ ASSERT (((unsigned) that % __TMP_ALIGN) == 0);
+ return that;
+}
+
+/* Typically called at function entry. <mark> is assigned so that
+ __gmp_tmp_free can later be used to reclaim all subsequently allocated
+ storage. */
+void
+__gmp_tmp_mark (struct tmp_marker *mark)
+{
+ mark->which_chunk = current;
+ mark->alloc_point = current->alloc_point;
+}
+
+/* Free everything allocated since <mark> was assigned by __gmp_tmp_mark */
+void
+__gmp_tmp_free (struct tmp_marker *mark)
+{
+ while (mark->which_chunk != current)
+ {
+ tmp_stack *tmp;
+
+ tmp = current;
+ current = tmp->prev;
+ current_total_allocation -= (((char *) (tmp->end) - (char *) tmp) - HSIZ);
+ (*__gmp_free_func) (tmp, (char *) tmp->end - (char *) tmp);
+ }
+ current->alloc_point = mark->alloc_point;
+}
diff --git a/gmp/tal-reent.c b/gmp/tal-reent.c
new file mode 100644
index 0000000000..92f516b5ff
--- /dev/null
+++ b/gmp/tal-reent.c
@@ -0,0 +1,82 @@
+/* TMP_ALLOC routines using malloc in a reentrant fashion.
+
+Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+
+/* Each TMP_ALLOC uses __gmp_allocate_func to get a block of memory of the
+ size requested, plus a header at the start which is used to hold the
+ blocks on a linked list in the marker variable, ready for TMP_FREE to
+ release.
+
+ Callers should try to do multiple allocs with one call, in the style of
+ TMP_ALLOC_LIMBS_2 if it's easy to arrange, since that will keep down the
+ number of separate malloc calls.
+
+ Enhancements:
+
+ Could inline both TMP_ALLOC and TMP_FREE, though TMP_ALLOC would need the
+ compiler to have "inline" since it returns a value. The calls to malloc
+ will be slow though, so it hardly seems worth worrying about one extra
+ level of function call. */
+
+
+#define HSIZ ROUND_UP_MULTIPLE (sizeof (struct tmp_reentrant_t), __TMP_ALIGN)
+
+void *
+__gmp_tmp_reentrant_alloc (struct tmp_reentrant_t **markp, size_t size)
+{
+ char *p;
+ size_t total_size;
+
+#define P ((struct tmp_reentrant_t *) p)
+
+ total_size = size + HSIZ;
+ p = (char *) (*__gmp_allocate_func) (total_size);
+ P->size = total_size;
+ P->next = *markp;
+ *markp = P;
+ return p + HSIZ;
+}
+
+void
+__gmp_tmp_reentrant_free (struct tmp_reentrant_t *mark)
+{
+ struct tmp_reentrant_t *next;
+
+ while (mark != NULL)
+ {
+ next = mark->next;
+ (*__gmp_free_func) ((char *) mark, mark->size);
+ mark = next;
+ }
+}
diff --git a/gmp/tests/Makefile.am b/gmp/tests/Makefile.am
new file mode 100644
index 0000000000..aa3c6c579f
--- /dev/null
+++ b/gmp/tests/Makefile.am
@@ -0,0 +1,39 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2000-2004, 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/.
+
+
+SUBDIRS = . devel mpn mpz mpq mpf rand misc cxx
+
+include ../mpn/Makeasm.am
+
+INCLUDES = -I$(top_srcdir)
+LDADD = libtests.la $(top_builddir)/libgmp.la
+
+check_LTLIBRARIES = libtests.la
+
+EXTRA_libtests_la_SOURCES = amd64call.asm amd64check.c x86call.asm x86check.c \
+ arm32call.asm arm32check.c
+libtests_la_SOURCES = tests.h \
+ memory.c misc.c refmpf.c refmpn.c refmpq.c refmpz.c spinner.c trace.c
+libtests_la_DEPENDENCIES = @CALLING_CONVENTIONS_OBJS@
+libtests_la_LIBADD = $(libtests_la_DEPENDENCIES) $(top_builddir)/libgmp.la
+
+check_PROGRAMS = t-bswap t-constants t-count_zeros t-gmpmax t-hightomask \
+ t-modlinv t-popc t-parity t-sub
+TESTS = $(check_PROGRAMS)
diff --git a/gmp/tests/Makefile.in b/gmp/tests/Makefile.in
new file mode 100644
index 0000000000..28ff1f4522
--- /dev/null
+++ b/gmp/tests/Makefile.in
@@ -0,0 +1,992 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2000-2004, 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/.
+
+# Copyright 1996, 1998-2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+DIST_COMMON = $(srcdir)/../mpn/Makeasm.am $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+check_PROGRAMS = t-bswap$(EXEEXT) t-constants$(EXEEXT) \
+ t-count_zeros$(EXEEXT) t-gmpmax$(EXEEXT) t-hightomask$(EXEEXT) \
+ t-modlinv$(EXEEXT) t-popc$(EXEEXT) t-parity$(EXEEXT) \
+ t-sub$(EXEEXT)
+subdir = tests
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__DEPENDENCIES_1 =
+am_libtests_la_OBJECTS = memory.lo misc.lo refmpf.lo refmpn.lo \
+ refmpq.lo refmpz.lo spinner.lo trace.lo
+libtests_la_OBJECTS = $(am_libtests_la_OBJECTS)
+t_bswap_SOURCES = t-bswap.c
+t_bswap_OBJECTS = t-bswap.$(OBJEXT)
+t_bswap_LDADD = $(LDADD)
+t_bswap_DEPENDENCIES = libtests.la $(top_builddir)/libgmp.la
+t_constants_SOURCES = t-constants.c
+t_constants_OBJECTS = t-constants.$(OBJEXT)
+t_constants_LDADD = $(LDADD)
+t_constants_DEPENDENCIES = libtests.la $(top_builddir)/libgmp.la
+t_count_zeros_SOURCES = t-count_zeros.c
+t_count_zeros_OBJECTS = t-count_zeros.$(OBJEXT)
+t_count_zeros_LDADD = $(LDADD)
+t_count_zeros_DEPENDENCIES = libtests.la $(top_builddir)/libgmp.la
+t_gmpmax_SOURCES = t-gmpmax.c
+t_gmpmax_OBJECTS = t-gmpmax.$(OBJEXT)
+t_gmpmax_LDADD = $(LDADD)
+t_gmpmax_DEPENDENCIES = libtests.la $(top_builddir)/libgmp.la
+t_hightomask_SOURCES = t-hightomask.c
+t_hightomask_OBJECTS = t-hightomask.$(OBJEXT)
+t_hightomask_LDADD = $(LDADD)
+t_hightomask_DEPENDENCIES = libtests.la $(top_builddir)/libgmp.la
+t_modlinv_SOURCES = t-modlinv.c
+t_modlinv_OBJECTS = t-modlinv.$(OBJEXT)
+t_modlinv_LDADD = $(LDADD)
+t_modlinv_DEPENDENCIES = libtests.la $(top_builddir)/libgmp.la
+t_parity_SOURCES = t-parity.c
+t_parity_OBJECTS = t-parity.$(OBJEXT)
+t_parity_LDADD = $(LDADD)
+t_parity_DEPENDENCIES = libtests.la $(top_builddir)/libgmp.la
+t_popc_SOURCES = t-popc.c
+t_popc_OBJECTS = t-popc.$(OBJEXT)
+t_popc_LDADD = $(LDADD)
+t_popc_DEPENDENCIES = libtests.la $(top_builddir)/libgmp.la
+t_sub_SOURCES = t-sub.c
+t_sub_OBJECTS = t-sub.$(OBJEXT)
+t_sub_LDADD = $(LDADD)
+t_sub_DEPENDENCIES = libtests.la $(top_builddir)/libgmp.la
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libtests_la_SOURCES) $(EXTRA_libtests_la_SOURCES) \
+ t-bswap.c t-constants.c t-count_zeros.c t-gmpmax.c \
+ t-hightomask.c t-modlinv.c t-parity.c t-popc.c t-sub.c
+DIST_SOURCES = $(libtests_la_SOURCES) $(EXTRA_libtests_la_SOURCES) \
+ t-bswap.c t-constants.c t-count_zeros.c t-gmpmax.c \
+ t-hightomask.c t-modlinv.c t-parity.c t-popc.c t-sub.c
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+SUBDIRS = . devel mpn mpz mpq mpf rand misc cxx
+
+# COMPILE minus CC.
+#
+COMPILE_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASMFLAGS)
+
+
+# Flags used for preprocessing (in ansi2knr rules).
+#
+PREPROCESS_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS)
+
+
+# Recent versions of automake (1.5 and up for instance) append automake
+# generated suffixes to this $(SUFFIXES) list. This is essential for us,
+# since .c must come after .s, .S and .asm. If .c is before .s, for
+# instance, then in the mpn directory "make" will see add_n.c mentioned in
+# an explicit rule (the ansi2knr stuff) and decide it must have add_n.c,
+# even if add_n.c doesn't exist but add_n.s does. See GNU make
+# documentation "(make)Implicit Rule Search", part 5c.
+#
+# On IRIX 6 native make this doesn't work properly though. Somehow .c
+# remains ahead of .s, perhaps because .c.s is a builtin rule. .asm works
+# fine though, and mpn/mips3 uses this.
+#
+SUFFIXES = .s .S .asm
+
+# can be overridden during development, eg. "make RM_TMP=: mul_1.lo"
+RM_TMP = rm -f
+INCLUDES = -I$(top_srcdir)
+LDADD = libtests.la $(top_builddir)/libgmp.la
+check_LTLIBRARIES = libtests.la
+EXTRA_libtests_la_SOURCES = amd64call.asm amd64check.c x86call.asm x86check.c \
+ arm32call.asm arm32check.c
+
+libtests_la_SOURCES = tests.h \
+ memory.c misc.c refmpf.c refmpn.c refmpq.c refmpz.c spinner.c trace.c
+
+libtests_la_DEPENDENCIES = @CALLING_CONVENTIONS_OBJS@
+libtests_la_LIBADD = $(libtests_la_DEPENDENCIES) $(top_builddir)/libgmp.la
+TESTS = $(check_PROGRAMS)
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .s .S .asm .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../mpn/Makeasm.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/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps tests/Makefile
+.PRECIOUS: 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;
+$(srcdir)/../mpn/Makeasm.am:
+
+$(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-checkLTLIBRARIES:
+ -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
+ @list='$(check_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libtests.la: $(libtests_la_OBJECTS) $(libtests_la_DEPENDENCIES) $(EXTRA_libtests_la_DEPENDENCIES)
+ $(LINK) $(libtests_la_OBJECTS) $(libtests_la_LIBADD) $(LIBS)
+
+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-bswap$(EXEEXT): $(t_bswap_OBJECTS) $(t_bswap_DEPENDENCIES) $(EXTRA_t_bswap_DEPENDENCIES)
+ @rm -f t-bswap$(EXEEXT)
+ $(LINK) $(t_bswap_OBJECTS) $(t_bswap_LDADD) $(LIBS)
+t-constants$(EXEEXT): $(t_constants_OBJECTS) $(t_constants_DEPENDENCIES) $(EXTRA_t_constants_DEPENDENCIES)
+ @rm -f t-constants$(EXEEXT)
+ $(LINK) $(t_constants_OBJECTS) $(t_constants_LDADD) $(LIBS)
+t-count_zeros$(EXEEXT): $(t_count_zeros_OBJECTS) $(t_count_zeros_DEPENDENCIES) $(EXTRA_t_count_zeros_DEPENDENCIES)
+ @rm -f t-count_zeros$(EXEEXT)
+ $(LINK) $(t_count_zeros_OBJECTS) $(t_count_zeros_LDADD) $(LIBS)
+t-gmpmax$(EXEEXT): $(t_gmpmax_OBJECTS) $(t_gmpmax_DEPENDENCIES) $(EXTRA_t_gmpmax_DEPENDENCIES)
+ @rm -f t-gmpmax$(EXEEXT)
+ $(LINK) $(t_gmpmax_OBJECTS) $(t_gmpmax_LDADD) $(LIBS)
+t-hightomask$(EXEEXT): $(t_hightomask_OBJECTS) $(t_hightomask_DEPENDENCIES) $(EXTRA_t_hightomask_DEPENDENCIES)
+ @rm -f t-hightomask$(EXEEXT)
+ $(LINK) $(t_hightomask_OBJECTS) $(t_hightomask_LDADD) $(LIBS)
+t-modlinv$(EXEEXT): $(t_modlinv_OBJECTS) $(t_modlinv_DEPENDENCIES) $(EXTRA_t_modlinv_DEPENDENCIES)
+ @rm -f t-modlinv$(EXEEXT)
+ $(LINK) $(t_modlinv_OBJECTS) $(t_modlinv_LDADD) $(LIBS)
+t-parity$(EXEEXT): $(t_parity_OBJECTS) $(t_parity_DEPENDENCIES) $(EXTRA_t_parity_DEPENDENCIES)
+ @rm -f t-parity$(EXEEXT)
+ $(LINK) $(t_parity_OBJECTS) $(t_parity_LDADD) $(LIBS)
+t-popc$(EXEEXT): $(t_popc_OBJECTS) $(t_popc_DEPENDENCIES) $(EXTRA_t_popc_DEPENDENCIES)
+ @rm -f t-popc$(EXEEXT)
+ $(LINK) $(t_popc_OBJECTS) $(t_popc_LDADD) $(LIBS)
+t-sub$(EXEEXT): $(t_sub_OBJECTS) $(t_sub_DEPENDENCIES) $(EXTRA_t_sub_DEPENDENCIES)
+ @rm -f t-sub$(EXEEXT)
+ $(LINK) $(t_sub_OBJECTS) $(t_sub_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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:
+
+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-recursive
+
+clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \
+ ctags-recursive install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-TESTS check-am clean \
+ clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \
+ clean-libtool ctags ctags-recursive 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 \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am
+
+
+# .s assembler, no preprocessing.
+#
+.s.o:
+ $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+.s.obj:
+ $(CCAS) $(COMPILE_FLAGS) `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+.s.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+# .S assembler, preprocessed with cpp.
+#
+# It's necessary to run $(CPP) separately, since it seems not all compilers
+# recognise .S files, in particular "cc" on HP-UX 10 and 11 doesn't (and
+# will silently do nothing if given a .S).
+#
+# For .lo we need a helper script, as described below for .asm.lo.
+#
+.S.o:
+ $(CPP) $(PREPROCESS_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$< | grep -v '^#' >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.S.obj:
+ $(CPP) $(PREPROCESS_FLAGS) `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` | grep -v '^#' >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.S.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(top_srcdir)/mpn/cpp-ccas --cpp="$(CPP) $(PREPROCESS_FLAGS)" $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+# .asm assembler, preprocessed with m4.
+#
+# .o and .obj are non-PIC and just need m4 followed by a compile.
+#
+# .lo is a bit tricky. Libtool (as of version 1.5) has foo.lo as a little
+# text file, and .libs/foo.o and foo.o as the PIC and non-PIC objects,
+# respectively. It'd be asking for lots of trouble to try to create foo.lo
+# ourselves, so instead arrange to invoke libtool like a --mode=compile, but
+# with a special m4-ccas script which first m4 preprocesses, then compiles.
+# --tag=CC is necessary since foo.asm is otherwise unknown to libtool.
+#
+# Libtool adds -DPIC when building a shared object and the .asm files look
+# for that. But it should be noted that the other PIC flags are on occasion
+# important too, in particular FreeBSD 2.2.8 gas 1.92.3 requires -k before
+# it accepts PIC constructs like @GOT, and gcc adds that flag only under
+# -fPIC. (Later versions of gas are happy to accept PIC stuff any time.)
+#
+.asm.o:
+ $(M4) -DOPERATION_$* `test -f '$<' || echo '$(srcdir)/'`$< >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.asm.obj:
+ $(M4) -DOPERATION_$* `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.asm.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(top_srcdir)/mpn/m4-ccas --m4="$(M4)" $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+# 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/gmp/tests/amd64call.asm b/gmp/tests/amd64call.asm
new file mode 100644
index 0000000000..dad7763028
--- /dev/null
+++ b/gmp/tests/amd64call.asm
@@ -0,0 +1,167 @@
+dnl AMD64 calling conventions checking.
+
+dnl Copyright 2000, 2003, 2004, 2006, 2007, 2010 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library test suite.
+
+dnl The GNU MP Library test suite is free software; you can redistribute it
+dnl and/or modify it under the terms of the GNU General Public License as
+dnl published by the Free Software Foundation; either version 3 of the
+dnl License, or (at your option) any later version.
+
+dnl The GNU MP Library test suite is distributed in the hope that it will be
+dnl useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+dnl Public License for more details.
+
+dnl You should have received a copy of the GNU General Public License along
+dnl with the GNU MP Library test suite. If not, see
+dnl https://www.gnu.org/licenses/.
+
+
+dnl The current version of the code attempts to keep the call/return
+dnl prediction stack valid, but matching calls and returns.
+
+include(`../config.m4')
+
+
+C void x86_fldcw (unsigned short cw);
+C
+C Execute an fldcw, setting the x87 control word to cw.
+
+PROLOGUE(x86_fldcw)
+ mov %rdi, -8(%rsp)
+ fldcw -8(%rsp)
+ ret
+EPILOGUE()
+
+
+C unsigned short x86_fstcw (void);
+C
+C Execute an fstcw, returning the current x87 control word.
+
+PROLOGUE(x86_fstcw)
+ movq $0, -8(%rsp)
+ fstcw -8(%rsp)
+ mov -8(%rsp), %rax
+ ret
+EPILOGUE()
+
+
+dnl Instrumented profiling won't come out quite right below, since we don't do
+dnl an actual "ret". There's only a few instructions here, so there's no
+dnl great need to get them separately accounted, just let them get attributed
+dnl to the caller. FIXME this comment might no longer be true.
+
+ifelse(WANT_PROFILING,instrument,
+`define(`WANT_PROFILING',no)')
+
+
+C int calling_conventions (...);
+C
+C The global variable "calling_conventions_function" is the function to
+C call, with the arguments as passed here.
+C
+C Perhaps the finit should be done only if the tags word isn't clear, but
+C nothing uses the rounding mode or anything at the moment.
+
+define(`WANT_RBX', eval(8*0)($1))
+define(`WANT_RBP', eval(8*1)($1))
+define(`WANT_R12', eval(8*2)($1))
+define(`WANT_R13', eval(8*3)($1))
+define(`WANT_R14', eval(8*4)($1))
+define(`WANT_R15', eval(8*5)($1))
+
+define(`JUNK_RAX', eval(8*6)($1))
+define(`JUNK_R10', eval(8*7)($1))
+define(`JUNK_R11', eval(8*8)($1))
+
+define(`SAVE_RBX', eval(8*9)($1))
+define(`SAVE_RBP', eval(8*10)($1))
+define(`SAVE_R12', eval(8*11)($1))
+define(`SAVE_R13', eval(8*12)($1))
+define(`SAVE_R14', eval(8*13)($1))
+define(`SAVE_R15', eval(8*14)($1))
+
+define(`RETADDR', eval(8*15)($1))
+
+define(`RBX', eval(8*16)($1))
+define(`RBP', eval(8*17)($1))
+define(`R12', eval(8*18)($1))
+define(`R13', eval(8*19)($1))
+define(`R14', eval(8*20)($1))
+define(`R15', eval(8*21)($1))
+define(`RFLAGS', eval(8*22)($1))
+
+
+define(G,
+m4_assert_numargs(1)
+`GSYM_PREFIX`'$1')
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(calling_conventions)
+ mov G(calling_conventions_values)@GOTPCREL(%rip), %rax
+ pop RETADDR(%rax)
+
+ mov %rbx, SAVE_RBX(%rax)
+ mov %rbp, SAVE_RBP(%rax)
+ mov %r12, SAVE_R12(%rax)
+ mov %r13, SAVE_R13(%rax)
+ mov %r14, SAVE_R14(%rax)
+ mov %r15, SAVE_R15(%rax)
+
+ C Values we expect to see unchanged, as per amd64check.c
+ mov WANT_RBX(%rax), %rbx
+ mov WANT_RBP(%rax), %rbp
+ mov WANT_R12(%rax), %r12
+ mov WANT_R13(%rax), %r13
+ mov WANT_R14(%rax), %r14
+ mov WANT_R15(%rax), %r15
+
+ C Try to provoke a problem by starting with junk in the caller-saves
+ C registers, especially %rax which will be the return value.
+C mov JUNK_RAX(%rax), %rax C overwritten below anyway
+ mov JUNK_R10(%rax), %r10
+ mov JUNK_R11(%rax), %r11
+
+ mov G(calling_conventions_function)@GOTPCREL(%rip), %rax
+ call *(%rax)
+
+ mov G(calling_conventions_values)@GOTPCREL(%rip), %rcx
+
+ mov %rbx, RBX(%rcx)
+ mov %rbp, RBP(%rcx)
+ mov %r12, R12(%rcx)
+ mov %r13, R13(%rcx)
+ mov %r14, R14(%rcx)
+ mov %r15, R15(%rcx)
+
+ pushf
+ pop %rbx
+ mov %rbx, RFLAGS(%rcx)
+
+ mov SAVE_RBX(%rcx), %rbx
+ mov SAVE_RBP(%rcx), %rbp
+ mov SAVE_R12(%rcx), %r12
+ mov SAVE_R13(%rcx), %r13
+ mov SAVE_R14(%rcx), %r14
+ mov SAVE_R15(%rcx), %r15
+
+ C Overwrite parameter registers
+C mov JUNK_R9(%rcx), %r9
+C mov JUNK_R8(%rcx), %r8
+C mov JUNK_RCX(%rcx), %rcx
+C mov JUNK_RDX(%rcx), %rdx
+C mov JUNK_RSI(%rcx), %rsi
+C mov JUNK_RDI(%rcx), %rdi
+
+ push RETADDR(%rcx)
+
+ mov G(calling_conventions_fenv)@GOTPCREL(%rip), %rcx
+ fstenv (%rcx)
+ finit
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/tests/amd64check.c b/gmp/tests/amd64check.c
new file mode 100644
index 0000000000..1b28d8c7ae
--- /dev/null
+++ b/gmp/tests/amd64check.c
@@ -0,0 +1,106 @@
+/* AMD64 calling conventions checking.
+
+Copyright 2000, 2001, 2004, 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 <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Vector if constants and register values. We use one vector to allow access
+ via a base pointer, very beneficial for the PIC-enabled amd64call.asm. */
+mp_limb_t calling_conventions_values[23] =
+{
+ CNST_LIMB(0x1234567887654321), /* want_rbx */
+ CNST_LIMB(0x89ABCDEFFEDCBA98), /* want_rbp */
+ CNST_LIMB(0xDEADBEEFBADECAFE), /* want_r12 */
+ CNST_LIMB(0xFFEEDDCCBBAA9988), /* want_r13 */
+ CNST_LIMB(0x0011223344556677), /* want_r14 */
+ CNST_LIMB(0x1234432156788765), /* want_r15 */
+
+ CNST_LIMB(0xFEEDABBACAAFBEED), /* JUNK_RAX */
+ CNST_LIMB(0xAB78DE89FF5125BB), /* JUNK_R10 */
+ CNST_LIMB(0x1238901890189031) /* JUNK_R11 */
+
+ /* rest of array used for dynamic values. */
+};
+
+/* Index starts for various regions in above vector. */
+#define WANT 0
+#define JUNK 6
+#define SAVE 9
+#define RETADDR 15
+#define VAL 16
+#define RFLAGS 22
+
+/* values to check */
+struct {
+ int control;
+ int status;
+ int tag;
+ int other[4];
+} calling_conventions_fenv;
+
+
+const char *regname[6] = {"rbx", "rbp", "r12", "r13", "r14", "r15"};
+
+#define DIR_BIT(rflags) (((rflags) & (1<<10)) != 0)
+
+
+/* Return 1 if ok, 0 if not */
+
+int
+calling_conventions_check (void)
+{
+ const char *header = "Violated calling conventions:\n";
+ int ret = 1;
+ int i;
+
+#define CHECK(callreg, regstr, value) \
+ if (callreg != value) \
+ { \
+ printf ("%s %s got 0x%016lX want 0x%016lX\n", \
+ header, regstr, callreg, value); \
+ header = ""; \
+ ret = 0; \
+ }
+
+ for (i = 0; i < 6; i++)
+ {
+ CHECK (calling_conventions_values[VAL+i], regname[i], calling_conventions_values[WANT+i]);
+ }
+
+ if (DIR_BIT (calling_conventions_values[RFLAGS]) != 0)
+ {
+ printf ("%s rflags dir bit got %d want 0\n",
+ header, DIR_BIT (calling_conventions_values[RFLAGS]));
+ header = "";
+ ret = 0;
+ }
+
+ if ((calling_conventions_fenv.tag & 0xFFFF) != 0xFFFF)
+ {
+ printf ("%s fpu tags got 0x%X want 0xFFFF\n",
+ header, calling_conventions_fenv.tag & 0xFFFF);
+ header = "";
+ ret = 0;
+ }
+
+ return ret;
+}
diff --git a/gmp/tests/arm32call.asm b/gmp/tests/arm32call.asm
new file mode 100644
index 0000000000..e689c5a4f0
--- /dev/null
+++ b/gmp/tests/arm32call.asm
@@ -0,0 +1,83 @@
+dnl ARM32 calling conventions checking.
+
+dnl Copyright 2000, 2003, 2004, 2006, 2007, 2010, 2013 Free Software
+dnl Foundation, Inc.
+
+dnl This file is part of the GNU MP Library test suite.
+
+dnl The GNU MP Library test suite is free software; you can redistribute it
+dnl and/or modify it under the terms of the GNU General Public License as
+dnl published by the Free Software Foundation; either version 3 of the
+dnl License, or (at your option) any later version.
+
+dnl The GNU MP Library test suite is distributed in the hope that it will be
+dnl useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+dnl Public License for more details.
+
+dnl You should have received a copy of the GNU General Public License along
+dnl with the GNU MP Library test suite. If not, see
+dnl https://www.gnu.org/licenses/.
+
+
+dnl The current version of the code attempts to keep the call/return
+dnl prediction stack valid, but matching calls and returns.
+
+include(`../config.m4')
+
+
+C int calling_conventions (...);
+C
+C The global variable "calling_conventions_function" is the function to
+C call, with the arguments as passed here.
+
+define(`WANT_CALLEE_SAVES', eval(4*0))
+define(`SAVE_CALLEE_SAVES', eval(4*8))
+define(`RETADDR', eval(4*16))
+define(`GOT_CALLEE_SAVES', eval(4*17))
+define(`JUNK_PARAMS', eval(4*25))
+
+ TEXT
+ ALIGN(32)
+PROLOGUE(calling_conventions)
+ LEA( r12, calling_conventions_values)
+
+ C Preserve callee-saves registers, including the link register r14
+ add r12, r12, #SAVE_CALLEE_SAVES
+ stm r12, {r4-r11,r14}
+ sub r12, r12, #SAVE_CALLEE_SAVES
+
+ C Put chosen junk into callee-saves registers
+ add r12, r12, #WANT_CALLEE_SAVES
+ ldm r12, {r4-r11}
+ sub r12, r12, #WANT_CALLEE_SAVES
+
+ C No callee-saves registers on arm except r12 and parameter registers
+ C
+
+ C Make the actual call
+ LEA( r12, calling_conventions_function)
+ ldr r12, [r12]
+ mov r14, pc
+ bx r12
+
+ LEA( r12, calling_conventions_values)
+
+ C Save callee-saves registers after call
+ add r12, r12, #GOT_CALLEE_SAVES
+ stm r12, {r4-r11}
+ sub r12, r12, #GOT_CALLEE_SAVES
+
+ C Restore callee-saves registers, including the link register r14
+ add r12, r12, #SAVE_CALLEE_SAVES
+ ldm r12, {r4-r11,r14}
+ sub r12, r12, #SAVE_CALLEE_SAVES
+
+ C Overwrite parameter registers. Note that we overwrite r1, which
+ C could hold one half of a 64-bit return value, since we don't use that
+ C in GMP.
+ add r12, r12, #JUNK_PARAMS
+ ldm r12, {r1-r3}
+
+ bx r14
+EPILOGUE()
diff --git a/gmp/tests/arm32check.c b/gmp/tests/arm32check.c
new file mode 100644
index 0000000000..f4bf06684c
--- /dev/null
+++ b/gmp/tests/arm32check.c
@@ -0,0 +1,96 @@
+/* ARM32 calling conventions checking.
+
+Copyright 2000, 2001, 2004, 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 <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Vector if constants and register values. */
+mp_limb_t calling_conventions_values[29] =
+{
+ 0x12345678, /* 0 want_r4 */
+ 0x87654321, /* 1 want_r5 */
+ 0x89ABCDEF, /* 2 want_r6 */
+ 0xFEDCBA98, /* 3 want_r7 */
+ 0xDEADBEEF, /* 4 want_r8 */
+ 0xBADECAFE, /* 5 want_r9 */
+ 0xFFEEDDCC, /* 6 want_r10 */
+ 0xBBAA9988, /* 7 want_r11 */
+
+ 0x00000000, /* 8 save_r4 */
+ 0x00000000, /* 9 save_r5 */
+ 0x00000000, /* 10 save_r6 */
+ 0x00000000, /* 11 save_r7 */
+ 0x00000000, /* 12 save_r8 */
+ 0x00000000, /* 13 save_r9 */
+ 0x00000000, /* 14 save_r10 */
+ 0x00000000, /* 15 save_r11 */
+ 0x00000000, /* 16 save_r14 */
+
+ 0x00000000, /* 17 got_r4 */
+ 0x00000000, /* 18 got_r5 */
+ 0x00000000, /* 19 got_r6 */
+ 0x00000000, /* 20 got_r7 */
+ 0x00000000, /* 21 got_r8 */
+ 0x00000000, /* 22 got_r9 */
+ 0x00000000, /* 23 got_r10 */
+ 0x00000000, /* 24 got_r11 */
+
+ 0x00112233, /* 25 junk_r0 */
+ 0x44556677, /* 26 junk_r1 */
+ 0x12344321, /* 27 junk_r2 */
+ 0x56788765, /* 28 junk_r3 */
+};
+
+/* Index starts for various regions in above vector. */
+#define WANT_CALLEE_SAVES 0
+#define SAVE_CALLEE_SAVES 8
+#define RETADDR 16
+#define GOT_CALLEE_SAVES 17
+#define JUNK_PARAMS 25
+
+/* Return 1 if ok, 0 if not */
+
+int
+calling_conventions_check (void)
+{
+ const char *header = "Violated calling conventions:\n";
+ int ret = 1;
+ int i;
+
+#define CHECK(callreg, regnum, value) \
+ if (callreg != value) \
+ { \
+ printf ("%s r%d got 0x%08lX want 0x%08lX\n", \
+ header, regnum, callreg, value); \
+ header = ""; \
+ ret = 0; \
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ CHECK (calling_conventions_values[GOT_CALLEE_SAVES + i],
+ i + 4,
+ calling_conventions_values[WANT_CALLEE_SAVES + i]);
+ }
+
+ return ret;
+}
diff --git a/gmp/tests/cxx/Makefile.am b/gmp/tests/cxx/Makefile.am
new file mode 100644
index 0000000000..a5428d5d76
--- /dev/null
+++ b/gmp/tests/cxx/Makefile.am
@@ -0,0 +1,81 @@
+## 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.
+#
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+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-ops2 t-ops3 t-ostream t-prec \
+ t-ternary t-unary \
+ t-do-exceptions-work-at-all-with-this-compiler \
+ t-assign t-constr t-rand
+TESTS = $(check_PROGRAMS)
+endif
+
+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_ops2_SOURCES = t-ops2.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/gmp/tests/cxx/Makefile.in b/gmp/tests/cxx/Makefile.in
new file mode 100644
index 0000000000..04e7520854
--- /dev/null
+++ b/gmp/tests/cxx/Makefile.in
@@ -0,0 +1,887 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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-ops2$(EXEEXT) \
+@WANT_CXX_TRUE@ t-ops3$(EXEEXT) t-ostream$(EXEEXT) \
+@WANT_CXX_TRUE@ t-prec$(EXEEXT) t-ternary$(EXEEXT) \
+@WANT_CXX_TRUE@ t-unary$(EXEEXT) \
+@WANT_CXX_TRUE@ t-do-exceptions-work-at-all-with-this-compiler$(EXEEXT) \
+@WANT_CXX_TRUE@ t-assign$(EXEEXT) t-constr$(EXEEXT) \
+@WANT_CXX_TRUE@ t-rand$(EXEEXT)
+subdir = tests/cxx
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+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_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_ops2_OBJECTS = t-ops2.$(OBJEXT)
+t_ops2_OBJECTS = $(am_t_ops2_OBJECTS)
+t_ops2_LDADD = $(LDADD)
+t_ops2_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
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+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_ops2_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_ops2_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
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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.
+#
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+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)
+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_ops2_SOURCES = t-ops2.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 .o .obj
+$(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
+.PRECIOUS: 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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(CXXLINK) $(t_ops_OBJECTS) $(t_ops_LDADD) $(LIBS)
+t-ops2$(EXEEXT): $(t_ops2_OBJECTS) $(t_ops2_DEPENDENCIES) $(EXTRA_t_ops2_DEPENDENCIES)
+ @rm -f t-ops2$(EXEEXT)
+ $(CXXLINK) $(t_ops2_OBJECTS) $(t_ops2_LDADD) $(LIBS)
+t-ops3$(EXEEXT): $(t_ops3_OBJECTS) $(t_ops3_DEPENDENCIES) $(EXTRA_t_ops3_DEPENDENCIES)
+ @rm -f t-ops3$(EXEEXT)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(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)
+ $(CXXLINK) $(t_unary_OBJECTS) $(t_unary_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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:
+
+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 all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool ctags \
+ 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 \
+ tags uninstall uninstall-am
+
+
+$(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/gmp/tests/cxx/clocale.c b/gmp/tests/cxx/clocale.c
new file mode 100644
index 0000000000..1bd6ed2f14
--- /dev/null
+++ b/gmp/tests/cxx/clocale.c
@@ -0,0 +1,60 @@
+/* Manipulable localeconv and nl_langinfo.
+
+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 "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
+struct lconv *
+localeconv (void)
+{
+ static struct lconv l;
+ l.decimal_point = point_string;
+ return &l;
+}
+#endif
+
+#if HAVE_NL_LANGINFO
+char *
+nl_langinfo (nl_item n)
+{
+ return point_string;
+}
+#endif
diff --git a/gmp/tests/cxx/t-assign.cc b/gmp/tests/cxx/t-assign.cc
new file mode 100644
index 0000000000..ad10edd8a8
--- /dev/null
+++ b/gmp/tests/cxx/t-assign.cc
@@ -0,0 +1,604 @@
+/* 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 "gmp.h"
+#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/gmp/tests/cxx/t-binary.cc b/gmp/tests/cxx/t-binary.cc
new file mode 100644
index 0000000000..09d202b226
--- /dev/null
+++ b/gmp/tests/cxx/t-binary.cc
@@ -0,0 +1,466 @@
+/* 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 "gmp.h"
+#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/gmp/tests/cxx/t-cast.cc b/gmp/tests/cxx/t-cast.cc
new file mode 100644
index 0000000000..117fd87b80
--- /dev/null
+++ b/gmp/tests/cxx/t-cast.cc
@@ -0,0 +1,57 @@
+/* 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 "gmp.h"
+#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/gmp/tests/cxx/t-constr.cc b/gmp/tests/cxx/t-constr.cc
new file mode 100644
index 0000000000..7a87f3cb04
--- /dev/null
+++ b/gmp/tests/cxx/t-constr.cc
@@ -0,0 +1,756 @@
+/* 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 "gmp.h"
+#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/gmp/tests/cxx/t-cxx11.cc b/gmp/tests/cxx/t-cxx11.cc
new file mode 100644
index 0000000000..758f016386
--- /dev/null
+++ b/gmp/tests/cxx/t-cxx11.cc
@@ -0,0 +1,220 @@
+/* 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 "gmp.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");
+}
+
+void check_common_type ()
+{
+#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);
+
+ /* These could be broken by a naive common_type specialization */
+ CHECK_COMMON_TYPE (decltype(-z), decltype(-z), decltype(-z));
+ CHECK_COMMON_TYPE (decltype(-q), decltype(-q), decltype(-q));
+ CHECK_COMMON_TYPE (decltype(-f), decltype(-f), decltype(-f));
+
+ /* 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/gmp/tests/cxx/t-do-exceptions-work-at-all-with-this-compiler.cc b/gmp/tests/cxx/t-do-exceptions-work-at-all-with-this-compiler.cc
new file mode 100644
index 0000000000..341a818b75
--- /dev/null
+++ b/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/gmp/tests/cxx/t-headers.cc b/gmp/tests/cxx/t-headers.cc
new file mode 100644
index 0000000000..35f7a25c26
--- /dev/null
+++ b/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/gmp/tests/cxx/t-iostream.cc b/gmp/tests/cxx/t-iostream.cc
new file mode 100644
index 0000000000..92bd917a97
--- /dev/null
+++ b/gmp/tests/cxx/t-iostream.cc
@@ -0,0 +1,107 @@
+/* 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 "gmp.h"
+#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/gmp/tests/cxx/t-istream.cc b/gmp/tests/cxx/t-istream.cc
new file mode 100644
index 0000000000..f04ae083f8
--- /dev/null
+++ b/gmp/tests/cxx/t-istream.cc
@@ -0,0 +1,599 @@
+/* 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.h"
+#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/gmp/tests/cxx/t-locale.cc b/gmp/tests/cxx/t-locale.cc
new file mode 100644
index 0000000000..01eacda9f2
--- /dev/null
+++ b/gmp/tests/cxx/t-locale.cc
@@ -0,0 +1,195 @@
+/* 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.h"
+#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/gmp/tests/cxx/t-misc.cc b/gmp/tests/cxx/t-misc.cc
new file mode 100644
index 0000000000..07079880e7
--- /dev/null
+++ b/gmp/tests/cxx/t-misc.cc
@@ -0,0 +1,398 @@
+/* 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 "gmp.h"
+#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/gmp/tests/cxx/t-mix.cc b/gmp/tests/cxx/t-mix.cc
new file mode 100644
index 0000000000..aeb6f67589
--- /dev/null
+++ b/gmp/tests/cxx/t-mix.cc
@@ -0,0 +1,83 @@
+/* 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 "gmp.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/gmp/tests/cxx/t-ops.cc b/gmp/tests/cxx/t-ops.cc
new file mode 100644
index 0000000000..b1bf0dc4d8
--- /dev/null
+++ b/gmp/tests/cxx/t-ops.cc
@@ -0,0 +1,723 @@
+/* Test mp*_class operators and functions.
+
+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 "gmp.h"
+#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);
+ }
+
+ // 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);
+ }
+}
+
+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);
+ }
+}
+
+
+int
+main (void)
+{
+ tests_start();
+
+ check_mpz();
+ check_mpq();
+ check_mpf();
+
+ tests_end();
+ return 0;
+}
diff --git a/gmp/tests/cxx/t-ops2.cc b/gmp/tests/cxx/t-ops2.cc
new file mode 100644
index 0000000000..3a25442aaf
--- /dev/null
+++ b/gmp/tests/cxx/t-ops2.cc
@@ -0,0 +1,256 @@
+/* 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 "gmp.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,!=)
+
+
+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,>>);
+ CHECK(mpz_class,unsigned long,-13,2,<<);
+ 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);
+}
+
+template<class T>
+void checkqf (){
+ 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,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);
+}
+
+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);
+ checkz();
+ checkqf<mpq_class>();
+ checkqf<mpf_class>();
+ checkf();
+
+ tests_end();
+ return 0;
+}
diff --git a/gmp/tests/cxx/t-ops3.cc b/gmp/tests/cxx/t-ops3.cc
new file mode 100644
index 0000000000..cb6a2efc7d
--- /dev/null
+++ b/gmp/tests/cxx/t-ops3.cc
@@ -0,0 +1,133 @@
+/* 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 "gmp.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/gmp/tests/cxx/t-ostream.cc b/gmp/tests/cxx/t-ostream.cc
new file mode 100644
index 0000000000..9b4f5e7dd7
--- /dev/null
+++ b/gmp/tests/cxx/t-ostream.cc
@@ -0,0 +1,450 @@
+/* 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.h"
+#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/gmp/tests/cxx/t-prec.cc b/gmp/tests/cxx/t-prec.cc
new file mode 100644
index 0000000000..8039219f21
--- /dev/null
+++ b/gmp/tests/cxx/t-prec.cc
@@ -0,0 +1,217 @@
+/* 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 "gmp.h"
+#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/gmp/tests/cxx/t-rand.cc b/gmp/tests/cxx/t-rand.cc
new file mode 100644
index 0000000000..b71c49627b
--- /dev/null
+++ b/gmp/tests/cxx/t-rand.cc
@@ -0,0 +1,149 @@
+/* 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 "gmp.h"
+#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/gmp/tests/cxx/t-ternary.cc b/gmp/tests/cxx/t-ternary.cc
new file mode 100644
index 0000000000..405f6f4981
--- /dev/null
+++ b/gmp/tests/cxx/t-ternary.cc
@@ -0,0 +1,735 @@
+/* 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 "gmp.h"
+#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/gmp/tests/cxx/t-unary.cc b/gmp/tests/cxx/t-unary.cc
new file mode 100644
index 0000000000..d33b995d21
--- /dev/null
+++ b/gmp/tests/cxx/t-unary.cc
@@ -0,0 +1,133 @@
+/* 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 "gmp.h"
+#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;
+}
diff --git a/gmp/tests/devel/Makefile.am b/gmp/tests/devel/Makefile.am
new file mode 100644
index 0000000000..7d62115bc3
--- /dev/null
+++ b/gmp/tests/devel/Makefile.am
@@ -0,0 +1,34 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2000-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/.
+
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+
+# add_n_sub_n add_n_sub_n_2 not yet built since mpn_add_n_sub_n doesn't yet exist
+#
+EXTRA_PROGRAMS = \
+ aors_n anymul_1 copy divmod_1 divrem shift logops_n tst-addsub try
+
+allprogs: $(EXTRA_PROGRAMS)
+
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
diff --git a/gmp/tests/devel/Makefile.in b/gmp/tests/devel/Makefile.in
new file mode 100644
index 0000000000..28a68c050b
--- /dev/null
+++ b/gmp/tests/devel/Makefile.in
@@ -0,0 +1,606 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2000-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/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+EXTRA_PROGRAMS = aors_n$(EXEEXT) anymul_1$(EXEEXT) copy$(EXEEXT) \
+ divmod_1$(EXEEXT) divrem$(EXEEXT) shift$(EXEEXT) \
+ logops_n$(EXEEXT) tst-addsub$(EXEEXT) try$(EXEEXT)
+subdir = tests/devel
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+anymul_1_SOURCES = anymul_1.c
+anymul_1_OBJECTS = anymul_1.$(OBJEXT)
+anymul_1_LDADD = $(LDADD)
+anymul_1_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+aors_n_SOURCES = aors_n.c
+aors_n_OBJECTS = aors_n.$(OBJEXT)
+aors_n_LDADD = $(LDADD)
+aors_n_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+copy_SOURCES = copy.c
+copy_OBJECTS = copy.$(OBJEXT)
+copy_LDADD = $(LDADD)
+copy_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+divmod_1_SOURCES = divmod_1.c
+divmod_1_OBJECTS = divmod_1.$(OBJEXT)
+divmod_1_LDADD = $(LDADD)
+divmod_1_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+divrem_SOURCES = divrem.c
+divrem_OBJECTS = divrem.$(OBJEXT)
+divrem_LDADD = $(LDADD)
+divrem_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+logops_n_SOURCES = logops_n.c
+logops_n_OBJECTS = logops_n.$(OBJEXT)
+logops_n_LDADD = $(LDADD)
+logops_n_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+shift_SOURCES = shift.c
+shift_OBJECTS = shift.$(OBJEXT)
+shift_LDADD = $(LDADD)
+shift_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+try_SOURCES = try.c
+try_OBJECTS = try.$(OBJEXT)
+try_LDADD = $(LDADD)
+try_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+tst_addsub_SOURCES = tst-addsub.c
+tst_addsub_OBJECTS = tst-addsub.$(OBJEXT)
+tst_addsub_LDADD = $(LDADD)
+tst_addsub_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = anymul_1.c aors_n.c copy.c divmod_1.c divrem.c logops_n.c \
+ shift.c try.c tst-addsub.c
+DIST_SOURCES = anymul_1.c aors_n.c copy.c divmod_1.c divrem.c \
+ logops_n.c shift.c try.c tst-addsub.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+CLEANFILES = $(EXTRA_PROGRAMS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/devel/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps tests/devel/Makefile
+.PRECIOUS: 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):
+anymul_1$(EXEEXT): $(anymul_1_OBJECTS) $(anymul_1_DEPENDENCIES) $(EXTRA_anymul_1_DEPENDENCIES)
+ @rm -f anymul_1$(EXEEXT)
+ $(LINK) $(anymul_1_OBJECTS) $(anymul_1_LDADD) $(LIBS)
+aors_n$(EXEEXT): $(aors_n_OBJECTS) $(aors_n_DEPENDENCIES) $(EXTRA_aors_n_DEPENDENCIES)
+ @rm -f aors_n$(EXEEXT)
+ $(LINK) $(aors_n_OBJECTS) $(aors_n_LDADD) $(LIBS)
+copy$(EXEEXT): $(copy_OBJECTS) $(copy_DEPENDENCIES) $(EXTRA_copy_DEPENDENCIES)
+ @rm -f copy$(EXEEXT)
+ $(LINK) $(copy_OBJECTS) $(copy_LDADD) $(LIBS)
+divmod_1$(EXEEXT): $(divmod_1_OBJECTS) $(divmod_1_DEPENDENCIES) $(EXTRA_divmod_1_DEPENDENCIES)
+ @rm -f divmod_1$(EXEEXT)
+ $(LINK) $(divmod_1_OBJECTS) $(divmod_1_LDADD) $(LIBS)
+divrem$(EXEEXT): $(divrem_OBJECTS) $(divrem_DEPENDENCIES) $(EXTRA_divrem_DEPENDENCIES)
+ @rm -f divrem$(EXEEXT)
+ $(LINK) $(divrem_OBJECTS) $(divrem_LDADD) $(LIBS)
+logops_n$(EXEEXT): $(logops_n_OBJECTS) $(logops_n_DEPENDENCIES) $(EXTRA_logops_n_DEPENDENCIES)
+ @rm -f logops_n$(EXEEXT)
+ $(LINK) $(logops_n_OBJECTS) $(logops_n_LDADD) $(LIBS)
+shift$(EXEEXT): $(shift_OBJECTS) $(shift_DEPENDENCIES) $(EXTRA_shift_DEPENDENCIES)
+ @rm -f shift$(EXEEXT)
+ $(LINK) $(shift_OBJECTS) $(shift_LDADD) $(LIBS)
+try$(EXEEXT): $(try_OBJECTS) $(try_DEPENDENCIES) $(EXTRA_try_DEPENDENCIES)
+ @rm -f try$(EXEEXT)
+ $(LINK) $(try_OBJECTS) $(try_LDADD) $(LIBS)
+tst-addsub$(EXEEXT): $(tst_addsub_OBJECTS) $(tst_addsub_DEPENDENCIES) $(EXTRA_tst_addsub_DEPENDENCIES)
+ @rm -f tst-addsub$(EXEEXT)
+ $(LINK) $(tst_addsub_OBJECTS) $(tst_addsub_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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-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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool ctags 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 \
+ tags uninstall uninstall-am
+
+
+allprogs: $(EXTRA_PROGRAMS)
+
+$(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/gmp/tests/devel/README b/gmp/tests/devel/README
new file mode 100644
index 0000000000..77fa65dba3
--- /dev/null
+++ b/gmp/tests/devel/README
@@ -0,0 +1,37 @@
+Copyright 2000, 2001 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/.
+
+
+
+
+ DEVELOPMENT TEST PROGRAMS
+
+
+This directory contains various programs used during development. Casual
+GMP users are unlikely to find anything of interest.
+
+Nothing here is built or installed, nor even run in a "make check", but
+there's Makefile rules to build each program, or "allprogs" to build
+everything.
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/tests/devel/anymul_1.c b/gmp/tests/devel/anymul_1.c
new file mode 100644
index 0000000000..79807b0ce5
--- /dev/null
+++ b/gmp/tests/devel/anymul_1.c
@@ -0,0 +1,256 @@
+/*
+Copyright 1996-2002, 2004, 2006-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 <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests/tests.h"
+
+#ifdef OPERATION_mul_1
+#define func __gmpn_mul_1
+#define reffunc refmpn_mul_1
+#define funcname "mpn_mul_1"
+#endif
+
+#ifdef OPERATION_addmul_1
+#define func __gmpn_addmul_1
+#define reffunc refmpn_addmul_1
+#define funcname "mpn_addmul_1"
+#endif
+
+#ifdef OPERATION_submul_1
+#define func __gmpn_submul_1
+#define reffunc refmpn_submul_1
+#define funcname "mpn_submul_1"
+#endif
+
+#if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
+#include <time.h>
+
+int
+cputime ()
+{
+ if (CLOCKS_PER_SEC < 100000)
+ return clock () * 1000 / CLOCKS_PER_SEC;
+ return clock () / (CLOCKS_PER_SEC / 1000);
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+int
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#endif
+
+static void print_posneg (mp_limb_t);
+static void mpn_print (mp_ptr, mp_size_t);
+
+#define LXW ((int) (2 * sizeof (mp_limb_t)))
+#define M * 1000000
+
+#ifndef CLOCK
+#error "Don't know CLOCK of your machine"
+#endif
+
+#ifndef OPS
+#define OPS (CLOCK/5)
+#endif
+#ifndef SIZE
+#define SIZE 496
+#endif
+#ifndef TIMES
+#define TIMES OPS/(SIZE+1)
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr s1, ref, rp;
+ mp_limb_t cy_ref, cy_try;
+ int i;
+ long t0, t;
+ unsigned int test;
+ mp_limb_t xlimb;
+ mp_size_t size;
+ double cyc;
+ unsigned int ntests;
+
+ s1 = malloc (SIZE * sizeof (mp_limb_t));
+ ref = malloc (SIZE * sizeof (mp_limb_t));
+ rp = malloc ((SIZE + 2) * sizeof (mp_limb_t));
+ rp++;
+
+ ntests = ~(unsigned) 0;
+ if (argc == 2)
+ ntests = strtol (argv[1], 0, 0);
+
+ for (test = 1; test <= ntests; test++)
+ {
+#if TIMES == 1 && ! defined (PRINT)
+ if (test % (1 + 0x80000 / (SIZE + 20)) == 0)
+ {
+ printf ("\r%u", test);
+ fflush (stdout);
+ }
+#endif
+
+#ifdef PLAIN_RANDOM
+#define MPN_RANDOM mpn_random
+#else
+#define MPN_RANDOM mpn_random2
+#endif
+
+#ifdef RANDOM
+ size = random () % SIZE + 1;
+#else
+ size = SIZE;
+#endif
+
+ rp[-1] = 0x87654321;
+ rp[size] = 0x12345678;
+
+#ifdef FIXED_XLIMB
+ xlimb = FIXED_XLIMB;
+#else
+ MPN_RANDOM (&xlimb, 1);
+#endif
+
+#if TIMES != 1
+ mpn_random (s1, size);
+ mpn_random (rp, size);
+
+ MPN_COPY (ref, rp, size);
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ func (ref, s1, size, xlimb);
+ t = cputime() - t0;
+ cyc = ((double) t * CLOCK) / (TIMES * size * 1000.0);
+ printf (funcname ": %5ldms (%.3f cycles/limb) [%.2f Gb/s]\n",
+ t, cyc,
+ CLOCK/cyc*GMP_LIMB_BITS*GMP_LIMB_BITS/1e9);
+#endif
+
+#ifndef NOCHECK
+ MPN_RANDOM (s1, size);
+#ifdef ZERO
+ memset (rp, 0, size * sizeof *rp);
+#else
+ MPN_RANDOM (rp, size);
+#endif
+#if defined (PRINT) || defined (XPRINT)
+ printf ("xlimb=");
+ mpn_print (&xlimb, 1);
+#endif
+#ifdef PRINT
+#ifndef OPERATION_mul_1
+ printf ("%*s ", (int) (2 * sizeof(mp_limb_t)), "");
+ mpn_print (rp, size);
+#endif
+ printf ("%*s ", (int) (2 * sizeof(mp_limb_t)), "");
+ mpn_print (s1, size);
+#endif
+
+ MPN_COPY (ref, rp, size);
+ cy_ref = reffunc (ref, s1, size, xlimb);
+ cy_try = func (rp, s1, size, xlimb);
+
+#ifdef PRINT
+ mpn_print (&cy_ref, 1);
+ mpn_print (ref, size);
+ mpn_print (&cy_try, 1);
+ mpn_print (rp, size);
+#endif
+
+ if (cy_ref != cy_try || mpn_cmp (ref, rp, size) != 0
+ || rp[-1] != 0x87654321 || rp[size] != 0x12345678)
+ {
+ printf ("\n ref%*s try%*s diff\n", LXW - 3, "", 2 * LXW - 6, "");
+ for (i = 0; i < size; i++)
+ {
+ printf ("%6d: ", i);
+ printf ("%0*llX ", LXW, (unsigned long long) ref[i]);
+ printf ("%0*llX ", LXW, (unsigned long long) rp[i]);
+ print_posneg (rp[i] - ref[i]);
+ printf ("\n");
+ }
+ printf ("retval: ");
+ printf ("%0*llX ", LXW, (unsigned long long) cy_ref);
+ printf ("%0*llX ", LXW, (unsigned long long) cy_try);
+ print_posneg (cy_try - cy_ref);
+ printf ("\n");
+ if (rp[-1] != 0x87654321)
+ printf ("clobbered at low end\n");
+ if (rp[size] != 0x12345678)
+ printf ("clobbered at high end\n");
+ printf ("TEST NUMBER %u\n", test);
+ abort();
+ }
+#endif
+ }
+ exit (0);
+}
+
+static void
+print_posneg (mp_limb_t d)
+{
+ char buf[LXW + 2];
+ if (d == 0)
+ printf (" %*X", LXW, 0);
+ else if (-d < d)
+ {
+ sprintf (buf, "%llX", (unsigned long long) -d);
+ printf ("%*s-%s", LXW - (int) strlen (buf), "", buf);
+ }
+ else
+ {
+ sprintf (buf, "%llX", (unsigned long long) d);
+ printf ("%*s+%s", LXW - (int) strlen (buf), "", buf);
+ }
+}
+
+static void
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+#ifdef _LONG_LONG_LIMB
+ printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
+ (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
+ (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
+#else
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#endif
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gmp/tests/devel/aors_n.c b/gmp/tests/devel/aors_n.c
new file mode 100644
index 0000000000..5112d0a8d9
--- /dev/null
+++ b/gmp/tests/devel/aors_n.c
@@ -0,0 +1,263 @@
+/*
+Copyright 1996-2004, 2009, 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 <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifdef OPERATION_add_n
+#define func __gmpn_add_n
+#define reffunc refmpn_add_n
+#define funcname "mpn_add_n"
+#endif
+
+#ifdef OPERATION_sub_n
+#define func __gmpn_sub_n
+#define reffunc refmpn_sub_n
+#define funcname "mpn_sub_n"
+#endif
+
+#ifdef OPERATION_addlsh1_n
+#define func __gmpn_addlsh1_n
+#define reffunc refmpn_addlsh1_n
+#define funcname "mpn_addlsh1_n"
+#endif
+
+#ifdef OPERATION_sublsh1_n
+#define func __gmpn_sublsh1_n
+#define reffunc refmpn_sublsh1_n
+#define funcname "mpn_sublsh1_n"
+#endif
+
+#ifdef OPERATION_rsh1add_n
+#define func __gmpn_rsh1add_n
+#define reffunc refmpn_rsh1add_n
+#define funcname "mpn_rsh1add_n"
+#endif
+
+#ifdef OPERATION_rsh1sub_n
+#define func __gmpn_rsh1sub_n
+#define reffunc refmpn_rsh1sub_n
+#define funcname "mpn_rsh1sub_n"
+#endif
+
+#if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
+#include <time.h>
+
+int
+cputime ()
+{
+ if (CLOCKS_PER_SEC < 100000)
+ return clock () * 1000 / CLOCKS_PER_SEC;
+ return clock () / (CLOCKS_PER_SEC / 1000);
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+int
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#endif
+
+static void print_posneg (mp_limb_t);
+static void mpn_print (mp_ptr, mp_size_t);
+
+#define LXW ((int) (2 * sizeof (mp_limb_t)))
+#define M * 1000000
+
+#ifndef CLOCK
+#error "Don't know CLOCK of your machine"
+#endif
+
+#ifndef OPS
+#define OPS (CLOCK/5)
+#endif
+#ifndef SIZE
+#define SIZE 328
+#endif
+#ifndef TIMES
+#define TIMES OPS/(SIZE+1)
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr s1, s2, dx, dy;
+ mp_limb_t cyx, cyy;
+ int i;
+#if TIMES != 1
+ long t0, t;
+#endif
+ unsigned int test;
+ mp_size_t size;
+ unsigned int ntests;
+
+ s1 = malloc (SIZE * sizeof (mp_limb_t));
+ s2 = malloc (SIZE * sizeof (mp_limb_t));
+ dx = malloc ((SIZE + 2) * sizeof (mp_limb_t));
+ dy = malloc ((SIZE + 2) * sizeof (mp_limb_t));
+
+ ntests = ~(unsigned) 0;
+ if (argc == 2)
+ ntests = strtol (argv[1], 0, 0);
+
+ for (test = 1; test <= ntests; test++)
+ {
+#if TIMES == 1 && ! defined (PRINT)
+ if (test % (SIZE > 100000 ? 1 : 100000 / SIZE) == 0)
+ {
+ printf ("\r%u", test);
+ fflush (stdout);
+ }
+#endif
+
+#ifdef RANDOM
+ size = random () % SIZE + 1;
+#else
+ size = SIZE;
+#endif
+
+ dx[0] = 0x87654321;
+ dy[0] = 0x87654321;
+ dx[size+1] = 0x12345678;
+ dy[size+1] = 0x12345678;
+
+#if TIMES != 1
+ mpn_random (s1, size);
+ mpn_random (s2, size);
+
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ func (dx+1, s1, s2, size);
+ t = cputime() - t0;
+ printf (funcname ": %5ldms (%.3f cycles/limb)\n",
+ t, ((double) t * CLOCK) / (TIMES * size * 1000.0));
+#endif
+
+#ifndef NOCHECK
+ mpn_random2 (s1, size);
+ mpn_random2 (s2, size);
+
+#ifdef PRINT
+ mpn_print (s1, size);
+ mpn_print (s2, size);
+#endif
+
+ /* Put garbage in the destination. */
+ for (i = 0; i < size; i++)
+ {
+ dx[i+1] = 0xdead;
+ dy[i+1] = 0xbeef;
+ }
+
+ cyx = reffunc (dx+1, s1, s2, size);
+ cyy = func (dy+1, s1, s2, size);
+
+#ifdef PRINT
+ mpn_print (&cyx, 1);
+ mpn_print (dx+1, size);
+ mpn_print (&cyy, 1);
+ mpn_print (dy+1, size);
+#endif
+
+ if (cyx != cyy || mpn_cmp (dx, dy, size+2) != 0
+ || dx[0] != 0x87654321 || dx[size+1] != 0x12345678)
+ {
+ mp_size_t s, e;
+ for (s = 0;; s++)
+ if ((unsigned long long) (dx+1)[s] != (unsigned long long) (dy+1)[s])
+ break;
+ for (e = size - 1;; e--)
+ if ((unsigned long long) (dx+1)[e] != (unsigned long long) (dy+1)[e])
+ break;
+#ifndef PRINT
+ for (i = s; i <= e; i++)
+ {
+ printf ("%6d: ", i);
+ printf ("%0*llX ", LXW, (unsigned long long) (dx+1)[i]);
+ printf ("%0*llX ", LXW, (unsigned long long) (dy+1)[i]);
+ print_posneg ((dy+1)[i] - (dx+1)[i]);
+ printf ("\n");
+ }
+ printf ("%6s: ", "retval");
+ printf ("%0*llX ", LXW, (unsigned long long) cyx);
+ printf ("%0*llX ", LXW, (unsigned long long) cyy);
+ print_posneg (cyx - cyy);
+#endif
+ printf ("\n");
+ if (dy[0] != 0x87654321)
+ printf ("clobbered at low end\n");
+ if (dy[size+1] != 0x12345678)
+ printf ("clobbered at high end\n");
+ printf ("TEST NUMBER %u\n", test);
+ abort();
+ }
+#endif
+ }
+ exit (0);
+}
+
+static void
+print_posneg (mp_limb_t d)
+{
+ char buf[LXW + 2];
+ if (d == 0)
+ printf (" %*X", LXW, 0);
+ else if (-d < d)
+ {
+ sprintf (buf, "%llX", (unsigned long long) -d);
+ printf ("%*s-%s", LXW - (int) strlen (buf), "", buf);
+ }
+ else
+ {
+ sprintf (buf, "%llX", (unsigned long long) d);
+ printf ("%*s+%s", LXW - (int) strlen (buf), "", buf);
+ }
+}
+
+static void
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+#ifdef _LONG_LONG_LIMB
+ printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
+ (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
+ (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
+#else
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#endif
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gmp/tests/devel/copy.c b/gmp/tests/devel/copy.c
new file mode 100644
index 0000000000..1f951f5389
--- /dev/null
+++ b/gmp/tests/devel/copy.c
@@ -0,0 +1,226 @@
+/*
+Copyright 1999-2001, 2004, 2009, 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 <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifdef OPERATION_copyi
+#define func MPN_COPY_INCR
+#define reffunc refmpn_copyi
+#define funcname "MPN_COPY_INCR"
+#endif
+
+#ifdef OPERATION_copyd
+#define func MPN_COPY_DECR
+#define reffunc refmpn_copyd
+#define funcname "MPN_COPY_DECR"
+#endif
+
+#if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
+#include <time.h>
+
+int
+cputime ()
+{
+ if (CLOCKS_PER_SEC < 100000)
+ return clock () * 1000 / CLOCKS_PER_SEC;
+ return clock () / (CLOCKS_PER_SEC / 1000);
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+int
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#endif
+
+static void print_posneg (mp_limb_t);
+static void mpn_print (mp_ptr, mp_size_t);
+
+#define LXW ((int) (2 * sizeof (mp_limb_t)))
+#define M * 1000000
+
+#ifndef CLOCK
+#error "Don't know CLOCK of your machine"
+#endif
+
+#ifndef OPS
+#define OPS (CLOCK/5)
+#endif
+#ifndef SIZE
+#define SIZE 496
+#endif
+#ifndef TIMES
+#define TIMES OPS/(SIZE+1)
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr s1, dx, dy;
+ int i;
+ long t0, t;
+ unsigned int test;
+ mp_size_t size;
+ unsigned int ntests;
+
+ s1 = malloc (SIZE * sizeof (mp_limb_t));
+ dx = malloc ((SIZE + 2) * sizeof (mp_limb_t));
+ dy = malloc ((SIZE + 2) * sizeof (mp_limb_t));
+
+ ntests = ~(unsigned) 0;
+ if (argc == 2)
+ ntests = strtol (argv[1], 0, 0);
+
+ for (test = 1; test <= ntests; test++)
+ {
+#if TIMES == 1 && ! defined (PRINT)
+ if (test % (SIZE > 100000 ? 1 : 100000 / SIZE) == 0)
+ {
+ printf ("\r%u", test);
+ fflush (stdout);
+ }
+#endif
+
+#ifdef RANDOM
+ size = random () % SIZE + 1;
+#else
+ size = SIZE;
+#endif
+
+ dx[0] = 0x87654321;
+ dy[0] = 0x87654321;
+ dx[size+1] = 0x12345678;
+ dy[size+1] = 0x12345678;
+
+#if TIMES != 1
+ mpn_random (s1, size);
+
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ func (dx+1, s1, size);
+ t = cputime() - t0;
+ printf (funcname ": %5ldms (%.3f cycles/limb)\n",
+ t, ((double) t * CLOCK) / (TIMES * size * 1000.0));
+#endif
+
+#ifndef NOCHECK
+ mpn_random2 (s1, size);
+
+#ifdef PRINT
+ mpn_print (s1, size);
+#endif
+
+ /* Put garbage in the destination. */
+ for (i = 0; i < size; i++)
+ {
+ dx[i+1] = 0xdead;
+ dy[i+1] = 0xbeef;
+ }
+
+ reffunc (dx+1, s1, size);
+ func (dy+1, s1, size);
+
+#ifdef PRINT
+ mpn_print (dx+1, size);
+ mpn_print (dy+1, size);
+#endif
+
+ if (mpn_cmp (dx, dy, size+2) != 0
+ || dx[0] != 0x87654321 || dx[size+1] != 0x12345678)
+ {
+ mp_size_t s, e;
+ for (s = 0;; s++)
+ if ((unsigned long long) (dx+1)[s] != (unsigned long long) (dy+1)[s])
+ break;
+ for (e = size - 1;; e--)
+ if ((unsigned long long) (dx+1)[e] != (unsigned long long) (dy+1)[e])
+ break;
+#ifndef PRINT
+ for (i = s; i <= e; i++)
+ {
+ printf ("%6d: ", i);
+ printf ("%0*llX ", LXW, (unsigned long long) (dx+1)[i]);
+ printf ("%0*llX ", LXW, (unsigned long long) (dy+1)[i]);
+ print_posneg ((dy+1)[i] - (dx+1)[i]);
+ printf ("\n");
+ }
+#endif
+ printf ("\n");
+ if (dy[0] != 0x87654321)
+ printf ("clobbered at low end\n");
+ if (dy[size+1] != 0x12345678)
+ printf ("clobbered at high end\n");
+ printf ("TEST NUMBER %u\n", test);
+ abort();
+ }
+#endif
+ }
+ exit (0);
+}
+
+static void
+print_posneg (mp_limb_t d)
+{
+ char buf[LXW + 2];
+ if (d == 0)
+ printf (" %*X", LXW, 0);
+ else if (-d < d)
+ {
+ sprintf (buf, "%llX", (unsigned long long) -d);
+ printf ("%*s-%s", LXW - (int) strlen (buf), "", buf);
+ }
+ else
+ {
+ sprintf (buf, "%llX", (unsigned long long) d);
+ printf ("%*s+%s", LXW - (int) strlen (buf), "", buf);
+ }
+}
+
+static void
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+#ifdef _LONG_LONG_LIMB
+ printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
+ (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
+ (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
+#else
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#endif
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gmp/tests/devel/divmod_1.c b/gmp/tests/devel/divmod_1.c
new file mode 100644
index 0000000000..54eaf36d96
--- /dev/null
+++ b/gmp/tests/devel/divmod_1.c
@@ -0,0 +1,200 @@
+/*
+Copyright 1996, 1998, 2000, 2001, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
+#include <time.h>
+
+int
+cputime ()
+{
+ if (CLOCKS_PER_SEC < 100000)
+ return clock () * 1000 / CLOCKS_PER_SEC;
+ return clock () / (CLOCKS_PER_SEC / 1000);
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+int
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#endif
+
+static void mpn_print (mp_ptr, mp_size_t);
+
+#define M * 1000000
+
+#ifndef CLOCK
+#error "Don't know CLOCK of your machine"
+#endif
+
+#ifndef OPS
+#define OPS 20000000
+#endif
+#ifndef SIZE
+#define SIZE 1000
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#endif
+
+#ifndef FSIZE
+#define FSIZE SIZE
+#endif
+
+int
+main ()
+{
+ mp_limb_t np[SIZE];
+ mp_limb_t dx[SIZE + FSIZE + 2];
+ mp_limb_t dy[SIZE + FSIZE + 2];
+ mp_limb_t dlimb;
+ mp_size_t nn, fn;
+ mp_limb_t retx, rety;
+ int test;
+#if TIMES != 1
+ int i;
+ long t0, t;
+ double cyc;
+#endif
+
+ for (test = 0; ; test++)
+ {
+#if TIMES == 1 && ! defined (PRINT)
+ if (test % (SIZE > 100000 ? 1 : 100000 / SIZE) == 0)
+ {
+ printf ("\r%u", test);
+ fflush (stdout);
+ }
+#endif
+
+#ifdef RANDOM
+ nn = random () % (SIZE + 1);
+ fn = random () % (FSIZE + 1);
+#else
+ nn = SIZE;
+ fn = FSIZE;
+#endif
+
+ dx[0] = 0x87654321;
+ dx[nn + fn + 1] = 0x12345678;
+ dy[0] = 0x87654321;
+ dy[nn + fn + 1] = 0x12345678;
+ mpn_random2 (np, nn);
+
+#ifdef FIXED_DLIMB
+ dlimb = FIXED_DLIMB;
+#else
+ do
+ {
+ mpn_random2 (&dlimb, 1);
+#ifdef FORCE_NORM
+ dlimb |= GMP_NUMB_HIGHBIT;
+#endif
+#ifdef FORCE_UNNORM
+ dlimb &= GMP_NUMB_MAX >> 1;
+#endif
+ }
+ while (dlimb == 0);
+#endif
+
+#if defined (PRINT) || defined (XPRINT)
+ printf ("N=");
+ mpn_print (np, nn);
+ printf ("D=");
+ mpn_print (&dlimb, 1);
+ printf ("nn=%ld\n", (long) nn);
+#endif
+
+#if TIMES != 1
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ mpn_divrem_1 (dx + 1, 0L, np, nn, dlimb);
+ t = cputime() - t0;
+ cyc = ((double) t * CLOCK) / (TIMES * nn * 1000.0);
+ printf ("mpn_divrem_1 int: %5ldms (%.3f cycles/limb) [%.2f Gb/s]\n",
+ t, cyc,
+ CLOCK/cyc*GMP_LIMB_BITS*GMP_LIMB_BITS/1e9);
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ mpn_divrem_1 (dx + 1, fn, np, 0, dlimb);
+ t = cputime() - t0;
+ cyc = ((double) t * CLOCK) / (TIMES * fn * 1000.0);
+ printf ("mpn_divrem_1 frac: %5ldms (%.3f cycles/limb) [%.2f Gb/s]\n",
+ t, cyc,
+ CLOCK/cyc*GMP_LIMB_BITS*GMP_LIMB_BITS/1e9);
+#endif
+
+ retx = refmpn_divrem_1 (dx + 1, fn, np, nn, dlimb);
+ rety = mpn_divrem_1 (dy + 1, fn, np, nn, dlimb);
+
+#ifndef NOCHECK
+ if (retx != rety || mpn_cmp (dx, dy, fn + nn + 2) != 0)
+ {
+ printf ("ERROR in test %d, nn=%ld, fn=%ld\n", test, nn, fn);
+ mpn_print (np, nn);
+ mpn_print (&dlimb, 1);
+ printf ("rq: ");
+ mpn_print (dx + 1, nn + fn);
+ printf ("rr: %*lX\n", (int) (2 * sizeof(mp_limb_t)), retx);
+ printf (" q: ");
+ mpn_print (dy + 1, nn + fn);
+ printf (" r: %*lX\n", (int) (2 * sizeof(mp_limb_t)), rety);
+ if (dy[0] != 0x87654321)
+ printf ("clobbered at low end %*lX\n", (int) (2 * sizeof(mp_limb_t)), dy[0]);
+ if (dy[nn + fn + 1] != 0x12345678)
+ printf ("clobbered at high end\n");
+ abort ();
+ }
+#endif
+ }
+}
+
+static void
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+#ifdef _LONG_LONG_LIMB
+ printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
+ (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
+ (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
+#else
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#endif
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gmp/tests/devel/divrem.c b/gmp/tests/devel/divrem.c
new file mode 100644
index 0000000000..8580789078
--- /dev/null
+++ b/gmp/tests/devel/divrem.c
@@ -0,0 +1,119 @@
+/*
+Copyright 1996-1998, 2000, 2001, 2007, 2009 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
+#include <time.h>
+
+int
+cputime ()
+{
+ if (CLOCKS_PER_SEC < 100000)
+ return clock () * 1000 / CLOCKS_PER_SEC;
+ return clock () / (CLOCKS_PER_SEC / 1000);
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+int
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#error "Don't know CLOCK of your machine"
+#endif
+
+#ifndef OPS
+#define OPS 20000000
+#endif
+#ifndef SIZE
+#define SIZE 100
+#endif
+#ifndef TIMES
+#define TIMES OPS/(SIZE+1)
+#endif
+
+int
+main ()
+{
+ mp_limb_t nptr[2 * SIZE];
+ mp_limb_t dptr[2 * SIZE];
+ mp_limb_t qptr[2 * SIZE];
+ mp_limb_t pptr[2 * SIZE + 1];
+ mp_limb_t rptr[2 * SIZE];
+ mp_size_t nsize, dsize, qsize, rsize, psize;
+ int test;
+ mp_limb_t qlimb;
+
+ for (test = 0; ; test++)
+ {
+ printf ("%d\n", test);
+#ifdef RANDOM
+ nsize = random () % (2 * SIZE) + 1;
+ dsize = random () % nsize + 1;
+#else
+ nsize = 2 * SIZE;
+ dsize = SIZE;
+#endif
+
+ mpn_random2 (nptr, nsize);
+ mpn_random2 (dptr, dsize);
+ dptr[dsize - 1] |= (mp_limb_t) 1 << (GMP_LIMB_BITS - 1);
+
+ MPN_COPY (rptr, nptr, nsize);
+ qlimb = mpn_divrem (qptr, (mp_size_t) 0, rptr, nsize, dptr, dsize);
+ rsize = dsize;
+ qsize = nsize - dsize;
+ qptr[qsize] = qlimb;
+ qsize += qlimb;
+ if (qsize == 0 || qsize > 2 * SIZE)
+ {
+ continue; /* bogus */
+ }
+ else
+ {
+ mp_limb_t cy;
+ if (qsize > dsize)
+ mpn_mul (pptr, qptr, qsize, dptr, dsize);
+ else
+ mpn_mul (pptr, dptr, dsize, qptr, qsize);
+ psize = qsize + dsize;
+ psize -= pptr[psize - 1] == 0;
+ cy = mpn_add (pptr, pptr, psize, rptr, rsize);
+ pptr[psize] = cy;
+ psize += cy;
+ }
+
+ if (nsize != psize || mpn_cmp (nptr, pptr, nsize) != 0)
+ abort ();
+ }
+}
diff --git a/gmp/tests/devel/logops_n.c b/gmp/tests/devel/logops_n.c
new file mode 100644
index 0000000000..be53336cf5
--- /dev/null
+++ b/gmp/tests/devel/logops_n.c
@@ -0,0 +1,230 @@
+/*
+Copyright 1996-2004, 2009 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 <stdlib.h>
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifdef OPERATION_and_n
+#define func __gmpn_and_n
+#define reffunc refmpn_and_n
+#define funcname "mpn_and_n"
+#endif
+
+#ifdef OPERATION_andn_n
+#define func __gmpn_andn_n
+#define reffunc refmpn_andn_n
+#define funcname "mpn_andn_n"
+#endif
+
+#ifdef OPERATION_nand_n
+#define func __gmpn_nand_n
+#define reffunc refmpn_nand_n
+#define funcname "mpn_nand_n"
+#endif
+
+#ifdef OPERATION_ior_n
+#define func __gmpn_ior_n
+#define reffunc refmpn_ior_n
+#define funcname "mpn_ior_n"
+#endif
+
+#ifdef OPERATION_iorn_n
+#define func __gmpn_iorn_n
+#define reffunc refmpn_iorn_n
+#define funcname "mpn_iorn_n"
+#endif
+
+#ifdef OPERATION_nior_n
+#define func __gmpn_nior_n
+#define reffunc refmpn_nior_n
+#define funcname "mpn_nior_n"
+#endif
+
+#ifdef OPERATION_xor_n
+#define func __gmpn_xor_n
+#define reffunc refmpn_xor_n
+#define funcname "mpn_xor_n"
+#endif
+
+#ifdef OPERATION_xnor_n
+#define func __gmpn_xnor_n
+#define reffunc refmpn_xnor_n
+#define funcname "mpn_xnor_n"
+#endif
+
+#if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
+#include <time.h>
+
+int
+cputime ()
+{
+ if (CLOCKS_PER_SEC < 100000)
+ return clock () * 1000 / CLOCKS_PER_SEC;
+ return clock () / (CLOCKS_PER_SEC / 1000);
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+int
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#endif
+
+static void mpn_print (mp_ptr, mp_size_t);
+
+#define M * 1000000
+
+#ifndef CLOCK
+#error "Don't know CLOCK of your machine"
+#endif
+
+#ifndef OPS
+#define OPS (CLOCK/5)
+#endif
+#ifndef SIZE
+#define SIZE 328
+#endif
+#ifndef TIMES
+#define TIMES OPS/(SIZE+1)
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr s1, s2, dx, dy;
+ int i;
+ long t0, t;
+ unsigned int test;
+ mp_size_t size;
+ unsigned int ntests;
+
+ s1 = malloc (SIZE * sizeof (mp_limb_t));
+ s2 = malloc (SIZE * sizeof (mp_limb_t));
+ dx = malloc ((SIZE + 2) * sizeof (mp_limb_t));
+ dy = malloc ((SIZE + 2) * sizeof (mp_limb_t));
+
+ ntests = ~(unsigned) 0;
+ if (argc == 2)
+ ntests = strtol (argv[1], 0, 0);
+
+ for (test = 1; test <= ntests; test++)
+ {
+#if TIMES == 1 && ! defined (PRINT)
+ if (test % (SIZE > 100000 ? 1 : 100000 / SIZE) == 0)
+ {
+ printf ("\r%d", test);
+ fflush (stdout);
+ }
+#endif
+
+#ifdef RANDOM
+ size = random () % SIZE + 1;
+#else
+ size = SIZE;
+#endif
+
+ dx[0] = 0x87654321;
+ dy[0] = 0x87654321;
+ dx[size+1] = 0x12345678;
+ dy[size+1] = 0x12345678;
+
+#if TIMES != 1
+ mpn_random (s1, size);
+ mpn_random (s2, size);
+
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ func (dx+1, s1, s2, size);
+ t = cputime() - t0;
+ printf (funcname ": %5ldms (%.3f cycles/limb)\n",
+ t, ((double) t * CLOCK) / (TIMES * size * 1000.0));
+#endif
+
+#ifndef NOCHECK
+ mpn_random2 (s1, size);
+ mpn_random2 (s2, size);
+
+#ifdef PRINT
+ mpn_print (s1, size);
+ mpn_print (s2, size);
+#endif
+
+ /* Put garbage in the destination. */
+ for (i = 0; i < size; i++)
+ {
+ dx[i+1] = 0xdead;
+ dy[i+1] = 0xbeef;
+ }
+
+ reffunc (dx+1, s1, s2, size);
+ func (dy+1, s1, s2, size);
+#ifdef PRINT
+ mpn_print (dx+1, size);
+ mpn_print (dy+1, size);
+#endif
+ if (mpn_cmp (dx, dy, size+2) != 0
+ || dx[0] != 0x87654321 || dx[size+1] != 0x12345678)
+ {
+#ifndef PRINT
+ mpn_print (dx+1, size);
+ mpn_print (dy+1, size);
+#endif
+ printf ("\n");
+ if (dy[0] != 0x87654321)
+ printf ("clobbered at low end\n");
+ if (dy[size+1] != 0x12345678)
+ printf ("clobbered at high end\n");
+ printf ("TEST NUMBER %u\n", test);
+ abort();
+ }
+#endif
+ }
+ exit (0);
+}
+
+static void
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+#ifdef _LONG_LONG_LIMB
+ printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
+ (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
+ (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
+#else
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#endif
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gmp/tests/devel/shift.c b/gmp/tests/devel/shift.c
new file mode 100644
index 0000000000..611a776776
--- /dev/null
+++ b/gmp/tests/devel/shift.c
@@ -0,0 +1,245 @@
+/*
+Copyright 1996, 1998-2001, 2004, 2007, 2009, 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 <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifdef OPERATION_lshift
+#define func __gmpn_lshift
+#define reffunc refmpn_lshift
+#define funcname "mpn_lshift"
+#endif
+
+#ifdef OPERATION_rshift
+#define func __gmpn_rshift
+#define reffunc refmpn_rshift
+#define funcname "mpn_rshift"
+#endif
+
+#if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
+#include <time.h>
+
+int
+cputime ()
+{
+ if (CLOCKS_PER_SEC < 100000)
+ return clock () * 1000 / CLOCKS_PER_SEC;
+ return clock () / (CLOCKS_PER_SEC / 1000);
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+int
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#endif
+
+static void print_posneg (mp_limb_t);
+static void mpn_print (mp_ptr, mp_size_t);
+
+#define LXW ((int) (2 * sizeof (mp_limb_t)))
+#define M * 1000000
+
+#ifndef CLOCK
+#error "Don't know CLOCK of your machine"
+#endif
+
+#ifndef OPS
+#define OPS (CLOCK/5)
+#endif
+#ifndef SIZE
+#define SIZE 496
+#endif
+#ifndef TIMES
+#define TIMES OPS/(SIZE+1)
+#endif
+
+#ifndef CNT
+int CNT = 4;
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr s1, dx, dy;
+ mp_limb_t cyx, cyy;
+ int i;
+ long t0, t;
+ unsigned int test;
+ int cnt = CNT;
+ mp_size_t size;
+ unsigned int ntests;
+
+ s1 = malloc (SIZE * sizeof (mp_limb_t));
+ dx = malloc ((SIZE + 2) * sizeof (mp_limb_t));
+ dy = malloc ((SIZE + 2) * sizeof (mp_limb_t));
+
+ ntests = ~(unsigned) 0;
+ if (argc == 2)
+ ntests = strtol (argv[1], 0, 0);
+
+ for (test = 1; test <= ntests; test++)
+ {
+#if TIMES == 1 && ! defined (PRINT)
+ if (test % (SIZE > 100000 ? 1 : 100000 / SIZE) == 0)
+ {
+ printf ("\r%u", test);
+ fflush (stdout);
+ }
+#endif
+
+#if TIMES == 1
+ cnt = random () % (GMP_NUMB_BITS - 1) + 1;
+#endif
+
+#ifdef RANDOM
+ size = random () % SIZE + 1;
+#else
+ size = SIZE;
+#endif
+
+ dx[0] = 0x87654321;
+ dy[0] = 0x87654321;
+ dx[size+1] = 0x12345678;
+ dy[size+1] = 0x12345678;
+
+#if TIMES != 1
+ mpn_random (s1, size);
+
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ func (dx+1, s1, size, cnt);
+ t = cputime() - t0;
+ printf (funcname ": %5ldms (%.3f cycles/limb)\n",
+ t, ((double) t * CLOCK) / (TIMES * size * 1000.0));
+#endif
+
+#ifndef NOCHECK
+ mpn_random (s1, size);
+
+#ifdef PRINT
+ printf ("cnt=%-*d ", (int) (2 * sizeof(mp_limb_t)) - 4, cnt);
+ mpn_print (s1, size);
+#endif
+
+ /* Put garbage in the destination. */
+ for (i = 0; i < size; i++)
+ {
+ dx[i+1] = 0xdead;
+ dy[i+1] = 0xbeef;
+ }
+
+ cyx = reffunc (dx+1, s1, size, cnt);
+ cyy = func (dy+1, s1, size, cnt);
+
+#ifdef PRINT
+ mpn_print (&cyx, 1);
+ mpn_print (dx+1, size);
+ mpn_print (&cyy, 1);
+ mpn_print (dy+1, size);
+#endif
+
+ if (cyx != cyy || mpn_cmp (dx, dy, size+2) != 0
+ || dx[0] != 0x87654321 || dx[size+1] != 0x12345678)
+ {
+ mp_size_t s, e;
+ for (s = 0;; s++)
+ if ((unsigned long long) (dx+1)[s] != (unsigned long long) (dy+1)[s])
+ break;
+ for (e = size - 1;; e--)
+ if ((unsigned long long) (dx+1)[e] != (unsigned long long) (dy+1)[e])
+ break;
+#ifndef PRINT
+ printf ("cnt=%-*d\n", (int) (2 * sizeof(mp_limb_t)) - 4, cnt);
+ for (i = s; i <= e; i++)
+ {
+ printf ("%6d: ", i);
+ printf ("%0*llX ", LXW, (unsigned long long) (dx+1)[i]);
+ printf ("%0*llX ", LXW, (unsigned long long) (dy+1)[i]);
+ print_posneg ((dy+1)[i] - (dx+1)[i]);
+ printf ("\n");
+ }
+ printf ("%6s: ", "retval");
+ printf ("%0*llX ", LXW, (unsigned long long) cyx);
+ printf ("%0*llX ", LXW, (unsigned long long) cyy);
+ print_posneg (cyx - cyy);
+#endif
+ printf ("\n");
+ if (dy[0] != 0x87654321)
+ printf ("clobbered at low end\n");
+ if (dy[size+1] != 0x12345678)
+ printf ("clobbered at high end\n");
+ printf ("TEST NUMBER %u\n", test);
+ abort();
+ }
+#endif
+ }
+ exit (0);
+}
+
+static void
+print_posneg (mp_limb_t d)
+{
+ char buf[LXW + 2];
+ if (d == 0)
+ printf (" %*X", LXW, 0);
+ else if (-d < d)
+ {
+ sprintf (buf, "%llX", (unsigned long long) -d);
+ printf ("%*s-%s", LXW - (int) strlen (buf), "", buf);
+ }
+ else
+ {
+ sprintf (buf, "%llX", (unsigned long long) d);
+ printf ("%*s+%s", LXW - (int) strlen (buf), "", buf);
+ }
+}
+
+static void
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+#ifdef _LONG_LONG_LIMB
+ printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
+ (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
+ (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
+#else
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#endif
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gmp/tests/devel/try.c b/gmp/tests/devel/try.c
new file mode 100644
index 0000000000..3911bc0091
--- /dev/null
+++ b/gmp/tests/devel/try.c
@@ -0,0 +1,3608 @@
+/* Run some tests on various mpn routines.
+
+ THIS IS A TEST PROGRAM USED ONLY FOR DEVELOPMENT. IT'S ALMOST CERTAIN TO
+ BE SUBJECT TO INCOMPATIBLE CHANGES IN FUTURE VERSIONS OF GMP.
+
+Copyright 2000-2006, 2008, 2009, 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/. */
+
+
+/* Usage: try [options] <function>...
+
+ For example, "./try mpn_add_n" to run tests of that function.
+
+ Combinations of alignments and overlaps are tested, with redzones above
+ or below the destinations, and with the sources write-protected.
+
+ The number of tests performed becomes ridiculously large with all the
+ combinations, and for that reason this can't be a part of a "make check",
+ it's meant only for development. The code isn't very pretty either.
+
+ During development it can help to disable the redzones, since seeing the
+ rest of the destination written can show where the wrong part is, or if
+ the dst pointers are off by 1 or whatever. The magic DEADVAL initial
+ fill (see below) will show locations never written.
+
+ The -s option can be used to test only certain size operands, which is
+ useful if some new code doesn't yet support say sizes less than the
+ unrolling, or whatever.
+
+ When a problem occurs it'll of course be necessary to run the program
+ under gdb to find out quite where, how and why it's going wrong. Disable
+ the spinner with the -W option when doing this, or single stepping won't
+ work. Using the "-1" option to run with simple data can be useful.
+
+ New functions to test can be added in try_array[]. If a new TYPE is
+ required then add it to the existing constants, set up its parameters in
+ param_init(), and add it to the call() function. Extra parameter fields
+ can be added if necessary, or further interpretations given to existing
+ fields.
+
+
+ Portability:
+
+ This program is not designed for use on Cray vector systems under Unicos,
+ it will fail to compile due to missing _SC_PAGE_SIZE. Those systems
+ don't really have pages or mprotect. We could arrange to run the tests
+ without the redzones, but we haven't bothered currently.
+
+
+ Enhancements:
+
+ umul_ppmm support is not very good, lots of source data is generated
+ whereas only two limbs are needed.
+
+ Make a little scheme for interpreting the "SIZE" selections uniformly.
+
+ Make tr->size==SIZE_2 work, for the benefit of find_a which wants just 2
+ source limbs. Possibly increase the default repetitions in that case.
+
+ Automatically detect gdb and disable the spinner (use -W for now).
+
+ Make a way to re-run a failing case in the debugger. Have an option to
+ snapshot each test case before it's run so the data is available if a
+ segv occurs. (This should be more reliable than the current print_all()
+ in the signal handler.)
+
+ When alignment means a dst isn't hard against the redzone, check the
+ space in between remains unchanged.
+
+ When a source overlaps a destination, don't run both s[i].high 0 and 1,
+ as s[i].high has no effect. Maybe encode s[i].high into overlap->s[i].
+
+ When partial overlaps aren't done, don't loop over source alignments
+ during overlaps.
+
+ Try to make the looping code a bit less horrible. Right now it's pretty
+ hard to see what iterations are actually done.
+
+ Perhaps specific setups and loops for each style of function under test
+ would be clearer than a parameterized general loop. There's lots of
+ stuff common to all functions, but the exceptions get messy.
+
+ When there's no overlap, run with both src>dst and src<dst. A subtle
+ calling-conventions violation occurred in a P6 copy which depended on the
+ relative location of src and dst.
+
+ multiplier_N is more or less a third source region for the addmul_N
+ routines, and could be done with the redzoned region scheme.
+
+*/
+
+
+/* always do assertion checking */
+#define WANT_ASSERT 1
+
+#include "config.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+
+#if !HAVE_DECL_OPTARG
+extern char *optarg;
+extern int optind, opterr;
+#endif
+
+#if ! HAVE_DECL_SYS_NERR
+extern int sys_nerr;
+#endif
+
+#if ! HAVE_DECL_SYS_ERRLIST
+extern char *sys_errlist[];
+#endif
+
+#if ! HAVE_STRERROR
+char *
+strerror (int n)
+{
+ if (n < 0 || n >= sys_nerr)
+ return "errno out of range";
+ else
+ return sys_errlist[n];
+}
+#endif
+
+/* Rumour has it some systems lack a define of PROT_NONE. */
+#ifndef PROT_NONE
+#define PROT_NONE 0
+#endif
+
+/* Dummy defines for when mprotect doesn't exist. */
+#ifndef PROT_READ
+#define PROT_READ 0
+#endif
+#ifndef PROT_WRITE
+#define PROT_WRITE 0
+#endif
+
+/* _SC_PAGESIZE is standard, but hpux 9 and possibly other systems have
+ _SC_PAGE_SIZE instead. */
+#if defined (_SC_PAGE_SIZE) && ! defined (_SC_PAGESIZE)
+#define _SC_PAGESIZE _SC_PAGE_SIZE
+#endif
+
+
+#ifdef EXTRA_PROTOS
+EXTRA_PROTOS
+#endif
+#ifdef EXTRA_PROTOS2
+EXTRA_PROTOS2
+#endif
+
+
+#define DEFAULT_REPETITIONS 10
+
+int option_repetitions = DEFAULT_REPETITIONS;
+int option_spinner = 1;
+int option_redzones = 1;
+int option_firstsize = 0;
+int option_lastsize = 500;
+int option_firstsize2 = 0;
+
+#define ALIGNMENTS 4
+#define OVERLAPS 4
+#define CARRY_RANDOMS 5
+#define MULTIPLIER_RANDOMS 5
+#define DIVISOR_RANDOMS 5
+#define FRACTION_COUNT 4
+
+int option_print = 0;
+
+#define DATA_TRAND 0
+#define DATA_ZEROS 1
+#define DATA_SEQ 2
+#define DATA_FFS 3
+#define DATA_2FD 4
+int option_data = DATA_TRAND;
+
+
+mp_size_t pagesize;
+#define PAGESIZE_LIMBS (pagesize / GMP_LIMB_BYTES)
+
+/* must be a multiple of the page size */
+#define REDZONE_BYTES (pagesize * 16)
+#define REDZONE_LIMBS (REDZONE_BYTES / GMP_LIMB_BYTES)
+
+
+#define MAX3(x,y,z) (MAX (x, MAX (y, z)))
+
+#if GMP_LIMB_BITS == 32
+#define DEADVAL CNST_LIMB(0xDEADBEEF)
+#else
+#define DEADVAL CNST_LIMB(0xDEADBEEFBADDCAFE)
+#endif
+
+
+struct region_t {
+ mp_ptr ptr;
+ mp_size_t size;
+};
+
+
+#define TRAP_NOWHERE 0
+#define TRAP_REF 1
+#define TRAP_FUN 2
+#define TRAP_SETUPS 3
+int trap_location = TRAP_NOWHERE;
+
+
+#define NUM_SOURCES 5
+#define NUM_DESTS 2
+
+struct source_t {
+ struct region_t region;
+ int high;
+ mp_size_t align;
+ mp_ptr p;
+};
+
+struct source_t s[NUM_SOURCES];
+
+struct dest_t {
+ int high;
+ mp_size_t align;
+ mp_size_t size;
+};
+
+struct dest_t d[NUM_DESTS];
+
+struct source_each_t {
+ mp_ptr p;
+};
+
+struct dest_each_t {
+ struct region_t region;
+ mp_ptr p;
+};
+
+mp_size_t size;
+mp_size_t size2;
+unsigned long shift;
+mp_limb_t carry;
+mp_limb_t divisor;
+mp_limb_t multiplier;
+mp_limb_t multiplier_N[8];
+
+struct each_t {
+ const char *name;
+ struct dest_each_t d[NUM_DESTS];
+ struct source_each_t s[NUM_SOURCES];
+ mp_limb_t retval;
+};
+
+struct each_t ref = { "Ref" };
+struct each_t fun = { "Fun" };
+
+#define SRC_SIZE(n) ((n) == 1 && tr->size2 ? size2 : size)
+
+void validate_fail (void);
+
+
+#if HAVE_TRY_NEW_C
+#include "try-new.c"
+#endif
+
+
+typedef mp_limb_t (*tryfun_t) (ANYARGS);
+
+struct try_t {
+ char retval;
+
+ char src[NUM_SOURCES];
+ char dst[NUM_DESTS];
+
+#define SIZE_YES 1
+#define SIZE_ALLOW_ZERO 2
+#define SIZE_1 3 /* 1 limb */
+#define SIZE_2 4 /* 2 limbs */
+#define SIZE_3 5 /* 3 limbs */
+#define SIZE_4 6 /* 4 limbs */
+#define SIZE_6 7 /* 6 limbs */
+#define SIZE_FRACTION 8 /* size2 is fraction for divrem etc */
+#define SIZE_SIZE2 9
+#define SIZE_PLUS_1 10
+#define SIZE_SUM 11
+#define SIZE_DIFF 12
+#define SIZE_DIFF_PLUS_1 13
+#define SIZE_DIFF_PLUS_3 14
+#define SIZE_RETVAL 15
+#define SIZE_CEIL_HALF 16
+#define SIZE_GET_STR 17
+#define SIZE_PLUS_MSIZE_SUB_1 18 /* size+msize-1 */
+#define SIZE_ODD 19
+ char size;
+ char size2;
+ char dst_size[NUM_DESTS];
+
+ /* multiplier_N size in limbs */
+ mp_size_t msize;
+
+ char dst_bytes[NUM_DESTS];
+
+ char dst0_from_src1;
+
+#define CARRY_BIT 1 /* single bit 0 or 1 */
+#define CARRY_3 2 /* 0, 1, 2 */
+#define CARRY_4 3 /* 0 to 3 */
+#define CARRY_LIMB 4 /* any limb value */
+#define CARRY_DIVISOR 5 /* carry<divisor */
+ char carry;
+
+ /* a fudge to tell the output when to print negatives */
+ char carry_sign;
+
+ char multiplier;
+ char shift;
+
+#define DIVISOR_LIMB 1
+#define DIVISOR_NORM 2
+#define DIVISOR_ODD 3
+ char divisor;
+
+#define DATA_NON_ZERO 1
+#define DATA_GCD 2
+#define DATA_SRC0_ODD 3
+#define DATA_SRC0_HIGHBIT 4
+#define DATA_SRC1_ODD 5
+#define DATA_SRC1_ODD_PRIME 6
+#define DATA_SRC1_HIGHBIT 7
+#define DATA_MULTIPLE_DIVISOR 8
+#define DATA_UDIV_QRNND 9
+#define DATA_DIV_QR_1 10
+ char data;
+
+/* Default is allow full overlap. */
+#define OVERLAP_NONE 1
+#define OVERLAP_LOW_TO_HIGH 2
+#define OVERLAP_HIGH_TO_LOW 3
+#define OVERLAP_NOT_SRCS 4
+#define OVERLAP_NOT_SRC2 8
+#define OVERLAP_NOT_DST2 16
+ char overlap;
+
+ tryfun_t reference;
+ const char *reference_name;
+
+ void (*validate) (void);
+ const char *validate_name;
+};
+
+struct try_t *tr;
+
+
+void
+validate_mod_34lsub1 (void)
+{
+#define CNST_34LSUB1 ((CNST_LIMB(1) << (3 * (GMP_NUMB_BITS / 4))) - 1)
+
+ mp_srcptr ptr = s[0].p;
+ int error = 0;
+ mp_limb_t got, got_mod, want, want_mod;
+
+ ASSERT (size >= 1);
+
+ got = fun.retval;
+ got_mod = got % CNST_34LSUB1;
+
+ want = refmpn_mod_34lsub1 (ptr, size);
+ want_mod = want % CNST_34LSUB1;
+
+ if (got_mod != want_mod)
+ {
+ gmp_printf ("got 0x%MX reduced from 0x%MX\n", got_mod, got);
+ gmp_printf ("want 0x%MX reduced from 0x%MX\n", want_mod, want);
+ error = 1;
+ }
+
+ if (error)
+ validate_fail ();
+}
+
+void
+validate_divexact_1 (void)
+{
+ mp_srcptr src = s[0].p;
+ mp_srcptr dst = fun.d[0].p;
+ int error = 0;
+
+ ASSERT (size >= 1);
+
+ {
+ mp_ptr tp = refmpn_malloc_limbs (size);
+ mp_limb_t rem;
+
+ rem = refmpn_divrem_1 (tp, 0, src, size, divisor);
+ if (rem != 0)
+ {
+ gmp_printf ("Remainder a%%d == 0x%MX, mpn_divexact_1 undefined\n", rem);
+ error = 1;
+ }
+ if (! refmpn_equal_anynail (tp, dst, size))
+ {
+ printf ("Quotient a/d wrong\n");
+ mpn_trace ("fun ", dst, size);
+ mpn_trace ("want", tp, size);
+ error = 1;
+ }
+ free (tp);
+ }
+
+ if (error)
+ validate_fail ();
+}
+
+void
+validate_bdiv_q_1
+ (void)
+{
+ mp_srcptr src = s[0].p;
+ mp_srcptr dst = fun.d[0].p;
+ int error = 0;
+
+ ASSERT (size >= 1);
+
+ {
+ mp_ptr tp = refmpn_malloc_limbs (size + 1);
+
+ refmpn_mul_1 (tp, dst, size, divisor);
+ /* Set ignored low bits */
+ tp[0] |= (src[0] & LOW_ZEROS_MASK (divisor));
+ if (! refmpn_equal_anynail (tp, src, size))
+ {
+ printf ("Bdiv wrong: res * divisor != src (mod B^size)\n");
+ mpn_trace ("res ", dst, size);
+ mpn_trace ("src ", src, size);
+ error = 1;
+ }
+ free (tp);
+ }
+
+ if (error)
+ validate_fail ();
+}
+
+
+void
+validate_modexact_1c_odd (void)
+{
+ mp_srcptr ptr = s[0].p;
+ mp_limb_t r = fun.retval;
+ int error = 0;
+
+ ASSERT (size >= 1);
+ ASSERT (divisor & 1);
+
+ if ((r & GMP_NAIL_MASK) != 0)
+ printf ("r has non-zero nail\n");
+
+ if (carry < divisor)
+ {
+ if (! (r < divisor))
+ {
+ printf ("Don't have r < divisor\n");
+ error = 1;
+ }
+ }
+ else /* carry >= divisor */
+ {
+ if (! (r <= divisor))
+ {
+ printf ("Don't have r <= divisor\n");
+ error = 1;
+ }
+ }
+
+ {
+ mp_limb_t c = carry % divisor;
+ mp_ptr tp = refmpn_malloc_limbs (size+1);
+ mp_size_t k;
+
+ for (k = size-1; k <= size; k++)
+ {
+ /* set {tp,size+1} to r*b^k + a - c */
+ refmpn_copyi (tp, ptr, size);
+ tp[size] = 0;
+ ASSERT_NOCARRY (refmpn_add_1 (tp+k, tp+k, size+1-k, r));
+ if (refmpn_sub_1 (tp, tp, size+1, c))
+ ASSERT_CARRY (mpn_add_1 (tp, tp, size+1, divisor));
+
+ if (refmpn_mod_1 (tp, size+1, divisor) == 0)
+ goto good_remainder;
+ }
+ printf ("Remainder matches neither r*b^(size-1) nor r*b^size\n");
+ error = 1;
+
+ good_remainder:
+ free (tp);
+ }
+
+ if (error)
+ validate_fail ();
+}
+
+void
+validate_modexact_1_odd (void)
+{
+ carry = 0;
+ validate_modexact_1c_odd ();
+}
+
+void
+validate_div_qr_1_pi1 (void)
+{
+ mp_srcptr up = ref.s[0].p;
+ mp_size_t un = size;
+ mp_size_t uh = ref.s[1].p[0];
+ mp_srcptr qp = fun.d[0].p;
+ mp_limb_t r = fun.retval;
+ mp_limb_t cy;
+ int cmp;
+ mp_ptr tp;
+ if (r >= divisor)
+ {
+ gmp_printf ("Bad remainder %Md, d = %Md\n", r, divisor);
+ validate_fail ();
+ }
+ tp = refmpn_malloc_limbs (un);
+ cy = refmpn_mul_1 (tp, qp, un, divisor);
+ cy += refmpn_add_1 (tp, tp, un, r);
+ if (cy != uh || refmpn_cmp (tp, up, un) != 0)
+ {
+ gmp_printf ("Incorrect result, size %ld.\n"
+ "d = %Mx, u = %Mx, %Nx\n"
+ "got: r = %Mx, q = %Nx\n"
+ "q d + r = %Mx, %Nx",
+ (long) un,
+ divisor, uh, up, un,
+ r, qp, un,
+ cy, tp, un);
+ validate_fail ();
+ }
+ free (tp);
+}
+
+
+void
+validate_sqrtrem (void)
+{
+ mp_srcptr orig_ptr = s[0].p;
+ mp_size_t orig_size = size;
+ mp_size_t root_size = (size+1)/2;
+ mp_srcptr root_ptr = fun.d[0].p;
+ mp_size_t rem_size = fun.retval;
+ mp_srcptr rem_ptr = fun.d[1].p;
+ mp_size_t prod_size = 2*root_size;
+ mp_ptr p;
+ int error = 0;
+
+ if (rem_size < 0 || rem_size > size)
+ {
+ printf ("Bad remainder size retval %ld\n", (long) rem_size);
+ validate_fail ();
+ }
+
+ p = refmpn_malloc_limbs (prod_size);
+
+ p[root_size] = refmpn_lshift (p, root_ptr, root_size, 1);
+ if (refmpn_cmp_twosizes (p,root_size+1, rem_ptr,rem_size) < 0)
+ {
+ printf ("Remainder bigger than 2*root\n");
+ error = 1;
+ }
+
+ refmpn_sqr (p, root_ptr, root_size);
+ if (rem_size != 0)
+ refmpn_add (p, p, prod_size, rem_ptr, rem_size);
+ if (refmpn_cmp_twosizes (p,prod_size, orig_ptr,orig_size) != 0)
+ {
+ printf ("root^2+rem != original\n");
+ mpn_trace ("prod", p, prod_size);
+ error = 1;
+ }
+ free (p);
+
+ if (error)
+ validate_fail ();
+}
+
+
+/* These types are indexes into the param[] array and are arbitrary so long
+ as they're all distinct and within the size of param[]. Renumber
+ whenever necessary or desired. */
+
+enum {
+ TYPE_ADD = 1, TYPE_ADD_N, TYPE_ADD_NC, TYPE_SUB, TYPE_SUB_N, TYPE_SUB_NC,
+
+ TYPE_ADD_ERR1_N, TYPE_ADD_ERR2_N, TYPE_ADD_ERR3_N,
+ TYPE_SUB_ERR1_N, TYPE_SUB_ERR2_N, TYPE_SUB_ERR3_N,
+
+ TYPE_MUL_1, TYPE_MUL_1C,
+
+ TYPE_MUL_2, TYPE_MUL_3, TYPE_MUL_4, TYPE_MUL_5, TYPE_MUL_6,
+
+ TYPE_ADDMUL_1, TYPE_ADDMUL_1C, TYPE_SUBMUL_1, TYPE_SUBMUL_1C,
+
+ TYPE_ADDMUL_2, TYPE_ADDMUL_3, TYPE_ADDMUL_4, TYPE_ADDMUL_5, TYPE_ADDMUL_6,
+ TYPE_ADDMUL_7, TYPE_ADDMUL_8,
+
+ TYPE_ADDSUB_N, TYPE_ADDSUB_NC,
+
+ TYPE_RSHIFT, TYPE_LSHIFT, TYPE_LSHIFTC,
+
+ TYPE_COPY, TYPE_COPYI, TYPE_COPYD, TYPE_COM,
+
+ TYPE_ADDLSH1_N, TYPE_ADDLSH2_N, TYPE_ADDLSH_N,
+ TYPE_ADDLSH1_N_IP1, TYPE_ADDLSH2_N_IP1, TYPE_ADDLSH_N_IP1,
+ TYPE_ADDLSH1_N_IP2, TYPE_ADDLSH2_N_IP2, TYPE_ADDLSH_N_IP2,
+ TYPE_SUBLSH1_N, TYPE_SUBLSH2_N, TYPE_SUBLSH_N,
+ TYPE_SUBLSH1_N_IP1, TYPE_SUBLSH2_N_IP1, TYPE_SUBLSH_N_IP1,
+ TYPE_RSBLSH1_N, TYPE_RSBLSH2_N, TYPE_RSBLSH_N,
+ TYPE_RSH1ADD_N, TYPE_RSH1SUB_N,
+
+ TYPE_ADDLSH1_NC, TYPE_ADDLSH2_NC, TYPE_ADDLSH_NC,
+ TYPE_SUBLSH1_NC, TYPE_SUBLSH2_NC, TYPE_SUBLSH_NC,
+ TYPE_RSBLSH1_NC, TYPE_RSBLSH2_NC, TYPE_RSBLSH_NC,
+
+ TYPE_ADDCND_N, TYPE_SUBCND_N,
+
+ TYPE_MOD_1, TYPE_MOD_1C, TYPE_DIVMOD_1, TYPE_DIVMOD_1C, TYPE_DIVREM_1,
+ TYPE_DIVREM_1C, TYPE_PREINV_DIVREM_1, TYPE_DIVREM_2, TYPE_PREINV_MOD_1,
+ TYPE_DIV_QR_1N_PI1,
+ TYPE_MOD_34LSUB1, TYPE_UDIV_QRNND, TYPE_UDIV_QRNND_R,
+
+ TYPE_DIVEXACT_1, TYPE_BDIV_Q_1, TYPE_DIVEXACT_BY3, TYPE_DIVEXACT_BY3C,
+ TYPE_MODEXACT_1_ODD, TYPE_MODEXACT_1C_ODD,
+
+ TYPE_INVERT, TYPE_BINVERT,
+
+ TYPE_GCD, TYPE_GCD_1, TYPE_GCD_FINDA, TYPE_MPZ_JACOBI, TYPE_MPZ_KRONECKER,
+ TYPE_MPZ_KRONECKER_UI, TYPE_MPZ_KRONECKER_SI, TYPE_MPZ_UI_KRONECKER,
+ TYPE_MPZ_SI_KRONECKER, TYPE_MPZ_LEGENDRE,
+
+ TYPE_AND_N, TYPE_NAND_N, TYPE_ANDN_N, TYPE_IOR_N, TYPE_IORN_N, TYPE_NIOR_N,
+ TYPE_XOR_N, TYPE_XNOR_N,
+
+ TYPE_MUL_MN, TYPE_MUL_N, TYPE_SQR, TYPE_UMUL_PPMM, TYPE_UMUL_PPMM_R,
+ TYPE_MULLO_N, TYPE_MULMID_MN, TYPE_MULMID_N,
+
+ TYPE_SBPI1_DIV_QR, TYPE_TDIV_QR,
+
+ TYPE_SQRTREM, TYPE_ZERO, TYPE_GET_STR, TYPE_POPCOUNT, TYPE_HAMDIST,
+
+ TYPE_EXTRA
+};
+
+struct try_t param[TYPE_EXTRA];
+
+
+void
+param_init (void)
+{
+ struct try_t *p;
+
+#define COPY(index) memcpy (p, &param[index], sizeof (*p))
+
+#if HAVE_STRINGIZE
+#define REFERENCE(fun) \
+ p->reference = (tryfun_t) fun; \
+ p->reference_name = #fun
+#define VALIDATE(fun) \
+ p->validate = fun; \
+ p->validate_name = #fun
+#else
+#define REFERENCE(fun) \
+ p->reference = (tryfun_t) fun; \
+ p->reference_name = "fun"
+#define VALIDATE(fun) \
+ p->validate = fun; \
+ p->validate_name = "fun"
+#endif
+
+
+ p = &param[TYPE_ADD_N];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ REFERENCE (refmpn_add_n);
+
+ p = &param[TYPE_ADD_NC];
+ COPY (TYPE_ADD_N);
+ p->carry = CARRY_BIT;
+ REFERENCE (refmpn_add_nc);
+
+ p = &param[TYPE_SUB_N];
+ COPY (TYPE_ADD_N);
+ REFERENCE (refmpn_sub_n);
+
+ p = &param[TYPE_SUB_NC];
+ COPY (TYPE_ADD_NC);
+ REFERENCE (refmpn_sub_nc);
+
+ p = &param[TYPE_ADD];
+ COPY (TYPE_ADD_N);
+ p->size = SIZE_ALLOW_ZERO;
+ p->size2 = 1;
+ REFERENCE (refmpn_add);
+
+ p = &param[TYPE_SUB];
+ COPY (TYPE_ADD);
+ REFERENCE (refmpn_sub);
+
+
+ p = &param[TYPE_ADD_ERR1_N];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->dst[1] = 1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ p->src[2] = 1;
+ p->dst_size[1] = SIZE_2;
+ p->carry = CARRY_BIT;
+ p->overlap = OVERLAP_NOT_DST2;
+ REFERENCE (refmpn_add_err1_n);
+
+ p = &param[TYPE_SUB_ERR1_N];
+ COPY (TYPE_ADD_ERR1_N);
+ REFERENCE (refmpn_sub_err1_n);
+
+ p = &param[TYPE_ADD_ERR2_N];
+ COPY (TYPE_ADD_ERR1_N);
+ p->src[3] = 1;
+ p->dst_size[1] = SIZE_4;
+ REFERENCE (refmpn_add_err2_n);
+
+ p = &param[TYPE_SUB_ERR2_N];
+ COPY (TYPE_ADD_ERR2_N);
+ REFERENCE (refmpn_sub_err2_n);
+
+ p = &param[TYPE_ADD_ERR3_N];
+ COPY (TYPE_ADD_ERR2_N);
+ p->src[4] = 1;
+ p->dst_size[1] = SIZE_6;
+ REFERENCE (refmpn_add_err3_n);
+
+ p = &param[TYPE_SUB_ERR3_N];
+ COPY (TYPE_ADD_ERR3_N);
+ REFERENCE (refmpn_sub_err3_n);
+
+ p = &param[TYPE_ADDCND_N];
+ COPY (TYPE_ADD_N);
+ p->carry = CARRY_BIT;
+ REFERENCE (refmpn_cnd_add_n);
+
+ p = &param[TYPE_SUBCND_N];
+ COPY (TYPE_ADD_N);
+ p->carry = CARRY_BIT;
+ REFERENCE (refmpn_cnd_sub_n);
+
+
+ p = &param[TYPE_MUL_1];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->multiplier = 1;
+ p->overlap = OVERLAP_LOW_TO_HIGH;
+ REFERENCE (refmpn_mul_1);
+
+ p = &param[TYPE_MUL_1C];
+ COPY (TYPE_MUL_1);
+ p->carry = CARRY_LIMB;
+ REFERENCE (refmpn_mul_1c);
+
+
+ p = &param[TYPE_MUL_2];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->dst_size[0] = SIZE_PLUS_MSIZE_SUB_1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ p->msize = 2;
+ p->overlap = OVERLAP_NOT_SRC2;
+ REFERENCE (refmpn_mul_2);
+
+ p = &param[TYPE_MUL_3];
+ COPY (TYPE_MUL_2);
+ p->msize = 3;
+ REFERENCE (refmpn_mul_3);
+
+ p = &param[TYPE_MUL_4];
+ COPY (TYPE_MUL_2);
+ p->msize = 4;
+ REFERENCE (refmpn_mul_4);
+
+ p = &param[TYPE_MUL_5];
+ COPY (TYPE_MUL_2);
+ p->msize = 5;
+ REFERENCE (refmpn_mul_5);
+
+ p = &param[TYPE_MUL_6];
+ COPY (TYPE_MUL_2);
+ p->msize = 6;
+ REFERENCE (refmpn_mul_6);
+
+
+ p = &param[TYPE_ADDMUL_1];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->multiplier = 1;
+ p->dst0_from_src1 = 1;
+ REFERENCE (refmpn_addmul_1);
+
+ p = &param[TYPE_ADDMUL_1C];
+ COPY (TYPE_ADDMUL_1);
+ p->carry = CARRY_LIMB;
+ REFERENCE (refmpn_addmul_1c);
+
+ p = &param[TYPE_SUBMUL_1];
+ COPY (TYPE_ADDMUL_1);
+ REFERENCE (refmpn_submul_1);
+
+ p = &param[TYPE_SUBMUL_1C];
+ COPY (TYPE_ADDMUL_1C);
+ REFERENCE (refmpn_submul_1c);
+
+
+ p = &param[TYPE_ADDMUL_2];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->dst_size[0] = SIZE_PLUS_MSIZE_SUB_1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ p->msize = 2;
+ p->dst0_from_src1 = 1;
+ p->overlap = OVERLAP_NONE;
+ REFERENCE (refmpn_addmul_2);
+
+ p = &param[TYPE_ADDMUL_3];
+ COPY (TYPE_ADDMUL_2);
+ p->msize = 3;
+ REFERENCE (refmpn_addmul_3);
+
+ p = &param[TYPE_ADDMUL_4];
+ COPY (TYPE_ADDMUL_2);
+ p->msize = 4;
+ REFERENCE (refmpn_addmul_4);
+
+ p = &param[TYPE_ADDMUL_5];
+ COPY (TYPE_ADDMUL_2);
+ p->msize = 5;
+ REFERENCE (refmpn_addmul_5);
+
+ p = &param[TYPE_ADDMUL_6];
+ COPY (TYPE_ADDMUL_2);
+ p->msize = 6;
+ REFERENCE (refmpn_addmul_6);
+
+ p = &param[TYPE_ADDMUL_7];
+ COPY (TYPE_ADDMUL_2);
+ p->msize = 7;
+ REFERENCE (refmpn_addmul_7);
+
+ p = &param[TYPE_ADDMUL_8];
+ COPY (TYPE_ADDMUL_2);
+ p->msize = 8;
+ REFERENCE (refmpn_addmul_8);
+
+
+ p = &param[TYPE_AND_N];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ REFERENCE (refmpn_and_n);
+
+ p = &param[TYPE_ANDN_N];
+ COPY (TYPE_AND_N);
+ REFERENCE (refmpn_andn_n);
+
+ p = &param[TYPE_NAND_N];
+ COPY (TYPE_AND_N);
+ REFERENCE (refmpn_nand_n);
+
+ p = &param[TYPE_IOR_N];
+ COPY (TYPE_AND_N);
+ REFERENCE (refmpn_ior_n);
+
+ p = &param[TYPE_IORN_N];
+ COPY (TYPE_AND_N);
+ REFERENCE (refmpn_iorn_n);
+
+ p = &param[TYPE_NIOR_N];
+ COPY (TYPE_AND_N);
+ REFERENCE (refmpn_nior_n);
+
+ p = &param[TYPE_XOR_N];
+ COPY (TYPE_AND_N);
+ REFERENCE (refmpn_xor_n);
+
+ p = &param[TYPE_XNOR_N];
+ COPY (TYPE_AND_N);
+ REFERENCE (refmpn_xnor_n);
+
+
+ p = &param[TYPE_ADDSUB_N];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->dst[1] = 1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ REFERENCE (refmpn_add_n_sub_n);
+
+ p = &param[TYPE_ADDSUB_NC];
+ COPY (TYPE_ADDSUB_N);
+ p->carry = CARRY_4;
+ REFERENCE (refmpn_add_n_sub_nc);
+
+
+ p = &param[TYPE_COPY];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->overlap = OVERLAP_NONE;
+ p->size = SIZE_ALLOW_ZERO;
+ REFERENCE (refmpn_copy);
+
+ p = &param[TYPE_COPYI];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->overlap = OVERLAP_LOW_TO_HIGH;
+ p->size = SIZE_ALLOW_ZERO;
+ REFERENCE (refmpn_copyi);
+
+ p = &param[TYPE_COPYD];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->overlap = OVERLAP_HIGH_TO_LOW;
+ p->size = SIZE_ALLOW_ZERO;
+ REFERENCE (refmpn_copyd);
+
+ p = &param[TYPE_COM];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ REFERENCE (refmpn_com);
+
+
+ p = &param[TYPE_ADDLSH1_N];
+ COPY (TYPE_ADD_N);
+ REFERENCE (refmpn_addlsh1_n);
+
+ p = &param[TYPE_ADDLSH2_N];
+ COPY (TYPE_ADD_N);
+ REFERENCE (refmpn_addlsh2_n);
+
+ p = &param[TYPE_ADDLSH_N];
+ COPY (TYPE_ADD_N);
+ p->shift = 1;
+ REFERENCE (refmpn_addlsh_n);
+
+ p = &param[TYPE_ADDLSH1_N_IP1];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->dst0_from_src1 = 1;
+ REFERENCE (refmpn_addlsh1_n_ip1);
+
+ p = &param[TYPE_ADDLSH2_N_IP1];
+ COPY (TYPE_ADDLSH1_N_IP1);
+ REFERENCE (refmpn_addlsh2_n_ip1);
+
+ p = &param[TYPE_ADDLSH_N_IP1];
+ COPY (TYPE_ADDLSH1_N_IP1);
+ p->shift = 1;
+ REFERENCE (refmpn_addlsh_n_ip1);
+
+ p = &param[TYPE_ADDLSH1_N_IP2];
+ COPY (TYPE_ADDLSH1_N_IP1);
+ REFERENCE (refmpn_addlsh1_n_ip2);
+
+ p = &param[TYPE_ADDLSH2_N_IP2];
+ COPY (TYPE_ADDLSH1_N_IP1);
+ REFERENCE (refmpn_addlsh2_n_ip2);
+
+ p = &param[TYPE_ADDLSH_N_IP2];
+ COPY (TYPE_ADDLSH_N_IP1);
+ REFERENCE (refmpn_addlsh_n_ip2);
+
+ p = &param[TYPE_SUBLSH1_N];
+ COPY (TYPE_ADD_N);
+ REFERENCE (refmpn_sublsh1_n);
+
+ p = &param[TYPE_SUBLSH2_N];
+ COPY (TYPE_ADD_N);
+ REFERENCE (refmpn_sublsh2_n);
+
+ p = &param[TYPE_SUBLSH_N];
+ COPY (TYPE_ADDLSH_N);
+ REFERENCE (refmpn_sublsh_n);
+
+ p = &param[TYPE_SUBLSH1_N_IP1];
+ COPY (TYPE_ADDLSH1_N_IP1);
+ REFERENCE (refmpn_sublsh1_n_ip1);
+
+ p = &param[TYPE_SUBLSH2_N_IP1];
+ COPY (TYPE_ADDLSH1_N_IP1);
+ REFERENCE (refmpn_sublsh2_n_ip1);
+
+ p = &param[TYPE_SUBLSH_N_IP1];
+ COPY (TYPE_ADDLSH_N_IP1);
+ REFERENCE (refmpn_sublsh_n_ip1);
+
+ p = &param[TYPE_RSBLSH1_N];
+ COPY (TYPE_ADD_N);
+ REFERENCE (refmpn_rsblsh1_n);
+
+ p = &param[TYPE_RSBLSH2_N];
+ COPY (TYPE_ADD_N);
+ REFERENCE (refmpn_rsblsh2_n);
+
+ p = &param[TYPE_RSBLSH_N];
+ COPY (TYPE_ADDLSH_N);
+ REFERENCE (refmpn_rsblsh_n);
+
+ p = &param[TYPE_RSH1ADD_N];
+ COPY (TYPE_ADD_N);
+ REFERENCE (refmpn_rsh1add_n);
+
+ p = &param[TYPE_RSH1SUB_N];
+ COPY (TYPE_ADD_N);
+ REFERENCE (refmpn_rsh1sub_n);
+
+
+ p = &param[TYPE_ADDLSH1_NC];
+ COPY (TYPE_ADDLSH1_N);
+ p->carry = CARRY_3;
+ REFERENCE (refmpn_addlsh1_nc);
+
+ p = &param[TYPE_ADDLSH2_NC];
+ COPY (TYPE_ADDLSH2_N);
+ p->carry = CARRY_4; /* FIXME */
+ REFERENCE (refmpn_addlsh2_nc);
+
+ p = &param[TYPE_ADDLSH_NC];
+ COPY (TYPE_ADDLSH_N);
+ p->carry = CARRY_BIT; /* FIXME */
+ REFERENCE (refmpn_addlsh_nc);
+
+ p = &param[TYPE_SUBLSH1_NC];
+ COPY (TYPE_ADDLSH1_NC);
+ REFERENCE (refmpn_sublsh1_nc);
+
+ p = &param[TYPE_SUBLSH2_NC];
+ COPY (TYPE_ADDLSH2_NC);
+ REFERENCE (refmpn_sublsh2_nc);
+
+ p = &param[TYPE_SUBLSH_NC];
+ COPY (TYPE_ADDLSH_NC);
+ REFERENCE (refmpn_sublsh_nc);
+
+ p = &param[TYPE_RSBLSH1_NC];
+ COPY (TYPE_RSBLSH1_N);
+ p->carry = CARRY_BIT; /* FIXME */
+ REFERENCE (refmpn_rsblsh1_nc);
+
+ p = &param[TYPE_RSBLSH2_NC];
+ COPY (TYPE_RSBLSH2_N);
+ p->carry = CARRY_4; /* FIXME */
+ REFERENCE (refmpn_rsblsh2_nc);
+
+ p = &param[TYPE_RSBLSH_NC];
+ COPY (TYPE_RSBLSH_N);
+ p->carry = CARRY_BIT; /* FIXME */
+ REFERENCE (refmpn_rsblsh_nc);
+
+
+ p = &param[TYPE_MOD_1];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->size = SIZE_ALLOW_ZERO;
+ p->divisor = DIVISOR_LIMB;
+ REFERENCE (refmpn_mod_1);
+
+ p = &param[TYPE_MOD_1C];
+ COPY (TYPE_MOD_1);
+ p->carry = CARRY_DIVISOR;
+ REFERENCE (refmpn_mod_1c);
+
+ p = &param[TYPE_DIVMOD_1];
+ COPY (TYPE_MOD_1);
+ p->dst[0] = 1;
+ REFERENCE (refmpn_divmod_1);
+
+ p = &param[TYPE_DIVMOD_1C];
+ COPY (TYPE_DIVMOD_1);
+ p->carry = CARRY_DIVISOR;
+ REFERENCE (refmpn_divmod_1c);
+
+ p = &param[TYPE_DIVREM_1];
+ COPY (TYPE_DIVMOD_1);
+ p->size2 = SIZE_FRACTION;
+ p->dst_size[0] = SIZE_SUM;
+ REFERENCE (refmpn_divrem_1);
+
+ p = &param[TYPE_DIVREM_1C];
+ COPY (TYPE_DIVREM_1);
+ p->carry = CARRY_DIVISOR;
+ REFERENCE (refmpn_divrem_1c);
+
+ p = &param[TYPE_PREINV_DIVREM_1];
+ COPY (TYPE_DIVREM_1);
+ p->size = SIZE_YES; /* ie. no size==0 */
+ REFERENCE (refmpn_preinv_divrem_1);
+
+ p = &param[TYPE_DIV_QR_1N_PI1];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ /* SIZE_1 not supported. Always uses low limb only. */
+ p->size2 = 1;
+ p->dst[0] = 1;
+ p->divisor = DIVISOR_NORM;
+ p->data = DATA_DIV_QR_1;
+ VALIDATE (validate_div_qr_1_pi1);
+
+ p = &param[TYPE_PREINV_MOD_1];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->divisor = DIVISOR_NORM;
+ REFERENCE (refmpn_preinv_mod_1);
+
+ p = &param[TYPE_MOD_34LSUB1];
+ p->retval = 1;
+ p->src[0] = 1;
+ VALIDATE (validate_mod_34lsub1);
+
+ p = &param[TYPE_UDIV_QRNND];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->dst[0] = 1;
+ p->dst_size[0] = SIZE_1;
+ p->divisor = UDIV_NEEDS_NORMALIZATION ? DIVISOR_NORM : DIVISOR_LIMB;
+ p->data = DATA_UDIV_QRNND;
+ p->overlap = OVERLAP_NONE;
+ REFERENCE (refmpn_udiv_qrnnd);
+
+ p = &param[TYPE_UDIV_QRNND_R];
+ COPY (TYPE_UDIV_QRNND);
+ REFERENCE (refmpn_udiv_qrnnd_r);
+
+
+ p = &param[TYPE_DIVEXACT_1];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->divisor = DIVISOR_LIMB;
+ p->data = DATA_MULTIPLE_DIVISOR;
+ VALIDATE (validate_divexact_1);
+ REFERENCE (refmpn_divmod_1);
+
+ p = &param[TYPE_BDIV_Q_1];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->divisor = DIVISOR_LIMB;
+ VALIDATE (validate_bdiv_q_1);
+
+ p = &param[TYPE_DIVEXACT_BY3];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ REFERENCE (refmpn_divexact_by3);
+
+ p = &param[TYPE_DIVEXACT_BY3C];
+ COPY (TYPE_DIVEXACT_BY3);
+ p->carry = CARRY_3;
+ REFERENCE (refmpn_divexact_by3c);
+
+
+ p = &param[TYPE_MODEXACT_1_ODD];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->divisor = DIVISOR_ODD;
+ VALIDATE (validate_modexact_1_odd);
+
+ p = &param[TYPE_MODEXACT_1C_ODD];
+ COPY (TYPE_MODEXACT_1_ODD);
+ p->carry = CARRY_LIMB;
+ VALIDATE (validate_modexact_1c_odd);
+
+
+ p = &param[TYPE_GCD_1];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->data = DATA_NON_ZERO;
+ p->divisor = DIVISOR_LIMB;
+ REFERENCE (refmpn_gcd_1);
+
+ p = &param[TYPE_GCD];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ p->size2 = 1;
+ p->dst_size[0] = SIZE_RETVAL;
+ p->overlap = OVERLAP_NOT_SRCS;
+ p->data = DATA_GCD;
+ REFERENCE (refmpn_gcd);
+
+
+ p = &param[TYPE_MPZ_LEGENDRE];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->size = SIZE_ALLOW_ZERO;
+ p->src[1] = 1;
+ p->data = DATA_SRC1_ODD_PRIME;
+ p->size2 = 1;
+ p->carry = CARRY_BIT;
+ p->carry_sign = 1;
+ REFERENCE (refmpz_legendre);
+
+ p = &param[TYPE_MPZ_JACOBI];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->size = SIZE_ALLOW_ZERO;
+ p->src[1] = 1;
+ p->data = DATA_SRC1_ODD;
+ p->size2 = 1;
+ p->carry = CARRY_BIT;
+ p->carry_sign = 1;
+ REFERENCE (refmpz_jacobi);
+
+ p = &param[TYPE_MPZ_KRONECKER];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->size = SIZE_ALLOW_ZERO;
+ p->src[1] = 1;
+ p->data = 0;
+ p->size2 = 1;
+ p->carry = CARRY_4;
+ p->carry_sign = 1;
+ REFERENCE (refmpz_kronecker);
+
+
+ p = &param[TYPE_MPZ_KRONECKER_UI];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->size = SIZE_ALLOW_ZERO;
+ p->multiplier = 1;
+ p->carry = CARRY_BIT;
+ REFERENCE (refmpz_kronecker_ui);
+
+ p = &param[TYPE_MPZ_KRONECKER_SI];
+ COPY (TYPE_MPZ_KRONECKER_UI);
+ REFERENCE (refmpz_kronecker_si);
+
+ p = &param[TYPE_MPZ_UI_KRONECKER];
+ COPY (TYPE_MPZ_KRONECKER_UI);
+ REFERENCE (refmpz_ui_kronecker);
+
+ p = &param[TYPE_MPZ_SI_KRONECKER];
+ COPY (TYPE_MPZ_KRONECKER_UI);
+ REFERENCE (refmpz_si_kronecker);
+
+
+ p = &param[TYPE_SQR];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->dst_size[0] = SIZE_SUM;
+ p->overlap = OVERLAP_NONE;
+ REFERENCE (refmpn_sqr);
+
+ p = &param[TYPE_MUL_N];
+ COPY (TYPE_SQR);
+ p->src[1] = 1;
+ REFERENCE (refmpn_mul_n);
+
+ p = &param[TYPE_MULLO_N];
+ COPY (TYPE_MUL_N);
+ p->dst_size[0] = 0;
+ REFERENCE (refmpn_mullo_n);
+
+ p = &param[TYPE_MUL_MN];
+ COPY (TYPE_MUL_N);
+ p->size2 = 1;
+ REFERENCE (refmpn_mul_basecase);
+
+ p = &param[TYPE_MULMID_MN];
+ COPY (TYPE_MUL_MN);
+ p->dst_size[0] = SIZE_DIFF_PLUS_3;
+ REFERENCE (refmpn_mulmid_basecase);
+
+ p = &param[TYPE_MULMID_N];
+ COPY (TYPE_MUL_N);
+ p->size = SIZE_ODD;
+ p->size2 = SIZE_CEIL_HALF;
+ p->dst_size[0] = SIZE_DIFF_PLUS_3;
+ REFERENCE (refmpn_mulmid_n);
+
+ p = &param[TYPE_UMUL_PPMM];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->dst[0] = 1;
+ p->dst_size[0] = SIZE_1;
+ p->overlap = OVERLAP_NONE;
+ REFERENCE (refmpn_umul_ppmm);
+
+ p = &param[TYPE_UMUL_PPMM_R];
+ COPY (TYPE_UMUL_PPMM);
+ REFERENCE (refmpn_umul_ppmm_r);
+
+
+ p = &param[TYPE_RSHIFT];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->shift = 1;
+ p->overlap = OVERLAP_LOW_TO_HIGH;
+ REFERENCE (refmpn_rshift);
+
+ p = &param[TYPE_LSHIFT];
+ COPY (TYPE_RSHIFT);
+ p->overlap = OVERLAP_HIGH_TO_LOW;
+ REFERENCE (refmpn_lshift);
+
+ p = &param[TYPE_LSHIFTC];
+ COPY (TYPE_RSHIFT);
+ p->overlap = OVERLAP_HIGH_TO_LOW;
+ REFERENCE (refmpn_lshiftc);
+
+
+ p = &param[TYPE_POPCOUNT];
+ p->retval = 1;
+ p->src[0] = 1;
+ REFERENCE (refmpn_popcount);
+
+ p = &param[TYPE_HAMDIST];
+ COPY (TYPE_POPCOUNT);
+ p->src[1] = 1;
+ REFERENCE (refmpn_hamdist);
+
+
+ p = &param[TYPE_SBPI1_DIV_QR];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->dst[1] = 1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ p->data = DATA_SRC1_HIGHBIT;
+ p->size2 = 1;
+ p->dst_size[0] = SIZE_DIFF;
+ p->overlap = OVERLAP_NONE;
+ REFERENCE (refmpn_sb_div_qr);
+
+ p = &param[TYPE_TDIV_QR];
+ p->dst[0] = 1;
+ p->dst[1] = 1;
+ p->src[0] = 1;
+ p->src[1] = 1;
+ p->size2 = 1;
+ p->dst_size[0] = SIZE_DIFF_PLUS_1;
+ p->dst_size[1] = SIZE_SIZE2;
+ p->overlap = OVERLAP_NONE;
+ REFERENCE (refmpn_tdiv_qr);
+
+ p = &param[TYPE_SQRTREM];
+ p->retval = 1;
+ p->dst[0] = 1;
+ p->dst[1] = 1;
+ p->src[0] = 1;
+ p->dst_size[0] = SIZE_CEIL_HALF;
+ p->dst_size[1] = SIZE_RETVAL;
+ p->overlap = OVERLAP_NONE;
+ VALIDATE (validate_sqrtrem);
+ REFERENCE (refmpn_sqrtrem);
+
+ p = &param[TYPE_ZERO];
+ p->dst[0] = 1;
+ p->size = SIZE_ALLOW_ZERO;
+ REFERENCE (refmpn_zero);
+
+ p = &param[TYPE_GET_STR];
+ p->retval = 1;
+ p->src[0] = 1;
+ p->size = SIZE_ALLOW_ZERO;
+ p->dst[0] = 1;
+ p->dst[1] = 1;
+ p->dst_size[0] = SIZE_GET_STR;
+ p->dst_bytes[0] = 1;
+ p->overlap = OVERLAP_NONE;
+ REFERENCE (refmpn_get_str);
+
+ p = &param[TYPE_BINVERT];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->data = DATA_SRC0_ODD;
+ p->overlap = OVERLAP_NONE;
+ REFERENCE (refmpn_binvert);
+
+ p = &param[TYPE_INVERT];
+ p->dst[0] = 1;
+ p->src[0] = 1;
+ p->data = DATA_SRC0_HIGHBIT;
+ p->overlap = OVERLAP_NONE;
+ REFERENCE (refmpn_invert);
+
+#ifdef EXTRA_PARAM_INIT
+ EXTRA_PARAM_INIT
+#endif
+}
+
+
+/* The following are macros if there's no native versions, so wrap them in
+ functions that can be in try_array[]. */
+
+void
+MPN_COPY_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{ MPN_COPY (rp, sp, size); }
+
+void
+MPN_COPY_INCR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{ MPN_COPY_INCR (rp, sp, size); }
+
+void
+MPN_COPY_DECR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{ MPN_COPY_DECR (rp, sp, size); }
+
+void
+__GMPN_COPY_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{ __GMPN_COPY (rp, sp, size); }
+
+#ifdef __GMPN_COPY_INCR
+void
+__GMPN_COPY_INCR_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{ __GMPN_COPY_INCR (rp, sp, size); }
+#endif
+
+void
+mpn_com_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{ mpn_com (rp, sp, size); }
+
+void
+mpn_and_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
+{ mpn_and_n (rp, s1, s2, size); }
+
+void
+mpn_andn_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
+{ mpn_andn_n (rp, s1, s2, size); }
+
+void
+mpn_nand_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
+{ mpn_nand_n (rp, s1, s2, size); }
+
+void
+mpn_ior_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
+{ mpn_ior_n (rp, s1, s2, size); }
+
+void
+mpn_iorn_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
+{ mpn_iorn_n (rp, s1, s2, size); }
+
+void
+mpn_nior_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
+{ mpn_nior_n (rp, s1, s2, size); }
+
+void
+mpn_xor_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
+{ mpn_xor_n (rp, s1, s2, size); }
+
+void
+mpn_xnor_n_fun (mp_ptr rp, mp_srcptr s1, mp_srcptr s2, mp_size_t size)
+{ mpn_xnor_n (rp, s1, s2, size); }
+
+mp_limb_t
+udiv_qrnnd_fun (mp_limb_t *remptr, mp_limb_t n1, mp_limb_t n0, mp_limb_t d)
+{
+ mp_limb_t q;
+ udiv_qrnnd (q, *remptr, n1, n0, d);
+ return q;
+}
+
+mp_limb_t
+mpn_divexact_by3_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ return mpn_divexact_by3 (rp, sp, size);
+}
+
+#if HAVE_NATIVE_mpn_addlsh1_n_ip1
+mp_limb_t
+mpn_addlsh1_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ return mpn_addlsh1_n_ip1 (rp, sp, size);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n_ip1
+mp_limb_t
+mpn_addlsh2_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ return mpn_addlsh2_n_ip1 (rp, sp, size);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n_ip1
+mp_limb_t
+mpn_addlsh_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned int sh)
+{
+ return mpn_addlsh_n_ip1 (rp, sp, size, sh);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh1_n_ip2
+mp_limb_t
+mpn_addlsh1_n_ip2_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ return mpn_addlsh1_n_ip2 (rp, sp, size);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n_ip2
+mp_limb_t
+mpn_addlsh2_n_ip2_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ return mpn_addlsh2_n_ip2 (rp, sp, size);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n_ip2
+mp_limb_t
+mpn_addlsh_n_ip2_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned int sh)
+{
+ return mpn_addlsh_n_ip2 (rp, sp, size, sh);
+}
+#endif
+#if HAVE_NATIVE_mpn_sublsh1_n_ip1
+mp_limb_t
+mpn_sublsh1_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ return mpn_sublsh1_n_ip1 (rp, sp, size);
+}
+#endif
+#if HAVE_NATIVE_mpn_sublsh2_n_ip1
+mp_limb_t
+mpn_sublsh2_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ return mpn_sublsh2_n_ip1 (rp, sp, size);
+}
+#endif
+#if HAVE_NATIVE_mpn_sublsh_n_ip1
+mp_limb_t
+mpn_sublsh_n_ip1_fun (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned int sh)
+{
+ return mpn_sublsh_n_ip1 (rp, sp, size, sh);
+}
+#endif
+
+mp_limb_t
+mpn_modexact_1_odd_fun (mp_srcptr ptr, mp_size_t size, mp_limb_t divisor)
+{
+ return mpn_modexact_1_odd (ptr, size, divisor);
+}
+
+void
+mpn_toom22_mul_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size)
+{
+ mp_ptr tspace;
+ TMP_DECL;
+ TMP_MARK;
+ tspace = TMP_ALLOC_LIMBS (mpn_toom22_mul_itch (size, size));
+ mpn_toom22_mul (dst, src1, size, src2, size, tspace);
+ TMP_FREE;
+}
+void
+mpn_toom2_sqr_fun (mp_ptr dst, mp_srcptr src, mp_size_t size)
+{
+ mp_ptr tspace;
+ TMP_DECL;
+ TMP_MARK;
+ tspace = TMP_ALLOC_LIMBS (mpn_toom2_sqr_itch (size));
+ mpn_toom2_sqr (dst, src, size, tspace);
+ TMP_FREE;
+}
+void
+mpn_toom33_mul_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size)
+{
+ mp_ptr tspace;
+ TMP_DECL;
+ TMP_MARK;
+ tspace = TMP_ALLOC_LIMBS (mpn_toom33_mul_itch (size, size));
+ mpn_toom33_mul (dst, src1, size, src2, size, tspace);
+ TMP_FREE;
+}
+void
+mpn_toom3_sqr_fun (mp_ptr dst, mp_srcptr src, mp_size_t size)
+{
+ mp_ptr tspace;
+ TMP_DECL;
+ TMP_MARK;
+ tspace = TMP_ALLOC_LIMBS (mpn_toom3_sqr_itch (size));
+ mpn_toom3_sqr (dst, src, size, tspace);
+ TMP_FREE;
+}
+void
+mpn_toom44_mul_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2, mp_size_t size)
+{
+ mp_ptr tspace;
+ TMP_DECL;
+ TMP_MARK;
+ tspace = TMP_ALLOC_LIMBS (mpn_toom44_mul_itch (size, size));
+ mpn_toom44_mul (dst, src1, size, src2, size, tspace);
+ TMP_FREE;
+}
+void
+mpn_toom4_sqr_fun (mp_ptr dst, mp_srcptr src, mp_size_t size)
+{
+ mp_ptr tspace;
+ TMP_DECL;
+ TMP_MARK;
+ tspace = TMP_ALLOC_LIMBS (mpn_toom4_sqr_itch (size));
+ mpn_toom4_sqr (dst, src, size, tspace);
+ TMP_FREE;
+}
+
+void
+mpn_toom42_mulmid_fun (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
+ mp_size_t size)
+{
+ mp_ptr tspace;
+ mp_size_t n;
+ TMP_DECL;
+ TMP_MARK;
+ tspace = TMP_ALLOC_LIMBS (mpn_toom42_mulmid_itch (size));
+ mpn_toom42_mulmid (dst, src1, src2, size, tspace);
+ TMP_FREE;
+}
+
+mp_limb_t
+umul_ppmm_fun (mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2)
+{
+ mp_limb_t high;
+ umul_ppmm (high, *lowptr, m1, m2);
+ return high;
+}
+
+void
+MPN_ZERO_fun (mp_ptr ptr, mp_size_t size)
+{ MPN_ZERO (ptr, size); }
+
+
+struct choice_t {
+ const char *name;
+ tryfun_t function;
+ int type;
+ mp_size_t minsize;
+};
+
+#if HAVE_STRINGIZE
+#define TRY(fun) #fun, (tryfun_t) fun
+#define TRY_FUNFUN(fun) #fun, (tryfun_t) fun##_fun
+#else
+#define TRY(fun) "fun", (tryfun_t) fun
+#define TRY_FUNFUN(fun) "fun", (tryfun_t) fun/**/_fun
+#endif
+
+const struct choice_t choice_array[] = {
+ { TRY(mpn_add), TYPE_ADD },
+ { TRY(mpn_sub), TYPE_SUB },
+
+ { TRY(mpn_add_n), TYPE_ADD_N },
+ { TRY(mpn_sub_n), TYPE_SUB_N },
+
+#if HAVE_NATIVE_mpn_add_nc
+ { TRY(mpn_add_nc), TYPE_ADD_NC },
+#endif
+#if HAVE_NATIVE_mpn_sub_nc
+ { TRY(mpn_sub_nc), TYPE_SUB_NC },
+#endif
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ { TRY(mpn_add_n_sub_n), TYPE_ADDSUB_N },
+#endif
+#if HAVE_NATIVE_mpn_add_n_sub_nc
+ { TRY(mpn_add_n_sub_nc), TYPE_ADDSUB_NC },
+#endif
+
+ { TRY(mpn_add_err1_n), TYPE_ADD_ERR1_N },
+ { TRY(mpn_sub_err1_n), TYPE_SUB_ERR1_N },
+ { TRY(mpn_add_err2_n), TYPE_ADD_ERR2_N },
+ { TRY(mpn_sub_err2_n), TYPE_SUB_ERR2_N },
+ { TRY(mpn_add_err3_n), TYPE_ADD_ERR3_N },
+ { TRY(mpn_sub_err3_n), TYPE_SUB_ERR3_N },
+
+ { TRY(mpn_addmul_1), TYPE_ADDMUL_1 },
+ { TRY(mpn_submul_1), TYPE_SUBMUL_1 },
+#if HAVE_NATIVE_mpn_addmul_1c
+ { TRY(mpn_addmul_1c), TYPE_ADDMUL_1C },
+#endif
+#if HAVE_NATIVE_mpn_submul_1c
+ { TRY(mpn_submul_1c), TYPE_SUBMUL_1C },
+#endif
+
+#if HAVE_NATIVE_mpn_addmul_2
+ { TRY(mpn_addmul_2), TYPE_ADDMUL_2, 2 },
+#endif
+#if HAVE_NATIVE_mpn_addmul_3
+ { TRY(mpn_addmul_3), TYPE_ADDMUL_3, 3 },
+#endif
+#if HAVE_NATIVE_mpn_addmul_4
+ { TRY(mpn_addmul_4), TYPE_ADDMUL_4, 4 },
+#endif
+#if HAVE_NATIVE_mpn_addmul_5
+ { TRY(mpn_addmul_5), TYPE_ADDMUL_5, 5 },
+#endif
+#if HAVE_NATIVE_mpn_addmul_6
+ { TRY(mpn_addmul_6), TYPE_ADDMUL_6, 6 },
+#endif
+#if HAVE_NATIVE_mpn_addmul_7
+ { TRY(mpn_addmul_7), TYPE_ADDMUL_7, 7 },
+#endif
+#if HAVE_NATIVE_mpn_addmul_8
+ { TRY(mpn_addmul_8), TYPE_ADDMUL_8, 8 },
+#endif
+
+ { TRY_FUNFUN(mpn_com), TYPE_COM },
+
+ { TRY_FUNFUN(MPN_COPY), TYPE_COPY },
+ { TRY_FUNFUN(MPN_COPY_INCR), TYPE_COPYI },
+ { TRY_FUNFUN(MPN_COPY_DECR), TYPE_COPYD },
+
+ { TRY_FUNFUN(__GMPN_COPY), TYPE_COPY },
+#ifdef __GMPN_COPY_INCR
+ { TRY_FUNFUN(__GMPN_COPY_INCR), TYPE_COPYI },
+#endif
+
+#if HAVE_NATIVE_mpn_copyi
+ { TRY(mpn_copyi), TYPE_COPYI },
+#endif
+#if HAVE_NATIVE_mpn_copyd
+ { TRY(mpn_copyd), TYPE_COPYD },
+#endif
+
+ { TRY(mpn_cnd_add_n), TYPE_ADDCND_N },
+ { TRY(mpn_cnd_sub_n), TYPE_SUBCND_N },
+#if HAVE_NATIVE_mpn_addlsh1_n == 1
+ { TRY(mpn_addlsh1_n), TYPE_ADDLSH1_N },
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n == 1
+ { TRY(mpn_addlsh2_n), TYPE_ADDLSH2_N },
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n
+ { TRY(mpn_addlsh_n), TYPE_ADDLSH_N },
+#endif
+#if HAVE_NATIVE_mpn_addlsh1_n_ip1
+ { TRY_FUNFUN(mpn_addlsh1_n_ip1), TYPE_ADDLSH1_N_IP1 },
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n_ip1
+ { TRY_FUNFUN(mpn_addlsh2_n_ip1), TYPE_ADDLSH2_N_IP1 },
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n_ip1
+ { TRY_FUNFUN(mpn_addlsh_n_ip1), TYPE_ADDLSH_N_IP1 },
+#endif
+#if HAVE_NATIVE_mpn_addlsh1_n_ip2
+ { TRY_FUNFUN(mpn_addlsh1_n_ip2), TYPE_ADDLSH1_N_IP2 },
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n_ip2
+ { TRY_FUNFUN(mpn_addlsh2_n_ip2), TYPE_ADDLSH2_N_IP2 },
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n_ip2
+ { TRY_FUNFUN(mpn_addlsh_n_ip2), TYPE_ADDLSH_N_IP2 },
+#endif
+#if HAVE_NATIVE_mpn_sublsh1_n == 1
+ { TRY(mpn_sublsh1_n), TYPE_SUBLSH1_N },
+#endif
+#if HAVE_NATIVE_mpn_sublsh2_n == 1
+ { TRY(mpn_sublsh2_n), TYPE_SUBLSH2_N },
+#endif
+#if HAVE_NATIVE_mpn_sublsh_n
+ { TRY(mpn_sublsh_n), TYPE_SUBLSH_N },
+#endif
+#if HAVE_NATIVE_mpn_sublsh1_n_ip1
+ { TRY_FUNFUN(mpn_sublsh1_n_ip1), TYPE_SUBLSH1_N_IP1 },
+#endif
+#if HAVE_NATIVE_mpn_sublsh2_n_ip1
+ { TRY_FUNFUN(mpn_sublsh2_n_ip1), TYPE_SUBLSH2_N_IP1 },
+#endif
+#if HAVE_NATIVE_mpn_sublsh_n_ip1
+ { TRY_FUNFUN(mpn_sublsh_n_ip1), TYPE_SUBLSH_N_IP1 },
+#endif
+#if HAVE_NATIVE_mpn_rsblsh1_n == 1
+ { TRY(mpn_rsblsh1_n), TYPE_RSBLSH1_N },
+#endif
+#if HAVE_NATIVE_mpn_rsblsh2_n == 1
+ { TRY(mpn_rsblsh2_n), TYPE_RSBLSH2_N },
+#endif
+#if HAVE_NATIVE_mpn_rsblsh_n
+ { TRY(mpn_rsblsh_n), TYPE_RSBLSH_N },
+#endif
+#if HAVE_NATIVE_mpn_rsh1add_n
+ { TRY(mpn_rsh1add_n), TYPE_RSH1ADD_N },
+#endif
+#if HAVE_NATIVE_mpn_rsh1sub_n
+ { TRY(mpn_rsh1sub_n), TYPE_RSH1SUB_N },
+#endif
+
+#if HAVE_NATIVE_mpn_addlsh1_nc
+ { TRY(mpn_addlsh1_nc), TYPE_ADDLSH1_NC },
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_nc
+ { TRY(mpn_addlsh2_nc), TYPE_ADDLSH2_NC },
+#endif
+#if HAVE_NATIVE_mpn_addlsh_nc
+ { TRY(mpn_addlsh_nc), TYPE_ADDLSH_NC },
+#endif
+#if HAVE_NATIVE_mpn_sublsh1_nc
+ { TRY(mpn_sublsh1_nc), TYPE_SUBLSH1_NC },
+#endif
+#if HAVE_NATIVE_mpn_sublsh2_nc
+ { TRY(mpn_sublsh2_nc), TYPE_SUBLSH2_NC },
+#endif
+#if HAVE_NATIVE_mpn_sublsh_nc
+ { TRY(mpn_sublsh_nc), TYPE_SUBLSH_NC },
+#endif
+#if HAVE_NATIVE_mpn_rsblsh1_nc
+ { TRY(mpn_rsblsh1_nc), TYPE_RSBLSH1_NC },
+#endif
+#if HAVE_NATIVE_mpn_rsblsh2_nc
+ { TRY(mpn_rsblsh2_nc), TYPE_RSBLSH2_NC },
+#endif
+#if HAVE_NATIVE_mpn_rsblsh_nc
+ { TRY(mpn_rsblsh_nc), TYPE_RSBLSH_NC },
+#endif
+
+ { TRY_FUNFUN(mpn_and_n), TYPE_AND_N },
+ { TRY_FUNFUN(mpn_andn_n), TYPE_ANDN_N },
+ { TRY_FUNFUN(mpn_nand_n), TYPE_NAND_N },
+ { TRY_FUNFUN(mpn_ior_n), TYPE_IOR_N },
+ { TRY_FUNFUN(mpn_iorn_n), TYPE_IORN_N },
+ { TRY_FUNFUN(mpn_nior_n), TYPE_NIOR_N },
+ { TRY_FUNFUN(mpn_xor_n), TYPE_XOR_N },
+ { TRY_FUNFUN(mpn_xnor_n), TYPE_XNOR_N },
+
+ { TRY(mpn_divrem_1), TYPE_DIVREM_1 },
+#if USE_PREINV_DIVREM_1
+ { TRY(mpn_preinv_divrem_1), TYPE_PREINV_DIVREM_1 },
+#endif
+ { TRY(mpn_mod_1), TYPE_MOD_1 },
+#if USE_PREINV_MOD_1
+ { TRY(mpn_preinv_mod_1), TYPE_PREINV_MOD_1 },
+#endif
+#if HAVE_NATIVE_mpn_divrem_1c
+ { TRY(mpn_divrem_1c), TYPE_DIVREM_1C },
+#endif
+#if HAVE_NATIVE_mpn_mod_1c
+ { TRY(mpn_mod_1c), TYPE_MOD_1C },
+#endif
+ { TRY(mpn_div_qr_1n_pi1), TYPE_DIV_QR_1N_PI1 },
+#if GMP_NUMB_BITS % 4 == 0
+ { TRY(mpn_mod_34lsub1), TYPE_MOD_34LSUB1 },
+#endif
+
+ { TRY_FUNFUN(udiv_qrnnd), TYPE_UDIV_QRNND, 2 },
+#if HAVE_NATIVE_mpn_udiv_qrnnd
+ { TRY(mpn_udiv_qrnnd), TYPE_UDIV_QRNND, 2 },
+#endif
+#if HAVE_NATIVE_mpn_udiv_qrnnd_r
+ { TRY(mpn_udiv_qrnnd_r), TYPE_UDIV_QRNND_R, 2 },
+#endif
+
+ { TRY(mpn_divexact_1), TYPE_DIVEXACT_1 },
+ { TRY(mpn_bdiv_q_1), TYPE_BDIV_Q_1 },
+ { TRY_FUNFUN(mpn_divexact_by3), TYPE_DIVEXACT_BY3 },
+ { TRY(mpn_divexact_by3c), TYPE_DIVEXACT_BY3C },
+
+ { TRY_FUNFUN(mpn_modexact_1_odd), TYPE_MODEXACT_1_ODD },
+ { TRY(mpn_modexact_1c_odd), TYPE_MODEXACT_1C_ODD },
+
+
+ { TRY(mpn_sbpi1_div_qr), TYPE_SBPI1_DIV_QR, 3},
+ { TRY(mpn_tdiv_qr), TYPE_TDIV_QR },
+
+ { TRY(mpn_mul_1), TYPE_MUL_1 },
+#if HAVE_NATIVE_mpn_mul_1c
+ { TRY(mpn_mul_1c), TYPE_MUL_1C },
+#endif
+#if HAVE_NATIVE_mpn_mul_2
+ { TRY(mpn_mul_2), TYPE_MUL_2, 2 },
+#endif
+#if HAVE_NATIVE_mpn_mul_3
+ { TRY(mpn_mul_3), TYPE_MUL_3, 3 },
+#endif
+#if HAVE_NATIVE_mpn_mul_4
+ { TRY(mpn_mul_4), TYPE_MUL_4, 4 },
+#endif
+#if HAVE_NATIVE_mpn_mul_5
+ { TRY(mpn_mul_5), TYPE_MUL_5, 5 },
+#endif
+#if HAVE_NATIVE_mpn_mul_6
+ { TRY(mpn_mul_6), TYPE_MUL_6, 6 },
+#endif
+
+ { TRY(mpn_rshift), TYPE_RSHIFT },
+ { TRY(mpn_lshift), TYPE_LSHIFT },
+ { TRY(mpn_lshiftc), TYPE_LSHIFTC },
+
+
+ { TRY(mpn_mul_basecase), TYPE_MUL_MN },
+ { TRY(mpn_mulmid_basecase), TYPE_MULMID_MN },
+ { TRY(mpn_mullo_basecase), TYPE_MULLO_N },
+#if SQR_TOOM2_THRESHOLD > 0
+ { TRY(mpn_sqr_basecase), TYPE_SQR },
+#endif
+
+ { TRY(mpn_mul), TYPE_MUL_MN },
+ { TRY(mpn_mul_n), TYPE_MUL_N },
+ { TRY(mpn_sqr), TYPE_SQR },
+
+ { TRY_FUNFUN(umul_ppmm), TYPE_UMUL_PPMM, 2 },
+#if HAVE_NATIVE_mpn_umul_ppmm
+ { TRY(mpn_umul_ppmm), TYPE_UMUL_PPMM, 2 },
+#endif
+#if HAVE_NATIVE_mpn_umul_ppmm_r
+ { TRY(mpn_umul_ppmm_r), TYPE_UMUL_PPMM_R, 2 },
+#endif
+
+ { TRY_FUNFUN(mpn_toom22_mul), TYPE_MUL_N, MPN_TOOM22_MUL_MINSIZE },
+ { TRY_FUNFUN(mpn_toom2_sqr), TYPE_SQR, MPN_TOOM2_SQR_MINSIZE },
+ { TRY_FUNFUN(mpn_toom33_mul), TYPE_MUL_N, MPN_TOOM33_MUL_MINSIZE },
+ { TRY_FUNFUN(mpn_toom3_sqr), TYPE_SQR, MPN_TOOM3_SQR_MINSIZE },
+ { TRY_FUNFUN(mpn_toom44_mul), TYPE_MUL_N, MPN_TOOM44_MUL_MINSIZE },
+ { TRY_FUNFUN(mpn_toom4_sqr), TYPE_SQR, MPN_TOOM4_SQR_MINSIZE },
+
+ { TRY(mpn_mulmid_n), TYPE_MULMID_N, 1 },
+ { TRY(mpn_mulmid), TYPE_MULMID_MN, 1 },
+ { TRY_FUNFUN(mpn_toom42_mulmid), TYPE_MULMID_N,
+ (2 * MPN_TOOM42_MULMID_MINSIZE - 1) },
+
+ { TRY(mpn_gcd_1), TYPE_GCD_1 },
+ { TRY(mpn_gcd), TYPE_GCD },
+ { TRY(mpz_legendre), TYPE_MPZ_LEGENDRE },
+ { TRY(mpz_jacobi), TYPE_MPZ_JACOBI },
+ { TRY(mpz_kronecker), TYPE_MPZ_KRONECKER },
+ { TRY(mpz_kronecker_ui), TYPE_MPZ_KRONECKER_UI },
+ { TRY(mpz_kronecker_si), TYPE_MPZ_KRONECKER_SI },
+ { TRY(mpz_ui_kronecker), TYPE_MPZ_UI_KRONECKER },
+ { TRY(mpz_si_kronecker), TYPE_MPZ_SI_KRONECKER },
+
+ { TRY(mpn_popcount), TYPE_POPCOUNT },
+ { TRY(mpn_hamdist), TYPE_HAMDIST },
+
+ { TRY(mpn_sqrtrem), TYPE_SQRTREM },
+
+ { TRY_FUNFUN(MPN_ZERO), TYPE_ZERO },
+
+ { TRY(mpn_get_str), TYPE_GET_STR },
+
+ { TRY(mpn_binvert), TYPE_BINVERT },
+ { TRY(mpn_invert), TYPE_INVERT },
+
+#ifdef EXTRA_ROUTINES
+ EXTRA_ROUTINES
+#endif
+};
+
+const struct choice_t *choice = NULL;
+
+
+void
+mprotect_maybe (void *addr, size_t len, int prot)
+{
+ if (!option_redzones)
+ return;
+
+#if HAVE_MPROTECT
+ if (mprotect (addr, len, prot) != 0)
+ {
+ fprintf (stderr, "Cannot mprotect %p 0x%X 0x%X: %s\n",
+ addr, (unsigned) len, prot, strerror (errno));
+ exit (1);
+ }
+#else
+ {
+ static int warned = 0;
+ if (!warned)
+ {
+ fprintf (stderr,
+ "mprotect not available, bounds testing not performed\n");
+ warned = 1;
+ }
+ }
+#endif
+}
+
+/* round "a" up to a multiple of "m" */
+size_t
+round_up_multiple (size_t a, size_t m)
+{
+ unsigned long r;
+
+ r = a % m;
+ if (r == 0)
+ return a;
+ else
+ return a + (m - r);
+}
+
+
+/* On some systems it seems that only an mmap'ed region can be mprotect'ed,
+ for instance HP-UX 10.
+
+ mmap will almost certainly return a pointer already aligned to a page
+ boundary, but it's easy enough to share the alignment handling with the
+ malloc case. */
+
+void
+malloc_region (struct region_t *r, mp_size_t n)
+{
+ mp_ptr p;
+ size_t nbytes;
+
+ ASSERT ((pagesize % GMP_LIMB_BYTES) == 0);
+
+ n = round_up_multiple (n, PAGESIZE_LIMBS);
+ r->size = n;
+
+ nbytes = n*GMP_LIMB_BYTES + 2*REDZONE_BYTES + pagesize;
+
+#if defined (MAP_ANONYMOUS) && ! defined (MAP_ANON)
+#define MAP_ANON MAP_ANONYMOUS
+#endif
+
+#if HAVE_MMAP && defined (MAP_ANON)
+ /* note must pass fd=-1 for MAP_ANON on BSD */
+ p = (mp_ptr) mmap (NULL, nbytes, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+ if (p == (void *) -1)
+ {
+ fprintf (stderr, "Cannot mmap %#x anon bytes: %s\n",
+ (unsigned) nbytes, strerror (errno));
+ exit (1);
+ }
+#else
+ p = (mp_ptr) malloc (nbytes);
+ ASSERT_ALWAYS (p != NULL);
+#endif
+
+ p = (mp_ptr) align_pointer (p, pagesize);
+
+ mprotect_maybe (p, REDZONE_BYTES, PROT_NONE);
+ p += REDZONE_LIMBS;
+ r->ptr = p;
+
+ mprotect_maybe (p + n, REDZONE_BYTES, PROT_NONE);
+}
+
+void
+mprotect_region (const struct region_t *r, int prot)
+{
+ mprotect_maybe (r->ptr, r->size, prot);
+}
+
+
+/* First four entries must be 0,1,2,3 for the benefit of CARRY_BIT, CARRY_3,
+ and CARRY_4 */
+mp_limb_t carry_array[] = {
+ 0, 1, 2, 3,
+ 4,
+ CNST_LIMB(1) << 8,
+ CNST_LIMB(1) << 16,
+ GMP_NUMB_MAX
+};
+int carry_index;
+
+#define CARRY_COUNT \
+ ((tr->carry == CARRY_BIT) ? 2 \
+ : tr->carry == CARRY_3 ? 3 \
+ : tr->carry == CARRY_4 ? 4 \
+ : (tr->carry == CARRY_LIMB || tr->carry == CARRY_DIVISOR) \
+ ? numberof(carry_array) + CARRY_RANDOMS \
+ : 1)
+
+#define MPN_RANDOM_ALT(index,dst,size) \
+ (((index) & 1) ? refmpn_random (dst, size) : refmpn_random2 (dst, size))
+
+/* The dummy value after MPN_RANDOM_ALT ensures both sides of the ":" have
+ the same type */
+#define CARRY_ITERATION \
+ for (carry_index = 0; \
+ (carry_index < numberof (carry_array) \
+ ? (carry = carry_array[carry_index]) \
+ : (MPN_RANDOM_ALT (carry_index, &carry, 1), (mp_limb_t) 0)), \
+ (tr->carry == CARRY_DIVISOR ? carry %= divisor : 0), \
+ carry_index < CARRY_COUNT; \
+ carry_index++)
+
+
+mp_limb_t multiplier_array[] = {
+ 0, 1, 2, 3,
+ CNST_LIMB(1) << 8,
+ CNST_LIMB(1) << 16,
+ GMP_NUMB_MAX - 2,
+ GMP_NUMB_MAX - 1,
+ GMP_NUMB_MAX
+};
+int multiplier_index;
+
+mp_limb_t divisor_array[] = {
+ 1, 2, 3,
+ CNST_LIMB(1) << 8,
+ CNST_LIMB(1) << 16,
+ CNST_LIMB(1) << (GMP_NUMB_BITS/2 - 1),
+ GMP_NUMB_MAX >> (GMP_NUMB_BITS/2),
+ GMP_NUMB_HIGHBIT,
+ GMP_NUMB_HIGHBIT + 1,
+ GMP_NUMB_MAX - 2,
+ GMP_NUMB_MAX - 1,
+ GMP_NUMB_MAX
+};
+
+int divisor_index;
+
+/* The dummy value after MPN_RANDOM_ALT ensures both sides of the ":" have
+ the same type */
+#define ARRAY_ITERATION(var, index, limit, array, randoms, cond) \
+ for (index = 0; \
+ (index < numberof (array) \
+ ? (var = array[index]) \
+ : (MPN_RANDOM_ALT (index, &var, 1), (mp_limb_t) 0)), \
+ index < limit; \
+ index++)
+
+#define MULTIPLIER_COUNT \
+ (tr->multiplier \
+ ? numberof (multiplier_array) + MULTIPLIER_RANDOMS \
+ : 1)
+
+#define MULTIPLIER_ITERATION \
+ ARRAY_ITERATION(multiplier, multiplier_index, MULTIPLIER_COUNT, \
+ multiplier_array, MULTIPLIER_RANDOMS, TRY_MULTIPLIER)
+
+#define DIVISOR_COUNT \
+ (tr->divisor \
+ ? numberof (divisor_array) + DIVISOR_RANDOMS \
+ : 1)
+
+#define DIVISOR_ITERATION \
+ ARRAY_ITERATION(divisor, divisor_index, DIVISOR_COUNT, divisor_array, \
+ DIVISOR_RANDOMS, TRY_DIVISOR)
+
+
+/* overlap_array[].s[i] is where s[i] should be, 0 or 1 means overlapping
+ d[0] or d[1] respectively, -1 means a separate (write-protected)
+ location. */
+
+struct overlap_t {
+ int s[NUM_SOURCES];
+} overlap_array[] = {
+ { { -1, -1, -1, -1, -1 } },
+ { { 0, -1, -1, -1, -1 } },
+ { { -1, 0, -1, -1, -1 } },
+ { { 0, 0, -1, -1, -1 } },
+ { { 1, -1, -1, -1, -1 } },
+ { { -1, 1, -1, -1, -1 } },
+ { { 1, 1, -1, -1, -1 } },
+ { { 0, 1, -1, -1, -1 } },
+ { { 1, 0, -1, -1, -1 } },
+};
+
+struct overlap_t *overlap, *overlap_limit;
+
+#define OVERLAP_COUNT \
+ (tr->overlap & OVERLAP_NONE ? 1 \
+ : tr->overlap & OVERLAP_NOT_SRCS ? 3 \
+ : tr->overlap & OVERLAP_NOT_SRC2 ? 2 \
+ : tr->overlap & OVERLAP_NOT_DST2 ? 4 \
+ : tr->dst[1] ? 9 \
+ : tr->src[1] ? 4 \
+ : tr->dst[0] ? 2 \
+ : 1)
+
+#define OVERLAP_ITERATION \
+ for (overlap = &overlap_array[0], \
+ overlap_limit = &overlap_array[OVERLAP_COUNT]; \
+ overlap < overlap_limit; \
+ overlap++)
+
+
+int base = 10;
+
+#define T_RAND_COUNT 2
+int t_rand;
+
+void
+t_random (mp_ptr ptr, mp_size_t n)
+{
+ if (n == 0)
+ return;
+
+ switch (option_data) {
+ case DATA_TRAND:
+ switch (t_rand) {
+ case 0: refmpn_random (ptr, n); break;
+ case 1: refmpn_random2 (ptr, n); break;
+ default: abort();
+ }
+ break;
+ case DATA_SEQ:
+ {
+ static mp_limb_t counter = 0;
+ mp_size_t i;
+ for (i = 0; i < n; i++)
+ ptr[i] = ++counter;
+ }
+ break;
+ case DATA_ZEROS:
+ refmpn_zero (ptr, n);
+ break;
+ case DATA_FFS:
+ refmpn_fill (ptr, n, GMP_NUMB_MAX);
+ break;
+ case DATA_2FD:
+ /* Special value 0x2FFF...FFFD, which divided by 3 gives 0xFFF...FFF,
+ inducing the q1_ff special case in the mul-by-inverse part of some
+ versions of divrem_1 and mod_1. */
+ refmpn_fill (ptr, n, (mp_limb_t) -1);
+ ptr[n-1] = 2;
+ ptr[0] -= 2;
+ break;
+
+ default:
+ abort();
+ }
+}
+#define T_RAND_ITERATION \
+ for (t_rand = 0; t_rand < T_RAND_COUNT; t_rand++)
+
+
+void
+print_each (const struct each_t *e)
+{
+ int i;
+
+ printf ("%s %s\n", e->name, e == &ref ? tr->reference_name : choice->name);
+ if (tr->retval)
+ mpn_trace (" retval", &e->retval, 1);
+
+ for (i = 0; i < NUM_DESTS; i++)
+ {
+ if (tr->dst[i])
+ {
+ if (tr->dst_bytes[i])
+ byte_tracen (" d[%d]", i, e->d[i].p, d[i].size);
+ else
+ mpn_tracen (" d[%d]", i, e->d[i].p, d[i].size);
+ printf (" located %p\n", (void *) (e->d[i].p));
+ }
+ }
+
+ for (i = 0; i < NUM_SOURCES; i++)
+ if (tr->src[i])
+ printf (" s[%d] located %p\n", i, (void *) (e->s[i].p));
+}
+
+
+void
+print_all (void)
+{
+ int i;
+
+ printf ("\n");
+ printf ("size %ld\n", (long) size);
+ if (tr->size2)
+ printf ("size2 %ld\n", (long) size2);
+
+ for (i = 0; i < NUM_DESTS; i++)
+ if (d[i].size != size)
+ printf ("d[%d].size %ld\n", i, (long) d[i].size);
+
+ if (tr->multiplier)
+ mpn_trace (" multiplier", &multiplier, 1);
+ if (tr->divisor)
+ mpn_trace (" divisor", &divisor, 1);
+ if (tr->shift)
+ printf (" shift %lu\n", shift);
+ if (tr->carry)
+ mpn_trace (" carry", &carry, 1);
+ if (tr->msize)
+ mpn_trace (" multiplier_N", multiplier_N, tr->msize);
+
+ for (i = 0; i < NUM_DESTS; i++)
+ if (tr->dst[i])
+ printf (" d[%d] %s, align %ld, size %ld\n",
+ i, d[i].high ? "high" : "low",
+ (long) d[i].align, (long) d[i].size);
+
+ for (i = 0; i < NUM_SOURCES; i++)
+ {
+ if (tr->src[i])
+ {
+ printf (" s[%d] %s, align %ld, ",
+ i, s[i].high ? "high" : "low", (long) s[i].align);
+ switch (overlap->s[i]) {
+ case -1:
+ printf ("no overlap\n");
+ break;
+ default:
+ printf ("==d[%d]%s\n",
+ overlap->s[i],
+ tr->overlap == OVERLAP_LOW_TO_HIGH ? "+a"
+ : tr->overlap == OVERLAP_HIGH_TO_LOW ? "-a"
+ : "");
+ break;
+ }
+ printf (" s[%d]=", i);
+ if (tr->carry_sign && (carry & (1 << i)))
+ printf ("-");
+ mpn_trace (NULL, s[i].p, SRC_SIZE(i));
+ }
+ }
+
+ if (tr->dst0_from_src1)
+ mpn_trace (" d[0]", s[1].region.ptr, size);
+
+ if (tr->reference)
+ print_each (&ref);
+ print_each (&fun);
+}
+
+void
+compare (void)
+{
+ int error = 0;
+ int i;
+
+ if (tr->retval && ref.retval != fun.retval)
+ {
+ gmp_printf ("Different return values (%Mu, %Mu)\n",
+ ref.retval, fun.retval);
+ error = 1;
+ }
+
+ for (i = 0; i < NUM_DESTS; i++)
+ {
+ switch (tr->dst_size[i]) {
+ case SIZE_RETVAL:
+ case SIZE_GET_STR:
+ d[i].size = ref.retval;
+ break;
+ }
+ }
+
+ for (i = 0; i < NUM_DESTS; i++)
+ {
+ if (! tr->dst[i])
+ continue;
+
+ if (tr->dst_bytes[i])
+ {
+ if (memcmp (ref.d[i].p, fun.d[i].p, d[i].size) != 0)
+ {
+ printf ("Different d[%d] data results, low diff at %ld, high diff at %ld\n",
+ i,
+ (long) byte_diff_lowest (ref.d[i].p, fun.d[i].p, d[i].size),
+ (long) byte_diff_highest (ref.d[i].p, fun.d[i].p, d[i].size));
+ error = 1;
+ }
+ }
+ else
+ {
+ if (d[i].size != 0
+ && ! refmpn_equal_anynail (ref.d[i].p, fun.d[i].p, d[i].size))
+ {
+ printf ("Different d[%d] data results, low diff at %ld, high diff at %ld\n",
+ i,
+ (long) mpn_diff_lowest (ref.d[i].p, fun.d[i].p, d[i].size),
+ (long) mpn_diff_highest (ref.d[i].p, fun.d[i].p, d[i].size));
+ error = 1;
+ }
+ }
+ }
+
+ if (error)
+ {
+ print_all();
+ abort();
+ }
+}
+
+
+/* The functions are cast if the return value should be a long rather than
+ the default mp_limb_t. This is necessary under _LONG_LONG_LIMB. This
+ might not be enough if some actual calling conventions checking is
+ implemented on a long long limb system. */
+
+void
+call (struct each_t *e, tryfun_t function)
+{
+ switch (choice->type) {
+ case TYPE_ADD:
+ case TYPE_SUB:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, e->s[1].p, size2);
+ break;
+
+ case TYPE_ADD_N:
+ case TYPE_SUB_N:
+ case TYPE_ADDLSH1_N:
+ case TYPE_ADDLSH2_N:
+ case TYPE_SUBLSH1_N:
+ case TYPE_SUBLSH2_N:
+ case TYPE_RSBLSH1_N:
+ case TYPE_RSBLSH2_N:
+ case TYPE_RSH1ADD_N:
+ case TYPE_RSH1SUB_N:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, e->s[1].p, size);
+ break;
+ case TYPE_ADDLSH_N:
+ case TYPE_SUBLSH_N:
+ case TYPE_RSBLSH_N:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, e->s[1].p, size, shift);
+ break;
+ case TYPE_ADDLSH_NC:
+ case TYPE_SUBLSH_NC:
+ case TYPE_RSBLSH_NC:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, e->s[1].p, size, shift, carry);
+ break;
+ case TYPE_ADDLSH1_NC:
+ case TYPE_ADDLSH2_NC:
+ case TYPE_SUBLSH1_NC:
+ case TYPE_SUBLSH2_NC:
+ case TYPE_RSBLSH1_NC:
+ case TYPE_RSBLSH2_NC:
+ case TYPE_ADD_NC:
+ case TYPE_SUB_NC:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, e->s[1].p, size, carry);
+ break;
+ case TYPE_ADDCND_N:
+ case TYPE_SUBCND_N:
+ e->retval = CALLING_CONVENTIONS (function)
+ (carry, e->d[0].p, e->s[0].p, e->s[1].p, size);
+ break;
+ case TYPE_ADD_ERR1_N:
+ case TYPE_SUB_ERR1_N:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, e->s[1].p, e->d[1].p, e->s[2].p, size, carry);
+ break;
+ case TYPE_ADD_ERR2_N:
+ case TYPE_SUB_ERR2_N:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, e->s[1].p, e->d[1].p, e->s[2].p, e->s[3].p, size, carry);
+ break;
+ case TYPE_ADD_ERR3_N:
+ case TYPE_SUB_ERR3_N:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, e->s[1].p, e->d[1].p, e->s[2].p, e->s[3].p, e->s[4].p, size, carry);
+ break;
+
+ case TYPE_MUL_1:
+ case TYPE_ADDMUL_1:
+ case TYPE_SUBMUL_1:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, multiplier);
+ break;
+ case TYPE_MUL_1C:
+ case TYPE_ADDMUL_1C:
+ case TYPE_SUBMUL_1C:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, multiplier, carry);
+ break;
+
+ case TYPE_MUL_2:
+ case TYPE_MUL_3:
+ case TYPE_MUL_4:
+ case TYPE_MUL_5:
+ case TYPE_MUL_6:
+ if (size == 1)
+ abort ();
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, multiplier_N);
+ break;
+
+ case TYPE_ADDMUL_2:
+ case TYPE_ADDMUL_3:
+ case TYPE_ADDMUL_4:
+ case TYPE_ADDMUL_5:
+ case TYPE_ADDMUL_6:
+ case TYPE_ADDMUL_7:
+ case TYPE_ADDMUL_8:
+ if (size == 1)
+ abort ();
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, multiplier_N);
+ break;
+
+ case TYPE_AND_N:
+ case TYPE_ANDN_N:
+ case TYPE_NAND_N:
+ case TYPE_IOR_N:
+ case TYPE_IORN_N:
+ case TYPE_NIOR_N:
+ case TYPE_XOR_N:
+ case TYPE_XNOR_N:
+ CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size);
+ break;
+
+ case TYPE_ADDSUB_N:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->d[1].p, e->s[0].p, e->s[1].p, size);
+ break;
+ case TYPE_ADDSUB_NC:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->d[1].p, e->s[0].p, e->s[1].p, size, carry);
+ break;
+
+ case TYPE_COPY:
+ case TYPE_COPYI:
+ case TYPE_COPYD:
+ case TYPE_COM:
+ CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size);
+ break;
+
+ case TYPE_ADDLSH1_N_IP1:
+ case TYPE_ADDLSH2_N_IP1:
+ case TYPE_ADDLSH1_N_IP2:
+ case TYPE_ADDLSH2_N_IP2:
+ case TYPE_SUBLSH1_N_IP1:
+ case TYPE_SUBLSH2_N_IP1:
+ case TYPE_DIVEXACT_BY3:
+ e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size);
+ break;
+ case TYPE_DIVEXACT_BY3C:
+ e->retval = CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size,
+ carry);
+ break;
+
+
+ case TYPE_DIVMOD_1:
+ case TYPE_DIVEXACT_1:
+ case TYPE_BDIV_Q_1:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, divisor);
+ break;
+ case TYPE_DIVMOD_1C:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, divisor, carry);
+ break;
+ case TYPE_DIVREM_1:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, size2, e->s[0].p, size, divisor);
+ break;
+ case TYPE_DIVREM_1C:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, size2, e->s[0].p, size, divisor, carry);
+ break;
+ case TYPE_PREINV_DIVREM_1:
+ {
+ mp_limb_t dinv;
+ unsigned shift;
+ shift = refmpn_count_leading_zeros (divisor);
+ dinv = refmpn_invert_limb (divisor << shift);
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, size2, e->s[0].p, size, divisor, dinv, shift);
+ }
+ break;
+ case TYPE_MOD_1:
+ case TYPE_MODEXACT_1_ODD:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->s[0].p, size, divisor);
+ break;
+ case TYPE_MOD_1C:
+ case TYPE_MODEXACT_1C_ODD:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->s[0].p, size, divisor, carry);
+ break;
+ case TYPE_PREINV_MOD_1:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->s[0].p, size, divisor, refmpn_invert_limb (divisor));
+ break;
+ case TYPE_DIV_QR_1N_PI1:
+ {
+ mp_limb_t dinv = refmpn_invert_limb (divisor);
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, e->s[1].p[0], divisor, dinv);
+ break;
+ }
+
+ case TYPE_MOD_34LSUB1:
+ e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size);
+ break;
+
+ case TYPE_UDIV_QRNND:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p[1], e->s[0].p[0], divisor);
+ break;
+ case TYPE_UDIV_QRNND_R:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->s[0].p[1], e->s[0].p[0], divisor, e->d[0].p);
+ break;
+
+ case TYPE_SBPI1_DIV_QR:
+ {
+ gmp_pi1_t dinv;
+ invert_pi1 (dinv, e->s[1].p[size2-1], e->s[1].p[size2-2]); /* FIXME: use refinvert_pi1 */
+ refmpn_copyi (e->d[1].p, e->s[0].p, size); /* dividend */
+ refmpn_fill (e->d[0].p, size-size2, 0x98765432); /* quotient */
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->d[1].p, size, e->s[1].p, size2, dinv.inv32);
+ refmpn_zero (e->d[1].p+size2, size-size2); /* excess over remainder */
+ }
+ break;
+
+ case TYPE_TDIV_QR:
+ CALLING_CONVENTIONS (function) (e->d[0].p, e->d[1].p, 0,
+ e->s[0].p, size, e->s[1].p, size2);
+ break;
+
+ case TYPE_GCD_1:
+ /* Must have a non-zero src, but this probably isn't the best way to do
+ it. */
+ if (refmpn_zero_p (e->s[0].p, size))
+ e->retval = 0;
+ else
+ e->retval = CALLING_CONVENTIONS (function) (e->s[0].p, size, divisor);
+ break;
+
+ case TYPE_GCD:
+ /* Sources are destroyed, so they're saved and replaced, but a general
+ approach to this might be better. Note that it's still e->s[0].p and
+ e->s[1].p that are passed, to get the desired alignments. */
+ {
+ mp_ptr s0 = refmpn_malloc_limbs (size);
+ mp_ptr s1 = refmpn_malloc_limbs (size2);
+ refmpn_copyi (s0, e->s[0].p, size);
+ refmpn_copyi (s1, e->s[1].p, size2);
+
+ mprotect_region (&s[0].region, PROT_READ|PROT_WRITE);
+ mprotect_region (&s[1].region, PROT_READ|PROT_WRITE);
+ e->retval = CALLING_CONVENTIONS (function) (e->d[0].p,
+ e->s[0].p, size,
+ e->s[1].p, size2);
+ refmpn_copyi (e->s[0].p, s0, size);
+ refmpn_copyi (e->s[1].p, s1, size2);
+ free (s0);
+ free (s1);
+ }
+ break;
+
+ case TYPE_GCD_FINDA:
+ {
+ /* FIXME: do this with a flag */
+ mp_limb_t c[2];
+ c[0] = e->s[0].p[0];
+ c[0] += (c[0] == 0);
+ c[1] = e->s[0].p[0];
+ c[1] += (c[1] == 0);
+ e->retval = CALLING_CONVENTIONS (function) (c);
+ }
+ break;
+
+ case TYPE_MPZ_LEGENDRE:
+ case TYPE_MPZ_JACOBI:
+ {
+ mpz_t a, b;
+ PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size);
+ PTR(b) = e->s[1].p; SIZ(b) = size2;
+ e->retval = CALLING_CONVENTIONS (function) (a, b);
+ }
+ break;
+ case TYPE_MPZ_KRONECKER:
+ {
+ mpz_t a, b;
+ PTR(a) = e->s[0].p; SIZ(a) = ((carry&1)==0 ? size : -size);
+ PTR(b) = e->s[1].p; SIZ(b) = ((carry&2)==0 ? size2 : -size2);
+ e->retval = CALLING_CONVENTIONS (function) (a, b);
+ }
+ break;
+ case TYPE_MPZ_KRONECKER_UI:
+ {
+ mpz_t a;
+ PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size);
+ e->retval = CALLING_CONVENTIONS(function) (a, (unsigned long)multiplier);
+ }
+ break;
+ case TYPE_MPZ_KRONECKER_SI:
+ {
+ mpz_t a;
+ PTR(a) = e->s[0].p; SIZ(a) = (carry==0 ? size : -size);
+ e->retval = CALLING_CONVENTIONS (function) (a, (long) multiplier);
+ }
+ break;
+ case TYPE_MPZ_UI_KRONECKER:
+ {
+ mpz_t b;
+ PTR(b) = e->s[0].p; SIZ(b) = (carry==0 ? size : -size);
+ e->retval = CALLING_CONVENTIONS(function) ((unsigned long)multiplier, b);
+ }
+ break;
+ case TYPE_MPZ_SI_KRONECKER:
+ {
+ mpz_t b;
+ PTR(b) = e->s[0].p; SIZ(b) = (carry==0 ? size : -size);
+ e->retval = CALLING_CONVENTIONS (function) ((long) multiplier, b);
+ }
+ break;
+
+ case TYPE_MUL_MN:
+ case TYPE_MULMID_MN:
+ CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, e->s[1].p, size2);
+ break;
+ case TYPE_MUL_N:
+ case TYPE_MULLO_N:
+ CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p, size);
+ break;
+ case TYPE_MULMID_N:
+ CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, e->s[1].p,
+ (size + 1) / 2);
+ break;
+ case TYPE_SQR:
+ CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size);
+ break;
+
+ case TYPE_UMUL_PPMM:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p[0], e->s[0].p[1]);
+ break;
+ case TYPE_UMUL_PPMM_R:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->s[0].p[0], e->s[0].p[1], e->d[0].p);
+ break;
+
+ case TYPE_ADDLSH_N_IP1:
+ case TYPE_ADDLSH_N_IP2:
+ case TYPE_SUBLSH_N_IP1:
+ case TYPE_LSHIFT:
+ case TYPE_LSHIFTC:
+ case TYPE_RSHIFT:
+ e->retval = CALLING_CONVENTIONS (function)
+ (e->d[0].p, e->s[0].p, size, shift);
+ break;
+
+ case TYPE_POPCOUNT:
+ e->retval = (* (unsigned long (*)(ANYARGS))
+ CALLING_CONVENTIONS (function)) (e->s[0].p, size);
+ break;
+ case TYPE_HAMDIST:
+ e->retval = (* (unsigned long (*)(ANYARGS))
+ CALLING_CONVENTIONS (function)) (e->s[0].p, e->s[1].p, size);
+ break;
+
+ case TYPE_SQRTREM:
+ e->retval = (* (long (*)(ANYARGS)) CALLING_CONVENTIONS (function))
+ (e->d[0].p, e->d[1].p, e->s[0].p, size);
+ break;
+
+ case TYPE_ZERO:
+ CALLING_CONVENTIONS (function) (e->d[0].p, size);
+ break;
+
+ case TYPE_GET_STR:
+ {
+ size_t sizeinbase, fill;
+ char *dst;
+ MPN_SIZEINBASE (sizeinbase, e->s[0].p, size, base);
+ ASSERT_ALWAYS (sizeinbase <= d[0].size);
+ fill = d[0].size - sizeinbase;
+ if (d[0].high)
+ {
+ memset (e->d[0].p, 0xBA, fill);
+ dst = (char *) e->d[0].p + fill;
+ }
+ else
+ {
+ dst = (char *) e->d[0].p;
+ memset (dst + sizeinbase, 0xBA, fill);
+ }
+ if (POW2_P (base))
+ {
+ e->retval = CALLING_CONVENTIONS (function) (dst, base,
+ e->s[0].p, size);
+ }
+ else
+ {
+ refmpn_copy (e->d[1].p, e->s[0].p, size);
+ e->retval = CALLING_CONVENTIONS (function) (dst, base,
+ e->d[1].p, size);
+ }
+ refmpn_zero (e->d[1].p, size); /* clobbered or unused */
+ }
+ break;
+
+ case TYPE_INVERT:
+ {
+ mp_ptr scratch;
+ TMP_DECL;
+ TMP_MARK;
+ scratch = TMP_ALLOC_LIMBS (mpn_invert_itch (size));
+ CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, scratch);
+ TMP_FREE;
+ }
+ break;
+ case TYPE_BINVERT:
+ {
+ mp_ptr scratch;
+ TMP_DECL;
+ TMP_MARK;
+ scratch = TMP_ALLOC_LIMBS (mpn_binvert_itch (size));
+ CALLING_CONVENTIONS (function) (e->d[0].p, e->s[0].p, size, scratch);
+ TMP_FREE;
+ }
+ break;
+
+#ifdef EXTRA_CALL
+ EXTRA_CALL
+#endif
+
+ default:
+ printf ("Unknown routine type %d\n", choice->type);
+ abort ();
+ break;
+ }
+}
+
+
+void
+pointer_setup (struct each_t *e)
+{
+ int i, j;
+
+ for (i = 0; i < NUM_DESTS; i++)
+ {
+ switch (tr->dst_size[i]) {
+ case 0:
+ case SIZE_RETVAL: /* will be adjusted later */
+ d[i].size = size;
+ break;
+
+ case SIZE_1:
+ d[i].size = 1;
+ break;
+ case SIZE_2:
+ d[i].size = 2;
+ break;
+ case SIZE_3:
+ d[i].size = 3;
+ break;
+ case SIZE_4:
+ d[i].size = 4;
+ break;
+ case SIZE_6:
+ d[i].size = 6;
+ break;
+
+ case SIZE_PLUS_1:
+ d[i].size = size+1;
+ break;
+ case SIZE_PLUS_MSIZE_SUB_1:
+ d[i].size = size + tr->msize - 1;
+ break;
+
+ case SIZE_SUM:
+ if (tr->size2)
+ d[i].size = size + size2;
+ else
+ d[i].size = 2*size;
+ break;
+
+ case SIZE_SIZE2:
+ d[i].size = size2;
+ break;
+
+ case SIZE_DIFF:
+ d[i].size = size - size2;
+ break;
+
+ case SIZE_DIFF_PLUS_1:
+ d[i].size = size - size2 + 1;
+ break;
+
+ case SIZE_DIFF_PLUS_3:
+ d[i].size = size - size2 + 3;
+ break;
+
+ case SIZE_CEIL_HALF:
+ d[i].size = (size+1)/2;
+ break;
+
+ case SIZE_GET_STR:
+ {
+ mp_limb_t ff = GMP_NUMB_MAX;
+ MPN_SIZEINBASE (d[i].size, &ff - (size-1), size, base);
+ }
+ break;
+
+ default:
+ printf ("Unrecognised dst_size type %d\n", tr->dst_size[i]);
+ abort ();
+ }
+ }
+
+ /* establish e->d[].p destinations */
+ for (i = 0; i < NUM_DESTS; i++)
+ {
+ mp_size_t offset = 0;
+
+ /* possible room for overlapping sources */
+ for (j = 0; j < numberof (overlap->s); j++)
+ if (overlap->s[j] == i)
+ offset = MAX (offset, s[j].align);
+
+ if (d[i].high)
+ {
+ if (tr->dst_bytes[i])
+ {
+ e->d[i].p = (mp_ptr)
+ ((char *) (e->d[i].region.ptr + e->d[i].region.size)
+ - d[i].size - d[i].align);
+ }
+ else
+ {
+ e->d[i].p = e->d[i].region.ptr + e->d[i].region.size
+ - d[i].size - d[i].align;
+ if (tr->overlap == OVERLAP_LOW_TO_HIGH)
+ e->d[i].p -= offset;
+ }
+ }
+ else
+ {
+ if (tr->dst_bytes[i])
+ {
+ e->d[i].p = (mp_ptr) ((char *) e->d[i].region.ptr + d[i].align);
+ }
+ else
+ {
+ e->d[i].p = e->d[i].region.ptr + d[i].align;
+ if (tr->overlap == OVERLAP_HIGH_TO_LOW)
+ e->d[i].p += offset;
+ }
+ }
+ }
+
+ /* establish e->s[].p sources */
+ for (i = 0; i < NUM_SOURCES; i++)
+ {
+ int o = overlap->s[i];
+ switch (o) {
+ case -1:
+ /* no overlap */
+ e->s[i].p = s[i].p;
+ break;
+ case 0:
+ case 1:
+ /* overlap with d[o] */
+ if (tr->overlap == OVERLAP_HIGH_TO_LOW)
+ e->s[i].p = e->d[o].p - s[i].align;
+ else if (tr->overlap == OVERLAP_LOW_TO_HIGH)
+ e->s[i].p = e->d[o].p + s[i].align;
+ else if (tr->size2 == SIZE_FRACTION)
+ e->s[i].p = e->d[o].p + size2;
+ else
+ e->s[i].p = e->d[o].p;
+ break;
+ default:
+ abort();
+ break;
+ }
+ }
+}
+
+
+void
+validate_fail (void)
+{
+ if (tr->reference)
+ {
+ trap_location = TRAP_REF;
+ call (&ref, tr->reference);
+ trap_location = TRAP_NOWHERE;
+ }
+
+ print_all();
+ abort();
+}
+
+
+void
+try_one (void)
+{
+ int i;
+
+ if (option_spinner)
+ spinner();
+ spinner_count++;
+
+ trap_location = TRAP_SETUPS;
+
+ if (tr->divisor == DIVISOR_NORM)
+ divisor |= GMP_NUMB_HIGHBIT;
+ if (tr->divisor == DIVISOR_ODD)
+ divisor |= 1;
+
+ for (i = 0; i < NUM_SOURCES; i++)
+ {
+ if (s[i].high)
+ s[i].p = s[i].region.ptr + s[i].region.size - SRC_SIZE(i) - s[i].align;
+ else
+ s[i].p = s[i].region.ptr + s[i].align;
+ }
+
+ pointer_setup (&ref);
+ pointer_setup (&fun);
+
+ ref.retval = 0x04152637;
+ fun.retval = 0x8C9DAEBF;
+
+ t_random (multiplier_N, tr->msize);
+
+ for (i = 0; i < NUM_SOURCES; i++)
+ {
+ if (! tr->src[i])
+ continue;
+
+ mprotect_region (&s[i].region, PROT_READ|PROT_WRITE);
+ t_random (s[i].p, SRC_SIZE(i));
+
+ switch (tr->data) {
+ case DATA_NON_ZERO:
+ if (refmpn_zero_p (s[i].p, SRC_SIZE(i)))
+ s[i].p[0] = 1;
+ break;
+
+ case DATA_MULTIPLE_DIVISOR:
+ /* same number of low zero bits as divisor */
+ s[i].p[0] &= ~ LOW_ZEROS_MASK (divisor);
+ refmpn_sub_1 (s[i].p, s[i].p, size,
+ refmpn_mod_1 (s[i].p, size, divisor));
+ break;
+
+ case DATA_GCD:
+ /* s[1] no more bits than s[0] */
+ if (i == 1 && size2 == size)
+ s[1].p[size-1] &= refmpn_msbone_mask (s[0].p[size-1]);
+
+ /* high limb non-zero */
+ s[i].p[SRC_SIZE(i)-1] += (s[i].p[SRC_SIZE(i)-1] == 0);
+
+ /* odd */
+ s[i].p[0] |= 1;
+ break;
+
+ case DATA_SRC0_ODD:
+ if (i == 0)
+ s[i].p[0] |= 1;
+ break;
+
+ case DATA_SRC1_ODD:
+ if (i == 1)
+ s[i].p[0] |= 1;
+ break;
+
+ case DATA_SRC1_ODD_PRIME:
+ if (i == 1)
+ {
+ if (refmpn_zero_p (s[i].p+1, SRC_SIZE(i)-1)
+ && s[i].p[0] <=3)
+ s[i].p[0] = 3;
+ else
+ {
+ mpz_t p;
+ mpz_init (p);
+ for (;;)
+ {
+ _mpz_realloc (p, SRC_SIZE(i));
+ MPN_COPY (PTR(p), s[i].p, SRC_SIZE(i));
+ SIZ(p) = SRC_SIZE(i);
+ MPN_NORMALIZE (PTR(p), SIZ(p));
+ mpz_nextprime (p, p);
+ if (mpz_size (p) <= SRC_SIZE(i))
+ break;
+
+ t_random (s[i].p, SRC_SIZE(i));
+ }
+ MPN_COPY (s[i].p, PTR(p), SIZ(p));
+ if (SIZ(p) < SRC_SIZE(i))
+ MPN_ZERO (s[i].p + SIZ(p), SRC_SIZE(i) - SIZ(p));
+ mpz_clear (p);
+ }
+ }
+ break;
+
+ case DATA_SRC1_HIGHBIT:
+ if (i == 1)
+ {
+ if (tr->size2)
+ s[i].p[size2-1] |= GMP_NUMB_HIGHBIT;
+ else
+ s[i].p[size-1] |= GMP_NUMB_HIGHBIT;
+ }
+ break;
+
+ case DATA_SRC0_HIGHBIT:
+ if (i == 0)
+ {
+ s[i].p[size-1] |= GMP_NUMB_HIGHBIT;
+ }
+ break;
+
+ case DATA_UDIV_QRNND:
+ s[i].p[1] %= divisor;
+ break;
+ case DATA_DIV_QR_1:
+ if (i == 1)
+ s[i].p[0] %= divisor;
+ break;
+ }
+
+ mprotect_region (&s[i].region, PROT_READ);
+ }
+
+ for (i = 0; i < NUM_DESTS; i++)
+ {
+ if (! tr->dst[i])
+ continue;
+
+ if (tr->dst0_from_src1 && i==0)
+ {
+ mp_size_t copy = MIN (d[0].size, SRC_SIZE(1));
+ mp_size_t fill = MAX (0, d[0].size - copy);
+ MPN_COPY (fun.d[0].p, s[1].region.ptr, copy);
+ MPN_COPY (ref.d[0].p, s[1].region.ptr, copy);
+ refmpn_fill (fun.d[0].p + copy, fill, DEADVAL);
+ refmpn_fill (ref.d[0].p + copy, fill, DEADVAL);
+ }
+ else if (tr->dst_bytes[i])
+ {
+ memset (ref.d[i].p, 0xBA, d[i].size);
+ memset (fun.d[i].p, 0xBA, d[i].size);
+ }
+ else
+ {
+ refmpn_fill (ref.d[i].p, d[i].size, DEADVAL);
+ refmpn_fill (fun.d[i].p, d[i].size, DEADVAL);
+ }
+ }
+
+ for (i = 0; i < NUM_SOURCES; i++)
+ {
+ if (! tr->src[i])
+ continue;
+
+ if (ref.s[i].p != s[i].p)
+ {
+ refmpn_copyi (ref.s[i].p, s[i].p, SRC_SIZE(i));
+ refmpn_copyi (fun.s[i].p, s[i].p, SRC_SIZE(i));
+ }
+ }
+
+ if (option_print)
+ print_all();
+
+ if (tr->validate != NULL)
+ {
+ trap_location = TRAP_FUN;
+ call (&fun, choice->function);
+ trap_location = TRAP_NOWHERE;
+
+ if (! CALLING_CONVENTIONS_CHECK ())
+ {
+ print_all();
+ abort();
+ }
+
+ (*tr->validate) ();
+ }
+ else
+ {
+ trap_location = TRAP_REF;
+ call (&ref, tr->reference);
+ trap_location = TRAP_FUN;
+ call (&fun, choice->function);
+ trap_location = TRAP_NOWHERE;
+
+ if (! CALLING_CONVENTIONS_CHECK ())
+ {
+ print_all();
+ abort();
+ }
+
+ compare ();
+ }
+}
+
+
+#define SIZE_ITERATION \
+ for (size = MAX3 (option_firstsize, \
+ choice->minsize, \
+ (tr->size == SIZE_ALLOW_ZERO) ? 0 : 1), \
+ size += (tr->size == SIZE_ODD) && !(size & 1); \
+ size <= option_lastsize; \
+ size += (tr->size == SIZE_ODD) ? 2 : 1)
+
+#define SIZE2_FIRST \
+ (tr->size2 == SIZE_2 ? 2 \
+ : tr->size2 == SIZE_FRACTION ? option_firstsize2 \
+ : tr->size2 == SIZE_CEIL_HALF ? ((size + 1) / 2) \
+ : tr->size2 ? \
+ MAX (choice->minsize, (option_firstsize2 != 0 \
+ ? option_firstsize2 : 1)) \
+ : 0)
+
+#define SIZE2_LAST \
+ (tr->size2 == SIZE_2 ? 2 \
+ : tr->size2 == SIZE_FRACTION ? FRACTION_COUNT-1 \
+ : tr->size2 == SIZE_CEIL_HALF ? ((size + 1) / 2) \
+ : tr->size2 ? size \
+ : 0)
+
+#define SIZE2_ITERATION \
+ for (size2 = SIZE2_FIRST; size2 <= SIZE2_LAST; size2++)
+
+#define ALIGN_COUNT(cond) ((cond) ? ALIGNMENTS : 1)
+#define ALIGN_ITERATION(w,n,cond) \
+ for (w[n].align = 0; w[n].align < ALIGN_COUNT(cond); w[n].align++)
+
+#define HIGH_LIMIT(cond) ((cond) != 0)
+#define HIGH_COUNT(cond) (HIGH_LIMIT (cond) + 1)
+#define HIGH_ITERATION(w,n,cond) \
+ for (w[n].high = 0; w[n].high <= HIGH_LIMIT(cond); w[n].high++)
+
+#define SHIFT_LIMIT \
+ ((unsigned long) (tr->shift ? GMP_NUMB_BITS -1 : 1))
+
+#define SHIFT_ITERATION \
+ for (shift = 1; shift <= SHIFT_LIMIT; shift++)
+
+
+void
+try_many (void)
+{
+ int i;
+
+ {
+ unsigned long total = 1;
+
+ total *= option_repetitions;
+ total *= option_lastsize;
+ if (tr->size2 == SIZE_FRACTION) total *= FRACTION_COUNT;
+ else if (tr->size2) total *= (option_lastsize+1)/2;
+
+ total *= SHIFT_LIMIT;
+ total *= MULTIPLIER_COUNT;
+ total *= DIVISOR_COUNT;
+ total *= CARRY_COUNT;
+ total *= T_RAND_COUNT;
+
+ total *= HIGH_COUNT (tr->dst[0]);
+ total *= HIGH_COUNT (tr->dst[1]);
+ total *= HIGH_COUNT (tr->src[0]);
+ total *= HIGH_COUNT (tr->src[1]);
+
+ total *= ALIGN_COUNT (tr->dst[0]);
+ total *= ALIGN_COUNT (tr->dst[1]);
+ total *= ALIGN_COUNT (tr->src[0]);
+ total *= ALIGN_COUNT (tr->src[1]);
+
+ total *= OVERLAP_COUNT;
+
+ printf ("%s %lu\n", choice->name, total);
+ }
+
+ spinner_count = 0;
+
+ for (i = 0; i < option_repetitions; i++)
+ SIZE_ITERATION
+ SIZE2_ITERATION
+
+ SHIFT_ITERATION
+ MULTIPLIER_ITERATION
+ DIVISOR_ITERATION
+ CARRY_ITERATION /* must be after divisor */
+ T_RAND_ITERATION
+
+ HIGH_ITERATION(d,0, tr->dst[0])
+ HIGH_ITERATION(d,1, tr->dst[1])
+ HIGH_ITERATION(s,0, tr->src[0])
+ HIGH_ITERATION(s,1, tr->src[1])
+
+ ALIGN_ITERATION(d,0, tr->dst[0])
+ ALIGN_ITERATION(d,1, tr->dst[1])
+ ALIGN_ITERATION(s,0, tr->src[0])
+ ALIGN_ITERATION(s,1, tr->src[1])
+
+ OVERLAP_ITERATION
+ try_one();
+
+ printf("\n");
+}
+
+
+/* Usually print_all() doesn't show much, but it might give a hint as to
+ where the function was up to when it died. */
+void
+trap (int sig)
+{
+ const char *name = "noname";
+
+ switch (sig) {
+ case SIGILL: name = "SIGILL"; break;
+#ifdef SIGBUS
+ case SIGBUS: name = "SIGBUS"; break;
+#endif
+ case SIGSEGV: name = "SIGSEGV"; break;
+ case SIGFPE: name = "SIGFPE"; break;
+ }
+
+ printf ("\n\nSIGNAL TRAP: %s\n", name);
+
+ switch (trap_location) {
+ case TRAP_REF:
+ printf (" in reference function: %s\n", tr->reference_name);
+ break;
+ case TRAP_FUN:
+ printf (" in test function: %s\n", choice->name);
+ print_all ();
+ break;
+ case TRAP_SETUPS:
+ printf (" in parameter setups\n");
+ print_all ();
+ break;
+ default:
+ printf (" somewhere unknown\n");
+ break;
+ }
+ exit (1);
+}
+
+
+void
+try_init (void)
+{
+#if HAVE_GETPAGESIZE
+ /* Prefer getpagesize() over sysconf(), since on SunOS 4 sysconf() doesn't
+ know _SC_PAGESIZE. */
+ pagesize = getpagesize ();
+#else
+#if HAVE_SYSCONF
+ if ((pagesize = sysconf (_SC_PAGESIZE)) == -1)
+ {
+ /* According to the linux man page, sysconf doesn't set errno */
+ fprintf (stderr, "Cannot get sysconf _SC_PAGESIZE\n");
+ exit (1);
+ }
+#else
+Error, error, cannot get page size
+#endif
+#endif
+
+ printf ("pagesize is 0x%lX bytes\n", pagesize);
+
+ signal (SIGILL, trap);
+#ifdef SIGBUS
+ signal (SIGBUS, trap);
+#endif
+ signal (SIGSEGV, trap);
+ signal (SIGFPE, trap);
+
+ {
+ int i;
+
+ for (i = 0; i < NUM_SOURCES; i++)
+ {
+ malloc_region (&s[i].region, 2*option_lastsize+ALIGNMENTS-1);
+ printf ("s[%d] %p to %p (0x%lX bytes)\n",
+ i, (void *) (s[i].region.ptr),
+ (void *) (s[i].region.ptr + s[i].region.size),
+ (long) s[i].region.size * GMP_LIMB_BYTES);
+ }
+
+#define INIT_EACH(e,es) \
+ for (i = 0; i < NUM_DESTS; i++) \
+ { \
+ malloc_region (&e.d[i].region, 2*option_lastsize+ALIGNMENTS-1); \
+ printf ("%s d[%d] %p to %p (0x%lX bytes)\n", \
+ es, i, (void *) (e.d[i].region.ptr), \
+ (void *) (e.d[i].region.ptr + e.d[i].region.size), \
+ (long) e.d[i].region.size * GMP_LIMB_BYTES); \
+ }
+
+ INIT_EACH(ref, "ref");
+ INIT_EACH(fun, "fun");
+ }
+}
+
+int
+strmatch_wild (const char *pattern, const char *str)
+{
+ size_t plen, slen;
+
+ /* wildcard at start */
+ if (pattern[0] == '*')
+ {
+ pattern++;
+ plen = strlen (pattern);
+ slen = strlen (str);
+ return (plen == 0
+ || (slen >= plen && memcmp (pattern, str+slen-plen, plen) == 0));
+ }
+
+ /* wildcard at end */
+ plen = strlen (pattern);
+ if (plen >= 1 && pattern[plen-1] == '*')
+ return (memcmp (pattern, str, plen-1) == 0);
+
+ /* no wildcards */
+ return (strcmp (pattern, str) == 0);
+}
+
+void
+try_name (const char *name)
+{
+ int found = 0;
+ int i;
+
+ for (i = 0; i < numberof (choice_array); i++)
+ {
+ if (strmatch_wild (name, choice_array[i].name))
+ {
+ choice = &choice_array[i];
+ tr = &param[choice->type];
+ try_many ();
+ found = 1;
+ }
+ }
+
+ if (!found)
+ {
+ printf ("%s unknown\n", name);
+ /* exit (1); */
+ }
+}
+
+
+void
+usage (const char *prog)
+{
+ int col = 0;
+ int i;
+
+ printf ("Usage: %s [options] function...\n", prog);
+ printf (" -1 use limb data 1,2,3,etc\n");
+ printf (" -9 use limb data all 0xFF..FFs\n");
+ printf (" -a zeros use limb data all zeros\n");
+ printf (" -a ffs use limb data all 0xFF..FFs (same as -9)\n");
+ printf (" -a 2fd use data 0x2FFF...FFFD\n");
+ printf (" -p print each case tried (try this if seg faulting)\n");
+ printf (" -R seed random numbers from time()\n");
+ printf (" -r reps set repetitions (default %d)\n", DEFAULT_REPETITIONS);
+ printf (" -s size starting size to test\n");
+ printf (" -S size2 starting size2 to test\n");
+ printf (" -s s1-s2 range of sizes to test\n");
+ printf (" -W don't show the spinner (use this in gdb)\n");
+ printf (" -z disable mprotect() redzones\n");
+ printf ("Default data is refmpn_random() and refmpn_random2().\n");
+ printf ("\n");
+ printf ("Functions that can be tested:\n");
+
+ for (i = 0; i < numberof (choice_array); i++)
+ {
+ if (col + 1 + strlen (choice_array[i].name) > 79)
+ {
+ printf ("\n");
+ col = 0;
+ }
+ printf (" %s", choice_array[i].name);
+ col += 1 + strlen (choice_array[i].name);
+ }
+ printf ("\n");
+
+ exit(1);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ /* unbuffered output */
+ setbuf (stdout, NULL);
+ setbuf (stderr, NULL);
+
+ /* default trace in hex, and in upper-case so can paste into bc */
+ mp_trace_base = -16;
+
+ param_init ();
+
+ {
+ unsigned long seed = 123;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "19a:b:E:pRr:S:s:Wz")) != EOF)
+ {
+ switch (opt) {
+ case '1':
+ /* use limb data values 1, 2, 3, ... etc */
+ option_data = DATA_SEQ;
+ break;
+ case '9':
+ /* use limb data values 0xFFF...FFF always */
+ option_data = DATA_FFS;
+ break;
+ case 'a':
+ if (strcmp (optarg, "zeros") == 0) option_data = DATA_ZEROS;
+ else if (strcmp (optarg, "seq") == 0) option_data = DATA_SEQ;
+ else if (strcmp (optarg, "ffs") == 0) option_data = DATA_FFS;
+ else if (strcmp (optarg, "2fd") == 0) option_data = DATA_2FD;
+ else
+ {
+ fprintf (stderr, "unrecognised data option: %s\n", optarg);
+ exit (1);
+ }
+ break;
+ case 'b':
+ mp_trace_base = atoi (optarg);
+ break;
+ case 'E':
+ /* re-seed */
+ sscanf (optarg, "%lu", &seed);
+ printf ("Re-seeding with %lu\n", seed);
+ break;
+ case 'p':
+ option_print = 1;
+ break;
+ case 'R':
+ /* randomize */
+ seed = time (NULL);
+ printf ("Seeding with %lu, re-run using \"-E %lu\"\n", seed, seed);
+ break;
+ case 'r':
+ option_repetitions = atoi (optarg);
+ break;
+ case 's':
+ {
+ char *p;
+ option_firstsize = strtol (optarg, 0, 0);
+ if ((p = strchr (optarg, '-')) != NULL)
+ option_lastsize = strtol (p+1, 0, 0);
+ }
+ break;
+ case 'S':
+ /* -S <size> sets the starting size for the second of a two size
+ routine (like mpn_mul_basecase) */
+ option_firstsize2 = strtol (optarg, 0, 0);
+ break;
+ case 'W':
+ /* use this when running in the debugger */
+ option_spinner = 0;
+ break;
+ case 'z':
+ /* disable redzones */
+ option_redzones = 0;
+ break;
+ case '?':
+ usage (argv[0]);
+ break;
+ }
+ }
+
+ gmp_randinit_default (__gmp_rands);
+ __gmp_rands_initialized = 1;
+ gmp_randseed_ui (__gmp_rands, seed);
+ }
+
+ try_init();
+
+ if (argc <= optind)
+ usage (argv[0]);
+
+ for (i = optind; i < argc; i++)
+ try_name (argv[i]);
+
+ return 0;
+}
diff --git a/gmp/tests/devel/tst-addsub.c b/gmp/tests/devel/tst-addsub.c
new file mode 100644
index 0000000000..50aa3a73b3
--- /dev/null
+++ b/gmp/tests/devel/tst-addsub.c
@@ -0,0 +1,98 @@
+/* Copyright 1996, 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define ADD 1
+#define SUB 2
+
+#ifndef METHOD
+#define METHOD ADD
+#endif
+
+#if METHOD == ADD
+#define REFCALL refmpn_add_n
+#define TESTCALL mpn_add_n
+#endif
+
+#if METHOD == SUB
+#define REFCALL refmpn_sub_n
+#define TESTCALL mpn_sub_n
+#endif
+
+#define SIZE 100
+
+int
+main (int argc, char **argv)
+{
+ mp_size_t alloc_size, max_size, size, i, cumul_size;
+ mp_ptr s1, s2, dx, dy;
+ int s1_align, s2_align, d_align;
+ long pass, n_passes;
+ mp_limb_t cx, cy;
+
+ max_size = SIZE;
+ n_passes = 1000000;
+
+ argc--; argv++;
+ if (argc)
+ {
+ max_size = atol (*argv);
+ argc--; argv++;
+ }
+
+ alloc_size = max_size + 32;
+ s1 = malloc (alloc_size * GMP_LIMB_BYTES);
+ s2 = malloc (alloc_size * GMP_LIMB_BYTES);
+ dx = malloc (alloc_size * GMP_LIMB_BYTES);
+ dy = malloc (alloc_size * GMP_LIMB_BYTES);
+
+ cumul_size = 0;
+ for (pass = 0; pass < n_passes; pass++)
+ {
+ size = random () % max_size + 1;
+
+ cumul_size += size;
+ if (cumul_size >= 1000000)
+ {
+ cumul_size -= 1000000;
+ printf ("\r%ld", pass); fflush (stdout);
+ }
+ s1_align = random () % 32;
+ s2_align = random () % 32;
+ d_align = random () % 32;
+
+ mpn_random2 (s1 + s1_align, size);
+ mpn_random2 (s2 + s2_align, size);
+
+ for (i = 0; i < alloc_size; i++)
+ dx[i] = dy[i] = i + 0x9876500;
+
+ cx = TESTCALL (dx + d_align, s1 + s1_align, s2 + s2_align, size);
+ cy = REFCALL (dy + d_align, s1 + s1_align, s2 + s2_align, size);
+
+ if (cx != cy || mpn_cmp (dx, dy, alloc_size) != 0)
+ abort ();
+ }
+
+ printf ("%ld passes OK\n", n_passes);
+ exit (0);
+}
diff --git a/gmp/tests/memory.c b/gmp/tests/memory.c
new file mode 100644
index 0000000000..c91813ea08
--- /dev/null
+++ b/gmp/tests/memory.c
@@ -0,0 +1,247 @@
+/* Memory allocation used during tests.
+
+Copyright 2001, 2002, 2007, 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 <stdio.h>
+#include <stdlib.h> /* for abort */
+#include <string.h> /* for memcpy, memcmp */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#if GMP_LIMB_BITS == 64
+#define PATTERN1 CNST_LIMB(0xcafebabedeadbeef)
+#define PATTERN2 CNST_LIMB(0xabacadabaedeedab)
+#else
+#define PATTERN1 CNST_LIMB(0xcafebabe)
+#define PATTERN2 CNST_LIMB(0xdeadbeef)
+#endif
+
+#if HAVE_INTPTR_T
+#define PTRLIMB(p) ((mp_limb_t) (intptr_t) p)
+#else
+#define PTRLIMB(p) ((mp_limb_t) (size_t) p)
+#endif
+
+/* Each block allocated is a separate malloc, for the benefit of a redzoning
+ malloc debugger during development or when bug hunting.
+
+ Sizes passed when reallocating or freeing are checked (the default
+ routines don't care about these).
+
+ Memory leaks are checked by requiring that all blocks have been freed
+ when tests_memory_end() is called. Test programs must be sure to have
+ "clear"s for all temporary variables used. */
+
+
+struct header {
+ void *ptr;
+ size_t size;
+ struct header *next;
+};
+
+struct header *tests_memory_list = NULL;
+
+/* Return a pointer to a pointer to the found block (so it can be updated
+ when unlinking). */
+struct header **
+tests_memory_find (void *ptr)
+{
+ struct header **hp;
+
+ for (hp = &tests_memory_list; *hp != NULL; hp = &((*hp)->next))
+ if ((*hp)->ptr == ptr)
+ return hp;
+
+ return NULL;
+}
+
+int
+tests_memory_valid (void *ptr)
+{
+ return (tests_memory_find (ptr) != NULL);
+}
+
+void *
+tests_allocate (size_t size)
+{
+ struct header *h;
+ void *rptr, *ptr;
+ mp_limb_t PATTERN2_var;
+
+ if (size == 0)
+ {
+ fprintf (stderr, "tests_allocate(): attempt to allocate 0 bytes\n");
+ abort ();
+ }
+
+ h = (struct header *) __gmp_default_allocate (sizeof (*h));
+ h->next = tests_memory_list;
+ tests_memory_list = h;
+
+ rptr = __gmp_default_allocate (size + 2 * sizeof (mp_limb_t));
+ ptr = (void *) ((gmp_intptr_t) rptr + sizeof (mp_limb_t));
+
+ *((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
+ = PATTERN1 - PTRLIMB (ptr);
+ PATTERN2_var = PATTERN2 - PTRLIMB (ptr);
+ memcpy ((void *) ((gmp_intptr_t) ptr + size), &PATTERN2_var, sizeof (mp_limb_t));
+
+ h->size = size;
+ h->ptr = ptr;
+ return h->ptr;
+}
+
+void *
+tests_reallocate (void *ptr, size_t old_size, size_t new_size)
+{
+ struct header **hp, *h;
+ void *rptr;
+ mp_limb_t PATTERN2_var;
+
+ if (new_size == 0)
+ {
+ fprintf (stderr, "tests_reallocate(): attempt to reallocate %p to 0 bytes\n",
+ ptr);
+ abort ();
+ }
+
+ hp = tests_memory_find (ptr);
+ if (hp == NULL)
+ {
+ fprintf (stderr, "tests_reallocate(): attempt to reallocate bad pointer %p\n",
+ ptr);
+ abort ();
+ }
+ h = *hp;
+
+ if (h->size != old_size)
+ {
+ fprintf (stderr, "tests_reallocate(): bad old size %lu, should be %lu\n",
+ (unsigned long) old_size, (unsigned long) h->size);
+ abort ();
+ }
+
+ if (*((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
+ != PATTERN1 - PTRLIMB (ptr))
+ {
+ fprintf (stderr, "in realloc: redzone clobbered before block\n");
+ abort ();
+ }
+ PATTERN2_var = PATTERN2 - PTRLIMB (ptr);
+ if (memcmp ((void *) ((gmp_intptr_t) ptr + h->size), &PATTERN2_var, sizeof (mp_limb_t)))
+ {
+ fprintf (stderr, "in realloc: redzone clobbered after block\n");
+ abort ();
+ }
+
+ rptr = __gmp_default_reallocate ((void *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)),
+ old_size + 2 * sizeof (mp_limb_t),
+ new_size + 2 * sizeof (mp_limb_t));
+ ptr = (void *) ((gmp_intptr_t) rptr + sizeof (mp_limb_t));
+
+ *((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
+ = PATTERN1 - PTRLIMB (ptr);
+ PATTERN2_var = PATTERN2 - PTRLIMB (ptr);
+ memcpy ((void *) ((gmp_intptr_t) ptr + new_size), &PATTERN2_var, sizeof (mp_limb_t));
+
+ h->size = new_size;
+ h->ptr = ptr;
+ return h->ptr;
+}
+
+struct header **
+tests_free_find (void *ptr)
+{
+ struct header **hp = tests_memory_find (ptr);
+ if (hp == NULL)
+ {
+ fprintf (stderr, "tests_free(): attempt to free bad pointer %p\n",
+ ptr);
+ abort ();
+ }
+ return hp;
+}
+
+void
+tests_free_nosize (void *ptr)
+{
+ struct header **hp = tests_free_find (ptr);
+ struct header *h = *hp;
+ mp_limb_t PATTERN2_var;
+
+ *hp = h->next; /* unlink */
+
+ if (*((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
+ != PATTERN1 - PTRLIMB (ptr))
+ {
+ fprintf (stderr, "in free: redzone clobbered before block\n");
+ abort ();
+ }
+ PATTERN2_var = PATTERN2 - PTRLIMB (ptr);
+ if (memcmp ((void *) ((gmp_intptr_t) ptr + h->size), &PATTERN2_var, sizeof (mp_limb_t)))
+ {
+ fprintf (stderr, "in free: redzone clobbered after block\n");
+ abort ();
+ }
+
+ __gmp_default_free ((void *) ((gmp_intptr_t) ptr - sizeof(mp_limb_t)),
+ h->size + 2 * sizeof (mp_limb_t));
+ __gmp_default_free (h, sizeof (*h));
+}
+
+void
+tests_free (void *ptr, size_t size)
+{
+ struct header **hp = tests_free_find (ptr);
+ struct header *h = *hp;
+
+ if (h->size != size)
+ {
+ fprintf (stderr, "tests_free(): bad size %lu, should be %lu\n",
+ (unsigned long) size, (unsigned long) h->size);
+ abort ();
+ }
+
+ tests_free_nosize (ptr);
+}
+
+void
+tests_memory_start (void)
+{
+ mp_set_memory_functions (tests_allocate, tests_reallocate, tests_free);
+}
+
+void
+tests_memory_end (void)
+{
+ if (tests_memory_list != NULL)
+ {
+ struct header *h;
+ unsigned count;
+
+ fprintf (stderr, "tests_memory_end(): not all memory freed\n");
+
+ count = 0;
+ for (h = tests_memory_list; h != NULL; h = h->next)
+ count++;
+
+ fprintf (stderr, " %u blocks remaining\n", count);
+ abort ();
+ }
+}
diff --git a/gmp/tests/misc.c b/gmp/tests/misc.c
new file mode 100644
index 0000000000..59920c2726
--- /dev/null
+++ b/gmp/tests/misc.c
@@ -0,0 +1,565 @@
+/* Miscellaneous test program support routines.
+
+Copyright 2000-2003, 2005, 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 "config.h"
+
+#include <ctype.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h> /* for getenv */
+#include <string.h>
+
+#if HAVE_FLOAT_H
+#include <float.h> /* for DBL_MANT_DIG */
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h> /* for struct timeval */
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* The various tests setups and final checks, collected up together. */
+void
+tests_start (void)
+{
+ /* don't buffer, so output is not lost if a test causes a segv etc */
+ setbuf (stdout, NULL);
+ setbuf (stderr, NULL);
+
+ tests_memory_start ();
+ tests_rand_start ();
+}
+void
+tests_end (void)
+{
+ tests_rand_end ();
+ tests_memory_end ();
+}
+
+
+void
+tests_rand_start (void)
+{
+ gmp_randstate_ptr rands;
+ char *perform_seed;
+ unsigned long seed;
+
+ if (__gmp_rands_initialized)
+ {
+ printf ("Please let tests_start() initialize the global __gmp_rands.\n");
+ printf ("ie. ensure that function is called before the first use of RANDS.\n");
+ abort ();
+ }
+
+ gmp_randinit_default (__gmp_rands);
+ __gmp_rands_initialized = 1;
+ rands = __gmp_rands;
+
+ perform_seed = getenv ("GMP_CHECK_RANDOMIZE");
+ if (perform_seed != NULL)
+ {
+#ifdef HAVE_STRTOUL
+ seed = strtoul (perform_seed, 0, 0);
+#else
+ /* This will not work right for seeds >= 2^31 on 64-bit machines.
+ Perhaps use atol unconditionally? Is that ubiquitous? */
+ seed = atoi (perform_seed);
+#endif
+ if (! (seed == 0 || seed == 1))
+ {
+ printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed);
+ gmp_randseed_ui (rands, seed);
+ }
+ else
+ {
+#if HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ seed = tv.tv_sec ^ (tv.tv_usec << 12);
+ seed &= 0xffffffff;
+#else
+ time_t tv;
+ time (&tv);
+ seed = tv;
+#endif
+ gmp_randseed_ui (rands, seed);
+ printf ("Seed GMP_CHECK_RANDOMIZE=%lu (include this in bug reports)\n", seed);
+ }
+ fflush (stdout);
+ }
+}
+void
+tests_rand_end (void)
+{
+ RANDS_CLEAR ();
+}
+
+
+/* Only used if CPU calling conventions checking is available. */
+mp_limb_t (*calling_conventions_function) (ANYARGS);
+
+
+/* Return p advanced to the next multiple of "align" bytes. "align" must be
+ a power of 2. Care is taken not to assume sizeof(int)==sizeof(pointer).
+ Using "unsigned long" avoids a warning on hpux. */
+void *
+align_pointer (void *p, size_t align)
+{
+ gmp_intptr_t d;
+ d = ((gmp_intptr_t) p) & (align-1);
+ d = (d != 0 ? align-d : 0);
+ return (void *) (((char *) p) + d);
+}
+
+
+/* Note that memory allocated with this function can never be freed, because
+ the start address of the block allocated is lost. */
+void *
+__gmp_allocate_func_aligned (size_t bytes, size_t align)
+{
+ return align_pointer ((*__gmp_allocate_func) (bytes + align-1), align);
+}
+
+
+void *
+__gmp_allocate_or_reallocate (void *ptr, size_t oldsize, size_t newsize)
+{
+ if (ptr == NULL)
+ return (*__gmp_allocate_func) (newsize);
+ else
+ return (*__gmp_reallocate_func) (ptr, oldsize, newsize);
+}
+
+char *
+__gmp_allocate_strdup (const char *s)
+{
+ size_t len;
+ char *t;
+ len = strlen (s);
+ t = (char *) (*__gmp_allocate_func) (len+1);
+ memcpy (t, s, len+1);
+ return t;
+}
+
+
+char *
+strtoupper (char *s_orig)
+{
+ char *s;
+ for (s = s_orig; *s != '\0'; s++)
+ if (isascii (*s))
+ *s = toupper (*s);
+ return s_orig;
+}
+
+
+void
+mpz_set_n (mpz_ptr z, mp_srcptr p, mp_size_t size)
+{
+ ASSERT (size >= 0);
+ MPN_NORMALIZE (p, size);
+ MPZ_REALLOC (z, size);
+ MPN_COPY (PTR(z), p, size);
+ SIZ(z) = size;
+}
+
+void
+mpz_init_set_n (mpz_ptr z, mp_srcptr p, mp_size_t size)
+{
+ ASSERT (size >= 0);
+
+ MPN_NORMALIZE (p, size);
+ ALLOC(z) = MAX (size, 1);
+ PTR(z) = __GMP_ALLOCATE_FUNC_LIMBS (ALLOC(z));
+ SIZ(z) = size;
+ MPN_COPY (PTR(z), p, size);
+}
+
+
+/* Find least significant limb position where p1,size and p2,size differ. */
+mp_size_t
+mpn_diff_lowest (mp_srcptr p1, mp_srcptr p2, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = 0; i < size; i++)
+ if (p1[i] != p2[i])
+ return i;
+
+ /* no differences */
+ return -1;
+}
+
+
+/* Find most significant limb position where p1,size and p2,size differ. */
+mp_size_t
+mpn_diff_highest (mp_srcptr p1, mp_srcptr p2, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size-1; i >= 0; i--)
+ if (p1[i] != p2[i])
+ return i;
+
+ /* no differences */
+ return -1;
+}
+
+
+/* Find least significant byte position where p1,size and p2,size differ. */
+mp_size_t
+byte_diff_lowest (const void *p1, const void *p2, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = 0; i < size; i++)
+ if (((const char *) p1)[i] != ((const char *) p2)[i])
+ return i;
+
+ /* no differences */
+ return -1;
+}
+
+
+/* Find most significant limb position where p1,size and p2,size differ. */
+mp_size_t
+byte_diff_highest (const void *p1, const void *p2, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size-1; i >= 0; i--)
+ if (((const char *) p1)[i] != ((const char *) p2)[i])
+ return i;
+
+ /* no differences */
+ return -1;
+}
+
+
+void
+mpz_set_str_or_abort (mpz_ptr z, const char *str, int base)
+{
+ if (mpz_set_str (z, str, base) != 0)
+ {
+ fprintf (stderr, "ERROR: mpz_set_str failed\n");
+ fprintf (stderr, " str = \"%s\"\n", str);
+ fprintf (stderr, " base = %d\n", base);
+ abort();
+ }
+}
+
+void
+mpq_set_str_or_abort (mpq_ptr q, const char *str, int base)
+{
+ if (mpq_set_str (q, str, base) != 0)
+ {
+ fprintf (stderr, "ERROR: mpq_set_str failed\n");
+ fprintf (stderr, " str = \"%s\"\n", str);
+ fprintf (stderr, " base = %d\n", base);
+ abort();
+ }
+}
+
+void
+mpf_set_str_or_abort (mpf_ptr f, const char *str, int base)
+{
+ if (mpf_set_str (f, str, base) != 0)
+ {
+ fprintf (stderr, "ERROR mpf_set_str failed\n");
+ fprintf (stderr, " str = \"%s\"\n", str);
+ fprintf (stderr, " base = %d\n", base);
+ abort();
+ }
+}
+
+
+/* Whether the absolute value of z is a power of 2. */
+int
+mpz_pow2abs_p (mpz_srcptr z)
+{
+ mp_size_t size, i;
+ mp_srcptr ptr;
+
+ size = SIZ (z);
+ if (size == 0)
+ return 0; /* zero is not a power of 2 */
+ size = ABS (size);
+
+ ptr = PTR (z);
+ for (i = 0; i < size-1; i++)
+ if (ptr[i] != 0)
+ return 0; /* non-zero low limb means not a power of 2 */
+
+ return POW2_P (ptr[i]); /* high limb power of 2 */
+}
+
+
+/* Exponentially distributed between 0 and 2^nbits-1, meaning the number of
+ bits in the result is uniformly distributed between 0 and nbits-1.
+
+ FIXME: This is not a proper exponential distribution, since the
+ probability function will have a stepped shape due to using a uniform
+ distribution after choosing how many bits. */
+
+void
+mpz_erandomb (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
+{
+ mpz_urandomb (rop, rstate, gmp_urandomm_ui (rstate, nbits));
+}
+
+void
+mpz_erandomb_nonzero (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
+{
+ mpz_erandomb (rop, rstate, nbits);
+ if (mpz_sgn (rop) == 0)
+ mpz_set_ui (rop, 1L);
+}
+
+void
+mpz_errandomb (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
+{
+ mpz_rrandomb (rop, rstate, gmp_urandomm_ui (rstate, nbits));
+}
+
+void
+mpz_errandomb_nonzero (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
+{
+ mpz_errandomb (rop, rstate, nbits);
+ if (mpz_sgn (rop) == 0)
+ mpz_set_ui (rop, 1L);
+}
+
+void
+mpz_negrandom (mpz_ptr rop, gmp_randstate_t rstate)
+{
+ mp_limb_t n;
+ _gmp_rand (&n, rstate, 1);
+ if (n != 0)
+ mpz_neg (rop, rop);
+}
+
+mp_limb_t
+urandom (void)
+{
+#if GMP_NAIL_BITS == 0
+ mp_limb_t n;
+ _gmp_rand (&n, RANDS, GMP_LIMB_BITS);
+ return n;
+#else
+ mp_limb_t n[2];
+ _gmp_rand (n, RANDS, GMP_LIMB_BITS);
+ return n[0] + (n[1] << GMP_NUMB_BITS);
+#endif
+}
+
+
+/* Call (*func)() with various random number generators. */
+void
+call_rand_algs (void (*func) (const char *, gmp_randstate_ptr))
+{
+ gmp_randstate_t rstate;
+ mpz_t a;
+
+ mpz_init (a);
+
+ gmp_randinit_default (rstate);
+ (*func) ("gmp_randinit_default", rstate);
+ gmp_randclear (rstate);
+
+ gmp_randinit_mt (rstate);
+ (*func) ("gmp_randinit_mt", rstate);
+ gmp_randclear (rstate);
+
+ gmp_randinit_lc_2exp_size (rstate, 8L);
+ (*func) ("gmp_randinit_lc_2exp_size 8", rstate);
+ gmp_randclear (rstate);
+
+ gmp_randinit_lc_2exp_size (rstate, 16L);
+ (*func) ("gmp_randinit_lc_2exp_size 16", rstate);
+ gmp_randclear (rstate);
+
+ gmp_randinit_lc_2exp_size (rstate, 128L);
+ (*func) ("gmp_randinit_lc_2exp_size 128", rstate);
+ gmp_randclear (rstate);
+
+ /* degenerate always zeros */
+ mpz_set_ui (a, 0L);
+ gmp_randinit_lc_2exp (rstate, a, 0L, 8L);
+ (*func) ("gmp_randinit_lc_2exp a=0 c=0 m=8", rstate);
+ gmp_randclear (rstate);
+
+ /* degenerate always FFs */
+ mpz_set_ui (a, 0L);
+ gmp_randinit_lc_2exp (rstate, a, 0xFFL, 8L);
+ (*func) ("gmp_randinit_lc_2exp a=0 c=0xFF m=8", rstate);
+ gmp_randclear (rstate);
+
+ mpz_clear (a);
+}
+
+
+/* Return +infinity if available, or 0 if not.
+ We don't want to use libm, so INFINITY or other system values are not
+ used here. */
+double
+tests_infinity_d (void)
+{
+#if _GMP_IEEE_FLOATS
+ union ieee_double_extract x;
+ x.s.exp = 2047;
+ x.s.manl = 0;
+ x.s.manh = 0;
+ x.s.sig = 0;
+ return x.d;
+#else
+ return 0;
+#endif
+}
+
+
+/* Return non-zero if d is an infinity (either positive or negative).
+ Don't want libm, so don't use isinf() or other system tests. */
+int
+tests_isinf (double d)
+{
+#if _GMP_IEEE_FLOATS
+ union ieee_double_extract x;
+ x.d = d;
+ return (x.s.exp == 2047 && x.s.manl == 0 && x.s.manh == 0);
+#else
+ return 0;
+#endif
+}
+
+
+/* Set the hardware floating point rounding mode. Same mode values as mpfr,
+ namely 0=nearest, 1=tozero, 2=up, 3=down. Return 1 if successful, 0 if
+ not. */
+int
+tests_hardware_setround (int mode)
+{
+#if WANT_ASSEMBLY && HAVE_HOST_CPU_FAMILY_x86
+ int rc;
+ switch (mode) {
+ case 0: rc = 0; break; /* nearest */
+ case 1: rc = 3; break; /* tozero */
+ case 2: rc = 2; break; /* up */
+ case 3: rc = 1; break; /* down */
+ default:
+ return 0;
+ }
+ x86_fldcw ((x86_fstcw () & ~0xC00) | (rc << 10));
+ return 1;
+#endif
+
+ return 0;
+}
+
+/* Return the hardware floating point rounding mode, or -1 if unknown. */
+int
+tests_hardware_getround (void)
+{
+#if WANT_ASSEMBLY && HAVE_HOST_CPU_FAMILY_x86
+ switch ((x86_fstcw () & ~0xC00) >> 10) {
+ case 0: return 0; break; /* nearest */
+ case 1: return 3; break; /* down */
+ case 2: return 2; break; /* up */
+ case 3: return 1; break; /* tozero */
+ }
+#endif
+
+ return -1;
+}
+
+
+/* tests_dbl_mant_bits() determines by experiment the number of bits in the
+ mantissa of a "double". If it's not possible to find a value (perhaps
+ due to the compiler optimizing too aggressively), then return 0.
+
+ This code is used rather than DBL_MANT_DIG from <float.h> since ancient
+ systems like SunOS don't have that file, and since one GNU/Linux ARM
+ system was seen where the float emulation seemed to have only 32 working
+ bits, not the 53 float.h claimed. */
+
+int
+tests_dbl_mant_bits (void)
+{
+ static int n = -1;
+ volatile double x, y, d;
+
+ if (n != -1)
+ return n;
+
+ n = 1;
+ x = 2.0;
+ for (;;)
+ {
+ /* see if 2^(n+1)+1 can be formed without rounding, if so then
+ continue, if not then "n" is the answer */
+ y = x + 1.0;
+ d = y - x;
+ if (d != 1.0)
+ {
+#if defined (DBL_MANT_DIG) && DBL_RADIX == 2
+ if (n != DBL_MANT_DIG)
+ printf ("Warning, tests_dbl_mant_bits got %d but DBL_MANT_DIG says %d\n", n, DBL_MANT_DIG);
+#endif
+ break;
+ }
+
+ x *= 2;
+ n++;
+
+ if (n > 1000)
+ {
+ printf ("Oops, tests_dbl_mant_bits can't determine mantissa size\n");
+ n = 0;
+ break;
+ }
+ }
+ return n;
+}
+
+
+/* See tests_setjmp_sigfpe in tests.h. */
+
+jmp_buf tests_sigfpe_target;
+
+RETSIGTYPE
+tests_sigfpe_handler (int sig)
+{
+ longjmp (tests_sigfpe_target, 1);
+}
+
+void
+tests_sigfpe_done (void)
+{
+ signal (SIGFPE, SIG_DFL);
+}
diff --git a/gmp/tests/misc/Makefile.am b/gmp/tests/misc/Makefile.am
new file mode 100644
index 0000000000..24f8767349
--- /dev/null
+++ b/gmp/tests/misc/Makefile.am
@@ -0,0 +1,33 @@
+## Process this file with automake to generate Makefile.in
+
+# 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/.
+
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+
+check_PROGRAMS = t-printf t-scanf t-locale
+TESTS = $(check_PROGRAMS)
+
+# Temporary files used by the tests. Removed automatically if the tests
+# pass, but ensure they're cleaned if they fail.
+#
+CLEANFILES = *.tmp
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
diff --git a/gmp/tests/misc/Makefile.in b/gmp/tests/misc/Makefile.in
new file mode 100644
index 0000000000..07ff68475a
--- /dev/null
+++ b/gmp/tests/misc/Makefile.in
@@ -0,0 +1,665 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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, 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/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+check_PROGRAMS = t-printf$(EXEEXT) t-scanf$(EXEEXT) t-locale$(EXEEXT)
+subdir = tests/misc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+t_locale_SOURCES = t-locale.c
+t_locale_OBJECTS = t-locale.$(OBJEXT)
+t_locale_LDADD = $(LDADD)
+t_locale_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_printf_SOURCES = t-printf.c
+t_printf_OBJECTS = t-printf.$(OBJEXT)
+t_printf_LDADD = $(LDADD)
+t_printf_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_scanf_SOURCES = t-scanf.c
+t_scanf_OBJECTS = t-scanf.$(OBJEXT)
+t_scanf_LDADD = $(LDADD)
+t_scanf_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = t-locale.c t-printf.c t-scanf.c
+DIST_SOURCES = t-locale.c t-printf.c t-scanf.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+TESTS = $(check_PROGRAMS)
+
+# Temporary files used by the tests. Removed automatically if the tests
+# pass, but ensure they're cleaned if they fail.
+#
+CLEANFILES = *.tmp
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/misc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps tests/misc/Makefile
+.PRECIOUS: 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-locale$(EXEEXT): $(t_locale_OBJECTS) $(t_locale_DEPENDENCIES) $(EXTRA_t_locale_DEPENDENCIES)
+ @rm -f t-locale$(EXEEXT)
+ $(LINK) $(t_locale_OBJECTS) $(t_locale_LDADD) $(LIBS)
+t-printf$(EXEEXT): $(t_printf_OBJECTS) $(t_printf_DEPENDENCIES) $(EXTRA_t_printf_DEPENDENCIES)
+ @rm -f t-printf$(EXEEXT)
+ $(LINK) $(t_printf_OBJECTS) $(t_printf_LDADD) $(LIBS)
+t-scanf$(EXEEXT): $(t_scanf_OBJECTS) $(t_scanf_DEPENDENCIES) $(EXTRA_t_scanf_DEPENDENCIES)
+ @rm -f t-scanf$(EXEEXT)
+ $(LINK) $(t_scanf_OBJECTS) $(t_scanf_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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 all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool ctags \
+ 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 \
+ tags uninstall uninstall-am
+
+
+$(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/gmp/tests/misc/t-locale.c b/gmp/tests/misc/t-locale.c
new file mode 100644
index 0000000000..5979e27955
--- /dev/null
+++ b/gmp/tests/misc/t-locale.c
@@ -0,0 +1,201 @@
+/* Test locale support, or attempt to do so.
+
+Copyright 2001, 2002, 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/. */
+
+#define _GNU_SOURCE /* for DECIMAL_POINT in glibc langinfo.h */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_NL_TYPES_H
+#include <nl_types.h> /* for nl_item (on netbsd 1.4.1 at least) */
+#endif
+
+#if HAVE_LANGINFO_H
+#include <langinfo.h> /* for nl_langinfo */
+#endif
+
+#if HAVE_LOCALE_H
+#include <locale.h> /* for lconv */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifdef __MINGW32__
+int
+main (void)
+{
+ exit (0);
+}
+#else
+
+const char *decimal_point;
+
+/* Replace the libc localeconv with one we can manipulate. */
+#if HAVE_LOCALECONV
+struct lconv *
+localeconv (void)
+{
+ static struct lconv l;
+ l.decimal_point = (char *) decimal_point;
+ return &l;
+}
+#endif
+
+/* Replace the libc nl_langinfo with one we can manipulate. */
+#if HAVE_NL_LANGINFO
+char *
+nl_langinfo (nl_item n)
+{
+#if defined (DECIMAL_POINT)
+ if (n == DECIMAL_POINT)
+ return (char *) decimal_point;
+#endif
+#if defined (RADIXCHAR)
+ if (n == RADIXCHAR)
+ return (char *) decimal_point;
+#endif
+ return (char *) "";
+}
+#endif
+
+void
+check_input (void)
+{
+ static const char *point[] = {
+ ".", ",", "WU", "STR", "ZTV***"
+ };
+
+ static const struct {
+ const char *str;
+ double d;
+ } data[] = {
+
+ { "1%s", 1.0 },
+ { "1%s0", 1.0 },
+ { "1%s00", 1.0 },
+
+ { "%s5", 0.5 },
+ { "0%s5", 0.5 },
+ { "00%s5", 0.5 },
+ { "00%s50", 0.5 },
+
+ { "1%s5", 1.5 },
+ { "1%s5e1", 15.0 },
+ };
+
+ int i, j, neg, ret;
+ char str[128];
+ mpf_t f;
+ double d;
+
+ mpf_init (f);
+
+ for (i = 0; i < numberof (point); i++)
+ {
+ decimal_point = (const char *) point[i];
+
+ for (neg = 0; neg <= 1; neg++)
+ {
+ for (j = 0; j < numberof (data); j++)
+ {
+ strcpy (str, neg ? "-" : "");
+ sprintf (str+strlen(str), data[j].str, decimal_point);
+
+ d = data[j].d;
+ if (neg)
+ d = -d;
+
+ mpf_set_d (f, 123.0);
+ if (mpf_set_str (f, str, 10) != 0)
+ {
+ printf ("mpf_set_str error\n");
+ printf (" point %s\n", decimal_point);
+ printf (" str %s\n", str);
+ abort ();
+ }
+ if (mpf_cmp_d (f, d) != 0)
+ {
+ printf ("mpf_set_str wrong result\n");
+ printf (" point %s\n", decimal_point);
+ printf (" str %s\n", str);
+ mpf_trace (" f", f);
+ printf (" d=%g\n", d);
+ abort ();
+ }
+
+ mpf_set_d (f, 123.0);
+ ret = gmp_sscanf (str, "%Ff", f);
+ if (ret != 1)
+ {
+ printf ("gmp_sscanf wrong return value\n");
+ printf (" point %s\n", decimal_point);
+ printf (" str %s\n", str);
+ printf (" ret %d\n", ret);
+ abort ();
+ }
+ if (mpf_cmp_d (f, d) != 0)
+ {
+ printf ("gmp_sscanf wrong result\n");
+ printf (" point %s\n", decimal_point);
+ printf (" str %s\n", str);
+ mpf_trace (" f", f);
+ printf (" d=%g\n", d);
+ abort ();
+ }
+ }
+ }
+ }
+ mpf_clear (f);
+}
+
+int
+main (void)
+{
+ /* The localeconv replacement breaks printf "%lu" on SunOS 4, so we can't
+ print the seed in tests_rand_start(). Nothing random is used in this
+ program though, so just use the memory tests alone. */
+ tests_memory_start ();
+
+ {
+ mpf_t f;
+ char buf[128];
+ mpf_init (f);
+ decimal_point = ",";
+ mpf_set_d (f, 1.5);
+ gmp_snprintf (buf, sizeof(buf), "%.1Ff", f);
+ mpf_clear (f);
+ if (strcmp (buf, "1,5") != 0)
+ {
+ printf ("Test skipped, replacing localeconv/nl_langinfo doesn't work\n");
+ goto done;
+ }
+ }
+
+ check_input ();
+
+ done:
+ tests_memory_end ();
+ exit (0);
+}
+#endif
diff --git a/gmp/tests/misc/t-printf.c b/gmp/tests/misc/t-printf.c
new file mode 100644
index 0000000000..8853dcc0ff
--- /dev/null
+++ b/gmp/tests/misc/t-printf.c
@@ -0,0 +1,948 @@
+/* Test gmp_printf and related functions.
+
+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/. */
+
+
+/* Usage: t-printf [-s]
+
+ -s Check the data against the system printf, where possible. This is
+ only an option since we don't want to fail if the system printf is
+ faulty or strange. */
+
+
+#include "config.h" /* needed for the HAVE_, could also move gmp incls */
+
+#include <stdarg.h>
+#include <stddef.h> /* for ptrdiff_t */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_OBSTACK_VPRINTF
+#define obstack_chunk_alloc tests_allocate
+#define obstack_chunk_free tests_free_nosize
+#include <obstack.h>
+#endif
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h> /* for intmax_t */
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for unlink */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+int option_check_printf = 0;
+
+
+#define CHECK_VFPRINTF_FILENAME "t-printf.tmp"
+FILE *check_vfprintf_fp;
+
+
+/* From any of the tests run here. */
+#define MAX_OUTPUT 1024
+
+
+void
+check_plain (const char *want, const char *fmt_orig, ...)
+{
+ char got[MAX_OUTPUT];
+ int got_len, want_len;
+ size_t fmtsize;
+ char *fmt, *q;
+ const char *p;
+ va_list ap;
+ va_start (ap, fmt_orig);
+
+ if (! option_check_printf)
+ return;
+
+ fmtsize = strlen (fmt_orig) + 1;
+ fmt = (char *) (*__gmp_allocate_func) (fmtsize);
+
+ for (p = fmt_orig, q = fmt; *p != '\0'; p++)
+ {
+ switch (*p) {
+ case 'a':
+ case 'A':
+ /* The exact value of the exponent isn't guaranteed in glibc, and it
+ and gmp_printf do slightly different things, so don't compare
+ directly. */
+ goto done;
+ case 'F':
+ if (p > fmt_orig && *(p-1) == '.')
+ goto done; /* don't test the "all digits" cases */
+ /* discard 'F' type */
+ break;
+ case 'Z':
+ /* transmute */
+ *q++ = 'l';
+ break;
+ default:
+ *q++ = *p;
+ break;
+ }
+ }
+ *q = '\0';
+
+ want_len = strlen (want);
+ ASSERT_ALWAYS (want_len < sizeof(got));
+
+ got_len = vsprintf (got, fmt, ap);
+
+ if (got_len != want_len || strcmp (got, want) != 0)
+ {
+ printf ("wanted data doesn't match plain vsprintf\n");
+ printf (" fmt |%s|\n", fmt);
+ printf (" got |%s|\n", got);
+ printf (" want |%s|\n", want);
+ printf (" got_len %d\n", got_len);
+ printf (" want_len %d\n", want_len);
+ abort ();
+ }
+
+ done:
+ (*__gmp_free_func) (fmt, fmtsize);
+}
+
+void
+check_vsprintf (const char *want, const char *fmt, va_list ap)
+{
+ char got[MAX_OUTPUT];
+ int got_len, want_len;
+
+ want_len = strlen (want);
+ got_len = gmp_vsprintf (got, fmt, ap);
+
+ if (got_len != want_len || strcmp (got, want) != 0)
+ {
+ printf ("gmp_vsprintf wrong\n");
+ printf (" fmt |%s|\n", fmt);
+ printf (" got |%s|\n", got);
+ printf (" want |%s|\n", want);
+ printf (" got_len %d\n", got_len);
+ printf (" want_len %d\n", want_len);
+ abort ();
+ }
+}
+
+void
+check_vfprintf (const char *want, const char *fmt, va_list ap)
+{
+ char got[MAX_OUTPUT];
+ int got_len, want_len, fread_len;
+ long ftell_len;
+
+ want_len = strlen (want);
+
+ rewind (check_vfprintf_fp);
+ got_len = gmp_vfprintf (check_vfprintf_fp, fmt, ap);
+ ASSERT_ALWAYS (got_len != -1);
+ ASSERT_ALWAYS (fflush (check_vfprintf_fp) == 0);
+
+ ftell_len = ftell (check_vfprintf_fp);
+ ASSERT_ALWAYS (ftell_len != -1);
+
+ rewind (check_vfprintf_fp);
+ ASSERT_ALWAYS (ftell_len <= sizeof(got));
+ fread_len = fread (got, 1, ftell_len, check_vfprintf_fp);
+
+ if (got_len != want_len
+ || ftell_len != want_len
+ || fread_len != want_len
+ || memcmp (got, want, want_len) != 0)
+ {
+ printf ("gmp_vfprintf wrong\n");
+ printf (" fmt |%s|\n", fmt);
+ printf (" got |%.*s|\n", fread_len, got);
+ printf (" want |%s|\n", want);
+ printf (" got_len %d\n", got_len);
+ printf (" ftell_len %ld\n", ftell_len);
+ printf (" fread_len %d\n", fread_len);
+ printf (" want_len %d\n", want_len);
+ abort ();
+ }
+}
+
+void
+check_vsnprintf (const char *want, const char *fmt, va_list ap)
+{
+ char got[MAX_OUTPUT+1];
+ int ret, got_len, want_len;
+ size_t bufsize;
+
+ want_len = strlen (want);
+
+ bufsize = -1;
+ for (;;)
+ {
+ /* do 0 to 5, then want-5 to want+5 */
+ bufsize++;
+ if (bufsize > 5 && bufsize < want_len-5)
+ bufsize = want_len-5;
+ if (bufsize > want_len + 5)
+ break;
+ ASSERT_ALWAYS (bufsize+1 <= sizeof (got));
+
+ got[bufsize] = '!';
+ ret = gmp_vsnprintf (got, bufsize, fmt, ap);
+
+ got_len = MIN (MAX(1,bufsize)-1, want_len);
+
+ if (got[bufsize] != '!')
+ {
+ printf ("gmp_vsnprintf overwrote bufsize sentinel\n");
+ goto error;
+ }
+
+ if (ret != want_len)
+ {
+ printf ("gmp_vsnprintf return value wrong\n");
+ goto error;
+ }
+
+ if (bufsize > 0)
+ {
+ if (memcmp (got, want, got_len) != 0 || got[got_len] != '\0')
+ {
+ printf ("gmp_vsnprintf wrong result string\n");
+ error:
+ printf (" fmt |%s|\n", fmt);
+ printf (" bufsize %lu\n", (unsigned long) bufsize);
+ printf (" got |%s|\n", got);
+ printf (" want |%.*s|\n", got_len, want);
+ printf (" want full |%s|\n", want);
+ printf (" ret %d\n", ret);
+ printf (" want_len %d\n", want_len);
+ abort ();
+ }
+ }
+ }
+}
+
+void
+check_vasprintf (const char *want, const char *fmt, va_list ap)
+{
+ char *got;
+ int got_len, want_len;
+
+ want_len = strlen (want);
+ got_len = gmp_vasprintf (&got, fmt, ap);
+
+ if (got_len != want_len || strcmp (got, want) != 0)
+ {
+ printf ("gmp_vasprintf wrong\n");
+ printf (" fmt |%s|\n", fmt);
+ printf (" got |%s|\n", got);
+ printf (" want |%s|\n", want);
+ printf (" got_len %d\n", got_len);
+ printf (" want_len %d\n", want_len);
+ abort ();
+ }
+ (*__gmp_free_func) (got, strlen(got)+1);
+}
+
+void
+check_obstack_vprintf (const char *want, const char *fmt, va_list ap)
+{
+#if HAVE_OBSTACK_VPRINTF
+ struct obstack ob;
+ int got_len, want_len, ob_len;
+ char *got;
+
+ want_len = strlen (want);
+
+ obstack_init (&ob);
+ got_len = gmp_obstack_vprintf (&ob, fmt, ap);
+ got = (char *) obstack_base (&ob);
+ ob_len = obstack_object_size (&ob);
+
+ if (got_len != want_len
+ || ob_len != want_len
+ || memcmp (got, want, want_len) != 0)
+ {
+ printf ("gmp_obstack_vprintf wrong\n");
+ printf (" fmt |%s|\n", fmt);
+ printf (" got |%s|\n", got);
+ printf (" want |%s|\n", want);
+ printf (" got_len %d\n", got_len);
+ printf (" ob_len %d\n", ob_len);
+ printf (" want_len %d\n", want_len);
+ abort ();
+ }
+ obstack_free (&ob, NULL);
+#endif
+}
+
+
+void
+check_one (const char *want, const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+
+ /* simplest first */
+ check_vsprintf (want, fmt, ap);
+ check_vfprintf (want, fmt, ap);
+ check_vsnprintf (want, fmt, ap);
+ check_vasprintf (want, fmt, ap);
+ check_obstack_vprintf (want, fmt, ap);
+}
+
+
+#define hex_or_octal_p(fmt) \
+ (strchr (fmt, 'x') != NULL \
+ || strchr (fmt, 'X') != NULL \
+ || strchr (fmt, 'o') != NULL)
+
+void
+check_z (void)
+{
+ static const struct {
+ const char *fmt;
+ const char *z;
+ const char *want;
+ } data[] = {
+ { "%Zd", "0", "0" },
+ { "%Zd", "1", "1" },
+ { "%Zd", "123", "123" },
+ { "%Zd", "-1", "-1" },
+ { "%Zd", "-123", "-123" },
+
+ { "%+Zd", "0", "+0" },
+ { "%+Zd", "123", "+123" },
+ { "%+Zd", "-123", "-123" },
+
+ { "%Zx", "123", "7b" },
+ { "%ZX", "123", "7B" },
+ { "%Zx", "-123", "-7b" },
+ { "%ZX", "-123", "-7B" },
+ { "%Zo", "123", "173" },
+ { "%Zo", "-123", "-173" },
+
+ { "%#Zx", "0", "0" },
+ { "%#ZX", "0", "0" },
+ { "%#Zx", "123", "0x7b" },
+ { "%#ZX", "123", "0X7B" },
+ { "%#Zx", "-123", "-0x7b" },
+ { "%#ZX", "-123", "-0X7B" },
+
+ { "%#Zo", "0", "0" },
+ { "%#Zo", "123", "0173" },
+ { "%#Zo", "-123", "-0173" },
+
+ { "%10Zd", "0", " 0" },
+ { "%10Zd", "123", " 123" },
+ { "%10Zd", "-123", " -123" },
+
+ { "%-10Zd", "0", "0 " },
+ { "%-10Zd", "123", "123 " },
+ { "%-10Zd", "-123", "-123 " },
+
+ { "%+10Zd", "123", " +123" },
+ { "%+-10Zd", "123", "+123 " },
+ { "%+10Zd", "-123", " -123" },
+ { "%+-10Zd", "-123", "-123 " },
+
+ { "%08Zd", "0", "00000000" },
+ { "%08Zd", "123", "00000123" },
+ { "%08Zd", "-123", "-0000123" },
+
+ { "%+08Zd", "0", "+0000000" },
+ { "%+08Zd", "123", "+0000123" },
+ { "%+08Zd", "-123", "-0000123" },
+
+ { "%#08Zx", "0", "00000000" },
+ { "%#08Zx", "123", "0x00007b" },
+ { "%#08Zx", "-123", "-0x0007b" },
+
+ { "%+#08Zx", "0", "+0000000" },
+ { "%+#08Zx", "123", "+0x0007b" },
+ { "%+#08Zx", "-123", "-0x0007b" },
+
+ { "%.0Zd", "0", "" },
+ { "%.1Zd", "0", "0" },
+ { "%.2Zd", "0", "00" },
+ { "%.3Zd", "0", "000" },
+ };
+
+ int i, j;
+ mpz_t z;
+ char *nfmt;
+ mp_size_t nsize, zeros;
+
+ mpz_init (z);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (z, data[i].z, 0);
+
+ /* don't try negatives or forced sign in hex or octal */
+ if (mpz_fits_slong_p (z)
+ && ! (hex_or_octal_p (data[i].fmt)
+ && (strchr (data[i].fmt, '+') != NULL || mpz_sgn(z) < 0)))
+ {
+ check_plain (data[i].want, data[i].fmt, mpz_get_si (z));
+ }
+
+ check_one (data[i].want, data[i].fmt, z);
+
+ /* Same again, with %N and possibly some high zero limbs */
+ nfmt = __gmp_allocate_strdup (data[i].fmt);
+ for (j = 0; nfmt[j] != '\0'; j++)
+ if (nfmt[j] == 'Z')
+ nfmt[j] = 'N';
+ for (zeros = 0; zeros <= 3; zeros++)
+ {
+ nsize = ABSIZ(z)+zeros;
+ MPZ_REALLOC (z, nsize);
+ nsize = (SIZ(z) >= 0 ? nsize : -nsize);
+ refmpn_zero (PTR(z)+ABSIZ(z), zeros);
+ check_one (data[i].want, nfmt, PTR(z), nsize);
+ }
+ __gmp_free_func (nfmt, strlen(nfmt)+1);
+ }
+
+ mpz_clear (z);
+}
+
+void
+check_q (void)
+{
+ static const struct {
+ const char *fmt;
+ const char *q;
+ const char *want;
+ } data[] = {
+ { "%Qd", "0", "0" },
+ { "%Qd", "1", "1" },
+ { "%Qd", "123", "123" },
+ { "%Qd", "-1", "-1" },
+ { "%Qd", "-123", "-123" },
+ { "%Qd", "3/2", "3/2" },
+ { "%Qd", "-3/2", "-3/2" },
+
+ { "%+Qd", "0", "+0" },
+ { "%+Qd", "123", "+123" },
+ { "%+Qd", "-123", "-123" },
+ { "%+Qd", "5/8", "+5/8" },
+ { "%+Qd", "-5/8", "-5/8" },
+
+ { "%Qx", "123", "7b" },
+ { "%QX", "123", "7B" },
+ { "%Qx", "15/16", "f/10" },
+ { "%QX", "15/16", "F/10" },
+ { "%Qx", "-123", "-7b" },
+ { "%QX", "-123", "-7B" },
+ { "%Qx", "-15/16", "-f/10" },
+ { "%QX", "-15/16", "-F/10" },
+ { "%Qo", "123", "173" },
+ { "%Qo", "-123", "-173" },
+ { "%Qo", "16/17", "20/21" },
+ { "%Qo", "-16/17", "-20/21" },
+
+ { "%#Qx", "0", "0" },
+ { "%#QX", "0", "0" },
+ { "%#Qx", "123", "0x7b" },
+ { "%#QX", "123", "0X7B" },
+ { "%#Qx", "5/8", "0x5/0x8" },
+ { "%#QX", "5/8", "0X5/0X8" },
+ { "%#Qx", "-123", "-0x7b" },
+ { "%#QX", "-123", "-0X7B" },
+ { "%#Qx", "-5/8", "-0x5/0x8" },
+ { "%#QX", "-5/8", "-0X5/0X8" },
+ { "%#Qo", "0", "0" },
+ { "%#Qo", "123", "0173" },
+ { "%#Qo", "-123", "-0173" },
+ { "%#Qo", "5/7", "05/07" },
+ { "%#Qo", "-5/7", "-05/07" },
+
+ /* zero denominator and showbase */
+ { "%#10Qo", "0/0", " 0/0" },
+ { "%#10Qd", "0/0", " 0/0" },
+ { "%#10Qx", "0/0", " 0/0" },
+ { "%#10Qo", "123/0", " 0173/0" },
+ { "%#10Qd", "123/0", " 123/0" },
+ { "%#10Qx", "123/0", " 0x7b/0" },
+ { "%#10QX", "123/0", " 0X7B/0" },
+ { "%#10Qo", "-123/0", " -0173/0" },
+ { "%#10Qd", "-123/0", " -123/0" },
+ { "%#10Qx", "-123/0", " -0x7b/0" },
+ { "%#10QX", "-123/0", " -0X7B/0" },
+
+ { "%10Qd", "0", " 0" },
+ { "%-10Qd", "0", "0 " },
+ { "%10Qd", "123", " 123" },
+ { "%-10Qd", "123", "123 " },
+ { "%10Qd", "-123", " -123" },
+ { "%-10Qd", "-123", "-123 " },
+
+ { "%+10Qd", "123", " +123" },
+ { "%+-10Qd", "123", "+123 " },
+ { "%+10Qd", "-123", " -123" },
+ { "%+-10Qd", "-123", "-123 " },
+
+ { "%08Qd", "0", "00000000" },
+ { "%08Qd", "123", "00000123" },
+ { "%08Qd", "-123", "-0000123" },
+
+ { "%+08Qd", "0", "+0000000" },
+ { "%+08Qd", "123", "+0000123" },
+ { "%+08Qd", "-123", "-0000123" },
+
+ { "%#08Qx", "0", "00000000" },
+ { "%#08Qx", "123", "0x00007b" },
+ { "%#08Qx", "-123", "-0x0007b" },
+
+ { "%+#08Qx", "0", "+0000000" },
+ { "%+#08Qx", "123", "+0x0007b" },
+ { "%+#08Qx", "-123", "-0x0007b" },
+ };
+
+ int i;
+ mpq_t q;
+
+ mpq_init (q);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpq_set_str_or_abort (q, data[i].q, 0);
+ check_one (data[i].want, data[i].fmt, q);
+ }
+
+ mpq_clear (q);
+}
+
+void
+check_f (void)
+{
+ static const struct {
+ const char *fmt;
+ const char *f;
+ const char *want;
+
+ } data[] = {
+
+ { "%Ff", "0", "0.000000" },
+ { "%Ff", "123", "123.000000" },
+ { "%Ff", "-123", "-123.000000" },
+
+ { "%+Ff", "0", "+0.000000" },
+ { "%+Ff", "123", "+123.000000" },
+ { "%+Ff", "-123", "-123.000000" },
+
+ { "%.0Ff", "0", "0" },
+ { "%.0Ff", "123", "123" },
+ { "%.0Ff", "-123", "-123" },
+
+ { "%8.0Ff", "0", " 0" },
+ { "%8.0Ff", "123", " 123" },
+ { "%8.0Ff", "-123", " -123" },
+
+ { "%08.0Ff", "0", "00000000" },
+ { "%08.0Ff", "123", "00000123" },
+ { "%08.0Ff", "-123", "-0000123" },
+
+ { "%10.2Ff", "0", " 0.00" },
+ { "%10.2Ff", "0.25", " 0.25" },
+ { "%10.2Ff", "123.25", " 123.25" },
+ { "%10.2Ff", "-123.25", " -123.25" },
+
+ { "%-10.2Ff", "0", "0.00 " },
+ { "%-10.2Ff", "0.25", "0.25 " },
+ { "%-10.2Ff", "123.25", "123.25 " },
+ { "%-10.2Ff", "-123.25", "-123.25 " },
+
+ { "%.2Ff", "0.00000000000001", "0.00" },
+ { "%.2Ff", "0.002", "0.00" },
+ { "%.2Ff", "0.008", "0.01" },
+
+ { "%.0Ff", "123.00000000000001", "123" },
+ { "%.0Ff", "123.2", "123" },
+ { "%.0Ff", "123.8", "124" },
+
+ { "%.0Ff", "999999.9", "1000000" },
+ { "%.0Ff", "3999999.9", "4000000" },
+
+ { "%Fe", "0", "0.000000e+00" },
+ { "%Fe", "1", "1.000000e+00" },
+ { "%Fe", "123", "1.230000e+02" },
+
+ { "%FE", "0", "0.000000E+00" },
+ { "%FE", "1", "1.000000E+00" },
+ { "%FE", "123", "1.230000E+02" },
+
+ { "%Fe", "0", "0.000000e+00" },
+ { "%Fe", "1", "1.000000e+00" },
+
+ { "%.0Fe", "10000000000", "1e+10" },
+ { "%.0Fe", "-10000000000", "-1e+10" },
+
+ { "%.2Fe", "10000000000", "1.00e+10" },
+ { "%.2Fe", "-10000000000", "-1.00e+10" },
+
+ { "%8.0Fe", "10000000000", " 1e+10" },
+ { "%8.0Fe", "-10000000000", " -1e+10" },
+
+ { "%-8.0Fe", "10000000000", "1e+10 " },
+ { "%-8.0Fe", "-10000000000", "-1e+10 " },
+
+ { "%12.2Fe", "10000000000", " 1.00e+10" },
+ { "%12.2Fe", "-10000000000", " -1.00e+10" },
+
+ { "%012.2Fe", "10000000000", "00001.00e+10" },
+ { "%012.2Fe", "-10000000000", "-0001.00e+10" },
+
+ { "%Fg", "0", "0" },
+ { "%Fg", "1", "1" },
+ { "%Fg", "-1", "-1" },
+
+ { "%.0Fg", "0", "0" },
+ { "%.0Fg", "1", "1" },
+ { "%.0Fg", "-1", "-1" },
+
+ { "%.1Fg", "100", "1e+02" },
+ { "%.2Fg", "100", "1e+02" },
+ { "%.3Fg", "100", "100" },
+ { "%.4Fg", "100", "100" },
+
+ { "%Fg", "0.001", "0.001" },
+ { "%Fg", "0.0001", "0.0001" },
+ { "%Fg", "0.00001", "1e-05" },
+ { "%Fg", "0.000001", "1e-06" },
+
+ { "%.4Fg", "1.00000000000001", "1" },
+ { "%.4Fg", "100000000000001", "1e+14" },
+
+ { "%.4Fg", "12345678", "1.235e+07" },
+
+ { "%Fa", "0","0x0p+0" },
+ { "%FA", "0","0X0P+0" },
+
+ { "%Fa", "1","0x1p+0" },
+ { "%Fa", "65535","0xf.fffp+12" },
+ { "%Fa", "65536","0x1p+16" },
+ { "%F.10a", "65536","0x1.0000000000p+16" },
+ { "%F.1a", "65535","0x1.0p+16" },
+ { "%F.0a", "65535","0x1p+16" },
+
+ { "%.2Ff", "0.99609375", "1.00" },
+ { "%.Ff", "0.99609375", "0.99609375" },
+ { "%.Fe", "0.99609375", "9.9609375e-01" },
+ { "%.Fg", "0.99609375", "0.99609375" },
+ { "%.20Fg", "1000000", "1000000" },
+ { "%.Fg", "1000000", "1000000" },
+
+ { "%#.0Ff", "1", "1." },
+ { "%#.0Fe", "1", "1.e+00" },
+ { "%#.0Fg", "1", "1." },
+
+ { "%#.1Ff", "1", "1.0" },
+ { "%#.1Fe", "1", "1.0e+00" },
+ { "%#.1Fg", "1", "1." },
+
+ { "%#.4Ff", "1234", "1234.0000" },
+ { "%#.4Fe", "1234", "1.2340e+03" },
+ { "%#.4Fg", "1234", "1234." },
+
+ { "%#.8Ff", "1234", "1234.00000000" },
+ { "%#.8Fe", "1234", "1.23400000e+03" },
+ { "%#.8Fg", "1234", "1234.0000" },
+
+ };
+
+ int i;
+ mpf_t f;
+ double d;
+
+ mpf_init2 (f, 256L);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ if (data[i].f[0] == '0' && data[i].f[1] == 'x')
+ mpf_set_str_or_abort (f, data[i].f, 16);
+ else
+ mpf_set_str_or_abort (f, data[i].f, 10);
+
+ /* if mpf->double doesn't truncate, then expect same result */
+ d = mpf_get_d (f);
+ if (mpf_cmp_d (f, d) == 0)
+ check_plain (data[i].want, data[i].fmt, d);
+
+ check_one (data[i].want, data[i].fmt, f);
+ }
+
+ mpf_clear (f);
+}
+
+
+void
+check_limb (void)
+{
+ int i;
+ mp_limb_t limb;
+ mpz_t z;
+ char *s;
+
+ check_one ("0", "%Md", CNST_LIMB(0));
+ check_one ("1", "%Md", CNST_LIMB(1));
+
+ /* "i" many 1 bits, tested against mpz_get_str in decimal and hex */
+ limb = 1;
+ mpz_init_set_ui (z, 1L);
+ for (i = 1; i <= GMP_LIMB_BITS; i++)
+ {
+ s = mpz_get_str (NULL, 10, z);
+ check_one (s, "%Mu", limb);
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ s = mpz_get_str (NULL, 16, z);
+ check_one (s, "%Mx", limb);
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ s = mpz_get_str (NULL, -16, z);
+ check_one (s, "%MX", limb);
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ limb = 2*limb + 1;
+ mpz_mul_2exp (z, z, 1L);
+ mpz_add_ui (z, z, 1L);
+ }
+
+ mpz_clear (z);
+}
+
+
+void
+check_n (void)
+{
+ {
+ int n = -1;
+ check_one ("blah", "%nblah", &n);
+ ASSERT_ALWAYS (n == 0);
+ }
+
+ {
+ int n = -1;
+ check_one ("hello ", "hello %n", &n);
+ ASSERT_ALWAYS (n == 6);
+ }
+
+ {
+ int n = -1;
+ check_one ("hello world", "hello %n world", &n);
+ ASSERT_ALWAYS (n == 6);
+ }
+
+#define CHECK_N(type, string) \
+ do { \
+ type x[2]; \
+ char fmt[128]; \
+ \
+ x[0] = ~ (type) 0; \
+ x[1] = ~ (type) 0; \
+ sprintf (fmt, "%%d%%%sn%%d", string); \
+ check_one ("123456", fmt, 123, &x[0], 456); \
+ \
+ /* should write whole of x[0] and none of x[1] */ \
+ ASSERT_ALWAYS (x[0] == 3); \
+ ASSERT_ALWAYS (x[1] == (type) ~ (type) 0); \
+ \
+ } while (0)
+
+ CHECK_N (mp_limb_t, "M");
+ CHECK_N (char, "hh");
+ CHECK_N (long, "l");
+#if HAVE_LONG_LONG
+ CHECK_N (long long, "L");
+#endif
+#if HAVE_INTMAX_T
+ CHECK_N (intmax_t, "j");
+#endif
+#if HAVE_PTRDIFF_T
+ CHECK_N (ptrdiff_t, "t");
+#endif
+ CHECK_N (short, "h");
+ CHECK_N (size_t, "z");
+
+ {
+ mpz_t x[2];
+ mpz_init_set_si (x[0], -987L);
+ mpz_init_set_si (x[1], 654L);
+ check_one ("123456", "%d%Zn%d", 123, x[0], 456);
+ MPZ_CHECK_FORMAT (x[0]);
+ MPZ_CHECK_FORMAT (x[1]);
+ ASSERT_ALWAYS (mpz_cmp_ui (x[0], 3L) == 0);
+ ASSERT_ALWAYS (mpz_cmp_ui (x[1], 654L) == 0);
+ mpz_clear (x[0]);
+ mpz_clear (x[1]);
+ }
+
+ {
+ mpq_t x[2];
+ mpq_init (x[0]);
+ mpq_init (x[1]);
+ mpq_set_ui (x[0], 987L, 654L);
+ mpq_set_ui (x[1], 4115L, 226L);
+ check_one ("123456", "%d%Qn%d", 123, x[0], 456);
+ MPQ_CHECK_FORMAT (x[0]);
+ MPQ_CHECK_FORMAT (x[1]);
+ ASSERT_ALWAYS (mpq_cmp_ui (x[0], 3L, 1L) == 0);
+ ASSERT_ALWAYS (mpq_cmp_ui (x[1], 4115L, 226L) == 0);
+ mpq_clear (x[0]);
+ mpq_clear (x[1]);
+ }
+
+ {
+ mpf_t x[2];
+ mpf_init (x[0]);
+ mpf_init (x[1]);
+ mpf_set_ui (x[0], 987L);
+ mpf_set_ui (x[1], 654L);
+ check_one ("123456", "%d%Fn%d", 123, x[0], 456);
+ MPF_CHECK_FORMAT (x[0]);
+ MPF_CHECK_FORMAT (x[1]);
+ ASSERT_ALWAYS (mpf_cmp_ui (x[0], 3L) == 0);
+ ASSERT_ALWAYS (mpf_cmp_ui (x[1], 654L) == 0);
+ mpf_clear (x[0]);
+ mpf_clear (x[1]);
+ }
+
+ {
+ mp_limb_t a[5];
+ mp_limb_t a_want[numberof(a)];
+ mp_size_t i;
+
+ a[0] = 123;
+ check_one ("blah", "bl%Nnah", a, (mp_size_t) 0);
+ ASSERT_ALWAYS (a[0] == 123);
+
+ MPN_ZERO (a_want, numberof (a_want));
+ for (i = 1; i < numberof (a); i++)
+ {
+ check_one ("blah", "bl%Nnah", a, i);
+ a_want[0] = 2;
+ ASSERT_ALWAYS (mpn_cmp (a, a_want, i) == 0);
+ }
+ }
+}
+
+
+void
+check_misc (void)
+{
+ mpz_t z;
+ mpf_t f;
+
+ mpz_init (z);
+ mpf_init2 (f, 128L);
+
+ check_one ("!", "%c", '!');
+
+ check_one ("hello world", "hello %s", "world");
+ check_one ("hello:", "%s:", "hello");
+ mpz_set_ui (z, 0L);
+ check_one ("hello0", "%s%Zd", "hello", z, z);
+
+ {
+ static char xs[801];
+ memset (xs, 'x', sizeof(xs)-1);
+ check_one (xs, "%s", xs);
+ }
+
+ mpz_set_ui (z, 12345L);
+ check_one (" 12345", "%*Zd", 10, z);
+ check_one ("0000012345", "%0*Zd", 10, z);
+ check_one ("12345 ", "%*Zd", -10, z);
+ check_one ("12345 and 678", "%Zd and %d", z, 678);
+ check_one ("12345,1,12345,2,12345", "%Zd,%d,%Zd,%d,%Zd", z, 1, z, 2, z);
+
+ /* from the glibc info docs */
+ mpz_set_si (z, 0L);
+ check_one ("| 0|0 | +0|+0 | 0|00000| | 00|0|",
+ "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
+ /**/ z, z, z, z, z, z, z, z, z);
+ mpz_set_si (z, 1L);
+ check_one ("| 1|1 | +1|+1 | 1|00001| 1| 01|1|",
+ "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
+ /**/ z, z, z, z, z, z, z, z, z);
+ mpz_set_si (z, -1L);
+ check_one ("| -1|-1 | -1|-1 | -1|-0001| -1| -01|-1|",
+ "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
+ /**/ z, z, z, z, z, z, z, z, z);
+ mpz_set_si (z, 100000L);
+ check_one ("|100000|100000|+100000|+100000| 100000|100000|100000|100000|100000|",
+ "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
+ /**/ z, z, z, z, z, z, z, z, z);
+ mpz_set_si (z, 0L);
+ check_one ("| 0| 0| 0| 0| 0| 0| 00000000|",
+ "|%5Zo|%5Zx|%5ZX|%#5Zo|%#5Zx|%#5ZX|%#10.8Zx|",
+ /**/ z, z, z, z, z, z, z);
+ mpz_set_si (z, 1L);
+ check_one ("| 1| 1| 1| 01| 0x1| 0X1|0x00000001|",
+ "|%5Zo|%5Zx|%5ZX|%#5Zo|%#5Zx|%#5ZX|%#10.8Zx|",
+ /**/ z, z, z, z, z, z, z);
+ mpz_set_si (z, 100000L);
+ check_one ("|303240|186a0|186A0|0303240|0x186a0|0X186A0|0x000186a0|",
+ "|%5Zo|%5Zx|%5ZX|%#5Zo|%#5Zx|%#5ZX|%#10.8Zx|",
+ /**/ z, z, z, z, z, z, z);
+
+ /* %zd for size_t won't be available on old systems, and running something
+ to see if it works might be bad, so only try it on glibc, and only on a
+ new enough version (glibc 2.0 doesn't have %zd) */
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0)
+ mpz_set_ui (z, 789L);
+ check_one ("456 789 blah", "%zd %Zd blah", (size_t) 456, z);
+#endif
+
+ mpz_clear (z);
+ mpf_clear (f);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (argc > 1 && strcmp (argv[1], "-s") == 0)
+ option_check_printf = 1;
+
+ tests_start ();
+ check_vfprintf_fp = fopen (CHECK_VFPRINTF_FILENAME, "w+");
+ ASSERT_ALWAYS (check_vfprintf_fp != NULL);
+
+ check_z ();
+ check_q ();
+ check_f ();
+ check_limb ();
+ check_n ();
+ check_misc ();
+
+ ASSERT_ALWAYS (fclose (check_vfprintf_fp) == 0);
+ unlink (CHECK_VFPRINTF_FILENAME);
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/misc/t-scanf.c b/gmp/tests/misc/t-scanf.c
new file mode 100644
index 0000000000..46c0a5f77c
--- /dev/null
+++ b/gmp/tests/misc/t-scanf.c
@@ -0,0 +1,1616 @@
+/* Test gmp_scanf and related functions.
+
+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/. */
+
+
+/* Usage: t-scanf [-s]
+
+ -s Check the data against the system scanf, where possible. This is
+ only an option since we don't want to fail if the system scanf is
+ faulty or strange.
+
+ There's some fairly unattractive repetition between check_z, check_q and
+ check_f, but enough differences to make a common loop or a set of macros
+ seem like too much trouble. */
+
+
+#include <stdarg.h>
+
+#include <stddef.h> /* for ptrdiff_t */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h> /* for intmax_t */
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for unlink */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#define TEMPFILE "t-scanf.tmp"
+
+int option_libc_scanf = 0;
+
+typedef int (*fun_t) (const char *, const char *, void *, void *);
+
+
+/* This problem was seen on powerpc7450-apple-darwin7.0.0, sscanf returns 0
+ where it should return EOF. A workaround in gmp_sscanf would be a bit
+ tedious, and since this is a rather obvious libc bug, quite likely
+ affecting other programs, we'll just suppress affected tests for now. */
+int
+test_sscanf_eof_ok (void)
+{
+ static int result = -1;
+
+ if (result == -1)
+ {
+ int x;
+ if (sscanf ("", "%d", &x) == EOF)
+ {
+ result = 1;
+ }
+ else
+ {
+ printf ("Warning, sscanf(\"\",\"%%d\",&x) doesn't return EOF.\n");
+ printf ("This affects gmp_sscanf, tests involving it will be suppressed.\n");
+ printf ("You should try to get a fix for your libc.\n");
+ result = 0;
+ }
+ }
+ return result;
+}
+
+
+/* Convert fmt from a GMP scanf format string to an equivalent for a plain
+ libc scanf, for example "%Zd" becomes "%ld". Return 1 if this succeeds,
+ 0 if it cannot (or should not) be done. */
+int
+libc_scanf_convert (char *fmt)
+{
+ char *p = fmt;
+
+ if (! option_libc_scanf)
+ return 0;
+
+ for ( ; *fmt != '\0'; fmt++)
+ {
+ switch (*fmt) {
+ case 'F':
+ case 'Q':
+ case 'Z':
+ /* transmute */
+ *p++ = 'l';
+ break;
+ default:
+ *p++ = *fmt;
+ break;
+ }
+ }
+ *p = '\0';
+ return 1;
+}
+
+
+long got_ftell;
+int fromstring_next_c;
+
+/* Call gmp_fscanf, reading the "input" string data provided. */
+int
+fromstring_gmp_fscanf (const char *input, const char *fmt, ...)
+{
+ va_list ap;
+ FILE *fp;
+ int ret;
+ va_start (ap, fmt);
+
+ fp = fopen (TEMPFILE, "w+");
+ ASSERT_ALWAYS (fp != NULL);
+ ASSERT_ALWAYS (fputs (input, fp) != EOF);
+ ASSERT_ALWAYS (fflush (fp) == 0);
+ rewind (fp);
+
+ ret = gmp_vfscanf (fp, fmt, ap);
+ got_ftell = ftell (fp);
+ ASSERT_ALWAYS (got_ftell != -1L);
+
+ fromstring_next_c = getc (fp);
+
+ ASSERT_ALWAYS (fclose (fp) == 0);
+ va_end (ap);
+ return ret;
+}
+
+
+int
+fun_gmp_sscanf (const char *input, const char *fmt, void *a1, void *a2)
+{
+ if (a2 == NULL)
+ return gmp_sscanf (input, fmt, a1);
+ else
+ return gmp_sscanf (input, fmt, a1, a2);
+}
+
+int
+fun_gmp_fscanf (const char *input, const char *fmt, void *a1, void *a2)
+{
+ if (a2 == NULL)
+ return fromstring_gmp_fscanf (input, fmt, a1);
+ else
+ return fromstring_gmp_fscanf (input, fmt, a1, a2);
+}
+
+
+int
+fun_fscanf (const char *input, const char *fmt, void *a1, void *a2)
+{
+ FILE *fp;
+ int ret;
+
+ fp = fopen (TEMPFILE, "w+");
+ ASSERT_ALWAYS (fp != NULL);
+ ASSERT_ALWAYS (fputs (input, fp) != EOF);
+ ASSERT_ALWAYS (fflush (fp) == 0);
+ rewind (fp);
+
+ if (a2 == NULL)
+ ret = fscanf (fp, fmt, a1);
+ else
+ ret = fscanf (fp, fmt, a1, a2);
+
+ got_ftell = ftell (fp);
+ ASSERT_ALWAYS (got_ftell != -1L);
+
+ fromstring_next_c = getc (fp);
+
+ ASSERT_ALWAYS (fclose (fp) == 0);
+ return ret;
+}
+
+
+/* On various old systems, for instance HP-UX 9, the C library sscanf needs
+ to be able to write into the input string. Ensure that this is possible,
+ when gcc is putting the test data into a read-only section.
+
+ Actually we ought to only need this under SSCANF_WRITABLE_INPUT from
+ configure, but it's just as easy to do it unconditionally, and in any
+ case this code is only executed under the -s option. */
+
+int
+fun_sscanf (const char *input, const char *fmt, void *a1, void *a2)
+{
+ char *input_writable;
+ size_t size;
+ int ret;
+
+ size = strlen (input) + 1;
+ input_writable = (char *) (*__gmp_allocate_func) (size);
+ memcpy (input_writable, input, size);
+
+ if (a2 == NULL)
+ ret = sscanf (input_writable, fmt, a1);
+ else
+ ret = sscanf (input_writable, fmt, a1, a2);
+
+ (*__gmp_free_func) (input_writable, size);
+ return ret;
+}
+
+
+/* whether the format string consists entirely of ignored fields */
+int
+fmt_allignore (const char *fmt)
+{
+ int saw_star = 1;
+ for ( ; *fmt != '\0'; fmt++)
+ {
+ switch (*fmt) {
+ case '%':
+ if (! saw_star)
+ return 0;
+ saw_star = 0;
+ break;
+ case '*':
+ saw_star = 1;
+ break;
+ }
+ }
+ return 1;
+}
+
+void
+check_z (void)
+{
+ static const struct {
+ const char *fmt;
+ const char *input;
+ const char *want;
+ int want_ret;
+ long want_ftell;
+ int want_upto;
+ int not_glibc;
+
+ } data[] = {
+
+ { "%Zd", "0", "0", 1, -1, -1 },
+ { "%Zd", "1", "1", 1, -1, -1 },
+ { "%Zd", "123", "123", 1, -1, -1 },
+ { "%Zd", "+0", "0", 1, -1, -1 },
+ { "%Zd", "+1", "1", 1, -1, -1 },
+ { "%Zd", "+123", "123", 1, -1, -1 },
+ { "%Zd", "-0", "0", 1, -1, -1 },
+ { "%Zd", "-1", "-1", 1, -1, -1 },
+ { "%Zd", "-123", "-123", 1, -1, -1 },
+
+ { "%Zo", "0", "0", 1, -1, -1 },
+ { "%Zo", "173", "123", 1, -1, -1 },
+ { "%Zo", "+0", "0", 1, -1, -1 },
+ { "%Zo", "+173", "123", 1, -1, -1 },
+ { "%Zo", "-0", "0", 1, -1, -1 },
+ { "%Zo", "-173", "-123", 1, -1, -1 },
+
+ { "%Zx", "0", "0", 1, -1, -1 },
+ { "%Zx", "7b", "123", 1, -1, -1 },
+ { "%Zx", "7b", "123", 1, -1, -1 },
+ { "%Zx", "+0", "0", 1, -1, -1 },
+ { "%Zx", "+7b", "123", 1, -1, -1 },
+ { "%Zx", "+7b", "123", 1, -1, -1 },
+ { "%Zx", "-0", "-0", 1, -1, -1 },
+ { "%Zx", "-7b", "-123", 1, -1, -1 },
+ { "%Zx", "-7b", "-123", 1, -1, -1 },
+ { "%ZX", "0", "0", 1, -1, -1 },
+ { "%ZX", "7b", "123", 1, -1, -1 },
+ { "%ZX", "7b", "123", 1, -1, -1 },
+ { "%ZX", "+0", "0", 1, -1, -1 },
+ { "%ZX", "+7b", "123", 1, -1, -1 },
+ { "%ZX", "+7b", "123", 1, -1, -1 },
+ { "%ZX", "-0", "-0", 1, -1, -1 },
+ { "%ZX", "-7b", "-123", 1, -1, -1 },
+ { "%ZX", "-7b", "-123", 1, -1, -1 },
+ { "%Zx", "0", "0", 1, -1, -1 },
+ { "%Zx", "7B", "123", 1, -1, -1 },
+ { "%Zx", "7B", "123", 1, -1, -1 },
+ { "%Zx", "+0", "0", 1, -1, -1 },
+ { "%Zx", "+7B", "123", 1, -1, -1 },
+ { "%Zx", "+7B", "123", 1, -1, -1 },
+ { "%Zx", "-0", "-0", 1, -1, -1 },
+ { "%Zx", "-7B", "-123", 1, -1, -1 },
+ { "%Zx", "-7B", "-123", 1, -1, -1 },
+ { "%ZX", "0", "0", 1, -1, -1 },
+ { "%ZX", "7B", "123", 1, -1, -1 },
+ { "%ZX", "7B", "123", 1, -1, -1 },
+ { "%ZX", "+0", "0", 1, -1, -1 },
+ { "%ZX", "+7B", "123", 1, -1, -1 },
+ { "%ZX", "+7B", "123", 1, -1, -1 },
+ { "%ZX", "-0", "-0", 1, -1, -1 },
+ { "%ZX", "-7B", "-123", 1, -1, -1 },
+ { "%ZX", "-7B", "-123", 1, -1, -1 },
+
+ { "%Zi", "0", "0", 1, -1, -1 },
+ { "%Zi", "1", "1", 1, -1, -1 },
+ { "%Zi", "123", "123", 1, -1, -1 },
+ { "%Zi", "+0", "0", 1, -1, -1 },
+ { "%Zi", "+1", "1", 1, -1, -1 },
+ { "%Zi", "+123", "123", 1, -1, -1 },
+ { "%Zi", "-0", "0", 1, -1, -1 },
+ { "%Zi", "-1", "-1", 1, -1, -1 },
+ { "%Zi", "-123", "-123", 1, -1, -1 },
+
+ { "%Zi", "00", "0", 1, -1, -1 },
+ { "%Zi", "0173", "123", 1, -1, -1 },
+ { "%Zi", "+00", "0", 1, -1, -1 },
+ { "%Zi", "+0173", "123", 1, -1, -1 },
+ { "%Zi", "-00", "0", 1, -1, -1 },
+ { "%Zi", "-0173", "-123", 1, -1, -1 },
+
+ { "%Zi", "0x0", "0", 1, -1, -1 },
+ { "%Zi", "0x7b", "123", 1, -1, -1 },
+ { "%Zi", "0x7b", "123", 1, -1, -1 },
+ { "%Zi", "+0x0", "0", 1, -1, -1 },
+ { "%Zi", "+0x7b", "123", 1, -1, -1 },
+ { "%Zi", "+0x7b", "123", 1, -1, -1 },
+ { "%Zi", "-0x0", "-0", 1, -1, -1 },
+ { "%Zi", "-0x7b", "-123", 1, -1, -1 },
+ { "%Zi", "-0x7b", "-123", 1, -1, -1 },
+ { "%Zi", "0X0", "0", 1, -1, -1 },
+ { "%Zi", "0X7b", "123", 1, -1, -1 },
+ { "%Zi", "0X7b", "123", 1, -1, -1 },
+ { "%Zi", "+0X0", "0", 1, -1, -1 },
+ { "%Zi", "+0X7b", "123", 1, -1, -1 },
+ { "%Zi", "+0X7b", "123", 1, -1, -1 },
+ { "%Zi", "-0X0", "-0", 1, -1, -1 },
+ { "%Zi", "-0X7b", "-123", 1, -1, -1 },
+ { "%Zi", "-0X7b", "-123", 1, -1, -1 },
+ { "%Zi", "0x0", "0", 1, -1, -1 },
+ { "%Zi", "0x7B", "123", 1, -1, -1 },
+ { "%Zi", "0x7B", "123", 1, -1, -1 },
+ { "%Zi", "+0x0", "0", 1, -1, -1 },
+ { "%Zi", "+0x7B", "123", 1, -1, -1 },
+ { "%Zi", "+0x7B", "123", 1, -1, -1 },
+ { "%Zi", "-0x0", "-0", 1, -1, -1 },
+ { "%Zi", "-0x7B", "-123", 1, -1, -1 },
+ { "%Zi", "-0x7B", "-123", 1, -1, -1 },
+ { "%Zi", "0X0", "0", 1, -1, -1 },
+ { "%Zi", "0X7B", "123", 1, -1, -1 },
+ { "%Zi", "0X7B", "123", 1, -1, -1 },
+ { "%Zi", "+0X0", "0", 1, -1, -1 },
+ { "%Zi", "+0X7B", "123", 1, -1, -1 },
+ { "%Zi", "+0X7B", "123", 1, -1, -1 },
+ { "%Zi", "-0X0", "-0", 1, -1, -1 },
+ { "%Zi", "-0X7B", "-123", 1, -1, -1 },
+ { "%Zi", "-0X7B", "-123", 1, -1, -1 },
+
+ { "%Zd", " 0", "0", 1, -1, -1 },
+ { "%Zd", " 0", "0", 1, -1, -1 },
+ { "%Zd", " 0", "0", 1, -1, -1 },
+ { "%Zd", "\t0", "0", 1, -1, -1 },
+ { "%Zd", "\t\t0", "0", 1, -1, -1 },
+
+ { "hello%Zd", "hello0", "0", 1, -1, -1 },
+ { "hello%Zd", "hello 0", "0", 1, -1, -1 },
+ { "hello%Zd", "hello \t0", "0", 1, -1, -1 },
+ { "hello%Zdworld", "hello 0world", "0", 1, -1, -1 },
+
+ { "hello%*Zd", "hello0", "-999", 0, -1, -1 },
+ { "hello%*Zd", "hello 0", "-999", 0, -1, -1 },
+ { "hello%*Zd", "hello \t0", "-999", 0, -1, -1 },
+ { "hello%*Zdworld", "hello 0world", "-999", 0, -1, -1 },
+
+ { "%Zd", "", "-999", -1, -1, -555 },
+ { "%Zd", " ", "-999", -1, -1, -555 },
+ { " %Zd", "", "-999", -1, -1, -555 },
+ { "xyz%Zd", "", "-999", -1, -1, -555 },
+
+ { "%*Zd", "", "-999", -1, -1, -555 },
+ { " %*Zd", "", "-999", -1, -1, -555 },
+ { "xyz%*Zd", "", "-999", -1, -1, -555 },
+
+ { "%Zd", "xyz", "0", 0, 0, -555 },
+
+ /* match something, but invalid */
+ { "%Zd", "-", "-999", 0, 1, -555 },
+ { "%Zd", "+", "-999", 0, 1, -555 },
+ { "xyz%Zd", "xyz-", "-999", 0, 4, -555 },
+ { "xyz%Zd", "xyz+", "-999", 0, 4, -555 },
+ { "%Zi", "0x", "-999", 0, 2, -555 },
+ { "%Zi", "0X", "-999", 0, 2, -555 },
+ { "%Zi", "0x-", "-999", 0, 2, -555 },
+ { "%Zi", "0X+", "-999", 0, 2, -555 },
+ { "%Zi", "-0x", "-999", 0, 3, -555 },
+ { "%Zi", "-0X", "-999", 0, 3, -555 },
+ { "%Zi", "+0x", "-999", 0, 3, -555 },
+ { "%Zi", "+0X", "-999", 0, 3, -555 },
+
+ { "%1Zi", "1234", "1", 1, 1, 1 },
+ { "%2Zi", "1234", "12", 1, 2, 2 },
+ { "%3Zi", "1234", "123", 1, 3, 3 },
+ { "%4Zi", "1234", "1234", 1, 4, 4 },
+ { "%5Zi", "1234", "1234", 1, 4, 4 },
+ { "%6Zi", "1234", "1234", 1, 4, 4 },
+
+ { "%1Zi", "01234", "0", 1, 1, 1 },
+ { "%2Zi", "01234", "01", 1, 2, 2 },
+ { "%3Zi", "01234", "012", 1, 3, 3 },
+ { "%4Zi", "01234", "0123", 1, 4, 4 },
+ { "%5Zi", "01234", "01234", 1, 5, 5 },
+ { "%6Zi", "01234", "01234", 1, 5, 5 },
+ { "%7Zi", "01234", "01234", 1, 5, 5 },
+
+ { "%1Zi", "0x1234", "0", 1, 1, 1 },
+ { "%2Zi", "0x1234", "-999", 0, 2, -555 },
+ { "%3Zi", "0x1234", "0x1", 1, 3, 3 },
+ { "%4Zi", "0x1234", "0x12", 1, 4, 4 },
+ { "%5Zi", "0x1234", "0x123", 1, 5, 5 },
+ { "%6Zi", "0x1234", "0x1234", 1, 6, 6 },
+ { "%7Zi", "0x1234", "0x1234", 1, 6, 6 },
+ { "%8Zi", "0x1234", "0x1234", 1, 6, 6 },
+
+ { "%%xyz%Zd", "%xyz123", "123", 1, -1, -1 },
+ { "12%%34%Zd", "12%34567", "567", 1, -1, -1 },
+ { "%%%%%Zd", "%%123", "123", 1, -1, -1 },
+
+ /* various subtle EOF cases */
+ { "x", "", "-999", EOF, 0, -555 },
+ { " x", "", "-999", EOF, 0, -555 },
+ { "xyz", "", "-999", EOF, 0, -555 },
+ { " ", "", "-999", 0, 0, 0 },
+ { " ", " ", "-999", 0, 1, 1 },
+ { "%*Zd%Zd", "", "-999", EOF, 0, -555 },
+ { "%*Zd%Zd", "123", "-999", EOF, 3, -555 },
+ { "x", "x", "-999", 0, 1, 1 },
+ { "xyz", "x", "-999", EOF, 1, -555 },
+ { "xyz", "xy", "-999", EOF, 2, -555 },
+ { "xyz", "xyz", "-999", 0, 3, 3 },
+ { "%Zn", "", "0", 0, 0, 0 },
+ { " %Zn", "", "0", 0, 0, 0 },
+ { " x%Zn", "", "-999", EOF, 0, -555 },
+ { "xyz%Zn", "", "-999", EOF, 0, -555 },
+ { " x%Zn", "", "-999", EOF, 0, -555 },
+ { " %Zn x", " ", "-999", EOF, 1, -555 },
+
+ /* these seem to tickle a bug in glibc 2.2.4 */
+ { " x", " ", "-999", EOF, 1, -555, 1 },
+ { " xyz", " ", "-999", EOF, 1, -555, 1 },
+ { " x%Zn", " ", "-999", EOF, 1, -555, 1 },
+ };
+
+ int i, j, ignore;
+ int got_ret, want_ret, got_upto, want_upto;
+ mpz_t got, want;
+ long got_l, want_ftell;
+ int error = 0;
+ fun_t fun;
+ const char *name;
+ char fmt[128];
+
+ mpz_init (got);
+ mpz_init (want);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (want, data[i].want, 0);
+
+ ASSERT_ALWAYS (strlen (data[i].fmt) + 2 < sizeof (fmt));
+ strcpy (fmt, data[i].fmt);
+ strcat (fmt, "%n");
+
+ ignore = fmt_allignore (fmt);
+
+ for (j = 0; j <= 3; j++)
+ {
+ want_ret = data[i].want_ret;
+
+ want_ftell = data[i].want_ftell;
+ if (want_ftell == -1)
+ want_ftell = strlen (data[i].input);
+
+ want_upto = data[i].want_upto;
+ if (want_upto == -1)
+ want_upto = strlen (data[i].input);
+
+ switch (j) {
+ case 0:
+ name = "gmp_sscanf";
+ fun = fun_gmp_sscanf;
+ break;
+ case 1:
+ name = "gmp_fscanf";
+ fun = fun_gmp_fscanf;
+ break;
+ case 2:
+#ifdef __GLIBC__
+ if (data[i].not_glibc)
+ continue;
+#endif
+ if (! libc_scanf_convert (fmt))
+ continue;
+ name = "standard sscanf";
+ fun = fun_sscanf;
+ break;
+ case 3:
+#ifdef __GLIBC__
+ if (data[i].not_glibc)
+ continue;
+#endif
+ if (! libc_scanf_convert (fmt))
+ continue;
+ name = "standard fscanf";
+ fun = fun_fscanf;
+ break;
+ default:
+ ASSERT_ALWAYS (0);
+ break;
+ }
+
+ got_upto = -555;
+ got_ftell = -1L;
+
+ switch (j) {
+ case 0:
+ case 1:
+ mpz_set_si (got, -999L);
+ if (ignore)
+ got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL);
+ else
+ got_ret = (*fun) (data[i].input, fmt, got, &got_upto);
+ break;
+ case 2:
+ case 3:
+ got_l = -999L;
+ if (ignore)
+ got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL);
+ else
+ got_ret = (*fun) (data[i].input, fmt, &got_l, &got_upto);
+ mpz_set_si (got, got_l);
+ break;
+ default:
+ ASSERT_ALWAYS (0);
+ break;
+ }
+
+ MPZ_CHECK_FORMAT (got);
+
+ if (got_ret != want_ret)
+ {
+ printf ("%s wrong return value\n", name);
+ error = 1;
+ }
+ if (want_ret == 1 && mpz_cmp (want, got) != 0)
+ {
+ printf ("%s wrong result\n", name);
+ error = 1;
+ }
+ if (got_upto != want_upto)
+ {
+ printf ("%s wrong upto\n", name);
+ error = 1;
+ }
+ if (got_ftell != -1 && want_ftell != -1 && got_ftell != want_ftell)
+ {
+ printf ("%s wrong ftell\n", name);
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" fmt \"%s\"\n", data[i].fmt);
+ printf (" input \"%s\"\n", data[i].input);
+ printf (" ignore %d\n", ignore);
+ printf (" ret want=%d\n", want_ret);
+ printf (" got =%d\n", got_ret);
+ mpz_trace (" value want", want);
+ mpz_trace (" got ", got);
+ printf (" upto want =%d\n", want_upto);
+ printf (" got =%d\n", got_upto);
+ if (got_ftell != -1)
+ {
+ printf (" ftell want =%ld\n", want_ftell);
+ printf (" got =%ld\n", got_ftell);
+ }
+ abort ();
+ }
+ }
+ }
+
+ mpz_clear (got);
+ mpz_clear (want);
+}
+
+void
+check_q (void)
+{
+ static const struct {
+ const char *fmt;
+ const char *input;
+ const char *want;
+ int ret;
+ long ftell;
+
+ } data[] = {
+
+ { "%Qd", "0", "0", 1, -1 },
+ { "%Qd", "1", "1", 1, -1 },
+ { "%Qd", "123", "123", 1, -1 },
+ { "%Qd", "+0", "0", 1, -1 },
+ { "%Qd", "+1", "1", 1, -1 },
+ { "%Qd", "+123", "123", 1, -1 },
+ { "%Qd", "-0", "0", 1, -1 },
+ { "%Qd", "-1", "-1", 1, -1 },
+ { "%Qd", "-123", "-123", 1, -1 },
+
+ { "%Qo", "0", "0", 1, -1 },
+ { "%Qo", "173", "123", 1, -1 },
+ { "%Qo", "+0", "0", 1, -1 },
+ { "%Qo", "+173", "123", 1, -1 },
+ { "%Qo", "-0", "0", 1, -1 },
+ { "%Qo", "-173", "-123", 1, -1 },
+
+ { "%Qx", "0", "0", 1, -1 },
+ { "%Qx", "7b", "123", 1, -1 },
+ { "%Qx", "7b", "123", 1, -1 },
+ { "%Qx", "+0", "0", 1, -1 },
+ { "%Qx", "+7b", "123", 1, -1 },
+ { "%Qx", "+7b", "123", 1, -1 },
+ { "%Qx", "-0", "-0", 1, -1 },
+ { "%Qx", "-7b", "-123", 1, -1 },
+ { "%Qx", "-7b", "-123", 1, -1 },
+ { "%QX", "0", "0", 1, -1 },
+ { "%QX", "7b", "123", 1, -1 },
+ { "%QX", "7b", "123", 1, -1 },
+ { "%QX", "+0", "0", 1, -1 },
+ { "%QX", "+7b", "123", 1, -1 },
+ { "%QX", "+7b", "123", 1, -1 },
+ { "%QX", "-0", "-0", 1, -1 },
+ { "%QX", "-7b", "-123", 1, -1 },
+ { "%QX", "-7b", "-123", 1, -1 },
+ { "%Qx", "0", "0", 1, -1 },
+ { "%Qx", "7B", "123", 1, -1 },
+ { "%Qx", "7B", "123", 1, -1 },
+ { "%Qx", "+0", "0", 1, -1 },
+ { "%Qx", "+7B", "123", 1, -1 },
+ { "%Qx", "+7B", "123", 1, -1 },
+ { "%Qx", "-0", "-0", 1, -1 },
+ { "%Qx", "-7B", "-123", 1, -1 },
+ { "%Qx", "-7B", "-123", 1, -1 },
+ { "%QX", "0", "0", 1, -1 },
+ { "%QX", "7B", "123", 1, -1 },
+ { "%QX", "7B", "123", 1, -1 },
+ { "%QX", "+0", "0", 1, -1 },
+ { "%QX", "+7B", "123", 1, -1 },
+ { "%QX", "+7B", "123", 1, -1 },
+ { "%QX", "-0", "-0", 1, -1 },
+ { "%QX", "-7B", "-123", 1, -1 },
+ { "%QX", "-7B", "-123", 1, -1 },
+
+ { "%Qi", "0", "0", 1, -1 },
+ { "%Qi", "1", "1", 1, -1 },
+ { "%Qi", "123", "123", 1, -1 },
+ { "%Qi", "+0", "0", 1, -1 },
+ { "%Qi", "+1", "1", 1, -1 },
+ { "%Qi", "+123", "123", 1, -1 },
+ { "%Qi", "-0", "0", 1, -1 },
+ { "%Qi", "-1", "-1", 1, -1 },
+ { "%Qi", "-123", "-123", 1, -1 },
+
+ { "%Qi", "00", "0", 1, -1 },
+ { "%Qi", "0173", "123", 1, -1 },
+ { "%Qi", "+00", "0", 1, -1 },
+ { "%Qi", "+0173", "123", 1, -1 },
+ { "%Qi", "-00", "0", 1, -1 },
+ { "%Qi", "-0173", "-123", 1, -1 },
+
+ { "%Qi", "0x0", "0", 1, -1 },
+ { "%Qi", "0x7b", "123", 1, -1 },
+ { "%Qi", "0x7b", "123", 1, -1 },
+ { "%Qi", "+0x0", "0", 1, -1 },
+ { "%Qi", "+0x7b", "123", 1, -1 },
+ { "%Qi", "+0x7b", "123", 1, -1 },
+ { "%Qi", "-0x0", "-0", 1, -1 },
+ { "%Qi", "-0x7b", "-123", 1, -1 },
+ { "%Qi", "-0x7b", "-123", 1, -1 },
+ { "%Qi", "0X0", "0", 1, -1 },
+ { "%Qi", "0X7b", "123", 1, -1 },
+ { "%Qi", "0X7b", "123", 1, -1 },
+ { "%Qi", "+0X0", "0", 1, -1 },
+ { "%Qi", "+0X7b", "123", 1, -1 },
+ { "%Qi", "+0X7b", "123", 1, -1 },
+ { "%Qi", "-0X0", "-0", 1, -1 },
+ { "%Qi", "-0X7b", "-123", 1, -1 },
+ { "%Qi", "-0X7b", "-123", 1, -1 },
+ { "%Qi", "0x0", "0", 1, -1 },
+ { "%Qi", "0x7B", "123", 1, -1 },
+ { "%Qi", "0x7B", "123", 1, -1 },
+ { "%Qi", "+0x0", "0", 1, -1 },
+ { "%Qi", "+0x7B", "123", 1, -1 },
+ { "%Qi", "+0x7B", "123", 1, -1 },
+ { "%Qi", "-0x0", "-0", 1, -1 },
+ { "%Qi", "-0x7B", "-123", 1, -1 },
+ { "%Qi", "-0x7B", "-123", 1, -1 },
+ { "%Qi", "0X0", "0", 1, -1 },
+ { "%Qi", "0X7B", "123", 1, -1 },
+ { "%Qi", "0X7B", "123", 1, -1 },
+ { "%Qi", "+0X0", "0", 1, -1 },
+ { "%Qi", "+0X7B", "123", 1, -1 },
+ { "%Qi", "+0X7B", "123", 1, -1 },
+ { "%Qi", "-0X0", "-0", 1, -1 },
+ { "%Qi", "-0X7B", "-123", 1, -1 },
+ { "%Qi", "-0X7B", "-123", 1, -1 },
+
+ { "%Qd", " 0", "0", 1, -1 },
+ { "%Qd", " 0", "0", 1, -1 },
+ { "%Qd", " 0", "0", 1, -1 },
+ { "%Qd", "\t0", "0", 1, -1 },
+ { "%Qd", "\t\t0", "0", 1, -1 },
+
+ { "%Qd", "3/2", "3/2", 1, -1 },
+ { "%Qd", "+3/2", "3/2", 1, -1 },
+ { "%Qd", "-3/2", "-3/2", 1, -1 },
+
+ { "%Qx", "f/10", "15/16", 1, -1 },
+ { "%Qx", "F/10", "15/16", 1, -1 },
+ { "%QX", "f/10", "15/16", 1, -1 },
+ { "%QX", "F/10", "15/16", 1, -1 },
+
+ { "%Qo", "20/21", "16/17", 1, -1 },
+ { "%Qo", "-20/21", "-16/17", 1, -1 },
+
+ { "%Qi", "10/11", "10/11", 1, -1 },
+ { "%Qi", "+10/11", "10/11", 1, -1 },
+ { "%Qi", "-10/11", "-10/11", 1, -1 },
+ { "%Qi", "010/11", "8/11", 1, -1 },
+ { "%Qi", "+010/11", "8/11", 1, -1 },
+ { "%Qi", "-010/11", "-8/11", 1, -1 },
+ { "%Qi", "0x10/11", "16/11", 1, -1 },
+ { "%Qi", "+0x10/11", "16/11", 1, -1 },
+ { "%Qi", "-0x10/11", "-16/11", 1, -1 },
+
+ { "%Qi", "10/011", "10/9", 1, -1 },
+ { "%Qi", "+10/011", "10/9", 1, -1 },
+ { "%Qi", "-10/011", "-10/9", 1, -1 },
+ { "%Qi", "010/011", "8/9", 1, -1 },
+ { "%Qi", "+010/011", "8/9", 1, -1 },
+ { "%Qi", "-010/011", "-8/9", 1, -1 },
+ { "%Qi", "0x10/011", "16/9", 1, -1 },
+ { "%Qi", "+0x10/011", "16/9", 1, -1 },
+ { "%Qi", "-0x10/011", "-16/9", 1, -1 },
+
+ { "%Qi", "10/0x11", "10/17", 1, -1 },
+ { "%Qi", "+10/0x11", "10/17", 1, -1 },
+ { "%Qi", "-10/0x11", "-10/17", 1, -1 },
+ { "%Qi", "010/0x11", "8/17", 1, -1 },
+ { "%Qi", "+010/0x11", "8/17", 1, -1 },
+ { "%Qi", "-010/0x11", "-8/17", 1, -1 },
+ { "%Qi", "0x10/0x11", "16/17", 1, -1 },
+ { "%Qi", "+0x10/0x11", "16/17", 1, -1 },
+ { "%Qi", "-0x10/0x11", "-16/17", 1, -1 },
+
+ { "hello%Qd", "hello0", "0", 1, -1 },
+ { "hello%Qd", "hello 0", "0", 1, -1 },
+ { "hello%Qd", "hello \t0", "0", 1, -1 },
+ { "hello%Qdworld", "hello 0world", "0", 1, -1 },
+ { "hello%Qd", "hello3/2", "3/2", 1, -1 },
+
+ { "hello%*Qd", "hello0", "-999/121", 0, -1 },
+ { "hello%*Qd", "hello 0", "-999/121", 0, -1 },
+ { "hello%*Qd", "hello \t0", "-999/121", 0, -1 },
+ { "hello%*Qdworld", "hello 0world", "-999/121", 0, -1 },
+ { "hello%*Qdworld", "hello3/2world", "-999/121", 0, -1 },
+
+ { "%Qd", "", "-999/121", -1, -1 },
+ { "%Qd", " ", "-999/121", -1, -1 },
+ { " %Qd", "", "-999/121", -1, -1 },
+ { "xyz%Qd", "", "-999/121", -1, -1 },
+
+ { "%*Qd", "", "-999/121", -1, -1 },
+ { " %*Qd", "", "-999/121", -1, -1 },
+ { "xyz%*Qd", "", "-999/121", -1, -1 },
+
+ /* match something, but invalid */
+ { "%Qd", "-", "-999/121", 0, 1 },
+ { "%Qd", "+", "-999/121", 0, 1 },
+ { "%Qd", "/-", "-999/121", 0, 1 },
+ { "%Qd", "/+", "-999/121", 0, 1 },
+ { "%Qd", "-/", "-999/121", 0, 1 },
+ { "%Qd", "+/", "-999/121", 0, 1 },
+ { "%Qd", "-/-", "-999/121", 0, 1 },
+ { "%Qd", "-/+", "-999/121", 0, 1 },
+ { "%Qd", "+/+", "-999/121", 0, 1 },
+ { "%Qd", "/123", "-999/121", 0, 1 },
+ { "%Qd", "-/123", "-999/121", 0, 1 },
+ { "%Qd", "+/123", "-999/121", 0, 1 },
+ { "%Qd", "123/", "-999/121", 0, 1 },
+ { "%Qd", "123/-", "-999/121", 0, 1 },
+ { "%Qd", "123/+", "-999/121", 0, 1 },
+ { "xyz%Qd", "xyz-", "-999/121", 0, 4 },
+ { "xyz%Qd", "xyz+", "-999/121", 0, 4 },
+
+ { "%1Qi", "12/57", "1", 1, 1 },
+ { "%2Qi", "12/57", "12", 1, 2 },
+ { "%3Qi", "12/57", "-999/121", 0, -1 },
+ { "%4Qi", "12/57", "12/5", 1, 4 },
+ { "%5Qi", "12/57", "12/57", 1, 5 },
+ { "%6Qi", "12/57", "12/57", 1, 5 },
+ { "%7Qi", "12/57", "12/57", 1, 5 },
+
+ { "%1Qi", "012/057", "0", 1, 1 },
+ { "%2Qi", "012/057", "01", 1, 2 },
+ { "%3Qi", "012/057", "012", 1, 3 },
+ { "%4Qi", "012/057", "-999/121", 0, -1 },
+ { "%5Qi", "012/057", "012/0", 1, 5 },
+ { "%6Qi", "012/057", "012/5", 1, 6 },
+ { "%7Qi", "012/057", "012/057", 1, 7 },
+ { "%8Qi", "012/057", "012/057", 1, 7 },
+ { "%9Qi", "012/057", "012/057", 1, 7 },
+
+ { "%1Qi", "0x12/0x57", "0", 1, 1 },
+ { "%2Qi", "0x12/0x57", "-999", 0, 2 },
+ { "%3Qi", "0x12/0x57", "0x1", 1, 3 },
+ { "%4Qi", "0x12/0x57", "0x12", 1, 4 },
+ { "%5Qi", "0x12/0x57", "-999/121", 0, 5 },
+ { "%6Qi", "0x12/0x57", "0x12/0", 1, 6 },
+ { "%7Qi", "0x12/0x57", "-999/121", 0, 7 },
+ { "%8Qi", "0x12/0x57", "0x12/0x5", 1, 8 },
+ { "%9Qi", "0x12/0x57", "0x12/0x57", 1, 9 },
+ { "%10Qi", "0x12/0x57", "0x12/0x57", 1, 9 },
+ { "%11Qi", "0x12/0x57", "0x12/0x57", 1, 9 },
+
+ { "%Qd", "xyz", "0", 0, 0 },
+ };
+
+ int i, j, ignore, got_ret, want_ret, got_upto, want_upto;
+ mpq_t got, want;
+ long got_l, want_ftell;
+ int error = 0;
+ fun_t fun;
+ const char *name;
+ char fmt[128];
+
+ mpq_init (got);
+ mpq_init (want);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpq_set_str_or_abort (want, data[i].want, 0);
+
+ ASSERT_ALWAYS (strlen (data[i].fmt) + 2 < sizeof (fmt));
+ strcpy (fmt, data[i].fmt);
+ strcat (fmt, "%n");
+
+ ignore = (strchr (fmt, '*') != NULL);
+
+ for (j = 0; j <= 3; j++)
+ {
+ want_ret = data[i].ret;
+
+ want_ftell = data[i].ftell;
+ if (want_ftell == -1)
+ want_ftell = strlen (data[i].input);
+ want_upto = want_ftell;
+
+ if (want_ret == -1 || (want_ret == 0 && ! ignore))
+ {
+ want_ftell = -1;
+ want_upto = -555;
+ }
+
+ switch (j) {
+ case 0:
+ name = "gmp_sscanf";
+ fun = fun_gmp_sscanf;
+ break;
+ case 1:
+ name = "gmp_fscanf";
+ fun = fun_gmp_fscanf;
+ break;
+ case 2:
+ if (strchr (data[i].input, '/') != NULL)
+ continue;
+ if (! libc_scanf_convert (fmt))
+ continue;
+ name = "standard sscanf";
+ fun = fun_sscanf;
+ break;
+ case 3:
+ if (strchr (data[i].input, '/') != NULL)
+ continue;
+ if (! libc_scanf_convert (fmt))
+ continue;
+ name = "standard fscanf";
+ fun = fun_fscanf;
+ break;
+ default:
+ ASSERT_ALWAYS (0);
+ break;
+ }
+
+ got_upto = -555;
+ got_ftell = -1;
+
+ switch (j) {
+ case 0:
+ case 1:
+ mpq_set_si (got, -999L, 121L);
+ if (ignore)
+ got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL);
+ else
+ got_ret = (*fun) (data[i].input, fmt, got, &got_upto);
+ break;
+ case 2:
+ case 3:
+ got_l = -999L;
+ if (ignore)
+ got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL);
+ else
+ got_ret = (*fun) (data[i].input, fmt, &got_l, &got_upto);
+ mpq_set_si (got, got_l, (got_l == -999L ? 121L : 1L));
+ break;
+ default:
+ ASSERT_ALWAYS (0);
+ break;
+ }
+
+ MPZ_CHECK_FORMAT (mpq_numref (got));
+ MPZ_CHECK_FORMAT (mpq_denref (got));
+
+ if (got_ret != want_ret)
+ {
+ printf ("%s wrong return value\n", name);
+ error = 1;
+ }
+ /* use direct mpz compares, since some of the test data is
+ non-canonical and can trip ASSERTs in mpq_equal */
+ if (want_ret == 1
+ && ! (mpz_cmp (mpq_numref(want), mpq_numref(got)) == 0
+ && mpz_cmp (mpq_denref(want), mpq_denref(got)) == 0))
+ {
+ printf ("%s wrong result\n", name);
+ error = 1;
+ }
+ if (got_upto != want_upto)
+ {
+ printf ("%s wrong upto\n", name);
+ error = 1;
+ }
+ if (got_ftell != -1 && want_ftell != -1 && got_ftell != want_ftell)
+ {
+ printf ("%s wrong ftell\n", name);
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" fmt \"%s\"\n", data[i].fmt);
+ printf (" input \"%s\"\n", data[i].input);
+ printf (" ret want=%d\n", want_ret);
+ printf (" got =%d\n", got_ret);
+ mpq_trace (" value want", want);
+ mpq_trace (" got ", got);
+ printf (" upto want=%d\n", want_upto);
+ printf (" got =%d\n", got_upto);
+ if (got_ftell != -1)
+ {
+ printf (" ftell want =%ld\n", want_ftell);
+ printf (" got =%ld\n", got_ftell);
+ }
+ abort ();
+ }
+ }
+ }
+
+ mpq_clear (got);
+ mpq_clear (want);
+}
+
+void
+check_f (void)
+{
+ static const struct {
+ const char *fmt;
+ const char *input;
+ const char *want;
+ int ret;
+ long ftell; /* or -1 for length of input string */
+
+ } data[] = {
+
+ { "%Ff", "0", "0", 1, -1 },
+ { "%Fe", "0", "0", 1, -1 },
+ { "%FE", "0", "0", 1, -1 },
+ { "%Fg", "0", "0", 1, -1 },
+ { "%FG", "0", "0", 1, -1 },
+
+ { "%Ff", "123", "123", 1, -1 },
+ { "%Ff", "+123", "123", 1, -1 },
+ { "%Ff", "-123", "-123", 1, -1 },
+ { "%Ff", "123.", "123", 1, -1 },
+ { "%Ff", "+123.", "123", 1, -1 },
+ { "%Ff", "-123.", "-123", 1, -1 },
+ { "%Ff", "123.0", "123", 1, -1 },
+ { "%Ff", "+123.0", "123", 1, -1 },
+ { "%Ff", "-123.0", "-123", 1, -1 },
+ { "%Ff", "0123", "123", 1, -1 },
+ { "%Ff", "-0123", "-123", 1, -1 },
+
+ { "%Ff", "123.456e3", "123456", 1, -1 },
+ { "%Ff", "-123.456e3", "-123456", 1, -1 },
+ { "%Ff", "123.456e+3", "123456", 1, -1 },
+ { "%Ff", "-123.456e+3", "-123456", 1, -1 },
+ { "%Ff", "123000e-3", "123", 1, -1 },
+ { "%Ff", "-123000e-3", "-123", 1, -1 },
+ { "%Ff", "123000.e-3", "123", 1, -1 },
+ { "%Ff", "-123000.e-3", "-123", 1, -1 },
+
+ { "%Ff", "123.456E3", "123456", 1, -1 },
+ { "%Ff", "-123.456E3", "-123456", 1, -1 },
+ { "%Ff", "123.456E+3", "123456", 1, -1 },
+ { "%Ff", "-123.456E+3", "-123456", 1, -1 },
+ { "%Ff", "123000E-3", "123", 1, -1 },
+ { "%Ff", "-123000E-3", "-123", 1, -1 },
+ { "%Ff", "123000.E-3", "123", 1, -1 },
+ { "%Ff", "-123000.E-3", "-123", 1, -1 },
+
+ { "%Ff", ".456e3", "456", 1, -1 },
+ { "%Ff", "-.456e3", "-456", 1, -1 },
+ { "%Ff", ".456e+3", "456", 1, -1 },
+ { "%Ff", "-.456e+3", "-456", 1, -1 },
+
+ { "%Ff", " 0", "0", 1, -1 },
+ { "%Ff", " 0", "0", 1, -1 },
+ { "%Ff", " 0", "0", 1, -1 },
+ { "%Ff", "\t0", "0", 1, -1 },
+ { "%Ff", "\t\t0", "0", 1, -1 },
+
+ { "hello%Fg", "hello0", "0", 1, -1 },
+ { "hello%Fg", "hello 0", "0", 1, -1 },
+ { "hello%Fg", "hello \t0", "0", 1, -1 },
+ { "hello%Fgworld", "hello 0world", "0", 1, -1 },
+ { "hello%Fg", "hello3.0", "3.0", 1, -1 },
+
+ { "hello%*Fg", "hello0", "-999", 0, -1 },
+ { "hello%*Fg", "hello 0", "-999", 0, -1 },
+ { "hello%*Fg", "hello \t0", "-999", 0, -1 },
+ { "hello%*Fgworld", "hello 0world", "-999", 0, -1 },
+ { "hello%*Fgworld", "hello3.0world", "-999", 0, -1 },
+
+ { "%Ff", "", "-999", -1, -1 },
+ { "%Ff", " ", "-999", -1, -1 },
+ { "%Ff", "\t", "-999", -1, -1 },
+ { "%Ff", " \t", "-999", -1, -1 },
+ { " %Ff", "", "-999", -1, -1 },
+ { "xyz%Ff", "", "-999", -1, -1 },
+
+ { "%*Ff", "", "-999", -1, -1 },
+ { " %*Ff", "", "-999", -1, -1 },
+ { "xyz%*Ff", "", "-999", -1, -1 },
+
+ { "%Ff", "xyz", "0", 0 },
+
+ /* various non-empty but invalid */
+ { "%Ff", "-", "-999", 0, 1 },
+ { "%Ff", "+", "-999", 0, 1 },
+ { "xyz%Ff", "xyz-", "-999", 0, 4 },
+ { "xyz%Ff", "xyz+", "-999", 0, 4 },
+ { "%Ff", "-.", "-999", 0, 2 },
+ { "%Ff", "+.", "-999", 0, 2 },
+ { "%Ff", ".e", "-999", 0, 1 },
+ { "%Ff", "-.e", "-999", 0, 2 },
+ { "%Ff", "+.e", "-999", 0, 2 },
+ { "%Ff", ".E", "-999", 0, 1 },
+ { "%Ff", "-.E", "-999", 0, 2 },
+ { "%Ff", "+.E", "-999", 0, 2 },
+ { "%Ff", ".e123", "-999", 0, 1 },
+ { "%Ff", "-.e123", "-999", 0, 2 },
+ { "%Ff", "+.e123", "-999", 0, 2 },
+ { "%Ff", "123e", "-999", 0, 4 },
+ { "%Ff", "-123e", "-999", 0, 5 },
+ { "%Ff", "123e-", "-999", 0, 5 },
+ { "%Ff", "-123e-", "-999", 0, 6 },
+ { "%Ff", "123e+", "-999", 0, 5 },
+ { "%Ff", "-123e+", "-999", 0, 6 },
+ { "%Ff", "123e-Z", "-999", 0, 5 },
+
+ /* hex floats */
+ { "%Ff", "0x123p0", "291", 1, -1 },
+ { "%Ff", "0x123P0", "291", 1, -1 },
+ { "%Ff", "0X123p0", "291", 1, -1 },
+ { "%Ff", "0X123P0", "291", 1, -1 },
+ { "%Ff", "-0x123p0", "-291", 1, -1 },
+ { "%Ff", "+0x123p0", "291", 1, -1 },
+ { "%Ff", "0x123.p0", "291", 1, -1 },
+ { "%Ff", "0x12.3p4", "291", 1, -1 },
+ { "%Ff", "-0x12.3p4", "-291", 1, -1 },
+ { "%Ff", "+0x12.3p4", "291", 1, -1 },
+ { "%Ff", "0x1230p-4", "291", 1, -1 },
+ { "%Ff", "-0x1230p-4", "-291", 1, -1 },
+ { "%Ff", "+0x1230p-4", "291", 1, -1 },
+ { "%Ff", "+0x.1230p12", "291", 1, -1 },
+ { "%Ff", "+0x123000p-12", "291", 1, -1 },
+ { "%Ff", "0x123 p12", "291", 1, 5 },
+ { "%Ff", "0x9 9", "9", 1, 3 },
+ { "%Ff", "0x01", "1", 1, 4 },
+ { "%Ff", "0x23", "35", 1, 4 },
+ { "%Ff", "0x45", "69", 1, 4 },
+ { "%Ff", "0x67", "103", 1, 4 },
+ { "%Ff", "0x89", "137", 1, 4 },
+ { "%Ff", "0xAB", "171", 1, 4 },
+ { "%Ff", "0xCD", "205", 1, 4 },
+ { "%Ff", "0xEF", "239", 1, 4 },
+ { "%Ff", "0xab", "171", 1, 4 },
+ { "%Ff", "0xcd", "205", 1, 4 },
+ { "%Ff", "0xef", "239", 1, 4 },
+ { "%Ff", "0x100p0A", "256", 1, 7 },
+ { "%Ff", "0x1p9", "512", 1, -1 },
+
+ /* invalid hex floats */
+ { "%Ff", "0x", "-999", 0, 2 },
+ { "%Ff", "-0x", "-999", 0, 3 },
+ { "%Ff", "+0x", "-999", 0, 3 },
+ { "%Ff", "0x-", "-999", 0, 2 },
+ { "%Ff", "0x+", "-999", 0, 2 },
+ { "%Ff", "0x.", "-999", 0, 3 },
+ { "%Ff", "-0x.", "-999", 0, 4 },
+ { "%Ff", "+0x.", "-999", 0, 4 },
+ { "%Ff", "0x.p", "-999", 0, 3 },
+ { "%Ff", "-0x.p", "-999", 0, 4 },
+ { "%Ff", "+0x.p", "-999", 0, 4 },
+ { "%Ff", "0x.P", "-999", 0, 3 },
+ { "%Ff", "-0x.P", "-999", 0, 4 },
+ { "%Ff", "+0x.P", "-999", 0, 4 },
+ { "%Ff", ".p123", "-999", 0, 1 },
+ { "%Ff", "-.p123", "-999", 0, 2 },
+ { "%Ff", "+.p123", "-999", 0, 2 },
+ { "%Ff", "0x1p", "-999", 0, 4 },
+ { "%Ff", "0x1p-", "-999", 0, 5 },
+ { "%Ff", "0x1p+", "-999", 0, 5 },
+ { "%Ff", "0x123p 12", "291", 0, 6 },
+ { "%Ff", "0x 123p12", "291", 0, 2 },
+
+ };
+
+ int i, j, ignore, got_ret, want_ret, got_upto, want_upto;
+ mpf_t got, want;
+ double got_d;
+ long want_ftell;
+ int error = 0;
+ fun_t fun;
+ const char *name;
+ char fmt[128];
+
+ mpf_init (got);
+ mpf_init (want);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpf_set_str_or_abort (want, data[i].want, 10);
+
+ ASSERT_ALWAYS (strlen (data[i].fmt) + 2 < sizeof (fmt));
+ strcpy (fmt, data[i].fmt);
+ strcat (fmt, "%n");
+
+ ignore = (strchr (fmt, '*') != NULL);
+
+ for (j = 0; j <= 3; j++)
+ {
+ want_ret = data[i].ret;
+
+ want_ftell = data[i].ftell;
+ if (want_ftell == -1)
+ want_ftell = strlen (data[i].input);
+ want_upto = want_ftell;
+
+ if (want_ret == -1 || (want_ret == 0 && ! ignore))
+ want_upto = -555;
+
+ switch (j) {
+ case 0:
+ name = "gmp_sscanf";
+ fun = fun_gmp_sscanf;
+ break;
+ case 1:
+ name = "gmp_fscanf";
+ fun = fun_gmp_fscanf;
+ break;
+ case 2:
+ if (! libc_scanf_convert (fmt))
+ continue;
+ name = "standard sscanf";
+ fun = fun_sscanf;
+ break;
+ case 3:
+ if (! libc_scanf_convert (fmt))
+ continue;
+ name = "standard fscanf";
+ fun = fun_fscanf;
+ break;
+ default:
+ ASSERT_ALWAYS (0);
+ break;
+ }
+
+ got_upto = -555;
+ got_ftell = -1;
+
+ switch (j) {
+ case 0:
+ case 1:
+ mpf_set_si (got, -999L);
+ if (ignore)
+ got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL);
+ else
+ got_ret = (*fun) (data[i].input, fmt, got, &got_upto);
+ break;
+ case 2:
+ case 3:
+ got_d = -999L;
+ if (ignore)
+ got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL);
+ else
+ got_ret = (*fun) (data[i].input, fmt, &got_d, &got_upto);
+ mpf_set_d (got, got_d);
+ break;
+ default:
+ ASSERT_ALWAYS (0);
+ break;
+ }
+
+ MPF_CHECK_FORMAT (got);
+
+ if (got_ret != want_ret)
+ {
+ printf ("%s wrong return value\n", name);
+ error = 1;
+ }
+ if (want_ret == 1 && mpf_cmp (want, got) != 0)
+ {
+ printf ("%s wrong result\n", name);
+ error = 1;
+ }
+ if (got_upto != want_upto)
+ {
+ printf ("%s wrong upto\n", name);
+ error = 1;
+ }
+ if (got_ftell != -1 && want_ftell != -1 && got_ftell != want_ftell)
+ {
+ printf ("%s wrong ftell\n", name);
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" fmt \"%s\"\n", data[i].fmt);
+ printf (" input \"%s\"\n", data[i].input);
+ printf (" ret want=%d\n", want_ret);
+ printf (" got =%d\n", got_ret);
+ mpf_trace (" value want", want);
+ mpf_trace (" got ", got);
+ printf (" upto want=%d\n", want_upto);
+ printf (" got =%d\n", got_upto);
+ if (got_ftell != -1)
+ {
+ printf (" ftell want =%ld\n", want_ftell);
+ printf (" got =%ld\n", got_ftell);
+ }
+ abort ();
+ }
+ }
+ }
+
+ mpf_clear (got);
+ mpf_clear (want);
+}
+
+
+void
+check_n (void)
+{
+ int ret;
+
+ /* %n suppressed */
+ {
+ int n = 123;
+ gmp_sscanf (" ", " %*n", &n);
+ ASSERT_ALWAYS (n == 123);
+ }
+ {
+ int n = 123;
+ fromstring_gmp_fscanf (" ", " %*n", &n);
+ ASSERT_ALWAYS (n == 123);
+ }
+
+
+#define CHECK_N(type, string) \
+ do { \
+ type x[2]; \
+ char fmt[128]; \
+ int ret; \
+ \
+ x[0] = ~ (type) 0; \
+ x[1] = ~ (type) 0; \
+ sprintf (fmt, "abc%%%sn", string); \
+ ret = gmp_sscanf ("abc", fmt, &x[0]); \
+ \
+ ASSERT_ALWAYS (ret == 0); \
+ \
+ /* should write whole of x[0] and none of x[1] */ \
+ ASSERT_ALWAYS (x[0] == 3); \
+ ASSERT_ALWAYS (x[1] == (type) ~ (type) 0); \
+ \
+ } while (0)
+
+ CHECK_N (char, "hh");
+ CHECK_N (long, "l");
+#if HAVE_LONG_LONG
+ CHECK_N (long long, "L");
+#endif
+#if HAVE_INTMAX_T
+ CHECK_N (intmax_t, "j");
+#endif
+#if HAVE_PTRDIFF_T
+ CHECK_N (ptrdiff_t, "t");
+#endif
+ CHECK_N (short, "h");
+ CHECK_N (size_t, "z");
+
+ /* %Zn */
+ {
+ mpz_t x[2];
+ mpz_init_set_si (x[0], -987L);
+ mpz_init_set_si (x[1], 654L);
+ ret = gmp_sscanf ("xyz ", "xyz%Zn", x[0]);
+ MPZ_CHECK_FORMAT (x[0]);
+ MPZ_CHECK_FORMAT (x[1]);
+ ASSERT_ALWAYS (ret == 0);
+ ASSERT_ALWAYS (mpz_cmp_ui (x[0], 3L) == 0);
+ ASSERT_ALWAYS (mpz_cmp_ui (x[1], 654L) == 0);
+ mpz_clear (x[0]);
+ mpz_clear (x[1]);
+ }
+ {
+ mpz_t x;
+ mpz_init (x);
+ ret = fromstring_gmp_fscanf ("xyz ", "xyz%Zn", x);
+ ASSERT_ALWAYS (ret == 0);
+ ASSERT_ALWAYS (mpz_cmp_ui (x, 3L) == 0);
+ mpz_clear (x);
+ }
+
+ /* %Qn */
+ {
+ mpq_t x[2];
+ mpq_init (x[0]);
+ mpq_init (x[1]);
+ mpq_set_ui (x[0], 987L, 654L);
+ mpq_set_ui (x[1], 4115L, 226L);
+ ret = gmp_sscanf ("xyz ", "xyz%Qn", x[0]);
+ MPQ_CHECK_FORMAT (x[0]);
+ MPQ_CHECK_FORMAT (x[1]);
+ ASSERT_ALWAYS (ret == 0);
+ ASSERT_ALWAYS (mpq_cmp_ui (x[0], 3L, 1L) == 0);
+ ASSERT_ALWAYS (mpq_cmp_ui (x[1], 4115L, 226L) == 0);
+ mpq_clear (x[0]);
+ mpq_clear (x[1]);
+ }
+ {
+ mpq_t x;
+ mpq_init (x);
+ ret = fromstring_gmp_fscanf ("xyz ", "xyz%Qn", x);
+ ASSERT_ALWAYS (ret == 0);
+ ASSERT_ALWAYS (mpq_cmp_ui (x, 3L, 1L) == 0);
+ mpq_clear (x);
+ }
+
+ /* %Fn */
+ {
+ mpf_t x[2];
+ mpf_init (x[0]);
+ mpf_init (x[1]);
+ mpf_set_ui (x[0], 987L);
+ mpf_set_ui (x[1], 654L);
+ ret = gmp_sscanf ("xyz ", "xyz%Fn", x[0]);
+ MPF_CHECK_FORMAT (x[0]);
+ MPF_CHECK_FORMAT (x[1]);
+ ASSERT_ALWAYS (ret == 0);
+ ASSERT_ALWAYS (mpf_cmp_ui (x[0], 3L) == 0);
+ ASSERT_ALWAYS (mpf_cmp_ui (x[1], 654L) == 0);
+ mpf_clear (x[0]);
+ mpf_clear (x[1]);
+ }
+ {
+ mpf_t x;
+ mpf_init (x);
+ ret = fromstring_gmp_fscanf ("xyz ", "xyz%Fn", x);
+ ASSERT_ALWAYS (ret == 0);
+ ASSERT_ALWAYS (mpf_cmp_ui (x, 3L) == 0);
+ mpf_clear (x);
+ }
+}
+
+
+void
+check_misc (void)
+{
+ int ret, cmp;
+ {
+ int a=9, b=8, c=7, n=66;
+ mpz_t z;
+ mpz_init (z);
+ ret = gmp_sscanf ("1 2 3 4", "%d %d %d %Zd%n",
+ &a, &b, &c, z, &n);
+ ASSERT_ALWAYS (ret == 4);
+ ASSERT_ALWAYS (a == 1);
+ ASSERT_ALWAYS (b == 2);
+ ASSERT_ALWAYS (c == 3);
+ ASSERT_ALWAYS (n == 7);
+ ASSERT_ALWAYS (mpz_cmp_ui (z, 4L) == 0);
+ mpz_clear (z);
+ }
+ {
+ int a=9, b=8, c=7, n=66;
+ mpz_t z;
+ mpz_init (z);
+ ret = fromstring_gmp_fscanf ("1 2 3 4", "%d %d %d %Zd%n",
+ &a, &b, &c, z, &n);
+ ASSERT_ALWAYS (ret == 4);
+ ASSERT_ALWAYS (a == 1);
+ ASSERT_ALWAYS (b == 2);
+ ASSERT_ALWAYS (c == 3);
+ ASSERT_ALWAYS (mpz_cmp_ui (z, 4L) == 0);
+ ASSERT_ALWAYS (n == 7);
+ ASSERT_ALWAYS (got_ftell == 7);
+ mpz_clear (z);
+ }
+
+ {
+ int a=9, n=8;
+ mpz_t z;
+ mpz_init (z);
+ ret = gmp_sscanf ("1 2 3 4", "%d %*d %*d %Zd%n", &a, z, &n);
+ ASSERT_ALWAYS (ret == 2);
+ ASSERT_ALWAYS (a == 1);
+ ASSERT_ALWAYS (mpz_cmp_ui (z, 4L) == 0);
+ ASSERT_ALWAYS (n == 7);
+ mpz_clear (z);
+ }
+ {
+ int a=9, n=8;
+ mpz_t z;
+ mpz_init (z);
+ ret = fromstring_gmp_fscanf ("1 2 3 4", "%d %*d %*d %Zd%n",
+ &a, z, &n);
+ ASSERT_ALWAYS (ret == 2);
+ ASSERT_ALWAYS (a == 1);
+ ASSERT_ALWAYS (mpz_cmp_ui (z, 4L) == 0);
+ ASSERT_ALWAYS (n == 7);
+ ASSERT_ALWAYS (got_ftell == 7);
+ mpz_clear (z);
+ }
+
+ /* EOF for no matching */
+ {
+ char buf[128];
+ ret = gmp_sscanf (" ", "%s", buf);
+ ASSERT_ALWAYS (ret == EOF);
+ ret = fromstring_gmp_fscanf (" ", "%s", buf);
+ ASSERT_ALWAYS (ret == EOF);
+ if (option_libc_scanf)
+ {
+ ret = sscanf (" ", "%s", buf);
+ ASSERT_ALWAYS (ret == EOF);
+ ret = fun_fscanf (" ", "%s", buf, NULL);
+ ASSERT_ALWAYS (ret == EOF);
+ }
+ }
+
+ /* suppressed field, then eof */
+ {
+ int x;
+ if (test_sscanf_eof_ok ())
+ {
+ ret = gmp_sscanf ("123", "%*d%d", &x);
+ ASSERT_ALWAYS (ret == EOF);
+ }
+ ret = fromstring_gmp_fscanf ("123", "%*d%d", &x);
+ ASSERT_ALWAYS (ret == EOF);
+ if (option_libc_scanf)
+ {
+ ret = sscanf ("123", "%*d%d", &x);
+ ASSERT_ALWAYS (ret == EOF);
+ ret = fun_fscanf ("123", "%*d%d", &x, NULL);
+ ASSERT_ALWAYS (ret == EOF);
+ }
+ }
+ {
+ mpz_t x;
+ mpz_init (x);
+ ret = gmp_sscanf ("123", "%*Zd%Zd", x);
+ ASSERT_ALWAYS (ret == EOF);
+ ret = fromstring_gmp_fscanf ("123", "%*Zd%Zd", x);
+ ASSERT_ALWAYS (ret == EOF);
+ mpz_clear (x);
+ }
+
+ /* %[...], glibc only */
+#ifdef __GLIBC__
+ {
+ char buf[128];
+ int n = -1;
+ buf[0] = '\0';
+ ret = gmp_sscanf ("abcdefgh", "%[a-d]ef%n", buf, &n);
+ ASSERT_ALWAYS (ret == 1);
+ cmp = strcmp (buf, "abcd");
+ ASSERT_ALWAYS (cmp == 0);
+ ASSERT_ALWAYS (n == 6);
+ }
+ {
+ char buf[128];
+ int n = -1;
+ buf[0] = '\0';
+ ret = gmp_sscanf ("xyza", "%[^a]a%n", buf, &n);
+ ASSERT_ALWAYS (ret == 1);
+ cmp = strcmp (buf, "xyz");
+ ASSERT_ALWAYS (cmp == 0);
+ ASSERT_ALWAYS (n == 4);
+ }
+ {
+ char buf[128];
+ int n = -1;
+ buf[0] = '\0';
+ ret = gmp_sscanf ("ab]ab]", "%[]ab]%n", buf, &n);
+ ASSERT_ALWAYS (ret == 1);
+ cmp = strcmp (buf, "ab]ab]");
+ ASSERT_ALWAYS (cmp == 0);
+ ASSERT_ALWAYS (n == 6);
+ }
+ {
+ char buf[128];
+ int n = -1;
+ buf[0] = '\0';
+ ret = gmp_sscanf ("xyzb", "%[^]ab]b%n", buf, &n);
+ ASSERT_ALWAYS (ret == 1);
+ cmp = strcmp (buf, "xyz");
+ ASSERT_ALWAYS (cmp == 0);
+ ASSERT_ALWAYS (n == 4);
+ }
+#endif
+
+ /* %zd etc won't be accepted by sscanf on old systems, and running
+ something to see if they work might be bad, so only try it on glibc,
+ and only on a new enough version (glibc 2.0 doesn't have %zd) */
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0)
+ {
+ mpz_t z;
+ size_t s = -1;
+ mpz_init (z);
+ ret = gmp_sscanf ("456 789", "%zd %Zd", &s, z);
+ ASSERT_ALWAYS (ret == 2);
+ ASSERT_ALWAYS (s == 456);
+ ASSERT_ALWAYS (mpz_cmp_ui (z, 789L) == 0);
+ mpz_clear (z);
+ }
+ {
+ mpz_t z;
+ ptrdiff_t d = -1;
+ mpz_init (z);
+ ret = gmp_sscanf ("456 789", "%td %Zd", &d, z);
+ ASSERT_ALWAYS (ret == 2);
+ ASSERT_ALWAYS (d == 456);
+ ASSERT_ALWAYS (mpz_cmp_ui (z, 789L) == 0);
+ mpz_clear (z);
+ }
+ {
+ mpz_t z;
+ long long ll = -1;
+ mpz_init (z);
+ ret = gmp_sscanf ("456 789", "%Ld %Zd", &ll, z);
+ ASSERT_ALWAYS (ret == 2);
+ ASSERT_ALWAYS (ll == 456);
+ ASSERT_ALWAYS (mpz_cmp_ui (z, 789L) == 0);
+ mpz_clear (z);
+ }
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (argc > 1 && strcmp (argv[1], "-s") == 0)
+ option_libc_scanf = 1;
+
+ tests_start ();
+
+ mp_trace_base = 16;
+
+ check_z ();
+ check_q ();
+ check_f ();
+ check_n ();
+ check_misc ();
+
+ unlink (TEMPFILE);
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/Makefile.am b/gmp/tests/mpf/Makefile.am
new file mode 100644
index 0000000000..71bccf1a29
--- /dev/null
+++ b/gmp/tests/mpf/Makefile.am
@@ -0,0 +1,31 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 1996, 1999-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/.
+
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+
+check_PROGRAMS = t-add t-sub t-conv t-sqrt t-sqrt_ui t-muldiv t-dm2exp reuse \
+ t-cmp_d t-cmp_si t-div t-fits t-get_d t-get_d_2exp \
+ t-get_si t-get_ui t-gsprec t-inp_str t-int_p t-mul_ui \
+ t-set t-set_q t-set_si t-set_ui t-trunc t-ui_div t-eq
+TESTS = $(check_PROGRAMS)
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
diff --git a/gmp/tests/mpf/Makefile.in b/gmp/tests/mpf/Makefile.in
new file mode 100644
index 0000000000..cbc7bef05b
--- /dev/null
+++ b/gmp/tests/mpf/Makefile.in
@@ -0,0 +1,867 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 1996, 1999-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__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+check_PROGRAMS = t-add$(EXEEXT) t-sub$(EXEEXT) t-conv$(EXEEXT) \
+ t-sqrt$(EXEEXT) t-sqrt_ui$(EXEEXT) t-muldiv$(EXEEXT) \
+ t-dm2exp$(EXEEXT) reuse$(EXEEXT) t-cmp_d$(EXEEXT) \
+ t-cmp_si$(EXEEXT) t-div$(EXEEXT) t-fits$(EXEEXT) \
+ t-get_d$(EXEEXT) t-get_d_2exp$(EXEEXT) t-get_si$(EXEEXT) \
+ t-get_ui$(EXEEXT) t-gsprec$(EXEEXT) t-inp_str$(EXEEXT) \
+ t-int_p$(EXEEXT) t-mul_ui$(EXEEXT) t-set$(EXEEXT) \
+ t-set_q$(EXEEXT) t-set_si$(EXEEXT) t-set_ui$(EXEEXT) \
+ t-trunc$(EXEEXT) t-ui_div$(EXEEXT) t-eq$(EXEEXT)
+subdir = tests/mpf
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+reuse_SOURCES = reuse.c
+reuse_OBJECTS = reuse.$(OBJEXT)
+reuse_LDADD = $(LDADD)
+reuse_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_add_SOURCES = t-add.c
+t_add_OBJECTS = t-add.$(OBJEXT)
+t_add_LDADD = $(LDADD)
+t_add_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cmp_d_SOURCES = t-cmp_d.c
+t_cmp_d_OBJECTS = t-cmp_d.$(OBJEXT)
+t_cmp_d_LDADD = $(LDADD)
+t_cmp_d_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cmp_si_SOURCES = t-cmp_si.c
+t_cmp_si_OBJECTS = t-cmp_si.$(OBJEXT)
+t_cmp_si_LDADD = $(LDADD)
+t_cmp_si_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_conv_SOURCES = t-conv.c
+t_conv_OBJECTS = t-conv.$(OBJEXT)
+t_conv_LDADD = $(LDADD)
+t_conv_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_div_SOURCES = t-div.c
+t_div_OBJECTS = t-div.$(OBJEXT)
+t_div_LDADD = $(LDADD)
+t_div_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_dm2exp_SOURCES = t-dm2exp.c
+t_dm2exp_OBJECTS = t-dm2exp.$(OBJEXT)
+t_dm2exp_LDADD = $(LDADD)
+t_dm2exp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_eq_SOURCES = t-eq.c
+t_eq_OBJECTS = t-eq.$(OBJEXT)
+t_eq_LDADD = $(LDADD)
+t_eq_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_fits_SOURCES = t-fits.c
+t_fits_OBJECTS = t-fits.$(OBJEXT)
+t_fits_LDADD = $(LDADD)
+t_fits_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_d_SOURCES = t-get_d.c
+t_get_d_OBJECTS = t-get_d.$(OBJEXT)
+t_get_d_LDADD = $(LDADD)
+t_get_d_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_d_2exp_SOURCES = t-get_d_2exp.c
+t_get_d_2exp_OBJECTS = t-get_d_2exp.$(OBJEXT)
+t_get_d_2exp_LDADD = $(LDADD)
+t_get_d_2exp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_si_SOURCES = t-get_si.c
+t_get_si_OBJECTS = t-get_si.$(OBJEXT)
+t_get_si_LDADD = $(LDADD)
+t_get_si_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_ui_SOURCES = t-get_ui.c
+t_get_ui_OBJECTS = t-get_ui.$(OBJEXT)
+t_get_ui_LDADD = $(LDADD)
+t_get_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_gsprec_SOURCES = t-gsprec.c
+t_gsprec_OBJECTS = t-gsprec.$(OBJEXT)
+t_gsprec_LDADD = $(LDADD)
+t_gsprec_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_inp_str_SOURCES = t-inp_str.c
+t_inp_str_OBJECTS = t-inp_str.$(OBJEXT)
+t_inp_str_LDADD = $(LDADD)
+t_inp_str_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_int_p_SOURCES = t-int_p.c
+t_int_p_OBJECTS = t-int_p.$(OBJEXT)
+t_int_p_LDADD = $(LDADD)
+t_int_p_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mul_ui_SOURCES = t-mul_ui.c
+t_mul_ui_OBJECTS = t-mul_ui.$(OBJEXT)
+t_mul_ui_LDADD = $(LDADD)
+t_mul_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_muldiv_SOURCES = t-muldiv.c
+t_muldiv_OBJECTS = t-muldiv.$(OBJEXT)
+t_muldiv_LDADD = $(LDADD)
+t_muldiv_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_SOURCES = t-set.c
+t_set_OBJECTS = t-set.$(OBJEXT)
+t_set_LDADD = $(LDADD)
+t_set_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_q_SOURCES = t-set_q.c
+t_set_q_OBJECTS = t-set_q.$(OBJEXT)
+t_set_q_LDADD = $(LDADD)
+t_set_q_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_si_SOURCES = t-set_si.c
+t_set_si_OBJECTS = t-set_si.$(OBJEXT)
+t_set_si_LDADD = $(LDADD)
+t_set_si_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_ui_SOURCES = t-set_ui.c
+t_set_ui_OBJECTS = t-set_ui.$(OBJEXT)
+t_set_ui_LDADD = $(LDADD)
+t_set_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_sqrt_SOURCES = t-sqrt.c
+t_sqrt_OBJECTS = t-sqrt.$(OBJEXT)
+t_sqrt_LDADD = $(LDADD)
+t_sqrt_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_sqrt_ui_SOURCES = t-sqrt_ui.c
+t_sqrt_ui_OBJECTS = t-sqrt_ui.$(OBJEXT)
+t_sqrt_ui_LDADD = $(LDADD)
+t_sqrt_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_sub_SOURCES = t-sub.c
+t_sub_OBJECTS = t-sub.$(OBJEXT)
+t_sub_LDADD = $(LDADD)
+t_sub_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_trunc_SOURCES = t-trunc.c
+t_trunc_OBJECTS = t-trunc.$(OBJEXT)
+t_trunc_LDADD = $(LDADD)
+t_trunc_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_ui_div_SOURCES = t-ui_div.c
+t_ui_div_OBJECTS = t-ui_div.$(OBJEXT)
+t_ui_div_LDADD = $(LDADD)
+t_ui_div_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = reuse.c t-add.c t-cmp_d.c t-cmp_si.c t-conv.c t-div.c \
+ t-dm2exp.c t-eq.c t-fits.c t-get_d.c t-get_d_2exp.c t-get_si.c \
+ t-get_ui.c t-gsprec.c t-inp_str.c t-int_p.c t-mul_ui.c \
+ t-muldiv.c t-set.c t-set_q.c t-set_si.c t-set_ui.c t-sqrt.c \
+ t-sqrt_ui.c t-sub.c t-trunc.c t-ui_div.c
+DIST_SOURCES = reuse.c t-add.c t-cmp_d.c t-cmp_si.c t-conv.c t-div.c \
+ t-dm2exp.c t-eq.c t-fits.c t-get_d.c t-get_d_2exp.c t-get_si.c \
+ t-get_ui.c t-gsprec.c t-inp_str.c t-int_p.c t-mul_ui.c \
+ t-muldiv.c t-set.c t-set_q.c t-set_si.c t-set_ui.c t-sqrt.c \
+ t-sqrt_ui.c t-sub.c t-trunc.c t-ui_div.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+TESTS = $(check_PROGRAMS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/mpf/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps tests/mpf/Makefile
+.PRECIOUS: 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
+reuse$(EXEEXT): $(reuse_OBJECTS) $(reuse_DEPENDENCIES) $(EXTRA_reuse_DEPENDENCIES)
+ @rm -f reuse$(EXEEXT)
+ $(LINK) $(reuse_OBJECTS) $(reuse_LDADD) $(LIBS)
+t-add$(EXEEXT): $(t_add_OBJECTS) $(t_add_DEPENDENCIES) $(EXTRA_t_add_DEPENDENCIES)
+ @rm -f t-add$(EXEEXT)
+ $(LINK) $(t_add_OBJECTS) $(t_add_LDADD) $(LIBS)
+t-cmp_d$(EXEEXT): $(t_cmp_d_OBJECTS) $(t_cmp_d_DEPENDENCIES) $(EXTRA_t_cmp_d_DEPENDENCIES)
+ @rm -f t-cmp_d$(EXEEXT)
+ $(LINK) $(t_cmp_d_OBJECTS) $(t_cmp_d_LDADD) $(LIBS)
+t-cmp_si$(EXEEXT): $(t_cmp_si_OBJECTS) $(t_cmp_si_DEPENDENCIES) $(EXTRA_t_cmp_si_DEPENDENCIES)
+ @rm -f t-cmp_si$(EXEEXT)
+ $(LINK) $(t_cmp_si_OBJECTS) $(t_cmp_si_LDADD) $(LIBS)
+t-conv$(EXEEXT): $(t_conv_OBJECTS) $(t_conv_DEPENDENCIES) $(EXTRA_t_conv_DEPENDENCIES)
+ @rm -f t-conv$(EXEEXT)
+ $(LINK) $(t_conv_OBJECTS) $(t_conv_LDADD) $(LIBS)
+t-div$(EXEEXT): $(t_div_OBJECTS) $(t_div_DEPENDENCIES) $(EXTRA_t_div_DEPENDENCIES)
+ @rm -f t-div$(EXEEXT)
+ $(LINK) $(t_div_OBJECTS) $(t_div_LDADD) $(LIBS)
+t-dm2exp$(EXEEXT): $(t_dm2exp_OBJECTS) $(t_dm2exp_DEPENDENCIES) $(EXTRA_t_dm2exp_DEPENDENCIES)
+ @rm -f t-dm2exp$(EXEEXT)
+ $(LINK) $(t_dm2exp_OBJECTS) $(t_dm2exp_LDADD) $(LIBS)
+t-eq$(EXEEXT): $(t_eq_OBJECTS) $(t_eq_DEPENDENCIES) $(EXTRA_t_eq_DEPENDENCIES)
+ @rm -f t-eq$(EXEEXT)
+ $(LINK) $(t_eq_OBJECTS) $(t_eq_LDADD) $(LIBS)
+t-fits$(EXEEXT): $(t_fits_OBJECTS) $(t_fits_DEPENDENCIES) $(EXTRA_t_fits_DEPENDENCIES)
+ @rm -f t-fits$(EXEEXT)
+ $(LINK) $(t_fits_OBJECTS) $(t_fits_LDADD) $(LIBS)
+t-get_d$(EXEEXT): $(t_get_d_OBJECTS) $(t_get_d_DEPENDENCIES) $(EXTRA_t_get_d_DEPENDENCIES)
+ @rm -f t-get_d$(EXEEXT)
+ $(LINK) $(t_get_d_OBJECTS) $(t_get_d_LDADD) $(LIBS)
+t-get_d_2exp$(EXEEXT): $(t_get_d_2exp_OBJECTS) $(t_get_d_2exp_DEPENDENCIES) $(EXTRA_t_get_d_2exp_DEPENDENCIES)
+ @rm -f t-get_d_2exp$(EXEEXT)
+ $(LINK) $(t_get_d_2exp_OBJECTS) $(t_get_d_2exp_LDADD) $(LIBS)
+t-get_si$(EXEEXT): $(t_get_si_OBJECTS) $(t_get_si_DEPENDENCIES) $(EXTRA_t_get_si_DEPENDENCIES)
+ @rm -f t-get_si$(EXEEXT)
+ $(LINK) $(t_get_si_OBJECTS) $(t_get_si_LDADD) $(LIBS)
+t-get_ui$(EXEEXT): $(t_get_ui_OBJECTS) $(t_get_ui_DEPENDENCIES) $(EXTRA_t_get_ui_DEPENDENCIES)
+ @rm -f t-get_ui$(EXEEXT)
+ $(LINK) $(t_get_ui_OBJECTS) $(t_get_ui_LDADD) $(LIBS)
+t-gsprec$(EXEEXT): $(t_gsprec_OBJECTS) $(t_gsprec_DEPENDENCIES) $(EXTRA_t_gsprec_DEPENDENCIES)
+ @rm -f t-gsprec$(EXEEXT)
+ $(LINK) $(t_gsprec_OBJECTS) $(t_gsprec_LDADD) $(LIBS)
+t-inp_str$(EXEEXT): $(t_inp_str_OBJECTS) $(t_inp_str_DEPENDENCIES) $(EXTRA_t_inp_str_DEPENDENCIES)
+ @rm -f t-inp_str$(EXEEXT)
+ $(LINK) $(t_inp_str_OBJECTS) $(t_inp_str_LDADD) $(LIBS)
+t-int_p$(EXEEXT): $(t_int_p_OBJECTS) $(t_int_p_DEPENDENCIES) $(EXTRA_t_int_p_DEPENDENCIES)
+ @rm -f t-int_p$(EXEEXT)
+ $(LINK) $(t_int_p_OBJECTS) $(t_int_p_LDADD) $(LIBS)
+t-mul_ui$(EXEEXT): $(t_mul_ui_OBJECTS) $(t_mul_ui_DEPENDENCIES) $(EXTRA_t_mul_ui_DEPENDENCIES)
+ @rm -f t-mul_ui$(EXEEXT)
+ $(LINK) $(t_mul_ui_OBJECTS) $(t_mul_ui_LDADD) $(LIBS)
+t-muldiv$(EXEEXT): $(t_muldiv_OBJECTS) $(t_muldiv_DEPENDENCIES) $(EXTRA_t_muldiv_DEPENDENCIES)
+ @rm -f t-muldiv$(EXEEXT)
+ $(LINK) $(t_muldiv_OBJECTS) $(t_muldiv_LDADD) $(LIBS)
+t-set$(EXEEXT): $(t_set_OBJECTS) $(t_set_DEPENDENCIES) $(EXTRA_t_set_DEPENDENCIES)
+ @rm -f t-set$(EXEEXT)
+ $(LINK) $(t_set_OBJECTS) $(t_set_LDADD) $(LIBS)
+t-set_q$(EXEEXT): $(t_set_q_OBJECTS) $(t_set_q_DEPENDENCIES) $(EXTRA_t_set_q_DEPENDENCIES)
+ @rm -f t-set_q$(EXEEXT)
+ $(LINK) $(t_set_q_OBJECTS) $(t_set_q_LDADD) $(LIBS)
+t-set_si$(EXEEXT): $(t_set_si_OBJECTS) $(t_set_si_DEPENDENCIES) $(EXTRA_t_set_si_DEPENDENCIES)
+ @rm -f t-set_si$(EXEEXT)
+ $(LINK) $(t_set_si_OBJECTS) $(t_set_si_LDADD) $(LIBS)
+t-set_ui$(EXEEXT): $(t_set_ui_OBJECTS) $(t_set_ui_DEPENDENCIES) $(EXTRA_t_set_ui_DEPENDENCIES)
+ @rm -f t-set_ui$(EXEEXT)
+ $(LINK) $(t_set_ui_OBJECTS) $(t_set_ui_LDADD) $(LIBS)
+t-sqrt$(EXEEXT): $(t_sqrt_OBJECTS) $(t_sqrt_DEPENDENCIES) $(EXTRA_t_sqrt_DEPENDENCIES)
+ @rm -f t-sqrt$(EXEEXT)
+ $(LINK) $(t_sqrt_OBJECTS) $(t_sqrt_LDADD) $(LIBS)
+t-sqrt_ui$(EXEEXT): $(t_sqrt_ui_OBJECTS) $(t_sqrt_ui_DEPENDENCIES) $(EXTRA_t_sqrt_ui_DEPENDENCIES)
+ @rm -f t-sqrt_ui$(EXEEXT)
+ $(LINK) $(t_sqrt_ui_OBJECTS) $(t_sqrt_ui_LDADD) $(LIBS)
+t-sub$(EXEEXT): $(t_sub_OBJECTS) $(t_sub_DEPENDENCIES) $(EXTRA_t_sub_DEPENDENCIES)
+ @rm -f t-sub$(EXEEXT)
+ $(LINK) $(t_sub_OBJECTS) $(t_sub_LDADD) $(LIBS)
+t-trunc$(EXEEXT): $(t_trunc_OBJECTS) $(t_trunc_DEPENDENCIES) $(EXTRA_t_trunc_DEPENDENCIES)
+ @rm -f t-trunc$(EXEEXT)
+ $(LINK) $(t_trunc_OBJECTS) $(t_trunc_LDADD) $(LIBS)
+t-ui_div$(EXEEXT): $(t_ui_div_OBJECTS) $(t_ui_div_DEPENDENCIES) $(EXTRA_t_ui_div_DEPENDENCIES)
+ @rm -f t-ui_div$(EXEEXT)
+ $(LINK) $(t_ui_div_OBJECTS) $(t_ui_div_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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:
+
+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 all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool ctags \
+ 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 \
+ tags uninstall uninstall-am
+
+
+$(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/gmp/tests/mpf/reuse.c b/gmp/tests/mpf/reuse.c
new file mode 100644
index 0000000000..3a382530b6
--- /dev/null
+++ b/gmp/tests/mpf/reuse.c
@@ -0,0 +1,219 @@
+/* Test that routines allow reusing a source variable as destination.
+
+Copyright 1996, 2000-2002, 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#if __GMP_LIBGMP_DLL
+
+/* FIXME: When linking to a DLL libgmp, mpf_add etc can't be used as
+ initializers for global variables because they're effectively global
+ variables (function pointers) themselves. Perhaps calling a test
+ function successively with mpf_add etc would be better. */
+
+int
+main (void)
+{
+ printf ("Test suppressed for windows DLL\n");
+ exit (0);
+}
+
+
+#else /* ! DLL_EXPORT */
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+#ifndef EXPO
+#define EXPO 32
+#endif
+
+void dump_abort (const char *, mpf_t, mpf_t);
+
+typedef void (*dss_func) (mpf_ptr, mpf_srcptr, mpf_srcptr);
+
+dss_func dss_funcs[] =
+{
+ mpf_div, mpf_add, mpf_mul, mpf_sub,
+};
+
+const char *dss_func_names[] =
+{
+ "mpf_div", "mpf_add", "mpf_mul", "mpf_sub",
+};
+
+typedef void (*dsi_func) (mpf_ptr, mpf_srcptr, unsigned long int);
+
+dsi_func dsi_funcs[] =
+{
+ mpf_div_ui, mpf_add_ui, mpf_mul_ui, mpf_sub_ui,
+ mpf_mul_2exp, mpf_div_2exp, mpf_pow_ui
+};
+
+const char *dsi_func_names[] =
+{
+ "mpf_div_ui", "mpf_add_ui", "mpf_mul_ui", "mpf_sub_ui",
+ "mpf_mul_2exp", "mpf_div_2exp", "mpf_pow_ui"
+};
+
+typedef void (*dis_func) (mpf_ptr, unsigned long int, mpf_srcptr);
+
+dis_func dis_funcs[] =
+{
+ mpf_ui_div, mpf_ui_sub,
+};
+
+const char *dis_func_names[] =
+{
+ "mpf_ui_div", "mpf_ui_sub",
+};
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ int pass, reps = 10000;
+ mpf_t in1, in2, out1;
+ unsigned long int in1i, in2i;
+ mpf_t res1, res2, res3;
+ mp_size_t bprec = 100;
+
+ tests_start ();
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init (in1);
+ mpf_init (in2);
+ mpf_init (out1);
+ mpf_init (res1);
+ mpf_init (res2);
+ mpf_init (res3);
+
+ for (pass = 1; pass <= reps; pass++)
+ {
+ mpf_random2 (in1, urandom () % SIZE - SIZE/2, urandom () % EXPO);
+ mpf_random2 (in2, urandom () % SIZE - SIZE/2, urandom () % EXPO);
+
+ for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
+ {
+ /* Don't divide by 0. */
+ if (i == 0 && mpf_cmp_ui (in2, 0) == 0)
+ continue;
+
+ (dss_funcs[i]) (res1, in1, in2);
+
+ mpf_set (out1, in1);
+ (dss_funcs[i]) (out1, out1, in2);
+ mpf_set (res2, out1);
+
+ mpf_set (out1, in2);
+ (dss_funcs[i]) (out1, in1, out1);
+ mpf_set (res3, out1);
+
+ if (mpf_cmp (res1, res2) != 0)
+ dump_abort (dss_func_names[i], res1, res2);
+ if (mpf_cmp (res1, res3) != 0)
+ dump_abort (dss_func_names[i], res1, res3);
+ }
+
+ in2i = urandom ();
+ for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++)
+ {
+ unsigned long this_in2i = in2i;
+
+ /* Don't divide by 0. */
+ if (dsi_funcs[i] == mpf_div_ui && this_in2i == 0)
+ continue;
+
+ /* Avoid overflow/underflow in the exponent. */
+ if (dsi_funcs[i] == mpf_mul_2exp || dsi_funcs[i] == mpf_div_2exp)
+ this_in2i %= 0x100000;
+ else if (dsi_funcs[i] == mpf_pow_ui)
+ this_in2i %= 0x1000;
+
+ (dsi_funcs[i]) (res1, in1, this_in2i);
+
+ mpf_set (out1, in1);
+ (dsi_funcs[i]) (out1, out1, this_in2i);
+ mpf_set (res2, out1);
+
+ if (mpf_cmp (res1, res2) != 0)
+ dump_abort (dsi_func_names[i], res1, res2);
+ }
+
+ in1i = urandom ();
+ for (i = 0; i < sizeof (dis_funcs) / sizeof (dis_func); i++)
+ {
+ /* Don't divide by 0. */
+ if (dis_funcs[i] == mpf_ui_div
+ && mpf_cmp_ui (in2, 0) == 0)
+ continue;
+
+ (dis_funcs[i]) (res1, in1i, in2);
+
+ mpf_set (out1, in2);
+ (dis_funcs[i]) (out1, in1i, out1);
+ mpf_set (res2, out1);
+
+ if (mpf_cmp (res1, res2) != 0)
+ dump_abort (dis_func_names[i], res1, res2);
+ }
+
+ }
+
+ mpf_clear (in1);
+ mpf_clear (in2);
+ mpf_clear (out1);
+ mpf_clear (res1);
+ mpf_clear (res2);
+ mpf_clear (res3);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort (const char *name, mpf_t res1, mpf_t res2)
+{
+ printf ("failure in %s:\n", name);
+ mpf_dump (res1);
+ mpf_dump (res2);
+ abort ();
+}
+
+#if 0
+void mpf_abs (mpf_ptr, mpf_srcptr);
+void mpf_sqrt (mpf_ptr, mpf_srcptr);
+void mpf_neg (mpf_ptr, mpf_srcptr);
+#endif
+
+#endif /* ! DLL_EXPORT */
diff --git a/gmp/tests/mpf/t-add.c b/gmp/tests/mpf/t-add.c
new file mode 100644
index 0000000000..dacc6382e4
--- /dev/null
+++ b/gmp/tests/mpf/t-add.c
@@ -0,0 +1,108 @@
+/* Test mpf_add.
+
+Copyright 1996, 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mp_size_t size;
+ mp_exp_t exp;
+ int reps = 20000;
+ int i;
+ mpf_t u, v, w, wref;
+ mp_size_t bprec = 100;
+ mpf_t rerr, max_rerr, limit_rerr;
+
+ tests_start ();
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, bprec);
+#if VERBOSE
+ mpf_dump (limit_rerr);
+#endif
+ mpf_init (rerr);
+ mpf_init_set_ui (max_rerr, 0);
+
+ mpf_init (u);
+ mpf_init (v);
+ mpf_init (w);
+ mpf_init (wref);
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (u, size, exp);
+
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (v, size, exp);
+
+ mpf_add (w, u, v);
+ refmpf_add (wref, u, v);
+
+ mpf_reldiff (rerr, w, wref);
+ if (mpf_cmp (rerr, max_rerr) > 0)
+ {
+ mpf_set (max_rerr, rerr);
+#if VERBOSE
+ mpf_dump (max_rerr);
+#endif
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf ("wref = "); mpf_dump (wref);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+ }
+ }
+
+ mpf_clear (limit_rerr);
+ mpf_clear (rerr);
+ mpf_clear (max_rerr);
+
+ mpf_clear (u);
+ mpf_clear (v);
+ mpf_clear (w);
+ mpf_clear (wref);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-cmp_d.c b/gmp/tests/mpf/t-cmp_d.c
new file mode 100644
index 0000000000..a1cbbadb17
--- /dev/null
+++ b/gmp/tests/mpf/t-cmp_d.c
@@ -0,0 +1,104 @@
+/* Test mpf_cmp_d.
+
+Copyright 2001, 2003, 2003, 2005 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#define SGN(n) ((n) > 0 ? 1 : (n) < 0 ? -1 : 0)
+
+void
+check_one (const char *name, mpf_srcptr x, double y, int cmp)
+{
+ int got;
+
+ got = mpf_cmp_d (x, y);
+ if (SGN(got) != cmp)
+ {
+ int i;
+ printf ("mpf_cmp_d wrong (from %s)\n", name);
+ printf (" got %d\n", got);
+ printf (" want %d\n", cmp);
+ mpf_trace (" x", x);
+ printf (" y %g\n", y);
+ mp_trace_base=-16;
+ mpf_trace (" x", x);
+ printf (" y %g\n", y);
+ printf (" y");
+ for (i = 0; i < sizeof(y); i++)
+ printf (" %02X", (unsigned) ((unsigned char *) &y)[i]);
+ printf ("\n");
+ abort ();
+ }
+}
+
+void
+check_infinity (void)
+{
+ mpf_t x;
+ double y = tests_infinity_d ();
+ if (y == 0.0)
+ return;
+
+ mpf_init (x);
+
+ /* 0 cmp inf */
+ mpf_set_ui (x, 0L);
+ check_one ("check_infinity", x, y, -1);
+ check_one ("check_infinity", x, -y, 1);
+
+ /* 123 cmp inf */
+ mpf_set_ui (x, 123L);
+ check_one ("check_infinity", x, y, -1);
+ check_one ("check_infinity", x, -y, 1);
+
+ /* -123 cmp inf */
+ mpf_set_si (x, -123L);
+ check_one ("check_infinity", x, y, -1);
+ check_one ("check_infinity", x, -y, 1);
+
+ /* 2^5000 cmp inf */
+ mpf_set_ui (x, 1L);
+ mpf_mul_2exp (x, x, 5000L);
+ check_one ("check_infinity", x, y, -1);
+ check_one ("check_infinity", x, -y, 1);
+
+ /* -2^5000 cmp inf */
+ mpf_neg (x, x);
+ check_one ("check_infinity", x, y, -1);
+ check_one ("check_infinity", x, -y, 1);
+
+ mpf_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ check_infinity ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-cmp_si.c b/gmp/tests/mpf/t-cmp_si.c
new file mode 100644
index 0000000000..3bf016ff28
--- /dev/null
+++ b/gmp/tests/mpf/t-cmp_si.c
@@ -0,0 +1,107 @@
+/* Test mpf_cmp_si.
+
+Copyright 2000, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define SGN(x) ((x) < 0 ? -1 : (x) == 0 ? 0 : 1)
+
+void
+check_data (void)
+{
+ static const struct {
+ int a_base;
+ const char *a;
+ const char *b;
+ int want;
+ } data[] = {
+ { 10, "0", "1", -1 },
+ { 10, "0", "0", 0 },
+ { 10, "0", "-1", 1 },
+
+ { 10, "1", "1", 0 },
+ { 10, "1", "0", 1 },
+ { 10, "1", "-1", 1 },
+
+ { 10, "-1", "1", -1 },
+ { 10, "-1", "0", -1 },
+ { 10, "-1", "-1", 0 },
+
+ { 16, "0", "-0x80000000", 1 },
+ { 16, "80000000", "-0x80000000", 1 },
+ { 16, "80000001", "-0x80000000", 1 },
+ { 16, "-80000000", "-0x80000000", 0 },
+ { 16, "-80000001", "-0x80000000", -1 },
+ { 16, "-FF0080000001", "-0x80000000", -1 },
+
+ { 16, "0", "-0x8000000000000000", 1 },
+ { 16, "8000000000000000", "-0x8000000000000000", 1 },
+ { 16, "8000000000000001", "-0x8000000000000000", 1 },
+ { 16, "-8000000000000000", "-0x8000000000000000", 0 },
+ { 16, "-8000000000000001", "-0x8000000000000000", -1 },
+ { 16, "-FF008000000000000001", "-0x8000000000000000", -1 },
+ };
+
+ mpf_t a;
+ mpz_t bz;
+ long b;
+ int got;
+ int i;
+
+ mpf_init (a);
+ mpz_init (bz);
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpf_set_str_or_abort (a, data[i].a, data[i].a_base);
+ mpz_set_str_or_abort (bz, data[i].b, 0);
+
+ if (mpz_fits_slong_p (bz))
+ {
+ b = mpz_get_si (bz);
+ got = mpf_cmp_si (a, b);
+ if (SGN (got) != data[i].want)
+ {
+ printf ("mpf_cmp_si wrong on data[%d]\n", i);
+ printf (" a="); mpf_out_str (stdout, 10, 0, a);
+ printf (" (%s)\n", data[i].a);
+ printf (" b=%ld (%s)\n", b, data[i].b);
+ printf (" got=%d\n", got);
+ printf (" want=%d\n", data[i].want);
+ abort();
+ }
+ }
+ }
+
+ mpf_clear (a);
+ mpz_clear (bz);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-conv.c b/gmp/tests/mpf/t-conv.c
new file mode 100644
index 0000000000..3b47866061
--- /dev/null
+++ b/gmp/tests/mpf/t-conv.c
@@ -0,0 +1,143 @@
+/* Test mpf_get_str and mpf_set_str.
+
+Copyright 1996, 2000, 2001, 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for strlen */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef SIZE
+#define SIZE 10
+#endif
+
+#ifndef EXPO
+#define EXPO 200
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mpf_t x, y;
+ int reps = 20000;
+ int i;
+ mp_size_t bprec = 100;
+ mpf_t d, rerr, max_rerr, limit_rerr;
+ char *str;
+ mp_exp_t bexp;
+ long size, exp;
+ int base;
+ char buf[SIZE * GMP_LIMB_BITS + 5];
+
+ tests_start ();
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, bprec);
+#if VERBOSE
+ mpf_dump (limit_rerr);
+#endif
+ mpf_init (rerr);
+ mpf_init_set_ui (max_rerr, 0);
+
+ mpf_init (x);
+ mpf_init (y);
+ mpf_init (d);
+
+ /* First test some specific values. */
+
+ mpf_set_str (y, "1.23456e1000", 0);
+
+ mpf_set_str (x, "1.23456e1000", 10);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "1.23456e+1000", 0);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+ mpf_set_str (x, "1.23456e+1000", 10);
+ if (mpf_cmp (x, y) != 0)
+ abort ();
+
+ /* Now test random values. */
+
+ for (i = 0; i < reps; i++)
+ {
+ if (i == 0)
+ {
+ /* exercise the special case in get_str for for x==0 */
+ mpf_set_ui (x, 0L);
+ base = 10;
+ }
+ else
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % EXPO;
+ mpf_random2 (x, size, exp);
+ base = urandom () % 61 + 2;
+ }
+
+ str = mpf_get_str (0, &bexp, base, 0, x);
+
+ if (str[0] == '-')
+ sprintf (buf, "-0.%s@%ld", str + 1, bexp);
+ else
+ sprintf (buf, "0.%s@%ld", str, bexp);
+
+ mpf_set_str_or_abort (y, buf, -base);
+ (*__gmp_free_func) (str, strlen (str) + 1);
+
+ mpf_reldiff (rerr, x, y);
+ if (mpf_cmp (rerr, max_rerr) > 0)
+ {
+ mpf_set (max_rerr, rerr);
+#if VERBOSE
+ mpf_dump (max_rerr);
+#endif
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR after %d tests\n", i);
+ printf ("base = %d\n", base);
+ printf (" x = "); mpf_dump (x);
+ printf (" y = "); mpf_dump (y);
+ abort ();
+ }
+ }
+ }
+
+ mpf_clear (limit_rerr);
+ mpf_clear (rerr);
+ mpf_clear (max_rerr);
+
+ mpf_clear (x);
+ mpf_clear (y);
+ mpf_clear (d);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-div.c b/gmp/tests/mpf/t-div.c
new file mode 100644
index 0000000000..2f34eabaca
--- /dev/null
+++ b/gmp/tests/mpf/t-div.c
@@ -0,0 +1,186 @@
+/* Test mpf_div.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpf_srcptr v)
+{
+ if (! refmpf_validate_division ("mpf_div", got, u, v))
+ {
+ mp_trace_base = -16;
+ mpf_trace (" u", u);
+ mpf_trace (" v", v);
+ printf (" %s\n", desc);
+ abort ();
+ }
+}
+
+void
+check_rand (void)
+{
+ unsigned long min_prec = __GMPF_BITS_TO_PREC (1);
+ gmp_randstate_ptr rands = RANDS;
+ unsigned long prec;
+ mpf_t got, u, v;
+ int i;
+
+ mpf_init (got);
+ mpf_init (u);
+ mpf_init (v);
+
+ /* separate */
+ for (i = 0; i < 100; i++)
+ {
+ /* got precision */
+ prec = min_prec + gmp_urandomm_ui (rands, 15L);
+ refmpf_set_prec_limbs (got, prec);
+
+ /* u */
+ prec = min_prec + gmp_urandomm_ui (rands, 15L);
+ refmpf_set_prec_limbs (u, prec);
+ do {
+ mpf_random2 (u, PREC(u), (mp_exp_t) 20);
+ } while (SIZ(u) == 0);
+ if (gmp_urandomb_ui (rands, 1L))
+ mpf_neg (u, u);
+
+ /* v */
+ prec = min_prec + gmp_urandomm_ui (rands, 15L);
+ refmpf_set_prec_limbs (v, prec);
+ do {
+ mpf_random2 (v, PREC(v), (mp_exp_t) 20);
+ } while (SIZ(v) == 0);
+ if (gmp_urandomb_ui (rands, 1L))
+ mpf_neg (v, v);
+
+ switch (i % 3) {
+ case 0:
+ mpf_div (got, u, v);
+ check_one ("separate", got, u, v);
+ break;
+ case 1:
+ prec = refmpf_set_overlap (got, u);
+ mpf_div (got, got, v);
+ check_one ("dst == u", got, u, v);
+ mpf_set_prec_raw (got, prec);
+ break;
+ case 2:
+ prec = refmpf_set_overlap (got, v);
+ mpf_div (got, u, got);
+ check_one ("dst == v", got, u, v);
+ mpf_set_prec_raw (got, prec);
+ break;
+ }
+ }
+
+ mpf_clear (got);
+ mpf_clear (u);
+ mpf_clear (v);
+}
+
+/* Exercise calls mpf(x,x,x) */
+void
+check_reuse_three (void)
+{
+ unsigned long min_prec = __GMPF_BITS_TO_PREC (1);
+ gmp_randstate_ptr rands = RANDS;
+ unsigned long result_prec, input_prec, set_prec;
+ mpf_t got;
+ int i;
+
+ mpf_init (got);
+
+ for (i = 0; i < 8; i++)
+ {
+ result_prec = min_prec + gmp_urandomm_ui (rands, 15L);
+ input_prec = min_prec + gmp_urandomm_ui (rands, 15L);
+
+ set_prec = MAX (result_prec, input_prec);
+ refmpf_set_prec_limbs (got, set_prec);
+
+ /* input, non-zero, possibly negative */
+ PREC(got) = input_prec;
+ do {
+ mpf_random2 (got, input_prec, (mp_exp_t) 20);
+ } while (SIZ(got) == 0);
+ if (gmp_urandomb_ui (rands, 1L))
+ mpf_neg (got, got);
+
+ PREC(got) = result_prec;
+
+ mpf_div (got, got, got);
+
+ /* expect exactly 1.0 always */
+ ASSERT_ALWAYS (mpf_cmp_ui (got, 1L) == 0);
+
+ PREC(got) = set_prec;
+ }
+
+ mpf_clear (got);
+}
+
+void
+check_various (void)
+{
+ mpf_t got, u, v;
+
+ mpf_init (got);
+ mpf_init (u);
+ mpf_init (v);
+
+ /* 100/4 == 25 */
+ mpf_set_prec (got, 20L);
+ mpf_set_ui (u, 100L);
+ mpf_set_ui (v, 4L);
+ mpf_div (got, u, v);
+ MPF_CHECK_FORMAT (got);
+ ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
+
+ /* 1/(2^n+1), a case where truncating the divisor would be wrong */
+ mpf_set_prec (got, 500L);
+ mpf_set_prec (v, 900L);
+ mpf_set_ui (v, 1L);
+ mpf_mul_2exp (v, v, 800L);
+ mpf_add_ui (v, v, 1L);
+ mpf_div (got, u, v);
+ check_one ("1/2^n+1, separate", got, u, v);
+
+ mpf_clear (got);
+ mpf_clear (u);
+ mpf_clear (v);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_various ();
+ check_rand ();
+ check_reuse_three ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-dm2exp.c b/gmp/tests/mpf/t-dm2exp.c
new file mode 100644
index 0000000000..90e4c18f16
--- /dev/null
+++ b/gmp/tests/mpf/t-dm2exp.c
@@ -0,0 +1,119 @@
+/* Test mpf_div, mpf_div_2exp, mpf_mul_2exp.
+
+Copyright 1996, 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+int
+main (int argc, char **argv)
+{
+ int reps = 100000;
+ int i;
+ mpf_t u, v, w1, w2, w3;
+ mp_size_t bprec = 100;
+ mpf_t rerr, limit_rerr;
+ mp_size_t un;
+ mp_exp_t ue;
+
+ tests_start ();
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init (rerr);
+ mpf_init (limit_rerr);
+
+ mpf_init (u);
+ mpf_init (v);
+ mpf_init (w1);
+ mpf_init (w2);
+ mpf_init (w3);
+
+ for (i = 0; i < reps; i++)
+ {
+ unsigned long int res_prec;
+ unsigned long int pow2;
+
+ res_prec = urandom () % (bprec + 100);
+ mpf_set_prec (w1, res_prec);
+ mpf_set_prec (w2, res_prec);
+ mpf_set_prec (w3, res_prec);
+
+ mpf_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, res_prec);
+
+ pow2 = urandom () % 0x10000;
+ mpf_set_ui (v, 1);
+ mpf_mul_2exp (v, v, pow2);
+
+ un = urandom () % (2 * SIZE) - SIZE;
+ ue = urandom () % SIZE;
+ mpf_random2 (u, un, ue);
+
+ mpf_div_2exp (w1, u, pow2);
+ mpf_div (w2, u, v);
+ mpf_reldiff (rerr, w1, w2);
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR in mpf_div or mpf_div_2exp after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf (" w1 = "); mpf_dump (w1);
+ printf (" w2 = "); mpf_dump (w2);
+ abort ();
+ }
+ mpf_mul_2exp (w3, w1, pow2);
+ mpf_reldiff (rerr, u, w3);
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR in mpf_mul_2exp after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf (" w1 = "); mpf_dump (w1);
+ printf (" w3 = "); mpf_dump (w3);
+ abort ();
+ }
+ }
+
+ mpf_clear (rerr);
+ mpf_clear (limit_rerr);
+
+ mpf_clear (u);
+ mpf_clear (v);
+ mpf_clear (w1);
+ mpf_clear (w2);
+ mpf_clear (w3);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-eq.c b/gmp/tests/mpf/t-eq.c
new file mode 100644
index 0000000000..359fec9316
--- /dev/null
+++ b/gmp/tests/mpf/t-eq.c
@@ -0,0 +1,218 @@
+/* Test mpf_eq.
+
+Copyright 2009, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define SZ (2 * sizeof(mp_limb_t))
+
+void insert_random_low_zero_limbs (mpf_t, gmp_randstate_ptr);
+void dump_abort (mpf_t, mpf_t, int, int, int, int, int, long);
+void hexdump (mpf_t);
+
+void
+check_data (void)
+{
+ static const struct
+ {
+ struct {
+ int exp, size;
+ mp_limb_t d[10];
+ } x, y;
+ mp_bitcnt_t bits;
+ int want;
+
+ } data[] = {
+ { { 0, 0, { 0 } }, { 0, 0, { 0 } }, 0, 1 },
+
+ { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 0, 1 },
+ { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 17, 1 },
+ { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 4711, 1 },
+
+ { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 0, 1 },
+ { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 2, 1 },
+ { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 3, 0 },
+
+ { { 0, 0, { 0 } }, { 0, 1, { 1 } }, 0, 0 },
+ { { 0, 1, { 1 } }, { 0,-1 ,{ 1 } }, 0, 0 },
+ { { 1, 1, { 1 } }, { 0, 1, { 1 } }, 0, 0 },
+
+ { { 0, 1, { 8 } }, { 0, 1, { 4 } }, 0, 0 },
+
+ { { 0, 2, { 0, 3 } }, { 0, 1, { 3 } }, 1000, 1 },
+ };
+
+ mpf_t x, y;
+ int got, got_swapped;
+ int i;
+ mp_trace_base = 16;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ PTR(x) = (mp_ptr) data[i].x.d;
+ SIZ(x) = data[i].x.size;
+ EXP(x) = data[i].x.exp;
+ PREC(x) = numberof (data[i].x.d);
+ MPF_CHECK_FORMAT (x);
+
+ PTR(y) = (mp_ptr) data[i].y.d;
+ SIZ(y) = data[i].y.size;
+ EXP(y) = data[i].y.exp;
+ PREC(y) = numberof (data[i].y.d);
+ MPF_CHECK_FORMAT (y);
+
+ got = mpf_eq (x, y, data[i].bits);
+ got_swapped = mpf_eq (y, x, data[i].bits);
+
+ if (got != got_swapped || got != data[i].want)
+ {
+ printf ("check_data() wrong result at data[%d]\n", i);
+ mpf_trace ("x ", x);
+ mpf_trace ("y ", y);
+ printf ("got %d\n", got);
+ printf ("got_swapped %d\n", got_swapped);
+ printf ("want %d\n", data[i].want);
+ abort ();
+ }
+ }
+}
+
+void
+check_random (long reps)
+{
+ unsigned long test;
+ gmp_randstate_ptr rands = RANDS;
+ mpf_t a, b, x;
+ mpz_t ds;
+ int hibits, lshift1, lshift2;
+ int xtra;
+
+#define HIBITS 10
+#define LSHIFT1 10
+#define LSHIFT2 10
+
+ mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2));
+
+ mpz_init (ds);
+ mpf_inits (a, b, x, NULL);
+
+ for (test = 0; test < reps; test++)
+ {
+ mpz_urandomb (ds, rands, HIBITS);
+ hibits = mpz_get_ui (ds) + 1;
+ mpz_urandomb (ds, rands, hibits);
+ mpz_setbit (ds, hibits - 1); /* make sure msb is set */
+ mpf_set_z (a, ds);
+ mpf_set_z (b, ds);
+
+ mpz_urandomb (ds, rands, LSHIFT1);
+ lshift1 = mpz_get_ui (ds);
+ mpf_mul_2exp (a, a, lshift1 + 1);
+ mpf_mul_2exp (b, b, lshift1 + 1);
+ mpf_add_ui (a, a, 1); /* make a one-bit difference */
+
+ mpz_urandomb (ds, rands, LSHIFT2);
+ lshift2 = mpz_get_ui (ds);
+ mpf_mul_2exp (a, a, lshift2);
+ mpf_mul_2exp (b, b, lshift2);
+ mpz_urandomb (ds, rands, lshift2);
+ mpf_set_z (x, ds);
+ mpf_add (a, a, x);
+ mpf_add (b, b, x);
+
+ insert_random_low_zero_limbs (a, rands);
+ insert_random_low_zero_limbs (b, rands);
+
+ if (mpf_eq (a, b, lshift1 + hibits) == 0 ||
+ mpf_eq (b, a, lshift1 + hibits) == 0)
+ {
+ dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test);
+ }
+ for (xtra = 1; xtra < 100; xtra++)
+ if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0 ||
+ mpf_eq (b, a, lshift1 + hibits + xtra) != 0)
+ {
+ dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test);
+ }
+ }
+
+ mpf_clears (a, b, x, NULL);
+ mpz_clear (ds);
+}
+
+void
+insert_random_low_zero_limbs (mpf_t x, gmp_randstate_ptr rands)
+{
+ mp_size_t max = PREC(x) - SIZ(x);
+ mp_size_t s;
+ mpz_t ds; mpz_init (ds);
+ mpz_urandomb (ds, rands, 32);
+ s = mpz_get_ui (ds) % (max + 1);
+ MPN_COPY_DECR (PTR(x) + s, PTR(x), SIZ(x));
+ MPN_ZERO (PTR(x), s);
+ SIZ(x) += s;
+ mpz_clear (ds);
+}
+
+void
+dump_abort (mpf_t a, mpf_t b, int cmp_prec, int lshift1, int lshift2, int hibits, int want, long test)
+{
+ printf ("ERROR in test %ld\n", test);
+ printf ("want %d got %d from mpf_eq\n", want, 1-want);
+ printf ("cmp_prec = %d\n", cmp_prec);
+ printf ("lshift1 = %d\n", lshift1);
+ printf ("lshift2 = %d\n", lshift2);
+ printf ("hibits = %d\n", hibits);
+ hexdump (a); puts ("");
+ hexdump (b); puts ("");
+ abort ();
+}
+
+void
+hexdump (mpf_t x)
+{
+ mp_size_t i;
+ for (i = ABSIZ(x) - 1; i >= 0; i--)
+ {
+ gmp_printf ("%0*MX", SZ, PTR(x)[i]);
+ if (i != 0)
+ printf (" ");
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ long reps = 10000;
+
+ if (argc == 2)
+ reps = strtol (argv[1], 0, 0);
+
+ tests_start ();
+
+ check_data ();
+ check_random (reps);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-fits.c b/gmp/tests/mpf/t-fits.c
new file mode 100644
index 0000000000..4b0e7c56ba
--- /dev/null
+++ b/gmp/tests/mpf/t-fits.c
@@ -0,0 +1,333 @@
+/* Test mpf_fits_*_p
+
+Copyright 2001, 2002, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Nothing sophisticated here, just exercise mpf_fits_*_p on a small amount
+ of data. */
+
+#define EXPECT_S(fun,name,answer) \
+ got = fun (f); \
+ if (got != answer) \
+ { \
+ printf ("%s (%s) got %d want %d\n", name, expr, got, answer); \
+ printf (" f size %d exp %ld\n", SIZ(f), EXP(f)); \
+ printf (" f dec "); mpf_out_str (stdout, 10, 0, f); printf ("\n"); \
+ printf (" f hex "); mpf_out_str (stdout, 16, 0, f); printf ("\n"); \
+ error = 1; \
+ }
+
+#if HAVE_STRINGIZE
+#define EXPECT(fun,answer) EXPECT_S(fun,#fun,answer)
+#else
+#define EXPECT(fun,answer) EXPECT_S(fun,"fun",answer)
+#endif
+
+int
+main (void)
+{
+ mpf_t f, f0p5;
+ int got;
+ const char *expr;
+ int error = 0;
+
+ tests_start ();
+ mpf_init2 (f, 200L);
+ mpf_init2 (f0p5, 200L);
+
+ /* 0.5 */
+ mpf_set_ui (f0p5, 1L);
+ mpf_div_2exp (f0p5, f0p5, 1L);
+
+ mpf_set_ui (f, 0L);
+ expr = "0";
+ EXPECT (mpf_fits_ulong_p, 1);
+ EXPECT (mpf_fits_uint_p, 1);
+ EXPECT (mpf_fits_ushort_p, 1);
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+ mpf_set_ui (f, 1L);
+ expr = "1";
+ EXPECT (mpf_fits_ulong_p, 1);
+ EXPECT (mpf_fits_uint_p, 1);
+ EXPECT (mpf_fits_ushort_p, 1);
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+ mpf_set_si (f, -1L);
+ expr = "-1";
+ EXPECT (mpf_fits_ulong_p, 0);
+ EXPECT (mpf_fits_uint_p, 0);
+ EXPECT (mpf_fits_ushort_p, 0);
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+
+ mpf_set_ui (f, (unsigned long) USHRT_MAX);
+ expr = "USHRT_MAX";
+ EXPECT (mpf_fits_ulong_p, 1);
+ EXPECT (mpf_fits_uint_p, 1);
+ EXPECT (mpf_fits_ushort_p, 1);
+
+ mpf_set_ui (f, (unsigned long) USHRT_MAX);
+ mpf_add (f, f, f0p5);
+ expr = "USHRT_MAX + 0.5";
+ EXPECT (mpf_fits_ulong_p, 1);
+ EXPECT (mpf_fits_uint_p, 1);
+ EXPECT (mpf_fits_ushort_p, 1);
+
+ mpf_set_ui (f, (unsigned long) USHRT_MAX);
+ mpf_add_ui (f, f, 1L);
+ expr = "USHRT_MAX + 1";
+ EXPECT (mpf_fits_ushort_p, 0);
+
+
+ mpf_set_ui (f, (unsigned long) UINT_MAX);
+ expr = "UINT_MAX";
+ EXPECT (mpf_fits_ulong_p, 1);
+ EXPECT (mpf_fits_uint_p, 1);
+
+ mpf_set_ui (f, (unsigned long) UINT_MAX);
+ mpf_add (f, f, f0p5);
+ expr = "UINT_MAX + 0.5";
+ EXPECT (mpf_fits_ulong_p, 1);
+ EXPECT (mpf_fits_uint_p, 1);
+
+ mpf_set_ui (f, (unsigned long) UINT_MAX);
+ mpf_add_ui (f, f, 1L);
+ expr = "UINT_MAX + 1";
+ EXPECT (mpf_fits_uint_p, 0);
+
+
+ mpf_set_ui (f, ULONG_MAX);
+ expr = "ULONG_MAX";
+ EXPECT (mpf_fits_ulong_p, 1);
+
+ mpf_set_ui (f, ULONG_MAX);
+ mpf_add (f, f, f0p5);
+ expr = "ULONG_MAX + 0.5";
+ EXPECT (mpf_fits_ulong_p, 1);
+
+ mpf_set_ui (f, ULONG_MAX);
+ mpf_add_ui (f, f, 1L);
+ expr = "ULONG_MAX + 1";
+ EXPECT (mpf_fits_ulong_p, 0);
+
+
+ mpf_set_si (f, (long) SHRT_MAX);
+ expr = "SHRT_MAX";
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+ mpf_set_si (f, (long) SHRT_MAX);
+ expr = "SHRT_MAX + 0.5";
+ mpf_add (f, f, f0p5);
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+ mpf_set_si (f, (long) SHRT_MAX);
+ mpf_add_ui (f, f, 1L);
+ expr = "SHRT_MAX + 1";
+ EXPECT (mpf_fits_sshort_p, 0);
+
+
+ mpf_set_si (f, (long) INT_MAX);
+ expr = "INT_MAX";
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+
+ mpf_set_si (f, (long) INT_MAX);
+ mpf_add (f, f, f0p5);
+ expr = "INT_MAX + 0.5";
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+
+ mpf_set_si (f, (long) INT_MAX);
+ mpf_add_ui (f, f, 1L);
+ expr = "INT_MAX + 1";
+ EXPECT (mpf_fits_sint_p, 0);
+
+
+ mpf_set_si (f, LONG_MAX);
+ expr = "LONG_MAX";
+ EXPECT (mpf_fits_slong_p, 1);
+
+ mpf_set_si (f, LONG_MAX);
+ mpf_add (f, f, f0p5);
+ expr = "LONG_MAX + 0.5";
+ EXPECT (mpf_fits_slong_p, 1);
+
+ mpf_set_si (f, LONG_MAX);
+ mpf_add_ui (f, f, 1L);
+ expr = "LONG_MAX + 1";
+ EXPECT (mpf_fits_slong_p, 0);
+
+
+ mpf_set_si (f, (long) SHRT_MIN);
+ expr = "SHRT_MIN";
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+ mpf_set_si (f, (long) SHRT_MIN);
+ mpf_sub (f, f, f0p5);
+ expr = "SHRT_MIN - 0.5";
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+ mpf_set_si (f, (long) SHRT_MIN);
+ mpf_sub_ui (f, f, 1L);
+ expr = "SHRT_MIN - 1";
+ EXPECT (mpf_fits_sshort_p, 0);
+
+
+ mpf_set_si (f, (long) INT_MIN);
+ expr = "INT_MIN";
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+
+ mpf_set_si (f, (long) INT_MIN);
+ mpf_sub (f, f, f0p5);
+ expr = "INT_MIN - 0.5";
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+
+ mpf_set_si (f, (long) INT_MIN);
+ mpf_sub_ui (f, f, 1L);
+ expr = "INT_MIN - 1";
+ EXPECT (mpf_fits_sint_p, 0);
+
+
+ mpf_set_si (f, LONG_MIN);
+ expr = "LONG_MIN";
+ EXPECT (mpf_fits_slong_p, 1);
+
+ mpf_set_si (f, LONG_MIN);
+ mpf_sub (f, f, f0p5);
+ expr = "LONG_MIN - 0.5";
+ EXPECT (mpf_fits_slong_p, 1);
+
+ mpf_set_si (f, LONG_MIN);
+ mpf_sub_ui (f, f, 1L);
+ expr = "LONG_MIN - 1";
+ EXPECT (mpf_fits_slong_p, 0);
+
+
+ mpf_set_str_or_abort (f, "0.5", 10);
+ expr = "0.5";
+ EXPECT (mpf_fits_ulong_p, 1);
+ EXPECT (mpf_fits_uint_p, 1);
+ EXPECT (mpf_fits_ushort_p, 1);
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+ mpf_set_str_or_abort (f, "-0.5", 10);
+ expr = "-0.5";
+ EXPECT (mpf_fits_ulong_p, 1);
+ EXPECT (mpf_fits_uint_p, 1);
+ EXPECT (mpf_fits_ushort_p, 1);
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+ mpf_set_str_or_abort (f, "-1.5", 10);
+ expr = "-1.5";
+ EXPECT (mpf_fits_ulong_p, 0);
+ EXPECT (mpf_fits_uint_p, 0);
+ EXPECT (mpf_fits_ushort_p, 0);
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+
+ mpf_set_str_or_abort (f, "1.000000000000000000000000000000000001", 16);
+ expr = "1.000000000000000000000000000000000001 base 16";
+ EXPECT (mpf_fits_ulong_p, 1);
+ EXPECT (mpf_fits_uint_p, 1);
+ EXPECT (mpf_fits_ushort_p, 1);
+ EXPECT (mpf_fits_slong_p, 1);
+ EXPECT (mpf_fits_sint_p, 1);
+ EXPECT (mpf_fits_sshort_p, 1);
+
+ mpf_set_str_or_abort (f, "1@1000", 16);
+ expr = "1@1000 base 16";
+ EXPECT (mpf_fits_ulong_p, 0);
+ EXPECT (mpf_fits_uint_p, 0);
+ EXPECT (mpf_fits_ushort_p, 0);
+ EXPECT (mpf_fits_slong_p, 0);
+ EXPECT (mpf_fits_sint_p, 0);
+ EXPECT (mpf_fits_sshort_p, 0);
+
+
+ mpf_set_ui (f, 1L);
+ mpf_mul_2exp (f, f, BITS_PER_ULONG + 1);
+ mpf_sub_ui (f, f, 1L);
+ expr = "2^(BITS_PER_ULONG+1) - 1";
+ EXPECT (mpf_fits_ulong_p, 0);
+ EXPECT (mpf_fits_uint_p, 0);
+ EXPECT (mpf_fits_ushort_p, 0);
+ EXPECT (mpf_fits_slong_p, 0);
+ EXPECT (mpf_fits_sint_p, 0);
+ EXPECT (mpf_fits_sshort_p, 0);
+
+ mpf_set_ui (f, 1L);
+ mpf_mul_2exp (f, f, BITS_PER_ULONG + 1);
+ mpf_sub_ui (f, f, 1L);
+ mpf_neg (f, f);
+ expr = "- (2^(BITS_PER_ULONG+1) - 1)";
+ EXPECT (mpf_fits_ulong_p, 0);
+ EXPECT (mpf_fits_uint_p, 0);
+ EXPECT (mpf_fits_ushort_p, 0);
+ EXPECT (mpf_fits_slong_p, 0);
+ EXPECT (mpf_fits_sint_p, 0);
+ EXPECT (mpf_fits_sshort_p, 0);
+
+ mpf_set_ui (f, 1L);
+ mpf_mul_2exp (f, f, BITS_PER_ULONG + 5);
+ mpf_sub_ui (f, f, 1L);
+ expr = "2^(BITS_PER_ULONG+5) - 1";
+ EXPECT (mpf_fits_ulong_p, 0);
+ EXPECT (mpf_fits_uint_p, 0);
+ EXPECT (mpf_fits_ushort_p, 0);
+ EXPECT (mpf_fits_slong_p, 0);
+ EXPECT (mpf_fits_sint_p, 0);
+ EXPECT (mpf_fits_sshort_p, 0);
+
+
+ if (error)
+ abort ();
+
+ mpf_clear (f);
+ mpf_clear (f0p5);
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-get_d.c b/gmp/tests/mpf/t-get_d.c
new file mode 100644
index 0000000000..66b9623f90
--- /dev/null
+++ b/gmp/tests/mpf/t-get_d.c
@@ -0,0 +1,106 @@
+/* Test mpf_get_d and mpf_set_d.
+
+Copyright 1996, 1999-2001, 2009 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "tests.h"
+
+#if defined (__vax) || defined (__vax__)
+#define LOW_BOUND 1e-38
+#define HIGH_BOUND 8e37
+#endif
+
+#if defined (_CRAY) && ! defined (_CRAYIEEE)
+/* The range varies mysteriously between Cray version. On an SV1,
+ the range seem to be 1e-600..1e603, but a cfp (non-ieee) T90
+ has a much smaller range of 1e-240..1e240. */
+#define LOW_BOUND 1e-240
+#define HIGH_BOUND 1e240
+#endif
+
+#if ! defined (LOW_BOUND)
+#define LOW_BOUND 1e-300
+#define HIGH_BOUND 1e300
+#endif
+
+void
+test_denorms (int prc)
+{
+#ifdef _GMP_IEEE_FLOATS
+ double d1, d2;
+ mpf_t f;
+ int i;
+
+ mpf_set_default_prec (prc);
+
+ mpf_init (f);
+
+ d1 = 1.9;
+ for (i = 0; i < 820; i++)
+ {
+ mpf_set_d (f, d1);
+ d2 = mpf_get_d (f);
+ if (d1 != d2)
+ abort ();
+ d1 *= 0.4;
+ }
+
+ mpf_clear (f);
+#endif
+}
+
+int
+main (int argc, char **argv)
+{
+ double d, e, r;
+ mpf_t u, v;
+
+ tests_start ();
+ mpf_init (u);
+ mpf_init (v);
+
+ mpf_set_d (u, LOW_BOUND);
+ for (d = 2.0 * LOW_BOUND; d < HIGH_BOUND; d *= 1.01)
+ {
+ mpf_set_d (v, d);
+ if (mpf_cmp (u, v) >= 0)
+ abort ();
+ e = mpf_get_d (v);
+ r = e/d;
+ if (r < 0.99999999999999 || r > 1.00000000000001)
+ {
+ fprintf (stderr, "should be one ulp from 1: %.16f\n", r);
+ abort ();
+ }
+ mpf_set (u, v);
+ }
+
+ mpf_clear (u);
+ mpf_clear (v);
+
+ test_denorms (10);
+ test_denorms (32);
+ test_denorms (64);
+ test_denorms (100);
+ test_denorms (200);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-get_d_2exp.c b/gmp/tests/mpf/t-get_d_2exp.c
new file mode 100644
index 0000000000..891e51d5a5
--- /dev/null
+++ b/gmp/tests/mpf/t-get_d_2exp.c
@@ -0,0 +1,121 @@
+/* Test mpf_get_d_2exp.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+static void
+check_onebit (void)
+{
+ static const long data[] = {
+ -513, -512, -511, -65, -64, -63, -32, -1,
+ 0, 1, 32, 53, 54, 64, 128, 256, 511, 512, 513
+ };
+ mpf_t f;
+ double got, want;
+ long got_exp, want_exp;
+ int i;
+
+ mpf_init2 (f, 1024L);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpf_set_ui (f, 1L);
+ if (data[i] >= 0)
+ mpf_mul_2exp (f, f, data[i]);
+ else
+ mpf_div_2exp (f, f, -data[i]);
+ want = 0.5;
+ want_exp = data[i] + 1;
+
+ got = mpf_get_d_2exp (&got_exp, f);
+ if (got != want || got_exp != want_exp)
+ {
+ printf ("mpf_get_d_2exp wrong on 2**%ld\n", data[i]);
+ mpf_trace (" f ", f);
+ d_trace (" want ", want);
+ d_trace (" got ", got);
+ printf (" want exp %ld\n", want_exp);
+ printf (" got exp %ld\n", got_exp);
+ abort();
+ }
+ }
+ mpf_clear (f);
+}
+
+/* Check that hardware rounding doesn't make mpf_get_d_2exp return a value
+ outside its defined range. */
+static void
+check_round (void)
+{
+ static const unsigned long data[] = { 1, 32, 53, 54, 64, 128, 256, 512 };
+ mpf_t f;
+ double got;
+ long got_exp;
+ int i, rnd_mode, old_rnd_mode;
+
+ mpf_init2 (f, 1024L);
+ old_rnd_mode = tests_hardware_getround ();
+
+ for (rnd_mode = 0; rnd_mode < 4; rnd_mode++)
+ {
+ tests_hardware_setround (rnd_mode);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpf_set_ui (f, 1L);
+ mpf_mul_2exp (f, f, data[i]);
+ mpf_sub_ui (f, f, 1L);
+
+ got = mpf_get_d_2exp (&got_exp, f);
+ if (got < 0.5 || got >= 1.0)
+ {
+ printf ("mpf_get_d_2exp bad on 2**%lu-1\n", data[i]);
+ printf ("result out of range, expect 0.5 <= got < 1.0\n");
+ printf (" rnd_mode = %d\n", rnd_mode);
+ printf (" data[i] = %lu\n", data[i]);
+ mpf_trace (" f ", f);
+ d_trace (" got ", got);
+ printf (" got exp %ld\n", got_exp);
+ abort();
+ }
+ }
+ }
+
+ mpf_clear (f);
+ tests_hardware_setround (old_rnd_mode);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = 16;
+
+ check_onebit ();
+ check_round ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-get_si.c b/gmp/tests/mpf/t-get_si.c
new file mode 100644
index 0000000000..80362616d7
--- /dev/null
+++ b/gmp/tests/mpf/t-get_si.c
@@ -0,0 +1,223 @@
+/* Exercise mpz_get_si.
+
+Copyright 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_data (void)
+{
+ static const struct {
+ int base;
+ const char *f;
+ long want;
+ } data[] = {
+ { 10, "0", 0L },
+ { 10, "1", 1L },
+ { 10, "-1", -1L },
+ { 10, "2", 2L },
+ { 10, "-2", -2L },
+ { 10, "12345", 12345L },
+ { 10, "-12345", -12345L },
+
+ /* fraction bits ignored */
+ { 10, "0.5", 0L },
+ { 10, "-0.5", 0L },
+ { 10, "1.1", 1L },
+ { 10, "-1.1", -1L },
+ { 10, "1.9", 1L },
+ { 10, "-1.9", -1L },
+ { 16, "1.000000000000000000000000000000000000000000000000001", 1L },
+ { 16, "-1.000000000000000000000000000000000000000000000000001", -1L },
+
+ /* low bits extracted (this is undocumented) */
+ { 16, "1000000000000000000000000000000000000000000000000001", 1L },
+ { 16, "-1000000000000000000000000000000000000000000000000001", -1L },
+ };
+
+ int i;
+ mpf_t f;
+ long got;
+
+ mpf_init2 (f, 2000L);
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpf_set_str_or_abort (f, data[i].f, data[i].base);
+
+ got = mpf_get_si (f);
+ if (got != data[i].want)
+ {
+ printf ("mpf_get_si wrong at data[%d]\n", i);
+ printf (" f \"%s\"\n", data[i].f);
+ printf (" dec "); mpf_out_str (stdout, 10, 0, f); printf ("\n");
+ printf (" hex "); mpf_out_str (stdout, 16, 0, f); printf ("\n");
+ printf (" size %ld\n", (long) SIZ(f));
+ printf (" exp %ld\n", (long) EXP(f));
+ printf (" got %ld (0x%lX)\n", got, got);
+ printf (" want %ld (0x%lX)\n", data[i].want, data[i].want);
+ abort();
+ }
+ }
+ mpf_clear (f);
+}
+
+
+void
+check_max (void)
+{
+ mpf_t f;
+ long want;
+ long got;
+
+ mpf_init2 (f, 200L);
+
+#define CHECK_MAX(name) \
+ if (got != want) \
+ { \
+ printf ("mpf_get_si wrong on %s\n", name); \
+ printf (" f "); \
+ mpf_out_str (stdout, 10, 0, f); printf (", hex "); \
+ mpf_out_str (stdout, 16, 0, f); printf ("\n"); \
+ printf (" got %ld, hex %lX\n", got, got); \
+ printf (" want %ld, hex %lX\n", want, want); \
+ abort(); \
+ }
+
+ want = LONG_MAX;
+ mpf_set_si (f, want);
+ got = mpf_get_si (f);
+ CHECK_MAX ("LONG_MAX");
+
+ want = LONG_MIN;
+ mpf_set_si (f, want);
+ got = mpf_get_si (f);
+ CHECK_MAX ("LONG_MIN");
+
+ mpf_clear (f);
+}
+
+
+void
+check_limbdata (void)
+{
+#define M GMP_NUMB_MAX
+
+ static const struct {
+ mp_exp_t exp;
+ mp_size_t size;
+ mp_limb_t d[10];
+ unsigned long want;
+
+ } data[] = {
+
+ /* in the comments here, a "_" indicates a digit (ie. limb) position not
+ included in the d data, and therefore zero */
+
+ { 0, 0, { 0 }, 0L }, /* 0 */
+
+ { 1, 1, { 1 }, 1L }, /* 1 */
+ { 1, -1, { 1 }, -1L }, /* -1 */
+
+ { 0, 1, { 1 }, 0L }, /* .1 */
+ { 0, -1, { 1 }, 0L }, /* -.1 */
+
+ { -1, 1, { 1 }, 0L }, /* ._1 */
+ { -1, -1, { 1 }, 0L }, /* -._1 */
+
+ { -999, 1, { 1 }, 0L }, /* .___1 small */
+ { MP_EXP_T_MIN, 1, { 1 }, 0L }, /* .____1 very small */
+
+ { 999, 1, { 1 }, 0L }, /* 1____. big */
+ { MP_EXP_T_MAX, 1, { 1 }, 0L }, /* 1_____. very big */
+
+ { 1, 2, { 999, 2 }, 2L }, /* 2.9 */
+ { 5, 8, { 7, 8, 9, 3, 0, 0, 0, 1 }, 3L }, /* 10003.987 */
+
+ { 2, 2, { M, M }, LONG_MAX }, /* FF. */
+ { 2, 2, { M, M, M }, LONG_MAX }, /* FF.F */
+ { 3, 3, { M, M, M }, LONG_MAX }, /* FFF. */
+
+#if GMP_NUMB_BITS >= BITS_PER_ULONG
+ /* normal case, numb bigger than long */
+ { 2, 1, { 1 }, 0L }, /* 1_. */
+ { 2, 2, { 0, 1 }, 0L }, /* 10. */
+ { 2, 2, { 999, 1 }, 999L }, /* 19. */
+ { 3, 2, { 999, 1 }, 0L }, /* 19_. */
+
+#else
+ /* nails case, numb smaller than long */
+ { 2, 1, { 1 }, 1L << GMP_NUMB_BITS }, /* 1_. */
+ { 3, 1, { 1 }, 0L }, /* 1__. */
+
+ { 2, 2, { 99, 1 }, 99L + (1L << GMP_NUMB_BITS) }, /* 19. */
+ { 3, 2, { 1, 99 }, 1L << GMP_NUMB_BITS }, /* 91_. */
+ { 3, 3, { 0, 1, 99 }, 1L << GMP_NUMB_BITS }, /* 910. */
+
+#endif
+ };
+
+ mpf_t f;
+ unsigned long got;
+ int i;
+ mp_limb_t buf[20 + numberof(data[i].d)];
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ refmpn_fill (buf, 10, CNST_LIMB(0xDEADBEEF));
+ refmpn_copy (buf+10, data[i].d, ABS(data[i].size));
+ refmpn_fill (buf+10+ABS(data[i].size), 10, CNST_LIMB(0xDEADBEEF));
+
+ PTR(f) = buf+10;
+ EXP(f) = data[i].exp;
+ SIZ(f) = data[i].size;
+ PREC(f) = numberof (data[i].d);
+ MPF_CHECK_FORMAT (f);
+
+ got = mpf_get_si (f);
+ if (got != data[i].want)
+ {
+ printf ("mpf_get_si wrong at limb data[%d]\n", i);
+ mpf_trace (" f", f);
+ mpn_trace (" d", data[i].d, data[i].size);
+ printf (" size %ld\n", (long) data[i].size);
+ printf (" exp %ld\n", (long) data[i].exp);
+ printf (" got %lu (0x%lX)\n", got, got);
+ printf (" want %lu (0x%lX)\n", data[i].want, data[i].want);
+ abort();
+ }
+ }
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+ check_max ();
+ check_limbdata ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-get_ui.c b/gmp/tests/mpf/t-get_ui.c
new file mode 100644
index 0000000000..2950cadaa5
--- /dev/null
+++ b/gmp/tests/mpf/t-get_ui.c
@@ -0,0 +1,128 @@
+/* Exercise mpf_get_ui.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_limbdata (void)
+{
+#define M GMP_NUMB_MAX
+
+ static const struct {
+ mp_exp_t exp;
+ mp_size_t size;
+ mp_limb_t d[10];
+ unsigned long want;
+
+ } data[] = {
+
+ /* in the comments here, a "_" indicates a digit (ie. limb) position not
+ included in the d data, and therefore zero */
+
+ { 0, 0, { 0 }, 0L }, /* 0 */
+
+ { 1, 1, { 1 }, 1L }, /* 1 */
+ { 1, -1, { 1 }, 1L }, /* -1 */
+
+ { 0, 1, { 1 }, 0L }, /* .1 */
+ { 0, -1, { 1 }, 0L }, /* -.1 */
+
+ { -1, 1, { 1 }, 0L }, /* ._1 */
+ { -1, -1, { 1 }, 0L }, /* -._1 */
+
+ { -999, 1, { 1 }, 0L }, /* .___1 small */
+ { MP_EXP_T_MIN, 1, { 1 }, 0L }, /* .____1 very small */
+
+ { 999, 1, { 1 }, 0L }, /* 1____. big */
+ { MP_EXP_T_MAX, 1, { 1 }, 0L }, /* 1_____. very big */
+
+ { 1, 2, { 999, 2 }, 2L }, /* 2.9 */
+ { 5, 8, { 7, 8, 9, 3, 0, 0, 0, 1 }, 3L }, /* 10003.987 */
+
+ { 2, 2, { M, M }, ULONG_MAX }, /* FF. */
+ { 2, 2, { M, M, M }, ULONG_MAX }, /* FF.F */
+ { 3, 3, { M, M, M }, ULONG_MAX }, /* FFF. */
+
+#if GMP_NUMB_BITS >= BITS_PER_ULONG
+ /* normal case, numb bigger than long */
+ { 2, 1, { 1 }, 0L }, /* 1_. */
+ { 2, 2, { 0, 1 }, 0L }, /* 10. */
+ { 2, 2, { 999, 1 }, 999L }, /* 19. */
+ { 3, 2, { 999, 1 }, 0L }, /* 19_. */
+
+#else
+ /* nails case, numb smaller than long */
+ { 2, 1, { 1 }, 1L << GMP_NUMB_BITS }, /* 1_. */
+ { 3, 1, { 1 }, 0L }, /* 1__. */
+
+ { 2, 2, { 99, 1 }, 99L + (1L << GMP_NUMB_BITS) }, /* 19. */
+ { 3, 2, { 1, 99 }, 1L << GMP_NUMB_BITS }, /* 91_. */
+ { 3, 3, { 0, 1, 99 }, 1L << GMP_NUMB_BITS }, /* 910. */
+
+#endif
+ };
+
+ mpf_t f;
+ unsigned long got;
+ int i;
+ mp_limb_t buf[20 + numberof(data[i].d)];
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ refmpn_fill (buf, 10, CNST_LIMB(0xDEADBEEF));
+ refmpn_copy (buf+10, data[i].d, ABS(data[i].size));
+ refmpn_fill (buf+10+ABS(data[i].size), 10, CNST_LIMB(0xDEADBEEF));
+
+ PTR(f) = buf+10;
+ EXP(f) = data[i].exp;
+ SIZ(f) = data[i].size;
+ PREC(f) = numberof (data[i].d);
+ MPF_CHECK_FORMAT (f);
+
+ got = mpf_get_ui (f);
+ if (got != data[i].want)
+ {
+ printf ("mpf_get_ui wrong at limb data[%d]\n", i);
+ mpf_trace (" f", f);
+ mpn_trace (" d", data[i].d, data[i].size);
+ printf (" size %ld\n", (long) data[i].size);
+ printf (" exp %ld\n", (long) data[i].exp);
+ printf (" got %lu (0x%lX)\n", got, got);
+ printf (" want %lu (0x%lX)\n", data[i].want, data[i].want);
+ abort();
+ }
+ }
+}
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = 16;
+
+ check_limbdata ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-gsprec.c b/gmp/tests/mpf/t-gsprec.c
new file mode 100644
index 0000000000..5a7615fc26
--- /dev/null
+++ b/gmp/tests/mpf/t-gsprec.c
@@ -0,0 +1,62 @@
+/* Test mpf_get_prec and mpf_set_prec.
+
+Copyright 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void
+check_consistency (void)
+{
+ mpf_t x;
+ unsigned long i, a, b;
+
+ mpf_init (x);
+
+ for (i = 1; i < 2000; i++)
+ {
+ mpf_set_prec (x, i);
+ a = mpf_get_prec (x);
+ mpf_set_prec (x, a);
+ b = mpf_get_prec (x);
+ if (a != b)
+ {
+ printf ("mpf_get_prec / mpf_set_prec inconsistent\n");
+ printf (" set %lu gives %lu, but then set %lu gives %lu\n",
+ i, a,
+ a, b);
+ abort ();
+ }
+ }
+
+ mpf_clear (x);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_consistency ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-inp_str.c b/gmp/tests/mpf/t-inp_str.c
new file mode 100644
index 0000000000..38b54e6a0d
--- /dev/null
+++ b/gmp/tests/mpf/t-inp_str.c
@@ -0,0 +1,192 @@
+/* Test mpf_inp_str.
+
+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 "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for unlink */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#define FILENAME "t-inp_str.tmp"
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *inp;
+ int base;
+ const char *want;
+ int want_nread;
+
+ } data[] = {
+
+ { "0", 10, "0", 1 },
+
+ { "abc", 10, "0", 0 },
+ { "ghi", 16, "0", 0 },
+
+ { "125", 10, "125", 3 },
+ { "125e1", 10, "1250", 5 },
+ { "12e+2", 10, "1200", 5 },
+ { "125e-1", 10, "12.5", 6 },
+
+ { "ff", 16, "255", 2 },
+ { "-ff", 16, "-255", 3 },
+ { "FF", 16, "255", 2 },
+ { "-FF", 16, "-255", 3 },
+
+ { "100", 16, "256", 3 },
+ { "100@1", 16, "4096", 5 },
+ { "100@10", 16, "4722366482869645213696", 6 },
+ { "100@10", -16, "281474976710656", 6 },
+ { "100@-1", 16, "16", 6 },
+ { "10000000000000000@-10", 16, "1", 21 },
+ { "10000000000@-10", -16, "1", 15 },
+
+ { "z", 36, "35", 1 },
+ { "Z", 36, "35", 1 },
+ { "z@1", 36, "1260", 3 },
+ { "Z@1", 36, "1260", 3 },
+
+ { "0", 0, "0", 1 },
+ };
+
+ mpf_t got, want;
+ long ftell_nread;
+ int i, pre, post, j, got_nread, want_nread;
+ FILE *fp;
+
+ mpf_init (got);
+ mpf_init (want);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ for (pre = 0; pre <= 3; pre++)
+ {
+ for (post = 0; post <= 2; post++)
+ {
+ mpf_set_str_or_abort (want, data[i].want, 10);
+ MPF_CHECK_FORMAT (want);
+
+ /* create the file new each time to ensure its length is what
+ we want */
+ fp = fopen (FILENAME, "w+");
+ ASSERT_ALWAYS (fp != NULL);
+ for (j = 0; j < pre; j++)
+ putc (' ', fp);
+ fputs (data[i].inp, fp);
+ for (j = 0; j < post; j++)
+ putc (' ', fp);
+ fflush (fp);
+ ASSERT_ALWAYS (! ferror(fp));
+
+ rewind (fp);
+ got_nread = mpf_inp_str (got, fp, data[i].base);
+
+ if (got_nread != 0)
+ {
+ ftell_nread = ftell (fp);
+ if (got_nread != ftell_nread)
+ {
+ printf ("mpf_inp_str nread wrong\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ printf (" pre %d\n", pre);
+ printf (" post %d\n", post);
+ printf (" got_nread %d\n", got_nread);
+ printf (" ftell_nread %ld\n", ftell_nread);
+ abort ();
+ }
+ }
+
+ /* if data[i].inp is a whole string to read and there's no post
+ whitespace then expect to have EOF */
+ if (post == 0 && data[i].want_nread == strlen(data[i].inp))
+ {
+ int c = getc(fp);
+ if (c != EOF)
+ {
+ printf ("mpf_inp_str didn't read to EOF\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ printf (" pre %d\n", pre);
+ printf (" post %d\n", post);
+ printf (" c '%c' %#x\n", c, c);
+ abort ();
+ }
+ }
+
+ /* only expect "pre" included in the count when non-zero */
+ want_nread = data[i].want_nread;
+ if (want_nread != 0)
+ want_nread += pre;
+
+ if (got_nread != want_nread)
+ {
+ printf ("mpf_inp_str nread wrong\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ printf (" pre %d\n", pre);
+ printf (" post %d\n", post);
+ printf (" got_nread %d\n", got_nread);
+ printf (" want_nread %d\n", want_nread);
+ abort ();
+ }
+
+ MPF_CHECK_FORMAT (got);
+
+ if (mpf_cmp (got, want) != 0)
+ {
+ printf ("mpf_inp_str wrong result\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ mpf_trace (" got ", got);
+ mpf_trace (" want", want);
+ abort ();
+ }
+
+ ASSERT_ALWAYS (fclose (fp) == 0);
+ }
+ }
+ }
+
+ mpf_clear (got);
+ mpf_clear (want);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ unlink (FILENAME);
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-int_p.c b/gmp/tests/mpf/t-int_p.c
new file mode 100644
index 0000000000..ea07668a1d
--- /dev/null
+++ b/gmp/tests/mpf/t-int_p.c
@@ -0,0 +1,84 @@
+/* Test mpf_integer_p.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+one (mpf_srcptr f, int want)
+{
+ int got;
+ got = mpf_integer_p (f);
+ if (got != want)
+ {
+ printf ("mpf_integer_p got %d want %d\n", got, want);
+ mpf_trace (" f", f);
+ abort ();
+ }
+}
+
+void
+all (mpf_ptr f, int want)
+{
+ one (f, want);
+ mpf_neg (f, f);
+ one (f, want);
+}
+
+int
+main (void)
+{
+ mpf_t f;
+
+ tests_start ();
+ mpf_init2 (f, 200L);
+
+ mpf_set_ui (f, 0L);
+ one (f, 1);
+
+ mpf_set_ui (f, 1L);
+ all (f, 1);
+
+ mpf_set_ui (f, 1L);
+ mpf_div_2exp (f, f, 1L);
+ all (f, 0);
+
+ mpf_set_ui (f, 1L);
+ mpf_div_2exp (f, f, 5000L);
+ all (f, 0);
+
+ mpf_set_ui (f, 1L);
+ mpf_mul_2exp (f, f, 5000L);
+ all (f, 1);
+
+ mpf_set_str (f, "0.5", 10);
+ all (f, 0);
+
+ mpf_set_ui (f, 1L);
+ mpf_div_ui (f, f, 3L);
+ all (f, 0);
+
+ mpf_clear (f);
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-mul_ui.c b/gmp/tests/mpf/t-mul_ui.c
new file mode 100644
index 0000000000..6a25c79477
--- /dev/null
+++ b/gmp/tests/mpf/t-mul_ui.c
@@ -0,0 +1,165 @@
+/* Exercise mpf_mul_ui.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (const char *desc, mpf_ptr got, mpf_srcptr u, unsigned long v)
+{
+ mp_size_t usize, usign;
+ mp_ptr wp;
+ mpf_t want;
+
+ MPF_CHECK_FORMAT (got);
+
+ /* this code not nailified yet */
+ ASSERT_ALWAYS (BITS_PER_ULONG <= GMP_NUMB_BITS);
+ usign = SIZ (u);
+ usize = ABS (usign);
+ wp = refmpn_malloc_limbs (usize + 1);
+ wp[usize] = mpn_mul_1 (wp, PTR(u), usize, (mp_limb_t) v);
+
+ PTR(want) = wp;
+ SIZ(want) = (usign >= 0 ? usize+1 : -(usize+1));
+ EXP(want) = EXP(u) + 1;
+ refmpf_normalize (want);
+
+ if (! refmpf_validate ("mpf_mul_ui", got, want))
+ {
+ mp_trace_base = -16;
+ printf (" %s\n", desc);
+ mpf_trace (" u", u);
+ printf (" v %ld 0x%lX\n", v, v);
+ abort ();
+ }
+
+ free (wp);
+}
+
+void
+check_rand (void)
+{
+ unsigned long min_prec = __GMPF_BITS_TO_PREC (1);
+ gmp_randstate_ptr rands = RANDS;
+ mpf_t got, u;
+ unsigned long prec, v;
+ int i;
+
+ /* The nails code in mpf_mul_ui currently isn't exact, so suppress these
+ tests for now. */
+ if (BITS_PER_ULONG > GMP_NUMB_BITS)
+ return;
+
+ mpf_init (got);
+ mpf_init (u);
+
+ for (i = 0; i < 200; i++)
+ {
+ /* got precision */
+ prec = min_prec + gmp_urandomm_ui (rands, 15L);
+ refmpf_set_prec_limbs (got, prec);
+
+ /* u precision */
+ prec = min_prec + gmp_urandomm_ui (rands, 15L);
+ refmpf_set_prec_limbs (u, prec);
+
+ /* u, possibly negative */
+ mpf_random2 (u, PREC(u), (mp_exp_t) 20);
+ if (gmp_urandomb_ui (rands, 1L))
+ mpf_neg (u, u);
+
+ /* v, 0 to BITS_PER_ULONG bits (inclusive) */
+ prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
+ v = gmp_urandomb_ui (rands, prec);
+
+ if ((i % 2) == 0)
+ {
+ /* separate */
+ mpf_mul_ui (got, u, v);
+ check_one ("separate", got, u, v);
+ }
+ else
+ {
+ /* overlap */
+ prec = refmpf_set_overlap (got, u);
+ mpf_mul_ui (got, got, v);
+ check_one ("overlap src==dst", got, u, v);
+
+ mpf_set_prec_raw (got, prec);
+ }
+ }
+
+ mpf_clear (got);
+ mpf_clear (u);
+}
+
+void
+check_various (void)
+{
+ mpf_t u, got, want;
+ const char *s;
+
+ mpf_init2 (u, 2*8*sizeof(long));
+ mpf_init2 (got, 2*8*sizeof(long));
+ mpf_init2 (want, 2*8*sizeof(long));
+
+ s = "0 * ULONG_MAX";
+ mpf_set_ui (u, 0L);
+ mpf_mul_ui (got, u, ULONG_MAX);
+ MPF_CHECK_FORMAT (got);
+ mpf_set_ui (want, 0L);
+ if (mpf_cmp (got, want) != 0)
+ {
+ error:
+ printf ("Wrong result from %s\n", s);
+ mpf_trace ("u ", u);
+ mpf_trace ("got ", got);
+ mpf_trace ("want", want);
+ abort ();
+ }
+
+ s = "1 * ULONG_MAX";
+ mpf_set_ui (u, 1L);
+ mpf_mul_ui (got, u, ULONG_MAX);
+ MPF_CHECK_FORMAT (got);
+ mpf_set_ui (want, ULONG_MAX);
+ if (mpf_cmp (got, want) != 0)
+ goto error;
+
+ mpf_clear (u);
+ mpf_clear (got);
+ mpf_clear (want);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_various ();
+ check_rand ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-muldiv.c b/gmp/tests/mpf/t-muldiv.c
new file mode 100644
index 0000000000..2751bb9dad
--- /dev/null
+++ b/gmp/tests/mpf/t-muldiv.c
@@ -0,0 +1,159 @@
+/* Test mpf_mul, mpf_div, mpf_ui_div, and mpf_div_ui.
+
+Copyright 1996, 2000, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mp_size_t size;
+ mp_exp_t exp;
+ int reps = 10000;
+ int i;
+ mpf_t u, v, w, x;
+ mp_size_t bprec = SIZE * GMP_LIMB_BITS;
+ mpf_t rerr, limit_rerr;
+ unsigned long ulimb, vlimb;
+ int single_flag;
+
+ tests_start ();
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init (rerr);
+ mpf_init (limit_rerr);
+
+ mpf_init (u);
+ mpf_init (v);
+ mpf_init (w);
+ mpf_init (x);
+
+ for (i = 0; i < reps; i++)
+ {
+ mp_size_t res_prec;
+
+ res_prec = urandom () % bprec + 1;
+ mpf_set_prec (w, res_prec);
+ mpf_set_prec (x, res_prec);
+
+ mpf_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, res_prec - 1);
+
+ single_flag = 0;
+
+ if ((urandom () & 1) != 0)
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (u, size, exp);
+ }
+ else
+ {
+ ulimb = urandom ();
+ mpf_set_ui (u, ulimb);
+ single_flag = 1;
+ }
+
+ if ((urandom () & 1) != 0)
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (v, size, exp);
+ }
+ else
+ {
+ vlimb = urandom ();
+ mpf_set_ui (v, vlimb);
+ single_flag = 2;
+ }
+
+ if (mpf_sgn (v) == 0)
+ continue;
+
+ mpf_div (w, u, v);
+ mpf_mul (x, w, v);
+ mpf_reldiff (rerr, u, x);
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR in mpf_mul or mpf_div after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf (" x = "); mpf_dump (x);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+
+ if (single_flag == 2)
+ {
+ mpf_div_ui (x, u, vlimb);
+ mpf_reldiff (rerr, w, x);
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR in mpf_div or mpf_div_ui after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf (" x = "); mpf_dump (x);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+ }
+
+ if (single_flag == 1)
+ {
+ mpf_ui_div (x, ulimb, v);
+ mpf_reldiff (rerr, w, x);
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR in mpf_div or mpf_ui_div after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf (" x = "); mpf_dump (x);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+ }
+ }
+
+ mpf_clear (rerr);
+ mpf_clear (limit_rerr);
+
+ mpf_clear (u);
+ mpf_clear (v);
+ mpf_clear (w);
+ mpf_clear (x);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-set.c b/gmp/tests/mpf/t-set.c
new file mode 100644
index 0000000000..3846d501a1
--- /dev/null
+++ b/gmp/tests/mpf/t-set.c
@@ -0,0 +1,113 @@
+/* Test mpf_set, mpf_init_set.
+
+Copyright 2004, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void
+check_reuse (void)
+{
+ /* Try mpf_set(f,f) when f is bigger than prec. In the past this had
+ resulted in an MPN_COPY with invalid operand overlap. */
+ mpf_t f;
+ mp_size_t limbs = 20;
+ unsigned long bits = limbs * GMP_NUMB_BITS;
+ mpf_init2 (f, bits);
+ refmpf_fill (f, limbs, GMP_NUMB_MAX);
+ mpf_set_prec_raw (f, bits / 2);
+ mpf_set (f, f);
+ MPF_CHECK_FORMAT (f);
+ mpf_set_prec_raw (f, bits);
+ mpf_clear (f);
+}
+
+void
+check_random (long reps)
+{
+ unsigned long test;
+ gmp_randstate_ptr rands;
+ mpf_t a, b;
+ mpz_t z;
+ int precbits;
+
+#define PRECBITS 10
+
+ rands = RANDS;
+
+ mpz_init (z);
+ mpf_init2 (a, 1 << PRECBITS);
+
+ for (test = 0; test < reps; test++)
+ {
+ mpz_urandomb (z, rands, PRECBITS + 1);
+ precbits = mpz_get_ui (z) + 1;
+ mpz_urandomb (z, rands, precbits);
+ mpz_setbit (z, precbits - 1); /* make sure msb is set */
+ mpf_set_z (a, z);
+ if (precbits & 1)
+ mpf_neg (a, a);
+ mpz_urandomb (z, rands, PRECBITS);
+ mpf_div_2exp (a, a, mpz_get_ui (z) + 1);
+ mpz_urandomb (z, rands, PRECBITS);
+ precbits -= mpz_get_ui (z);
+ if (precbits <= 0)
+ precbits = 1 - precbits;
+ mpf_set_default_prec (precbits);
+
+ mpf_init_set (b, a);
+ MPF_CHECK_FORMAT (b);
+ if (!mpf_eq (a, b, precbits))
+ {
+ printf ("mpf_init_set wrong.\n");
+ abort();
+ }
+
+ mpf_set_ui (b, 0);
+ mpf_set (b, a);
+ MPF_CHECK_FORMAT (b);
+ if (!mpf_eq (a, b, precbits))
+ {
+ printf ("mpf_set wrong.\n");
+ abort();
+ }
+
+ mpf_clear (b);
+ }
+
+ mpf_clear (a);
+ mpz_clear (z);
+}
+
+int
+main (int argc, char *argv[])
+{
+ long reps = 10000;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ check_reuse ();
+ check_random (reps);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-set_q.c b/gmp/tests/mpf/t-set_q.c
new file mode 100644
index 0000000000..2c48b277da
--- /dev/null
+++ b/gmp/tests/mpf/t-set_q.c
@@ -0,0 +1,127 @@
+/* Test mpf_set_q.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpf_ptr got, mpq_srcptr q)
+{
+ mpf_t n, d;
+
+ mpf_set_q (got, q);
+
+ PTR(n) = PTR(&q->_mp_num);
+ SIZ(n) = SIZ(&q->_mp_num);
+ EXP(n) = ABSIZ(&q->_mp_num);
+
+ PTR(d) = PTR(&q->_mp_den);
+ SIZ(d) = SIZ(&q->_mp_den);
+ EXP(d) = ABSIZ(&q->_mp_den);
+
+ if (! refmpf_validate_division ("mpf_set_q", got, n, d))
+ {
+ mp_trace_base = -16;
+ mpq_trace (" q", q);
+ abort ();
+ }
+}
+
+void
+check_rand (void)
+{
+ unsigned long min_prec = __GMPF_BITS_TO_PREC (1);
+ gmp_randstate_ptr rands = RANDS;
+ unsigned long prec;
+ mpf_t got;
+ mpq_t q;
+ int i;
+
+ mpf_init (got);
+ mpq_init (q);
+
+ for (i = 0; i < 400; i++)
+ {
+ /* result precision */
+ prec = min_prec + gmp_urandomm_ui (rands, 20L);
+ refmpf_set_prec_limbs (got, prec);
+
+ /* num */
+ prec = gmp_urandomm_ui (rands, 20L * GMP_NUMB_BITS);
+ mpz_rrandomb (mpq_numref(q), rands, prec);
+
+ /* possibly negative num */
+ if (gmp_urandomb_ui (rands, 1L))
+ mpz_neg (mpq_numref(q), mpq_numref(q));
+
+ /* den, non-zero */
+ do {
+ prec = gmp_urandomm_ui (rands, 20L * GMP_NUMB_BITS);
+ mpz_rrandomb (mpq_denref(q), rands, prec);
+ } while (mpz_sgn (mpq_denref(q)) <= 0);
+
+ check_one (got, q);
+ }
+
+ mpf_clear (got);
+ mpq_clear (q);
+}
+
+void
+check_various (void)
+{
+ mpf_t got;
+ mpq_t q;
+
+ mpf_init (got);
+ mpq_init (q);
+
+ /* 1/1 == 1 */
+ mpf_set_prec (got, 20L);
+ mpq_set_ui (q, 1L, 1L);
+ mpf_set_q (got, q);
+ MPF_CHECK_FORMAT (got);
+ ASSERT_ALWAYS (mpf_cmp_ui (got, 1L) == 0);
+
+ /* 1/(2^n+1), a case where truncating the divisor would be wrong */
+ mpf_set_prec (got, 500L);
+ mpq_set_ui (q, 1L, 1L);
+ mpz_mul_2exp (mpq_denref(q), mpq_denref(q), 800L);
+ mpz_add_ui (mpq_denref(q), mpq_denref(q), 1L);
+ check_one (got, q);
+
+ mpf_clear (got);
+ mpq_clear (q);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_various ();
+ check_rand ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-set_si.c b/gmp/tests/mpf/t-set_si.c
new file mode 100644
index 0000000000..8975be7bed
--- /dev/null
+++ b/gmp/tests/mpf/t-set_si.c
@@ -0,0 +1,91 @@
+/* Test mpf_set_si and mpf_init_set_si.
+
+Copyright 2000, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void
+check_data (void)
+{
+ static const struct {
+ long x;
+ mp_size_t want_size;
+ mp_limb_t want_data[2];
+ } data[] = {
+
+ { 0L, 0 },
+ { 1L, 1, { 1 } },
+ { -1L, -1, { 1 } },
+
+#if GMP_NUMB_BITS >= BITS_PER_ULONG
+ { LONG_MAX, 1, { LONG_MAX, 0 } },
+ { -LONG_MAX, -1, { LONG_MAX, 0 } },
+ { LONG_HIGHBIT, -1, { ULONG_HIGHBIT, 0 } },
+#else
+ { LONG_MAX, 2, { LONG_MAX & GMP_NUMB_MASK, LONG_MAX >> GMP_NUMB_BITS } },
+ { -LONG_MAX, -2, { LONG_MAX & GMP_NUMB_MASK, LONG_MAX >> GMP_NUMB_BITS }},
+ { LONG_HIGHBIT, -2, { 0, ULONG_HIGHBIT >> GMP_NUMB_BITS } },
+#endif
+ };
+
+ mpf_t x;
+ int i;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpf_init (x);
+ mpf_set_si (x, data[i].x);
+ MPF_CHECK_FORMAT (x);
+ if (x->_mp_size != data[i].want_size
+ || refmpn_cmp_allowzero (x->_mp_d, data[i].want_data,
+ ABS (data[i].want_size)) != 0
+ || x->_mp_exp != ABS (data[i].want_size))
+ {
+ printf ("mpf_set_si wrong on data[%d]\n", i);
+ abort();
+ }
+ mpf_clear (x);
+
+ mpf_init_set_si (x, data[i].x);
+ MPF_CHECK_FORMAT (x);
+ if (x->_mp_size != data[i].want_size
+ || refmpn_cmp_allowzero (x->_mp_d, data[i].want_data,
+ ABS (data[i].want_size)) != 0
+ || x->_mp_exp != ABS (data[i].want_size))
+ {
+ printf ("mpf_init_set_si wrong on data[%d]\n", i);
+ abort();
+ }
+ mpf_clear (x);
+ }
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-set_ui.c b/gmp/tests/mpf/t-set_ui.c
new file mode 100644
index 0000000000..8c49e91e67
--- /dev/null
+++ b/gmp/tests/mpf/t-set_ui.c
@@ -0,0 +1,90 @@
+/* Test mpf_set_ui and mpf_init_set_ui.
+
+Copyright 2000, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void
+check_data (void)
+{
+ static const struct {
+ unsigned long x;
+ mp_size_t want_size;
+ mp_limb_t want_data[2];
+ } data[] = {
+
+ { 0L, 0 },
+ { 1L, 1, { 1 } },
+
+#if GMP_NUMB_BITS >= BITS_PER_ULONG
+ { ULONG_MAX, 1, { ULONG_MAX, 0 } },
+ { ULONG_HIGHBIT, 1, { ULONG_HIGHBIT, 0 } },
+#else
+ { ULONG_MAX, 2, { ULONG_MAX & GMP_NUMB_MASK,
+ ULONG_MAX >> GMP_NUMB_BITS } },
+ { ULONG_HIGHBIT, 2, { 0,
+ ULONG_HIGHBIT >> GMP_NUMB_BITS } },
+#endif
+ };
+
+ mpf_t x;
+ int i;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpf_init (x);
+ mpf_set_ui (x, data[i].x);
+ MPF_CHECK_FORMAT (x);
+ if (x->_mp_size != data[i].want_size
+ || refmpn_cmp_allowzero (x->_mp_d, data[i].want_data,
+ ABS (data[i].want_size)) != 0
+ || x->_mp_exp != ABS (data[i].want_size))
+ {
+ printf ("mpf_set_ui wrong on data[%d]\n", i);
+ abort();
+ }
+ mpf_clear (x);
+
+ mpf_init_set_ui (x, data[i].x);
+ MPF_CHECK_FORMAT (x);
+ if (x->_mp_size != data[i].want_size
+ || refmpn_cmp_allowzero (x->_mp_d, data[i].want_data,
+ ABS (data[i].want_size)) != 0
+ || x->_mp_exp != ABS (data[i].want_size))
+ {
+ printf ("mpf_init_set_ui wrong on data[%d]\n", i);
+ abort();
+ }
+ mpf_clear (x);
+ }
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-sqrt.c b/gmp/tests/mpf/t-sqrt.c
new file mode 100644
index 0000000000..16a823d9a4
--- /dev/null
+++ b/gmp/tests/mpf/t-sqrt.c
@@ -0,0 +1,194 @@
+/* Test mpf_sqrt, mpf_mul.
+
+Copyright 1996, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+void
+check_rand1 (int argc, char **argv)
+{
+ mp_size_t size;
+ mp_exp_t exp;
+ int reps = 20000;
+ int i;
+ mpf_t x, y, y2;
+ mp_size_t bprec = 100;
+ mpf_t rerr, max_rerr, limit_rerr;
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, bprec);
+#if VERBOSE
+ mpf_dump (limit_rerr);
+#endif
+ mpf_init (rerr);
+ mpf_init_set_ui (max_rerr, 0);
+
+ mpf_init (x);
+ mpf_init (y);
+ mpf_init (y2);
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (x, size, exp);
+
+ mpf_sqrt (y, x);
+ MPF_CHECK_FORMAT (y);
+ mpf_mul (y2, y, y);
+
+ mpf_reldiff (rerr, x, y2);
+ if (mpf_cmp (rerr, max_rerr) > 0)
+ {
+ mpf_set (max_rerr, rerr);
+#if VERBOSE
+ mpf_dump (max_rerr);
+#endif
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR after %d tests\n", i);
+ printf (" x = "); mpf_dump (x);
+ printf (" y = "); mpf_dump (y);
+ printf (" y2 = "); mpf_dump (y2);
+ printf (" rerr = "); mpf_dump (rerr);
+ printf (" limit_rerr = "); mpf_dump (limit_rerr);
+ printf ("in hex:\n");
+ mp_trace_base = 16;
+ mpf_trace (" x ", x);
+ mpf_trace (" y ", y);
+ mpf_trace (" y2 ", y2);
+ mpf_trace (" rerr ", rerr);
+ mpf_trace (" limit_rerr", limit_rerr);
+ abort ();
+ }
+ }
+ }
+
+ mpf_clear (limit_rerr);
+ mpf_clear (rerr);
+ mpf_clear (max_rerr);
+
+ mpf_clear (x);
+ mpf_clear (y);
+ mpf_clear (y2);
+}
+
+void
+check_rand2 (void)
+{
+ unsigned long max_prec = 20;
+ unsigned long min_prec = __GMPF_BITS_TO_PREC (1);
+ gmp_randstate_ptr rands = RANDS;
+ unsigned long x_prec, r_prec;
+ mpf_t x, r, s;
+ int i;
+
+ mpf_init (x);
+ mpf_init (r);
+ mpf_init (s);
+ refmpf_set_prec_limbs (s, 2*max_prec+10);
+
+ for (i = 0; i < 500; i++)
+ {
+ /* input precision */
+ x_prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec;
+ refmpf_set_prec_limbs (x, x_prec);
+
+ /* result precision */
+ r_prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec;
+ refmpf_set_prec_limbs (r, r_prec);
+
+ mpf_random2 (x, x_prec, 1000);
+
+ mpf_sqrt (r, x);
+ MPF_CHECK_FORMAT (r);
+
+ /* Expect to prec limbs of result.
+ In the current implementation there's no stripping of low zero
+ limbs in mpf_sqrt, so size should be exactly prec. */
+ if (SIZ(r) != r_prec)
+ {
+ printf ("mpf_sqrt wrong number of result limbs\n");
+ mpf_trace (" x", x);
+ mpf_trace (" r", r);
+ printf (" r_prec=%lu\n", r_prec);
+ printf (" SIZ(r) %ld\n", (long) SIZ(r));
+ printf (" PREC(r) %ld\n", (long) PREC(r));
+ abort ();
+ }
+
+ /* Must have r^2 <= x, since r has been truncated. */
+ mpf_mul (s, r, r);
+ if (! (mpf_cmp (s, x) <= 0))
+ {
+ printf ("mpf_sqrt result too big\n");
+ mpf_trace (" x", x);
+ printf (" r_prec=%lu\n", r_prec);
+ mpf_trace (" r", r);
+ mpf_trace (" s", s);
+ abort ();
+ }
+
+ /* Must have (r+ulp)^2 > x, or else r is too small. */
+ refmpf_add_ulp (r);
+ mpf_mul (s, r, r);
+ if (! (mpf_cmp (s, x) > 0))
+ {
+ printf ("mpf_sqrt result too small\n");
+ mpf_trace (" x", x);
+ printf (" r_prec=%lu\n", r_prec);
+ mpf_trace (" r+ulp", r);
+ mpf_trace (" s", s);
+ abort ();
+ }
+ }
+
+ mpf_clear (x);
+ mpf_clear (r);
+ mpf_clear (s);
+}
+
+int
+main (int argc, char **argv)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_rand1 (argc, argv);
+ check_rand2 ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-sqrt_ui.c b/gmp/tests/mpf/t-sqrt_ui.c
new file mode 100644
index 0000000000..c9233da29c
--- /dev/null
+++ b/gmp/tests/mpf/t-sqrt_ui.c
@@ -0,0 +1,113 @@
+/* Test mpf_sqrt_ui.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_rand (void)
+{
+ unsigned long max_prec = 15;
+ unsigned long min_prec = __GMPF_BITS_TO_PREC (1);
+ gmp_randstate_ptr rands = RANDS;
+ unsigned long x, prec;
+ mpf_t r, s;
+ int i;
+
+ mpf_init (r);
+ mpf_init (s);
+ refmpf_set_prec_limbs (s, 2*max_prec+10);
+
+ for (i = 0; i < 50; i++)
+ {
+ /* input, a random non-zero ulong, exponentially distributed */
+ do {
+ x = gmp_urandomb_ui (rands,
+ gmp_urandomm_ui (rands, BITS_PER_ULONG) + 1);
+ } while (x == 0);
+
+ /* result precision */
+ prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec;
+ refmpf_set_prec_limbs (r, prec);
+
+ mpf_sqrt_ui (r, x);
+ MPF_CHECK_FORMAT (r);
+
+ /* Expect to prec limbs of result.
+ In the current implementation there's no stripping of low zero
+ limbs in mpf_sqrt_ui, not even on perfect squares, so size should
+ be exactly prec. */
+ if (SIZ(r) != prec)
+ {
+ printf ("mpf_sqrt_ui result not enough result limbs\n");
+ printf (" x=%lu\n", x);
+ printf (" want prec=%lu\n", prec);
+ mpf_trace (" r", r);
+ printf (" r size %ld\n", (long) SIZ(r));
+ printf (" r prec %ld\n", (long) PREC(r));
+ abort ();
+ }
+
+ /* Must have r^2 <= x, since r has been truncated. */
+ mpf_mul (s, r, r);
+ if (! (mpf_cmp_ui (s, x) <= 0))
+ {
+ printf ("mpf_sqrt_ui result too big\n");
+ printf (" x=%lu\n", x);
+ printf (" want prec=%lu\n", prec);
+ mpf_trace (" r", r);
+ mpf_trace (" s", s);
+ abort ();
+ }
+
+ /* Must have (r+ulp)^2 > x.
+ No overflow from refmpf_add_ulp since r is only prec limbs. */
+ refmpf_add_ulp (r);
+ mpf_mul (s, r, r);
+ if (! (mpf_cmp_ui (s, x) > 0))
+ {
+ printf ("mpf_sqrt_ui result too small\n");
+ printf (" x=%lu\n", x);
+ printf (" want prec=%lu\n", prec);
+ mpf_trace (" r+ulp", r);
+ mpf_trace (" s", s);
+ abort ();
+ }
+ }
+
+ mpf_clear (r);
+ mpf_clear (s);
+}
+
+int
+main (int argc, char **argv)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_rand ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-sub.c b/gmp/tests/mpf/t-sub.c
new file mode 100644
index 0000000000..66281f4243
--- /dev/null
+++ b/gmp/tests/mpf/t-sub.c
@@ -0,0 +1,206 @@
+/* Test mpf_sub.
+
+Copyright 1996, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+void
+check_rand (int argc, char **argv)
+{
+ mp_size_t size;
+ mp_exp_t exp;
+ int reps = 20000;
+ int i;
+ mpf_t u, v, w, wref;
+ mp_size_t bprec = 100;
+ mpf_t rerr, max_rerr, limit_rerr;
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, bprec);
+#if VERBOSE
+ mpf_dump (limit_rerr);
+#endif
+ mpf_init (rerr);
+ mpf_init_set_ui (max_rerr, 0);
+
+ mpf_init (u);
+ mpf_init (v);
+ mpf_init (w);
+ mpf_init (wref);
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (u, size, exp);
+
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (v, size, exp);
+
+ if ((urandom () & 1) != 0)
+ mpf_add_ui (u, v, 1);
+ else if ((urandom () & 1) != 0)
+ mpf_sub_ui (u, v, 1);
+
+ mpf_sub (w, u, v);
+ refmpf_sub (wref, u, v);
+
+ mpf_reldiff (rerr, w, wref);
+ if (mpf_cmp (rerr, max_rerr) > 0)
+ {
+ mpf_set (max_rerr, rerr);
+#if VERBOSE
+ mpf_dump (max_rerr);
+#endif
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf ("wref = "); mpf_dump (wref);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+ }
+ }
+
+ mpf_clear (limit_rerr);
+ mpf_clear (rerr);
+ mpf_clear (max_rerr);
+
+ mpf_clear (u);
+ mpf_clear (v);
+ mpf_clear (w);
+ mpf_clear (wref);
+}
+
+
+void
+check_data (void)
+{
+ static const struct {
+ struct {
+ int exp, size;
+ mp_limb_t d[10];
+ } x, y, want;
+
+ } data[] = {
+ { { 123, 2, { 8, 9 } }, { 123, 1, { 9 } }, { 122, 1, { 8 } } },
+
+ /* f - f == 0, various sizes.
+ These exercise a past problem (gmp 4.1.3 and earlier) where the
+ result exponent was not zeroed on a zero result like this. */
+ { { 0, 0 }, { 0, 0 }, { 0, 0 } },
+ { { 99, 1, { 1 } }, { 99, 1, { 1 } }, { 0, 0 } },
+ { { 99, 2, { 123, 456 } }, { 99, 2, { 123, 456 } }, { 0, 0 } },
+ { { 99, 3, { 123, 456, 789 } }, { 99, 3, { 123, 456, 789 } }, { 0, 0 } },
+
+ /* High limbs cancel, leaving just the low limbs of the longer operand.
+ This exercises a past problem (gmp 4.1.3 and earlier) where high zero
+ limbs on the remainder were not stripped before truncating to the
+ destination, causing loss of precision. */
+ { { 123, 2, { 8, 9 } }, { 123, 1, { 9 } }, { 122, 1, { 8 } } },
+ { { 123, 3, { 8, 0, 9 } }, { 123, 1, { 9 } }, { 121, 1, { 8 } } },
+ { { 123, 4, { 8, 0, 0, 9 } }, { 123, 1, { 9 } }, { 120, 1, { 8 } } },
+ { { 123, 5, { 8, 0, 0, 0, 9 } }, { 123, 1, { 9 } }, { 119, 1, { 8 } } },
+ { { 123, 6, { 8, 0, 0, 0, 0, 9 } }, { 123, 1, { 9 } }, { 118, 1, { 8 } } },
+
+ };
+
+ mpf_t x, y, got, want;
+ int i, swap;
+
+ mp_trace_base = 16;
+ mpf_init (got);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ for (swap = 0; swap <= 1; swap++)
+ {
+ PTR(x) = (mp_ptr) data[i].x.d;
+ SIZ(x) = data[i].x.size;
+ EXP(x) = data[i].x.exp;
+ PREC(x) = numberof (data[i].x.d);
+ MPF_CHECK_FORMAT (x);
+
+ PTR(y) = (mp_ptr) data[i].y.d;
+ SIZ(y) = data[i].y.size;
+ EXP(y) = data[i].y.exp;
+ PREC(y) = numberof (data[i].y.d);
+ MPF_CHECK_FORMAT (y);
+
+ PTR(want) = (mp_ptr) data[i].want.d;
+ SIZ(want) = data[i].want.size;
+ EXP(want) = data[i].want.exp;
+ PREC(want) = numberof (data[i].want.d);
+ MPF_CHECK_FORMAT (want);
+
+ if (swap)
+ {
+ mpf_swap (x, y);
+ SIZ(want) = - SIZ(want);
+ }
+
+ mpf_sub (got, x, y);
+/* MPF_CHECK_FORMAT (got); */
+
+ if (mpf_cmp (got, want) != 0)
+ {
+ printf ("check_data() wrong result at data[%d] (operands%s swapped)\n", i, swap ? "" : " not");
+ mpf_trace ("x ", x);
+ mpf_trace ("y ", y);
+ mpf_trace ("got ", got);
+ mpf_trace ("want", want);
+ abort ();
+ }
+ }
+ }
+
+ mpf_clear (got);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ tests_start ();
+
+ check_data ();
+ check_rand (argc, argv);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-trunc.c b/gmp/tests/mpf/t-trunc.c
new file mode 100644
index 0000000000..2eef414b00
--- /dev/null
+++ b/gmp/tests/mpf/t-trunc.c
@@ -0,0 +1,271 @@
+/* Test mpf_trunc, mpf_ceil, mpf_floor.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_print (mpf_srcptr src, mpf_srcptr got, mpf_srcptr want)
+{
+ mp_trace_base = 16;
+ mpf_trace ("src ", src);
+ mpf_trace ("got ", got);
+ mpf_trace ("want", want);
+
+ printf ("got size=%d exp=%ld\n", SIZ(got), EXP(got));
+ mpn_trace (" limbs=", PTR(got), (mp_size_t) ABSIZ(got));
+
+ printf ("want size=%d exp=%ld\n", SIZ(want), EXP(want));
+ mpn_trace (" limbs=", PTR(want), (mp_size_t) ABSIZ(want));
+}
+
+void
+check_one (mpf_srcptr src, mpf_srcptr trunc, mpf_srcptr ceil, mpf_srcptr floor)
+{
+ mpf_t got;
+
+ mpf_init2 (got, mpf_get_prec (trunc));
+ ASSERT_ALWAYS (PREC(got) == PREC(trunc));
+ ASSERT_ALWAYS (PREC(got) == PREC(ceil));
+ ASSERT_ALWAYS (PREC(got) == PREC(floor));
+
+#define CHECK_SEP(name, fun, want) \
+ mpf_set_ui (got, 54321L); /* initial junk */ \
+ fun (got, src); \
+ MPF_CHECK_FORMAT (got); \
+ if (mpf_cmp (got, want) != 0) \
+ { \
+ printf ("%s wrong\n", name); \
+ check_print (src, got, want); \
+ abort (); \
+ }
+
+ CHECK_SEP ("mpf_trunc", mpf_trunc, trunc);
+ CHECK_SEP ("mpf_ceil", mpf_ceil, ceil);
+ CHECK_SEP ("mpf_floor", mpf_floor, floor);
+
+#define CHECK_INPLACE(name, fun, want) \
+ mpf_set (got, src); \
+ fun (got, got); \
+ MPF_CHECK_FORMAT (got); \
+ if (mpf_cmp (got, want) != 0) \
+ { \
+ printf ("%s wrong\n", name); \
+ check_print (src, got, want); \
+ abort (); \
+ }
+
+ CHECK_INPLACE ("mpf_trunc", mpf_trunc, trunc);
+
+ /* Can't do these unconditionally in case truncation by mpf_set strips
+ some low non-zero limbs which would have rounded the result. */
+ if (ABSIZ(src) <= PREC(trunc)+1)
+ {
+ CHECK_INPLACE ("mpf_ceil", mpf_ceil, ceil);
+ CHECK_INPLACE ("mpf_floor", mpf_floor, floor);
+ }
+
+ mpf_clear (got);
+}
+
+void
+check_all (mpf_ptr src, mpf_ptr trunc, mpf_ptr ceil, mpf_ptr floor)
+{
+ /* some of these values are generated with direct field assignments */
+ MPF_CHECK_FORMAT (src);
+ MPF_CHECK_FORMAT (trunc);
+ MPF_CHECK_FORMAT (ceil);
+ MPF_CHECK_FORMAT (floor);
+
+ check_one (src, trunc, ceil, floor);
+
+ mpf_neg (src, src);
+ mpf_neg (trunc, trunc);
+ mpf_neg (ceil, ceil);
+ mpf_neg (floor, floor);
+ check_one (src, trunc, floor, ceil);
+}
+
+void
+check_various (void)
+{
+ mpf_t src, trunc, ceil, floor;
+ int n, i;
+
+ mpf_init2 (src, 512L);
+ mpf_init2 (trunc, 256L);
+ mpf_init2 (ceil, 256L);
+ mpf_init2 (floor, 256L);
+
+ /* 0 */
+ mpf_set_ui (src, 0L);
+ mpf_set_ui (trunc, 0L);
+ mpf_set_ui (ceil, 0L);
+ mpf_set_ui (floor, 0L);
+ check_all (src, trunc, ceil, floor);
+
+ /* 1 */
+ mpf_set_ui (src, 1L);
+ mpf_set_ui (trunc, 1L);
+ mpf_set_ui (ceil, 1L);
+ mpf_set_ui (floor, 1L);
+ check_all (src, trunc, ceil, floor);
+
+ /* 2^1024 */
+ mpf_set_ui (src, 1L);
+ mpf_mul_2exp (src, src, 1024L);
+ mpf_set (trunc, src);
+ mpf_set (ceil, src);
+ mpf_set (floor, src);
+ check_all (src, trunc, ceil, floor);
+
+ /* 1/2^1024, fraction only */
+ mpf_set_ui (src, 1L);
+ mpf_div_2exp (src, src, 1024L);
+ mpf_set_si (trunc, 0L);
+ mpf_set_si (ceil, 1L);
+ mpf_set_si (floor, 0L);
+ check_all (src, trunc, ceil, floor);
+
+ /* 1/2 */
+ mpf_set_ui (src, 1L);
+ mpf_div_2exp (src, src, 1L);
+ mpf_set_si (trunc, 0L);
+ mpf_set_si (ceil, 1L);
+ mpf_set_si (floor, 0L);
+ check_all (src, trunc, ceil, floor);
+
+ /* 123+1/2^64 */
+ mpf_set_ui (src, 1L);
+ mpf_div_2exp (src, src, 64L);
+ mpf_add_ui (src, src, 123L);
+ mpf_set_si (trunc, 123L);
+ mpf_set_si (ceil, 124L);
+ mpf_set_si (floor, 123L);
+ check_all (src, trunc, ceil, floor);
+
+ /* integer of full prec+1 limbs, unchanged */
+ n = PREC(trunc)+1;
+ ASSERT_ALWAYS (n <= PREC(src)+1);
+ EXP(src) = n;
+ SIZ(src) = n;
+ for (i = 0; i < SIZ(src); i++)
+ PTR(src)[i] = i+100;
+ mpf_set (trunc, src);
+ mpf_set (ceil, src);
+ mpf_set (floor, src);
+ check_all (src, trunc, ceil, floor);
+
+ /* full prec+1 limbs, 1 trimmed for integer */
+ n = PREC(trunc)+1;
+ ASSERT_ALWAYS (n <= PREC(src)+1);
+ EXP(src) = n-1;
+ SIZ(src) = n;
+ for (i = 0; i < SIZ(src); i++)
+ PTR(src)[i] = i+200;
+ EXP(trunc) = n-1;
+ SIZ(trunc) = n-1;
+ for (i = 0; i < SIZ(trunc); i++)
+ PTR(trunc)[i] = i+201;
+ mpf_set (floor, trunc);
+ mpf_add_ui (ceil, trunc, 1L);
+ check_all (src, trunc, ceil, floor);
+
+ /* prec+3 limbs, 2 trimmed for size */
+ n = PREC(trunc)+3;
+ ASSERT_ALWAYS (n <= PREC(src)+1);
+ EXP(src) = n;
+ SIZ(src) = n;
+ for (i = 0; i < SIZ(src); i++)
+ PTR(src)[i] = i+300;
+ EXP(trunc) = n;
+ SIZ(trunc) = n-2;
+ for (i = 0; i < SIZ(trunc); i++)
+ PTR(trunc)[i] = i+302;
+ mpf_set (floor, trunc);
+ mpf_set (ceil, trunc);
+ PTR(ceil)[0]++;
+ check_all (src, trunc, ceil, floor);
+
+ /* prec+4 limbs, 2 trimmed for size, 1 trimmed for integer */
+ n = PREC(trunc)+4;
+ ASSERT_ALWAYS (n <= PREC(src)+1);
+ EXP(src) = n-1;
+ SIZ(src) = n;
+ for (i = 0; i < SIZ(src); i++)
+ PTR(src)[i] = i+400;
+ EXP(trunc) = n-1;
+ SIZ(trunc) = n-3;
+ for (i = 0; i < SIZ(trunc); i++)
+ PTR(trunc)[i] = i+403;
+ mpf_set (floor, trunc);
+ mpf_set (ceil, trunc);
+ PTR(ceil)[0]++;
+ check_all (src, trunc, ceil, floor);
+
+ /* F.F, carry out of ceil */
+ EXP(src) = 1;
+ SIZ(src) = 2;
+ PTR(src)[0] = GMP_NUMB_MAX;
+ PTR(src)[1] = GMP_NUMB_MAX;
+ EXP(trunc) = 1;
+ SIZ(trunc) = 1;
+ PTR(trunc)[0] = GMP_NUMB_MAX;
+ mpf_set (floor, trunc);
+ EXP(ceil) = 2;
+ SIZ(ceil) = 1;
+ PTR(ceil)[0] = 1;
+ check_all (src, trunc, ceil, floor);
+
+ /* FF.F, carry out of ceil */
+ EXP(src) = 2;
+ SIZ(src) = 3;
+ PTR(src)[0] = GMP_NUMB_MAX;
+ PTR(src)[1] = GMP_NUMB_MAX;
+ PTR(src)[2] = GMP_NUMB_MAX;
+ EXP(trunc) = 2;
+ SIZ(trunc) = 2;
+ PTR(trunc)[0] = GMP_NUMB_MAX;
+ PTR(trunc)[1] = GMP_NUMB_MAX;
+ mpf_set (floor, trunc);
+ EXP(ceil) = 3;
+ SIZ(ceil) = 1;
+ PTR(ceil)[0] = 1;
+ check_all (src, trunc, ceil, floor);
+
+ mpf_clear (src);
+ mpf_clear (trunc);
+ mpf_clear (ceil);
+ mpf_clear (floor);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_various ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpf/t-ui_div.c b/gmp/tests/mpf/t-ui_div.c
new file mode 100644
index 0000000000..3024efdbc4
--- /dev/null
+++ b/gmp/tests/mpf/t-ui_div.c
@@ -0,0 +1,152 @@
+/* Test mpf_ui_div.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (const char *desc, mpf_ptr got, unsigned long u, mpf_srcptr v)
+{
+ mpf_t uf;
+ mp_limb_t ulimbs[2];
+ mp_size_t usize;
+
+ ulimbs[0] = u & GMP_NUMB_MASK;
+ usize = (u != 0);
+#if BITS_PER_ULONG > GMP_NUMB_BITS
+ u >>= GMP_NUMB_BITS;
+ ulimbs[1] = u;
+ usize += (u != 0);
+#endif
+ PTR(uf) = ulimbs;
+ SIZ(uf) = usize;
+ EXP(uf) = usize;
+
+ if (! refmpf_validate_division ("mpf_ui_div", got, uf, v))
+ {
+ mp_trace_base = -16;
+ printf (" u 0x%lX (%lu)\n", u, u);
+ mpf_trace (" v", v);
+ printf (" %s\n", desc);
+ abort ();
+ }
+}
+
+void
+check_rand (void)
+{
+ unsigned long min_prec = __GMPF_BITS_TO_PREC (1);
+ gmp_randstate_ptr rands = RANDS;
+ unsigned long prec, u;
+ mpf_t got, v;
+ int i;
+
+ mpf_init (got);
+ mpf_init (v);
+
+ for (i = 0; i < 200; i++)
+ {
+ /* got precision */
+ prec = min_prec + gmp_urandomm_ui (rands, 15L);
+ refmpf_set_prec_limbs (got, prec);
+
+ /* u */
+ prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
+ u = gmp_urandomb_ui (rands, prec);
+
+ /* v precision */
+ prec = min_prec + gmp_urandomm_ui (rands, 15L);
+ refmpf_set_prec_limbs (v, prec);
+
+ /* v, non-zero */
+ do {
+ mpf_random2 (v, PREC(v), (mp_exp_t) 20);
+ } while (SIZ(v) == 0);
+
+ /* v possibly negative */
+ if (gmp_urandomb_ui (rands, 1L))
+ mpf_neg (v, v);
+
+ if ((i % 2) == 0)
+ {
+ /* src != dst */
+ mpf_ui_div (got, u, v);
+ check_one ("separate", got, u, v);
+ }
+ else
+ {
+ /* src == dst */
+ prec = refmpf_set_overlap (got, v);
+ mpf_ui_div (got, u, got);
+ check_one ("overlap src==dst", got, u, v);
+
+ mpf_set_prec_raw (got, prec);
+ }
+ }
+
+ mpf_clear (got);
+ mpf_clear (v);
+}
+
+void
+check_various (void)
+{
+ mpf_t got, v;
+
+ mpf_init (got);
+ mpf_init (v);
+
+ /* 100/4 == 25 */
+ mpf_set_prec (got, 20L);
+ mpf_set_ui (v, 4L);
+ mpf_ui_div (got, 100L, v);
+ MPF_CHECK_FORMAT (got);
+ ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
+
+ {
+ /* 1/(2^n+1), a case where truncating the divisor would be wrong */
+ unsigned long u = 1L;
+ mpf_set_prec (got, 500L);
+ mpf_set_prec (v, 900L);
+ mpf_set_ui (v, 1L);
+ mpf_mul_2exp (v, v, 800L);
+ mpf_add_ui (v, v, 1L);
+ mpf_ui_div (got, u, v);
+ check_one ("1/2^n+1, separate", got, u, v);
+ }
+
+ mpf_clear (got);
+ mpf_clear (v);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_various ();
+ check_rand ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpn/Makefile.am b/gmp/tests/mpn/Makefile.am
new file mode 100644
index 0000000000..180c58692c
--- /dev/null
+++ b/gmp/tests/mpn/Makefile.am
@@ -0,0 +1,38 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2001-2003, 2009-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/.
+
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+
+check_PROGRAMS = t-asmtype t-aors_1 t-divrem_1 t-mod_1 t-fat t-get_d \
+ t-instrument t-iord_u t-mp_bases t-perfsqr t-scan logic \
+ t-toom22 t-toom32 t-toom33 t-toom42 t-toom43 t-toom44 \
+ t-toom52 t-toom53 t-toom54 t-toom62 t-toom63 t-toom6h t-toom8h \
+ t-toom2-sqr t-toom3-sqr t-toom4-sqr t-toom6-sqr t-toom8-sqr \
+ t-mul t-mullo t-mulmod_bnm1 t-sqrmod_bnm1 t-mulmid \
+ t-hgcd t-hgcd_appr t-matrix22 t-invert t-div t-bdiv \
+ t-broot t-brootinv t-minvert t-sizeinbase
+
+EXTRA_DIST = toom-shared.h toom-sqr-shared.h
+
+TESTS = $(check_PROGRAMS)
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
diff --git a/gmp/tests/mpn/Makefile.in b/gmp/tests/mpn/Makefile.in
new file mode 100644
index 0000000000..5db22d4f0c
--- /dev/null
+++ b/gmp/tests/mpn/Makefile.in
@@ -0,0 +1,1029 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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-2003, 2009-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/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+check_PROGRAMS = t-asmtype$(EXEEXT) t-aors_1$(EXEEXT) \
+ t-divrem_1$(EXEEXT) t-mod_1$(EXEEXT) t-fat$(EXEEXT) \
+ t-get_d$(EXEEXT) t-instrument$(EXEEXT) t-iord_u$(EXEEXT) \
+ t-mp_bases$(EXEEXT) t-perfsqr$(EXEEXT) t-scan$(EXEEXT) \
+ logic$(EXEEXT) t-toom22$(EXEEXT) t-toom32$(EXEEXT) \
+ t-toom33$(EXEEXT) t-toom42$(EXEEXT) t-toom43$(EXEEXT) \
+ t-toom44$(EXEEXT) t-toom52$(EXEEXT) t-toom53$(EXEEXT) \
+ t-toom54$(EXEEXT) t-toom62$(EXEEXT) t-toom63$(EXEEXT) \
+ t-toom6h$(EXEEXT) t-toom8h$(EXEEXT) t-toom2-sqr$(EXEEXT) \
+ t-toom3-sqr$(EXEEXT) t-toom4-sqr$(EXEEXT) t-toom6-sqr$(EXEEXT) \
+ t-toom8-sqr$(EXEEXT) t-mul$(EXEEXT) t-mullo$(EXEEXT) \
+ t-mulmod_bnm1$(EXEEXT) t-sqrmod_bnm1$(EXEEXT) \
+ t-mulmid$(EXEEXT) t-hgcd$(EXEEXT) t-hgcd_appr$(EXEEXT) \
+ t-matrix22$(EXEEXT) t-invert$(EXEEXT) t-div$(EXEEXT) \
+ t-bdiv$(EXEEXT) t-broot$(EXEEXT) t-brootinv$(EXEEXT) \
+ t-minvert$(EXEEXT) t-sizeinbase$(EXEEXT)
+subdir = tests/mpn
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+logic_SOURCES = logic.c
+logic_OBJECTS = logic.$(OBJEXT)
+logic_LDADD = $(LDADD)
+logic_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_aors_1_SOURCES = t-aors_1.c
+t_aors_1_OBJECTS = t-aors_1.$(OBJEXT)
+t_aors_1_LDADD = $(LDADD)
+t_aors_1_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_asmtype_SOURCES = t-asmtype.c
+t_asmtype_OBJECTS = t-asmtype.$(OBJEXT)
+t_asmtype_LDADD = $(LDADD)
+t_asmtype_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_bdiv_SOURCES = t-bdiv.c
+t_bdiv_OBJECTS = t-bdiv.$(OBJEXT)
+t_bdiv_LDADD = $(LDADD)
+t_bdiv_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_broot_SOURCES = t-broot.c
+t_broot_OBJECTS = t-broot.$(OBJEXT)
+t_broot_LDADD = $(LDADD)
+t_broot_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_brootinv_SOURCES = t-brootinv.c
+t_brootinv_OBJECTS = t-brootinv.$(OBJEXT)
+t_brootinv_LDADD = $(LDADD)
+t_brootinv_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_div_SOURCES = t-div.c
+t_div_OBJECTS = t-div.$(OBJEXT)
+t_div_LDADD = $(LDADD)
+t_div_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_divrem_1_SOURCES = t-divrem_1.c
+t_divrem_1_OBJECTS = t-divrem_1.$(OBJEXT)
+t_divrem_1_LDADD = $(LDADD)
+t_divrem_1_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_fat_SOURCES = t-fat.c
+t_fat_OBJECTS = t-fat.$(OBJEXT)
+t_fat_LDADD = $(LDADD)
+t_fat_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_d_SOURCES = t-get_d.c
+t_get_d_OBJECTS = t-get_d.$(OBJEXT)
+t_get_d_LDADD = $(LDADD)
+t_get_d_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_hgcd_SOURCES = t-hgcd.c
+t_hgcd_OBJECTS = t-hgcd.$(OBJEXT)
+t_hgcd_LDADD = $(LDADD)
+t_hgcd_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_hgcd_appr_SOURCES = t-hgcd_appr.c
+t_hgcd_appr_OBJECTS = t-hgcd_appr.$(OBJEXT)
+t_hgcd_appr_LDADD = $(LDADD)
+t_hgcd_appr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_instrument_SOURCES = t-instrument.c
+t_instrument_OBJECTS = t-instrument.$(OBJEXT)
+t_instrument_LDADD = $(LDADD)
+t_instrument_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_invert_SOURCES = t-invert.c
+t_invert_OBJECTS = t-invert.$(OBJEXT)
+t_invert_LDADD = $(LDADD)
+t_invert_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_iord_u_SOURCES = t-iord_u.c
+t_iord_u_OBJECTS = t-iord_u.$(OBJEXT)
+t_iord_u_LDADD = $(LDADD)
+t_iord_u_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_matrix22_SOURCES = t-matrix22.c
+t_matrix22_OBJECTS = t-matrix22.$(OBJEXT)
+t_matrix22_LDADD = $(LDADD)
+t_matrix22_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_minvert_SOURCES = t-minvert.c
+t_minvert_OBJECTS = t-minvert.$(OBJEXT)
+t_minvert_LDADD = $(LDADD)
+t_minvert_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mod_1_SOURCES = t-mod_1.c
+t_mod_1_OBJECTS = t-mod_1.$(OBJEXT)
+t_mod_1_LDADD = $(LDADD)
+t_mod_1_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mp_bases_SOURCES = t-mp_bases.c
+t_mp_bases_OBJECTS = t-mp_bases.$(OBJEXT)
+t_mp_bases_LDADD = $(LDADD)
+t_mp_bases_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mul_SOURCES = t-mul.c
+t_mul_OBJECTS = t-mul.$(OBJEXT)
+t_mul_LDADD = $(LDADD)
+t_mul_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mullo_SOURCES = t-mullo.c
+t_mullo_OBJECTS = t-mullo.$(OBJEXT)
+t_mullo_LDADD = $(LDADD)
+t_mullo_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mulmid_SOURCES = t-mulmid.c
+t_mulmid_OBJECTS = t-mulmid.$(OBJEXT)
+t_mulmid_LDADD = $(LDADD)
+t_mulmid_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mulmod_bnm1_SOURCES = t-mulmod_bnm1.c
+t_mulmod_bnm1_OBJECTS = t-mulmod_bnm1.$(OBJEXT)
+t_mulmod_bnm1_LDADD = $(LDADD)
+t_mulmod_bnm1_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_perfsqr_SOURCES = t-perfsqr.c
+t_perfsqr_OBJECTS = t-perfsqr.$(OBJEXT)
+t_perfsqr_LDADD = $(LDADD)
+t_perfsqr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_scan_SOURCES = t-scan.c
+t_scan_OBJECTS = t-scan.$(OBJEXT)
+t_scan_LDADD = $(LDADD)
+t_scan_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_sizeinbase_SOURCES = t-sizeinbase.c
+t_sizeinbase_OBJECTS = t-sizeinbase.$(OBJEXT)
+t_sizeinbase_LDADD = $(LDADD)
+t_sizeinbase_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_sqrmod_bnm1_SOURCES = t-sqrmod_bnm1.c
+t_sqrmod_bnm1_OBJECTS = t-sqrmod_bnm1.$(OBJEXT)
+t_sqrmod_bnm1_LDADD = $(LDADD)
+t_sqrmod_bnm1_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom2_sqr_SOURCES = t-toom2-sqr.c
+t_toom2_sqr_OBJECTS = t-toom2-sqr.$(OBJEXT)
+t_toom2_sqr_LDADD = $(LDADD)
+t_toom2_sqr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom22_SOURCES = t-toom22.c
+t_toom22_OBJECTS = t-toom22.$(OBJEXT)
+t_toom22_LDADD = $(LDADD)
+t_toom22_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom3_sqr_SOURCES = t-toom3-sqr.c
+t_toom3_sqr_OBJECTS = t-toom3-sqr.$(OBJEXT)
+t_toom3_sqr_LDADD = $(LDADD)
+t_toom3_sqr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom32_SOURCES = t-toom32.c
+t_toom32_OBJECTS = t-toom32.$(OBJEXT)
+t_toom32_LDADD = $(LDADD)
+t_toom32_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom33_SOURCES = t-toom33.c
+t_toom33_OBJECTS = t-toom33.$(OBJEXT)
+t_toom33_LDADD = $(LDADD)
+t_toom33_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom4_sqr_SOURCES = t-toom4-sqr.c
+t_toom4_sqr_OBJECTS = t-toom4-sqr.$(OBJEXT)
+t_toom4_sqr_LDADD = $(LDADD)
+t_toom4_sqr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom42_SOURCES = t-toom42.c
+t_toom42_OBJECTS = t-toom42.$(OBJEXT)
+t_toom42_LDADD = $(LDADD)
+t_toom42_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom43_SOURCES = t-toom43.c
+t_toom43_OBJECTS = t-toom43.$(OBJEXT)
+t_toom43_LDADD = $(LDADD)
+t_toom43_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom44_SOURCES = t-toom44.c
+t_toom44_OBJECTS = t-toom44.$(OBJEXT)
+t_toom44_LDADD = $(LDADD)
+t_toom44_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom52_SOURCES = t-toom52.c
+t_toom52_OBJECTS = t-toom52.$(OBJEXT)
+t_toom52_LDADD = $(LDADD)
+t_toom52_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom53_SOURCES = t-toom53.c
+t_toom53_OBJECTS = t-toom53.$(OBJEXT)
+t_toom53_LDADD = $(LDADD)
+t_toom53_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom54_SOURCES = t-toom54.c
+t_toom54_OBJECTS = t-toom54.$(OBJEXT)
+t_toom54_LDADD = $(LDADD)
+t_toom54_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom6_sqr_SOURCES = t-toom6-sqr.c
+t_toom6_sqr_OBJECTS = t-toom6-sqr.$(OBJEXT)
+t_toom6_sqr_LDADD = $(LDADD)
+t_toom6_sqr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom62_SOURCES = t-toom62.c
+t_toom62_OBJECTS = t-toom62.$(OBJEXT)
+t_toom62_LDADD = $(LDADD)
+t_toom62_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom63_SOURCES = t-toom63.c
+t_toom63_OBJECTS = t-toom63.$(OBJEXT)
+t_toom63_LDADD = $(LDADD)
+t_toom63_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom6h_SOURCES = t-toom6h.c
+t_toom6h_OBJECTS = t-toom6h.$(OBJEXT)
+t_toom6h_LDADD = $(LDADD)
+t_toom6h_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom8_sqr_SOURCES = t-toom8-sqr.c
+t_toom8_sqr_OBJECTS = t-toom8-sqr.$(OBJEXT)
+t_toom8_sqr_LDADD = $(LDADD)
+t_toom8_sqr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_toom8h_SOURCES = t-toom8h.c
+t_toom8h_OBJECTS = t-toom8h.$(OBJEXT)
+t_toom8h_LDADD = $(LDADD)
+t_toom8h_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = logic.c t-aors_1.c t-asmtype.c t-bdiv.c t-broot.c \
+ t-brootinv.c t-div.c t-divrem_1.c t-fat.c t-get_d.c t-hgcd.c \
+ t-hgcd_appr.c t-instrument.c t-invert.c t-iord_u.c \
+ t-matrix22.c t-minvert.c t-mod_1.c t-mp_bases.c t-mul.c \
+ t-mullo.c t-mulmid.c t-mulmod_bnm1.c t-perfsqr.c t-scan.c \
+ t-sizeinbase.c t-sqrmod_bnm1.c t-toom2-sqr.c t-toom22.c \
+ t-toom3-sqr.c t-toom32.c t-toom33.c t-toom4-sqr.c t-toom42.c \
+ t-toom43.c t-toom44.c t-toom52.c t-toom53.c t-toom54.c \
+ t-toom6-sqr.c t-toom62.c t-toom63.c t-toom6h.c t-toom8-sqr.c \
+ t-toom8h.c
+DIST_SOURCES = logic.c t-aors_1.c t-asmtype.c t-bdiv.c t-broot.c \
+ t-brootinv.c t-div.c t-divrem_1.c t-fat.c t-get_d.c t-hgcd.c \
+ t-hgcd_appr.c t-instrument.c t-invert.c t-iord_u.c \
+ t-matrix22.c t-minvert.c t-mod_1.c t-mp_bases.c t-mul.c \
+ t-mullo.c t-mulmid.c t-mulmod_bnm1.c t-perfsqr.c t-scan.c \
+ t-sizeinbase.c t-sqrmod_bnm1.c t-toom2-sqr.c t-toom22.c \
+ t-toom3-sqr.c t-toom32.c t-toom33.c t-toom4-sqr.c t-toom42.c \
+ t-toom43.c t-toom44.c t-toom52.c t-toom53.c t-toom54.c \
+ t-toom6-sqr.c t-toom62.c t-toom63.c t-toom6h.c t-toom8-sqr.c \
+ t-toom8h.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+EXTRA_DIST = toom-shared.h toom-sqr-shared.h
+TESTS = $(check_PROGRAMS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/mpn/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps tests/mpn/Makefile
+.PRECIOUS: 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
+logic$(EXEEXT): $(logic_OBJECTS) $(logic_DEPENDENCIES) $(EXTRA_logic_DEPENDENCIES)
+ @rm -f logic$(EXEEXT)
+ $(LINK) $(logic_OBJECTS) $(logic_LDADD) $(LIBS)
+t-aors_1$(EXEEXT): $(t_aors_1_OBJECTS) $(t_aors_1_DEPENDENCIES) $(EXTRA_t_aors_1_DEPENDENCIES)
+ @rm -f t-aors_1$(EXEEXT)
+ $(LINK) $(t_aors_1_OBJECTS) $(t_aors_1_LDADD) $(LIBS)
+t-asmtype$(EXEEXT): $(t_asmtype_OBJECTS) $(t_asmtype_DEPENDENCIES) $(EXTRA_t_asmtype_DEPENDENCIES)
+ @rm -f t-asmtype$(EXEEXT)
+ $(LINK) $(t_asmtype_OBJECTS) $(t_asmtype_LDADD) $(LIBS)
+t-bdiv$(EXEEXT): $(t_bdiv_OBJECTS) $(t_bdiv_DEPENDENCIES) $(EXTRA_t_bdiv_DEPENDENCIES)
+ @rm -f t-bdiv$(EXEEXT)
+ $(LINK) $(t_bdiv_OBJECTS) $(t_bdiv_LDADD) $(LIBS)
+t-broot$(EXEEXT): $(t_broot_OBJECTS) $(t_broot_DEPENDENCIES) $(EXTRA_t_broot_DEPENDENCIES)
+ @rm -f t-broot$(EXEEXT)
+ $(LINK) $(t_broot_OBJECTS) $(t_broot_LDADD) $(LIBS)
+t-brootinv$(EXEEXT): $(t_brootinv_OBJECTS) $(t_brootinv_DEPENDENCIES) $(EXTRA_t_brootinv_DEPENDENCIES)
+ @rm -f t-brootinv$(EXEEXT)
+ $(LINK) $(t_brootinv_OBJECTS) $(t_brootinv_LDADD) $(LIBS)
+t-div$(EXEEXT): $(t_div_OBJECTS) $(t_div_DEPENDENCIES) $(EXTRA_t_div_DEPENDENCIES)
+ @rm -f t-div$(EXEEXT)
+ $(LINK) $(t_div_OBJECTS) $(t_div_LDADD) $(LIBS)
+t-divrem_1$(EXEEXT): $(t_divrem_1_OBJECTS) $(t_divrem_1_DEPENDENCIES) $(EXTRA_t_divrem_1_DEPENDENCIES)
+ @rm -f t-divrem_1$(EXEEXT)
+ $(LINK) $(t_divrem_1_OBJECTS) $(t_divrem_1_LDADD) $(LIBS)
+t-fat$(EXEEXT): $(t_fat_OBJECTS) $(t_fat_DEPENDENCIES) $(EXTRA_t_fat_DEPENDENCIES)
+ @rm -f t-fat$(EXEEXT)
+ $(LINK) $(t_fat_OBJECTS) $(t_fat_LDADD) $(LIBS)
+t-get_d$(EXEEXT): $(t_get_d_OBJECTS) $(t_get_d_DEPENDENCIES) $(EXTRA_t_get_d_DEPENDENCIES)
+ @rm -f t-get_d$(EXEEXT)
+ $(LINK) $(t_get_d_OBJECTS) $(t_get_d_LDADD) $(LIBS)
+t-hgcd$(EXEEXT): $(t_hgcd_OBJECTS) $(t_hgcd_DEPENDENCIES) $(EXTRA_t_hgcd_DEPENDENCIES)
+ @rm -f t-hgcd$(EXEEXT)
+ $(LINK) $(t_hgcd_OBJECTS) $(t_hgcd_LDADD) $(LIBS)
+t-hgcd_appr$(EXEEXT): $(t_hgcd_appr_OBJECTS) $(t_hgcd_appr_DEPENDENCIES) $(EXTRA_t_hgcd_appr_DEPENDENCIES)
+ @rm -f t-hgcd_appr$(EXEEXT)
+ $(LINK) $(t_hgcd_appr_OBJECTS) $(t_hgcd_appr_LDADD) $(LIBS)
+t-instrument$(EXEEXT): $(t_instrument_OBJECTS) $(t_instrument_DEPENDENCIES) $(EXTRA_t_instrument_DEPENDENCIES)
+ @rm -f t-instrument$(EXEEXT)
+ $(LINK) $(t_instrument_OBJECTS) $(t_instrument_LDADD) $(LIBS)
+t-invert$(EXEEXT): $(t_invert_OBJECTS) $(t_invert_DEPENDENCIES) $(EXTRA_t_invert_DEPENDENCIES)
+ @rm -f t-invert$(EXEEXT)
+ $(LINK) $(t_invert_OBJECTS) $(t_invert_LDADD) $(LIBS)
+t-iord_u$(EXEEXT): $(t_iord_u_OBJECTS) $(t_iord_u_DEPENDENCIES) $(EXTRA_t_iord_u_DEPENDENCIES)
+ @rm -f t-iord_u$(EXEEXT)
+ $(LINK) $(t_iord_u_OBJECTS) $(t_iord_u_LDADD) $(LIBS)
+t-matrix22$(EXEEXT): $(t_matrix22_OBJECTS) $(t_matrix22_DEPENDENCIES) $(EXTRA_t_matrix22_DEPENDENCIES)
+ @rm -f t-matrix22$(EXEEXT)
+ $(LINK) $(t_matrix22_OBJECTS) $(t_matrix22_LDADD) $(LIBS)
+t-minvert$(EXEEXT): $(t_minvert_OBJECTS) $(t_minvert_DEPENDENCIES) $(EXTRA_t_minvert_DEPENDENCIES)
+ @rm -f t-minvert$(EXEEXT)
+ $(LINK) $(t_minvert_OBJECTS) $(t_minvert_LDADD) $(LIBS)
+t-mod_1$(EXEEXT): $(t_mod_1_OBJECTS) $(t_mod_1_DEPENDENCIES) $(EXTRA_t_mod_1_DEPENDENCIES)
+ @rm -f t-mod_1$(EXEEXT)
+ $(LINK) $(t_mod_1_OBJECTS) $(t_mod_1_LDADD) $(LIBS)
+t-mp_bases$(EXEEXT): $(t_mp_bases_OBJECTS) $(t_mp_bases_DEPENDENCIES) $(EXTRA_t_mp_bases_DEPENDENCIES)
+ @rm -f t-mp_bases$(EXEEXT)
+ $(LINK) $(t_mp_bases_OBJECTS) $(t_mp_bases_LDADD) $(LIBS)
+t-mul$(EXEEXT): $(t_mul_OBJECTS) $(t_mul_DEPENDENCIES) $(EXTRA_t_mul_DEPENDENCIES)
+ @rm -f t-mul$(EXEEXT)
+ $(LINK) $(t_mul_OBJECTS) $(t_mul_LDADD) $(LIBS)
+t-mullo$(EXEEXT): $(t_mullo_OBJECTS) $(t_mullo_DEPENDENCIES) $(EXTRA_t_mullo_DEPENDENCIES)
+ @rm -f t-mullo$(EXEEXT)
+ $(LINK) $(t_mullo_OBJECTS) $(t_mullo_LDADD) $(LIBS)
+t-mulmid$(EXEEXT): $(t_mulmid_OBJECTS) $(t_mulmid_DEPENDENCIES) $(EXTRA_t_mulmid_DEPENDENCIES)
+ @rm -f t-mulmid$(EXEEXT)
+ $(LINK) $(t_mulmid_OBJECTS) $(t_mulmid_LDADD) $(LIBS)
+t-mulmod_bnm1$(EXEEXT): $(t_mulmod_bnm1_OBJECTS) $(t_mulmod_bnm1_DEPENDENCIES) $(EXTRA_t_mulmod_bnm1_DEPENDENCIES)
+ @rm -f t-mulmod_bnm1$(EXEEXT)
+ $(LINK) $(t_mulmod_bnm1_OBJECTS) $(t_mulmod_bnm1_LDADD) $(LIBS)
+t-perfsqr$(EXEEXT): $(t_perfsqr_OBJECTS) $(t_perfsqr_DEPENDENCIES) $(EXTRA_t_perfsqr_DEPENDENCIES)
+ @rm -f t-perfsqr$(EXEEXT)
+ $(LINK) $(t_perfsqr_OBJECTS) $(t_perfsqr_LDADD) $(LIBS)
+t-scan$(EXEEXT): $(t_scan_OBJECTS) $(t_scan_DEPENDENCIES) $(EXTRA_t_scan_DEPENDENCIES)
+ @rm -f t-scan$(EXEEXT)
+ $(LINK) $(t_scan_OBJECTS) $(t_scan_LDADD) $(LIBS)
+t-sizeinbase$(EXEEXT): $(t_sizeinbase_OBJECTS) $(t_sizeinbase_DEPENDENCIES) $(EXTRA_t_sizeinbase_DEPENDENCIES)
+ @rm -f t-sizeinbase$(EXEEXT)
+ $(LINK) $(t_sizeinbase_OBJECTS) $(t_sizeinbase_LDADD) $(LIBS)
+t-sqrmod_bnm1$(EXEEXT): $(t_sqrmod_bnm1_OBJECTS) $(t_sqrmod_bnm1_DEPENDENCIES) $(EXTRA_t_sqrmod_bnm1_DEPENDENCIES)
+ @rm -f t-sqrmod_bnm1$(EXEEXT)
+ $(LINK) $(t_sqrmod_bnm1_OBJECTS) $(t_sqrmod_bnm1_LDADD) $(LIBS)
+t-toom2-sqr$(EXEEXT): $(t_toom2_sqr_OBJECTS) $(t_toom2_sqr_DEPENDENCIES) $(EXTRA_t_toom2_sqr_DEPENDENCIES)
+ @rm -f t-toom2-sqr$(EXEEXT)
+ $(LINK) $(t_toom2_sqr_OBJECTS) $(t_toom2_sqr_LDADD) $(LIBS)
+t-toom22$(EXEEXT): $(t_toom22_OBJECTS) $(t_toom22_DEPENDENCIES) $(EXTRA_t_toom22_DEPENDENCIES)
+ @rm -f t-toom22$(EXEEXT)
+ $(LINK) $(t_toom22_OBJECTS) $(t_toom22_LDADD) $(LIBS)
+t-toom3-sqr$(EXEEXT): $(t_toom3_sqr_OBJECTS) $(t_toom3_sqr_DEPENDENCIES) $(EXTRA_t_toom3_sqr_DEPENDENCIES)
+ @rm -f t-toom3-sqr$(EXEEXT)
+ $(LINK) $(t_toom3_sqr_OBJECTS) $(t_toom3_sqr_LDADD) $(LIBS)
+t-toom32$(EXEEXT): $(t_toom32_OBJECTS) $(t_toom32_DEPENDENCIES) $(EXTRA_t_toom32_DEPENDENCIES)
+ @rm -f t-toom32$(EXEEXT)
+ $(LINK) $(t_toom32_OBJECTS) $(t_toom32_LDADD) $(LIBS)
+t-toom33$(EXEEXT): $(t_toom33_OBJECTS) $(t_toom33_DEPENDENCIES) $(EXTRA_t_toom33_DEPENDENCIES)
+ @rm -f t-toom33$(EXEEXT)
+ $(LINK) $(t_toom33_OBJECTS) $(t_toom33_LDADD) $(LIBS)
+t-toom4-sqr$(EXEEXT): $(t_toom4_sqr_OBJECTS) $(t_toom4_sqr_DEPENDENCIES) $(EXTRA_t_toom4_sqr_DEPENDENCIES)
+ @rm -f t-toom4-sqr$(EXEEXT)
+ $(LINK) $(t_toom4_sqr_OBJECTS) $(t_toom4_sqr_LDADD) $(LIBS)
+t-toom42$(EXEEXT): $(t_toom42_OBJECTS) $(t_toom42_DEPENDENCIES) $(EXTRA_t_toom42_DEPENDENCIES)
+ @rm -f t-toom42$(EXEEXT)
+ $(LINK) $(t_toom42_OBJECTS) $(t_toom42_LDADD) $(LIBS)
+t-toom43$(EXEEXT): $(t_toom43_OBJECTS) $(t_toom43_DEPENDENCIES) $(EXTRA_t_toom43_DEPENDENCIES)
+ @rm -f t-toom43$(EXEEXT)
+ $(LINK) $(t_toom43_OBJECTS) $(t_toom43_LDADD) $(LIBS)
+t-toom44$(EXEEXT): $(t_toom44_OBJECTS) $(t_toom44_DEPENDENCIES) $(EXTRA_t_toom44_DEPENDENCIES)
+ @rm -f t-toom44$(EXEEXT)
+ $(LINK) $(t_toom44_OBJECTS) $(t_toom44_LDADD) $(LIBS)
+t-toom52$(EXEEXT): $(t_toom52_OBJECTS) $(t_toom52_DEPENDENCIES) $(EXTRA_t_toom52_DEPENDENCIES)
+ @rm -f t-toom52$(EXEEXT)
+ $(LINK) $(t_toom52_OBJECTS) $(t_toom52_LDADD) $(LIBS)
+t-toom53$(EXEEXT): $(t_toom53_OBJECTS) $(t_toom53_DEPENDENCIES) $(EXTRA_t_toom53_DEPENDENCIES)
+ @rm -f t-toom53$(EXEEXT)
+ $(LINK) $(t_toom53_OBJECTS) $(t_toom53_LDADD) $(LIBS)
+t-toom54$(EXEEXT): $(t_toom54_OBJECTS) $(t_toom54_DEPENDENCIES) $(EXTRA_t_toom54_DEPENDENCIES)
+ @rm -f t-toom54$(EXEEXT)
+ $(LINK) $(t_toom54_OBJECTS) $(t_toom54_LDADD) $(LIBS)
+t-toom6-sqr$(EXEEXT): $(t_toom6_sqr_OBJECTS) $(t_toom6_sqr_DEPENDENCIES) $(EXTRA_t_toom6_sqr_DEPENDENCIES)
+ @rm -f t-toom6-sqr$(EXEEXT)
+ $(LINK) $(t_toom6_sqr_OBJECTS) $(t_toom6_sqr_LDADD) $(LIBS)
+t-toom62$(EXEEXT): $(t_toom62_OBJECTS) $(t_toom62_DEPENDENCIES) $(EXTRA_t_toom62_DEPENDENCIES)
+ @rm -f t-toom62$(EXEEXT)
+ $(LINK) $(t_toom62_OBJECTS) $(t_toom62_LDADD) $(LIBS)
+t-toom63$(EXEEXT): $(t_toom63_OBJECTS) $(t_toom63_DEPENDENCIES) $(EXTRA_t_toom63_DEPENDENCIES)
+ @rm -f t-toom63$(EXEEXT)
+ $(LINK) $(t_toom63_OBJECTS) $(t_toom63_LDADD) $(LIBS)
+t-toom6h$(EXEEXT): $(t_toom6h_OBJECTS) $(t_toom6h_DEPENDENCIES) $(EXTRA_t_toom6h_DEPENDENCIES)
+ @rm -f t-toom6h$(EXEEXT)
+ $(LINK) $(t_toom6h_OBJECTS) $(t_toom6h_LDADD) $(LIBS)
+t-toom8-sqr$(EXEEXT): $(t_toom8_sqr_OBJECTS) $(t_toom8_sqr_DEPENDENCIES) $(EXTRA_t_toom8_sqr_DEPENDENCIES)
+ @rm -f t-toom8-sqr$(EXEEXT)
+ $(LINK) $(t_toom8_sqr_OBJECTS) $(t_toom8_sqr_LDADD) $(LIBS)
+t-toom8h$(EXEEXT): $(t_toom8h_OBJECTS) $(t_toom8h_DEPENDENCIES) $(EXTRA_t_toom8h_DEPENDENCIES)
+ @rm -f t-toom8h$(EXEEXT)
+ $(LINK) $(t_toom8h_OBJECTS) $(t_toom8h_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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:
+
+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 all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool ctags \
+ 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 \
+ tags uninstall uninstall-am
+
+
+$(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/gmp/tests/mpn/logic.c b/gmp/tests/mpn/logic.c
new file mode 100644
index 0000000000..75b5dca1fc
--- /dev/null
+++ b/gmp/tests/mpn/logic.c
@@ -0,0 +1,134 @@
+/* Test mpn_and, mpn_ior, mpn_xor, mpn_andn, mpn_iorn, mpn_xnor, mpn_nand, and
+ mpn_nior.
+
+Copyright 2011-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 <stdlib.h>
+#include <stdio.h>
+
+/* Fake native prevalence of the tested operations, so that we actually test
+ the compiled functions, i.e., the ones which users will reach. The inlined
+ variants will be tested through tests/mpz/logic.c. */
+#define HAVE_NATIVE_mpn_com 1
+#define HAVE_NATIVE_mpn_and_n 1
+#define HAVE_NATIVE_mpn_andn_n 1
+#define HAVE_NATIVE_mpn_nand_n 1
+#define HAVE_NATIVE_mpn_ior_n 1
+#define HAVE_NATIVE_mpn_iorn_n 1
+#define HAVE_NATIVE_mpn_nior_n 1
+#define HAVE_NATIVE_mpn_xor_n 1
+#define HAVE_NATIVE_mpn_xnor_n 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mp_srcptr refp, mp_srcptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n, char *funcname)
+{
+ if (mpn_cmp (refp, rp, n))
+ {
+ printf ("ERROR in mpn_%s\n", funcname);
+ printf ("a: "); mpn_dump (ap, n);
+ printf ("b: "); mpn_dump (bp, n);
+ printf ("r: "); mpn_dump (rp, n);
+ printf ("ref: "); mpn_dump (refp, n);
+ abort();
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ mpz_t a, b;
+ mp_ptr ap, bp, rp, refp;
+ mp_size_t max_n, n, i;
+ gmp_randstate_ptr rands;
+ long test, reps = 1000;
+ TMP_SDECL;
+ TMP_SMARK;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ mpz_inits (a, b, NULL);
+
+ rands = RANDS; /* FIXME: not used */
+
+ max_n = 100;
+
+ rp = TMP_SALLOC_LIMBS (1 + max_n * 8 / GMP_LIMB_BITS);
+ refp = TMP_SALLOC_LIMBS (1 + max_n * 8 / GMP_LIMB_BITS);
+
+ for (test = 0; test < reps; test++)
+ {
+ for (i = 1; i <= max_n; i++)
+ {
+ mpz_rrandomb (a, rands, i * 8);
+ mpz_rrandomb (b, rands, i * 8);
+ mpz_setbit (a, i * 8 - 1);
+ mpz_setbit (b, i * 8 - 1);
+ ap = PTR(a);
+ bp = PTR(b);
+ n = SIZ(a);
+
+ refmpn_and_n (refp, ap, bp, n);
+ mpn_and_n (rp, ap, bp, n);
+ check_one (refp, rp, ap, bp, n, "and_n");
+
+ refmpn_ior_n (refp, ap, bp, n);
+ mpn_ior_n (rp, ap, bp, n);
+ check_one (refp, rp, ap, bp, n, "ior_n");
+
+ refmpn_xor_n (refp, ap, bp, n);
+ mpn_xor_n (rp, ap, bp, n);
+ check_one (refp, rp, ap, bp, n, "xor_n");
+
+ refmpn_andn_n (refp, ap, bp, n);
+ mpn_andn_n (rp, ap, bp, n);
+ check_one (refp, rp, ap, bp, n, "andn_n");
+
+ refmpn_iorn_n (refp, ap, bp, n);
+ mpn_iorn_n (rp, ap, bp, n);
+ check_one (refp, rp, ap, bp, n, "iorn_n");
+
+ refmpn_nand_n (refp, ap, bp, n);
+ mpn_nand_n (rp, ap, bp, n);
+ check_one (refp, rp, ap, bp, n, "nand_n");
+
+ refmpn_nior_n (refp, ap, bp, n);
+ mpn_nior_n (rp, ap, bp, n);
+ check_one (refp, rp, ap, bp, n, "nior_n");
+
+ refmpn_xnor_n (refp, ap, bp, n);
+ mpn_xnor_n (rp, ap, bp, n);
+ check_one (refp, rp, ap, bp, n, "xnor_n");
+
+ refmpn_com (refp, ap, n);
+ mpn_com (rp, ap, n);
+ check_one (refp, rp, ap, bp, n, "com");
+ }
+ }
+
+ TMP_SFREE;
+ mpz_clears (a, b, NULL);
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-aors_1.c b/gmp/tests/mpn/t-aors_1.c
new file mode 100644
index 0000000000..6a946f2d57
--- /dev/null
+++ b/gmp/tests/mpn/t-aors_1.c
@@ -0,0 +1,311 @@
+/* Test mpn_add_1 and mpn_sub_1.
+
+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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#define M GMP_NUMB_MAX
+#define ASIZE 10
+#define MAGIC 0x1234
+
+#define SETUP() \
+ do { \
+ refmpn_random (got, data[i].size); \
+ got[data[i].size] = MAGIC; \
+ } while (0)
+
+#define SETUP_INPLACE() \
+ do { \
+ refmpn_copyi (got, data[i].src, data[i].size); \
+ got[data[i].size] = MAGIC; \
+ } while (0)
+
+#define VERIFY(name) \
+ do { \
+ verify (name, i, data[i].src, data[i].n, \
+ got_c, data[i].want_c, \
+ got, data[i].want, data[i].size); \
+ } while (0)
+
+typedef mp_limb_t (*mpn_aors_1_t) (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mpn_aors_1_t fudge (mpn_aors_1_t);
+
+
+void
+verify (const char *name, int i,
+ mp_srcptr src, mp_limb_t n,
+ mp_limb_t got_c, mp_limb_t want_c,
+ mp_srcptr got, mp_srcptr want, mp_size_t size)
+{
+ if (got[size] != MAGIC)
+ {
+ printf ("Overwrite at %s i=%d\n", name, i);
+ abort ();
+ }
+
+ if (got_c != want_c || ! refmpn_equal_anynail (got, want, size))
+ {
+ printf ("Wrong at %s i=%d size=%ld\n", name, i, size);
+ mpn_trace (" src", src, size);
+ mpn_trace (" n", &n, (mp_size_t) 1);
+ mpn_trace (" got", got, size);
+ mpn_trace (" want", want, size);
+ mpn_trace (" got c", &got_c, (mp_size_t) 1);
+ mpn_trace ("want c", &want_c, (mp_size_t) 1);
+ abort ();
+ }
+}
+
+
+void
+check_add_1 (void)
+{
+ static const struct {
+ mp_size_t size;
+ mp_limb_t n;
+ const mp_limb_t src[ASIZE];
+ mp_limb_t want_c;
+ const mp_limb_t want[ASIZE];
+ } data[] = {
+ { 1, 0, { 0 }, 0, { 0 } },
+ { 1, 0, { 1 }, 0, { 1 } },
+ { 1, 1, { 0 }, 0, { 1 } },
+ { 1, 0, { M }, 0, { M } },
+ { 1, M, { 0 }, 0, { M } },
+ { 1, 1, { 123 }, 0, { 124 } },
+
+ { 1, 1, { M }, 1, { 0 } },
+ { 1, M, { 1 }, 1, { 0 } },
+ { 1, M, { M }, 1, { M-1 } },
+
+ { 2, 0, { 0, 0 }, 0, { 0, 0 } },
+ { 2, 0, { 1, 0 }, 0, { 1, 0 } },
+ { 2, 1, { 0, 0 }, 0, { 1, 0 } },
+ { 2, 0, { M, 0 }, 0, { M, 0 } },
+ { 2, M, { 0, 0 }, 0, { M, 0 } },
+ { 2, 1, { M, 0 }, 0, { 0, 1 } },
+ { 2, M, { 1, 0 }, 0, { 0, 1 } },
+ { 2, M, { M, 0 }, 0, { M-1, 1 } },
+ { 2, M, { M, 0 }, 0, { M-1, 1 } },
+
+ { 2, 1, { M, M }, 1, { 0, 0 } },
+ { 2, M, { 1, M }, 1, { 0, 0 } },
+ { 2, M, { M, M }, 1, { M-1, 0 } },
+ { 2, M, { M, M }, 1, { M-1, 0 } },
+
+ { 3, 1, { M, M, M }, 1, { 0, 0, 0 } },
+ { 3, M, { 1, M, M }, 1, { 0, 0, 0 } },
+ { 3, M, { M, M, M }, 1, { M-1, 0, 0 } },
+ { 3, M, { M, M, M }, 1, { M-1, 0, 0 } },
+
+ { 4, 1, { M, M, M, M }, 1, { 0, 0, 0, 0 } },
+ { 4, M, { 1, M, M, M }, 1, { 0, 0, 0, 0 } },
+ { 4, M, { M, M, M, M }, 1, { M-1, 0, 0, 0 } },
+ { 4, M, { M, M, M, M }, 1, { M-1, 0, 0, 0 } },
+
+ { 4, M, { M, 0, M, M }, 0, { M-1, 1, M, M } },
+ { 4, M, { M, M-1, M, M }, 0, { M-1, M, M, M } },
+
+ { 4, M, { M, M, 0, M }, 0, { M-1, 0, 1, M } },
+ { 4, M, { M, M, M-1, M }, 0, { M-1, 0, M, M } },
+ };
+
+ mp_limb_t got[ASIZE];
+ mp_limb_t got_c;
+ /* mpn_sec_add_a_itch(n) <= n */
+ mp_limb_t scratch[ASIZE];
+ int i;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ SETUP ();
+ got_c = mpn_add_1 (got, data[i].src, data[i].size, data[i].n);
+ VERIFY ("check_add_1 (separate)");
+
+ SETUP_INPLACE ();
+ got_c = mpn_add_1 (got, got, data[i].size, data[i].n);
+ VERIFY ("check_add_1 (in-place)");
+
+ SETUP ();
+ scratch [mpn_sec_add_1_itch(data[i].size)] = MAGIC;
+ got_c = mpn_sec_add_1 (got, data[i].src, data[i].size, data[i].n, scratch);
+ got_c ^= scratch [mpn_sec_add_1_itch(data[i].size)] ^ MAGIC;
+ VERIFY ("check_sec_add_1 (separate)");
+
+ SETUP_INPLACE ();
+ got_c = mpn_sec_add_1 (got, got, data[i].size, data[i].n, scratch);
+ VERIFY ("check_sec_add_1 (in-place)");
+
+ if (data[i].n == 1)
+ {
+ SETUP ();
+ got_c = mpn_add_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
+ VERIFY ("check_add_1 (separate, const 1)");
+
+ SETUP_INPLACE ();
+ got_c = mpn_add_1 (got, got, data[i].size, CNST_LIMB(1));
+ VERIFY ("check_add_1 (in-place, const 1)");
+
+ SETUP ();
+ got_c = mpn_sec_add_1 (got, data[i].src, data[i].size,
+ CNST_LIMB(1), scratch);
+ VERIFY ("check_sec_add_1 (separate, const 1)");
+
+ SETUP_INPLACE ();
+ got_c = mpn_sec_add_1 (got, got, data[i].size,
+ CNST_LIMB(1), scratch);
+ VERIFY ("check_sec_add_1 (in-place, const 1)");
+ }
+
+ /* Same again on functions, not inlines. */
+ SETUP ();
+ got_c = (*fudge(mpn_add_1)) (got, data[i].src, data[i].size, data[i].n);
+ VERIFY ("check_add_1 (function, separate)");
+
+ SETUP_INPLACE ();
+ got_c = (*fudge(mpn_add_1)) (got, got, data[i].size, data[i].n);
+ VERIFY ("check_add_1 (function, in-place)");
+ }
+}
+
+void
+check_sub_1 (void)
+{
+ static const struct {
+ mp_size_t size;
+ mp_limb_t n;
+ const mp_limb_t src[ASIZE];
+ mp_limb_t want_c;
+ const mp_limb_t want[ASIZE];
+ } data[] = {
+ { 1, 0, { 0 }, 0, { 0 } },
+ { 1, 0, { 1 }, 0, { 1 } },
+ { 1, 1, { 1 }, 0, { 0 } },
+ { 1, 0, { M }, 0, { M } },
+ { 1, 1, { M }, 0, { M-1 } },
+ { 1, 1, { 123 }, 0, { 122 } },
+
+ { 1, 1, { 0 }, 1, { M } },
+ { 1, M, { 0 }, 1, { 1 } },
+
+ { 2, 0, { 0, 0 }, 0, { 0, 0 } },
+ { 2, 0, { 1, 0 }, 0, { 1, 0 } },
+ { 2, 1, { 1, 0 }, 0, { 0, 0 } },
+ { 2, 0, { M, 0 }, 0, { M, 0 } },
+ { 2, 1, { M, 0 }, 0, { M-1, 0 } },
+ { 2, 1, { 123, 0 }, 0, { 122, 0 } },
+
+ { 2, 1, { 0, 0 }, 1, { M, M } },
+ { 2, M, { 0, 0 }, 1, { 1, M } },
+
+ { 3, 0, { 0, 0, 0 }, 0, { 0, 0, 0 } },
+ { 3, 0, { 123, 0, 0 }, 0, { 123, 0, 0 } },
+
+ { 3, 1, { 0, 0, 0 }, 1, { M, M, M } },
+ { 3, M, { 0, 0, 0 }, 1, { 1, M, M } },
+
+ { 4, 1, { 0, 0, 0, 0 }, 1, { M, M, M, M } },
+ { 4, M, { 0, 0, 0, 0 }, 1, { 1, M, M, M } },
+
+ { 4, 1, { 0, 0, 1, 42 }, 0, { M, M, 0, 42 } },
+ { 4, M, { 0, 0, 123, 24 }, 0, { 1, M, 122, 24 } },
+ };
+
+ mp_limb_t got[ASIZE];
+ mp_limb_t got_c;
+ /* mpn_sec_sub_1_itch(n) <= n */
+ mp_limb_t scratch[ASIZE];
+ int i;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ SETUP ();
+ got_c = mpn_sub_1 (got, data[i].src, data[i].size, data[i].n);
+ VERIFY ("check_sub_1 (separate)");
+
+ SETUP_INPLACE ();
+ got_c = mpn_sub_1 (got, got, data[i].size, data[i].n);
+ VERIFY ("check_sub_1 (in-place)");
+
+ SETUP ();
+ scratch [mpn_sec_sub_1_itch(data[i].size)] = MAGIC;
+ got_c = mpn_sec_sub_1 (got, data[i].src, data[i].size, data[i].n, scratch);
+ got_c ^= scratch [mpn_sec_sub_1_itch(data[i].size)] ^ MAGIC;
+ VERIFY ("check_sec_sub_1 (separate)");
+
+ SETUP_INPLACE ();
+ got_c = mpn_sec_sub_1 (got, got, data[i].size, data[i].n, scratch);
+ VERIFY ("check_sec_sub_1 (in-place)");
+
+ if (data[i].n == 1)
+ {
+ SETUP ();
+ got_c = mpn_sub_1 (got, data[i].src, data[i].size, CNST_LIMB(1));
+ VERIFY ("check_sub_1 (separate, const 1)");
+
+ SETUP_INPLACE ();
+ got_c = mpn_sub_1 (got, got, data[i].size, CNST_LIMB(1));
+ VERIFY ("check_sub_1 (in-place, const 1)");
+
+ SETUP ();
+ got_c = mpn_sec_sub_1 (got, data[i].src, data[i].size,
+ CNST_LIMB(1), scratch);
+ VERIFY ("check_sec_sub_1 (separate, const 1)");
+
+ SETUP_INPLACE ();
+ got_c = mpn_sec_sub_1 (got, got, data[i].size,
+ CNST_LIMB(1), scratch);
+ VERIFY ("check_sec_sub_1 (in-place, const 1)");
+ }
+
+ /* Same again on functions, not inlines. */
+ SETUP ();
+ got_c = (*fudge(mpn_sub_1)) (got, data[i].src, data[i].size, data[i].n);
+ VERIFY ("check_sub_1 (function, separate)");
+
+ SETUP_INPLACE ();
+ got_c = (*fudge(mpn_sub_1)) (got, got, data[i].size, data[i].n);
+ VERIFY ("check_sub_1 (function, in-place)");
+ }
+}
+
+/* Try to prevent the optimizer inlining. */
+mpn_aors_1_t
+fudge (mpn_aors_1_t f)
+{
+ return f;
+}
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_add_1 ();
+ check_sub_1 ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpn/t-asmtype.c b/gmp/tests/mpn/t-asmtype.c
new file mode 100644
index 0000000000..93960f7aef
--- /dev/null
+++ b/gmp/tests/mpn/t-asmtype.c
@@ -0,0 +1,64 @@
+/* Test .type directives on assembler functions.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#include "tests.h"
+
+
+/* This apparently trivial test is designed to detect missing .type and
+ .size directives in asm code, per the problem described under
+ GMP_ASM_TYPE in acinclude.m4.
+
+ A failure can be provoked in a shared or shared+static build by making
+ TYPE and SIZE in config.m4 empty, either by editing it or by configuring
+ with
+
+ ./configure gmp_cv_asm_type= gmp_cv_asm_size=
+
+ mpn_add_n is used for the test because normally it's implemented in
+ assembler on a CPU that has any asm code.
+
+ Enhancement: As noted with GMP_ASM_TYPE, if .type is wrong but .size is
+ right then everything works, but uses code copied down to the mainline
+ data area. Maybe we could detect that if we built a test library with an
+ object that had .size deliberately disabled. */
+
+int
+main (void)
+{
+ static const mp_limb_t x[3] = { 1, 2, 3 };
+ static const mp_limb_t y[3] = { 4, 5, 6 };
+ static const mp_limb_t want[3] = { 5, 7, 9 };
+ mp_limb_t got[3];
+
+ mpn_add_n (got, x, y, (mp_size_t) 3);
+
+ if (refmpn_cmp (got, want, (mp_size_t) 3) != 0)
+ {
+ printf ("Wrong result from mpn_add_n\n");
+ abort ();
+ }
+
+ exit (0);
+}
diff --git a/gmp/tests/mpn/t-bdiv.c b/gmp/tests/mpn/t-bdiv.c
new file mode 100644
index 0000000000..0056ca9e38
--- /dev/null
+++ b/gmp/tests/mpn/t-bdiv.c
@@ -0,0 +1,368 @@
+/* Copyright 2006, 2007, 2009, 2010 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 <stdlib.h> /* for strtol */
+#include <stdio.h> /* for printf */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests/tests.h"
+
+
+static void
+dumpy (mp_srcptr p, mp_size_t n)
+{
+ mp_size_t i;
+ if (n > 20)
+ {
+ for (i = n - 1; i >= n - 4; i--)
+ {
+ printf ("%0*lx", (int) (2 * sizeof (mp_limb_t)), p[i]);
+ printf (" ");
+ }
+ printf ("... ");
+ for (i = 3; i >= 0; i--)
+ {
+ printf ("%0*lx", (int) (2 * sizeof (mp_limb_t)), p[i]);
+ printf (" " + (i == 0));
+ }
+ }
+ else
+ {
+ for (i = n - 1; i >= 0; i--)
+ {
+ printf ("%0*lx", (int) (2 * sizeof (mp_limb_t)), p[i]);
+ printf (" " + (i == 0));
+ }
+ }
+ puts ("");
+}
+
+static unsigned long test;
+
+void
+check_one (mp_ptr qp, mp_srcptr rp, mp_limb_t rh,
+ mp_srcptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn, const char *fname)
+{
+ mp_size_t qn;
+ int cmp;
+ mp_ptr tp;
+ mp_limb_t cy = 4711; /* silence warnings */
+ TMP_DECL;
+
+ qn = nn - dn;
+
+ if (qn == 0)
+ return;
+
+ TMP_MARK;
+
+ tp = TMP_ALLOC_LIMBS (nn + 1);
+
+ if (dn >= qn)
+ mpn_mul (tp, dp, dn, qp, qn);
+ else
+ mpn_mul (tp, qp, qn, dp, dn);
+
+ if (rp != NULL)
+ {
+ cy = mpn_add_n (tp + qn, tp + qn, rp, dn);
+ cmp = cy != rh || mpn_cmp (tp, np, nn) != 0;
+ }
+ else
+ cmp = mpn_cmp (tp, np, nn - dn) != 0;
+
+ if (cmp != 0)
+ {
+ printf ("\r*******************************************************************************\n");
+ printf ("%s inconsistent in test %lu\n", fname, test);
+ printf ("N= "); dumpy (np, nn);
+ printf ("D= "); dumpy (dp, dn);
+ printf ("Q= "); dumpy (qp, qn);
+ if (rp != NULL)
+ {
+ printf ("R= "); dumpy (rp, dn);
+ printf ("Rb= %d, Cy=%d\n", (int) cy, (int) rh);
+ }
+ printf ("T= "); dumpy (tp, nn);
+ printf ("nn = %ld, dn = %ld, qn = %ld", nn, dn, qn);
+ printf ("\n*******************************************************************************\n");
+ abort ();
+ }
+
+ TMP_FREE;
+}
+
+
+/* These are *bit* sizes. */
+#define SIZE_LOG 16
+#define MAX_DN (1L << SIZE_LOG)
+#define MAX_NN (1L << (SIZE_LOG + 1))
+
+#define COUNT 500
+
+mp_limb_t
+random_word (gmp_randstate_ptr rs)
+{
+ mpz_t x;
+ mp_limb_t r;
+ TMP_DECL;
+ TMP_MARK;
+
+ MPZ_TMP_INIT (x, 2);
+ mpz_urandomb (x, rs, 32);
+ r = mpz_get_ui (x);
+ TMP_FREE;
+ return r;
+}
+
+int
+main (int argc, char **argv)
+{
+ gmp_randstate_ptr rands;
+ unsigned long maxnbits, maxdbits, nbits, dbits;
+ mpz_t n, d, tz;
+ mp_size_t maxnn, maxdn, nn, dn, clearn, i;
+ mp_ptr np, dp, qp, rp;
+ mp_limb_t rh;
+ mp_limb_t t;
+ mp_limb_t dinv;
+ int count = COUNT;
+ mp_ptr scratch;
+ mp_limb_t ran;
+ mp_size_t alloc, itch;
+ mp_limb_t rran0, rran1, qran0, qran1;
+ TMP_DECL;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+
+ maxdbits = MAX_DN;
+ maxnbits = MAX_NN;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (n);
+ mpz_init (d);
+ mpz_init (tz);
+
+ maxnn = maxnbits / GMP_NUMB_BITS + 1;
+ maxdn = maxdbits / GMP_NUMB_BITS + 1;
+
+ TMP_MARK;
+
+ qp = TMP_ALLOC_LIMBS (maxnn + 2) + 1;
+ rp = TMP_ALLOC_LIMBS (maxnn + 2) + 1;
+
+ alloc = 1;
+ scratch = __GMP_ALLOCATE_FUNC_LIMBS (alloc);
+
+ for (test = 0; test < count;)
+ {
+ nbits = random_word (rands) % (maxnbits - GMP_NUMB_BITS) + 2 * GMP_NUMB_BITS;
+ if (maxdbits > nbits)
+ dbits = random_word (rands) % nbits + 1;
+ else
+ dbits = random_word (rands) % maxdbits + 1;
+
+#if RAND_UNIFORM
+#define RANDFUNC mpz_urandomb
+#else
+#define RANDFUNC mpz_rrandomb
+#endif
+
+ do
+ {
+ RANDFUNC (n, rands, nbits);
+ do
+ {
+ RANDFUNC (d, rands, dbits);
+ }
+ while (mpz_sgn (d) == 0);
+
+ np = PTR (n);
+ dp = PTR (d);
+ nn = SIZ (n);
+ dn = SIZ (d);
+ }
+ while (nn < dn);
+
+ dp[0] |= 1;
+
+ mpz_urandomb (tz, rands, 32);
+ t = mpz_get_ui (tz);
+
+ if (t % 17 == 0)
+ dp[0] = GMP_NUMB_MAX;
+
+ switch ((int) t % 16)
+ {
+ case 0:
+ clearn = random_word (rands) % nn;
+ for (i = 0; i <= clearn; i++)
+ np[i] = 0;
+ break;
+ case 1:
+ mpn_sub_1 (np + nn - dn, dp, dn, random_word (rands));
+ break;
+ case 2:
+ mpn_add_1 (np + nn - dn, dp, dn, random_word (rands));
+ break;
+ }
+
+ test++;
+
+ binvert_limb (dinv, dp[0]);
+
+ rran0 = random_word (rands);
+ rran1 = random_word (rands);
+ qran0 = random_word (rands);
+ qran1 = random_word (rands);
+
+ qp[-1] = qran0;
+ qp[nn - dn + 1] = qran1;
+ rp[-1] = rran0;
+
+ ran = random_word (rands);
+
+ if ((double) (nn - dn) * dn < 1e5)
+ {
+ if (nn > dn)
+ {
+ /* Test mpn_sbpi1_bdiv_qr */
+ MPN_ZERO (qp, nn - dn);
+ MPN_ZERO (rp, dn);
+ MPN_COPY (rp, np, nn);
+ rh = mpn_sbpi1_bdiv_qr (qp, rp, nn, dp, dn, -dinv);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0);
+ check_one (qp, rp + nn - dn, rh, np, nn, dp, dn, "mpn_sbpi1_bdiv_qr");
+ }
+
+ if (nn > dn)
+ {
+ /* Test mpn_sbpi1_bdiv_q */
+ MPN_COPY (rp, np, nn);
+ MPN_ZERO (qp, nn - dn);
+ mpn_sbpi1_bdiv_q (qp, rp, nn - dn, dp, MIN(dn,nn-dn), -dinv);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0);
+ check_one (qp, NULL, 0, np, nn, dp, dn, "mpn_sbpi1_bdiv_q");
+ }
+ }
+
+ if (dn >= 4 && nn - dn >= 2)
+ {
+ /* Test mpn_dcpi1_bdiv_qr */
+ MPN_COPY (rp, np, nn);
+ MPN_ZERO (qp, nn - dn);
+ rh = mpn_dcpi1_bdiv_qr (qp, rp, nn, dp, dn, -dinv);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0);
+ check_one (qp, rp + nn - dn, rh, np, nn, dp, dn, "mpn_dcpi1_bdiv_qr");
+ }
+
+ if (dn >= 4 && nn - dn >= 2)
+ {
+ /* Test mpn_dcpi1_bdiv_q */
+ MPN_COPY (rp, np, nn);
+ MPN_ZERO (qp, nn - dn);
+ mpn_dcpi1_bdiv_q (qp, rp, nn - dn, dp, MIN(dn,nn-dn), -dinv);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0);
+ check_one (qp, NULL, 0, np, nn, dp, dn, "mpn_dcpi1_bdiv_q");
+ }
+
+ if (nn > dn)
+ {
+ /* Test mpn_bdiv_qr */
+ itch = mpn_bdiv_qr_itch (nn, dn);
+ if (itch + 1 > alloc)
+ {
+ scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
+ alloc = itch + 1;
+ }
+ scratch[itch] = ran;
+ MPN_ZERO (qp, nn - dn);
+ MPN_ZERO (rp, dn);
+ rp[dn] = rran1;
+ rh = mpn_bdiv_qr (qp, rp, np, nn, dp, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0); ASSERT_ALWAYS (rp[dn] == rran1);
+
+ check_one (qp, rp, rh, np, nn, dp, dn, "mpn_bdiv_qr");
+ }
+
+ if (nn - dn < 2 || dn < 2)
+ continue;
+
+ /* Test mpn_mu_bdiv_qr */
+ itch = mpn_mu_bdiv_qr_itch (nn, dn);
+ if (itch + 1 > alloc)
+ {
+ scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
+ alloc = itch + 1;
+ }
+ scratch[itch] = ran;
+ MPN_ZERO (qp, nn - dn);
+ MPN_ZERO (rp, dn);
+ rp[dn] = rran1;
+ rh = mpn_mu_bdiv_qr (qp, rp, np, nn, dp, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0); ASSERT_ALWAYS (rp[dn] == rran1);
+ check_one (qp, rp, rh, np, nn, dp, dn, "mpn_mu_bdiv_qr");
+
+ /* Test mpn_mu_bdiv_q */
+ itch = mpn_mu_bdiv_q_itch (nn, dn);
+ if (itch + 1 > alloc)
+ {
+ scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
+ alloc = itch + 1;
+ }
+ scratch[itch] = ran;
+ MPN_ZERO (qp, nn - dn + 1);
+ mpn_mu_bdiv_q (qp, np, nn - dn, dp, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ check_one (qp, NULL, 0, np, nn, dp, dn, "mpn_mu_bdiv_q");
+ }
+
+ __GMP_FREE_FUNC_LIMBS (scratch, alloc);
+
+ TMP_FREE;
+
+ mpz_clear (n);
+ mpz_clear (d);
+ mpz_clear (tz);
+
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-broot.c b/gmp/tests/mpn/t-broot.c
new file mode 100644
index 0000000000..1aa43319ec
--- /dev/null
+++ b/gmp/tests/mpn/t-broot.c
@@ -0,0 +1,105 @@
+/* Copyright 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 <stdlib.h> /* for strtol */
+#include <stdio.h> /* for printf */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests/tests.h"
+
+#define MAX_LIMBS 150
+#define COUNT 500
+
+int
+main (int argc, char **argv)
+{
+ gmp_randstate_ptr rands;
+
+ mp_ptr ap, rp, pp, scratch;
+ int count = COUNT;
+ unsigned i;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ tests_start ();
+ rands = RANDS;
+
+ ap = TMP_ALLOC_LIMBS (MAX_LIMBS);
+ rp = TMP_ALLOC_LIMBS (MAX_LIMBS);
+ pp = TMP_ALLOC_LIMBS (MAX_LIMBS);
+ scratch = TMP_ALLOC_LIMBS (3*MAX_LIMBS); /* For mpn_powlo */
+
+ for (i = 0; i < count; i++)
+ {
+ mp_size_t n;
+ mp_limb_t k;
+ int c;
+
+ n = 1 + gmp_urandomm_ui (rands, MAX_LIMBS);
+
+ if (i & 1)
+ mpn_random2 (ap, n);
+ else
+ mpn_random (ap, n);
+
+ ap[0] |= 1;
+
+ if (i < 100)
+ k = 3 + 2*i;
+ else
+ {
+ mpn_random (&k, 1);
+ if (k < 3)
+ k = 3;
+ else
+ k |= 1;
+ }
+ mpn_broot (rp, ap, n, k);
+ mpn_powlo (pp, rp, &k, 1, n, scratch);
+
+ MPN_CMP (c, ap, pp, n);
+ if (c != 0)
+ {
+ gmp_fprintf (stderr,
+ "mpn_broot returned bad result: %u limbs\n",
+ (unsigned) n);
+ gmp_fprintf (stderr, "k = %Mx\n", k);
+ gmp_fprintf (stderr, "a = %Nx\n", ap, n);
+ gmp_fprintf (stderr, "r = %Nx\n", rp, n);
+ gmp_fprintf (stderr, "r^n = %Nx\n", pp, n);
+ abort ();
+ }
+ }
+ TMP_FREE;
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-brootinv.c b/gmp/tests/mpn/t-brootinv.c
new file mode 100644
index 0000000000..11f40b9543
--- /dev/null
+++ b/gmp/tests/mpn/t-brootinv.c
@@ -0,0 +1,106 @@
+/* Copyright 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 <stdlib.h> /* for strtol */
+#include <stdio.h> /* for printf */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests/tests.h"
+
+#define MAX_LIMBS 150
+#define COUNT 500
+
+int
+main (int argc, char **argv)
+{
+ gmp_randstate_ptr rands;
+
+ mp_ptr ap, rp, pp, app, scratch;
+ int count = COUNT;
+ unsigned i;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ tests_start ();
+ rands = RANDS;
+
+ ap = TMP_ALLOC_LIMBS (MAX_LIMBS);
+ rp = TMP_ALLOC_LIMBS (MAX_LIMBS);
+ pp = TMP_ALLOC_LIMBS (MAX_LIMBS);
+ app = TMP_ALLOC_LIMBS (MAX_LIMBS);
+ scratch = TMP_ALLOC_LIMBS (5*MAX_LIMBS);
+
+ for (i = 0; i < count; i++)
+ {
+ mp_size_t n;
+ mp_limb_t k;
+
+ n = 1 + gmp_urandomm_ui (rands, MAX_LIMBS);
+
+ if (i & 1)
+ mpn_random2 (ap, n);
+ else
+ mpn_random (ap, n);
+
+ ap[0] |= 1;
+
+ if (i < 100)
+ k = 3 + 2*i;
+ else
+ {
+ mpn_random (&k, 1);
+ if (k < 3)
+ k = 3;
+ else
+ k |= 1;
+ }
+ mpn_brootinv (rp, ap, n, k, scratch);
+ mpn_powlo (pp, rp, &k, 1, n, scratch);
+ mpn_mullo_n (app, ap, pp, n);
+
+ if (app[0] != 1 || !mpn_zero_p (app+1, n-1))
+ {
+ gmp_fprintf (stderr,
+ "mpn_brootinv returned bad result: %u limbs\n",
+ (unsigned) n);
+ gmp_fprintf (stderr, "k = %Mx\n", k);
+ gmp_fprintf (stderr, "a = %Nx\n", ap, n);
+ gmp_fprintf (stderr, "r = %Nx\n", rp, n);
+ gmp_fprintf (stderr, "r^n = %Nx\n", pp, n);
+ gmp_fprintf (stderr, "a r^n = %Nx\n", app, n);
+ abort ();
+ }
+ }
+ TMP_FREE;
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-div.c b/gmp/tests/mpn/t-div.c
new file mode 100644
index 0000000000..9dbe0f8185
--- /dev/null
+++ b/gmp/tests/mpn/t-div.c
@@ -0,0 +1,505 @@
+/* Copyright 2006, 2007, 2009, 2010, 2013, 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 <stdlib.h> /* for strtol */
+#include <stdio.h> /* for printf */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests/tests.h"
+
+
+static void
+dumpy (mp_srcptr p, mp_size_t n)
+{
+ mp_size_t i;
+ if (n > 20)
+ {
+ for (i = n - 1; i >= n - 4; i--)
+ {
+ printf ("%0*lx", (int) (2 * sizeof (mp_limb_t)), p[i]);
+ printf (" ");
+ }
+ printf ("... ");
+ for (i = 3; i >= 0; i--)
+ {
+ printf ("%0*lx", (int) (2 * sizeof (mp_limb_t)), p[i]);
+ printf (" " + (i == 0));
+ }
+ }
+ else
+ {
+ for (i = n - 1; i >= 0; i--)
+ {
+ printf ("%0*lx", (int) (2 * sizeof (mp_limb_t)), p[i]);
+ printf (" " + (i == 0));
+ }
+ }
+ puts ("");
+}
+
+static signed long test;
+
+static void
+check_one (mp_ptr qp, mp_srcptr rp,
+ mp_srcptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn,
+ const char *fname, mp_limb_t q_allowed_err)
+{
+ mp_size_t qn = nn - dn + 1;
+ mp_ptr tp;
+ const char *msg;
+ const char *tvalue;
+ mp_limb_t i;
+ TMP_DECL;
+ TMP_MARK;
+
+ tp = TMP_ALLOC_LIMBS (nn + 1);
+ if (dn >= qn)
+ refmpn_mul (tp, dp, dn, qp, qn);
+ else
+ refmpn_mul (tp, qp, qn, dp, dn);
+
+ for (i = 0; i < q_allowed_err && (tp[nn] > 0 || mpn_cmp (tp, np, nn) > 0); i++)
+ ASSERT_NOCARRY (refmpn_sub (tp, tp, nn+1, dp, dn));
+
+ if (tp[nn] > 0 || mpn_cmp (tp, np, nn) > 0)
+ {
+ msg = "q too large";
+ tvalue = "Q*D";
+ error:
+ printf ("\r*******************************************************************************\n");
+ printf ("%s failed test %ld: %s\n", fname, test, msg);
+ printf ("N= "); dumpy (np, nn);
+ printf ("D= "); dumpy (dp, dn);
+ printf ("Q= "); dumpy (qp, qn);
+ if (rp)
+ { printf ("R= "); dumpy (rp, dn); }
+ printf ("%5s=", tvalue); dumpy (tp, nn+1);
+ printf ("nn = %ld, dn = %ld, qn = %ld\n", nn, dn, qn);
+ abort ();
+ }
+
+ ASSERT_NOCARRY (refmpn_sub_n (tp, np, tp, nn));
+ tvalue = "N-Q*D";
+ if (!mpn_zero_p (tp + dn, nn - dn) || mpn_cmp (tp, dp, dn) >= 0)
+ {
+ msg = "q too small";
+ goto error;
+ }
+
+ if (rp && mpn_cmp (rp, tp, dn) != 0)
+ {
+ msg = "r incorrect";
+ goto error;
+ }
+
+ TMP_FREE;
+}
+
+
+/* These are *bit* sizes. */
+#ifndef SIZE_LOG
+#define SIZE_LOG 17
+#endif
+#define MAX_DN (1L << SIZE_LOG)
+#define MAX_NN (1L << (SIZE_LOG + 1))
+
+#define COUNT 200
+
+int
+main (int argc, char **argv)
+{
+ gmp_randstate_ptr rands;
+ unsigned long maxnbits, maxdbits, nbits, dbits;
+ mpz_t n, d, q, r, tz, junk;
+ mp_size_t maxnn, maxdn, nn, dn, clearn, i;
+ mp_ptr np, dup, dnp, qp, rp, junkp;
+ mp_limb_t t;
+ gmp_pi1_t dinv;
+ long count = COUNT;
+ mp_ptr scratch;
+ mp_limb_t ran;
+ mp_size_t alloc, itch;
+ mp_limb_t rran0, rran1, qran0, qran1;
+ TMP_DECL;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ maxdbits = MAX_DN;
+ maxnbits = MAX_NN;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (n);
+ mpz_init (d);
+ mpz_init (q);
+ mpz_init (r);
+ mpz_init (tz);
+ mpz_init (junk);
+
+ maxnn = maxnbits / GMP_NUMB_BITS + 1;
+ maxdn = maxdbits / GMP_NUMB_BITS + 1;
+
+ TMP_MARK;
+
+ qp = TMP_ALLOC_LIMBS (maxnn + 2) + 1;
+ rp = TMP_ALLOC_LIMBS (maxnn + 2) + 1;
+ dnp = TMP_ALLOC_LIMBS (maxdn);
+
+ alloc = 1;
+ scratch = __GMP_ALLOCATE_FUNC_LIMBS (alloc);
+
+ for (test = -300; test < count; test++)
+ {
+ nbits = urandom () % (maxnbits - GMP_NUMB_BITS) + 2 * GMP_NUMB_BITS;
+
+ if (test < 0)
+ dbits = (test + 300) % (nbits - 1) + 1;
+ else
+ dbits = urandom () % (nbits - 1) % maxdbits + 1;
+
+#if RAND_UNIFORM
+#define RANDFUNC mpz_urandomb
+#else
+#define RANDFUNC mpz_rrandomb
+#endif
+
+ do
+ RANDFUNC (d, rands, dbits);
+ while (mpz_sgn (d) == 0);
+ dn = SIZ (d);
+ dup = PTR (d);
+ MPN_COPY (dnp, dup, dn);
+ dnp[dn - 1] |= GMP_NUMB_HIGHBIT;
+
+ if (test % 2 == 0)
+ {
+ RANDFUNC (n, rands, nbits);
+ nn = SIZ (n);
+ ASSERT_ALWAYS (nn >= dn);
+ }
+ else
+ {
+ do
+ {
+ RANDFUNC (q, rands, urandom () % (nbits - dbits + 1));
+ RANDFUNC (r, rands, urandom () % mpz_sizeinbase (d, 2));
+ mpz_mul (n, q, d);
+ mpz_add (n, n, r);
+ nn = SIZ (n);
+ }
+ while (nn > maxnn || nn < dn);
+ }
+
+ ASSERT_ALWAYS (nn <= maxnn);
+ ASSERT_ALWAYS (dn <= maxdn);
+
+ mpz_urandomb (junk, rands, nbits);
+ junkp = PTR (junk);
+
+ np = PTR (n);
+
+ mpz_urandomb (tz, rands, 32);
+ t = mpz_get_ui (tz);
+
+ if (t % 17 == 0)
+ {
+ dnp[dn - 1] = GMP_NUMB_MAX;
+ dup[dn - 1] = GMP_NUMB_MAX;
+ }
+
+ switch ((int) t % 16)
+ {
+ case 0:
+ clearn = urandom () % nn;
+ for (i = clearn; i < nn; i++)
+ np[i] = 0;
+ break;
+ case 1:
+ mpn_sub_1 (np + nn - dn, dnp, dn, urandom ());
+ break;
+ case 2:
+ mpn_add_1 (np + nn - dn, dnp, dn, urandom ());
+ break;
+ }
+
+ if (dn >= 2)
+ invert_pi1 (dinv, dnp[dn - 1], dnp[dn - 2]);
+
+ rran0 = urandom ();
+ rran1 = urandom ();
+ qran0 = urandom ();
+ qran1 = urandom ();
+
+ qp[-1] = qran0;
+ qp[nn - dn + 1] = qran1;
+ rp[-1] = rran0;
+
+ ran = urandom ();
+
+ if ((double) (nn - dn) * dn < 1e5)
+ {
+ /* Test mpn_sbpi1_div_qr */
+ if (dn > 2)
+ {
+ MPN_COPY (rp, np, nn);
+ if (nn > dn)
+ MPN_COPY (qp, junkp, nn - dn);
+ qp[nn - dn] = mpn_sbpi1_div_qr (qp, rp, nn, dnp, dn, dinv.inv32);
+ check_one (qp, rp, np, nn, dnp, dn, "mpn_sbpi1_div_qr", 0);
+ }
+
+ /* Test mpn_sbpi1_divappr_q */
+ if (dn > 2)
+ {
+ MPN_COPY (rp, np, nn);
+ if (nn > dn)
+ MPN_COPY (qp, junkp, nn - dn);
+ qp[nn - dn] = mpn_sbpi1_divappr_q (qp, rp, nn, dnp, dn, dinv.inv32);
+ check_one (qp, NULL, np, nn, dnp, dn, "mpn_sbpi1_divappr_q", 1);
+ }
+
+ /* Test mpn_sbpi1_div_q */
+ if (dn > 2)
+ {
+ MPN_COPY (rp, np, nn);
+ if (nn > dn)
+ MPN_COPY (qp, junkp, nn - dn);
+ qp[nn - dn] = mpn_sbpi1_div_q (qp, rp, nn, dnp, dn, dinv.inv32);
+ check_one (qp, NULL, np, nn, dnp, dn, "mpn_sbpi1_div_q", 0);
+ }
+
+ /* Test mpn_sec_div_qr */
+ itch = mpn_sec_div_qr_itch (nn, dn);
+ if (itch + 1 > alloc)
+ {
+ scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
+ alloc = itch + 1;
+ }
+ scratch[itch] = ran;
+ MPN_COPY (rp, np, nn);
+ if (nn >= dn)
+ MPN_COPY (qp, junkp, nn - dn + 1);
+ qp[nn - dn] = mpn_sec_div_qr (qp, rp, nn, dup, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ check_one (qp, rp, np, nn, dup, dn, "mpn_sec_div_qr (unnorm)", 0);
+
+ /* Test mpn_sec_div_r */
+ itch = mpn_sec_div_r_itch (nn, dn);
+ if (itch + 1 > alloc)
+ {
+ scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
+ alloc = itch + 1;
+ }
+ scratch[itch] = ran;
+ MPN_COPY (rp, np, nn);
+ mpn_sec_div_r (rp, nn, dup, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ /* Note: Since check_one cannot cope with remainder-only functions, we
+ pass qp[] from the previous function, mpn_sec_div_qr. */
+ check_one (qp, rp, np, nn, dup, dn, "mpn_sec_div_r (unnorm)", 0);
+
+ /* Normalised case, mpn_sec_div_qr */
+ itch = mpn_sec_div_qr_itch (nn, dn);
+ scratch[itch] = ran;
+
+ MPN_COPY (rp, np, nn);
+ if (nn >= dn)
+ MPN_COPY (qp, junkp, nn - dn + 1);
+ qp[nn - dn] = mpn_sec_div_qr (qp, rp, nn, dnp, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ check_one (qp, rp, np, nn, dnp, dn, "mpn_sec_div_qr (norm)", 0);
+
+ /* Normalised case, mpn_sec_div_r */
+ itch = mpn_sec_div_r_itch (nn, dn);
+ scratch[itch] = ran;
+ MPN_COPY (rp, np, nn);
+ mpn_sec_div_r (rp, nn, dnp, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ /* Note: Since check_one cannot cope with remainder-only functions, we
+ pass qp[] from the previous function, mpn_sec_div_qr. */
+ check_one (qp, rp, np, nn, dnp, dn, "mpn_sec_div_r (norm)", 0);
+ }
+
+ /* Test mpn_dcpi1_div_qr */
+ if (dn >= 6 && nn - dn >= 3)
+ {
+ MPN_COPY (rp, np, nn);
+ if (nn > dn)
+ MPN_COPY (qp, junkp, nn - dn);
+ qp[nn - dn] = mpn_dcpi1_div_qr (qp, rp, nn, dnp, dn, &dinv);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0);
+ check_one (qp, rp, np, nn, dnp, dn, "mpn_dcpi1_div_qr", 0);
+ }
+
+ /* Test mpn_dcpi1_divappr_q */
+ if (dn >= 6 && nn - dn >= 3)
+ {
+ MPN_COPY (rp, np, nn);
+ if (nn > dn)
+ MPN_COPY (qp, junkp, nn - dn);
+ qp[nn - dn] = mpn_dcpi1_divappr_q (qp, rp, nn, dnp, dn, &dinv);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0);
+ check_one (qp, NULL, np, nn, dnp, dn, "mpn_dcpi1_divappr_q", 1);
+ }
+
+ /* Test mpn_dcpi1_div_q */
+ if (dn >= 6 && nn - dn >= 3)
+ {
+ MPN_COPY (rp, np, nn);
+ if (nn > dn)
+ MPN_COPY (qp, junkp, nn - dn);
+ qp[nn - dn] = mpn_dcpi1_div_q (qp, rp, nn, dnp, dn, &dinv);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0);
+ check_one (qp, NULL, np, nn, dnp, dn, "mpn_dcpi1_div_q", 0);
+ }
+
+ /* Test mpn_mu_div_qr */
+ if (nn - dn > 2 && dn >= 2)
+ {
+ itch = mpn_mu_div_qr_itch (nn, dn, 0);
+ if (itch + 1 > alloc)
+ {
+ scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
+ alloc = itch + 1;
+ }
+ scratch[itch] = ran;
+ MPN_COPY (qp, junkp, nn - dn);
+ MPN_ZERO (rp, dn);
+ rp[dn] = rran1;
+ qp[nn - dn] = mpn_mu_div_qr (qp, rp, np, nn, dnp, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ ASSERT_ALWAYS (rp[-1] == rran0); ASSERT_ALWAYS (rp[dn] == rran1);
+ check_one (qp, rp, np, nn, dnp, dn, "mpn_mu_div_qr", 0);
+ }
+
+ /* Test mpn_mu_divappr_q */
+ if (nn - dn > 2 && dn >= 2)
+ {
+ itch = mpn_mu_divappr_q_itch (nn, dn, 0);
+ if (itch + 1 > alloc)
+ {
+ scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
+ alloc = itch + 1;
+ }
+ scratch[itch] = ran;
+ MPN_COPY (qp, junkp, nn - dn);
+ qp[nn - dn] = mpn_mu_divappr_q (qp, np, nn, dnp, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ check_one (qp, NULL, np, nn, dnp, dn, "mpn_mu_divappr_q", 4);
+ }
+
+ /* Test mpn_mu_div_q */
+ if (nn - dn > 2 && dn >= 2)
+ {
+ itch = mpn_mu_div_q_itch (nn, dn, 0);
+ if (itch + 1> alloc)
+ {
+ scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
+ alloc = itch + 1;
+ }
+ scratch[itch] = ran;
+ MPN_COPY (qp, junkp, nn - dn);
+ qp[nn - dn] = mpn_mu_div_q (qp, np, nn, dnp, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ check_one (qp, NULL, np, nn, dnp, dn, "mpn_mu_div_q", 0);
+ }
+
+ if (1)
+ {
+ itch = nn + 1;
+ if (itch + 1> alloc)
+ {
+ scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
+ alloc = itch + 1;
+ }
+ scratch[itch] = ran;
+ mpn_div_q (qp, np, nn, dup, dn, scratch);
+ ASSERT_ALWAYS (ran == scratch[itch]);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
+ check_one (qp, NULL, np, nn, dup, dn, "mpn_div_q", 0);
+ }
+
+ if (dn >= 2 && nn >= 2)
+ {
+ mp_limb_t qh;
+
+ /* mpn_divrem_2 */
+ MPN_COPY (rp, np, nn);
+ qp[nn - 2] = qp[nn-1] = qran1;
+
+ qh = mpn_divrem_2 (qp, 0, rp, nn, dnp + dn - 2);
+ ASSERT_ALWAYS (qp[nn - 2] == qran1);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - 1] == qran1);
+ qp[nn - 2] = qh;
+ check_one (qp, rp, np, nn, dnp + dn - 2, 2, "mpn_divrem_2", 0);
+
+ /* Missing: divrem_2 with fraction limbs. */
+
+ /* mpn_div_qr_2 */
+ qp[nn - 2] = qran1;
+
+ qh = mpn_div_qr_2 (qp, rp, np, nn, dup + dn - 2);
+ ASSERT_ALWAYS (qp[nn - 2] == qran1);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - 1] == qran1);
+ qp[nn - 2] = qh;
+ check_one (qp, rp, np, nn, dup + dn - 2, 2, "mpn_div_qr_2", 0);
+ }
+ if (dn >= 1 && nn >= 1)
+ {
+ /* mpn_div_qr_1 */
+ mp_limb_t qh;
+ qp[nn-1] = qran1;
+ rp[0] = mpn_div_qr_1 (qp, &qh, np, nn, dnp[dn - 1]);
+ ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - 1] == qran1);
+ qp[nn - 1] = qh;
+ check_one (qp, rp, np, nn, dnp + dn - 1, 1, "mpn_div_qr_1", 0);
+ }
+ }
+
+ __GMP_FREE_FUNC_LIMBS (scratch, alloc);
+
+ TMP_FREE;
+
+ mpz_clear (n);
+ mpz_clear (d);
+ mpz_clear (q);
+ mpz_clear (r);
+ mpz_clear (tz);
+ mpz_clear (junk);
+
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-divrem_1.c b/gmp/tests/mpn/t-divrem_1.c
new file mode 100644
index 0000000000..9ffe90548f
--- /dev/null
+++ b/gmp/tests/mpn/t-divrem_1.c
@@ -0,0 +1,124 @@
+/* Test mpn_divrem_1 and mpn_preinv_divrem_1.
+
+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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_data (void)
+{
+ static const struct {
+ mp_limb_t n[1];
+ mp_size_t nsize;
+ mp_limb_t d;
+ mp_size_t qxn;
+ mp_limb_t want_q[5];
+ mp_limb_t want_r;
+ } data[] = {
+ { { 0 }, 1, 1, 0,
+ { 0 }, 0},
+
+ { { 5 }, 1, 2, 0,
+ { 2 }, 1},
+
+ /* Exercises the q update in the nl == constant 0 case of
+ udiv_qrnnd_preinv3. Test case copied from t-fat.c. */
+ { { 287 }, 1, 7, 1,
+ { 0, 41 }, 0 },
+
+#if GMP_NUMB_BITS == 32
+ { { 0x3C }, 1, 0xF2, 1,
+ { 0x3F789854, 0 }, 0x98 },
+#endif
+
+#if GMP_NUMB_BITS == 64
+ { { 0x3C }, 1, 0xF2, 1,
+ { CNST_LIMB(0x3F789854A0CB1B81), 0 }, 0x0E },
+
+ /* This case exposed some wrong code generated by SGI cc on mips64 irix
+ 6.5 with -n32 -O2, in the fractional loop for normalized divisor
+ using udiv_qrnnd_preinv. A test "x>al" in one of the sub_ddmmss
+ expansions came out wrong, leading to an incorrect quotient. */
+ { { CNST_LIMB(0x3C00000000000000) }, 1, CNST_LIMB(0xF200000000000000), 1,
+ { CNST_LIMB(0x3F789854A0CB1B81), 0 }, CNST_LIMB(0x0E00000000000000) },
+#endif
+ };
+
+ mp_limb_t dinv, got_r, got_q[numberof(data[0].want_q)];
+ mp_size_t qsize;
+ int i, shift;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ qsize = data[i].nsize + data[i].qxn;
+ ASSERT_ALWAYS (qsize <= numberof (got_q));
+
+ got_r = mpn_divrem_1 (got_q, data[i].qxn, data[i].n, data[i].nsize,
+ data[i].d);
+ if (got_r != data[i].want_r
+ || refmpn_cmp (got_q, data[i].want_q, qsize) != 0)
+ {
+ printf ("mpn_divrem_1 wrong at data[%d]\n", i);
+ bad:
+ mpn_trace (" n", data[i].n, data[i].nsize);
+ printf (" nsize=%ld\n", (long) data[i].nsize);
+ mp_limb_trace (" d", data[i].d);
+ printf (" qxn=%ld\n", (long) data[i].qxn);
+ mpn_trace (" want q", data[i].want_q, qsize);
+ mpn_trace (" got q", got_q, qsize);
+ mp_limb_trace (" want r", data[i].want_r);
+ mp_limb_trace (" got r", got_r);
+ abort ();
+ }
+
+ /* test if available */
+#if USE_PREINV_DIVREM_1 || HAVE_NATIVE_mpn_preinv_divrem_1
+ shift = refmpn_count_leading_zeros (data[i].d);
+ dinv = refmpn_invert_limb (data[i].d << shift);
+ got_r = mpn_preinv_divrem_1 (got_q, data[i].qxn,
+ data[i].n, data[i].nsize,
+ data[i].d, dinv, shift);
+ if (got_r != data[i].want_r
+ || refmpn_cmp (got_q, data[i].want_q, qsize) != 0)
+ {
+ printf ("mpn_preinv divrem_1 wrong at data[%d]\n", i);
+ printf (" shift=%d\n", shift);
+ mp_limb_trace (" dinv", dinv);
+ goto bad;
+ }
+#endif
+ }
+}
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpn/t-fat.c b/gmp/tests/mpn/t-fat.c
new file mode 100644
index 0000000000..abb288e4b0
--- /dev/null
+++ b/gmp/tests/mpn/t-fat.c
@@ -0,0 +1,311 @@
+/* Test fat binary setups.
+
+Copyright 2003, 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+
+/* In this program we're aiming to pick up certain subtle problems that
+ might creep into a fat binary.
+
+ 1. We want to ensure the application entry point routines like
+ __gmpn_add_n dispatch to the correct field of __gmpn_cpuvec.
+
+ Note that these routines are not exercised as a side effect of other
+ tests (eg. the mpz routines). Internally the fields of __gmpn_cpuvec
+ are used directly, so we need to write test code explicitly calling
+ the mpn functions, like an application will have.
+
+ 2. We want to ensure the initial __gmpn_cpuvec data has the initializer
+ function pointers in the correct fields, and that those initializer
+ functions dispatch to their correct corresponding field once
+ initialization has been done.
+
+ Only one of the initializer routines executes in a normal program,
+ since that routine sets all the pointers to actual mpn functions. We
+ forcibly reset __gmpn_cpuvec so we can run each.
+
+ In both cases for the above, the data put through the functions is
+ nothing special, just enough to verify that for instance an add_n is
+ really doing an add_n and has not for instance mistakenly gone to sub_n
+ or something.
+
+ The loop around each test will exercise the initializer routine on the
+ first iteration, and the dispatcher routine on the second.
+
+ If the dispatcher and/or initializer routines are generated mechanically
+ via macros (eg. mpn/x86/fat/fat_entry.asm) then there shouldn't be too
+ much risk of them going wrong, provided the structure layout is correctly
+ expressed. But if they're in C then it's good to guard against typos in
+ what is rather repetitive code. The initializer data for __gmpn_cpuvec
+ in fat.c is always done by hand and is likewise a bit repetitive. */
+
+
+/* dummies when not a fat binary */
+#if ! WANT_FAT_BINARY
+struct cpuvec_t {
+ int dummy;
+};
+struct cpuvec_t __gmpn_cpuvec;
+#define ITERATE_FAT_THRESHOLDS() do { } while (0)
+#endif
+
+/* saved from program startup */
+struct cpuvec_t initial_cpuvec;
+
+void
+check_functions (void)
+{
+ mp_limb_t wp[2], xp[2], yp[2], r;
+ int i;
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 123;
+ yp[0] = 456;
+ mpn_add_n (wp, xp, yp, (mp_size_t) 1);
+ ASSERT_ALWAYS (wp[0] == 579);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 123;
+ wp[0] = 456;
+ r = mpn_addmul_1 (wp, xp, (mp_size_t) 1, CNST_LIMB(2));
+ ASSERT_ALWAYS (wp[0] == 702);
+ ASSERT_ALWAYS (r == 0);
+ }
+
+#if HAVE_NATIVE_mpn_copyd
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 123;
+ xp[1] = 456;
+ mpn_copyd (xp+1, xp, (mp_size_t) 1);
+ ASSERT_ALWAYS (xp[1] == 123);
+ }
+#endif
+
+#if HAVE_NATIVE_mpn_copyi
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 123;
+ xp[1] = 456;
+ mpn_copyi (xp, xp+1, (mp_size_t) 1);
+ ASSERT_ALWAYS (xp[0] == 456);
+ }
+#endif
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 1605;
+ mpn_divexact_1 (wp, xp, (mp_size_t) 1, CNST_LIMB(5));
+ ASSERT_ALWAYS (wp[0] == 321);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 1296;
+ r = mpn_divexact_by3c (wp, xp, (mp_size_t) 1, CNST_LIMB(0));
+ ASSERT_ALWAYS (wp[0] == 432);
+ ASSERT_ALWAYS (r == 0);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 287;
+ r = mpn_divrem_1 (wp, (mp_size_t) 1, xp, (mp_size_t) 1, CNST_LIMB(7));
+ ASSERT_ALWAYS (wp[1] == 41);
+ ASSERT_ALWAYS (wp[0] == 0);
+ ASSERT_ALWAYS (r == 0);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 12;
+ r = mpn_gcd_1 (xp, (mp_size_t) 1, CNST_LIMB(9));
+ ASSERT_ALWAYS (r == 3);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 0x1001;
+ mpn_lshift (wp, xp, (mp_size_t) 1, 1);
+ ASSERT_ALWAYS (wp[0] == 0x2002);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 14;
+ r = mpn_mod_1 (xp, (mp_size_t) 1, CNST_LIMB(4));
+ ASSERT_ALWAYS (r == 2);
+ }
+
+#if (GMP_NUMB_BITS % 4) == 0
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ int bits = (GMP_NUMB_BITS / 4) * 3;
+ mp_limb_t mod = (CNST_LIMB(1) << bits) - 1;
+ mp_limb_t want = GMP_NUMB_MAX % mod;
+ xp[0] = GMP_NUMB_MAX;
+ r = mpn_mod_34lsub1 (xp, (mp_size_t) 1);
+ ASSERT_ALWAYS (r % mod == want);
+ }
+#endif
+
+ /* DECL_modexact_1c_odd ((*modexact_1c_odd)); */
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 14;
+ r = mpn_mul_1 (wp, xp, (mp_size_t) 1, CNST_LIMB(4));
+ ASSERT_ALWAYS (wp[0] == 56);
+ ASSERT_ALWAYS (r == 0);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 5;
+ yp[0] = 7;
+ mpn_mul_basecase (wp, xp, (mp_size_t) 1, yp, (mp_size_t) 1);
+ ASSERT_ALWAYS (wp[0] == 35);
+ ASSERT_ALWAYS (wp[1] == 0);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 5;
+ yp[0] = 7;
+ mpn_mullo_basecase (wp, xp, yp, (mp_size_t) 1);
+ ASSERT_ALWAYS (wp[0] == 35);
+ }
+
+#if HAVE_NATIVE_mpn_preinv_divrem_1 && GMP_NAIL_BITS == 0
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 0x101;
+ r = mpn_preinv_divrem_1 (wp, (mp_size_t) 1, xp, (mp_size_t) 1,
+ GMP_LIMB_HIGHBIT,
+ refmpn_invert_limb (GMP_LIMB_HIGHBIT), 0);
+ ASSERT_ALWAYS (wp[0] == 0x202);
+ ASSERT_ALWAYS (wp[1] == 0);
+ ASSERT_ALWAYS (r == 0);
+ }
+#endif
+
+#if GMP_NAIL_BITS == 0
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = GMP_LIMB_HIGHBIT+123;
+ r = mpn_preinv_mod_1 (xp, (mp_size_t) 1, GMP_LIMB_HIGHBIT,
+ refmpn_invert_limb (GMP_LIMB_HIGHBIT));
+ ASSERT_ALWAYS (r == 123);
+ }
+#endif
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 0x8008;
+ mpn_rshift (wp, xp, (mp_size_t) 1, 1);
+ ASSERT_ALWAYS (wp[0] == 0x4004);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 5;
+ mpn_sqr_basecase (wp, xp, (mp_size_t) 1);
+ ASSERT_ALWAYS (wp[0] == 25);
+ ASSERT_ALWAYS (wp[1] == 0);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 999;
+ yp[0] = 666;
+ mpn_sub_n (wp, xp, yp, (mp_size_t) 1);
+ ASSERT_ALWAYS (wp[0] == 333);
+ }
+
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec));
+ for (i = 0; i < 2; i++)
+ {
+ xp[0] = 123;
+ wp[0] = 456;
+ r = mpn_submul_1 (wp, xp, (mp_size_t) 1, CNST_LIMB(2));
+ ASSERT_ALWAYS (wp[0] == 210);
+ ASSERT_ALWAYS (r == 0);
+ }
+}
+
+/* Expect the first use of each fat threshold to invoke the necessary
+ initialization. */
+void
+check_thresholds (void)
+{
+#define ITERATE(name,field) \
+ do { \
+ __gmpn_cpuvec_initialized = 0; \
+ memcpy (&__gmpn_cpuvec, &initial_cpuvec, sizeof (__gmpn_cpuvec)); \
+ ASSERT_ALWAYS (name != 0); \
+ ASSERT_ALWAYS (name == __gmpn_cpuvec.field); \
+ ASSERT_ALWAYS (__gmpn_cpuvec_initialized); \
+ } while (0)
+
+ ITERATE_FAT_THRESHOLDS ();
+}
+
+
+int
+main (void)
+{
+ memcpy (&initial_cpuvec, &__gmpn_cpuvec, sizeof (__gmpn_cpuvec));
+
+ tests_start ();
+
+ check_functions ();
+ check_thresholds ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpn/t-get_d.c b/gmp/tests/mpn/t-get_d.c
new file mode 100644
index 0000000000..1499391e06
--- /dev/null
+++ b/gmp/tests/mpn/t-get_d.c
@@ -0,0 +1,498 @@
+/* Test mpn_get_d.
+
+Copyright 2002-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 "config.h"
+
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#ifndef _GMP_IEEE_FLOATS
+#define _GMP_IEEE_FLOATS 0
+#endif
+
+
+/* Exercise various 2^n values, with various exponents and positive and
+ negative. */
+void
+check_onebit (void)
+{
+ static const int bit_table[] = {
+ 0, 1, 2, 3,
+ GMP_NUMB_BITS - 2, GMP_NUMB_BITS - 1,
+ GMP_NUMB_BITS,
+ GMP_NUMB_BITS + 1, GMP_NUMB_BITS + 2,
+ 2 * GMP_NUMB_BITS - 2, 2 * GMP_NUMB_BITS - 1,
+ 2 * GMP_NUMB_BITS,
+ 2 * GMP_NUMB_BITS + 1, 2 * GMP_NUMB_BITS + 2,
+ 3 * GMP_NUMB_BITS - 2, 3 * GMP_NUMB_BITS - 1,
+ 3 * GMP_NUMB_BITS,
+ 3 * GMP_NUMB_BITS + 1, 3 * GMP_NUMB_BITS + 2,
+ 4 * GMP_NUMB_BITS - 2, 4 * GMP_NUMB_BITS - 1,
+ 4 * GMP_NUMB_BITS,
+ 4 * GMP_NUMB_BITS + 1, 4 * GMP_NUMB_BITS + 2,
+ 5 * GMP_NUMB_BITS - 2, 5 * GMP_NUMB_BITS - 1,
+ 5 * GMP_NUMB_BITS,
+ 5 * GMP_NUMB_BITS + 1, 5 * GMP_NUMB_BITS + 2,
+ 6 * GMP_NUMB_BITS - 2, 6 * GMP_NUMB_BITS - 1,
+ 6 * GMP_NUMB_BITS,
+ 6 * GMP_NUMB_BITS + 1, 6 * GMP_NUMB_BITS + 2,
+ };
+ static const int exp_table[] = {
+ 0, -100, -10, -1, 1, 10, 100,
+ };
+
+ /* FIXME: It'd be better to base this on the float format. */
+#if defined (__vax) || defined (__vax__)
+ int limit = 127; /* vax fp numbers have limited range */
+#else
+ int limit = 511;
+#endif
+
+ int bit_i, exp_i, i;
+ double got, want;
+ mp_size_t nsize, sign;
+ long bit, exp, want_bit;
+ mp_limb_t np[20];
+
+ for (bit_i = 0; bit_i < numberof (bit_table); bit_i++)
+ {
+ bit = bit_table[bit_i];
+
+ nsize = BITS_TO_LIMBS (bit+1);
+ refmpn_zero (np, nsize);
+ np[bit/GMP_NUMB_BITS] = CNST_LIMB(1) << (bit % GMP_NUMB_BITS);
+
+ for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
+ {
+ exp = exp_table[exp_i];
+
+ want_bit = bit + exp;
+ if (want_bit >= limit || want_bit <= -limit)
+ continue;
+
+ want = 1.0;
+ for (i = 0; i < want_bit; i++)
+ want *= 2.0;
+ for (i = 0; i > want_bit; i--)
+ want *= 0.5;
+
+ for (sign = 0; sign >= -1; sign--, want = -want)
+ {
+ got = mpn_get_d (np, nsize, sign, exp);
+ if (got != want)
+ {
+ printf ("mpn_get_d wrong on 2^n\n");
+ printf (" bit %ld\n", bit);
+ printf (" exp %ld\n", exp);
+ printf (" want_bit %ld\n", want_bit);
+ printf (" sign %ld\n", (long) sign);
+ mpn_trace (" n ", np, nsize);
+ printf (" nsize %ld\n", (long) nsize);
+ d_trace (" want ", want);
+ d_trace (" got ", got);
+ abort();
+ }
+ }
+ }
+ }
+}
+
+
+/* Exercise values 2^n+1, while such a value fits the mantissa of a double. */
+void
+check_twobit (void)
+{
+ int i, mant_bits;
+ double got, want;
+ mp_size_t nsize, sign;
+ mp_ptr np;
+
+ mant_bits = tests_dbl_mant_bits ();
+ if (mant_bits == 0)
+ return;
+
+ np = refmpn_malloc_limbs (BITS_TO_LIMBS (mant_bits));
+ want = 3.0;
+ for (i = 1; i < mant_bits; i++)
+ {
+ nsize = BITS_TO_LIMBS (i+1);
+ refmpn_zero (np, nsize);
+ np[i/GMP_NUMB_BITS] = CNST_LIMB(1) << (i % GMP_NUMB_BITS);
+ np[0] |= 1;
+
+ for (sign = 0; sign >= -1; sign--)
+ {
+ got = mpn_get_d (np, nsize, sign, 0);
+ if (got != want)
+ {
+ printf ("mpn_get_d wrong on 2^%d + 1\n", i);
+ printf (" sign %ld\n", (long) sign);
+ mpn_trace (" n ", np, nsize);
+ printf (" nsize %ld\n", (long) nsize);
+ d_trace (" want ", want);
+ d_trace (" got ", got);
+ abort();
+ }
+ want = -want;
+ }
+
+ want = 2.0 * want - 1.0;
+ }
+
+ free (np);
+}
+
+
+/* Expect large negative exponents to underflow to 0.0.
+ Some systems might have hardware traps for such an underflow (though
+ usually it's not the default), so watch out for SIGFPE. */
+void
+check_underflow (void)
+{
+ static const long exp_table[] = {
+ -999999L, LONG_MIN,
+ };
+ static const mp_limb_t np[1] = { 1 };
+
+ static long exp;
+ mp_size_t nsize, sign;
+ double got;
+ int exp_i;
+
+ nsize = numberof (np);
+
+ if (tests_setjmp_sigfpe() == 0)
+ {
+ for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
+ {
+ exp = exp_table[exp_i];
+
+ for (sign = 0; sign >= -1; sign--)
+ {
+ got = mpn_get_d (np, nsize, sign, exp);
+ if (got != 0.0)
+ {
+ printf ("mpn_get_d wrong, didn't get 0.0 on underflow\n");
+ printf (" nsize %ld\n", (long) nsize);
+ printf (" exp %ld\n", exp);
+ printf (" sign %ld\n", (long) sign);
+ d_trace (" got ", got);
+ abort ();
+ }
+ }
+ }
+ }
+ else
+ {
+ printf ("Warning, underflow to zero tests skipped due to SIGFPE (exp=%ld)\n", exp);
+ }
+ tests_sigfpe_done ();
+}
+
+
+/* Expect large values to result in +/-inf, on IEEE systems. */
+void
+check_inf (void)
+{
+ static const long exp_table[] = {
+ 999999L, LONG_MAX,
+ };
+ static const mp_limb_t np[4] = { 1, 1, 1, 1 };
+ long exp;
+ mp_size_t nsize, sign, got_sign;
+ double got;
+ int exp_i;
+
+ if (! _GMP_IEEE_FLOATS)
+ return;
+
+ for (nsize = 1; nsize <= numberof (np); nsize++)
+ {
+ for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
+ {
+ exp = exp_table[exp_i];
+
+ for (sign = 0; sign >= -1; sign--)
+ {
+ got = mpn_get_d (np, nsize, sign, exp);
+ got_sign = (got >= 0 ? 0 : -1);
+ if (! tests_isinf (got))
+ {
+ printf ("mpn_get_d wrong, didn't get infinity\n");
+ bad:
+ printf (" nsize %ld\n", (long) nsize);
+ printf (" exp %ld\n", exp);
+ printf (" sign %ld\n", (long) sign);
+ d_trace (" got ", got);
+ printf (" got sign %ld\n", (long) got_sign);
+ abort ();
+ }
+ if (got_sign != sign)
+ {
+ printf ("mpn_get_d wrong sign on infinity\n");
+ goto bad;
+ }
+ }
+ }
+ }
+}
+
+/* Check values 2^n approaching and into IEEE denorm range.
+ Some systems might not support denorms, or might have traps setup, so
+ watch out for SIGFPE. */
+void
+check_ieee_denorm (void)
+{
+ static long exp;
+ mp_limb_t n = 1;
+ long i;
+ mp_size_t sign;
+ double want, got;
+
+ if (! _GMP_IEEE_FLOATS)
+ return;
+
+ if (tests_setjmp_sigfpe() == 0)
+ {
+ exp = -1020;
+ want = 1.0;
+ for (i = 0; i > exp; i--)
+ want *= 0.5;
+
+ for ( ; exp > -1500 && want != 0.0; exp--)
+ {
+ for (sign = 0; sign >= -1; sign--)
+ {
+ got = mpn_get_d (&n, (mp_size_t) 1, sign, exp);
+ if (got != want)
+ {
+ printf ("mpn_get_d wrong on denorm\n");
+ printf (" n=1\n");
+ printf (" exp %ld\n", exp);
+ printf (" sign %ld\n", (long) sign);
+ d_trace (" got ", got);
+ d_trace (" want ", want);
+ abort ();
+ }
+ want = -want;
+ }
+ want *= 0.5;
+ FORCE_DOUBLE (want);
+ }
+ }
+ else
+ {
+ printf ("Warning, IEEE denorm tests skipped due to SIGFPE (exp=%ld)\n", exp);
+ }
+ tests_sigfpe_done ();
+}
+
+
+/* Check values 2^n approaching exponent overflow.
+ Some systems might trap on overflow, so watch out for SIGFPE. */
+void
+check_ieee_overflow (void)
+{
+ static long exp;
+ mp_limb_t n = 1;
+ long i;
+ mp_size_t sign;
+ double want, got;
+
+ if (! _GMP_IEEE_FLOATS)
+ return;
+
+ if (tests_setjmp_sigfpe() == 0)
+ {
+ exp = 1010;
+ want = 1.0;
+ for (i = 0; i < exp; i++)
+ want *= 2.0;
+
+ for ( ; exp < 1050; exp++)
+ {
+ for (sign = 0; sign >= -1; sign--)
+ {
+ got = mpn_get_d (&n, (mp_size_t) 1, sign, exp);
+ if (got != want)
+ {
+ printf ("mpn_get_d wrong on overflow\n");
+ printf (" n=1\n");
+ printf (" exp %ld\n", exp);
+ printf (" sign %ld\n", (long) sign);
+ d_trace (" got ", got);
+ d_trace (" want ", want);
+ abort ();
+ }
+ want = -want;
+ }
+ want *= 2.0;
+ FORCE_DOUBLE (want);
+ }
+ }
+ else
+ {
+ printf ("Warning, IEEE overflow tests skipped due to SIGFPE (exp=%ld)\n", exp);
+ }
+ tests_sigfpe_done ();
+}
+
+
+/* ARM gcc 2.95.4 was seen generating bad code for ulong->double
+ conversions, resulting in for instance 0x81c25113 incorrectly converted.
+ This test exercises that value, to see mpn_get_d has avoided the
+ problem. */
+void
+check_0x81c25113 (void)
+{
+#if GMP_NUMB_BITS >= 32
+ double want = 2176995603.0;
+ double got;
+ mp_limb_t np[4];
+ mp_size_t nsize;
+ long exp;
+
+ if (tests_dbl_mant_bits() < 32)
+ return;
+
+ for (nsize = 1; nsize <= numberof (np); nsize++)
+ {
+ refmpn_zero (np, nsize-1);
+ np[nsize-1] = CNST_LIMB(0x81c25113);
+ exp = - (nsize-1) * GMP_NUMB_BITS;
+ got = mpn_get_d (np, nsize, (mp_size_t) 0, exp);
+ if (got != want)
+ {
+ printf ("mpn_get_d wrong on 2176995603 (0x81c25113)\n");
+ printf (" nsize %ld\n", (long) nsize);
+ printf (" exp %ld\n", exp);
+ d_trace (" got ", got);
+ d_trace (" want ", want);
+ abort ();
+ }
+ }
+#endif
+}
+
+
+void
+check_rand (void)
+{
+ gmp_randstate_ptr rands = RANDS;
+ int rep, i;
+ unsigned long mant_bits;
+ long exp, exp_min, exp_max;
+ double got, want, d;
+ mp_size_t nalloc, nsize, sign;
+ mp_limb_t nhigh_mask;
+ mp_ptr np;
+
+ mant_bits = tests_dbl_mant_bits ();
+ if (mant_bits == 0)
+ return;
+
+ /* Allow for vax D format with exponent 127 to -128 only.
+ FIXME: Do something to probe for a valid exponent range. */
+ exp_min = -100 - mant_bits;
+ exp_max = 100 - mant_bits;
+
+ /* space for mant_bits */
+ nalloc = BITS_TO_LIMBS (mant_bits);
+ np = refmpn_malloc_limbs (nalloc);
+ nhigh_mask = MP_LIMB_T_MAX
+ >> (GMP_NAIL_BITS + nalloc * GMP_NUMB_BITS - mant_bits);
+
+ for (rep = 0; rep < 200; rep++)
+ {
+ /* random exp_min to exp_max, inclusive */
+ exp = exp_min + (long) gmp_urandomm_ui (rands, exp_max - exp_min + 1);
+
+ /* mant_bits worth of random at np */
+ if (rep & 1)
+ mpn_random (np, nalloc);
+ else
+ mpn_random2 (np, nalloc);
+ nsize = nalloc;
+ np[nsize-1] &= nhigh_mask;
+ MPN_NORMALIZE (np, nsize);
+ if (nsize == 0)
+ continue;
+
+ sign = (mp_size_t) gmp_urandomb_ui (rands, 1L) - 1;
+
+ /* want = {np,nsize}, converting one bit at a time */
+ want = 0.0;
+ for (i = 0, d = 1.0; i < mant_bits; i++, d *= 2.0)
+ if (np[i/GMP_NUMB_BITS] & (CNST_LIMB(1) << (i%GMP_NUMB_BITS)))
+ want += d;
+ if (sign < 0)
+ want = -want;
+
+ /* want = want * 2^exp */
+ for (i = 0; i < exp; i++)
+ want *= 2.0;
+ for (i = 0; i > exp; i--)
+ want *= 0.5;
+
+ got = mpn_get_d (np, nsize, sign, exp);
+
+ if (got != want)
+ {
+ printf ("mpn_get_d wrong on random data\n");
+ printf (" sign %ld\n", (long) sign);
+ mpn_trace (" n ", np, nsize);
+ printf (" nsize %ld\n", (long) nsize);
+ printf (" exp %ld\n", exp);
+ d_trace (" want ", want);
+ d_trace (" got ", got);
+ abort();
+ }
+ }
+
+ free (np);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_onebit ();
+ check_twobit ();
+ check_inf ();
+ check_underflow ();
+ check_ieee_denorm ();
+ check_ieee_overflow ();
+ check_0x81c25113 ();
+#if ! (defined (__vax) || defined (__vax__))
+ check_rand ();
+#endif
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpn/t-hgcd.c b/gmp/tests/mpn/t-hgcd.c
new file mode 100644
index 0000000000..64d33ef006
--- /dev/null
+++ b/gmp/tests/mpn/t-hgcd.c
@@ -0,0 +1,407 @@
+/* Test mpn_hgcd.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+static mp_size_t one_test (mpz_t, mpz_t, int);
+static void debug_mp (mpz_t, int);
+
+#define MIN_OPERAND_SIZE 2
+
+/* Fixed values, for regression testing of mpn_hgcd. */
+struct value { int res; const char *a; const char *b; };
+static const struct value hgcd_values[] = {
+#if GMP_NUMB_BITS == 32
+ { 5,
+ "0x1bddff867272a9296ac493c251d7f46f09a5591fe",
+ "0xb55930a2a68a916450a7de006031068c5ddb0e5c" },
+ { 4,
+ "0x2f0ece5b1ee9c15e132a01d55768dc13",
+ "0x1c6f4fd9873cdb24466e6d03e1cc66e7" },
+ { 3, "0x7FFFFC003FFFFFFFFFC5", "0x3FFFFE001FFFFFFFFFE3"},
+#endif
+ { -1, NULL, NULL }
+};
+
+struct hgcd_ref
+{
+ mpz_t m[2][2];
+};
+
+static void hgcd_ref_init (struct hgcd_ref *);
+static void hgcd_ref_clear (struct hgcd_ref *);
+static int hgcd_ref (struct hgcd_ref *, mpz_t, mpz_t);
+static int hgcd_ref_equal (const struct hgcd_matrix *, const struct hgcd_ref *);
+
+int
+main (int argc, char **argv)
+{
+ mpz_t op1, op2, temp1, temp2;
+ int i, j, chain_len;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long size_range;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (temp1);
+ mpz_init (temp2);
+
+ for (i = 0; hgcd_values[i].res >= 0; i++)
+ {
+ mp_size_t res;
+
+ mpz_set_str (op1, hgcd_values[i].a, 0);
+ mpz_set_str (op2, hgcd_values[i].b, 0);
+
+ res = one_test (op1, op2, -1-i);
+ if (res != hgcd_values[i].res)
+ {
+ fprintf (stderr, "ERROR in test %d\n", -1-i);
+ fprintf (stderr, "Bad return code from hgcd\n");
+ fprintf (stderr, "op1="); debug_mp (op1, -16);
+ fprintf (stderr, "op2="); debug_mp (op2, -16);
+ fprintf (stderr, "expected: %d\n", hgcd_values[i].res);
+ fprintf (stderr, "hgcd: %d\n", (int) res);
+ abort ();
+ }
+ }
+
+ for (i = 0; i < 15; i++)
+ {
+ /* Generate plain operands with unknown gcd. These types of operands
+ have proven to trigger certain bugs in development versions of the
+ gcd code. */
+
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 13 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_SIZE);
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_SIZE);
+
+ if (mpz_cmp (op1, op2) < 0)
+ mpz_swap (op1, op2);
+
+ if (mpz_size (op1) > 0)
+ one_test (op1, op2, i);
+
+ /* Generate a division chain backwards, allowing otherwise
+ unlikely huge quotients. */
+
+ mpz_set_ui (op1, 0);
+ mpz_urandomb (bs, rands, 32);
+ mpz_urandomb (bs, rands, mpz_get_ui (bs) % 16 + 1);
+ mpz_rrandomb (op2, rands, mpz_get_ui (bs));
+ mpz_add_ui (op2, op2, 1);
+
+#if 0
+ chain_len = 1000000;
+#else
+ mpz_urandomb (bs, rands, 32);
+ chain_len = mpz_get_ui (bs) % (GMP_NUMB_BITS * GCD_DC_THRESHOLD / 256);
+#endif
+
+ for (j = 0; j < chain_len; j++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1);
+ mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1);
+ mpz_add_ui (temp2, temp2, 1);
+ mpz_mul (temp1, op2, temp2);
+ mpz_add (op1, op1, temp1);
+
+ /* Don't generate overly huge operands. */
+ if (SIZ (op1) > 3 * GCD_DC_THRESHOLD)
+ break;
+
+ mpz_urandomb (bs, rands, 32);
+ mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1);
+ mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1);
+ mpz_add_ui (temp2, temp2, 1);
+ mpz_mul (temp1, op1, temp2);
+ mpz_add (op2, op2, temp1);
+
+ /* Don't generate overly huge operands. */
+ if (SIZ (op2) > 3 * GCD_DC_THRESHOLD)
+ break;
+ }
+ if (mpz_cmp (op1, op2) < 0)
+ mpz_swap (op1, op2);
+
+ if (mpz_size (op1) > 0)
+ one_test (op1, op2, i);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (op1);
+ mpz_clear (op2);
+ mpz_clear (temp1);
+ mpz_clear (temp2);
+
+ tests_end ();
+ exit (0);
+}
+
+static void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
+
+static int
+mpz_mpn_equal (const mpz_t a, mp_srcptr bp, mp_size_t bsize);
+
+static mp_size_t
+one_test (mpz_t a, mpz_t b, int i)
+{
+ struct hgcd_matrix hgcd;
+ struct hgcd_ref ref;
+
+ mpz_t ref_r0;
+ mpz_t ref_r1;
+ mpz_t hgcd_r0;
+ mpz_t hgcd_r1;
+
+ mp_size_t res[2];
+ mp_size_t asize;
+ mp_size_t bsize;
+
+ mp_size_t hgcd_init_scratch;
+ mp_size_t hgcd_scratch;
+
+ mp_ptr hgcd_init_tp;
+ mp_ptr hgcd_tp;
+
+ asize = a->_mp_size;
+ bsize = b->_mp_size;
+
+ ASSERT (asize >= bsize);
+
+ hgcd_init_scratch = MPN_HGCD_MATRIX_INIT_ITCH (asize);
+ hgcd_init_tp = refmpn_malloc_limbs (hgcd_init_scratch);
+ mpn_hgcd_matrix_init (&hgcd, asize, hgcd_init_tp);
+
+ hgcd_scratch = mpn_hgcd_itch (asize);
+ hgcd_tp = refmpn_malloc_limbs (hgcd_scratch);
+
+#if 0
+ fprintf (stderr,
+ "one_test: i = %d asize = %d, bsize = %d\n",
+ i, a->_mp_size, b->_mp_size);
+
+ gmp_fprintf (stderr,
+ "one_test: i = %d\n"
+ " a = %Zx\n"
+ " b = %Zx\n",
+ i, a, b);
+#endif
+ hgcd_ref_init (&ref);
+
+ mpz_init_set (ref_r0, a);
+ mpz_init_set (ref_r1, b);
+ res[0] = hgcd_ref (&ref, ref_r0, ref_r1);
+
+ mpz_init_set (hgcd_r0, a);
+ mpz_init_set (hgcd_r1, b);
+ if (bsize < asize)
+ {
+ _mpz_realloc (hgcd_r1, asize);
+ MPN_ZERO (hgcd_r1->_mp_d + bsize, asize - bsize);
+ }
+ res[1] = mpn_hgcd (hgcd_r0->_mp_d,
+ hgcd_r1->_mp_d,
+ asize,
+ &hgcd, hgcd_tp);
+
+ if (res[0] != res[1])
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ fprintf (stderr, "Different return value from hgcd and hgcd_ref\n");
+ fprintf (stderr, "op1="); debug_mp (a, -16);
+ fprintf (stderr, "op2="); debug_mp (b, -16);
+ fprintf (stderr, "hgcd_ref: %ld\n", (long) res[0]);
+ fprintf (stderr, "mpn_hgcd: %ld\n", (long) res[1]);
+ abort ();
+ }
+ if (res[0] > 0)
+ {
+ if (!hgcd_ref_equal (&hgcd, &ref)
+ || !mpz_mpn_equal (ref_r0, hgcd_r0->_mp_d, res[1])
+ || !mpz_mpn_equal (ref_r1, hgcd_r1->_mp_d, res[1]))
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ fprintf (stderr, "mpn_hgcd and hgcd_ref returned different values\n");
+ fprintf (stderr, "op1="); debug_mp (a, -16);
+ fprintf (stderr, "op2="); debug_mp (b, -16);
+ abort ();
+ }
+ }
+
+ refmpn_free_limbs (hgcd_init_tp);
+ refmpn_free_limbs (hgcd_tp);
+ hgcd_ref_clear (&ref);
+ mpz_clear (ref_r0);
+ mpz_clear (ref_r1);
+ mpz_clear (hgcd_r0);
+ mpz_clear (hgcd_r1);
+
+ return res[0];
+}
+
+static void
+hgcd_ref_init (struct hgcd_ref *hgcd)
+{
+ unsigned i;
+ for (i = 0; i<2; i++)
+ {
+ unsigned j;
+ for (j = 0; j<2; j++)
+ mpz_init (hgcd->m[i][j]);
+ }
+}
+
+static void
+hgcd_ref_clear (struct hgcd_ref *hgcd)
+{
+ unsigned i;
+ for (i = 0; i<2; i++)
+ {
+ unsigned j;
+ for (j = 0; j<2; j++)
+ mpz_clear (hgcd->m[i][j]);
+ }
+}
+
+
+static int
+sdiv_qr (mpz_t q, mpz_t r, mp_size_t s, const mpz_t a, const mpz_t b)
+{
+ mpz_fdiv_qr (q, r, a, b);
+ if (mpz_size (r) <= s)
+ {
+ mpz_add (r, r, b);
+ mpz_sub_ui (q, q, 1);
+ }
+
+ return (mpz_sgn (q) > 0);
+}
+
+static int
+hgcd_ref (struct hgcd_ref *hgcd, mpz_t a, mpz_t b)
+{
+ mp_size_t n = MAX (mpz_size (a), mpz_size (b));
+ mp_size_t s = n/2 + 1;
+ mp_size_t asize;
+ mp_size_t bsize;
+ mpz_t q;
+ int res;
+
+ if (mpz_size (a) <= s || mpz_size (b) <= s)
+ return 0;
+
+ res = mpz_cmp (a, b);
+ if (res < 0)
+ {
+ mpz_sub (b, b, a);
+ if (mpz_size (b) <= s)
+ return 0;
+
+ mpz_set_ui (hgcd->m[0][0], 1); mpz_set_ui (hgcd->m[0][1], 0);
+ mpz_set_ui (hgcd->m[1][0], 1); mpz_set_ui (hgcd->m[1][1], 1);
+ }
+ else if (res > 0)
+ {
+ mpz_sub (a, a, b);
+ if (mpz_size (a) <= s)
+ return 0;
+
+ mpz_set_ui (hgcd->m[0][0], 1); mpz_set_ui (hgcd->m[0][1], 1);
+ mpz_set_ui (hgcd->m[1][0], 0); mpz_set_ui (hgcd->m[1][1], 1);
+ }
+ else
+ return 0;
+
+ mpz_init (q);
+
+ for (;;)
+ {
+ ASSERT (mpz_size (a) > s);
+ ASSERT (mpz_size (b) > s);
+
+ if (mpz_cmp (a, b) > 0)
+ {
+ if (!sdiv_qr (q, a, s, a, b))
+ break;
+ mpz_addmul (hgcd->m[0][1], q, hgcd->m[0][0]);
+ mpz_addmul (hgcd->m[1][1], q, hgcd->m[1][0]);
+ }
+ else
+ {
+ if (!sdiv_qr (q, b, s, b, a))
+ break;
+ mpz_addmul (hgcd->m[0][0], q, hgcd->m[0][1]);
+ mpz_addmul (hgcd->m[1][0], q, hgcd->m[1][1]);
+ }
+ }
+
+ mpz_clear (q);
+
+ asize = mpz_size (a);
+ bsize = mpz_size (b);
+ return MAX (asize, bsize);
+}
+
+static int
+mpz_mpn_equal (const mpz_t a, mp_srcptr bp, mp_size_t bsize)
+{
+ mp_srcptr ap = a->_mp_d;
+ mp_size_t asize = a->_mp_size;
+
+ MPN_NORMALIZE (bp, bsize);
+ return asize == bsize && mpn_cmp (ap, bp, asize) == 0;
+}
+
+static int
+hgcd_ref_equal (const struct hgcd_matrix *hgcd, const struct hgcd_ref *ref)
+{
+ unsigned i;
+
+ for (i = 0; i<2; i++)
+ {
+ unsigned j;
+
+ for (j = 0; j<2; j++)
+ if (!mpz_mpn_equal (ref->m[i][j], hgcd->p[i][j], hgcd->n))
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/gmp/tests/mpn/t-hgcd_appr.c b/gmp/tests/mpn/t-hgcd_appr.c
new file mode 100644
index 0000000000..23ffbf0b76
--- /dev/null
+++ b/gmp/tests/mpn/t-hgcd_appr.c
@@ -0,0 +1,564 @@
+/* Test mpn_hgcd_appr.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-2004, 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+static mp_size_t one_test (mpz_t, mpz_t, int);
+static void debug_mp (mpz_t, int);
+
+#define MIN_OPERAND_SIZE 2
+
+struct hgcd_ref
+{
+ mpz_t m[2][2];
+};
+
+static void hgcd_ref_init (struct hgcd_ref *hgcd);
+static void hgcd_ref_clear (struct hgcd_ref *hgcd);
+static int hgcd_ref (struct hgcd_ref *hgcd, mpz_t a, mpz_t b);
+static int hgcd_ref_equal (const struct hgcd_ref *, const struct hgcd_ref *);
+static int hgcd_appr_valid_p (mpz_t, mpz_t, mp_size_t, struct hgcd_ref *,
+ mpz_t, mpz_t, mp_size_t, struct hgcd_matrix *);
+
+static int verbose_flag = 0;
+
+int
+main (int argc, char **argv)
+{
+ mpz_t op1, op2, temp1, temp2;
+ int i, j, chain_len;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long size_range;
+
+ if (argc > 1)
+ {
+ if (strcmp (argv[1], "-v") == 0)
+ verbose_flag = 1;
+ else
+ {
+ fprintf (stderr, "Invalid argument.\n");
+ return 1;
+ }
+ }
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (temp1);
+ mpz_init (temp2);
+
+ for (i = 0; i < 15; i++)
+ {
+ /* Generate plain operands with unknown gcd. These types of operands
+ have proven to trigger certain bugs in development versions of the
+ gcd code. */
+
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 13 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ mpz_urandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_SIZE);
+ mpz_urandomb (bs, rands, size_range);
+ mpz_urandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_SIZE);
+
+ if (mpz_cmp (op1, op2) < 0)
+ mpz_swap (op1, op2);
+
+ if (mpz_size (op1) > 0)
+ one_test (op1, op2, i);
+
+ /* Generate a division chain backwards, allowing otherwise
+ unlikely huge quotients. */
+
+ mpz_set_ui (op1, 0);
+ mpz_urandomb (bs, rands, 32);
+ mpz_urandomb (bs, rands, mpz_get_ui (bs) % 16 + 1);
+ mpz_rrandomb (op2, rands, mpz_get_ui (bs));
+ mpz_add_ui (op2, op2, 1);
+
+#if 0
+ chain_len = 1000000;
+#else
+ mpz_urandomb (bs, rands, 32);
+ chain_len = mpz_get_ui (bs) % (GMP_NUMB_BITS * GCD_DC_THRESHOLD / 256);
+#endif
+
+ for (j = 0; j < chain_len; j++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1);
+ mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1);
+ mpz_add_ui (temp2, temp2, 1);
+ mpz_mul (temp1, op2, temp2);
+ mpz_add (op1, op1, temp1);
+
+ /* Don't generate overly huge operands. */
+ if (SIZ (op1) > 3 * GCD_DC_THRESHOLD)
+ break;
+
+ mpz_urandomb (bs, rands, 32);
+ mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1);
+ mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1);
+ mpz_add_ui (temp2, temp2, 1);
+ mpz_mul (temp1, op1, temp2);
+ mpz_add (op2, op2, temp1);
+
+ /* Don't generate overly huge operands. */
+ if (SIZ (op2) > 3 * GCD_DC_THRESHOLD)
+ break;
+ }
+ if (mpz_cmp (op1, op2) < 0)
+ mpz_swap (op1, op2);
+
+ if (mpz_size (op1) > 0)
+ one_test (op1, op2, i);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (op1);
+ mpz_clear (op2);
+ mpz_clear (temp1);
+ mpz_clear (temp2);
+
+ tests_end ();
+ exit (0);
+}
+
+static void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
+
+static mp_size_t
+one_test (mpz_t a, mpz_t b, int i)
+{
+ struct hgcd_matrix hgcd;
+ struct hgcd_ref ref;
+
+ mpz_t ref_r0;
+ mpz_t ref_r1;
+ mpz_t hgcd_r0;
+ mpz_t hgcd_r1;
+
+ int res[2];
+ mp_size_t asize;
+ mp_size_t bsize;
+
+ mp_size_t hgcd_init_scratch;
+ mp_size_t hgcd_scratch;
+
+ mp_ptr hgcd_init_tp;
+ mp_ptr hgcd_tp;
+ mp_limb_t marker[4];
+
+ asize = a->_mp_size;
+ bsize = b->_mp_size;
+
+ ASSERT (asize >= bsize);
+
+ hgcd_init_scratch = MPN_HGCD_MATRIX_INIT_ITCH (asize);
+ hgcd_init_tp = refmpn_malloc_limbs (hgcd_init_scratch + 2) + 1;
+ mpn_hgcd_matrix_init (&hgcd, asize, hgcd_init_tp);
+
+ hgcd_scratch = mpn_hgcd_appr_itch (asize);
+ hgcd_tp = refmpn_malloc_limbs (hgcd_scratch + 2) + 1;
+
+ mpn_random (marker, 4);
+
+ hgcd_init_tp[-1] = marker[0];
+ hgcd_init_tp[hgcd_init_scratch] = marker[1];
+ hgcd_tp[-1] = marker[2];
+ hgcd_tp[hgcd_scratch] = marker[3];
+
+#if 0
+ fprintf (stderr,
+ "one_test: i = %d asize = %d, bsize = %d\n",
+ i, a->_mp_size, b->_mp_size);
+
+ gmp_fprintf (stderr,
+ "one_test: i = %d\n"
+ " a = %Zx\n"
+ " b = %Zx\n",
+ i, a, b);
+#endif
+ hgcd_ref_init (&ref);
+
+ mpz_init_set (ref_r0, a);
+ mpz_init_set (ref_r1, b);
+ res[0] = hgcd_ref (&ref, ref_r0, ref_r1);
+
+ mpz_init_set (hgcd_r0, a);
+ mpz_init_set (hgcd_r1, b);
+ if (bsize < asize)
+ {
+ _mpz_realloc (hgcd_r1, asize);
+ MPN_ZERO (hgcd_r1->_mp_d + bsize, asize - bsize);
+ }
+ res[1] = mpn_hgcd_appr (hgcd_r0->_mp_d,
+ hgcd_r1->_mp_d,
+ asize,
+ &hgcd, hgcd_tp);
+
+ if (hgcd_init_tp[-1] != marker[0]
+ || hgcd_init_tp[hgcd_init_scratch] != marker[1]
+ || hgcd_tp[-1] != marker[2]
+ || hgcd_tp[hgcd_scratch] != marker[3])
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ fprintf (stderr, "scratch space overwritten!\n");
+
+ if (hgcd_init_tp[-1] != marker[0])
+ gmp_fprintf (stderr,
+ "before init_tp: %Mx\n"
+ "expected: %Mx\n",
+ hgcd_init_tp[-1], marker[0]);
+ if (hgcd_init_tp[hgcd_init_scratch] != marker[1])
+ gmp_fprintf (stderr,
+ "after init_tp: %Mx\n"
+ "expected: %Mx\n",
+ hgcd_init_tp[hgcd_init_scratch], marker[1]);
+ if (hgcd_tp[-1] != marker[2])
+ gmp_fprintf (stderr,
+ "before tp: %Mx\n"
+ "expected: %Mx\n",
+ hgcd_tp[-1], marker[2]);
+ if (hgcd_tp[hgcd_scratch] != marker[3])
+ gmp_fprintf (stderr,
+ "after tp: %Mx\n"
+ "expected: %Mx\n",
+ hgcd_tp[hgcd_scratch], marker[3]);
+
+ abort ();
+ }
+
+ if (!hgcd_appr_valid_p (a, b, res[0], &ref, ref_r0, ref_r1,
+ res[1], &hgcd))
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ fprintf (stderr, "Invalid results for hgcd and hgcd_ref\n");
+ fprintf (stderr, "op1="); debug_mp (a, -16);
+ fprintf (stderr, "op2="); debug_mp (b, -16);
+ fprintf (stderr, "hgcd_ref: %ld\n", (long) res[0]);
+ fprintf (stderr, "mpn_hgcd_appr: %ld\n", (long) res[1]);
+ abort ();
+ }
+
+ refmpn_free_limbs (hgcd_init_tp - 1);
+ refmpn_free_limbs (hgcd_tp - 1);
+ hgcd_ref_clear (&ref);
+ mpz_clear (ref_r0);
+ mpz_clear (ref_r1);
+ mpz_clear (hgcd_r0);
+ mpz_clear (hgcd_r1);
+
+ return res[0];
+}
+
+static void
+hgcd_ref_init (struct hgcd_ref *hgcd)
+{
+ unsigned i;
+ for (i = 0; i<2; i++)
+ {
+ unsigned j;
+ for (j = 0; j<2; j++)
+ mpz_init (hgcd->m[i][j]);
+ }
+}
+
+static void
+hgcd_ref_clear (struct hgcd_ref *hgcd)
+{
+ unsigned i;
+ for (i = 0; i<2; i++)
+ {
+ unsigned j;
+ for (j = 0; j<2; j++)
+ mpz_clear (hgcd->m[i][j]);
+ }
+}
+
+static int
+sdiv_qr (mpz_t q, mpz_t r, mp_size_t s, const mpz_t a, const mpz_t b)
+{
+ mpz_fdiv_qr (q, r, a, b);
+ if (mpz_size (r) <= s)
+ {
+ mpz_add (r, r, b);
+ mpz_sub_ui (q, q, 1);
+ }
+
+ return (mpz_sgn (q) > 0);
+}
+
+static int
+hgcd_ref (struct hgcd_ref *hgcd, mpz_t a, mpz_t b)
+{
+ mp_size_t n = MAX (mpz_size (a), mpz_size (b));
+ mp_size_t s = n/2 + 1;
+ mpz_t q;
+ int res;
+
+ if (mpz_size (a) <= s || mpz_size (b) <= s)
+ return 0;
+
+ res = mpz_cmp (a, b);
+ if (res < 0)
+ {
+ mpz_sub (b, b, a);
+ if (mpz_size (b) <= s)
+ return 0;
+
+ mpz_set_ui (hgcd->m[0][0], 1); mpz_set_ui (hgcd->m[0][1], 0);
+ mpz_set_ui (hgcd->m[1][0], 1); mpz_set_ui (hgcd->m[1][1], 1);
+ }
+ else if (res > 0)
+ {
+ mpz_sub (a, a, b);
+ if (mpz_size (a) <= s)
+ return 0;
+
+ mpz_set_ui (hgcd->m[0][0], 1); mpz_set_ui (hgcd->m[0][1], 1);
+ mpz_set_ui (hgcd->m[1][0], 0); mpz_set_ui (hgcd->m[1][1], 1);
+ }
+ else
+ return 0;
+
+ mpz_init (q);
+
+ for (;;)
+ {
+ ASSERT (mpz_size (a) > s);
+ ASSERT (mpz_size (b) > s);
+
+ if (mpz_cmp (a, b) > 0)
+ {
+ if (!sdiv_qr (q, a, s, a, b))
+ break;
+ mpz_addmul (hgcd->m[0][1], q, hgcd->m[0][0]);
+ mpz_addmul (hgcd->m[1][1], q, hgcd->m[1][0]);
+ }
+ else
+ {
+ if (!sdiv_qr (q, b, s, b, a))
+ break;
+ mpz_addmul (hgcd->m[0][0], q, hgcd->m[0][1]);
+ mpz_addmul (hgcd->m[1][0], q, hgcd->m[1][1]);
+ }
+ }
+
+ mpz_clear (q);
+
+ return 1;
+}
+
+static int
+hgcd_ref_equal (const struct hgcd_ref *A, const struct hgcd_ref *B)
+{
+ unsigned i;
+
+ for (i = 0; i<2; i++)
+ {
+ unsigned j;
+
+ for (j = 0; j<2; j++)
+ if (mpz_cmp (A->m[i][j], B->m[i][j]) != 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+hgcd_appr_valid_p (mpz_t a, mpz_t b, mp_size_t res0,
+ struct hgcd_ref *ref, mpz_t ref_r0, mpz_t ref_r1,
+ mp_size_t res1, struct hgcd_matrix *hgcd)
+{
+ mp_size_t n = MAX (mpz_size (a), mpz_size (b));
+ mp_size_t s = n/2 + 1;
+
+ mp_bitcnt_t dbits, abits, margin;
+ mpz_t appr_r0, appr_r1, t, q;
+ struct hgcd_ref appr;
+
+ if (!res0)
+ {
+ if (!res1)
+ return 1;
+
+ fprintf (stderr, "mpn_hgcd_appr returned 1 when no reduction possible.\n");
+ return 0;
+ }
+
+ /* NOTE: No *_clear calls on error return, since we're going to
+ abort anyway. */
+ mpz_init (t);
+ mpz_init (q);
+ hgcd_ref_init (&appr);
+ mpz_init (appr_r0);
+ mpz_init (appr_r1);
+
+ if (mpz_size (ref_r0) <= s)
+ {
+ fprintf (stderr, "ref_r0 too small!!!: "); debug_mp (ref_r0, 16);
+ return 0;
+ }
+ if (mpz_size (ref_r1) <= s)
+ {
+ fprintf (stderr, "ref_r1 too small!!!: "); debug_mp (ref_r1, 16);
+ return 0;
+ }
+
+ mpz_sub (t, ref_r0, ref_r1);
+ dbits = mpz_sizeinbase (t, 2);
+ if (dbits > s*GMP_NUMB_BITS)
+ {
+ fprintf (stderr, "ref |r0 - r1| too large!!!: "); debug_mp (t, 16);
+ return 0;
+ }
+
+ if (!res1)
+ {
+ mpz_set (appr_r0, a);
+ mpz_set (appr_r1, b);
+ }
+ else
+ {
+ unsigned i;
+
+ for (i = 0; i<2; i++)
+ {
+ unsigned j;
+
+ for (j = 0; j<2; j++)
+ {
+ mp_size_t mn = hgcd->n;
+ MPN_NORMALIZE (hgcd->p[i][j], mn);
+ mpz_realloc (appr.m[i][j], mn);
+ MPN_COPY (PTR (appr.m[i][j]), hgcd->p[i][j], mn);
+ SIZ (appr.m[i][j]) = mn;
+ }
+ }
+ mpz_mul (appr_r0, appr.m[1][1], a);
+ mpz_mul (t, appr.m[0][1], b);
+ mpz_sub (appr_r0, appr_r0, t);
+ if (mpz_sgn (appr_r0) <= 0
+ || mpz_size (appr_r0) <= s)
+ {
+ fprintf (stderr, "appr_r0 too small: "); debug_mp (appr_r0, 16);
+ return 0;
+ }
+
+ mpz_mul (appr_r1, appr.m[1][0], a);
+ mpz_mul (t, appr.m[0][0], b);
+ mpz_sub (appr_r1, t, appr_r1);
+ if (mpz_sgn (appr_r1) <= 0
+ || mpz_size (appr_r1) <= s)
+ {
+ fprintf (stderr, "appr_r1 too small: "); debug_mp (appr_r1, 16);
+ return 0;
+ }
+ }
+
+ mpz_sub (t, appr_r0, appr_r1);
+ abits = mpz_sizeinbase (t, 2);
+ if (abits < dbits)
+ {
+ fprintf (stderr, "|r0 - r1| too small: "); debug_mp (t, 16);
+ return 0;
+ }
+
+ /* We lose one bit each time we discard the least significant limbs.
+ For the lehmer code, that can happen at most s * (GMP_NUMB_BITS)
+ / (GMP_NUMB_BITS - 1) times. For the dc code, we lose an entire
+ limb (or more?) for each level of recursion. */
+
+ margin = (n/2+1) * GMP_NUMB_BITS / (GMP_NUMB_BITS - 1);
+ {
+ mp_size_t rn;
+ for (rn = n; ABOVE_THRESHOLD (rn, HGCD_APPR_THRESHOLD); rn = (rn + 1)/2)
+ margin += GMP_NUMB_BITS;
+ }
+
+ if (verbose_flag && abits > dbits)
+ fprintf (stderr, "n = %u: sbits = %u: ref #(r0-r1): %u, appr #(r0-r1): %u excess: %d, margin: %u\n",
+ (unsigned) n, (unsigned) s*GMP_NUMB_BITS,
+ (unsigned) dbits, (unsigned) abits,
+ (int) (abits - s * GMP_NUMB_BITS), (unsigned) margin);
+
+ if (abits > s*GMP_NUMB_BITS + margin)
+ {
+ fprintf (stderr, "appr |r0 - r1| much larger than minimal (by %u bits, margin = %u bits)\n",
+ (unsigned) (abits - s*GMP_NUMB_BITS), (unsigned) margin);
+ return 0;
+ }
+
+ while (mpz_cmp (appr_r0, ref_r0) > 0 || mpz_cmp (appr_r1, ref_r1) > 0)
+ {
+ ASSERT (mpz_size (appr_r0) > s);
+ ASSERT (mpz_size (appr_r1) > s);
+
+ if (mpz_cmp (appr_r0, appr_r1) > 0)
+ {
+ if (!sdiv_qr (q, appr_r0, s, appr_r0, appr_r1))
+ break;
+ mpz_addmul (appr.m[0][1], q, appr.m[0][0]);
+ mpz_addmul (appr.m[1][1], q, appr.m[1][0]);
+ }
+ else
+ {
+ if (!sdiv_qr (q, appr_r1, s, appr_r1, appr_r0))
+ break;
+ mpz_addmul (appr.m[0][0], q, appr.m[0][1]);
+ mpz_addmul (appr.m[1][0], q, appr.m[1][1]);
+ }
+ }
+
+ if (mpz_cmp (appr_r0, ref_r0) != 0
+ || mpz_cmp (appr_r1, ref_r1) != 0
+ || !hgcd_ref_equal (ref, &appr))
+ {
+ fprintf (stderr, "appr_r0: "); debug_mp (appr_r0, 16);
+ fprintf (stderr, "ref_r0: "); debug_mp (ref_r0, 16);
+
+ fprintf (stderr, "appr_r1: "); debug_mp (appr_r1, 16);
+ fprintf (stderr, "ref_r1: "); debug_mp (ref_r1, 16);
+
+ return 0;
+ }
+ mpz_clear (t);
+ mpz_clear (q);
+ hgcd_ref_clear (&appr);
+ mpz_clear (appr_r0);
+ mpz_clear (appr_r1);
+
+ return 1;
+}
diff --git a/gmp/tests/mpn/t-instrument.c b/gmp/tests/mpn/t-instrument.c
new file mode 100644
index 0000000000..338fef1773
--- /dev/null
+++ b/gmp/tests/mpn/t-instrument.c
@@ -0,0 +1,416 @@
+/* Test assembler support for --enable-profiling=instrument.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+
+#if WANT_PROFILING_INSTRUMENT
+
+/* This program exercises each mpn routine that might be implemented in
+ assembler. It ensures the __cyg_profile_func_enter and exit calls have
+ come out right, and that in the x86 code "ret_internal" is correctly used
+ for PIC setups. */
+
+
+/* Changes to enter_seen done by __cyg_profile_func_enter are essentially
+ unknown to the optimizer, so must use volatile. */
+volatile int enter_seen;
+
+/* Dummy used to stop various calls going dead. */
+unsigned long notdead;
+
+const char *name = "<none>";
+int old_ncall;
+
+struct {
+ void *this_fn;
+ void *call_site;
+} call[100];
+int ncall;
+
+
+void __cyg_profile_func_enter (void *, void *)
+ __attribute__ ((no_instrument_function));
+
+void
+__cyg_profile_func_enter (void *this_fn, void *call_site)
+{
+#if 0
+ printf ("%24s %p %p\n", name, this_fn, call_site);
+#endif
+ ASSERT_ALWAYS (ncall >= 0);
+ ASSERT_ALWAYS (ncall <= numberof (call));
+
+ if (ncall >= numberof (call))
+ {
+ printf ("__cyg_profile_func_enter: oops, call stack full, from %s\n", name);
+ abort ();
+ }
+
+ enter_seen = 1;
+ call[ncall].this_fn = this_fn;
+ call[ncall].call_site = call_site;
+ ncall++;
+}
+
+void __cyg_profile_func_exit (void *, void *)
+ __attribute__ ((no_instrument_function));
+
+void
+__cyg_profile_func_exit (void *this_fn, void *call_site)
+{
+ ASSERT_ALWAYS (ncall >= 0);
+ ASSERT_ALWAYS (ncall <= numberof (call));
+
+ if (ncall == 0)
+ {
+ printf ("__cyg_profile_func_exit: call stack empty, from %s\n", name);
+ abort ();
+ }
+
+ ncall--;
+ if (this_fn != call[ncall].this_fn || call_site != call[ncall].call_site)
+ {
+ printf ("__cyg_profile_func_exit: unbalanced this_fn/call_site from %s\n", name);
+ printf (" this_fn got %p\n", this_fn);
+ printf (" want %p\n", call[ncall].this_fn);
+ printf (" call_site got %p\n", call_site);
+ printf (" want %p\n", call[ncall].call_site);
+ abort ();
+ }
+}
+
+
+void
+pre (const char *str)
+{
+ name = str;
+ enter_seen = 0;
+ old_ncall = ncall;
+}
+
+void
+post (void)
+{
+ if (! enter_seen)
+ {
+ printf ("did not reach __cyg_profile_func_enter from %s\n", name);
+ abort ();
+ }
+
+ if (ncall != old_ncall)
+ {
+ printf ("unbalance enter/exit calls from %s\n", name);
+ printf (" ncall %d\n", ncall);
+ printf (" old_ncall %d\n", old_ncall);
+ abort ();
+ }
+}
+
+void
+check (void)
+{
+ mp_limb_t wp[100], xp[100], yp[100];
+ mp_size_t size = 100;
+
+ refmpn_zero (xp, size);
+ refmpn_zero (yp, size);
+ refmpn_zero (wp, size);
+
+ pre ("mpn_add_n");
+ mpn_add_n (wp, xp, yp, size);
+ post ();
+
+#if HAVE_NATIVE_mpn_add_nc
+ pre ("mpn_add_nc");
+ mpn_add_nc (wp, xp, yp, size, CNST_LIMB(0));
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_addlsh1_n
+ pre ("mpn_addlsh1_n");
+ mpn_addlsh1_n (wp, xp, yp, size);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_and_n
+ pre ("mpn_and_n");
+ mpn_and_n (wp, xp, yp, size);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_andn_n
+ pre ("mpn_andn_n");
+ mpn_andn_n (wp, xp, yp, size);
+ post ();
+#endif
+
+ pre ("mpn_addmul_1");
+ mpn_addmul_1 (wp, xp, size, yp[0]);
+ post ();
+
+#if HAVE_NATIVE_mpn_addmul_1c
+ pre ("mpn_addmul_1c");
+ mpn_addmul_1c (wp, xp, size, yp[0], CNST_LIMB(0));
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_com
+ pre ("mpn_com");
+ mpn_com (wp, xp, size);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_copyd
+ pre ("mpn_copyd");
+ mpn_copyd (wp, xp, size);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_copyi
+ pre ("mpn_copyi");
+ mpn_copyi (wp, xp, size);
+ post ();
+#endif
+
+ pre ("mpn_divexact_1");
+ mpn_divexact_1 (wp, xp, size, CNST_LIMB(123));
+ post ();
+
+ pre ("mpn_divexact_by3c");
+ mpn_divexact_by3c (wp, xp, size, CNST_LIMB(0));
+ post ();
+
+ pre ("mpn_divrem_1");
+ mpn_divrem_1 (wp, (mp_size_t) 0, xp, size, CNST_LIMB(123));
+ post ();
+
+#if HAVE_NATIVE_mpn_divrem_1c
+ pre ("mpn_divrem_1c");
+ mpn_divrem_1c (wp, (mp_size_t) 0, xp, size, CNST_LIMB(123), CNST_LIMB(122));
+ post ();
+#endif
+
+ pre ("mpn_gcd_1");
+ xp[0] |= 1;
+ notdead += (unsigned long) mpn_gcd_1 (xp, size, CNST_LIMB(123));
+ post ();
+
+ pre ("mpn_hamdist");
+ notdead += mpn_hamdist (xp, yp, size);
+ post ();
+
+#if HAVE_NATIVE_mpn_ior_n
+ pre ("mpn_ior_n");
+ mpn_ior_n (wp, xp, yp, size);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_iorn_n
+ pre ("mpn_iorn_n");
+ mpn_iorn_n (wp, xp, yp, size);
+ post ();
+#endif
+
+ pre ("mpn_lshift");
+ mpn_lshift (wp, xp, size, 1);
+ post ();
+
+ pre ("mpn_mod_1");
+ notdead += mpn_mod_1 (xp, size, CNST_LIMB(123));
+ post ();
+
+#if HAVE_NATIVE_mpn_mod_1c
+ pre ("mpn_mod_1c");
+ notdead += mpn_mod_1c (xp, size, CNST_LIMB(123), CNST_LIMB(122));
+ post ();
+#endif
+
+#if GMP_NUMB_BITS % 4 == 0
+ pre ("mpn_mod_34lsub1");
+ notdead += mpn_mod_34lsub1 (xp, size);
+ post ();
+#endif
+
+ pre ("mpn_modexact_1_odd");
+ notdead += mpn_modexact_1_odd (xp, size, CNST_LIMB(123));
+ post ();
+
+ pre ("mpn_modexact_1c_odd");
+ notdead += mpn_modexact_1c_odd (xp, size, CNST_LIMB(123), CNST_LIMB(456));
+ post ();
+
+ pre ("mpn_mul_1");
+ mpn_mul_1 (wp, xp, size, yp[0]);
+ post ();
+
+#if HAVE_NATIVE_mpn_mul_1c
+ pre ("mpn_mul_1c");
+ mpn_mul_1c (wp, xp, size, yp[0], CNST_LIMB(0));
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_mul_2
+ pre ("mpn_mul_2");
+ mpn_mul_2 (wp, xp, size-1, yp);
+ post ();
+#endif
+
+ pre ("mpn_mul_basecase");
+ mpn_mul_basecase (wp, xp, (mp_size_t) 3, yp, (mp_size_t) 3);
+ post ();
+
+#if HAVE_NATIVE_mpn_nand_n
+ pre ("mpn_nand_n");
+ mpn_nand_n (wp, xp, yp, size);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_nior_n
+ pre ("mpn_nior_n");
+ mpn_nior_n (wp, xp, yp, size);
+ post ();
+#endif
+
+ pre ("mpn_popcount");
+ notdead += mpn_popcount (xp, size);
+ post ();
+
+ pre ("mpn_preinv_mod_1");
+ notdead += mpn_preinv_mod_1 (xp, size, GMP_NUMB_MAX,
+ refmpn_invert_limb (GMP_NUMB_MAX));
+ post ();
+
+#if USE_PREINV_DIVREM_1 || HAVE_NATIVE_mpn_preinv_divrem_1
+ pre ("mpn_preinv_divrem_1");
+ mpn_preinv_divrem_1 (wp, (mp_size_t) 0, xp, size, GMP_NUMB_MAX,
+ refmpn_invert_limb (GMP_NUMB_MAX), 0);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_rsh1add_n
+ pre ("mpn_rsh1add_n");
+ mpn_rsh1add_n (wp, xp, yp, size);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_rsh1sub_n
+ pre ("mpn_rsh1sub_n");
+ mpn_rsh1sub_n (wp, xp, yp, size);
+ post ();
+#endif
+
+ pre ("mpn_rshift");
+ mpn_rshift (wp, xp, size, 1);
+ post ();
+
+ pre ("mpn_sqr_basecase");
+ mpn_sqr_basecase (wp, xp, (mp_size_t) 3);
+ post ();
+
+ pre ("mpn_submul_1");
+ mpn_submul_1 (wp, xp, size, yp[0]);
+ post ();
+
+#if HAVE_NATIVE_mpn_submul_1c
+ pre ("mpn_submul_1c");
+ mpn_submul_1c (wp, xp, size, yp[0], CNST_LIMB(0));
+ post ();
+#endif
+
+ pre ("mpn_sub_n");
+ mpn_sub_n (wp, xp, yp, size);
+ post ();
+
+#if HAVE_NATIVE_mpn_sub_nc
+ pre ("mpn_sub_nc");
+ mpn_sub_nc (wp, xp, yp, size, CNST_LIMB(0));
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_sublsh1_n
+ pre ("mpn_sublsh1_n");
+ mpn_sublsh1_n (wp, xp, yp, size);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_udiv_qrnnd
+ pre ("mpn_udiv_qrnnd");
+ mpn_udiv_qrnnd (&wp[0], CNST_LIMB(122), xp[0], CNST_LIMB(123));
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_udiv_qrnnd_r
+ pre ("mpn_udiv_qrnnd_r");
+ mpn_udiv_qrnnd (CNST_LIMB(122), xp[0], CNST_LIMB(123), &wp[0]);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_umul_ppmm
+ pre ("mpn_umul_ppmm");
+ mpn_umul_ppmm (&wp[0], xp[0], yp[0]);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_umul_ppmm_r
+ pre ("mpn_umul_ppmm_r");
+ mpn_umul_ppmm_r (&wp[0], xp[0], yp[0]);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_xor_n
+ pre ("mpn_xor_n");
+ mpn_xor_n (wp, xp, yp, size);
+ post ();
+#endif
+
+#if HAVE_NATIVE_mpn_xnor_n
+ pre ("mpn_xnor_n");
+ mpn_xnor_n (wp, xp, yp, size);
+ post ();
+#endif
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ check ();
+
+ tests_end ();
+ exit (0);
+}
+
+
+#else /* ! WANT_PROFILING_INSTRUMENT */
+
+int
+main (void)
+{
+ exit (0);
+}
+
+#endif
diff --git a/gmp/tests/mpn/t-invert.c b/gmp/tests/mpn/t-invert.c
new file mode 100644
index 0000000000..c9b0080b76
--- /dev/null
+++ b/gmp/tests/mpn/t-invert.c
@@ -0,0 +1,161 @@
+/* Test for mpn_invert function.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+Copyright 2009 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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Sizes are up to 2^SIZE_LOG limbs */
+#ifndef SIZE_LOG
+#define SIZE_LOG 12
+#endif
+
+#ifndef COUNT
+#define COUNT 1000
+#endif
+
+#define MAX_N (1L << SIZE_LOG)
+#define MIN_N 1
+
+
+static int
+invert_valid (mp_srcptr ip, mp_srcptr dp, mp_size_t n)
+{
+ mp_ptr tp;
+ int cy;
+ TMP_DECL;
+
+ TMP_MARK;
+ tp = TMP_ALLOC_LIMBS (2*n);
+
+ refmpn_mul (tp, ip, n, dp, n);
+ cy = refmpn_add_n (tp + n, tp + n, dp, n); /* This must not give a carry. */
+ cy -= refmpn_add (tp, tp, 2*n, dp, n); /* This must give a carry. */
+ TMP_FREE;
+
+ return (cy == -1);
+}
+
+/*
+ Check the result of the mpn_invert function in the library.
+*/
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr ip, dp, scratch;
+ int count = COUNT;
+ int test;
+ gmp_randstate_ptr rands;
+ TMP_DECL;
+ TMP_MARK;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ tests_start ();
+ rands = RANDS;
+
+ dp = TMP_ALLOC_LIMBS (MAX_N);
+ ip = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
+ scratch
+ = 1+TMP_ALLOC_LIMBS (mpn_invert_itch (MAX_N) + 2);
+
+ for (test = 0; test < count; test++)
+ {
+ unsigned size_min;
+ unsigned size_range;
+ mp_size_t n;
+ mp_size_t itch;
+ mp_limb_t i_before, i_after, s_before, s_after;
+
+ for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
+ ;
+
+ /* We generate an in the MIN_N <= n <= (1 << size_range). */
+ size_range = size_min
+ + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
+
+ n = MIN_N
+ + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);
+
+ mpn_random2 (dp, n);
+
+ mpn_random2 (ip-1, n + 2);
+ i_before = ip[-1];
+ i_after = ip[n];
+
+ itch = mpn_invert_itch (n);
+ ASSERT_ALWAYS (itch <= mpn_invert_itch (MAX_N));
+ mpn_random2 (scratch-1, itch+2);
+ s_before = scratch[-1];
+ s_after = scratch[itch];
+
+ dp[n-1] |= GMP_NUMB_HIGHBIT;
+ mpn_invert (ip, dp, n, scratch);
+ if (ip[-1] != i_before || ip[n] != i_after
+ || scratch[-1] != s_before || scratch[itch] != s_after
+ || ! invert_valid(ip, dp, n))
+ {
+ printf ("ERROR in test %d, n = %d\n",
+ test, (int) n);
+ if (ip[-1] != i_before)
+ {
+ printf ("before ip:"); mpn_dump (ip -1, 1);
+ printf ("keep: "); mpn_dump (&i_before, 1);
+ }
+ if (ip[n] != i_after)
+ {
+ printf ("after ip:"); mpn_dump (ip + n, 1);
+ printf ("keep: "); mpn_dump (&i_after, 1);
+ }
+ if (scratch[-1] != s_before)
+ {
+ printf ("before scratch:"); mpn_dump (scratch-1, 1);
+ printf ("keep: "); mpn_dump (&s_before, 1);
+ }
+ if (scratch[itch] != s_after)
+ {
+ printf ("after scratch:"); mpn_dump (scratch + itch, 1);
+ printf ("keep: "); mpn_dump (&s_after, 1);
+ }
+ mpn_dump (dp, n);
+ mpn_dump (ip, n);
+
+ abort();
+ }
+ }
+ TMP_FREE;
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-iord_u.c b/gmp/tests/mpn/t-iord_u.c
new file mode 100644
index 0000000000..93e68c5c3f
--- /dev/null
+++ b/gmp/tests/mpn/t-iord_u.c
@@ -0,0 +1,221 @@
+/* Test MPN_INCR_U and MPN_DECR_U.
+
+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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* The i386 MPN_INCR_U and MPN_DECR_U have special cases for "n" being a
+ compile-time constant 1, so that's exercised explicitly. */
+
+
+#define M GMP_NUMB_MAX
+#define SIZE ((mp_size_t) 10)
+
+
+void
+check_one (const char *name, int i,
+ mp_srcptr src, mp_limb_t n,
+ mp_srcptr got, mp_srcptr want, mp_size_t size)
+{
+ if (! refmpn_equal_anynail (got, want, size))
+ {
+ printf ("Wrong at %s i=%d\n", name, i);
+ mpn_trace (" src", src, size);
+ mpn_trace (" n", &n, (mp_size_t) 1);
+ mpn_trace (" got", got, size);
+ mpn_trace (" want", want, size);
+ abort ();
+ }
+}
+
+
+void
+check_incr_data (void)
+{
+ static const struct {
+ mp_limb_t n;
+ const mp_limb_t src[SIZE];
+ const mp_limb_t want[SIZE];
+ } data[] = {
+ { 1, { 0 }, { 1 } },
+ { 1, { 123 }, { 124 } },
+ { 2, { 0 }, { 2 } },
+ { 2, { 123 }, { 125 } },
+ { M, { 0 }, { M } },
+
+ { 1, { M, 0 }, { 0, 1 } },
+ { 1, { M, 123 }, { 0, 124 } },
+ { 2, { M, 0 }, { 1, 1 } },
+ { 2, { M, 123 }, { 1, 124 } },
+ { M, { M, 0 }, { M-1, 1 } },
+ { M, { M, 123 }, { M-1, 124 } },
+
+ { 1, { M, M, 0 }, { 0, 0, 1 } },
+ { 1, { M, M, 123 }, { 0, 0, 124 } },
+ { 2, { M, M, 0 }, { 1, 0, 1 } },
+ { 2, { M, M, 123 }, { 1, 0, 124 } },
+ { M, { M, M, 0 }, { M-1, 0, 1 } },
+ { M, { M, M, 123 }, { M-1, 0, 124 } },
+
+ { 1, { M, M, M, 0 }, { 0, 0, 0, 1 } },
+ { 1, { M, M, M, 123 }, { 0, 0, 0, 124 } },
+ { 2, { M, M, M, 0 }, { 1, 0, 0, 1 } },
+ { 2, { M, M, M, 123 }, { 1, 0, 0, 124 } },
+ { M, { M, M, M, 0 }, { M-1, 0, 0, 1 } },
+ { M, { M, M, M, 123 }, { M-1, 0, 0, 124 } },
+
+ { 1, { M, M, M, M, 0 }, { 0, 0, 0, 0, 1 } },
+ { 1, { M, M, M, M, 123 }, { 0, 0, 0, 0, 124 } },
+ { 2, { M, M, M, M, 0 }, { 1, 0, 0, 0, 1 } },
+ { 2, { M, M, M, M, 123 }, { 1, 0, 0, 0, 124 } },
+ { M, { M, M, M, M, 0 }, { M-1, 0, 0, 0, 1 } },
+ { M, { M, M, M, M, 123 }, { M-1, 0, 0, 0, 124
+#if defined (__hpux) && ! defined (__GNUC__)
+ /* Some versions (at least HP92453-01 B.11.11.23709.GP) of the
+ HP C compilers fail to zero-fill aggregates as the ISO C standard
+ requires (cf 6.5.7 Initialization). Compensate here: */
+ , 0, 0, 0, 0, 0
+#endif
+ } }
+ };
+
+ mp_limb_t got[SIZE];
+ int i;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ refmpn_copyi (got, data[i].src, SIZE);
+ MPN_INCR_U (got, SIZE, data[i].n);
+ check_one ("check_incr (general)", i,
+ data[i].src, data[i].n,
+ got, data[i].want, SIZE);
+
+ if (data[i].n == 1)
+ {
+ refmpn_copyi (got, data[i].src, SIZE);
+ MPN_INCR_U (got, SIZE, CNST_LIMB(1));
+ check_one ("check_incr (const 1)", i,
+ data[i].src, data[i].n,
+ got, data[i].want, SIZE);
+ }
+ }
+}
+
+void
+check_decr_data (void)
+{
+ static const struct {
+ mp_limb_t n;
+ const mp_limb_t src[SIZE];
+ const mp_limb_t want[SIZE];
+ } data[] = {
+ { 1, { 1 }, { 0 } },
+ { 1, { 123 }, { 122 } },
+ { 1, { M }, { M-1 } },
+ { 2, { 2 }, { 0 } },
+ { 2, { 123 }, { 121 } },
+ { M, { M }, { 0 } },
+ { M-1, { M }, { 1 } },
+
+ { 1, { 0, 1 }, { M, 0 } },
+ { 1, { 0, 123 }, { M, 122 } },
+ { 1, { 0, M }, { M, M-1 } },
+ { 2, { 0, 123 }, { M-1, 122 } },
+ { 2, { 1, 123 }, { M, 122 } },
+ { M, { 0, 123 }, { 1, 122 } },
+ { M, { M-1, M }, { M, M-1 } },
+
+ { 1, { 0, 0, 1 }, { M, M, 0 } },
+ { 1, { 0, 0, 123 }, { M, M, 122 } },
+ { 1, { 0, 0, M }, { M, M, M-1 } },
+ { 2, { 0, 0, 123 }, { M-1, M, 122 } },
+ { 2, { 1, 0, 123 }, { M, M, 122 } },
+ { M, { 0, 0, 123 }, { 1, M, 122 } },
+ { M, { M-1, 0, M }, { M, M, M-1 } },
+
+ { 1, { 0, 0, 0, 1 }, { M, M, M, 0 } },
+ { 1, { 0, 0, 0, 123 }, { M, M, M, 122 } },
+ { 1, { 0, 0, 0, M }, { M, M, M, M-1 } },
+ { 2, { 0, 0, 0, 123 }, { M-1, M, M, 122 } },
+ { 2, { 1, 0, 0, 123 }, { M, M, M, 122 } },
+ { M, { 0, 0, 0, 123 }, { 1, M, M, 122 } },
+ { M, { M-1, 0, 0, M }, { M, M, M, M-1 } },
+
+ { 1, { 0, 0, 0, 0, 1 }, { M, M, M, M, 0 } },
+ { 1, { 0, 0, 0, 0, 123 }, { M, M, M, M, 122 } },
+ { 1, { 0, 0, 0, 0, M }, { M, M, M, M, M-1 } },
+ { 2, { 0, 0, 0, 0, 123 }, { M-1, M, M, M, 122 } },
+ { 2, { 1, 0, 0, 0, 123 }, { M, M, M, M, 122 } },
+ { M, { 0, 0, 0, 0, 123 }, { 1, M, M, M, 122 } },
+ { M, { M-1, 0, 0, 0, M }, { M, M, M, M, M-1 } },
+
+ { 1, { 0, 0, 0, 0, 0, 1 }, { M, M, M, M, M, 0 } },
+ { 1, { 0, 0, 0, 0, 0, 123 }, { M, M, M, M, M, 122 } },
+ { 1, { 0, 0, 0, 0, 0, M }, { M, M, M, M, M, M-1 } },
+ { 2, { 0, 0, 0, 0, 0, 123 }, { M-1, M, M, M, M, 122 } },
+ { 2, { 1, 0, 0, 0, 0, 123 }, { M, M, M, M, M, 122 } },
+ { M, { 0, 0, 0, 0, 0, 123 }, { 1, M, M, M, M, 122 } },
+ { M, { M-1, 0, 0, 0, 0, M }, { M, M, M, M, M, M-1
+#if defined (__hpux) && ! defined (__GNUC__)
+ /* For explanation of this garbage, see previous function. */
+ , 0, 0, 0, 0
+#endif
+ } }
+ };
+
+ mp_limb_t got[SIZE];
+ int i;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ refmpn_copyi (got, data[i].src, SIZE);
+ MPN_DECR_U (got, SIZE, data[i].n);
+ check_one ("check_decr_data", i,
+ data[i].src, data[i].n,
+ got, data[i].want, SIZE);
+
+ if (data[i].n == 1)
+ {
+ refmpn_copyi (got, data[i].src, SIZE);
+ MPN_DECR_U (got, SIZE, CNST_LIMB(1));
+ check_one ("check_decr (const 1)", i,
+ data[i].src, data[i].n,
+ got, data[i].want, SIZE);
+ }
+ }
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_incr_data ();
+ check_decr_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpn/t-matrix22.c b/gmp/tests/mpn/t-matrix22.c
new file mode 100644
index 0000000000..e63cbe27bb
--- /dev/null
+++ b/gmp/tests/mpn/t-matrix22.c
@@ -0,0 +1,207 @@
+/* Tests matrix22_mul.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+struct matrix {
+ mp_size_t alloc;
+ mp_size_t n;
+ mp_ptr e00, e01, e10, e11;
+};
+
+static void
+matrix_init (struct matrix *M, mp_size_t n)
+{
+ mp_ptr p = refmpn_malloc_limbs (4*(n+1));
+ M->e00 = p; p += n+1;
+ M->e01 = p; p += n+1;
+ M->e10 = p; p += n+1;
+ M->e11 = p;
+ M->alloc = n + 1;
+ M->n = 0;
+}
+
+static void
+matrix_clear (struct matrix *M)
+{
+ refmpn_free_limbs (M->e00);
+}
+
+static void
+matrix_copy (struct matrix *R, const struct matrix *M)
+{
+ R->n = M->n;
+ MPN_COPY (R->e00, M->e00, M->n);
+ MPN_COPY (R->e01, M->e01, M->n);
+ MPN_COPY (R->e10, M->e10, M->n);
+ MPN_COPY (R->e11, M->e11, M->n);
+}
+
+/* Used with same size, so no need for normalization. */
+static int
+matrix_equal_p (const struct matrix *A, const struct matrix *B)
+{
+ return (A->n == B->n
+ && mpn_cmp (A->e00, B->e00, A->n) == 0
+ && mpn_cmp (A->e01, B->e01, A->n) == 0
+ && mpn_cmp (A->e10, B->e10, A->n) == 0
+ && mpn_cmp (A->e11, B->e11, A->n) == 0);
+}
+
+static void
+matrix_random(struct matrix *M, mp_size_t n, gmp_randstate_ptr rands)
+{
+ M->n = n;
+ mpn_random (M->e00, n);
+ mpn_random (M->e01, n);
+ mpn_random (M->e10, n);
+ mpn_random (M->e11, n);
+}
+
+#define MUL(rp, ap, an, bp, bn) do { \
+ if (an > bn) \
+ mpn_mul (rp, ap, an, bp, bn); \
+ else \
+ mpn_mul (rp, bp, bn, ap, an); \
+ } while(0)
+
+static void
+ref_matrix22_mul (struct matrix *R,
+ const struct matrix *A,
+ const struct matrix *B, mp_ptr tp)
+{
+ mp_size_t an, bn, n;
+ mp_ptr r00, r01, r10, r11, a00, a01, a10, a11, b00, b01, b10, b11;
+
+ if (A->n >= B->n)
+ {
+ r00 = R->e00; a00 = A->e00; b00 = B->e00;
+ r01 = R->e01; a01 = A->e01; b01 = B->e01;
+ r10 = R->e10; a10 = A->e10; b10 = B->e10;
+ r11 = R->e11; a11 = A->e11; b11 = B->e11;
+ an = A->n, bn = B->n;
+ }
+ else
+ {
+ /* Transpose */
+ r00 = R->e00; a00 = B->e00; b00 = A->e00;
+ r01 = R->e10; a01 = B->e10; b01 = A->e10;
+ r10 = R->e01; a10 = B->e01; b10 = A->e01;
+ r11 = R->e11; a11 = B->e11; b11 = A->e11;
+ an = B->n, bn = A->n;
+ }
+ n = an + bn;
+ R->n = n + 1;
+
+ mpn_mul (r00, a00, an, b00, bn);
+ mpn_mul (tp, a01, an, b10, bn);
+ r00[n] = mpn_add_n (r00, r00, tp, n);
+
+ mpn_mul (r01, a00, an, b01, bn);
+ mpn_mul (tp, a01, an, b11, bn);
+ r01[n] = mpn_add_n (r01, r01, tp, n);
+
+ mpn_mul (r10, a10, an, b00, bn);
+ mpn_mul (tp, a11, an, b10, bn);
+ r10[n] = mpn_add_n (r10, r10, tp, n);
+
+ mpn_mul (r11, a10, an, b01, bn);
+ mpn_mul (tp, a11, an, b11, bn);
+ r11[n] = mpn_add_n (r11, r11, tp, n);
+}
+
+static void
+one_test (const struct matrix *A, const struct matrix *B, int i)
+{
+ struct matrix R;
+ struct matrix P;
+ mp_ptr tp;
+
+ matrix_init (&R, A->n + B->n + 1);
+ matrix_init (&P, A->n + B->n + 1);
+
+ tp = refmpn_malloc_limbs (mpn_matrix22_mul_itch (A->n, B->n));
+
+ ref_matrix22_mul (&R, A, B, tp);
+ matrix_copy (&P, A);
+ mpn_matrix22_mul (P.e00, P.e01, P.e10, P.e11, A->n,
+ B->e00, B->e01, B->e10, B->e11, B->n, tp);
+ P.n = A->n + B->n + 1;
+ if (!matrix_equal_p (&R, &P))
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ gmp_fprintf (stderr, "A = (%Nx, %Nx\n %Nx, %Nx)\n"
+ "B = (%Nx, %Nx\n %Nx, %Nx)\n"
+ "R = (%Nx, %Nx (expected)\n %Nx, %Nx)\n"
+ "P = (%Nx, %Nx (incorrect)\n %Nx, %Nx)\n",
+ A->e00, A->n, A->e01, A->n, A->e10, A->n, A->e11, A->n,
+ B->e00, B->n, B->e01, B->n, B->e10, B->n, B->e11, B->n,
+ R.e00, R.n, R.e01, R.n, R.e10, R.n, R.e11, R.n,
+ P.e00, P.n, P.e01, P.n, P.e10, P.n, P.e11, P.n);
+ abort();
+ }
+ refmpn_free_limbs (tp);
+ matrix_clear (&R);
+ matrix_clear (&P);
+}
+
+#define MAX_SIZE (2+2*MATRIX22_STRASSEN_THRESHOLD)
+
+int
+main (int argc, char **argv)
+{
+ struct matrix A;
+ struct matrix B;
+
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ int i;
+
+ tests_start ();
+ rands = RANDS;
+
+ matrix_init (&A, MAX_SIZE);
+ matrix_init (&B, MAX_SIZE);
+ mpz_init (bs);
+
+ for (i = 0; i < 1000; i++)
+ {
+ mp_size_t an, bn;
+ mpz_urandomb (bs, rands, 32);
+ an = 1 + mpz_get_ui (bs) % MAX_SIZE;
+ mpz_urandomb (bs, rands, 32);
+ bn = 1 + mpz_get_ui (bs) % MAX_SIZE;
+
+ matrix_random (&A, an, rands);
+ matrix_random (&B, bn, rands);
+
+ one_test (&A, &B, i);
+ }
+ mpz_clear (bs);
+ matrix_clear (&A);
+ matrix_clear (&B);
+
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-minvert.c b/gmp/tests/mpn/t-minvert.c
new file mode 100644
index 0000000000..ade61a1523
--- /dev/null
+++ b/gmp/tests/mpn/t-minvert.c
@@ -0,0 +1,179 @@
+/* Copyright 2013, 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 <stdio.h>
+#include <stdlib.h> /* for strtol */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests/tests.h"
+
+#define MAX_SIZE 50
+
+#define COUNT 200
+
+static void
+mpz_to_mpn (mp_ptr ap, mp_size_t an, const mpz_t b)
+{
+ mp_size_t bn = mpz_size (b);
+ ASSERT_ALWAYS (bn <= an);
+ MPN_COPY_INCR (ap, mpz_limbs_read (b), bn);
+ MPN_ZERO (ap + bn, an - bn);
+}
+
+int
+mpz_eq_mpn (mp_ptr ap, mp_size_t an, const mpz_t b)
+{
+ mp_size_t bn = mpz_size (b);
+
+ return (bn >= 0 && bn <= an
+ && mpn_cmp (ap, mpz_limbs_read (b), bn) == 0
+ && mpn_zero_p (ap + bn, an - bn));
+}
+
+static mp_bitcnt_t
+bit_size (mp_srcptr xp, mp_size_t n)
+{
+ MPN_NORMALIZE (xp, n);
+ return n > 0 ? mpn_sizeinbase (xp, n, 2) : 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ gmp_randstate_ptr rands;
+ long count = COUNT;
+ mp_ptr mp;
+ mp_ptr ap;
+ mp_ptr vp;
+ mp_ptr tp;
+ mp_ptr scratch;
+ mpz_t m, a, r, g;
+ int test;
+ mp_limb_t ran;
+ mp_size_t itch;
+ TMP_DECL;
+
+ tests_start ();
+ rands = RANDS;
+
+
+ TMP_MARK;
+ mpz_init (m);
+ mpz_init (a);
+ mpz_init (r);
+ mpz_init (g);
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ mp = TMP_ALLOC_LIMBS (MAX_SIZE);
+ ap = TMP_ALLOC_LIMBS (MAX_SIZE);
+ vp = TMP_ALLOC_LIMBS (MAX_SIZE);
+ tp = TMP_ALLOC_LIMBS (MAX_SIZE);
+ scratch = TMP_ALLOC_LIMBS (mpn_sec_invert_itch (MAX_SIZE) + 1);
+
+ for (test = 0; test < count; test++)
+ {
+ mp_bitcnt_t bits;
+ int rres, tres;
+ mp_size_t n;
+
+ bits = urandom () % (GMP_NUMB_BITS * MAX_SIZE) + 1;
+
+ if (test & 1)
+ mpz_rrandomb (m, rands, bits);
+ else
+ mpz_urandomb (m, rands, bits);
+ if (test & 2)
+ mpz_rrandomb (a, rands, bits);
+ else
+ mpz_urandomb (a, rands, bits);
+
+ mpz_setbit (m, 0);
+ if (test & 4)
+ {
+ /* Ensure it really is invertible */
+ if (mpz_sgn (a) == 0)
+ mpz_set_ui (a, 1);
+ else
+ for (;;)
+ {
+ mpz_gcd (g, a, m);
+ if (mpz_cmp_ui (g, 1) == 0)
+ break;
+ mpz_remove (a, a, g);
+ }
+ }
+
+ rres = mpz_invert (r, a, m);
+ if ( (test & 4) && !rres)
+ {
+ gmp_fprintf (stderr, "test %d: Not invertible!\n"
+ "m = %Zd\n"
+ "a = %Zd\n", test, m, a);
+ abort ();
+ }
+ ASSERT_ALWAYS (! (test & 4) || rres);
+
+ n = (bits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
+ ASSERT_ALWAYS (n <= MAX_SIZE);
+ itch = mpn_sec_invert_itch (n);
+ scratch[itch] = ran = urandom ();
+
+ mpz_to_mpn (ap, n, a);
+ mpz_to_mpn (mp, n, m);
+ tres = mpn_sec_invert (tp, ap, mp, n,
+ bit_size (ap, n) + bit_size (mp, n),
+ scratch);
+
+ if (rres != tres || (rres == 1 && !mpz_eq_mpn (tp, n, r)) || ran != scratch[itch])
+ {
+ gmp_fprintf (stderr, "Test %d failed.\n"
+ "m = %Zd\n"
+ "a = %Zd\n", test, m, a);
+ fprintf (stderr, "ref ret: %d\n"
+ "got ret: %d\n", rres, tres);
+ if (rres)
+ gmp_fprintf (stderr, "ref: %Zd\n", r);
+ if (tres)
+ gmp_fprintf (stderr, "got: %Nd\n", tp, n);
+ if (ran != scratch[itch])
+ fprintf (stderr, "scratch[itch] changed.\n");
+ abort ();
+ }
+ }
+
+ TMP_FREE;
+
+ mpz_clear (m);
+ mpz_clear (a);
+ mpz_clear (r);
+ mpz_clear (g);
+
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-mod_1.c b/gmp/tests/mpn/t-mod_1.c
new file mode 100644
index 0000000000..3d08a9018f
--- /dev/null
+++ b/gmp/tests/mpn/t-mod_1.c
@@ -0,0 +1,129 @@
+/* Test mpn_mod_1 variants.
+
+Copyright 2010, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+static void
+check_one (mp_srcptr ap, mp_size_t n, mp_limb_t b)
+{
+ mp_limb_t r_ref = refmpn_mod_1 (ap, n, b);
+ mp_limb_t r;
+
+ if (n >= 2)
+ {
+ mp_limb_t pre[4];
+ mpn_mod_1_1p_cps (pre, b);
+ r = mpn_mod_1_1p (ap, n, b << pre[1], pre);
+ if (r != r_ref)
+ {
+ printf ("mpn_mod_1_1p failed\n");
+ goto fail;
+ }
+ }
+ if ((b & GMP_NUMB_HIGHBIT) == 0)
+ {
+ mp_limb_t pre[5];
+ mpn_mod_1s_2p_cps (pre, b);
+ r = mpn_mod_1s_2p (ap, n, b << pre[1], pre);
+ if (r != r_ref)
+ {
+ printf ("mpn_mod_1s_2p failed\n");
+ goto fail;
+ }
+ }
+ if (b <= GMP_NUMB_MASK / 3)
+ {
+ mp_limb_t pre[6];
+ mpn_mod_1s_3p_cps (pre, b);
+ r = mpn_mod_1s_3p (ap, n, b << pre[1], pre);
+ if (r != r_ref)
+ {
+ printf ("mpn_mod_1s_3p failed\n");
+ goto fail;
+ }
+ }
+ if (b <= GMP_NUMB_MASK / 4)
+ {
+ mp_limb_t pre[7];
+ mpn_mod_1s_4p_cps (pre, b);
+ r = mpn_mod_1s_4p (ap, n, b << pre[1], pre);
+ if (r != r_ref)
+ {
+ printf ("mpn_mod_1s_4p failed\n");
+ goto fail;
+ }
+ }
+ r = mpn_mod_1 (ap, n, b);
+ if (r != r_ref)
+ {
+ printf ("mpn_mod_1 failed\n");
+ fail:
+ printf ("an = %d, a: ", (int) n); mpn_dump (ap, n);
+ printf ("b : "); mpn_dump (&b, 1);
+ printf ("r (expected): "); mpn_dump (&r_ref, 1);
+ printf ("r (bad) : "); mpn_dump (&r, 1);
+ abort();
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ gmp_randstate_ptr rands;
+ int i;
+ unsigned a_bits;
+ unsigned b_bits;
+ mpz_t a;
+ mpz_t b;
+
+ tests_start ();
+ rands = RANDS;
+ mpz_init (a);
+ mpz_init (b);
+
+ for (i = 0; i < 300; i++)
+ {
+ mp_size_t asize;
+ a_bits = 1 + gmp_urandomm_ui (rands, 1000);
+ b_bits = 1 + gmp_urandomm_ui (rands, GMP_NUMB_BITS);
+
+ mpz_rrandomb (a, rands, a_bits);
+ mpz_rrandomb (b, rands, b_bits);
+
+ asize = SIZ(a);
+ if (!asize)
+ asize = 1;
+ if (mpz_sgn (b) == 0)
+ mpz_set_ui (b, 1);
+
+ check_one (PTR(a), asize, PTR(b)[0]);
+ }
+
+ mpz_clear (a);
+ mpz_clear (b);
+
+ tests_end ();
+ return 0;
+}
+
diff --git a/gmp/tests/mpn/t-mp_bases.c b/gmp/tests/mpn/t-mp_bases.c
new file mode 100644
index 0000000000..c0b228825a
--- /dev/null
+++ b/gmp/tests/mpn/t-mp_bases.c
@@ -0,0 +1,105 @@
+/* Check mp_bases values.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+
+int
+main (int argc, char *argv[])
+{
+ mp_limb_t want_bb, want_bb_inv;
+ int base, want_chars_per_limb;
+
+ want_chars_per_limb = refmpn_chars_per_limb (10);
+ if (MP_BASES_CHARS_PER_LIMB_10 != want_chars_per_limb)
+ {
+ printf ("MP_BASES_CHARS_PER_LIMB_10 wrong\n");
+ abort ();
+ }
+
+ want_bb = refmpn_big_base (10);
+ if (MP_BASES_BIG_BASE_10 != want_bb)
+ {
+ printf ("MP_BASES_BIG_BASE_10 wrong\n");
+ abort ();
+ }
+
+ want_bb_inv = refmpn_invert_limb
+ (want_bb << refmpn_count_leading_zeros (want_bb));
+ if (MP_BASES_BIG_BASE_INVERTED_10 != want_bb_inv)
+ {
+ printf ("MP_BASES_BIG_BASE_INVERTED_10 wrong\n");
+ abort ();
+ }
+
+ if (MP_BASES_NORMALIZATION_STEPS_10
+ != refmpn_count_leading_zeros (MP_BASES_BIG_BASE_10))
+ {
+ printf ("MP_BASES_NORMALIZATION_STEPS_10 wrong\n");
+ abort ();
+ }
+
+ for (base = 2; base < numberof (mp_bases); base++)
+ {
+ want_chars_per_limb = refmpn_chars_per_limb (base);
+ if (mp_bases[base].chars_per_limb != want_chars_per_limb)
+ {
+ printf ("mp_bases[%d].chars_per_limb wrong\n", base);
+ printf (" got %d\n", mp_bases[base].chars_per_limb);
+ printf (" want %d\n", want_chars_per_limb);
+ abort ();
+ }
+
+ if (POW2_P (base))
+ {
+ want_bb = refmpn_count_trailing_zeros ((mp_limb_t) base);
+ if (mp_bases[base].big_base != want_bb)
+ {
+ printf ("mp_bases[%d].big_base (log2 of base) wrong\n", base);
+ abort ();
+ }
+ }
+ else
+ {
+ want_bb = refmpn_big_base (base);
+ if (mp_bases[base].big_base != want_bb)
+ {
+ printf ("mp_bases[%d].big_base wrong\n", base);
+ abort ();
+ }
+
+#if USE_PREINV_DIVREM_1
+ want_bb_inv = refmpn_invert_limb
+ (want_bb << refmpn_count_leading_zeros (want_bb));
+ if (mp_bases[base].big_base_inverted != want_bb_inv)
+ {
+ printf ("mp_bases[%d].big_base_inverted wrong\n", base);
+ abort ();
+ }
+#endif
+ }
+ }
+
+ exit (0);
+}
diff --git a/gmp/tests/mpn/t-mul.c b/gmp/tests/mpn/t-mul.c
new file mode 100644
index 0000000000..26e4227334
--- /dev/null
+++ b/gmp/tests/mpn/t-mul.c
@@ -0,0 +1,101 @@
+/* Test mpn_mul function for all sizes up to a selected limit.
+
+Copyright 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library 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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+static unsigned
+isqrt (unsigned t)
+{
+ unsigned s, b;
+
+ for (b = 0, s = t; b++, s >>= 1; )
+ ;
+
+ s = 1 << (b >> 1);
+ if (b & 1)
+ s += s >> 1;
+
+ do
+ {
+ b = t / s;
+ s = (s + b) >> 1;
+ }
+ while (b < s);
+
+ return s;
+}
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr ap, bp, rp, refp;
+ mp_size_t max_n, an, bn, rn;
+ gmp_randstate_ptr rands;
+ int reps;
+ TMP_DECL;
+ TMP_MARK;
+
+ reps = 1;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ /* Re-interpret reps argument as a size argument. */
+ max_n = isqrt (reps * 25000);
+
+ ap = TMP_ALLOC_LIMBS (max_n + 1);
+ bp = TMP_ALLOC_LIMBS (max_n + 1);
+ rp = TMP_ALLOC_LIMBS (2 * max_n);
+ refp = TMP_ALLOC_LIMBS (2 * max_n);
+
+ for (an = 1; an <= max_n; an += 1)
+ {
+ for (bn = 1; bn <= an; bn += 1)
+ {
+ mpn_random2 (ap, an + 1);
+ mpn_random2 (bp, bn + 1);
+
+ refmpn_mul (refp, ap, an, bp, bn);
+ mpn_mul (rp, ap, an, bp, bn);
+
+ rn = an + bn;
+ if (mpn_cmp (refp, rp, rn))
+ {
+ printf ("ERROR, an = %d, bn = %d, rn = %d\n",
+ (int) an, (int) bn, (int) rn);
+ printf ("a: "); mpn_dump (ap, an);
+ printf ("b: "); mpn_dump (bp, bn);
+ printf ("r: "); mpn_dump (rp, rn);
+ printf ("ref: "); mpn_dump (refp, rn);
+ abort();
+ }
+ }
+ }
+ TMP_FREE;
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-mullo.c b/gmp/tests/mpn/t-mullo.c
new file mode 100644
index 0000000000..d4789976ac
--- /dev/null
+++ b/gmp/tests/mpn/t-mullo.c
@@ -0,0 +1,142 @@
+/* Test for mullo function.
+
+Copyright 2009 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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Sizes are up to 2^SIZE_LOG limbs */
+#ifndef SIZE_LOG
+#define SIZE_LOG 10
+#endif
+
+#ifndef COUNT
+#define COUNT 10000
+#endif
+
+#define MAX_N (1L << SIZE_LOG)
+#define MIN_N (1)
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr ap, bp, refp, pp, scratch;
+ int count = COUNT;
+ int test;
+ gmp_randstate_ptr rands;
+ TMP_DECL;
+ TMP_MARK;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ tests_start ();
+ rands = RANDS;
+
+#define mpn_mullo_itch(n) (0)
+
+ ap = TMP_ALLOC_LIMBS (MAX_N);
+ bp = TMP_ALLOC_LIMBS (MAX_N);
+ refp = TMP_ALLOC_LIMBS (MAX_N * 2);
+ pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
+ scratch
+ = 1+TMP_ALLOC_LIMBS (mpn_mullo_itch (MAX_N) + 2);
+
+ for (test = 0; test < count; test++)
+ {
+ unsigned size_min;
+ unsigned size_range;
+ mp_size_t n;
+ mp_size_t itch;
+ mp_limb_t p_before, p_after, s_before, s_after;
+
+ for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
+ ;
+
+ /* We generate an in the MIN_N <= n <= (1 << size_range). */
+ size_range = size_min
+ + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
+
+ n = MIN_N
+ + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);
+
+ mpn_random2 (ap, n);
+ mpn_random2 (bp, n);
+ mpn_random2 (pp-1, n + 2);
+ p_before = pp[-1];
+ p_after = pp[n];
+
+ itch = mpn_mullo_itch (n);
+ ASSERT_ALWAYS (itch <= mpn_mullo_itch (MAX_N));
+ mpn_random2 (scratch-1, itch+2);
+ s_before = scratch[-1];
+ s_after = scratch[itch];
+
+ mpn_mullo_n (pp, ap, bp, n);
+ mpn_mul_n (refp, ap, bp, n);
+ if (pp[-1] != p_before || pp[n] != p_after
+ || scratch[-1] != s_before || scratch[itch] != s_after
+ || mpn_cmp (refp, pp, n) != 0)
+ {
+ printf ("ERROR in test %d, n = %d",
+ test, (int) n);
+ if (pp[-1] != p_before)
+ {
+ printf ("before pp:"); mpn_dump (pp -1, 1);
+ printf ("keep: "); mpn_dump (&p_before, 1);
+ }
+ if (pp[n] != p_after)
+ {
+ printf ("after pp:"); mpn_dump (pp + n, 1);
+ printf ("keep: "); mpn_dump (&p_after, 1);
+ }
+ if (scratch[-1] != s_before)
+ {
+ printf ("before scratch:"); mpn_dump (scratch-1, 1);
+ printf ("keep: "); mpn_dump (&s_before, 1);
+ }
+ if (scratch[itch] != s_after)
+ {
+ printf ("after scratch:"); mpn_dump (scratch + itch, 1);
+ printf ("keep: "); mpn_dump (&s_after, 1);
+ }
+ mpn_dump (ap, n);
+ mpn_dump (bp, n);
+ mpn_dump (pp, n);
+ mpn_dump (refp, n);
+
+ abort();
+ }
+ }
+ TMP_FREE;
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-mulmid.c b/gmp/tests/mpn/t-mulmid.c
new file mode 100644
index 0000000000..8978c4c1fd
--- /dev/null
+++ b/gmp/tests/mpn/t-mulmid.c
@@ -0,0 +1,93 @@
+/* Test for mulmid function.
+
+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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Sizes are up to 2^SIZE_LOG limbs */
+#ifndef SIZE_LOG
+#define SIZE_LOG 9
+#endif
+
+#ifndef COUNT
+#define COUNT 5000
+#endif
+
+#define MAX_N (1L << SIZE_LOG)
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr ap, bp, rp, refp;
+ gmp_randstate_ptr rands;
+ int test;
+ TMP_DECL;
+ TMP_MARK;
+
+ tests_start ();
+ rands = RANDS;
+
+ ap = TMP_ALLOC_LIMBS (MAX_N);
+ bp = TMP_ALLOC_LIMBS (MAX_N);
+ rp = TMP_ALLOC_LIMBS (MAX_N + 2);
+ refp = TMP_ALLOC_LIMBS (MAX_N + 2);
+
+ for (test = 0; test < COUNT; test++)
+ {
+ mp_size_t an, bn, rn;
+ unsigned size_log;
+
+ size_log = 1 + gmp_urandomm_ui (rands, SIZE_LOG);
+ an = 1 + gmp_urandomm_ui(rands, 1L << size_log);
+
+ size_log = 1 + gmp_urandomm_ui (rands, SIZE_LOG);
+ bn = 1 + gmp_urandomm_ui(rands, 1L << size_log);
+
+ /* Make sure an >= bn */
+ if (an < bn)
+ MP_SIZE_T_SWAP (an, bn);
+
+ mpn_random2 (ap, an);
+ mpn_random2 (bp, bn);
+
+ refmpn_mulmid (refp, ap, an, bp, bn);
+ mpn_mulmid (rp, ap, an, bp, bn);
+
+ rn = an + 3 - bn;
+ if (mpn_cmp (refp, rp, rn))
+ {
+ printf ("ERROR in test %d, an = %d, bn = %d, rn = %d\n",
+ test, (int) an, (int) bn, (int) rn);
+ printf("a: "); mpn_dump (ap, an);
+ printf("b: "); mpn_dump (bp, bn);
+ printf("r: "); mpn_dump (rp, rn);
+ printf("ref: "); mpn_dump (refp, rn);
+
+ abort();
+ }
+ }
+ TMP_FREE;
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-mulmod_bnm1.c b/gmp/tests/mpn/t-mulmod_bnm1.c
new file mode 100644
index 0000000000..374b722c6b
--- /dev/null
+++ b/gmp/tests/mpn/t-mulmod_bnm1.c
@@ -0,0 +1,218 @@
+/* Test for mulmod_bnm1 function.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+Copyright 2009 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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Sizes are up to 2^SIZE_LOG limbs */
+#ifndef SIZE_LOG
+#define SIZE_LOG 11
+#endif
+
+#ifndef COUNT
+#define COUNT 5000
+#endif
+
+#define MAX_N (1L << SIZE_LOG)
+#define MIN_N 1
+
+/*
+ Reference function for multiplication modulo B^rn-1.
+
+ The result is expected to be ZERO if and only if one of the operand
+ already is. Otherwise the class [0] Mod(B^rn-1) is represented by
+ B^rn-1. This should not be a problem if mulmod_bnm1 is used to
+ combine results and obtain a natural number when one knows in
+ advance that the final value is less than (B^rn-1).
+*/
+
+static void
+ref_mulmod_bnm1 (mp_ptr rp, mp_size_t rn, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
+{
+ mp_limb_t cy;
+
+ ASSERT (0 < an && an <= rn);
+ ASSERT (0 < bn && bn <= rn);
+
+ if (an >= bn)
+ refmpn_mul (rp, ap, an, bp, bn);
+ else
+ refmpn_mul (rp, bp, bn, ap, an);
+ an += bn;
+ if (an > rn) {
+ cy = mpn_add (rp, rp, rn, rp + rn, an - rn);
+ /* If cy == 1, then the value of rp is at most B^rn - 2, so there can
+ * be no overflow when adding in the carry. */
+ MPN_INCR_U (rp, rn, cy);
+ }
+}
+
+/*
+ Compare the result of the mpn_mulmod_bnm1 function in the library
+ with the reference function above.
+*/
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr ap, bp, refp, pp, scratch;
+ int count = COUNT;
+ int test;
+ gmp_randstate_ptr rands;
+ TMP_DECL;
+ TMP_MARK;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ tests_start ();
+ rands = RANDS;
+
+ ASSERT_ALWAYS (mpn_mulmod_bnm1_next_size (MAX_N) == MAX_N);
+
+ ap = TMP_ALLOC_LIMBS (MAX_N);
+ bp = TMP_ALLOC_LIMBS (MAX_N);
+ refp = TMP_ALLOC_LIMBS (MAX_N * 4);
+ pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
+ scratch
+ = 1+TMP_ALLOC_LIMBS (mpn_mulmod_bnm1_itch (MAX_N, MAX_N, MAX_N) + 2);
+
+ for (test = 0; test < count; test++)
+ {
+ unsigned size_min;
+ unsigned size_range;
+ mp_size_t an,bn,rn,n;
+ mp_size_t itch;
+ mp_limb_t p_before, p_after, s_before, s_after;
+
+ for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
+ ;
+
+ /* We generate an in the MIN_N <= n <= (1 << size_range). */
+ size_range = size_min
+ + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
+
+ n = MIN_N
+ + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);
+ n = mpn_mulmod_bnm1_next_size (n);
+
+ if ( (test & 1) || n == 1) {
+ /* Half of the tests are done with the main scenario in mind:
+ both an and bn >= rn/2 */
+ an = ((n+1) >> 1) + gmp_urandomm_ui (rands, (n+1) >> 1);
+ bn = ((n+1) >> 1) + gmp_urandomm_ui (rands, (n+1) >> 1);
+ } else {
+ /* Second half of the tests are done using mulmod to compute a
+ full product with n/2 < an+bn <= n. */
+ an = 1 + gmp_urandomm_ui (rands, n - 1);
+ if (an >= n/2)
+ bn = 1 + gmp_urandomm_ui (rands, n - an);
+ else
+ bn = n/2 + 1 - an + gmp_urandomm_ui (rands, (n+1)/2);
+ }
+
+ /* Make sure an >= bn */
+ if (an < bn)
+ MP_SIZE_T_SWAP (an, bn);
+
+ mpn_random2 (ap, an);
+ mpn_random2 (bp, bn);
+
+ /* Sometime trigger the borderline conditions
+ A = -1,0,+1 or B = -1,0,+1 or A*B == -1,0,1 Mod(B^{n/2}+1).
+ This only makes sense if there is at least a split, i.e. n is even. */
+ if ((test & 0x1f) == 1 && (n & 1) == 0) {
+ mp_size_t x;
+ MPN_COPY (ap, ap + (n >> 1), an - (n >> 1));
+ MPN_ZERO (ap + an - (n >> 1) , n - an);
+ MPN_COPY (bp, bp + (n >> 1), bn - (n >> 1));
+ MPN_ZERO (bp + bn - (n >> 1) , n - bn);
+ x = (n == an) ? 0 : gmp_urandomm_ui (rands, n - an);
+ ap[x] += gmp_urandomm_ui (rands, 3) - 1;
+ x = (n >> 1) - x % (n >> 1);
+ bp[x] += gmp_urandomm_ui (rands, 3) - 1;
+ /* We don't propagate carry, this means that the desired condition
+ is not triggered all the times. A few times are enough anyway. */
+ }
+ rn = MIN(n, an + bn);
+ mpn_random2 (pp-1, rn + 2);
+ p_before = pp[-1];
+ p_after = pp[rn];
+
+ itch = mpn_mulmod_bnm1_itch (n, an, bn);
+ ASSERT_ALWAYS (itch <= mpn_mulmod_bnm1_itch (MAX_N, MAX_N, MAX_N));
+ mpn_random2 (scratch-1, itch+2);
+ s_before = scratch[-1];
+ s_after = scratch[itch];
+
+ mpn_mulmod_bnm1 ( pp, n, ap, an, bp, bn, scratch);
+ ref_mulmod_bnm1 (refp, n, ap, an, bp, bn);
+ if (pp[-1] != p_before || pp[rn] != p_after
+ || scratch[-1] != s_before || scratch[itch] != s_after
+ || mpn_cmp (refp, pp, rn) != 0)
+ {
+ printf ("ERROR in test %d, an = %d, bn = %d, n = %d\n",
+ test, (int) an, (int) bn, (int) n);
+ if (pp[-1] != p_before)
+ {
+ printf ("before pp:"); mpn_dump (pp -1, 1);
+ printf ("keep: "); mpn_dump (&p_before, 1);
+ }
+ if (pp[rn] != p_after)
+ {
+ printf ("after pp:"); mpn_dump (pp + rn, 1);
+ printf ("keep: "); mpn_dump (&p_after, 1);
+ }
+ if (scratch[-1] != s_before)
+ {
+ printf ("before scratch:"); mpn_dump (scratch-1, 1);
+ printf ("keep: "); mpn_dump (&s_before, 1);
+ }
+ if (scratch[itch] != s_after)
+ {
+ printf ("after scratch:"); mpn_dump (scratch + itch, 1);
+ printf ("keep: "); mpn_dump (&s_after, 1);
+ }
+ mpn_dump (ap, an);
+ mpn_dump (bp, bn);
+ mpn_dump (pp, rn);
+ mpn_dump (refp, rn);
+
+ abort();
+ }
+ }
+ TMP_FREE;
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-perfsqr.c b/gmp/tests/mpn/t-perfsqr.c
new file mode 100644
index 0000000000..322ab6c3a4
--- /dev/null
+++ b/gmp/tests/mpn/t-perfsqr.c
@@ -0,0 +1,117 @@
+/* Test mpn_perfect_square_p data.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#include "mpn/perfsqr.h"
+
+
+#define PERFSQR_MOD_MASK ((CNST_LIMB(1) << PERFSQR_MOD_BITS) - 1)
+
+void
+check_mod_2 (mp_limb_t d, mp_limb_t inv, mp_limb_t got_hi, mp_limb_t got_lo)
+{
+ int want[2*GMP_LIMB_BITS], got;
+ unsigned r, idx;
+ mp_limb_t q;
+
+ ASSERT_ALWAYS (d <= numberof (want));
+ ASSERT_ALWAYS (((inv * d) & PERFSQR_MOD_MASK) == 1);
+ ASSERT_ALWAYS (MP_LIMB_T_MAX / d >= PERFSQR_MOD_MASK);
+
+ /* the squares mod d */
+ for (r = 0; r < d; r++)
+ want[r] = 0;
+ for (r = 0; r < d; r++)
+ want[(r*r)%d] = 1;
+
+ /* for each remainder mod d, expect the table data to correctly identify
+ it as a residue or non-residue */
+ for (r = 0; r < d; r++)
+ {
+ /* as per PERFSQR_MOD_IDX */
+ q = ((r) * (inv)) & PERFSQR_MOD_MASK;
+ idx = (q * (d)) >> PERFSQR_MOD_BITS;
+
+ if (idx >= GMP_LIMB_BITS)
+ got = (got_hi >> (idx - GMP_LIMB_BITS)) & 1;
+ else
+ got = (got_lo >> idx) & 1;
+
+ if (got != want[r])
+ {
+ printf ("Wrong generated data\n");
+ printf (" d=%u\n", (unsigned) d);
+ printf (" r=%u\n", r);
+ printf (" idx=%u\n", idx);
+ printf (" got %d\n", got);
+ printf (" want %d\n", want[r]);
+ abort ();
+ }
+ }
+}
+
+/* Check the generated data in perfsqr.h. */
+void
+check_mod (void)
+{
+#define PERFSQR_MOD_34(r, up, usize) { r = 0; } /* so r isn't unused */
+#define PERFSQR_MOD_PP(r, up, usize) { r = 0; }
+#define PERFSQR_MOD_1(r, d, inv, mask) check_mod_2 (d, inv, CNST_LIMB(0), mask)
+#define PERFSQR_MOD_2(r, d, inv, mhi, mlo) check_mod_2 (d, inv, mhi, mlo)
+
+ PERFSQR_MOD_TEST (dummy, dummy);
+}
+
+/* Check PERFSQR_PP, if in use. */
+void
+check_pp (void)
+{
+#ifdef PERFSQR_PP
+ ASSERT_ALWAYS_LIMB (PERFSQR_PP);
+ ASSERT_ALWAYS_LIMB (PERFSQR_PP_NORM);
+ ASSERT_ALWAYS_LIMB (PERFSQR_PP_INVERTED);
+
+ /* preinv stuff only for nails==0 */
+ if (GMP_NAIL_BITS == 0)
+ {
+ ASSERT_ALWAYS (PERFSQR_PP_NORM
+ == PERFSQR_PP << refmpn_count_leading_zeros (PERFSQR_PP));
+ ASSERT_ALWAYS (PERFSQR_PP_INVERTED
+ == refmpn_invert_limb (PERFSQR_PP_NORM));
+ }
+#endif
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_mod ();
+ check_pp ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpn/t-scan.c b/gmp/tests/mpn/t-scan.c
new file mode 100644
index 0000000000..f4478af335
--- /dev/null
+++ b/gmp/tests/mpn/t-scan.c
@@ -0,0 +1,145 @@
+/* Test mpn_scan0 and mpn_scan1.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#include "tests.h"
+
+
+#define SIZE ((mp_size_t) 3)
+mp_limb_t x[SIZE+1];
+
+void
+check (void)
+{
+ unsigned long i, got, want;
+
+ x[SIZE] = 1;
+ for (i = 0; i < SIZE*GMP_NUMB_BITS; i++)
+ {
+ got = refmpn_scan1 (x, i);
+ want = mpn_scan1 (x, i);
+ if (got != want)
+ {
+ printf ("mpn_scan1\n");
+ printf (" i %lu\n", i);
+ printf (" got %lu\n", got);
+ printf (" want %lu\n", want);
+ mpn_trace (" x ", x, SIZE);
+ abort ();
+ }
+ }
+
+ x[SIZE] = 0;
+ for (i = 0; i < SIZE*GMP_NUMB_BITS; i++)
+ {
+ got = refmpn_scan0 (x, i);
+ want = mpn_scan0 (x, i);
+ if (got != want)
+ {
+ printf ("mpn_scan0\n");
+ printf (" i %lu\n", i);
+ printf (" got %lu\n", got);
+ printf (" want %lu\n", want);
+ mpn_trace (" x ", x, SIZE);
+ abort ();
+ }
+ }
+}
+
+void
+check_twobits (void)
+{
+#define TWOBITS(a, b) \
+ ((CNST_LIMB(1) << (a)) | (CNST_LIMB(1) << (b)))
+
+ refmpn_zero (x, SIZE);
+ x[0] = TWOBITS (1, 0);
+ check ();
+
+ refmpn_zero (x, SIZE);
+ x[0] = TWOBITS (GMP_NUMB_BITS-1, 1);
+ check ();
+
+ refmpn_zero (x, SIZE);
+ x[0] = CNST_LIMB(1);
+ x[1] = CNST_LIMB(1);
+ check ();
+
+ refmpn_zero (x, SIZE);
+ x[0] = CNST_LIMB(1) << (GMP_NUMB_BITS-1);
+ x[1] = CNST_LIMB(1);
+ check ();
+
+ refmpn_zero (x, SIZE);
+ x[1] = TWOBITS (1, 0);
+ check ();
+
+ refmpn_zero (x, SIZE);
+ x[1] = CNST_LIMB(1);
+ x[2] = CNST_LIMB(1);
+ check ();
+}
+
+/* This is unused, it takes too long, especially on 64-bit systems. */
+void
+check_twobits_exhaustive (void)
+{
+ unsigned long i, j;
+
+ for (i = 0; i < GMP_NUMB_BITS * SIZE; i++)
+ {
+ for (j = 0; j < GMP_NUMB_BITS * SIZE; j++)
+ {
+ refmpn_zero (x, SIZE);
+ refmpn_setbit (x, i);
+ refmpn_setbit (x, j);
+ check ();
+ }
+ }
+}
+
+void
+check_rand (void)
+{
+ int i;
+
+ for (i = 0; i < 100; i++)
+ {
+ refmpn_random2 (x, SIZE);
+ check ();
+ }
+}
+
+int
+main (void)
+{
+ mp_trace_base = -16;
+ tests_start ();
+
+ check_twobits ();
+ check_rand ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpn/t-sizeinbase.c b/gmp/tests/mpn/t-sizeinbase.c
new file mode 100644
index 0000000000..0887815d8b
--- /dev/null
+++ b/gmp/tests/mpn/t-sizeinbase.c
@@ -0,0 +1,108 @@
+/* Test for sizeinbase function.
+
+Copyright 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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Exponents up to 2^SIZE_LOG */
+#ifndef SIZE_LOG
+#define SIZE_LOG 13
+#endif
+
+#ifndef COUNT
+#define COUNT 30
+#endif
+
+#define MAX_N (1<<SIZE_LOG)
+
+int
+main (int argc, char **argv)
+{
+ mp_limb_t a;
+ mp_ptr pp, scratch;
+ mp_limb_t max_b;
+ int count = COUNT;
+ int test;
+ gmp_randstate_ptr rands;
+ TMP_DECL;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ tests_start ();
+ TMP_MARK;
+ rands = RANDS;
+
+ pp = TMP_ALLOC_LIMBS (MAX_N);
+ scratch = TMP_ALLOC_LIMBS (MAX_N);
+ max_b = numberof (mp_bases);
+
+ ASSERT_ALWAYS (max_b > 62);
+ ASSERT_ALWAYS (max_b < GMP_NUMB_MAX);
+
+ for (a = 2; a < max_b; ++a)
+ for (test = 0; test < count; ++test)
+ {
+ mp_size_t pn;
+ mp_limb_t exp;
+ mp_bitcnt_t res;
+
+ exp = gmp_urandomm_ui (rands, MAX_N);
+
+ pn = mpn_pow_1 (pp, &a, 1, exp, scratch);
+
+ res = mpn_sizeinbase (pp, pn, a) - 1;
+
+ if ((res < exp) || (res > exp + 1))
+ {
+ printf ("ERROR in test %d, base = %d, exp = %d, res = %d\n",
+ test, (int) a, (int) exp, (int) res);
+ abort();
+ }
+
+ mpn_sub_1 (pp, pp, pn, CNST_LIMB(1));
+ pn -= pp[pn-1] == 0;
+
+ res = mpn_sizeinbase (pp, pn, a);
+
+ if ((res < exp) || (res - 1 > exp))
+ {
+ printf ("ERROR in -1 test %d, base = %d, exp = %d, res = %d\n",
+ test, (int) a, (int) exp, (int) res);
+ abort();
+ }
+ }
+
+ TMP_FREE;
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-sqrmod_bnm1.c b/gmp/tests/mpn/t-sqrmod_bnm1.c
new file mode 100644
index 0000000000..47ccf81083
--- /dev/null
+++ b/gmp/tests/mpn/t-sqrmod_bnm1.c
@@ -0,0 +1,191 @@
+/* Test for sqrmod_bnm1 function.
+
+ Contributed to the GNU project by Marco Bodrato.
+
+Copyright 2009 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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Sizes are up to 2^SIZE_LOG limbs */
+#ifndef SIZE_LOG
+#define SIZE_LOG 12
+#endif
+
+#ifndef COUNT
+#define COUNT 3000
+#endif
+
+#define MAX_N (1L << SIZE_LOG)
+#define MIN_N 1
+
+/*
+ Reference function for squaring modulo B^rn-1.
+
+ The result is expected to be ZERO if and only if one of the operand
+ already is. Otherwise the class [0] Mod(B^rn-1) is represented by
+ B^rn-1. This should not be a problem if sqrmod_bnm1 is used to
+ combine results and obtain a natural number when one knows in
+ advance that the final value is less than (B^rn-1).
+*/
+
+static void
+ref_sqrmod_bnm1 (mp_ptr rp, mp_size_t rn, mp_srcptr ap, mp_size_t an)
+{
+ mp_limb_t cy;
+
+ ASSERT (0 < an && an <= rn);
+
+ refmpn_mul (rp, ap, an, ap, an);
+ an *= 2;
+ if (an > rn) {
+ cy = mpn_add (rp, rp, rn, rp + rn, an - rn);
+ /* If cy == 1, then the value of rp is at most B^rn - 2, so there can
+ * be no overflow when adding in the carry. */
+ MPN_INCR_U (rp, rn, cy);
+ }
+}
+
+/*
+ Compare the result of the mpn_sqrmod_bnm1 function in the library
+ with the reference function above.
+*/
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr ap, refp, pp, scratch;
+ int count = COUNT;
+ int test;
+ gmp_randstate_ptr rands;
+ TMP_DECL;
+ TMP_MARK;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ tests_start ();
+ rands = RANDS;
+
+ ASSERT_ALWAYS (mpn_sqrmod_bnm1_next_size (MAX_N) == MAX_N);
+
+ ap = TMP_ALLOC_LIMBS (MAX_N);
+ refp = TMP_ALLOC_LIMBS (MAX_N * 4);
+ pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
+ scratch
+ = 1+TMP_ALLOC_LIMBS (mpn_sqrmod_bnm1_itch (MAX_N, MAX_N) + 2);
+
+ for (test = 0; test < count; test++)
+ {
+ unsigned size_min;
+ unsigned size_range;
+ mp_size_t an,rn,n;
+ mp_size_t itch;
+ mp_limb_t p_before, p_after, s_before, s_after;
+
+ for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
+ ;
+
+ /* We generate an in the MIN_N <= n <= (1 << size_range). */
+ size_range = size_min
+ + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
+
+ n = MIN_N
+ + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);
+ n = mpn_sqrmod_bnm1_next_size (n);
+
+ if (n == 1)
+ an = 1;
+ else
+ an = ((n+1) >> 1) + gmp_urandomm_ui (rands, (n+1) >> 1);
+
+ mpn_random2 (ap, an);
+
+ /* Sometime trigger the borderline conditions
+ A = -1,0,+1 Mod(B^{n/2}+1).
+ This only makes sense if there is at least a split, i.e. n is even. */
+ if ((test & 0x1f) == 1 && (n & 1) == 0) {
+ mp_size_t x;
+ MPN_COPY (ap, ap + (n >> 1), an - (n >> 1));
+ MPN_ZERO (ap + an - (n >> 1) , n - an);
+ x = (n == an) ? 0 : gmp_urandomm_ui (rands, n - an);
+ ap[x] += gmp_urandomm_ui (rands, 3) - 1;
+ }
+ rn = MIN(n, 2*an);
+ mpn_random2 (pp-1, rn + 2);
+ p_before = pp[-1];
+ p_after = pp[rn];
+
+ itch = mpn_sqrmod_bnm1_itch (n, an);
+ ASSERT_ALWAYS (itch <= mpn_sqrmod_bnm1_itch (MAX_N, MAX_N));
+ mpn_random2 (scratch-1, itch+2);
+ s_before = scratch[-1];
+ s_after = scratch[itch];
+
+ mpn_sqrmod_bnm1 ( pp, n, ap, an, scratch);
+ ref_sqrmod_bnm1 (refp, n, ap, an);
+ if (pp[-1] != p_before || pp[rn] != p_after
+ || scratch[-1] != s_before || scratch[itch] != s_after
+ || mpn_cmp (refp, pp, rn) != 0)
+ {
+ printf ("ERROR in test %d, an = %d, n = %d\n",
+ test, (int) an, (int) n);
+ if (pp[-1] != p_before)
+ {
+ printf ("before pp:"); mpn_dump (pp -1, 1);
+ printf ("keep: "); mpn_dump (&p_before, 1);
+ }
+ if (pp[rn] != p_after)
+ {
+ printf ("after pp:"); mpn_dump (pp + rn, 1);
+ printf ("keep: "); mpn_dump (&p_after, 1);
+ }
+ if (scratch[-1] != s_before)
+ {
+ printf ("before scratch:"); mpn_dump (scratch-1, 1);
+ printf ("keep: "); mpn_dump (&s_before, 1);
+ }
+ if (scratch[itch] != s_after)
+ {
+ printf ("after scratch:"); mpn_dump (scratch + itch, 1);
+ printf ("keep: "); mpn_dump (&s_after, 1);
+ }
+ mpn_dump (ap, an);
+ mpn_dump (pp, rn);
+ mpn_dump (refp, rn);
+
+ abort();
+ }
+ }
+ TMP_FREE;
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/t-toom2-sqr.c b/gmp/tests/mpn/t-toom2-sqr.c
new file mode 100644
index 0000000000..a5cdcb5778
--- /dev/null
+++ b/gmp/tests/mpn/t-toom2-sqr.c
@@ -0,0 +1,6 @@
+#define mpn_toomN_sqr mpn_toom2_sqr
+#define mpn_toomN_sqr_itch mpn_toom2_sqr_itch
+#define MIN_AN MPN_TOOM2_SQR_MINSIZE
+#define MAX_AN SQR_TOOM3_THRESHOLD
+
+#include "toom-sqr-shared.h"
diff --git a/gmp/tests/mpn/t-toom22.c b/gmp/tests/mpn/t-toom22.c
new file mode 100644
index 0000000000..939a88e9d8
--- /dev/null
+++ b/gmp/tests/mpn/t-toom22.c
@@ -0,0 +1,10 @@
+#define mpn_toomMN_mul mpn_toom22_mul
+#define mpn_toomMN_mul_itch mpn_toom22_mul_itch
+#define MIN_AN 2
+
+#define MIN_BN(an) \
+ ((an) >= 2*MUL_TOOM22_THRESHOLD \
+ ? (an) + 2 - MUL_TOOM22_THRESHOLD \
+ : ((an)+1)/2 + 1)
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom3-sqr.c b/gmp/tests/mpn/t-toom3-sqr.c
new file mode 100644
index 0000000000..ccc3b99504
--- /dev/null
+++ b/gmp/tests/mpn/t-toom3-sqr.c
@@ -0,0 +1,6 @@
+#define mpn_toomN_sqr mpn_toom3_sqr
+#define mpn_toomN_sqr_itch mpn_toom3_sqr_itch
+#define MIN_AN MAX(SQR_TOOM3_THRESHOLD,MPN_TOOM3_SQR_MINSIZE)
+#define MAX_AN SQR_TOOM4_THRESHOLD
+
+#include "toom-sqr-shared.h"
diff --git a/gmp/tests/mpn/t-toom32.c b/gmp/tests/mpn/t-toom32.c
new file mode 100644
index 0000000000..e42745da96
--- /dev/null
+++ b/gmp/tests/mpn/t-toom32.c
@@ -0,0 +1,8 @@
+#define mpn_toomMN_mul mpn_toom32_mul
+#define mpn_toomMN_mul_itch mpn_toom32_mul_itch
+
+#define MIN_AN 6
+#define MIN_BN(an) (((an) + 8) / (size_t) 3)
+#define MAX_BN(an) ((an) - 2)
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom33.c b/gmp/tests/mpn/t-toom33.c
new file mode 100644
index 0000000000..7de82b20c9
--- /dev/null
+++ b/gmp/tests/mpn/t-toom33.c
@@ -0,0 +1,11 @@
+#define mpn_toomMN_mul mpn_toom33_mul
+#define mpn_toomMN_mul_itch mpn_toom33_mul_itch
+
+/* Smaller sizes not supported; may lead to recursive calls to
+ toom22_mul with invalid input size. */
+#define MIN_AN MUL_TOOM33_THRESHOLD
+#define MIN_BN(an) (1 + 2*(((an)+2)/(size_t) 3))
+
+#define COUNT 1000
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom4-sqr.c b/gmp/tests/mpn/t-toom4-sqr.c
new file mode 100644
index 0000000000..ca14ab1482
--- /dev/null
+++ b/gmp/tests/mpn/t-toom4-sqr.c
@@ -0,0 +1,6 @@
+#define mpn_toomN_sqr mpn_toom4_sqr
+#define mpn_toomN_sqr_itch mpn_toom4_sqr_itch
+#define MIN_AN MAX(SQR_TOOM3_THRESHOLD,MAX(SQR_TOOM4_THRESHOLD,MPN_TOOM4_SQR_MINSIZE))
+#define MAX_AN SQR_TOOM6_THRESHOLD
+
+#include "toom-sqr-shared.h"
diff --git a/gmp/tests/mpn/t-toom42.c b/gmp/tests/mpn/t-toom42.c
new file mode 100644
index 0000000000..09a4a0c115
--- /dev/null
+++ b/gmp/tests/mpn/t-toom42.c
@@ -0,0 +1,8 @@
+#define mpn_toomMN_mul mpn_toom42_mul
+#define mpn_toomMN_mul_itch mpn_toom42_mul_itch
+
+#define MIN_AN 10
+#define MIN_BN(an) (((an) + 7) >> 2)
+#define MAX_BN(an) ((2*(an)-5) / (size_t) 3)
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom43.c b/gmp/tests/mpn/t-toom43.c
new file mode 100644
index 0000000000..224a45bc38
--- /dev/null
+++ b/gmp/tests/mpn/t-toom43.c
@@ -0,0 +1,8 @@
+#define mpn_toomMN_mul mpn_toom43_mul
+#define mpn_toomMN_mul_itch mpn_toom43_mul_itch
+
+#define MIN_AN 25
+#define MIN_BN(an) (1 + 2*(((an)+3) >> 2))
+#define MAX_BN(an) ((an)-3)
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom44.c b/gmp/tests/mpn/t-toom44.c
new file mode 100644
index 0000000000..6c627e3428
--- /dev/null
+++ b/gmp/tests/mpn/t-toom44.c
@@ -0,0 +1,11 @@
+#define mpn_toomMN_mul mpn_toom44_mul
+#define mpn_toomMN_mul_itch mpn_toom44_mul_itch
+
+/* Smaller sizes not supported; may lead to recursive calls to
+ toom22_mul or toom33_mul with invalid input size. */
+#define MIN_AN MUL_TOOM44_THRESHOLD
+#define MIN_BN(an) (1 + 3*(((an)+3)>>2))
+
+#define COUNT 1000
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom52.c b/gmp/tests/mpn/t-toom52.c
new file mode 100644
index 0000000000..d3fb134f2e
--- /dev/null
+++ b/gmp/tests/mpn/t-toom52.c
@@ -0,0 +1,8 @@
+#define mpn_toomMN_mul mpn_toom52_mul
+#define mpn_toomMN_mul_itch mpn_toom52_mul_itch
+
+#define MIN_AN 32
+#define MIN_BN(an) (((an) + 9) / (size_t) 5)
+#define MAX_BN(an) (((an) - 3) >> 1)
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom53.c b/gmp/tests/mpn/t-toom53.c
new file mode 100644
index 0000000000..ddbf177aec
--- /dev/null
+++ b/gmp/tests/mpn/t-toom53.c
@@ -0,0 +1,8 @@
+#define mpn_toomMN_mul mpn_toom53_mul
+#define mpn_toomMN_mul_itch mpn_toom53_mul_itch
+
+#define MIN_AN 17
+#define MIN_BN(an) (1 + 2*(((an) + 4) / (size_t) 5))
+#define MAX_BN(an) ((3*(an) - 11) >> 2)
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom54.c b/gmp/tests/mpn/t-toom54.c
new file mode 100644
index 0000000000..52a2bee7b3
--- /dev/null
+++ b/gmp/tests/mpn/t-toom54.c
@@ -0,0 +1,8 @@
+#define mpn_toomMN_mul mpn_toom54_mul
+#define mpn_toomMN_mul_itch mpn_toom54_mul_itch
+
+#define MIN_AN 31
+#define MIN_BN(an) ((3*(an) + 32) / (size_t) 5) /* 3/5 */
+#define MAX_BN(an) ((an) - 6) /* 1/1 */
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom6-sqr.c b/gmp/tests/mpn/t-toom6-sqr.c
new file mode 100644
index 0000000000..67d7a63d32
--- /dev/null
+++ b/gmp/tests/mpn/t-toom6-sqr.c
@@ -0,0 +1,8 @@
+#define mpn_toomN_sqr mpn_toom6_sqr
+#define mpn_toomN_sqr_itch mpn_toom6_sqr_itch
+#define MIN_AN MAX(SQR_TOOM3_THRESHOLD,MAX(SQR_TOOM4_THRESHOLD,MAX(SQR_TOOM6_THRESHOLD,MPN_TOOM6_SQR_MINSIZE)))
+#define MAX_AN SQR_TOOM8_THRESHOLD
+
+#define COUNT 250
+
+#include "toom-sqr-shared.h"
diff --git a/gmp/tests/mpn/t-toom62.c b/gmp/tests/mpn/t-toom62.c
new file mode 100644
index 0000000000..1cb2aab26c
--- /dev/null
+++ b/gmp/tests/mpn/t-toom62.c
@@ -0,0 +1,8 @@
+#define mpn_toomMN_mul mpn_toom62_mul
+#define mpn_toomMN_mul_itch mpn_toom62_mul_itch
+
+#define MIN_AN 31
+#define MIN_BN(an) (((an) + 11) / (size_t) 6)
+#define MAX_BN(an) ((2*(an) - 7) / (size_t) 5)
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom63.c b/gmp/tests/mpn/t-toom63.c
new file mode 100644
index 0000000000..d79165dcbe
--- /dev/null
+++ b/gmp/tests/mpn/t-toom63.c
@@ -0,0 +1,8 @@
+#define mpn_toomMN_mul mpn_toom63_mul
+#define mpn_toomMN_mul_itch mpn_toom63_mul_itch
+
+#define MIN_AN 49
+#define MIN_BN(an) (2*(((an) + 23) / (size_t) 6)) /* 2/6 */
+#define MAX_BN(an) ((3*(an) - 23) / (size_t) 5) /* 3/5 */
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom6h.c b/gmp/tests/mpn/t-toom6h.c
new file mode 100644
index 0000000000..5cca9fc90e
--- /dev/null
+++ b/gmp/tests/mpn/t-toom6h.c
@@ -0,0 +1,13 @@
+#define mpn_toomMN_mul mpn_toom6h_mul
+#define mpn_toomMN_mul_itch mpn_toom6h_mul_itch
+
+#define SIZE_LOG 11
+
+/* Smaller sizes not supported; may lead to recursive calls to
+ toom22_mul, toom33_mul, or toom44_mul with invalid input size. */
+#define MIN_AN MUL_TOOM6H_MIN
+#define MIN_BN(an) (MAX ((an*3)>>3, 46))
+
+#define COUNT 1000
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/t-toom8-sqr.c b/gmp/tests/mpn/t-toom8-sqr.c
new file mode 100644
index 0000000000..0eee605928
--- /dev/null
+++ b/gmp/tests/mpn/t-toom8-sqr.c
@@ -0,0 +1,8 @@
+#define mpn_toomN_sqr mpn_toom8_sqr
+#define mpn_toomN_sqr_itch mpn_toom8_sqr_itch
+#define MIN_AN MAX(SQR_TOOM3_THRESHOLD,MAX(SQR_TOOM4_THRESHOLD,MAX(SQR_TOOM6_THRESHOLD,MAX(SQR_TOOM8_THRESHOLD,MPN_TOOM8_SQR_MINSIZE))))
+#define MAX_AN SQR_FFT_THRESHOLD
+
+#define COUNT 250
+
+#include "toom-sqr-shared.h"
diff --git a/gmp/tests/mpn/t-toom8h.c b/gmp/tests/mpn/t-toom8h.c
new file mode 100644
index 0000000000..aeeabb274b
--- /dev/null
+++ b/gmp/tests/mpn/t-toom8h.c
@@ -0,0 +1,18 @@
+#define mpn_toomMN_mul mpn_toom8h_mul
+#define mpn_toomMN_mul_itch mpn_toom8h_mul_itch
+
+#define SIZE_LOG 11
+
+/* Smaller sizes not supported; may lead to recursive calls to
+ toom{22,33,44,6h}_mul with invalid input size. */
+#define MIN_AN MUL_TOOM8H_MIN
+
+#define MIN_BN(an) \
+(MAX(GMP_NUMB_BITS <= 10*3 ? (an*6)/10 : \
+ GMP_NUMB_BITS <= 11*3 ? (an*5)/11 : \
+ GMP_NUMB_BITS <= 12*3 ? (an*4)/12 : \
+ (an*4)/13, 86) )
+
+#define COUNT 1000
+
+#include "toom-shared.h"
diff --git a/gmp/tests/mpn/toom-shared.h b/gmp/tests/mpn/toom-shared.h
new file mode 100644
index 0000000000..7479e7efd9
--- /dev/null
+++ b/gmp/tests/mpn/toom-shared.h
@@ -0,0 +1,158 @@
+/* Test for various Toom functions.
+
+Copyright 2009 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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Main file is expected to define mpn_toomMN_mul,
+ * mpn_toomMN_mul_itch, MIN_AN, MIN_BN(an), MAX_BN(an) and then
+ * include this file. */
+
+/* Sizes are up to 2^SIZE_LOG limbs */
+#ifndef SIZE_LOG
+#define SIZE_LOG 10
+#endif
+
+#ifndef COUNT
+#define COUNT 2000
+#endif
+
+#define MAX_AN (1L << SIZE_LOG)
+
+#ifndef MAX_BN
+#define MAX_BN(an) (an)
+#endif
+
+/* For general toomMN_mul, we need
+ *
+ * MIN_BN(an) = N + floor(((N-1)*an + M - N)/M)
+ *
+ * MAX_BN(an) = floor(N*(an-1)/(M-1)) - N + 1
+ */
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr ap, bp, refp, pp, scratch;
+ int count = COUNT;
+ int test;
+ gmp_randstate_ptr rands;
+ TMP_DECL;
+ TMP_MARK;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ tests_start ();
+ rands = RANDS;
+
+ ap = TMP_ALLOC_LIMBS (MAX_AN);
+ bp = TMP_ALLOC_LIMBS (MAX_BN(MAX_AN));
+ refp = TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN));
+ pp = 1+TMP_ALLOC_LIMBS (MAX_AN + MAX_BN(MAX_AN)+2);
+ scratch
+ = 1+TMP_ALLOC_LIMBS (mpn_toomMN_mul_itch (MAX_AN, MAX_BN(MAX_AN))
+ + 2);
+
+ for (test = 0; test < count; test++)
+ {
+ unsigned size_min;
+ unsigned size_range;
+ mp_size_t an, bn;
+ mp_size_t itch;
+ mp_limb_t p_before, p_after, s_before, s_after;
+
+ for (size_min = 1; (1L << size_min) < MIN_AN; size_min++)
+ ;
+
+ /* We generate an in the MIN_AN <= an <= (1 << size_range). */
+ size_range = size_min
+ + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
+
+ an = MIN_AN
+ + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_AN);
+ bn = MIN_BN(an)
+ + gmp_urandomm_ui (rands, MAX_BN(an) + 1 - MIN_BN(an));
+
+ mpn_random2 (ap, an);
+ mpn_random2 (bp, bn);
+ mpn_random2 (pp-1, an + bn + 2);
+ p_before = pp[-1];
+ p_after = pp[an + bn];
+
+ itch = mpn_toomMN_mul_itch (an, bn);
+ ASSERT_ALWAYS (itch <= mpn_toomMN_mul_itch (MAX_AN, MAX_BN(MAX_AN)));
+ mpn_random2 (scratch-1, itch+2);
+ s_before = scratch[-1];
+ s_after = scratch[itch];
+
+ mpn_toomMN_mul (pp, ap, an, bp, bn, scratch);
+ refmpn_mul (refp, ap, an, bp, bn);
+ if (pp[-1] != p_before || pp[an + bn] != p_after
+ || scratch[-1] != s_before || scratch[itch] != s_after
+ || mpn_cmp (refp, pp, an + bn) != 0)
+ {
+ printf ("ERROR in test %d, an = %d, bn = %d\n",
+ test, (int) an, (int) bn);
+ if (pp[-1] != p_before)
+ {
+ printf ("before pp:"); mpn_dump (pp -1, 1);
+ printf ("keep: "); mpn_dump (&p_before, 1);
+ }
+ if (pp[an + bn] != p_after)
+ {
+ printf ("after pp:"); mpn_dump (pp + an + bn, 1);
+ printf ("keep: "); mpn_dump (&p_after, 1);
+ }
+ if (scratch[-1] != s_before)
+ {
+ printf ("before scratch:"); mpn_dump (scratch-1, 1);
+ printf ("keep: "); mpn_dump (&s_before, 1);
+ }
+ if (scratch[itch] != s_after)
+ {
+ printf ("after scratch:"); mpn_dump (scratch + itch, 1);
+ printf ("keep: "); mpn_dump (&s_after, 1);
+ }
+ mpn_dump (ap, an);
+ mpn_dump (bp, bn);
+ mpn_dump (pp, an + bn);
+ mpn_dump (refp, an + bn);
+
+ abort();
+ }
+ }
+ TMP_FREE;
+
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpn/toom-sqr-shared.h b/gmp/tests/mpn/toom-sqr-shared.h
new file mode 100644
index 0000000000..944cfab000
--- /dev/null
+++ b/gmp/tests/mpn/toom-sqr-shared.h
@@ -0,0 +1,129 @@
+/* Test for various Toom squaring functions.
+
+Copyright 2009, 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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Main file is expected to define mpn_toomN_mul, mpn_toomN_sqr_itch,
+ * MIN_AN, MAX_AN and then include this file. */
+
+#ifndef COUNT
+#define COUNT 2000
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mp_ptr ap, refp, pp, scratch;
+ int count = COUNT;
+ int test;
+ gmp_randstate_ptr rands;
+ TMP_DECL;
+ TMP_MARK;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+
+ tests_start ();
+
+ if (MAX_AN > MIN_AN) {
+ rands = RANDS;
+
+ ap = TMP_ALLOC_LIMBS (MAX_AN);
+ refp = TMP_ALLOC_LIMBS (MAX_AN * 2);
+ pp = 1 + TMP_ALLOC_LIMBS (MAX_AN * 2 + 2);
+ scratch
+ = 1+TMP_ALLOC_LIMBS (mpn_toomN_sqr_itch (MAX_AN) + 2);
+
+ for (test = 0; test < count; test++)
+ {
+ unsigned size_min;
+ unsigned size_range;
+ mp_size_t an;
+ mp_size_t itch;
+ mp_limb_t p_before, p_after, s_before, s_after;
+
+ an = MIN_AN
+ + gmp_urandomm_ui (rands, MAX_AN - MIN_AN);
+
+ mpn_random2 (ap, an);
+ mpn_random2 (pp-1, an * 2 + 2);
+ p_before = pp[-1];
+ p_after = pp[an * 2];
+
+ itch = mpn_toomN_sqr_itch (an);
+ ASSERT_ALWAYS (itch <= mpn_toomN_sqr_itch (MAX_AN));
+ mpn_random2 (scratch-1, itch+2);
+ s_before = scratch[-1];
+ s_after = scratch[itch];
+
+ mpn_toomN_sqr (pp, ap, an, scratch);
+ refmpn_mul (refp, ap, an, ap, an);
+ if (pp[-1] != p_before || pp[an * 2] != p_after
+ || scratch[-1] != s_before || scratch[itch] != s_after
+ || mpn_cmp (refp, pp, an * 2) != 0)
+ {
+ printf ("ERROR in test %d, an = %d\n",
+ test, (int) an);
+ if (pp[-1] != p_before)
+ {
+ printf ("before pp:"); mpn_dump (pp -1, 1);
+ printf ("keep: "); mpn_dump (&p_before, 1);
+ }
+ if (pp[an * 2] != p_after)
+ {
+ printf ("after pp:"); mpn_dump (pp + an * 2, 1);
+ printf ("keep: "); mpn_dump (&p_after, 1);
+ }
+ if (scratch[-1] != s_before)
+ {
+ printf ("before scratch:"); mpn_dump (scratch-1, 1);
+ printf ("keep: "); mpn_dump (&s_before, 1);
+ }
+ if (scratch[itch] != s_after)
+ {
+ printf ("after scratch:"); mpn_dump (scratch + itch, 1);
+ printf ("keep: "); mpn_dump (&s_after, 1);
+ }
+ mpn_dump (ap, an);
+ mpn_dump (pp, an * 2);
+ mpn_dump (refp, an * 2);
+
+ abort();
+ }
+ }
+ TMP_FREE;
+ }
+
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpq/Makefile.am b/gmp/tests/mpq/Makefile.am
new file mode 100644
index 0000000000..ca8dfd9a70
--- /dev/null
+++ b/gmp/tests/mpq/Makefile.am
@@ -0,0 +1,34 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 1996, 1999-2002, 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/.
+
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+
+check_PROGRAMS = t-aors t-cmp t-cmp_ui t-cmp_si t-equal t-get_d t-get_str \
+ t-inp_str t-inv t-md_2exp t-set_f t-set_str io reuse
+TESTS = $(check_PROGRAMS)
+
+# Temporary files used by the tests. Removed automatically if the tests
+# pass, but ensure they're cleaned if they fail.
+#
+CLEANFILES = *.tmp
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
diff --git a/gmp/tests/mpq/Makefile.in b/gmp/tests/mpq/Makefile.in
new file mode 100644
index 0000000000..89b3c1266f
--- /dev/null
+++ b/gmp/tests/mpq/Makefile.in
@@ -0,0 +1,761 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 1996, 1999-2002, 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/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+check_PROGRAMS = t-aors$(EXEEXT) t-cmp$(EXEEXT) t-cmp_ui$(EXEEXT) \
+ t-cmp_si$(EXEEXT) t-equal$(EXEEXT) t-get_d$(EXEEXT) \
+ t-get_str$(EXEEXT) t-inp_str$(EXEEXT) t-inv$(EXEEXT) \
+ t-md_2exp$(EXEEXT) t-set_f$(EXEEXT) t-set_str$(EXEEXT) \
+ io$(EXEEXT) reuse$(EXEEXT)
+subdir = tests/mpq
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+io_SOURCES = io.c
+io_OBJECTS = io.$(OBJEXT)
+io_LDADD = $(LDADD)
+io_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+reuse_SOURCES = reuse.c
+reuse_OBJECTS = reuse.$(OBJEXT)
+reuse_LDADD = $(LDADD)
+reuse_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_aors_SOURCES = t-aors.c
+t_aors_OBJECTS = t-aors.$(OBJEXT)
+t_aors_LDADD = $(LDADD)
+t_aors_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cmp_SOURCES = t-cmp.c
+t_cmp_OBJECTS = t-cmp.$(OBJEXT)
+t_cmp_LDADD = $(LDADD)
+t_cmp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cmp_si_SOURCES = t-cmp_si.c
+t_cmp_si_OBJECTS = t-cmp_si.$(OBJEXT)
+t_cmp_si_LDADD = $(LDADD)
+t_cmp_si_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cmp_ui_SOURCES = t-cmp_ui.c
+t_cmp_ui_OBJECTS = t-cmp_ui.$(OBJEXT)
+t_cmp_ui_LDADD = $(LDADD)
+t_cmp_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_equal_SOURCES = t-equal.c
+t_equal_OBJECTS = t-equal.$(OBJEXT)
+t_equal_LDADD = $(LDADD)
+t_equal_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_d_SOURCES = t-get_d.c
+t_get_d_OBJECTS = t-get_d.$(OBJEXT)
+t_get_d_LDADD = $(LDADD)
+t_get_d_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_str_SOURCES = t-get_str.c
+t_get_str_OBJECTS = t-get_str.$(OBJEXT)
+t_get_str_LDADD = $(LDADD)
+t_get_str_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_inp_str_SOURCES = t-inp_str.c
+t_inp_str_OBJECTS = t-inp_str.$(OBJEXT)
+t_inp_str_LDADD = $(LDADD)
+t_inp_str_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_inv_SOURCES = t-inv.c
+t_inv_OBJECTS = t-inv.$(OBJEXT)
+t_inv_LDADD = $(LDADD)
+t_inv_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_md_2exp_SOURCES = t-md_2exp.c
+t_md_2exp_OBJECTS = t-md_2exp.$(OBJEXT)
+t_md_2exp_LDADD = $(LDADD)
+t_md_2exp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_f_SOURCES = t-set_f.c
+t_set_f_OBJECTS = t-set_f.$(OBJEXT)
+t_set_f_LDADD = $(LDADD)
+t_set_f_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_str_SOURCES = t-set_str.c
+t_set_str_OBJECTS = t-set_str.$(OBJEXT)
+t_set_str_LDADD = $(LDADD)
+t_set_str_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = io.c reuse.c t-aors.c t-cmp.c t-cmp_si.c t-cmp_ui.c \
+ t-equal.c t-get_d.c t-get_str.c t-inp_str.c t-inv.c \
+ t-md_2exp.c t-set_f.c t-set_str.c
+DIST_SOURCES = io.c reuse.c t-aors.c t-cmp.c t-cmp_si.c t-cmp_ui.c \
+ t-equal.c t-get_d.c t-get_str.c t-inp_str.c t-inv.c \
+ t-md_2exp.c t-set_f.c t-set_str.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+TESTS = $(check_PROGRAMS)
+
+# Temporary files used by the tests. Removed automatically if the tests
+# pass, but ensure they're cleaned if they fail.
+#
+CLEANFILES = *.tmp
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/mpq/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps tests/mpq/Makefile
+.PRECIOUS: 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
+io$(EXEEXT): $(io_OBJECTS) $(io_DEPENDENCIES) $(EXTRA_io_DEPENDENCIES)
+ @rm -f io$(EXEEXT)
+ $(LINK) $(io_OBJECTS) $(io_LDADD) $(LIBS)
+reuse$(EXEEXT): $(reuse_OBJECTS) $(reuse_DEPENDENCIES) $(EXTRA_reuse_DEPENDENCIES)
+ @rm -f reuse$(EXEEXT)
+ $(LINK) $(reuse_OBJECTS) $(reuse_LDADD) $(LIBS)
+t-aors$(EXEEXT): $(t_aors_OBJECTS) $(t_aors_DEPENDENCIES) $(EXTRA_t_aors_DEPENDENCIES)
+ @rm -f t-aors$(EXEEXT)
+ $(LINK) $(t_aors_OBJECTS) $(t_aors_LDADD) $(LIBS)
+t-cmp$(EXEEXT): $(t_cmp_OBJECTS) $(t_cmp_DEPENDENCIES) $(EXTRA_t_cmp_DEPENDENCIES)
+ @rm -f t-cmp$(EXEEXT)
+ $(LINK) $(t_cmp_OBJECTS) $(t_cmp_LDADD) $(LIBS)
+t-cmp_si$(EXEEXT): $(t_cmp_si_OBJECTS) $(t_cmp_si_DEPENDENCIES) $(EXTRA_t_cmp_si_DEPENDENCIES)
+ @rm -f t-cmp_si$(EXEEXT)
+ $(LINK) $(t_cmp_si_OBJECTS) $(t_cmp_si_LDADD) $(LIBS)
+t-cmp_ui$(EXEEXT): $(t_cmp_ui_OBJECTS) $(t_cmp_ui_DEPENDENCIES) $(EXTRA_t_cmp_ui_DEPENDENCIES)
+ @rm -f t-cmp_ui$(EXEEXT)
+ $(LINK) $(t_cmp_ui_OBJECTS) $(t_cmp_ui_LDADD) $(LIBS)
+t-equal$(EXEEXT): $(t_equal_OBJECTS) $(t_equal_DEPENDENCIES) $(EXTRA_t_equal_DEPENDENCIES)
+ @rm -f t-equal$(EXEEXT)
+ $(LINK) $(t_equal_OBJECTS) $(t_equal_LDADD) $(LIBS)
+t-get_d$(EXEEXT): $(t_get_d_OBJECTS) $(t_get_d_DEPENDENCIES) $(EXTRA_t_get_d_DEPENDENCIES)
+ @rm -f t-get_d$(EXEEXT)
+ $(LINK) $(t_get_d_OBJECTS) $(t_get_d_LDADD) $(LIBS)
+t-get_str$(EXEEXT): $(t_get_str_OBJECTS) $(t_get_str_DEPENDENCIES) $(EXTRA_t_get_str_DEPENDENCIES)
+ @rm -f t-get_str$(EXEEXT)
+ $(LINK) $(t_get_str_OBJECTS) $(t_get_str_LDADD) $(LIBS)
+t-inp_str$(EXEEXT): $(t_inp_str_OBJECTS) $(t_inp_str_DEPENDENCIES) $(EXTRA_t_inp_str_DEPENDENCIES)
+ @rm -f t-inp_str$(EXEEXT)
+ $(LINK) $(t_inp_str_OBJECTS) $(t_inp_str_LDADD) $(LIBS)
+t-inv$(EXEEXT): $(t_inv_OBJECTS) $(t_inv_DEPENDENCIES) $(EXTRA_t_inv_DEPENDENCIES)
+ @rm -f t-inv$(EXEEXT)
+ $(LINK) $(t_inv_OBJECTS) $(t_inv_LDADD) $(LIBS)
+t-md_2exp$(EXEEXT): $(t_md_2exp_OBJECTS) $(t_md_2exp_DEPENDENCIES) $(EXTRA_t_md_2exp_DEPENDENCIES)
+ @rm -f t-md_2exp$(EXEEXT)
+ $(LINK) $(t_md_2exp_OBJECTS) $(t_md_2exp_LDADD) $(LIBS)
+t-set_f$(EXEEXT): $(t_set_f_OBJECTS) $(t_set_f_DEPENDENCIES) $(EXTRA_t_set_f_DEPENDENCIES)
+ @rm -f t-set_f$(EXEEXT)
+ $(LINK) $(t_set_f_OBJECTS) $(t_set_f_LDADD) $(LIBS)
+t-set_str$(EXEEXT): $(t_set_str_OBJECTS) $(t_set_str_DEPENDENCIES) $(EXTRA_t_set_str_DEPENDENCIES)
+ @rm -f t-set_str$(EXEEXT)
+ $(LINK) $(t_set_str_OBJECTS) $(t_set_str_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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 all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool ctags \
+ 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 \
+ tags uninstall uninstall-am
+
+
+$(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/gmp/tests/mpq/io.c b/gmp/tests/mpq/io.c
new file mode 100644
index 0000000000..a1b718d2cf
--- /dev/null
+++ b/gmp/tests/mpq/io.c
@@ -0,0 +1,137 @@
+/* Test conversion and I/O using mpq_out_str and mpq_inp_str.
+
+Copyright 1993, 1994, 1996, 2000, 2001, 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 <stdio.h>
+#include <stdlib.h>
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for unlink */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define FILENAME "io.tmp"
+
+void
+debug_mp (mpq_t x, int base)
+{
+ mpq_out_str (stdout, base, x); fputc ('\n', stdout);
+}
+
+int
+main (int argc, char **argv)
+{
+ mpq_t op1, op2;
+ mp_size_t size;
+ int i;
+ int reps = 10000;
+ FILE *fp;
+ int base;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+ size_t nread;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpq_init (op1);
+ mpq_init (op2);
+
+ fp = fopen (FILENAME, "w+");
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 10 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_errandomb (mpq_numref(op1), rands, 512L);
+ mpz_errandomb_nonzero (mpq_denref(op1), rands, 512L);
+ mpq_canonicalize (op1);
+
+ mpz_urandomb (bs, rands, 1);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpq_neg (op1, op1);
+
+ mpz_urandomb (bs, rands, 16);
+ bsi = mpz_get_ui (bs);
+ base = bsi % 36 + 1;
+ if (base == 1)
+ base = 0;
+
+ rewind (fp);
+ if (mpq_out_str (fp, base, op1) == 0
+ || putc (' ', fp) == EOF
+ || fflush (fp) != 0)
+ {
+ printf ("mpq_out_str write error\n");
+ abort ();
+ }
+
+ rewind (fp);
+ nread = mpq_inp_str (op2, fp, base);
+ if (nread == 0)
+ {
+ if (ferror (fp))
+ printf ("mpq_inp_str stream read error\n");
+ else
+ printf ("mpq_inp_str data conversion error\n");
+ abort ();
+ }
+
+ if (nread != ftell(fp))
+ {
+ printf ("mpq_inp_str nread doesn't match ftell\n");
+ printf (" nread %lu\n", (unsigned long) nread);
+ printf (" ftell %ld\n", ftell(fp));
+ abort ();
+ }
+
+ if (mpq_cmp (op1, op2))
+ {
+ printf ("ERROR\n");
+ printf ("op1 = "); debug_mp (op1, -16);
+ printf ("op2 = "); debug_mp (op2, -16);
+ printf ("base = %d\n", base);
+ abort ();
+ }
+ }
+
+ fclose (fp);
+
+ unlink (FILENAME);
+
+ mpz_clear (bs);
+ mpq_clear (op1);
+ mpq_clear (op2);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpq/reuse.c b/gmp/tests/mpq/reuse.c
new file mode 100644
index 0000000000..da60bde940
--- /dev/null
+++ b/gmp/tests/mpq/reuse.c
@@ -0,0 +1,230 @@
+/* Test that routines allow reusing a source variable as destination.
+
+Copyright 1996, 2000-2002, 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#if __GMP_LIBGMP_DLL
+
+/* FIXME: When linking to a DLL libgmp, mpq_add etc can't be used as
+ initializers for global variables because they're effectively global
+ variables (function pointers) themselves. Perhaps calling a test
+ function successively with mpq_add etc would be better. */
+
+int
+main (void)
+{
+ printf ("Test suppressed for windows DLL\n");
+ exit (0);
+}
+
+
+#else /* ! DLL_EXPORT */
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+void dump_abort (const char *, mpq_t, mpq_t);
+
+typedef void (*dss_func) (mpq_ptr, mpq_srcptr, mpq_srcptr);
+
+dss_func dss_funcs[] =
+{
+ mpq_div, mpq_add, mpq_mul, mpq_sub,
+};
+
+const char *dss_func_names[] =
+{
+ "mpq_div", "mpq_add", "mpq_mul", "mpq_sub",
+};
+
+typedef void (*ds_func) (mpq_ptr, mpq_srcptr);
+
+ds_func ds_funcs[] =
+{
+ mpq_abs, mpq_neg,
+};
+
+const char *ds_func_names[] =
+{
+ "mpq_abs", "mpq_neg",
+};
+
+typedef void (*dsi_func) (mpq_ptr, mpq_srcptr, unsigned long int);
+
+dsi_func dsi_funcs[] =
+{
+ mpq_mul_2exp, mpq_div_2exp
+};
+
+const char *dsi_func_names[] =
+{
+ "mpq_mul_2exp", "mpq_div_2exp"
+};
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ int pass, reps = 100;
+ mpq_t in1, in2, out1;
+ unsigned long int randbits, in2i;
+ mpq_t res1, res2, res3;
+ gmp_randstate_ptr rands;
+
+ tests_start ();
+
+ if (argc > 1)
+ reps = strtol (argv[1], 0, 0);
+
+ rands = RANDS;
+
+ mpq_init (in1);
+ mpq_init (in2);
+ mpq_init (out1);
+ mpq_init (res1);
+ mpq_init (res2);
+ mpq_init (res3);
+
+ for (pass = 1; pass <= reps; pass++)
+ {
+ randbits = urandom ();
+
+ if (randbits & 1)
+ {
+ mpq_clear (in1);
+ mpq_init (in1);
+ }
+ randbits >>= 1;
+ mpz_errandomb (mpq_numref(in1), rands, 512L);
+ mpz_errandomb_nonzero (mpq_denref(in1), rands, 512L);
+ if (randbits & 1)
+ mpz_neg (mpq_numref(in1),mpq_numref(in1));
+ randbits >>= 1;
+ mpq_canonicalize (in1);
+
+ if (randbits & 1)
+ {
+ mpq_clear (in2);
+ mpq_init (in2);
+ }
+ randbits >>= 1;
+ mpz_errandomb (mpq_numref(in2), rands, 512L);
+ mpz_errandomb_nonzero (mpq_denref(in2), rands, 512L);
+ if (randbits & 1)
+ mpz_neg (mpq_numref(in2),mpq_numref(in2));
+ randbits >>= 1;
+ mpq_canonicalize (in2);
+
+ for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
+ {
+ /* Don't divide by 0. */
+ if (i == 0 && mpq_cmp_ui (in2, 0, 1) == 0)
+ continue;
+
+ if (randbits & 1)
+ {
+ mpq_clear (res1);
+ mpq_init (res1);
+ }
+ randbits >>= 1;
+
+ (dss_funcs[i]) (res1, in1, in2);
+
+ mpq_set (out1, in1);
+ (dss_funcs[i]) (out1, out1, in2);
+ mpq_set (res2, out1);
+
+ mpq_set (out1, in2);
+ (dss_funcs[i]) (out1, in1, out1);
+ mpq_set (res3, out1);
+
+ if (mpq_cmp (res1, res2) != 0)
+ dump_abort (dss_func_names[i], res1, res2);
+ if (mpq_cmp (res1, res3) != 0)
+ dump_abort (dss_func_names[i], res1, res3);
+ }
+
+ for (i = 0; i < sizeof (ds_funcs) / sizeof (ds_func); i++)
+ {
+ if (randbits & 1)
+ {
+ mpq_clear (res1);
+ mpq_init (res1);
+ }
+ randbits >>= 1;
+ (ds_funcs[i]) (res1, in1);
+
+ mpq_set (out1, in1);
+ (ds_funcs[i]) (out1, out1);
+ mpq_set (res2, out1);
+
+ if (mpq_cmp (res1, res2) != 0)
+ dump_abort (ds_func_names[i], res1, res2);
+ }
+
+ in2i = urandom () % 65536;
+ for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++)
+ {
+ if (randbits & 1)
+ {
+ mpq_clear (res1);
+ mpq_init (res1);
+ }
+ randbits >>= 1;
+
+ (dsi_funcs[i]) (res1, in1, in2i);
+
+ mpq_set (out1, in1);
+ (dsi_funcs[i]) (out1, out1, in2i);
+ mpq_set (res2, out1);
+
+ if (mpq_cmp (res1, res2) != 0)
+ dump_abort (dsi_func_names[i], res1, res2);
+ }
+
+ }
+
+ mpq_clear (in1);
+ mpq_clear (in2);
+ mpq_clear (out1);
+ mpq_clear (res1);
+ mpq_clear (res2);
+ mpq_clear (res3);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort (const char *name, mpq_t res1, mpq_t res2)
+{
+ printf ("failure in %s:\n", name);
+ mpq_trace (" res1 ", res1);
+ mpq_trace (" res2 ", res2);
+ abort ();
+}
+
+#endif /* ! DLL_EXPORT */
diff --git a/gmp/tests/mpq/t-aors.c b/gmp/tests/mpq/t-aors.c
new file mode 100644
index 0000000000..a65f5d8ab8
--- /dev/null
+++ b/gmp/tests/mpq/t-aors.c
@@ -0,0 +1,183 @@
+/* Test mpq_add and mpq_sub.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_all (mpq_ptr x, mpq_ptr y, mpq_ptr want_add, mpq_ptr want_sub)
+{
+ mpq_t got;
+ int neg_x, neg_y, swap;
+
+ mpq_init (got);
+
+ MPQ_CHECK_FORMAT (want_add);
+ MPQ_CHECK_FORMAT (want_sub);
+ MPQ_CHECK_FORMAT (x);
+ MPQ_CHECK_FORMAT (y);
+
+ for (swap = 0; swap <= 1; swap++)
+ {
+ for (neg_x = 0; neg_x <= 1; neg_x++)
+ {
+ for (neg_y = 0; neg_y <= 1; neg_y++)
+ {
+ mpq_add (got, x, y);
+ MPQ_CHECK_FORMAT (got);
+ if (! mpq_equal (got, want_add))
+ {
+ printf ("mpq_add wrong\n");
+ mpq_trace (" x ", x);
+ mpq_trace (" y ", y);
+ mpq_trace (" got ", got);
+ mpq_trace (" want", want_add);
+ abort ();
+ }
+
+ mpq_sub (got, x, y);
+ MPQ_CHECK_FORMAT (got);
+ if (! mpq_equal (got, want_sub))
+ {
+ printf ("mpq_sub wrong\n");
+ mpq_trace (" x ", x);
+ mpq_trace (" y ", y);
+ mpq_trace (" got ", got);
+ mpq_trace (" want", want_sub);
+ abort ();
+ }
+
+
+ mpq_neg (y, y);
+ mpq_swap (want_add, want_sub);
+ }
+
+ mpq_neg (x, x);
+ mpq_swap (want_add, want_sub);
+ mpq_neg (want_add, want_add);
+ mpq_neg (want_sub, want_sub);
+ }
+
+ mpq_swap (x, y);
+ mpq_neg (want_sub, want_sub);
+ }
+
+ mpq_clear (got);
+}
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *x;
+ const char *y;
+ const char *want_add;
+ const char *want_sub;
+
+ } data[] = {
+
+ { "0", "0", "0", "0" },
+ { "1", "0", "1", "1" },
+ { "1", "1", "2", "0" },
+
+ { "1/2", "1/2", "1", "0" },
+ { "5/6", "14/15", "53/30", "-1/10" },
+ };
+
+ mpq_t x, y, want_add, want_sub;
+ int i;
+
+ mpq_init (x);
+ mpq_init (y);
+ mpq_init (want_add);
+ mpq_init (want_sub);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpq_set_str_or_abort (x, data[i].x, 0);
+ mpq_set_str_or_abort (y, data[i].y, 0);
+ mpq_set_str_or_abort (want_add, data[i].want_add, 0);
+ mpq_set_str_or_abort (want_sub, data[i].want_sub, 0);
+
+ check_all (x, y, want_add, want_sub);
+ }
+
+ mpq_clear (x);
+ mpq_clear (y);
+ mpq_clear (want_add);
+ mpq_clear (want_sub);
+}
+
+
+void
+check_rand (void)
+{
+ mpq_t x, y, want_add, want_sub;
+ int i;
+ gmp_randstate_ptr rands = RANDS;
+
+ mpq_init (x);
+ mpq_init (y);
+ mpq_init (want_add);
+ mpq_init (want_sub);
+
+ for (i = 0; i < 500; i++)
+ {
+ mpz_errandomb (mpq_numref(x), rands, 512L);
+ mpz_errandomb_nonzero (mpq_denref(x), rands, 512L);
+ mpq_canonicalize (x);
+
+ mpz_errandomb (mpq_numref(y), rands, 512L);
+ mpz_errandomb_nonzero (mpq_denref(y), rands, 512L);
+ mpq_canonicalize (y);
+
+ refmpq_add (want_add, x, y);
+ refmpq_sub (want_sub, x, y);
+
+ check_all (x, y, want_add, want_sub);
+ }
+
+ mpq_clear (x);
+ mpq_clear (y);
+ mpq_clear (want_add);
+ mpq_clear (want_sub);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+ check_rand ();
+
+ tests_end ();
+
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-cmp.c b/gmp/tests/mpq/t-cmp.c
new file mode 100644
index 0000000000..5858fa23c2
--- /dev/null
+++ b/gmp/tests/mpq/t-cmp.c
@@ -0,0 +1,102 @@
+/* Test mpq_cmp.
+
+Copyright 1996, 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define SGN(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0)
+
+int
+ref_mpq_cmp (mpq_t a, mpq_t b)
+{
+ mpz_t ai, bi;
+ int cc;
+
+ mpz_init (ai);
+ mpz_init (bi);
+
+ mpz_mul (ai, NUM (a), DEN (b));
+ mpz_mul (bi, NUM (b), DEN (a));
+ cc = mpz_cmp (ai, bi);
+ mpz_clear (ai);
+ mpz_clear (bi);
+ return cc;
+}
+
+#ifndef SIZE
+#define SIZE 8 /* increasing this lowers the probability of finding an error */
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mpq_t a, b;
+ mp_size_t size;
+ int reps = 10000;
+ int i;
+ int cc, ccref;
+
+ tests_start ();
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpq_init (a);
+ mpq_init (b);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (NUM (a), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (DEN (a), size);
+ }
+ while (mpz_cmp_ui (DEN (a), 0) == 0);
+
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (NUM (b), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (DEN (b), size);
+ }
+ while (mpz_cmp_ui (DEN (b), 0) == 0);
+
+ mpq_canonicalize (a);
+ mpq_canonicalize (b);
+
+ ccref = ref_mpq_cmp (a, b);
+ cc = mpq_cmp (a, b);
+
+ if (SGN (ccref) != SGN (cc))
+ abort ();
+ }
+
+ mpq_clear (a);
+ mpq_clear (b);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-cmp_si.c b/gmp/tests/mpq/t-cmp_si.c
new file mode 100644
index 0000000000..15252cc7cc
--- /dev/null
+++ b/gmp/tests/mpq/t-cmp_si.c
@@ -0,0 +1,118 @@
+/* Test mpq_cmp_si.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#define SGN(x) ((x)<0 ? -1 : (x) != 0)
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *q;
+ long n;
+ unsigned long d;
+ int want;
+ } data[] = {
+ { "0", 0, 1, 0 },
+ { "0", 0, 123, 0 },
+ { "0", 0, ULONG_MAX, 0 },
+ { "1", 0, 1, 1 },
+ { "1", 0, 123, 1 },
+ { "1", 0, ULONG_MAX, 1 },
+ { "-1", 0, 1, -1 },
+ { "-1", 0, 123, -1 },
+ { "-1", 0, ULONG_MAX, -1 },
+
+ { "123", 123, 1, 0 },
+ { "124", 123, 1, 1 },
+ { "122", 123, 1, -1 },
+
+ { "-123", 123, 1, -1 },
+ { "-124", 123, 1, -1 },
+ { "-122", 123, 1, -1 },
+
+ { "123", -123, 1, 1 },
+ { "124", -123, 1, 1 },
+ { "122", -123, 1, 1 },
+
+ { "-123", -123, 1, 0 },
+ { "-124", -123, 1, -1 },
+ { "-122", -123, 1, 1 },
+
+ { "5/7", 3,4, -1 },
+ { "5/7", -3,4, 1 },
+ { "-5/7", 3,4, -1 },
+ { "-5/7", -3,4, 1 },
+ };
+
+ mpq_t q;
+ int i, got;
+
+ mpq_init (q);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpq_set_str_or_abort (q, data[i].q, 0);
+ MPQ_CHECK_FORMAT (q);
+
+ got = mpq_cmp_si (q, data[i].n, data[i].d);
+ if (SGN(got) != data[i].want)
+ {
+ printf ("mpq_cmp_si wrong\n");
+ error:
+ mpq_trace (" q", q);
+ printf (" n=%ld\n", data[i].n);
+ printf (" d=%lu\n", data[i].d);
+ printf (" got=%d\n", got);
+ printf (" want=%d\n", data[i].want);
+ abort ();
+ }
+
+ if (data[i].n == 0)
+ {
+ got = mpq_cmp_si (q, 0L, data[i].d);
+ if (SGN(got) != data[i].want)
+ {
+ printf ("mpq_cmp_si wrong\n");
+ goto error;
+ }
+ }
+ }
+
+ mpq_clear (q);
+}
+
+int
+main (int argc, char **argv)
+{
+ tests_start ();
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-cmp_ui.c b/gmp/tests/mpq/t-cmp_ui.c
new file mode 100644
index 0000000000..9d2808393b
--- /dev/null
+++ b/gmp/tests/mpq/t-cmp_ui.c
@@ -0,0 +1,117 @@
+/* Test mpq_cmp_ui.
+
+Copyright 1996, 1997, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define SGN(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0)
+
+int
+ref_mpq_cmp_ui (mpq_t a, unsigned long int bn, unsigned long int bd)
+{
+ mpz_t ai, bi;
+ int cc;
+
+ mpz_init (ai);
+ mpz_init (bi);
+
+ mpz_mul_ui (ai, NUM (a), bd);
+ mpz_mul_ui (bi, DEN (a), bn);
+ cc = mpz_cmp (ai, bi);
+ mpz_clear (ai);
+ mpz_clear (bi);
+ return cc;
+}
+
+#ifndef SIZE
+#define SIZE 8 /* increasing this lowers the probability of finding an error */
+#endif
+
+int
+main (int argc, char **argv)
+{
+ mpq_t a, b;
+ mp_size_t size;
+ int reps = 10000;
+ int i;
+ int cc, ccref;
+ unsigned long int bn, bd;
+
+ tests_start ();
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpq_init (a);
+ mpq_init (b);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (NUM (a), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (DEN (a), size);
+ }
+ while (mpz_cmp_ui (DEN (a), 0) == 0);
+
+ mpz_random2 (NUM (b), (mp_size_t) 1);
+ mpz_mod_ui (NUM (b), NUM (b), ~(unsigned long int) 0);
+ mpz_add_ui (NUM (b), NUM (b), 1);
+
+ mpz_random2 (DEN (b), (mp_size_t) 1);
+ mpz_mod_ui (DEN (b), DEN (b), ~(unsigned long int) 0);
+ mpz_add_ui (DEN (b), DEN (b), 1);
+
+ mpq_canonicalize (a);
+ mpq_canonicalize (b);
+
+ ccref = ref_mpq_cmp_ui (a, 1, 1);
+ cc = mpq_cmp_ui (a, 1, 1);
+
+ if (SGN (ccref) != SGN (cc))
+ abort ();
+
+ ccref = ref_mpq_cmp_ui (a, 0, 1);
+ cc = mpq_cmp_ui (a, 0, 1);
+
+ if (SGN (ccref) != SGN (cc))
+ abort ();
+
+ bn = mpz_get_ui (NUM (b));
+ bd = mpz_get_ui (DEN (b));
+
+ ccref = ref_mpq_cmp_ui (a, bn, bd);
+ cc = mpq_cmp_ui (a, bn, bd);
+
+ if (SGN (ccref) != SGN (cc))
+ abort ();
+ }
+
+ mpq_clear (a);
+ mpq_clear (b);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-equal.c b/gmp/tests/mpq/t-equal.c
new file mode 100644
index 0000000000..4523dd8b1e
--- /dev/null
+++ b/gmp/tests/mpq/t-equal.c
@@ -0,0 +1,147 @@
+/* Test mpq_equal.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpq_srcptr x, mpq_srcptr y, int want)
+{
+ int got;
+
+ MPQ_CHECK_FORMAT (x);
+ MPQ_CHECK_FORMAT (y);
+
+ got = mpq_equal (x, y);
+ if ((got != 0) != (want != 0))
+ {
+ printf ("mpq_equal got %d want %d\n", got, want);
+ mpq_trace ("x", x);
+ mpq_trace ("y", y);
+ abort ();
+ }
+}
+
+
+void
+check_all (mpq_ptr x, mpq_ptr y, int want)
+{
+ check_one (x, y, want);
+ check_one (y, x, want);
+
+ mpq_neg (x, x);
+ mpq_neg (y, y);
+
+ check_one (x, y, want);
+ check_one (y, x, want);
+}
+
+
+#define SET4Z(z, size,l3,l2,l1,l0) \
+ SIZ(z) = size; PTR(z)[3] = l3; PTR(z)[2] = l2; PTR(z)[1] = l1; PTR(z)[0] = l0
+
+#define SET4(q, nsize,n3,n2,n1,n0, dsize,d3,d2,d1,d0) \
+ SET4Z (mpq_numref(q), nsize,n3,n2,n1,n0); \
+ SET4Z (mpq_denref(q), dsize,d3,d2,d1,d0)
+
+
+/* Exercise various combinations of same and slightly different values. */
+
+void
+check_various (void)
+{
+ mpq_t x, y;
+
+ mpq_init (x);
+ mpq_init (y);
+
+ mpz_realloc (mpq_numref(x), (mp_size_t) 20);
+ mpz_realloc (mpq_denref(x), (mp_size_t) 20);
+ mpz_realloc (mpq_numref(y), (mp_size_t) 20);
+ mpz_realloc (mpq_denref(y), (mp_size_t) 20);
+
+ /* 0 == 0 */
+ SET4 (x, 0,13,12,11,10, 1,23,22,21,1);
+ SET4 (y, 0,33,32,31,30, 1,43,42,41,1);
+ check_all (x, y, 1);
+
+ /* 83/99 == 83/99 */
+ SET4 (x, 1,13,12,11,83, 1,23,22,21,99);
+ SET4 (y, 1,33,32,31,83, 1,43,42,41,99);
+ check_all (x, y, 1);
+
+ /* 1:2:3:4/5:6:7 == 1:2:3:4/5:6:7 */
+ SET4 (x, 4,1,2,3,4, 3,88,5,6,7);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 1);
+
+ /* various individual changes making != */
+ SET4 (x, 4,1,2,3,667, 3,88,5,6,7);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 0);
+ SET4 (x, 4,1,2,666,4, 3,88,5,6,7);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 0);
+ SET4 (x, 4,1,666,3,4, 3,88,5,6,7);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 0);
+#if GMP_NUMB_BITS != 62
+ SET4 (x, 4,667,2,3,4, 3,88,5,6,7);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 0);
+#endif
+ SET4 (x, 4,1,2,3,4, 3,88,5,6,667);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 0);
+ SET4 (x, 4,1,2,3,4, 3,88,5,667,7);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 0);
+ SET4 (x, 4,1,2,3,4, 3,88,666,6,7);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 0);
+ SET4 (x, -4,1,2,3,4, 3,88,5,6,7);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 0);
+ SET4 (x, 1,1,2,3,4, 3,88,5,6,7);
+ SET4 (y, 4,1,2,3,4, 3,99,5,6,7);
+ check_all (x, y, 0);
+ SET4 (x, 4,1,2,3,4, 3,88,5,6,7);
+ SET4 (y, 4,1,2,3,4, 2,99,5,6,7);
+ check_all (x, y, 0);
+
+ mpq_clear (x);
+ mpq_clear (y);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_various ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-get_d.c b/gmp/tests/mpq/t-get_d.c
new file mode 100644
index 0000000000..aa848e029c
--- /dev/null
+++ b/gmp/tests/mpq/t-get_d.c
@@ -0,0 +1,295 @@
+/* Test mpq_get_d and mpq_set_d
+
+Copyright 1991, 1993, 1994, 1996, 2000-2003, 2012, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+/* VAX D floats only have an 8 bit signed exponent, so anything 2^128 or
+ bigger will overflow, that being 4 limbs. */
+#if defined (__vax) || defined (__vax__) && SIZE > 4
+#undef SIZE
+#define SIZE 4
+#define EPSIZE 3
+#else
+#define EPSIZE SIZE
+#endif
+
+void dump (mpq_t);
+
+void
+check_monotonic (int argc, char **argv)
+{
+ mpq_t a;
+ mp_size_t size;
+ int reps = 100;
+ int i, j;
+ double last_d, new_d;
+ mpq_t qlast_d, qnew_d;
+ mpq_t eps;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ /* The idea here is to test the monotonousness of mpq_get_d by adding
+ numbers to the numerator and denominator. */
+
+ mpq_init (a);
+ mpq_init (eps);
+ mpq_init (qlast_d);
+ mpq_init (qnew_d);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (mpq_numref (a), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (mpq_denref (a), size);
+ }
+ while (mpz_cmp_ui (mpq_denref (a), 0) == 0);
+
+ mpq_canonicalize (a);
+
+ last_d = mpq_get_d (a);
+ mpq_set_d (qlast_d, last_d);
+ for (j = 0; j < 10; j++)
+ {
+ size = urandom () % EPSIZE + 1;
+ mpz_random2 (mpq_numref (eps), size);
+ size = urandom () % EPSIZE + 1;
+ mpz_random2 (mpq_denref (eps), size);
+ mpq_canonicalize (eps);
+
+ mpq_add (a, a, eps);
+ mpq_canonicalize (a);
+ new_d = mpq_get_d (a);
+ if (last_d > new_d)
+ {
+ printf ("\nERROR (test %d/%d): bad mpq_get_d results\n", i, j);
+ printf ("last: %.16g\n", last_d);
+ printf (" new: %.16g\n", new_d); dump (a);
+ abort ();
+ }
+ mpq_set_d (qnew_d, new_d);
+ MPQ_CHECK_FORMAT (qnew_d);
+ if (mpq_cmp (qlast_d, qnew_d) > 0)
+ {
+ printf ("ERROR (test %d/%d): bad mpq_set_d results\n", i, j);
+ printf ("last: %.16g\n", last_d); dump (qlast_d);
+ printf (" new: %.16g\n", new_d); dump (qnew_d);
+ abort ();
+ }
+ last_d = new_d;
+ mpq_set (qlast_d, qnew_d);
+ }
+ }
+
+ mpq_clear (a);
+ mpq_clear (eps);
+ mpq_clear (qlast_d);
+ mpq_clear (qnew_d);
+}
+
+double
+my_ldexp (double d, int e)
+{
+ for (;;)
+ {
+ if (e > 0)
+ {
+ if (e >= 16)
+ {
+ d *= 65536.0;
+ e -= 16;
+ }
+ else
+ {
+ d *= 2.0;
+ e -= 1;
+ }
+ }
+ else if (e < 0)
+ {
+
+ if (e <= -16)
+ {
+ d /= 65536.0;
+ e += 16;
+ }
+ else
+ {
+ d /= 2.0;
+ e += 1;
+ }
+ }
+ else
+ return d;
+ }
+}
+
+#define MAXEXP 500
+
+#if defined (__vax) || defined (__vax__)
+#undef MAXEXP
+#define MAXEXP 30
+#endif
+
+void
+check_random (int argc, char **argv)
+{
+ gmp_randstate_ptr rands = RANDS;
+
+ double d;
+ mpq_t q;
+ mpz_t a, t;
+ int exp;
+
+ int test, reps = 100000;
+
+ if (argc == 2)
+ reps = 100 * atoi (argv[1]);
+
+ mpq_init (q);
+ mpz_init (a);
+ mpz_init (t);
+
+ for (test = 0; test < reps; test++)
+ {
+ mpz_rrandomb (a, rands, 53);
+ mpz_urandomb (t, rands, 32);
+ exp = mpz_get_ui (t) % (2*MAXEXP) - MAXEXP;
+
+ d = my_ldexp (mpz_get_d (a), exp);
+ mpq_set_d (q, d);
+ /* Check that n/d = a * 2^exp, or
+ d*a 2^{exp} = n */
+ mpz_mul (t, a, mpq_denref (q));
+ if (exp > 0)
+ mpz_mul_2exp (t, t, exp);
+ else
+ {
+ if (!mpz_divisible_2exp_p (t, -exp))
+ goto fail;
+ mpz_div_2exp (t, t, -exp);
+ }
+ if (mpz_cmp (t, mpq_numref (q)) != 0)
+ {
+ fail:
+ printf ("ERROR (check_random test %d): bad mpq_set_d results\n", test);
+ printf ("%.16g\n", d);
+ gmp_printf ("%Qd\n", q);
+ abort ();
+ }
+ }
+ mpq_clear (q);
+ mpz_clear (t);
+ mpz_clear (a);
+}
+
+void
+dump (mpq_t x)
+{
+ mpz_out_str (stdout, 10, mpq_numref (x));
+ printf ("/");
+ mpz_out_str (stdout, 10, mpq_denref (x));
+ printf ("\n");
+}
+
+/* Check various values 2^n and 1/2^n. */
+void
+check_onebit (void)
+{
+ static const long data[] = {
+ -3*GMP_NUMB_BITS-1, -3*GMP_NUMB_BITS, -3*GMP_NUMB_BITS+1,
+ -2*GMP_NUMB_BITS-1, -2*GMP_NUMB_BITS, -2*GMP_NUMB_BITS+1,
+ -GMP_NUMB_BITS-1, -GMP_NUMB_BITS, -GMP_NUMB_BITS+1,
+ -5, -2, -1, 0, 1, 2, 5,
+ GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1,
+ 2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1,
+ 3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1,
+ };
+
+ int i, neg;
+ long exp, l;
+ mpq_t q;
+ double got, want;
+
+ mpq_init (q);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ exp = data[i];
+
+ mpq_set_ui (q, 1L, 1L);
+ if (exp >= 0)
+ mpq_mul_2exp (q, q, exp);
+ else
+ mpq_div_2exp (q, q, -exp);
+
+ want = 1.0;
+ for (l = 0; l < exp; l++)
+ want *= 2.0;
+ for (l = 0; l > exp; l--)
+ want /= 2.0;
+
+ for (neg = 0; neg <= 1; neg++)
+ {
+ if (neg)
+ {
+ mpq_neg (q, q);
+ want = -want;
+ }
+
+ got = mpq_get_d (q);
+
+ if (got != want)
+ {
+ printf ("mpq_get_d wrong on %s2**%ld\n", neg ? "-" : "", exp);
+ mpq_trace (" q ", q);
+ d_trace (" want ", want);
+ d_trace (" got ", got);
+ abort();
+ }
+ }
+ }
+ mpq_clear (q);
+}
+
+int
+main (int argc, char **argv)
+{
+ tests_start ();
+
+ check_onebit ();
+ check_monotonic (argc, argv);
+ check_random (argc, argv);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-get_str.c b/gmp/tests/mpq/t-get_str.c
new file mode 100644
index 0000000000..c3c9dd6e91
--- /dev/null
+++ b/gmp/tests/mpq/t-get_str.c
@@ -0,0 +1,143 @@
+/* Test mpq_get_str.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpq_srcptr q, int base, const char *want)
+{
+ char *str, *ret;
+ size_t str_alloc;
+
+ MPQ_CHECK_FORMAT (q);
+ mp_trace_base = base;
+
+ str_alloc =
+ mpz_sizeinbase (mpq_numref(q), ABS(base)) +
+ mpz_sizeinbase (mpq_denref(q), ABS(base)) + 3;
+
+ str = mpq_get_str (NULL, base, q);
+ if (strlen(str)+1 > str_alloc)
+ {
+ printf ("mpq_get_str size bigger than should be (passing NULL)\n");
+ printf (" base %d\n", base);
+ printf (" got size %lu \"%s\"\n", (unsigned long) strlen(str)+1, str);
+ printf (" want size %lu\n", (unsigned long) str_alloc);
+ abort ();
+ }
+ if (strcmp (str, want) != 0)
+ {
+ printf ("mpq_get_str wrong (passing NULL)\n");
+ printf (" base %d\n", base);
+ printf (" got \"%s\"\n", str);
+ printf (" want \"%s\"\n", want);
+ mpq_trace (" q", q);
+ abort ();
+ }
+ (*__gmp_free_func) (str, strlen (str) + 1);
+
+ str = (char *) (*__gmp_allocate_func) (str_alloc);
+
+ ret = mpq_get_str (str, base, q);
+ if (str != ret)
+ {
+ printf ("mpq_get_str wrong return value (passing non-NULL)\n");
+ printf (" base %d\n", base);
+ printf (" got %p\n", ret);
+ printf (" want %p\n", want);
+ abort ();
+ }
+ if (strcmp (str, want) != 0)
+ {
+ printf ("mpq_get_str wrong (passing non-NULL)\n");
+ printf (" base %d\n", base);
+ printf (" got \"%s\"\n", str);
+ printf (" want \"%s\"\n", want);
+ abort ();
+ }
+ (*__gmp_free_func) (str, str_alloc);
+}
+
+
+void
+check_all (mpq_srcptr q, int base, const char *want)
+{
+ char *s;
+
+ check_one (q, base, want);
+
+ s = __gmp_allocate_strdup (want);
+ strtoupper (s);
+ check_one (q, -base, s);
+ (*__gmp_free_func) (s, strlen(s)+1);
+}
+
+void
+check_data (void)
+{
+ static const struct {
+ int base;
+ const char *num;
+ const char *den;
+ const char *want;
+ } data[] = {
+ { 10, "0", "1", "0" },
+ { 10, "1", "1", "1" },
+
+ { 16, "ffffffff", "1", "ffffffff" },
+ { 16, "ffffffffffffffff", "1", "ffffffffffffffff" },
+
+ { 16, "1", "ffffffff", "1/ffffffff" },
+ { 16, "1", "ffffffffffffffff", "1/ffffffffffffffff" },
+ { 16, "1", "10000000000000003", "1/10000000000000003" },
+
+ { 10, "12345678901234567890", "9876543210987654323",
+ "12345678901234567890/9876543210987654323" },
+ };
+
+ mpq_t q;
+ int i;
+
+ mpq_init (q);
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (mpq_numref(q), data[i].num, data[i].base);
+ mpz_set_str_or_abort (mpq_denref(q), data[i].den, data[i].base);
+ check_all (q, data[i].base, data[i].want);
+ }
+ mpq_clear (q);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-inp_str.c b/gmp/tests/mpq/t-inp_str.c
new file mode 100644
index 0000000000..601cee3729
--- /dev/null
+++ b/gmp/tests/mpq/t-inp_str.c
@@ -0,0 +1,172 @@
+/* Test mpq_inp_str.
+
+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 "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for unlink */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#define FILENAME "t-inp_str.tmp"
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *inp;
+ int base;
+ const char *want;
+ int want_nread;
+
+ } data[] = {
+
+ { "0", 10, "0", 1 },
+ { "0/1", 10, "0", 3 },
+
+ { "0/", 10, "0", 0 },
+ { "/123", 10, "0", 0 },
+ { "blah", 10, "0", 0 },
+ { "123/blah", 10, "0", 0 },
+ { "5 /8", 10, "5", 1 },
+ { "5/ 8", 10, "0", 0 },
+
+ { "ff", 16, "255", 2 },
+ { "-ff", 16, "-255", 3 },
+ { "FF", 16, "255", 2 },
+ { "-FF", 16, "-255", 3 },
+
+ { "z", 36, "35", 1 },
+ { "Z", 36, "35", 1 },
+
+ { "0x0", 0, "0", 3 },
+ { "0x10", 0, "16", 4 },
+ { "-0x0", 0, "0", 4 },
+ { "-0x10", 0, "-16", 5 },
+ { "-0x10/5", 0, "-16/5", 7 },
+
+ { "00", 0, "0", 2 },
+ { "010", 0, "8", 3 },
+ { "-00", 0, "0", 3 },
+ { "-010", 0, "-8", 4 },
+ };
+
+ mpq_t got, want;
+ long ftell_nread;
+ int i, post, j, got_nread;
+ FILE *fp;
+
+ mpq_init (got);
+ mpq_init (want);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ for (post = 0; post <= 2; post++)
+ {
+ mpq_set_str_or_abort (want, data[i].want, 0);
+ MPQ_CHECK_FORMAT (want);
+
+ fp = fopen (FILENAME, "w+");
+ ASSERT_ALWAYS (fp != NULL);
+ fputs (data[i].inp, fp);
+ for (j = 0; j < post; j++)
+ putc (' ', fp);
+ fflush (fp);
+ ASSERT_ALWAYS (! ferror(fp));
+
+ rewind (fp);
+ got_nread = mpq_inp_str (got, fp, data[i].base);
+
+ if (got_nread != 0)
+ {
+ ftell_nread = ftell (fp);
+ if (got_nread != ftell_nread)
+ {
+ printf ("mpq_inp_str nread wrong\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ printf (" got_nread %d\n", got_nread);
+ printf (" ftell_nread %ld\n", ftell_nread);
+ abort ();
+ }
+ }
+
+ if (post == 0 && data[i].want_nread == strlen(data[i].inp))
+ {
+ int c = getc(fp);
+ if (c != EOF)
+ {
+ printf ("mpq_inp_str didn't read to EOF\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ printf (" c '%c' %#x\n", c, c);
+ abort ();
+ }
+ }
+
+ if (got_nread != data[i].want_nread)
+ {
+ printf ("mpq_inp_str nread wrong\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ printf (" got_nread %d\n", got_nread);
+ printf (" want_nread %d\n", data[i].want_nread);
+ abort ();
+ }
+
+ MPQ_CHECK_FORMAT (got);
+
+ if (! mpq_equal (got, want))
+ {
+ printf ("mpq_inp_str wrong result\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ mpq_trace (" got ", got);
+ mpq_trace (" want", want);
+ abort ();
+ }
+
+ ASSERT_ALWAYS (fclose (fp) == 0);
+ }
+ }
+
+ mpq_clear (got);
+ mpq_clear (want);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ unlink (FILENAME);
+ tests_end ();
+
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-inv.c b/gmp/tests/mpq/t-inv.c
new file mode 100644
index 0000000000..1a0df8d728
--- /dev/null
+++ b/gmp/tests/mpq/t-inv.c
@@ -0,0 +1,61 @@
+/* Test mpq_inv (and set/get_num/den).
+
+Copyright 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 "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+int
+main (int argc, char **argv)
+{
+ mpq_t a, b;
+ mpz_t m, n;
+ const char* s = "-420000000000000000000000";
+
+ tests_start ();
+
+ mpq_inits (a, b, (mpq_ptr)0);
+ mpz_inits (m, n, (mpz_ptr)0);
+
+ mpz_set_ui (m, 13);
+ mpq_set_den (a, m);
+ mpz_set_str (m, s, 0);
+ mpq_set_num (a, m);
+ MPQ_CHECK_FORMAT (a);
+ mpq_inv (b, a);
+ MPQ_CHECK_FORMAT (b);
+ mpq_get_num (n, b);
+ ASSERT_ALWAYS (mpz_cmp_si (n, -13) == 0);
+ mpq_neg (b, b);
+ mpq_inv (a, b);
+ MPQ_CHECK_FORMAT (a);
+ mpq_inv (b, b);
+ MPQ_CHECK_FORMAT (b);
+ mpq_get_den (n, b);
+ ASSERT_ALWAYS (mpz_cmp_ui (n, 13) == 0);
+ mpq_get_num (n, a);
+ mpz_add (n, n, m);
+ ASSERT_ALWAYS (mpz_sgn (n) == 0);
+
+ mpq_clears (a, b, (mpq_ptr)0);
+ mpz_clears (m, n, (mpz_ptr)0);
+
+ tests_end ();
+ return 0;
+}
diff --git a/gmp/tests/mpq/t-md_2exp.c b/gmp/tests/mpq/t-md_2exp.c
new file mode 100644
index 0000000000..c6e4028580
--- /dev/null
+++ b/gmp/tests/mpq/t-md_2exp.c
@@ -0,0 +1,245 @@
+/* Test mpq_mul_2exp and mpq_div_2exp.
+
+Copyright 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+struct pair_t {
+ const char *num;
+ const char *den;
+};
+
+void
+check_random ()
+{
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long arg_size, size_range;
+ mpq_t q, r;
+ int i;
+ mp_bitcnt_t shift;
+ int reps = 10000;
+
+ rands = RANDS;
+
+ mpz_init (bs);
+ mpq_init (q);
+ mpq_init (r);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 11 + 2; /* 0..4096 bit operands */
+
+ mpz_urandomb (bs, rands, size_range);
+ arg_size = mpz_get_ui (bs);
+ mpz_rrandomb (mpq_numref (q), rands, arg_size);
+ do
+ {
+ mpz_urandomb (bs, rands, size_range);
+ arg_size = mpz_get_ui (bs);
+ mpz_rrandomb (mpq_denref (q), rands, arg_size);
+ }
+ while (mpz_sgn (mpq_denref (q)) == 0);
+
+ /* We now have a random rational in q, albeit an unnormalised one. The
+ lack of normalisation should not matter here, so let's save the time a
+ gcd would require. */
+
+ mpz_urandomb (bs, rands, 32);
+ shift = mpz_get_ui (bs) % 4096;
+
+ mpq_mul_2exp (r, q, shift);
+
+ if (mpq_cmp (r, q) < 0)
+ {
+ printf ("mpq_mul_2exp wrong on random\n");
+ abort ();
+ }
+
+ mpq_div_2exp (r, r, shift);
+
+ if (mpq_cmp (r, q) != 0)
+ {
+ printf ("mpq_mul_2exp or mpq_div_2exp wrong on random\n");
+ abort ();
+ }
+ }
+ mpq_clear (q);
+ mpq_clear (r);
+ mpz_clear (bs);
+}
+
+int
+main (int argc, char **argv)
+{
+ static const struct {
+ struct pair_t left;
+ unsigned long n;
+ struct pair_t right;
+
+ } data[] = {
+ { {"0","1"}, 0, {"0","1"} },
+ { {"0","1"}, 1, {"0","1"} },
+ { {"0","1"}, 2, {"0","1"} },
+
+ { {"1","1"}, 0, {"1","1"} },
+ { {"1","1"}, 1, {"2","1"} },
+ { {"1","1"}, 2, {"4","1"} },
+ { {"1","1"}, 3, {"8","1"} },
+
+ { {"1","1"}, 31, {"0x80000000","1"} },
+ { {"1","1"}, 32, {"0x100000000","1"} },
+ { {"1","1"}, 33, {"0x200000000","1"} },
+ { {"1","1"}, 63, {"0x8000000000000000","1"} },
+ { {"1","1"}, 64, {"0x10000000000000000","1"} },
+ { {"1","1"}, 65, {"0x20000000000000000","1"} },
+ { {"1","1"}, 95, {"0x800000000000000000000000","1"} },
+ { {"1","1"}, 96, {"0x1000000000000000000000000","1"} },
+ { {"1","1"}, 97, {"0x2000000000000000000000000","1"} },
+ { {"1","1"}, 127, {"0x80000000000000000000000000000000","1"} },
+ { {"1","1"}, 128, {"0x100000000000000000000000000000000","1"} },
+ { {"1","1"}, 129, {"0x200000000000000000000000000000000","1"} },
+
+ { {"1","2"}, 31, {"0x40000000","1"} },
+ { {"1","2"}, 32, {"0x80000000","1"} },
+ { {"1","2"}, 33, {"0x100000000","1"} },
+ { {"1","2"}, 63, {"0x4000000000000000","1"} },
+ { {"1","2"}, 64, {"0x8000000000000000","1"} },
+ { {"1","2"}, 65, {"0x10000000000000000","1"} },
+ { {"1","2"}, 95, {"0x400000000000000000000000","1"} },
+ { {"1","2"}, 96, {"0x800000000000000000000000","1"} },
+ { {"1","2"}, 97, {"0x1000000000000000000000000","1"} },
+ { {"1","2"}, 127, {"0x40000000000000000000000000000000","1"} },
+ { {"1","2"}, 128, {"0x80000000000000000000000000000000","1"} },
+ { {"1","2"}, 129, {"0x100000000000000000000000000000000","1"} },
+
+ { {"1","0x80000000"}, 30, {"1","2"} },
+ { {"1","0x80000000"}, 31, {"1","1"} },
+ { {"1","0x80000000"}, 32, {"2","1"} },
+ { {"1","0x80000000"}, 33, {"4","1"} },
+ { {"1","0x80000000"}, 62, {"0x80000000","1"} },
+ { {"1","0x80000000"}, 63, {"0x100000000","1"} },
+ { {"1","0x80000000"}, 64, {"0x200000000","1"} },
+ { {"1","0x80000000"}, 94, {"0x8000000000000000","1"} },
+ { {"1","0x80000000"}, 95, {"0x10000000000000000","1"} },
+ { {"1","0x80000000"}, 96, {"0x20000000000000000","1"} },
+ { {"1","0x80000000"}, 126, {"0x800000000000000000000000","1"} },
+ { {"1","0x80000000"}, 127, {"0x1000000000000000000000000","1"} },
+ { {"1","0x80000000"}, 128, {"0x2000000000000000000000000","1"} },
+
+ { {"1","0x100000000"}, 1, {"1","0x80000000"} },
+ { {"1","0x100000000"}, 2, {"1","0x40000000"} },
+ { {"1","0x100000000"}, 3, {"1","0x20000000"} },
+
+ { {"1","0x10000000000000000"}, 1, {"1","0x8000000000000000"} },
+ { {"1","0x10000000000000000"}, 2, {"1","0x4000000000000000"} },
+ { {"1","0x10000000000000000"}, 3, {"1","0x2000000000000000"} },
+ };
+
+ void (*fun) (mpq_ptr, mpq_srcptr, unsigned long);
+ const struct pair_t *p_start, *p_want;
+ const char *name;
+ mpq_t sep, got, want;
+ mpq_ptr q;
+ int i, muldiv, sign, overlap;
+
+ tests_start ();
+
+ mpq_init (sep);
+ mpq_init (got);
+ mpq_init (want);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ for (muldiv = 0; muldiv < 2; muldiv++)
+ {
+ if (muldiv == 0)
+ {
+ fun = mpq_mul_2exp;
+ name = "mpq_mul_2exp";
+ p_start = &data[i].left;
+ p_want = &data[i].right;
+ }
+ else
+ {
+ fun = mpq_div_2exp;
+ name = "mpq_div_2exp";
+ p_start = &data[i].right;
+ p_want = &data[i].left;
+ }
+
+ for (sign = 0; sign <= 1; sign++)
+ {
+ mpz_set_str_or_abort (mpq_numref(want), p_want->num, 0);
+ mpz_set_str_or_abort (mpq_denref(want), p_want->den, 0);
+ if (sign)
+ mpq_neg (want, want);
+
+ for (overlap = 0; overlap <= 1; overlap++)
+ {
+ q = overlap ? got : sep;
+
+ /* initial garbage in "got" */
+ mpq_set_ui (got, 123L, 456L);
+
+ mpz_set_str_or_abort (mpq_numref(q), p_start->num, 0);
+ mpz_set_str_or_abort (mpq_denref(q), p_start->den, 0);
+ if (sign)
+ mpq_neg (q, q);
+
+ (*fun) (got, q, data[i].n);
+ MPQ_CHECK_FORMAT (got);
+
+ if (! mpq_equal (got, want))
+ {
+ printf ("%s wrong at data[%d], sign %d, overlap %d\n",
+ name, i, sign, overlap);
+ printf (" num \"%s\"\n", p_start->num);
+ printf (" den \"%s\"\n", p_start->den);
+ printf (" n %lu\n", data[i].n);
+
+ printf (" got ");
+ mpq_out_str (stdout, 16, got);
+ printf (" (hex)\n");
+
+ printf (" want ");
+ mpq_out_str (stdout, 16, want);
+ printf (" (hex)\n");
+
+ abort ();
+ }
+ }
+ }
+ }
+ }
+
+ check_random ();
+
+ mpq_clear (sep);
+ mpq_clear (got);
+ mpq_clear (want);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-set_f.c b/gmp/tests/mpq/t-set_f.c
new file mode 100644
index 0000000000..76f4a68df8
--- /dev/null
+++ b/gmp/tests/mpq/t-set_f.c
@@ -0,0 +1,170 @@
+/* Test mpq_set_f.
+
+Copyright 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+int
+main (int argc, char **argv)
+{
+#if GMP_NAIL_BITS == 0
+ static const struct {
+ int f_base;
+ const char *f;
+ int z_base;
+ const char *want_num;
+ const char *want_den;
+
+ } data[] = {
+
+ { -2, "0", 16, "0", "1" },
+ { -2, "1", 16, "1", "1" },
+ { -2, "1@1", 16, "2", "1" },
+ { -2, "1@2", 16, "4", "1" },
+ { -2, "1@3", 16, "8", "1" },
+
+ { -2, "1@30", 16, "40000000", "1" },
+ { -2, "1@31", 16, "80000000", "1" },
+ { -2, "1@32", 16, "100000000", "1" },
+ { -2, "1@33", 16, "200000000", "1" },
+ { -2, "1@34", 16, "400000000", "1" },
+
+ { -2, "1@62", 16, "4000000000000000", "1" },
+ { -2, "1@63", 16, "8000000000000000", "1" },
+ { -2, "1@64", 16, "10000000000000000", "1" },
+ { -2, "1@65", 16, "20000000000000000", "1" },
+ { -2, "1@66", 16, "40000000000000000", "1" },
+
+ { -2, "1@126", 16, "40000000000000000000000000000000", "1" },
+ { -2, "1@127", 16, "80000000000000000000000000000000", "1" },
+ { -2, "1@128", 16, "100000000000000000000000000000000", "1" },
+ { -2, "1@129", 16, "200000000000000000000000000000000", "1" },
+ { -2, "1@130", 16, "400000000000000000000000000000000", "1" },
+
+ { -2, "1@-1", 16, "1", "2" },
+ { -2, "1@-2", 16, "1", "4" },
+ { -2, "1@-3", 16, "1", "8" },
+
+ { -2, "1@-30", 16, "1", "40000000" },
+ { -2, "1@-31", 16, "1", "80000000" },
+ { -2, "1@-32", 16, "1", "100000000" },
+ { -2, "1@-33", 16, "1", "200000000" },
+ { -2, "1@-34", 16, "1", "400000000" },
+
+ { -2, "1@-62", 16, "1", "4000000000000000" },
+ { -2, "1@-63", 16, "1", "8000000000000000" },
+ { -2, "1@-64", 16, "1", "10000000000000000" },
+ { -2, "1@-65", 16, "1", "20000000000000000" },
+ { -2, "1@-66", 16, "1", "40000000000000000" },
+
+ { -2, "1@-126", 16, "1", "40000000000000000000000000000000" },
+ { -2, "1@-127", 16, "1", "80000000000000000000000000000000" },
+ { -2, "1@-128", 16, "1", "100000000000000000000000000000000" },
+ { -2, "1@-129", 16, "1", "200000000000000000000000000000000" },
+ { -2, "1@-130", 16, "1", "400000000000000000000000000000000" },
+
+ { -2, "1@-30", 16, "1", "40000000" },
+ { -2, "1@-31", 16, "1", "80000000" },
+ { -2, "1@-32", 16, "1", "100000000" },
+ { -2, "1@-33", 16, "1", "200000000" },
+ { -2, "1@-34", 16, "1", "400000000" },
+
+ { -2, "11@-62", 16, "3", "4000000000000000" },
+ { -2, "11@-63", 16, "3", "8000000000000000" },
+ { -2, "11@-64", 16, "3", "10000000000000000" },
+ { -2, "11@-65", 16, "3", "20000000000000000" },
+ { -2, "11@-66", 16, "3", "40000000000000000" },
+
+ { 16, "80000000.00000001", 16, "8000000000000001", "100000000" },
+ { 16, "80000000.00000008", 16, "1000000000000001", "20000000" },
+ { 16, "80000000.8", 16, "100000001", "2" },
+
+ };
+
+ mpf_t f;
+ mpq_t got;
+ mpz_t want_num, want_den;
+ int i, neg;
+
+ tests_start ();
+
+ mpf_init2 (f, 1024L);
+ mpq_init (got);
+ mpz_init (want_num);
+ mpz_init (want_den);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ for (neg = 0; neg <= 1; neg++)
+ {
+ mpf_set_str_or_abort (f, data[i].f, data[i].f_base);
+ mpz_set_str_or_abort (want_num, data[i].want_num, data[i].z_base);
+ mpz_set_str_or_abort (want_den, data[i].want_den, data[i].z_base);
+
+ if (neg)
+ {
+ mpf_neg (f, f);
+ mpz_neg (want_num, want_num);
+ }
+
+ mpq_set_f (got, f);
+ MPQ_CHECK_FORMAT (got);
+
+ if (mpz_cmp (mpq_numref(got), want_num) != 0
+ || mpz_cmp (mpq_denref(got), want_den) != 0)
+ {
+ printf ("wrong at data[%d]\n", i);
+ printf (" f_base %d, z_base %d\n",
+ data[i].f_base, data[i].z_base);
+
+ printf (" f \"%s\" hex ", data[i].f);
+ mpf_out_str (stdout, 16, 0, f);
+ printf ("\n");
+
+ printf (" want num 0x");
+ mpz_out_str (stdout, 16, want_num);
+ printf ("\n");
+ printf (" want den 0x");
+ mpz_out_str (stdout, 16, want_den);
+ printf ("\n");
+
+ printf (" got num 0x");
+ mpz_out_str (stdout, 16, mpq_numref(got));
+ printf ("\n");
+ printf (" got den 0x");
+ mpz_out_str (stdout, 16, mpq_denref(got));
+ printf ("\n");
+
+ abort ();
+ }
+ }
+ }
+
+ mpf_clear (f);
+ mpq_clear (got);
+ mpz_clear (want_num);
+ mpz_clear (want_den);
+
+ tests_end ();
+#endif
+ exit (0);
+}
diff --git a/gmp/tests/mpq/t-set_str.c b/gmp/tests/mpq/t-set_str.c
new file mode 100644
index 0000000000..92cb9205a7
--- /dev/null
+++ b/gmp/tests/mpq/t-set_str.c
@@ -0,0 +1,103 @@
+/* Test mpq_set_str.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpq_srcptr want, int base, const char *str)
+{
+ mpq_t got;
+
+ MPQ_CHECK_FORMAT (want);
+ mp_trace_base = base;
+
+ mpq_init (got);
+
+ if (mpq_set_str (got, str, base) != 0)
+ {
+ printf ("mpq_set_str unexpectedly failed\n");
+ printf (" base %d\n", base);
+ printf (" str \"%s\"\n", str);
+ abort ();
+ }
+ MPQ_CHECK_FORMAT (got);
+
+ if (! mpq_equal (got, want))
+ {
+ printf ("mpq_set_str wrong\n");
+ printf (" base %d\n", base);
+ printf (" str \"%s\"\n", str);
+ mpq_trace ("got ", got);
+ mpq_trace ("want", want);
+ abort ();
+ }
+
+ mpq_clear (got);
+}
+
+void
+check_samples (void)
+{
+ mpq_t q;
+
+ mpq_init (q);
+
+ mpq_set_ui (q, 0L, 1L);
+ check_one (q, 10, "0");
+ check_one (q, 10, "0/1");
+ check_one (q, 10, "0 / 1");
+ check_one (q, 0, "0x0/ 1");
+ check_one (q, 0, "0x0/ 0x1");
+ check_one (q, 0, "0 / 0x1");
+
+ check_one (q, 10, "-0");
+ check_one (q, 10, "-0/1");
+ check_one (q, 10, "-0 / 1");
+ check_one (q, 0, "-0x0/ 1");
+ check_one (q, 0, "-0x0/ 0x1");
+ check_one (q, 0, "-0 / 0x1");
+
+ mpq_set_ui (q, 255L, 256L);
+ check_one (q, 10, "255/256");
+ check_one (q, 0, "0xFF/0x100");
+ check_one (q, 16, "FF/100");
+
+ mpq_neg (q, q);
+ check_one (q, 10, "-255/256");
+ check_one (q, 0, "-0xFF/0x100");
+ check_one (q, 16, "-FF/100");
+
+ mpq_clear (q);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_samples ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/Makefile.am b/gmp/tests/mpz/Makefile.am
new file mode 100644
index 0000000000..8dc5721e0a
--- /dev/null
+++ b/gmp/tests/mpz/Makefile.am
@@ -0,0 +1,42 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 1996, 1997, 1999-2003, 2009, 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/.
+
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+
+check_PROGRAMS = t-addsub t-cmp t-mul t-mul_i t-tdiv t-tdiv_ui t-fdiv \
+ t-fdiv_ui t-cdiv_ui t-gcd t-gcd_ui t-lcm t-invert dive dive_ui t-sqrtrem \
+ convert io t-inp_str logic bit t-powm t-powm_ui t-pow t-div_2exp reuse \
+ t-root t-perfsqr t-perfpow t-jac t-bin t-get_d t-get_d_2exp t-get_si \
+ t-set_d t-set_si \
+ t-fac_ui t-mfac_uiui t-primorial_ui t-fib_ui t-lucnum_ui t-scan t-fits \
+ t-divis t-divis_2exp t-cong t-cong_2exp t-sizeinbase t-set_str \
+ t-aorsmul t-cmp_d t-cmp_si t-hamdist t-oddeven t-popcount t-set_f \
+ t-io_raw t-import t-export t-pprime_p t-nextprime t-remove t-limbs
+
+TESTS = $(check_PROGRAMS)
+
+# Temporary files used by the tests. Removed automatically if the tests
+# pass, but ensure they're cleaned if they fail.
+#
+CLEANFILES = *.tmp
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
diff --git a/gmp/tests/mpz/Makefile.in b/gmp/tests/mpz/Makefile.in
new file mode 100644
index 0000000000..ec96613ff3
--- /dev/null
+++ b/gmp/tests/mpz/Makefile.in
@@ -0,0 +1,1187 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 1996, 1997, 1999-2003, 2009, 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/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+check_PROGRAMS = t-addsub$(EXEEXT) t-cmp$(EXEEXT) t-mul$(EXEEXT) \
+ t-mul_i$(EXEEXT) t-tdiv$(EXEEXT) t-tdiv_ui$(EXEEXT) \
+ t-fdiv$(EXEEXT) t-fdiv_ui$(EXEEXT) t-cdiv_ui$(EXEEXT) \
+ t-gcd$(EXEEXT) t-gcd_ui$(EXEEXT) t-lcm$(EXEEXT) \
+ t-invert$(EXEEXT) dive$(EXEEXT) dive_ui$(EXEEXT) \
+ t-sqrtrem$(EXEEXT) convert$(EXEEXT) io$(EXEEXT) \
+ t-inp_str$(EXEEXT) logic$(EXEEXT) bit$(EXEEXT) t-powm$(EXEEXT) \
+ t-powm_ui$(EXEEXT) t-pow$(EXEEXT) t-div_2exp$(EXEEXT) \
+ reuse$(EXEEXT) t-root$(EXEEXT) t-perfsqr$(EXEEXT) \
+ t-perfpow$(EXEEXT) t-jac$(EXEEXT) t-bin$(EXEEXT) \
+ t-get_d$(EXEEXT) t-get_d_2exp$(EXEEXT) t-get_si$(EXEEXT) \
+ t-set_d$(EXEEXT) t-set_si$(EXEEXT) t-fac_ui$(EXEEXT) \
+ t-mfac_uiui$(EXEEXT) t-primorial_ui$(EXEEXT) t-fib_ui$(EXEEXT) \
+ t-lucnum_ui$(EXEEXT) t-scan$(EXEEXT) t-fits$(EXEEXT) \
+ t-divis$(EXEEXT) t-divis_2exp$(EXEEXT) t-cong$(EXEEXT) \
+ t-cong_2exp$(EXEEXT) t-sizeinbase$(EXEEXT) t-set_str$(EXEEXT) \
+ t-aorsmul$(EXEEXT) t-cmp_d$(EXEEXT) t-cmp_si$(EXEEXT) \
+ t-hamdist$(EXEEXT) t-oddeven$(EXEEXT) t-popcount$(EXEEXT) \
+ t-set_f$(EXEEXT) t-io_raw$(EXEEXT) t-import$(EXEEXT) \
+ t-export$(EXEEXT) t-pprime_p$(EXEEXT) t-nextprime$(EXEEXT) \
+ t-remove$(EXEEXT) t-limbs$(EXEEXT)
+subdir = tests/mpz
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+bit_SOURCES = bit.c
+bit_OBJECTS = bit.$(OBJEXT)
+bit_LDADD = $(LDADD)
+bit_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+convert_SOURCES = convert.c
+convert_OBJECTS = convert.$(OBJEXT)
+convert_LDADD = $(LDADD)
+convert_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+dive_SOURCES = dive.c
+dive_OBJECTS = dive.$(OBJEXT)
+dive_LDADD = $(LDADD)
+dive_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+dive_ui_SOURCES = dive_ui.c
+dive_ui_OBJECTS = dive_ui.$(OBJEXT)
+dive_ui_LDADD = $(LDADD)
+dive_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+io_SOURCES = io.c
+io_OBJECTS = io.$(OBJEXT)
+io_LDADD = $(LDADD)
+io_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+logic_SOURCES = logic.c
+logic_OBJECTS = logic.$(OBJEXT)
+logic_LDADD = $(LDADD)
+logic_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+reuse_SOURCES = reuse.c
+reuse_OBJECTS = reuse.$(OBJEXT)
+reuse_LDADD = $(LDADD)
+reuse_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_addsub_SOURCES = t-addsub.c
+t_addsub_OBJECTS = t-addsub.$(OBJEXT)
+t_addsub_LDADD = $(LDADD)
+t_addsub_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_aorsmul_SOURCES = t-aorsmul.c
+t_aorsmul_OBJECTS = t-aorsmul.$(OBJEXT)
+t_aorsmul_LDADD = $(LDADD)
+t_aorsmul_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_bin_SOURCES = t-bin.c
+t_bin_OBJECTS = t-bin.$(OBJEXT)
+t_bin_LDADD = $(LDADD)
+t_bin_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cdiv_ui_SOURCES = t-cdiv_ui.c
+t_cdiv_ui_OBJECTS = t-cdiv_ui.$(OBJEXT)
+t_cdiv_ui_LDADD = $(LDADD)
+t_cdiv_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cmp_SOURCES = t-cmp.c
+t_cmp_OBJECTS = t-cmp.$(OBJEXT)
+t_cmp_LDADD = $(LDADD)
+t_cmp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cmp_d_SOURCES = t-cmp_d.c
+t_cmp_d_OBJECTS = t-cmp_d.$(OBJEXT)
+t_cmp_d_LDADD = $(LDADD)
+t_cmp_d_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cmp_si_SOURCES = t-cmp_si.c
+t_cmp_si_OBJECTS = t-cmp_si.$(OBJEXT)
+t_cmp_si_LDADD = $(LDADD)
+t_cmp_si_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cong_SOURCES = t-cong.c
+t_cong_OBJECTS = t-cong.$(OBJEXT)
+t_cong_LDADD = $(LDADD)
+t_cong_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_cong_2exp_SOURCES = t-cong_2exp.c
+t_cong_2exp_OBJECTS = t-cong_2exp.$(OBJEXT)
+t_cong_2exp_LDADD = $(LDADD)
+t_cong_2exp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_div_2exp_SOURCES = t-div_2exp.c
+t_div_2exp_OBJECTS = t-div_2exp.$(OBJEXT)
+t_div_2exp_LDADD = $(LDADD)
+t_div_2exp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_divis_SOURCES = t-divis.c
+t_divis_OBJECTS = t-divis.$(OBJEXT)
+t_divis_LDADD = $(LDADD)
+t_divis_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_divis_2exp_SOURCES = t-divis_2exp.c
+t_divis_2exp_OBJECTS = t-divis_2exp.$(OBJEXT)
+t_divis_2exp_LDADD = $(LDADD)
+t_divis_2exp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_export_SOURCES = t-export.c
+t_export_OBJECTS = t-export.$(OBJEXT)
+t_export_LDADD = $(LDADD)
+t_export_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_fac_ui_SOURCES = t-fac_ui.c
+t_fac_ui_OBJECTS = t-fac_ui.$(OBJEXT)
+t_fac_ui_LDADD = $(LDADD)
+t_fac_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_fdiv_SOURCES = t-fdiv.c
+t_fdiv_OBJECTS = t-fdiv.$(OBJEXT)
+t_fdiv_LDADD = $(LDADD)
+t_fdiv_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_fdiv_ui_SOURCES = t-fdiv_ui.c
+t_fdiv_ui_OBJECTS = t-fdiv_ui.$(OBJEXT)
+t_fdiv_ui_LDADD = $(LDADD)
+t_fdiv_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_fib_ui_SOURCES = t-fib_ui.c
+t_fib_ui_OBJECTS = t-fib_ui.$(OBJEXT)
+t_fib_ui_LDADD = $(LDADD)
+t_fib_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_fits_SOURCES = t-fits.c
+t_fits_OBJECTS = t-fits.$(OBJEXT)
+t_fits_LDADD = $(LDADD)
+t_fits_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_gcd_SOURCES = t-gcd.c
+t_gcd_OBJECTS = t-gcd.$(OBJEXT)
+t_gcd_LDADD = $(LDADD)
+t_gcd_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_gcd_ui_SOURCES = t-gcd_ui.c
+t_gcd_ui_OBJECTS = t-gcd_ui.$(OBJEXT)
+t_gcd_ui_LDADD = $(LDADD)
+t_gcd_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_d_SOURCES = t-get_d.c
+t_get_d_OBJECTS = t-get_d.$(OBJEXT)
+t_get_d_LDADD = $(LDADD)
+t_get_d_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_d_2exp_SOURCES = t-get_d_2exp.c
+t_get_d_2exp_OBJECTS = t-get_d_2exp.$(OBJEXT)
+t_get_d_2exp_LDADD = $(LDADD)
+t_get_d_2exp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_get_si_SOURCES = t-get_si.c
+t_get_si_OBJECTS = t-get_si.$(OBJEXT)
+t_get_si_LDADD = $(LDADD)
+t_get_si_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_hamdist_SOURCES = t-hamdist.c
+t_hamdist_OBJECTS = t-hamdist.$(OBJEXT)
+t_hamdist_LDADD = $(LDADD)
+t_hamdist_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_import_SOURCES = t-import.c
+t_import_OBJECTS = t-import.$(OBJEXT)
+t_import_LDADD = $(LDADD)
+t_import_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_inp_str_SOURCES = t-inp_str.c
+t_inp_str_OBJECTS = t-inp_str.$(OBJEXT)
+t_inp_str_LDADD = $(LDADD)
+t_inp_str_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_invert_SOURCES = t-invert.c
+t_invert_OBJECTS = t-invert.$(OBJEXT)
+t_invert_LDADD = $(LDADD)
+t_invert_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_io_raw_SOURCES = t-io_raw.c
+t_io_raw_OBJECTS = t-io_raw.$(OBJEXT)
+t_io_raw_LDADD = $(LDADD)
+t_io_raw_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_jac_SOURCES = t-jac.c
+t_jac_OBJECTS = t-jac.$(OBJEXT)
+t_jac_LDADD = $(LDADD)
+t_jac_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_lcm_SOURCES = t-lcm.c
+t_lcm_OBJECTS = t-lcm.$(OBJEXT)
+t_lcm_LDADD = $(LDADD)
+t_lcm_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_limbs_SOURCES = t-limbs.c
+t_limbs_OBJECTS = t-limbs.$(OBJEXT)
+t_limbs_LDADD = $(LDADD)
+t_limbs_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_lucnum_ui_SOURCES = t-lucnum_ui.c
+t_lucnum_ui_OBJECTS = t-lucnum_ui.$(OBJEXT)
+t_lucnum_ui_LDADD = $(LDADD)
+t_lucnum_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mfac_uiui_SOURCES = t-mfac_uiui.c
+t_mfac_uiui_OBJECTS = t-mfac_uiui.$(OBJEXT)
+t_mfac_uiui_LDADD = $(LDADD)
+t_mfac_uiui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mul_SOURCES = t-mul.c
+t_mul_OBJECTS = t-mul.$(OBJEXT)
+t_mul_LDADD = $(LDADD)
+t_mul_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mul_i_SOURCES = t-mul_i.c
+t_mul_i_OBJECTS = t-mul_i.$(OBJEXT)
+t_mul_i_LDADD = $(LDADD)
+t_mul_i_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_nextprime_SOURCES = t-nextprime.c
+t_nextprime_OBJECTS = t-nextprime.$(OBJEXT)
+t_nextprime_LDADD = $(LDADD)
+t_nextprime_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_oddeven_SOURCES = t-oddeven.c
+t_oddeven_OBJECTS = t-oddeven.$(OBJEXT)
+t_oddeven_LDADD = $(LDADD)
+t_oddeven_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_perfpow_SOURCES = t-perfpow.c
+t_perfpow_OBJECTS = t-perfpow.$(OBJEXT)
+t_perfpow_LDADD = $(LDADD)
+t_perfpow_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_perfsqr_SOURCES = t-perfsqr.c
+t_perfsqr_OBJECTS = t-perfsqr.$(OBJEXT)
+t_perfsqr_LDADD = $(LDADD)
+t_perfsqr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_popcount_SOURCES = t-popcount.c
+t_popcount_OBJECTS = t-popcount.$(OBJEXT)
+t_popcount_LDADD = $(LDADD)
+t_popcount_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_pow_SOURCES = t-pow.c
+t_pow_OBJECTS = t-pow.$(OBJEXT)
+t_pow_LDADD = $(LDADD)
+t_pow_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_powm_SOURCES = t-powm.c
+t_powm_OBJECTS = t-powm.$(OBJEXT)
+t_powm_LDADD = $(LDADD)
+t_powm_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_powm_ui_SOURCES = t-powm_ui.c
+t_powm_ui_OBJECTS = t-powm_ui.$(OBJEXT)
+t_powm_ui_LDADD = $(LDADD)
+t_powm_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_pprime_p_SOURCES = t-pprime_p.c
+t_pprime_p_OBJECTS = t-pprime_p.$(OBJEXT)
+t_pprime_p_LDADD = $(LDADD)
+t_pprime_p_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_primorial_ui_SOURCES = t-primorial_ui.c
+t_primorial_ui_OBJECTS = t-primorial_ui.$(OBJEXT)
+t_primorial_ui_LDADD = $(LDADD)
+t_primorial_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_remove_SOURCES = t-remove.c
+t_remove_OBJECTS = t-remove.$(OBJEXT)
+t_remove_LDADD = $(LDADD)
+t_remove_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_root_SOURCES = t-root.c
+t_root_OBJECTS = t-root.$(OBJEXT)
+t_root_LDADD = $(LDADD)
+t_root_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_scan_SOURCES = t-scan.c
+t_scan_OBJECTS = t-scan.$(OBJEXT)
+t_scan_LDADD = $(LDADD)
+t_scan_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_d_SOURCES = t-set_d.c
+t_set_d_OBJECTS = t-set_d.$(OBJEXT)
+t_set_d_LDADD = $(LDADD)
+t_set_d_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_f_SOURCES = t-set_f.c
+t_set_f_OBJECTS = t-set_f.$(OBJEXT)
+t_set_f_LDADD = $(LDADD)
+t_set_f_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_si_SOURCES = t-set_si.c
+t_set_si_OBJECTS = t-set_si.$(OBJEXT)
+t_set_si_LDADD = $(LDADD)
+t_set_si_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_set_str_SOURCES = t-set_str.c
+t_set_str_OBJECTS = t-set_str.$(OBJEXT)
+t_set_str_LDADD = $(LDADD)
+t_set_str_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_sizeinbase_SOURCES = t-sizeinbase.c
+t_sizeinbase_OBJECTS = t-sizeinbase.$(OBJEXT)
+t_sizeinbase_LDADD = $(LDADD)
+t_sizeinbase_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_sqrtrem_SOURCES = t-sqrtrem.c
+t_sqrtrem_OBJECTS = t-sqrtrem.$(OBJEXT)
+t_sqrtrem_LDADD = $(LDADD)
+t_sqrtrem_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_tdiv_SOURCES = t-tdiv.c
+t_tdiv_OBJECTS = t-tdiv.$(OBJEXT)
+t_tdiv_LDADD = $(LDADD)
+t_tdiv_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_tdiv_ui_SOURCES = t-tdiv_ui.c
+t_tdiv_ui_OBJECTS = t-tdiv_ui.$(OBJEXT)
+t_tdiv_ui_LDADD = $(LDADD)
+t_tdiv_ui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = bit.c convert.c dive.c dive_ui.c io.c logic.c reuse.c \
+ t-addsub.c t-aorsmul.c t-bin.c t-cdiv_ui.c t-cmp.c t-cmp_d.c \
+ t-cmp_si.c t-cong.c t-cong_2exp.c t-div_2exp.c t-divis.c \
+ t-divis_2exp.c t-export.c t-fac_ui.c t-fdiv.c t-fdiv_ui.c \
+ t-fib_ui.c t-fits.c t-gcd.c t-gcd_ui.c t-get_d.c \
+ t-get_d_2exp.c t-get_si.c t-hamdist.c t-import.c t-inp_str.c \
+ t-invert.c t-io_raw.c t-jac.c t-lcm.c t-limbs.c t-lucnum_ui.c \
+ t-mfac_uiui.c t-mul.c t-mul_i.c t-nextprime.c t-oddeven.c \
+ t-perfpow.c t-perfsqr.c t-popcount.c t-pow.c t-powm.c \
+ t-powm_ui.c t-pprime_p.c t-primorial_ui.c t-remove.c t-root.c \
+ t-scan.c t-set_d.c t-set_f.c t-set_si.c t-set_str.c \
+ t-sizeinbase.c t-sqrtrem.c t-tdiv.c t-tdiv_ui.c
+DIST_SOURCES = bit.c convert.c dive.c dive_ui.c io.c logic.c reuse.c \
+ t-addsub.c t-aorsmul.c t-bin.c t-cdiv_ui.c t-cmp.c t-cmp_d.c \
+ t-cmp_si.c t-cong.c t-cong_2exp.c t-div_2exp.c t-divis.c \
+ t-divis_2exp.c t-export.c t-fac_ui.c t-fdiv.c t-fdiv_ui.c \
+ t-fib_ui.c t-fits.c t-gcd.c t-gcd_ui.c t-get_d.c \
+ t-get_d_2exp.c t-get_si.c t-hamdist.c t-import.c t-inp_str.c \
+ t-invert.c t-io_raw.c t-jac.c t-lcm.c t-limbs.c t-lucnum_ui.c \
+ t-mfac_uiui.c t-mul.c t-mul_i.c t-nextprime.c t-oddeven.c \
+ t-perfpow.c t-perfsqr.c t-popcount.c t-pow.c t-powm.c \
+ t-powm_ui.c t-pprime_p.c t-primorial_ui.c t-remove.c t-root.c \
+ t-scan.c t-set_d.c t-set_f.c t-set_si.c t-set_str.c \
+ t-sizeinbase.c t-sqrtrem.c t-tdiv.c t-tdiv_ui.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+TESTS = $(check_PROGRAMS)
+
+# Temporary files used by the tests. Removed automatically if the tests
+# pass, but ensure they're cleaned if they fail.
+#
+CLEANFILES = *.tmp
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/mpz/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps tests/mpz/Makefile
+.PRECIOUS: 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
+bit$(EXEEXT): $(bit_OBJECTS) $(bit_DEPENDENCIES) $(EXTRA_bit_DEPENDENCIES)
+ @rm -f bit$(EXEEXT)
+ $(LINK) $(bit_OBJECTS) $(bit_LDADD) $(LIBS)
+convert$(EXEEXT): $(convert_OBJECTS) $(convert_DEPENDENCIES) $(EXTRA_convert_DEPENDENCIES)
+ @rm -f convert$(EXEEXT)
+ $(LINK) $(convert_OBJECTS) $(convert_LDADD) $(LIBS)
+dive$(EXEEXT): $(dive_OBJECTS) $(dive_DEPENDENCIES) $(EXTRA_dive_DEPENDENCIES)
+ @rm -f dive$(EXEEXT)
+ $(LINK) $(dive_OBJECTS) $(dive_LDADD) $(LIBS)
+dive_ui$(EXEEXT): $(dive_ui_OBJECTS) $(dive_ui_DEPENDENCIES) $(EXTRA_dive_ui_DEPENDENCIES)
+ @rm -f dive_ui$(EXEEXT)
+ $(LINK) $(dive_ui_OBJECTS) $(dive_ui_LDADD) $(LIBS)
+io$(EXEEXT): $(io_OBJECTS) $(io_DEPENDENCIES) $(EXTRA_io_DEPENDENCIES)
+ @rm -f io$(EXEEXT)
+ $(LINK) $(io_OBJECTS) $(io_LDADD) $(LIBS)
+logic$(EXEEXT): $(logic_OBJECTS) $(logic_DEPENDENCIES) $(EXTRA_logic_DEPENDENCIES)
+ @rm -f logic$(EXEEXT)
+ $(LINK) $(logic_OBJECTS) $(logic_LDADD) $(LIBS)
+reuse$(EXEEXT): $(reuse_OBJECTS) $(reuse_DEPENDENCIES) $(EXTRA_reuse_DEPENDENCIES)
+ @rm -f reuse$(EXEEXT)
+ $(LINK) $(reuse_OBJECTS) $(reuse_LDADD) $(LIBS)
+t-addsub$(EXEEXT): $(t_addsub_OBJECTS) $(t_addsub_DEPENDENCIES) $(EXTRA_t_addsub_DEPENDENCIES)
+ @rm -f t-addsub$(EXEEXT)
+ $(LINK) $(t_addsub_OBJECTS) $(t_addsub_LDADD) $(LIBS)
+t-aorsmul$(EXEEXT): $(t_aorsmul_OBJECTS) $(t_aorsmul_DEPENDENCIES) $(EXTRA_t_aorsmul_DEPENDENCIES)
+ @rm -f t-aorsmul$(EXEEXT)
+ $(LINK) $(t_aorsmul_OBJECTS) $(t_aorsmul_LDADD) $(LIBS)
+t-bin$(EXEEXT): $(t_bin_OBJECTS) $(t_bin_DEPENDENCIES) $(EXTRA_t_bin_DEPENDENCIES)
+ @rm -f t-bin$(EXEEXT)
+ $(LINK) $(t_bin_OBJECTS) $(t_bin_LDADD) $(LIBS)
+t-cdiv_ui$(EXEEXT): $(t_cdiv_ui_OBJECTS) $(t_cdiv_ui_DEPENDENCIES) $(EXTRA_t_cdiv_ui_DEPENDENCIES)
+ @rm -f t-cdiv_ui$(EXEEXT)
+ $(LINK) $(t_cdiv_ui_OBJECTS) $(t_cdiv_ui_LDADD) $(LIBS)
+t-cmp$(EXEEXT): $(t_cmp_OBJECTS) $(t_cmp_DEPENDENCIES) $(EXTRA_t_cmp_DEPENDENCIES)
+ @rm -f t-cmp$(EXEEXT)
+ $(LINK) $(t_cmp_OBJECTS) $(t_cmp_LDADD) $(LIBS)
+t-cmp_d$(EXEEXT): $(t_cmp_d_OBJECTS) $(t_cmp_d_DEPENDENCIES) $(EXTRA_t_cmp_d_DEPENDENCIES)
+ @rm -f t-cmp_d$(EXEEXT)
+ $(LINK) $(t_cmp_d_OBJECTS) $(t_cmp_d_LDADD) $(LIBS)
+t-cmp_si$(EXEEXT): $(t_cmp_si_OBJECTS) $(t_cmp_si_DEPENDENCIES) $(EXTRA_t_cmp_si_DEPENDENCIES)
+ @rm -f t-cmp_si$(EXEEXT)
+ $(LINK) $(t_cmp_si_OBJECTS) $(t_cmp_si_LDADD) $(LIBS)
+t-cong$(EXEEXT): $(t_cong_OBJECTS) $(t_cong_DEPENDENCIES) $(EXTRA_t_cong_DEPENDENCIES)
+ @rm -f t-cong$(EXEEXT)
+ $(LINK) $(t_cong_OBJECTS) $(t_cong_LDADD) $(LIBS)
+t-cong_2exp$(EXEEXT): $(t_cong_2exp_OBJECTS) $(t_cong_2exp_DEPENDENCIES) $(EXTRA_t_cong_2exp_DEPENDENCIES)
+ @rm -f t-cong_2exp$(EXEEXT)
+ $(LINK) $(t_cong_2exp_OBJECTS) $(t_cong_2exp_LDADD) $(LIBS)
+t-div_2exp$(EXEEXT): $(t_div_2exp_OBJECTS) $(t_div_2exp_DEPENDENCIES) $(EXTRA_t_div_2exp_DEPENDENCIES)
+ @rm -f t-div_2exp$(EXEEXT)
+ $(LINK) $(t_div_2exp_OBJECTS) $(t_div_2exp_LDADD) $(LIBS)
+t-divis$(EXEEXT): $(t_divis_OBJECTS) $(t_divis_DEPENDENCIES) $(EXTRA_t_divis_DEPENDENCIES)
+ @rm -f t-divis$(EXEEXT)
+ $(LINK) $(t_divis_OBJECTS) $(t_divis_LDADD) $(LIBS)
+t-divis_2exp$(EXEEXT): $(t_divis_2exp_OBJECTS) $(t_divis_2exp_DEPENDENCIES) $(EXTRA_t_divis_2exp_DEPENDENCIES)
+ @rm -f t-divis_2exp$(EXEEXT)
+ $(LINK) $(t_divis_2exp_OBJECTS) $(t_divis_2exp_LDADD) $(LIBS)
+t-export$(EXEEXT): $(t_export_OBJECTS) $(t_export_DEPENDENCIES) $(EXTRA_t_export_DEPENDENCIES)
+ @rm -f t-export$(EXEEXT)
+ $(LINK) $(t_export_OBJECTS) $(t_export_LDADD) $(LIBS)
+t-fac_ui$(EXEEXT): $(t_fac_ui_OBJECTS) $(t_fac_ui_DEPENDENCIES) $(EXTRA_t_fac_ui_DEPENDENCIES)
+ @rm -f t-fac_ui$(EXEEXT)
+ $(LINK) $(t_fac_ui_OBJECTS) $(t_fac_ui_LDADD) $(LIBS)
+t-fdiv$(EXEEXT): $(t_fdiv_OBJECTS) $(t_fdiv_DEPENDENCIES) $(EXTRA_t_fdiv_DEPENDENCIES)
+ @rm -f t-fdiv$(EXEEXT)
+ $(LINK) $(t_fdiv_OBJECTS) $(t_fdiv_LDADD) $(LIBS)
+t-fdiv_ui$(EXEEXT): $(t_fdiv_ui_OBJECTS) $(t_fdiv_ui_DEPENDENCIES) $(EXTRA_t_fdiv_ui_DEPENDENCIES)
+ @rm -f t-fdiv_ui$(EXEEXT)
+ $(LINK) $(t_fdiv_ui_OBJECTS) $(t_fdiv_ui_LDADD) $(LIBS)
+t-fib_ui$(EXEEXT): $(t_fib_ui_OBJECTS) $(t_fib_ui_DEPENDENCIES) $(EXTRA_t_fib_ui_DEPENDENCIES)
+ @rm -f t-fib_ui$(EXEEXT)
+ $(LINK) $(t_fib_ui_OBJECTS) $(t_fib_ui_LDADD) $(LIBS)
+t-fits$(EXEEXT): $(t_fits_OBJECTS) $(t_fits_DEPENDENCIES) $(EXTRA_t_fits_DEPENDENCIES)
+ @rm -f t-fits$(EXEEXT)
+ $(LINK) $(t_fits_OBJECTS) $(t_fits_LDADD) $(LIBS)
+t-gcd$(EXEEXT): $(t_gcd_OBJECTS) $(t_gcd_DEPENDENCIES) $(EXTRA_t_gcd_DEPENDENCIES)
+ @rm -f t-gcd$(EXEEXT)
+ $(LINK) $(t_gcd_OBJECTS) $(t_gcd_LDADD) $(LIBS)
+t-gcd_ui$(EXEEXT): $(t_gcd_ui_OBJECTS) $(t_gcd_ui_DEPENDENCIES) $(EXTRA_t_gcd_ui_DEPENDENCIES)
+ @rm -f t-gcd_ui$(EXEEXT)
+ $(LINK) $(t_gcd_ui_OBJECTS) $(t_gcd_ui_LDADD) $(LIBS)
+t-get_d$(EXEEXT): $(t_get_d_OBJECTS) $(t_get_d_DEPENDENCIES) $(EXTRA_t_get_d_DEPENDENCIES)
+ @rm -f t-get_d$(EXEEXT)
+ $(LINK) $(t_get_d_OBJECTS) $(t_get_d_LDADD) $(LIBS)
+t-get_d_2exp$(EXEEXT): $(t_get_d_2exp_OBJECTS) $(t_get_d_2exp_DEPENDENCIES) $(EXTRA_t_get_d_2exp_DEPENDENCIES)
+ @rm -f t-get_d_2exp$(EXEEXT)
+ $(LINK) $(t_get_d_2exp_OBJECTS) $(t_get_d_2exp_LDADD) $(LIBS)
+t-get_si$(EXEEXT): $(t_get_si_OBJECTS) $(t_get_si_DEPENDENCIES) $(EXTRA_t_get_si_DEPENDENCIES)
+ @rm -f t-get_si$(EXEEXT)
+ $(LINK) $(t_get_si_OBJECTS) $(t_get_si_LDADD) $(LIBS)
+t-hamdist$(EXEEXT): $(t_hamdist_OBJECTS) $(t_hamdist_DEPENDENCIES) $(EXTRA_t_hamdist_DEPENDENCIES)
+ @rm -f t-hamdist$(EXEEXT)
+ $(LINK) $(t_hamdist_OBJECTS) $(t_hamdist_LDADD) $(LIBS)
+t-import$(EXEEXT): $(t_import_OBJECTS) $(t_import_DEPENDENCIES) $(EXTRA_t_import_DEPENDENCIES)
+ @rm -f t-import$(EXEEXT)
+ $(LINK) $(t_import_OBJECTS) $(t_import_LDADD) $(LIBS)
+t-inp_str$(EXEEXT): $(t_inp_str_OBJECTS) $(t_inp_str_DEPENDENCIES) $(EXTRA_t_inp_str_DEPENDENCIES)
+ @rm -f t-inp_str$(EXEEXT)
+ $(LINK) $(t_inp_str_OBJECTS) $(t_inp_str_LDADD) $(LIBS)
+t-invert$(EXEEXT): $(t_invert_OBJECTS) $(t_invert_DEPENDENCIES) $(EXTRA_t_invert_DEPENDENCIES)
+ @rm -f t-invert$(EXEEXT)
+ $(LINK) $(t_invert_OBJECTS) $(t_invert_LDADD) $(LIBS)
+t-io_raw$(EXEEXT): $(t_io_raw_OBJECTS) $(t_io_raw_DEPENDENCIES) $(EXTRA_t_io_raw_DEPENDENCIES)
+ @rm -f t-io_raw$(EXEEXT)
+ $(LINK) $(t_io_raw_OBJECTS) $(t_io_raw_LDADD) $(LIBS)
+t-jac$(EXEEXT): $(t_jac_OBJECTS) $(t_jac_DEPENDENCIES) $(EXTRA_t_jac_DEPENDENCIES)
+ @rm -f t-jac$(EXEEXT)
+ $(LINK) $(t_jac_OBJECTS) $(t_jac_LDADD) $(LIBS)
+t-lcm$(EXEEXT): $(t_lcm_OBJECTS) $(t_lcm_DEPENDENCIES) $(EXTRA_t_lcm_DEPENDENCIES)
+ @rm -f t-lcm$(EXEEXT)
+ $(LINK) $(t_lcm_OBJECTS) $(t_lcm_LDADD) $(LIBS)
+t-limbs$(EXEEXT): $(t_limbs_OBJECTS) $(t_limbs_DEPENDENCIES) $(EXTRA_t_limbs_DEPENDENCIES)
+ @rm -f t-limbs$(EXEEXT)
+ $(LINK) $(t_limbs_OBJECTS) $(t_limbs_LDADD) $(LIBS)
+t-lucnum_ui$(EXEEXT): $(t_lucnum_ui_OBJECTS) $(t_lucnum_ui_DEPENDENCIES) $(EXTRA_t_lucnum_ui_DEPENDENCIES)
+ @rm -f t-lucnum_ui$(EXEEXT)
+ $(LINK) $(t_lucnum_ui_OBJECTS) $(t_lucnum_ui_LDADD) $(LIBS)
+t-mfac_uiui$(EXEEXT): $(t_mfac_uiui_OBJECTS) $(t_mfac_uiui_DEPENDENCIES) $(EXTRA_t_mfac_uiui_DEPENDENCIES)
+ @rm -f t-mfac_uiui$(EXEEXT)
+ $(LINK) $(t_mfac_uiui_OBJECTS) $(t_mfac_uiui_LDADD) $(LIBS)
+t-mul$(EXEEXT): $(t_mul_OBJECTS) $(t_mul_DEPENDENCIES) $(EXTRA_t_mul_DEPENDENCIES)
+ @rm -f t-mul$(EXEEXT)
+ $(LINK) $(t_mul_OBJECTS) $(t_mul_LDADD) $(LIBS)
+t-mul_i$(EXEEXT): $(t_mul_i_OBJECTS) $(t_mul_i_DEPENDENCIES) $(EXTRA_t_mul_i_DEPENDENCIES)
+ @rm -f t-mul_i$(EXEEXT)
+ $(LINK) $(t_mul_i_OBJECTS) $(t_mul_i_LDADD) $(LIBS)
+t-nextprime$(EXEEXT): $(t_nextprime_OBJECTS) $(t_nextprime_DEPENDENCIES) $(EXTRA_t_nextprime_DEPENDENCIES)
+ @rm -f t-nextprime$(EXEEXT)
+ $(LINK) $(t_nextprime_OBJECTS) $(t_nextprime_LDADD) $(LIBS)
+t-oddeven$(EXEEXT): $(t_oddeven_OBJECTS) $(t_oddeven_DEPENDENCIES) $(EXTRA_t_oddeven_DEPENDENCIES)
+ @rm -f t-oddeven$(EXEEXT)
+ $(LINK) $(t_oddeven_OBJECTS) $(t_oddeven_LDADD) $(LIBS)
+t-perfpow$(EXEEXT): $(t_perfpow_OBJECTS) $(t_perfpow_DEPENDENCIES) $(EXTRA_t_perfpow_DEPENDENCIES)
+ @rm -f t-perfpow$(EXEEXT)
+ $(LINK) $(t_perfpow_OBJECTS) $(t_perfpow_LDADD) $(LIBS)
+t-perfsqr$(EXEEXT): $(t_perfsqr_OBJECTS) $(t_perfsqr_DEPENDENCIES) $(EXTRA_t_perfsqr_DEPENDENCIES)
+ @rm -f t-perfsqr$(EXEEXT)
+ $(LINK) $(t_perfsqr_OBJECTS) $(t_perfsqr_LDADD) $(LIBS)
+t-popcount$(EXEEXT): $(t_popcount_OBJECTS) $(t_popcount_DEPENDENCIES) $(EXTRA_t_popcount_DEPENDENCIES)
+ @rm -f t-popcount$(EXEEXT)
+ $(LINK) $(t_popcount_OBJECTS) $(t_popcount_LDADD) $(LIBS)
+t-pow$(EXEEXT): $(t_pow_OBJECTS) $(t_pow_DEPENDENCIES) $(EXTRA_t_pow_DEPENDENCIES)
+ @rm -f t-pow$(EXEEXT)
+ $(LINK) $(t_pow_OBJECTS) $(t_pow_LDADD) $(LIBS)
+t-powm$(EXEEXT): $(t_powm_OBJECTS) $(t_powm_DEPENDENCIES) $(EXTRA_t_powm_DEPENDENCIES)
+ @rm -f t-powm$(EXEEXT)
+ $(LINK) $(t_powm_OBJECTS) $(t_powm_LDADD) $(LIBS)
+t-powm_ui$(EXEEXT): $(t_powm_ui_OBJECTS) $(t_powm_ui_DEPENDENCIES) $(EXTRA_t_powm_ui_DEPENDENCIES)
+ @rm -f t-powm_ui$(EXEEXT)
+ $(LINK) $(t_powm_ui_OBJECTS) $(t_powm_ui_LDADD) $(LIBS)
+t-pprime_p$(EXEEXT): $(t_pprime_p_OBJECTS) $(t_pprime_p_DEPENDENCIES) $(EXTRA_t_pprime_p_DEPENDENCIES)
+ @rm -f t-pprime_p$(EXEEXT)
+ $(LINK) $(t_pprime_p_OBJECTS) $(t_pprime_p_LDADD) $(LIBS)
+t-primorial_ui$(EXEEXT): $(t_primorial_ui_OBJECTS) $(t_primorial_ui_DEPENDENCIES) $(EXTRA_t_primorial_ui_DEPENDENCIES)
+ @rm -f t-primorial_ui$(EXEEXT)
+ $(LINK) $(t_primorial_ui_OBJECTS) $(t_primorial_ui_LDADD) $(LIBS)
+t-remove$(EXEEXT): $(t_remove_OBJECTS) $(t_remove_DEPENDENCIES) $(EXTRA_t_remove_DEPENDENCIES)
+ @rm -f t-remove$(EXEEXT)
+ $(LINK) $(t_remove_OBJECTS) $(t_remove_LDADD) $(LIBS)
+t-root$(EXEEXT): $(t_root_OBJECTS) $(t_root_DEPENDENCIES) $(EXTRA_t_root_DEPENDENCIES)
+ @rm -f t-root$(EXEEXT)
+ $(LINK) $(t_root_OBJECTS) $(t_root_LDADD) $(LIBS)
+t-scan$(EXEEXT): $(t_scan_OBJECTS) $(t_scan_DEPENDENCIES) $(EXTRA_t_scan_DEPENDENCIES)
+ @rm -f t-scan$(EXEEXT)
+ $(LINK) $(t_scan_OBJECTS) $(t_scan_LDADD) $(LIBS)
+t-set_d$(EXEEXT): $(t_set_d_OBJECTS) $(t_set_d_DEPENDENCIES) $(EXTRA_t_set_d_DEPENDENCIES)
+ @rm -f t-set_d$(EXEEXT)
+ $(LINK) $(t_set_d_OBJECTS) $(t_set_d_LDADD) $(LIBS)
+t-set_f$(EXEEXT): $(t_set_f_OBJECTS) $(t_set_f_DEPENDENCIES) $(EXTRA_t_set_f_DEPENDENCIES)
+ @rm -f t-set_f$(EXEEXT)
+ $(LINK) $(t_set_f_OBJECTS) $(t_set_f_LDADD) $(LIBS)
+t-set_si$(EXEEXT): $(t_set_si_OBJECTS) $(t_set_si_DEPENDENCIES) $(EXTRA_t_set_si_DEPENDENCIES)
+ @rm -f t-set_si$(EXEEXT)
+ $(LINK) $(t_set_si_OBJECTS) $(t_set_si_LDADD) $(LIBS)
+t-set_str$(EXEEXT): $(t_set_str_OBJECTS) $(t_set_str_DEPENDENCIES) $(EXTRA_t_set_str_DEPENDENCIES)
+ @rm -f t-set_str$(EXEEXT)
+ $(LINK) $(t_set_str_OBJECTS) $(t_set_str_LDADD) $(LIBS)
+t-sizeinbase$(EXEEXT): $(t_sizeinbase_OBJECTS) $(t_sizeinbase_DEPENDENCIES) $(EXTRA_t_sizeinbase_DEPENDENCIES)
+ @rm -f t-sizeinbase$(EXEEXT)
+ $(LINK) $(t_sizeinbase_OBJECTS) $(t_sizeinbase_LDADD) $(LIBS)
+t-sqrtrem$(EXEEXT): $(t_sqrtrem_OBJECTS) $(t_sqrtrem_DEPENDENCIES) $(EXTRA_t_sqrtrem_DEPENDENCIES)
+ @rm -f t-sqrtrem$(EXEEXT)
+ $(LINK) $(t_sqrtrem_OBJECTS) $(t_sqrtrem_LDADD) $(LIBS)
+t-tdiv$(EXEEXT): $(t_tdiv_OBJECTS) $(t_tdiv_DEPENDENCIES) $(EXTRA_t_tdiv_DEPENDENCIES)
+ @rm -f t-tdiv$(EXEEXT)
+ $(LINK) $(t_tdiv_OBJECTS) $(t_tdiv_LDADD) $(LIBS)
+t-tdiv_ui$(EXEEXT): $(t_tdiv_ui_OBJECTS) $(t_tdiv_ui_DEPENDENCIES) $(EXTRA_t_tdiv_ui_DEPENDENCIES)
+ @rm -f t-tdiv_ui$(EXEEXT)
+ $(LINK) $(t_tdiv_ui_OBJECTS) $(t_tdiv_ui_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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 all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool ctags \
+ 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 \
+ tags uninstall uninstall-am
+
+
+$(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/gmp/tests/mpz/bit.c b/gmp/tests/mpz/bit.c
new file mode 100644
index 0000000000..c42e9f0cc5
--- /dev/null
+++ b/gmp/tests/mpz/bit.c
@@ -0,0 +1,406 @@
+/* Test mpz_setbit, mpz_clrbit, mpz_tstbit.
+
+Copyright 1997, 2000-2003, 2012, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef SIZE
+#define SIZE 4
+#endif
+
+
+void
+debug_mp (mpz_srcptr x, int base)
+{
+ mpz_out_str (stdout, base, x); fputc ('\n', stdout);
+}
+
+
+/* exercise the case where mpz_clrbit or mpz_combit ends up extending a
+ value like -2^(k*GMP_NUMB_BITS-1) when clearing bit k*GMP_NUMB_BITS-1. */
+/* And vice-versa. */
+void
+check_clr_extend (void)
+{
+ mpz_t got, want;
+ unsigned long i;
+ int f;
+
+ mpz_init (got);
+ mpz_init (want);
+
+ for (i = 1; i < 5; i++)
+ {
+ for (f = 0; f <= 1; f++)
+ {
+ /* lots of 1 bits in _mp_d */
+ mpz_set_si (got, 1L);
+ mpz_mul_2exp (got, got, 10*GMP_NUMB_BITS);
+ mpz_sub_ui (got, got, 1L);
+
+ /* value -2^(n-1) representing ..11100..00 */
+ mpz_set_si (got, -1L);
+ mpz_mul_2exp (got, got, i*GMP_NUMB_BITS-1);
+
+ /* complement bit n, giving ..11000..00 which is -2^n */
+ if (f == 0)
+ mpz_clrbit (got, i*GMP_NUMB_BITS-1);
+ else
+ mpz_combit (got, i*GMP_NUMB_BITS-1);
+ MPZ_CHECK_FORMAT (got);
+
+ mpz_set_si (want, -1L);
+ mpz_mul_2exp (want, want, i*GMP_NUMB_BITS);
+
+ if (mpz_cmp (got, want) != 0)
+ {
+ if (f == 0)
+ printf ("mpz_clrbit: ");
+ else
+ printf ("mpz_combit: ");
+ printf ("wrong after extension\n");
+ mpz_trace ("got ", got);
+ mpz_trace ("want", want);
+ abort ();
+ }
+
+ /* complement bit n, going back to ..11100..00 which is -2^(n-1) */
+ if (f == 0)
+ mpz_setbit (got, i*GMP_NUMB_BITS-1);
+ else
+ mpz_combit (got, i*GMP_NUMB_BITS-1);
+ MPZ_CHECK_FORMAT (got);
+
+ mpz_set_si (want, -1L);
+ mpz_mul_2exp (want, want, i*GMP_NUMB_BITS - 1);
+
+ if (mpz_cmp (got, want) != 0)
+ {
+ if (f == 0)
+ printf ("mpz_setbit: ");
+ else
+ printf ("mpz_combit: ");
+ printf ("wrong after shrinking\n");
+ mpz_trace ("got ", got);
+ mpz_trace ("want", want);
+ abort ();
+ }
+ }
+ }
+
+ mpz_clear (got);
+ mpz_clear (want);
+}
+
+void
+check_com_negs (void)
+{
+ static const struct {
+ unsigned long bit;
+ mp_size_t inp_size;
+ mp_limb_t inp_n[5];
+ mp_size_t want_size;
+ mp_limb_t want_n[5];
+ } data[] = {
+ { GMP_NUMB_BITS, 2, { 1, 1 }, 1, { 1 } },
+ { GMP_NUMB_BITS+1, 2, { 1, 1 }, 2, { 1, 3 } },
+
+ { GMP_NUMB_BITS, 2, { 0, 1 }, 2, { 0, 2 } },
+ { GMP_NUMB_BITS+1, 2, { 0, 1 }, 2, { 0, 3 } },
+ };
+ mpz_t inp, got, want;
+ int i;
+
+ mpz_init (got);
+ mpz_init (want);
+ mpz_init (inp);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_n (inp, data[i].inp_n, data[i].inp_size);
+ mpz_neg (inp, inp);
+
+ mpz_set_n (want, data[i].want_n, data[i].want_size);
+ mpz_neg (want, want);
+
+ mpz_set (got, inp);
+ mpz_combit (got, data[i].bit);
+
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_combit: wrong on neg data[%d]\n", i);
+ mpz_trace ("inp ", inp);
+ printf ("bit %lu\n", data[i].bit);
+ mpz_trace ("got ", got);
+ mpz_trace ("want", want);
+ abort ();
+ }
+ }
+
+ mpz_clear (inp);
+ mpz_clear (got);
+ mpz_clear (want);
+}
+
+/* See that mpz_tstbit matches a twos complement calculated explicitly, for
+ various low zeros. */
+void
+check_tstbit (void)
+{
+#define MAX_ZEROS 3
+#define NUM_LIMBS 3
+
+ mp_limb_t pos[1+NUM_LIMBS+MAX_ZEROS];
+ mp_limb_t neg[1+NUM_LIMBS+MAX_ZEROS];
+ mpz_t z;
+ unsigned long i;
+ int zeros, low1;
+ int got, want;
+
+ mpz_init (z);
+ for (zeros = 0; zeros <= MAX_ZEROS; zeros++)
+ {
+ MPN_ZERO (pos, numberof(pos));
+ mpn_random2 (pos+zeros, (mp_size_t) NUM_LIMBS);
+
+ for (low1 = 0; low1 <= 1; low1++)
+ {
+ if (low1)
+ pos[0] |= 1;
+
+ refmpn_neg (neg, pos, (mp_size_t) numberof(neg));
+ mpz_set_n (z, neg, (mp_size_t) numberof(neg));
+ mpz_neg (z, z);
+
+ for (i = 0; i < numberof(pos)*GMP_NUMB_BITS; i++)
+ {
+ got = mpz_tstbit (z, i);
+ want = refmpn_tstbit (pos, i);
+ if (got != want)
+ {
+ printf ("wrong at bit %lu, with %d zeros\n", i, zeros);
+ printf ("z neg "); debug_mp (z, -16);
+ mpz_set_n (z, pos, (mp_size_t) numberof(pos));
+ printf ("pos "); debug_mp (z, -16);
+ mpz_set_n (z, neg, (mp_size_t) numberof(neg));
+ printf ("neg "); debug_mp (z, -16);
+ exit (1);
+ }
+ }
+ }
+ }
+ mpz_clear (z);
+}
+
+
+void
+check_single (void)
+{
+ mpz_t x;
+ int limb, offset, initial;
+ unsigned long bit;
+
+ mpz_init (x);
+
+ for (limb = 0; limb < 4; limb++)
+ {
+ for (offset = (limb==0 ? 0 : -2); offset <= 2; offset++)
+ {
+ for (initial = 1; initial >= -1; initial--)
+ {
+ mpz_set_si (x, (long) initial);
+
+ bit = (unsigned long) limb*GMP_LIMB_BITS + offset;
+
+ mpz_clrbit (x, bit);
+ MPZ_CHECK_FORMAT (x);
+ if (mpz_tstbit (x, bit) != 0)
+ {
+ printf ("check_single(): expected 0\n");
+ abort ();
+ }
+
+ mpz_setbit (x, bit);
+ MPZ_CHECK_FORMAT (x);
+ if (mpz_tstbit (x, bit) != 1)
+ {
+ printf ("check_single(): expected 1\n");
+ abort ();
+ }
+
+ mpz_clrbit (x, bit);
+ MPZ_CHECK_FORMAT (x);
+ if (mpz_tstbit (x, bit) != 0)
+ {
+ printf ("check_single(): expected 0\n");
+ abort ();
+ }
+
+ mpz_combit (x, bit);
+ MPZ_CHECK_FORMAT (x);
+ if (mpz_tstbit (x, bit) != 1)
+ {
+ printf ("check_single(): expected 1\n");
+ abort ();
+ }
+
+ mpz_combit (x, bit);
+ MPZ_CHECK_FORMAT (x);
+ if (mpz_tstbit (x, bit) != 0)
+ {
+ printf ("check_single(): expected 0\n");
+ abort ();
+ }
+ }
+ }
+ }
+
+ mpz_clear (x);
+}
+
+
+void
+check_random (int argc, char *argv[])
+{
+ mpz_t x, s0, s1, s2, s3, m;
+ mp_size_t xsize;
+ int i;
+ int reps = 100000;
+ int bit0, bit1, bit2, bit3;
+ unsigned long int bitindex;
+ const char *s = "";
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (x);
+ mpz_init (s0);
+ mpz_init (s1);
+ mpz_init (s2);
+ mpz_init (s3);
+ mpz_init (m);
+
+ for (i = 0; i < reps; i++)
+ {
+ xsize = urandom () % (2 * SIZE) - SIZE;
+ mpz_random2 (x, xsize);
+ bitindex = urandom () % SIZE;
+
+ mpz_set (s0, x);
+ bit0 = mpz_tstbit (x, bitindex);
+ mpz_setbit (x, bitindex);
+ MPZ_CHECK_FORMAT (x);
+
+ mpz_set (s1, x);
+ bit1 = mpz_tstbit (x, bitindex);
+ mpz_clrbit (x, bitindex);
+ MPZ_CHECK_FORMAT (x);
+
+ mpz_set (s2, x);
+ bit2 = mpz_tstbit (x, bitindex);
+ mpz_combit (x, bitindex);
+ MPZ_CHECK_FORMAT (x);
+
+ mpz_set (s3, x);
+ bit3 = mpz_tstbit (x, bitindex);
+
+#define FAIL(str) do { s = str; goto fail; } while (0)
+
+ if (bit1 != 1) FAIL ("bit1 != 1");
+ if (bit2 != 0) FAIL ("bit2 != 0");
+ if (bit3 != 1) FAIL ("bit3 != 1");
+
+ if (bit0 == 0)
+ {
+ if (mpz_cmp (s0, s1) == 0 || mpz_cmp (s0, s2) != 0 || mpz_cmp (s0, s3) == 0)
+ abort ();
+ }
+ else
+ {
+ if (mpz_cmp (s0, s1) != 0 || mpz_cmp (s0, s2) == 0 || mpz_cmp (s0, s3) != 0)
+ abort ();
+ }
+
+ if (mpz_cmp (s1, s2) == 0 || mpz_cmp (s1, s3) != 0)
+ abort ();
+ if (mpz_cmp (s2, s3) == 0)
+ abort ();
+
+ mpz_combit (x, bitindex);
+ MPZ_CHECK_FORMAT (x);
+ if (mpz_cmp (s2, x) != 0)
+ abort ();
+
+ mpz_clrbit (x, bitindex);
+ MPZ_CHECK_FORMAT (x);
+ if (mpz_cmp (s2, x) != 0)
+ abort ();
+
+ mpz_ui_pow_ui (m, 2L, bitindex);
+ MPZ_CHECK_FORMAT (m);
+ mpz_ior (x, s0, m);
+ MPZ_CHECK_FORMAT (x);
+ if (mpz_cmp (x, s3) != 0)
+ abort ();
+
+ mpz_com (m, m);
+ MPZ_CHECK_FORMAT (m);
+ mpz_and (x, s0, m);
+ MPZ_CHECK_FORMAT (x);
+ if (mpz_cmp (x, s2) != 0)
+ abort ();
+ }
+
+ mpz_clear (x);
+ mpz_clear (s0);
+ mpz_clear (s1);
+ mpz_clear (s2);
+ mpz_clear (s3);
+ mpz_clear (m);
+ return;
+
+
+ fail:
+ printf ("%s\n", s);
+ printf ("bitindex = %lu\n", bitindex);
+ printf ("x = "); mpz_out_str (stdout, -16, x); printf (" hex\n");
+ exit (1);
+}
+
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_clr_extend ();
+ check_com_negs ();
+ check_tstbit ();
+ check_random (argc, argv);
+ check_single ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/convert.c b/gmp/tests/mpz/convert.c
new file mode 100644
index 0000000000..ada6d11a16
--- /dev/null
+++ b/gmp/tests/mpz/convert.c
@@ -0,0 +1,170 @@
+/* Test conversion using mpz_get_str and mpz_set_str.
+
+Copyright 1993, 1994, 1996, 1999-2002, 2006, 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for strlen */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void debug_mp (mpz_t, int);
+
+
+void
+string_urandomb (char *bp, size_t len, int base, gmp_randstate_ptr rands)
+{
+ mpz_t bs;
+ unsigned long bsi;
+ int d, l;
+ const char *collseq = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+ mpz_init (bs);
+
+ mpz_urandomb (bs, rands, 32);
+ bsi = mpz_get_ui (bs);
+ d = bsi % base;
+ while (len != 0)
+ {
+ l = (bsi >> 16) % 20;
+ l = MIN (l, len);
+
+ memset (bp, collseq[d], l);
+
+ len -= l;
+ bp += l;
+
+ mpz_urandomb (bs, rands, 32);
+ bsi = mpz_get_ui (bs);
+ d = bsi & 0xfff;
+ if (d >= base)
+ d = 0;
+ }
+
+ bp[0] = '\0';
+ mpz_clear (bs);
+}
+
+int
+main (int argc, char **argv)
+{
+ mpz_t op1, op2;
+ mp_size_t size;
+ int i;
+ int reps = 2000;
+ char *str, *buf, *bp;
+ int base;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+ size_t len;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ mpz_init (op1);
+ mpz_init (op2);
+
+ for (i = 0; i < reps; i++)
+ {
+ /* 1. Generate random mpz_t and convert to a string and back to mpz_t
+ again. */
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 17 + 2; /* 2..18 */
+ mpz_urandomb (bs, rands, size_range); /* 3..262144 bits */
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (op1, rands, size);
+
+ mpz_urandomb (bs, rands, 1);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (op1, op1);
+
+ mpz_urandomb (bs, rands, 32);
+ bsi = mpz_get_ui (bs);
+ base = bsi % 62 + 1;
+ if (base == 1)
+ base = 0;
+
+ str = mpz_get_str ((char *) 0, base, op1);
+ mpz_set_str_or_abort (op2, str, base);
+
+ if (mpz_cmp (op1, op2))
+ {
+ fprintf (stderr, "ERROR, op1 and op2 different in test %d\n", i);
+ fprintf (stderr, "str = %s\n", str);
+ fprintf (stderr, "base = %d\n", base);
+ fprintf (stderr, "op1 = "); debug_mp (op1, -16);
+ fprintf (stderr, "op2 = "); debug_mp (op2, -16);
+ abort ();
+ }
+
+ (*__gmp_free_func) (str, strlen (str) + 1);
+
+ /* 2. Generate random string and convert to mpz_t and back to a string
+ again. */
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 16 + 1; /* 1..16 */
+ mpz_urandomb (bs, rands, size_range); /* 1..65536 digits */
+ len = mpz_get_ui (bs) + 1;
+ buf = (char *) (*__gmp_allocate_func) (len + 1);
+ if (base == 0)
+ base = 10;
+ string_urandomb (buf, len, base, rands);
+
+ mpz_set_str_or_abort (op1, buf, base);
+ str = mpz_get_str ((char *) 0, base, op1);
+
+ /* Skip over leading zeros, but don't leave the string at zero length. */
+ for (bp = buf; bp[0] == '0' && bp[1] != '\0'; bp++)
+ ;
+
+ if (strcasecmp (str, bp) != 0)
+ {
+ fprintf (stderr, "ERROR, str and buf different in test %d\n", i);
+ fprintf (stderr, "str = %s\n", str);
+ fprintf (stderr, "buf = %s\n", buf);
+ fprintf (stderr, "base = %d\n", base);
+ fprintf (stderr, "op1 = "); debug_mp (op1, -16);
+ abort ();
+ }
+
+ (*__gmp_free_func) (buf, len + 1);
+ (*__gmp_free_func) (str, strlen (str) + 1);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (op1);
+ mpz_clear (op2);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/dive.c b/gmp/tests/mpz/dive.c
new file mode 100644
index 0000000000..7970e718a0
--- /dev/null
+++ b/gmp/tests/mpz/dive.c
@@ -0,0 +1,101 @@
+/* Test mpz_mul, mpz_divexact.
+
+Copyright 1996, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+int
+main (int argc, char **argv)
+{
+ mpz_t op1, op2;
+ mpz_t prod, quot;
+ mp_size_t size;
+ int i;
+ int reps = 5000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ mp_trace_base = -16;
+
+ mpz_init (bs);
+
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (prod);
+ mpz_init (quot);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 17 + 2; /* 0..2047 bit operands */
+
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (op1, rands, size);
+
+ do
+ {
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (op2, rands, size);
+ }
+ while (mpz_sgn (op2) == 0);
+
+ mpz_urandomb (bs, rands, 2);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (op1, op1);
+ if ((bsi & 2) != 0)
+ mpz_neg (op2, op2);
+
+ mpz_mul (prod, op1, op2);
+
+ mpz_divexact (quot, prod, op2);
+ MPZ_CHECK_FORMAT (quot);
+
+ if (mpz_cmp (quot, op1) != 0)
+ {
+ printf ("Wrong results:\n");
+ mpz_trace (" got ", quot);
+ mpz_trace (" want ", op1);
+ mpz_trace (" dividend", prod);
+ mpz_trace (" divisor ", op2);
+ abort ();
+ }
+ }
+
+ mpz_clear (bs);
+ mpz_clear (op1);
+ mpz_clear (op2);
+ mpz_clear (prod);
+ mpz_clear (quot);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/dive_ui.c b/gmp/tests/mpz/dive_ui.c
new file mode 100644
index 0000000000..6771677f1f
--- /dev/null
+++ b/gmp/tests/mpz/dive_ui.c
@@ -0,0 +1,87 @@
+/* Test mpz_divexact_ui.
+
+Copyright 1996, 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_random (int argc, char *argv[])
+{
+ gmp_randstate_ptr rands = RANDS;
+ int reps = 500000;
+ mpz_t a, q, got;
+ int i, qneg;
+ unsigned long d;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (a);
+ mpz_init (q);
+ mpz_init (got);
+
+ for (i = 0; i < reps; i++)
+ {
+ do
+ d = (unsigned long) urandom();
+ while (d == 0);
+ mpz_erandomb (q, rands, 512);
+ mpz_mul_ui (a, q, d);
+
+ for (qneg = 0; qneg <= 1; qneg++)
+ {
+ mpz_divexact_ui (got, a, d);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (got, q) != 0)
+ {
+ printf ("mpz_divexact_ui wrong\n");
+ mpz_trace (" a", a);
+ printf (" d=%lu\n", d);
+ mpz_trace (" q", q);
+ mpz_trace (" got", got);
+ abort ();
+ }
+
+ mpz_neg (q, q);
+ mpz_neg (a, a);
+ }
+
+ }
+
+ mpz_clear (a);
+ mpz_clear (q);
+ mpz_clear (got);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ tests_start ();
+
+ check_random (argc, argv);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/io.c b/gmp/tests/mpz/io.c
new file mode 100644
index 0000000000..7674d69b1c
--- /dev/null
+++ b/gmp/tests/mpz/io.c
@@ -0,0 +1,139 @@
+/* Test conversion and I/O using mpz_out_str and mpz_inp_str.
+
+Copyright 1993, 1994, 1996, 2000, 2001, 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 <stdio.h>
+#include <stdlib.h>
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for unlink */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define FILENAME "io.tmp"
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stdout, base, x); fputc ('\n', stdout);
+}
+
+int
+main (int argc, char **argv)
+{
+ mpz_t op1, op2;
+ mp_size_t size;
+ int i;
+ int reps = 10000;
+ FILE *fp;
+ int base, base_out;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+ size_t nread;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (op1);
+ mpz_init (op2);
+
+ fp = fopen (FILENAME, "w+");
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 10 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (op1, rands, size);
+ mpz_urandomb (bs, rands, 1);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (op1, op1);
+
+ mpz_urandomb (bs, rands, 16);
+ bsi = mpz_get_ui (bs);
+ base = bsi % 62 + 1;
+ if (base == 1)
+ base = 0;
+
+ if (i % 2 == 0 && base <= 36)
+ base_out = -base;
+ else
+ base_out = base;
+
+ rewind (fp);
+ if (mpz_out_str (fp, base_out, op1) == 0
+ || putc (' ', fp) == EOF
+ || fflush (fp) != 0)
+ {
+ printf ("mpz_out_str write error\n");
+ abort ();
+ }
+
+ rewind (fp);
+ nread = mpz_inp_str (op2, fp, base);
+ if (nread == 0)
+ {
+ if (ferror (fp))
+ printf ("mpz_inp_str stream read error\n");
+ else
+ printf ("mpz_inp_str data conversion error\n");
+ abort ();
+ }
+
+ if (nread != ftell(fp))
+ {
+ printf ("mpz_inp_str nread doesn't match ftell\n");
+ printf (" nread %lu\n", (unsigned long) nread);
+ printf (" ftell %ld\n", ftell(fp));
+ abort ();
+ }
+
+ if (mpz_cmp (op1, op2))
+ {
+ printf ("ERROR\n");
+ printf ("op1 = "); debug_mp (op1, -16);
+ printf ("op2 = "); debug_mp (op2, -16);
+ printf ("base = %d\n", base);
+ abort ();
+ }
+ }
+
+ fclose (fp);
+
+ unlink (FILENAME);
+
+ mpz_clear (bs);
+ mpz_clear (op1);
+ mpz_clear (op2);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/logic.c b/gmp/tests/mpz/logic.c
new file mode 100644
index 0000000000..d99cadc2bd
--- /dev/null
+++ b/gmp/tests/mpz/logic.c
@@ -0,0 +1,195 @@
+/* Test mpz_com, mpz_and, mpz_ior, and mpz_xor.
+
+Copyright 1993, 1994, 1996, 1997, 2001, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void dump_abort (void);
+void debug_mp (mpz_t, int);
+
+int
+main (int argc, char **argv)
+{
+ mpz_t x, y, r1, r2;
+ mpz_t t1, t2, t3;
+ mp_size_t xsize, ysize;
+ int i;
+ int reps = 100000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (x);
+ mpz_init (y);
+ mpz_init (r1);
+ mpz_init (r2);
+ mpz_init (t1);
+ mpz_init (t2);
+ mpz_init (t3);
+
+ mpz_set_si (x, -1);
+ mpz_set_ui (y, 0);
+ for (i = 0; i < 300; i++)
+ {
+ mpz_mul_2exp (x, x, 1);
+
+ mpz_and (r1, x, x);
+ MPZ_CHECK_FORMAT (r1);
+ if (mpz_cmp (r1, x) != 0)
+ dump_abort ();
+
+ mpz_ior (r2, x, x);
+ MPZ_CHECK_FORMAT (r2);
+ if (mpz_cmp (r2, x) != 0)
+ dump_abort ();
+
+ mpz_xor (t1, x, x);
+ MPZ_CHECK_FORMAT (t1);
+ if (mpz_cmp_si (t1, 0) != 0)
+ dump_abort ();
+
+ mpz_ior (t1, x, y);
+ MPZ_CHECK_FORMAT (t1);
+ if (mpz_cmp (t1, x) != 0)
+ dump_abort ();
+
+ mpz_xor (t2, x, y);
+ MPZ_CHECK_FORMAT (t2);
+ if (mpz_cmp (t2, x) != 0)
+ dump_abort ();
+
+ mpz_com (t2, x);
+ MPZ_CHECK_FORMAT (t2);
+ mpz_xor (t3, t2, x);
+ MPZ_CHECK_FORMAT (t3);
+ if (mpz_cmp_si (t3, -1) != 0)
+ dump_abort ();
+ }
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 8 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ xsize = mpz_get_ui (bs);
+ mpz_rrandomb (x, rands, xsize);
+ mpz_urandomb (bs, rands, 1);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (x, x);
+
+ mpz_urandomb (bs, rands, size_range);
+ ysize = mpz_get_ui (bs);
+ mpz_rrandomb (y, rands, ysize);
+ mpz_urandomb (bs, rands, 1);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (y, y);
+
+ mpz_com (r1, x);
+ MPZ_CHECK_FORMAT (r1);
+ mpz_com (r1, r1);
+ MPZ_CHECK_FORMAT (r1);
+ if (mpz_cmp (r1, x) != 0)
+ dump_abort ();
+
+ mpz_com (r1, y);
+ MPZ_CHECK_FORMAT (r1);
+ mpz_com (r2, r1);
+ MPZ_CHECK_FORMAT (r2);
+ if (mpz_cmp (r2, y) != 0)
+ dump_abort ();
+
+ mpz_com (t1, x);
+ MPZ_CHECK_FORMAT (t1);
+ mpz_com (t2, y);
+ MPZ_CHECK_FORMAT (t2);
+ mpz_and (t3, t1, t2);
+ MPZ_CHECK_FORMAT (t3);
+ mpz_com (r1, t3);
+ MPZ_CHECK_FORMAT (r1);
+ mpz_ior (r2, x, y);
+ MPZ_CHECK_FORMAT (r2);
+ if (mpz_cmp (r1, r2) != 0)
+ dump_abort ();
+
+ mpz_com (t1, x);
+ MPZ_CHECK_FORMAT (t1);
+ mpz_com (t2, y);
+ MPZ_CHECK_FORMAT (t2);
+ mpz_ior (t3, t1, t2);
+ MPZ_CHECK_FORMAT (t3);
+ mpz_com (r1, t3);
+ MPZ_CHECK_FORMAT (r1);
+ mpz_and (r2, x, y);
+ MPZ_CHECK_FORMAT (r2);
+ if (mpz_cmp (r1, r2) != 0)
+ dump_abort ();
+
+ mpz_ior (t1, x, y);
+ MPZ_CHECK_FORMAT (t1);
+ mpz_and (t2, x, y);
+ MPZ_CHECK_FORMAT (t2);
+ mpz_com (t3, t2);
+ MPZ_CHECK_FORMAT (t3);
+ mpz_and (r1, t1, t3);
+ MPZ_CHECK_FORMAT (r1);
+ mpz_xor (r2, x, y);
+ MPZ_CHECK_FORMAT (r2);
+ if (mpz_cmp (r1, r2) != 0)
+ dump_abort ();
+ }
+
+ mpz_clear (bs);
+ mpz_clear (x);
+ mpz_clear (y);
+ mpz_clear (r1);
+ mpz_clear (r2);
+ mpz_clear (t1);
+ mpz_clear (t2);
+ mpz_clear (t3);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort ()
+{
+ abort();
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/reuse.c b/gmp/tests/mpz/reuse.c
new file mode 100644
index 0000000000..4b67fbe38b
--- /dev/null
+++ b/gmp/tests/mpz/reuse.c
@@ -0,0 +1,722 @@
+/* Test that routines allow reusing a source variable as destination.
+
+ Test all relevant functions except:
+ mpz_bin_ui
+ mpz_nextprime
+ mpz_mul_si
+ mpz_addmul_ui (should this really allow a+=a*c?)
+
+Copyright 1996, 1999-2002, 2009, 2012, 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#if __GMP_LIBGMP_DLL
+
+/* FIXME: When linking to a DLL libgmp, mpz_add etc can't be used as
+ initializers for global variables because they're effectively global
+ variables (function pointers) themselves. Perhaps calling a test
+ function successively with mpz_add etc would be better. */
+
+int
+main (void)
+{
+ printf ("Test suppressed for windows DLL\n");
+ exit (0);
+}
+
+
+#else /* ! DLL_EXPORT */
+
+void dump (const char *, mpz_t, mpz_t, mpz_t);
+
+typedef void (*dss_func) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+typedef void (*dsi_func) (mpz_ptr, mpz_srcptr, unsigned long int);
+typedef unsigned long int (*dsi_div_func) (mpz_ptr, mpz_srcptr, unsigned long int);
+typedef unsigned long int (*ddsi_div_func) (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int);
+typedef void (*ddss_div_func) (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
+typedef void (*ds_func) (mpz_ptr, mpz_srcptr);
+
+
+void
+mpz_xinvert (mpz_ptr r, mpz_srcptr a, mpz_srcptr b)
+{
+ int res;
+ res = mpz_invert (r, a, b);
+ if (res == 0)
+ mpz_set_ui (r, 0);
+}
+
+struct {
+ dss_func fptr;
+ const char *fname;
+ int isdivision;
+ int isslow;
+} dss[] =
+ { { mpz_add, "mpz_add", 0, 0 },
+ { mpz_sub, "mpz_sub", 0, 0 },
+ { mpz_mul, "mpz_mul", 0, 0 },
+ { mpz_cdiv_q, "mpz_cdiv_q", 1, 0 },
+ { mpz_cdiv_r, "mpz_cdiv_r", 1, 0 },
+ { mpz_fdiv_q, "mpz_fdiv_q", 1, 0 },
+ { mpz_fdiv_r, "mpz_fdiv_r", 1, 0 },
+ { mpz_tdiv_q, "mpz_tdiv_q", 1, 0 },
+ { mpz_tdiv_r, "mpz_tdiv_r", 1, 0 },
+ { mpz_mod, "mpz_mod", 1, 0 },
+ { mpz_xinvert, "mpz_xinvert", 1, 1 },
+ { mpz_gcd, "mpz_gcd", 0, 1 },
+ { mpz_lcm, "mpz_lcm", 0, 1 },
+ { mpz_and, "mpz_and", 0, 0 },
+ { mpz_ior, "mpz_ior", 0, 0 },
+ { mpz_xor, "mpz_xor", 0, 0 }
+ };
+
+
+struct {
+ dsi_func fptr;
+ const char *fname;
+ int mod;
+} dsi[] =
+{
+ /* Don't change order here without changing the code in main(). */
+ { mpz_add_ui, "mpz_add_ui", 0 },
+ { mpz_mul_ui, "mpz_mul_ui", 0 },
+ { mpz_sub_ui, "mpz_sub_ui", 0 },
+ { mpz_fdiv_q_2exp, "mpz_fdiv_q_2exp", 0x1000 },
+ { mpz_fdiv_r_2exp, "mpz_fdiv_r_2exp", 0x1000 },
+ { mpz_cdiv_q_2exp, "mpz_cdiv_q_2exp", 0x1000 },
+ { mpz_cdiv_r_2exp, "mpz_cdiv_r_2exp", 0x1000 },
+ { mpz_tdiv_q_2exp, "mpz_tdiv_q_2exp", 0x1000 },
+ { mpz_tdiv_r_2exp, "mpz_tdiv_r_2exp", 0x1000 },
+ { mpz_mul_2exp, "mpz_mul_2exp", 0x100 },
+ { mpz_pow_ui, "mpz_pow_ui", 0x10 }
+};
+
+struct {
+ dsi_div_func fptr;
+ const char *fname;
+} dsi_div[] =
+{
+ { mpz_cdiv_q_ui, "mpz_cdiv_q_ui" },
+ { mpz_cdiv_r_ui, "mpz_cdiv_r_ui" },
+ { mpz_fdiv_q_ui, "mpz_fdiv_q_ui" },
+ { mpz_fdiv_r_ui, "mpz_fdiv_r_ui" },
+ { mpz_tdiv_q_ui, "mpz_tdiv_q_ui" },
+ { mpz_tdiv_r_ui, "mpz_tdiv_r_ui" }
+};
+
+struct {
+ ddsi_div_func fptr;
+ const char *fname;
+ int isslow;
+} ddsi_div[] =
+{
+ { mpz_cdiv_qr_ui, "mpz_cdiv_qr_ui", 0 },
+ { mpz_fdiv_qr_ui, "mpz_fdiv_qr_ui", 0 },
+ { mpz_tdiv_qr_ui, "mpz_tdiv_qr_ui", 0 },
+};
+
+
+struct {
+ ddss_div_func fptr;
+ const char *fname;
+ int isslow;
+} ddss_div[] =
+{
+ { mpz_cdiv_qr, "mpz_cdiv_qr", 0 },
+ { mpz_fdiv_qr, "mpz_fdiv_qr", 0 },
+ { mpz_tdiv_qr, "mpz_tdiv_qr", 0 },
+};
+
+struct {
+ ds_func fptr;
+ const char *fname;
+ int nonneg;
+} ds[] =
+{
+ { mpz_abs, "mpz_abs", 0 },
+ { mpz_com, "mpz_com", 0 },
+ { mpz_neg, "mpz_neg", 0 },
+ { mpz_sqrt, "mpz_sqrt", 1 },
+};
+
+#define FAIL(class,indx,op1,op2,op3) \
+ do { \
+ dump (class[indx].fname, op1, op2, op3); \
+ exit (1); \
+ } while (0)
+
+#define FAIL2(fname,op1,op2,op3) \
+ do { \
+ dump (#fname, op1, op2, op3); \
+ exit (1); \
+ } while (0)
+
+
+#define INVOKE_RRS(desc,r1,r2,i1) \
+ do { \
+ if (pass & 1) _mpz_realloc (r1, ABSIZ(r1)); \
+ if (pass & 2) _mpz_realloc (r2, ABSIZ(r2)); \
+ (desc).fptr (r1, r2, i1); \
+ } while (0)
+#define INVOKE_RS(desc,r1,i1) \
+ do { \
+ if (pass & 1) _mpz_realloc (r1, ABSIZ(r1)); \
+ (desc).fptr (r1, i1); \
+ } while (0)
+#define INVOKE_RRSS(desc,r1,r2,i1,i2) \
+ do { \
+ if (pass & 1) _mpz_realloc (r1, ABSIZ(r1)); \
+ if (pass & 2) _mpz_realloc (r2, ABSIZ(r2)); \
+ (desc).fptr (r1, r2, i1, i2); \
+ } while (0)
+#define INVOKE_RSS(desc,r1,i1,i2) \
+ do { \
+ if (pass & 1) _mpz_realloc (r1, ABSIZ(r1)); \
+ (desc).fptr (r1, i1, i2); \
+ } while (0)
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ int pass, reps = 400;
+ mpz_t in1, in2, in3;
+ unsigned long int in2i;
+ mp_size_t size;
+ mpz_t res1, res2, res3;
+ mpz_t ref1, ref2, ref3;
+ mpz_t t;
+ unsigned long int r1, r2;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ mpz_init (in1);
+ mpz_init (in2);
+ mpz_init (in3);
+ mpz_init (ref1);
+ mpz_init (ref2);
+ mpz_init (ref3);
+ mpz_init (res1);
+ mpz_init (res2);
+ mpz_init (res3);
+ mpz_init (t);
+
+ for (pass = 1; pass <= reps; pass++)
+ {
+ if (isatty (fileno (stdout)))
+ {
+ printf ("\r%d/%d passes", pass, reps);
+ fflush (stdout);
+ }
+
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 21 + 2;
+
+ if ((pass & 1) == 0)
+ {
+ /* Make all input operands have quite different sizes */
+ mpz_urandomb (bs, rands, 32);
+ size = mpz_get_ui (bs) % size_range;
+ mpz_rrandomb (in1, rands, size);
+
+ mpz_urandomb (bs, rands, 32);
+ size = mpz_get_ui (bs) % size_range;
+ mpz_rrandomb (in2, rands, size);
+
+ mpz_urandomb (bs, rands, 32);
+ size = mpz_get_ui (bs) % size_range;
+ mpz_rrandomb (in3, rands, size);
+ }
+ else
+ {
+ /* Make all input operands have about the same size */
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (in1, rands, size);
+
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (in2, rands, size);
+
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (in3, rands, size);
+ }
+
+ mpz_urandomb (bs, rands, 3);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (in1, in1);
+ if ((bsi & 2) != 0)
+ mpz_neg (in2, in2);
+ if ((bsi & 4) != 0)
+ mpz_neg (in3, in3);
+
+ for (i = 0; i < numberof (dss); i++)
+ {
+ if (dss[i].isdivision && mpz_sgn (in2) == 0)
+ continue;
+ if (dss[i].isslow && size_range > 19)
+ continue;
+
+ (dss[i].fptr) (ref1, in1, in2);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ INVOKE_RSS (dss[i], res1, res1, in2);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL (dss, i, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ INVOKE_RSS (dss[i], res1, in1, res1);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL (dss, i, in1, in2, NULL);
+ }
+
+ for (i = 0; i < numberof (ddss_div); i++)
+ {
+ if (mpz_sgn (in2) == 0)
+ continue;
+
+ (ddss_div[i].fptr) (ref1, ref2, in1, in2);
+ MPZ_CHECK_FORMAT (ref1);
+ MPZ_CHECK_FORMAT (ref2);
+
+ mpz_set (res1, in1);
+ INVOKE_RRSS (ddss_div[i], res1, res2, res1, in2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL (ddss_div, i, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ INVOKE_RRSS (ddss_div[i], res1, res2, res2, in2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL (ddss_div, i, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ INVOKE_RRSS (ddss_div[i], res1, res2, in1, res1);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL (ddss_div, i, in1, in2, NULL);
+
+ mpz_set (res2, in2);
+ INVOKE_RRSS (ddss_div[i], res1, res2, in1, res2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL (ddss_div, i, in1, in2, NULL);
+ }
+
+ for (i = 0; i < numberof (ds); i++)
+ {
+ if (ds[i].nonneg && mpz_sgn (in1) < 0)
+ continue;
+
+ (ds[i].fptr) (ref1, in1);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ INVOKE_RS (ds[i], res1, res1);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL (ds, i, in1, in2, NULL);
+ }
+
+ in2i = mpz_get_ui (in2);
+
+ for (i = 0; i < numberof (dsi); i++)
+ {
+ if (dsi[i].mod != 0)
+ in2i = mpz_get_ui (in2) % dsi[i].mod;
+
+ (dsi[i].fptr) (ref1, in1, in2i);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ INVOKE_RRS (dsi[i], res1, res1, in2i);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL (dsi, i, in1, in2, NULL);
+ }
+
+ if (in2i != 0) /* Don't divide by 0. */
+ {
+ for (i = 0; i < numberof (dsi_div); i++)
+ {
+ r1 = (dsi_div[i].fptr) (ref1, in1, in2i);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ r2 = (dsi_div[i].fptr) (res1, res1, in2i);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0 || r1 != r2)
+ FAIL (dsi_div, i, in1, in2, NULL);
+ }
+
+ for (i = 0; i < numberof (ddsi_div); i++)
+ {
+ r1 = (ddsi_div[i].fptr) (ref1, ref2, in1, in2i);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ r2 = (ddsi_div[i].fptr) (res1, res2, res1, in2i);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
+ FAIL (ddsi_div, i, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ (ddsi_div[i].fptr) (res1, res2, res2, in2i);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
+ FAIL (ddsi_div, i, in1, in2, NULL);
+ }
+ }
+
+ if (mpz_sgn (in1) >= 0)
+ {
+ mpz_sqrtrem (ref1, ref2, in1);
+ MPZ_CHECK_FORMAT (ref1);
+ MPZ_CHECK_FORMAT (ref2);
+
+ mpz_set (res1, in1);
+ mpz_sqrtrem (res1, res2, res1);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
+
+ mpz_set (res2, in1);
+ mpz_sqrtrem (res1, res2, res2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
+
+ mpz_set (res1, in1);
+ mpz_sqrtrem (res1, res1, res1);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref2, res1) != 0)
+ FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
+ }
+
+ if (mpz_sgn (in1) >= 0)
+ {
+ mpz_root (ref1, in1, in2i % 0x100 + 1);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ mpz_root (res1, res1, in2i % 0x100 + 1);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_root, in1, in2, NULL);
+ }
+
+ if (mpz_sgn (in1) >= 0)
+ {
+ mpz_rootrem (ref1, ref2, in1, in2i % 0x100 + 1);
+ MPZ_CHECK_FORMAT (ref1);
+ MPZ_CHECK_FORMAT (ref2);
+
+ mpz_set (res1, in1);
+ mpz_rootrem (res1, res2, res1, in2i % 0x100 + 1);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL2 (mpz_rootrem, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ mpz_rootrem (res1, res2, res2, in2i % 0x100 + 1);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
+ FAIL2 (mpz_rootrem, in1, in2, NULL);
+ }
+
+ if (size_range < 18) /* run fewer tests since gcdext is slow */
+ {
+ mpz_gcdext (ref1, ref2, ref3, in1, in2);
+ MPZ_CHECK_FORMAT (ref1);
+ MPZ_CHECK_FORMAT (ref2);
+ MPZ_CHECK_FORMAT (ref3);
+
+ mpz_set (res1, in1);
+ mpz_gcdext (res1, res2, res3, res1, in2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ MPZ_CHECK_FORMAT (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ mpz_gcdext (res1, res2, res3, res2, in2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ MPZ_CHECK_FORMAT (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res3, in1);
+ mpz_gcdext (res1, res2, res3, res3, in2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ MPZ_CHECK_FORMAT (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ mpz_gcdext (res1, res2, res3, in1, res1);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ MPZ_CHECK_FORMAT (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res2, in2);
+ mpz_gcdext (res1, res2, res3, in1, res2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ MPZ_CHECK_FORMAT (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res3, in2);
+ mpz_gcdext (res1, res2, res3, in1, res3);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ MPZ_CHECK_FORMAT (res3);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res1, in1);
+ mpz_gcdext (res1, res2, NULL, res1, in2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res2, in1);
+ mpz_gcdext (res1, res2, NULL, res2, in2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ mpz_gcdext (res1, res2, NULL, in1, res1);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+
+ mpz_set (res2, in2);
+ mpz_gcdext (res1, res2, NULL, in1, res2);
+ MPZ_CHECK_FORMAT (res1);
+ MPZ_CHECK_FORMAT (res2);
+ if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
+ || mpz_cmp (ref3, res3) != 0)
+ FAIL2 (mpz_gcdext, in1, in2, NULL);
+ }
+
+ /* Don't run mpz_powm for huge exponents or when undefined. */
+ if (size_range < 17 && mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0
+ && (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3)))
+ {
+ mpz_powm (ref1, in1, in2, in3);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ mpz_powm (res1, res1, in2, in3);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm, in1, in2, in3);
+
+ mpz_set (res1, in2);
+ mpz_powm (res1, in1, res1, in3);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm, in1, in2, in3);
+
+ mpz_set (res1, in3);
+ mpz_powm (res1, in1, in2, res1);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm, in1, in2, in3);
+ }
+
+ /* Don't run mpz_powm_ui when undefined. */
+ if (size_range < 17 && mpz_sgn (in3) != 0)
+ {
+ mpz_powm_ui (ref1, in1, in2i, in3);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ mpz_powm_ui (res1, res1, in2i, in3);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm_ui, in1, in2, in3);
+
+ mpz_set (res1, in3);
+ mpz_powm_ui (res1, in1, in2i, res1);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_powm_ui, in1, in2, in3);
+ }
+
+ {
+ r1 = mpz_gcd_ui (ref1, in1, in2i);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ r2 = mpz_gcd_ui (res1, res1, in2i);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_gcd_ui, in1, in2, NULL);
+ }
+
+ if (mpz_sgn (in2) != 0)
+ {
+ /* Test mpz_remove */
+ mp_bitcnt_t refretval, retval;
+ refretval = mpz_remove (ref1, in1, in2);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, in1);
+ retval = mpz_remove (res1, res1, in2);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
+ FAIL2 (mpz_remove, in1, in2, NULL);
+
+ mpz_set (res1, in2);
+ retval = mpz_remove (res1, in1, res1);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
+ FAIL2 (mpz_remove, in1, in2, NULL);
+ }
+
+ if (mpz_sgn (in2) != 0)
+ {
+ /* Test mpz_divexact */
+ mpz_mul (t, in1, in2);
+ mpz_divexact (ref1, t, in2);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, t);
+ mpz_divexact (res1, res1, in2);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_divexact, t, in2, NULL);
+
+ mpz_set (res1, in2);
+ mpz_divexact (res1, t, res1);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_divexact, t, in2, NULL);
+ }
+
+ if (mpz_sgn (in2) > 0)
+ {
+ /* Test mpz_divexact_gcd, same as mpz_divexact */
+ mpz_mul (t, in1, in2);
+ mpz_divexact_gcd (ref1, t, in2);
+ MPZ_CHECK_FORMAT (ref1);
+
+ mpz_set (res1, t);
+ mpz_divexact_gcd (res1, res1, in2);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_divexact_gcd, t, in2, NULL);
+
+ mpz_set (res1, in2);
+ mpz_divexact_gcd (res1, t, res1);
+ MPZ_CHECK_FORMAT (res1);
+ if (mpz_cmp (ref1, res1) != 0)
+ FAIL2 (mpz_divexact_gcd, t, in2, NULL);
+ }
+ }
+
+ if (isatty (fileno (stdout)))
+ printf ("\r%20s", "");
+
+ mpz_clear (bs);
+ mpz_clear (in1);
+ mpz_clear (in2);
+ mpz_clear (in3);
+ mpz_clear (ref1);
+ mpz_clear (ref2);
+ mpz_clear (ref3);
+ mpz_clear (res1);
+ mpz_clear (res2);
+ mpz_clear (res3);
+ mpz_clear (t);
+
+ if (isatty (fileno (stdout)))
+ printf ("\r");
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump (const char *name, mpz_t in1, mpz_t in2, mpz_t in3)
+{
+ printf ("failure in %s (", name);
+ 0 && mpz_out_str (stdout, -16, in1);
+ if (in2 != NULL)
+ {
+ printf (" ");
+ 0 && mpz_out_str (stdout, -16, in2);
+ }
+ if (in3 != NULL)
+ {
+ printf (" ");
+ 0 && mpz_out_str (stdout, -16, in3);
+ }
+ printf (")\n");
+}
+
+#endif /* ! DLL_EXPORT */
diff --git a/gmp/tests/mpz/t-addsub.c b/gmp/tests/mpz/t-addsub.c
new file mode 100644
index 0000000000..bf89841150
--- /dev/null
+++ b/gmp/tests/mpz/t-addsub.c
@@ -0,0 +1,122 @@
+/* Test mpz_add, mpz_sub, mpz_add_ui, mpz_sub_ui, and mpz_ui_sub.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+void debug_mp (mpz_t, int);
+void dump_abort (int, const char *, mpz_t, mpz_t);
+
+int
+main (int argc, char **argv)
+{
+ mpz_t op1, op2, r1, r2;
+ mp_size_t op1n, op2n;
+ unsigned long int op2long;
+ int i;
+ int reps = 100000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (r1);
+ mpz_init (r2);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 10 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ op1n = mpz_get_ui (bs);
+ mpz_rrandomb (op1, rands, op1n);
+
+ mpz_urandomb (bs, rands, size_range);
+ op2n = mpz_get_ui (bs);
+ mpz_rrandomb (op2, rands, op2n);
+
+ mpz_urandomb (bs, rands, 2);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (op1, op1);
+ if ((bsi & 2) != 0)
+ mpz_neg (op2, op2);
+
+ /* printf ("%ld %ld\n", SIZ (multiplier), SIZ (multiplicand)); */
+
+ mpz_add (r1, op1, op2);
+ mpz_sub (r2, r1, op2);
+ if (mpz_cmp (r2, op1) != 0)
+ dump_abort (i, "mpz_add or mpz_sub incorrect", op1, op2);
+
+ if (mpz_fits_ulong_p (op2))
+ {
+ op2long = mpz_get_ui (op2);
+ mpz_add_ui (r1, op1, op2long);
+ mpz_sub_ui (r2, r1, op2long);
+ if (mpz_cmp (r2, op1) != 0)
+ dump_abort (i, "mpz_add_ui or mpz_sub_ui incorrect", op1, op2);
+
+ mpz_ui_sub (r1, op2long, op1);
+ mpz_sub_ui (r2, op1, op2long);
+ mpz_neg (r2, r2);
+ if (mpz_cmp (r1, r2) != 0)
+ dump_abort (i, "mpz_add_ui or mpz_ui_sub incorrect", op1, op2);
+ }
+ }
+
+ mpz_clear (bs);
+ mpz_clear (op1);
+ mpz_clear (op2);
+ mpz_clear (r1);
+ mpz_clear (r2);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort (int i, const char *s, mpz_t op1, mpz_t op2)
+{
+ fprintf (stderr, "ERROR: %s in test %d\n", s, i);
+ fprintf (stderr, "op1 = "); debug_mp (op1, -16);
+ fprintf (stderr, "op2 = "); debug_mp (op2, -16);
+ abort();
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/t-aorsmul.c b/gmp/tests/mpz/t-aorsmul.c
new file mode 100644
index 0000000000..918725fdcb
--- /dev/null
+++ b/gmp/tests/mpz/t-aorsmul.c
@@ -0,0 +1,422 @@
+/* Test mpz_addmul, mpz_addmul_ui, mpz_submul, mpz_submul_ui.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#define M GMP_NUMB_MAX
+
+
+void
+check_one_inplace (mpz_srcptr w, mpz_srcptr y)
+{
+ mpz_t want, got;
+
+ mpz_init (want);
+ mpz_init (got);
+
+ mpz_mul (want, w, y);
+ mpz_add (want, w, want);
+ mpz_set (got, w);
+ mpz_addmul (got, got, y);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (want, got) != 0)
+ {
+ printf ("mpz_addmul inplace fail\n");
+ fail:
+ mpz_trace ("w", w);
+ mpz_trace ("y", y);
+ mpz_trace ("want", want);
+ mpz_trace ("got ", got);
+ abort ();
+ }
+
+ mpz_mul (want, w, y);
+ mpz_sub (want, w, want);
+ mpz_set (got, w);
+ mpz_submul (got, got, y);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (want, got) != 0)
+ {
+ printf ("mpz_submul inplace fail\n");
+ goto fail;
+ }
+
+ mpz_clear (want);
+ mpz_clear (got);
+}
+
+void
+check_one_ui_inplace (mpz_ptr w, unsigned long y)
+{
+ mpz_t want, got;
+
+ mpz_init (want);
+ mpz_init (got);
+
+ mpz_mul_ui (want, w, (unsigned long) y);
+ mpz_add (want, w, want);
+ mpz_set (got, w);
+ mpz_addmul_ui (got, got, (unsigned long) y);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (want, got) != 0)
+ {
+ printf ("mpz_addmul_ui fail\n");
+ fail:
+ mpz_trace ("w", w);
+ printf ("y=0x%lX %lu\n", y, y);
+ mpz_trace ("want", want);
+ mpz_trace ("got ", got);
+ abort ();
+ }
+
+ mpz_mul_ui (want, w, y);
+ mpz_sub (want, w, want);
+ mpz_set (got, w);
+ mpz_submul_ui (got, got, y);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (want, got) != 0)
+ {
+ printf ("mpz_submul_ui fail\n");
+ goto fail;
+ }
+
+ mpz_clear (want);
+ mpz_clear (got);
+}
+
+void
+check_all_inplace (mpz_ptr w, mpz_ptr y)
+{
+ int wneg, yneg;
+
+ MPZ_CHECK_FORMAT (w);
+ MPZ_CHECK_FORMAT (y);
+
+ for (wneg = 0; wneg < 2; wneg++)
+ {
+ for (yneg = 0; yneg < 2; yneg++)
+ {
+ check_one_inplace (w, y);
+
+ if (mpz_fits_ulong_p (y))
+ check_one_ui_inplace (w, mpz_get_ui (y));
+
+ mpz_neg (y, y);
+ }
+ mpz_neg (w, w);
+ }
+}
+
+void
+check_one (mpz_srcptr w, mpz_srcptr x, mpz_srcptr y)
+{
+ mpz_t want, got;
+
+ mpz_init (want);
+ mpz_init (got);
+
+ mpz_mul (want, x, y);
+ mpz_add (want, w, want);
+ mpz_set (got, w);
+ mpz_addmul (got, x, y);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (want, got) != 0)
+ {
+ printf ("mpz_addmul fail\n");
+ fail:
+ mpz_trace ("w", w);
+ mpz_trace ("x", x);
+ mpz_trace ("y", y);
+ mpz_trace ("want", want);
+ mpz_trace ("got ", got);
+ abort ();
+ }
+
+ mpz_mul (want, x, y);
+ mpz_sub (want, w, want);
+ mpz_set (got, w);
+ mpz_submul (got, x, y);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (want, got) != 0)
+ {
+ printf ("mpz_submul fail\n");
+ goto fail;
+ }
+
+ mpz_clear (want);
+ mpz_clear (got);
+}
+
+void
+check_one_ui (mpz_ptr w, mpz_ptr x, unsigned long y)
+{
+ mpz_t want, got;
+
+ mpz_init (want);
+ mpz_init (got);
+
+ mpz_mul_ui (want, x, (unsigned long) y);
+ mpz_add (want, w, want);
+ mpz_set (got, w);
+ mpz_addmul_ui (got, x, (unsigned long) y);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (want, got) != 0)
+ {
+ printf ("mpz_addmul_ui fail\n");
+ fail:
+ mpz_trace ("w", w);
+ mpz_trace ("x", x);
+ printf ("y=0x%lX %lu\n", y, y);
+ mpz_trace ("want", want);
+ mpz_trace ("got ", got);
+ abort ();
+ }
+
+ mpz_mul_ui (want, x, y);
+ mpz_sub (want, w, want);
+ mpz_set (got, w);
+ mpz_submul_ui (got, x, y);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (want, got) != 0)
+ {
+ printf ("mpz_submul_ui fail\n");
+ goto fail;
+ }
+
+ mpz_clear (want);
+ mpz_clear (got);
+}
+
+
+void
+check_all (mpz_ptr w, mpz_ptr x, mpz_ptr y)
+{
+ int swap, wneg, xneg, yneg;
+
+ MPZ_CHECK_FORMAT (w);
+ MPZ_CHECK_FORMAT (x);
+ MPZ_CHECK_FORMAT (y);
+
+ for (swap = 0; swap < 2; swap++)
+ {
+ for (wneg = 0; wneg < 2; wneg++)
+ {
+ for (xneg = 0; xneg < 2; xneg++)
+ {
+ for (yneg = 0; yneg < 2; yneg++)
+ {
+ check_one (w, x, y);
+
+ if (mpz_fits_ulong_p (y))
+ check_one_ui (w, x, mpz_get_ui (y));
+
+ mpz_neg (y, y);
+ }
+ mpz_neg (x, x);
+ }
+ mpz_neg (w, w);
+ }
+ mpz_swap (x, y);
+ }
+}
+
+void
+check_data_inplace_ui (void)
+{
+ static const struct {
+ mp_limb_t w[6];
+ unsigned long y;
+
+ } data[] = {
+
+ { { 0 }, 0 },
+ { { 0 }, 1 },
+ { { 1 }, 1 },
+ { { 2 }, 1 },
+
+ { { 123 }, 1 },
+ { { 123 }, ULONG_MAX },
+ { { M }, 1 },
+ { { M }, ULONG_MAX },
+
+ { { 123, 456 }, 1 },
+ { { M, M }, 1 },
+ { { 123, 456 }, ULONG_MAX },
+ { { M, M }, ULONG_MAX },
+
+ { { 123, 456, 789 }, 1 },
+ { { M, M, M }, 1 },
+ { { 123, 456, 789 }, ULONG_MAX },
+ { { M, M, M }, ULONG_MAX },
+ };
+
+ mpz_t w, y;
+ int i;
+
+ mpz_init (w);
+ mpz_init (y);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_n (w, data[i].w, (mp_size_t) numberof(data[i].w));
+ mpz_set_ui (y, data[i].y);
+ check_all_inplace (w, y);
+ }
+
+ mpz_clear (w);
+ mpz_clear (y);
+}
+
+void
+check_data (void)
+{
+ static const struct {
+ mp_limb_t w[6];
+ mp_limb_t x[6];
+ mp_limb_t y[6];
+
+ } data[] = {
+
+ /* reducing to zero */
+ { { 1 }, { 1 }, { 1 } },
+ { { 2 }, { 1 }, { 2 } },
+ { { 0,1 }, { 0,1 }, { 1 } },
+
+ /* reducing to 1 */
+ { { 0,1 }, { M }, { 1 } },
+ { { 0,0,1 }, { M,M }, { 1 } },
+ { { 0,0,0,1 }, { M,M,M }, { 1 } },
+ { { 0,0,0,0,1 }, { M,M,M,M }, { 1 } },
+
+ /* reducing to -1 */
+ { { M }, { 0,1 }, { 1 } },
+ { { M,M }, { 0,0,1 }, { 1 } },
+ { { M,M,M }, { 0,0,0,1 }, { 1 } },
+ { { M,M,M,M }, { 0,0,0,0,1 }, { 1 } },
+
+ /* carry out of addmul */
+ { { M }, { 1 }, { 1 } },
+ { { M,M }, { 1 }, { 1 } },
+ { { M,M,M }, { 1 }, { 1 } },
+
+ /* borrow from submul */
+ { { 0,1 }, { 1 }, { 1 } },
+ { { 0,0,1 }, { 1 }, { 1 } },
+ { { 0,0,0,1 }, { 1 }, { 1 } },
+
+ /* borrow from submul */
+ { { 0,0,1 }, { 0,1 }, { 1 } },
+ { { 0,0,0,1 }, { 0,1 }, { 1 } },
+ { { 0,0,0,0,1 }, { 0,1 }, { 1 } },
+
+ /* more borrow from submul */
+ { { M }, { 0,1 }, { 1 } },
+ { { M }, { 0,0,1 }, { 1 } },
+ { { M }, { 0,0,0,1 }, { 1 } },
+ { { M }, { 0,0,0,0,1 }, { 1 } },
+
+ /* big borrow from submul */
+ { { 0,0,1 }, { M,M }, { M } },
+ { { 0,0,0,1 }, { M,M }, { M } },
+ { { 0,0,0,0,1 }, { M,M }, { M } },
+
+ /* small w */
+ { { 0,1 }, { M,M }, { M } },
+ { { 0,1 }, { M,M,M }, { M } },
+ { { 0,1 }, { M,M,M,M }, { M } },
+ { { 0,1 }, { M,M,M,M,M }, { M } },
+ };
+
+ mpz_t w, x, y;
+ int i;
+
+ mpz_init (w);
+ mpz_init (x);
+ mpz_init (y);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_n (w, data[i].w, (mp_size_t) numberof(data[i].w));
+ mpz_set_n (x, data[i].x, (mp_size_t) numberof(data[i].x));
+ mpz_set_n (y, data[i].y, (mp_size_t) numberof(data[i].y));
+ check_all (w, x, y);
+ }
+
+ mpz_clear (w);
+ mpz_clear (x);
+ mpz_clear (y);
+}
+
+
+void
+check_random (int argc, char *argv[])
+{
+ gmp_randstate_ptr rands = RANDS;
+ mpz_t w, x, y;
+ int i, reps = 2000;
+
+ mpz_init (w);
+ mpz_init (x);
+ mpz_init (y);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_errandomb (w, rands, 5*GMP_LIMB_BITS);
+ mpz_errandomb (x, rands, 5*GMP_LIMB_BITS);
+ mpz_errandomb (y, rands, 5*GMP_LIMB_BITS);
+ check_all (w, x, y);
+ check_all_inplace (w, y);
+
+ mpz_errandomb (w, rands, 5*GMP_LIMB_BITS);
+ mpz_errandomb (x, rands, 5*GMP_LIMB_BITS);
+ mpz_errandomb (y, rands, BITS_PER_ULONG);
+ check_all (w, x, y);
+ check_all_inplace (w, y);
+ }
+
+ mpz_clear (w);
+ mpz_clear (x);
+ mpz_clear (y);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_data ();
+ check_data_inplace_ui ();
+ check_random (argc, argv);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-bin.c b/gmp/tests/mpz/t-bin.c
new file mode 100644
index 0000000000..acce41df9a
--- /dev/null
+++ b/gmp/tests/mpz/t-bin.c
@@ -0,0 +1,266 @@
+/* Exercise mpz_bin_ui and mpz_bin_uiui.
+
+Copyright 2000, 2001, 2010, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Default number of generated tests. */
+#define COUNT 700
+
+void
+try_mpz_bin_ui (mpz_srcptr want, mpz_srcptr n, unsigned long k)
+{
+ mpz_t got;
+
+ mpz_init (got);
+ mpz_bin_ui (got, n, k);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_bin_ui wrong\n");
+ printf (" n="); mpz_out_str (stdout, 10, n); printf ("\n");
+ printf (" k=%lu\n", k);
+ printf (" got="); mpz_out_str (stdout, 10, got); printf ("\n");
+ printf (" want="); mpz_out_str (stdout, 10, want); printf ("\n");
+ abort();
+ }
+ mpz_clear (got);
+}
+
+
+void
+try_mpz_bin_uiui (mpz_srcptr want, unsigned long n, unsigned long k)
+{
+ mpz_t got;
+
+ mpz_init (got);
+ mpz_bin_uiui (got, n, k);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_bin_uiui wrong\n");
+ printf (" n=%lu\n", n);
+ printf (" k=%lu\n", k);
+ printf (" got="); mpz_out_str (stdout, 10, got); printf ("\n");
+ printf (" want="); mpz_out_str (stdout, 10, want); printf ("\n");
+ abort();
+ }
+ mpz_clear (got);
+}
+
+
+void
+samples (void)
+{
+ static const struct {
+ const char *n;
+ unsigned long k;
+ const char *want;
+ } data[] = {
+
+ { "0", 123456, "0" },
+ { "1", 543210, "0" },
+ { "2", 123321, "0" },
+ { "3", 234567, "0" },
+ { "10", 23456, "0" },
+
+ /* negatives, using bin(-n,k)=bin(n+k-1,k) */
+ { "-1", 0, "1" },
+ { "-1", 1, "-1" },
+ { "-1", 2, "1" },
+ { "-1", 3, "-1" },
+ { "-1", 4, "1" },
+
+ { "-2", 0, "1" },
+ { "-2", 1, "-2" },
+ { "-2", 2, "3" },
+ { "-2", 3, "-4" },
+ { "-2", 4, "5" },
+ { "-2", 5, "-6" },
+ { "-2", 6, "7" },
+
+ { "-3", 0, "1" },
+ { "-3", 1, "-3" },
+ { "-3", 2, "6" },
+ { "-3", 3, "-10" },
+ { "-3", 4, "15" },
+ { "-3", 5, "-21" },
+ { "-3", 6, "28" },
+
+ /* A few random values */
+ { "41", 20, "269128937220" },
+ { "62", 37, "147405545359541742" },
+ { "50", 18, "18053528883775" },
+ { "149", 21, "19332950844468483467894649" },
+ };
+
+ mpz_t n, want;
+ int i;
+
+ mpz_init (n);
+ mpz_init (want);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (n, data[i].n, 0);
+ mpz_set_str_or_abort (want, data[i].want, 0);
+
+ try_mpz_bin_ui (want, n, data[i].k);
+
+ if (mpz_fits_ulong_p (n))
+ try_mpz_bin_uiui (want, mpz_get_ui (n), data[i].k);
+ }
+
+ mpz_clear (n);
+ mpz_clear (want);
+}
+
+
+/* Test some bin(2k,k) cases. This produces some biggish numbers to
+ exercise the limb accumulating code. */
+void
+twos (int count)
+{
+ mpz_t n, want;
+ unsigned long k;
+
+ mpz_init (n);
+ mpz_init (want);
+
+ mpz_set_ui (want, (unsigned long) 2);
+ for (k = 1; k < count; k++)
+ {
+ mpz_set_ui (n, 2*k);
+ try_mpz_bin_ui (want, n, k);
+
+ try_mpz_bin_uiui (want, 2*k, k);
+
+ mpz_mul_ui (want, want, 2*(2*k+1));
+ mpz_fdiv_q_ui (want, want, k+1);
+ }
+
+ mpz_clear (n);
+ mpz_clear (want);
+}
+
+/* Test some random bin(n,k) cases. This produces some biggish
+ numbers to exercise the limb accumulating code. */
+void
+randomwalk (int count)
+{
+ mpz_t n_z, want;
+ unsigned long n, k, i, r;
+ int tests;
+ gmp_randstate_ptr rands;
+
+ rands = RANDS;
+ mpz_init (n_z);
+ mpz_init (want);
+
+ k = 3;
+ n = 12;
+ mpz_set_ui (want, (unsigned long) 220); /* binomial(12,3) = 220 */
+
+ for (tests = 1; tests < count; tests++)
+ {
+ r = gmp_urandomm_ui (rands, 62) + 1;
+ for (i = r & 7; i > 0; i--)
+ {
+ n++; k++;
+ mpz_mul_ui (want, want, n);
+ mpz_fdiv_q_ui (want, want, k);
+ }
+ for (i = r >> 3; i > 0; i--)
+ {
+ n++;
+ mpz_mul_ui (want, want, n);
+ mpz_fdiv_q_ui (want, want, n - k);
+ }
+
+ mpz_set_ui (n_z, n);
+ try_mpz_bin_ui (want, n_z, k);
+
+ try_mpz_bin_uiui (want, n, k);
+ }
+
+ mpz_clear (n_z);
+ mpz_clear (want);
+}
+
+
+/* Test all bin(n,k) cases, with 0 <= k <= n + 1 <= count. */
+void
+smallexaustive (unsigned int count)
+{
+ mpz_t n_z, want;
+ unsigned long n, k;
+
+ mpz_init (n_z);
+ mpz_init (want);
+
+ for (n = 0; n < count; n++)
+ {
+ mpz_set_ui (want, (unsigned long) 1);
+ mpz_set_ui (n_z, n);
+ for (k = 0; k <= n; k++)
+ {
+ try_mpz_bin_ui (want, n_z, k);
+ try_mpz_bin_uiui (want, n, k);
+ mpz_mul_ui (want, want, n - k);
+ mpz_fdiv_q_ui (want, want, k + 1);
+ }
+ try_mpz_bin_ui (want, n_z, k);
+ try_mpz_bin_uiui (want, n, k);
+ }
+
+ mpz_clear (n_z);
+ mpz_clear (want);
+}
+
+int
+main (int argc, char **argv)
+{
+ int count;
+
+ if (argc > 1)
+ {
+ char *end;
+ count = strtol (argv[1], &end, 0);
+ if (*end || count <= 0)
+ {
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+ return 1;
+ }
+ }
+ else
+ count = COUNT;
+
+ tests_start ();
+
+ samples ();
+ smallexaustive (count >> 4);
+ twos (count >> 1);
+ randomwalk (count - (count >> 1));
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-cdiv_ui.c b/gmp/tests/mpz/t-cdiv_ui.c
new file mode 100644
index 0000000000..39735a92e9
--- /dev/null
+++ b/gmp/tests/mpz/t-cdiv_ui.c
@@ -0,0 +1,159 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_cdiv_qr_ui, mpz_cdiv_q_ui,
+ mpz_cdiv_r_ui, , mpz_cdiv_ui, mpz_mul_ui.
+
+Copyright 1993, 1994, 1996, 2000-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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void dump_abort (const char *, mpz_t, unsigned long);
+void debug_mp (mpz_t, int);
+
+int
+main (int argc, char **argv)
+{
+ mpz_t dividend;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size;
+ unsigned long divisor;
+ int i;
+ int reps = 10000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+ unsigned long r_rq, r_q, r_r, r;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */
+
+ do
+ {
+ mpz_rrandomb (bs, rands, 64);
+ divisor = mpz_get_ui (bs);
+ }
+ while (divisor == 0);
+
+ mpz_urandomb (bs, rands, size_range);
+ dividend_size = mpz_get_ui (bs);
+ mpz_rrandomb (dividend, rands, dividend_size);
+
+ mpz_urandomb (bs, rands, 2);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (dividend, dividend);
+
+ /* printf ("%ld\n", SIZ (dividend)); */
+
+ r_rq = mpz_cdiv_qr_ui (quotient, remainder, dividend, divisor);
+ r_q = mpz_cdiv_q_ui (quotient2, dividend, divisor);
+ r_r = mpz_cdiv_r_ui (remainder2, dividend, divisor);
+ r = mpz_cdiv_ui (dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort ("quotients from mpz_cdiv_qr_ui and mpz_cdiv_q_ui differ",
+ dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort ("remainders from mpz_cdiv_qr_ui and mpz_cdiv_r_ui differ",
+ dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort ("quotient sign wrong", dividend, divisor);
+
+ /* Check if the remainder has the opposite sign as the (positive) divisor
+ (quotient rounded towards minus infinity). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if (mpz_cmp_ui (remainder, 0) > 0)
+ dump_abort ("remainder sign wrong", dividend, divisor);
+
+ mpz_mul_ui (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort ("n mod d != n - [n/d]*d", dividend, divisor);
+
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp_ui (remainder, divisor) >= 0)
+ dump_abort ("remainder greater than divisor", dividend, divisor);
+
+ if (mpz_cmp_ui (remainder, r_rq) != 0)
+ dump_abort ("remainder returned from mpz_cdiv_qr_ui is wrong",
+ dividend, divisor);
+ if (mpz_cmp_ui (remainder, r_q) != 0)
+ dump_abort ("remainder returned from mpz_cdiv_q_ui is wrong",
+ dividend, divisor);
+ if (mpz_cmp_ui (remainder, r_r) != 0)
+ dump_abort ("remainder returned from mpz_cdiv_r_ui is wrong",
+ dividend, divisor);
+ if (mpz_cmp_ui (remainder, r) != 0)
+ dump_abort ("remainder returned from mpz_cdiv_ui is wrong",
+ dividend, divisor);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (dividend);
+ mpz_clear (quotient);
+ mpz_clear (remainder);
+ mpz_clear (quotient2);
+ mpz_clear (remainder2);
+ mpz_clear (temp);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort (const char *str, mpz_t dividend, unsigned long divisor)
+{
+ fprintf (stderr, "ERROR: %s\n", str);
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = %lX\n", divisor);
+ abort();
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/t-cmp.c b/gmp/tests/mpz/t-cmp.c
new file mode 100644
index 0000000000..cf0474e7f1
--- /dev/null
+++ b/gmp/tests/mpz/t-cmp.c
@@ -0,0 +1,182 @@
+/* Test mpz_cmp and mpz_cmpabs.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Nothing sophisticated here, just exercise some combinations of sizes and
+ signs. */
+
+
+void
+check_one (mpz_ptr x, mpz_ptr y, int want_cmp, int want_cmpabs)
+{
+ int got;
+
+ got = mpz_cmp (x, y);
+ if (( got < 0) != (want_cmp < 0)
+ || (got == 0) != (want_cmp == 0)
+ || (got > 0) != (want_cmp > 0))
+ {
+ printf ("mpz_cmp got %d want %d\n", got, want_cmp);
+ mpz_trace ("x", x);
+ mpz_trace ("y", y);
+ abort ();
+ }
+
+ got = mpz_cmpabs (x, y);
+ if (( got < 0) != (want_cmpabs < 0)
+ || (got == 0) != (want_cmpabs == 0)
+ || (got > 0) != (want_cmpabs > 0))
+ {
+ printf ("mpz_cmpabs got %d want %d\n", got, want_cmpabs);
+ mpz_trace ("x", x);
+ mpz_trace ("y", y);
+ abort ();
+ }
+}
+
+
+void
+check_all (mpz_ptr x, mpz_ptr y, int want_cmp, int want_cmpabs)
+{
+ check_one (x, y, want_cmp, want_cmpabs);
+ check_one (y, x, -want_cmp, -want_cmpabs);
+
+ mpz_neg (x, x);
+ mpz_neg (y, y);
+ want_cmp = -want_cmp;
+
+ check_one (x, y, want_cmp, want_cmpabs);
+ check_one (y, x, -want_cmp, -want_cmpabs);
+}
+
+
+#define SET1(z,size, n) \
+ SIZ(z) = size; PTR(z)[0] = n
+
+#define SET2(z,size, n1,n0) \
+ SIZ(z) = size; PTR(z)[1] = n1; PTR(z)[0] = n0
+
+#define SET4(z,size, n3,n2,n1,n0) \
+ SIZ(z) = size; PTR(z)[3] = n3; PTR(z)[2] = n2; PTR(z)[1] = n1; PTR(z)[0] = n0
+
+void
+check_various (void)
+{
+ mpz_t x, y;
+
+ mpz_init (x);
+ mpz_init (y);
+
+ mpz_realloc (x, (mp_size_t) 20);
+ mpz_realloc (y, (mp_size_t) 20);
+
+ /* 0 cmp 0, junk in low limbs */
+ SET1 (x,0, 123);
+ SET1 (y,0, 456);
+ check_all (x, y, 0, 0);
+
+
+ /* 123 cmp 0 */
+ SET1 (x,1, 123);
+ SET1 (y,0, 456);
+ check_all (x, y, 1, 1);
+
+ /* 123:456 cmp 0 */
+ SET2 (x,2, 456,123);
+ SET1 (y,0, 9999);
+ check_all (x, y, 1, 1);
+
+
+ /* 123 cmp 123 */
+ SET1(x,1, 123);
+ SET1(y,1, 123);
+ check_all (x, y, 0, 0);
+
+ /* -123 cmp 123 */
+ SET1(x,-1, 123);
+ SET1(y,1, 123);
+ check_all (x, y, -1, 0);
+
+
+ /* 123 cmp 456 */
+ SET1(x,1, 123);
+ SET1(y,1, 456);
+ check_all (x, y, -1, -1);
+
+ /* -123 cmp 456 */
+ SET1(x,-1, 123);
+ SET1(y,1, 456);
+ check_all (x, y, -1, -1);
+
+ /* 123 cmp -456 */
+ SET1(x,1, 123);
+ SET1(y,-1, 456);
+ check_all (x, y, 1, -1);
+
+
+ /* 1:0 cmp 1:0 */
+ SET2 (x,2, 1,0);
+ SET2 (y,2, 1,0);
+ check_all (x, y, 0, 0);
+
+ /* -1:0 cmp 1:0 */
+ SET2 (x,-2, 1,0);
+ SET2 (y,2, 1,0);
+ check_all (x, y, -1, 0);
+
+
+ /* 2:0 cmp 1:0 */
+ SET2 (x,2, 2,0);
+ SET2 (y,2, 1,0);
+ check_all (x, y, 1, 1);
+
+
+ /* 4:3:2:1 cmp 2:1 */
+ SET4 (x,4, 4,3,2,1);
+ SET2 (y,2, 2,1);
+ check_all (x, y, 1, 1);
+
+ /* -4:3:2:1 cmp 2:1 */
+ SET4 (x,-4, 4,3,2,1);
+ SET2 (y,2, 2,1);
+ check_all (x, y, -1, 1);
+
+
+ mpz_clear (x);
+ mpz_clear (y);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_various ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-cmp_d.c b/gmp/tests/mpz/t-cmp_d.c
new file mode 100644
index 0000000000..c9877fc521
--- /dev/null
+++ b/gmp/tests/mpz/t-cmp_d.c
@@ -0,0 +1,293 @@
+/* Test mpz_cmp_d and mpz_cmpabs_d.
+
+Copyright 2001-2003, 2005 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* FIXME: Not sure if the tests here are exhaustive. Ought to try to get
+ each possible exit from mpz_cmp_d (and mpz_cmpabs_d) exercised. */
+
+
+#define SGN(n) ((n) > 0 ? 1 : (n) < 0 ? -1 : 0)
+
+
+void
+check_one (const char *name, mpz_srcptr x, double y, int cmp, int cmpabs)
+{
+ int got;
+
+ got = mpz_cmp_d (x, y);
+ if (SGN(got) != cmp)
+ {
+ int i;
+ printf ("mpz_cmp_d wrong (from %s)\n", name);
+ printf (" got %d\n", got);
+ printf (" want %d\n", cmp);
+ fail:
+ mpz_trace (" x", x);
+ printf (" y %g\n", y);
+ mp_trace_base=-16;
+ mpz_trace (" x", x);
+ printf (" y %g\n", y);
+ printf (" y");
+ for (i = 0; i < sizeof(y); i++)
+ printf (" %02X", (unsigned) ((unsigned char *) &y)[i]);
+ printf ("\n");
+ abort ();
+ }
+
+ got = mpz_cmpabs_d (x, y);
+ if (SGN(got) != cmpabs)
+ {
+ printf ("mpz_cmpabs_d wrong\n");
+ printf (" got %d\n", got);
+ printf (" want %d\n", cmpabs);
+ goto fail;
+ }
+}
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *x;
+ double y;
+ int cmp, cmpabs;
+
+ } data[] = {
+
+ { "0", 0.0, 0, 0 },
+
+ { "1", 0.0, 1, 1 },
+ { "-1", 0.0, -1, 1 },
+
+ { "1", 0.5, 1, 1 },
+ { "-1", -0.5, -1, 1 },
+
+ { "0", 1.0, -1, -1 },
+ { "0", -1.0, 1, -1 },
+
+ { "0x1000000000000000000000000000000000000000000000000", 1.0, 1, 1 },
+ { "-0x1000000000000000000000000000000000000000000000000", 1.0, -1, 1 },
+
+ { "0", 1e100, -1, -1 },
+ { "0", -1e100, 1, -1 },
+
+ { "2", 1.5, 1, 1 },
+ { "2", -1.5, 1, 1 },
+ { "-2", 1.5, -1, 1 },
+ { "-2", -1.5, -1, 1 },
+ };
+
+ mpz_t x;
+ int i;
+
+ mpz_init (x);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (x, data[i].x, 0);
+ check_one ("check_data", x, data[i].y, data[i].cmp, data[i].cmpabs);
+ }
+
+ mpz_clear (x);
+}
+
+
+/* Equality of integers with up to 53 bits */
+void
+check_onebits (void)
+{
+ mpz_t x, x2;
+ double y;
+ int i;
+
+ mpz_init_set_ui (x, 0L);
+ mpz_init (x2);
+
+ for (i = 0; i < 512; i++)
+ {
+ mpz_mul_2exp (x, x, 1);
+ mpz_add_ui (x, x, 1L);
+
+ y = mpz_get_d (x);
+ mpz_set_d (x2, y);
+
+ /* stop if any truncation is occurring */
+ if (mpz_cmp (x, x2) != 0)
+ break;
+
+ check_one ("check_onebits", x, y, 0, 0);
+ check_one ("check_onebits", x, -y, 1, 0);
+ mpz_neg (x, x);
+ check_one ("check_onebits", x, y, -1, 0);
+ check_one ("check_onebits", x, -y, 0, 0);
+ mpz_neg (x, x);
+ }
+
+ mpz_clear (x);
+ mpz_clear (x2);
+}
+
+
+/* With the mpz differing by 1, in a limb position possibly below the double */
+void
+check_low_z_one (void)
+{
+ mpz_t x;
+ double y;
+ unsigned long i;
+
+ mpz_init (x);
+
+ /* FIXME: It'd be better to base this on the float format. */
+#if defined (__vax) || defined (__vax__)
+#define LIM 127 /* vax fp numbers have limited range */
+#else
+#define LIM 512
+#endif
+
+ for (i = 1; i < LIM; i++)
+ {
+ mpz_set_ui (x, 1L);
+ mpz_mul_2exp (x, x, i);
+ y = mpz_get_d (x);
+
+ check_one ("check_low_z_one", x, y, 0, 0);
+ check_one ("check_low_z_one", x, -y, 1, 0);
+ mpz_neg (x, x);
+ check_one ("check_low_z_one", x, y, -1, 0);
+ check_one ("check_low_z_one", x, -y, 0, 0);
+ mpz_neg (x, x);
+
+ mpz_sub_ui (x, x, 1);
+
+ check_one ("check_low_z_one", x, y, -1, -1);
+ check_one ("check_low_z_one", x, -y, 1, -1);
+ mpz_neg (x, x);
+ check_one ("check_low_z_one", x, y, -1, -1);
+ check_one ("check_low_z_one", x, -y, 1, -1);
+ mpz_neg (x, x);
+
+ mpz_add_ui (x, x, 2);
+
+ check_one ("check_low_z_one", x, y, 1, 1);
+ check_one ("check_low_z_one", x, -y, 1, 1);
+ mpz_neg (x, x);
+ check_one ("check_low_z_one", x, y, -1, 1);
+ check_one ("check_low_z_one", x, -y, -1, 1);
+ mpz_neg (x, x);
+ }
+
+ mpz_clear (x);
+}
+
+/* Comparing 1 and 1+2^-n. "y" is volatile to make gcc store and fetch it,
+ which forces it to a 64-bit double, whereas on x86 it would otherwise
+ remain on the float stack as an 80-bit long double. */
+void
+check_one_2exp (void)
+{
+ double e;
+ mpz_t x;
+ volatile double y;
+ int i;
+
+ mpz_init (x);
+
+ e = 1.0;
+ for (i = 0; i < 128; i++)
+ {
+ e /= 2.0;
+ y = 1.0 + e;
+ if (y == 1.0)
+ break;
+
+ mpz_set_ui (x, 1L);
+ check_one ("check_one_2exp", x, y, -1, -1);
+ check_one ("check_one_2exp", x, -y, 1, -1);
+
+ mpz_set_si (x, -1L);
+ check_one ("check_one_2exp", x, y, -1, -1);
+ check_one ("check_one_2exp", x, -y, 1, -1);
+ }
+
+ mpz_clear (x);
+}
+
+void
+check_infinity (void)
+{
+ mpz_t x;
+ double y = tests_infinity_d ();
+ if (y == 0.0)
+ return;
+
+ mpz_init (x);
+
+ /* 0 cmp inf */
+ mpz_set_ui (x, 0L);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ /* 123 cmp inf */
+ mpz_set_ui (x, 123L);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ /* -123 cmp inf */
+ mpz_set_si (x, -123L);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ /* 2^5000 cmp inf */
+ mpz_set_ui (x, 1L);
+ mpz_mul_2exp (x, x, 5000L);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ /* -2^5000 cmp inf */
+ mpz_neg (x, x);
+ check_one ("check_infinity", x, y, -1, -1);
+ check_one ("check_infinity", x, -y, 1, -1);
+
+ mpz_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ check_data ();
+ check_onebits ();
+ check_low_z_one ();
+ check_one_2exp ();
+ check_infinity ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-cmp_si.c b/gmp/tests/mpz/t-cmp_si.c
new file mode 100644
index 0000000000..97fdbcaae3
--- /dev/null
+++ b/gmp/tests/mpz/t-cmp_si.c
@@ -0,0 +1,102 @@
+/* Test mpz_cmp_si.
+
+Copyright 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define SGN(x) ((x) < 0 ? -1 : (x) == 0 ? 0 : 1)
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *a, *b;
+ int want;
+ } data[] = {
+ { "0", "1", -1 },
+ { "0", "0", 0 },
+ { "0", "-1", 1 },
+
+ { "1", "1", 0 },
+ { "1", "0", 1 },
+ { "1", "-1", 1 },
+
+ { "-1", "1", -1 },
+ { "-1", "0", -1 },
+ { "-1", "-1", 0 },
+
+ { "0", "-0x80000000", 1 },
+ { "0x80000000", "-0x80000000", 1 },
+ { "0x80000001", "-0x80000000", 1 },
+ { "-0x80000000", "-0x80000000", 0 },
+ { "-0x80000001", "-0x80000000", -1 },
+
+ { "0", "-0x8000000000000000", 1 },
+ { "0x8000000000000000", "-0x8000000000000000", 1 },
+ { "0x8000000000000001", "-0x8000000000000000", 1 },
+ { "-0x8000000000000000", "-0x8000000000000000", 0 },
+ { "-0x8000000000000001", "-0x8000000000000000", -1 },
+ };
+
+ mpz_t a, bz;
+ long b;
+ int got;
+ int i;
+
+ mpz_init (a);
+ mpz_init (bz);
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (a, data[i].a, 0);
+ mpz_set_str_or_abort (bz, data[i].b, 0);
+
+ if (mpz_fits_slong_p (bz))
+ {
+ b = mpz_get_si (bz);
+ got = mpz_cmp_si (a, b);
+ if (SGN (got) != data[i].want)
+ {
+ printf ("mpz_cmp_si wrong on data[%d]\n", i);
+ printf (" a="); mpz_out_str (stdout, 10, a); printf ("\n");
+ printf (" b=%ld\n", b);
+ printf (" got=%d\n", got);
+ printf (" want=%d\n", data[i].want);
+ abort();
+ }
+ }
+ }
+
+ mpz_clear (a);
+ mpz_clear (bz);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-cong.c b/gmp/tests/mpz/t-cong.c
new file mode 100644
index 0000000000..1227335ec5
--- /dev/null
+++ b/gmp/tests/mpz/t-cong.c
@@ -0,0 +1,227 @@
+/* test mpz_congruent_p and mpz_congruent_ui_p
+
+Copyright 2001, 2002, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want)
+{
+ int got;
+ int swap;
+
+ for (swap = 0; swap <= 1; swap++)
+ {
+ got = (mpz_congruent_p (a, c, d) != 0);
+ if (want != got)
+ {
+ printf ("mpz_congruent_p wrong\n");
+ printf (" expected %d got %d\n", want, got);
+ mpz_trace (" a", a);
+ mpz_trace (" c", c);
+ mpz_trace (" d", d);
+ mp_trace_base = -16;
+ mpz_trace (" a", a);
+ mpz_trace (" c", c);
+ mpz_trace (" d", d);
+ abort ();
+ }
+
+ if (mpz_fits_ulong_p (c) && mpz_fits_ulong_p (d))
+ {
+ unsigned long uc = mpz_get_ui (c);
+ unsigned long ud = mpz_get_ui (d);
+ got = (mpz_congruent_ui_p (a, uc, ud) != 0);
+ if (want != got)
+ {
+ printf ("mpz_congruent_ui_p wrong\n");
+ printf (" expected %d got %d\n", want, got);
+ mpz_trace (" a", a);
+ printf (" c=%lu\n", uc);
+ printf (" d=%lu\n", ud);
+ mp_trace_base = -16;
+ mpz_trace (" a", a);
+ printf (" c=0x%lX\n", uc);
+ printf (" d=0x%lX\n", ud);
+ abort ();
+ }
+ }
+
+ MPZ_SRCPTR_SWAP (a, c);
+ }
+}
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *a;
+ const char *c;
+ const char *d;
+ int want;
+
+ } data[] = {
+
+ /* strict equality mod 0 */
+ { "0", "0", "0", 1 },
+ { "11", "11", "0", 1 },
+ { "3", "11", "0", 0 },
+
+ /* anything congruent mod 1 */
+ { "0", "0", "1", 1 },
+ { "1", "0", "1", 1 },
+ { "0", "1", "1", 1 },
+ { "123", "456", "1", 1 },
+ { "0x123456789123456789", "0x987654321987654321", "1", 1 },
+
+ /* csize==1, dsize==2 changing to 1 after stripping 2s */
+ { "0x3333333333333333", "0x33333333",
+ "0x180000000", 1 },
+ { "0x33333333333333333333333333333333", "0x3333333333333333",
+ "0x18000000000000000", 1 },
+
+ /* another dsize==2 becoming 1, with opposite signs this time */
+ { "0x444444441",
+ "-0x22222221F",
+ "0x333333330", 1 },
+ { "0x44444444444444441",
+ "-0x2222222222222221F",
+ "0x33333333333333330", 1 },
+ };
+
+ mpz_t a, c, d;
+ int i;
+
+ mpz_init (a);
+ mpz_init (c);
+ mpz_init (d);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (a, data[i].a, 0);
+ mpz_set_str_or_abort (c, data[i].c, 0);
+ mpz_set_str_or_abort (d, data[i].d, 0);
+ check_one (a, c, d, data[i].want);
+ }
+
+ mpz_clear (a);
+ mpz_clear (c);
+ mpz_clear (d);
+}
+
+
+void
+check_random (int argc, char *argv[])
+{
+ gmp_randstate_ptr rands = RANDS;
+ mpz_t a, c, d, ra, rc;
+ int i;
+ int want;
+ int reps = 10000;
+ mpz_t bs;
+ unsigned long size_range, size;
+
+ if (argc >= 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (bs);
+
+ mpz_init (a);
+ mpz_init (c);
+ mpz_init (d);
+ mpz_init (ra);
+ mpz_init (rc);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */
+
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (a, rands, size);
+
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */
+
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (c, rands, size);
+
+ do
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */
+
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (d, rands, size);
+ }
+ while (SIZ(d) == 0);
+
+ mpz_negrandom (a, rands);
+ MPZ_CHECK_FORMAT (a);
+ mpz_negrandom (c, rands);
+ MPZ_CHECK_FORMAT (c);
+ mpz_negrandom (d, rands);
+
+ mpz_fdiv_r (ra, a, d);
+ mpz_fdiv_r (rc, c, d);
+
+ want = (mpz_cmp (ra, rc) == 0);
+ check_one (a, c, d, want);
+
+ mpz_sub (ra, ra, rc);
+ mpz_sub (a, a, ra);
+ MPZ_CHECK_FORMAT (a);
+ check_one (a, c, d, 1);
+
+ if (! mpz_pow2abs_p (d))
+ {
+ refmpz_combit (a, urandom() % (8*GMP_LIMB_BITS));
+ check_one (a, c, d, 0);
+ }
+ }
+
+ mpz_clear (bs);
+
+ mpz_clear (a);
+ mpz_clear (c);
+ mpz_clear (d);
+ mpz_clear (ra);
+ mpz_clear (rc);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ check_data ();
+ check_random (argc, argv);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-cong_2exp.c b/gmp/tests/mpz/t-cong_2exp.c
new file mode 100644
index 0000000000..3ccb5aab04
--- /dev/null
+++ b/gmp/tests/mpz/t-cong_2exp.c
@@ -0,0 +1,209 @@
+/* test mpz_congruent_2exp_p */
+
+/*
+Copyright 2001, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpz_srcptr a, mpz_srcptr c, unsigned long d, int want)
+{
+ mpz_t diff, d2exp;
+ int got;
+ int swap;
+
+ for (swap = 0; swap <= 1; swap++)
+ {
+ got = (mpz_congruent_2exp_p (a, c, d) != 0);
+ if (want != got)
+ {
+ mpz_init (diff);
+ mpz_init (d2exp);
+
+ mpz_sub (diff, a, c);
+ mpz_set_ui (d2exp, 1L);
+ mpz_mul_2exp (d2exp, d2exp, d);
+
+ printf ("mpz_congruent_2exp_p wrong\n");
+ printf (" expected %d got %d\n", want, got);
+ mpz_trace (" a", a);
+ mpz_trace (" c", c);
+ mpz_trace (" a-c", diff);
+ mpz_trace (" 2^d", d2exp);
+ printf (" d=%lu\n", d);
+
+ mp_trace_base = -16;
+ mpz_trace (" a", a);
+ mpz_trace (" c", c);
+ mpz_trace (" a-c", diff);
+ mpz_trace (" 2^d", d2exp);
+ printf (" d=0x%lX\n", d);
+ abort ();
+ }
+
+ MPZ_SRCPTR_SWAP (a, c);
+ }
+}
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *a;
+ const char *c;
+ unsigned long d;
+ int want;
+
+ } data[] = {
+
+ /* anything is congruent mod 1 */
+ { "0", "0", 0, 1 },
+ { "1", "0", 0, 1 },
+ { "0", "1", 0, 1 },
+ { "123", "-456", 0, 1 },
+ { "0x123456789123456789", "0x987654321987654321", 0, 1 },
+ { "0xfffffffffffffffffffffffffffffff7", "-0x9", 129, 0 },
+ { "0xfffffffffffffffffffffffffffffff6", "-0xa", 128, 1 },
+
+ };
+
+ mpz_t a, c;
+ int i;
+
+ mpz_init (a);
+ mpz_init (c);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (a, data[i].a, 0);
+ mpz_set_str_or_abort (c, data[i].c, 0);
+ check_one (a, c, data[i].d, data[i].want);
+ }
+
+ mpz_clear (a);
+ mpz_clear (c);
+}
+
+
+void
+check_random (int reps)
+{
+ gmp_randstate_ptr rands = RANDS;
+ unsigned long d;
+ mpz_t a, c, ra, rc;
+ int i;
+
+ mpz_init (a);
+ mpz_init (c);
+ mpz_init (ra);
+ mpz_init (rc);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_errandomb (a, rands, 8*GMP_LIMB_BITS);
+ mpz_errandomb (c, rands, 8*GMP_LIMB_BITS);
+ d = urandom() % (8*GMP_LIMB_BITS);
+
+ mpz_mul_2exp (a, a, urandom() % (2*GMP_LIMB_BITS));
+ mpz_mul_2exp (c, c, urandom() % (2*GMP_LIMB_BITS));
+
+ mpz_negrandom (a, rands);
+ mpz_negrandom (c, rands);
+
+ mpz_fdiv_r_2exp (ra, a, d);
+ mpz_fdiv_r_2exp (rc, c, d);
+
+ mpz_sub (ra, ra, rc);
+ if (mpz_cmp_ui (ra, 0) != 0)
+ {
+ check_one (a, c, d, 0);
+ mpz_sub (a, a, ra);
+ }
+ check_one (a, c, d, 1);
+ if (d != 0)
+ {
+ mpz_combit (a, urandom() % d);
+ check_one (a, c, d, 0);
+ }
+ }
+
+ mpz_clear (a);
+ mpz_clear (c);
+ mpz_clear (ra);
+ mpz_clear (rc);
+}
+
+void
+check_random_bits (int reps)
+{
+ gmp_randstate_ptr rands = RANDS;
+ mp_bitcnt_t ea, ec, en, d;
+ mp_bitcnt_t m = 10 * GMP_LIMB_BITS;
+ mpz_t a, c;
+ int i;
+
+ mpz_init2 (a, m + 1);
+ mpz_init2 (c, m);
+
+ for (i = 0; i < reps; i++)
+ {
+ d = urandom() % m;
+ ea = urandom() % m;
+ ec = urandom() % m;
+ en = urandom() % m;
+
+ mpz_set_ui (c, 0);
+ mpz_setbit (c, en);
+
+ mpz_set_ui (a, 0);
+ mpz_setbit (a, ec);
+ mpz_sub (c , a, c);
+
+ mpz_set_ui (a, 0);
+ mpz_setbit (a, ea);
+ mpz_add (a , a, c);
+
+ check_one (a, c, d, ea >= d);
+ }
+
+ mpz_clear (a);
+ mpz_clear (c);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int reps = 5000;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ check_data ();
+ check_random (reps);
+ check_random_bits (reps);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-div_2exp.c b/gmp/tests/mpz/t-div_2exp.c
new file mode 100644
index 0000000000..1620698b12
--- /dev/null
+++ b/gmp/tests/mpz/t-div_2exp.c
@@ -0,0 +1,224 @@
+/* Test mpz_[cft]div_[qr]_2exp.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* If the remainder is in the correct range and q*d+r is correct, then q
+ must have rounded correctly. */
+
+void
+check_one (mpz_srcptr a, unsigned long d)
+{
+ mpz_t q, r, p, d2exp;
+ int inplace;
+
+ mpz_init (d2exp);
+ mpz_init (q);
+ mpz_init (r);
+ mpz_init (p);
+
+ mpz_set_ui (d2exp, 1L);
+ mpz_mul_2exp (d2exp, d2exp, d);
+
+#define INPLACE(fun,dst,src,d) \
+ if (inplace) \
+ { \
+ mpz_set (dst, src); \
+ fun (dst, dst, d); \
+ } \
+ else \
+ fun (dst, src, d);
+
+ for (inplace = 0; inplace <= 1; inplace++)
+ {
+ INPLACE (mpz_fdiv_q_2exp, q, a, d);
+ INPLACE (mpz_fdiv_r_2exp, r, a, d);
+
+ mpz_mul_2exp (p, q, d);
+ mpz_add (p, p, r);
+ if (mpz_sgn (r) < 0 || mpz_cmp (r, d2exp) >= 0)
+ {
+ printf ("mpz_fdiv_r_2exp result out of range\n");
+ goto error;
+ }
+ if (mpz_cmp (p, a) != 0)
+ {
+ printf ("mpz_fdiv_[qr]_2exp doesn't multiply back\n");
+ goto error;
+ }
+
+
+ INPLACE (mpz_cdiv_q_2exp, q, a, d);
+ INPLACE (mpz_cdiv_r_2exp, r, a, d);
+
+ mpz_mul_2exp (p, q, d);
+ mpz_add (p, p, r);
+ if (mpz_sgn (r) > 0 || mpz_cmpabs (r, d2exp) >= 0)
+ {
+ printf ("mpz_cdiv_r_2exp result out of range\n");
+ goto error;
+ }
+ if (mpz_cmp (p, a) != 0)
+ {
+ printf ("mpz_cdiv_[qr]_2exp doesn't multiply back\n");
+ goto error;
+ }
+
+
+ INPLACE (mpz_tdiv_q_2exp, q, a, d);
+ INPLACE (mpz_tdiv_r_2exp, r, a, d);
+
+ mpz_mul_2exp (p, q, d);
+ mpz_add (p, p, r);
+ if (mpz_sgn (r) != 0 && mpz_sgn (r) != mpz_sgn (a))
+ {
+ printf ("mpz_tdiv_r_2exp result wrong sign\n");
+ goto error;
+ }
+ if (mpz_cmpabs (r, d2exp) >= 0)
+ {
+ printf ("mpz_tdiv_r_2exp result out of range\n");
+ goto error;
+ }
+ if (mpz_cmp (p, a) != 0)
+ {
+ printf ("mpz_tdiv_[qr]_2exp doesn't multiply back\n");
+ goto error;
+ }
+ }
+
+ mpz_clear (d2exp);
+ mpz_clear (q);
+ mpz_clear (r);
+ mpz_clear (p);
+ return;
+
+
+ error:
+ mpz_trace ("a", a);
+ printf ("d=%lu\n", d);
+ mpz_trace ("q", q);
+ mpz_trace ("r", r);
+ mpz_trace ("p", p);
+
+ mp_trace_base = -16;
+ mpz_trace ("a", a);
+ printf ("d=0x%lX\n", d);
+ mpz_trace ("q", q);
+ mpz_trace ("r", r);
+ mpz_trace ("p", p);
+
+ abort ();
+}
+
+
+void
+check_all (mpz_ptr a, unsigned long d)
+{
+ check_one (a, d);
+ mpz_neg (a, a);
+ check_one (a, d);
+}
+
+
+void
+check_various (void)
+{
+ static const unsigned long table[] = {
+ 0, 1, 2, 3, 4, 5,
+ GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1,
+ 2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1,
+ 3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1,
+ 4*GMP_NUMB_BITS-1, 4*GMP_NUMB_BITS, 4*GMP_NUMB_BITS+1
+ };
+
+ int i, j;
+ unsigned long n, d;
+ mpz_t a;
+
+ mpz_init (a);
+
+ /* a==0, and various d */
+ mpz_set_ui (a, 0L);
+ for (i = 0; i < numberof (table); i++)
+ check_one (a, table[i]);
+
+ /* a==2^n, and various d */
+ for (i = 0; i < numberof (table); i++)
+ {
+ n = table[i];
+ mpz_set_ui (a, 1L);
+ mpz_mul_2exp (a, a, n);
+
+ for (j = 0; j < numberof (table); j++)
+ {
+ d = table[j];
+ check_all (a, d);
+ }
+ }
+
+ mpz_clear (a);
+}
+
+
+void
+check_random (int argc, char *argv[])
+{
+ gmp_randstate_ptr rands = RANDS;
+ int reps = 100;
+ mpz_t a;
+ unsigned long d;
+ int i;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (a);
+
+ for (i = 0; i < reps; i++)
+ {
+ /* exponentially within 2 to 257 bits */
+ mpz_erandomb (a, rands, urandom () % 8 + 2);
+
+ d = urandom () % 256;
+
+ check_all (a, d);
+ }
+
+ mpz_clear (a);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ check_various ();
+ check_random (argc, argv);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-divis.c b/gmp/tests/mpz/t-divis.c
new file mode 100644
index 0000000000..fdfedc82b3
--- /dev/null
+++ b/gmp/tests/mpz/t-divis.c
@@ -0,0 +1,168 @@
+/* test mpz_divisible_p and mpz_divisible_ui_p
+
+Copyright 2001, 2009 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpz_srcptr a, mpz_srcptr d, int want)
+{
+ int got;
+
+ if (mpz_fits_ulong_p (d))
+ {
+ unsigned long u = mpz_get_ui (d);
+ got = (mpz_divisible_ui_p (a, u) != 0);
+ if (want != got)
+ {
+ printf ("mpz_divisible_ui_p wrong\n");
+ printf (" expected %d got %d\n", want, got);
+ mpz_trace (" a", a);
+ printf (" d=%lu\n", u);
+ mp_trace_base = -16;
+ mpz_trace (" a", a);
+ printf (" d=0x%lX\n", u);
+ abort ();
+ }
+ }
+
+ got = (mpz_divisible_p (a, d) != 0);
+ if (want != got)
+ {
+ printf ("mpz_divisible_p wrong\n");
+ printf (" expected %d got %d\n", want, got);
+ mpz_trace (" a", a);
+ mpz_trace (" d", d);
+ mp_trace_base = -16;
+ mpz_trace (" a", a);
+ mpz_trace (" d", d);
+ abort ();
+ }
+}
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *a;
+ const char *d;
+ int want;
+
+ } data[] = {
+
+ { "0", "0", 1 },
+ { "17", "0", 0 },
+ { "0", "1", 1 },
+ { "123", "1", 1 },
+ { "-123", "1", 1 },
+
+ { "0", "2", 1 },
+ { "1", "2", 0 },
+ { "2", "2", 1 },
+ { "-2", "2", 1 },
+ { "0x100000000000000000000000000000000", "2", 1 },
+ { "0x100000000000000000000000000000001", "2", 0 },
+
+ { "0x3333333333333333", "3", 1 },
+ { "0x3333333333333332", "3", 0 },
+ { "0x33333333333333333333333333333333", "3", 1 },
+ { "0x33333333333333333333333333333332", "3", 0 },
+
+ /* divisor changes from 2 to 1 limb after stripping 2s */
+ { "0x3333333300000000", "0x180000000", 1 },
+ { "0x33333333333333330000000000000000", "0x18000000000000000", 1 },
+ { "0x133333333333333330000000000000000", "0x18000000000000000", 0 },
+ };
+
+ mpz_t a, d;
+ int i;
+
+ mpz_init (a);
+ mpz_init (d);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (a, data[i].a, 0);
+ mpz_set_str_or_abort (d, data[i].d, 0);
+ check_one (a, d, data[i].want);
+ }
+
+ mpz_clear (a);
+ mpz_clear (d);
+}
+
+void
+check_random (int reps)
+{
+ gmp_randstate_ptr rands = RANDS;
+ mpz_t a, d, r;
+ int i;
+ int want;
+
+ mpz_init (a);
+ mpz_init (d);
+ mpz_init (r);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_erandomb (a, rands, 1 << 19);
+ mpz_erandomb_nonzero (d, rands, 1 << 18);
+
+ mpz_fdiv_r (r, a, d);
+
+ want = (mpz_sgn (r) == 0);
+ check_one (a, d, want);
+
+ mpz_sub (a, a, r);
+ check_one (a, d, 1);
+
+ if (mpz_cmpabs_ui (d, 1L) == 0)
+ continue;
+
+ mpz_add_ui (a, a, 1L);
+ check_one (a, d, 0);
+ }
+
+ mpz_clear (a);
+ mpz_clear (d);
+ mpz_clear (r);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int reps = 100;
+
+ tests_start ();
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ check_data ();
+ check_random (reps);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-divis_2exp.c b/gmp/tests/mpz/t-divis_2exp.c
new file mode 100644
index 0000000000..ecd7440eae
--- /dev/null
+++ b/gmp/tests/mpz/t-divis_2exp.c
@@ -0,0 +1,133 @@
+/* test mpz_divisible_2exp_p */
+
+/*
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpz_srcptr a, unsigned long d, int want)
+{
+ int got;
+
+ got = (mpz_divisible_2exp_p (a, d) != 0);
+ if (want != got)
+ {
+ printf ("mpz_divisible_2exp_p wrong\n");
+ printf (" expected %d got %d\n", want, got);
+ mpz_trace (" a", a);
+ printf (" d=%lu\n", d);
+ mp_trace_base = -16;
+ mpz_trace (" a", a);
+ printf (" d=0x%lX\n", d);
+ abort ();
+ }
+}
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *a;
+ unsigned long d;
+ int want;
+
+ } data[] = {
+
+ { "0", 0, 1 },
+ { "0", 1, 1 },
+ { "0", 2, 1 },
+ { "0", 3, 1 },
+
+ { "1", 0, 1 },
+ { "1", 1, 0 },
+ { "1", 2, 0 },
+ { "1", 3, 0 },
+ { "1", 10000, 0 },
+
+ { "4", 0, 1 },
+ { "4", 1, 1 },
+ { "4", 2, 1 },
+ { "4", 3, 0 },
+ { "4", 4, 0 },
+ { "4", 10000, 0 },
+
+ { "0x80000000", 31, 1 },
+ { "0x80000000", 32, 0 },
+ { "0x80000000", 64, 0 },
+
+ { "0x100000000", 32, 1 },
+ { "0x100000000", 33, 0 },
+ { "0x100000000", 64, 0 },
+
+ { "0x8000000000000000", 63, 1 },
+ { "0x8000000000000000", 64, 0 },
+ { "0x8000000000000000", 128, 0 },
+
+ { "0x10000000000000000", 64, 1 },
+ { "0x10000000000000000", 65, 0 },
+ { "0x10000000000000000", 128, 0 },
+ { "0x10000000000000000", 256, 0 },
+
+ { "0x10000000000000000100000000", 32, 1 },
+ { "0x10000000000000000100000000", 33, 0 },
+ { "0x10000000000000000100000000", 64, 0 },
+
+ { "0x1000000000000000010000000000000000", 64, 1 },
+ { "0x1000000000000000010000000000000000", 65, 0 },
+ { "0x1000000000000000010000000000000000", 128, 0 },
+ { "0x1000000000000000010000000000000000", 256, 0 },
+ { "0x1000000000000000010000000000000000", 1024, 0 },
+
+ };
+
+ mpz_t a, d;
+ int i;
+
+ mpz_init (a);
+ mpz_init (d);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (a, data[i].a, 0);
+ check_one (a, data[i].d, data[i].want);
+
+ mpz_neg (a, a);
+ check_one (a, data[i].d, data[i].want);
+ }
+
+ mpz_clear (a);
+ mpz_clear (d);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-export.c b/gmp/tests/mpz/t-export.c
new file mode 100644
index 0000000000..d07476486d
--- /dev/null
+++ b/gmp/tests/mpz/t-export.c
@@ -0,0 +1,206 @@
+/* Test mpz_export.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *src;
+ size_t want_count;
+ int order;
+ size_t size;
+ int endian;
+ int nail;
+ char want_data[64];
+
+ } data[] = {
+
+ { "0", 0,1, 1,1, 0 },
+ { "0", 0,1, 2,1, 0 },
+ { "0", 0,1, 3,1, 0 },
+
+ { "0x12345678", 4,1, 1,1, 0, { '\022', '\064', '\126', '\170' } },
+ { "0x12345678", 1,1, 4,1, 0, { '\022', '\064', '\126', '\170' } },
+ { "0x12345678", 1,-1, 4,1, 0, { '\022', '\064', '\126', '\170' } },
+
+ { "0x12345678", 4,-1, 1,-1, 0, { '\170', '\126', '\064', '\022' } },
+ { "0x12345678", 1,1, 4,-1, 0, { '\170', '\126', '\064', '\022' } },
+ { "0x12345678", 1,-1, 4,-1, 0, { '\170', '\126', '\064', '\022' } },
+
+ { "0x15", 5,1, 1,1, 7, { '\001', '\000', '\001', '\000', '\001' } },
+
+ { "0x1FFFFFFFFFFF", 3,1, 2,1, 1, {
+ '\177','\377', '\177','\377', '\177','\377' } },
+ { "0x1FFFFFFFFFFF", 3,1, 2,-1, 1, {
+ '\377','\177', '\377','\177', '\377','\177' } },
+ { "0x7", 3,1, 2,1, 15, {
+ '\000','\001', '\000','\001', '\000','\001' } },
+ { "0x7", 3,1, 2,-1, 15, {
+ '\001','\000', '\001','\000', '\001','\000' } },
+
+ { "0x24", 3,1, 2,1, 14, { '\000','\002', '\000','\001', '\000','\000' }},
+ { "0x24", 3,1, 2,-1, 14, { '\002','\000', '\001','\000', '\000','\000' }},
+ { "0x24", 3,-1, 2,-1, 14, { '\000','\000', '\001','\000', '\002','\000' }},
+ { "0x24", 3,-1, 2,1, 14, { '\000','\000', '\000','\001', '\000','\002' }},
+
+ { "0x123456789ABC", 3,1, 2,1, 0, {
+ '\022','\064', '\126','\170', '\232','\274' } },
+ { "0x123456789ABC", 3,-1, 2,1, 0, {
+ '\232','\274', '\126','\170', '\022','\064' } },
+ { "0x123456789ABC", 3,1, 2,-1, 0, {
+ '\064','\022', '\170','\126', '\274','\232' } },
+ { "0x123456789ABC", 3,-1, 2,-1, 0, {
+ '\274','\232', '\170','\126', '\064','\022' } },
+
+ { "0x112233445566778899AABBCC", 3,1, 4,1, 0,
+ { '\021','\042','\063','\104',
+ '\125','\146','\167','\210',
+ '\231','\252','\273','\314' } },
+ { "0x112233445566778899AABBCC", 3,-1, 4,1, 0,
+ { '\231','\252','\273','\314',
+ '\125','\146','\167','\210',
+ '\021','\042','\063','\104' } },
+ { "0x112233445566778899AABBCC", 3,1, 4,-1, 0,
+ { '\104','\063','\042','\021',
+ '\210','\167','\146','\125',
+ '\314','\273','\252','\231' } },
+ { "0x112233445566778899AABBCC", 3,-1, 4,-1, 0,
+ { '\314','\273','\252','\231',
+ '\210','\167','\146','\125',
+ '\104','\063','\042','\021' } },
+
+ { "0x100120023003400450056006700780089009A00AB00BC00C", 3,1, 8,1, 0,
+ { '\020','\001','\040','\002','\060','\003','\100','\004',
+ '\120','\005','\140','\006','\160','\007','\200','\010',
+ '\220','\011','\240','\012','\260','\013','\300','\014' } },
+ { "0x100120023003400450056006700780089009A00AB00BC00C", 3,-1, 8,1, 0,
+ { '\220','\011','\240','\012','\260','\013','\300','\014',
+ '\120','\005','\140','\006','\160','\007','\200','\010',
+ '\020','\001','\040','\002','\060','\003','\100','\004' } },
+ { "0x100120023003400450056006700780089009A00AB00BC00C", 3,1, 8,-1, 0,
+ { '\004','\100','\003','\060','\002','\040','\001','\020',
+ '\010','\200','\007','\160','\006','\140','\005','\120',
+ '\014','\300','\013','\260','\012','\240','\011','\220' } },
+ { "0x100120023003400450056006700780089009A00AB00BC00C", 3,-1, 8,-1, 0,
+ { '\014','\300','\013','\260','\012','\240','\011','\220',
+ '\010','\200','\007','\160','\006','\140','\005','\120',
+ '\004','\100','\003','\060','\002','\040','\001','\020' } },
+
+ { "0x155555555555555555555555", 3,1, 4,1, 1,
+ { '\125','\125','\125','\125',
+ '\052','\252','\252','\252',
+ '\125','\125','\125','\125' } },
+ { "0x155555555555555555555555", 3,-1, 4,1, 1,
+ { '\125','\125','\125','\125',
+ '\052','\252','\252','\252',
+ '\125','\125','\125','\125' } },
+ { "0x155555555555555555555555", 3,1, 4,-1, 1,
+ { '\125','\125','\125','\125',
+ '\252','\252','\252','\052',
+ '\125','\125','\125','\125' } },
+ { "0x155555555555555555555555", 3,-1, 4,-1, 1,
+ { '\125','\125','\125','\125',
+ '\252','\252','\252','\052',
+ '\125','\125','\125','\125' } },
+ };
+
+ char buf[sizeof(data[0].src) + sizeof (mp_limb_t) + 128];
+ char *got_data;
+ void *ret;
+ size_t align, got_count, j;
+ int i, error = 0;
+ mpz_t src;
+
+ mpz_init (src);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ for (align = 0; align < sizeof (mp_limb_t); align++)
+ {
+ mpz_set_str_or_abort (src, data[i].src, 0);
+ MPZ_CHECK_FORMAT (src);
+ got_data = buf + align;
+
+ ASSERT_ALWAYS (data[i].want_count * data[i].size + align
+ <= sizeof (buf));
+
+ memset (got_data, '\0', data[i].want_count * data[i].size);
+ ret = mpz_export (got_data, &got_count, data[i].order,
+ data[i].size, data[i].endian, data[i].nail, src);
+
+ if (ret != got_data)
+ {
+ printf ("return doesn't equal given pointer\n");
+ error = 1;
+ }
+ if (got_count != data[i].want_count)
+ {
+ printf ("wrong count\n");
+ error = 1;
+ }
+ if (memcmp (got_data, data[i].want_data, got_count * data[i].size) != 0)
+ {
+ printf ("wrong result data\n");
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" at data[%d] align=%d\n", i, (int) align);
+ printf (" src \"%s\"\n", data[i].src);
+ mpz_trace (" src", src);
+ printf (" order=%d size=%lu endian=%d nail=%u\n",
+ data[i].order,
+ (unsigned long) data[i].size, data[i].endian, data[i].nail);
+ printf (" want count %lu\n", (unsigned long) data[i].want_count);
+ printf (" got count %lu\n", (unsigned long) got_count);
+ printf (" want");
+ for (j = 0; j < data[i].want_count*data[i].size; j++)
+ printf (" 0x%02X,", (unsigned) (unsigned char) data[i].want_data[j]);
+ printf ("\n");
+ printf (" got ");
+ for (j = 0; j < got_count*data[i].size; j++)
+ printf (" 0x%02X,", (unsigned) (unsigned char) got_data[j]);
+ printf ("\n");
+ abort ();
+ }
+ }
+ }
+ mpz_clear (src);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ mp_trace_base = -16;
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-fac_ui.c b/gmp/tests/mpz/t-fac_ui.c
new file mode 100644
index 0000000000..079bdff912
--- /dev/null
+++ b/gmp/tests/mpz/t-fac_ui.c
@@ -0,0 +1,106 @@
+/* Exercise mpz_fac_ui and mpz_2fac_ui.
+
+Copyright 2000-2002, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Usage: t-fac_ui [x|num]
+
+ With no arguments testing goes up to the initial value of "limit" below.
+ With a number argument tests are carried that far, or with a literal "x"
+ tests are continued without limit (this being meant only for development
+ purposes). */
+
+
+int
+main (int argc, char *argv[])
+{
+ unsigned long n, m;
+ unsigned long limit = 2222;
+ mpz_t df[2], f, r;
+
+ tests_start ();
+
+ if (argc > 1 && argv[1][0] == 'x')
+ limit = ULONG_MAX;
+ else if (argc > 1)
+ limit = atoi (argv[1]);
+
+ /* for small limb testing */
+ limit = MIN (limit, MP_LIMB_T_MAX);
+
+ mpz_init_set_ui (df[0], 1); /* 0!! = 1 */
+ mpz_init_set_ui (df[1], 1); /* -1!! = 1 */
+ mpz_init_set_ui (f, 1); /* 0! = 1 */
+ mpz_init (r);
+
+ for (n = 0, m = 0; n < limit; n++)
+ {
+ mpz_fac_ui (r, n);
+ MPZ_CHECK_FORMAT (r);
+
+ if (mpz_cmp (f, r) != 0)
+ {
+ printf ("mpz_fac_ui(%lu) wrong\n", n);
+ printf (" got "); mpz_out_str (stdout, 10, r); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, f); printf("\n");
+ abort ();
+ }
+
+ mpz_2fac_ui (r, n);
+ MPZ_CHECK_FORMAT (r);
+
+ if (mpz_cmp (df[m], r) != 0)
+ {
+ printf ("mpz_2fac_ui(%lu) wrong\n", n);
+ printf (" got "); mpz_out_str (stdout, 10, r); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, df[m]); printf("\n");
+ abort ();
+ }
+
+ m ^= 1;
+ mpz_mul_ui (df[m], df[m], n+1); /* (n+1)!! = (n-1)!! * (n+1) */
+ mpz_mul_ui (f, f, n+1); /* (n+1)! = n! * (n+1) */
+ }
+
+ n = 1048573; /* a prime */
+ if (n > MP_LIMB_T_MAX)
+ n = 65521; /* a smaller prime :-) */
+ mpz_fac_ui (f, n - 1);
+ m = mpz_fdiv_ui (f, n);
+ if ( m != n - 1)
+ {
+ printf ("mpz_fac_ui(%lu) wrong\n", n - 1);
+ printf (" Wilson's theorem not verified: got %lu, expected %lu.\n",m ,n - 1);
+ abort ();
+ }
+
+ mpz_clear (df[0]);
+ mpz_clear (df[1]);
+ mpz_clear (f);
+ mpz_clear (r);
+
+ tests_end ();
+
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-fdiv.c b/gmp/tests/mpz/t-fdiv.c
new file mode 100644
index 0000000000..a616e5b101
--- /dev/null
+++ b/gmp/tests/mpz/t-fdiv.c
@@ -0,0 +1,147 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_fdiv_qr, mpz_fdiv_q,
+ mpz_fdiv_r, mpz_mul.
+
+Copyright 1993, 1994, 1996, 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void dump_abort (mpz_t, mpz_t);
+void debug_mp (mpz_t, int);
+
+int
+main (int argc, char **argv)
+{
+ mpz_t dividend, divisor;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size, divisor_size;
+ int i;
+ int reps = 1000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (divisor);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 16 + 2; /* 0..131071 bit operands */
+
+ do
+ {
+ mpz_urandomb (bs, rands, size_range);
+ divisor_size = mpz_get_ui (bs);
+ mpz_rrandomb (divisor, rands, divisor_size);
+ }
+ while (mpz_sgn (divisor) == 0);
+
+ mpz_urandomb (bs, rands, size_range);
+ dividend_size = mpz_get_ui (bs) + divisor_size;
+ mpz_rrandomb (dividend, rands, dividend_size);
+
+ mpz_urandomb (bs, rands, 2);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (dividend, dividend);
+ if ((bsi & 2) != 0)
+ mpz_neg (divisor, divisor);
+
+ /* printf ("%ld %ld\n", SIZ (dividend), SIZ (divisor)); */
+
+ mpz_fdiv_qr (quotient, remainder, dividend, divisor);
+ mpz_fdiv_q (quotient2, dividend, divisor);
+ mpz_fdiv_r (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the divisor
+ (quotient rounded towards minus infinity). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (divisor, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ mpz_mul (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (temp, divisor);
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp (remainder, temp) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (dividend);
+ mpz_clear (divisor);
+ mpz_clear (quotient);
+ mpz_clear (remainder);
+ mpz_clear (quotient2);
+ mpz_clear (remainder2);
+ mpz_clear (temp);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort (mpz_t dividend, mpz_t divisor)
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/t-fdiv_ui.c b/gmp/tests/mpz/t-fdiv_ui.c
new file mode 100644
index 0000000000..031b519f8f
--- /dev/null
+++ b/gmp/tests/mpz/t-fdiv_ui.c
@@ -0,0 +1,159 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_fdiv_qr_ui, mpz_fdiv_q_ui,
+ mpz_fdiv_r_ui, mpz_fdiv_ui, mpz_mul_ui.
+
+Copyright 1993, 1994, 1996, 2000-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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void dump_abort (const char *, mpz_t, unsigned long);
+void debug_mp (mpz_t, int);
+
+int
+main (int argc, char **argv)
+{
+ mpz_t dividend;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size;
+ unsigned long divisor;
+ int i;
+ int reps = 10000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+ unsigned long r_rq, r_q, r_r, r;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */
+
+ do
+ {
+ mpz_rrandomb (bs, rands, 64);
+ divisor = mpz_get_ui (bs);
+ }
+ while (divisor == 0);
+
+ mpz_urandomb (bs, rands, size_range);
+ dividend_size = mpz_get_ui (bs);
+ mpz_rrandomb (dividend, rands, dividend_size);
+
+ mpz_urandomb (bs, rands, 2);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (dividend, dividend);
+
+ /* printf ("%ld\n", SIZ (dividend)); */
+
+ r_rq = mpz_fdiv_qr_ui (quotient, remainder, dividend, divisor);
+ r_q = mpz_fdiv_q_ui (quotient2, dividend, divisor);
+ r_r = mpz_fdiv_r_ui (remainder2, dividend, divisor);
+ r = mpz_fdiv_ui (dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort ("quotients from mpz_fdiv_qr_ui and mpz_fdiv_q_ui differ",
+ dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort ("remainders from mpz_fdiv_qr_ui and mpz_fdiv_r_ui differ",
+ dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort ("quotient sign wrong", dividend, divisor);
+
+ /* Check if the remainder has the same sign as the (positive) divisor
+ (quotient rounded towards minus infinity). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if (mpz_cmp_ui (remainder, 0) < 0)
+ dump_abort ("remainder sign wrong", dividend, divisor);
+
+ mpz_mul_ui (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort ("n mod d != n - [n/d]*d", dividend, divisor);
+
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp_ui (remainder, divisor) >= 0)
+ dump_abort ("remainder greater than divisor", dividend, divisor);
+
+ if (mpz_cmp_ui (remainder, r_rq) != 0)
+ dump_abort ("remainder returned from mpz_fdiv_qr_ui is wrong",
+ dividend, divisor);
+ if (mpz_cmp_ui (remainder, r_q) != 0)
+ dump_abort ("remainder returned from mpz_fdiv_q_ui is wrong",
+ dividend, divisor);
+ if (mpz_cmp_ui (remainder, r_r) != 0)
+ dump_abort ("remainder returned from mpz_fdiv_r_ui is wrong",
+ dividend, divisor);
+ if (mpz_cmp_ui (remainder, r) != 0)
+ dump_abort ("remainder returned from mpz_fdiv_ui is wrong",
+ dividend, divisor);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (dividend);
+ mpz_clear (quotient);
+ mpz_clear (remainder);
+ mpz_clear (quotient2);
+ mpz_clear (remainder2);
+ mpz_clear (temp);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort (const char *str, mpz_t dividend, unsigned long divisor)
+{
+ fprintf (stderr, "ERROR: %s\n", str);
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = %lX\n", divisor);
+ abort();
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/t-fib_ui.c b/gmp/tests/mpz/t-fib_ui.c
new file mode 100644
index 0000000000..a7425b5b89
--- /dev/null
+++ b/gmp/tests/mpz/t-fib_ui.c
@@ -0,0 +1,156 @@
+/* Test mpz_fib_ui and mpz_fib2_ui.
+
+Copyright 2000-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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Usage: t-fib_ui [x|num]
+
+ Run with no arguments, tests goes up to the initial value of "limit"
+ below. With a number argument tests are carried up that far, or with a
+ literal "x" tests are continued without limit (this being only meant for
+ development purposes).
+
+ The size tests performed are designed to partially replicate what will be
+ going on in mpz_fib_ui. There's plenty of ASSERTs there, but of course
+ they're not normally enabled.
+
+ Misfeatures:
+
+ The tests on MPN_FIB2_SIZE are a bit useless, since that macro includes a
+ +2 for the internal purposes of mpn_fib2_ui. It's probably better to
+ give mpn_fib2_ui a run with assertion checking enabled. */
+
+
+#define MPZ_FIB_SIZE_FLOAT(n) \
+ ((mp_size_t) ((n) * 0.6942419 / GMP_NUMB_BITS + 1))
+
+
+void
+check_fib_table (void)
+{
+ int i;
+ mp_limb_t want;
+
+ ASSERT_ALWAYS (FIB_TABLE(-1) == 1);
+ ASSERT_ALWAYS (FIB_TABLE(0) == 0);
+
+ for (i = 1; i <= FIB_TABLE_LIMIT; i++)
+ {
+ want = FIB_TABLE(i-1) + FIB_TABLE(i-2);
+ if (FIB_TABLE(i) != want)
+ {
+ printf ("FIB_TABLE(%d) wrong\n", i);
+ gmp_printf (" got %#Nx\n", &FIB_TABLE(i), 1);
+ gmp_printf (" want %#Nx\n", &want, 1);
+ abort ();
+ }
+ }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ unsigned long n;
+ unsigned long limit = 100 * GMP_LIMB_BITS;
+ mpz_t want_fn, want_fn1, got_fn, got_fn1;
+
+ tests_start ();
+ mp_trace_base = -16;
+ if (argc > 1 && argv[1][0] == 'x')
+ limit = ULONG_MAX;
+ else if (argc > 1)
+ limit = atoi (argv[1]);
+
+ check_fib_table ();
+
+ /* start at n==0 */
+ mpz_init_set_ui (want_fn1, 1); /* F[-1] */
+ mpz_init_set_ui (want_fn, 0); /* F[0] */
+ mpz_init (got_fn);
+ mpz_init (got_fn1);
+
+ for (n = 0; n < limit; n++)
+ {
+ /* check our float formula seems right */
+ if (MPZ_FIB_SIZE_FLOAT (n) < SIZ(want_fn))
+ {
+ printf ("MPZ_FIB_SIZE_FLOAT wrong at n=%lu\n", n);
+ printf (" MPZ_FIB_SIZE_FLOAT %ld\n", MPZ_FIB_SIZE_FLOAT (n));
+ printf (" SIZ(want_fn) %d\n", SIZ(want_fn));
+ abort ();
+ }
+
+ /* check MPN_FIB2_SIZE seems right, compared to actual size and
+ compared to our float formula */
+ if (MPN_FIB2_SIZE (n) < MPZ_FIB_SIZE_FLOAT (n))
+ {
+ printf ("MPN_FIB2_SIZE wrong at n=%lu\n", n);
+ printf (" MPN_FIB2_SIZE %ld\n", MPN_FIB2_SIZE (n));
+ printf (" MPZ_FIB_SIZE_FLOAT %ld\n", MPZ_FIB_SIZE_FLOAT (n));
+ abort ();
+ }
+ if (MPN_FIB2_SIZE (n) < SIZ(want_fn))
+ {
+ printf ("MPN_FIB2_SIZE wrong at n=%lu\n", n);
+ printf (" MPN_FIB2_SIZE %ld\n", MPN_FIB2_SIZE (n));
+ printf (" SIZ(want_fn) %d\n", SIZ(want_fn));
+ abort ();
+ }
+
+ mpz_fib2_ui (got_fn, got_fn1, n);
+ MPZ_CHECK_FORMAT (got_fn);
+ MPZ_CHECK_FORMAT (got_fn1);
+ if (mpz_cmp (got_fn, want_fn) != 0 || mpz_cmp (got_fn1, want_fn1) != 0)
+ {
+ printf ("mpz_fib2_ui(%lu) wrong\n", n);
+ mpz_trace ("want fn ", want_fn);
+ mpz_trace ("got fn ", got_fn);
+ mpz_trace ("want fn1", want_fn1);
+ mpz_trace ("got fn1", got_fn1);
+ abort ();
+ }
+
+ mpz_fib_ui (got_fn, n);
+ MPZ_CHECK_FORMAT (got_fn);
+ if (mpz_cmp (got_fn, want_fn) != 0)
+ {
+ printf ("mpz_fib_ui(%lu) wrong\n", n);
+ mpz_trace ("want fn", want_fn);
+ mpz_trace ("got fn", got_fn);
+ abort ();
+ }
+
+ mpz_add (want_fn1, want_fn1, want_fn); /* F[n+1] = F[n] + F[n-1] */
+ mpz_swap (want_fn1, want_fn);
+ }
+
+ mpz_clear (want_fn);
+ mpz_clear (want_fn1);
+ mpz_clear (got_fn);
+ mpz_clear (got_fn1);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-fits.c b/gmp/tests/mpz/t-fits.c
new file mode 100644
index 0000000000..b1db216573
--- /dev/null
+++ b/gmp/tests/mpz/t-fits.c
@@ -0,0 +1,202 @@
+/* Test mpz_fits_*_p */
+
+/*
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Nothing sophisticated here, just exercise mpz_fits_*_p on a small amount
+ of data. */
+
+#define EXPECT_S(fun,name,answer) \
+ got = fun (z); \
+ if (got != answer) \
+ { \
+ printf ("%s (%s) got %d want %d\n", name, expr, got, answer); \
+ printf (" z size %d\n", SIZ(z)); \
+ printf (" z dec "); mpz_out_str (stdout, 10, z); printf ("\n"); \
+ printf (" z hex "); mpz_out_str (stdout, 16, z); printf ("\n"); \
+ error = 1; \
+ }
+
+#if HAVE_STRINGIZE
+#define EXPECT(fun,answer) EXPECT_S(fun,#fun,answer)
+#else
+#define EXPECT(fun,answer) EXPECT_S(fun,"fun",answer)
+#endif
+
+int
+main (void)
+{
+ mpz_t z;
+ int got;
+ const char *expr;
+ int error = 0;
+
+ tests_start ();
+ mpz_init (z);
+
+ mpz_set_ui (z, 0L);
+ expr = "0";
+ EXPECT (mpz_fits_ulong_p, 1);
+ EXPECT (mpz_fits_uint_p, 1);
+ EXPECT (mpz_fits_ushort_p, 1);
+ EXPECT (mpz_fits_slong_p, 1);
+ EXPECT (mpz_fits_sint_p, 1);
+ EXPECT (mpz_fits_sshort_p, 1);
+
+ mpz_set_ui (z, 1L);
+ expr = "1";
+ EXPECT (mpz_fits_ulong_p, 1);
+ EXPECT (mpz_fits_uint_p, 1);
+ EXPECT (mpz_fits_ushort_p, 1);
+ EXPECT (mpz_fits_slong_p, 1);
+ EXPECT (mpz_fits_sint_p, 1);
+ EXPECT (mpz_fits_sshort_p, 1);
+
+ mpz_set_si (z, -1L);
+ expr = "-1";
+ EXPECT (mpz_fits_ulong_p, 0);
+ EXPECT (mpz_fits_uint_p, 0);
+ EXPECT (mpz_fits_ushort_p, 0);
+ EXPECT (mpz_fits_slong_p, 1);
+ EXPECT (mpz_fits_sint_p, 1);
+ EXPECT (mpz_fits_sshort_p, 1);
+
+ mpz_set_ui (z, 1L);
+ mpz_mul_2exp (z, z, 5L*GMP_LIMB_BITS);
+ expr = "2^(5*BPML)";
+ EXPECT (mpz_fits_ulong_p, 0);
+ EXPECT (mpz_fits_uint_p, 0);
+ EXPECT (mpz_fits_ushort_p, 0);
+ EXPECT (mpz_fits_slong_p, 0);
+ EXPECT (mpz_fits_sint_p, 0);
+ EXPECT (mpz_fits_sshort_p, 0);
+
+
+ mpz_set_ui (z, (unsigned long) USHRT_MAX);
+ expr = "USHRT_MAX";
+ EXPECT (mpz_fits_ulong_p, 1);
+ EXPECT (mpz_fits_uint_p, 1);
+ EXPECT (mpz_fits_ushort_p, 1);
+
+ mpz_set_ui (z, (unsigned long) USHRT_MAX);
+ mpz_add_ui (z, z, 1L);
+ expr = "USHRT_MAX + 1";
+ EXPECT (mpz_fits_ushort_p, 0);
+
+
+ mpz_set_ui (z, (unsigned long) UINT_MAX);
+ expr = "UINT_MAX";
+ EXPECT (mpz_fits_ulong_p, 1);
+ EXPECT (mpz_fits_uint_p, 1);
+
+ mpz_set_ui (z, (unsigned long) UINT_MAX);
+ mpz_add_ui (z, z, 1L);
+ expr = "UINT_MAX + 1";
+ EXPECT (mpz_fits_uint_p, 0);
+
+
+ mpz_set_ui (z, ULONG_MAX);
+ expr = "ULONG_MAX";
+ EXPECT (mpz_fits_ulong_p, 1);
+
+ mpz_set_ui (z, ULONG_MAX);
+ mpz_add_ui (z, z, 1L);
+ expr = "ULONG_MAX + 1";
+ EXPECT (mpz_fits_ulong_p, 0);
+
+
+ mpz_set_si (z, (long) SHRT_MAX);
+ expr = "SHRT_MAX";
+ EXPECT (mpz_fits_slong_p, 1);
+ EXPECT (mpz_fits_sint_p, 1);
+ EXPECT (mpz_fits_sshort_p, 1);
+
+ mpz_set_si (z, (long) SHRT_MAX);
+ mpz_add_ui (z, z, 1L);
+ expr = "SHRT_MAX + 1";
+ EXPECT (mpz_fits_sshort_p, 0);
+
+
+ mpz_set_si (z, (long) INT_MAX);
+ expr = "INT_MAX";
+ EXPECT (mpz_fits_slong_p, 1);
+ EXPECT (mpz_fits_sint_p, 1);
+
+ mpz_set_si (z, (long) INT_MAX);
+ mpz_add_ui (z, z, 1L);
+ expr = "INT_MAX + 1";
+ EXPECT (mpz_fits_sint_p, 0);
+
+
+ mpz_set_si (z, LONG_MAX);
+ expr = "LONG_MAX";
+ EXPECT (mpz_fits_slong_p, 1);
+
+ mpz_set_si (z, LONG_MAX);
+ mpz_add_ui (z, z, 1L);
+ expr = "LONG_MAX + 1";
+ EXPECT (mpz_fits_slong_p, 0);
+
+
+ mpz_set_si (z, (long) SHRT_MIN);
+ expr = "SHRT_MIN";
+ EXPECT (mpz_fits_slong_p, 1);
+ EXPECT (mpz_fits_sint_p, 1);
+ EXPECT (mpz_fits_sshort_p, 1);
+
+ mpz_set_si (z, (long) SHRT_MIN);
+ mpz_sub_ui (z, z, 1L);
+ expr = "SHRT_MIN + 1";
+ EXPECT (mpz_fits_sshort_p, 0);
+
+
+ mpz_set_si (z, (long) INT_MIN);
+ expr = "INT_MIN";
+ EXPECT (mpz_fits_slong_p, 1);
+ EXPECT (mpz_fits_sint_p, 1);
+
+ mpz_set_si (z, (long) INT_MIN);
+ mpz_sub_ui (z, z, 1L);
+ expr = "INT_MIN + 1";
+ EXPECT (mpz_fits_sint_p, 0);
+
+
+ mpz_set_si (z, LONG_MIN);
+ expr = "LONG_MIN";
+ EXPECT (mpz_fits_slong_p, 1);
+
+ mpz_set_si (z, LONG_MIN);
+ mpz_sub_ui (z, z, 1L);
+ expr = "LONG_MIN + 1";
+ EXPECT (mpz_fits_slong_p, 0);
+
+
+ if (error)
+ abort ();
+
+ mpz_clear (z);
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-gcd.c b/gmp/tests/mpz/t-gcd.c
new file mode 100644
index 0000000000..fef4fde0cf
--- /dev/null
+++ b/gmp/tests/mpz/t-gcd.c
@@ -0,0 +1,454 @@
+/* Test mpz_gcd, mpz_gcdext, and mpz_gcd_ui.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-2005, 2008, 2009, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void one_test (mpz_t, mpz_t, mpz_t, int);
+void debug_mp (mpz_t, int);
+
+static int gcdext_valid_p (const mpz_t, const mpz_t, const mpz_t, const mpz_t);
+
+/* Keep one_test's variables global, so that we don't need
+ to reinitialize them for each test. */
+mpz_t gcd1, gcd2, s, temp1, temp2, temp3;
+
+#define MAX_SCHOENHAGE_THRESHOLD HGCD_REDUCE_THRESHOLD
+
+/* Define this to make all operands be large enough for Schoenhage gcd
+ to be used. */
+#ifndef WHACK_SCHOENHAGE
+#define WHACK_SCHOENHAGE 0
+#endif
+
+#if WHACK_SCHOENHAGE
+#define MIN_OPERAND_BITSIZE (MAX_SCHOENHAGE_THRESHOLD * GMP_NUMB_BITS)
+#else
+#define MIN_OPERAND_BITSIZE 1
+#endif
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *a;
+ const char *b;
+ const char *want;
+ } data[] = {
+ /* This tickled a bug in gmp 4.1.2 mpn/x86/k6/gcd_finda.asm. */
+ { "0x3FFC000007FFFFFFFFFF00000000003F83FFFFFFFFFFFFFFF80000000000000001",
+ "0x1FFE0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC000000000000000000000001",
+ "5" }
+ };
+
+ mpz_t a, b, got, want;
+ int i;
+
+ mpz_inits (a, b, got, want, NULL);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (a, data[i].a, 0);
+ mpz_set_str_or_abort (b, data[i].b, 0);
+ mpz_set_str_or_abort (want, data[i].want, 0);
+ mpz_gcd (got, a, b);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_gcd wrong on data[%d]\n", i);
+ printf (" a %s\n", data[i].a);
+ printf (" b %s\n", data[i].b);
+ mpz_trace (" a", a);
+ mpz_trace (" b", b);
+ mpz_trace (" want", want);
+ mpz_trace (" got ", got);
+ abort ();
+ }
+ }
+
+ mpz_clears (a, b, got, want, NULL);
+}
+
+void
+make_chain_operands (mpz_t ref, mpz_t a, mpz_t b, gmp_randstate_t rs, int nb1, int nb2, int chain_len)
+{
+ mpz_t bs, temp1, temp2;
+ int j;
+
+ mpz_inits (bs, temp1, temp2, NULL);
+
+ /* Generate a division chain backwards, allowing otherwise unlikely huge
+ quotients. */
+
+ mpz_set_ui (a, 0);
+ mpz_urandomb (bs, rs, 32);
+ mpz_urandomb (bs, rs, mpz_get_ui (bs) % nb1 + 1);
+ mpz_rrandomb (b, rs, mpz_get_ui (bs));
+ mpz_add_ui (b, b, 1);
+ mpz_set (ref, b);
+
+ for (j = 0; j < chain_len; j++)
+ {
+ mpz_urandomb (bs, rs, 32);
+ mpz_urandomb (bs, rs, mpz_get_ui (bs) % nb2 + 1);
+ mpz_rrandomb (temp2, rs, mpz_get_ui (bs) + 1);
+ mpz_add_ui (temp2, temp2, 1);
+ mpz_mul (temp1, b, temp2);
+ mpz_add (a, a, temp1);
+
+ mpz_urandomb (bs, rs, 32);
+ mpz_urandomb (bs, rs, mpz_get_ui (bs) % nb2 + 1);
+ mpz_rrandomb (temp2, rs, mpz_get_ui (bs) + 1);
+ mpz_add_ui (temp2, temp2, 1);
+ mpz_mul (temp1, a, temp2);
+ mpz_add (b, b, temp1);
+ }
+
+ mpz_clears (bs, temp1, temp2, NULL);
+}
+
+/* Test operands from a table of seed data. This variant creates the operands
+ using plain ol' mpz_rrandomb. This is a hack for better coverage of the gcd
+ code, which depends on that the random number generators give the exact
+ numbers we expect. */
+void
+check_kolmo1 (void)
+{
+ static const struct {
+ unsigned int seed;
+ int nb;
+ const char *want;
+ } data[] = {
+ { 59618, 38208, "5"},
+ { 76521, 49024, "3"},
+ { 85869, 54976, "1"},
+ { 99449, 63680, "1"},
+ {112453, 72000, "1"}
+ };
+
+ gmp_randstate_t rs;
+ mpz_t bs, a, b, want;
+ int i, unb, vnb, nb;
+
+ gmp_randinit_default (rs);
+
+ mpz_inits (bs, a, b, want, NULL);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ nb = data[i].nb;
+
+ gmp_randseed_ui (rs, data[i].seed);
+
+ mpz_urandomb (bs, rs, 32);
+ unb = mpz_get_ui (bs) % nb;
+ mpz_urandomb (bs, rs, 32);
+ vnb = mpz_get_ui (bs) % nb;
+
+ mpz_rrandomb (a, rs, unb);
+ mpz_rrandomb (b, rs, vnb);
+
+ mpz_set_str_or_abort (want, data[i].want, 0);
+
+ one_test (a, b, want, -1);
+ }
+
+ mpz_clears (bs, a, b, want, NULL);
+ gmp_randclear (rs);
+}
+
+/* Test operands from a table of seed data. This variant creates the operands
+ using a division chain. This is a hack for better coverage of the gcd
+ code, which depends on that the random number generators give the exact
+ numbers we expect. */
+void
+check_kolmo2 (void)
+{
+ static const struct {
+ unsigned int seed;
+ int nb, chain_len;
+ } data[] = {
+ { 917, 15, 5 },
+ { 1032, 18, 6 },
+ { 1167, 18, 6 },
+ { 1174, 18, 6 },
+ { 1192, 18, 6 },
+ };
+
+ gmp_randstate_t rs;
+ mpz_t bs, a, b, want;
+ int i;
+
+ gmp_randinit_default (rs);
+
+ mpz_inits (bs, a, b, want, NULL);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ gmp_randseed_ui (rs, data[i].seed);
+ make_chain_operands (want, a, b, rs, data[i].nb, data[i].nb, data[i].chain_len);
+ one_test (a, b, want, -1);
+ }
+
+ mpz_clears (bs, a, b, want, NULL);
+ gmp_randclear (rs);
+}
+
+int
+main (int argc, char **argv)
+{
+ mpz_t op1, op2, ref;
+ int i, chain_len;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+ long int reps = 200;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ mpz_inits (bs, op1, op2, ref, gcd1, gcd2, temp1, temp2, temp3, s, NULL);
+
+ check_data ();
+ check_kolmo1 ();
+ check_kolmo2 ();
+
+ /* Testcase to exercise the u0 == u1 case in mpn_gcdext_lehmer_n. */
+ mpz_set_ui (op2, GMP_NUMB_MAX); /* FIXME: Huge limb doesn't always fit */
+ mpz_mul_2exp (op1, op2, 100);
+ mpz_add (op1, op1, op2);
+ mpz_mul_ui (op2, op2, 2);
+ one_test (op1, op2, NULL, -1);
+
+ for (i = 0; i < reps; i++)
+ {
+ /* Generate plain operands with unknown gcd. These types of operands
+ have proven to trigger certain bugs in development versions of the
+ gcd code. The "hgcd->row[3].rsize > M" ASSERT is not triggered by
+ the division chain code below, but that is most likely just a result
+ of that other ASSERTs are triggered before it. */
+
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 17 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);
+
+ mpz_urandomb (bs, rands, 8);
+ bsi = mpz_get_ui (bs);
+
+ if ((bsi & 0x3c) == 4)
+ mpz_mul (op1, op1, op2); /* make op1 a multiple of op2 */
+ else if ((bsi & 0x3c) == 8)
+ mpz_mul (op2, op1, op2); /* make op2 a multiple of op1 */
+
+ if ((bsi & 1) != 0)
+ mpz_neg (op1, op1);
+ if ((bsi & 2) != 0)
+ mpz_neg (op2, op2);
+
+ one_test (op1, op2, NULL, i);
+
+ /* Generate a division chain backwards, allowing otherwise unlikely huge
+ quotients. */
+
+ mpz_urandomb (bs, rands, 32);
+ chain_len = mpz_get_ui (bs) % LOG2C (GMP_NUMB_BITS * MAX_SCHOENHAGE_THRESHOLD);
+ mpz_urandomb (bs, rands, 32);
+ chain_len = mpz_get_ui (bs) % (1 << chain_len) / 32;
+
+ make_chain_operands (ref, op1, op2, rands, 16, 12, chain_len);
+
+ one_test (op1, op2, ref, i);
+ }
+
+ mpz_clears (bs, op1, op2, ref, gcd1, gcd2, temp1, temp2, temp3, s, NULL);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
+
+void
+one_test (mpz_t op1, mpz_t op2, mpz_t ref, int i)
+{
+ /*
+ printf ("%d %d %d\n", SIZ (op1), SIZ (op2), ref != NULL ? SIZ (ref) : 0);
+ fflush (stdout);
+ */
+
+ /*
+ fprintf (stderr, "op1="); debug_mp (op1, -16);
+ fprintf (stderr, "op2="); debug_mp (op2, -16);
+ */
+
+ mpz_gcdext (gcd1, s, NULL, op1, op2);
+ MPZ_CHECK_FORMAT (gcd1);
+ MPZ_CHECK_FORMAT (s);
+
+ if (ref && mpz_cmp (ref, gcd1) != 0)
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ fprintf (stderr, "mpz_gcdext returned incorrect result\n");
+ fprintf (stderr, "op1="); debug_mp (op1, -16);
+ fprintf (stderr, "op2="); debug_mp (op2, -16);
+ fprintf (stderr, "expected result:\n"); debug_mp (ref, -16);
+ fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd1, -16);
+ abort ();
+ }
+
+ if (!gcdext_valid_p(op1, op2, gcd1, s))
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ fprintf (stderr, "mpz_gcdext returned invalid result\n");
+ fprintf (stderr, "op1="); debug_mp (op1, -16);
+ fprintf (stderr, "op2="); debug_mp (op2, -16);
+ fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd1, -16);
+ fprintf (stderr, "s="); debug_mp (s, -16);
+ abort ();
+ }
+
+ mpz_gcd (gcd2, op1, op2);
+ MPZ_CHECK_FORMAT (gcd2);
+
+ if (mpz_cmp (gcd2, gcd1) != 0)
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ fprintf (stderr, "mpz_gcd returned incorrect result\n");
+ fprintf (stderr, "op1="); debug_mp (op1, -16);
+ fprintf (stderr, "op2="); debug_mp (op2, -16);
+ fprintf (stderr, "expected result:\n"); debug_mp (gcd1, -16);
+ fprintf (stderr, "mpz_gcd returns:\n"); debug_mp (gcd2, -16);
+ abort ();
+ }
+
+ /* This should probably move to t-gcd_ui.c */
+ if (mpz_fits_ulong_p (op1) || mpz_fits_ulong_p (op2))
+ {
+ if (mpz_fits_ulong_p (op1))
+ mpz_gcd_ui (gcd2, op2, mpz_get_ui (op1));
+ else
+ mpz_gcd_ui (gcd2, op1, mpz_get_ui (op2));
+ if (mpz_cmp (gcd2, gcd1))
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ fprintf (stderr, "mpz_gcd_ui returned incorrect result\n");
+ fprintf (stderr, "op1="); debug_mp (op1, -16);
+ fprintf (stderr, "op2="); debug_mp (op2, -16);
+ fprintf (stderr, "expected result:\n"); debug_mp (gcd1, -16);
+ fprintf (stderr, "mpz_gcd_ui returns:\n"); debug_mp (gcd2, -16);
+ abort ();
+ }
+ }
+
+ mpz_gcdext (gcd2, temp1, temp2, op1, op2);
+ MPZ_CHECK_FORMAT (gcd2);
+ MPZ_CHECK_FORMAT (temp1);
+ MPZ_CHECK_FORMAT (temp2);
+
+ mpz_mul (temp1, temp1, op1);
+ mpz_mul (temp2, temp2, op2);
+ mpz_add (temp1, temp1, temp2);
+
+ if (mpz_cmp (gcd1, gcd2) != 0
+ || mpz_cmp (gcd2, temp1) != 0)
+ {
+ fprintf (stderr, "ERROR in test %d\n", i);
+ fprintf (stderr, "mpz_gcdext returned incorrect result\n");
+ fprintf (stderr, "op1="); debug_mp (op1, -16);
+ fprintf (stderr, "op2="); debug_mp (op2, -16);
+ fprintf (stderr, "expected result:\n"); debug_mp (gcd1, -16);
+ fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd2, -16);
+ abort ();
+ }
+}
+
+/* Called when g is supposed to be gcd(a,b), and g = s a + t b, for some t.
+ Uses temp1, temp2 and temp3. */
+static int
+gcdext_valid_p (const mpz_t a, const mpz_t b, const mpz_t g, const mpz_t s)
+{
+ /* It's not clear that gcd(0,0) is well defined, but we allow it and require that
+ gcd(0,0) = 0. */
+ if (mpz_sgn (g) < 0)
+ return 0;
+
+ if (mpz_sgn (a) == 0)
+ {
+ /* Must have g == abs (b). Any value for s is in some sense "correct",
+ but it makes sense to require that s == 0. */
+ return mpz_cmpabs (g, b) == 0 && mpz_sgn (s) == 0;
+ }
+ else if (mpz_sgn (b) == 0)
+ {
+ /* Must have g == abs (a), s == sign (a) */
+ return mpz_cmpabs (g, a) == 0 && mpz_cmp_si (s, mpz_sgn (a)) == 0;
+ }
+
+ if (mpz_sgn (g) <= 0)
+ return 0;
+
+ mpz_tdiv_qr (temp1, temp3, a, g);
+ if (mpz_sgn (temp3) != 0)
+ return 0;
+
+ mpz_tdiv_qr (temp2, temp3, b, g);
+ if (mpz_sgn (temp3) != 0)
+ return 0;
+
+ /* Require that 2 |s| < |b/g|, or |s| == 1. */
+ if (mpz_cmpabs_ui (s, 1) > 0)
+ {
+ mpz_mul_2exp (temp3, s, 1);
+ if (mpz_cmpabs (temp3, temp2) >= 0)
+ return 0;
+ }
+
+ /* Compute the other cofactor. */
+ mpz_mul(temp2, s, a);
+ mpz_sub(temp2, g, temp2);
+ mpz_tdiv_qr(temp2, temp3, temp2, b);
+
+ if (mpz_sgn (temp3) != 0)
+ return 0;
+
+ /* Require that 2 |t| < |a/g| or |t| == 1*/
+ if (mpz_cmpabs_ui (temp2, 1) > 0)
+ {
+ mpz_mul_2exp (temp2, temp2, 1);
+ if (mpz_cmpabs (temp2, temp1) >= 0)
+ return 0;
+ }
+ return 1;
+}
diff --git a/gmp/tests/mpz/t-gcd_ui.c b/gmp/tests/mpz/t-gcd_ui.c
new file mode 100644
index 0000000000..16f51e11b6
--- /dev/null
+++ b/gmp/tests/mpz/t-gcd_ui.c
@@ -0,0 +1,63 @@
+/* Test mpz_gcd_ui.
+
+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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Check mpz_gcd_ui doesn't try to return a value out of range.
+ This was wrong in gmp 4.1.2 with a long long limb. */
+static void
+check_ui_range (void)
+{
+ unsigned long got;
+ mpz_t x;
+ int i;
+
+ mpz_init_set_ui (x, ULONG_MAX);
+
+ for (i = 0; i < 20; i++)
+ {
+ mpz_mul_2exp (x, x, 1L);
+ got = mpz_gcd_ui (NULL, x, 0L);
+ if (got != 0)
+ {
+ printf ("mpz_gcd_ui (ULONG_MAX*2^%d, 0)\n", i);
+ printf (" return %#lx\n", got);
+ printf (" should be 0\n");
+ abort ();
+ }
+ }
+
+ mpz_clear (x);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_ui_range ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-get_d.c b/gmp/tests/mpz/t-get_d.c
new file mode 100644
index 0000000000..4a4a930498
--- /dev/null
+++ b/gmp/tests/mpz/t-get_d.c
@@ -0,0 +1,74 @@
+/* Test mpz_get_d.
+
+Copyright 2002, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_onebit (void)
+{
+ int i;
+ mpz_t z;
+ double got, want;
+ /* FIXME: It'd be better to base this on the float format. */
+#if defined (__vax) || defined (__vax__)
+ int limit = 127 - 1; /* vax fp numbers have limited range */
+#else
+ int limit = 512;
+#endif
+
+ mpz_init (z);
+
+ mpz_set_ui (z, 1L);
+ want = 1.0;
+
+ for (i = 0; i < limit; i++)
+ {
+ got = mpz_get_d (z);
+
+ if (got != want)
+ {
+ printf ("mpz_get_d wrong on 2**%d\n", i);
+ mpz_trace (" z ", z);
+ printf (" want %.20g\n", want);
+ printf (" got %.20g\n", got);
+ abort();
+ }
+
+ mpz_mul_2exp (z, z, 1L);
+ want *= 2.0;
+ }
+ mpz_clear (z);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_onebit ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-get_d_2exp.c b/gmp/tests/mpz/t-get_d_2exp.c
new file mode 100644
index 0000000000..2f5555daf5
--- /dev/null
+++ b/gmp/tests/mpz/t-get_d_2exp.c
@@ -0,0 +1,223 @@
+/* Test mpz_get_d_2exp.
+
+Copyright 2002, 2003, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+static void
+check_zero (void)
+{
+ mpz_t z;
+ double got, want;
+ long got_exp, want_exp;
+
+ mpz_init_set_ui (z, 0);
+
+ want = 0.0;
+ want_exp = 0;
+ got = mpz_get_d_2exp (&got_exp, z);
+ if (got != want || got_exp != want_exp)
+ {
+ printf ("mpz_get_d_2exp wrong on zero\n");
+ mpz_trace (" z ", z);
+ d_trace (" want ", want);
+ d_trace (" got ", got);
+ printf (" want exp %ld\n", want_exp);
+ printf (" got exp %ld\n", got_exp);
+ abort();
+ }
+
+ mpz_clear (z);
+}
+
+static void
+check_onebit (void)
+{
+ static const unsigned long data[] = {
+ 1, 32, 52, 53, 54, 63, 64, 65, 128, 256, 511, 512, 513
+ };
+ mpz_t z;
+ double got, want;
+ long got_exp, want_exp;
+ int i;
+
+ mpz_init (z);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_ui (z, 1L);
+ mpz_mul_2exp (z, z, data[i]);
+ want = 0.5;
+ want_exp = data[i] + 1;
+ got = mpz_get_d_2exp (&got_exp, z);
+ if (got != want || got_exp != want_exp)
+ {
+ printf ("mpz_get_d_2exp wrong on 2**%ld\n", data[i]);
+ mpz_trace (" z ", z);
+ d_trace (" want ", want);
+ d_trace (" got ", got);
+ printf (" want exp %ld\n", want_exp);
+ printf (" got exp %ld\n", got_exp);
+ abort();
+ }
+
+ mpz_set_si (z, -1L);
+ mpz_mul_2exp (z, z, data[i]);
+ want = -0.5;
+ want_exp = data[i] + 1;
+ got = mpz_get_d_2exp (&got_exp, z);
+ if (got != want || got_exp != want_exp)
+ {
+ printf ("mpz_get_d_2exp wrong on -2**%ld\n", data[i]);
+ mpz_trace (" z ", z);
+ d_trace (" want ", want);
+ d_trace (" got ", got);
+ printf (" want exp %ld\n", want_exp);
+ printf (" got exp %ld\n", got_exp);
+ abort();
+ }
+ }
+ mpz_clear (z);
+}
+
+/* Check that hardware rounding doesn't make mpz_get_d_2exp return a value
+ outside its defined range. */
+static void
+check_round (void)
+{
+ static const unsigned long data[] = { 1, 32, 53, 54, 64, 128, 256, 512 };
+ mpz_t z;
+ double got;
+ long got_exp;
+ int i, rnd_mode, old_rnd_mode;
+
+ mpz_init (z);
+ old_rnd_mode = tests_hardware_getround ();
+
+ for (rnd_mode = 0; rnd_mode < 4; rnd_mode++)
+ {
+ tests_hardware_setround (rnd_mode);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_ui (z, 1L);
+ mpz_mul_2exp (z, z, data[i]);
+ mpz_sub_ui (z, z, 1L);
+
+ got = mpz_get_d_2exp (&got_exp, z);
+ if (got < 0.5 || got >= 1.0)
+ {
+ printf ("mpz_get_d_2exp wrong on 2**%lu-1\n", data[i]);
+ printf ("result out of range, expect 0.5 <= got < 1.0\n");
+ printf (" rnd_mode = %d\n", rnd_mode);
+ printf (" data[i] = %lu\n", data[i]);
+ mpz_trace (" z ", z);
+ d_trace (" got ", got);
+ printf (" got exp %ld\n", got_exp);
+ abort();
+ }
+
+ mpz_neg (z, z);
+ got = mpz_get_d_2exp (&got_exp, z);
+ if (got <= -1.0 || got > -0.5)
+ {
+ printf ("mpz_get_d_2exp wrong on -2**%lu-1\n", data[i]);
+ printf ("result out of range, expect -1.0 < got <= -0.5\n");
+ printf (" rnd_mode = %d\n", rnd_mode);
+ printf (" data[i] = %lu\n", data[i]);
+ mpz_trace (" z ", z);
+ d_trace (" got ", got);
+ printf (" got exp %ld\n", got_exp);
+ abort();
+ }
+ }
+ }
+
+ mpz_clear (z);
+ tests_hardware_setround (old_rnd_mode);
+}
+
+static void
+check_rand (void)
+{
+ gmp_randstate_ptr rands = RANDS;
+ int i;
+ mpz_t z;
+ double got;
+ long got_exp;
+ unsigned long bits;
+
+ mpz_init (z);
+
+ for (i = 0; i < 200; i++)
+ {
+ bits = gmp_urandomm_ui (rands, 512L);
+ mpz_urandomb (z, rands, bits);
+
+ got = mpz_get_d_2exp (&got_exp, z);
+ if (mpz_sgn (z) == 0)
+ continue;
+ bits = mpz_sizeinbase (z, 2);
+
+ if (got < 0.5 || got >= 1.0)
+ {
+ printf ("mpz_get_d_2exp out of range, expect 0.5 <= got < 1.0\n");
+ mpz_trace (" z ", z);
+ d_trace (" got ", got);
+ printf (" got exp %ld\n", got_exp);
+ abort();
+ }
+
+ /* FIXME: If mpz_get_d_2exp rounds upwards we might have got_exp ==
+ bits+1, so leave this test disabled until we decide if that's what
+ should happen, or not. */
+#if 0
+ if (got_exp != bits)
+ {
+ printf ("mpz_get_d_2exp wrong exponent\n", i);
+ mpz_trace (" z ", z);
+ d_trace (" bits ", bits);
+ d_trace (" got ", got);
+ printf (" got exp %ld\n", got_exp);
+ abort();
+ }
+#endif
+ }
+ mpz_clear (z);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_zero ();
+ check_onebit ();
+ check_round ();
+ check_rand ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-get_si.c b/gmp/tests/mpz/t-get_si.c
new file mode 100644
index 0000000000..083ada7f1e
--- /dev/null
+++ b/gmp/tests/mpz/t-get_si.c
@@ -0,0 +1,122 @@
+/* Exercise mpz_get_si.
+
+Copyright 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *n;
+ long want;
+ } data[] = {
+ { "0", 0L },
+ { "1", 1L },
+ { "-1", -1L },
+ { "2", 2L },
+ { "-2", -2L },
+ { "12345", 12345L },
+ { "-12345", -12345L },
+ };
+
+ int i;
+ mpz_t n;
+ long got;
+
+ mpz_init (n);
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (n, data[i].n, 0);
+
+ got = mpz_get_si (n);
+ if (got != data[i].want)
+ {
+ printf ("mpz_get_si wrong at data[%d]\n", i);
+ printf (" n \"%s\" (", data[i].n);
+ mpz_out_str (stdout, 10, n); printf (", hex ");
+ mpz_out_str (stdout, 16, n); printf (")\n");
+ printf (" got %ld (0x%lX)\n", got, got);
+ printf (" want %ld (0x%lX)\n", data[i].want, data[i].want);
+ abort();
+ }
+ }
+ mpz_clear (n);
+}
+
+
+void
+check_max (void)
+{
+ mpz_t n;
+ long want;
+ long got;
+
+ mpz_init (n);
+
+#define CHECK_MAX(name) \
+ if (got != want) \
+ { \
+ printf ("mpz_get_si wrong on %s\n", name); \
+ printf (" n "); \
+ mpz_out_str (stdout, 10, n); printf (", hex "); \
+ mpz_out_str (stdout, 16, n); printf ("\n"); \
+ printf (" got %ld, hex %lX\n", got, got); \
+ printf (" want %ld, hex %lX\n", want, want); \
+ abort(); \
+ }
+
+ want = LONG_MAX;
+ mpz_set_si (n, want);
+ got = mpz_get_si (n);
+ CHECK_MAX ("LONG_MAX");
+
+ want = LONG_MIN;
+ mpz_set_si (n, want);
+ got = mpz_get_si (n);
+ CHECK_MAX ("LONG_MIN");
+
+ /* The following checks that -0x100000000 gives -0x80000000. This doesn't
+ actually fit in a long and the result from mpz_get_si() is undefined,
+ but -0x80000000 is what comes out currently, and it should be that
+ value irrespective of the mp_limb_t size (long or long long). */
+
+ want = LONG_MIN;
+ mpz_mul_2exp (n, n, 1);
+ CHECK_MAX ("-0x100...00");
+
+ mpz_clear (n);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+ check_max ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-hamdist.c b/gmp/tests/mpz/t-hamdist.c
new file mode 100644
index 0000000000..f39c8ab8c2
--- /dev/null
+++ b/gmp/tests/mpz/t-hamdist.c
@@ -0,0 +1,124 @@
+/* Test mpz_hamdist.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_twobits (void)
+{
+ unsigned long i, j, got, want;
+ mpz_t x, y;
+
+ mpz_init (x);
+ mpz_init (y);
+ for (i = 0; i < 5 * GMP_NUMB_BITS; i++)
+ {
+ for (j = 0; j < 5 * GMP_NUMB_BITS; j++)
+ {
+ mpz_set_ui (x, 0L);
+ mpz_setbit (x, i);
+ mpz_set_ui (y, 0L);
+ mpz_setbit (y, j);
+
+ want = 2 * (i != j);
+ got = mpz_hamdist (x, y);
+ if (got != want)
+ {
+ printf ("mpz_hamdist wrong on 2 bits pos/pos\n");
+ wrong:
+ printf (" i %lu\n", i);
+ printf (" j %lu\n", j);
+ printf (" got %lu\n", got);
+ printf (" want %lu\n", want);
+ mpz_trace (" x ", x);
+ mpz_trace (" y ", y);
+ abort();
+ }
+
+ mpz_neg (x, x);
+ mpz_neg (y, y);
+ want = ABS ((long) (i-j));
+ got = mpz_hamdist (x, y);
+ if (got != want)
+ {
+ printf ("mpz_hamdist wrong on 2 bits neg/neg\n");
+ goto wrong;
+ }
+ }
+
+ }
+ mpz_clear (x);
+ mpz_clear (y);
+}
+
+
+void
+check_rand (void)
+{
+ gmp_randstate_ptr rands = RANDS;
+ unsigned long got, want;
+ int i;
+ mpz_t x, y;
+
+ mpz_init (x);
+ mpz_init (y);
+
+ for (i = 0; i < 2000; i++)
+ {
+ mpz_erandomb (x, rands, 6 * GMP_NUMB_BITS);
+ mpz_negrandom (x, rands);
+ mpz_mul_2exp (x, x, urandom() % (4 * GMP_NUMB_BITS));
+
+ mpz_erandomb (y, rands, 6 * GMP_NUMB_BITS);
+ mpz_negrandom (y, rands);
+ mpz_mul_2exp (y, y, urandom() % (4 * GMP_NUMB_BITS));
+
+ want = refmpz_hamdist (x, y);
+ got = mpz_hamdist (x, y);
+ if (got != want)
+ {
+ printf ("mpz_hamdist wrong on random\n");
+ printf (" got %lu\n", got);
+ printf (" want %lu\n", want);
+ mpz_trace (" x ", x);
+ mpz_trace (" y ", y);
+ abort();
+ }
+ }
+ mpz_clear (x);
+ mpz_clear (y);
+}
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_twobits ();
+ check_rand ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-import.c b/gmp/tests/mpz/t-import.c
new file mode 100644
index 0000000000..8d10fdc8aa
--- /dev/null
+++ b/gmp/tests/mpz/t-import.c
@@ -0,0 +1,176 @@
+/* Test mpz_import.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *want;
+ size_t count;
+ int order;
+ size_t size;
+ int endian;
+ int nail;
+ char src[64];
+
+ } data[] = {
+
+ { "0", 0,1, 1,1, 0 },
+ { "0", 1,1, 0,1, 0 },
+
+ { "0x12345678", 4,1, 1,1, 0, { '\22', '\64', '\126', '\170' } },
+ { "0x12345678", 1,1, 4,1, 0, { '\22', '\64', '\126', '\170' } },
+ { "0x12345678", 1,-1, 4,1, 0, { '\22', '\64', '\126', '\170' } },
+
+ { "0x12345678", 4,-1, 1,-1, 0, { '\170', '\126', '\064', '\22' } },
+ { "0x12345678", 1,1, 4,-1, 0, { '\170', '\126', '\064', '\22' } },
+ { "0x12345678", 1,-1, 4,-1, 0, { '\170', '\126', '\064', '\22' } },
+
+ { "0", 5,1, 1,1, 7, { '\376', '\376', '\376', '\376', '\376' } },
+ { "0", 5,-1, 1,1, 7, { '\376', '\376', '\376', '\376', '\376' } },
+ { "0x15", 5,1, 1,1, 7, { '\377', '\376', '\377', '\376', '\377' } },
+
+ { "0", 3,1, 2,1, 1, { '\200','\000', '\200','\000', '\200','\000' }},
+ { "0", 3,1, 2,-1, 1, { '\000','\200', '\000','\200', '\000','\200' }},
+ { "0", 3,1, 2,1, 15, { '\377','\376', '\377','\376', '\377','\376' }},
+
+ { "0x2A", 3,1, 2,1, 14, { '\377','\376', '\377','\376', '\377','\376' } },
+ { "0x06", 3,1, 2,1, 14, { '\377','\374', '\377','\375', '\377','\376' } },
+ { "0x24", 3,-1, 2,1, 14, { '\377','\374', '\377','\375', '\377','\376' } },
+
+ { "0x123456789ABC", 3,1, 2,1, 0, {
+ '\022','\064', '\126','\170', '\232','\274' } },
+ { "0x123456789ABC", 3,-1, 2,1, 0, {
+ '\232','\274', '\126','\170', '\022','\064' } },
+ { "0x123456789ABC", 3,1, 2,-1, 0, {
+ '\064','\022', '\170','\126', '\274','\232' } },
+ { "0x123456789ABC", 3,-1, 2,-1, 0, {
+ '\274','\232', '\170','\126', '\064','\022' } },
+
+ { "0x112233445566778899AABBCC", 3,1, 4,1, 0,
+ { '\021','\042','\063','\104',
+ '\125','\146','\167','\210',
+ '\231','\252','\273','\314' } },
+ { "0x112233445566778899AABBCC", 3,-1, 4,1, 0,
+ { '\231','\252','\273','\314',
+ '\125','\146','\167','\210',
+ '\021','\042','\063','\104' } },
+ { "0x112233445566778899AABBCC", 3,1, 4,-1, 0,
+ { '\104','\063','\042','\021',
+ '\210','\167','\146','\125',
+ '\314','\273','\252','\231' } },
+ { "0x112233445566778899AABBCC", 3,-1, 4,-1, 0,
+ { '\314','\273','\252','\231',
+ '\210','\167','\146','\125',
+ '\104','\063','\042','\021' } },
+
+ { "0x100120023003400450056006700780089009A00AB00BC00C", 3,1, 8,1, 0,
+ { '\020','\001','\040','\002','\060','\003','\100','\004',
+ '\120','\005','\140','\006','\160','\007','\200','\010',
+ '\220','\011','\240','\012','\260','\013','\300','\014' } },
+ { "0x100120023003400450056006700780089009A00AB00BC00C", 3,-1, 8,1, 0,
+ { '\220','\011','\240','\012','\260','\013','\300','\014',
+ '\120','\005','\140','\006','\160','\007','\200','\010',
+ '\020','\001','\040','\002','\060','\003','\100','\004' } },
+ { "0x100120023003400450056006700780089009A00AB00BC00C", 3,1, 8,-1, 0,
+ { '\004','\100','\003','\060','\002','\040','\001','\020',
+ '\010','\200','\007','\160','\006','\140','\005','\120',
+ '\014','\300','\013','\260','\012','\240','\011','\220' } },
+ { "0x100120023003400450056006700780089009A00AB00BC00C", 3,-1, 8,-1, 0,
+ { '\014','\300','\013','\260','\012','\240','\011','\220',
+ '\010','\200','\007','\160','\006','\140','\005','\120',
+ '\004','\100','\003','\060','\002','\040','\001','\020' } },
+
+ { "0x155555555555555555555555", 3,1, 4,1, 1,
+ { '\325','\125','\125','\125',
+ '\252','\252','\252','\252',
+ '\325','\125','\125','\125' } },
+ { "0x155555555555555555555555", 3,-1, 4,1, 1,
+ { '\325','\125','\125','\125',
+ '\252','\252','\252','\252',
+ '\325','\125','\125','\125' } },
+ { "0x155555555555555555555555", 3,1, 4,-1, 1,
+ { '\125','\125','\125','\325',
+ '\252','\252','\252','\252',
+ '\125','\125','\125','\325' } },
+ { "0x155555555555555555555555", 3,-1, 4,-1, 1,
+ { '\125','\125','\125','\325',
+ '\252','\252','\252','\252',
+ '\125','\125','\125','\325' } },
+ };
+
+ char buf[sizeof(data[0].src) + sizeof (mp_limb_t)];
+ char *src;
+ size_t align;
+ int i;
+ mpz_t got, want;
+
+ mpz_init (got);
+ mpz_init (want);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ for (align = 0; align < sizeof (mp_limb_t); align++)
+ {
+ mpz_set_str_or_abort (want, data[i].want, 0);
+ src = buf + align;
+ memcpy (src, data[i].src, data[i].count * data[i].size);
+
+ mpz_set_ui (got, 0L);
+ mpz_import (got, data[i].count, data[i].order,
+ data[i].size, data[i].endian, data[i].nail, src);
+
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("wrong at data[%d]\n", i);
+ printf (" count=%lu order=%d size=%lu endian=%d nail=%u align=%lu\n",
+ (unsigned long) data[i].count, data[i].order,
+ (unsigned long) data[i].size, data[i].endian, data[i].nail,
+ (unsigned long) align);
+ mpz_trace (" got ", got);
+ mpz_trace (" want", want);
+ abort ();
+ }
+ }
+ }
+ mpz_clear (got);
+ mpz_clear (want);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ mp_trace_base = -16;
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-inp_str.c b/gmp/tests/mpz/t-inp_str.c
new file mode 100644
index 0000000000..f50290bff6
--- /dev/null
+++ b/gmp/tests/mpz/t-inp_str.c
@@ -0,0 +1,199 @@
+/* Test mpz_inp_str.
+
+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 "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for unlink */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#define FILENAME "t-inp_str.tmp"
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *inp;
+ int base;
+ const char *want;
+ int want_nread;
+
+ } data[] = {
+
+ { "0", 10, "0", 1 },
+
+ { "abc", 10, "0", 0 },
+ { "0xf", 10, "0", 1 },
+ { "ghi", 16, "0", 0 },
+ { "100", 90, "0", 0 },
+
+ { "ff", 16, "255", 2 },
+ { "-ff", 16, "-255", 3 },
+ { "FF", 16, "255", 2 },
+ { "-FF", 16, "-255", 3 },
+
+ { "z", 36, "35", 1 },
+ { "Z", 36, "35", 1 },
+ { "1B", 59, "70", 2 },
+ { "a", 60, "36", 1 },
+ { "A", 61, "10", 1 },
+
+ { "0x0", 0, "0", 3 },
+ { "0X10", 0, "16", 4 },
+ { "-0X0", 0, "0", 4 },
+ { "-0x10", 0, "-16", 5 },
+
+ { "0b0", 0, "0", 3 },
+ { "0B10", 0, "2", 4 },
+ { "-0B0", 0, "0", 4 },
+ { "-0b10", 0, "-2", 5 },
+
+ { "00", 0, "0", 2 },
+ { "010", 0, "8", 3 },
+ { "-00", 0, "0", 3 },
+ { "-010", 0, "-8", 4 },
+
+ { "0x", 0, "0", 2 },
+ { "0", 0, "0", 1 },
+ { " 030", 10, "30", 4 },
+ };
+
+ mpz_t got, want;
+ long ftell_nread;
+ int i, pre, post, j, got_nread, want_nread;
+ FILE *fp;
+
+ mpz_init (got);
+ mpz_init (want);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ for (pre = 0; pre <= 3; pre++)
+ {
+ for (post = 0; post <= 2; post++)
+ {
+ mpz_set_str_or_abort (want, data[i].want, 0);
+ MPZ_CHECK_FORMAT (want);
+
+ /* create the file new each time to ensure its length is what
+ we want */
+ fp = fopen (FILENAME, "w+");
+ ASSERT_ALWAYS (fp != NULL);
+ for (j = 0; j < pre; j++)
+ putc (' ', fp);
+ fputs (data[i].inp, fp);
+ for (j = 0; j < post; j++)
+ putc (' ', fp);
+ fflush (fp);
+ ASSERT_ALWAYS (! ferror(fp));
+
+ rewind (fp);
+ got_nread = mpz_inp_str (got, fp, data[i].base);
+
+ if (got_nread != 0)
+ {
+ ftell_nread = ftell (fp);
+ if (got_nread != ftell_nread)
+ {
+ printf ("mpz_inp_str nread wrong\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ printf (" pre %d\n", pre);
+ printf (" post %d\n", post);
+ printf (" got_nread %d\n", got_nread);
+ printf (" ftell_nread %ld\n", ftell_nread);
+ abort ();
+ }
+ }
+
+ /* if data[i].inp is a whole string to read and there's no post
+ whitespace then expect to have EOF */
+ if (post == 0 && data[i].want_nread == strlen(data[i].inp))
+ {
+ int c = getc(fp);
+ if (c != EOF)
+ {
+ printf ("mpz_inp_str didn't read to EOF\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ printf (" pre %d\n", pre);
+ printf (" post %d\n", post);
+ printf (" c '%c' %#x\n", c, c);
+ abort ();
+ }
+ }
+
+ /* only expect "pre" included in the count when non-zero */
+ want_nread = data[i].want_nread;
+ if (want_nread != 0)
+ want_nread += pre;
+
+ if (got_nread != want_nread)
+ {
+ printf ("mpz_inp_str nread wrong\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ printf (" pre %d\n", pre);
+ printf (" post %d\n", post);
+ printf (" got_nread %d\n", got_nread);
+ printf (" want_nread %d\n", want_nread);
+ abort ();
+ }
+
+ MPZ_CHECK_FORMAT (got);
+
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_inp_str wrong result\n");
+ printf (" inp \"%s\"\n", data[i].inp);
+ printf (" base %d\n", data[i].base);
+ mpz_trace (" got ", got);
+ mpz_trace (" want", want);
+ abort ();
+ }
+
+ ASSERT_ALWAYS (fclose (fp) == 0);
+ }
+ }
+ }
+
+ mpz_clear (got);
+ mpz_clear (want);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ unlink (FILENAME);
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-invert.c b/gmp/tests/mpz/t-invert.c
new file mode 100644
index 0000000000..a033409a2f
--- /dev/null
+++ b/gmp/tests/mpz/t-invert.c
@@ -0,0 +1,121 @@
+/* Test mpz_invert.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-2005, 2008, 2009, 2012, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+int
+main (int argc, char **argv)
+{
+ mpz_t a, m, ainv, t;
+ int test, r;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+ int reps = 1000;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ mpz_init (bs);
+ mpz_init (a);
+ mpz_init (m);
+ mpz_init (ainv);
+ mpz_init (t);
+
+ for (test = 0; test < reps; test++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 16 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (a, rands, mpz_get_ui (bs));
+ do {
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (m, rands, mpz_get_ui (bs));
+ } while (mpz_sgn (m) == 0);
+
+ mpz_urandomb (bs, rands, 8);
+ bsi = mpz_get_ui (bs);
+
+ if ((bsi & 1) != 0)
+ mpz_neg (a, a);
+ if ((bsi & 2) != 0)
+ mpz_neg (m, m);
+
+ r = mpz_invert (ainv, a, m);
+ if (r != 0)
+ {
+ MPZ_CHECK_FORMAT (ainv);
+
+ if (mpz_cmp_ui (ainv, 0) < 0 || mpz_cmpabs (ainv, m) >= 0)
+ {
+ fprintf (stderr, "ERROR in test %d\n", test);
+ gmp_fprintf (stderr, "Inverse out of range.\n");
+ gmp_fprintf (stderr, "a = %Zx\n", a);
+ gmp_fprintf (stderr, "1/a = %Zx\n", ainv);
+ gmp_fprintf (stderr, "m = %Zx\n", m);
+ abort ();
+ }
+
+ mpz_mul (t, ainv, a);
+ mpz_mod (t, t, m);
+
+ if (mpz_cmp_ui (t, mpz_cmpabs_ui (m, 1) != 0) != 0)
+ {
+ fprintf (stderr, "ERROR in test %d\n", test);
+ gmp_fprintf (stderr, "a^(-1)*a != 1 (mod m)\n");
+ gmp_fprintf (stderr, "a = %Zx\n", a);
+ gmp_fprintf (stderr, "m = %Zx\n", m);
+ abort ();
+ }
+ }
+ else /* Inverse deos not exist */
+ {
+ if (mpz_cmpabs_ui (m, 1) <= 0)
+ continue; /* OK */
+
+ mpz_gcd (t, a, m);
+ if (mpz_cmp_ui (t, 1) == 0)
+ {
+ fprintf (stderr, "ERROR in test %d\n", test);
+ gmp_fprintf (stderr, "Inverse exists, but was not found.\n");
+ gmp_fprintf (stderr, "a = %Zx\n", a);
+ gmp_fprintf (stderr, "m = %Zx\n", m);
+ abort ();
+ }
+ }
+ }
+
+ mpz_clear (bs);
+ mpz_clear (a);
+ mpz_clear (m);
+ mpz_clear (ainv);
+ mpz_clear (t);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-io_raw.c b/gmp/tests/mpz/t-io_raw.c
new file mode 100644
index 0000000000..e06e7bb14b
--- /dev/null
+++ b/gmp/tests/mpz/t-io_raw.c
@@ -0,0 +1,287 @@
+/* Test mpz_inp_raw and mpz_out_raw.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define FILENAME "t-io_raw.tmp"
+
+
+/* In the fopen, "b" selects binary mode on DOS systems, meaning no
+ conversion of '\n' to and from CRLF. It's believed systems without such
+ nonsense will simply ignore the "b", but in case that's not so a plain
+ "w+" is attempted if "w+b" fails. */
+
+FILE *
+fopen_wplusb_or_die (const char *filename)
+{
+ FILE *fp;
+ fp = fopen (filename, "w+b");
+ if (fp == NULL)
+ fp = fopen (filename, "w+");
+
+ if (fp == NULL)
+ {
+ printf ("Cannot create file %s\n", filename);
+ abort ();
+ }
+ return fp;
+}
+
+/* use 0x80 to check nothing bad happens with sign extension etc */
+#define BYTEVAL(i) (((i) + 1) | 0x80)
+
+void
+check_in (void)
+{
+ int i, j, zeros, neg, error = 0;
+ mpz_t want, got;
+ size_t want_ret, got_ret;
+ mp_size_t size;
+ FILE *fp;
+
+ mpz_init (want);
+ mpz_init (got);
+
+ for (i = 0; i < 32; i++)
+ {
+ for (zeros = 0; zeros < 8; zeros++)
+ {
+ for (neg = 0; neg <= 1; neg++)
+ {
+ want_ret = i + zeros + 4;
+
+ /* need this to get the twos complement right */
+ ASSERT_ALWAYS (sizeof (size) >= 4);
+
+ size = i + zeros;
+ if (neg)
+ size = -size;
+
+ fp = fopen_wplusb_or_die (FILENAME);
+ for (j = 3; j >= 0; j--)
+ ASSERT_ALWAYS (putc ((size >> (j*8)) & 0xFF, fp) != EOF);
+ for (j = 0; j < zeros; j++)
+ ASSERT_ALWAYS (putc ('\0', fp) != EOF);
+ for (j = 0; j < i; j++)
+ ASSERT_ALWAYS (putc (BYTEVAL (j), fp) != EOF);
+ /* and some trailing garbage */
+ ASSERT_ALWAYS (putc ('x', fp) != EOF);
+ ASSERT_ALWAYS (putc ('y', fp) != EOF);
+ ASSERT_ALWAYS (putc ('z', fp) != EOF);
+ ASSERT_ALWAYS (fflush (fp) == 0);
+ rewind (fp);
+
+ got_ret = mpz_inp_raw (got, fp);
+ ASSERT_ALWAYS (! ferror(fp));
+ ASSERT_ALWAYS (fclose (fp) == 0);
+
+ MPZ_CHECK_FORMAT (got);
+
+ if (got_ret != want_ret)
+ {
+ printf ("check_in: return value wrong\n");
+ error = 1;
+ }
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("check_in: result wrong\n");
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" i=%d zeros=%d neg=%d\n", i, zeros, neg);
+ printf (" got_ret %lu\n", (unsigned long) got_ret);
+ printf (" want_ret %lu\n", (unsigned long) want_ret);
+ mpz_trace (" got ", got);
+ mpz_trace (" want ", want);
+ abort ();
+ }
+
+ mpz_neg (want, want);
+ }
+ }
+ mpz_mul_2exp (want, want, 8);
+ mpz_add_ui (want, want, (unsigned long) BYTEVAL (i));
+ }
+
+ mpz_clear (want);
+ mpz_clear (got);
+}
+
+
+void
+check_out (void)
+{
+ int i, j, neg, error = 0;
+ mpz_t z;
+ char want[256], got[256], *p;
+ size_t want_len, got_ret, got_read;
+ mp_size_t size;
+ FILE *fp;
+
+ mpz_init (z);
+
+ for (i = 0; i < 32; i++)
+ {
+ for (neg = 0; neg <= 1; neg++)
+ {
+ want_len = i + 4;
+
+ /* need this to get the twos complement right */
+ ASSERT_ALWAYS (sizeof (size) >= 4);
+
+ size = i;
+ if (neg)
+ size = -size;
+
+ p = want;
+ for (j = 3; j >= 0; j--)
+ *p++ = size >> (j*8);
+ for (j = 0; j < i; j++)
+ *p++ = BYTEVAL (j);
+ ASSERT_ALWAYS (p <= want + sizeof (want));
+
+ fp = fopen_wplusb_or_die (FILENAME);
+ got_ret = mpz_out_raw (fp, z);
+ ASSERT_ALWAYS (fflush (fp) == 0);
+ rewind (fp);
+ got_read = fread (got, 1, sizeof(got), fp);
+ ASSERT_ALWAYS (! ferror(fp));
+ ASSERT_ALWAYS (fclose (fp) == 0);
+
+ if (got_ret != want_len)
+ {
+ printf ("check_out: wrong return value\n");
+ error = 1;
+ }
+ if (got_read != want_len)
+ {
+ printf ("check_out: wrong number of bytes read back\n");
+ error = 1;
+ }
+ if (memcmp (want, got, want_len) != 0)
+ {
+ printf ("check_out: wrong data\n");
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" i=%d neg=%d\n", i, neg);
+ mpz_trace (" z", z);
+ printf (" got_ret %lu\n", (unsigned long) got_ret);
+ printf (" got_read %lu\n", (unsigned long) got_read);
+ printf (" want_len %lu\n", (unsigned long) want_len);
+ printf (" want");
+ for (j = 0; j < want_len; j++)
+ printf (" %02X", (unsigned) (unsigned char) want[j]);
+ printf ("\n");
+ printf (" got ");
+ for (j = 0; j < want_len; j++)
+ printf (" %02X", (unsigned) (unsigned char) got[j]);
+ printf ("\n");
+ abort ();
+ }
+
+ mpz_neg (z, z);
+ }
+ mpz_mul_2exp (z, z, 8);
+ mpz_add_ui (z, z, (unsigned long) BYTEVAL (i));
+ }
+
+ mpz_clear (z);
+}
+
+
+void
+check_rand (void)
+{
+ gmp_randstate_ptr rands = RANDS;
+ int i, error = 0;
+ mpz_t got, want;
+ size_t inp_ret, out_ret;
+ FILE *fp;
+
+ mpz_init (want);
+ mpz_init (got);
+
+ for (i = 0; i < 500; i++)
+ {
+ mpz_erandomb (want, rands, 10*GMP_LIMB_BITS);
+ mpz_negrandom (want, rands);
+
+ fp = fopen_wplusb_or_die (FILENAME);
+ out_ret = mpz_out_raw (fp, want);
+ ASSERT_ALWAYS (fflush (fp) == 0);
+ rewind (fp);
+ inp_ret = mpz_inp_raw (got, fp);
+ ASSERT_ALWAYS (fclose (fp) == 0);
+
+ MPZ_CHECK_FORMAT (got);
+
+ if (inp_ret != out_ret)
+ {
+ printf ("check_rand: different inp/out return values\n");
+ error = 1;
+ }
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("check_rand: wrong result\n");
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" out_ret %lu\n", (unsigned long) out_ret);
+ printf (" inp_ret %lu\n", (unsigned long) inp_ret);
+ mpz_trace (" want", want);
+ mpz_trace (" got ", got);
+ abort ();
+ }
+ }
+
+ mpz_clear (got);
+ mpz_clear (want);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_in ();
+ check_out ();
+ check_rand ();
+
+ unlink (FILENAME);
+ tests_end ();
+
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-jac.c b/gmp/tests/mpz/t-jac.c
new file mode 100644
index 0000000000..b6a0c33106
--- /dev/null
+++ b/gmp/tests/mpz/t-jac.c
@@ -0,0 +1,1012 @@
+/* Exercise mpz_*_kronecker_*() and mpz_jacobi() functions.
+
+Copyright 1999-2004, 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/. */
+
+
+/* With no arguments the various Kronecker/Jacobi symbol routines are
+ checked against some test data and a lot of derived data.
+
+ To check the test data against PARI-GP, run
+
+ t-jac -p | gp -q
+
+ It takes a while because the output from "t-jac -p" is big.
+
+
+ Enhancements:
+
+ More big test cases than those given by check_squares_zi would be good. */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifdef _LONG_LONG_LIMB
+#define LL(l,ll) ll
+#else
+#define LL(l,ll) l
+#endif
+
+
+int option_pari = 0;
+
+
+unsigned long
+mpz_mod4 (mpz_srcptr z)
+{
+ mpz_t m;
+ unsigned long ret;
+
+ mpz_init (m);
+ mpz_fdiv_r_2exp (m, z, 2);
+ ret = mpz_get_ui (m);
+ mpz_clear (m);
+ return ret;
+}
+
+int
+mpz_fits_ulimb_p (mpz_srcptr z)
+{
+ return (SIZ(z) == 1 || SIZ(z) == 0);
+}
+
+mp_limb_t
+mpz_get_ulimb (mpz_srcptr z)
+{
+ if (SIZ(z) == 0)
+ return 0;
+ else
+ return PTR(z)[0];
+}
+
+
+void
+try_base (mp_limb_t a, mp_limb_t b, int answer)
+{
+ int got;
+
+ if ((b & 1) == 0 || b == 1 || a > b)
+ return;
+
+ got = mpn_jacobi_base (a, b, 0);
+ if (got != answer)
+ {
+ printf (LL("mpn_jacobi_base (%lu, %lu) is %d should be %d\n",
+ "mpn_jacobi_base (%llu, %llu) is %d should be %d\n"),
+ a, b, got, answer);
+ abort ();
+ }
+}
+
+
+void
+try_zi_ui (mpz_srcptr a, unsigned long b, int answer)
+{
+ int got;
+
+ got = mpz_kronecker_ui (a, b);
+ if (got != answer)
+ {
+ printf ("mpz_kronecker_ui (");
+ mpz_out_str (stdout, 10, a);
+ printf (", %lu) is %d should be %d\n", b, got, answer);
+ abort ();
+ }
+}
+
+
+void
+try_zi_si (mpz_srcptr a, long b, int answer)
+{
+ int got;
+
+ got = mpz_kronecker_si (a, b);
+ if (got != answer)
+ {
+ printf ("mpz_kronecker_si (");
+ mpz_out_str (stdout, 10, a);
+ printf (", %ld) is %d should be %d\n", b, got, answer);
+ abort ();
+ }
+}
+
+
+void
+try_ui_zi (unsigned long a, mpz_srcptr b, int answer)
+{
+ int got;
+
+ got = mpz_ui_kronecker (a, b);
+ if (got != answer)
+ {
+ printf ("mpz_ui_kronecker (%lu, ", a);
+ mpz_out_str (stdout, 10, b);
+ printf (") is %d should be %d\n", got, answer);
+ abort ();
+ }
+}
+
+
+void
+try_si_zi (long a, mpz_srcptr b, int answer)
+{
+ int got;
+
+ got = mpz_si_kronecker (a, b);
+ if (got != answer)
+ {
+ printf ("mpz_si_kronecker (%ld, ", a);
+ mpz_out_str (stdout, 10, b);
+ printf (") is %d should be %d\n", got, answer);
+ abort ();
+ }
+}
+
+
+/* Don't bother checking mpz_jacobi, since it only differs for b even, and
+ we don't have an actual expected answer for it. tests/devel/try.c does
+ some checks though. */
+void
+try_zi_zi (mpz_srcptr a, mpz_srcptr b, int answer)
+{
+ int got;
+
+ got = mpz_kronecker (a, b);
+ if (got != answer)
+ {
+ printf ("mpz_kronecker (");
+ mpz_out_str (stdout, 10, a);
+ printf (", ");
+ mpz_out_str (stdout, 10, b);
+ printf (") is %d should be %d\n", got, answer);
+ abort ();
+ }
+}
+
+
+void
+try_pari (mpz_srcptr a, mpz_srcptr b, int answer)
+{
+ printf ("try(");
+ mpz_out_str (stdout, 10, a);
+ printf (",");
+ mpz_out_str (stdout, 10, b);
+ printf (",%d)\n", answer);
+}
+
+
+void
+try_each (mpz_srcptr a, mpz_srcptr b, int answer)
+{
+#if 0
+ fprintf(stderr, "asize = %d, bsize = %d\n",
+ mpz_sizeinbase (a, 2), mpz_sizeinbase (b, 2));
+#endif
+ if (option_pari)
+ {
+ try_pari (a, b, answer);
+ return;
+ }
+
+ if (mpz_fits_ulimb_p (a) && mpz_fits_ulimb_p (b))
+ try_base (mpz_get_ulimb (a), mpz_get_ulimb (b), answer);
+
+ if (mpz_fits_ulong_p (b))
+ try_zi_ui (a, mpz_get_ui (b), answer);
+
+ if (mpz_fits_slong_p (b))
+ try_zi_si (a, mpz_get_si (b), answer);
+
+ if (mpz_fits_ulong_p (a))
+ try_ui_zi (mpz_get_ui (a), b, answer);
+
+ if (mpz_fits_sint_p (a))
+ try_si_zi (mpz_get_si (a), b, answer);
+
+ try_zi_zi (a, b, answer);
+}
+
+
+/* Try (a/b) and (a/-b). */
+void
+try_pn (mpz_srcptr a, mpz_srcptr b_orig, int answer)
+{
+ mpz_t b;
+
+ mpz_init_set (b, b_orig);
+ try_each (a, b, answer);
+
+ mpz_neg (b, b);
+ if (mpz_sgn (a) < 0)
+ answer = -answer;
+
+ try_each (a, b, answer);
+
+ mpz_clear (b);
+}
+
+
+/* Try (a+k*p/b) for various k, using the fact (a/b) is periodic in a with
+ period p. For b>0, p=b if b!=2mod4 or p=4*b if b==2mod4. */
+
+void
+try_periodic_num (mpz_srcptr a_orig, mpz_srcptr b, int answer)
+{
+ mpz_t a, a_period;
+ int i;
+
+ if (mpz_sgn (b) <= 0)
+ return;
+
+ mpz_init_set (a, a_orig);
+ mpz_init_set (a_period, b);
+ if (mpz_mod4 (b) == 2)
+ mpz_mul_ui (a_period, a_period, 4);
+
+ /* don't bother with these tests if they're only going to produce
+ even/even */
+ if (mpz_even_p (a) && mpz_even_p (b) && mpz_even_p (a_period))
+ goto done;
+
+ for (i = 0; i < 6; i++)
+ {
+ mpz_add (a, a, a_period);
+ try_pn (a, b, answer);
+ }
+
+ mpz_set (a, a_orig);
+ for (i = 0; i < 6; i++)
+ {
+ mpz_sub (a, a, a_period);
+ try_pn (a, b, answer);
+ }
+
+ done:
+ mpz_clear (a);
+ mpz_clear (a_period);
+}
+
+
+/* Try (a/b+k*p) for various k, using the fact (a/b) is periodic in b of
+ period p.
+
+ period p
+ a==0,1mod4 a
+ a==2mod4 4*a
+ a==3mod4 and b odd 4*a
+ a==3mod4 and b even 8*a
+
+ In Henri Cohen's book the period is given as 4*a for all a==2,3mod4, but
+ a counterexample would seem to be (3/2)=-1 which with (3/14)=+1 doesn't
+ have period 4*a (but rather 8*a with (3/26)=-1). Maybe the plain 4*a is
+ to be read as applying to a plain Jacobi symbol with b odd, rather than
+ the Kronecker extension to b even. */
+
+void
+try_periodic_den (mpz_srcptr a, mpz_srcptr b_orig, int answer)
+{
+ mpz_t b, b_period;
+ int i;
+
+ if (mpz_sgn (a) == 0 || mpz_sgn (b_orig) == 0)
+ return;
+
+ mpz_init_set (b, b_orig);
+
+ mpz_init_set (b_period, a);
+ if (mpz_mod4 (a) == 3 && mpz_even_p (b))
+ mpz_mul_ui (b_period, b_period, 8L);
+ else if (mpz_mod4 (a) >= 2)
+ mpz_mul_ui (b_period, b_period, 4L);
+
+ /* don't bother with these tests if they're only going to produce
+ even/even */
+ if (mpz_even_p (a) && mpz_even_p (b) && mpz_even_p (b_period))
+ goto done;
+
+ for (i = 0; i < 6; i++)
+ {
+ mpz_add (b, b, b_period);
+ try_pn (a, b, answer);
+ }
+
+ mpz_set (b, b_orig);
+ for (i = 0; i < 6; i++)
+ {
+ mpz_sub (b, b, b_period);
+ try_pn (a, b, answer);
+ }
+
+ done:
+ mpz_clear (b);
+ mpz_clear (b_period);
+}
+
+
+static const unsigned long ktable[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1,
+ 2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1,
+ 3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1
+};
+
+
+/* Try (a/b*2^k) for various k. */
+void
+try_2den (mpz_srcptr a, mpz_srcptr b_orig, int answer)
+{
+ mpz_t b;
+ int kindex;
+ int answer_a2, answer_k;
+ unsigned long k;
+
+ /* don't bother when b==0 */
+ if (mpz_sgn (b_orig) == 0)
+ return;
+
+ mpz_init_set (b, b_orig);
+
+ /* (a/2) is 0 if a even, 1 if a==1 or 7 mod 8, -1 if a==3 or 5 mod 8 */
+ answer_a2 = (mpz_even_p (a) ? 0
+ : (((SIZ(a) >= 0 ? PTR(a)[0] : -PTR(a)[0]) + 2) & 7) < 4 ? 1
+ : -1);
+
+ for (kindex = 0; kindex < numberof (ktable); kindex++)
+ {
+ k = ktable[kindex];
+
+ /* answer_k = answer*(answer_a2^k) */
+ answer_k = (answer_a2 == 0 && k != 0 ? 0
+ : (k & 1) == 1 && answer_a2 == -1 ? -answer
+ : answer);
+
+ mpz_mul_2exp (b, b_orig, k);
+ try_pn (a, b, answer_k);
+ }
+
+ mpz_clear (b);
+}
+
+
+/* Try (a*2^k/b) for various k. If it happens mpz_ui_kronecker() gets (2/b)
+ wrong it will show up as wrong answers demanded. */
+void
+try_2num (mpz_srcptr a_orig, mpz_srcptr b, int answer)
+{
+ mpz_t a;
+ int kindex;
+ int answer_2b, answer_k;
+ unsigned long k;
+
+ /* don't bother when a==0 */
+ if (mpz_sgn (a_orig) == 0)
+ return;
+
+ mpz_init (a);
+
+ /* (2/b) is 0 if b even, 1 if b==1 or 7 mod 8, -1 if b==3 or 5 mod 8 */
+ answer_2b = (mpz_even_p (b) ? 0
+ : (((SIZ(b) >= 0 ? PTR(b)[0] : -PTR(b)[0]) + 2) & 7) < 4 ? 1
+ : -1);
+
+ for (kindex = 0; kindex < numberof (ktable); kindex++)
+ {
+ k = ktable[kindex];
+
+ /* answer_k = answer*(answer_2b^k) */
+ answer_k = (answer_2b == 0 && k != 0 ? 0
+ : (k & 1) == 1 && answer_2b == -1 ? -answer
+ : answer);
+
+ mpz_mul_2exp (a, a_orig, k);
+ try_pn (a, b, answer_k);
+ }
+
+ mpz_clear (a);
+}
+
+
+/* The try_2num() and try_2den() routines don't in turn call
+ try_periodic_num() and try_periodic_den() because it hugely increases the
+ number of tests performed, without obviously increasing coverage.
+
+ Useful extra derived cases can be added here. */
+
+void
+try_all (mpz_t a, mpz_t b, int answer)
+{
+ try_pn (a, b, answer);
+ try_periodic_num (a, b, answer);
+ try_periodic_den (a, b, answer);
+ try_2num (a, b, answer);
+ try_2den (a, b, answer);
+}
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *a;
+ const char *b;
+ int answer;
+
+ } data[] = {
+
+ /* Note that the various derived checks in try_all() reduce the cases
+ that need to be given here. */
+
+ /* some zeros */
+ { "0", "0", 0 },
+ { "0", "2", 0 },
+ { "0", "6", 0 },
+ { "5", "0", 0 },
+ { "24", "60", 0 },
+
+ /* (a/1) = 1, any a
+ In particular note (0/1)=1 so that (a/b)=(a mod b/b). */
+ { "0", "1", 1 },
+ { "1", "1", 1 },
+ { "2", "1", 1 },
+ { "3", "1", 1 },
+ { "4", "1", 1 },
+ { "5", "1", 1 },
+
+ /* (0/b) = 0, b != 1 */
+ { "0", "3", 0 },
+ { "0", "5", 0 },
+ { "0", "7", 0 },
+ { "0", "9", 0 },
+ { "0", "11", 0 },
+ { "0", "13", 0 },
+ { "0", "15", 0 },
+
+ /* (1/b) = 1 */
+ { "1", "1", 1 },
+ { "1", "3", 1 },
+ { "1", "5", 1 },
+ { "1", "7", 1 },
+ { "1", "9", 1 },
+ { "1", "11", 1 },
+
+ /* (-1/b) = (-1)^((b-1)/2) which is -1 for b==3 mod 4 */
+ { "-1", "1", 1 },
+ { "-1", "3", -1 },
+ { "-1", "5", 1 },
+ { "-1", "7", -1 },
+ { "-1", "9", 1 },
+ { "-1", "11", -1 },
+ { "-1", "13", 1 },
+ { "-1", "15", -1 },
+ { "-1", "17", 1 },
+ { "-1", "19", -1 },
+
+ /* (2/b) = (-1)^((b^2-1)/8) which is -1 for b==3,5 mod 8.
+ try_2num() will exercise multiple powers of 2 in the numerator. */
+ { "2", "1", 1 },
+ { "2", "3", -1 },
+ { "2", "5", -1 },
+ { "2", "7", 1 },
+ { "2", "9", 1 },
+ { "2", "11", -1 },
+ { "2", "13", -1 },
+ { "2", "15", 1 },
+ { "2", "17", 1 },
+
+ /* (-2/b) = (-1)^((b^2-1)/8)*(-1)^((b-1)/2) which is -1 for b==5,7mod8.
+ try_2num() will exercise multiple powers of 2 in the numerator, which
+ will test that the shift in mpz_si_kronecker() uses unsigned not
+ signed. */
+ { "-2", "1", 1 },
+ { "-2", "3", 1 },
+ { "-2", "5", -1 },
+ { "-2", "7", -1 },
+ { "-2", "9", 1 },
+ { "-2", "11", 1 },
+ { "-2", "13", -1 },
+ { "-2", "15", -1 },
+ { "-2", "17", 1 },
+
+ /* (a/2)=(2/a).
+ try_2den() will exercise multiple powers of 2 in the denominator. */
+ { "3", "2", -1 },
+ { "5", "2", -1 },
+ { "7", "2", 1 },
+ { "9", "2", 1 },
+ { "11", "2", -1 },
+
+ /* Harriet Griffin, "Elementary Theory of Numbers", page 155, various
+ examples. */
+ { "2", "135", 1 },
+ { "135", "19", -1 },
+ { "2", "19", -1 },
+ { "19", "135", 1 },
+ { "173", "135", 1 },
+ { "38", "135", 1 },
+ { "135", "173", 1 },
+ { "173", "5", -1 },
+ { "3", "5", -1 },
+ { "5", "173", -1 },
+ { "173", "3", -1 },
+ { "2", "3", -1 },
+ { "3", "173", -1 },
+ { "253", "21", 1 },
+ { "1", "21", 1 },
+ { "21", "253", 1 },
+ { "21", "11", -1 },
+ { "-1", "11", -1 },
+
+ /* Griffin page 147 */
+ { "-1", "17", 1 },
+ { "2", "17", 1 },
+ { "-2", "17", 1 },
+ { "-1", "89", 1 },
+ { "2", "89", 1 },
+
+ /* Griffin page 148 */
+ { "89", "11", 1 },
+ { "1", "11", 1 },
+ { "89", "3", -1 },
+ { "2", "3", -1 },
+ { "3", "89", -1 },
+ { "11", "89", 1 },
+ { "33", "89", -1 },
+
+ /* H. Davenport, "The Higher Arithmetic", page 65, the quadratic
+ residues and non-residues mod 19. */
+ { "1", "19", 1 },
+ { "4", "19", 1 },
+ { "5", "19", 1 },
+ { "6", "19", 1 },
+ { "7", "19", 1 },
+ { "9", "19", 1 },
+ { "11", "19", 1 },
+ { "16", "19", 1 },
+ { "17", "19", 1 },
+ { "2", "19", -1 },
+ { "3", "19", -1 },
+ { "8", "19", -1 },
+ { "10", "19", -1 },
+ { "12", "19", -1 },
+ { "13", "19", -1 },
+ { "14", "19", -1 },
+ { "15", "19", -1 },
+ { "18", "19", -1 },
+
+ /* Residues and non-residues mod 13 */
+ { "0", "13", 0 },
+ { "1", "13", 1 },
+ { "2", "13", -1 },
+ { "3", "13", 1 },
+ { "4", "13", 1 },
+ { "5", "13", -1 },
+ { "6", "13", -1 },
+ { "7", "13", -1 },
+ { "8", "13", -1 },
+ { "9", "13", 1 },
+ { "10", "13", 1 },
+ { "11", "13", -1 },
+ { "12", "13", 1 },
+
+ /* various */
+ { "5", "7", -1 },
+ { "15", "17", 1 },
+ { "67", "89", 1 },
+
+ /* special values inducing a==b==1 at the end of jac_or_kron() */
+ { "0x10000000000000000000000000000000000000000000000001",
+ "0x10000000000000000000000000000000000000000000000003", 1 },
+
+ /* Test for previous bugs in jacobi_2. */
+ { "0x43900000000", "0x42400000439", -1 }, /* 32-bit limbs */
+ { "0x4390000000000000000", "0x4240000000000000439", -1 }, /* 64-bit limbs */
+
+ { "198158408161039063", "198158360916398807", -1 },
+
+ /* Some tests involving large quotients in the continued fraction
+ expansion. */
+ { "37200210845139167613356125645445281805",
+ "451716845976689892447895811408978421929", -1 },
+ { "67674091930576781943923596701346271058970643542491743605048620644676477275152701774960868941561652032482173612421015",
+ "4902678867794567120224500687210807069172039735", 0 },
+ { "2666617146103764067061017961903284334497474492754652499788571378062969111250584288683585223600172138551198546085281683283672592", "2666617146103764067061017961903284334497474492754652499788571378062969111250584288683585223600172138551198546085281683290481773", 1 },
+
+ /* Exercises the case asize == 1, btwos > 0 in mpz_jacobi. */
+ { "804609", "421248363205206617296534688032638102314410556521742428832362659824", 1 } ,
+ { "4190209", "2239744742177804210557442048984321017460028974602978995388383905961079286530650825925074203175536427000", 1 },
+
+ /* Exercises the case asize == 1, btwos = 63 in mpz_jacobi
+ (relevant when GMP_LIMB_BITS == 64). */
+ { "17311973299000934401", "1675975991242824637446753124775689449936871337036614677577044717424700351103148799107651171694863695242089956242888229458836426332300124417011114380886016", 1 },
+ { "3220569220116583677", "41859917623035396746", -1 },
+
+ /* Other test cases that triggered bugs during development. */
+ { "37200210845139167613356125645445281805", "340116213441272389607827434472642576514", -1 },
+ { "74400421690278335226712251290890563610", "451716845976689892447895811408978421929", -1 },
+ };
+
+ int i;
+ mpz_t a, b;
+
+ mpz_init (a);
+ mpz_init (b);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (a, data[i].a, 0);
+ mpz_set_str_or_abort (b, data[i].b, 0);
+ try_all (a, b, data[i].answer);
+ }
+
+ mpz_clear (a);
+ mpz_clear (b);
+}
+
+
+/* (a^2/b)=1 if gcd(a,b)=1, or (a^2/b)=0 if gcd(a,b)!=1.
+ This includes when a=0 or b=0. */
+void
+check_squares_zi (void)
+{
+ gmp_randstate_ptr rands = RANDS;
+ mpz_t a, b, g;
+ int i, answer;
+ mp_size_t size_range, an, bn;
+ mpz_t bs;
+
+ mpz_init (bs);
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (g);
+
+ for (i = 0; i < 50; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 10 + i/8 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ an = mpz_get_ui (bs);
+ mpz_rrandomb (a, rands, an);
+
+ mpz_urandomb (bs, rands, size_range);
+ bn = mpz_get_ui (bs);
+ mpz_rrandomb (b, rands, bn);
+
+ mpz_gcd (g, a, b);
+ if (mpz_cmp_ui (g, 1L) == 0)
+ answer = 1;
+ else
+ answer = 0;
+
+ mpz_mul (a, a, a);
+
+ try_all (a, b, answer);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (g);
+}
+
+
+/* Check the handling of asize==0, make sure it isn't affected by the low
+ limb. */
+void
+check_a_zero (void)
+{
+ mpz_t a, b;
+
+ mpz_init_set_ui (a, 0);
+ mpz_init (b);
+
+ mpz_set_ui (b, 1L);
+ PTR(a)[0] = 0;
+ try_all (a, b, 1); /* (0/1)=1 */
+ PTR(a)[0] = 1;
+ try_all (a, b, 1); /* (0/1)=1 */
+
+ mpz_set_si (b, -1L);
+ PTR(a)[0] = 0;
+ try_all (a, b, 1); /* (0/-1)=1 */
+ PTR(a)[0] = 1;
+ try_all (a, b, 1); /* (0/-1)=1 */
+
+ mpz_set_ui (b, 0);
+ PTR(a)[0] = 0;
+ try_all (a, b, 0); /* (0/0)=0 */
+ PTR(a)[0] = 1;
+ try_all (a, b, 0); /* (0/0)=0 */
+
+ mpz_set_ui (b, 2);
+ PTR(a)[0] = 0;
+ try_all (a, b, 0); /* (0/2)=0 */
+ PTR(a)[0] = 1;
+ try_all (a, b, 0); /* (0/2)=0 */
+
+ mpz_clear (a);
+ mpz_clear (b);
+}
+
+
+/* Assumes that b = prod p_k^e_k */
+int
+ref_jacobi (mpz_srcptr a, mpz_srcptr b, unsigned nprime,
+ mpz_t prime[], unsigned *exp)
+{
+ unsigned i;
+ int res;
+
+ for (i = 0, res = 1; i < nprime; i++)
+ if (exp[i])
+ {
+ int legendre = refmpz_legendre (a, prime[i]);
+ if (!legendre)
+ return 0;
+ if (exp[i] & 1)
+ res *= legendre;
+ }
+ return res;
+}
+
+void
+check_jacobi_factored (void)
+{
+#define PRIME_N 10
+#define PRIME_MAX_SIZE 50
+#define PRIME_MAX_EXP 4
+#define PRIME_A_COUNT 10
+#define PRIME_B_COUNT 5
+#define PRIME_MAX_B_SIZE 2000
+
+ gmp_randstate_ptr rands = RANDS;
+ mpz_t prime[PRIME_N];
+ unsigned exp[PRIME_N];
+ mpz_t a, b, t, bs;
+ unsigned i;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (t);
+ mpz_init (bs);
+
+ /* Generate primes */
+ for (i = 0; i < PRIME_N; i++)
+ {
+ mp_size_t size;
+ mpz_init (prime[i]);
+ mpz_urandomb (bs, rands, 32);
+ size = mpz_get_ui (bs) % PRIME_MAX_SIZE + 2;
+ mpz_rrandomb (prime[i], rands, size);
+ if (mpz_cmp_ui (prime[i], 3) <= 0)
+ mpz_set_ui (prime[i], 3);
+ else
+ mpz_nextprime (prime[i], prime[i]);
+ }
+
+ for (i = 0; i < PRIME_B_COUNT; i++)
+ {
+ unsigned j, k;
+ mp_bitcnt_t bsize;
+
+ mpz_set_ui (b, 1);
+ bsize = 1;
+
+ for (j = 0; j < PRIME_N && bsize < PRIME_MAX_B_SIZE; j++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ exp[j] = mpz_get_ui (bs) % PRIME_MAX_EXP;
+ mpz_pow_ui (t, prime[j], exp[j]);
+ mpz_mul (b, b, t);
+ bsize = mpz_sizeinbase (b, 2);
+ }
+ for (k = 0; k < PRIME_A_COUNT; k++)
+ {
+ int answer;
+ mpz_rrandomb (a, rands, bsize + 2);
+ answer = ref_jacobi (a, b, j, prime, exp);
+ try_all (a, b, answer);
+ }
+ }
+ for (i = 0; i < PRIME_N; i++)
+ mpz_clear (prime[i]);
+
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (t);
+ mpz_clear (bs);
+
+#undef PRIME_N
+#undef PRIME_MAX_SIZE
+#undef PRIME_MAX_EXP
+#undef PRIME_A_COUNT
+#undef PRIME_B_COUNT
+#undef PRIME_MAX_B_SIZE
+}
+
+/* These tests compute (a|n), where the quotient sequence includes
+ large quotients, and n has a known factorization. Such inputs are
+ generated as follows. First, construct a large n, as a power of a
+ prime p of moderate size.
+
+ Next, compute a matrix from factors (q,1;1,0), with q chosen with
+ uniformly distributed size. We must stop with matrix elements of
+ roughly half the size of n. Denote elements of M as M = (m00, m01;
+ m10, m11).
+
+ We now look for solutions to
+
+ n = m00 x + m01 y
+ a = m10 x + m11 y
+
+ with x,y > 0. Since n >= m00 * m01, there exists a positive
+ solution to the first equation. Find those x, y, and substitute in
+ the second equation to get a. Then the quotient sequence for (a|n)
+ is precisely the quotients used when constructing M, followed by
+ the quotient sequence for (x|y).
+
+ Numbers should also be large enough that we exercise hgcd_jacobi,
+ which means that they should be larger than
+
+ max (GCD_DC_THRESHOLD, 3 * HGCD_THRESHOLD)
+
+ With an n of roughly 40000 bits, this should hold on most machines.
+*/
+
+void
+check_large_quotients (void)
+{
+#define COUNT 50
+#define PBITS 200
+#define PPOWER 201
+#define MAX_QBITS 500
+
+ gmp_randstate_ptr rands = RANDS;
+
+ mpz_t p, n, q, g, s, t, x, y, bs;
+ mpz_t M[2][2];
+ mp_bitcnt_t nsize;
+ unsigned i;
+
+ mpz_init (p);
+ mpz_init (n);
+ mpz_init (q);
+ mpz_init (g);
+ mpz_init (s);
+ mpz_init (t);
+ mpz_init (x);
+ mpz_init (y);
+ mpz_init (bs);
+ mpz_init (M[0][0]);
+ mpz_init (M[0][1]);
+ mpz_init (M[1][0]);
+ mpz_init (M[1][1]);
+
+ /* First generate a number with known factorization, as a random
+ smallish prime raised to an odd power. Then (a|n) = (a|p). */
+ mpz_rrandomb (p, rands, PBITS);
+ mpz_nextprime (p, p);
+ mpz_pow_ui (n, p, PPOWER);
+
+ nsize = mpz_sizeinbase (n, 2);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ int answer;
+ mp_bitcnt_t msize;
+
+ mpz_set_ui (M[0][0], 1);
+ mpz_set_ui (M[0][1], 0);
+ mpz_set_ui (M[1][0], 0);
+ mpz_set_ui (M[1][1], 1);
+
+ for (msize = 1; 2*(msize + MAX_QBITS) + 1 < nsize ;)
+ {
+ unsigned i;
+ mpz_rrandomb (bs, rands, 32);
+ mpz_rrandomb (q, rands, 1 + mpz_get_ui (bs) % MAX_QBITS);
+
+ /* Multiply by (q, 1; 1,0) from the right */
+ for (i = 0; i < 2; i++)
+ {
+ mp_bitcnt_t size;
+ mpz_swap (M[i][0], M[i][1]);
+ mpz_addmul (M[i][0], M[i][1], q);
+ size = mpz_sizeinbase (M[i][0], 2);
+ if (size > msize)
+ msize = size;
+ }
+ }
+ mpz_gcdext (g, s, t, M[0][0], M[0][1]);
+ ASSERT_ALWAYS (mpz_cmp_ui (g, 1) == 0);
+
+ /* Solve n = M[0][0] * x + M[0][1] * y */
+ if (mpz_sgn (s) > 0)
+ {
+ mpz_mul (x, n, s);
+ mpz_fdiv_qr (q, x, x, M[0][1]);
+ mpz_mul (y, q, M[0][0]);
+ mpz_addmul (y, t, n);
+ ASSERT_ALWAYS (mpz_sgn (y) > 0);
+ }
+ else
+ {
+ mpz_mul (y, n, t);
+ mpz_fdiv_qr (q, y, y, M[0][0]);
+ mpz_mul (x, q, M[0][1]);
+ mpz_addmul (x, s, n);
+ ASSERT_ALWAYS (mpz_sgn (x) > 0);
+ }
+ mpz_mul (x, x, M[1][0]);
+ mpz_addmul (x, y, M[1][1]);
+
+ /* Now (x|n) has the selected large quotients */
+ answer = refmpz_legendre (x, p);
+ try_zi_zi (x, n, answer);
+ }
+ mpz_clear (p);
+ mpz_clear (n);
+ mpz_clear (q);
+ mpz_clear (g);
+ mpz_clear (s);
+ mpz_clear (t);
+ mpz_clear (x);
+ mpz_clear (y);
+ mpz_clear (bs);
+ mpz_clear (M[0][0]);
+ mpz_clear (M[0][1]);
+ mpz_clear (M[1][0]);
+ mpz_clear (M[1][1]);
+#undef COUNT
+#undef PBITS
+#undef PPOWER
+#undef MAX_QBITS
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ if (argc >= 2 && strcmp (argv[1], "-p") == 0)
+ {
+ option_pari = 1;
+
+ printf ("\
+try(a,b,answer) =\n\
+{\n\
+ if (kronecker(a,b) != answer,\n\
+ print(\"wrong at \", a, \",\", b,\n\
+ \" expected \", answer,\n\
+ \" pari says \", kronecker(a,b)))\n\
+}\n");
+ }
+
+ check_data ();
+ check_squares_zi ();
+ check_a_zero ();
+ check_jacobi_factored ();
+ check_large_quotients ();
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-lcm.c b/gmp/tests/mpz/t-lcm.c
new file mode 100644
index 0000000000..3cc41483ef
--- /dev/null
+++ b/gmp/tests/mpz/t-lcm.c
@@ -0,0 +1,185 @@
+/* Test mpz_lcm and mpz_lcm_ui.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_all (mpz_ptr want, mpz_srcptr x_orig, mpz_srcptr y_orig)
+{
+ mpz_t got, x, y;
+ int negx, negy, swap, inplace;
+
+ mpz_init (got);
+ mpz_init_set (x, x_orig);
+ mpz_init_set (y, y_orig);
+
+ for (swap = 0; swap < 2; swap++)
+ {
+ mpz_swap (x, y);
+
+ for (negx = 0; negx < 2; negx++)
+ {
+ mpz_neg (x, x);
+
+ for (negy = 0; negy < 2; negy++)
+ {
+ mpz_neg (y, y);
+
+ for (inplace = 0; inplace <= 1; inplace++)
+ {
+ if (inplace)
+ { mpz_set (got, x); mpz_lcm (got, got, y); }
+ else
+ mpz_lcm (got, x, y);
+ MPZ_CHECK_FORMAT (got);
+
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_lcm wrong, inplace=%d\n", inplace);
+ fail:
+ mpz_trace ("x", x);
+ mpz_trace ("y", y);
+ mpz_trace ("got", got);
+ mpz_trace ("want", want);
+ abort ();
+ }
+
+ if (mpz_fits_ulong_p (y))
+ {
+ unsigned long yu = mpz_get_ui (y);
+ if (inplace)
+ { mpz_set (got, x); mpz_lcm_ui (got, got, yu); }
+ else
+ mpz_lcm_ui (got, x, yu);
+
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_lcm_ui wrong, inplace=%d\n", inplace);
+ printf ("yu=%lu\n", yu);
+ goto fail;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ mpz_clear (got);
+ mpz_clear (x);
+ mpz_clear (y);
+}
+
+
+void
+check_primes (void)
+{
+ static unsigned long prime[] = {
+ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,
+ 101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,
+ 191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,
+ 281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,
+ 389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,
+ };
+ mpz_t want, x, y;
+ int i;
+
+ mpz_init (want);
+ mpz_init (x);
+ mpz_init (y);
+
+ /* Check zeros. */
+ mpz_set_ui (want, 0);
+ mpz_set_ui (x, 1);
+ check_all (want, want, want);
+ check_all (want, want, x);
+ check_all (want, x, want);
+
+ /* New prime each time. */
+ mpz_set_ui (want, 1L);
+ for (i = 0; i < numberof (prime); i++)
+ {
+ mpz_set (x, want);
+ mpz_set_ui (y, prime[i]);
+ mpz_mul_ui (want, want, prime[i]);
+ check_all (want, x, y);
+ }
+
+ /* Old prime each time. */
+ mpz_set (x, want);
+ for (i = 0; i < numberof (prime); i++)
+ {
+ mpz_set_ui (y, prime[i]);
+ check_all (want, x, y);
+ }
+
+ /* One old, one new each time. */
+ mpz_set_ui (want, prime[0]);
+ for (i = 1; i < numberof (prime); i++)
+ {
+ mpz_set (x, want);
+ mpz_set_ui (y, prime[i] * prime[i-1]);
+ mpz_mul_ui (want, want, prime[i]);
+ check_all (want, x, y);
+ }
+
+ /* Triplets with A,B in x and B,C in y. */
+ mpz_set_ui (want, 1L);
+ mpz_set_ui (x, 1L);
+ mpz_set_ui (y, 1L);
+ for (i = 0; i+2 < numberof (prime); i += 3)
+ {
+ mpz_mul_ui (want, want, prime[i]);
+ mpz_mul_ui (want, want, prime[i+1]);
+ mpz_mul_ui (want, want, prime[i+2]);
+
+ mpz_mul_ui (x, x, prime[i]);
+ mpz_mul_ui (x, x, prime[i+1]);
+
+ mpz_mul_ui (y, y, prime[i+1]);
+ mpz_mul_ui (y, y, prime[i+2]);
+
+ check_all (want, x, y);
+ }
+
+
+ mpz_clear (want);
+ mpz_clear (x);
+ mpz_clear (y);
+}
+
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ check_primes ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-limbs.c b/gmp/tests/mpz/t-limbs.c
new file mode 100644
index 0000000000..43bcfb03e8
--- /dev/null
+++ b/gmp/tests/mpz/t-limbs.c
@@ -0,0 +1,233 @@
+/* Test mpz_limbs_* functions
+
+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 <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define COUNT 100
+#define BITSIZE 500
+
+/* Like mpz_add. For simplicity, support positive inputs only. */
+static void
+alt_add (mpz_ptr r, mpz_srcptr a, mpz_srcptr b)
+{
+ mp_size_t an = mpz_size (a);
+ mp_size_t bn = mpz_size (b);
+ mp_ptr rp;
+
+ ASSERT (an > 0);
+ ASSERT (bn > 0);
+ if (an < bn)
+ {
+ MP_SIZE_T_SWAP (an, bn);
+ MPZ_SRCPTR_SWAP (a, b);
+ }
+ rp = mpz_limbs_modify (r, an + 1);
+ rp[an] = mpn_add (rp, mpz_limbs_read (a), an, mpz_limbs_read (b), bn);
+ mpz_limbs_finish (r, an + 1);
+}
+
+static void
+check_funcs (const char *name,
+ void (*f)(mpz_ptr, mpz_srcptr, mpz_srcptr),
+ void (*ref_f)(mpz_ptr, mpz_srcptr, mpz_srcptr),
+ mpz_srcptr a, mpz_srcptr b)
+{
+ mpz_t r, ref;
+ mpz_inits (r, ref, NULL);
+
+ ref_f (ref, a, b);
+ MPZ_CHECK_FORMAT (ref);
+ f (r, a, b);
+ MPZ_CHECK_FORMAT (r);
+
+ if (mpz_cmp (r, ref) != 0)
+ {
+ printf ("%s failed, abits %u, bbits %u\n",
+ name,
+ (unsigned) mpz_sizeinbase (a, 2),
+ (unsigned) mpz_sizeinbase (b, 2));
+ gmp_printf ("a = %Zx\n", a);
+ gmp_printf ("b = %Zx\n", b);
+ gmp_printf ("r = %Zx (bad)\n", r);
+ gmp_printf ("ref = %Zx\n", ref);
+ abort ();
+ }
+ mpz_clears (r, ref, NULL);
+}
+
+static void
+check_add (void)
+{
+ gmp_randstate_ptr rands = RANDS;
+ mpz_t bs, a, b;
+ unsigned i;
+ mpz_inits (bs, a, b, NULL);
+ for (i = 0; i < COUNT; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE);
+ mpz_urandomb (bs, rands, 32);
+ mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE);
+
+ check_funcs ("add", alt_add, mpz_add, a, b);
+ }
+ mpz_clears (bs, a, b, NULL);
+}
+
+static void
+alt_mul (mpz_ptr r, mpz_srcptr a, mpz_srcptr b)
+{
+ mp_size_t an = mpz_size (a);
+ mp_size_t bn = mpz_size (b);
+ mp_srcptr ap, bp;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ ASSERT (an > 0);
+ ASSERT (bn > 0);
+ if (an < bn)
+ {
+ MP_SIZE_T_SWAP (an, bn);
+ MPZ_SRCPTR_SWAP (a, b);
+ }
+ /* NOTE: This copying seems unnecessary; better to allocate new
+ result area, and free the old area when done. */
+ if (r == a)
+ {
+ mp_ptr tp = TMP_ALLOC_LIMBS (an);
+ MPN_COPY (tp, mpz_limbs_read (a), an);
+ ap = tp;
+ bp = (a == b) ? ap : mpz_limbs_read (b);
+ }
+ else if (r == b)
+ {
+ mp_ptr tp = TMP_ALLOC_LIMBS (bn);
+ MPN_COPY (tp, mpz_limbs_read (b), bn);
+ bp = tp;
+ ap = mpz_limbs_read (a);
+ }
+ else
+ {
+ ap = mpz_limbs_read (a);
+ bp = mpz_limbs_read (b);
+ }
+ mpn_mul (mpz_limbs_write (r, an + bn),
+ ap, an, bp, bn);
+
+ mpz_limbs_finish (r, an + bn);
+}
+
+void
+check_mul (void)
+{
+ gmp_randstate_ptr rands = RANDS;
+ mpz_t bs, a, b;
+ unsigned i;
+ mpz_inits (bs, a, b, NULL);
+ for (i = 0; i < COUNT; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE);
+ mpz_urandomb (bs, rands, 32);
+ mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE);
+
+ check_funcs ("mul", alt_mul, mpz_mul, a, b);
+ }
+ mpz_clears (bs, a, b, NULL);
+}
+
+#define MAX_SIZE 100
+
+static void
+check_roinit (void)
+{
+ gmp_randstate_ptr rands = RANDS;
+ mpz_t bs, a, b, r, ref;
+ unsigned i;
+
+ mpz_inits (bs, a, b, r, ref, NULL);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mp_srcptr ap, bp;
+ mp_size_t an, bn;
+ mpz_urandomb (bs, rands, 32);
+ mpz_rrandomb (a, rands, 1 + mpz_get_ui (bs) % BITSIZE);
+ mpz_urandomb (bs, rands, 32);
+ mpz_rrandomb (b, rands, 1 + mpz_get_ui (bs) % BITSIZE);
+
+ an = mpz_size (a);
+ ap = mpz_limbs_read (a);
+ bn = mpz_size (b);
+ bp = mpz_limbs_read (b);
+
+ mpz_add (ref, a, b);
+ {
+ mpz_t a1, b1;
+#if __STDC_VERSION__ >= 199901
+ const mpz_t a2 = MPZ_ROINIT_N ( (mp_ptr) ap, an);
+ const mpz_t b2 = MPZ_ROINIT_N ( (mp_ptr) bp, bn);
+
+ mpz_set_ui (r, 0);
+ mpz_add (r, a2, b2);
+ if (mpz_cmp (r, ref) != 0)
+ {
+ printf ("MPZ_ROINIT_N failed\n");
+ gmp_printf ("a = %Zx\n", a);
+ gmp_printf ("b = %Zx\n", b);
+ gmp_printf ("r = %Zx (bad)\n", r);
+ gmp_printf ("ref = %Zx\n", ref);
+ abort ();
+ }
+#endif
+ mpz_set_ui (r, 0);
+ mpz_add (r, mpz_roinit_n (a1, ap, an), mpz_roinit_n (b1, bp, bn));
+ if (mpz_cmp (r, ref) != 0)
+ {
+ printf ("mpz_roinit_n failed\n");
+ gmp_printf ("a = %Zx\n", a);
+ gmp_printf ("b = %Zx\n", b);
+ gmp_printf ("r = %Zx (bad)\n", r);
+ gmp_printf ("ref = %Zx\n", ref);
+ abort ();
+ }
+ }
+ }
+ mpz_clears (bs, a, b, r, ref, NULL);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+ tests_end ();
+
+ check_add ();
+ check_mul ();
+ check_roinit ();
+
+ return 0;
+
+}
diff --git a/gmp/tests/mpz/t-lucnum_ui.c b/gmp/tests/mpz/t-lucnum_ui.c
new file mode 100644
index 0000000000..7cb734195b
--- /dev/null
+++ b/gmp/tests/mpz/t-lucnum_ui.c
@@ -0,0 +1,97 @@
+/* Test mpz_lucnum_ui and mpz_lucnum2_ui.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Usage: t-lucnum_ui [n]
+
+ Test up to L[n], or if n is omitted then the default limit below. A
+ literal "x" for the limit means continue forever, this being meant only
+ for development. */
+
+
+void
+check_sequence (int argc, char *argv[])
+{
+ unsigned long n;
+ unsigned long limit = 100 * GMP_LIMB_BITS;
+ mpz_t want_ln, want_ln1, got_ln, got_ln1;
+
+ if (argc > 1 && argv[1][0] == 'x')
+ limit = ULONG_MAX;
+ else if (argc > 1)
+ limit = atoi (argv[1]);
+
+ /* start at n==0 */
+ mpz_init_set_si (want_ln1, -1); /* L[-1] */
+ mpz_init_set_ui (want_ln, 2); /* L[0] */
+ mpz_init (got_ln);
+ mpz_init (got_ln1);
+
+ for (n = 0; n < limit; n++)
+ {
+ mpz_lucnum2_ui (got_ln, got_ln1, n);
+ MPZ_CHECK_FORMAT (got_ln);
+ MPZ_CHECK_FORMAT (got_ln1);
+ if (mpz_cmp (got_ln, want_ln) != 0 || mpz_cmp (got_ln1, want_ln1) != 0)
+ {
+ printf ("mpz_lucnum2_ui(%lu) wrong\n", n);
+ mpz_trace ("want ln ", want_ln);
+ mpz_trace ("got ln ", got_ln);
+ mpz_trace ("want ln1", want_ln1);
+ mpz_trace ("got ln1", got_ln1);
+ abort ();
+ }
+
+ mpz_lucnum_ui (got_ln, n);
+ MPZ_CHECK_FORMAT (got_ln);
+ if (mpz_cmp (got_ln, want_ln) != 0)
+ {
+ printf ("mpz_lucnum_ui(%lu) wrong\n", n);
+ mpz_trace ("want ln", want_ln);
+ mpz_trace ("got ln", got_ln);
+ abort ();
+ }
+
+ mpz_add (want_ln1, want_ln1, want_ln); /* L[n+1] = L[n] + L[n-1] */
+ mpz_swap (want_ln1, want_ln);
+ }
+
+ mpz_clear (want_ln);
+ mpz_clear (want_ln1);
+ mpz_clear (got_ln);
+ mpz_clear (got_ln1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_sequence (argc, argv);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-mfac_uiui.c b/gmp/tests/mpz/t-mfac_uiui.c
new file mode 100644
index 0000000000..7bf51a5dac
--- /dev/null
+++ b/gmp/tests/mpz/t-mfac_uiui.c
@@ -0,0 +1,136 @@
+/* Exercise mpz_mfac_uiui.
+
+Copyright 2000-2002, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Usage: t-mfac_uiui [x|num]
+
+ With no arguments testing goes up to the initial value of "limit" below.
+ With a number argument tests are carried that far, or with a literal "x"
+ tests are continued without limit (this being meant only for development
+ purposes). */
+
+#define MULTIFAC_WHEEL (2*3*11)
+#define MULTIFAC_WHEEL2 (5*13)
+
+int
+main (int argc, char *argv[])
+{
+ mpz_t ref[MULTIFAC_WHEEL], ref2[MULTIFAC_WHEEL2], res;
+ unsigned long n, j, m, m2;
+ unsigned long limit = 2222, step = 1;
+
+ tests_start ();
+
+ if (argc > 1 && argv[1][0] == 'x')
+ limit = ULONG_MAX;
+ else if (argc > 1)
+ limit = atoi (argv[1]);
+
+ /* for small limb testing */
+ limit = MIN (limit, MP_LIMB_T_MAX);
+
+ for (m = 0; m < MULTIFAC_WHEEL; m++)
+ mpz_init_set_ui(ref [m],1);
+ for (m2 = 0; m2 < MULTIFAC_WHEEL2; m2++)
+ mpz_init_set_ui(ref2 [m2],1);
+
+ mpz_init (res);
+
+ m = 0;
+ m2 = 0;
+ for (n = 0; n <= limit;)
+ {
+ mpz_mfac_uiui (res, n, MULTIFAC_WHEEL);
+ MPZ_CHECK_FORMAT (res);
+ if (mpz_cmp (ref[m], res) != 0)
+ {
+ printf ("mpz_mfac_uiui(%lu,%d) wrong\n", n, MULTIFAC_WHEEL);
+ printf (" got "); mpz_out_str (stdout, 10, res); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, ref[m]); printf("\n");
+ abort ();
+ }
+ mpz_mfac_uiui (res, n, MULTIFAC_WHEEL2);
+ MPZ_CHECK_FORMAT (res);
+ if (mpz_cmp (ref2[m2], res) != 0)
+ {
+ printf ("mpz_mfac_uiui(%lu,%d) wrong\n", n, MULTIFAC_WHEEL2);
+ printf (" got "); mpz_out_str (stdout, 10, res); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, ref2[m2]); printf("\n");
+ abort ();
+ }
+ if (n + step <= limit)
+ for (j = 0; j < step; j++) {
+ n++; m++; m2++;
+ if (m >= MULTIFAC_WHEEL) m -= MULTIFAC_WHEEL;
+ if (m2 >= MULTIFAC_WHEEL2) m2 -= MULTIFAC_WHEEL2;
+ mpz_mul_ui (ref[m], ref[m], n); /* Compute a reference, with current library */
+ mpz_mul_ui (ref2[m2], ref2[m2], n); /* Compute a reference, with current library */
+ }
+ else n += step;
+ }
+ mpz_fac_ui (ref[0], n);
+ mpz_mfac_uiui (res, n, 1);
+ MPZ_CHECK_FORMAT (res);
+ if (mpz_cmp (ref[0], res) != 0)
+ {
+ printf ("mpz_mfac_uiui(%lu,1) wrong\n", n);
+ printf (" got "); mpz_out_str (stdout, 10, res); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, ref[0]); printf("\n");
+ abort ();
+ }
+
+ mpz_2fac_ui (ref[0], n);
+ mpz_mfac_uiui (res, n, 2);
+ MPZ_CHECK_FORMAT (res);
+ if (mpz_cmp (ref[0], res) != 0)
+ {
+ printf ("mpz_mfac_uiui(%lu,1) wrong\n", n);
+ printf (" got "); mpz_out_str (stdout, 10, res); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, ref[0]); printf("\n");
+ abort ();
+ }
+
+ n++;
+ mpz_2fac_ui (ref[0], n);
+ mpz_mfac_uiui (res, n, 2);
+ MPZ_CHECK_FORMAT (res);
+ if (mpz_cmp (ref[0], res) != 0)
+ {
+ printf ("mpz_mfac_uiui(%lu,2) wrong\n", n);
+ printf (" got "); mpz_out_str (stdout, 10, res); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, ref[0]); printf("\n");
+ abort ();
+ }
+
+ for (m = 0; m < MULTIFAC_WHEEL; m++)
+ mpz_clear (ref[m]);
+ for (m2 = 0; m2 < MULTIFAC_WHEEL2; m2++)
+ mpz_clear (ref2[m2]);
+ mpz_clear (res);
+
+ tests_end ();
+
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-mul.c b/gmp/tests/mpz/t-mul.c
new file mode 100644
index 0000000000..690b89f7fd
--- /dev/null
+++ b/gmp/tests/mpz/t-mul.c
@@ -0,0 +1,219 @@
+/* Test mpz_cmp, mpz_mul.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+void debug_mp (mpz_t);
+static void refmpz_mul (mpz_t, const mpz_t, const mpz_t);
+void dump_abort (int, const char *, mpz_t, mpz_t, mpz_t, mpz_t);
+
+#define FFT_MIN_BITSIZE 100000
+
+char *extra_fft;
+
+void
+one (int i, mpz_t multiplicand, mpz_t multiplier)
+{
+ mpz_t product, ref_product;
+
+ mpz_init (product);
+ mpz_init (ref_product);
+
+ /* Test plain multiplication comparing results against reference code. */
+ mpz_mul (product, multiplier, multiplicand);
+ refmpz_mul (ref_product, multiplier, multiplicand);
+ if (mpz_cmp (product, ref_product))
+ dump_abort (i, "incorrect plain product",
+ multiplier, multiplicand, product, ref_product);
+
+ /* Test squaring, comparing results against plain multiplication */
+ mpz_mul (product, multiplier, multiplier);
+ mpz_set (multiplicand, multiplier);
+ mpz_mul (ref_product, multiplier, multiplicand);
+ if (mpz_cmp (product, ref_product))
+ dump_abort (i, "incorrect square product",
+ multiplier, multiplier, product, ref_product);
+
+ mpz_clear (product);
+ mpz_clear (ref_product);
+}
+
+int
+main (int argc, char **argv)
+{
+ mpz_t op1, op2;
+ int i;
+ int fft_max_2exp;
+
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range, fsize_range;
+
+ tests_start ();
+ rands = RANDS;
+
+ extra_fft = getenv ("GMP_CHECK_FFT");
+ fft_max_2exp = 0;
+ if (extra_fft != NULL)
+ fft_max_2exp = atoi (extra_fft);
+
+ if (fft_max_2exp <= 1) /* compat with old use of GMP_CHECK_FFT */
+ fft_max_2exp = 22; /* default limit, good for any machine */
+
+ mpz_init (bs);
+ mpz_init (op1);
+ mpz_init (op2);
+
+ fsize_range = 4 << 8; /* a fraction 1/256 of size_range */
+ for (i = 0;; i++)
+ {
+ size_range = fsize_range >> 8;
+ fsize_range = fsize_range * 33 / 32;
+
+ if (size_range > fft_max_2exp)
+ break;
+
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (op1, rands, mpz_get_ui (bs));
+ if (i & 1)
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (op2, rands, mpz_get_ui (bs));
+
+ mpz_urandomb (bs, rands, 4);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 0x3) == 0)
+ mpz_neg (op1, op1);
+ if ((bsi & 0xC) == 0)
+ mpz_neg (op2, op2);
+
+ /* printf ("%d %d\n", SIZ (op1), SIZ (op2)); */
+ one (i, op2, op1);
+ }
+
+ for (i = -50; i < 0; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % fft_max_2exp;
+
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (op1, rands, mpz_get_ui (bs) + FFT_MIN_BITSIZE);
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (op2, rands, mpz_get_ui (bs) + FFT_MIN_BITSIZE);
+
+ /* printf ("%d: %d %d\n", i, SIZ (op1), SIZ (op2)); */
+ fflush (stdout);
+ one (-1, op2, op1);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (op1);
+ mpz_clear (op2);
+
+ tests_end ();
+ exit (0);
+}
+
+static void
+refmpz_mul (mpz_t w, const mpz_t u, const mpz_t v)
+{
+ mp_size_t usize = u->_mp_size;
+ mp_size_t vsize = v->_mp_size;
+ mp_size_t wsize;
+ mp_size_t sign_product;
+ mp_ptr up, vp;
+ mp_ptr wp;
+ mp_size_t talloc;
+
+ sign_product = usize ^ vsize;
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ if (usize == 0 || vsize == 0)
+ {
+ SIZ (w) = 0;
+ return;
+ }
+
+ talloc = usize + vsize;
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ wp = __GMP_ALLOCATE_FUNC_LIMBS (talloc);
+
+ if (usize > vsize)
+ refmpn_mul (wp, up, usize, vp, vsize);
+ else
+ refmpn_mul (wp, vp, vsize, up, usize);
+ wsize = usize + vsize;
+ wsize -= wp[wsize - 1] == 0;
+ MPZ_REALLOC (w, wsize);
+ MPN_COPY (PTR(w), wp, wsize);
+
+ SIZ(w) = sign_product < 0 ? -wsize : wsize;
+ __GMP_FREE_FUNC_LIMBS (wp, talloc);
+}
+
+void
+dump_abort (int i, const char *s,
+ mpz_t op1, mpz_t op2, mpz_t product, mpz_t ref_product)
+{
+ mp_size_t b, e;
+ fprintf (stderr, "ERROR: %s in test %d\n", s, i);
+ fprintf (stderr, "op1 = "); debug_mp (op1);
+ fprintf (stderr, "op2 = "); debug_mp (op2);
+ fprintf (stderr, " product = "); debug_mp (product);
+ fprintf (stderr, "ref_product = "); debug_mp (ref_product);
+ for (b = 0; b < ABSIZ(ref_product); b++)
+ if (PTR(ref_product)[b] != PTR(product)[b])
+ break;
+ for (e = ABSIZ(ref_product) - 1; e >= 0; e--)
+ if (PTR(ref_product)[e] != PTR(product)[e])
+ break;
+ printf ("ERRORS in %ld--%ld\n", b, e);
+ abort();
+}
+
+void
+debug_mp (mpz_t x)
+{
+ size_t siz = mpz_sizeinbase (x, 16);
+
+ if (siz > 65)
+ {
+ mpz_t q;
+ mpz_init (q);
+ mpz_tdiv_q_2exp (q, x, 4 * (mpz_sizeinbase (x, 16) - 25));
+ gmp_fprintf (stderr, "%ZX...", q);
+ mpz_tdiv_r_2exp (q, x, 4 * 25);
+ gmp_fprintf (stderr, "%025ZX [%d]\n", q, (int) siz);
+ mpz_clear (q);
+ }
+ else
+ {
+ gmp_fprintf (stderr, "%ZX\n", x);
+ }
+}
diff --git a/gmp/tests/mpz/t-mul_i.c b/gmp/tests/mpz/t-mul_i.c
new file mode 100644
index 0000000000..cbbe54d40d
--- /dev/null
+++ b/gmp/tests/mpz/t-mul_i.c
@@ -0,0 +1,135 @@
+/* Test mpz_mul_ui and mpz_mul_si.
+
+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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+mpz_t got, want, x;
+
+void
+compare_si (long y)
+{
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_mul_si wrong\n");
+ mpz_trace (" x", x);
+ printf (" y=%ld (0x%lX)\n", y, y);
+ mpz_trace (" got ", got);
+ mpz_trace (" want", want);
+ abort ();
+ }
+}
+
+void
+compare_ui (unsigned long y)
+{
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_mul_ui wrong\n");
+ mpz_trace (" x", x);
+ printf (" y=%lu (0x%lX)\n", y, y);
+ mpz_trace (" got ", got);
+ mpz_trace (" want", want);
+ abort ();
+ }
+}
+
+void
+check_samples (void)
+{
+ {
+ long y;
+
+ mpz_set_ui (x, 1L);
+ y = 0;
+ mpz_mul_si (got, x, y);
+ mpz_set_si (want, y);
+ compare_si (y);
+
+ mpz_set_ui (x, 1L);
+ y = 1;
+ mpz_mul_si (got, x, y);
+ mpz_set_si (want, y);
+ compare_si (y);
+
+ mpz_set_ui (x, 1L);
+ y = -1;
+ mpz_mul_si (got, x, y);
+ mpz_set_si (want, y);
+ compare_si (y);
+
+ mpz_set_ui (x, 1L);
+ y = LONG_MIN;
+ mpz_mul_si (got, x, y);
+ mpz_set_si (want, y);
+ compare_si (y);
+
+ mpz_set_ui (x, 1L);
+ y = LONG_MAX;
+ mpz_mul_si (got, x, y);
+ mpz_set_si (want, y);
+ compare_si (y);
+ }
+
+ {
+ unsigned long y;
+
+ mpz_set_ui (x, 1L);
+ y = 0;
+ mpz_mul_ui (got, x, y);
+ mpz_set_ui (want, y);
+ compare_ui (y);
+
+ mpz_set_ui (x, 1L);
+ y = 1;
+ mpz_mul_ui (got, x, y);
+ mpz_set_ui (want, y);
+ compare_ui (y);
+
+ mpz_set_ui (x, 1L);
+ y = ULONG_MAX;
+ mpz_mul_ui (got, x, y);
+ mpz_set_ui (want, y);
+ compare_ui (y);
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ tests_start ();
+
+ mpz_init (x);
+ mpz_init (got);
+ mpz_init (want);
+
+ check_samples ();
+
+ mpz_clear (x);
+ mpz_clear (got);
+ mpz_clear (want);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-nextprime.c b/gmp/tests/mpz/t-nextprime.c
new file mode 100644
index 0000000000..6e291c334d
--- /dev/null
+++ b/gmp/tests/mpz/t-nextprime.c
@@ -0,0 +1,222 @@
+/* Test mpz_nextprime.
+
+Copyright 2009 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void
+refmpz_nextprime (mpz_ptr p, mpz_srcptr t)
+{
+ mpz_add_ui (p, t, 1L);
+ while (! mpz_probab_prime_p (p, 10))
+ mpz_add_ui (p, p, 1L);
+}
+
+void
+run (const char *start, int reps, const char *end, short diffs[])
+{
+ mpz_t x, y;
+ int i;
+
+ mpz_init_set_str (x, start, 0);
+ mpz_init (y);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_nextprime (y, x);
+ mpz_sub (x, y, x);
+ if (diffs != NULL && diffs[i] != mpz_get_ui (x))
+ {
+ gmp_printf ("diff list discrepancy\n");
+ abort ();
+ }
+ mpz_set (x, y);
+ }
+
+ mpz_set_str (y, end, 0);
+
+ if (mpz_cmp (x, y) != 0)
+ {
+ gmp_printf ("got %Zx\n", x);
+ gmp_printf ("want %Zx\n", y);
+ abort ();
+ }
+
+ mpz_clear (y);
+ mpz_clear (x);
+}
+
+extern short diff1[];
+extern short diff3[];
+extern short diff4[];
+extern short diff5[];
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ int reps = 20;
+ gmp_randstate_ptr rands;
+ mpz_t bs, x, nxtp, ref_nxtp;
+ unsigned long size_range;
+
+ tests_start();
+ rands = RANDS;
+
+ run ("2", 1000, "0x1ef7", diff1);
+
+ run ("3", 1000 - 1, "0x1ef7", NULL);
+
+ run ("0x8a43866f5776ccd5b02186e90d28946aeb0ed914", 50,
+ "0x8a43866f5776ccd5b02186e90d28946aeb0eeec5", diff3);
+
+ run ("0x10000000000000000000000000000000000000", 50,
+ "0x100000000000000000000000000000000010ab", diff4);
+
+ run ("0x1c2c26be55317530311facb648ea06b359b969715db83292ab8cf898d8b1b", 50,
+ "0x1c2c26be55317530311facb648ea06b359b969715db83292ab8cf898da957", diff5);
+
+ mpz_init (bs);
+ mpz_init (x);
+ mpz_init (nxtp);
+ mpz_init (ref_nxtp);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 8 + 2; /* 0..1024 bit operands */
+
+ mpz_urandomb (bs, rands, size_range);
+ mpz_rrandomb (x, rands, mpz_get_ui (bs));
+
+/* gmp_printf ("%ld: %Zd\n", mpz_sizeinbase (x, 2), x); */
+
+ mpz_nextprime (nxtp, x);
+ refmpz_nextprime (ref_nxtp, x);
+ if (mpz_cmp (nxtp, ref_nxtp) != 0)
+ abort ();
+ }
+
+ mpz_clear (bs);
+ mpz_clear (x);
+ mpz_clear (nxtp);
+ mpz_clear (ref_nxtp);
+
+ tests_end ();
+ return 0;
+}
+
+short diff1[] =
+{
+ 1,2,2,4,2,4,2,4,6,2,6,4,2,4,6,6,
+ 2,6,4,2,6,4,6,8,4,2,4,2,4,14,4,6,
+ 2,10,2,6,6,4,6,6,2,10,2,4,2,12,12,4,
+ 2,4,6,2,10,6,6,6,2,6,4,2,10,14,4,2,
+ 4,14,6,10,2,4,6,8,6,6,4,6,8,4,8,10,
+ 2,10,2,6,4,6,8,4,2,4,12,8,4,8,4,6,
+ 12,2,18,6,10,6,6,2,6,10,6,6,2,6,6,4,
+ 2,12,10,2,4,6,6,2,12,4,6,8,10,8,10,8,
+ 6,6,4,8,6,4,8,4,14,10,12,2,10,2,4,2,
+ 10,14,4,2,4,14,4,2,4,20,4,8,10,8,4,6,
+ 6,14,4,6,6,8,6,12,4,6,2,10,2,6,10,2,
+ 10,2,6,18,4,2,4,6,6,8,6,6,22,2,10,8,
+ 10,6,6,8,12,4,6,6,2,6,12,10,18,2,4,6,
+ 2,6,4,2,4,12,2,6,34,6,6,8,18,10,14,4,
+ 2,4,6,8,4,2,6,12,10,2,4,2,4,6,12,12,
+ 8,12,6,4,6,8,4,8,4,14,4,6,2,4,6,2,
+ 6,10,20,6,4,2,24,4,2,10,12,2,10,8,6,6,
+ 6,18,6,4,2,12,10,12,8,16,14,6,4,2,4,2,
+ 10,12,6,6,18,2,16,2,22,6,8,6,4,2,4,8,
+ 6,10,2,10,14,10,6,12,2,4,2,10,12,2,16,2,
+ 6,4,2,10,8,18,24,4,6,8,16,2,4,8,16,2,
+ 4,8,6,6,4,12,2,22,6,2,6,4,6,14,6,4,
+ 2,6,4,6,12,6,6,14,4,6,12,8,6,4,26,18,
+ 10,8,4,6,2,6,22,12,2,16,8,4,12,14,10,2,
+ 4,8,6,6,4,2,4,6,8,4,2,6,10,2,10,8,
+ 4,14,10,12,2,6,4,2,16,14,4,6,8,6,4,18,
+ 8,10,6,6,8,10,12,14,4,6,6,2,28,2,10,8,
+ 4,14,4,8,12,6,12,4,6,20,10,2,16,26,4,2,
+ 12,6,4,12,6,8,4,8,22,2,4,2,12,28,2,6,
+ 6,6,4,6,2,12,4,12,2,10,2,16,2,16,6,20,
+ 16,8,4,2,4,2,22,8,12,6,10,2,4,6,2,6,
+ 10,2,12,10,2,10,14,6,4,6,8,6,6,16,12,2,
+ 4,14,6,4,8,10,8,6,6,22,6,2,10,14,4,6,
+ 18,2,10,14,4,2,10,14,4,8,18,4,6,2,4,6,
+ 2,12,4,20,22,12,2,4,6,6,2,6,22,2,6,16,
+ 6,12,2,6,12,16,2,4,6,14,4,2,18,24,10,6,
+ 2,10,2,10,2,10,6,2,10,2,10,6,8,30,10,2,
+ 10,8,6,10,18,6,12,12,2,18,6,4,6,6,18,2,
+ 10,14,6,4,2,4,24,2,12,6,16,8,6,6,18,16,
+ 2,4,6,2,6,6,10,6,12,12,18,2,6,4,18,8,
+ 24,4,2,4,6,2,12,4,14,30,10,6,12,14,6,10,
+ 12,2,4,6,8,6,10,2,4,14,6,6,4,6,2,10,
+ 2,16,12,8,18,4,6,12,2,6,6,6,28,6,14,4,
+ 8,10,8,12,18,4,2,4,24,12,6,2,16,6,6,14,
+ 10,14,4,30,6,6,6,8,6,4,2,12,6,4,2,6,
+ 22,6,2,4,18,2,4,12,2,6,4,26,6,6,4,8,
+ 10,32,16,2,6,4,2,4,2,10,14,6,4,8,10,6,
+ 20,4,2,6,30,4,8,10,6,6,8,6,12,4,6,2,
+ 6,4,6,2,10,2,16,6,20,4,12,14,28,6,20,4,
+ 18,8,6,4,6,14,6,6,10,2,10,12,8,10,2,10,
+ 8,12,10,24,2,4,8,6,4,8,18,10,6,6,2,6,
+ 10,12,2,10,6,6,6,8,6,10,6,2,6,6,6,10,
+ 8,24,6,22,2,18,4,8,10,30,8,18,4,2,10,6,
+ 2,6,4,18,8,12,18,16,6,2,12,6,10,2,10,2,
+ 6,10,14,4,24,2,16,2,10,2,10,20,4,2,4,8,
+ 16,6,6,2,12,16,8,4,6,30,2,10,2,6,4,6,
+ 6,8,6,4,12,6,8,12,4,14,12,10,24,6,12,6,
+ 2,22,8,18,10,6,14,4,2,6,10,8,6,4,6,30,
+ 14,10,2,12,10,2,16,2,18,24,18,6,16,18,6,2,
+ 18,4,6,2,10,8,10,6,6,8,4,6,2,10,2,12,
+ 4,6,6,2,12,4,14,18,4,6,20,4,8,6,4,8,
+ 4,14,6,4,14,12,4,2,30,4,24,6,6,12,12,14,
+ 6,4,2,4,18,6,12,8
+};
+
+short diff3[] =
+{
+ 33,32,136,116,24,22,104,114,76,278,238,162,36,44,388,134,
+ 130,26,312,42,138,28,24,80,138,108,270,12,330,130,98,102,
+ 162,34,36,170,90,34,14,6,24,66,154,218,70,132,188,88,
+ 80,82
+};
+
+short diff4[] =
+{
+ 91,92,64,6,104,24,46,258,68,18,54,100,68,154,26,4,
+ 38,142,168,42,18,26,286,104,136,116,40,2,28,110,52,78,
+ 104,24,54,96,4,626,196,24,56,36,52,102,48,156,26,18,
+ 42,40
+};
+
+short diff5[] =
+{
+ 268,120,320,184,396,2,94,108,20,318,274,14,64,122,220,108,
+ 18,174,6,24,348,32,64,116,268,162,20,156,28,110,52,428,
+ 196,14,262,30,194,120,300,66,268,12,428,370,212,198,192,130,
+ 30,80
+};
diff --git a/gmp/tests/mpz/t-oddeven.c b/gmp/tests/mpz/t-oddeven.c
new file mode 100644
index 0000000000..107f2436ab
--- /dev/null
+++ b/gmp/tests/mpz/t-oddeven.c
@@ -0,0 +1,88 @@
+/* Test mpz_odd_p and mpz_even_p.
+
+Copyright 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *n;
+ int odd, even;
+ } data[] = {
+ { "0", 0, 1 },
+ { "1", 1, 0 },
+ { "2", 0, 1 },
+ { "3", 1, 0 },
+ { "4", 0, 1 },
+
+ { "-4", 0, 1 },
+ { "-3", 1, 0 },
+ { "-2", 0, 1 },
+ { "-1", 1, 0 },
+
+ { "0x1000000000000000000000000000000000000000000000000000", 0, 1 },
+ { "0x1000000000000000000000000000000000000000000000000001", 1, 0 },
+ { "0x1000000000000000000000000000000000000000000000000002", 0, 1 },
+ { "0x1000000000000000000000000000000000000000000000000003", 1, 0 },
+
+ { "-0x1000000000000000000000000000000000000000000000000004", 0, 1 },
+ { "-0x1000000000000000000000000000000000000000000000000003", 1, 0 },
+ { "-0x1000000000000000000000000000000000000000000000000002", 0, 1 },
+ { "-0x1000000000000000000000000000000000000000000000000001", 1, 0 },
+ };
+
+ mpz_t n;
+ int i;
+
+ mpz_init (n);
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (n, data[i].n, 0);
+
+ if ((mpz_odd_p (n) != 0) != data[i].odd)
+ {
+ printf ("mpz_odd_p wrong on data[%d]\n", i);
+ abort();
+ }
+
+ if ((mpz_even_p (n) != 0) != data[i].even)
+ {
+ printf ("mpz_even_p wrong on data[%d]\n", i);
+ abort();
+ }
+ }
+
+ mpz_clear (n);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-perfpow.c b/gmp/tests/mpz/t-perfpow.c
new file mode 100644
index 0000000000..72fe5c519d
--- /dev/null
+++ b/gmp/tests/mpz/t-perfpow.c
@@ -0,0 +1,243 @@
+/* Test mpz_perfect_power_p.
+
+ Contributed to the GNU project by Torbjorn Granlund and Martin Boij.
+
+Copyright 2008-2010 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+struct
+{
+ const char *num_as_str;
+ char want;
+} tests[] =
+ {
+ { "0", 1},
+ { "1", 1},
+ {"-1", 1},
+ { "2", 0},
+ {"-2", 0},
+ { "3", 0},
+ {"-3", 0},
+ { "4", 1},
+ {"-4", 0},
+ { "64", 1},
+ {"-64", 1},
+ { "128", 1},
+ {"-128", 1},
+ { "256", 1},
+ {"-256", 0},
+ { "512", 1},
+ {"-512", 1},
+ { "0x4000000", 1},
+ {"-0x4000000", 1},
+ { "0x3cab640", 1},
+ {"-0x3cab640", 0},
+ { "0x3e23840", 1},
+ {"-0x3e23840", 0},
+ { "0x3d3a7ed1", 1},
+ {"-0x3d3a7ed1", 1},
+ { "0x30a7a6000", 1},
+ {"-0x30a7a6000", 1},
+ { "0xf33e5a5a59", 1},
+ {"-0xf33e5a5a59", 0},
+ { "0xed1b1182118135d", 1},
+ {"-0xed1b1182118135d", 1},
+ { "0xe71f6eb7689cc276b2f1", 1},
+ {"-0xe71f6eb7689cc276b2f1", 0},
+ { "0x12644507fe78cf563a4b342c92e7da9fe5e99cb75a01", 1},
+ {"-0x12644507fe78cf563a4b342c92e7da9fe5e99cb75a01", 0},
+ { "0x1ff2e7c581bb0951df644885bd33f50e472b0b73a204e13cbe98fdb424d66561e4000000", 1},
+ {"-0x1ff2e7c581bb0951df644885bd33f50e472b0b73a204e13cbe98fdb424d66561e4000000", 1},
+ { "0x2b9b44db2d91a6f8165c8c7339ef73633228ea29e388592e80354e4380004aad84000000", 1},
+ {"-0x2b9b44db2d91a6f8165c8c7339ef73633228ea29e388592e80354e4380004aad84000000", 1},
+ { "0x28d5a2b8f330910a9d3cda06036ae0546442e5b1a83b26a436efea5b727bf1bcbe7e12b47d81", 1},
+ {"-0x28d5a2b8f330910a9d3cda06036ae0546442e5b1a83b26a436efea5b727bf1bcbe7e12b47d81", 1},
+ {NULL, 0}
+ };
+
+
+void
+check_tests ()
+{
+ mpz_t x;
+ int i;
+ int got, want;
+
+ mpz_init (x);
+
+ for (i = 0; tests[i].num_as_str != NULL; i++)
+ {
+ mpz_set_str (x, tests[i].num_as_str, 0);
+ got = mpz_perfect_power_p (x);
+ want = tests[i].want;
+ if (got != want)
+ {
+ fprintf (stderr, "mpz_perfect_power_p returns %d when %d was expected\n", got, want);
+ fprintf (stderr, "fault operand: %s\n", tests[i].num_as_str);
+ abort ();
+ }
+ }
+
+ mpz_clear (x);
+}
+
+#define NRP 15
+
+void
+check_random (int reps)
+{
+ mpz_t n, np, temp, primes[NRP];
+ int i, j, k, unique, destroy, res;
+ unsigned long int nrprimes, primebits;
+ mp_limb_t g, exp[NRP], e;
+ gmp_randstate_ptr rands;
+
+ rands = RANDS;
+
+ mpz_init (n);
+ mpz_init (np);
+ mpz_init (temp);
+
+ for (i = 0; i < NRP; i++)
+ mpz_init (primes[i]);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (np, rands, 32);
+ nrprimes = mpz_get_ui (np) % NRP + 1; /* 1-NRP unique primes */
+
+ mpz_urandomb (np, rands, 32);
+ g = mpz_get_ui (np) % 32 + 2; /* gcd 2-33 */
+
+ for (j = 0; j < nrprimes;)
+ {
+ mpz_urandomb (np, rands, 32);
+ primebits = mpz_get_ui (np) % 100 + 3; /* 3-102 bit primes */
+ mpz_urandomb (primes[j], rands, primebits);
+ mpz_nextprime (primes[j], primes[j]);
+ unique = 1;
+ for (k = 0; k < j; k++)
+ {
+ if (mpz_cmp (primes[j], primes[k]) == 0)
+ {
+ unique = 0;
+ break;
+ }
+ }
+ if (unique)
+ {
+ mpz_urandomb (np, rands, 32);
+ e = 371 / (10 * primebits) + mpz_get_ui (np) % 11 + 1; /* Magic constants */
+ exp[j++] = g * e;
+ }
+ }
+
+ if (nrprimes > 1)
+ {
+ /* Destroy d exponents, d in [1, nrprimes - 1] */
+ if (nrprimes == 2)
+ {
+ destroy = 1;
+ }
+ else
+ {
+ mpz_urandomb (np, rands, 32);
+ destroy = mpz_get_ui (np) % (nrprimes - 2) + 1;
+ }
+
+ g = exp[destroy];
+ for (k = destroy + 1; k < nrprimes; k++)
+ g = mpn_gcd_1 (&g, 1, exp[k]);
+
+ for (j = 0; j < destroy; j++)
+ {
+ mpz_urandomb (np, rands, 32);
+ e = mpz_get_ui (np) % 50 + 1;
+ while (mpn_gcd_1 (&g, 1, e) > 1)
+ e++;
+
+ exp[j] = e;
+ }
+ }
+
+ /* Compute n */
+ mpz_pow_ui (n, primes[0], exp[0]);
+ for (j = 1; j < nrprimes; j++)
+ {
+ mpz_pow_ui (temp, primes[j], exp[j]);
+ mpz_mul (n, n, temp);
+ }
+
+ res = mpz_perfect_power_p (n);
+
+ if (nrprimes == 1)
+ {
+ if (res == 0 && exp[0] > 1)
+ {
+ printf("n is a perfect power, perfpow_p disagrees\n");
+ gmp_printf("n = %Zu\nprimes[0] = %Zu\nexp[0] = %lu\n", n, primes[0], exp[0]);
+ abort ();
+ }
+ else if (res == 1 && exp[0] == 1)
+ {
+ gmp_printf("n = %Zu\n", n);
+ printf("n is now a prime number, but perfpow_p still believes n is a perfect power\n");
+ abort ();
+ }
+ }
+ else
+ {
+ if (res == 1)
+ {
+ gmp_printf("n = %Zu\nn was destroyed, but perfpow_p still believes n is a perfect power\n", n);
+ abort ();
+ }
+ }
+ }
+
+ mpz_clear (n);
+ mpz_clear (np);
+ mpz_clear (temp);
+ for (i = 0; i < NRP; i++)
+ mpz_clear (primes[i]);
+}
+
+int
+main (int argc, char **argv)
+{
+ int n_tests;
+
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_tests ();
+
+ n_tests = 500;
+ if (argc == 2)
+ n_tests = atoi (argv[1]);
+ check_random (n_tests);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-perfsqr.c b/gmp/tests/mpz/t-perfsqr.c
new file mode 100644
index 0000000000..2a54e59e65
--- /dev/null
+++ b/gmp/tests/mpz/t-perfsqr.c
@@ -0,0 +1,155 @@
+/* Test mpz_perfect_square_p.
+
+Copyright 2000-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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#include "mpn/perfsqr.h"
+
+
+/* check_modulo() exercises mpz_perfect_square_p on squares which cover each
+ possible quadratic residue to each divisor used within
+ mpn_perfect_square_p, ensuring those residues aren't incorrectly claimed
+ to be non-residues.
+
+ Each divisor is taken separately. It's arranged that n is congruent to 0
+ modulo the other divisors, 0 of course being a quadratic residue to any
+ modulus.
+
+ The values "(j*others)^2" cover all quadratic residues mod divisor[i],
+ but in no particular order. j is run from 1<=j<=divisor[i] so that zero
+ is excluded. A literal n==0 doesn't reach the residue tests. */
+
+void
+check_modulo (void)
+{
+ static const unsigned long divisor[] = PERFSQR_DIVISORS;
+ unsigned long i, j;
+
+ mpz_t alldiv, others, n;
+
+ mpz_init (alldiv);
+ mpz_init (others);
+ mpz_init (n);
+
+ /* product of all divisors */
+ mpz_set_ui (alldiv, 1L);
+ for (i = 0; i < numberof (divisor); i++)
+ mpz_mul_ui (alldiv, alldiv, divisor[i]);
+
+ for (i = 0; i < numberof (divisor); i++)
+ {
+ /* product of all divisors except i */
+ mpz_set_ui (others, 1L);
+ for (j = 0; j < numberof (divisor); j++)
+ if (i != j)
+ mpz_mul_ui (others, others, divisor[j]);
+
+ for (j = 1; j <= divisor[i]; j++)
+ {
+ /* square */
+ mpz_mul_ui (n, others, j);
+ mpz_mul (n, n, n);
+ if (! mpz_perfect_square_p (n))
+ {
+ printf ("mpz_perfect_square_p got 0, want 1\n");
+ mpz_trace (" n", n);
+ abort ();
+ }
+ }
+ }
+
+ mpz_clear (alldiv);
+ mpz_clear (others);
+ mpz_clear (n);
+}
+
+
+/* Exercise mpz_perfect_square_p compared to what mpz_sqrt says. */
+void
+check_sqrt (int reps)
+{
+ mpz_t x2, x2t, x;
+ mp_size_t x2n;
+ int res;
+ int i;
+ /* int cnt = 0; */
+ gmp_randstate_ptr rands = RANDS;
+ mpz_t bs;
+
+ mpz_init (bs);
+
+ mpz_init (x2);
+ mpz_init (x);
+ mpz_init (x2t);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 9);
+ x2n = mpz_get_ui (bs);
+ mpz_rrandomb (x2, rands, x2n);
+ /* mpz_out_str (stdout, -16, x2); puts (""); */
+
+ res = mpz_perfect_square_p (x2);
+ mpz_sqrt (x, x2);
+ mpz_mul (x2t, x, x);
+
+ if (res != (mpz_cmp (x2, x2t) == 0))
+ {
+ printf ("mpz_perfect_square_p and mpz_sqrt differ\n");
+ mpz_trace (" x ", x);
+ mpz_trace (" x2 ", x2);
+ mpz_trace (" x2t", x2t);
+ printf (" mpz_perfect_square_p %d\n", res);
+ printf (" mpz_sqrt %d\n", mpz_cmp (x2, x2t) == 0);
+ abort ();
+ }
+
+ /* cnt += res != 0; */
+ }
+ /* printf ("%d/%d perfect squares\n", cnt, reps); */
+
+ mpz_clear (bs);
+ mpz_clear (x2);
+ mpz_clear (x);
+ mpz_clear (x2t);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int reps = 200000;
+
+ tests_start ();
+ mp_trace_base = -16;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ check_modulo ();
+ check_sqrt (reps);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-popcount.c b/gmp/tests/mpz/t-popcount.c
new file mode 100644
index 0000000000..c27c4efda9
--- /dev/null
+++ b/gmp/tests/mpz/t-popcount.c
@@ -0,0 +1,168 @@
+/* Test mpz_popcount.
+
+Copyright 2001, 2005 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+
+void
+check_onebit (void)
+{
+ mpz_t n;
+ unsigned long i, got;
+
+ mpz_init (n);
+ for (i = 0; i < 5 * GMP_LIMB_BITS; i++)
+ {
+ mpz_setbit (n, i);
+ got = mpz_popcount (n);
+ if (got != 1)
+ {
+ printf ("mpz_popcount wrong on single bit at %lu\n", i);
+ printf (" got %lu, want 1\n", got);
+ abort();
+ }
+ mpz_clrbit (n, i);
+ }
+ mpz_clear (n);
+}
+
+
+void
+check_data (void)
+{
+ static const struct {
+ const char *n;
+ unsigned long want;
+ } data[] = {
+ { "-1", ~ (unsigned long) 0 },
+ { "-12345678", ~ (unsigned long) 0 },
+ { "0", 0 },
+ { "1", 1 },
+ { "3", 2 },
+ { "5", 2 },
+ { "0xFFFF", 16 },
+ { "0xFFFFFFFF", 32 },
+ { "0xFFFFFFFFFFFFFFFF", 64 },
+ { "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 128 },
+ };
+
+ unsigned long got;
+ int i;
+ mpz_t n;
+
+ mpz_init (n);
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (n, data[i].n, 0);
+ got = mpz_popcount (n);
+ if (got != data[i].want)
+ {
+ printf ("mpz_popcount wrong at data[%d]\n", i);
+ printf (" n \"%s\"\n", data[i].n);
+ printf (" "); mpz_out_str (stdout, 10, n); printf ("\n");
+ printf (" 0x"); mpz_out_str (stdout, 16, n); printf ("\n");
+ printf (" got %lu\n", got);
+ printf (" want %lu\n", data[i].want);
+ abort ();
+ }
+ }
+ mpz_clear (n);
+}
+
+unsigned long
+refmpz_popcount (mpz_t arg)
+{
+ mp_size_t n, i;
+ unsigned long cnt;
+ mp_limb_t x;
+
+ n = SIZ(arg);
+ if (n < 0)
+ return ~(unsigned long) 0;
+
+ cnt = 0;
+ for (i = 0; i < n; i++)
+ {
+ x = PTR(arg)[i];
+ while (x != 0)
+ {
+ cnt += (x & 1);
+ x >>= 1;
+ }
+ }
+ return cnt;
+}
+
+void
+check_random (void)
+{
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ mpz_t arg;
+ unsigned long arg_size, size_range;
+ unsigned long got, ref;
+ int i;
+
+ rands = RANDS;
+
+ mpz_init (bs);
+ mpz_init (arg);
+
+ for (i = 0; i < 10000; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 11 + 2; /* 0..4096 bit operands */
+
+ mpz_urandomb (bs, rands, size_range);
+ arg_size = mpz_get_ui (bs);
+ mpz_rrandomb (arg, rands, arg_size);
+
+ got = mpz_popcount (arg);
+ ref = refmpz_popcount (arg);
+ if (got != ref)
+ {
+ printf ("mpz_popcount wrong on random\n");
+ printf (" "); mpz_out_str (stdout, 10, arg); printf ("\n");
+ printf (" 0x"); mpz_out_str (stdout, 16, arg); printf ("\n");
+ printf (" got %lu\n", got);
+ printf (" want %lu\n", ref);
+ abort ();
+ }
+ }
+ mpz_clear (arg);
+ mpz_clear (bs);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_onebit ();
+ check_data ();
+ check_random ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-pow.c b/gmp/tests/mpz/t-pow.c
new file mode 100644
index 0000000000..312ef98884
--- /dev/null
+++ b/gmp/tests/mpz/t-pow.c
@@ -0,0 +1,218 @@
+/* Test mpz_pow_ui and mpz_ui_pow_ui.
+
+Copyright 1997, 1999-2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpz_srcptr want, mpz_srcptr base, unsigned long exp)
+{
+ mpz_t got;
+
+ mpz_init (got);
+
+ MPZ_CHECK_FORMAT (want);
+
+ mpz_pow_ui (got, base, exp);
+ if (mpz_cmp (got, want))
+ {
+ printf ("mpz_pow_ui wrong\n");
+ mpz_trace (" base", base);
+ printf (" exp = %lu (0x%lX)\n", exp, exp);
+ mpz_trace (" got ", got);
+ mpz_trace (" want", want);
+ abort ();
+ }
+
+ mpz_set (got, base);
+ mpz_pow_ui (got, got, exp);
+ if (mpz_cmp (got, want))
+ {
+ printf ("mpz_pow_ui wrong\n");
+ mpz_trace (" base", base);
+ printf (" exp = %lu (0x%lX)\n", exp, exp);
+ mpz_trace (" got ", got);
+ mpz_trace (" want", want);
+ abort ();
+ }
+
+ if (mpz_fits_ulong_p (base))
+ {
+ unsigned long base_u = mpz_get_ui (base);
+ mpz_ui_pow_ui (got, base_u, exp);
+ if (mpz_cmp (got, want))
+ {
+ printf ("mpz_ui_pow_ui wrong\n");
+ printf (" base=%lu (0x%lX)\n", base_u, base_u);
+ printf (" exp = %lu (0x%lX)\n", exp, exp);
+ mpz_trace (" got ", got);
+ mpz_trace (" want", want);
+ abort ();
+ }
+ }
+
+ mpz_clear (got);
+}
+
+void
+check_base (mpz_srcptr base)
+{
+ unsigned long exp;
+ mpz_t want;
+
+ mpz_init (want);
+ mpz_set_ui (want, 1L);
+
+ for (exp = 0; exp < 20; exp++)
+ {
+ check_one (want, base, exp);
+ mpz_mul (want, want, base);
+ }
+
+ mpz_clear (want);
+}
+
+void
+check_various (void)
+{
+ static const struct {
+ const char *base;
+ } data[] = {
+ { "0" },
+ { "1" },
+ { "2" },
+ { "3" },
+ { "4" },
+ { "5" },
+ { "6" },
+ { "10" },
+ { "15" },
+ { "16" },
+
+ { "0x1F" },
+ { "0xFF" },
+ { "0x1001" },
+ { "0xFFFF" },
+ { "0x10000001" },
+ { "0x1000000000000001" },
+
+ /* actual size closest to estimate */
+ { "0xFFFFFFFF" },
+ { "0xFFFFFFFFFFFFFFFF" },
+
+ /* same after rshift */
+ { "0xFFFFFFFF0" },
+ { "0xFFFFFFFF00" },
+ { "0xFFFFFFFFFFFFFFFF0" },
+ { "0xFFFFFFFFFFFFFFFF00" },
+
+ /* change from 2 limbs to 1 after rshift */
+ { "0x180000000" },
+ { "0x18000000000000000" },
+
+ /* change from 3 limbs to 2 after rshift */
+ { "0x18000000100000000" },
+ { "0x180000000000000010000000000000000" },
+
+ /* handling of absolute value */
+ { "-0x80000000" },
+ { "-0x8000000000000000" },
+
+ /* low zero limb, and size>2, checking argument overlap detection */
+ { "0x3000000000000000300000000000000030000000000000000" },
+ };
+
+ mpz_t base;
+ int i;
+
+ mpz_init (base);
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_set_str_or_abort (base, data[i].base, 0);
+ check_base (base);
+ }
+
+ mpz_clear (base);
+}
+
+void
+check_random (int reps)
+{
+ mpz_t base, want;
+ mp_size_t base_size;
+ int i;
+ unsigned long size_range, exp;
+ gmp_randstate_ptr rands = RANDS;
+
+ mpz_init (base);
+ mpz_init (want);
+
+ for (i = 0; i < reps; i++)
+ {
+ /* exponentially random 0 to 2^13 bits for base */
+ mpz_urandomb (want, rands, 32);
+ size_range = mpz_get_ui (want) % 12 + 2;
+ mpz_urandomb (want, rands, size_range);
+ base_size = mpz_get_ui (want);
+ mpz_rrandomb (base, rands, base_size);
+
+ /* randomly signed base */
+ mpz_urandomb (want, rands, 2);
+ if ((mpz_get_ui (want) & 1) != 0)
+ mpz_neg (base, base);
+
+ /* random 5 bits for exponent */
+ mpz_urandomb (want, rands, 5L);
+ exp = mpz_get_ui (want);
+
+ refmpz_pow_ui (want, base, exp);
+ check_one (want, base, exp);
+ }
+
+ mpz_clear (base);
+ mpz_clear (want);
+}
+
+int
+main (int argc, char **argv)
+{
+ int reps = 5000;
+
+ /* dummy call to drag in refmpn.o for testing mpz/n_pow_ui.c with
+ refmpn_mul_2 */
+ refmpn_zero_p (NULL, (mp_size_t) 0);
+
+ tests_start ();
+ mp_trace_base = -16;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ check_various ();
+ check_random (reps);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-powm.c b/gmp/tests/mpz/t-powm.c
new file mode 100644
index 0000000000..240e1c89b9
--- /dev/null
+++ b/gmp/tests/mpz/t-powm.c
@@ -0,0 +1,184 @@
+/* Test mpz_powm, mpz_mul, mpz_mod, mpz_mod_ui, mpz_div_ui.
+
+Copyright 1991, 1993, 1994, 1996, 1999-2001, 2009, 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void debug_mp (mpz_t, int);
+
+#define SIZEM 13
+
+/* Check that all sizes up to just above MUL_TOOM22_THRESHOLD have been tested
+ a few times. FIXME: If SIZEM is set too low, this will never happen. */
+int
+allsizes_seen (unsigned int *allsizes)
+{
+ mp_size_t i;
+
+ for (i = 1; i < MUL_TOOM22_THRESHOLD + 4; i++)
+ if (allsizes[i] < 4)
+ return 0;
+ return 1;
+}
+
+int
+main (int argc, char **argv)
+{
+ mpz_t base, exp, mod;
+ mpz_t r1, r2, t1, exp2, base2;
+ mp_size_t base_size, exp_size, mod_size;
+ int i;
+ int reps = 1000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+ unsigned int allsizes[1 << (SIZEM + 2 - 1)];
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ mpz_init (base);
+ mpz_init (exp);
+ mpz_init (mod);
+ mpz_init (r1);
+ mpz_init (r2);
+ mpz_init (t1);
+ mpz_init (exp2);
+ mpz_init (base2);
+
+ memset (allsizes, 0, (1 << (SIZEM + 2 - 1)) * sizeof (int));
+
+ for (i = 0; i < reps || ! allsizes_seen (allsizes); i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % SIZEM + 2;
+
+ do /* Loop until mathematically well-defined. */
+ {
+ mpz_urandomb (bs, rands, size_range);
+ base_size = mpz_get_ui (bs);
+ mpz_rrandomb (base, rands, base_size);
+
+ mpz_urandomb (bs, rands, 7L);
+ exp_size = mpz_get_ui (bs);
+ mpz_rrandomb (exp, rands, exp_size);
+ }
+ while (mpz_cmp_ui (base, 0) == 0 && mpz_cmp_ui (exp, 0) == 0);
+
+ do
+ {
+ mpz_urandomb (bs, rands, size_range);
+ mod_size = mpz_get_ui (bs);
+ mpz_rrandomb (mod, rands, mod_size);
+ }
+ while (mpz_cmp_ui (mod, 0) == 0);
+
+ allsizes[SIZ(mod)] += 1;
+
+ mpz_urandomb (bs, rands, 2);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (base, base);
+
+ /* printf ("%ld %ld %ld\n", SIZ (base), SIZ (exp), SIZ (mod)); */
+
+ mpz_set_ui (r2, 1);
+ mpz_mod (base2, base, mod);
+ mpz_set (exp2, exp);
+ mpz_mod (r2, r2, mod);
+
+ for (;;)
+ {
+ if (mpz_tstbit (exp2, 0))
+ {
+ mpz_mul (r2, r2, base2);
+ mpz_mod (r2, r2, mod);
+ }
+ if (mpz_cmp_ui (exp2, 1) <= 0)
+ break;
+ mpz_mul (base2, base2, base2);
+ mpz_mod (base2, base2, mod);
+ mpz_tdiv_q_2exp (exp2, exp2, 1);
+ }
+
+ mpz_powm (r1, base, exp, mod);
+ MPZ_CHECK_FORMAT (r1);
+
+ if (mpz_cmp (r1, r2) != 0)
+ {
+ fprintf (stderr, "\nIncorrect results in test %d for operands:\n", i);
+ debug_mp (base, -16);
+ debug_mp (exp, -16);
+ debug_mp (mod, -16);
+ fprintf (stderr, "mpz_powm result:\n");
+ debug_mp (r1, -16);
+ fprintf (stderr, "reference result:\n");
+ debug_mp (r2, -16);
+ abort ();
+ }
+
+ if (mpz_tdiv_ui (mod, 2) == 0)
+ continue;
+
+ mpz_powm_sec (r1, base, exp, mod);
+ MPZ_CHECK_FORMAT (r1);
+
+ if (mpz_cmp (r1, r2) != 0)
+ {
+ fprintf (stderr, "\nIncorrect results in test %d for operands:\n", i);
+ debug_mp (base, -16);
+ debug_mp (exp, -16);
+ debug_mp (mod, -16);
+ fprintf (stderr, "mpz_powm_sec result:\n");
+ debug_mp (r1, -16);
+ fprintf (stderr, "reference result:\n");
+ debug_mp (r2, -16);
+ abort ();
+ }
+ }
+
+ mpz_clear (bs);
+ mpz_clear (base);
+ mpz_clear (exp);
+ mpz_clear (mod);
+ mpz_clear (r1);
+ mpz_clear (r2);
+ mpz_clear (t1);
+ mpz_clear (exp2);
+ mpz_clear (base2);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/t-powm_ui.c b/gmp/tests/mpz/t-powm_ui.c
new file mode 100644
index 0000000000..a95e473c32
--- /dev/null
+++ b/gmp/tests/mpz/t-powm_ui.c
@@ -0,0 +1,128 @@
+/* Test mpz_powm_ui, mpz_mul, mpz_mod.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+int
+main (int argc, char **argv)
+{
+ mpz_t base, exp, mod;
+ mpz_t r1, r2, base2;
+ mp_size_t base_size, exp_size, mod_size;
+ unsigned long int exp2;
+ int i;
+ int reps = 100;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+
+ tests_start ();
+ rands = RANDS;
+
+ TESTS_REPS (reps, argv, argc);
+
+ mpz_inits (bs, base, exp, mod, r1, r2, base2, NULL);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 18 + 2;
+
+ do /* Loop until mathematically well-defined. */
+ {
+ mpz_urandomb (bs, rands, size_range);
+ base_size = mpz_get_ui (bs);
+ mpz_rrandomb (base, rands, base_size);
+
+ mpz_urandomb (bs, rands, 6L);
+ exp_size = mpz_get_ui (bs);
+ mpz_rrandomb (exp, rands, exp_size);
+ exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
+ }
+ while (mpz_cmp_ui (base, 0) == 0 && exp2 == 0);
+
+ do
+ {
+ mpz_urandomb (bs, rands, size_range);
+ mod_size = mpz_get_ui (bs);
+ mpz_rrandomb (mod, rands, mod_size);
+ }
+ while (mpz_cmp_ui (mod, 0) == 0);
+
+ mpz_urandomb (bs, rands, 2);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (base, base);
+
+ /* printf ("%ld %ld\n", SIZ (base), SIZ (mod)); */
+
+#if 0
+ putc ('\n', stderr);
+ gmp_fprintf (stderr, "B = 0x%Zx\n", base);
+ gmp_fprintf (stderr, "M = 0x%Zx\n", mod);
+#endif
+
+ exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
+ mpz_set_ui (r2, 1);
+ mpz_set (base2, base);
+ mpz_mod (r2, r2, mod); /* needed when exp==0 and mod==1 */
+ while (exp2 != 0)
+ {
+ if (exp2 % 2 != 0)
+ {
+ mpz_mul (r2, r2, base2);
+ mpz_mod (r2, r2, mod);
+ }
+ mpz_mul (base2, base2, base2);
+ mpz_mod (base2, base2, mod);
+ exp2 = exp2 / 2;
+ }
+
+ exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
+ mpz_powm_ui (r1, base, exp2, mod);
+ MPZ_CHECK_FORMAT (r1);
+
+#if 0
+ gmp_fprintf (stderr, "R = 0x%Zx\n", r1);
+ gmp_fprintf (stderr, "REF = 0x%Zx\n", r2);
+#endif
+
+ if (mpz_cmp (r1, r2) != 0)
+ {
+ fprintf (stderr, "\ntest %d: Incorrect results for operands:\n", i);
+ gmp_fprintf (stderr, "B = 0x%Zx\n", base);
+ gmp_fprintf (stderr, "E = 0x%Zx\n", exp);
+ gmp_fprintf (stderr, "M = 0x%Zx\n", mod);
+ gmp_fprintf (stderr, "R = 0x%Zx\n", r1);
+ gmp_fprintf (stderr, "REF = 0x%Zx\n", r2);
+ abort ();
+ }
+ }
+
+ mpz_clears (bs, base, exp, mod, r1, r2, base2, NULL);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-pprime_p.c b/gmp/tests/mpz/t-pprime_p.c
new file mode 100644
index 0000000000..d437299e53
--- /dev/null
+++ b/gmp/tests/mpz/t-pprime_p.c
@@ -0,0 +1,190 @@
+/* Exercise mpz_probab_prime_p.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Enhancements:
+
+ - Test some big primes don't come back claimed to be composite.
+ - Test some big composites don't come back claimed to be certainly prime.
+ - Test some big composites with small factors are identified as certainly
+ composite. */
+
+
+/* return 1 if prime, 0 if composite */
+int
+isprime (long n)
+{
+ long i;
+
+ n = ABS(n);
+
+ if (n < 2)
+ return 0;
+ if (n == 2)
+ return 1;
+ if ((n & 1) == 0)
+ return 0;
+
+ for (i = 3; i < n; i++)
+ if ((n % i) == 0)
+ return 0;
+
+ return 1;
+}
+
+void
+check_one (mpz_srcptr n, int want)
+{
+ int got;
+
+ got = mpz_probab_prime_p (n, 25);
+
+ /* "definitely prime" is fine if we only wanted "probably prime" */
+ if (got == 2 && want == 1)
+ want = 2;
+
+ if (got != want)
+ {
+ printf ("mpz_probab_prime_p\n");
+ mpz_trace (" n ", n);
+ printf (" got =%d", got);
+ printf (" want=%d", want);
+ abort ();
+ }
+}
+
+void
+check_pn (mpz_ptr n, int want)
+{
+ check_one (n, want);
+ mpz_neg (n, n);
+ check_one (n, want);
+}
+
+/* expect certainty for small n */
+void
+check_small (void)
+{
+ mpz_t n;
+ long i;
+
+ mpz_init (n);
+
+ for (i = 0; i < 300; i++)
+ {
+ mpz_set_si (n, i);
+ check_pn (n, isprime (i));
+ }
+
+ mpz_clear (n);
+}
+
+void
+check_composites (int count)
+{
+ int i;
+ mpz_t a, b, n, bs;
+ unsigned long size_range, size;
+ gmp_randstate_ptr rands = RANDS;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (n);
+ mpz_init (bs);
+
+ for (i = 0; i < count; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
+
+ mpz_urandomb (bs, rands, size_range);
+ size = mpz_get_ui (bs);
+ mpz_rrandomb (a, rands, size);
+
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
+ mpz_rrandomb (b, rands, size);
+
+ /* Exclude trivial factors */
+ if (mpz_cmp_ui (a, 1) == 0)
+ mpz_set_ui (a, 2);
+ if (mpz_cmp_ui (b, 1) == 0)
+ mpz_set_ui (b, 2);
+
+ mpz_mul (n, a, b);
+
+ check_pn (n, 0);
+ }
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (n);
+ mpz_clear (bs);
+}
+
+static void
+check_primes (void)
+{
+ static const char * const primes[] = {
+ "2", "17", "65537",
+ /* diffie-hellman-group1-sha1, also "Well known group 2" in RFC
+ 2412, 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 } */
+ "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
+ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
+ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
+ "FFFFFFFFFFFFFFFF",
+ NULL
+ };
+
+ mpz_t n;
+ int i;
+
+ mpz_init (n);
+
+ for (i = 0; primes[i]; i++)
+ {
+ mpz_set_str_or_abort (n, primes[i], 0);
+ check_one (n, 1);
+ }
+ mpz_clear (n);
+}
+
+int
+main (int argc, char **argv)
+{
+ int count = 1000;
+
+ TESTS_REPS (count, argv, argc);
+
+ tests_start ();
+
+ check_small ();
+ check_composites (count);
+ check_primes ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-primorial_ui.c b/gmp/tests/mpz/t-primorial_ui.c
new file mode 100644
index 0000000000..253040ca1e
--- /dev/null
+++ b/gmp/tests/mpz/t-primorial_ui.c
@@ -0,0 +1,97 @@
+/* Exercise mpz_primorial_ui.
+
+Copyright 2000-2002, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Usage: t-primorial_ui [x|num]
+
+ With no arguments testing goes up to the initial value of "limit" below.
+ With a number argument tests are carried that far, or with a literal "x"
+ tests are continued without limit (this being meant only for development
+ purposes). */
+
+static int isprime (unsigned long int t);
+
+int
+main (int argc, char *argv[])
+{
+ unsigned long n;
+ unsigned long limit = 2222;
+ mpz_t f, r;
+
+ tests_start ();
+
+ if (argc > 1 && argv[1][0] == 'x')
+ limit = ULONG_MAX;
+ else if (argc > 1)
+ limit = atoi (argv[1]);
+
+ /* for small limb testing */
+ limit = MIN (limit, MP_LIMB_T_MAX);
+
+ mpz_init_set_ui (f, 1); /* 0# = 1 */
+ mpz_init (r);
+
+ for (n = 0; n < limit; n++)
+ {
+ mpz_primorial_ui (r, n);
+ MPZ_CHECK_FORMAT (r);
+
+ if (mpz_cmp (f, r) != 0)
+ {
+ printf ("mpz_primorial_ui(%lu) wrong\n", n);
+ printf (" got "); mpz_out_str (stdout, 10, r); printf("\n");
+ printf (" want "); mpz_out_str (stdout, 10, f); printf("\n");
+ abort ();
+ }
+
+ if (isprime (n+1))
+ mpz_mul_ui (f, f, n+1); /* p# = (p-1)# * (p) */
+ }
+
+ mpz_clear (f);
+ mpz_clear (r);
+
+ tests_end ();
+
+ exit (0);
+}
+
+static int
+isprime (unsigned long int t)
+{
+ unsigned long int q, r, d;
+
+ if (t < 3 || (t & 1) == 0)
+ return t == 2;
+
+ for (d = 3, r = 1; r != 0; d += 2)
+ {
+ q = t / d;
+ r = t - q * d;
+ if (q < d)
+ return 1;
+ }
+ return 0;
+}
diff --git a/gmp/tests/mpz/t-remove.c b/gmp/tests/mpz/t-remove.c
new file mode 100644
index 0000000000..4de74675fd
--- /dev/null
+++ b/gmp/tests/mpz/t-remove.c
@@ -0,0 +1,147 @@
+/* Test mpz_remove.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2009, 2012, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void debug_mp (mpz_t);
+unsigned long int mpz_refremove (mpz_t, const mpz_t, const mpz_t);
+
+int
+main (int argc, char **argv)
+{
+ unsigned long int exp;
+ mpz_t t, dest, refdest, dividend, divisor;
+ mp_size_t dividend_size, divisor_size;
+ int i;
+ int reps = 1000;
+ unsigned long int pwr, refpwr;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long size_range;
+
+ tests_start ();
+ rands = RANDS;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_inits (bs, t, dest, refdest, dividend, divisor, NULL);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 18 + 1; /* 1..524288 bit operands */
+
+ do
+ {
+ mpz_urandomb (bs, rands, size_range);
+ divisor_size = mpz_get_ui (bs);
+ mpz_rrandomb (divisor, rands, divisor_size);
+ }
+ while (mpz_sgn (divisor) == 0);
+
+ mpz_urandomb (bs, rands, size_range);
+ dividend_size = mpz_get_ui (bs) + divisor_size;
+ mpz_rrandomb (dividend, rands, dividend_size);
+
+ mpz_urandomb (bs, rands, 32);
+ exp = mpz_get_ui (bs) % (5 + 10000 / mpz_sizeinbase (divisor, 2));
+ if (mpz_get_ui (bs) & 2)
+ mpz_neg (divisor, divisor);
+ mpz_pow_ui (t, divisor, exp);
+ mpz_mul (dividend, dividend, t);
+
+ refpwr = mpz_refremove (refdest, dividend, divisor);
+ pwr = mpz_remove (dest, dividend, divisor);
+
+ if (refpwr != pwr || mpz_cmp (refdest, dest) != 0)
+ {
+ fprintf (stderr, "ERROR after %d tests\n", i);
+ fprintf (stderr, "refpower = %lu\n", refpwr);
+ fprintf (stderr, " power = %lu\n", pwr);
+ fprintf (stderr, " op1 = "); debug_mp (dividend);
+ fprintf (stderr, " op2 = "); debug_mp (divisor);
+ fprintf (stderr, "refdest = "); debug_mp (refdest);
+ fprintf (stderr, " dest = "); debug_mp (dest);
+ abort ();
+ }
+ }
+
+ mpz_clears (bs, t, dest, refdest, dividend, divisor, NULL);
+
+ tests_end ();
+ exit (0);
+}
+
+unsigned long int
+mpz_refremove (mpz_t dest, const mpz_t src, const mpz_t f)
+{
+ unsigned long int pwr;
+
+ pwr = 0;
+
+ mpz_set (dest, src);
+ if (mpz_cmpabs_ui (f, 1) > 0)
+ {
+ mpz_t rem, x;
+
+ mpz_init (x);
+ mpz_init (rem);
+
+ for (;; pwr++)
+ {
+ mpz_tdiv_qr (x, rem, dest, f);
+ if (mpz_cmp_ui (rem, 0) != 0)
+ break;
+ mpz_swap (dest, x);
+ }
+
+ mpz_clear (x);
+ mpz_clear (rem);
+ }
+
+ return pwr;
+}
+
+void
+debug_mp (mpz_t x)
+{
+ size_t siz = mpz_sizeinbase (x, 16);
+
+ if (siz > 65)
+ {
+ mpz_t q;
+ mpz_init (q);
+ mpz_tdiv_q_2exp (q, x, 4 * (mpz_sizeinbase (x, 16) - 25));
+ gmp_fprintf (stderr, "%ZX...", q);
+ mpz_tdiv_r_2exp (q, x, 4 * 25);
+ gmp_fprintf (stderr, "%025ZX [%d]\n", q, (int) siz);
+ mpz_clear (q);
+ }
+ else
+ {
+ gmp_fprintf (stderr, "%ZX\n", x);
+ }
+}
diff --git a/gmp/tests/mpz/t-root.c b/gmp/tests/mpz/t-root.c
new file mode 100644
index 0000000000..17efe4cca8
--- /dev/null
+++ b/gmp/tests/mpz/t-root.c
@@ -0,0 +1,174 @@
+/* Test mpz_root, mpz_rootrem, and mpz_perfect_power_p.
+
+Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2009 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void debug_mp (mpz_t, int);
+
+void
+check_one (mpz_t root1, mpz_t x2, unsigned long nth, int i)
+{
+ mpz_t temp, temp2;
+ mpz_t root2, rem2;
+
+ mpz_init (root2);
+ mpz_init (rem2);
+ mpz_init (temp);
+ mpz_init (temp2);
+
+ MPZ_CHECK_FORMAT (root1);
+
+ mpz_rootrem (root2, rem2, x2, nth);
+ MPZ_CHECK_FORMAT (root2);
+ MPZ_CHECK_FORMAT (rem2);
+
+ mpz_pow_ui (temp, root1, nth);
+ MPZ_CHECK_FORMAT (temp);
+
+ mpz_add (temp2, temp, rem2);
+
+ /* Is power of result > argument? */
+ if (mpz_cmp (root1, root2) != 0 || mpz_cmp (x2, temp2) != 0 || mpz_cmpabs (temp, x2) > 0)
+ {
+ fprintf (stderr, "ERROR after test %d\n", i);
+ debug_mp (x2, 10);
+ debug_mp (root1, 10);
+ debug_mp (root2, 10);
+ fprintf (stderr, "nth: %lu\n", nth);
+ abort ();
+ }
+
+ if (nth > 1 && mpz_cmp_ui (temp, 1L) > 0 && ! mpz_perfect_power_p (temp))
+ {
+ fprintf (stderr, "ERROR in mpz_perfect_power_p after test %d\n", i);
+ debug_mp (temp, 10);
+ debug_mp (root1, 10);
+ fprintf (stderr, "nth: %lu\n", nth);
+ abort ();
+ }
+
+ if (nth <= 10000 && mpz_sgn(x2) > 0) /* skip too expensive test */
+ {
+ mpz_add_ui (temp2, root1, 1L);
+ mpz_pow_ui (temp2, temp2, nth);
+ MPZ_CHECK_FORMAT (temp2);
+
+ /* Is square of (result + 1) <= argument? */
+ if (mpz_cmp (temp2, x2) <= 0)
+ {
+ fprintf (stderr, "ERROR after test %d\n", i);
+ debug_mp (x2, 10);
+ debug_mp (root1, 10);
+ fprintf (stderr, "nth: %lu\n", nth);
+ abort ();
+ }
+ }
+
+ mpz_clear (root2);
+ mpz_clear (rem2);
+ mpz_clear (temp);
+ mpz_clear (temp2);
+}
+
+int
+main (int argc, char **argv)
+{
+ mpz_t x2;
+ mpz_t root1;
+ mp_size_t x2_size;
+ int i;
+ int reps = 500;
+ unsigned long nth;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ mpz_init (x2);
+ mpz_init (root1);
+
+ /* This triggers a gcc 4.3.2 bug */
+ mpz_set_str (x2, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000002", 16);
+ mpz_root (root1, x2, 2);
+ check_one (root1, x2, 2, -1);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 17 + 2;
+
+ mpz_urandomb (bs, rands, size_range);
+ x2_size = mpz_get_ui (bs) + 10;
+ mpz_rrandomb (x2, rands, x2_size);
+
+ mpz_urandomb (bs, rands, 15);
+ nth = mpz_getlimbn (bs, 0) % mpz_sizeinbase (x2, 2) + 2;
+
+ mpz_root (root1, x2, nth);
+
+ mpz_urandomb (bs, rands, 4);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ {
+ /* With 50% probability, set x2 near a perfect power. */
+ mpz_pow_ui (x2, root1, nth);
+ if ((bsi & 2) != 0)
+ {
+ mpz_sub_ui (x2, x2, bsi >> 2);
+ mpz_abs (x2, x2);
+ }
+ else
+ mpz_add_ui (x2, x2, bsi >> 2);
+ mpz_root (root1, x2, nth);
+ }
+
+ check_one (root1, x2, nth, i);
+
+ if (((nth & 1) != 0) && ((bsi & 2) != 0))
+ {
+ mpz_neg (x2, x2);
+ mpz_neg (root1, root1);
+ check_one (root1, x2, nth, i);
+ }
+ }
+
+ mpz_clear (bs);
+ mpz_clear (x2);
+ mpz_clear (root1);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/t-scan.c b/gmp/tests/mpz/t-scan.c
new file mode 100644
index 0000000000..95b896b1be
--- /dev/null
+++ b/gmp/tests/mpz/t-scan.c
@@ -0,0 +1,132 @@
+/* Tests of mpz_scan0 and mpz_scan1.
+
+Copyright 2000-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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+unsigned long
+refmpz_scan (mpz_srcptr z, unsigned long i, int sought)
+{
+ unsigned long z_bits = (unsigned long) ABSIZ(z) * GMP_NUMB_BITS;
+
+ do
+ {
+ if (mpz_tstbit (z, i) == sought)
+ return i;
+ i++;
+ }
+ while (i <= z_bits);
+
+ return ULONG_MAX;
+}
+
+unsigned long
+refmpz_scan0 (mpz_srcptr z, unsigned long starting_bit)
+{
+ return refmpz_scan (z, starting_bit, 0);
+}
+
+unsigned long
+refmpz_scan1 (mpz_srcptr z, unsigned long starting_bit)
+{
+ return refmpz_scan (z, starting_bit, 1);
+}
+
+
+void
+check_ref (void)
+{
+ static const int offset[] = {
+ -2, -1, 0, 1, 2, 3
+ };
+
+ mpz_t z;
+ int test, neg, sought, oindex, o;
+ mp_size_t size, isize;
+ unsigned long start, got, want;
+
+ mpz_init (z);
+ for (test = 0; test < 5; test++)
+ {
+ for (size = 0; size < 5; size++)
+ {
+ mpz_random2 (z, size);
+
+ for (neg = 0; neg <= 1; neg++)
+ {
+ if (neg)
+ mpz_neg (z, z);
+
+ for (isize = 0; isize <= size; isize++)
+ {
+ for (oindex = 0; oindex < numberof (offset); oindex++)
+ {
+ o = offset[oindex];
+ if ((int) isize*GMP_NUMB_BITS < -o)
+ continue; /* start would be negative */
+
+ start = isize*GMP_NUMB_BITS + o;
+
+ for (sought = 0; sought <= 1; sought++)
+ {
+ if (sought == 0)
+ {
+ got = mpz_scan0 (z, start);
+ want = refmpz_scan0 (z, start);
+ }
+ else
+ {
+ got = mpz_scan1 (z, start);
+ want = refmpz_scan1 (z, start);
+ }
+
+ if (got != want)
+ {
+ printf ("wrong at test=%d, size=%ld, neg=%d, start=%lu, sought=%d\n",
+ test, size, neg, start, sought);
+ printf (" z 0x");
+ mpz_out_str (stdout, -16, z);
+ printf ("\n");
+ printf (" got=%lu, want=%lu\n", got, want);
+ exit (1);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ mpz_clear (z);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ check_ref ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-set_d.c b/gmp/tests/mpz/t-set_d.c
new file mode 100644
index 0000000000..d587e65442
--- /dev/null
+++ b/gmp/tests/mpz/t-set_d.c
@@ -0,0 +1,140 @@
+/* Test mpz_set_d and mpz_init_set_d.
+
+Copyright 2000-2003, 2006 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_data (void)
+{
+ static const struct {
+ double d;
+ mp_size_t want_size;
+ mp_limb_t want_data[2];
+ } data[] = {
+
+ { 0.0, 0 },
+ { 1.0, 1, { 1 } },
+ { -1.0, -1, { 1 } },
+
+ { 123.0, 1, { 123 } },
+ { -123.0, -1, { 123 } },
+
+ { 1e-1, 0, { 0 } },
+ { -1e-1, 0, { 0 } },
+ { 2.328306436538696e-10, 0, { 0 } },
+ { -2.328306436538696e-10, 0, { 0 } },
+ { 5.421010862427522e-20, 0, { 0 } },
+ { -5.421010862427522e-20, 0, { 0 } },
+ { 2.938735877055719e-39, 0, { 0 } },
+ { -2.938735877055719e-39, 0, { 0 } },
+ };
+
+ mpz_t z;
+ int i;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_init (z);
+ mpz_set_d (z, data[i].d);
+ MPZ_CHECK_FORMAT (z);
+ if (z->_mp_size != data[i].want_size
+ || refmpn_cmp_allowzero (z->_mp_d, data[i].want_data,
+ ABS (data[i].want_size)) != 0)
+ {
+ printf ("mpz_set_d wrong on data[%d]\n", i);
+ bad:
+ d_trace (" d ", data[i].d);
+ printf (" got size %ld\n", (long) z->_mp_size);
+ printf (" want size %ld\n", (long) data[i].want_size);
+ mpn_trace (" got z", z->_mp_d, z->_mp_size);
+ mpn_trace (" want z", data[i].want_data, data[i].want_size);
+ abort();
+ }
+ mpz_clear (z);
+
+ mpz_init_set_d (z, data[i].d);
+ MPZ_CHECK_FORMAT (z);
+ if (z->_mp_size != data[i].want_size
+ || refmpn_cmp_allowzero (z->_mp_d, data[i].want_data,
+ ABS (data[i].want_size)) != 0)
+ {
+ printf ("mpz_init_set_d wrong on data[%d]\n", i);
+ goto bad;
+ }
+ mpz_clear (z);
+ }
+}
+
+/* Try mpz_set_d on values 2^i+1, while such a value fits a double. */
+void
+check_2n_plus_1 (void)
+{
+ volatile double p, d, diff;
+ mpz_t want, got;
+ int i;
+
+ mpz_init (want);
+ mpz_init (got);
+
+ p = 1.0;
+ mpz_set_ui (want, 2L); /* gives 3 on first step */
+
+ for (i = 1; i < 500; i++)
+ {
+ mpz_mul_2exp (want, want, 1L);
+ mpz_sub_ui (want, want, 1L); /* want = 2^i+1 */
+
+ p *= 2.0; /* p = 2^i */
+ d = p + 1.0;
+ diff = d - p;
+ if (diff != 1.0)
+ break; /* rounding occurred, stop now */
+
+ mpz_set_d (got, d);
+ MPZ_CHECK_FORMAT (got);
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_set_d wrong on 2^%d+1\n", i);
+ d_trace (" d ", d);
+ mpz_trace (" got ", got);
+ mpz_trace (" want ", want);
+ abort ();
+ }
+ }
+
+ mpz_clear (want);
+ mpz_clear (got);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+ check_2n_plus_1 ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-set_f.c b/gmp/tests/mpz/t-set_f.c
new file mode 100644
index 0000000000..38b5a2c438
--- /dev/null
+++ b/gmp/tests/mpz/t-set_f.c
@@ -0,0 +1,126 @@
+/* Test mpz_set_f.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpz_srcptr z)
+{
+ static const int shift[] = {
+ 0, 1, GMP_LIMB_BITS, 2*GMP_LIMB_BITS, 5*GMP_LIMB_BITS
+ };
+
+ int sh, shneg, neg;
+ mpf_t f;
+ mpz_t got, want;
+
+ mpf_init2 (f, mpz_sizeinbase(z,2));
+ mpz_init (got);
+ mpz_init (want);
+
+ for (sh = 0; sh < numberof(shift); sh++)
+ {
+ for (shneg = 0; shneg <= 1; shneg++)
+ {
+ for (neg = 0; neg <= 1; neg++)
+ {
+ mpf_set_z (f, z);
+ mpz_set (want, z);
+
+ if (neg)
+ {
+ mpf_neg (f, f);
+ mpz_neg (want, want);
+ }
+
+ if (shneg)
+ {
+ mpz_tdiv_q_2exp (want, want, shift[sh]);
+ mpf_div_2exp (f, f, shift[sh]);
+ }
+ else
+ {
+ mpz_mul_2exp (want, want, shift[sh]);
+ mpf_mul_2exp (f, f, shift[sh]);
+ }
+
+ mpz_set_f (got, f);
+ MPZ_CHECK_FORMAT (got);
+
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("wrong result\n");
+ printf (" shift %d\n", shneg ? -shift[sh] : shift[sh]);
+ printf (" neg %d\n", neg);
+ mpf_trace (" f", f);
+ mpz_trace (" got", got);
+ mpz_trace (" want", want);
+ abort ();
+ }
+ }
+ }
+ }
+
+ mpf_clear (f);
+ mpz_clear (got);
+ mpz_clear (want);
+}
+
+
+void
+check_various (void)
+{
+ mpz_t z;
+
+ mpz_init (z);
+
+ mpz_set_ui (z, 0L);
+ check_one (z);
+
+ mpz_set_si (z, 123L);
+ check_one (z);
+
+ mpz_rrandomb (z, RANDS, 2*GMP_LIMB_BITS);
+ check_one (z);
+
+ mpz_rrandomb (z, RANDS, 5*GMP_LIMB_BITS);
+ check_one (z);
+
+ mpz_clear (z);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+#if GMP_NAIL_BITS == 0
+ tests_start ();
+ mp_trace_base = 16;
+
+ check_various ();
+
+ tests_end ();
+#endif
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-set_si.c b/gmp/tests/mpz/t-set_si.c
new file mode 100644
index 0000000000..b1e55ede33
--- /dev/null
+++ b/gmp/tests/mpz/t-set_si.c
@@ -0,0 +1,97 @@
+/* Test mpz_set_si and mpz_init_set_si.
+
+Copyright 2000-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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_data (void)
+{
+#if GMP_NUMB_BITS <= BITS_PER_ULONG
+#define ENTRY(n) { n, { n, 0 } }
+#else
+#define ENTRY(n) { n, { (n) & GMP_NUMB_MASK, (n) >> GMP_NUMB_BITS } }
+#endif
+
+ static const struct {
+ long n;
+ mp_size_t want_size;
+ mp_limb_t want_data[2];
+ } data[] = {
+
+ { 0L, 0 },
+ { 1L, 1, { 1 } },
+ { -1L, -1, { 1 } },
+
+#if GMP_NUMB_BITS >= BITS_PER_ULONG
+ { LONG_MAX, 1, { LONG_MAX, 0 } },
+ { -LONG_MAX, -1, { LONG_MAX, 0 } },
+ { LONG_HIGHBIT, -1, { ULONG_HIGHBIT, 0 } },
+#else
+ { LONG_MAX, 2, { LONG_MAX & GMP_NUMB_MASK, LONG_MAX >> GMP_NUMB_BITS } },
+ { -LONG_MAX, -2, { LONG_MAX & GMP_NUMB_MASK, LONG_MAX >> GMP_NUMB_BITS }},
+ { LONG_HIGHBIT, -2, { 0, ULONG_HIGHBIT >> GMP_NUMB_BITS } },
+#endif
+ };
+
+ mpz_t n;
+ int i;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ mpz_init (n);
+ mpz_set_si (n, data[i].n);
+ MPZ_CHECK_FORMAT (n);
+ if (n->_mp_size != data[i].want_size
+ || refmpn_cmp_allowzero (n->_mp_d, data[i].want_data,
+ ABS (data[i].want_size)) != 0)
+ {
+ printf ("mpz_set_si wrong on data[%d]\n", i);
+ abort();
+ }
+ mpz_clear (n);
+
+ mpz_init_set_si (n, data[i].n);
+ MPZ_CHECK_FORMAT (n);
+ if (n->_mp_size != data[i].want_size
+ || refmpn_cmp_allowzero (n->_mp_d, data[i].want_data,
+ ABS (data[i].want_size)) != 0)
+ {
+ printf ("mpz_init_set_si wrong on data[%d]\n", i);
+ abort();
+ }
+ mpz_clear (n);
+ }
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_data ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-set_str.c b/gmp/tests/mpz/t-set_str.c
new file mode 100644
index 0000000000..c6a59f2fed
--- /dev/null
+++ b/gmp/tests/mpz/t-set_str.c
@@ -0,0 +1,109 @@
+/* Test mpz_set_str.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+check_one (mpz_srcptr want, int fail, int base, const char *str)
+{
+ mpz_t got;
+
+ MPZ_CHECK_FORMAT (want);
+ mp_trace_base = (base == 0 ? 16 : base);
+
+ mpz_init (got);
+
+ if (mpz_set_str (got, str, base) != fail)
+ {
+ printf ("mpz_set_str unexpectedly failed\n");
+ printf (" base %d\n", base);
+ printf (" str \"%s\"\n", str);
+ abort ();
+ }
+ MPZ_CHECK_FORMAT (got);
+
+ if (fail == 0 && mpz_cmp (got, want) != 0)
+ {
+ printf ("mpz_set_str wrong\n");
+ printf (" base %d\n", base);
+ printf (" str \"%s\"\n", str);
+ mpz_trace ("got ", got);
+ mpz_trace ("want", want);
+ abort ();
+ }
+
+ mpz_clear (got);
+}
+
+void
+check_samples (void)
+{
+ mpz_t z;
+
+ mpz_init (z);
+
+ mpz_set_ui (z, 0L);
+ check_one (z, 0, 0, "0 ");
+ check_one (z, 0, 0, " 0 0 0 ");
+ check_one (z, 0, 0, " -0B 0 ");
+ check_one (z, 0, 0, " 0X 0 ");
+ check_one (z, 0, 10, "0 ");
+ check_one (z, 0, 10, "-0 ");
+ check_one (z, 0, 10, " 0 000 000 ");
+
+ mpz_set_ui (z, 123L);
+ check_one (z, 0, 0, "123 ");
+ check_one (z, 0, 0, "123 ");
+ check_one (z, 0, 0, "0173 ");
+ check_one (z, 0, 0, " 0b 1 11 10 11 ");
+ check_one (z, 0, 0, " 0x 7b ");
+ check_one (z, 0, 0, "0x7B");
+ check_one (z, 0, 10, "123 ");
+ check_one (z, 0, 10, "123 ");
+ check_one (z, 0, 0, " 123 ");
+ check_one (z, 0, 0, " 123 ");
+ check_one (z, 0, 10, " 0000123 ");
+ check_one (z, 0, 10, " 123 ");
+ check_one (z,-1, 10, "1%");
+ check_one (z,-1, 0, "3!");
+ check_one (z,-1, 0, "0123456789");
+ check_one (z,-1, 0, "13579BDF");
+ check_one (z,-1, 0, "0b0102");
+ check_one (z,-1, 0, "0x010G");
+ check_one (z,-1, 37,"0x010G");
+ check_one (z,-1, 99,"0x010G");
+
+ mpz_clear (z);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_samples ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-sizeinbase.c b/gmp/tests/mpz/t-sizeinbase.c
new file mode 100644
index 0000000000..b5eab8846f
--- /dev/null
+++ b/gmp/tests/mpz/t-sizeinbase.c
@@ -0,0 +1,90 @@
+/* Test mpz_sizeinbase.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#if 0
+ /* Disabled due to the bogosity of trying to fake an _mp_d pointer to
+ below an object. Has been seen to fail on a hppa system and on ia64. */
+
+
+/* Create a fake mpz consisting of just a single 1 bit, with totbits being
+ the total number of bits, inclusive of that 1 bit. */
+void
+mpz_fake_bits (mpz_ptr z, unsigned long totbits)
+{
+ static mp_limb_t n;
+ unsigned long zero_bits, zero_limbs;
+
+ zero_bits = totbits - 1;
+ zero_limbs = zero_bits / GMP_NUMB_BITS;
+ zero_bits %= GMP_NUMB_BITS;
+
+ SIZ(z) = zero_limbs + 1;
+ PTR(z) = (&n) - (SIZ(z) - 1);
+ n = CNST_LIMB(1) << zero_bits;
+
+ ASSERT_ALWAYS (mpz_sizeinbase (z, 2) == totbits);
+}
+
+
+/* This was seen to fail on a GNU/Linux powerpc32 with gcc 2.95.2,
+ apparently due to a doubtful value of mp_bases[10].chars_per_bit_exactly
+ (0X1.34413509F79FDP-2 whereas 0X1.34413509F79FFP-2 is believed correct).
+ Presumably this is a glibc problem when gcc converts the decimal string
+ in mp_bases.c, or maybe it's only a function of the rounding mode during
+ compilation. */
+void
+check_sample (void)
+{
+ unsigned long totbits = 198096465;
+ int base = 10;
+ size_t want = 59632979;
+ size_t got;
+ mpz_t z;
+
+ mpz_fake_bits (z, totbits);
+ got = mpz_sizeinbase (z, base);
+ if (got != want)
+ {
+ printf ("mpz_sizeinbase\n");
+ printf (" base %d\n", base);
+ printf (" totbits %lu\n", totbits);
+ printf (" got %u\n", got);
+ printf (" want %u\n", want);
+ abort ();
+ }
+}
+#endif
+
+int
+main (void)
+{
+ tests_start ();
+
+ /* check_sample (); */
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/mpz/t-sqrtrem.c b/gmp/tests/mpz/t-sqrtrem.c
new file mode 100644
index 0000000000..9aeb233890
--- /dev/null
+++ b/gmp/tests/mpz/t-sqrtrem.c
@@ -0,0 +1,116 @@
+/* Test mpz_add, mpz_add_ui, mpz_cmp, mpz_cmp, mpz_mul, mpz_sqrtrem.
+
+Copyright 1991, 1993, 1994, 1996, 2000-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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void dump_abort (mpz_t, mpz_t, mpz_t);
+void debug_mp (mpz_t, int);
+
+int
+main (int argc, char **argv)
+{
+ mpz_t x2;
+ mpz_t x, rem;
+ mpz_t temp, temp2;
+ mp_size_t x2_size;
+ int i;
+ int reps = 1000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long size_range;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ mpz_init (x2);
+ mpz_init (x);
+ mpz_init (rem);
+ mpz_init (temp);
+ mpz_init (temp2);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 17 + 2; /* 0..262144 bit operands */
+
+ mpz_urandomb (bs, rands, size_range);
+ x2_size = mpz_get_ui (bs);
+ mpz_rrandomb (x2, rands, x2_size);
+
+ /* printf ("%ld\n", SIZ (x2)); */
+
+ mpz_sqrtrem (x, rem, x2);
+ MPZ_CHECK_FORMAT (x);
+ MPZ_CHECK_FORMAT (rem);
+
+ mpz_mul (temp, x, x);
+
+ /* Is square of result > argument? */
+ if (mpz_cmp (temp, x2) > 0)
+ dump_abort (x2, x, rem);
+
+ mpz_add_ui (temp2, x, 1);
+ mpz_mul (temp2, temp2, temp2);
+
+ /* Is square of (result + 1) <= argument? */
+ if (mpz_cmp (temp2, x2) <= 0)
+ dump_abort (x2, x, rem);
+
+ mpz_add (temp2, temp, rem);
+
+ /* Is the remainder wrong? */
+ if (mpz_cmp (x2, temp2) != 0)
+ dump_abort (x2, x, rem);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (x2);
+ mpz_clear (x);
+ mpz_clear (rem);
+ mpz_clear (temp);
+ mpz_clear (temp2);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort (mpz_t x2, mpz_t x, mpz_t rem)
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "x2 = "); debug_mp (x2, -16);
+ fprintf (stderr, "x = "); debug_mp (x, -16);
+ fprintf (stderr, "remainder = "); debug_mp (rem, -16);
+ abort();
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/t-tdiv.c b/gmp/tests/mpz/t-tdiv.c
new file mode 100644
index 0000000000..902b51c003
--- /dev/null
+++ b/gmp/tests/mpz/t-tdiv.c
@@ -0,0 +1,146 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_tdiv_qr, mpz_tdiv_q,
+ mpz_tdiv_r, mpz_mul.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void dump_abort (mpz_t, mpz_t);
+void debug_mp (mpz_t, int);
+
+int
+main (int argc, char **argv)
+{
+ mpz_t dividend, divisor;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size, divisor_size;
+ int i;
+ int reps = 1000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+
+ tests_start ();
+ TESTS_REPS (reps, argv, argc);
+
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ mpz_init (dividend);
+ mpz_init (divisor);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 18 + 2; /* 0..524288 bit operands */
+
+ do
+ {
+ mpz_urandomb (bs, rands, size_range);
+ divisor_size = mpz_get_ui (bs);
+ mpz_rrandomb (divisor, rands, divisor_size);
+ }
+ while (mpz_sgn (divisor) == 0);
+
+ mpz_urandomb (bs, rands, size_range);
+ dividend_size = mpz_get_ui (bs) + divisor_size;
+ mpz_rrandomb (dividend, rands, dividend_size);
+
+ mpz_urandomb (bs, rands, 2);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (dividend, dividend);
+ if ((bsi & 2) != 0)
+ mpz_neg (divisor, divisor);
+
+ /* printf ("%ld %ld\n", SIZ (dividend), SIZ (divisor)); */
+
+ mpz_tdiv_qr (quotient, remainder, dividend, divisor);
+ mpz_tdiv_q (quotient2, dividend, divisor);
+ mpz_tdiv_r (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the dividend
+ (quotient rounded towards 0). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ mpz_mul (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (temp, divisor);
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp (remainder, temp) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (dividend);
+ mpz_clear (divisor);
+ mpz_clear (quotient);
+ mpz_clear (remainder);
+ mpz_clear (quotient2);
+ mpz_clear (remainder2);
+ mpz_clear (temp);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort (mpz_t dividend, mpz_t divisor)
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/mpz/t-tdiv_ui.c b/gmp/tests/mpz/t-tdiv_ui.c
new file mode 100644
index 0000000000..db266eb9d0
--- /dev/null
+++ b/gmp/tests/mpz/t-tdiv_ui.c
@@ -0,0 +1,159 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_tdiv_qr_ui, mpz_tdiv_q_ui,
+ mpz_tdiv_r_ui, mpz_tdiv_ui, mpz_mul_ui.
+
+Copyright 1993, 1994, 1996, 2000-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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void dump_abort (const char *, mpz_t, unsigned long);
+void debug_mp (mpz_t, int);
+
+int
+main (int argc, char **argv)
+{
+ mpz_t dividend;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size;
+ unsigned long divisor;
+ int i;
+ int reps = 200000;
+ gmp_randstate_ptr rands;
+ mpz_t bs;
+ unsigned long bsi, size_range;
+ unsigned long r_rq, r_q, r_r, r;
+
+ tests_start ();
+ rands = RANDS;
+
+ mpz_init (bs);
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ mpz_urandomb (bs, rands, 32);
+ size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */
+
+ do
+ {
+ mpz_rrandomb (bs, rands, 64);
+ divisor = mpz_get_ui (bs);
+ }
+ while (divisor == 0);
+
+ mpz_urandomb (bs, rands, size_range);
+ dividend_size = mpz_get_ui (bs);
+ mpz_rrandomb (dividend, rands, dividend_size);
+
+ mpz_urandomb (bs, rands, 2);
+ bsi = mpz_get_ui (bs);
+ if ((bsi & 1) != 0)
+ mpz_neg (dividend, dividend);
+
+ /* printf ("%ld\n", SIZ (dividend)); */
+
+ r_rq = mpz_tdiv_qr_ui (quotient, remainder, dividend, divisor);
+ r_q = mpz_tdiv_q_ui (quotient2, dividend, divisor);
+ r_r = mpz_tdiv_r_ui (remainder2, dividend, divisor);
+ r = mpz_tdiv_ui (dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort ("quotients from mpz_tdiv_qr_ui and mpz_tdiv_q_ui differ",
+ dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort ("remainders from mpz_tdiv_qr_ui and mpz_tdiv_r_ui differ",
+ dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort ("quotient sign wrong", dividend, divisor);
+
+ /* Check if the remainder has the same sign as the dividend
+ (quotient rounded towards 0). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort ("remainder sign wrong", dividend, divisor);
+
+ mpz_mul_ui (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort ("n mod d != n - [n/d]*d", dividend, divisor);
+
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp_ui (remainder, divisor) >= 0)
+ dump_abort ("remainder greater than divisor", dividend, divisor);
+
+ if (mpz_cmp_ui (remainder, r_rq) != 0)
+ dump_abort ("remainder returned from mpz_tdiv_qr_ui is wrong",
+ dividend, divisor);
+ if (mpz_cmp_ui (remainder, r_q) != 0)
+ dump_abort ("remainder returned from mpz_tdiv_q_ui is wrong",
+ dividend, divisor);
+ if (mpz_cmp_ui (remainder, r_r) != 0)
+ dump_abort ("remainder returned from mpz_tdiv_r_ui is wrong",
+ dividend, divisor);
+ if (mpz_cmp_ui (remainder, r) != 0)
+ dump_abort ("remainder returned from mpz_tdiv_ui is wrong",
+ dividend, divisor);
+ }
+
+ mpz_clear (bs);
+ mpz_clear (dividend);
+ mpz_clear (quotient);
+ mpz_clear (remainder);
+ mpz_clear (quotient2);
+ mpz_clear (remainder2);
+ mpz_clear (temp);
+
+ tests_end ();
+ exit (0);
+}
+
+void
+dump_abort (const char *str, mpz_t dividend, unsigned long divisor)
+{
+ fprintf (stderr, "ERROR: %s\n", str);
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = %lX\n", divisor);
+ abort();
+}
+
+void
+debug_mp (mpz_t x, int base)
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gmp/tests/rand/Makefile.am b/gmp/tests/rand/Makefile.am
new file mode 100644
index 0000000000..ed585b7edc
--- /dev/null
+++ b/gmp/tests/rand/Makefile.am
@@ -0,0 +1,89 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2000-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/.
+
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+
+check_PROGRAMS = t-iset t-lc2exp t-mt t-rand t-urbui t-urmui t-urndmm
+TESTS = $(check_PROGRAMS)
+
+EXTRA_PROGRAMS = findlc gen gen.static spect stat
+gen_static_SOURCES = gen.c
+gen_static_LDFLAGS = -static
+findlc_LDADD = libstat.la
+spect_LDADD = libstat.la
+stat_LDADD = libstat.la
+
+EXTRA_LTLIBRARIES = libstat.la
+libstat_la_SOURCES = gmpstat.h statlib.c zdiv_round.c
+libstat_la_LIBADD = $(top_builddir)/libgmp.la $(LIBM)
+
+CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LTLIBRARIES)
+
+allprogs: $(EXTRA_PROGRAMS)
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
+
+manual-test: gen$(EXEEXT) stat$(EXEEXT)
+ @(echo -n '16i: '; ./gen -f mpz_urandomb -z 16 1000 \
+ | ./stat -i 0xffff | grep '^[0-9]')
+ @(echo -n '32i: '; ./gen -f mpz_urandomb -z 32 1000 \
+ | ./stat -i 0xffffffff | grep '^[0-9]')
+ @(echo -n '33i: '; ./gen -f mpz_urandomb -z 33 1000 \
+ | ./stat -i 0x1ffffffff | grep '^[0-9]')
+ @(echo -n '64i: '; ./gen -f mpz_urandomb -z 64 1000 \
+ | ./stat -i 0xffffffffffffffff | grep '^[0-9]')
+ @(echo -n '128i: '; ./gen -f mpz_urandomb -z 128 1000 \
+ | ./stat -i 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | grep '^[0-9]')
+
+ @(echo -n '16f: '; ./gen -f mpf_urandomb -z 16 1000 \
+ | ./stat | grep '^[0-9]')
+ @(echo -n '32f: '; ./gen -f mpf_urandomb -z 32 1000 \
+ | ./stat | grep '^[0-9]')
+ @(echo -n '33f: '; ./gen -f mpf_urandomb -z 33 1000 \
+ | ./stat | grep '^[0-9]')
+ @(echo -n '64f: '; ./gen -f mpf_urandomb -z 64 1000 \
+ | ./stat | grep '^[0-9]')
+ @(echo -n '128f: '; ./gen -f mpf_urandomb -z 128 1000 \
+ | ./stat | grep '^[0-9]')
+
+manual-bigtest: gen$(EXEEXT) stat$(EXEEXT)
+ @(echo '16i: '; ./gen -f mpz_urandomb -z 16 50000 \
+ | ./stat -2 1000 -i 0xffff | grep '^K[mp]')
+ @(echo '32i: '; ./gen -f mpz_urandomb -z 32 50000 \
+ | ./stat -2 1000 -i 0xffffffff | grep '^K[mp]')
+ @(echo '33i: '; ./gen -f mpz_urandomb -z 33 50000 \
+ | ./stat -2 1000 -i 0x1ffffffff | grep '^K[mp]')
+ @(echo '64i: '; ./gen -f mpz_urandomb -z 64 50000 \
+ | ./stat -2 1000 -i 0xffffffffffffffff | grep '^K[mp]')
+ @(echo '128i: '; ./gen -f mpz_urandomb -z 128 50000 \
+ | ./stat -2 1000 -i 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | grep '^K[mp]')
+
+ @(echo '16f: '; ./gen -f mpf_urandomb -z 16 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
+ @(echo '32f: '; ./gen -f mpf_urandomb -z 32 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
+ @(echo '33f: '; ./gen -f mpf_urandomb -z 33 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
+ @(echo '64f: '; ./gen -f mpf_urandomb -z 64 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
+ @(echo '128f: '; ./gen -f mpf_urandomb -z 128 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
diff --git a/gmp/tests/rand/Makefile.in b/gmp/tests/rand/Makefile.in
new file mode 100644
index 0000000000..b902bc5586
--- /dev/null
+++ b/gmp/tests/rand/Makefile.in
@@ -0,0 +1,801 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2000-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/.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+check_PROGRAMS = t-iset$(EXEEXT) t-lc2exp$(EXEEXT) t-mt$(EXEEXT) \
+ t-rand$(EXEEXT) t-urbui$(EXEEXT) t-urmui$(EXEEXT) \
+ t-urndmm$(EXEEXT)
+EXTRA_PROGRAMS = findlc$(EXEEXT) gen$(EXEEXT) gen.static$(EXEEXT) \
+ spect$(EXEEXT) stat$(EXEEXT)
+subdir = tests/rand
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__DEPENDENCIES_1 =
+libstat_la_DEPENDENCIES = $(top_builddir)/libgmp.la \
+ $(am__DEPENDENCIES_1)
+am_libstat_la_OBJECTS = statlib.lo zdiv_round.lo
+libstat_la_OBJECTS = $(am_libstat_la_OBJECTS)
+findlc_SOURCES = findlc.c
+findlc_OBJECTS = findlc.$(OBJEXT)
+findlc_DEPENDENCIES = libstat.la
+gen_SOURCES = gen.c
+gen_OBJECTS = gen.$(OBJEXT)
+gen_LDADD = $(LDADD)
+gen_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+am_gen_static_OBJECTS = gen.$(OBJEXT)
+gen_static_OBJECTS = $(am_gen_static_OBJECTS)
+gen_static_LDADD = $(LDADD)
+gen_static_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+gen_static_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(gen_static_LDFLAGS) $(LDFLAGS) -o $@
+spect_SOURCES = spect.c
+spect_OBJECTS = spect.$(OBJEXT)
+spect_DEPENDENCIES = libstat.la
+stat_SOURCES = stat.c
+stat_OBJECTS = stat.$(OBJEXT)
+stat_DEPENDENCIES = libstat.la
+t_iset_SOURCES = t-iset.c
+t_iset_OBJECTS = t-iset.$(OBJEXT)
+t_iset_LDADD = $(LDADD)
+t_iset_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_lc2exp_SOURCES = t-lc2exp.c
+t_lc2exp_OBJECTS = t-lc2exp.$(OBJEXT)
+t_lc2exp_LDADD = $(LDADD)
+t_lc2exp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_mt_SOURCES = t-mt.c
+t_mt_OBJECTS = t-mt.$(OBJEXT)
+t_mt_LDADD = $(LDADD)
+t_mt_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_rand_SOURCES = t-rand.c
+t_rand_OBJECTS = t-rand.$(OBJEXT)
+t_rand_LDADD = $(LDADD)
+t_rand_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_urbui_SOURCES = t-urbui.c
+t_urbui_OBJECTS = t-urbui.$(OBJEXT)
+t_urbui_LDADD = $(LDADD)
+t_urbui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_urmui_SOURCES = t-urmui.c
+t_urmui_OBJECTS = t-urmui.$(OBJEXT)
+t_urmui_LDADD = $(LDADD)
+t_urmui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+t_urndmm_SOURCES = t-urndmm.c
+t_urndmm_OBJECTS = t-urndmm.$(OBJEXT)
+t_urndmm_LDADD = $(LDADD)
+t_urndmm_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+ $(top_builddir)/libgmp.la
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstat_la_SOURCES) findlc.c gen.c $(gen_static_SOURCES) \
+ spect.c stat.c t-iset.c t-lc2exp.c t-mt.c t-rand.c t-urbui.c \
+ t-urmui.c t-urndmm.c
+DIST_SOURCES = $(libstat_la_SOURCES) findlc.c gen.c \
+ $(gen_static_SOURCES) spect.c stat.c t-iset.c t-lc2exp.c \
+ t-mt.c t-rand.c t-urbui.c t-urmui.c t-urndmm.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+TESTS = $(check_PROGRAMS)
+gen_static_SOURCES = gen.c
+gen_static_LDFLAGS = -static
+findlc_LDADD = libstat.la
+spect_LDADD = libstat.la
+stat_LDADD = libstat.la
+EXTRA_LTLIBRARIES = libstat.la
+libstat_la_SOURCES = gmpstat.h statlib.c zdiv_round.c
+libstat_la_LIBADD = $(top_builddir)/libgmp.la $(LIBM)
+CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LTLIBRARIES)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/rand/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps tests/rand/Makefile
+.PRECIOUS: 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):
+libstat.la: $(libstat_la_OBJECTS) $(libstat_la_DEPENDENCIES) $(EXTRA_libstat_la_DEPENDENCIES)
+ $(LINK) $(libstat_la_OBJECTS) $(libstat_la_LIBADD) $(LIBS)
+
+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
+findlc$(EXEEXT): $(findlc_OBJECTS) $(findlc_DEPENDENCIES) $(EXTRA_findlc_DEPENDENCIES)
+ @rm -f findlc$(EXEEXT)
+ $(LINK) $(findlc_OBJECTS) $(findlc_LDADD) $(LIBS)
+gen$(EXEEXT): $(gen_OBJECTS) $(gen_DEPENDENCIES) $(EXTRA_gen_DEPENDENCIES)
+ @rm -f gen$(EXEEXT)
+ $(LINK) $(gen_OBJECTS) $(gen_LDADD) $(LIBS)
+gen.static$(EXEEXT): $(gen_static_OBJECTS) $(gen_static_DEPENDENCIES) $(EXTRA_gen_static_DEPENDENCIES)
+ @rm -f gen.static$(EXEEXT)
+ $(gen_static_LINK) $(gen_static_OBJECTS) $(gen_static_LDADD) $(LIBS)
+spect$(EXEEXT): $(spect_OBJECTS) $(spect_DEPENDENCIES) $(EXTRA_spect_DEPENDENCIES)
+ @rm -f spect$(EXEEXT)
+ $(LINK) $(spect_OBJECTS) $(spect_LDADD) $(LIBS)
+stat$(EXEEXT): $(stat_OBJECTS) $(stat_DEPENDENCIES) $(EXTRA_stat_DEPENDENCIES)
+ @rm -f stat$(EXEEXT)
+ $(LINK) $(stat_OBJECTS) $(stat_LDADD) $(LIBS)
+t-iset$(EXEEXT): $(t_iset_OBJECTS) $(t_iset_DEPENDENCIES) $(EXTRA_t_iset_DEPENDENCIES)
+ @rm -f t-iset$(EXEEXT)
+ $(LINK) $(t_iset_OBJECTS) $(t_iset_LDADD) $(LIBS)
+t-lc2exp$(EXEEXT): $(t_lc2exp_OBJECTS) $(t_lc2exp_DEPENDENCIES) $(EXTRA_t_lc2exp_DEPENDENCIES)
+ @rm -f t-lc2exp$(EXEEXT)
+ $(LINK) $(t_lc2exp_OBJECTS) $(t_lc2exp_LDADD) $(LIBS)
+t-mt$(EXEEXT): $(t_mt_OBJECTS) $(t_mt_DEPENDENCIES) $(EXTRA_t_mt_DEPENDENCIES)
+ @rm -f t-mt$(EXEEXT)
+ $(LINK) $(t_mt_OBJECTS) $(t_mt_LDADD) $(LIBS)
+t-rand$(EXEEXT): $(t_rand_OBJECTS) $(t_rand_DEPENDENCIES) $(EXTRA_t_rand_DEPENDENCIES)
+ @rm -f t-rand$(EXEEXT)
+ $(LINK) $(t_rand_OBJECTS) $(t_rand_LDADD) $(LIBS)
+t-urbui$(EXEEXT): $(t_urbui_OBJECTS) $(t_urbui_DEPENDENCIES) $(EXTRA_t_urbui_DEPENDENCIES)
+ @rm -f t-urbui$(EXEEXT)
+ $(LINK) $(t_urbui_OBJECTS) $(t_urbui_LDADD) $(LIBS)
+t-urmui$(EXEEXT): $(t_urmui_OBJECTS) $(t_urmui_DEPENDENCIES) $(EXTRA_t_urmui_DEPENDENCIES)
+ @rm -f t-urmui$(EXEEXT)
+ $(LINK) $(t_urmui_OBJECTS) $(t_urmui_LDADD) $(LIBS)
+t-urndmm$(EXEEXT): $(t_urndmm_OBJECTS) $(t_urndmm_DEPENDENCIES) $(EXTRA_t_urndmm_DEPENDENCIES)
+ @rm -f t-urndmm$(EXEEXT)
+ $(LINK) $(t_urndmm_OBJECTS) $(t_urndmm_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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 all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool ctags \
+ 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 \
+ tags uninstall uninstall-am
+
+
+allprogs: $(EXTRA_PROGRAMS)
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
+
+manual-test: gen$(EXEEXT) stat$(EXEEXT)
+ @(echo -n '16i: '; ./gen -f mpz_urandomb -z 16 1000 \
+ | ./stat -i 0xffff | grep '^[0-9]')
+ @(echo -n '32i: '; ./gen -f mpz_urandomb -z 32 1000 \
+ | ./stat -i 0xffffffff | grep '^[0-9]')
+ @(echo -n '33i: '; ./gen -f mpz_urandomb -z 33 1000 \
+ | ./stat -i 0x1ffffffff | grep '^[0-9]')
+ @(echo -n '64i: '; ./gen -f mpz_urandomb -z 64 1000 \
+ | ./stat -i 0xffffffffffffffff | grep '^[0-9]')
+ @(echo -n '128i: '; ./gen -f mpz_urandomb -z 128 1000 \
+ | ./stat -i 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | grep '^[0-9]')
+
+ @(echo -n '16f: '; ./gen -f mpf_urandomb -z 16 1000 \
+ | ./stat | grep '^[0-9]')
+ @(echo -n '32f: '; ./gen -f mpf_urandomb -z 32 1000 \
+ | ./stat | grep '^[0-9]')
+ @(echo -n '33f: '; ./gen -f mpf_urandomb -z 33 1000 \
+ | ./stat | grep '^[0-9]')
+ @(echo -n '64f: '; ./gen -f mpf_urandomb -z 64 1000 \
+ | ./stat | grep '^[0-9]')
+ @(echo -n '128f: '; ./gen -f mpf_urandomb -z 128 1000 \
+ | ./stat | grep '^[0-9]')
+
+manual-bigtest: gen$(EXEEXT) stat$(EXEEXT)
+ @(echo '16i: '; ./gen -f mpz_urandomb -z 16 50000 \
+ | ./stat -2 1000 -i 0xffff | grep '^K[mp]')
+ @(echo '32i: '; ./gen -f mpz_urandomb -z 32 50000 \
+ | ./stat -2 1000 -i 0xffffffff | grep '^K[mp]')
+ @(echo '33i: '; ./gen -f mpz_urandomb -z 33 50000 \
+ | ./stat -2 1000 -i 0x1ffffffff | grep '^K[mp]')
+ @(echo '64i: '; ./gen -f mpz_urandomb -z 64 50000 \
+ | ./stat -2 1000 -i 0xffffffffffffffff | grep '^K[mp]')
+ @(echo '128i: '; ./gen -f mpz_urandomb -z 128 50000 \
+ | ./stat -2 1000 -i 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | grep '^K[mp]')
+
+ @(echo '16f: '; ./gen -f mpf_urandomb -z 16 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
+ @(echo '32f: '; ./gen -f mpf_urandomb -z 32 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
+ @(echo '33f: '; ./gen -f mpf_urandomb -z 33 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
+ @(echo '64f: '; ./gen -f mpf_urandomb -z 64 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
+ @(echo '128f: '; ./gen -f mpf_urandomb -z 128 50000 \
+ | ./stat -2 1000 | grep '^K[mp]')
+
+# 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/gmp/tests/rand/findlc.c b/gmp/tests/rand/findlc.c
new file mode 100644
index 0000000000..2406c3b645
--- /dev/null
+++ b/gmp/tests/rand/findlc.c
@@ -0,0 +1,252 @@
+/*
+Copyright 2000 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <math.h>
+#include "gmp.h"
+#include "gmpstat.h"
+
+#define RCSID(msg) \
+static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
+
+RCSID("$Id$");
+
+int g_debug = 0;
+
+static mpz_t a;
+
+static void
+sh_status (int sig)
+{
+ printf ("sh_status: signal %d caught. dumping status.\n", sig);
+
+ printf (" a = ");
+ mpz_out_str (stdout, 10, a);
+ printf ("\n");
+ fflush (stdout);
+
+ if (SIGSEGV == sig) /* remove SEGV handler */
+ signal (SIGSEGV, SIG_DFL);
+}
+
+/* Input is a modulus (m). We shall find multiplier (a) and adder (c)
+ conforming to the rules found in the first comment block in file
+ mpz/urandom.c.
+
+ Then run a spectral test on the generator and discard any
+ multipliers not passing. */
+
+/* TODO:
+
+ . find a better algorithm than a+=8; bigger jumps perhaps?
+
+*/
+
+void
+mpz_true_random (mpz_t s, unsigned long int nbits)
+{
+#if __FreeBSD__
+ FILE *fs;
+ char c[1];
+ int i;
+
+ mpz_set_ui (s, 0);
+ for (i = 0; i < nbits; i += 8)
+ {
+ for (;;)
+ {
+ int nread;
+ fs = fopen ("/dev/random", "r");
+ nread = fread (c, 1, 1, fs);
+ fclose (fs);
+ if (nread != 0)
+ break;
+ sleep (1);
+ }
+ mpz_mul_2exp (s, s, 8);
+ mpz_add_ui (s, s, ((unsigned long int) c[0]) & 0xff);
+ printf ("%d random bits\n", i + 8);
+ }
+ if (nbits % 8 != 0)
+ mpz_mod_2exp (s, s, nbits);
+#endif
+}
+
+int
+main (int argc, char *argv[])
+{
+ const char usage[] = "usage: findlc [-dv] m2exp [low_merit [high_merit]]\n";
+ int f;
+ int v_lose, m_lose, v_best, m_best;
+ int c;
+ int debug = 1;
+ int cnt_high_merit;
+ mpz_t m;
+ unsigned long int m2exp;
+#define DIMS 6 /* dimensions run in spectral test */
+ mpf_t v[DIMS-1]; /* spectral test result (there's no v
+ for 1st dimension */
+ mpf_t f_merit, low_merit, high_merit;
+ mpz_t acc, minus8;
+ mpz_t min, max;
+ mpz_t s;
+
+
+ mpz_init (m);
+ mpz_init (a);
+ for (f = 0; f < DIMS-1; f++)
+ mpf_init (v[f]);
+ mpf_init (f_merit);
+ mpf_init_set_d (low_merit, .1);
+ mpf_init_set_d (high_merit, .1);
+
+ while ((c = getopt (argc, argv, "a:di:hv")) != -1)
+ switch (c)
+ {
+ case 'd': /* debug */
+ g_debug++;
+ break;
+
+ case 'v': /* print version */
+ puts (rcsid[1]);
+ exit (0);
+
+ case 'h':
+ case '?':
+ default:
+ fputs (usage, stderr);
+ exit (1);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1)
+ {
+ fputs (usage, stderr);
+ exit (1);
+ }
+
+ /* Install signal handler. */
+ if (SIG_ERR == signal (SIGSEGV, sh_status))
+ {
+ perror ("signal (SIGSEGV)");
+ exit (1);
+ }
+ if (SIG_ERR == signal (SIGHUP, sh_status))
+ {
+ perror ("signal (SIGHUP)");
+ exit (1);
+ }
+
+ printf ("findlc: version: %s\n", rcsid[1]);
+ m2exp = atol (argv[0]);
+ mpz_init_set_ui (m, 1);
+ mpz_mul_2exp (m, m, m2exp);
+ printf ("m = 0x");
+ mpz_out_str (stdout, 16, m);
+ puts ("");
+
+ if (argc > 1) /* have low_merit */
+ mpf_set_str (low_merit, argv[1], 0);
+ if (argc > 2) /* have high_merit */
+ mpf_set_str (high_merit, argv[2], 0);
+
+ if (debug)
+ {
+ fprintf (stderr, "low_merit = ");
+ mpf_out_str (stderr, 10, 2, low_merit);
+ fprintf (stderr, "; high_merit = ");
+ mpf_out_str (stderr, 10, 2, high_merit);
+ fputs ("\n", stderr);
+ }
+
+ mpz_init (minus8);
+ mpz_set_si (minus8, -8L);
+ mpz_init_set_ui (acc, 0);
+ mpz_init (s);
+ mpz_init_set_d (min, 0.01 * pow (2.0, (double) m2exp));
+ mpz_init_set_d (max, 0.99 * pow (2.0, (double) m2exp));
+
+ mpz_true_random (s, m2exp); /* Start. */
+ mpz_setbit (s, 0); /* Make it odd. */
+
+ v_best = m_best = 2*(DIMS-1);
+ for (;;)
+ {
+ mpz_add (acc, acc, s);
+ mpz_mod_2exp (acc, acc, m2exp);
+#if later
+ mpz_and_si (a, acc, -8L);
+#else
+ mpz_and (a, acc, minus8);
+#endif
+ mpz_add_ui (a, a, 5);
+ if (mpz_cmp (a, min) <= 0 || mpz_cmp (a, max) >= 0)
+ continue;
+
+ spectral_test (v, DIMS, a, m);
+ for (f = 0, v_lose = m_lose = 0, cnt_high_merit = DIMS-1;
+ f < DIMS-1; f++)
+ {
+ merit (f_merit, f + 2, v[f], m);
+
+ if (mpf_cmp_ui (v[f], 1 << (30 / (f + 2) + (f == 2))) < 0)
+ v_lose++;
+
+ if (mpf_cmp (f_merit, low_merit) < 0)
+ m_lose++;
+
+ if (mpf_cmp (f_merit, high_merit) >= 0)
+ cnt_high_merit--;
+ }
+
+ if (0 == v_lose && 0 == m_lose)
+ {
+ mpz_out_str (stdout, 10, a); puts (""); fflush (stdout);
+ if (0 == cnt_high_merit)
+ break; /* leave loop */
+ }
+ if (v_lose < v_best)
+ {
+ v_best = v_lose;
+ printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose);
+ mpz_out_str (stdout, 10, a); puts (""); fflush (stdout);
+ }
+ if (m_lose < m_best)
+ {
+ m_best = m_lose;
+ printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose);
+ mpz_out_str (stdout, 10, a); puts (""); fflush (stdout);
+ }
+ }
+
+ mpz_clear (m);
+ mpz_clear (a);
+ for (f = 0; f < DIMS-1; f++)
+ mpf_clear (v[f]);
+ mpf_clear (f_merit);
+ mpf_clear (low_merit);
+ mpf_clear (high_merit);
+
+ printf ("done.\n");
+ return 0;
+}
diff --git a/gmp/tests/rand/gen.c b/gmp/tests/rand/gen.c
new file mode 100644
index 0000000000..65401e3751
--- /dev/null
+++ b/gmp/tests/rand/gen.c
@@ -0,0 +1,481 @@
+/* gen.c -- Generate pseudorandom numbers.
+
+Copyright 1999, 2000, 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/. */
+
+/* Examples:
+
+ $ gen 10
+10 integers 0 <= X < 2^32 generated by mpz_urandomb()
+
+ $ gen -f mpf_urandomb 10
+10 real numbers 0 <= X < 1
+
+ $ gen -z 127 10
+10 integers 0 <= X < 2^127
+
+ $ gen -f mpf_urandomb -x .9,1 10
+10 real numbers 0 <= X < .9
+
+ $ gen -s 1 10
+10 integers, sequence seeded with 1
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+
+#if !HAVE_DECL_OPTARG
+extern char *optarg;
+extern int optind, opterr;
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ const char usage[] =
+ "usage: gen [-bhpq] [-a n] [-c a,c,m2exp] [-C a,c,m] [-f func] [-g alg] [-m n] [-s n] " \
+ "[-x f,t] [-z n] [n]\n" \
+ " n number of random numbers to generate\n" \
+ " -a n ASCII output in radix n (default, with n=10)\n" \
+ " -b binary output\n" \
+ " -c a,c,m2exp use supplied LC scheme\n" \
+ " -f func random function, one of\n" \
+ " mpz_urandomb (default), mpz_urandomm, mpf_urandomb, rand, random\n" \
+ " -g alg algorithm, one of mt (default), lc\n" \
+ " -h print this text and exit\n" \
+ " -m n maximum size of generated number plus 1 (0<= X < n) for mpz_urandomm\n" \
+ " -p print used seed on stderr\n" \
+ " -q quiet, no output\n" \
+ " -s n initial seed (default: output from time(3))\n" \
+ " -x f,t exclude all numbers f <= x <= t\n" \
+ " -z n size in bits of generated numbers (0<= X <2^n) (default 32)\n" \
+ "";
+
+ unsigned long int f;
+ unsigned long int n = 0;
+ unsigned long int seed;
+ unsigned long int m2exp = 0;
+ unsigned int size = 32;
+ int seed_from_user = 0;
+ int ascout = 1, binout = 0, printseed = 0;
+ int output_radix = 10;
+ int lc_scheme_from_user = 0;
+ int quiet_flag = 0;
+ mpz_t z_seed;
+ mpz_t z1;
+ mpf_t f1;
+ gmp_randstate_t rstate;
+ int c, i;
+ double drand;
+ long lrand;
+ int do_exclude = 0;
+ mpf_t f_xf, f_xt; /* numbers to exclude from sequence */
+ char *str_xf, *str_xt; /* numbers to exclude from sequence */
+ char *str_a, *str_adder, *str_m;
+ mpz_t z_a, z_m, z_mmax;
+ unsigned long int ul_adder;
+
+ enum
+ {
+ RFUNC_mpz_urandomb = 0,
+ RFUNC_mpz_urandomm,
+ RFUNC_mpf_urandomb,
+ RFUNC_rand,
+ RFUNC_random,
+ } rfunc = RFUNC_mpz_urandomb;
+ char *rfunc_str[] = { "mpz_urandomb", "mpz_urandomm", "mpf_urandomb",
+ "rand", "random" };
+ enum
+ {
+ RNG_MT = 0,
+ RNG_LC
+ };
+ gmp_randalg_t ralg = RNG_MT;
+ /* Texts for the algorithms. The index of each must match the
+ corresponding algorithm in the enum above. */
+ char *ralg_str[] = { "mt", "lc" };
+
+ mpf_init (f_xf);
+ mpf_init (f_xt);
+ mpf_init (f1);
+ mpz_init (z1);
+ mpz_init (z_seed);
+ mpz_init_set_ui (z_mmax, 0);
+
+
+ while ((c = getopt (argc, argv, "a:bc:f:g:hm:n:pqs:z:x:")) != -1)
+ switch (c)
+ {
+ case 'a':
+ ascout = 1;
+ binout = 0;
+ output_radix = atoi (optarg);
+ break;
+
+ case 'b':
+ ascout = 0;
+ binout = 1;
+ break;
+
+ case 'c': /* User supplied LC scheme: a,c,m2exp */
+ if (NULL == (str_a = strtok (optarg, ","))
+ || NULL == (str_adder = strtok (NULL, ","))
+ || NULL == (str_m = strtok (NULL, ",")))
+ {
+ fprintf (stderr, "gen: bad LC scheme parameters: %s\n", optarg);
+ exit (1);
+ }
+#ifdef HAVE_STRTOUL
+ ul_adder = strtoul (str_adder, NULL, 0);
+#elif HAVE_STRTOL
+ ul_adder = (unsigned long int) strtol (str_adder, NULL, 0);
+#else
+ ul_adder = (unsigned long int) atoi (str_adder);
+#endif
+
+ if (mpz_init_set_str (z_a, str_a, 0))
+ {
+ fprintf (stderr, "gen: bad LC scheme parameter `a': %s\n", str_a);
+ exit (1);
+ }
+ if (ULONG_MAX == ul_adder)
+ {
+ fprintf (stderr, "gen: bad LC scheme parameter `c': %s\n",
+ str_adder);
+ exit (1);
+ }
+ m2exp = atol (str_m);
+
+ lc_scheme_from_user = 1;
+ break;
+
+
+ case 'f':
+ rfunc = -1;
+ for (f = 0; f < sizeof (rfunc_str) / sizeof (*rfunc_str); f++)
+ if (!strcmp (optarg, rfunc_str[f]))
+ {
+ rfunc = f;
+ break;
+ }
+ if (rfunc == -1)
+ {
+ fputs (usage, stderr);
+ exit (1);
+ }
+ break;
+
+ case 'g': /* algorithm */
+ ralg = -1;
+ for (f = 0; f < sizeof (ralg_str) / sizeof (*ralg_str); f++)
+ if (!strcmp (optarg, ralg_str[f]))
+ {
+ ralg = f;
+ break;
+ }
+ if (ralg == -1)
+ {
+ fputs (usage, stderr);
+ exit (1);
+ }
+ break;
+
+ case 'm': /* max for mpz_urandomm() */
+ if (mpz_set_str (z_mmax, optarg, 0))
+ {
+ fprintf (stderr, "gen: bad max value: %s\n", optarg);
+ exit (1);
+ }
+ break;
+
+ case 'p': /* print seed on stderr */
+ printseed = 1;
+ break;
+
+ case 'q': /* quiet */
+ quiet_flag = 1;
+ break;
+
+ case 's': /* user provided seed */
+ if (mpz_set_str (z_seed, optarg, 0))
+ {
+ fprintf (stderr, "gen: bad seed argument %s\n", optarg);
+ exit (1);
+ }
+ seed_from_user = 1;
+ break;
+
+ case 'z':
+ size = atoi (optarg);
+ if (size < 1)
+ {
+ fprintf (stderr, "gen: bad size argument (-z %u)\n", size);
+ exit (1);
+ }
+ break;
+
+ case 'x': /* Exclude. from,to */
+ str_xf = optarg;
+ str_xt = strchr (optarg, ',');
+ if (NULL == str_xt)
+ {
+ fprintf (stderr, "gen: bad exclusion parameters: %s\n", optarg);
+ exit (1);
+ }
+ *str_xt++ = '\0';
+ do_exclude = 1;
+ break;
+
+ case 'h':
+ case '?':
+ default:
+ fputs (usage, stderr);
+ exit (1);
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (! seed_from_user)
+ mpz_set_ui (z_seed, (unsigned long int) time (NULL));
+ seed = mpz_get_ui (z_seed);
+ if (printseed)
+ {
+ fprintf (stderr, "gen: seed used: ");
+ mpz_out_str (stderr, output_radix, z_seed);
+ fprintf (stderr, "\n");
+ }
+
+ mpf_set_prec (f1, size);
+
+ /* init random state and plant seed */
+ switch (rfunc)
+ {
+ case RFUNC_mpf_urandomb:
+#if 0
+ /* Don't init a too small generator. */
+ size = PREC (f1) * GMP_LIMB_BITS;
+ /* Fall through. */
+#endif
+ case RFUNC_mpz_urandomb:
+ case RFUNC_mpz_urandomm:
+ switch (ralg)
+ {
+ case RNG_MT:
+ gmp_randinit_mt (rstate);
+ break;
+
+ case RNG_LC:
+ if (! lc_scheme_from_user)
+ gmp_randinit_lc_2exp_size (rstate, MIN (128, size));
+ else
+ gmp_randinit_lc_2exp (rstate, z_a, ul_adder, m2exp);
+ break;
+
+ default:
+ fprintf (stderr, "gen: unsupported algorithm\n");
+ exit (1);
+ }
+
+ gmp_randseed (rstate, z_seed);
+ break;
+
+ case RFUNC_rand:
+ srand (seed);
+ break;
+
+ case RFUNC_random:
+#ifdef __FreeBSD__ /* FIXME */
+ if (seed_from_user)
+ srandom (seed);
+ else
+ srandomdev ();
+#else
+ fprintf (stderr, "gen: unsupported algorithm\n");
+#endif
+ break;
+
+ default:
+ fprintf (stderr, "gen: random function not implemented\n");
+ exit (1);
+ }
+
+ /* set up excludes */
+ if (do_exclude)
+ switch (rfunc)
+ {
+ case RFUNC_mpf_urandomb:
+
+ if (mpf_set_str (f_xf, str_xf, 10) ||
+ mpf_set_str (f_xt, str_xt, 10))
+ {
+ fprintf (stderr, "gen: bad exclusion-from (\"%s\") " \
+ "or exclusion-to (\"%s\") string. no exclusion done.\n",
+ str_xf, str_xt);
+ do_exclude = 0;
+ }
+ break;
+
+ default:
+ fprintf (stderr, "gen: exclusion not implemented for chosen " \
+ "randomization function. all numbers included in sequence.\n");
+ }
+
+ /* generate and print */
+ if (argc > 0)
+ {
+#if HAVE_STRTOUL
+ n = strtoul (argv[0], (char **) NULL, 10);
+#elif HAVE_STRTOL
+ n = (unsigned long int) strtol (argv[0], (char **) NULL, 10);
+#else
+ n = (unsigned long int) atoi (argv[0]);
+#endif
+ }
+
+ for (f = 0; n == 0 || f < n; f++)
+ {
+ switch (rfunc)
+ {
+ case RFUNC_mpz_urandomb:
+ mpz_urandomb (z1, rstate, size);
+ if (quiet_flag)
+ break;
+ if (binout)
+ {
+ /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
+ fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n");
+ exit (1);
+ }
+ else
+ {
+ mpz_out_str (stdout, output_radix, z1);
+ puts ("");
+ }
+ break;
+
+ case RFUNC_mpz_urandomm:
+ mpz_urandomm (z1, rstate, z_mmax);
+ if (quiet_flag)
+ break;
+ if (binout)
+ {
+ /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
+ fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n");
+ exit (1);
+ }
+ else
+ {
+ mpz_out_str (stdout, output_radix, z1);
+ puts ("");
+ }
+ break;
+
+ case RFUNC_mpf_urandomb:
+ mpf_urandomb (f1, rstate, size);
+ if (do_exclude)
+ if (mpf_cmp (f1, f_xf) >= 0 && mpf_cmp (f1, f_xt) <= 0)
+ break;
+ if (quiet_flag)
+ break;
+ if (binout)
+ {
+ fprintf (stderr, "gen: binary output for floating point numbers "\
+ "not implemented\n");
+ exit (1);
+ }
+ else
+ {
+ mpf_out_str (stdout, output_radix, 0, f1);
+ puts ("");
+ }
+ break;
+
+ case RFUNC_rand:
+ i = rand ();
+#ifdef FLOAT_OUTPUT
+ if (i)
+ drand = (double) i / (double) RAND_MAX;
+ else
+ drand = 0.0;
+ if (quiet_flag)
+ break;
+ if (binout)
+ fwrite (&drand, sizeof (drand), 1, stdout);
+ else
+ printf ("%e\n", drand);
+#else
+ if (quiet_flag)
+ break;
+ if (binout)
+ fwrite (&i, sizeof (i), 1, stdout);
+ else
+ printf ("%d\n", i);
+#endif
+ break;
+
+ case RFUNC_random:
+ lrand = random ();
+ if (lrand)
+ drand = (double) lrand / (double) 0x7fffffff;
+ else
+ drand = 0;
+ if (quiet_flag)
+ break;
+ if (binout)
+ fwrite (&drand, sizeof (drand), 1, stdout);
+ else
+ printf ("%e\n", drand);
+ break;
+
+ default:
+ fprintf (stderr, "gen: random function not implemented\n");
+ exit (1);
+ }
+
+ }
+
+ /* clean up */
+ switch (rfunc)
+ {
+ case RFUNC_mpz_urandomb:
+ case RFUNC_mpf_urandomb:
+ gmp_randclear (rstate);
+ break;
+ default:
+ break;
+ }
+ mpf_clear (f1);
+ mpf_clear (f_xf);
+ mpf_clear (f_xt);
+ mpz_clear (z1);
+ mpz_clear (z_seed);
+
+ return 0;
+}
+
+static void *debug_dummyz = mpz_dump;
+static void *debug_dummyf = mpf_dump;
diff --git a/gmp/tests/rand/gmpstat.h b/gmp/tests/rand/gmpstat.h
new file mode 100644
index 0000000000..99c5cca195
--- /dev/null
+++ b/gmp/tests/rand/gmpstat.h
@@ -0,0 +1,75 @@
+/* gmpstat.h */
+
+/*
+Copyright 1999 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/. */
+
+/* This file requires the following header files: gmp.h */
+
+#ifndef __GMPSTAT_H__
+#define __GMPSTAT_H__
+
+/* Global debug flag. FIXME: Remove. */
+extern int g_debug;
+#define DEBUG_1 0
+#define DEBUG_2 1
+
+/* Max number of dimensions in spectral test. FIXME: Makw dynamic. */
+#define GMP_SPECT_MAXT 10
+
+void
+mpf_freqt (mpf_t Kp,
+ mpf_t Km,
+ mpf_t X[],
+ const unsigned long int n);
+unsigned long int
+mpz_freqt (mpf_t V,
+ mpz_t X[],
+ unsigned int imax,
+ const unsigned long int n);
+
+/* Low level functions. */
+void
+ks (mpf_t Kp,
+ mpf_t Km,
+ mpf_t X[],
+ void (P) (mpf_t, mpf_t),
+ const unsigned long int n);
+
+void
+ks_table (mpf_t p, mpf_t val, const unsigned int n);
+
+void
+x2_table (double t[],
+ unsigned int v);
+
+void
+spectral_test (mpf_t rop[], unsigned int T, mpz_t a, mpz_t m);
+void
+vz_dot (mpz_t rop, mpz_t V1[], mpz_t V2[], unsigned int n);
+void
+f_floor (mpf_t rop, mpf_t op);
+
+void
+merit (mpf_t rop, unsigned int t, mpf_t v, mpz_t m);
+double
+merit_u (unsigned int t, mpf_t v, mpz_t m);
+
+/* From separate source files: */
+void zdiv_round (mpz_t rop, mpz_t n, mpz_t d);
+
+#endif /* !__GMPSTAT_H__ */
diff --git a/gmp/tests/rand/spect.c b/gmp/tests/rand/spect.c
new file mode 100644
index 0000000000..596ff3a9c4
--- /dev/null
+++ b/gmp/tests/rand/spect.c
@@ -0,0 +1,137 @@
+/* spect.c -- the spectral test */
+
+/*
+Copyright 1999 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/. */
+
+/* T is upper dimension. Z_A is the LC multiplier, which is
+ relatively prime to Z_M, the LC modulus. The result is put in
+ rop[] with v[t] in rop[t-2]. */
+
+/* BUGS: Due to lazy allocation scheme, maximum T is hard coded to MAXT. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include "gmp.h"
+
+#include "gmpstat.h"
+
+int g_debug = 0;
+
+int
+main (int argc, char *argv[])
+{
+ const char usage[] = "usage: spect [-d] a m n\n";
+ int c;
+ unsigned int n;
+ mpz_t a, m;
+ mpf_t res[GMP_SPECT_MAXT], res_min[GMP_SPECT_MAXT], f_tmp;
+ int f;
+
+
+ mpz_init (a);
+ mpz_init (m);
+ for (f = 0; f < GMP_SPECT_MAXT; f++)
+ {
+ mpf_init (res[f]);
+ mpf_init (res_min[f]);
+ }
+ mpf_init (f_tmp);
+ mpf_set_ui (res_min[0], 32768); /* 2^15 */
+ mpf_set_ui (res_min[1], 1024); /* 2^10 */
+ mpf_set_ui (res_min[2], 256); /* 2^8 */
+ mpf_set_ui (res_min[3], 64); /* 2^6 */
+ mpf_set_ui (res_min[4], 32); /* 2^5 */
+
+ while ((c = getopt (argc, argv, "dh")) != -1)
+ switch (c)
+ {
+ case 'd': /* debug */
+ g_debug++;
+ break;
+ case 'h':
+ default:
+ fputs (usage, stderr);
+ exit (1);
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 3)
+ {
+ fputs (usage, stderr);
+ exit (1);
+ }
+
+ mpz_set_str (a, argv[0], 0);
+ mpz_set_str (m, argv[1], 0);
+ n = (unsigned int) atoi (argv[2]);
+ if (n + 1 > GMP_SPECT_MAXT)
+ n = GMP_SPECT_MAXT + 1;
+
+ spectral_test (res, n, a, m);
+
+ for (f = 0; f < n - 1; f++)
+ {
+ /* print v */
+ printf ("%d: v = ", f + 2);
+ mpf_out_str (stdout, 10, 4, res[f]);
+
+#ifdef PRINT_RAISED_BY_TWO_AS_WELL
+ printf (" (^2 = ");
+ mpf_mul (f_tmp, res[f], res[f]);
+ mpf_out_str (stdout, 10, 4, f_tmp);
+ printf (")");
+#endif /* PRINT_RAISED_BY_TWO_AS_WELL */
+
+ /* print merit */
+ printf (" m = ");
+ merit (f_tmp, f + 2, res[f], m);
+ mpf_out_str (stdout, 10, 4, f_tmp);
+
+ if (mpf_cmp (res[f], res_min[f]) < 0)
+ printf ("\t*** v too low ***");
+ if (mpf_get_d (f_tmp) < .1)
+ printf ("\t*** merit too low ***");
+
+ puts ("");
+ }
+
+ mpz_clear (a);
+ mpz_clear (m);
+ for (f = 0; f < GMP_SPECT_MAXT; f++)
+ {
+ mpf_clear (res[f]);
+ mpf_clear (res_min[f]);
+ }
+ mpf_clear (f_tmp);
+
+ return 0;
+}
+
+
+void
+debug_foo()
+{
+ if (0)
+ {
+ mpz_dump (0);
+ mpf_dump (0);
+ }
+}
diff --git a/gmp/tests/rand/stat.c b/gmp/tests/rand/stat.c
new file mode 100644
index 0000000000..1285ccfb9f
--- /dev/null
+++ b/gmp/tests/rand/stat.c
@@ -0,0 +1,407 @@
+/* stat.c -- statistical tests of random number sequences. */
+
+/*
+Copyright 1999, 2000 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/. */
+
+/* Examples:
+
+ $ gen 1000 | stat
+Test 1000 real numbers.
+
+ $ gen 30000 | stat -2 1000
+Test 1000 real numbers 30 times and then test the 30 results in a
+``second level''.
+
+ $ gen -f mpz_urandomb 1000 | stat -i 0xffffffff
+Test 1000 integers 0 <= X <= 2^32-1.
+
+ $ gen -f mpz_urandomb -z 34 1000 | stat -i 0x3ffffffff
+Test 1000 integers 0 <= X <= 2^34-1.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include "gmp.h"
+#include "gmpstat.h"
+
+#if !HAVE_DECL_OPTARG
+extern char *optarg;
+extern int optind, opterr;
+#endif
+
+#define FVECSIZ (100000L)
+
+int g_debug = 0;
+
+static void
+print_ks_results (mpf_t f_p, mpf_t f_p_prob,
+ mpf_t f_m, mpf_t f_m_prob,
+ FILE *fp)
+{
+ double p, pp, m, mp;
+
+ p = mpf_get_d (f_p);
+ m = mpf_get_d (f_m);
+ pp = mpf_get_d (f_p_prob);
+ mp = mpf_get_d (f_m_prob);
+
+ fprintf (fp, "%.4f (%.0f%%)\t", p, pp * 100.0);
+ fprintf (fp, "%.4f (%.0f%%)\n", m, mp * 100.0);
+}
+
+static void
+print_x2_table (unsigned int v, FILE *fp)
+{
+ double t[7];
+ int f;
+
+
+ fprintf (fp, "Chi-square table for v=%u\n", v);
+ fprintf (fp, "1%%\t5%%\t25%%\t50%%\t75%%\t95%%\t99%%\n");
+ x2_table (t, v);
+ for (f = 0; f < 7; f++)
+ fprintf (fp, "%.2f\t", t[f]);
+ fputs ("\n", fp);
+}
+
+
+
+/* Pks () -- Distribution function for KS results with a big n (like 1000
+ or so): F(x) = 1 - pow(e, -2*x^2) [Knuth, vol 2, p.51]. */
+/* gnuplot: plot [0:1] Pks(x), Pks(x) = 1-exp(-2*x**2) */
+
+static void
+Pks (mpf_t p, mpf_t x)
+{
+ double dt; /* temp double */
+
+ mpf_set (p, x);
+ mpf_mul (p, p, p); /* p = x^2 */
+ mpf_mul_ui (p, p, 2); /* p = 2*x^2 */
+ mpf_neg (p, p); /* p = -2*x^2 */
+ /* No pow() in gmp. Use doubles. */
+ /* FIXME: Use exp()? */
+ dt = pow (M_E, mpf_get_d (p));
+ mpf_set_d (p, dt);
+ mpf_ui_sub (p, 1, p);
+}
+
+/* f_freq() -- frequency test on real numbers 0<=f<1*/
+static void
+f_freq (const unsigned l1runs, const unsigned l2runs,
+ mpf_t fvec[], const unsigned long n)
+{
+ unsigned f;
+ mpf_t f_p, f_p_prob;
+ mpf_t f_m, f_m_prob;
+ mpf_t *l1res; /* level 1 result array */
+
+ mpf_init (f_p); mpf_init (f_m);
+ mpf_init (f_p_prob); mpf_init (f_m_prob);
+
+
+ /* Allocate space for 1st level results. */
+ l1res = (mpf_t *) malloc (l2runs * 2 * sizeof (mpf_t));
+ if (NULL == l1res)
+ {
+ fprintf (stderr, "stat: malloc failure\n");
+ exit (1);
+ }
+
+ printf ("\nEquidistribution/Frequency test on real numbers (0<=X<1):\n");
+ printf ("\tKp\t\tKm\n");
+
+ for (f = 0; f < l2runs; f++)
+ {
+ /* f_printvec (fvec, n); */
+ mpf_freqt (f_p, f_m, fvec + f * n, n);
+
+ /* what's the probability of getting these results? */
+ ks_table (f_p_prob, f_p, n);
+ ks_table (f_m_prob, f_m, n);
+
+ if (l1runs == 0)
+ {
+ /*printf ("%u:\t", f + 1);*/
+ print_ks_results (f_p, f_p_prob, f_m, f_m_prob, stdout);
+ }
+ else
+ {
+ /* save result */
+ mpf_init_set (l1res[f], f_p);
+ mpf_init_set (l1res[f + l2runs], f_m);
+ }
+ }
+
+ /* Now, apply the KS test on the results from the 1st level rounds
+ with the distribution
+ F(x) = 1 - pow(e, -2*x^2) [Knuth, vol 2, p.51] */
+
+ if (l1runs != 0)
+ {
+ /*printf ("-------------------------------------\n");*/
+
+ /* The Kp's. */
+ ks (f_p, f_m, l1res, Pks, l2runs);
+ ks_table (f_p_prob, f_p, l2runs);
+ ks_table (f_m_prob, f_m, l2runs);
+ printf ("Kp:\t");
+ print_ks_results (f_p, f_p_prob, f_m, f_m_prob, stdout);
+
+ /* The Km's. */
+ ks (f_p, f_m, l1res + l2runs, Pks, l2runs);
+ ks_table (f_p_prob, f_p, l2runs);
+ ks_table (f_m_prob, f_m, l2runs);
+ printf ("Km:\t");
+ print_ks_results (f_p, f_p_prob, f_m, f_m_prob, stdout);
+ }
+
+ mpf_clear (f_p); mpf_clear (f_m);
+ mpf_clear (f_p_prob); mpf_clear (f_m_prob);
+ free (l1res);
+}
+
+/* z_freq(l1runs, l2runs, zvec, n, max) -- frequency test on integers
+ 0<=z<=MAX */
+static void
+z_freq (const unsigned l1runs,
+ const unsigned l2runs,
+ mpz_t zvec[],
+ const unsigned long n,
+ unsigned int max)
+{
+ mpf_t V; /* result */
+ double d_V; /* result as a double */
+
+ mpf_init (V);
+
+
+ printf ("\nEquidistribution/Frequency test on integers (0<=X<=%u):\n", max);
+ print_x2_table (max, stdout);
+
+ mpz_freqt (V, zvec, max, n);
+
+ d_V = mpf_get_d (V);
+ printf ("V = %.2f (n = %lu)\n", d_V, n);
+
+ mpf_clear (V);
+}
+
+unsigned int stat_debug = 0;
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ const char usage[] =
+ "usage: stat [-d] [-2 runs] [-i max | -r max] [file]\n" \
+ " file filename\n" \
+ " -2 runs perform 2-level test with RUNS runs on 1st level\n" \
+ " -d increase debugging level\n" \
+ " -i max input is integers 0 <= Z <= MAX\n" \
+ " -r max input is real numbers 0 <= R < 1 and use MAX as\n" \
+ " maximum value when converting real numbers to integers\n" \
+ "";
+
+ mpf_t fvec[FVECSIZ];
+ mpz_t zvec[FVECSIZ];
+ unsigned long int f, n, vecentries;
+ char *filen;
+ FILE *fp;
+ int c;
+ int omitoutput = 0;
+ int realinput = -1; /* 1: input is real numbers 0<=R<1;
+ 0: input is integers 0 <= Z <= MAX. */
+ long l1runs = 0, /* 1st level runs */
+ l2runs = 1; /* 2nd level runs */
+ mpf_t f_temp;
+ mpz_t z_imax; /* max value when converting between
+ real number and integer. */
+ mpf_t f_imax_plus1; /* f_imax + 1 stored in an mpf_t for
+ convenience */
+ mpf_t f_imax_minus1; /* f_imax - 1 stored in an mpf_t for
+ convenience */
+
+
+ mpf_init (f_temp);
+ mpz_init_set_ui (z_imax, 0x7fffffff);
+ mpf_init (f_imax_plus1);
+ mpf_init (f_imax_minus1);
+
+ while ((c = getopt (argc, argv, "d2:i:r:")) != -1)
+ switch (c)
+ {
+ case '2':
+ l1runs = atol (optarg);
+ l2runs = -1; /* set later on */
+ break;
+ case 'd': /* increase debug level */
+ stat_debug++;
+ break;
+ case 'i':
+ if (1 == realinput)
+ {
+ fputs ("stat: options -i and -r are mutually exclusive\n", stderr);
+ exit (1);
+ }
+ if (mpz_set_str (z_imax, optarg, 0))
+ {
+ fprintf (stderr, "stat: bad max value %s\n", optarg);
+ exit (1);
+ }
+ realinput = 0;
+ break;
+ case 'r':
+ if (0 == realinput)
+ {
+ fputs ("stat: options -i and -r are mutually exclusive\n", stderr);
+ exit (1);
+ }
+ if (mpz_set_str (z_imax, optarg, 0))
+ {
+ fprintf (stderr, "stat: bad max value %s\n", optarg);
+ exit (1);
+ }
+ realinput = 1;
+ break;
+ case 'o':
+ omitoutput = atoi (optarg);
+ break;
+ case '?':
+ default:
+ fputs (usage, stderr);
+ exit (1);
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1)
+ fp = stdin;
+ else
+ filen = argv[0];
+
+ if (fp != stdin)
+ if (NULL == (fp = fopen (filen, "r")))
+ {
+ perror (filen);
+ exit (1);
+ }
+
+ if (-1 == realinput)
+ realinput = 1; /* default is real numbers */
+
+ /* read file and fill appropriate vec */
+ if (1 == realinput) /* real input */
+ {
+ for (f = 0; f < FVECSIZ ; f++)
+ {
+ mpf_init (fvec[f]);
+ if (!mpf_inp_str (fvec[f], fp, 10))
+ break;
+ }
+ }
+ else /* integer input */
+ {
+ for (f = 0; f < FVECSIZ ; f++)
+ {
+ mpz_init (zvec[f]);
+ if (!mpz_inp_str (zvec[f], fp, 10))
+ break;
+ }
+ }
+ vecentries = n = f; /* number of entries read */
+ fclose (fp);
+
+ if (FVECSIZ == f)
+ fprintf (stderr, "stat: warning: discarding input due to lazy allocation "\
+ "of only %ld entries. sorry.\n", FVECSIZ);
+
+ printf ("Got %lu numbers.\n", n);
+
+ /* convert and fill the other vec */
+ /* since fvec[] contains 0<=f<1 and we want ivec[] to contain
+ 0<=z<=imax and we are truncating all fractions when
+ converting float to int, we have to add 1 to imax.*/
+ mpf_set_z (f_imax_plus1, z_imax);
+ mpf_add_ui (f_imax_plus1, f_imax_plus1, 1);
+ if (1 == realinput) /* fill zvec[] */
+ {
+ for (f = 0; f < n; f++)
+ {
+ mpf_mul (f_temp, fvec[f], f_imax_plus1);
+ mpz_init (zvec[f]);
+ mpz_set_f (zvec[f], f_temp); /* truncating fraction */
+ if (stat_debug > 1)
+ {
+ mpz_out_str (stderr, 10, zvec[f]);
+ fputs ("\n", stderr);
+ }
+ }
+ }
+ else /* integer input; fill fvec[] */
+ {
+ /* mpf_set_z (f_imax_minus1, z_imax);
+ mpf_sub_ui (f_imax_minus1, f_imax_minus1, 1);*/
+ for (f = 0; f < n; f++)
+ {
+ mpf_init (fvec[f]);
+ mpf_set_z (fvec[f], zvec[f]);
+ mpf_div (fvec[f], fvec[f], f_imax_plus1);
+ if (stat_debug > 1)
+ {
+ mpf_out_str (stderr, 10, 0, fvec[f]);
+ fputs ("\n", stderr);
+ }
+ }
+ }
+
+ /* 2 levels? */
+ if (1 != l2runs)
+ {
+ l2runs = n / l1runs;
+ printf ("Doing %ld second level rounds "\
+ "with %ld entries in each round", l2runs, l1runs);
+ if (n % l1runs)
+ printf (" (discarding %ld entr%s)", n % l1runs,
+ n % l1runs == 1 ? "y" : "ies");
+ puts (".");
+ n = l1runs;
+ }
+
+#ifndef DONT_FFREQ
+ f_freq (l1runs, l2runs, fvec, n);
+#endif
+#ifdef DO_ZFREQ
+ z_freq (l1runs, l2runs, zvec, n, mpz_get_ui (z_imax));
+#endif
+
+ mpf_clear (f_temp); mpz_clear (z_imax);
+ mpf_clear (f_imax_plus1);
+ mpf_clear (f_imax_minus1);
+ for (f = 0; f < vecentries; f++)
+ {
+ mpf_clear (fvec[f]);
+ mpz_clear (zvec[f]);
+ }
+
+ return 0;
+}
diff --git a/gmp/tests/rand/statlib.c b/gmp/tests/rand/statlib.c
new file mode 100644
index 0000000000..7cecd6dee2
--- /dev/null
+++ b/gmp/tests/rand/statlib.c
@@ -0,0 +1,837 @@
+/* statlib.c -- Statistical functions for testing the randomness of
+ number sequences. */
+
+/*
+Copyright 1999, 2000 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/. */
+
+/* The theories for these functions are taken from D. Knuth's "The Art
+of Computer Programming: Volume 2, Seminumerical Algorithms", Third
+Edition, Addison Wesley, 1998. */
+
+/* Implementation notes.
+
+The Kolmogorov-Smirnov test.
+
+Eq. (13) in Knuth, p. 50, says that if X1, X2, ..., Xn are independent
+observations arranged into ascending order
+
+ Kp = sqr(n) * max(j/n - F(Xj)) for all 1<=j<=n
+ Km = sqr(n) * max(F(Xj) - (j-1)/n)) for all 1<=j<=n
+
+where F(x) = Pr(X <= x) = probability that (X <= x), which for a
+uniformly distributed random real number between zero and one is
+exactly the number itself (x).
+
+
+The answer to exercise 23 gives the following implementation, which
+doesn't need the observations to be sorted in ascending order:
+
+for (k = 0; k < m; k++)
+ a[k] = 1.0
+ b[k] = 0.0
+ c[k] = 0
+
+for (each observation Xj)
+ Y = F(Xj)
+ k = floor (m * Y)
+ a[k] = min (a[k], Y)
+ b[k] = max (b[k], Y)
+ c[k] += 1
+
+ j = 0
+ rp = rm = 0
+ for (k = 0; k < m; k++)
+ if (c[k] > 0)
+ rm = max (rm, a[k] - j/n)
+ j += c[k]
+ rp = max (rp, j/n - b[k])
+
+Kp = sqr (n) * rp
+Km = sqr (n) * rm
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "gmp.h"
+#include "gmpstat.h"
+
+/* ks (Kp, Km, X, P, n) -- Perform a Kolmogorov-Smirnov test on the N
+ real numbers between zero and one in vector X. P is the
+ distribution function, called for each entry in X, which should
+ calculate the probability of X being greater than or equal to any
+ number in the sequence. (For a uniformly distributed sequence of
+ real numbers between zero and one, this is simply equal to X.) The
+ result is put in Kp and Km. */
+
+void
+ks (mpf_t Kp,
+ mpf_t Km,
+ mpf_t X[],
+ void (P) (mpf_t, mpf_t),
+ unsigned long int n)
+{
+ mpf_t Kt; /* temp */
+ mpf_t f_x;
+ mpf_t f_j; /* j */
+ mpf_t f_jnq; /* j/n or (j-1)/n */
+ unsigned long int j;
+
+ /* Sort the vector in ascending order. */
+ qsort (X, n, sizeof (__mpf_struct), mpf_cmp);
+
+ /* K-S test. */
+ /* Kp = sqr(n) * max(j/n - F(Xj)) for all 1<=j<=n
+ Km = sqr(n) * max(F(Xj) - (j-1)/n)) for all 1<=j<=n
+ */
+
+ mpf_init (Kt); mpf_init (f_x); mpf_init (f_j); mpf_init (f_jnq);
+ mpf_set_ui (Kp, 0); mpf_set_ui (Km, 0);
+ for (j = 1; j <= n; j++)
+ {
+ P (f_x, X[j-1]);
+ mpf_set_ui (f_j, j);
+
+ mpf_div_ui (f_jnq, f_j, n);
+ mpf_sub (Kt, f_jnq, f_x);
+ if (mpf_cmp (Kt, Kp) > 0)
+ mpf_set (Kp, Kt);
+ if (g_debug > DEBUG_2)
+ {
+ printf ("j=%lu ", j);
+ printf ("P()="); mpf_out_str (stdout, 10, 2, f_x); printf ("\t");
+
+ printf ("jnq="); mpf_out_str (stdout, 10, 2, f_jnq); printf (" ");
+ printf ("diff="); mpf_out_str (stdout, 10, 2, Kt); printf (" ");
+ printf ("Kp="); mpf_out_str (stdout, 10, 2, Kp); printf ("\t");
+ }
+ mpf_sub_ui (f_j, f_j, 1);
+ mpf_div_ui (f_jnq, f_j, n);
+ mpf_sub (Kt, f_x, f_jnq);
+ if (mpf_cmp (Kt, Km) > 0)
+ mpf_set (Km, Kt);
+
+ if (g_debug > DEBUG_2)
+ {
+ printf ("jnq="); mpf_out_str (stdout, 10, 2, f_jnq); printf (" ");
+ printf ("diff="); mpf_out_str (stdout, 10, 2, Kt); printf (" ");
+ printf ("Km="); mpf_out_str (stdout, 10, 2, Km); printf (" ");
+ printf ("\n");
+ }
+ }
+ mpf_sqrt_ui (Kt, n);
+ mpf_mul (Kp, Kp, Kt);
+ mpf_mul (Km, Km, Kt);
+
+ mpf_clear (Kt); mpf_clear (f_x); mpf_clear (f_j); mpf_clear (f_jnq);
+}
+
+/* ks_table(val, n) -- calculate probability for Kp/Km less than or
+ equal to VAL with N observations. See [Knuth section 3.3.1] */
+
+void
+ks_table (mpf_t p, mpf_t val, const unsigned int n)
+{
+ /* We use Eq. (27), Knuth p.58, skipping O(1/n) for simplicity.
+ This shortcut will result in too high probabilities, especially
+ when n is small.
+
+ Pr(Kp(n) <= s) = 1 - pow(e, -2*s^2) * (1 - 2/3*s/sqrt(n) + O(1/n)) */
+
+ /* We have 's' in variable VAL and store the result in P. */
+
+ mpf_t t1, t2;
+
+ mpf_init (t1); mpf_init (t2);
+
+ /* t1 = 1 - 2/3 * s/sqrt(n) */
+ mpf_sqrt_ui (t1, n);
+ mpf_div (t1, val, t1);
+ mpf_mul_ui (t1, t1, 2);
+ mpf_div_ui (t1, t1, 3);
+ mpf_ui_sub (t1, 1, t1);
+
+ /* t2 = pow(e, -2*s^2) */
+#ifndef OLDGMP
+ mpf_pow_ui (t2, val, 2); /* t2 = s^2 */
+ mpf_set_d (t2, exp (-(2.0 * mpf_get_d (t2))));
+#else
+ /* hmmm, gmp doesn't have pow() for floats. use doubles. */
+ mpf_set_d (t2, pow (M_E, -(2 * pow (mpf_get_d (val), 2))));
+#endif
+
+ /* p = 1 - t1 * t2 */
+ mpf_mul (t1, t1, t2);
+ mpf_ui_sub (p, 1, t1);
+
+ mpf_clear (t1); mpf_clear (t2);
+}
+
+static double x2_table_X[][7] = {
+ { -2.33, -1.64, -.674, 0.0, 0.674, 1.64, 2.33 }, /* x */
+ { 5.4289, 2.6896, .454276, 0.0, .454276, 2.6896, 5.4289} /* x^2 */
+};
+
+#define _2D3 ((double) .6666666666)
+
+/* x2_table (t, v, n) -- return chi-square table row for V in T[]. */
+void
+x2_table (double t[],
+ unsigned int v)
+{
+ int f;
+
+
+ /* FIXME: Do a table lookup for v <= 30 since the following formula
+ [Knuth, vol 2, 3.3.1] is only good for v > 30. */
+
+ /* value = v + sqrt(2*v) * X[p] + (2/3) * X[p]^2 - 2/3 + O(1/sqrt(t) */
+ /* NOTE: The O() term is ignored for simplicity. */
+
+ for (f = 0; f < 7; f++)
+ t[f] =
+ v +
+ sqrt (2 * v) * x2_table_X[0][f] +
+ _2D3 * x2_table_X[1][f] - _2D3;
+}
+
+
+/* P(p, x) -- Distribution function. Calculate the probability of X
+being greater than or equal to any number in the sequence. For a
+random real number between zero and one given by a uniformly
+distributed random number generator, this is simply equal to X. */
+
+static void
+P (mpf_t p, mpf_t x)
+{
+ mpf_set (p, x);
+}
+
+/* mpf_freqt() -- Frequency test using KS on N real numbers between zero
+ and one. See [Knuth vol 2, p.61]. */
+void
+mpf_freqt (mpf_t Kp,
+ mpf_t Km,
+ mpf_t X[],
+ const unsigned long int n)
+{
+ ks (Kp, Km, X, P, n);
+}
+
+
+/* The Chi-square test. Eq. (8) in Knuth vol. 2 says that if Y[]
+ holds the observations and p[] is the probability for.. (to be
+ continued!)
+
+ V = 1/n * sum((s=1 to k) Y[s]^2 / p[s]) - n */
+
+void
+x2 (mpf_t V, /* result */
+ unsigned long int X[], /* data */
+ unsigned int k, /* #of categories */
+ void (P) (mpf_t, unsigned long int, void *), /* probability func */
+ void *x, /* extra user data passed to P() */
+ unsigned long int n) /* #of samples */
+{
+ unsigned int f;
+ mpf_t f_t, f_t2; /* temp floats */
+
+ mpf_init (f_t); mpf_init (f_t2);
+
+
+ mpf_set_ui (V, 0);
+ for (f = 0; f < k; f++)
+ {
+ if (g_debug > DEBUG_2)
+ fprintf (stderr, "%u: P()=", f);
+ mpf_set_ui (f_t, X[f]);
+ mpf_mul (f_t, f_t, f_t); /* f_t = X[f]^2 */
+ P (f_t2, f, x); /* f_t2 = Pr(f) */
+ if (g_debug > DEBUG_2)
+ mpf_out_str (stderr, 10, 2, f_t2);
+ mpf_div (f_t, f_t, f_t2);
+ mpf_add (V, V, f_t);
+ if (g_debug > DEBUG_2)
+ {
+ fprintf (stderr, "\tV=");
+ mpf_out_str (stderr, 10, 2, V);
+ fprintf (stderr, "\t");
+ }
+ }
+ if (g_debug > DEBUG_2)
+ fprintf (stderr, "\n");
+ mpf_div_ui (V, V, n);
+ mpf_sub_ui (V, V, n);
+
+ mpf_clear (f_t); mpf_clear (f_t2);
+}
+
+/* Pzf(p, s, x) -- Probability for category S in mpz_freqt(). It's
+ 1/d for all S. X is a pointer to an unsigned int holding 'd'. */
+static void
+Pzf (mpf_t p, unsigned long int s, void *x)
+{
+ mpf_set_ui (p, 1);
+ mpf_div_ui (p, p, *((unsigned int *) x));
+}
+
+/* mpz_freqt(V, X, imax, n) -- Frequency test on integers. [Knuth,
+ vol 2, 3.3.2]. Keep IMAX low on this one, since we loop from 0 to
+ IMAX. 128 or 256 could be nice.
+
+ X[] must not contain numbers outside the range 0 <= X <= IMAX.
+
+ Return value is number of observations actually used, after
+ discarding entries out of range.
+
+ Since X[] contains integers between zero and IMAX, inclusive, we
+ have IMAX+1 categories.
+
+ Note that N should be at least 5*IMAX. Result is put in V and can
+ be compared to output from x2_table (v=IMAX). */
+
+unsigned long int
+mpz_freqt (mpf_t V,
+ mpz_t X[],
+ unsigned int imax,
+ const unsigned long int n)
+{
+ unsigned long int *v; /* result */
+ unsigned int f;
+ unsigned int d; /* number of categories = imax+1 */
+ unsigned int uitemp;
+ unsigned long int usedn;
+
+
+ d = imax + 1;
+
+ v = (unsigned long int *) calloc (imax + 1, sizeof (unsigned long int));
+ if (NULL == v)
+ {
+ fprintf (stderr, "mpz_freqt(): out of memory\n");
+ exit (1);
+ }
+
+ /* count */
+ usedn = n; /* actual number of observations */
+ for (f = 0; f < n; f++)
+ {
+ uitemp = mpz_get_ui(X[f]);
+ if (uitemp > imax) /* sanity check */
+ {
+ if (g_debug)
+ fprintf (stderr, "mpz_freqt(): warning: input insanity: %u, "\
+ "ignored.\n", uitemp);
+ usedn--;
+ continue;
+ }
+ v[uitemp]++;
+ }
+
+ if (g_debug > DEBUG_2)
+ {
+ fprintf (stderr, "counts:\n");
+ for (f = 0; f <= imax; f++)
+ fprintf (stderr, "%u:\t%lu\n", f, v[f]);
+ }
+
+ /* chi-square with k=imax+1 and P(x)=1/(imax+1) for all x.*/
+ x2 (V, v, d, Pzf, (void *) &d, usedn);
+
+ free (v);
+ return (usedn);
+}
+
+/* debug dummy to drag in dump funcs */
+void
+foo_debug ()
+{
+ if (0)
+ {
+ mpf_dump (0);
+#ifndef OLDGMP
+ mpz_dump (0);
+#endif
+ }
+}
+
+/* merit (rop, t, v, m) -- calculate merit for spectral test result in
+ dimension T, see Knuth p. 105. BUGS: Only valid for 2 <= T <=
+ 6. */
+void
+merit (mpf_t rop, unsigned int t, mpf_t v, mpz_t m)
+{
+ int f;
+ mpf_t f_m, f_const, f_pi;
+
+ mpf_init (f_m);
+ mpf_set_z (f_m, m);
+ mpf_init_set_d (f_const, M_PI);
+ mpf_init_set_d (f_pi, M_PI);
+
+ switch (t)
+ {
+ case 2: /* PI */
+ break;
+ case 3: /* PI * 4/3 */
+ mpf_mul_ui (f_const, f_const, 4);
+ mpf_div_ui (f_const, f_const, 3);
+ break;
+ case 4: /* PI^2 * 1/2 */
+ mpf_mul (f_const, f_const, f_pi);
+ mpf_div_ui (f_const, f_const, 2);
+ break;
+ case 5: /* PI^2 * 8/15 */
+ mpf_mul (f_const, f_const, f_pi);
+ mpf_mul_ui (f_const, f_const, 8);
+ mpf_div_ui (f_const, f_const, 15);
+ break;
+ case 6: /* PI^3 * 1/6 */
+ mpf_mul (f_const, f_const, f_pi);
+ mpf_mul (f_const, f_const, f_pi);
+ mpf_div_ui (f_const, f_const, 6);
+ break;
+ default:
+ fprintf (stderr,
+ "spect (merit): can't calculate merit for dimensions > 6\n");
+ mpf_set_ui (f_const, 0);
+ break;
+ }
+
+ /* rop = v^t */
+ mpf_set (rop, v);
+ for (f = 1; f < t; f++)
+ mpf_mul (rop, rop, v);
+ mpf_mul (rop, rop, f_const);
+ mpf_div (rop, rop, f_m);
+
+ mpf_clear (f_m);
+ mpf_clear (f_const);
+ mpf_clear (f_pi);
+}
+
+double
+merit_u (unsigned int t, mpf_t v, mpz_t m)
+{
+ mpf_t rop;
+ double res;
+
+ mpf_init (rop);
+ merit (rop, t, v, m);
+ res = mpf_get_d (rop);
+ mpf_clear (rop);
+ return res;
+}
+
+/* f_floor (rop, op) -- Set rop = floor (op). */
+void
+f_floor (mpf_t rop, mpf_t op)
+{
+ mpz_t z;
+
+ mpz_init (z);
+
+ /* No mpf_floor(). Convert to mpz and back. */
+ mpz_set_f (z, op);
+ mpf_set_z (rop, z);
+
+ mpz_clear (z);
+}
+
+
+/* vz_dot (rop, v1, v2, nelem) -- compute dot product of z-vectors V1,
+ V2. N is number of elements in vectors V1 and V2. */
+
+void
+vz_dot (mpz_t rop, mpz_t V1[], mpz_t V2[], unsigned int n)
+{
+ mpz_t t;
+
+ mpz_init (t);
+ mpz_set_ui (rop, 0);
+ while (n--)
+ {
+ mpz_mul (t, V1[n], V2[n]);
+ mpz_add (rop, rop, t);
+ }
+
+ mpz_clear (t);
+}
+
+void
+spectral_test (mpf_t rop[], unsigned int T, mpz_t a, mpz_t m)
+{
+ /* Knuth "Seminumerical Algorithms, Third Edition", section 3.3.4
+ (pp. 101-103). */
+
+ /* v[t] = min { sqrt (x[1]^2 + ... + x[t]^2) |
+ x[1] + a*x[2] + ... + pow (a, t-1) * x[t] is congruent to 0 (mod m) } */
+
+
+ /* Variables. */
+ unsigned int ui_t;
+ unsigned int ui_i, ui_j, ui_k, ui_l;
+ mpf_t f_tmp1, f_tmp2;
+ mpz_t tmp1, tmp2, tmp3;
+ mpz_t U[GMP_SPECT_MAXT][GMP_SPECT_MAXT],
+ V[GMP_SPECT_MAXT][GMP_SPECT_MAXT],
+ X[GMP_SPECT_MAXT],
+ Y[GMP_SPECT_MAXT],
+ Z[GMP_SPECT_MAXT];
+ mpz_t h, hp, r, s, p, pp, q, u, v;
+
+ /* GMP inits. */
+ mpf_init (f_tmp1);
+ mpf_init (f_tmp2);
+ for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++)
+ {
+ for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++)
+ {
+ mpz_init_set_ui (U[ui_i][ui_j], 0);
+ mpz_init_set_ui (V[ui_i][ui_j], 0);
+ }
+ mpz_init_set_ui (X[ui_i], 0);
+ mpz_init_set_ui (Y[ui_i], 0);
+ mpz_init (Z[ui_i]);
+ }
+ mpz_init (tmp1);
+ mpz_init (tmp2);
+ mpz_init (tmp3);
+ mpz_init (h);
+ mpz_init (hp);
+ mpz_init (r);
+ mpz_init (s);
+ mpz_init (p);
+ mpz_init (pp);
+ mpz_init (q);
+ mpz_init (u);
+ mpz_init (v);
+
+ /* Implementation inits. */
+ if (T > GMP_SPECT_MAXT)
+ T = GMP_SPECT_MAXT; /* FIXME: Lazy. */
+
+ /* S1 [Initialize.] */
+ ui_t = 2 - 1; /* NOTE: `t' in description == ui_t + 1
+ for easy indexing */
+ mpz_set (h, a);
+ mpz_set (hp, m);
+ mpz_set_ui (p, 1);
+ mpz_set_ui (pp, 0);
+ mpz_set (r, a);
+ mpz_pow_ui (s, a, 2);
+ mpz_add_ui (s, s, 1); /* s = 1 + a^2 */
+
+ /* S2 [Euclidean step.] */
+ while (1)
+ {
+ if (g_debug > DEBUG_1)
+ {
+ mpz_mul (tmp1, h, pp);
+ mpz_mul (tmp2, hp, p);
+ mpz_sub (tmp1, tmp1, tmp2);
+ if (mpz_cmpabs (m, tmp1))
+ {
+ printf ("***BUG***: h*pp - hp*p = ");
+ mpz_out_str (stdout, 10, tmp1);
+ printf ("\n");
+ }
+ }
+ if (g_debug > DEBUG_2)
+ {
+ printf ("hp = ");
+ mpz_out_str (stdout, 10, hp);
+ printf ("\nh = ");
+ mpz_out_str (stdout, 10, h);
+ printf ("\n");
+ fflush (stdout);
+ }
+
+ if (mpz_sgn (h))
+ mpz_tdiv_q (q, hp, h); /* q = floor(hp/h) */
+ else
+ mpz_set_ui (q, 1);
+
+ if (g_debug > DEBUG_2)
+ {
+ printf ("q = ");
+ mpz_out_str (stdout, 10, q);
+ printf ("\n");
+ fflush (stdout);
+ }
+
+ mpz_mul (tmp1, q, h);
+ mpz_sub (u, hp, tmp1); /* u = hp - q*h */
+
+ mpz_mul (tmp1, q, p);
+ mpz_sub (v, pp, tmp1); /* v = pp - q*p */
+
+ mpz_pow_ui (tmp1, u, 2);
+ mpz_pow_ui (tmp2, v, 2);
+ mpz_add (tmp1, tmp1, tmp2);
+ if (mpz_cmp (tmp1, s) < 0)
+ {
+ mpz_set (s, tmp1); /* s = u^2 + v^2 */
+ mpz_set (hp, h); /* hp = h */
+ mpz_set (h, u); /* h = u */
+ mpz_set (pp, p); /* pp = p */
+ mpz_set (p, v); /* p = v */
+ }
+ else
+ break;
+ }
+
+ /* S3 [Compute v2.] */
+ mpz_sub (u, u, h);
+ mpz_sub (v, v, p);
+
+ mpz_pow_ui (tmp1, u, 2);
+ mpz_pow_ui (tmp2, v, 2);
+ mpz_add (tmp1, tmp1, tmp2);
+ if (mpz_cmp (tmp1, s) < 0)
+ {
+ mpz_set (s, tmp1); /* s = u^2 + v^2 */
+ mpz_set (hp, u);
+ mpz_set (pp, v);
+ }
+ mpf_set_z (f_tmp1, s);
+ mpf_sqrt (rop[ui_t - 1], f_tmp1);
+
+ /* S4 [Advance t.] */
+ mpz_neg (U[0][0], h);
+ mpz_set (U[0][1], p);
+ mpz_neg (U[1][0], hp);
+ mpz_set (U[1][1], pp);
+
+ mpz_set (V[0][0], pp);
+ mpz_set (V[0][1], hp);
+ mpz_neg (V[1][0], p);
+ mpz_neg (V[1][1], h);
+ if (mpz_cmp_ui (pp, 0) > 0)
+ {
+ mpz_neg (V[0][0], V[0][0]);
+ mpz_neg (V[0][1], V[0][1]);
+ mpz_neg (V[1][0], V[1][0]);
+ mpz_neg (V[1][1], V[1][1]);
+ }
+
+ while (ui_t + 1 != T) /* S4 loop */
+ {
+ ui_t++;
+ mpz_mul (r, a, r);
+ mpz_mod (r, r, m);
+
+ /* Add new row and column to U and V. They are initialized with
+ all elements set to zero, so clearing is not necessary. */
+
+ mpz_neg (U[ui_t][0], r); /* U: First col in new row. */
+ mpz_set_ui (U[ui_t][ui_t], 1); /* U: Last col in new row. */
+
+ mpz_set (V[ui_t][ui_t], m); /* V: Last col in new row. */
+
+ /* "Finally, for 1 <= i < t,
+ set q = round (vi1 * r / m),
+ vit = vi1*r - q*m,
+ and Ut=Ut+q*Ui */
+
+ for (ui_i = 0; ui_i < ui_t; ui_i++)
+ {
+ mpz_mul (tmp1, V[ui_i][0], r); /* tmp1=vi1*r */
+ zdiv_round (q, tmp1, m); /* q=round(vi1*r/m) */
+ mpz_mul (tmp2, q, m); /* tmp2=q*m */
+ mpz_sub (V[ui_i][ui_t], tmp1, tmp2);
+
+ for (ui_j = 0; ui_j <= ui_t; ui_j++) /* U[t] = U[t] + q*U[i] */
+ {
+ mpz_mul (tmp1, q, U[ui_i][ui_j]); /* tmp=q*uij */
+ mpz_add (U[ui_t][ui_j], U[ui_t][ui_j], tmp1); /* utj = utj + q*uij */
+ }
+ }
+
+ /* s = min (s, zdot (U[t], U[t]) */
+ vz_dot (tmp1, U[ui_t], U[ui_t], ui_t + 1);
+ if (mpz_cmp (tmp1, s) < 0)
+ mpz_set (s, tmp1);
+
+ ui_k = ui_t;
+ ui_j = 0; /* WARNING: ui_j no longer a temp. */
+
+ /* S5 [Transform.] */
+ if (g_debug > DEBUG_2)
+ printf ("(t, k, j, q1, q2, ...)\n");
+ do
+ {
+ if (g_debug > DEBUG_2)
+ printf ("(%u, %u, %u", ui_t + 1, ui_k + 1, ui_j + 1);
+
+ for (ui_i = 0; ui_i <= ui_t; ui_i++)
+ {
+ if (ui_i != ui_j)
+ {
+ vz_dot (tmp1, V[ui_i], V[ui_j], ui_t + 1); /* tmp1=dot(Vi,Vj). */
+ mpz_abs (tmp2, tmp1);
+ mpz_mul_ui (tmp2, tmp2, 2); /* tmp2 = 2*abs(dot(Vi,Vj) */
+ vz_dot (tmp3, V[ui_j], V[ui_j], ui_t + 1); /* tmp3=dot(Vj,Vj). */
+
+ if (mpz_cmp (tmp2, tmp3) > 0)
+ {
+ zdiv_round (q, tmp1, tmp3); /* q=round(Vi.Vj/Vj.Vj) */
+ if (g_debug > DEBUG_2)
+ {
+ printf (", ");
+ mpz_out_str (stdout, 10, q);
+ }
+
+ for (ui_l = 0; ui_l <= ui_t; ui_l++)
+ {
+ mpz_mul (tmp1, q, V[ui_j][ui_l]);
+ mpz_sub (V[ui_i][ui_l], V[ui_i][ui_l], tmp1); /* Vi=Vi-q*Vj */
+ mpz_mul (tmp1, q, U[ui_i][ui_l]);
+ mpz_add (U[ui_j][ui_l], U[ui_j][ui_l], tmp1); /* Uj=Uj+q*Ui */
+ }
+
+ vz_dot (tmp1, U[ui_j], U[ui_j], ui_t + 1); /* tmp1=dot(Uj,Uj) */
+ if (mpz_cmp (tmp1, s) < 0) /* s = min(s,dot(Uj,Uj)) */
+ mpz_set (s, tmp1);
+ ui_k = ui_j;
+ }
+ else if (g_debug > DEBUG_2)
+ printf (", #"); /* 2|Vi.Vj| <= Vj.Vj */
+ }
+ else if (g_debug > DEBUG_2)
+ printf (", *"); /* i == j */
+ }
+
+ if (g_debug > DEBUG_2)
+ printf (")\n");
+
+ /* S6 [Advance j.] */
+ if (ui_j == ui_t)
+ ui_j = 0;
+ else
+ ui_j++;
+ }
+ while (ui_j != ui_k); /* S5 */
+
+ /* From Knuth p. 104: "The exhaustive search in steps S8-S10
+ reduces the value of s only rarely." */
+#ifdef DO_SEARCH
+ /* S7 [Prepare for search.] */
+ /* Find minimum in (x[1], ..., x[t]) satisfying condition
+ x[k]^2 <= f(y[1], ...,y[t]) * dot(V[k],V[k]) */
+
+ ui_k = ui_t;
+ if (g_debug > DEBUG_2)
+ {
+ printf ("searching...");
+ /*for (f = 0; f < ui_t*/
+ fflush (stdout);
+ }
+
+ /* Z[i] = floor (sqrt (floor (dot(V[i],V[i]) * s / m^2))); */
+ mpz_pow_ui (tmp1, m, 2);
+ mpf_set_z (f_tmp1, tmp1);
+ mpf_set_z (f_tmp2, s);
+ mpf_div (f_tmp1, f_tmp2, f_tmp1); /* f_tmp1 = s/m^2 */
+ for (ui_i = 0; ui_i <= ui_t; ui_i++)
+ {
+ vz_dot (tmp1, V[ui_i], V[ui_i], ui_t + 1);
+ mpf_set_z (f_tmp2, tmp1);
+ mpf_mul (f_tmp2, f_tmp2, f_tmp1);
+ f_floor (f_tmp2, f_tmp2);
+ mpf_sqrt (f_tmp2, f_tmp2);
+ mpz_set_f (Z[ui_i], f_tmp2);
+ }
+
+ /* S8 [Advance X[k].] */
+ do
+ {
+ if (g_debug > DEBUG_2)
+ {
+ printf ("X[%u] = ", ui_k);
+ mpz_out_str (stdout, 10, X[ui_k]);
+ printf ("\tZ[%u] = ", ui_k);
+ mpz_out_str (stdout, 10, Z[ui_k]);
+ printf ("\n");
+ fflush (stdout);
+ }
+
+ if (mpz_cmp (X[ui_k], Z[ui_k]))
+ {
+ mpz_add_ui (X[ui_k], X[ui_k], 1);
+ for (ui_i = 0; ui_i <= ui_t; ui_i++)
+ mpz_add (Y[ui_i], Y[ui_i], U[ui_k][ui_i]);
+
+ /* S9 [Advance k.] */
+ while (++ui_k <= ui_t)
+ {
+ mpz_neg (X[ui_k], Z[ui_k]);
+ mpz_mul_ui (tmp1, Z[ui_k], 2);
+ for (ui_i = 0; ui_i <= ui_t; ui_i++)
+ {
+ mpz_mul (tmp2, tmp1, U[ui_k][ui_i]);
+ mpz_sub (Y[ui_i], Y[ui_i], tmp2);
+ }
+ }
+ vz_dot (tmp1, Y, Y, ui_t + 1);
+ if (mpz_cmp (tmp1, s) < 0)
+ mpz_set (s, tmp1);
+ }
+ }
+ while (--ui_k);
+#endif /* DO_SEARCH */
+ mpf_set_z (f_tmp1, s);
+ mpf_sqrt (rop[ui_t - 1], f_tmp1);
+#ifdef DO_SEARCH
+ if (g_debug > DEBUG_2)
+ printf ("done.\n");
+#endif /* DO_SEARCH */
+ } /* S4 loop */
+
+ /* Clear GMP variables. */
+
+ mpf_clear (f_tmp1);
+ mpf_clear (f_tmp2);
+ for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++)
+ {
+ for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++)
+ {
+ mpz_clear (U[ui_i][ui_j]);
+ mpz_clear (V[ui_i][ui_j]);
+ }
+ mpz_clear (X[ui_i]);
+ mpz_clear (Y[ui_i]);
+ mpz_clear (Z[ui_i]);
+ }
+ mpz_clear (tmp1);
+ mpz_clear (tmp2);
+ mpz_clear (tmp3);
+ mpz_clear (h);
+ mpz_clear (hp);
+ mpz_clear (r);
+ mpz_clear (s);
+ mpz_clear (p);
+ mpz_clear (pp);
+ mpz_clear (q);
+ mpz_clear (u);
+ mpz_clear (v);
+
+ return;
+}
diff --git a/gmp/tests/rand/t-iset.c b/gmp/tests/rand/t-iset.c
new file mode 100644
index 0000000000..0414037c19
--- /dev/null
+++ b/gmp/tests/rand/t-iset.c
@@ -0,0 +1,68 @@
+/* Test gmp_randinit_set.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* expect after a gmp_randinit_set that the new and old generators will
+ produce the same sequence of numbers */
+void
+check_one (const char *name, gmp_randstate_ptr src)
+{
+ gmp_randstate_t dst;
+ mpz_t sz, dz;
+ int i;
+
+ gmp_randinit_set (dst, src);
+ mpz_init (sz);
+ mpz_init (dz);
+
+ for (i = 0; i < 20; i++)
+ {
+ mpz_urandomb (sz, src, 123);
+ mpz_urandomb (dz, dst, 123);
+
+ if (mpz_cmp (sz, dz) != 0)
+ {
+ printf ("gmp_randinit_set didn't duplicate randstate\n");
+ printf (" algorithm: %s\n", name);
+ gmp_printf (" from src: %#Zx\n", sz);
+ gmp_printf (" from dst: %#Zx\n", dz);
+ abort ();
+ }
+ }
+
+ mpz_clear (sz);
+ mpz_clear (dz);
+ gmp_randclear (dst);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ call_rand_algs (check_one);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/rand/t-lc2exp.c b/gmp/tests/rand/t-lc2exp.c
new file mode 100644
index 0000000000..b524441f29
--- /dev/null
+++ b/gmp/tests/rand/t-lc2exp.c
@@ -0,0 +1,217 @@
+/* Exercise the lc2exp random functions.
+
+Copyright 2002, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* a=0 and c=0 produces zero results always. */
+void
+check_zero (unsigned long m2exp)
+{
+ gmp_randstate_t r;
+ mpz_t a;
+ unsigned long c;
+ int i;
+
+ mpz_init_set_ui (a, 0L);
+ c = 0L;
+
+ gmp_randinit_lc_2exp (r, a, c, m2exp);
+ gmp_randseed_ui (r, 0L);
+
+ for (i = 0; i < 5; i++)
+ {
+ mpz_urandomb (a, r, 123L);
+ if (mpz_sgn (a) != 0)
+ {
+ printf ("check_zero m2exp=%lu: didn't get zero\n", m2exp);
+ gmp_printf (" rand=%#Zx\n", a);
+ abort ();
+ }
+ }
+
+ mpz_clear (a);
+ gmp_randclear (r);
+}
+
+/* negative a */
+void
+check_nega (void)
+{
+ gmp_randstate_t r;
+ mpz_t a;
+ unsigned long c, m2exp;
+ int i;
+
+ mpz_init (a);
+ mpz_setbit (a, 1000L);
+ mpz_neg (a, a);
+ c = 0L;
+ m2exp = 45L;
+
+ gmp_randinit_lc_2exp (r, a, c, m2exp);
+ gmp_randseed_ui (r, 0L);
+
+ for (i = 0; i < 5; i++)
+ {
+ mpz_urandomb (a, r, 123L);
+ if (mpz_sgn (a) != 0)
+ printf ("check_nega m2exp=%lu: didn't get zero\n", m2exp);
+ }
+
+ mpz_clear (a);
+ gmp_randclear (r);
+}
+
+void
+check_bigc (void)
+{
+ gmp_randstate_t r;
+ mpz_t a;
+ unsigned long c, m2exp, bits;
+ int i;
+
+ mpz_init_set_ui (a, 0L);
+ c = ULONG_MAX;
+ m2exp = 8;
+
+ gmp_randinit_lc_2exp (r, a, c, m2exp);
+ gmp_randseed_ui (r, 0L);
+
+ for (i = 0; i < 20; i++)
+ {
+ bits = 123L;
+ mpz_urandomb (a, r, bits);
+ if (mpz_sgn (a) < 0 || mpz_sizeinbase (a, 2) > bits)
+ {
+ printf ("check_bigc: mpz_urandomb out of range\n");
+ printf (" m2exp=%lu\n", m2exp);
+ gmp_printf (" rand=%#ZX\n", a);
+ gmp_printf (" sizeinbase2=%u\n", mpz_sizeinbase (a, 2));
+ abort ();
+ }
+ }
+
+ mpz_clear (a);
+ gmp_randclear (r);
+}
+
+void
+check_bigc1 (void)
+{
+ gmp_randstate_t r;
+ mpz_t a;
+ unsigned long c, m2exp;
+ int i;
+
+ mpz_init_set_ui (a, 0L);
+ c = ULONG_MAX;
+ m2exp = 2;
+
+ gmp_randinit_lc_2exp (r, a, c, m2exp);
+ gmp_randseed_ui (r, 0L);
+
+ for (i = 0; i < 20; i++)
+ {
+ mpz_urandomb (a, r, 1L);
+ if (mpz_cmp_ui (a, 1L) != 0)
+ {
+ printf ("check_bigc1: mpz_urandomb didn't give 1\n");
+ printf (" m2exp=%lu\n", m2exp);
+ gmp_printf (" got rand=%#ZX\n", a);
+ abort ();
+ }
+ }
+
+ mpz_clear (a);
+ gmp_randclear (r);
+}
+
+/* Checks parameters which triggered an assertion failure in the past.
+ Happened when limbs(a)+limbs(c) < bits_to_limbs(m2exp). */
+void
+check_bigm (void)
+{
+ gmp_randstate_t rstate;
+ mpz_t a;
+
+ mpz_init_set_ui (a, 5L);
+ gmp_randinit_lc_2exp (rstate, a, 1L, 384L);
+
+ mpz_urandomb (a, rstate, 20L);
+
+ gmp_randclear (rstate);
+ mpz_clear (a);
+}
+
+/* Checks for seeds bigger than the modulus. */
+void
+check_bigs (void)
+{
+ gmp_randstate_t rstate;
+ mpz_t sd, a;
+ int i;
+
+ mpz_init (sd);
+ mpz_setbit (sd, 300L);
+ mpz_sub_ui (sd, sd, 1L);
+ mpz_clrbit (sd, 13L);
+ mpz_init_set_ui (a, 123456789L);
+
+ gmp_randinit_lc_2exp (rstate, a, 5L, 64L);
+
+ for (i = 0; i < 20; i++)
+ {
+ mpz_neg (sd, sd);
+ gmp_randseed (rstate, sd);
+ mpz_mul_ui (sd, sd, 7L);
+
+ mpz_urandomb (a, rstate, 80L);
+ }
+
+ gmp_randclear (rstate);
+ mpz_clear (a);
+ mpz_clear (sd);
+}
+
+int
+main (void)
+{
+ tests_start ();
+
+ check_zero (2L);
+ check_zero (7L);
+ check_zero (32L);
+ check_zero (64L);
+ check_zero (1000L);
+
+ check_nega ();
+ check_bigc ();
+ check_bigc1 ();
+
+ check_bigm ();
+ check_bigs ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/rand/t-mt.c b/gmp/tests/rand/t-mt.c
new file mode 100644
index 0000000000..3aabffe88d
--- /dev/null
+++ b/gmp/tests/rand/t-mt.c
@@ -0,0 +1,83 @@
+/* Test the Mersenne Twister random number generator.
+
+Copyright 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 <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+/* Test that the sequence without seeding equals the sequence with the
+ default seed. */
+int
+chk_default_seed (void)
+{
+ gmp_randstate_t r1, r2;
+ mpz_t a, b;
+ int i;
+ int ok = TRUE;
+
+ mpz_init2 (a, 19936L);
+ mpz_init2 (b, 19936L);
+
+ gmp_randinit_mt (r1);
+ gmp_randinit_mt (r2);
+ gmp_randseed_ui (r2, 5489L); /* Must match DEFAULT_SEED in randmt.c */
+ for (i = 0; i < 3; i++)
+ {
+ /* Extract one whole buffer per iteration. */
+ mpz_urandomb (a, r1, 19936L);
+ mpz_urandomb (b, r2, 19936L);
+ if (mpz_cmp (a, b) != 0)
+ {
+ ok = FALSE;
+ printf ("Default seed fails in iteration %d\n", i);
+ break;
+ }
+ }
+ gmp_randclear (r1);
+ gmp_randclear (r2);
+
+ mpz_clear (a);
+ mpz_clear (b);
+ return ok;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ok;
+
+ tests_start ();
+
+ ok = chk_default_seed ();
+
+ tests_end ();
+
+ if (ok)
+ return 0; /* pass */
+ else
+ return 1; /* fail */
+}
diff --git a/gmp/tests/rand/t-rand.c b/gmp/tests/rand/t-rand.c
new file mode 100644
index 0000000000..1265a0d0a5
--- /dev/null
+++ b/gmp/tests/rand/t-rand.c
@@ -0,0 +1,290 @@
+/* t-rand -- Test random number generators. */
+
+/*
+Copyright 2000, 2001 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 <stdlib.h>
+#include <stdio.h>
+#include "gmp.h"
+
+#define SEED 1
+#define BASE 16
+#define ENTS 10 /* Number of entries in array when
+ printing. */
+
+/* These were generated by this very program. Do not edit! */
+/* Integers. */
+const char *z1[ENTS] = {"0", "1", "1", "1", "1", "0", "1", "1", "1", "1"};
+const char *z2[ENTS] = {"0", "3", "1", "3", "3", "0", "3", "3", "3", "1"};
+const char *z3[ENTS] = {"4", "3", "1", "7", "3", "0", "3", "3", "3", "1"};
+const char *z4[ENTS] = {"c", "3", "1", "f", "b", "8", "3", "3", "3", "1"};
+const char *z5[ENTS] = {"1c", "13", "11", "1f", "b", "18", "3", "13", "3", "1"};
+
+const char *z10[ENTS] = {"29c", "213", "f1", "17f", "12b", "178", "383", "d3", "3a3", "281"};
+
+const char *z15[ENTS] = {"29c", "1a13", "74f1", "257f", "592b", "4978", "4783", "7cd3", "5ba3", "4681"};
+const char *z16[ENTS] = {"29c", "9a13", "74f1", "a57f", "d92b", "4978", "c783", "fcd3", "5ba3", "c681"};
+const char *z17[ENTS] = {"51e", "f17a", "54ff", "1a335", "cf65", "5d6f", "583f", "618f", "1bc6", "98ff"};
+
+const char *z31[ENTS] = {"3aecd515", "13ae8ec6", "518c8090", "81ca077", "70b7134", "7ee78d71", "323a7636", "2122cb1a", "19811941", "41fd605"};
+const char *z32[ENTS] = {"baecd515", "13ae8ec6", "518c8090", "881ca077", "870b7134", "7ee78d71", "323a7636", "a122cb1a", "99811941", "841fd605"};
+const char *z33[ENTS] = {"1faf4cca", "15d6ef83b", "9095fe72", "1b6a3dff6", "b17cbddd", "16e5209d4", "6f65b12c", "493bbbc6", "abf2a5d5", "6d491a3c"};
+
+const char *z63[ENTS] = {"48a74f367fa7b5c8", "3ba9e9dc1b263076", "1e0ac84e7678e0fb", "11416581728b3e35", "36ab610523f0f1f7", "3e540e8e95c0eb4b", "439ae16057dbc9d3", "734fb260db243950", "7d3a317effc289bf", "1d80301fb3d1a0d1"};
+const char *z64[ENTS] = {"48a74f367fa7b5c8", "bba9e9dc1b263076", "9e0ac84e7678e0fb", "11416581728b3e35", "b6ab610523f0f1f7", "be540e8e95c0eb4b", "439ae16057dbc9d3", "f34fb260db243950", "fd3a317effc289bf", "1d80301fb3d1a0d1"};
+const char *z65[ENTS] = {"1ff77710d846d49f0", "1b1411701d709ee10", "31ffa81a208b6af4", "446638d431d3c681", "df5c569d5baa8b55", "197d99ea9bf28e5a0", "191ade09edd94cfae", "194acefa6dde5e18d", "1afc1167c56272d92", "d092994da72f206f"};
+
+const char *z127[ENTS] = {"2f66ba932aaf58a071fd8f0742a99a0c", "73cfa3c664c9c1753507ca60ec6b8425", "53ea074ca131dec12cd68b8aa8e20278", "3cf5ac8c343532f8a53cc0eb47581f73", "50c11d5869e208aa1b9aa317b8c2d0a9", "b23163c892876472b1ef19642eace09", "489f4c03d41f87509c8d6c90ce674f95", "2ab8748c96aa6762ea1932b44c9d7164", "98cb5591fc05ad31afbbc1d67b90edd", "77848bb991fd0be331adcf1457fbc672"};
+const char *z128[ENTS] = {"af66ba932aaf58a071fd8f0742a99a0c", "73cfa3c664c9c1753507ca60ec6b8425", "53ea074ca131dec12cd68b8aa8e20278", "3cf5ac8c343532f8a53cc0eb47581f73", "50c11d5869e208aa1b9aa317b8c2d0a9", "8b23163c892876472b1ef19642eace09", "489f4c03d41f87509c8d6c90ce674f95", "aab8748c96aa6762ea1932b44c9d7164", "98cb5591fc05ad31afbbc1d67b90edd", "f7848bb991fd0be331adcf1457fbc672"};
+
+/* Floats. */
+const char *f1[ENTS] = {"0.@0", "0.8@0", "0.8@0", "0.8@0", "0.8@0", "0.@0", "0.8@0", "0.8@0", "0.8@0", "0.8@0"};
+const char *f2[ENTS] = {"0.@0", "0.c@0", "0.4@0", "0.c@0", "0.c@0", "0.@0", "0.c@0", "0.c@0", "0.c@0", "0.4@0"};
+const char *f3[ENTS] = {"0.8@0", "0.6@0", "0.2@0", "0.e@0", "0.6@0", "0.@0", "0.6@0", "0.6@0", "0.6@0", "0.2@0"};
+const char *f4[ENTS] = {"0.c@0", "0.3@0", "0.1@0", "0.f@0", "0.b@0", "0.8@0", "0.3@0", "0.3@0", "0.3@0", "0.1@0"};
+const char *f5[ENTS] = {"0.e@0", "0.98@0", "0.88@0", "0.f8@0", "0.58@0", "0.c@0", "0.18@0", "0.98@0", "0.18@0", "0.8@-1"};
+
+const char *f10[ENTS] = {"0.a7@0", "0.84c@0", "0.3c4@0", "0.5fc@0", "0.4ac@0", "0.5e@0", "0.e0c@0", "0.34c@0", "0.e8c@0", "0.a04@0"};
+
+const char *f15[ENTS] = {"0.538@-1", "0.3426@0", "0.e9e2@0", "0.4afe@0", "0.b256@0", "0.92f@0", "0.8f06@0", "0.f9a6@0", "0.b746@0", "0.8d02@0"};
+const char *f16[ENTS] = {"0.29c@-1", "0.9a13@0", "0.74f1@0", "0.a57f@0", "0.d92b@0", "0.4978@0", "0.c783@0", "0.fcd3@0", "0.5ba3@0", "0.c681@0"};
+const char *f17[ENTS] = {"0.28f@-1", "0.78bd@0", "0.2a7f8@0", "0.d19a8@0", "0.67b28@0", "0.2eb78@0", "0.2c1f8@0", "0.30c78@0", "0.de3@-1", "0.4c7f8@0"};
+
+const char *f31[ENTS] = {"0.75d9aa2a@0", "0.275d1d8c@0", "0.a319012@0", "0.103940ee@0", "0.e16e268@-1", "0.fdcf1ae2@0", "0.6474ec6c@0", "0.42459634@0", "0.33023282@0", "0.83fac0a@-1"};
+const char *f32[ENTS] = {"0.baecd515@0", "0.13ae8ec6@0", "0.518c809@0", "0.881ca077@0", "0.870b7134@0", "0.7ee78d71@0", "0.323a7636@0", "0.a122cb1a@0", "0.99811941@0", "0.841fd605@0"};
+const char *f33[ENTS] = {"0.fd7a665@-1", "0.aeb77c1d8@0", "0.484aff39@0", "0.db51effb@0", "0.58be5eee8@0", "0.b72904ea@0", "0.37b2d896@0", "0.249ddde3@0", "0.55f952ea8@0", "0.36a48d1e@0"};
+
+const char *f63[ENTS] = {"0.914e9e6cff4f6b9@0", "0.7753d3b8364c60ec@0", "0.3c15909cecf1c1f6@0", "0.2282cb02e5167c6a@0", "0.6d56c20a47e1e3ee@0", "0.7ca81d1d2b81d696@0", "0.8735c2c0afb793a6@0", "0.e69f64c1b64872a@0", "0.fa7462fdff85137e@0", "0.3b00603f67a341a2@0"};
+const char *f64[ENTS] = {"0.48a74f367fa7b5c8@0", "0.bba9e9dc1b263076@0", "0.9e0ac84e7678e0fb@0", "0.11416581728b3e35@0", "0.b6ab610523f0f1f7@0", "0.be540e8e95c0eb4b@0", "0.439ae16057dbc9d3@0", "0.f34fb260db24395@0", "0.fd3a317effc289bf@0", "0.1d80301fb3d1a0d1@0"};
+const char *f65[ENTS] = {"0.ffbbb886c236a4f8@0", "0.d8a08b80eb84f708@0", "0.18ffd40d1045b57a@0", "0.22331c6a18e9e3408@0", "0.6fae2b4eadd545aa8@0", "0.cbeccf54df9472d@0", "0.c8d6f04f6eca67d7@0", "0.ca5677d36ef2f0c68@0", "0.d7e08b3e2b1396c9@0", "0.68494ca6d39790378@0"};
+
+const char *f127[ENTS] = {"0.5ecd7526555eb140e3fb1e0e85533418@0", "0.e79f478cc99382ea6a0f94c1d8d7084a@0", "0.a7d40e994263bd8259ad171551c404f@0", "0.79eb5918686a65f14a7981d68eb03ee6@0", "0.a1823ab0d3c411543735462f7185a152@0", "0.16462c791250ec8e563de32c85d59c12@0", "0.913e9807a83f0ea1391ad9219cce9f2a@0", "0.5570e9192d54cec5d4326568993ae2c8@0", "0.13196ab23f80b5a635f7783acf721dba@0", "0.ef09177323fa17c6635b9e28aff78ce4@0"};
+const char *f128[ENTS] = {"0.af66ba932aaf58a071fd8f0742a99a0c@0", "0.73cfa3c664c9c1753507ca60ec6b8425@0", "0.53ea074ca131dec12cd68b8aa8e20278@0", "0.3cf5ac8c343532f8a53cc0eb47581f73@0", "0.50c11d5869e208aa1b9aa317b8c2d0a9@0", "0.8b23163c892876472b1ef19642eace09@0", "0.489f4c03d41f87509c8d6c90ce674f95@0", "0.aab8748c96aa6762ea1932b44c9d7164@0", "0.98cb5591fc05ad31afbbc1d67b90edd@-1", "0.f7848bb991fd0be331adcf1457fbc672@0"};
+
+
+struct rt
+{
+ const char **s;
+ int nbits;
+};
+
+static struct rt zarr[] =
+{
+ {z1, 1},
+ {z2, 2},
+ {z3, 3},
+ {z4, 4},
+ {z5, 5},
+ {z10, 10},
+ {z15, 15},
+ {z16, 16},
+ {z17, 17},
+ {z31, 31},
+ {z32, 32},
+ {z33, 33},
+ {z63, 63},
+ {z64, 64},
+ {z65, 65},
+ {z127, 127},
+ {z128, 128},
+ {NULL, 0}
+};
+
+static struct rt farr[] =
+{
+ {f1, 1},
+ {f2, 2},
+ {f3, 3},
+ {f4, 4},
+ {f5, 5},
+ {f10, 10},
+ {f15, 15},
+ {f16, 16},
+ {f17, 17},
+ {f31, 31},
+ {f32, 32},
+ {f33, 33},
+ {f63, 63},
+ {f64, 64},
+ {f65, 65},
+ {f127, 127},
+ {f128, 128},
+ {NULL, 0}
+};
+
+
+int
+main (int argc, char *argv[])
+{
+ static char usage[] = "\
+usage: t-rand [function nbits]\n\
+ function is one of z, f\n\
+ nbits is number of bits\n\
+";
+ gmp_randstate_t rstate;
+ mpz_t z, rz;
+ mpf_t f, rf;
+ enum { Z, F } func = Z;
+ int nbits = 1;
+ int verify_mode_flag = 1;
+ int i;
+ struct rt *a;
+
+
+ if (argc > 1)
+ {
+ if (argc < 3)
+ {
+ fputs (usage, stderr);
+ exit (1);
+ }
+ verify_mode_flag = 0;
+ if (*argv[1] == 'z')
+ func = Z;
+ if (*argv[1] == 'f')
+ func = F;
+ nbits = atoi (argv[2]);
+ }
+
+ mpz_init (rz);
+
+ if (verify_mode_flag)
+ {
+#ifdef VERBOSE
+ printf ("%s: verifying random numbers: ", argv[0]);
+#endif
+
+ /* Test z. */
+ mpz_init (z);
+ for (a = zarr; a->s != NULL; a++)
+ {
+ gmp_randinit (rstate, GMP_RAND_ALG_LC, a->nbits);
+ if (gmp_errno != GMP_ERROR_NONE)
+ exit (1);
+ gmp_randseed_ui (rstate, SEED);
+
+ for (i = 0; i < ENTS; i++)
+ {
+ mpz_urandomb (rz, rstate, a->nbits);
+ mpz_set_str (z, a->s[i], BASE);
+ if (mpz_cmp (z, rz) != 0)
+ {
+ printf ("z%d: ", a->nbits);
+ mpz_out_str (stdout, BASE, rz);
+ printf (" should be ");
+ mpz_out_str (stdout, BASE, z);
+ puts ("");
+ exit (1);
+ }
+ }
+#ifdef VERBOSE
+ printf ("z%d ", a->nbits);
+#endif
+ gmp_randclear (rstate);
+ }
+ mpz_clear (z);
+
+
+ /* Test f. */
+ for (a = farr; a->s != NULL; a++)
+ {
+ gmp_randinit (rstate, GMP_RAND_ALG_LC, a->nbits);
+ if (gmp_errno != GMP_ERROR_NONE)
+ exit (1);
+ gmp_randseed_ui (rstate, SEED);
+
+ mpf_init2 (f, a->nbits);
+ mpf_init2 (rf, a->nbits);
+ for (i = 0; i < ENTS; i++)
+ {
+ mpf_urandomb (rf, rstate, a->nbits);
+ mpf_set_str (f, a->s[i], BASE);
+ if (mpf_cmp (f, rf) != 0)
+ {
+ printf ("f%d: ", a->nbits);
+ mpf_out_str (stdout, BASE, a->nbits, rf);
+ printf (" should be ");
+ mpf_out_str (stdout, BASE, a->nbits, f);
+ puts ("");
+ exit (1);
+ }
+ }
+#ifdef VERBOSE
+ printf ("f%d ", a->nbits);
+#endif
+ gmp_randclear (rstate);
+ mpf_clear (f);
+ mpf_clear (rf);
+ }
+
+#ifdef VERBOSE
+ puts ("");
+#endif
+ }
+ else /* Print mode. */
+ {
+ gmp_randinit (rstate, GMP_RAND_ALG_LC, nbits);
+ if (gmp_errno != GMP_ERROR_NONE)
+ exit (1);
+ gmp_randseed_ui (rstate, SEED);
+
+ switch (func)
+ {
+ case Z:
+ printf ("char *z%d[ENTS] = {", nbits);
+ for (i = 0; i < ENTS; i++)
+ {
+ mpz_urandomb (rz, rstate, nbits);
+ printf ("\"");
+ mpz_out_str (stdout, BASE, rz);
+ printf ("\"");
+ if (i != ENTS - 1)
+ printf (", ");
+ }
+ printf ("};\n");
+ printf (" {z%d, %d},\n", nbits, nbits);
+ break;
+
+ case F:
+ printf ("char *f%d[ENTS] = {", nbits);
+ mpf_init2 (rf, nbits);
+ for (i = 0; i < ENTS; i++)
+ {
+ mpf_urandomb (rf, rstate, nbits);
+ printf ("\"");
+ mpf_out_str (stdout, BASE, nbits, rf);
+ printf ("\"");
+ if (i != ENTS - 1)
+ printf (", ");
+ }
+ printf ("};\n");
+ printf (" {f%d, %d},\n", nbits, nbits);
+ mpf_clear (rf);
+ break;
+
+ default:
+ exit (1);
+ }
+
+ gmp_randclear (rstate);
+ }
+
+ mpz_clear (rz);
+
+ return 0;
+}
diff --git a/gmp/tests/rand/t-urbui.c b/gmp/tests/rand/t-urbui.c
new file mode 100644
index 0000000000..bac8b6d5a0
--- /dev/null
+++ b/gmp/tests/rand/t-urbui.c
@@ -0,0 +1,65 @@
+/* Test gmp_urandomb_ui.
+
+Copyright 2003, 2005 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Expect numbers generated by rstate to obey the number of bits requested.
+ No point testing bits==BITS_PER_ULONG, since any return is acceptable in
+ that case. */
+void
+check_one (const char *name, gmp_randstate_ptr rstate)
+{
+ unsigned long bits, limit, got;
+ int i;
+
+ for (bits = 0; bits < BITS_PER_ULONG; bits++)
+ {
+ /* will demand got < limit */
+ limit = (1UL << bits);
+
+ for (i = 0; i < 5; i++)
+ {
+ got = gmp_urandomb_ui (rstate, bits);
+ if (got >= limit)
+ {
+ printf ("Return value out of range:\n");
+ printf (" algorithm: %s\n", name);
+ printf (" bits: %lu\n", bits);
+ printf (" limit: %#lx\n", limit);
+ printf (" got: %#lx\n", got);
+ abort ();
+ }
+ }
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ call_rand_algs (check_one);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/rand/t-urmui.c b/gmp/tests/rand/t-urmui.c
new file mode 100644
index 0000000000..c58d740f4e
--- /dev/null
+++ b/gmp/tests/rand/t-urmui.c
@@ -0,0 +1,75 @@
+/* Test gmp_urandomm_ui.
+
+Copyright 2003, 2005 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+/* Expect numbers generated by rstate to obey the limit requested. */
+void
+check_one (const char *name, gmp_randstate_ptr rstate)
+{
+ static const unsigned long n_table[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 123, 456, 789,
+
+ 255, 256, 257,
+ 1023, 1024, 1025,
+ 32767, 32768, 32769,
+
+ ULONG_MAX/2-2, ULONG_MAX/2-1, ULONG_MAX/2, ULONG_MAX/2+1, ULONG_MAX/2+2,
+
+ ULONG_MAX-2, ULONG_MAX-1, ULONG_MAX,
+ };
+
+ unsigned long got, n;
+ int i, j;
+
+ for (i = 0; i < numberof (n_table); i++)
+ {
+ n = n_table[i];
+
+ for (j = 0; j < 5; j++)
+ {
+ got = gmp_urandomm_ui (rstate, n);
+ if (got >= n)
+ {
+ printf ("Return value out of range:\n");
+ printf (" algorithm: %s\n", name);
+ printf (" n: %#lx\n", n);
+ printf (" got: %#lx\n", got);
+ abort ();
+ }
+ }
+ }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ call_rand_algs (check_one);
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/rand/t-urndmm.c b/gmp/tests/rand/t-urndmm.c
new file mode 100644
index 0000000000..d5a9217b40
--- /dev/null
+++ b/gmp/tests/rand/t-urndmm.c
@@ -0,0 +1,159 @@
+/* Test mpz_urandomm.
+
+Copyright 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 <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+int
+check_params (void)
+{
+ gmp_randstate_t r1, r2;
+ mpz_t a, b, m;
+ int i;
+ int result;
+
+ result = TRUE;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (m);
+
+ if (result)
+ {
+ /* Test the consistency between urandomm and urandomb. */
+ gmp_randinit_default (r1);
+ gmp_randinit_default (r2);
+ gmp_randseed_ui (r1, 85L);
+ gmp_randseed_ui (r2, 85L);
+ mpz_set_ui (m, 0L);
+ mpz_setbit (m, 80L);
+ for (i = 0; i < 100; i++)
+ {
+ mpz_urandomm (a, r1, m);
+ mpz_urandomb (b, r2, 80L);
+ if (mpz_cmp (a, b) != 0)
+ {
+ result = FALSE;
+ printf ("mpz_urandomm != mpz_urandomb\n");
+ break;
+ }
+ }
+ gmp_randclear (r1);
+ gmp_randclear (r2);
+ }
+
+ if (result)
+ {
+ /* Test that mpz_urandomm returns the correct result with a
+ broken LC. */
+ mpz_set_ui (a, 0L);
+ gmp_randinit_lc_2exp (r1, a, 0xffL, 8L);
+ mpz_set_ui (m, 5L);
+ /* Warning: This code hangs in gmp 4.1 and below */
+ for (i = 0; i < 100; i++)
+ {
+ mpz_urandomm (a, r1, m);
+ if (mpz_cmp_ui (a, 2L) != 0)
+ {
+ result = FALSE;
+ gmp_printf ("mpz_urandomm returns %Zd instead of 2\n", a);
+ break;
+ }
+ }
+ gmp_randclear (r1);
+ }
+
+ if (result)
+ {
+ /* Test that the results are always in range for either
+ positive or negative values of m. */
+ gmp_randinit_default (r1);
+ mpz_set_ui (m, 5L);
+ mpz_set_si (b, -5L);
+ for (i = 0; i < 100; i++)
+ {
+ mpz_urandomm (a, r1, m);
+ if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0)
+ {
+ result = FALSE;
+ gmp_printf ("Out-of-range or non-positive value: %Zd\n", a);
+ break;
+ }
+ mpz_urandomm (a, r1, b);
+ if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0)
+ {
+ result = FALSE;
+ gmp_printf ("Out-of-range or non-positive value (from negative modulus): %Zd\n", a);
+ break;
+ }
+ }
+ gmp_randclear (r1);
+ }
+
+ if (result)
+ {
+ /* Test that m=1 forces always result=0. */
+ gmp_randinit_default (r1);
+ mpz_set_ui (m, 1L);
+ for (i = 0; i < 100; i++)
+ {
+ mpz_urandomm (a, r1, m);
+ if (mpz_sgn (a) != 0)
+ {
+ result = FALSE;
+ gmp_printf ("mpz_urandomm fails with m=1 (result=%Zd)\n", a);
+ break;
+ }
+ }
+ gmp_randclear (r1);
+ }
+
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (m);
+ return result;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int result = TRUE;
+
+ tests_start ();
+
+ if (result)
+ if (!check_params ())
+ result = FALSE;
+
+ tests_end ();
+
+ if (result)
+ return 0; /* pass */
+ else
+ return 1; /* fail */
+}
diff --git a/gmp/tests/rand/zdiv_round.c b/gmp/tests/rand/zdiv_round.c
new file mode 100644
index 0000000000..3a91e3092c
--- /dev/null
+++ b/gmp/tests/rand/zdiv_round.c
@@ -0,0 +1,44 @@
+/* zdiv_round() -- divide integers, round to nearest */
+
+/*
+Copyright 1999 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 "gmp.h"
+
+void
+zdiv_round (mpz_t rop, mpz_t n, mpz_t d)
+{
+ mpf_t f_n, f_d;
+
+ mpf_init (f_n);
+ mpf_init (f_d);
+
+ mpf_set_z (f_d, d);
+ mpf_set_z (f_n, n);
+
+ mpf_div (f_n, f_n, f_d);
+ mpf_set_d (f_d, .5);
+ if (mpf_sgn (f_n) < 0)
+ mpf_neg (f_d, f_d);
+ mpf_add (f_n, f_n, f_d);
+ mpz_set_f (rop, f_n);
+
+ mpf_clear (f_n);
+ mpf_clear (f_d);
+ return;
+}
diff --git a/gmp/tests/refmpf.c b/gmp/tests/refmpf.c
new file mode 100644
index 0000000000..0ba9fbca3a
--- /dev/null
+++ b/gmp/tests/refmpf.c
@@ -0,0 +1,428 @@
+/* Reference floating point routines.
+
+Copyright 1996, 2001, 2004, 2005 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+refmpf_add (mpf_ptr w, mpf_srcptr u, mpf_srcptr v)
+{
+ mp_size_t hi, lo, size;
+ mp_ptr ut, vt, wt;
+ int neg;
+ mp_exp_t exp;
+ mp_limb_t cy;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ if (SIZ (u) == 0)
+ {
+ size = ABSIZ (v);
+ wt = TMP_ALLOC_LIMBS (size + 1);
+ MPN_COPY (wt, PTR (v), size);
+ exp = EXP (v);
+ neg = SIZ (v) < 0;
+ goto done;
+ }
+ if (SIZ (v) == 0)
+ {
+ size = ABSIZ (u);
+ wt = TMP_ALLOC_LIMBS (size + 1);
+ MPN_COPY (wt, PTR (u), size);
+ exp = EXP (u);
+ neg = SIZ (u) < 0;
+ goto done;
+ }
+ if ((SIZ (u) ^ SIZ (v)) < 0)
+ {
+ mpf_t tmp;
+ SIZ (tmp) = -SIZ (v);
+ EXP (tmp) = EXP (v);
+ PTR (tmp) = PTR (v);
+ refmpf_sub (w, u, tmp);
+ return;
+ }
+ neg = SIZ (u) < 0;
+
+ /* Compute the significance of the hi and lo end of the result. */
+ hi = MAX (EXP (u), EXP (v));
+ lo = MIN (EXP (u) - ABSIZ (u), EXP (v) - ABSIZ (v));
+ size = hi - lo;
+ ut = TMP_ALLOC_LIMBS (size + 1);
+ vt = TMP_ALLOC_LIMBS (size + 1);
+ wt = TMP_ALLOC_LIMBS (size + 1);
+ MPN_ZERO (ut, size);
+ MPN_ZERO (vt, size);
+ {int off;
+ off = size + (EXP (u) - hi) - ABSIZ (u);
+ MPN_COPY (ut + off, PTR (u), ABSIZ (u));
+ off = size + (EXP (v) - hi) - ABSIZ (v);
+ MPN_COPY (vt + off, PTR (v), ABSIZ (v));
+ }
+
+ cy = mpn_add_n (wt, ut, vt, size);
+ wt[size] = cy;
+ size += cy;
+ exp = hi + cy;
+
+done:
+ if (size > PREC (w))
+ {
+ wt += size - PREC (w);
+ size = PREC (w);
+ }
+ MPN_COPY (PTR (w), wt, size);
+ SIZ (w) = neg == 0 ? size : -size;
+ EXP (w) = exp;
+ TMP_FREE;
+}
+
+
+/* Add 1 "unit in last place" (ie. in the least significant limb) to f.
+ f cannot be zero, since that has no well-defined "last place".
+
+ This routine is designed for use in cases where we pay close attention to
+ the size of the data value and are using that (and the exponent) to
+ indicate the accurate part of a result, or similar. For this reason, if
+ there's a carry out we don't store 1 and adjust the exponent, we just
+ leave 100..00. We don't even adjust if there's a carry out of prec+1
+ limbs, but instead give up in that case (which we intend shouldn't arise
+ in normal circumstances). */
+
+void
+refmpf_add_ulp (mpf_ptr f)
+{
+ mp_ptr fp = PTR(f);
+ mp_size_t fsize = SIZ(f);
+ mp_size_t abs_fsize = ABSIZ(f);
+ mp_limb_t c;
+
+ if (fsize == 0)
+ {
+ printf ("Oops, refmpf_add_ulp called with f==0\n");
+ abort ();
+ }
+
+ c = refmpn_add_1 (fp, fp, abs_fsize, CNST_LIMB(1));
+ if (c != 0)
+ {
+ if (abs_fsize >= PREC(f) + 1)
+ {
+ printf ("Oops, refmpf_add_ulp carried out of prec+1 limbs\n");
+ abort ();
+ }
+
+ fp[abs_fsize] = c;
+ abs_fsize++;
+ SIZ(f) = (fsize > 0 ? abs_fsize : - abs_fsize);
+ EXP(f)++;
+ }
+}
+
+/* Fill f with size limbs of the given value, setup as an integer. */
+void
+refmpf_fill (mpf_ptr f, mp_size_t size, mp_limb_t value)
+{
+ ASSERT (size >= 0);
+ size = MIN (PREC(f) + 1, size);
+ SIZ(f) = size;
+ EXP(f) = size;
+ refmpn_fill (PTR(f), size, value);
+}
+
+/* Strip high zero limbs from the f data, adjusting exponent accordingly. */
+void
+refmpf_normalize (mpf_ptr f)
+{
+ while (SIZ(f) != 0 && PTR(f)[ABSIZ(f)-1] == 0)
+ {
+ SIZ(f) = (SIZ(f) >= 0 ? SIZ(f)-1 : SIZ(f)+1);
+ EXP(f) --;
+ }
+ if (SIZ(f) == 0)
+ EXP(f) = 0;
+}
+
+/* refmpf_set_overlap sets up dst as a copy of src, but with PREC(dst)
+ unchanged, in preparation for an overlap test.
+
+ The full value of src is copied, and the space at PTR(dst) is extended as
+ necessary. The way PREC(dst) is unchanged is as per an mpf_set_prec_raw.
+ The return value is the new PTR(dst) space precision, in bits, ready for
+ a restoring mpf_set_prec_raw before mpf_clear. */
+
+unsigned long
+refmpf_set_overlap (mpf_ptr dst, mpf_srcptr src)
+{
+ mp_size_t dprec = PREC(dst);
+ mp_size_t ssize = ABSIZ(src);
+ unsigned long ret;
+
+ refmpf_set_prec_limbs (dst, (unsigned long) MAX (dprec, ssize));
+ mpf_set (dst, src);
+
+ ret = mpf_get_prec (dst);
+ PREC(dst) = dprec;
+ return ret;
+}
+
+/* Like mpf_set_prec, but taking a precision in limbs.
+ PREC(f) ends up as the given "prec" value. */
+void
+refmpf_set_prec_limbs (mpf_ptr f, unsigned long prec)
+{
+ mpf_set_prec (f, __GMPF_PREC_TO_BITS (prec));
+}
+
+
+void
+refmpf_sub (mpf_ptr w, mpf_srcptr u, mpf_srcptr v)
+{
+ mp_size_t hi, lo, size;
+ mp_ptr ut, vt, wt;
+ int neg;
+ mp_exp_t exp;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ if (SIZ (u) == 0)
+ {
+ size = ABSIZ (v);
+ wt = TMP_ALLOC_LIMBS (size + 1);
+ MPN_COPY (wt, PTR (v), size);
+ exp = EXP (v);
+ neg = SIZ (v) > 0;
+ goto done;
+ }
+ if (SIZ (v) == 0)
+ {
+ size = ABSIZ (u);
+ wt = TMP_ALLOC_LIMBS (size + 1);
+ MPN_COPY (wt, PTR (u), size);
+ exp = EXP (u);
+ neg = SIZ (u) < 0;
+ goto done;
+ }
+ if ((SIZ (u) ^ SIZ (v)) < 0)
+ {
+ mpf_t tmp;
+ SIZ (tmp) = -SIZ (v);
+ EXP (tmp) = EXP (v);
+ PTR (tmp) = PTR (v);
+ refmpf_add (w, u, tmp);
+ if (SIZ (u) < 0)
+ mpf_neg (w, w);
+ return;
+ }
+ neg = SIZ (u) < 0;
+
+ /* Compute the significance of the hi and lo end of the result. */
+ hi = MAX (EXP (u), EXP (v));
+ lo = MIN (EXP (u) - ABSIZ (u), EXP (v) - ABSIZ (v));
+ size = hi - lo;
+ ut = TMP_ALLOC_LIMBS (size + 1);
+ vt = TMP_ALLOC_LIMBS (size + 1);
+ wt = TMP_ALLOC_LIMBS (size + 1);
+ MPN_ZERO (ut, size);
+ MPN_ZERO (vt, size);
+ {int off;
+ off = size + (EXP (u) - hi) - ABSIZ (u);
+ MPN_COPY (ut + off, PTR (u), ABSIZ (u));
+ off = size + (EXP (v) - hi) - ABSIZ (v);
+ MPN_COPY (vt + off, PTR (v), ABSIZ (v));
+ }
+
+ if (mpn_cmp (ut, vt, size) >= 0)
+ mpn_sub_n (wt, ut, vt, size);
+ else
+ {
+ mpn_sub_n (wt, vt, ut, size);
+ neg ^= 1;
+ }
+ exp = hi;
+ while (size != 0 && wt[size - 1] == 0)
+ {
+ size--;
+ exp--;
+ }
+
+done:
+ if (size > PREC (w))
+ {
+ wt += size - PREC (w);
+ size = PREC (w);
+ }
+ MPN_COPY (PTR (w), wt, size);
+ SIZ (w) = neg == 0 ? size : -size;
+ EXP (w) = exp;
+ TMP_FREE;
+}
+
+
+/* Validate got by comparing to want. Return 1 if good, 0 if bad.
+
+ The data in got is compared to that in want, up to either PREC(got) limbs
+ or the size of got, whichever is bigger. Clearly we always demand
+ PREC(got) of accuracy, but we go further and say that if got is bigger
+ then any extra must be correct too.
+
+ want needs to have enough data to allow this comparison. The size in
+ want doesn't have to be that big though, if it's smaller then further low
+ limbs are taken to be zero.
+
+ This validation approach is designed to allow some flexibility in exactly
+ how much data is generated by an mpf function, ie. either prec or prec+1
+ limbs. We don't try to make a reference function that emulates that same
+ size decision, instead the idea is for a validation function to generate
+ at least as much data as the real function, then compare. */
+
+int
+refmpf_validate (const char *name, mpf_srcptr got, mpf_srcptr want)
+{
+ int bad = 0;
+ mp_size_t gsize, wsize, cmpsize, i;
+ mp_srcptr gp, wp;
+ mp_limb_t glimb, wlimb;
+
+ MPF_CHECK_FORMAT (got);
+
+ if (EXP (got) != EXP (want))
+ {
+ printf ("%s: wrong exponent\n", name);
+ bad = 1;
+ }
+
+ gsize = SIZ (got);
+ wsize = SIZ (want);
+ if ((gsize < 0 && wsize > 0) || (gsize > 0 && wsize < 0))
+ {
+ printf ("%s: wrong sign\n", name);
+ bad = 1;
+ }
+
+ gsize = ABS (gsize);
+ wsize = ABS (wsize);
+
+ /* most significant limb of respective data */
+ gp = PTR (got) + gsize - 1;
+ wp = PTR (want) + wsize - 1;
+
+ /* compare limb data */
+ cmpsize = MAX (PREC (got), gsize);
+ for (i = 0; i < cmpsize; i++)
+ {
+ glimb = (i < gsize ? gp[-i] : 0);
+ wlimb = (i < wsize ? wp[-i] : 0);
+
+ if (glimb != wlimb)
+ {
+ printf ("%s: wrong data starting at index %ld from top\n",
+ name, (long) i);
+ bad = 1;
+ break;
+ }
+ }
+
+ if (bad)
+ {
+ printf (" prec %d\n", PREC(got));
+ printf (" exp got %ld\n", (long) EXP(got));
+ printf (" exp want %ld\n", (long) EXP(want));
+ printf (" size got %d\n", SIZ(got));
+ printf (" size want %d\n", SIZ(want));
+ printf (" limbs (high to low)\n");
+ printf (" got ");
+ for (i = ABSIZ(got)-1; i >= 0; i--)
+ {
+ gmp_printf ("%MX", PTR(got)[i]);
+ if (i != 0)
+ printf (",");
+ }
+ printf ("\n");
+ printf (" want ");
+ for (i = ABSIZ(want)-1; i >= 0; i--)
+ {
+ gmp_printf ("%MX", PTR(want)[i]);
+ if (i != 0)
+ printf (",");
+ }
+ printf ("\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+
+int
+refmpf_validate_division (const char *name, mpf_srcptr got,
+ mpf_srcptr n, mpf_srcptr d)
+{
+ mp_size_t nsize, dsize, sign, prec, qsize, tsize;
+ mp_srcptr np, dp;
+ mp_ptr tp, qp, rp;
+ mpf_t want;
+ int ret;
+
+ nsize = SIZ (n);
+ dsize = SIZ (d);
+ ASSERT_ALWAYS (dsize != 0);
+
+ sign = nsize ^ dsize;
+ nsize = ABS (nsize);
+ dsize = ABS (dsize);
+
+ np = PTR (n);
+ dp = PTR (d);
+ prec = PREC (got);
+
+ EXP (want) = EXP (n) - EXP (d) + 1;
+
+ qsize = prec + 2; /* at least prec+1 limbs, after high zero */
+ tsize = qsize + dsize - 1; /* dividend size to give desired qsize */
+
+ /* dividend n, extended or truncated */
+ tp = refmpn_malloc_limbs (tsize);
+ refmpn_copy_extend (tp, tsize, np, nsize);
+
+ qp = refmpn_malloc_limbs (qsize);
+ rp = refmpn_malloc_limbs (dsize); /* remainder, unused */
+
+ ASSERT_ALWAYS (qsize == tsize - dsize + 1);
+ refmpn_tdiv_qr (qp, rp, (mp_size_t) 0, tp, tsize, dp, dsize);
+
+ PTR (want) = qp;
+ SIZ (want) = (sign >= 0 ? qsize : -qsize);
+ refmpf_normalize (want);
+
+ ret = refmpf_validate (name, got, want);
+
+ free (tp);
+ free (qp);
+ free (rp);
+
+ return ret;
+}
diff --git a/gmp/tests/refmpn.c b/gmp/tests/refmpn.c
new file mode 100644
index 0000000000..bcb322f352
--- /dev/null
+++ b/gmp/tests/refmpn.c
@@ -0,0 +1,2578 @@
+/* Reference mpn functions, designed to be simple, portable and independent
+ of the normal gmp code. Speed isn't a consideration.
+
+Copyright 1996-2009, 2011-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/. */
+
+
+/* Most routines have assertions representing what the mpn routines are
+ supposed to accept. Many of these reference routines do sensible things
+ outside these ranges (eg. for size==0), but the assertions are present to
+ pick up bad parameters passed here that are about to be passed the same
+ to a real mpn routine being compared. */
+
+/* always do assertion checking */
+#define WANT_ASSERT 1
+
+#include <stdio.h> /* for NULL */
+#include <stdlib.h> /* for malloc */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#include "tests.h"
+
+
+
+/* Return non-zero if regions {xp,xsize} and {yp,ysize} overlap, with sizes
+ in bytes. */
+int
+byte_overlap_p (const void *v_xp, mp_size_t xsize,
+ const void *v_yp, mp_size_t ysize)
+{
+ const char *xp = (const char *) v_xp;
+ const char *yp = (const char *) v_yp;
+
+ ASSERT (xsize >= 0);
+ ASSERT (ysize >= 0);
+
+ /* no wraparounds */
+ ASSERT (xp+xsize >= xp);
+ ASSERT (yp+ysize >= yp);
+
+ if (xp + xsize <= yp)
+ return 0;
+
+ if (yp + ysize <= xp)
+ return 0;
+
+ return 1;
+}
+
+/* Return non-zero if limb regions {xp,xsize} and {yp,ysize} overlap. */
+int
+refmpn_overlap_p (mp_srcptr xp, mp_size_t xsize, mp_srcptr yp, mp_size_t ysize)
+{
+ return byte_overlap_p (xp, xsize * GMP_LIMB_BYTES,
+ yp, ysize * GMP_LIMB_BYTES);
+}
+
+/* Check overlap for a routine defined to work low to high. */
+int
+refmpn_overlap_low_to_high_p (mp_srcptr dst, mp_srcptr src, mp_size_t size)
+{
+ return (dst <= src || ! refmpn_overlap_p (dst, size, src, size));
+}
+
+/* Check overlap for a routine defined to work high to low. */
+int
+refmpn_overlap_high_to_low_p (mp_srcptr dst, mp_srcptr src, mp_size_t size)
+{
+ return (dst >= src || ! refmpn_overlap_p (dst, size, src, size));
+}
+
+/* Check overlap for a standard routine requiring equal or separate. */
+int
+refmpn_overlap_fullonly_p (mp_srcptr dst, mp_srcptr src, mp_size_t size)
+{
+ return (dst == src || ! refmpn_overlap_p (dst, size, src, size));
+}
+int
+refmpn_overlap_fullonly_two_p (mp_srcptr dst, mp_srcptr src1, mp_srcptr src2,
+ mp_size_t size)
+{
+ return (refmpn_overlap_fullonly_p (dst, src1, size)
+ && refmpn_overlap_fullonly_p (dst, src2, size));
+}
+
+
+mp_ptr
+refmpn_malloc_limbs (mp_size_t size)
+{
+ mp_ptr p;
+ ASSERT (size >= 0);
+ if (size == 0)
+ size = 1;
+ p = (mp_ptr) malloc ((size_t) (size * GMP_LIMB_BYTES));
+ ASSERT (p != NULL);
+ return p;
+}
+
+/* Free limbs allocated by refmpn_malloc_limbs. NOTE: Can't free
+ * memory allocated by refmpn_malloc_limbs_aligned. */
+void
+refmpn_free_limbs (mp_ptr p)
+{
+ free (p);
+}
+
+mp_ptr
+refmpn_memdup_limbs (mp_srcptr ptr, mp_size_t size)
+{
+ mp_ptr p;
+ p = refmpn_malloc_limbs (size);
+ refmpn_copyi (p, ptr, size);
+ return p;
+}
+
+/* malloc n limbs on a multiple of m bytes boundary */
+mp_ptr
+refmpn_malloc_limbs_aligned (mp_size_t n, size_t m)
+{
+ return (mp_ptr) align_pointer (refmpn_malloc_limbs (n + m-1), m);
+}
+
+
+void
+refmpn_fill (mp_ptr ptr, mp_size_t size, mp_limb_t value)
+{
+ mp_size_t i;
+ ASSERT (size >= 0);
+ for (i = 0; i < size; i++)
+ ptr[i] = value;
+}
+
+void
+refmpn_zero (mp_ptr ptr, mp_size_t size)
+{
+ refmpn_fill (ptr, size, CNST_LIMB(0));
+}
+
+void
+refmpn_zero_extend (mp_ptr ptr, mp_size_t oldsize, mp_size_t newsize)
+{
+ ASSERT (newsize >= oldsize);
+ refmpn_zero (ptr+oldsize, newsize-oldsize);
+}
+
+int
+refmpn_zero_p (mp_srcptr ptr, mp_size_t size)
+{
+ mp_size_t i;
+ for (i = 0; i < size; i++)
+ if (ptr[i] != 0)
+ return 0;
+ return 1;
+}
+
+mp_size_t
+refmpn_normalize (mp_srcptr ptr, mp_size_t size)
+{
+ ASSERT (size >= 0);
+ while (size > 0 && ptr[size-1] == 0)
+ size--;
+ return size;
+}
+
+/* the highest one bit in x */
+mp_limb_t
+refmpn_msbone (mp_limb_t x)
+{
+ mp_limb_t n = (mp_limb_t) 1 << (GMP_LIMB_BITS-1);
+
+ while (n != 0)
+ {
+ if (x & n)
+ break;
+ n >>= 1;
+ }
+ return n;
+}
+
+/* a mask of the highest one bit plus and all bits below */
+mp_limb_t
+refmpn_msbone_mask (mp_limb_t x)
+{
+ if (x == 0)
+ return 0;
+
+ return (refmpn_msbone (x) << 1) - 1;
+}
+
+/* How many digits in the given base will fit in a limb.
+ Notice that the product b is allowed to be equal to the limit
+ 2^GMP_NUMB_BITS, this ensures the result for base==2 will be
+ GMP_NUMB_BITS (and similarly other powers of 2). */
+int
+refmpn_chars_per_limb (int base)
+{
+ mp_limb_t limit[2], b[2];
+ int chars_per_limb;
+
+ ASSERT (base >= 2);
+
+ limit[0] = 0; /* limit = 2^GMP_NUMB_BITS */
+ limit[1] = 1;
+ b[0] = 1; /* b = 1 */
+ b[1] = 0;
+
+ chars_per_limb = 0;
+ for (;;)
+ {
+ if (refmpn_mul_1 (b, b, (mp_size_t) 2, (mp_limb_t) base))
+ break;
+ if (refmpn_cmp (b, limit, (mp_size_t) 2) > 0)
+ break;
+ chars_per_limb++;
+ }
+ return chars_per_limb;
+}
+
+/* The biggest value base**n which fits in GMP_NUMB_BITS. */
+mp_limb_t
+refmpn_big_base (int base)
+{
+ int chars_per_limb = refmpn_chars_per_limb (base);
+ int i;
+ mp_limb_t bb;
+
+ ASSERT (base >= 2);
+ bb = 1;
+ for (i = 0; i < chars_per_limb; i++)
+ bb *= base;
+ return bb;
+}
+
+
+void
+refmpn_setbit (mp_ptr ptr, unsigned long bit)
+{
+ ptr[bit/GMP_NUMB_BITS] |= CNST_LIMB(1) << (bit%GMP_NUMB_BITS);
+}
+
+void
+refmpn_clrbit (mp_ptr ptr, unsigned long bit)
+{
+ ptr[bit/GMP_NUMB_BITS] &= ~ (CNST_LIMB(1) << (bit%GMP_NUMB_BITS));
+}
+
+#define REFMPN_TSTBIT(ptr,bit) \
+ (((ptr)[(bit)/GMP_NUMB_BITS] & (CNST_LIMB(1) << ((bit)%GMP_NUMB_BITS))) != 0)
+
+int
+refmpn_tstbit (mp_srcptr ptr, unsigned long bit)
+{
+ return REFMPN_TSTBIT (ptr, bit);
+}
+
+unsigned long
+refmpn_scan0 (mp_srcptr ptr, unsigned long bit)
+{
+ while (REFMPN_TSTBIT (ptr, bit) != 0)
+ bit++;
+ return bit;
+}
+
+unsigned long
+refmpn_scan1 (mp_srcptr ptr, unsigned long bit)
+{
+ while (REFMPN_TSTBIT (ptr, bit) == 0)
+ bit++;
+ return bit;
+}
+
+void
+refmpn_copy (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ ASSERT (refmpn_overlap_fullonly_p (rp, sp, size));
+ refmpn_copyi (rp, sp, size);
+}
+
+void
+refmpn_copyi (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ mp_size_t i;
+
+ ASSERT (refmpn_overlap_low_to_high_p (rp, sp, size));
+ ASSERT (size >= 0);
+
+ for (i = 0; i < size; i++)
+ rp[i] = sp[i];
+}
+
+void
+refmpn_copyd (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ mp_size_t i;
+
+ ASSERT (refmpn_overlap_high_to_low_p (rp, sp, size));
+ ASSERT (size >= 0);
+
+ for (i = size-1; i >= 0; i--)
+ rp[i] = sp[i];
+}
+
+/* Copy {xp,xsize} to {wp,wsize}. If x is shorter, then pad w with low
+ zeros to wsize. If x is longer, then copy just the high wsize limbs. */
+void
+refmpn_copy_extend (mp_ptr wp, mp_size_t wsize, mp_srcptr xp, mp_size_t xsize)
+{
+ ASSERT (wsize >= 0);
+ ASSERT (xsize >= 0);
+
+ /* high part of x if x bigger than w */
+ if (xsize > wsize)
+ {
+ xp += xsize - wsize;
+ xsize = wsize;
+ }
+
+ refmpn_copy (wp + wsize-xsize, xp, xsize);
+ refmpn_zero (wp, wsize-xsize);
+}
+
+int
+refmpn_cmp (mp_srcptr xp, mp_srcptr yp, mp_size_t size)
+{
+ mp_size_t i;
+
+ ASSERT (size >= 1);
+ ASSERT_MPN (xp, size);
+ ASSERT_MPN (yp, size);
+
+ for (i = size-1; i >= 0; i--)
+ {
+ if (xp[i] > yp[i]) return 1;
+ if (xp[i] < yp[i]) return -1;
+ }
+ return 0;
+}
+
+int
+refmpn_cmp_allowzero (mp_srcptr xp, mp_srcptr yp, mp_size_t size)
+{
+ if (size == 0)
+ return 0;
+ else
+ return refmpn_cmp (xp, yp, size);
+}
+
+int
+refmpn_cmp_twosizes (mp_srcptr xp, mp_size_t xsize,
+ mp_srcptr yp, mp_size_t ysize)
+{
+ int opp, cmp;
+
+ ASSERT_MPN (xp, xsize);
+ ASSERT_MPN (yp, ysize);
+
+ opp = (xsize < ysize);
+ if (opp)
+ MPN_SRCPTR_SWAP (xp,xsize, yp,ysize);
+
+ if (! refmpn_zero_p (xp+ysize, xsize-ysize))
+ cmp = 1;
+ else
+ cmp = refmpn_cmp (xp, yp, ysize);
+
+ return (opp ? -cmp : cmp);
+}
+
+int
+refmpn_equal_anynail (mp_srcptr xp, mp_srcptr yp, mp_size_t size)
+{
+ mp_size_t i;
+ ASSERT (size >= 0);
+
+ for (i = 0; i < size; i++)
+ if (xp[i] != yp[i])
+ return 0;
+ return 1;
+}
+
+
+#define LOGOPS(operation) \
+ { \
+ mp_size_t i; \
+ \
+ ASSERT (refmpn_overlap_fullonly_two_p (rp, s1p, s2p, size)); \
+ ASSERT (size >= 1); \
+ ASSERT_MPN (s1p, size); \
+ ASSERT_MPN (s2p, size); \
+ \
+ for (i = 0; i < size; i++) \
+ rp[i] = operation; \
+ }
+
+void
+refmpn_and_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ LOGOPS (s1p[i] & s2p[i]);
+}
+void
+refmpn_andn_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ LOGOPS (s1p[i] & ~s2p[i]);
+}
+void
+refmpn_nand_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ LOGOPS ((s1p[i] & s2p[i]) ^ GMP_NUMB_MASK);
+}
+void
+refmpn_ior_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ LOGOPS (s1p[i] | s2p[i]);
+}
+void
+refmpn_iorn_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ LOGOPS (s1p[i] | (s2p[i] ^ GMP_NUMB_MASK));
+}
+void
+refmpn_nior_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ LOGOPS ((s1p[i] | s2p[i]) ^ GMP_NUMB_MASK);
+}
+void
+refmpn_xor_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ LOGOPS (s1p[i] ^ s2p[i]);
+}
+void
+refmpn_xnor_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ LOGOPS ((s1p[i] ^ s2p[i]) ^ GMP_NUMB_MASK);
+}
+
+
+/* set *dh,*dl to mh:ml - sh:sl, in full limbs */
+void
+refmpn_sub_ddmmss (mp_limb_t *dh, mp_limb_t *dl,
+ mp_limb_t mh, mp_limb_t ml, mp_limb_t sh, mp_limb_t sl)
+{
+ *dl = ml - sl;
+ *dh = mh - sh - (ml < sl);
+}
+
+
+/* set *w to x+y, return 0 or 1 carry */
+mp_limb_t
+ref_addc_limb (mp_limb_t *w, mp_limb_t x, mp_limb_t y)
+{
+ mp_limb_t sum, cy;
+
+ ASSERT_LIMB (x);
+ ASSERT_LIMB (y);
+
+ sum = x + y;
+#if GMP_NAIL_BITS == 0
+ *w = sum;
+ cy = (sum < x);
+#else
+ *w = sum & GMP_NUMB_MASK;
+ cy = (sum >> GMP_NUMB_BITS);
+#endif
+ return cy;
+}
+
+/* set *w to x-y, return 0 or 1 borrow */
+mp_limb_t
+ref_subc_limb (mp_limb_t *w, mp_limb_t x, mp_limb_t y)
+{
+ mp_limb_t diff, cy;
+
+ ASSERT_LIMB (x);
+ ASSERT_LIMB (y);
+
+ diff = x - y;
+#if GMP_NAIL_BITS == 0
+ *w = diff;
+ cy = (diff > x);
+#else
+ *w = diff & GMP_NUMB_MASK;
+ cy = (diff >> GMP_NUMB_BITS) & 1;
+#endif
+ return cy;
+}
+
+/* set *w to x+y+c (where c is 0 or 1), return 0 or 1 carry */
+mp_limb_t
+adc (mp_limb_t *w, mp_limb_t x, mp_limb_t y, mp_limb_t c)
+{
+ mp_limb_t r;
+
+ ASSERT_LIMB (x);
+ ASSERT_LIMB (y);
+ ASSERT (c == 0 || c == 1);
+
+ r = ref_addc_limb (w, x, y);
+ return r + ref_addc_limb (w, *w, c);
+}
+
+/* set *w to x-y-c (where c is 0 or 1), return 0 or 1 borrow */
+mp_limb_t
+sbb (mp_limb_t *w, mp_limb_t x, mp_limb_t y, mp_limb_t c)
+{
+ mp_limb_t r;
+
+ ASSERT_LIMB (x);
+ ASSERT_LIMB (y);
+ ASSERT (c == 0 || c == 1);
+
+ r = ref_subc_limb (w, x, y);
+ return r + ref_subc_limb (w, *w, c);
+}
+
+
+#define AORS_1(operation) \
+ { \
+ mp_size_t i; \
+ \
+ ASSERT (refmpn_overlap_fullonly_p (rp, sp, size)); \
+ ASSERT (size >= 1); \
+ ASSERT_MPN (sp, size); \
+ ASSERT_LIMB (n); \
+ \
+ for (i = 0; i < size; i++) \
+ n = operation (&rp[i], sp[i], n); \
+ return n; \
+ }
+
+mp_limb_t
+refmpn_add_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t n)
+{
+ AORS_1 (ref_addc_limb);
+}
+mp_limb_t
+refmpn_sub_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t n)
+{
+ AORS_1 (ref_subc_limb);
+}
+
+#define AORS_NC(operation) \
+ { \
+ mp_size_t i; \
+ \
+ ASSERT (refmpn_overlap_fullonly_two_p (rp, s1p, s2p, size)); \
+ ASSERT (carry == 0 || carry == 1); \
+ ASSERT (size >= 1); \
+ ASSERT_MPN (s1p, size); \
+ ASSERT_MPN (s2p, size); \
+ \
+ for (i = 0; i < size; i++) \
+ carry = operation (&rp[i], s1p[i], s2p[i], carry); \
+ return carry; \
+ }
+
+mp_limb_t
+refmpn_add_nc (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size,
+ mp_limb_t carry)
+{
+ AORS_NC (adc);
+}
+mp_limb_t
+refmpn_sub_nc (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size,
+ mp_limb_t carry)
+{
+ AORS_NC (sbb);
+}
+
+
+mp_limb_t
+refmpn_add_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ return refmpn_add_nc (rp, s1p, s2p, size, CNST_LIMB(0));
+}
+mp_limb_t
+refmpn_sub_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ return refmpn_sub_nc (rp, s1p, s2p, size, CNST_LIMB(0));
+}
+
+mp_limb_t
+refmpn_cnd_add_n (mp_limb_t cnd, mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ if (cnd != 0)
+ return refmpn_add_n (rp, s1p, s2p, size);
+ else
+ {
+ refmpn_copyi (rp, s1p, size);
+ return 0;
+ }
+}
+mp_limb_t
+refmpn_cnd_sub_n (mp_limb_t cnd, mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ if (cnd != 0)
+ return refmpn_sub_n (rp, s1p, s2p, size);
+ else
+ {
+ refmpn_copyi (rp, s1p, size);
+ return 0;
+ }
+}
+
+
+#define AORS_ERR1_N(operation) \
+ { \
+ mp_size_t i; \
+ mp_limb_t carry2; \
+ \
+ ASSERT (refmpn_overlap_fullonly_p (rp, s1p, size)); \
+ ASSERT (refmpn_overlap_fullonly_p (rp, s2p, size)); \
+ ASSERT (! refmpn_overlap_p (rp, size, yp, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 2, s1p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 2, s2p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 2, yp, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 2, rp, size)); \
+ \
+ ASSERT (carry == 0 || carry == 1); \
+ ASSERT (size >= 1); \
+ ASSERT_MPN (s1p, size); \
+ ASSERT_MPN (s2p, size); \
+ ASSERT_MPN (yp, size); \
+ \
+ ep[0] = ep[1] = CNST_LIMB(0); \
+ \
+ for (i = 0; i < size; i++) \
+ { \
+ carry = operation (&rp[i], s1p[i], s2p[i], carry); \
+ if (carry == 1) \
+ { \
+ carry2 = ref_addc_limb (&ep[0], ep[0], yp[size - 1 - i]); \
+ carry2 = ref_addc_limb (&ep[1], ep[1], carry2); \
+ ASSERT (carry2 == 0); \
+ } \
+ } \
+ return carry; \
+ }
+
+mp_limb_t
+refmpn_add_err1_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p,
+ mp_ptr ep, mp_srcptr yp,
+ mp_size_t size, mp_limb_t carry)
+{
+ AORS_ERR1_N (adc);
+}
+mp_limb_t
+refmpn_sub_err1_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p,
+ mp_ptr ep, mp_srcptr yp,
+ mp_size_t size, mp_limb_t carry)
+{
+ AORS_ERR1_N (sbb);
+}
+
+
+#define AORS_ERR2_N(operation) \
+ { \
+ mp_size_t i; \
+ mp_limb_t carry2; \
+ \
+ ASSERT (refmpn_overlap_fullonly_p (rp, s1p, size)); \
+ ASSERT (refmpn_overlap_fullonly_p (rp, s2p, size)); \
+ ASSERT (! refmpn_overlap_p (rp, size, y1p, size)); \
+ ASSERT (! refmpn_overlap_p (rp, size, y2p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 4, s1p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 4, s2p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 4, y1p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 4, y2p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 4, rp, size)); \
+ \
+ ASSERT (carry == 0 || carry == 1); \
+ ASSERT (size >= 1); \
+ ASSERT_MPN (s1p, size); \
+ ASSERT_MPN (s2p, size); \
+ ASSERT_MPN (y1p, size); \
+ ASSERT_MPN (y2p, size); \
+ \
+ ep[0] = ep[1] = CNST_LIMB(0); \
+ ep[2] = ep[3] = CNST_LIMB(0); \
+ \
+ for (i = 0; i < size; i++) \
+ { \
+ carry = operation (&rp[i], s1p[i], s2p[i], carry); \
+ if (carry == 1) \
+ { \
+ carry2 = ref_addc_limb (&ep[0], ep[0], y1p[size - 1 - i]); \
+ carry2 = ref_addc_limb (&ep[1], ep[1], carry2); \
+ ASSERT (carry2 == 0); \
+ carry2 = ref_addc_limb (&ep[2], ep[2], y2p[size - 1 - i]); \
+ carry2 = ref_addc_limb (&ep[3], ep[3], carry2); \
+ ASSERT (carry2 == 0); \
+ } \
+ } \
+ return carry; \
+ }
+
+mp_limb_t
+refmpn_add_err2_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p,
+ mp_ptr ep, mp_srcptr y1p, mp_srcptr y2p,
+ mp_size_t size, mp_limb_t carry)
+{
+ AORS_ERR2_N (adc);
+}
+mp_limb_t
+refmpn_sub_err2_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p,
+ mp_ptr ep, mp_srcptr y1p, mp_srcptr y2p,
+ mp_size_t size, mp_limb_t carry)
+{
+ AORS_ERR2_N (sbb);
+}
+
+
+#define AORS_ERR3_N(operation) \
+ { \
+ mp_size_t i; \
+ mp_limb_t carry2; \
+ \
+ ASSERT (refmpn_overlap_fullonly_p (rp, s1p, size)); \
+ ASSERT (refmpn_overlap_fullonly_p (rp, s2p, size)); \
+ ASSERT (! refmpn_overlap_p (rp, size, y1p, size)); \
+ ASSERT (! refmpn_overlap_p (rp, size, y2p, size)); \
+ ASSERT (! refmpn_overlap_p (rp, size, y3p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 6, s1p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 6, s2p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 6, y1p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 6, y2p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 6, y3p, size)); \
+ ASSERT (! refmpn_overlap_p (ep, 6, rp, size)); \
+ \
+ ASSERT (carry == 0 || carry == 1); \
+ ASSERT (size >= 1); \
+ ASSERT_MPN (s1p, size); \
+ ASSERT_MPN (s2p, size); \
+ ASSERT_MPN (y1p, size); \
+ ASSERT_MPN (y2p, size); \
+ ASSERT_MPN (y3p, size); \
+ \
+ ep[0] = ep[1] = CNST_LIMB(0); \
+ ep[2] = ep[3] = CNST_LIMB(0); \
+ ep[4] = ep[5] = CNST_LIMB(0); \
+ \
+ for (i = 0; i < size; i++) \
+ { \
+ carry = operation (&rp[i], s1p[i], s2p[i], carry); \
+ if (carry == 1) \
+ { \
+ carry2 = ref_addc_limb (&ep[0], ep[0], y1p[size - 1 - i]); \
+ carry2 = ref_addc_limb (&ep[1], ep[1], carry2); \
+ ASSERT (carry2 == 0); \
+ carry2 = ref_addc_limb (&ep[2], ep[2], y2p[size - 1 - i]); \
+ carry2 = ref_addc_limb (&ep[3], ep[3], carry2); \
+ ASSERT (carry2 == 0); \
+ carry2 = ref_addc_limb (&ep[4], ep[4], y3p[size - 1 - i]); \
+ carry2 = ref_addc_limb (&ep[5], ep[5], carry2); \
+ ASSERT (carry2 == 0); \
+ } \
+ } \
+ return carry; \
+ }
+
+mp_limb_t
+refmpn_add_err3_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p,
+ mp_ptr ep, mp_srcptr y1p, mp_srcptr y2p, mp_srcptr y3p,
+ mp_size_t size, mp_limb_t carry)
+{
+ AORS_ERR3_N (adc);
+}
+mp_limb_t
+refmpn_sub_err3_n (mp_ptr rp, mp_srcptr s1p, mp_srcptr s2p,
+ mp_ptr ep, mp_srcptr y1p, mp_srcptr y2p, mp_srcptr y3p,
+ mp_size_t size, mp_limb_t carry)
+{
+ AORS_ERR3_N (sbb);
+}
+
+
+mp_limb_t
+refmpn_addlsh_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_size_t n, unsigned int s)
+{
+ mp_limb_t cy;
+ mp_ptr tp;
+
+ ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
+ ASSERT (n >= 1);
+ ASSERT (0 < s && s < GMP_NUMB_BITS);
+ ASSERT_MPN (up, n);
+ ASSERT_MPN (vp, n);
+
+ tp = refmpn_malloc_limbs (n);
+ cy = refmpn_lshift (tp, vp, n, s);
+ cy += refmpn_add_n (rp, up, tp, n);
+ free (tp);
+ return cy;
+}
+mp_limb_t
+refmpn_addlsh1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_addlsh_n (rp, up, vp, n, 1);
+}
+mp_limb_t
+refmpn_addlsh2_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_addlsh_n (rp, up, vp, n, 2);
+}
+mp_limb_t
+refmpn_addlsh_n_ip1 (mp_ptr rp, mp_srcptr vp, mp_size_t n, unsigned int s)
+{
+ return refmpn_addlsh_n (rp, rp, vp, n, s);
+}
+mp_limb_t
+refmpn_addlsh1_n_ip1 (mp_ptr rp, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_addlsh_n (rp, rp, vp, n, 1);
+}
+mp_limb_t
+refmpn_addlsh2_n_ip1 (mp_ptr rp, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_addlsh_n (rp, rp, vp, n, 2);
+}
+mp_limb_t
+refmpn_addlsh_n_ip2 (mp_ptr rp, mp_srcptr vp, mp_size_t n, unsigned int s)
+{
+ return refmpn_addlsh_n (rp, vp, rp, n, s);
+}
+mp_limb_t
+refmpn_addlsh1_n_ip2 (mp_ptr rp, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_addlsh_n (rp, vp, rp, n, 1);
+}
+mp_limb_t
+refmpn_addlsh2_n_ip2 (mp_ptr rp, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_addlsh_n (rp, vp, rp, n, 2);
+}
+mp_limb_t
+refmpn_addlsh_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_size_t n, unsigned int s, mp_limb_t carry)
+{
+ mp_limb_t cy;
+
+ ASSERT (carry <= (CNST_LIMB(1) << s));
+
+ cy = refmpn_addlsh_n (rp, up, vp, n, s);
+ cy += refmpn_add_1 (rp, rp, n, carry);
+ return cy;
+}
+mp_limb_t
+refmpn_addlsh1_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n, mp_limb_t carry)
+{
+ return refmpn_addlsh_nc (rp, up, vp, n, 1, carry);
+}
+mp_limb_t
+refmpn_addlsh2_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n, mp_limb_t carry)
+{
+ return refmpn_addlsh_nc (rp, up, vp, n, 2, carry);
+}
+
+mp_limb_t
+refmpn_sublsh_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_size_t n, unsigned int s)
+{
+ mp_limb_t cy;
+ mp_ptr tp;
+
+ ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
+ ASSERT (n >= 1);
+ ASSERT (0 < s && s < GMP_NUMB_BITS);
+ ASSERT_MPN (up, n);
+ ASSERT_MPN (vp, n);
+
+ tp = refmpn_malloc_limbs (n);
+ cy = mpn_lshift (tp, vp, n, s);
+ cy += mpn_sub_n (rp, up, tp, n);
+ free (tp);
+ return cy;
+}
+mp_limb_t
+refmpn_sublsh1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_sublsh_n (rp, up, vp, n, 1);
+}
+mp_limb_t
+refmpn_sublsh2_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_sublsh_n (rp, up, vp, n, 2);
+}
+mp_limb_t
+refmpn_sublsh_n_ip1 (mp_ptr rp, mp_srcptr vp, mp_size_t n, unsigned int s)
+{
+ return refmpn_sublsh_n (rp, rp, vp, n, s);
+}
+mp_limb_t
+refmpn_sublsh1_n_ip1 (mp_ptr rp, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_sublsh_n (rp, rp, vp, n, 1);
+}
+mp_limb_t
+refmpn_sublsh2_n_ip1 (mp_ptr rp, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_sublsh_n (rp, rp, vp, n, 2);
+}
+mp_limb_t
+refmpn_sublsh_n_ip2 (mp_ptr rp, mp_srcptr vp, mp_size_t n, unsigned int s)
+{
+ return refmpn_sublsh_n (rp, vp, rp, n, s);
+}
+mp_limb_t
+refmpn_sublsh1_n_ip2 (mp_ptr rp, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_sublsh_n (rp, vp, rp, n, 1);
+}
+mp_limb_t
+refmpn_sublsh2_n_ip2 (mp_ptr rp, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_sublsh_n (rp, vp, rp, n, 2);
+}
+mp_limb_t
+refmpn_sublsh_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_size_t n, unsigned int s, mp_limb_t carry)
+{
+ mp_limb_t cy;
+
+ ASSERT (carry <= (CNST_LIMB(1) << s));
+
+ cy = refmpn_sublsh_n (rp, up, vp, n, s);
+ cy += refmpn_sub_1 (rp, rp, n, carry);
+ return cy;
+}
+mp_limb_t
+refmpn_sublsh1_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n, mp_limb_t carry)
+{
+ return refmpn_sublsh_nc (rp, up, vp, n, 1, carry);
+}
+mp_limb_t
+refmpn_sublsh2_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n, mp_limb_t carry)
+{
+ return refmpn_sublsh_nc (rp, up, vp, n, 2, carry);
+}
+
+mp_limb_signed_t
+refmpn_rsblsh_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_size_t n, unsigned int s)
+{
+ mp_limb_signed_t cy;
+ mp_ptr tp;
+
+ ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
+ ASSERT (n >= 1);
+ ASSERT (0 < s && s < GMP_NUMB_BITS);
+ ASSERT_MPN (up, n);
+ ASSERT_MPN (vp, n);
+
+ tp = refmpn_malloc_limbs (n);
+ cy = mpn_lshift (tp, vp, n, s);
+ cy -= mpn_sub_n (rp, tp, up, n);
+ free (tp);
+ return cy;
+}
+mp_limb_signed_t
+refmpn_rsblsh1_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_rsblsh_n (rp, up, vp, n, 1);
+}
+mp_limb_signed_t
+refmpn_rsblsh2_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ return refmpn_rsblsh_n (rp, up, vp, n, 2);
+}
+mp_limb_signed_t
+refmpn_rsblsh_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp,
+ mp_size_t n, unsigned int s, mp_limb_signed_t carry)
+{
+ mp_limb_signed_t cy;
+
+ ASSERT (carry == -1 || (carry >> s) == 0);
+
+ cy = refmpn_rsblsh_n (rp, up, vp, n, s);
+ if (carry > 0)
+ cy += refmpn_add_1 (rp, rp, n, carry);
+ else
+ cy -= refmpn_sub_1 (rp, rp, n, -carry);
+ return cy;
+}
+mp_limb_signed_t
+refmpn_rsblsh1_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n, mp_limb_signed_t carry)
+{
+ return refmpn_rsblsh_nc (rp, up, vp, n, 1, carry);
+}
+mp_limb_signed_t
+refmpn_rsblsh2_nc (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n, mp_limb_signed_t carry)
+{
+ return refmpn_rsblsh_nc (rp, up, vp, n, 2, carry);
+}
+
+mp_limb_t
+refmpn_rsh1add_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t cya, cys;
+
+ ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
+ ASSERT (n >= 1);
+ ASSERT_MPN (up, n);
+ ASSERT_MPN (vp, n);
+
+ cya = mpn_add_n (rp, up, vp, n);
+ cys = mpn_rshift (rp, rp, n, 1) >> (GMP_NUMB_BITS - 1);
+ rp[n - 1] |= cya << (GMP_NUMB_BITS - 1);
+ return cys;
+}
+mp_limb_t
+refmpn_rsh1sub_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ mp_limb_t cya, cys;
+
+ ASSERT (refmpn_overlap_fullonly_two_p (rp, up, vp, n));
+ ASSERT (n >= 1);
+ ASSERT_MPN (up, n);
+ ASSERT_MPN (vp, n);
+
+ cya = mpn_sub_n (rp, up, vp, n);
+ cys = mpn_rshift (rp, rp, n, 1) >> (GMP_NUMB_BITS - 1);
+ rp[n - 1] |= cya << (GMP_NUMB_BITS - 1);
+ return cys;
+}
+
+/* Twos complement, return borrow. */
+mp_limb_t
+refmpn_neg (mp_ptr dst, mp_srcptr src, mp_size_t size)
+{
+ mp_ptr zeros;
+ mp_limb_t ret;
+
+ ASSERT (size >= 1);
+
+ zeros = refmpn_malloc_limbs (size);
+ refmpn_fill (zeros, size, CNST_LIMB(0));
+ ret = refmpn_sub_n (dst, zeros, src, size);
+ free (zeros);
+ return ret;
+}
+
+
+#define AORS(aors_n, aors_1) \
+ { \
+ mp_limb_t c; \
+ ASSERT (s1size >= s2size); \
+ ASSERT (s2size >= 1); \
+ c = aors_n (rp, s1p, s2p, s2size); \
+ if (s1size-s2size != 0) \
+ c = aors_1 (rp+s2size, s1p+s2size, s1size-s2size, c); \
+ return c; \
+ }
+mp_limb_t
+refmpn_add (mp_ptr rp,
+ mp_srcptr s1p, mp_size_t s1size,
+ mp_srcptr s2p, mp_size_t s2size)
+{
+ AORS (refmpn_add_n, refmpn_add_1);
+}
+mp_limb_t
+refmpn_sub (mp_ptr rp,
+ mp_srcptr s1p, mp_size_t s1size,
+ mp_srcptr s2p, mp_size_t s2size)
+{
+ AORS (refmpn_sub_n, refmpn_sub_1);
+}
+
+
+#define SHIFTHIGH(x) ((x) << GMP_LIMB_BITS/2)
+#define SHIFTLOW(x) ((x) >> GMP_LIMB_BITS/2)
+
+#define LOWMASK (((mp_limb_t) 1 << GMP_LIMB_BITS/2)-1)
+#define HIGHMASK SHIFTHIGH(LOWMASK)
+
+#define LOWPART(x) ((x) & LOWMASK)
+#define HIGHPART(x) SHIFTLOW((x) & HIGHMASK)
+
+/* Set return:*lo to x*y, using full limbs not nails. */
+mp_limb_t
+refmpn_umul_ppmm (mp_limb_t *lo, mp_limb_t x, mp_limb_t y)
+{
+ mp_limb_t hi, s;
+
+ *lo = LOWPART(x) * LOWPART(y);
+ hi = HIGHPART(x) * HIGHPART(y);
+
+ s = LOWPART(x) * HIGHPART(y);
+ hi += HIGHPART(s);
+ s = SHIFTHIGH(LOWPART(s));
+ *lo += s;
+ hi += (*lo < s);
+
+ s = HIGHPART(x) * LOWPART(y);
+ hi += HIGHPART(s);
+ s = SHIFTHIGH(LOWPART(s));
+ *lo += s;
+ hi += (*lo < s);
+
+ return hi;
+}
+
+mp_limb_t
+refmpn_umul_ppmm_r (mp_limb_t x, mp_limb_t y, mp_limb_t *lo)
+{
+ return refmpn_umul_ppmm (lo, x, y);
+}
+
+mp_limb_t
+refmpn_mul_1c (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t multiplier,
+ mp_limb_t carry)
+{
+ mp_size_t i;
+ mp_limb_t hi, lo;
+
+ ASSERT (refmpn_overlap_low_to_high_p (rp, sp, size));
+ ASSERT (size >= 1);
+ ASSERT_MPN (sp, size);
+ ASSERT_LIMB (multiplier);
+ ASSERT_LIMB (carry);
+
+ multiplier <<= GMP_NAIL_BITS;
+ for (i = 0; i < size; i++)
+ {
+ hi = refmpn_umul_ppmm (&lo, sp[i], multiplier);
+ lo >>= GMP_NAIL_BITS;
+ ASSERT_NOCARRY (ref_addc_limb (&hi, hi, ref_addc_limb (&lo, lo, carry)));
+ rp[i] = lo;
+ carry = hi;
+ }
+ return carry;
+}
+
+mp_limb_t
+refmpn_mul_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t multiplier)
+{
+ return refmpn_mul_1c (rp, sp, size, multiplier, CNST_LIMB(0));
+}
+
+
+mp_limb_t
+refmpn_mul_N (mp_ptr dst, mp_srcptr src, mp_size_t size,
+ mp_srcptr mult, mp_size_t msize)
+{
+ mp_ptr src_copy;
+ mp_limb_t ret;
+ mp_size_t i;
+
+ ASSERT (refmpn_overlap_fullonly_p (dst, src, size));
+ ASSERT (! refmpn_overlap_p (dst, size+msize-1, mult, msize));
+ ASSERT (size >= msize);
+ ASSERT_MPN (mult, msize);
+
+ /* in case dst==src */
+ src_copy = refmpn_malloc_limbs (size);
+ refmpn_copyi (src_copy, src, size);
+ src = src_copy;
+
+ dst[size] = refmpn_mul_1 (dst, src, size, mult[0]);
+ for (i = 1; i < msize-1; i++)
+ dst[size+i] = refmpn_addmul_1 (dst+i, src, size, mult[i]);
+ ret = refmpn_addmul_1 (dst+i, src, size, mult[i]);
+
+ free (src_copy);
+ return ret;
+}
+
+mp_limb_t
+refmpn_mul_2 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_mul_N (rp, sp, size, mult, (mp_size_t) 2);
+}
+mp_limb_t
+refmpn_mul_3 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_mul_N (rp, sp, size, mult, (mp_size_t) 3);
+}
+mp_limb_t
+refmpn_mul_4 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_mul_N (rp, sp, size, mult, (mp_size_t) 4);
+}
+mp_limb_t
+refmpn_mul_5 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_mul_N (rp, sp, size, mult, (mp_size_t) 5);
+}
+mp_limb_t
+refmpn_mul_6 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_mul_N (rp, sp, size, mult, (mp_size_t) 6);
+}
+
+#define AORSMUL_1C(operation_n) \
+ { \
+ mp_ptr p; \
+ mp_limb_t ret; \
+ \
+ ASSERT (refmpn_overlap_fullonly_p (rp, sp, size)); \
+ \
+ p = refmpn_malloc_limbs (size); \
+ ret = refmpn_mul_1c (p, sp, size, multiplier, carry); \
+ ret += operation_n (rp, rp, p, size); \
+ \
+ free (p); \
+ return ret; \
+ }
+
+mp_limb_t
+refmpn_addmul_1c (mp_ptr rp, mp_srcptr sp, mp_size_t size,
+ mp_limb_t multiplier, mp_limb_t carry)
+{
+ AORSMUL_1C (refmpn_add_n);
+}
+mp_limb_t
+refmpn_submul_1c (mp_ptr rp, mp_srcptr sp, mp_size_t size,
+ mp_limb_t multiplier, mp_limb_t carry)
+{
+ AORSMUL_1C (refmpn_sub_n);
+}
+
+
+mp_limb_t
+refmpn_addmul_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t multiplier)
+{
+ return refmpn_addmul_1c (rp, sp, size, multiplier, CNST_LIMB(0));
+}
+mp_limb_t
+refmpn_submul_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t multiplier)
+{
+ return refmpn_submul_1c (rp, sp, size, multiplier, CNST_LIMB(0));
+}
+
+
+mp_limb_t
+refmpn_addmul_N (mp_ptr dst, mp_srcptr src, mp_size_t size,
+ mp_srcptr mult, mp_size_t msize)
+{
+ mp_ptr src_copy;
+ mp_limb_t ret;
+ mp_size_t i;
+
+ ASSERT (dst == src || ! refmpn_overlap_p (dst, size+msize-1, src, size));
+ ASSERT (! refmpn_overlap_p (dst, size+msize-1, mult, msize));
+ ASSERT (size >= msize);
+ ASSERT_MPN (mult, msize);
+
+ /* in case dst==src */
+ src_copy = refmpn_malloc_limbs (size);
+ refmpn_copyi (src_copy, src, size);
+ src = src_copy;
+
+ for (i = 0; i < msize-1; i++)
+ dst[size+i] = refmpn_addmul_1 (dst+i, src, size, mult[i]);
+ ret = refmpn_addmul_1 (dst+i, src, size, mult[i]);
+
+ free (src_copy);
+ return ret;
+}
+
+mp_limb_t
+refmpn_addmul_2 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 2);
+}
+mp_limb_t
+refmpn_addmul_3 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 3);
+}
+mp_limb_t
+refmpn_addmul_4 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 4);
+}
+mp_limb_t
+refmpn_addmul_5 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 5);
+}
+mp_limb_t
+refmpn_addmul_6 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 6);
+}
+mp_limb_t
+refmpn_addmul_7 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 7);
+}
+mp_limb_t
+refmpn_addmul_8 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_srcptr mult)
+{
+ return refmpn_addmul_N (rp, sp, size, mult, (mp_size_t) 8);
+}
+
+mp_limb_t
+refmpn_add_n_sub_nc (mp_ptr r1p, mp_ptr r2p,
+ mp_srcptr s1p, mp_srcptr s2p, mp_size_t size,
+ mp_limb_t carry)
+{
+ mp_ptr p;
+ mp_limb_t acy, scy;
+
+ /* Destinations can't overlap. */
+ ASSERT (! refmpn_overlap_p (r1p, size, r2p, size));
+ ASSERT (refmpn_overlap_fullonly_two_p (r1p, s1p, s2p, size));
+ ASSERT (refmpn_overlap_fullonly_two_p (r2p, s1p, s2p, size));
+ ASSERT (size >= 1);
+
+ /* in case r1p==s1p or r1p==s2p */
+ p = refmpn_malloc_limbs (size);
+
+ acy = refmpn_add_nc (p, s1p, s2p, size, carry >> 1);
+ scy = refmpn_sub_nc (r2p, s1p, s2p, size, carry & 1);
+ refmpn_copyi (r1p, p, size);
+
+ free (p);
+ return 2 * acy + scy;
+}
+
+mp_limb_t
+refmpn_add_n_sub_n (mp_ptr r1p, mp_ptr r2p,
+ mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ return refmpn_add_n_sub_nc (r1p, r2p, s1p, s2p, size, CNST_LIMB(0));
+}
+
+
+/* Right shift hi,lo and return the low limb of the result.
+ Note a shift by GMP_LIMB_BITS isn't assumed to work (doesn't on x86). */
+mp_limb_t
+rshift_make (mp_limb_t hi, mp_limb_t lo, unsigned shift)
+{
+ ASSERT (shift < GMP_NUMB_BITS);
+ if (shift == 0)
+ return lo;
+ else
+ return ((hi << (GMP_NUMB_BITS-shift)) | (lo >> shift)) & GMP_NUMB_MASK;
+}
+
+/* Left shift hi,lo and return the high limb of the result.
+ Note a shift by GMP_LIMB_BITS isn't assumed to work (doesn't on x86). */
+mp_limb_t
+lshift_make (mp_limb_t hi, mp_limb_t lo, unsigned shift)
+{
+ ASSERT (shift < GMP_NUMB_BITS);
+ if (shift == 0)
+ return hi;
+ else
+ return ((hi << shift) | (lo >> (GMP_NUMB_BITS-shift))) & GMP_NUMB_MASK;
+}
+
+
+mp_limb_t
+refmpn_rshift (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
+{
+ mp_limb_t ret;
+ mp_size_t i;
+
+ ASSERT (refmpn_overlap_low_to_high_p (rp, sp, size));
+ ASSERT (size >= 1);
+ ASSERT (shift >= 1 && shift < GMP_NUMB_BITS);
+ ASSERT_MPN (sp, size);
+
+ ret = rshift_make (sp[0], CNST_LIMB(0), shift);
+
+ for (i = 0; i < size-1; i++)
+ rp[i] = rshift_make (sp[i+1], sp[i], shift);
+
+ rp[i] = rshift_make (CNST_LIMB(0), sp[i], shift);
+ return ret;
+}
+
+mp_limb_t
+refmpn_lshift (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
+{
+ mp_limb_t ret;
+ mp_size_t i;
+
+ ASSERT (refmpn_overlap_high_to_low_p (rp, sp, size));
+ ASSERT (size >= 1);
+ ASSERT (shift >= 1 && shift < GMP_NUMB_BITS);
+ ASSERT_MPN (sp, size);
+
+ ret = lshift_make (CNST_LIMB(0), sp[size-1], shift);
+
+ for (i = size-2; i >= 0; i--)
+ rp[i+1] = lshift_make (sp[i+1], sp[i], shift);
+
+ rp[i+1] = lshift_make (sp[i+1], CNST_LIMB(0), shift);
+ return ret;
+}
+
+void
+refmpn_com (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ mp_size_t i;
+
+ /* We work downwards since mpn_lshiftc needs that. */
+ ASSERT (refmpn_overlap_high_to_low_p (rp, sp, size));
+
+ for (i = size - 1; i >= 0; i--)
+ rp[i] = (~sp[i]) & GMP_NUMB_MASK;
+}
+
+mp_limb_t
+refmpn_lshiftc (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
+{
+ mp_limb_t res;
+
+ /* No asserts here, refmpn_lshift will assert what we need. */
+
+ res = refmpn_lshift (rp, sp, size, shift);
+ refmpn_com (rp, rp, size);
+ return res;
+}
+
+/* accepting shift==0 and doing a plain copyi or copyd in that case */
+mp_limb_t
+refmpn_rshift_or_copy (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
+{
+ if (shift == 0)
+ {
+ refmpn_copyi (rp, sp, size);
+ return 0;
+ }
+ else
+ {
+ return refmpn_rshift (rp, sp, size, shift);
+ }
+}
+mp_limb_t
+refmpn_lshift_or_copy (mp_ptr rp, mp_srcptr sp, mp_size_t size, unsigned shift)
+{
+ if (shift == 0)
+ {
+ refmpn_copyd (rp, sp, size);
+ return 0;
+ }
+ else
+ {
+ return refmpn_lshift (rp, sp, size, shift);
+ }
+}
+
+/* accepting size==0 too */
+mp_limb_t
+refmpn_rshift_or_copy_any (mp_ptr rp, mp_srcptr sp, mp_size_t size,
+ unsigned shift)
+{
+ return (size == 0 ? 0 : refmpn_rshift_or_copy (rp, sp, size, shift));
+}
+mp_limb_t
+refmpn_lshift_or_copy_any (mp_ptr rp, mp_srcptr sp, mp_size_t size,
+ unsigned shift)
+{
+ return (size == 0 ? 0 : refmpn_lshift_or_copy (rp, sp, size, shift));
+}
+
+/* Divide h,l by d, return quotient, store remainder to *rp.
+ Operates on full limbs, not nails.
+ Must have h < d.
+ __udiv_qrnnd_c isn't simple, and it's a bit slow, but it works. */
+mp_limb_t
+refmpn_udiv_qrnnd (mp_limb_t *rp, mp_limb_t h, mp_limb_t l, mp_limb_t d)
+{
+ mp_limb_t q, r;
+ int n;
+
+ ASSERT (d != 0);
+ ASSERT (h < d);
+
+#if 0
+ udiv_qrnnd (q, r, h, l, d);
+ *rp = r;
+ return q;
+#endif
+
+ n = refmpn_count_leading_zeros (d);
+ d <<= n;
+
+ if (n != 0)
+ {
+ h = (h << n) | (l >> (GMP_LIMB_BITS - n));
+ l <<= n;
+ }
+
+ __udiv_qrnnd_c (q, r, h, l, d);
+ r >>= n;
+ *rp = r;
+ return q;
+}
+
+mp_limb_t
+refmpn_udiv_qrnnd_r (mp_limb_t h, mp_limb_t l, mp_limb_t d, mp_limb_t *rp)
+{
+ return refmpn_udiv_qrnnd (rp, h, l, d);
+}
+
+/* This little subroutine avoids some bad code generation from i386 gcc 3.0
+ -fPIC -O2 -fomit-frame-pointer (%ebp being used uninitialized). */
+static mp_limb_t
+refmpn_divmod_1c_workaround (mp_ptr rp, mp_srcptr sp, mp_size_t size,
+ mp_limb_t divisor, mp_limb_t carry)
+{
+ mp_size_t i;
+ mp_limb_t rem[1];
+ for (i = size-1; i >= 0; i--)
+ {
+ rp[i] = refmpn_udiv_qrnnd (rem, carry,
+ sp[i] << GMP_NAIL_BITS,
+ divisor << GMP_NAIL_BITS);
+ carry = *rem >> GMP_NAIL_BITS;
+ }
+ return carry;
+}
+
+mp_limb_t
+refmpn_divmod_1c (mp_ptr rp, mp_srcptr sp, mp_size_t size,
+ mp_limb_t divisor, mp_limb_t carry)
+{
+ mp_ptr sp_orig;
+ mp_ptr prod;
+ mp_limb_t carry_orig;
+
+ ASSERT (refmpn_overlap_fullonly_p (rp, sp, size));
+ ASSERT (size >= 0);
+ ASSERT (carry < divisor);
+ ASSERT_MPN (sp, size);
+ ASSERT_LIMB (divisor);
+ ASSERT_LIMB (carry);
+
+ if (size == 0)
+ return carry;
+
+ sp_orig = refmpn_memdup_limbs (sp, size);
+ prod = refmpn_malloc_limbs (size);
+ carry_orig = carry;
+
+ carry = refmpn_divmod_1c_workaround (rp, sp, size, divisor, carry);
+
+ /* check by multiplying back */
+#if 0
+ printf ("size=%ld divisor=0x%lX carry=0x%lX remainder=0x%lX\n",
+ size, divisor, carry_orig, carry);
+ mpn_trace("s",sp_copy,size);
+ mpn_trace("r",rp,size);
+ printf ("mul_1c %lX\n", refmpn_mul_1c (prod, rp, size, divisor, carry));
+ mpn_trace("p",prod,size);
+#endif
+ ASSERT (refmpn_mul_1c (prod, rp, size, divisor, carry) == carry_orig);
+ ASSERT (refmpn_cmp (prod, sp_orig, size) == 0);
+ free (sp_orig);
+ free (prod);
+
+ return carry;
+}
+
+mp_limb_t
+refmpn_divmod_1 (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t divisor)
+{
+ return refmpn_divmod_1c (rp, sp, size, divisor, CNST_LIMB(0));
+}
+
+
+mp_limb_t
+refmpn_mod_1c (mp_srcptr sp, mp_size_t size, mp_limb_t divisor,
+ mp_limb_t carry)
+{
+ mp_ptr p = refmpn_malloc_limbs (size);
+ carry = refmpn_divmod_1c (p, sp, size, divisor, carry);
+ free (p);
+ return carry;
+}
+
+mp_limb_t
+refmpn_mod_1 (mp_srcptr sp, mp_size_t size, mp_limb_t divisor)
+{
+ return refmpn_mod_1c (sp, size, divisor, CNST_LIMB(0));
+}
+
+mp_limb_t
+refmpn_preinv_mod_1 (mp_srcptr sp, mp_size_t size, mp_limb_t divisor,
+ mp_limb_t inverse)
+{
+ ASSERT (divisor & GMP_NUMB_HIGHBIT);
+ ASSERT (inverse == refmpn_invert_limb (divisor));
+ return refmpn_mod_1 (sp, size, divisor);
+}
+
+/* This implementation will be rather slow, but has the advantage of being
+ in a different style than the libgmp versions. */
+mp_limb_t
+refmpn_mod_34lsub1 (mp_srcptr p, mp_size_t n)
+{
+ ASSERT ((GMP_NUMB_BITS % 4) == 0);
+ return mpn_mod_1 (p, n, (CNST_LIMB(1) << (3 * GMP_NUMB_BITS / 4)) - 1);
+}
+
+
+mp_limb_t
+refmpn_divrem_1c (mp_ptr rp, mp_size_t xsize,
+ mp_srcptr sp, mp_size_t size, mp_limb_t divisor,
+ mp_limb_t carry)
+{
+ mp_ptr z;
+
+ z = refmpn_malloc_limbs (xsize);
+ refmpn_fill (z, xsize, CNST_LIMB(0));
+
+ carry = refmpn_divmod_1c (rp+xsize, sp, size, divisor, carry);
+ carry = refmpn_divmod_1c (rp, z, xsize, divisor, carry);
+
+ free (z);
+ return carry;
+}
+
+mp_limb_t
+refmpn_divrem_1 (mp_ptr rp, mp_size_t xsize,
+ mp_srcptr sp, mp_size_t size, mp_limb_t divisor)
+{
+ return refmpn_divrem_1c (rp, xsize, sp, size, divisor, CNST_LIMB(0));
+}
+
+mp_limb_t
+refmpn_preinv_divrem_1 (mp_ptr rp, mp_size_t xsize,
+ mp_srcptr sp, mp_size_t size,
+ mp_limb_t divisor, mp_limb_t inverse, unsigned shift)
+{
+ ASSERT (size >= 0);
+ ASSERT (shift == refmpn_count_leading_zeros (divisor));
+ ASSERT (inverse == refmpn_invert_limb (divisor << shift));
+
+ return refmpn_divrem_1 (rp, xsize, sp, size, divisor);
+}
+
+mp_limb_t
+refmpn_divrem_2 (mp_ptr qp, mp_size_t qxn,
+ mp_ptr np, mp_size_t nn,
+ mp_srcptr dp)
+{
+ mp_ptr tp;
+ mp_limb_t qh;
+
+ tp = refmpn_malloc_limbs (nn + qxn);
+ refmpn_zero (tp, qxn);
+ refmpn_copyi (tp + qxn, np, nn);
+ qh = refmpn_sb_div_qr (qp, tp, nn + qxn, dp, 2);
+ refmpn_copyi (np, tp, 2);
+ free (tp);
+ return qh;
+}
+
+/* Inverse is floor((b*(b-d)-1) / d), per division by invariant integers
+ paper, figure 8.1 m', where b=2^GMP_LIMB_BITS. Note that -d-1 < d
+ since d has the high bit set. */
+
+mp_limb_t
+refmpn_invert_limb (mp_limb_t d)
+{
+ mp_limb_t r;
+ ASSERT (d & GMP_LIMB_HIGHBIT);
+ return refmpn_udiv_qrnnd (&r, -d-1, MP_LIMB_T_MAX, d);
+}
+
+void
+refmpn_invert (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_ptr scratch)
+{
+ mp_ptr qp, tp;
+ TMP_DECL;
+ TMP_MARK;
+
+ tp = TMP_ALLOC_LIMBS (2 * n);
+ qp = TMP_ALLOC_LIMBS (n + 1);
+
+ MPN_ZERO (tp, 2 * n); mpn_sub_1 (tp, tp, 2 * n, 1);
+
+ refmpn_tdiv_qr (qp, rp, 0, tp, 2 * n, up, n);
+ refmpn_copyi (rp, qp, n);
+
+ TMP_FREE;
+}
+
+void
+refmpn_binvert (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_ptr scratch)
+{
+ mp_ptr tp;
+ mp_limb_t binv;
+ TMP_DECL;
+ TMP_MARK;
+
+ /* We use the library mpn_sbpi1_bdiv_q here, which isn't kosher in testing
+ code. To make up for it, we check that the inverse is correct using a
+ multiply. */
+
+ tp = TMP_ALLOC_LIMBS (2 * n);
+
+ MPN_ZERO (tp, n);
+ tp[0] = 1;
+ binvert_limb (binv, up[0]);
+ mpn_sbpi1_bdiv_q (rp, tp, n, up, n, -binv);
+
+ refmpn_mul_n (tp, rp, up, n);
+ ASSERT_ALWAYS (tp[0] == 1 && mpn_zero_p (tp + 1, n - 1));
+
+ TMP_FREE;
+}
+
+/* The aim is to produce a dst quotient and return a remainder c, satisfying
+ c*b^n + src-i == 3*dst, where i is the incoming carry.
+
+ Some value c==0, c==1 or c==2 will satisfy, so just try each.
+
+ If GMP_NUMB_BITS is even then 2^GMP_NUMB_BITS==1mod3 and a non-zero
+ remainder from the first division attempt determines the correct
+ remainder (3-c), but don't bother with that, since we can't guarantee
+ anything about GMP_NUMB_BITS when using nails.
+
+ If the initial src-i produces a borrow then refmpn_sub_1 leaves a twos
+ complement negative, ie. b^n+a-i, and the calculation produces c1
+ satisfying c1*b^n + b^n+src-i == 3*dst, from which clearly c=c1+1. This
+ means it's enough to just add any borrow back at the end.
+
+ A borrow only occurs when a==0 or a==1, and, by the same reasoning as in
+ mpn/generic/diveby3.c, the c1 that results in those cases will only be 0
+ or 1 respectively, so with 1 added the final return value is still in the
+ prescribed range 0 to 2. */
+
+mp_limb_t
+refmpn_divexact_by3c (mp_ptr rp, mp_srcptr sp, mp_size_t size, mp_limb_t carry)
+{
+ mp_ptr spcopy;
+ mp_limb_t c, cs;
+
+ ASSERT (refmpn_overlap_fullonly_p (rp, sp, size));
+ ASSERT (size >= 1);
+ ASSERT (carry <= 2);
+ ASSERT_MPN (sp, size);
+
+ spcopy = refmpn_malloc_limbs (size);
+ cs = refmpn_sub_1 (spcopy, sp, size, carry);
+
+ for (c = 0; c <= 2; c++)
+ if (refmpn_divmod_1c (rp, spcopy, size, CNST_LIMB(3), c) == 0)
+ goto done;
+ ASSERT_FAIL (no value of c satisfies);
+
+ done:
+ c += cs;
+ ASSERT (c <= 2);
+
+ free (spcopy);
+ return c;
+}
+
+mp_limb_t
+refmpn_divexact_by3 (mp_ptr rp, mp_srcptr sp, mp_size_t size)
+{
+ return refmpn_divexact_by3c (rp, sp, size, CNST_LIMB(0));
+}
+
+
+/* The same as mpn/generic/mul_basecase.c, but using refmpn functions. */
+void
+refmpn_mul_basecase (mp_ptr prodp,
+ mp_srcptr up, mp_size_t usize,
+ mp_srcptr vp, mp_size_t vsize)
+{
+ mp_size_t i;
+
+ ASSERT (! refmpn_overlap_p (prodp, usize+vsize, up, usize));
+ ASSERT (! refmpn_overlap_p (prodp, usize+vsize, vp, vsize));
+ ASSERT (usize >= vsize);
+ ASSERT (vsize >= 1);
+ ASSERT_MPN (up, usize);
+ ASSERT_MPN (vp, vsize);
+
+ prodp[usize] = refmpn_mul_1 (prodp, up, usize, vp[0]);
+ for (i = 1; i < vsize; i++)
+ prodp[usize+i] = refmpn_addmul_1 (prodp+i, up, usize, vp[i]);
+}
+
+
+/* The same as mpn/generic/mulmid_basecase.c, but using refmpn functions. */
+void
+refmpn_mulmid_basecase (mp_ptr rp,
+ mp_srcptr up, mp_size_t un,
+ mp_srcptr vp, mp_size_t vn)
+{
+ mp_limb_t cy;
+ mp_size_t i;
+
+ ASSERT (un >= vn);
+ ASSERT (vn >= 1);
+ ASSERT (! refmpn_overlap_p (rp, un - vn + 3, up, un));
+ ASSERT (! refmpn_overlap_p (rp, un - vn + 3, vp, vn));
+ ASSERT_MPN (up, un);
+ ASSERT_MPN (vp, vn);
+
+ rp[un - vn + 1] = refmpn_mul_1 (rp, up + vn - 1, un - vn + 1, vp[0]);
+ rp[un - vn + 2] = CNST_LIMB (0);
+ for (i = 1; i < vn; i++)
+ {
+ cy = refmpn_addmul_1 (rp, up + vn - i - 1, un - vn + 1, vp[i]);
+ cy = ref_addc_limb (&rp[un - vn + 1], rp[un - vn + 1], cy);
+ cy = ref_addc_limb (&rp[un - vn + 2], rp[un - vn + 2], cy);
+ ASSERT (cy == 0);
+ }
+}
+
+void
+refmpn_toom42_mulmid (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n,
+ mp_ptr scratch)
+{
+ refmpn_mulmid_basecase (rp, up, 2*n - 1, vp, n);
+}
+
+void
+refmpn_mulmid_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
+{
+ /* FIXME: this could be made faster by using refmpn_mul and then subtracting
+ off products near the middle product region boundary */
+ refmpn_mulmid_basecase (rp, up, 2*n - 1, vp, n);
+}
+
+void
+refmpn_mulmid (mp_ptr rp, mp_srcptr up, mp_size_t un,
+ mp_srcptr vp, mp_size_t vn)
+{
+ /* FIXME: this could be made faster by using refmpn_mul and then subtracting
+ off products near the middle product region boundary */
+ refmpn_mulmid_basecase (rp, up, un, vp, vn);
+}
+
+
+
+#define TOOM3_THRESHOLD (MAX (MUL_TOOM33_THRESHOLD, SQR_TOOM3_THRESHOLD))
+#define TOOM4_THRESHOLD (MAX (MUL_TOOM44_THRESHOLD, SQR_TOOM4_THRESHOLD))
+#define TOOM6_THRESHOLD (MAX (MUL_TOOM6H_THRESHOLD, SQR_TOOM6_THRESHOLD))
+#if WANT_FFT
+#define FFT_THRESHOLD (MAX (MUL_FFT_THRESHOLD, SQR_FFT_THRESHOLD))
+#else
+#define FFT_THRESHOLD MP_SIZE_T_MAX /* don't use toom44 here */
+#endif
+
+void
+refmpn_mul (mp_ptr wp, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn)
+{
+ mp_ptr tp;
+ mp_size_t tn;
+
+ if (vn < TOOM3_THRESHOLD)
+ {
+ /* In the mpn_mul_basecase and toom2 range, use our own mul_basecase. */
+ if (vn != 0)
+ refmpn_mul_basecase (wp, up, un, vp, vn);
+ else
+ MPN_ZERO (wp, un);
+ return;
+ }
+
+ if (vn < TOOM4_THRESHOLD)
+ {
+ /* In the toom3 range, use mpn_toom22_mul. */
+ tn = 2 * vn + mpn_toom22_mul_itch (vn, vn);
+ tp = refmpn_malloc_limbs (tn);
+ mpn_toom22_mul (tp, up, vn, vp, vn, tp + 2 * vn);
+ }
+ else if (vn < TOOM6_THRESHOLD)
+ {
+ /* In the toom4 range, use mpn_toom33_mul. */
+ tn = 2 * vn + mpn_toom33_mul_itch (vn, vn);
+ tp = refmpn_malloc_limbs (tn);
+ mpn_toom33_mul (tp, up, vn, vp, vn, tp + 2 * vn);
+ }
+ else if (vn < FFT_THRESHOLD)
+ {
+ /* In the toom6 range, use mpn_toom44_mul. */
+ tn = 2 * vn + mpn_toom44_mul_itch (vn, vn);
+ tp = refmpn_malloc_limbs (tn);
+ mpn_toom44_mul (tp, up, vn, vp, vn, tp + 2 * vn);
+ }
+ else
+ {
+ /* Finally, for the largest operands, use mpn_toom6h_mul. */
+ tn = 2 * vn + mpn_toom6h_mul_itch (vn, vn);
+ tp = refmpn_malloc_limbs (tn);
+ mpn_toom6h_mul (tp, up, vn, vp, vn, tp + 2 * vn);
+ }
+
+ if (un != vn)
+ {
+ if (un - vn < vn)
+ refmpn_mul (wp + vn, vp, vn, up + vn, un - vn);
+ else
+ refmpn_mul (wp + vn, up + vn, un - vn, vp, vn);
+
+ MPN_COPY (wp, tp, vn);
+ ASSERT_NOCARRY (refmpn_add (wp + vn, wp + vn, un, tp + vn, vn));
+ }
+ else
+ {
+ MPN_COPY (wp, tp, 2 * vn);
+ }
+
+ free (tp);
+}
+
+void
+refmpn_mul_n (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size)
+{
+ refmpn_mul (prodp, up, size, vp, size);
+}
+
+void
+refmpn_mullo_n (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size)
+{
+ mp_ptr tp = refmpn_malloc_limbs (2*size);
+ refmpn_mul (tp, up, size, vp, size);
+ refmpn_copyi (prodp, tp, size);
+ free (tp);
+}
+
+void
+refmpn_sqr (mp_ptr dst, mp_srcptr src, mp_size_t size)
+{
+ refmpn_mul (dst, src, size, src, size);
+}
+
+/* Allowing usize<vsize, usize==0 or vsize==0. */
+void
+refmpn_mul_any (mp_ptr prodp,
+ mp_srcptr up, mp_size_t usize,
+ mp_srcptr vp, mp_size_t vsize)
+{
+ ASSERT (! refmpn_overlap_p (prodp, usize+vsize, up, usize));
+ ASSERT (! refmpn_overlap_p (prodp, usize+vsize, vp, vsize));
+ ASSERT (usize >= 0);
+ ASSERT (vsize >= 0);
+ ASSERT_MPN (up, usize);
+ ASSERT_MPN (vp, vsize);
+
+ if (usize == 0)
+ {
+ refmpn_fill (prodp, vsize, CNST_LIMB(0));
+ return;
+ }
+
+ if (vsize == 0)
+ {
+ refmpn_fill (prodp, usize, CNST_LIMB(0));
+ return;
+ }
+
+ if (usize >= vsize)
+ refmpn_mul (prodp, up, usize, vp, vsize);
+ else
+ refmpn_mul (prodp, vp, vsize, up, usize);
+}
+
+
+mp_limb_t
+refmpn_gcd_1 (mp_srcptr xp, mp_size_t xsize, mp_limb_t y)
+{
+ mp_limb_t x;
+ int twos;
+
+ ASSERT (y != 0);
+ ASSERT (! refmpn_zero_p (xp, xsize));
+ ASSERT_MPN (xp, xsize);
+ ASSERT_LIMB (y);
+
+ x = refmpn_mod_1 (xp, xsize, y);
+ if (x == 0)
+ return y;
+
+ twos = 0;
+ while ((x & 1) == 0 && (y & 1) == 0)
+ {
+ x >>= 1;
+ y >>= 1;
+ twos++;
+ }
+
+ for (;;)
+ {
+ while ((x & 1) == 0) x >>= 1;
+ while ((y & 1) == 0) y >>= 1;
+
+ if (x < y)
+ MP_LIMB_T_SWAP (x, y);
+
+ x -= y;
+ if (x == 0)
+ break;
+ }
+
+ return y << twos;
+}
+
+
+/* Based on the full limb x, not nails. */
+unsigned
+refmpn_count_leading_zeros (mp_limb_t x)
+{
+ unsigned n = 0;
+
+ ASSERT (x != 0);
+
+ while ((x & GMP_LIMB_HIGHBIT) == 0)
+ {
+ x <<= 1;
+ n++;
+ }
+ return n;
+}
+
+/* Full limbs allowed, not limited to nails. */
+unsigned
+refmpn_count_trailing_zeros (mp_limb_t x)
+{
+ unsigned n = 0;
+
+ ASSERT (x != 0);
+ ASSERT_LIMB (x);
+
+ while ((x & 1) == 0)
+ {
+ x >>= 1;
+ n++;
+ }
+ return n;
+}
+
+/* Strip factors of two (low zero bits) from {p,size} by right shifting.
+ The return value is the number of twos stripped. */
+mp_size_t
+refmpn_strip_twos (mp_ptr p, mp_size_t size)
+{
+ mp_size_t limbs;
+ unsigned shift;
+
+ ASSERT (size >= 1);
+ ASSERT (! refmpn_zero_p (p, size));
+ ASSERT_MPN (p, size);
+
+ for (limbs = 0; p[0] == 0; limbs++)
+ {
+ refmpn_copyi (p, p+1, size-1);
+ p[size-1] = 0;
+ }
+
+ shift = refmpn_count_trailing_zeros (p[0]);
+ if (shift)
+ refmpn_rshift (p, p, size, shift);
+
+ return limbs*GMP_NUMB_BITS + shift;
+}
+
+mp_limb_t
+refmpn_gcd (mp_ptr gp, mp_ptr xp, mp_size_t xsize, mp_ptr yp, mp_size_t ysize)
+{
+ int cmp;
+
+ ASSERT (ysize >= 1);
+ ASSERT (xsize >= ysize);
+ ASSERT ((xp[0] & 1) != 0);
+ ASSERT ((yp[0] & 1) != 0);
+ /* ASSERT (xp[xsize-1] != 0); */ /* don't think x needs to be odd */
+ ASSERT (yp[ysize-1] != 0);
+ ASSERT (refmpn_overlap_fullonly_p (gp, xp, xsize));
+ ASSERT (refmpn_overlap_fullonly_p (gp, yp, ysize));
+ ASSERT (! refmpn_overlap_p (xp, xsize, yp, ysize));
+ if (xsize == ysize)
+ ASSERT (refmpn_msbone (xp[xsize-1]) >= refmpn_msbone (yp[ysize-1]));
+ ASSERT_MPN (xp, xsize);
+ ASSERT_MPN (yp, ysize);
+
+ refmpn_strip_twos (xp, xsize);
+ MPN_NORMALIZE (xp, xsize);
+ MPN_NORMALIZE (yp, ysize);
+
+ for (;;)
+ {
+ cmp = refmpn_cmp_twosizes (xp, xsize, yp, ysize);
+ if (cmp == 0)
+ break;
+ if (cmp < 0)
+ MPN_PTR_SWAP (xp,xsize, yp,ysize);
+
+ ASSERT_NOCARRY (refmpn_sub (xp, xp, xsize, yp, ysize));
+
+ refmpn_strip_twos (xp, xsize);
+ MPN_NORMALIZE (xp, xsize);
+ }
+
+ refmpn_copyi (gp, xp, xsize);
+ return xsize;
+}
+
+unsigned long
+ref_popc_limb (mp_limb_t src)
+{
+ unsigned long count;
+ int i;
+
+ count = 0;
+ for (i = 0; i < GMP_LIMB_BITS; i++)
+ {
+ count += (src & 1);
+ src >>= 1;
+ }
+ return count;
+}
+
+unsigned long
+refmpn_popcount (mp_srcptr sp, mp_size_t size)
+{
+ unsigned long count = 0;
+ mp_size_t i;
+
+ ASSERT (size >= 0);
+ ASSERT_MPN (sp, size);
+
+ for (i = 0; i < size; i++)
+ count += ref_popc_limb (sp[i]);
+ return count;
+}
+
+unsigned long
+refmpn_hamdist (mp_srcptr s1p, mp_srcptr s2p, mp_size_t size)
+{
+ mp_ptr d;
+ unsigned long count;
+
+ ASSERT (size >= 0);
+ ASSERT_MPN (s1p, size);
+ ASSERT_MPN (s2p, size);
+
+ if (size == 0)
+ return 0;
+
+ d = refmpn_malloc_limbs (size);
+ refmpn_xor_n (d, s1p, s2p, size);
+ count = refmpn_popcount (d, size);
+ free (d);
+ return count;
+}
+
+
+/* set r to a%d */
+void
+refmpn_mod2 (mp_limb_t r[2], const mp_limb_t a[2], const mp_limb_t d[2])
+{
+ mp_limb_t D[2];
+ int n;
+
+ ASSERT (! refmpn_overlap_p (r, (mp_size_t) 2, d, (mp_size_t) 2));
+ ASSERT_MPN (a, 2);
+ ASSERT_MPN (d, 2);
+
+ D[1] = d[1], D[0] = d[0];
+ r[1] = a[1], r[0] = a[0];
+ n = 0;
+
+ for (;;)
+ {
+ if (D[1] & GMP_NUMB_HIGHBIT)
+ break;
+ if (refmpn_cmp (r, D, (mp_size_t) 2) <= 0)
+ break;
+ refmpn_lshift (D, D, (mp_size_t) 2, 1);
+ n++;
+ ASSERT (n <= GMP_NUMB_BITS);
+ }
+
+ while (n >= 0)
+ {
+ if (refmpn_cmp (r, D, (mp_size_t) 2) >= 0)
+ ASSERT_NOCARRY (refmpn_sub_n (r, r, D, (mp_size_t) 2));
+ refmpn_rshift (D, D, (mp_size_t) 2, 1);
+ n--;
+ }
+
+ ASSERT (refmpn_cmp (r, d, (mp_size_t) 2) < 0);
+}
+
+
+
+/* Similar to the old mpn/generic/sb_divrem_mn.c, but somewhat simplified, in
+ particular the trial quotient is allowed to be 2 too big. */
+mp_limb_t
+refmpn_sb_div_qr (mp_ptr qp,
+ mp_ptr np, mp_size_t nsize,
+ mp_srcptr dp, mp_size_t dsize)
+{
+ mp_limb_t retval = 0;
+ mp_size_t i;
+ mp_limb_t d1 = dp[dsize-1];
+ mp_ptr np_orig = refmpn_memdup_limbs (np, nsize);
+
+ ASSERT (nsize >= dsize);
+ /* ASSERT (dsize > 2); */
+ ASSERT (dsize >= 2);
+ ASSERT (dp[dsize-1] & GMP_NUMB_HIGHBIT);
+ ASSERT (! refmpn_overlap_p (qp, nsize-dsize, np, nsize) || qp+dsize >= np);
+ ASSERT_MPN (np, nsize);
+ ASSERT_MPN (dp, dsize);
+
+ i = nsize-dsize;
+ if (refmpn_cmp (np+i, dp, dsize) >= 0)
+ {
+ ASSERT_NOCARRY (refmpn_sub_n (np+i, np+i, dp, dsize));
+ retval = 1;
+ }
+
+ for (i--; i >= 0; i--)
+ {
+ mp_limb_t n0 = np[i+dsize];
+ mp_limb_t n1 = np[i+dsize-1];
+ mp_limb_t q, dummy_r;
+
+ ASSERT (n0 <= d1);
+ if (n0 == d1)
+ q = GMP_NUMB_MAX;
+ else
+ q = refmpn_udiv_qrnnd (&dummy_r, n0, n1 << GMP_NAIL_BITS,
+ d1 << GMP_NAIL_BITS);
+
+ n0 -= refmpn_submul_1 (np+i, dp, dsize, q);
+ ASSERT (n0 == 0 || n0 == MP_LIMB_T_MAX);
+ if (n0)
+ {
+ q--;
+ if (! refmpn_add_n (np+i, np+i, dp, dsize))
+ {
+ q--;
+ ASSERT_CARRY (refmpn_add_n (np+i, np+i, dp, dsize));
+ }
+ }
+ np[i+dsize] = 0;
+
+ qp[i] = q;
+ }
+
+ /* remainder < divisor */
+#if 0 /* ASSERT triggers gcc 4.2.1 bug */
+ ASSERT (refmpn_cmp (np, dp, dsize) < 0);
+#endif
+
+ /* multiply back to original */
+ {
+ mp_ptr mp = refmpn_malloc_limbs (nsize);
+
+ refmpn_mul_any (mp, qp, nsize-dsize, dp, dsize);
+ if (retval)
+ ASSERT_NOCARRY (refmpn_add_n (mp+nsize-dsize,mp+nsize-dsize, dp, dsize));
+ ASSERT_NOCARRY (refmpn_add (mp, mp, nsize, np, dsize));
+ ASSERT (refmpn_cmp (mp, np_orig, nsize) == 0);
+
+ free (mp);
+ }
+
+ free (np_orig);
+ return retval;
+}
+
+/* Similar to the old mpn/generic/sb_divrem_mn.c, but somewhat simplified, in
+ particular the trial quotient is allowed to be 2 too big. */
+void
+refmpn_tdiv_qr (mp_ptr qp, mp_ptr rp, mp_size_t qxn,
+ mp_ptr np, mp_size_t nsize,
+ mp_srcptr dp, mp_size_t dsize)
+{
+ ASSERT (qxn == 0);
+ ASSERT_MPN (np, nsize);
+ ASSERT_MPN (dp, dsize);
+ ASSERT (dsize > 0);
+ ASSERT (dp[dsize-1] != 0);
+
+ if (dsize == 1)
+ {
+ rp[0] = refmpn_divmod_1 (qp, np, nsize, dp[0]);
+ return;
+ }
+ else
+ {
+ mp_ptr n2p = refmpn_malloc_limbs (nsize+1);
+ mp_ptr d2p = refmpn_malloc_limbs (dsize);
+ int norm = refmpn_count_leading_zeros (dp[dsize-1]) - GMP_NAIL_BITS;
+
+ n2p[nsize] = refmpn_lshift_or_copy (n2p, np, nsize, norm);
+ ASSERT_NOCARRY (refmpn_lshift_or_copy (d2p, dp, dsize, norm));
+
+ refmpn_sb_div_qr (qp, n2p, nsize+1, d2p, dsize);
+ refmpn_rshift_or_copy (rp, n2p, dsize, norm);
+
+ /* ASSERT (refmpn_zero_p (tp+dsize, nsize-dsize)); */
+ free (n2p);
+ free (d2p);
+ }
+}
+
+mp_limb_t
+refmpn_redc_1 (mp_ptr rp, mp_ptr up, mp_srcptr mp, mp_size_t n, mp_limb_t invm)
+{
+ mp_size_t j;
+ mp_limb_t cy;
+
+ ASSERT_MPN (up, 2*n);
+ /* ASSERT about directed overlap rp, up */
+ /* ASSERT about overlap rp, mp */
+ /* ASSERT about overlap up, mp */
+
+ for (j = n - 1; j >= 0; j--)
+ {
+ up[0] = refmpn_addmul_1 (up, mp, n, (up[0] * invm) & GMP_NUMB_MASK);
+ up++;
+ }
+ cy = mpn_add_n (rp, up, up - n, n);
+ return cy;
+}
+
+size_t
+refmpn_get_str (unsigned char *dst, int base, mp_ptr src, mp_size_t size)
+{
+ unsigned char *d;
+ size_t dsize;
+
+ ASSERT (size >= 0);
+ ASSERT (base >= 2);
+ ASSERT (base < numberof (mp_bases));
+ ASSERT (size == 0 || src[size-1] != 0);
+ ASSERT_MPN (src, size);
+
+ MPN_SIZEINBASE (dsize, src, size, base);
+ ASSERT (dsize >= 1);
+ ASSERT (! byte_overlap_p (dst, (mp_size_t) dsize, src, size * GMP_LIMB_BYTES));
+
+ if (size == 0)
+ {
+ dst[0] = 0;
+ return 1;
+ }
+
+ /* don't clobber input for power of 2 bases */
+ if (POW2_P (base))
+ src = refmpn_memdup_limbs (src, size);
+
+ d = dst + dsize;
+ do
+ {
+ d--;
+ ASSERT (d >= dst);
+ *d = refmpn_divrem_1 (src, (mp_size_t) 0, src, size, (mp_limb_t) base);
+ size -= (src[size-1] == 0);
+ }
+ while (size != 0);
+
+ /* Move result back and decrement dsize if we didn't generate
+ the maximum possible digits. */
+ if (d != dst)
+ {
+ size_t i;
+ dsize -= d - dst;
+ for (i = 0; i < dsize; i++)
+ dst[i] = d[i];
+ }
+
+ if (POW2_P (base))
+ free (src);
+
+ return dsize;
+}
+
+
+mp_limb_t
+ref_bswap_limb (mp_limb_t src)
+{
+ mp_limb_t dst;
+ int i;
+
+ dst = 0;
+ for (i = 0; i < GMP_LIMB_BYTES; i++)
+ {
+ dst = (dst << 8) + (src & 0xFF);
+ src >>= 8;
+ }
+ return dst;
+}
+
+
+/* These random functions are mostly for transitional purposes while adding
+ nail support, since they're independent of the normal mpn routines. They
+ can probably be removed when those normal routines are reliable, though
+ perhaps something independent would still be useful at times. */
+
+#if GMP_LIMB_BITS == 32
+#define RAND_A CNST_LIMB(0x29CF535)
+#endif
+#if GMP_LIMB_BITS == 64
+#define RAND_A CNST_LIMB(0xBAECD515DAF0B49D)
+#endif
+
+mp_limb_t refmpn_random_seed;
+
+mp_limb_t
+refmpn_random_half (void)
+{
+ refmpn_random_seed = refmpn_random_seed * RAND_A + 1;
+ return (refmpn_random_seed >> GMP_LIMB_BITS/2);
+}
+
+mp_limb_t
+refmpn_random_limb (void)
+{
+ return ((refmpn_random_half () << (GMP_LIMB_BITS/2))
+ | refmpn_random_half ()) & GMP_NUMB_MASK;
+}
+
+void
+refmpn_random (mp_ptr ptr, mp_size_t size)
+{
+ mp_size_t i;
+ if (GMP_NAIL_BITS == 0)
+ {
+ mpn_random (ptr, size);
+ return;
+ }
+
+ for (i = 0; i < size; i++)
+ ptr[i] = refmpn_random_limb ();
+}
+
+void
+refmpn_random2 (mp_ptr ptr, mp_size_t size)
+{
+ mp_size_t i;
+ mp_limb_t bit, mask, limb;
+ int run;
+
+ if (GMP_NAIL_BITS == 0)
+ {
+ mpn_random2 (ptr, size);
+ return;
+ }
+
+#define RUN_MODULUS 32
+
+ /* start with ones at a random pos in the high limb */
+ bit = CNST_LIMB(1) << (refmpn_random_half () % GMP_NUMB_BITS);
+ mask = 0;
+ run = 0;
+
+ for (i = size-1; i >= 0; i--)
+ {
+ limb = 0;
+ do
+ {
+ if (run == 0)
+ {
+ run = (refmpn_random_half () % RUN_MODULUS) + 1;
+ mask = ~mask;
+ }
+
+ limb |= (bit & mask);
+ bit >>= 1;
+ run--;
+ }
+ while (bit != 0);
+
+ ptr[i] = limb;
+ bit = GMP_NUMB_HIGHBIT;
+ }
+}
+
+/* This is a simple bitwise algorithm working high to low across "s" and
+ testing each time whether setting the bit would make s^2 exceed n. */
+mp_size_t
+refmpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr np, mp_size_t nsize)
+{
+ mp_ptr tp, dp;
+ mp_size_t ssize, talloc, tsize, dsize, ret, ilimbs;
+ unsigned ibit;
+ long i;
+ mp_limb_t c;
+
+ ASSERT (nsize >= 0);
+
+ /* If n==0, then s=0 and r=0. */
+ if (nsize == 0)
+ return 0;
+
+ ASSERT (np[nsize - 1] != 0);
+ ASSERT (rp == NULL || MPN_SAME_OR_SEPARATE_P (np, rp, nsize));
+ ASSERT (rp == NULL || ! MPN_OVERLAP_P (sp, (nsize + 1) / 2, rp, nsize));
+ ASSERT (! MPN_OVERLAP_P (sp, (nsize + 1) / 2, np, nsize));
+
+ /* root */
+ ssize = (nsize+1)/2;
+ refmpn_zero (sp, ssize);
+
+ /* the remainder so far */
+ dp = refmpn_memdup_limbs (np, nsize);
+ dsize = nsize;
+
+ /* temporary */
+ talloc = 2*ssize + 1;
+ tp = refmpn_malloc_limbs (talloc);
+
+ for (i = GMP_NUMB_BITS * ssize - 1; i >= 0; i--)
+ {
+ /* t = 2*s*2^i + 2^(2*i), being the amount s^2 will increase by if 2^i
+ is added to it */
+
+ ilimbs = (i+1) / GMP_NUMB_BITS;
+ ibit = (i+1) % GMP_NUMB_BITS;
+ refmpn_zero (tp, ilimbs);
+ c = refmpn_lshift_or_copy (tp+ilimbs, sp, ssize, ibit);
+ tsize = ilimbs + ssize;
+ tp[tsize] = c;
+ tsize += (c != 0);
+
+ ilimbs = (2*i) / GMP_NUMB_BITS;
+ ibit = (2*i) % GMP_NUMB_BITS;
+ if (ilimbs + 1 > tsize)
+ {
+ refmpn_zero_extend (tp, tsize, ilimbs + 1);
+ tsize = ilimbs + 1;
+ }
+ c = refmpn_add_1 (tp+ilimbs, tp+ilimbs, tsize-ilimbs,
+ CNST_LIMB(1) << ibit);
+ ASSERT (tsize < talloc);
+ tp[tsize] = c;
+ tsize += (c != 0);
+
+ if (refmpn_cmp_twosizes (dp, dsize, tp, tsize) >= 0)
+ {
+ /* set this bit in s and subtract from the remainder */
+ refmpn_setbit (sp, i);
+
+ ASSERT_NOCARRY (refmpn_sub_n (dp, dp, tp, dsize));
+ dsize = refmpn_normalize (dp, dsize);
+ }
+ }
+
+ if (rp == NULL)
+ {
+ ret = ! refmpn_zero_p (dp, dsize);
+ }
+ else
+ {
+ ASSERT (dsize == 0 || dp[dsize-1] != 0);
+ refmpn_copy (rp, dp, dsize);
+ ret = dsize;
+ }
+
+ free (dp);
+ free (tp);
+ return ret;
+}
diff --git a/gmp/tests/refmpq.c b/gmp/tests/refmpq.c
new file mode 100644
index 0000000000..6ca51c4bc5
--- /dev/null
+++ b/gmp/tests/refmpq.c
@@ -0,0 +1,41 @@
+/* Reference rational routines.
+
+Copyright 2001 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 "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+void
+refmpq_add (mpq_ptr w, mpq_srcptr x, mpq_srcptr y)
+{
+ mpz_mul (mpq_numref(w), mpq_numref(x), mpq_denref(y));
+ mpz_addmul (mpq_numref(w), mpq_denref(x), mpq_numref(y));
+ mpz_mul (mpq_denref(w), mpq_denref(x), mpq_denref(y));
+ mpq_canonicalize (w);
+}
+
+void
+refmpq_sub (mpq_ptr w, mpq_srcptr x, mpq_srcptr y)
+{
+ mpz_mul (mpq_numref(w), mpq_numref(x), mpq_denref(y));
+ mpz_submul (mpq_numref(w), mpq_denref(x), mpq_numref(y));
+ mpz_mul (mpq_denref(w), mpq_denref(x), mpq_denref(y));
+ mpq_canonicalize (w);
+}
diff --git a/gmp/tests/refmpz.c b/gmp/tests/refmpz.c
new file mode 100644
index 0000000000..2aef7aaa87
--- /dev/null
+++ b/gmp/tests/refmpz.c
@@ -0,0 +1,298 @@
+/* Reference mpz functions.
+
+Copyright 1997, 1999-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/. */
+
+/* always do assertion checking */
+#define WANT_ASSERT 1
+
+#include <stdio.h>
+#include <stdlib.h> /* for free */
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+
+/* Change this to "#define TRACE(x) x" for some traces. */
+#define TRACE(x)
+
+
+/* FIXME: Shouldn't use plain mpz functions in a reference routine. */
+void
+refmpz_combit (mpz_ptr r, unsigned long bit)
+{
+ if (mpz_tstbit (r, bit))
+ mpz_clrbit (r, bit);
+ else
+ mpz_setbit (r, bit);
+}
+
+
+unsigned long
+refmpz_hamdist (mpz_srcptr x, mpz_srcptr y)
+{
+ mp_size_t xsize, ysize, tsize;
+ mp_ptr xp, yp;
+ unsigned long ret;
+
+ if ((SIZ(x) < 0 && SIZ(y) >= 0)
+ || (SIZ(y) < 0 && SIZ(x) >= 0))
+ return ULONG_MAX;
+
+ xsize = ABSIZ(x);
+ ysize = ABSIZ(y);
+ tsize = MAX (xsize, ysize);
+
+ xp = refmpn_malloc_limbs (tsize);
+ refmpn_zero (xp, tsize);
+ refmpn_copy (xp, PTR(x), xsize);
+
+ yp = refmpn_malloc_limbs (tsize);
+ refmpn_zero (yp, tsize);
+ refmpn_copy (yp, PTR(y), ysize);
+
+ if (SIZ(x) < 0)
+ refmpn_neg (xp, xp, tsize);
+
+ if (SIZ(x) < 0)
+ refmpn_neg (yp, yp, tsize);
+
+ ret = refmpn_hamdist (xp, yp, tsize);
+
+ free (xp);
+ free (yp);
+ return ret;
+}
+
+
+/* (0/b), with mpz b; is 1 if b=+/-1, 0 otherwise */
+#define JACOBI_0Z(b) JACOBI_0LS (PTR(b)[0], SIZ(b))
+
+/* (a/b) effect due to sign of b: mpz/mpz */
+#define JACOBI_BSGN_ZZ_BIT1(a, b) JACOBI_BSGN_SS_BIT1 (SIZ(a), SIZ(b))
+
+/* (a/b) effect due to sign of a: mpz/unsigned-mpz, b odd;
+ is (-1/b) if a<0, or +1 if a>=0 */
+#define JACOBI_ASGN_ZZU_BIT1(a, b) JACOBI_ASGN_SU_BIT1 (SIZ(a), PTR(b)[0])
+
+int
+refmpz_kronecker (mpz_srcptr a_orig, mpz_srcptr b_orig)
+{
+ unsigned long twos;
+ mpz_t a, b;
+ int result_bit1 = 0;
+
+ if (mpz_sgn (b_orig) == 0)
+ return JACOBI_Z0 (a_orig); /* (a/0) */
+
+ if (mpz_sgn (a_orig) == 0)
+ return JACOBI_0Z (b_orig); /* (0/b) */
+
+ if (mpz_even_p (a_orig) && mpz_even_p (b_orig))
+ return 0;
+
+ if (mpz_cmp_ui (b_orig, 1) == 0)
+ return 1;
+
+ mpz_init_set (a, a_orig);
+ mpz_init_set (b, b_orig);
+
+ if (mpz_sgn (b) < 0)
+ {
+ result_bit1 ^= JACOBI_BSGN_ZZ_BIT1 (a, b);
+ mpz_neg (b, b);
+ }
+ if (mpz_even_p (b))
+ {
+ twos = mpz_scan1 (b, 0L);
+ mpz_tdiv_q_2exp (b, b, twos);
+ result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, PTR(a)[0]);
+ }
+
+ if (mpz_sgn (a) < 0)
+ {
+ result_bit1 ^= JACOBI_N1B_BIT1 (PTR(b)[0]);
+ mpz_neg (a, a);
+ }
+ if (mpz_even_p (a))
+ {
+ twos = mpz_scan1 (a, 0L);
+ mpz_tdiv_q_2exp (a, a, twos);
+ result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, PTR(b)[0]);
+ }
+
+ for (;;)
+ {
+ ASSERT (mpz_odd_p (a));
+ ASSERT (mpz_odd_p (b));
+ ASSERT (mpz_sgn (a) > 0);
+ ASSERT (mpz_sgn (b) > 0);
+
+ TRACE (printf ("top\n");
+ mpz_trace (" a", a);
+ mpz_trace (" b", b));
+
+ if (mpz_cmp (a, b) < 0)
+ {
+ TRACE (printf ("swap\n"));
+ mpz_swap (a, b);
+ result_bit1 ^= JACOBI_RECIP_UU_BIT1 (PTR(a)[0], PTR(b)[0]);
+ }
+
+ if (mpz_cmp_ui (b, 1) == 0)
+ break;
+
+ mpz_sub (a, a, b);
+ TRACE (printf ("sub\n");
+ mpz_trace (" a", a));
+ if (mpz_sgn (a) == 0)
+ goto zero;
+
+ twos = mpz_scan1 (a, 0L);
+ mpz_fdiv_q_2exp (a, a, twos);
+ TRACE (printf ("twos %lu\n", twos);
+ mpz_trace (" a", a));
+ result_bit1 ^= JACOBI_TWOS_U_BIT1 (twos, PTR(b)[0]);
+ }
+
+ mpz_clear (a);
+ mpz_clear (b);
+ return JACOBI_BIT1_TO_PN (result_bit1);
+
+ zero:
+ mpz_clear (a);
+ mpz_clear (b);
+ return 0;
+}
+
+/* Same as mpz_kronecker, but ignoring factors of 2 on b */
+int
+refmpz_jacobi (mpz_srcptr a, mpz_srcptr b)
+{
+ ASSERT_ALWAYS (mpz_sgn (b) > 0);
+ ASSERT_ALWAYS (mpz_odd_p (b));
+
+ return refmpz_kronecker (a, b);
+}
+
+/* Legendre symbol via powm. p must be an odd prime. */
+int
+refmpz_legendre (mpz_srcptr a, mpz_srcptr p)
+{
+ int res;
+
+ mpz_t r;
+ mpz_t e;
+
+ ASSERT_ALWAYS (mpz_sgn (p) > 0);
+ ASSERT_ALWAYS (mpz_odd_p (p));
+
+ mpz_init (r);
+ mpz_init (e);
+
+ mpz_fdiv_r (r, a, p);
+
+ mpz_set (e, p);
+ mpz_sub_ui (e, e, 1);
+ mpz_fdiv_q_2exp (e, e, 1);
+ mpz_powm (r, r, e, p);
+
+ /* Normalize to a more or less symmetric range around zero */
+ if (mpz_cmp (r, e) > 0)
+ mpz_sub (r, r, p);
+
+ ASSERT_ALWAYS (mpz_cmpabs_ui (r, 1) <= 0);
+
+ res = mpz_sgn (r);
+
+ mpz_clear (r);
+ mpz_clear (e);
+
+ return res;
+}
+
+
+int
+refmpz_kronecker_ui (mpz_srcptr a, unsigned long b)
+{
+ mpz_t bz;
+ int ret;
+ mpz_init_set_ui (bz, b);
+ ret = refmpz_kronecker (a, bz);
+ mpz_clear (bz);
+ return ret;
+}
+
+int
+refmpz_kronecker_si (mpz_srcptr a, long b)
+{
+ mpz_t bz;
+ int ret;
+ mpz_init_set_si (bz, b);
+ ret = refmpz_kronecker (a, bz);
+ mpz_clear (bz);
+ return ret;
+}
+
+int
+refmpz_ui_kronecker (unsigned long a, mpz_srcptr b)
+{
+ mpz_t az;
+ int ret;
+ mpz_init_set_ui (az, a);
+ ret = refmpz_kronecker (az, b);
+ mpz_clear (az);
+ return ret;
+}
+
+int
+refmpz_si_kronecker (long a, mpz_srcptr b)
+{
+ mpz_t az;
+ int ret;
+ mpz_init_set_si (az, a);
+ ret = refmpz_kronecker (az, b);
+ mpz_clear (az);
+ return ret;
+}
+
+
+void
+refmpz_pow_ui (mpz_ptr w, mpz_srcptr b, unsigned long e)
+{
+ mpz_t s, t;
+ unsigned long i;
+
+ mpz_init_set_ui (t, 1L);
+ mpz_init_set (s, b);
+
+ if ((e & 1) != 0)
+ mpz_mul (t, t, s);
+
+ for (i = 2; i <= e; i <<= 1)
+ {
+ mpz_mul (s, s, s);
+ if ((i & e) != 0)
+ mpz_mul (t, t, s);
+ }
+
+ mpz_set (w, t);
+
+ mpz_clear (s);
+ mpz_clear (t);
+}
diff --git a/gmp/tests/spinner.c b/gmp/tests/spinner.c
new file mode 100644
index 0000000000..3435d20923
--- /dev/null
+++ b/gmp/tests/spinner.c
@@ -0,0 +1,129 @@
+/* A stupid little spinning wheel designed to make it look like useful work
+ is being done.
+
+Copyright 1999-2001 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 <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for isatty */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#include "tests.h"
+
+
+/* "alarm" is not available on mingw32, and the SIGALRM constant is not
+ defined. Don't bother with a spinner in this case. */
+#if ! HAVE_ALARM || ! defined (SIGALRM)
+#define alarm(n) abort()
+#define signal(sig,func) SIG_ERR
+#endif
+
+
+/* An application can update this to get a count printed with the spinner.
+ If left at 0, no count is printed. */
+
+unsigned long spinner_count = 0;
+
+
+int spinner_wanted = -1; /* -1 uninitialized, 1 wanted, 0 not */
+int spinner_tick = 1; /* 1 ready to print, 0 not */
+
+
+/*ARGSUSED*/
+RETSIGTYPE
+spinner_signal (int signum)
+{
+ spinner_tick = 1;
+
+ if (signal (SIGALRM, spinner_signal) == SIG_ERR)
+ {
+ printf ("spinner_signal(): Oops, cannot reinstall SIGALRM\n");
+ abort ();
+ }
+ alarm (1);
+}
+
+
+/* Initialize the spinner.
+
+ This is done the first time spinner() is called, so an application
+ doesn't need to call this directly.
+
+ The spinner is only wanted if the output is a tty. */
+
+#define SPINNER_WANTED_INIT() \
+ if (spinner_wanted < 0) spinner_init ()
+
+void
+spinner_init (void)
+{
+ spinner_wanted = isatty (fileno (stdout));
+ if (spinner_wanted == -1)
+ abort ();
+
+ if (!spinner_wanted)
+ return;
+
+ if (signal (SIGALRM, spinner_signal) == SIG_ERR)
+ {
+ printf ("(no spinner)\r");
+ spinner_tick = 0;
+ return;
+ }
+ alarm (1);
+
+ /* unbuffered output so the spinner will show up */
+ setbuf (stdout, NULL);
+}
+
+
+void
+spinner (void)
+{
+ static const char data[] = { '|', '/', '-', '\\' };
+ static int pos = 0;
+
+ char buf[128];
+
+ SPINNER_WANTED_INIT ();
+
+ if (spinner_tick)
+ {
+ buf[0] = data[pos];
+ pos = (pos + 1) % numberof (data);
+ spinner_tick = 0;
+
+ if (spinner_count != 0)
+ {
+ sprintf (buf+1, " %lu\r", spinner_count);
+ }
+ else
+ {
+ buf[1] = '\r';
+ buf[2] = '\0';
+ }
+ fputs (buf, stdout);
+ }
+}
diff --git a/gmp/tests/t-bswap.c b/gmp/tests/t-bswap.c
new file mode 100644
index 0000000000..2543f9fc32
--- /dev/null
+++ b/gmp/tests/t-bswap.c
@@ -0,0 +1,71 @@
+/* Test BSWAP_LIMB.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+int
+main (void)
+{
+ mp_limb_t src, want, got;
+ int i;
+
+ tests_start ();
+ mp_trace_base = -16;
+
+ for (i = 0; i < 1000; i++)
+ {
+ mpn_random (&src, (mp_size_t) 1);
+
+ want = ref_bswap_limb (src);
+
+ BSWAP_LIMB (got, src);
+ if (got != want)
+ {
+ printf ("BSWAP_LIMB wrong result\n");
+ error:
+ mpn_trace (" src ", &src, (mp_size_t) 1);
+ mpn_trace (" want", &want, (mp_size_t) 1);
+ mpn_trace (" got ", &got, (mp_size_t) 1);
+ abort ();
+ }
+
+ BSWAP_LIMB_FETCH (got, &src);
+ if (got != want)
+ {
+ printf ("BSWAP_LIMB_FETCH wrong result\n");
+ goto error;
+ }
+
+ BSWAP_LIMB_STORE (&got, src);
+ if (got != want)
+ {
+ printf ("BSWAP_LIMB_STORE wrong result\n");
+ goto error;
+ }
+ }
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/t-constants.c b/gmp/tests/t-constants.c
new file mode 100644
index 0000000000..8583ccd4d6
--- /dev/null
+++ b/gmp/tests/t-constants.c
@@ -0,0 +1,352 @@
+/* Check the values of some constants.
+
+Copyright 2000-2003, 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "tests.h"
+
+
+#ifdef ULONG_MAX
+const char *ulong_max_def = "defined";
+#else
+const char *ulong_max_def = "not defined";
+#endif
+#ifdef LONG_MAX
+const char *long_max_def = "defined";
+#else
+const char *long_max_def = "not defined";
+#endif
+
+#ifdef UINT_MAX
+const char *uint_max_def = "defined";
+#else
+const char *uint_max_def = "not defined";
+#endif
+#ifdef INT_MAX
+const char *int_max_def = "defined";
+#else
+const char *int_max_def = "not defined";
+#endif
+
+#ifdef USHRT_MAX
+const char *ushrt_max_def = "defined";
+#else
+const char *ushrt_max_def = "not defined";
+#endif
+#ifdef SHRT_MAX
+const char *shrt_max_def = "defined";
+#else
+const char *shrt_max_def = "not defined";
+#endif
+
+#include "gmp-impl.h"
+#include "longlong.h"
+
+
+#ifdef _LONG_LONG_LIMB
+#define LL(l,ll) ll
+#else
+#define LL(l,ll) l
+#endif
+
+#if __GMP_MP_SIZE_T_INT
+#define SS(i,l) i
+#else
+#define SS(i,l) l
+#endif
+
+
+#define CHECK_LIMB_S(x, xname, y, yname) \
+ do { \
+ if ((x) != (y)) \
+ { \
+ printf (LL("%s == %lx, but %s == %lx\n", \
+ "%s == %llx, but %s == %llx\n"), \
+ xname, x, yname, y); \
+ error = 1; \
+ } \
+ } while (0)
+
+#define CHECK_INT_S(x, xname, y, yname) \
+ do { \
+ if ((x) != (y)) \
+ { \
+ printf ("%s == %d, but %s == %d\n", xname, x, yname, y); \
+ error = 1; \
+ } \
+ } while (0)
+
+
+
+#define CHECK_CONDITION_S(x, xname) \
+ do { \
+ if (!(x)) \
+ { \
+ printf ("%s is false\n", xname); \
+ error = 1; \
+ } \
+ } while (0)
+
+
+/* How many bits seem to work in the given type. */
+#define CALC_BITS(result, type) \
+ do { \
+ type n = 1; \
+ result = 0; \
+ while (n != 0) \
+ { \
+ n <<= 1; \
+ result++; \
+ } \
+ } while (0)
+
+#define CHECK_BITS_S(constant, constant_name, type) \
+ do { \
+ int calculated; \
+ CALC_BITS (calculated, type); \
+ if (calculated != constant) \
+ { \
+ printf ("%s == %d, but calculated %d\n", \
+ constant_name, constant, calculated); \
+ error = 1; \
+ } \
+ } while (0)
+
+
+#define CHECK_HIGHBIT_S(value, value_name, type, format) \
+ do { \
+ type n = value; \
+ if (n == 0) \
+ { \
+ printf ("%s == 0\n", value_name); \
+ error = 1; \
+ } \
+ n <<= 1; \
+ if (n != 0) \
+ { \
+ printf ("%s << 1 = ", value_name); \
+ printf (format, n); \
+ printf (" != 0\n"); \
+ error = 1; \
+ } \
+ } while (0)
+
+
+#define CHECK_MAX_S(max_val, max_name, min_val, min_name, type, format) \
+ do { \
+ type maxval = max_val; \
+ type minval = min_val; \
+ type n = maxval; \
+ n++; \
+ if (n != minval) \
+ { \
+ printf ("%s + 1 = ", max_name); \
+ printf (format, n); \
+ printf (" != %s = ", min_name); \
+ printf (format, minval); \
+ printf ("\n"); \
+ error = 1; \
+ } \
+ if (maxval <= minval) \
+ { \
+ printf ("%s = ", max_name); \
+ printf (format, maxval); \
+ printf (" <= %s = ", min_name); \
+ printf (format, minval); \
+ printf ("\n"); \
+ error = 1; \
+ } \
+ } while (0)
+
+
+#if HAVE_STRINGIZE
+#define CHECK_LIMB(x,y) CHECK_LIMB_S (x, #x, y, #y)
+#define CHECK_INT(x,y) CHECK_INT_S (x, #x, y, #y)
+#define CHECK_CONDITION(x) CHECK_CONDITION_S (x, #x)
+#define CHECK_BITS(c,t) CHECK_BITS_S (c, #c, t)
+#define CHECK_MAX(m,n,t,f) CHECK_MAX_S (m, #m, n, #n, t, f)
+#define CHECK_HIGHBIT(n,t,f) CHECK_HIGHBIT_S (n, #n, t, f)
+#else
+#define CHECK_LIMB(x,y) CHECK_LIMB_S (x, "x", y, "y")
+#define CHECK_INT(x,y) CHECK_INT_S (x, "x", y, "y")
+#define CHECK_CONDITION(x) CHECK_CONDITION_S (x, "x")
+#define CHECK_BITS(c,t) CHECK_BITS_S (c, "c", t)
+#define CHECK_MAX(m,n,t,f) CHECK_MAX_S (m, "m", n, "n", t, f)
+#define CHECK_HIGHBIT(n,t,f) CHECK_HIGHBIT_S (n, "n", t, f)
+#endif
+
+
+/* The tests below marked "Bad!" fail on Cray T90 systems, where int, short
+ and mp_size_t are 48 bits or some such but don't wraparound in a plain
+ twos complement fashion. In particular,
+
+ INT_HIGHBIT << 1 = 0xFFFFC00000000000 != 0
+ INT_MAX + 1 = 35184372088832 != INT_MIN = -35184372088832
+
+ This is a bit bizarre, but doesn't matter because GMP doesn't rely on any
+ particular overflow behaviour for int or short, only for mp_limb_t. */
+
+int
+main (int argc, char *argv[])
+{
+ int error = 0;
+
+ CHECK_INT (GMP_LIMB_BYTES, (int) sizeof(mp_limb_t));
+ CHECK_INT (mp_bits_per_limb, GMP_LIMB_BITS);
+
+ CHECK_BITS (GMP_LIMB_BITS, mp_limb_t);
+ CHECK_BITS (BITS_PER_ULONG, unsigned long);
+
+ CHECK_HIGHBIT (GMP_LIMB_HIGHBIT, mp_limb_t, LL("0x%lX","0x%llX"));
+ CHECK_HIGHBIT (ULONG_HIGHBIT, unsigned long, "0x%lX");
+ CHECK_HIGHBIT (UINT_HIGHBIT, unsigned int, "0x%X");
+ CHECK_HIGHBIT (USHRT_HIGHBIT, unsigned short, "0x%hX");
+#if 0 /* Bad! */
+ CHECK_HIGHBIT (LONG_HIGHBIT, long, "0x%lX");
+ CHECK_HIGHBIT (INT_HIGHBIT, int, "0x%X");
+ CHECK_HIGHBIT (SHRT_HIGHBIT, short, "0x%hX");
+#endif
+
+#if 0 /* Bad! */
+ CHECK_MAX (LONG_MAX, LONG_MIN, long, "%ld");
+ CHECK_MAX (INT_MAX, INT_MIN, int, "%d");
+ CHECK_MAX (SHRT_MAX, SHRT_MIN, short, "%hd");
+#endif
+ CHECK_MAX (ULONG_MAX, 0, unsigned long, "%lu");
+ CHECK_MAX (UINT_MAX, 0, unsigned int, "%u");
+ CHECK_MAX (USHRT_MAX, 0, unsigned short, "%hu");
+#if 0 /* Bad! */
+ CHECK_MAX (MP_SIZE_T_MAX, MP_SIZE_T_MIN, mp_size_t, SS("%d","%ld"));
+#endif
+
+ /* UHWtype should have at least enough bits for half a UWtype */
+ {
+ int bits_per_UWtype, bits_per_UHWtype;
+ CALC_BITS (bits_per_UWtype, UWtype);
+ CALC_BITS (bits_per_UHWtype, UHWtype);
+ CHECK_CONDITION (2*bits_per_UHWtype >= bits_per_UWtype);
+ }
+
+ ASSERT_ALWAYS_LIMB (MODLIMB_INVERSE_3);
+ {
+ mp_limb_t modlimb_inverse_3_calc;
+ binvert_limb (modlimb_inverse_3_calc, CNST_LIMB(3));
+ ASSERT_ALWAYS_LIMB (modlimb_inverse_3_calc);
+ CHECK_LIMB (MODLIMB_INVERSE_3, modlimb_inverse_3_calc);
+ }
+ {
+ mp_limb_t MODLIMB_INVERSE_3_times_3
+ = (MODLIMB_INVERSE_3 * CNST_LIMB(3)) & GMP_NUMB_MASK;
+ CHECK_LIMB (MODLIMB_INVERSE_3_times_3, CNST_LIMB(1));
+ }
+
+ {
+ mp_limb_t hi, lo;
+ hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_MAX_DIV3-1,
+ CNST_LIMB(3) << GMP_NAIL_BITS);
+ if (! (hi < 1))
+ {
+ printf ("GMP_NUMB_CEIL_MAX_DIV3 too big\n");
+ error = 1;
+ }
+ hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_MAX_DIV3,
+ CNST_LIMB(3) << GMP_NAIL_BITS);
+ if (! (hi >= 1))
+ {
+ printf ("GMP_NUMB_CEIL_MAX_DIV3 too small\n");
+ error = 1;
+ }
+ }
+
+ {
+ mp_limb_t hi, lo;
+ hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_2MAX_DIV3-1,
+ CNST_LIMB(3) << GMP_NAIL_BITS);
+ if (! (hi < 2))
+ {
+ printf ("GMP_NUMB_CEIL_2MAX_DIV3 too big\n");
+ error = 1;
+ }
+ hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_2MAX_DIV3,
+ CNST_LIMB(3) << GMP_NAIL_BITS);
+ if (! (hi >= 2))
+ {
+ printf ("GMP_NUMB_CEIL_2MAX_DIV3 too small\n");
+ error = 1;
+ }
+ }
+
+#ifdef PP_INVERTED
+ {
+ mp_limb_t pp_inverted_calc;
+ invert_limb (pp_inverted_calc, PP);
+ CHECK_LIMB (PP_INVERTED, pp_inverted_calc);
+ }
+#endif
+
+ if (argc >= 2 || error)
+ {
+ int bits;
+
+ printf ("\n");
+ printf ("After gmp.h,\n");
+ printf (" ULONG_MAX %s\n", ulong_max_def);
+ printf (" LONG_MAX %s\n", long_max_def);
+ printf (" UINT_MAX %s\n", uint_max_def);
+ printf (" INT_MAX %s\n", int_max_def);
+ printf (" USHRT_MAX %s\n", ushrt_max_def);
+ printf (" SHRT_MAX %s\n", shrt_max_def);
+ printf ("\n");
+
+#ifdef _CRAY
+ printf ("_CRAY is defined, so limits.h is being used\n");
+#endif
+
+ printf ("ULONG_MAX %lX\n", ULONG_MAX);
+ printf ("ULONG_HIGHBIT %lX\n", ULONG_HIGHBIT);
+ printf ("LONG_MAX %lX\n", LONG_MAX);
+ printf ("LONG_MIN %lX\n", LONG_MIN);
+
+ printf ("UINT_MAX %X\n", UINT_MAX);
+ printf ("UINT_HIGHBIT %X\n", UINT_HIGHBIT);
+ printf ("INT_MAX %X\n", INT_MAX);
+ printf ("INT_MIN %X\n", INT_MIN);
+
+ printf ("USHRT_MAX %X\n", USHRT_MAX);
+ printf ("USHRT_HIGHBIT %X\n", USHRT_HIGHBIT);
+ printf ("SHRT_MAX %X\n", SHRT_MAX);
+ printf ("SHRT_MIN %X\n", SHRT_MIN);
+
+ printf ("\n");
+ printf ("Bits\n");
+ CALC_BITS (bits, long); printf (" long %d\n", bits);
+ CALC_BITS (bits, int); printf (" int %d\n", bits);
+ CALC_BITS (bits, short); printf (" short %d\n", bits);
+ CALC_BITS (bits, unsigned long); printf (" unsigned long %d\n", bits);
+ CALC_BITS (bits, unsigned int); printf (" unsigned int %d\n", bits);
+ CALC_BITS (bits, unsigned short); printf (" unsigned short %d\n", bits);
+ CALC_BITS (bits, mp_size_t); printf (" mp_size_t %d\n", bits);
+ }
+
+ if (error)
+ abort ();
+
+ exit (0);
+}
diff --git a/gmp/tests/t-count_zeros.c b/gmp/tests/t-count_zeros.c
new file mode 100644
index 0000000000..117babadc6
--- /dev/null
+++ b/gmp/tests/t-count_zeros.c
@@ -0,0 +1,87 @@
+/* Test count_leading_zeros and count_trailing_zeros.
+
+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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+void
+check_clz (int want, mp_limb_t n)
+{
+ int got;
+ count_leading_zeros (got, n);
+ if (got != want)
+ {
+ printf ("count_leading_zeros wrong\n");
+ mp_limb_trace (" n ", n);
+ printf (" want %d\n", want);
+ printf (" got %d\n", got);
+ abort ();
+ }
+}
+
+void
+check_ctz (int want, mp_limb_t n)
+{
+ int got;
+ count_trailing_zeros (got, n);
+ if (got != want)
+ {
+ printf ("count_trailing_zeros wrong\n");
+ mpn_trace (" n ", &n, (mp_size_t) 1);
+ printf (" want %d\n", want);
+ printf (" got %d\n", got);
+ abort ();
+ }
+}
+
+void
+check_various (void)
+{
+ int i;
+
+#ifdef COUNT_LEADING_ZEROS_0
+ check_clz (COUNT_LEADING_ZEROS_0, CNST_LIMB(0));
+#endif
+
+ for (i=0; i < GMP_LIMB_BITS; i++)
+ {
+ check_clz (i, CNST_LIMB(1) << (GMP_LIMB_BITS-1-i));
+ check_ctz (i, CNST_LIMB(1) << i);
+
+ check_ctz (i, MP_LIMB_T_MAX << i);
+ check_clz (i, MP_LIMB_T_MAX >> i);
+ }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+ mp_trace_base = 16;
+
+ check_various ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/t-gmpmax.c b/gmp/tests/t-gmpmax.c
new file mode 100644
index 0000000000..76fdd28e61
--- /dev/null
+++ b/gmp/tests/t-gmpmax.c
@@ -0,0 +1,69 @@
+/* Check the values of __GMP_UINT_MAX etc.
+
+Copyright 2001 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 <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "gmp.h"
+
+
+/* __GMP_UINT_MAX etc are generated with expressions in gmp.h since we don't
+ want to demand <limits.h> or forcibly include it. Check the expressions
+ come out the same as <limits.h>. */
+
+int
+main (int argc, char *argv[])
+{
+ int error = 0;
+
+#ifdef UINT_MAX
+ if (__GMP_UINT_MAX != UINT_MAX)
+ {
+ printf ("__GMP_UINT_MAX incorrect\n");
+ printf (" __GMP_UINT_MAX %u 0x%X\n", __GMP_UINT_MAX, __GMP_UINT_MAX);
+ printf (" UINT_MAX %u 0x%X\n", UINT_MAX, UINT_MAX);
+ error = 1;
+ }
+#endif
+
+#ifdef ULONG_MAX
+ if (__GMP_ULONG_MAX != ULONG_MAX)
+ {
+ printf ("__GMP_ULONG_MAX incorrect\n");
+ printf (" __GMP_ULONG_MAX %lu 0x%lX\n", __GMP_ULONG_MAX, __GMP_ULONG_MAX);
+ printf (" ULONG_MAX %lu 0x%lX\n", ULONG_MAX, ULONG_MAX);
+ error = 1;
+ }
+#endif
+
+#ifdef USHRT_MAX
+ if (__GMP_USHRT_MAX != USHRT_MAX)
+ {
+ printf ("__GMP_USHRT_MAX incorrect\n");
+ printf (" __GMP_USHRT_MAX %u 0x%X\n", __GMP_USHRT_MAX, __GMP_USHRT_MAX);
+ printf (" USHRT_MAX %u 0x%X\n", USHRT_MAX, USHRT_MAX);
+ error = 1;
+ }
+#endif
+
+ if (error)
+ abort ();
+
+ exit (0);
+}
diff --git a/gmp/tests/t-hightomask.c b/gmp/tests/t-hightomask.c
new file mode 100644
index 0000000000..1de20c94f6
--- /dev/null
+++ b/gmp/tests/t-hightomask.c
@@ -0,0 +1,43 @@
+/* Test LIMB_HIGHBIT_TO_MASK.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* There's very little to these tests, but it's nice to have them since if
+ something has gone wrong with the arithmetic right shift business in
+ LIMB_HIGHBIT_TO_MASK then the only symptom is likely to be failures in
+ udiv_qrnnd_preinv, which would not be easy to diagnose. */
+
+int
+main (void)
+{
+ ASSERT_ALWAYS (LIMB_HIGHBIT_TO_MASK (0) == 0);
+ ASSERT_ALWAYS (LIMB_HIGHBIT_TO_MASK (GMP_LIMB_HIGHBIT) == MP_LIMB_T_MAX);
+ ASSERT_ALWAYS (LIMB_HIGHBIT_TO_MASK (MP_LIMB_T_MAX) == MP_LIMB_T_MAX);
+ ASSERT_ALWAYS (LIMB_HIGHBIT_TO_MASK (GMP_LIMB_HIGHBIT >> 1) == 0);
+ ASSERT_ALWAYS (LIMB_HIGHBIT_TO_MASK (MP_LIMB_T_MAX >> 1) == 0);
+
+ exit (0);
+}
diff --git a/gmp/tests/t-modlinv.c b/gmp/tests/t-modlinv.c
new file mode 100644
index 0000000000..8e17d7787f
--- /dev/null
+++ b/gmp/tests/t-modlinv.c
@@ -0,0 +1,84 @@
+/* Test binvert_limb.
+
+Copyright 2000-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+
+void
+one (mp_limb_t n)
+{
+ mp_limb_t inv, prod;
+
+ binvert_limb (inv, n);
+ prod = (inv * n) & GMP_NUMB_MASK;
+ if (prod != 1)
+ {
+ printf ("binvert_limb wrong\n");
+ mp_limb_trace (" n ", n);
+ mp_limb_trace (" got ", inv);
+ mp_limb_trace (" product ", prod);
+ abort ();
+ }
+}
+
+void
+some (void)
+{
+ int i;
+ for (i = 0; i < 10000; i++)
+ one (refmpn_random_limb () | 1);
+}
+
+void
+all (void)
+{
+ mp_limb_t n;
+
+ n = 1;
+ do {
+ one (n);
+ n += 2;
+ } while (n != 1);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+
+ if (argc >= 2 && strcmp (argv[1], "-a") == 0)
+ {
+ /* it's feasible to run all values on a 32-bit limb, but not a 64-bit */
+ all ();
+ }
+ else
+ {
+ some ();
+ }
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/t-parity.c b/gmp/tests/t-parity.c
new file mode 100644
index 0000000000..b6da112733
--- /dev/null
+++ b/gmp/tests/t-parity.c
@@ -0,0 +1,67 @@
+/* Test ULONG_PARITY.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+void
+check_one (int want, unsigned long n)
+{
+ int got;
+ ULONG_PARITY (got, n);
+ if (got != want)
+ {
+ printf ("ULONG_PARITY wrong\n");
+ printf (" n %lX\n", n);
+ printf (" want %d\n", want);
+ printf (" got %d\n", got);
+ abort ();
+ }
+}
+
+void
+check_various (void)
+{
+ int i;
+
+ check_one (0, 0L);
+ check_one (BITS_PER_ULONG & 1, ULONG_MAX);
+ check_one (0, 0x11L);
+ check_one (1, 0x111L);
+ check_one (1, 0x3111L);
+
+ for (i = 0; i < BITS_PER_ULONG; i++)
+ check_one (1, 1UL << i);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ tests_start ();
+ mp_trace_base = 16;
+
+ check_various ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/t-popc.c b/gmp/tests/t-popc.c
new file mode 100644
index 0000000000..c3b3288607
--- /dev/null
+++ b/gmp/tests/t-popc.c
@@ -0,0 +1,80 @@
+/* Test popc_limb.
+
+Copyright 2002, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+int
+main (void)
+{
+ mp_limb_t src, want, got;
+ int i;
+
+ tests_start ();
+ mp_trace_base = -16;
+
+ for (i = 0; i < GMP_LIMB_BITS; i++)
+ {
+ src = CNST_LIMB(1) << i;
+ want = 1;
+
+ popc_limb (got, src);
+ if (got != want)
+ {
+ error:
+ printf ("popc_limb wrong result\n");
+ mpn_trace (" src ", &src, (mp_size_t) 1);
+ mpn_trace (" want", &want, (mp_size_t) 1);
+ mpn_trace (" got ", &got, (mp_size_t) 1);
+ abort ();
+ }
+ }
+
+ src = 0;
+ want = 0;
+ for (i = 0; i < GMP_LIMB_BITS; i++)
+ {
+ src += CNST_LIMB(1) << i;
+ want += 1;
+
+ popc_limb (got, src);
+ if (got != want)
+ {
+ goto error;
+ }
+ }
+
+ for (i = 0; i < 100; i++)
+ {
+ mpn_random2 (&src, (mp_size_t) 1);
+ want = ref_popc_limb (src);
+
+ popc_limb (got, src);
+ if (got != want)
+ goto error;
+ }
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/t-sub.c b/gmp/tests/t-sub.c
new file mode 100644
index 0000000000..331705ff6f
--- /dev/null
+++ b/gmp/tests/t-sub.c
@@ -0,0 +1,115 @@
+/* Test sub_ddmmss.
+
+Copyright 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 <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "tests.h"
+
+
+void
+check_data (void)
+{
+#define M MP_LIMB_T_MAX
+
+ static const struct {
+ mp_limb_t want_dh,want_dl, mh,ml, sh,sl;
+ } data[] = {
+ { 0,0, 0,0, 0,0 },
+ { 0,0, 0,1, 0,1 },
+ { 0,0, 1,2, 1,2 },
+
+ { 0,1, 0,2, 0,1 },
+ { 0,M, 1,0, 0,1 },
+ { M,M, 0,0, 0,1 },
+
+ { M,M, 0,M-1, 0,M },
+ { 0,0, 0,M-1, 0,M-1 },
+ { 0,1, 0,M-1, 0,M-2 },
+ };
+ int i;
+ mp_limb_t got_dh, got_dl;
+
+ for (i = 0; i < numberof (data); i++)
+ {
+ sub_ddmmss (got_dh,got_dl, data[i].mh,data[i].ml, data[i].sh,data[i].sl);
+ if (got_dh != data[i].want_dh || got_dl != data[i].want_dl)
+ {
+ printf ("check_data wrong at data[%d]\n", i);
+ mp_limb_trace (" mh", data[i].mh);
+ mp_limb_trace (" ml", data[i].ml);
+ mp_limb_trace (" sh", data[i].sh);
+ mp_limb_trace (" sl", data[i].sl);
+ mp_limb_trace (" want dh", data[i].want_dh);
+ mp_limb_trace (" want dl", data[i].want_dl);
+ mp_limb_trace (" got dh ", got_dh);
+ mp_limb_trace (" got dl ", got_dl);
+ abort ();
+ }
+ }
+}
+
+void
+check_random (void)
+{
+ mp_limb_t want_dh,want_dl, got_dh,got_dl, mh,ml, sh,sl;
+ int i;
+
+ for (i = 0; i < 20; i++)
+ {
+ mh = urandom ();
+ ml = urandom ();
+ sh = urandom ();
+ sl = urandom ();
+
+ refmpn_sub_ddmmss (&want_dh,&want_dl, mh,ml, sh,sl);
+
+ sub_ddmmss (got_dh,got_dl, mh,ml, sh,sl);
+
+ if (got_dh != want_dh || got_dl != want_dl)
+ {
+ printf ("check_data wrong at data[%d]\n", i);
+ mp_limb_trace (" mh", mh);
+ mp_limb_trace (" ml", ml);
+ mp_limb_trace (" sh", sh);
+ mp_limb_trace (" sl", sl);
+ mp_limb_trace (" want dh", want_dh);
+ mp_limb_trace (" want dl", want_dl);
+ mp_limb_trace (" got dh ", got_dh);
+ mp_limb_trace (" got dl ", got_dl);
+ abort ();
+ }
+ }
+}
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_data ();
+ check_random ();
+
+ tests_end ();
+ exit (0);
+}
diff --git a/gmp/tests/tests.h b/gmp/tests/tests.h
new file mode 100644
index 0000000000..f0c3fa780b
--- /dev/null
+++ b/gmp/tests/tests.h
@@ -0,0 +1,442 @@
+/* Tests support prototypes etc.
+
+Copyright 2000-2004, 2008-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/. */
+
+
+#ifndef __TESTS_H__
+#define __TESTS_H__
+
+#include "config.h"
+
+#include <setjmp.h> /* for jmp_buf */
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+#define ANYARGS ...
+#else
+#define ANYARGS
+#endif
+
+
+void tests_start (void);
+void tests_end (void);
+
+void tests_memory_start (void);
+void tests_memory_end (void);
+void *tests_allocate (size_t);
+void *tests_reallocate (void *, size_t, size_t);
+void tests_free (void *, size_t);
+void tests_free_nosize (void *);
+int tests_memory_valid (void *);
+
+void tests_rand_start (void);
+void tests_rand_end (void);
+
+double tests_infinity_d ();
+int tests_hardware_getround (void);
+int tests_hardware_setround (int);
+int tests_isinf (double);
+int tests_dbl_mant_bits (void);
+
+void x86_fldcw (unsigned short);
+unsigned short x86_fstcw (void);
+
+
+/* tests_setjmp_sigfpe is like a setjmp, establishing a trap for SIGFPE.
+ The initial return is 0, if SIGFPE is trapped execution goes back there
+ with return value 1.
+
+ tests_sigfpe_done puts SIGFPE back to SIG_DFL, which should be used once
+ the setjmp point is out of scope, so a later SIGFPE won't try to go back
+ there. */
+
+#define tests_setjmp_sigfpe() \
+ (signal (SIGFPE, tests_sigfpe_handler), \
+ setjmp (tests_sigfpe_target))
+
+RETSIGTYPE tests_sigfpe_handler (int);
+void tests_sigfpe_done (void);
+extern jmp_buf tests_sigfpe_target;
+
+
+#if HAVE_CALLING_CONVENTIONS
+extern mp_limb_t (*calling_conventions_function) (ANYARGS);
+mp_limb_t calling_conventions (ANYARGS);
+int calling_conventions_check (void);
+#define CALLING_CONVENTIONS(function) \
+ (calling_conventions_function = (function), calling_conventions)
+#define CALLING_CONVENTIONS_CHECK() (calling_conventions_check())
+#else
+#define CALLING_CONVENTIONS(function) (function)
+#define CALLING_CONVENTIONS_CHECK() 1 /* always ok */
+#endif
+
+
+extern int mp_trace_base;
+void mp_limb_trace (const char *, mp_limb_t);
+void mpn_trace (const char *, mp_srcptr, mp_size_t);
+void mpn_tracea (const char *, const mp_ptr *, int, mp_size_t);
+void mpn_tracen (const char *, int, mp_srcptr, mp_size_t);
+void mpn_trace_file (const char *, mp_srcptr, mp_size_t);
+void mpn_tracea_file (const char *, const mp_ptr *, int, mp_size_t);
+void mpf_trace (const char *, mpf_srcptr);
+void mpq_trace (const char *, mpq_srcptr);
+void mpz_trace (const char *, mpz_srcptr);
+void mpz_tracen (const char *, int, mpz_srcptr);
+void byte_trace (const char *, const void *, mp_size_t);
+void byte_tracen (const char *, int, const void *, mp_size_t);
+void d_trace (const char *, double);
+
+
+void spinner (void);
+extern unsigned long spinner_count;
+extern int spinner_wanted;
+extern int spinner_tick;
+
+
+void *align_pointer (void *, size_t);
+void *__gmp_allocate_func_aligned (size_t, size_t);
+void *__gmp_allocate_or_reallocate (void *, size_t, size_t);
+char *__gmp_allocate_strdup (const char *);
+char *strtoupper (char *);
+mp_limb_t urandom (void);
+void call_rand_algs (void (*func) (const char *, gmp_randstate_t));
+
+
+void mpf_set_str_or_abort (mpf_ptr, const char *, int);
+
+
+void mpq_set_str_or_abort (mpq_ptr, const char *, int);
+
+
+void mpz_erandomb (mpz_ptr, gmp_randstate_t, unsigned long);
+void mpz_erandomb_nonzero (mpz_ptr, gmp_randstate_t, unsigned long);
+void mpz_errandomb (mpz_ptr, gmp_randstate_t, unsigned long);
+void mpz_errandomb_nonzero (mpz_ptr, gmp_randstate_t, unsigned long);
+void mpz_init_set_n (mpz_ptr, mp_srcptr, mp_size_t);
+void mpz_negrandom (mpz_ptr, gmp_randstate_t);
+int mpz_pow2abs_p (mpz_srcptr) __GMP_ATTRIBUTE_PURE;
+void mpz_set_n (mpz_ptr, mp_srcptr, mp_size_t);
+void mpz_set_str_or_abort (mpz_ptr, const char *, int);
+
+mp_size_t mpn_diff_highest (mp_srcptr, mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE;
+mp_size_t mpn_diff_lowest (mp_srcptr, mp_srcptr, mp_size_t) __GMP_ATTRIBUTE_PURE;
+mp_size_t byte_diff_highest (const void *, const void *, mp_size_t) __GMP_ATTRIBUTE_PURE;
+mp_size_t byte_diff_lowest (const void *, const void *, mp_size_t) __GMP_ATTRIBUTE_PURE;
+
+
+mp_limb_t ref_addc_limb (mp_limb_t *, mp_limb_t, mp_limb_t);
+mp_limb_t ref_bswap_limb (mp_limb_t);
+unsigned long ref_popc_limb (mp_limb_t);
+mp_limb_t ref_subc_limb (mp_limb_t *, mp_limb_t, mp_limb_t);
+
+
+void refmpf_add (mpf_ptr, mpf_srcptr, mpf_srcptr);
+void refmpf_add_ulp (mpf_ptr );
+void refmpf_fill (mpf_ptr, mp_size_t, mp_limb_t);
+void refmpf_normalize (mpf_ptr);
+void refmpf_set_prec_limbs (mpf_ptr, unsigned long);
+unsigned long refmpf_set_overlap (mpf_ptr, mpf_srcptr);
+void refmpf_sub (mpf_ptr, mpf_srcptr, mpf_srcptr);
+int refmpf_validate (const char *, mpf_srcptr, mpf_srcptr);
+int refmpf_validate_division (const char *, mpf_srcptr, mpf_srcptr, mpf_srcptr);
+
+
+mp_limb_t refmpn_cnd_add_n (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_cnd_sub_n (mp_limb_t, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+mp_limb_t refmpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_add_err1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_add_err2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_add_err3_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_add_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_addlsh1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_addlsh2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_addlsh_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned);
+mp_limb_t refmpn_addlsh1_n_ip1 (mp_ptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_addlsh2_n_ip1 (mp_ptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_addlsh_n_ip1 (mp_ptr, mp_srcptr, mp_size_t, unsigned);
+mp_limb_t refmpn_addlsh1_n_ip2 (mp_ptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_addlsh2_n_ip2 (mp_ptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_addlsh_n_ip2 (mp_ptr, mp_srcptr, mp_size_t, unsigned);
+mp_limb_t refmpn_addlsh1_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_addlsh2_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_addlsh_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned, mp_limb_t);
+mp_limb_t refmpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_addmul_1c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+mp_limb_t refmpn_addmul_2 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_addmul_3 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_addmul_4 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_addmul_5 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_addmul_6 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_addmul_7 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_addmul_8 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+mp_limb_t refmpn_add_n_sub_n (mp_ptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_add_n_sub_nc (mp_ptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+void refmpn_and_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+void refmpn_andn_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+mp_limb_t refmpn_big_base (int);
+
+int refmpn_chars_per_limb (int);
+void refmpn_clrbit (mp_ptr, unsigned long);
+int refmpn_cmp (mp_srcptr, mp_srcptr, mp_size_t);
+int refmpn_cmp_allowzero (mp_srcptr, mp_srcptr, mp_size_t);
+int refmpn_cmp_twosizes (mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+void refmpn_com (mp_ptr, mp_srcptr, mp_size_t);
+void refmpn_copy (mp_ptr, mp_srcptr, mp_size_t);
+void refmpn_copyi (mp_ptr, mp_srcptr, mp_size_t);
+void refmpn_copyd (mp_ptr, mp_srcptr, mp_size_t);
+void refmpn_copy_extend (mp_ptr, mp_size_t, mp_srcptr, mp_size_t);
+
+unsigned refmpn_count_leading_zeros (mp_limb_t);
+unsigned refmpn_count_trailing_zeros (mp_limb_t);
+
+mp_limb_t refmpn_divexact_by3 (mp_ptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_divexact_by3c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+
+mp_limb_t refmpn_divmod_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_divmod_1c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+mp_limb_t refmpn_divrem_1 (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_divrem_1c (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+mp_limb_t refmpn_divrem_2 (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr);
+
+int refmpn_equal_anynail (mp_srcptr, mp_srcptr, mp_size_t);
+
+void refmpn_fill (mp_ptr, mp_size_t, mp_limb_t);
+
+mp_limb_t refmpn_gcd_1 (mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_gcd (mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
+
+size_t refmpn_get_str (unsigned char *, int, mp_ptr, mp_size_t);
+
+unsigned long refmpn_hamdist (mp_srcptr, mp_srcptr, mp_size_t);
+
+mp_limb_t refmpn_invert_limb (mp_limb_t);
+void refmpn_ior_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+void refmpn_iorn_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+mp_limb_t refmpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned);
+mp_limb_t refmpn_lshift_or_copy (mp_ptr, mp_srcptr, mp_size_t, unsigned);
+mp_limb_t refmpn_lshift_or_copy_any (mp_ptr, mp_srcptr, mp_size_t, unsigned);
+mp_limb_t refmpn_lshiftc (mp_ptr, mp_srcptr, mp_size_t, unsigned);
+void refmpn_com (mp_ptr, mp_srcptr, mp_size_t);
+
+mp_ptr refmpn_malloc_limbs (mp_size_t);
+mp_ptr refmpn_malloc_limbs_aligned (mp_size_t, size_t);
+void refmpn_free_limbs (mp_ptr);
+mp_limb_t refmpn_msbone (mp_limb_t);
+mp_limb_t refmpn_msbone_mask (mp_limb_t);
+mp_ptr refmpn_memdup_limbs (mp_srcptr, mp_size_t);
+
+mp_limb_t refmpn_mod_1 (mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_mod_1c (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+mp_limb_t refmpn_mod_34lsub1 (mp_srcptr, mp_size_t);
+
+mp_limb_t refmpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_mul_1c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+mp_limb_t refmpn_mul_2 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_mul_3 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_mul_4 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_mul_5 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+mp_limb_t refmpn_mul_6 (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr);
+
+void refmpn_mul_basecase (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+void refmpn_mulmid_basecase (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+void refmpn_toom42_mulmid (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_ptr);
+void refmpn_mulmid_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+void refmpn_mulmid (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+void refmpn_mullo_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+void refmpn_mul_any (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+void refmpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+void refmpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+
+void refmpn_nand_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+void refmpn_nior_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_neg (mp_ptr, mp_srcptr, mp_size_t);
+mp_size_t refmpn_normalize (mp_srcptr, mp_size_t);
+
+unsigned long refmpn_popcount (mp_srcptr, mp_size_t);
+mp_limb_t refmpn_preinv_divrem_1 (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, unsigned);
+mp_limb_t refmpn_preinv_mod_1 (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+
+void refmpn_random (mp_ptr, mp_size_t);
+void refmpn_random2 (mp_ptr, mp_size_t);
+mp_limb_t refmpn_random_limb (void);
+
+mp_limb_t refmpn_rsh1add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_rsh1sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned);
+mp_limb_t refmpn_rshift_or_copy (mp_ptr, mp_srcptr, mp_size_t, unsigned);
+mp_limb_t refmpn_rshift_or_copy_any (mp_ptr, mp_srcptr, mp_size_t, unsigned);
+
+mp_limb_t refmpn_sb_div_qr (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t);
+unsigned long refmpn_scan0 (mp_srcptr, unsigned long);
+unsigned long refmpn_scan1 (mp_srcptr, unsigned long);
+void refmpn_setbit (mp_ptr, unsigned long);
+void refmpn_sqr (mp_ptr, mp_srcptr, mp_size_t);
+mp_size_t refmpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t);
+
+void refmpn_sub_ddmmss (mp_limb_t *, mp_limb_t *, mp_limb_t, mp_limb_t, mp_limb_t, mp_limb_t);
+mp_limb_t refmpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_sub_err1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_sub_err2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_sub_err3_n (mp_ptr, mp_srcptr, mp_srcptr, mp_ptr, mp_srcptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_sub_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_sublsh1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_sublsh2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_sublsh_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned int);
+mp_limb_t refmpn_sublsh1_n_ip1 (mp_ptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_sublsh2_n_ip1 (mp_ptr, mp_srcptr, mp_size_t);
+mp_limb_t refmpn_sublsh_n_ip1 (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
+mp_limb_t refmpn_sublsh1_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_sublsh2_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_sublsh_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned int, mp_limb_t);
+mp_limb_t refmpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t refmpn_submul_1c (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t);
+
+mp_limb_signed_t refmpn_rsblsh1_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_signed_t refmpn_rsblsh2_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+mp_limb_signed_t refmpn_rsblsh_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned int);
+mp_limb_signed_t refmpn_rsblsh1_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_signed_t);
+mp_limb_signed_t refmpn_rsblsh2_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, mp_limb_signed_t);
+mp_limb_signed_t refmpn_rsblsh_nc (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t, unsigned int, mp_limb_signed_t);
+
+void refmpn_tdiv_qr (mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr, mp_size_t);
+int refmpn_tstbit (mp_srcptr, unsigned long);
+
+mp_limb_t refmpn_udiv_qrnnd (mp_limb_t *, mp_limb_t, mp_limb_t, mp_limb_t);
+mp_limb_t refmpn_udiv_qrnnd_r (mp_limb_t, mp_limb_t, mp_limb_t, mp_limb_t *);
+mp_limb_t refmpn_umul_ppmm (mp_limb_t *, mp_limb_t, mp_limb_t);
+mp_limb_t refmpn_umul_ppmm_r (mp_limb_t, mp_limb_t, mp_limb_t *);
+
+void refmpn_xnor_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+void refmpn_xor_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+
+void refmpn_zero (mp_ptr, mp_size_t);
+void refmpn_zero_extend (mp_ptr, mp_size_t, mp_size_t);
+int refmpn_zero_p (mp_srcptr, mp_size_t);
+
+void refmpn_binvert (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+void refmpn_invert (mp_ptr, mp_srcptr, mp_size_t, mp_ptr);
+
+
+void refmpq_add (mpq_ptr, mpq_srcptr, mpq_srcptr);
+void refmpq_sub (mpq_ptr, mpq_srcptr, mpq_srcptr);
+
+
+void refmpz_combit (mpz_ptr, unsigned long);
+unsigned long refmpz_hamdist (mpz_srcptr, mpz_srcptr);
+int refmpz_kronecker (mpz_srcptr, mpz_srcptr);
+int refmpz_jacobi (mpz_srcptr, mpz_srcptr);
+int refmpz_legendre (mpz_srcptr, mpz_srcptr);
+int refmpz_kronecker_si (mpz_srcptr, long);
+int refmpz_kronecker_ui (mpz_srcptr, unsigned long);
+int refmpz_si_kronecker (long, mpz_srcptr);
+int refmpz_ui_kronecker (unsigned long, mpz_srcptr);
+
+void refmpz_pow_ui (mpz_ptr, mpz_srcptr, unsigned long);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+
+/* Establish ostringstream and istringstream. Do this here so as to hide
+ the conditionals, rather than putting stuff in each test program.
+
+ Oldish versions of g++, like 2.95.2, don't have <sstream>, only
+ <strstream>. Fake up ostringstream and istringstream classes, but not a
+ full implementation, just enough for our purposes. */
+
+#ifdef __cplusplus
+#if 1 || HAVE_SSTREAM
+#include <sstream>
+#else /* ! HAVE_SSTREAM */
+#include <string>
+#include <strstream>
+class
+ostringstream : public std::ostrstream {
+ public:
+ string str() {
+ int pcount = ostrstream::pcount ();
+ char *s = (char *) (*__gmp_allocate_func) (pcount + 1);
+ memcpy (s, ostrstream::str(), pcount);
+ s[pcount] = '\0';
+ string ret = string(s);
+ (*__gmp_free_func) (s, pcount + 1);
+ return ret; }
+};
+class
+istringstream : public std::istrstream {
+ public:
+ istringstream (const char *s) : istrstream (s) { };
+};
+#endif /* ! HAVE_SSTREAM */
+#endif /* __cplusplus */
+
+
+#define TESTS_REPS(count, argv, argc) \
+ do { \
+ char *envval, *end; \
+ double repfactor; \
+ int reps_nondefault = 0; \
+ if (argc > 1) \
+ { \
+ count = strtol (argv[1], &end, 0); \
+ if (*end || count <= 0) \
+ { \
+ fprintf (stderr, "Invalid test count: %s.\n", argv[1]); \
+ exit (1); \
+ } \
+ argv++; \
+ argc--; \
+ reps_nondefault = 1; \
+ } \
+ envval = getenv ("GMP_CHECK_REPFACTOR"); \
+ if (envval != NULL) \
+ { \
+ repfactor = strtod (envval, &end); \
+ if (*end || repfactor <= 0) \
+ { \
+ fprintf (stderr, "Invalid repfactor: %f.\n", repfactor); \
+ exit (1); \
+ } \
+ count *= repfactor; \
+ count = MAX (count, 1); \
+ reps_nondefault = 1; \
+ } \
+ if (reps_nondefault) \
+ printf ("Running test with %ld repetitions (include this in bug reports)\n",\
+ (long) count); \
+ } while (0)
+
+
+#endif /* __TESTS_H__ */
diff --git a/gmp/tests/trace.c b/gmp/tests/trace.c
new file mode 100644
index 0000000000..4b05bdb824
--- /dev/null
+++ b/gmp/tests/trace.c
@@ -0,0 +1,318 @@
+/* Support for diagnostic traces.
+
+Copyright 1999-2005 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/. */
+
+
+/* Future: Would like commas printed between limbs in hex or binary, but
+ perhaps not always since it might upset cutting and pasting into bc or
+ whatever. */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for strlen */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#include "tests.h"
+
+
+/* Number base for the various trace printing routines.
+ Set this in main() or with the debugger.
+ If hexadecimal is going to be fed into GNU bc, remember to use -16
+ because bc requires upper case. */
+
+int mp_trace_base = 10;
+
+
+void
+mp_trace_start (const char *name)
+{
+ if (name != NULL && name[0] != '\0')
+ printf ("%s=", name);
+
+ switch (ABS (mp_trace_base)) {
+ case 2: printf ("bin:"); break;
+ case 8: printf ("oct:"); break;
+ case 10: break;
+ case 16: printf ("0x"); break;
+ default: printf ("base%d:", ABS (mp_trace_base)); break;
+ }
+}
+
+/* Print "name=value\n" to stdout for an mpq_t value. */
+void
+mpq_trace (const char *name, mpq_srcptr q)
+{
+ mp_trace_start (name);
+ if (q == NULL)
+ {
+ printf ("NULL\n");
+ return;
+ }
+
+ mpq_out_str (stdout, mp_trace_base, q);
+ printf ("\n");
+}
+
+
+/* Print "name=value\n" to stdout for an mpz_t value. */
+void
+mpz_trace (const char *name, mpz_srcptr z)
+{
+ mpq_t q;
+ mp_limb_t one;
+
+ if (z == NULL)
+ {
+ mpq_trace (name, NULL);
+ return;
+ }
+
+ q->_mp_num._mp_alloc = ALLOC(z);
+ q->_mp_num._mp_size = SIZ(z);
+ q->_mp_num._mp_d = PTR(z);
+
+ one = 1;
+ q->_mp_den._mp_alloc = 1;
+ q->_mp_den._mp_size = 1;
+ q->_mp_den._mp_d = &one;
+
+ mpq_trace(name, q);
+}
+
+
+/* Print "name=value\n" to stdout for an mpf_t value. */
+void
+mpf_trace (const char *name, mpf_srcptr f)
+{
+ mp_trace_start (name);
+ if (f == NULL)
+ {
+ printf ("NULL\n");
+ return;
+ }
+
+ mpf_out_str (stdout, ABS (mp_trace_base), 0, f);
+ printf ("\n");
+}
+
+
+/* Print "namenum=value\n" to stdout for an mpz_t value.
+ "name" should have a "%d" to get the number. */
+void
+mpz_tracen (const char *name, int num, mpz_srcptr z)
+{
+ if (name != NULL && name[0] != '\0')
+ {
+ printf (name, num);
+ putchar ('=');
+ }
+ mpz_trace (NULL, z);
+}
+
+
+/* Print "name=value\n" to stdout for an mpn style ptr,size. */
+void
+mpn_trace (const char *name, mp_srcptr ptr, mp_size_t size)
+{
+ mpz_t z;
+ if (ptr == NULL)
+ {
+ mpz_trace (name, NULL);
+ return;
+ }
+ MPN_NORMALIZE (ptr, size);
+ PTR(z) = (mp_ptr) ptr;
+ SIZ(z) = size;
+ ALLOC(z) = size;
+ mpz_trace (name, z);
+}
+
+/* Print "name=value\n" to stdout for a limb, nail doesn't have to be zero. */
+void
+mp_limb_trace (const char *name, mp_limb_t n)
+{
+#if GMP_NAIL_BITS != 0
+ mp_limb_t a[2];
+ a[0] = n & GMP_NUMB_MASK;
+ a[1] = n >> GMP_NUMB_BITS;
+ mpn_trace (name, a, (mp_size_t) 2);
+#else
+ mpn_trace (name, &n, (mp_size_t) 1);
+#endif
+}
+
+
+/* Print "namenum=value\n" to stdout for an mpn style ptr,size.
+ "name" should have a "%d" to get the number. */
+void
+mpn_tracen (const char *name, int num, mp_srcptr ptr, mp_size_t size)
+{
+ if (name != NULL && name[0] != '\0')
+ {
+ printf (name, num);
+ putchar ('=');
+ }
+ mpn_trace (NULL, ptr, size);
+}
+
+
+/* Print "namenum=value\n" to stdout for an array of mpn style ptr,size.
+
+ "a" is an array of pointers, each a[i] is a pointer to "size" many limbs.
+ The formal parameter isn't mp_srcptr because that causes compiler
+ warnings, but the values aren't modified.
+
+ "name" should have a printf style "%d" to get the array index. */
+
+void
+mpn_tracea (const char *name, const mp_ptr *a, int count, mp_size_t size)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ mpn_tracen (name, i, a[i], size);
+}
+
+
+/* Print "value\n" to a file for an mpz_t value. Any previous contents of
+ the file are overwritten, so you need different file names each time this
+ is called.
+
+ Overwriting the file is a feature, it means you get old data replaced
+ when you run a test program repeatedly. */
+
+void
+mpn_trace_file (const char *filename, mp_srcptr ptr, mp_size_t size)
+{
+ FILE *fp;
+ mpz_t z;
+
+ fp = fopen (filename, "w");
+ if (fp == NULL)
+ {
+ perror ("fopen");
+ abort();
+ }
+
+ MPN_NORMALIZE (ptr, size);
+ PTR(z) = (mp_ptr) ptr;
+ SIZ(z) = (int) size;
+
+ mpz_out_str (fp, mp_trace_base, z);
+ fprintf (fp, "\n");
+
+ if (ferror (fp) || fclose (fp) != 0)
+ {
+ printf ("error writing %s\n", filename);
+ abort();
+ }
+}
+
+
+/* Print "value\n" to a set of files, one file for each element of the given
+ array of mpn style ptr,size. Any previous contents of the files are
+ overwritten, so you need different file names each time this is called.
+ Each file is "filenameN" where N is 0 to count-1.
+
+ "a" is an array of pointers, each a[i] is a pointer to "size" many limbs.
+ The formal parameter isn't mp_srcptr because that causes compiler
+ warnings, but the values aren't modified.
+
+ Overwriting the files is a feature, it means you get old data replaced
+ when you run a test program repeatedly. The output style isn't
+ particularly pretty, but at least it gets something out, and you can cat
+ the files into bc, or whatever. */
+
+void
+mpn_tracea_file (const char *filename,
+ const mp_ptr *a, int count, mp_size_t size)
+{
+ char *s;
+ int i;
+ TMP_DECL;
+
+ TMP_MARK;
+ s = (char *) TMP_ALLOC (strlen (filename) + 50);
+
+ for (i = 0; i < count; i++)
+ {
+ sprintf (s, "%s%d", filename, i);
+ mpn_trace_file (s, a[i], size);
+ }
+
+ TMP_FREE;
+}
+
+
+void
+byte_trace (const char *name, const void *ptr, mp_size_t size)
+{
+ const char *fmt;
+ mp_size_t i;
+
+ mp_trace_start (name);
+
+ switch (mp_trace_base) {
+ case 8: fmt = " %o"; break;
+ case 10: fmt = " %d"; break;
+ case 16: fmt = " %x"; break;
+ case -16: fmt = " %X"; break;
+ default: printf ("Oops, unsupported base in byte_trace\n"); abort (); break;
+ }
+
+ for (i = 0; i < size; i++)
+ printf (fmt, (int) ((unsigned char *) ptr)[i]);
+ printf ("\n");
+}
+
+void
+byte_tracen (const char *name, int num, const void *ptr, mp_size_t size)
+{
+ if (name != NULL && name[0] != '\0')
+ {
+ printf (name, num);
+ putchar ('=');
+ }
+ byte_trace (NULL, ptr, size);
+}
+
+
+void
+d_trace (const char *name, double d)
+{
+ union {
+ double d;
+ unsigned char b[sizeof(double)];
+ } u;
+ int i;
+
+ if (name != NULL && name[0] != '\0')
+ printf ("%s=", name);
+
+ u.d = d;
+ printf ("[");
+ for (i = 0; i < sizeof (u.b); i++)
+ {
+ if (i != 0)
+ printf (" ");
+ printf ("%02X", (int) u.b[i]);
+ }
+ printf ("] %.20g\n", d);
+}
diff --git a/gmp/tests/x86call.asm b/gmp/tests/x86call.asm
new file mode 100644
index 0000000000..de2fbcde2f
--- /dev/null
+++ b/gmp/tests/x86call.asm
@@ -0,0 +1,153 @@
+dnl x86 calling conventions checking.
+
+dnl Copyright 2000, 2003, 2010, 2013 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library test suite.
+
+dnl The GNU MP Library test suite is free software; you can redistribute it
+dnl and/or modify it under the terms of the GNU General Public License as
+dnl published by the Free Software Foundation; either version 3 of the
+dnl License, or (at your option) any later version.
+
+dnl The GNU MP Library test suite is distributed in the hope that it will be
+dnl useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+dnl Public License for more details.
+
+dnl You should have received a copy of the GNU General Public License along
+dnl with the GNU MP Library test suite. If not, see
+dnl https://www.gnu.org/licenses/.
+
+
+dnl The current version of the code attempts to keep the call/return
+dnl prediction stack valid, but matching calls and returns.
+
+include(`../config.m4')
+
+
+C void x86_fldcw (unsigned short cw);
+C
+C Execute an fldcw, setting the x87 control word to cw.
+
+PROLOGUE(x86_fldcw)
+ fldcw 4(%esp)
+ ret
+EPILOGUE()
+
+
+C unsigned short x86_fstcw (void);
+C
+C Execute an fstcw, returning the current x87 control word.
+
+PROLOGUE(x86_fstcw)
+ xor %eax, %eax
+ push %eax
+ fstcw (%esp)
+ pop %eax
+ ret
+EPILOGUE()
+
+
+dnl Instrumented profiling doesn't come out quite right below, since we don't
+dnl do an actual "ret". There's only a few instructions here, so there's no
+dnl great need to get them separately accounted, just let them get attributed
+dnl to the caller. FIXME this comment might no longer be true.
+
+ifelse(WANT_PROFILING,instrument,
+`define(`WANT_PROFILING',no)')
+
+
+C int calling_conventions (...);
+C
+C The global variable "calling_conventions_function" is the function to
+C call, with the arguments as passed here.
+C
+C Perhaps the finit should be done only if the tags word isn't clear, but
+C nothing uses the rounding mode or anything at the moment.
+
+define(`WANT_EBX', eval(4*0)($1))
+define(`WANT_EBP', eval(4*1)($1))
+define(`WANT_ESI', eval(4*2)($1))
+define(`WANT_EDI', eval(4*3)($1))
+
+define(`JUNK_EAX', eval(4*4)($1))
+define(`JUNK_ECX', eval(4*5)($1))
+define(`JUNK_EDX', eval(4*6)($1))
+
+define(`SAVE_EBX', eval(4*7)($1))
+define(`SAVE_EBP', eval(4*8)($1))
+define(`SAVE_ESI', eval(4*9)($1))
+define(`SAVE_EDI', eval(4*10)($1))
+
+define(`RETADDR', eval(4*11)($1))
+
+define(`EBX', eval(4*12)($1))
+define(`EBP', eval(4*13)($1))
+define(`ESI', eval(4*14)($1))
+define(`EDI', eval(4*15)($1))
+define(`EFLAGS', eval(4*16)($1))
+
+
+define(G,
+m4_assert_numargs(1)
+`GSYM_PREFIX`'$1')
+
+ TEXT
+ ALIGN(8)
+PROLOGUE(calling_conventions)
+ LEA( G(calling_conventions_values), %ecx)
+ pop RETADDR(%ecx)
+
+ mov %ebx, SAVE_EBX(%ecx)
+ mov %ebp, SAVE_EBP(%ecx)
+ mov %esi, SAVE_ESI(%ecx)
+ mov %edi, SAVE_EDI(%ecx)
+
+ C Values we expect to see unchanged, as per amd64check.c
+ mov WANT_EBX(%ecx), %ebx
+ mov WANT_EBP(%ecx), %ebp
+ mov WANT_ESI(%ecx), %esi
+ mov WANT_EDI(%ecx), %edi
+
+ C Try to provoke a problem by starting with junk in the caller-saves
+ C registers, especially in %eax and %edx which will be return values
+ mov JUNK_EAX(%ecx), %eax
+ mov JUNK_EDX(%ecx), %edx
+C mov JUNK_ECX(%ecx), %ecx
+
+ifdef(`PIC',`
+ LEA( G(calling_conventions_function), %ecx)
+ call *(%ecx)
+',`
+ call *G(calling_conventions_function)
+')
+
+ LEA( G(calling_conventions_values), %ecx)
+
+ mov %ebx, EBX(%ecx)
+ mov %ebp, EBP(%ecx)
+ mov %esi, ESI(%ecx)
+ mov %edi, EDI(%ecx)
+
+ pushf
+ pop %ebx
+ mov %ebx, EFLAGS(%ecx)
+
+ mov SAVE_EBX(%ecx), %ebx
+ mov SAVE_ESI(%ecx), %esi
+ mov SAVE_EDI(%ecx), %edi
+ mov SAVE_EBP(%ecx), %ebp
+
+ push RETADDR(%ecx)
+
+ifdef(`PIC',`
+ LEA( G(calling_conventions_fenv), %ecx)
+ fstenv (%ecx)
+',`
+ fstenv G(calling_conventions_fenv)
+')
+ finit
+
+ ret
+
+EPILOGUE()
diff --git a/gmp/tests/x86check.c b/gmp/tests/x86check.c
new file mode 100644
index 0000000000..067c8155b9
--- /dev/null
+++ b/gmp/tests/x86check.c
@@ -0,0 +1,112 @@
+/* x86 calling conventions checking. */
+
+/*
+Copyright 2000, 2001, 2010 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 <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+/* Vector if constants and register values. We use one vector to allow access
+ via a base pointer, very beneficial for the PIC-enabled amd64call.asm. */
+mp_limb_t calling_conventions_values[17] =
+{
+ CNST_LIMB(0x12345678), /* want_ebx */
+ CNST_LIMB(0x89ABCDEF), /* want_ebp */
+ CNST_LIMB(0xDEADBEEF), /* want_esi */
+ CNST_LIMB(0xFFEEDDCC), /* want_edi */
+
+ CNST_LIMB(0xFEEDABBA), /* JUNK_EAX */
+ CNST_LIMB(0xAB78DE89), /* JUNK_ECX */
+ CNST_LIMB(0x12389018) /* JUNK_EDX */
+
+ /* rest of array used for dynamic values. */
+};
+
+/* Index starts for various regions in above vector. */
+#define WANT 0
+#define JUNK 4
+#define SAVE 7
+#define RETADDR 11
+#define VAL 12
+#define EFLAGS 16
+
+
+/* values to check */
+struct {
+ unsigned control;
+ unsigned status;
+ unsigned tag;
+ unsigned other[4];
+} calling_conventions_fenv;
+
+/* expected values, as per x86call.asm */
+#define VALUE_EBX 0x01234567
+#define VALUE_ESI 0x89ABCDEF
+#define VALUE_EDI 0xFEDCBA98
+#define VALUE_EBP 0x76543210
+
+
+const char *regname[] = {"ebx", "ebp", "esi", "edi"};
+
+#define DIR_BIT(eflags) (((eflags) & (1<<10)) != 0)
+
+
+/* Return 1 if ok, 0 if not */
+
+int
+calling_conventions_check (void)
+{
+ const char *header = "Violated calling conventions:\n";
+ int ret = 1;
+ int i;
+
+#define CHECK(callreg, regstr, value) \
+ if (callreg != value) \
+ { \
+ printf ("%s %s got 0x%08X want 0x%08X\n", \
+ header, regstr, callreg, value); \
+ header = ""; \
+ ret = 0; \
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ CHECK (calling_conventions_values[VAL+i], regname[i], calling_conventions_values[WANT+i]);
+ }
+
+ if (DIR_BIT (calling_conventions_values[EFLAGS]) != 0)
+ {
+ printf ("%s eflags dir bit got %d want 0\n",
+ header, DIR_BIT (calling_conventions_values[EFLAGS]));
+ header = "";
+ ret = 0;
+ }
+
+ if ((calling_conventions_fenv.tag & 0xFFFF) != 0xFFFF)
+ {
+ printf ("%s fpu tags got 0x%X want 0xFFFF\n",
+ header, calling_conventions_fenv.tag & 0xFFFF);
+ header = "";
+ ret = 0;
+ }
+
+ return ret;
+}
diff --git a/gmp/tune/Makefile.am b/gmp/tune/Makefile.am
new file mode 100644
index 0000000000..bbe503a201
--- /dev/null
+++ b/gmp/tune/Makefile.am
@@ -0,0 +1,181 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2000-2003, 2005-2011 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+
+EXTRA_DIST = alpha.asm pentium.asm sparcv9.asm hppa.asm hppa2.asm hppa2w.asm \
+ ia64.asm powerpc.asm powerpc64.asm x86_64.asm many.pl
+noinst_HEADERS = speed.h
+
+# Prefer -static on the speed and tune programs, since that can avoid
+# overheads of shared library linkages on some systems. Libtool tends to
+# botch -static if configured with --disable-static, perhaps reasonably
+# enough. In any event under --disable-static the only choice is a dynamic
+# link so there's no point in -static.
+#
+if ENABLE_STATIC
+STATIC = -static
+else
+STATIC =
+endif
+
+
+EXTRA_LTLIBRARIES = libspeed.la
+
+libspeed_la_SOURCES = \
+ common.c divrem1div.c divrem1inv.c divrem2div.c divrem2inv.c \
+ div_qr_1n_pi1_1.c div_qr_1n_pi1_2.c div_qr_1_tune.c \
+ freq.c \
+ gcdext_single.c gcdext_double.c gcdextod.c gcdextos.c \
+ hgcd_lehmer.c hgcd_appr_lehmer.c hgcd_reduce_1.c hgcd_reduce_2.c \
+ jacbase1.c jacbase2.c jacbase3.c jacbase4.c \
+ mod_1_div.c mod_1_inv.c mod_1_1-1.c mod_1_1-2.c modlinv.c \
+ noop.c powm_mod.c powm_redc.c pre_divrem_1.c \
+ set_strb.c set_strs.c set_strp.c time.c
+
+libspeed_la_DEPENDENCIES = $(SPEED_CYCLECOUNTER_OBJ) \
+ $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+libspeed_la_LIBADD = $(libspeed_la_DEPENDENCIES) $(LIBM)
+libspeed_la_LDFLAGS = $(STATIC)
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
+
+
+# The library code is faster static than shared on some systems, so do
+# tuning and measuring with static, since users who care about maximizing
+# speed will be using that. speed-dynamic exists to show the difference.
+#
+# On Solaris 8, gcc 2.95.2 -static is somehow broken (it creates executables
+# that immediately seg fault), so -all-static is not used. The only thing
+# -all-static does is make libc static linked as well as libgmp, and that
+# makes a difference only when measuring malloc and friends in the speed
+# program. This can always be forced with "make speed_LDFLAGS=-all-static
+# ..." if desired, see tune/README.
+
+EXTRA_PROGRAMS = speed speed-dynamic speed-ext tuneup tune-gcd-p
+
+DEPENDENCIES = libspeed.la
+LDADD = $(DEPENDENCIES) $(TUNE_LIBS)
+
+speed_SOURCES = speed.c
+speed_LDFLAGS = $(STATIC)
+
+speed_dynamic_SOURCES = speed.c
+
+speed_ext_SOURCES = speed-ext.c
+speed_ext_LDFLAGS = $(STATIC)
+
+tuneup_SOURCES = tuneup.c
+nodist_tuneup_SOURCES = sqr_basecase.c fac_ui.c $(TUNE_MPN_SRCS)
+tuneup_DEPENDENCIES = $(TUNE_SQR_OBJ) libspeed.la
+tuneup_LDADD = $(tuneup_DEPENDENCIES) $(TUNE_LIBS)
+tuneup_LDFLAGS = $(STATIC)
+
+tune_gcd_p_SOURCES = tune-gcd-p.c
+tune_gcd_p_DEPENDENCIES = ../mpn/gcd.c
+tune_gcd_p_LDFLAGS = $(STATIC)
+
+
+tune:
+ $(MAKE) $(AM_MAKEFLAGS) tuneup$(EXEEXT)
+ ./tuneup
+
+allprogs: $(EXTRA_PROGRAMS)
+
+# $(MANY_CLEAN) and $(MANY_DISTCLEAN) are hooks for many.pl
+CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LTLIBRARIES) \
+ $(TUNE_MPN_SRCS) fac_ui.c sqr_asm.asm \
+ stg.gnuplot stg.data \
+ mtg.gnuplot mtg.data \
+ fibg.gnuplot fibg.data \
+ graph.gnuplot graph.data \
+ $(MANY_CLEAN)
+DISTCLEANFILES = sqr_basecase.c $(MANY_DISTCLEAN)
+
+
+# Generating these little files at build time seems better than including
+# them in the distribution, since the list can be changed more easily.
+#
+# mpn/generic/tdiv_qr.c uses mpn_divrem_1 and mpn_divrem_2, but only for 1
+# and 2 limb divisors, which are never used during tuning, so it doesn't
+# matter whether it picks up a tuned or untuned version of those.
+#
+# divrem_1 and mod_1 are recompiled renamed to "_tune" to avoid a linking
+# problem. If a native divrem_1 provides an mpn_divrem_1c entrypoint then
+# common.c will want that, but the generic divrem_1 doesn't provide it,
+# likewise for mod_1. The simplest way around this is to have the tune
+# build versions renamed suitably.
+#
+# FIXME: Would like say mul_n.c to depend on $(top_builddir)/mul_n.c so the
+# recompiled object will be rebuilt if that file changes.
+
+TUNE_MPN_SRCS = $(TUNE_MPN_SRCS_BASIC) divrem_1.c mod_1.c
+TUNE_MPN_SRCS_BASIC = div_qr_2.c bdiv_q.c bdiv_qr.c \
+ dcpi1_div_qr.c dcpi1_divappr_q.c dcpi1_bdiv_qr.c dcpi1_bdiv_q.c \
+ invertappr.c invert.c binvert.c divrem_2.c gcd.c gcdext.c \
+ get_str.c set_str.c matrix22_mul.c \
+ hgcd.c hgcd_appr.c hgcd_reduce.c \
+ mul_n.c sqr.c sec_powm.c \
+ mullo_n.c mul_fft.c mul.c tdiv_qr.c mulmod_bnm1.c sqrmod_bnm1.c \
+ mulmid.c mulmid_n.c toom42_mulmid.c \
+ nussbaumer_mul.c toom6h_mul.c toom8h_mul.c toom6_sqr.c toom8_sqr.c \
+ toom22_mul.c toom2_sqr.c toom33_mul.c toom3_sqr.c toom44_mul.c toom4_sqr.c
+
+$(TUNE_MPN_SRCS_BASIC):
+ for i in $(TUNE_MPN_SRCS_BASIC); do \
+ echo "#define TUNE_PROGRAM_BUILD 1" >$$i; \
+ echo "#include \"mpn/generic/$$i\"" >>$$i; \
+ done
+
+divrem_1.c:
+ echo "#define TUNE_PROGRAM_BUILD 1" >divrem_1.c
+ echo "#define __gmpn_divrem_1 mpn_divrem_1_tune" >>divrem_1.c
+ echo "#include \"mpn/generic/divrem_1.c\"" >>divrem_1.c
+
+mod_1.c:
+ echo "#define TUNE_PROGRAM_BUILD 1" >mod_1.c
+ echo "#define __gmpn_mod_1 mpn_mod_1_tune" >>mod_1.c
+ echo "#include \"mpn/generic/mod_1.c\"" >>mod_1.c
+
+sqr_asm.asm: $(top_builddir)/mpn/sqr_basecase.asm
+ echo 'define(SQR_TOOM2_THRESHOLD_OVERRIDE,SQR_TOOM2_THRESHOLD_MAX)' >sqr_asm.asm
+ echo 'include(../mpn/sqr_basecase.asm)' >>sqr_asm.asm
+
+# FIXME: Should it depend on $(top_builddir)/fac_ui.h too?
+fac_ui.c: $(top_builddir)/mpz/fac_ui.c
+ echo "#define TUNE_PROGRAM_BUILD 1" >fac_ui.c
+ echo "#define __gmpz_fac_ui mpz_fac_ui_tune" >>fac_ui.c
+ echo "#define __gmpz_oddfac_1 mpz_oddfac_1_tune" >>fac_ui.c
+ echo "#include \"mpz/oddfac_1.c\"" >>fac_ui.c
+ echo "#include \"mpz/fac_ui.c\"" >>fac_ui.c
+
+include ../mpn/Makeasm.am
diff --git a/gmp/tune/Makefile.in b/gmp/tune/Makefile.in
new file mode 100644
index 0000000000..07abb022a3
--- /dev/null
+++ b/gmp/tune/Makefile.in
@@ -0,0 +1,860 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2000-2003, 2005-2011 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+# Copyright 1996, 1998-2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+EXTRA_PROGRAMS = speed$(EXEEXT) speed-dynamic$(EXEEXT) \
+ speed-ext$(EXEEXT) tuneup$(EXEEXT) tune-gcd-p$(EXEEXT)
+DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/../mpn/Makeasm.am \
+ $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+subdir = tune
+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)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+am_libspeed_la_OBJECTS = common.lo divrem1div.lo divrem1inv.lo \
+ divrem2div.lo divrem2inv.lo div_qr_1n_pi1_1.lo \
+ div_qr_1n_pi1_2.lo div_qr_1_tune.lo freq.lo gcdext_single.lo \
+ gcdext_double.lo gcdextod.lo gcdextos.lo hgcd_lehmer.lo \
+ hgcd_appr_lehmer.lo hgcd_reduce_1.lo hgcd_reduce_2.lo \
+ jacbase1.lo jacbase2.lo jacbase3.lo jacbase4.lo mod_1_div.lo \
+ mod_1_inv.lo mod_1_1-1.lo mod_1_1-2.lo modlinv.lo noop.lo \
+ powm_mod.lo powm_redc.lo pre_divrem_1.lo set_strb.lo \
+ set_strs.lo set_strp.lo time.lo
+libspeed_la_OBJECTS = $(am_libspeed_la_OBJECTS)
+libspeed_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libspeed_la_LDFLAGS) $(LDFLAGS) -o $@
+am_speed_OBJECTS = speed.$(OBJEXT)
+speed_OBJECTS = $(am_speed_OBJECTS)
+speed_LDADD = $(LDADD)
+speed_DEPENDENCIES = $(DEPENDENCIES) $(am__DEPENDENCIES_1)
+speed_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(speed_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_speed_dynamic_OBJECTS = speed.$(OBJEXT)
+speed_dynamic_OBJECTS = $(am_speed_dynamic_OBJECTS)
+speed_dynamic_LDADD = $(LDADD)
+speed_dynamic_DEPENDENCIES = $(DEPENDENCIES) $(am__DEPENDENCIES_1)
+am_speed_ext_OBJECTS = speed-ext.$(OBJEXT)
+speed_ext_OBJECTS = $(am_speed_ext_OBJECTS)
+speed_ext_LDADD = $(LDADD)
+speed_ext_DEPENDENCIES = $(DEPENDENCIES) $(am__DEPENDENCIES_1)
+speed_ext_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(speed_ext_LDFLAGS) $(LDFLAGS) -o $@
+am_tune_gcd_p_OBJECTS = tune-gcd-p.$(OBJEXT)
+tune_gcd_p_OBJECTS = $(am_tune_gcd_p_OBJECTS)
+tune_gcd_p_LDADD = $(LDADD)
+tune_gcd_p_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(tune_gcd_p_LDFLAGS) $(LDFLAGS) -o $@
+am_tuneup_OBJECTS = tuneup.$(OBJEXT)
+am__objects_1 = div_qr_2.$(OBJEXT) bdiv_q.$(OBJEXT) bdiv_qr.$(OBJEXT) \
+ dcpi1_div_qr.$(OBJEXT) dcpi1_divappr_q.$(OBJEXT) \
+ dcpi1_bdiv_qr.$(OBJEXT) dcpi1_bdiv_q.$(OBJEXT) \
+ invertappr.$(OBJEXT) invert.$(OBJEXT) binvert.$(OBJEXT) \
+ divrem_2.$(OBJEXT) gcd.$(OBJEXT) gcdext.$(OBJEXT) \
+ get_str.$(OBJEXT) set_str.$(OBJEXT) matrix22_mul.$(OBJEXT) \
+ hgcd.$(OBJEXT) hgcd_appr.$(OBJEXT) hgcd_reduce.$(OBJEXT) \
+ mul_n.$(OBJEXT) sqr.$(OBJEXT) sec_powm.$(OBJEXT) \
+ mullo_n.$(OBJEXT) mul_fft.$(OBJEXT) mul.$(OBJEXT) \
+ tdiv_qr.$(OBJEXT) mulmod_bnm1.$(OBJEXT) sqrmod_bnm1.$(OBJEXT) \
+ mulmid.$(OBJEXT) mulmid_n.$(OBJEXT) toom42_mulmid.$(OBJEXT) \
+ nussbaumer_mul.$(OBJEXT) toom6h_mul.$(OBJEXT) \
+ toom8h_mul.$(OBJEXT) toom6_sqr.$(OBJEXT) toom8_sqr.$(OBJEXT) \
+ toom22_mul.$(OBJEXT) toom2_sqr.$(OBJEXT) toom33_mul.$(OBJEXT) \
+ toom3_sqr.$(OBJEXT) toom44_mul.$(OBJEXT) toom4_sqr.$(OBJEXT)
+am__objects_2 = $(am__objects_1) divrem_1.$(OBJEXT) mod_1.$(OBJEXT)
+nodist_tuneup_OBJECTS = sqr_basecase.$(OBJEXT) fac_ui.$(OBJEXT) \
+ $(am__objects_2)
+tuneup_OBJECTS = $(am_tuneup_OBJECTS) $(nodist_tuneup_OBJECTS)
+am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) libspeed.la
+tuneup_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(tuneup_LDFLAGS) \
+ $(LDFLAGS) -o $@
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libspeed_la_SOURCES) $(speed_SOURCES) \
+ $(speed_dynamic_SOURCES) $(speed_ext_SOURCES) \
+ $(tune_gcd_p_SOURCES) $(tuneup_SOURCES) \
+ $(nodist_tuneup_SOURCES)
+DIST_SOURCES = $(libspeed_la_SOURCES) $(speed_SOURCES) \
+ $(speed_dynamic_SOURCES) $(speed_ext_SOURCES) \
+ $(tune_gcd_p_SOURCES) $(tuneup_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+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@
+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@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
+EXTRA_DIST = alpha.asm pentium.asm sparcv9.asm hppa.asm hppa2.asm hppa2w.asm \
+ ia64.asm powerpc.asm powerpc64.asm x86_64.asm many.pl
+
+noinst_HEADERS = speed.h
+@ENABLE_STATIC_FALSE@STATIC =
+
+# Prefer -static on the speed and tune programs, since that can avoid
+# overheads of shared library linkages on some systems. Libtool tends to
+# botch -static if configured with --disable-static, perhaps reasonably
+# enough. In any event under --disable-static the only choice is a dynamic
+# link so there's no point in -static.
+#
+@ENABLE_STATIC_TRUE@STATIC = -static
+EXTRA_LTLIBRARIES = libspeed.la
+libspeed_la_SOURCES = \
+ common.c divrem1div.c divrem1inv.c divrem2div.c divrem2inv.c \
+ div_qr_1n_pi1_1.c div_qr_1n_pi1_2.c div_qr_1_tune.c \
+ freq.c \
+ gcdext_single.c gcdext_double.c gcdextod.c gcdextos.c \
+ hgcd_lehmer.c hgcd_appr_lehmer.c hgcd_reduce_1.c hgcd_reduce_2.c \
+ jacbase1.c jacbase2.c jacbase3.c jacbase4.c \
+ mod_1_div.c mod_1_inv.c mod_1_1-1.c mod_1_1-2.c modlinv.c \
+ noop.c powm_mod.c powm_redc.c pre_divrem_1.c \
+ set_strb.c set_strs.c set_strp.c time.c
+
+libspeed_la_DEPENDENCIES = $(SPEED_CYCLECOUNTER_OBJ) \
+ $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
+
+libspeed_la_LIBADD = $(libspeed_la_DEPENDENCIES) $(LIBM)
+libspeed_la_LDFLAGS = $(STATIC)
+DEPENDENCIES = libspeed.la
+LDADD = $(DEPENDENCIES) $(TUNE_LIBS)
+speed_SOURCES = speed.c
+speed_LDFLAGS = $(STATIC)
+speed_dynamic_SOURCES = speed.c
+speed_ext_SOURCES = speed-ext.c
+speed_ext_LDFLAGS = $(STATIC)
+tuneup_SOURCES = tuneup.c
+nodist_tuneup_SOURCES = sqr_basecase.c fac_ui.c $(TUNE_MPN_SRCS)
+tuneup_DEPENDENCIES = $(TUNE_SQR_OBJ) libspeed.la
+tuneup_LDADD = $(tuneup_DEPENDENCIES) $(TUNE_LIBS)
+tuneup_LDFLAGS = $(STATIC)
+tune_gcd_p_SOURCES = tune-gcd-p.c
+tune_gcd_p_DEPENDENCIES = ../mpn/gcd.c
+tune_gcd_p_LDFLAGS = $(STATIC)
+
+# $(MANY_CLEAN) and $(MANY_DISTCLEAN) are hooks for many.pl
+CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LTLIBRARIES) \
+ $(TUNE_MPN_SRCS) fac_ui.c sqr_asm.asm \
+ stg.gnuplot stg.data \
+ mtg.gnuplot mtg.data \
+ fibg.gnuplot fibg.data \
+ graph.gnuplot graph.data \
+ $(MANY_CLEAN)
+
+DISTCLEANFILES = sqr_basecase.c $(MANY_DISTCLEAN)
+
+# Generating these little files at build time seems better than including
+# them in the distribution, since the list can be changed more easily.
+#
+# mpn/generic/tdiv_qr.c uses mpn_divrem_1 and mpn_divrem_2, but only for 1
+# and 2 limb divisors, which are never used during tuning, so it doesn't
+# matter whether it picks up a tuned or untuned version of those.
+#
+# divrem_1 and mod_1 are recompiled renamed to "_tune" to avoid a linking
+# problem. If a native divrem_1 provides an mpn_divrem_1c entrypoint then
+# common.c will want that, but the generic divrem_1 doesn't provide it,
+# likewise for mod_1. The simplest way around this is to have the tune
+# build versions renamed suitably.
+#
+# FIXME: Would like say mul_n.c to depend on $(top_builddir)/mul_n.c so the
+# recompiled object will be rebuilt if that file changes.
+TUNE_MPN_SRCS = $(TUNE_MPN_SRCS_BASIC) divrem_1.c mod_1.c
+TUNE_MPN_SRCS_BASIC = div_qr_2.c bdiv_q.c bdiv_qr.c \
+ dcpi1_div_qr.c dcpi1_divappr_q.c dcpi1_bdiv_qr.c dcpi1_bdiv_q.c \
+ invertappr.c invert.c binvert.c divrem_2.c gcd.c gcdext.c \
+ get_str.c set_str.c matrix22_mul.c \
+ hgcd.c hgcd_appr.c hgcd_reduce.c \
+ mul_n.c sqr.c sec_powm.c \
+ mullo_n.c mul_fft.c mul.c tdiv_qr.c mulmod_bnm1.c sqrmod_bnm1.c \
+ mulmid.c mulmid_n.c toom42_mulmid.c \
+ nussbaumer_mul.c toom6h_mul.c toom8h_mul.c toom6_sqr.c toom8_sqr.c \
+ toom22_mul.c toom2_sqr.c toom33_mul.c toom3_sqr.c toom44_mul.c toom4_sqr.c
+
+
+# COMPILE minus CC.
+#
+COMPILE_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASMFLAGS)
+
+
+# Flags used for preprocessing (in ansi2knr rules).
+#
+PREPROCESS_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS)
+
+
+# Recent versions of automake (1.5 and up for instance) append automake
+# generated suffixes to this $(SUFFIXES) list. This is essential for us,
+# since .c must come after .s, .S and .asm. If .c is before .s, for
+# instance, then in the mpn directory "make" will see add_n.c mentioned in
+# an explicit rule (the ansi2knr stuff) and decide it must have add_n.c,
+# even if add_n.c doesn't exist but add_n.s does. See GNU make
+# documentation "(make)Implicit Rule Search", part 5c.
+#
+# On IRIX 6 native make this doesn't work properly though. Somehow .c
+# remains ahead of .s, perhaps because .c.s is a builtin rule. .asm works
+# fine though, and mpn/mips3 uses this.
+#
+SUFFIXES = .s .S .asm
+
+# can be overridden during development, eg. "make RM_TMP=: mul_1.lo"
+RM_TMP = rm -f
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .s .S .asm .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../mpn/Makeasm.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 tune/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu --ignore-deps tune/Makefile
+.PRECIOUS: 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;
+$(srcdir)/../mpn/Makeasm.am:
+
+$(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):
+libspeed.la: $(libspeed_la_OBJECTS) $(libspeed_la_DEPENDENCIES) $(EXTRA_libspeed_la_DEPENDENCIES)
+ $(libspeed_la_LINK) $(libspeed_la_OBJECTS) $(libspeed_la_LIBADD) $(LIBS)
+speed$(EXEEXT): $(speed_OBJECTS) $(speed_DEPENDENCIES) $(EXTRA_speed_DEPENDENCIES)
+ @rm -f speed$(EXEEXT)
+ $(speed_LINK) $(speed_OBJECTS) $(speed_LDADD) $(LIBS)
+speed-dynamic$(EXEEXT): $(speed_dynamic_OBJECTS) $(speed_dynamic_DEPENDENCIES) $(EXTRA_speed_dynamic_DEPENDENCIES)
+ @rm -f speed-dynamic$(EXEEXT)
+ $(LINK) $(speed_dynamic_OBJECTS) $(speed_dynamic_LDADD) $(LIBS)
+speed-ext$(EXEEXT): $(speed_ext_OBJECTS) $(speed_ext_DEPENDENCIES) $(EXTRA_speed_ext_DEPENDENCIES)
+ @rm -f speed-ext$(EXEEXT)
+ $(speed_ext_LINK) $(speed_ext_OBJECTS) $(speed_ext_LDADD) $(LIBS)
+tune-gcd-p$(EXEEXT): $(tune_gcd_p_OBJECTS) $(tune_gcd_p_DEPENDENCIES) $(EXTRA_tune_gcd_p_DEPENDENCIES)
+ @rm -f tune-gcd-p$(EXEEXT)
+ $(tune_gcd_p_LINK) $(tune_gcd_p_OBJECTS) $(tune_gcd_p_LDADD) $(LIBS)
+tuneup$(EXEEXT): $(tuneup_OBJECTS) $(tuneup_DEPENDENCIES) $(EXTRA_tuneup_DEPENDENCIES)
+ @rm -f tuneup$(EXEEXT)
+ $(tuneup_LINK) $(tuneup_OBJECTS) $(tuneup_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(HEADERS)
+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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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-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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool ctags 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 \
+ tags uninstall uninstall-am
+
+
+$(top_builddir)/tests/libtests.la:
+ cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
+
+tune:
+ $(MAKE) $(AM_MAKEFLAGS) tuneup$(EXEEXT)
+ ./tuneup
+
+allprogs: $(EXTRA_PROGRAMS)
+
+$(TUNE_MPN_SRCS_BASIC):
+ for i in $(TUNE_MPN_SRCS_BASIC); do \
+ echo "#define TUNE_PROGRAM_BUILD 1" >$$i; \
+ echo "#include \"mpn/generic/$$i\"" >>$$i; \
+ done
+
+divrem_1.c:
+ echo "#define TUNE_PROGRAM_BUILD 1" >divrem_1.c
+ echo "#define __gmpn_divrem_1 mpn_divrem_1_tune" >>divrem_1.c
+ echo "#include \"mpn/generic/divrem_1.c\"" >>divrem_1.c
+
+mod_1.c:
+ echo "#define TUNE_PROGRAM_BUILD 1" >mod_1.c
+ echo "#define __gmpn_mod_1 mpn_mod_1_tune" >>mod_1.c
+ echo "#include \"mpn/generic/mod_1.c\"" >>mod_1.c
+
+sqr_asm.asm: $(top_builddir)/mpn/sqr_basecase.asm
+ echo 'define(SQR_TOOM2_THRESHOLD_OVERRIDE,SQR_TOOM2_THRESHOLD_MAX)' >sqr_asm.asm
+ echo 'include(../mpn/sqr_basecase.asm)' >>sqr_asm.asm
+
+# FIXME: Should it depend on $(top_builddir)/fac_ui.h too?
+fac_ui.c: $(top_builddir)/mpz/fac_ui.c
+ echo "#define TUNE_PROGRAM_BUILD 1" >fac_ui.c
+ echo "#define __gmpz_fac_ui mpz_fac_ui_tune" >>fac_ui.c
+ echo "#define __gmpz_oddfac_1 mpz_oddfac_1_tune" >>fac_ui.c
+ echo "#include \"mpz/oddfac_1.c\"" >>fac_ui.c
+ echo "#include \"mpz/fac_ui.c\"" >>fac_ui.c
+
+# .s assembler, no preprocessing.
+#
+.s.o:
+ $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+.s.obj:
+ $(CCAS) $(COMPILE_FLAGS) `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+.s.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+# .S assembler, preprocessed with cpp.
+#
+# It's necessary to run $(CPP) separately, since it seems not all compilers
+# recognise .S files, in particular "cc" on HP-UX 10 and 11 doesn't (and
+# will silently do nothing if given a .S).
+#
+# For .lo we need a helper script, as described below for .asm.lo.
+#
+.S.o:
+ $(CPP) $(PREPROCESS_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$< | grep -v '^#' >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.S.obj:
+ $(CPP) $(PREPROCESS_FLAGS) `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` | grep -v '^#' >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.S.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(top_srcdir)/mpn/cpp-ccas --cpp="$(CPP) $(PREPROCESS_FLAGS)" $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+# .asm assembler, preprocessed with m4.
+#
+# .o and .obj are non-PIC and just need m4 followed by a compile.
+#
+# .lo is a bit tricky. Libtool (as of version 1.5) has foo.lo as a little
+# text file, and .libs/foo.o and foo.o as the PIC and non-PIC objects,
+# respectively. It'd be asking for lots of trouble to try to create foo.lo
+# ourselves, so instead arrange to invoke libtool like a --mode=compile, but
+# with a special m4-ccas script which first m4 preprocesses, then compiles.
+# --tag=CC is necessary since foo.asm is otherwise unknown to libtool.
+#
+# Libtool adds -DPIC when building a shared object and the .asm files look
+# for that. But it should be noted that the other PIC flags are on occasion
+# important too, in particular FreeBSD 2.2.8 gas 1.92.3 requires -k before
+# it accepts PIC constructs like @GOT, and gcc adds that flag only under
+# -fPIC. (Later versions of gas are happy to accept PIC stuff any time.)
+#
+.asm.o:
+ $(M4) -DOPERATION_$* `test -f '$<' || echo '$(srcdir)/'`$< >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.asm.obj:
+ $(M4) -DOPERATION_$* `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` >tmp-$*.s
+ $(CCAS) $(COMPILE_FLAGS) tmp-$*.s -o $@
+ $(RM_TMP) tmp-$*.s
+.asm.lo:
+ $(LIBTOOL) --mode=compile --tag=CC $(top_srcdir)/mpn/m4-ccas --m4="$(M4)" $(CCAS) $(COMPILE_FLAGS) `test -f '$<' || echo '$(srcdir)/'`$<
+
+# 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/gmp/tune/README b/gmp/tune/README
new file mode 100644
index 0000000000..f76407f7ca
--- /dev/null
+++ b/gmp/tune/README
@@ -0,0 +1,501 @@
+Copyright 2000-2002, 2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/.
+
+
+
+
+
+ GMP SPEED MEASURING AND PARAMETER TUNING
+
+
+The programs in this directory are for knowledgeable users who want to
+measure GMP routines on their machine, and perhaps tweak some settings or
+identify things that can be improved.
+
+The programs here are tools, not ready to run solutions. Nothing is built
+in a normal "make all", but various Makefile targets described below exist.
+
+Relatively few systems and CPUs have been tested, so be sure to verify that
+results are sensible before relying on them.
+
+
+
+
+MISCELLANEOUS NOTES
+
+--enable-assert
+
+ Don't configure with --enable-assert, since the extra code added by
+ assertion checking may influence measurements.
+
+Direct mapped caches
+
+ Some effort has been made to accommodate CPUs with direct mapped caches,
+ by putting data blocks more or less contiguously on the stack. But this
+ will depend on TMP_ALLOC using alloca, and even then it may or may not
+ be enough.
+
+FreeBSD 4.2 i486 getrusage
+
+ This getrusage seems to be a bit doubtful, it looks like it's
+ microsecond accurate, but sometimes ru_utime remains unchanged after a
+ time of many microseconds has elapsed. It'd be good to detect this in
+ the time.c initializations, but for now the suggestion is to pretend it
+ doesn't exist.
+
+ ./configure ac_cv_func_getrusage=no
+
+NetBSD 1.4.1 m68k macintosh time base
+
+ On this system it's been found getrusage often goes backwards, making it
+ unusable (time.c getrusage_backwards_p detects this). gettimeofday
+ sometimes doesn't update atomically when it crosses a 1 second boundary.
+ Not sure what to do about this. Expect possible intermittent failures.
+
+SCO OpenUNIX 8 /etc/hw
+
+ /etc/hw takes about a second to return the cpu frequency, which suggests
+ perhaps it's measuring each time it runs. If this is annoying when
+ running the speed program repeatedly then set a GMP_CPU_FREQUENCY
+ environment variable (see TIME BASE section below).
+
+Timing on GNU/Linux
+
+ On Linux, timing currently uses the cycle counter. This is unreliable,
+ since the counter is not saved and restored at context switches (unlike
+ FreeBSD and Solaris where the cycle counter is "virtualized").
+
+ Using the clock_gettime method with CLOCK_PROCESS_CPUTIME_ID (posix) or
+ CLOCK_VIRTUAL (BSD) should be more reliable. To get clock_gettime
+ with glibc, one has to link with -lrt (which also drags in the pthreads
+ threading library). configure.in must be hacked to detect this and
+ arrange proper linking. Something like
+
+ old_LIBS="$LIBS"
+ AC_SEARCH_LIBS(clock_gettime, rt, [AC_DEFINE(HAVE_CLOCK_GETTIME)])
+ TUNE_LIBS="$LIBS"
+ LIBS="$old_LIBS"
+
+ AC_SUBST(TUNE_LIBS)
+
+ might work.
+
+Low resolution timebase
+
+ Parameter tuning can be very time consuming if the only timebase
+ available is a 10 millisecond clock tick, to the point of being
+ unusable. This is currently the case on VAX and ARM systems.
+
+
+
+
+PARAMETER TUNING
+
+The "tuneup" program runs some tests designed to find the best settings for
+various thresholds, like MUL_TOOM22_THRESHOLD. Its output can be put
+into gmp-mparam.h. The program is built and run with
+
+ make tune
+
+If the thresholds indicated are grossly different from the values in the
+selected gmp-mparam.h then there may be a performance boost in applicable
+size ranges by changing gmp-mparam.h accordingly.
+
+Be sure to do a full reconfigure and rebuild to get any newly set thresholds
+to take effect. A partial rebuild is enough sometimes, but a fresh
+configure and make is certain to be correct.
+
+If a CPU has specific tuned parameters coming from a gmp-mparam.h in one of
+the mpn subdirectories then the values from "make tune" should be similar.
+But check that the configured CPU is right and there are no machine specific
+effects causing a difference.
+
+It's hoped the compiler and options used won't have too much effect on
+thresholds, since for most CPUs they ultimately come down to comparisons
+between assembler subroutines. Missing out on the longlong.h macros by not
+using gcc will probably have an effect.
+
+Some thresholds produced by the tune program are merely single values chosen
+from what's a range of sizes where two algorithms are pretty much the same
+speed. When this happens the program is likely to give somewhat different
+values on successive runs. This is noticeable on the toom3 thresholds for
+instance.
+
+
+
+
+SPEED PROGRAM
+
+The "speed" program can be used for measuring and comparing various
+routines, and producing tables of data or gnuplot graphs. Compile it with
+
+ make speed
+
+(Or on DOS systems "make speed.exe".)
+
+Here are some examples of how to use it. Check the code for all the
+options.
+
+Draw a graph of mpn_mul_n, stepping through sizes by 10 or a factor of 1.05
+(whichever is greater).
+
+ ./speed -s 10-5000 -t 10 -f 1.05 -P foo mpn_mul_n
+ gnuplot foo.gnuplot
+
+Compare mpn_add_n and an mpn_lshift by 1, showing times in cycles and
+showing under mpn_lshift the difference between it and mpn_add_n.
+
+ ./speed -s 1-40 -c -d mpn_add_n mpn_lshift.1
+
+Using option -c for times in cycles is interesting but normally only
+necessary when looking carefully at assembler subroutines. You might think
+it would always give an integer value, but this doesn't happen in practice,
+probably due to overheads in the time measurements.
+
+In the free-form output the "#" symbol against a measurement means the
+corresponding routine is fastest at that size. This is a convenient visual
+cue when comparing different routines. The graph data files <name>.data
+don't get this since it would upset gnuplot or other data viewers.
+
+
+
+
+TIME BASE
+
+The time measuring method is determined in time.c, based on what the
+configured host has available. A cycle counter is preferred, possibly
+supplemented by another method if the counter has a limited range. A
+microsecond accurate getrusage() or gettimeofday() will work quite well too.
+
+The cycle counters (except possibly on alpha) and gettimeofday() will depend
+on the machine being otherwise idle, or rather on other jobs not stealing
+CPU time from the measuring program. Short routines (those that complete
+within a timeslice) should work even on a busy machine.
+
+Some trouble is taken by speed_measure() in common.c to avoid ill effects
+from sporadic interrupts, or other intermittent things (like cron waking up
+every minute). But generally an idle machine will be necessary to be
+certain of consistent results.
+
+The CPU frequency is needed to convert between cycles and seconds, or for
+when a cycle counter is supplemented by getrusage() etc. The speed program
+will convert as necessary according to the output format requested. The
+tune program will work with either cycles or seconds.
+
+freq.c knows how to get the frequency on some systems, or can measure a
+cycle counter against gettimeofday() or getrusage(), but when that fails, or
+needs to be overridden, an environment variable GMP_CPU_FREQUENCY can be
+used (in Hertz). For example in "bash" on a 650 MHz machine,
+
+ export GMP_CPU_FREQUENCY=650e6
+
+A high precision time base makes it possible to get accurate measurements in
+a shorter time.
+
+
+
+
+EXAMPLE COMPARISONS - VARIOUS
+
+Here are some ideas for things that can be done with the speed program.
+
+There's always going to be a certain amount of overhead in the time
+measurements, due to reading the time base, and in the loop that runs a
+routine enough times to get a reading of the desired precision. Noop
+functions taking various arguments are available to measure this. The
+"overhead" printed by the speed program each time in its intro is the "noop"
+routine, but note that this is just for information, it isn't deducted from
+the times printed or anything.
+
+ ./speed -s 1 noop noop_wxs noop_wxys
+
+To see how many cycles per limb a routine is taking, look at the time
+increase when the size increments, using option -D. This avoids fixed
+overheads in the measuring. Also, remember many of the assembler routines
+have unrolled loops, so it might be necessary to compare times at, say, 16,
+32, 48, 64 etc to see what the unrolled part is taking, as opposed to any
+finishing off.
+
+ ./speed -s 16-64 -t 16 -C -D mpn_add_n
+
+The -C option on its own gives cycles per limb, but is really only useful at
+big sizes where fixed overheads are small compared to the code doing the
+real work. Remember of course memory caching and/or page swapping will
+affect results at large sizes.
+
+ ./speed -s 500000 -C mpn_add_n
+
+Once a calculation stops fitting in the CPU data cache, it's going to start
+taking longer. Exactly where this happens depends on the cache priming in
+the measuring routines, and on what sort of "least recently used" the
+hardware does. Here's an example for a CPU with a 16kbyte L1 data cache and
+32-bit limb, showing a suddenly steeper curve for mpn_add_n at about 2000
+limbs.
+
+ ./speed -s 1-4000 -t 5 -f 1.02 -P foo mpn_add_n
+ gnuplot foo.gnuplot
+
+When a routine has an unrolled loop for, say, multiples of 8 limbs and then
+an ordinary loop for the remainder, it can happen that it's actually faster
+to do an operation on, say, 8 limbs than it is on 7 limbs. The following
+draws a graph of mpn_sub_n, to see whether times smoothly increase with
+size.
+
+ ./speed -s 1-100 -c -P foo mpn_sub_n
+ gnuplot foo.gnuplot
+
+If mpn_lshift and mpn_rshift have special case code for shifts by 1, it
+ought to be faster (or at least not slower) than shifting by, say, 2 bits.
+
+ ./speed -s 1-200 -c mpn_rshift.1 mpn_rshift.2
+
+An mpn_lshift by 1 can be done by mpn_add_n adding a number to itself, and
+if the lshift isn't faster there's an obvious improvement that's possible.
+
+ ./speed -s 1-200 -c mpn_lshift.1 mpn_add_n_self
+
+On some CPUs (AMD K6 for example) an "in-place" mpn_add_n where the
+destination is one of the sources is faster than a separate destination.
+Here's an example to see this. ".1" selects dst==src1 for mpn_add_n (and
+mpn_sub_n), for other values see speed.h SPEED_ROUTINE_MPN_BINARY_N_CALL.
+
+ ./speed -s 1-200 -c mpn_add_n mpn_add_n.1
+
+The gmp manual points out that divisions by powers of two should be done
+using a right shift because it'll be significantly faster than an actual
+division. The following shows by what factor mpn_rshift is faster than
+mpn_divrem_1, using division by 32 as an example.
+
+ ./speed -s 10-20 -r mpn_rshift.5 mpn_divrem_1.32
+
+
+
+
+EXAMPLE COMPARISONS - MULTIPLICATION
+
+mul_basecase takes a ".<r>" parameter. If positive, it gives the second
+(smaller) operand size. For example to show speeds for 3x3 up to 20x3 in
+cycles,
+
+ ./speed -s 3-20 -c mpn_mul_basecase.3
+
+A negative ".<-r>" parameter fixes the size of the product to the absolute
+value r. For example to show speeds for 10x10 up to 19x1 in cycles,
+
+ ./speed -s 10-19 -c mpn_mul_basecase.-20
+
+mul_basecase with no parameter does an NxN multiply, so for example to show
+speeds in cycles for 1x1, 2x2, 3x3, etc, up to 20x20, in cycles,
+
+ ./speed -s 1-20 -c mpn_mul_basecase
+
+sqr_basecase is implemented by a "triangular" method on most CPUs, making it
+up to twice as fast as mul_basecase. In practice loop overheads and the
+products on the diagonal mean it falls short of this. Here's an example
+running the two and showing by what factor an NxN mul_basecase is slower
+than an NxN sqr_basecase. (Some versions of sqr_basecase only allow sizes
+below SQR_TOOM2_THRESHOLD, so if it crashes at that point don't worry.)
+
+ ./speed -s 1-20 -r mpn_sqr_basecase mpn_mul_basecase
+
+The technique described above with -CD for showing the time difference in
+cycles per limb between two size operations can be done on an NxN
+mul_basecase using -E to change the basis for the size increment to N*N.
+For instance a 20x20 operation is taken to be doing 400 limbs, and a 16x16
+doing 256 limbs. The following therefore shows the per crossproduct speed
+of mul_basecase and sqr_basecase at around 20x20 limbs.
+
+ ./speed -s 16-20 -t 4 -CDE mpn_mul_basecase mpn_sqr_basecase
+
+Of course sqr_basecase isn't really doing NxN crossproducts, but it can be
+interesting to compare it to mul_basecase as if it was. For sqr_basecase
+the -F option can be used to base the deltas on N*(N+1)/2 operations, which
+is the triangular products sqr_basecase does. For example,
+
+ ./speed -s 16-20 -t 4 -CDF mpn_sqr_basecase
+
+Both -E and -F are preliminary and might change. A consistent approach to
+using them when claiming certain per crossproduct or per triangularproduct
+speeds hasn't really been established, but the increment between speeds in
+the range karatsuba will call seems sensible, that being k to k/2. For
+instance, if the karatsuba threshold was 20 for the multiply and 30 for the
+square,
+
+ ./speed -s 10-20 -t 10 -CDE mpn_mul_basecase
+ ./speed -s 15-30 -t 15 -CDF mpn_sqr_basecase
+
+
+
+EXAMPLE COMPARISONS - MALLOC
+
+The gmp manual recommends application programs avoid excessive initializing
+and clearing of mpz_t variables (and mpq_t and mpf_t too). Every new
+variable will at a minimum go through an init, a realloc for its first
+store, and finally a clear. Quite how long that takes depends on the C
+library. The following compares an mpz_init/realloc/clear to a 10 limb
+mpz_add. Don't be surprised if the mallocing is quite slow.
+
+ ./speed -s 10 -c mpz_init_realloc_clear mpz_add
+
+On some systems malloc and free are much slower when dynamic linked. The
+speed-dynamic program can be used to see this. For example the following
+measures malloc/free, first static then dynamic.
+
+ ./speed -s 10 -c malloc_free
+ ./speed-dynamic -s 10 -c malloc_free
+
+Of course a real world program has big problems if it's doing so many
+mallocs and frees that it gets slowed down by a dynamic linked malloc.
+
+
+
+
+
+EXAMPLE COMPARISONS - STRING CONVERSIONS
+
+mpn_get_str does a binary to string conversion. The base is specified with
+a ".<r>" parameter, or decimal by default. Power of 2 bases are much faster
+than general bases. The following compares decimal and hex for instance.
+
+ ./speed -s 1-20 -c mpn_get_str mpn_get_str.16
+
+Smaller bases need more divisions to split a given size number, and so are
+slower. The following compares base 3 and base 9. On small operands 9 will
+be nearly twice as fast, though at bigger sizes this reduces since in the
+current implementation both divide repeatedly by 3^20 (or 3^40 for 64 bit
+limbs) and those divisions come to dominate.
+
+ ./speed -s 1-20 -cr mpn_get_str.3 mpn_get_str.9
+
+mpn_set_str does a string to binary conversion. The base is specified with
+a ".<r>" parameter, or decimal by default. Power of 2 bases are faster than
+general bases on large conversions.
+
+ ./speed -s 1-512 -f 2 -c mpn_set_str.8 mpn_set_str.10
+
+mpn_set_str also has some special case code for decimal which is a bit
+faster than the general case, basically by giving the compiler a chance to
+optimize some multiplications by 10.
+
+ ./speed -s 20-40 -c mpn_set_str.9 mpn_set_str.10 mpn_set_str.11
+
+
+
+
+EXAMPLE COMPARISONS - GCDs
+
+mpn_gcd_1 has a threshold for when to reduce using an initial x%y when both
+x and y are single limbs. This isn't tuned currently, but a value can be
+established by a measurement like
+
+ ./speed -s 10-32 mpn_gcd_1.10
+
+This runs src[0] from 10 to 32 bits, and y fixed at 10 bits. If the div
+threshold is high, say 31 so it's effectively disabled then a 32x10 bit gcd
+is done by nibbling away at the 32-bit operands bit-by-bit. When the
+threshold is small, say 1 bit, then an initial x%y is done to reduce it to a
+10x10 bit operation.
+
+The threshold in mpn/generic/gcd_1.c or the various assembler
+implementations can be tweaked up or down until there's no more speedups on
+interesting combinations of sizes. Note that this affects only a 1x1 limb
+operation and so isn't very important. (An Nx1 limb operation always does
+an initial modular reduction, using mpn_mod_1 or mpn_modexact_1_odd.)
+
+
+
+
+SPEED PROGRAM EXTENSIONS
+
+Potentially lots of things could be made available in the program, but it's
+been left at only the things that have actually been wanted and are likely
+to be reasonably useful in the future.
+
+Extensions should be fairly easy to make though. speed-ext.c is an example,
+in a style that should suit one-off tests, or new code fragments under
+development.
+
+many.pl is a script for generating a new speed program supplemented with
+alternate versions of the standard routines. It can be used for measuring
+experimental code, or for comparing different implementations that exist
+within a CPU family.
+
+
+
+
+THRESHOLD EXAMINING
+
+The speed program can be used to examine the speeds of different algorithms
+to check the tune program has done the right thing. For example to examine
+the karatsuba multiply threshold,
+
+ ./speed -s 5-40 mpn_mul_basecase mpn_kara_mul_n
+
+When examining the toom3 threshold, remember it depends on the karatsuba
+threshold, so the right karatsuba threshold needs to be compiled into the
+library first. The tune program uses specially recompiled versions of
+mpn/mul_n.c etc for this reason, but the speed program simply uses the
+normal libgmp.la.
+
+Note further that the various routines may recurse into themselves on sizes
+far enough above applicable thresholds. For example, mpn_kara_mul_n will
+recurse into itself on sizes greater than twice the compiled-in
+MUL_TOOM22_THRESHOLD.
+
+When doing the above comparison between mul_basecase and kara_mul_n what's
+probably of interest is mul_basecase versus a kara_mul_n that does one level
+of Karatsuba then calls to mul_basecase, but this only happens on sizes less
+than twice the compiled MUL_TOOM22_THRESHOLD. A larger value for that
+setting can be compiled-in to avoid the problem if necessary. The same
+applies to toom3 and DC, though in a trickier fashion.
+
+There are some upper limits on some of the thresholds, arising from arrays
+dimensioned according to a threshold (mpn_mul_n), or asm code with certain
+sized displacements (some x86 versions of sqr_basecase). So putting huge
+values for the thresholds, even just for testing, may fail.
+
+
+
+
+FUTURE
+
+Make a program to check the time base is working properly, for small and
+large measurements. Make it able to test each available method, including
+perhaps the apparent resolution of each.
+
+Make a general mechanism for specifying operand overlap, and a syntax like
+maybe "mpn_add_n.dst=src2" to select it. Some measuring routines do this
+sort of thing with the "r" parameter currently.
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
diff --git a/gmp/tune/alpha.asm b/gmp/tune/alpha.asm
new file mode 100644
index 0000000000..888c77fe9d
--- /dev/null
+++ b/gmp/tune/alpha.asm
@@ -0,0 +1,59 @@
+dnl Alpha time stamp counter access routine.
+
+dnl Copyright 2000, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C void speed_cyclecounter (unsigned int p[2]);
+C
+
+C The rpcc instruction returns a 64-bit value split into two 32-bit fields.
+C The lower 32 bits are set by the hardware, and the upper 32 bits are set
+C by the operating system. The real per-process cycle count is the sum of
+C these halves.
+
+C Unfortunately, some operating systems don't get this right. NetBSD 1.3 is
+C known to sometimes put garbage in the upper half. Whether newer NetBSD
+C versions get it right, is unknown to us.
+
+C rpcc measures cycles elapsed in the user program and hence should be very
+C accurate even on a busy system. Losing cache contents due to task
+C switching may have an effect though.
+
+ASM_START()
+PROLOGUE(speed_cyclecounter)
+ rpcc r0
+ srl r0,32,r1
+ addq r1,r0,r0
+ stl r0,0(r16)
+ stl r31,4(r16) C zero upper return word
+ ret r31,(r26),1
+EPILOGUE(speed_cyclecounter)
+ASM_END()
diff --git a/gmp/tune/common.c b/gmp/tune/common.c
new file mode 100644
index 0000000000..8d06b4dc02
--- /dev/null
+++ b/gmp/tune/common.c
@@ -0,0 +1,2659 @@
+/* Shared speed subroutines.
+
+Copyright 1999-2006, 2008-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __GMP_NO_ATTRIBUTE_CONST_PURE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h> /* for qsort */
+#include <string.h>
+#include <unistd.h>
+#if 0
+#include <sys/ioctl.h>
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#include "tests.h"
+#include "speed.h"
+
+
+int speed_option_addrs = 0;
+int speed_option_verbose = 0;
+int speed_option_cycles_broken = 0;
+
+
+/* Provide __clz_tab even if it's not required, for the benefit of new code
+ being tested with many.pl. */
+#ifndef COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#include "mp_clz_tab.c"
+#undef COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#endif
+
+
+void
+pentium_wbinvd(void)
+{
+#if 0
+ {
+ static int fd = -2;
+
+ if (fd == -2)
+ {
+ fd = open ("/dev/wbinvd", O_RDWR);
+ if (fd == -1)
+ perror ("open /dev/wbinvd");
+ }
+
+ if (fd != -1)
+ ioctl (fd, 0, 0);
+ }
+#endif
+
+#if 0
+#define WBINVDSIZE 1024*1024*2
+ {
+ static char *p = NULL;
+ int i, sum;
+
+ if (p == NULL)
+ p = malloc (WBINVDSIZE);
+
+#if 0
+ for (i = 0; i < WBINVDSIZE; i++)
+ p[i] = i & 0xFF;
+#endif
+
+ sum = 0;
+ for (i = 0; i < WBINVDSIZE; i++)
+ sum += p[i];
+
+ mpn_cache_fill_dummy (sum);
+ }
+#endif
+}
+
+
+int
+double_cmp_ptr (const double *p, const double *q)
+{
+ if (*p > *q) return 1;
+ if (*p < *q) return -1;
+ return 0;
+}
+
+
+/* Measure the speed of a given routine.
+
+ The routine is run with enough repetitions to make it take at least
+ speed_precision * speed_unittime. This aims to minimize the effects of a
+ limited accuracy time base and the overhead of the measuring itself.
+
+ Measurements are made looking for 4 results within TOLERANCE of each
+ other (or 3 for routines taking longer than 2 seconds). This aims to get
+ an accurate reading even if some runs are bloated by interrupts or task
+ switches or whatever.
+
+ The given (*fun)() is expected to run its function "s->reps" many times
+ and return the total elapsed time measured using speed_starttime() and
+ speed_endtime(). If the function doesn't support the given s->size or
+ s->r, -1.0 should be returned. See the various base routines below. */
+
+double
+speed_measure (double (*fun) (struct speed_params *s), struct speed_params *s)
+{
+#define TOLERANCE 1.01 /* 1% */
+ const int max_zeros = 10;
+
+ struct speed_params s_dummy;
+ int i, j, e;
+ double t[30];
+ double t_unsorted[30];
+ double reps_d;
+ int zeros = 0;
+
+ /* Use dummy parameters if caller doesn't provide any. Only a few special
+ "fun"s will cope with this, speed_noop() is one. */
+ if (s == NULL)
+ {
+ memset (&s_dummy, '\0', sizeof (s_dummy));
+ s = &s_dummy;
+ }
+
+ s->reps = 1;
+ s->time_divisor = 1.0;
+ for (i = 0; i < numberof (t); i++)
+ {
+ for (;;)
+ {
+ s->src_num = 0;
+ s->dst_num = 0;
+
+ t[i] = (*fun) (s);
+
+ if (speed_option_verbose >= 3)
+ gmp_printf("size=%ld reps=%u r=%Md attempt=%d %.9f\n",
+ (long) s->size, s->reps, s->r, i, t[i]);
+
+ if (t[i] == 0.0)
+ {
+ zeros++;
+ if (zeros > max_zeros)
+ {
+ fprintf (stderr, "Fatal error: too many (%d) failed measurements (0.0)\n", zeros);
+ abort ();
+ }
+ if (s->reps < 10000)
+ s->reps *= 2;
+
+ continue;
+ }
+
+ if (t[i] == -1.0)
+ return -1.0;
+
+ if (t[i] >= speed_unittime * speed_precision)
+ break;
+
+ /* go to a value of reps to make t[i] >= precision */
+ reps_d = ceil (1.1 * s->reps
+ * speed_unittime * speed_precision
+ / MAX (t[i], speed_unittime));
+ if (reps_d > 2e9 || reps_d < 1.0)
+ {
+ fprintf (stderr, "Fatal error: new reps bad: %.2f\n", reps_d);
+ fprintf (stderr, " (old reps %u, unittime %.4g, precision %d, t[i] %.4g)\n",
+ s->reps, speed_unittime, speed_precision, t[i]);
+ abort ();
+ }
+ s->reps = (unsigned) reps_d;
+ }
+ t[i] /= s->reps;
+ t_unsorted[i] = t[i];
+
+ if (speed_precision == 0)
+ return t[i];
+
+ /* require 3 values within TOLERANCE when >= 2 secs, 4 when below */
+ if (t[0] >= 2.0)
+ e = 3;
+ else
+ e = 4;
+
+ /* Look for e many t[]'s within TOLERANCE of each other to consider a
+ valid measurement. Return smallest among them. */
+ if (i >= e)
+ {
+ qsort (t, i+1, sizeof(t[0]), (qsort_function_t) double_cmp_ptr);
+ for (j = e-1; j < i; j++)
+ if (t[j] <= t[j-e+1] * TOLERANCE)
+ return t[j-e+1] / s->time_divisor;
+ }
+ }
+
+ fprintf (stderr, "speed_measure() could not get %d results within %.1f%%\n",
+ e, (TOLERANCE-1.0)*100.0);
+ fprintf (stderr, " unsorted sorted\n");
+ fprintf (stderr, " %.12f %.12f is about 0.5%%\n",
+ t_unsorted[0]*(TOLERANCE-1.0), t[0]*(TOLERANCE-1.0));
+ for (i = 0; i < numberof (t); i++)
+ fprintf (stderr, " %.09f %.09f\n", t_unsorted[i], t[i]);
+
+ return -1.0;
+}
+
+
+/* Read all of ptr,size to get it into the CPU memory cache.
+
+ A call to mpn_cache_fill_dummy() is used to make sure the compiler
+ doesn't optimize away the whole loop. Using "volatile mp_limb_t sum"
+ would work too, but the function call means we don't rely on every
+ compiler actually implementing volatile properly.
+
+ mpn_cache_fill_dummy() is in a separate source file to stop gcc thinking
+ it can inline it. */
+
+void
+mpn_cache_fill (mp_srcptr ptr, mp_size_t size)
+{
+ mp_limb_t sum = 0;
+ mp_size_t i;
+
+ for (i = 0; i < size; i++)
+ sum += ptr[i];
+
+ mpn_cache_fill_dummy(sum);
+}
+
+
+void
+mpn_cache_fill_write (mp_ptr ptr, mp_size_t size)
+{
+ mpn_cache_fill (ptr, size);
+
+#if 0
+ mpn_random (ptr, size);
+#endif
+
+#if 0
+ mp_size_t i;
+
+ for (i = 0; i < size; i++)
+ ptr[i] = i;
+#endif
+}
+
+
+void
+speed_operand_src (struct speed_params *s, mp_ptr ptr, mp_size_t size)
+{
+ if (s->src_num >= numberof (s->src))
+ {
+ fprintf (stderr, "speed_operand_src: no room left in s->src[]\n");
+ abort ();
+ }
+ s->src[s->src_num].ptr = ptr;
+ s->src[s->src_num].size = size;
+ s->src_num++;
+}
+
+
+void
+speed_operand_dst (struct speed_params *s, mp_ptr ptr, mp_size_t size)
+{
+ if (s->dst_num >= numberof (s->dst))
+ {
+ fprintf (stderr, "speed_operand_dst: no room left in s->dst[]\n");
+ abort ();
+ }
+ s->dst[s->dst_num].ptr = ptr;
+ s->dst[s->dst_num].size = size;
+ s->dst_num++;
+}
+
+
+void
+speed_cache_fill (struct speed_params *s)
+{
+ static struct speed_params prev;
+ int i;
+
+ /* FIXME: need a better way to get the format string for a pointer */
+
+ if (speed_option_addrs)
+ {
+ int different;
+
+ different = (s->dst_num != prev.dst_num || s->src_num != prev.src_num);
+ for (i = 0; i < s->dst_num; i++)
+ different |= (s->dst[i].ptr != prev.dst[i].ptr);
+ for (i = 0; i < s->src_num; i++)
+ different |= (s->src[i].ptr != prev.src[i].ptr);
+
+ if (different)
+ {
+ if (s->dst_num != 0)
+ {
+ printf ("dst");
+ for (i = 0; i < s->dst_num; i++)
+ printf (" %08lX", (unsigned long) s->dst[i].ptr);
+ printf (" ");
+ }
+
+ if (s->src_num != 0)
+ {
+ printf ("src");
+ for (i = 0; i < s->src_num; i++)
+ printf (" %08lX", (unsigned long) s->src[i].ptr);
+ printf (" ");
+ }
+ printf (" (cf sp approx %08lX)\n", (unsigned long) &different);
+
+ }
+
+ memcpy (&prev, s, sizeof(prev));
+ }
+
+ switch (s->cache) {
+ case 0:
+ for (i = 0; i < s->dst_num; i++)
+ mpn_cache_fill_write (s->dst[i].ptr, s->dst[i].size);
+ for (i = 0; i < s->src_num; i++)
+ mpn_cache_fill (s->src[i].ptr, s->src[i].size);
+ break;
+ case 1:
+ pentium_wbinvd();
+ break;
+ }
+}
+
+
+/* Miscellaneous options accepted by tune and speed programs under -o. */
+
+void
+speed_option_set (const char *s)
+{
+ int n;
+
+ if (strcmp (s, "addrs") == 0)
+ {
+ speed_option_addrs = 1;
+ }
+ else if (strcmp (s, "verbose") == 0)
+ {
+ speed_option_verbose++;
+ }
+ else if (sscanf (s, "verbose=%d", &n) == 1)
+ {
+ speed_option_verbose = n;
+ }
+ else if (strcmp (s, "cycles-broken") == 0)
+ {
+ speed_option_cycles_broken = 1;
+ }
+ else
+ {
+ printf ("Unrecognised -o option: %s\n", s);
+ exit (1);
+ }
+}
+
+
+/* The following are basic speed running routines for various gmp functions.
+ Many are very similar and use speed.h macros.
+
+ Each routine allocates it's own destination space for the result of the
+ function, because only it can know what the function needs.
+
+ speed_starttime() and speed_endtime() are put tight around the code to be
+ measured. Any setups are done outside the timed portion.
+
+ Each routine is responsible for its own cache priming.
+ speed_cache_fill() is a good way to do this, see examples in speed.h.
+ One cache priming possibility, for CPUs with write-allocate cache, and
+ functions that don't take too long, is to do one dummy call before timing
+ so as to cache everything that gets used. But speed_measure() runs a
+ routine at least twice and will take the smaller time, so this might not
+ be necessary.
+
+ Data alignment will be important, for source, destination and temporary
+ workspace. A routine can align its destination and workspace. Programs
+ using the routines will ensure s->xp and s->yp are aligned. Aligning
+ onto a CACHE_LINE_SIZE boundary is suggested. s->align_wp and
+ s->align_wp2 should be respected where it makes sense to do so.
+ SPEED_TMP_ALLOC_LIMBS is a good way to do this.
+
+ A loop of the following form can be expected to turn into good assembler
+ code on most CPUs, thereby minimizing overhead in the measurement. It
+ can always be assumed s->reps >= 1.
+
+ i = s->reps
+ do
+ foo();
+ while (--i != 0);
+
+ Additional parameters might be added to "struct speed_params" in the
+ future. Routines should ignore anything they don't use.
+
+ s->size can be used creatively, and s->xp and s->yp can be ignored. For
+ example, speed_mpz_fac_ui() uses s->size as n for the factorial. s->r is
+ just a user-supplied parameter. speed_mpn_lshift() uses it as a shift,
+ speed_mpn_mul_1() uses it as a multiplier. */
+
+
+/* MPN_COPY etc can be macros, so the _CALL forms are necessary */
+double
+speed_MPN_COPY (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (MPN_COPY);
+}
+double
+speed_MPN_COPY_INCR (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (MPN_COPY_INCR);
+}
+double
+speed_MPN_COPY_DECR (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (MPN_COPY_DECR);
+}
+#if HAVE_NATIVE_mpn_copyi
+double
+speed_mpn_copyi (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_copyi);
+}
+#endif
+#if HAVE_NATIVE_mpn_copyd
+double
+speed_mpn_copyd (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_copyd);
+}
+#endif
+double
+speed_memcpy (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY_BYTES (memcpy);
+}
+double
+speed_mpn_com (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_com);
+}
+double
+speed_mpn_sec_tabselect (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TABSELECT (mpn_sec_tabselect);
+}
+
+
+double
+speed_mpn_addmul_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1 (mpn_addmul_1);
+}
+double
+speed_mpn_submul_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1 (mpn_submul_1);
+}
+
+#if HAVE_NATIVE_mpn_addmul_2
+double
+speed_mpn_addmul_2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_2 (mpn_addmul_2);
+}
+#endif
+#if HAVE_NATIVE_mpn_addmul_3
+double
+speed_mpn_addmul_3 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_3 (mpn_addmul_3);
+}
+#endif
+#if HAVE_NATIVE_mpn_addmul_4
+double
+speed_mpn_addmul_4 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_4 (mpn_addmul_4);
+}
+#endif
+#if HAVE_NATIVE_mpn_addmul_5
+double
+speed_mpn_addmul_5 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_5 (mpn_addmul_5);
+}
+#endif
+#if HAVE_NATIVE_mpn_addmul_6
+double
+speed_mpn_addmul_6 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_6 (mpn_addmul_6);
+}
+#endif
+#if HAVE_NATIVE_mpn_addmul_7
+double
+speed_mpn_addmul_7 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_7 (mpn_addmul_7);
+}
+#endif
+#if HAVE_NATIVE_mpn_addmul_8
+double
+speed_mpn_addmul_8 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_8 (mpn_addmul_8);
+}
+#endif
+
+double
+speed_mpn_mul_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1 (mpn_mul_1);
+}
+double
+speed_mpn_mul_1_inplace (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1_INPLACE (mpn_mul_1);
+}
+
+#if HAVE_NATIVE_mpn_mul_2
+double
+speed_mpn_mul_2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_2 (mpn_mul_2);
+}
+#endif
+#if HAVE_NATIVE_mpn_mul_3
+double
+speed_mpn_mul_3 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_3 (mpn_mul_3);
+}
+#endif
+#if HAVE_NATIVE_mpn_mul_4
+double
+speed_mpn_mul_4 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_4 (mpn_mul_4);
+}
+#endif
+#if HAVE_NATIVE_mpn_mul_5
+double
+speed_mpn_mul_5 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_5 (mpn_mul_5);
+}
+#endif
+#if HAVE_NATIVE_mpn_mul_6
+double
+speed_mpn_mul_6 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_6 (mpn_mul_6);
+}
+#endif
+
+
+double
+speed_mpn_lshift (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1 (mpn_lshift);
+}
+double
+speed_mpn_lshiftc (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1 (mpn_lshiftc);
+}
+double
+speed_mpn_rshift (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1 (mpn_rshift);
+}
+
+
+/* The carry-in variants (if available) are good for measuring because they
+ won't skip a division if high<divisor. Alternately, use -1 as a divisor
+ with the plain _1 forms. */
+double
+speed_mpn_divrem_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_1 (mpn_divrem_1);
+}
+double
+speed_mpn_divrem_1f (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_1F (mpn_divrem_1);
+}
+#if HAVE_NATIVE_mpn_divrem_1c
+double
+speed_mpn_divrem_1c (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_1C (mpn_divrem_1c);
+}
+double
+speed_mpn_divrem_1cf (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_1CF (mpn_divrem_1c);
+}
+#endif
+
+double
+speed_mpn_divrem_1_div (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_1 (mpn_divrem_1_div);
+}
+double
+speed_mpn_divrem_1f_div (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_1F (mpn_divrem_1_div);
+}
+double
+speed_mpn_divrem_1_inv (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_1 (mpn_divrem_1_inv);
+}
+double
+speed_mpn_divrem_1f_inv (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_1F (mpn_divrem_1_inv);
+}
+double
+speed_mpn_mod_1_div (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1 (mpn_mod_1_div);
+}
+double
+speed_mpn_mod_1_inv (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1 (mpn_mod_1_inv);
+}
+
+double
+speed_mpn_preinv_divrem_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PREINV_DIVREM_1 (mpn_preinv_divrem_1);
+}
+double
+speed_mpn_preinv_divrem_1f (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PREINV_DIVREM_1F (mpn_preinv_divrem_1);
+}
+
+#if GMP_NUMB_BITS % 4 == 0
+double
+speed_mpn_mod_34lsub1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_34LSUB1 (mpn_mod_34lsub1);
+}
+#endif
+
+double
+speed_mpn_divrem_2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_2 (mpn_divrem_2);
+}
+double
+speed_mpn_divrem_2_div (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_2 (mpn_divrem_2_div);
+}
+double
+speed_mpn_divrem_2_inv (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_2 (mpn_divrem_2_inv);
+}
+
+double
+speed_mpn_div_qr_1n_pi1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIV_QR_1N_PI1 (mpn_div_qr_1n_pi1);
+}
+double
+speed_mpn_div_qr_1n_pi1_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIV_QR_1N_PI1 (mpn_div_qr_1n_pi1_1);
+}
+double
+speed_mpn_div_qr_1n_pi1_2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIV_QR_1N_PI1 (mpn_div_qr_1n_pi1_2);
+}
+
+double
+speed_mpn_div_qr_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIV_QR_1 (mpn_div_qr_1);
+}
+
+double
+speed_mpn_div_qr_2n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIV_QR_2 (mpn_div_qr_2, 1);
+}
+double
+speed_mpn_div_qr_2u (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIV_QR_2 (mpn_div_qr_2, 0);
+}
+
+double
+speed_mpn_mod_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1 (mpn_mod_1);
+}
+#if HAVE_NATIVE_mpn_mod_1c
+double
+speed_mpn_mod_1c (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1C (mpn_mod_1c);
+}
+#endif
+double
+speed_mpn_preinv_mod_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PREINV_MOD_1 (mpn_preinv_mod_1);
+}
+double
+speed_mpn_mod_1_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1_1 (mpn_mod_1_1p,mpn_mod_1_1p_cps);
+}
+double
+speed_mpn_mod_1_1_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1_1 (mpn_mod_1_1p_1,mpn_mod_1_1p_cps_1);
+}
+double
+speed_mpn_mod_1_1_2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1_1 (mpn_mod_1_1p_2,mpn_mod_1_1p_cps_2);
+}
+double
+speed_mpn_mod_1_2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1_N (mpn_mod_1s_2p,mpn_mod_1s_2p_cps,2);
+}
+double
+speed_mpn_mod_1_3 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1_N (mpn_mod_1s_3p,mpn_mod_1s_3p_cps,3);
+}
+double
+speed_mpn_mod_1_4 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1_N (mpn_mod_1s_4p,mpn_mod_1s_4p_cps,4);
+}
+
+double
+speed_mpn_divexact_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVEXACT_1 (mpn_divexact_1);
+}
+
+double
+speed_mpn_divexact_by3 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_divexact_by3);
+}
+
+double
+speed_mpn_bdiv_dbm1c (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BDIV_DBM1C (mpn_bdiv_dbm1c);
+}
+
+double
+speed_mpn_bdiv_q_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BDIV_Q_1 (mpn_bdiv_q_1);
+}
+
+double
+speed_mpn_pi1_bdiv_q_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PI1_BDIV_Q_1 (mpn_pi1_bdiv_q_1);
+}
+
+#if HAVE_NATIVE_mpn_modexact_1_odd
+double
+speed_mpn_modexact_1_odd (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MODEXACT_1_ODD (mpn_modexact_1_odd);
+}
+#endif
+
+double
+speed_mpn_modexact_1c_odd (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MODEXACT_1C_ODD (mpn_modexact_1c_odd);
+}
+
+double
+speed_mpz_mod (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_MOD (mpz_mod);
+}
+
+double
+speed_mpn_sbpi1_div_qr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PI1_DIV (mpn_sbpi1_div_qr, inv.inv32, 2,0);
+}
+double
+speed_mpn_dcpi1_div_qr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PI1_DIV (mpn_dcpi1_div_qr, &inv, 6,3);
+}
+double
+speed_mpn_sbpi1_divappr_q (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PI1_DIV (mpn_sbpi1_divappr_q, inv.inv32, 2,0);
+}
+double
+speed_mpn_dcpi1_divappr_q (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PI1_DIV (mpn_dcpi1_divappr_q, &inv, 6,3);
+}
+double
+speed_mpn_mu_div_qr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MU_DIV_QR (mpn_mu_div_qr, mpn_mu_div_qr_itch);
+}
+double
+speed_mpn_mu_divappr_q (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MU_DIV_Q (mpn_mu_divappr_q, mpn_mu_divappr_q_itch);
+}
+double
+speed_mpn_mu_div_q (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MU_DIV_Q (mpn_mu_div_q, mpn_mu_div_q_itch);
+}
+double
+speed_mpn_mupi_div_qr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUPI_DIV_QR (mpn_preinv_mu_div_qr, mpn_preinv_mu_div_qr_itch);
+}
+
+double
+speed_mpn_sbpi1_bdiv_qr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PI1_BDIV_QR (mpn_sbpi1_bdiv_qr);
+}
+double
+speed_mpn_dcpi1_bdiv_qr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PI1_BDIV_QR (mpn_dcpi1_bdiv_qr);
+}
+double
+speed_mpn_sbpi1_bdiv_q (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PI1_BDIV_Q (mpn_sbpi1_bdiv_q);
+}
+double
+speed_mpn_dcpi1_bdiv_q (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_PI1_BDIV_Q (mpn_dcpi1_bdiv_q);
+}
+double
+speed_mpn_mu_bdiv_q (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MU_BDIV_Q (mpn_mu_bdiv_q, mpn_mu_bdiv_q_itch);
+}
+double
+speed_mpn_mu_bdiv_qr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MU_BDIV_QR (mpn_mu_bdiv_qr, mpn_mu_bdiv_qr_itch);
+}
+
+double
+speed_mpn_broot (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BROOT (mpn_broot);
+}
+double
+speed_mpn_broot_invm1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BROOT (mpn_broot_invm1);
+}
+double
+speed_mpn_brootinv (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BROOTINV (mpn_brootinv, 5*s->size);
+}
+
+double
+speed_mpn_binvert (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINVERT (mpn_binvert, mpn_binvert_itch);
+}
+
+double
+speed_mpn_invert (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_INVERT (mpn_invert, mpn_invert_itch);
+}
+
+double
+speed_mpn_invertappr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_INVERTAPPR (mpn_invertappr, mpn_invertappr_itch);
+}
+
+double
+speed_mpn_ni_invertappr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_INVERTAPPR (mpn_ni_invertappr, mpn_invertappr_itch);
+}
+
+double
+speed_mpn_sec_invert (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SEC_INVERT (mpn_sec_invert, mpn_sec_invert_itch);
+}
+
+double
+speed_mpn_redc_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_REDC_1 (mpn_redc_1);
+}
+double
+speed_mpn_redc_2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_REDC_2 (mpn_redc_2);
+}
+double
+speed_mpn_redc_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_REDC_N (mpn_redc_n);
+}
+
+
+double
+speed_mpn_popcount (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_POPCOUNT (mpn_popcount);
+}
+double
+speed_mpn_hamdist (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_HAMDIST (mpn_hamdist);
+}
+
+
+double
+speed_mpn_add_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N (mpn_add_n);
+}
+double
+speed_mpn_sub_n (struct speed_params *s)
+{
+SPEED_ROUTINE_MPN_BINARY_N (mpn_sub_n);
+}
+
+double
+speed_mpn_add_err1_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_ERR1_N (mpn_add_err1_n);
+}
+double
+speed_mpn_sub_err1_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_ERR1_N (mpn_sub_err1_n);
+}
+double
+speed_mpn_add_err2_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_ERR2_N (mpn_add_err2_n);
+}
+double
+speed_mpn_sub_err2_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_ERR2_N (mpn_sub_err2_n);
+}
+double
+speed_mpn_add_err3_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_ERR3_N (mpn_add_err3_n);
+}
+double
+speed_mpn_sub_err3_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_ERR3_N (mpn_sub_err3_n);
+}
+
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+double
+speed_mpn_add_n_sub_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_ADDSUB_N_CALL (mpn_add_n_sub_n (ap, sp, s->xp, s->yp, s->size));
+}
+#endif
+
+#if HAVE_NATIVE_mpn_addlsh1_n == 1
+double
+speed_mpn_addlsh1_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N (mpn_addlsh1_n);
+}
+#endif
+#if HAVE_NATIVE_mpn_sublsh1_n == 1
+double
+speed_mpn_sublsh1_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N (mpn_sublsh1_n);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh1_n_ip1
+double
+speed_mpn_addlsh1_n_ip1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_addlsh1_n_ip1);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh1_n_ip2
+double
+speed_mpn_addlsh1_n_ip2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_addlsh1_n_ip2);
+}
+#endif
+#if HAVE_NATIVE_mpn_sublsh1_n_ip1
+double
+speed_mpn_sublsh1_n_ip1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_sublsh1_n_ip1);
+}
+#endif
+#if HAVE_NATIVE_mpn_rsblsh1_n == 1
+double
+speed_mpn_rsblsh1_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N (mpn_rsblsh1_n);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n == 1
+double
+speed_mpn_addlsh2_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N (mpn_addlsh2_n);
+}
+#endif
+#if HAVE_NATIVE_mpn_sublsh2_n == 1
+double
+speed_mpn_sublsh2_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N (mpn_sublsh2_n);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n_ip1
+double
+speed_mpn_addlsh2_n_ip1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_addlsh2_n_ip1);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n_ip2
+double
+speed_mpn_addlsh2_n_ip2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_addlsh2_n_ip2);
+}
+#endif
+#if HAVE_NATIVE_mpn_sublsh2_n_ip1
+double
+speed_mpn_sublsh2_n_ip1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_COPY (mpn_sublsh2_n_ip1);
+}
+#endif
+#if HAVE_NATIVE_mpn_rsblsh2_n == 1
+double
+speed_mpn_rsblsh2_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N (mpn_rsblsh2_n);
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n
+double
+speed_mpn_addlsh_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_addlsh_n (wp, xp, yp, s->size, 7));
+}
+#endif
+#if HAVE_NATIVE_mpn_sublsh_n
+double
+speed_mpn_sublsh_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_sublsh_n (wp, xp, yp, s->size, 7));
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n_ip1
+double
+speed_mpn_addlsh_n_ip1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1_CALL (mpn_addlsh_n_ip1 (wp, s->xp, s->size, 7));
+}
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n_ip2
+double
+speed_mpn_addlsh_n_ip2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1_CALL (mpn_addlsh_n_ip2 (wp, s->xp, s->size, 7));
+}
+#endif
+#if HAVE_NATIVE_mpn_sublsh_n_ip1
+double
+speed_mpn_sublsh_n_ip1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_UNARY_1_CALL (mpn_sublsh_n_ip1 (wp, s->xp, s->size, 7));
+}
+#endif
+#if HAVE_NATIVE_mpn_rsblsh_n
+double
+speed_mpn_rsblsh_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_rsblsh_n (wp, xp, yp, s->size, 7));
+}
+#endif
+#if HAVE_NATIVE_mpn_rsh1add_n
+double
+speed_mpn_rsh1add_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N (mpn_rsh1add_n);
+}
+#endif
+#if HAVE_NATIVE_mpn_rsh1sub_n
+double
+speed_mpn_rsh1sub_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N (mpn_rsh1sub_n);
+}
+#endif
+
+double
+speed_mpn_cnd_add_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_cnd_add_n (1, wp, xp, yp, s->size));
+}
+double
+speed_mpn_cnd_sub_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_cnd_sub_n (1, wp, xp, yp, s->size));
+}
+
+/* mpn_and_n etc can be macros and so have to be handled with
+ SPEED_ROUTINE_MPN_BINARY_N_CALL forms */
+double
+speed_mpn_and_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_and_n (wp, xp, yp, s->size));
+}
+double
+speed_mpn_andn_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_andn_n (wp, xp, yp, s->size));
+}
+double
+speed_mpn_nand_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_nand_n (wp, xp, yp, s->size));
+}
+double
+speed_mpn_ior_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_ior_n (wp, xp, yp, s->size));
+}
+double
+speed_mpn_iorn_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_iorn_n (wp, xp, yp, s->size));
+}
+double
+speed_mpn_nior_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_nior_n (wp, xp, yp, s->size));
+}
+double
+speed_mpn_xor_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_xor_n (wp, xp, yp, s->size));
+}
+double
+speed_mpn_xnor_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_BINARY_N_CALL (mpn_xnor_n (wp, xp, yp, s->size));
+}
+
+
+double
+speed_mpn_mul_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUL_N (mpn_mul_n);
+}
+double
+speed_mpn_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SQR (mpn_sqr);
+}
+double
+speed_mpn_mul_n_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SQR_CALL (mpn_mul_n (wp, s->xp, s->xp, s->size));
+}
+
+double
+speed_mpn_mul_basecase (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUL(mpn_mul_basecase);
+}
+double
+speed_mpn_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUL(mpn_mul);
+}
+double
+speed_mpn_sqr_basecase (struct speed_params *s)
+{
+ /* FIXME: size restrictions on some versions of sqr_basecase */
+ SPEED_ROUTINE_MPN_SQR (mpn_sqr_basecase);
+}
+
+#if HAVE_NATIVE_mpn_sqr_diagonal
+double
+speed_mpn_sqr_diagonal (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SQR (mpn_sqr_diagonal);
+}
+#endif
+
+#if HAVE_NATIVE_mpn_sqr_diag_addlsh1
+double
+speed_mpn_sqr_diag_addlsh1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SQR_DIAG_ADDLSH1_CALL (mpn_sqr_diag_addlsh1 (wp, tp, s->xp, s->size));
+}
+#endif
+
+double
+speed_mpn_toom2_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM2_SQR (mpn_toom2_sqr);
+}
+double
+speed_mpn_toom3_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM3_SQR (mpn_toom3_sqr);
+}
+double
+speed_mpn_toom4_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM4_SQR (mpn_toom4_sqr);
+}
+double
+speed_mpn_toom6_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM6_SQR (mpn_toom6_sqr);
+}
+double
+speed_mpn_toom8_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM8_SQR (mpn_toom8_sqr);
+}
+double
+speed_mpn_toom22_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM22_MUL_N (mpn_toom22_mul);
+}
+double
+speed_mpn_toom33_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM33_MUL_N (mpn_toom33_mul);
+}
+double
+speed_mpn_toom44_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM44_MUL_N (mpn_toom44_mul);
+}
+double
+speed_mpn_toom6h_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM6H_MUL_N (mpn_toom6h_mul);
+}
+double
+speed_mpn_toom8h_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM8H_MUL_N (mpn_toom8h_mul);
+}
+
+double
+speed_mpn_toom32_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM32_MUL (mpn_toom32_mul);
+}
+double
+speed_mpn_toom42_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM42_MUL (mpn_toom42_mul);
+}
+double
+speed_mpn_toom43_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM43_MUL (mpn_toom43_mul);
+}
+double
+speed_mpn_toom63_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM63_MUL (mpn_toom63_mul);
+}
+double
+speed_mpn_toom32_for_toom43_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM32_FOR_TOOM43_MUL (mpn_toom32_mul);
+}
+double
+speed_mpn_toom43_for_toom32_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM43_FOR_TOOM32_MUL (mpn_toom43_mul);
+}
+double
+speed_mpn_toom32_for_toom53_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM32_FOR_TOOM53_MUL (mpn_toom32_mul);
+}
+double
+speed_mpn_toom53_for_toom32_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM53_FOR_TOOM32_MUL (mpn_toom53_mul);
+}
+double
+speed_mpn_toom42_for_toom53_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM42_FOR_TOOM53_MUL (mpn_toom42_mul);
+}
+double
+speed_mpn_toom53_for_toom42_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM53_FOR_TOOM42_MUL (mpn_toom53_mul);
+}
+double
+speed_mpn_toom43_for_toom54_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM43_FOR_TOOM54_MUL (mpn_toom43_mul);
+}
+double
+speed_mpn_toom54_for_toom43_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM54_FOR_TOOM43_MUL (mpn_toom54_mul);
+}
+
+double
+speed_mpn_nussbaumer_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUL_N_CALL
+ (mpn_nussbaumer_mul (wp, s->xp, s->size, s->yp, s->size));
+}
+double
+speed_mpn_nussbaumer_mul_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SQR_CALL
+ (mpn_nussbaumer_mul (wp, s->xp, s->size, s->xp, s->size));
+}
+
+#if WANT_OLD_FFT_FULL
+double
+speed_mpn_mul_fft_full (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUL_N_CALL
+ (mpn_mul_fft_full (wp, s->xp, s->size, s->yp, s->size));
+}
+double
+speed_mpn_mul_fft_full_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SQR_CALL
+ (mpn_mul_fft_full (wp, s->xp, s->size, s->xp, s->size));
+}
+#endif
+
+/* These are mod 2^N+1 multiplies and squares. If s->r is supplied it's
+ used as k, otherwise the best k for the size is used. If s->size isn't a
+ multiple of 2^k it's rounded up to make the effective operation size. */
+
+#define SPEED_ROUTINE_MPN_MUL_FFT_CALL(call, sqr) \
+ { \
+ mp_ptr wp; \
+ mp_size_t pl; \
+ int k; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ if (s->r != 0) \
+ k = s->r; \
+ else \
+ k = mpn_fft_best_k (s->size, sqr); \
+ \
+ TMP_MARK; \
+ pl = mpn_fft_next_size (s->size, k); \
+ SPEED_TMP_ALLOC_LIMBS (wp, pl+1, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ if (!sqr) \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, pl+1); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+double
+speed_mpn_mul_fft (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUL_FFT_CALL
+ (mpn_mul_fft (wp, pl, s->xp, s->size, s->yp, s->size, k), 0);
+}
+
+double
+speed_mpn_mul_fft_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUL_FFT_CALL
+ (mpn_mul_fft (wp, pl, s->xp, s->size, s->xp, s->size, k), 1);
+}
+
+double
+speed_mpn_fft_mul (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUL_N_CALL (mpn_fft_mul (wp, s->xp, s->size, s->yp, s->size));
+}
+
+double
+speed_mpn_fft_sqr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SQR_CALL (mpn_fft_mul (wp, s->xp, s->size, s->xp, s->size));
+}
+
+double
+speed_mpn_mullo_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MULLO_N (mpn_mullo_n);
+}
+double
+speed_mpn_mullo_basecase (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MULLO_BASECASE (mpn_mullo_basecase);
+}
+
+double
+speed_mpn_mulmid_basecase (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MULMID (mpn_mulmid_basecase);
+}
+
+double
+speed_mpn_mulmid (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MULMID (mpn_mulmid);
+}
+
+double
+speed_mpn_mulmid_n (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MULMID_N (mpn_mulmid_n);
+}
+
+double
+speed_mpn_toom42_mulmid (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_TOOM42_MULMID (mpn_toom42_mulmid);
+}
+
+double
+speed_mpn_mulmod_bnm1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MULMOD_BNM1_CALL (mpn_mulmod_bnm1 (wp, s->size, s->xp, s->size, s->yp, s->size, tp));
+}
+
+double
+speed_mpn_bc_mulmod_bnm1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MULMOD_BNM1_CALL (mpn_bc_mulmod_bnm1 (wp, s->xp, s->yp, s->size, tp));
+}
+
+double
+speed_mpn_mulmod_bnm1_rounded (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MULMOD_BNM1_ROUNDED (mpn_mulmod_bnm1);
+}
+
+double
+speed_mpn_sqrmod_bnm1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MULMOD_BNM1_CALL (mpn_sqrmod_bnm1 (wp, s->size, s->xp, s->size, tp));
+}
+
+double
+speed_mpn_matrix22_mul (struct speed_params *s)
+{
+ /* Speed params only includes 2 inputs, so we have to invent the
+ other 6. */
+
+ mp_ptr a;
+ mp_ptr r;
+ mp_ptr b;
+ mp_ptr tp;
+ mp_size_t itch;
+ unsigned i;
+ double t;
+ TMP_DECL;
+
+ TMP_MARK;
+ SPEED_TMP_ALLOC_LIMBS (a, 4 * s->size, s->align_xp);
+ SPEED_TMP_ALLOC_LIMBS (b, 4 * s->size, s->align_yp);
+ SPEED_TMP_ALLOC_LIMBS (r, 8 * s->size + 4, s->align_wp);
+
+ MPN_COPY (a, s->xp, s->size);
+ mpn_random (a + s->size, 3 * s->size);
+ MPN_COPY (b, s->yp, s->size);
+ mpn_random (b + s->size, 3 * s->size);
+
+ itch = mpn_matrix22_mul_itch (s->size, s->size);
+ SPEED_TMP_ALLOC_LIMBS (tp, itch, s->align_wp2);
+
+ speed_operand_src (s, a, 4 * s->size);
+ speed_operand_src (s, b, 4 * s->size);
+ speed_operand_dst (s, r, 8 * s->size + 4);
+ speed_operand_dst (s, tp, itch);
+ speed_cache_fill (s);
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ {
+ mp_size_t sz = s->size;
+ MPN_COPY (r + 0 * sz + 0, a + 0 * sz, sz);
+ MPN_COPY (r + 2 * sz + 1, a + 1 * sz, sz);
+ MPN_COPY (r + 4 * sz + 2, a + 2 * sz, sz);
+ MPN_COPY (r + 6 * sz + 3, a + 3 * sz, sz);
+ mpn_matrix22_mul (r, r + 2 * sz + 1, r + 4 * sz + 2, r + 6 * sz + 3, sz,
+ b, b + 1 * sz, b + 2 * sz, b + 3 * sz, sz,
+ tp);
+ }
+ while (--i != 0);
+ t = speed_endtime();
+ TMP_FREE;
+ return t;
+}
+
+double
+speed_mpn_hgcd (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_HGCD_CALL (mpn_hgcd, mpn_hgcd_itch);
+}
+
+double
+speed_mpn_hgcd_lehmer (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_HGCD_CALL (mpn_hgcd_lehmer, mpn_hgcd_lehmer_itch);
+}
+
+double
+speed_mpn_hgcd_appr (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_HGCD_CALL (mpn_hgcd_appr, mpn_hgcd_appr_itch);
+}
+
+double
+speed_mpn_hgcd_appr_lehmer (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_HGCD_CALL (mpn_hgcd_appr_lehmer, mpn_hgcd_appr_lehmer_itch);
+}
+
+double
+speed_mpn_hgcd_reduce (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_HGCD_REDUCE_CALL (mpn_hgcd_reduce, mpn_hgcd_reduce_itch);
+}
+double
+speed_mpn_hgcd_reduce_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_HGCD_REDUCE_CALL (mpn_hgcd_reduce_1, mpn_hgcd_reduce_1_itch);
+}
+double
+speed_mpn_hgcd_reduce_2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_HGCD_REDUCE_CALL (mpn_hgcd_reduce_2, mpn_hgcd_reduce_2_itch);
+}
+
+double
+speed_mpn_gcd (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GCD (mpn_gcd);
+}
+
+double
+speed_mpn_gcdext (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GCDEXT (mpn_gcdext);
+}
+#if 0
+double
+speed_mpn_gcdext_lehmer (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GCDEXT (__gmpn_gcdext_lehmer);
+}
+#endif
+double
+speed_mpn_gcdext_single (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GCDEXT (mpn_gcdext_single);
+}
+double
+speed_mpn_gcdext_double (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GCDEXT (mpn_gcdext_double);
+}
+double
+speed_mpn_gcdext_one_single (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GCDEXT_ONE (mpn_gcdext_one_single);
+}
+double
+speed_mpn_gcdext_one_double (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GCDEXT_ONE (mpn_gcdext_one_double);
+}
+double
+speed_mpn_gcd_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GCD_1 (mpn_gcd_1);
+}
+double
+speed_mpn_gcd_1N (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GCD_1N (mpn_gcd_1);
+}
+
+
+double
+speed_mpz_jacobi (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_JACOBI (mpz_jacobi);
+}
+double
+speed_mpn_jacobi_base (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_JACBASE (mpn_jacobi_base);
+}
+double
+speed_mpn_jacobi_base_1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_JACBASE (mpn_jacobi_base_1);
+}
+double
+speed_mpn_jacobi_base_2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_JACBASE (mpn_jacobi_base_2);
+}
+double
+speed_mpn_jacobi_base_3 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_JACBASE (mpn_jacobi_base_3);
+}
+double
+speed_mpn_jacobi_base_4 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_JACBASE (mpn_jacobi_base_4);
+}
+
+
+double
+speed_mpn_sqrtrem (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SQRTREM (mpn_sqrtrem);
+}
+
+double
+speed_mpn_rootrem (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_ROOTREM (mpn_rootrem);
+}
+
+
+double
+speed_mpz_fac_ui (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_FAC_UI (mpz_fac_ui);
+}
+
+
+double
+speed_mpn_fib2_ui (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_FIB2_UI (mpn_fib2_ui);
+}
+double
+speed_mpz_fib_ui (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_FIB_UI (mpz_fib_ui);
+}
+double
+speed_mpz_fib2_ui (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_FIB2_UI (mpz_fib2_ui);
+}
+double
+speed_mpz_lucnum_ui (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_LUCNUM_UI (mpz_lucnum_ui);
+}
+double
+speed_mpz_lucnum2_ui (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_LUCNUM2_UI (mpz_lucnum2_ui);
+}
+
+
+double
+speed_mpz_powm (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_POWM (mpz_powm);
+}
+double
+speed_mpz_powm_mod (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_POWM (mpz_powm_mod);
+}
+double
+speed_mpz_powm_redc (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_POWM (mpz_powm_redc);
+}
+double
+speed_mpz_powm_sec (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_POWM (mpz_powm_sec);
+}
+double
+speed_mpz_powm_ui (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_POWM_UI (mpz_powm_ui);
+}
+
+
+double
+speed_binvert_limb (struct speed_params *s)
+{
+ SPEED_ROUTINE_MODLIMB_INVERT (binvert_limb);
+}
+
+
+double
+speed_noop (struct speed_params *s)
+{
+ unsigned i;
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ noop ();
+ while (--i != 0);
+ return speed_endtime ();
+}
+
+double
+speed_noop_wxs (struct speed_params *s)
+{
+ mp_ptr wp;
+ unsigned i;
+ double t;
+ TMP_DECL;
+
+ TMP_MARK;
+ wp = TMP_ALLOC_LIMBS (1);
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ noop_wxs (wp, s->xp, s->size);
+ while (--i != 0);
+ t = speed_endtime ();
+
+ TMP_FREE;
+ return t;
+}
+
+double
+speed_noop_wxys (struct speed_params *s)
+{
+ mp_ptr wp;
+ unsigned i;
+ double t;
+ TMP_DECL;
+
+ TMP_MARK;
+ wp = TMP_ALLOC_LIMBS (1);
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ noop_wxys (wp, s->xp, s->yp, s->size);
+ while (--i != 0);
+ t = speed_endtime ();
+
+ TMP_FREE;
+ return t;
+}
+
+
+#define SPEED_ROUTINE_ALLOC_FREE(variables, calls) \
+ { \
+ unsigned i; \
+ variables; \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ calls; \
+ } \
+ while (--i != 0); \
+ return speed_endtime (); \
+ }
+
+
+/* Compare these to see how much malloc/free costs and then how much
+ __gmp_default_allocate/free and mpz_init/clear add. mpz_init/clear or
+ mpq_init/clear will be doing a 1 limb allocate, so use that as the size
+ when including them in comparisons. */
+
+double
+speed_malloc_free (struct speed_params *s)
+{
+ size_t bytes = s->size * GMP_LIMB_BYTES;
+ SPEED_ROUTINE_ALLOC_FREE (void *p,
+ p = malloc (bytes);
+ free (p));
+}
+
+double
+speed_malloc_realloc_free (struct speed_params *s)
+{
+ size_t bytes = s->size * GMP_LIMB_BYTES;
+ SPEED_ROUTINE_ALLOC_FREE (void *p,
+ p = malloc (GMP_LIMB_BYTES);
+ p = realloc (p, bytes);
+ free (p));
+}
+
+double
+speed_gmp_allocate_free (struct speed_params *s)
+{
+ size_t bytes = s->size * GMP_LIMB_BYTES;
+ SPEED_ROUTINE_ALLOC_FREE (void *p,
+ p = (*__gmp_allocate_func) (bytes);
+ (*__gmp_free_func) (p, bytes));
+}
+
+double
+speed_gmp_allocate_reallocate_free (struct speed_params *s)
+{
+ size_t bytes = s->size * GMP_LIMB_BYTES;
+ SPEED_ROUTINE_ALLOC_FREE
+ (void *p,
+ p = (*__gmp_allocate_func) (GMP_LIMB_BYTES);
+ p = (*__gmp_reallocate_func) (p, bytes, GMP_LIMB_BYTES);
+ (*__gmp_free_func) (p, bytes));
+}
+
+double
+speed_mpz_init_clear (struct speed_params *s)
+{
+ SPEED_ROUTINE_ALLOC_FREE (mpz_t z,
+ mpz_init (z);
+ mpz_clear (z));
+}
+
+double
+speed_mpz_init_realloc_clear (struct speed_params *s)
+{
+ SPEED_ROUTINE_ALLOC_FREE (mpz_t z,
+ mpz_init (z);
+ _mpz_realloc (z, s->size);
+ mpz_clear (z));
+}
+
+double
+speed_mpq_init_clear (struct speed_params *s)
+{
+ SPEED_ROUTINE_ALLOC_FREE (mpq_t q,
+ mpq_init (q);
+ mpq_clear (q));
+}
+
+double
+speed_mpf_init_clear (struct speed_params *s)
+{
+ SPEED_ROUTINE_ALLOC_FREE (mpf_t f,
+ mpf_init (f);
+ mpf_clear (f));
+}
+
+
+/* Compare this to mpn_add_n to see how much overhead mpz_add adds. Note
+ that repeatedly calling mpz_add with the same data gives branch prediction
+ in it an advantage. */
+
+double
+speed_mpz_add (struct speed_params *s)
+{
+ mpz_t w, x, y;
+ unsigned i;
+ double t;
+
+ mpz_init (w);
+ mpz_init (x);
+ mpz_init (y);
+
+ mpz_set_n (x, s->xp, s->size);
+ mpz_set_n (y, s->yp, s->size);
+ mpz_add (w, x, y);
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ {
+ mpz_add (w, x, y);
+ }
+ while (--i != 0);
+ t = speed_endtime ();
+
+ mpz_clear (w);
+ mpz_clear (x);
+ mpz_clear (y);
+ return t;
+}
+
+
+/* If r==0, calculate (size,size/2),
+ otherwise calculate (size,r). */
+
+double
+speed_mpz_bin_uiui (struct speed_params *s)
+{
+ mpz_t w;
+ unsigned long k;
+ unsigned i;
+ double t;
+
+ mpz_init (w);
+ if (s->r != 0)
+ k = s->r;
+ else
+ k = s->size/2;
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ {
+ mpz_bin_uiui (w, s->size, k);
+ }
+ while (--i != 0);
+ t = speed_endtime ();
+
+ mpz_clear (w);
+ return t;
+}
+
+/* If r==0, calculate binomial(2^size,size),
+ otherwise calculate binomial(2^size,r). */
+
+double
+speed_mpz_bin_ui (struct speed_params *s)
+{
+ mpz_t w, x;
+ unsigned long k;
+ unsigned i;
+ double t;
+
+ mpz_init (w);
+ mpz_init_set_ui (x, 0);
+
+ mpz_setbit (x, s->size);
+
+ if (s->r != 0)
+ k = s->r;
+ else
+ k = s->size;
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ {
+ mpz_bin_ui (w, x, k);
+ }
+ while (--i != 0);
+ t = speed_endtime ();
+
+ mpz_clear (w);
+ mpz_clear (x);
+ return t;
+}
+
+/* The multiplies are successively dependent so the latency is measured, not
+ the issue rate. There's only 10 per loop so the code doesn't get too big
+ since umul_ppmm is several instructions on some cpus.
+
+ Putting the arguments as "h,l,l,h" gets slightly better code from gcc
+ 2.95.2 on x86, it puts only one mov between each mul, not two. That mov
+ though will probably show up as a bogus extra cycle though.
+
+ The measuring function macros are into three parts to avoid overflowing
+ preprocessor expansion space if umul_ppmm is big.
+
+ Limitations:
+
+ Don't blindly use this to set UMUL_TIME in gmp-mparam.h, check the code
+ generated first, especially on CPUs with low latency multipliers.
+
+ The default umul_ppmm doing h*l will be getting increasing numbers of
+ high zero bits in the calculation. CPUs with data-dependent multipliers
+ will want to use umul_ppmm.1 to get some randomization into the
+ calculation. The extra xors and fetches will be a slowdown of course. */
+
+#define SPEED_MACRO_UMUL_PPMM_A \
+ { \
+ mp_limb_t h, l; \
+ unsigned i; \
+ double t; \
+ \
+ s->time_divisor = 10; \
+ \
+ h = s->xp[0]; \
+ l = s->yp[0]; \
+ \
+ if (s->r == 1) \
+ { \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ {
+
+#define SPEED_MACRO_UMUL_PPMM_B \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ } \
+ else \
+ { \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ {
+
+#define SPEED_MACRO_UMUL_PPMM_C \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ } \
+ \
+ /* stop the compiler optimizing away the whole calculation! */ \
+ noop_1 (h); \
+ noop_1 (l); \
+ \
+ return t; \
+ }
+
+
+double
+speed_umul_ppmm (struct speed_params *s)
+{
+ SPEED_MACRO_UMUL_PPMM_A;
+ {
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[0]; l ^= s->yp_block[0];
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[1]; l ^= s->yp_block[1];
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[2]; l ^= s->yp_block[2];
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[3]; l ^= s->yp_block[3];
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[4]; l ^= s->yp_block[4];
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[5]; l ^= s->yp_block[5];
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[6]; l ^= s->yp_block[6];
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[7]; l ^= s->yp_block[7];
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[8]; l ^= s->yp_block[8];
+ umul_ppmm (h, l, l, h); h ^= s->xp_block[9]; l ^= s->yp_block[9];
+ }
+ SPEED_MACRO_UMUL_PPMM_B;
+ {
+ umul_ppmm (h, l, l, h);
+ umul_ppmm (h, l, l, h);
+ umul_ppmm (h, l, l, h);
+ umul_ppmm (h, l, l, h);
+ umul_ppmm (h, l, l, h);
+ umul_ppmm (h, l, l, h);
+ umul_ppmm (h, l, l, h);
+ umul_ppmm (h, l, l, h);
+ umul_ppmm (h, l, l, h);
+ umul_ppmm (h, l, l, h);
+ }
+ SPEED_MACRO_UMUL_PPMM_C;
+}
+
+
+#if HAVE_NATIVE_mpn_umul_ppmm
+double
+speed_mpn_umul_ppmm (struct speed_params *s)
+{
+ SPEED_MACRO_UMUL_PPMM_A;
+ {
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[0]; l ^= s->yp_block[0];
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[1]; l ^= s->yp_block[1];
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[2]; l ^= s->yp_block[2];
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[3]; l ^= s->yp_block[3];
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[4]; l ^= s->yp_block[4];
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[5]; l ^= s->yp_block[5];
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[6]; l ^= s->yp_block[6];
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[7]; l ^= s->yp_block[7];
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[8]; l ^= s->yp_block[8];
+ h = mpn_umul_ppmm (&l, h, l); h ^= s->xp_block[9]; l ^= s->yp_block[9];
+ }
+ SPEED_MACRO_UMUL_PPMM_B;
+ {
+ h = mpn_umul_ppmm (&l, h, l);
+ h = mpn_umul_ppmm (&l, h, l);
+ h = mpn_umul_ppmm (&l, h, l);
+ h = mpn_umul_ppmm (&l, h, l);
+ h = mpn_umul_ppmm (&l, h, l);
+ h = mpn_umul_ppmm (&l, h, l);
+ h = mpn_umul_ppmm (&l, h, l);
+ h = mpn_umul_ppmm (&l, h, l);
+ h = mpn_umul_ppmm (&l, h, l);
+ h = mpn_umul_ppmm (&l, h, l);
+ }
+ SPEED_MACRO_UMUL_PPMM_C;
+}
+#endif
+
+#if HAVE_NATIVE_mpn_umul_ppmm_r
+double
+speed_mpn_umul_ppmm_r (struct speed_params *s)
+{
+ SPEED_MACRO_UMUL_PPMM_A;
+ {
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[0]; l ^= s->yp_block[0];
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[1]; l ^= s->yp_block[1];
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[2]; l ^= s->yp_block[2];
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[3]; l ^= s->yp_block[3];
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[4]; l ^= s->yp_block[4];
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[5]; l ^= s->yp_block[5];
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[6]; l ^= s->yp_block[6];
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[7]; l ^= s->yp_block[7];
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[8]; l ^= s->yp_block[8];
+ h = mpn_umul_ppmm_r (h, l, &l); h ^= s->xp_block[9]; l ^= s->yp_block[9];
+ }
+ SPEED_MACRO_UMUL_PPMM_B;
+ {
+ h = mpn_umul_ppmm_r (h, l, &l);
+ h = mpn_umul_ppmm_r (h, l, &l);
+ h = mpn_umul_ppmm_r (h, l, &l);
+ h = mpn_umul_ppmm_r (h, l, &l);
+ h = mpn_umul_ppmm_r (h, l, &l);
+ h = mpn_umul_ppmm_r (h, l, &l);
+ h = mpn_umul_ppmm_r (h, l, &l);
+ h = mpn_umul_ppmm_r (h, l, &l);
+ h = mpn_umul_ppmm_r (h, l, &l);
+ h = mpn_umul_ppmm_r (h, l, &l);
+ }
+ SPEED_MACRO_UMUL_PPMM_C;
+}
+#endif
+
+
+/* The divisions are successively dependent so latency is measured, not
+ issue rate. There's only 10 per loop so the code doesn't get too big,
+ especially for udiv_qrnnd_preinv and preinv2norm, which are several
+ instructions each.
+
+ Note that it's only the division which is measured here, there's no data
+ fetching and no shifting if the divisor gets normalized.
+
+ In speed_udiv_qrnnd with gcc 2.95.2 on x86 the parameters "q,r,r,q,d"
+ generate x86 div instructions with nothing in between.
+
+ The measuring function macros are in two parts to avoid overflowing
+ preprocessor expansion space if udiv_qrnnd etc are big.
+
+ Limitations:
+
+ Don't blindly use this to set UDIV_TIME in gmp-mparam.h, check the code
+ generated first.
+
+ CPUs with data-dependent divisions may want more attention paid to the
+ randomness of the data used. Probably the measurement wanted is over
+ uniformly distributed numbers, but what's here might not be giving that. */
+
+#define SPEED_ROUTINE_UDIV_QRNND_A(normalize) \
+ { \
+ double t; \
+ unsigned i; \
+ mp_limb_t q, r, d; \
+ mp_limb_t dinv; \
+ \
+ s->time_divisor = 10; \
+ \
+ /* divisor from "r" parameter, or a default */ \
+ d = s->r; \
+ if (d == 0) \
+ d = mp_bases[10].big_base; \
+ \
+ if (normalize) \
+ { \
+ unsigned norm; \
+ count_leading_zeros (norm, d); \
+ d <<= norm; \
+ invert_limb (dinv, d); \
+ } \
+ \
+ q = s->xp[0]; \
+ r = s->yp[0] % d; \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ {
+
+#define SPEED_ROUTINE_UDIV_QRNND_B \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ /* stop the compiler optimizing away the whole calculation! */ \
+ noop_1 (q); \
+ noop_1 (r); \
+ \
+ return t; \
+ }
+
+double
+speed_udiv_qrnnd (struct speed_params *s)
+{
+ SPEED_ROUTINE_UDIV_QRNND_A (UDIV_NEEDS_NORMALIZATION);
+ {
+ udiv_qrnnd (q, r, r, q, d);
+ udiv_qrnnd (q, r, r, q, d);
+ udiv_qrnnd (q, r, r, q, d);
+ udiv_qrnnd (q, r, r, q, d);
+ udiv_qrnnd (q, r, r, q, d);
+ udiv_qrnnd (q, r, r, q, d);
+ udiv_qrnnd (q, r, r, q, d);
+ udiv_qrnnd (q, r, r, q, d);
+ udiv_qrnnd (q, r, r, q, d);
+ udiv_qrnnd (q, r, r, q, d);
+ }
+ SPEED_ROUTINE_UDIV_QRNND_B;
+}
+
+double
+speed_udiv_qrnnd_c (struct speed_params *s)
+{
+ SPEED_ROUTINE_UDIV_QRNND_A (1);
+ {
+ __udiv_qrnnd_c (q, r, r, q, d);
+ __udiv_qrnnd_c (q, r, r, q, d);
+ __udiv_qrnnd_c (q, r, r, q, d);
+ __udiv_qrnnd_c (q, r, r, q, d);
+ __udiv_qrnnd_c (q, r, r, q, d);
+ __udiv_qrnnd_c (q, r, r, q, d);
+ __udiv_qrnnd_c (q, r, r, q, d);
+ __udiv_qrnnd_c (q, r, r, q, d);
+ __udiv_qrnnd_c (q, r, r, q, d);
+ __udiv_qrnnd_c (q, r, r, q, d);
+ }
+ SPEED_ROUTINE_UDIV_QRNND_B;
+}
+
+#if HAVE_NATIVE_mpn_udiv_qrnnd
+double
+speed_mpn_udiv_qrnnd (struct speed_params *s)
+{
+ SPEED_ROUTINE_UDIV_QRNND_A (1);
+ {
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ q = mpn_udiv_qrnnd (&r, r, q, d);
+ }
+ SPEED_ROUTINE_UDIV_QRNND_B;
+}
+#endif
+
+#if HAVE_NATIVE_mpn_udiv_qrnnd_r
+double
+speed_mpn_udiv_qrnnd_r (struct speed_params *s)
+{
+ SPEED_ROUTINE_UDIV_QRNND_A (1);
+ {
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ q = mpn_udiv_qrnnd_r (r, q, d, &r);
+ }
+ SPEED_ROUTINE_UDIV_QRNND_B;
+}
+#endif
+
+
+double
+speed_invert_limb (struct speed_params *s)
+{
+ SPEED_ROUTINE_INVERT_LIMB_CALL (invert_limb (dinv, d));
+}
+
+
+/* xp[0] might not be particularly random, but should give an indication how
+ "/" runs. Same for speed_operator_mod below. */
+double
+speed_operator_div (struct speed_params *s)
+{
+ double t;
+ unsigned i;
+ mp_limb_t x, q, d;
+
+ s->time_divisor = 10;
+
+ /* divisor from "r" parameter, or a default */
+ d = s->r;
+ if (d == 0)
+ d = mp_bases[10].big_base;
+
+ x = s->xp[0];
+ q = 0;
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ {
+ q ^= x; q /= d;
+ q ^= x; q /= d;
+ q ^= x; q /= d;
+ q ^= x; q /= d;
+ q ^= x; q /= d;
+ q ^= x; q /= d;
+ q ^= x; q /= d;
+ q ^= x; q /= d;
+ q ^= x; q /= d;
+ q ^= x; q /= d;
+ }
+ while (--i != 0);
+ t = speed_endtime ();
+
+ /* stop the compiler optimizing away the whole calculation! */
+ noop_1 (q);
+
+ return t;
+}
+
+double
+speed_operator_mod (struct speed_params *s)
+{
+ double t;
+ unsigned i;
+ mp_limb_t x, r, d;
+
+ s->time_divisor = 10;
+
+ /* divisor from "r" parameter, or a default */
+ d = s->r;
+ if (d == 0)
+ d = mp_bases[10].big_base;
+
+ x = s->xp[0];
+ r = 0;
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ {
+ r ^= x; r %= d;
+ r ^= x; r %= d;
+ r ^= x; r %= d;
+ r ^= x; r %= d;
+ r ^= x; r %= d;
+ r ^= x; r %= d;
+ r ^= x; r %= d;
+ r ^= x; r %= d;
+ r ^= x; r %= d;
+ r ^= x; r %= d;
+ }
+ while (--i != 0);
+ t = speed_endtime ();
+
+ /* stop the compiler optimizing away the whole calculation! */
+ noop_1 (r);
+
+ return t;
+}
+
+
+/* r==0 measures on data with the values uniformly distributed. This will
+ be typical for count_trailing_zeros in a GCD etc.
+
+ r==1 measures on data with the resultant count uniformly distributed
+ between 0 and GMP_LIMB_BITS-1. This is probably sensible for
+ count_leading_zeros on the high limbs of divisors. */
+
+int
+speed_routine_count_zeros_setup (struct speed_params *s,
+ mp_ptr xp, int leading, int zero)
+{
+ int i, c;
+ mp_limb_t n;
+
+ if (s->r == 0)
+ {
+ /* Make uniformly distributed data. If zero isn't allowed then change
+ it to 1 for leading, or 0x800..00 for trailing. */
+ MPN_COPY (xp, s->xp_block, SPEED_BLOCK_SIZE);
+ if (! zero)
+ for (i = 0; i < SPEED_BLOCK_SIZE; i++)
+ if (xp[i] == 0)
+ xp[i] = leading ? 1 : GMP_LIMB_HIGHBIT;
+ }
+ else if (s->r == 1)
+ {
+ /* Make counts uniformly distributed. A randomly chosen bit is set, and
+ for leading the rest above it are cleared, or for trailing then the
+ rest below. */
+ for (i = 0; i < SPEED_BLOCK_SIZE; i++)
+ {
+ mp_limb_t set = CNST_LIMB(1) << (s->yp_block[i] % GMP_LIMB_BITS);
+ mp_limb_t keep_below = set-1;
+ mp_limb_t keep_above = MP_LIMB_T_MAX ^ keep_below;
+ mp_limb_t keep = (leading ? keep_below : keep_above);
+ xp[i] = (s->xp_block[i] & keep) | set;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+
+ /* Account for the effect of n^=c. */
+ c = 0;
+ for (i = 0; i < SPEED_BLOCK_SIZE; i++)
+ {
+ n = xp[i];
+ xp[i] ^= c;
+
+ if (leading)
+ count_leading_zeros (c, n);
+ else
+ count_trailing_zeros (c, n);
+ }
+
+ return 1;
+}
+
+double
+speed_count_leading_zeros (struct speed_params *s)
+{
+#ifdef COUNT_LEADING_ZEROS_0
+#define COUNT_LEADING_ZEROS_0_ALLOWED 1
+#else
+#define COUNT_LEADING_ZEROS_0_ALLOWED 0
+#endif
+
+ SPEED_ROUTINE_COUNT_ZEROS_A (1, COUNT_LEADING_ZEROS_0_ALLOWED);
+ count_leading_zeros (c, n);
+ SPEED_ROUTINE_COUNT_ZEROS_B ();
+}
+double
+speed_count_trailing_zeros (struct speed_params *s)
+{
+ SPEED_ROUTINE_COUNT_ZEROS_A (0, 0);
+ count_trailing_zeros (c, n);
+ SPEED_ROUTINE_COUNT_ZEROS_B ();
+}
+
+
+double
+speed_mpn_get_str (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_GET_STR (mpn_get_str);
+}
+
+double
+speed_mpn_set_str (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SET_STR_CALL (mpn_set_str (wp, xp, s->size, base));
+}
+double
+speed_mpn_bc_set_str (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SET_STR_CALL (mpn_bc_set_str (wp, xp, s->size, base));
+}
+
+double
+speed_MPN_ZERO (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_ZERO_CALL (MPN_ZERO (wp, s->size));
+}
+
+
+int
+speed_randinit (struct speed_params *s, gmp_randstate_ptr rstate)
+{
+ if (s->r == 0)
+ gmp_randinit_default (rstate);
+ else if (s->r == 1)
+ gmp_randinit_mt (rstate);
+ else
+ {
+ return gmp_randinit_lc_2exp_size (rstate, s->r);
+ }
+ return 1;
+}
+
+double
+speed_gmp_randseed (struct speed_params *s)
+{
+ gmp_randstate_t rstate;
+ unsigned i;
+ double t;
+ mpz_t x;
+
+ SPEED_RESTRICT_COND (s->size >= 1);
+ SPEED_RESTRICT_COND (speed_randinit (s, rstate));
+
+ /* s->size bits of seed */
+ mpz_init_set_n (x, s->xp, s->size);
+ mpz_fdiv_r_2exp (x, x, (unsigned long) s->size);
+
+ /* cache priming */
+ gmp_randseed (rstate, x);
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ gmp_randseed (rstate, x);
+ while (--i != 0);
+ t = speed_endtime ();
+
+ gmp_randclear (rstate);
+ mpz_clear (x);
+ return t;
+}
+
+double
+speed_gmp_randseed_ui (struct speed_params *s)
+{
+ gmp_randstate_t rstate;
+ unsigned i, j;
+ double t;
+
+ SPEED_RESTRICT_COND (speed_randinit (s, rstate));
+
+ /* cache priming */
+ gmp_randseed_ui (rstate, 123L);
+
+ speed_starttime ();
+ i = s->reps;
+ j = 0;
+ do
+ {
+ gmp_randseed_ui (rstate, (unsigned long) s->xp_block[j]);
+ j++;
+ if (j >= SPEED_BLOCK_SIZE)
+ j = 0;
+ }
+ while (--i != 0);
+ t = speed_endtime ();
+
+ gmp_randclear (rstate);
+ return t;
+}
+
+double
+speed_mpz_urandomb (struct speed_params *s)
+{
+ gmp_randstate_t rstate;
+ mpz_t z;
+ unsigned i;
+ double t;
+
+ SPEED_RESTRICT_COND (s->size >= 0);
+ SPEED_RESTRICT_COND (speed_randinit (s, rstate));
+
+ mpz_init (z);
+
+ /* cache priming */
+ mpz_urandomb (z, rstate, (unsigned long) s->size);
+ mpz_urandomb (z, rstate, (unsigned long) s->size);
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ mpz_urandomb (z, rstate, (unsigned long) s->size);
+ while (--i != 0);
+ t = speed_endtime ();
+
+ mpz_clear (z);
+ gmp_randclear (rstate);
+ return t;
+}
diff --git a/gmp/tune/div_qr_1_tune.c b/gmp/tune/div_qr_1_tune.c
new file mode 100644
index 0000000000..7e928dcce9
--- /dev/null
+++ b/gmp/tune/div_qr_1_tune.c
@@ -0,0 +1,47 @@
+/* mpn/generic/div_qr_1, using tuned threshold and method.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define TUNE_PROGRAM_BUILD 1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t mpn_div_qr_1n_pi1_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, mp_limb_t);
+mp_limb_t mpn_div_qr_1n_pi1_2 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, mp_limb_t);
+
+#if !HAVE_NATIVE_mpn_div_qr_1n_pi1
+#define __gmpn_div_qr_1n_pi1 \
+ (div_qr_1n_pi1_method == 1 ? mpn_div_qr_1n_pi1_1 : mpn_div_qr_1n_pi1_2)
+#endif
+
+#undef mpn_div_qr_1
+#define mpn_div_qr_1 mpn_div_qr_1_tune
+
+#include "mpn/generic/div_qr_1.c"
diff --git a/gmp/tune/div_qr_1n_pi1_1.c b/gmp/tune/div_qr_1n_pi1_1.c
new file mode 100644
index 0000000000..6dd8ceb438
--- /dev/null
+++ b/gmp/tune/div_qr_1n_pi1_1.c
@@ -0,0 +1,39 @@
+/* mpn/generic/div_qr_1n_pi1.c method 1.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef DIV_QR_1N_METHOD
+#define DIV_QR_1N_METHOD 1
+#undef mpn_div_qr_1n_pi1
+#define mpn_div_qr_1n_pi1 mpn_div_qr_1n_pi1_1
+
+#include "mpn/generic/div_qr_1n_pi1.c"
diff --git a/gmp/tune/div_qr_1n_pi1_2.c b/gmp/tune/div_qr_1n_pi1_2.c
new file mode 100644
index 0000000000..acc80d4695
--- /dev/null
+++ b/gmp/tune/div_qr_1n_pi1_2.c
@@ -0,0 +1,39 @@
+/* mpn/generic/div_qr_1n_pi1.c method 2.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef DIV_QR_1N_METHOD
+#define DIV_QR_1N_METHOD 2
+#undef mpn_div_qr_1n_pi1
+#define mpn_div_qr_1n_pi1 mpn_div_qr_1n_pi1_2
+
+#include "mpn/generic/div_qr_1n_pi1.c"
diff --git a/gmp/tune/divrem1div.c b/gmp/tune/divrem1div.c
new file mode 100644
index 0000000000..b680f9d222
--- /dev/null
+++ b/gmp/tune/divrem1div.c
@@ -0,0 +1,42 @@
+/* mpn/generic/divrem_1.c forced to use plain udiv_qrnnd.
+
+Copyright 2000, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define OPERATION_divrem_1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef DIVREM_1_NORM_THRESHOLD
+#undef DIVREM_1_UNNORM_THRESHOLD
+#define DIVREM_1_NORM_THRESHOLD MP_SIZE_T_MAX
+#define DIVREM_1_UNNORM_THRESHOLD MP_SIZE_T_MAX
+#define __gmpn_divrem_1 mpn_divrem_1_div
+
+#include "mpn/generic/divrem_1.c"
diff --git a/gmp/tune/divrem1inv.c b/gmp/tune/divrem1inv.c
new file mode 100644
index 0000000000..598c03c739
--- /dev/null
+++ b/gmp/tune/divrem1inv.c
@@ -0,0 +1,42 @@
+/* mpn/generic/divrem_1.c forced to use mul-by-inverse udiv_qrnnd_preinv.
+
+Copyright 2000, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define OPERATION_divrem_1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef DIVREM_1_NORM_THRESHOLD
+#undef DIVREM_1_UNNORM_THRESHOLD
+#define DIVREM_1_NORM_THRESHOLD 0
+#define DIVREM_1_UNNORM_THRESHOLD 0
+#define __gmpn_divrem_1 mpn_divrem_1_inv
+
+#include "mpn/generic/divrem_1.c"
diff --git a/gmp/tune/divrem2div.c b/gmp/tune/divrem2div.c
new file mode 100644
index 0000000000..cd7f3f5a88
--- /dev/null
+++ b/gmp/tune/divrem2div.c
@@ -0,0 +1,41 @@
+/* mpn/generic/divrem_2.c forced to use plain udiv_qrnnd. */
+
+/*
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifdef DIVREM_2_THRESHOLD
+#undef DIVREM_2_THRESHOLD
+#endif
+#define DIVREM_2_THRESHOLD MP_SIZE_T_MAX
+#define __gmpn_divrem_2 mpn_divrem_2_div
+
+#include "mpn/generic/divrem_2.c"
diff --git a/gmp/tune/divrem2inv.c b/gmp/tune/divrem2inv.c
new file mode 100644
index 0000000000..bd7c4268f7
--- /dev/null
+++ b/gmp/tune/divrem2inv.c
@@ -0,0 +1,41 @@
+/* mpn/generic/divrem_2.c forced to use udiv_qrnnd_preinv. */
+
+/*
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifdef DIVREM_2_THRESHOLD
+#undef DIVREM_2_THRESHOLD
+#endif
+#define DIVREM_2_THRESHOLD 0
+#define __gmpn_divrem_2 mpn_divrem_2_inv
+
+#include "mpn/generic/divrem_2.c"
diff --git a/gmp/tune/freq.c b/gmp/tune/freq.c
new file mode 100644
index 0000000000..210f42564e
--- /dev/null
+++ b/gmp/tune/freq.c
@@ -0,0 +1,894 @@
+/* CPU frequency determination.
+
+Copyright 1999-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* Currently we don't get a CPU frequency on the following systems,
+
+ alphaev5-cray-unicosmk2.0.6.X
+ times() has been seen at 13.33 ns (75 MHz), which is probably not the
+ cpu frequency. Measuring the cycle counter against that would be
+ possible though. But currently we don't use the cycle counter due to
+ unicos having int==8bytes where tune/alpha.asm assumes int==4bytes.
+
+ m68040-unknown-netbsd1.4.1
+ Not sure if the system even knows the cpu frequency. There's no
+ cycle counter to measure, though we could perhaps make a loop taking
+ a known number of cycles and measure that.
+
+ power-ibm-aix4.2.1.0
+ power2-ibm-aix4.3.1.0
+ powerpc604-ibm-aix4.3.1.0
+ powerpc604-ibm-aix4.3.3.0
+ powerpc630-ibm-aix4.3.3.0
+ powerpc-unknown-netbsd1.6
+ Don't know where any info hides on these. mftb is not related to the
+ cpu frequency so doesn't help.
+
+ sparc-unknown-linux-gnu [maybe]
+ Don't know where any info hides on this.
+
+ t90-cray-unicos10.0.X
+ The times() call seems to be for instance 2.22 nanoseconds, which
+ might be the cpu frequency (450 mhz), but need to confirm that.
+
+*/
+
+#include "config.h"
+
+#if HAVE_INVENT_H
+#include <invent.h> /* for IRIX invent_cpuinfo_t */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h> /* for getenv, qsort */
+#include <string.h> /* for memcmp */
+
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for sysconf */
+#endif
+
+#include <sys/types.h>
+
+#if HAVE_SYS_ATTRIBUTES_H
+#include <sys/attributes.h> /* for IRIX attr_get(), needs sys/types.h */
+#endif
+
+#if HAVE_SYS_IOGRAPH_H
+#include <sys/iograph.h> /* for IRIX INFO_LBL_DETAIL_INVENT */
+#endif
+
+#if HAVE_SYS_PARAM_H /* for constants needed by NetBSD <sys/sysctl.h> */
+#include <sys/param.h> /* and needed by HPUX <sys/pstat.h> */
+#endif
+
+#if HAVE_SYS_PSTAT_H
+#include <sys/pstat.h> /* for HPUX pstat_getprocessor() */
+#endif
+
+#if HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h> /* for sysctlbyname() */
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h> /* for struct timeval */
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h> /* for struct rusage */
+#endif
+
+#if HAVE_SYS_PROCESSOR_H
+#include <sys/processor.h> /* for solaris processor_info_t */
+#endif
+
+/* On AIX 5.1 with gcc 2.9-aix51-020209 in -maix64 mode, <sys/sysinfo.h>
+ gets an error about "fill" in "struct cpuinfo" having a negative size,
+ apparently due to __64BIT_KERNEL not being defined because _KERNEL is not
+ defined. Avoid this file if we don't actually need it, which we don't on
+ AIX since there's no getsysinfo there. */
+#if HAVE_SYS_SYSINFO_H && HAVE_GETSYSINFO
+#include <sys/sysinfo.h> /* for OSF getsysinfo */
+#endif
+
+#if HAVE_MACHINE_HAL_SYSINFO_H
+#include <machine/hal_sysinfo.h> /* for OSF GSI_CPU_INFO, struct cpu_info */
+#endif
+
+/* Remove definitions from NetBSD <sys/param.h>, to avoid conflicts with
+ gmp-impl.h. */
+#ifdef MIN
+#undef MIN
+#endif
+#ifdef MAX
+#undef MAX
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#include "speed.h"
+
+
+#define HELP(str) \
+ if (help) \
+ { \
+ printf (" - %s\n", str); \
+ return 0; \
+ }
+
+
+/* GMP_CPU_FREQUENCY environment variable. Should be in Hertz and can be
+ floating point, for example "450e6". */
+static int
+freq_environment (int help)
+{
+ char *e;
+
+ HELP ("environment variable GMP_CPU_FREQUENCY (in Hertz)");
+
+ e = getenv ("GMP_CPU_FREQUENCY");
+ if (e == NULL)
+ return 0;
+
+ speed_cycletime = 1.0 / atof (e);
+
+ if (speed_option_verbose)
+ printf ("Using GMP_CPU_FREQUENCY %.2f for cycle time %.3g\n",
+ atof (e), speed_cycletime);
+
+ return 1;
+}
+
+
+/* getsysinfo is available on OSF, or 4.0 and up at least.
+ The man page (on 4.0) suggests a 0 return indicates information not
+ available, but that seems to be the normal return for GSI_CPU_INFO. */
+static int
+freq_getsysinfo (int help)
+{
+#if HAVE_GETSYSINFO
+ struct cpu_info c;
+ int start;
+
+ HELP ("getsysinfo() GSI_CPU_INFO");
+
+ start = 0;
+ if (getsysinfo (GSI_CPU_INFO, (caddr_t) &c, sizeof (c),
+ &start, NULL, NULL) != -1)
+ {
+ speed_cycletime = 1e-6 / (double) c.mhz;
+ if (speed_option_verbose)
+ printf ("Using getsysinfo() GSI_CPU_INFO %u for cycle time %.3g\n",
+ c.mhz, speed_cycletime);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+
+/* In HPUX 10 and up, pstat_getprocessor() psp_iticksperclktick is the
+ number of CPU cycles (ie. the CR16 register) per CLK_TCK. HPUX 9 doesn't
+ have that field in pst_processor though, and has no apparent
+ equivalent. */
+
+static int
+freq_pstat_getprocessor (int help)
+{
+#if HAVE_PSTAT_GETPROCESSOR && HAVE_PSP_ITICKSPERCLKTICK
+ struct pst_processor p;
+
+ HELP ("pstat_getprocessor() psp_iticksperclktick");
+
+ if (pstat_getprocessor (&p, sizeof(p), 1, 0) != -1)
+ {
+ long c = clk_tck();
+ speed_cycletime = 1.0 / (c * p.psp_iticksperclktick);
+ if (speed_option_verbose)
+ printf ("Using pstat_getprocessor() psp_iticksperclktick %lu and clk_tck %ld for cycle time %.3g\n",
+ (unsigned long) p.psp_iticksperclktick, c,
+ speed_cycletime);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+
+/* i386 FreeBSD 2.2.8 sysctlbyname machdep.i586_freq is in Hertz.
+ There's no obvious defines available to get this from plain sysctl. */
+static int
+freq_sysctlbyname_i586_freq (int help)
+{
+#if HAVE_SYSCTLBYNAME
+ unsigned val;
+ size_t size;
+
+ HELP ("sysctlbyname() machdep.i586_freq");
+
+ size = sizeof(val);
+ if (sysctlbyname ("machdep.i586_freq", &val, &size, NULL, 0) == 0
+ && size == sizeof(val))
+ {
+ speed_cycletime = 1.0 / (double) val;
+ if (speed_option_verbose)
+ printf ("Using sysctlbyname() machdep.i586_freq %u for cycle time %.3g\n",
+ val, speed_cycletime);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+
+/* i368 FreeBSD 3.3 sysctlbyname machdep.tsc_freq is in Hertz.
+ There's no obvious defines to get this from plain sysctl. */
+
+static int
+freq_sysctlbyname_tsc_freq (int help)
+{
+#if HAVE_SYSCTLBYNAME
+ unsigned val;
+ size_t size;
+
+ HELP ("sysctlbyname() machdep.tsc_freq");
+
+ size = sizeof(val);
+ if (sysctlbyname ("machdep.tsc_freq", &val, &size, NULL, 0) == 0
+ && size == sizeof(val))
+ {
+ speed_cycletime = 1.0 / (double) val;
+ if (speed_option_verbose)
+ printf ("Using sysctlbyname() machdep.tsc_freq %u for cycle time %.3g\n",
+ val, speed_cycletime);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+
+/* Apple powerpc Darwin 1.3 sysctl hw.cpufrequency is in hertz. For some
+ reason only seems to be available from sysctl(), not sysctlbyname(). */
+
+static int
+freq_sysctl_hw_cpufrequency (int help)
+{
+#if HAVE_SYSCTL && defined (CTL_HW) && defined (HW_CPU_FREQ)
+ int mib[2];
+ unsigned val;
+ size_t size;
+
+ HELP ("sysctl() hw.cpufrequency");
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_CPU_FREQ;
+ size = sizeof(val);
+ if (sysctl (mib, 2, &val, &size, NULL, 0) == 0)
+ {
+ speed_cycletime = 1.0 / (double) val;
+ if (speed_option_verbose)
+ printf ("Using sysctl() hw.cpufrequency %u for cycle time %.3g\n",
+ val, speed_cycletime);
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+
+/* The following ssyctl hw.model strings have been observed,
+
+ Alpha FreeBSD 4.1: Digital AlphaPC 164LX 599 MHz
+ NetBSD 1.4: Digital AlphaPC 164LX 599 MHz
+ NetBSD 1.6.1: CY7C601 @ 40 MHz, TMS390C602A FPU
+
+ NetBSD 1.4 doesn't seem to have sysctlbyname, so sysctl() is used. */
+
+static int
+freq_sysctl_hw_model (int help)
+{
+#if HAVE_SYSCTL && defined (CTL_HW) && defined (HW_MODEL)
+ int mib[2];
+ char str[128];
+ unsigned val;
+ size_t size;
+ char *p;
+ int end;
+
+ HELP ("sysctl() hw.model");
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_MODEL;
+ size = sizeof(str);
+ if (sysctl (mib, 2, str, &size, NULL, 0) == 0)
+ {
+ for (p = str; *p != '\0'; p++)
+ {
+ end = 0;
+ if (sscanf (p, "%u MHz%n", &val, &end) == 1 && end != 0)
+ {
+ speed_cycletime = 1e-6 / (double) val;
+ if (speed_option_verbose)
+ printf ("Using sysctl() hw.model %u for cycle time %.3g\n",
+ val, speed_cycletime);
+ return 1;
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
+
+/* /proc/cpuinfo for linux kernel.
+
+ Linux doesn't seem to have any system call to get the CPU frequency, at
+ least not in 2.0.x or 2.2.x, so it's necessary to read /proc/cpuinfo.
+
+ i386 2.0.36 - "bogomips" is the CPU frequency.
+
+ i386 2.2.13 - has both "cpu MHz" and "bogomips", and it's "cpu MHz" which
+ is the frequency.
+
+ alpha 2.2.5 - "cycle frequency [Hz]" seems to be right, "BogoMIPS" is
+ very slightly different.
+
+ alpha 2.2.18pre21 - "cycle frequency [Hz]" is 0 on at least one system,
+ "BogoMIPS" seems near enough.
+
+ powerpc 2.2.19 - "clock" is the frequency, bogomips is something weird
+ */
+
+static int
+freq_proc_cpuinfo (int help)
+{
+ FILE *fp;
+ char buf[128];
+ double val;
+ int ret = 0;
+ int end;
+
+ HELP ("linux kernel /proc/cpuinfo file, cpu MHz or bogomips");
+
+ if ((fp = fopen ("/proc/cpuinfo", "r")) != NULL)
+ {
+ while (fgets (buf, sizeof (buf), fp) != NULL)
+ {
+ if (sscanf (buf, "cycle frequency [Hz] : %lf", &val) == 1
+ && val != 0.0)
+ {
+ speed_cycletime = 1.0 / val;
+ if (speed_option_verbose)
+ printf ("Using /proc/cpuinfo \"cycle frequency\" %.2f for cycle time %.3g\n", val, speed_cycletime);
+ ret = 1;
+ break;
+ }
+ if (sscanf (buf, "cpu MHz : %lf\n", &val) == 1)
+ {
+ speed_cycletime = 1e-6 / val;
+ if (speed_option_verbose)
+ printf ("Using /proc/cpuinfo \"cpu MHz\" %.2f for cycle time %.3g\n", val, speed_cycletime);
+ ret = 1;
+ break;
+ }
+ end = 0;
+ if (sscanf (buf, "clock : %lfMHz\n%n", &val, &end) == 1 && end != 0)
+ {
+ speed_cycletime = 1e-6 / val;
+ if (speed_option_verbose)
+ printf ("Using /proc/cpuinfo \"clock\" %.2f for cycle time %.3g\n", val, speed_cycletime);
+ ret = 1;
+ break;
+ }
+ if (sscanf (buf, "bogomips : %lf\n", &val) == 1
+ || sscanf (buf, "BogoMIPS : %lf\n", &val) == 1)
+ {
+ speed_cycletime = 1e-6 / val;
+ if (speed_option_verbose)
+ printf ("Using /proc/cpuinfo \"bogomips\" %.2f for cycle time %.3g\n", val, speed_cycletime);
+ ret = 1;
+ break;
+ }
+ }
+ fclose (fp);
+ }
+ return ret;
+}
+
+
+/* /bin/sysinfo for SunOS 4.
+ Prints a line like: cpu0 is a "75 MHz TI,TMS390Z55" CPU */
+static int
+freq_sunos_sysinfo (int help)
+{
+ int ret = 0;
+#if HAVE_POPEN
+ FILE *fp;
+ char buf[128];
+ double val;
+ int end;
+
+ HELP ("SunOS /bin/sysinfo program output, cpu0");
+
+ /* Error messages are sent to /dev/null in case /bin/sysinfo doesn't
+ exist. The brackets are necessary for some shells. */
+ if ((fp = popen ("(/bin/sysinfo) 2>/dev/null", "r")) != NULL)
+ {
+ while (fgets (buf, sizeof (buf), fp) != NULL)
+ {
+ end = 0;
+ if (sscanf (buf, " cpu0 is a \"%lf MHz%n", &val, &end) == 1
+ && end != 0)
+ {
+ speed_cycletime = 1e-6 / val;
+ if (speed_option_verbose)
+ printf ("Using /bin/sysinfo \"cpu0 MHz\" %.2f for cycle time %.3g\n", val, speed_cycletime);
+ ret = 1;
+ break;
+ }
+ }
+ pclose (fp);
+ }
+#endif
+ return ret;
+}
+
+
+/* "/etc/hw -r cpu" for SCO OpenUnix 8, printing a line like
+ The speed of the CPU is approximately 450MHz
+ */
+static int
+freq_sco_etchw (int help)
+{
+ int ret = 0;
+#if HAVE_POPEN
+ FILE *fp;
+ char buf[128];
+ double val;
+ int end;
+
+ HELP ("SCO /etc/hw program output");
+
+ /* Error messages are sent to /dev/null in case /etc/hw doesn't exist.
+ The brackets are necessary for some shells. */
+ if ((fp = popen ("(/etc/hw -r cpu) 2>/dev/null", "r")) != NULL)
+ {
+ while (fgets (buf, sizeof (buf), fp) != NULL)
+ {
+ end = 0;
+ if (sscanf (buf, " The speed of the CPU is approximately %lfMHz%n",
+ &val, &end) == 1 && end != 0)
+ {
+ speed_cycletime = 1e-6 / val;
+ if (speed_option_verbose)
+ printf ("Using /etc/hw %.2f MHz, for cycle time %.3g\n",
+ val, speed_cycletime);
+ ret = 1;
+ break;
+ }
+ }
+ pclose (fp);
+ }
+#endif
+ return ret;
+}
+
+
+/* attr_get("/hw/cpunum/0",INFO_LBL_DETAIL_INVENT) ic_cpu_info.cpufq for
+ IRIX 6.5. Past versions don't have INFO_LBL_DETAIL_INVENT,
+ invent_cpuinfo_t, or /hw/cpunum/0.
+
+ The same information is available from the "hinv -c processor" command,
+ but it seems better to make a system call where possible. */
+
+static int
+freq_attr_get_invent (int help)
+{
+ int ret = 0;
+#if HAVE_ATTR_GET && HAVE_INVENT_H && defined (INFO_LBL_DETAIL_INVENT)
+ invent_cpuinfo_t inv;
+ int len, val;
+
+ HELP ("attr_get(\"/hw/cpunum/0\") ic_cpu_info.cpufq");
+
+ len = sizeof (inv);
+ if (attr_get ("/hw/cpunum/0", INFO_LBL_DETAIL_INVENT,
+ (char *) &inv, &len, 0) == 0
+ && len == sizeof (inv)
+ && inv.ic_gen.ig_invclass == INV_PROCESSOR)
+ {
+ val = inv.ic_cpu_info.cpufq;
+ speed_cycletime = 1e-6 / val;
+ if (speed_option_verbose)
+ printf ("Using attr_get(\"/hw/cpunum/0\") ic_cpu_info.cpufq %d MHz for cycle time %.3g\n", val, speed_cycletime);
+ ret = 1;
+ }
+#endif
+ return ret;
+}
+
+
+/* FreeBSD on i386 gives a line like the following at bootup, and which can
+ be read back from /var/run/dmesg.boot.
+
+ CPU: AMD Athlon(tm) Processor (755.29-MHz 686-class CPU)
+ CPU: Pentium 4 (1707.56-MHz 686-class CPU)
+ CPU: i486 DX4 (486-class CPU)
+
+ This is useful on FreeBSD 4.x, where there's no sysctl machdep.tsc_freq
+ or machdep.i586_freq.
+
+ It's better to use /var/run/dmesg.boot than to run /sbin/dmesg, since the
+ latter prints the current system message buffer, which is a limited size
+ and can wrap around if the system is up for a long time. */
+
+static int
+freq_bsd_dmesg (int help)
+{
+ FILE *fp;
+ char buf[256], *p;
+ double val;
+ int ret = 0;
+ int end;
+
+ HELP ("BSD /var/run/dmesg.boot file");
+
+ if ((fp = fopen ("/var/run/dmesg.boot", "r")) != NULL)
+ {
+ while (fgets (buf, sizeof (buf), fp) != NULL)
+ {
+ if (memcmp (buf, "CPU:", 4) == 0)
+ {
+ for (p = buf; *p != '\0'; p++)
+ {
+ end = 0;
+ if (sscanf (p, "(%lf-MHz%n", &val, &end) == 1 && end != 0)
+ {
+ speed_cycletime = 1e-6 / val;
+ if (speed_option_verbose)
+ printf ("Using /var/run/dmesg.boot CPU: %.2f MHz for cycle time %.3g\n", val, speed_cycletime);
+ ret = 1;
+ break;
+ }
+ }
+ }
+ }
+ fclose (fp);
+ }
+ return ret;
+}
+
+
+/* "hinv -c processor" for IRIX. The following lines have been seen,
+
+ 1 150 MHZ IP20 Processor
+ 2 195 MHZ IP27 Processors
+ Processor 0: 500 MHZ IP35
+
+ This information is available from attr_get() on IRIX 6.5 (see above),
+ but on IRIX 6.2 it's not clear where to look, so fall back on
+ parsing. */
+
+static int
+freq_irix_hinv (int help)
+{
+ int ret = 0;
+#if HAVE_POPEN
+ FILE *fp;
+ char buf[128];
+ double val;
+ int nproc, end;
+
+ HELP ("IRIX \"hinv -c processor\" output");
+
+ /* Error messages are sent to /dev/null in case hinv doesn't exist. The
+ brackets are necessary for some shells. */
+ if ((fp = popen ("(hinv -c processor) 2>/dev/null", "r")) != NULL)
+ {
+ while (fgets (buf, sizeof (buf), fp) != NULL)
+ {
+ end = 0;
+ if (sscanf (buf, "Processor 0: %lf MHZ%n", &val, &end) == 1
+ && end != 0)
+ {
+ found:
+ speed_cycletime = 1e-6 / val;
+ if (speed_option_verbose)
+ printf ("Using hinv -c processor \"%.2f MHZ\" for cycle time %.3g\n", val, speed_cycletime);
+ ret = 1;
+ break;
+ }
+ end = 0;
+ if (sscanf (buf, "%d %lf MHZ%n", &nproc, &val, &end) == 2
+ && end != 0)
+ goto found;
+ }
+ pclose (fp);
+ }
+#endif
+ return ret;
+}
+
+
+/* processor_info() for Solaris. "psrinfo" is the command-line interface to
+ this. "prtconf -vp" gives similar information.
+
+ Apple Darwin has a processor_info, but in an incompatible style. It
+ doesn't have <sys/processor.h>, so test for that. */
+
+static int
+freq_processor_info (int help)
+{
+#if HAVE_PROCESSOR_INFO && HAVE_SYS_PROCESSOR_H
+ processor_info_t p;
+ int i, n, mhz = 0;
+
+ HELP ("processor_info() pi_clock");
+
+ n = sysconf (_SC_NPROCESSORS_CONF);
+ for (i = 0; i < n; i++)
+ {
+ if (processor_info (i, &p) != 0)
+ continue;
+ if (p.pi_state != P_ONLINE)
+ continue;
+
+ if (mhz != 0 && p.pi_clock != mhz)
+ {
+ fprintf (stderr,
+ "freq_processor_info(): There's more than one CPU and they have different clock speeds\n");
+ return 0;
+ }
+
+ mhz = p.pi_clock;
+ }
+
+ speed_cycletime = 1.0e-6 / (double) mhz;
+
+ if (speed_option_verbose)
+ printf ("Using processor_info() %d mhz for cycle time %.3g\n",
+ mhz, speed_cycletime);
+ return 1;
+
+#else
+ return 0;
+#endif
+}
+
+
+#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETTIMEOFDAY
+static double
+freq_measure_gettimeofday_one (void)
+{
+#define call_gettimeofday(t) gettimeofday (&(t), NULL)
+#define timeval_tv_sec(t) ((t).tv_sec)
+#define timeval_tv_usec(t) ((t).tv_usec)
+ FREQ_MEASURE_ONE ("gettimeofday", struct timeval,
+ call_gettimeofday, speed_cyclecounter,
+ timeval_tv_sec, timeval_tv_usec);
+}
+#endif
+
+#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETRUSAGE
+static double
+freq_measure_getrusage_one (void)
+{
+#define call_getrusage(t) getrusage (0, &(t))
+#define rusage_tv_sec(t) ((t).ru_utime.tv_sec)
+#define rusage_tv_usec(t) ((t).ru_utime.tv_usec)
+ FREQ_MEASURE_ONE ("getrusage", struct rusage,
+ call_getrusage, speed_cyclecounter,
+ rusage_tv_sec, rusage_tv_usec);
+}
+#endif
+
+
+/* MEASURE_MATCH is how many readings within MEASURE_TOLERANCE of each other
+ are required. This must be at least 2. */
+#define MEASURE_MAX_ATTEMPTS 20
+#define MEASURE_TOLERANCE 1.005 /* 0.5% */
+#define MEASURE_MATCH 3
+
+double
+freq_measure (const char *name, double (*one) (void))
+{
+ double t[MEASURE_MAX_ATTEMPTS];
+ int i, j;
+
+ for (i = 0; i < numberof (t); i++)
+ {
+ t[i] = (*one) ();
+
+ qsort (t, i+1, sizeof(t[0]), (qsort_function_t) double_cmp_ptr);
+ if (speed_option_verbose >= 3)
+ for (j = 0; j <= i; j++)
+ printf (" t[%d] is %.6g\n", j, t[j]);
+
+ for (j = 0; j+MEASURE_MATCH-1 <= i; j++)
+ {
+ if (t[j+MEASURE_MATCH-1] <= t[j] * MEASURE_TOLERANCE)
+ {
+ /* use the average of the range found */
+ return (t[j+MEASURE_MATCH-1] + t[j]) / 2.0;
+ }
+ }
+ }
+ return -1.0;
+}
+
+static int
+freq_measure_getrusage (int help)
+{
+#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETRUSAGE
+ double cycletime;
+
+ if (! getrusage_microseconds_p ())
+ return 0;
+ if (! cycles_works_p ())
+ return 0;
+
+ HELP ("cycle counter measured with microsecond getrusage()");
+
+ cycletime = freq_measure ("getrusage", freq_measure_getrusage_one);
+ if (cycletime == -1.0)
+ return 0;
+
+ speed_cycletime = cycletime;
+ if (speed_option_verbose)
+ printf ("Using getrusage() measured cycle counter %.4g (%.2f MHz)\n",
+ speed_cycletime, 1e-6/speed_cycletime);
+ return 1;
+
+#else
+ return 0;
+#endif
+}
+
+static int
+freq_measure_gettimeofday (int help)
+{
+#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETTIMEOFDAY
+ double cycletime;
+
+ if (! gettimeofday_microseconds_p ())
+ return 0;
+ if (! cycles_works_p ())
+ return 0;
+
+ HELP ("cycle counter measured with microsecond gettimeofday()");
+
+ cycletime = freq_measure ("gettimeofday", freq_measure_gettimeofday_one);
+ if (cycletime == -1.0)
+ return 0;
+
+ speed_cycletime = cycletime;
+ if (speed_option_verbose)
+ printf ("Using gettimeofday() measured cycle counter %.4g (%.2f MHz)\n",
+ speed_cycletime, 1e-6/speed_cycletime);
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+
+/* Each function returns 1 if it succeeds in setting speed_cycletime, or 0
+ if not.
+
+ In general system call tests are first since they're fast, then file
+ tests, then tests running programs. Necessary exceptions to this rule
+ are noted. The measuring is last since it's time consuming, and rather
+ wasteful of cpu. */
+
+static int
+freq_all (int help)
+{
+ return
+ /* This should be first, so an environment variable can override
+ anything the system gives. */
+ freq_environment (help)
+
+ || freq_attr_get_invent (help)
+ || freq_getsysinfo (help)
+ || freq_pstat_getprocessor (help)
+ || freq_sysctl_hw_model (help)
+ || freq_sysctl_hw_cpufrequency (help)
+ || freq_sysctlbyname_i586_freq (help)
+ || freq_sysctlbyname_tsc_freq (help)
+
+ /* SCO openunix 8 puts a dummy pi_clock==16 in processor_info, so be
+ sure to check /etc/hw before that function. */
+ || freq_sco_etchw (help)
+
+ || freq_processor_info (help)
+ || freq_proc_cpuinfo (help)
+ || freq_bsd_dmesg (help)
+ || freq_irix_hinv (help)
+ || freq_sunos_sysinfo (help)
+ || freq_measure_getrusage (help)
+ || freq_measure_gettimeofday (help);
+}
+
+
+void
+speed_cycletime_init (void)
+{
+ static int attempted = 0;
+
+ if (attempted)
+ return;
+ attempted = 1;
+
+ if (freq_all (0))
+ return;
+
+ if (speed_option_verbose)
+ printf ("CPU frequency couldn't be determined\n");
+}
+
+
+void
+speed_cycletime_fail (const char *str)
+{
+ fprintf (stderr, "Measuring with: %s\n", speed_time_string);
+ fprintf (stderr, "%s,\n", str);
+ fprintf (stderr, "but none of the following are available,\n");
+ freq_all (1);
+ abort ();
+}
+
+/* speed_time_init leaves speed_cycletime set to either 0.0 or 1.0 when the
+ CPU frequency is unknown. 0.0 is when the time base is in seconds, so
+ that's no good if cycles are wanted. 1.0 is when the time base is in
+ cycles, which conversely is no good if seconds are wanted. */
+void
+speed_cycletime_need_cycles (void)
+{
+ speed_time_init ();
+ if (speed_cycletime == 0.0)
+ speed_cycletime_fail
+ ("Need to know CPU frequency to give times in cycles");
+}
+void
+speed_cycletime_need_seconds (void)
+{
+ speed_time_init ();
+ if (speed_cycletime == 1.0)
+ speed_cycletime_fail
+ ("Need to know CPU frequency to convert cycles to seconds");
+}
diff --git a/gmp/tune/gcdext_double.c b/gmp/tune/gcdext_double.c
new file mode 100644
index 0000000000..c72f07ea9f
--- /dev/null
+++ b/gmp/tune/gcdext_double.c
@@ -0,0 +1,39 @@
+/* mpn/generic/gcdext.c forced to use double limb calculations. */
+
+/*
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef GCDEXT_THRESHOLD
+#define GCDEXT_THRESHOLD 0
+#define __gmpn_gcdext mpn_gcdext_double
+
+#include "../mpn/generic/gcdext.c"
diff --git a/gmp/tune/gcdext_single.c b/gmp/tune/gcdext_single.c
new file mode 100644
index 0000000000..292e9e87e0
--- /dev/null
+++ b/gmp/tune/gcdext_single.c
@@ -0,0 +1,39 @@
+/* mpn/generic/gcdext.c forced to use single limb calculations. */
+
+/*
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef GCDEXT_THRESHOLD
+#define GCDEXT_THRESHOLD MP_SIZE_T_MAX
+#define __gmpn_gcdext mpn_gcdext_single
+
+#include "../mpn/generic/gcdext.c"
diff --git a/gmp/tune/gcdextod.c b/gmp/tune/gcdextod.c
new file mode 100644
index 0000000000..c08087d480
--- /dev/null
+++ b/gmp/tune/gcdextod.c
@@ -0,0 +1,40 @@
+/* mpn/generic/gcdext.c forced to one double limb step. */
+
+/*
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef GCDEXT_THRESHOLD
+#define GCDEXT_THRESHOLD 0
+#define WANT_GCDEXT_ONE_STEP 1
+#define __gmpn_gcdext mpn_gcdext_one_double
+
+#include "../mpn/generic/gcdext.c"
diff --git a/gmp/tune/gcdextos.c b/gmp/tune/gcdextos.c
new file mode 100644
index 0000000000..fb8af29279
--- /dev/null
+++ b/gmp/tune/gcdextos.c
@@ -0,0 +1,40 @@
+/* mpn/generic/gcdext.c forced to one single limb step. */
+
+/*
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef GCDEXT_THRESHOLD
+#define GCDEXT_THRESHOLD MP_SIZE_T_MAX
+#define WANT_GCDEXT_ONE_STEP 1
+#define __gmpn_gcdext mpn_gcdext_one_single
+
+#include "../mpn/generic/gcdext.c"
diff --git a/gmp/tune/hgcd_appr_lehmer.c b/gmp/tune/hgcd_appr_lehmer.c
new file mode 100644
index 0000000000..790e61e3cb
--- /dev/null
+++ b/gmp/tune/hgcd_appr_lehmer.c
@@ -0,0 +1,40 @@
+/* mpn/generic/hgcd_appr.c forced to use Lehmer's quadratic algorithm. */
+
+/*
+Copyright 2010, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef HGCD_APPR_THRESHOLD
+#define HGCD_APPR_THRESHOLD MP_SIZE_T_MAX
+#define __gmpn_hgcd_appr mpn_hgcd_appr_lehmer
+#define __gmpn_hgcd_appr_itch mpn_hgcd_appr_lehmer_itch
+
+#include "../mpn/generic/hgcd_appr.c"
diff --git a/gmp/tune/hgcd_lehmer.c b/gmp/tune/hgcd_lehmer.c
new file mode 100644
index 0000000000..11d0ef8821
--- /dev/null
+++ b/gmp/tune/hgcd_lehmer.c
@@ -0,0 +1,40 @@
+/* mpn/generic/hgcd.c forced to use Lehmer's quadratic algorithm. */
+
+/*
+Copyright 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef HGCD_THRESHOLD
+#define HGCD_THRESHOLD MP_SIZE_T_MAX
+#define __gmpn_hgcd mpn_hgcd_lehmer
+#define __gmpn_hgcd_itch mpn_hgcd_lehmer_itch
+
+#include "../mpn/generic/hgcd.c"
diff --git a/gmp/tune/hgcd_reduce_1.c b/gmp/tune/hgcd_reduce_1.c
new file mode 100644
index 0000000000..383c2d7009
--- /dev/null
+++ b/gmp/tune/hgcd_reduce_1.c
@@ -0,0 +1,41 @@
+/* mpn/generic/hgcd_reduce.c forced to use hgcd. */
+
+/*
+Copyright 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef HGCD_REDUCE_THRESHOLD
+#define HGCD_REDUCE_THRESHOLD MP_SIZE_T_MAX
+#define __gmpn_hgcd_reduce mpn_hgcd_reduce_1
+#define __gmpn_hgcd_reduce_itch mpn_hgcd_reduce_1_itch
+
+
+#include "../mpn/generic/hgcd_reduce.c"
diff --git a/gmp/tune/hgcd_reduce_2.c b/gmp/tune/hgcd_reduce_2.c
new file mode 100644
index 0000000000..ac18b6033a
--- /dev/null
+++ b/gmp/tune/hgcd_reduce_2.c
@@ -0,0 +1,40 @@
+/* mpn/generic/hgcd_reduce.c forced to use hgcd_appr. */
+
+/*
+Copyright 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef HGCD_REDUCE_THRESHOLD
+#define HGCD_REDUCE_THRESHOLD 0
+#define __gmpn_hgcd_reduce mpn_hgcd_reduce_2
+#define __gmpn_hgcd_reduce_itch mpn_hgcd_reduce_2_itch
+
+#include "../mpn/generic/hgcd_reduce.c"
diff --git a/gmp/tune/hppa.asm b/gmp/tune/hppa.asm
new file mode 100644
index 0000000000..fc9d62e3b2
--- /dev/null
+++ b/gmp/tune/hppa.asm
@@ -0,0 +1,42 @@
+dnl HPPA 32-bit time stamp counter access routine.
+
+dnl Copyright 2000, 2002, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+dnl void speed_cyclecounter (unsigned p[2]);
+dnl
+dnl Get the HPPA interval timer.
+
+PROLOGUE(speed_cyclecounter)
+ mfctl %cr16,%r28
+ stw %r28,0(0,%r26)
+ bv 0(%r2)
+ stw %r0,4(0,%r26)
+EPILOGUE(speed_cyclecounter)
diff --git a/gmp/tune/hppa2.asm b/gmp/tune/hppa2.asm
new file mode 100644
index 0000000000..57ef4c4683
--- /dev/null
+++ b/gmp/tune/hppa2.asm
@@ -0,0 +1,44 @@
+dnl HPPA 64-bit time stamp counter access routine.
+
+dnl Copyright 2000, 2002, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+dnl void speed_cyclecounter (unsigned p[2]);
+dnl
+dnl Get the HPPA interval timer.
+
+ .level 2.0
+PROLOGUE(speed_cyclecounter)
+ mfctl %cr16,%r28
+ stw %r28,0(0,%r26) ; low word
+ extrd,u %r28,31,32,%r28
+ bve (%r2)
+ stw %r28,4(0,%r26) ; high word
+EPILOGUE(speed_cyclecounter)
diff --git a/gmp/tune/hppa2w.asm b/gmp/tune/hppa2w.asm
new file mode 100644
index 0000000000..215a0cc5c2
--- /dev/null
+++ b/gmp/tune/hppa2w.asm
@@ -0,0 +1,44 @@
+dnl HPPA 64-bit time stamp counter access routine.
+
+dnl Copyright 2000, 2002, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+dnl void speed_cyclecounter (unsigned p[2]);
+dnl
+dnl Get the HPPA interval timer.
+
+ .level 2.0w
+PROLOGUE(speed_cyclecounter)
+ mfctl %cr16,%r28
+ stw %r28,0(0,%r26) ; low word
+ extrd,u %r28,31,32,%r28
+ bve (%r2)
+ stw %r28,4(0,%r26) ; high word
+EPILOGUE(speed_cyclecounter)
diff --git a/gmp/tune/ia64.asm b/gmp/tune/ia64.asm
new file mode 100644
index 0000000000..0651111031
--- /dev/null
+++ b/gmp/tune/ia64.asm
@@ -0,0 +1,47 @@
+dnl IA-64 time stamp counter access routine.
+
+dnl Copyright 2000, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C void speed_cyclecounter (unsigned int p[2]);
+C
+
+ASM_START()
+PROLOGUE(speed_cyclecounter)
+ mov r14 = ar.itc
+ ;;
+ st4 [r32] = r14, 4
+ shr.u r14 = r14, 32
+ ;;
+ st4 [r32] = r14
+ br.ret.sptk.many b0
+EPILOGUE(speed_cyclecounter)
+ASM_END()
diff --git a/gmp/tune/jacbase1.c b/gmp/tune/jacbase1.c
new file mode 100644
index 0000000000..a73df8b723
--- /dev/null
+++ b/gmp/tune/jacbase1.c
@@ -0,0 +1,38 @@
+/* mpn/generic/jacbase.c method 1.
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef JACOBI_BASE_METHOD
+#define JACOBI_BASE_METHOD 1
+#define __gmpn_jacobi_base mpn_jacobi_base_1
+
+#include "mpn/generic/jacbase.c"
diff --git a/gmp/tune/jacbase2.c b/gmp/tune/jacbase2.c
new file mode 100644
index 0000000000..b99ebe9061
--- /dev/null
+++ b/gmp/tune/jacbase2.c
@@ -0,0 +1,38 @@
+/* mpn/generic/jacbase.c method 2.
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef JACOBI_BASE_METHOD
+#define JACOBI_BASE_METHOD 2
+#define __gmpn_jacobi_base mpn_jacobi_base_2
+
+#include "mpn/generic/jacbase.c"
diff --git a/gmp/tune/jacbase3.c b/gmp/tune/jacbase3.c
new file mode 100644
index 0000000000..408b0fed6b
--- /dev/null
+++ b/gmp/tune/jacbase3.c
@@ -0,0 +1,38 @@
+/* mpn/generic/jacbase.c method 3.
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef JACOBI_BASE_METHOD
+#define JACOBI_BASE_METHOD 3
+#define __gmpn_jacobi_base mpn_jacobi_base_3
+
+#include "mpn/generic/jacbase.c"
diff --git a/gmp/tune/jacbase4.c b/gmp/tune/jacbase4.c
new file mode 100644
index 0000000000..70d535240b
--- /dev/null
+++ b/gmp/tune/jacbase4.c
@@ -0,0 +1,38 @@
+/* mpn/generic/jacbase.c method 4.
+
+Copyright 2002, 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef JACOBI_BASE_METHOD
+#define JACOBI_BASE_METHOD 4
+#define __gmpn_jacobi_base mpn_jacobi_base_4
+
+#include "mpn/generic/jacbase.c"
diff --git a/gmp/tune/many.pl b/gmp/tune/many.pl
new file mode 100644
index 0000000000..524a67dd1e
--- /dev/null
+++ b/gmp/tune/many.pl
@@ -0,0 +1,1334 @@
+#! /usr/bin/perl -w
+
+# Copyright 2000-2002 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library.
+#
+# The GNU MP Library is free software; you can redistribute it and/or modify
+# it under the terms of either:
+#
+# * the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# or
+#
+# * the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# or both in parallel, as here.
+#
+# The GNU MP Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received copies of the GNU General Public License and the
+# GNU Lesser General Public License along with the GNU MP Library. If not,
+# see https://www.gnu.org/licenses/.
+
+
+# Usage: cd $builddir/tune
+# perl $srcdir/tune/many.pl [-t] <files/dirs>...
+#
+# Output: speed-many.c
+# try-many.c
+# Makefile.many
+#
+# Make alternate versions of various mpn routines available for measuring
+# and testing.
+#
+# The $srcdir and $builddir in the invocation above just means the script
+# lives in the tune source directory, but should be run in the tune build
+# directory. When not using a separate object directory this just becomes
+#
+# cd tune
+# perl many.pl [-t] <files/dirs>...
+#
+#
+# SINGLE FILES
+#
+# Suppose $HOME/newcode/mul_1_experiment.asm is a new implementation of
+# mpn_mul_1, then
+#
+# cd $builddir/tune
+# perl $srcdir/tune/many.pl $HOME/newcode/mul_1_experiment.asm
+#
+# will produce rules and renaming so that a speed program incorporating it
+# can be built,
+#
+# make -f Makefile.many speed-many
+#
+# then for example it can be compared to the standard mul_1,
+#
+# ./speed-many -s 1-30 mpn_mul_1 mpn_mul_1_experiment
+#
+# An expanded try program can be used to check correctness,
+#
+# make -f Makefile.many try-many
+#
+# and run
+#
+# ./try-many mpn_mul_1_experiment
+#
+# Files can be ".c", ".S" or ".asm". ".s" files can't be used because they
+# don't get any preprocessing so there's no way to do renaming of their
+# functions.
+#
+#
+# WHOLE DIRECTORIES
+#
+# If a directory is given, then all files in it will be made available.
+# For example,
+#
+# cd $builddir/tune
+# perl $srcdir/tune/many.pl $HOME/newcode
+#
+# Each file should have a suffix, like "_experiment" above.
+#
+#
+# MPN DIRECTORIES
+#
+# mpn directories from the GMP source tree can be included, and this is a
+# convenient way to compare multiple implementations suiting different chips
+# in a CPU family. For example the following would make all x86 routines
+# available,
+#
+# cd $builddir/tune
+# perl $srcdir/tune/many.pl `find $srcdir/mpn/x86 -type d`
+#
+# On a new x86 chip a comparison could then be made to see how existing code
+# runs. For example,
+#
+# make -f Makefile.many speed-many
+# ./speed-many -s 1-30 -c \
+# mpn_add_n_x86 mpn_add_n_pentium mpn_add_n_k6 mpn_add_n_k7
+#
+# Files in "mpn" subdirectories don't need the "_experiment" style suffix
+# described above, instead a suffix is constructed from the subdirectory.
+# For example "mpn/x86/k7/mmx/mod_1.asm" will generate a function
+# mpn_mod_1_k7_mmx. The rule is to take the last directory name after the
+# "mpn", or the last two if there's three or more. (Check the generated
+# speed-many.c if in doubt.)
+#
+#
+# GENERIC C
+#
+# The mpn/generic directory can be included too, just like any processor
+# specific directory. This is a good way to compare assembler and generic C
+# implementations. For example,
+#
+# cd $builddir/tune
+# perl $srcdir/tune/many.pl $srcdir/mpn/generic
+#
+# or if just a few routines are of interest, then for example
+#
+# cd $builddir/tune
+# perl $srcdir/tune/many.pl \
+# $srcdir/mpn/generic/lshift.c \
+# $srcdir/mpn/generic/mod_1.c \
+# $srcdir/mpn/generic/aorsmul_1.c
+#
+# giving mpn_lshift_generic etc.
+#
+#
+# TESTS/DEVEL PROGRAMS
+#
+# Makefile.many also has rules to build the tests/devel programs with suitable
+# renaming, and with some parameters for correctness or speed. This is less
+# convenient than the speed and try programs, but provides an independent
+# check. For example,
+#
+# make -f Makefile.many tests_mul_1_experimental
+# ./tests_mul_1_experimental
+#
+# and for speed
+#
+# make -f Makefile.many tests_mul_1_experimental_sp
+# ./tests_mul_1_experimental_sp
+#
+# Not all the programs support speed measuring, in which case only the
+# correctness test will be useful.
+#
+# The parameters for repetitions and host clock speed are -D defines. Some
+# defaults are provided at the end of Makefile.many, but probably these will
+# want to be overridden. For example,
+#
+# rm tests_mul_1_experimental.o
+# make -f Makefile.many \
+# CFLAGS_TESTS="-DSIZE=50 -DTIMES=1000 -DRANDOM -DCLOCK=175000000" \
+# tests_mul_1_experimental
+# ./tests_mul_1_experimental
+#
+#
+# OTHER NOTES
+#
+# The mappings of file names to functions, and the macros to then use for
+# speed measuring etc are driven by @table below. The scheme isn't
+# completely general, it's only got as many variations as have been needed
+# so far.
+#
+# Some functions are only made available in speed-many, or others only in
+# try-many. An @table entry speed=>none means no speed measuring is
+# available, or try=>none no try program testing. These can be removed
+# if/when the respective programs get the necessary support.
+#
+# If a file has "1c" or "nc" carry-in entrypoints, they're renamed and made
+# available too. These are recognised from PROLOGUE or MULFUNC_PROLOGUE in
+# .S and .asm files, or from a line starting with "mpn_foo_1c" in a .c file
+# (possibly via a #define), and on that basis are entirely optional. This
+# entrypoint matching is done for the standard entrypoints too, but it would
+# be very unusual to have for instance a mul_1c without a mul_1.
+#
+# Some mpz files are recognized. For example an experimental copy of
+# mpz/powm.c could be included as powm_new.c and would be called
+# mpz_powm_new. So far only speed measuring is available for these.
+#
+# For the ".S" and ".asm" files, both PIC and non-PIC objects are built.
+# The PIC functions have a "_pic" suffix, for example "mpn_mod_1_k7_mmx_pic".
+# This can be ignored for routines that don't differ for PIC, or for CPUs
+# where everything is PIC anyway.
+#
+# K&R compilers are supported via the same ansi2knr mechanism used by
+# automake, though it's hard to believe anyone will have much interest in
+# measuring a compiler so old that it doesn't even have an ANSI mode.
+#
+# The "-t" option can be used to print a trace of the files found and what's
+# done with them. A great deal of obscure output is produced, but it can
+# indicate where or why some files aren't being recognised etc. For
+# example,
+#
+# cd $builddir/tune
+# perl $srcdir/tune/many.pl -t $HOME/newcode/add_n_weird.asm
+#
+# In general, when including new code, all that's really necessary is that
+# it will compile or assemble under the current configuration. It's fine if
+# some code doesn't actually run due to bugs, or to needing a newer CPU or
+# whatever, simply don't ask for the offending routines when invoking
+# speed-many or try-many, or don't try to run them on sizes they don't yet
+# support, or whatever.
+#
+#
+# CPU SPECIFICS
+#
+# x86 - All the x86 code will assemble on any system, but code for newer
+# chips might not run on older chips. Expect SIGILLs from new
+# instructions on old chips.
+#
+# A few "new" instructions, like cmov for instance, are done as macros
+# and will generate some equivalent plain i386 code when HAVE_HOST_CPU
+# in config.m4 indicates an old CPU. It won't run fast, but it does
+# make it possible to test correctness.
+#
+#
+# INTERNALS
+#
+# The nonsense involving $ENV is some hooks used during development to add
+# additional functions temporarily.
+#
+#
+# FUTURE
+#
+# Maybe the C files should be compiled pic and non-pic too. Wait until
+# there's a difference that might be of interest.
+#
+# Warn if a file provides no functions.
+#
+# Allow mpz and mpn files of the same name. Currently the mpn fib2_ui
+# matching hides the mpz version of that. Will need to check the file
+# contents to see which it is. Would be worth allowing an "mpz_" or "mpn_"
+# prefix on the filenames to have working versions of both in one directory.
+#
+#
+# LIMITATIONS
+#
+# Some of the command lines can become very long when a lot of files are
+# included. If this is a problem on a given system the only suggestion is
+# to run many.pl for just those that are actually wanted at a particular
+# time.
+#
+# DOS 8.3 or SysV 14 char filesystems won't work, since the long filenames
+# generated will almost certainly fail to be unique.
+
+
+use strict;
+use File::Basename;
+use Getopt::Std;
+
+my %opt;
+getopts('t', \%opt);
+
+my @DIRECTORIES = @ARGV;
+if (defined $ENV{directories}) { push @DIRECTORIES, @{$ENV{directories}} }
+
+
+# regexp - matched against the start of the filename. If a grouping "(...)"
+# is present then only the first such part is used.
+#
+# mulfunc - filenames to be generated from a multi-function file.
+#
+# funs - functions provided by the file, defaulting to the filename with mpn
+# (or mpX).
+#
+# mpX - prefix like "mpz", defaulting to "mpn".
+#
+# ret - return value type.
+#
+# args, args_<fun> - arguments for the given function. If an args_<fun> is
+# set then it's used, otherwise plain args is used. "mp_limb_t
+# carry" is appended for carry-in variants.
+#
+# try - try.c TYPE_ to use, defaulting to TYPE_fun with the function name
+# in upper case. "C" is appended for carry-in variants. Can be
+# 'none' for no try program entry.
+#
+# speed - SPEED_ROUTINE_ to use, handled like "try".
+#
+# speed_flags - SPEED_ROUTINE_ to use, handled like "try".
+
+
+my @table =
+ (
+ {
+ 'regexp'=> 'add_n|sub_n|addlsh1_n|sublsh1_n|rsh1add_n|rsh1sub_n',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
+ 'speed' => 'SPEED_ROUTINE_MPN_BINARY_N',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ },
+ {
+ 'regexp'=> 'aors_n',
+ 'mulfunc'=> ['add_n','sub_n'],
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
+ 'speed' => 'SPEED_ROUTINE_MPN_BINARY_N',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ },
+
+ {
+ 'regexp'=> 'addmul_1|submul_1',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_limb_t mult',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
+ 'speed_flags'=> 'FLAG_R',
+ },
+ {
+ 'regexp'=> 'aorsmul_1',
+ 'mulfunc'=> ['addmul_1','submul_1'],
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_limb_t mult',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
+ 'speed_flags'=> 'FLAG_R',
+ },
+
+ {
+ 'regexp'=> 'addmul_2|submul_2',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_2',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'try-minsize' => 2,
+ },
+ {
+ 'regexp'=> 'addmul_3|submul_3',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_3',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'try-minsize' => 3,
+ },
+ {
+ 'regexp'=> 'addmul_4|submul_4',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_4',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'try-minsize' => 4,
+ },
+ {
+ 'regexp'=> 'addmul_5|submul_5',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_5',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'try-minsize' => 5,
+ },
+ {
+ 'regexp'=> 'addmul_6|submul_6',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_6',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'try-minsize' => 6,
+ },
+ {
+ 'regexp'=> 'addmul_7|submul_7',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_7',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'try-minsize' => 7,
+ },
+ {
+ 'regexp'=> 'addmul_8|submul_8',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr yp',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_8',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'try-minsize' => 8,
+ },
+
+ {
+ 'regexp'=> 'add_n_sub_n',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr sum, mp_ptr diff, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ },
+
+ {
+ 'regexp'=> 'com|copyi|copyd',
+ 'ret' => 'void',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size',
+ 'speed' => 'SPEED_ROUTINE_MPN_COPY',
+ },
+
+ {
+ 'regexp'=> 'dive_1',
+ 'funs' => ['divexact_1'],
+ 'ret' => 'void',
+ 'args' => 'mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor',
+ 'speed_flags'=> 'FLAG_R',
+ },
+ {
+ 'regexp'=> 'diveby3',
+ 'funs' => ['divexact_by3c'],
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr dst, mp_srcptr src, mp_size_t size',
+ 'carrys'=> [''],
+ 'speed' => 'SPEED_ROUTINE_MPN_COPY',
+ },
+
+ # mpn_preinv_divrem_1 is an optional extra entrypoint
+ {
+ 'regexp'=> 'divrem_1',
+ 'funs' => ['divrem_1', 'preinv_divrem_1'],
+ 'ret' => 'mp_limb_t',
+ 'args_divrem_1' => 'mp_ptr rp, mp_size_t xsize, mp_srcptr sp, mp_size_t size, mp_limb_t divisor',
+ 'args_preinv_divrem_1' => 'mp_ptr rp, mp_size_t xsize, mp_srcptr sp, mp_size_t size, mp_limb_t divisor, mp_limb_t inverse, unsigned shift',
+ 'speed_flags'=> 'FLAG_R',
+ 'speed_suffixes' => ['f'],
+ },
+ {
+ 'regexp'=> 'pre_divrem_1',
+ 'funs' => ['preinv_divrem_1'],
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr qp, mp_size_t qxn, mp_srcptr ap, mp_size_t asize, mp_limb_t divisor, mp_limb_t inverse, int shift',
+ 'speed_flags' => 'FLAG_R',
+ },
+
+ {
+ 'regexp'=> 'divrem_2',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr qp, mp_size_t qxn, mp_srcptr np, mp_size_t nsize, mp_srcptr dp',
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'sb_divrem_mn',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr qp, mp_ptr np, mp_size_t nsize, mp_srcptr dp, mp_size_t dsize',
+ 'speed' => 'SPEED_ROUTINE_MPN_DC_DIVREM_SB',
+ 'try-minsize' => 3,
+ },
+ {
+ 'regexp'=> 'tdiv_qr',
+ 'ret' => 'void',
+ 'args' => 'mp_ptr qp, mp_size_t qxn, mp_ptr np, mp_size_t nsize, mp_srcptr dp, mp_size_t dsize',
+ 'speed' => 'none',
+ },
+
+ {
+ 'regexp'=> 'get_str',
+ 'ret' => 'size_t',
+ 'args' => 'unsigned char *str, int base, mp_ptr mptr, mp_size_t msize',
+ 'speed_flags' => 'FLAG_R_OPTIONAL',
+ 'try' => 'none',
+ },
+ {
+ 'regexp'=> 'set_str',
+ 'ret' => 'mp_size_t',
+ 'args' => 'mp_ptr xp, const unsigned char *str, size_t str_len, int base',
+ 'speed_flags' => 'FLAG_R_OPTIONAL',
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'fac_ui',
+ 'mpX' => 'mpz',
+ 'ret' => 'void',
+ 'args' => 'mpz_ptr r, unsigned long n',
+ 'speed_flags' => 'FLAG_NODATA',
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'fib2_ui',
+ 'ret' => 'void',
+ 'args' => 'mp_ptr fp, mp_ptr f1p, unsigned long n',
+ 'rename'=> ['__gmp_fib_table'],
+ 'speed_flags' => 'FLAG_NODATA',
+ 'try' => 'none',
+ },
+ {
+ 'regexp'=> 'fib_ui',
+ 'mpX' => 'mpz',
+ 'ret' => 'void',
+ 'args' => 'mpz_ptr fn, unsigned long n',
+ 'speed_flags' => 'FLAG_NODATA',
+ 'try' => 'none',
+ },
+ {
+ 'regexp'=> 'fib2_ui',
+ 'mpX' => 'mpz',
+ 'ret' => 'void',
+ 'args' => 'mpz_ptr fn, mpz_ptr fnsub1, unsigned long n',
+ 'speed_flags' => 'FLAG_NODATA',
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'lucnum_ui',
+ 'mpX' => 'mpz',
+ 'ret' => 'void',
+ 'args' => 'mpz_ptr ln, unsigned long n',
+ 'speed_flags' => 'FLAG_NODATA',
+ 'try' => 'none',
+ },
+ {
+ 'regexp'=> 'lucnum2_ui',
+ 'mpX' => 'mpz',
+ 'ret' => 'void',
+ 'args' => 'mpz_ptr ln, mpz_ptr lnsub1, unsigned long n',
+ 'speed_flags' => 'FLAG_NODATA',
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'gcd_1',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr xp, mp_size_t xsize, mp_limb_t y',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'speed_suffixes' => ['N'],
+ },
+ {
+ 'regexp'=> '(gcd)(?!(_1|ext|_finda))',
+ 'ret' => 'mp_size_t',
+ 'args' => 'mp_ptr gp, mp_ptr up, mp_size_t usize, mp_ptr vp, mp_size_t vsize',
+ },
+ {
+ 'regexp'=> 'gcd_finda',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_srcptr cp',
+ },
+
+
+ {
+ 'regexp'=> 'jacobi',
+ 'funs' => ['jacobi', 'legendre', 'kronecker'],
+ 'mpX' => 'mpz',
+ 'ret' => 'int',
+ 'args' => 'mpz_srcptr a, mpz_srcptr b',
+ 'try-legendre' => 'TYPE_MPZ_JACOBI',
+ },
+ {
+ 'regexp'=> 'jacbase',
+ 'funs' => ['jacobi_base'],
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_limb_t a, mp_limb_t b, int bit1',
+ 'speed' => 'SPEED_ROUTINE_MPN_JACBASE',
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'logops_n',
+ 'mulfunc'=> ['and_n','andn_n','nand_n','ior_n','iorn_n','nior_n','xor_n','xnor_n'],
+ 'ret' => 'void',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
+ 'speed' => 'SPEED_ROUTINE_MPN_BINARY_N',
+ },
+
+ {
+ 'regexp'=> '[lr]shift',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, unsigned shift',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
+ 'speed_flags'=> 'FLAG_R',
+ },
+
+ # mpn_preinv_mod_1 is an optional extra entrypoint
+ {
+ 'regexp'=> '(mod_1)(?!_rs)',
+ 'funs' => ['mod_1','preinv_mod_1'],
+ 'ret' => 'mp_limb_t',
+ 'args_mod_1' => 'mp_srcptr xp, mp_size_t size, mp_limb_t divisor',
+ 'args_preinv_mod_1'=> 'mp_srcptr xp, mp_size_t size, mp_limb_t divisor, mp_limb_t inverse',
+ 'speed_flags'=> 'FLAG_R',
+ },
+ {
+ 'regexp'=> 'pre_mod_1',
+ 'funs' => ['preinv_mod_1'],
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_srcptr xp, mp_size_t size, mp_limb_t divisor, mp_limb_t inverse',
+ 'speed_flags'=> 'FLAG_R',
+ },
+ {
+ 'regexp'=> 'mod_34lsub1',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_srcptr src, mp_size_t len',
+ },
+ {
+ 'regexp'=> 'invert_limb',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_limb_t divisor',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'try' => 'none',
+ },
+
+ {
+ # not for use with hppa reversed argument versions of mpn_umul_ppmm
+ 'regexp'=> 'udiv',
+ 'funs' => ['udiv_qrnnd','udiv_qrnnd_r'],
+ 'ret' => 'mp_limb_t',
+ 'args_udiv_qrnnd' => 'mp_limb_t *, mp_limb_t, mp_limb_t, mp_limb_t',
+ 'args_udiv_qrnnd_r' => 'mp_limb_t, mp_limb_t, mp_limb_t, mp_limb_t *',
+ 'speed' => 'none',
+ 'try-minsize' => 2,
+ },
+
+ {
+ 'regexp'=> 'mode1o',
+ 'funs' => ['modexact_1_odd'],
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_srcptr src, mp_size_t size, mp_limb_t divisor',
+ 'speed_flags'=> 'FLAG_R',
+ },
+ {
+ 'regexp'=> 'modlinv',
+ 'funs' => ['modlimb_invert'],
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_limb_t v',
+ 'carrys'=> [''],
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'mul_1',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_limb_t mult',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_1',
+ 'speed_flags'=> 'FLAG_R',
+ },
+ {
+ 'regexp'=> 'mul_2',
+ 'ret' => 'mp_limb_t',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size, mp_srcptr mult',
+ 'speed' => 'SPEED_ROUTINE_MPN_UNARY_2',
+ 'speed_flags'=> 'FLAG_R',
+ },
+
+ {
+ 'regexp'=> 'mul_basecase',
+ 'ret' => 'void',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t xsize, mp_srcptr yp, mp_size_t ysize',
+ 'speed_flags' => 'FLAG_R_OPTIONAL | FLAG_RSIZE',
+ },
+ {
+ 'regexp'=> '(mul_n)[_.]',
+ 'ret' => 'void',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size',
+ 'rename'=> ['kara_mul_n','kara_sqr_n','toom3_mul_n','toom3_sqr_n'],
+ },
+ {
+ 'regexp'=> 'umul',
+ 'funs' => ['umul_ppmm','umul_ppmm_r'],
+ 'ret' => 'mp_limb_t',
+ 'args_umul_ppmm' => 'mp_limb_t *lowptr, mp_limb_t m1, mp_limb_t m2',
+ 'args_umul_ppmm_r' => 'mp_limb_t m1, mp_limb_t m2, mp_limb_t *lowptr',
+ 'speed' => 'none',
+ 'try-minsize' => 3,
+ },
+
+
+ {
+ 'regexp'=> 'popham',
+ 'mulfunc'=> ['popcount','hamdist'],
+ 'ret' => 'unsigned long',
+ 'args_popcount'=> 'mp_srcptr xp, mp_size_t size',
+ 'args_hamdist' => 'mp_srcptr xp, mp_srcptr yp, mp_size_t size',
+ },
+ {
+ 'regexp'=> 'popcount',
+ 'ret' => 'unsigned long',
+ 'args' => 'mp_srcptr xp, mp_size_t size',
+ },
+ {
+ 'regexp'=> 'hamdist',
+ 'ret' => 'unsigned long',
+ 'args' => 'mp_srcptr xp, mp_srcptr yp, mp_size_t size',
+ # extra renaming to support sharing a data table with mpn_popcount
+ 'rename'=> ['popcount'],
+ },
+
+ {
+ 'regexp'=> 'sqr_basecase',
+ 'ret' => 'void',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size',
+ 'speed' => 'SPEED_ROUTINE_MPN_SQR',
+ 'try' => 'TYPE_SQR',
+ },
+ {
+ 'regexp'=> 'sqr_diagonal',
+ 'ret' => 'void',
+ 'args' => 'mp_ptr wp, mp_srcptr xp, mp_size_t size',
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'sqrtrem',
+ 'ret' => 'mp_size_t',
+ 'args' => 'mp_ptr root, mp_ptr rem, mp_srcptr src, mp_size_t size',
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'cntlz',
+ 'funs' => ['count_leading_zeros'],
+ 'ret' => 'unsigned',
+ 'args' => 'mp_limb_t',
+ 'macro-before' => "#undef COUNT_LEADING_ZEROS_0",
+ 'macro-speed' =>
+'#ifdef COUNT_LEADING_ZEROS_0
+#define COUNT_LEADING_ZEROS_0_ALLOWED 1
+#else
+#define COUNT_LEADING_ZEROS_0_ALLOWED 0
+#endif
+ SPEED_ROUTINE_COUNT_ZEROS_A (1, COUNT_LEADING_ZEROS_0_ALLOWED);
+ $fun (c, n);
+ SPEED_ROUTINE_COUNT_ZEROS_B ()',
+ 'speed_flags'=> 'FLAG_R_OPTIONAL',
+ 'try' => 'none',
+ },
+ {
+ 'regexp'=> 'cnttz',
+ 'funs' => ['count_trailing_zeros'],
+ 'ret' => 'unsigned',
+ 'args' => 'mp_limb_t',
+ 'macro-speed' => '
+ SPEED_ROUTINE_COUNT_ZEROS_A (0, 0);
+ $fun (c, n);
+ SPEED_ROUTINE_COUNT_ZEROS_B ()',
+ 'speed_flags' => 'FLAG_R_OPTIONAL',
+ 'try' => 'none',
+ },
+
+ {
+ 'regexp'=> 'zero',
+ 'ret' => 'void',
+ 'args' => 'mp_ptr ptr, mp_size_t size',
+ },
+
+ {
+ 'regexp'=> '(powm)(?!_ui)',
+ 'mpX' => 'mpz',
+ 'ret' => 'void',
+ 'args' => 'mpz_ptr r, mpz_srcptr b, mpz_srcptr e, mpz_srcptr m',
+ 'try' => 'none',
+ },
+ {
+ 'regexp'=> 'powm_ui',
+ 'mpX' => 'mpz',
+ 'ret' => 'void',
+ 'args' => 'mpz_ptr r, mpz_srcptr b, unsigned long e, mpz_srcptr m',
+ 'try' => 'none',
+ },
+
+ # special for use during development
+ {
+ 'regexp'=> 'back',
+ 'funs' => ['back_to_back'],
+ 'ret' => 'void',
+ 'args' => 'void',
+ 'pic' => 'no',
+ 'try' => 'none',
+ 'speed_flags'=> 'FLAG_NODATA',
+ },
+ );
+
+if (defined $ENV{table2}) {
+ my @newtable = @{$ENV{table2}};
+ push @newtable, @table;
+ @table = @newtable;
+}
+
+
+my %pictable =
+ (
+ 'yes' => {
+ 'suffix' => '_pic',
+ 'asmflags'=> '$(ASMFLAGS_PIC)',
+ 'cflags' => '$(CFLAGS_PIC)',
+ },
+ 'no' => {
+ 'suffix' => '',
+ 'asmflags'=> '',
+ 'cflags' => '',
+ },
+ );
+
+
+my $builddir = $ENV{builddir};
+$builddir = "." if (! defined $builddir);
+
+my $top_builddir = "${builddir}/..";
+
+
+open(MAKEFILE, "<${builddir}/Makefile")
+ or die "Cannot open ${builddir}/Makefile: $!\n"
+ . "Is this a tune build directory?";
+my ($srcdir, $top_srcdir);
+while (<MAKEFILE>) {
+ if (/^srcdir = (.*)/) { $srcdir = $1; }
+ if (/^top_srcdir = (.*)/) { $top_srcdir = $1; }
+}
+die "Cannot find \$srcdir in Makefile\n" if (! defined $srcdir);
+die "Cannot find \$top_srcdir in Makefile\n" if (! defined $top_srcdir);
+print "srcdir $srcdir\n" if $opt{'t'};
+print "top_srcdir $top_srcdir\n" if $opt{'t'};
+close(MAKEFILE);
+
+
+open(SPEED, ">speed-many.c") or die;
+print SPEED
+"/* speed-many.c generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST */
+
+";
+my $SPEED_EXTRA_ROUTINES = "#define SPEED_EXTRA_ROUTINES \\\n";
+my $SPEED_EXTRA_PROTOS = "#define SPEED_EXTRA_PROTOS \\\n";
+my $SPEED_CODE = "";
+
+open(TRY, ">try-many.c") or die;
+print TRY
+ "/* try-many.c generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST */\n" .
+ "\n";
+my $TRY_EXTRA_ROUTINES = "#define EXTRA_ROUTINES \\\n";
+my $TRY_EXTRA_PROTOS = "#define EXTRA_PROTOS \\\n";
+
+open(FD,"<${top_builddir}/libtool") or die "Cannot open \"${top_builddir}/libtool\": $!\n";
+my $pic_flag;
+while (<FD>) {
+ if (/^pic_flag="?([^"]*)"?$/) {
+ $pic_flag=$1;
+ last;
+ }
+}
+close FD;
+if (! defined $pic_flag) {
+ die "Cannot find pic_flag in ${top_builddir}/libtool";
+}
+
+my $CFLAGS_PIC = $pic_flag;
+
+my $ASMFLAGS_PIC = "";
+foreach (split /[ \t]/, $pic_flag) {
+ if (/^-D/) {
+ $ASMFLAGS_PIC .= " " . $_;
+ }
+}
+
+open(MAKEFILE, ">Makefile.many") or die;
+print MAKEFILE
+ "# Makefile.many generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST\n" .
+ "\n" .
+ "all: speed-many try-many\n" .
+ "\n" .
+ "#--------- begin included copy of basic Makefile ----------\n" .
+ "\n";
+open(FD,"<${builddir}/Makefile") or die "Cannot open \"${builddir}/Makefile\": $!\n";
+print MAKEFILE <FD>;
+close FD;
+print MAKEFILE
+ "\n" .
+ "#--------- end included copy of basic Makefile ----------\n" .
+ "\n" .
+ "CFLAGS_PIC = $CFLAGS_PIC\n" .
+ "ASMFLAGS_PIC = $ASMFLAGS_PIC\n" .
+ "\n";
+
+my $CLEAN="";
+my $MANY_OBJS="";
+
+
+sub print_ansi2knr {
+ my ($base,$file,$includes) = @_;
+ if (! defined $file) { $file = "$base.c"; }
+ if (! defined $includes) { $includes = ""; }
+
+ print MAKEFILE <<EOF;
+${base}_.c: $file \$(ANSI2KNR)
+ \$(CPP) \$(DEFS) \$(INCLUDES) $includes \$(AM_CPPFLAGS) \$(CPPFLAGS) $file | sed 's/^# \([0-9]\)/#line \\1/' | \$(ANSI2KNR) >${base}_.c
+
+EOF
+}
+
+
+# Spawning a glob is a touch slow when there's lots of files.
+my @files = ();
+foreach my $dir (@DIRECTORIES) {
+ print "dir $dir\n" if $opt{'t'};
+ if (-f $dir) {
+ push @files,$dir;
+ } else {
+ if (! opendir DD,$dir) {
+ print "Cannot open $dir: $!\n";
+ } else {
+ push @files, map {$_="$dir/$_"} grep /\.(c|asm|S|h)$/, readdir DD;
+ closedir DD;
+ }
+ }
+}
+@files = sort @files;
+print "@files ",join(" ",@files),"\n" if $opt{'t'};
+
+my $count_files = 0;
+my $count_functions = 0;
+my %seen_obj;
+my %seen_file;
+
+foreach my $file_full (@files) {
+ if (! -f $file_full) {
+ print "Not a file: $file_full\n";
+ next;
+ }
+ if (defined $seen_file{$file_full}) {
+ print "Skipping duplicate file: $file_full\n";
+ next;
+ }
+ $seen_file{$file_full} = 1;
+
+ my ($FILE,$path,$lang) = fileparse($file_full,"\.[a-zA-Z]+");
+ $path =~ s/\/$//;
+ print "file $FILE path $path lang $lang\n" if $opt{'t'};
+
+ my @pic_choices;
+ if ($lang eq '.asm') { @pic_choices=('no','yes'); }
+ elsif ($lang eq '.c') { @pic_choices=('no'); }
+ elsif ($lang eq '.S') { @pic_choices=('no','yes'); }
+ elsif ($lang eq '.h') { @pic_choices=('no'); }
+ else { next };
+
+ my ($t, $file_match);
+ foreach my $p (@table) {
+ # print " ",$p->{'regexp'},"\n" if $opt{'t'};
+ if ($FILE =~ "^($p->{'regexp'})") {
+ $t = $p;
+ $file_match = $1;
+ $file_match = $2 if defined $2;
+ last;
+ }
+ }
+ next if ! defined $t;
+ print "match $t->{'regexp'} $FILE ($file_full)\n" if $opt{'t'};
+
+ if (! open FD,"<$file_full") { print "Can't open $file_full: $!\n"; next }
+ my @file_contents = <FD>;
+ close FD;
+
+ my $objs;
+ if (defined $t->{'mulfunc'}) { $objs = $t->{'mulfunc'}; }
+ else { $objs = [$file_match]; }
+ print "objs @$objs\n" if $opt{'t'};
+
+ my $ret = $t->{'ret'};
+ if (! defined $ret && $lang eq '.h') { $ret = ''; }
+ if (! defined $ret) { die "$FILE return type not defined\n" };
+ print "ret $ret\n" if $opt{'t'};
+
+ my $mpX = $t->{'mpX'};
+ if (! defined $mpX) { $mpX = ($lang eq '.h' ? '' : 'mpn'); }
+ $mpX = "${mpX}_" if $mpX ne '';
+ print "mpX $mpX\n" if $opt{'t'};
+
+ my $carrys;
+ if (defined $t->{'carrys'}) { $carrys = $t->{'carrys'}; }
+ else { $carrys = ['','c']; }
+ print "carrys $carrys @$carrys\n" if $opt{'t'};
+
+ # some restriction functions are implemented, but they're not very useful
+ my $restriction='';
+
+ my $suffix;
+ if ($FILE =~ ("${file_match}_(.+)")) {
+ $suffix = $1;
+ } elsif ($path =~ /\/mp[zn]\/(.*)$/) {
+ # derive the suffix from the path
+ $suffix = $1;
+ $suffix =~ s/\//_/g;
+ # use last directory name, or if there's 3 or more then the last two
+ if ($suffix =~ /([^_]*_)+([^_]+_[^_]+)$/) {
+ $suffix = $2;
+ } elsif ($suffix =~ /([^_]*_)*([^_]+)$/) {
+ $suffix = $2;
+ }
+ } else {
+ die "Can't determine suffix for: $file_full (path $path)\n";
+ }
+ print "suffix $suffix\n" if $opt{'t'};
+
+ $count_files++;
+
+ foreach my $obj (@{$objs}) {
+ print "obj $obj\n" if $opt{'t'};
+
+ my $obj_with_suffix = "${obj}_$suffix";
+ if (defined $seen_obj{$obj_with_suffix}) {
+ print "Skipping duplicate object: $obj_with_suffix\n";
+ print " first from: $seen_obj{$obj_with_suffix}\n";
+ print " now from: $file_full\n";
+ next;
+ }
+ $seen_obj{$obj_with_suffix} = $file_full;
+
+ my $funs = $t->{'funs'};
+ $funs = [$obj] if ! defined $funs;
+ print "funs @$funs\n" if $opt{'t'};
+
+ if (defined $t->{'pic'}) { @pic_choices = ('no'); }
+
+ foreach my $pic (map {$pictable{$_}} @pic_choices) {
+ print "pic $pic->{'suffix'}\n" if $opt{'t'};
+
+ my $objbase = "${obj}_$suffix$pic->{'suffix'}";
+ print "objbase $objbase\n" if $opt{'t'};
+
+ if ($path !~ "." && -f "${objbase}.c") {
+ die "Already have ${objbase}.c";
+ }
+
+ my $tmp_file = "tmp-$objbase.c";
+
+ my $renaming;
+ foreach my $fun (@{$funs}) {
+ if ($mpX eq 'mpn_' && $lang eq '.c') {
+ $renaming .= "\t\t-DHAVE_NATIVE_mpn_$fun=1 \\\n";
+ }
+
+ # The carry-in variant is with a "c" appended, unless there's a "_1"
+ # somewhere, eg. "modexact_1_odd", in which case that becomes "_1c".
+ my $fun_carry = $fun;
+ if (! ($fun_carry =~ s/_1/_1c/)) { $fun_carry = "${fun}c"; }
+
+ $renaming .=
+ "\t\t-D__g$mpX$fun=$mpX${fun}_$suffix$pic->{'suffix'} \\\n" .
+ "\t\t-D__g$mpX$fun_carry=$mpX${fun_carry}_$suffix$pic->{'suffix'} \\\n";
+ }
+ foreach my $r (@{$t->{'rename'}}) {
+ if ($r =~ /^__gmp/) {
+ $renaming .= "\\\n" .
+ "\t\t-D$r=${r}_$suffix$pic->{'suffix'}";
+ } else {
+ $renaming .= "\\\n" .
+ "\t\t-D__g$mpX$r=$mpX${r}_$suffix$pic->{'suffix'}";
+ }
+ }
+ print "renaming $renaming\n" if $opt{'t'};
+
+ print MAKEFILE "\n";
+ if ($lang eq '.asm') {
+ print MAKEFILE
+ "$objbase.o: $file_full \$(ASM_HEADERS)\n" .
+ " \$(M4) \$(M4FLAGS) -DOPERATION_$obj $pic->{'asmflags'} \\\n" .
+ "$renaming" .
+ " $file_full >tmp-$objbase.s\n" .
+ " \$(CCAS) \$(COMPILE_FLAGS) $pic->{'cflags'} tmp-$objbase.s -o $objbase.o\n" .
+ " \$(RM_TMP) tmp-$objbase.s\n";
+ $MANY_OBJS .= " $objbase.o";
+
+ } elsif ($lang eq '.c') {
+ print MAKEFILE
+ "$objbase.o: $file_full\n" .
+ " \$(COMPILE) -DOPERATION_$obj $pic->{'cflags'} \\\n" .
+ "$renaming" .
+ " -c $file_full -o $objbase.o\n";
+ print_ansi2knr($objbase,
+ $file_full,
+ " -DOPERATION_$obj\\\n$renaming\t\t");
+ $MANY_OBJS .= " $objbase\$U.o";
+
+ } elsif ($lang eq '.S') {
+ print MAKEFILE
+ "$objbase.o: $file_full\n" .
+ " \$(COMPILE) -g $pic->{'asmflags'} \\\n" .
+ "$renaming" .
+ " -c $file_full -o $objbase.o\n";
+ $MANY_OBJS .= " $objbase.o";
+
+ } elsif ($lang eq '.h') {
+ print MAKEFILE
+ "$objbase.o: tmp-$objbase.c $file_full\n" .
+ " \$(COMPILE) -DOPERATION_$obj $pic->{'cflags'} \\\n" .
+ "$renaming" .
+ " -c tmp-$objbase.c -o $objbase.o\n";
+ print_ansi2knr($objbase,
+ "tmp-$objbase.c",
+ " -DOPERATION_$obj\\\n$renaming\t\t");
+ $MANY_OBJS .= " $objbase\$U.o";
+
+ $CLEAN .= " tmp-$objbase.c";
+ open(TMP_C,">tmp-$objbase.c")
+ or die "Can't create tmp-$objbase.c: $!\n";
+ print TMP_C
+"/* tmp-$objbase.c generated by many.pl - DO NOT EDIT, CHANGES WILL BE LOST */
+
+#include \"gmp.h\"
+#include \"gmp-impl.h\"
+#include \"longlong.h\"
+#include \"speed.h\"
+
+";
+ }
+
+ my $tests_program = "$top_srcdir/tests/devel/$obj.c";
+ if (-f $tests_program) {
+ $tests_program = "\$(top_srcdir)/tests/devel/$obj.c";
+ print_ansi2knr("tests_${objbase}",
+ $tests_program,
+ "\\\n$renaming\t\t\$(CFLAGS_TESTS_SP)");
+ print_ansi2knr("tests_${objbase}_sp",
+ $tests_program,
+ "\\\n$renaming\t\t\$(CFLAGS_TESTS_SP)");
+
+ print MAKEFILE <<EOF;
+tests_$objbase.o: $tests_program
+ \$(COMPILE) \$(CFLAGS_TESTS) \\
+$renaming -c $tests_program -o tests_$objbase.o
+
+tests_$objbase: $objbase\$U.o tests_$objbase\$U.o ../libgmp.la
+ \$(LINK) tests_$objbase\$U.o $objbase\$U.o ../libgmp.la -o tests_$objbase
+
+tests_${objbase}_sp.o: $tests_program
+ \$(COMPILE) \$(CFLAGS_TESTS_SP) \\
+$renaming -c $tests_program -o tests_${objbase}_sp.o
+
+tests_${objbase}_sp: $objbase\$U.o tests_${objbase}_sp\$U.o ../libgmp.la
+ \$(LINK) tests_${objbase}_sp\$U.o $objbase\$U.o ../libgmp.la -o tests_${objbase}_sp
+
+EOF
+ $CLEAN .= " tests_$objbase tests_${objbase}_sp";
+ }
+
+ foreach my $fun (@{$funs}) {
+ print "fun $fun\n" if $opt{'t'};
+
+ if ($lang eq '.h') {
+ my $macro_before = $t->{'macro_before'};
+ $macro_before = "" if ! defined $macro_before;
+ print TMP_C
+"$macro_before
+#undef $fun
+#include \"$file_full\"
+
+";
+ }
+
+ my $args = $t->{"args_$fun"};
+ if (! defined $args) { $args = $t->{'args'}; }
+ if (! defined $args) { die "Need args for $fun\n"; }
+ print "args $args\n" if $opt{'t'};
+
+ foreach my $carry (@$carrys) {
+ print "carry $carry\n" if $opt{'t'};
+
+ my $fun_carry = $fun;
+ if (! ($fun_carry =~ s/_1/_1$carry/)) { $fun_carry = "$fun$carry"; }
+ print "fun_carry $fun_carry\n" if $opt{'t'};
+
+ if ($lang =~ /\.(asm|S)/
+ && ! grep(m"PROLOGUE\((.* )?$mpX$fun_carry[ ,)]",@file_contents)) {
+ print "no PROLOGUE $mpX$fun_carry\n" if $opt{'t'};
+ next;
+ }
+ if ($lang eq '.c'
+ && ! grep(m"^(#define FUNCTION\s+)?$mpX$fun_carry\W", @file_contents)) {
+ print "no mention of $mpX$fun_carry\n" if $opt{'t'};
+ next;
+ }
+ if ($lang eq '.h'
+ && ! grep(m"^#define $fun_carry\W", @file_contents)) {
+ print "no mention of #define $fun_carry\n" if $opt{'t'};
+ next;
+ }
+
+ $count_functions++;
+
+ my $carryarg;
+ if (defined $t->{'carryarg'}) { $carryarg = $t->{'carryarg'}; }
+ if ($carry eq '') { $carryarg = ''; }
+ else { $carryarg = ', mp_limb_t carry'; }
+ print "carryarg $carryarg\n" if $opt{'t'};
+
+ my $funfull="$mpX${fun_carry}_$suffix$pic->{'suffix'}";
+ print "funfull $funfull\n" if $opt{'t'};
+
+ if ($lang ne '.h') {
+ my $proto = "$t->{'ret'} $funfull _PROTO (($args$carryarg)); \\\n";
+ $SPEED_EXTRA_PROTOS .= $proto;
+ $TRY_EXTRA_PROTOS .= $proto;
+ }
+
+ my $try_type = $t->{"try-$fun"};
+ $try_type = $t->{'try'} if ! defined $try_type;
+ if (! defined $try_type) {
+ if ($mpX eq 'mpn_') {
+ $try_type = "TYPE_\U$fun_carry";
+ } else {
+ $try_type = "TYPE_\U$mpX\U$fun_carry";
+ }
+ }
+ print "try_type $try_type\n" if $opt{'t'};
+
+ my $try_minsize = $t->{'try-minsize'};
+ if (defined $try_minsize) {
+ $try_minsize = ", " . $try_minsize;
+ } else {
+ $try_minsize = "";
+ }
+ print "try_minsize $try_minsize\n" if $opt{'t'};
+
+ if ($try_type ne 'none') {
+ $TRY_EXTRA_ROUTINES .=
+ " { TRY($mpX${fun_carry}_$suffix$pic->{'suffix'}), $try_type$try_minsize }, \\\n";
+ }
+
+ my $speed_flags = $t->{'speed_flags'};
+ $speed_flags = '0' if ! defined $speed_flags;
+ print "speed_flags $speed_flags\n" if $opt{'t'};
+
+ my $speed_routine = $t->{'speed'};
+ $speed_routine = "SPEED_ROUTINE_\U$mpX\U$fun"
+ if !defined $speed_routine;
+ if (! ($speed_routine =~ s/_1/_1\U$carry/)) {
+ $speed_routine = "$speed_routine\U$carry";
+ }
+ print "speed_routine $speed_routine\n" if $opt{'t'};
+
+ my @speed_suffixes = ();
+ push (@speed_suffixes, '') if $speed_routine ne 'none';
+ push (@speed_suffixes, @{$t->{'speed_suffixes'}})
+ if defined $t->{'speed_suffixes'};
+
+ my $macro_speed = $t->{'macro-speed'};
+ $macro_speed = "$speed_routine ($fun_carry)" if ! defined $macro_speed;
+ $macro_speed =~ s/\$fun/$fun_carry/g;
+
+ foreach my $S (@speed_suffixes) {
+ my $Sfunfull="$mpX${fun_carry}${S}_$suffix$pic->{'suffix'}";
+
+ $SPEED_EXTRA_PROTOS .=
+ "double speed_$Sfunfull _PROTO ((struct speed_params *s)); \\\n";
+ $SPEED_EXTRA_ROUTINES .=
+ " { \"$Sfunfull\", speed_$Sfunfull, $speed_flags }, \\\n";
+ if ($lang eq '.h') {
+ print TMP_C
+"double
+speed_$Sfunfull (struct speed_params *s)
+{
+$macro_speed
+}
+
+";
+ } else {
+ $SPEED_CODE .=
+ "double\n" .
+ "speed_$Sfunfull (struct speed_params *s)\n" .
+ "{\n" .
+ "$restriction" .
+ " $speed_routine\U$S\E ($funfull)\n" .
+ "}\n";
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+print SPEED $SPEED_EXTRA_PROTOS . "\n";
+print SPEED $SPEED_EXTRA_ROUTINES . "\n";
+if (defined $ENV{speedinc}) { print SPEED $ENV{speedinc} . "\n"; }
+print SPEED
+ "#include \"speed.c\"\n" .
+ "\n";
+print SPEED $SPEED_CODE;
+
+print TRY $TRY_EXTRA_ROUTINES . "\n";
+print TRY $TRY_EXTRA_PROTOS . "\n";
+my $tryinc = "";
+if (defined $ENV{tryinc}) {
+ $tryinc = $ENV{tryinc};
+ print TRY "#include \"$tryinc\"\n";
+}
+print "tryinc $tryinc\n" if $opt{'t'};
+print TRY
+ "#include \"try.c\"\n" .
+ "\n";
+
+my $extra_libraries = "";
+if (defined $ENV{extra_libraries}) { $extra_libraries = $ENV{extra_libraries};}
+
+my $trydeps = "";
+if (defined $ENV{trydeps}) { $trydeps = $ENV{trydeps}; }
+$trydeps .= " $tryinc";
+print "trydeps $trydeps\n" if $opt{'t'};
+
+print MAKEFILE <<EOF;
+
+MANY_OBJS = $MANY_OBJS
+MANY_CLEAN = \$(MANY_OBJS) \\
+ speed-many.c speed-many\$U.o speed-many\$(EXEEXT) \\
+ try-many.c try-many\$U.o try-many \\
+ $CLEAN
+MANY_DISTCLEAN = Makefile.many
+
+speed-many: \$(MANY_OBJS) speed-many\$U.o libspeed.la $extra_libraries
+ \$(LINK) \$(LDFLAGS) speed-many\$U.o \$(MANY_OBJS) \$(LDADD) \$(LIBS) $extra_libraries
+
+try-many: \$(MANY_OBJS) try-many\$U.o libspeed.la $extra_libraries
+ \$(LINK) \$(LDFLAGS) try-many\$U.o \$(MANY_OBJS) \$(LDADD) \$(LIBS) $extra_libraries
+
+try-many.o: try-many.c \$(top_srcdir)/tests/devel/try.c $trydeps
+ \$(COMPILE) -I\$(top_srcdir)/tests/devel -c try-many.c
+
+EOF
+
+print_ansi2knr("speed-many");
+print_ansi2knr("try-many",
+ "\$(top_srcdir)/tests/devel/try.c",
+ "-I\$(top_srcdir)/tests/devel");
+
+print MAKEFILE <<EOF;
+RM_TMP = rm -f
+CFLAGS_TESTS = -DSIZE=50 -DTIMES=1 -DRANDOM -DCLOCK=333000000
+CFLAGS_TESTS_SP = -DSIZE=1024 -DNOCHECK -DOPS=200000000 -DCLOCK=333000000
+EOF
+
+close MAKEFILE or die;
+
+print "Total $count_files files, $count_functions functions\n";
+
+
+
+# Local variables:
+# perl-indent-level: 2
+# End:
diff --git a/gmp/tune/mod_1_1-1.c b/gmp/tune/mod_1_1-1.c
new file mode 100644
index 0000000000..7eb7fcdf79
--- /dev/null
+++ b/gmp/tune/mod_1_1-1.c
@@ -0,0 +1,41 @@
+/* mpn/generic/mod_1_1.c method 1.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef MOD_1_1P_METHOD
+#define MOD_1_1P_METHOD 1
+#undef mpn_mod_1_1p
+#undef mpn_mod_1_1p_cps
+#define mpn_mod_1_1p mpn_mod_1_1p_1
+#define mpn_mod_1_1p_cps mpn_mod_1_1p_cps_1
+
+#include "mpn/generic/mod_1_1.c"
diff --git a/gmp/tune/mod_1_1-2.c b/gmp/tune/mod_1_1-2.c
new file mode 100644
index 0000000000..52ca57749b
--- /dev/null
+++ b/gmp/tune/mod_1_1-2.c
@@ -0,0 +1,41 @@
+/* mpn/generic/mod_1_1.c method 2.
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef MOD_1_1P_METHOD
+#define MOD_1_1P_METHOD 2
+#undef mpn_mod_1_1p
+#undef mpn_mod_1_1p_cps
+#define mpn_mod_1_1p mpn_mod_1_1p_2
+#define mpn_mod_1_1p_cps mpn_mod_1_1p_cps_2
+
+#include "mpn/generic/mod_1_1.c"
diff --git a/gmp/tune/mod_1_div.c b/gmp/tune/mod_1_div.c
new file mode 100644
index 0000000000..a0663be055
--- /dev/null
+++ b/gmp/tune/mod_1_div.c
@@ -0,0 +1,46 @@
+/* mpn/generic/mod_1.c forced to use plain udiv_qrnnd.
+
+Copyright 2000, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define OPERATION_mod_1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef MOD_1_NORM_THRESHOLD
+#undef MOD_1_UNNORM_THRESHOLD
+#undef MOD_1N_TO_MOD_1_1_THRESHOLD
+#undef MOD_1U_TO_MOD_1_1_THRESHOLD
+#define MOD_1_NORM_THRESHOLD MP_SIZE_T_MAX
+#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX
+#define MOD_1N_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX
+#define MOD_1U_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX
+#define __gmpn_mod_1 mpn_mod_1_div
+
+#include "mpn/generic/mod_1.c"
diff --git a/gmp/tune/mod_1_inv.c b/gmp/tune/mod_1_inv.c
new file mode 100644
index 0000000000..92c936ddcf
--- /dev/null
+++ b/gmp/tune/mod_1_inv.c
@@ -0,0 +1,46 @@
+/* mpn/generic/mod_1.c forced to use mul-by-inverse udiv_qrnnd_preinv.
+
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define OPERATION_mod_1
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef MOD_1_NORM_THRESHOLD
+#undef MOD_1_UNNORM_THRESHOLD
+#undef MOD_1N_TO_MOD_1_1_THRESHOLD
+#undef MOD_1U_TO_MOD_1_1_THRESHOLD
+#define MOD_1_NORM_THRESHOLD 0
+#define MOD_1_UNNORM_THRESHOLD 0
+#define MOD_1N_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX
+#define MOD_1U_TO_MOD_1_1_THRESHOLD MP_SIZE_T_MAX
+#define __gmpn_mod_1 mpn_mod_1_inv
+
+#include "mpn/generic/mod_1.c"
diff --git a/gmp/tune/modlinv.c b/gmp/tune/modlinv.c
new file mode 100644
index 0000000000..e3f2063e07
--- /dev/null
+++ b/gmp/tune/modlinv.c
@@ -0,0 +1,178 @@
+/* Alternate implementations of binvert_limb to compare speeds. */
+
+/*
+Copyright 2000, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "speed.h"
+
+
+/* Like the standard version in gmp-impl.h, but with the expressions using a
+ "1-" form. This has the same number of steps, but "1-" is on the
+ dependent chain, whereas the "2*" in the standard version isn't.
+ Depending on the CPU this should be the same or a touch slower. */
+
+#if GMP_LIMB_BITS <= 32
+#define binvert_limb_mul1(inv,n) \
+ do { \
+ mp_limb_t __n = (n); \
+ mp_limb_t __inv; \
+ ASSERT ((__n & 1) == 1); \
+ __inv = binvert_limb_table[(__n&0xFF)/2]; /* 8 */ \
+ __inv = (1 - __n * __inv) * __inv + __inv; /* 16 */ \
+ __inv = (1 - __n * __inv) * __inv + __inv; /* 32 */ \
+ ASSERT (__inv * __n == 1); \
+ (inv) = __inv; \
+ } while (0)
+#endif
+
+#if GMP_LIMB_BITS > 32 && GMP_LIMB_BITS <= 64
+#define binvert_limb_mul1(inv,n) \
+ do { \
+ mp_limb_t __n = (n); \
+ mp_limb_t __inv; \
+ ASSERT ((__n & 1) == 1); \
+ __inv = binvert_limb_table[(__n&0xFF)/2]; /* 8 */ \
+ __inv = (1 - __n * __inv) * __inv + __inv; /* 16 */ \
+ __inv = (1 - __n * __inv) * __inv + __inv; /* 32 */ \
+ __inv = (1 - __n * __inv) * __inv + __inv; /* 64 */ \
+ ASSERT (__inv * __n == 1); \
+ (inv) = __inv; \
+ } while (0)
+#endif
+
+
+/* The loop based version used in GMP 3.0 and earlier. Usually slower than
+ multiplying, due to the number of steps that must be performed. Much
+ slower when the processor has a good multiply. */
+
+#define binvert_limb_loop(inv,n) \
+ do { \
+ mp_limb_t __v = (n); \
+ mp_limb_t __v_orig = __v; \
+ mp_limb_t __make_zero = 1; \
+ mp_limb_t __two_i = 1; \
+ mp_limb_t __v_inv = 0; \
+ \
+ ASSERT ((__v & 1) == 1); \
+ \
+ do \
+ { \
+ while ((__two_i & __make_zero) == 0) \
+ __two_i <<= 1, __v <<= 1; \
+ __v_inv += __two_i; \
+ __make_zero -= __v; \
+ } \
+ while (__make_zero); \
+ \
+ ASSERT (__v_orig * __v_inv == 1); \
+ (inv) = __v_inv; \
+ } while (0)
+
+
+/* Another loop based version with conditionals, but doing a fixed number of
+ steps. */
+
+#define binvert_limb_cond(inv,n) \
+ do { \
+ mp_limb_t __n = (n); \
+ mp_limb_t __rem = (1 - __n) >> 1; \
+ mp_limb_t __inv = GMP_LIMB_HIGHBIT; \
+ int __count; \
+ \
+ ASSERT ((__n & 1) == 1); \
+ \
+ __count = GMP_LIMB_BITS-1; \
+ do \
+ { \
+ __inv >>= 1; \
+ if (__rem & 1) \
+ { \
+ __inv |= GMP_LIMB_HIGHBIT; \
+ __rem -= __n; \
+ } \
+ __rem >>= 1; \
+ } \
+ while (-- __count); \
+ \
+ ASSERT (__inv * __n == 1); \
+ (inv) = __inv; \
+ } while (0)
+
+
+/* Another loop based bitwise version, but purely arithmetic, no
+ conditionals. */
+
+#define binvert_limb_arith(inv,n) \
+ do { \
+ mp_limb_t __n = (n); \
+ mp_limb_t __rem = (1 - __n) >> 1; \
+ mp_limb_t __inv = GMP_LIMB_HIGHBIT; \
+ mp_limb_t __lowbit; \
+ int __count; \
+ \
+ ASSERT ((__n & 1) == 1); \
+ \
+ __count = GMP_LIMB_BITS-1; \
+ do \
+ { \
+ __lowbit = __rem & 1; \
+ __inv = (__inv >> 1) | (__lowbit << (GMP_LIMB_BITS-1)); \
+ __rem = (__rem - (__n & -__lowbit)) >> 1; \
+ } \
+ while (-- __count); \
+ \
+ ASSERT (__inv * __n == 1); \
+ (inv) = __inv; \
+ } while (0)
+
+
+double
+speed_binvert_limb_mul1 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MODLIMB_INVERT (binvert_limb_mul1);
+}
+double
+speed_binvert_limb_loop (struct speed_params *s)
+{
+ SPEED_ROUTINE_MODLIMB_INVERT (binvert_limb_loop);
+}
+double
+speed_binvert_limb_cond (struct speed_params *s)
+{
+ SPEED_ROUTINE_MODLIMB_INVERT (binvert_limb_cond);
+}
+double
+speed_binvert_limb_arith (struct speed_params *s)
+{
+ SPEED_ROUTINE_MODLIMB_INVERT (binvert_limb_arith);
+}
diff --git a/gmp/tune/noop.c b/gmp/tune/noop.c
new file mode 100644
index 0000000000..5c13c96ee3
--- /dev/null
+++ b/gmp/tune/noop.c
@@ -0,0 +1,68 @@
+/* Noop routines.
+
+ These are in a separate file to stop gcc recognising do-nothing functions
+ and optimizing away calls to them. */
+
+/*
+Copyright 1999, 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#include "speed.h"
+
+
+void
+noop (void)
+{
+}
+
+/*ARGSUSED*/
+void
+noop_1 (mp_limb_t n)
+{
+}
+
+/*ARGSUSED*/
+void
+noop_wxs (mp_ptr wp, mp_srcptr xp, mp_size_t size)
+{
+}
+
+/*ARGSUSED*/
+void
+noop_wxys (mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size)
+{
+}
+
+/*ARGSUSED*/
+void
+mpn_cache_fill_dummy (mp_limb_t n)
+{
+}
diff --git a/gmp/tune/pentium.asm b/gmp/tune/pentium.asm
new file mode 100644
index 0000000000..fb1e8332c8
--- /dev/null
+++ b/gmp/tune/pentium.asm
@@ -0,0 +1,60 @@
+dnl x86 pentium time stamp counter access routine.
+
+dnl Copyright 1999, 2000, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+
+C void speed_cyclecounter (unsigned p[2]);
+C
+C Get the pentium rdtsc cycle counter, storing the least significant word in
+C p[0] and the most significant in p[1].
+C
+C cpuid is used to serialize execution. On big measurements this won't be
+C significant but it may help make small single measurements more accurate.
+
+ .text
+ ALIGN(8)
+
+defframe(PARAM_P,4)
+
+PROLOGUE(speed_cyclecounter)
+deflit(`FRAME',0)
+ pushl %ebx
+FRAME_pushl()
+ xorl %eax, %eax
+ cpuid
+ rdtsc
+ movl PARAM_P, %ebx
+ movl %eax, (%ebx)
+ movl %edx, 4(%ebx)
+ popl %ebx
+ ret
+EPILOGUE()
diff --git a/gmp/tune/powerpc.asm b/gmp/tune/powerpc.asm
new file mode 100644
index 0000000000..2f4ac27bea
--- /dev/null
+++ b/gmp/tune/powerpc.asm
@@ -0,0 +1,53 @@
+dnl PowerPC mftb_function -- read time base registers.
+
+dnl Copyright 2002 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C void mftb_function (unsigned a[2]);
+C
+
+ASM_START()
+PROLOGUE(mftb_function)
+
+ C r3 a
+
+L(again):
+ mftbu r4
+ mftb r5
+ mftbu r6
+ cmpw cr0, r4, r6
+ bne L(again)
+
+ stw r5, 0(r3)
+ stw r4, 4(r3)
+ blr
+
+EPILOGUE()
diff --git a/gmp/tune/powerpc64.asm b/gmp/tune/powerpc64.asm
new file mode 100644
index 0000000000..1ade99638a
--- /dev/null
+++ b/gmp/tune/powerpc64.asm
@@ -0,0 +1,49 @@
+dnl PowerPC mftb_function -- read time base registers, 64-bit integer.
+
+dnl Copyright 2002-2004 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C void mftb_function (unsigned a[2]);
+C
+
+ASM_START()
+PROLOGUE(mftb_function)
+
+ C r3 a
+
+ mftb r5
+
+ srdi r4, r5, 32
+ stw r5, 0(r3)
+ stw r4, 4(r3)
+ blr
+
+EPILOGUE()
diff --git a/gmp/tune/powm_mod.c b/gmp/tune/powm_mod.c
new file mode 100644
index 0000000000..7c20f53e70
--- /dev/null
+++ b/gmp/tune/powm_mod.c
@@ -0,0 +1,39 @@
+/* mpz/powm.c forced to use division. */
+
+/*
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef POWM_THRESHOLD
+#define POWM_THRESHOLD 1
+#define __gmpz_powm mpz_powm_mod
+
+#include "../mpz/powm.c"
diff --git a/gmp/tune/powm_redc.c b/gmp/tune/powm_redc.c
new file mode 100644
index 0000000000..c34bb2e0a5
--- /dev/null
+++ b/gmp/tune/powm_redc.c
@@ -0,0 +1,41 @@
+/* mpz/powm.c forced to use REDC. */
+
+/*
+Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* WANT_GLOBAL_REDC makes redc() available for speed and tune program use. */
+#undef POWM_THRESHOLD
+#define POWM_THRESHOLD MP_SIZE_T_MAX
+#define WANT_REDC_GLOBAL 1
+#define __gmpz_powm mpz_powm_redc
+
+#include "../mpz/powm.c"
diff --git a/gmp/tune/pre_divrem_1.c b/gmp/tune/pre_divrem_1.c
new file mode 100644
index 0000000000..388ca4150a
--- /dev/null
+++ b/gmp/tune/pre_divrem_1.c
@@ -0,0 +1,41 @@
+/* mpn_preinv_divrem_1 -- if not already in libgmp.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if ! USE_PREINV_DIVREM_1
+
+#undef USE_PREINV_DIVREM_1
+#define USE_PREINV_DIVREM_1 1
+
+#include "mpn/generic/pre_divrem_1.c"
+
+#endif
diff --git a/gmp/tune/set_strb.c b/gmp/tune/set_strb.c
new file mode 100644
index 0000000000..842ec4cd44
--- /dev/null
+++ b/gmp/tune/set_strb.c
@@ -0,0 +1,48 @@
+/* mpn_set_str_basecase -- mpn_set_str forced to its basecase.
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __gmpn_set_str mpn_set_str_basecase
+#define __gmpn_bc_set_str mpn_bc_set_str_basecase
+#define __gmpn_dc_set_str mpn_dc_set_str_basecase
+#define __gmpn_set_str_compute_powtab mpn_set_str_compute_powtab_basecase
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef SIZE_T_MAX
+#define SIZE_T_MAX ((size_t) ULONG_MAX)
+#endif
+
+#undef SET_STR_DC_THRESHOLD
+#define SET_STR_DC_THRESHOLD SIZE_T_MAX /* always */
+#undef SET_STR_PRECOMPUTE_THRESHOLD
+#define SET_STR_PRECOMPUTE_THRESHOLD SIZE_T_MAX /* always */
+
+#include "mpn/generic/set_str.c"
diff --git a/gmp/tune/set_strp.c b/gmp/tune/set_strp.c
new file mode 100644
index 0000000000..5520f28696
--- /dev/null
+++ b/gmp/tune/set_strp.c
@@ -0,0 +1,43 @@
+/* mpn_set_str_subquad -- mpn_set_str forced to the sub-quadratic case.
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define TUNE_PROGRAM_BUILD 1 /* for gmp-impl.h */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_pre_set_str (mp_ptr wp, unsigned char *str, size_t str_len, powers_t *powtab, mp_ptr tp)
+{
+ if (BELOW_THRESHOLD (str_len, set_str_dc_threshold))
+ mpn_bc_set_str (wp, str, str_len, powtab->base);
+ else
+ mpn_dc_set_str (wp, str, str_len, powtab, tp);
+}
diff --git a/gmp/tune/set_strs.c b/gmp/tune/set_strs.c
new file mode 100644
index 0000000000..75b6f39b4d
--- /dev/null
+++ b/gmp/tune/set_strs.c
@@ -0,0 +1,44 @@
+/* mpn_set_str_subquad -- mpn_set_str forced to the sub-quadratic case.
+
+Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define __gmpn_set_str mpn_set_str_subquad
+#define __gmpn_bc_set_str mpn_bc_set_str_subquad
+#define __gmpn_dc_set_str mpn_dc_set_str_subquad
+#define __gmpn_set_str_compute_powtab mpn_set_str_compute_powtab_subquad
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#undef SET_STR_DC_THRESHOLD
+#define SET_STR_DC_THRESHOLD 2 /* never */
+#undef SET_STR_PRECOMPUTE_THRESHOLD
+#define SET_STR_PRECOMPUTE_THRESHOLD 2 /* never */
+
+#include "mpn/generic/set_str.c"
diff --git a/gmp/tune/sparcv9.asm b/gmp/tune/sparcv9.asm
new file mode 100644
index 0000000000..f0981c70fe
--- /dev/null
+++ b/gmp/tune/sparcv9.asm
@@ -0,0 +1,45 @@
+dnl Sparc v9 32-bit time stamp counter access routine.
+
+dnl Copyright 2000, 2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+include(`../config.m4')
+
+
+C void speed_cyclecounter (unsigned p[2]);
+C
+C Get the sparc v9 tick counter.
+
+ASM_START()
+PROLOGUE(speed_cyclecounter)
+ rd %tick,%g1
+ st %g1,[%o0] C low 32 bits
+ srlx %g1,32,%g4
+ retl
+ st %g4,[%o0+4] C high 32 bits
+EPILOGUE(speed_cyclecounter)
diff --git a/gmp/tune/speed-ext.c b/gmp/tune/speed-ext.c
new file mode 100644
index 0000000000..e7fb8b9f60
--- /dev/null
+++ b/gmp/tune/speed-ext.c
@@ -0,0 +1,233 @@
+/* An example of extending the speed program to measure routines not in GMP.
+
+Copyright 1999, 2000, 2002, 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* The extension here is three versions of an mpn arithmetic mean. These
+ aren't meant to be particularly useful, just examples.
+
+ You can run something like the following to compare their speeds.
+
+ ./speed-ext -s 1-20 -c mean_calls mean_open mean_open2
+
+ On RISC chips, mean_open() might be fastest if the compiler is doing a
+ good job. On the register starved x86s, mean_calls will be fastest.
+
+
+ Notes:
+
+ SPEED_EXTRA_PROTOS and SPEED_EXTRA_ROUTINES are macros that get expanded
+ by speed.c in useful places. SPEED_EXTRA_PROTOS goes after the header
+ files, and SPEED_EXTRA_ROUTINES goes in the array of available routines.
+
+ The advantage of this #include "speed.c" scheme is that there's no
+ editing of a copy of that file, and new features in new versions of it
+ will be immediately available.
+
+ In a real program the routines mean_calls() etc would probably be in
+ separate C or assembler source files, and just the measuring
+ speed_mean_calls() etc would be here. Linking against other libraries
+ for things to measure is perfectly possible too.
+
+ When attempting to compare two versions of the same named routine, say
+ like the generic and assembler versions of mpn_add_n(), creative use of
+ cc -D or #define is suggested, so one or both can be renamed and linked
+ into the same program. It'll be much easier to compare them side by side
+ than with separate programs for each.
+
+ common.c has notes on writing speed measuring routines.
+
+ Remember to link against tune/libspeed.la (or tune/.libs/libspeed.a if
+ not using libtool) to get common.o and other objects needed by speed.c. */
+
+
+#define SPEED_EXTRA_PROTOS \
+ double speed_mean_calls (struct speed_params *s); \
+ double speed_mean_open (struct speed_params *s); \
+ double speed_mean_open2 (struct speed_params *s);
+
+#define SPEED_EXTRA_ROUTINES \
+ { "mean_calls", speed_mean_calls }, \
+ { "mean_open", speed_mean_open }, \
+ { "mean_open2", speed_mean_open2 },
+
+#include "speed.c"
+
+
+/* A straightforward implementation calling mpn subroutines.
+
+ wp,size is set to (xp,size + yp,size) / 2. The return value is the
+ remainder from the division. The other versions are the same. */
+
+mp_limb_t
+mean_calls (mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size)
+{
+ mp_limb_t c, ret;
+
+ ASSERT (size >= 1);
+
+ c = mpn_add_n (wp, xp, yp, size);
+ ret = mpn_rshift (wp, wp, size, 1) >> (GMP_LIMB_BITS-1);
+ wp[size-1] |= (c << (GMP_LIMB_BITS-1));
+ return ret;
+}
+
+
+/* An open-coded version, making one pass over the data. The right shift is
+ done as the added limbs are produced. The addition code follows
+ mpn/generic/add_n.c. */
+
+mp_limb_t
+mean_open (mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size)
+{
+ mp_limb_t w, wprev, x, y, c, ret;
+ mp_size_t i;
+
+ ASSERT (size >= 1);
+
+ x = xp[0];
+ y = yp[0];
+
+ wprev = x + y;
+ c = (wprev < x);
+ ret = (wprev & 1);
+
+#define RSHIFT(hi,lo) (((lo) >> 1) | ((hi) << (GMP_LIMB_BITS-1)))
+
+ for (i = 1; i < size; i++)
+ {
+ x = xp[i];
+ y = yp[i];
+
+ w = x + c;
+ c = (w < x);
+ w += y;
+ c += (w < y);
+
+ wp[i-1] = RSHIFT (w, wprev);
+ wprev = w;
+ }
+
+ wp[i-1] = RSHIFT (c, wprev);
+
+ return ret;
+}
+
+
+/* Another one-pass version, but right shifting the source limbs rather than
+ the result limbs. There's not much chance of this being better than the
+ above, but it's an alternative at least. */
+
+mp_limb_t
+mean_open2 (mp_ptr wp, mp_srcptr xp, mp_srcptr yp, mp_size_t size)
+{
+ mp_limb_t w, x, y, xnext, ynext, c, ret;
+ mp_size_t i;
+
+ ASSERT (size >= 1);
+
+ x = xp[0];
+ y = yp[0];
+
+ /* ret is the low bit of x+y, c is the carry out of that low bit add */
+ ret = (x ^ y) & 1;
+ c = (x & y) & 1;
+
+ for (i = 0; i < size-1; i++)
+ {
+ xnext = xp[i+1];
+ ynext = yp[i+1];
+ x = RSHIFT (xnext, x);
+ y = RSHIFT (ynext, y);
+
+ w = x + c;
+ c = (w < x);
+ w += y;
+ c += (w < y);
+ wp[i] = w;
+
+ x = xnext;
+ y = ynext;
+ }
+
+ wp[i] = (x >> 1) + (y >> 1) + c;
+
+ return ret;
+}
+
+
+/* The speed measuring routines are the same apart from which function they
+ run, so a macro is used. Actually this macro is the same as
+ SPEED_ROUTINE_MPN_BINARY_N. */
+
+#define SPEED_ROUTINE_MEAN(mean_fun) \
+ { \
+ unsigned i; \
+ mp_ptr wp; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ mean_fun (wp, s->xp, s->yp, s->size); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+double
+speed_mean_calls (struct speed_params *s)
+{
+ SPEED_ROUTINE_MEAN (mean_calls);
+}
+
+double
+speed_mean_open (struct speed_params *s)
+{
+ SPEED_ROUTINE_MEAN (mean_open);
+}
+
+double
+speed_mean_open2 (struct speed_params *s)
+{
+ SPEED_ROUTINE_MEAN (mean_open2);
+}
diff --git a/gmp/tune/speed.c b/gmp/tune/speed.c
new file mode 100644
index 0000000000..12d53bcaa3
--- /dev/null
+++ b/gmp/tune/speed.c
@@ -0,0 +1,1384 @@
+/* Speed measuring program.
+
+Copyright 1999-2003, 2005, 2006, 2008-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+/* Usage message is in the code below, run with no arguments to print it.
+ See README for interesting applications.
+
+ To add a new routine foo(), create a speed_foo() function in the style of
+ the existing ones and add an entry in the routine[] array. Put FLAG_R if
+ speed_foo() wants an "r" parameter.
+
+ The routines don't have help messages or descriptions, but most have
+ suggestive names. See the source code for full details.
+
+*/
+
+#include "config.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for getpid, R_OK */
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h> /* for struct timeval */
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h> /* for getrusage() */
+#endif
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h" /* for the benefit of speed-many.c */
+#include "tests.h"
+#include "speed.h"
+
+
+#if !HAVE_DECL_OPTARG
+extern char *optarg;
+extern int optind, opterr;
+#endif
+
+#if !HAVE_STRTOUL
+#define strtoul(p,e,b) (unsigned long) strtol(p,e,b)
+#endif
+
+#ifdef SPEED_EXTRA_PROTOS
+SPEED_EXTRA_PROTOS
+#endif
+#ifdef SPEED_EXTRA_PROTOS2
+SPEED_EXTRA_PROTOS2
+#endif
+
+
+#define MPN_FILL(ptr, size, n) \
+ do { \
+ mp_size_t __i; \
+ ASSERT ((size) >= 0); \
+ for (__i = 0; __i < (size); __i++) \
+ (ptr)[__i] = (n); \
+ } while (0)
+
+
+#if GMP_LIMB_BITS == 32
+#define GMP_NUMB_0xAA (CNST_LIMB(0xAAAAAAAA) & GMP_NUMB_MASK)
+#endif
+#if GMP_LIMB_BITS == 64
+#define GMP_NUMB_0xAA (CNST_LIMB(0xAAAAAAAAAAAAAAAA) & GMP_NUMB_MASK)
+#endif
+
+
+#define CMP_ABSOLUTE 1
+#define CMP_RATIO 2
+#define CMP_DIFFERENCE 3
+#define CMP_DIFFPREV 4
+int option_cmp = CMP_ABSOLUTE;
+
+#define UNIT_SECONDS 1
+#define UNIT_CYCLES 2
+#define UNIT_CYCLESPERLIMB 3
+int option_unit = UNIT_SECONDS;
+
+#define DATA_RANDOM 1
+#define DATA_RANDOM2 2
+#define DATA_ZEROS 3
+#define DATA_AAS 4
+#define DATA_FFS 5
+#define DATA_2FD 6
+int option_data = DATA_RANDOM;
+
+int option_square = 0;
+double option_factor = 0.0;
+mp_size_t option_step = 1;
+int option_gnuplot = 0;
+char *option_gnuplot_basename;
+struct size_array_t {
+ mp_size_t start, end;
+} *size_array = NULL;
+mp_size_t size_num = 0;
+mp_size_t size_allocnum = 0;
+int option_resource_usage = 0;
+long option_seed = 123456789;
+
+struct speed_params sp;
+
+#define COLUMN_WIDTH 13 /* for the free-form output */
+
+#define FLAG_R (1<<0) /* require ".r" */
+#define FLAG_R_OPTIONAL (1<<1) /* optional ".r" */
+#define FLAG_RSIZE (1<<2)
+#define FLAG_NODATA (1<<3) /* don't alloc xp, yp */
+
+const struct routine_t {
+ /* constants */
+ const char *name;
+ speed_function_t fun;
+ int flag;
+} routine[] = {
+
+ { "noop", speed_noop },
+ { "noop_wxs", speed_noop_wxs },
+ { "noop_wxys", speed_noop_wxys },
+
+ { "mpn_add_n", speed_mpn_add_n, FLAG_R_OPTIONAL },
+ { "mpn_sub_n", speed_mpn_sub_n, FLAG_R_OPTIONAL },
+
+ { "mpn_add_err1_n", speed_mpn_add_err1_n },
+ { "mpn_add_err2_n", speed_mpn_add_err2_n },
+ { "mpn_add_err3_n", speed_mpn_add_err3_n },
+ { "mpn_sub_err1_n", speed_mpn_sub_err1_n },
+ { "mpn_sub_err2_n", speed_mpn_sub_err2_n },
+ { "mpn_sub_err3_n", speed_mpn_sub_err3_n },
+
+#if HAVE_NATIVE_mpn_add_n_sub_n
+ { "mpn_add_n_sub_n", speed_mpn_add_n_sub_n, FLAG_R_OPTIONAL },
+#endif
+
+ { "mpn_addmul_1", speed_mpn_addmul_1, FLAG_R },
+ { "mpn_submul_1", speed_mpn_submul_1, FLAG_R },
+#if HAVE_NATIVE_mpn_addmul_2
+ { "mpn_addmul_2", speed_mpn_addmul_2, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addmul_3
+ { "mpn_addmul_3", speed_mpn_addmul_3, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addmul_4
+ { "mpn_addmul_4", speed_mpn_addmul_4, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addmul_5
+ { "mpn_addmul_5", speed_mpn_addmul_5, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addmul_6
+ { "mpn_addmul_6", speed_mpn_addmul_6, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addmul_7
+ { "mpn_addmul_7", speed_mpn_addmul_7, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addmul_8
+ { "mpn_addmul_8", speed_mpn_addmul_8, FLAG_R_OPTIONAL },
+#endif
+ { "mpn_mul_1", speed_mpn_mul_1, FLAG_R },
+ { "mpn_mul_1_inplace", speed_mpn_mul_1_inplace, FLAG_R },
+#if HAVE_NATIVE_mpn_mul_2
+ { "mpn_mul_2", speed_mpn_mul_2, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_mul_3
+ { "mpn_mul_3", speed_mpn_mul_3, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_mul_4
+ { "mpn_mul_4", speed_mpn_mul_4, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_mul_5
+ { "mpn_mul_5", speed_mpn_mul_5, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_mul_6
+ { "mpn_mul_6", speed_mpn_mul_6, FLAG_R_OPTIONAL },
+#endif
+
+ { "mpn_divrem_1", speed_mpn_divrem_1, FLAG_R },
+ { "mpn_divrem_1f", speed_mpn_divrem_1f, FLAG_R },
+#if HAVE_NATIVE_mpn_divrem_1c
+ { "mpn_divrem_1c", speed_mpn_divrem_1c, FLAG_R },
+ { "mpn_divrem_1cf", speed_mpn_divrem_1cf,FLAG_R },
+#endif
+ { "mpn_mod_1", speed_mpn_mod_1, FLAG_R },
+#if HAVE_NATIVE_mpn_mod_1c
+ { "mpn_mod_1c", speed_mpn_mod_1c, FLAG_R },
+#endif
+ { "mpn_preinv_divrem_1", speed_mpn_preinv_divrem_1, FLAG_R },
+ { "mpn_preinv_divrem_1f", speed_mpn_preinv_divrem_1f, FLAG_R },
+ { "mpn_preinv_mod_1", speed_mpn_preinv_mod_1, FLAG_R },
+
+ { "mpn_mod_1_1", speed_mpn_mod_1_1, FLAG_R },
+ { "mpn_mod_1_1_1", speed_mpn_mod_1_1_1, FLAG_R },
+ { "mpn_mod_1_1_2", speed_mpn_mod_1_1_2, FLAG_R },
+ { "mpn_mod_1s_2", speed_mpn_mod_1_2, FLAG_R },
+ { "mpn_mod_1s_3", speed_mpn_mod_1_3, FLAG_R },
+ { "mpn_mod_1s_4", speed_mpn_mod_1_4, FLAG_R },
+
+ { "mpn_divrem_1_div", speed_mpn_divrem_1_div, FLAG_R },
+ { "mpn_divrem_1_inv", speed_mpn_divrem_1_inv, FLAG_R },
+ { "mpn_divrem_1f_div", speed_mpn_divrem_1f_div, FLAG_R },
+ { "mpn_divrem_1f_inv", speed_mpn_divrem_1f_inv, FLAG_R },
+ { "mpn_mod_1_div", speed_mpn_mod_1_div, FLAG_R },
+ { "mpn_mod_1_inv", speed_mpn_mod_1_inv, FLAG_R },
+
+ { "mpn_divrem_2", speed_mpn_divrem_2, },
+ { "mpn_divrem_2_div", speed_mpn_divrem_2_div, },
+ { "mpn_divrem_2_inv", speed_mpn_divrem_2_inv, },
+
+ { "mpn_div_qr_1n_pi1", speed_mpn_div_qr_1n_pi1, FLAG_R },
+ { "mpn_div_qr_1n_pi1_1",speed_mpn_div_qr_1n_pi1_1, FLAG_R },
+ { "mpn_div_qr_1n_pi1_2",speed_mpn_div_qr_1n_pi1_2, FLAG_R },
+ { "mpn_div_qr_1", speed_mpn_div_qr_1, FLAG_R },
+
+ { "mpn_div_qr_2n", speed_mpn_div_qr_2n, },
+ { "mpn_div_qr_2u", speed_mpn_div_qr_2u, },
+
+ { "mpn_divexact_1", speed_mpn_divexact_1, FLAG_R },
+ { "mpn_divexact_by3", speed_mpn_divexact_by3 },
+
+ { "mpn_bdiv_q_1", speed_mpn_bdiv_q_1, FLAG_R },
+ { "mpn_pi1_bdiv_q_1", speed_mpn_pi1_bdiv_q_1, FLAG_R_OPTIONAL },
+ { "mpn_bdiv_dbm1c", speed_mpn_bdiv_dbm1c, FLAG_R_OPTIONAL },
+
+#if HAVE_NATIVE_mpn_modexact_1_odd
+ { "mpn_modexact_1_odd", speed_mpn_modexact_1_odd, FLAG_R },
+#endif
+ { "mpn_modexact_1c_odd", speed_mpn_modexact_1c_odd, FLAG_R },
+
+#if GMP_NUMB_BITS % 4 == 0
+ { "mpn_mod_34lsub1", speed_mpn_mod_34lsub1 },
+#endif
+
+ { "mpn_lshift", speed_mpn_lshift, FLAG_R },
+ { "mpn_lshiftc", speed_mpn_lshiftc, FLAG_R },
+ { "mpn_rshift", speed_mpn_rshift, FLAG_R },
+
+ { "mpn_and_n", speed_mpn_and_n, FLAG_R_OPTIONAL },
+ { "mpn_andn_n", speed_mpn_andn_n, FLAG_R_OPTIONAL },
+ { "mpn_nand_n", speed_mpn_nand_n, FLAG_R_OPTIONAL },
+ { "mpn_ior_n", speed_mpn_ior_n, FLAG_R_OPTIONAL },
+ { "mpn_iorn_n", speed_mpn_iorn_n, FLAG_R_OPTIONAL },
+ { "mpn_nior_n", speed_mpn_nior_n, FLAG_R_OPTIONAL },
+ { "mpn_xor_n", speed_mpn_xor_n, FLAG_R_OPTIONAL },
+ { "mpn_xnor_n", speed_mpn_xnor_n, FLAG_R_OPTIONAL },
+ { "mpn_com", speed_mpn_com },
+
+ { "mpn_popcount", speed_mpn_popcount },
+ { "mpn_hamdist", speed_mpn_hamdist },
+
+ { "mpn_matrix22_mul", speed_mpn_matrix22_mul },
+
+ { "mpn_hgcd", speed_mpn_hgcd },
+ { "mpn_hgcd_lehmer", speed_mpn_hgcd_lehmer },
+ { "mpn_hgcd_appr", speed_mpn_hgcd_appr },
+ { "mpn_hgcd_appr_lehmer", speed_mpn_hgcd_appr_lehmer },
+
+ { "mpn_hgcd_reduce", speed_mpn_hgcd_reduce },
+ { "mpn_hgcd_reduce_1", speed_mpn_hgcd_reduce_1 },
+ { "mpn_hgcd_reduce_2", speed_mpn_hgcd_reduce_2 },
+
+ { "mpn_gcd_1", speed_mpn_gcd_1, FLAG_R_OPTIONAL },
+ { "mpn_gcd_1N", speed_mpn_gcd_1N, FLAG_R_OPTIONAL },
+
+ { "mpn_gcd", speed_mpn_gcd },
+
+ { "mpn_gcdext", speed_mpn_gcdext },
+ { "mpn_gcdext_single", speed_mpn_gcdext_single },
+ { "mpn_gcdext_double", speed_mpn_gcdext_double },
+ { "mpn_gcdext_one_single", speed_mpn_gcdext_one_single },
+ { "mpn_gcdext_one_double", speed_mpn_gcdext_one_double },
+#if 0
+ { "mpn_gcdext_lehmer", speed_mpn_gcdext_lehmer },
+#endif
+ { "mpz_jacobi", speed_mpz_jacobi },
+ { "mpn_jacobi_base", speed_mpn_jacobi_base },
+ { "mpn_jacobi_base_1", speed_mpn_jacobi_base_1 },
+ { "mpn_jacobi_base_2", speed_mpn_jacobi_base_2 },
+ { "mpn_jacobi_base_3", speed_mpn_jacobi_base_3 },
+ { "mpn_jacobi_base_4", speed_mpn_jacobi_base_4 },
+
+ { "mpn_mul", speed_mpn_mul, FLAG_R_OPTIONAL },
+ { "mpn_mul_basecase", speed_mpn_mul_basecase,FLAG_R_OPTIONAL },
+ { "mpn_sqr_basecase", speed_mpn_sqr_basecase },
+#if HAVE_NATIVE_mpn_sqr_diagonal
+ { "mpn_sqr_diagonal", speed_mpn_sqr_diagonal },
+#endif
+#if HAVE_NATIVE_mpn_sqr_diag_addlsh1
+ { "mpn_sqr_diag_addlsh1", speed_mpn_sqr_diag_addlsh1 },
+#endif
+
+ { "mpn_mul_n", speed_mpn_mul_n },
+ { "mpn_sqr", speed_mpn_sqr },
+
+ { "mpn_toom2_sqr", speed_mpn_toom2_sqr },
+ { "mpn_toom3_sqr", speed_mpn_toom3_sqr },
+ { "mpn_toom4_sqr", speed_mpn_toom4_sqr },
+ { "mpn_toom6_sqr", speed_mpn_toom6_sqr },
+ { "mpn_toom8_sqr", speed_mpn_toom8_sqr },
+ { "mpn_toom22_mul", speed_mpn_toom22_mul },
+ { "mpn_toom33_mul", speed_mpn_toom33_mul },
+ { "mpn_toom44_mul", speed_mpn_toom44_mul },
+ { "mpn_toom6h_mul", speed_mpn_toom6h_mul },
+ { "mpn_toom8h_mul", speed_mpn_toom8h_mul },
+ { "mpn_toom32_mul", speed_mpn_toom32_mul },
+ { "mpn_toom42_mul", speed_mpn_toom42_mul },
+ { "mpn_toom43_mul", speed_mpn_toom43_mul },
+ { "mpn_toom63_mul", speed_mpn_toom63_mul },
+ { "mpn_nussbaumer_mul", speed_mpn_nussbaumer_mul },
+ { "mpn_nussbaumer_mul_sqr",speed_mpn_nussbaumer_mul_sqr},
+#if WANT_OLD_FFT_FULL
+ { "mpn_mul_fft_full", speed_mpn_mul_fft_full },
+ { "mpn_mul_fft_full_sqr", speed_mpn_mul_fft_full_sqr },
+#endif
+ { "mpn_mul_fft", speed_mpn_mul_fft, FLAG_R_OPTIONAL },
+ { "mpn_mul_fft_sqr", speed_mpn_mul_fft_sqr, FLAG_R_OPTIONAL },
+
+ { "mpn_mullo_n", speed_mpn_mullo_n },
+ { "mpn_mullo_basecase", speed_mpn_mullo_basecase },
+
+ { "mpn_mulmid_basecase", speed_mpn_mulmid_basecase, FLAG_R_OPTIONAL },
+ { "mpn_toom42_mulmid", speed_mpn_toom42_mulmid },
+ { "mpn_mulmid_n", speed_mpn_mulmid_n },
+ { "mpn_mulmid", speed_mpn_mulmid, FLAG_R_OPTIONAL },
+
+ { "mpn_bc_mulmod_bnm1", speed_mpn_bc_mulmod_bnm1 },
+ { "mpn_mulmod_bnm1", speed_mpn_mulmod_bnm1 },
+ { "mpn_mulmod_bnm1_rounded", speed_mpn_mulmod_bnm1_rounded },
+ { "mpn_sqrmod_bnm1", speed_mpn_sqrmod_bnm1 },
+
+ { "mpn_invert", speed_mpn_invert },
+ { "mpn_invertappr", speed_mpn_invertappr },
+ { "mpn_ni_invertappr", speed_mpn_ni_invertappr },
+ { "mpn_binvert", speed_mpn_binvert },
+ { "mpn_sec_invert", speed_mpn_sec_invert },
+
+ { "mpn_sbpi1_div_qr", speed_mpn_sbpi1_div_qr, FLAG_R_OPTIONAL},
+ { "mpn_dcpi1_div_qr", speed_mpn_dcpi1_div_qr, FLAG_R_OPTIONAL},
+ { "mpn_mu_div_qr", speed_mpn_mu_div_qr, FLAG_R_OPTIONAL},
+ { "mpn_mupi_div_qr", speed_mpn_mupi_div_qr, FLAG_R_OPTIONAL},
+ { "mpn_sbpi1_divappr_q", speed_mpn_sbpi1_divappr_q, FLAG_R_OPTIONAL},
+ { "mpn_dcpi1_divappr_q", speed_mpn_dcpi1_divappr_q, FLAG_R_OPTIONAL},
+
+ { "mpn_sbpi1_bdiv_qr", speed_mpn_sbpi1_bdiv_qr },
+ { "mpn_dcpi1_bdiv_qr", speed_mpn_dcpi1_bdiv_qr },
+ { "mpn_sbpi1_bdiv_q", speed_mpn_sbpi1_bdiv_q },
+ { "mpn_dcpi1_bdiv_q", speed_mpn_dcpi1_bdiv_q },
+
+ { "mpn_broot", speed_mpn_broot, FLAG_R },
+ { "mpn_broot_invm1", speed_mpn_broot_invm1, FLAG_R },
+ { "mpn_brootinv", speed_mpn_brootinv, FLAG_R },
+
+ { "mpn_get_str", speed_mpn_get_str, FLAG_R_OPTIONAL },
+ { "mpn_set_str", speed_mpn_set_str, FLAG_R_OPTIONAL },
+ { "mpn_set_str_basecase", speed_mpn_bc_set_str, FLAG_R_OPTIONAL },
+
+ { "mpn_sqrtrem", speed_mpn_sqrtrem },
+ { "mpn_rootrem", speed_mpn_rootrem, FLAG_R },
+
+ { "mpn_fib2_ui", speed_mpn_fib2_ui, FLAG_NODATA },
+ { "mpz_fib_ui", speed_mpz_fib_ui, FLAG_NODATA },
+ { "mpz_fib2_ui", speed_mpz_fib2_ui, FLAG_NODATA },
+ { "mpz_lucnum_ui", speed_mpz_lucnum_ui, FLAG_NODATA },
+ { "mpz_lucnum2_ui", speed_mpz_lucnum2_ui, FLAG_NODATA },
+
+ { "mpz_add", speed_mpz_add },
+ { "mpz_bin_uiui", speed_mpz_bin_uiui, FLAG_NODATA | FLAG_R_OPTIONAL },
+ { "mpz_bin_ui", speed_mpz_bin_ui, FLAG_NODATA | FLAG_R_OPTIONAL },
+ { "mpz_fac_ui", speed_mpz_fac_ui, FLAG_NODATA },
+ { "mpz_powm", speed_mpz_powm },
+ { "mpz_powm_mod", speed_mpz_powm_mod },
+ { "mpz_powm_redc", speed_mpz_powm_redc },
+ { "mpz_powm_sec", speed_mpz_powm_sec },
+ { "mpz_powm_ui", speed_mpz_powm_ui, FLAG_R_OPTIONAL },
+
+ { "mpz_mod", speed_mpz_mod },
+ { "mpn_redc_1", speed_mpn_redc_1 },
+ { "mpn_redc_2", speed_mpn_redc_2 },
+ { "mpn_redc_n", speed_mpn_redc_n },
+
+ { "MPN_COPY", speed_MPN_COPY },
+ { "MPN_COPY_INCR", speed_MPN_COPY_INCR },
+ { "MPN_COPY_DECR", speed_MPN_COPY_DECR },
+ { "memcpy", speed_memcpy },
+#if HAVE_NATIVE_mpn_copyi
+ { "mpn_copyi", speed_mpn_copyi },
+#endif
+#if HAVE_NATIVE_mpn_copyd
+ { "mpn_copyd", speed_mpn_copyd },
+#endif
+ { "mpn_sec_tabselect", speed_mpn_sec_tabselect, FLAG_R_OPTIONAL },
+#if HAVE_NATIVE_mpn_addlsh1_n == 1
+ { "mpn_addlsh1_n", speed_mpn_addlsh1_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_sublsh1_n == 1
+ { "mpn_sublsh1_n", speed_mpn_sublsh1_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addlsh1_n_ip1
+ { "mpn_addlsh1_n_ip1", speed_mpn_addlsh1_n_ip1 },
+#endif
+#if HAVE_NATIVE_mpn_addlsh1_n_ip2
+ { "mpn_addlsh1_n_ip2", speed_mpn_addlsh1_n_ip2 },
+#endif
+#if HAVE_NATIVE_mpn_sublsh1_n_ip1
+ { "mpn_sublsh1_n_ip1", speed_mpn_sublsh1_n_ip1 },
+#endif
+#if HAVE_NATIVE_mpn_rsblsh1_n == 1
+ { "mpn_rsblsh1_n", speed_mpn_rsblsh1_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n == 1
+ { "mpn_addlsh2_n", speed_mpn_addlsh2_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_sublsh2_n == 1
+ { "mpn_sublsh2_n", speed_mpn_sublsh2_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n_ip1
+ { "mpn_addlsh2_n_ip1", speed_mpn_addlsh2_n_ip1 },
+#endif
+#if HAVE_NATIVE_mpn_addlsh2_n_ip2
+ { "mpn_addlsh2_n_ip2", speed_mpn_addlsh2_n_ip2 },
+#endif
+#if HAVE_NATIVE_mpn_sublsh2_n_ip1
+ { "mpn_sublsh2_n_ip1", speed_mpn_sublsh2_n_ip1 },
+#endif
+#if HAVE_NATIVE_mpn_rsblsh2_n == 1
+ { "mpn_rsblsh2_n", speed_mpn_rsblsh2_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n
+ { "mpn_addlsh_n", speed_mpn_addlsh_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_sublsh_n
+ { "mpn_sublsh_n", speed_mpn_sublsh_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n_ip1
+ { "mpn_addlsh_n_ip1", speed_mpn_addlsh_n_ip1 },
+#endif
+#if HAVE_NATIVE_mpn_addlsh_n_ip2
+ { "mpn_addlsh_n_ip2", speed_mpn_addlsh_n_ip2 },
+#endif
+#if HAVE_NATIVE_mpn_sublsh_n_ip1
+ { "mpn_sublsh_n_ip1", speed_mpn_sublsh_n_ip1 },
+#endif
+#if HAVE_NATIVE_mpn_rsblsh_n
+ { "mpn_rsblsh_n", speed_mpn_rsblsh_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_rsh1add_n
+ { "mpn_rsh1add_n", speed_mpn_rsh1add_n, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_rsh1sub_n
+ { "mpn_rsh1sub_n", speed_mpn_rsh1sub_n, FLAG_R_OPTIONAL },
+#endif
+
+ { "mpn_cnd_add_n", speed_mpn_cnd_add_n, FLAG_R_OPTIONAL },
+ { "mpn_cnd_sub_n", speed_mpn_cnd_sub_n, FLAG_R_OPTIONAL },
+
+ { "MPN_ZERO", speed_MPN_ZERO },
+
+ { "binvert_limb", speed_binvert_limb, FLAG_NODATA },
+ { "binvert_limb_mul1", speed_binvert_limb_mul1, FLAG_NODATA },
+ { "binvert_limb_loop", speed_binvert_limb_loop, FLAG_NODATA },
+ { "binvert_limb_cond", speed_binvert_limb_cond, FLAG_NODATA },
+ { "binvert_limb_arith", speed_binvert_limb_arith, FLAG_NODATA },
+
+ { "malloc_free", speed_malloc_free },
+ { "malloc_realloc_free", speed_malloc_realloc_free },
+ { "gmp_allocate_free", speed_gmp_allocate_free },
+ { "gmp_allocate_reallocate_free", speed_gmp_allocate_reallocate_free },
+ { "mpz_init_clear", speed_mpz_init_clear },
+ { "mpq_init_clear", speed_mpq_init_clear },
+ { "mpf_init_clear", speed_mpf_init_clear },
+ { "mpz_init_realloc_clear", speed_mpz_init_realloc_clear },
+
+ { "umul_ppmm", speed_umul_ppmm, FLAG_R_OPTIONAL },
+#if HAVE_NATIVE_mpn_umul_ppmm
+ { "mpn_umul_ppmm", speed_mpn_umul_ppmm, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_umul_ppmm_r
+ { "mpn_umul_ppmm_r", speed_mpn_umul_ppmm_r, FLAG_R_OPTIONAL },
+#endif
+
+ { "count_leading_zeros", speed_count_leading_zeros, FLAG_NODATA | FLAG_R_OPTIONAL },
+ { "count_trailing_zeros", speed_count_trailing_zeros, FLAG_NODATA | FLAG_R_OPTIONAL },
+
+ { "udiv_qrnnd", speed_udiv_qrnnd, FLAG_R_OPTIONAL },
+ { "udiv_qrnnd_c", speed_udiv_qrnnd_c, FLAG_R_OPTIONAL },
+#if HAVE_NATIVE_mpn_udiv_qrnnd
+ { "mpn_udiv_qrnnd", speed_mpn_udiv_qrnnd, FLAG_R_OPTIONAL },
+#endif
+#if HAVE_NATIVE_mpn_udiv_qrnnd_r
+ { "mpn_udiv_qrnnd_r", speed_mpn_udiv_qrnnd_r, FLAG_R_OPTIONAL },
+#endif
+ { "invert_limb", speed_invert_limb, FLAG_R_OPTIONAL },
+
+ { "operator_div", speed_operator_div, FLAG_R_OPTIONAL },
+ { "operator_mod", speed_operator_mod, FLAG_R_OPTIONAL },
+
+ { "gmp_randseed", speed_gmp_randseed, FLAG_R_OPTIONAL },
+ { "gmp_randseed_ui", speed_gmp_randseed_ui, FLAG_R_OPTIONAL | FLAG_NODATA },
+ { "mpz_urandomb", speed_mpz_urandomb, FLAG_R_OPTIONAL | FLAG_NODATA },
+
+#ifdef SPEED_EXTRA_ROUTINES
+ SPEED_EXTRA_ROUTINES
+#endif
+#ifdef SPEED_EXTRA_ROUTINES2
+ SPEED_EXTRA_ROUTINES2
+#endif
+};
+
+
+struct choice_t {
+ const struct routine_t *p;
+ mp_limb_t r;
+ double scale;
+ double time;
+ int no_time;
+ double prev_time;
+ const char *name;
+};
+struct choice_t *choice;
+int num_choices = 0;
+
+
+void
+data_fill (mp_ptr ptr, mp_size_t size)
+{
+ switch (option_data) {
+ case DATA_RANDOM:
+ mpn_random (ptr, size);
+ break;
+ case DATA_RANDOM2:
+ mpn_random2 (ptr, size);
+ break;
+ case DATA_ZEROS:
+ MPN_ZERO (ptr, size);
+ break;
+ case DATA_AAS:
+ MPN_FILL (ptr, size, GMP_NUMB_0xAA);
+ break;
+ case DATA_FFS:
+ MPN_FILL (ptr, size, GMP_NUMB_MAX);
+ break;
+ case DATA_2FD:
+ MPN_FILL (ptr, size, GMP_NUMB_MAX);
+ ptr[0] -= 2;
+ break;
+ default:
+ abort();
+ /*NOTREACHED*/
+ }
+}
+
+/* The code here handling the various combinations of output options isn't
+ too attractive, but it works and is fairly clean. */
+
+#define SIZE_TO_DIVISOR(n) \
+ (option_square == 1 ? (n)*(n) \
+ : option_square == 2 ? (n)*((n)+1)/2 \
+ : (n))
+
+void
+run_one (FILE *fp, struct speed_params *s, mp_size_t prev_size)
+{
+ const char *first_open_fastest, *first_open_notfastest, *first_close;
+ int i, fastest, want_data;
+ double fastest_time;
+ TMP_DECL;
+
+ TMP_MARK;
+
+ /* allocate data, unless all routines are NODATA */
+ want_data = 0;
+ for (i = 0; i < num_choices; i++)
+ want_data |= ((choice[i].p->flag & FLAG_NODATA) == 0);
+
+ if (want_data)
+ {
+ SPEED_TMP_ALLOC_LIMBS (sp.xp, s->size, s->align_xp);
+ SPEED_TMP_ALLOC_LIMBS (sp.yp, s->size, s->align_yp);
+
+ data_fill (s->xp, s->size);
+ data_fill (s->yp, s->size);
+ }
+ else
+ {
+ sp.xp = NULL;
+ sp.yp = NULL;
+ }
+
+ if (prev_size == -1 && option_cmp == CMP_DIFFPREV)
+ {
+ first_open_fastest = "(#";
+ first_open_notfastest = " (";
+ first_close = ")";
+ }
+ else
+ {
+ first_open_fastest = "#";
+ first_open_notfastest = " ";
+ first_close = "";
+ }
+
+ fastest = -1;
+ fastest_time = -1.0;
+ for (i = 0; i < num_choices; i++)
+ {
+ s->r = choice[i].r;
+ choice[i].time = speed_measure (choice[i].p->fun, s);
+ choice[i].no_time = (choice[i].time == -1.0);
+ if (! choice[i].no_time)
+ choice[i].time *= choice[i].scale;
+
+ /* Apply the effect of CMP_DIFFPREV, but the new choice[i].prev_time
+ is before any differences. */
+ {
+ double t;
+ t = choice[i].time;
+ if (t != -1.0 && option_cmp == CMP_DIFFPREV && prev_size != -1)
+ {
+ if (choice[i].prev_time == -1.0)
+ choice[i].no_time = 1;
+ else
+ choice[i].time = choice[i].time - choice[i].prev_time;
+ }
+ choice[i].prev_time = t;
+ }
+
+ if (choice[i].no_time)
+ continue;
+
+ /* Look for the fastest after CMP_DIFFPREV has been applied, but
+ before CMP_RATIO or CMP_DIFFERENCE. There's only a fastest shown
+ if there's more than one routine. */
+ if (num_choices > 1 && (fastest == -1 || choice[i].time < fastest_time))
+ {
+ fastest = i;
+ fastest_time = choice[i].time;
+ }
+
+ if (option_cmp == CMP_DIFFPREV)
+ {
+ /* Conversion for UNIT_CYCLESPERLIMB differs in CMP_DIFFPREV. */
+ if (option_unit == UNIT_CYCLES)
+ choice[i].time /= speed_cycletime;
+ else if (option_unit == UNIT_CYCLESPERLIMB)
+ {
+ if (prev_size == -1)
+ choice[i].time /= speed_cycletime;
+ else
+ choice[i].time /= (speed_cycletime
+ * (SIZE_TO_DIVISOR(s->size)
+ - SIZE_TO_DIVISOR(prev_size)));
+ }
+ }
+ else
+ {
+ if (option_unit == UNIT_CYCLES)
+ choice[i].time /= speed_cycletime;
+ else if (option_unit == UNIT_CYCLESPERLIMB)
+ choice[i].time /= (speed_cycletime * SIZE_TO_DIVISOR(s->size));
+
+ if (option_cmp == CMP_RATIO && i > 0)
+ {
+ /* A ratio isn't affected by the units chosen. */
+ if (choice[0].no_time || choice[0].time == 0.0)
+ choice[i].no_time = 1;
+ else
+ choice[i].time /= choice[0].time;
+ }
+ else if (option_cmp == CMP_DIFFERENCE && i > 0)
+ {
+ if (choice[0].no_time)
+ {
+ choice[i].no_time = 1;
+ continue;
+ }
+ choice[i].time -= choice[0].time;
+ }
+ }
+ }
+
+ if (option_gnuplot)
+ {
+ /* In CMP_DIFFPREV, don't print anything for the first size, start
+ with the second where an actual difference is available.
+
+ In CMP_RATIO, print the first column as 1.0.
+
+ The 9 decimals printed is much more than the expected precision of
+ the measurements actually. */
+
+ if (! (option_cmp == CMP_DIFFPREV && prev_size == -1))
+ {
+ fprintf (fp, "%-6ld ", s->size);
+ for (i = 0; i < num_choices; i++)
+ fprintf (fp, " %.9e",
+ choice[i].no_time ? 0.0
+ : (option_cmp == CMP_RATIO && i == 0) ? 1.0
+ : choice[i].time);
+ fprintf (fp, "\n");
+ }
+ }
+ else
+ {
+ fprintf (fp, "%-6ld ", s->size);
+ for (i = 0; i < num_choices; i++)
+ {
+ char buf[128];
+ int decimals;
+
+ if (choice[i].no_time)
+ {
+ fprintf (fp, " %*s", COLUMN_WIDTH, "n/a");
+ }
+ else
+ {if (option_unit == UNIT_CYCLESPERLIMB
+ || (option_cmp == CMP_RATIO && i > 0))
+ decimals = 4;
+ else if (option_unit == UNIT_CYCLES)
+ decimals = 2;
+ else
+ decimals = 9;
+
+ sprintf (buf, "%s%.*f%s",
+ i == fastest ? first_open_fastest : first_open_notfastest,
+ decimals, choice[i].time, first_close);
+ fprintf (fp, " %*s", COLUMN_WIDTH, buf);
+ }
+ }
+ fprintf (fp, "\n");
+ }
+
+ TMP_FREE;
+}
+
+void
+run_all (FILE *fp)
+{
+ mp_size_t prev_size;
+ int i;
+ TMP_DECL;
+
+ TMP_MARK;
+ SPEED_TMP_ALLOC_LIMBS (sp.xp_block, SPEED_BLOCK_SIZE, sp.align_xp);
+ SPEED_TMP_ALLOC_LIMBS (sp.yp_block, SPEED_BLOCK_SIZE, sp.align_yp);
+
+ data_fill (sp.xp_block, SPEED_BLOCK_SIZE);
+ data_fill (sp.yp_block, SPEED_BLOCK_SIZE);
+
+ for (i = 0; i < size_num; i++)
+ {
+ sp.size = size_array[i].start;
+ prev_size = -1;
+ for (;;)
+ {
+ mp_size_t step;
+
+ if (option_data == DATA_2FD && sp.size >= 2)
+ sp.xp[sp.size-1] = 2;
+
+ run_one (fp, &sp, prev_size);
+ prev_size = sp.size;
+
+ if (option_data == DATA_2FD && sp.size >= 2)
+ sp.xp[sp.size-1] = MP_LIMB_T_MAX;
+
+ if (option_factor != 0.0)
+ {
+ step = (mp_size_t) (sp.size * option_factor - sp.size);
+ if (step < 1)
+ step = 1;
+ }
+ else
+ step = 1;
+ if (step < option_step)
+ step = option_step;
+
+ sp.size += step;
+ if (sp.size > size_array[i].end)
+ break;
+ }
+ }
+
+ TMP_FREE;
+}
+
+
+FILE *
+fopen_for_write (const char *filename)
+{
+ FILE *fp;
+ if ((fp = fopen (filename, "w")) == NULL)
+ {
+ fprintf (stderr, "Cannot create %s\n", filename);
+ exit(1);
+ }
+ return fp;
+}
+
+void
+fclose_written (FILE *fp, const char *filename)
+{
+ int err;
+
+ err = ferror (fp);
+ err |= fclose (fp);
+
+ if (err)
+ {
+ fprintf (stderr, "Error writing %s\n", filename);
+ exit(1);
+ }
+}
+
+
+void
+run_gnuplot (int argc, char *argv[])
+{
+ char *plot_filename;
+ char *data_filename;
+ FILE *fp;
+ int i;
+
+ plot_filename = (char *) (*__gmp_allocate_func)
+ (strlen (option_gnuplot_basename) + 20);
+ data_filename = (char *) (*__gmp_allocate_func)
+ (strlen (option_gnuplot_basename) + 20);
+
+ sprintf (plot_filename, "%s.gnuplot", option_gnuplot_basename);
+ sprintf (data_filename, "%s.data", option_gnuplot_basename);
+
+ fp = fopen_for_write (plot_filename);
+
+ fprintf (fp, "# Generated with:\n");
+ fprintf (fp, "#");
+ for (i = 0; i < argc; i++)
+ fprintf (fp, " %s", argv[i]);
+ fprintf (fp, "\n");
+ fprintf (fp, "\n");
+
+ fprintf (fp, "reset\n");
+
+ /* Putting the key at the top left is usually good, and you can change it
+ interactively if it's not. */
+ fprintf (fp, "set key left\n");
+
+ /* designed to make it possible to see crossovers easily */
+ fprintf (fp, "set style data lines\n");
+
+ fprintf (fp, "plot ");
+ for (i = 0; i < num_choices; i++)
+ {
+ fprintf (fp, " \"%s\" using 1:%d", data_filename, i+2);
+ fprintf (fp, " title \"%s\"", choice[i].name);
+
+ if (i != num_choices-1)
+ fprintf (fp, ", \\");
+ fprintf (fp, "\n");
+ }
+
+ fprintf (fp, "load \"-\"\n");
+ fclose_written (fp, plot_filename);
+
+ fp = fopen_for_write (data_filename);
+
+ /* Unbuffered so you can see where the program was up to if it crashes or
+ you kill it. */
+ setbuf (fp, NULL);
+
+ run_all (fp);
+ fclose_written (fp, data_filename);
+}
+
+
+/* Return a limb with n many one bits (starting from the least significant) */
+
+#define LIMB_ONES(n) \
+ ((n) == GMP_LIMB_BITS ? MP_LIMB_T_MAX \
+ : (n) == 0 ? CNST_LIMB(0) \
+ : (CNST_LIMB(1) << (n)) - 1)
+
+mp_limb_t
+r_string (const char *s)
+{
+ const char *s_orig = s;
+ long n;
+
+ if (strcmp (s, "aas") == 0)
+ return GMP_NUMB_0xAA;
+
+ {
+ mpz_t z;
+ mp_limb_t l;
+ int set, siz;
+
+ mpz_init (z);
+ set = mpz_set_str (z, s, 0);
+ siz = SIZ(z);
+ l = (siz == 0 ? 0 : siz > 0 ? PTR(z)[0] : -PTR(z)[0]);
+ mpz_clear (z);
+ if (set == 0)
+ {
+ if (siz > 1 || siz < -1)
+ printf ("Warning, r parameter %s truncated to %d bits\n",
+ s_orig, GMP_LIMB_BITS);
+ return l;
+ }
+ }
+
+ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
+ n = strtoul (s+2, (char **) &s, 16);
+ else
+ n = strtol (s, (char **) &s, 10);
+
+ if (strcmp (s, "bits") == 0)
+ {
+ mp_limb_t l;
+ if (n > GMP_LIMB_BITS)
+ {
+ fprintf (stderr, "%ld bit parameter invalid (max %d bits)\n",
+ n, GMP_LIMB_BITS);
+ exit (1);
+ }
+ mpn_random (&l, 1);
+ return (l | (CNST_LIMB(1) << (n-1))) & LIMB_ONES(n);
+ }
+ else if (strcmp (s, "ones") == 0)
+ {
+ if (n > GMP_LIMB_BITS)
+ {
+ fprintf (stderr, "%ld bit parameter invalid (max %d bits)\n",
+ n, GMP_LIMB_BITS);
+ exit (1);
+ }
+ return LIMB_ONES (n);
+ }
+ else if (*s != '\0')
+ {
+ fprintf (stderr, "invalid r parameter: %s\n", s_orig);
+ exit (1);
+ }
+
+ return n;
+}
+
+
+void
+routine_find (struct choice_t *c, const char *s_orig)
+{
+ const char *s;
+ int i;
+ size_t nlen;
+
+ c->name = s_orig;
+ s = strchr (s_orig, '*');
+ if (s != NULL)
+ {
+ c->scale = atof(s_orig);
+ s++;
+ }
+ else
+ {
+ c->scale = 1.0;
+ s = s_orig;
+ }
+
+ for (i = 0; i < numberof (routine); i++)
+ {
+ nlen = strlen (routine[i].name);
+ if (memcmp (s, routine[i].name, nlen) != 0)
+ continue;
+
+ if (s[nlen] == '.')
+ {
+ /* match, with a .r parameter */
+
+ if (! (routine[i].flag & (FLAG_R|FLAG_R_OPTIONAL)))
+ {
+ fprintf (stderr,
+ "Choice %s bad: doesn't take a \".<r>\" parameter\n",
+ s_orig);
+ exit (1);
+ }
+
+ c->p = &routine[i];
+ c->r = r_string (s + nlen + 1);
+ return;
+ }
+
+ if (s[nlen] == '\0')
+ {
+ /* match, with no parameter */
+
+ if (routine[i].flag & FLAG_R)
+ {
+ fprintf (stderr,
+ "Choice %s bad: needs a \".<r>\" parameter\n",
+ s_orig);
+ exit (1);
+ }
+
+ c->p = &routine[i];
+ c->r = 0;
+ return;
+ }
+ }
+
+ fprintf (stderr, "Choice %s unrecognised\n", s_orig);
+ exit (1);
+}
+
+
+void
+usage (void)
+{
+ int i;
+
+ speed_time_init ();
+
+ printf ("Usage: speed [-options] -s size <routine>...\n");
+ printf ("Measure the speed of some routines.\n");
+ printf ("Times are in seconds, accuracy is shown.\n");
+ printf ("\n");
+ printf (" -p num set precision as number of time units each routine must run\n");
+ printf (" -s size[-end][,size[-end]]... sizes to measure\n");
+ printf (" single sizes or ranges, sep with comma or use multiple -s\n");
+ printf (" -t step step through sizes by given amount\n");
+ printf (" -f factor step through sizes by given factor (eg. 1.05)\n");
+ printf (" -r show times as ratios of the first routine\n");
+ printf (" -d show times as difference from the first routine\n");
+ printf (" -D show times as difference from previous size shown\n");
+ printf (" -c show times in CPU cycles\n");
+ printf (" -C show times in cycles per limb\n");
+ printf (" -u print resource usage (memory) at end\n");
+ printf (" -P name output plot files \"name.gnuplot\" and \"name.data\"\n");
+ printf (" -a <type> use given data: random(default), random2, zeros, aas, ffs, 2fd\n");
+ printf (" -x, -y, -w, -W <align> specify data alignments, sources and dests\n");
+ printf (" -o addrs print addresses of data blocks\n");
+ printf ("\n");
+ printf ("If both -t and -f are used, it means step by the factor or the step, whichever\n");
+ printf ("is greater.\n");
+ printf ("If both -C and -D are used, it means cycles per however many limbs between a\n");
+ printf ("size and the previous size.\n");
+ printf ("\n");
+ printf ("After running with -P, plots can be viewed with Gnuplot or Quickplot.\n");
+ printf ("\"gnuplot name.gnuplot\" (use \"set logscale xy; replot\" at the prompt for\n");
+ printf ("a log/log plot).\n");
+ printf ("\"quickplot -s name.data\" (has interactive zooming, and note -s is important\n");
+ printf ("when viewing more than one routine, it means same axis scales for all data).\n");
+ printf ("\n");
+ printf ("The available routines are as follows.\n");
+ printf ("\n");
+
+ for (i = 0; i < numberof (routine); i++)
+ {
+ if (routine[i].flag & FLAG_R)
+ printf ("\t%s.r\n", routine[i].name);
+ else if (routine[i].flag & FLAG_R_OPTIONAL)
+ printf ("\t%s (optional .r)\n", routine[i].name);
+ else
+ printf ("\t%s\n", routine[i].name);
+ }
+ printf ("\n");
+ printf ("Routines with a \".r\" need an extra parameter, for example mpn_lshift.6\n");
+ printf ("r should be in decimal, or use 0xN for hexadecimal.\n");
+ printf ("\n");
+ printf ("Special forms for r are \"<N>bits\" for a random N bit number, \"<N>ones\" for\n");
+ printf ("N one bits, or \"aas\" for 0xAA..AA.\n");
+ printf ("\n");
+ printf ("Times for sizes out of the range accepted by a routine are shown as 0.\n");
+ printf ("The fastest routine at each size is marked with a # (free form output only).\n");
+ printf ("\n");
+ printf ("%s", speed_time_string);
+ printf ("\n");
+ printf ("Gnuplot home page http://www.gnuplot.info/\n");
+ printf ("Quickplot home page http://quickplot.sourceforge.net/\n");
+}
+
+void
+check_align_option (const char *name, mp_size_t align)
+{
+ if (align < 0 || align > SPEED_TMP_ALLOC_ADJUST_MASK)
+ {
+ fprintf (stderr, "Alignment request out of range: %s %ld\n",
+ name, (long) align);
+ fprintf (stderr, " should be 0 to %d (limbs), inclusive\n",
+ SPEED_TMP_ALLOC_ADJUST_MASK);
+ exit (1);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ int opt;
+
+ /* Unbuffered so output goes straight out when directed to a pipe or file
+ and isn't lost on killing the program half way. */
+ setbuf (stdout, NULL);
+
+ for (;;)
+ {
+ opt = getopt(argc, argv, "a:CcDdEFf:o:p:P:rRs:t:ux:y:w:W:z");
+ if (opt == EOF)
+ break;
+
+ switch (opt) {
+ case 'a':
+ if (strcmp (optarg, "random") == 0) option_data = DATA_RANDOM;
+ else if (strcmp (optarg, "random2") == 0) option_data = DATA_RANDOM2;
+ else if (strcmp (optarg, "zeros") == 0) option_data = DATA_ZEROS;
+ else if (strcmp (optarg, "aas") == 0) option_data = DATA_AAS;
+ else if (strcmp (optarg, "ffs") == 0) option_data = DATA_FFS;
+ else if (strcmp (optarg, "2fd") == 0) option_data = DATA_2FD;
+ else
+ {
+ fprintf (stderr, "unrecognised data option: %s\n", optarg);
+ exit (1);
+ }
+ break;
+ case 'C':
+ if (option_unit != UNIT_SECONDS) goto bad_unit;
+ option_unit = UNIT_CYCLESPERLIMB;
+ break;
+ case 'c':
+ if (option_unit != UNIT_SECONDS)
+ {
+ bad_unit:
+ fprintf (stderr, "cannot use more than one of -c, -C\n");
+ exit (1);
+ }
+ option_unit = UNIT_CYCLES;
+ break;
+ case 'D':
+ if (option_cmp != CMP_ABSOLUTE) goto bad_cmp;
+ option_cmp = CMP_DIFFPREV;
+ break;
+ case 'd':
+ if (option_cmp != CMP_ABSOLUTE)
+ {
+ bad_cmp:
+ fprintf (stderr, "cannot use more than one of -d, -D, -r\n");
+ exit (1);
+ }
+ option_cmp = CMP_DIFFERENCE;
+ break;
+ case 'E':
+ option_square = 1;
+ break;
+ case 'F':
+ option_square = 2;
+ break;
+ case 'f':
+ option_factor = atof (optarg);
+ if (option_factor <= 1.0)
+ {
+ fprintf (stderr, "-f factor must be > 1.0\n");
+ exit (1);
+ }
+ break;
+ case 'o':
+ speed_option_set (optarg);
+ break;
+ case 'P':
+ option_gnuplot = 1;
+ option_gnuplot_basename = optarg;
+ break;
+ case 'p':
+ speed_precision = atoi (optarg);
+ break;
+ case 'R':
+ option_seed = time (NULL);
+ break;
+ case 'r':
+ if (option_cmp != CMP_ABSOLUTE)
+ goto bad_cmp;
+ option_cmp = CMP_RATIO;
+ break;
+ case 's':
+ {
+ char *s;
+ for (s = strtok (optarg, ","); s != NULL; s = strtok (NULL, ","))
+ {
+ if (size_num == size_allocnum)
+ {
+ size_array = (struct size_array_t *)
+ __gmp_allocate_or_reallocate
+ (size_array,
+ size_allocnum * sizeof(size_array[0]),
+ (size_allocnum+10) * sizeof(size_array[0]));
+ size_allocnum += 10;
+ }
+ if (sscanf (s, "%ld-%ld",
+ &size_array[size_num].start,
+ &size_array[size_num].end) != 2)
+ {
+ size_array[size_num].start = size_array[size_num].end
+ = atol (s);
+ }
+
+ if (size_array[size_num].start < 0
+ || size_array[size_num].end < 0
+ || size_array[size_num].start > size_array[size_num].end)
+ {
+ fprintf (stderr, "invalid size parameter: %s\n", s);
+ exit (1);
+ }
+
+ size_num++;
+ }
+ }
+ break;
+ case 't':
+ option_step = atol (optarg);
+ if (option_step < 1)
+ {
+ fprintf (stderr, "-t step must be >= 1\n");
+ exit (1);
+ }
+ break;
+ case 'u':
+ option_resource_usage = 1;
+ break;
+ case 'z':
+ sp.cache = 1;
+ break;
+ case 'x':
+ sp.align_xp = atol (optarg);
+ check_align_option ("-x", sp.align_xp);
+ break;
+ case 'y':
+ sp.align_yp = atol (optarg);
+ check_align_option ("-y", sp.align_yp);
+ break;
+ case 'w':
+ sp.align_wp = atol (optarg);
+ check_align_option ("-w", sp.align_wp);
+ break;
+ case 'W':
+ sp.align_wp2 = atol (optarg);
+ check_align_option ("-W", sp.align_wp2);
+ break;
+ case '?':
+ exit(1);
+ }
+ }
+
+ if (optind >= argc)
+ {
+ usage ();
+ exit (1);
+ }
+
+ if (size_num == 0)
+ {
+ fprintf (stderr, "-s <size> must be specified\n");
+ exit (1);
+ }
+
+ gmp_randinit_default (__gmp_rands);
+ __gmp_rands_initialized = 1;
+ gmp_randseed_ui (__gmp_rands, option_seed);
+
+ choice = (struct choice_t *) (*__gmp_allocate_func)
+ ((argc - optind) * sizeof(choice[0]));
+ for ( ; optind < argc; optind++)
+ {
+ struct choice_t c;
+ routine_find (&c, argv[optind]);
+ choice[num_choices] = c;
+ num_choices++;
+ }
+
+ if ((option_cmp == CMP_RATIO || option_cmp == CMP_DIFFERENCE) &&
+ num_choices < 2)
+ {
+ fprintf (stderr, "WARNING, -d or -r does nothing when only one routine requested\n");
+ }
+
+ speed_time_init ();
+ if (option_unit == UNIT_CYCLES || option_unit == UNIT_CYCLESPERLIMB)
+ speed_cycletime_need_cycles ();
+ else
+ speed_cycletime_need_seconds ();
+
+ if (option_gnuplot)
+ {
+ run_gnuplot (argc, argv);
+ }
+ else
+ {
+ if (option_unit == UNIT_SECONDS)
+ printf ("overhead %.9f secs", speed_measure (speed_noop, NULL));
+ else
+ printf ("overhead %.2f cycles",
+ speed_measure (speed_noop, NULL) / speed_cycletime);
+ printf (", precision %d units of %.2e secs",
+ speed_precision, speed_unittime);
+
+ if (speed_cycletime == 1.0 || speed_cycletime == 0.0)
+ printf (", CPU freq unknown\n");
+ else
+ printf (", CPU freq %.2f MHz\n", 1e-6/speed_cycletime);
+
+ printf (" ");
+ for (i = 0; i < num_choices; i++)
+ printf (" %*s", COLUMN_WIDTH, choice[i].name);
+ printf ("\n");
+
+ run_all (stdout);
+ }
+
+ if (option_resource_usage)
+ {
+#if HAVE_GETRUSAGE
+ {
+ /* This doesn't give data sizes on linux 2.0.x, only utime. */
+ struct rusage r;
+ if (getrusage (RUSAGE_SELF, &r) != 0)
+ perror ("getrusage");
+ else
+ printf ("getrusage(): utime %ld.%06ld data %ld stack %ld maxresident %ld\n",
+ r.ru_utime.tv_sec, r.ru_utime.tv_usec,
+ r.ru_idrss, r.ru_isrss, r.ru_ixrss);
+ }
+#else
+ printf ("getrusage() not available\n");
+#endif
+
+ /* Linux kernel. */
+ {
+ char buf[128];
+ sprintf (buf, "/proc/%d/status", getpid());
+ if (access (buf, R_OK) == 0)
+ {
+ sprintf (buf, "cat /proc/%d/status", getpid());
+ system (buf);
+ }
+
+ }
+ }
+
+ return 0;
+}
diff --git a/gmp/tune/speed.h b/gmp/tune/speed.h
new file mode 100644
index 0000000000..d9474adb35
--- /dev/null
+++ b/gmp/tune/speed.h
@@ -0,0 +1,3646 @@
+/* Header for speed and threshold things.
+
+Copyright 1999-2003, 2005, 2006, 2008-2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#ifndef __SPEED_H__
+#define __SPEED_H__
+
+
+/* Pad ptr,oldsize with zero limbs (at the most significant end) to make it
+ newsize long. */
+#define MPN_ZERO_EXTEND(ptr, oldsize, newsize) \
+ do { \
+ ASSERT ((newsize) >= (oldsize)); \
+ MPN_ZERO ((ptr)+(oldsize), (newsize)-(oldsize)); \
+ } while (0)
+
+/* A mask of the least significant n bits. Note 1<<32 doesn't give zero on
+ x86 family CPUs, hence the separate case for GMP_LIMB_BITS. */
+#define MP_LIMB_T_LOWBITMASK(n) \
+ ((n) == GMP_LIMB_BITS ? MP_LIMB_T_MAX : ((mp_limb_t) 1 << (n)) - 1)
+
+
+/* align must be a power of 2 here, usually CACHE_LINE_SIZE is a good choice */
+
+#define TMP_ALLOC_ALIGNED(bytes, align) \
+ align_pointer (TMP_ALLOC ((bytes) + (align)-1), (align))
+#define TMP_ALLOC_LIMBS_ALIGNED(limbs, align) \
+ ((mp_ptr) TMP_ALLOC_ALIGNED ((limbs)*sizeof(mp_limb_t), align))
+
+/* CACHE_LINE_SIZE is our default alignment for speed operands, and the
+ limit on what s->align_xp etc and then request for off-alignment. Maybe
+ this should be an option of some sort, but in any case here are some line
+ sizes,
+
+ bytes
+ 32 pentium
+ 64 athlon
+ 64 itanium-2 L1
+ 128 itanium-2 L2
+*/
+#define CACHE_LINE_SIZE 64 /* bytes */
+
+#define SPEED_TMP_ALLOC_ADJUST_MASK (CACHE_LINE_SIZE/GMP_LIMB_BYTES - 1)
+
+/* Set ptr to a TMP_ALLOC block of the given limbs, with the given limb
+ alignment. */
+#define SPEED_TMP_ALLOC_LIMBS(ptr, limbs, align) \
+ do { \
+ mp_ptr __ptr; \
+ mp_size_t __ptr_align, __ptr_add; \
+ \
+ ASSERT ((CACHE_LINE_SIZE % GMP_LIMB_BYTES) == 0); \
+ __ptr = TMP_ALLOC_LIMBS ((limbs) + SPEED_TMP_ALLOC_ADJUST_MASK); \
+ __ptr_align = (__ptr - (mp_ptr) NULL); \
+ __ptr_add = ((align) - __ptr_align) & SPEED_TMP_ALLOC_ADJUST_MASK; \
+ (ptr) = __ptr + __ptr_add; \
+ } while (0)
+
+
+/* This is the size for s->xp_block and s->yp_block, used in certain
+ routines that want to run across many different data values and use
+ s->size for a different purpose, eg. SPEED_ROUTINE_MPN_GCD_1.
+
+ 512 means 2kbytes of data for each of xp_block and yp_block, making 4k
+ total, which should fit easily in any L1 data cache. */
+
+#define SPEED_BLOCK_SIZE 512 /* limbs */
+
+
+extern double speed_unittime;
+extern double speed_cycletime;
+extern int speed_precision;
+extern char speed_time_string[];
+void speed_time_init (void);
+void speed_cycletime_fail (const char *str);
+void speed_cycletime_init (void);
+void speed_cycletime_need_cycles (void);
+void speed_cycletime_need_seconds (void);
+void speed_starttime (void);
+double speed_endtime (void);
+
+
+struct speed_params {
+ unsigned reps; /* how many times to run the routine */
+ mp_ptr xp; /* first argument */
+ mp_ptr yp; /* second argument */
+ mp_size_t size; /* size of both arguments */
+ mp_limb_t r; /* user supplied parameter */
+ mp_size_t align_xp; /* alignment of xp */
+ mp_size_t align_yp; /* alignment of yp */
+ mp_size_t align_wp; /* intended alignment of wp */
+ mp_size_t align_wp2; /* intended alignment of wp2 */
+ mp_ptr xp_block; /* first special SPEED_BLOCK_SIZE block */
+ mp_ptr yp_block; /* second special SPEED_BLOCK_SIZE block */
+
+ double time_divisor; /* optionally set by the speed routine */
+
+ /* used by the cache priming things */
+ int cache;
+ unsigned src_num, dst_num;
+ struct {
+ mp_ptr ptr;
+ mp_size_t size;
+ } src[5], dst[4];
+};
+
+typedef double (*speed_function_t) (struct speed_params *);
+
+double speed_measure (speed_function_t fun, struct speed_params *);
+
+/* Prototypes for speed measuring routines */
+
+double speed_back_to_back (struct speed_params *);
+double speed_count_leading_zeros (struct speed_params *);
+double speed_count_trailing_zeros (struct speed_params *);
+double speed_find_a (struct speed_params *);
+double speed_gmp_allocate_free (struct speed_params *);
+double speed_gmp_allocate_reallocate_free (struct speed_params *);
+double speed_invert_limb (struct speed_params *);
+double speed_malloc_free (struct speed_params *);
+double speed_malloc_realloc_free (struct speed_params *);
+double speed_memcpy (struct speed_params *);
+double speed_binvert_limb (struct speed_params *);
+double speed_binvert_limb_mul1 (struct speed_params *);
+double speed_binvert_limb_loop (struct speed_params *);
+double speed_binvert_limb_cond (struct speed_params *);
+double speed_binvert_limb_arith (struct speed_params *);
+
+double speed_mpf_init_clear (struct speed_params *);
+
+double speed_mpn_add_n (struct speed_params *);
+double speed_mpn_add_err1_n (struct speed_params *);
+double speed_mpn_add_err2_n (struct speed_params *);
+double speed_mpn_add_err3_n (struct speed_params *);
+double speed_mpn_addlsh_n (struct speed_params *);
+double speed_mpn_addlsh1_n (struct speed_params *);
+double speed_mpn_addlsh2_n (struct speed_params *);
+double speed_mpn_addlsh_n_ip1 (struct speed_params *);
+double speed_mpn_addlsh1_n_ip1 (struct speed_params *);
+double speed_mpn_addlsh2_n_ip1 (struct speed_params *);
+double speed_mpn_addlsh_n_ip2 (struct speed_params *);
+double speed_mpn_addlsh1_n_ip2 (struct speed_params *);
+double speed_mpn_addlsh2_n_ip2 (struct speed_params *);
+double speed_mpn_add_n_sub_n (struct speed_params *);
+double speed_mpn_and_n (struct speed_params *);
+double speed_mpn_andn_n (struct speed_params *);
+double speed_mpn_addmul_1 (struct speed_params *);
+double speed_mpn_addmul_2 (struct speed_params *);
+double speed_mpn_addmul_3 (struct speed_params *);
+double speed_mpn_addmul_4 (struct speed_params *);
+double speed_mpn_addmul_5 (struct speed_params *);
+double speed_mpn_addmul_6 (struct speed_params *);
+double speed_mpn_addmul_7 (struct speed_params *);
+double speed_mpn_addmul_8 (struct speed_params *);
+double speed_mpn_cnd_add_n (struct speed_params *);
+double speed_mpn_cnd_sub_n (struct speed_params *);
+double speed_mpn_com (struct speed_params *);
+double speed_mpn_copyd (struct speed_params *);
+double speed_mpn_copyi (struct speed_params *);
+double speed_MPN_COPY (struct speed_params *);
+double speed_MPN_COPY_DECR (struct speed_params *);
+double speed_MPN_COPY_INCR (struct speed_params *);
+double speed_mpn_sec_tabselect (struct speed_params *);
+double speed_mpn_divexact_1 (struct speed_params *);
+double speed_mpn_divexact_by3 (struct speed_params *);
+double speed_mpn_bdiv_q_1 (struct speed_params *);
+double speed_mpn_pi1_bdiv_q_1 (struct speed_params *);
+double speed_mpn_bdiv_dbm1c (struct speed_params *);
+double speed_mpn_divrem_1 (struct speed_params *);
+double speed_mpn_divrem_1f (struct speed_params *);
+double speed_mpn_divrem_1c (struct speed_params *);
+double speed_mpn_divrem_1cf (struct speed_params *);
+double speed_mpn_divrem_1_div (struct speed_params *);
+double speed_mpn_divrem_1f_div (struct speed_params *);
+double speed_mpn_divrem_1_inv (struct speed_params *);
+double speed_mpn_divrem_1f_inv (struct speed_params *);
+double speed_mpn_divrem_2 (struct speed_params *);
+double speed_mpn_divrem_2_div (struct speed_params *);
+double speed_mpn_divrem_2_inv (struct speed_params *);
+double speed_mpn_div_qr_1n_pi1 (struct speed_params *);
+double speed_mpn_div_qr_1n_pi1_1 (struct speed_params *);
+double speed_mpn_div_qr_1n_pi1_2 (struct speed_params *);
+double speed_mpn_div_qr_1 (struct speed_params *);
+double speed_mpn_div_qr_2n (struct speed_params *);
+double speed_mpn_div_qr_2u (struct speed_params *);
+double speed_mpn_fib2_ui (struct speed_params *);
+double speed_mpn_matrix22_mul (struct speed_params *);
+double speed_mpn_hgcd (struct speed_params *);
+double speed_mpn_hgcd_lehmer (struct speed_params *);
+double speed_mpn_hgcd_appr (struct speed_params *);
+double speed_mpn_hgcd_appr_lehmer (struct speed_params *);
+double speed_mpn_hgcd_reduce (struct speed_params *);
+double speed_mpn_hgcd_reduce_1 (struct speed_params *);
+double speed_mpn_hgcd_reduce_2 (struct speed_params *);
+double speed_mpn_gcd (struct speed_params *);
+double speed_mpn_gcd_1 (struct speed_params *);
+double speed_mpn_gcd_1N (struct speed_params *);
+double speed_mpn_gcdext (struct speed_params *);
+double speed_mpn_gcdext_double (struct speed_params *);
+double speed_mpn_gcdext_one_double (struct speed_params *);
+double speed_mpn_gcdext_one_single (struct speed_params *);
+double speed_mpn_gcdext_single (struct speed_params *);
+double speed_mpn_get_str (struct speed_params *);
+double speed_mpn_hamdist (struct speed_params *);
+double speed_mpn_ior_n (struct speed_params *);
+double speed_mpn_iorn_n (struct speed_params *);
+double speed_mpn_jacobi_base (struct speed_params *);
+double speed_mpn_jacobi_base_1 (struct speed_params *);
+double speed_mpn_jacobi_base_2 (struct speed_params *);
+double speed_mpn_jacobi_base_3 (struct speed_params *);
+double speed_mpn_jacobi_base_4 (struct speed_params *);
+double speed_mpn_lshift (struct speed_params *);
+double speed_mpn_lshiftc (struct speed_params *);
+double speed_mpn_mod_1 (struct speed_params *);
+double speed_mpn_mod_1c (struct speed_params *);
+double speed_mpn_mod_1_div (struct speed_params *);
+double speed_mpn_mod_1_inv (struct speed_params *);
+double speed_mpn_mod_1_1 (struct speed_params *);
+double speed_mpn_mod_1_1_1 (struct speed_params *);
+double speed_mpn_mod_1_1_2 (struct speed_params *);
+double speed_mpn_mod_1_2 (struct speed_params *);
+double speed_mpn_mod_1_3 (struct speed_params *);
+double speed_mpn_mod_1_4 (struct speed_params *);
+double speed_mpn_mod_34lsub1 (struct speed_params *);
+double speed_mpn_modexact_1_odd (struct speed_params *);
+double speed_mpn_modexact_1c_odd (struct speed_params *);
+double speed_mpn_mul_1 (struct speed_params *);
+double speed_mpn_mul_1_inplace (struct speed_params *);
+double speed_mpn_mul_2 (struct speed_params *);
+double speed_mpn_mul_3 (struct speed_params *);
+double speed_mpn_mul_4 (struct speed_params *);
+double speed_mpn_mul_5 (struct speed_params *);
+double speed_mpn_mul_6 (struct speed_params *);
+double speed_mpn_mul (struct speed_params *);
+double speed_mpn_mul_basecase (struct speed_params *);
+double speed_mpn_mulmid (struct speed_params *);
+double speed_mpn_mulmid_basecase (struct speed_params *);
+double speed_mpn_mul_fft (struct speed_params *);
+double speed_mpn_mul_fft_sqr (struct speed_params *);
+double speed_mpn_fft_mul (struct speed_params *);
+double speed_mpn_fft_sqr (struct speed_params *);
+#if WANT_OLD_FFT_FULL
+double speed_mpn_mul_fft_full (struct speed_params *);
+double speed_mpn_mul_fft_full_sqr (struct speed_params *);
+#endif
+double speed_mpn_nussbaumer_mul (struct speed_params *);
+double speed_mpn_nussbaumer_mul_sqr (struct speed_params *);
+double speed_mpn_mul_n (struct speed_params *);
+double speed_mpn_mul_n_sqr (struct speed_params *);
+double speed_mpn_mulmid_n (struct speed_params *);
+double speed_mpn_mullo_n (struct speed_params *);
+double speed_mpn_mullo_basecase (struct speed_params *);
+double speed_mpn_nand_n (struct speed_params *);
+double speed_mpn_nior_n (struct speed_params *);
+double speed_mpn_popcount (struct speed_params *);
+double speed_mpn_preinv_divrem_1 (struct speed_params *);
+double speed_mpn_preinv_divrem_1f (struct speed_params *);
+double speed_mpn_preinv_mod_1 (struct speed_params *);
+double speed_mpn_sbpi1_div_qr (struct speed_params *);
+double speed_mpn_dcpi1_div_qr (struct speed_params *);
+double speed_mpn_sbpi1_divappr_q (struct speed_params *);
+double speed_mpn_dcpi1_divappr_q (struct speed_params *);
+double speed_mpn_mu_div_qr (struct speed_params *);
+double speed_mpn_mu_divappr_q (struct speed_params *);
+double speed_mpn_mupi_div_qr (struct speed_params *);
+double speed_mpn_mu_div_q (struct speed_params *);
+double speed_mpn_sbpi1_bdiv_qr (struct speed_params *);
+double speed_mpn_dcpi1_bdiv_qr (struct speed_params *);
+double speed_mpn_sbpi1_bdiv_q (struct speed_params *);
+double speed_mpn_dcpi1_bdiv_q (struct speed_params *);
+double speed_mpn_mu_bdiv_q (struct speed_params *);
+double speed_mpn_mu_bdiv_qr (struct speed_params *);
+double speed_mpn_broot (struct speed_params *);
+double speed_mpn_broot_invm1 (struct speed_params *);
+double speed_mpn_brootinv (struct speed_params *);
+double speed_mpn_invert (struct speed_params *);
+double speed_mpn_invertappr (struct speed_params *);
+double speed_mpn_ni_invertappr (struct speed_params *);
+double speed_mpn_sec_invert (struct speed_params *s);
+double speed_mpn_binvert (struct speed_params *);
+double speed_mpn_redc_1 (struct speed_params *);
+double speed_mpn_redc_2 (struct speed_params *);
+double speed_mpn_redc_n (struct speed_params *);
+double speed_mpn_rsblsh_n (struct speed_params *);
+double speed_mpn_rsblsh1_n (struct speed_params *);
+double speed_mpn_rsblsh2_n (struct speed_params *);
+double speed_mpn_rsh1add_n (struct speed_params *);
+double speed_mpn_rsh1sub_n (struct speed_params *);
+double speed_mpn_rshift (struct speed_params *);
+double speed_mpn_sb_divrem_m3 (struct speed_params *);
+double speed_mpn_sb_divrem_m3_div (struct speed_params *);
+double speed_mpn_sb_divrem_m3_inv (struct speed_params *);
+double speed_mpn_set_str (struct speed_params *);
+double speed_mpn_bc_set_str (struct speed_params *);
+double speed_mpn_dc_set_str (struct speed_params *);
+double speed_mpn_set_str_pre (struct speed_params *);
+double speed_mpn_sqr_basecase (struct speed_params *);
+double speed_mpn_sqr_diag_addlsh1 (struct speed_params *);
+double speed_mpn_sqr_diagonal (struct speed_params *);
+double speed_mpn_sqr (struct speed_params *);
+double speed_mpn_sqrtrem (struct speed_params *);
+double speed_mpn_rootrem (struct speed_params *);
+double speed_mpn_sub_n (struct speed_params *);
+double speed_mpn_sub_err1_n (struct speed_params *);
+double speed_mpn_sub_err2_n (struct speed_params *);
+double speed_mpn_sub_err3_n (struct speed_params *);
+double speed_mpn_sublsh_n (struct speed_params *);
+double speed_mpn_sublsh1_n (struct speed_params *);
+double speed_mpn_sublsh2_n (struct speed_params *);
+double speed_mpn_sublsh_n_ip1 (struct speed_params *);
+double speed_mpn_sublsh1_n_ip1 (struct speed_params *);
+double speed_mpn_sublsh2_n_ip1 (struct speed_params *);
+double speed_mpn_submul_1 (struct speed_params *);
+double speed_mpn_toom2_sqr (struct speed_params *);
+double speed_mpn_toom3_sqr (struct speed_params *);
+double speed_mpn_toom4_sqr (struct speed_params *);
+double speed_mpn_toom6_sqr (struct speed_params *);
+double speed_mpn_toom8_sqr (struct speed_params *);
+double speed_mpn_toom22_mul (struct speed_params *);
+double speed_mpn_toom33_mul (struct speed_params *);
+double speed_mpn_toom44_mul (struct speed_params *);
+double speed_mpn_toom6h_mul (struct speed_params *);
+double speed_mpn_toom8h_mul (struct speed_params *);
+double speed_mpn_toom32_mul (struct speed_params *);
+double speed_mpn_toom42_mul (struct speed_params *);
+double speed_mpn_toom43_mul (struct speed_params *);
+double speed_mpn_toom63_mul (struct speed_params *);
+double speed_mpn_toom32_for_toom43_mul (struct speed_params *);
+double speed_mpn_toom43_for_toom32_mul (struct speed_params *);
+double speed_mpn_toom32_for_toom53_mul (struct speed_params *);
+double speed_mpn_toom53_for_toom32_mul (struct speed_params *);
+double speed_mpn_toom42_for_toom53_mul (struct speed_params *);
+double speed_mpn_toom53_for_toom42_mul (struct speed_params *);
+double speed_mpn_toom43_for_toom54_mul (struct speed_params *);
+double speed_mpn_toom54_for_toom43_mul (struct speed_params *);
+double speed_mpn_toom42_mulmid (struct speed_params *);
+double speed_mpn_mulmod_bnm1 (struct speed_params *);
+double speed_mpn_bc_mulmod_bnm1 (struct speed_params *);
+double speed_mpn_mulmod_bnm1_rounded (struct speed_params *);
+double speed_mpn_sqrmod_bnm1 (struct speed_params *);
+double speed_mpn_udiv_qrnnd (struct speed_params *);
+double speed_mpn_udiv_qrnnd_r (struct speed_params *);
+double speed_mpn_umul_ppmm (struct speed_params *);
+double speed_mpn_umul_ppmm_r (struct speed_params *);
+double speed_mpn_xnor_n (struct speed_params *);
+double speed_mpn_xor_n (struct speed_params *);
+double speed_MPN_ZERO (struct speed_params *);
+
+double speed_mpq_init_clear (struct speed_params *);
+
+double speed_mpz_add (struct speed_params *);
+double speed_mpz_bin_uiui (struct speed_params *);
+double speed_mpz_bin_ui (struct speed_params *);
+double speed_mpz_fac_ui (struct speed_params *);
+double speed_mpz_fib_ui (struct speed_params *);
+double speed_mpz_fib2_ui (struct speed_params *);
+double speed_mpz_init_clear (struct speed_params *);
+double speed_mpz_init_realloc_clear (struct speed_params *);
+double speed_mpz_jacobi (struct speed_params *);
+double speed_mpz_lucnum_ui (struct speed_params *);
+double speed_mpz_lucnum2_ui (struct speed_params *);
+double speed_mpz_mod (struct speed_params *);
+double speed_mpz_powm (struct speed_params *);
+double speed_mpz_powm_mod (struct speed_params *);
+double speed_mpz_powm_redc (struct speed_params *);
+double speed_mpz_powm_sec (struct speed_params *);
+double speed_mpz_powm_ui (struct speed_params *);
+double speed_mpz_urandomb (struct speed_params *);
+
+double speed_gmp_randseed (struct speed_params *);
+double speed_gmp_randseed_ui (struct speed_params *);
+
+double speed_noop (struct speed_params *);
+double speed_noop_wxs (struct speed_params *);
+double speed_noop_wxys (struct speed_params *);
+
+double speed_operator_div (struct speed_params *);
+double speed_operator_mod (struct speed_params *);
+
+double speed_udiv_qrnnd (struct speed_params *);
+double speed_udiv_qrnnd_preinv1 (struct speed_params *);
+double speed_udiv_qrnnd_preinv2 (struct speed_params *);
+double speed_udiv_qrnnd_preinv3 (struct speed_params *);
+double speed_udiv_qrnnd_c (struct speed_params *);
+double speed_umul_ppmm (struct speed_params *);
+
+/* Prototypes for other routines */
+
+/* low 32-bits in p[0], high 32-bits in p[1] */
+void speed_cyclecounter (unsigned p[2]);
+
+void mftb_function (unsigned p[2]);
+
+/* In i386 gcc -fPIC, ebx is a fixed register and can't be declared a dummy
+ output or a clobber for the cpuid, hence an explicit save and restore. A
+ clobber as such doesn't provoke an error unfortunately (gcc 3.0), so use
+ the dummy output style in non-PIC, so there's an error if somehow -fPIC
+ is used without a -DPIC to tell us about it. */
+#if defined(__GNUC__) && ! defined (NO_ASM) \
+ && (defined (__i386__) || defined (__i486__))
+#if defined (PIC) || defined (__APPLE_CC__)
+#define speed_cyclecounter(p) \
+ do { \
+ int __speed_cyclecounter__save_ebx; \
+ int __speed_cyclecounter__dummy; \
+ __asm__ __volatile__ ("movl %%ebx, %1\n" \
+ "cpuid\n" \
+ "movl %1, %%ebx\n" \
+ "rdtsc" \
+ : "=a" ((p)[0]), \
+ "=&rm" (__speed_cyclecounter__save_ebx), \
+ "=c" (__speed_cyclecounter__dummy), \
+ "=d" ((p)[1])); \
+ } while (0)
+#else
+#define speed_cyclecounter(p) \
+ do { \
+ int __speed_cyclecounter__dummy1; \
+ int __speed_cyclecounter__dummy2; \
+ __asm__ __volatile__ ("cpuid\n" \
+ "rdtsc" \
+ : "=a" ((p)[0]), \
+ "=b" (__speed_cyclecounter__dummy1), \
+ "=c" (__speed_cyclecounter__dummy2), \
+ "=d" ((p)[1])); \
+ } while (0)
+#endif
+#endif
+
+double speed_cyclecounter_diff (const unsigned [2], const unsigned [2]);
+int gettimeofday_microseconds_p (void);
+int getrusage_microseconds_p (void);
+int cycles_works_p (void);
+long clk_tck (void);
+double freq_measure (const char *, double (*)(void));
+
+int double_cmp_ptr (const double *, const double *);
+void pentium_wbinvd (void);
+typedef int (*qsort_function_t) (const void *, const void *);
+
+void noop (void);
+void noop_1 (mp_limb_t);
+void noop_wxs (mp_ptr, mp_srcptr, mp_size_t);
+void noop_wxys (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
+void mpn_cache_fill (mp_srcptr, mp_size_t);
+void mpn_cache_fill_dummy (mp_limb_t);
+void speed_cache_fill (struct speed_params *);
+void speed_operand_src (struct speed_params *, mp_ptr, mp_size_t);
+void speed_operand_dst (struct speed_params *, mp_ptr, mp_size_t);
+
+extern int speed_option_addrs;
+extern int speed_option_verbose;
+extern int speed_option_cycles_broken;
+void speed_option_set (const char *);
+
+mp_limb_t mpn_div_qr_1n_pi1_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, mp_limb_t);
+mp_limb_t mpn_div_qr_1n_pi1_2 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t, mp_limb_t);
+
+mp_limb_t mpn_divrem_1_div (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t mpn_divrem_1_inv (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t mpn_divrem_2_div (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr);
+mp_limb_t mpn_divrem_2_inv (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr);
+
+int mpn_jacobi_base_1 (mp_limb_t, mp_limb_t, int);
+int mpn_jacobi_base_2 (mp_limb_t, mp_limb_t, int);
+int mpn_jacobi_base_3 (mp_limb_t, mp_limb_t, int);
+int mpn_jacobi_base_4 (mp_limb_t, mp_limb_t, int);
+
+mp_limb_t mpn_mod_1_div (mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t mpn_mod_1_inv (mp_srcptr, mp_size_t, mp_limb_t);
+
+mp_limb_t mpn_mod_1_1p_1 (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t [4]);
+mp_limb_t mpn_mod_1_1p_2 (mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t [4]);
+
+void mpn_mod_1_1p_cps_1 (mp_limb_t [4], mp_limb_t);
+void mpn_mod_1_1p_cps_2 (mp_limb_t [4], mp_limb_t);
+
+mp_size_t mpn_gcdext_one_double (mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
+mp_size_t mpn_gcdext_one_single (mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
+mp_size_t mpn_gcdext_single (mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
+mp_size_t mpn_gcdext_double (mp_ptr, mp_ptr, mp_size_t *, mp_ptr, mp_size_t, mp_ptr, mp_size_t);
+mp_size_t mpn_hgcd_lehmer (mp_ptr, mp_ptr, mp_size_t, struct hgcd_matrix *, mp_ptr);
+mp_size_t mpn_hgcd_lehmer_itch (mp_size_t);
+
+mp_size_t mpn_hgcd_appr_lehmer (mp_ptr, mp_ptr, mp_size_t, struct hgcd_matrix *, mp_ptr);
+mp_size_t mpn_hgcd_appr_lehmer_itch (mp_size_t);
+
+mp_size_t mpn_hgcd_reduce_1 (struct hgcd_matrix *, mp_ptr, mp_ptr, mp_size_t, mp_size_t, mp_ptr);
+mp_size_t mpn_hgcd_reduce_1_itch (mp_size_t, mp_size_t);
+
+mp_size_t mpn_hgcd_reduce_2 (struct hgcd_matrix *, mp_ptr, mp_ptr, mp_size_t, mp_size_t, mp_ptr);
+mp_size_t mpn_hgcd_reduce_2_itch (mp_size_t, mp_size_t);
+
+mp_limb_t mpn_sb_divrem_mn_div (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t);
+mp_limb_t mpn_sb_divrem_mn_inv (mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t);
+
+mp_size_t mpn_set_str_basecase (mp_ptr, const unsigned char *, size_t, int);
+void mpn_pre_set_str (mp_ptr, unsigned char *, size_t, powers_t *, mp_ptr);
+
+void mpz_powm_mod (mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr);
+void mpz_powm_redc (mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr);
+
+int speed_routine_count_zeros_setup (struct speed_params *, mp_ptr, int, int);
+
+
+/* "get" is called repeatedly until it ticks over, just in case on a fast
+ processor it takes less than a microsecond, though this is probably
+ unlikely if it's a system call.
+
+ speed_cyclecounter is called on the same side of the "get" for the start
+ and end measurements. It doesn't matter how long it takes from the "get"
+ sample to the cycles sample, since that period will cancel out in the
+ difference calculation (assuming it's the same each time).
+
+ Letting the test run for more than a process time slice is probably only
+ going to reduce accuracy, especially for getrusage when the cycle counter
+ is real time, or for gettimeofday if the cycle counter is in fact process
+ time. Use CLK_TCK/2 as a reasonable stop.
+
+ It'd be desirable to be quite accurate here. The default speed_precision
+ for a cycle counter is 10000 cycles, so to mix that with getrusage or
+ gettimeofday the frequency should be at least that accurate. But running
+ measurements for 10000 microseconds (or more) is too long. Be satisfied
+ with just a half clock tick (5000 microseconds usually). */
+
+#define FREQ_MEASURE_ONE(name, type, get, getc, sec, usec) \
+ do { \
+ type st1, st, et1, et; \
+ unsigned sc[2], ec[2]; \
+ long dt, half_tick; \
+ double dc, cyc; \
+ \
+ half_tick = (1000000L / clk_tck()) / 2; \
+ \
+ get (st1); \
+ do { \
+ get (st); \
+ } while (usec(st) == usec(st1) && sec(st) == sec(st1)); \
+ \
+ getc (sc); \
+ \
+ for (;;) \
+ { \
+ get (et1); \
+ do { \
+ get (et); \
+ } while (usec(et) == usec(et1) && sec(et) == sec(et1)); \
+ \
+ getc (ec); \
+ \
+ dc = speed_cyclecounter_diff (ec, sc); \
+ \
+ /* allow secs to cancel before multiplying */ \
+ dt = sec(et) - sec(st); \
+ dt = dt * 1000000L + (usec(et) - usec(st)); \
+ \
+ if (dt >= half_tick) \
+ break; \
+ } \
+ \
+ cyc = dt * 1e-6 / dc; \
+ \
+ if (speed_option_verbose >= 2) \
+ printf ("freq_measure_%s_one() dc=%.6g dt=%ld cyc=%.6g\n", \
+ name, dc, dt, cyc); \
+ \
+ return dt * 1e-6 / dc; \
+ \
+ } while (0)
+
+
+
+
+/* The measuring routines use these big macros to save duplication for
+ similar forms. They also get used for some automatically generated
+ measuring of new implementations of functions.
+
+ Having something like SPEED_ROUTINE_BINARY_N as a subroutine accepting a
+ function pointer is considered undesirable since it's not the way a
+ normal application will be calling, and some processors might do
+ different things with an indirect call, like not branch predicting, or
+ doing a full pipe flush. At least some of the "functions" measured are
+ actually macros too.
+
+ The net effect is to bloat the object code, possibly in a big way, but
+ only what's being measured is being run, so that doesn't matter.
+
+ The loop forms don't try to cope with __GMP_ATTRIBUTE_PURE or
+ ATTRIBUTE_CONST on the called functions. Adding a cast to a non-pure
+ function pointer doesn't work in gcc 3.2. Using an actual non-pure
+ function pointer variable works, but stands a real risk of a
+ non-optimizing compiler generating unnecessary overheads in the call.
+ Currently the best idea is not to use those attributes for a timing
+ program build. __GMP_NO_ATTRIBUTE_CONST_PURE will tell gmp.h and
+ gmp-impl.h to omit them from routines there. */
+
+#define SPEED_RESTRICT_COND(cond) if (!(cond)) return -1.0;
+
+/* For mpn_copy or similar. */
+#define SPEED_ROUTINE_MPN_COPY_CALL(call) \
+ { \
+ mp_ptr wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_MPN_COPY(function) \
+ SPEED_ROUTINE_MPN_COPY_CALL (function (wp, s->xp, s->size))
+
+#define SPEED_ROUTINE_MPN_TABSELECT(function) \
+ { \
+ mp_ptr xp, wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ if (s->r == 0) \
+ s->r = s->size; /* default to a quadratic shape */ \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (xp, s->size * s->r, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ speed_operand_src (s, xp, s->size * s->r); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, xp, s->size, s->r, (s->r) / 2); \
+ while (--i != 0); \
+ t = speed_endtime () / s->r; \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+#define SPEED_ROUTINE_MPN_COPYC(function) \
+ { \
+ mp_ptr wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, s->xp, s->size, 0); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+/* s->size is still in limbs, and it's limbs which are copied, but
+ "function" takes a size in bytes not limbs. */
+#define SPEED_ROUTINE_MPN_COPY_BYTES(function) \
+ { \
+ mp_ptr wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, s->xp, s->size * GMP_LIMB_BYTES); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+/* For mpn_add_n, mpn_sub_n, or similar. */
+#define SPEED_ROUTINE_MPN_BINARY_N_CALL(call) \
+ { \
+ mp_ptr wp; \
+ mp_ptr xp, yp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ xp = s->xp; \
+ yp = s->yp; \
+ \
+ if (s->r == 0) ; \
+ else if (s->r == 1) { xp = wp; } \
+ else if (s->r == 2) { yp = wp; } \
+ else if (s->r == 3) { xp = wp; yp = wp; } \
+ else if (s->r == 4) { yp = xp; } \
+ else { \
+ TMP_FREE; \
+ return -1.0; \
+ } \
+ \
+ /* initialize wp if operand overlap */ \
+ if (xp == wp || yp == wp) \
+ MPN_COPY (wp, s->xp, s->size); \
+ \
+ speed_operand_src (s, xp, s->size); \
+ speed_operand_src (s, yp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+/* For mpn_aors_errK_n, where 1 <= K <= 3. */
+#define SPEED_ROUTINE_MPN_BINARY_ERR_N_CALL(call, K) \
+ { \
+ mp_ptr wp; \
+ mp_ptr xp, yp; \
+ mp_ptr zp[K]; \
+ mp_limb_t ep[2*K]; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ /* (don't have a mechanism to specify zp alignments) */ \
+ for (i = 0; i < K; i++) \
+ SPEED_TMP_ALLOC_LIMBS (zp[i], s->size, 0); \
+ \
+ xp = s->xp; \
+ yp = s->yp; \
+ \
+ if (s->r == 0) ; \
+ else if (s->r == 1) { xp = wp; } \
+ else if (s->r == 2) { yp = wp; } \
+ else if (s->r == 3) { xp = wp; yp = wp; } \
+ else if (s->r == 4) { yp = xp; } \
+ else { \
+ TMP_FREE; \
+ return -1.0; \
+ } \
+ \
+ /* initialize wp if operand overlap */ \
+ if (xp == wp || yp == wp) \
+ MPN_COPY (wp, s->xp, s->size); \
+ \
+ speed_operand_src (s, xp, s->size); \
+ speed_operand_src (s, yp, s->size); \
+ for (i = 0; i < K; i++) \
+ speed_operand_src (s, zp[i], s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_BINARY_ERR1_N(function) \
+ SPEED_ROUTINE_MPN_BINARY_ERR_N_CALL ((*function) (wp, xp, yp, ep, zp[0], s->size, 0), 1)
+
+#define SPEED_ROUTINE_MPN_BINARY_ERR2_N(function) \
+ SPEED_ROUTINE_MPN_BINARY_ERR_N_CALL ((*function) (wp, xp, yp, ep, zp[0], zp[1], s->size, 0), 2)
+
+#define SPEED_ROUTINE_MPN_BINARY_ERR3_N(function) \
+ SPEED_ROUTINE_MPN_BINARY_ERR_N_CALL ((*function) (wp, xp, yp, ep, zp[0], zp[1], zp[2], s->size, 0), 3)
+
+
+/* For mpn_add_n, mpn_sub_n, or similar. */
+#define SPEED_ROUTINE_MPN_ADDSUB_N_CALL(call) \
+ { \
+ mp_ptr ap, sp; \
+ mp_ptr xp, yp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ap, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (sp, s->size, s->align_wp); \
+ \
+ xp = s->xp; \
+ yp = s->yp; \
+ \
+ if ((s->r & 1) != 0) { xp = ap; } \
+ if ((s->r & 2) != 0) { yp = ap; } \
+ if ((s->r & 4) != 0) { xp = sp; } \
+ if ((s->r & 8) != 0) { yp = sp; } \
+ if ((s->r & 3) == 3 || (s->r & 12) == 12) \
+ { \
+ TMP_FREE; \
+ return -1.0; \
+ } \
+ \
+ /* initialize ap if operand overlap */ \
+ if (xp == ap || yp == ap) \
+ MPN_COPY (ap, s->xp, s->size); \
+ /* initialize sp if operand overlap */ \
+ if (xp == sp || yp == sp) \
+ MPN_COPY (sp, s->xp, s->size); \
+ \
+ speed_operand_src (s, xp, s->size); \
+ speed_operand_src (s, yp, s->size); \
+ speed_operand_dst (s, ap, s->size); \
+ speed_operand_dst (s, sp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_BINARY_N(function) \
+ SPEED_ROUTINE_MPN_BINARY_N_CALL ((*function) (wp, xp, yp, s->size))
+
+#define SPEED_ROUTINE_MPN_BINARY_NC(function) \
+ SPEED_ROUTINE_MPN_BINARY_N_CALL ((*function) (wp, xp, yp, s->size, 0))
+
+
+/* For mpn_lshift, mpn_rshift, mpn_mul_1, with r, or similar. */
+#define SPEED_ROUTINE_MPN_UNARY_1_CALL(call) \
+ { \
+ mp_ptr wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_UNARY_1(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->xp, s->size, s->r))
+
+#define SPEED_ROUTINE_MPN_UNARY_1C(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->xp, s->size, s->r, 0))
+
+/* FIXME: wp is uninitialized here, should start it off from xp */
+#define SPEED_ROUTINE_MPN_UNARY_1_INPLACE(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, wp, s->size, s->r))
+
+#define SPEED_ROUTINE_MPN_DIVEXACT_1(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->xp, s->size, s->r))
+
+#define SPEED_ROUTINE_MPN_BDIV_Q_1(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->xp, s->size, s->r))
+
+#define SPEED_ROUTINE_MPN_PI1_BDIV_Q_1_CALL(call) \
+ { \
+ unsigned shift; \
+ mp_limb_t dinv; \
+ \
+ SPEED_RESTRICT_COND (s->size > 0); \
+ SPEED_RESTRICT_COND (s->r != 0); \
+ \
+ count_trailing_zeros (shift, s->r); \
+ binvert_limb (dinv, s->r >> shift); \
+ \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL (call); \
+ }
+#define SPEED_ROUTINE_MPN_PI1_BDIV_Q_1(function) \
+ SPEED_ROUTINE_MPN_PI1_BDIV_Q_1_CALL \
+ ((*function) (wp, s->xp, s->size, s->r, dinv, shift))
+
+#define SPEED_ROUTINE_MPN_BDIV_DBM1C(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->xp, s->size, s->r, 0))
+
+#define SPEED_ROUTINE_MPN_DIVREM_1(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, 0, s->xp, s->size, s->r))
+
+#define SPEED_ROUTINE_MPN_DIVREM_1C(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, 0, s->xp, s->size, s->r, 0))
+
+#define SPEED_ROUTINE_MPN_DIVREM_1F(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->size, s->xp, 0, s->r))
+
+#define SPEED_ROUTINE_MPN_DIVREM_1CF(function) \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL ((*function) (wp, s->size, s->xp, 0, s->r, 0))
+
+
+#define SPEED_ROUTINE_MPN_PREINV_DIVREM_1_CALL(call) \
+ { \
+ unsigned shift; \
+ mp_limb_t dinv; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ SPEED_RESTRICT_COND (s->r != 0); \
+ \
+ count_leading_zeros (shift, s->r); \
+ invert_limb (dinv, s->r << shift); \
+ \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL (call); \
+ } \
+
+#define SPEED_ROUTINE_MPN_PREINV_DIVREM_1(function) \
+ SPEED_ROUTINE_MPN_PREINV_DIVREM_1_CALL \
+ ((*function) (wp, 0, s->xp, s->size, s->r, dinv, shift))
+
+/* s->size limbs worth of fraction part */
+#define SPEED_ROUTINE_MPN_PREINV_DIVREM_1F(function) \
+ SPEED_ROUTINE_MPN_PREINV_DIVREM_1_CALL \
+ ((*function) (wp, s->size, s->xp, 0, s->r, dinv, shift))
+
+
+/* s->r is duplicated to form the multiplier, defaulting to
+ MP_BASES_BIG_BASE_10. Not sure if that's particularly useful, but at
+ least it provides some control. */
+#define SPEED_ROUTINE_MPN_UNARY_N(function,N) \
+ { \
+ mp_ptr wp; \
+ mp_size_t wn; \
+ unsigned i; \
+ double t; \
+ mp_limb_t yp[N]; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= N); \
+ \
+ TMP_MARK; \
+ wn = s->size + N-1; \
+ SPEED_TMP_ALLOC_LIMBS (wp, wn, s->align_wp); \
+ for (i = 0; i < N; i++) \
+ yp[i] = (s->r != 0 ? s->r : MP_BASES_BIG_BASE_10); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, yp, (mp_size_t) N); \
+ speed_operand_dst (s, wp, wn); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, s->xp, s->size, yp); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_UNARY_2(function) \
+ SPEED_ROUTINE_MPN_UNARY_N (function, 2)
+#define SPEED_ROUTINE_MPN_UNARY_3(function) \
+ SPEED_ROUTINE_MPN_UNARY_N (function, 3)
+#define SPEED_ROUTINE_MPN_UNARY_4(function) \
+ SPEED_ROUTINE_MPN_UNARY_N (function, 4)
+#define SPEED_ROUTINE_MPN_UNARY_5(function) \
+ SPEED_ROUTINE_MPN_UNARY_N (function, 5)
+#define SPEED_ROUTINE_MPN_UNARY_6(function) \
+ SPEED_ROUTINE_MPN_UNARY_N (function, 6)
+#define SPEED_ROUTINE_MPN_UNARY_7(function) \
+ SPEED_ROUTINE_MPN_UNARY_N (function, 7)
+#define SPEED_ROUTINE_MPN_UNARY_8(function) \
+ SPEED_ROUTINE_MPN_UNARY_N (function, 8)
+
+
+/* For mpn_mul, mpn_mul_basecase, xsize=r, ysize=s->size. */
+#define SPEED_ROUTINE_MPN_MUL(function) \
+ { \
+ mp_ptr wp; \
+ mp_size_t size1; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ size1 = (s->r == 0 ? s->size : s->r); \
+ if (size1 < 0) size1 = -size1 - s->size; \
+ \
+ SPEED_RESTRICT_COND (size1 >= 1); \
+ SPEED_RESTRICT_COND (s->size >= size1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, size1 + s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, size1); \
+ speed_operand_dst (s, wp, size1 + s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, s->xp, s->size, s->yp, size1); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+#define SPEED_ROUTINE_MPN_MUL_N_CALL(call) \
+ { \
+ mp_ptr wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, 2*s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, 2*s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_MUL_N(function) \
+ SPEED_ROUTINE_MPN_MUL_N_CALL (function (wp, s->xp, s->yp, s->size));
+
+#define SPEED_ROUTINE_MPN_MULLO_N_CALL(call) \
+ { \
+ mp_ptr wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_MULLO_N(function) \
+ SPEED_ROUTINE_MPN_MULLO_N_CALL (function (wp, s->xp, s->yp, s->size));
+
+/* For mpn_mul_basecase, xsize=r, ysize=s->size. */
+#define SPEED_ROUTINE_MPN_MULLO_BASECASE(function) \
+ { \
+ mp_ptr wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, s->xp, s->yp, s->size); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+/* For mpn_mulmid, mpn_mulmid_basecase, xsize=r, ysize=s->size. */
+#define SPEED_ROUTINE_MPN_MULMID(function) \
+ { \
+ mp_ptr wp, xp; \
+ mp_size_t size1; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ size1 = (s->r == 0 ? (2 * s->size - 1) : s->r); \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ SPEED_RESTRICT_COND (size1 >= s->size); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, size1 - s->size + 3, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (xp, size1, s->align_xp); \
+ \
+ speed_operand_src (s, xp, size1); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, size1 - s->size + 3); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, xp, size1, s->yp, s->size); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_MULMID_N(function) \
+ { \
+ mp_ptr wp, xp; \
+ mp_size_t size1; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ size1 = 2 * s->size - 1; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, size1 - s->size + 3, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (xp, size1, s->align_xp); \
+ \
+ speed_operand_src (s, xp, size1); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, size1 - s->size + 3); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, xp, s->yp, s->size); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_TOOM42_MULMID(function) \
+ { \
+ mp_ptr wp, xp, scratch; \
+ mp_size_t size1, scratch_size; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ size1 = 2 * s->size - 1; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, size1 - s->size + 3, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (xp, size1, s->align_xp); \
+ scratch_size = mpn_toom42_mulmid_itch (s->size); \
+ SPEED_TMP_ALLOC_LIMBS (scratch, scratch_size, 0); \
+ \
+ speed_operand_src (s, xp, size1); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, size1 - s->size + 3); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, xp, s->yp, s->size, scratch); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_MULMOD_BNM1_CALL(call) \
+ { \
+ mp_ptr wp, tp; \
+ unsigned i; \
+ double t; \
+ mp_size_t itch; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ itch = mpn_mulmod_bnm1_itch (s->size, s->size, s->size); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, 2 * s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, itch, s->align_wp2); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, 2 * s->size); \
+ speed_operand_dst (s, tp, itch); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_MPN_MULMOD_BNM1_ROUNDED(function) \
+ { \
+ mp_ptr wp, tp; \
+ unsigned i; \
+ double t; \
+ mp_size_t size, itch; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ size = mpn_mulmod_bnm1_next_size (s->size); \
+ itch = mpn_mulmod_bnm1_itch (size, size, size); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, itch, s->align_wp2); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, size); \
+ speed_operand_dst (s, tp, itch); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, size, s->xp, s->size, s->yp, s->size, tp); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_MUL_N_TSPACE(call, tsize, minsize) \
+ { \
+ mp_ptr wp, tspace; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= minsize); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, 2*s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tspace, tsize, s->align_wp2); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, wp, 2*s->size); \
+ speed_operand_dst (s, tspace, tsize); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_TOOM22_MUL_N(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, s->size, tspace), \
+ mpn_toom22_mul_itch (s->size, s->size), \
+ MPN_TOOM22_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM33_MUL_N(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, s->size, tspace), \
+ mpn_toom33_mul_itch (s->size, s->size), \
+ MPN_TOOM33_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM44_MUL_N(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, s->size, tspace), \
+ mpn_toom44_mul_itch (s->size, s->size), \
+ MPN_TOOM44_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM6H_MUL_N(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, s->size, tspace), \
+ mpn_toom6h_mul_itch (s->size, s->size), \
+ MPN_TOOM6H_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM8H_MUL_N(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, s->size, tspace), \
+ mpn_toom8h_mul_itch (s->size, s->size), \
+ MPN_TOOM8H_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM32_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, 2*s->size/3, tspace), \
+ mpn_toom32_mul_itch (s->size, 2*s->size/3), \
+ MPN_TOOM32_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM42_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, s->size/2, tspace), \
+ mpn_toom42_mul_itch (s->size, s->size/2), \
+ MPN_TOOM42_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM43_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, s->size*3/4, tspace), \
+ mpn_toom43_mul_itch (s->size, s->size*3/4), \
+ MPN_TOOM43_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM63_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, s->size/2, tspace), \
+ mpn_toom63_mul_itch (s->size, s->size/2), \
+ MPN_TOOM63_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM32_FOR_TOOM43_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, 17*s->size/24, tspace), \
+ mpn_toom32_mul_itch (s->size, 17*s->size/24), \
+ MPN_TOOM32_MUL_MINSIZE)
+#define SPEED_ROUTINE_MPN_TOOM43_FOR_TOOM32_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, 17*s->size/24, tspace), \
+ mpn_toom43_mul_itch (s->size, 17*s->size/24), \
+ MPN_TOOM43_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM32_FOR_TOOM53_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, 19*s->size/30, tspace), \
+ mpn_toom32_mul_itch (s->size, 19*s->size/30), \
+ MPN_TOOM32_MUL_MINSIZE)
+#define SPEED_ROUTINE_MPN_TOOM53_FOR_TOOM32_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, 19*s->size/30, tspace), \
+ mpn_toom53_mul_itch (s->size, 19*s->size/30), \
+ MPN_TOOM53_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM42_FOR_TOOM53_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, 11*s->size/20, tspace), \
+ mpn_toom42_mul_itch (s->size, 11*s->size/20), \
+ MPN_TOOM42_MUL_MINSIZE)
+#define SPEED_ROUTINE_MPN_TOOM53_FOR_TOOM42_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, 11*s->size/20, tspace), \
+ mpn_toom53_mul_itch (s->size, 11*s->size/20), \
+ MPN_TOOM53_MUL_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM43_FOR_TOOM54_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, 5*s->size/6, tspace), \
+ mpn_toom42_mul_itch (s->size, 5*s->size/6), \
+ MPN_TOOM54_MUL_MINSIZE)
+#define SPEED_ROUTINE_MPN_TOOM54_FOR_TOOM43_MUL(function) \
+ SPEED_ROUTINE_MPN_MUL_N_TSPACE \
+ (function (wp, s->xp, s->size, s->yp, 5*s->size/6, tspace), \
+ mpn_toom54_mul_itch (s->size, 5*s->size/6), \
+ MPN_TOOM54_MUL_MINSIZE)
+
+
+
+#define SPEED_ROUTINE_MPN_SQR_CALL(call) \
+ { \
+ mp_ptr wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, 2*s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, 2*s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_SQR(function) \
+ SPEED_ROUTINE_MPN_SQR_CALL (function (wp, s->xp, s->size))
+
+#define SPEED_ROUTINE_MPN_SQR_DIAG_ADDLSH1_CALL(call) \
+ { \
+ mp_ptr wp, tp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 2); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (tp, 2 * s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (wp, 2 * s->size, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, tp, 2 * s->size); \
+ speed_operand_dst (s, wp, 2 * s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime () / 2; \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_SQR_TSPACE(call, tsize, minsize) \
+ { \
+ mp_ptr wp, tspace; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= minsize); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, 2*s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tspace, tsize, s->align_wp2); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, 2*s->size); \
+ speed_operand_dst (s, tspace, tsize); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_TOOM2_SQR(function) \
+ SPEED_ROUTINE_MPN_SQR_TSPACE (function (wp, s->xp, s->size, tspace), \
+ mpn_toom2_sqr_itch (s->size), \
+ MPN_TOOM2_SQR_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM3_SQR(function) \
+ SPEED_ROUTINE_MPN_SQR_TSPACE (function (wp, s->xp, s->size, tspace), \
+ mpn_toom3_sqr_itch (s->size), \
+ MPN_TOOM3_SQR_MINSIZE)
+
+
+#define SPEED_ROUTINE_MPN_TOOM4_SQR(function) \
+ SPEED_ROUTINE_MPN_SQR_TSPACE (function (wp, s->xp, s->size, tspace), \
+ mpn_toom4_sqr_itch (s->size), \
+ MPN_TOOM4_SQR_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM6_SQR(function) \
+ SPEED_ROUTINE_MPN_SQR_TSPACE (function (wp, s->xp, s->size, tspace), \
+ mpn_toom6_sqr_itch (s->size), \
+ MPN_TOOM6_SQR_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_TOOM8_SQR(function) \
+ SPEED_ROUTINE_MPN_SQR_TSPACE (function (wp, s->xp, s->size, tspace), \
+ mpn_toom8_sqr_itch (s->size), \
+ MPN_TOOM8_SQR_MINSIZE)
+
+#define SPEED_ROUTINE_MPN_MOD_CALL(call) \
+ { \
+ unsigned i; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ \
+ return speed_endtime (); \
+ }
+
+#define SPEED_ROUTINE_MPN_MOD_1(function) \
+ SPEED_ROUTINE_MPN_MOD_CALL ((*function) (s->xp, s->size, s->r))
+
+#define SPEED_ROUTINE_MPN_MOD_1C(function) \
+ SPEED_ROUTINE_MPN_MOD_CALL ((*function)(s->xp, s->size, s->r, CNST_LIMB(0)))
+
+#define SPEED_ROUTINE_MPN_MODEXACT_1_ODD(function) \
+ SPEED_ROUTINE_MPN_MOD_CALL (function (s->xp, s->size, s->r));
+
+#define SPEED_ROUTINE_MPN_MODEXACT_1C_ODD(function) \
+ SPEED_ROUTINE_MPN_MOD_CALL (function (s->xp, s->size, s->r, CNST_LIMB(0)));
+
+#define SPEED_ROUTINE_MPN_MOD_34LSUB1(function) \
+ SPEED_ROUTINE_MPN_MOD_CALL ((*function) (s->xp, s->size))
+
+#define SPEED_ROUTINE_MPN_PREINV_MOD_1(function) \
+ { \
+ unsigned i; \
+ mp_limb_t inv; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ SPEED_RESTRICT_COND (s->r & GMP_LIMB_HIGHBIT); \
+ \
+ invert_limb (inv, s->r); \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ (*function) (s->xp, s->size, s->r, inv); \
+ while (--i != 0); \
+ \
+ return speed_endtime (); \
+ }
+
+#define SPEED_ROUTINE_MPN_MOD_1_1(function,pfunc) \
+ { \
+ unsigned i; \
+ mp_limb_t inv[4]; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 2); \
+ \
+ mpn_mod_1_1p_cps (inv, s->r); \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ pfunc (inv, s->r); \
+ function (s->xp, s->size, s->r << inv[1], inv); \
+ } while (--i != 0); \
+ \
+ return speed_endtime (); \
+ }
+#define SPEED_ROUTINE_MPN_MOD_1_N(function,pfunc,N) \
+ { \
+ unsigned i; \
+ mp_limb_t inv[N+3]; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ SPEED_RESTRICT_COND (s->r <= ~(mp_limb_t)0 / N); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ pfunc (inv, s->r); \
+ function (s->xp, s->size, s->r, inv); \
+ } while (--i != 0); \
+ \
+ return speed_endtime (); \
+ }
+
+
+/* A division of 2*s->size by s->size limbs */
+
+#define SPEED_ROUTINE_MPN_DC_DIVREM_CALL(call) \
+ { \
+ unsigned i; \
+ mp_ptr a, d, q, r; \
+ double t; \
+ gmp_pi1_t dinv; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (a, 2*s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (d, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (q, s->size+1, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (r, s->size, s->align_wp2); \
+ \
+ MPN_COPY (a, s->xp, s->size); \
+ MPN_COPY (a+s->size, s->xp, s->size); \
+ \
+ MPN_COPY (d, s->yp, s->size); \
+ \
+ /* normalize the data */ \
+ d[s->size-1] |= GMP_NUMB_HIGHBIT; \
+ a[2*s->size-1] = d[s->size-1] - 1; \
+ \
+ invert_pi1 (dinv, d[s->size-1], d[s->size-2]); \
+ \
+ speed_operand_src (s, a, 2*s->size); \
+ speed_operand_src (s, d, s->size); \
+ speed_operand_dst (s, q, s->size+1); \
+ speed_operand_dst (s, r, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+/* A remainder 2*s->size by s->size limbs */
+
+#define SPEED_ROUTINE_MPZ_MOD(function) \
+ { \
+ unsigned i; \
+ mpz_t a, d, r; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ mpz_init_set_n (d, s->yp, s->size); \
+ \
+ /* high part less than d, low part a duplicate copied in */ \
+ mpz_init_set_n (a, s->xp, s->size); \
+ mpz_mod (a, a, d); \
+ mpz_mul_2exp (a, a, GMP_LIMB_BITS * s->size); \
+ MPN_COPY (PTR(a), s->xp, s->size); \
+ \
+ mpz_init (r); \
+ \
+ speed_operand_src (s, PTR(a), SIZ(a)); \
+ speed_operand_src (s, PTR(d), SIZ(d)); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (r, a, d); \
+ while (--i != 0); \
+ return speed_endtime (); \
+ }
+
+#define SPEED_ROUTINE_MPN_PI1_DIV(function, INV, DMIN, QMIN) \
+ { \
+ unsigned i; \
+ mp_ptr dp, tp, ap, qp; \
+ gmp_pi1_t inv; \
+ double t; \
+ mp_size_t size1; \
+ TMP_DECL; \
+ \
+ size1 = (s->r == 0 ? 2 * s->size : s->r); \
+ \
+ SPEED_RESTRICT_COND (s->size >= DMIN); \
+ SPEED_RESTRICT_COND (size1 - s->size >= QMIN); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ap, size1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (dp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (qp, size1 - s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, size1, s->align_wp2); \
+ \
+ /* we don't fill in dividend completely when size1 > s->size */ \
+ MPN_COPY (ap, s->xp, s->size); \
+ MPN_COPY (ap + size1 - s->size, s->xp, s->size); \
+ \
+ MPN_COPY (dp, s->yp, s->size); \
+ \
+ /* normalize the data */ \
+ dp[s->size-1] |= GMP_NUMB_HIGHBIT; \
+ ap[size1 - 1] = dp[s->size - 1] - 1; \
+ \
+ invert_pi1 (inv, dp[s->size-1], dp[s->size-2]); \
+ \
+ speed_operand_src (s, ap, size1); \
+ speed_operand_dst (s, tp, size1); \
+ speed_operand_src (s, dp, s->size); \
+ speed_operand_dst (s, qp, size1 - s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ MPN_COPY (tp, ap, size1); \
+ function (qp, tp, size1, dp, s->size, INV); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_MPN_MU_DIV_Q(function,itchfn) \
+ { \
+ unsigned i; \
+ mp_ptr dp, tp, qp, scratch; \
+ double t; \
+ mp_size_t itch; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 2); \
+ \
+ itch = itchfn (2 * s->size, s->size, 0); \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (dp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (qp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, 2 * s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (scratch, itch, s->align_wp2); \
+ \
+ MPN_COPY (tp, s->xp, s->size); \
+ MPN_COPY (tp+s->size, s->xp, s->size); \
+ \
+ /* normalize the data */ \
+ dp[s->size-1] |= GMP_NUMB_HIGHBIT; \
+ tp[2*s->size-1] = dp[s->size-1] - 1; \
+ \
+ speed_operand_dst (s, qp, s->size); \
+ speed_operand_src (s, tp, 2 * s->size); \
+ speed_operand_src (s, dp, s->size); \
+ speed_operand_dst (s, scratch, itch); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ function (qp, tp, 2 * s->size, dp, s->size, scratch); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_MPN_MU_DIV_QR(function,itchfn) \
+ { \
+ unsigned i; \
+ mp_ptr dp, tp, qp, rp, scratch; \
+ double t; \
+ mp_size_t size1, itch; \
+ TMP_DECL; \
+ \
+ size1 = (s->r == 0 ? 2 * s->size : s->r); \
+ \
+ SPEED_RESTRICT_COND (s->size >= 2); \
+ SPEED_RESTRICT_COND (size1 >= s->size); \
+ \
+ itch = itchfn (size1, s->size, 0); \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (dp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (qp, size1 - s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, size1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (scratch, itch, s->align_wp2); \
+ SPEED_TMP_ALLOC_LIMBS (rp, s->size, s->align_wp2); /* alignment? */ \
+ \
+ /* we don't fill in dividend completely when size1 > s->size */ \
+ MPN_COPY (tp, s->xp, s->size); \
+ MPN_COPY (tp + size1 - s->size, s->xp, s->size); \
+ \
+ MPN_COPY (dp, s->yp, s->size); \
+ \
+ /* normalize the data */ \
+ dp[s->size-1] |= GMP_NUMB_HIGHBIT; \
+ tp[size1 - 1] = dp[s->size - 1] - 1; \
+ \
+ speed_operand_dst (s, qp, size1 - s->size); \
+ speed_operand_dst (s, rp, s->size); \
+ speed_operand_src (s, tp, size1); \
+ speed_operand_src (s, dp, s->size); \
+ speed_operand_dst (s, scratch, itch); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ function (qp, rp, tp, size1, dp, s->size, scratch); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_MPN_MUPI_DIV_QR(function,itchfn) \
+ { \
+ unsigned i; \
+ mp_ptr dp, tp, qp, rp, ip, scratch, tmp; \
+ double t; \
+ mp_size_t size1, itch; \
+ TMP_DECL; \
+ \
+ size1 = (s->r == 0 ? 2 * s->size : s->r); \
+ \
+ SPEED_RESTRICT_COND (s->size >= 2); \
+ SPEED_RESTRICT_COND (size1 >= s->size); \
+ \
+ itch = itchfn (size1, s->size, s->size); \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (dp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (qp, size1 - s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, size1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (scratch, itch, s->align_wp2); \
+ SPEED_TMP_ALLOC_LIMBS (rp, s->size, s->align_wp2); /* alignment? */ \
+ SPEED_TMP_ALLOC_LIMBS (ip, s->size, s->align_wp2); /* alignment? */ \
+ \
+ /* we don't fill in dividend completely when size1 > s->size */ \
+ MPN_COPY (tp, s->xp, s->size); \
+ MPN_COPY (tp + size1 - s->size, s->xp, s->size); \
+ \
+ MPN_COPY (dp, s->yp, s->size); \
+ \
+ /* normalize the data */ \
+ dp[s->size-1] |= GMP_NUMB_HIGHBIT; \
+ tp[size1 - 1] = dp[s->size-1] - 1; \
+ \
+ tmp = TMP_ALLOC_LIMBS (mpn_invert_itch (s->size)); \
+ mpn_invert (ip, dp, s->size, tmp); \
+ \
+ speed_operand_dst (s, qp, size1 - s->size); \
+ speed_operand_dst (s, rp, s->size); \
+ speed_operand_src (s, tp, size1); \
+ speed_operand_src (s, dp, s->size); \
+ speed_operand_src (s, ip, s->size); \
+ speed_operand_dst (s, scratch, itch); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ function (qp, rp, tp, size1, dp, s->size, ip, s->size, scratch); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_PI1_BDIV_QR(function) \
+ { \
+ unsigned i; \
+ mp_ptr dp, tp, ap, qp; \
+ mp_limb_t inv; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ap, 2*s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (dp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (qp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, 2*s->size, s->align_wp2); \
+ \
+ MPN_COPY (ap, s->xp, s->size); \
+ MPN_COPY (ap+s->size, s->xp, s->size); \
+ \
+ /* divisor must be odd */ \
+ MPN_COPY (dp, s->yp, s->size); \
+ dp[0] |= 1; \
+ binvert_limb (inv, dp[0]); \
+ inv = -inv; \
+ \
+ speed_operand_src (s, ap, 2*s->size); \
+ speed_operand_dst (s, tp, 2*s->size); \
+ speed_operand_src (s, dp, s->size); \
+ speed_operand_dst (s, qp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ MPN_COPY (tp, ap, 2*s->size); \
+ function (qp, tp, 2*s->size, dp, s->size, inv); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_MPN_PI1_BDIV_Q(function) \
+ { \
+ unsigned i; \
+ mp_ptr dp, tp, qp; \
+ mp_limb_t inv; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (dp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (qp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, s->size, s->align_wp2); \
+ \
+ /* divisor must be odd */ \
+ MPN_COPY (dp, s->yp, s->size); \
+ dp[0] |= 1; \
+ binvert_limb (inv, dp[0]); \
+ inv = -inv; \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, tp, s->size); \
+ speed_operand_src (s, dp, s->size); \
+ speed_operand_dst (s, qp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ MPN_COPY (tp, s->xp, s->size); \
+ function (qp, tp, s->size, dp, s->size, inv); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_MPN_MU_BDIV_Q(function,itchfn) \
+ { \
+ unsigned i; \
+ mp_ptr dp, qp, scratch; \
+ double t; \
+ mp_size_t itch; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 2); \
+ \
+ itch = itchfn (s->size, s->size); \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (dp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (qp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (scratch, itch, s->align_wp2); \
+ \
+ /* divisor must be odd */ \
+ MPN_COPY (dp, s->yp, s->size); \
+ dp[0] |= 1; \
+ \
+ speed_operand_dst (s, qp, s->size); \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, dp, s->size); \
+ speed_operand_dst (s, scratch, itch); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ function (qp, s->xp, s->size, dp, s->size, scratch); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_MPN_MU_BDIV_QR(function,itchfn) \
+ { \
+ unsigned i; \
+ mp_ptr dp, tp, qp, rp, scratch; \
+ double t; \
+ mp_size_t itch; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 2); \
+ \
+ itch = itchfn (2 * s->size, s->size); \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (dp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (qp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, 2 * s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (scratch, itch, s->align_wp2); \
+ SPEED_TMP_ALLOC_LIMBS (rp, s->size, s->align_wp2); /* alignment? */ \
+ \
+ MPN_COPY (tp, s->xp, s->size); \
+ MPN_COPY (tp+s->size, s->xp, s->size); \
+ \
+ /* divisor must be odd */ \
+ MPN_COPY (dp, s->yp, s->size); \
+ dp[0] |= 1; \
+ \
+ speed_operand_dst (s, qp, s->size); \
+ speed_operand_dst (s, rp, s->size); \
+ speed_operand_src (s, tp, 2 * s->size); \
+ speed_operand_src (s, dp, s->size); \
+ speed_operand_dst (s, scratch, itch); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ function (qp, rp, tp, 2 * s->size, dp, s->size, scratch); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_BROOT(function) \
+ { \
+ SPEED_RESTRICT_COND (s->r & 1); \
+ s->xp[0] |= 1; \
+ SPEED_ROUTINE_MPN_UNARY_1_CALL \
+ ((*function) (wp, s->xp, s->size, s->r)); \
+ }
+
+#define SPEED_ROUTINE_MPN_BROOTINV(function, itch) \
+ { \
+ mp_ptr wp, tp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ TMP_MARK; \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ SPEED_RESTRICT_COND (s->r & 1); \
+ wp = TMP_ALLOC_LIMBS (s->size); \
+ tp = TMP_ALLOC_LIMBS ( (itch)); \
+ s->xp[0] |= 1; \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ (*function) (wp, s->xp, s->size, s->r, tp); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_INVERT(function,itchfn) \
+ { \
+ long i; \
+ mp_ptr up, tp, ip; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ip, s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (up, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, itchfn (s->size), s->align_wp); \
+ \
+ MPN_COPY (up, s->xp, s->size); \
+ \
+ /* normalize the data */ \
+ up[s->size-1] |= GMP_NUMB_HIGHBIT; \
+ \
+ speed_operand_src (s, up, s->size); \
+ speed_operand_dst (s, tp, s->size); \
+ speed_operand_dst (s, ip, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (ip, up, s->size, tp); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_INVERTAPPR(function,itchfn) \
+ { \
+ long i; \
+ mp_ptr up, tp, ip; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ip, s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (up, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, itchfn (s->size), s->align_wp); \
+ \
+ MPN_COPY (up, s->xp, s->size); \
+ \
+ /* normalize the data */ \
+ up[s->size-1] |= GMP_NUMB_HIGHBIT; \
+ \
+ speed_operand_src (s, up, s->size); \
+ speed_operand_dst (s, tp, s->size); \
+ speed_operand_dst (s, ip, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (ip, up, s->size, tp); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_NI_INVERTAPPR(function,itchfn) \
+ { \
+ long i; \
+ mp_ptr up, tp, ip; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 3); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ip, s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (up, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, itchfn (s->size), s->align_wp); \
+ \
+ MPN_COPY (up, s->xp, s->size); \
+ \
+ /* normalize the data */ \
+ up[s->size-1] |= GMP_NUMB_HIGHBIT; \
+ \
+ speed_operand_src (s, up, s->size); \
+ speed_operand_dst (s, tp, s->size); \
+ speed_operand_dst (s, ip, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (ip, up, s->size, tp); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_BINVERT(function,itchfn) \
+ { \
+ long i; \
+ mp_ptr up, tp, ip; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ip, s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (up, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, itchfn (s->size), s->align_wp); \
+ \
+ MPN_COPY (up, s->xp, s->size); \
+ \
+ /* normalize the data */ \
+ up[0] |= 1; \
+ \
+ speed_operand_src (s, up, s->size); \
+ speed_operand_dst (s, tp, s->size); \
+ speed_operand_dst (s, ip, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (ip, up, s->size, tp); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_SEC_INVERT(function,itchfn) \
+ { \
+ long i; \
+ mp_ptr up, mp, tp, ip; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ip, s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (up, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (mp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, itchfn (s->size), s->align_wp); \
+ \
+ speed_operand_src (s, up, s->size); \
+ speed_operand_dst (s, tp, s->size); \
+ speed_operand_dst (s, ip, s->size); \
+ speed_cache_fill (s); \
+ \
+ MPN_COPY (mp, s->yp, s->size); \
+ /* Must be odd */ \
+ mp[0] |= 1; \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ MPN_COPY (up, s->xp, s->size); \
+ function (ip, up, mp, s->size, 2*s->size*GMP_NUMB_BITS, tp); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_REDC_1(function) \
+ { \
+ unsigned i; \
+ mp_ptr cp, mp, tp, ap; \
+ mp_limb_t inv; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ap, 2*s->size+1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (mp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (cp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, 2*s->size+1, s->align_wp2); \
+ \
+ MPN_COPY (ap, s->xp, s->size); \
+ MPN_COPY (ap+s->size, s->xp, s->size); \
+ \
+ /* modulus must be odd */ \
+ MPN_COPY (mp, s->yp, s->size); \
+ mp[0] |= 1; \
+ binvert_limb (inv, mp[0]); \
+ inv = -inv; \
+ \
+ speed_operand_src (s, ap, 2*s->size+1); \
+ speed_operand_dst (s, tp, 2*s->size+1); \
+ speed_operand_src (s, mp, s->size); \
+ speed_operand_dst (s, cp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ MPN_COPY (tp, ap, 2*s->size); \
+ function (cp, tp, mp, s->size, inv); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_REDC_2(function) \
+ { \
+ unsigned i; \
+ mp_ptr cp, mp, tp, ap; \
+ mp_limb_t invp[2]; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ap, 2*s->size+1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (mp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (cp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, 2*s->size+1, s->align_wp2); \
+ \
+ MPN_COPY (ap, s->xp, s->size); \
+ MPN_COPY (ap+s->size, s->xp, s->size); \
+ \
+ /* modulus must be odd */ \
+ MPN_COPY (mp, s->yp, s->size); \
+ mp[0] |= 1; \
+ mpn_binvert (invp, mp, 2, tp); \
+ invp[0] = -invp[0]; invp[1] = ~invp[1]; \
+ \
+ speed_operand_src (s, ap, 2*s->size+1); \
+ speed_operand_dst (s, tp, 2*s->size+1); \
+ speed_operand_src (s, mp, s->size); \
+ speed_operand_dst (s, cp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ MPN_COPY (tp, ap, 2*s->size); \
+ function (cp, tp, mp, s->size, invp); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+#define SPEED_ROUTINE_REDC_N(function) \
+ { \
+ unsigned i; \
+ mp_ptr cp, mp, tp, ap, invp; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size > 8); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (ap, 2*s->size+1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (mp, s->size, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (cp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (tp, 2*s->size+1, s->align_wp2); \
+ SPEED_TMP_ALLOC_LIMBS (invp, s->size, s->align_wp2); /* align? */ \
+ \
+ MPN_COPY (ap, s->xp, s->size); \
+ MPN_COPY (ap+s->size, s->xp, s->size); \
+ \
+ /* modulus must be odd */ \
+ MPN_COPY (mp, s->yp, s->size); \
+ mp[0] |= 1; \
+ mpn_binvert (invp, mp, s->size, tp); \
+ \
+ speed_operand_src (s, ap, 2*s->size+1); \
+ speed_operand_dst (s, tp, 2*s->size+1); \
+ speed_operand_src (s, mp, s->size); \
+ speed_operand_dst (s, cp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do { \
+ MPN_COPY (tp, ap, 2*s->size); \
+ function (cp, tp, mp, s->size, invp); \
+ } while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+#define SPEED_ROUTINE_MPN_POPCOUNT(function) \
+ { \
+ unsigned i; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (s->xp, s->size); \
+ while (--i != 0); \
+ \
+ return speed_endtime (); \
+ }
+
+#define SPEED_ROUTINE_MPN_HAMDIST(function) \
+ { \
+ unsigned i; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (s->xp, s->yp, s->size); \
+ while (--i != 0); \
+ \
+ return speed_endtime (); \
+ }
+
+
+#define SPEED_ROUTINE_MPZ_UI(function) \
+ { \
+ mpz_t z; \
+ unsigned i; \
+ double t; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ mpz_init (z); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (z, s->size); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ mpz_clear (z); \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPZ_FAC_UI(function) SPEED_ROUTINE_MPZ_UI(function)
+#define SPEED_ROUTINE_MPZ_FIB_UI(function) SPEED_ROUTINE_MPZ_UI(function)
+#define SPEED_ROUTINE_MPZ_LUCNUM_UI(function) SPEED_ROUTINE_MPZ_UI(function)
+
+
+#define SPEED_ROUTINE_MPZ_2_UI(function) \
+ { \
+ mpz_t z, z2; \
+ unsigned i; \
+ double t; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ mpz_init (z); \
+ mpz_init (z2); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (z, z2, s->size); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ mpz_clear (z); \
+ mpz_clear (z2); \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPZ_FIB2_UI(function) SPEED_ROUTINE_MPZ_2_UI(function)
+#define SPEED_ROUTINE_MPZ_LUCNUM2_UI(function) SPEED_ROUTINE_MPZ_2_UI(function)
+
+
+#define SPEED_ROUTINE_MPN_FIB2_UI(function) \
+ { \
+ mp_ptr fp, f1p; \
+ mp_size_t alloc; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ TMP_MARK; \
+ alloc = MPN_FIB2_SIZE (s->size); \
+ SPEED_TMP_ALLOC_LIMBS (fp, alloc, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (f1p, alloc, s->align_yp); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (fp, f1p, s->size); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+
+/* Calculate b^e mod m for random b and m of s->size limbs and random e of 6
+ limbs. m is forced to odd so that redc can be used. e is limited in
+ size so the calculation doesn't take too long. */
+#define SPEED_ROUTINE_MPZ_POWM(function) \
+ { \
+ mpz_t r, b, e, m; \
+ unsigned i; \
+ double t; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ mpz_init (r); \
+ mpz_init_set_n (b, s->xp, s->size); \
+ mpz_init_set_n (m, s->yp, s->size); \
+ mpz_setbit (m, 0); /* force m to odd */ \
+ mpz_init_set_n (e, s->xp_block, 6); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (r, b, e, m); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ mpz_clear (r); \
+ mpz_clear (b); \
+ mpz_clear (e); \
+ mpz_clear (m); \
+ return t; \
+ }
+
+/* (m-2)^0xAAAAAAAA mod m */
+#define SPEED_ROUTINE_MPZ_POWM_UI(function) \
+ { \
+ mpz_t r, b, m; \
+ unsigned long e; \
+ unsigned i; \
+ double t; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ mpz_init (r); \
+ \
+ /* force m to odd */ \
+ mpz_init (m); \
+ mpz_set_n (m, s->xp, s->size); \
+ PTR(m)[0] |= 1; \
+ \
+ e = (~ (unsigned long) 0) / 3; \
+ if (s->r != 0) \
+ e = s->r; \
+ \
+ mpz_init_set (b, m); \
+ mpz_sub_ui (b, b, 2); \
+/* printf ("%X\n", mpz_get_ui(m)); */ \
+ i = s->reps; \
+ speed_starttime (); \
+ do \
+ function (r, b, e, m); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ mpz_clear (r); \
+ mpz_clear (b); \
+ mpz_clear (m); \
+ return t; \
+ }
+
+
+#define SPEED_ROUTINE_MPN_ADDSUB_CALL(call) \
+ { \
+ mp_ptr wp, wp2, xp, yp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (wp2, s->size, s->align_wp2); \
+ xp = s->xp; \
+ yp = s->yp; \
+ \
+ if (s->r == 0) ; \
+ else if (s->r == 1) { xp = wp; } \
+ else if (s->r == 2) { yp = wp2; } \
+ else if (s->r == 3) { xp = wp; yp = wp2; } \
+ else if (s->r == 4) { xp = wp2; yp = wp; } \
+ else { \
+ TMP_FREE; \
+ return -1.0; \
+ } \
+ if (xp != s->xp) MPN_COPY (xp, s->xp, s->size); \
+ if (yp != s->yp) MPN_COPY (yp, s->yp, s->size); \
+ \
+ speed_operand_src (s, xp, s->size); \
+ speed_operand_src (s, yp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_operand_dst (s, wp2, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_ADDSUB_N(function) \
+ SPEED_ROUTINE_MPN_ADDSUB_CALL \
+ (function (wp, wp2, xp, yp, s->size));
+
+#define SPEED_ROUTINE_MPN_ADDSUB_NC(function) \
+ SPEED_ROUTINE_MPN_ADDSUB_CALL \
+ (function (wp, wp2, xp, yp, s->size, 0));
+
+
+/* Doing an Nx1 gcd with the given r. */
+#define SPEED_ROUTINE_MPN_GCD_1N(function) \
+ { \
+ mp_ptr xp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ SPEED_RESTRICT_COND (s->r != 0); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (xp, s->size, s->align_xp); \
+ MPN_COPY (xp, s->xp, s->size); \
+ xp[0] |= refmpn_zero_p (xp, s->size); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (xp, s->size, s->r); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+/* SPEED_BLOCK_SIZE many one GCDs of s->size bits each. */
+
+#define SPEED_ROUTINE_MPN_GCD_1_CALL(setup, call) \
+ { \
+ unsigned i, j; \
+ mp_ptr px, py; \
+ mp_limb_t x_mask, y_mask; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ SPEED_RESTRICT_COND (s->size <= mp_bits_per_limb); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (px, SPEED_BLOCK_SIZE, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (py, SPEED_BLOCK_SIZE, s->align_yp); \
+ MPN_COPY (px, s->xp_block, SPEED_BLOCK_SIZE); \
+ MPN_COPY (py, s->yp_block, SPEED_BLOCK_SIZE); \
+ \
+ x_mask = MP_LIMB_T_LOWBITMASK (s->size); \
+ y_mask = MP_LIMB_T_LOWBITMASK (s->r != 0 ? s->r : s->size); \
+ for (i = 0; i < SPEED_BLOCK_SIZE; i++) \
+ { \
+ px[i] &= x_mask; px[i] += (px[i] == 0); \
+ py[i] &= y_mask; py[i] += (py[i] == 0); \
+ setup; \
+ } \
+ \
+ speed_operand_src (s, px, SPEED_BLOCK_SIZE); \
+ speed_operand_src (s, py, SPEED_BLOCK_SIZE); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ j = SPEED_BLOCK_SIZE; \
+ do \
+ { \
+ call; \
+ } \
+ while (--j != 0); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ \
+ s->time_divisor = SPEED_BLOCK_SIZE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_GCD_1(function) \
+ SPEED_ROUTINE_MPN_GCD_1_CALL( , function (&px[j-1], 1, py[j-1]))
+
+#define SPEED_ROUTINE_MPN_JACBASE(function) \
+ SPEED_ROUTINE_MPN_GCD_1_CALL \
+ ({ \
+ /* require x<y, y odd, y!=1 */ \
+ px[i] %= py[i]; \
+ px[i] |= 1; \
+ py[i] |= 1; \
+ if (py[i]==1) py[i]=3; \
+ }, \
+ function (px[j-1], py[j-1], 0))
+
+
+#define SPEED_ROUTINE_MPN_HGCD_CALL(func, itchfunc) \
+ { \
+ mp_size_t hgcd_init_itch, hgcd_itch; \
+ mp_ptr ap, bp, wp, tmp1; \
+ struct hgcd_matrix hgcd; \
+ int res; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ if (s->size < 2) \
+ return -1; \
+ \
+ TMP_MARK; \
+ \
+ SPEED_TMP_ALLOC_LIMBS (ap, s->size + 1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (bp, s->size + 1, s->align_yp); \
+ \
+ s->xp[s->size - 1] |= 1; \
+ s->yp[s->size - 1] |= 1; \
+ \
+ hgcd_init_itch = MPN_HGCD_MATRIX_INIT_ITCH (s->size); \
+ hgcd_itch = itchfunc (s->size); \
+ \
+ SPEED_TMP_ALLOC_LIMBS (tmp1, hgcd_init_itch, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (wp, hgcd_itch, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, ap, s->size + 1); \
+ speed_operand_dst (s, bp, s->size + 1); \
+ speed_operand_dst (s, wp, hgcd_itch); \
+ speed_operand_dst (s, tmp1, hgcd_init_itch); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ MPN_COPY (ap, s->xp, s->size); \
+ MPN_COPY (bp, s->yp, s->size); \
+ mpn_hgcd_matrix_init (&hgcd, s->size, tmp1); \
+ res = func (ap, bp, s->size, &hgcd, wp); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_HGCD_REDUCE_CALL(func, itchfunc) \
+ { \
+ mp_size_t hgcd_init_itch, hgcd_step_itch; \
+ mp_ptr ap, bp, wp, tmp1; \
+ struct hgcd_matrix hgcd; \
+ mp_size_t p = s->size/2; \
+ int res; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ if (s->size < 2) \
+ return -1; \
+ \
+ TMP_MARK; \
+ \
+ SPEED_TMP_ALLOC_LIMBS (ap, s->size + 1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (bp, s->size + 1, s->align_yp); \
+ \
+ s->xp[s->size - 1] |= 1; \
+ s->yp[s->size - 1] |= 1; \
+ \
+ hgcd_init_itch = MPN_HGCD_MATRIX_INIT_ITCH (s->size); \
+ hgcd_step_itch = itchfunc (s->size, p); \
+ \
+ SPEED_TMP_ALLOC_LIMBS (tmp1, hgcd_init_itch, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (wp, hgcd_step_itch, s->align_wp); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, s->yp, s->size); \
+ speed_operand_dst (s, ap, s->size + 1); \
+ speed_operand_dst (s, bp, s->size + 1); \
+ speed_operand_dst (s, wp, hgcd_step_itch); \
+ speed_operand_dst (s, tmp1, hgcd_init_itch); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ MPN_COPY (ap, s->xp, s->size); \
+ MPN_COPY (bp, s->yp, s->size); \
+ mpn_hgcd_matrix_init (&hgcd, s->size, tmp1); \
+ res = func (&hgcd, ap, bp, s->size, p, wp); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ TMP_FREE; \
+ return t; \
+ }
+
+/* Run some GCDs of s->size limbs each. The number of different data values
+ is decreased as s->size**2, since GCD is a quadratic algorithm.
+ SPEED_ROUTINE_MPN_GCD runs more times than SPEED_ROUTINE_MPN_GCDEXT
+ though, because the plain gcd is about twice as fast as gcdext. */
+
+#define SPEED_ROUTINE_MPN_GCD_CALL(datafactor, call) \
+ { \
+ unsigned i; \
+ mp_size_t j, pieces, psize; \
+ mp_ptr wp, wp2, xtmp, ytmp, px, py; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (xtmp, s->size+1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (ytmp, s->size+1, s->align_yp); \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size+1, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (wp2, s->size+1, s->align_wp2); \
+ \
+ pieces = SPEED_BLOCK_SIZE * datafactor / s->size / s->size; \
+ pieces = MIN (pieces, SPEED_BLOCK_SIZE / s->size); \
+ pieces = MAX (pieces, 1); \
+ \
+ psize = pieces * s->size; \
+ px = TMP_ALLOC_LIMBS (psize); \
+ py = TMP_ALLOC_LIMBS (psize); \
+ MPN_COPY (px, pieces==1 ? s->xp : s->xp_block, psize); \
+ MPN_COPY (py, pieces==1 ? s->yp : s->yp_block, psize); \
+ \
+ /* Requirements: x >= y, y must be odd, high limbs != 0. \
+ No need to ensure random numbers are really great. */ \
+ for (j = 0; j < pieces; j++) \
+ { \
+ mp_ptr x = px + j * s->size; \
+ mp_ptr y = py + j * s->size; \
+ if (x[s->size - 1] == 0) x[s->size - 1] = 1; \
+ if (y[s->size - 1] == 0) y[s->size - 1] = 1; \
+ \
+ if (x[s->size - 1] < y[s->size - 1]) \
+ MP_LIMB_T_SWAP (x[s->size - 1], y[s->size - 1]); \
+ else if (x[s->size - 1] == y[s->size - 1]) \
+ { \
+ x[s->size - 1] = 2; \
+ y[s->size - 1] = 1; \
+ } \
+ y[0] |= 1; \
+ } \
+ \
+ speed_operand_src (s, px, psize); \
+ speed_operand_src (s, py, psize); \
+ speed_operand_dst (s, xtmp, s->size); \
+ speed_operand_dst (s, ytmp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ j = pieces; \
+ do \
+ { \
+ MPN_COPY (xtmp, px+(j - 1)*s->size, s->size); \
+ MPN_COPY (ytmp, py+(j - 1)*s->size, s->size); \
+ call; \
+ } \
+ while (--j != 0); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ \
+ s->time_divisor = pieces; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_GCD(function) \
+ SPEED_ROUTINE_MPN_GCD_CALL (8, function (wp, xtmp, s->size, ytmp, s->size))
+
+#define SPEED_ROUTINE_MPN_GCDEXT(function) \
+ SPEED_ROUTINE_MPN_GCD_CALL \
+ (4, { mp_size_t wp2size; \
+ function (wp, wp2, &wp2size, xtmp, s->size, ytmp, s->size); })
+
+
+#define SPEED_ROUTINE_MPN_GCDEXT_ONE(function) \
+ { \
+ unsigned i; \
+ mp_size_t j, pieces, psize, wp2size; \
+ mp_ptr wp, wp2, xtmp, ytmp, px, py; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ \
+ SPEED_TMP_ALLOC_LIMBS (xtmp, s->size+1, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (ytmp, s->size+1, s->align_yp); \
+ MPN_COPY (xtmp, s->xp, s->size); \
+ MPN_COPY (ytmp, s->yp, s->size); \
+ \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size+1, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (wp2, s->size+1, s->align_wp2); \
+ \
+ pieces = SPEED_BLOCK_SIZE / 3; \
+ psize = 3 * pieces; \
+ px = TMP_ALLOC_LIMBS (psize); \
+ py = TMP_ALLOC_LIMBS (psize); \
+ MPN_COPY (px, s->xp_block, psize); \
+ MPN_COPY (py, s->yp_block, psize); \
+ \
+ /* x must have at least as many bits as y, \
+ high limbs must be non-zero */ \
+ for (j = 0; j < pieces; j++) \
+ { \
+ mp_ptr x = px+3*j; \
+ mp_ptr y = py+3*j; \
+ x[2] += (x[2] == 0); \
+ y[2] += (y[2] == 0); \
+ if (x[2] < y[2]) \
+ MP_LIMB_T_SWAP (x[2], y[2]); \
+ } \
+ \
+ speed_operand_src (s, px, psize); \
+ speed_operand_src (s, py, psize); \
+ speed_operand_dst (s, xtmp, s->size); \
+ speed_operand_dst (s, ytmp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ mp_ptr x = px; \
+ mp_ptr y = py; \
+ mp_ptr xth = &xtmp[s->size-3]; \
+ mp_ptr yth = &ytmp[s->size-3]; \
+ j = pieces; \
+ do \
+ { \
+ xth[0] = x[0], xth[1] = x[1], xth[2] = x[2]; \
+ yth[0] = y[0], yth[1] = y[1], yth[2] = y[2]; \
+ \
+ ytmp[0] |= 1; /* y must be odd, */ \
+ \
+ function (wp, wp2, &wp2size, xtmp, s->size, ytmp, s->size); \
+ \
+ x += 3; \
+ y += 3; \
+ } \
+ while (--j != 0); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ \
+ s->time_divisor = pieces; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPZ_JACOBI(function) \
+ { \
+ mpz_t a, b; \
+ unsigned i; \
+ mp_size_t j, pieces, psize; \
+ mp_ptr px, py; \
+ double t; \
+ TMP_DECL; \
+ \
+ TMP_MARK; \
+ pieces = SPEED_BLOCK_SIZE / MAX (s->size, 1); \
+ pieces = MAX (pieces, 1); \
+ s->time_divisor = pieces; \
+ \
+ psize = pieces * s->size; \
+ px = TMP_ALLOC_LIMBS (psize); \
+ py = TMP_ALLOC_LIMBS (psize); \
+ MPN_COPY (px, pieces==1 ? s->xp : s->xp_block, psize); \
+ MPN_COPY (py, pieces==1 ? s->yp : s->yp_block, psize); \
+ \
+ for (j = 0; j < pieces; j++) \
+ { \
+ mp_ptr x = px+j*s->size; \
+ mp_ptr y = py+j*s->size; \
+ \
+ /* y odd */ \
+ y[0] |= 1; \
+ \
+ /* high limbs non-zero */ \
+ if (x[s->size-1] == 0) x[s->size-1] = 1; \
+ if (y[s->size-1] == 0) y[s->size-1] = 1; \
+ } \
+ \
+ SIZ(a) = s->size; \
+ SIZ(b) = s->size; \
+ \
+ speed_operand_src (s, px, psize); \
+ speed_operand_src (s, py, psize); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ j = pieces; \
+ do \
+ { \
+ PTR(a) = px+(j-1)*s->size; \
+ PTR(b) = py+(j-1)*s->size; \
+ function (a, b); \
+ } \
+ while (--j != 0); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_DIVREM_2(function) \
+ { \
+ mp_ptr wp, xp; \
+ mp_limb_t yp[2]; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 2); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (xp, s->size, s->align_xp); \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ /* source is destroyed */ \
+ MPN_COPY (xp, s->xp, s->size); \
+ \
+ /* divisor must be normalized */ \
+ MPN_COPY (yp, s->yp_block, 2); \
+ yp[1] |= GMP_NUMB_HIGHBIT; \
+ \
+ speed_operand_src (s, xp, s->size); \
+ speed_operand_src (s, yp, 2); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, 0, xp, s->size, yp); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_DIV_QR_1(function) \
+ { \
+ mp_ptr wp, xp; \
+ mp_limb_t d; \
+ mp_limb_t r; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ d = s->r; \
+ if (d == 0) \
+ d = 1; \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ r = function (wp, wp+s->size-1, s->xp, s->size, d); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_DIV_QR_1N_PI1(function) \
+ { \
+ mp_ptr wp, xp; \
+ mp_limb_t d, dinv; \
+ mp_limb_t r; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ d = s->r; \
+ /* divisor must be normalized */ \
+ SPEED_RESTRICT_COND (d & GMP_NUMB_HIGHBIT); \
+ invert_limb (dinv, d); \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ r = function (wp, s->xp, s->size, 0, d, dinv); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_DIV_QR_2(function, norm) \
+ { \
+ mp_ptr wp, xp; \
+ mp_limb_t yp[2]; \
+ mp_limb_t rp[2]; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 2); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ \
+ /* divisor must be normalized */ \
+ MPN_COPY (yp, s->yp_block, 2); \
+ if (norm) \
+ yp[1] |= GMP_NUMB_HIGHBIT; \
+ else \
+ { \
+ yp[1] &= ~GMP_NUMB_HIGHBIT; \
+ if (yp[1] == 0) \
+ yp[1] = 1; \
+ } \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_src (s, yp, 2); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_operand_dst (s, rp, 2); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, rp, s->xp, s->size, yp); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MODLIMB_INVERT(function) \
+ { \
+ unsigned i, j; \
+ mp_ptr xp; \
+ mp_limb_t n = 1; \
+ double t; \
+ \
+ xp = s->xp_block-1; \
+ \
+ speed_operand_src (s, s->xp_block, SPEED_BLOCK_SIZE); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ j = SPEED_BLOCK_SIZE; \
+ do \
+ { \
+ /* randomized but successively dependent */ \
+ n += (xp[j] << 1); \
+ \
+ function (n, n); \
+ } \
+ while (--j != 0); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ /* make sure the compiler won't optimize away n */ \
+ noop_1 (n); \
+ \
+ s->time_divisor = SPEED_BLOCK_SIZE; \
+ return t; \
+ }
+
+
+#define SPEED_ROUTINE_MPN_SQRTREM(function) \
+ { \
+ mp_ptr wp, wp2; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (wp2, s->size, s->align_wp2); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_operand_dst (s, wp2, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, wp2, s->xp, s->size); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_ROOTREM(function) \
+ { \
+ mp_ptr wp, wp2; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ SPEED_TMP_ALLOC_LIMBS (wp2, s->size, s->align_wp2); \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_operand_dst (s, wp2, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (wp, wp2, s->xp, s->size, s->r); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+/* s->size controls the number of limbs in the input, s->r is the base, or
+ decimal by default. */
+#define SPEED_ROUTINE_MPN_GET_STR(function) \
+ { \
+ unsigned char *wp; \
+ mp_size_t wn; \
+ mp_ptr xp; \
+ int base; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ base = s->r == 0 ? 10 : s->r; \
+ SPEED_RESTRICT_COND (base >= 2 && base <= 256); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (xp, s->size + 1, s->align_xp); \
+ \
+ MPN_SIZEINBASE (wn, s->xp, s->size, base); \
+ wp = TMP_ALLOC (wn); \
+ \
+ /* use this during development to guard against overflowing wp */ \
+ /* \
+ MPN_COPY (xp, s->xp, s->size); \
+ ASSERT_ALWAYS (mpn_get_str (wp, base, xp, s->size) <= wn); \
+ */ \
+ \
+ speed_operand_src (s, s->xp, s->size); \
+ speed_operand_dst (s, xp, s->size); \
+ speed_operand_dst (s, (mp_ptr) wp, wn/GMP_LIMB_BYTES); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ MPN_COPY (xp, s->xp, s->size); \
+ function (wp, base, xp, s->size); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+/* s->size controls the number of digits in the input, s->r is the base, or
+ decimal by default. */
+#define SPEED_ROUTINE_MPN_SET_STR_CALL(call) \
+ { \
+ unsigned char *xp; \
+ mp_ptr wp; \
+ mp_size_t wn; \
+ unsigned i; \
+ int base; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 1); \
+ \
+ base = s->r == 0 ? 10 : s->r; \
+ SPEED_RESTRICT_COND (base >= 2 && base <= 256); \
+ \
+ TMP_MARK; \
+ \
+ xp = TMP_ALLOC (s->size); \
+ for (i = 0; i < s->size; i++) \
+ xp[i] = s->xp[i] % base; \
+ \
+ LIMBS_PER_DIGIT_IN_BASE (wn, s->size, base); \
+ SPEED_TMP_ALLOC_LIMBS (wp, wn, s->align_wp); \
+ \
+ /* use this during development to check wn is big enough */ \
+ /* \
+ ASSERT_ALWAYS (mpn_set_str (wp, xp, s->size, base) <= wn); \
+ */ \
+ \
+ speed_operand_src (s, (mp_ptr) xp, s->size/GMP_LIMB_BYTES); \
+ speed_operand_dst (s, wp, wn); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+
+/* Run an accel gcd find_a() function over various data values. A set of
+ values is used in case some run particularly fast or slow. The size
+ parameter is ignored, the amount of data tested is fixed. */
+
+#define SPEED_ROUTINE_MPN_GCD_FINDA(function) \
+ { \
+ unsigned i, j; \
+ mp_limb_t cp[SPEED_BLOCK_SIZE][2]; \
+ double t; \
+ TMP_DECL; \
+ \
+ TMP_MARK; \
+ \
+ /* low must be odd, high must be non-zero */ \
+ for (i = 0; i < SPEED_BLOCK_SIZE; i++) \
+ { \
+ cp[i][0] = s->xp_block[i] | 1; \
+ cp[i][1] = s->yp_block[i] + (s->yp_block[i] == 0); \
+ } \
+ \
+ speed_operand_src (s, &cp[0][0], 2*SPEED_BLOCK_SIZE); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ j = SPEED_BLOCK_SIZE; \
+ do \
+ { \
+ function (cp[j-1]); \
+ } \
+ while (--j != 0); \
+ } \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ \
+ s->time_divisor = SPEED_BLOCK_SIZE; \
+ return t; \
+ }
+
+
+/* "call" should do "count_foo_zeros(c,n)".
+ Give leading=1 if foo is leading zeros, leading=0 for trailing.
+ Give zero=1 if n=0 is allowed in the call, zero=0 if not. */
+
+#define SPEED_ROUTINE_COUNT_ZEROS_A(leading, zero) \
+ { \
+ mp_ptr xp; \
+ int i, c; \
+ unsigned j; \
+ mp_limb_t n; \
+ double t; \
+ TMP_DECL; \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (xp, SPEED_BLOCK_SIZE, s->align_xp); \
+ \
+ if (! speed_routine_count_zeros_setup (s, xp, leading, zero)) \
+ return -1.0; \
+ speed_operand_src (s, xp, SPEED_BLOCK_SIZE); \
+ speed_cache_fill (s); \
+ \
+ c = 0; \
+ speed_starttime (); \
+ j = s->reps; \
+ do { \
+ for (i = 0; i < SPEED_BLOCK_SIZE; i++) \
+ { \
+ n = xp[i]; \
+ n ^= c; \
+
+#define SPEED_ROUTINE_COUNT_ZEROS_B() \
+ } \
+ } while (--j != 0); \
+ t = speed_endtime (); \
+ \
+ /* don't let c go dead */ \
+ noop_1 (c); \
+ \
+ s->time_divisor = SPEED_BLOCK_SIZE; \
+ \
+ TMP_FREE; \
+ return t; \
+ } \
+
+#define SPEED_ROUTINE_COUNT_ZEROS_C(call, leading, zero) \
+ do { \
+ SPEED_ROUTINE_COUNT_ZEROS_A (leading, zero); \
+ call; \
+ SPEED_ROUTINE_COUNT_ZEROS_B (); \
+ } while (0) \
+
+#define SPEED_ROUTINE_COUNT_LEADING_ZEROS_C(call,zero) \
+ SPEED_ROUTINE_COUNT_ZEROS_C (call, 1, zero)
+#define SPEED_ROUTINE_COUNT_LEADING_ZEROS(fun) \
+ SPEED_ROUTINE_COUNT_ZEROS_C (fun (c, n), 1, 0)
+
+#define SPEED_ROUTINE_COUNT_TRAILING_ZEROS_C(call,zero) \
+ SPEED_ROUTINE_COUNT_ZEROS_C (call, 0, zero)
+#define SPEED_ROUTINE_COUNT_TRAILING_ZEROS(call) \
+ SPEED_ROUTINE_COUNT_ZEROS_C (fun (c, n), 0, 0)
+
+
+#define SPEED_ROUTINE_INVERT_LIMB_CALL(call) \
+ { \
+ unsigned i, j; \
+ mp_limb_t d, dinv=0; \
+ mp_ptr xp = s->xp_block - 1; \
+ \
+ s->time_divisor = SPEED_BLOCK_SIZE; \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ { \
+ j = SPEED_BLOCK_SIZE; \
+ do \
+ { \
+ d = dinv ^ xp[j]; \
+ d |= GMP_LIMB_HIGHBIT; \
+ do { call; } while (0); \
+ } \
+ while (--j != 0); \
+ } \
+ while (--i != 0); \
+ \
+ /* don't let the compiler optimize everything away */ \
+ noop_1 (dinv); \
+ \
+ return speed_endtime(); \
+ }
+
+
+#define SPEED_ROUTINE_MPN_BACK_TO_BACK(function) \
+ { \
+ unsigned i; \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ function (); \
+ while (--i != 0); \
+ return speed_endtime (); \
+ }
+
+
+#define SPEED_ROUTINE_MPN_ZERO_CALL(call) \
+ { \
+ mp_ptr wp; \
+ unsigned i; \
+ double t; \
+ TMP_DECL; \
+ \
+ SPEED_RESTRICT_COND (s->size >= 0); \
+ \
+ TMP_MARK; \
+ SPEED_TMP_ALLOC_LIMBS (wp, s->size, s->align_wp); \
+ speed_operand_dst (s, wp, s->size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ call; \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ TMP_FREE; \
+ return t; \
+ }
+
+#define SPEED_ROUTINE_MPN_ZERO(function) \
+ SPEED_ROUTINE_MPN_ZERO_CALL (function (wp, s->size))
+
+
+#endif
diff --git a/gmp/tune/time.c b/gmp/tune/time.c
new file mode 100644
index 0000000000..0178b345af
--- /dev/null
+++ b/gmp/tune/time.c
@@ -0,0 +1,1597 @@
+/* Time routines for speed measurements.
+
+Copyright 1999-2004, 2010-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* Usage:
+
+ The code in this file implements the lowest level of time measuring,
+ simple one-time measuring of time between two points.
+
+ void speed_starttime (void)
+ double speed_endtime (void)
+ Call speed_starttime to start measuring, and then call speed_endtime
+ when done.
+
+ speed_endtime returns the time taken, in seconds. Or if the timebase
+ is in CPU cycles and the CPU frequency is unknown then speed_endtime
+ returns cycles. Applications can identify the cycles return by
+ checking for speed_cycletime (described below) equal to 1.0.
+
+ If some sort of temporary glitch occurs then speed_endtime returns
+ 0.0. Currently this is for various cases where a negative time has
+ occurred. This unfortunately occurs with getrusage on some systems,
+ and with the hppa cycle counter on hpux.
+
+ double speed_cycletime
+ The time in seconds for each CPU cycle. For example on a 100 MHz CPU
+ this would be 1.0e-8.
+
+ If the CPU frequency is unknown, then speed_cycletime is either 0.0
+ or 1.0. It's 0.0 when speed_endtime is returning seconds, or it's
+ 1.0 when speed_endtime is returning cycles.
+
+ It may be noted that "speed_endtime() / speed_cycletime" gives a
+ measured time in cycles, irrespective of whether speed_endtime is
+ returning cycles or seconds. (Assuming cycles can be had, ie. it's
+ either cycles already or the cpu frequency is known. See also
+ speed_cycletime_need_cycles below.)
+
+ double speed_unittime
+ The unit of time measurement accuracy for the timing method in use.
+ This is in seconds or cycles, as per speed_endtime.
+
+ char speed_time_string[]
+ A null-terminated string describing the time method in use.
+
+ void speed_time_init (void)
+ Initialize time measuring. speed_starttime() does this
+ automatically, so it's only needed if an application wants to inspect
+ the above global variables before making a measurement.
+
+ int speed_precision
+ The intended accuracy of time measurements. speed_measure() in
+ common.c for instance runs target routines with enough repetitions so
+ it takes at least "speed_unittime * speed_precision" (this expression
+ works for both cycles or seconds from speed_endtime).
+
+ A program can provide an option so the user to set speed_precision.
+ If speed_precision is zero when speed_time_init or speed_starttime
+ first run then it gets a default based on the measuring method
+ chosen. (More precision for higher accuracy methods.)
+
+ void speed_cycletime_need_seconds (void)
+ Call this to demand that speed_endtime will return seconds, and not
+ cycles. If only cycles are available then an error is printed and
+ the program exits.
+
+ void speed_cycletime_need_cycles (void)
+ Call this to demand that speed_cycletime is non-zero, so that
+ "speed_endtime() / speed_cycletime" will give times in cycles.
+
+
+
+ Notes:
+
+ Various combinations of cycle counter, read_real_time(), getrusage(),
+ gettimeofday() and times() can arise, according to which are available
+ and their precision.
+
+
+ Allowing speed_endtime() to return either seconds or cycles is only a
+ slight complication and makes it possible for the speed program to do
+ some sensible things without demanding the CPU frequency. If seconds are
+ being measured then it can always print seconds, and if cycles are being
+ measured then it can always print them without needing to know how long
+ they are. Also the tune program doesn't care at all what the units are.
+
+ GMP_CPU_FREQUENCY can always be set when the automated methods in freq.c
+ fail. This will be needed if times in seconds are wanted but a cycle
+ counter is being used, or if times in cycles are wanted but getrusage or
+ another seconds based timer is in use.
+
+ If the measuring method uses a cycle counter but supplements it with
+ getrusage or the like, then knowing the CPU frequency is mandatory since
+ the code compares values from the two.
+
+
+ Not done:
+
+ Solaris gethrtime() seems no more than a slow way to access the Sparc V9
+ cycle counter. gethrvtime() seems to be relevant only to light weight
+ processes, it doesn't for instance give nanosecond virtual time. So
+ neither of these are used.
+
+
+ Bugs:
+
+ getrusage_microseconds_p is fundamentally flawed, getrusage and
+ gettimeofday can have resolutions other than clock ticks or microseconds,
+ for instance IRIX 5 has a tick of 10 ms but a getrusage of 1 ms.
+
+
+ Enhancements:
+
+ The SGI hardware counter has 64 bits on some machines, which could be
+ used when available. But perhaps 32 bits is enough range, and then rely
+ on the getrusage supplement.
+
+ Maybe getrusage (or times) should be used as a supplement for any
+ wall-clock measuring method. Currently a wall clock with a good range
+ (eg. a 64-bit cycle counter) is used without a supplement.
+
+ On PowerPC the timebase registers could be used, but would have to do
+ something to find out the speed. On 6xx chips it's normally 1/4 bus
+ speed, on 4xx chips it's either that or an external clock. Measuring
+ against gettimeofday might be ok. */
+
+
+#include "config.h"
+
+#include <errno.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h> /* for getenv() */
+
+#if HAVE_FCNTL_H
+#include <fcntl.h> /* for open() */
+#endif
+
+#if HAVE_STDINT_H
+#include <stdint.h> /* for uint64_t */
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h> /* for sysconf() */
+#endif
+
+#include <sys/types.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h> /* for struct timeval */
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#if HAVE_SYS_MMAN_H
+#include <sys/mman.h> /* for mmap() */
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h> /* for struct rusage */
+#endif
+
+#if HAVE_SYS_SYSSGI_H
+#include <sys/syssgi.h> /* for syssgi() */
+#endif
+
+#if HAVE_SYS_SYSTEMCFG_H
+#include <sys/systemcfg.h> /* for RTC_POWER on AIX */
+#endif
+
+#if HAVE_SYS_TIMES_H
+#include <sys/times.h> /* for times() and struct tms */
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#include "speed.h"
+
+
+/* strerror is only used for some stuff on newish systems, no need to have a
+ proper replacement */
+#if ! HAVE_STRERROR
+#define strerror(n) "<strerror not available>"
+#endif
+
+
+char speed_time_string[256];
+int speed_precision = 0;
+double speed_unittime;
+double speed_cycletime = 0.0;
+
+
+/* don't rely on "unsigned" to "double" conversion, it's broken in SunOS 4
+ native cc */
+#define M_2POWU (((double) INT_MAX + 1.0) * 2.0)
+
+#define M_2POW32 4294967296.0
+#define M_2POW64 (M_2POW32 * M_2POW32)
+
+
+/* Conditionals for the time functions available are done with normal C
+ code, which is a lot easier than wildly nested preprocessor directives.
+
+ The choice of what to use is partly made at run-time, according to
+ whether the cycle counter works and the measured accuracy of getrusage
+ and gettimeofday.
+
+ A routine that's not available won't be getting called, but is an abort()
+ to be sure it isn't called mistakenly.
+
+ It can be assumed that if a function exists then its data type will, but
+ if the function doesn't then the data type might or might not exist, so
+ the type can't be used unconditionally. The "struct_rusage" etc macros
+ provide dummies when the respective function doesn't exist. */
+
+
+#if HAVE_SPEED_CYCLECOUNTER
+static const int have_cycles = HAVE_SPEED_CYCLECOUNTER;
+#else
+static const int have_cycles = 0;
+#define speed_cyclecounter(p) ASSERT_FAIL (speed_cyclecounter not available)
+#endif
+
+/* "stck" returns ticks since 1 Jan 1900 00:00 GMT, where each tick is 2^-12
+ microseconds. Same #ifdefs here as in longlong.h. */
+#if defined (__GNUC__) && ! defined (NO_ASM) \
+ && (defined (__i370__) || defined (__s390__) || defined (__mvs__))
+static const int have_stck = 1;
+static const int use_stck = 1; /* always use when available */
+typedef uint64_t stck_t; /* gcc for s390 is quite new, always has uint64_t */
+#define STCK(timestamp) \
+ do { \
+ asm ("stck %0" : "=Q" (timestamp)); \
+ } while (0)
+#else
+static const int have_stck = 0;
+static const int use_stck = 0;
+typedef unsigned long stck_t; /* dummy */
+#define STCK(timestamp) ASSERT_FAIL (stck instruction not available)
+#endif
+#define STCK_PERIOD (1.0 / 4096e6) /* 2^-12 microseconds */
+
+/* mftb
+ Enhancement: On 64-bit chips mftb gives a 64-bit value, no need for mftbu
+ and a loop (see powerpc64.asm). */
+#if HAVE_HOST_CPU_FAMILY_powerpc
+static const int have_mftb = 1;
+#if defined (__GNUC__) && ! defined (NO_ASM)
+#define MFTB(a) \
+ do { \
+ unsigned __h1, __l, __h2; \
+ do { \
+ asm volatile ("mftbu %0\n" \
+ "mftb %1\n" \
+ "mftbu %2" \
+ : "=r" (__h1), \
+ "=r" (__l), \
+ "=r" (__h2)); \
+ } while (__h1 != __h2); \
+ a[0] = __l; \
+ a[1] = __h1; \
+ } while (0)
+#else
+#define MFTB(a) mftb_function (a)
+#endif
+#else /* ! powerpc */
+static const int have_mftb = 0;
+#define MFTB(a) \
+ do { \
+ a[0] = 0; \
+ a[1] = 0; \
+ ASSERT_FAIL (mftb not available); \
+ } while (0)
+#endif
+
+/* Unicos 10.X has syssgi(), but not mmap(). */
+#if HAVE_SYSSGI && HAVE_MMAP
+static const int have_sgi = 1;
+#else
+static const int have_sgi = 0;
+#endif
+
+#if HAVE_READ_REAL_TIME
+static const int have_rrt = 1;
+#else
+static const int have_rrt = 0;
+#define read_real_time(t,s) ASSERT_FAIL (read_real_time not available)
+#define time_base_to_time(t,s) ASSERT_FAIL (time_base_to_time not available)
+#define RTC_POWER 1
+#define RTC_POWER_PC 2
+#define timebasestruct_t struct timebasestruct_dummy
+struct timebasestruct_dummy {
+ int flag;
+ unsigned int tb_high;
+ unsigned int tb_low;
+};
+#endif
+
+#if HAVE_CLOCK_GETTIME
+static const int have_cgt = 1;
+#define struct_timespec struct timespec
+#else
+static const int have_cgt = 0;
+#define struct_timespec struct timespec_dummy
+#define clock_gettime(id,ts) (ASSERT_FAIL (clock_gettime not available), -1)
+#define clock_getres(id,ts) (ASSERT_FAIL (clock_getres not available), -1)
+#endif
+
+#if HAVE_GETRUSAGE
+static const int have_grus = 1;
+#define struct_rusage struct rusage
+#else
+static const int have_grus = 0;
+#define getrusage(n,ru) ASSERT_FAIL (getrusage not available)
+#define struct_rusage struct rusage_dummy
+#endif
+
+#if HAVE_GETTIMEOFDAY
+static const int have_gtod = 1;
+#define struct_timeval struct timeval
+#else
+static const int have_gtod = 0;
+#define gettimeofday(tv,tz) ASSERT_FAIL (gettimeofday not available)
+#define struct_timeval struct timeval_dummy
+#endif
+
+#if HAVE_TIMES
+static const int have_times = 1;
+#define struct_tms struct tms
+#else
+static const int have_times = 0;
+#define times(tms) ASSERT_FAIL (times not available)
+#define struct_tms struct tms_dummy
+#endif
+
+struct tms_dummy {
+ long tms_utime;
+};
+struct timeval_dummy {
+ long tv_sec;
+ long tv_usec;
+};
+struct rusage_dummy {
+ struct_timeval ru_utime;
+};
+struct timespec_dummy {
+ long tv_sec;
+ long tv_nsec;
+};
+
+static int use_cycles;
+static int use_mftb;
+static int use_sgi;
+static int use_rrt;
+static int use_cgt;
+static int use_gtod;
+static int use_grus;
+static int use_times;
+static int use_tick_boundary;
+
+static unsigned start_cycles[2];
+static stck_t start_stck;
+static unsigned start_mftb[2];
+static unsigned start_sgi;
+static timebasestruct_t start_rrt;
+static struct_timespec start_cgt;
+static struct_rusage start_grus;
+static struct_timeval start_gtod;
+static struct_tms start_times;
+
+static double cycles_limit = 1e100;
+static double mftb_unittime;
+static double sgi_unittime;
+static double cgt_unittime;
+static double grus_unittime;
+static double gtod_unittime;
+static double times_unittime;
+
+/* for RTC_POWER format, ie. seconds and nanoseconds */
+#define TIMEBASESTRUCT_SECS(t) ((t)->tb_high + (t)->tb_low * 1e-9)
+
+
+/* Return a string representing a time in seconds, nicely formatted.
+ Eg. "10.25ms". */
+char *
+unittime_string (double t)
+{
+ static char buf[128];
+
+ const char *unit;
+ int prec;
+
+ /* choose units and scale */
+ if (t < 1e-6)
+ t *= 1e9, unit = "ns";
+ else if (t < 1e-3)
+ t *= 1e6, unit = "us";
+ else if (t < 1.0)
+ t *= 1e3, unit = "ms";
+ else
+ unit = "s";
+
+ /* want 4 significant figures */
+ if (t < 1.0)
+ prec = 4;
+ else if (t < 10.0)
+ prec = 3;
+ else if (t < 100.0)
+ prec = 2;
+ else
+ prec = 1;
+
+ sprintf (buf, "%.*f%s", prec, t, unit);
+ return buf;
+}
+
+
+static jmp_buf cycles_works_buf;
+
+static RETSIGTYPE
+cycles_works_handler (int sig)
+{
+ longjmp (cycles_works_buf, 1);
+}
+
+int
+cycles_works_p (void)
+{
+ static int result = -1;
+
+ if (result != -1)
+ goto done;
+
+ /* FIXME: On linux, the cycle counter is not saved and restored over
+ * context switches, making it almost useless for precise cputime
+ * measurements. When available, it's better to use clock_gettime,
+ * which seems to have reasonable accuracy (tested on x86_32,
+ * linux-2.6.26, glibc-2.7). However, there are also some linux
+ * systems where clock_gettime is broken in one way or the other,
+ * like CLOCK_PROCESS_CPUTIME_ID not implemented (easy case) or
+ * kind-of implemented but broken (needs code to detect that), and
+ * on those systems a wall-clock cycle counter is the least bad
+ * fallback.
+ *
+ * So we need some code to disable the cycle counter on some but not
+ * all linux systems. */
+#ifdef SIGILL
+ {
+ RETSIGTYPE (*old_handler) (int);
+ unsigned cycles[2];
+
+ old_handler = signal (SIGILL, cycles_works_handler);
+ if (old_handler == SIG_ERR)
+ {
+ if (speed_option_verbose)
+ printf ("cycles_works_p(): SIGILL not supported, assuming speed_cyclecounter() works\n");
+ goto yes;
+ }
+ if (setjmp (cycles_works_buf))
+ {
+ if (speed_option_verbose)
+ printf ("cycles_works_p(): SIGILL during speed_cyclecounter(), so doesn't work\n");
+ result = 0;
+ goto done;
+ }
+ speed_cyclecounter (cycles);
+ signal (SIGILL, old_handler);
+ if (speed_option_verbose)
+ printf ("cycles_works_p(): speed_cyclecounter() works\n");
+ }
+#else
+
+ if (speed_option_verbose)
+ printf ("cycles_works_p(): SIGILL not defined, assuming speed_cyclecounter() works\n");
+ goto yes;
+#endif
+
+ yes:
+ result = 1;
+
+ done:
+ return result;
+}
+
+
+/* The number of clock ticks per second, but looking at sysconf rather than
+ just CLK_TCK, where possible. */
+long
+clk_tck (void)
+{
+ static long result = -1L;
+ if (result != -1L)
+ return result;
+
+#if HAVE_SYSCONF
+ result = sysconf (_SC_CLK_TCK);
+ if (result != -1L)
+ {
+ if (speed_option_verbose)
+ printf ("sysconf(_SC_CLK_TCK) is %ld per second\n", result);
+ return result;
+ }
+
+ fprintf (stderr,
+ "sysconf(_SC_CLK_TCK) not working, using CLK_TCK instead\n");
+#endif
+
+#ifdef CLK_TCK
+ result = CLK_TCK;
+ if (speed_option_verbose)
+ printf ("CLK_TCK is %ld per second\n", result);
+ return result;
+#else
+ fprintf (stderr, "CLK_TCK not defined, cannot continue\n");
+ abort ();
+#endif
+}
+
+
+/* If two times can be observed less than half a clock tick apart, then
+ assume "get" is microsecond accurate.
+
+ Two times only 1 microsecond apart are not believed, since some kernels
+ take it upon themselves to ensure gettimeofday doesn't return the same
+ value twice, for the benefit of applications using it for a timestamp.
+ This is obviously very stupid given the speed of CPUs these days.
+
+ Making "reps" many calls to noop_1() is designed to waste some CPU, with
+ a view to getting measurements 2 microseconds (or more) apart. "reps" is
+ increased progressively until such a period is seen.
+
+ The outer loop "attempts" are just to allow for any random nonsense or
+ system load upsetting the measurements (ie. making two successive calls
+ to "get" come out as a longer interval than normal).
+
+ Bugs:
+
+ The assumption that any interval less than a half tick implies
+ microsecond resolution is obviously fairly rash, the true resolution
+ could be anything between a microsecond and that half tick. Perhaps
+ something special would have to be done on a system where this is the
+ case, since there's no obvious reliable way to detect it
+ automatically. */
+
+#define MICROSECONDS_P(name, type, get, sec, usec) \
+ { \
+ static int result = -1; \
+ type st, et; \
+ long dt, half_tick; \
+ unsigned attempt, reps, i, j; \
+ \
+ if (result != -1) \
+ return result; \
+ \
+ result = 0; \
+ half_tick = (1000000L / clk_tck ()) / 2; \
+ \
+ for (attempt = 0; attempt < 5; attempt++) \
+ { \
+ reps = 0; \
+ for (;;) \
+ { \
+ get (st); \
+ for (i = 0; i < reps; i++) \
+ for (j = 0; j < 100; j++) \
+ noop_1 (CNST_LIMB(0)); \
+ get (et); \
+ \
+ dt = (sec(et)-sec(st))*1000000L + usec(et)-usec(st); \
+ \
+ if (speed_option_verbose >= 2) \
+ printf ("%s attempt=%u, reps=%u, dt=%ld\n", \
+ name, attempt, reps, dt); \
+ \
+ if (dt >= 2) \
+ break; \
+ \
+ reps = (reps == 0 ? 1 : 2*reps); \
+ if (reps == 0) \
+ break; /* uint overflow, not normal */ \
+ } \
+ \
+ if (dt < half_tick) \
+ { \
+ result = 1; \
+ break; \
+ } \
+ } \
+ \
+ if (speed_option_verbose) \
+ { \
+ if (result) \
+ printf ("%s is microsecond accurate\n", name); \
+ else \
+ printf ("%s is only %s clock tick accurate\n", \
+ name, unittime_string (1.0/clk_tck())); \
+ } \
+ return result; \
+ }
+
+
+int
+gettimeofday_microseconds_p (void)
+{
+#define call_gettimeofday(t) gettimeofday (&(t), NULL)
+#define timeval_tv_sec(t) ((t).tv_sec)
+#define timeval_tv_usec(t) ((t).tv_usec)
+ MICROSECONDS_P ("gettimeofday", struct_timeval,
+ call_gettimeofday, timeval_tv_sec, timeval_tv_usec);
+}
+
+int
+getrusage_microseconds_p (void)
+{
+#define call_getrusage(t) getrusage (0, &(t))
+#define rusage_tv_sec(t) ((t).ru_utime.tv_sec)
+#define rusage_tv_usec(t) ((t).ru_utime.tv_usec)
+ MICROSECONDS_P ("getrusage", struct_rusage,
+ call_getrusage, rusage_tv_sec, rusage_tv_usec);
+}
+
+/* Test whether getrusage goes backwards, return non-zero if it does
+ (suggesting it's flawed).
+
+ On a macintosh m68040-unknown-netbsd1.4.1 getrusage looks like it's
+ microsecond accurate, but has been seen remaining unchanged after many
+ microseconds have elapsed. It also regularly goes backwards by 1000 to
+ 5000 usecs, this has been seen after between 500 and 4000 attempts taking
+ perhaps 0.03 seconds. We consider this too broken for good measuring.
+ We used to have configure pretend getrusage didn't exist on this system,
+ but a runtime test should be more reliable, since we imagine the problem
+ is not confined to just this exact system tuple. */
+
+int
+getrusage_backwards_p (void)
+{
+ static int result = -1;
+ struct rusage start, prev, next;
+ long d;
+ int i;
+
+ if (result != -1)
+ return result;
+
+ getrusage (0, &start);
+ memcpy (&next, &start, sizeof (next));
+
+ result = 0;
+ i = 0;
+ for (;;)
+ {
+ memcpy (&prev, &next, sizeof (prev));
+ getrusage (0, &next);
+
+ if (next.ru_utime.tv_sec < prev.ru_utime.tv_sec
+ || (next.ru_utime.tv_sec == prev.ru_utime.tv_sec
+ && next.ru_utime.tv_usec < prev.ru_utime.tv_usec))
+ {
+ if (speed_option_verbose)
+ printf ("getrusage went backwards (attempt %d: %ld.%06ld -> %ld.%06ld)\n",
+ i,
+ (long) prev.ru_utime.tv_sec, (long) prev.ru_utime.tv_usec,
+ (long) next.ru_utime.tv_sec, (long) next.ru_utime.tv_usec);
+ result = 1;
+ break;
+ }
+
+ /* minimum 1000 attempts, then stop after either 0.1 seconds or 50000
+ attempts, whichever comes first */
+ d = 1000000 * (next.ru_utime.tv_sec - start.ru_utime.tv_sec)
+ + (next.ru_utime.tv_usec - start.ru_utime.tv_usec);
+ i++;
+ if (i > 50000 || (i > 1000 && d > 100000))
+ break;
+ }
+
+ return result;
+}
+
+/* CLOCK_PROCESS_CPUTIME_ID looks like it's going to be in a future version
+ of glibc (some time post 2.2).
+
+ CLOCK_VIRTUAL is process time, available in BSD systems (though sometimes
+ defined, but returning -1 for an error). */
+
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+# define CGT_ID CLOCK_PROCESS_CPUTIME_ID
+#else
+# ifdef CLOCK_VIRTUAL
+# define CGT_ID CLOCK_VIRTUAL
+# endif
+#endif
+#ifdef CGT_ID
+const int have_cgt_id = 1;
+#else
+const int have_cgt_id = 0;
+# define CGT_ID (ASSERT_FAIL (CGT_ID not determined), -1)
+#endif
+
+#define CGT_DELAY_COUNT 1000
+
+int
+cgt_works_p (void)
+{
+ static int result = -1;
+ struct_timespec unit;
+
+ if (! have_cgt)
+ return 0;
+
+ if (! have_cgt_id)
+ {
+ if (speed_option_verbose)
+ printf ("clock_gettime don't know what ID to use\n");
+ result = 0;
+ return result;
+ }
+
+ if (result != -1)
+ return result;
+
+ /* trial run to see if it works */
+ if (clock_gettime (CGT_ID, &unit) != 0)
+ {
+ if (speed_option_verbose)
+ printf ("clock_gettime id=%d error: %s\n", CGT_ID, strerror (errno));
+ result = 0;
+ return result;
+ }
+
+ /* get the resolution */
+ if (clock_getres (CGT_ID, &unit) != 0)
+ {
+ if (speed_option_verbose)
+ printf ("clock_getres id=%d error: %s\n", CGT_ID, strerror (errno));
+ result = 0;
+ return result;
+ }
+
+ cgt_unittime = unit.tv_sec + unit.tv_nsec * 1e-9;
+ printf ("clock_gettime is %s accurate\n",
+ unittime_string (cgt_unittime));
+
+ if (cgt_unittime < 10e-9)
+ {
+ /* Do we believe this? */
+ struct timespec start, end;
+ static volatile int counter;
+ double duration;
+ if (clock_gettime (CGT_ID, &start))
+ {
+ if (speed_option_verbose)
+ printf ("clock_gettime id=%d error: %s\n", CGT_ID, strerror (errno));
+ result = 0;
+ return result;
+ }
+ /* Loop of at least 1000 memory accesses, ought to take at
+ least 100 ns*/
+ for (counter = 0; counter < CGT_DELAY_COUNT; counter++)
+ ;
+ if (clock_gettime (CGT_ID, &end))
+ {
+ if (speed_option_verbose)
+ printf ("clock_gettime id=%d error: %s\n", CGT_ID, strerror (errno));
+ result = 0;
+ return result;
+ }
+ duration = (end.tv_sec + end.tv_nsec * 1e-9
+ - start.tv_sec - start.tv_nsec * 1e-9);
+ if (speed_option_verbose)
+ printf ("delay loop of %d rounds took %s (according to clock_gettime)\n",
+ CGT_DELAY_COUNT, unittime_string (duration));
+ if (duration < 100e-9)
+ {
+ if (speed_option_verbose)
+ printf ("clock_gettime id=%d not believable\n", CGT_ID);
+ result = 0;
+ return result;
+ }
+ }
+ result = 1;
+ return result;
+}
+
+
+static double
+freq_measure_mftb_one (void)
+{
+#define call_gettimeofday(t) gettimeofday (&(t), NULL)
+#define timeval_tv_sec(t) ((t).tv_sec)
+#define timeval_tv_usec(t) ((t).tv_usec)
+ FREQ_MEASURE_ONE ("mftb", struct_timeval,
+ call_gettimeofday, MFTB,
+ timeval_tv_sec, timeval_tv_usec);
+}
+
+
+static jmp_buf mftb_works_buf;
+
+static RETSIGTYPE
+mftb_works_handler (int sig)
+{
+ longjmp (mftb_works_buf, 1);
+}
+
+int
+mftb_works_p (void)
+{
+ unsigned a[2];
+ RETSIGTYPE (*old_handler) (int);
+ double cycletime;
+
+ /* suppress a warning about a[] unused */
+ a[0] = 0;
+
+ if (! have_mftb)
+ return 0;
+
+#ifdef SIGILL
+ old_handler = signal (SIGILL, mftb_works_handler);
+ if (old_handler == SIG_ERR)
+ {
+ if (speed_option_verbose)
+ printf ("mftb_works_p(): SIGILL not supported, assuming mftb works\n");
+ return 1;
+ }
+ if (setjmp (mftb_works_buf))
+ {
+ if (speed_option_verbose)
+ printf ("mftb_works_p(): SIGILL during mftb, so doesn't work\n");
+ return 0;
+ }
+ MFTB (a);
+ signal (SIGILL, old_handler);
+ if (speed_option_verbose)
+ printf ("mftb_works_p(): mftb works\n");
+#else
+
+ if (speed_option_verbose)
+ printf ("mftb_works_p(): SIGILL not defined, assuming mftb works\n");
+#endif
+
+#if ! HAVE_GETTIMEOFDAY
+ if (speed_option_verbose)
+ printf ("mftb_works_p(): no gettimeofday available to measure mftb\n");
+ return 0;
+#endif
+
+ /* The time base is normally 1/4 of the bus speed on 6xx and 7xx chips, on
+ other chips it can be driven from an external clock. */
+ cycletime = freq_measure ("mftb", freq_measure_mftb_one);
+ if (cycletime == -1.0)
+ {
+ if (speed_option_verbose)
+ printf ("mftb_works_p(): cannot measure mftb period\n");
+ return 0;
+ }
+
+ mftb_unittime = cycletime;
+ return 1;
+}
+
+
+volatile unsigned *sgi_addr;
+
+int
+sgi_works_p (void)
+{
+#if HAVE_SYSSGI && HAVE_MMAP
+ static int result = -1;
+
+ size_t pagesize, offset;
+ __psunsigned_t phys, physpage;
+ void *virtpage;
+ unsigned period_picoseconds;
+ int size, fd;
+
+ if (result != -1)
+ return result;
+
+ phys = syssgi (SGI_QUERY_CYCLECNTR, &period_picoseconds);
+ if (phys == (__psunsigned_t) -1)
+ {
+ /* ENODEV is the error when a counter is not available */
+ if (speed_option_verbose)
+ printf ("syssgi SGI_QUERY_CYCLECNTR error: %s\n", strerror (errno));
+ result = 0;
+ return result;
+ }
+ sgi_unittime = period_picoseconds * 1e-12;
+
+ /* IRIX 5 doesn't have SGI_CYCLECNTR_SIZE, assume 32 bits in that case.
+ Challenge/ONYX hardware has a 64 bit byte counter, but there seems no
+ obvious way to identify that without SGI_CYCLECNTR_SIZE. */
+#ifdef SGI_CYCLECNTR_SIZE
+ size = syssgi (SGI_CYCLECNTR_SIZE);
+ if (size == -1)
+ {
+ if (speed_option_verbose)
+ {
+ printf ("syssgi SGI_CYCLECNTR_SIZE error: %s\n", strerror (errno));
+ printf (" will assume size==4\n");
+ }
+ size = 32;
+ }
+#else
+ size = 32;
+#endif
+
+ if (size < 32)
+ {
+ printf ("syssgi SGI_CYCLECNTR_SIZE gives %d, expected 32 or 64\n", size);
+ result = 0;
+ return result;
+ }
+
+ pagesize = getpagesize();
+ offset = (size_t) phys & (pagesize-1);
+ physpage = phys - offset;
+
+ /* shouldn't cross over a page boundary */
+ ASSERT_ALWAYS (offset + size/8 <= pagesize);
+
+ fd = open("/dev/mmem", O_RDONLY);
+ if (fd == -1)
+ {
+ if (speed_option_verbose)
+ printf ("open /dev/mmem: %s\n", strerror (errno));
+ result = 0;
+ return result;
+ }
+
+ virtpage = mmap (0, pagesize, PROT_READ, MAP_PRIVATE, fd, (off_t) physpage);
+ if (virtpage == (void *) -1)
+ {
+ if (speed_option_verbose)
+ printf ("mmap /dev/mmem: %s\n", strerror (errno));
+ result = 0;
+ return result;
+ }
+
+ /* address of least significant 4 bytes, knowing mips is big endian */
+ sgi_addr = (unsigned *) ((char *) virtpage + offset
+ + size/8 - sizeof(unsigned));
+ result = 1;
+ return result;
+
+#else /* ! (HAVE_SYSSGI && HAVE_MMAP) */
+ return 0;
+#endif
+}
+
+
+#define DEFAULT(var,n) \
+ do { \
+ if (! (var)) \
+ (var) = (n); \
+ } while (0)
+
+void
+speed_time_init (void)
+{
+ double supplement_unittime = 0.0;
+
+ static int speed_time_initialized = 0;
+ if (speed_time_initialized)
+ return;
+ speed_time_initialized = 1;
+
+ speed_cycletime_init ();
+
+ if (!speed_option_cycles_broken && have_cycles && cycles_works_p ())
+ {
+ use_cycles = 1;
+ DEFAULT (speed_cycletime, 1.0);
+ speed_unittime = speed_cycletime;
+ DEFAULT (speed_precision, 10000);
+ strcpy (speed_time_string, "CPU cycle counter");
+
+ /* only used if a supplementary method is chosen below */
+ cycles_limit = (have_cycles == 1 ? M_2POW32 : M_2POW64) / 2.0
+ * speed_cycletime;
+
+ if (have_grus && getrusage_microseconds_p() && ! getrusage_backwards_p())
+ {
+ /* this is a good combination */
+ use_grus = 1;
+ supplement_unittime = grus_unittime = 1.0e-6;
+ strcpy (speed_time_string, "CPU cycle counter, supplemented by microsecond getrusage()");
+ }
+ else if (have_cycles == 1)
+ {
+ /* When speed_cyclecounter has a limited range, look for something
+ to supplement it. */
+ if (have_gtod && gettimeofday_microseconds_p())
+ {
+ use_gtod = 1;
+ supplement_unittime = gtod_unittime = 1.0e-6;
+ strcpy (speed_time_string, "CPU cycle counter, supplemented by microsecond gettimeofday()");
+ }
+ else if (have_grus)
+ {
+ use_grus = 1;
+ supplement_unittime = grus_unittime = 1.0 / (double) clk_tck ();
+ sprintf (speed_time_string, "CPU cycle counter, supplemented by %s clock tick getrusage()", unittime_string (supplement_unittime));
+ }
+ else if (have_times)
+ {
+ use_times = 1;
+ supplement_unittime = times_unittime = 1.0 / (double) clk_tck ();
+ sprintf (speed_time_string, "CPU cycle counter, supplemented by %s clock tick times()", unittime_string (supplement_unittime));
+ }
+ else if (have_gtod)
+ {
+ use_gtod = 1;
+ supplement_unittime = gtod_unittime = 1.0 / (double) clk_tck ();
+ sprintf (speed_time_string, "CPU cycle counter, supplemented by %s clock tick gettimeofday()", unittime_string (supplement_unittime));
+ }
+ else
+ {
+ fprintf (stderr, "WARNING: cycle counter is 32 bits and there's no other functions.\n");
+ fprintf (stderr, " Wraparounds may produce bad results on long measurements.\n");
+ }
+ }
+
+ if (use_grus || use_times || use_gtod)
+ {
+ /* must know cycle period to compare cycles to other measuring
+ (via cycles_limit) */
+ speed_cycletime_need_seconds ();
+
+ if (speed_precision * supplement_unittime > cycles_limit)
+ {
+ fprintf (stderr, "WARNING: requested precision can't always be achieved due to limited range\n");
+ fprintf (stderr, " cycle counter and limited precision supplemental method\n");
+ fprintf (stderr, " (%s)\n", speed_time_string);
+ }
+ }
+ }
+ else if (have_stck)
+ {
+ strcpy (speed_time_string, "STCK timestamp");
+ /* stck is in units of 2^-12 microseconds, which is very likely higher
+ resolution than a cpu cycle */
+ if (speed_cycletime == 0.0)
+ speed_cycletime_fail
+ ("Need to know CPU frequency for effective stck unit");
+ speed_unittime = MAX (speed_cycletime, STCK_PERIOD);
+ DEFAULT (speed_precision, 10000);
+ }
+ else if (have_mftb && mftb_works_p ())
+ {
+ use_mftb = 1;
+ DEFAULT (speed_precision, 10000);
+ speed_unittime = mftb_unittime;
+ sprintf (speed_time_string, "mftb counter (%s)",
+ unittime_string (speed_unittime));
+ }
+ else if (have_sgi && sgi_works_p ())
+ {
+ use_sgi = 1;
+ DEFAULT (speed_precision, 10000);
+ speed_unittime = sgi_unittime;
+ sprintf (speed_time_string, "syssgi() mmap counter (%s), supplemented by millisecond getrusage()",
+ unittime_string (speed_unittime));
+ /* supplemented with getrusage, which we assume to have 1ms resolution */
+ use_grus = 1;
+ supplement_unittime = 1e-3;
+ }
+ else if (have_rrt)
+ {
+ timebasestruct_t t;
+ use_rrt = 1;
+ DEFAULT (speed_precision, 10000);
+ read_real_time (&t, sizeof(t));
+ switch (t.flag) {
+ case RTC_POWER:
+ /* FIXME: What's the actual RTC resolution? */
+ speed_unittime = 1e-7;
+ strcpy (speed_time_string, "read_real_time() power nanoseconds");
+ break;
+ case RTC_POWER_PC:
+ t.tb_high = 1;
+ t.tb_low = 0;
+ time_base_to_time (&t, sizeof(t));
+ speed_unittime = TIMEBASESTRUCT_SECS(&t) / M_2POW32;
+ sprintf (speed_time_string, "%s read_real_time() powerpc ticks",
+ unittime_string (speed_unittime));
+ break;
+ default:
+ fprintf (stderr, "ERROR: Unrecognised timebasestruct_t flag=%d\n",
+ t.flag);
+ abort ();
+ }
+ }
+ else if (have_cgt && cgt_works_p() && cgt_unittime < 1.5e-6)
+ {
+ /* use clock_gettime if microsecond or better resolution */
+ choose_cgt:
+ use_cgt = 1;
+ speed_unittime = cgt_unittime;
+ DEFAULT (speed_precision, (cgt_unittime <= 0.1e-6 ? 10000 : 1000));
+ strcpy (speed_time_string, "microsecond accurate clock_gettime()");
+ }
+ else if (have_times && clk_tck() > 1000000)
+ {
+ /* Cray vector systems have times() which is clock cycle resolution
+ (eg. 450 MHz). */
+ DEFAULT (speed_precision, 10000);
+ goto choose_times;
+ }
+ else if (have_grus && getrusage_microseconds_p() && ! getrusage_backwards_p())
+ {
+ use_grus = 1;
+ speed_unittime = grus_unittime = 1.0e-6;
+ DEFAULT (speed_precision, 1000);
+ strcpy (speed_time_string, "microsecond accurate getrusage()");
+ }
+ else if (have_gtod && gettimeofday_microseconds_p())
+ {
+ use_gtod = 1;
+ speed_unittime = gtod_unittime = 1.0e-6;
+ DEFAULT (speed_precision, 1000);
+ strcpy (speed_time_string, "microsecond accurate gettimeofday()");
+ }
+ else if (have_cgt && cgt_works_p() && cgt_unittime < 1.5/clk_tck())
+ {
+ /* use clock_gettime if 1 tick or better resolution */
+ goto choose_cgt;
+ }
+ else if (have_times)
+ {
+ use_tick_boundary = 1;
+ DEFAULT (speed_precision, 200);
+ choose_times:
+ use_times = 1;
+ speed_unittime = times_unittime = 1.0 / (double) clk_tck ();
+ sprintf (speed_time_string, "%s clock tick times()",
+ unittime_string (speed_unittime));
+ }
+ else if (have_grus)
+ {
+ use_grus = 1;
+ use_tick_boundary = 1;
+ speed_unittime = grus_unittime = 1.0 / (double) clk_tck ();
+ DEFAULT (speed_precision, 200);
+ sprintf (speed_time_string, "%s clock tick getrusage()\n",
+ unittime_string (speed_unittime));
+ }
+ else if (have_gtod)
+ {
+ use_gtod = 1;
+ use_tick_boundary = 1;
+ speed_unittime = gtod_unittime = 1.0 / (double) clk_tck ();
+ DEFAULT (speed_precision, 200);
+ sprintf (speed_time_string, "%s clock tick gettimeofday()",
+ unittime_string (speed_unittime));
+ }
+ else
+ {
+ fprintf (stderr, "No time measuring method available\n");
+ fprintf (stderr, "None of: speed_cyclecounter(), STCK(), getrusage(), gettimeofday(), times()\n");
+ abort ();
+ }
+
+ if (speed_option_verbose)
+ {
+ printf ("speed_time_init: %s\n", speed_time_string);
+ printf (" speed_precision %d\n", speed_precision);
+ printf (" speed_unittime %.2g\n", speed_unittime);
+ if (supplement_unittime)
+ printf (" supplement_unittime %.2g\n", supplement_unittime);
+ printf (" use_tick_boundary %d\n", use_tick_boundary);
+ if (have_cycles)
+ printf (" cycles_limit %.2g seconds\n", cycles_limit);
+ }
+}
+
+
+
+/* Burn up CPU until a clock tick boundary, for greater accuracy. Set the
+ corresponding "start_foo" appropriately too. */
+
+void
+grus_tick_boundary (void)
+{
+ struct_rusage prev;
+ getrusage (0, &prev);
+ do {
+ getrusage (0, &start_grus);
+ } while (start_grus.ru_utime.tv_usec == prev.ru_utime.tv_usec);
+}
+
+void
+gtod_tick_boundary (void)
+{
+ struct_timeval prev;
+ gettimeofday (&prev, NULL);
+ do {
+ gettimeofday (&start_gtod, NULL);
+ } while (start_gtod.tv_usec == prev.tv_usec);
+}
+
+void
+times_tick_boundary (void)
+{
+ struct_tms prev;
+ times (&prev);
+ do
+ times (&start_times);
+ while (start_times.tms_utime == prev.tms_utime);
+}
+
+
+/* "have_" values are tested to let unused code go dead. */
+
+void
+speed_starttime (void)
+{
+ speed_time_init ();
+
+ if (have_grus && use_grus)
+ {
+ if (use_tick_boundary)
+ grus_tick_boundary ();
+ else
+ getrusage (0, &start_grus);
+ }
+
+ if (have_gtod && use_gtod)
+ {
+ if (use_tick_boundary)
+ gtod_tick_boundary ();
+ else
+ gettimeofday (&start_gtod, NULL);
+ }
+
+ if (have_times && use_times)
+ {
+ if (use_tick_boundary)
+ times_tick_boundary ();
+ else
+ times (&start_times);
+ }
+
+ if (have_cgt && use_cgt)
+ clock_gettime (CGT_ID, &start_cgt);
+
+ if (have_rrt && use_rrt)
+ read_real_time (&start_rrt, sizeof(start_rrt));
+
+ if (have_sgi && use_sgi)
+ start_sgi = *sgi_addr;
+
+ if (have_mftb && use_mftb)
+ MFTB (start_mftb);
+
+ if (have_stck && use_stck)
+ STCK (start_stck);
+
+ /* Cycles sampled last for maximum accuracy. */
+ if (have_cycles && use_cycles)
+ speed_cyclecounter (start_cycles);
+}
+
+
+/* Calculate the difference between two cycle counter samples, as a "double"
+ counter of cycles.
+
+ The start and end values are allowed to cancel in integers in case the
+ counter values are bigger than the 53 bits that normally fit in a double.
+
+ This works even if speed_cyclecounter() puts a value bigger than 32-bits
+ in the low word (the high word always gets a 2**32 multiplier though). */
+
+double
+speed_cyclecounter_diff (const unsigned end[2], const unsigned start[2])
+{
+ unsigned d;
+ double t;
+
+ if (have_cycles == 1)
+ {
+ t = (end[0] - start[0]);
+ }
+ else
+ {
+ d = end[0] - start[0];
+ t = d - (d > end[0] ? M_2POWU : 0.0);
+ t += (end[1] - start[1]) * M_2POW32;
+ }
+ return t;
+}
+
+
+double
+speed_mftb_diff (const unsigned end[2], const unsigned start[2])
+{
+ unsigned d;
+ double t;
+
+ d = end[0] - start[0];
+ t = (double) d - (d > end[0] ? M_2POW32 : 0.0);
+ t += (end[1] - start[1]) * M_2POW32;
+ return t;
+}
+
+
+/* Calculate the difference between "start" and "end" using fields "sec" and
+ "psec", where each "psec" is a "punit" of a second.
+
+ The seconds parts are allowed to cancel before being combined with the
+ psec parts, in case a simple "sec+psec*punit" exceeds the precision of a
+ double.
+
+ Total time is only calculated in a "double" since an integer count of
+ psecs might overflow. 2^32 microseconds is only a bit over an hour, or
+ 2^32 nanoseconds only about 4 seconds.
+
+ The casts to "long" are for the benefit of timebasestruct_t, where the
+ fields are only "unsigned int", but we want a signed difference. */
+
+#define DIFF_SECS_ROUTINE(sec, psec, punit) \
+ { \
+ long sec_diff, psec_diff; \
+ sec_diff = (long) end->sec - (long) start->sec; \
+ psec_diff = (long) end->psec - (long) start->psec; \
+ return (double) sec_diff + punit * (double) psec_diff; \
+ }
+
+double
+timeval_diff_secs (const struct_timeval *end, const struct_timeval *start)
+{
+ DIFF_SECS_ROUTINE (tv_sec, tv_usec, 1e-6);
+}
+
+double
+rusage_diff_secs (const struct_rusage *end, const struct_rusage *start)
+{
+ DIFF_SECS_ROUTINE (ru_utime.tv_sec, ru_utime.tv_usec, 1e-6);
+}
+
+double
+timespec_diff_secs (const struct_timespec *end, const struct_timespec *start)
+{
+ DIFF_SECS_ROUTINE (tv_sec, tv_nsec, 1e-9);
+}
+
+/* This is for use after time_base_to_time, ie. for seconds and nanoseconds. */
+double
+timebasestruct_diff_secs (const timebasestruct_t *end,
+ const timebasestruct_t *start)
+{
+ DIFF_SECS_ROUTINE (tb_high, tb_low, 1e-9);
+}
+
+
+double
+speed_endtime (void)
+{
+#define END_USE(name,value) \
+ do { \
+ if (speed_option_verbose >= 3) \
+ printf ("speed_endtime(): used %s\n", name); \
+ result = value; \
+ goto done; \
+ } while (0)
+
+#define END_ENOUGH(name,value) \
+ do { \
+ if (speed_option_verbose >= 3) \
+ printf ("speed_endtime(): %s gives enough precision\n", name); \
+ result = value; \
+ goto done; \
+ } while (0)
+
+#define END_EXCEED(name,value) \
+ do { \
+ if (speed_option_verbose >= 3) \
+ printf ("speed_endtime(): cycle counter limit exceeded, used %s\n", \
+ name); \
+ result = value; \
+ goto done; \
+ } while (0)
+
+ unsigned end_cycles[2];
+ stck_t end_stck;
+ unsigned end_mftb[2];
+ unsigned end_sgi;
+ timebasestruct_t end_rrt;
+ struct_timespec end_cgt;
+ struct_timeval end_gtod;
+ struct_rusage end_grus;
+ struct_tms end_times;
+ double t_gtod, t_grus, t_times, t_cgt;
+ double t_rrt, t_sgi, t_mftb, t_stck, t_cycles;
+ double result;
+
+ /* Cycles sampled first for maximum accuracy.
+ "have_" values tested to let unused code go dead. */
+
+ if (have_cycles && use_cycles) speed_cyclecounter (end_cycles);
+ if (have_stck && use_stck) STCK (end_stck);
+ if (have_mftb && use_mftb) MFTB (end_mftb);
+ if (have_sgi && use_sgi) end_sgi = *sgi_addr;
+ if (have_rrt && use_rrt) read_real_time (&end_rrt, sizeof(end_rrt));
+ if (have_cgt && use_cgt) clock_gettime (CGT_ID, &end_cgt);
+ if (have_gtod && use_gtod) gettimeofday (&end_gtod, NULL);
+ if (have_grus && use_grus) getrusage (0, &end_grus);
+ if (have_times && use_times) times (&end_times);
+
+ result = -1.0;
+
+ if (speed_option_verbose >= 4)
+ {
+ printf ("speed_endtime():\n");
+ if (use_cycles)
+ printf (" cycles 0x%X,0x%X -> 0x%X,0x%X\n",
+ start_cycles[1], start_cycles[0],
+ end_cycles[1], end_cycles[0]);
+
+ if (use_stck)
+ printf (" stck 0x%lX -> 0x%lX\n", start_stck, end_stck);
+
+ if (use_mftb)
+ printf (" mftb 0x%X,%08X -> 0x%X,%08X\n",
+ start_mftb[1], start_mftb[0],
+ end_mftb[1], end_mftb[0]);
+
+ if (use_sgi)
+ printf (" sgi 0x%X -> 0x%X\n", start_sgi, end_sgi);
+
+ if (use_rrt)
+ printf (" read_real_time (%d)%u,%u -> (%d)%u,%u\n",
+ start_rrt.flag, start_rrt.tb_high, start_rrt.tb_low,
+ end_rrt.flag, end_rrt.tb_high, end_rrt.tb_low);
+
+ if (use_cgt)
+ printf (" clock_gettime %ld.%09ld -> %ld.%09ld\n",
+ start_cgt.tv_sec, start_cgt.tv_nsec,
+ end_cgt.tv_sec, end_cgt.tv_nsec);
+
+ if (use_gtod)
+ printf (" gettimeofday %ld.%06ld -> %ld.%06ld\n",
+ start_gtod.tv_sec, start_gtod.tv_usec,
+ end_gtod.tv_sec, end_gtod.tv_usec);
+
+ if (use_grus)
+ printf (" getrusage %ld.%06ld -> %ld.%06ld\n",
+ start_grus.ru_utime.tv_sec, start_grus.ru_utime.tv_usec,
+ end_grus.ru_utime.tv_sec, end_grus.ru_utime.tv_usec);
+
+ if (use_times)
+ printf (" times %ld -> %ld\n",
+ start_times.tms_utime, end_times.tms_utime);
+ }
+
+ if (use_rrt)
+ {
+ time_base_to_time (&start_rrt, sizeof(start_rrt));
+ time_base_to_time (&end_rrt, sizeof(end_rrt));
+ t_rrt = timebasestruct_diff_secs (&end_rrt, &start_rrt);
+ END_USE ("read_real_time()", t_rrt);
+ }
+
+ if (use_cgt)
+ {
+ t_cgt = timespec_diff_secs (&end_cgt, &start_cgt);
+ END_USE ("clock_gettime()", t_cgt);
+ }
+
+ if (use_grus)
+ {
+ t_grus = rusage_diff_secs (&end_grus, &start_grus);
+
+ /* Use getrusage() if the cycle counter limit would be exceeded, or if
+ it provides enough accuracy already. */
+ if (use_cycles)
+ {
+ if (t_grus >= speed_precision*grus_unittime)
+ END_ENOUGH ("getrusage()", t_grus);
+ if (t_grus >= cycles_limit)
+ END_EXCEED ("getrusage()", t_grus);
+ }
+ }
+
+ if (use_times)
+ {
+ t_times = (end_times.tms_utime - start_times.tms_utime) * times_unittime;
+
+ /* Use times() if the cycle counter limit would be exceeded, or if
+ it provides enough accuracy already. */
+ if (use_cycles)
+ {
+ if (t_times >= speed_precision*times_unittime)
+ END_ENOUGH ("times()", t_times);
+ if (t_times >= cycles_limit)
+ END_EXCEED ("times()", t_times);
+ }
+ }
+
+ if (use_gtod)
+ {
+ t_gtod = timeval_diff_secs (&end_gtod, &start_gtod);
+
+ /* Use gettimeofday() if it measured a value bigger than the cycle
+ counter can handle. */
+ if (use_cycles)
+ {
+ if (t_gtod >= cycles_limit)
+ END_EXCEED ("gettimeofday()", t_gtod);
+ }
+ }
+
+ if (use_mftb)
+ {
+ t_mftb = speed_mftb_diff (end_mftb, start_mftb) * mftb_unittime;
+ END_USE ("mftb", t_mftb);
+ }
+
+ if (use_stck)
+ {
+ t_stck = (end_stck - start_stck) * STCK_PERIOD;
+ END_USE ("stck", t_stck);
+ }
+
+ if (use_sgi)
+ {
+ t_sgi = (end_sgi - start_sgi) * sgi_unittime;
+ END_USE ("SGI hardware counter", t_sgi);
+ }
+
+ if (use_cycles)
+ {
+ t_cycles = speed_cyclecounter_diff (end_cycles, start_cycles)
+ * speed_cycletime;
+ END_USE ("cycle counter", t_cycles);
+ }
+
+ if (use_grus && getrusage_microseconds_p())
+ END_USE ("getrusage()", t_grus);
+
+ if (use_gtod && gettimeofday_microseconds_p())
+ END_USE ("gettimeofday()", t_gtod);
+
+ if (use_times) END_USE ("times()", t_times);
+ if (use_grus) END_USE ("getrusage()", t_grus);
+ if (use_gtod) END_USE ("gettimeofday()", t_gtod);
+
+ fprintf (stderr, "speed_endtime(): oops, no time method available\n");
+ abort ();
+
+ done:
+ if (result < 0.0)
+ {
+ if (speed_option_verbose >= 2)
+ fprintf (stderr, "speed_endtime(): warning, treating negative time as zero: %.9f\n", result);
+ result = 0.0;
+ }
+ return result;
+}
diff --git a/gmp/tune/tune-gcd-p.c b/gmp/tune/tune-gcd-p.c
new file mode 100644
index 0000000000..4d52f5610c
--- /dev/null
+++ b/gmp/tune/tune-gcd-p.c
@@ -0,0 +1,225 @@
+/* tune-gcd-p
+
+ Tune the choice for splitting p in divide-and-conquer gcd.
+
+Copyright 2008, 2010, 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#define TUNE_GCD_P 1
+
+#include "../mpn/gcd.c"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "speed.h"
+
+/* Search for minimum over a range. FIXME: Implement golden-section /
+ fibonacci search*/
+static int
+search (double *minp, double (*f)(void *, int), void *ctx, int start, int end)
+{
+ int x[4];
+ double y[4];
+
+ int best_i;
+
+ x[0] = start;
+ x[3] = end;
+
+ y[0] = f(ctx, x[0]);
+ y[3] = f(ctx, x[3]);
+
+ for (;;)
+ {
+ int i;
+ int length = x[3] - x[0];
+
+ x[1] = x[0] + length/3;
+ x[2] = x[0] + 2*length/3;
+
+ y[1] = f(ctx, x[1]);
+ y[2] = f(ctx, x[2]);
+
+#if 0
+ printf("%d: %f, %d: %f, %d:, %f %d: %f\n",
+ x[0], y[0], x[1], y[1], x[2], y[2], x[3], y[3]);
+#endif
+ for (best_i = 0, i = 1; i < 4; i++)
+ if (y[i] < y[best_i])
+ best_i = i;
+
+ if (length <= 4)
+ break;
+
+ if (best_i >= 2)
+ {
+ x[0] = x[1];
+ y[0] = y[1];
+ }
+ else
+ {
+ x[3] = x[2];
+ y[3] = y[2];
+ }
+ }
+ *minp = y[best_i];
+ return x[best_i];
+}
+
+static int
+compare_double(const void *ap, const void *bp)
+{
+ double a = * (const double *) ap;
+ double b = * (const double *) bp;
+
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+ else
+ return 0;
+}
+
+static double
+median (double *v, size_t n)
+{
+ qsort(v, n, sizeof(*v), compare_double);
+
+ return v[n/2];
+}
+
+#define TIME(res, code) do { \
+ double time_measurement[5]; \
+ unsigned time_i; \
+ \
+ for (time_i = 0; time_i < 5; time_i++) \
+ { \
+ speed_starttime(); \
+ code; \
+ time_measurement[time_i] = speed_endtime(); \
+ } \
+ res = median(time_measurement, 5); \
+} while (0)
+
+struct bench_data
+{
+ mp_size_t n;
+ mp_ptr ap;
+ mp_ptr bp;
+ mp_ptr up;
+ mp_ptr vp;
+ mp_ptr gp;
+};
+
+static double
+bench_gcd (void *ctx, int p)
+{
+ struct bench_data *data = ctx;
+ double t;
+
+ p_table[data->n] = p;
+ TIME(t, {
+ MPN_COPY (data->up, data->ap, data->n);
+ MPN_COPY (data->vp, data->bp, data->n);
+ mpn_gcd (data->gp, data->up, data->n, data->vp, data->n);
+ });
+
+ return t;
+}
+
+int
+main(int argc, char **argv)
+{
+ gmp_randstate_t rands; struct bench_data data;
+ mp_size_t n;
+
+ TMP_DECL;
+
+ /* Unbuffered so if output is redirected to a file it isn't lost if the
+ program is killed part way through. */
+ setbuf (stdout, NULL);
+ setbuf (stderr, NULL);
+
+ gmp_randinit_default (rands);
+
+ TMP_MARK;
+
+ data.ap = TMP_ALLOC_LIMBS (P_TABLE_SIZE);
+ data.bp = TMP_ALLOC_LIMBS (P_TABLE_SIZE);
+ data.up = TMP_ALLOC_LIMBS (P_TABLE_SIZE);
+ data.vp = TMP_ALLOC_LIMBS (P_TABLE_SIZE);
+ data.gp = TMP_ALLOC_LIMBS (P_TABLE_SIZE);
+
+ mpn_random (data.ap, P_TABLE_SIZE);
+ mpn_random (data.bp, P_TABLE_SIZE);
+
+ memset (p_table, 0, sizeof(p_table));
+
+ for (n = 100; n < P_TABLE_SIZE; n++)
+ {
+ mp_size_t p;
+ mp_size_t best_p;
+ double best_time;
+ double lehmer_time;
+
+ if (data.ap[n-1] == 0)
+ data.ap[n-1] = 1;
+
+ if (data.bp[n-1] == 0)
+ data.bp[n-1] = 1;
+
+ data.n = n;
+
+ lehmer_time = bench_gcd (&data, 0);
+
+ best_p = search (&best_time, bench_gcd, &data, n/5, 4*n/5);
+ if (best_time > lehmer_time)
+ best_p = 0;
+
+ printf("%6d %6d %5.3g", n, best_p, (double) best_p / n);
+ if (best_p > 0)
+ {
+ double speedup = 100 * (lehmer_time - best_time) / lehmer_time;
+ printf(" %5.3g%%", speedup);
+ if (speedup < 1.0)
+ {
+ printf(" (ignored)");
+ best_p = 0;
+ }
+ }
+ printf("\n");
+
+ p_table[n] = best_p;
+ }
+ TMP_FREE;
+ gmp_randclear(rands);
+ return 0;
+}
diff --git a/gmp/tune/tuneup.c b/gmp/tune/tuneup.c
new file mode 100644
index 0000000000..2fba6b2955
--- /dev/null
+++ b/gmp/tune/tuneup.c
@@ -0,0 +1,2912 @@
+/* Create tuned thresholds for various algorithms.
+
+Copyright 1999-2003, 2005, 2006, 2008-2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+
+/* Usage: tuneup [-t] [-t] [-p precision]
+
+ -t turns on some diagnostic traces, a second -t turns on more traces.
+
+ Notes:
+
+ The code here isn't a vision of loveliness, mainly because it's subject
+ to ongoing changes according to new things wanting to be tuned, and
+ practical requirements of systems tested.
+
+ Sometimes running the program twice produces slightly different results.
+ This is probably because there's so little separating algorithms near
+ their crossover, and on that basis it should make little or no difference
+ to the final speed of the relevant routines, but nothing has been done to
+ check that carefully.
+
+ Algorithm:
+
+ The thresholds are determined as follows. A crossover may not be a
+ single size but rather a range where it oscillates between method A or
+ method B faster. If the threshold is set making B used where A is faster
+ (or vice versa) that's bad. Badness is the percentage time lost and
+ total badness is the sum of this over all sizes measured. The threshold
+ is set to minimize total badness.
+
+ Suppose, as sizes increase, method B becomes faster than method A. The
+ effect of the rule is that, as you look at increasing sizes, isolated
+ points where B is faster are ignored, but when it's consistently faster,
+ or faster on balance, then the threshold is set there. The same result
+ is obtained thinking in the other direction of A becoming faster at
+ smaller sizes.
+
+ In practice the thresholds tend to be chosen to bring on the next
+ algorithm fairly quickly.
+
+ This rule is attractive because it's got a basis in reason and is fairly
+ easy to implement, but no work has been done to actually compare it in
+ absolute terms to other possibilities.
+
+ Implementation:
+
+ In a normal library build the thresholds are constants. To tune them
+ selected objects are recompiled with the thresholds as global variables
+ instead. #define TUNE_PROGRAM_BUILD does this, with help from code at
+ the end of gmp-impl.h, and rules in tune/Makefile.am.
+
+ MUL_TOOM22_THRESHOLD for example uses a recompiled mpn_mul_n. The
+ threshold is set to "size+1" to avoid karatsuba, or to "size" to use one
+ level, but recurse into the basecase.
+
+ MUL_TOOM33_THRESHOLD makes use of the tuned MUL_TOOM22_THRESHOLD value.
+ Other routines in turn will make use of both of those. Naturally the
+ dependants must be tuned first.
+
+ In a couple of cases, like DIVEXACT_1_THRESHOLD, there's no recompiling,
+ just a threshold based on comparing two routines (mpn_divrem_1 and
+ mpn_divexact_1), and no further use of the value determined.
+
+ Flags like USE_PREINV_MOD_1 or JACOBI_BASE_METHOD are even simpler, being
+ just comparisons between certain routines on representative data.
+
+ Shortcuts are applied when native (assembler) versions of routines exist.
+ For instance a native mpn_sqr_basecase is assumed to be always faster
+ than mpn_mul_basecase, with no measuring.
+
+ No attempt is made to tune within assembler routines, for instance
+ DIVREM_1_NORM_THRESHOLD. An assembler mpn_divrem_1 is expected to be
+ written and tuned all by hand. Assembler routines that might have hard
+ limits are recompiled though, to make them accept a bigger range of sizes
+ than normal, eg. mpn_sqr_basecase to compare against mpn_toom2_sqr.
+
+ Limitations:
+
+ The FFTs aren't subject to the same badness rule as the other thresholds,
+ so each k is probably being brought on a touch early. This isn't likely
+ to make a difference, and the simpler probing means fewer tests.
+
+*/
+
+#define TUNE_PROGRAM_BUILD 1 /* for gmp-impl.h */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#include "tests.h"
+#include "speed.h"
+
+#if !HAVE_DECL_OPTARG
+extern char *optarg;
+extern int optind, opterr;
+#endif
+
+
+#define DEFAULT_MAX_SIZE 1000 /* limbs */
+
+#if WANT_FFT
+mp_size_t option_fft_max_size = 50000; /* limbs */
+#else
+mp_size_t option_fft_max_size = 0;
+#endif
+int option_trace = 0;
+int option_fft_trace = 0;
+struct speed_params s;
+
+struct dat_t {
+ mp_size_t size;
+ double d;
+} *dat = NULL;
+int ndat = 0;
+int allocdat = 0;
+
+/* This is not defined if mpn_sqr_basecase doesn't declare a limit. In that
+ case use zero here, which for params.max_size means no limit. */
+#ifndef TUNE_SQR_TOOM2_MAX
+#define TUNE_SQR_TOOM2_MAX 0
+#endif
+
+mp_size_t mul_toom22_threshold = MP_SIZE_T_MAX;
+mp_size_t mul_toom33_threshold = MUL_TOOM33_THRESHOLD_LIMIT;
+mp_size_t mul_toom44_threshold = MUL_TOOM44_THRESHOLD_LIMIT;
+mp_size_t mul_toom6h_threshold = MUL_TOOM6H_THRESHOLD_LIMIT;
+mp_size_t mul_toom8h_threshold = MUL_TOOM8H_THRESHOLD_LIMIT;
+mp_size_t mul_toom32_to_toom43_threshold = MP_SIZE_T_MAX;
+mp_size_t mul_toom32_to_toom53_threshold = MP_SIZE_T_MAX;
+mp_size_t mul_toom42_to_toom53_threshold = MP_SIZE_T_MAX;
+mp_size_t mul_toom42_to_toom63_threshold = MP_SIZE_T_MAX;
+mp_size_t mul_toom43_to_toom54_threshold = MP_SIZE_T_MAX;
+mp_size_t mul_fft_threshold = MP_SIZE_T_MAX;
+mp_size_t mul_fft_modf_threshold = MP_SIZE_T_MAX;
+mp_size_t sqr_basecase_threshold = MP_SIZE_T_MAX;
+mp_size_t sqr_toom2_threshold
+ = (TUNE_SQR_TOOM2_MAX == 0 ? MP_SIZE_T_MAX : TUNE_SQR_TOOM2_MAX);
+mp_size_t sqr_toom3_threshold = SQR_TOOM3_THRESHOLD_LIMIT;
+mp_size_t sqr_toom4_threshold = SQR_TOOM4_THRESHOLD_LIMIT;
+mp_size_t sqr_toom6_threshold = SQR_TOOM6_THRESHOLD_LIMIT;
+mp_size_t sqr_toom8_threshold = SQR_TOOM8_THRESHOLD_LIMIT;
+mp_size_t sqr_fft_threshold = MP_SIZE_T_MAX;
+mp_size_t sqr_fft_modf_threshold = MP_SIZE_T_MAX;
+mp_size_t mullo_basecase_threshold = MP_SIZE_T_MAX;
+mp_size_t mullo_dc_threshold = MP_SIZE_T_MAX;
+mp_size_t mullo_mul_n_threshold = MP_SIZE_T_MAX;
+mp_size_t mulmid_toom42_threshold = MP_SIZE_T_MAX;
+mp_size_t mulmod_bnm1_threshold = MP_SIZE_T_MAX;
+mp_size_t sqrmod_bnm1_threshold = MP_SIZE_T_MAX;
+mp_size_t div_qr_2_pi2_threshold = MP_SIZE_T_MAX;
+mp_size_t dc_div_qr_threshold = MP_SIZE_T_MAX;
+mp_size_t dc_divappr_q_threshold = MP_SIZE_T_MAX;
+mp_size_t mu_div_qr_threshold = MP_SIZE_T_MAX;
+mp_size_t mu_divappr_q_threshold = MP_SIZE_T_MAX;
+mp_size_t mupi_div_qr_threshold = MP_SIZE_T_MAX;
+mp_size_t mu_div_q_threshold = MP_SIZE_T_MAX;
+mp_size_t dc_bdiv_qr_threshold = MP_SIZE_T_MAX;
+mp_size_t dc_bdiv_q_threshold = MP_SIZE_T_MAX;
+mp_size_t mu_bdiv_qr_threshold = MP_SIZE_T_MAX;
+mp_size_t mu_bdiv_q_threshold = MP_SIZE_T_MAX;
+mp_size_t inv_mulmod_bnm1_threshold = MP_SIZE_T_MAX;
+mp_size_t inv_newton_threshold = MP_SIZE_T_MAX;
+mp_size_t inv_appr_threshold = MP_SIZE_T_MAX;
+mp_size_t binv_newton_threshold = MP_SIZE_T_MAX;
+mp_size_t redc_1_to_redc_2_threshold = MP_SIZE_T_MAX;
+mp_size_t redc_1_to_redc_n_threshold = MP_SIZE_T_MAX;
+mp_size_t redc_2_to_redc_n_threshold = MP_SIZE_T_MAX;
+mp_size_t matrix22_strassen_threshold = MP_SIZE_T_MAX;
+mp_size_t hgcd_threshold = MP_SIZE_T_MAX;
+mp_size_t hgcd_appr_threshold = MP_SIZE_T_MAX;
+mp_size_t hgcd_reduce_threshold = MP_SIZE_T_MAX;
+mp_size_t gcd_dc_threshold = MP_SIZE_T_MAX;
+mp_size_t gcdext_dc_threshold = MP_SIZE_T_MAX;
+int div_qr_1n_pi1_method = 0;
+mp_size_t div_qr_1_norm_threshold = MP_SIZE_T_MAX;
+mp_size_t div_qr_1_unnorm_threshold = MP_SIZE_T_MAX;
+mp_size_t divrem_1_norm_threshold = MP_SIZE_T_MAX;
+mp_size_t divrem_1_unnorm_threshold = MP_SIZE_T_MAX;
+mp_size_t mod_1_norm_threshold = MP_SIZE_T_MAX;
+mp_size_t mod_1_unnorm_threshold = MP_SIZE_T_MAX;
+int mod_1_1p_method = 0;
+mp_size_t mod_1n_to_mod_1_1_threshold = MP_SIZE_T_MAX;
+mp_size_t mod_1u_to_mod_1_1_threshold = MP_SIZE_T_MAX;
+mp_size_t mod_1_1_to_mod_1_2_threshold = MP_SIZE_T_MAX;
+mp_size_t mod_1_2_to_mod_1_4_threshold = MP_SIZE_T_MAX;
+mp_size_t preinv_mod_1_to_mod_1_threshold = MP_SIZE_T_MAX;
+mp_size_t divrem_2_threshold = MP_SIZE_T_MAX;
+mp_size_t get_str_dc_threshold = MP_SIZE_T_MAX;
+mp_size_t get_str_precompute_threshold = MP_SIZE_T_MAX;
+mp_size_t set_str_dc_threshold = MP_SIZE_T_MAX;
+mp_size_t set_str_precompute_threshold = MP_SIZE_T_MAX;
+mp_size_t fac_odd_threshold = 0;
+mp_size_t fac_dsc_threshold = FAC_DSC_THRESHOLD_LIMIT;
+
+mp_size_t fft_modf_sqr_threshold = MP_SIZE_T_MAX;
+mp_size_t fft_modf_mul_threshold = MP_SIZE_T_MAX;
+
+struct param_t {
+ const char *name;
+ speed_function_t function;
+ speed_function_t function2;
+ double step_factor; /* how much to step relatively */
+ int step; /* how much to step absolutely */
+ double function_fudge; /* multiplier for "function" speeds */
+ int stop_since_change;
+ double stop_factor;
+ mp_size_t min_size;
+ int min_is_always;
+ mp_size_t max_size;
+ mp_size_t check_size;
+ mp_size_t size_extra;
+
+#define DATA_HIGH_LT_R 1
+#define DATA_HIGH_GE_R 2
+ int data_high;
+
+ int noprint;
+};
+
+
+/* These are normally undefined when false, which suits "#if" fine.
+ But give them zero values so they can be used in plain C "if"s. */
+#ifndef UDIV_PREINV_ALWAYS
+#define UDIV_PREINV_ALWAYS 0
+#endif
+#ifndef HAVE_NATIVE_mpn_divexact_1
+#define HAVE_NATIVE_mpn_divexact_1 0
+#endif
+#ifndef HAVE_NATIVE_mpn_div_qr_1n_pi1
+#define HAVE_NATIVE_mpn_div_qr_1n_pi1 0
+#endif
+#ifndef HAVE_NATIVE_mpn_divrem_1
+#define HAVE_NATIVE_mpn_divrem_1 0
+#endif
+#ifndef HAVE_NATIVE_mpn_divrem_2
+#define HAVE_NATIVE_mpn_divrem_2 0
+#endif
+#ifndef HAVE_NATIVE_mpn_mod_1
+#define HAVE_NATIVE_mpn_mod_1 0
+#endif
+#ifndef HAVE_NATIVE_mpn_mod_1_1p
+#define HAVE_NATIVE_mpn_mod_1_1p 0
+#endif
+#ifndef HAVE_NATIVE_mpn_modexact_1_odd
+#define HAVE_NATIVE_mpn_modexact_1_odd 0
+#endif
+#ifndef HAVE_NATIVE_mpn_preinv_divrem_1
+#define HAVE_NATIVE_mpn_preinv_divrem_1 0
+#endif
+#ifndef HAVE_NATIVE_mpn_preinv_mod_1
+#define HAVE_NATIVE_mpn_preinv_mod_1 0
+#endif
+#ifndef HAVE_NATIVE_mpn_sqr_basecase
+#define HAVE_NATIVE_mpn_sqr_basecase 0
+#endif
+
+
+#define MAX3(a,b,c) MAX (MAX (a, b), c)
+
+mp_limb_t
+randlimb_norm (void)
+{
+ mp_limb_t n;
+ mpn_random (&n, 1);
+ n |= GMP_NUMB_HIGHBIT;
+ return n;
+}
+
+#define GMP_NUMB_HALFMASK ((CNST_LIMB(1) << (GMP_NUMB_BITS/2)) - 1)
+
+mp_limb_t
+randlimb_half (void)
+{
+ mp_limb_t n;
+ mpn_random (&n, 1);
+ n &= GMP_NUMB_HALFMASK;
+ n += (n==0);
+ return n;
+}
+
+
+/* Add an entry to the end of the dat[] array, reallocing to make it bigger
+ if necessary. */
+void
+add_dat (mp_size_t size, double d)
+{
+#define ALLOCDAT_STEP 500
+
+ ASSERT_ALWAYS (ndat <= allocdat);
+
+ if (ndat == allocdat)
+ {
+ dat = (struct dat_t *) __gmp_allocate_or_reallocate
+ (dat, allocdat * sizeof(dat[0]),
+ (allocdat+ALLOCDAT_STEP) * sizeof(dat[0]));
+ allocdat += ALLOCDAT_STEP;
+ }
+
+ dat[ndat].size = size;
+ dat[ndat].d = d;
+ ndat++;
+}
+
+
+/* Return the threshold size based on the data accumulated. */
+mp_size_t
+analyze_dat (int final)
+{
+ double x, min_x;
+ int j, min_j;
+
+ /* If the threshold is set at dat[0].size, any positive values are bad. */
+ x = 0.0;
+ for (j = 0; j < ndat; j++)
+ if (dat[j].d > 0.0)
+ x += dat[j].d;
+
+ if (option_trace >= 2 && final)
+ {
+ printf ("\n");
+ printf ("x is the sum of the badness from setting thresh at given size\n");
+ printf (" (minimum x is sought)\n");
+ printf ("size=%ld first x=%.4f\n", (long) dat[j].size, x);
+ }
+
+ min_x = x;
+ min_j = 0;
+
+
+ /* When stepping to the next dat[j].size, positive values are no longer
+ bad (so subtracted), negative values become bad (so add the absolute
+ value, meaning subtract). */
+ for (j = 0; j < ndat; x -= dat[j].d, j++)
+ {
+ if (option_trace >= 2 && final)
+ printf ("size=%ld x=%.4f\n", (long) dat[j].size, x);
+
+ if (x < min_x)
+ {
+ min_x = x;
+ min_j = j;
+ }
+ }
+
+ return min_j;
+}
+
+
+/* Measuring for recompiled mpn/generic/div_qr_1.c,
+ * mpn/generic/divrem_1.c, mpn/generic/mod_1.c and mpz/fac_ui.c */
+
+mp_limb_t mpn_div_qr_1_tune (mp_ptr, mp_limb_t *, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t mpn_divrem_1_tune (mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t);
+mp_limb_t mpn_mod_1_tune (mp_srcptr, mp_size_t, mp_limb_t);
+void mpz_fac_ui_tune (mpz_ptr, unsigned long);
+
+double
+speed_mpn_mod_1_tune (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MOD_1 (mpn_mod_1_tune);
+}
+double
+speed_mpn_divrem_1_tune (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIVREM_1 (mpn_divrem_1_tune);
+}
+double
+speed_mpz_fac_ui_tune (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPZ_FAC_UI (mpz_fac_ui_tune);
+}
+double
+speed_mpn_div_qr_1_tune (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DIV_QR_1 (mpn_div_qr_1_tune);
+}
+
+double
+tuneup_measure (speed_function_t fun,
+ const struct param_t *param,
+ struct speed_params *s)
+{
+ static struct param_t dummy;
+ double t;
+ TMP_DECL;
+
+ if (! param)
+ param = &dummy;
+
+ s->size += param->size_extra;
+
+ TMP_MARK;
+ SPEED_TMP_ALLOC_LIMBS (s->xp, s->size, 0);
+ SPEED_TMP_ALLOC_LIMBS (s->yp, s->size, 0);
+
+ mpn_random (s->xp, s->size);
+ mpn_random (s->yp, s->size);
+
+ switch (param->data_high) {
+ case DATA_HIGH_LT_R:
+ s->xp[s->size-1] %= s->r;
+ s->yp[s->size-1] %= s->r;
+ break;
+ case DATA_HIGH_GE_R:
+ s->xp[s->size-1] |= s->r;
+ s->yp[s->size-1] |= s->r;
+ break;
+ }
+
+ t = speed_measure (fun, s);
+
+ s->size -= param->size_extra;
+
+ TMP_FREE;
+ return t;
+}
+
+
+#define PRINT_WIDTH 31
+
+void
+print_define_start (const char *name)
+{
+ printf ("#define %-*s ", PRINT_WIDTH, name);
+ if (option_trace)
+ printf ("...\n");
+}
+
+void
+print_define_end_remark (const char *name, mp_size_t value, const char *remark)
+{
+ if (option_trace)
+ printf ("#define %-*s ", PRINT_WIDTH, name);
+
+ if (value == MP_SIZE_T_MAX)
+ printf ("MP_SIZE_T_MAX");
+ else
+ printf ("%5ld", (long) value);
+
+ if (remark != NULL)
+ printf (" /* %s */", remark);
+ printf ("\n");
+ fflush (stdout);
+}
+
+void
+print_define_end (const char *name, mp_size_t value)
+{
+ const char *remark;
+ if (value == MP_SIZE_T_MAX)
+ remark = "never";
+ else if (value == 0)
+ remark = "always";
+ else
+ remark = NULL;
+ print_define_end_remark (name, value, remark);
+}
+
+void
+print_define (const char *name, mp_size_t value)
+{
+ print_define_start (name);
+ print_define_end (name, value);
+}
+
+void
+print_define_remark (const char *name, mp_size_t value, const char *remark)
+{
+ print_define_start (name);
+ print_define_end_remark (name, value, remark);
+}
+
+
+void
+one (mp_size_t *threshold, struct param_t *param)
+{
+ int since_positive, since_thresh_change;
+ int thresh_idx, new_thresh_idx;
+
+#define DEFAULT(x,n) do { if (! (x)) (x) = (n); } while (0)
+
+ DEFAULT (param->function_fudge, 1.0);
+ DEFAULT (param->function2, param->function);
+ DEFAULT (param->step_factor, 0.01); /* small steps by default */
+ DEFAULT (param->step, 1); /* small steps by default */
+ DEFAULT (param->stop_since_change, 80);
+ DEFAULT (param->stop_factor, 1.2);
+ DEFAULT (param->min_size, 10);
+ DEFAULT (param->max_size, DEFAULT_MAX_SIZE);
+
+ if (param->check_size != 0)
+ {
+ double t1, t2;
+ s.size = param->check_size;
+
+ *threshold = s.size+1;
+ t1 = tuneup_measure (param->function, param, &s);
+
+ *threshold = s.size;
+ t2 = tuneup_measure (param->function2, param, &s);
+ if (t1 == -1.0 || t2 == -1.0)
+ {
+ printf ("Oops, can't run both functions at size %ld\n",
+ (long) s.size);
+ abort ();
+ }
+ t1 *= param->function_fudge;
+
+ /* ask that t2 is at least 4% below t1 */
+ if (t1 < t2*1.04)
+ {
+ if (option_trace)
+ printf ("function2 never enough faster: t1=%.9f t2=%.9f\n", t1, t2);
+ *threshold = MP_SIZE_T_MAX;
+ if (! param->noprint)
+ print_define (param->name, *threshold);
+ return;
+ }
+
+ if (option_trace >= 2)
+ printf ("function2 enough faster at size=%ld: t1=%.9f t2=%.9f\n",
+ (long) s.size, t1, t2);
+ }
+
+ if (! param->noprint || option_trace)
+ print_define_start (param->name);
+
+ ndat = 0;
+ since_positive = 0;
+ since_thresh_change = 0;
+ thresh_idx = 0;
+
+ if (option_trace >= 2)
+ {
+ printf (" algorithm-A algorithm-B ratio possible\n");
+ printf (" (seconds) (seconds) diff thresh\n");
+ }
+
+ for (s.size = param->min_size;
+ s.size < param->max_size;
+ s.size += MAX ((mp_size_t) floor (s.size * param->step_factor), param->step))
+ {
+ double ti, tiplus1, d;
+
+ /*
+ FIXME: check minimum size requirements are met, possibly by just
+ checking for the -1 returns from the speed functions.
+ */
+
+ /* using method A at this size */
+ *threshold = s.size+1;
+ ti = tuneup_measure (param->function, param, &s);
+ if (ti == -1.0)
+ abort ();
+ ti *= param->function_fudge;
+
+ /* using method B at this size */
+ *threshold = s.size;
+ tiplus1 = tuneup_measure (param->function2, param, &s);
+ if (tiplus1 == -1.0)
+ abort ();
+
+ /* Calculate the fraction by which the one or the other routine is
+ slower. */
+ if (tiplus1 >= ti)
+ d = (tiplus1 - ti) / tiplus1; /* negative */
+ else
+ d = (tiplus1 - ti) / ti; /* positive */
+
+ add_dat (s.size, d);
+
+ new_thresh_idx = analyze_dat (0);
+
+ if (option_trace >= 2)
+ printf ("size=%ld %.9f %.9f % .4f %c %ld\n",
+ (long) s.size, ti, tiplus1, d,
+ ti > tiplus1 ? '#' : ' ',
+ (long) dat[new_thresh_idx].size);
+
+ /* Stop if the last time method i was faster was more than a
+ certain number of measurements ago. */
+#define STOP_SINCE_POSITIVE 200
+ if (d >= 0)
+ since_positive = 0;
+ else
+ if (++since_positive > STOP_SINCE_POSITIVE)
+ {
+ if (option_trace >= 1)
+ printf ("stopped due to since_positive (%d)\n",
+ STOP_SINCE_POSITIVE);
+ break;
+ }
+
+ /* Stop if method A has become slower by a certain factor. */
+ if (ti >= tiplus1 * param->stop_factor)
+ {
+ if (option_trace >= 1)
+ printf ("stopped due to ti >= tiplus1 * factor (%.1f)\n",
+ param->stop_factor);
+ break;
+ }
+
+ /* Stop if the threshold implied hasn't changed in a certain
+ number of measurements. (It's this condition that usually
+ stops the loop.) */
+ if (thresh_idx != new_thresh_idx)
+ since_thresh_change = 0, thresh_idx = new_thresh_idx;
+ else
+ if (++since_thresh_change > param->stop_since_change)
+ {
+ if (option_trace >= 1)
+ printf ("stopped due to since_thresh_change (%d)\n",
+ param->stop_since_change);
+ break;
+ }
+
+ /* Stop if the threshold implied is more than a certain number of
+ measurements ago. */
+#define STOP_SINCE_AFTER 500
+ if (ndat - thresh_idx > STOP_SINCE_AFTER)
+ {
+ if (option_trace >= 1)
+ printf ("stopped due to ndat - thresh_idx > amount (%d)\n",
+ STOP_SINCE_AFTER);
+ break;
+ }
+
+ /* Stop when the size limit is reached before the end of the
+ crossover, but only show this as an error for >= the default max
+ size. FIXME: Maybe should make it a param choice whether this is
+ an error. */
+ if (s.size >= param->max_size && param->max_size >= DEFAULT_MAX_SIZE)
+ {
+ fprintf (stderr, "%s\n", param->name);
+ fprintf (stderr, "sizes %ld to %ld total %d measurements\n",
+ (long) dat[0].size, (long) dat[ndat-1].size, ndat);
+ fprintf (stderr, " max size reached before end of crossover\n");
+ break;
+ }
+ }
+
+ if (option_trace >= 1)
+ printf ("sizes %ld to %ld total %d measurements\n",
+ (long) dat[0].size, (long) dat[ndat-1].size, ndat);
+
+ *threshold = dat[analyze_dat (1)].size;
+
+ if (param->min_is_always)
+ {
+ if (*threshold == param->min_size)
+ *threshold = 0;
+ }
+
+ if (! param->noprint || option_trace)
+ print_define_end (param->name, *threshold);
+}
+
+
+/* Special probing for the fft thresholds. The size restrictions on the
+ FFTs mean the graph of time vs size has a step effect. See this for
+ example using
+
+ ./speed -s 4096-16384 -t 128 -P foo mpn_mul_fft.8 mpn_mul_fft.9
+ gnuplot foo.gnuplot
+
+ The current approach is to compare routines at the midpoint of relevant
+ steps. Arguably a more sophisticated system of threshold data is wanted
+ if this step effect remains. */
+
+struct fft_param_t {
+ const char *table_name;
+ const char *threshold_name;
+ const char *modf_threshold_name;
+ mp_size_t *p_threshold;
+ mp_size_t *p_modf_threshold;
+ mp_size_t first_size;
+ mp_size_t max_size;
+ speed_function_t function;
+ speed_function_t mul_modf_function;
+ speed_function_t mul_function;
+ mp_size_t sqr;
+};
+
+
+/* mpn_mul_fft requires pl a multiple of 2^k limbs, but with
+ N=pl*BIT_PER_MP_LIMB it internally also pads out so N/2^k is a multiple
+ of 2^(k-1) bits. */
+
+mp_size_t
+fft_step_size (int k)
+{
+ mp_size_t step;
+
+ step = MAX ((mp_size_t) 1 << (k-1), GMP_LIMB_BITS) / GMP_LIMB_BITS;
+ step *= (mp_size_t) 1 << k;
+
+ if (step <= 0)
+ {
+ printf ("Can't handle k=%d\n", k);
+ abort ();
+ }
+
+ return step;
+}
+
+mp_size_t
+fft_next_size (mp_size_t pl, int k)
+{
+ mp_size_t m = fft_step_size (k);
+
+/* printf ("[k=%d %ld] %ld ->", k, m, pl); */
+
+ if (pl == 0 || (pl & (m-1)) != 0)
+ pl = (pl | (m-1)) + 1;
+
+/* printf (" %ld\n", pl); */
+ return pl;
+}
+
+#define NMAX_DEFAULT 1000000
+#define MAX_REPS 25
+#define MIN_REPS 5
+
+static inline size_t
+mpn_mul_fft_lcm (size_t a, unsigned int k)
+{
+ unsigned int l = k;
+
+ while (a % 2 == 0 && k > 0)
+ {
+ a >>= 1;
+ k--;
+ }
+ return a << l;
+}
+
+mp_size_t
+fftfill (mp_size_t pl, int k, int sqr)
+{
+ mp_size_t maxLK;
+ mp_bitcnt_t N, Nprime, nprime, M;
+
+ N = pl * GMP_NUMB_BITS;
+ M = N >> k;
+
+ maxLK = mpn_mul_fft_lcm ((unsigned long) GMP_NUMB_BITS, k);
+
+ Nprime = (1 + (2 * M + k + 2) / maxLK) * maxLK;
+ nprime = Nprime / GMP_NUMB_BITS;
+ if (nprime >= (sqr ? SQR_FFT_MODF_THRESHOLD : MUL_FFT_MODF_THRESHOLD))
+ {
+ size_t K2;
+ for (;;)
+ {
+ K2 = 1L << mpn_fft_best_k (nprime, sqr);
+ if ((nprime & (K2 - 1)) == 0)
+ break;
+ nprime = (nprime + K2 - 1) & -K2;
+ Nprime = nprime * GMP_LIMB_BITS;
+ }
+ }
+ ASSERT_ALWAYS (nprime < pl);
+
+ return Nprime;
+}
+
+static int
+compare_double (const void *ap, const void *bp)
+{
+ double a = * (const double *) ap;
+ double b = * (const double *) bp;
+
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+ else
+ return 0;
+}
+
+double
+median (double *times, int n)
+{
+ qsort (times, n, sizeof (double), compare_double);
+ return times[n/2];
+}
+
+#define FFT_CACHE_SIZE 25
+typedef struct fft_cache
+{
+ mp_size_t n;
+ double time;
+} fft_cache_t;
+
+fft_cache_t fft_cache[FFT_CACHE_SIZE];
+
+double
+cached_measure (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n, int k,
+ int n_measurements)
+{
+ int i;
+ double t, ttab[MAX_REPS];
+
+ if (fft_cache[k].n == n)
+ return fft_cache[k].time;
+
+ for (i = 0; i < n_measurements; i++)
+ {
+ speed_starttime ();
+ mpn_mul_fft (rp, n, ap, n, bp, n, k);
+ ttab[i] = speed_endtime ();
+ }
+
+ t = median (ttab, n_measurements);
+ fft_cache[k].n = n;
+ fft_cache[k].time = t;
+ return t;
+}
+
+#define INSERT_FFTTAB(idx, nval, kval) \
+ do { \
+ fft_tab[idx].n = nval; \
+ fft_tab[idx].k = kval; \
+ fft_tab[idx+1].n = -1; /* sentinel */ \
+ fft_tab[idx+1].k = -1; \
+ } while (0)
+
+int
+fftmes (mp_size_t nmin, mp_size_t nmax, int initial_k, struct fft_param_t *p, int idx, int print)
+{
+ mp_size_t n, n1, prev_n1;
+ int k, best_k, last_best_k, kmax;
+ int eff, prev_eff;
+ double t0, t1;
+ int n_measurements;
+ mp_limb_t *ap, *bp, *rp;
+ mp_size_t alloc;
+ char *linepref;
+ struct fft_table_nk *fft_tab;
+
+ fft_tab = mpn_fft_table3[p->sqr];
+
+ for (k = 0; k < FFT_CACHE_SIZE; k++)
+ fft_cache[k].n = 0;
+
+ if (nmin < (p->sqr ? SQR_FFT_MODF_THRESHOLD : MUL_FFT_MODF_THRESHOLD))
+ {
+ nmin = (p->sqr ? SQR_FFT_MODF_THRESHOLD : MUL_FFT_MODF_THRESHOLD);
+ }
+
+ if (print)
+ printf ("#define %s%*s", p->table_name, 38, "");
+
+ if (idx == 0)
+ {
+ INSERT_FFTTAB (0, nmin, initial_k);
+
+ if (print)
+ {
+ printf ("\\\n { ");
+ printf ("{%7u,%2u}", fft_tab[0].n, fft_tab[0].k);
+ linepref = " ";
+ }
+
+ idx = 1;
+ }
+
+ ap = malloc (sizeof (mp_limb_t));
+ if (p->sqr)
+ bp = ap;
+ else
+ bp = malloc (sizeof (mp_limb_t));
+ rp = malloc (sizeof (mp_limb_t));
+ alloc = 1;
+
+ /* Round n to comply to initial k value */
+ n = (nmin + ((1ul << initial_k) - 1)) & (MP_SIZE_T_MAX << initial_k);
+
+ n_measurements = (18 - initial_k) | 1;
+ n_measurements = MAX (n_measurements, MIN_REPS);
+ n_measurements = MIN (n_measurements, MAX_REPS);
+
+ last_best_k = initial_k;
+ best_k = initial_k;
+
+ while (n < nmax)
+ {
+ int start_k, end_k;
+
+ /* Assume the current best k is best until we hit its next FFT step. */
+ t0 = 99999;
+
+ prev_n1 = n + 1;
+
+ start_k = MAX (4, best_k - 4);
+ end_k = MIN (24, best_k + 4);
+ for (k = start_k; k <= end_k; k++)
+ {
+ n1 = mpn_fft_next_size (prev_n1, k);
+
+ eff = 200 * (n1 * GMP_NUMB_BITS >> k) / fftfill (n1, k, p->sqr);
+
+ if (eff < 70) /* avoid measuring too slow fft:s */
+ continue;
+
+ if (n1 > alloc)
+ {
+ alloc = n1;
+ if (p->sqr)
+ {
+ ap = realloc (ap, sizeof (mp_limb_t));
+ rp = realloc (rp, sizeof (mp_limb_t));
+ ap = bp = realloc (ap, alloc * sizeof (mp_limb_t));
+ mpn_random (ap, alloc);
+ rp = realloc (rp, alloc * sizeof (mp_limb_t));
+ }
+ else
+ {
+ ap = realloc (ap, sizeof (mp_limb_t));
+ bp = realloc (bp, sizeof (mp_limb_t));
+ rp = realloc (rp, sizeof (mp_limb_t));
+ ap = realloc (ap, alloc * sizeof (mp_limb_t));
+ mpn_random (ap, alloc);
+ bp = realloc (bp, alloc * sizeof (mp_limb_t));
+ mpn_random (bp, alloc);
+ rp = realloc (rp, alloc * sizeof (mp_limb_t));
+ }
+ }
+
+ t1 = cached_measure (rp, ap, bp, n1, k, n_measurements);
+
+ if (t1 * n_measurements > 0.3)
+ n_measurements -= 2;
+ n_measurements = MAX (n_measurements, MIN_REPS);
+
+ if (t1 < t0)
+ {
+ best_k = k;
+ t0 = t1;
+ }
+ }
+
+ n1 = mpn_fft_next_size (prev_n1, best_k);
+
+ if (last_best_k != best_k)
+ {
+ ASSERT_ALWAYS ((prev_n1 & ((1ul << last_best_k) - 1)) == 1);
+
+ if (idx >= FFT_TABLE3_SIZE)
+ {
+ printf ("FFT table exhausted, increase FFT_TABLE3_SIZE in gmp-impl.h\n");
+ abort ();
+ }
+ INSERT_FFTTAB (idx, prev_n1 >> last_best_k, best_k);
+
+ if (print)
+ {
+ printf (", ");
+ if (idx % 4 == 0)
+ printf ("\\\n ");
+ printf ("{%7u,%2u}", fft_tab[idx].n, fft_tab[idx].k);
+ }
+
+ if (option_trace >= 2)
+ {
+ printf ("{%lu,%u}\n", prev_n1, best_k);
+ fflush (stdout);
+ }
+
+ last_best_k = best_k;
+ idx++;
+ }
+
+ for (;;)
+ {
+ prev_n1 = n1;
+ prev_eff = fftfill (prev_n1, best_k, p->sqr);
+ n1 = mpn_fft_next_size (prev_n1 + 1, best_k);
+ eff = fftfill (n1, best_k, p->sqr);
+
+ if (eff != prev_eff)
+ break;
+ }
+
+ n = prev_n1;
+ }
+
+ kmax = sizeof (mp_size_t) * 4; /* GMP_MP_SIZE_T_BITS / 2 */
+ kmax = MIN (kmax, 25-1);
+ for (k = last_best_k + 1; k <= kmax; k++)
+ {
+ if (idx >= FFT_TABLE3_SIZE)
+ {
+ printf ("FFT table exhausted, increase FFT_TABLE3_SIZE in gmp-impl.h\n");
+ abort ();
+ }
+ INSERT_FFTTAB (idx, ((1ul << (2*k-2)) + 1) >> (k-1), k);
+
+ if (print)
+ {
+ printf (", ");
+ if (idx % 4 == 0)
+ printf ("\\\n ");
+ printf ("{%7u,%2u}", fft_tab[idx].n, fft_tab[idx].k);
+ }
+
+ idx++;
+ }
+
+ if (print)
+ printf (" }\n");
+
+ free (ap);
+ if (! p->sqr)
+ free (bp);
+ free (rp);
+
+ return idx;
+}
+
+void
+fft (struct fft_param_t *p)
+{
+ mp_size_t size;
+ int k, idx, initial_k;
+
+ /*** Generate MUL_FFT_MODF_THRESHOLD / SQR_FFT_MODF_THRESHOLD ***/
+
+#if 1
+ {
+ /* Use plain one() mechanism, for some reasonable initial values of k. The
+ advantage is that we don't depend on mpn_fft_table3, which can therefore
+ leave it completely uninitialized. */
+
+ static struct param_t param;
+ mp_size_t thres, best_thres;
+ int best_k;
+ char buf[20];
+
+ best_thres = MP_SIZE_T_MAX;
+ best_k = -1;
+
+ for (k = 5; k <= 7; k++)
+ {
+ param.name = p->modf_threshold_name;
+ param.min_size = 100;
+ param.max_size = 2000;
+ param.function = p->mul_function;
+ param.step_factor = 0.0;
+ param.step = 4;
+ param.function2 = p->mul_modf_function;
+ param.noprint = 1;
+ s.r = k;
+ one (&thres, &param);
+ if (thres < best_thres)
+ {
+ best_thres = thres;
+ best_k = k;
+ }
+ }
+
+ *(p->p_modf_threshold) = best_thres;
+ sprintf (buf, "k = %d", best_k);
+ print_define_remark (p->modf_threshold_name, best_thres, buf);
+ initial_k = best_k;
+ }
+#else
+ size = p->first_size;
+ for (;;)
+ {
+ double tk, tm;
+
+ size = mpn_fft_next_size (size+1, mpn_fft_best_k (size+1, p->sqr));
+ k = mpn_fft_best_k (size, p->sqr);
+
+ if (size >= p->max_size)
+ break;
+
+ s.size = size + fft_step_size (k) / 2;
+ s.r = k;
+ tk = tuneup_measure (p->mul_modf_function, NULL, &s);
+ if (tk == -1.0)
+ abort ();
+
+ tm = tuneup_measure (p->mul_function, NULL, &s);
+ if (tm == -1.0)
+ abort ();
+
+ if (option_trace >= 2)
+ printf ("at %ld size=%ld k=%d %.9f size=%ld modf %.9f\n",
+ (long) size,
+ (long) size + fft_step_size (k) / 2, k, tk,
+ (long) s.size, tm);
+
+ if (tk < tm)
+ {
+ *p->p_modf_threshold = s.size;
+ print_define (p->modf_threshold_name, *p->p_modf_threshold);
+ break;
+ }
+ }
+ initial_k = ?;
+#endif
+
+ /*** Generate MUL_FFT_TABLE3 / SQR_FFT_TABLE3 ***/
+
+ idx = fftmes (*p->p_modf_threshold, p->max_size, initial_k, p, 0, 1);
+ printf ("#define %s_SIZE %d\n", p->table_name, idx);
+
+ /*** Generate MUL_FFT_THRESHOLD / SQR_FFT_THRESHOLD ***/
+
+ size = 2 * *p->p_modf_threshold; /* OK? */
+ for (;;)
+ {
+ double tk, tm;
+ mp_size_t mulmod_size, mul_size;;
+
+ if (size >= p->max_size)
+ break;
+
+ mulmod_size = mpn_mulmod_bnm1_next_size (2 * (size + 1)) / 2;
+ mul_size = (size + mulmod_size) / 2; /* middle of step */
+
+ s.size = mulmod_size;
+ tk = tuneup_measure (p->function, NULL, &s);
+ if (tk == -1.0)
+ abort ();
+
+ s.size = mul_size;
+ tm = tuneup_measure (p->mul_function, NULL, &s);
+ if (tm == -1.0)
+ abort ();
+
+ if (option_trace >= 2)
+ printf ("at %ld size=%ld %.9f size=%ld mul %.9f\n",
+ (long) size,
+ (long) mulmod_size, tk,
+ (long) mul_size, tm);
+
+ size = mulmod_size;
+
+ if (tk < tm)
+ {
+ *p->p_threshold = s.size;
+ print_define (p->threshold_name, *p->p_threshold);
+ break;
+ }
+ }
+}
+
+
+
+/* Start karatsuba from 4, since the Cray t90 ieee code is much faster at 2,
+ giving wrong results. */
+void
+tune_mul_n (void)
+{
+ static struct param_t param;
+ mp_size_t next_toom_start;
+ int something_changed;
+
+ param.function = speed_mpn_mul_n;
+
+ param.name = "MUL_TOOM22_THRESHOLD";
+ param.min_size = MAX (4, MPN_TOOM22_MUL_MINSIZE);
+ param.max_size = MUL_TOOM22_THRESHOLD_LIMIT-1;
+ one (&mul_toom22_threshold, &param);
+
+ param.noprint = 1;
+
+ /* Threshold sequence loop. Disable functions that would be used in a very
+ narrow range, re-measuring things when that happens. */
+ something_changed = 1;
+ while (something_changed)
+ {
+ something_changed = 0;
+
+ next_toom_start = mul_toom22_threshold;
+
+ if (mul_toom33_threshold != 0)
+ {
+ param.name = "MUL_TOOM33_THRESHOLD";
+ param.min_size = MAX (next_toom_start, MPN_TOOM33_MUL_MINSIZE);
+ param.max_size = MUL_TOOM33_THRESHOLD_LIMIT-1;
+ one (&mul_toom33_threshold, &param);
+
+ if (next_toom_start * 1.05 >= mul_toom33_threshold)
+ {
+ mul_toom33_threshold = 0;
+ something_changed = 1;
+ }
+ }
+
+ next_toom_start = MAX (next_toom_start, mul_toom33_threshold);
+
+ if (mul_toom44_threshold != 0)
+ {
+ param.name = "MUL_TOOM44_THRESHOLD";
+ param.min_size = MAX (next_toom_start, MPN_TOOM44_MUL_MINSIZE);
+ param.max_size = MUL_TOOM44_THRESHOLD_LIMIT-1;
+ one (&mul_toom44_threshold, &param);
+
+ if (next_toom_start * 1.05 >= mul_toom44_threshold)
+ {
+ mul_toom44_threshold = 0;
+ something_changed = 1;
+ }
+ }
+
+ next_toom_start = MAX (next_toom_start, mul_toom44_threshold);
+
+ if (mul_toom6h_threshold != 0)
+ {
+ param.name = "MUL_TOOM6H_THRESHOLD";
+ param.min_size = MAX (next_toom_start, MPN_TOOM6H_MUL_MINSIZE);
+ param.max_size = MUL_TOOM6H_THRESHOLD_LIMIT-1;
+ one (&mul_toom6h_threshold, &param);
+
+ if (next_toom_start * 1.05 >= mul_toom6h_threshold)
+ {
+ mul_toom6h_threshold = 0;
+ something_changed = 1;
+ }
+ }
+
+ next_toom_start = MAX (next_toom_start, mul_toom6h_threshold);
+
+ if (mul_toom8h_threshold != 0)
+ {
+ param.name = "MUL_TOOM8H_THRESHOLD";
+ param.min_size = MAX (next_toom_start, MPN_TOOM8H_MUL_MINSIZE);
+ param.max_size = MUL_TOOM8H_THRESHOLD_LIMIT-1;
+ one (&mul_toom8h_threshold, &param);
+
+ if (next_toom_start * 1.05 >= mul_toom8h_threshold)
+ {
+ mul_toom8h_threshold = 0;
+ something_changed = 1;
+ }
+ }
+ }
+
+ print_define ("MUL_TOOM33_THRESHOLD", MUL_TOOM33_THRESHOLD);
+ print_define ("MUL_TOOM44_THRESHOLD", MUL_TOOM44_THRESHOLD);
+ print_define ("MUL_TOOM6H_THRESHOLD", MUL_TOOM6H_THRESHOLD);
+ print_define ("MUL_TOOM8H_THRESHOLD", MUL_TOOM8H_THRESHOLD);
+
+ /* disabled until tuned */
+ MUL_FFT_THRESHOLD = MP_SIZE_T_MAX;
+}
+
+void
+tune_mul (void)
+{
+ static struct param_t param;
+ mp_size_t thres;
+
+ param.noprint = 1;
+
+ param.function = speed_mpn_toom32_for_toom43_mul;
+ param.function2 = speed_mpn_toom43_for_toom32_mul;
+ param.name = "MUL_TOOM32_TO_TOOM43_THRESHOLD";
+ param.min_size = MPN_TOOM43_MUL_MINSIZE * 24 / 17;
+ one (&thres, &param);
+ mul_toom32_to_toom43_threshold = thres * 17 / 24;
+ print_define ("MUL_TOOM32_TO_TOOM43_THRESHOLD", mul_toom32_to_toom43_threshold);
+
+ param.function = speed_mpn_toom32_for_toom53_mul;
+ param.function2 = speed_mpn_toom53_for_toom32_mul;
+ param.name = "MUL_TOOM32_TO_TOOM53_THRESHOLD";
+ param.min_size = MPN_TOOM53_MUL_MINSIZE * 30 / 19;
+ one (&thres, &param);
+ mul_toom32_to_toom53_threshold = thres * 19 / 30;
+ print_define ("MUL_TOOM32_TO_TOOM53_THRESHOLD", mul_toom32_to_toom53_threshold);
+
+ param.function = speed_mpn_toom42_for_toom53_mul;
+ param.function2 = speed_mpn_toom53_for_toom42_mul;
+ param.name = "MUL_TOOM42_TO_TOOM53_THRESHOLD";
+ param.min_size = MPN_TOOM53_MUL_MINSIZE * 20 / 11;
+ one (&thres, &param);
+ mul_toom42_to_toom53_threshold = thres * 11 / 20;
+ print_define ("MUL_TOOM42_TO_TOOM53_THRESHOLD", mul_toom42_to_toom53_threshold);
+
+ param.function = speed_mpn_toom42_mul;
+ param.function2 = speed_mpn_toom63_mul;
+ param.name = "MUL_TOOM42_TO_TOOM63_THRESHOLD";
+ param.min_size = MPN_TOOM63_MUL_MINSIZE * 2;
+ one (&thres, &param);
+ mul_toom42_to_toom63_threshold = thres / 2;
+ print_define ("MUL_TOOM42_TO_TOOM63_THRESHOLD", mul_toom42_to_toom63_threshold);
+
+ /* Use ratio 5/6 when measuring, the middle of the range 2/3 to 1. */
+ param.function = speed_mpn_toom43_for_toom54_mul;
+ param.function2 = speed_mpn_toom54_for_toom43_mul;
+ param.name = "MUL_TOOM43_TO_TOOM54_THRESHOLD";
+ param.min_size = MPN_TOOM54_MUL_MINSIZE * 6 / 5;
+ one (&thres, &param);
+ mul_toom43_to_toom54_threshold = thres * 5 / 6;
+ print_define ("MUL_TOOM43_TO_TOOM54_THRESHOLD", mul_toom43_to_toom54_threshold);
+}
+
+
+void
+tune_mullo (void)
+{
+ static struct param_t param;
+
+ param.function = speed_mpn_mullo_n;
+
+ param.name = "MULLO_BASECASE_THRESHOLD";
+ param.min_size = 1;
+ param.min_is_always = 1;
+ param.max_size = MULLO_BASECASE_THRESHOLD_LIMIT-1;
+ param.stop_factor = 1.5;
+ param.noprint = 1;
+ one (&mullo_basecase_threshold, &param);
+
+ param.name = "MULLO_DC_THRESHOLD";
+ param.min_size = 8;
+ param.min_is_always = 0;
+ param.max_size = 1000;
+ one (&mullo_dc_threshold, &param);
+
+ if (mullo_basecase_threshold >= mullo_dc_threshold)
+ {
+ print_define ("MULLO_BASECASE_THRESHOLD", mullo_dc_threshold);
+ print_define_remark ("MULLO_DC_THRESHOLD", 0, "never mpn_mullo_basecase");
+ }
+ else
+ {
+ print_define ("MULLO_BASECASE_THRESHOLD", mullo_basecase_threshold);
+ print_define ("MULLO_DC_THRESHOLD", mullo_dc_threshold);
+ }
+
+#if WANT_FFT
+ param.name = "MULLO_MUL_N_THRESHOLD";
+ param.min_size = mullo_dc_threshold;
+ param.max_size = 2 * mul_fft_threshold;
+ param.noprint = 0;
+ param.step_factor = 0.03;
+ one (&mullo_mul_n_threshold, &param);
+#else
+ print_define_remark ("MULLO_MUL_N_THRESHOLD", MP_SIZE_T_MAX,
+ "without FFT use mullo forever");
+#endif
+}
+
+void
+tune_mulmid (void)
+{
+ static struct param_t param;
+
+ param.name = "MULMID_TOOM42_THRESHOLD";
+ param.function = speed_mpn_mulmid_n;
+ param.min_size = 4;
+ param.max_size = 100;
+ one (&mulmid_toom42_threshold, &param);
+}
+
+void
+tune_mulmod_bnm1 (void)
+{
+ static struct param_t param;
+
+ param.name = "MULMOD_BNM1_THRESHOLD";
+ param.function = speed_mpn_mulmod_bnm1;
+ param.min_size = 4;
+ param.max_size = 100;
+ one (&mulmod_bnm1_threshold, &param);
+}
+
+void
+tune_sqrmod_bnm1 (void)
+{
+ static struct param_t param;
+
+ param.name = "SQRMOD_BNM1_THRESHOLD";
+ param.function = speed_mpn_sqrmod_bnm1;
+ param.min_size = 4;
+ param.max_size = 100;
+ one (&sqrmod_bnm1_threshold, &param);
+}
+
+
+/* Start the basecase from 3, since 1 is a special case, and if mul_basecase
+ is faster only at size==2 then we don't want to bother with extra code
+ just for that. Start karatsuba from 4 same as MUL above. */
+
+void
+tune_sqr (void)
+{
+ /* disabled until tuned */
+ SQR_FFT_THRESHOLD = MP_SIZE_T_MAX;
+
+ if (HAVE_NATIVE_mpn_sqr_basecase)
+ {
+ print_define_remark ("SQR_BASECASE_THRESHOLD", 0, "always (native)");
+ sqr_basecase_threshold = 0;
+ }
+ else
+ {
+ static struct param_t param;
+ param.name = "SQR_BASECASE_THRESHOLD";
+ param.function = speed_mpn_sqr;
+ param.min_size = 3;
+ param.min_is_always = 1;
+ param.max_size = TUNE_SQR_TOOM2_MAX;
+ param.noprint = 1;
+ one (&sqr_basecase_threshold, &param);
+ }
+
+ {
+ static struct param_t param;
+ param.name = "SQR_TOOM2_THRESHOLD";
+ param.function = speed_mpn_sqr;
+ param.min_size = MAX (4, MPN_TOOM2_SQR_MINSIZE);
+ param.max_size = TUNE_SQR_TOOM2_MAX;
+ param.noprint = 1;
+ one (&sqr_toom2_threshold, &param);
+
+ if (! HAVE_NATIVE_mpn_sqr_basecase
+ && sqr_toom2_threshold < sqr_basecase_threshold)
+ {
+ /* Karatsuba becomes faster than mul_basecase before
+ sqr_basecase does. Arrange for the expression
+ "BELOW_THRESHOLD (un, SQR_TOOM2_THRESHOLD))" which
+ selects mpn_sqr_basecase in mpn_sqr to be false, by setting
+ SQR_TOOM2_THRESHOLD to zero, making
+ SQR_BASECASE_THRESHOLD the toom2 threshold. */
+
+ sqr_basecase_threshold = SQR_TOOM2_THRESHOLD;
+ SQR_TOOM2_THRESHOLD = 0;
+
+ print_define_remark ("SQR_BASECASE_THRESHOLD", sqr_basecase_threshold,
+ "toom2");
+ print_define_remark ("SQR_TOOM2_THRESHOLD",SQR_TOOM2_THRESHOLD,
+ "never sqr_basecase");
+ }
+ else
+ {
+ if (! HAVE_NATIVE_mpn_sqr_basecase)
+ print_define ("SQR_BASECASE_THRESHOLD", sqr_basecase_threshold);
+ print_define ("SQR_TOOM2_THRESHOLD", SQR_TOOM2_THRESHOLD);
+ }
+ }
+
+ {
+ static struct param_t param;
+ mp_size_t next_toom_start;
+ int something_changed;
+
+ param.function = speed_mpn_sqr;
+ param.noprint = 1;
+
+ /* Threshold sequence loop. Disable functions that would be used in a very
+ narrow range, re-measuring things when that happens. */
+ something_changed = 1;
+ while (something_changed)
+ {
+ something_changed = 0;
+
+ next_toom_start = MAX (sqr_toom2_threshold, sqr_basecase_threshold);
+
+ sqr_toom3_threshold = SQR_TOOM3_THRESHOLD_LIMIT;
+ param.name = "SQR_TOOM3_THRESHOLD";
+ param.min_size = MAX (next_toom_start, MPN_TOOM3_SQR_MINSIZE);
+ param.max_size = SQR_TOOM3_THRESHOLD_LIMIT-1;
+ one (&sqr_toom3_threshold, &param);
+
+ next_toom_start = MAX (next_toom_start, sqr_toom3_threshold);
+
+ if (sqr_toom4_threshold != 0)
+ {
+ param.name = "SQR_TOOM4_THRESHOLD";
+ sqr_toom4_threshold = SQR_TOOM4_THRESHOLD_LIMIT;
+ param.min_size = MAX (next_toom_start, MPN_TOOM4_SQR_MINSIZE);
+ param.max_size = SQR_TOOM4_THRESHOLD_LIMIT-1;
+ one (&sqr_toom4_threshold, &param);
+
+ if (next_toom_start * 1.05 >= sqr_toom4_threshold)
+ {
+ sqr_toom4_threshold = 0;
+ something_changed = 1;
+ }
+ }
+
+ next_toom_start = MAX (next_toom_start, sqr_toom4_threshold);
+
+ if (sqr_toom6_threshold != 0)
+ {
+ param.name = "SQR_TOOM6_THRESHOLD";
+ sqr_toom6_threshold = SQR_TOOM6_THRESHOLD_LIMIT;
+ param.min_size = MAX (next_toom_start, MPN_TOOM6_SQR_MINSIZE);
+ param.max_size = SQR_TOOM6_THRESHOLD_LIMIT-1;
+ one (&sqr_toom6_threshold, &param);
+
+ if (next_toom_start * 1.05 >= sqr_toom6_threshold)
+ {
+ sqr_toom6_threshold = 0;
+ something_changed = 1;
+ }
+ }
+
+ next_toom_start = MAX (next_toom_start, sqr_toom6_threshold);
+
+ if (sqr_toom8_threshold != 0)
+ {
+ param.name = "SQR_TOOM8_THRESHOLD";
+ sqr_toom8_threshold = SQR_TOOM8_THRESHOLD_LIMIT;
+ param.min_size = MAX (next_toom_start, MPN_TOOM8_SQR_MINSIZE);
+ param.max_size = SQR_TOOM8_THRESHOLD_LIMIT-1;
+ one (&sqr_toom8_threshold, &param);
+
+ if (next_toom_start * 1.05 >= sqr_toom8_threshold)
+ {
+ sqr_toom8_threshold = 0;
+ something_changed = 1;
+ }
+ }
+ }
+
+ print_define ("SQR_TOOM3_THRESHOLD", SQR_TOOM3_THRESHOLD);
+ print_define ("SQR_TOOM4_THRESHOLD", SQR_TOOM4_THRESHOLD);
+ print_define ("SQR_TOOM6_THRESHOLD", SQR_TOOM6_THRESHOLD);
+ print_define ("SQR_TOOM8_THRESHOLD", SQR_TOOM8_THRESHOLD);
+ }
+}
+
+
+void
+tune_dc_div (void)
+{
+ s.r = 0; /* clear to make speed function do 2n/n */
+ {
+ static struct param_t param;
+ param.name = "DC_DIV_QR_THRESHOLD";
+ param.function = speed_mpn_sbpi1_div_qr;
+ param.function2 = speed_mpn_dcpi1_div_qr;
+ param.min_size = 6;
+ one (&dc_div_qr_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "DC_DIVAPPR_Q_THRESHOLD";
+ param.function = speed_mpn_sbpi1_divappr_q;
+ param.function2 = speed_mpn_dcpi1_divappr_q;
+ param.min_size = 6;
+ one (&dc_divappr_q_threshold, &param);
+ }
+}
+
+static double
+speed_mpn_sbordcpi1_div_qr (struct speed_params *s)
+{
+ if (s->size < DC_DIV_QR_THRESHOLD)
+ return speed_mpn_sbpi1_div_qr (s);
+ else
+ return speed_mpn_dcpi1_div_qr (s);
+}
+
+void
+tune_mu_div (void)
+{
+ s.r = 0; /* clear to make speed function do 2n/n */
+ {
+ static struct param_t param;
+ param.name = "MU_DIV_QR_THRESHOLD";
+ param.function = speed_mpn_dcpi1_div_qr;
+ param.function2 = speed_mpn_mu_div_qr;
+ param.min_size = mul_toom22_threshold;
+ param.max_size = 5000;
+ param.step_factor = 0.02;
+ one (&mu_div_qr_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "MU_DIVAPPR_Q_THRESHOLD";
+ param.function = speed_mpn_dcpi1_divappr_q;
+ param.function2 = speed_mpn_mu_divappr_q;
+ param.min_size = mul_toom22_threshold;
+ param.max_size = 5000;
+ param.step_factor = 0.02;
+ one (&mu_divappr_q_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "MUPI_DIV_QR_THRESHOLD";
+ param.function = speed_mpn_sbordcpi1_div_qr;
+ param.function2 = speed_mpn_mupi_div_qr;
+ param.min_size = 6;
+ param.min_is_always = 1;
+ param.max_size = 1000;
+ param.step_factor = 0.02;
+ one (&mupi_div_qr_threshold, &param);
+ }
+}
+
+void
+tune_dc_bdiv (void)
+{
+ s.r = 0; /* clear to make speed function do 2n/n*/
+ {
+ static struct param_t param;
+ param.name = "DC_BDIV_QR_THRESHOLD";
+ param.function = speed_mpn_sbpi1_bdiv_qr;
+ param.function2 = speed_mpn_dcpi1_bdiv_qr;
+ param.min_size = 4;
+ one (&dc_bdiv_qr_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "DC_BDIV_Q_THRESHOLD";
+ param.function = speed_mpn_sbpi1_bdiv_q;
+ param.function2 = speed_mpn_dcpi1_bdiv_q;
+ param.min_size = 4;
+ one (&dc_bdiv_q_threshold, &param);
+ }
+}
+
+void
+tune_mu_bdiv (void)
+{
+ s.r = 0; /* clear to make speed function do 2n/n*/
+ {
+ static struct param_t param;
+ param.name = "MU_BDIV_QR_THRESHOLD";
+ param.function = speed_mpn_dcpi1_bdiv_qr;
+ param.function2 = speed_mpn_mu_bdiv_qr;
+ param.min_size = mul_toom22_threshold;
+ param.max_size = 5000;
+ param.step_factor = 0.02;
+ one (&mu_bdiv_qr_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "MU_BDIV_Q_THRESHOLD";
+ param.function = speed_mpn_dcpi1_bdiv_q;
+ param.function2 = speed_mpn_mu_bdiv_q;
+ param.min_size = mul_toom22_threshold;
+ param.max_size = 5000;
+ param.step_factor = 0.02;
+ one (&mu_bdiv_q_threshold, &param);
+ }
+}
+
+void
+tune_invertappr (void)
+{
+ static struct param_t param;
+
+ param.function = speed_mpn_ni_invertappr;
+ param.name = "INV_MULMOD_BNM1_THRESHOLD";
+ param.min_size = 4;
+ one (&inv_mulmod_bnm1_threshold, &param);
+
+ param.function = speed_mpn_invertappr;
+ param.name = "INV_NEWTON_THRESHOLD";
+ param.min_size = 3;
+ one (&inv_newton_threshold, &param);
+}
+
+void
+tune_invert (void)
+{
+ static struct param_t param;
+
+ param.function = speed_mpn_invert;
+ param.name = "INV_APPR_THRESHOLD";
+ param.min_size = 3;
+ one (&inv_appr_threshold, &param);
+}
+
+void
+tune_binvert (void)
+{
+ static struct param_t param;
+
+ param.function = speed_mpn_binvert;
+ param.name = "BINV_NEWTON_THRESHOLD";
+ param.min_size = 8; /* pointless with smaller operands */
+ one (&binv_newton_threshold, &param);
+}
+
+void
+tune_redc (void)
+{
+#define TUNE_REDC_2_MAX 100
+#if HAVE_NATIVE_mpn_addmul_2 || HAVE_NATIVE_mpn_redc_2
+#define WANT_REDC_2 1
+#endif
+
+#if WANT_REDC_2
+ {
+ static struct param_t param;
+ param.name = "REDC_1_TO_REDC_2_THRESHOLD";
+ param.function = speed_mpn_redc_1;
+ param.function2 = speed_mpn_redc_2;
+ param.min_size = 1;
+ param.min_is_always = 1;
+ param.max_size = TUNE_REDC_2_MAX;
+ param.noprint = 1;
+ param.stop_factor = 1.5;
+ one (&redc_1_to_redc_2_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "REDC_2_TO_REDC_N_THRESHOLD";
+ param.function = speed_mpn_redc_2;
+ param.function2 = speed_mpn_redc_n;
+ param.min_size = 16;
+ param.noprint = 1;
+ one (&redc_2_to_redc_n_threshold, &param);
+ }
+ if (redc_1_to_redc_2_threshold >= redc_2_to_redc_n_threshold)
+ {
+ redc_2_to_redc_n_threshold = 0; /* disable redc_2 */
+
+ /* Never use redc2, measure redc_1 -> redc_n cutoff, store result as
+ REDC_1_TO_REDC_2_THRESHOLD. */
+ {
+ static struct param_t param;
+ param.name = "REDC_1_TO_REDC_2_THRESHOLD";
+ param.function = speed_mpn_redc_1;
+ param.function2 = speed_mpn_redc_n;
+ param.min_size = 16;
+ param.noprint = 1;
+ one (&redc_1_to_redc_2_threshold, &param);
+ }
+ }
+ print_define ("REDC_1_TO_REDC_2_THRESHOLD", REDC_1_TO_REDC_2_THRESHOLD);
+ print_define ("REDC_2_TO_REDC_N_THRESHOLD", REDC_2_TO_REDC_N_THRESHOLD);
+#else
+ {
+ static struct param_t param;
+ param.name = "REDC_1_TO_REDC_N_THRESHOLD";
+ param.function = speed_mpn_redc_1;
+ param.function2 = speed_mpn_redc_n;
+ param.min_size = 16;
+ one (&redc_1_to_redc_n_threshold, &param);
+ }
+#endif
+}
+
+void
+tune_matrix22_mul (void)
+{
+ static struct param_t param;
+ param.name = "MATRIX22_STRASSEN_THRESHOLD";
+ param.function = speed_mpn_matrix22_mul;
+ param.min_size = 2;
+ one (&matrix22_strassen_threshold, &param);
+}
+
+void
+tune_hgcd (void)
+{
+ static struct param_t param;
+ param.name = "HGCD_THRESHOLD";
+ param.function = speed_mpn_hgcd;
+ /* We seem to get strange results for small sizes */
+ param.min_size = 30;
+ one (&hgcd_threshold, &param);
+}
+
+void
+tune_hgcd_appr (void)
+{
+ static struct param_t param;
+ param.name = "HGCD_APPR_THRESHOLD";
+ param.function = speed_mpn_hgcd_appr;
+ /* We seem to get strange results for small sizes */
+ param.min_size = 50;
+ param.stop_since_change = 150;
+ one (&hgcd_appr_threshold, &param);
+}
+
+void
+tune_hgcd_reduce (void)
+{
+ static struct param_t param;
+ param.name = "HGCD_REDUCE_THRESHOLD";
+ param.function = speed_mpn_hgcd_reduce;
+ param.min_size = 30;
+ param.max_size = 7000;
+ param.step_factor = 0.04;
+ one (&hgcd_reduce_threshold, &param);
+}
+
+void
+tune_gcd_dc (void)
+{
+ static struct param_t param;
+ param.name = "GCD_DC_THRESHOLD";
+ param.function = speed_mpn_gcd;
+ param.min_size = hgcd_threshold;
+ param.max_size = 3000;
+ param.step_factor = 0.02;
+ one (&gcd_dc_threshold, &param);
+}
+
+void
+tune_gcdext_dc (void)
+{
+ static struct param_t param;
+ param.name = "GCDEXT_DC_THRESHOLD";
+ param.function = speed_mpn_gcdext;
+ param.min_size = hgcd_threshold;
+ param.max_size = 3000;
+ param.step_factor = 0.02;
+ one (&gcdext_dc_threshold, &param);
+}
+
+/* In tune_powm_sec we compute the table used by the win_size function. The
+ cutoff points are in exponent bits, disregarding other operand sizes. It is
+ not possible to use the one framework since it currently uses a granularity
+ of full limbs.
+*/
+
+/* This win_size replaces the variant in the powm code, allowing us to
+ control k in the k-ary algorithms. */
+int winsize;
+int
+win_size (mp_bitcnt_t eb)
+{
+ return winsize;
+}
+
+void
+tune_powm_sec (void)
+{
+ mp_size_t n;
+ int k, i;
+ mp_size_t itch;
+ mp_bitcnt_t nbits, nbits_next, possible_nbits_cutoff;
+ const int n_max = 3000 / GMP_NUMB_BITS;
+ const int n_measurements = 5;
+ mp_ptr rp, bp, ep, mp, tp;
+ double ttab[n_measurements], tk, tkp1;
+ TMP_DECL;
+ TMP_MARK;
+
+ possible_nbits_cutoff = 0;
+
+ k = 1;
+
+ winsize = 10; /* the itch function needs this */
+ itch = mpn_sec_powm_itch (n_max, n_max * GMP_NUMB_BITS, n_max);
+
+ rp = TMP_ALLOC_LIMBS (n_max);
+ bp = TMP_ALLOC_LIMBS (n_max);
+ ep = TMP_ALLOC_LIMBS (n_max);
+ mp = TMP_ALLOC_LIMBS (n_max);
+ tp = TMP_ALLOC_LIMBS (itch);
+
+ mpn_random (bp, n_max);
+ mpn_random (mp, n_max);
+ mp[0] |= 1;
+
+/* How about taking the M operand size into account?
+
+ An operation R=powm(B,E,N) will take time O(log(E)*M(log(N))) (assuming
+ B = O(M)).
+
+ Using k-ary and no sliding window, the precomputation will need time
+ O(2^(k-1)*M(log(N))) and the main computation will need O(log(E)*S(N)) +
+ O(log(E)/k*M(N)), for the squarings, multiplications, respectively.
+
+ An operation R=powm_sec(B,E,N) will take time like powm.
+
+ Using k-ary, the precomputation will need time O(2^k*M(log(N))) and the
+ main computation will need O(log(E)*S(N)) + O(log(E)/k*M(N)) +
+ O(log(E)/k*2^k*log(N)), for the squarings, multiplications, and full
+ table reads, respectively. */
+
+ printf ("#define POWM_SEC_TABLE ");
+
+ /* For nbits == 1, we should always use k == 1, so no need to tune
+ that. Starting with nbits == 2 also ensure that nbits always is
+ larger than the windowsize k+1. */
+ for (nbits = 2; nbits <= n_max * GMP_NUMB_BITS; )
+ {
+ n = (nbits - 1) / GMP_NUMB_BITS + 1;
+
+ /* Generate E such that sliding-window for k and k+1 works equally
+ well/poorly (but sliding is not used in powm_sec, of course). */
+ for (i = 0; i < n; i++)
+ ep[i] = ~CNST_LIMB(0);
+
+ winsize = k;
+ for (i = 0; i < n_measurements; i++)
+ {
+ speed_starttime ();
+ mpn_sec_powm (rp, bp, n, ep, nbits, mp, n, tp);
+ ttab[i] = speed_endtime ();
+ }
+ tk = median (ttab, n_measurements);
+
+ winsize = k + 1;
+ speed_starttime ();
+ for (i = 0; i < n_measurements; i++)
+ {
+ speed_starttime ();
+ mpn_sec_powm (rp, bp, n, ep, nbits, mp, n, tp);
+ ttab[i] = speed_endtime ();
+ }
+ tkp1 = median (ttab, n_measurements);
+/*
+ printf ("testing: %ld, %d", nbits, k, ep[n-1]);
+ printf (" %10.5f %10.5f\n", tk, tkp1);
+*/
+ if (tkp1 < tk)
+ {
+ if (possible_nbits_cutoff)
+ {
+ /* Two consecutive sizes indicate k increase, obey. */
+
+ /* Must always have x[k] >= k */
+ ASSERT_ALWAYS (possible_nbits_cutoff >= k);
+
+ if (k > 1)
+ printf (",");
+ printf ("%ld", (long) possible_nbits_cutoff);
+ k++;
+ possible_nbits_cutoff = 0;
+ }
+ else
+ {
+ /* One measurement indicate k increase, save nbits for further
+ consideration. */
+ /* The new larger k gets used for sizes > the cutoff
+ value, hence the cutoff should be one less than the
+ smallest size where it gives a speedup. */
+ possible_nbits_cutoff = nbits - 1;
+ }
+ }
+ else
+ possible_nbits_cutoff = 0;
+
+ nbits_next = nbits * 65 / 64;
+ nbits = nbits_next + (nbits_next == nbits);
+ }
+ printf ("\n");
+ TMP_FREE;
+}
+
+
+/* size_extra==1 reflects the fact that with high<divisor one division is
+ always skipped. Forcing high<divisor while testing ensures consistency
+ while stepping through sizes, ie. that size-1 divides will be done each
+ time.
+
+ min_size==2 and min_is_always are used so that if plain division is only
+ better at size==1 then don't bother including that code just for that
+ case, instead go with preinv always and get a size saving. */
+
+#define DIV_1_PARAMS \
+ param.check_size = 256; \
+ param.min_size = 2; \
+ param.min_is_always = 1; \
+ param.data_high = DATA_HIGH_LT_R; \
+ param.size_extra = 1; \
+ param.stop_factor = 2.0;
+
+
+double (*tuned_speed_mpn_divrem_1) (struct speed_params *);
+
+void
+tune_divrem_1 (void)
+{
+ /* plain version by default */
+ tuned_speed_mpn_divrem_1 = speed_mpn_divrem_1;
+
+ /* No support for tuning native assembler code, do that by hand and put
+ the results in the .asm file, there's no need for such thresholds to
+ appear in gmp-mparam.h. */
+ if (HAVE_NATIVE_mpn_divrem_1)
+ return;
+
+ if (GMP_NAIL_BITS != 0)
+ {
+ print_define_remark ("DIVREM_1_NORM_THRESHOLD", MP_SIZE_T_MAX,
+ "no preinv with nails");
+ print_define_remark ("DIVREM_1_UNNORM_THRESHOLD", MP_SIZE_T_MAX,
+ "no preinv with nails");
+ return;
+ }
+
+ if (UDIV_PREINV_ALWAYS)
+ {
+ print_define_remark ("DIVREM_1_NORM_THRESHOLD", 0L, "preinv always");
+ print_define ("DIVREM_1_UNNORM_THRESHOLD", 0L);
+ return;
+ }
+
+ tuned_speed_mpn_divrem_1 = speed_mpn_divrem_1_tune;
+
+ /* Tune for the integer part of mpn_divrem_1. This will very possibly be
+ a bit out for the fractional part, but that's too bad, the integer part
+ is more important. */
+ {
+ static struct param_t param;
+ param.name = "DIVREM_1_NORM_THRESHOLD";
+ DIV_1_PARAMS;
+ s.r = randlimb_norm ();
+ param.function = speed_mpn_divrem_1_tune;
+ one (&divrem_1_norm_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "DIVREM_1_UNNORM_THRESHOLD";
+ DIV_1_PARAMS;
+ s.r = randlimb_half ();
+ param.function = speed_mpn_divrem_1_tune;
+ one (&divrem_1_unnorm_threshold, &param);
+ }
+}
+
+void
+tune_div_qr_1 (void)
+{
+ static struct param_t param;
+ double t1, t2;
+
+ if (!HAVE_NATIVE_mpn_div_qr_1n_pi1)
+ {
+ static struct param_t param;
+ double t1, t2;
+
+ s.size = 10;
+ s.r = randlimb_norm ();
+
+ t1 = tuneup_measure (speed_mpn_div_qr_1n_pi1_1, &param, &s);
+ t2 = tuneup_measure (speed_mpn_div_qr_1n_pi1_2, &param, &s);
+
+ if (t1 == -1.0 || t2 == -1.0)
+ {
+ printf ("Oops, can't measure all mpn_div_qr_1n_pi1 methods at %ld\n",
+ (long) s.size);
+ abort ();
+ }
+ div_qr_1n_pi1_method = (t1 < t2) ? 1 : 2;
+ print_define ("DIV_QR_1N_PI1_METHOD", div_qr_1n_pi1_method);
+ }
+
+ {
+ static struct param_t param;
+ param.name = "DIV_QR_1_NORM_THRESHOLD";
+ DIV_1_PARAMS;
+ param.min_size = 1;
+ param.min_is_always = 0;
+ s.r = randlimb_norm ();
+ param.function = speed_mpn_div_qr_1_tune;
+ one (&div_qr_1_norm_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "DIV_QR_1_UNNORM_THRESHOLD";
+ DIV_1_PARAMS;
+ param.min_size = 1;
+ param.min_is_always = 0;
+ s.r = randlimb_half();
+ param.function = speed_mpn_div_qr_1_tune;
+ one (&div_qr_1_unnorm_threshold, &param);
+ }
+}
+
+
+void
+tune_mod_1 (void)
+{
+ /* No support for tuning native assembler code, do that by hand and put
+ the results in the .asm file, there's no need for such thresholds to
+ appear in gmp-mparam.h. */
+ if (HAVE_NATIVE_mpn_mod_1)
+ return;
+
+ if (GMP_NAIL_BITS != 0)
+ {
+ print_define_remark ("MOD_1_NORM_THRESHOLD", MP_SIZE_T_MAX,
+ "no preinv with nails");
+ print_define_remark ("MOD_1_UNNORM_THRESHOLD", MP_SIZE_T_MAX,
+ "no preinv with nails");
+ return;
+ }
+
+ if (!HAVE_NATIVE_mpn_mod_1_1p)
+ {
+ static struct param_t param;
+ double t1, t2;
+
+ s.size = 10;
+ s.r = randlimb_half ();
+
+ t1 = tuneup_measure (speed_mpn_mod_1_1_1, &param, &s);
+ t2 = tuneup_measure (speed_mpn_mod_1_1_2, &param, &s);
+
+ if (t1 == -1.0 || t2 == -1.0)
+ {
+ printf ("Oops, can't measure all mpn_mod_1_1 methods at %ld\n",
+ (long) s.size);
+ abort ();
+ }
+ mod_1_1p_method = (t1 < t2) ? 1 : 2;
+ print_define ("MOD_1_1P_METHOD", mod_1_1p_method);
+ }
+
+ if (UDIV_PREINV_ALWAYS)
+ {
+ print_define ("MOD_1_NORM_THRESHOLD", 0L);
+ print_define ("MOD_1_UNNORM_THRESHOLD", 0L);
+ }
+ else
+ {
+ {
+ static struct param_t param;
+ param.name = "MOD_1_NORM_THRESHOLD";
+ DIV_1_PARAMS;
+ s.r = randlimb_norm ();
+ param.function = speed_mpn_mod_1_tune;
+ one (&mod_1_norm_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "MOD_1_UNNORM_THRESHOLD";
+ DIV_1_PARAMS;
+ s.r = randlimb_half ();
+ param.function = speed_mpn_mod_1_tune;
+ one (&mod_1_unnorm_threshold, &param);
+ }
+ }
+ {
+ static struct param_t param;
+
+ param.check_size = 256;
+
+ s.r = randlimb_norm ();
+ param.function = speed_mpn_mod_1_tune;
+
+ param.name = "MOD_1N_TO_MOD_1_1_THRESHOLD";
+ param.min_size = 2;
+ one (&mod_1n_to_mod_1_1_threshold, &param);
+ }
+
+ {
+ static struct param_t param;
+
+ param.check_size = 256;
+ s.r = randlimb_half ();
+ param.noprint = 1;
+
+ param.function = speed_mpn_mod_1_1;
+ param.function2 = speed_mpn_mod_1_2;
+ param.min_is_always = 1;
+ param.name = "MOD_1_1_TO_MOD_1_2_THRESHOLD";
+ param.min_size = 2;
+ one (&mod_1_1_to_mod_1_2_threshold, &param);
+
+ param.function = speed_mpn_mod_1_2;
+ param.function2 = speed_mpn_mod_1_4;
+ param.min_is_always = 1;
+ param.name = "MOD_1_2_TO_MOD_1_4_THRESHOLD";
+ param.min_size = 1;
+ one (&mod_1_2_to_mod_1_4_threshold, &param);
+
+ if (mod_1_1_to_mod_1_2_threshold >= mod_1_2_to_mod_1_4_threshold)
+ {
+ /* Never use mod_1_2, measure mod_1_1 -> mod_1_4 */
+ mod_1_2_to_mod_1_4_threshold = 0;
+
+ param.function = speed_mpn_mod_1_1;
+ param.function2 = speed_mpn_mod_1_4;
+ param.min_is_always = 1;
+ param.name = "MOD_1_1_TO_MOD_1_4_THRESHOLD fake";
+ param.min_size = 2;
+ one (&mod_1_1_to_mod_1_2_threshold, &param);
+ }
+
+ param.function = speed_mpn_mod_1_tune;
+ param.function2 = NULL;
+ param.name = "MOD_1U_TO_MOD_1_1_THRESHOLD";
+ param.min_size = 2;
+ param.min_is_always = 0;
+ one (&mod_1u_to_mod_1_1_threshold, &param);
+
+ if (mod_1u_to_mod_1_1_threshold >= mod_1_1_to_mod_1_2_threshold)
+ mod_1_1_to_mod_1_2_threshold = 0;
+ if (mod_1u_to_mod_1_1_threshold >= mod_1_2_to_mod_1_4_threshold)
+ mod_1_2_to_mod_1_4_threshold = 0;
+
+ print_define_remark ("MOD_1U_TO_MOD_1_1_THRESHOLD", mod_1u_to_mod_1_1_threshold, NULL);
+ print_define_remark ("MOD_1_1_TO_MOD_1_2_THRESHOLD", mod_1_1_to_mod_1_2_threshold,
+ mod_1_1_to_mod_1_2_threshold == 0 ? "never mpn_mod_1_1p" : NULL);
+ print_define_remark ("MOD_1_2_TO_MOD_1_4_THRESHOLD", mod_1_2_to_mod_1_4_threshold,
+ mod_1_2_to_mod_1_4_threshold == 0 ? "never mpn_mod_1s_2p" : NULL);
+ }
+
+ {
+ static struct param_t param;
+
+ param.check_size = 256;
+
+ param.name = "PREINV_MOD_1_TO_MOD_1_THRESHOLD";
+ s.r = randlimb_norm ();
+ param.function = speed_mpn_preinv_mod_1;
+ param.function2 = speed_mpn_mod_1_tune;
+ param.min_size = 1;
+ one (&preinv_mod_1_to_mod_1_threshold, &param);
+ }
+}
+
+
+/* A non-zero DIVREM_1_UNNORM_THRESHOLD (or DIVREM_1_NORM_THRESHOLD) would
+ imply that udiv_qrnnd_preinv is worth using, but it seems most
+ straightforward to compare mpn_preinv_divrem_1 and mpn_divrem_1_div
+ directly. */
+
+void
+tune_preinv_divrem_1 (void)
+{
+ static struct param_t param;
+ speed_function_t divrem_1;
+ const char *divrem_1_name;
+ double t1, t2;
+
+ if (GMP_NAIL_BITS != 0)
+ {
+ print_define_remark ("USE_PREINV_DIVREM_1", 0, "no preinv with nails");
+ return;
+ }
+
+ /* Any native version of mpn_preinv_divrem_1 is assumed to exist because
+ it's faster than mpn_divrem_1. */
+ if (HAVE_NATIVE_mpn_preinv_divrem_1)
+ {
+ print_define_remark ("USE_PREINV_DIVREM_1", 1, "native");
+ return;
+ }
+
+ /* If udiv_qrnnd_preinv is the only division method then of course
+ mpn_preinv_divrem_1 should be used. */
+ if (UDIV_PREINV_ALWAYS)
+ {
+ print_define_remark ("USE_PREINV_DIVREM_1", 1, "preinv always");
+ return;
+ }
+
+ /* If we've got an assembler version of mpn_divrem_1, then compare against
+ that, not the mpn_divrem_1_div generic C. */
+ if (HAVE_NATIVE_mpn_divrem_1)
+ {
+ divrem_1 = speed_mpn_divrem_1;
+ divrem_1_name = "mpn_divrem_1";
+ }
+ else
+ {
+ divrem_1 = speed_mpn_divrem_1_div;
+ divrem_1_name = "mpn_divrem_1_div";
+ }
+
+ param.data_high = DATA_HIGH_LT_R; /* allow skip one division */
+ s.size = 200; /* generous but not too big */
+ /* Divisor, nonzero. Unnormalized so as to exercise the shift!=0 case,
+ since in general that's probably most common, though in fact for a
+ 64-bit limb mp_bases[10].big_base is normalized. */
+ s.r = urandom() & (GMP_NUMB_MASK >> 4);
+ if (s.r == 0) s.r = 123;
+
+ t1 = tuneup_measure (speed_mpn_preinv_divrem_1, &param, &s);
+ t2 = tuneup_measure (divrem_1, &param, &s);
+ if (t1 == -1.0 || t2 == -1.0)
+ {
+ printf ("Oops, can't measure mpn_preinv_divrem_1 and %s at %ld\n",
+ divrem_1_name, (long) s.size);
+ abort ();
+ }
+ if (option_trace >= 1)
+ printf ("size=%ld, mpn_preinv_divrem_1 %.9f, %s %.9f\n",
+ (long) s.size, t1, divrem_1_name, t2);
+
+ print_define_remark ("USE_PREINV_DIVREM_1", (mp_size_t) (t1 < t2), NULL);
+}
+
+
+
+void
+tune_divrem_2 (void)
+{
+ static struct param_t param;
+
+ /* No support for tuning native assembler code, do that by hand and put
+ the results in the .asm file, and there's no need for such thresholds
+ to appear in gmp-mparam.h. */
+ if (HAVE_NATIVE_mpn_divrem_2)
+ return;
+
+ if (GMP_NAIL_BITS != 0)
+ {
+ print_define_remark ("DIVREM_2_THRESHOLD", MP_SIZE_T_MAX,
+ "no preinv with nails");
+ return;
+ }
+
+ if (UDIV_PREINV_ALWAYS)
+ {
+ print_define_remark ("DIVREM_2_THRESHOLD", 0L, "preinv always");
+ return;
+ }
+
+ /* Tune for the integer part of mpn_divrem_2. This will very possibly be
+ a bit out for the fractional part, but that's too bad, the integer part
+ is more important.
+
+ min_size must be >=2 since nsize>=2 is required, but is set to 4 to save
+ code space if plain division is better only at size==2 or size==3. */
+ param.name = "DIVREM_2_THRESHOLD";
+ param.check_size = 256;
+ param.min_size = 4;
+ param.min_is_always = 1;
+ param.size_extra = 2; /* does qsize==nsize-2 divisions */
+ param.stop_factor = 2.0;
+
+ s.r = randlimb_norm ();
+ param.function = speed_mpn_divrem_2;
+ one (&divrem_2_threshold, &param);
+}
+
+void
+tune_div_qr_2 (void)
+{
+ static struct param_t param;
+ param.name = "DIV_QR_2_PI2_THRESHOLD";
+ param.function = speed_mpn_div_qr_2n;
+ param.check_size = 500;
+ param.min_size = 4;
+ one (&div_qr_2_pi2_threshold, &param);
+}
+
+/* mpn_divexact_1 is vaguely expected to be used on smallish divisors, so
+ tune for that. Its speed can differ on odd or even divisor, so take an
+ average threshold for the two.
+
+ mpn_divrem_1 can vary with high<divisor or not, whereas mpn_divexact_1
+ might not vary that way, but don't test this since high<divisor isn't
+ expected to occur often with small divisors. */
+
+void
+tune_divexact_1 (void)
+{
+ static struct param_t param;
+ mp_size_t thresh[2], average;
+ int low, i;
+
+ /* Any native mpn_divexact_1 is assumed to incorporate all the speed of a
+ full mpn_divrem_1. */
+ if (HAVE_NATIVE_mpn_divexact_1)
+ {
+ print_define_remark ("DIVEXACT_1_THRESHOLD", 0, "always (native)");
+ return;
+ }
+
+ ASSERT_ALWAYS (tuned_speed_mpn_divrem_1 != NULL);
+
+ param.name = "DIVEXACT_1_THRESHOLD";
+ param.data_high = DATA_HIGH_GE_R;
+ param.check_size = 256;
+ param.min_size = 2;
+ param.stop_factor = 1.5;
+ param.function = tuned_speed_mpn_divrem_1;
+ param.function2 = speed_mpn_divexact_1;
+ param.noprint = 1;
+
+ print_define_start (param.name);
+
+ for (low = 0; low <= 1; low++)
+ {
+ s.r = randlimb_half();
+ if (low == 0)
+ s.r |= 1;
+ else
+ s.r &= ~CNST_LIMB(7);
+
+ one (&thresh[low], &param);
+ if (option_trace)
+ printf ("low=%d thresh %ld\n", low, (long) thresh[low]);
+
+ if (thresh[low] == MP_SIZE_T_MAX)
+ {
+ average = MP_SIZE_T_MAX;
+ goto divexact_1_done;
+ }
+ }
+
+ if (option_trace)
+ {
+ printf ("average of:");
+ for (i = 0; i < numberof(thresh); i++)
+ printf (" %ld", (long) thresh[i]);
+ printf ("\n");
+ }
+
+ average = 0;
+ for (i = 0; i < numberof(thresh); i++)
+ average += thresh[i];
+ average /= numberof(thresh);
+
+ /* If divexact turns out to be better as early as 3 limbs, then use it
+ always, so as to reduce code size and conditional jumps. */
+ if (average <= 3)
+ average = 0;
+
+ divexact_1_done:
+ print_define_end (param.name, average);
+}
+
+
+/* The generic mpn_modexact_1_odd skips a divide step if high<divisor, the
+ same as mpn_mod_1, but this might not be true of an assembler
+ implementation. The threshold used is an average based on data where a
+ divide can be skipped and where it can't.
+
+ If modexact turns out to be better as early as 3 limbs, then use it
+ always, so as to reduce code size and conditional jumps. */
+
+void
+tune_modexact_1_odd (void)
+{
+ static struct param_t param;
+ mp_size_t thresh_lt, thresh_ge, average;
+
+#if 0
+ /* Any native mpn_modexact_1_odd is assumed to incorporate all the speed
+ of a full mpn_mod_1. */
+ if (HAVE_NATIVE_mpn_modexact_1_odd)
+ {
+ print_define_remark ("BMOD_1_TO_MOD_1_THRESHOLD", MP_SIZE_T_MAX, "always bmod_1");
+ return;
+ }
+#endif
+
+ param.name = "BMOD_1_TO_MOD_1_THRESHOLD";
+ param.check_size = 256;
+ param.min_size = 2;
+ param.stop_factor = 1.5;
+ param.function = speed_mpn_modexact_1c_odd;
+ param.function2 = speed_mpn_mod_1_tune;
+ param.noprint = 1;
+ s.r = randlimb_half () | 1;
+
+ print_define_start (param.name);
+
+ param.data_high = DATA_HIGH_LT_R;
+ one (&thresh_lt, &param);
+ if (option_trace)
+ printf ("lt thresh %ld\n", (long) thresh_lt);
+
+ average = thresh_lt;
+ if (thresh_lt != MP_SIZE_T_MAX)
+ {
+ param.data_high = DATA_HIGH_GE_R;
+ one (&thresh_ge, &param);
+ if (option_trace)
+ printf ("ge thresh %ld\n", (long) thresh_ge);
+
+ if (thresh_ge != MP_SIZE_T_MAX)
+ {
+ average = (thresh_ge + thresh_lt) / 2;
+ if (thresh_ge <= 3)
+ average = 0;
+ }
+ }
+
+ print_define_end (param.name, average);
+}
+
+
+void
+tune_jacobi_base (void)
+{
+ static struct param_t param;
+ double t1, t2, t3, t4;
+ int method;
+
+ s.size = GMP_LIMB_BITS * 3 / 4;
+
+ t1 = tuneup_measure (speed_mpn_jacobi_base_1, &param, &s);
+ if (option_trace >= 1)
+ printf ("size=%ld, mpn_jacobi_base_1 %.9f\n", (long) s.size, t1);
+
+ t2 = tuneup_measure (speed_mpn_jacobi_base_2, &param, &s);
+ if (option_trace >= 1)
+ printf ("size=%ld, mpn_jacobi_base_2 %.9f\n", (long) s.size, t2);
+
+ t3 = tuneup_measure (speed_mpn_jacobi_base_3, &param, &s);
+ if (option_trace >= 1)
+ printf ("size=%ld, mpn_jacobi_base_3 %.9f\n", (long) s.size, t3);
+
+ t4 = tuneup_measure (speed_mpn_jacobi_base_4, &param, &s);
+ if (option_trace >= 1)
+ printf ("size=%ld, mpn_jacobi_base_4 %.9f\n", (long) s.size, t4);
+
+ if (t1 == -1.0 || t2 == -1.0 || t3 == -1.0 || t4 == -1.0)
+ {
+ printf ("Oops, can't measure all mpn_jacobi_base methods at %ld\n",
+ (long) s.size);
+ abort ();
+ }
+
+ if (t1 < t2 && t1 < t3 && t1 < t4)
+ method = 1;
+ else if (t2 < t3 && t2 < t4)
+ method = 2;
+ else if (t3 < t4)
+ method = 3;
+ else
+ method = 4;
+
+ print_define ("JACOBI_BASE_METHOD", method);
+}
+
+
+void
+tune_get_str (void)
+{
+ /* Tune for decimal, it being most common. Some rough testing suggests
+ other bases are different, but not by very much. */
+ s.r = 10;
+ {
+ static struct param_t param;
+ GET_STR_PRECOMPUTE_THRESHOLD = 0;
+ param.name = "GET_STR_DC_THRESHOLD";
+ param.function = speed_mpn_get_str;
+ param.min_size = 4;
+ param.max_size = GET_STR_THRESHOLD_LIMIT;
+ one (&get_str_dc_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.name = "GET_STR_PRECOMPUTE_THRESHOLD";
+ param.function = speed_mpn_get_str;
+ param.min_size = GET_STR_DC_THRESHOLD;
+ param.max_size = GET_STR_THRESHOLD_LIMIT;
+ one (&get_str_precompute_threshold, &param);
+ }
+}
+
+
+double
+speed_mpn_pre_set_str (struct speed_params *s)
+{
+ unsigned char *str;
+ mp_ptr wp;
+ mp_size_t wn;
+ unsigned i;
+ int base;
+ double t;
+ mp_ptr powtab_mem, tp;
+ powers_t powtab[GMP_LIMB_BITS];
+ mp_size_t un;
+ int chars_per_limb;
+ TMP_DECL;
+
+ SPEED_RESTRICT_COND (s->size >= 1);
+
+ base = s->r == 0 ? 10 : s->r;
+ SPEED_RESTRICT_COND (base >= 2 && base <= 256);
+
+ TMP_MARK;
+
+ str = TMP_ALLOC (s->size);
+ for (i = 0; i < s->size; i++)
+ str[i] = s->xp[i] % base;
+
+ LIMBS_PER_DIGIT_IN_BASE (wn, s->size, base);
+ SPEED_TMP_ALLOC_LIMBS (wp, wn, s->align_wp);
+
+ /* use this during development to check wn is big enough */
+ /*
+ ASSERT_ALWAYS (mpn_set_str (wp, str, s->size, base) <= wn);
+ */
+
+ speed_operand_src (s, (mp_ptr) str, s->size/GMP_LIMB_BYTES);
+ speed_operand_dst (s, wp, wn);
+ speed_cache_fill (s);
+
+ chars_per_limb = mp_bases[base].chars_per_limb;
+ un = s->size / chars_per_limb + 1;
+ powtab_mem = TMP_BALLOC_LIMBS (mpn_dc_set_str_powtab_alloc (un));
+ mpn_set_str_compute_powtab (powtab, powtab_mem, un, base);
+ tp = TMP_BALLOC_LIMBS (mpn_dc_set_str_itch (un));
+
+ speed_starttime ();
+ i = s->reps;
+ do
+ {
+ mpn_pre_set_str (wp, str, s->size, powtab, tp);
+ }
+ while (--i != 0);
+ t = speed_endtime ();
+
+ TMP_FREE;
+ return t;
+}
+
+void
+tune_set_str (void)
+{
+ s.r = 10; /* decimal */
+ {
+ static struct param_t param;
+ SET_STR_PRECOMPUTE_THRESHOLD = 0;
+ param.step_factor = 0.01;
+ param.name = "SET_STR_DC_THRESHOLD";
+ param.function = speed_mpn_pre_set_str;
+ param.min_size = 100;
+ param.max_size = 50000;
+ one (&set_str_dc_threshold, &param);
+ }
+ {
+ static struct param_t param;
+ param.step_factor = 0.02;
+ param.name = "SET_STR_PRECOMPUTE_THRESHOLD";
+ param.function = speed_mpn_set_str;
+ param.min_size = SET_STR_DC_THRESHOLD;
+ param.max_size = 100000;
+ one (&set_str_precompute_threshold, &param);
+ }
+}
+
+
+void
+tune_fft_mul (void)
+{
+ static struct fft_param_t param;
+
+ if (option_fft_max_size == 0)
+ return;
+
+ param.table_name = "MUL_FFT_TABLE3";
+ param.threshold_name = "MUL_FFT_THRESHOLD";
+ param.p_threshold = &mul_fft_threshold;
+ param.modf_threshold_name = "MUL_FFT_MODF_THRESHOLD";
+ param.p_modf_threshold = &mul_fft_modf_threshold;
+ param.first_size = MUL_TOOM33_THRESHOLD / 2;
+ param.max_size = option_fft_max_size;
+ param.function = speed_mpn_fft_mul;
+ param.mul_modf_function = speed_mpn_mul_fft;
+ param.mul_function = speed_mpn_mul_n;
+ param.sqr = 0;
+ fft (&param);
+}
+
+
+void
+tune_fft_sqr (void)
+{
+ static struct fft_param_t param;
+
+ if (option_fft_max_size == 0)
+ return;
+
+ param.table_name = "SQR_FFT_TABLE3";
+ param.threshold_name = "SQR_FFT_THRESHOLD";
+ param.p_threshold = &sqr_fft_threshold;
+ param.modf_threshold_name = "SQR_FFT_MODF_THRESHOLD";
+ param.p_modf_threshold = &sqr_fft_modf_threshold;
+ param.first_size = SQR_TOOM3_THRESHOLD / 2;
+ param.max_size = option_fft_max_size;
+ param.function = speed_mpn_fft_sqr;
+ param.mul_modf_function = speed_mpn_mul_fft_sqr;
+ param.mul_function = speed_mpn_sqr;
+ param.sqr = 1;
+ fft (&param);
+}
+
+void
+tune_fac_ui (void)
+{
+ static struct param_t param;
+
+ param.function = speed_mpz_fac_ui_tune;
+
+ param.name = "FAC_DSC_THRESHOLD";
+ param.min_size = 70;
+ param.max_size = FAC_DSC_THRESHOLD_LIMIT;
+ one (&fac_dsc_threshold, &param);
+
+ param.name = "FAC_ODD_THRESHOLD";
+ param.min_size = 22;
+ param.stop_factor = 1.7;
+ param.min_is_always = 1;
+ one (&fac_odd_threshold, &param);
+}
+
+void
+all (void)
+{
+ time_t start_time, end_time;
+ TMP_DECL;
+
+ TMP_MARK;
+ SPEED_TMP_ALLOC_LIMBS (s.xp_block, SPEED_BLOCK_SIZE, 0);
+ SPEED_TMP_ALLOC_LIMBS (s.yp_block, SPEED_BLOCK_SIZE, 0);
+
+ mpn_random (s.xp_block, SPEED_BLOCK_SIZE);
+ mpn_random (s.yp_block, SPEED_BLOCK_SIZE);
+
+ fprintf (stderr, "Parameters for %s\n", GMP_MPARAM_H_SUGGEST);
+
+ speed_time_init ();
+ fprintf (stderr, "Using: %s\n", speed_time_string);
+
+ fprintf (stderr, "speed_precision %d", speed_precision);
+ if (speed_unittime == 1.0)
+ fprintf (stderr, ", speed_unittime 1 cycle");
+ else
+ fprintf (stderr, ", speed_unittime %.2e secs", speed_unittime);
+ if (speed_cycletime == 1.0 || speed_cycletime == 0.0)
+ fprintf (stderr, ", CPU freq unknown\n");
+ else
+ fprintf (stderr, ", CPU freq %.2f MHz\n", 1e-6/speed_cycletime);
+
+ fprintf (stderr, "DEFAULT_MAX_SIZE %d, fft_max_size %ld\n",
+ DEFAULT_MAX_SIZE, (long) option_fft_max_size);
+ fprintf (stderr, "\n");
+
+ time (&start_time);
+ {
+ struct tm *tp;
+ tp = localtime (&start_time);
+ printf ("/* Generated by tuneup.c, %d-%02d-%02d, ",
+ tp->tm_year+1900, tp->tm_mon+1, tp->tm_mday);
+
+#ifdef __GNUC__
+ /* gcc sub-minor version doesn't seem to come through as a define */
+ printf ("gcc %d.%d */\n", __GNUC__, __GNUC_MINOR__);
+#define PRINTED_COMPILER
+#endif
+#if defined (__SUNPRO_C)
+ printf ("Sun C %d.%d */\n", __SUNPRO_C / 0x100, __SUNPRO_C % 0x100);
+#define PRINTED_COMPILER
+#endif
+#if ! defined (__GNUC__) && defined (__sgi) && defined (_COMPILER_VERSION)
+ /* gcc defines __sgi and _COMPILER_VERSION on irix 6, avoid that */
+ printf ("MIPSpro C %d.%d.%d */\n",
+ _COMPILER_VERSION / 100,
+ _COMPILER_VERSION / 10 % 10,
+ _COMPILER_VERSION % 10);
+#define PRINTED_COMPILER
+#endif
+#if defined (__DECC) && defined (__DECC_VER)
+ printf ("DEC C %d */\n", __DECC_VER);
+#define PRINTED_COMPILER
+#endif
+#if ! defined (PRINTED_COMPILER)
+ printf ("system compiler */\n");
+#endif
+ }
+ printf ("\n");
+
+ tune_divrem_1 ();
+ tune_mod_1 ();
+ tune_preinv_divrem_1 ();
+ tune_div_qr_1 ();
+#if 0
+ tune_divrem_2 ();
+#endif
+ tune_div_qr_2 ();
+ tune_divexact_1 ();
+ tune_modexact_1_odd ();
+ printf("\n");
+
+ tune_mul_n ();
+ printf("\n");
+
+ tune_mul ();
+ printf("\n");
+
+ tune_sqr ();
+ printf("\n");
+
+ tune_mulmid ();
+ printf("\n");
+
+ tune_mulmod_bnm1 ();
+ tune_sqrmod_bnm1 ();
+ printf("\n");
+
+ tune_fft_mul ();
+ printf("\n");
+
+ tune_fft_sqr ();
+ printf ("\n");
+
+ tune_mullo ();
+ printf("\n");
+
+ tune_dc_div ();
+ tune_dc_bdiv ();
+
+ printf("\n");
+ tune_invertappr ();
+ tune_invert ();
+ printf("\n");
+
+ tune_binvert ();
+ tune_redc ();
+ printf("\n");
+
+ tune_mu_div ();
+ tune_mu_bdiv ();
+ printf("\n");
+
+ tune_powm_sec ();
+ printf("\n");
+
+ tune_matrix22_mul ();
+ tune_hgcd ();
+ tune_hgcd_appr ();
+ tune_hgcd_reduce();
+ tune_gcd_dc ();
+ tune_gcdext_dc ();
+ tune_jacobi_base ();
+ printf("\n");
+
+ tune_get_str ();
+ tune_set_str ();
+ printf("\n");
+
+ tune_fac_ui ();
+ printf("\n");
+
+ time (&end_time);
+ printf ("/* Tuneup completed successfully, took %ld seconds */\n",
+ (long) (end_time - start_time));
+
+ TMP_FREE;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int opt;
+
+ /* Unbuffered so if output is redirected to a file it isn't lost if the
+ program is killed part way through. */
+ setbuf (stdout, NULL);
+ setbuf (stderr, NULL);
+
+ while ((opt = getopt(argc, argv, "f:o:p:t")) != EOF)
+ {
+ switch (opt) {
+ case 'f':
+ if (optarg[0] == 't')
+ option_fft_trace = 2;
+ else
+ option_fft_max_size = atol (optarg);
+ break;
+ case 'o':
+ speed_option_set (optarg);
+ break;
+ case 'p':
+ speed_precision = atoi (optarg);
+ break;
+ case 't':
+ option_trace++;
+ break;
+ case '?':
+ exit(1);
+ }
+ }
+
+ all ();
+ exit (0);
+}
diff --git a/gmp/tune/x86_64.asm b/gmp/tune/x86_64.asm
new file mode 100644
index 0000000000..b7ec44c544
--- /dev/null
+++ b/gmp/tune/x86_64.asm
@@ -0,0 +1,55 @@
+dnl x86 pentium time stamp counter access routine.
+
+dnl Copyright 1999, 2000, 2003-2005 Free Software Foundation, Inc.
+
+dnl This file is part of the GNU MP Library.
+dnl
+dnl The GNU MP Library is free software; you can redistribute it and/or modify
+dnl it under the terms of either:
+dnl
+dnl * the GNU Lesser General Public License as published by the Free
+dnl Software Foundation; either version 3 of the License, or (at your
+dnl option) any later version.
+dnl
+dnl or
+dnl
+dnl * the GNU General Public License as published by the Free Software
+dnl Foundation; either version 2 of the License, or (at your option) any
+dnl later version.
+dnl
+dnl or both in parallel, as here.
+dnl
+dnl The GNU MP Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received copies of the GNU General Public License and the
+dnl GNU Lesser General Public License along with the GNU MP Library. If not,
+dnl see https://www.gnu.org/licenses/.
+
+
+include(`../config.m4')
+
+
+C void speed_cyclecounter (unsigned p[2]);
+C
+C Get the pentium rdtsc cycle counter, storing the least significant word in
+C p[0] and the most significant in p[1].
+C
+C cpuid is used to serialize execution. On big measurements this won't be
+C significant but it may help make small single measurements more accurate.
+
+PROLOGUE(speed_cyclecounter)
+
+ C rdi p
+
+ movq %rbx, %r10
+ xorl %eax, %eax
+ cpuid
+ rdtsc
+ movl %eax, (%rdi)
+ movl %edx, 4(%rdi)
+ movq %r10, %rbx
+ ret
+EPILOGUE()
diff --git a/gmp/version.c b/gmp/version.c
new file mode 100644
index 0000000000..b75a3389e0
--- /dev/null
+++ b/gmp/version.c
@@ -0,0 +1,34 @@
+/* gmp_version -- version number compiled into the library.
+
+Copyright 1996, 1999-2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+or
+
+ * the GNU General Public License as published by the Free Software
+ Foundation; either version 2 of the License, or (at your option) any
+ later version.
+
+or both in parallel, as here.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received copies of the GNU General Public License and the
+GNU Lesser General Public License along with the GNU MP Library. If not,
+see https://www.gnu.org/licenses/. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+const char * const gmp_version = VERSION;
diff --git a/gmp/ylwrap b/gmp/ylwrap
new file mode 100755
index 0000000000..92536350cb
--- /dev/null
+++ b/gmp/ylwrap
@@ -0,0 +1,226 @@
+#! /bin/sh
+# ylwrap - wrapper for lex/yacc invocations.
+
+scriptversion=2011-08-25.18; # UTC
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005,
+# 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+#
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case "$1" in
+ '')
+ echo "$0: No files given. Try \`$0 --help' for more information." 1>&2
+ exit 1
+ ;;
+ --basedir)
+ basedir=$2
+ shift 2
+ ;;
+ -h|--h*)
+ cat <<\EOF
+Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
+
+Wrapper for lex/yacc invocations, renaming files as desired.
+
+ INPUT is the input file
+ OUTPUT is one file PROG generates
+ DESIRED is the file we actually want instead of OUTPUT
+ PROGRAM is program to run
+ ARGS are passed to PROG
+
+Any number of OUTPUT,DESIRED pairs may be used.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v|--v*)
+ echo "ylwrap $scriptversion"
+ exit $?
+ ;;
+esac
+
+
+# The input.
+input="$1"
+shift
+case "$input" in
+ [\\/]* | ?:[\\/]*)
+ # Absolute path; do nothing.
+ ;;
+ *)
+ # Relative path. Make it absolute.
+ input="`pwd`/$input"
+ ;;
+esac
+
+pairlist=
+while test "$#" -ne 0; do
+ if test "$1" = "--"; then
+ shift
+ break
+ fi
+ pairlist="$pairlist $1"
+ shift
+done
+
+# The program to run.
+prog="$1"
+shift
+# Make any relative path in $prog absolute.
+case "$prog" in
+ [\\/]* | ?:[\\/]*) ;;
+ *[\\/]*) prog="`pwd`/$prog" ;;
+esac
+
+# FIXME: add hostname here for parallel makes that run commands on
+# other machines. But that might take us over the 14-char limit.
+dirname=ylwrap$$
+do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
+trap "ret=129; $do_exit" 1
+trap "ret=130; $do_exit" 2
+trap "ret=141; $do_exit" 13
+trap "ret=143; $do_exit" 15
+mkdir $dirname || exit 1
+
+cd $dirname
+
+case $# in
+ 0) "$prog" "$input" ;;
+ *) "$prog" "$@" "$input" ;;
+esac
+ret=$?
+
+if test $ret -eq 0; then
+ set X $pairlist
+ shift
+ first=yes
+ # Since DOS filename conventions don't allow two dots,
+ # the DOS version of Bison writes out y_tab.c instead of y.tab.c
+ # and y_tab.h instead of y.tab.h. Test to see if this is the case.
+ y_tab_nodot="no"
+ if test -f y_tab.c || test -f y_tab.h; then
+ y_tab_nodot="yes"
+ fi
+
+ # The directory holding the input.
+ input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'`
+ # Quote $INPUT_DIR so we can use it in a regexp.
+ # FIXME: really we should care about more than `.' and `\'.
+ input_rx=`echo "$input_dir" | sed 's,\\\\,\\\\\\\\,g;s,\\.,\\\\.,g'`
+
+ while test "$#" -ne 0; do
+ from="$1"
+ # Handle y_tab.c and y_tab.h output by DOS
+ if test $y_tab_nodot = "yes"; then
+ if test $from = "y.tab.c"; then
+ from="y_tab.c"
+ else
+ if test $from = "y.tab.h"; then
+ from="y_tab.h"
+ fi
+ fi
+ fi
+ if test -f "$from"; then
+ # If $2 is an absolute path name, then just use that,
+ # otherwise prepend `../'.
+ case "$2" in
+ [\\/]* | ?:[\\/]*) target="$2";;
+ *) target="../$2";;
+ esac
+
+ # We do not want to overwrite a header file if it hasn't
+ # changed. This avoid useless recompilations. However the
+ # parser itself (the first file) should always be updated,
+ # because it is the destination of the .y.c rule in the
+ # Makefile. Divert the output of all other files to a temporary
+ # file so we can compare them to existing versions.
+ if test $first = no; then
+ realtarget="$target"
+ target="tmp-`echo $target | sed s/.*[\\/]//g`"
+ fi
+ # Edit out `#line' or `#' directives.
+ #
+ # We don't want the resulting debug information to point at
+ # an absolute srcdir; it is better for it to just mention the
+ # .y file with no path.
+ #
+ # We want to use the real output file name, not yy.lex.c for
+ # instance.
+ #
+ # We want the include guards to be adjusted too.
+ FROM=`echo "$from" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
+ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
+ TARGET=`echo "$2" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
+ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
+
+ sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$2," \
+ -e "s,$FROM,$TARGET," "$from" >"$target" || ret=$?
+
+ # Check whether header files must be updated.
+ if test $first = no; then
+ if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
+ echo "$2" is unchanged
+ rm -f "$target"
+ else
+ echo updating "$2"
+ mv -f "$target" "$realtarget"
+ fi
+ fi
+ else
+ # A missing file is only an error for the first file. This
+ # is a blatant hack to let us support using "yacc -d". If -d
+ # is not specified, we don't want an error when the header
+ # file is "missing".
+ if test $first = yes; then
+ ret=1
+ fi
+ fi
+ shift
+ shift
+ first=no
+ done
+else
+ ret=$?
+fi
+
+# Remove the directory.
+cd ..
+rm -rf $dirname
+
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mpc/AUTHORS b/mpc/AUTHORS
new file mode 100644
index 0000000000..04bb21bd1b
--- /dev/null
+++ b/mpc/AUTHORS
@@ -0,0 +1,6 @@
+Main authors:
+ Andreas Enge
+ Philippe Théveny
+ Paul Zimmermann
+
+Mickaël Gastineau has contributed the file Makefile.vc.
diff --git a/mpc/COPYING.LESSER b/mpc/COPYING.LESSER
new file mode 100644
index 0000000000..65c5ca88a6
--- /dev/null
+++ b/mpc/COPYING.LESSER
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/mpc/ChangeLog b/mpc/ChangeLog
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mpc/ChangeLog
diff --git a/mpc/INSTALL b/mpc/INSTALL
new file mode 100644
index 0000000000..1081630cd2
--- /dev/null
+++ b/mpc/INSTALL
@@ -0,0 +1,101 @@
+Copyright (C) INRIA 2003, 2005, 2007, 2008, 2009, 2010, 2011, 2012
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
+
+
+ Installing GNU MPC
+ ==================
+
+This is for the impatient, for deeper explanations see the chapter
+"Installing GNU MPC" in the Texinfo documentation (type 'info mpc.info').
+
+0. You first need to install GMP, the GNU Multiprecision Arithmetic Library,
+ see <http://gmplib.org/>, and GNU MPFR, see <http://www.mpfr.org>.
+ GNU MPC requires GMP version 4.3.2 or later
+ and GNU MPFR version 2.4.2 or later.
+
+1. In the directory of the GNU MPC archive, type
+
+ tar xzf mpc-1.0.2.tar.gz
+ cd mpc-1.0.2
+ ./configure
+ make
+
+ This assumes that GMP and GNU MPFR are installed in a directory searched
+ by default by the compiler. Otherwise, use --with-gmp=DIR or
+ --with-mpfr=DIR with ./configure (see the Texinfo documentation).
+
+2. You should run the test suite, type
+
+ make check
+
+ If any error occurs, please report it on the mailing list
+ <mpc-discuss@lists.gforge.inria.fr>, or file a bug at the bug tracker
+ <https://gforge.inria.fr/tracker/?atid=607&group_id=131&func=browse> .
+
+3. To install the GNU MPC library, type
+
+ make install
+
+ By default, the files are copied into subdirectories of /usr/local.
+ You need write permissions on these directories, or pass an alternative
+ installation directory using the --prefix option to ./configure.
+
+4. You can optionally create documentation, type
+
+ make dvi
+
+ or
+
+ make ps
+
+ This requires the Texinfo package (version 4.2 at least).
+
+In case of difficulties, please send a description of the problem to
+<mpc-discuss@lists.gforge.inria.fr>.
+
+##############################################################################
+
+Note for AIX users:
+===================
+
+If GMP was built with the 64-bit ABI, before building and testing GNU MPC,
+it might be necessary to set the OBJECT_MODE environment variable to 64
+by, e.g.,
+ export OBJECT_MODE=64
+This has been tested with the C compiler IBM XL C/C++ Enterprise Edition
+V8.0 for AIX, version: 08.00.0000.0021, GMP 4.2.4 and GNU MPFR 2.4.1.
+
+##############################################################################
+
+Note for Windows users:
+=======================
+
+There is a special file Makefile.vc for Windows, contributed by Mickaël
+Gastineau. This file works both for the Windows Server 2003 R2 Platform SDK,
+and for the Windows SDK of Vista. To use it, simply replace "make" by
+"nmake /f makefile.vc" in the above instructions:
+
+compilation :
+nmake /f makefile.vc GMP=<gmp_install_dir> MPFR=<mpfr_install_dir>
+
+clean :
+nmake /f makefile.vc GMP=<gmp_install_dir> MPFR=<mpfr_install_dir> clean
+
+check :
+nmake /f makefile.vc GMP=<gmp_install_dir> MPFR=<mpfr_install_dir> check
+
+If you want to compile mpc with mingw in the msys shell, you might need to
+add the following to the configure command (or in your environment):
+
+LDFLAGS=-L/usr/local/lib CPPFLAGS=-I/usr/local/include
+
+In addition, you might need to give the following additional argument to
+configure (reported for mpc-0.9):
+
+CPP="x86_64-w64-mingw32-gcc -E"
+
+(reported by Sisyphus)
diff --git a/mpc/Makefile.am b/mpc/Makefile.am
new file mode 100644
index 0000000000..cf0b6cb8a6
--- /dev/null
+++ b/mpc/Makefile.am
@@ -0,0 +1,29 @@
+## Makefile.am -- Process this file with automake to produce Makefile.in
+##
+## Copyright (C) 2008, 2010, 2011 INRIA
+##
+## This file is part of GNU MPC.
+##
+## GNU MPC is free software; you can redistribute it and/or modify it under
+## the terms of the GNU Lesser General Public License as published by the
+## Free Software Foundation; either version 3 of the License, or (at your
+## option) any later version.
+##
+## GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+## FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+## more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this program. If not, see http://www.gnu.org/licenses/ .
+
+ACLOCAL_AMFLAGS = -I m4
+
+# version number for distribution tarball
+VERSION = @VERSION@@SVNVERSION@
+
+SUBDIRS = src tests doc
+
+EXTRA_HEADERS = src/mpc-log.h
+include_HEADERS = src/mpc.h @MPC_LOG_H@
+EXTRA_DIST = doc/fdl-1.3.texi src/mpc-log.h tests/tgeneric.c Makefile.vc
diff --git a/mpc/Makefile.in b/mpc/Makefile.in
new file mode 100644
index 0000000000..fe7686034f
--- /dev/null
+++ b/mpc/Makefile.in
@@ -0,0 +1,831 @@
+# Makefile.in generated by automake 1.12.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2012 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@
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(include_HEADERS) \
+ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/config.h.in $(top_srcdir)/configure AUTHORS \
+ COPYING.LESSER ChangeLog INSTALL NEWS TODO ar-lib config.guess \
+ config.sub depcomp install-sh ltmain.sh missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c_check_flag.m4 \
+ $(top_srcdir)/m4/ax_gcc_option.m4 \
+ $(top_srcdir)/m4/ax_gcc_version.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/mpc.m4 $(top_srcdir)/m4/valgrind-tests.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+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__installdirs = "$(DESTDIR)$(includedir)"
+HEADERS = $(include_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ cscope distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCC_VERSION = @GCC_VERSION@
+GREP = @GREP@
+HASSVNVERSION = @HASSVNVERSION@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPC_LDFLAGS = @MPC_LDFLAGS@
+MPC_LOG_H = @MPC_LOG_H@
+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@
+STRIP = @STRIP@
+SVNVERSION = @SVNVERSION@
+VALGRIND = @VALGRIND@
+
+# version number for distribution tarball
+VERSION = @VERSION@@SVNVERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+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@
+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@
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = src tests doc
+EXTRA_HEADERS = src/mpc-log.h
+include_HEADERS = src/mpc.h @MPC_LOG_H@
+EXTRA_DIST = doc/fdl-1.3.texi src/mpc-log.h tests/tgeneric.c Makefile.vc
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @if test ! -f $@; then rm -f stamp-h1; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+cscopelist-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+
+clean-cscope:
+ -rm -f cscope.files
+
+cscope.files: clean-cscope cscopelist-recursive cscopelist
+
+cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP)'; \
+ 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
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @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
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__post_remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__post_remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__post_remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__post_remove_distdir)
+
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__post_remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(HEADERS) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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:
+
+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-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-includeHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-includeHEADERS
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
+ cscopelist-recursive ctags-recursive install-am install-strip \
+ tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am am--refresh check check-am clean clean-cscope \
+ clean-generic clean-libtool cscope cscopelist \
+ cscopelist-recursive ctags ctags-recursive dist dist-all \
+ dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ dist-xz \
+ dist-zip distcheck distclean distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags distcleancheck distdir \
+ distuninstallcheck 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-includeHEADERS install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-includeHEADERS
+
+
+# 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/mpc/Makefile.vc b/mpc/Makefile.vc
new file mode 100644
index 0000000000..e8640a047e
--- /dev/null
+++ b/mpc/Makefile.vc
@@ -0,0 +1,426 @@
+# Makefile for the MPC library (Windows version).
+#
+# Copyright (C) INRIA - CNRS, 2002, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012, 2014
+#
+# This file is part of the MPC Library.
+#
+# The MPC Library is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or (at your
+# option) any later version.
+#
+# The MPC Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with the MPC Library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+# MA 02111-1307, USA.
+#
+
+# usage:
+# nmake /f Makefile.vc clean
+# clean the temporaries objects
+#
+# nmake /f Makefile.vc STATIC=0|1 GMPDIR=gmpdirectory MPFRDIR=mpfrdirectory
+# compile MPC
+#
+# nmake /f Makefile.vc STATIC=0|1 install GMPDIR=gmpdirectory MPFRDIR=mpfrdirectory DESTDIR=installdirectory
+# install MPC to installdirectory
+#
+# nmake /f Makefile.vc STATIC=0|1 check GMPDIR=gmpdirectory MPFRDIR=mpfrdirectory
+# perform tests on MPC
+#
+# GMPDIR : specify the location where GMP is installed
+# MPFRDIR : specify the location where MPFR is installed
+# DESTDIR : specify the location where MPC will be installed
+# STATIC : specify if a static or dynamic library of MPC will be created
+# STATIC=1 : build a static library
+# STATIC=0 : build a dynamic library (DLL)
+# A dynamic library is created by default if STATIC is omitted (STATIC=0)
+# ENABLELOGGING : specify if MPC functions calls are logged
+# ENABLELOGGING=1 : MPC functions calls are logged
+# ENABLELOGGING=0 : MPC functions calls are not logged (default)
+# Functions calls are not logged by default if ENABLELOGGING is omitted (ENABLELOGGING=0)
+
+
+CPP = cl.exe
+CC = cl.exe
+CDEFAULTFLAGS=/O2 /GR- /MD /nologo /EHs
+
+VERSION=1.0.2
+
+######################## do not edit below this line ##########################
+
+DIRMPC=.\src
+DIRMPCTESTS=.\tests\\
+
+!if "$(STATIC)" == "0"
+LIBRARY = libmpc.dll
+LINKER = link.exe /DLL
+GMPMUSTBEDLL=/D__GMP_LIBGMP_DLL
+!else
+LIBRARY = libmpc.lib
+LINKER = lib.exe
+GMPMUSTBEDLL=
+!endif
+
+#check for logging. if yes then add logging.c to the library
+!if "$(ENABLELOGGING)" == "1"
+CPPOBJECTS_LOGGING = $(DIRMPC)\logging.obj
+CPPLINKOBJECTS_LOGGING = logging.obj
+LIBS_LOGGING = kernel32.lib
+!else
+CPPOBJECTS_LOGGING =
+CPPLINKOBJECTS_LOGGING =
+LIBS_LOGGING =
+!endif
+
+
+INCLUDES = /I$(DIRMPC) /I$(GMPDIR)\include /I$(MPFR)\include
+CKERNELFLAGS = $(CDEFAULTFLAGS) $(GMPMUSTBEDLL) $(INCLUDES)
+CFLAGS = $(CKERNELFLAGS) /D__MPC_WITHIN_MPC /D_GMP_IEEE_FLOATS /DHAVE_CONFIG_H
+
+TESTCOMPILE=$(CC) $(CKERNELFLAGS) $(DIRMPCTESTS)\tgeneric.c $(DIRMPCTESTS)\comparisons.c $(DIRMPCTESTS)\read_data.c $(DIRMPCTESTS)\random.c $(DIRMPCTESTS)
+MIDTESTCOMPILE=/link /out:$(DIRMPCTESTS)
+ENDTESTCOMPILE=/LIBPATH:"$(GMPDIR)\lib" libmpc.lib libmpfr.lib libgmp.lib $(LIBS_LOGGING)
+
+
+#generate the CPPOBJECTS : goto src and execute
+# ls *.c | sed "s/\.c/\.obj/" | awk ' { printf("$(DIRMPC)\\%s \\\n",$1); } '
+#generate the CPPLINKOBJECTS : goto src and execute
+# ls *.c | sed "s/\.c/\.obj/" | awk ' { printf("%s \\\n",$1); } '
+#generate the list for tests : goto tests and execute
+# ls t*.c | sed "s/\.c//" | grep -v tgeneric| grep -v comparisons | grep -v read_data | grep -v random | awk ' { printf("\t$(TESTCOMPILE)%s.c $(MIDTESTCOMPILE)%s.exe $(ENDTESTCOMPILE)\n\tcd $(DIRMPCTESTS) && %s.exe && cd ..\n",$1,$1,$1,$1); } '
+
+LIBRARYLIB = libmpc.lib
+
+CPPOBJECTS =$(DIRMPC)\abs.obj \
+$(DIRMPC)\acos.obj \
+$(DIRMPC)\acosh.obj \
+$(DIRMPC)\add.obj \
+$(DIRMPC)\add_fr.obj \
+$(DIRMPC)\add_si.obj \
+$(DIRMPC)\add_ui.obj \
+$(DIRMPC)\arg.obj \
+$(DIRMPC)\asin.obj \
+$(DIRMPC)\asinh.obj \
+$(DIRMPC)\atan.obj \
+$(DIRMPC)\atanh.obj \
+$(DIRMPC)\clear.obj \
+$(DIRMPC)\cmp.obj \
+$(DIRMPC)\cmp_si_si.obj \
+$(DIRMPC)\conj.obj \
+$(DIRMPC)\cos.obj \
+$(DIRMPC)\cosh.obj \
+$(DIRMPC)\div.obj \
+$(DIRMPC)\div_2ui.obj \
+$(DIRMPC)\div_fr.obj \
+$(DIRMPC)\div_ui.obj \
+$(DIRMPC)\exp.obj \
+$(DIRMPC)\fma.obj \
+$(DIRMPC)\fr_div.obj \
+$(DIRMPC)\fr_sub.obj \
+$(DIRMPC)\get_prec.obj \
+$(DIRMPC)\get_prec2.obj \
+$(DIRMPC)\get_version.obj \
+$(DIRMPC)\get_x.obj \
+$(DIRMPC)\imag.obj \
+$(DIRMPC)\init2.obj \
+$(DIRMPC)\init3.obj \
+$(DIRMPC)\inp_str.obj \
+$(DIRMPC)\log.obj \
+$(DIRMPC)\log10.obj \
+$(DIRMPC)\mem.obj \
+$(DIRMPC)\mul.obj \
+$(DIRMPC)\mul_2ui.obj \
+$(DIRMPC)\mul_fr.obj \
+$(DIRMPC)\mul_i.obj \
+$(DIRMPC)\mul_si.obj \
+$(DIRMPC)\mul_ui.obj \
+$(DIRMPC)\neg.obj \
+$(DIRMPC)\norm.obj \
+$(DIRMPC)\out_str.obj \
+$(DIRMPC)\pow.obj \
+$(DIRMPC)\pow_d.obj \
+$(DIRMPC)\pow_fr.obj \
+$(DIRMPC)\pow_ld.obj \
+$(DIRMPC)\pow_si.obj \
+$(DIRMPC)\pow_ui.obj \
+$(DIRMPC)\pow_z.obj \
+$(DIRMPC)\proj.obj \
+$(DIRMPC)\real.obj \
+$(DIRMPC)\set.obj \
+$(DIRMPC)\set_prec.obj \
+$(DIRMPC)\set_str.obj \
+$(DIRMPC)\set_x.obj \
+$(DIRMPC)\set_x_x.obj \
+$(DIRMPC)\sin.obj \
+$(DIRMPC)\sin_cos.obj \
+$(DIRMPC)\sinh.obj \
+$(DIRMPC)\sqr.obj \
+$(DIRMPC)\sqrt.obj \
+$(DIRMPC)\strtoc.obj \
+$(DIRMPC)\sub.obj \
+$(DIRMPC)\sub_fr.obj \
+$(DIRMPC)\sub_ui.obj \
+$(DIRMPC)\swap.obj \
+$(DIRMPC)\tan.obj \
+$(DIRMPC)\tanh.obj \
+$(DIRMPC)\uceil_log2.obj \
+$(DIRMPC)\ui_div.obj \
+$(DIRMPC)\ui_ui_sub.obj $(CPPOBJECTS_LOGGING) \
+$(DIRMPC)\urandom.obj
+
+CPPLINKOBJECTS = abs.obj \
+acos.obj \
+acosh.obj \
+add.obj \
+add_fr.obj \
+add_si.obj \
+add_ui.obj \
+arg.obj \
+asin.obj \
+asinh.obj \
+atan.obj \
+atanh.obj \
+clear.obj \
+cmp.obj \
+cmp_si_si.obj \
+conj.obj \
+cos.obj \
+cosh.obj \
+div.obj \
+div_2ui.obj \
+div_fr.obj \
+div_ui.obj \
+exp.obj \
+fma.obj \
+fr_div.obj \
+fr_sub.obj \
+get_prec.obj \
+get_prec2.obj \
+get_version.obj \
+get_x.obj \
+imag.obj \
+init2.obj \
+init3.obj \
+inp_str.obj \
+log.obj \
+log10.obj \
+mem.obj \
+mul.obj \
+mul_2ui.obj \
+mul_fr.obj \
+mul_i.obj \
+mul_si.obj \
+mul_ui.obj \
+neg.obj \
+norm.obj \
+out_str.obj \
+pow.obj \
+pow_d.obj \
+pow_fr.obj \
+pow_ld.obj \
+pow_si.obj \
+pow_ui.obj \
+pow_z.obj \
+proj.obj \
+real.obj \
+set.obj \
+set_prec.obj \
+set_str.obj \
+set_x.obj \
+set_x_x.obj \
+sin.obj \
+sin_cos.obj \
+sinh.obj \
+sqr.obj \
+sqrt.obj \
+strtoc.obj \
+sub.obj \
+sub_fr.obj \
+sub_ui.obj \
+swap.obj \
+tan.obj \
+tanh.obj \
+uceil_log2.obj \
+ui_div.obj \
+ui_ui_sub.obj $(CPPLINKOBJECTS_LOGGING) \
+urandom.obj
+
+#
+# Link target: automatically builds its object dependencies before
+# executing its link command.
+#
+
+$(LIBRARY): $(DIRMPC)config.h $(CPPOBJECTS)
+ $(LINKER) /out:$@ $(CPPLINKOBJECTS) /LIBPATH:"$(GMPDIR)\lib" libmpfr.lib libgmp.lib $(LIBS_LOGGING)
+
+$(DIRMPC)config.h :
+ echo #define PACKAGE_STRING "mpc" >$(DIRMPC)\config.h
+ echo #define PACKAGE_VERSION "$(VERSION)" >>$(DIRMPC)\config.h
+ echo #define STDC_HEADERS 1 >>$(DIRMPC)\config.h
+ echo #define dlsym(handle, name) GetProcAddress(GetModuleHandle(handle), name) >>$(DIRMPC)\config.h
+ echo #include "windows.h" >>$(DIRMPC)\config.h
+
+
+#
+# Clean target: "nmake /f Makefile.vc clean" to remove unwanted
+# objects and executables.
+#
+
+clean:
+ del *.obj $(CPPLINKOBJECTS) $(LIBRARY) *.tlh $(DIRMPC)config.h *.dll *.lib *.exe
+
+
+
+#
+# install target: "nmake /f Makefile.vc install DESTDIR=xxx" to perform the installation.
+#
+
+install: $(LIBRARY)
+ -mkdir $(DESTDIR)
+ -mkdir $(DESTDIR)\include
+ copy $(DIRMPC)\mpc.h $(DESTDIR)\include
+ -mkdir $(DESTDIR)\lib
+ copy $(LIBRARY) $(DESTDIR)\lib
+ copy $(LIBRARYLIB) $(DESTDIR)\lib
+
+#
+# check target: "nmake /f Makefile.vc check GMPDIR=xxx MPFRDIR=xxx" to perform the installation.
+#
+check : test
+test :
+ -copy $(GMPDIR)\lib\*gmp*.dll $(DIRMPCTESTS)
+ -copy $(MPFRDIR)\lib\*mpfr*.dll $(DIRMPCTESTS)
+ copy $(LIBRARY) $(DIRMPCTESTS)
+ $(TESTCOMPILE)tabs.c $(MIDTESTCOMPILE)tabs.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tabs.exe && cd ..
+ $(TESTCOMPILE)tacos.c $(MIDTESTCOMPILE)tacos.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tacos.exe && cd ..
+ $(TESTCOMPILE)tacosh.c $(MIDTESTCOMPILE)tacosh.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tacosh.exe && cd ..
+ $(TESTCOMPILE)tadd.c $(MIDTESTCOMPILE)tadd.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tadd.exe && cd ..
+ $(TESTCOMPILE)tadd_fr.c $(MIDTESTCOMPILE)tadd_fr.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tadd_fr.exe && cd ..
+ $(TESTCOMPILE)tadd_si.c $(MIDTESTCOMPILE)tadd_si.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tadd_si.exe && cd ..
+ $(TESTCOMPILE)tadd_ui.c $(MIDTESTCOMPILE)tadd_ui.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tadd_ui.exe && cd ..
+ $(TESTCOMPILE)targ.c $(MIDTESTCOMPILE)targ.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && targ.exe && cd ..
+ $(TESTCOMPILE)tasin.c $(MIDTESTCOMPILE)tasin.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tasin.exe && cd ..
+ $(TESTCOMPILE)tasinh.c $(MIDTESTCOMPILE)tasinh.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tasinh.exe && cd ..
+ $(TESTCOMPILE)tatan.c $(MIDTESTCOMPILE)tatan.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tatan.exe && cd ..
+ $(TESTCOMPILE)tatanh.c $(MIDTESTCOMPILE)tatanh.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tatanh.exe && cd ..
+ $(TESTCOMPILE)tconj.c $(MIDTESTCOMPILE)tconj.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tconj.exe && cd ..
+ $(TESTCOMPILE)tcos.c $(MIDTESTCOMPILE)tcos.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tcos.exe && cd ..
+ $(TESTCOMPILE)tcosh.c $(MIDTESTCOMPILE)tcosh.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tcosh.exe && cd ..
+ $(TESTCOMPILE)tdiv.c $(MIDTESTCOMPILE)tdiv.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tdiv.exe && cd ..
+ $(TESTCOMPILE)tdiv_2ui.c $(MIDTESTCOMPILE)tdiv_2ui.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tdiv_2ui.exe && cd ..
+ $(TESTCOMPILE)tdiv_fr.c $(MIDTESTCOMPILE)tdiv_fr.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tdiv_fr.exe && cd ..
+ $(TESTCOMPILE)tdiv_ui.c $(MIDTESTCOMPILE)tdiv_ui.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tdiv_ui.exe && cd ..
+ $(TESTCOMPILE)texp.c $(MIDTESTCOMPILE)texp.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && texp.exe && cd ..
+ $(TESTCOMPILE)tfma.c $(MIDTESTCOMPILE)tfma.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tfma.exe && cd ..
+ $(TESTCOMPILE)tfr_div.c $(MIDTESTCOMPILE)tfr_div.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tfr_div.exe && cd ..
+ $(TESTCOMPILE)tfr_sub.c $(MIDTESTCOMPILE)tfr_sub.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tfr_sub.exe && cd ..
+ $(TESTCOMPILE)tget_version.c $(MIDTESTCOMPILE)tget_version.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tget_version.exe && cd ..
+ $(TESTCOMPILE)timag.c $(MIDTESTCOMPILE)timag.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && timag.exe && cd ..
+ $(TESTCOMPILE)tio_str.c $(MIDTESTCOMPILE)tio_str.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tio_str.exe && cd ..
+ $(TESTCOMPILE)tlog.c $(MIDTESTCOMPILE)tlog.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tlog.exe && cd ..
+ $(TESTCOMPILE)tlog10.c $(MIDTESTCOMPILE)tlog10.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tlog10.exe && cd ..
+ $(TESTCOMPILE)tmul.c $(MIDTESTCOMPILE)tmul.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tmul.exe && cd ..
+ $(TESTCOMPILE)tmul_2ui.c $(MIDTESTCOMPILE)tmul_2ui.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tmul_2ui.exe && cd ..
+ $(TESTCOMPILE)tmul_fr.c $(MIDTESTCOMPILE)tmul_fr.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tmul_fr.exe && cd ..
+ $(TESTCOMPILE)tmul_i.c $(MIDTESTCOMPILE)tmul_i.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tmul_i.exe && cd ..
+ $(TESTCOMPILE)tmul_si.c $(MIDTESTCOMPILE)tmul_si.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tmul_si.exe && cd ..
+ $(TESTCOMPILE)tmul_ui.c $(MIDTESTCOMPILE)tmul_ui.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tmul_ui.exe && cd ..
+ $(TESTCOMPILE)tneg.c $(MIDTESTCOMPILE)tneg.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tneg.exe && cd ..
+ $(TESTCOMPILE)tnorm.c $(MIDTESTCOMPILE)tnorm.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tnorm.exe && cd ..
+ $(TESTCOMPILE)tpow.c $(MIDTESTCOMPILE)tpow.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tpow.exe && cd ..
+ $(TESTCOMPILE)tpow_d.c $(MIDTESTCOMPILE)tpow_d.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tpow_d.exe && cd ..
+ $(TESTCOMPILE)tpow_fr.c $(MIDTESTCOMPILE)tpow_fr.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tpow_fr.exe && cd ..
+ $(TESTCOMPILE)tpow_ld.c $(MIDTESTCOMPILE)tpow_ld.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tpow_ld.exe && cd ..
+ $(TESTCOMPILE)tpow_si.c $(MIDTESTCOMPILE)tpow_si.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tpow_si.exe && cd ..
+ $(TESTCOMPILE)tpow_ui.c $(MIDTESTCOMPILE)tpow_ui.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tpow_ui.exe && cd ..
+ $(TESTCOMPILE)tpow_z.c $(MIDTESTCOMPILE)tpow_z.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tpow_z.exe && cd ..
+ $(TESTCOMPILE)tprec.c $(MIDTESTCOMPILE)tprec.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tprec.exe && cd ..
+ $(TESTCOMPILE)tproj.c $(MIDTESTCOMPILE)tproj.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tproj.exe && cd ..
+ $(TESTCOMPILE)treal.c $(MIDTESTCOMPILE)treal.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && treal.exe && cd ..
+ $(TESTCOMPILE)treimref.c $(MIDTESTCOMPILE)treimref.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && treimref.exe && cd ..
+ $(TESTCOMPILE)tset.c $(MIDTESTCOMPILE)tset.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tset.exe && cd ..
+ $(TESTCOMPILE)tsin.c $(MIDTESTCOMPILE)tsin.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tsin.exe && cd ..
+ $(TESTCOMPILE)tsin_cos.c $(MIDTESTCOMPILE)tsin_cos.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tsin_cos.exe && cd ..
+ $(TESTCOMPILE)tsinh.c $(MIDTESTCOMPILE)tsinh.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tsinh.exe && cd ..
+ $(TESTCOMPILE)tsqr.c $(MIDTESTCOMPILE)tsqr.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tsqr.exe && cd ..
+ $(TESTCOMPILE)tsqrt.c $(MIDTESTCOMPILE)tsqrt.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tsqrt.exe && cd ..
+ $(TESTCOMPILE)tstrtoc.c $(MIDTESTCOMPILE)tstrtoc.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tstrtoc.exe && cd ..
+ $(TESTCOMPILE)tsub.c $(MIDTESTCOMPILE)tsub.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tsub.exe && cd ..
+ $(TESTCOMPILE)tsub_fr.c $(MIDTESTCOMPILE)tsub_fr.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tsub_fr.exe && cd ..
+ $(TESTCOMPILE)tsub_ui.c $(MIDTESTCOMPILE)tsub_ui.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tsub_ui.exe && cd ..
+ $(TESTCOMPILE)tswap.c $(MIDTESTCOMPILE)tswap.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tswap.exe && cd ..
+ $(TESTCOMPILE)ttan.c $(MIDTESTCOMPILE)ttan.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && ttan.exe && cd ..
+ $(TESTCOMPILE)ttanh.c $(MIDTESTCOMPILE)ttanh.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && ttanh.exe && cd ..
+ $(TESTCOMPILE)tui_div.c $(MIDTESTCOMPILE)tui_div.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tui_div.exe && cd ..
+ $(TESTCOMPILE)tui_ui_sub.c $(MIDTESTCOMPILE)tui_ui_sub.exe $(ENDTESTCOMPILE)
+ cd $(DIRMPCTESTS) && tui_ui_sub.exe && cd ..
+ @echo --------------------------------------------------
+ @echo All tests passed
+ @echo --------------------------------------------------
diff --git a/mpc/NEWS b/mpc/NEWS
new file mode 100644
index 0000000000..dbe390dddd
--- /dev/null
+++ b/mpc/NEWS
@@ -0,0 +1,154 @@
+Changes in version 1.0.2:
+ - Fixed mpc_atan, mpc_atanh for (+-0, +-1), see
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57994#c7
+ - Fixed mpc_log10 for purely imaginary argument, see
+ http://lists.gforge.inria.fr/pipermail/mpc-discuss/2012-September/001208.html
+
+Changes in version 1.0.1:
+ - Switched to automake 1.11.6, see
+ https://lists.gnu.org/archive/html/automake/2012-07/msg00023.html
+ - #14669: Fixed extraction of CC from gmp.h
+ - Fixed case of intermediate zero real or imaginary part in mpc_fma,
+ found by hydra with GMP_CHECK_RANDOMIZE=1346362345
+
+Changes in version 1.0:
+ - First release as a GNU package
+ - License change: LGPLv3+ for code, GFDLv1.3+ (with no invariant sections)
+ for documentation
+ - 100% of all lines are covered by tests
+ - Functions renamed:
+ mpc_mul_2exp to mpc_mul_2ui, mpc_div_2exp to mpc_div_2ui
+ - 0^0, which returned (NaN,NaN) previously, now returns (1,+0)
+ - Removed compatibility with K&R compilers, untestable due to lack of
+ such compilers
+ - New functions: mpc_log10, mpc_mul_2si, mpc_div_2si
+ - Speed-ups:
+ - mpc_fma
+ - Bug fixes:
+ - mpc_div and mpc_norm now return a value indicating the effective
+ rounding direction, as the other functions
+ - mpc_mul, mpc_sqr and mpc_norm now return correct results even if there
+ are over- or underflows during the computation
+ - mpc_asin, mpc_proj, mpc_sqr: Wrong result when input variable has
+ infinite part and equals output variable is corrected
+ - mpc_fr_sub: Wrong return value for imaginary part is corrected
+
+Changes in version 0.9:
+ - New functions:
+ - mpc_set_dc, mpc_set_ldc, mpc_get_dc, mpc_get_ldc for converting
+ between mpc type variables and C variables of type double _Complex
+ or long double _Complex
+ - mpc_sin_cos, computing simultaneously the sine and cosine
+ - Speed-ups:
+ - mpc_pow_si through binary exponentiation
+ - mpc_pow_z when the exponent fits in a long
+ - mpc_tan through the use of mpc_sin_cos
+ - Bug fixes:
+ - trigonometric functions: infinite loop due to overflow for large
+ arguments
+ - mpc_exp: close to infinite loop for argument close to 0
+ - mpc_sqrt: close to infinite loop for argument close to 1
+ - mpc_add_si: replaced macro by function, since the macro evaluated the
+ same expression twice
+ - Logging feature for debugging:
+ ./configure --enable-logging
+ #include "mpc-log.h" instead of #include "mpc.h"
+ - Minimally required library versions: gmp 4.3.2, mpfr 2.4.2
+
+Changes in version 0.8.2:
+ - Speed-up of mpc_pow_ui through binary exponentiation
+
+Changes in version 0.8.1:
+ - Bug fixes:
+ - mpc_acosh, mpc_asinh, mpc_atanh: swap of precisions between real and
+ imaginary parts
+ - mpc_atan: memory leak
+ - mpc_log: wrong ternary value in data file; masked by bug in mpfr-2.4.1
+
+Changes in version 0.8 ("Dianthus deltoides"):
+ - New functions:
+ - mpc_asin, mpc_acos, mpc_atan, mpc_asinh, mpc_acosh, mpc_atanh,
+ mpc_pow_d, mpc_pow_ld, mpc_pow_si, mpc_pow_ui, mpc_pow_z, mpc_pow_fr
+ - Bug fixes:
+ - mpc_ui_div: real divisor
+
+Changes in version 0.7 ("Campanula uniflora"):
+ - New functions: mpc_pow, mpc_set_nan, mpc_swap
+ - Bug fixes:
+ - mpc_log: along branch cut
+ - mpc_norm: infinite loop in case of overflow
+ - mpc_ui_div, mpc_div, mpc_fr_div: handling of division by 0 and
+ infinities following the example code of the C99 standard
+ - compilation with g++
+ - Makefile.vc updated (thanks to Mickael Gastineau)
+ - Minimal gmp version is 4.2
+ - Changed MPC_SET_X_Y macro
+ - Functions mpc_random and mpc_random2 removed
+
+Changes in version 0.6 ("Bellis perennis"):
+ - New functions: mpc_get_str, mpc_set_str, mpc_strtoc, mpc_set_uj,
+ mpc_set_sj, mpc_set_ld, mpc_set_ld_ld, mpc_set_si_si, mpc_set_uj_uj,
+ mpc_set_sj_sj, mpc_set_f, mpc_set_f_f, mpc_set_q, mpc_set_q_q, mpc_set_z,
+ mpc_set_z_z and mpc_free_str
+ - New macro: MPC_SET_X_Y
+ - mpc_set_ui_fr removed
+ - Default precision removed, as well as mpc_init and all mpc_init_set*
+ combinations; use mpc_init2 or mpc_init3, followed by mpc_set, instead
+ - mpc_exp, mpc_log, mpc_cos, mpc_sin, mpc_tan, mpc_cosh, mpc_sinh,
+ mpc_tanh and mpc_sqrt return inexact value
+ - inp_str returns inexact value and the number of read characters
+ in an additional parameter
+ - Get default $CC and $CFLAGS from gmp.h (__GMP_CC / __GMP_CFLAGS,
+ which are available as of GMP 4.2.3)
+ - Bug fixes:
+ - mpc_get_version and MPC_VERSION_STRING agree
+ - Compilation on i686-pc-cygwin and i686-pc-mingw32 fixed
+
+Changes in version 0.5.2:
+ - New macros:
+ - version number: MPC_VERSION_NUM, MPC_VERSION
+ - Makefile.vc updated (thanks to Mickael Gastineau)
+ - Compilation on Debian-Gnu-Linux-PowerPC and MacOsX
+ fixed (thanks to Laurent Fousse and Mickael Gastineau)
+
+Changes in version 0.5.1:
+ - New functions:
+ - mpc_set_fr_fr
+ - mpc_real, mpc_imag
+ - mpc_arg, mpc_proj
+ - New macros:
+ - version number: MPC_VERSION_MAJOR, MPC_VERSION_MINOR,
+ MPC_VERSION_PATCHLEVEL, MPC_VERSION_STRING
+ - references to number parts: mpc_realref and mpc_imagref
+ - Test framework rewritten
+ - Configure checks for recent gmp (>= 4.2) and mpfr (>= 2.3.1)
+ libraries
+ - New configure options: --with-gmp-lib, --with-gmp-include,
+ --with-mpfr-lib, and --with-mpfr-include
+ - Export declarations for MSWindows, makefile.vc updated (thanks to
+ Mickael Gastineau)
+ - Optimisations:
+ - cmp_mul_fr, cmp_sin, cmp_cos
+ - Bug fixes:
+ - configure looks for gmp first, then for mpfr
+ - mpc_cos, mpc_div, mpc_div_fr, mpc_fr_sub, mpc_mul_fr, mpc_set_fr,
+ mpc_sqr
+ - fix handling of special values: mpc_exp, mpc_log, mpc_mul, mpc_norm,
+ mpc_sqr, mpc_sqrt
+
+Changes in version 0.5 ("Aconitum neomontanum"):
+ - Support for autotools
+ - New functions:
+ - logarithm
+ - trigonometric functions: mpc_cos, mpc_tan
+ - hyperbolic functions: mpc_cosh, mpc_sinh, mpc_tanh
+ - Bug fixes:
+ - mpc_sqrt with directed rounding
+
+
+Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
diff --git a/mpc/README b/mpc/README
new file mode 100644
index 0000000000..55369dbd0f
--- /dev/null
+++ b/mpc/README
@@ -0,0 +1,11 @@
+Copyright (C) INRIA 2003, 2005, 2008, 2009, 2011
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without any warranty.
+
+
+GNU MPC is a complex floating-point library with exact rounding.
+It is based on the GNU MPFR floating-point library (http://www.mpfr.org/),
+which is itself based on the GNU MP library (http://gmplib.org/).
diff --git a/mpc/TODO b/mpc/TODO
new file mode 100644
index 0000000000..df70e2e6b2
--- /dev/null
+++ b/mpc/TODO
@@ -0,0 +1,40 @@
+From Andreas Enge 31 August 2011:
+implement mul_karatsuba with three multiplications at precision around p,
+instead of two at precision 2*p and one at precision p
+requires analysis of error propagation
+
+From Andreas Enge 30 August 2011:
+As soon as dependent on mpfr>=3, remove auxiliary functions from
+get_version.c and update mpc.h.
+Use MPFR_RND? instead of GMP_RND?, and remove workarounds for MPFR_RNDA from
+mpc-impl.h.
+
+From Andreas Enge 05 July 2012:
+Add support for rounding mode MPFR_RNDA.
+
+From Andreas Enge and Paul Zimmermann 6 July 2012:
+Improve speed of Im (atan) for x+i*y with small y, for instance by using
+the Taylor series directly.
+
+Bench:
+- from Andreas Enge 9 June 2009:
+ Scripts and web page comparing timings with different systems,
+ as done for mpfr at http://www.mpfr.org/mpfr-2.4.0/timings.html
+
+New functions to implement:
+- from Joseph S. Myers <joseph at codesourcery dot com> 19 Mar 2012: mpc_erf,
+ mpc_erfc, mpc_exp2, mpc_expm1, mpc_log1p, mpc_log2, mpc_lgamma, mpc_tgamma
+ http://lists.gforge.inria.fr/pipermail/mpc-discuss/2012-March/001090.html
+- from Andreas Enge and Philippe Théveny 17 July 2008
+ agm (and complex logarithm with agm ?)
+- from Andreas Enge 25 June 2009:
+ correctly rounded roots of unity zeta_n^i
+- implement a root-finding algorithm using the Durand-Kerner method
+ (cf http://en.wikipedia.org/wiki/Durand%E2%80%93Kerner_method)
+ See also the CEVAL algorithm from Yap and Sagraloff:
+ http://www.mpi-inf.mpg.de/~msagralo/ceval.pdf
+
+New tests to add:
+- from Andreas Enge and Philippe Théveny 9 April 2008
+ correct handling of Nan and infinities in the case of
+ intermediate overflows while the result may fit (we need special code)
diff --git a/mpc/aclocal.m4 b/mpc/aclocal.m4
new file mode 100644
index 0000000000..36e7990dc5
--- /dev/null
+++ b/mpc/aclocal.m4
@@ -0,0 +1,1051 @@
+# generated automatically by aclocal 1.12.6 -*- Autoconf -*-
+
+# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+
+# This file 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.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 2002-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.12'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.12.6], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.12.6])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed. If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+ [am_cv_ar_interface=ar
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+ [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([am_ar_try])
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=ar
+ else
+ am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([am_ar_try])
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=lib
+ else
+ am_cv_ar_interface=unknown
+ fi
+ fi
+ rm -f conftest.lib libconftest.a
+ ])
+ ])
+
+case $am_cv_ar_interface in
+ar)
+ ;;
+lib)
+ # Microsoft lib, so override with the ar-lib wrapper script.
+ # FIXME: It is wrong to rewrite AR.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__AR in this case,
+ # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+ # similar.
+ AR="$am_aux_dir/ar-lib $AR"
+ ;;
+unknown)
+ m4_default([$1],
+ [AC_MSG_ERROR([could not determine $AR interface])])
+ ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+#
+# This file 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 macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+[$0: two- and three-arguments forms are deprecated. For more info, see:
+http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+dnl Support for Objective C++ was only introduced in Autoconf 2.65,
+dnl but we still cater to Autoconf 2.62.
+m4_ifdef([AC_PROG_OBJCXX],
+[AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+ [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+ am_maintainer_other[ make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer])],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2001-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of '-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/ax_c_check_flag.m4])
+m4_include([m4/ax_gcc_option.m4])
+m4_include([m4/ax_gcc_version.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/mpc.m4])
+m4_include([m4/valgrind-tests.m4])
diff --git a/mpc/ar-lib b/mpc/ar-lib
new file mode 100755
index 0000000000..0f62c6fc34
--- /dev/null
+++ b/mpc/ar-lib
@@ -0,0 +1,270 @@
+#! /bin/sh
+# Wrapper for Microsoft lib.exe
+
+me=ar-lib
+scriptversion=2012-03-01.08; # UTC
+
+# Copyright (C) 2010, 2012 Free Software Foundation, Inc.
+# Written by Peter Rosin <peda@lysator.liu.se>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+
+# func_error message
+func_error ()
+{
+ echo "$me: $1" 1>&2
+ exit 1
+}
+
+file_conv=
+
+# func_file_conv build_file
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv in
+ mingw)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_at_file at_file operation archive
+# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
+# for each of them.
+# When interpreting the content of the @FILE, do NOT use func_file_conv,
+# since the user would need to supply preconverted file names to
+# binutils ar, at least for MinGW.
+func_at_file ()
+{
+ operation=$2
+ archive=$3
+ at_file_contents=`cat "$1"`
+ eval set x "$at_file_contents"
+ shift
+
+ for member
+ do
+ $AR -NOLOGO $operation:"$member" "$archive" || exit $?
+ done
+}
+
+case $1 in
+ '')
+ func_error "no command. Try '$0 --help' for more information."
+ ;;
+ -h | --h*)
+ cat <<EOF
+Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
+
+Members may be specified in a file named with @FILE.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "$me, version $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test $# -lt 3; then
+ func_error "you must specify a program, an action and an archive"
+fi
+
+AR=$1
+shift
+while :
+do
+ if test $# -lt 2; then
+ func_error "you must specify a program, an action and an archive"
+ fi
+ case $1 in
+ -lib | -LIB \
+ | -ltcg | -LTCG \
+ | -machine* | -MACHINE* \
+ | -subsystem* | -SUBSYSTEM* \
+ | -verbose | -VERBOSE \
+ | -wx* | -WX* )
+ AR="$AR $1"
+ shift
+ ;;
+ *)
+ action=$1
+ shift
+ break
+ ;;
+ esac
+done
+orig_archive=$1
+shift
+func_file_conv "$orig_archive"
+archive=$file
+
+# strip leading dash in $action
+action=${action#-}
+
+delete=
+extract=
+list=
+quick=
+replace=
+index=
+create=
+
+while test -n "$action"
+do
+ case $action in
+ d*) delete=yes ;;
+ x*) extract=yes ;;
+ t*) list=yes ;;
+ q*) quick=yes ;;
+ r*) replace=yes ;;
+ s*) index=yes ;;
+ S*) ;; # the index is always updated implicitly
+ c*) create=yes ;;
+ u*) ;; # TODO: don't ignore the update modifier
+ v*) ;; # TODO: don't ignore the verbose modifier
+ *)
+ func_error "unknown action specified"
+ ;;
+ esac
+ action=${action#?}
+done
+
+case $delete$extract$list$quick$replace,$index in
+ yes,* | ,yes)
+ ;;
+ yesyes*)
+ func_error "more than one action specified"
+ ;;
+ *)
+ func_error "no action specified"
+ ;;
+esac
+
+if test -n "$delete"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ for member
+ do
+ case $1 in
+ @*)
+ func_at_file "${1#@}" -REMOVE "$archive"
+ ;;
+ *)
+ func_file_conv "$1"
+ $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
+ ;;
+ esac
+ done
+
+elif test -n "$extract"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ if test $# -gt 0; then
+ for member
+ do
+ case $1 in
+ @*)
+ func_at_file "${1#@}" -EXTRACT "$archive"
+ ;;
+ *)
+ func_file_conv "$1"
+ $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
+ ;;
+ esac
+ done
+ else
+ $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
+ do
+ $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
+ done
+ fi
+
+elif test -n "$quick$replace"; then
+ if test ! -f "$orig_archive"; then
+ if test -z "$create"; then
+ echo "$me: creating $orig_archive"
+ fi
+ orig_archive=
+ else
+ orig_archive=$archive
+ fi
+
+ for member
+ do
+ case $1 in
+ @*)
+ func_file_conv "${1#@}"
+ set x "$@" "@$file"
+ ;;
+ *)
+ func_file_conv "$1"
+ set x "$@" "$file"
+ ;;
+ esac
+ shift
+ shift
+ done
+
+ if test -n "$orig_archive"; then
+ $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
+ else
+ $AR -NOLOGO -OUT:"$archive" "$@" || exit $?
+ fi
+
+elif test -n "$list"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ $AR -NOLOGO -LIST "$archive" || exit $?
+fi
diff --git a/mpc/config.guess b/mpc/config.guess
new file mode 100755
index 0000000000..d622a44e55
--- /dev/null
+++ b/mpc/config.guess
@@ -0,0 +1,1530 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012 Free Software Foundation, Inc.
+
+timestamp='2012-02-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ i386)
+ eval $set_cc_for_build
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ UNAME_PROCESSOR="x86_64"
+ fi
+ fi ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/mpc/config.h.in b/mpc/config.h.in
new file mode 100644
index 0000000000..4f53b5183d
--- /dev/null
+++ b/mpc/config.h.in
@@ -0,0 +1,123 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* complex.h present and usable */
+#undef HAVE_COMPLEX_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dup' function. */
+#undef HAVE_DUP
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if the system has the type `intptr_t'. */
+#undef HAVE_INTPTR_T
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Library dl present */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the `localeconv' function. */
+#undef HAVE_LOCALECONV
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* C compiler */
+#undef MPC_CC
+
+/* Gcc yes or no */
+#undef MPC_GCC
+
+/* Version of gcc */
+#undef MPC_GCC_VERSION
+
+/* Do not check mpc_out_str on stdout */
+#undef MPC_NO_STREAM_REDIRECTION
+
+/* Use valgrind for make check */
+#undef MPC_USE_VALGRIND
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to the type of a signed integer type wide enough to hold a pointer,
+ if such a type exists, and if the system does not define it. */
+#undef intptr_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/mpc/config.sub b/mpc/config.sub
new file mode 100755
index 0000000000..6205f8423d
--- /dev/null
+++ b/mpc/config.sub
@@ -0,0 +1,1782 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012 Free Software Foundation, Inc.
+
+timestamp='2012-04-18'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | open8 \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i386-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/mpc/configure b/mpc/configure
new file mode 100755
index 0000000000..239f3f41fd
--- /dev/null
+++ b/mpc/configure
@@ -0,0 +1,16404 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for mpc 1.0.2.
+#
+# Report bugs to <mpc-discuss@lists.gforge.inria.fr>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: mpc-discuss@lists.gforge.inria.fr about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='mpc'
+PACKAGE_TARNAME='mpc'
+PACKAGE_VERSION='1.0.2'
+PACKAGE_STRING='mpc 1.0.2'
+PACKAGE_BUGREPORT='mpc-discuss@lists.gforge.inria.fr'
+PACKAGE_URL=''
+
+ac_unique_file="src/mpc-impl.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+SVNVERSION
+HASSVNVERSION
+GCC_VERSION
+AS
+MPC_LDFLAGS
+MPC_LOG_H
+LIBOBJS
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+LIBTOOL
+ac_ct_AR
+AR
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+SED
+EGREP
+GREP
+VALGRIND
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+with_mpfr_include
+with_mpfr_lib
+with_mpfr
+with_gmp_include
+with_gmp_lib
+with_gmp
+enable_logging
+enable_valgrind_tests
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures mpc 1.0.2 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/mpc]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of mpc 1.0.2:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful (and
+ sometimes confusing) to the casual installer
+ --enable-logging enable logging of function calls to stderr (default
+ = no)
+ --enable-valgrind-tests run checks through valgrind (default = no)
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-mpfr-include=DIR MPFR include directory
+ --with-mpfr-lib=DIR MPFR lib directory
+ --with-mpfr=DIR MPFR install directory
+ --with-gmp-include=DIR GMP include directory
+ --with-gmp-lib=DIR GMP lib directory
+ --with-gmp=DIR GMP install directory
+ --with-pic try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot=DIR Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <mpc-discuss@lists.gforge.inria.fr>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+mpc configure 1.0.2
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------------------ ##
+## Report this to mpc-discuss@lists.gforge.inria.fr ##
+## ------------------------------------------------ ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by mpc $as_me 1.0.2, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+am__api_version='1.12'
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='mpc'
+ VERSION='1.0.2'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+USER_CC=$CC
+USER_CFLAGS=$CFLAGS
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+
+
+# Extra arguments to configure
+
+# Check whether --with-mpfr_include was given.
+if test "${with_mpfr_include+set}" = set; then :
+ withval=$with_mpfr_include; CPPFLAGS="-I$withval $CPPFLAGS"
+fi
+
+
+# Check whether --with-mpfr_lib was given.
+if test "${with_mpfr_lib+set}" = set; then :
+ withval=$with_mpfr_lib; LDFLAGS="-L$withval $LDFLAGS"
+fi
+
+
+# Check whether --with-mpfr was given.
+if test "${with_mpfr+set}" = set; then :
+ withval=$with_mpfr;
+ if test -z "$with_mpfr_include" -a -z "$with_mpfr_lib" ; then
+ CPPFLAGS="-I$withval/include $CPPFLAGS"
+ LDFLAGS="-L$withval/lib $LDFLAGS"
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Do not use --with-mpfr and --with-mpfr-include/--with-mpfr-lib options simultaneously.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+
+fi
+
+
+# Check whether --with-gmp_include was given.
+if test "${with_gmp_include+set}" = set; then :
+ withval=$with_gmp_include; CPPFLAGS="-I$withval $CPPFLAGS"
+fi
+
+
+# Check whether --with-gmp_lib was given.
+if test "${with_gmp_lib+set}" = set; then :
+ withval=$with_gmp_lib; LDFLAGS="-L$withval $LDFLAGS"
+fi
+
+
+# Check whether --with-gmp was given.
+if test "${with_gmp+set}" = set; then :
+ withval=$with_gmp;
+ if test -z "$with_gmp_lib" -a -z "$with_gmp_include" ; then
+ CPPFLAGS="-I$withval/include $CPPFLAGS"
+ LDFLAGS="-L$withval/lib $LDFLAGS"
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Do not use --with-gmp and --with-gmp-include/--with-gmp-lib options simultaneously.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+
+fi
+
+# Check whether --enable-logging was given.
+if test "${enable_logging+set}" = set; then :
+ enableval=$enable_logging; case $enableval in
+ yes) if test "x$enable_shared" = "xno"; then :
+ as_fn_error $? "Logging works only with shared libraries; do not mix --enable-logging and --disable-shared" "$LINENO" 5
+fi ;;
+ no) ;;
+ *) as_fn_error $? "Bad value for --enable-logging: Use yes or no" "$LINENO" 5 ;;
+ esac
+
+
+fi
+
+# Check whether --enable-valgrind-tests was given.
+if test "${enable_valgrind_tests+set}" = set; then :
+ enableval=$enable_valgrind_tests; case $enableval in
+ yes)
+ # Run self-tests under valgrind?
+ if test "$cross_compiling" = no; then
+ for ac_prog in valgrind
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_VALGRIND+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$VALGRIND"; then
+ ac_cv_prog_VALGRIND="$VALGRIND" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_VALGRIND="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+VALGRIND=$ac_cv_prog_VALGRIND
+if test -n "$VALGRIND"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $VALGRIND" >&5
+$as_echo "$VALGRIND" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$VALGRIND" && break
+done
+
+ fi
+
+ if test -n "$VALGRIND" && $VALGRIND -q true > /dev/null 2>&1; then
+ opt_valgrind_tests=yes
+ VALGRIND="$VALGRIND -q --error-exitcode=1 --leak-check=full"
+# Addition AE: enable suppression file through a shell variable
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for valgrind suppression file" >&5
+$as_echo_n "checking for valgrind suppression file... " >&6; }
+ if test -n "$VALGRIND_SUPPRESSION"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $VALGRIND_SUPPRESSION" >&5
+$as_echo "$VALGRIND_SUPPRESSION" >&6; }
+ VALGRIND="$VALGRIND --suppressions=$VALGRIND_SUPPRESSION"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+$as_echo "#define MPC_USE_VALGRIND 1" >>confdefs.h
+
+ else
+ opt_valgrind_tests=no
+ VALGRIND=
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether self tests are run under valgrind" >&5
+$as_echo_n "checking whether self tests are run under valgrind... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $opt_valgrind_tests" >&5
+$as_echo "$opt_valgrind_tests" >&6; }
+ ;;
+ no) ;;
+ *) as_fn_error $? "Bad value for --enable-valgrind-tests: Use yes or no" "$LINENO" 5 ;;
+ esac
+
+
+fi
+
+
+# Check for CC and CFLAGS in gmp.h unless the user specified one of them
+# look for EGREP and SED here, see continued problem
+# at http://lists.gforge.inria.fr/pipermail/mpc-discuss/2012-January/001056.html
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+if test -z "$USER_CC" && test -z "$USER_CFLAGS"; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CC and CFLAGS in gmp.h" >&5
+$as_echo_n "checking for CC and CFLAGS in gmp.h... " >&6; }
+ # AC_PROG_CPP triggers the search for a C compiler; use hack instead
+ for cpp in /lib/cpp gcc cc c99
+ do
+ test $cpp = /lib/cpp || cpp="$cpp -E"
+ echo foo > conftest.c
+ if $cpp $CPPFLAGS conftest.c > /dev/null 2> /dev/null ; then
+ # Get CC
+ echo "#include \"gmp.h\"" > conftest.c
+ echo "MPFR_OPTION __GMP_CC" >> conftest.c
+ GMP_CC=`$cpp $CPPFLAGS conftest.c 2> /dev/null | $EGREP MPFR_OPTION | $SED -e 's/MPFR_OPTION //g;s/ *" *//g'`
+ # Get CFLAGS
+ echo "#include \"gmp.h\"" > conftest.c
+ echo "MPFR_OPTION __GMP_CFLAGS" >> conftest.c
+ GMP_CFLAGS=`$cpp $CPPFLAGS conftest.c 2> /dev/null | $EGREP MPFR_OPTION | $SED -e 's/MPFR_OPTION //g;s/ *" *//g'`
+ break
+ fi
+ done
+
+ if test "x$GMP_CFLAGS" = "x__GMP_CFLAGS" -o "x$GMP_CC" = "x__GMP_CC" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ GMP_CC=
+ GMP_CFLAGS=
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes CC=$GMP_CC CFLAGS=$GMP_CFLAGS" >&5
+$as_echo "yes CC=$GMP_CC CFLAGS=$GMP_CFLAGS" >&6; }
+ fi
+
+ # Check for validity of CC and CFLAGS obtained from gmp.h
+ if test -n "$GMP_CC$GMP_CFLAGS" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CC=$GMP_CC and CFLAGS=$GMP_CFLAGS" >&5
+$as_echo_n "checking for CC=$GMP_CC and CFLAGS=$GMP_CFLAGS... " >&6; }
+ echo "int main (void) { return 0; }" > conftest.c
+ if $GMP_CC $GMP_CFLAGS -o conftest conftest.c 2> /dev/null ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CC=$GMP_CC
+ CFLAGS=$GMP_CFLAGS
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ fi
+
+ rm -f conftest*
+
+fi
+
+# Setup CC and CFLAGS
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# automake 1.12 seems to require this, but automake 1.11 doesn't recognize it
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar lib "link -lib"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar lib "link -lib"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ am_cv_ar_interface=ar
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+ (eval $am_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=ar
+ else
+ am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+ (eval $am_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=lib
+ else
+ am_cv_ar_interface=unknown
+ fi
+ fi
+ rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+ ;;
+lib)
+ # Microsoft lib, so override with the ar-lib wrapper script.
+ # FIXME: It is wrong to rewrite AR.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__AR in this case,
+ # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+ # similar.
+ AR="$am_aux_dir/ar-lib $AR"
+ ;;
+unknown)
+ as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+ ;;
+esac
+
+
+# Set up LibTool
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case "$ECHO" in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ lt_prog_compiler_pic='-Xcompiler -fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ F* | *Sun*Fortran*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ link_all_deplibs=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld='-rpath $libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ link_all_deplibs=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_ld='+b $libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# Check GMP Header
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmp.h" >&5
+$as_echo_n "checking for gmp.h... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "gmp.h"
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "gmp.h cannot be found or is unusable." "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# Check (only in development versions) if the compiler accepts warning
+# flags and add them to CFLAGS
+# Note: don't do this if the user defined CFLAGS, since adding new flags
+# might override the user's settings, see
+# http://lists.gforge.inria.fr/pipermail/mpc-discuss/2012-May/001115.html
+if test -z "$USER_CFLAGS"; then
+
+
+ if echo $VERSION | grep -c dev >/dev/null 2>&1 ; then
+ if test "x$GCC" = "xyes" -a "x$compiler" != "xicc" -a "x$compiler" != "xg++"; then
+ # enable -Werror for myself (Andreas Enge)
+ if test "x$USER" = "xenge"; then
+
+
+
+
+
+
+ flag=`echo "-Werror" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Werror flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Werror flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Werror"
+
+else
+
+ :
+
+
+fi
+
+
+ fi
+
+
+
+
+
+
+ flag=`echo "-g" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -g flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -g flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -g"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-std=c99" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -std=c99 flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -std=c99 flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -std=c99"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -std=c99"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-pedantic" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -pedantic flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -pedantic flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -pedantic"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -pedantic"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-Wno-long-long" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Wno-long-long flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Wno-long-long flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wno-long-long"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Wno-long-long"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-Wall" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Wall flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Wall flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wall"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Wall"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-Wextra" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Wextra flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Wextra flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wextra"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Wextra"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-Wdeclaration-after-statement" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Wdeclaration-after-statement flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Wdeclaration-after-statement flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wdeclaration-after-statement"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Wdeclaration-after-statement"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-Wundef" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Wundef flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Wundef flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wundef"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Wundef"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-Wshadow" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Wshadow flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Wshadow flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wshadow"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Wshadow"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-Wstrict-prototypes" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Wstrict-prototypes flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Wstrict-prototypes flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wstrict-prototypes"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Wstrict-prototypes"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-Wmissing-prototypes" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Wmissing-prototypes flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Wmissing-prototypes flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wmissing-prototypes"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Wmissing-prototypes"
+
+else
+
+ :
+
+
+fi
+
+
+
+
+
+
+
+
+ flag=`echo "-Wno-unused-value" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts the -Wno-unused-value flag" >&5
+$as_echo_n "checking whether the C compiler accepts the -Wno-unused-value flag... " >&6; }
+if eval \${ax_cv_c_check_flag_$flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wno-unused-value"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ eval "ax_cv_c_check_flag_$flag=yes"
+
+else
+
+ eval "ax_cv_c_check_flag_$flag=no"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ CFLAGS="$save_CFLAGS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+fi
+eval ac_res=\$ax_cv_c_check_flag_$flag
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+ if eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"; then :
+
+ :
+ CFLAGS="$CFLAGS -Wno-unused-value"
+
+else
+
+ :
+
+
+fi
+
+
+ fi
+ fi
+
+fi
+
+
+# Checks for header files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+for ac_header in locale.h inttypes.h stdint.h limits.h unistd.h sys/time.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_time=yes
+else
+ ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "complex.h" "ac_cv_header_complex_h" "$ac_includes_default"
+if test "x$ac_cv_header_complex_h" = xyes; then :
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing creal" >&5
+$as_echo_n "checking for library containing creal... " >&6; }
+if ${ac_cv_search_creal+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char creal ();
+int
+main ()
+{
+return creal ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' m; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_creal=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_creal+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_creal+:} false; then :
+
+else
+ ac_cv_search_creal=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_creal" >&5
+$as_echo "$ac_cv_search_creal" >&6; }
+ac_res=$ac_cv_search_creal
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+# needed on Solaris
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether creal, cimag and I can be used" >&5
+$as_echo_n "checking whether creal, cimag and I can be used... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <complex.h>
+int
+main ()
+{
+complex double x = 1.0 + 2.0 * I; return (creal (x) + cimag (x));
+
+ ;
+ return 0;
+}
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_COMPLEX_H 1" >>confdefs.h
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, build without support for C complex numbers" >&5
+$as_echo "no, build without support for C complex numbers" >&6; }
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+
+fi
+
+
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this sort of thing. */
+ typedef int charset[2];
+ const charset cs = { 0, 0 };
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+
+# Checks for libraries.
+for ac_func in gettimeofday localeconv setlocale
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in dup dup2
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+
+$as_echo "#define MPC_NO_STREAM_REDIRECTION 1" >>confdefs.h
+
+fi
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpz_init in -lgmp" >&5
+$as_echo_n "checking for __gmpz_init in -lgmp... " >&6; }
+if ${ac_cv_lib_gmp___gmpz_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __gmpz_init ();
+int
+main ()
+{
+return __gmpz_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gmp___gmpz_init=yes
+else
+ ac_cv_lib_gmp___gmpz_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp___gmpz_init" >&5
+$as_echo "$ac_cv_lib_gmp___gmpz_init" >&6; }
+if test "x$ac_cv_lib_gmp___gmpz_init" = xyes; then :
+ LIBS="-lgmp $LIBS"
+else
+ as_fn_error $? "libgmp not found or uses a different ABI (including static vs shared)." "$LINENO" 5
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MPFR" >&5
+$as_echo_n "checking for MPFR... " >&6; }
+LIBS="-lmpfr $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include "mpfr.h"
+int
+main ()
+{
+mpfr_t x; mpfr_init(x) ; mpfr_clear(x);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "libmpfr not found or uses a different ABI (including static vs shared)." "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+# Check for a recent GMP
+# We only guarantee that with a *functional* and recent enough GMP version,
+# MPC will compile; we do not guarantee that GMP will compile.
+# In particular fat builds are broken in GMP 4.3.2 and GMP 5.0.0
+# (at least on 64-bit Core 2 under GNU/Linux),
+# see http://gmplib.org/list-archives/gmp-bugs/2011-August/002345.html.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for recent GMP" >&5
+$as_echo_n "checking for recent GMP... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "gmp.h"
+#if (__GNU_MP_VERSION*100 + __GNU_MP_VERSION_MINOR*10 + __GNU_MP_VERSION_PATCHLEVEL < 432)
+# error "Minimal GMP version is 4.3.2"
+error
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "GMP version >= 4.3.2 required" "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# Check for a recent MPFR: we require MPFR 2.4.2 so that the tests
+# in log.dat pass
+# The same remark as above for GMP applies.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for recent MPFR" >&5
+$as_echo_n "checking for recent MPFR... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "mpfr.h"
+#if (MPFR_VERSION < MPFR_VERSION_NUM (2,4,2))
+# error "Minimal MPFR version is 2.4.2"
+error
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "MPFR version >= 2.4.2 required" "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# Check for logging feature
+if test "x$enable_logging" = "xyes"; then :
+ for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlsym in -ldl" >&5
+$as_echo_n "checking for dlsym in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlsym+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlsym ();
+int
+main ()
+{
+return dlsym ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlsym=yes
+else
+ ac_cv_lib_dl_dlsym=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlsym" >&5
+$as_echo "$ac_cv_lib_dl_dlsym" >&6; }
+if test "x$ac_cv_lib_dl_dlsym" = xyes; then :
+
+
+$as_echo "#define HAVE_LIBDL 1" >>confdefs.h
+
+ LIBS="-ldl $LIBS"
+
+ ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_intptr_t" = xyes; then :
+
+$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h
+
+else
+ for ac_type in 'int' 'long int' 'long long int'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define intptr_t $ac_type
+_ACEOF
+
+ ac_type=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test -z "$ac_type" && break
+ done
+fi
+
+
+ case " $LIBOBJS " in
+ *" logging.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS logging.$ac_objext"
+ ;;
+esac
+
+ MPC_LOG_H=src/mpc-log.h
+
+
+else
+ as_fn_error $? "Library dl not found, logging impossible" "$LINENO" 5
+fi
+
+
+
+fi
+
+# Configs for Windows DLLs
+
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+ ac_ct_AS=$AS
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AS"; then
+ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AS="as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AS" = x; then
+ AS="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AS=$ac_ct_AS
+ fi
+else
+ AS="$ac_cv_prog_AS"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+ ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+
+ if test "$enable_shared" = yes; then
+ MPC_LDFLAGS="$MPC_LDFLAGS -no-undefined"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DLL/static gmp" >&5
+$as_echo_n "checking for DLL/static gmp... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "gmp.h"
+#if !__GMP_LIBGMP_DLL
+#error
+error
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: DLL" >&5
+$as_echo "DLL" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
+ as_fn_error $? "gmp is not available as a DLL: use --enable-static --disable-shared" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DLL/static mpfr" >&5
+$as_echo_n "checking for DLL/static mpfr... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "mpfr.h"
+#if !__GMP_LIBGMP_DLL
+#error
+error
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: DLL" >&5
+$as_echo "DLL" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
+ as_fn_error $? "mpfr is not available as a DLL: use --enable-static --disable-shared" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "gmp.h"
+#if __GMP_LIBGMP_DLL
+#error
+error
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: DLL" >&5
+$as_echo "DLL" >&6; }
+ as_fn_error $? "gmp is only available as a DLL: use --disable-static --enable-shared" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ ;;
+
+esac
+
+# Checks for gcc version, result in variables MPC_GCC etc. inside config.log
+
+ GCC_VERSION=""
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc accepts -dumpversion option" >&5
+$as_echo_n "checking if gcc accepts -dumpversion option... " >&6; }
+
+ if test "x$GCC" = "xyes" ; then :
+
+ if test -z "" ; then :
+
+ ax_gcc_option_test="int main()
+{
+ return 0;
+}"
+
+else
+
+ ax_gcc_option_test=""
+
+fi
+
+ # Dump the test program to file
+ cat <<EOF > conftest.c
+$ax_gcc_option_test
+EOF
+
+ # Dump back the file to the log, useful for debugging purposes
+ { ac_try='cat conftest.c 1>&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+
+ if { ac_try='$CC -dumpversion -c conftest.c 1>&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } ; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ ax_gcc_version_option=yes
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ ax_gcc_version_option=no
+
+
+fi
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no gcc available" >&5
+$as_echo "no gcc available" >&6; }
+
+fi
+
+ if test "x$GCC" = "xyes"; then :
+
+ if test "x$ax_gcc_version_option" != "xno"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking gcc version" >&5
+$as_echo_n "checking gcc version... " >&6; }
+if ${ax_cv_gcc_version+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ax_cv_gcc_version="`$CC -dumpversion`"
+ if test "x$ax_cv_gcc_version" = "x"; then :
+
+ ax_cv_gcc_version=""
+
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_version" >&5
+$as_echo "$ax_cv_gcc_version" >&6; }
+ GCC_VERSION=$ax_cv_gcc_version
+
+fi
+
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define MPC_GCC "$GCC"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define MPC_CC "$CC"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define MPC_GCC_VERSION "$GCC_VERSION"
+_ACEOF
+
+
+# Looks for svn version if the version string contains "dev"
+
+ if echo $VERSION | grep -c dev >/dev/null 2>&1 ; then
+ # Extract the first word of "svnversion", so it can be a program name with args.
+set dummy svnversion; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_HASSVNVERSION+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$HASSVNVERSION"; then
+ ac_cv_prog_HASSVNVERSION="$HASSVNVERSION" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_HASSVNVERSION="yes"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_HASSVNVERSION" && ac_cv_prog_HASSVNVERSION="no"
+fi
+fi
+HASSVNVERSION=$ac_cv_prog_HASSVNVERSION
+if test -n "$HASSVNVERSION"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HASSVNVERSION" >&5
+$as_echo "$HASSVNVERSION" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$HASSVNVERSION" = "xyes"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for current svn version" >&5
+$as_echo_n "checking for current svn version... " >&6; }
+ SVNVERSION=1405:1407M
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SVNVERSION" >&5
+$as_echo "$SVNVERSION" >&6; }
+
+fi
+ fi
+
+
+ac_config_files="$ac_config_files Makefile src/Makefile tests/Makefile doc/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by mpc $as_me 1.0.2, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <mpc-discuss@lists.gforge.inria.fr>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+mpc config.status 1.0.2
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+AS; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
+# Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Assembler program.
+AS=$lt_AS
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ if test x"$xsi_shell" = xyes; then
+ sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\ # positional parameters, so assign one to ordinary parameter first.\
+\ func_stripname_result=${3}\
+\ func_stripname_result=${func_stripname_result#"${1}"}\
+\ func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\ func_split_long_opt_name=${1%%=*}\
+\ func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\ func_split_short_opt_arg=${1#??}\
+\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\ case ${1} in\
+\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\ *) func_lo2o_result=${1} ;;\
+\ esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+ func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+ func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+ func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+ eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\ func_quote_for_eval "${2}"\
+\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/mpc/configure.ac b/mpc/configure.ac
new file mode 100644
index 0000000000..f81397adcb
--- /dev/null
+++ b/mpc/configure.ac
@@ -0,0 +1,242 @@
+# Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.61)
+AC_INIT(mpc, 1.0.2, mpc-discuss@lists.gforge.inria.fr)
+AC_CONFIG_SRCDIR([src/mpc-impl.h])
+AC_CONFIG_HEADER([config.h])
+
+AM_INIT_AUTOMAKE([1.9 -Wall -Werror])
+AM_MAINTAINER_MODE
+
+USER_CC=$CC
+USER_CFLAGS=$CFLAGS
+
+AC_CANONICAL_HOST
+AC_CONFIG_MACRO_DIR([m4])
+
+
+# Extra arguments to configure
+AC_ARG_WITH([mpfr_include],
+ [AC_HELP_STRING([--with-mpfr-include=DIR],
+ [MPFR include directory])],
+ [CPPFLAGS="-I$withval $CPPFLAGS"])
+AC_ARG_WITH([mpfr_lib],
+ [AC_HELP_STRING([--with-mpfr-lib=DIR],
+ [MPFR lib directory])],
+ [LDFLAGS="-L$withval $LDFLAGS"])
+AC_ARG_WITH([mpfr],
+ [AC_HELP_STRING([--with-mpfr=DIR],
+ [MPFR install directory])],
+ [
+ if test -z "$with_mpfr_include" -a -z "$with_mpfr_lib" ; then
+ CPPFLAGS="-I$withval/include $CPPFLAGS"
+ LDFLAGS="-L$withval/lib $LDFLAGS"
+ else
+ AC_MSG_FAILURE([Do not use --with-mpfr and --with-mpfr-include/--with-mpfr-lib options simultaneously.])
+ fi
+ ])
+AC_ARG_WITH([gmp_include],
+ [AC_HELP_STRING([--with-gmp-include=DIR],
+ [GMP include directory])],
+ [CPPFLAGS="-I$withval $CPPFLAGS"])
+AC_ARG_WITH([gmp_lib],
+ [AC_HELP_STRING([--with-gmp-lib=DIR],
+ [GMP lib directory])],
+ [LDFLAGS="-L$withval $LDFLAGS"])
+AC_ARG_WITH([gmp],
+ [AC_HELP_STRING([--with-gmp=DIR],
+ [GMP install directory])],
+ [
+ if test -z "$with_gmp_lib" -a -z "$with_gmp_include" ; then
+ CPPFLAGS="-I$withval/include $CPPFLAGS"
+ LDFLAGS="-L$withval/lib $LDFLAGS"
+ else
+ AC_MSG_FAILURE([Do not use --with-gmp and --with-gmp-include/--with-gmp-lib options simultaneously.])
+ fi
+ ])
+AC_ARG_ENABLE([logging],
+ [AC_HELP_STRING([--enable-logging],
+ [enable logging of function calls to stderr (default = no)])],
+ [case $enableval in
+ yes) AS_IF([test "x$enable_shared" = "xno"],
+ AC_MSG_ERROR([Logging works only with shared libraries; do not mix --enable-logging and --disable-shared])) ;;
+ no) ;;
+ *) AC_MSG_ERROR([Bad value for --enable-logging: Use yes or no]) ;;
+ esac
+ ]
+ )
+AC_ARG_ENABLE([valgrind-tests],
+ [AC_HELP_STRING([--enable-valgrind-tests],
+ [run checks through valgrind (default = no)])],
+ [case $enableval in
+ yes) gl_VALGRIND_TESTS ;;
+ no) ;;
+ *) AC_MSG_ERROR([Bad value for --enable-valgrind-tests: Use yes or no]) ;;
+ esac
+ ]
+ )
+
+# Check for CC and CFLAGS in gmp.h unless the user specified one of them
+# look for EGREP and SED here, see continued problem
+# at http://lists.gforge.inria.fr/pipermail/mpc-discuss/2012-January/001056.html
+AC_PROG_EGREP
+AC_PROG_SED
+if test -z "$USER_CC" && test -z "$USER_CFLAGS"; then
+ MPC_GMP_CC_CFLAGS
+fi
+
+# Setup CC and CFLAGS
+AC_PROG_CC
+AC_LANG(C)
+
+# automake 1.12 seems to require this, but automake 1.11 doesn't recognize it
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+# Set up LibTool
+LT_INIT
+
+# Check GMP Header
+AC_MSG_CHECKING(for gmp.h)
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#include "gmp.h"
+]])],[AC_MSG_RESULT(yes)],[
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([gmp.h cannot be found or is unusable.])
+])
+
+# Check (only in development versions) if the compiler accepts warning
+# flags and add them to CFLAGS
+# Note: don't do this if the user defined CFLAGS, since adding new flags
+# might override the user's settings, see
+# http://lists.gforge.inria.fr/pipermail/mpc-discuss/2012-May/001115.html
+if test -z "$USER_CFLAGS"; then
+ MPC_C_CHECK_WARNINGCFLAGS
+fi
+
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([locale.h inttypes.h stdint.h limits.h unistd.h sys/time.h])
+AC_HEADER_TIME
+MPC_COMPLEX_H
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+
+# Checks for libraries.
+AC_CHECK_FUNCS([gettimeofday localeconv setlocale])
+AC_CHECK_FUNCS([dup dup2],,
+ [AC_DEFINE([MPC_NO_STREAM_REDIRECTION],1,[Do not check mpc_out_str on stdout])])
+
+AC_CHECK_LIB([gmp], [__gmpz_init],
+ [LIBS="-lgmp $LIBS"],
+ [AC_MSG_ERROR([libgmp not found or uses a different ABI (including static vs shared).])])
+
+AC_MSG_CHECKING(for MPFR)
+LIBS="-lmpfr $LIBS"
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include "mpfr.h"]],
+ [[mpfr_t x; mpfr_init(x) ; mpfr_clear(x);]]
+ )],
+ [AC_MSG_RESULT(yes)],
+ [
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([libmpfr not found or uses a different ABI (including static vs shared).])
+ ])
+
+# Check for a recent GMP
+# We only guarantee that with a *functional* and recent enough GMP version,
+# MPC will compile; we do not guarantee that GMP will compile.
+# In particular fat builds are broken in GMP 4.3.2 and GMP 5.0.0
+# (at least on 64-bit Core 2 under GNU/Linux),
+# see http://gmplib.org/list-archives/gmp-bugs/2011-August/002345.html.
+AC_MSG_CHECKING(for recent GMP)
+AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[
+#include "gmp.h"
+#if (__GNU_MP_VERSION*100 + __GNU_MP_VERSION_MINOR*10 + __GNU_MP_VERSION_PATCHLEVEL < 432)
+# error "Minimal GMP version is 4.3.2"
+error
+#endif
+ ]])],
+ [AC_MSG_RESULT(yes)],
+ [
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([GMP version >= 4.3.2 required])
+ ])
+
+# Check for a recent MPFR: we require MPFR 2.4.2 so that the tests
+# in log.dat pass
+# The same remark as above for GMP applies.
+AC_MSG_CHECKING(for recent MPFR)
+AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[
+#include "mpfr.h"
+#if (MPFR_VERSION < MPFR_VERSION_NUM (2,4,2))
+# error "Minimal MPFR version is 2.4.2"
+error
+#endif
+ ]])],
+ [AC_MSG_RESULT(yes)],
+ [
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([MPFR version >= 2.4.2 required])
+ ])
+
+# Check for logging feature
+AS_IF([test "x$enable_logging" = "xyes"],
+ [AC_CHECK_HEADERS([dlfcn.h])
+ AC_CHECK_LIB([dl],[dlsym],
+ [
+ AC_DEFINE(HAVE_LIBDL, 1, [Library dl present])
+ LIBS="-ldl $LIBS"
+ AC_TYPE_INTPTR_T
+ AC_LIBOBJ([logging])
+ AC_SUBST([MPC_LOG_H],[src/mpc-log.h])
+ ],
+ [AC_MSG_ERROR([Library dl not found, logging impossible])])
+ ]
+ )
+
+# Configs for Windows DLLs
+AC_SUBST(MPC_LDFLAGS)
+AC_LIBTOOL_WIN32_DLL
+case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ MPC_WINDOWS
+esac
+
+# Checks for gcc version, result in variables MPC_GCC etc. inside config.log
+AX_GCC_VERSION
+AC_DEFINE_UNQUOTED([MPC_GCC], ["$GCC"], [Gcc yes or no])
+AC_DEFINE_UNQUOTED([MPC_CC], ["$CC"], [C compiler])
+AC_DEFINE_UNQUOTED([MPC_GCC_VERSION], ["$GCC_VERSION"], [Version of gcc])
+
+# Looks for svn version if the version string contains "dev"
+MPC_SVNVERSION
+
+AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile doc/Makefile])
+AC_OUTPUT
diff --git a/mpc/depcomp b/mpc/depcomp
new file mode 100755
index 0000000000..25a39e6cd5
--- /dev/null
+++ b/mpc/depcomp
@@ -0,0 +1,708 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2012-03-27.16; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
+# 2011, 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' "$nl" < "$tmpdepfile" |
+## Some versions of gcc put a space before the ':'. On the theory
+## that the space means something, we add a space to the output as
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like '#:fec' to the end of the
+ # dependency line.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts '$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # '$object: dependent.h' and one to simply 'dependent.h:'.
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
+ # However on
+ # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using '\':
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+ # tcc 0.9.26 (FIXME still under development at the moment of writing)
+ # will emit a similar output, but also prepend the continuation lines
+ # with horizontal tabulation characters.
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form 'foo.o: dependent.h',
+ # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # '$object: dependent.h' and one to simply 'dependent.h:'.
+ sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
+ < "$tmpdepfile" > "$depfile"
+ sed '
+ s/[ '"$tab"'][ '"$tab"']*/ /g
+ s/^ *//
+ s/ *\\*$//
+ s/^[^:]*: *//
+ /^$/d
+ /:$/d
+ s/$/ :/
+ ' < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mechanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test "$stat" = 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for ':'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' "$nl" < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mpc/doc/Makefile.am b/mpc/doc/Makefile.am
new file mode 100644
index 0000000000..9e1709db84
--- /dev/null
+++ b/mpc/doc/Makefile.am
@@ -0,0 +1,20 @@
+## doc/Makefile.am -- Process this file with automake to produce Makefile.in
+##
+## Copyright (C) 2008 INRIA
+##
+## This file is part of GNU MPC.
+##
+## GNU MPC is free software; you can redistribute it and/or modify it under
+## the terms of the GNU Lesser General Public License as published by the
+## Free Software Foundation; either version 3 of the License, or (at your
+## option) any later version.
+##
+## GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+## FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+## more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this program. If not, see http://www.gnu.org/licenses/ .
+
+info_TEXINFOS = mpc.texi
diff --git a/mpc/doc/Makefile.in b/mpc/doc/Makefile.in
new file mode 100644
index 0000000000..2f724131ae
--- /dev/null
+++ b/mpc/doc/Makefile.in
@@ -0,0 +1,702 @@
+# Makefile.in generated by automake 1.12.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2012 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@
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/stamp-vti $(srcdir)/version.texi mdate-sh \
+ texinfo.tex
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c_check_flag.m4 \
+ $(top_srcdir)/m4/ax_gcc_option.m4 \
+ $(top_srcdir)/m4/ax_gcc_version.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/mpc.m4 $(top_srcdir)/m4/valgrind-tests.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+INFO_DEPS = $(srcdir)/mpc.info
+am__TEXINFO_TEX_DIR = $(srcdir)
+DVIS = mpc.dvi
+PDFS = mpc.pdf
+PSS = mpc.ps
+HTMLS = mpc.html
+TEXINFOS = mpc.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__installdirs = "$(DESTDIR)$(infodir)"
+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; }; \
+ }
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCC_VERSION = @GCC_VERSION@
+GREP = @GREP@
+HASSVNVERSION = @HASSVNVERSION@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPC_LDFLAGS = @MPC_LDFLAGS@
+MPC_LOG_H = @MPC_LOG_H@
+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@
+STRIP = @STRIP@
+SVNVERSION = @SVNVERSION@
+VALGRIND = @VALGRIND@
+VERSION = @VERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+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@
+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@
+info_TEXINFOS = mpc.texi
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .html .info .pdf .ps .texi
+$(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 doc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu doc/Makefile
+.PRECIOUS: 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):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+.texi.info:
+ restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ am__cwd=`pwd` && $(am__cd) $(srcdir) && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+ done; \
+ else :; fi && \
+ cd "$$am__cwd"; \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<; \
+ then \
+ rc=0; \
+ $(am__cd) $(srcdir); \
+ else \
+ rc=$$?; \
+ $(am__cd) $(srcdir) && \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) --clean $<
+
+.texi.pdf:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) --clean $<
+
+.texi.html:
+ rm -rf $(@:.html=.htp)
+ if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ else \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+ exit 1; \
+ fi
+$(srcdir)/mpc.info: mpc.texi $(srcdir)/version.texi
+mpc.dvi: mpc.texi $(srcdir)/version.texi
+mpc.pdf: mpc.texi $(srcdir)/version.texi
+mpc.html: mpc.texi $(srcdir)/version.texi
+$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti
+$(srcdir)/stamp-vti: mpc.texi $(top_srcdir)/configure
+ @(dir=.; test -f ./mpc.texi || dir=$(srcdir); \
+ set `$(SHELL) $(srcdir)/mdate-sh $$dir/mpc.texi`; \
+ echo "@set UPDATED $$1 $$2 $$3"; \
+ echo "@set UPDATED-MONTH $$2 $$3"; \
+ echo "@set EDITION $(VERSION)"; \
+ echo "@set VERSION $(VERSION)") > vti.tmp
+ @cmp -s vti.tmp $(srcdir)/version.texi \
+ || (echo "Updating $(srcdir)/version.texi"; \
+ cp vti.tmp $(srcdir)/version.texi)
+ -@rm -f vti.tmp
+ @cp $(srcdir)/version.texi $@
+
+mostlyclean-vti:
+ -rm -f vti.tmp
+
+maintainer-clean-vti:
+@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
+.dvi.ps:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) -o $@ $<
+
+uninstall-dvi-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
+ rm -f "$(DESTDIR)$(dvidir)/$$f"; \
+ done
+
+uninstall-html-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-info-am:
+ @$(PRE_UNINSTALL)
+ @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
+ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+uninstall-pdf-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
+
+uninstall-ps-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(psdir)/$$f"; \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+ if test -f $$file; then \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f "$(distdir)/$$relfile" || \
+ cp -p $$file "$(distdir)/$$relfile"; \
+ else :; fi; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf mpc.aux mpc.cp mpc.cps mpc.fn mpc.fns mpc.ky mpc.kys mpc.log mpc.pg \
+ mpc.pgs mpc.tmp mpc.toc mpc.tp mpc.vr mpc.vrs
+
+clean-aminfo:
+ -test -z "mpc.dvi mpc.pdf mpc.ps mpc.html" \
+ || rm -rf mpc.dvi mpc.pdf mpc.ps mpc.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+cscope cscopelist:
+
+
+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
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-info
+check-am: all-am
+check: check-am
+all-am: Makefile $(INFO_DEPS)
+installdirs:
+ for dir in "$(DESTDIR)$(infodir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+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:
+
+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-aminfo clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am
+
+install-dvi: install-dvi-am
+
+install-dvi-am: $(DVIS)
+ @$(NORMAL_INSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
+ done
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am: $(HTMLS)
+ @$(NORMAL_INSTALL)
+ @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__strip_dir) \
+ d2=$$d$$p; \
+ if test -d "$$d2"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+ echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+ else \
+ list2="$$list2 $$d2"; \
+ fi; \
+ done; \
+ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
+ done; }
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \
+ fi; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ echo "$$ifile"; \
+ else : ; fi; \
+ done; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
+ @$(POST_INSTALL)
+ @if $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am: $(PDFS)
+ @$(NORMAL_INSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
+install-ps: install-ps-am
+
+install-ps-am: $(PSS)
+ @$(NORMAL_INSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+ maintainer-clean-generic maintainer-clean-vti
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-libtool mostlyclean-vti
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-aminfo clean-generic \
+ clean-libtool dist-info distclean distclean-generic \
+ distclean-libtool 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-aminfo \
+ maintainer-clean-generic maintainer-clean-vti mostlyclean \
+ mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool \
+ mostlyclean-vti pdf pdf-am ps ps-am uninstall uninstall-am \
+ uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+
+# 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/mpc/doc/fdl-1.3.texi b/mpc/doc/fdl-1.3.texi
new file mode 100644
index 0000000000..fc19ddddfa
--- /dev/null
+++ b/mpc/doc/fdl-1.3.texi
@@ -0,0 +1,506 @@
+@c The GNU Free Documentation License.
+@center Version 1.3, 3 November 2008
+
+@c This file is intended to be included within another document,
+@c hence no sectioning command or @node.
+
+@display
+Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+@uref{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, La@TeX{} input
+format, SGML or XML using a publicly available
+DTD, and standard-conforming simple HTML,
+PostScript or PDF designed for human modification. Examples
+of transparent image formats include PNG, XCF and
+JPG. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, SGML or
+XML for which the DTD and/or processing tools are
+not generally available, and the machine-generated HTML,
+PostScript or PDF produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+The ``publisher'' means any person or entity that distributes copies
+of the Document to the public.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense, or distribute it is void, and
+will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation. If the Document
+specifies that a proxy can decide which future versions of this
+License can be used, that proxy's public statement of acceptance of a
+version permanently authorizes you to choose that version for the
+Document.
+
+@item
+RELICENSING
+
+``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
+World Wide Web server that publishes copyrightable works and also
+provides prominent facilities for anybody to edit those works. A
+public wiki that anybody can edit is an example of such a server. A
+``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
+site means any set of copyrightable works thus published on the MMC
+site.
+
+``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
+license published by Creative Commons Corporation, a not-for-profit
+corporation with a principal place of business in San Francisco,
+California, as well as future copyleft versions of that license
+published by that same organization.
+
+``Incorporate'' means to publish or republish a Document, in whole or
+in part, as part of another Document.
+
+An MMC is ``eligible for relicensing'' if it is licensed under this
+License, and if all works that were first published under this License
+somewhere other than this MMC, and subsequently incorporated in whole
+or in part into the MMC, (1) had no cover texts or invariant sections,
+and (2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+@end enumerate
+
+@page
+@heading ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with@dots{}Texts.'' line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
+
diff --git a/mpc/doc/mdate-sh b/mpc/doc/mdate-sh
new file mode 100755
index 0000000000..e631b2219a
--- /dev/null
+++ b/mpc/doc/mdate-sh
@@ -0,0 +1,205 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005, 2007, 2009 Free
+# Software Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+ '')
+ echo "$0: No file. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: mdate-sh [--help] [--version] FILE
+
+Pretty-print the modification time of FILE.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "mdate-sh $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# GNU ls changes its time format in response to the TIME_STYLE
+# variable. Since we cannot assume `unset' works, revert this
+# variable to its documented default.
+if test "${TIME_STYLE+set}" = set; then
+ TIME_STYLE=posix-long-iso
+ export TIME_STYLE
+fi
+
+save_arg1=$1
+
+# Find out how to get the extended ls output of a file or directory.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+ ls_command='ls -L -l -d'
+else
+ ls_command='ls -l -d'
+fi
+# Avoid user/group names that might have spaces, when possible.
+if ls -n /dev/null 1>/dev/null 2>&1; then
+ ls_command="$ls_command -n"
+fi
+
+# A `ls -l' line looks as follows on OS/2.
+# drwxrwx--- 0 Aug 11 2001 foo
+# This differs from Unix, which adds ownership information.
+# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
+#
+# To find the date, we split the line on spaces and iterate on words
+# until we find a month. This cannot work with files whose owner is a
+# user named `Jan', or `Feb', etc. However, it's unlikely that `/'
+# will be owned by a user whose name is a month. So we first look at
+# the extended ls output of the root directory to decide how many
+# words should be skipped to get the date.
+
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+set x`$ls_command /`
+
+# Find which argument is the month.
+month=
+command=
+until test $month
+do
+ shift
+ # Add another shift to the command.
+ command="$command shift;"
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+done
+
+# Get the extended ls output of the file or directory.
+set dummy x`eval "$ls_command \"\$save_arg1\""`
+
+# Remove all preceding arguments
+eval $command
+
+# Because of the dummy argument above, month is in $2.
+#
+# On a POSIX system, we should have
+#
+# $# = 5
+# $1 = file size
+# $2 = month
+# $3 = day
+# $4 = year or time
+# $5 = filename
+#
+# On Darwin 7.7.0 and 7.6.0, we have
+#
+# $# = 4
+# $1 = day
+# $2 = month
+# $3 = year or time
+# $4 = filename
+
+# Get the month.
+case $2 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+esac
+
+case $3 in
+ ???*) day=$1;;
+ *) day=$3; shift;;
+esac
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+ *:*) set `date`; eval year=\$$#
+ case $2 in
+ Jan) nummonthtod=1;;
+ Feb) nummonthtod=2;;
+ Mar) nummonthtod=3;;
+ Apr) nummonthtod=4;;
+ May) nummonthtod=5;;
+ Jun) nummonthtod=6;;
+ Jul) nummonthtod=7;;
+ Aug) nummonthtod=8;;
+ Sep) nummonthtod=9;;
+ Oct) nummonthtod=10;;
+ Nov) nummonthtod=11;;
+ Dec) nummonthtod=12;;
+ esac
+ # For the first six month of the year the time notation can also
+ # be used for files modified in the last year.
+ if (expr $nummonth \> $nummonthtod) > /dev/null;
+ then
+ year=`expr $year - 1`
+ fi;;
+ *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mpc/doc/mpc.info b/mpc/doc/mpc.info
new file mode 100644
index 0000000000..7f1552aeb7
--- /dev/null
+++ b/mpc/doc/mpc.info
@@ -0,0 +1,1799 @@
+This is mpc.info, produced by makeinfo version 5.1 from mpc.texi.
+
+This manual is for GNU MPC, a library for multiple precision complex
+arithmetic, version 1.0.2 of January 2014.
+
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012 INRIA
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with no Invariant Sections. A copy of the license is
+ included in the section entitled "GNU Free Documentation License."
+INFO-DIR-SECTION GNU Packages
+START-INFO-DIR-ENTRY
+* mpc: (mpc)Multiple Precision Complex Library.
+END-INFO-DIR-ENTRY
+
+
+File: mpc.info, Node: Top, Next: Copying, Up: (dir)
+
+GNU MPC
+*******
+
+This manual documents how to install and use the GNU Multiple Precision
+Complex Library, version 1.0.2
+
+* Menu:
+
+* Copying:: GNU MPC Copying Conditions (LGPL).
+* Introduction to GNU MPC:: Brief introduction to GNU MPC.
+* Installing GNU MPC:: How to configure and compile the GNU MPC library.
+* Reporting Bugs:: How to usefully report bugs.
+* GNU MPC Basics:: What every GNU MPC user should know.
+* Complex Functions:: Functions for arithmetic on complex numbers.
+* References::
+* Concept Index::
+* Function Index::
+* GNU Free Documentation License::
+
+
+File: mpc.info, Node: Copying, Next: Introduction to GNU MPC, Prev: Top, Up: Top
+
+GNU MPC Copying Conditions
+**************************
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+ GNU MPC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+License along with this program. If not, see
+<http://www.gnu.org/licenses/>.
+
+
+File: mpc.info, Node: Introduction to GNU MPC, Next: Installing GNU MPC, Prev: Copying, Up: Top
+
+1 Introduction to GNU MPC
+*************************
+
+GNU MPC is a portable library written in C for arbitrary precision
+arithmetic on complex numbers providing correct rounding. It implements
+a multiprecision equivalent of the C99 standard. It builds upon the GNU
+MP and the GNU MPFR libraries.
+
+1.1 How to use this Manual
+==========================
+
+Everyone should read *note GNU MPC Basics::. If you need to install the
+library yourself, you need to read *note Installing GNU MPC::, too.
+
+ The remainder of the manual can be used for later reference, although
+it is probably a good idea to skim through it.
+
+
+File: mpc.info, Node: Installing GNU MPC, Next: Reporting Bugs, Prev: Introduction to GNU MPC, Up: Top
+
+2 Installing GNU MPC
+********************
+
+To build GNU MPC, you first have to install GNU MP (version 4.3.2 or
+higher) and GNU MPFR (version 2.4.2 or higher) on your computer. You
+need a C compiler; GCC version 4.4 or higher is recommended, since GNU
+MPC may trigger a bug in previous versions, see the thread at
+<http://lists.gforge.inria.fr/pipermail/mpc-discuss/2011-February/000823.html>.
+And you need a standard Unix 'make' program, plus some other standard
+Unix utility programs.
+
+ Here are the steps needed to install the library on Unix systems:
+
+ 1. 'tar xzf mpc-1.0.2.tar.gz'
+
+ 2. 'cd mpc-1.0.2'
+
+ 3. './configure'
+
+ if GMP and GNU MPFR are installed into standard directories, that
+ is, directories that are searched by default by the compiler and
+ the linking tools.
+
+ './configure --with-gmp=<gmp_install_dir>'
+
+ is used to indicate a different location where GMP is installed.
+ Alternatively, you can specify directly GMP include and GMP lib
+ directories with './configure --with-gmp-lib=<gmp_lib_dir>
+ --with-gmp-include=<gmp_include_dir>'.
+
+ './configure --with-mpfr=<mpfr_install_dir>'
+
+ is used to indicate a different location where GNU MPFR is
+ installed. Alternatively, you can specify directly GNU MPFR
+ include and GNU MPFR lib directories with './configure
+ --with-mpf-lib=<mpfr_lib_dir>
+ --with-mpfr-include=<mpfr_include_dir>'.
+
+ Another useful parameter is '--prefix', which can be used to
+ specify an alternative installation location instead of
+ '/usr/local'; see 'make install' below.
+
+ To enable checking for memory leaks using 'valgrind' during 'make
+ check', add the parameter '--enable-valgrind-tests'.
+
+ If for debugging purposes you wish to log calls to GNU MPC
+ functions from within your code, add the parameter
+ '--enable-logging'. In your code, replace the inclusion of 'mpc.h'
+ by 'mpc-log.h' and link the executable dynamically. Then all calls
+ to functions with only complex arguments are printed to 'stderr' in
+ the following form: First, the function name is given, followed by
+ its type such as 'c_cc', meaning that the function has one complex
+ result (one 'c' in front of the '_'), computed from two complex
+ arguments (two 'c' after the '_'). Then, the precisions of the
+ real and the imaginary part of the first result is given, followed
+ by the second one and so on. Finally, for each argument, the
+ precisions of its real and imaginary part are specified and the
+ argument itself is printed in hexadecimal via the function
+ 'mpc_out_str' (*note String and Stream Input and Output::). The
+ option requires a dynamic library, so it may not be combined with
+ '--disable-shared'.
+
+ Use './configure --help' for an exhaustive list of parameters.
+
+ 4. 'make'
+
+ This compiles GNU MPC in the working directory.
+
+ 5. 'make check'
+
+ This will make sure GNU MPC was built correctly.
+
+ If you get error messages, please report them to
+ 'mpc-discuss@lists.gforge.inria.fr' (*Note Reporting Bugs::, for
+ information on what to include in useful bug reports).
+
+ 6. 'make install'
+
+ This will copy the file 'mpc.h' to the directory
+ '/usr/local/include', the file 'libmpc.a' to the directory
+ '/usr/local/lib', and the file 'mpc.info' to the directory
+ '/usr/local/share/info' (or if you passed the '--prefix' option to
+ 'configure', using the prefix directory given as argument to
+ '--prefix' instead of '/usr/local'). Note: you need write
+ permissions on these directories.
+
+2.1 Other 'make' Targets
+========================
+
+There are some other useful make targets:
+
+ * 'info'
+
+ Create an info version of the manual, in 'mpc.info'.
+
+ * 'pdf'
+
+ Create a PDF version of the manual, in 'doc/mpc.pdf'.
+
+ * 'dvi'
+
+ Create a DVI version of the manual, in 'doc/mpc.dvi'.
+
+ * 'ps'
+
+ Create a Postscript version of the manual, in 'doc/mpc.ps'.
+
+ * 'html'
+
+ Create an HTML version of the manual, in several pages in the
+ directory 'doc/mpc.html'; if you want only one output HTML file,
+ then type 'makeinfo --html --no-split mpc.texi' instead.
+
+ * 'clean'
+
+ Delete all object files and archive files, but not the
+ configuration files.
+
+ * 'distclean'
+
+ Delete all files not included in the distribution.
+
+ * 'uninstall'
+
+ Delete all files copied by 'make install'.
+
+2.2 Known Build Problems
+========================
+
+On AIX, if GMP was built with the 64-bit ABI, before building and
+testing GNU MPC, it might be necessary to set the 'OBJECT_MODE'
+environment variable to 64 by, e.g.,
+
+ 'export OBJECT_MODE=64'
+
+ This has been tested with the C compiler IBM XL C/C++ Enterprise
+Edition V8.0 for AIX, version: 08.00.0000.0021, GMP 4.2.4 and GNU MPFR
+2.4.1.
+
+ Please report any other problems you encounter to
+'mpc-discuss@lists.gforge.inria.fr'. *Note Reporting Bugs::.
+
+
+File: mpc.info, Node: Reporting Bugs, Next: GNU MPC Basics, Prev: Installing GNU MPC, Up: Top
+
+3 Reporting Bugs
+****************
+
+If you think you have found a bug in the GNU MPC library, please
+investigate and report it. We have made this library available to you,
+and it is not to ask too much from you, to ask you to report the bugs
+that you find.
+
+ There are a few things you should think about when you put your bug
+report together.
+
+ You have to send us a test case that makes it possible for us to
+reproduce the bug. Include instructions on how to run the test case.
+
+ You also have to explain what is wrong; if you get a crash, or if the
+results printed are incorrect and in that case, in what way.
+
+ Please include compiler version information in your bug report. This
+can be extracted using 'gcc -v', or 'cc -V' on some machines. Also,
+include the output from 'uname -a'.
+
+ If your bug report is good, we will do our best to help you to get a
+corrected version of the library; if the bug report is poor, we will not
+do anything about it (aside of chiding you to send better bug reports).
+
+ Send your bug report to: 'mpc-discuss@lists.gforge.inria.fr'.
+
+ If you think something in this manual is unclear, or downright
+incorrect, or if the language needs to be improved, please send a note
+to the same address.
+
+
+File: mpc.info, Node: GNU MPC Basics, Next: Complex Functions, Prev: Reporting Bugs, Up: Top
+
+4 GNU MPC Basics
+****************
+
+All declarations needed to use GNU MPC are collected in the include file
+'mpc.h'. It is designed to work with both C and C++ compilers. You
+should include that file in any program using the GNU MPC library by
+adding the line
+ #include "mpc.h"
+
+4.1 Nomenclature and Types
+==========================
+
+"Complex number" or "Complex" for short, is a pair of two arbitrary
+precision floating-point numbers (for the real and imaginary parts).
+The C data type for such objects is 'mpc_t'.
+
+The "Precision" is the number of bits used to represent the mantissa of
+the real and imaginary parts; the corresponding C data type is
+'mpfr_prec_t'. For more details on the allowed precision range, *note
+(mpfr.info)Nomenclature and Types::.
+
+The "rounding mode" specifies the way to round the result of a complex
+operation, in case the exact result can not be represented exactly in
+the destination mantissa; the corresponding C data type is 'mpc_rnd_t'.
+A complex rounding mode is a pair of two rounding modes: one for the
+real part, one for the imaginary part.
+
+4.2 Function Classes
+====================
+
+There is only one class of functions in the GNU MPC library, namely
+functions for complex arithmetic. The function names begin with 'mpc_'.
+The associated type is 'mpc_t'.
+
+4.3 GNU MPC Variable Conventions
+================================
+
+As a general rule, all GNU MPC functions expect output arguments before
+input arguments. This notation is based on an analogy with the
+assignment operator.
+
+ GNU MPC allows you to use the same variable for both input and output
+in the same expression. For example, the main function for
+floating-point multiplication, 'mpc_mul', can be used like this:
+'mpc_mul (x, x, x, rnd_mode)'. This computes the square of X with
+rounding mode 'rnd_mode' and puts the result back in X.
+
+ Before you can assign to an GNU MPC variable, you need to initialize
+it by calling one of the special initialization functions. When you are
+done with a variable, you need to clear it out, using one of the
+functions for that purpose.
+
+ A variable should only be initialized once, or at least cleared out
+between each initialization. After a variable has been initialized, it
+may be assigned to any number of times.
+
+ For efficiency reasons, avoid to initialize and clear out a variable
+in loops. Instead, initialize it before entering the loop, and clear it
+out after the loop has exited.
+
+ You do not need to be concerned about allocating additional space for
+GNU MPC variables, since each of its real and imaginary part has a
+mantissa of fixed size. Hence unless you change its precision, or clear
+and reinitialize it, a complex variable will have the same allocated
+space during all its life.
+
+4.4 Rounding Modes
+==================
+
+A complex rounding mode is of the form 'MPC_RNDxy' where 'x' and 'y' are
+one of 'N' (to nearest), 'Z' (towards zero), 'U' (towards plus
+infinity), 'D' (towards minus infinity). The first letter refers to the
+rounding mode for the real part, and the second one for the imaginary
+part. For example 'MPC_RNDZU' indicates to round the real part towards
+zero, and the imaginary part towards plus infinity.
+
+ The 'round to nearest' mode works as in the IEEE P754 standard: in
+case the number to be rounded lies exactly in the middle of two
+representable numbers, it is rounded to the one with the least
+significant bit set to zero. For example, the number 5, which is
+represented by (101) in binary, is rounded to (100)=4 with a precision
+of two bits, and not to (110)=6.
+
+4.5 Return Value
+================
+
+Most GNU MPC functions have a return value of type 'int', which is used
+to indicate the position of the rounded real and imaginary parts with
+respect to the exact (infinite precision) values. If this integer is
+'i', the macros 'MPC_INEX_RE(i)' and 'MPC_INEX_IM(i)' give 0 if the
+corresponding rounded value is exact, a negative value if the rounded
+value is less than the exact one, and a positive value if it is greater
+than the exact one. Similarly, functions computing a result of type
+'mpfr_t' return an integer that is 0, positive or negative depending on
+whether the rounded value is the same, larger or smaller then the exact
+result.
+
+ Some functions, such as 'mpc_sin_cos', compute two complex results;
+the macros 'MPC_INEX1(i)' and 'MPC_INEX2(i)', applied to the return
+value 'i' of such a function, yield the exactness value corresponding to
+the first or the second computed value, respectively.
+
+4.6 Branch Cuts And Special Values
+==================================
+
+Some complex functions have branch cuts, across which the function is
+discontinous. In GNU MPC, the branch cuts chosen are the same as those
+specified for the corresponding functions in the ISO C99 standard.
+
+ Likewise, when evaluated at a point whose real or imaginary part is
+either infinite or a NaN or a signed zero, a function returns the same
+value as those specified for the corresponding function in the ISO C99
+standard.
+
+
+File: mpc.info, Node: Complex Functions, Next: References, Prev: GNU MPC Basics, Up: Top
+
+5 Complex Functions
+*******************
+
+The complex functions expect arguments of type 'mpc_t'.
+
+ The GNU MPC floating-point functions have an interface that is
+similar to the GNU MP integer functions. The function prefix for
+operations on complex numbers is 'mpc_'.
+
+ The precision of a computation is defined as follows: Compute the
+requested operation exactly (with "infinite precision"), and round the
+result to the destination variable precision with the given rounding
+mode.
+
+ The GNU MPC complex functions are intended to be a smooth extension
+of the IEEE P754 arithmetic. The results obtained on one computer
+should not differ from the results obtained on a computer with a
+different word size.
+
+* Menu:
+
+* Initializing Complex Numbers::
+* Assigning Complex Numbers::
+* Converting Complex Numbers::
+* String and Stream Input and Output::
+* Complex Comparison::
+* Projection & Decomposing::
+* Basic Arithmetic::
+* Power Functions and Logarithm::
+* Trigonometric Functions::
+* Miscellaneous Complex Functions::
+* Advanced Functions::
+* Internals::
+
+
+File: mpc.info, Node: Initializing Complex Numbers, Next: Assigning Complex Numbers, Up: Complex Functions
+
+5.1 Initialization Functions
+============================
+
+An 'mpc_t' object must be initialized before storing the first value in
+it. The functions 'mpc_init2' and 'mpc_init3' are used for that
+purpose.
+
+ -- Function: void mpc_init2 (mpc_t Z, mpfr_prec_t PREC)
+ Initialize Z to precision PREC bits and set its real and imaginary
+ parts to NaN. Normally, a variable should be initialized once only
+ or at least be cleared, using 'mpc_clear', between initializations.
+
+ -- Function: void mpc_init3 (mpc_t Z, mpfr_prec_t PREC_R, mpfr_prec_t
+ PREC_I)
+ Initialize Z with the precision of its real part being PREC_R bits
+ and the precision of its imaginary part being PREC_I bits, and set
+ the real and imaginary parts to NaN.
+
+ -- Function: void mpc_clear (mpc_t Z)
+ Free the space occupied by Z. Make sure to call this function for
+ all 'mpc_t' variables when you are done with them.
+
+ Here is an example on how to initialize complex variables:
+ {
+ mpc_t x, y;
+ mpc_init2 (x, 256); /* precision _exactly_ 256 bits */
+ mpc_init3 (y, 100, 50); /* 100/50 bits for the real/imaginary part */
+ ...
+ mpc_clear (x);
+ mpc_clear (y);
+ }
+
+ The following function is useful for changing the precision during a
+calculation. A typical use would be for adjusting the precision
+gradually in iterative algorithms like Newton-Raphson, making the
+computation precision closely match the actual accurate part of the
+numbers.
+
+ -- Function: void mpc_set_prec (mpc_t X, mpfr_prec_t PREC)
+ Reset the precision of X to be *exactly* PREC bits, and set its
+ real/imaginary parts to NaN. The previous value stored in X is
+ lost. It is equivalent to a call to 'mpc_clear(x)' followed by a
+ call to 'mpc_init2(x, prec)', but more efficient as no allocation
+ is done in case the current allocated space for the mantissa of X
+ is sufficient.
+
+ -- Function: mpfr_prec_t mpc_get_prec (mpc_t X)
+ If the real and imaginary part of X have the same precision, it is
+ returned, otherwise, 0 is returned.
+
+ -- Function: void mpc_get_prec2 (mpfr_prec_t* PR, mpfr_prec_t* PI,
+ mpc_t X)
+ Returns the precision of the real part of X via PR and of its
+ imaginary part via PI.
+
+
+File: mpc.info, Node: Assigning Complex Numbers, Next: Converting Complex Numbers, Prev: Initializing Complex Numbers, Up: Complex Functions
+
+5.2 Assignment Functions
+========================
+
+These functions assign new values to already initialized complex numbers
+(*note Initializing Complex Numbers::). When using any functions with
+'intmax_t' or 'uintmax_t' parameters, you must include '<stdint.h>' or
+'<inttypes.h>' _before_ 'mpc.h', to allow 'mpc.h' to define prototypes
+for these functions. Similarly, functions with parameters of type
+'complex' or 'long complex' are defined only if '<complex.h>' is
+included _before_ 'mpc.h'. If you need assignment functions that are
+not in the current API, you can define them using the 'MPC_SET_X_Y'
+macro (*note Advanced Functions::).
+
+ -- Function: int mpc_set (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set the value of ROP from OP, rounded to the precision of ROP with
+ the given rounding mode RND.
+
+ -- Function: int mpc_set_ui (mpc_t ROP, unsigned long int OP, mpc_rnd_t
+ RND)
+ -- Function: int mpc_set_si (mpc_t ROP, long int OP, mpc_rnd_t RND)
+ -- Function: int mpc_set_uj (mpc_t ROP, uintmax_t OP, mpc_rnd_t RND)
+ -- Function: int mpc_set_sj (mpc_t ROP, intmax_t OP, mpc_rnd_t RND)
+ -- Function: int mpc_set_d (mpc_t ROP, double OP, mpc_rnd_t RND)
+ -- Function: int mpc_set_ld (mpc_t ROP, long double OP, mpc_rnd_t RND)
+ -- Function: int mpc_set_dc (mpc_t ROP, double _Complex OP, mpc_rnd_t
+ RND)
+ -- Function: int mpc_set_ldc (mpc_t ROP, long double _Complex OP,
+ mpc_rnd_t RND)
+ -- Function: int mpc_set_z (mpc_t ROP, mpz_t OP mpc_rnd_t RND)
+ -- Function: int mpc_set_q (mpc_t ROP, mpq_t OP mpc_rnd_t RND)
+ -- Function: int mpc_set_f (mpc_t ROP, mpf_t OP mpc_rnd_t RND)
+ -- Function: int mpc_set_fr (mpc_t ROP, mpfr_t OP, mpc_rnd_t RND)
+ Set the value of ROP from OP, rounded to the precision of ROP with
+ the given rounding mode RND. The argument OP is interpreted as
+ real, so the imaginary part of ROP is set to zero with a positive
+ sign. Please note that even a 'long int' may have to be rounded,
+ if the destination precision is less than the machine word width.
+ For 'mpc_set_d', be careful that the input number OP may not be
+ exactly representable as a double-precision number (this happens
+ for 0.1 for instance), in which case it is first rounded by the C
+ compiler to a double-precision number, and then only to a complex
+ number.
+
+ -- Function: int mpc_set_ui_ui (mpc_t ROP, unsigned long int OP1,
+ unsigned long int OP2, mpc_rnd_t RND)
+ -- Function: int mpc_set_si_si (mpc_t ROP, long int OP1, long int OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_set_uj_uj (mpc_t ROP, uintmax_t OP1, uintmax_t
+ OP2, mpc_rnd_t RND)
+ -- Function: int mpc_set_sj_sj (mpc_t ROP, intmax_t OP1, intmax_t OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_set_d_d (mpc_t ROP, double OP1, double OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_set_ld_ld (mpc_t ROP, long double OP1, long double
+ OP2, mpc_rnd_t RND)
+ -- Function: int mpc_set_z_z (mpc_t ROP, mpz_t OP1, mpz_t OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_set_q_q (mpc_t ROP, mpq_t OP1, mpq_t OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_set_f_f (mpc_t ROP, mpf_t OP1, mpf_t OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_set_fr_fr (mpc_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpc_rnd_t RND)
+ Set the real part of ROP from OP1, and its imaginary part from OP2,
+ according to the rounding mode RND.
+
+ Beware that the behaviour of 'mpc_set_fr_fr' is undefined if OP1 or
+ OP2 is a pointer to the real or imaginary part of ROP. To exchange
+ the real and the imaginary part of a complex number, either use
+ 'mpfr_swap (mpc_realref (rop), mpc_imagref (rop))', which also
+ exchanges the precisions of the two parts; or use a temporary
+ variable.
+
+ For functions assigning complex variables from strings or input
+streams, *note String and Stream Input and Output::.
+
+ -- Function: void mpc_set_nan (mpc_t ROP)
+ Set ROP to Nan+i*NaN.
+
+ -- Function: void mpc_swap (mpc_t OP1, mpc_t OP2)
+ Swap the values of OP1 and OP2 efficiently. Warning: The
+ precisions are exchanged, too; in case these are different,
+ 'mpc_swap' is thus not equivalent to three 'mpc_set' calls using a
+ third auxiliary variable.
+
+
+File: mpc.info, Node: Converting Complex Numbers, Next: String and Stream Input and Output, Prev: Assigning Complex Numbers, Up: Complex Functions
+
+5.3 Conversion Functions
+========================
+
+The following functions are available only if '<complex.h>' is included
+_before_ 'mpc.h'.
+
+ -- Function: double _Complex mpc_get_dc (mpc_t OP, mpc_rnd_t RND)
+ -- Function: long double _Complex mpc_get_ldc (mpc_t OP, mpc_rnd_t RND)
+ Convert OP to a C complex number, using the rounding mode RND.
+
+ For functions converting complex variables to strings or stream
+output, *note String and Stream Input and Output::.
+
+
+File: mpc.info, Node: String and Stream Input and Output, Next: Complex Comparison, Prev: Converting Complex Numbers, Up: Complex Functions
+
+5.4 String and Stream Input and Output
+======================================
+
+ -- Function: int mpc_strtoc (mpc_t ROP, const char *NPTR, char
+ **ENDPTR, int BASE, mpc_rnd_t RND)
+ Read a complex number from a string NPTR in base BASE, rounded to
+ the precision of ROP with the given rounding mode RND. The BASE
+ must be either 0 or a number from 2 to 36 (otherwise the behaviour
+ is undefined). If NPTR starts with valid data, the result is
+ stored in ROP, the usual inexact value is returned (*note Return
+ Value: return-value.) and, if ENDPTR is not the null pointer,
+ *ENDPTR points to the character just after the valid data.
+ Otherwise, ROP is set to 'NaN + i * NaN', -1 is returned and, if
+ ENDPTR is not the null pointer, the value of NPTR is stored in the
+ location referenced by ENDPTR.
+
+ The expected form of a complex number string is either a real
+ number (an optional leading whitespace, an optional sign followed
+ by a floating-point number), or a pair of real numbers in
+ parentheses separated by whitespace. If a real number is read, the
+ missing imaginary part is set to +0. The form of a floating-point
+ number depends on the base and is described in the documentation of
+ 'mpfr_strtofr' (*note (mpfr.info)Assignment Functions::). For
+ instance, '"3.1415926"', '"(1.25e+7 +.17)"', '"(@nan@ 2)"' and
+ '"(-0 -7)"' are valid strings for BASE = 10. If BASE = 0, then a
+ prefix may be used to indicate the base in which the floating-point
+ number is written. Use prefix '0b' for binary numbers, prefix '0x'
+ for hexadecimal numbers, and no prefix for decimal numbers. The
+ real and imaginary part may then be written in different bases.
+ For instance, '"(1.024e+3 +2.05e+3)"' and '"(0b1p+10 +0x802)"' are
+ valid strings for 'base'=0 and represent the same value.
+
+ -- Function: int mpc_set_str (mpc_t ROP, const char *S, int BASE,
+ mpc_rnd_t rnd)
+ Set ROP to the value of the string S in base BASE, rounded to the
+ precision of ROP with the given rounding mode RND. See the
+ documentation of 'mpc_strtoc' for a detailed description of the
+ valid string formats. Contrarily to 'mpc_strtoc', 'mpc_set_str'
+ requires the _whole_ string to represent a valid complex number
+ (potentially followed by additional white space). This function
+ returns the usual inexact value (*note Return Value: return-value.)
+ if the entire string up to the final null character is a valid
+ number in base BASE; otherwise it returns -1, and ROP is set to
+ NaN+i*NaN.
+
+ -- Function: char * mpc_get_str (int B, size_t N, mpc_t OP, mpc_rnd_t
+ RND)
+ Convert OP to a string containing its real and imaginary parts,
+ separated by a space and enclosed in a pair of parentheses. The
+ numbers are written in base B (which may vary from 2 to 36) and
+ rounded according to RND. The number of significant digits, at
+ least 2, is given by N. It is also possible to let N be zero, in
+ which case the number of digits is chosen large enough so that
+ re-reading the printed value with the same precision, assuming both
+ output and input use rounding to nearest, will recover the original
+ value of OP. Note that 'mpc_get_str' uses the decimal point of the
+ current locale if available, and '.' otherwise.
+
+ The string is generated using the current memory allocation
+ function ('malloc' by default, unless it has been modified using
+ the custom memory allocation interface of 'gmp'); once it is not
+ needed any more, it should be freed by calling 'mpc_free_str'.
+
+ -- Function: void mpc_free_str (char *STR)
+ Free the string STR, which needs to have been allocated by a call
+ to 'mpc_get_str'.
+
+ The following two functions read numbers from input streams and write
+them to output streams. When using any of these functions, you need to
+include 'stdio.h' _before_ 'mpc.h'.
+
+ -- Function: int mpc_inp_str (mpc_t ROP, FILE *STREAM, size_t *READ,
+ int BASE, mpc_rnd_t RND)
+ Input a string in base BASE in the same format as for 'mpc_strtoc'
+ from stdio stream STREAM, rounded according to RND, and put the
+ read complex number into ROP. If STREAM is the null pointer, ROP
+ is read from 'stdin'. Return the usual inexact value; if an error
+ occurs, set ROP to 'NaN + i * NaN' and return -1. If READ is not
+ the null pointer, it is set to the number of read characters.
+
+ Unlike 'mpc_strtoc', the function 'mpc_inp_str' does not possess
+ perfect knowledge of the string to transform and has to read it
+ character by character, so it behaves slightly differently: It
+ tries to read a string describing a complex number and processes
+ this string through a call to 'mpc_set_str'. Precisely, after
+ skipping optional whitespace, a minimal string is read according to
+ the regular expression 'mpfr | '(' \s* mpfr \s+ mpfr \s* ')'',
+ where '\s' denotes a whitespace, and 'mpfr' is either a string
+ containing neither whitespaces nor parentheses, or
+ 'nan(n-char-sequence)' or '@nan@(n-char-sequence)' (regardless of
+ capitalisation) with 'n-char-sequence' a string of ascii letters,
+ digits or ''_''.
+
+ For instance, upon input of '"nan(13 1)"', the function
+ 'mpc_inp_str' starts to recognise a value of NaN followed by an
+ n-char-sequence indicated by the opening parenthesis; as soon as
+ the space is reached, it becocmes clear that the expression in
+ parentheses is not an n-char-sequence, and the error flag -1 is
+ returned after 6 characters have been consumed from the stream (the
+ whitespace itself remaining in the stream). The function
+ 'mpc_strtoc', on the other hand, may track back when reaching the
+ whitespace; it treats the string as the two successive complex
+ numbers 'NaN + i * 0' and '13 + i'. It is thus recommended to have
+ a whitespace follow each floating point number to avoid this
+ problem.
+
+ -- Function: size_t mpc_out_str (FILE *STREAM, int BASE, size_t
+ N_DIGITS, mpc_t OP, mpc_rnd_t RND)
+ Output OP on stdio stream STREAM in base BASE, rounded according to
+ RND, in the same format as for 'mpc_strtoc' If STREAM is the null
+ pointer, ROP is written to 'stdout'.
+
+ Return the number of characters written.
+
+
+File: mpc.info, Node: Complex Comparison, Next: Projection & Decomposing, Prev: String and Stream Input and Output, Up: Complex Functions
+
+5.5 Comparison Functions
+========================
+
+ -- Function: int mpc_cmp (mpc_t OP1, mpc_t OP2)
+ -- Function: int mpc_cmp_si_si (mpc_t OP1, long int OP2R, long int
+ OP2I)
+ -- Macro: int mpc_cmp_si (mpc_t OP1, long int OP2)
+
+ Compare OP1 and OP2, where in the case of 'mpc_cmp_si_si', OP2 is
+ taken to be OP2R + i OP2I. The return value C can be decomposed
+ into 'x = MPC_INEX_RE(c)' and 'y = MPC_INEX_IM(c)', such that X is
+ positive if the real part of OP1 is greater than that of OP2, zero
+ if both real parts are equal, and negative if the real part of OP1
+ is less than that of OP2, and likewise for Y. Both OP1 and OP2 are
+ considered to their full own precision, which may differ. It is
+ not allowed that one of the operands has a NaN (Not-a-Number) part.
+
+ The storage of the return value is such that equality can be simply
+ checked with 'mpc_cmp (op1, op2) == 0'.
+
+
+File: mpc.info, Node: Projection & Decomposing, Next: Basic Arithmetic, Prev: Complex Comparison, Up: Complex Functions
+
+5.6 Projection and Decomposing Functions
+========================================
+
+ -- Function: int mpc_real (mpfr_t ROP, mpc_t OP, mpfr_rnd_t RND)
+ Set ROP to the value of the real part of OP rounded in the
+ direction RND.
+
+ -- Function: int mpc_imag (mpfr_t ROP, mpc_t OP, mpfr_rnd_t RND)
+ Set ROP to the value of the imaginary part of OP rounded in the
+ direction RND.
+
+ -- Macro: mpfr_t mpc_realref (mpc_t OP)
+ -- Macro: mpfr_t mpc_imagref (mpc_t OP)
+ Return a reference to the real part and imaginary part of OP,
+ respectively. The 'mpfr' functions can be used on the result of
+ these macros (note that the 'mpfr_t' type is itself a pointer).
+
+ -- Function: int mpc_arg (mpfr_t ROP, mpc_t OP, mpfr_rnd_t RND)
+ Set ROP to the argument of OP, with a branch cut along the negative
+ real axis.
+
+ -- Function: int mpc_proj (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Compute a projection of OP onto the Riemann sphere. Set ROP to OP
+ rounded in the direction RND, except when at least one part of OP
+ is infinite (even if the other part is a NaN) in which case the
+ real part of ROP is set to plus infinity and its imaginary part to
+ a signed zero with the same sign as the imaginary part of OP.
+
+
+File: mpc.info, Node: Basic Arithmetic, Next: Power Functions and Logarithm, Prev: Projection & Decomposing, Up: Complex Functions
+
+5.7 Basic Arithmetic Functions
+==============================
+
+All the following functions are designed in such a way that, when
+working with real numbers instead of complex numbers, their complexity
+should essentially be the same as with the GNU MPFR library, with only a
+marginal overhead due to the GNU MPC layer.
+
+ -- Function: int mpc_add (mpc_t ROP, mpc_t OP1, mpc_t OP2, mpc_rnd_t
+ RND)
+ -- Function: int mpc_add_ui (mpc_t ROP, mpc_t OP1, unsigned long int
+ OP2, mpc_rnd_t RND)
+ -- Function: int mpc_add_fr (mpc_t ROP, mpc_t OP1, mpfr_t OP2,
+ mpc_rnd_t RND)
+ Set ROP to OP1 + OP2 rounded according to RND.
+
+ -- Function: int mpc_sub (mpc_t ROP, mpc_t OP1, mpc_t OP2, mpc_rnd_t
+ RND)
+ -- Function: int mpc_sub_fr (mpc_t ROP, mpc_t OP1, mpfr_t OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_fr_sub (mpc_t ROP, mpfr_t OP1, mpc_t OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_sub_ui (mpc_t ROP, mpc_t OP1, unsigned long int
+ OP2, mpc_rnd_t RND)
+ -- Macro: int mpc_ui_sub (mpc_t ROP, unsigned long int OP1, mpc_t OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_ui_ui_sub (mpc_t ROP, unsigned long int RE1,
+ unsigned long int IM1, mpc_t OP2, mpc_rnd_t RND)
+ Set ROP to OP1 - OP2 rounded according to RND. For
+ 'mpc_ui_ui_sub', OP1 is RE1 + IM1.
+
+ -- Function: int mpc_neg (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to -OP rounded according to RND. Just changes the sign if
+ ROP and OP are the same variable.
+
+ -- Function: int mpc_mul (mpc_t ROP, mpc_t OP1, mpc_t OP2, mpc_rnd_t
+ RND)
+ -- Function: int mpc_mul_ui (mpc_t ROP, mpc_t OP1, unsigned long int
+ OP2, mpc_rnd_t RND)
+ -- Function: int mpc_mul_si (mpc_t ROP, mpc_t OP1, long int OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_mul_fr (mpc_t ROP, mpc_t OP1, mpfr_t OP2,
+ mpc_rnd_t RND)
+ Set ROP to OP1 times OP2 rounded according to RND. Note: for
+ 'mpc_mul', in case OP1 and OP2 have the same value, use 'mpc_sqr'
+ for better efficiency.
+
+ -- Function: int mpc_mul_i (mpc_t ROP, mpc_t OP, int SGN, mpc_rnd_t
+ RND)
+ Set ROP to OP times the imaginary unit i if SGN is non-negative,
+ set ROP to OP times -i otherwise, in both cases rounded according
+ to RND.
+
+ -- Function: int mpc_sqr (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the square of OP rounded according to RND.
+
+ -- Function: int mpc_fma (mpc_t ROP, mpc_t OP1, mpc_t OP2, mpc_t OP3,
+ mpc_rnd_t RND)
+ Set ROP to OP1*OP2+OP3, rounded according to RND, with only one
+ final rounding.
+
+ -- Function: int mpc_div (mpc_t ROP, mpc_t OP1, mpc_t OP2, mpc_rnd_t
+ RND)
+ -- Function: int mpc_div_ui (mpc_t ROP, mpc_t OP1, unsigned long int
+ OP2, mpc_rnd_t RND)
+ -- Function: int mpc_div_fr (mpc_t ROP, mpc_t OP1, mpfr_t OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_ui_div (mpc_t ROP, unsigned long int OP1, mpc_t
+ OP2, mpc_rnd_t RND)
+ -- Function: int mpc_fr_div (mpc_t ROP, mpfr_t OP1, mpc_t OP2,
+ mpc_rnd_t RND)
+ Set ROP to OP1/OP2 rounded according to RND.
+
+ -- Function: int mpc_conj (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the conjugate of OP rounded according to RND. Just
+ changes the sign of the imaginary part if ROP and OP are the same
+ variable.
+
+ -- Function: int mpc_abs (mpfr_t ROP, mpc_t OP, mpfr_rnd_t RND)
+ Set the floating-point number ROP to the absolute value of OP,
+ rounded in the direction RND.
+
+ -- Function: int mpc_norm (mpfr_t ROP, mpc_t OP, mpfr_rnd_t RND)
+ Set the floating-point number ROP to the norm of OP (i.e., the
+ square of its absolute value), rounded in the direction RND.
+
+ -- Function: int mpc_mul_2ui (mpc_t ROP, mpc_t OP1, unsigned long int
+ OP2, mpc_rnd_t RND)
+ -- Function: int mpc_mul_2si (mpc_t ROP, mpc_t OP1, long int OP2,
+ mpc_rnd_t RND)
+ Set ROP to OP1 times 2 raised to OP2 rounded according to RND.
+ Just modifies the exponents of the real and imaginary parts by OP2
+ when ROP and OP1 are identical.
+
+ -- Function: int mpc_div_2ui (mpc_t ROP, mpc_t OP1, unsigned long int
+ OP2, mpc_rnd_t RND)
+ -- Function: int mpc_div_2si (mpc_t ROP, mpc_t OP1, long int OP2,
+ mpc_rnd_t RND)
+ Set ROP to OP1 divided by 2 raised to OP2 rounded according to RND.
+ Just modifies the exponents of the real and imaginary parts by OP2
+ when ROP and OP1 are identical.
+
+
+File: mpc.info, Node: Power Functions and Logarithm, Next: Trigonometric Functions, Prev: Basic Arithmetic, Up: Complex Functions
+
+5.8 Power Functions and Logarithm
+=================================
+
+ -- Function: int mpc_sqrt (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the square root of OP rounded according to RND. The
+ returned value ROP has a non-negative real part, and if its real
+ part is zero, a non-negative imaginary part.
+
+ -- Function: int mpc_pow (mpc_t ROP, mpc_t OP1, mpc_t OP2, mpc_rnd_t
+ RND)
+ -- Function: int mpc_pow_d (mpc_t ROP, mpc_t OP1, double OP2, mpc_rnd_t
+ RND)
+ -- Function: int mpc_pow_ld (mpc_t ROP, mpc_t OP1, long double OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_pow_si (mpc_t ROP, mpc_t OP1, long OP2, mpc_rnd_t
+ RND)
+ -- Function: int mpc_pow_ui (mpc_t ROP, mpc_t OP1, unsigned long OP2,
+ mpc_rnd_t RND)
+ -- Function: int mpc_pow_z (mpc_t ROP, mpc_t OP1, mpz_t OP2, mpc_rnd_t
+ RND)
+ -- Function: int mpc_pow_fr (mpc_t ROP, mpc_t OP1, mpfr_t OP2,
+ mpc_rnd_t RND)
+ Set ROP to OP1 raised to the power OP2, rounded according to RND.
+ For 'mpc_pow_d', 'mpc_pow_ld', 'mpc_pow_si', 'mpc_pow_ui',
+ 'mpc_pow_z' and 'mpc_pow_fr', the imaginary part of OP2 is
+ considered as +0. When both OP1 and OP2 are zero, the result has
+ real part 1, and imaginary part 0, with sign being the opposite of
+ that of OP2.
+
+ -- Function: int mpc_exp (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the exponential of OP, rounded according to RND with the
+ precision of ROP.
+
+ -- Function: int mpc_log (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ -- Function: int mpc_log10 (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the natural and base-10 logarithm of OP respectively,
+ rounded according to RND with the precision of ROP. The principal
+ branch is chosen, with the branch cut on the negative real axis, so
+ that the imaginary part of the result lies in ]-\pi , \pi] and
+ ]-\pi/log(10) , \pi/log(10)] respectively.
+
+
+File: mpc.info, Node: Trigonometric Functions, Next: Miscellaneous Complex Functions, Prev: Power Functions and Logarithm, Up: Complex Functions
+
+5.9 Trigonometric Functions
+===========================
+
+ -- Function: int mpc_sin (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the sine of OP, rounded according to RND with the
+ precision of ROP.
+
+ -- Function: int mpc_cos (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the cosine of OP, rounded according to RND with the
+ precision of ROP.
+
+ -- Function: int mpc_sin_cos (mpc_t ROP_SIN, mpc_t ROP_COS, mpc_t OP,
+ mpc_rnd_t RND_SIN, mpc_rnd_t RND_COS)
+ Set ROP_SIN to the sine of OP, rounded according to RND_SIN with
+ the precision of ROP_SIN, and ROP_COS to the cosine of OP, rounded
+ according to RND_COS with the precision of ROP_COS.
+
+ -- Function: int mpc_tan (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the tangent of OP, rounded according to RND with the
+ precision of ROP.
+
+ -- Function: int mpc_sinh (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the hyperbolic sine of OP, rounded according to RND with
+ the precision of ROP.
+
+ -- Function: int mpc_cosh (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the hyperbolic cosine of OP, rounded according to RND
+ with the precision of ROP.
+
+ -- Function: int mpc_tanh (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the hyperbolic tangent of OP, rounded according to RND
+ with the precision of ROP.
+
+ -- Function: int mpc_asin (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ -- Function: int mpc_acos (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ -- Function: int mpc_atan (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the inverse sine, inverse cosine, inverse tangent of OP,
+ rounded according to RND with the precision of ROP.
+
+ -- Function: int mpc_asinh (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ -- Function: int mpc_acosh (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ -- Function: int mpc_atanh (mpc_t ROP, mpc_t OP, mpc_rnd_t RND)
+ Set ROP to the inverse hyperbolic sine, inverse hyperbolic cosine,
+ inverse hyperbolic tangent of OP, rounded according to RND with the
+ precision of ROP. The branch cut of MPC_ACOSH is (-\infty, 1).
+
+
+File: mpc.info, Node: Miscellaneous Complex Functions, Next: Advanced Functions, Prev: Trigonometric Functions, Up: Complex Functions
+
+5.10 Miscellaneous Functions
+============================
+
+ -- Function: int mpc_urandom (mpc_t ROP, gmp_randstate_t STATE)
+ Generate a uniformly distributed random complex in the unit square
+ [0, 1] x [0, 1]. Return 0, unless an exponent in the real or
+ imaginary part is not in the current exponent range, in which case
+ that part is set to NaN and a zero value is returned. The second
+ argument is a 'gmp_randstate_t' structure which should be created
+ using the GMP 'rand_init' function, see the GMP manual.
+
+ -- Function: const char * mpc_get_version (void)
+ Return the GNU MPC version, as a null-terminated string.
+
+ -- Macro: MPC_VERSION
+ -- Macro: MPC_VERSION_MAJOR
+ -- Macro: MPC_VERSION_MINOR
+ -- Macro: MPC_VERSION_PATCHLEVEL
+ -- Macro: MPC_VERSION_STRING
+ 'MPC_VERSION' is the version of GNU MPC as a preprocessing
+ constant. 'MPC_VERSION_MAJOR', 'MPC_VERSION_MINOR' and
+ 'MPC_VERSION_PATCHLEVEL' are respectively the major, minor and
+ patch level of GNU MPC version, as preprocessing constants.
+ 'MPC_VERSION_STRING' is the version as a string constant, which can
+ be compared to the result of 'mpc_get_version' to check at run time
+ the header file and library used match:
+ if (strcmp (mpc_get_version (), MPC_VERSION_STRING))
+ fprintf (stderr, "Warning: header and library do not match\n");
+ Note: Obtaining different strings is not necessarily an error, as
+ in general, a program compiled with some old GNU MPC version can be
+ dynamically linked with a newer GNU MPC library version (if allowed
+ by the library versioning system).
+
+ -- Macro: long MPC_VERSION_NUM (MAJOR, MINOR, PATCHLEVEL)
+ Create an integer in the same format as used by 'MPC_VERSION' from
+ the given MAJOR, MINOR and PATCHLEVEL. Here is an example of how
+ to check the GNU MPC version at compile time:
+ #if (!defined(MPC_VERSION) || (MPC_VERSION<MPC_VERSION_NUM(2,1,0)))
+ # error "Wrong GNU MPC version."
+ #endif
+
+
+File: mpc.info, Node: Advanced Functions, Next: Internals, Prev: Miscellaneous Complex Functions, Up: Complex Functions
+
+5.11 Advanced Functions
+=======================
+
+ -- Macro: MPC_SET_X_Y (REAL_SUFFIX, IMAG_SUFFIX, ROP, REAL, IMAG, RND)
+ The macro MPC_SET_X_Y is designed to serve as the body of an
+ assignment function and cannot be used by itself. The REAL_SUFFIX
+ and IMAG_SUFFIX parameters are the types of the real and imaginary
+ part, that is, the 'x' in the 'mpfr_set_x' function one would use
+ to set the part; for the mpfr type, use 'fr'. REAL (respectively
+ IMAG) is the value you want to assign to the real (resp.
+ imaginary) part, its type must conform to REAL_SUFFIX (resp.
+ IMAG_SUFFIX). RND is the 'mpc_rnd_t' rounding mode. The return
+ value is the usual inexact value (*note Return Value:
+ return-value.).
+
+ For instance, you can define mpc_set_ui_fr as follows:
+ int mpc_set_ui_fr (mpc_t rop, long int re, double im, mpc_rnd_t rnd)
+ MPC_SET_X_Y (ui, fr, rop, re, im, rnd);
+
+
+File: mpc.info, Node: Internals, Prev: Advanced Functions, Up: Complex Functions
+
+5.12 Internals
+==============
+
+These macros and functions are mainly designed for the implementation of
+GNU MPC, but may be useful for users too. However, no upward
+compatibility is guaranteed. You need to include 'mpc-impl.h' to use
+them.
+
+ The macro 'MPC_MAX_PREC(z)' gives the maximum of the precisions of
+the real and imaginary parts of a complex number.
+
+
+File: mpc.info, Node: References, Next: Concept Index, Prev: Complex Functions, Up: Top
+
+References
+**********
+
+ * Torbjo"rn Granlund et al. 'gmp' - GNU multiprecision library.
+ Version 4.2.4, <http://gmplib.org/>.
+
+ * Guillaume Hanrot, Vincent Lefe`vre, Patrick Pe'lissier, Paul
+ Zimmermann et al. 'mpfr' - A library for multiple-precision
+ floating-point computations with exact rounding. Version 2.4.1,
+ <http://www.mpfr.org>.
+
+ * IEEE standard for binary floating-point arithmetic, Technical
+ Report ANSI-IEEE Standard 754-1985, New York, 1985. Approved March
+ 21, 1985: IEEE Standards Board; approved July 26, 1985: American
+ National Standards Institute, 18 pages.
+
+ * Donald E. Knuth, "The Art of Computer Programming", vol 2,
+ "Seminumerical Algorithms", 2nd edition, Addison-Wesley, 1981.
+
+ * ISO/IEC 9899:1999, Programming languages — C.
+
+
+File: mpc.info, Node: Concept Index, Next: Function Index, Prev: References, Up: Top
+
+Concept Index
+*************
+
+
+* Menu:
+
+* Arithmetic functions: Basic Arithmetic. (line 6)
+* Comparison functions: Complex Comparison. (line 6)
+* Complex arithmetic functions: Basic Arithmetic. (line 6)
+* Complex assignment functions: Assigning Complex Numbers.
+ (line 6)
+* Complex comparisons functions: Complex Comparison. (line 6)
+* Complex functions: Complex Functions. (line 6)
+* Complex number: GNU MPC Basics. (line 15)
+* Conditions for copying GNU MPC: Copying. (line 6)
+* Conversion functions: Converting Complex Numbers.
+ (line 6)
+* Copying conditions: Copying. (line 6)
+* Installation: Installing GNU MPC. (line 6)
+* Logarithm: Power Functions and Logarithm.
+ (line 6)
+* Miscellaneous complex functions: Miscellaneous Complex Functions.
+ (line 6)
+* 'mpc.h': GNU MPC Basics. (line 6)
+* Power functions: Power Functions and Logarithm.
+ (line 6)
+* Precision: GNU MPC Basics. (line 19)
+* Projection and Decomposing Functions: Projection & Decomposing.
+ (line 6)
+* Reporting bugs: Reporting Bugs. (line 6)
+* Rounding Mode: GNU MPC Basics. (line 24)
+* String and stream input and output: String and Stream Input and Output.
+ (line 6)
+* Trigonometric functions: Trigonometric Functions.
+ (line 6)
+* User-defined precision: Complex Functions. (line 12)
+
+
+File: mpc.info, Node: Function Index, Next: GNU Free Documentation License, Prev: Concept Index, Up: Top
+
+Function Index
+**************
+
+
+* Menu:
+
+* _Complex: Converting Complex Numbers.
+ (line 9)
+* mpc_abs: Basic Arithmetic. (line 81)
+* mpc_acos: Trigonometric Functions.
+ (line 37)
+* mpc_acosh: Trigonometric Functions.
+ (line 43)
+* mpc_add: Basic Arithmetic. (line 11)
+* mpc_add_fr: Basic Arithmetic. (line 15)
+* mpc_add_ui: Basic Arithmetic. (line 13)
+* mpc_arg: Projection & Decomposing.
+ (line 20)
+* mpc_asin: Trigonometric Functions.
+ (line 36)
+* mpc_asinh: Trigonometric Functions.
+ (line 42)
+* mpc_atan: Trigonometric Functions.
+ (line 38)
+* mpc_atanh: Trigonometric Functions.
+ (line 44)
+* mpc_clear: Initializing Complex Numbers.
+ (line 21)
+* mpc_cmp: Complex Comparison. (line 6)
+* mpc_cmp_si: Complex Comparison. (line 9)
+* mpc_cmp_si_si: Complex Comparison. (line 7)
+* mpc_conj: Basic Arithmetic. (line 76)
+* mpc_cos: Trigonometric Functions.
+ (line 10)
+* mpc_cosh: Trigonometric Functions.
+ (line 28)
+* mpc_div: Basic Arithmetic. (line 64)
+* mpc_div_2si: Basic Arithmetic. (line 99)
+* mpc_div_2ui: Basic Arithmetic. (line 97)
+* mpc_div_fr: Basic Arithmetic. (line 68)
+* mpc_div_ui: Basic Arithmetic. (line 66)
+* mpc_exp: Power Functions and Logarithm.
+ (line 32)
+* mpc_fma: Basic Arithmetic. (line 59)
+* mpc_free_str: String and Stream Input and Output.
+ (line 66)
+* mpc_fr_div: Basic Arithmetic. (line 72)
+* mpc_fr_sub: Basic Arithmetic. (line 23)
+* mpc_get_ldc: Converting Complex Numbers.
+ (line 10)
+* mpc_get_prec: Initializing Complex Numbers.
+ (line 49)
+* mpc_get_prec2: Initializing Complex Numbers.
+ (line 53)
+* mpc_get_str: String and Stream Input and Output.
+ (line 48)
+* mpc_get_version: Miscellaneous Complex Functions.
+ (line 14)
+* mpc_imag: Projection & Decomposing.
+ (line 10)
+* mpc_imagref: Projection & Decomposing.
+ (line 15)
+* mpc_init2: Initializing Complex Numbers.
+ (line 10)
+* mpc_init3: Initializing Complex Numbers.
+ (line 15)
+* mpc_inp_str: String and Stream Input and Output.
+ (line 74)
+* mpc_log: Power Functions and Logarithm.
+ (line 36)
+* mpc_log10: Power Functions and Logarithm.
+ (line 37)
+* mpc_mul: Basic Arithmetic. (line 38)
+* mpc_mul_2si: Basic Arithmetic. (line 91)
+* mpc_mul_2ui: Basic Arithmetic. (line 89)
+* mpc_mul_fr: Basic Arithmetic. (line 44)
+* mpc_mul_i: Basic Arithmetic. (line 50)
+* mpc_mul_si: Basic Arithmetic. (line 42)
+* mpc_mul_ui: Basic Arithmetic. (line 40)
+* mpc_neg: Basic Arithmetic. (line 34)
+* mpc_norm: Basic Arithmetic. (line 85)
+* mpc_out_str: String and Stream Input and Output.
+ (line 109)
+* mpc_pow: Power Functions and Logarithm.
+ (line 11)
+* mpc_pow_d: Power Functions and Logarithm.
+ (line 13)
+* mpc_pow_fr: Power Functions and Logarithm.
+ (line 23)
+* mpc_pow_ld: Power Functions and Logarithm.
+ (line 15)
+* mpc_pow_si: Power Functions and Logarithm.
+ (line 17)
+* mpc_pow_ui: Power Functions and Logarithm.
+ (line 19)
+* mpc_pow_z: Power Functions and Logarithm.
+ (line 21)
+* mpc_proj: Projection & Decomposing.
+ (line 24)
+* mpc_real: Projection & Decomposing.
+ (line 6)
+* mpc_realref: Projection & Decomposing.
+ (line 14)
+* 'mpc_rnd_t': GNU MPC Basics. (line 24)
+* mpc_set: Assigning Complex Numbers.
+ (line 16)
+* mpc_set_d: Assigning Complex Numbers.
+ (line 25)
+* mpc_set_dc: Assigning Complex Numbers.
+ (line 27)
+* mpc_set_d_d: Assigning Complex Numbers.
+ (line 54)
+* mpc_set_f: Assigning Complex Numbers.
+ (line 33)
+* mpc_set_fr: Assigning Complex Numbers.
+ (line 34)
+* mpc_set_fr_fr: Assigning Complex Numbers.
+ (line 64)
+* mpc_set_f_f: Assigning Complex Numbers.
+ (line 62)
+* mpc_set_ld: Assigning Complex Numbers.
+ (line 26)
+* mpc_set_ldc: Assigning Complex Numbers.
+ (line 29)
+* mpc_set_ld_ld: Assigning Complex Numbers.
+ (line 56)
+* mpc_set_nan: Assigning Complex Numbers.
+ (line 79)
+* mpc_set_prec: Initializing Complex Numbers.
+ (line 41)
+* mpc_set_q: Assigning Complex Numbers.
+ (line 32)
+* mpc_set_q_q: Assigning Complex Numbers.
+ (line 60)
+* mpc_set_si: Assigning Complex Numbers.
+ (line 22)
+* mpc_set_si_si: Assigning Complex Numbers.
+ (line 48)
+* mpc_set_sj: Assigning Complex Numbers.
+ (line 24)
+* mpc_set_sj_sj: Assigning Complex Numbers.
+ (line 52)
+* mpc_set_str: String and Stream Input and Output.
+ (line 35)
+* mpc_set_ui: Assigning Complex Numbers.
+ (line 20)
+* mpc_set_ui_ui: Assigning Complex Numbers.
+ (line 46)
+* mpc_set_uj: Assigning Complex Numbers.
+ (line 23)
+* mpc_set_uj_uj: Assigning Complex Numbers.
+ (line 50)
+* MPC_SET_X_Y: Advanced Functions. (line 6)
+* mpc_set_z: Assigning Complex Numbers.
+ (line 31)
+* mpc_set_z_z: Assigning Complex Numbers.
+ (line 58)
+* mpc_sin: Trigonometric Functions.
+ (line 6)
+* mpc_sinh: Trigonometric Functions.
+ (line 24)
+* mpc_sin_cos: Trigonometric Functions.
+ (line 14)
+* mpc_sqr: Basic Arithmetic. (line 56)
+* mpc_sqrt: Power Functions and Logarithm.
+ (line 6)
+* mpc_strtoc: String and Stream Input and Output.
+ (line 6)
+* mpc_sub: Basic Arithmetic. (line 19)
+* mpc_sub_fr: Basic Arithmetic. (line 21)
+* mpc_sub_ui: Basic Arithmetic. (line 25)
+* mpc_swap: Assigning Complex Numbers.
+ (line 82)
+* 'mpc_t': GNU MPC Basics. (line 15)
+* mpc_tan: Trigonometric Functions.
+ (line 20)
+* mpc_tanh: Trigonometric Functions.
+ (line 32)
+* mpc_ui_div: Basic Arithmetic. (line 70)
+* mpc_ui_sub: Basic Arithmetic. (line 27)
+* mpc_ui_ui_sub: Basic Arithmetic. (line 29)
+* mpc_urandom: Miscellaneous Complex Functions.
+ (line 6)
+* MPC_VERSION: Miscellaneous Complex Functions.
+ (line 17)
+* MPC_VERSION_MAJOR: Miscellaneous Complex Functions.
+ (line 18)
+* MPC_VERSION_MINOR: Miscellaneous Complex Functions.
+ (line 19)
+* MPC_VERSION_NUM: Miscellaneous Complex Functions.
+ (line 36)
+* MPC_VERSION_PATCHLEVEL: Miscellaneous Complex Functions.
+ (line 20)
+* MPC_VERSION_STRING: Miscellaneous Complex Functions.
+ (line 21)
+* 'mpfr_prec_t': GNU MPC Basics. (line 19)
+
+
+File: mpc.info, Node: GNU Free Documentation License, Prev: Function Index, Up: Top
+
+Appendix A GNU Free Documentation License
+*****************************************
+
+ Version 1.3, 3 November 2008
+
+ Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+ <http://fsf.org/>
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book. We
+ recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it can
+ be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You accept
+ the license if you copy, modify or distribute the work in a way
+ requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in the
+ notice that says that the Document is released under this License.
+ If a section does not fit the above definition of Secondary then it
+ is not allowed to be designated as Invariant. The Document may
+ contain zero Invariant Sections. If the Document does not identify
+ any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images composed
+ of pixels) generic paint programs or (for drawings) some widely
+ available drawing editor, and that is suitable for input to text
+ formatters or for automatic translation to a variety of formats
+ suitable for input to text formatters. A copy made in an otherwise
+ Transparent file format whose markup, or absence of markup, has
+ been arranged to thwart or discourage subsequent modification by
+ readers is not Transparent. An image format is not Transparent if
+ used for any substantial amount of text. A copy that is not
+ "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and standard-conforming
+ simple HTML, PostScript or PDF designed for human modification.
+ Examples of transparent image formats include PNG, XCF and JPG.
+ Opaque formats include proprietary formats that can be read and
+ edited only by proprietary word processors, SGML or XML for which
+ the DTD and/or processing tools are not generally available, and
+ the machine-generated HTML, PostScript or PDF produced by some word
+ processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ The "publisher" means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow the
+ conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the title
+ equally prominent and visible. You may add other material on the
+ covers in addition. Copying with changes limited to the covers, as
+ long as they preserve the title of the Document and satisfy these
+ conditions, can be treated as verbatim copying in other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a machine-readable
+ Transparent copy along with each Opaque copy, or state in or with
+ each Opaque copy a computer-network location from which the general
+ network-using public has access to download using public-standard
+ network protocols a complete Transparent copy of the Document, free
+ of added material. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque
+ copies in quantity, to ensure that this Transparent copy will
+ remain thus accessible at the stated location until at least one
+ year after the last time you distribute an Opaque copy (directly or
+ through your agents or retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of copies,
+ to give them a chance to provide you with an updated version of the
+ Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with the
+ Modified Version filling the role of the Document, thus licensing
+ distribution and modification of the Modified Version to whoever
+ possesses a copy of it. In addition, you must do these things in
+ the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of previous
+ versions (which should, if there were any, be listed in the
+ History section of the Document). You may use the same title
+ as a previous version if the original publisher of that
+ version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on the
+ Title Page. If there is no section Entitled "History" in the
+ Document, create one stating the title, year, authors, and
+ publisher of the Document as given on its Title Page, then add
+ an item describing the Modified Version as stated in the
+ previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in the
+ "History" section. You may omit a network location for a work
+ that was published at least four years before the Document
+ itself, or if the original publisher of the version it refers
+ to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the section
+ all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document, unaltered
+ in their text and in their titles. Section numbers or the
+ equivalent are not considered part of the section titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option designate
+ some or all of these sections as invariant. To do this, add their
+ titles to the list of Invariant Sections in the Modified Version's
+ license notice. These titles must be distinct from any other
+ section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end of
+ the list of Cover Texts in the Modified Version. Only one passage
+ of Front-Cover Text and one of Back-Cover Text may be added by (or
+ through arrangements made by) any one entity. If the Document
+ already includes a cover text for the same cover, previously added
+ by you or by arrangement made by the same entity you are acting on
+ behalf of, you may not add another; but you may replace the old
+ one, on explicit permission from the previous publisher that added
+ the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination all
+ of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the documents
+ in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow this
+ License in all other respects regarding verbatim copying of that
+ document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of a
+ storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from you
+ under this License. If your rights have been terminated and not
+ permanently reinstated, receipt of a copy of some or all of the
+ same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ <http://www.gnu.org/copyleft/>.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If the
+ Document does not specify a version number of this License, you may
+ choose any version ever published (not as a draft) by the Free
+ Software Foundation. If the Document specifies that a proxy can
+ decide which future versions of this License can be used, that
+ proxy's public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ "Incorporate" means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is "eligible for relicensing" if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+
+
+
+Tag Table:
+Node: Top735
+Node: Copying1442
+Node: Introduction to GNU MPC2214
+Node: Installing GNU MPC2933
+Node: Reporting Bugs8018
+Node: GNU MPC Basics9362
+Ref: return-value13039
+Node: Complex Functions14490
+Node: Initializing Complex Numbers15650
+Node: Assigning Complex Numbers18037
+Node: Converting Complex Numbers22437
+Node: String and Stream Input and Output23062
+Node: Complex Comparison29619
+Node: Projection & Decomposing30694
+Node: Basic Arithmetic32071
+Node: Power Functions and Logarithm36644
+Node: Trigonometric Functions38711
+Node: Miscellaneous Complex Functions40936
+Node: Advanced Functions43112
+Node: Internals44185
+Node: References44636
+Node: Concept Index45539
+Node: Function Index47853
+Node: GNU Free Documentation License61637
+
+End Tag Table
diff --git a/mpc/doc/mpc.texi b/mpc/doc/mpc.texi
new file mode 100644
index 0000000000..8b37ba2e1a
--- /dev/null
+++ b/mpc/doc/mpc.texi
@@ -0,0 +1,1165 @@
+\input texinfo
+@setfilename mpc.info
+@include version.texi
+@settitle GNU MPC @value{VERSION}
+@synindex tp fn
+
+@set MINGMP 4.3.2
+@set MINMPFR 2.4.2
+
+@set AUTHORS Andreas Enge, Philippe Th@'eveny, Paul Zimmermann
+
+@copying
+This manual is for GNU MPC, a library for multiple precision complex arithmetic,
+version @value{VERSION} of @value{UPDATED-MONTH}.
+
+Copyright @copyright{} 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 INRIA
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections. A copy of the license is included in the section
+entitled ``GNU Free Documentation License.''
+@end quotation
+@end copying
+
+@iftex
+@afourpaper
+@end iftex
+@tex
+\global\parindent=0pt
+\global\parskip=8pt
+\global\baselineskip=13pt
+@end tex
+
+@dircategory GNU Packages
+@direntry
+* mpc: (mpc)Multiple Precision Complex Library.
+@end direntry
+
+
+@titlepage
+@title GNU MPC
+@subtitle The GNU Multiple Precision Complex Library
+@subtitle Edition @value{VERSION}
+@subtitle @value{UPDATED-MONTH}
+@author @value{AUTHORS}
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+
+@ifnottex
+@node Top
+@top GNU MPC
+
+This manual documents how to install and use the GNU Multiple Precision
+Complex Library, version @value{VERSION}
+@end ifnottex
+
+@menu
+* Copying:: GNU MPC Copying Conditions (LGPL).
+* Introduction to GNU MPC:: Brief introduction to GNU MPC.
+* Installing GNU MPC:: How to configure and compile the GNU MPC library.
+* Reporting Bugs:: How to usefully report bugs.
+* GNU MPC Basics:: What every GNU MPC user should know.
+* Complex Functions:: Functions for arithmetic on complex numbers.
+* References::
+* Concept Index::
+* Function Index::
+* GNU Free Documentation License::
+@end menu
+
+@c @times{} made available as a "x" in info and html (already works in tex).
+@ifnottex
+@macro times
+x
+@end macro
+@end ifnottex
+
+
+@node Copying
+@unnumbered GNU MPC Copying Conditions
+@cindex Copying conditions
+@cindex Conditions for copying GNU MPC
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see @uref{http://www.gnu.org/licenses/}.
+
+
+@node Introduction to GNU MPC
+@chapter Introduction to GNU MPC
+
+
+GNU MPC is a portable library written in C for arbitrary precision arithmetic
+on complex numbers providing correct rounding. It implements a multiprecision
+equivalent of the C99 standard.
+It builds upon the GNU MP and the GNU MPFR libraries.
+
+@section How to use this Manual
+
+Everyone should read @ref{GNU MPC Basics}. If you need to install the library
+yourself, you need to read @ref{Installing GNU MPC}, too.
+
+The remainder of the manual can be used for later reference, although it is
+probably a good idea to skim through it.
+
+@node Installing GNU MPC
+@chapter Installing GNU MPC
+@cindex Installation
+
+To build GNU MPC, you first have to install GNU MP (version @value{MINGMP} or higher) and
+GNU MPFR (version @value{MINMPFR} or higher) on your computer. You need a C compiler;
+GCC version 4.4 or higher is recommended, since GNU MPC may trigger a bug in previous
+versions, see the thread at
+@uref{http://lists.gforge.inria.fr/pipermail/mpc-discuss/2011-February/000823.html}.
+And you need a
+standard Unix @samp{make} program, plus some other standard Unix utility
+programs.
+
+Here are the steps needed to install the library on Unix systems:
+
+@enumerate
+@item
+@samp{tar xzf mpc-@value{VERSION}.tar.gz}
+
+@item
+@samp{cd mpc-@value{VERSION}}
+
+@item
+@samp{./configure}
+
+if GMP and GNU MPFR are installed into standard directories, that is, directories
+that are searched by default by the compiler and the linking tools.
+
+@samp{./configure --with-gmp=<gmp_install_dir>}
+
+is used to indicate a different location where GMP is
+installed. Alternatively, you can specify directly GMP include and GMP lib
+directories with @samp{./configure --with-gmp-lib=<gmp_lib_dir>
+--with-gmp-include=<gmp_include_dir>}.
+
+@samp{./configure --with-mpfr=<mpfr_install_dir>}
+
+is used to indicate a different location where GNU MPFR is
+installed. Alternatively, you can specify directly GNU MPFR include and GNU MPFR lib
+directories with @samp{./configure --with-mpf-lib=<mpfr_lib_dir>
+--with-mpfr-include=<mpfr_include_dir>}.
+
+Another useful parameter is @samp{--prefix}, which can be used to
+specify an alternative installation location instead of
+@file{/usr/local}; see @samp{make install} below.
+
+To enable checking for memory leaks using @command{valgrind} during
+@code{make check}, add the parameter @code{--enable-valgrind-tests}.
+
+If for debugging purposes you wish to log calls to GNU MPC functions from
+within your code, add the parameter @samp{--enable-logging}.
+In your code, replace the inclusion of @file{mpc.h} by @file{mpc-log.h}
+and link the executable dynamically.
+Then all calls to functions with only complex arguments are printed to
+@file{stderr} in the following form: First, the function name is given,
+followed by its type such as @samp{c_cc}, meaning that the function has
+one complex result (one @samp{c} in front of the @samp{_}), computed from
+two complex arguments (two @samp{c} after the @samp{_}). Then, the
+precisions of the real and the imaginary part of the first result is given,
+followed by the second one and so on. Finally, for each argument, the
+precisions of its real and imaginary part are specified and the argument
+itself is printed in hexadecimal via the function
+@code{mpc_out_str}
+(@pxref{String and Stream Input and Output}).
+The option requires a dynamic library, so it may not be combined with
+@code{--disable-shared}.
+
+Use @samp{./configure --help} for an exhaustive list of parameters.
+
+@item
+@samp{make}
+
+This compiles GNU MPC in the working directory.
+
+@item
+@samp{make check}
+
+This will make sure GNU MPC was built correctly.
+
+If you get error messages, please report them to
+@samp{mpc-discuss@@lists.gforge.inria.fr} (@xref{Reporting Bugs}, for
+information on what to include in useful bug reports).
+
+@item
+@samp{make install}
+
+This will copy the file @file{mpc.h} to the directory
+@file{/usr/local/include}, the file @file{libmpc.a} to the directory
+@file{/usr/local/lib}, and the file @file{mpc.info} to the directory
+@file{/usr/local/share/info} (or if you passed the @samp{--prefix} option to
+@file{configure}, using the prefix directory given as argument to
+@samp{--prefix} instead of @file{/usr/local}). Note: you need write permissions
+on these directories.
+
+@end enumerate
+
+
+@section Other `make' Targets
+
+There are some other useful make targets:
+
+@itemize @bullet
+@item
+@samp{info}
+
+Create an info version of the manual, in @file{mpc.info}.
+
+@item
+@samp{pdf}
+
+Create a PDF version of the manual, in @file{doc/mpc.pdf}.
+
+@item
+@samp{dvi}
+
+Create a DVI version of the manual, in @file{doc/mpc.dvi}.
+
+@item
+@samp{ps}
+
+Create a Postscript version of the manual, in @file{doc/mpc.ps}.
+
+@item
+@samp{html}
+
+Create an HTML version of the manual, in several pages in the
+directory @file{doc/mpc.html}; if you want only one output HTML file,
+then type @samp{makeinfo --html --no-split mpc.texi} instead.
+
+@item
+@samp{clean}
+
+Delete all object files and archive files, but not the configuration files.
+
+@item
+@samp{distclean}
+
+Delete all files not included in the distribution.
+
+@item
+@samp{uninstall}
+
+Delete all files copied by @samp{make install}.
+@end itemize
+
+
+
+@section Known Build Problems
+
+On AIX, if GMP was built with the 64-bit ABI, before building and testing GNU MPC,
+it might be necessary to set the @samp{OBJECT_MODE} environment variable to 64
+by, e.g.,
+
+@samp{export OBJECT_MODE=64}
+
+This has been tested with the C compiler IBM XL C/C++ Enterprise Edition
+V8.0 for AIX, version: 08.00.0000.0021, GMP 4.2.4 and GNU MPFR 2.4.1.
+
+Please report any other problems you encounter to
+@samp{mpc-discuss@@lists.gforge.inria.fr}.
+@xref{Reporting Bugs}.
+
+@node Reporting Bugs
+@chapter Reporting Bugs
+@cindex Reporting bugs
+
+If you think you have found a bug in the GNU MPC library,
+please investigate
+and report it. We have made this library available to you, and it is not to ask
+too much from you, to ask you to report the bugs that you find.
+
+There are a few things you should think about when you put your bug report
+together.
+
+You have to send us a test case that makes it possible for us to reproduce the
+bug. Include instructions on how to run the test case.
+
+You also have to explain what is wrong; if you get a crash, or if the results
+printed are incorrect and in that case, in what way.
+
+Please include compiler version information in your bug report.
+This can be extracted using @samp{gcc -v},
+or @samp{cc -V} on some machines.
+Also, include the output from @samp{uname -a}.
+
+If your bug report is good, we will do our best to help you to get a corrected
+version of the library; if the bug report is poor, we will not do anything about
+it (aside of chiding you to send better bug reports).
+
+Send your bug report to: @samp{mpc-discuss@@lists.gforge.inria.fr}.
+
+If you think something in this manual is unclear, or downright incorrect, or if
+the language needs to be improved, please send a note to the same address.
+
+@node GNU MPC Basics
+@chapter GNU MPC Basics
+
+
+@cindex @file{mpc.h}
+All declarations needed to use GNU MPC are collected in the include file
+@file{mpc.h}. It is designed to work with both C and C++ compilers.
+You should include that file in any program using the GNU MPC library
+by adding the line
+@example
+ #include "mpc.h"
+@end example
+
+@section Nomenclature and Types
+
+@cindex Complex number
+@tindex @code{mpc_t}
+@noindent
+@dfn{Complex number} or @dfn{Complex} for short, is a pair of two
+arbitrary precision floating-point numbers (for the real and imaginary parts).
+The C data type for such objects is @code{mpc_t}.
+
+@cindex Precision
+@tindex @code{mpfr_prec_t}
+@noindent
+The @dfn{Precision} is the number of bits used to represent the mantissa
+of the real and imaginary parts;
+the corresponding C data type is @code{mpfr_prec_t}.
+For more details on the allowed precision range,
+@ifinfo
+@pxref{Nomenclature and Types,,, mpfr.info,GNU MPFR}.
+@end ifinfo
+@ifnotinfo
+see Section ``Nomenclature and Types'' in @cite{GNU MPFR}.
+@end ifnotinfo
+
+@cindex Rounding Mode
+@tindex @code{mpc_rnd_t}
+@noindent
+The @dfn{rounding mode} specifies the way to round the result of a
+complex operation, in case the exact result can not be represented
+exactly in the destination mantissa;
+the corresponding C data type is @code{mpc_rnd_t}.
+A complex rounding mode is a pair of two rounding modes: one for the real
+part, one for the imaginary part.
+
+@section Function Classes
+
+There is only one class of functions in the GNU MPC library, namely functions for
+complex arithmetic. The function names begin with @code{mpc_}. The
+associated type is @code{mpc_t}.
+
+
+@section GNU MPC Variable Conventions
+
+As a general rule, all GNU MPC functions expect output arguments before input
+arguments. This notation is based on an analogy with the assignment operator.
+
+GNU MPC allows you to use the same variable for both input and output in the same
+expression. For example, the main function for floating-point multiplication,
+@code{mpc_mul}, can be used like this: @code{mpc_mul (x, x, x, rnd_mode)}.
+This
+computes the square of @var{x} with rounding mode @code{rnd_mode}
+and puts the result back in @var{x}.
+
+Before you can assign to an GNU MPC variable, you need to initialize it by calling
+one of the special initialization functions. When you are done with a
+variable, you need to clear it out, using one of the functions for that
+purpose.
+
+A variable should only be initialized once, or at least cleared out between
+each initialization. After a variable has been initialized, it may be
+assigned to any number of times.
+
+For efficiency reasons, avoid to initialize and clear out a variable in loops.
+Instead, initialize it before entering the loop, and clear it out after the
+loop has exited.
+
+You do not need to be concerned about allocating additional space for GNU MPC
+variables, since each of its real and imaginary part
+has a mantissa of fixed size.
+Hence unless you change its precision, or clear and reinitialize it,
+a complex variable will have the same allocated space during all its
+life.
+
+
+@section Rounding Modes
+
+A complex rounding mode is of the form @code{MPC_RNDxy} where
+@code{x} and @code{y} are one of @code{N} (to nearest), @code{Z} (towards
+zero), @code{U} (towards plus infinity), @code{D} (towards minus infinity).
+The first letter refers to the rounding mode for the real part,
+and the second one for the imaginary part.
+For example @code{MPC_RNDZU} indicates to round the real part towards zero,
+and the imaginary part towards plus infinity.
+
+The @samp{round to nearest} mode works as in the IEEE P754 standard: in case
+the number to be rounded lies exactly in the middle of two representable
+numbers, it is rounded to the one with the least significant bit set to zero.
+For example, the number 5, which is represented by (101) in binary, is rounded
+to (100)=4 with a precision of two bits, and not to (110)=6.
+
+
+@anchor{return-value}
+@section Return Value
+
+Most GNU MPC functions have a return value of type @code{int}, which is used
+to indicate the position of the rounded real and imaginary parts with respect
+to the exact (infinite precision) values.
+If this integer is @code{i}, the macros @code{MPC_INEX_RE(i)} and
+@code{MPC_INEX_IM(i)} give 0 if the corresponding rounded value is exact,
+a negative value if the rounded value is less than the exact one,
+and a positive value if it is greater than the exact one.
+Similarly, functions computing a result of type @code{mpfr_t}
+return an integer that is 0, positive or negative depending on
+whether the rounded value is the same, larger or smaller then
+the exact result.
+
+Some functions, such as @code{mpc_sin_cos}, compute two complex results;
+the macros @code{MPC_INEX1(i)} and @code{MPC_INEX2(i)}, applied to
+the return value @code{i} of such a function, yield the exactness value
+corresponding to the first or the second computed value, respectively.
+
+
+@section Branch Cuts And Special Values
+
+Some complex functions have branch cuts, across which the function is
+discontinous. In GNU MPC, the branch cuts chosen are the same as those
+specified for the corresponding functions in the ISO C99 standard.
+
+Likewise, when evaluated at a point whose real or imaginary part is
+either infinite or a NaN or a signed zero, a function returns the same
+value as those specified for the corresponding function in the ISO C99
+standard.
+
+
+@node Complex Functions
+@chapter Complex Functions
+@cindex Complex functions
+
+The complex functions expect arguments of type @code{mpc_t}.
+
+The GNU MPC floating-point functions have an interface that is similar to the
+GNU MP
+integer functions. The function prefix for operations on complex numbers is
+@code{mpc_}.
+
+@cindex User-defined precision
+The precision of a computation is defined as follows: Compute the requested
+operation exactly (with ``infinite precision''), and round the result to
+the destination variable precision with the given rounding mode.
+
+The GNU MPC complex functions are intended to be a smooth extension
+of the IEEE P754 arithmetic. The results obtained on one
+computer should not differ from the results obtained on a computer with a
+different word size.
+
+
+@menu
+* Initializing Complex Numbers::
+* Assigning Complex Numbers::
+* Converting Complex Numbers::
+* String and Stream Input and Output::
+* Complex Comparison::
+* Projection & Decomposing::
+* Basic Arithmetic::
+* Power Functions and Logarithm::
+* Trigonometric Functions::
+* Miscellaneous Complex Functions::
+* Advanced Functions::
+* Internals::
+@end menu
+
+@node Initializing Complex Numbers
+@section Initialization Functions
+
+An @code{mpc_t} object must be initialized before storing the first value in
+it. The functions @code{mpc_init2} and @code{mpc_init3}
+are used for that purpose.
+
+@deftypefun void mpc_init2 (mpc_t @var{z}, mpfr_prec_t @var{prec})
+Initialize @var{z} to precision @var{prec} bits
+and set its real and imaginary parts to NaN.
+Normally, a variable should be initialized once only
+or at least be cleared, using @code{mpc_clear}, between initializations.
+@end deftypefun
+
+@deftypefun void mpc_init3 (mpc_t @var{z}, mpfr_prec_t @var{prec_r}, mpfr_prec_t @var{prec_i})
+Initialize @var{z} with the precision of its real part being
+@var{prec_r} bits and the precision of its imaginary part being
+@var{prec_i} bits, and set the real and imaginary parts to NaN.
+@end deftypefun
+
+@deftypefun void mpc_clear (mpc_t @var{z})
+Free the space occupied by @var{z}. Make sure to call this function for all
+@code{mpc_t} variables when you are done with them.
+@end deftypefun
+
+@need 2000
+Here is an example on how to initialize complex variables:
+@example
+@{
+ mpc_t x, y;
+ mpc_init2 (x, 256); /* precision @emph{exactly} 256 bits */
+ mpc_init3 (y, 100, 50); /* 100/50 bits for the real/imaginary part */
+ @dots{}
+ mpc_clear (x);
+ mpc_clear (y);
+@}
+@end example
+
+The following function is useful for changing the precision during a
+calculation. A typical use would be for adjusting the precision gradually in
+iterative algorithms like Newton-Raphson, making the computation precision
+closely match the actual accurate part of the numbers.
+
+@deftypefun void mpc_set_prec (mpc_t @var{x}, mpfr_prec_t @var{prec})
+Reset the precision of @var{x} to be @strong{exactly} @var{prec} bits,
+and set its real/imaginary parts to NaN.
+The previous value stored in @var{x} is lost. It is equivalent to
+a call to @code{mpc_clear(x)} followed by a call to
+@code{mpc_init2(x, prec)}, but more efficient as no allocation is done in
+case the current allocated space for the mantissa of @var{x} is sufficient.
+@end deftypefun
+
+@deftypefun mpfr_prec_t mpc_get_prec (mpc_t @var{x})
+If the real and imaginary part of @var{x} have the same precision, it is returned,
+otherwise, 0 is returned.
+@end deftypefun
+
+@deftypefun void mpc_get_prec2 (mpfr_prec_t* @var{pr}, mpfr_prec_t* @var{pi}, mpc_t @var{x})
+Returns the precision of the real part of @var{x} via @var{pr} and of its imaginary part
+via @var{pi}.
+@end deftypefun
+
+
+@node Assigning Complex Numbers
+@section Assignment Functions
+@cindex Complex assignment functions
+
+These functions assign new values to already initialized complex numbers
+(@pxref{Initializing Complex Numbers}).
+When using any functions with @code{intmax_t} or @code{uintmax_t}
+parameters, you must include
+@code{<stdint.h>} or @code{<inttypes.h>} @emph{before} @file{mpc.h}, to allow
+@file{mpc.h} to define prototypes for these functions.
+Similarly, functions with parameters of type @code{complex} or
+@code{long complex} are defined only if @code{<complex.h>} is included
+@emph{before} @file{mpc.h}.
+If you need assignment functions that are not in the current API, you can
+define them using the @code{MPC_SET_X_Y} macro (@pxref{Advanced Functions}).
+
+@deftypefun int mpc_set (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set the value of @var{rop} from @var{op}, rounded to the precision of @var{rop}
+with the given rounding mode @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpc_set_ui (mpc_t @var{rop}, unsigned long int @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_si (mpc_t @var{rop}, long int @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_uj (mpc_t @var{rop}, uintmax_t @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_sj (mpc_t @var{rop}, intmax_t @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_d (mpc_t @var{rop}, double @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_ld (mpc_t @var{rop}, long double @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_dc (mpc_t @var{rop}, double _Complex @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_ldc (mpc_t @var{rop}, long double _Complex @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_z (mpc_t @var{rop}, mpz_t @var{op} mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_q (mpc_t @var{rop}, mpq_t @var{op} mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_f (mpc_t @var{rop}, mpf_t @var{op} mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_fr (mpc_t @var{rop}, mpfr_t @var{op}, mpc_rnd_t @var{rnd})
+Set the value of @var{rop} from @var{op}, rounded to the precision of
+@var{rop} with the given rounding mode @var{rnd}.
+The argument @var{op} is interpreted as real, so the imaginary part of
+@var{rop} is set to zero with a positive sign.
+Please note that even a @code{long int} may have to be rounded, if the
+destination precision is less than the machine word width.
+For @code{mpc_set_d}, be careful that the input number @var{op} may not be
+exactly representable as a double-precision number (this happens for 0.1 for
+instance), in which case it is first rounded by the C compiler to a
+double-precision number, and then only to a complex number.
+@end deftypefun
+
+@deftypefun int mpc_set_ui_ui (mpc_t @var{rop}, unsigned long int @var{op1}, unsigned long int @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_si_si (mpc_t @var{rop}, long int @var{op1}, long int @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_uj_uj (mpc_t @var{rop}, uintmax_t @var{op1}, uintmax_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_sj_sj (mpc_t @var{rop}, intmax_t @var{op1}, intmax_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_d_d (mpc_t @var{rop}, double @var{op1}, double @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_ld_ld (mpc_t @var{rop}, long double @var{op1}, long double @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_z_z (mpc_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_q_q (mpc_t @var{rop}, mpq_t @var{op1}, mpq_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_f_f (mpc_t @var{rop}, mpf_t @var{op1}, mpf_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_set_fr_fr (mpc_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpc_rnd_t @var{rnd})
+Set the real part of @var{rop} from @var{op1}, and its imaginary part from
+@var{op2}, according to the rounding mode @var{rnd}.
+
+Beware that the behaviour of @code{mpc_set_fr_fr} is undefined if @var{op1}
+or @var{op2} is a pointer to the real or imaginary part of @var{rop}.
+To exchange the real and the imaginary part of a complex number, either use
+@code{mpfr_swap (mpc_realref (rop), mpc_imagref (rop))}, which also exchanges
+the precisions of the two parts; or use a temporary variable.
+@end deftypefun
+
+For functions assigning complex variables from strings or input streams,
+@pxref{String and Stream Input and Output}.
+
+@deftypefun void mpc_set_nan (mpc_t @var{rop})
+Set @var{rop} to Nan+i*NaN.
+@end deftypefun
+
+@deftypefun void mpc_swap (mpc_t @var{op1}, mpc_t @var{op2})
+Swap the values of @var{op1} and @var{op2} efficiently. Warning: The
+precisions are exchanged, too; in case these are different,
+@code{mpc_swap} is thus not equivalent to three @code{mpc_set} calls using a
+third auxiliary variable.
+@end deftypefun
+
+
+@node Converting Complex Numbers
+@section Conversion Functions
+@cindex Conversion functions
+
+The following functions are available only if @code{<complex.h>}
+is included @emph{before} @file{mpc.h}.
+
+@deftypefun double _Complex mpc_get_dc (mpc_t @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx {long double _Complex} mpc_get_ldc (mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Convert @var{op} to a C complex number, using the rounding mode @var{rnd}.
+@end deftypefun
+
+
+For functions converting complex variables to strings or stream output,
+@pxref{String and Stream Input and Output}.
+
+
+@node String and Stream Input and Output
+@section String and Stream Input and Output
+@cindex String and stream input and output
+
+@deftypefun int mpc_strtoc (mpc_t @var{rop}, const char *@var{nptr}, char **@var{endptr}, int @var{base}, mpc_rnd_t @var{rnd})
+Read a complex number from a string @var{nptr} in base @var{base}, rounded to
+the precision of @var{rop} with the given rounding mode @var{rnd}.
+The @var{base} must be either 0 or a number from 2 to 36 (otherwise the
+behaviour is undefined).
+If @var{nptr} starts with valid data, the result is stored in @var{rop},
+the usual inexact value is returned (@pxref{return-value,, Return
+Value}) and, if @var{endptr} is not the null pointer,
+@var{*endptr} points to the character just after the valid data.
+Otherwise, @var{rop} is set to @code{NaN + i * NaN}, -1 is returned and,
+if @var{endptr} is not the null pointer,
+the value of @var{nptr} is stored in the location referenced by
+@var{endptr}.
+
+The expected form of a complex number string is either a real number (an
+optional leading whitespace, an optional sign followed by a floating-point
+number), or a pair of real numbers in parentheses separated by whitespace. If
+a real number is read, the missing imaginary part is set to +0.
+The form of a floating-point number depends on the base and is described
+in the documentation of @code{mpfr_strtofr}
+@ifinfo
+(@pxref{Assignment Functions,,, mpfr.info,GNU MPFR}).
+@end ifinfo
+@ifnotinfo
+in the GNU MPFR manual.
+@end ifnotinfo
+For instance, @code{"3.1415926"}, @code{"(1.25e+7 +.17)"}, @code{"(@@nan@@
+2)"} and @code{"(-0 -7)"} are valid strings for @var{base} = 10.
+If @var{base} = 0, then a prefix may be used to indicate the base in which the
+floating-point number is written. Use prefix '0b' for binary numbers, prefix
+'0x' for hexadecimal numbers, and no prefix for decimal numbers.
+The real and imaginary part may then be written in different bases.
+For instance, @code{"(1.024e+3 +2.05e+3)"} and @code{"(0b1p+10 +0x802)"} are
+valid strings for @code{base}=0 and represent the same value.
+@end deftypefun
+
+@deftypefun int mpc_set_str (mpc_t @var{rop}, const char *@var{s}, int @var{base}, mpc_rnd_t rnd)
+Set @var{rop} to the value of the string @var{s} in base @var{base}, rounded
+to the precision of @var{rop} with the given rounding mode @var{rnd}.
+See the documentation of @code{mpc_strtoc} for a detailed description of the
+valid string formats.
+Contrarily to @code{mpc_strtoc}, @code{mpc_set_str} requires the @emph{whole}
+string to represent a valid complex number (potentially followed by
+additional white space).
+This function returns the usual inexact value (@pxref{return-value,, Return
+Value}) if the entire string up to the final null character is a valid number
+in base @var{base}; otherwise it returns @minus{}1, and @var{rop} is set to
+NaN+i*NaN.
+@end deftypefun
+
+@deftypefun {char *} mpc_get_str (int @var{b}, size_t @var{n}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Convert @var{op} to a string containing its real and imaginary parts,
+separated by a space and enclosed in a pair of parentheses.
+The numbers are written in base @var{b} (which may vary from 2 to 36) and
+rounded according to @var{rnd}. The number of significant digits, at least 2,
+is given by @var{n}. It is also possible to let
+@var{n} be zero, in which case the number of digits is chosen large
+enough so that re-reading the printed value with the same precision, assuming
+both output and input use rounding to nearest, will recover the original value
+of @var{op}.
+Note that @code{mpc_get_str} uses the decimal point of the current locale
+if available, and @samp{.} otherwise.
+
+The string is generated using the current memory allocation function
+(@code{malloc} by default, unless it has been modified using the custom
+memory allocation interface of @code{gmp}); once it is not needed any more,
+it should be freed by calling @code{mpc_free_str}.
+@end deftypefun
+
+@deftypefun {void} mpc_free_str (char *@var{str})
+Free the string @var{str}, which needs to have been allocated by
+a call to @code{mpc_get_str}.
+@end deftypefun
+
+The following two functions read numbers from input streams and write
+them to output streams.
+When using any of these functions, you need to include @file{stdio.h}
+@emph{before} @file{mpc.h}.
+
+@deftypefun int mpc_inp_str (mpc_t @var{rop}, FILE *@var{stream}, size_t *@var{read}, int @var{base}, mpc_rnd_t @var{rnd})
+Input a string in base @var{base} in the same format as for @code{mpc_strtoc}
+from stdio stream @var{stream}, rounded according to @var{rnd}, and put the
+read complex number into @var{rop}.
+If @var{stream} is the null pointer, @var{rop} is read from @code{stdin}.
+Return the usual inexact value; if an error occurs, set @var{rop} to @code{NaN
++ i * NaN} and return -1.
+If @var{read} is not the null pointer, it is set to the number of read
+characters.
+
+Unlike @code{mpc_strtoc}, the function @code{mpc_inp_str} does not possess
+perfect knowledge of the string to transform and has to read it
+character by character, so it behaves slightly differently: It tries
+to read a string describing a complex number and processes this string
+through a call to @code{mpc_set_str}. Precisely, after skipping optional
+whitespace, a minimal string is read according to the regular expression
+@code{mpfr | '(' \s* mpfr \s+ mpfr \s* ')'}, where @code{\s} denotes a whitespace,
+and @code{mpfr} is either a string containing neither whitespaces nor
+parentheses, or @code{nan(n-char-sequence)} or @code{@@nan@@(n-char-sequence)}
+(regardless of capitalisation) with @code{n-char-sequence} a string
+of ascii letters, digits or @code{'_'}.
+
+For instance, upon input of @code{"nan(13 1)"}, the function
+@code{mpc_inp_str} starts to recognise a value of NaN followed by an
+n-char-sequence indicated by the opening parenthesis; as soon as the
+space is reached, it becocmes clear that the expression in parentheses
+is not an n-char-sequence, and the error flag -1 is returned after 6
+characters have been consumed from the stream (the whitespace itself
+remaining in the stream).
+The function @code{mpc_strtoc}, on the other hand, may track back
+when reaching the whitespace; it treats the string as the two successive
+complex numbers @code{NaN + i * 0} and @code{13 + i}.
+It is thus recommended to have a whitespace follow each floating point number
+to avoid this problem.
+@end deftypefun
+
+@deftypefun size_t mpc_out_str (FILE *@var{stream}, int @var{base}, size_t @var{n_digits}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Output @var{op} on stdio stream @var{stream} in
+base @var{base}, rounded according to @var{rnd}, in the same format
+as for @code{mpc_strtoc}
+If @var{stream} is the null pointer, @var{rop} is written to @code{stdout}.
+
+Return the number of characters written.
+@end deftypefun
+
+
+@node Complex Comparison
+@section Comparison Functions
+@cindex Complex comparisons functions
+@cindex Comparison functions
+
+@deftypefn Function int mpc_cmp (mpc_t @var{op1}, mpc_t @var{op2})
+@deftypefnx Function int mpc_cmp_si_si (mpc_t @var{op1}, long int @var{op2r}, long int @var{op2i})
+@deftypefnx Macro int mpc_cmp_si (mpc_t @var{op1}, long int @var{op2})
+
+Compare @var{op1} and @var{op2}, where in the case of @code{mpc_cmp_si_si},
+@var{op2} is taken to be @var{op2r} + i @var{op2i}.
+The return value @var{c} can be decomposed into @code{x = MPC_INEX_RE(c)}
+and @code{y = MPC_INEX_IM(c)}, such that @var{x} is
+positive if the real part of @var{op1} is greater than that of @var{op2},
+zero if both real parts are equal, and negative if the real part of @var{op1}
+is less than that of @var{op2}, and likewise for @var{y}.
+Both @var{op1} and @var{op2} are considered to their full own precision,
+which may differ.
+It is not allowed that one of the operands has a NaN (Not-a-Number) part.
+
+The storage of the return value is such that equality can be simply checked
+with @code{mpc_cmp (op1, op2) == 0}.
+@end deftypefn
+
+
+@node Projection & Decomposing
+@section Projection and Decomposing Functions
+@cindex Projection and Decomposing Functions
+
+@deftypefn Function int mpc_real (mpfr_t @var{rop}, mpc_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the real part of @var{op} rounded
+in the direction @var{rnd}.
+@end deftypefn
+
+@deftypefn Function int mpc_imag (mpfr_t @var{rop}, mpc_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the imaginary part of @var{op} rounded in the
+direction @var{rnd}.
+@end deftypefn
+
+@deftypefn Macro mpfr_t mpc_realref (mpc_t @var{op})
+@deftypefnx Macro mpfr_t mpc_imagref (mpc_t @var{op})
+Return a reference to the real part and imaginary part of @var{op},
+respectively. The @code{mpfr} functions can be used on the result of these
+macros (note that the @code{mpfr_t} type is itself a pointer).
+@end deftypefn
+
+@deftypefn Function int mpc_arg (mpfr_t @var{rop}, mpc_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the argument of @var{op}, with a branch cut along the
+negative real axis.
+@end deftypefn
+
+@deftypefn Function int mpc_proj (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Compute a projection of @var{op} onto the Riemann sphere. Set @var{rop} to
+@var{op} rounded in the direction @var{rnd}, except when at least one part of
+@var{op} is infinite (even if the other part is a NaN) in which case the real
+part of @var{rop} is set to plus infinity and its imaginary part to a signed
+zero with the same sign as the imaginary part of @var{op}.
+@end deftypefn
+
+
+@node Basic Arithmetic
+@section Basic Arithmetic Functions
+@cindex Complex arithmetic functions
+@cindex Arithmetic functions
+
+All the following functions are designed in such a way that, when working
+with real numbers instead of complex numbers, their complexity should
+essentially be the same as with the GNU MPFR library, with only a marginal
+overhead due to the GNU MPC layer.
+
+@deftypefun int mpc_add (mpc_t @var{rop}, mpc_t @var{op1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_add_ui (mpc_t @var{rop}, mpc_t @var{op1}, unsigned long int @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_add_fr (mpc_t @var{rop}, mpc_t @var{op1}, mpfr_t @var{op2}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @var{op1} @math{+} @var{op2} rounded according to @var{rnd}.
+@end deftypefun
+
+@deftypefn Function int mpc_sub (mpc_t @var{rop}, mpc_t @var{op1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefnx Function int mpc_sub_fr (mpc_t @var{rop}, mpc_t @var{op1}, mpfr_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefnx Function int mpc_fr_sub (mpc_t @var{rop}, mpfr_t @var{op1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefnx Function int mpc_sub_ui (mpc_t @var{rop}, mpc_t @var{op1}, unsigned long int @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefnx Macro int mpc_ui_sub (mpc_t @var{rop}, unsigned long int @var{op1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefnx Function int mpc_ui_ui_sub (mpc_t @var{rop}, unsigned long int @var{re1}, unsigned long int @var{im1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @var{op1} @minus{} @var{op2} rounded according to @var{rnd}.
+For @code{mpc_ui_ui_sub}, @var{op1} is @var{re1} + @var{im1}.
+@end deftypefn
+
+@deftypefun int mpc_neg (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @minus{}@var{op} rounded according to @var{rnd}.
+Just changes the sign if @var{rop} and @var{op} are the same variable.
+@end deftypefun
+
+@deftypefun int mpc_mul (mpc_t @var{rop}, mpc_t @var{op1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_mul_ui (mpc_t @var{rop}, mpc_t @var{op1}, unsigned long int @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_mul_si (mpc_t @var{rop}, mpc_t @var{op1}, long int @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_mul_fr (mpc_t @var{rop}, mpc_t @var{op1}, mpfr_t @var{op2}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @var{op1} times @var{op2} rounded according to @var{rnd}.
+Note: for @code{mpc_mul}, in case @var{op1} and @var{op2} have the same value,
+use @code{mpc_sqr} for better efficiency.
+@end deftypefun
+
+@deftypefun int mpc_mul_i (mpc_t @var{rop}, mpc_t @var{op}, int @var{sgn}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @var{op} times the imaginary unit i if @var{sgn} is
+non-negative, set @var{rop} to @var{op} times -i otherwise,
+in both cases rounded according to @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpc_sqr (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the square of @var{op} rounded according to @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpc_fma (mpc_t @var{rop}, mpc_t @var{op1}, mpc_t @var{op2}, mpc_t @var{op3}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @var{op1}*@var{op2}+@var{op3},
+rounded according to @var{rnd}, with only one final rounding.
+@end deftypefun
+
+@deftypefun int mpc_div (mpc_t @var{rop}, mpc_t @var{op1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_div_ui (mpc_t @var{rop}, mpc_t @var{op1}, unsigned long int @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_div_fr (mpc_t @var{rop}, mpc_t @var{op1}, mpfr_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_ui_div (mpc_t @var{rop}, unsigned long int @var{op1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_fr_div (mpc_t @var{rop}, mpfr_t @var{op1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @var{op1}/@var{op2} rounded according to @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpc_conj (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the conjugate of @var{op} rounded according to @var{rnd}.
+Just changes the sign of the imaginary part
+if @var{rop} and @var{op} are the same variable.
+@end deftypefun
+
+@deftypefun int mpc_abs (mpfr_t @var{rop}, mpc_t @var{op}, mpfr_rnd_t @var{rnd})
+Set the floating-point number @var{rop} to the absolute value of @var{op},
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpc_norm (mpfr_t @var{rop}, mpc_t @var{op}, mpfr_rnd_t @var{rnd})
+Set the floating-point number @var{rop} to the norm of @var{op}
+(i.e., the square of its absolute value),
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpc_mul_2ui (mpc_t @var{rop}, mpc_t @var{op1}, unsigned long int @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_mul_2si (mpc_t @var{rop}, mpc_t @var{op1}, long int @var{op2}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @var{op1} times 2 raised to @var{op2}
+rounded according to @var{rnd}. Just modifies the exponents
+of the real and imaginary parts by @var{op2}
+when @var{rop} and @var{op1} are identical.
+@end deftypefun
+
+@deftypefun int mpc_div_2ui (mpc_t @var{rop}, mpc_t @var{op1}, unsigned long int @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_div_2si (mpc_t @var{rop}, mpc_t @var{op1}, long int @var{op2}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @var{op1} divided by 2 raised to @var{op2}
+rounded according to @var{rnd}. Just modifies the exponents
+of the real and imaginary parts by @var{op2}
+when @var{rop} and @var{op1} are identical.
+@end deftypefun
+
+
+@node Power Functions and Logarithm
+@section Power Functions and Logarithm
+@cindex Power functions
+@cindex Logarithm
+
+@deftypefun int mpc_sqrt (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the square root of @var{op} rounded according to @var{rnd}.
+The returned value @var{rop} has a non-negative real part, and if its real
+part is zero, a non-negative imaginary part.
+@end deftypefun
+
+@deftypefun int mpc_pow (mpc_t @var{rop}, mpc_t @var{op1}, mpc_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_pow_d (mpc_t @var{rop}, mpc_t @var{op1}, double @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_pow_ld (mpc_t @var{rop}, mpc_t @var{op1}, long double @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_pow_si (mpc_t @var{rop}, mpc_t @var{op1}, long @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_pow_ui (mpc_t @var{rop}, mpc_t @var{op1}, unsigned long @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_pow_z (mpc_t @var{rop}, mpc_t @var{op1}, mpz_t @var{op2}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_pow_fr (mpc_t @var{rop}, mpc_t @var{op1}, mpfr_t @var{op2}, mpc_rnd_t @var{rnd})
+Set @var{rop} to @var{op1} raised to the power @var{op2}, rounded according
+to @var{rnd}.
+For @code{mpc_pow_d}, @code{mpc_pow_ld}, @code{mpc_pow_si}, @code{mpc_pow_ui},
+@code{mpc_pow_z} and @code{mpc_pow_fr},
+the imaginary part of @var{op2} is considered as +0.
+When both @var{op1} and @var{op2} are zero, the result has real part 1,
+and imaginary part 0, with sign being the opposite of that of @var{op2}.
+@end deftypefun
+
+@deftypefun int mpc_exp (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the exponential of @var{op},
+rounded according to @var{rnd} with the precision of @var{rop}.
+@end deftypefun
+
+@deftypefun int mpc_log (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_log10 (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the natural and base-10 logarithm of @var{op} respectively,
+rounded according to @var{rnd} with the precision of @var{rop}.
+The principal branch is chosen, with the branch cut on the negative real axis,
+so that the imaginary part of the result lies in
+@math{]-\pi , \pi]} and @math{]-\pi/log(10) , \pi/log(10)]} respectively.
+@end deftypefun
+
+
+@node Trigonometric Functions
+@section Trigonometric Functions
+@cindex Trigonometric functions
+
+@deftypefun int mpc_sin (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the sine of @var{op},
+rounded according to @var{rnd} with the precision of @var{rop}.
+@end deftypefun
+
+@deftypefun int mpc_cos (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the cosine of @var{op},
+rounded according to @var{rnd} with the precision of @var{rop}.
+@end deftypefun
+
+@deftypefun int mpc_sin_cos (mpc_t @var{rop_sin}, mpc_t @var{rop_cos}, mpc_t @var{op}, mpc_rnd_t @var{rnd_sin}, mpc_rnd_t @var{rnd_cos})
+Set @var{rop_sin} to the sine of @var{op},
+rounded according to @var{rnd_sin} with the precision of @var{rop_sin},
+and @var{rop_cos} to the cosine of @var{op},
+rounded according to @var{rnd_cos} with the precision of @var{rop_cos}.
+@end deftypefun
+
+@deftypefun int mpc_tan (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the tangent of @var{op},
+rounded according to @var{rnd} with the precision of @var{rop}.
+@end deftypefun
+
+@deftypefun int mpc_sinh (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the hyperbolic sine of @var{op},
+rounded according to @var{rnd} with the precision of @var{rop}.
+@end deftypefun
+
+@deftypefun int mpc_cosh (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the hyperbolic cosine of @var{op},
+rounded according to @var{rnd} with the precision of @var{rop}.
+@end deftypefun
+
+@deftypefun int mpc_tanh (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the hyperbolic tangent of @var{op},
+rounded according to @var{rnd} with the precision of @var{rop}.
+@end deftypefun
+
+@deftypefun int mpc_asin (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_acos (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_atan (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the inverse sine, inverse cosine, inverse tangent of @var{op},
+rounded according to @var{rnd} with the precision of @var{rop}.
+@end deftypefun
+
+@deftypefun int mpc_asinh (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_acosh (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+@deftypefunx int mpc_atanh (mpc_t @var{rop}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
+Set @var{rop} to the inverse hyperbolic sine, inverse hyperbolic cosine,
+inverse hyperbolic tangent of @var{op},
+rounded according to @var{rnd} with the precision of @var{rop}.
+The branch cut of @var{mpc_acosh} is @math{(-\infty, 1)}.
+@end deftypefun
+
+@node Miscellaneous Complex Functions
+@section Miscellaneous Functions
+@cindex Miscellaneous complex functions
+
+@deftypefun int mpc_urandom (mpc_t @var{rop}, gmp_randstate_t @var{state})
+Generate a uniformly distributed random complex in the unit square @math{[0,
+1] @times [0, 1]}. Return 0, unless an exponent in the real or imaginary part
+is not in the current exponent range, in which case that part is set to NaN
+and a zero value is returned. The second argument is a @code{gmp_randstate_t}
+structure which should be created using the GMP @code{rand_init} function, see
+the GMP manual.
+@end deftypefun
+
+@deftypefun {const char *} mpc_get_version (void)
+Return the GNU MPC version, as a null-terminated string.
+@end deftypefun
+
+@defmac MPC_VERSION
+@defmacx MPC_VERSION_MAJOR
+@defmacx MPC_VERSION_MINOR
+@defmacx MPC_VERSION_PATCHLEVEL
+@defmacx MPC_VERSION_STRING
+@code{MPC_VERSION} is the version of GNU MPC as a preprocessing constant.
+@code{MPC_VERSION_MAJOR}, @code{MPC_VERSION_MINOR} and
+@code{MPC_VERSION_PATCHLEVEL} are respectively the major, minor and
+patch level of GNU MPC version, as preprocessing constants.
+@code{MPC_VERSION_STRING} is the version as a string constant, which
+can be compared to the result of @code{mpc_get_version} to check at
+run time the header file and library used match:
+@example
+if (strcmp (mpc_get_version (), MPC_VERSION_STRING))
+ fprintf (stderr, "Warning: header and library do not match\n");
+@end example
+Note: Obtaining different strings is not necessarily an error, as in
+general, a program compiled with some old GNU MPC version can be
+dynamically linked with a newer GNU MPC library version (if allowed by the
+library versioning system).
+@end defmac
+
+@deftypefn Macro long MPC_VERSION_NUM (@var{major}, @var{minor}, @var{patchlevel})
+Create an integer in the same format as used by @code{MPC_VERSION} from the
+given @var{major}, @var{minor} and @var{patchlevel}.
+Here is an example of how to check the GNU MPC version at compile time:
+@example
+#if (!defined(MPC_VERSION) || (MPC_VERSION<MPC_VERSION_NUM(2,1,0)))
+# error "Wrong GNU MPC version."
+#endif
+@end example
+@end deftypefn
+
+@node Advanced Functions
+@section Advanced Functions
+
+@defmac MPC_SET_X_Y (@var{real_suffix}, @var{imag_suffix}, @var{rop}, @var{real}, @var{imag}, @var{rnd})
+The macro MPC_SET_X_Y is designed to serve as the body of an assignment
+function and cannot be used by itself.
+The @var{real_suffix} and @var{imag_suffix} parameters are the
+types of the real and imaginary part, that is, the @code{x} in the
+@code{mpfr_set_x} function one would use to set the part;
+for the mpfr type, use @code{fr}.
+@var{real} (respectively @var{imag}) is the value you want to assign to the
+real (resp. imaginary) part, its type must conform to @var{real_suffix}
+(resp. @var{imag_suffix}).
+@var{rnd} is the @code{mpc_rnd_t} rounding mode.
+The return value is the usual inexact value (@pxref{return-value,, Return
+Value}).
+
+For instance, you can define mpc_set_ui_fr as follows:
+@example
+int mpc_set_ui_fr (mpc_t rop, long int re, double im, mpc_rnd_t rnd)
+ MPC_SET_X_Y (ui, fr, rop, re, im, rnd);
+@end example
+@end defmac
+
+
+@node Internals
+@section Internals
+
+These macros and
+functions are mainly designed for the implementation of GNU MPC,
+but may be useful for users too.
+However, no upward compatibility is guaranteed.
+You need to include @code{mpc-impl.h} to use them.
+
+The macro @code{MPC_MAX_PREC(z)} gives the maximum of the precisions
+of the real and imaginary parts of a complex number.
+
+
+@node References
+@unnumbered References
+
+@itemize @bullet
+
+@item
+Torbj@"orn Granlund et al.
+@code{gmp} -- GNU multiprecision library.
+Version 4.2.4, @url{http://gmplib.org/}.
+
+@item
+Guillaume Hanrot, Vincent Lef@`evre, Patrick P@'elissier, Paul Zimmermann et al.
+@code{mpfr} -- A library for multiple-precision floating-point computations with exact rounding.
+Version 2.4.1, @url{http://www.mpfr.org}.
+
+@item
+IEEE standard for binary floating-point arithmetic, Technical Report
+ANSI-IEEE Standard 754-1985, New York, 1985.
+Approved March 21, 1985: IEEE Standards Board; approved July 26,
+ 1985: American National Standards Institute, 18 pages.
+
+@item
+Donald E. Knuth, "The Art of Computer Programming", vol 2,
+"Seminumerical Algorithms", 2nd edition, Addison-Wesley, 1981.
+
+@item
+ISO/IEC 9899:1999, Programming languages — C.
+
+@end itemize
+
+@node Concept Index
+@unnumbered Concept Index
+@printindex cp
+
+@node Function Index
+@unnumbered Function Index
+@printindex fn
+
+@node GNU Free Documentation License
+@appendix GNU Free Documentation License
+@include fdl-1.3.texi
+
+@ifnothtml
+@contents
+@end ifnothtml
+
+@bye
diff --git a/mpc/doc/stamp-vti b/mpc/doc/stamp-vti
new file mode 100644
index 0000000000..200ab0df3a
--- /dev/null
+++ b/mpc/doc/stamp-vti
@@ -0,0 +1,4 @@
+@set UPDATED 15 January 2014
+@set UPDATED-MONTH January 2014
+@set EDITION 1.0.2
+@set VERSION 1.0.2
diff --git a/mpc/doc/texinfo.tex b/mpc/doc/texinfo.tex
new file mode 100644
index 0000000000..b5f3141577
--- /dev/null
+++ b/mpc/doc/texinfo.tex
@@ -0,0 +1,10074 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2012-11-08.11}
+%
+% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+%
+% This texinfo.tex file is free software: you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation, either version 3 of the
+% License, or (at your option) any later version.
+%
+% This texinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction. (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or
+% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page)
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org. Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem. Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution. For a simple
+% manual foo.texi, however, you can get away with this:
+% tex foo.texi
+% texindex foo.??
+% tex foo.texi
+% tex foo.texi
+% dvips foo.dvi -o # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent. You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexraggedright=\raggedright
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+\let\ptextop=\top
+{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Pre-3.0.
+\else
+ \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putworderror\undefined \gdef\putworderror{error}\fi
+\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\ampChar = `\&
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar = `\-
+\chardef\dotChar = `\.
+\chardef\exclamChar= `\!
+\chardef\hashChar = `\#
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar = `\;
+\chardef\slashChar = `\/
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+ ap-pen-dix bit-map bit-maps
+ data-base data-bases eshell fall-ing half-way long-est man-u-script
+ man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+ par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+ spell-ing spell-ings
+ stand-alone strong-est time-stamp time-stamps which-ever white-space
+ wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt }
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal. We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+ \tracingstats2
+ \tracingpages1
+ \tracinglostchars2 % 2 gives us more in etex
+ \tracingparagraphs1
+ \tracingoutput1
+ \tracingmacros2
+ \tracingrestores1
+ \showboxbreadth\maxdimen \showboxdepth\maxdimen
+ \ifx\eTeXversion\thisisundefined\else % etex gives us more logging
+ \tracingscantokens1
+ \tracingifs1
+ \tracinggroups1
+ \tracingnesting2
+ \tracingassigns1
+ \fi
+ \tracingcommands3 % 3 gives us more in etex
+ \errorcontextlines16
+}%
+
+% @errormsg{MSG}. Do the index-like expansions on MSG, but if things
+% aren't perfect, it's not the end of the world, being an error message,
+% after all.
+%
+\def\errormsg{\begingroup \indexnofonts \doerrormsg}
+\def\doerrormsg#1{\errmessage{#1}}
+
+% add check for \lastpenalty to plain's definitions. If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+ \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+ \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+ \removelastskip\penalty-200\bigskip\fi\fi}
+
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Output a mark which sets \thischapter, \thissection and \thiscolor.
+% We dump everything together because we only have one kind of mark.
+% This works because we only use \botmark / \topmark, not \firstmark.
+%
+% A mark contains a subexpression of the \ifcase ... \fi construct.
+% \get*marks macros below extract the needed part using \ifcase.
+%
+% Another complication is to let the user choose whether \thischapter
+% (\thissection) refers to the chapter (section) in effect at the top
+% of a page, or that at the bottom of a page. The solution is
+% described on page 260 of The TeXbook. It involves outputting two
+% marks for the sectioning macros, one before the section break, and
+% one after. I won't pretend I can describe this better than DEK...
+\def\domark{%
+ \toks0=\expandafter{\lastchapterdefs}%
+ \toks2=\expandafter{\lastsectiondefs}%
+ \toks4=\expandafter{\prevchapterdefs}%
+ \toks6=\expandafter{\prevsectiondefs}%
+ \toks8=\expandafter{\lastcolordefs}%
+ \mark{%
+ \the\toks0 \the\toks2
+ \noexpand\or \the\toks4 \the\toks6
+ \noexpand\else \the\toks8
+ }%
+}
+% \topmark doesn't work for the very first chapter (after the title
+% page or the contents), so we use \firstmark there -- this gets us
+% the mark with the chapter defs, unless the user sneaks in, e.g.,
+% @setcolor (or @url, or @link, etc.) between @contents and the very
+% first @chapter.
+\def\gettopheadingmarks{%
+ \ifcase0\topmark\fi
+ \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
+}
+\def\getbottomheadingmarks{\ifcase1\botmark\fi}
+\def\getcolormarks{\ifcase2\topmark\fi}
+
+% Avoid "undefined control sequence" errors.
+\def\lastchapterdefs{}
+\def\lastsectiondefs{}
+\def\prevchapterdefs{}
+\def\prevsectiondefs{}
+\def\lastcolordefs{}
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+ %
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
+ \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ % We don't want .vr (or whatever) entries like this:
+ % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+ % "\acronym" won't work when it's read back in;
+ % it needs to be
+ % {\code {{\tt \backslashcurfont }acronym}
+ \shipout\vbox{%
+ % Do this early so pdf references go to the beginning of the page.
+ \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+ %
+ \ifcropmarks \vbox to \outervsize\bgroup
+ \hsize = \outerhsize
+ \vskip-\topandbottommargin
+ \vtop to0pt{%
+ \line{\ewtop\hfil\ewtop}%
+ \nointerlineskip
+ \line{%
+ \vbox{\moveleft\cornerthick\nstop}%
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}%
+ }%
+ \vss}%
+ \vskip\topandbottommargin
+ \line\bgroup
+ \hfil % center the page within the outer (page) hsize.
+ \ifodd\pageno\hskip\bindingoffset\fi
+ \vbox\bgroup
+ \fi
+ %
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \ifdim\ht\footlinebox > 0pt
+ % Only leave this space if the footline is nonempty.
+ % (We lessened \vsize for it in \oddfootingyyy.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 24pt
+ \unvbox\footlinebox
+ \fi
+ %
+ \ifcropmarks
+ \egroup % end of \vbox\bgroup
+ \hfil\egroup % end of (centering) \line\bgroup
+ \vskip\topandbottommargin plus1fill minus1fill
+ \boxmaxdepth = \cornerthick
+ \vbox to0pt{\vss
+ \line{%
+ \vbox{\moveleft\cornerthick\nsbot}%
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}%
+ }%
+ \nointerlineskip
+ \line{\ewbot\hfil\ewbot}%
+ }%
+ \egroup % \vbox from first cropmarks clause
+ \fi
+ }% end of \shipout\vbox
+ }% end of group with \indexdummies
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+ \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1\relax \unvbox#1\relax
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+ \def\argtorun{#2}%
+ \begingroup
+ \obeylines
+ \spaceisspace
+ #1%
+ \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ \argremovecomment #1\comment\ArgTerm%
+ }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+% @end itemize @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+ \def\temp{#3}%
+ \ifx\temp\empty
+ % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+ \let\temp\finishparsearg
+ \else
+ \let\temp\argcheckspaces
+ \fi
+ % Put the space token in:
+ \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \argtorun.
+% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\foo{...}
+% is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick. --kasal, 16nov03
+
+\def\parseargdef#1{%
+ \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+ \def#2{\parsearg#1}%
+ \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+ \obeyspaces
+ \gdef\obeyedspace{ }
+
+ % Make each space character in the input produce a normal interword
+ % space in the output. Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ \gdef\sepspaces{\obeyspaces\let =\tie}
+
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\leavevmode \penalty \@M \ ).
+ \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex. It's used like this:
+%
+% \envdef\foo{...}
+% \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo. \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches. The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as environments; they don't open a group. (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At run-time, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+ \def\temp{#1}%
+ \ifx\thisenv\temp
+ \else
+ \badenverr
+ \fi
+}
+
+% Environment mismatch, #1 expected:
+\def\badenverr{%
+ \errhelp = \EMsimple
+ \errmessage{This command can appear only \inenvironment\temp,
+ not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+ \ifx#1\empty
+ outside of any environment%
+ \else
+ in environment \expandafter\string#1%
+ \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+ \if 1\csname iscond.#1\endcsname
+ \else
+ % The general wording of \badenverr may not be ideal.
+ \expandafter\checkenv\csname#1\endcsname
+ \csname E#1\endcsname
+ \endgroup
+ \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\unskip\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+ \def\temp{#1}%
+ \ifx\temp\onword \plainfrenchspacing
+ \else\ifx\temp\offword \plainnonfrenchspacing
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @frenchspacing option `\temp', must be on|off}%
+ \fi\fi
+}
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large. This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material. In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom. The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+ \ifnum\catcode`\^^M=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ \startsavinginserts
+ %
+ \setbox\groupbox = \vtop\bgroup
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it. Thus, space below is not quite equal to space
+% above. But it's pretty close.
+\def\Egroup{%
+ % To get correct interline space between the last line of the group
+ % and the first line afterwards, we have to propagate \prevdepth.
+ \endgraf % Not \par, as it may have been set to \lisppar.
+ \global\dimen1 = \prevdepth
+ \egroup % End the \vtop.
+ % \dimen0 is the vertical size of the group's box.
+ \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
+ % \dimen2 is how much space is left on the page (more or less).
+ \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
+ % if the group doesn't fit on the current page, and it's a big big
+ % group, force a page break.
+ \ifdim \dimen0 > \dimen2
+ \ifdim \pagetotal < \vfilllimit\pageheight
+ \page
+ \fi
+ \fi
+ \box\groupbox
+ \prevdepth = \dimen1
+ \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+\parseargdef\need{%
+ % Ensure vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % If the @need value is less than one line space, it's useless.
+ \dimen0 = #1\mil
+ \dimen2 = \ht\strutbox
+ \advance\dimen2 by \dp\strutbox
+ \ifdim\dimen0 > \dimen2
+ %
+ % Do a \strut just to make the height of this box be normal, so the
+ % normal leading is inserted relative to the preceding line.
+ % And a page break here is fine.
+ \vtop to #1\mil{\strut\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+ \fi
+}
+
+% @br forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph. For more general purposes, use the \margin insertion
+% class. WHICH is `l' or `r'. Not documented, written for gawk manual.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+ \nobreak
+ \kern-\strutdepth
+ \vtop to \strutdepth{%
+ \baselineskip=\strutdepth
+ \vss
+ % if you have multiple lines of stuff to put here, you'll need to
+ % make the vbox yourself of the appropriate size.
+ \ifx#1l%
+ \llap{\ignorespaces #2\hskip\inmarginspacing}%
+ \else
+ \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+ \fi
+ \null
+ }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \def\lefttext{#1}% have both texts
+ \def\righttext{#2}%
+ \else
+ \def\lefttext{#1}% have only one text
+ \def\righttext{#1}%
+ \fi
+ %
+ \ifodd\pageno
+ \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+ \else
+ \def\temp{\inleftmargin\lefttext}%
+ \fi
+ \temp
+}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change). This command
+% is not documented, not supported, and doesn't work.
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% @include FILE -- \input text of FILE.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+ \pushthisfilestack
+ \def\thisfile{#1}%
+ {%
+ \makevalueexpandable % we want to expand any @value in FILE.
+ \turnoffactive % and allow special characters in the expansion
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @include of #1^^J}%
+ \edef\temp{\noexpand\input #1 }%
+ %
+ % This trickery is to read FILE outside of a group, in case it makes
+ % definitions, etc.
+ \expandafter
+ }\temp
+ \popthisfilestack
+}
+\def\filenamecatcodes{%
+ \catcode`\\=\other
+ \catcode`~=\other
+ \catcode`^=\other
+ \catcode`_=\other
+ \catcode`|=\other
+ \catcode`<=\other
+ \catcode`>=\other
+ \catcode`+=\other
+ \catcode`-=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
+}
+
+\def\pushthisfilestack{%
+ \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+ \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+ \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+ the stack of filenames is empty.}}
+%
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+ \ifhmode
+ \let\centersub\centerH
+ \else
+ \let\centersub\centerV
+ \fi
+ \centersub{\hfil \ignorespaces#1\unskip \hfil}%
+ \let\centersub\relax % don't let the definition persist, just in case
+}
+\def\centerH#1{{%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+}}
+%
+\newcount\centerpenalty
+\def\centerV#1{%
+ % The idea here is the same as in \startdefun, \cartouche, etc.: if
+ % @center is the first thing after a section heading, we need to wipe
+ % out the negative parskip inserted by \sectionheading, but still
+ % prevent a page break here.
+ \centerpenalty = \lastpenalty
+ \ifnum\centerpenalty>10000 \vskip\parskip \fi
+ \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi
+ \line{\kern\leftskip #1\kern\rightskip}%
+}
+
+% @sp n outputs n lines of vertical space
+%
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+%
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+%
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \defaultparindent = 0pt
+ \else
+ \defaultparindent = #1em
+ \fi
+ \fi
+ \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \lispnarrowing = 0pt
+ \else
+ \lispnarrowing = #1em
+ \fi
+ \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading. If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\noneword
+ \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+ \else\ifx\temp\insertword
+ \let\suppressfirstparagraphindent = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @firstparagraphindent option `\temp'}%
+ \fi\fi
+}
+
+% Here is how we actually suppress indentation. Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+ \gdef\indent{%
+ \restorefirstparagraphindent
+ \indent
+ }%
+ \gdef\noindent{%
+ \restorefirstparagraphindent
+ \noindent
+ }%
+ \global\everypar = {%
+ \kern -\parindent
+ \restorefirstparagraphindent
+ }%
+}
+
+\gdef\restorefirstparagraphindent{%
+ \global \let \indent = \ptexindent
+ \global \let \noindent = \ptexnoindent
+ \global \everypar = {}%
+}
+
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \iflinks
+ \tryauxfile
+ % Open the new aux file. TeX will close it automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ \openin 1 texinfo.cnf
+ \ifeof 1 \else \input texinfo.cnf \fi
+ \closein 1
+ %
+ \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set). So we test for \relax and 0 as well as being undefined.
+\ifx\pdfoutput\thisisundefined
+\else
+ \ifx\pdfoutput\relax
+ \else
+ \ifcase\pdfoutput
+ \else
+ \pdftrue
+ \fi
+ \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places. Thus, we have to
+% double any backslashes. Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e. Not good.
+%
+% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
+% related messages. The final outcome is that it is up to the TeX user
+% to double the backslashes and otherwise make the string valid, so
+% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to
+% do this reliably, so we use it.
+
+% #1 is a control sequence in which to do the replacements,
+% which we \xdef.
+\def\txiescapepdf#1{%
+ \ifx\pdfescapestring\thisisundefined
+ % No primitive available; should we give a warning or log?
+ % Many times it won't matter.
+ \else
+ % The expandable \pdfescapestring primitive escapes parentheses,
+ % backslashes, and other special chars.
+ \xdef#1{\pdfescapestring{#1}}%
+ \fi
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found. (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
+\ifpdf
+ %
+ % Color manipulation macros based on pdfcolor.tex,
+ % except using rgb instead of cmyk; the latter is said to render as a
+ % very dark gray on-screen and a very dark halftone in print, instead
+ % of actual black.
+ \def\rgbDarkRed{0.50 0.09 0.12}
+ \def\rgbBlack{0 0 0}
+ %
+ % k sets the color for filling (usual text, etc.);
+ % K sets the color for stroking (thin rules, e.g., normal _'s).
+ \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}}
+ %
+ % Set color, and create a mark which defines \thiscolor accordingly,
+ % so that \makeheadline knows which color to restore.
+ \def\setcolor#1{%
+ \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
+ \domark
+ \pdfsetcolor{#1}%
+ }
+ %
+ \def\maincolor{\rgbBlack}
+ \pdfsetcolor{\maincolor}
+ \edef\thiscolor{\maincolor}
+ \def\lastcolordefs{}
+ %
+ \def\makefootline{%
+ \baselineskip24pt
+ \line{\pdfsetcolor{\maincolor}\the\footline}%
+ }
+ %
+ \def\makeheadline{%
+ \vbox to 0pt{%
+ \vskip-22.5pt
+ \line{%
+ \vbox to8.5pt{}%
+ % Extract \thiscolor definition from the marks.
+ \getcolormarks
+ % Typeset the headline with \maincolor, then restore the color.
+ \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
+ }%
+ \vss
+ }%
+ \nointerlineskip
+ }
+ %
+ %
+ \pdfcatalog{/PageMode /UseOutlines}
+ %
+ % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+ \def\dopdfimage#1#2#3{%
+ \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ %
+ % pdftex (and the PDF format) support .pdf, .png, .jpg (among
+ % others). Let's try in that order, PDF first since if
+ % someone has a scalable image, presumably better to use that than a
+ % bitmap.
+ \let\pdfimgext=\empty
+ \begingroup
+ \openin 1 #1.pdf \ifeof 1
+ \openin 1 #1.PDF \ifeof 1
+ \openin 1 #1.png \ifeof 1
+ \openin 1 #1.jpg \ifeof 1
+ \openin 1 #1.jpeg \ifeof 1
+ \openin 1 #1.JPG \ifeof 1
+ \errhelp = \nopdfimagehelp
+ \errmessage{Could not find image file #1 for pdf}%
+ \else \gdef\pdfimgext{JPG}%
+ \fi
+ \else \gdef\pdfimgext{jpeg}%
+ \fi
+ \else \gdef\pdfimgext{jpg}%
+ \fi
+ \else \gdef\pdfimgext{png}%
+ \fi
+ \else \gdef\pdfimgext{PDF}%
+ \fi
+ \else \gdef\pdfimgext{pdf}%
+ \fi
+ \closein 1
+ \endgroup
+ %
+ % without \immediate, ancient pdftex seg faults when the same image is
+ % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
+ \ifnum\pdftexversion < 14
+ \immediate\pdfimage
+ \else
+ \immediate\pdfximage
+ \fi
+ \ifdim \wd0 >0pt width \pdfimagewidth \fi
+ \ifdim \wd2 >0pt height \pdfimageheight \fi
+ \ifnum\pdftexversion<13
+ #1.\pdfimgext
+ \else
+ {#1.\pdfimgext}%
+ \fi
+ \ifnum\pdftexversion < 14 \else
+ \pdfrefximage \pdflastximage
+ \fi}
+ %
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code, and characters
+ % such as \, aren't expanded when present in a section title.
+ \indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ \def\pdfdestname{#1}%
+ \txiescapepdf\pdfdestname
+ \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+ }}
+ %
+ % used to mark target names; must be expandable.
+ \def\pdfmkpgn#1{#1}
+ %
+ % by default, use a color that is dark enough to print on paper as
+ % nearly black, but still distinguishable for online viewing.
+ \def\urlcolor{\rgbDarkRed}
+ \def\linkcolor{\rgbDarkRed}
+ \def\endlink{\setcolor{\maincolor}\pdfendlink}
+ %
+ % Adding outlines to PDF; macros for calculating structure of outlines
+ % come from Petr Olsak
+ \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi}
+ \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+ \advance\tempnum by 1
+ \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+ %
+ % #1 is the section text, which is what will be displayed in the
+ % outline by the pdf viewer. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node text,
+ % which might be empty if this toc entry had no corresponding node.
+ % #4 is the page number
+ %
+ \def\dopdfoutline#1#2#3#4{%
+ % Generate a link to the node text if that exists; else, use the
+ % page number. We could generate a destination for the section
+ % text in the case where a section has no node, but it doesn't
+ % seem worth the trouble, since most documents are normally structured.
+ \edef\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty
+ \def\pdfoutlinedest{#4}%
+ \else
+ \txiescapepdf\pdfoutlinedest
+ \fi
+ %
+ % Also escape PDF chars in the display string.
+ \edef\pdfoutlinetext{#1}%
+ \txiescapepdf\pdfoutlinetext
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \begingroup
+ % Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\partentry##1##2##3##4{}% ignore parts in the outlines
+ \def\numchapentry##1##2##3##4{%
+ \def\thischapnum{##2}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsecentry##1##2##3##4{%
+ \advancenumber{chap\thischapnum}%
+ \def\thissecnum{##2}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsubsecentry##1##2##3##4{%
+ \advancenumber{sec\thissecnum}%
+ \def\thissubsecnum{##2}%
+ }%
+ \def\numsubsubsecentry##1##2##3##4{%
+ \advancenumber{subsec\thissubsecnum}%
+ }%
+ \def\thischapnum{0}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ %
+ % use \def rather than \let here because we redefine \chapentry et
+ % al. a second time, below.
+ \def\appentry{\numchapentry}%
+ \def\appsecentry{\numsecentry}%
+ \def\appsubsecentry{\numsubsecentry}%
+ \def\appsubsubsecentry{\numsubsubsecentry}%
+ \def\unnchapentry{\numchapentry}%
+ \def\unnsecentry{\numsecentry}%
+ \def\unnsubsecentry{\numsubsecentry}%
+ \def\unnsubsubsecentry{\numsubsubsecentry}%
+ \readdatafile{toc}%
+ %
+ % Read toc second time, this time actually producing the outlines.
+ % The `-' means take the \expnumber as the absolute number of
+ % subentries, which we calculated on our first read of the .toc above.
+ %
+ % We use the node names as the destinations.
+ \def\numchapentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+ \def\numsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+ \def\numsubsubsecentry##1##2##3##4{% count is always zero
+ \dopdfoutline{##1}{}{##3}{##4}}%
+ %
+ % PDF outlines are displayed using system fonts, instead of
+ % document fonts. Therefore we cannot use special characters,
+ % since the encoding is unknown. For example, the eogonek from
+ % Latin 2 (0xea) gets translated to a | character. Info from
+ % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+ %
+ % TODO this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Too
+ % much work for too little return. Just use the ASCII equivalents
+ % we use for the index sort strings.
+ %
+ \indexnofonts
+ \setupdatafile
+ % We can have normal brace characters in the PDF outlines, unlike
+ % Texinfo index files. So set that up.
+ \def\{{\lbracecharliteral}%
+ \def\}{\rbracecharliteral}%
+ \catcode`\\=\active \otherbackslash
+ \input \tocreadfilename
+ \endgroup
+ }
+ {\catcode`[=1 \catcode`]=2
+ \catcode`{=\other \catcode`}=\other
+ \gdef\lbracecharliteral[{]%
+ \gdef\rbracecharliteral[}]%
+ ]
+ %
+ \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+ \ifx\PP\D\let\nextsp\relax
+ \else\let\nextsp\skipspaces
+ \addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
+ \fi
+ \nextsp}
+ \def\getfilename#1{%
+ \filenamelength=0
+ % If we don't expand the argument now, \skipspaces will get
+ % snagged on things like "@value{foo}".
+ \edef\temp{#1}%
+ \expandafter\skipspaces\temp|\relax
+ }
+ \ifnum\pdftexversion < 14
+ \let \startlink \pdfannotlink
+ \else
+ \let \startlink \pdfstartlink
+ \fi
+ % make a live url in pdf output.
+ \def\pdfurl#1{%
+ \begingroup
+ % it seems we really need yet another set of dummies; have not
+ % tried to figure out what each command should do in the context
+ % of @url. for now, just make @/ a no-op, that's the only one
+ % people have actually reported a problem with.
+ %
+ \normalturnoffactive
+ \def\@{@}%
+ \let\/=\empty
+ \makevalueexpandable
+ % do we want to go so far as to use \indexnofonts instead of just
+ % special-casing \var here?
+ \def\var##1{##1}%
+ %
+ \leavevmode\setcolor{\urlcolor}%
+ \startlink attr{/Border [0 0 0]}%
+ user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+ \endgroup}
+ \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+ \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+ \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+ \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+ \def\maketoks{%
+ \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+ \ifx\first0\adn0
+ \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+ \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+ \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+ \else
+ \ifnum0=\countA\else\makelink\fi
+ \ifx\first.\let\next=\done\else
+ \let\next=\maketoks
+ \addtokens{\toksB}{\the\toksD}
+ \ifx\first,\addtokens{\toksB}{\space}\fi
+ \fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next}
+ \def\makelink{\addtokens{\toksB}%
+ {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+ \def\pdflink#1{%
+ \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+ \setcolor{\linkcolor}#1\endlink}
+ \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+ % non-pdf mode
+ \let\pdfmkdest = \gobble
+ \let\pdfurl = \gobble
+ \let\endlink = \relax
+ \let\setcolor = \gobble
+ \let\pdfsetcolor = \gobble
+ \let\pdfmakeoutlines = \relax
+\fi % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+ \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+ \csname ten#1\endcsname % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Unfortunately, we have to override this for titles and the like, since
+% in those cases "rm" is bold. Sigh.
+\def\rmisbold{\rm\def\curfontstyle{bf}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+% can get a sort of poor man's double spacing by redefining this.
+\def\baselinefactor{1}
+%
+\newdimen\textleading
+\def\setleading#1{%
+ \dimen0 = #1\relax
+ \normalbaselineskip = \baselinefactor\dimen0
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+% PDF CMaps. See also LaTeX's t1.cmap.
+%
+% do nothing with this by default.
+\expandafter\let\csname cmapOT1\endcsname\gobble
+\expandafter\let\csname cmapOT1IT\endcsname\gobble
+\expandafter\let\csname cmapOT1TT\endcsname\gobble
+
+% if we are producing pdf, and we have \pdffontattr, then define cmaps.
+% (\pdffontattr was introduced many years ago, but people still run
+% older pdftex's; it's easy to conditionalize, so we do.)
+\ifpdf \ifx\pdffontattr\thisisundefined \else
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1IT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1TT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+\fi\fi
+
+
+% Set the font macro #1 to the font named \fontprefix#2.
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit).
+% Example:
+% #1 = \textrm
+% #2 = \rmshape
+% #3 = 10
+% #4 = \mainmagstep
+% #5 = OT1
+%
+\def\setfont#1#2#3#4#5{%
+ \font#1=\fontprefix#2#3 scaled #4
+ \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+%
+% (end of cmaps)
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\thisisundefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx} % where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Definitions for a main text size of 11pt. (The default in Texinfo.)
+%
+\def\definetextfontsizexi{%
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1095}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+\def\chapecsize{1728}
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+\def\sececsize{1440}
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+\def\ssececsize{1200}
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+\def\reducedecsize{1000}
+
+\textleading = 13.2pt % line spacing for 11pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 11pt text font size definitions, \definetextfontsizexi
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit. This is for the GNU
+% Press printing of the Emacs 22 manual. Maybe other manuals in the
+% future. Used with @smallbook, which sets the leading to 12pt.
+%
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1000}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+\def\chapecsize{1440}
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+\def\sececsize{1200}
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+\def\ssececsize{1000}
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+\def\reducedecsize{0900}
+
+\divide\parskip by 2 % reduce space between paragraphs
+\textleading = 12pt % line spacing for 10pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 10pt text font size definitions, \definetextfontsizex
+
+
+% We provide the user-level command
+% @fonttextsize 10
+% (or 11) to redefine the text font size. pt is assumed.
+%
+\def\xiword{11}
+\def\xword{10}
+\def\xwordpt{10pt}
+%
+\parseargdef\fonttextsize{%
+ \def\textsizearg{#1}%
+ %\wlog{doing @fonttextsize \textsizearg}%
+ %
+ % Set \globaldefs so that documents can use this inside @tex, since
+ % makeinfo 4.8 does not support it, but we need it nonetheless.
+ %
+ \begingroup \globaldefs=1
+ \ifx\textsizearg\xword \definetextfontsizex
+ \else \ifx\textsizearg\xiword \definetextfontsizexi
+ \else
+ \errhelp=\EMsimple
+ \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+ \fi\fi
+ \endgroup
+}
+
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+ \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+ \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this because \STYLE needs to also set the
+% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower). These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \let\tenttsl=\textttsl
+ \def\curfontsize{text}%
+ \def\lsize{reduced}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+ \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+ \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+ \let\tenttsl=\titlettsl
+ \def\curfontsize{title}%
+ \def\lsize{chap}\def\lllsize{subsec}%
+ \resetmathfonts \setleading{27pt}}
+\def\titlefont#1{{\titlefonts\rmisbold #1}}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \let\tenttsl=\chapttsl
+ \def\curfontsize{chap}%
+ \def\lsize{sec}\def\lllsize{text}%
+ \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \let\tenttsl=\secttsl
+ \def\curfontsize{sec}%
+ \def\lsize{subsec}\def\lllsize{reduced}%
+ \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \let\tenttsl=\ssecttsl
+ \def\curfontsize{ssec}%
+ \def\lsize{text}\def\lllsize{small}%
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+ \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+ \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+ \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+ \let\tenttsl=\reducedttsl
+ \def\curfontsize{reduced}%
+ \def\lsize{small}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+ \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+ \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+ \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+ \let\tenttsl=\smallttsl
+ \def\curfontsize{small}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+ \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+ \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+ \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+ \let\tenttsl=\smallerttsl
+ \def\curfontsize{smaller}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{9.5pt}}
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+% Define these just so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+% 8.5x11=86 smallbook=72 a4=90 a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+% 8.5x11=90+ smallbook=80 a4=90+ a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt. So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+% 8.5x11=71 smallbook=60 a4=75 a5=58
+% --karl, 24jan03.
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+
+\message{markup,}
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will
+% define and register \INITMACRO to be called on markup style changes.
+% \INITMACRO can check \currentmarkupstyle for the innermost
+% style and the set of \ifmarkupSTYLE switches for all styles
+% currently in effect.
+\newif\ifmarkupvar
+\newif\ifmarkupsamp
+\newif\ifmarkupkey
+%\newif\ifmarkupfile % @file == @samp.
+%\newif\ifmarkupoption % @option == @samp.
+\newif\ifmarkupcode
+\newif\ifmarkupkbd
+%\newif\ifmarkupenv % @env == @code.
+%\newif\ifmarkupcommand % @command == @code.
+\newif\ifmarkuptex % @tex (and part of @math, for now).
+\newif\ifmarkupexample
+\newif\ifmarkupverb
+\newif\ifmarkupverbatim
+
+\let\currentmarkupstyle\empty
+
+\def\setupmarkupstyle#1{%
+ \csname markup#1true\endcsname
+ \def\currentmarkupstyle{#1}%
+ \markupstylesetup
+}
+
+\let\markupstylesetup\empty
+
+\def\defmarkupstylesetup#1{%
+ \expandafter\def\expandafter\markupstylesetup
+ \expandafter{\markupstylesetup #1}%
+ \def#1%
+}
+
+% Markup style setup for left and right quotes.
+\defmarkupstylesetup\markupsetuplq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuplq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuplqdefault \else \temp \fi
+}
+
+\defmarkupstylesetup\markupsetuprq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuprq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuprqdefault \else \temp \fi
+}
+
+{
+\catcode`\'=\active
+\catcode`\`=\active
+
+\gdef\markupsetuplqdefault{\let`\lq}
+\gdef\markupsetuprqdefault{\let'\rq}
+
+\gdef\markupsetcodequoteleft{\let`\codequoteleft}
+\gdef\markupsetcodequoteright{\let'\codequoteright}
+}
+
+\let\markupsetuplqcode \markupsetcodequoteleft
+\let\markupsetuprqcode \markupsetcodequoteright
+%
+\let\markupsetuplqexample \markupsetcodequoteleft
+\let\markupsetuprqexample \markupsetcodequoteright
+%
+\let\markupsetuplqkbd \markupsetcodequoteleft
+\let\markupsetuprqkbd \markupsetcodequoteright
+%
+\let\markupsetuplqsamp \markupsetcodequoteleft
+\let\markupsetuprqsamp \markupsetcodequoteright
+%
+\let\markupsetuplqverb \markupsetcodequoteleft
+\let\markupsetuprqverb \markupsetcodequoteright
+%
+\let\markupsetuplqverbatim \markupsetcodequoteleft
+\let\markupsetuprqverbatim \markupsetcodequoteright
+
+% Allow an option to not use regular directed right quote/apostrophe
+% (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
+% The undirected quote is ugly, so don't make it the default, but it
+% works for pasting with more pdf viewers (at least evince), the
+% lilypond developers report. xpdf does work with the regular 0x27.
+%
+\def\codequoteright{%
+ \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+ \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ '%
+ \else \char'15 \fi
+ \else \char'15 \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+ \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
+ \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ % [Knuth] pp. 380,381,391
+ % \relax disables Spanish ligatures ?` and !` of \tt font.
+ \relax`%
+ \else \char'22 \fi
+ \else \char'22 \fi
+}
+
+% Commands to set the quote options.
+%
+\parseargdef\codequoteundirected{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}%
+ \fi\fi
+}
+%
+\parseargdef\codequotebacktick{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}%
+ \fi\fi
+}
+
+% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font.
+\def\noligaturesquoteleft{\relax\lq}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Font commands.
+
+% #1 is the font command (\sl or \it), #2 is the text to slant.
+% If we are in a monospaced environment, however, 1) always use \ttsl,
+% and 2) do not add an italic correction.
+\def\dosmartslant#1#2{%
+ \ifusingtt
+ {{\ttsl #2}\let\next=\relax}%
+ {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}%
+ \next
+}
+\def\smartslanted{\dosmartslant\sl}
+\def\smartitalic{\dosmartslant\it}
+
+% Output an italic correction unless \next (presumed to be the following
+% character) is such as not to need one.
+\def\smartitaliccorrection{%
+ \ifx\next,%
+ \else\ifx\next-%
+ \else\ifx\next.%
+ \else\ptexslash
+ \fi\fi\fi
+ \aftersmartic
+}
+
+% Unconditional use \ttsl, and no ic. @var is set to this for defuns.
+\def\ttslanted#1{{\ttsl #1}}
+
+% @cite is like \smartslanted except unconditionally use \sl. We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection}
+
+\def\aftersmartic{}
+\def\var#1{%
+ \let\saveaftersmartic = \aftersmartic
+ \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}%
+ \smartslanted{#1}%
+}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @b, explicit bold. Also @strong.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+ \def\plainfrenchspacing{%
+ \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+ \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ \def\endofsentencespacefactor{1000}% for @. and friends
+ }
+ \def\plainnonfrenchspacing{%
+ \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+ \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+ \def\endofsentencespacefactor{3000}% for @. and friends
+ }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+% @t, explicit typewriter.
+\def\t#1{%
+ {\tt \rawbackslash \plainfrenchspacing #1}%
+ \null
+}
+
+% @samp.
+\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
+
+% @indicateurl is \samp, that is, with quotes.
+\let\indicateurl=\samp
+
+% @code (and similar) prints in typewriter, but with spaces the same
+% size as normal in the surrounding text, without hyphenation, etc.
+% This is a subroutine for that.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \plainfrenchspacing
+ #1%
+ }%
+ \null % reset spacefactor to 1000
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+%
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+% -- rms.
+{
+ \catcode`\-=\active \catcode`\_=\active
+ \catcode`\'=\active \catcode`\`=\active
+ \global\let'=\rq \global\let`=\lq % default definitions
+ %
+ \global\def\code{\begingroup
+ \setupmarkupstyle{code}%
+ % The following should really be moved into \setupmarkupstyle handlers.
+ \catcode\dashChar=\active \catcode\underChar=\active
+ \ifallowcodebreaks
+ \let-\codedash
+ \let_\codeunder
+ \else
+ \let-\realdash
+ \let_\realunder
+ \fi
+ \codex
+ }
+}
+
+\def\codex #1{\tclose{#1}\endgroup}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+ % this is all so @math{@code{var_name}+1} can work. In math mode, _
+ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+ % will therefore expand the active definition of _, which is us
+ % (inside @code that is), therefore an endless loop.
+ \ifusingtt{\ifmmode
+ \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+ \else\normalunderscore \fi
+ \discretionary{}{}{}}%
+ {\_}%
+}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__. This is undesirable in
+% some manuals, especially if they don't have long identifiers in
+% general. @allowcodebreaks provides a way to control this.
+%
+\newif\ifallowcodebreaks \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\keywordtrue
+ \allowcodebreakstrue
+ \else\ifx\txiarg\keywordfalse
+ \allowcodebreaksfalse
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}%
+ \fi\fi
+}
+
+% For @command, @env, @file, @option quotes seem unnecessary,
+% so use \code rather than \samp.
+\let\command=\code
+\let\env=\code
+\let\file=\code
+\let\option=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself. First (mandatory) arg is the url.
+% (This \urefnobreak definition isn't used now, leaving it for a while
+% for comparison.)
+\def\urefnobreak#1{\dourefnobreak #1,,,\finish}
+\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \code{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% This \urefbreak definition is the active one.
+\def\urefbreak{\begingroup \urefcatcodes \dourefbreak}
+\let\uref=\urefbreak
+\def\dourefbreak#1{\urefbreakfinish #1,,,\finish}
+\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \urefcode{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% Allow line breaks around only a few characters (only).
+\def\urefcatcodes{%
+ \catcode\ampChar=\active \catcode\dotChar=\active
+ \catcode\hashChar=\active \catcode\questChar=\active
+ \catcode\slashChar=\active
+}
+{
+ \urefcatcodes
+ %
+ \global\def\urefcode{\begingroup
+ \setupmarkupstyle{code}%
+ \urefcatcodes
+ \let&\urefcodeamp
+ \let.\urefcodedot
+ \let#\urefcodehash
+ \let?\urefcodequest
+ \let/\urefcodeslash
+ \codex
+ }
+ %
+ % By default, they are just regular characters.
+ \global\def&{\normalamp}
+ \global\def.{\normaldot}
+ \global\def#{\normalhash}
+ \global\def?{\normalquest}
+ \global\def/{\normalslash}
+}
+
+% we put a little stretch before and after the breakable chars, to help
+% line breaking of long url's. The unequal skips make look better in
+% cmtt at least, especially for dots.
+\def\urefprestretch{\urefprebreak \hskip0pt plus.13em }
+\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em }
+%
+\def\urefcodeamp{\urefprestretch \&\urefpoststretch}
+\def\urefcodedot{\urefprestretch .\urefpoststretch}
+\def\urefcodehash{\urefprestretch \#\urefpoststretch}
+\def\urefcodequest{\urefprestretch ?\urefpoststretch}
+\def\urefcodeslash{\futurelet\next\urefcodeslashfinish}
+{
+ \catcode`\/=\active
+ \global\def\urefcodeslashfinish{%
+ \urefprestretch \slashChar
+ % Allow line break only after the final / in a sequence of
+ % slashes, to avoid line break between the slashes in http://.
+ \ifx\next/\else \urefpoststretch \fi
+ }
+}
+
+% One more complication: by default we'll break after the special
+% characters, but some people like to break before the special chars, so
+% allow that. Also allow no breaking at all, for manual control.
+%
+\parseargdef\urefbreakstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\wordnone
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordbefore
+ \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordafter
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak}
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @urefbreakstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\wordafter{after}
+\def\wordbefore{before}
+\def\wordnone{none}
+
+\urefbreakstyle after
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+ \def\email#1{\doemail#1,,\finish}
+ \def\doemail#1,#2,#3\finish{\begingroup
+ \unsepspaces
+ \pdfurl{mailto:#1}%
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+ \endlink
+ \endgroup}
+\else
+ \let\email=\uref
+\fi
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct'.
+\kbdinputstyle distinct
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}}
+
+\def\xkey{\key}
+\def\kbdsub#1#2#3\par{%
+ \def\one{#1}\def\three{#3}\def\threex{??}%
+ \ifx\one\xkey\ifx\threex\three \key{#2}%
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+}
+
+% definition of @key that produces a lozenge. Doesn't adjust to text size.
+%\setfont\keyrm\rmshape{8}{1000}{OT1}
+%\font\keysy=cmsy9
+%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+% \vbox{\hrule\kern-0.4pt
+% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+% \kern-0.4pt\hrule}%
+% \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+
+% definition of @key with no lozenge. If the current font is already
+% monospace, don't change it; that way, we respect @kbdinputstyle. But
+% if it isn't monospace, then use \tt.
+%
+\def\key#1{{\setupmarkupstyle{key}%
+ \nohyphenation
+ \ifmonospace\else\tt\fi
+ #1}\null}
+
+% @clicksequence{File @click{} Open ...}
+\def\clicksequence#1{\begingroup #1\endgroup}
+
+% @clickstyle @arrow (by default)
+\parseargdef\clickstyle{\def\click{#1}}
+\def\click{\arrow}
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+%
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+ {\selectfonts\lsize #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+ \null % reset \spacefactor=1000
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+%
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+ {\plainfrenchspacing #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+ \null % reset \spacefactor=1000
+}
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode`\_ = \active
+ \gdef\mathunderscore{%
+ \catcode`\_=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a math (or tt) \.
+% FYI, plain.tex uses \\ as a temporary control sequence (for no
+% particular reason), but this is not advertised and we don't care.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ % make the texinfo accent commands work in math mode
+ \let\"=\ddot
+ \let\'=\acute
+ \let\==\bar
+ \let\^=\hat
+ \let\`=\grave
+ \let\u=\breve
+ \let\v=\check
+ \let\~=\tilde
+ \let\dotaccent=\dot
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \catcode`' = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ \let' = \ptexquoteright
+ }
+}
+
+% ctrl is no longer a Texinfo command, but leave this definition for fun.
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
+% Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
+% except specified as a normal braced arg, so no newlines to worry about.
+%
+\def\outfmtnametex{tex}
+%
+\long\def\inlinefmt#1{\doinlinefmt #1,\finish}
+\long\def\doinlinefmt#1,#2,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi
+}
+% For raw, must switch into @tex before parsing the argument, to avoid
+% setting catcodes prematurely. Doing it this way means that, for
+% example, @inlineraw{html, foo{bar} gets a parse error instead of being
+% ignored. But this isn't important because if people want a literal
+% *right* brace they would have to use a command anyway, so they may as
+% well use a command to get a left brace too. We could re-use the
+% delimiter character idea from \verb, but it seems like overkill.
+%
+\long\def\inlineraw{\tex \doinlineraw}
+\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish}
+\def\doinlinerawtwo#1,#2,\finish{%
+ \def\inlinerawname{#1}%
+ \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi
+ \endgroup % close group opened by \tex.
+}
+
+
+\message{glyphs,}
+% and logos.
+
+% @@ prints an @, as does @atchar{}.
+\def\@{\char64 }
+\let\atchar=\@
+
+% @{ @} @lbracechar{} @rbracechar{} all generate brace characters.
+% Unless we're in typewriter, use \ecfont because the CM text fonts do
+% not have braces, and we don't want to switch into math.
+\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}}
+\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}}
+\let\{=\mylbrace \let\lbracechar=\{
+\let\}=\myrbrace \let\rbracechar=\}
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux/toc files.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \ptexc
+\let\dotaccent = \ptexdot
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \ptext
+\let\ubaraccent = \ptexb
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi
+ \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{%
+ \ifx\textnominalsize\xwordpt
+ % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX.
+ % Revert to plain's \scriptsize, which is 7pt.
+ \count255=\the\fam $\fam\count255 \scriptstyle A$%
+ \else
+ % For 11pt, we can use our lllsize.
+ \selectfonts\lllsize A%
+ \fi
+ }%
+ \vss
+ }}%
+ \kern-.15em
+ \TeX
+}
+
+% Some math mode symbols.
+\def\bullet{$\ptexbullet$}
+\def\geq{\ifmmode \ge\else $\ge$\fi}
+\def\leq{\ifmmode \le\else $\le$\fi}
+\def\minus{\ifmmode -\else $-$\fi}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em. So do
+% whichever is larger.
+%
+\def\dots{%
+ \leavevmode
+ \setbox0=\hbox{...}% get width of three periods
+ \ifdim\wd0 > 1.5em
+ \dimen0 = \wd0
+ \else
+ \dimen0 = 1.5em
+ \fi
+ \hbox to \dimen0{%
+ \hskip 0pt plus.25fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=\endofsentencespacefactor
+}
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, they should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}}
+\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that. The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math. Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+ % We set the font at each command, rather than predefining it in
+ % \textfonts and the other font-switching commands, so that
+ % installations which never need the symbol don't have to have the
+ % font installed.
+ %
+ % There is only one designed size (nominal 10pt), so we always scale
+ % that to the current nominal size.
+ %
+ % By the way, simply using "at 1em" works for cmr10 and the like, but
+ % does not work for cmbx10 and other extended/shrunken fonts.
+ %
+ \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+ %
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+ \else
+ % regular:
+ \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+ \fi
+ \thiseurofont
+}
+
+% Glyphs from the EC fonts. We don't use \let for the aliases, because
+% sometimes we redefine the original macro, and the alias should reflect
+% the redefinition.
+%
+% Use LaTeX names for the Icelandic letters.
+\def\DH{{\ecfont \char"D0}} % Eth
+\def\dh{{\ecfont \char"F0}} % eth
+\def\TH{{\ecfont \char"DE}} % Thorn
+\def\th{{\ecfont \char"FE}} % thorn
+%
+\def\guillemetleft{{\ecfont \char"13}}
+\def\guillemotleft{\guillemetleft}
+\def\guillemetright{{\ecfont \char"14}}
+\def\guillemotright{\guillemetright}
+\def\guilsinglleft{{\ecfont \char"0E}}
+\def\guilsinglright{{\ecfont \char"0F}}
+\def\quotedblbase{{\ecfont \char"12}}
+\def\quotesinglbase{{\ecfont \char"0D}}
+%
+% This positioning is not perfect (see the ogonek LaTeX package), but
+% we have the precomposed glyphs for the most common cases. We put the
+% tests to use those glyphs in the single \ogonek macro so we have fewer
+% dummy definitions to worry about for index entries, etc.
+%
+% ogonek is also used with other letters in Lithuanian (IOU), but using
+% the precomposed glyphs for those is not so easy since they aren't in
+% the same EC font.
+\def\ogonek#1{{%
+ \def\temp{#1}%
+ \ifx\temp\macrocharA\Aogonek
+ \else\ifx\temp\macrochara\aogonek
+ \else\ifx\temp\macrocharE\Eogonek
+ \else\ifx\temp\macrochare\eogonek
+ \else
+ \ecfont \setbox0=\hbox{#1}%
+ \ifdim\ht0=1ex\accent"0C #1%
+ \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}%
+ \fi
+ \fi\fi\fi\fi
+ }%
+}
+\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A}
+\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a}
+\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E}
+\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e}
+%
+% Use the ec* fonts (cm-super in outline format) for non-CM glyphs.
+\def\ecfont{%
+ % We can't distinguish serif/sans and italic/slanted, but this
+ % is used for crude hacks anyway (like adding French and German
+ % quotes to documents typeset with CM, where we lose kerning), so
+ % hopefully nobody will notice/care.
+ \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+ \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+ \ifmonospace
+ % typewriter:
+ \font\thisecfont = ectt\ecsize \space at \nominalsize
+ \else
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \else
+ % regular:
+ \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \fi
+ \fi
+ \thisecfont
+}
+
+% @registeredsymbol - R in a circle. The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+ \hfil\crcr\Orb}}%
+ }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% Laurent Siebenmann reports \Orb undefined with:
+% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
+% so we'll define it if necessary.
+%
+\ifx\Orb\thisisundefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+% Quotes.
+\chardef\quotedblleft="5C
+\chardef\quotedblright=`\"
+\chardef\quoteleft=`\`
+\chardef\quoteright=`\'
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{%
+ \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+ % Open one extra group, as we want to close it in the middle of \Etitlepage.
+ \begingroup
+ \parindent=0pt \textfonts
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \let\page = \oldpage
+ \page
+ \null
+ }%
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ %
+ % Need this before the \...aftertitlepage checks so that if they are
+ % in effect the toc pages will come out with page numbers.
+ \HEADINGSon
+ %
+ % If they want short, they certainly want long too.
+ \ifsetshortcontentsaftertitlepage
+ \shortcontents
+ \contents
+ \global\let\shortcontents = \relax
+ \global\let\contents = \relax
+ \fi
+ %
+ \ifsetcontentsaftertitlepage
+ \contents
+ \global\let\contents = \relax
+ \global\let\shortcontents = \relax
+ \fi
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+% Settings used for typesetting titles: no hyphenation, no indentation,
+% don't worry much about spacing, ragged right. This should be used
+% inside a \vbox, and fonts need to be set appropriately first. Because
+% it is always used for titles, nothing else, we call \rmisbold. \par
+% should be specified before the end of the \vbox, since a vbox is a group.
+%
+\def\raggedtitlesettings{%
+ \rmisbold
+ \hyphenpenalty=10000
+ \parindent=0pt
+ \tolerance=5000
+ \ptexraggedright
+}
+
+% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\parseargdef\title{%
+ \checkenv\titlepage
+ \vbox{\titlefonts \raggedtitlesettings #1\par}%
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+ \checkenv\titlepage
+ {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+ \def\temp{\quotation}%
+ \ifx\thisenv\temp
+ \def\quotationauthor{#1}% printed in \Equotation.
+ \else
+ \checkenv\titlepage
+ \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+ {\secfonts\rmisbold \leftline{#1}}%
+ \fi
+}
+
+
+% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline % headline on even pages
+\newtoks\oddheadline % headline on odd pages
+\newtoks\evenfootline % footline on even pages
+\newtoks\oddfootline % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+ \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+ %
+ % Leave some space for the footline. Hopefully ok to assume
+ % @evenfooting will not be used by itself.
+ \global\advance\pageheight by -12pt
+ \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+% @evenheadingmarks top \thischapter <- chapter at the top of a page
+% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page
+%
+% The same set of arguments for:
+%
+% @oddheadingmarks
+% @evenfootingmarks
+% @oddfootingmarks
+% @everyheadingmarks
+% @everyfootingmarks
+
+\def\evenheadingmarks{\headingmarks{even}{heading}}
+\def\oddheadingmarks{\headingmarks{odd}{heading}}
+\def\evenfootingmarks{\headingmarks{even}{footing}}
+\def\oddfootingmarks{\headingmarks{odd}{footing}}
+\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
+ \headingmarks{odd}{heading}{#1} }
+\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
+ \headingmarks{odd}{footing}{#1} }
+% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
+\def\headingmarks#1#2#3 {%
+ \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
+ \global\expandafter\let\csname get#1#2marks\endcsname \temp
+}
+
+\everyheadingmarks bottom
+\everyfootingmarks bottom
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\headingsoff{% non-global headings elimination
+ \evenheadline={\hfil}\evenfootline={\hfil}%
+ \oddheadline={\hfil}\oddfootline={\hfil}%
+}
+
+\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting
+\HEADINGSoff % it's the default
+
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\thisisundefined
+\def\today{%
+ \number\day\space
+ \ifcase\month
+ \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+ \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+ \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+ \fi
+ \space\number\year}
+\fi
+
+% @settitle line... specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemindicate{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil\relax
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. However, if
+ % what follows is an environment such as @example, there will be no
+ % \parskip glue; then the negative vskip we just inserted would
+ % cause the example and the item to crash together. So we use this
+ % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+ % \parskip glue after all. Section titles are handled this way also.
+ %
+ \penalty 10001
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line.
+ \noindent
+ % Do this with kerns and \unhbox so that if there is a footnote in
+ % the item text, it can migrate to the main vertical list and
+ % eventually be printed.
+ \nobreak\kern-\tableindent
+ \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+ \unhbox0
+ \nobreak\kern\dimen0
+ \endgroup
+ \itemxneedsnegativevskiptrue
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+ \let\itemindex\gobble
+ \tablecheck{table}%
+}
+\envdef\ftable{%
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablecheck{ftable}%
+}
+\envdef\vtable{%
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+ \ifnum \the\catcode`\^^M=\active
+ \endgroup
+ \errmessage{This command won't work in this context; perhaps the problem is
+ that we are \inenvironment\thisenv}%
+ \def\next{\doignore{#1}}%
+ \else
+ \let\next\tablex
+ \fi
+ \next
+}
+\def\tablex#1{%
+ \def\itemindicate{#1}%
+ \parsearg\tabley
+}
+\def\tabley#1{%
+ {%
+ \makevalueexpandable
+ \edef\temp{\noexpand\tablez #1\space\space\space}%
+ \expandafter
+ }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+ \aboveenvbreak
+ \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+ \ifnum 0#2>0 \tableindent=#2\mil \fi
+ \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+ \itemmax=\tableindent
+ \advance \itemmax by -\itemmargin
+ \advance \leftskip by \tableindent
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi
+ \let\item = \internalBitem
+ \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+ \aboveenvbreak
+ \itemmax=\itemindent
+ \advance\itemmax by -\itemmargin
+ \advance\leftskip by \itemindent
+ \exdentamount=\itemindent
+ \parindent=0pt
+ \parskip=\smallskipamount
+ \ifdim\parskip=0pt \parskip=2pt \fi
+ %
+ % Try typesetting the item mark that if the document erroneously says
+ % something like @itemize @samp (intending @table), there's an error
+ % right away at the @itemize. It's not the best error message in the
+ % world, but it's better than leaving it to the @item. This means if
+ % the user wants an empty mark, they have to say @w{} not just @w.
+ \def\itemcontents{#1}%
+ \setbox0 = \hbox{\itemcontents}%
+ %
+ % @itemize with no arg is equivalent to @itemize @bullet.
+ \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ %
+ \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+ \advance\itemno by 1 % for enumerations
+ {\let\par=\endgraf \smallbreak}% reasonable place to break
+ {%
+ % If the document has an @itemize directly after a section title, a
+ % \nobreak will be last on the list, and \sectionheading will have
+ % done a \vskip-\parskip. In that case, we don't want to zero
+ % parskip, or the item text will crash with the heading. On the
+ % other hand, when there is normal text preceding the item (as there
+ % usually is), we do want to zero parskip, or there would be too much
+ % space. In that case, we won't have a \nobreak before. At least
+ % that's the theory.
+ \ifnum\lastpenalty<10000 \parskip=0in \fi
+ \noindent
+ \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ %
+ \vadjust{\penalty 1200}}% not good to break after first line of item.
+ \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @columnfractions .25 .3 .45
+% @item ...
+%
+% Numbers following @columnfractions are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1. We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+ \global\advance\colcount by 1
+ \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+ \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+ \def\firstarg{#1}%
+ \ifx\firstarg\xendsetuptable
+ \let\go = \relax
+ \else
+ \ifx\firstarg\xcolumnfractions
+ \global\setpercenttrue
+ \else
+ \ifsetpercent
+ \let\go\pickupwholefraction
+ \else
+ \global\advance\colcount by 1
+ \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+ % separator; typically that is always in the input, anyway.
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi
+ \fi
+ \ifx\go\pickupwholefraction
+ % Put the argument back for the \pickupwholefraction call, so
+ % we'll always have a period there to be parsed.
+ \def\go{\pickupwholefraction#1}%
+ \else
+ \let\go = \setuptable
+ \fi%
+ \fi
+ \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry. \everycr resets \everytab so we don't have to
+% undo it ourselves.
+\def\headitemfont{\b}% for people to use in the template row; not changeable
+\def\headitem{%
+ \checkenv\multitable
+ \crcr
+ \global\everytab={\bf}% can't use \headitemfont since the parsing differs
+ \the\everytab % for the first item
+}%
+%
+% A \tab used to include \hskip1sp. But then the space in a template
+% line is not enough. That is bad. So let's go back to just `&' until
+% we again encounter the problem the 1sp was intended to solve.
+% --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab % insert after every tab.
+%
+\envdef\multitable{%
+ \vskip\parskip
+ \startsavinginserts
+ %
+ % @item within a multitable starts a normal row.
+ % We use \def instead of \let so that if one of the multitable entries
+ % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+ % \endtemplate) expanding \doitemize.
+ \def\item{\crcr}%
+ %
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ %
+ \everycr = {%
+ \noalign{%
+ \global\everytab={}%
+ \global\colcount=0 % Reset the column counter.
+ % Check for saved footnotes, etc.
+ \checkinserts
+ % Keeps underfull box messages off when table breaks over pages.
+ %\filbreak
+ % Maybe so, but it also creates really weird page breaks when the
+ % table breaks over pages. Wouldn't \vfil be better? Wait until the
+ % problem manifests itself, so it can be fixed for real --karl.
+ }%
+ }%
+ %
+ \parsearg\domultitable
+}
+\def\domultitable#1{%
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+ \halign\bgroup &%
+ \global\advance\colcount by 1
+ \multistrut
+ \vtop{%
+ % Use the current \colcount to find the correct column width:
+ \hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively
+ % marking characters.
+ \noindent\ignorespaces##\unskip\multistrut
+ }\cr
+}
+\def\Emultitable{%
+ \crcr
+ \egroup % end the \halign
+ \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+ \def\multistrut{\strut}% just use the standard line spacing
+ %
+ % Compute \multitablelinespace (if not defined by user) for use in
+ % \multitableparskip calculation. We used define \multistrut based on
+ % this, but (ironically) that caused the spacing to be off.
+ % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+% Test to see if parskip is larger than space between lines of
+% table. If not, do nothing.
+% If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed. They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested. But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+ \expandafter\let\csname #1\endcsname = \relax
+ \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+ % Scan in ``verbatim'' mode:
+ \obeylines
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \spaceisspace
+ %
+ % Count number of #1's that we've seen.
+ \doignorecount = 0
+ %
+ % Swallow text until we reach the matching `@end #1'.
+ \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+ \obeylines %
+ %
+ \gdef\dodoignore#1{%
+ % #1 contains the command name as a string, e.g., `ifinfo'.
+ %
+ % Define a command to find the next `@end #1'.
+ \long\def\doignoretext##1^^M@end #1{%
+ \doignoretextyyy##1^^M@#1\_STOP_}%
+ %
+ % And this command to find another #1 command, at the beginning of a
+ % line. (Otherwise, we would consider a line `@c @ifset', for
+ % example, to count as an @ifset for nesting.)
+ \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+ %
+ % And now expand that command.
+ \doignoretext ^^M%
+ }%
+}
+
+\def\doignoreyyy#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty % Nothing found.
+ \let\next\doignoretextzzz
+ \else % Found a nested condition, ...
+ \advance\doignorecount by 1
+ \let\next\doignoretextyyy % ..., look for another.
+ % If we're here, #1 ends with ^^M\ifinfo (for example).
+ \fi
+ \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+ \ifnum\doignorecount = 0 % We have just found the outermost @end.
+ \let\next\enddoignore
+ \else % Still inside a nested condition.
+ \advance\doignorecount by -1
+ \let\next\doignoretext % Look for the next @end.
+ \fi
+ \next
+}
+
+% Finish off ignored text.
+{ \obeylines%
+ % Ignore anything after the last `@end #1'; this matters in verbatim
+ % environments, where otherwise the newline after an ignored conditional
+ % would result in a blank line in the output.
+ \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ {%
+ \makevalueexpandable
+ \def\temp{#2}%
+ \edef\next{\gdef\makecsname{SET#1}}%
+ \ifx\temp\empty
+ \next{}%
+ \else
+ \setzzz#2\endsetzzz
+ \fi
+ }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+ {%
+ \makevalueexpandable
+ \global\expandafter\let\csname SET#1\endcsname=\relax
+ }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+ \catcode`\- = \active \catcode`\_ = \active
+ %
+ \gdef\makevalueexpandable{%
+ \let\value = \expandablevalue
+ % We don't want these characters active, ...
+ \catcode`\-=\other \catcode`\_=\other
+ % ..., but we might end up with active ones in the argument if
+ % we're called from @code, as @code{@value{foo-bar_}}, though.
+ % So \let them to their normal equivalents.
+ \let-\realdash \let_\normalunderscore
+ }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file. This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {[No value for ``#1'']}%
+ \message{Variable `#1', used in @value, is not set.}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+ {%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname SET#2\endcsname\relax
+ #1% If not set, redefine \next.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end executes the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written
+% without the @) is in fact defined. We can only feasibly check at the
+% TeX level, so something like `mathcode' is going to considered
+% defined even though it is not a Texinfo command.
+%
+\makecond{ifcommanddefined}
+\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}}
+%
+\def\doifcmddefined#1#2{{%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname #2\endcsname\relax
+ #1% If not defined, \let\next as above.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifcmddefinedfail{\doignore{ifcommanddefined}}
+
+% @ifcommandnotdefined CMD ... handled similar to @ifclear above.
+\makecond{ifcommandnotdefined}
+\def\ifcommandnotdefined{%
+ \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}}
+\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}}
+
+% Set the `txicommandconditionals' variable, so documents have a way to
+% test if the @ifcommand...defined conditionals are available.
+\set txicommandconditionals
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{% % Define @#1index
+ \noexpand\doindex{#1}}
+}
+
+% @defindex foo == \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{%
+ \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+ % Only do \closeout if we haven't already done it, else we'll end up
+ % closing the target index.
+ \expandafter \ifx\csname donesynindex#2\endcsname \relax
+ % The \closeout helps reduce unnecessary open files; the limit on the
+ % Acorn RISC OS is a mere 16 files.
+ \expandafter\closeout\csname#2indfile\endcsname
+ \expandafter\let\csname donesynindex#2\endcsname = 1
+ \fi
+ % redefine \fooindfile:
+ \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+ \expandafter\let\csname#2indfile\endcsname=\temp
+ % redefine \fooindex:
+ \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+ \escapechar = `\\ % use backslash in output files.
+ \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+ \def\ {\realbackslash\space }%
+ %
+ % Need these unexpandable (because we define \tt as a dummy)
+ % definitions when @{ or @} appear in index entry text. Also, more
+ % complicated, when \tex is in effect and \{ is a \delimiter again.
+ % We can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters. Perhaps we
+ % should define @lbrace and @rbrace commands a la @comma.
+ \def\{{{\tt\char123}}%
+ \def\}{{\tt\char125}}%
+ %
+ % I don't entirely understand this, but when an index entry is
+ % generated from a macro call, the \endinput which \scanmacro inserts
+ % causes processing to be prematurely terminated. This is,
+ % apparently, because \indexsorttmp is fully expanded, and \endinput
+ % is an expandable command. The redefinition below makes \endinput
+ % disappear altogether for that purpose -- although logging shows that
+ % processing continues to some further point. On the other hand, it
+ % seems \endinput does not hurt in the printed index arg, since that
+ % is still getting written without apparent harm.
+ %
+ % Sample source (mac-idx3.tex, reported by Graham Percival to
+ % help-texinfo, 22may06):
+ % @macro funindex {WORD}
+ % @findex xyz
+ % @end macro
+ % ...
+ % @funindex commtest
+ %
+ % The above is not enough to reproduce the bug, but it gives the flavor.
+ %
+ % Sample whatsit resulting:
+ % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+ %
+ % So:
+ \let\endinput = \empty
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% For the aux and toc files, @ is the escape character. So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files). When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+ \def\@{@@}%
+ \def\ {@ }%
+ \let\{ = \lbraceatcmd
+ \let\} = \rbraceatcmd
+ %
+ % Do the redefinitions.
+ \commondummies
+ \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+ %
+ % \definedummyword defines \#1 as \string\#1\space, thus effectively
+ % preventing its expansion. This is used only for control words,
+ % not control letters, because the \space would be incorrect for
+ % control characters, but is needed to separate the control word
+ % from whatever follows.
+ %
+ % For control letters, we have \definedummyletter, which omits the
+ % space.
+ %
+ % These can be used both for control words that take an argument and
+ % those that do not. If it is followed by {arg} in the input, then
+ % that will dutifully get written to the index (or wherever).
+ %
+ \def\definedummyword ##1{\def##1{\string##1\space}}%
+ \def\definedummyletter##1{\def##1{\string##1}}%
+ \let\definedummyaccent\definedummyletter
+ %
+ \commondummiesnofonts
+ %
+ \definedummyletter\_%
+ \definedummyletter\-%
+ %
+ % Non-English letters.
+ \definedummyword\AA
+ \definedummyword\AE
+ \definedummyword\DH
+ \definedummyword\L
+ \definedummyword\O
+ \definedummyword\OE
+ \definedummyword\TH
+ \definedummyword\aa
+ \definedummyword\ae
+ \definedummyword\dh
+ \definedummyword\exclamdown
+ \definedummyword\l
+ \definedummyword\o
+ \definedummyword\oe
+ \definedummyword\ordf
+ \definedummyword\ordm
+ \definedummyword\questiondown
+ \definedummyword\ss
+ \definedummyword\th
+ %
+ % Although these internal commands shouldn't show up, sometimes they do.
+ \definedummyword\bf
+ \definedummyword\gtr
+ \definedummyword\hat
+ \definedummyword\less
+ \definedummyword\sf
+ \definedummyword\sl
+ \definedummyword\tclose
+ \definedummyword\tt
+ %
+ \definedummyword\LaTeX
+ \definedummyword\TeX
+ %
+ % Assorted special characters.
+ \definedummyword\arrow
+ \definedummyword\bullet
+ \definedummyword\comma
+ \definedummyword\copyright
+ \definedummyword\registeredsymbol
+ \definedummyword\dots
+ \definedummyword\enddots
+ \definedummyword\entrybreak
+ \definedummyword\equiv
+ \definedummyword\error
+ \definedummyword\euro
+ \definedummyword\expansion
+ \definedummyword\geq
+ \definedummyword\guillemetleft
+ \definedummyword\guillemetright
+ \definedummyword\guilsinglleft
+ \definedummyword\guilsinglright
+ \definedummyword\lbracechar
+ \definedummyword\leq
+ \definedummyword\minus
+ \definedummyword\ogonek
+ \definedummyword\pounds
+ \definedummyword\point
+ \definedummyword\print
+ \definedummyword\quotedblbase
+ \definedummyword\quotedblleft
+ \definedummyword\quotedblright
+ \definedummyword\quoteleft
+ \definedummyword\quoteright
+ \definedummyword\quotesinglbase
+ \definedummyword\rbracechar
+ \definedummyword\result
+ \definedummyword\textdegree
+ %
+ % We want to disable all macros so that they are not expanded by \write.
+ \macrolist
+ %
+ \normalturnoffactive
+ %
+ % Handle some cases of @value -- where it does not contain any
+ % (non-fully-expandable) commands.
+ \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter\!%
+ \definedummyaccent\"%
+ \definedummyaccent\'%
+ \definedummyletter\*%
+ \definedummyaccent\,%
+ \definedummyletter\.%
+ \definedummyletter\/%
+ \definedummyletter\:%
+ \definedummyaccent\=%
+ \definedummyletter\?%
+ \definedummyaccent\^%
+ \definedummyaccent\`%
+ \definedummyaccent\~%
+ \definedummyword\u
+ \definedummyword\v
+ \definedummyword\H
+ \definedummyword\dotaccent
+ \definedummyword\ogonek
+ \definedummyword\ringaccent
+ \definedummyword\tieaccent
+ \definedummyword\ubaraccent
+ \definedummyword\udotaccent
+ \definedummyword\dotless
+ %
+ % Texinfo font commands.
+ \definedummyword\b
+ \definedummyword\i
+ \definedummyword\r
+ \definedummyword\sansserif
+ \definedummyword\sc
+ \definedummyword\slanted
+ \definedummyword\t
+ %
+ % Commands that take arguments.
+ \definedummyword\abbr
+ \definedummyword\acronym
+ \definedummyword\anchor
+ \definedummyword\cite
+ \definedummyword\code
+ \definedummyword\command
+ \definedummyword\dfn
+ \definedummyword\dmn
+ \definedummyword\email
+ \definedummyword\emph
+ \definedummyword\env
+ \definedummyword\file
+ \definedummyword\image
+ \definedummyword\indicateurl
+ \definedummyword\inforef
+ \definedummyword\kbd
+ \definedummyword\key
+ \definedummyword\math
+ \definedummyword\option
+ \definedummyword\pxref
+ \definedummyword\ref
+ \definedummyword\samp
+ \definedummyword\strong
+ \definedummyword\tie
+ \definedummyword\uref
+ \definedummyword\url
+ \definedummyword\var
+ \definedummyword\verb
+ \definedummyword\w
+ \definedummyword\xref
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names. It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+ % Accent commands should become @asis.
+ \def\definedummyaccent##1{\let##1\asis}%
+ % We can just ignore other control letters.
+ \def\definedummyletter##1{\let##1\empty}%
+ % All control words become @asis by default; overrides below.
+ \let\definedummyword\definedummyaccent
+ %
+ \commondummiesnofonts
+ %
+ % Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the active chars like <, >, |, etc.
+ % Likewise with the other plain tex font commands.
+ %\let\tt=\asis
+ %
+ \def\ { }%
+ \def\@{@}%
+ \def\_{\normalunderscore}%
+ \def\-{}% @- shouldn't affect sorting
+ %
+ % Unfortunately, texindex is not prepared to handle braces in the
+ % content at all. So for index sorting, we map @{ and @} to strings
+ % starting with |, since that ASCII character is between ASCII { and }.
+ \def\{{|a}%
+ \def\lbracechar{|a}%
+ %
+ \def\}{|b}%
+ \def\rbracechar{|b}%
+ %
+ % Non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\DH{DZZ}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\TH{ZZZ}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\dh{dzz}%
+ \def\exclamdown{!}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ \def\o{o}%
+ \def\questiondown{?}%
+ \def\ss{ss}%
+ \def\th{zzz}%
+ %
+ \def\LaTeX{LaTeX}%
+ \def\TeX{TeX}%
+ %
+ % Assorted special characters.
+ % (The following {} will end up in the sort string, but that's ok.)
+ \def\arrow{->}%
+ \def\bullet{bullet}%
+ \def\comma{,}%
+ \def\copyright{copyright}%
+ \def\dots{...}%
+ \def\enddots{...}%
+ \def\equiv{==}%
+ \def\error{error}%
+ \def\euro{euro}%
+ \def\expansion{==>}%
+ \def\geq{>=}%
+ \def\guillemetleft{<<}%
+ \def\guillemetright{>>}%
+ \def\guilsinglleft{<}%
+ \def\guilsinglright{>}%
+ \def\leq{<=}%
+ \def\minus{-}%
+ \def\point{.}%
+ \def\pounds{pounds}%
+ \def\print{-|}%
+ \def\quotedblbase{"}%
+ \def\quotedblleft{"}%
+ \def\quotedblright{"}%
+ \def\quoteleft{`}%
+ \def\quoteright{'}%
+ \def\quotesinglbase{,}%
+ \def\registeredsymbol{R}%
+ \def\result{=>}%
+ \def\textdegree{o}%
+ %
+ \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax
+ \else \indexlquoteignore \fi
+ %
+ % We need to get rid of all macros, leaving only the arguments (if present).
+ % Of course this is not nearly correct, but it is the best we can do for now.
+ % makeinfo does not expand macros in the argument to @deffn, which ends up
+ % writing an index entry, and texindex isn't prepared for an index sort entry
+ % that starts with \.
+ %
+ % Since macro invocations are followed by braces, we can just redefine them
+ % to take a single TeX argument. The case of a macro invocation that
+ % goes to end-of-line is not handled.
+ %
+ \macrolist
+}
+
+% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us
+% ignore left quotes in the sort term.
+{\catcode`\`=\active
+ \gdef\indexlquoteignore{\let`=\empty}}
+
+\let\indexbackslash=0 %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+ \iflinks
+ {%
+ % Store the main index entry text (including the third arg).
+ \toks0 = {#2}%
+ % If third arg is present, precede it with a space.
+ \def\thirdarg{#3}%
+ \ifx\thirdarg\empty \else
+ \toks0 = \expandafter{\the\toks0 \space #3}%
+ \fi
+ %
+ \edef\writeto{\csname#1indfile\endcsname}%
+ %
+ \safewhatsit\dosubindwrite
+ }%
+ \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+ \fi
+ %
+ % Remember, we are within a group.
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % Process the index entry with all font commands turned off, to
+ % get the string to sort by.
+ {\indexnofonts
+ \edef\temp{\the\toks0}% need full expansion
+ \xdef\indexsorttmp{\temp}%
+ }%
+ %
+ % Set up the complete index entry, with both the sort key and
+ % the original text, including any font commands. We write
+ % three arguments to \entry to the .?? file (four in the
+ % subentry case), texindex reduces to two when writing the .??s
+ % sorted result.
+ \edef\temp{%
+ \write\writeto{%
+ \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+ }%
+ \temp
+}
+
+% Take care of unwanted page breaks/skips around a whatsit:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again. Otherwise, the whatsit generated by the
+% \write or \pdfdest will make \lastskip zero. The result is that
+% sequences like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode. We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip. \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip. The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
+% ..., ready, GO:
+%
+\def\safewhatsit#1{\ifhmode
+ #1%
+ \else
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \whatsitskip = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \whatsitpenalty = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\whatsitskip glue we're inserting is preceded by a
+ % non-discardable item, therefore it is not a potential
+ % breakpoint, therefore no \nobreak needed.
+ \ifx\lastskipmacro\zeroskipmacro
+ \else
+ \vskip-\whatsitskip
+ \fi
+ %
+ #1%
+ %
+ \ifx\lastskipmacro\zeroskipmacro
+ % If \lastskip was zero, perhaps the last item was a penalty, and
+ % perhaps it was >=10000, e.g., a \nobreak. In that case, we want
+ % to re-insert the same penalty (values >10000 are used for various
+ % signals); since we just inserted a non-discardable item, any
+ % following glue (such as a \parskip) would be a breakpoint. For example:
+ % @deffn deffn-whatever
+ % @vindex index-whatever
+ % Description.
+ % would allow a break between the index-whatever whatsit
+ % and the "Description." paragraph.
+ \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
+ \else
+ % On the other hand, if we had a nonzero \lastskip,
+ % this make-up glue would be preceded by a non-discardable item
+ % (the whatsit from the \write), so we must insert a \nobreak.
+ \nobreak\vskip\whatsitskip
+ \fi
+\fi}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \smallfonts \rm
+ \tolerance = 9500
+ \plainfrenchspacing
+ \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+ %
+ % See if the index file exists and is nonempty.
+ % Change catcode of @ here so that if the index file contains
+ % \initial {@}
+ % as its first line, TeX doesn't complain about mismatched braces
+ % (because it thinks @} is a control sequence).
+ \catcode`\@ = 11
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ \putwordIndexNonexistent
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ \putwordIndexIsEmpty
+ \else
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \def\indexbackslash{\backslashcurfont}%
+ \catcode`\\ = 0
+ \escapechar = `\\
+ \begindoublecolumns
+ \input \jobname.#1s
+ \enddoublecolumns
+ \fi
+ \fi
+ \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+ % Some minor font changes for the special characters.
+ \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+ %
+ % Remove any glue we may have, we'll be inserting our own.
+ \removelastskip
+ %
+ % We like breaks before the index initials, so insert a bonus.
+ \nobreak
+ \vskip 0pt plus 3\baselineskip
+ \penalty 0
+ \vskip 0pt plus -3\baselineskip
+ %
+ % Typeset the initial. Making this add up to a whole number of
+ % baselineskips increases the chance of the dots lining up from column
+ % to column. It still won't often be perfect, because of the stretch
+ % we need before each entry, but it's better.
+ %
+ % No shrink because it confuses \balancecolumns.
+ \vskip 1.67\baselineskip plus .5\baselineskip
+ \leftline{\secbf #1}%
+ % Do our best not to break after the initial.
+ \nobreak
+ \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin. It is used for index
+% and table of contents entries. The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+% \def\entry#1#2{...
+% But this freezes the catcodes in the argument, and can cause problems to
+% @code, which sets - active. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+% The right solution is to prevent \entry from swallowing the whole text.
+% --kasal, 21nov03
+\def\entry{%
+ \begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent = 2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % A bit of stretch before each entry for the benefit of balancing
+ % columns.
+ \vskip 0pt plus1pt
+ %
+ % When reading the text of entry, convert explicit line breaks
+ % from @* into spaces. The user might give these in long section
+ % titles, for instance.
+ \def\*{\unskip\space\ignorespaces}%
+ \def\entrybreak{\hfil\break}%
+ %
+ % Swallow the left brace of the text (first parameter):
+ \afterassignment\doentry
+ \let\temp =
+}
+\def\entrybreak{\unskip\space\ignorespaces}%
+\def\doentry{%
+ \bgroup % Instead of the swallowed brace.
+ \noindent
+ \aftergroup\finishentry
+ % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+ % #1 is the page number.
+ %
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \setbox\boxA = \hbox{#1}%
+ \ifdim\wd\boxA = 0pt
+ \ %
+ \else
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ifpdf
+ \pdfgettoks#1.%
+ \ \the\toksA
+ \else
+ \ #1%
+ \fi
+ \fi
+ \par
+ \endgroup
+}
+
+% Like plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+ \parfillskip=0in
+ \parskip=0in
+ \hangindent=1in
+ \hangafter=1
+ \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+ \ifpdf
+ \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+ \else
+ #2
+ \fi
+ \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+ % Grab any single-column material above us.
+ \output = {%
+ %
+ % Here is a possibility not foreseen in manmac: if we accumulate a
+ % whole lot of material, we might end up calling this \output
+ % routine twice in a row (see the doublecol-lose test, which is
+ % essentially a couple of indexes with @setchapternewpage off). In
+ % that case we just ship out what is in \partialpage with the normal
+ % output routine. Generally, \partialpage will be empty when this
+ % runs and this will be a no-op. See the indexspread.tex test case.
+ \ifvoid\partialpage \else
+ \onepageout{\pagecontents\partialpage}%
+ \fi
+ %
+ \global\setbox\partialpage = \vbox{%
+ % Unvbox the main output page.
+ \unvbox\PAGE
+ \kern-\topskip \kern\baselineskip
+ }%
+ }%
+ \eject % run that output routine to set \partialpage
+ %
+ % Use the double-column output routine for subsequent pages.
+ \output = {\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it in one place.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +-<1pt)
+ % as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@ = \vsize
+ \divide\dimen@ by 2
+ \advance\dimen@ by -\ht\partialpage
+ %
+ % box0 will be the left-hand column, box2 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255
+ \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+ \unvbox\partialpage
+ %
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize
+ \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+ % The following penalty ensures that the page builder is exercised
+ % _before_ we change the output routine. This is necessary in the
+ % following situation:
+ %
+ % The last section of the index consists only of a single entry.
+ % Before this section, \pagetotal is less than \pagegoal, so no
+ % break occurs before the last section starts. However, the last
+ % section, consisting of \initial and the single \entry, does not
+ % fit on the page and has to be broken off. Without the following
+ % penalty the page builder will not be exercised until \eject
+ % below, and by that time we'll already have changed the output
+ % routine to the \balancecolumns version, so the next-to-last
+ % double-column page will be processed with \balancecolumns, which
+ % is wrong: The two columns will go to the main vertical list, with
+ % the broken-off section in the recent contributions. As soon as
+ % the output routine finishes, TeX starts reconsidering the page
+ % break. The two columns and the broken-off section both fit on the
+ % page, because the two columns now take up only half of the page
+ % goal. When TeX sees \eject from below which follows the final
+ % section, it invokes the new output routine that we've set after
+ % \balancecolumns below; \onepageout will try to fit the two columns
+ % and the final section into the vbox of \pageheight (see
+ % \pagebody), causing an overfull box.
+ %
+ % Note that glue won't work here, because glue does not exercise the
+ % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+ \penalty0
+ %
+ \output = {%
+ % Split the last of the double-column material. Leave it on the
+ % current page, no automatic page break.
+ \balancecolumns
+ %
+ % If we end up splitting too much material for the current page,
+ % though, there will be another page break right after this \output
+ % invocation ends. Having called \balancecolumns once, we do not
+ % want to call it again. Therefore, reset \output to its normal
+ % definition right away. (We hope \balancecolumns will never be
+ % called on to balance too much material, but if it is, this makes
+ % the output somewhat more palatable.)
+ \global\output = {\onepageout{\pagecontents\PAGE}}%
+ }%
+ \eject
+ \endgroup % started in \begindoublecolumns
+ %
+ % \pagegoal was set to the doubled \vsize above, since we restarted
+ % the current page. We're now back to normal single-column
+ % typesetting, so reset \pagegoal to the normal \vsize (after the
+ % \endgroup where \vsize got restored).
+ \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+ \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2 % target to split to
+ %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {%
+ \vbadness = 10000
+ \loop
+ \global\setbox3 = \copy0
+ \global\setbox1 = \vsplit3 to \dimen@
+ \ifdim\ht3>\dimen@
+ \global\advance\dimen@ by 1pt
+ \repeat
+ }%
+ %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ %
+ \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% Let's start with @part.
+\outer\parseargdef\part{\partzzz{#1}}
+\def\partzzz#1{%
+ \chapoddpage
+ \null
+ \vskip.3\vsize % move it down on the page a bit
+ \begingroup
+ \noindent \titlefonts\rmisbold #1\par % the text
+ \let\lastnode=\empty % no node to associate with
+ \writetocentry{part}{#1}{}% but put it in the toc
+ \headingsoff % no headline or footline on the part page
+ \chapoddpage
+ \endgroup
+}
+
+% \unnumberedno is an oxymoron. But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number". We avoid collisions with chapter
+% numbers by starting them at 10000. (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno \secno=0
+\newcount\subsecno \subsecno=0
+\newcount\subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+ \ifnum\appendixno=`A A%
+ \else\ifnum\appendixno=`B B%
+ \else\ifnum\appendixno=`C C%
+ \else\ifnum\appendixno=`D D%
+ \else\ifnum\appendixno=`E E%
+ \else\ifnum\appendixno=`F F%
+ \else\ifnum\appendixno=`G G%
+ \else\ifnum\appendixno=`H H%
+ \else\ifnum\appendixno=`I I%
+ \else\ifnum\appendixno=`J J%
+ \else\ifnum\appendixno=`K K%
+ \else\ifnum\appendixno=`L L%
+ \else\ifnum\appendixno=`M M%
+ \else\ifnum\appendixno=`N N%
+ \else\ifnum\appendixno=`O O%
+ \else\ifnum\appendixno=`P P%
+ \else\ifnum\appendixno=`Q Q%
+ \else\ifnum\appendixno=`R R%
+ \else\ifnum\appendixno=`S S%
+ \else\ifnum\appendixno=`T T%
+ \else\ifnum\appendixno=`U U%
+ \else\ifnum\appendixno=`V V%
+ \else\ifnum\appendixno=`W W%
+ \else\ifnum\appendixno=`X X%
+ \else\ifnum\appendixno=`Y Y%
+ \else\ifnum\appendixno=`Z Z%
+ % The \the is necessary, despite appearances, because \appendixletter is
+ % expanded while writing the .toc file. \char\appendixno is not
+ % expandable, thus it is written literally, thus all appendixes come out
+ % with the same letter (or @) in the toc without it.
+ \else\char\the\appendixno
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines these (using marks) as the number+name, number
+% and name of the chapter. Page headings and footings can use
+% these. @section does likewise.
+\def\thischapter{}
+\def\thischapternum{}
+\def\thischaptername{}
+\def\thissection{}
+\def\thissectionnum{}
+\def\thissectionname{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achieve this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unnlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+ % Compute the abs. sec. level:
+ \absseclevel=#2
+ \advance\absseclevel by \secbase
+ % Make sure \absseclevel doesn't fall outside the range:
+ \ifnum \absseclevel < 0
+ \absseclevel = 0
+ \else
+ \ifnum \absseclevel > 3
+ \absseclevel = 3
+ \fi
+ \fi
+ % The heading type:
+ \def\headtype{#1}%
+ \if \headtype U%
+ \ifnum \absseclevel < \unnlevel
+ \chardef\unnlevel = \absseclevel
+ \fi
+ \else
+ % Check for appendix sections:
+ \ifnum \absseclevel = 0
+ \edef\chapheadtype{\headtype}%
+ \else
+ \if \headtype A\if \chapheadtype N%
+ \errmessage{@appendix... within a non-appendix chapter}%
+ \fi\fi
+ \fi
+ % Check for numbered within unnumbered:
+ \ifnum \absseclevel > \unnlevel
+ \def\headtype{U}%
+ \else
+ \chardef\unnlevel = 3
+ \fi
+ \fi
+ % Now print the heading:
+ \if \headtype U%
+ \ifcase\absseclevel
+ \unnumberedzzz{#3}%
+ \or \unnumberedseczzz{#3}%
+ \or \unnumberedsubseczzz{#3}%
+ \or \unnumberedsubsubseczzz{#3}%
+ \fi
+ \else
+ \if \headtype A%
+ \ifcase\absseclevel
+ \appendixzzz{#3}%
+ \or \appendixsectionzzz{#3}%
+ \or \appendixsubseczzz{#3}%
+ \or \appendixsubsubseczzz{#3}%
+ \fi
+ \else
+ \ifcase\absseclevel
+ \chapterzzz{#3}%
+ \or \seczzz{#3}%
+ \or \numberedsubseczzz{#3}%
+ \or \numberedsubsubseczzz{#3}%
+ \fi
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered. Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v. By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+ % section resetting is \global in case the chapter is in a group, such
+ % as an @include file.
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\chapno by 1
+ %
+ % Used for \float.
+ \gdef\chaplevelprefix{\the\chapno.}%
+ \resetallfloatnos
+ %
+ % \putwordChapter can contain complex things in translations.
+ \toks0=\expandafter{\putwordChapter}%
+ \message{\the\toks0 \space \the\chapno}%
+ %
+ % Write the actual heading.
+ \chapmacro{#1}{Ynumbered}{\the\chapno}%
+ %
+ % So @section and the like are numbered underneath this chapter.
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz
+%
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \gdef\chaplevelprefix{\appendixletter.}%
+ \resetallfloatnos
+ %
+ % \putwordAppendix can contain complex things in translations.
+ \toks0=\expandafter{\putwordAppendix}%
+ \message{\the\toks0 \space \appendixletter}%
+ %
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ %
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+}
+
+% normally unnmhead0 calls unnumberedzzz:
+\outer\parseargdef\unnumbered{\unnmhead0{#1}}
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % Since an unnumbered has no number, no prefix for figures.
+ \global\let\chaplevelprefix = \empty
+ \resetallfloatnos
+ %
+ % This used to be simply \message{#1}, but TeX fully expands the
+ % argument to \message. Therefore, if #1 contained @-commands, TeX
+ % expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+ % expanded @cite (which turns out to cause errors because \cite is meant
+ % to be executed, not expanded).
+ %
+ % Anyway, we don't want the fully-expanded definition of @cite to appear
+ % as a result of the \message, we just want `@cite' itself. We use
+ % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+ % simply yielding the contents of <toks register>. (We also do this for
+ % the toc entries.)
+ \toks0 = {#1}%
+ \message{(\the\toks0)}%
+ %
+ \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+ %
+ \global\let\section = \unnumberedsec
+ \global\let\subsection = \unnumberedsubsec
+ \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+ % Well, we could do the following in a group, but that would break
+ % an assumption that \chapmacro is called at the outermost level.
+ % Thus we are safer this way: --kasal, 24feb04
+ \let\centerparametersmaybe = \centerparameters
+ \unnmhead0{#1}%
+ \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+%
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+% normally calls appendixsectionzzz:
+\outer\parseargdef\appendixsection{\apphead1{#1}}
+\def\appendixsectionzzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+% normally calls unnumberedseczzz:
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}}
+\def\unnumberedseczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+%
+% normally calls numberedsubseczzz:
+\outer\parseargdef\numberedsubsec{\numhead2{#1}}
+\def\numberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+% normally calls appendixsubseczzz:
+\outer\parseargdef\appendixsubsec{\apphead2{#1}}
+\def\appendixsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+% normally calls unnumberedsubseczzz:
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}}
+\def\unnumberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+%
+% normally numberedsubsubseczzz:
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}}
+\def\numberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynumbered}%
+ {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% normally appendixsubsubseczzz:
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}}
+\def\appendixsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% normally unnumberedsubsubseczzz:
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}}
+\def\unnumberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+\def\majorheading{%
+ {\advance\chapheadingskip by 10pt \chapbreak }%
+ \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip \nobreak
+ \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+% Parameter controlling skip before chapter headings (if needed)
+\newskip\chapheadingskip
+
+% Define plain chapter starts, and page on/off switching for it.
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+% Because \domark is called before \chapoddpage, the filler page will
+% get the headings for the next chapter, which is wrong. But we don't
+% care -- we just disable all headings on the filler page.
+\def\chapoddpage{%
+ \chappager
+ \ifodd\pageno \else
+ \begingroup
+ \headingsoff
+ \null
+ \chappager
+ \endgroup
+ \fi
+}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+ % Insert the first mark before the heading break (see notes for \domark).
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
+ \gdef\thissection{}}%
+ %
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{\thischaptername}}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{}}%
+ \else\ifx\temptype\Yappendixkeyword
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\appendixletter}%
+ % \noexpand\putwordAppendix avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordAppendix{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \else
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\the\chapno}%
+ % \noexpand\putwordChapter avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordChapter{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \fi\fi\fi
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert the chapter heading break.
+ \pchapsepmacro
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ {%
+ \chapfonts \rmisbold
+ %
+ % Have to define \lastsection before calling \donoderef, because the
+ % xref code eventually uses it. On the other hand, it has to be called
+ % after \pchapsepmacro, or the headline will change too soon.
+ \gdef\lastsection{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \fi\fi\fi
+ %
+ % Write the toc entry for this chapter. Must come before the
+ % \donoderef, because we include the current node name in the toc
+ % entry, and \donoderef resets it to empty.
+ \writetocentry{\toctype}{#1}{#3}%
+ %
+ % For pdftex, we have to write out the node definition (aka, make
+ % the pdfdest) after any page break, but before the actual text has
+ % been typeset. If the destination for the pdf outline is after the
+ % text, then jumping from the outline may wind up with the text not
+ % being visible, for instance under high magnification.
+ \donoderef{#2}%
+ %
+ % Typeset the actual heading.
+ \nobreak % Avoid page breaks at the interline glue.
+ \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
+ }%
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff. We'll see. --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}%
+ \nobreak\bigskip \nobreak
+}
+\def\CHAPFopen{%
+ \global\let\chapmacro=\chfopen
+ \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles. These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\seckeyword{sec}
+%
+\def\sectionheading#1#2#3#4{%
+ {%
+ \checkenv{}% should not be in an environment.
+ %
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rmisbold
+ %
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ % Insert first mark before the heading break (see notes for \domark).
+ \let\prevsectiondefs=\lastsectiondefs
+ \ifx\temptype\Ynothingkeyword
+ \ifx\sectionlevel\seckeyword
+ \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
+ \gdef\thissection{\thissectionname}}%
+ \fi
+ \else\ifx\temptype\Yomitfromtockeyword
+ % Don't redefine \thissection.
+ \else\ifx\temptype\Yappendixkeyword
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \else
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \fi\fi\fi
+ %
+ % Go into vertical mode. Usually we'll already be there, but we
+ % don't want the following whatsit to end up in a preceding paragraph
+ % if the document didn't happen to have a blank line.
+ \par
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ % Only insert the space after the number if we have a section number.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\lastsection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \lastsection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\lastsection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\lastsection{#1}%
+ \fi\fi\fi
+ %
+ % Write the toc entry (before \donoderef). See comments in \chapmacro.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chapmacro.
+ \donoderef{#3}%
+ %
+ % Interline glue will be inserted when the vbox is completed.
+ % That glue will be a valid breakpoint for the page, since it'll be
+ % preceded by a whatsit (usually from the \donoderef, or from the
+ % \writetocentry if there was no node). We don't want to allow that
+ % break, since then the whatsits could end up on page n while the
+ % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000.
+ \nobreak
+ %
+ % Output the actual section heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
+ \hangindent=\wd0 % zero if no section number
+ \unhbox0 #1}%
+ }%
+ % Add extra space after the heading -- half of whatever came above it.
+ % Don't allow stretch, though.
+ \kern .5 \csname #2headingskip\endcsname
+ %
+ % Do not let the kern be a potential breakpoint, as it would be if it
+ % was followed by glue.
+ \nobreak
+ %
+ % We'll almost certainly start a paragraph next, so don't let that
+ % glue accumulate. (Not a breakpoint because it's preceded by a
+ % discardable item.) However, when a paragraph is not started next
+ % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out
+ % or the negative glue will cause weirdly wrong output, typically
+ % obscuring the section heading with something else.
+ \vskip-\parskip
+ %
+ % This is so the last item on the main vertical list is a known
+ % \penalty > 10000, so \startdefun, etc., can recognize the situation
+ % and do the needful.
+ \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this. The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything. This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+ \edef\writetoctype{#1}%
+ \ifx\writetoctype\omitkeyword \else
+ \iftocfileopened\else
+ \immediate\openout\tocfile = \jobname.toc
+ \global\tocfileopenedtrue
+ \fi
+ %
+ \iflinks
+ {\atdummies
+ \edef\temp{%
+ \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+ \temp
+ }%
+ \fi
+ \fi
+ %
+ % Tell \shipout to create a pdf destination on each page, if we're
+ % writing pdf. These are used in the table of contents. We can't
+ % just write one on every page because the title pages are numbered
+ % 1 and 2 (the page numbers aren't printed), and so are the first
+ % two pages of the document. Thus, we'd have two destinations named
+ % `1', and two named `2'.
+ \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care. This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+%
+\def\activecatcodes{%
+ \catcode`\"=\active
+ \catcode`\$=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
+ \catcode`\\=\active
+ \catcode`\^=\active
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+ \setupdatafile
+ \activecatcodes
+ \input \tocreadfilename
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout\tocfile
+ %
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+ %
+ % Roman numerals for page numbers.
+ \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+% redefined for the two-volume lispref. We always output on
+% \jobname.toc even if this is redefined.
+%
+\def\tocreadfilename{\jobname.toc}
+
+% Normal (long) toc.
+%
+\def\contents{%
+ \startcontents{\putwordTOC}%
+ \openin 1 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \ifeof 1 \else
+ \pdfmakeoutlines
+ \fi
+ \closein 1
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+ \startcontents{\putwordShortTOC}%
+ %
+ \let\partentry = \shortpartentry
+ \let\numchapentry = \shortchapentry
+ \let\appentry = \shortchapentry
+ \let\unnchapentry = \shortunnchapentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf
+ \let\sl=\shortcontsl \let\tt=\shortconttt
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\numsecentry##1##2##3##4{}
+ \let\appsecentry = \numsecentry
+ \let\unnsecentry = \numsecentry
+ \let\numsubsecentry = \numsecentry
+ \let\appsubsecentry = \numsecentry
+ \let\unnsubsecentry = \numsecentry
+ \let\numsubsubsecentry = \numsecentry
+ \let\appsubsubsecentry = \numsecentry
+ \let\unnsubsubsecentry = \numsecentry
+ \openin 1 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \closein 1
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+ % This space should be enough, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % But use \hss just in case.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ %
+ % We'd like to right-justify chapter numbers, but that looks strange
+ % with appendix letters. And right-justifying numbers and
+ % left-justifying letters looks strange when there is less than 10
+ % chapters. Have to read the whole toc once to know how many chapters
+ % there are before deciding ...
+ \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Parts, in the main contents. Replace the part number, which doesn't
+% exist, with an empty box. Let's hope all the numbers have the same width.
+% Also ignore the page number, which is conventionally not printed.
+\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}}
+\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}}
+%
+% Parts, in the short toc.
+\def\shortpartentry#1#2#3#4{%
+ \penalty-300
+ \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip
+ \shortchapentry{{\bf #1}}{\numeralbox}{}{}%
+}
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+ % We use M since it's probably the widest letter.
+ \setbox0 = \hbox{\putwordAppendix{} M}%
+ \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @tex ... @end tex escapes into raw TeX temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain @ character.
+
+\envdef\tex{%
+ \setupmarkupstyle{tex}%
+ \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+ \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+ \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+ \catcode `\%=14
+ \catcode `\+=\other
+ \catcode `\"=\other
+ \catcode `\|=\other
+ \catcode `\<=\other
+ \catcode `\>=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
+ \escapechar=`\\
+ %
+ % ' is active in math mode (mathcode"8000). So reset it, and all our
+ % other math active characters (just in case), to plain's definitions.
+ \mathactive
+ %
+ \let\b=\ptexb
+ \let\bullet=\ptexbullet
+ \let\c=\ptexc
+ \let\,=\ptexcomma
+ \let\.=\ptexdot
+ \let\dots=\ptexdots
+ \let\equiv=\ptexequiv
+ \let\!=\ptexexclam
+ \let\i=\ptexi
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \let\{=\ptexlbrace
+ \let\+=\tabalign
+ \let\}=\ptexrbrace
+ \let\/=\ptexslash
+ \let\*=\ptexstar
+ \let\t=\ptext
+ \expandafter \let\csname top\endcsname=\ptextop % outer
+ \let\frenchspacing=\plainfrenchspacing
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+ % =10000 instead of <10000 because of a special case in \itemzzz and
+ % \sectionheading, q.v.
+ \ifnum \lastpenalty=10000 \else
+ \advance\envskipamount by \parskip
+ \endgraf
+ \ifdim\lastskip<\envskipamount
+ \removelastskip
+ % it's not a good place to break if the last penalty was \nobreak
+ % or better ...
+ \ifnum\lastpenalty<10000 \penalty-50 \fi
+ \vskip\envskipamount
+ \fi
+ \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+ \ifhmode\par\fi % can't be in the midst of a paragraph.
+ \startsavinginserts
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt % we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ % side, and for 6pt waste from
+ % each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing = t%
+ %
+ % If this cartouche directly follows a sectioning command, we need the
+ % \parskip glue (backspaced over by default) or the cartouche can
+ % collide with the section heading.
+ \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi
+ %
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \kern3pt
+ \hsize=\cartinner
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+ \comment % For explanation, see the end of def\group.
+}
+\def\Ecartouche{%
+ \ifhmode\par\fi
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+ \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\newdimen\nonfillparindent
+\def\nonfillstart{%
+ \aboveenvbreak
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ % Turn off paragraph indentation but redefine \indent to emulate
+ % the normal \indent.
+ \nonfillparindent=\parindent
+ \parindent = 0pt
+ \let\indent\nonfillindent
+ %
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \let\exdent=\nofillexdent
+}
+
+\begingroup
+\obeyspaces
+% We want to swallow spaces (but not other tokens) after the fake
+% @indent in our nonfill-environments, where spaces are normally
+% active and set to @tie, resulting in them not being ignored after
+% @indent.
+\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}%
+\gdef\nonfillindentcheck{%
+\ifx\temp %
+\expandafter\nonfillindentgobble%
+\else%
+\leavevmode\nonfillindentbox%
+\fi%
+}%
+\endgroup
+\def\nonfillindentgobble#1{\nonfillindent}
+\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+% @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+ \ifx\SETdispenvsize\smallword
+ % end paragraph for sake of leading, in case document has no blank
+ % line. This is redundant with what happens in \aboveenvbreak, but
+ % we need to do it before changing the fonts, and it's inconvenient
+ % to change the fonts afterward.
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+\def\setsmalldispenv{%
+ \ifx\SETdispenvsize\nosmallword
+ \else
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it in one command. #1 is the env name, #2 the definition.
+\def\makedispenvdef#1#2{%
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}%
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}%
+ \expandafter\let\csname E#1\endcsname \afterenvbreak
+ \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two environment synonyms (#1 and #2) for an environment.
+\def\maketwodispenvdef#1#2#3{%
+ \makedispenvdef{#1}{#3}%
+ \makedispenvdef{#2}{#3}%
+}
+%
+% @lisp: indented, narrowed, typewriter font;
+% @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvdef{lisp}{example}{%
+ \nonfillstart
+ \tt\setupmarkupstyle{example}%
+ \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+ \gobble % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenvdef{display}{%
+ \nonfillstart
+ \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenvdef{format}{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \advance\leftskip by 0pt plus 1fill\relax
+ \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @raggedright does more-or-less normal line breaking but no right
+% justification. From plain.tex.
+\envdef\raggedright{%
+ \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax
+}
+\let\Eraggedright\par
+
+\envdef\raggedleft{%
+ \parindent=0pt \leftskip0pt plus2em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedleft\par
+
+\envdef\raggedcenter{%
+ \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedcenter\par
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins. We keep \parskip nonzero in general, since
+% we're doing normal filling. So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\makedispenvdef{quotation}{\quotationstart}
+%
+\def\quotationstart{%
+ \indentedblockstart % same as \indentedblock, but increase right margin too.
+ \ifx\nonarrowing\relax
+ \advance\rightskip by \lispnarrowing
+ \fi
+ \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+ \par
+ \ifx\quotationauthor\thisisundefined\else
+ % indent a bit.
+ \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+ \fi
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallquotation{\Equotation}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty \else
+ {\bf #1: }%
+ \fi
+}
+
+% @indentedblock is like @quotation, but indents only on the left and
+% has no optional argument.
+%
+\makedispenvdef{indentedblock}{\indentedblockstart}
+%
+\def\indentedblockstart{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+}
+
+% Keep a nonzero parskip for the environment, since we're doing normal filling.
+%
+\def\Eindentedblock{%
+ \par
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallindentedblock{\Eindentedblock}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too. Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+ \do\ \do\\\do\{\do\}\do\$\do\&%
+ \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+ \do\<\do\>\do\|\do\@\do+\do\"%
+ % Don't do the quotes -- if we do, @set txicodequoteundirected and
+ % @set txicodequotebacktick will not have effect on @verb and
+ % @verbatim, and ?` and !` ligatures won't get disabled.
+ %\do\`\do\'%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+ \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+ \tt % easiest (and conventionally used) font for verbatim
+ \def\par{\leavevmode\endgraf}%
+ \setupmarkupstyle{verb}%
+ \tabeightspaces
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion.
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+% We typeset each line of the verbatim in an \hbox, so we can handle
+% tabs. The \global is in case the verbatim line starts with an accent,
+% or some other command that starts with a begin-group. Otherwise, the
+% entire \verbbox would disappear at the corresponding end-group, before
+% it is typeset. Meanwhile, we can't have nested verbatim commands
+% (can we?), so the \global won't be overwriting itself.
+\newbox\verbbox
+\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup}
+%
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabexpand{%
+ \catcode`\^^I=\active
+ \def^^I{\leavevmode\egroup
+ \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab
+ \divide\dimen\verbbox by\tabw
+ \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw
+ \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw
+ \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox
+ }%
+ }
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \tt % easiest (and conventionally used) font for verbatim
+ % The \leavevmode here is for blank lines. Otherwise, we would
+ % never \starttabox and the \egroup would end verbatim mode.
+ \def\par{\leavevmode\egroup\box\verbbox\endgraf}%
+ \tabexpand
+ \setupmarkupstyle{verbatim}%
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count.
+ % Must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+ \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters. Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+% \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+ \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+ \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+% \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+ \catcode`\ =\active
+ \obeylines %
+ % ignore everything up to the first ^^M, that's the newline at the end
+ % of the @verbatim input line itself. Otherwise we get an extra blank
+ % line in the output.
+ \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+ % We really want {...\end verbatim} in the body of the macro, but
+ % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+ \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+ {%
+ \makevalueexpandable
+ \setupverbatim
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}%
+ \input #1
+ \afterenvbreak
+ }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+ \begingroup
+ \parindent = 0pt % paragraph indentation looks wrong on title page
+ \scanexp\copyingtext
+ \endgroup
+}
+
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
+
+% Start the processing of @deffn:
+\def\startdefun{%
+ \ifnum\lastpenalty<10000
+ \medbreak
+ \defunpenalty=10003 % Will keep this @deffn together with the
+ % following @def command, see below.
+ \else
+ % If there are two @def commands in a row, we'll have a \nobreak,
+ % which is there to keep the function description together with its
+ % header. But if there's nothing but headers, we need to allow a
+ % break somewhere. Check specifically for penalty 10002, inserted
+ % by \printdefunline, instead of 10000, since the sectioning
+ % commands also insert a nobreak penalty, and we don't want to allow
+ % a break between a section heading and a defun.
+ %
+ % As a further refinement, we avoid "club" headers by signalling
+ % with penalty of 10003 after the very first @deffn in the
+ % sequence (see above), and penalty of 10002 after any following
+ % @def command.
+ \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
+ %
+ % Similarly, after a section heading, do not allow a break.
+ % But do insert the glue.
+ \medskip % preceded by discardable penalty, so not a breakpoint
+ \fi
+ %
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+ % First, check whether we are in the right environment:
+ \checkenv#1%
+ %
+ % As above, allow line break if we have multiple x headers in a row.
+ % It's not a great place, though.
+ \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
+ %
+ % And now, it's time to reuse the body of the original defun:
+ \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+ \begingroup
+ % call \deffnheader:
+ #1#2 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil\relax
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty\defunpenalty % signal to \startdefun and \dodefunx
+ % Some of the @defun-type tags do not enable magic parentheses,
+ % rendering the following check redundant. But we don't optimize.
+ \checkparencounts
+ \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remaining is to define \deffnheader.
+%
+\def\makedefun#1{%
+ \expandafter\let\csname E#1\endcsname = \Edefun
+ \edef\temp{\noexpand\domakedefun
+ \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+ \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+ \envdef#1{%
+ \startdefun
+ \doingtypefnfalse % distinguish typed functions from all else
+ \parseargusing\activeparens{\printdefunline#3}%
+ }%
+ \def#2{\dodefunx#1}%
+ \def#3%
+}
+
+\newif\ifdoingtypefn % doing typed function?
+\newif\ifrettypeownline % typeset return type on its own line?
+
+% @deftypefnnewline on|off says whether the return type of typed functions
+% are printed on their own line. This affects @deftypefn, @deftypefun,
+% @deftypeop, and @deftypemethod.
+%
+\parseargdef\deftypefnnewline{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @txideftypefnnl value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+ % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{fn}{\code{#4}}{#1}%
+ \doingtypefntrue
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{vr}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+% Types:
+
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+ \par
+ % Get the values of \leftskip and \rightskip as they were outside the @def...
+ \advance\leftskip by -\defbodyindent
+ %
+ % Determine if we are typesetting the return type of a typed function
+ % on a line by itself.
+ \rettypeownlinefalse
+ \ifdoingtypefn % doing a typed function specifically?
+ % then check user option for putting return type on its own line:
+ \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else
+ \rettypeownlinetrue
+ \fi
+ \fi
+ %
+ % How we'll format the category name. Putting it in brackets helps
+ % distinguish it from the body text that may end up on the next line
+ % just below it.
+ \def\temp{#1}%
+ \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+ %
+ % Figure out line sizes for the paragraph shape. We'll always have at
+ % least two.
+ \tempnum = 2
+ %
+ % The first line needs space for \box0; but if \rightskip is nonzero,
+ % we need only space for the part of \box0 which exceeds it:
+ \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ %
+ % If doing a return type on its own line, we'll have another line.
+ \ifrettypeownline
+ \advance\tempnum by 1
+ \def\maybeshapeline{0in \hsize}%
+ \else
+ \def\maybeshapeline{}%
+ \fi
+ %
+ % The continuations:
+ \dimen2=\hsize \advance\dimen2 by -\defargsindent
+ %
+ % The final paragraph shape:
+ \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2
+ %
+ % Put the category name at the right margin.
+ \noindent
+ \hbox to 0pt{%
+ \hfil\box0 \kern-\hsize
+ % \hsize has to be shortened this way:
+ \kern\leftskip
+ % Intentionally do not respect \rightskip, since we need the space.
+ }%
+ %
+ % Allow all lines to be underfull without complaint:
+ \tolerance=10000 \hbadness=10000
+ \exdentamount=\defbodyindent
+ {%
+ % defun fonts. We use typewriter by default (used to be bold) because:
+ % . we're printing identifiers, they should be in tt in principle.
+ % . in languages with many accents, such as Czech or French, it's
+ % common to leave accents off identifiers. The result looks ok in
+ % tt, but exceedingly strange in rm.
+ % . we don't want -- and --- to be treated as ligatures.
+ % . this still does not fix the ?` and !` ligatures, but so far no
+ % one has made identifiers using them :).
+ \df \tt
+ \def\temp{#2}% text of the return type
+ \ifx\temp\empty\else
+ \tclose{\temp}% typeset the return type
+ \ifrettypeownline
+ % put return type on its own line; prohibit line break following:
+ \hfil\vadjust{\nobreak}\break
+ \else
+ \space % type on same line, so just followed by a space
+ \fi
+ \fi % no return type
+ #3% output function name
+ }%
+ {\rm\enskip}% hskip 0.5 em of \tenrm
+ %
+ \boldbrax
+ % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name. This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable. Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+ % use sl by default (not ttsl),
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ %
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. We used to recommend @var for that, so
+ % leave the code in, but it's strange for @var to lead to typewriter.
+ % Nowadays we recommend @code, since the difference between a ttsl hyphen
+ % and a tt hyphen is pretty tiny. @code also disables ?` !`.
+ \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
+ #1%
+ \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
+
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
+}
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
+}
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
+}
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+% these should not use \errmessage; the glibc manual, at least, actually
+% has such constructs (when documenting function pointers).
+\def\badparencount{%
+ \message{Warning: unbalanced parentheses in @def...}%
+ \global\parencount=0
+}
+\def\badbrackcount{%
+ \message{Warning: unbalanced square brackets in @def...}%
+ \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\thisisundefined
+ \newwrite\macscribble
+ \def\scantokens#1{%
+ \toks0={#1}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \input \jobname.tmp
+ }
+\fi
+
+\def\scanmacro#1{\begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ %
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ %
+ % ... and for \example:
+ \spaceisspace
+ %
+ % The \empty here causes a following catcode 5 newline to be eaten as
+ % part of reading whitespace after a control sequence. It does not
+ % eat a catcode 13 newline. There's no good way to handle the two
+ % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX
+ % would then have different behavior). See the Macro Details node in
+ % the manual for the workaround we recommend for macros and
+ % line-oriented commands.
+ %
+ \scantokens{#1\empty}%
+\endgroup}
+
+\def\scanexp#1{%
+ \edef\temp{\noexpand\scanmacro{#1}}%
+ \temp
+}
+
+\newcount\paramno % Count of parameters
+\newtoks\macname % Macro name
+\newif\ifrecursive % Is it recursive?
+
+% List of all defined macros in the form
+% \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+ \toks0 = \expandafter{\macrolist\definedummyword#1}%
+ \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+% \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+%
+\def\cslet#1#2{%
+ \expandafter\let
+ \csname#1\expandafter\endcsname
+ \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \
+% to recognize macro arguments; this is the job of \mbodybackslash.
+%
+% Non-ASCII encodings make 8-bit characters active, so un-activate
+% them to avoid their expansion. Must do this non-globally, to
+% confine the change to the current group.
+%
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+%
+\def\scanctxt{% used as subroutine
+ \catcode`\"=\other
+ \catcode`\+=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\~=\other
+ \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
+}
+
+\def\scanargctxt{% used for copying and captions, not macros.
+ \scanctxt
+ \catcode`\\=\other
+ \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{% used for @macro definitions
+ \scanctxt
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\^^M=\other
+ \usembodybackslash
+}
+
+\def\macroargctxt{% used when scanning invocations
+ \scanctxt
+ \catcode`\\=0
+}
+% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes"
+% for the single characters \ { }. Thus, we end up with the "commands"
+% that would be written @\ @{ @} in a Texinfo document.
+%
+% We already have @{ and @}. For @\, we define it here, and only for
+% this purpose, to produce a typewriter backslash (so, the @\ that we
+% define for @math can't be used with @macro calls):
+%
+\def\\{\normalbackslash}%
+%
+% We would like to do this for \, too, since that is what makeinfo does.
+% But it is not possible, because Texinfo already has a command @, for a
+% cedilla accent. Documents must use @comma{} instead.
+%
+% \anythingelse will almost certainly be an error of some kind.
+
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+%
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\margbackslash#1{\char`\#1 }
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+ \getargs{#1}% now \macname is the macname and \argl the arglist
+ \ifx\argl\empty % no arguments
+ \paramno=0\relax
+ \else
+ \expandafter\parsemargdef \argl;%
+ \if\paramno>256\relax
+ \ifx\eTeXversion\thisisundefined
+ \errhelp = \EMsimple
+ \errmessage{You need eTeX to compile a file with macros with more than 256 arguments}
+ \fi
+ \fi
+ \fi
+ \if1\csname ismacro.\the\macname\endcsname
+ \message{Warning: redefining \the\macname}%
+ \else
+ \expandafter\ifx\csname \the\macname\endcsname \relax
+ \else \errmessage{Macro name \the\macname\space already defined}\fi
+ \global\cslet{macsave.\the\macname}{\the\macname}%
+ \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+ \addtomacrolist{\the\macname}%
+ \fi
+ \begingroup \macrobodyctxt
+ \ifrecursive \expandafter\parsermacbody
+ \else \expandafter\parsemacbody
+ \fi}
+
+\parseargdef\unmacro{%
+ \if1\csname ismacro.#1\endcsname
+ \global\cslet{#1}{macsave.#1}%
+ \global\expandafter\let \csname ismacro.#1\endcsname=0%
+ % Remove the macro name from \macrolist:
+ \begingroup
+ \expandafter\let\csname#1\endcsname \relax
+ \let\definedummyword\unmacrodo
+ \xdef\macrolist{\macrolist}%
+ \endgroup
+ \else
+ \errmessage{Macro #1 not defined}%
+ \fi
+}
+
+% Called by \do from \dounmacro on each macro. The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+ \ifx #1\relax
+ % remove this
+ \else
+ \noexpand\definedummyword \noexpand#1%
+ \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname#1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% For macro processing make @ a letter so that we can make Texinfo private macro names.
+\edef\texiatcatcode{\the\catcode`\@}
+\catcode `@=11\relax
+
+% Parse the optional {params} list. Set up \paramno and \paramlist
+% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH
+% in the params list to some hook where the argument si to be expanded. If
+% there are less than 10 arguments that hook is to be replaced by ##N where N
+% is the position in that list, that is to say the macro arguments are to be
+% defined `a la TeX in the macro body.
+%
+% That gets used by \mbodybackslash (above).
+%
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX: let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+%
+% If there are 10 or more arguments, a different technique is used, where the
+% hook remains in the body, and when macro is to be expanded the body is
+% processed again to replace the arguments.
+%
+% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the
+% argument N value and then \edef the body (nothing else will expand because of
+% the catcode regime underwhich the body was input).
+%
+% If you compile with TeX (not eTeX), and you have macros with 10 or more
+% arguments, you need that no macro has more than 256 arguments, otherwise an
+% error is produced.
+\def\parsemargdef#1;{%
+ \paramno=0\def\paramlist{}%
+ \let\hash\relax
+ \let\xeatspaces\relax
+ \parsemargdefxxx#1,;,%
+ % In case that there are 10 or more arguments we parse again the arguments
+ % list to set new definitions for the \macarg.BLAH macros corresponding to
+ % each BLAH argument. It was anyhow needed to parse already once this list
+ % in order to count the arguments, and as macros with at most 9 arguments
+ % are by far more frequent than macro with 10 or more arguments, defining
+ % twice the \macarg.BLAH macros does not cost too much processing power.
+ \ifnum\paramno<10\relax\else
+ \paramno0\relax
+ \parsemmanyargdef@@#1,;,% 10 or more arguments
+ \fi
+}
+\def\parsemargdefxxx#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\parsemargdefxxx
+ \advance\paramno by 1
+ \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+ {\xeatspaces{\hash\the\paramno}}%
+ \edef\paramlist{\paramlist\hash\the\paramno,}%
+ \fi\next}
+
+\def\parsemmanyargdef@@#1,{%
+ \if#1;\let\next=\relax
+ \else
+ \let\next=\parsemmanyargdef@@
+ \edef\tempb{\eatspaces{#1}}%
+ \expandafter\def\expandafter\tempa
+ \expandafter{\csname macarg.\tempb\endcsname}%
+ % Note that we need some extra \noexpand\noexpand, this is because we
+ % don't want \the to be expanded in the \parsermacbody as it uses an
+ % \xdef .
+ \expandafter\edef\tempa
+ {\noexpand\noexpand\noexpand\the\toks\the\paramno}%
+ \advance\paramno by 1\relax
+ \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+%
+
+\catcode `\@\texiatcatcode
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\catcode `\@=11\relax
+
+\let\endargs@\relax
+\let\nil@\relax
+\def\nilm@{\nil@}%
+\long\def\nillm@{\nil@}%
+
+% This macro is expanded during the Texinfo macro expansion, not during its
+% definition. It gets all the arguments values and assigns them to macros
+% macarg.ARGNAME
+%
+% #1 is the macro name
+% #2 is the list of argument names
+% #3 is the list of argument values
+\def\getargvals@#1#2#3{%
+ \def\macargdeflist@{}%
+ \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion.
+ \def\paramlist{#2,\nil@}%
+ \def\macroname{#1}%
+ \begingroup
+ \macroargctxt
+ \def\argvaluelist{#3,\nil@}%
+ \def\@tempa{#3}%
+ \ifx\@tempa\empty
+ \setemptyargvalues@
+ \else
+ \getargvals@@
+ \fi
+}
+
+%
+\def\getargvals@@{%
+ \ifx\paramlist\nilm@
+ % Some sanity check needed here that \argvaluelist is also empty.
+ \ifx\argvaluelist\nillm@
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Too many arguments in macro `\macroname'!}%
+ \fi
+ \let\next\macargexpandinbody@
+ \else
+ \ifx\argvaluelist\nillm@
+ % No more arguments values passed to macro. Set remaining named-arg
+ % macros to empty.
+ \let\next\setemptyargvalues@
+ \else
+ % pop current arg name into \@tempb
+ \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\paramlist}%
+ % pop current argument value into \@tempc
+ \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\argvaluelist}%
+ % Here \@tempb is the current arg name and \@tempc is the current arg value.
+ % First place the new argument macro definition into \@tempd
+ \expandafter\macname\expandafter{\@tempc}%
+ \expandafter\let\csname macarg.\@tempb\endcsname\relax
+ \expandafter\def\expandafter\@tempe\expandafter{%
+ \csname macarg.\@tempb\endcsname}%
+ \edef\@tempd{\long\def\@tempe{\the\macname}}%
+ \push@\@tempd\macargdeflist@
+ \let\next\getargvals@@
+ \fi
+ \fi
+ \next
+}
+
+\def\push@#1#2{%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter#2%
+ \expandafter\expandafter\expandafter{%
+ \expandafter#1#2}%
+}
+
+% Replace arguments by their values in the macro body, and place the result
+% in macro \@tempa
+\def\macvalstoargs@{%
+ % To do this we use the property that token registers that are \the'ed
+ % within an \edef expand only once. So we are going to place all argument
+ % values into respective token registers.
+ %
+ % First we save the token context, and initialize argument numbering.
+ \begingroup
+ \paramno0\relax
+ % Then, for each argument number #N, we place the corresponding argument
+ % value into a new token list register \toks#N
+ \expandafter\putargsintokens@\saveparamlist@,;,%
+ % Then, we expand the body so that argument are replaced by their
+ % values. The trick for values not to be expanded themselves is that they
+ % are within tokens and that tokens expand only once in an \edef .
+ \edef\@tempc{\csname mac.\macroname .body\endcsname}%
+ % Now we restore the token stack pointer to free the token list registers
+ % which we have used, but we make sure that expanded body is saved after
+ % group.
+ \expandafter
+ \endgroup
+ \expandafter\def\expandafter\@tempa\expandafter{\@tempc}%
+ }
+
+\def\macargexpandinbody@{%
+ %% Define the named-macro outside of this group and then close this group.
+ \expandafter
+ \endgroup
+ \macargdeflist@
+ % First the replace in body the macro arguments by their values, the result
+ % is in \@tempa .
+ \macvalstoargs@
+ % Then we point at the \norecurse or \gobble (for recursive) macro value
+ % with \@tempb .
+ \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname
+ % Depending on whether it is recursive or not, we need some tailing
+ % \egroup .
+ \ifx\@tempb\gobble
+ \let\@tempc\relax
+ \else
+ \let\@tempc\egroup
+ \fi
+ % And now we do the real job:
+ \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}%
+ \@tempd
+}
+
+\def\putargsintokens@#1,{%
+ \if#1;\let\next\relax
+ \else
+ \let\next\putargsintokens@
+ % First we allocate the new token list register, and give it a temporary
+ % alias \@tempb .
+ \toksdef\@tempb\the\paramno
+ % Then we place the argument value into that token list register.
+ \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname
+ \expandafter\@tempb\expandafter{\@tempa}%
+ \advance\paramno by 1\relax
+ \fi
+ \next
+}
+
+% Save the token stack pointer into macro #1
+\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}}
+% Restore the token stack pointer from number in macro #1
+\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax}
+% newtoks that can be used non \outer .
+\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi}
+
+% Tailing missing arguments are set to empty
+\def\setemptyargvalues@{%
+ \ifx\paramlist\nilm@
+ \let\next\macargexpandinbody@
+ \else
+ \expandafter\setemptyargvaluesparser@\paramlist\endargs@
+ \let\next\setemptyargvalues@
+ \fi
+ \next
+}
+
+\def\setemptyargvaluesparser@#1,#2\endargs@{%
+ \expandafter\def\expandafter\@tempa\expandafter{%
+ \expandafter\def\csname macarg.#1\endcsname{}}%
+ \push@\@tempa\macargdeflist@
+ \def\paramlist{#2}%
+}
+
+% #1 is the element target macro
+% #2 is the list macro
+% #3,#4\endargs@ is the list value
+\def\pop@#1#2#3,#4\endargs@{%
+ \def#1{#3}%
+ \def#2{#4}%
+}
+\long\def\longpop@#1#2#3,#4\endargs@{%
+ \long\def#1{#3}%
+ \long\def#2{#4}%
+}
+
+% This defines a Texinfo @macro. There are eight cases: recursive and
+% nonrecursive macros of zero, one, up to nine, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+%
+\def\defmacro{%
+ \let\hash=##% convert placeholders to macro parameter chars
+ \ifrecursive
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\scanmacro{\temp}}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup\noexpand\scanmacro{\temp}}%
+ \else
+ \ifnum\paramno<10\relax % at most 9
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \else % 10 or more
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble
+ \fi
+ \fi
+ \else
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % at most 9
+ \ifnum\paramno<10\relax
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % 10 or more:
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse
+ \fi
+ \fi
+ \fi}
+
+\catcode `\@\texiatcatcode\relax
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {. If so it reads up to the closing }, if not, it reads the whole
+% line. Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg).
+%
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+ \ifx\nchar\bgroup\else
+ \expandafter\parsearg
+ \fi \macnamexxx}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign. Make them active and then expand them all to nothing.
+%
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+ {%
+ \expandafter\let\obeyedspace=\empty
+ \addtomacrolist{#1}%
+ \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+ }%
+ \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{%
+ \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references. The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross, , , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node. #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+ \ifx\lastnode\empty\else
+ \setref{\lastnode}{#1}%
+ \global\let\lastnode=\empty
+ \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \lastsection,
+% or the anchor name.
+% 2) NAME-snt - section number and type, passed as the SNT arg, or
+% empty for anchors.
+% 3) NAME-pg - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat. In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+ \pdfmkdest{#1}%
+ \iflinks
+ {%
+ \atdummies % preserve commands, but don't expand them
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\lastsection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout
+ }%
+ \fi
+}
+
+% @xrefautosectiontitle on|off says whether @section(ing) names are used
+% automatically in xrefs, if the third arg is not explicitly specified.
+% This was provided as a "secret" @set xref-automatic-section-title
+% variable, now it's official.
+%
+\parseargdef\xrefautomaticsectiontitle{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @xrefautomaticsectiontitle value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+%
+% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual. All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+%
+\newbox\toprefbox
+\newbox\printedrefnamebox
+\newbox\infofilenamebox
+\newbox\printedmanualbox
+%
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \unsepspaces
+ %
+ % Get args without leading/trailing spaces.
+ \def\printedrefname{\ignorespaces #3}%
+ \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
+ %
+ \def\infofilename{\ignorespaces #4}%
+ \setbox\infofilenamebox = \hbox{\infofilename\unskip}%
+ %
+ \def\printedmanual{\ignorespaces #5}%
+ \setbox\printedmanualbox = \hbox{\printedmanual\unskip}%
+ %
+ % If the printed reference name (arg #3) was not explicitly given in
+ % the @xref, figure out what we want to use.
+ \ifdim \wd\printedrefnamebox = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax
+ % Not auto section-title: use node name inside the square brackets.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ % Auto section-title: use chapter/section title inside
+ % the square brackets if we have it.
+ \ifdim \wd\printedmanualbox > 0pt
+ % It is in another manual, so we don't have it; use node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We (should) know the real title if we have the xref values.
+ \def\printedrefname{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % Make link in pdf output.
+ \ifpdf
+ {\indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ % This expands tokens, so do it after making catcode changes, so _
+ % etc. don't get their TeX definitions. This ignores all spaces in
+ % #4, including (wrongly) those in the middle of the filename.
+ \getfilename{#4}%
+ %
+ % This (wrongly) does not take account of leading or trailing
+ % spaces in #1, which should be ignored.
+ \edef\pdfxrefdest{#1}%
+ \ifx\pdfxrefdest\empty
+ \def\pdfxrefdest{Top}% no empty targets
+ \else
+ \txiescapepdf\pdfxrefdest % escape PDF special chars
+ \fi
+ %
+ \leavevmode
+ \startlink attr{/Border [0 0 0]}%
+ \ifnum\filenamelength>0
+ goto file{\the\filename.pdf} name{\pdfxrefdest}%
+ \else
+ goto name{\pdfmkpgn{\pdfxrefdest}}%
+ \fi
+ }%
+ \setcolor{\linkcolor}%
+ \fi
+ %
+ % Float references are printed completely differently: "Figure 1.2"
+ % instead of "[somenode], p.3". We distinguish them by the
+ % LABEL-title being set to a magic string.
+ {%
+ % Have to otherify everything special to allow the \csname to
+ % include an _ in the xref name, etc.
+ \indexnofonts
+ \turnoffactive
+ \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+ \csname XR#1-title\endcsname
+ }%
+ \iffloat\Xthisreftitle
+ % If the user specified the print name (third arg) to the ref,
+ % print it instead of our usual "Figure 1.2".
+ \ifdim\wd\printedrefnamebox = 0pt
+ \refx{#1-snt}{}%
+ \else
+ \printedrefname
+ \fi
+ %
+ % If the user also gave the printed manual name (fifth arg), append
+ % "in MANUALNAME".
+ \ifdim \wd\printedmanualbox > 0pt
+ \space \putwordin{} \cite{\printedmanual}%
+ \fi
+ \else
+ % node/anchor (non-float) references.
+ %
+ % If we use \unhbox to print the node names, TeX does not insert
+ % empty discretionaries after hyphens, which means that it will not
+ % find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens,
+ % this is a loss. Therefore, we give the text of the node name
+ % again, so it is as if TeX is seeing it for the first time.
+ %
+ \ifdim \wd\printedmanualbox > 0pt
+ % Cross-manual reference with a printed manual name.
+ %
+ \crossmanualxref{\cite{\printedmanual\unskip}}%
+ %
+ \else\ifdim \wd\infofilenamebox > 0pt
+ % Cross-manual reference with only an info filename (arg 4), no
+ % printed manual name (arg 5). This is essentially the same as
+ % the case above; we output the filename, since we have nothing else.
+ %
+ \crossmanualxref{\code{\infofilename\unskip}}%
+ %
+ \else
+ % Reference within this manual.
+ %
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive
+ % Only output a following space if the -snt ref is nonempty; for
+ % @unnumbered and @anchor, it won't be.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+ }%
+ % output the `[mynode]' via the macro below so it can be overridden.
+ \xrefprintnodename\printedrefname
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi\fi
+ \fi
+ \endlink
+\endgroup}
+
+% Output a cross-manual xref to #1. Used just above (twice).
+%
+% Only include the text "Section ``foo'' in" if the foo is neither
+% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply
+% "see The Foo Manual", the idea being to refer to the whole manual.
+%
+% But, this being TeX, we can't easily compare our node name against the
+% string "Top" while ignoring the possible spaces before and after in
+% the input. By adding the arbitrary 7sp below, we make it much less
+% likely that a real node name would have the same width as "Top" (e.g.,
+% in a monospaced font). Hopefully it will never happen in practice.
+%
+% For the same basic reason, we retypeset the "Top" at every
+% reference, since the current font is indeterminate.
+%
+\def\crossmanualxref#1{%
+ \setbox\toprefbox = \hbox{Top\kern7sp}%
+ \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
+ \ifdim \wd2 > 7sp % nonempty?
+ \ifdim \wd2 = \wd\toprefbox \else % same as Top?
+ \putwordSection{} ``\printedrefname'' \putwordin{}\space
+ \fi
+ \fi
+ #1%
+}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output. It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents. Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+ \ifnum\secno=0
+ \putwordChapter@tie \the\chapno
+ \else \ifnum\subsecno=0
+ \putwordSection@tie \the\chapno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+\def\Yappendix{%
+ \ifnum\secno=0
+ \putwordAppendix@tie @char\the\appendixno{}%
+ \else \ifnum\subsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie
+ @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+ {%
+ \indexnofonts
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\thisrefX
+ \csname XR#1\endcsname
+ }%
+ \ifx\thisrefX\relax
+ % If not defined, say something at least.
+ \angleleft un\-de\-fined\angleright
+ \iflinks
+ \ifhavexrefs
+ {\toks0 = {#1}% avoid expansion of possibly-complex value
+ \message{\linenumber Undefined cross reference `\the\toks0'.}}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \thisrefX
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file. Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions). But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+ {% The node name might contain 8-bit characters, which in our current
+ % implementation are changed to commands like @'e. Don't let these
+ % mess up the control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safexrefname{#1}%
+ }%
+ %
+ \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
+ %
+ % Was that xref control sequence that we just defined for a float?
+ \expandafter\iffloat\csname XR\safexrefname\endcsname
+ % it was a float, and we have the (safe) float type in \iffloattype.
+ \expandafter\let\expandafter\floatlist
+ \csname floatlist\iffloattype\endcsname
+ %
+ % Is this the first time we've seen this float type?
+ \expandafter\ifx\floatlist\relax
+ \toks0 = {\do}% yes, so just \do
+ \else
+ % had it before, so preserve previous elements in list.
+ \toks0 = \expandafter{\floatlist\do}%
+ \fi
+ %
+ % Remember this xref in the control sequence \floatlistFLOATTYPE,
+ % for later use in \listoffloats.
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+ {\safexrefname}}%
+ \fi
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+%
+\def\tryauxfile{%
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \readdatafile{aux}%
+ \global\havexrefstrue
+ \fi
+ \closein 1
+}
+
+\def\setupdatafile{%
+ \catcode`\^^@=\other
+ \catcode`\^^A=\other
+ \catcode`\^^B=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\^^K=\other
+ \catcode`\^^L=\other
+ \catcode`\^^N=\other
+ \catcode`\^^P=\other
+ \catcode`\^^Q=\other
+ \catcode`\^^R=\other
+ \catcode`\^^S=\other
+ \catcode`\^^T=\other
+ \catcode`\^^U=\other
+ \catcode`\^^V=\other
+ \catcode`\^^W=\other
+ \catcode`\^^X=\other
+ \catcode`\^^Z=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\^=\other
+ %
+ % Special characters. Should be turned off anyway, but...
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ \catcode`\%=\other
+ \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+ %
+ % This is to support \ in node names and titles, since the \
+ % characters end up in a \csname. It's easier than
+ % leaving it active and making its active definition an actual \
+ % character. What I don't understand is why it works in the *value*
+ % of the xrdef. Seems like it should be a catcode12 \, and that
+ % should not typeset properly. But it works, so I'm moving on for
+ % now. --karl, 15jan04.
+ \catcode`\\=\other
+ %
+ % Make the characters 128-255 be printing characters.
+ {%
+ \count1=128
+ \def\loop{%
+ \catcode\count1=\other
+ \advance\count1 by 1
+ \ifnum \count1<256 \loop \fi
+ }%
+ }%
+ %
+ % @ is our escape character in .aux files, and we need braces.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+ \setupdatafile
+ \input\jobname.#1
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for Info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
+%
+\gdef\dofootnote{%
+ \insert\footins\bgroup
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \hsize=\pagewidth
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ \smallfonts \rm
+ %
+ % Because we use hanging indentation in footnotes, a @noindent appears
+ % to exdent this text, so make it be a no-op. makeinfo does not use
+ % hanging indentation so @noindent can still be needed within footnote
+ % text after an @example or the like (not that this is good style).
+ \let\noindent = \relax
+ %
+ % Hang the footnote text off the number. Use \everypar in case the
+ % footnote extends for more than one paragraph.
+ \everypar = {\hang}%
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ %
+ % Invoke rest of plain TeX footnote routine.
+ \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished. Otherwise, the insertion
+% would be lost.
+% Similarly, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes. --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+ \ifx \insert\ptexinsert
+ \let\insert\saveinsert
+ \else
+ \let\checkinserts\relax
+ \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+ \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+ \afterassignment\next
+ % swallow the left brace
+ \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+ \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+ {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+ \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-)
+ \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+ \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+ \next
+}
+\def\newsaveinsX #1{%
+ \csname newbox\endcsname #1%
+ \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+ \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image. We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front. If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+ % Do not bother showing banner with epsf.tex v2.7k (available in
+ % doc/epsf.tex and on ctan).
+ \def\epsfannounce{\toks0 = }%
+ \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+ work. It is also included in the Texinfo distribution, or you can get
+ it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+ \ifx\epsfbox\thisisundefined
+ \ifwarnednoepsf \else
+ \errhelp = \noepsfhelp
+ \errmessage{epsf.tex not found, images will be ignored}%
+ \global\warnednoepsftrue
+ \fi
+ \else
+ \imagexxx #1,,,,,\finish
+ \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+ \catcode`\^^M = 5 % in case we're inside an example
+ \normalturnoffactive % allow _ et al. in names
+ % If the image is by itself, center it.
+ \ifvmode
+ \imagevmodetrue
+ \else \ifx\centersub\centerV
+ % for @center @image, we need a vbox so we can have our vertical space
+ \imagevmodetrue
+ \vbox\bgroup % vbox has better behavior than vtop herev
+ \fi\fi
+ %
+ \ifimagevmode
+ \nobreak\medskip
+ % Usually we'll have text after the image which will insert
+ % \parskip glue, so insert it here too to equalize the space
+ % above and below.
+ \nobreak\vskip\parskip
+ \nobreak
+ \fi
+ %
+ % Leave vertical mode so that indentation from an enclosing
+ % environment such as @quotation is respected.
+ % However, if we're at the top level, we don't want the
+ % normal paragraph indentation.
+ % On the other hand, if we are in the case of @center @image, we don't
+ % want to start a paragraph, which will create a hsize-width box and
+ % eradicate the centering.
+ \ifx\centersub\centerV\else \noindent \fi
+ %
+ % Output the image.
+ \ifpdf
+ \dopdfimage{#1}{#2}{#3}%
+ \else
+ % \epsfbox itself resets \epsf?size at each figure.
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+ \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+ \epsfbox{#1.eps}%
+ \fi
+ %
+ \ifimagevmode
+ \medskip % space after a standalone image
+ \fi
+ \ifx\centersub\centerV \egroup \fi
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc. We don't actually implement floating yet, we always include the
+% float "here". But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc. Can't contain commas. If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label. Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored. It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+ \let\thiscaption=\empty
+ \let\thisshortcaption=\empty
+ %
+ % don't lose footnotes inside @float.
+ %
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
+ %
+ \startsavinginserts
+ %
+ % We can't be used inside a paragraph.
+ \par
+ %
+ \vtop\bgroup
+ \def\floattype{#1}%
+ \def\floatlabel{#2}%
+ \def\floatloc{#3}% we do nothing with this yet.
+ %
+ \ifx\floattype\empty
+ \let\safefloattype=\empty
+ \else
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ \fi
+ %
+ % If label is given but no type, we handle that as the empty type.
+ \ifx\floatlabel\empty \else
+ % We want each FLOATTYPE to be numbered separately (Figure 1,
+ % Table 1, Figure 2, ...). (And if no label, no number.)
+ %
+ \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+ \global\advance\floatno by 1
+ %
+ {%
+ % This magic value for \lastsection is output by \setref as the
+ % XREFLABEL-title value. \xrefX uses it to distinguish float
+ % labels (which have a completely different output format) from
+ % node and anchor labels. And \xrdef uses it to construct the
+ % lists of floats.
+ %
+ \edef\lastsection{\floatmagic=\safefloattype}%
+ \setref{\floatlabel}{Yfloat}%
+ }%
+ \fi
+ %
+ % start with \parskip glue, I guess.
+ \vskip\parskip
+ %
+ % Don't suppress indentation if a float happens to start a section.
+ \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption: Foo 1.1
+% @float Foo & @caption{Cap}: Foo: Cap
+% @float Foo & no caption: Foo
+% @float ,lbl & Caption{Cap}: 1.1: Cap
+% @float ,lbl & no caption: 1.1
+% @float & @caption{Cap}: Cap
+% @float & no caption:
+%
+\def\Efloat{%
+ \let\floatident = \empty
+ %
+ % In all cases, if we have a float type, it comes first.
+ \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+ %
+ % If we have an xref label, the number comes next.
+ \ifx\floatlabel\empty \else
+ \ifx\floattype\empty \else % if also had float type, need tie first.
+ \appendtomacro\floatident{\tie}%
+ \fi
+ % the number.
+ \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+ \fi
+ %
+ % Start the printed caption with what we've constructed in
+ % \floatident, but keep it separate; we need \floatident again.
+ \let\captionline = \floatident
+ %
+ \ifx\thiscaption\empty \else
+ \ifx\floatident\empty \else
+ \appendtomacro\captionline{: }% had ident, so need a colon between
+ \fi
+ %
+ % caption text.
+ \appendtomacro\captionline{\scanexp\thiscaption}%
+ \fi
+ %
+ % If we have anything to print, print it, with space before.
+ % Eventually this needs to become an \insert.
+ \ifx\captionline\empty \else
+ \vskip.5\parskip
+ \captionline
+ %
+ % Space below caption.
+ \vskip\parskip
+ \fi
+ %
+ % If have an xref label, write the list of floats info. Do this
+ % after the caption, to avoid chance of it being a breakpoint.
+ \ifx\floatlabel\empty \else
+ % Write the text that goes in the lof to the aux file as
+ % \floatlabel-lof. Besides \floatident, we include the short
+ % caption if specified, else the full caption if specified, else nothing.
+ {%
+ \atdummies
+ %
+ % since we read the caption text in the macro world, where ^^M
+ % is turned into a normal character, we have to scan it back, so
+ % we don't write the literal three characters "^^M" into the aux file.
+ \scanexp{%
+ \xdef\noexpand\gtemp{%
+ \ifx\thisshortcaption\empty
+ \thiscaption
+ \else
+ \thisshortcaption
+ \fi
+ }%
+ }%
+ \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+ \ifx\gtemp\empty \else : \gtemp \fi}}%
+ }%
+ \fi
+ \egroup % end of \vtop
+ %
+ % place the captured inserts
+ %
+ % BEWARE: when the floats start floating, we have to issue warning
+ % whenever an insert appears inside a float which could possibly
+ % float. --kasal, 26may04
+ %
+ \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use. Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+ \ifx#1\relax
+ % Haven't seen this figure type before.
+ \csname newcount\endcsname #1%
+ %
+ % Remember to reset this floatno at the next chap.
+ \expandafter\gdef\expandafter\resetallfloatnos
+ \expandafter{\resetallfloatnos #1=0 }%
+ \fi
+ \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value. We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref. That is, the magic
+% \lastsection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string. If so, #2 will be the
+% (safe) float type for this float. We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+ \def\temp{#1}%
+ \def\iffloattype{#2}%
+ \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+ \def\floattype{#1}% floattype
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ %
+ % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+ \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+ \ifhavexrefs
+ % if the user said @listoffloats foo but never @float foo.
+ \message{\linenumber No `\safefloattype' floats to list.}%
+ \fi
+ \else
+ \begingroup
+ \leftskip=\tocindent % indent these entries like a toc
+ \let\do=\listoffloatsdo
+ \csname floatlist\safefloattype\endcsname
+ \endgroup
+ \fi
+}
+
+% This is called on each entry in a list of floats. We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file. We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+ % Can't fully expand XR#1-lof because it can contain anything. Just
+ % pass the control sequence. On the other hand, XR#1-pg is just the
+ % page number, and we want to fully expand that so we can get a link
+ % in pdf output.
+ \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+ %
+ % use the same \entry macro we use to generate the TOC and index.
+ \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+ \writeentry
+}}
+
+
+\message{localization,}
+
+% For single-language documents, @documentlanguage is usually given very
+% early, just after @documentencoding. Single argument is the language
+% (de) or locale (de_DE) abbreviation.
+%
+{
+ \catcode`\_ = \active
+ \globaldefs=1
+\parseargdef\documentlanguage{\begingroup
+ \let_=\normalunderscore % normal _ character for filenames
+ \tex % read txi-??.tex file in plain TeX.
+ % Read the file by the name they passed if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \documentlanguagetrywithoutunderscore{#1_\finish}%
+ \else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
+ \input txi-#1.tex
+ \fi
+ \closein 1
+ \endgroup % end raw TeX
+\endgroup}
+%
+% If they passed de_DE, and txi-de_DE.tex doesn't exist,
+% try txi-de.tex.
+%
+\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{%
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
+ \input txi-#1.tex
+ \fi
+ \closein 1
+}
+}% end of special _ catcode
+%
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty. Maybe you need to install it? Putting it in the current
+directory should work if nowhere else does.}
+
+% This macro is called from txi-??.tex files; the first argument is the
+% \language name to set (without the "\lang@" prefix), the second and
+% third args are \{left,right}hyphenmin.
+%
+% The language names to pass are determined when the format is built.
+% See the etex.log file created at that time, e.g.,
+% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log.
+%
+% With TeX Live 2008, etex now includes hyphenation patterns for all
+% available languages. This means we can support hyphenation in
+% Texinfo, at least to some extent. (This still doesn't solve the
+% accented characters problem.)
+%
+\catcode`@=11
+\def\txisetlanguage#1#2#3{%
+ % do not set the language if the name is undefined in the current TeX.
+ \expandafter\ifx\csname lang@#1\endcsname \relax
+ \message{no patterns for #1}%
+ \else
+ \global\language = \csname lang@#1\endcsname
+ \fi
+ % but there is no harm in adjusting the hyphenmin values regardless.
+ \global\lefthyphenmin = #2\relax
+ \global\righthyphenmin = #3\relax
+}
+
+% Helpers for encodings.
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \global\catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+\def\setnonasciicharscatcodenonglobal#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+ % Encoding being declared for the document.
+ \def\declaredencoding{\csname #1.enc\endcsname}%
+ %
+ % Supported encodings: names converted to tokens in order to be able
+ % to compare them with \ifx.
+ \def\ascii{\csname US-ASCII.enc\endcsname}%
+ \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+ \def\latone{\csname ISO-8859-1.enc\endcsname}%
+ \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+ \def\utfeight{\csname UTF-8.enc\endcsname}%
+ %
+ \ifx \declaredencoding \ascii
+ \asciichardefs
+ %
+ \else \ifx \declaredencoding \lattwo
+ \setnonasciicharscatcode\active
+ \lattwochardefs
+ %
+ \else \ifx \declaredencoding \latone
+ \setnonasciicharscatcode\active
+ \latonechardefs
+ %
+ \else \ifx \declaredencoding \latnine
+ \setnonasciicharscatcode\active
+ \latninechardefs
+ %
+ \else \ifx \declaredencoding \utfeight
+ \setnonasciicharscatcode\active
+ \utfeightchardefs
+ %
+ \else
+ \message{Unknown document encoding #1, ignoring.}%
+ %
+ \fi % utfeight
+ \fi % latnine
+ \fi % latone
+ \fi % lattwo
+ \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\exclamdown}
+ \gdef^^a2{\missingcharmsg{CENT SIGN}}
+ \gdef^^a3{{\pounds}}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\missingcharmsg{YEN SIGN}}
+ \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\copyright}
+ \gdef^^aa{\ordf}
+ \gdef^^ab{\guillemetleft}
+ \gdef^^ac{$\lnot$}
+ \gdef^^ad{\-}
+ \gdef^^ae{\registeredsymbol}
+ \gdef^^af{\={}}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{$\pm$}
+ \gdef^^b2{$^2$}
+ \gdef^^b3{$^3$}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{$\mu$}
+ \gdef^^b6{\P}
+ %
+ \gdef^^b7{$^.$}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{$^1$}
+ \gdef^^ba{\ordm}
+ %
+ \gdef^^bb{\guillemetright}
+ \gdef^^bc{$1\over4$}
+ \gdef^^bd{$1\over2$}
+ \gdef^^be{$3\over4$}
+ \gdef^^bf{\questiondown}
+ %
+ \gdef^^c0{\`A}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\~A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\ringaccent A}
+ \gdef^^c6{\AE}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\`E}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\^E}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\`I}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\"I}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\~N}
+ \gdef^^d2{\`O}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\~O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\O}
+ \gdef^^d9{\`U}
+ \gdef^^da{\'U}
+ \gdef^^db{\^U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\TH}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\`a}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\~a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\ringaccent a}
+ \gdef^^e6{\ae}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\`e}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\^e}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\`{\dotless i}}
+ \gdef^^ed{\'{\dotless i}}
+ \gdef^^ee{\^{\dotless i}}
+ \gdef^^ef{\"{\dotless i}}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\~n}
+ \gdef^^f2{\`o}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\~o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\o}
+ \gdef^^f9{\`u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\^u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\th}
+ \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+ % Encoding is almost identical to Latin1.
+ \latonechardefs
+ %
+ \gdef^^a4{\euro}
+ \gdef^^a6{\v S}
+ \gdef^^a8{\v s}
+ \gdef^^b4{\v Z}
+ \gdef^^b8{\v z}
+ \gdef^^bc{\OE}
+ \gdef^^bd{\oe}
+ \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\ogonek{A}}
+ \gdef^^a2{\u{}}
+ \gdef^^a3{\L}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\v L}
+ \gdef^^a6{\'S}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\v S}
+ \gdef^^aa{\cedilla S}
+ \gdef^^ab{\v T}
+ \gdef^^ac{\'Z}
+ \gdef^^ad{\-}
+ \gdef^^ae{\v Z}
+ \gdef^^af{\dotaccent Z}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{\ogonek{a}}
+ \gdef^^b2{\ogonek{ }}
+ \gdef^^b3{\l}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{\v l}
+ \gdef^^b6{\'s}
+ \gdef^^b7{\v{}}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{\v s}
+ \gdef^^ba{\cedilla s}
+ \gdef^^bb{\v t}
+ \gdef^^bc{\'z}
+ \gdef^^bd{\H{}}
+ \gdef^^be{\v z}
+ \gdef^^bf{\dotaccent z}
+ %
+ \gdef^^c0{\'R}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\u A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\'L}
+ \gdef^^c6{\'C}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\v C}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\ogonek{E}}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\v E}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\v D}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\'N}
+ \gdef^^d2{\v N}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\H O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\v R}
+ \gdef^^d9{\ringaccent U}
+ \gdef^^da{\'U}
+ \gdef^^db{\H U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\cedilla T}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\'r}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\u a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\'l}
+ \gdef^^e6{\'c}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\v c}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\ogonek{e}}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\v e}
+ \gdef^^ed{\'{\dotless{i}}}
+ \gdef^^ee{\^{\dotless{i}}}
+ \gdef^^ef{\v d}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\'n}
+ \gdef^^f2{\v n}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\H o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\v r}
+ \gdef^^f9{\ringaccent u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\H u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\cedilla t}
+ \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions. It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+ \ifx #1\relax
+ \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+ \else
+ \expandafter #1%
+ \fi
+}
+
+\begingroup
+ \catcode`\~13
+ \catcode`\"12
+
+ \def\UTFviiiLoop{%
+ \global\catcode\countUTFx\active
+ \uccode`\~\countUTFx
+ \uppercase\expandafter{\UTFviiiTmp}%
+ \advance\countUTFx by 1
+ \ifnum\countUTFx < \countUTFy
+ \expandafter\UTFviiiLoop
+ \fi}
+
+ \countUTFx = "C2
+ \countUTFy = "E0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "E0
+ \countUTFy = "F0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "F0
+ \countUTFy = "F4
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+ \UTFviiiLoop
+\endgroup
+
+\begingroup
+ \catcode`\"=12
+ \catcode`\<=12
+ \catcode`\.=12
+ \catcode`\,=12
+ \catcode`\;=12
+ \catcode`\!=12
+ \catcode`\~=13
+
+ \gdef\DeclareUnicodeCharacter#1#2{%
+ \countUTFz = "#1\relax
+ %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+ \begingroup
+ \parseXMLCharref
+ \def\UTFviiiTwoOctets##1##2{%
+ \csname u8:##1\string ##2\endcsname}%
+ \def\UTFviiiThreeOctets##1##2##3{%
+ \csname u8:##1\string ##2\string ##3\endcsname}%
+ \def\UTFviiiFourOctets##1##2##3##4{%
+ \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+ \expandafter\expandafter\expandafter\expandafter
+ \expandafter\expandafter\expandafter
+ \gdef\UTFviiiTmp{#2}%
+ \endgroup}
+
+ \gdef\parseXMLCharref{%
+ \ifnum\countUTFz < "A0\relax
+ \errhelp = \EMsimple
+ \errmessage{Cannot define Unicode char value < 00A0}%
+ \else\ifnum\countUTFz < "800\relax
+ \parseUTFviiiA,%
+ \parseUTFviiiB C\UTFviiiTwoOctets.,%
+ \else\ifnum\countUTFz < "10000\relax
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+ \else
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiA!%
+ \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+ \fi\fi\fi
+ }
+
+ \gdef\parseUTFviiiA#1{%
+ \countUTFx = \countUTFz
+ \divide\countUTFz by 64
+ \countUTFy = \countUTFz
+ \multiply\countUTFz by 64
+ \advance\countUTFx by -\countUTFz
+ \advance\countUTFx by 128
+ \uccode `#1\countUTFx
+ \countUTFz = \countUTFy}
+
+ \gdef\parseUTFviiiB#1#2#3#4{%
+ \advance\countUTFz by "#10\relax
+ \uccode `#3\countUTFz
+ \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+ \DeclareUnicodeCharacter{00A0}{\tie}
+ \DeclareUnicodeCharacter{00A1}{\exclamdown}
+ \DeclareUnicodeCharacter{00A3}{\pounds}
+ \DeclareUnicodeCharacter{00A8}{\"{ }}
+ \DeclareUnicodeCharacter{00A9}{\copyright}
+ \DeclareUnicodeCharacter{00AA}{\ordf}
+ \DeclareUnicodeCharacter{00AB}{\guillemetleft}
+ \DeclareUnicodeCharacter{00AD}{\-}
+ \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+ \DeclareUnicodeCharacter{00AF}{\={ }}
+
+ \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+ \DeclareUnicodeCharacter{00B4}{\'{ }}
+ \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+ \DeclareUnicodeCharacter{00BA}{\ordm}
+ \DeclareUnicodeCharacter{00BB}{\guillemetright}
+ \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+ \DeclareUnicodeCharacter{00C0}{\`A}
+ \DeclareUnicodeCharacter{00C1}{\'A}
+ \DeclareUnicodeCharacter{00C2}{\^A}
+ \DeclareUnicodeCharacter{00C3}{\~A}
+ \DeclareUnicodeCharacter{00C4}{\"A}
+ \DeclareUnicodeCharacter{00C5}{\AA}
+ \DeclareUnicodeCharacter{00C6}{\AE}
+ \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+ \DeclareUnicodeCharacter{00C8}{\`E}
+ \DeclareUnicodeCharacter{00C9}{\'E}
+ \DeclareUnicodeCharacter{00CA}{\^E}
+ \DeclareUnicodeCharacter{00CB}{\"E}
+ \DeclareUnicodeCharacter{00CC}{\`I}
+ \DeclareUnicodeCharacter{00CD}{\'I}
+ \DeclareUnicodeCharacter{00CE}{\^I}
+ \DeclareUnicodeCharacter{00CF}{\"I}
+
+ \DeclareUnicodeCharacter{00D0}{\DH}
+ \DeclareUnicodeCharacter{00D1}{\~N}
+ \DeclareUnicodeCharacter{00D2}{\`O}
+ \DeclareUnicodeCharacter{00D3}{\'O}
+ \DeclareUnicodeCharacter{00D4}{\^O}
+ \DeclareUnicodeCharacter{00D5}{\~O}
+ \DeclareUnicodeCharacter{00D6}{\"O}
+ \DeclareUnicodeCharacter{00D8}{\O}
+ \DeclareUnicodeCharacter{00D9}{\`U}
+ \DeclareUnicodeCharacter{00DA}{\'U}
+ \DeclareUnicodeCharacter{00DB}{\^U}
+ \DeclareUnicodeCharacter{00DC}{\"U}
+ \DeclareUnicodeCharacter{00DD}{\'Y}
+ \DeclareUnicodeCharacter{00DE}{\TH}
+ \DeclareUnicodeCharacter{00DF}{\ss}
+
+ \DeclareUnicodeCharacter{00E0}{\`a}
+ \DeclareUnicodeCharacter{00E1}{\'a}
+ \DeclareUnicodeCharacter{00E2}{\^a}
+ \DeclareUnicodeCharacter{00E3}{\~a}
+ \DeclareUnicodeCharacter{00E4}{\"a}
+ \DeclareUnicodeCharacter{00E5}{\aa}
+ \DeclareUnicodeCharacter{00E6}{\ae}
+ \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+ \DeclareUnicodeCharacter{00E8}{\`e}
+ \DeclareUnicodeCharacter{00E9}{\'e}
+ \DeclareUnicodeCharacter{00EA}{\^e}
+ \DeclareUnicodeCharacter{00EB}{\"e}
+ \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+ \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{00F0}{\dh}
+ \DeclareUnicodeCharacter{00F1}{\~n}
+ \DeclareUnicodeCharacter{00F2}{\`o}
+ \DeclareUnicodeCharacter{00F3}{\'o}
+ \DeclareUnicodeCharacter{00F4}{\^o}
+ \DeclareUnicodeCharacter{00F5}{\~o}
+ \DeclareUnicodeCharacter{00F6}{\"o}
+ \DeclareUnicodeCharacter{00F8}{\o}
+ \DeclareUnicodeCharacter{00F9}{\`u}
+ \DeclareUnicodeCharacter{00FA}{\'u}
+ \DeclareUnicodeCharacter{00FB}{\^u}
+ \DeclareUnicodeCharacter{00FC}{\"u}
+ \DeclareUnicodeCharacter{00FD}{\'y}
+ \DeclareUnicodeCharacter{00FE}{\th}
+ \DeclareUnicodeCharacter{00FF}{\"y}
+
+ \DeclareUnicodeCharacter{0100}{\=A}
+ \DeclareUnicodeCharacter{0101}{\=a}
+ \DeclareUnicodeCharacter{0102}{\u{A}}
+ \DeclareUnicodeCharacter{0103}{\u{a}}
+ \DeclareUnicodeCharacter{0104}{\ogonek{A}}
+ \DeclareUnicodeCharacter{0105}{\ogonek{a}}
+ \DeclareUnicodeCharacter{0106}{\'C}
+ \DeclareUnicodeCharacter{0107}{\'c}
+ \DeclareUnicodeCharacter{0108}{\^C}
+ \DeclareUnicodeCharacter{0109}{\^c}
+ \DeclareUnicodeCharacter{0118}{\ogonek{E}}
+ \DeclareUnicodeCharacter{0119}{\ogonek{e}}
+ \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+ \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+ \DeclareUnicodeCharacter{010C}{\v{C}}
+ \DeclareUnicodeCharacter{010D}{\v{c}}
+ \DeclareUnicodeCharacter{010E}{\v{D}}
+
+ \DeclareUnicodeCharacter{0112}{\=E}
+ \DeclareUnicodeCharacter{0113}{\=e}
+ \DeclareUnicodeCharacter{0114}{\u{E}}
+ \DeclareUnicodeCharacter{0115}{\u{e}}
+ \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+ \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+ \DeclareUnicodeCharacter{011A}{\v{E}}
+ \DeclareUnicodeCharacter{011B}{\v{e}}
+ \DeclareUnicodeCharacter{011C}{\^G}
+ \DeclareUnicodeCharacter{011D}{\^g}
+ \DeclareUnicodeCharacter{011E}{\u{G}}
+ \DeclareUnicodeCharacter{011F}{\u{g}}
+
+ \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+ \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+ \DeclareUnicodeCharacter{0124}{\^H}
+ \DeclareUnicodeCharacter{0125}{\^h}
+ \DeclareUnicodeCharacter{0128}{\~I}
+ \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+ \DeclareUnicodeCharacter{012A}{\=I}
+ \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+ \DeclareUnicodeCharacter{012C}{\u{I}}
+ \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+ \DeclareUnicodeCharacter{0131}{\dotless{i}}
+ \DeclareUnicodeCharacter{0132}{IJ}
+ \DeclareUnicodeCharacter{0133}{ij}
+ \DeclareUnicodeCharacter{0134}{\^J}
+ \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+ \DeclareUnicodeCharacter{0139}{\'L}
+ \DeclareUnicodeCharacter{013A}{\'l}
+
+ \DeclareUnicodeCharacter{0141}{\L}
+ \DeclareUnicodeCharacter{0142}{\l}
+ \DeclareUnicodeCharacter{0143}{\'N}
+ \DeclareUnicodeCharacter{0144}{\'n}
+ \DeclareUnicodeCharacter{0147}{\v{N}}
+ \DeclareUnicodeCharacter{0148}{\v{n}}
+ \DeclareUnicodeCharacter{014C}{\=O}
+ \DeclareUnicodeCharacter{014D}{\=o}
+ \DeclareUnicodeCharacter{014E}{\u{O}}
+ \DeclareUnicodeCharacter{014F}{\u{o}}
+
+ \DeclareUnicodeCharacter{0150}{\H{O}}
+ \DeclareUnicodeCharacter{0151}{\H{o}}
+ \DeclareUnicodeCharacter{0152}{\OE}
+ \DeclareUnicodeCharacter{0153}{\oe}
+ \DeclareUnicodeCharacter{0154}{\'R}
+ \DeclareUnicodeCharacter{0155}{\'r}
+ \DeclareUnicodeCharacter{0158}{\v{R}}
+ \DeclareUnicodeCharacter{0159}{\v{r}}
+ \DeclareUnicodeCharacter{015A}{\'S}
+ \DeclareUnicodeCharacter{015B}{\'s}
+ \DeclareUnicodeCharacter{015C}{\^S}
+ \DeclareUnicodeCharacter{015D}{\^s}
+ \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+ \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+ \DeclareUnicodeCharacter{0160}{\v{S}}
+ \DeclareUnicodeCharacter{0161}{\v{s}}
+ \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+ \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+ \DeclareUnicodeCharacter{0164}{\v{T}}
+
+ \DeclareUnicodeCharacter{0168}{\~U}
+ \DeclareUnicodeCharacter{0169}{\~u}
+ \DeclareUnicodeCharacter{016A}{\=U}
+ \DeclareUnicodeCharacter{016B}{\=u}
+ \DeclareUnicodeCharacter{016C}{\u{U}}
+ \DeclareUnicodeCharacter{016D}{\u{u}}
+ \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+ \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+ \DeclareUnicodeCharacter{0170}{\H{U}}
+ \DeclareUnicodeCharacter{0171}{\H{u}}
+ \DeclareUnicodeCharacter{0174}{\^W}
+ \DeclareUnicodeCharacter{0175}{\^w}
+ \DeclareUnicodeCharacter{0176}{\^Y}
+ \DeclareUnicodeCharacter{0177}{\^y}
+ \DeclareUnicodeCharacter{0178}{\"Y}
+ \DeclareUnicodeCharacter{0179}{\'Z}
+ \DeclareUnicodeCharacter{017A}{\'z}
+ \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+ \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+ \DeclareUnicodeCharacter{017D}{\v{Z}}
+ \DeclareUnicodeCharacter{017E}{\v{z}}
+
+ \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+ \DeclareUnicodeCharacter{01C5}{D\v{z}}
+ \DeclareUnicodeCharacter{01C6}{d\v{z}}
+ \DeclareUnicodeCharacter{01C7}{LJ}
+ \DeclareUnicodeCharacter{01C8}{Lj}
+ \DeclareUnicodeCharacter{01C9}{lj}
+ \DeclareUnicodeCharacter{01CA}{NJ}
+ \DeclareUnicodeCharacter{01CB}{Nj}
+ \DeclareUnicodeCharacter{01CC}{nj}
+ \DeclareUnicodeCharacter{01CD}{\v{A}}
+ \DeclareUnicodeCharacter{01CE}{\v{a}}
+ \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+ \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+ \DeclareUnicodeCharacter{01D1}{\v{O}}
+ \DeclareUnicodeCharacter{01D2}{\v{o}}
+ \DeclareUnicodeCharacter{01D3}{\v{U}}
+ \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+ \DeclareUnicodeCharacter{01E2}{\={\AE}}
+ \DeclareUnicodeCharacter{01E3}{\={\ae}}
+ \DeclareUnicodeCharacter{01E6}{\v{G}}
+ \DeclareUnicodeCharacter{01E7}{\v{g}}
+ \DeclareUnicodeCharacter{01E8}{\v{K}}
+ \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+ \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+ \DeclareUnicodeCharacter{01F1}{DZ}
+ \DeclareUnicodeCharacter{01F2}{Dz}
+ \DeclareUnicodeCharacter{01F3}{dz}
+ \DeclareUnicodeCharacter{01F4}{\'G}
+ \DeclareUnicodeCharacter{01F5}{\'g}
+ \DeclareUnicodeCharacter{01F8}{\`N}
+ \DeclareUnicodeCharacter{01F9}{\`n}
+ \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+ \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+ \DeclareUnicodeCharacter{01FE}{\'{\O}}
+ \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+ \DeclareUnicodeCharacter{021E}{\v{H}}
+ \DeclareUnicodeCharacter{021F}{\v{h}}
+
+ \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+ \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+ \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+ \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+ \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+ \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+ \DeclareUnicodeCharacter{0232}{\=Y}
+ \DeclareUnicodeCharacter{0233}{\=y}
+ \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+ \DeclareUnicodeCharacter{02DB}{\ogonek{ }}
+
+ \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+ \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+ \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+ \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+ \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+ \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+ \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+ \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+ \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+ \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+ \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+ \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+ \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+ \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+ \DeclareUnicodeCharacter{1E20}{\=G}
+ \DeclareUnicodeCharacter{1E21}{\=g}
+ \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+ \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+ \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+ \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+ \DeclareUnicodeCharacter{1E26}{\"H}
+ \DeclareUnicodeCharacter{1E27}{\"h}
+
+ \DeclareUnicodeCharacter{1E30}{\'K}
+ \DeclareUnicodeCharacter{1E31}{\'k}
+ \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+ \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+ \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+ \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+ \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+ \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+ \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+ \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+ \DeclareUnicodeCharacter{1E3E}{\'M}
+ \DeclareUnicodeCharacter{1E3F}{\'m}
+
+ \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+ \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+ \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+ \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+ \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+ \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+ \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+ \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+ \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+ \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+ \DeclareUnicodeCharacter{1E54}{\'P}
+ \DeclareUnicodeCharacter{1E55}{\'p}
+ \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+ \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+ \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+ \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+ \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+ \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+ \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+ \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+ \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+ \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+ \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+ \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+ \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+ \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+ \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+ \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+ \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+ \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+ \DeclareUnicodeCharacter{1E7C}{\~V}
+ \DeclareUnicodeCharacter{1E7D}{\~v}
+ \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+ \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+ \DeclareUnicodeCharacter{1E80}{\`W}
+ \DeclareUnicodeCharacter{1E81}{\`w}
+ \DeclareUnicodeCharacter{1E82}{\'W}
+ \DeclareUnicodeCharacter{1E83}{\'w}
+ \DeclareUnicodeCharacter{1E84}{\"W}
+ \DeclareUnicodeCharacter{1E85}{\"w}
+ \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+ \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+ \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+ \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+ \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+ \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+ \DeclareUnicodeCharacter{1E8C}{\"X}
+ \DeclareUnicodeCharacter{1E8D}{\"x}
+ \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+ \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+ \DeclareUnicodeCharacter{1E90}{\^Z}
+ \DeclareUnicodeCharacter{1E91}{\^z}
+ \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+ \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+ \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+ \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+ \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+ \DeclareUnicodeCharacter{1E97}{\"t}
+ \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+ \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+ \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+ \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+ \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+ \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+ \DeclareUnicodeCharacter{1EBC}{\~E}
+ \DeclareUnicodeCharacter{1EBD}{\~e}
+
+ \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+ \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+ \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+ \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+ \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+ \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+ \DeclareUnicodeCharacter{1EF2}{\`Y}
+ \DeclareUnicodeCharacter{1EF3}{\`y}
+ \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+ \DeclareUnicodeCharacter{1EF8}{\~Y}
+ \DeclareUnicodeCharacter{1EF9}{\~y}
+
+ \DeclareUnicodeCharacter{2013}{--}
+ \DeclareUnicodeCharacter{2014}{---}
+ \DeclareUnicodeCharacter{2018}{\quoteleft}
+ \DeclareUnicodeCharacter{2019}{\quoteright}
+ \DeclareUnicodeCharacter{201A}{\quotesinglbase}
+ \DeclareUnicodeCharacter{201C}{\quotedblleft}
+ \DeclareUnicodeCharacter{201D}{\quotedblright}
+ \DeclareUnicodeCharacter{201E}{\quotedblbase}
+ \DeclareUnicodeCharacter{2022}{\bullet}
+ \DeclareUnicodeCharacter{2026}{\dots}
+ \DeclareUnicodeCharacter{2039}{\guilsinglleft}
+ \DeclareUnicodeCharacter{203A}{\guilsinglright}
+ \DeclareUnicodeCharacter{20AC}{\euro}
+
+ \DeclareUnicodeCharacter{2192}{\expansion}
+ \DeclareUnicodeCharacter{21D2}{\result}
+
+ \DeclareUnicodeCharacter{2212}{\minus}
+ \DeclareUnicodeCharacter{2217}{\point}
+ \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+ \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be very finicky about underfull hboxes, either.
+\hbadness = 6666
+
+% Following George Bush, get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+ \ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+ \else
+ \emergencystretch = .15\hsize
+ \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading. The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+ \voffset = #3\relax
+ \topskip = #6\relax
+ \splittopskip = \topskip
+ %
+ \vsize = #1\relax
+ \advance\vsize by \topskip
+ \outervsize = \vsize
+ \advance\outervsize by 2\topandbottommargin
+ \pageheight = \vsize
+ %
+ \hsize = #2\relax
+ \outerhsize = \hsize
+ \advance\outerhsize by 0.5in
+ \pagewidth = \hsize
+ %
+ \normaloffset = #4\relax
+ \bindingoffset = #5\relax
+ %
+ \ifpdf
+ \pdfpageheight #7\relax
+ \pdfpagewidth #8\relax
+ % if we don't reset these, they will remain at "1 true in" of
+ % whatever layout pdftex was dumped with.
+ \pdfhorigin = 1 true in
+ \pdfvorigin = 1 true in
+ \fi
+ %
+ \setleading{\textleading}
+ %
+ \parindent = \defaultparindent
+ \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % If page is nothing but text, make it come out even.
+ \internalpagesizes{607.2pt}{6in}% that's 46 lines
+ {\voffset}{.25in}%
+ {\bindingoffset}{36pt}%
+ {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+ \parskip = 2pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.5in}{5in}%
+ {-.2in}{0in}%
+ {\bindingoffset}{16pt}%
+ {9.25in}{7in}%
+ %
+ \lispnarrowing = 0.3in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+ \parskip = 1.5pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.4in}{4.8in}%
+ {-.2in}{-.4in}%
+ {0pt}{14pt}%
+ {9in}{6in}%
+ %
+ \lispnarrowing = 0.25in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % Double-side printing via postscript on Laserjet 4050
+ % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+ % To change the settings for a different printer or situation, adjust
+ % \normaloffset until the front-side and back-side texts align. Then
+ % do the same for \bindingoffset. You can set these for testing in
+ % your texinfo source file like this:
+ % @tex
+ % \global\normaloffset = -6mm
+ % \global\bindingoffset = 10mm
+ % @end tex
+ \internalpagesizes{673.2pt}{160mm}% that's 51 lines
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{44pt}%
+ {297mm}{210mm}%
+ %
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+ \parskip = 2pt plus 1pt minus 0.1pt
+ \textleading = 12.5pt
+ %
+ \internalpagesizes{160mm}{120mm}%
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{8pt}%
+ {210mm}{148mm}%
+ %
+ \lispnarrowing = 0.2in
+ \tolerance = 800
+ \hfuzz = 1.2pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 2mm
+ \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{237mm}{150mm}%
+ {\voffset}{4.6mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ %
+ % Must explicitly reset to 0 because we call \afourpaper.
+ \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{241mm}{165mm}%
+ {\voffset}{-2.95mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+ \globaldefs = 1
+ %
+ \parskip = 3pt plus 2pt minus 1pt
+ \setleading{\textleading}%
+ %
+ \dimen0 = #1\relax
+ \advance\dimen0 by \voffset
+ %
+ \dimen2 = \hsize
+ \advance\dimen2 by \normaloffset
+ %
+ \internalpagesizes{#1}{\hsize}%
+ {\voffset}{\normaloffset}%
+ {\bindingoffset}{44pt}%
+ {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+\def^^L{\par} % remove \outer, so ^L can appear in an @comment
+
+% DEL is a comment character, in case @c does not suffice.
+\catcode`\^^? = 14
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other \def\normaldoublequote{"}
+\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix
+\catcode`\+=\other \def\normalplus{+}
+\catcode`\<=\other \def\normalless{<}
+\catcode`\>=\other \def\normalgreater{>}
+\catcode`\^=\other \def\normalcaret{^}
+\catcode`\_=\other \def\normalunderscore{_}
+\catcode`\|=\other \def\normalverticalbar{|}
+\catcode`\~=\other \def\normaltilde{~}
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font. Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts. But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+ \normalturnoffactive
+ \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active % @ for escape char from now on.
+
+% The story here is that in math mode, the \char of \backslashcurfont
+% ends up printing the roman \ from the math symbol font (because \char
+% in math mode uses the \mathcode, and plain.tex sets
+% \mathcode`\\="026E). It seems better for @backslashchar{} to always
+% print a typewriter backslash, hence we use an explicit \mathchar,
+% which is the decimal equivalent of "715c (class 7, e.g., use \fam;
+% ignored family value; char position "5C). We can't use " for the
+% usual hex value because it has already been made active.
+@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}}
+@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents.
+
+% On startup, @fixbackslash assigns:
+% @let \ = @normalbackslash
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other. We switch back and forth between these.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.
+%
+@def@normalturnoffactive{%
+ @let"=@normaldoublequote
+ @let$=@normaldollar %$ font-lock fix
+ @let+=@normalplus
+ @let<=@normalless
+ @let>=@normalgreater
+ @let\=@normalbackslash
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let~=@normaltilde
+ @markupsetuplqdefault
+ @markupsetuprqdefault
+ @unsepspaces
+}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\' in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+ @ifx\@eatinput @let\ = @normalbackslash @fi
+ @catcode`+=@active
+ @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These (along with & and #) are made active for url-breaking, so need
+% active definitions as the normal characters.
+@def@normaldot{.}
+@def@normalquest{?}
+@def@normalslash{/}
+
+% These look ok in all fonts, so just make them not special.
+% @hashchar{} gets its own user-level command, because of #line.
+@catcode`@& = @other @def@normalamp{&}
+@catcode`@# = @other @def@normalhash{#}
+@catcode`@% = @other @def@normalpercent{%}
+
+@let @hashchar = @normalhash
+
+@c Finally, make ` and ' active, so that txicodequoteundirected and
+@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we
+@c don't make ` and ' active, @code will not get them as active chars.
+@c Do this last of all since we use ` in the previous @catcode assignments.
+@catcode`@'=@active
+@catcode`@`=@active
+@markupsetuplqdefault
+@markupsetuprqdefault
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/mpc/doc/version.texi b/mpc/doc/version.texi
new file mode 100644
index 0000000000..200ab0df3a
--- /dev/null
+++ b/mpc/doc/version.texi
@@ -0,0 +1,4 @@
+@set UPDATED 15 January 2014
+@set UPDATED-MONTH January 2014
+@set EDITION 1.0.2
+@set VERSION 1.0.2
diff --git a/mpc/install-sh b/mpc/install-sh
new file mode 100755
index 0000000000..a9244eb078
--- /dev/null
+++ b/mpc/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-01-19.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for `test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mpc/ltmain.sh b/mpc/ltmain.sh
new file mode 100644
index 0000000000..33f642a0f0
--- /dev/null
+++ b/mpc/ltmain.sh
@@ -0,0 +1,9661 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --no-quiet, --no-silent
+# print informational messages (default)
+# --no-warn don't display warning messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print more informational messages than default
+# --no-verbose don't print the extra informational messages
+# --version print version information
+# -h, --help, --help-all print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE. When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.1
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.2 Debian-2.4.2-1.1"
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+ s@/\./@/@g
+ t dotsl
+ s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+# value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test "$func_normal_abspath_tpath" = / ; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result" ; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+# value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=${func_dirname_result}
+ if test "x$func_relative_path_tlibdir" = x ; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test "x$func_stripname_result" != x ; then
+ func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+ fi
+
+ # Normalisation. If bindir is libdir, return empty string,
+ # else relative path ending with a slash; either way, target
+ # file name can be directly appended.
+ if test ! -z "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result/"
+ func_relative_path_result=$func_stripname_result
+ fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "$1" | $SED \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $opt_debug
+
+ $SED -n '/(C)/!b go
+ :more
+ /\./!{
+ N
+ s/\n# / /
+ b more
+ }
+ :go
+ /^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/^# *.*--help/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ echo
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ :print
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+ p
+ d
+ }
+ /^# .* home page:/b print
+ /^# General help using/b print
+ ' < "$progpath"
+ ret=$?
+ if test -z "$1"; then
+ exit $ret
+ fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $opt_debug
+
+ func_error "missing argument for $1."
+ exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+ my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+ my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+ func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+ func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+ my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+ my_sed_long_arg='1s/^--[^=]*=//'
+
+ func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+ func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+ func_quote_for_eval "${2}"
+ eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly. This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+ # this just eases exit handling
+ while test $# -gt 0; do
+ opt="$1"
+ shift
+ case $opt in
+ --debug|-x) opt_debug='set -x'
+ func_echo "enabling shell trace mode"
+ $opt_debug
+ ;;
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+ --config)
+ opt_config=:
+func_config
+ ;;
+ --dlopen|-dlopen)
+ optarg="$1"
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+ shift
+ ;;
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=:
+ ;;
+ --features)
+ opt_features=:
+func_features
+ ;;
+ --finish)
+ opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ --help)
+ opt_help=:
+ ;;
+ --help-all)
+ opt_help_all=:
+opt_help=': help-all'
+ ;;
+ --mode)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_mode="$optarg"
+case $optarg in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+esac
+ shift
+ ;;
+ --no-silent|--no-quiet)
+ opt_silent=false
+func_append preserve_args " $opt"
+ ;;
+ --no-warning|--no-warn)
+ opt_warning=false
+func_append preserve_args " $opt"
+ ;;
+ --no-verbose)
+ opt_verbose=false
+func_append preserve_args " $opt"
+ ;;
+ --silent|--quiet)
+ opt_silent=:
+func_append preserve_args " $opt"
+ opt_verbose=false
+ ;;
+ --verbose|-v)
+ opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+ ;;
+ --tag)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+ --version) func_version ;;
+
+ # Separate optargs to long options:
+ --*=*)
+ func_split_long_opt "$opt"
+ set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-n*|-v*)
+ func_split_short_opt "$opt"
+ set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+ *) set dummy "$opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # Validate options:
+
+ # save first non-option argument
+ if test "$#" -gt 0; then
+ nonopt="$opt"
+ shift
+ fi
+
+ # preserve --debug
+ test "$opt_debug" = : || func_append preserve_args " --debug"
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$opt_mode' for more information."
+ }
+
+
+ # Bail if the options were screwed
+ $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case "$lt_sysroot:$1" in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result="=$func_stripname_result"
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $opt_debug
+ func_convert_core_file_wine_to_w32_result="$1"
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $opt_debug
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=""
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $opt_debug
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $opt_debug
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $opt_debug
+ if test -z "$2" && test -n "$1" ; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " \`$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result="$1"
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $opt_debug
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " \`$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result="$3"
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $opt_debug
+ case $4 in
+ $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $opt_debug
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $opt_debug
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $opt_debug
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd="func_convert_path_${func_stripname_result}"
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $opt_debug
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_append_quoted lastarg "$arg"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test "$opt_help" = :; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | sed -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ sed '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "\`$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument \`$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test "x$prev" = x-m && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=""
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname" ; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename="$func_basename_result"
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename" ; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $opt_debug
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $opt_debug
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $opt_debug
+ if func_cygming_gnu_implib_p "$1" ; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1" ; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=""
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ if test "$lock_old_archive_extraction" = yes; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test "$lock_old_archive_extraction" = yes; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+# define _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (strcmp (argv[i], debug_opt) == 0)
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $opt_debug
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir="$arg"
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps ; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test "$prefer_static_libs" = yes ||
+ test "$prefer_static_libs,$installed" = "built,no"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$lt_sysroot$libdir"
+ absdir="$lt_sysroot$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ case "$host" in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ echo
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$opt_mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$absdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$opt_mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ func_append libobjs " $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$opt_mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test "$want_nocaseglob" = yes; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Remove ${wl} instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd1 in $cmds; do
+ IFS="$save_ifs"
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test "$try_normal_branch" = yes \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=${output_objdir}/${output_la}.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " ${wl}-bind_at_load"
+ func_append finalize_command " ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ func_append oldobjs " $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ func_resolve_sysroot "$deplib"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test "x$bindir" != x ;
+ then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=yes ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ odir="$objdir"
+ else
+ odir="$dir/$objdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$opt_mode" = uninstall && odir="$dir"
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test "$opt_mode" = clean; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case "$opt_mode" in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$opt_mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ func_append rmfiles " $odir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/mpc/m4/ax_c_check_flag.m4 b/mpc/m4/ax_c_check_flag.m4
new file mode 100644
index 0000000000..d96df54ba5
--- /dev/null
+++ b/mpc/m4/ax_c_check_flag.m4
@@ -0,0 +1,86 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_c_check_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_C_CHECK_FLAG(FLAG-TO-CHECK,[PROLOGUE],[BODY],[ACTION-IF-SUCCESS],[ACTION-IF-FAILURE])
+#
+# DESCRIPTION
+#
+# This macro tests if the C compiler supports the flag FLAG-TO-CHECK. If
+# successfull execute ACTION-IF-SUCCESS otherwise ACTION-IF-FAILURE.
+# PROLOGUE and BODY are optional and should be used as in AC_LANG_PROGRAM
+# macro.
+#
+# This code is inspired from KDE_CHECK_COMPILER_FLAG macro. Thanks to
+# Bogdan Drozdowski <bogdandr@op.pl> for testing and bug fixes.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Francesco Salvestrini <salvestrini@users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 6
+
+AC_DEFUN([AX_C_CHECK_FLAG],[
+ AC_PREREQ([2.61])
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_PROG_SED])
+
+ flag=`echo "$1" | $SED 'y% .=/+-(){}<>:*,%_______________%'`
+
+ AC_CACHE_CHECK([whether the C compiler accepts the $1 flag],
+ [ax_cv_c_check_flag_$flag],[
+
+ AC_LANG_PUSH([C])
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([$2],[$3])
+ ],[
+ eval "ax_cv_c_check_flag_$flag=yes"
+ ],[
+ eval "ax_cv_c_check_flag_$flag=no"
+ ])
+
+ CFLAGS="$save_CFLAGS"
+
+ AC_LANG_POP
+
+ ])
+
+ AS_IF([eval "test \"`echo '$ax_cv_c_check_flag_'$flag`\" = yes"],[
+ :
+ $4
+ ],[
+ :
+ $5
+ ])
+])
diff --git a/mpc/m4/ax_gcc_option.m4 b/mpc/m4/ax_gcc_option.m4
new file mode 100644
index 0000000000..f8c7cd1310
--- /dev/null
+++ b/mpc/m4/ax_gcc_option.m4
@@ -0,0 +1,130 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_gcc_option.html
+# ===========================================================================
+#
+# OBSOLETE MACRO
+#
+# Deprecated in favor of AX_C_CHECK_FLAG, AX_CXX_CHECK_FLAG,
+# AX_CPP_CHECK_FLAG, AX_CXXCPP_CHECK_FLAG and AX_LD_CHECK_FLAG.
+#
+# SYNOPSIS
+#
+# AX_GCC_OPTION(OPTION,EXTRA-OPTIONS,TEST-PROGRAM,ACTION-IF-SUCCESSFUL,ACTION-IF-NOT-SUCCESFUL)
+#
+# DESCRIPTION
+#
+# AX_GCC_OPTION checks wheter gcc accepts the passed OPTION. If it accepts
+# the OPTION then ACTION-IF-SUCCESSFUL will be executed, otherwise
+# ACTION-IF-UNSUCCESSFUL.
+#
+# A typical usage should be the following one:
+#
+# AX_GCC_OPTION([-fomit-frame-pointer],[],[],[
+# AC_MSG_NOTICE([The option is supported])],[
+# AC_MSG_NOTICE([No luck this time])
+# ])
+#
+# The macro doesn't discriminate between languages so, if you are testing
+# for an option that works for C++ but not for C you should use '-x c++'
+# as EXTRA-OPTIONS:
+#
+# AX_GCC_OPTION([-fno-rtti],[-x c++],[],[ ... ],[ ... ])
+#
+# OPTION is tested against the following code:
+#
+# int main()
+# {
+# return 0;
+# }
+#
+# The optional TEST-PROGRAM comes handy when the default main() is not
+# suited for the option being checked
+#
+# So, if you need to test for -fstrict-prototypes option you should
+# probably use the macro as follows:
+#
+# AX_GCC_OPTION([-fstrict-prototypes],[-x c++],[
+# int main(int argc, char ** argv)
+# {
+# (void) argc;
+# (void) argv;
+#
+# return 0;
+# }
+# ],[ ... ],[ ... ])
+#
+# Note that the macro compiles but doesn't link the test program so it is
+# not suited for checking options that are passed to the linker, like:
+#
+# -Wl,-L<a-library-path>
+#
+# In order to avoid such kind of problems you should think about usinguse
+# the AX_*_CHECK_FLAG family macros
+#
+# LICENSE
+#
+# Copyright (c) 2008 Francesco Salvestrini <salvestrini@users.sourceforge.net>
+# Copyright (c) 2008 Bogdan Drozdowski <bogdandr@op.pl>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 13
+
+AC_DEFUN([AX_GCC_OPTION], [
+ AC_REQUIRE([AC_PROG_CC])
+
+ AC_MSG_CHECKING([if gcc accepts $1 option])
+
+ AS_IF([ test "x$GCC" = "xyes" ],[
+ AS_IF([ test -z "$3" ],[
+ ax_gcc_option_test="int main()
+{
+ return 0;
+}"
+ ],[
+ ax_gcc_option_test="$3"
+ ])
+
+ # Dump the test program to file
+ cat <<EOF > conftest.c
+$ax_gcc_option_test
+EOF
+
+ # Dump back the file to the log, useful for debugging purposes
+ AC_TRY_COMMAND(cat conftest.c 1>&AS_MESSAGE_LOG_FD)
+
+ AS_IF([ AC_TRY_COMMAND($CC $2 $1 -c conftest.c 1>&AS_MESSAGE_LOG_FD) ],[
+ AC_MSG_RESULT([yes])
+ $4
+ ],[
+ AC_MSG_RESULT([no])
+ $5
+ ])
+ ],[
+ AC_MSG_RESULT([no gcc available])
+ ])
+])
diff --git a/mpc/m4/ax_gcc_version.m4 b/mpc/m4/ax_gcc_version.m4
new file mode 100644
index 0000000000..9923c08028
--- /dev/null
+++ b/mpc/m4/ax_gcc_version.m4
@@ -0,0 +1,65 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_gcc_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_GCC_VERSION
+#
+# DESCRIPTION
+#
+# This macro retrieves the gcc version and returns it in the GCC_VERSION
+# variable if available, an empty string otherwise.
+#
+# LICENSE
+#
+# Copyright (c) 2009 Francesco Salvestrini <salvestrini@users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 7
+
+AC_DEFUN([AX_GCC_VERSION], [
+ GCC_VERSION=""
+ AX_GCC_OPTION([-dumpversion],[],[],[
+ ax_gcc_version_option=yes
+ ],[
+ ax_gcc_version_option=no
+ ])
+ AS_IF([test "x$GCC" = "xyes"],[
+ AS_IF([test "x$ax_gcc_version_option" != "xno"],[
+ AC_CACHE_CHECK([gcc version],[ax_cv_gcc_version],[
+ ax_cv_gcc_version="`$CC -dumpversion`"
+ AS_IF([test "x$ax_cv_gcc_version" = "x"],[
+ ax_cv_gcc_version=""
+ ])
+ ])
+ GCC_VERSION=$ax_cv_gcc_version
+ ])
+ ])
+ AC_SUBST([GCC_VERSION])
+])
diff --git a/mpc/m4/libtool.m4 b/mpc/m4/libtool.m4
new file mode 100644
index 0000000000..8ff3c76f8b
--- /dev/null
+++ b/mpc/m4/libtool.m4
@@ -0,0 +1,7851 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
+# Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file 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.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
+# Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ _LT_PROG_REPLACE_SHELLFNS
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES
+# --------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ m4_if([$1], [CXX],
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case "$ECHO" in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[ --with-sysroot[=DIR] Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([${with_sysroot}])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[123]]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd* | netbsdelf*-gnu)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ F* | *Sun*Fortran*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*) ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ freebsd1*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS="$save_LDFLAGS"])
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
+ [[If ld is used when linking, flag to hardcode $libdir into a binary
+ during linking. This must work even if $libdir does not exist]])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report which library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd[[12]]*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case ${prev}${p} in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test "$pre_test_object_deps_done" = no; then
+ case ${prev} in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+ CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+ func_split_long_opt_name=${1%%=*}
+ func_split_long_opt_arg=${1#*=}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo])
+
+ _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))])
+
+ _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+ func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+ eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/mpc/m4/ltoptions.m4 b/mpc/m4/ltoptions.m4
new file mode 100644
index 0000000000..17cfd51c0b
--- /dev/null
+++ b/mpc/m4/ltoptions.m4
@@ -0,0 +1,369 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file 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.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [pic_mode="$withval"],
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/mpc/m4/ltsugar.m4 b/mpc/m4/ltsugar.m4
new file mode 100644
index 0000000000..9000a057d3
--- /dev/null
+++ b/mpc/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file 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.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/mpc/m4/ltversion.m4 b/mpc/m4/ltversion.m4
new file mode 100644
index 0000000000..07a8602d48
--- /dev/null
+++ b/mpc/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file 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.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/mpc/m4/lt~obsolete.m4 b/mpc/m4/lt~obsolete.m4
new file mode 100644
index 0000000000..c573da90c5
--- /dev/null
+++ b/mpc/m4/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file 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.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/mpc/m4/mpc.m4 b/mpc/m4/mpc.m4
new file mode 100644
index 0000000000..414229be41
--- /dev/null
+++ b/mpc/m4/mpc.m4
@@ -0,0 +1,242 @@
+# mpc.m4
+#
+# Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+
+#
+# SYNOPSIS
+#
+#
+# MPC_COMPLEX_H
+#
+# DESCRIPTION
+#
+# Check whether complex.h is usable; if yes, define HAVE_COMPLEX_H.
+#
+AC_DEFUN([MPC_COMPLEX_H], [
+ AC_CHECK_HEADER(
+ [complex.h],
+ [
+ m4_define(
+ [MPC_CONFTEST],
+ [
+ AC_LANG_PROGRAM(
+ [[#include <complex.h>]],
+ [[complex double x = 1.0 + 2.0 * I; return (creal (x) + cimag (x));]]
+ )
+ ]
+ )
+
+ AC_SEARCH_LIBS([creal], [m])
+# needed on Solaris
+ AC_MSG_CHECKING([whether creal, cimag and I can be used])
+ AC_LINK_IFELSE(
+ [MPC_CONFTEST],
+ [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_COMPLEX_H], [1], [complex.h present and usable])
+ ],
+ [
+ AC_MSG_RESULT([no, build without support for C complex numbers])
+ ]
+ )
+ ]
+ )
+])
+
+
+#
+# SYNOPSIS
+#
+#
+# MPC_C_CHECK_FLAG([FLAG,ACCUMULATOR])
+#
+# DESCRIPTION
+#
+# Checks if the C compiler accepts the flag FLAG
+# If yes, adds it to CFLAGS.
+
+AC_DEFUN([MPC_C_CHECK_FLAG], [
+ AX_C_CHECK_FLAG($1,,,[CFLAGS="$CFLAGS $1"])
+])
+
+
+#
+# SYNOPSIS
+#
+#
+# MPC_C_CHECK_WARNINGFLAGS
+#
+# DESCRIPTION
+#
+# For development version only: Checks if gcc accepts warning flags.
+# Adds accepted ones to CFLAGS.
+#
+AC_DEFUN([MPC_C_CHECK_WARNINGCFLAGS], [
+ AC_REQUIRE([AC_PROG_GREP])
+ if echo $VERSION | grep -c dev >/dev/null 2>&1 ; then
+ if test "x$GCC" = "xyes" -a "x$compiler" != "xicc" -a "x$compiler" != "xg++"; then
+ # enable -Werror for myself (Andreas Enge)
+ if test "x$USER" = "xenge"; then
+ MPC_C_CHECK_FLAG(-Werror)
+ fi
+ MPC_C_CHECK_FLAG(-g)
+ MPC_C_CHECK_FLAG(-std=c99)
+ MPC_C_CHECK_FLAG(-pedantic)
+ MPC_C_CHECK_FLAG(-Wno-long-long)
+ MPC_C_CHECK_FLAG(-Wall)
+ MPC_C_CHECK_FLAG(-Wextra)
+ MPC_C_CHECK_FLAG(-Wdeclaration-after-statement)
+ MPC_C_CHECK_FLAG(-Wundef)
+ MPC_C_CHECK_FLAG(-Wshadow)
+ MPC_C_CHECK_FLAG(-Wstrict-prototypes)
+ MPC_C_CHECK_FLAG(-Wmissing-prototypes)
+ MPC_C_CHECK_FLAG(-Wno-unused-value)
+ fi
+ fi
+])
+
+
+#
+# SYNOPSIS
+#
+#
+# MPC_GMP_CC_CFLAGS
+#
+# DESCRIPTION
+#
+# Checks if CC and CFLAGS can be extracted from gmp.h
+# essentially copied from mpfr
+#
+AC_DEFUN([MPC_GMP_CC_CFLAGS], [
+ AC_MSG_CHECKING(for CC and CFLAGS in gmp.h)
+ # AC_PROG_CPP triggers the search for a C compiler; use hack instead
+ for cpp in /lib/cpp gcc cc c99
+ do
+ test $cpp = /lib/cpp || cpp="$cpp -E"
+ echo foo > conftest.c
+ if $cpp $CPPFLAGS conftest.c > /dev/null 2> /dev/null ; then
+ # Get CC
+ echo "#include \"gmp.h\"" > conftest.c
+ echo "MPFR_OPTION __GMP_CC" >> conftest.c
+ GMP_CC=`$cpp $CPPFLAGS conftest.c 2> /dev/null | $EGREP MPFR_OPTION | $SED -e 's/MPFR_OPTION //g;s/ *" *//g'`
+ # Get CFLAGS
+ echo "#include \"gmp.h\"" > conftest.c
+ echo "MPFR_OPTION __GMP_CFLAGS" >> conftest.c
+ GMP_CFLAGS=`$cpp $CPPFLAGS conftest.c 2> /dev/null | $EGREP MPFR_OPTION | $SED -e 's/MPFR_OPTION //g;s/ *" *//g'`
+ break
+ fi
+ done
+
+ if test "x$GMP_CFLAGS" = "x__GMP_CFLAGS" -o "x$GMP_CC" = "x__GMP_CC" ; then
+ AC_MSG_RESULT(no)
+ GMP_CC=
+ GMP_CFLAGS=
+ else
+ AC_MSG_RESULT(yes [CC=$GMP_CC CFLAGS=$GMP_CFLAGS])
+ fi
+
+ # Check for validity of CC and CFLAGS obtained from gmp.h
+ if test -n "$GMP_CC$GMP_CFLAGS" ; then
+ AC_MSG_CHECKING(for CC=$GMP_CC and CFLAGS=$GMP_CFLAGS)
+ echo "int main (void) { return 0; }" > conftest.c
+ if $GMP_CC $GMP_CFLAGS -o conftest conftest.c 2> /dev/null ; then
+ AC_MSG_RESULT(yes)
+ CC=$GMP_CC
+ CFLAGS=$GMP_CFLAGS
+ else
+ AC_MSG_RESULT(no)
+ fi
+ fi
+
+ rm -f conftest*
+])
+
+
+#
+# SYNOPSIS
+#
+#
+# MPC_WINDOWS
+#
+# DESCRIPTION
+#
+# Additional checks on windows
+# libtool requires "-no-undefined" for win32 dll
+# It also disables the tests involving the linking with LIBGMP if DLL
+#
+AC_DEFUN([MPC_WINDOWS], [
+ if test "$enable_shared" = yes; then
+ MPC_LDFLAGS="$MPC_LDFLAGS -no-undefined"
+ AC_MSG_CHECKING(for DLL/static gmp)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include "gmp.h"
+#if !__GMP_LIBGMP_DLL
+#error
+error
+#endif
+ ]], [[]])],[AC_MSG_RESULT(DLL)],[
+ AC_MSG_RESULT(static)
+ AC_MSG_ERROR([gmp is not available as a DLL: use --enable-static --disable-shared]) ])
+ AC_MSG_CHECKING(for DLL/static mpfr)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include "mpfr.h"
+#if !__GMP_LIBGMP_DLL
+#error
+error
+#endif
+ ]], [[]])],[AC_MSG_RESULT(DLL)],[
+ AC_MSG_RESULT(static)
+ AC_MSG_ERROR([mpfr is not available as a DLL: use --enable-static --disable-shared]) ])
+ else
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include "gmp.h"
+#if __GMP_LIBGMP_DLL
+#error
+error
+#endif
+ ]], [[]])],[AC_MSG_RESULT(static)],[
+ AC_MSG_RESULT(DLL)
+ AC_MSG_ERROR([gmp is only available as a DLL: use --disable-static --enable-shared]) ])
+ fi
+ ;;
+])
+
+
+#
+# SYNOPSIS
+#
+#
+# MPC_SVNVERSION
+#
+# DESCRIPTION
+#
+# If current version string contains "dev", substitutes svn version into
+# SVNVERSION
+#
+AC_DEFUN([MPC_SVNVERSION], [
+ if echo $VERSION | grep -c dev >/dev/null 2>&1 ; then
+ AC_CHECK_PROG([HASSVNVERSION], [svnversion], [yes], [no])
+ AS_IF([test "x$HASSVNVERSION" = "xyes"], [
+ AC_MSG_CHECKING([for current svn version])
+ SVNVERSION=esyscmd([svnversion -n])
+ AC_SUBST([SVNVERSION])
+ AC_MSG_RESULT([$SVNVERSION])
+ ])
+ fi
+])
diff --git a/mpc/m4/valgrind-tests.m4 b/mpc/m4/valgrind-tests.m4
new file mode 100644
index 0000000000..e38236ed2c
--- /dev/null
+++ b/mpc/m4/valgrind-tests.m4
@@ -0,0 +1,40 @@
+# valgrind-tests.m4 serial 2
+dnl Copyright (C) 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Simon Josefsson
+dnl with adaptations to MPC
+
+# gl_VALGRIND_TESTS()
+# -------------------
+# Check if valgrind is available, and set VALGRIND to it if available.
+AC_DEFUN([gl_VALGRIND_TESTS],
+[
+ # Run self-tests under valgrind?
+ if test "$cross_compiling" = no; then
+ AC_CHECK_PROGS(VALGRIND, valgrind)
+ fi
+
+ if test -n "$VALGRIND" && $VALGRIND -q true > /dev/null 2>&1; then
+ opt_valgrind_tests=yes
+ VALGRIND="$VALGRIND -q --error-exitcode=1 --leak-check=full"
+# Addition AE: enable suppression file through a shell variable
+ AC_MSG_CHECKING([for valgrind suppression file])
+ if test -n "$VALGRIND_SUPPRESSION"; then
+ AC_MSG_RESULT($VALGRIND_SUPPRESSION)
+ VALGRIND="$VALGRIND --suppressions=$VALGRIND_SUPPRESSION"
+ else
+ AC_MSG_RESULT([no])
+ fi
+ AC_DEFINE([MPC_USE_VALGRIND], 1, [Use valgrind for make check])
+ else
+ opt_valgrind_tests=no
+ VALGRIND=
+ fi
+
+ AC_MSG_CHECKING([whether self tests are run under valgrind])
+ AC_MSG_RESULT($opt_valgrind_tests)
+])
+
diff --git a/mpc/missing b/mpc/missing
new file mode 100755
index 0000000000..86a8fc31e3
--- /dev/null
+++ b/mpc/missing
@@ -0,0 +1,331 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2012-01-06.13; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ autom4te touch the output file, or create a stub one
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program). This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+ lex*|yacc*)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case $f in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te*)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison*|yacc*)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if test $# -ne 1; then
+ eval LASTARG=\${$#}
+ case $LASTARG in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f y.tab.h; then
+ echo >y.tab.h
+ fi
+ if test ! -f y.tab.c; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex*|flex*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if test $# -ne 1; then
+ eval LASTARG=\${$#}
+ case $LASTARG in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f lex.yy.c; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit $?
+ fi
+ ;;
+
+ makeinfo*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '
+ /^@setfilename/{
+ s/.* \([^ ]*\) *$/\1/
+ p
+ q
+ }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ # If the file does not exist, the user really needs makeinfo;
+ # let's fail without touching anything.
+ test -f $file || exit 1
+ touch $file
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mpc/src/Makefile.am b/mpc/src/Makefile.am
new file mode 100644
index 0000000000..0ece3117e8
--- /dev/null
+++ b/mpc/src/Makefile.am
@@ -0,0 +1,34 @@
+## src/Makefile.am -- Process this file with automake to produce Makefile.in
+##
+## Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
+##
+## This file is part of GNU MPC.
+##
+## GNU MPC is free software; you can redistribute it and/or modify it under
+## the terms of the GNU Lesser General Public License as published by the
+## Free Software Foundation; either version 3 of the License, or (at your
+## option) any later version.
+##
+## GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+## FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+## more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this program. If not, see http://www.gnu.org/licenses/ .
+
+lib_LTLIBRARIES = libmpc.la
+libmpc_la_LDFLAGS = $(MPC_LDFLAGS) -version-info 3:0:0
+libmpc_la_SOURCES = mpc-impl.h abs.c acos.c acosh.c add.c add_fr.c \
+ add_si.c add_ui.c arg.c asin.c asinh.c atan.c atanh.c clear.c cmp.c \
+ cmp_si_si.c conj.c cos.c cosh.c div_2si.c div_2ui.c div.c div_fr.c \
+ div_ui.c exp.c fma.c fr_div.c fr_sub.c get_prec2.c get_prec.c \
+ get_version.c get_x.c imag.c init2.c init3.c inp_str.c log.c log10.c \
+ mem.c mul_2si.c mul_2ui.c mul.c mul_fr.c mul_i.c mul_si.c mul_ui.c \
+ neg.c norm.c out_str.c pow.c pow_fr.c \
+ pow_ld.c pow_d.c pow_si.c pow_ui.c pow_z.c proj.c real.c urandom.c set.c \
+ set_prec.c set_str.c set_x.c set_x_x.c sin.c sin_cos.c sinh.c sqr.c \
+ sqrt.c strtoc.c sub.c sub_fr.c sub_ui.c swap.c tan.c tanh.c uceil_log2.c \
+ ui_div.c ui_ui_sub.c
+
+libmpc_la_LIBADD = @LTLIBOBJS@
diff --git a/mpc/src/Makefile.in b/mpc/src/Makefile.in
new file mode 100644
index 0000000000..69b893d8b4
--- /dev/null
+++ b/mpc/src/Makefile.in
@@ -0,0 +1,683 @@
+# Makefile.in generated by automake 1.12.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2012 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@
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/depcomp logging.c
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c_check_flag.m4 \
+ $(top_srcdir)/m4/ax_gcc_option.m4 \
+ $(top_srcdir)/m4/ax_gcc_version.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/mpc.m4 $(top_srcdir)/m4/valgrind-tests.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+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__installdirs = "$(DESTDIR)$(libdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libmpc_la_DEPENDENCIES = @LTLIBOBJS@
+am_libmpc_la_OBJECTS = abs.lo acos.lo acosh.lo add.lo add_fr.lo \
+ add_si.lo add_ui.lo arg.lo asin.lo asinh.lo atan.lo atanh.lo \
+ clear.lo cmp.lo cmp_si_si.lo conj.lo cos.lo cosh.lo div_2si.lo \
+ div_2ui.lo div.lo div_fr.lo div_ui.lo exp.lo fma.lo fr_div.lo \
+ fr_sub.lo get_prec2.lo get_prec.lo get_version.lo get_x.lo \
+ imag.lo init2.lo init3.lo inp_str.lo log.lo log10.lo mem.lo \
+ mul_2si.lo mul_2ui.lo mul.lo mul_fr.lo mul_i.lo mul_si.lo \
+ mul_ui.lo neg.lo norm.lo out_str.lo pow.lo pow_fr.lo pow_ld.lo \
+ pow_d.lo pow_si.lo pow_ui.lo pow_z.lo proj.lo real.lo \
+ urandom.lo set.lo set_prec.lo set_str.lo set_x.lo set_x_x.lo \
+ sin.lo sin_cos.lo sinh.lo sqr.lo sqrt.lo strtoc.lo sub.lo \
+ sub_fr.lo sub_ui.lo swap.lo tan.lo tanh.lo uceil_log2.lo \
+ ui_div.lo ui_ui_sub.lo
+libmpc_la_OBJECTS = $(am_libmpc_la_OBJECTS)
+libmpc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libmpc_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libmpc_la_SOURCES)
+DIST_SOURCES = $(libmpc_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCC_VERSION = @GCC_VERSION@
+GREP = @GREP@
+HASSVNVERSION = @HASSVNVERSION@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPC_LDFLAGS = @MPC_LDFLAGS@
+MPC_LOG_H = @MPC_LOG_H@
+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@
+STRIP = @STRIP@
+SVNVERSION = @SVNVERSION@
+VALGRIND = @VALGRIND@
+VERSION = @VERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+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@
+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@
+lib_LTLIBRARIES = libmpc.la
+libmpc_la_LDFLAGS = $(MPC_LDFLAGS) -version-info 3:0:0
+libmpc_la_SOURCES = mpc-impl.h abs.c acos.c acosh.c add.c add_fr.c \
+ add_si.c add_ui.c arg.c asin.c asinh.c atan.c atanh.c clear.c cmp.c \
+ cmp_si_si.c conj.c cos.c cosh.c div_2si.c div_2ui.c div.c div_fr.c \
+ div_ui.c exp.c fma.c fr_div.c fr_sub.c get_prec2.c get_prec.c \
+ get_version.c get_x.c imag.c init2.c init3.c inp_str.c log.c log10.c \
+ mem.c mul_2si.c mul_2ui.c mul.c mul_fr.c mul_i.c mul_si.c mul_ui.c \
+ neg.c norm.c out_str.c pow.c pow_fr.c \
+ pow_ld.c pow_d.c pow_si.c pow_ui.c pow_z.c proj.c real.c urandom.c set.c \
+ set_prec.c set_str.c set_x.c set_x_x.c sin.c sin_cos.c sinh.c sqr.c \
+ sqrt.c strtoc.c sub.c sub_fr.c sub_ui.c swap.c tan.c tanh.c uceil_log2.c \
+ ui_div.c ui_ui_sub.c
+
+libmpc_la_LIBADD = @LTLIBOBJS@
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: 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):
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+libmpc.la: $(libmpc_la_OBJECTS) $(libmpc_la_DEPENDENCIES) $(EXTRA_libmpc_la_DEPENDENCIES)
+ $(libmpc_la_LINK) -rpath $(libdir) $(libmpc_la_OBJECTS) $(libmpc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/logging.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acos.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acosh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add_fr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add_si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asinh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atanh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clear.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp_si_si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conj.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cos.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cosh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_2si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_2ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_fr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fma.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fr_div.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fr_sub.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_prec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_prec2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_version.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imag.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inp_str.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log10.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_2si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_2ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_fr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_i.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/neg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/norm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/out_str.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_fr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_ld.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_z.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proj.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/real.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_prec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_str.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_x_x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sin_cos.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sinh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqrt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub_fr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tanh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uceil_log2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui_div.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui_ui_sub.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/urandom.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP)'; \
+ 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
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+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:
+
+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-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf $(DEPDIR) ./$(DEPDIR)
+ -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-libLTLIBRARIES
+
+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 -rf $(DEPDIR) ./$(DEPDIR)
+ -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: uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool cscopelist ctags 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-libLTLIBRARIES 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 \
+ tags uninstall uninstall-am uninstall-libLTLIBRARIES
+
+
+# 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/mpc/src/abs.c b/mpc/src/abs.c
new file mode 100644
index 0000000000..bf1e5fda09
--- /dev/null
+++ b/mpc/src/abs.c
@@ -0,0 +1,28 @@
+/* mpc_abs -- Absolute value of a complex number.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* the rounding mode is mpfr_rnd_t here since we return an mpfr number */
+int
+mpc_abs (mpfr_ptr a, mpc_srcptr b, mpfr_rnd_t rnd)
+{
+ return mpfr_hypot (a, mpc_realref(b), mpc_imagref(b), rnd);
+}
diff --git a/mpc/src/acos.c b/mpc/src/acos.c
new file mode 100644
index 0000000000..e7a269149a
--- /dev/null
+++ b/mpc/src/acos.c
@@ -0,0 +1,228 @@
+/* mpc_acos -- arccosine of a complex number.
+
+Copyright (C) 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for MPC_ASSERT */
+#include "mpc-impl.h"
+
+int
+mpc_acos (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im, inex;
+ mpfr_prec_t p_re, p_im, p;
+ mpc_t z1;
+ mpfr_t pi_over_2;
+ mpfr_exp_t e1, e2;
+ mpfr_rnd_t rnd_im;
+ mpc_rnd_t rnd1;
+
+ inex_re = 0;
+ inex_im = 0;
+
+ /* special values */
+ if (mpfr_nan_p (mpc_realref (op)) || mpfr_nan_p (mpc_imagref (op)))
+ {
+ if (mpfr_inf_p (mpc_realref (op)) || mpfr_inf_p (mpc_imagref (op)))
+ {
+ mpfr_set_inf (mpc_imagref (rop), mpfr_signbit (mpc_imagref (op)) ? +1 : -1);
+ mpfr_set_nan (mpc_realref (rop));
+ }
+ else if (mpfr_zero_p (mpc_realref (op)))
+ {
+ inex_re = set_pi_over_2 (mpc_realref (rop), +1, MPC_RND_RE (rnd));
+ mpfr_set_nan (mpc_imagref (rop));
+ }
+ else
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ }
+
+ return MPC_INEX (inex_re, 0);
+ }
+
+ if (mpfr_inf_p (mpc_realref (op)) || mpfr_inf_p (mpc_imagref (op)))
+ {
+ if (mpfr_inf_p (mpc_realref (op)))
+ {
+ if (mpfr_inf_p (mpc_imagref (op)))
+ {
+ if (mpfr_sgn (mpc_realref (op)) > 0)
+ {
+ inex_re =
+ set_pi_over_2 (mpc_realref (rop), +1, MPC_RND_RE (rnd));
+ mpfr_div_2ui (mpc_realref (rop), mpc_realref (rop), 1, GMP_RNDN);
+ }
+ else
+ {
+
+ /* the real part of the result is 3*pi/4
+ a = o(pi) error(a) < 1 ulp(a)
+ b = o(3*a) error(b) < 2 ulp(b)
+ c = b/4 exact
+ thus 1 bit is lost */
+ mpfr_t x;
+ mpfr_prec_t prec;
+ int ok;
+ mpfr_init (x);
+ prec = mpfr_get_prec (mpc_realref (rop));
+ p = prec;
+
+ do
+ {
+ p += mpc_ceil_log2 (p);
+ mpfr_set_prec (x, p);
+ mpfr_const_pi (x, GMP_RNDD);
+ mpfr_mul_ui (x, x, 3, GMP_RNDD);
+ ok =
+ mpfr_can_round (x, p - 1, GMP_RNDD, MPC_RND_RE (rnd),
+ prec+(MPC_RND_RE (rnd) == GMP_RNDN));
+
+ } while (ok == 0);
+ inex_re =
+ mpfr_div_2ui (mpc_realref (rop), x, 2, MPC_RND_RE (rnd));
+ mpfr_clear (x);
+ }
+ }
+ else
+ {
+ if (mpfr_sgn (mpc_realref (op)) > 0)
+ mpfr_set_ui (mpc_realref (rop), 0, GMP_RNDN);
+ else
+ inex_re = mpfr_const_pi (mpc_realref (rop), MPC_RND_RE (rnd));
+ }
+ }
+ else
+ inex_re = set_pi_over_2 (mpc_realref (rop), +1, MPC_RND_RE (rnd));
+
+ mpfr_set_inf (mpc_imagref (rop), mpfr_signbit (mpc_imagref (op)) ? +1 : -1);
+
+ return MPC_INEX (inex_re, 0);
+ }
+
+ /* pure real argument */
+ if (mpfr_zero_p (mpc_imagref (op)))
+ {
+ int s_im;
+ s_im = mpfr_signbit (mpc_imagref (op));
+
+ if (mpfr_cmp_ui (mpc_realref (op), 1) > 0)
+ {
+ if (s_im)
+ inex_im = mpfr_acosh (mpc_imagref (rop), mpc_realref (op),
+ MPC_RND_IM (rnd));
+ else
+ inex_im = -mpfr_acosh (mpc_imagref (rop), mpc_realref (op),
+ INV_RND (MPC_RND_IM (rnd)));
+
+ mpfr_set_ui (mpc_realref (rop), 0, GMP_RNDN);
+ }
+ else if (mpfr_cmp_si (mpc_realref (op), -1) < 0)
+ {
+ mpfr_t minus_op_re;
+ minus_op_re[0] = mpc_realref (op)[0];
+ MPFR_CHANGE_SIGN (minus_op_re);
+
+ if (s_im)
+ inex_im = mpfr_acosh (mpc_imagref (rop), minus_op_re,
+ MPC_RND_IM (rnd));
+ else
+ inex_im = -mpfr_acosh (mpc_imagref (rop), minus_op_re,
+ INV_RND (MPC_RND_IM (rnd)));
+ inex_re = mpfr_const_pi (mpc_realref (rop), MPC_RND_RE (rnd));
+ }
+ else
+ {
+ inex_re = mpfr_acos (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd));
+ mpfr_set_ui (mpc_imagref (rop), 0, MPC_RND_IM (rnd));
+ }
+
+ if (!s_im)
+ mpc_conj (rop, rop, MPC_RNDNN);
+
+ return MPC_INEX (inex_re, inex_im);
+ }
+
+ /* pure imaginary argument */
+ if (mpfr_zero_p (mpc_realref (op)))
+ {
+ inex_re = set_pi_over_2 (mpc_realref (rop), +1, MPC_RND_RE (rnd));
+ inex_im = -mpfr_asinh (mpc_imagref (rop), mpc_imagref (op),
+ INV_RND (MPC_RND_IM (rnd)));
+ mpc_conj (rop,rop, MPC_RNDNN);
+
+ return MPC_INEX (inex_re, inex_im);
+ }
+
+ /* regular complex argument: acos(z) = Pi/2 - asin(z) */
+ p_re = mpfr_get_prec (mpc_realref(rop));
+ p_im = mpfr_get_prec (mpc_imagref(rop));
+ p = p_re;
+ mpc_init3 (z1, p, p_im); /* we round directly the imaginary part to p_im,
+ with rounding mode opposite to rnd_im */
+ rnd_im = MPC_RND_IM(rnd);
+ /* the imaginary part of asin(z) has the same sign as Im(z), thus if
+ Im(z) > 0 and rnd_im = RNDZ, we want to round the Im(asin(z)) to -Inf
+ so that -Im(asin(z)) is rounded to zero */
+ if (rnd_im == GMP_RNDZ)
+ rnd_im = mpfr_sgn (mpc_imagref(op)) > 0 ? GMP_RNDD : GMP_RNDU;
+ else
+ rnd_im = rnd_im == GMP_RNDU ? GMP_RNDD
+ : rnd_im == GMP_RNDD ? GMP_RNDU
+ : rnd_im; /* both RNDZ and RNDA map to themselves for -asin(z) */
+ rnd1 = MPC_RND (GMP_RNDN, rnd_im);
+ mpfr_init2 (pi_over_2, p);
+ for (;;)
+ {
+ p += mpc_ceil_log2 (p) + 3;
+
+ mpfr_set_prec (mpc_realref(z1), p);
+ mpfr_set_prec (pi_over_2, p);
+
+ set_pi_over_2 (pi_over_2, +1, GMP_RNDN);
+ e1 = 1; /* Exp(pi_over_2) */
+ inex = mpc_asin (z1, op, rnd1); /* asin(z) */
+ MPC_ASSERT (mpfr_sgn (mpc_imagref(z1)) * mpfr_sgn (mpc_imagref(op)) > 0);
+ inex_im = MPC_INEX_IM(inex); /* inex_im is in {-1, 0, 1} */
+ e2 = mpfr_get_exp (mpc_realref(z1));
+ mpfr_sub (mpc_realref(z1), pi_over_2, mpc_realref(z1), GMP_RNDN);
+ if (!mpfr_zero_p (mpc_realref(z1)))
+ {
+ /* the error on x=Re(z1) is bounded by 1/2 ulp(x) + 2^(e1-p-1) +
+ 2^(e2-p-1) */
+ e1 = e1 >= e2 ? e1 + 1 : e2 + 1;
+ /* the error on x is bounded by 1/2 ulp(x) + 2^(e1-p-1) */
+ e1 -= mpfr_get_exp (mpc_realref(z1));
+ /* the error on x is bounded by 1/2 ulp(x) [1 + 2^e1] */
+ e1 = e1 <= 0 ? 0 : e1;
+ /* the error on x is bounded by 2^e1 * ulp(x) */
+ mpfr_neg (mpc_imagref(z1), mpc_imagref(z1), GMP_RNDN); /* exact */
+ inex_im = -inex_im;
+ if (mpfr_can_round (mpc_realref(z1), p - e1, GMP_RNDN, GMP_RNDZ,
+ p_re + (MPC_RND_RE(rnd) == GMP_RNDN)))
+ break;
+ }
+ }
+ inex = mpc_set (rop, z1, rnd);
+ inex_re = MPC_INEX_RE(inex);
+ mpc_clear (z1);
+ mpfr_clear (pi_over_2);
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/acosh.c b/mpc/src/acosh.c
new file mode 100644
index 0000000000..782f5550c2
--- /dev/null
+++ b/mpc/src/acosh.c
@@ -0,0 +1,76 @@
+/* mpc_acosh -- inverse hyperbolic cosine of a complex number.
+
+Copyright (C) 2009, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_acosh (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ /* acosh(z) =
+ NaN + i*NaN, if z=0+i*NaN
+ -i*acos(z), if sign(Im(z)) = -
+ i*acos(z), if sign(Im(z)) = +
+ http://functions.wolfram.com/ElementaryFunctions/ArcCosh/27/02/03/01/01/
+ */
+ mpc_t a;
+ mpfr_t tmp;
+ int inex;
+
+ if (mpfr_zero_p (mpc_realref (op)) && mpfr_nan_p (mpc_imagref (op)))
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ return 0;
+ }
+
+ /* Note reversal of precisions due to later multiplication by i or -i */
+ mpc_init3 (a, MPC_PREC_IM(rop), MPC_PREC_RE(rop));
+
+ if (mpfr_signbit (mpc_imagref (op)))
+ {
+ inex = mpc_acos (a, op,
+ MPC_RND (INV_RND (MPC_RND_IM (rnd)), MPC_RND_RE (rnd)));
+
+ /* change a to -i*a, i.e., -y+i*x to x+i*y */
+ tmp[0] = mpc_realref (a)[0];
+ mpc_realref (a)[0] = mpc_imagref (a)[0];
+ mpc_imagref (a)[0] = tmp[0];
+ MPFR_CHANGE_SIGN (mpc_imagref (a));
+ inex = MPC_INEX (MPC_INEX_IM (inex), -MPC_INEX_RE (inex));
+ }
+ else
+ {
+ inex = mpc_acos (a, op,
+ MPC_RND (MPC_RND_IM (rnd), INV_RND(MPC_RND_RE (rnd))));
+
+ /* change a to i*a, i.e., y-i*x to x+i*y */
+ tmp[0] = mpc_realref (a)[0];
+ mpc_realref (a)[0] = mpc_imagref (a)[0];
+ mpc_imagref (a)[0] = tmp[0];
+ MPFR_CHANGE_SIGN (mpc_realref (a));
+ inex = MPC_INEX (-MPC_INEX_IM (inex), MPC_INEX_RE (inex));
+ }
+
+ mpc_set (rop, a, rnd);
+
+ mpc_clear (a);
+
+ return inex;
+}
diff --git a/mpc/src/add.c b/mpc/src/add.c
new file mode 100644
index 0000000000..ee9ec19b3c
--- /dev/null
+++ b/mpc/src/add.c
@@ -0,0 +1,33 @@
+/* mpc_add -- Add two complex numbers.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* return 0 iff both the real and imaginary parts are exact */
+int
+mpc_add (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_add (mpc_realref(a), mpc_realref(b), mpc_realref(c), MPC_RND_RE(rnd));
+ inex_im = mpfr_add (mpc_imagref(a), mpc_imagref(b), mpc_imagref(c), MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/add_fr.c b/mpc/src/add_fr.c
new file mode 100644
index 0000000000..ea7b59560d
--- /dev/null
+++ b/mpc/src/add_fr.c
@@ -0,0 +1,33 @@
+/* mpc_add_fr -- Add a complex number and a floating-point number.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* return 0 iff both the real and imaginary parts are exact */
+int
+mpc_add_fr (mpc_ptr a, mpc_srcptr b, mpfr_srcptr c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_add (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_set (mpc_imagref(a), mpc_imagref(b), MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/add_si.c b/mpc/src/add_si.c
new file mode 100644
index 0000000000..ba14803e76
--- /dev/null
+++ b/mpc/src/add_si.c
@@ -0,0 +1,32 @@
+/* mpc_add_si -- Add a complex number and a signed long int.
+
+Copyright (C) 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_add_si (mpc_ptr rop, mpc_srcptr op1, long int op2, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_add_si (mpc_realref (rop), mpc_realref (op1), op2, MPC_RND_RE (rnd));
+ inex_im = mpfr_set (mpc_imagref (rop), mpc_imagref (op1), MPC_RND_IM (rnd));
+
+ return MPC_INEX (inex_re, inex_im);
+}
diff --git a/mpc/src/add_ui.c b/mpc/src/add_ui.c
new file mode 100644
index 0000000000..85f4d13d2d
--- /dev/null
+++ b/mpc/src/add_ui.c
@@ -0,0 +1,33 @@
+/* mpc_add_ui -- Add a complex number and an unsigned long int.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* return 0 iff both the real and imaginary parts are exact */
+int
+mpc_add_ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_add_ui (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_set (mpc_imagref(a), mpc_imagref(b), MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/arg.c b/mpc/src/arg.c
new file mode 100644
index 0000000000..20b5180926
--- /dev/null
+++ b/mpc/src/arg.c
@@ -0,0 +1,27 @@
+/* mpc_arg -- Get the argument of a complex number.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_arg (mpfr_ptr a, mpc_srcptr b, mpfr_rnd_t rnd)
+{
+ return mpfr_atan2 (a, mpc_imagref (b), mpc_realref (b), rnd);
+}
diff --git a/mpc/src/asin.c b/mpc/src/asin.c
new file mode 100644
index 0000000000..bd4e3132de
--- /dev/null
+++ b/mpc/src/asin.c
@@ -0,0 +1,226 @@
+/* mpc_asin -- arcsine of a complex number.
+
+Copyright (C) 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_asin (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ mpfr_prec_t p, p_re, p_im, incr_p = 0;
+ mpfr_rnd_t rnd_re, rnd_im;
+ mpc_t z1;
+ int inex;
+
+ /* special values */
+ if (mpfr_nan_p (mpc_realref (op)) || mpfr_nan_p (mpc_imagref (op)))
+ {
+ if (mpfr_inf_p (mpc_realref (op)) || mpfr_inf_p (mpc_imagref (op)))
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_inf (mpc_imagref (rop), mpfr_signbit (mpc_imagref (op)) ? -1 : +1);
+ }
+ else if (mpfr_zero_p (mpc_realref (op)))
+ {
+ mpfr_set (mpc_realref (rop), mpc_realref (op), GMP_RNDN);
+ mpfr_set_nan (mpc_imagref (rop));
+ }
+ else
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ }
+
+ return 0;
+ }
+
+ if (mpfr_inf_p (mpc_realref (op)) || mpfr_inf_p (mpc_imagref (op)))
+ {
+ int inex_re;
+ if (mpfr_inf_p (mpc_realref (op)))
+ {
+ int inf_im = mpfr_inf_p (mpc_imagref (op));
+
+ inex_re = set_pi_over_2 (mpc_realref (rop),
+ (mpfr_signbit (mpc_realref (op)) ? -1 : 1), MPC_RND_RE (rnd));
+ mpfr_set_inf (mpc_imagref (rop), (mpfr_signbit (mpc_imagref (op)) ? -1 : 1));
+
+ if (inf_im)
+ mpfr_div_2ui (mpc_realref (rop), mpc_realref (rop), 1, GMP_RNDN);
+ }
+ else
+ {
+ mpfr_set_zero (mpc_realref (rop), (mpfr_signbit (mpc_realref (op)) ? -1 : 1));
+ inex_re = 0;
+ mpfr_set_inf (mpc_imagref (rop), (mpfr_signbit (mpc_imagref (op)) ? -1 : 1));
+ }
+
+ return MPC_INEX (inex_re, 0);
+ }
+
+ /* pure real argument */
+ if (mpfr_zero_p (mpc_imagref (op)))
+ {
+ int inex_re;
+ int inex_im;
+ int s_im;
+ s_im = mpfr_signbit (mpc_imagref (op));
+
+ if (mpfr_cmp_ui (mpc_realref (op), 1) > 0)
+ {
+ if (s_im)
+ inex_im = -mpfr_acosh (mpc_imagref (rop), mpc_realref (op),
+ INV_RND (MPC_RND_IM (rnd)));
+ else
+ inex_im = mpfr_acosh (mpc_imagref (rop), mpc_realref (op),
+ MPC_RND_IM (rnd));
+ inex_re = set_pi_over_2 (mpc_realref (rop),
+ (mpfr_signbit (mpc_realref (op)) ? -1 : 1), MPC_RND_RE (rnd));
+ if (s_im)
+ mpc_conj (rop, rop, MPC_RNDNN);
+ }
+ else if (mpfr_cmp_si (mpc_realref (op), -1) < 0)
+ {
+ mpfr_t minus_op_re;
+ minus_op_re[0] = mpc_realref (op)[0];
+ MPFR_CHANGE_SIGN (minus_op_re);
+
+ if (s_im)
+ inex_im = -mpfr_acosh (mpc_imagref (rop), minus_op_re,
+ INV_RND (MPC_RND_IM (rnd)));
+ else
+ inex_im = mpfr_acosh (mpc_imagref (rop), minus_op_re,
+ MPC_RND_IM (rnd));
+ inex_re = set_pi_over_2 (mpc_realref (rop),
+ (mpfr_signbit (mpc_realref (op)) ? -1 : 1), MPC_RND_RE (rnd));
+ if (s_im)
+ mpc_conj (rop, rop, MPC_RNDNN);
+ }
+ else
+ {
+ inex_im = mpfr_set_ui (mpc_imagref (rop), 0, MPC_RND_IM (rnd));
+ if (s_im)
+ mpfr_neg (mpc_imagref (rop), mpc_imagref (rop), GMP_RNDN);
+ inex_re = mpfr_asin (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd));
+ }
+
+ return MPC_INEX (inex_re, inex_im);
+ }
+
+ /* pure imaginary argument */
+ if (mpfr_zero_p (mpc_realref (op)))
+ {
+ int inex_im;
+ int s;
+ s = mpfr_signbit (mpc_realref (op));
+ mpfr_set_ui (mpc_realref (rop), 0, GMP_RNDN);
+ if (s)
+ mpfr_neg (mpc_realref (rop), mpc_realref (rop), GMP_RNDN);
+ inex_im = mpfr_asinh (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd));
+
+ return MPC_INEX (0, inex_im);
+ }
+
+ /* regular complex: asin(z) = -i*log(i*z+sqrt(1-z^2)) */
+ p_re = mpfr_get_prec (mpc_realref(rop));
+ p_im = mpfr_get_prec (mpc_imagref(rop));
+ rnd_re = MPC_RND_RE(rnd);
+ rnd_im = MPC_RND_IM(rnd);
+ p = p_re >= p_im ? p_re : p_im;
+ mpc_init2 (z1, p);
+ while (1)
+ {
+ mpfr_exp_t ex, ey, err;
+
+ p += mpc_ceil_log2 (p) + 3 + incr_p; /* incr_p is zero initially */
+ incr_p = p / 2;
+ mpfr_set_prec (mpc_realref(z1), p);
+ mpfr_set_prec (mpc_imagref(z1), p);
+
+ /* z1 <- z^2 */
+ mpc_sqr (z1, op, MPC_RNDNN);
+ /* err(x) <= 1/2 ulp(x), err(y) <= 1/2 ulp(y) */
+ /* z1 <- 1-z1 */
+ ex = mpfr_get_exp (mpc_realref(z1));
+ mpfr_ui_sub (mpc_realref(z1), 1, mpc_realref(z1), GMP_RNDN);
+ mpfr_neg (mpc_imagref(z1), mpc_imagref(z1), GMP_RNDN);
+ ex = ex - mpfr_get_exp (mpc_realref(z1));
+ ex = (ex <= 0) ? 0 : ex;
+ /* err(x) <= 2^ex * ulp(x) */
+ ex = ex + mpfr_get_exp (mpc_realref(z1)) - p;
+ /* err(x) <= 2^ex */
+ ey = mpfr_get_exp (mpc_imagref(z1)) - p - 1;
+ /* err(y) <= 2^ey */
+ ex = (ex >= ey) ? ex : ey; /* err(x), err(y) <= 2^ex, i.e., the norm
+ of the error is bounded by |h|<=2^(ex+1/2) */
+ /* z1 <- sqrt(z1): if z1 = z + h, then sqrt(z1) = sqrt(z) + h/2/sqrt(t) */
+ ey = mpfr_get_exp (mpc_realref(z1)) >= mpfr_get_exp (mpc_imagref(z1))
+ ? mpfr_get_exp (mpc_realref(z1)) : mpfr_get_exp (mpc_imagref(z1));
+ /* we have |z1| >= 2^(ey-1) thus 1/|z1| <= 2^(1-ey) */
+ mpc_sqrt (z1, z1, MPC_RNDNN);
+ ex = (2 * ex + 1) - 2 - (ey - 1); /* |h^2/4/|t| <= 2^ex */
+ ex = (ex + 1) / 2; /* ceil(ex/2) */
+ /* express ex in terms of ulp(z1) */
+ ey = mpfr_get_exp (mpc_realref(z1)) <= mpfr_get_exp (mpc_imagref(z1))
+ ? mpfr_get_exp (mpc_realref(z1)) : mpfr_get_exp (mpc_imagref(z1));
+ ex = ex - ey + p;
+ /* take into account the rounding error in the mpc_sqrt call */
+ err = (ex <= 0) ? 1 : ex + 1;
+ /* err(x) <= 2^err * ulp(x), err(y) <= 2^err * ulp(y) */
+ /* z1 <- i*z + z1 */
+ ex = mpfr_get_exp (mpc_realref(z1));
+ ey = mpfr_get_exp (mpc_imagref(z1));
+ mpfr_sub (mpc_realref(z1), mpc_realref(z1), mpc_imagref(op), GMP_RNDN);
+ mpfr_add (mpc_imagref(z1), mpc_imagref(z1), mpc_realref(op), GMP_RNDN);
+ if (mpfr_cmp_ui (mpc_realref(z1), 0) == 0 || mpfr_cmp_ui (mpc_imagref(z1), 0) == 0)
+ continue;
+ ex -= mpfr_get_exp (mpc_realref(z1)); /* cancellation in x */
+ ey -= mpfr_get_exp (mpc_imagref(z1)); /* cancellation in y */
+ ex = (ex >= ey) ? ex : ey; /* maximum cancellation */
+ err += ex;
+ err = (err <= 0) ? 1 : err + 1; /* rounding error in sub/add */
+ /* z1 <- log(z1): if z1 = z + h, then log(z1) = log(z) + h/t with
+ |t| >= min(|z1|,|z|) */
+ ex = mpfr_get_exp (mpc_realref(z1));
+ ey = mpfr_get_exp (mpc_imagref(z1));
+ ex = (ex >= ey) ? ex : ey;
+ err += ex - p; /* revert to absolute error <= 2^err */
+ mpc_log (z1, z1, GMP_RNDN);
+ err -= ex - 1; /* 1/|t| <= 1/|z| <= 2^(1-ex) */
+ /* express err in terms of ulp(z1) */
+ ey = mpfr_get_exp (mpc_realref(z1)) <= mpfr_get_exp (mpc_imagref(z1))
+ ? mpfr_get_exp (mpc_realref(z1)) : mpfr_get_exp (mpc_imagref(z1));
+ err = err - ey + p;
+ /* take into account the rounding error in the mpc_log call */
+ err = (err <= 0) ? 1 : err + 1;
+ /* z1 <- -i*z1 */
+ mpfr_swap (mpc_realref(z1), mpc_imagref(z1));
+ mpfr_neg (mpc_imagref(z1), mpc_imagref(z1), GMP_RNDN);
+ if (mpfr_can_round (mpc_realref(z1), p - err, GMP_RNDN, GMP_RNDZ,
+ p_re + (rnd_re == GMP_RNDN)) &&
+ mpfr_can_round (mpc_imagref(z1), p - err, GMP_RNDN, GMP_RNDZ,
+ p_im + (rnd_im == GMP_RNDN)))
+ break;
+ }
+
+ inex = mpc_set (rop, z1, rnd);
+ mpc_clear (z1);
+
+ return inex;
+}
diff --git a/mpc/src/asinh.c b/mpc/src/asinh.c
new file mode 100644
index 0000000000..2807a8bb31
--- /dev/null
+++ b/mpc/src/asinh.c
@@ -0,0 +1,55 @@
+/* mpc_asinh -- inverse hyperbolic sine of a complex number.
+
+Copyright (C) 2009, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_asinh (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ /* asinh(op) = -i*asin(i*op) */
+ int inex;
+ mpc_t z, a;
+ mpfr_t tmp;
+
+ /* z = i*op */
+ mpc_realref (z)[0] = mpc_imagref (op)[0];
+ mpc_imagref (z)[0] = mpc_realref (op)[0];
+ MPFR_CHANGE_SIGN (mpc_realref (z));
+
+ /* Note reversal of precisions due to later multiplication by -i */
+ mpc_init3 (a, MPC_PREC_IM(rop), MPC_PREC_RE(rop));
+
+ inex = mpc_asin (a, z,
+ MPC_RND (INV_RND (MPC_RND_IM (rnd)), MPC_RND_RE (rnd)));
+
+ /* if a = asin(i*op) = x+i*y, and we want y-i*x */
+
+ /* change a to -i*a */
+ tmp[0] = mpc_realref (a)[0];
+ mpc_realref (a)[0] = mpc_imagref (a)[0];
+ mpc_imagref (a)[0] = tmp[0];
+ MPFR_CHANGE_SIGN (mpc_imagref (a));
+
+ mpc_set (rop, a, MPC_RNDNN); /* exact */
+
+ mpc_clear (a);
+
+ return MPC_INEX (MPC_INEX_IM (inex), -MPC_INEX_RE (inex));
+}
diff --git a/mpc/src/atan.c b/mpc/src/atan.c
new file mode 100644
index 0000000000..285f79f6cb
--- /dev/null
+++ b/mpc/src/atan.c
@@ -0,0 +1,367 @@
+/* mpc_atan -- arctangent of a complex number.
+
+Copyright (C) 2009, 2010, 2011, 2012, 2013 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h>
+#include "mpc-impl.h"
+
+/* set rop to
+ -pi/2 if s < 0
+ +pi/2 else
+ rounded in the direction rnd
+*/
+int
+set_pi_over_2 (mpfr_ptr rop, int s, mpfr_rnd_t rnd)
+{
+ int inex;
+
+ inex = mpfr_const_pi (rop, s < 0 ? INV_RND (rnd) : rnd);
+ mpfr_div_2ui (rop, rop, 1, GMP_RNDN);
+ if (s < 0)
+ {
+ inex = -inex;
+ mpfr_neg (rop, rop, GMP_RNDN);
+ }
+
+ return inex;
+}
+
+int
+mpc_atan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ int s_re;
+ int s_im;
+ int inex_re;
+ int inex_im;
+ int inex;
+
+ inex_re = 0;
+ inex_im = 0;
+ s_re = mpfr_signbit (mpc_realref (op));
+ s_im = mpfr_signbit (mpc_imagref (op));
+
+ /* special values */
+ if (mpfr_nan_p (mpc_realref (op)) || mpfr_nan_p (mpc_imagref (op)))
+ {
+ if (mpfr_nan_p (mpc_realref (op)))
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ if (mpfr_zero_p (mpc_imagref (op)) || mpfr_inf_p (mpc_imagref (op)))
+ {
+ mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
+ if (s_im)
+ mpc_conj (rop, rop, MPC_RNDNN);
+ }
+ else
+ mpfr_set_nan (mpc_imagref (rop));
+ }
+ else
+ {
+ if (mpfr_inf_p (mpc_realref (op)))
+ {
+ inex_re = set_pi_over_2 (mpc_realref (rop), -s_re, MPC_RND_RE (rnd));
+ mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
+ }
+ else
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ }
+ }
+ return MPC_INEX (inex_re, 0);
+ }
+
+ if (mpfr_inf_p (mpc_realref (op)) || mpfr_inf_p (mpc_imagref (op)))
+ {
+ inex_re = set_pi_over_2 (mpc_realref (rop), -s_re, MPC_RND_RE (rnd));
+
+ mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
+ if (s_im)
+ mpc_conj (rop, rop, GMP_RNDN);
+
+ return MPC_INEX (inex_re, 0);
+ }
+
+ /* pure real argument */
+ if (mpfr_zero_p (mpc_imagref (op)))
+ {
+ inex_re = mpfr_atan (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd));
+
+ mpfr_set_ui (mpc_imagref (rop), 0, GMP_RNDN);
+ if (s_im)
+ mpc_conj (rop, rop, GMP_RNDN);
+
+ return MPC_INEX (inex_re, 0);
+ }
+
+ /* pure imaginary argument */
+ if (mpfr_zero_p (mpc_realref (op)))
+ {
+ int cmp_1;
+
+ if (s_im)
+ cmp_1 = -mpfr_cmp_si (mpc_imagref (op), -1);
+ else
+ cmp_1 = mpfr_cmp_ui (mpc_imagref (op), +1);
+
+ if (cmp_1 < 0)
+ {
+ /* atan(+0+iy) = +0 +i*atanh(y), if |y| < 1
+ atan(-0+iy) = -0 +i*atanh(y), if |y| < 1 */
+
+ mpfr_set_ui (mpc_realref (rop), 0, GMP_RNDN);
+ if (s_re)
+ mpfr_neg (mpc_realref (rop), mpc_realref (rop), GMP_RNDN);
+
+ inex_im = mpfr_atanh (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd));
+ }
+ else if (cmp_1 == 0)
+ {
+ /* atan(+/-0 +i) = +/-0 +i*inf
+ atan(+/-0 -i) = +/-0 -i*inf */
+ mpfr_set_zero (mpc_realref (rop), s_re ? -1 : +1);
+ mpfr_set_inf (mpc_imagref (rop), s_im ? -1 : +1);
+ }
+ else
+ {
+ /* atan(+0+iy) = +pi/2 +i*atanh(1/y), if |y| > 1
+ atan(-0+iy) = -pi/2 +i*atanh(1/y), if |y| > 1 */
+ mpfr_rnd_t rnd_im, rnd_away;
+ mpfr_t y;
+ mpfr_prec_t p, p_im;
+ int ok;
+
+ rnd_im = MPC_RND_IM (rnd);
+ mpfr_init (y);
+ p_im = mpfr_get_prec (mpc_imagref (rop));
+ p = p_im;
+
+ /* a = o(1/y) with error(a) < 1 ulp(a)
+ b = o(atanh(a)) with error(b) < (1+2^{1+Exp(a)-Exp(b)}) ulp(b)
+
+ As |atanh (1/y)| > |1/y| we have Exp(a)-Exp(b) <=0 so, at most,
+ 2 bits of precision are lost.
+
+ We round atanh(1/y) away from 0.
+ */
+ do
+ {
+ p += mpc_ceil_log2 (p) + 2;
+ mpfr_set_prec (y, p);
+ rnd_away = s_im == 0 ? GMP_RNDU : GMP_RNDD;
+ inex_im = mpfr_ui_div (y, 1, mpc_imagref (op), rnd_away);
+ /* FIXME: should we consider the case with unreasonably huge
+ precision prec(y)>3*exp_min, where atanh(1/Im(op)) could be
+ representable while 1/Im(op) underflows ?
+ This corresponds to |y| = 0.5*2^emin, in which case the
+ result may be wrong. */
+
+ /* atanh cannot underflow: |atanh(x)| > |x| for |x| < 1 */
+ inex_im |= mpfr_atanh (y, y, rnd_away);
+
+ ok = inex_im == 0
+ || mpfr_can_round (y, p - 2, rnd_away, GMP_RNDZ,
+ p_im + (rnd_im == GMP_RNDN));
+ } while (ok == 0);
+
+ inex_re = set_pi_over_2 (mpc_realref (rop), -s_re, MPC_RND_RE (rnd));
+ inex_im = mpfr_set (mpc_imagref (rop), y, rnd_im);
+ mpfr_clear (y);
+ }
+ return MPC_INEX (inex_re, inex_im);
+ }
+
+ /* regular number argument */
+ {
+ mpfr_t a, b, x, y;
+ mpfr_prec_t prec, p;
+ mpfr_exp_t err, expo;
+ int ok = 0;
+ mpfr_t minus_op_re;
+ mpfr_exp_t op_re_exp, op_im_exp;
+ mpfr_rnd_t rnd1, rnd2;
+
+ mpfr_inits2 (MPFR_PREC_MIN, a, b, x, y, (mpfr_ptr) 0);
+
+ /* real part: Re(arctan(x+i*y)) = [arctan2(x,1-y) - arctan2(-x,1+y)]/2 */
+ minus_op_re[0] = mpc_realref (op)[0];
+ MPFR_CHANGE_SIGN (minus_op_re);
+ op_re_exp = mpfr_get_exp (mpc_realref (op));
+ op_im_exp = mpfr_get_exp (mpc_imagref (op));
+
+ prec = mpfr_get_prec (mpc_realref (rop)); /* result precision */
+
+ /* a = o(1-y) error(a) < 1 ulp(a)
+ b = o(atan2(x,a)) error(b) < [1+2^{3+Exp(x)-Exp(a)-Exp(b)}] ulp(b)
+ = kb ulp(b)
+ c = o(1+y) error(c) < 1 ulp(c)
+ d = o(atan2(-x,c)) error(d) < [1+2^{3+Exp(x)-Exp(c)-Exp(d)}] ulp(d)
+ = kd ulp(d)
+ e = o(b - d) error(e) < [1 + kb*2^{Exp(b}-Exp(e)}
+ + kd*2^{Exp(d)-Exp(e)}] ulp(e)
+ error(e) < [1 + 2^{4+Exp(x)-Exp(a)-Exp(e)}
+ + 2^{4+Exp(x)-Exp(c)-Exp(e)}] ulp(e)
+ because |atan(u)| < |u|
+ < [1 + 2^{5+Exp(x)-min(Exp(a),Exp(c))
+ -Exp(e)}] ulp(e)
+ f = e/2 exact
+ */
+
+ /* p: working precision */
+ p = (op_im_exp > 0 || prec > SAFE_ABS (mpfr_prec_t, op_im_exp)) ? prec
+ : (prec - op_im_exp);
+ rnd1 = mpfr_sgn (mpc_realref (op)) > 0 ? GMP_RNDD : GMP_RNDU;
+ rnd2 = mpfr_sgn (mpc_realref (op)) < 0 ? GMP_RNDU : GMP_RNDD;
+
+ do
+ {
+ p += mpc_ceil_log2 (p) + 2;
+ mpfr_set_prec (a, p);
+ mpfr_set_prec (b, p);
+ mpfr_set_prec (x, p);
+
+ /* x = upper bound for atan (x/(1-y)). Since atan is increasing, we
+ need an upper bound on x/(1-y), i.e., a lower bound on 1-y for
+ x positive, and an upper bound on 1-y for x negative */
+ mpfr_ui_sub (a, 1, mpc_imagref (op), rnd1);
+ if (mpfr_sgn (a) == 0) /* y is near 1, thus 1+y is near 2, and
+ expo will be 1 or 2 below */
+ {
+ MPC_ASSERT (mpfr_cmp_ui (mpc_imagref(op), 1) == 0);
+ /* check for intermediate underflow */
+ err = 2; /* ensures err will be expo below */
+ }
+ else
+ err = mpfr_get_exp (a); /* err = Exp(a) with the notations above */
+ mpfr_atan2 (x, mpc_realref (op), a, GMP_RNDU);
+
+ /* b = lower bound for atan (-x/(1+y)): for x negative, we need a
+ lower bound on -x/(1+y), i.e., an upper bound on 1+y */
+ mpfr_add_ui (a, mpc_imagref(op), 1, rnd2);
+ /* if a is exactly zero, i.e., Im(op) = -1, then the error on a is 0,
+ and we can simply ignore the terms involving Exp(a) in the error */
+ if (mpfr_sgn (a) == 0)
+ {
+ MPC_ASSERT (mpfr_cmp_si (mpc_imagref(op), -1) == 0);
+ /* check for intermediate underflow */
+ expo = err; /* will leave err unchanged below */
+ }
+ else
+ expo = mpfr_get_exp (a); /* expo = Exp(c) with the notations above */
+ mpfr_atan2 (b, minus_op_re, a, GMP_RNDD);
+
+ err = err < expo ? err : expo; /* err = min(Exp(a),Exp(c)) */
+ mpfr_sub (x, x, b, GMP_RNDU);
+
+ err = 5 + op_re_exp - err - mpfr_get_exp (x);
+ /* error is bounded by [1 + 2^err] ulp(e) */
+ err = err < 0 ? 1 : err + 1;
+
+ mpfr_div_2ui (x, x, 1, GMP_RNDU);
+
+ /* Note: using RND2=RNDD guarantees that if x is exactly representable
+ on prec + ... bits, mpfr_can_round will return 0 */
+ ok = mpfr_can_round (x, p - err, GMP_RNDU, GMP_RNDD,
+ prec + (MPC_RND_RE (rnd) == GMP_RNDN));
+ } while (ok == 0);
+
+ /* Imaginary part
+ Im(atan(x+I*y)) = 1/4 * [log(x^2+(1+y)^2) - log (x^2 +(1-y)^2)] */
+ prec = mpfr_get_prec (mpc_imagref (rop)); /* result precision */
+
+ /* a = o(1+y) error(a) < 1 ulp(a)
+ b = o(a^2) error(b) < 5 ulp(b)
+ c = o(x^2) error(c) < 1 ulp(c)
+ d = o(b+c) error(d) < 7 ulp(d)
+ e = o(log(d)) error(e) < [1 + 7*2^{2-Exp(e)}] ulp(e) = ke ulp(e)
+ f = o(1-y) error(f) < 1 ulp(f)
+ g = o(f^2) error(g) < 5 ulp(g)
+ h = o(c+f) error(h) < 7 ulp(h)
+ i = o(log(h)) error(i) < [1 + 7*2^{2-Exp(i)}] ulp(i) = ki ulp(i)
+ j = o(e-i) error(j) < [1 + ke*2^{Exp(e)-Exp(j)}
+ + ki*2^{Exp(i)-Exp(j)}] ulp(j)
+ error(j) < [1 + 2^{Exp(e)-Exp(j)} + 2^{Exp(i)-Exp(j)}
+ + 7*2^{3-Exp(j)}] ulp(j)
+ < [1 + 2^{max(Exp(e),Exp(i))-Exp(j)+1}
+ + 7*2^{3-Exp(j)}] ulp(j)
+ k = j/4 exact
+ */
+ err = 2;
+ p = prec; /* working precision */
+
+ do
+ {
+ p += mpc_ceil_log2 (p) + err;
+ mpfr_set_prec (a, p);
+ mpfr_set_prec (b, p);
+ mpfr_set_prec (y, p);
+
+ /* a = upper bound for log(x^2 + (1+y)^2) */
+ ROUND_AWAY (mpfr_add_ui (a, mpc_imagref (op), 1, MPFR_RNDA), a);
+ mpfr_sqr (a, a, GMP_RNDU);
+ mpfr_sqr (y, mpc_realref (op), GMP_RNDU);
+ mpfr_add (a, a, y, GMP_RNDU);
+ mpfr_log (a, a, GMP_RNDU);
+
+ /* b = lower bound for log(x^2 + (1-y)^2) */
+ mpfr_ui_sub (b, 1, mpc_imagref (op), GMP_RNDZ); /* round to zero */
+ mpfr_sqr (b, b, GMP_RNDZ);
+ /* we could write mpfr_sqr (y, mpc_realref (op), GMP_RNDZ) but it is
+ more efficient to reuse the value of y (x^2) above and subtract
+ one ulp */
+ mpfr_nextbelow (y);
+ mpfr_add (b, b, y, GMP_RNDZ);
+ mpfr_log (b, b, GMP_RNDZ);
+
+ mpfr_sub (y, a, b, GMP_RNDU);
+
+ if (mpfr_zero_p (y))
+ /* FIXME: happens when x and y have very different magnitudes;
+ could be handled more efficiently */
+ ok = 0;
+ else
+ {
+ expo = MPC_MAX (mpfr_get_exp (a), mpfr_get_exp (b));
+ expo = expo - mpfr_get_exp (y) + 1;
+ err = 3 - mpfr_get_exp (y);
+ /* error(j) <= [1 + 2^expo + 7*2^err] ulp(j) */
+ if (expo <= err) /* error(j) <= [1 + 2^{err+1}] ulp(j) */
+ err = (err < 0) ? 1 : err + 2;
+ else
+ err = (expo < 0) ? 1 : expo + 2;
+
+ mpfr_div_2ui (y, y, 2, GMP_RNDN);
+ MPC_ASSERT (!mpfr_zero_p (y));
+ /* FIXME: underflow. Since the main term of the Taylor series
+ in y=0 is 1/(x^2+1) * y, this means that y is very small
+ and/or x very large; but then the mpfr_zero_p (y) above
+ should be true. This needs a proof, or better yet,
+ special code. */
+
+ ok = mpfr_can_round (y, p - err, GMP_RNDU, GMP_RNDD,
+ prec + (MPC_RND_IM (rnd) == GMP_RNDN));
+ }
+ } while (ok == 0);
+
+ inex = mpc_set_fr_fr (rop, x, y, rnd);
+
+ mpfr_clears (a, b, x, y, (mpfr_ptr) 0);
+ return inex;
+ }
+}
diff --git a/mpc/src/atanh.c b/mpc/src/atanh.c
new file mode 100644
index 0000000000..e5716cc703
--- /dev/null
+++ b/mpc/src/atanh.c
@@ -0,0 +1,52 @@
+/* mpc_atanh -- inverse hyperbolic tangent of a complex number.
+
+Copyright (C) 2009, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_atanh (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ /* atanh(op) = -i*atan(i*op) */
+ int inex;
+ mpfr_t tmp;
+ mpc_t z, a;
+
+ mpc_realref (z)[0] = mpc_imagref (op)[0];
+ mpc_imagref (z)[0] = mpc_realref (op)[0];
+ MPFR_CHANGE_SIGN (mpc_realref (z));
+
+ /* Note reversal of precisions due to later multiplication by -i */
+ mpc_init3 (a, MPC_PREC_IM(rop), MPC_PREC_RE(rop));
+
+ inex = mpc_atan (a, z,
+ MPC_RND (INV_RND (MPC_RND_IM (rnd)), MPC_RND_RE (rnd)));
+
+ /* change a to -i*a, i.e., x+i*y to y-i*x */
+ tmp[0] = mpc_realref (a)[0];
+ mpc_realref (a)[0] = mpc_imagref (a)[0];
+ mpc_imagref (a)[0] = tmp[0];
+ MPFR_CHANGE_SIGN (mpc_imagref (a));
+
+ mpc_set (rop, a, rnd);
+
+ mpc_clear (a);
+
+ return MPC_INEX (MPC_INEX_IM (inex), -MPC_INEX_RE (inex));
+}
diff --git a/mpc/src/clear.c b/mpc/src/clear.c
new file mode 100644
index 0000000000..f76b5db0f9
--- /dev/null
+++ b/mpc/src/clear.c
@@ -0,0 +1,28 @@
+/* mpc_clear -- Clear a complex variable.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+void
+mpc_clear (mpc_t x)
+{
+ mpfr_clear (mpc_realref(x));
+ mpfr_clear (mpc_imagref(x));
+}
diff --git a/mpc/src/cmp.c b/mpc/src/cmp.c
new file mode 100644
index 0000000000..ce1871c430
--- /dev/null
+++ b/mpc/src/cmp.c
@@ -0,0 +1,33 @@
+/* mpc_cmp -- Compare two complex numbers.
+
+Copyright (C) 2002, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* return 0 iff a = b */
+int
+mpc_cmp (mpc_srcptr a, mpc_srcptr b)
+{
+ int cmp_re, cmp_im;
+
+ cmp_re = mpfr_cmp (mpc_realref(a), mpc_realref(b));
+ cmp_im = mpfr_cmp (mpc_imagref(a), mpc_imagref(b));
+
+ return MPC_INEX(cmp_re, cmp_im);
+}
diff --git a/mpc/src/cmp_si_si.c b/mpc/src/cmp_si_si.c
new file mode 100644
index 0000000000..a50b7585f5
--- /dev/null
+++ b/mpc/src/cmp_si_si.c
@@ -0,0 +1,34 @@
+/* mpc_cmp_si_si -- Compare a complex number to a number of the form
+ b+c*i with b and c signed integers.
+
+Copyright (C) 2005, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* return 0 iff a = b */
+int
+mpc_cmp_si_si (mpc_srcptr a, long int b, long int c)
+{
+ int cmp_re, cmp_im;
+
+ cmp_re = mpfr_cmp_si (mpc_realref(a), b);
+ cmp_im = mpfr_cmp_si (mpc_imagref(a), c);
+
+ return MPC_INEX(cmp_re, cmp_im);
+}
diff --git a/mpc/src/conj.c b/mpc/src/conj.c
new file mode 100644
index 0000000000..0905b1d358
--- /dev/null
+++ b/mpc/src/conj.c
@@ -0,0 +1,32 @@
+/* mpc_conj -- Conjugate of a complex number.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_conj (mpc_ptr a, mpc_srcptr b, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_set (mpc_realref(a), mpc_realref(b), MPC_RND_RE(rnd));
+ inex_im = mpfr_neg (mpc_imagref(a), mpc_imagref(b), MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/cos.c b/mpc/src/cos.c
new file mode 100644
index 0000000000..3810f3ec4c
--- /dev/null
+++ b/mpc/src/cos.c
@@ -0,0 +1,27 @@
+/* mpc_cos -- cosine of a complex number.
+
+Copyright (C) 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_cos (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ return MPC_INEX2 (mpc_sin_cos (NULL, rop, op, 0, rnd));
+}
diff --git a/mpc/src/cosh.c b/mpc/src/cosh.c
new file mode 100644
index 0000000000..0d4aab9e4d
--- /dev/null
+++ b/mpc/src/cosh.c
@@ -0,0 +1,35 @@
+/* mpc_cosh -- hyperbolic cosine of a complex number.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_cosh (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ /* cosh(op) = cos(i*op) */
+ mpc_t z;
+
+ /* z = i*op without copying significand */
+ mpc_realref (z)[0] = mpc_imagref (op)[0];
+ mpc_imagref (z)[0] = mpc_realref (op)[0];
+ MPFR_CHANGE_SIGN (mpc_realref (z));
+
+ return mpc_cos (rop, z, rnd);
+}
diff --git a/mpc/src/div.c b/mpc/src/div.c
new file mode 100644
index 0000000000..83584b8b5f
--- /dev/null
+++ b/mpc/src/div.c
@@ -0,0 +1,449 @@
+/* mpc_div -- Divide two complex numbers.
+
+Copyright (C) 2002, 2003, 2004, 2005, 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* this routine deals with the case where w is zero */
+static int
+mpc_div_zero (mpc_ptr a, mpc_srcptr z, mpc_srcptr w, mpc_rnd_t rnd)
+/* Assumes w==0, implementation according to C99 G.5.1.8 */
+{
+ int sign = MPFR_SIGNBIT (mpc_realref (w));
+ mpfr_t infty;
+
+ mpfr_init2 (infty, MPFR_PREC_MIN);
+ mpfr_set_inf (infty, sign);
+ mpfr_mul (mpc_realref (a), infty, mpc_realref (z), MPC_RND_RE (rnd));
+ mpfr_mul (mpc_imagref (a), infty, mpc_imagref (z), MPC_RND_IM (rnd));
+ mpfr_clear (infty);
+ return MPC_INEX (0, 0); /* exact */
+}
+
+/* this routine deals with the case where z is infinite and w finite */
+static int
+mpc_div_inf_fin (mpc_ptr rop, mpc_srcptr z, mpc_srcptr w)
+/* Assumes w finite and non-zero and z infinite; implementation
+ according to C99 G.5.1.8 */
+{
+ int a, b, x, y;
+
+ a = (mpfr_inf_p (mpc_realref (z)) ? MPFR_SIGNBIT (mpc_realref (z)) : 0);
+ b = (mpfr_inf_p (mpc_imagref (z)) ? MPFR_SIGNBIT (mpc_imagref (z)) : 0);
+
+ /* a is -1 if Re(z) = -Inf, 1 if Re(z) = +Inf, 0 if Re(z) is finite
+ b is -1 if Im(z) = -Inf, 1 if Im(z) = +Inf, 0 if Im(z) is finite */
+
+ /* x = MPC_MPFR_SIGN (a * mpc_realref (w) + b * mpc_imagref (w)) */
+ /* y = MPC_MPFR_SIGN (b * mpc_realref (w) - a * mpc_imagref (w)) */
+ if (a == 0 || b == 0) {
+ /* only one of a or b can be zero, since z is infinite */
+ x = a * MPC_MPFR_SIGN (mpc_realref (w)) + b * MPC_MPFR_SIGN (mpc_imagref (w));
+ y = b * MPC_MPFR_SIGN (mpc_realref (w)) - a * MPC_MPFR_SIGN (mpc_imagref (w));
+ }
+ else {
+ /* Both parts of z are infinite; x could be determined by sign
+ considerations and comparisons. Since operations with non-finite
+ numbers are not considered time-critical, we let mpfr do the work. */
+ mpfr_t sign;
+
+ mpfr_init2 (sign, 2);
+ /* This is enough to determine the sign of sums and differences. */
+
+ if (a == 1)
+ if (b == 1) {
+ mpfr_add (sign, mpc_realref (w), mpc_imagref (w), GMP_RNDN);
+ x = MPC_MPFR_SIGN (sign);
+ mpfr_sub (sign, mpc_realref (w), mpc_imagref (w), GMP_RNDN);
+ y = MPC_MPFR_SIGN (sign);
+ }
+ else { /* b == -1 */
+ mpfr_sub (sign, mpc_realref (w), mpc_imagref (w), GMP_RNDN);
+ x = MPC_MPFR_SIGN (sign);
+ mpfr_add (sign, mpc_realref (w), mpc_imagref (w), GMP_RNDN);
+ y = -MPC_MPFR_SIGN (sign);
+ }
+ else /* a == -1 */
+ if (b == 1) {
+ mpfr_sub (sign, mpc_imagref (w), mpc_realref (w), GMP_RNDN);
+ x = MPC_MPFR_SIGN (sign);
+ mpfr_add (sign, mpc_realref (w), mpc_imagref (w), GMP_RNDN);
+ y = MPC_MPFR_SIGN (sign);
+ }
+ else { /* b == -1 */
+ mpfr_add (sign, mpc_realref (w), mpc_imagref (w), GMP_RNDN);
+ x = -MPC_MPFR_SIGN (sign);
+ mpfr_sub (sign, mpc_imagref (w), mpc_realref (w), GMP_RNDN);
+ y = MPC_MPFR_SIGN (sign);
+ }
+ mpfr_clear (sign);
+ }
+
+ if (x == 0)
+ mpfr_set_nan (mpc_realref (rop));
+ else
+ mpfr_set_inf (mpc_realref (rop), x);
+ if (y == 0)
+ mpfr_set_nan (mpc_imagref (rop));
+ else
+ mpfr_set_inf (mpc_imagref (rop), y);
+
+ return MPC_INEX (0, 0); /* exact */
+}
+
+
+/* this routine deals with the case where z if finite and w infinite */
+static int
+mpc_div_fin_inf (mpc_ptr rop, mpc_srcptr z, mpc_srcptr w)
+/* Assumes z finite and w infinite; implementation according to
+ C99 G.5.1.8 */
+{
+ mpfr_t c, d, a, b, x, y, zero;
+
+ mpfr_init2 (c, 2); /* needed to hold a signed zero, +1 or -1 */
+ mpfr_init2 (d, 2);
+ mpfr_init2 (x, 2);
+ mpfr_init2 (y, 2);
+ mpfr_init2 (zero, 2);
+ mpfr_set_ui (zero, 0ul, GMP_RNDN);
+ mpfr_init2 (a, mpfr_get_prec (mpc_realref (z)));
+ mpfr_init2 (b, mpfr_get_prec (mpc_imagref (z)));
+
+ mpfr_set_ui (c, (mpfr_inf_p (mpc_realref (w)) ? 1 : 0), GMP_RNDN);
+ MPFR_COPYSIGN (c, c, mpc_realref (w), GMP_RNDN);
+ mpfr_set_ui (d, (mpfr_inf_p (mpc_imagref (w)) ? 1 : 0), GMP_RNDN);
+ MPFR_COPYSIGN (d, d, mpc_imagref (w), GMP_RNDN);
+
+ mpfr_mul (a, mpc_realref (z), c, GMP_RNDN); /* exact */
+ mpfr_mul (b, mpc_imagref (z), d, GMP_RNDN);
+ mpfr_add (x, a, b, GMP_RNDN);
+
+ mpfr_mul (b, mpc_imagref (z), c, GMP_RNDN);
+ mpfr_mul (a, mpc_realref (z), d, GMP_RNDN);
+ mpfr_sub (y, b, a, GMP_RNDN);
+
+ MPFR_COPYSIGN (mpc_realref (rop), zero, x, GMP_RNDN);
+ MPFR_COPYSIGN (mpc_imagref (rop), zero, y, GMP_RNDN);
+
+ mpfr_clear (c);
+ mpfr_clear (d);
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (zero);
+ mpfr_clear (a);
+ mpfr_clear (b);
+
+ return MPC_INEX (0, 0); /* exact */
+}
+
+
+static int
+mpc_div_real (mpc_ptr rop, mpc_srcptr z, mpc_srcptr w, mpc_rnd_t rnd)
+/* Assumes z finite and w finite and non-zero, with imaginary part
+ of w a signed zero. */
+{
+ int inex_re, inex_im;
+ /* save signs of operands in case there are overlaps */
+ int zrs = MPFR_SIGNBIT (mpc_realref (z));
+ int zis = MPFR_SIGNBIT (mpc_imagref (z));
+ int wrs = MPFR_SIGNBIT (mpc_realref (w));
+ int wis = MPFR_SIGNBIT (mpc_imagref (w));
+
+ /* warning: rop may overlap with z,w so treat the imaginary part first */
+ inex_im = mpfr_div (mpc_imagref(rop), mpc_imagref(z), mpc_realref(w), MPC_RND_IM(rnd));
+ inex_re = mpfr_div (mpc_realref(rop), mpc_realref(z), mpc_realref(w), MPC_RND_RE(rnd));
+
+ /* correct signs of zeroes if necessary, which does not affect the
+ inexact flags */
+ if (mpfr_zero_p (mpc_realref (rop)))
+ mpfr_setsign (mpc_realref (rop), mpc_realref (rop), (zrs != wrs && zis != wis),
+ GMP_RNDN); /* exact */
+ if (mpfr_zero_p (mpc_imagref (rop)))
+ mpfr_setsign (mpc_imagref (rop), mpc_imagref (rop), (zis != wrs && zrs == wis),
+ GMP_RNDN);
+
+ return MPC_INEX(inex_re, inex_im);
+}
+
+
+static int
+mpc_div_imag (mpc_ptr rop, mpc_srcptr z, mpc_srcptr w, mpc_rnd_t rnd)
+/* Assumes z finite and w finite and non-zero, with real part
+ of w a signed zero. */
+{
+ int inex_re, inex_im;
+ int overlap = (rop == z) || (rop == w);
+ int imag_z = mpfr_zero_p (mpc_realref (z));
+ mpfr_t wloc;
+ mpc_t tmprop;
+ mpc_ptr dest = (overlap) ? tmprop : rop;
+ /* save signs of operands in case there are overlaps */
+ int zrs = MPFR_SIGNBIT (mpc_realref (z));
+ int zis = MPFR_SIGNBIT (mpc_imagref (z));
+ int wrs = MPFR_SIGNBIT (mpc_realref (w));
+ int wis = MPFR_SIGNBIT (mpc_imagref (w));
+
+ if (overlap)
+ mpc_init3 (tmprop, MPC_PREC_RE (rop), MPC_PREC_IM (rop));
+
+ wloc[0] = mpc_imagref(w)[0]; /* copies mpfr struct IM(w) into wloc */
+ inex_re = mpfr_div (mpc_realref(dest), mpc_imagref(z), wloc, MPC_RND_RE(rnd));
+ mpfr_neg (wloc, wloc, GMP_RNDN);
+ /* changes the sign only in wloc, not in w; no need to correct later */
+ inex_im = mpfr_div (mpc_imagref(dest), mpc_realref(z), wloc, MPC_RND_IM(rnd));
+
+ if (overlap) {
+ /* Note: we could use mpc_swap here, but this might cause problems
+ if rop and tmprop have been allocated using different methods, since
+ it will swap the significands of rop and tmprop. See
+ http://lists.gforge.inria.fr/pipermail/mpc-discuss/2009-August/000504.html */
+ mpc_set (rop, tmprop, MPC_RNDNN); /* exact */
+ mpc_clear (tmprop);
+ }
+
+ /* correct signs of zeroes if necessary, which does not affect the
+ inexact flags */
+ if (mpfr_zero_p (mpc_realref (rop)))
+ mpfr_setsign (mpc_realref (rop), mpc_realref (rop), (zrs != wrs && zis != wis),
+ GMP_RNDN); /* exact */
+ if (imag_z)
+ mpfr_setsign (mpc_imagref (rop), mpc_imagref (rop), (zis != wrs && zrs == wis),
+ GMP_RNDN);
+
+ return MPC_INEX(inex_re, inex_im);
+}
+
+
+int
+mpc_div (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
+{
+ int ok_re = 0, ok_im = 0;
+ mpc_t res, c_conj;
+ mpfr_t q;
+ mpfr_prec_t prec;
+ int inex, inexact_prod, inexact_norm, inexact_re, inexact_im, loops = 0;
+ int underflow_norm, overflow_norm, underflow_prod, overflow_prod;
+ int underflow_re = 0, overflow_re = 0, underflow_im = 0, overflow_im = 0;
+ mpfr_rnd_t rnd_re = MPC_RND_RE (rnd), rnd_im = MPC_RND_IM (rnd);
+ int saved_underflow, saved_overflow;
+ int tmpsgn;
+
+ /* According to the C standard G.3, there are three types of numbers: */
+ /* finite (both parts are usual real numbers; contains 0), infinite */
+ /* (at least one part is a real infinity) and all others; the latter */
+ /* are numbers containing a nan, but no infinity, and could reasonably */
+ /* be called nan. */
+ /* By G.5.1.4, infinite/finite=infinite; finite/infinite=0; */
+ /* all other divisions that are not finite/finite return nan+i*nan. */
+ /* Division by 0 could be handled by the following case of division by */
+ /* a real; we handle it separately instead. */
+ if (mpc_zero_p (c))
+ return mpc_div_zero (a, b, c, rnd);
+ else if (mpc_inf_p (b) && mpc_fin_p (c))
+ return mpc_div_inf_fin (a, b, c);
+ else if (mpc_fin_p (b) && mpc_inf_p (c))
+ return mpc_div_fin_inf (a, b, c);
+ else if (!mpc_fin_p (b) || !mpc_fin_p (c)) {
+ mpc_set_nan (a);
+ return MPC_INEX (0, 0);
+ }
+ else if (mpfr_zero_p(mpc_imagref(c)))
+ return mpc_div_real (a, b, c, rnd);
+ else if (mpfr_zero_p(mpc_realref(c)))
+ return mpc_div_imag (a, b, c, rnd);
+
+ prec = MPC_MAX_PREC(a);
+
+ mpc_init2 (res, 2);
+ mpfr_init (q);
+
+ /* create the conjugate of c in c_conj without allocating new memory */
+ mpc_realref (c_conj)[0] = mpc_realref (c)[0];
+ mpc_imagref (c_conj)[0] = mpc_imagref (c)[0];
+ MPFR_CHANGE_SIGN (mpc_imagref (c_conj));
+
+ /* save the underflow or overflow flags from MPFR */
+ saved_underflow = mpfr_underflow_p ();
+ saved_overflow = mpfr_overflow_p ();
+
+ do {
+ loops ++;
+ prec += loops <= 2 ? mpc_ceil_log2 (prec) + 5 : prec / 2;
+
+ mpc_set_prec (res, prec);
+ mpfr_set_prec (q, prec);
+
+ /* first compute norm(c) */
+ mpfr_clear_underflow ();
+ mpfr_clear_overflow ();
+ inexact_norm = mpc_norm (q, c, GMP_RNDU);
+ underflow_norm = mpfr_underflow_p ();
+ overflow_norm = mpfr_overflow_p ();
+ if (underflow_norm)
+ mpfr_set_ui (q, 0ul, GMP_RNDN);
+ /* to obtain divisions by 0 later on */
+
+ /* now compute b*conjugate(c) */
+ mpfr_clear_underflow ();
+ mpfr_clear_overflow ();
+ inexact_prod = mpc_mul (res, b, c_conj, MPC_RNDZZ);
+ inexact_re = MPC_INEX_RE (inexact_prod);
+ inexact_im = MPC_INEX_IM (inexact_prod);
+ underflow_prod = mpfr_underflow_p ();
+ overflow_prod = mpfr_overflow_p ();
+ /* unfortunately, does not distinguish between under-/overflow
+ in real or imaginary parts
+ hopefully, the side-effects of mpc_mul do indeed raise the
+ mpfr exceptions */
+ if (overflow_prod) {
+ int isinf = 0;
+ tmpsgn = mpfr_sgn (mpc_realref(res));
+ if (tmpsgn > 0)
+ {
+ mpfr_nextabove (mpc_realref(res));
+ isinf = mpfr_inf_p (mpc_realref(res));
+ mpfr_nextbelow (mpc_realref(res));
+ }
+ else if (tmpsgn < 0)
+ {
+ mpfr_nextbelow (mpc_realref(res));
+ isinf = mpfr_inf_p (mpc_realref(res));
+ mpfr_nextabove (mpc_realref(res));
+ }
+ if (isinf)
+ {
+ mpfr_set_inf (mpc_realref(res), tmpsgn);
+ overflow_re = 1;
+ }
+ tmpsgn = mpfr_sgn (mpc_imagref(res));
+ isinf = 0;
+ if (tmpsgn > 0)
+ {
+ mpfr_nextabove (mpc_imagref(res));
+ isinf = mpfr_inf_p (mpc_imagref(res));
+ mpfr_nextbelow (mpc_imagref(res));
+ }
+ else if (tmpsgn < 0)
+ {
+ mpfr_nextbelow (mpc_imagref(res));
+ isinf = mpfr_inf_p (mpc_imagref(res));
+ mpfr_nextabove (mpc_imagref(res));
+ }
+ if (isinf)
+ {
+ mpfr_set_inf (mpc_imagref(res), tmpsgn);
+ overflow_im = 1;
+ }
+ mpc_set (a, res, rnd);
+ goto end;
+ }
+
+ /* divide the product by the norm */
+ if (inexact_norm == 0 && (inexact_re == 0 || inexact_im == 0)) {
+ /* The division has good chances to be exact in at least one part. */
+ /* Since this can cause problems when not rounding to the nearest, */
+ /* we use the division code of mpfr, which handles the situation. */
+ mpfr_clear_underflow ();
+ mpfr_clear_overflow ();
+ inexact_re |= mpfr_div (mpc_realref (res), mpc_realref (res), q, GMP_RNDZ);
+ underflow_re = mpfr_underflow_p ();
+ overflow_re = mpfr_overflow_p ();
+ ok_re = !inexact_re || underflow_re || overflow_re
+ || mpfr_can_round (mpc_realref (res), prec - 4, GMP_RNDN,
+ GMP_RNDZ, MPC_PREC_RE(a) + (rnd_re == GMP_RNDN));
+
+ if (ok_re) /* compute imaginary part */ {
+ mpfr_clear_underflow ();
+ mpfr_clear_overflow ();
+ inexact_im |= mpfr_div (mpc_imagref (res), mpc_imagref (res), q, GMP_RNDZ);
+ underflow_im = mpfr_underflow_p ();
+ overflow_im = mpfr_overflow_p ();
+ ok_im = !inexact_im || underflow_im || overflow_im
+ || mpfr_can_round (mpc_imagref (res), prec - 4, GMP_RNDN,
+ GMP_RNDZ, MPC_PREC_IM(a) + (rnd_im == GMP_RNDN));
+ }
+ }
+ else {
+ /* The division is inexact, so for efficiency reasons we invert q */
+ /* only once and multiply by the inverse. */
+ if (mpfr_ui_div (q, 1ul, q, GMP_RNDZ) || inexact_norm) {
+ /* if 1/q is inexact, the approximations of the real and
+ imaginary part below will be inexact, unless RE(res)
+ or IM(res) is zero */
+ inexact_re |= ~mpfr_zero_p (mpc_realref (res));
+ inexact_im |= ~mpfr_zero_p (mpc_imagref (res));
+ }
+ mpfr_clear_underflow ();
+ mpfr_clear_overflow ();
+ inexact_re |= mpfr_mul (mpc_realref (res), mpc_realref (res), q, GMP_RNDZ);
+ underflow_re = mpfr_underflow_p ();
+ overflow_re = mpfr_overflow_p ();
+ ok_re = !inexact_re || underflow_re || overflow_re
+ || mpfr_can_round (mpc_realref (res), prec - 4, GMP_RNDN,
+ GMP_RNDZ, MPC_PREC_RE(a) + (rnd_re == GMP_RNDN));
+
+ if (ok_re) /* compute imaginary part */ {
+ mpfr_clear_underflow ();
+ mpfr_clear_overflow ();
+ inexact_im |= mpfr_mul (mpc_imagref (res), mpc_imagref (res), q, GMP_RNDZ);
+ underflow_im = mpfr_underflow_p ();
+ overflow_im = mpfr_overflow_p ();
+ ok_im = !inexact_im || underflow_im || overflow_im
+ || mpfr_can_round (mpc_imagref (res), prec - 4, GMP_RNDN,
+ GMP_RNDZ, MPC_PREC_IM(a) + (rnd_im == GMP_RNDN));
+ }
+ }
+ } while ((!ok_re || !ok_im) && !underflow_norm && !overflow_norm
+ && !underflow_prod && !overflow_prod);
+
+ inex = mpc_set (a, res, rnd);
+ inexact_re = MPC_INEX_RE (inex);
+ inexact_im = MPC_INEX_IM (inex);
+
+ end:
+ /* fix values and inexact flags in case of overflow/underflow */
+ /* FIXME: heuristic, certainly does not cover all cases */
+ if (overflow_re || (underflow_norm && !underflow_prod)) {
+ mpfr_set_inf (mpc_realref (a), mpfr_sgn (mpc_realref (res)));
+ inexact_re = mpfr_sgn (mpc_realref (res));
+ }
+ else if (underflow_re || (overflow_norm && !overflow_prod)) {
+ inexact_re = mpfr_signbit (mpc_realref (res)) ? 1 : -1;
+ mpfr_set_zero (mpc_realref (a), -inexact_re);
+ }
+ if (overflow_im || (underflow_norm && !underflow_prod)) {
+ mpfr_set_inf (mpc_imagref (a), mpfr_sgn (mpc_imagref (res)));
+ inexact_im = mpfr_sgn (mpc_imagref (res));
+ }
+ else if (underflow_im || (overflow_norm && !overflow_prod)) {
+ inexact_im = mpfr_signbit (mpc_imagref (res)) ? 1 : -1;
+ mpfr_set_zero (mpc_imagref (a), -inexact_im);
+ }
+
+ mpc_clear (res);
+ mpfr_clear (q);
+
+ /* restore underflow and overflow flags from MPFR */
+ if (saved_underflow)
+ mpfr_set_underflow ();
+ if (saved_overflow)
+ mpfr_set_overflow ();
+
+ return MPC_INEX (inexact_re, inexact_im);
+}
diff --git a/mpc/src/div_2si.c b/mpc/src/div_2si.c
new file mode 100644
index 0000000000..511f2cb52f
--- /dev/null
+++ b/mpc/src/div_2si.c
@@ -0,0 +1,32 @@
+/* mpc_div_2si -- Divide a complex number by 2^e.
+
+Copyright (C) 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_div_2si (mpc_ptr a, mpc_srcptr b, long int c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_div_2si (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_div_2si (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/div_2ui.c b/mpc/src/div_2ui.c
new file mode 100644
index 0000000000..cd53855cf6
--- /dev/null
+++ b/mpc/src/div_2ui.c
@@ -0,0 +1,32 @@
+/* mpc_div_2ui -- Divide a complex number by 2^e.
+
+Copyright (C) 2002, 2009, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_div_2ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_div_2ui (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_div_2ui (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/div_fr.c b/mpc/src/div_fr.c
new file mode 100644
index 0000000000..d5ea24030f
--- /dev/null
+++ b/mpc/src/div_fr.c
@@ -0,0 +1,39 @@
+/* mpc_div_fr -- Divide a complex number by a floating-point number.
+
+Copyright (C) 2002, 2008, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_div_fr (mpc_ptr a, mpc_srcptr b, mpfr_srcptr c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+ mpfr_t real;
+
+ /* We have to use temporary variable in case c=mpc_realref (a). */
+ mpfr_init2 (real, MPC_PREC_RE (a));
+
+ inex_re = mpfr_div (real, mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_div (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
+ mpfr_set (mpc_realref (a), real, GMP_RNDN);
+
+ mpfr_clear (real);
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/div_ui.c b/mpc/src/div_ui.c
new file mode 100644
index 0000000000..26debf7dfe
--- /dev/null
+++ b/mpc/src/div_ui.c
@@ -0,0 +1,32 @@
+/* mpc_div_ui -- Divide a complex number by a nonnegative integer.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_div_ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_div_ui (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_div_ui (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/exp.c b/mpc/src/exp.c
new file mode 100644
index 0000000000..36462251c1
--- /dev/null
+++ b/mpc/src/exp.c
@@ -0,0 +1,202 @@
+/* mpc_exp -- exponential of a complex number.
+
+Copyright (C) 2002, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_exp (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ mpfr_t x, y, z;
+ mpfr_prec_t prec;
+ int ok = 0;
+ int inex_re, inex_im;
+ int saved_underflow, saved_overflow;
+
+ /* special values */
+ if (mpfr_nan_p (mpc_realref (op)) || mpfr_nan_p (mpc_imagref (op)))
+ /* NaNs
+ exp(nan +i*y) = nan -i*0 if y = -0,
+ nan +i*0 if y = +0,
+ nan +i*nan otherwise
+ exp(x+i*nan) = +/-0 +/-i*0 if x=-inf,
+ +/-inf +i*nan if x=+inf,
+ nan +i*nan otherwise */
+ {
+ if (mpfr_zero_p (mpc_imagref (op)))
+ return mpc_set (rop, op, MPC_RNDNN);
+
+ if (mpfr_inf_p (mpc_realref (op)))
+ {
+ if (mpfr_signbit (mpc_realref (op)))
+ return mpc_set_ui_ui (rop, 0, 0, MPC_RNDNN);
+ else
+ {
+ mpfr_set_inf (mpc_realref (rop), +1);
+ mpfr_set_nan (mpc_imagref (rop));
+ return MPC_INEX(0, 0); /* Inf/NaN are exact */
+ }
+ }
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ return MPC_INEX(0, 0); /* NaN is exact */
+ }
+
+
+ if (mpfr_zero_p (mpc_imagref(op)))
+ /* special case when the input is real
+ exp(x-i*0) = exp(x) -i*0, even if x is NaN
+ exp(x+i*0) = exp(x) +i*0, even if x is NaN */
+ {
+ inex_re = mpfr_exp (mpc_realref(rop), mpc_realref(op), MPC_RND_RE(rnd));
+ inex_im = mpfr_set (mpc_imagref(rop), mpc_imagref(op), MPC_RND_IM(rnd));
+ return MPC_INEX(inex_re, inex_im);
+ }
+
+ if (mpfr_zero_p (mpc_realref (op)))
+ /* special case when the input is imaginary */
+ {
+ inex_re = mpfr_cos (mpc_realref (rop), mpc_imagref (op), MPC_RND_RE(rnd));
+ inex_im = mpfr_sin (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM(rnd));
+ return MPC_INEX(inex_re, inex_im);
+ }
+
+
+ if (mpfr_inf_p (mpc_realref (op)))
+ /* real part is an infinity,
+ exp(-inf +i*y) = 0*(cos y +i*sin y)
+ exp(+inf +i*y) = +/-inf +i*nan if y = +/-inf
+ +inf*(cos y +i*sin y) if 0 < |y| < inf */
+ {
+ mpfr_t n;
+
+ mpfr_init2 (n, 2);
+ if (mpfr_signbit (mpc_realref (op)))
+ mpfr_set_ui (n, 0, GMP_RNDN);
+ else
+ mpfr_set_inf (n, +1);
+
+ if (mpfr_inf_p (mpc_imagref (op)))
+ {
+ inex_re = mpfr_set (mpc_realref (rop), n, GMP_RNDN);
+ if (mpfr_signbit (mpc_realref (op)))
+ inex_im = mpfr_set (mpc_imagref (rop), n, GMP_RNDN);
+ else
+ {
+ mpfr_set_nan (mpc_imagref (rop));
+ inex_im = 0; /* NaN is exact */
+ }
+ }
+ else
+ {
+ mpfr_t c, s;
+ mpfr_init2 (c, 2);
+ mpfr_init2 (s, 2);
+
+ mpfr_sin_cos (s, c, mpc_imagref (op), GMP_RNDN);
+ inex_re = mpfr_copysign (mpc_realref (rop), n, c, GMP_RNDN);
+ inex_im = mpfr_copysign (mpc_imagref (rop), n, s, GMP_RNDN);
+
+ mpfr_clear (s);
+ mpfr_clear (c);
+ }
+
+ mpfr_clear (n);
+ return MPC_INEX(inex_re, inex_im);
+ }
+
+ if (mpfr_inf_p (mpc_imagref (op)))
+ /* real part is finite non-zero number, imaginary part is an infinity */
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ return MPC_INEX(0, 0); /* NaN is exact */
+ }
+
+
+ /* from now on, both parts of op are regular numbers */
+
+ prec = MPC_MAX_PREC(rop)
+ + MPC_MAX (MPC_MAX (-mpfr_get_exp (mpc_realref (op)), 0),
+ -mpfr_get_exp (mpc_imagref (op)));
+ /* When op is close to 0, then exp is close to 1+Re(op), while
+ cos is close to 1-Im(op); to decide on the ternary value of exp*cos,
+ we need a high enough precision so that none of exp or cos is
+ computed as 1. */
+ mpfr_init2 (x, 2);
+ mpfr_init2 (y, 2);
+ mpfr_init2 (z, 2);
+
+ /* save the underflow or overflow flags from MPFR */
+ saved_underflow = mpfr_underflow_p ();
+ saved_overflow = mpfr_overflow_p ();
+
+ do
+ {
+ prec += mpc_ceil_log2 (prec) + 5;
+
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (y, prec);
+ mpfr_set_prec (z, prec);
+
+ /* FIXME: x may overflow so x.y does overflow too, while Re(exp(op))
+ could be represented in the precision of rop. */
+ mpfr_clear_overflow ();
+ mpfr_clear_underflow ();
+ mpfr_exp (x, mpc_realref(op), GMP_RNDN); /* error <= 0.5ulp */
+ mpfr_sin_cos (z, y, mpc_imagref(op), GMP_RNDN); /* errors <= 0.5ulp */
+ mpfr_mul (y, y, x, GMP_RNDN); /* error <= 2ulp */
+ ok = mpfr_overflow_p () || mpfr_zero_p (x)
+ || mpfr_can_round (y, prec - 2, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_RE(rop) + (MPC_RND_RE(rnd) == GMP_RNDN));
+ if (ok) /* compute imaginary part */
+ {
+ mpfr_mul (z, z, x, GMP_RNDN);
+ ok = mpfr_overflow_p () || mpfr_zero_p (x)
+ || mpfr_can_round (z, prec - 2, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_IM(rop) + (MPC_RND_IM(rnd) == GMP_RNDN));
+ }
+ }
+ while (ok == 0);
+
+ inex_re = mpfr_set (mpc_realref(rop), y, MPC_RND_RE(rnd));
+ inex_im = mpfr_set (mpc_imagref(rop), z, MPC_RND_IM(rnd));
+ if (mpfr_overflow_p ()) {
+ /* overflow in real exponential, inex is sign of infinite result */
+ inex_re = mpfr_sgn (y);
+ inex_im = mpfr_sgn (z);
+ }
+ else if (mpfr_underflow_p ()) {
+ /* underflow in real exponential, inex is opposite of sign of 0 result */
+ inex_re = (mpfr_signbit (y) ? +1 : -1);
+ inex_im = (mpfr_signbit (z) ? +1 : -1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ /* restore underflow and overflow flags from MPFR */
+ if (saved_underflow)
+ mpfr_set_underflow ();
+ if (saved_overflow)
+ mpfr_set_overflow ();
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/fma.c b/mpc/src/fma.c
new file mode 100644
index 0000000000..7f5cd31b8a
--- /dev/null
+++ b/mpc/src/fma.c
@@ -0,0 +1,191 @@
+/* mpc_fma -- Fused multiply-add of three complex numbers
+
+Copyright (C) 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* return a bound on the precision needed to add or subtract x and y exactly */
+static mpfr_prec_t
+bound_prec_addsub (mpfr_srcptr x, mpfr_srcptr y)
+{
+ if (!mpfr_regular_p (x))
+ return mpfr_get_prec (y);
+ else if (!mpfr_regular_p (y))
+ return mpfr_get_prec (x);
+ else /* neither x nor y are NaN, Inf or zero */
+ {
+ mpfr_exp_t ex = mpfr_get_exp (x);
+ mpfr_exp_t ey = mpfr_get_exp (y);
+ mpfr_exp_t ulpx = ex - mpfr_get_prec (x);
+ mpfr_exp_t ulpy = ey - mpfr_get_prec (y);
+ return ((ex >= ey) ? ex : ey) + 1 - ((ulpx <= ulpy) ? ulpx : ulpy);
+ }
+}
+
+/* r <- a*b+c */
+int
+mpc_fma_naive (mpc_ptr r, mpc_srcptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
+{
+ mpfr_t rea_reb, rea_imb, ima_reb, ima_imb, tmp;
+ mpfr_prec_t pre12, pre13, pre23, pim12, pim13, pim23;
+ int inex_re, inex_im;
+
+ mpfr_init2 (rea_reb, mpfr_get_prec (mpc_realref(a)) + mpfr_get_prec (mpc_realref(b)));
+ mpfr_init2 (rea_imb, mpfr_get_prec (mpc_realref(a)) + mpfr_get_prec (mpc_imagref(b)));
+ mpfr_init2 (ima_reb, mpfr_get_prec (mpc_imagref(a)) + mpfr_get_prec (mpc_realref(b)));
+ mpfr_init2 (ima_imb, mpfr_get_prec (mpc_imagref(a)) + mpfr_get_prec (mpc_imagref(b)));
+
+ mpfr_mul (rea_reb, mpc_realref(a), mpc_realref(b), GMP_RNDZ); /* exact */
+ mpfr_mul (rea_imb, mpc_realref(a), mpc_imagref(b), GMP_RNDZ); /* exact */
+ mpfr_mul (ima_reb, mpc_imagref(a), mpc_realref(b), GMP_RNDZ); /* exact */
+ mpfr_mul (ima_imb, mpc_imagref(a), mpc_imagref(b), GMP_RNDZ); /* exact */
+
+ /* Re(r) <- rea_reb - ima_imb + Re(c) */
+
+ pre12 = bound_prec_addsub (rea_reb, ima_imb); /* bound on exact precision for
+ rea_reb - ima_imb */
+ pre13 = bound_prec_addsub (rea_reb, mpc_realref(c));
+ /* bound for rea_reb + Re(c) */
+ pre23 = bound_prec_addsub (ima_imb, mpc_realref(c));
+ /* bound for ima_imb - Re(c) */
+ if (pre12 <= pre13 && pre12 <= pre23) /* (rea_reb - ima_imb) + Re(c) */
+ {
+ mpfr_init2 (tmp, pre12);
+ mpfr_sub (tmp, rea_reb, ima_imb, GMP_RNDZ); /* exact */
+ inex_re = mpfr_add (mpc_realref(r), tmp, mpc_realref(c), MPC_RND_RE(rnd));
+ /* the only possible bad overlap is between r and c, but since we are
+ only touching the real part of both, it is ok */
+ }
+ else if (pre13 <= pre23) /* (rea_reb + Re(c)) - ima_imb */
+ {
+ mpfr_init2 (tmp, pre13);
+ mpfr_add (tmp, rea_reb, mpc_realref(c), GMP_RNDZ); /* exact */
+ inex_re = mpfr_sub (mpc_realref(r), tmp, ima_imb, MPC_RND_RE(rnd));
+ /* the only possible bad overlap is between r and c, but since we are
+ only touching the real part of both, it is ok */
+ }
+ else /* rea_reb + (Re(c) - ima_imb) */
+ {
+ mpfr_init2 (tmp, pre23);
+ mpfr_sub (tmp, mpc_realref(c), ima_imb, GMP_RNDZ); /* exact */
+ inex_re = mpfr_add (mpc_realref(r), tmp, rea_reb, MPC_RND_RE(rnd));
+ /* the only possible bad overlap is between r and c, but since we are
+ only touching the real part of both, it is ok */
+ }
+
+ /* Im(r) <- rea_imb + ima_reb + Im(c) */
+ pim12 = bound_prec_addsub (rea_imb, ima_reb); /* bound on exact precision for
+ rea_imb + ima_reb */
+ pim13 = bound_prec_addsub (rea_imb, mpc_imagref(c));
+ /* bound for rea_imb + Im(c) */
+ pim23 = bound_prec_addsub (ima_reb, mpc_imagref(c));
+ /* bound for ima_reb + Im(c) */
+ if (pim12 <= pim13 && pim12 <= pim23) /* (rea_imb + ima_reb) + Im(c) */
+ {
+ mpfr_set_prec (tmp, pim12);
+ mpfr_add (tmp, rea_imb, ima_reb, GMP_RNDZ); /* exact */
+ inex_im = mpfr_add (mpc_imagref(r), tmp, mpc_imagref(c), MPC_RND_IM(rnd));
+ /* the only possible bad overlap is between r and c, but since we are
+ only touching the imaginary part of both, it is ok */
+ }
+ else if (pim13 <= pim23) /* (rea_imb + Im(c)) + ima_reb */
+ {
+ mpfr_set_prec (tmp, pim13);
+ mpfr_add (tmp, rea_imb, mpc_imagref(c), GMP_RNDZ); /* exact */
+ inex_im = mpfr_add (mpc_imagref(r), tmp, ima_reb, MPC_RND_IM(rnd));
+ /* the only possible bad overlap is between r and c, but since we are
+ only touching the imaginary part of both, it is ok */
+ }
+ else /* rea_imb + (Im(c) + ima_reb) */
+ {
+ mpfr_set_prec (tmp, pre23);
+ mpfr_add (tmp, mpc_imagref(c), ima_reb, GMP_RNDZ); /* exact */
+ inex_im = mpfr_add (mpc_imagref(r), tmp, rea_imb, MPC_RND_IM(rnd));
+ /* the only possible bad overlap is between r and c, but since we are
+ only touching the imaginary part of both, it is ok */
+ }
+
+ mpfr_clear (rea_reb);
+ mpfr_clear (rea_imb);
+ mpfr_clear (ima_reb);
+ mpfr_clear (ima_imb);
+ mpfr_clear (tmp);
+
+ return MPC_INEX(inex_re, inex_im);
+}
+
+/* The algorithm is as follows:
+ - in a first pass, we use the target precision + some extra bits
+ - if it fails, we add the number of cancelled bits when adding
+ Re(a*b) and Re(c) [similarly for the imaginary part]
+ - it is fails again, we call the mpc_fma_naive function, which also
+ deals with the special cases */
+int
+mpc_fma (mpc_ptr r, mpc_srcptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
+{
+ mpc_t ab;
+ mpfr_prec_t pre, pim, wpre, wpim;
+ mpfr_exp_t diffre, diffim;
+ int i, inex = 0, okre = 0, okim = 0;
+
+ if (mpc_fin_p (a) == 0 || mpc_fin_p (b) == 0 || mpc_fin_p (c) == 0)
+ return mpc_fma_naive (r, a, b, c, rnd);
+
+ pre = mpfr_get_prec (mpc_realref(r));
+ pim = mpfr_get_prec (mpc_imagref(r));
+ wpre = pre + mpc_ceil_log2 (pre) + 10;
+ wpim = pim + mpc_ceil_log2 (pim) + 10;
+ mpc_init3 (ab, wpre, wpim);
+ for (i = 0; i < 2; ++i)
+ {
+ mpc_mul (ab, a, b, MPC_RNDZZ);
+ if (mpfr_zero_p (mpc_realref(ab)) || mpfr_zero_p (mpc_imagref(ab)))
+ break;
+ diffre = mpfr_get_exp (mpc_realref(ab));
+ diffim = mpfr_get_exp (mpc_imagref(ab));
+ mpc_add (ab, ab, c, MPC_RNDZZ);
+ if (mpfr_zero_p (mpc_realref(ab)) || mpfr_zero_p (mpc_imagref(ab)))
+ break;
+ diffre -= mpfr_get_exp (mpc_realref(ab));
+ diffim -= mpfr_get_exp (mpc_imagref(ab));
+ diffre = (diffre > 0 ? diffre + 1 : 1);
+ diffim = (diffim > 0 ? diffim + 1 : 1);
+ okre = diffre > (mpfr_exp_t) wpre ? 0 : mpfr_can_round (mpc_realref(ab),
+ wpre - diffre, GMP_RNDN, GMP_RNDZ,
+ pre + (MPC_RND_RE (rnd) == GMP_RNDN));
+ okim = diffim > (mpfr_exp_t) wpim ? 0 : mpfr_can_round (mpc_imagref(ab),
+ wpim - diffim, GMP_RNDN, GMP_RNDZ,
+ pim + (MPC_RND_IM (rnd) == GMP_RNDN));
+ if (okre && okim)
+ {
+ inex = mpc_set (r, ab, rnd);
+ break;
+ }
+ if (i == 1)
+ break;
+ if (okre == 0 && diffre > 1)
+ wpre += diffre;
+ if (okim == 0 && diffim > 1)
+ wpim += diffim;
+ mpfr_set_prec (mpc_realref(ab), wpre);
+ mpfr_set_prec (mpc_imagref(ab), wpim);
+ }
+ mpc_clear (ab);
+ return okre && okim ? inex : mpc_fma_naive (r, a, b, c, rnd);
+}
diff --git a/mpc/src/fr_div.c b/mpc/src/fr_div.c
new file mode 100644
index 0000000000..e57eced1f8
--- /dev/null
+++ b/mpc/src/fr_div.c
@@ -0,0 +1,39 @@
+/* mpc_fr_div -- Divide a floating-point number by a complex number.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_fr_div (mpc_ptr a, mpfr_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
+{
+ mpc_t bc;
+ int inexact;
+
+ mpc_realref (bc)[0] = b [0];
+ mpfr_init (mpc_imagref (bc));
+ /* we consider the operand b to have imaginary part +0 */
+ mpfr_set_ui (mpc_imagref (bc), 0, GMP_RNDN);
+
+ inexact = mpc_div (a, bc, c, rnd);
+
+ mpfr_clear (mpc_imagref (bc));
+
+ return inexact;
+}
diff --git a/mpc/src/fr_sub.c b/mpc/src/fr_sub.c
new file mode 100644
index 0000000000..91338a4fd6
--- /dev/null
+++ b/mpc/src/fr_sub.c
@@ -0,0 +1,33 @@
+/* mpc_fr_sub -- Substract a complex number from a floating-point number.
+
+Copyright (C) 2008, 2009, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* return 0 iff both the real and imaginary parts are exact */
+int
+mpc_fr_sub (mpc_ptr a, mpfr_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_sub (mpc_realref (a), b, mpc_realref (c), MPC_RND_RE (rnd));
+ inex_im = mpfr_neg (mpc_imagref (a), mpc_imagref (c), MPC_RND_IM (rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/get_prec.c b/mpc/src/get_prec.c
new file mode 100644
index 0000000000..f1fe856c3e
--- /dev/null
+++ b/mpc/src/get_prec.c
@@ -0,0 +1,28 @@
+/* mpc_get_prec -- returns the common precision of real and imaginary part, or 0 if they differ
+
+Copyright (C) 2007, 2009, 2010 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+mpfr_prec_t
+mpc_get_prec (mpc_srcptr x)
+{
+ mpfr_prec_t precre = MPC_PREC_RE (x);
+ return (MPC_PREC_IM (x) == precre ? precre : 0);
+}
diff --git a/mpc/src/get_prec2.c b/mpc/src/get_prec2.c
new file mode 100644
index 0000000000..79015c8392
--- /dev/null
+++ b/mpc/src/get_prec2.c
@@ -0,0 +1,29 @@
+/* mpc_get_prec2 -- returns the precisions of the real and of the imaginary
+ part through the first two arguments
+
+Copyright (C) 2007, 2009, 2010 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+void
+mpc_get_prec2 (mpfr_prec_t *pr, mpfr_prec_t *pi, mpc_srcptr x)
+{
+ *pr = MPC_PREC_RE (x);
+ *pi = MPC_PREC_IM (x);
+}
diff --git a/mpc/src/get_version.c b/mpc/src/get_version.c
new file mode 100644
index 0000000000..1bf77f0a4f
--- /dev/null
+++ b/mpc/src/get_version.c
@@ -0,0 +1,48 @@
+/* mpc_get_version -- MPC version
+
+Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+#if MPFR_VERSION_MAJOR < 3
+/* The following are functions defined for compatibility with mpfr < 3;
+ logically, they should be defined in a separate file, but then gcc
+ complains about an empty translation unit with mpfr >= 3. */
+
+void
+mpfr_set_zero (mpfr_ptr z, int s)
+{
+ mpfr_set_ui (z, 0ul, GMP_RNDN);
+ if (s < 0)
+ mpfr_neg (z, z, GMP_RNDN);
+}
+
+int
+mpfr_regular_p (mpfr_srcptr z)
+{
+ return (mpfr_number_p (z) && !mpfr_zero_p (z));
+}
+#endif /* mpfr < 3 */
+
+
+const char *
+mpc_get_version (void)
+{
+ return "1.0.2";
+}
diff --git a/mpc/src/get_x.c b/mpc/src/get_x.c
new file mode 100644
index 0000000000..31610ac61d
--- /dev/null
+++ b/mpc/src/get_x.c
@@ -0,0 +1,236 @@
+/* mpc_get_dc, mpc_get_ldc -- Transform mpc number into C complex number
+ mpc_get_str -- Convert a complex number into a string.
+
+Copyright (C) 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "config.h"
+
+#ifdef HAVE_COMPLEX_H
+#include <complex.h>
+#endif
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include <stdio.h> /* for sprintf, fprintf */
+#include <ctype.h>
+#include <string.h>
+#include "mpc-impl.h"
+
+#ifdef HAVE_COMPLEX_H
+double _Complex
+mpc_get_dc (mpc_srcptr op, mpc_rnd_t rnd) {
+ return I * mpfr_get_d (mpc_imagref (op), MPC_RND_IM (rnd))
+ + mpfr_get_d (mpc_realref (op), MPC_RND_RE (rnd));
+}
+
+long double _Complex
+mpc_get_ldc (mpc_srcptr op, mpc_rnd_t rnd) {
+ return I * mpfr_get_ld (mpc_imagref (op), MPC_RND_IM (rnd))
+ + mpfr_get_ld (mpc_realref (op), MPC_RND_RE (rnd));
+}
+#endif
+
+
+/* Code for mpc_get_str. The output format is "(real imag)", the decimal point
+ of the locale is used. */
+
+/* mpfr_prec_t can be either int or long int */
+#if (__GMP_MP_SIZE_T_INT == 1)
+#define MPC_EXP_FORMAT_SPEC "i"
+#elif (__GMP_MP_SIZE_T_INT == 0)
+#define MPC_EXP_FORMAT_SPEC "li"
+#else
+#error "mpfr_exp_t size not supported"
+#endif
+
+static char *
+pretty_zero (mpfr_srcptr zero)
+{
+ char *pretty;
+
+ pretty = mpc_alloc_str (3);
+
+ pretty[0] = mpfr_signbit (zero) ? '-' : '+';
+ pretty[1] = '0';
+ pretty[2] = '\0';
+
+ return pretty;
+}
+
+static char *
+prettify (const char *str, const mp_exp_t expo, int base, int special)
+{
+ size_t sz;
+ char *pretty;
+ char *p;
+ const char *s;
+ mp_exp_t x;
+ int sign;
+
+ sz = strlen (str) + 1; /* + terminal '\0' */
+
+ if (special)
+ {
+ /* special number: nan or inf */
+ pretty = mpc_alloc_str (sz);
+ strcpy (pretty, str);
+
+ return pretty;
+ }
+
+ /* regular number */
+
+ sign = (str[0] == '-' || str[0] == '+');
+
+ x = expo - 1; /* expo is the exponent value with decimal point BEFORE
+ the first digit, we wants decimal point AFTER the first
+ digit */
+ if (base == 16)
+ x <<= 2; /* the output exponent is a binary exponent */
+
+ ++sz; /* + decimal point */
+
+ if (x != 0)
+ {
+ /* augment sz with the size needed for an exponent written in base
+ ten */
+ mp_exp_t xx;
+
+ sz += 3; /* + exponent char + sign + 1 digit */
+
+ if (x < 0)
+ {
+ /* avoid overflow when changing sign (assuming that, for the
+ mp_exp_t type, (max value) is greater than (- min value / 10)) */
+ if (x < -10)
+ {
+ xx = - (x / 10);
+ sz++;
+ }
+ else
+ xx = -x;
+ }
+ else
+ xx = x;
+
+ /* compute sz += floor(log(expo)/log(10)) without using libm
+ functions */
+ while (xx > 9)
+ {
+ sz++;
+ xx /= 10;
+ }
+ }
+
+ pretty = mpc_alloc_str (sz);
+ p = pretty;
+
+ /* 1. optional sign plus first digit */
+ s = str;
+ *p++ = *s++;
+ if (sign)
+ *p++ = *s++;
+
+ /* 2. decimal point */
+#ifdef HAVE_LOCALECONV
+ *p++ = *localeconv ()->decimal_point;
+#else
+ *p++ = '.';
+#endif
+ *p = '\0';
+
+ /* 3. other significant digits */
+ strcat (pretty, s);
+
+ /* 4. exponent (in base ten) */
+ if (x == 0)
+ return pretty;
+
+ p = pretty + strlen (str) + 1;
+
+ switch (base)
+ {
+ case 10:
+ *p++ = 'e';
+ break;
+ case 2:
+ case 16:
+ *p++ = 'p';
+ break;
+ default:
+ *p++ = '@';
+ }
+
+ *p = '\0';
+
+ sprintf (p, "%+"MPC_EXP_FORMAT_SPEC, x);
+
+ return pretty;
+}
+
+static char *
+get_pretty_str (const int base, const size_t n, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ mp_exp_t expo;
+ char *ugly;
+ char *pretty;
+
+ if (mpfr_zero_p (x))
+ return pretty_zero (x);
+
+ ugly = mpfr_get_str (NULL, &expo, base, n, x, rnd);
+ MPC_ASSERT (ugly != NULL);
+ pretty = prettify (ugly, expo, base, !mpfr_number_p (x));
+ mpfr_free_str (ugly);
+
+ return pretty;
+}
+
+char *
+mpc_get_str (int base, size_t n, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ size_t needed_size;
+ char *real_str;
+ char *imag_str;
+ char *complex_str = NULL;
+
+ if (base < 2 || base > 36)
+ return NULL;
+
+ real_str = get_pretty_str (base, n, mpc_realref (op), MPC_RND_RE (rnd));
+ imag_str = get_pretty_str (base, n, mpc_imagref (op), MPC_RND_IM (rnd));
+
+ needed_size = strlen (real_str) + strlen (imag_str) + 4;
+
+ complex_str = mpc_alloc_str (needed_size);
+MPC_ASSERT (complex_str != NULL);
+
+ strcpy (complex_str, "(");
+ strcat (complex_str, real_str);
+ strcat (complex_str, " ");
+ strcat (complex_str, imag_str);
+ strcat (complex_str, ")");
+
+ mpc_free_str (real_str);
+ mpc_free_str (imag_str);
+
+ return complex_str;
+}
diff --git a/mpc/src/imag.c b/mpc/src/imag.c
new file mode 100644
index 0000000000..5f3b3a5873
--- /dev/null
+++ b/mpc/src/imag.c
@@ -0,0 +1,27 @@
+/* mpc_imag -- Get the imaginary part of a complex number.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_imag (mpfr_ptr a, mpc_srcptr b, mpfr_rnd_t rnd)
+{
+ return mpfr_set (a, mpc_imagref (b), rnd);
+}
diff --git a/mpc/src/init2.c b/mpc/src/init2.c
new file mode 100644
index 0000000000..ce4173e72e
--- /dev/null
+++ b/mpc/src/init2.c
@@ -0,0 +1,28 @@
+/* mpc_init2 -- Initialize a complex variable with a given precision.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+void
+mpc_init2 (mpc_t x, mpfr_prec_t prec)
+{
+ mpfr_init2 (mpc_realref(x), prec);
+ mpfr_init2 (mpc_imagref(x), prec);
+}
diff --git a/mpc/src/init3.c b/mpc/src/init3.c
new file mode 100644
index 0000000000..69f91b2580
--- /dev/null
+++ b/mpc/src/init3.c
@@ -0,0 +1,28 @@
+/* mpc_init3 -- Initialize a complex variable with given precisions.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+void
+mpc_init3 (mpc_t x, mpfr_prec_t prec_re, mpfr_prec_t prec_im)
+{
+ mpfr_init2 (mpc_realref(x), prec_re);
+ mpfr_init2 (mpc_imagref(x), prec_im);
+}
diff --git a/mpc/src/inp_str.c b/mpc/src/inp_str.c
new file mode 100644
index 0000000000..695a3adff6
--- /dev/null
+++ b/mpc/src/inp_str.c
@@ -0,0 +1,239 @@
+/* mpc_inp_str -- Input a complex number from a given stream.
+
+Copyright (C) 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for FILE */
+#include <ctype.h>
+#include <string.h>
+#include "mpc-impl.h"
+
+static size_t
+skip_whitespace (FILE *stream)
+{
+ int c = getc (stream);
+ size_t size = 0;
+ while (c != EOF && isspace ((unsigned char) c)) {
+ c = getc (stream);
+ size++;
+ }
+ if (c != EOF)
+ ungetc (c, stream);
+ return size;
+}
+
+/* Extract from stream the longest string made up of alphanumeric char and
+ '_' (i.e. n-char-sequence).
+ The user must free the returned string. */
+static char *
+extract_suffix (FILE *stream)
+{
+ int c;
+ size_t nread = 0;
+ size_t strsize = 100;
+ char *str = mpc_alloc_str (strsize);
+
+ c = getc (stream);
+ while (isalnum ((unsigned char) c) || c == '_') {
+ str [nread] = (char) c;
+ nread++;
+ if (nread == strsize) {
+ str = mpc_realloc_str (str, strsize, 2 * strsize);
+ strsize *= 2;
+ }
+ c = getc (stream);
+ }
+
+ str = mpc_realloc_str (str, strsize, nread + 1);
+ strsize = nread + 1;
+ str [nread] = '\0';
+
+ if (c != EOF)
+ ungetc (c, stream);
+ return str;
+}
+
+
+/* Extract from the stream the longest string of characters which are neither
+ whitespace nor brackets (except for an optional bracketed n-char_sequence
+ directly following nan or @nan@ independently of case).
+ The user must free the returned string. */
+static char *
+extract_string (FILE *stream)
+{
+ int c;
+ size_t nread = 0;
+ size_t strsize = 100;
+ char *str = mpc_alloc_str (strsize);
+ size_t lenstr;
+
+ c = getc (stream);
+ while (c != EOF && c != '\n'
+ && !isspace ((unsigned char) c)
+ && c != '(' && c != ')') {
+ str [nread] = (char) c;
+ nread++;
+ if (nread == strsize) {
+ str = mpc_realloc_str (str, strsize, 2 * strsize);
+ strsize *= 2;
+ }
+ c = getc (stream);
+ }
+
+ str = mpc_realloc_str (str, strsize, nread + 1);
+ strsize = nread + 1;
+ str [nread] = '\0';
+
+ if (nread == 0)
+ return str;
+
+ lenstr = nread;
+
+ if (c == '(') {
+ size_t n;
+ char *suffix;
+ int ret;
+
+ /* (n-char-sequence) only after a NaN */
+ if ((nread != 3
+ || tolower ((unsigned char) (str[0])) != 'n'
+ || tolower ((unsigned char) (str[1])) != 'a'
+ || tolower ((unsigned char) (str[2])) != 'n')
+ && (nread != 5
+ || str[0] != '@'
+ || tolower ((unsigned char) (str[1])) != 'n'
+ || tolower ((unsigned char) (str[2])) != 'a'
+ || tolower ((unsigned char) (str[3])) != 'n'
+ || str[4] != '@')) {
+ ungetc (c, stream);
+ return str;
+ }
+
+ suffix = extract_suffix (stream);
+ nread += strlen (suffix) + 1;
+ if (nread >= strsize) {
+ str = mpc_realloc_str (str, strsize, nread + 1);
+ strsize = nread + 1;
+ }
+
+ /* Warning: the sprintf does not allow overlap between arguments. */
+ ret = sprintf (str + lenstr, "(%s", suffix);
+ MPC_ASSERT (ret >= 0);
+ n = lenstr + (size_t) ret;
+ MPC_ASSERT (n == nread);
+
+ c = getc (stream);
+ if (c == ')') {
+ str = mpc_realloc_str (str, strsize, nread + 2);
+ strsize = nread + 2;
+ str [nread] = (char) c;
+ str [nread+1] = '\0';
+ nread++;
+ }
+ else if (c != EOF)
+ ungetc (c, stream);
+
+ mpc_free_str (suffix);
+ }
+ else if (c != EOF)
+ ungetc (c, stream);
+
+ return str;
+}
+
+
+int
+mpc_inp_str (mpc_ptr rop, FILE *stream, size_t *read, int base,
+mpc_rnd_t rnd_mode)
+{
+ size_t white, nread = 0;
+ int inex = -1;
+ int c;
+ char *str;
+
+ if (stream == NULL)
+ stream = stdin;
+
+ white = skip_whitespace (stream);
+ c = getc (stream);
+ if (c != EOF) {
+ if (c == '(') {
+ char *real_str;
+ char *imag_str;
+ size_t n;
+ int ret;
+
+ nread++; /* the opening parenthesis */
+ white = skip_whitespace (stream);
+ real_str = extract_string (stream);
+ nread += strlen(real_str);
+
+ c = getc (stream);
+ if (!isspace ((unsigned int) c)) {
+ if (c != EOF)
+ ungetc (c, stream);
+ mpc_free_str (real_str);
+ goto error;
+ }
+ else
+ ungetc (c, stream);
+
+ white += skip_whitespace (stream);
+ imag_str = extract_string (stream);
+ nread += strlen (imag_str);
+
+ str = mpc_alloc_str (nread + 2);
+ ret = sprintf (str, "(%s %s", real_str, imag_str);
+ MPC_ASSERT (ret >= 0);
+ n = (size_t) ret;
+ MPC_ASSERT (n == nread + 1);
+ mpc_free_str (real_str);
+ mpc_free_str (imag_str);
+
+ white += skip_whitespace (stream);
+ c = getc (stream);
+ if (c == ')') {
+ str = mpc_realloc_str (str, nread +2, nread + 3);
+ str [nread+1] = (char) c;
+ str [nread+2] = '\0';
+ nread++;
+ }
+ else if (c != EOF)
+ ungetc (c, stream);
+ }
+ else {
+ if (c != EOF)
+ ungetc (c, stream);
+ str = extract_string (stream);
+ nread += strlen (str);
+ }
+
+ inex = mpc_set_str (rop, str, base, rnd_mode);
+
+ mpc_free_str (str);
+ }
+
+error:
+ if (inex == -1) {
+ mpfr_set_nan (mpc_realref(rop));
+ mpfr_set_nan (mpc_imagref(rop));
+ }
+ if (read != NULL)
+ *read = white + nread;
+ return inex;
+}
diff --git a/mpc/src/log.c b/mpc/src/log.c
new file mode 100644
index 0000000000..ad1d448053
--- /dev/null
+++ b/mpc/src/log.c
@@ -0,0 +1,217 @@
+/* mpc_log -- Take the logarithm of a complex number.
+
+Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for MPC_ASSERT */
+#include "mpc-impl.h"
+
+int
+mpc_log (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd){
+ int ok, underflow = 0;
+ mpfr_srcptr x, y;
+ mpfr_t v, w;
+ mpfr_prec_t prec;
+ int loops;
+ int re_cmp, im_cmp;
+ int inex_re, inex_im;
+ int err;
+ mpfr_exp_t expw;
+ int sgnw;
+
+ /* special values: NaN and infinities */
+ if (!mpc_fin_p (op)) {
+ if (mpfr_nan_p (mpc_realref (op))) {
+ if (mpfr_inf_p (mpc_imagref (op)))
+ mpfr_set_inf (mpc_realref (rop), +1);
+ else
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ inex_im = 0; /* Inf/NaN is exact */
+ }
+ else if (mpfr_nan_p (mpc_imagref (op))) {
+ if (mpfr_inf_p (mpc_realref (op)))
+ mpfr_set_inf (mpc_realref (rop), +1);
+ else
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ inex_im = 0; /* Inf/NaN is exact */
+ }
+ else /* We have an infinity in at least one part. */ {
+ inex_im = mpfr_atan2 (mpc_imagref (rop), mpc_imagref (op), mpc_realref (op),
+ MPC_RND_IM (rnd));
+ mpfr_set_inf (mpc_realref (rop), +1);
+ }
+ return MPC_INEX(0, inex_im);
+ }
+
+ /* special cases: real and purely imaginary numbers */
+ re_cmp = mpfr_cmp_ui (mpc_realref (op), 0);
+ im_cmp = mpfr_cmp_ui (mpc_imagref (op), 0);
+ if (im_cmp == 0) {
+ if (re_cmp == 0) {
+ inex_im = mpfr_atan2 (mpc_imagref (rop), mpc_imagref (op), mpc_realref (op),
+ MPC_RND_IM (rnd));
+ mpfr_set_inf (mpc_realref (rop), -1);
+ inex_re = 0; /* -Inf is exact */
+ }
+ else if (re_cmp > 0) {
+ inex_re = mpfr_log (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd));
+ inex_im = mpfr_set (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd));
+ }
+ else {
+ /* op = x + 0*y; let w = -x = |x| */
+ int negative_zero;
+ mpfr_rnd_t rnd_im;
+
+ negative_zero = mpfr_signbit (mpc_imagref (op));
+ if (negative_zero)
+ rnd_im = INV_RND (MPC_RND_IM (rnd));
+ else
+ rnd_im = MPC_RND_IM (rnd);
+ w [0] = *mpc_realref (op);
+ MPFR_CHANGE_SIGN (w);
+ inex_re = mpfr_log (mpc_realref (rop), w, MPC_RND_RE (rnd));
+ inex_im = mpfr_const_pi (mpc_imagref (rop), rnd_im);
+ if (negative_zero) {
+ mpc_conj (rop, rop, MPC_RNDNN);
+ inex_im = -inex_im;
+ }
+ }
+ return MPC_INEX(inex_re, inex_im);
+ }
+ else if (re_cmp == 0) {
+ if (im_cmp > 0) {
+ inex_re = mpfr_log (mpc_realref (rop), mpc_imagref (op), MPC_RND_RE (rnd));
+ inex_im = mpfr_const_pi (mpc_imagref (rop), MPC_RND_IM (rnd));
+ /* division by 2 does not change the ternary flag */
+ mpfr_div_2ui (mpc_imagref (rop), mpc_imagref (rop), 1, GMP_RNDN);
+ }
+ else {
+ w [0] = *mpc_imagref (op);
+ MPFR_CHANGE_SIGN (w);
+ inex_re = mpfr_log (mpc_realref (rop), w, MPC_RND_RE (rnd));
+ inex_im = mpfr_const_pi (mpc_imagref (rop), INV_RND (MPC_RND_IM (rnd)));
+ /* division by 2 does not change the ternary flag */
+ mpfr_div_2ui (mpc_imagref (rop), mpc_imagref (rop), 1, GMP_RNDN);
+ mpfr_neg (mpc_imagref (rop), mpc_imagref (rop), GMP_RNDN);
+ inex_im = -inex_im; /* negate the ternary flag */
+ }
+ return MPC_INEX(inex_re, inex_im);
+ }
+
+ prec = MPC_PREC_RE(rop);
+ mpfr_init2 (w, 2);
+ /* let op = x + iy; log = 1/2 log (x^2 + y^2) + i atan2 (y, x) */
+ /* loop for the real part: 1/2 log (x^2 + y^2), fast, but unsafe */
+ /* implementation */
+ ok = 0;
+ for (loops = 1; !ok && loops <= 2; loops++) {
+ prec += mpc_ceil_log2 (prec) + 4;
+ mpfr_set_prec (w, prec);
+
+ mpc_abs (w, op, GMP_RNDN);
+ /* error 0.5 ulp */
+ if (mpfr_inf_p (w))
+ /* intermediate overflow; the logarithm may be representable.
+ Intermediate underflow is impossible. */
+ break;
+
+ mpfr_log (w, w, GMP_RNDN);
+ /* generic error of log: (2^(- exp(w)) + 0.5) ulp */
+
+ if (mpfr_zero_p (w))
+ /* impossible to round, switch to second algorithm */
+ break;
+
+ err = MPC_MAX (-mpfr_get_exp (w), 0) + 1;
+ /* number of lost digits */
+ ok = mpfr_can_round (w, prec - err, GMP_RNDN, GMP_RNDZ,
+ mpfr_get_prec (mpc_realref (rop)) + (MPC_RND_RE (rnd) == GMP_RNDN));
+ }
+
+ if (!ok) {
+ prec = MPC_PREC_RE(rop);
+ mpfr_init2 (v, 2);
+ /* compute 1/2 log (x^2 + y^2) = log |x| + 1/2 * log (1 + (y/x)^2)
+ if |x| >= |y|; otherwise, exchange x and y */
+ if (mpfr_cmpabs (mpc_realref (op), mpc_imagref (op)) >= 0) {
+ x = mpc_realref (op);
+ y = mpc_imagref (op);
+ }
+ else {
+ x = mpc_imagref (op);
+ y = mpc_realref (op);
+ }
+
+ do {
+ prec += mpc_ceil_log2 (prec) + 4;
+ mpfr_set_prec (v, prec);
+ mpfr_set_prec (w, prec);
+
+ mpfr_div (v, y, x, GMP_RNDD); /* error 1 ulp */
+ mpfr_sqr (v, v, GMP_RNDD);
+ /* generic error of multiplication:
+ 1 + 2*1*(2+1*2^(1-prec)) <= 5.0625 since prec >= 6 */
+ mpfr_log1p (v, v, GMP_RNDD);
+ /* error 1 + 4*5.0625 = 21.25 , see algorithms.tex */
+ mpfr_div_2ui (v, v, 1, GMP_RNDD);
+ /* If the result is 0, then there has been an underflow somewhere. */
+
+ mpfr_abs (w, x, GMP_RNDN); /* exact */
+ mpfr_log (w, w, GMP_RNDN); /* error 0.5 ulp */
+ expw = mpfr_get_exp (w);
+ sgnw = mpfr_signbit (w);
+
+ mpfr_add (w, w, v, GMP_RNDN);
+ if (!sgnw) /* v is positive, so no cancellation;
+ error 22.25 ulp; error counts lost bits */
+ err = 5;
+ else
+ err = MPC_MAX (5 + mpfr_get_exp (v),
+ /* 21.25 ulp (v) rewritten in ulp (result, now in w) */
+ -1 + expw - mpfr_get_exp (w)
+ /* 0.5 ulp (previous w), rewritten in ulp (result) */
+ ) + 2;
+
+ /* handle one special case: |x|=1, and (y/x)^2 underflows;
+ then 1/2*log(x^2+y^2) \approx 1/2*y^2 also underflows. */
+ if ( (mpfr_cmp_si (x, -1) == 0 || mpfr_cmp_ui (x, 1) == 0)
+ && mpfr_zero_p (w))
+ underflow = 1;
+
+ } while (!underflow &&
+ !mpfr_can_round (w, prec - err, GMP_RNDN, GMP_RNDZ,
+ mpfr_get_prec (mpc_realref (rop)) + (MPC_RND_RE (rnd) == GMP_RNDN)));
+ mpfr_clear (v);
+ }
+
+ /* imaginary part */
+ inex_im = mpfr_atan2 (mpc_imagref (rop), mpc_imagref (op), mpc_realref (op),
+ MPC_RND_IM (rnd));
+
+ /* set the real part; cannot be done before if rop==op */
+ if (underflow)
+ /* create underflow in result */
+ inex_re = mpfr_set_ui_2exp (mpc_realref (rop), 1,
+ mpfr_get_emin_min () - 2, MPC_RND_RE (rnd));
+ else
+ inex_re = mpfr_set (mpc_realref (rop), w, MPC_RND_RE (rnd));
+ mpfr_clear (w);
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/log10.c b/mpc/src/log10.c
new file mode 100644
index 0000000000..4e77aafe15
--- /dev/null
+++ b/mpc/src/log10.c
@@ -0,0 +1,286 @@
+/* mpc_log10 -- Take the base-10 logarithm of a complex number.
+
+Copyright (C) 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <limits.h> /* for CHAR_BIT */
+#include "mpc-impl.h"
+
+/* Auxiliary functions which implement Ziv's strategy for special cases.
+ if flag = 0: compute only real part
+ if flag = 1: compute only imaginary
+ Exact cases should be dealt with separately. */
+static int
+mpc_log10_aux (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd, int flag, int nb)
+{
+ mp_prec_t prec = (MPFR_PREC_MIN > 4) ? MPFR_PREC_MIN : 4;
+ mpc_t tmp;
+ mpfr_t log10;
+ int ok = 0, ret;
+
+ prec = mpfr_get_prec ((flag == 0) ? mpc_realref (rop) : mpc_imagref (rop));
+ prec += 10;
+ mpc_init2 (tmp, prec);
+ mpfr_init2 (log10, prec);
+ while (ok == 0)
+ {
+ mpfr_set_ui (log10, 10, GMP_RNDN); /* exact since prec >= 4 */
+ mpfr_log (log10, log10, GMP_RNDN);
+ /* In each case we have two roundings, thus the final value is
+ x * (1+u)^2 where x is the exact value, and |u| <= 2^(-prec-1).
+ Thus the error is always less than 3 ulps. */
+ switch (nb)
+ {
+ case 0: /* imag <- atan2(y/x) */
+ mpfr_atan2 (mpc_imagref (tmp), mpc_imagref (op), mpc_realref (op),
+ MPC_RND_IM (rnd));
+ mpfr_div (mpc_imagref (tmp), mpc_imagref (tmp), log10, GMP_RNDN);
+ ok = mpfr_can_round (mpc_imagref (tmp), prec - 2, GMP_RNDN,
+ GMP_RNDZ, MPC_PREC_IM(rop) +
+ (MPC_RND_IM (rnd) == GMP_RNDN));
+ if (ok)
+ ret = mpfr_set (mpc_imagref (rop), mpc_imagref (tmp),
+ MPC_RND_IM (rnd));
+ break;
+ case 1: /* real <- log(x) */
+ mpfr_log (mpc_realref (tmp), mpc_realref (op), MPC_RND_RE (rnd));
+ mpfr_div (mpc_realref (tmp), mpc_realref (tmp), log10, GMP_RNDN);
+ ok = mpfr_can_round (mpc_realref (tmp), prec - 2, GMP_RNDN,
+ GMP_RNDZ, MPC_PREC_RE(rop) +
+ (MPC_RND_RE (rnd) == GMP_RNDN));
+ if (ok)
+ ret = mpfr_set (mpc_realref (rop), mpc_realref (tmp),
+ MPC_RND_RE (rnd));
+ break;
+ case 2: /* imag <- pi */
+ mpfr_const_pi (mpc_imagref (tmp), MPC_RND_IM (rnd));
+ mpfr_div (mpc_imagref (tmp), mpc_imagref (tmp), log10, GMP_RNDN);
+ ok = mpfr_can_round (mpc_imagref (tmp), prec - 2, GMP_RNDN,
+ GMP_RNDZ, MPC_PREC_IM(rop) +
+ (MPC_RND_IM (rnd) == GMP_RNDN));
+ if (ok)
+ ret = mpfr_set (mpc_imagref (rop), mpc_imagref (tmp),
+ MPC_RND_IM (rnd));
+ break;
+ }
+ prec += prec / 2;
+ mpc_set_prec (tmp, prec);
+ mpfr_set_prec (log10, prec);
+ }
+ mpc_clear (tmp);
+ mpfr_clear (log10);
+ return ret;
+}
+
+int
+mpc_log10 (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ int ok = 0, loops = 0, re_cmp, im_cmp, inex_re, inex_im, negative_zero;
+ mpfr_t w;
+ mpfr_prec_t prec;
+ mpfr_rnd_t rnd_im;
+ mpc_t ww;
+ mpc_rnd_t invrnd;
+
+ /* special values: NaN and infinities: same as mpc_log */
+ if (!mpc_fin_p (op)) /* real or imaginary parts are NaN or Inf */
+ {
+ if (mpfr_nan_p (mpc_realref (op)))
+ {
+ if (mpfr_inf_p (mpc_imagref (op)))
+ /* (NaN, Inf) -> (+Inf, NaN) */
+ mpfr_set_inf (mpc_realref (rop), +1);
+ else
+ /* (NaN, xxx) -> (NaN, NaN) */
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ inex_im = 0; /* Inf/NaN is exact */
+ }
+ else if (mpfr_nan_p (mpc_imagref (op)))
+ {
+ if (mpfr_inf_p (mpc_realref (op)))
+ /* (Inf, NaN) -> (+Inf, NaN) */
+ mpfr_set_inf (mpc_realref (rop), +1);
+ else
+ /* (xxx, NaN) -> (NaN, NaN) */
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ inex_im = 0; /* Inf/NaN is exact */
+ }
+ else /* We have an infinity in at least one part. */
+ {
+ /* (+Inf, y) -> (+Inf, 0) for finite positive-signed y */
+ if (mpfr_inf_p (mpc_realref (op)) && mpfr_signbit (mpc_realref (op))
+ == 0 && mpfr_number_p (mpc_imagref (op)))
+ inex_im = mpfr_atan2 (mpc_imagref (rop), mpc_imagref (op),
+ mpc_realref (op), MPC_RND_IM (rnd));
+ else
+ /* (xxx, Inf) -> (+Inf, atan2(Inf/xxx))
+ (Inf, yyy) -> (+Inf, atan2(yyy/Inf)) */
+ inex_im = mpc_log10_aux (rop, op, rnd, 1, 0);
+ mpfr_set_inf (mpc_realref (rop), +1);
+ }
+ return MPC_INEX(0, inex_im);
+ }
+
+ /* special cases: real and purely imaginary numbers */
+ re_cmp = mpfr_cmp_ui (mpc_realref (op), 0);
+ im_cmp = mpfr_cmp_ui (mpc_imagref (op), 0);
+ if (im_cmp == 0) /* Im(op) = 0 */
+ {
+ if (re_cmp == 0) /* Re(op) = 0 */
+ {
+ if (mpfr_signbit (mpc_realref (op)) == 0)
+ inex_im = mpfr_atan2 (mpc_imagref (rop), mpc_imagref (op),
+ mpc_realref (op), MPC_RND_IM (rnd));
+ else
+ inex_im = mpc_log10_aux (rop, op, rnd, 1, 0);
+ mpfr_set_inf (mpc_realref (rop), -1);
+ inex_re = 0; /* -Inf is exact */
+ }
+ else if (re_cmp > 0)
+ {
+ inex_re = mpfr_log10 (mpc_realref (rop), mpc_realref (op),
+ MPC_RND_RE (rnd));
+ inex_im = mpfr_set (mpc_imagref (rop), mpc_imagref (op),
+ MPC_RND_IM (rnd));
+ }
+ else /* log10(x + 0*i) for negative x */
+ { /* op = x + 0*i; let w = -x = |x| */
+ negative_zero = mpfr_signbit (mpc_imagref (op));
+ if (negative_zero)
+ rnd_im = INV_RND (MPC_RND_IM (rnd));
+ else
+ rnd_im = MPC_RND_IM (rnd);
+ ww->re[0] = *mpc_realref (op);
+ MPFR_CHANGE_SIGN (ww->re);
+ ww->im[0] = *mpc_imagref (op);
+ if (mpfr_cmp_ui (ww->re, 1) == 0)
+ inex_re = mpfr_set_ui (mpc_realref (rop), 0, MPC_RND_RE (rnd));
+ else
+ inex_re = mpc_log10_aux (rop, ww, rnd, 0, 1);
+ inex_im = mpc_log10_aux (rop, op, MPC_RND (0,rnd_im), 1, 2);
+ if (negative_zero)
+ {
+ mpc_conj (rop, rop, MPC_RNDNN);
+ inex_im = -inex_im;
+ }
+ }
+ return MPC_INEX(inex_re, inex_im);
+ }
+ else if (re_cmp == 0)
+ {
+ if (im_cmp > 0)
+ {
+ inex_re = mpfr_log10 (mpc_realref (rop), mpc_imagref (op), MPC_RND_RE (rnd));
+ inex_im = mpc_log10_aux (rop, op, rnd, 1, 2);
+ /* division by 2 does not change the ternary flag */
+ mpfr_div_2ui (mpc_imagref (rop), mpc_imagref (rop), 1, GMP_RNDN);
+ }
+ else
+ {
+ w [0] = *mpc_imagref (op);
+ MPFR_CHANGE_SIGN (w);
+ inex_re = mpfr_log10 (mpc_realref (rop), w, MPC_RND_RE (rnd));
+ invrnd = MPC_RND (0, INV_RND (MPC_RND_IM (rnd)));
+ inex_im = mpc_log10_aux (rop, op, invrnd, 1, 2);
+ /* division by 2 does not change the ternary flag */
+ mpfr_div_2ui (mpc_imagref (rop), mpc_imagref (rop), 1, GMP_RNDN);
+ mpfr_neg (mpc_imagref (rop), mpc_imagref (rop), GMP_RNDN);
+ inex_im = -inex_im; /* negate the ternary flag */
+ }
+ return MPC_INEX(inex_re, inex_im);
+ }
+
+ /* generic case: neither Re(op) nor Im(op) is NaN, Inf or zero */
+ prec = MPC_PREC_RE(rop);
+ mpfr_init2 (w, prec);
+ mpc_init2 (ww, prec);
+ /* let op = x + iy; compute log(op)/log(10) */
+ while (ok == 0)
+ {
+ loops ++;
+ prec += (loops <= 2) ? mpc_ceil_log2 (prec) + 4 : prec / 2;
+ mpfr_set_prec (w, prec);
+ mpc_set_prec (ww, prec);
+
+ mpc_log (ww, op, MPC_RNDNN);
+ mpfr_set_ui (w, 10, GMP_RNDN); /* exact since prec >= 4 */
+ mpfr_log (w, w, GMP_RNDN);
+ mpc_div_fr (ww, ww, w, MPC_RNDNN);
+
+ ok = mpfr_can_round (mpc_realref (ww), prec - 2, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_RE(rop) + (MPC_RND_RE (rnd) == GMP_RNDN));
+
+ /* Special code to deal with cases where the real part of log10(x+i*y)
+ is exact, like x=3 and y=1. Since Re(log10(x+i*y)) = log10(x^2+y^2)/2
+ this happens whenever x^2+y^2 is a nonnegative power of 10.
+ Indeed x^2+y^2 cannot equal 10^(a/2^b) for a, b integers, a odd, b>0,
+ since x^2+y^2 is rational, and 10^(a/2^b) is irrational.
+ Similarly, for b=0, x^2+y^2 cannot equal 10^a for a < 0 since x^2+y^2
+ is a rational with denominator a power of 2.
+ Now let x^2+y^2 = 10^s. Without loss of generality we can assume
+ x = u/2^e and y = v/2^e with u, v, e integers: u^2+v^2 = 10^s*2^(2e)
+ thus u^2+v^2 = 0 mod 2^(2e). By recurrence on e, necessarily
+ u = v = 0 mod 2^e, thus x and y are necessarily integers.
+ */
+ if ((ok == 0) && (loops == 1) && mpfr_integer_p (mpc_realref (op)) &&
+ mpfr_integer_p (mpc_imagref (op)))
+ {
+ mpz_t x, y;
+ unsigned long s, v;
+
+ mpz_init (x);
+ mpz_init (y);
+ mpfr_get_z (x, mpc_realref (op), GMP_RNDN); /* exact */
+ mpfr_get_z (y, mpc_imagref (op), GMP_RNDN); /* exact */
+ mpz_mul (x, x, x);
+ mpz_mul (y, y, y);
+ mpz_add (x, x, y); /* x^2+y^2 */
+ v = mpz_scan1 (x, 0);
+ /* if x = 10^s then necessarily s = v */
+ s = mpz_sizeinbase (x, 10);
+ /* since s is either the number of digits of x or one more,
+ then x = 10^(s-1) or 10^(s-2) */
+ if (s == v + 1 || s == v + 2)
+ {
+ mpz_div_2exp (x, x, v);
+ mpz_ui_pow_ui (y, 5, v);
+ if (mpz_cmp (y, x) == 0) /* Re(log10(x+i*y)) is exactly v/2 */
+ {
+ /* we reset the precision of Re(ww) so that v can be
+ represented exactly */
+ mpfr_set_prec (mpc_realref (ww), sizeof(unsigned long)*CHAR_BIT);
+ mpfr_set_ui_2exp (mpc_realref (ww), v, -1, GMP_RNDN); /* exact */
+ ok = 1;
+ }
+ }
+ mpz_clear (x);
+ mpz_clear (y);
+ }
+
+ ok = ok && mpfr_can_round (mpc_imagref (ww), prec-2, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_IM(rop) + (MPC_RND_IM (rnd) == GMP_RNDN));
+ }
+
+ inex_re = mpfr_set (mpc_realref(rop), mpc_realref (ww), MPC_RND_RE (rnd));
+ inex_im = mpfr_set (mpc_imagref(rop), mpc_imagref (ww), MPC_RND_IM (rnd));
+ mpfr_clear (w);
+ mpc_clear (ww);
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/logging.c b/mpc/src/logging.c
new file mode 100644
index 0000000000..79ed0338e7
--- /dev/null
+++ b/mpc/src/logging.c
@@ -0,0 +1,147 @@
+/* logging.c -- "Dummy" functions logging calls to real mpc functions.
+
+Copyright (C) 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "config.h"
+#include <stdio.h>
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#define __MPC_LIBRARY_BUILD
+ /* to indicate we are inside the library build; needed here since mpc-log.h
+ includes mpc.h and not mpc-impl.h */
+#include "mpc-log.h"
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+typedef int (*c_c_func_ptr) (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+typedef int (*c_cc_func_ptr) (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+typedef int (*c_ccc_func_ptr) (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+typedef int (*cc_c_func_ptr) (mpc_ptr, mpc_ptr, mpc_srcptr, mpc_rnd_t, mpc_rnd_t);
+
+#define MPC_LOGGING_OUT_PREC(z) \
+ do { \
+ fprintf (stderr, " %li %li", (long) mpfr_get_prec (mpc_realref (z)), \
+ (long) mpfr_get_prec (mpc_imagref (z))); \
+ } while (0);
+
+#define MPC_LOGGING_OUT_C(z) \
+ do { \
+ MPC_LOGGING_OUT_PREC (z); \
+ fprintf (stderr, " "); \
+ mpc_out_str (stderr, 16, 0, z, MPC_RNDNN); \
+ } while (0);
+
+#define MPC_LOGGING_FUNC_TYPE(funcname, type) \
+ do { \
+ fprintf (stderr, "mpc_"#funcname" "#type); \
+ } while (0);
+
+#define MPC_LOGGING_C_C(funcname) \
+__MPC_DECLSPEC int mpc_log_##funcname (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) \
+{ \
+ static c_c_func_ptr func = NULL; \
+ if (func == NULL) \
+ func = (c_c_func_ptr) (intptr_t) dlsym (NULL, "mpc_"#funcname); \
+ MPC_LOGGING_FUNC_TYPE (funcname, c_c); \
+ MPC_LOGGING_OUT_PREC (rop); \
+ MPC_LOGGING_OUT_C (op); \
+ fprintf (stderr, "\n"); \
+ return func (rop, op, rnd); \
+}
+
+#define MPC_LOGGING_C_CC(funcname) \
+__MPC_DECLSPEC int mpc_log_##funcname (mpc_ptr rop, mpc_srcptr op1, mpc_srcptr op2, mpc_rnd_t rnd) \
+{ \
+ static c_cc_func_ptr func = NULL; \
+ if (func == NULL) \
+ func = (c_cc_func_ptr) (intptr_t) dlsym (NULL, "mpc_"#funcname); \
+ MPC_LOGGING_FUNC_TYPE (funcname, c_cc); \
+ MPC_LOGGING_OUT_PREC (rop); \
+ MPC_LOGGING_OUT_C (op1); \
+ MPC_LOGGING_OUT_C (op2); \
+ fprintf (stderr, "\n"); \
+ return func (rop, op1, op2, rnd); \
+}
+
+#define MPC_LOGGING_C_CCC(funcname) \
+__MPC_DECLSPEC int mpc_log_##funcname (mpc_ptr rop, mpc_srcptr op1, mpc_srcptr op2, mpc_srcptr op3, mpc_rnd_t rnd) \
+{ \
+ static c_ccc_func_ptr func = NULL; \
+ if (func == NULL) \
+ func = (c_ccc_func_ptr) (intptr_t) dlsym (NULL, "mpc_"#funcname); \
+ MPC_LOGGING_FUNC_TYPE (funcname, c_ccc); \
+ MPC_LOGGING_OUT_PREC (rop); \
+ MPC_LOGGING_OUT_C (op1); \
+ MPC_LOGGING_OUT_C (op2); \
+ MPC_LOGGING_OUT_C (op3); \
+ fprintf (stderr, "\n"); \
+ return func (rop, op1, op2, op3, rnd); \
+}
+
+#define MPC_LOGGING_CC_C(funcname) \
+__MPC_DECLSPEC int mpc_log_##funcname (mpc_ptr rop1, mpc_ptr rop2, mpc_srcptr op, mpc_rnd_t rnd1, mpc_rnd_t rnd2) \
+{ \
+ static cc_c_func_ptr func = NULL; \
+ if (func == NULL) \
+ func = (cc_c_func_ptr) (intptr_t) dlsym (NULL, "mpc_"#funcname); \
+ MPC_LOGGING_FUNC_TYPE (funcname, cc_c); \
+ MPC_LOGGING_OUT_PREC (rop1); \
+ MPC_LOGGING_OUT_PREC (rop2); \
+ MPC_LOGGING_OUT_C (op); \
+ fprintf (stderr, "\n"); \
+ return func (rop1, rop2, op, rnd1, rnd2); \
+}
+
+MPC_LOGGING_C_C (sqr)
+MPC_LOGGING_C_C (conj)
+MPC_LOGGING_C_C (neg)
+MPC_LOGGING_C_C (sqrt)
+MPC_LOGGING_C_C (proj)
+MPC_LOGGING_C_C (exp)
+MPC_LOGGING_C_C (log)
+MPC_LOGGING_C_C (sin)
+MPC_LOGGING_C_C (cos)
+MPC_LOGGING_C_C (tan)
+MPC_LOGGING_C_C (sinh)
+MPC_LOGGING_C_C (cosh)
+MPC_LOGGING_C_C (tanh)
+MPC_LOGGING_C_C (asin)
+MPC_LOGGING_C_C (acos)
+MPC_LOGGING_C_C (atan)
+MPC_LOGGING_C_C (asinh)
+MPC_LOGGING_C_C (acosh)
+MPC_LOGGING_C_C (atanh)
+
+MPC_LOGGING_C_CC (add)
+MPC_LOGGING_C_CC (sub)
+MPC_LOGGING_C_CC (mul)
+MPC_LOGGING_C_CC (div)
+MPC_LOGGING_C_CC (pow)
+
+MPC_LOGGING_C_CCC (fma)
+
+MPC_LOGGING_CC_C (sin_cos)
diff --git a/mpc/src/mem.c b/mpc/src/mem.c
new file mode 100644
index 0000000000..b4c327c079
--- /dev/null
+++ b/mpc/src/mem.c
@@ -0,0 +1,46 @@
+/* wrapper functions to allocate, reallocate and free memory
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <string.h> /* for strlen */
+#include "mpc-impl.h"
+
+char *
+mpc_alloc_str (size_t len)
+{
+ void * (*allocfunc) (size_t);
+ mp_get_memory_functions (&allocfunc, NULL, NULL);
+ return (char *) ((*allocfunc) (len));
+}
+
+char *
+mpc_realloc_str (char * str, size_t oldlen, size_t newlen)
+{
+ void * (*reallocfunc) (void *, size_t, size_t);
+ mp_get_memory_functions (NULL, &reallocfunc, NULL);
+ return (char *) ((*reallocfunc) (str, oldlen, newlen));
+}
+
+void
+mpc_free_str (char *str)
+{
+ void (*freefunc) (void *, size_t);
+ mp_get_memory_functions (NULL, NULL, &freefunc);
+ (*freefunc) (str, strlen (str) + 1);
+}
diff --git a/mpc/src/mpc-impl.h b/mpc/src/mpc-impl.h
new file mode 100644
index 0000000000..b2aaa90eb3
--- /dev/null
+++ b/mpc/src/mpc-impl.h
@@ -0,0 +1,194 @@
+/* mpc-impl.h -- Internal include file for mpc.
+
+Copyright (C) 2002, 2004, 2005, 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#ifndef __MPC_IMPL_H
+#define __MPC_IMPL_H
+#define __MPC_LIBRARY_BUILD
+ /* to indicate we are inside the library build */
+
+#include "config.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "mpc.h"
+
+/*
+ * Miscellaneous useful macros
+ */
+
+#define MPC_MIN(h,i) ((h) < (i) ? (h) : (i))
+#define MPC_MAX(h,i) ((h) > (i) ? (h) : (i))
+
+/* Safe absolute value (to avoid possible integer overflow) */
+/* type is the target (unsigned) type (copied from mpfr-impl.h) */
+#ifdef SAFE_ABS
+#undef SAFE_ABS
+#endif
+#define SAFE_ABS(type,x) ((x) >= 0 ? (type)(x) : -(type)(x))
+
+
+/*
+ * MPFR constants and macros
+ */
+
+#ifndef BITS_PER_MP_LIMB
+#define BITS_PER_MP_LIMB mp_bits_per_limb
+#endif
+
+#define MPFR_SIGNBIT(x) (mpfr_signbit (x) ? -1 : 1)
+#define MPC_MPFR_SIGN(x) (mpfr_zero_p (x) ? 0 : MPFR_SIGNBIT (x))
+ /* should be called MPFR_SIGN, but this is taken in mpfr.h */
+#define MPFR_CHANGE_SIGN(x) mpfr_neg(x,x,GMP_RNDN)
+#define MPFR_COPYSIGN(x,y,z,rnd) (mpfr_nan_p (z) ? \
+ mpfr_setsign (x, y, 0, rnd) : \
+ mpfr_copysign (x, y, z, rnd))
+ /* work around spurious signs in nan */
+#define MPFR_ADD_ONE_ULP(x) mpfr_add_one_ulp (x, GMP_RNDN)
+#define MPFR_SUB_ONE_ULP(x) mpfr_sub_one_ulp (x, GMP_RNDN)
+ /* drop unused rounding mode from macroes */
+#define MPFR_SWAP(a,b) do { mpfr_srcptr tmp; tmp = a; a = b; b = tmp; } while (0)
+
+
+/*
+ * Macro implementing rounding away from zero, to ease compatibility with
+ * mpfr < 3. f is the complete function call with a rounding mode of
+ * MPFR_RNDA, rop the name of the variable containing the result; it is
+ * already contained in f, but needs to be repeated so that the macro can
+ * modify the variable.
+ * Usage: replace each call to a function such as
+ * mpfr_add (rop, a, b, MPFR_RNDA)
+ * by
+ * ROUND_AWAY (mpfr_add (rop, a, b, MPFR_RNDA), rop)
+*/
+#if MPFR_VERSION_MAJOR < 3
+ /* round towards zero, add 1 ulp if not exact */
+#define MPFR_RNDA GMP_RNDZ
+#define ROUND_AWAY(f,rop) \
+ ((f) ? MPFR_ADD_ONE_ULP (rop), MPFR_SIGNBIT (rop) : 0)
+#else
+#define ROUND_AWAY(f,rop) \
+ (f)
+#endif /* mpfr < 3 */
+
+#if MPFR_VERSION_MAJOR < 3
+/* declare missing functions, defined in get_version.c */
+__MPC_DECLSPEC void mpfr_set_zero (mpfr_ptr, int);
+__MPC_DECLSPEC int mpfr_regular_p (mpfr_srcptr);
+#endif /* mpfr < 3 */
+
+
+/*
+ * MPC macros
+ */
+
+#define MPC_PREC_RE(x) (mpfr_get_prec(mpc_realref(x)))
+#define MPC_PREC_IM(x) (mpfr_get_prec(mpc_imagref(x)))
+#define MPC_MAX_PREC(x) MPC_MAX(MPC_PREC_RE(x), MPC_PREC_IM(x))
+
+#define INV_RND(r) \
+ (((r) == GMP_RNDU) ? GMP_RNDD : (((r) == GMP_RNDD) ? GMP_RNDU : (r)))
+
+#define mpc_inf_p(z) (mpfr_inf_p(mpc_realref(z))||mpfr_inf_p(mpc_imagref(z)))
+ /* Convention in C99 (G.3): z is regarded as an infinity if at least one of
+ its parts is infinite */
+#define mpc_zero_p(z) (mpfr_zero_p(mpc_realref(z))&&mpfr_zero_p(mpc_imagref(z)))
+ /* Convention in C99 (G.3): z is regarded as a zero if each of its parts is
+ a zero */
+#define mpc_fin_p(z) (mpfr_number_p(mpc_realref(z))&&mpfr_number_p(mpc_imagref(z)))
+ /* Convention in C99 (G.3): z is regarded as finite if both its parts are */
+#define mpc_nan_p(z) ((mpfr_nan_p(mpc_realref(z)) && !mpfr_inf_p(mpc_imagref(z))) || (mpfr_nan_p(mpc_imagref(z)) && !mpfr_inf_p(mpc_realref(z))))
+ /* Consider as NaN all other numbers containing at least one NaN */
+
+
+/*
+ * ASSERT macros
+ */
+
+#ifdef NDEBUG
+#define MPC_ASSERT(expr) \
+ do { \
+ } while (0)
+#else
+#define MPC_ASSERT(expr) \
+ do { \
+ if (!(expr)) \
+ { \
+ fprintf (stderr, "%s:%d: MPC assertion failed: %s\n", \
+ __FILE__, __LINE__, #expr); \
+ abort(); \
+ } \
+ } while (0)
+#endif
+
+
+/*
+ * Debug macros
+ */
+
+#define MPC_OUT(x) \
+do { \
+ printf (#x "[%lu,%lu]=", (unsigned long int) MPC_PREC_RE (x), \
+ (unsigned long int) MPC_PREC_IM (x)); \
+ mpc_out_str (stdout, 2, 0, x, MPC_RNDNN); \
+ printf ("\n"); \
+} while (0)
+
+#define MPFR_OUT(x) \
+do { \
+ printf (#x "[%lu]=", (unsigned long int) mpfr_get_prec (x)); \
+ mpfr_out_str (stdout, 2, 0, x, GMP_RNDN); \
+ printf ("\n"); \
+} while (0)
+
+
+/*
+ * Constants
+ */
+
+#ifndef MUL_KARATSUBA_THRESHOLD
+#define MUL_KARATSUBA_THRESHOLD 23
+#endif
+
+
+/*
+ * Define internal functions
+ */
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+__MPC_DECLSPEC int mpc_mul_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_mul_karatsuba (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_fma_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_pow_usi (mpc_ptr, mpc_srcptr, unsigned long, int, mpc_rnd_t);
+__MPC_DECLSPEC char* mpc_alloc_str (size_t);
+__MPC_DECLSPEC char* mpc_realloc_str (char*, size_t, size_t);
+__MPC_DECLSPEC void mpc_free_str (char*);
+__MPC_DECLSPEC mpfr_prec_t mpc_ceil_log2 (mpfr_prec_t);
+__MPC_DECLSPEC int set_pi_over_2 (mpfr_ptr, int, mpfr_rnd_t);
+
+#if defined (__cplusplus)
+}
+#endif
+
+
+#endif
diff --git a/mpc/src/mpc-log.h b/mpc/src/mpc-log.h
new file mode 100644
index 0000000000..78c98d2da4
--- /dev/null
+++ b/mpc/src/mpc-log.h
@@ -0,0 +1,51 @@
+/* mpc-log.h -- Include file to enable function call logging; replaces mpc.h.
+
+Copyright (C) 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#define mpc_sqr mpc_log_sqr
+#define mpc_conj mpc_log_conj
+#define mpc_neg mpc_log_neg
+#define mpc_sqrt mpc_log_sqrt
+#define mpc_proj mpc_log_proj
+#define mpc_exp mpc_log_exp
+#define mpc_log mpc_log_log
+#define mpc_sin mpc_log_sin
+#define mpc_cos mpc_log_cos
+#define mpc_tan mpc_log_tan
+#define mpc_sinh mpc_log_sinh
+#define mpc_cosh mpc_log_cosh
+#define mpc_tanh mpc_log_tanh
+#define mpc_asin mpc_log_asin
+#define mpc_acos mpc_log_acos
+#define mpc_atan mpc_log_atan
+#define mpc_asinh mpc_log_asinh
+#define mpc_acosh mpc_log_acosh
+#define mpc_atanh mpc_log_atanh
+
+#define mpc_add mpc_log_add
+#define mpc_sub mpc_log_sub
+#define mpc_mul mpc_log_mul
+#define mpc_div mpc_log_div
+#define mpc_pow mpc_log_pow
+
+#define mpc_fma mpc_log_fma
+
+#define mpc_sin_cos mpc_log_sin_cos
+
+#include "mpc.h"
diff --git a/mpc/src/mpc.h b/mpc/src/mpc.h
new file mode 100644
index 0000000000..1607cac041
--- /dev/null
+++ b/mpc/src/mpc.h
@@ -0,0 +1,269 @@
+/* mpc.h -- Include file for mpc.
+
+Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012, 2014 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#ifndef __MPC_H
+#define __MPC_H
+
+#include "gmp.h"
+#include "mpfr.h"
+
+/* Backwards compatibility with mpfr<3.0.0 */
+#ifndef mpfr_exp_t
+#define mpfr_exp_t mp_exp_t
+#endif
+
+/* Define MPC version number */
+#define MPC_VERSION_MAJOR 1
+#define MPC_VERSION_MINOR 0
+#define MPC_VERSION_PATCHLEVEL 2
+#define MPC_VERSION_STRING "1.0.2"
+
+/* Macros dealing with MPC VERSION */
+#define MPC_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+#define MPC_VERSION \
+ MPC_VERSION_NUM(MPC_VERSION_MAJOR,MPC_VERSION_MINOR,MPC_VERSION_PATCHLEVEL)
+
+/* Check if stdint.h/inttypes.h is included */
+#if defined (INTMAX_C) && defined (UINTMAX_C)
+#define _MPC_H_HAVE_INTMAX_T 1
+#endif
+
+/* Return values */
+
+/* Transform negative to 2, positive to 1, leave 0 unchanged */
+#define MPC_INEX_POS(inex) (((inex) < 0) ? 2 : ((inex) == 0) ? 0 : 1)
+/* Transform 2 to negative, 1 to positive, leave 0 unchanged */
+#define MPC_INEX_NEG(inex) (((inex) == 2) ? -1 : ((inex) == 0) ? 0 : 1)
+
+/* The global inexact flag is made of (real flag) + 4 * (imaginary flag), where
+ each of the real and imaginary inexact flag are:
+ 0 when the result is exact (no rounding error)
+ 1 when the result is larger than the exact value
+ 2 when the result is smaller than the exact value */
+#define MPC_INEX(inex_re, inex_im) \
+ (MPC_INEX_POS(inex_re) | (MPC_INEX_POS(inex_im) << 2))
+#define MPC_INEX_RE(inex) MPC_INEX_NEG((inex) & 3)
+#define MPC_INEX_IM(inex) MPC_INEX_NEG((inex) >> 2)
+
+/* For functions computing two results, the return value is
+ inexact1+16*inexact2, which is 0 iif both results are exact. */
+#define MPC_INEX12(inex1, inex2) (inex1 | (inex2 << 4))
+#define MPC_INEX1(inex) (inex & 15)
+#define MPC_INEX2(inex) (inex >> 4)
+
+/* Definition of rounding modes */
+
+/* a complex rounding mode is just a pair of two real rounding modes
+ we reserve four bits for a real rounding mode. */
+typedef int mpc_rnd_t;
+
+#define MPC_RND(r1,r2) (((int)(r1)) + ((int)(r2) << 4))
+#define MPC_RND_RE(x) ((mpfr_rnd_t)((x) & 0x0F))
+#define MPC_RND_IM(x) ((mpfr_rnd_t)((x) >> 4))
+
+#define MPC_RNDNN MPC_RND (GMP_RNDN,GMP_RNDN)
+#define MPC_RNDNZ MPC_RND (GMP_RNDN,GMP_RNDZ)
+#define MPC_RNDNU MPC_RND (GMP_RNDN,GMP_RNDU)
+#define MPC_RNDND MPC_RND (GMP_RNDN,GMP_RNDD)
+
+#define MPC_RNDZN MPC_RND (GMP_RNDZ,GMP_RNDN)
+#define MPC_RNDZZ MPC_RND (GMP_RNDZ,GMP_RNDZ)
+#define MPC_RNDZU MPC_RND (GMP_RNDZ,GMP_RNDU)
+#define MPC_RNDZD MPC_RND (GMP_RNDZ,GMP_RNDD)
+
+#define MPC_RNDUN MPC_RND (GMP_RNDU,GMP_RNDN)
+#define MPC_RNDUZ MPC_RND (GMP_RNDU,GMP_RNDZ)
+#define MPC_RNDUU MPC_RND (GMP_RNDU,GMP_RNDU)
+#define MPC_RNDUD MPC_RND (GMP_RNDU,GMP_RNDD)
+
+#define MPC_RNDDN MPC_RND (GMP_RNDD,GMP_RNDN)
+#define MPC_RNDDZ MPC_RND (GMP_RNDD,GMP_RNDZ)
+#define MPC_RNDDU MPC_RND (GMP_RNDD,GMP_RNDU)
+#define MPC_RNDDD MPC_RND (GMP_RNDD,GMP_RNDD)
+
+
+/* Definitions of types and their semantics */
+
+typedef struct {
+ mpfr_t re;
+ mpfr_t im;
+}
+__mpc_struct;
+
+typedef __mpc_struct mpc_t[1];
+typedef __mpc_struct *mpc_ptr;
+typedef const __mpc_struct *mpc_srcptr;
+
+/* Support for WINDOWS DLL, see
+ http://lists.gforge.inria.fr/pipermail/mpc-discuss/2011-November/000990.html;
+ when building the DLL, export symbols, otherwise behave as GMP */
+#if defined (__MPC_LIBRARY_BUILD) && __GMP_LIBGMP_DLL
+#define __MPC_DECLSPEC __GMP_DECLSPEC_EXPORT
+#else
+#define __MPC_DECLSPEC __GMP_DECLSPEC
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+__MPC_DECLSPEC int mpc_add (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_add_fr (mpc_ptr, mpc_srcptr, mpfr_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_add_si (mpc_ptr, mpc_srcptr, long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_add_ui (mpc_ptr, mpc_srcptr, unsigned long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_sub (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_sub_fr (mpc_ptr, mpc_srcptr, mpfr_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_fr_sub (mpc_ptr, mpfr_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_sub_ui (mpc_ptr, mpc_srcptr, unsigned long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_ui_ui_sub (mpc_ptr, unsigned long int, unsigned long int, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_mul (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_mul_fr (mpc_ptr, mpc_srcptr, mpfr_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_mul_ui (mpc_ptr, mpc_srcptr, unsigned long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_mul_si (mpc_ptr, mpc_srcptr, long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_mul_i (mpc_ptr, mpc_srcptr, int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_sqr (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_div (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_pow (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_pow_fr (mpc_ptr, mpc_srcptr, mpfr_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_pow_ld (mpc_ptr, mpc_srcptr, long double, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_pow_d (mpc_ptr, mpc_srcptr, double, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_pow_si (mpc_ptr, mpc_srcptr, long, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_pow_ui (mpc_ptr, mpc_srcptr, unsigned long, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_pow_z (mpc_ptr, mpc_srcptr, mpz_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_div_fr (mpc_ptr, mpc_srcptr, mpfr_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_fr_div (mpc_ptr, mpfr_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_div_ui (mpc_ptr, mpc_srcptr, unsigned long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_ui_div (mpc_ptr, unsigned long int, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_div_2ui (mpc_ptr, mpc_srcptr, unsigned long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_mul_2ui (mpc_ptr, mpc_srcptr, unsigned long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_div_2si (mpc_ptr, mpc_srcptr, long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_mul_2si (mpc_ptr, mpc_srcptr, long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_conj (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_neg (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_norm (mpfr_ptr, mpc_srcptr, mpfr_rnd_t);
+__MPC_DECLSPEC int mpc_abs (mpfr_ptr, mpc_srcptr, mpfr_rnd_t);
+__MPC_DECLSPEC int mpc_sqrt (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_d (mpc_ptr, double, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_d_d (mpc_ptr, double, double, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_ld (mpc_ptr, long double, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_ld_ld (mpc_ptr, long double, long double, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_f (mpc_ptr, mpf_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_f_f (mpc_ptr, mpf_srcptr, mpf_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_fr (mpc_ptr, mpfr_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_fr_fr (mpc_ptr, mpfr_srcptr, mpfr_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_q (mpc_ptr, mpq_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_q_q (mpc_ptr, mpq_srcptr, mpq_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_si (mpc_ptr, long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_si_si (mpc_ptr, long int, long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_ui (mpc_ptr, unsigned long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_ui_ui (mpc_ptr, unsigned long int, unsigned long int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_z (mpc_ptr, mpz_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_z_z (mpc_ptr, mpz_srcptr, mpz_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC void mpc_swap (mpc_ptr, mpc_ptr);
+__MPC_DECLSPEC int mpc_fma (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+
+__MPC_DECLSPEC void mpc_set_nan (mpc_ptr);
+
+__MPC_DECLSPEC int mpc_real (mpfr_ptr, mpc_srcptr, mpfr_rnd_t);
+__MPC_DECLSPEC int mpc_imag (mpfr_ptr, mpc_srcptr, mpfr_rnd_t);
+__MPC_DECLSPEC int mpc_arg (mpfr_ptr, mpc_srcptr, mpfr_rnd_t);
+__MPC_DECLSPEC int mpc_proj (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_cmp (mpc_srcptr, mpc_srcptr);
+__MPC_DECLSPEC int mpc_cmp_si_si (mpc_srcptr, long int, long int);
+__MPC_DECLSPEC int mpc_exp (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_log (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_log10 (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_sin (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_cos (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_sin_cos (mpc_ptr, mpc_ptr, mpc_srcptr, mpc_rnd_t, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_tan (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_sinh (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_cosh (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_tanh (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_asin (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_acos (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_atan (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_asinh (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_acosh (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_atanh (mpc_ptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC void mpc_clear (mpc_ptr);
+__MPC_DECLSPEC int mpc_urandom (mpc_ptr, gmp_randstate_t);
+__MPC_DECLSPEC void mpc_init2 (mpc_ptr, mpfr_prec_t);
+__MPC_DECLSPEC void mpc_init3 (mpc_ptr, mpfr_prec_t, mpfr_prec_t);
+__MPC_DECLSPEC mpfr_prec_t mpc_get_prec (mpc_srcptr x);
+__MPC_DECLSPEC void mpc_get_prec2 (mpfr_prec_t *pr, mpfr_prec_t *pi, mpc_srcptr x);
+__MPC_DECLSPEC void mpc_set_prec (mpc_ptr, mpfr_prec_t);
+__MPC_DECLSPEC const char * mpc_get_version (void);
+
+__MPC_DECLSPEC int mpc_strtoc (mpc_ptr, const char *, char **, int, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_str (mpc_ptr, const char *, int, mpc_rnd_t);
+__MPC_DECLSPEC char * mpc_get_str (int, size_t, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC void mpc_free_str (char *);
+
+/* declare certain functions only if appropriate headers have been included */
+#ifdef _MPC_H_HAVE_INTMAX_T
+__MPC_DECLSPEC int mpc_set_sj (mpc_ptr, intmax_t, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_uj (mpc_ptr, uintmax_t, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_sj_sj (mpc_ptr, intmax_t, intmax_t, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_uj_uj (mpc_ptr, uintmax_t, uintmax_t, mpc_rnd_t);
+#endif
+
+#ifdef _Complex_I
+__MPC_DECLSPEC int mpc_set_dc (mpc_ptr, double _Complex, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_set_ldc (mpc_ptr, long double _Complex, mpc_rnd_t);
+__MPC_DECLSPEC double _Complex mpc_get_dc (mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC long double _Complex mpc_get_ldc (mpc_srcptr, mpc_rnd_t);
+#endif
+
+#ifdef _GMP_H_HAVE_FILE
+__MPC_DECLSPEC int mpc_inp_str (mpc_ptr, FILE *, size_t *, int, mpc_rnd_t);
+__MPC_DECLSPEC size_t mpc_out_str (FILE *, int, size_t, mpc_srcptr, mpc_rnd_t);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+#define mpc_realref(x) ((x)->re)
+#define mpc_imagref(x) ((x)->im)
+
+#define mpc_cmp_si(x, y) \
+ ( mpc_cmp_si_si ((x), (y), 0l) )
+#define mpc_ui_sub(x, y, z, r) mpc_ui_ui_sub (x, y, 0ul, z, r)
+
+/*
+ Define a fake mpfr_set_fr so that, for instance, mpc_set_fr_z would
+ be defined as follows:
+ mpc_set_fr_z (mpc_t rop, mpfr_t x, mpz_t y, mpc_rnd_t rnd)
+ MPC_SET_X_Y (fr, z, rop, x, y, rnd)
+*/
+#ifndef mpfr_set_fr
+#define mpfr_set_fr mpfr_set
+#endif
+#define MPC_SET_X_Y(real_t, imag_t, z, real_value, imag_value, rnd) \
+ { \
+ int _inex_re, _inex_im; \
+ _inex_re = (mpfr_set_ ## real_t) (mpc_realref (z), (real_value), MPC_RND_RE (rnd)); \
+ _inex_im = (mpfr_set_ ## imag_t) (mpc_imagref (z), (imag_value), MPC_RND_IM (rnd)); \
+ return MPC_INEX (_inex_re, _inex_im); \
+ }
+
+#endif /* ifndef __MPC_H */
diff --git a/mpc/src/mul.c b/mpc/src/mul.c
new file mode 100644
index 0000000000..2be9b8d646
--- /dev/null
+++ b/mpc/src/mul.c
@@ -0,0 +1,639 @@
+/* mpc_mul -- Multiply two complex numbers
+
+Copyright (C) 2002, 2004, 2005, 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for MPC_ASSERT */
+#include "mpc-impl.h"
+
+#define mpz_add_si(z,x,y) do { \
+ if (y >= 0) \
+ mpz_add_ui (z, x, (long int) y); \
+ else \
+ mpz_sub_ui (z, x, (long int) (-y)); \
+ } while (0);
+
+/* compute z=x*y when x has an infinite part */
+static int
+mul_infinite (mpc_ptr z, mpc_srcptr x, mpc_srcptr y)
+{
+ /* Let x=xr+i*xi and y=yr+i*yi; extract the signs of the operands */
+ int xrs = mpfr_signbit (mpc_realref (x)) ? -1 : 1;
+ int xis = mpfr_signbit (mpc_imagref (x)) ? -1 : 1;
+ int yrs = mpfr_signbit (mpc_realref (y)) ? -1 : 1;
+ int yis = mpfr_signbit (mpc_imagref (y)) ? -1 : 1;
+
+ int u, v;
+
+ /* compute the sign of
+ u = xrs * yrs * xr * yr - xis * yis * xi * yi
+ v = xrs * yis * xr * yi + xis * yrs * xi * yr
+ +1 if positive, -1 if negatiye, 0 if NaN */
+ if ( mpfr_nan_p (mpc_realref (x)) || mpfr_nan_p (mpc_imagref (x))
+ || mpfr_nan_p (mpc_realref (y)) || mpfr_nan_p (mpc_imagref (y))) {
+ u = 0;
+ v = 0;
+ }
+ else if (mpfr_inf_p (mpc_realref (x))) {
+ /* x = (+/-inf) xr + i*xi */
+ u = ( mpfr_zero_p (mpc_realref (y))
+ || (mpfr_inf_p (mpc_imagref (x)) && mpfr_zero_p (mpc_imagref (y)))
+ || (mpfr_zero_p (mpc_imagref (x)) && mpfr_inf_p (mpc_imagref (y)))
+ || ( (mpfr_inf_p (mpc_imagref (x)) || mpfr_inf_p (mpc_imagref (y)))
+ && xrs*yrs == xis*yis)
+ ? 0 : xrs * yrs);
+ v = ( mpfr_zero_p (mpc_imagref (y))
+ || (mpfr_inf_p (mpc_imagref (x)) && mpfr_zero_p (mpc_realref (y)))
+ || (mpfr_zero_p (mpc_imagref (x)) && mpfr_inf_p (mpc_realref (y)))
+ || ( (mpfr_inf_p (mpc_imagref (x)) || mpfr_inf_p (mpc_imagref (x)))
+ && xrs*yis != xis*yrs)
+ ? 0 : xrs * yis);
+ }
+ else {
+ /* x = xr + i*(+/-inf) with |xr| != inf */
+ u = ( mpfr_zero_p (mpc_imagref (y))
+ || (mpfr_zero_p (mpc_realref (x)) && mpfr_inf_p (mpc_realref (y)))
+ || (mpfr_inf_p (mpc_realref (y)) && xrs*yrs == xis*yis)
+ ? 0 : -xis * yis);
+ v = ( mpfr_zero_p (mpc_realref (y))
+ || (mpfr_zero_p (mpc_realref (x)) && mpfr_inf_p (mpc_imagref (y)))
+ || (mpfr_inf_p (mpc_imagref (y)) && xrs*yis != xis*yrs)
+ ? 0 : xis * yrs);
+ }
+
+ if (u == 0 && v == 0) {
+ /* Naive result is NaN+i*NaN. Obtain an infinity using the algorithm
+ given in Annex G.5.1 of the ISO C99 standard */
+ int xr = (mpfr_zero_p (mpc_realref (x)) || mpfr_nan_p (mpc_realref (x)) ? 0
+ : (mpfr_inf_p (mpc_realref (x)) ? 1 : 0));
+ int xi = (mpfr_zero_p (mpc_imagref (x)) || mpfr_nan_p (mpc_imagref (x)) ? 0
+ : (mpfr_inf_p (mpc_imagref (x)) ? 1 : 0));
+ int yr = (mpfr_zero_p (mpc_realref (y)) || mpfr_nan_p (mpc_realref (y)) ? 0 : 1);
+ int yi = (mpfr_zero_p (mpc_imagref (y)) || mpfr_nan_p (mpc_imagref (y)) ? 0 : 1);
+ if (mpc_inf_p (y)) {
+ yr = mpfr_inf_p (mpc_realref (y)) ? 1 : 0;
+ yi = mpfr_inf_p (mpc_imagref (y)) ? 1 : 0;
+ }
+
+ u = xrs * xr * yrs * yr - xis * xi * yis * yi;
+ v = xrs * xr * yis * yi + xis * xi * yrs * yr;
+ }
+
+ if (u == 0)
+ mpfr_set_nan (mpc_realref (z));
+ else
+ mpfr_set_inf (mpc_realref (z), u);
+
+ if (v == 0)
+ mpfr_set_nan (mpc_imagref (z));
+ else
+ mpfr_set_inf (mpc_imagref (z), v);
+
+ return MPC_INEX (0, 0); /* exact */
+}
+
+
+/* compute z = x*y for Im(y) == 0 */
+static int
+mul_real (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd)
+{
+ int xrs, xis, yrs, yis;
+ int inex;
+
+ /* save signs of operands */
+ xrs = MPFR_SIGNBIT (mpc_realref (x));
+ xis = MPFR_SIGNBIT (mpc_imagref (x));
+ yrs = MPFR_SIGNBIT (mpc_realref (y));
+ yis = MPFR_SIGNBIT (mpc_imagref (y));
+
+ inex = mpc_mul_fr (z, x, mpc_realref (y), rnd);
+ /* Signs of zeroes may be wrong. Their correction does not change the
+ inexact flag. */
+ if (mpfr_zero_p (mpc_realref (z)))
+ mpfr_setsign (mpc_realref (z), mpc_realref (z), MPC_RND_RE(rnd) == GMP_RNDD
+ || (xrs != yrs && xis == yis), GMP_RNDN);
+ if (mpfr_zero_p (mpc_imagref (z)))
+ mpfr_setsign (mpc_imagref (z), mpc_imagref (z), MPC_RND_IM (rnd) == GMP_RNDD
+ || (xrs != yis && xis != yrs), GMP_RNDN);
+
+ return inex;
+}
+
+
+/* compute z = x*y for Re(y) == 0, and Im(x) != 0 and Im(y) != 0 */
+static int
+mul_imag (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd)
+{
+ int sign;
+ int inex_re, inex_im;
+ int overlap = z == x || z == y;
+ mpc_t rop;
+
+ if (overlap)
+ mpc_init3 (rop, MPC_PREC_RE (z), MPC_PREC_IM (z));
+ else
+ rop [0] = z[0];
+
+ sign = (MPFR_SIGNBIT (mpc_realref (y)) != MPFR_SIGNBIT (mpc_imagref (x)))
+ && (MPFR_SIGNBIT (mpc_imagref (y)) != MPFR_SIGNBIT (mpc_realref (x)));
+
+ inex_re = -mpfr_mul (mpc_realref (rop), mpc_imagref (x), mpc_imagref (y),
+ INV_RND (MPC_RND_RE (rnd)));
+ mpfr_neg (mpc_realref (rop), mpc_realref (rop), GMP_RNDN); /* exact */
+ inex_im = mpfr_mul (mpc_imagref (rop), mpc_realref (x), mpc_imagref (y),
+ MPC_RND_IM (rnd));
+ mpc_set (z, rop, MPC_RNDNN);
+
+ /* Sign of zeroes may be wrong (note that Re(z) cannot be zero) */
+ if (mpfr_zero_p (mpc_imagref (z)))
+ mpfr_setsign (mpc_imagref (z), mpc_imagref (z), MPC_RND_IM (rnd) == GMP_RNDD
+ || sign, GMP_RNDN);
+
+ if (overlap)
+ mpc_clear (rop);
+
+ return MPC_INEX (inex_re, inex_im);
+}
+
+
+static int
+mpfr_fmma (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpfr_srcptr c,
+ mpfr_srcptr d, int sign, mpfr_rnd_t rnd)
+{
+ /* Computes z = ab+cd if sign >= 0, or z = ab-cd if sign < 0.
+ Assumes that a, b, c, d are finite and non-zero; so any multiplication
+ of two of them yielding an infinity is an overflow, and a
+ multiplication yielding 0 is an underflow.
+ Assumes further that z is distinct from a, b, c, d. */
+
+ int inex;
+ mpfr_t u, v;
+
+ /* u=a*b, v=sign*c*d exactly */
+ mpfr_init2 (u, mpfr_get_prec (a) + mpfr_get_prec (b));
+ mpfr_init2 (v, mpfr_get_prec (c) + mpfr_get_prec (d));
+ mpfr_mul (u, a, b, GMP_RNDN);
+ mpfr_mul (v, c, d, GMP_RNDN);
+ if (sign < 0)
+ mpfr_neg (v, v, GMP_RNDN);
+
+ /* tentatively compute z as u+v; here we need z to be distinct
+ from a, b, c, d to not lose the latter */
+ inex = mpfr_add (z, u, v, rnd);
+
+ if (mpfr_inf_p (z)) {
+ /* replace by "correctly rounded overflow" */
+ mpfr_set_si (z, (mpfr_signbit (z) ? -1 : 1), GMP_RNDN);
+ inex = mpfr_mul_2ui (z, z, mpfr_get_emax (), rnd);
+ }
+ else if (mpfr_zero_p (u) && !mpfr_zero_p (v)) {
+ /* exactly u underflowed, determine inexact flag */
+ inex = (mpfr_signbit (u) ? 1 : -1);
+ }
+ else if (mpfr_zero_p (v) && !mpfr_zero_p (u)) {
+ /* exactly v underflowed, determine inexact flag */
+ inex = (mpfr_signbit (v) ? 1 : -1);
+ }
+ else if (mpfr_nan_p (z) || (mpfr_zero_p (u) && mpfr_zero_p (v))) {
+ /* In the first case, u and v are infinities with opposite signs.
+ In the second case, u and v are zeroes; their sum may be 0 or the
+ least representable number, with a sign to be determined.
+ Redo the computations with mpz_t exponents */
+ mpfr_exp_t ea, eb, ec, ed;
+ mpz_t eu, ev;
+ /* cheat to work around the const qualifiers */
+
+ /* Normalise the input by shifting and keep track of the shifts in
+ the exponents of u and v */
+ ea = mpfr_get_exp (a);
+ eb = mpfr_get_exp (b);
+ ec = mpfr_get_exp (c);
+ ed = mpfr_get_exp (d);
+
+ mpfr_set_exp ((mpfr_ptr) a, (mpfr_prec_t) 0);
+ mpfr_set_exp ((mpfr_ptr) b, (mpfr_prec_t) 0);
+ mpfr_set_exp ((mpfr_ptr) c, (mpfr_prec_t) 0);
+ mpfr_set_exp ((mpfr_ptr) d, (mpfr_prec_t) 0);
+
+ mpz_init (eu);
+ mpz_init (ev);
+ mpz_set_si (eu, (long int) ea);
+ mpz_add_si (eu, eu, (long int) eb);
+ mpz_set_si (ev, (long int) ec);
+ mpz_add_si (ev, ev, (long int) ed);
+
+ /* recompute u and v and move exponents to eu and ev */
+ mpfr_mul (u, a, b, GMP_RNDN);
+ /* exponent of u is non-positive */
+ mpz_sub_ui (eu, eu, (unsigned long int) (-mpfr_get_exp (u)));
+ mpfr_set_exp (u, (mpfr_prec_t) 0);
+ mpfr_mul (v, c, d, GMP_RNDN);
+ if (sign < 0)
+ mpfr_neg (v, v, GMP_RNDN);
+ mpz_sub_ui (ev, ev, (unsigned long int) (-mpfr_get_exp (v)));
+ mpfr_set_exp (v, (mpfr_prec_t) 0);
+
+ if (mpfr_nan_p (z)) {
+ mpfr_exp_t emax = mpfr_get_emax ();
+ int overflow;
+ /* We have a = ma * 2^ea with 1/2 <= |ma| < 1 and ea <= emax, and
+ analogously for b. So eu <= 2*emax, and eu > emax since we have
+ an overflow. The same holds for ev. Shift u and v by as much as
+ possible so that one of them has exponent emax and the
+ remaining exponents in eu and ev are the same. Then carry out
+ the addition. Shifting u and v prevents an underflow. */
+ if (mpz_cmp (eu, ev) >= 0) {
+ mpfr_set_exp (u, emax);
+ mpz_sub_ui (eu, eu, (long int) emax);
+ mpz_sub (ev, ev, eu);
+ mpfr_set_exp (v, (mpfr_exp_t) mpz_get_ui (ev));
+ /* remaining common exponent is now in eu */
+ }
+ else {
+ mpfr_set_exp (v, emax);
+ mpz_sub_ui (ev, ev, (long int) emax);
+ mpz_sub (eu, eu, ev);
+ mpfr_set_exp (u, (mpfr_exp_t) mpz_get_ui (eu));
+ mpz_set (eu, ev);
+ /* remaining common exponent is now also in eu */
+ }
+ inex = mpfr_add (z, u, v, rnd);
+ /* Result is finite since u and v have different signs. */
+ overflow = mpfr_mul_2ui (z, z, mpz_get_ui (eu), rnd);
+ if (overflow)
+ inex = overflow;
+ }
+ else {
+ int underflow;
+ /* Addition of two zeroes with same sign. We have a = ma * 2^ea
+ with 1/2 <= |ma| < 1 and ea >= emin and similarly for b.
+ So 2*emin < 2*emin+1 <= eu < emin < 0, and analogously for v. */
+ mpfr_exp_t emin = mpfr_get_emin ();
+ if (mpz_cmp (eu, ev) <= 0) {
+ mpfr_set_exp (u, emin);
+ mpz_add_ui (eu, eu, (unsigned long int) (-emin));
+ mpz_sub (ev, ev, eu);
+ mpfr_set_exp (v, (mpfr_exp_t) mpz_get_si (ev));
+ }
+ else {
+ mpfr_set_exp (v, emin);
+ mpz_add_ui (ev, ev, (unsigned long int) (-emin));
+ mpz_sub (eu, eu, ev);
+ mpfr_set_exp (u, (mpfr_exp_t) mpz_get_si (eu));
+ mpz_set (eu, ev);
+ }
+ inex = mpfr_add (z, u, v, rnd);
+ mpz_neg (eu, eu);
+ underflow = mpfr_div_2ui (z, z, mpz_get_ui (eu), rnd);
+ if (underflow)
+ inex = underflow;
+ }
+
+ mpz_clear (eu);
+ mpz_clear (ev);
+
+ mpfr_set_exp ((mpfr_ptr) a, ea);
+ mpfr_set_exp ((mpfr_ptr) b, eb);
+ mpfr_set_exp ((mpfr_ptr) c, ec);
+ mpfr_set_exp ((mpfr_ptr) d, ed);
+ /* works also when some of a, b, c, d are not all distinct */
+ }
+
+ mpfr_clear (u);
+ mpfr_clear (v);
+
+ return inex;
+}
+
+
+int
+mpc_mul_naive (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd)
+{
+ /* computes z=x*y by the schoolbook method, where x and y are assumed
+ to be finite and without zero parts */
+ int overlap, inex;
+ mpc_t rop;
+
+ MPC_ASSERT ( mpfr_regular_p (mpc_realref (x)) && mpfr_regular_p (mpc_imagref (x))
+ && mpfr_regular_p (mpc_realref (y)) && mpfr_regular_p (mpc_imagref (y)));
+ overlap = (z == x) || (z == y);
+ if (overlap)
+ mpc_init3 (rop, MPC_PREC_RE (z), MPC_PREC_IM (z));
+ else
+ rop [0] = z [0];
+
+ inex = MPC_INEX (mpfr_fmma (mpc_realref (rop), mpc_realref (x), mpc_realref (y), mpc_imagref (x),
+ mpc_imagref (y), -1, MPC_RND_RE (rnd)),
+ mpfr_fmma (mpc_imagref (rop), mpc_realref (x), mpc_imagref (y), mpc_imagref (x),
+ mpc_realref (y), +1, MPC_RND_IM (rnd)));
+
+ mpc_set (z, rop, MPC_RNDNN);
+ if (overlap)
+ mpc_clear (rop);
+
+ return inex;
+}
+
+
+int
+mpc_mul_karatsuba (mpc_ptr rop, mpc_srcptr op1, mpc_srcptr op2, mpc_rnd_t rnd)
+{
+ /* computes rop=op1*op2 by a Karatsuba algorithm, where op1 and op2
+ are assumed to be finite and without zero parts */
+ mpfr_srcptr a, b, c, d;
+ int mul_i, ok, inexact, mul_a, mul_c, inex_re = 0, inex_im = 0, sign_x, sign_u;
+ mpfr_t u, v, w, x;
+ mpfr_prec_t prec, prec_re, prec_u, prec_v, prec_w;
+ mpfr_rnd_t rnd_re, rnd_u;
+ int overlap;
+ /* true if rop == op1 or rop == op2 */
+ mpc_t result;
+ /* overlap is quite difficult to handle, because we have to tentatively
+ round the variable u in the end to either the real or the imaginary
+ part of rop (it is not possible to tell now whether the real or
+ imaginary part is used). If this fails, we have to start again and
+ need the correct values of op1 and op2.
+ So we just create a new variable for the result in this case. */
+ int loop;
+ const int MAX_MUL_LOOP = 1;
+
+ overlap = (rop == op1) || (rop == op2);
+ if (overlap)
+ mpc_init3 (result, MPC_PREC_RE (rop), MPC_PREC_IM (rop));
+ else
+ result [0] = rop [0];
+
+ a = mpc_realref(op1);
+ b = mpc_imagref(op1);
+ c = mpc_realref(op2);
+ d = mpc_imagref(op2);
+
+ /* (a + i*b) * (c + i*d) = [ac - bd] + i*[ad + bc] */
+
+ mul_i = 0; /* number of multiplications by i */
+ mul_a = 1; /* implicit factor for a */
+ mul_c = 1; /* implicit factor for c */
+
+ if (mpfr_cmp_abs (a, b) < 0)
+ {
+ MPFR_SWAP (a, b);
+ mul_i ++;
+ mul_a = -1; /* consider i * (a+i*b) = -b + i*a */
+ }
+
+ if (mpfr_cmp_abs (c, d) < 0)
+ {
+ MPFR_SWAP (c, d);
+ mul_i ++;
+ mul_c = -1; /* consider -d + i*c instead of c + i*d */
+ }
+
+ /* find the precision and rounding mode for the new real part */
+ if (mul_i % 2)
+ {
+ prec_re = MPC_PREC_IM(rop);
+ rnd_re = MPC_RND_IM(rnd);
+ }
+ else /* mul_i = 0 or 2 */
+ {
+ prec_re = MPC_PREC_RE(rop);
+ rnd_re = MPC_RND_RE(rnd);
+ }
+
+ if (mul_i)
+ rnd_re = INV_RND(rnd_re);
+
+ /* now |a| >= |b| and |c| >= |d| */
+ prec = MPC_MAX_PREC(rop);
+
+ mpfr_init2 (v, prec_v = mpfr_get_prec (a) + mpfr_get_prec (d));
+ mpfr_init2 (w, prec_w = mpfr_get_prec (b) + mpfr_get_prec (c));
+ mpfr_init2 (u, 2);
+ mpfr_init2 (x, 2);
+
+ inexact = mpfr_mul (v, a, d, GMP_RNDN);
+ if (inexact) {
+ /* over- or underflow */
+ ok = 0;
+ goto clear;
+ }
+ if (mul_a == -1)
+ mpfr_neg (v, v, GMP_RNDN);
+
+ inexact = mpfr_mul (w, b, c, GMP_RNDN);
+ if (inexact) {
+ /* over- or underflow */
+ ok = 0;
+ goto clear;
+ }
+ if (mul_c == -1)
+ mpfr_neg (w, w, GMP_RNDN);
+
+ /* compute sign(v-w) */
+ sign_x = mpfr_cmp_abs (v, w);
+ if (sign_x > 0)
+ sign_x = 2 * mpfr_sgn (v) - mpfr_sgn (w);
+ else if (sign_x == 0)
+ sign_x = mpfr_sgn (v) - mpfr_sgn (w);
+ else
+ sign_x = mpfr_sgn (v) - 2 * mpfr_sgn (w);
+
+ sign_u = mul_a * mpfr_sgn (a) * mul_c * mpfr_sgn (c);
+
+ if (sign_x * sign_u < 0)
+ { /* swap inputs */
+ MPFR_SWAP (a, c);
+ MPFR_SWAP (b, d);
+ mpfr_swap (v, w);
+ { int tmp; tmp = mul_a; mul_a = mul_c; mul_c = tmp; }
+ sign_x = - sign_x;
+ }
+
+ /* now sign_x * sign_u >= 0 */
+ loop = 0;
+ do
+ {
+ loop++;
+ /* the following should give failures with prob. <= 1/prec */
+ prec += mpc_ceil_log2 (prec) + 3;
+
+ mpfr_set_prec (u, prec_u = prec);
+ mpfr_set_prec (x, prec);
+
+ /* first compute away(b +/- a) and store it in u */
+ inexact = (mul_a == -1 ?
+ ROUND_AWAY (mpfr_sub (u, b, a, MPFR_RNDA), u) :
+ ROUND_AWAY (mpfr_add (u, b, a, MPFR_RNDA), u));
+
+ /* then compute away(+/-c - d) and store it in x */
+ inexact |= (mul_c == -1 ?
+ ROUND_AWAY (mpfr_add (x, c, d, MPFR_RNDA), x) :
+ ROUND_AWAY (mpfr_sub (x, c, d, MPFR_RNDA), x));
+ if (mul_c == -1)
+ mpfr_neg (x, x, GMP_RNDN);
+
+ if (inexact == 0)
+ mpfr_prec_round (u, prec_u = 2 * prec, GMP_RNDN);
+
+ /* compute away(u*x) and store it in u */
+ inexact |= ROUND_AWAY (mpfr_mul (u, u, x, MPFR_RNDA), u);
+ /* (a+b)*(c-d) */
+
+ /* if all computations are exact up to here, it may be that
+ the real part is exact, thus we need if possible to
+ compute v - w exactly */
+ if (inexact == 0)
+ {
+ mpfr_prec_t prec_x;
+ /* v and w are different from 0, so mpfr_get_exp is safe to use */
+ prec_x = SAFE_ABS (mpfr_exp_t, mpfr_get_exp (v) - mpfr_get_exp (w))
+ + MPC_MAX (prec_v, prec_w) + 1;
+ /* +1 is necessary for a potential carry */
+ /* ensure we do not use a too large precision */
+ if (prec_x > prec_u)
+ prec_x = prec_u;
+ if (prec_x > prec)
+ mpfr_prec_round (x, prec_x, GMP_RNDN);
+ }
+
+ rnd_u = (sign_u > 0) ? GMP_RNDU : GMP_RNDD;
+ inexact |= mpfr_sub (x, v, w, rnd_u); /* ad - bc */
+
+ /* in case u=0, ensure that rnd_u rounds x away from zero */
+ if (mpfr_sgn (u) == 0)
+ rnd_u = (mpfr_sgn (x) > 0) ? GMP_RNDU : GMP_RNDD;
+ inexact |= mpfr_add (u, u, x, rnd_u); /* ac - bd */
+
+ ok = inexact == 0 ||
+ mpfr_can_round (u, prec_u - 3, rnd_u, GMP_RNDZ,
+ prec_re + (rnd_re == GMP_RNDN));
+ /* this ensures both we can round correctly and determine the correct
+ inexact flag (for rounding to nearest) */
+ }
+ while (!ok && loop <= MAX_MUL_LOOP);
+ /* after MAX_MUL_LOOP rounds, use mpc_naive instead */
+
+ if (ok) {
+ /* if inexact is zero, then u is exactly ac-bd, otherwise fix the sign
+ of the inexact flag for u, which was rounded away from ac-bd */
+ if (inexact != 0)
+ inexact = mpfr_sgn (u);
+
+ if (mul_i == 0)
+ {
+ inex_re = mpfr_set (mpc_realref(result), u, MPC_RND_RE(rnd));
+ if (inex_re == 0)
+ {
+ inex_re = inexact; /* u is rounded away from 0 */
+ inex_im = mpfr_add (mpc_imagref(result), v, w, MPC_RND_IM(rnd));
+ }
+ else
+ inex_im = mpfr_add (mpc_imagref(result), v, w, MPC_RND_IM(rnd));
+ }
+ else if (mul_i == 1) /* (x+i*y)/i = y - i*x */
+ {
+ inex_im = mpfr_neg (mpc_imagref(result), u, MPC_RND_IM(rnd));
+ if (inex_im == 0)
+ {
+ inex_im = -inexact; /* u is rounded away from 0 */
+ inex_re = mpfr_add (mpc_realref(result), v, w, MPC_RND_RE(rnd));
+ }
+ else
+ inex_re = mpfr_add (mpc_realref(result), v, w, MPC_RND_RE(rnd));
+ }
+ else /* mul_i = 2, z/i^2 = -z */
+ {
+ inex_re = mpfr_neg (mpc_realref(result), u, MPC_RND_RE(rnd));
+ if (inex_re == 0)
+ {
+ inex_re = -inexact; /* u is rounded away from 0 */
+ inex_im = -mpfr_add (mpc_imagref(result), v, w,
+ INV_RND(MPC_RND_IM(rnd)));
+ mpfr_neg (mpc_imagref(result), mpc_imagref(result), MPC_RND_IM(rnd));
+ }
+ else
+ {
+ inex_im = -mpfr_add (mpc_imagref(result), v, w,
+ INV_RND(MPC_RND_IM(rnd)));
+ mpfr_neg (mpc_imagref(result), mpc_imagref(result), MPC_RND_IM(rnd));
+ }
+ }
+
+ mpc_set (rop, result, MPC_RNDNN);
+ }
+
+clear:
+ mpfr_clear (u);
+ mpfr_clear (v);
+ mpfr_clear (w);
+ mpfr_clear (x);
+ if (overlap)
+ mpc_clear (result);
+
+ if (ok)
+ return MPC_INEX(inex_re, inex_im);
+ else
+ return mpc_mul_naive (rop, op1, op2, rnd);
+}
+
+
+int
+mpc_mul (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
+{
+ /* Conforming to ISO C99 standard (G.5.1 multiplicative operators),
+ infinities are treated specially if both parts are NaN when computed
+ naively. */
+ if (mpc_inf_p (b))
+ return mul_infinite (a, b, c);
+ if (mpc_inf_p (c))
+ return mul_infinite (a, c, b);
+
+ /* NaN contamination of both parts in result */
+ if (mpfr_nan_p (mpc_realref (b)) || mpfr_nan_p (mpc_imagref (b))
+ || mpfr_nan_p (mpc_realref (c)) || mpfr_nan_p (mpc_imagref (c))) {
+ mpfr_set_nan (mpc_realref (a));
+ mpfr_set_nan (mpc_imagref (a));
+ return MPC_INEX (0, 0);
+ }
+
+ /* check for real multiplication */
+ if (mpfr_zero_p (mpc_imagref (b)))
+ return mul_real (a, c, b, rnd);
+ if (mpfr_zero_p (mpc_imagref (c)))
+ return mul_real (a, b, c, rnd);
+
+ /* check for purely imaginary multiplication */
+ if (mpfr_zero_p (mpc_realref (b)))
+ return mul_imag (a, c, b, rnd);
+ if (mpfr_zero_p (mpc_realref (c)))
+ return mul_imag (a, b, c, rnd);
+
+ /* If the real and imaginary part of one argument have a very different */
+ /* exponent, it is not reasonable to use Karatsuba multiplication. */
+ if ( SAFE_ABS (mpfr_exp_t,
+ mpfr_get_exp (mpc_realref (b)) - mpfr_get_exp (mpc_imagref (b)))
+ > (mpfr_exp_t) MPC_MAX_PREC (b) / 2
+ || SAFE_ABS (mpfr_exp_t,
+ mpfr_get_exp (mpc_realref (c)) - mpfr_get_exp (mpc_imagref (c)))
+ > (mpfr_exp_t) MPC_MAX_PREC (c) / 2)
+ return mpc_mul_naive (a, b, c, rnd);
+ else
+ return ((MPC_MAX_PREC(a)
+ <= (mpfr_prec_t) MUL_KARATSUBA_THRESHOLD * BITS_PER_MP_LIMB)
+ ? mpc_mul_naive : mpc_mul_karatsuba) (a, b, c, rnd);
+}
diff --git a/mpc/src/mul_2si.c b/mpc/src/mul_2si.c
new file mode 100644
index 0000000000..14d0ca2516
--- /dev/null
+++ b/mpc/src/mul_2si.c
@@ -0,0 +1,32 @@
+/* mpc_mul_2si -- Multiply a complex number by 2^e.
+
+Copyright (C) 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_mul_2si (mpc_ptr a, mpc_srcptr b, long int c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_mul_2si (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_mul_2si (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/mul_2ui.c b/mpc/src/mul_2ui.c
new file mode 100644
index 0000000000..46aa788ec9
--- /dev/null
+++ b/mpc/src/mul_2ui.c
@@ -0,0 +1,32 @@
+/* mpc_mul_2ui -- Multiply a complex number by 2^e.
+
+Copyright (C) 2002, 2009, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_mul_2ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_mul_2ui (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_mul_2ui (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/mul_fr.c b/mpc/src/mul_fr.c
new file mode 100644
index 0000000000..bd3574d857
--- /dev/null
+++ b/mpc/src/mul_fr.c
@@ -0,0 +1,43 @@
+/* mpc_mul_fr -- Multiply a complex number by a floating-point number.
+
+Copyright (C) 2002, 2008, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_mul_fr (mpc_ptr a, mpc_srcptr b, mpfr_srcptr c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+ mpfr_t real;
+
+ if (c == mpc_realref (a))
+ /* We have to use a temporary variable. */
+ mpfr_init2 (real, MPC_PREC_RE (a));
+ else
+ real [0] = mpc_realref (a) [0];
+
+ inex_re = mpfr_mul (real, mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_mul (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
+ mpfr_set (mpc_realref (a), real, GMP_RNDN); /* exact */
+
+ if (c == mpc_realref (a))
+ mpfr_clear (real);
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/mul_i.c b/mpc/src/mul_i.c
new file mode 100644
index 0000000000..591b0c6d7f
--- /dev/null
+++ b/mpc/src/mul_i.c
@@ -0,0 +1,80 @@
+/* mpc_mul_i -- Multiply a complex number by plus or minus i.
+
+Copyright (C) 2005, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_mul_i (mpc_ptr a, mpc_srcptr b, int sign, mpc_rnd_t rnd)
+/* if sign is >= 0, multiply by i, otherwise by -i */
+{
+ int inex_re, inex_im;
+ mpfr_t tmp;
+
+ /* Treat the most probable case of compatible precisions first */
+ if ( MPC_PREC_RE (b) == MPC_PREC_IM (a)
+ && MPC_PREC_IM (b) == MPC_PREC_RE (a))
+ {
+ if (a == b)
+ mpfr_swap (mpc_realref (a), mpc_imagref (a));
+ else
+ {
+ mpfr_set (mpc_realref (a), mpc_imagref (b), GMP_RNDN);
+ mpfr_set (mpc_imagref (a), mpc_realref (b), GMP_RNDN);
+ }
+ if (sign >= 0)
+ MPFR_CHANGE_SIGN (mpc_realref (a));
+ else
+ MPFR_CHANGE_SIGN (mpc_imagref (a));
+ inex_re = 0;
+ inex_im = 0;
+ }
+ else
+ {
+ if (a == b)
+ {
+ mpfr_init2 (tmp, MPC_PREC_RE (a));
+ if (sign >= 0)
+ {
+ inex_re = mpfr_neg (tmp, mpc_imagref (b), MPC_RND_RE (rnd));
+ inex_im = mpfr_set (mpc_imagref (a), mpc_realref (b), MPC_RND_IM (rnd));
+ }
+ else
+ {
+ inex_re = mpfr_set (tmp, mpc_imagref (b), MPC_RND_RE (rnd));
+ inex_im = mpfr_neg (mpc_imagref (a), mpc_realref (b), MPC_RND_IM (rnd));
+ }
+ mpfr_clear (mpc_realref (a));
+ mpc_realref (a)[0] = tmp [0];
+ }
+ else
+ if (sign >= 0)
+ {
+ inex_re = mpfr_neg (mpc_realref (a), mpc_imagref (b), MPC_RND_RE (rnd));
+ inex_im = mpfr_set (mpc_imagref (a), mpc_realref (b), MPC_RND_IM (rnd));
+ }
+ else
+ {
+ inex_re = mpfr_set (mpc_realref (a), mpc_imagref (b), MPC_RND_RE (rnd));
+ inex_im = mpfr_neg (mpc_imagref (a), mpc_realref (b), MPC_RND_IM (rnd));
+ }
+ }
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/mul_si.c b/mpc/src/mul_si.c
new file mode 100644
index 0000000000..f539d8b075
--- /dev/null
+++ b/mpc/src/mul_si.c
@@ -0,0 +1,32 @@
+/* mpc_mul_si -- Multiply a complex number by a signed integer.
+
+Copyright (C) 2005, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_mul_si (mpc_ptr a, mpc_srcptr b, long int c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_mul_si (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_mul_si (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/mul_ui.c b/mpc/src/mul_ui.c
new file mode 100644
index 0000000000..922e4b3777
--- /dev/null
+++ b/mpc/src/mul_ui.c
@@ -0,0 +1,32 @@
+/* mpc_mul_ui -- Multiply a complex number by a nonnegative integer.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_mul_ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_mul_ui (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_mul_ui (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/neg.c b/mpc/src/neg.c
new file mode 100644
index 0000000000..2aae7ca4db
--- /dev/null
+++ b/mpc/src/neg.c
@@ -0,0 +1,32 @@
+/* mpc_neg -- Negate a complex number.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_neg (mpc_ptr a, mpc_srcptr b, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_neg (mpc_realref(a), mpc_realref(b), MPC_RND_RE(rnd));
+ inex_im = mpfr_neg (mpc_imagref(a), mpc_imagref(b), MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/norm.c b/mpc/src/norm.c
new file mode 100644
index 0000000000..ab413b6798
--- /dev/null
+++ b/mpc/src/norm.c
@@ -0,0 +1,182 @@
+/* mpc_norm -- Square of the norm of a complex number.
+
+Copyright (C) 2002, 2005, 2008, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for MPC_ASSERT */
+#include "mpc-impl.h"
+
+/* a <- norm(b) = b * conj(b)
+ (the rounding mode is mpfr_rnd_t here since we return an mpfr number) */
+int
+mpc_norm (mpfr_ptr a, mpc_srcptr b, mpfr_rnd_t rnd)
+{
+ int inexact;
+ int saved_underflow, saved_overflow;
+
+ /* handling of special values; consistent with abs in that
+ norm = abs^2; so norm (+-inf, xxx) = norm (xxx, +-inf) = +inf */
+ if (!mpc_fin_p (b))
+ return mpc_abs (a, b, rnd);
+ else if (mpfr_zero_p (mpc_realref (b))) {
+ if (mpfr_zero_p (mpc_imagref (b)))
+ return mpfr_set_ui (a, 0, rnd); /* +0 */
+ else
+ return mpfr_sqr (a, mpc_imagref (b), rnd);
+ }
+ else if (mpfr_zero_p (mpc_imagref (b)))
+ return mpfr_sqr (a, mpc_realref (b), rnd); /* Re(b) <> 0 */
+
+ else /* everything finite and non-zero */ {
+ mpfr_t u, v, res;
+ mpfr_prec_t prec, prec_u, prec_v;
+ int loops;
+ const int max_loops = 2;
+ /* switch to exact squarings when loops==max_loops */
+
+ prec = mpfr_get_prec (a);
+
+ mpfr_init (u);
+ mpfr_init (v);
+ mpfr_init (res);
+
+ /* save the underflow or overflow flags from MPFR */
+ saved_underflow = mpfr_underflow_p ();
+ saved_overflow = mpfr_overflow_p ();
+
+ loops = 0;
+ mpfr_clear_underflow ();
+ mpfr_clear_overflow ();
+ do {
+ loops++;
+ prec += mpc_ceil_log2 (prec) + 3;
+ if (loops >= max_loops) {
+ prec_u = 2 * MPC_PREC_RE (b);
+ prec_v = 2 * MPC_PREC_IM (b);
+ }
+ else {
+ prec_u = MPC_MIN (prec, 2 * MPC_PREC_RE (b));
+ prec_v = MPC_MIN (prec, 2 * MPC_PREC_IM (b));
+ }
+
+ mpfr_set_prec (u, prec_u);
+ mpfr_set_prec (v, prec_v);
+
+ inexact = mpfr_sqr (u, mpc_realref(b), GMP_RNDD); /* err <= 1 ulp in prec */
+ inexact |= mpfr_sqr (v, mpc_imagref(b), GMP_RNDD); /* err <= 1 ulp in prec */
+
+ /* If loops = max_loops, inexact should be 0 here, except in case
+ of underflow or overflow.
+ If loops < max_loops and inexact is zero, we can exit the
+ while-loop since it only remains to add u and v into a. */
+ if (inexact) {
+ mpfr_set_prec (res, prec);
+ mpfr_add (res, u, v, GMP_RNDD); /* err <= 3 ulp in prec */
+ }
+
+ } while (loops < max_loops && inexact != 0
+ && !mpfr_can_round (res, prec - 2, GMP_RNDD, GMP_RNDU,
+ mpfr_get_prec (a) + (rnd == GMP_RNDN)));
+
+ if (!inexact)
+ /* squarings were exact, neither underflow nor overflow */
+ inexact = mpfr_add (a, u, v, rnd);
+ /* if there was an overflow in Re(b)^2 or Im(b)^2 or their sum,
+ since the norm is larger, there is an overflow for the norm */
+ else if (mpfr_overflow_p ()) {
+ /* replace by "correctly rounded overflow" */
+ mpfr_set_ui (a, 1ul, GMP_RNDN);
+ inexact = mpfr_mul_2ui (a, a, mpfr_get_emax (), rnd);
+ }
+ else if (mpfr_underflow_p ()) {
+ /* necessarily one of the squarings did underflow (otherwise their
+ sum could not underflow), thus one of u, v is zero. */
+ mpfr_exp_t emin = mpfr_get_emin ();
+
+ /* Now either both u and v are zero, or u is zero and v exact,
+ or v is zero and u exact.
+ In the latter case, Im(b)^2 < 2^(emin-1).
+ If ulp(u) >= 2^(emin+1) and norm(b) is not exactly
+ representable at the target precision, then rounding u+Im(b)^2
+ is equivalent to rounding u+2^(emin-1).
+ For instance, if exp(u)>0 and the target precision is smaller
+ than about |emin|, the norm is not representable. To make the
+ scaling in the "else" case work without underflow, we test
+ whether exp(u) is larger than a small negative number instead.
+ The second case is handled analogously. */
+ if (!mpfr_zero_p (u)
+ && mpfr_get_exp (u) - 2 * (mpfr_exp_t) prec_u > emin
+ && mpfr_get_exp (u) > -10) {
+ mpfr_set_prec (v, MPFR_PREC_MIN);
+ mpfr_set_ui_2exp (v, 1, emin - 1, GMP_RNDZ);
+ inexact = mpfr_add (a, u, v, rnd);
+ }
+ else if (!mpfr_zero_p (v)
+ && mpfr_get_exp (v) - 2 * (mpfr_exp_t) prec_v > emin
+ && mpfr_get_exp (v) > -10) {
+ mpfr_set_prec (u, MPFR_PREC_MIN);
+ mpfr_set_ui_2exp (u, 1, emin - 1, GMP_RNDZ);
+ inexact = mpfr_add (a, u, v, rnd);
+ }
+ else {
+ unsigned long int scale, exp_re, exp_im;
+ int inex_underflow;
+
+ /* scale the input to an average exponent close to 0 */
+ exp_re = (unsigned long int) (-mpfr_get_exp (mpc_realref (b)));
+ exp_im = (unsigned long int) (-mpfr_get_exp (mpc_imagref (b)));
+ scale = exp_re / 2 + exp_im / 2 + (exp_re % 2 + exp_im % 2) / 2;
+ /* (exp_re + exp_im) / 2, computed in a way avoiding
+ integer overflow */
+ if (mpfr_zero_p (u)) {
+ /* recompute the scaled value exactly */
+ mpfr_mul_2ui (u, mpc_realref (b), scale, GMP_RNDN);
+ mpfr_sqr (u, u, GMP_RNDN);
+ }
+ else /* just scale */
+ mpfr_mul_2ui (u, u, 2*scale, GMP_RNDN);
+ if (mpfr_zero_p (v)) {
+ mpfr_mul_2ui (v, mpc_imagref (b), scale, GMP_RNDN);
+ mpfr_sqr (v, v, GMP_RNDN);
+ }
+ else
+ mpfr_mul_2ui (v, v, 2*scale, GMP_RNDN);
+
+ inexact = mpfr_add (a, u, v, rnd);
+ mpfr_clear_underflow ();
+ inex_underflow = mpfr_div_2ui (a, a, 2*scale, rnd);
+ if (mpfr_underflow_p ())
+ inexact = inex_underflow;
+ }
+ }
+ else /* no problems, ternary value due to mpfr_can_round trick */
+ inexact = mpfr_set (a, res, rnd);
+
+ /* restore underflow and overflow flags from MPFR */
+ if (saved_underflow)
+ mpfr_set_underflow ();
+ if (saved_overflow)
+ mpfr_set_overflow ();
+
+ mpfr_clear (u);
+ mpfr_clear (v);
+ mpfr_clear (res);
+ }
+
+ return inexact;
+}
diff --git a/mpc/src/out_str.c b/mpc/src/out_str.c
new file mode 100644
index 0000000000..87cc823308
--- /dev/null
+++ b/mpc/src/out_str.c
@@ -0,0 +1,39 @@
+/* mpc_out_str -- Output a complex number on a given stream.
+
+Copyright (C) 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for FILE */
+#include <ctype.h>
+#include "mpc-impl.h"
+
+size_t
+mpc_out_str (FILE *stream, int base, size_t n, mpc_srcptr op, mpc_rnd_t rnd) {
+ size_t size = 3; /* for '(', ' ' and ')' */
+
+ if (stream == NULL)
+ stream = stdout; /* fprintf does not allow NULL as first argument */
+
+ fprintf (stream, "(");
+ size += mpfr_out_str (stream, base, n, mpc_realref(op), MPC_RND_RE(rnd));
+ fprintf (stream, " ");
+ size += mpfr_out_str (stream, base, n, mpc_imagref(op), MPC_RND_RE(rnd));
+ fprintf (stream, ")");
+
+ return size;
+}
diff --git a/mpc/src/pow.c b/mpc/src/pow.c
new file mode 100644
index 0000000000..892f467c57
--- /dev/null
+++ b/mpc/src/pow.c
@@ -0,0 +1,819 @@
+/* mpc_pow -- Raise a complex number to the power of another complex number.
+
+Copyright (C) 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for MPC_ASSERT */
+#include "mpc-impl.h"
+
+/* Return non-zero iff c+i*d is an exact square (a+i*b)^2,
+ with a, b both of the form m*2^e with m, e integers.
+ If so, returns in a+i*b the corresponding square root, with a >= 0.
+ The variables a, b must not overlap with c, d.
+
+ We have c = a^2 - b^2 and d = 2*a*b.
+
+ If one of a, b is exact, then both are (see algorithms.tex).
+
+ Case 1: a <> 0 and b <> 0.
+ Let a = m*2^e and b = n*2^f with m, e, n, f integers, m and n odd
+ (we will treat apart the case a = 0 or b = 0).
+ Then 2*a*b = m*n*2^(e+f+1), thus necessarily e+f >= -1.
+ Assume e < 0, then f >= 0, then a^2 - b^2 = m^2*2^(2e) - n^2*2^(2f) cannot
+ be an integer, since n^2*2^(2f) is an integer, and m^2*2^(2e) is not.
+ Similarly when f < 0 (and thus e >= 0).
+ Thus we have e, f >= 0, and a, b are both integers.
+ Let A = 2a^2, then eliminating b between c = a^2 - b^2 and d = 2*a*b
+ gives A^2 - 2c*A - d^2 = 0, which has solutions c +/- sqrt(c^2+d^2).
+ We thus need c^2+d^2 to be a square, and c + sqrt(c^2+d^2) --- the solution
+ we are interested in --- to be two times a square. Then b = d/(2a) is
+ necessarily an integer.
+
+ Case 2: a = 0. Then d is necessarily zero, thus it suffices to check
+ whether c = -b^2, i.e., if -c is a square.
+
+ Case 3: b = 0. Then d is necessarily zero, thus it suffices to check
+ whether c = a^2, i.e., if c is a square.
+*/
+static int
+mpc_perfect_square_p (mpz_t a, mpz_t b, mpz_t c, mpz_t d)
+{
+ if (mpz_cmp_ui (d, 0) == 0) /* case a = 0 or b = 0 */
+ {
+ /* necessarily c < 0 here, since we have already considered the case
+ where x is real non-negative and y is real */
+ MPC_ASSERT (mpz_cmp_ui (c, 0) < 0);
+ mpz_neg (b, c);
+ if (mpz_perfect_square_p (b)) /* case 2 above */
+ {
+ mpz_sqrt (b, b);
+ mpz_set_ui (a, 0);
+ return 1; /* c + i*d = (0 + i*b)^2 */
+ }
+ }
+ else /* both a and b are non-zero */
+ {
+ if (mpz_divisible_2exp_p (d, 1) == 0)
+ return 0; /* d must be even */
+ mpz_mul (a, c, c);
+ mpz_addmul (a, d, d); /* c^2 + d^2 */
+ if (mpz_perfect_square_p (a))
+ {
+ mpz_sqrt (a, a);
+ mpz_add (a, c, a); /* c + sqrt(c^2+d^2) */
+ if (mpz_divisible_2exp_p (a, 1))
+ {
+ mpz_tdiv_q_2exp (a, a, 1);
+ if (mpz_perfect_square_p (a))
+ {
+ mpz_sqrt (a, a);
+ mpz_tdiv_q_2exp (b, d, 1); /* d/2 */
+ mpz_divexact (b, b, a); /* d/(2a) */
+ return 1;
+ }
+ }
+ }
+ }
+ return 0; /* not a square */
+}
+
+/* fix the sign of Re(z) or Im(z) in case it is zero,
+ and Re(x) is zero.
+ sign_eps is 0 if Re(x) = +0, 1 if Re(x) = -0
+ sign_a is the sign bit of Im(x).
+ Assume y is an integer (does nothing otherwise).
+*/
+static void
+fix_sign (mpc_ptr z, int sign_eps, int sign_a, mpfr_srcptr y)
+{
+ int ymod4 = -1;
+ mpfr_exp_t ey;
+ mpz_t my;
+ unsigned long int t;
+
+ mpz_init (my);
+
+ ey = mpfr_get_z_exp (my, y);
+ /* normalize so that my is odd */
+ t = mpz_scan1 (my, 0);
+ ey += (mpfr_exp_t) t;
+ mpz_tdiv_q_2exp (my, my, t);
+ /* y = my*2^ey */
+
+ /* compute y mod 4 (in case y is an integer) */
+ if (ey >= 2)
+ ymod4 = 0;
+ else if (ey == 1)
+ ymod4 = mpz_tstbit (my, 0) * 2; /* correct if my < 0 */
+ else if (ey == 0)
+ {
+ ymod4 = mpz_tstbit (my, 1) * 2 + mpz_tstbit (my, 0);
+ if (mpz_cmp_ui (my , 0) < 0)
+ ymod4 = 4 - ymod4;
+ }
+ else /* y is not an integer */
+ goto end;
+
+ if (mpfr_zero_p (mpc_realref(z)))
+ {
+ /* we assume y is always integer in that case (FIXME: prove it):
+ (eps+I*a)^y = +0 + I*a^y for y = 1 mod 4 and sign_eps = 0
+ (eps+I*a)^y = -0 - I*a^y for y = 3 mod 4 and sign_eps = 0 */
+ MPC_ASSERT (ymod4 == 1 || ymod4 == 3);
+ if ((ymod4 == 3 && sign_eps == 0) ||
+ (ymod4 == 1 && sign_eps == 1))
+ mpfr_neg (mpc_realref(z), mpc_realref(z), GMP_RNDZ);
+ }
+ else if (mpfr_zero_p (mpc_imagref(z)))
+ {
+ /* we assume y is always integer in that case (FIXME: prove it):
+ (eps+I*a)^y = a^y - 0*I for y = 0 mod 4 and sign_a = sign_eps
+ (eps+I*a)^y = -a^y +0*I for y = 2 mod 4 and sign_a = sign_eps */
+ MPC_ASSERT (ymod4 == 0 || ymod4 == 2);
+ if ((ymod4 == 0 && sign_a == sign_eps) ||
+ (ymod4 == 2 && sign_a != sign_eps))
+ mpfr_neg (mpc_imagref(z), mpc_imagref(z), GMP_RNDZ);
+ }
+
+ end:
+ mpz_clear (my);
+}
+
+/* If x^y is exactly representable (with maybe a larger precision than z),
+ round it in z and return the (mpc) inexact flag in [0, 10].
+
+ If x^y is not exactly representable, return -1.
+
+ If intermediate computations lead to numbers of more than maxprec bits,
+ then abort and return -2 (in that case, to avoid loops, mpc_pow_exact
+ should be called again with a larger value of maxprec).
+
+ Assume one of Re(x) or Im(x) is non-zero, and y is non-zero (y is real).
+
+ Warning: z and x might be the same variable, same for Re(z) or Im(z) and y.
+
+ In case -1 or -2 is returned, z is not modified.
+*/
+static int
+mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd,
+ mpfr_prec_t maxprec)
+{
+ mpfr_exp_t ec, ed, ey;
+ mpz_t my, a, b, c, d, u;
+ unsigned long int t;
+ int ret = -2;
+ int sign_rex = mpfr_signbit (mpc_realref(x));
+ int sign_imx = mpfr_signbit (mpc_imagref(x));
+ int x_imag = mpfr_zero_p (mpc_realref(x));
+ int z_is_y = 0;
+ mpfr_t copy_of_y;
+
+ if (mpc_realref (z) == y || mpc_imagref (z) == y)
+ {
+ z_is_y = 1;
+ mpfr_init2 (copy_of_y, mpfr_get_prec (y));
+ mpfr_set (copy_of_y, y, GMP_RNDN);
+ }
+
+ mpz_init (my);
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (c);
+ mpz_init (d);
+ mpz_init (u);
+
+ ey = mpfr_get_z_exp (my, y);
+ /* normalize so that my is odd */
+ t = mpz_scan1 (my, 0);
+ ey += (mpfr_exp_t) t;
+ mpz_tdiv_q_2exp (my, my, t);
+ /* y = my*2^ey with my odd */
+
+ if (x_imag)
+ {
+ mpz_set_ui (c, 0);
+ ec = 0;
+ }
+ else
+ ec = mpfr_get_z_exp (c, mpc_realref(x));
+ if (mpfr_zero_p (mpc_imagref(x)))
+ {
+ mpz_set_ui (d, 0);
+ ed = ec;
+ }
+ else
+ {
+ ed = mpfr_get_z_exp (d, mpc_imagref(x));
+ if (x_imag)
+ ec = ed;
+ }
+ /* x = c*2^ec + I * d*2^ed */
+ /* equalize the exponents of x */
+ if (ec < ed)
+ {
+ mpz_mul_2exp (d, d, (unsigned long int) (ed - ec));
+ if ((mpfr_prec_t) mpz_sizeinbase (d, 2) > maxprec)
+ goto end;
+ }
+ else if (ed < ec)
+ {
+ mpz_mul_2exp (c, c, (unsigned long int) (ec - ed));
+ if ((mpfr_prec_t) mpz_sizeinbase (c, 2) > maxprec)
+ goto end;
+ ec = ed;
+ }
+ /* now ec=ed and x = (c + I * d) * 2^ec */
+
+ /* divide by two if possible */
+ if (mpz_cmp_ui (c, 0) == 0)
+ {
+ t = mpz_scan1 (d, 0);
+ mpz_tdiv_q_2exp (d, d, t);
+ ec += (mpfr_exp_t) t;
+ }
+ else if (mpz_cmp_ui (d, 0) == 0)
+ {
+ t = mpz_scan1 (c, 0);
+ mpz_tdiv_q_2exp (c, c, t);
+ ec += (mpfr_exp_t) t;
+ }
+ else /* neither c nor d is zero */
+ {
+ unsigned long v;
+ t = mpz_scan1 (c, 0);
+ v = mpz_scan1 (d, 0);
+ if (v < t)
+ t = v;
+ mpz_tdiv_q_2exp (c, c, t);
+ mpz_tdiv_q_2exp (d, d, t);
+ ec += (mpfr_exp_t) t;
+ }
+
+ /* now either one of c, d is odd */
+
+ while (ey < 0)
+ {
+ /* check if x is a square */
+ if (ec & 1)
+ {
+ mpz_mul_2exp (c, c, 1);
+ mpz_mul_2exp (d, d, 1);
+ ec --;
+ }
+ /* now ec is even */
+ if (mpc_perfect_square_p (a, b, c, d) == 0)
+ break;
+ mpz_swap (a, c);
+ mpz_swap (b, d);
+ ec /= 2;
+ ey ++;
+ }
+
+ if (ey < 0)
+ {
+ ret = -1; /* not representable */
+ goto end;
+ }
+
+ /* Now ey >= 0, it thus suffices to check that x^my is representable.
+ If my > 0, this is always true. If my < 0, we first try to invert
+ (c+I*d)*2^ec.
+ */
+ if (mpz_cmp_ui (my, 0) < 0)
+ {
+ /* If my < 0, 1 / (c + I*d) = (c - I*d)/(c^2 + d^2), thus a sufficient
+ condition is that c^2 + d^2 is a power of two, assuming |c| <> |d|.
+ Assume a prime p <> 2 divides c^2 + d^2,
+ then if p does not divide c or d, 1 / (c + I*d) cannot be exact.
+ If p divides both c and d, then we can write c = p*c', d = p*d',
+ and 1 / (c + I*d) = 1/p * 1/(c' + I*d'). This shows that if 1/(c+I*d)
+ is exact, then 1/(c' + I*d') is exact too, and we are back to the
+ previous case. In conclusion, a necessary and sufficient condition
+ is that c^2 + d^2 is a power of two.
+ */
+ /* FIXME: we could first compute c^2+d^2 mod a limb for example */
+ mpz_mul (a, c, c);
+ mpz_addmul (a, d, d);
+ t = mpz_scan1 (a, 0);
+ if (mpz_sizeinbase (a, 2) != 1 + t) /* a is not a power of two */
+ {
+ ret = -1; /* not representable */
+ goto end;
+ }
+ /* replace (c,d) by (c/(c^2+d^2), -d/(c^2+d^2)) */
+ mpz_neg (d, d);
+ ec = -ec - (mpfr_exp_t) t;
+ mpz_neg (my, my);
+ }
+
+ /* now ey >= 0 and my >= 0, and we want to compute
+ [(c + I * d) * 2^ec] ^ (my * 2^ey).
+
+ We first compute [(c + I * d) * 2^ec]^my, then square ey times. */
+ t = mpz_sizeinbase (my, 2) - 1;
+ mpz_set (a, c);
+ mpz_set (b, d);
+ ed = ec;
+ /* invariant: (a + I*b) * 2^ed = ((c + I*d) * 2^ec)^trunc(my/2^t) */
+ while (t-- > 0)
+ {
+ unsigned long int v, w;
+ /* square a + I*b */
+ mpz_mul (u, a, b);
+ mpz_mul (a, a, a);
+ mpz_submul (a, b, b);
+ mpz_mul_2exp (b, u, 1);
+ ed *= 2;
+ if (mpz_tstbit (my, t)) /* multiply by c + I*d */
+ {
+ mpz_mul (u, a, c);
+ mpz_submul (u, b, d); /* ac-bd */
+ mpz_mul (b, b, c);
+ mpz_addmul (b, a, d); /* bc+ad */
+ mpz_swap (a, u);
+ ed += ec;
+ }
+ /* remove powers of two in (a,b) */
+ if (mpz_cmp_ui (a, 0) == 0)
+ {
+ w = mpz_scan1 (b, 0);
+ mpz_tdiv_q_2exp (b, b, w);
+ ed += (mpfr_exp_t) w;
+ }
+ else if (mpz_cmp_ui (b, 0) == 0)
+ {
+ w = mpz_scan1 (a, 0);
+ mpz_tdiv_q_2exp (a, a, w);
+ ed += (mpfr_exp_t) w;
+ }
+ else
+ {
+ w = mpz_scan1 (a, 0);
+ v = mpz_scan1 (b, 0);
+ if (v < w)
+ w = v;
+ mpz_tdiv_q_2exp (a, a, w);
+ mpz_tdiv_q_2exp (b, b, w);
+ ed += (mpfr_exp_t) w;
+ }
+ if ( (mpfr_prec_t) mpz_sizeinbase (a, 2) > maxprec
+ || (mpfr_prec_t) mpz_sizeinbase (b, 2) > maxprec)
+ goto end;
+ }
+ /* now a+I*b = (c+I*d)^my */
+
+ while (ey-- > 0)
+ {
+ unsigned long sa, sb;
+
+ /* square a + I*b */
+ mpz_mul (u, a, b);
+ mpz_mul (a, a, a);
+ mpz_submul (a, b, b);
+ mpz_mul_2exp (b, u, 1);
+ ed *= 2;
+
+ /* divide by largest 2^n possible, to avoid many loops for e.g.,
+ (2+2*I)^16777216 */
+ sa = mpz_scan1 (a, 0);
+ sb = mpz_scan1 (b, 0);
+ sa = (sa <= sb) ? sa : sb;
+ mpz_tdiv_q_2exp (a, a, sa);
+ mpz_tdiv_q_2exp (b, b, sa);
+ ed += (mpfr_exp_t) sa;
+
+ if ( (mpfr_prec_t) mpz_sizeinbase (a, 2) > maxprec
+ || (mpfr_prec_t) mpz_sizeinbase (b, 2) > maxprec)
+ goto end;
+ }
+
+ ret = mpfr_set_z (mpc_realref(z), a, MPC_RND_RE(rnd));
+ ret = MPC_INEX(ret, mpfr_set_z (mpc_imagref(z), b, MPC_RND_IM(rnd)));
+ mpfr_mul_2si (mpc_realref(z), mpc_realref(z), ed, MPC_RND_RE(rnd));
+ mpfr_mul_2si (mpc_imagref(z), mpc_imagref(z), ed, MPC_RND_IM(rnd));
+
+ end:
+ mpz_clear (my);
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (c);
+ mpz_clear (d);
+ mpz_clear (u);
+
+ if (ret >= 0 && x_imag)
+ fix_sign (z, sign_rex, sign_imx, (z_is_y) ? copy_of_y : y);
+
+ if (z_is_y)
+ mpfr_clear (copy_of_y);
+
+ return ret;
+}
+
+/* Return 1 if y*2^k is an odd integer, 0 otherwise.
+ Adapted from MPFR, file pow.c.
+
+ Examples: with k=0, check if y is an odd integer,
+ with k=1, check if y is half-an-integer,
+ with k=-1, check if y/2 is an odd integer.
+*/
+#define MPFR_LIMB_HIGHBIT ((mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1))
+static int
+is_odd (mpfr_srcptr y, mpfr_exp_t k)
+{
+ mpfr_exp_t expo;
+ mpfr_prec_t prec;
+ mp_size_t yn;
+ mp_limb_t *yp;
+
+ expo = mpfr_get_exp (y) + k;
+ if (expo <= 0)
+ return 0; /* |y| < 1 and not 0 */
+
+ prec = mpfr_get_prec (y);
+ if ((mpfr_prec_t) expo > prec)
+ return 0; /* y is a multiple of 2^(expo-prec), thus not odd */
+
+ /* 0 < expo <= prec:
+ y = 1xxxxxxxxxt.zzzzzzzzzzzzzzzzzz[000]
+ expo bits (prec-expo) bits
+
+ We have to check that:
+ (a) the bit 't' is set
+ (b) all the 'z' bits are zero
+ */
+
+ prec = ((prec - 1) / BITS_PER_MP_LIMB + 1) * BITS_PER_MP_LIMB - expo;
+ /* number of z+0 bits */
+
+ yn = prec / BITS_PER_MP_LIMB;
+ /* yn is the index of limb containing the 't' bit */
+
+ yp = y->_mpfr_d;
+ /* if expo is a multiple of BITS_PER_MP_LIMB, t is bit 0 */
+ if (expo % BITS_PER_MP_LIMB == 0 ? (yp[yn] & 1) == 0
+ : yp[yn] << ((expo % BITS_PER_MP_LIMB) - 1) != MPFR_LIMB_HIGHBIT)
+ return 0;
+ while (--yn >= 0)
+ if (yp[yn] != 0)
+ return 0;
+ return 1;
+}
+
+/* Put in z the value of x^y, rounded according to 'rnd'.
+ Return the inexact flag in [0, 10]. */
+int
+mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd)
+{
+ int ret = -2, loop, x_real, x_imag, y_real, z_real = 0, z_imag = 0;
+ mpc_t t, u;
+ mpfr_prec_t p, pr, pi, maxprec;
+ int saved_underflow, saved_overflow;
+
+ /* save the underflow or overflow flags from MPFR */
+ saved_underflow = mpfr_underflow_p ();
+ saved_overflow = mpfr_overflow_p ();
+
+ x_real = mpfr_zero_p (mpc_imagref(x));
+ y_real = mpfr_zero_p (mpc_imagref(y));
+
+ if (y_real && mpfr_zero_p (mpc_realref(y))) /* case y zero */
+ {
+ if (x_real && mpfr_zero_p (mpc_realref(x)))
+ {
+ /* we define 0^0 to be (1, +0) since the real part is
+ coherent with MPFR where 0^0 gives 1, and the sign of the
+ imaginary part cannot be determined */
+ mpc_set_ui_ui (z, 1, 0, MPC_RNDNN);
+ return 0;
+ }
+ else /* x^0 = 1 +/- i*0 even for x=NaN see algorithms.tex for the
+ sign of zero */
+ {
+ mpfr_t n;
+ int inex, cx1;
+ int sign_zi;
+ /* cx1 < 0 if |x| < 1
+ cx1 = 0 if |x| = 1
+ cx1 > 0 if |x| > 1
+ */
+ mpfr_init (n);
+ inex = mpc_norm (n, x, GMP_RNDN);
+ cx1 = mpfr_cmp_ui (n, 1);
+ if (cx1 == 0 && inex != 0)
+ cx1 = -inex;
+
+ sign_zi = (cx1 < 0 && mpfr_signbit (mpc_imagref (y)) == 0)
+ || (cx1 == 0
+ && mpfr_signbit (mpc_imagref (x)) != mpfr_signbit (mpc_realref (y)))
+ || (cx1 > 0 && mpfr_signbit (mpc_imagref (y)));
+
+ /* warning: mpc_set_ui_ui does not set Im(z) to -0 if Im(rnd)=RNDD */
+ ret = mpc_set_ui_ui (z, 1, 0, rnd);
+
+ if (MPC_RND_IM (rnd) == GMP_RNDD || sign_zi)
+ mpc_conj (z, z, MPC_RNDNN);
+
+ mpfr_clear (n);
+ return ret;
+ }
+ }
+
+ if (!mpc_fin_p (x) || !mpc_fin_p (y))
+ {
+ /* special values: exp(y*log(x)) */
+ mpc_init2 (u, 2);
+ mpc_log (u, x, MPC_RNDNN);
+ mpc_mul (u, u, y, MPC_RNDNN);
+ ret = mpc_exp (z, u, rnd);
+ mpc_clear (u);
+ goto end;
+ }
+
+ if (x_real) /* case x real */
+ {
+ if (mpfr_zero_p (mpc_realref(x))) /* x is zero */
+ {
+ /* special values: exp(y*log(x)) */
+ mpc_init2 (u, 2);
+ mpc_log (u, x, MPC_RNDNN);
+ mpc_mul (u, u, y, MPC_RNDNN);
+ ret = mpc_exp (z, u, rnd);
+ mpc_clear (u);
+ goto end;
+ }
+
+ /* Special case 1^y = 1 */
+ if (mpfr_cmp_ui (mpc_realref(x), 1) == 0)
+ {
+ int s1, s2;
+ s1 = mpfr_signbit (mpc_realref (y));
+ s2 = mpfr_signbit (mpc_imagref (x));
+
+ ret = mpc_set_ui (z, +1, rnd);
+ /* the sign of the zero imaginary part is known in some cases (see
+ algorithm.tex). In such cases we have
+ (x +s*0i)^(y+/-0i) = x^y + s*sign(y)*0i
+ where s = +/-1. We extend here this rule to fix the sign of the
+ zero part.
+
+ Note that the sign must also be set explicitly when rnd=RNDD
+ because mpfr_set_ui(z_i, 0, rnd) always sets z_i to +0.
+ */
+ if (MPC_RND_IM (rnd) == GMP_RNDD || s1 != s2)
+ mpc_conj (z, z, MPC_RNDNN);
+ goto end;
+ }
+
+ /* x^y is real when:
+ (a) x is real and y is integer
+ (b) x is real non-negative and y is real */
+ if (y_real && (mpfr_integer_p (mpc_realref(y)) ||
+ mpfr_cmp_ui (mpc_realref(x), 0) >= 0))
+ {
+ int s1, s2;
+ s1 = mpfr_signbit (mpc_realref (y));
+ s2 = mpfr_signbit (mpc_imagref (x));
+
+ ret = mpfr_pow (mpc_realref(z), mpc_realref(x), mpc_realref(y), MPC_RND_RE(rnd));
+ ret = MPC_INEX(ret, mpfr_set_ui (mpc_imagref(z), 0, MPC_RND_IM(rnd)));
+
+ /* the sign of the zero imaginary part is known in some cases
+ (see algorithm.tex). In such cases we have (x +s*0i)^(y+/-0i)
+ = x^y + s*sign(y)*0i where s = +/-1.
+ We extend here this rule to fix the sign of the zero part.
+
+ Note that the sign must also be set explicitly when rnd=RNDD
+ because mpfr_set_ui(z_i, 0, rnd) always sets z_i to +0.
+ */
+ if (MPC_RND_IM(rnd) == GMP_RNDD || s1 != s2)
+ mpfr_neg (mpc_imagref(z), mpc_imagref(z), MPC_RND_IM(rnd));
+ goto end;
+ }
+
+ /* (-1)^(n+I*t) is real for n integer and t real */
+ if (mpfr_cmp_si (mpc_realref(x), -1) == 0 && mpfr_integer_p (mpc_realref(y)))
+ z_real = 1;
+
+ /* for x real, x^y is imaginary when:
+ (a) x is negative and y is half-an-integer
+ (b) x = -1 and Re(y) is half-an-integer
+ */
+ if ((mpfr_cmp_ui (mpc_realref(x), 0) < 0) && is_odd (mpc_realref(y), 1)
+ && (y_real || mpfr_cmp_si (mpc_realref(x), -1) == 0))
+ z_imag = 1;
+ }
+ else /* x non real */
+ /* I^(t*I) and (-I)^(t*I) are real for t real,
+ I^(n+t*I) and (-I)^(n+t*I) are real for n even and t real, and
+ I^(n+t*I) and (-I)^(n+t*I) are imaginary for n odd and t real
+ (s*I)^n is real for n even and imaginary for n odd */
+ if ((mpc_cmp_si_si (x, 0, 1) == 0 || mpc_cmp_si_si (x, 0, -1) == 0 ||
+ (mpfr_cmp_ui (mpc_realref(x), 0) == 0 && y_real)) &&
+ mpfr_integer_p (mpc_realref(y)))
+ { /* x is I or -I, and Re(y) is an integer */
+ if (is_odd (mpc_realref(y), 0))
+ z_imag = 1; /* Re(y) odd: z is imaginary */
+ else
+ z_real = 1; /* Re(y) even: z is real */
+ }
+ else /* (t+/-t*I)^(2n) is imaginary for n odd and real for n even */
+ if (mpfr_cmpabs (mpc_realref(x), mpc_imagref(x)) == 0 && y_real &&
+ mpfr_integer_p (mpc_realref(y)) && is_odd (mpc_realref(y), 0) == 0)
+ {
+ if (is_odd (mpc_realref(y), -1)) /* y/2 is odd */
+ z_imag = 1;
+ else
+ z_real = 1;
+ }
+
+ pr = mpfr_get_prec (mpc_realref(z));
+ pi = mpfr_get_prec (mpc_imagref(z));
+ p = (pr > pi) ? pr : pi;
+ p += 12; /* experimentally, seems to give less than 10% of failures in
+ Ziv's strategy; probably wrong now since q is not computed */
+ if (p < 64)
+ p = 64;
+ mpc_init2 (u, p);
+ mpc_init2 (t, p);
+ pr += MPC_RND_RE(rnd) == GMP_RNDN;
+ pi += MPC_RND_IM(rnd) == GMP_RNDN;
+ maxprec = MPC_MAX_PREC (z);
+ x_imag = mpfr_zero_p (mpc_realref(x));
+ for (loop = 0;; loop++)
+ {
+ int ret_exp;
+ mpfr_exp_t dr, di;
+ mpfr_prec_t q=0;
+ /* to avoid warning message, real initialisation below */
+
+ mpc_log (t, x, MPC_RNDNN);
+ mpc_mul (t, t, y, MPC_RNDNN);
+
+ if (loop == 0) {
+ /* compute q such that |Re (y log x)|, |Im (y log x)| < 2^q */
+ q = mpfr_get_exp (mpc_realref(t)) > 0 ? mpfr_get_exp (mpc_realref(t)) : 0;
+ if (mpfr_get_exp (mpc_imagref(t)) > (mpfr_exp_t) q)
+ q = mpfr_get_exp (mpc_imagref(t));
+ }
+
+ mpfr_clear_overflow ();
+ mpfr_clear_underflow ();
+ ret_exp = mpc_exp (u, t, MPC_RNDNN);
+ if (mpfr_underflow_p () || mpfr_overflow_p ()) {
+ /* under- and overflow flags are set by mpc_exp */
+ mpc_set (z, u, MPC_RNDNN);
+ ret = ret_exp;
+ goto exact;
+ }
+
+ /* Since the error bound is global, we have to take into account the
+ exponent difference between the real and imaginary parts. We assume
+ either the real or the imaginary part of u is not zero.
+ */
+ dr = mpfr_zero_p (mpc_realref(u)) ? mpfr_get_exp (mpc_imagref(u))
+ : mpfr_get_exp (mpc_realref(u));
+ di = mpfr_zero_p (mpc_imagref(u)) ? dr : mpfr_get_exp (mpc_imagref(u));
+ if (dr > di)
+ {
+ di = dr - di;
+ dr = 0;
+ }
+ else
+ {
+ dr = di - dr;
+ di = 0;
+ }
+ /* the term -3 takes into account the factor 4 in the complex error
+ (see algorithms.tex) plus one due to the exponent difference: if
+ z = a + I*b, where the relative error on z is at most 2^(-p), and
+ EXP(a) = EXP(b) + k, the relative error on b is at most 2^(k-p) */
+ if ((z_imag || (p > q + 3 + dr && mpfr_can_round (mpc_realref(u), p - q - 3 - dr, GMP_RNDN, GMP_RNDZ, pr))) &&
+ (z_real || (p > q + 3 + di && mpfr_can_round (mpc_imagref(u), p - q - 3 - di, GMP_RNDN, GMP_RNDZ, pi))))
+ break;
+
+ /* if Re(u) is not known to be zero, assume it is a normal number, i.e.,
+ neither zero, Inf or NaN, otherwise we might enter an infinite loop */
+ MPC_ASSERT (z_imag || mpfr_number_p (mpc_realref(u)));
+ /* idem for Im(u) */
+ MPC_ASSERT (z_real || mpfr_number_p (mpc_imagref(u)));
+
+ if (ret == -2) /* we did not yet call mpc_pow_exact, or it aborted
+ because intermediate computations had > maxprec bits */
+ {
+ /* check exact cases (see algorithms.tex) */
+ if (y_real)
+ {
+ maxprec *= 2;
+ ret = mpc_pow_exact (z, x, mpc_realref(y), rnd, maxprec);
+ if (ret != -1 && ret != -2)
+ goto exact;
+ }
+ p += dr + di + 64;
+ }
+ else
+ p += p / 2;
+ mpc_set_prec (t, p);
+ mpc_set_prec (u, p);
+ }
+
+ if (z_real)
+ {
+ /* When the result is real (see algorithm.tex for details),
+ Im(x^y) =
+ + sign(imag(y))*0i, if |x| > 1
+ + sign(imag(x))*sign(real(y))*0i, if |x| = 1
+ - sign(imag(y))*0i, if |x| < 1
+ */
+ mpfr_t n;
+ int inex, cx1;
+ int sign_zi, sign_rex, sign_imx;
+ /* cx1 < 0 if |x| < 1
+ cx1 = 0 if |x| = 1
+ cx1 > 0 if |x| > 1
+ */
+
+ sign_rex = mpfr_signbit (mpc_realref (x));
+ sign_imx = mpfr_signbit (mpc_imagref (x));
+ mpfr_init (n);
+ inex = mpc_norm (n, x, GMP_RNDN);
+ cx1 = mpfr_cmp_ui (n, 1);
+ if (cx1 == 0 && inex != 0)
+ cx1 = -inex;
+
+ sign_zi = (cx1 < 0 && mpfr_signbit (mpc_imagref (y)) == 0)
+ || (cx1 == 0 && sign_imx != mpfr_signbit (mpc_realref (y)))
+ || (cx1 > 0 && mpfr_signbit (mpc_imagref (y)));
+
+ /* copy RE(y) to n since if z==y we will destroy Re(y) below */
+ mpfr_set_prec (n, mpfr_get_prec (mpc_realref (y)));
+ mpfr_set (n, mpc_realref (y), GMP_RNDN);
+ ret = mpfr_set (mpc_realref(z), mpc_realref(u), MPC_RND_RE(rnd));
+ if (y_real && (x_real || x_imag))
+ {
+ /* FIXME: with y_real we assume Im(y) is really 0, which is the case
+ for example when y comes from pow_fr, but in case Im(y) is +0 or
+ -0, we might get different results */
+ mpfr_set_ui (mpc_imagref (z), 0, MPC_RND_IM (rnd));
+ fix_sign (z, sign_rex, sign_imx, n);
+ ret = MPC_INEX(ret, 0); /* imaginary part is exact */
+ }
+ else
+ {
+ ret = MPC_INEX (ret, mpfr_set_ui (mpc_imagref (z), 0, MPC_RND_IM (rnd)));
+ /* warning: mpfr_set_ui does not set Im(z) to -0 if Im(rnd) = RNDD */
+ if (MPC_RND_IM (rnd) == GMP_RNDD || sign_zi)
+ mpc_conj (z, z, MPC_RNDNN);
+ }
+
+ mpfr_clear (n);
+ }
+ else if (z_imag)
+ {
+ ret = mpfr_set (mpc_imagref(z), mpc_imagref(u), MPC_RND_IM(rnd));
+ /* if z is imaginary and y real, then x cannot be real */
+ if (y_real && x_imag)
+ {
+ int sign_rex = mpfr_signbit (mpc_realref (x));
+
+ /* If z overlaps with y we set Re(z) before checking Re(y) below,
+ but in that case y=0, which was dealt with above. */
+ mpfr_set_ui (mpc_realref (z), 0, MPC_RND_RE (rnd));
+ /* Note: fix_sign only does something when y is an integer,
+ then necessarily y = 1 or 3 (mod 4), and in that case the
+ sign of Im(x) is irrelevant. */
+ fix_sign (z, sign_rex, 0, mpc_realref (y));
+ ret = MPC_INEX(0, ret);
+ }
+ else
+ ret = MPC_INEX(mpfr_set_ui (mpc_realref(z), 0, MPC_RND_RE(rnd)), ret);
+ }
+ else
+ ret = mpc_set (z, u, rnd);
+ exact:
+ mpc_clear (t);
+ mpc_clear (u);
+
+ /* restore underflow and overflow flags from MPFR */
+ if (saved_underflow)
+ mpfr_set_underflow ();
+ if (saved_overflow)
+ mpfr_set_overflow ();
+
+ end:
+ return ret;
+}
diff --git a/mpc/src/pow_d.c b/mpc/src/pow_d.c
new file mode 100644
index 0000000000..8034b26293
--- /dev/null
+++ b/mpc/src/pow_d.c
@@ -0,0 +1,38 @@
+/* mpc_pow_d -- Raise a complex number to a double-precision power.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for MPC_ASSERT */
+#include <float.h> /* for DBL_MANT_DIG */
+#include "mpc-impl.h"
+
+int
+mpc_pow_d (mpc_ptr z, mpc_srcptr x, double y, mpc_rnd_t rnd)
+{
+ mpc_t yy;
+ int inex;
+
+ MPC_ASSERT(FLT_RADIX == 2);
+ mpc_init3 (yy, DBL_MANT_DIG, MPFR_PREC_MIN);
+ mpc_set_d (yy, y, MPC_RNDNN); /* exact */
+ inex = mpc_pow (z, x, yy, rnd);
+ mpc_clear (yy);
+ return inex;
+}
+
diff --git a/mpc/src/pow_fr.c b/mpc/src/pow_fr.c
new file mode 100644
index 0000000000..8c5d930421
--- /dev/null
+++ b/mpc/src/pow_fr.c
@@ -0,0 +1,37 @@
+/* mpc_pow_fr -- Raise a complex number to a floating-point power.
+
+Copyright (C) 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_pow_fr (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd)
+{
+ mpc_t yy;
+ int inex;
+
+ /* avoid copying the significand of y by copying only the struct */
+ mpc_realref(yy)[0] = y[0];
+ mpfr_init2 (mpc_imagref(yy), MPFR_PREC_MIN);
+ mpfr_set_ui (mpc_imagref(yy), 0, GMP_RNDN);
+ inex = mpc_pow (z, x, yy, rnd);
+ mpfr_clear (mpc_imagref(yy));
+ return inex;
+}
+
diff --git a/mpc/src/pow_ld.c b/mpc/src/pow_ld.c
new file mode 100644
index 0000000000..9d98a98478
--- /dev/null
+++ b/mpc/src/pow_ld.c
@@ -0,0 +1,38 @@
+/* mpc_pow_ld -- Raise a complex number to a long double power.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for MPC_ASSERT */
+#include <float.h> /* for LDBL_MANT_DIG */
+#include "mpc-impl.h"
+
+int
+mpc_pow_ld (mpc_ptr z, mpc_srcptr x, long double y, mpc_rnd_t rnd)
+{
+ mpc_t yy;
+ int inex;
+
+ MPC_ASSERT(FLT_RADIX == 2);
+ mpc_init3 (yy, LDBL_MANT_DIG, MPFR_PREC_MIN);
+ mpc_set_ld (yy, y, MPC_RNDNN); /* exact */
+ inex = mpc_pow (z, x, yy, rnd);
+ mpc_clear (yy);
+ return inex;
+}
+
diff --git a/mpc/src/pow_si.c b/mpc/src/pow_si.c
new file mode 100644
index 0000000000..5b5c5d9dfb
--- /dev/null
+++ b/mpc/src/pow_si.c
@@ -0,0 +1,30 @@
+/* mpc_pow_si -- Raise a complex number to an integer power.
+
+Copyright (C) 2009, 2010 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_pow_si (mpc_ptr z, mpc_srcptr x, long y, mpc_rnd_t rnd)
+{
+ if (y >= 0)
+ return mpc_pow_usi (z, x, (unsigned long) y, 1, rnd);
+ else
+ return mpc_pow_usi (z, x, (unsigned long) (-y), -1, rnd);
+}
diff --git a/mpc/src/pow_ui.c b/mpc/src/pow_ui.c
new file mode 100644
index 0000000000..da82a9471f
--- /dev/null
+++ b/mpc/src/pow_ui.c
@@ -0,0 +1,169 @@
+/* mpc_pow_ui -- Raise a complex number to an integer power.
+
+Copyright (C) 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <limits.h> /* for CHAR_BIT */
+#include "mpc-impl.h"
+
+static int
+mpc_pow_usi_naive (mpc_ptr z, mpc_srcptr x, unsigned long y, int sign,
+ mpc_rnd_t rnd)
+{
+ int inex;
+ mpc_t t;
+
+ mpc_init3 (t, sizeof (unsigned long) * CHAR_BIT, MPFR_PREC_MIN);
+ if (sign > 0)
+ mpc_set_ui (t, y, MPC_RNDNN); /* exact */
+ else
+ mpc_set_si (t, - (signed long) y, MPC_RNDNN);
+ inex = mpc_pow (z, x, t, rnd);
+ mpc_clear (t);
+
+ return inex;
+}
+
+
+int
+mpc_pow_usi (mpc_ptr z, mpc_srcptr x, unsigned long y, int sign,
+ mpc_rnd_t rnd)
+ /* computes z = x^(sign*y) */
+{
+ int inex;
+ mpc_t t, x3;
+ mpfr_prec_t p, l, l0;
+ long unsigned int u;
+ int has3; /* non-zero if y has '11' in its binary representation */
+ int loop, done;
+
+ /* let mpc_pow deal with special values */
+ if (!mpc_fin_p (x) || mpfr_zero_p (mpc_realref (x)) || mpfr_zero_p (mpc_imagref(x))
+ || y == 0)
+ return mpc_pow_usi_naive (z, x, y, sign, rnd);
+ /* easy special cases */
+ else if (y == 1) {
+ if (sign > 0)
+ return mpc_set (z, x, rnd);
+ else
+ return mpc_ui_div (z, 1ul, x, rnd);
+ }
+ else if (y == 2 && sign > 0)
+ return mpc_sqr (z, x, rnd);
+ /* let mpc_pow treat potential over- and underflows */
+ else {
+ mpfr_exp_t exp_r = mpfr_get_exp (mpc_realref (x)),
+ exp_i = mpfr_get_exp (mpc_imagref (x));
+ if ( MPC_MAX (exp_r, exp_i) > mpfr_get_emax () / (mpfr_exp_t) y
+ /* heuristic for overflow */
+ || MPC_MAX (-exp_r, -exp_i) > (-mpfr_get_emin ()) / (mpfr_exp_t) y
+ /* heuristic for underflow */
+ )
+ return mpc_pow_usi_naive (z, x, y, sign, rnd);
+ }
+
+ has3 = (y & (y >> 1)) != 0;
+ for (l = 0, u = y; u > 3; l ++, u >>= 1);
+ /* l>0 is the number of bits of y, minus 2, thus y has bits:
+ y_{l+1} y_l y_{l-1} ... y_1 y_0 */
+ l0 = l + 2;
+ p = MPC_MAX_PREC(z) + l0 + 32; /* l0 ensures that y*2^{-p} <= 1 below */
+ mpc_init2 (t, p);
+ if (has3)
+ mpc_init2 (x3, p);
+
+ loop = 0;
+ done = 0;
+ while (!done) {
+ loop++;
+
+ mpc_sqr (t, x, MPC_RNDNN);
+ if (has3) {
+ mpc_mul (x3, t, x, MPC_RNDNN);
+ if ((y >> l) & 1) /* y starts with 11... */
+ mpc_set (t, x3, MPC_RNDNN);
+ }
+ while (l-- > 0) {
+ mpc_sqr (t, t, MPC_RNDNN);
+ if ((y >> l) & 1) {
+ if ((l > 0) && ((y >> (l-1)) & 1)) /* implies has3 <> 0 */ {
+ l--;
+ mpc_sqr (t, t, MPC_RNDNN);
+ mpc_mul (t, t, x3, MPC_RNDNN);
+ }
+ else
+ mpc_mul (t, t, x, MPC_RNDNN);
+ }
+ }
+ if (sign < 0)
+ mpc_ui_div (t, 1ul, t, MPC_RNDNN);
+
+ if (mpfr_zero_p (mpc_realref(t)) || mpfr_zero_p (mpc_imagref(t))) {
+ inex = mpc_pow_usi_naive (z, x, y, sign, rnd);
+ /* since mpfr_get_exp() is not defined for zero */
+ done = 1;
+ }
+ else {
+ /* see error bound in algorithms.tex; we use y<2^l0 instead of y-1
+ also when sign>0 */
+ mpfr_exp_t diff;
+ mpfr_prec_t er, ei;
+
+ diff = mpfr_get_exp (mpc_realref(t)) - mpfr_get_exp (mpc_imagref(t));
+ /* the factor on the real part is 2+2^(-diff+2) <= 4 for diff >= 1
+ and < 2^(-diff+3) for diff <= 0 */
+ er = (diff >= 1) ? l0 + 3 : l0 + (-diff) + 3;
+ /* the factor on the imaginary part is 2+2^(diff+2) <= 4 for diff <= -1
+ and < 2^(diff+3) for diff >= 0 */
+ ei = (diff <= -1) ? l0 + 3 : l0 + diff + 3;
+ if (mpfr_can_round (mpc_realref(t), p - er, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_RE(z) + (MPC_RND_RE(rnd) == GMP_RNDN))
+ && mpfr_can_round (mpc_imagref(t), p - ei, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_IM(z) + (MPC_RND_IM(rnd) == GMP_RNDN))) {
+ inex = mpc_set (z, t, rnd);
+ done = 1;
+ }
+ else if (loop == 1 && SAFE_ABS(mpfr_prec_t, diff) < MPC_MAX_PREC(z)) {
+ /* common case, make a second trial at higher precision */
+ p += MPC_MAX_PREC(x);
+ mpc_set_prec (t, p);
+ if (has3)
+ mpc_set_prec (x3, p);
+ l = l0 - 2;
+ }
+ else {
+ /* stop the loop and use mpc_pow */
+ inex = mpc_pow_usi_naive (z, x, y, sign, rnd);
+ done = 1;
+ }
+ }
+ }
+
+ mpc_clear (t);
+ if (has3)
+ mpc_clear (x3);
+
+ return inex;
+}
+
+
+int
+mpc_pow_ui (mpc_ptr z, mpc_srcptr x, unsigned long y, mpc_rnd_t rnd)
+{
+ return mpc_pow_usi (z, x, y, 1, rnd);
+}
diff --git a/mpc/src/pow_z.c b/mpc/src/pow_z.c
new file mode 100644
index 0000000000..22eb544ca9
--- /dev/null
+++ b/mpc/src/pow_z.c
@@ -0,0 +1,47 @@
+/* mpc_pow_z -- Raise a complex number to an integer power.
+
+Copyright (C) 2009, 2010 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_pow_z (mpc_ptr z, mpc_srcptr x, mpz_srcptr y, mpc_rnd_t rnd)
+{
+ mpc_t yy;
+ int inex;
+ mpfr_prec_t n = (mpfr_prec_t) mpz_sizeinbase (y, 2);
+
+ /* if y fits in an unsigned long or long, call the corresponding functions,
+ which are supposed to be more efficient */
+ if (mpz_cmp_ui (y, 0ul) >= 0) {
+ if (mpz_fits_ulong_p (y))
+ return mpc_pow_usi (z, x, mpz_get_ui (y), 1, rnd);
+ }
+ else {
+ if (mpz_fits_slong_p (y))
+ return mpc_pow_usi (z, x, (unsigned long) (-mpz_get_si (y)), -1, rnd);
+ }
+
+ mpc_init3 (yy, (n < MPFR_PREC_MIN) ? MPFR_PREC_MIN : n, MPFR_PREC_MIN);
+ mpc_set_z (yy, y, MPC_RNDNN); /* exact */
+ inex = mpc_pow (z, x, yy, rnd);
+ mpc_clear (yy);
+ return inex;
+}
+
diff --git a/mpc/src/proj.c b/mpc/src/proj.c
new file mode 100644
index 0000000000..ace58c5331
--- /dev/null
+++ b/mpc/src/proj.c
@@ -0,0 +1,34 @@
+/* mpc_proj -- projection of a complex number onto the Riemann sphere.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_proj (mpc_ptr a, mpc_srcptr b, mpc_rnd_t rnd)
+{
+ if (mpc_inf_p (b)) {
+ /* infinities project to +Inf +i* copysign(0.0, cimag(z)) */
+ mpfr_set_inf (mpc_realref (a), +1);
+ mpfr_set_zero (mpc_imagref (a), (mpfr_signbit (mpc_imagref (b)) ? -1 : 1));
+ return MPC_INEX (0, 0);
+ }
+ else
+ return mpc_set (a, b, rnd);
+}
diff --git a/mpc/src/real.c b/mpc/src/real.c
new file mode 100644
index 0000000000..041dddb5ff
--- /dev/null
+++ b/mpc/src/real.c
@@ -0,0 +1,27 @@
+/* mpc_real -- Get the real part of a complex number.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_real (mpfr_ptr a, mpc_srcptr b, mpfr_rnd_t rnd)
+{
+ return mpfr_set (a, mpc_realref (b), rnd);
+}
diff --git a/mpc/src/set.c b/mpc/src/set.c
new file mode 100644
index 0000000000..e7a3c1148c
--- /dev/null
+++ b/mpc/src/set.c
@@ -0,0 +1,32 @@
+/* mpc_set -- Set a complex number from another complex number.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_set (mpc_ptr a, mpc_srcptr b, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_set (mpc_realref(a), mpc_realref(b), MPC_RND_RE(rnd));
+ inex_im = mpfr_set (mpc_imagref(a), mpc_imagref(b), MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/set_prec.c b/mpc/src/set_prec.c
new file mode 100644
index 0000000000..c5e6f24a37
--- /dev/null
+++ b/mpc/src/set_prec.c
@@ -0,0 +1,28 @@
+/* mpc_set_prec -- reset the precision of a complex variable.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+void
+mpc_set_prec (mpc_t x, mpfr_prec_t prec)
+{
+ mpfr_set_prec (mpc_realref(x), prec);
+ mpfr_set_prec (mpc_imagref(x), prec);
+}
diff --git a/mpc/src/set_str.c b/mpc/src/set_str.c
new file mode 100644
index 0000000000..195b9ac0bf
--- /dev/null
+++ b/mpc/src/set_str.c
@@ -0,0 +1,42 @@
+/* mpc_set_str -- Convert a string into a complex number.
+
+Copyright (C) 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <ctype.h>
+#include "mpc-impl.h"
+
+int
+mpc_set_str (mpc_t z, const char *str, int base, mpc_rnd_t rnd)
+{
+ char *p;
+ int inex;
+
+ inex = mpc_strtoc (z, str, &p, base, rnd);
+
+ if (inex != -1){
+ while (isspace ((unsigned char) (*p)))
+ p++;
+ if (*p == '\0')
+ return inex;
+ }
+
+ mpfr_set_nan (mpc_realref (z));
+ mpfr_set_nan (mpc_imagref (z));
+ return -1;
+}
diff --git a/mpc/src/set_x.c b/mpc/src/set_x.c
new file mode 100644
index 0000000000..94ec12d96b
--- /dev/null
+++ b/mpc/src/set_x.c
@@ -0,0 +1,104 @@
+/* mpc_set_x -- Set the real part of a complex number
+ (imaginary part equals +0 regardless of rounding mode).
+
+Copyright (C) 2008, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h> /* for intmax_t */
+#else
+# ifdef HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+
+#ifdef HAVE_COMPLEX_H
+# include <complex.h>
+#endif
+
+#include "mpc-impl.h"
+
+#define MPC_SET_X(real_t, z, real_value, rnd) \
+ { \
+ int _inex_re, _inex_im; \
+ _inex_re = (mpfr_set_ ## real_t) (mpc_realref (z), (real_value), MPC_RND_RE (rnd)); \
+ _inex_im = mpfr_set_ui (mpc_imagref (z), 0, MPC_RND_IM (rnd)); \
+ return MPC_INEX (_inex_re, _inex_im); \
+ }
+
+int
+mpc_set_fr (mpc_ptr a, mpfr_srcptr b, mpc_rnd_t rnd)
+ MPC_SET_X (fr, a, b, rnd)
+
+int
+mpc_set_d (mpc_ptr a, double b, mpc_rnd_t rnd)
+ MPC_SET_X (d, a, b, rnd)
+
+int
+mpc_set_ld (mpc_ptr a, long double b, mpc_rnd_t rnd)
+ MPC_SET_X (ld, a, b, rnd)
+
+int
+mpc_set_ui (mpc_ptr a, unsigned long int b, mpc_rnd_t rnd)
+ MPC_SET_X (ui, a, b, rnd)
+
+int
+mpc_set_si (mpc_ptr a, long int b, mpc_rnd_t rnd)
+ MPC_SET_X (si, a, b, rnd)
+
+int
+mpc_set_z (mpc_ptr a, mpz_srcptr b, mpc_rnd_t rnd)
+ MPC_SET_X (z, a, b, rnd)
+
+int
+mpc_set_q (mpc_ptr a, mpq_srcptr b, mpc_rnd_t rnd)
+ MPC_SET_X (q, a, b, rnd)
+
+int
+mpc_set_f (mpc_ptr a, mpf_srcptr b, mpc_rnd_t rnd)
+ MPC_SET_X (f, a, b, rnd)
+
+#ifdef _MPC_H_HAVE_INTMAX_T
+int
+mpc_set_uj (mpc_ptr a, uintmax_t b, mpc_rnd_t rnd)
+ MPC_SET_X (uj, a, b, rnd)
+
+int
+mpc_set_sj (mpc_ptr a, intmax_t b, mpc_rnd_t rnd)
+ MPC_SET_X (sj, a, b, rnd)
+#endif
+
+#ifdef HAVE_COMPLEX_H
+int
+mpc_set_dc (mpc_ptr a, double _Complex b, mpc_rnd_t rnd) {
+ return mpc_set_d_d (a, creal (b), cimag (b), rnd);
+}
+
+int
+mpc_set_ldc (mpc_ptr a, long double _Complex b, mpc_rnd_t rnd) {
+ return mpc_set_ld_ld (a, creall (b), cimagl (b), rnd);
+}
+#endif
+
+void
+mpc_set_nan (mpc_ptr a) {
+ mpfr_set_nan (mpc_realref (a));
+ mpfr_set_nan (mpc_imagref (a));
+}
diff --git a/mpc/src/set_x_x.c b/mpc/src/set_x_x.c
new file mode 100644
index 0000000000..3ce69f2454
--- /dev/null
+++ b/mpc/src/set_x_x.c
@@ -0,0 +1,78 @@
+/* mpc_set_x_x -- Set complex number real and imaginary parts from parameters
+ whose type is known by mpfr.
+
+Copyright (C) 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "config.h"
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h> /* for intmax_t */
+#else
+# ifdef HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+
+#include "mpc-impl.h"
+
+#define MPC_SET_X_X(type, z, real_value, imag_value, rnd) \
+ MPC_SET_X_Y (type, type, z, real_value, imag_value, rnd)
+
+int
+mpc_set_d_d (mpc_ptr z, double a, double b, mpc_rnd_t rnd)
+ MPC_SET_X_X (d, z, a, b, rnd)
+
+int
+mpc_set_f_f (mpc_ptr z, mpf_srcptr a, mpf_srcptr b, mpc_rnd_t rnd)
+ MPC_SET_X_X (f, z, a, b, rnd)
+
+int
+mpc_set_fr_fr (mpc_ptr z, mpfr_srcptr a, mpfr_srcptr b, mpc_rnd_t rnd)
+ MPC_SET_X_X (fr, z, a, b, rnd)
+
+int
+mpc_set_ld_ld (mpc_ptr z, long double a, long double b, mpc_rnd_t rnd)
+ MPC_SET_X_X (ld, z, a, b, rnd)
+
+int
+mpc_set_q_q (mpc_ptr z, mpq_srcptr a, mpq_srcptr b, mpc_rnd_t rnd)
+ MPC_SET_X_X (q, z, a, b, rnd)
+
+int
+mpc_set_si_si (mpc_ptr z, long int a, long int b, mpc_rnd_t rnd)
+ MPC_SET_X_X (si, z, a, b, rnd)
+
+int
+mpc_set_ui_ui (mpc_ptr z, unsigned long int a, unsigned long int b,
+ mpc_rnd_t rnd)
+ MPC_SET_X_X (ui, z, a, b, rnd)
+
+int
+mpc_set_z_z (mpc_ptr z, mpz_srcptr a, mpz_srcptr b, mpc_rnd_t rnd)
+ MPC_SET_X_X (z, z, a, b, rnd)
+
+#ifdef _MPC_H_HAVE_INTMAX_T
+int
+mpc_set_uj_uj (mpc_ptr z, uintmax_t a, uintmax_t b, mpc_rnd_t rnd)
+ MPC_SET_X_X (uj, z, a, b, rnd)
+
+int
+mpc_set_sj_sj (mpc_ptr z, intmax_t a, intmax_t b, mpc_rnd_t rnd)
+ MPC_SET_X_X (sj, z, a, b, rnd)
+#endif
diff --git a/mpc/src/sin.c b/mpc/src/sin.c
new file mode 100644
index 0000000000..27df7618df
--- /dev/null
+++ b/mpc/src/sin.c
@@ -0,0 +1,27 @@
+/* mpc_sin -- sine of a complex number.
+
+Copyright (C) 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_sin (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ return MPC_INEX1 (mpc_sin_cos (rop, NULL, op, rnd, 0));
+}
diff --git a/mpc/src/sin_cos.c b/mpc/src/sin_cos.c
new file mode 100644
index 0000000000..0cff45acd5
--- /dev/null
+++ b/mpc/src/sin_cos.c
@@ -0,0 +1,402 @@
+/* mpc_sin_cos -- combined sine and cosine of a complex number.
+
+Copyright (C) 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+static int
+mpc_sin_cos_nonfinite (mpc_ptr rop_sin, mpc_ptr rop_cos, mpc_srcptr op,
+ mpc_rnd_t rnd_sin, mpc_rnd_t rnd_cos)
+ /* assumes that op (that is, its real or imaginary part) is not finite */
+{
+ int overlap;
+ mpc_t op_loc;
+
+ overlap = (rop_sin == op || rop_cos == op);
+ if (overlap) {
+ mpc_init3 (op_loc, MPC_PREC_RE (op), MPC_PREC_IM (op));
+ mpc_set (op_loc, op, MPC_RNDNN);
+ }
+ else
+ op_loc [0] = op [0];
+
+ if (rop_sin != NULL) {
+ if (mpfr_nan_p (mpc_realref (op_loc)) || mpfr_nan_p (mpc_imagref (op_loc))) {
+ mpc_set (rop_sin, op_loc, rnd_sin);
+ if (mpfr_nan_p (mpc_imagref (op_loc))) {
+ /* sin(x +i*NaN) = NaN +i*NaN, except for x=0 */
+ /* sin(-0 +i*NaN) = -0 +i*NaN */
+ /* sin(+0 +i*NaN) = +0 +i*NaN */
+ if (!mpfr_zero_p (mpc_realref (op_loc)))
+ mpfr_set_nan (mpc_realref (rop_sin));
+ }
+ else /* op = NaN + i*y */
+ if (!mpfr_inf_p (mpc_imagref (op_loc)) && !mpfr_zero_p (mpc_imagref (op_loc)))
+ /* sin(NaN -i*Inf) = NaN -i*Inf */
+ /* sin(NaN -i*0) = NaN -i*0 */
+ /* sin(NaN +i*0) = NaN +i*0 */
+ /* sin(NaN +i*Inf) = NaN +i*Inf */
+ /* sin(NaN +i*y) = NaN +i*NaN, when 0<|y|<Inf */
+ mpfr_set_nan (mpc_imagref (rop_sin));
+ }
+ else if (mpfr_inf_p (mpc_realref (op_loc))) {
+ mpfr_set_nan (mpc_realref (rop_sin));
+
+ if (!mpfr_inf_p (mpc_imagref (op_loc)) && !mpfr_zero_p (mpc_imagref (op_loc)))
+ /* sin(+/-Inf +i*y) = NaN +i*NaN, when 0<|y|<Inf */
+ mpfr_set_nan (mpc_imagref (rop_sin));
+ else
+ /* sin(+/-Inf -i*Inf) = NaN -i*Inf */
+ /* sin(+/-Inf +i*Inf) = NaN +i*Inf */
+ /* sin(+/-Inf -i*0) = NaN -i*0 */
+ /* sin(+/-Inf +i*0) = NaN +i*0 */
+ mpfr_set (mpc_imagref (rop_sin), mpc_imagref (op_loc), MPC_RND_IM (rnd_sin));
+ }
+ else if (mpfr_zero_p (mpc_realref (op_loc))) {
+ /* sin(-0 -i*Inf) = -0 -i*Inf */
+ /* sin(+0 -i*Inf) = +0 -i*Inf */
+ /* sin(-0 +i*Inf) = -0 +i*Inf */
+ /* sin(+0 +i*Inf) = +0 +i*Inf */
+ mpc_set (rop_sin, op_loc, rnd_sin);
+ }
+ else {
+ /* sin(x -i*Inf) = +Inf*(sin(x) -i*cos(x)) */
+ /* sin(x +i*Inf) = +Inf*(sin(x) +i*cos(x)) */
+ mpfr_t s, c;
+ mpfr_init2 (s, 2);
+ mpfr_init2 (c, 2);
+ mpfr_sin_cos (s, c, mpc_realref (op_loc), GMP_RNDZ);
+ mpfr_set_inf (mpc_realref (rop_sin), MPFR_SIGN (s));
+ mpfr_set_inf (mpc_imagref (rop_sin), MPFR_SIGN (c)*MPFR_SIGN (mpc_imagref (op_loc)));
+ mpfr_clear (s);
+ mpfr_clear (c);
+ }
+ }
+
+ if (rop_cos != NULL) {
+ if (mpfr_nan_p (mpc_realref (op_loc))) {
+ /* cos(NaN + i * NaN) = NaN + i * NaN */
+ /* cos(NaN - i * Inf) = +Inf + i * NaN */
+ /* cos(NaN + i * Inf) = +Inf + i * NaN */
+ /* cos(NaN - i * 0) = NaN - i * 0 */
+ /* cos(NaN + i * 0) = NaN + i * 0 */
+ /* cos(NaN + i * y) = NaN + i * NaN, when y != 0 */
+ if (mpfr_inf_p (mpc_imagref (op_loc)))
+ mpfr_set_inf (mpc_realref (rop_cos), +1);
+ else
+ mpfr_set_nan (mpc_realref (rop_cos));
+
+ if (mpfr_zero_p (mpc_imagref (op_loc)))
+ mpfr_set (mpc_imagref (rop_cos), mpc_imagref (op_loc), MPC_RND_IM (rnd_cos));
+ else
+ mpfr_set_nan (mpc_imagref (rop_cos));
+ }
+ else if (mpfr_nan_p (mpc_imagref (op_loc))) {
+ /* cos(-Inf + i * NaN) = NaN + i * NaN */
+ /* cos(+Inf + i * NaN) = NaN + i * NaN */
+ /* cos(-0 + i * NaN) = NaN - i * 0 */
+ /* cos(+0 + i * NaN) = NaN + i * 0 */
+ /* cos(x + i * NaN) = NaN + i * NaN, when x != 0 */
+ if (mpfr_zero_p (mpc_realref (op_loc)))
+ mpfr_set (mpc_imagref (rop_cos), mpc_realref (op_loc), MPC_RND_IM (rnd_cos));
+ else
+ mpfr_set_nan (mpc_imagref (rop_cos));
+
+ mpfr_set_nan (mpc_realref (rop_cos));
+ }
+ else if (mpfr_inf_p (mpc_realref (op_loc))) {
+ /* cos(-Inf -i*Inf) = cos(+Inf +i*Inf) = -Inf +i*NaN */
+ /* cos(-Inf +i*Inf) = cos(+Inf -i*Inf) = +Inf +i*NaN */
+ /* cos(-Inf -i*0) = cos(+Inf +i*0) = NaN -i*0 */
+ /* cos(-Inf +i*0) = cos(+Inf -i*0) = NaN +i*0 */
+ /* cos(-Inf +i*y) = cos(+Inf +i*y) = NaN +i*NaN, when y != 0 */
+
+ const int same_sign =
+ mpfr_signbit (mpc_realref (op_loc)) == mpfr_signbit (mpc_imagref (op_loc));
+
+ if (mpfr_inf_p (mpc_imagref (op_loc)))
+ mpfr_set_inf (mpc_realref (rop_cos), (same_sign ? -1 : +1));
+ else
+ mpfr_set_nan (mpc_realref (rop_cos));
+
+ if (mpfr_zero_p (mpc_imagref (op_loc)))
+ mpfr_setsign (mpc_imagref (rop_cos), mpc_imagref (op_loc), same_sign,
+ MPC_RND_IM(rnd_cos));
+ else
+ mpfr_set_nan (mpc_imagref (rop_cos));
+ }
+ else if (mpfr_zero_p (mpc_realref (op_loc))) {
+ /* cos(-0 -i*Inf) = cos(+0 +i*Inf) = +Inf -i*0 */
+ /* cos(-0 +i*Inf) = cos(+0 -i*Inf) = +Inf +i*0 */
+ const int same_sign =
+ mpfr_signbit (mpc_realref (op_loc)) == mpfr_signbit (mpc_imagref (op_loc));
+
+ mpfr_setsign (mpc_imagref (rop_cos), mpc_realref (op_loc), same_sign,
+ MPC_RND_IM (rnd_cos));
+ mpfr_set_inf (mpc_realref (rop_cos), +1);
+ }
+ else {
+ /* cos(x -i*Inf) = +Inf*cos(x) +i*Inf*sin(x), when x != 0 */
+ /* cos(x +i*Inf) = +Inf*cos(x) -i*Inf*sin(x), when x != 0 */
+ mpfr_t s, c;
+ mpfr_init2 (c, 2);
+ mpfr_init2 (s, 2);
+ mpfr_sin_cos (s, c, mpc_realref (op_loc), GMP_RNDN);
+ mpfr_set_inf (mpc_realref (rop_cos), mpfr_sgn (c));
+ mpfr_set_inf (mpc_imagref (rop_cos),
+ (mpfr_sgn (mpc_imagref (op_loc)) == mpfr_sgn (s) ? -1 : +1));
+ mpfr_clear (s);
+ mpfr_clear (c);
+ }
+ }
+
+ if (overlap)
+ mpc_clear (op_loc);
+
+ return MPC_INEX12 (MPC_INEX (0,0), MPC_INEX (0,0));
+ /* everything is exact */
+}
+
+
+static int
+mpc_sin_cos_real (mpc_ptr rop_sin, mpc_ptr rop_cos, mpc_srcptr op,
+ mpc_rnd_t rnd_sin, mpc_rnd_t rnd_cos)
+ /* assumes that op is real */
+{
+ int inex_sin_re = 0, inex_cos_re = 0;
+ /* Until further notice, assume computations exact; in particular,
+ by definition, for not computed values. */
+ mpfr_t s, c;
+ int inex_s, inex_c;
+ int sign_im = mpfr_signbit (mpc_imagref (op));
+
+ /* sin(x +-0*i) = sin(x) +-0*i*sign(cos(x)) */
+ /* cos(x +-i*0) = cos(x) -+i*0*sign(sin(x)) */
+ if (rop_sin != 0)
+ mpfr_init2 (s, MPC_PREC_RE (rop_sin));
+ else
+ mpfr_init2 (s, 2); /* We need only the sign. */
+ if (rop_cos != NULL)
+ mpfr_init2 (c, MPC_PREC_RE (rop_cos));
+ else
+ mpfr_init2 (c, 2);
+ inex_s = mpfr_sin (s, mpc_realref (op), MPC_RND_RE (rnd_sin));
+ inex_c = mpfr_cos (c, mpc_realref (op), MPC_RND_RE (rnd_cos));
+ /* We cannot use mpfr_sin_cos since we may need two distinct rounding
+ modes and the exact return values. If we need only the sign, an
+ arbitrary rounding mode will work. */
+
+ if (rop_sin != NULL) {
+ mpfr_set (mpc_realref (rop_sin), s, GMP_RNDN); /* exact */
+ inex_sin_re = inex_s;
+ mpfr_set_zero (mpc_imagref (rop_sin),
+ ( ( sign_im && !mpfr_signbit(c))
+ || (!sign_im && mpfr_signbit(c)) ? -1 : 1));
+ }
+
+ if (rop_cos != NULL) {
+ mpfr_set (mpc_realref (rop_cos), c, GMP_RNDN); /* exact */
+ inex_cos_re = inex_c;
+ mpfr_set_zero (mpc_imagref (rop_cos),
+ ( ( sign_im && mpfr_signbit(s))
+ || (!sign_im && !mpfr_signbit(s)) ? -1 : 1));
+ }
+
+ mpfr_clear (s);
+ mpfr_clear (c);
+
+ return MPC_INEX12 (MPC_INEX (inex_sin_re, 0), MPC_INEX (inex_cos_re, 0));
+}
+
+
+static int
+mpc_sin_cos_imag (mpc_ptr rop_sin, mpc_ptr rop_cos, mpc_srcptr op,
+ mpc_rnd_t rnd_sin, mpc_rnd_t rnd_cos)
+ /* assumes that op is purely imaginary, but not zero */
+{
+ int inex_sin_im = 0, inex_cos_re = 0;
+ /* assume exact if not computed */
+ int overlap;
+ mpc_t op_loc;
+
+ overlap = (rop_sin == op || rop_cos == op);
+ if (overlap) {
+ mpc_init3 (op_loc, MPC_PREC_RE (op), MPC_PREC_IM (op));
+ mpc_set (op_loc, op, MPC_RNDNN);
+ }
+ else
+ op_loc [0] = op [0];
+
+ if (rop_sin != NULL) {
+ /* sin(+-O +i*y) = +-0 +i*sinh(y) */
+ mpfr_set (mpc_realref(rop_sin), mpc_realref(op_loc), GMP_RNDN);
+ inex_sin_im = mpfr_sinh (mpc_imagref(rop_sin), mpc_imagref(op_loc), MPC_RND_IM(rnd_sin));
+ }
+
+ if (rop_cos != NULL) {
+ /* cos(-0 - i * y) = cos(+0 + i * y) = cosh(y) - i * 0,
+ cos(-0 + i * y) = cos(+0 - i * y) = cosh(y) + i * 0,
+ where y > 0 */
+ inex_cos_re = mpfr_cosh (mpc_realref (rop_cos), mpc_imagref (op_loc), MPC_RND_RE (rnd_cos));
+
+ mpfr_set_ui (mpc_imagref (rop_cos), 0ul, MPC_RND_IM (rnd_cos));
+ if (mpfr_signbit (mpc_realref (op_loc)) == mpfr_signbit (mpc_imagref (op_loc)))
+ MPFR_CHANGE_SIGN (mpc_imagref (rop_cos));
+ }
+
+ if (overlap)
+ mpc_clear (op_loc);
+
+ return MPC_INEX12 (MPC_INEX (0, inex_sin_im), MPC_INEX (inex_cos_re, 0));
+}
+
+
+int
+mpc_sin_cos (mpc_ptr rop_sin, mpc_ptr rop_cos, mpc_srcptr op,
+ mpc_rnd_t rnd_sin, mpc_rnd_t rnd_cos)
+ /* Feature not documented in the texinfo file: One of rop_sin or
+ rop_cos may be NULL, in which case it is not computed, and the
+ corresponding ternary inexact value is set to 0 (exact). */
+{
+ if (!mpc_fin_p (op))
+ return mpc_sin_cos_nonfinite (rop_sin, rop_cos, op, rnd_sin, rnd_cos);
+ else if (mpfr_zero_p (mpc_imagref (op)))
+ return mpc_sin_cos_real (rop_sin, rop_cos, op, rnd_sin, rnd_cos);
+ else if (mpfr_zero_p (mpc_realref (op)))
+ return mpc_sin_cos_imag (rop_sin, rop_cos, op, rnd_sin, rnd_cos);
+ else {
+ /* let op = a + i*b, then sin(op) = sin(a)*cosh(b) + i*cos(a)*sinh(b)
+ and cos(op) = cos(a)*cosh(b) - i*sin(a)*sinh(b).
+
+ For Re(sin(op)) (and analogously, the other parts), we use the
+ following algorithm, with rounding to nearest for all operations
+ and working precision w:
+
+ (1) x = o(sin(a))
+ (2) y = o(cosh(b))
+ (3) r = o(x*y)
+ then the error on r is at most 4 ulps, since we can write
+ r = sin(a)*cosh(b)*(1+t)^3 with |t| <= 2^(-w),
+ thus for w >= 2, r = sin(a)*cosh(b)*(1+4*t) with |t| <= 2^(-w),
+ thus the relative error is bounded by 4*2^(-w) <= 4*ulp(r).
+ */
+ mpfr_t s, c, sh, ch, sch, csh;
+ mpfr_prec_t prec;
+ int ok;
+ int inex_re, inex_im, inex_sin, inex_cos;
+
+ prec = 2;
+ if (rop_sin != NULL)
+ prec = MPC_MAX (prec, MPC_MAX_PREC (rop_sin));
+ if (rop_cos != NULL)
+ prec = MPC_MAX (prec, MPC_MAX_PREC (rop_cos));
+
+ mpfr_init2 (s, 2);
+ mpfr_init2 (c, 2);
+ mpfr_init2 (sh, 2);
+ mpfr_init2 (ch, 2);
+ mpfr_init2 (sch, 2);
+ mpfr_init2 (csh, 2);
+
+ do {
+ ok = 1;
+ prec += mpc_ceil_log2 (prec) + 5;
+
+ mpfr_set_prec (s, prec);
+ mpfr_set_prec (c, prec);
+ mpfr_set_prec (sh, prec);
+ mpfr_set_prec (ch, prec);
+ mpfr_set_prec (sch, prec);
+ mpfr_set_prec (csh, prec);
+
+ mpfr_sin_cos (s, c, mpc_realref(op), GMP_RNDN);
+ mpfr_sinh_cosh (sh, ch, mpc_imagref(op), GMP_RNDN);
+
+ if (rop_sin != NULL) {
+ /* real part of sine */
+ mpfr_mul (sch, s, ch, GMP_RNDN);
+ ok = (!mpfr_number_p (sch))
+ || mpfr_can_round (sch, prec - 2, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_RE (rop_sin)
+ + (MPC_RND_RE (rnd_sin) == GMP_RNDN));
+
+ if (ok) {
+ /* imaginary part of sine */
+ mpfr_mul (csh, c, sh, GMP_RNDN);
+ ok = (!mpfr_number_p (csh))
+ || mpfr_can_round (csh, prec - 2, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_IM (rop_sin)
+ + (MPC_RND_IM (rnd_sin) == GMP_RNDN));
+ }
+ }
+
+ if (rop_cos != NULL && ok) {
+ /* real part of cosine */
+ mpfr_mul (c, c, ch, GMP_RNDN);
+ ok = (!mpfr_number_p (c))
+ || mpfr_can_round (c, prec - 2, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_RE (rop_cos)
+ + (MPC_RND_RE (rnd_cos) == GMP_RNDN));
+
+ if (ok) {
+ /* imaginary part of cosine */
+ mpfr_mul (s, s, sh, GMP_RNDN);
+ mpfr_neg (s, s, GMP_RNDN);
+ ok = (!mpfr_number_p (s))
+ || mpfr_can_round (s, prec - 2, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_IM (rop_cos)
+ + (MPC_RND_IM (rnd_cos) == GMP_RNDN));
+ }
+ }
+ } while (ok == 0);
+
+ if (rop_sin != NULL) {
+ inex_re = mpfr_set (mpc_realref (rop_sin), sch, MPC_RND_RE (rnd_sin));
+ if (mpfr_inf_p (sch))
+ inex_re = mpfr_sgn (sch);
+ inex_im = mpfr_set (mpc_imagref (rop_sin), csh, MPC_RND_IM (rnd_sin));
+ if (mpfr_inf_p (csh))
+ inex_im = mpfr_sgn (csh);
+ inex_sin = MPC_INEX (inex_re, inex_im);
+ }
+ else
+ inex_sin = MPC_INEX (0,0); /* return exact if not computed */
+
+ if (rop_cos != NULL) {
+ inex_re = mpfr_set (mpc_realref (rop_cos), c, MPC_RND_RE (rnd_cos));
+ if (mpfr_inf_p (c))
+ inex_re = mpfr_sgn (c);
+ inex_im = mpfr_set (mpc_imagref (rop_cos), s, MPC_RND_IM (rnd_cos));
+ if (mpfr_inf_p (s))
+ inex_im = mpfr_sgn (s);
+ inex_cos = MPC_INEX (inex_re, inex_im);
+ }
+ else
+ inex_cos = MPC_INEX (0,0); /* return exact if not computed */
+
+ mpfr_clear (s);
+ mpfr_clear (c);
+ mpfr_clear (sh);
+ mpfr_clear (ch);
+ mpfr_clear (sch);
+ mpfr_clear (csh);
+
+ return (MPC_INEX12 (inex_sin, inex_cos));
+ }
+}
diff --git a/mpc/src/sinh.c b/mpc/src/sinh.c
new file mode 100644
index 0000000000..509cc57dea
--- /dev/null
+++ b/mpc/src/sinh.c
@@ -0,0 +1,47 @@
+/* mpc_sinh -- hyperbolic sine of a complex number.
+
+Copyright (C)2008, 2009, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_sinh (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ /* sinh(op) = -i*sin(i*op) = conj(-i*sin(conj(-i*op))) */
+ mpc_t z;
+ mpc_t sin_z;
+ int inex;
+
+ /* z := conj(-i * op) and rop = conj(-i * sin(z)), in other words, we have
+ to switch real and imaginary parts. Let us set them without copying
+ significands. */
+ mpc_realref (z)[0] = mpc_imagref (op)[0];
+ mpc_imagref (z)[0] = mpc_realref (op)[0];
+ mpc_realref (sin_z)[0] = mpc_imagref (rop)[0];
+ mpc_imagref (sin_z)[0] = mpc_realref (rop)[0];
+
+ inex = mpc_sin (sin_z, z, MPC_RND (MPC_RND_IM (rnd), MPC_RND_RE (rnd)));
+
+ /* sin_z and rop parts share the same significands, copy the rest now. */
+ mpc_realref (rop)[0] = mpc_imagref (sin_z)[0];
+ mpc_imagref (rop)[0] = mpc_realref (sin_z)[0];
+
+ /* swap inexact flags for real and imaginary parts */
+ return MPC_INEX (MPC_INEX_IM (inex), MPC_INEX_RE (inex));
+}
diff --git a/mpc/src/sqr.c b/mpc/src/sqr.c
new file mode 100644
index 0000000000..f1ce1bac8a
--- /dev/null
+++ b/mpc/src/sqr.c
@@ -0,0 +1,324 @@
+/* mpc_sqr -- Square a complex number.
+
+Copyright (C) 2002, 2005, 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for MPC_ASSERT */
+#include "mpc-impl.h"
+
+
+static int
+mpfr_fsss (mpfr_ptr z, mpfr_srcptr a, mpfr_srcptr c, mpfr_rnd_t rnd)
+{
+ /* Computes z = a^2 - c^2.
+ Assumes that a and c are finite and non-zero; so a squaring yielding
+ an infinity is an overflow, and a squaring yielding 0 is an underflow.
+ Assumes further that z is distinct from a and c. */
+
+ int inex;
+ mpfr_t u, v;
+
+ /* u=a^2, v=c^2 exactly */
+ mpfr_init2 (u, 2*mpfr_get_prec (a));
+ mpfr_init2 (v, 2*mpfr_get_prec (c));
+ mpfr_sqr (u, a, GMP_RNDN);
+ mpfr_sqr (v, c, GMP_RNDN);
+
+ /* tentatively compute z as u-v; here we need z to be distinct
+ from a and c to not lose the latter */
+ inex = mpfr_sub (z, u, v, rnd);
+
+ if (mpfr_inf_p (z)) {
+ /* replace by "correctly rounded overflow" */
+ mpfr_set_si (z, (mpfr_signbit (z) ? -1 : 1), GMP_RNDN);
+ inex = mpfr_mul_2ui (z, z, mpfr_get_emax (), rnd);
+ }
+ else if (mpfr_zero_p (u) && !mpfr_zero_p (v)) {
+ /* exactly u underflowed, determine inexact flag */
+ inex = (mpfr_signbit (u) ? 1 : -1);
+ }
+ else if (mpfr_zero_p (v) && !mpfr_zero_p (u)) {
+ /* exactly v underflowed, determine inexact flag */
+ inex = (mpfr_signbit (v) ? -1 : 1);
+ }
+ else if (mpfr_nan_p (z) || (mpfr_zero_p (u) && mpfr_zero_p (v))) {
+ /* In the first case, u and v are +inf.
+ In the second case, u and v are zeroes; their difference may be 0
+ or the least representable number, with a sign to be determined.
+ Redo the computations with mpz_t exponents */
+ mpfr_exp_t ea, ec;
+ mpz_t eu, ev;
+ /* cheat to work around the const qualifiers */
+
+ /* Normalise the input by shifting and keep track of the shifts in
+ the exponents of u and v */
+ ea = mpfr_get_exp (a);
+ ec = mpfr_get_exp (c);
+
+ mpfr_set_exp ((mpfr_ptr) a, (mpfr_prec_t) 0);
+ mpfr_set_exp ((mpfr_ptr) c, (mpfr_prec_t) 0);
+
+ mpz_init (eu);
+ mpz_init (ev);
+ mpz_set_si (eu, (long int) ea);
+ mpz_mul_2exp (eu, eu, 1);
+ mpz_set_si (ev, (long int) ec);
+ mpz_mul_2exp (ev, ev, 1);
+
+ /* recompute u and v and move exponents to eu and ev */
+ mpfr_sqr (u, a, GMP_RNDN);
+ /* exponent of u is non-positive */
+ mpz_sub_ui (eu, eu, (unsigned long int) (-mpfr_get_exp (u)));
+ mpfr_set_exp (u, (mpfr_prec_t) 0);
+ mpfr_sqr (v, c, GMP_RNDN);
+ mpz_sub_ui (ev, ev, (unsigned long int) (-mpfr_get_exp (v)));
+ mpfr_set_exp (v, (mpfr_prec_t) 0);
+ if (mpfr_nan_p (z)) {
+ mpfr_exp_t emax = mpfr_get_emax ();
+ int overflow;
+ /* We have a = ma * 2^ea with 1/2 <= |ma| < 1 and ea <= emax.
+ So eu <= 2*emax, and eu > emax since we have
+ an overflow. The same holds for ev. Shift u and v by as much as
+ possible so that one of them has exponent emax and the
+ remaining exponents in eu and ev are the same. Then carry out
+ the addition. Shifting u and v prevents an underflow. */
+ if (mpz_cmp (eu, ev) >= 0) {
+ mpfr_set_exp (u, emax);
+ mpz_sub_ui (eu, eu, (long int) emax);
+ mpz_sub (ev, ev, eu);
+ mpfr_set_exp (v, (mpfr_exp_t) mpz_get_ui (ev));
+ /* remaining common exponent is now in eu */
+ }
+ else {
+ mpfr_set_exp (v, emax);
+ mpz_sub_ui (ev, ev, (long int) emax);
+ mpz_sub (eu, eu, ev);
+ mpfr_set_exp (u, (mpfr_exp_t) mpz_get_ui (eu));
+ mpz_set (eu, ev);
+ /* remaining common exponent is now also in eu */
+ }
+ inex = mpfr_sub (z, u, v, rnd);
+ /* Result is finite since u and v have the same sign. */
+ overflow = mpfr_mul_2ui (z, z, mpz_get_ui (eu), rnd);
+ if (overflow)
+ inex = overflow;
+ }
+ else {
+ int underflow;
+ /* Subtraction of two zeroes. We have a = ma * 2^ea
+ with 1/2 <= |ma| < 1 and ea >= emin and similarly for b.
+ So 2*emin < 2*emin+1 <= eu < emin < 0, and analogously for v. */
+ mpfr_exp_t emin = mpfr_get_emin ();
+ if (mpz_cmp (eu, ev) <= 0) {
+ mpfr_set_exp (u, emin);
+ mpz_add_ui (eu, eu, (unsigned long int) (-emin));
+ mpz_sub (ev, ev, eu);
+ mpfr_set_exp (v, (mpfr_exp_t) mpz_get_si (ev));
+ }
+ else {
+ mpfr_set_exp (v, emin);
+ mpz_add_ui (ev, ev, (unsigned long int) (-emin));
+ mpz_sub (eu, eu, ev);
+ mpfr_set_exp (u, (mpfr_exp_t) mpz_get_si (eu));
+ mpz_set (eu, ev);
+ }
+ inex = mpfr_sub (z, u, v, rnd);
+ mpz_neg (eu, eu);
+ underflow = mpfr_div_2ui (z, z, mpz_get_ui (eu), rnd);
+ if (underflow)
+ inex = underflow;
+ }
+
+ mpz_clear (eu);
+ mpz_clear (ev);
+
+ mpfr_set_exp ((mpfr_ptr) a, ea);
+ mpfr_set_exp ((mpfr_ptr) c, ec);
+ /* works also when a == c */
+ }
+
+ mpfr_clear (u);
+ mpfr_clear (v);
+
+ return inex;
+}
+
+
+int
+mpc_sqr (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ int ok;
+ mpfr_t u, v;
+ mpfr_t x;
+ /* temporary variable to hold the real part of op,
+ needed in the case rop==op */
+ mpfr_prec_t prec;
+ int inex_re, inex_im, inexact;
+ mpfr_exp_t emin;
+ int saved_underflow;
+
+ /* special values: NaN and infinities */
+ if (!mpc_fin_p (op)) {
+ if (mpfr_nan_p (mpc_realref (op)) || mpfr_nan_p (mpc_imagref (op))) {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ }
+ else if (mpfr_inf_p (mpc_realref (op))) {
+ if (mpfr_inf_p (mpc_imagref (op))) {
+ mpfr_set_inf (mpc_imagref (rop),
+ MPFR_SIGN (mpc_realref (op)) * MPFR_SIGN (mpc_imagref (op)));
+ mpfr_set_nan (mpc_realref (rop));
+ }
+ else {
+ if (mpfr_zero_p (mpc_imagref (op)))
+ mpfr_set_nan (mpc_imagref (rop));
+ else
+ mpfr_set_inf (mpc_imagref (rop),
+ MPFR_SIGN (mpc_realref (op)) * MPFR_SIGN (mpc_imagref (op)));
+ mpfr_set_inf (mpc_realref (rop), +1);
+ }
+ }
+ else /* IM(op) is infinity, RE(op) is not */ {
+ if (mpfr_zero_p (mpc_realref (op)))
+ mpfr_set_nan (mpc_imagref (rop));
+ else
+ mpfr_set_inf (mpc_imagref (rop),
+ MPFR_SIGN (mpc_realref (op)) * MPFR_SIGN (mpc_imagref (op)));
+ mpfr_set_inf (mpc_realref (rop), -1);
+ }
+ return MPC_INEX (0, 0); /* exact */
+ }
+
+ prec = MPC_MAX_PREC(rop);
+
+ /* Check for real resp. purely imaginary number */
+ if (mpfr_zero_p (mpc_imagref(op))) {
+ int same_sign = mpfr_signbit (mpc_realref (op)) == mpfr_signbit (mpc_imagref (op));
+ inex_re = mpfr_sqr (mpc_realref(rop), mpc_realref(op), MPC_RND_RE(rnd));
+ inex_im = mpfr_set_ui (mpc_imagref(rop), 0ul, GMP_RNDN);
+ if (!same_sign)
+ mpc_conj (rop, rop, MPC_RNDNN);
+ return MPC_INEX(inex_re, inex_im);
+ }
+ if (mpfr_zero_p (mpc_realref(op))) {
+ int same_sign = mpfr_signbit (mpc_realref (op)) == mpfr_signbit (mpc_imagref (op));
+ inex_re = -mpfr_sqr (mpc_realref(rop), mpc_imagref(op), INV_RND (MPC_RND_RE(rnd)));
+ mpfr_neg (mpc_realref(rop), mpc_realref(rop), GMP_RNDN);
+ inex_im = mpfr_set_ui (mpc_imagref(rop), 0ul, GMP_RNDN);
+ if (!same_sign)
+ mpc_conj (rop, rop, MPC_RNDNN);
+ return MPC_INEX(inex_re, inex_im);
+ }
+
+ if (rop == op)
+ {
+ mpfr_init2 (x, MPC_PREC_RE (op));
+ mpfr_set (x, op->re, GMP_RNDN);
+ }
+ else
+ x [0] = op->re [0];
+ /* From here on, use x instead of op->re and safely overwrite rop->re. */
+
+ /* Compute real part of result. */
+ if (SAFE_ABS (mpfr_exp_t,
+ mpfr_get_exp (mpc_realref (op)) - mpfr_get_exp (mpc_imagref (op)))
+ > (mpfr_exp_t) MPC_MAX_PREC (op) / 2) {
+ /* If the real and imaginary parts of the argument have very different
+ exponents, it is not reasonable to use Karatsuba squaring; compute
+ exactly with the standard formulae instead, even if this means an
+ additional multiplication. Using the approach copied from mul, over-
+ and underflows are also handled correctly. */
+
+ inex_re = mpfr_fsss (rop->re, x, op->im, MPC_RND_RE (rnd));
+ }
+ else {
+ /* Karatsuba squaring: we compute the real part as (x+y)*(x-y) and the
+ imaginary part as 2*x*y, with a total of 2M instead of 2S+1M for the
+ naive algorithm, which computes x^2-y^2 and 2*y*y */
+ mpfr_init (u);
+ mpfr_init (v);
+
+ emin = mpfr_get_emin ();
+
+ do
+ {
+ prec += mpc_ceil_log2 (prec) + 5;
+
+ mpfr_set_prec (u, prec);
+ mpfr_set_prec (v, prec);
+
+ /* Let op = x + iy. We need u = x+y and v = x-y, rounded away. */
+ /* The error is bounded above by 1 ulp. */
+ /* We first let inexact be 1 if the real part is not computed */
+ /* exactly and determine the sign later. */
+ inexact = ROUND_AWAY (mpfr_add (u, x, mpc_imagref (op), MPFR_RNDA), u)
+ | ROUND_AWAY (mpfr_sub (v, x, mpc_imagref (op), MPFR_RNDA), v);
+
+ /* compute the real part as u*v, rounded away */
+ /* determine also the sign of inex_re */
+
+ if (mpfr_sgn (u) == 0 || mpfr_sgn (v) == 0) {
+ /* as we have rounded away, the result is exact */
+ mpfr_set_ui (mpc_realref (rop), 0, GMP_RNDN);
+ inex_re = 0;
+ ok = 1;
+ }
+ else {
+ mpfr_rnd_t rnd_away;
+ /* FIXME: can be replaced by MPFR_RNDA in mpfr >= 3 */
+ rnd_away = (mpfr_sgn (u) * mpfr_sgn (v) > 0 ? GMP_RNDU : GMP_RNDD);
+ inexact |= ROUND_AWAY (mpfr_mul (u, u, v, MPFR_RNDA), u); /* error 5 */
+ if (mpfr_get_exp (u) == emin || mpfr_inf_p (u)) {
+ /* under- or overflow */
+ inex_re = mpfr_fsss (rop->re, x, op->im, MPC_RND_RE (rnd));
+ ok = 1;
+ }
+ else {
+ ok = (!inexact) | mpfr_can_round (u, prec - 3,
+ rnd_away, GMP_RNDZ,
+ MPC_PREC_RE (rop) + (MPC_RND_RE (rnd) == GMP_RNDN));
+ if (ok) {
+ inex_re = mpfr_set (mpc_realref (rop), u, MPC_RND_RE (rnd));
+ if (inex_re == 0)
+ /* remember that u was already rounded */
+ inex_re = inexact;
+ }
+ }
+ }
+ }
+ while (!ok);
+
+ mpfr_clear (u);
+ mpfr_clear (v);
+ }
+
+ saved_underflow = mpfr_underflow_p ();
+ mpfr_clear_underflow ();
+ inex_im = mpfr_mul (rop->im, x, op->im, MPC_RND_IM (rnd));
+ if (!mpfr_underflow_p ())
+ inex_im |= mpfr_mul_2ui (rop->im, rop->im, 1, MPC_RND_IM (rnd));
+ /* We must not multiply by 2 if rop->im has been set to the smallest
+ representable number. */
+ if (saved_underflow)
+ mpfr_set_underflow ();
+
+ if (rop == op)
+ mpfr_clear (x);
+
+ return MPC_INEX (inex_re, inex_im);
+}
diff --git a/mpc/src/sqrt.c b/mpc/src/sqrt.c
new file mode 100644
index 0000000000..dd2ff60034
--- /dev/null
+++ b/mpc/src/sqrt.c
@@ -0,0 +1,364 @@
+/* mpc_sqrt -- Take the square root of a complex number.
+
+Copyright (C) 2002, 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+#if MPFR_VERSION_MAJOR < 3
+#define mpfr_min_prec(x) \
+ ( ((prec + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB) * BITS_PER_MP_LIMB \
+ - mpn_scan1 (x->_mpfr_d, 0))
+#endif
+
+
+int
+mpc_sqrt (mpc_ptr a, mpc_srcptr b, mpc_rnd_t rnd)
+{
+ int ok_w, ok_t = 0;
+ mpfr_t w, t;
+ mpfr_rnd_t rnd_w, rnd_t;
+ mpfr_prec_t prec_w, prec_t;
+ /* the rounding mode and the precision required for w and t, which can */
+ /* be either the real or the imaginary part of a */
+ mpfr_prec_t prec;
+ int inex_w, inex_t = 1, inex_re, inex_im, loops = 0;
+ const int re_cmp = mpfr_cmp_ui (mpc_realref (b), 0),
+ im_cmp = mpfr_cmp_ui (mpc_imagref (b), 0);
+ /* comparison of the real/imaginary part of b with 0 */
+ int repr_w, repr_t = 0 /* to avoid gcc warning */ ;
+ /* flag indicating whether the computed value is already representable
+ at the target precision */
+ const int im_sgn = mpfr_signbit (mpc_imagref (b)) == 0 ? 0 : -1;
+ /* we need to know the sign of Im(b) when it is +/-0 */
+ const mpfr_rnd_t r = im_sgn ? GMP_RNDD : GMP_RNDU;
+ /* rounding mode used when computing t */
+
+ /* special values */
+ if (!mpc_fin_p (b)) {
+ /* sqrt(x +i*Inf) = +Inf +I*Inf, even if x = NaN */
+ /* sqrt(x -i*Inf) = +Inf -I*Inf, even if x = NaN */
+ if (mpfr_inf_p (mpc_imagref (b)))
+ {
+ mpfr_set_inf (mpc_realref (a), +1);
+ mpfr_set_inf (mpc_imagref (a), im_sgn);
+ return MPC_INEX (0, 0);
+ }
+
+ if (mpfr_inf_p (mpc_realref (b)))
+ {
+ if (mpfr_signbit (mpc_realref (b)))
+ {
+ if (mpfr_number_p (mpc_imagref (b)))
+ {
+ /* sqrt(-Inf +i*y) = +0 +i*Inf, when y positive */
+ /* sqrt(-Inf +i*y) = +0 -i*Inf, when y positive */
+ mpfr_set_ui (mpc_realref (a), 0, GMP_RNDN);
+ mpfr_set_inf (mpc_imagref (a), im_sgn);
+ return MPC_INEX (0, 0);
+ }
+ else
+ {
+ /* sqrt(-Inf +i*NaN) = NaN +/-i*Inf */
+ mpfr_set_nan (mpc_realref (a));
+ mpfr_set_inf (mpc_imagref (a), im_sgn);
+ return MPC_INEX (0, 0);
+ }
+ }
+ else
+ {
+ if (mpfr_number_p (mpc_imagref (b)))
+ {
+ /* sqrt(+Inf +i*y) = +Inf +i*0, when y positive */
+ /* sqrt(+Inf +i*y) = +Inf -i*0, when y positive */
+ mpfr_set_inf (mpc_realref (a), +1);
+ mpfr_set_ui (mpc_imagref (a), 0, GMP_RNDN);
+ if (im_sgn)
+ mpc_conj (a, a, MPC_RNDNN);
+ return MPC_INEX (0, 0);
+ }
+ else
+ {
+ /* sqrt(+Inf -i*Inf) = +Inf -i*Inf */
+ /* sqrt(+Inf +i*Inf) = +Inf +i*Inf */
+ /* sqrt(+Inf +i*NaN) = +Inf +i*NaN */
+ return mpc_set (a, b, rnd);
+ }
+ }
+ }
+
+ /* sqrt(x +i*NaN) = NaN +i*NaN, if x is not infinite */
+ /* sqrt(NaN +i*y) = NaN +i*NaN, if y is not infinite */
+ if (mpfr_nan_p (mpc_realref (b)) || mpfr_nan_p (mpc_imagref (b)))
+ {
+ mpfr_set_nan (mpc_realref (a));
+ mpfr_set_nan (mpc_imagref (a));
+ return MPC_INEX (0, 0);
+ }
+ }
+
+ /* purely real */
+ if (im_cmp == 0)
+ {
+ if (re_cmp == 0)
+ {
+ mpc_set_ui_ui (a, 0, 0, MPC_RNDNN);
+ if (im_sgn)
+ mpc_conj (a, a, MPC_RNDNN);
+ return MPC_INEX (0, 0);
+ }
+ else if (re_cmp > 0)
+ {
+ inex_w = mpfr_sqrt (mpc_realref (a), mpc_realref (b), MPC_RND_RE (rnd));
+ mpfr_set_ui (mpc_imagref (a), 0, GMP_RNDN);
+ if (im_sgn)
+ mpc_conj (a, a, MPC_RNDNN);
+ return MPC_INEX (inex_w, 0);
+ }
+ else
+ {
+ mpfr_init2 (w, MPC_PREC_RE (b));
+ mpfr_neg (w, mpc_realref (b), GMP_RNDN);
+ if (im_sgn)
+ {
+ inex_w = -mpfr_sqrt (mpc_imagref (a), w, INV_RND (MPC_RND_IM (rnd)));
+ mpfr_neg (mpc_imagref (a), mpc_imagref (a), GMP_RNDN);
+ }
+ else
+ inex_w = mpfr_sqrt (mpc_imagref (a), w, MPC_RND_IM (rnd));
+
+ mpfr_set_ui (mpc_realref (a), 0, GMP_RNDN);
+ mpfr_clear (w);
+ return MPC_INEX (0, inex_w);
+ }
+ }
+
+ /* purely imaginary */
+ if (re_cmp == 0)
+ {
+ mpfr_t y;
+
+ y[0] = mpc_imagref (b)[0];
+ /* If y/2 underflows, so does sqrt(y/2) */
+ mpfr_div_2ui (y, y, 1, GMP_RNDN);
+ if (im_cmp > 0)
+ {
+ inex_w = mpfr_sqrt (mpc_realref (a), y, MPC_RND_RE (rnd));
+ inex_t = mpfr_sqrt (mpc_imagref (a), y, MPC_RND_IM (rnd));
+ }
+ else
+ {
+ mpfr_neg (y, y, GMP_RNDN);
+ inex_w = mpfr_sqrt (mpc_realref (a), y, MPC_RND_RE (rnd));
+ inex_t = -mpfr_sqrt (mpc_imagref (a), y, INV_RND (MPC_RND_IM (rnd)));
+ mpfr_neg (mpc_imagref (a), mpc_imagref (a), GMP_RNDN);
+ }
+ return MPC_INEX (inex_w, inex_t);
+ }
+
+ prec = MPC_MAX_PREC(a);
+
+ mpfr_init (w);
+ mpfr_init (t);
+
+ if (re_cmp > 0) {
+ rnd_w = MPC_RND_RE (rnd);
+ prec_w = MPC_PREC_RE (a);
+ rnd_t = MPC_RND_IM(rnd);
+ if (rnd_t == GMP_RNDZ)
+ /* force GMP_RNDD or GMP_RNDUP, using sign(t) = sign(y) */
+ rnd_t = (im_cmp > 0 ? GMP_RNDD : GMP_RNDU);
+ prec_t = MPC_PREC_IM (a);
+ }
+ else {
+ prec_w = MPC_PREC_IM (a);
+ prec_t = MPC_PREC_RE (a);
+ if (im_cmp > 0) {
+ rnd_w = MPC_RND_IM(rnd);
+ rnd_t = MPC_RND_RE(rnd);
+ if (rnd_t == GMP_RNDZ)
+ rnd_t = GMP_RNDD;
+ }
+ else {
+ rnd_w = INV_RND(MPC_RND_IM (rnd));
+ rnd_t = INV_RND(MPC_RND_RE (rnd));
+ if (rnd_t == GMP_RNDZ)
+ rnd_t = GMP_RNDU;
+ }
+ }
+
+ do
+ {
+ loops ++;
+ prec += (loops <= 2) ? mpc_ceil_log2 (prec) + 4 : prec / 2;
+ mpfr_set_prec (w, prec);
+ mpfr_set_prec (t, prec);
+ /* let b = x + iy */
+ /* w = sqrt ((|x| + sqrt (x^2 + y^2)) / 2), rounded down */
+ /* total error bounded by 3 ulps */
+ inex_w = mpc_abs (w, b, GMP_RNDD);
+ if (re_cmp < 0)
+ inex_w |= mpfr_sub (w, w, mpc_realref (b), GMP_RNDD);
+ else
+ inex_w |= mpfr_add (w, w, mpc_realref (b), GMP_RNDD);
+ inex_w |= mpfr_div_2ui (w, w, 1, GMP_RNDD);
+ inex_w |= mpfr_sqrt (w, w, GMP_RNDD);
+
+ repr_w = mpfr_min_prec (w) <= prec_w;
+ if (!repr_w)
+ /* use the usual trick for obtaining the ternary value */
+ ok_w = mpfr_can_round (w, prec - 2, GMP_RNDD, GMP_RNDU,
+ prec_w + (rnd_w == GMP_RNDN));
+ else {
+ /* w is representable in the target precision and thus cannot be
+ rounded up */
+ if (rnd_w == GMP_RNDN)
+ /* If w can be rounded to nearest, then actually no rounding
+ occurs, and the ternary value is known from inex_w. */
+ ok_w = mpfr_can_round (w, prec - 2, GMP_RNDD, GMP_RNDN, prec_w);
+ else
+ /* If w can be rounded down, then any direct rounding and the
+ ternary flag can be determined from inex_w. */
+ ok_w = mpfr_can_round (w, prec - 2, GMP_RNDD, GMP_RNDD, prec_w);
+ }
+
+ if (!inex_w || ok_w) {
+ /* t = y / 2w, rounded away */
+ /* total error bounded by 7 ulps */
+ inex_t = mpfr_div (t, mpc_imagref (b), w, r);
+ if (!inex_t && inex_w)
+ /* The division was exact, but w was not. */
+ inex_t = im_sgn ? -1 : 1;
+ inex_t |= mpfr_div_2ui (t, t, 1, r);
+ repr_t = mpfr_min_prec (t) <= prec_t;
+ if (!repr_t)
+ /* As for w; since t was rounded away, we check whether rounding to 0
+ is possible. */
+ ok_t = mpfr_can_round (t, prec - 3, r, GMP_RNDZ,
+ prec_t + (rnd_t == GMP_RNDN));
+ else {
+ if (rnd_t == GMP_RNDN)
+ ok_t = mpfr_can_round (t, prec - 3, r, GMP_RNDN, prec_t);
+ else
+ ok_t = mpfr_can_round (t, prec - 3, r, r, prec_t);
+ }
+ }
+ }
+ while ((inex_w && !ok_w) || (inex_t && !ok_t));
+
+ if (re_cmp > 0) {
+ inex_re = mpfr_set (mpc_realref (a), w, MPC_RND_RE(rnd));
+ inex_im = mpfr_set (mpc_imagref (a), t, MPC_RND_IM(rnd));
+ }
+ else if (im_cmp > 0) {
+ inex_re = mpfr_set (mpc_realref(a), t, MPC_RND_RE(rnd));
+ inex_im = mpfr_set (mpc_imagref(a), w, MPC_RND_IM(rnd));
+ }
+ else {
+ inex_re = mpfr_neg (mpc_realref (a), t, MPC_RND_RE(rnd));
+ inex_im = mpfr_neg (mpc_imagref (a), w, MPC_RND_IM(rnd));
+ }
+
+ if (repr_w && inex_w) {
+ if (rnd_w == GMP_RNDN) {
+ /* w has not been rounded with mpfr_set/mpfr_neg, determine ternary
+ value from inex_w instead */
+ if (re_cmp > 0)
+ inex_re = inex_w;
+ else if (im_cmp > 0)
+ inex_im = inex_w;
+ else
+ inex_im = -inex_w;
+ }
+ else {
+ /* determine ternary value, but also potentially add 1 ulp; can only
+ be done now when we are in the target precision */
+ if (re_cmp > 0) {
+ if (rnd_w == GMP_RNDU) {
+ MPFR_ADD_ONE_ULP (mpc_realref (a));
+ inex_re = +1;
+ }
+ else
+ inex_re = -1;
+ }
+ else if (im_cmp > 0) {
+ if (rnd_w == GMP_RNDU) {
+ MPFR_ADD_ONE_ULP (mpc_imagref (a));
+ inex_im = +1;
+ }
+ else
+ inex_im = -1;
+ }
+ else {
+ if (rnd_w == GMP_RNDU) {
+ MPFR_ADD_ONE_ULP (mpc_imagref (a));
+ inex_im = -1;
+ }
+ else
+ inex_im = +1;
+ }
+ }
+ }
+ if (repr_t && inex_t) {
+ if (rnd_t == GMP_RNDN) {
+ if (re_cmp > 0)
+ inex_im = inex_t;
+ else if (im_cmp > 0)
+ inex_re = inex_t;
+ else
+ inex_re = -inex_t;
+ }
+ else {
+ if (re_cmp > 0) {
+ if (rnd_t == r)
+ inex_im = inex_t;
+ else {
+ inex_im = -inex_t;
+ /* im_cmp > 0 implies that Im(b) > 0, thus im_sgn = 0
+ and r = GMP_RNDU.
+ im_cmp < 0 implies that Im(b) < 0, thus im_sgn = -1
+ and r = GMP_RNDD. */
+ MPFR_SUB_ONE_ULP (mpc_imagref (a));
+ }
+ }
+ else if (im_cmp > 0) {
+ if (rnd_t == r)
+ inex_re = inex_t;
+ else {
+ inex_re = -inex_t;
+ /* im_cmp > 0 implies r = GMP_RNDU (see above) */
+ MPFR_SUB_ONE_ULP (mpc_realref (a));
+ }
+ }
+ else { /* im_cmp < 0 */
+ if (rnd_t == r)
+ inex_re = -inex_t;
+ else {
+ inex_re = inex_t;
+ /* im_cmp < 0 implies r = GMP_RNDD (see above) */
+ MPFR_SUB_ONE_ULP (mpc_realref (a));
+ }
+ }
+ }
+ }
+
+ mpfr_clear (w);
+ mpfr_clear (t);
+
+ return MPC_INEX (inex_re, inex_im);
+}
diff --git a/mpc/src/strtoc.c b/mpc/src/strtoc.c
new file mode 100644
index 0000000000..b96ccee528
--- /dev/null
+++ b/mpc/src/strtoc.c
@@ -0,0 +1,89 @@
+/* mpc_strtoc -- Read a complex number from a string.
+
+Copyright (C) 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <string.h>
+#include <ctype.h>
+#include "mpc-impl.h"
+
+static void
+skip_whitespace (const char **p)
+{
+ /* TODO: This function had better be inlined, but it is unclear whether
+ the hassle to get this implemented across all platforms is worth it. */
+ while (isspace ((unsigned char) **p))
+ (*p)++;
+}
+
+int
+mpc_strtoc (mpc_ptr rop, const char *nptr, char **endptr, int base, mpc_rnd_t rnd)
+{
+ const char *p;
+ char *end;
+ int bracketed = 0;
+
+ int inex_re = 0, inex_im = 0;
+
+ if (nptr == NULL || base > 36 || base == 1)
+ goto error;
+
+ p = nptr;
+ skip_whitespace (&p);
+
+ if (*p == '('){
+ bracketed = 1;
+ ++p;
+ }
+
+ inex_re = mpfr_strtofr (mpc_realref(rop), p, &end, base, MPC_RND_RE (rnd));
+ if (end == p)
+ goto error;
+ p = end;
+
+ if (!bracketed)
+ inex_im = mpfr_set_ui (mpc_imagref (rop), 0ul, GMP_RNDN);
+ else {
+ if (!isspace ((unsigned char)*p))
+ goto error;
+
+ skip_whitespace (&p);
+
+ inex_im = mpfr_strtofr (mpc_imagref(rop), p, &end, base, MPC_RND_IM (rnd));
+ if (end == p)
+ goto error;
+ p = end;
+
+ skip_whitespace (&p);
+ if (*p != ')')
+ goto error;
+
+ p++;
+ }
+
+ if (endptr != NULL)
+ *endptr = (char*) p;
+ return MPC_INEX (inex_re, inex_im);
+
+error:
+ if (endptr != NULL)
+ *endptr = (char*) nptr;
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ return -1;
+}
diff --git a/mpc/src/sub.c b/mpc/src/sub.c
new file mode 100644
index 0000000000..8b8a97d24f
--- /dev/null
+++ b/mpc/src/sub.c
@@ -0,0 +1,32 @@
+/* mpc_sub -- Subtract two complex numbers.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_sub (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_sub (mpc_realref(a), mpc_realref(b), mpc_realref(c), MPC_RND_RE(rnd));
+ inex_im = mpfr_sub (mpc_imagref(a), mpc_imagref(b), mpc_imagref(c), MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/sub_fr.c b/mpc/src/sub_fr.c
new file mode 100644
index 0000000000..ade33a95cd
--- /dev/null
+++ b/mpc/src/sub_fr.c
@@ -0,0 +1,34 @@
+/* mpc_sub_fr -- Substract a floating-point number to the real part of a
+ complex number.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* return 0 iff both the real and imaginary parts are exact */
+int
+mpc_sub_fr (mpc_ptr a, mpc_srcptr b, mpfr_srcptr c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_sub (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_set (mpc_imagref(a), mpc_imagref(b), MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/sub_ui.c b/mpc/src/sub_ui.c
new file mode 100644
index 0000000000..561c469676
--- /dev/null
+++ b/mpc/src/sub_ui.c
@@ -0,0 +1,33 @@
+/* mpc_sub_ui -- Add a complex number and an unsigned long int.
+
+Copyright (C) 2002, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* return 0 iff both the real and imaginary parts are exact */
+int
+mpc_sub_ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_sub_ui (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
+ inex_im = mpfr_set (mpc_imagref(a), mpc_imagref(b), MPC_RND_IM(rnd));
+
+ return MPC_INEX(inex_re, inex_im);
+}
diff --git a/mpc/src/swap.c b/mpc/src/swap.c
new file mode 100644
index 0000000000..9590132e3b
--- /dev/null
+++ b/mpc/src/swap.c
@@ -0,0 +1,29 @@
+/* mpc_swap -- Swap two complex numbers.
+
+Copyright (C) 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+void
+mpc_swap (mpc_ptr a, mpc_ptr b)
+{
+ /* assumes real and imaginary parts do not overlap */
+ mpfr_swap (mpc_realref(a), mpc_realref(b));
+ mpfr_swap (mpc_imagref(a), mpc_imagref(b));
+}
diff --git a/mpc/src/tan.c b/mpc/src/tan.c
new file mode 100644
index 0000000000..24cd92b7ce
--- /dev/null
+++ b/mpc/src/tan.c
@@ -0,0 +1,284 @@
+/* mpc_tan -- tangent of a complex number.
+
+Copyright (C) 2008, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdio.h> /* for MPC_ASSERT */
+#include <limits.h>
+#include "mpc-impl.h"
+
+int
+mpc_tan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ mpc_t x, y;
+ mpfr_prec_t prec;
+ mpfr_exp_t err;
+ int ok = 0;
+ int inex;
+
+ /* special values */
+ if (!mpc_fin_p (op))
+ {
+ if (mpfr_nan_p (mpc_realref (op)))
+ {
+ if (mpfr_inf_p (mpc_imagref (op)))
+ /* tan(NaN -i*Inf) = +/-0 -i */
+ /* tan(NaN +i*Inf) = +/-0 +i */
+ {
+ /* exact unless 1 is not in exponent range */
+ inex = mpc_set_si_si (rop, 0,
+ (MPFR_SIGN (mpc_imagref (op)) < 0) ? -1 : +1,
+ rnd);
+ }
+ else
+ /* tan(NaN +i*y) = NaN +i*NaN, when y is finite */
+ /* tan(NaN +i*NaN) = NaN +i*NaN */
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ inex = MPC_INEX (0, 0); /* always exact */
+ }
+ }
+ else if (mpfr_nan_p (mpc_imagref (op)))
+ {
+ if (mpfr_cmp_ui (mpc_realref (op), 0) == 0)
+ /* tan(-0 +i*NaN) = -0 +i*NaN */
+ /* tan(+0 +i*NaN) = +0 +i*NaN */
+ {
+ mpc_set (rop, op, rnd);
+ inex = MPC_INEX (0, 0); /* always exact */
+ }
+ else
+ /* tan(x +i*NaN) = NaN +i*NaN, when x != 0 */
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ inex = MPC_INEX (0, 0); /* always exact */
+ }
+ }
+ else if (mpfr_inf_p (mpc_realref (op)))
+ {
+ if (mpfr_inf_p (mpc_imagref (op)))
+ /* tan(-Inf -i*Inf) = -/+0 -i */
+ /* tan(-Inf +i*Inf) = -/+0 +i */
+ /* tan(+Inf -i*Inf) = +/-0 -i */
+ /* tan(+Inf +i*Inf) = +/-0 +i */
+ {
+ const int sign_re = mpfr_signbit (mpc_realref (op));
+ int inex_im;
+
+ mpfr_set_ui (mpc_realref (rop), 0, MPC_RND_RE (rnd));
+ mpfr_setsign (mpc_realref (rop), mpc_realref (rop), sign_re, GMP_RNDN);
+
+ /* exact, unless 1 is not in exponent range */
+ inex_im = mpfr_set_si (mpc_imagref (rop),
+ mpfr_signbit (mpc_imagref (op)) ? -1 : +1,
+ MPC_RND_IM (rnd));
+ inex = MPC_INEX (0, inex_im);
+ }
+ else
+ /* tan(-Inf +i*y) = tan(+Inf +i*y) = NaN +i*NaN, when y is
+ finite */
+ {
+ mpfr_set_nan (mpc_realref (rop));
+ mpfr_set_nan (mpc_imagref (rop));
+ inex = MPC_INEX (0, 0); /* always exact */
+ }
+ }
+ else
+ /* tan(x -i*Inf) = +0*sin(x)*cos(x) -i, when x is finite */
+ /* tan(x +i*Inf) = +0*sin(x)*cos(x) +i, when x is finite */
+ {
+ mpfr_t c;
+ mpfr_t s;
+ int inex_im;
+
+ mpfr_init (c);
+ mpfr_init (s);
+
+ mpfr_sin_cos (s, c, mpc_realref (op), GMP_RNDN);
+ mpfr_set_ui (mpc_realref (rop), 0, MPC_RND_RE (rnd));
+ mpfr_setsign (mpc_realref (rop), mpc_realref (rop),
+ mpfr_signbit (c) != mpfr_signbit (s), GMP_RNDN);
+ /* exact, unless 1 is not in exponent range */
+ inex_im = mpfr_set_si (mpc_imagref (rop),
+ (mpfr_signbit (mpc_imagref (op)) ? -1 : +1),
+ MPC_RND_IM (rnd));
+ inex = MPC_INEX (0, inex_im);
+
+ mpfr_clear (s);
+ mpfr_clear (c);
+ }
+
+ return inex;
+ }
+
+ if (mpfr_zero_p (mpc_realref (op)))
+ /* tan(-0 -i*y) = -0 +i*tanh(y), when y is finite. */
+ /* tan(+0 +i*y) = +0 +i*tanh(y), when y is finite. */
+ {
+ int inex_im;
+
+ mpfr_set (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd));
+ inex_im = mpfr_tanh (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd));
+
+ return MPC_INEX (0, inex_im);
+ }
+
+ if (mpfr_zero_p (mpc_imagref (op)))
+ /* tan(x -i*0) = tan(x) -i*0, when x is finite. */
+ /* tan(x +i*0) = tan(x) +i*0, when x is finite. */
+ {
+ int inex_re;
+
+ inex_re = mpfr_tan (mpc_realref (rop), mpc_realref (op), MPC_RND_RE (rnd));
+ mpfr_set (mpc_imagref (rop), mpc_imagref (op), MPC_RND_IM (rnd));
+
+ return MPC_INEX (inex_re, 0);
+ }
+
+ /* ordinary (non-zero) numbers */
+
+ /* tan(op) = sin(op) / cos(op).
+
+ We use the following algorithm with rounding away from 0 for all
+ operations, and working precision w:
+
+ (1) x = A(sin(op))
+ (2) y = A(cos(op))
+ (3) z = A(x/y)
+
+ the error on Im(z) is at most 81 ulp,
+ the error on Re(z) is at most
+ 7 ulp if k < 2,
+ 8 ulp if k = 2,
+ else 5+k ulp, where
+ k = Exp(Re(x))+Exp(Re(y))-2min{Exp(Re(y)), Exp(Im(y))}-Exp(Re(x/y))
+ see proof in algorithms.tex.
+ */
+
+ prec = MPC_MAX_PREC(rop);
+
+ mpc_init2 (x, 2);
+ mpc_init2 (y, 2);
+
+ err = 7;
+
+ do
+ {
+ mpfr_exp_t k, exr, eyr, eyi, ezr;
+
+ ok = 0;
+
+ /* FIXME: prevent addition overflow */
+ prec += mpc_ceil_log2 (prec) + err;
+ mpc_set_prec (x, prec);
+ mpc_set_prec (y, prec);
+
+ /* rounding away from zero: except in the cases x=0 or y=0 (processed
+ above), sin x and cos y are never exact, so rounding away from 0 is
+ rounding towards 0 and adding one ulp to the absolute value */
+ mpc_sin_cos (x, y, op, MPC_RNDZZ, MPC_RNDZZ);
+ MPFR_ADD_ONE_ULP (mpc_realref (x));
+ MPFR_ADD_ONE_ULP (mpc_imagref (x));
+ MPFR_ADD_ONE_ULP (mpc_realref (y));
+ MPFR_ADD_ONE_ULP (mpc_imagref (y));
+ MPC_ASSERT (mpfr_zero_p (mpc_realref (x)) == 0);
+
+ if ( mpfr_inf_p (mpc_realref (x)) || mpfr_inf_p (mpc_imagref (x))
+ || mpfr_inf_p (mpc_realref (y)) || mpfr_inf_p (mpc_imagref (y))) {
+ /* If the real or imaginary part of x is infinite, it means that
+ Im(op) was large, in which case the result is
+ sign(tan(Re(op)))*0 + sign(Im(op))*I,
+ where sign(tan(Re(op))) = sign(Re(x))*sign(Re(y)). */
+ int inex_re, inex_im;
+ mpfr_set_ui (mpc_realref (rop), 0, GMP_RNDN);
+ if (mpfr_sgn (mpc_realref (x)) * mpfr_sgn (mpc_realref (y)) < 0)
+ {
+ mpfr_neg (mpc_realref (rop), mpc_realref (rop), GMP_RNDN);
+ inex_re = 1;
+ }
+ else
+ inex_re = -1; /* +0 is rounded down */
+ if (mpfr_sgn (mpc_imagref (op)) > 0)
+ {
+ mpfr_set_ui (mpc_imagref (rop), 1, GMP_RNDN);
+ inex_im = 1;
+ }
+ else
+ {
+ mpfr_set_si (mpc_imagref (rop), -1, GMP_RNDN);
+ inex_im = -1;
+ }
+ inex = MPC_INEX(inex_re, inex_im);
+ goto end;
+ }
+
+ exr = mpfr_get_exp (mpc_realref (x));
+ eyr = mpfr_get_exp (mpc_realref (y));
+ eyi = mpfr_get_exp (mpc_imagref (y));
+
+ /* some parts of the quotient may be exact */
+ inex = mpc_div (x, x, y, MPC_RNDZZ);
+ /* OP is no pure real nor pure imaginary, so in theory the real and
+ imaginary parts of its tangent cannot be null. However due to
+ rouding errors this might happen. Consider for example
+ tan(1+14*I) = 1.26e-10 + 1.00*I. For small precision sin(op) and
+ cos(op) differ only by a factor I, thus after mpc_div x = I and
+ its real part is zero. */
+ if (mpfr_zero_p (mpc_realref (x)) || mpfr_zero_p (mpc_imagref (x)))
+ {
+ err = prec; /* double precision */
+ continue;
+ }
+ if (MPC_INEX_RE (inex))
+ MPFR_ADD_ONE_ULP (mpc_realref (x));
+ if (MPC_INEX_IM (inex))
+ MPFR_ADD_ONE_ULP (mpc_imagref (x));
+ MPC_ASSERT (mpfr_zero_p (mpc_realref (x)) == 0);
+ ezr = mpfr_get_exp (mpc_realref (x));
+
+ /* FIXME: compute
+ k = Exp(Re(x))+Exp(Re(y))-2min{Exp(Re(y)), Exp(Im(y))}-Exp(Re(x/y))
+ avoiding overflow */
+ k = exr - ezr + MPC_MAX(-eyr, eyr - 2 * eyi);
+ err = k < 2 ? 7 : (k == 2 ? 8 : (5 + k));
+
+ /* Can the real part be rounded? */
+ ok = (!mpfr_number_p (mpc_realref (x)))
+ || mpfr_can_round (mpc_realref(x), prec - err, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_RE(rop) + (MPC_RND_RE(rnd) == GMP_RNDN));
+
+ if (ok)
+ {
+ /* Can the imaginary part be rounded? */
+ ok = (!mpfr_number_p (mpc_imagref (x)))
+ || mpfr_can_round (mpc_imagref(x), prec - 6, GMP_RNDN, GMP_RNDZ,
+ MPC_PREC_IM(rop) + (MPC_RND_IM(rnd) == GMP_RNDN));
+ }
+ }
+ while (ok == 0);
+
+ inex = mpc_set (rop, x, rnd);
+
+ end:
+ mpc_clear (x);
+ mpc_clear (y);
+
+ return inex;
+}
diff --git a/mpc/src/tanh.c b/mpc/src/tanh.c
new file mode 100644
index 0000000000..78f21037cf
--- /dev/null
+++ b/mpc/src/tanh.c
@@ -0,0 +1,47 @@
+/* mpc_tanh -- hyperbolic tangent of a complex number.
+
+Copyright (C) 2008, 2009, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_tanh (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
+{
+ /* tanh(op) = -i*tan(i*op) = conj(-i*tan(conj(-i*op))) */
+ mpc_t z;
+ mpc_t tan_z;
+ int inex;
+
+ /* z := conj(-i * op) and rop = conj(-i * tan(z)), in other words, we have
+ to switch real and imaginary parts. Let us set them without copying
+ significands. */
+ mpc_realref (z)[0] = mpc_imagref (op)[0];
+ mpc_imagref (z)[0] = mpc_realref (op)[0];
+ mpc_realref (tan_z)[0] = mpc_imagref (rop)[0];
+ mpc_imagref (tan_z)[0] = mpc_realref (rop)[0];
+
+ inex = mpc_tan (tan_z, z, MPC_RND (MPC_RND_IM (rnd), MPC_RND_RE (rnd)));
+
+ /* tan_z and rop parts share the same significands, copy the rest now. */
+ mpc_realref (rop)[0] = mpc_imagref (tan_z)[0];
+ mpc_imagref (rop)[0] = mpc_realref (tan_z)[0];
+
+ /* swap inexact flags for real and imaginary parts */
+ return MPC_INEX (MPC_INEX_IM (inex), MPC_INEX_RE (inex));
+}
diff --git a/mpc/src/uceil_log2.c b/mpc/src/uceil_log2.c
new file mode 100644
index 0000000000..df946128d8
--- /dev/null
+++ b/mpc/src/uceil_log2.c
@@ -0,0 +1,33 @@
+/* mpc_ceil_log2 - returns ceil(log(d)/log(2))
+
+Copyright (C) 2004, 2009, 2010 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+/* returns ceil(log(d)/log(2)) if d > 0 */
+/* Don't use count_leading_zeros since it is in longlong.h */
+mpfr_prec_t
+mpc_ceil_log2 (mpfr_prec_t d)
+{
+ mpfr_prec_t exp;
+
+ for (exp = 0; d > 1; d = (d + 1) / 2)
+ exp++;
+ return exp;
+}
diff --git a/mpc/src/ui_div.c b/mpc/src/ui_div.c
new file mode 100644
index 0000000000..6e3b955b53
--- /dev/null
+++ b/mpc/src/ui_div.c
@@ -0,0 +1,36 @@
+/* mpc_ui_div -- Divide an unsigned long int by a complex number.
+
+Copyright (C) 2002, 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <limits.h>
+#include "mpc-impl.h"
+
+int
+mpc_ui_div (mpc_ptr a, unsigned long int b, mpc_srcptr c, mpc_rnd_t rnd)
+{
+ int inex;
+ mpc_t bb;
+
+ mpc_init2 (bb, sizeof(unsigned long int) * CHAR_BIT);
+ mpc_set_ui (bb, b, rnd); /* exact */
+ inex = mpc_div (a, bb, c, rnd);
+ mpc_clear (bb);
+
+ return inex;
+}
diff --git a/mpc/src/ui_ui_sub.c b/mpc/src/ui_ui_sub.c
new file mode 100644
index 0000000000..597ee0566c
--- /dev/null
+++ b/mpc/src/ui_ui_sub.c
@@ -0,0 +1,34 @@
+/* mpc_ui_ui_sub -- Subtract a complex number from another one given
+ implicitly by its real and imaginary parts of type unsigned long int.
+
+Copyright (C) 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_ui_ui_sub (mpc_ptr rop, unsigned long int re, unsigned long int im,
+ mpc_srcptr op, mpc_rnd_t rnd)
+{
+ int inex_re, inex_im;
+
+ inex_re = mpfr_ui_sub (mpc_realref (rop), re, mpc_realref (op), MPC_RND_RE (rnd));
+ inex_im = mpfr_ui_sub (mpc_imagref (rop), im, mpc_imagref (op), MPC_RND_IM (rnd));
+
+ return MPC_INEX (inex_re, inex_im);
+}
diff --git a/mpc/src/urandom.c b/mpc/src/urandom.c
new file mode 100644
index 0000000000..f8e5f9004d
--- /dev/null
+++ b/mpc/src/urandom.c
@@ -0,0 +1,32 @@
+/* mpc_urandom -- Generate a random complex number uniformly distributed in
+ the interval [0,1[.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-impl.h"
+
+int
+mpc_urandom (mpc_ptr a, gmp_randstate_t state)
+{
+ int r, i;
+
+ r = mpfr_urandomb (mpc_realref(a), state);
+ i = mpfr_urandomb (mpc_imagref(a), state);
+ return r && i;
+}
diff --git a/mpc/tests/Makefile.am b/mpc/tests/Makefile.am
new file mode 100644
index 0000000000..8bae3ef6f4
--- /dev/null
+++ b/mpc/tests/Makefile.am
@@ -0,0 +1,52 @@
+## tests/Makefile.am -- Process this file with automake to produce Makefile.in
+##
+## Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
+##
+## This file is part of GNU MPC.
+##
+## GNU MPC is free software; you can redistribute it and/or modify it under
+## the terms of the GNU Lesser General Public License as published by the
+## Free Software Foundation; either version 3 of the License, or (at your
+## option) any later version.
+##
+## GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+## FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+## more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this program. If not, see http://www.gnu.org/licenses/ .
+
+AM_CPPFLAGS = -I$(top_srcdir)/src
+LDADD = libmpc-tests.la $(top_builddir)/src/libmpc.la
+# let libtool create an executable instead of a shell script
+# useful for tests with valgrind
+AM_LDFLAGS = -no-install
+# LOADLIBES (documented in the "GNU make" manual and equivalent to LDLIBS)
+# enables to compile a program foo.c in the test directory by simply doing
+# "make foo".
+LOADLIBES=$(DEFS) -I$(top_srcdir)/src -I$(top_builddir) $(CPPFLAGS) $(CFLAGS) -L$(top_builddir)/tests/.libs -lmpc-tests -lmpc -lm $(LIBS)
+
+check_PROGRAMS = tabs tacos tacosh tadd tadd_fr tadd_si tadd_ui targ tasin \
+tasinh tatan tatanh tconj tcos tcosh tdiv tdiv_2si tdiv_2ui tdiv_fr tdiv_ui \
+texp tfma tfr_div tfr_sub timag tio_str tlog tlog10 \
+tmul tmul_2si tmul_2ui tmul_fr tmul_i tmul_si tmul_ui \
+tneg tnorm tpow tpow_ld tpow_d tpow_fr tpow_si tpow_ui tpow_z \
+tprec tproj treal treimref tset tsin tsin_cos tsinh tsqr tsqrt tstrtoc tsub \
+tsub_fr tsub_ui tswap ttan ttanh tui_div tui_ui_sub tget_version
+
+check_LTLIBRARIES=libmpc-tests.la
+libmpc_tests_la_SOURCES=mpc-tests.h random.c tgeneric.c read_data.c \
+comparisons.c
+
+EXTRA_DIST = abs.dat acos.dat acosh.dat asin.dat asinh.dat atan.dat atanh.dat \
+add.dat add_fr.dat arg.dat conj.dat cos.dat cosh.dat div.dat div_fr.dat \
+exp.dat fma.dat fr_div.dat fr_sub.dat inp_str.dat log.dat log10.dat mul.dat \
+mul_fr.dat neg.dat norm.dat pow.dat pow_fr.dat pow_si.dat pow_ui.dat proj.dat \
+sin.dat sinh.dat sqr.dat sqrt.dat strtoc.dat sub.dat sub_fr.dat tan.dat \
+tanh.dat
+
+TESTS_ENVIRONMENT = $(VALGRIND)
+TESTS = $(check_PROGRAMS)
+CLEANFILES = mpc_test
+
diff --git a/mpc/tests/Makefile.in b/mpc/tests/Makefile.in
new file mode 100644
index 0000000000..159fc27f5e
--- /dev/null
+++ b/mpc/tests/Makefile.in
@@ -0,0 +1,1208 @@
+# Makefile.in generated by automake 1.12.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2012 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@
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+check_PROGRAMS = tabs$(EXEEXT) tacos$(EXEEXT) tacosh$(EXEEXT) \
+ tadd$(EXEEXT) tadd_fr$(EXEEXT) tadd_si$(EXEEXT) \
+ tadd_ui$(EXEEXT) targ$(EXEEXT) tasin$(EXEEXT) tasinh$(EXEEXT) \
+ tatan$(EXEEXT) tatanh$(EXEEXT) tconj$(EXEEXT) tcos$(EXEEXT) \
+ tcosh$(EXEEXT) tdiv$(EXEEXT) tdiv_2si$(EXEEXT) \
+ tdiv_2ui$(EXEEXT) tdiv_fr$(EXEEXT) tdiv_ui$(EXEEXT) \
+ texp$(EXEEXT) tfma$(EXEEXT) tfr_div$(EXEEXT) tfr_sub$(EXEEXT) \
+ timag$(EXEEXT) tio_str$(EXEEXT) tlog$(EXEEXT) tlog10$(EXEEXT) \
+ tmul$(EXEEXT) tmul_2si$(EXEEXT) tmul_2ui$(EXEEXT) \
+ tmul_fr$(EXEEXT) tmul_i$(EXEEXT) tmul_si$(EXEEXT) \
+ tmul_ui$(EXEEXT) tneg$(EXEEXT) tnorm$(EXEEXT) tpow$(EXEEXT) \
+ tpow_ld$(EXEEXT) tpow_d$(EXEEXT) tpow_fr$(EXEEXT) \
+ tpow_si$(EXEEXT) tpow_ui$(EXEEXT) tpow_z$(EXEEXT) \
+ tprec$(EXEEXT) tproj$(EXEEXT) treal$(EXEEXT) treimref$(EXEEXT) \
+ tset$(EXEEXT) tsin$(EXEEXT) tsin_cos$(EXEEXT) tsinh$(EXEEXT) \
+ tsqr$(EXEEXT) tsqrt$(EXEEXT) tstrtoc$(EXEEXT) tsub$(EXEEXT) \
+ tsub_fr$(EXEEXT) tsub_ui$(EXEEXT) tswap$(EXEEXT) ttan$(EXEEXT) \
+ ttanh$(EXEEXT) tui_div$(EXEEXT) tui_ui_sub$(EXEEXT) \
+ tget_version$(EXEEXT)
+subdir = tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c_check_flag.m4 \
+ $(top_srcdir)/m4/ax_gcc_option.m4 \
+ $(top_srcdir)/m4/ax_gcc_version.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/mpc.m4 $(top_srcdir)/m4/valgrind-tests.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+libmpc_tests_la_LIBADD =
+am_libmpc_tests_la_OBJECTS = random.lo tgeneric.lo read_data.lo \
+ comparisons.lo
+libmpc_tests_la_OBJECTS = $(am_libmpc_tests_la_OBJECTS)
+tabs_SOURCES = tabs.c
+tabs_OBJECTS = tabs.$(OBJEXT)
+tabs_LDADD = $(LDADD)
+tabs_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tacos_SOURCES = tacos.c
+tacos_OBJECTS = tacos.$(OBJEXT)
+tacos_LDADD = $(LDADD)
+tacos_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tacosh_SOURCES = tacosh.c
+tacosh_OBJECTS = tacosh.$(OBJEXT)
+tacosh_LDADD = $(LDADD)
+tacosh_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tadd_SOURCES = tadd.c
+tadd_OBJECTS = tadd.$(OBJEXT)
+tadd_LDADD = $(LDADD)
+tadd_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tadd_fr_SOURCES = tadd_fr.c
+tadd_fr_OBJECTS = tadd_fr.$(OBJEXT)
+tadd_fr_LDADD = $(LDADD)
+tadd_fr_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tadd_si_SOURCES = tadd_si.c
+tadd_si_OBJECTS = tadd_si.$(OBJEXT)
+tadd_si_LDADD = $(LDADD)
+tadd_si_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tadd_ui_SOURCES = tadd_ui.c
+tadd_ui_OBJECTS = tadd_ui.$(OBJEXT)
+tadd_ui_LDADD = $(LDADD)
+tadd_ui_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+targ_SOURCES = targ.c
+targ_OBJECTS = targ.$(OBJEXT)
+targ_LDADD = $(LDADD)
+targ_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tasin_SOURCES = tasin.c
+tasin_OBJECTS = tasin.$(OBJEXT)
+tasin_LDADD = $(LDADD)
+tasin_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tasinh_SOURCES = tasinh.c
+tasinh_OBJECTS = tasinh.$(OBJEXT)
+tasinh_LDADD = $(LDADD)
+tasinh_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tatan_SOURCES = tatan.c
+tatan_OBJECTS = tatan.$(OBJEXT)
+tatan_LDADD = $(LDADD)
+tatan_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tatanh_SOURCES = tatanh.c
+tatanh_OBJECTS = tatanh.$(OBJEXT)
+tatanh_LDADD = $(LDADD)
+tatanh_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tconj_SOURCES = tconj.c
+tconj_OBJECTS = tconj.$(OBJEXT)
+tconj_LDADD = $(LDADD)
+tconj_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tcos_SOURCES = tcos.c
+tcos_OBJECTS = tcos.$(OBJEXT)
+tcos_LDADD = $(LDADD)
+tcos_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tcosh_SOURCES = tcosh.c
+tcosh_OBJECTS = tcosh.$(OBJEXT)
+tcosh_LDADD = $(LDADD)
+tcosh_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tdiv_SOURCES = tdiv.c
+tdiv_OBJECTS = tdiv.$(OBJEXT)
+tdiv_LDADD = $(LDADD)
+tdiv_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tdiv_2si_SOURCES = tdiv_2si.c
+tdiv_2si_OBJECTS = tdiv_2si.$(OBJEXT)
+tdiv_2si_LDADD = $(LDADD)
+tdiv_2si_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tdiv_2ui_SOURCES = tdiv_2ui.c
+tdiv_2ui_OBJECTS = tdiv_2ui.$(OBJEXT)
+tdiv_2ui_LDADD = $(LDADD)
+tdiv_2ui_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tdiv_fr_SOURCES = tdiv_fr.c
+tdiv_fr_OBJECTS = tdiv_fr.$(OBJEXT)
+tdiv_fr_LDADD = $(LDADD)
+tdiv_fr_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tdiv_ui_SOURCES = tdiv_ui.c
+tdiv_ui_OBJECTS = tdiv_ui.$(OBJEXT)
+tdiv_ui_LDADD = $(LDADD)
+tdiv_ui_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+texp_SOURCES = texp.c
+texp_OBJECTS = texp.$(OBJEXT)
+texp_LDADD = $(LDADD)
+texp_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tfma_SOURCES = tfma.c
+tfma_OBJECTS = tfma.$(OBJEXT)
+tfma_LDADD = $(LDADD)
+tfma_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tfr_div_SOURCES = tfr_div.c
+tfr_div_OBJECTS = tfr_div.$(OBJEXT)
+tfr_div_LDADD = $(LDADD)
+tfr_div_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tfr_sub_SOURCES = tfr_sub.c
+tfr_sub_OBJECTS = tfr_sub.$(OBJEXT)
+tfr_sub_LDADD = $(LDADD)
+tfr_sub_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tget_version_SOURCES = tget_version.c
+tget_version_OBJECTS = tget_version.$(OBJEXT)
+tget_version_LDADD = $(LDADD)
+tget_version_DEPENDENCIES = libmpc-tests.la \
+ $(top_builddir)/src/libmpc.la
+timag_SOURCES = timag.c
+timag_OBJECTS = timag.$(OBJEXT)
+timag_LDADD = $(LDADD)
+timag_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tio_str_SOURCES = tio_str.c
+tio_str_OBJECTS = tio_str.$(OBJEXT)
+tio_str_LDADD = $(LDADD)
+tio_str_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tlog_SOURCES = tlog.c
+tlog_OBJECTS = tlog.$(OBJEXT)
+tlog_LDADD = $(LDADD)
+tlog_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tlog10_SOURCES = tlog10.c
+tlog10_OBJECTS = tlog10.$(OBJEXT)
+tlog10_LDADD = $(LDADD)
+tlog10_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tmul_SOURCES = tmul.c
+tmul_OBJECTS = tmul.$(OBJEXT)
+tmul_LDADD = $(LDADD)
+tmul_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tmul_2si_SOURCES = tmul_2si.c
+tmul_2si_OBJECTS = tmul_2si.$(OBJEXT)
+tmul_2si_LDADD = $(LDADD)
+tmul_2si_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tmul_2ui_SOURCES = tmul_2ui.c
+tmul_2ui_OBJECTS = tmul_2ui.$(OBJEXT)
+tmul_2ui_LDADD = $(LDADD)
+tmul_2ui_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tmul_fr_SOURCES = tmul_fr.c
+tmul_fr_OBJECTS = tmul_fr.$(OBJEXT)
+tmul_fr_LDADD = $(LDADD)
+tmul_fr_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tmul_i_SOURCES = tmul_i.c
+tmul_i_OBJECTS = tmul_i.$(OBJEXT)
+tmul_i_LDADD = $(LDADD)
+tmul_i_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tmul_si_SOURCES = tmul_si.c
+tmul_si_OBJECTS = tmul_si.$(OBJEXT)
+tmul_si_LDADD = $(LDADD)
+tmul_si_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tmul_ui_SOURCES = tmul_ui.c
+tmul_ui_OBJECTS = tmul_ui.$(OBJEXT)
+tmul_ui_LDADD = $(LDADD)
+tmul_ui_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tneg_SOURCES = tneg.c
+tneg_OBJECTS = tneg.$(OBJEXT)
+tneg_LDADD = $(LDADD)
+tneg_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tnorm_SOURCES = tnorm.c
+tnorm_OBJECTS = tnorm.$(OBJEXT)
+tnorm_LDADD = $(LDADD)
+tnorm_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tpow_SOURCES = tpow.c
+tpow_OBJECTS = tpow.$(OBJEXT)
+tpow_LDADD = $(LDADD)
+tpow_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tpow_d_SOURCES = tpow_d.c
+tpow_d_OBJECTS = tpow_d.$(OBJEXT)
+tpow_d_LDADD = $(LDADD)
+tpow_d_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tpow_fr_SOURCES = tpow_fr.c
+tpow_fr_OBJECTS = tpow_fr.$(OBJEXT)
+tpow_fr_LDADD = $(LDADD)
+tpow_fr_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tpow_ld_SOURCES = tpow_ld.c
+tpow_ld_OBJECTS = tpow_ld.$(OBJEXT)
+tpow_ld_LDADD = $(LDADD)
+tpow_ld_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tpow_si_SOURCES = tpow_si.c
+tpow_si_OBJECTS = tpow_si.$(OBJEXT)
+tpow_si_LDADD = $(LDADD)
+tpow_si_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tpow_ui_SOURCES = tpow_ui.c
+tpow_ui_OBJECTS = tpow_ui.$(OBJEXT)
+tpow_ui_LDADD = $(LDADD)
+tpow_ui_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tpow_z_SOURCES = tpow_z.c
+tpow_z_OBJECTS = tpow_z.$(OBJEXT)
+tpow_z_LDADD = $(LDADD)
+tpow_z_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tprec_SOURCES = tprec.c
+tprec_OBJECTS = tprec.$(OBJEXT)
+tprec_LDADD = $(LDADD)
+tprec_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tproj_SOURCES = tproj.c
+tproj_OBJECTS = tproj.$(OBJEXT)
+tproj_LDADD = $(LDADD)
+tproj_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+treal_SOURCES = treal.c
+treal_OBJECTS = treal.$(OBJEXT)
+treal_LDADD = $(LDADD)
+treal_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+treimref_SOURCES = treimref.c
+treimref_OBJECTS = treimref.$(OBJEXT)
+treimref_LDADD = $(LDADD)
+treimref_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tset_SOURCES = tset.c
+tset_OBJECTS = tset.$(OBJEXT)
+tset_LDADD = $(LDADD)
+tset_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tsin_SOURCES = tsin.c
+tsin_OBJECTS = tsin.$(OBJEXT)
+tsin_LDADD = $(LDADD)
+tsin_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tsin_cos_SOURCES = tsin_cos.c
+tsin_cos_OBJECTS = tsin_cos.$(OBJEXT)
+tsin_cos_LDADD = $(LDADD)
+tsin_cos_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tsinh_SOURCES = tsinh.c
+tsinh_OBJECTS = tsinh.$(OBJEXT)
+tsinh_LDADD = $(LDADD)
+tsinh_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tsqr_SOURCES = tsqr.c
+tsqr_OBJECTS = tsqr.$(OBJEXT)
+tsqr_LDADD = $(LDADD)
+tsqr_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tsqrt_SOURCES = tsqrt.c
+tsqrt_OBJECTS = tsqrt.$(OBJEXT)
+tsqrt_LDADD = $(LDADD)
+tsqrt_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tstrtoc_SOURCES = tstrtoc.c
+tstrtoc_OBJECTS = tstrtoc.$(OBJEXT)
+tstrtoc_LDADD = $(LDADD)
+tstrtoc_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tsub_SOURCES = tsub.c
+tsub_OBJECTS = tsub.$(OBJEXT)
+tsub_LDADD = $(LDADD)
+tsub_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tsub_fr_SOURCES = tsub_fr.c
+tsub_fr_OBJECTS = tsub_fr.$(OBJEXT)
+tsub_fr_LDADD = $(LDADD)
+tsub_fr_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tsub_ui_SOURCES = tsub_ui.c
+tsub_ui_OBJECTS = tsub_ui.$(OBJEXT)
+tsub_ui_LDADD = $(LDADD)
+tsub_ui_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tswap_SOURCES = tswap.c
+tswap_OBJECTS = tswap.$(OBJEXT)
+tswap_LDADD = $(LDADD)
+tswap_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+ttan_SOURCES = ttan.c
+ttan_OBJECTS = ttan.$(OBJEXT)
+ttan_LDADD = $(LDADD)
+ttan_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+ttanh_SOURCES = ttanh.c
+ttanh_OBJECTS = ttanh.$(OBJEXT)
+ttanh_LDADD = $(LDADD)
+ttanh_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tui_div_SOURCES = tui_div.c
+tui_div_OBJECTS = tui_div.$(OBJEXT)
+tui_div_LDADD = $(LDADD)
+tui_div_DEPENDENCIES = libmpc-tests.la $(top_builddir)/src/libmpc.la
+tui_ui_sub_SOURCES = tui_ui_sub.c
+tui_ui_sub_OBJECTS = tui_ui_sub.$(OBJEXT)
+tui_ui_sub_LDADD = $(LDADD)
+tui_ui_sub_DEPENDENCIES = libmpc-tests.la \
+ $(top_builddir)/src/libmpc.la
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libmpc_tests_la_SOURCES) tabs.c tacos.c tacosh.c tadd.c \
+ tadd_fr.c tadd_si.c tadd_ui.c targ.c tasin.c tasinh.c tatan.c \
+ tatanh.c tconj.c tcos.c tcosh.c tdiv.c tdiv_2si.c tdiv_2ui.c \
+ tdiv_fr.c tdiv_ui.c texp.c tfma.c tfr_div.c tfr_sub.c \
+ tget_version.c timag.c tio_str.c tlog.c tlog10.c tmul.c \
+ tmul_2si.c tmul_2ui.c tmul_fr.c tmul_i.c tmul_si.c tmul_ui.c \
+ tneg.c tnorm.c tpow.c tpow_d.c tpow_fr.c tpow_ld.c tpow_si.c \
+ tpow_ui.c tpow_z.c tprec.c tproj.c treal.c treimref.c tset.c \
+ tsin.c tsin_cos.c tsinh.c tsqr.c tsqrt.c tstrtoc.c tsub.c \
+ tsub_fr.c tsub_ui.c tswap.c ttan.c ttanh.c tui_div.c \
+ tui_ui_sub.c
+DIST_SOURCES = $(libmpc_tests_la_SOURCES) tabs.c tacos.c tacosh.c \
+ tadd.c tadd_fr.c tadd_si.c tadd_ui.c targ.c tasin.c tasinh.c \
+ tatan.c tatanh.c tconj.c tcos.c tcosh.c tdiv.c tdiv_2si.c \
+ tdiv_2ui.c tdiv_fr.c tdiv_ui.c texp.c tfma.c tfr_div.c \
+ tfr_sub.c tget_version.c timag.c tio_str.c tlog.c tlog10.c \
+ tmul.c tmul_2si.c tmul_2ui.c tmul_fr.c tmul_i.c tmul_si.c \
+ tmul_ui.c tneg.c tnorm.c tpow.c tpow_d.c tpow_fr.c tpow_ld.c \
+ tpow_si.c tpow_ui.c tpow_z.c tprec.c tproj.c treal.c \
+ treimref.c tset.c tsin.c tsin_cos.c tsinh.c tsqr.c tsqrt.c \
+ tstrtoc.c tsub.c tsub_fr.c tsub_ui.c tswap.c ttan.c ttanh.c \
+ tui_div.c tui_ui_sub.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+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)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GCC_VERSION = @GCC_VERSION@
+GREP = @GREP@
+HASSVNVERSION = @HASSVNVERSION@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPC_LDFLAGS = @MPC_LDFLAGS@
+MPC_LOG_H = @MPC_LOG_H@
+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@
+STRIP = @STRIP@
+SVNVERSION = @SVNVERSION@
+VALGRIND = @VALGRIND@
+VERSION = @VERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+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@
+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@
+AM_CPPFLAGS = -I$(top_srcdir)/src
+LDADD = libmpc-tests.la $(top_builddir)/src/libmpc.la
+# let libtool create an executable instead of a shell script
+# useful for tests with valgrind
+AM_LDFLAGS = -no-install
+# LOADLIBES (documented in the "GNU make" manual and equivalent to LDLIBS)
+# enables to compile a program foo.c in the test directory by simply doing
+# "make foo".
+LOADLIBES = $(DEFS) -I$(top_srcdir)/src -I$(top_builddir) $(CPPFLAGS) $(CFLAGS) -L$(top_builddir)/tests/.libs -lmpc-tests -lmpc -lm $(LIBS)
+check_LTLIBRARIES = libmpc-tests.la
+libmpc_tests_la_SOURCES = mpc-tests.h random.c tgeneric.c read_data.c \
+comparisons.c
+
+EXTRA_DIST = abs.dat acos.dat acosh.dat asin.dat asinh.dat atan.dat atanh.dat \
+add.dat add_fr.dat arg.dat conj.dat cos.dat cosh.dat div.dat div_fr.dat \
+exp.dat fma.dat fr_div.dat fr_sub.dat inp_str.dat log.dat log10.dat mul.dat \
+mul_fr.dat neg.dat norm.dat pow.dat pow_fr.dat pow_si.dat pow_ui.dat proj.dat \
+sin.dat sinh.dat sqr.dat sqrt.dat strtoc.dat sub.dat sub_fr.dat tan.dat \
+tanh.dat
+
+TESTS_ENVIRONMENT = $(VALGRIND)
+TESTS = $(check_PROGRAMS)
+CLEANFILES = mpc_test
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tests/Makefile
+.PRECIOUS: 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-checkLTLIBRARIES:
+ -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
+ @list='$(check_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+libmpc-tests.la: $(libmpc_tests_la_OBJECTS) $(libmpc_tests_la_DEPENDENCIES) $(EXTRA_libmpc_tests_la_DEPENDENCIES)
+ $(LINK) $(libmpc_tests_la_OBJECTS) $(libmpc_tests_la_LIBADD) $(LIBS)
+
+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
+tabs$(EXEEXT): $(tabs_OBJECTS) $(tabs_DEPENDENCIES) $(EXTRA_tabs_DEPENDENCIES)
+ @rm -f tabs$(EXEEXT)
+ $(LINK) $(tabs_OBJECTS) $(tabs_LDADD) $(LIBS)
+tacos$(EXEEXT): $(tacos_OBJECTS) $(tacos_DEPENDENCIES) $(EXTRA_tacos_DEPENDENCIES)
+ @rm -f tacos$(EXEEXT)
+ $(LINK) $(tacos_OBJECTS) $(tacos_LDADD) $(LIBS)
+tacosh$(EXEEXT): $(tacosh_OBJECTS) $(tacosh_DEPENDENCIES) $(EXTRA_tacosh_DEPENDENCIES)
+ @rm -f tacosh$(EXEEXT)
+ $(LINK) $(tacosh_OBJECTS) $(tacosh_LDADD) $(LIBS)
+tadd$(EXEEXT): $(tadd_OBJECTS) $(tadd_DEPENDENCIES) $(EXTRA_tadd_DEPENDENCIES)
+ @rm -f tadd$(EXEEXT)
+ $(LINK) $(tadd_OBJECTS) $(tadd_LDADD) $(LIBS)
+tadd_fr$(EXEEXT): $(tadd_fr_OBJECTS) $(tadd_fr_DEPENDENCIES) $(EXTRA_tadd_fr_DEPENDENCIES)
+ @rm -f tadd_fr$(EXEEXT)
+ $(LINK) $(tadd_fr_OBJECTS) $(tadd_fr_LDADD) $(LIBS)
+tadd_si$(EXEEXT): $(tadd_si_OBJECTS) $(tadd_si_DEPENDENCIES) $(EXTRA_tadd_si_DEPENDENCIES)
+ @rm -f tadd_si$(EXEEXT)
+ $(LINK) $(tadd_si_OBJECTS) $(tadd_si_LDADD) $(LIBS)
+tadd_ui$(EXEEXT): $(tadd_ui_OBJECTS) $(tadd_ui_DEPENDENCIES) $(EXTRA_tadd_ui_DEPENDENCIES)
+ @rm -f tadd_ui$(EXEEXT)
+ $(LINK) $(tadd_ui_OBJECTS) $(tadd_ui_LDADD) $(LIBS)
+targ$(EXEEXT): $(targ_OBJECTS) $(targ_DEPENDENCIES) $(EXTRA_targ_DEPENDENCIES)
+ @rm -f targ$(EXEEXT)
+ $(LINK) $(targ_OBJECTS) $(targ_LDADD) $(LIBS)
+tasin$(EXEEXT): $(tasin_OBJECTS) $(tasin_DEPENDENCIES) $(EXTRA_tasin_DEPENDENCIES)
+ @rm -f tasin$(EXEEXT)
+ $(LINK) $(tasin_OBJECTS) $(tasin_LDADD) $(LIBS)
+tasinh$(EXEEXT): $(tasinh_OBJECTS) $(tasinh_DEPENDENCIES) $(EXTRA_tasinh_DEPENDENCIES)
+ @rm -f tasinh$(EXEEXT)
+ $(LINK) $(tasinh_OBJECTS) $(tasinh_LDADD) $(LIBS)
+tatan$(EXEEXT): $(tatan_OBJECTS) $(tatan_DEPENDENCIES) $(EXTRA_tatan_DEPENDENCIES)
+ @rm -f tatan$(EXEEXT)
+ $(LINK) $(tatan_OBJECTS) $(tatan_LDADD) $(LIBS)
+tatanh$(EXEEXT): $(tatanh_OBJECTS) $(tatanh_DEPENDENCIES) $(EXTRA_tatanh_DEPENDENCIES)
+ @rm -f tatanh$(EXEEXT)
+ $(LINK) $(tatanh_OBJECTS) $(tatanh_LDADD) $(LIBS)
+tconj$(EXEEXT): $(tconj_OBJECTS) $(tconj_DEPENDENCIES) $(EXTRA_tconj_DEPENDENCIES)
+ @rm -f tconj$(EXEEXT)
+ $(LINK) $(tconj_OBJECTS) $(tconj_LDADD) $(LIBS)
+tcos$(EXEEXT): $(tcos_OBJECTS) $(tcos_DEPENDENCIES) $(EXTRA_tcos_DEPENDENCIES)
+ @rm -f tcos$(EXEEXT)
+ $(LINK) $(tcos_OBJECTS) $(tcos_LDADD) $(LIBS)
+tcosh$(EXEEXT): $(tcosh_OBJECTS) $(tcosh_DEPENDENCIES) $(EXTRA_tcosh_DEPENDENCIES)
+ @rm -f tcosh$(EXEEXT)
+ $(LINK) $(tcosh_OBJECTS) $(tcosh_LDADD) $(LIBS)
+tdiv$(EXEEXT): $(tdiv_OBJECTS) $(tdiv_DEPENDENCIES) $(EXTRA_tdiv_DEPENDENCIES)
+ @rm -f tdiv$(EXEEXT)
+ $(LINK) $(tdiv_OBJECTS) $(tdiv_LDADD) $(LIBS)
+tdiv_2si$(EXEEXT): $(tdiv_2si_OBJECTS) $(tdiv_2si_DEPENDENCIES) $(EXTRA_tdiv_2si_DEPENDENCIES)
+ @rm -f tdiv_2si$(EXEEXT)
+ $(LINK) $(tdiv_2si_OBJECTS) $(tdiv_2si_LDADD) $(LIBS)
+tdiv_2ui$(EXEEXT): $(tdiv_2ui_OBJECTS) $(tdiv_2ui_DEPENDENCIES) $(EXTRA_tdiv_2ui_DEPENDENCIES)
+ @rm -f tdiv_2ui$(EXEEXT)
+ $(LINK) $(tdiv_2ui_OBJECTS) $(tdiv_2ui_LDADD) $(LIBS)
+tdiv_fr$(EXEEXT): $(tdiv_fr_OBJECTS) $(tdiv_fr_DEPENDENCIES) $(EXTRA_tdiv_fr_DEPENDENCIES)
+ @rm -f tdiv_fr$(EXEEXT)
+ $(LINK) $(tdiv_fr_OBJECTS) $(tdiv_fr_LDADD) $(LIBS)
+tdiv_ui$(EXEEXT): $(tdiv_ui_OBJECTS) $(tdiv_ui_DEPENDENCIES) $(EXTRA_tdiv_ui_DEPENDENCIES)
+ @rm -f tdiv_ui$(EXEEXT)
+ $(LINK) $(tdiv_ui_OBJECTS) $(tdiv_ui_LDADD) $(LIBS)
+texp$(EXEEXT): $(texp_OBJECTS) $(texp_DEPENDENCIES) $(EXTRA_texp_DEPENDENCIES)
+ @rm -f texp$(EXEEXT)
+ $(LINK) $(texp_OBJECTS) $(texp_LDADD) $(LIBS)
+tfma$(EXEEXT): $(tfma_OBJECTS) $(tfma_DEPENDENCIES) $(EXTRA_tfma_DEPENDENCIES)
+ @rm -f tfma$(EXEEXT)
+ $(LINK) $(tfma_OBJECTS) $(tfma_LDADD) $(LIBS)
+tfr_div$(EXEEXT): $(tfr_div_OBJECTS) $(tfr_div_DEPENDENCIES) $(EXTRA_tfr_div_DEPENDENCIES)
+ @rm -f tfr_div$(EXEEXT)
+ $(LINK) $(tfr_div_OBJECTS) $(tfr_div_LDADD) $(LIBS)
+tfr_sub$(EXEEXT): $(tfr_sub_OBJECTS) $(tfr_sub_DEPENDENCIES) $(EXTRA_tfr_sub_DEPENDENCIES)
+ @rm -f tfr_sub$(EXEEXT)
+ $(LINK) $(tfr_sub_OBJECTS) $(tfr_sub_LDADD) $(LIBS)
+tget_version$(EXEEXT): $(tget_version_OBJECTS) $(tget_version_DEPENDENCIES) $(EXTRA_tget_version_DEPENDENCIES)
+ @rm -f tget_version$(EXEEXT)
+ $(LINK) $(tget_version_OBJECTS) $(tget_version_LDADD) $(LIBS)
+timag$(EXEEXT): $(timag_OBJECTS) $(timag_DEPENDENCIES) $(EXTRA_timag_DEPENDENCIES)
+ @rm -f timag$(EXEEXT)
+ $(LINK) $(timag_OBJECTS) $(timag_LDADD) $(LIBS)
+tio_str$(EXEEXT): $(tio_str_OBJECTS) $(tio_str_DEPENDENCIES) $(EXTRA_tio_str_DEPENDENCIES)
+ @rm -f tio_str$(EXEEXT)
+ $(LINK) $(tio_str_OBJECTS) $(tio_str_LDADD) $(LIBS)
+tlog$(EXEEXT): $(tlog_OBJECTS) $(tlog_DEPENDENCIES) $(EXTRA_tlog_DEPENDENCIES)
+ @rm -f tlog$(EXEEXT)
+ $(LINK) $(tlog_OBJECTS) $(tlog_LDADD) $(LIBS)
+tlog10$(EXEEXT): $(tlog10_OBJECTS) $(tlog10_DEPENDENCIES) $(EXTRA_tlog10_DEPENDENCIES)
+ @rm -f tlog10$(EXEEXT)
+ $(LINK) $(tlog10_OBJECTS) $(tlog10_LDADD) $(LIBS)
+tmul$(EXEEXT): $(tmul_OBJECTS) $(tmul_DEPENDENCIES) $(EXTRA_tmul_DEPENDENCIES)
+ @rm -f tmul$(EXEEXT)
+ $(LINK) $(tmul_OBJECTS) $(tmul_LDADD) $(LIBS)
+tmul_2si$(EXEEXT): $(tmul_2si_OBJECTS) $(tmul_2si_DEPENDENCIES) $(EXTRA_tmul_2si_DEPENDENCIES)
+ @rm -f tmul_2si$(EXEEXT)
+ $(LINK) $(tmul_2si_OBJECTS) $(tmul_2si_LDADD) $(LIBS)
+tmul_2ui$(EXEEXT): $(tmul_2ui_OBJECTS) $(tmul_2ui_DEPENDENCIES) $(EXTRA_tmul_2ui_DEPENDENCIES)
+ @rm -f tmul_2ui$(EXEEXT)
+ $(LINK) $(tmul_2ui_OBJECTS) $(tmul_2ui_LDADD) $(LIBS)
+tmul_fr$(EXEEXT): $(tmul_fr_OBJECTS) $(tmul_fr_DEPENDENCIES) $(EXTRA_tmul_fr_DEPENDENCIES)
+ @rm -f tmul_fr$(EXEEXT)
+ $(LINK) $(tmul_fr_OBJECTS) $(tmul_fr_LDADD) $(LIBS)
+tmul_i$(EXEEXT): $(tmul_i_OBJECTS) $(tmul_i_DEPENDENCIES) $(EXTRA_tmul_i_DEPENDENCIES)
+ @rm -f tmul_i$(EXEEXT)
+ $(LINK) $(tmul_i_OBJECTS) $(tmul_i_LDADD) $(LIBS)
+tmul_si$(EXEEXT): $(tmul_si_OBJECTS) $(tmul_si_DEPENDENCIES) $(EXTRA_tmul_si_DEPENDENCIES)
+ @rm -f tmul_si$(EXEEXT)
+ $(LINK) $(tmul_si_OBJECTS) $(tmul_si_LDADD) $(LIBS)
+tmul_ui$(EXEEXT): $(tmul_ui_OBJECTS) $(tmul_ui_DEPENDENCIES) $(EXTRA_tmul_ui_DEPENDENCIES)
+ @rm -f tmul_ui$(EXEEXT)
+ $(LINK) $(tmul_ui_OBJECTS) $(tmul_ui_LDADD) $(LIBS)
+tneg$(EXEEXT): $(tneg_OBJECTS) $(tneg_DEPENDENCIES) $(EXTRA_tneg_DEPENDENCIES)
+ @rm -f tneg$(EXEEXT)
+ $(LINK) $(tneg_OBJECTS) $(tneg_LDADD) $(LIBS)
+tnorm$(EXEEXT): $(tnorm_OBJECTS) $(tnorm_DEPENDENCIES) $(EXTRA_tnorm_DEPENDENCIES)
+ @rm -f tnorm$(EXEEXT)
+ $(LINK) $(tnorm_OBJECTS) $(tnorm_LDADD) $(LIBS)
+tpow$(EXEEXT): $(tpow_OBJECTS) $(tpow_DEPENDENCIES) $(EXTRA_tpow_DEPENDENCIES)
+ @rm -f tpow$(EXEEXT)
+ $(LINK) $(tpow_OBJECTS) $(tpow_LDADD) $(LIBS)
+tpow_d$(EXEEXT): $(tpow_d_OBJECTS) $(tpow_d_DEPENDENCIES) $(EXTRA_tpow_d_DEPENDENCIES)
+ @rm -f tpow_d$(EXEEXT)
+ $(LINK) $(tpow_d_OBJECTS) $(tpow_d_LDADD) $(LIBS)
+tpow_fr$(EXEEXT): $(tpow_fr_OBJECTS) $(tpow_fr_DEPENDENCIES) $(EXTRA_tpow_fr_DEPENDENCIES)
+ @rm -f tpow_fr$(EXEEXT)
+ $(LINK) $(tpow_fr_OBJECTS) $(tpow_fr_LDADD) $(LIBS)
+tpow_ld$(EXEEXT): $(tpow_ld_OBJECTS) $(tpow_ld_DEPENDENCIES) $(EXTRA_tpow_ld_DEPENDENCIES)
+ @rm -f tpow_ld$(EXEEXT)
+ $(LINK) $(tpow_ld_OBJECTS) $(tpow_ld_LDADD) $(LIBS)
+tpow_si$(EXEEXT): $(tpow_si_OBJECTS) $(tpow_si_DEPENDENCIES) $(EXTRA_tpow_si_DEPENDENCIES)
+ @rm -f tpow_si$(EXEEXT)
+ $(LINK) $(tpow_si_OBJECTS) $(tpow_si_LDADD) $(LIBS)
+tpow_ui$(EXEEXT): $(tpow_ui_OBJECTS) $(tpow_ui_DEPENDENCIES) $(EXTRA_tpow_ui_DEPENDENCIES)
+ @rm -f tpow_ui$(EXEEXT)
+ $(LINK) $(tpow_ui_OBJECTS) $(tpow_ui_LDADD) $(LIBS)
+tpow_z$(EXEEXT): $(tpow_z_OBJECTS) $(tpow_z_DEPENDENCIES) $(EXTRA_tpow_z_DEPENDENCIES)
+ @rm -f tpow_z$(EXEEXT)
+ $(LINK) $(tpow_z_OBJECTS) $(tpow_z_LDADD) $(LIBS)
+tprec$(EXEEXT): $(tprec_OBJECTS) $(tprec_DEPENDENCIES) $(EXTRA_tprec_DEPENDENCIES)
+ @rm -f tprec$(EXEEXT)
+ $(LINK) $(tprec_OBJECTS) $(tprec_LDADD) $(LIBS)
+tproj$(EXEEXT): $(tproj_OBJECTS) $(tproj_DEPENDENCIES) $(EXTRA_tproj_DEPENDENCIES)
+ @rm -f tproj$(EXEEXT)
+ $(LINK) $(tproj_OBJECTS) $(tproj_LDADD) $(LIBS)
+treal$(EXEEXT): $(treal_OBJECTS) $(treal_DEPENDENCIES) $(EXTRA_treal_DEPENDENCIES)
+ @rm -f treal$(EXEEXT)
+ $(LINK) $(treal_OBJECTS) $(treal_LDADD) $(LIBS)
+treimref$(EXEEXT): $(treimref_OBJECTS) $(treimref_DEPENDENCIES) $(EXTRA_treimref_DEPENDENCIES)
+ @rm -f treimref$(EXEEXT)
+ $(LINK) $(treimref_OBJECTS) $(treimref_LDADD) $(LIBS)
+tset$(EXEEXT): $(tset_OBJECTS) $(tset_DEPENDENCIES) $(EXTRA_tset_DEPENDENCIES)
+ @rm -f tset$(EXEEXT)
+ $(LINK) $(tset_OBJECTS) $(tset_LDADD) $(LIBS)
+tsin$(EXEEXT): $(tsin_OBJECTS) $(tsin_DEPENDENCIES) $(EXTRA_tsin_DEPENDENCIES)
+ @rm -f tsin$(EXEEXT)
+ $(LINK) $(tsin_OBJECTS) $(tsin_LDADD) $(LIBS)
+tsin_cos$(EXEEXT): $(tsin_cos_OBJECTS) $(tsin_cos_DEPENDENCIES) $(EXTRA_tsin_cos_DEPENDENCIES)
+ @rm -f tsin_cos$(EXEEXT)
+ $(LINK) $(tsin_cos_OBJECTS) $(tsin_cos_LDADD) $(LIBS)
+tsinh$(EXEEXT): $(tsinh_OBJECTS) $(tsinh_DEPENDENCIES) $(EXTRA_tsinh_DEPENDENCIES)
+ @rm -f tsinh$(EXEEXT)
+ $(LINK) $(tsinh_OBJECTS) $(tsinh_LDADD) $(LIBS)
+tsqr$(EXEEXT): $(tsqr_OBJECTS) $(tsqr_DEPENDENCIES) $(EXTRA_tsqr_DEPENDENCIES)
+ @rm -f tsqr$(EXEEXT)
+ $(LINK) $(tsqr_OBJECTS) $(tsqr_LDADD) $(LIBS)
+tsqrt$(EXEEXT): $(tsqrt_OBJECTS) $(tsqrt_DEPENDENCIES) $(EXTRA_tsqrt_DEPENDENCIES)
+ @rm -f tsqrt$(EXEEXT)
+ $(LINK) $(tsqrt_OBJECTS) $(tsqrt_LDADD) $(LIBS)
+tstrtoc$(EXEEXT): $(tstrtoc_OBJECTS) $(tstrtoc_DEPENDENCIES) $(EXTRA_tstrtoc_DEPENDENCIES)
+ @rm -f tstrtoc$(EXEEXT)
+ $(LINK) $(tstrtoc_OBJECTS) $(tstrtoc_LDADD) $(LIBS)
+tsub$(EXEEXT): $(tsub_OBJECTS) $(tsub_DEPENDENCIES) $(EXTRA_tsub_DEPENDENCIES)
+ @rm -f tsub$(EXEEXT)
+ $(LINK) $(tsub_OBJECTS) $(tsub_LDADD) $(LIBS)
+tsub_fr$(EXEEXT): $(tsub_fr_OBJECTS) $(tsub_fr_DEPENDENCIES) $(EXTRA_tsub_fr_DEPENDENCIES)
+ @rm -f tsub_fr$(EXEEXT)
+ $(LINK) $(tsub_fr_OBJECTS) $(tsub_fr_LDADD) $(LIBS)
+tsub_ui$(EXEEXT): $(tsub_ui_OBJECTS) $(tsub_ui_DEPENDENCIES) $(EXTRA_tsub_ui_DEPENDENCIES)
+ @rm -f tsub_ui$(EXEEXT)
+ $(LINK) $(tsub_ui_OBJECTS) $(tsub_ui_LDADD) $(LIBS)
+tswap$(EXEEXT): $(tswap_OBJECTS) $(tswap_DEPENDENCIES) $(EXTRA_tswap_DEPENDENCIES)
+ @rm -f tswap$(EXEEXT)
+ $(LINK) $(tswap_OBJECTS) $(tswap_LDADD) $(LIBS)
+ttan$(EXEEXT): $(ttan_OBJECTS) $(ttan_DEPENDENCIES) $(EXTRA_ttan_DEPENDENCIES)
+ @rm -f ttan$(EXEEXT)
+ $(LINK) $(ttan_OBJECTS) $(ttan_LDADD) $(LIBS)
+ttanh$(EXEEXT): $(ttanh_OBJECTS) $(ttanh_DEPENDENCIES) $(EXTRA_ttanh_DEPENDENCIES)
+ @rm -f ttanh$(EXEEXT)
+ $(LINK) $(ttanh_OBJECTS) $(ttanh_LDADD) $(LIBS)
+tui_div$(EXEEXT): $(tui_div_OBJECTS) $(tui_div_DEPENDENCIES) $(EXTRA_tui_div_DEPENDENCIES)
+ @rm -f tui_div$(EXEEXT)
+ $(LINK) $(tui_div_OBJECTS) $(tui_div_LDADD) $(LIBS)
+tui_ui_sub$(EXEEXT): $(tui_ui_sub_OBJECTS) $(tui_ui_sub_DEPENDENCIES) $(EXTRA_tui_ui_sub_DEPENDENCIES)
+ @rm -f tui_ui_sub$(EXEEXT)
+ $(LINK) $(tui_ui_sub_OBJECTS) $(tui_ui_sub_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comparisons.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read_data.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tabs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tacos.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tacosh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd_fr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd_si.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/targ.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tasin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tasinh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tatan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tatanh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconj.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcos.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcosh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv_2si.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv_2ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv_fr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfma.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfr_div.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfr_sub.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgeneric.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_version.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timag.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio_str.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog10.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_2si.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_2ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_fr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_i.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_si.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tneg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnorm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_d.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_fr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_ld.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_si.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_z.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tprec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tproj.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/treal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/treimref.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsin_cos.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsinh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsqr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsqrt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tstrtoc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub_fr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tswap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttanh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tui_div.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tui_ui_sub.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP)'; \
+ 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
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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_LTLIBRARIES) $(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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -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 -rf ./$(DEPDIR)
+ -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 all all-am check check-TESTS check-am clean \
+ clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \
+ clean-libtool cscopelist ctags 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 \
+ tags uninstall uninstall-am
+
+
+# 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/mpc/tests/abs.dat b/mpc/tests/abs.dat
new file mode 100644
index 0000000000..19098683cd
--- /dev/null
+++ b/mpc/tests/abs.dat
@@ -0,0 +1,84 @@
+# Data file for mpc_abs.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX PREC_ROP ROP PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND
+#
+# where op = op_re + i * op_im,
+# rop is ROP rounded to nearest to the precision of PREC_ROP
+# op_re is OP_RE rounded to nearest to the precision of PREC_OP_RE
+# op_im is OP_IM rounded to nearest to the precision of PREC_OP_IM
+# ROP is checked against abs(op) rounded to the precision PREC_ROP
+# in the direction RND
+# INEX is the ternary value with the following notation:
+# "?" ternary value not checked
+# "+" if ROP is greater than the exact mathematical result
+# "0" if ROP is exactly the mathematical result
+# "-" if ROP is less than the exact mathematical result
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
+0 53 +inf 53 -inf 53 -inf N
+0 53 +inf 53 -inf 53 -1 N
+0 53 +inf 53 -inf 53 -0 N
+0 53 +inf 53 -inf 53 +0 N
+0 53 +inf 53 -inf 53 +1 N
+0 53 +inf 53 -inf 53 +inf N
+0 53 +inf 53 -inf 53 nan N
+0 53 +inf 53 -1 53 -inf N
+0 53 +inf 53 -1 53 +inf N
+0 53 nan 53 -1 53 nan N
+0 53 +inf 53 -0 53 -inf N
+0 53 +0 53 -0 53 -0 N
+0 53 +0 53 -0 53 +0 N
+0 53 +inf 53 -0 53 +inf N
+0 53 nan 53 -0 53 nan N
+0 53 +inf 53 +0 53 -inf N
+0 53 +0 53 +0 53 -0 N
+0 53 +0 53 +0 53 +0 N
+0 53 +inf 53 +0 53 +inf N
+0 53 nan 53 +0 53 nan N
+0 53 +inf 53 +1 53 -inf N
+0 53 +inf 53 +1 53 +inf N
+0 53 nan 53 +1 53 nan N
+0 53 +inf 53 +inf 53 -inf N
+0 53 +inf 53 +inf 53 -1 N
+0 53 +inf 53 +inf 53 -0 N
+0 53 +inf 53 +inf 53 +0 N
+0 53 +inf 53 +inf 53 +1 N
+0 53 +inf 53 +inf 53 +inf N
+0 53 +inf 53 +inf 53 nan N
+0 53 +inf 53 nan 53 -inf N
+0 53 nan 53 nan 53 -1 N
+0 53 nan 53 nan 53 -0 N
+0 53 nan 53 nan 53 +0 N
+0 53 nan 53 nan 53 +1 N
+0 53 +inf 53 nan 53 +inf N
+0 53 nan 53 nan 53 nan N
+
diff --git a/mpc/tests/acos.dat b/mpc/tests/acos.dat
new file mode 100644
index 0000000000..e5956abb5e
--- /dev/null
+++ b/mpc/tests/acos.dat
@@ -0,0 +1,127 @@
+# Data file for mpc_acos.
+#
+# Copyright (C) INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# where op = op_re + i * op_im, rop = rop_re + i * rop_im,
+# rop_re is ROP_RE rounded to nearest to the precision of PREC_ROP_RE
+# rop_im is ROP_IM rounded to nearest to the precision of PREC_ROP_IM
+# op_re is OP_RE rounded to nearest to the precision of PREC_OP_RE
+# op_im is OP_IM rounded to nearest to the precision of PREC_OP_IM
+# ROP_RE is checked against Re(acos op) rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against Im(acos op) rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
+- 0 53 0x12D97C7F3321D2p-51 53 +inf 53 -inf 53 -inf N N
+- 0 53 0x1921FB54442D18p-51 53 +inf 53 -inf 53 -1 N N
+- 0 53 0x1921FB54442D18p-51 53 +inf 53 -inf 53 -0 N N
+- 0 53 0x1921FB54442D18p-51 53 -inf 53 -inf 53 +0 N N
+- 0 53 0x1921FB54442D18p-51 53 -inf 53 -inf 53 +1 N N
+- 0 53 0x12D97C7F3321D2p-51 53 -inf 53 -inf 53 +inf N N
+0 0 53 nan 53 inf 53 -inf 53 nan N N
+- 0 53 0x1921FB54442D18p-52 53 +inf 53 -6 53 -inf N N
+- 0 53 0x1921FB54442D18p-52 53 -inf 53 -6 53 +inf N N
+0 0 53 nan 53 nan 53 -6 53 nan N N
+- 0 53 0x1921FB54442D18p-52 53 +inf 53 -0.5 53 -inf N N
+- 0 53 0x1921FB54442D18p-52 53 -inf 53 -0.5 53 +inf N N
+0 0 53 nan 53 nan 53 -0.5 53 nan N N
+- 0 53 0x1921FB54442D18p-52 53 +inf 53 -0 53 -inf N N
+- 0 53 0x1921FB54442D18p-52 53 +0 53 -0 53 -0 N N
+- 0 53 0x1921FB54442D18p-52 53 -0 53 -0 53 +0 N N
+- 0 53 0x1921FB54442D18p-52 53 -inf 53 -0 53 +inf N N
+- 0 53 0x1921FB54442D18p-52 53 nan 53 -0 53 nan N N
+- 0 53 0x1921FB54442D18p-52 53 +inf 53 +0 53 -inf N N
+- 0 53 0x1921FB54442D18p-52 53 +0 53 +0 53 -0 N N
+- 0 53 0x1921FB54442D18p-52 53 -0 53 +0 53 +0 N N
+- 0 53 0x1921FB54442D18p-52 53 -inf 53 +0 53 +inf N N
+- 0 53 0x1921FB54442D18p-52 53 nan 53 +0 53 nan N N
+- 0 53 0x1921FB54442D18p-52 53 +inf 53 +0.5 53 -inf N N
+- 0 53 0x1921FB54442D18p-52 53 -inf 53 +0.5 53 +inf N N
+0 0 53 nan 53 nan 53 +0.5 53 nan N N
+- 0 53 0x1921FB54442D18p-52 53 +inf 53 +6 53 -inf N N
+- 0 53 0x1921FB54442D18p-52 53 -inf 53 +6 53 +inf N N
+0 0 53 nan 53 nan 53 +6 53 nan N N
+- 0 53 0x1921FB54442D18p-53 53 +inf 53 +inf 53 -inf N N
+0 0 53 +0 53 +inf 53 +inf 53 -1 N N
+0 0 53 +0 53 +inf 53 +inf 53 -0 N N
+0 0 53 +0 53 -inf 53 +inf 53 +0 N N
+0 0 53 +0 53 -inf 53 +inf 53 +1 N N
+- 0 53 0x1921FB54442D18p-53 53 -inf 53 +inf 53 +inf N N
+0 0 53 nan 53 inf 53 +inf 53 nan N N
+0 0 53 nan 53 +inf 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 nan 53 nan 53 -0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 0 53 nan 53 -inf 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# pure real argument
+- + 53 0x1921FB54442D18p-51 53 0x13D2B7539DBA4Cp-51 53 -6 53 -0 N N
+- - 53 0x1921FB54442D18p-51 53 -0x13D2B7539DBA4Cp-51 53 -6 53 +0 N N
+- + 53 0x1921FB54442D18p-51 53 0x15124271980435p-52 53 -2 53 -0 N N
+- - 53 0x1921FB54442D18p-51 53 -0x15124271980435p-52 53 -2 53 +0 N N
+- 0 53 0x1921FB54442D18p-51 53 +0 53 -1 53 -0 N N
+- 0 53 0x1921FB54442D18p-51 53 -0 53 -1 53 +0 N N
++ 0 53 0x10C152382D7366p-51 53 +0 53 -0.5 53 -0 N N
++ 0 53 0x10C152382D7366p-51 53 -0 53 -0.5 53 +0 N N
++ 0 53 0x10C152382D7366p-52 53 -0 53 +0.5 53 +0 N N
++ 0 53 0x10C152382D7366p-52 53 +0 53 +0.5 53 -0 N N
+0 0 53 +0 53 -0 53 +1 53 +0 N N
+0 0 53 +0 53 +0 53 +1 53 -0 N N
+0 - 53 +0 53 -0x15124271980435p-52 53 +2 53 +0 N N
+0 + 53 +0 53 0x15124271980435p-52 53 +2 53 -0 N N
+0 - 53 +0 53 -0x13D2B7539DBA4Cp-51 53 +6 53 +0 N N
+0 + 53 +0 53 0x13D2B7539DBA4Cp-51 53 +6 53 -0 N N
+
+# pure imaginary argument
+- + 53 0x1921FB54442D18p-52 53 0x1D185B507EDC0Ep-52 53 -0 53 -3 N N
+- + 53 0x1921FB54442D18p-52 53 0x1D185B507EDC0Ep-52 53 +0 53 -3 N N
+- + 53 0x1921FB54442D18p-52 53 0x1FACFB2399E637p-55 53 -0 53 -.25 N N
+- + 53 0x1921FB54442D18p-52 53 0x1FACFB2399E637p-55 53 +0 53 -.25 N N
+- - 53 0x1921FB54442D18p-52 53 -0x1FACFB2399E637p-55 53 -0 53 +.25 N N
+- - 53 0x1921FB54442D18p-52 53 -0x1FACFB2399E637p-55 53 +0 53 +.25 N N
+- - 53 0x1921FB54442D18p-52 53 -0x1D185B507EDC0Ep-52 53 -0 53 +3 N N
+- - 53 0x1921FB54442D18p-52 53 -0x1D185B507EDC0Ep-52 53 +0 53 +3 N N
+
+# regular argument for various precisions
+- + 2 0.5 2 -1 2 2 2 1 N Z
++ + 9 0x5Dp-6 9 0x9Fp-5 9 8.5 9 -71 N U
++ + 2 0x3p-9 2 1.5 2 2 2 -0x1p-7 U N
++ - 53 0x74C141310E695p-53 53 -0x1D6D2CFA9F3F11p-52 53 0x3243F6A8885A3p-48 53 0x162E42FEFA39EFp-53 N N
diff --git a/mpc/tests/acosh.dat b/mpc/tests/acosh.dat
new file mode 100644
index 0000000000..2a5d62b447
--- /dev/null
+++ b/mpc/tests/acosh.dat
@@ -0,0 +1,121 @@
+# Data file for mpc_acosh.
+#
+# Copyright (C) 2009 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# where op = op_re + i * op_im, rop = rop_re + i * rop_im,
+# rop_re is ROP_RE rounded to nearest to the precision of PREC_ROP_RE
+# rop_im is ROP_IM rounded to nearest to the precision of PREC_ROP_IM
+# op_re is OP_RE rounded to nearest to the precision of PREC_OP_RE
+# op_im is OP_IM rounded to nearest to the precision of PREC_OP_IM
+# ROP_RE is checked against Re(acos op) rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against Im(acos op) rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
+0 + 53 +inf 53 -0x12D97C7F3321D2p-51 53 -inf 53 -inf N N
+0 + 53 +inf 53 -0x1921FB54442D18p-51 53 -inf 53 -1 N N
+0 + 53 +inf 53 -0x1921FB54442D18p-51 53 -inf 53 -0 N N
+0 - 53 +inf 53 0x1921FB54442D18p-51 53 -inf 53 +0 N N
+0 - 53 +inf 53 0x1921FB54442D18p-51 53 -inf 53 +1 N N
+0 - 53 +inf 53 0x12D97C7F3321D2p-51 53 -inf 53 +inf N N
+0 0 53 +inf 53 nan 53 -inf 53 nan N N
+0 + 53 +inf 53 -0x1921FB54442D18p-52 53 -6 53 -inf N N
+0 - 53 +inf 53 0x1921FB54442D18p-52 53 -6 53 +inf N N
+0 0 53 nan 53 nan 53 -6 53 nan N N
+0 + 53 +inf 53 -0x1921FB54442D18p-52 53 -0.5 53 -inf N N
+0 - 53 +inf 53 0x1921FB54442D18p-52 53 -0.5 53 +inf N N
+0 0 53 nan 53 nan 53 -0.5 53 nan N N
+0 + 53 +inf 53 -0x1921FB54442D18p-52 53 -0 53 -inf N N
+0 + 53 +0 53 -0x1921FB54442D18p-52 53 -0 53 -0 N N
+0 - 53 +0 53 0x1921FB54442D18p-52 53 -0 53 +0 N N
+0 - 53 +inf 53 0x1921FB54442D18p-52 53 -0 53 +inf N N
+0 0 53 nan 53 nan 53 -0 53 nan N N
+0 + 53 +inf 53 -0x1921FB54442D18p-52 53 +0 53 -inf N N
+0 + 53 +0 53 -0x1921FB54442D18p-52 53 +0 53 -0 N N
+0 - 53 +0 53 0x1921FB54442D18p-52 53 +0 53 +0 N N
+0 - 53 +inf 53 0x1921FB54442D18p-52 53 +0 53 +inf N N
+0 0 53 nan 53 nan 53 +0 53 nan N N
+0 + 53 +inf 53 -0x1921FB54442D18p-52 53 +6 53 -inf N N
+0 - 53 +inf 53 0x1921FB54442D18p-52 53 +6 53 +inf N N
+0 0 53 nan 53 nan 53 +6 53 nan N N
+0 + 53 +inf 53 -0x1921FB54442D18p-53 53 +inf 53 -inf N N
+0 0 53 +inf 53 -0 53 +inf 53 -1 N N
+0 0 53 +inf 53 -0 53 +inf 53 -0 N N
+0 0 53 +inf 53 +0 53 +inf 53 +0 N N
+0 0 53 +inf 53 +0 53 +inf 53 +1 N N
+0 - 53 +inf 53 0x1921FB54442D18p-53 53 +inf 53 +inf N N
+0 0 53 +inf 53 nan 53 +inf 53 nan N N
+0 0 53 +inf 53 nan 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 nan 53 nan 53 -0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 0 53 +inf 53 nan 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# pure real argument
++ + 53 0x1C34366179D427p-51 53 -0x1921FB54442D18p-51 53 -17 53 -0 N N
++ - 53 0x1C34366179D427p-51 53 0x1921FB54442D18p-51 53 -17 53 +0 N N
+0 + 53 +0 53 -0x1921FB54442D18p-51 53 -1 53 -0 N N
+0 - 53 +0 53 0x1921FB54442D18p-51 53 -1 53 +0 N N
+0 - 53 +0 53 -0x10C152382D7366p-51 53 -0.5 53 -0 N N
+0 + 53 +0 53 0x10C152382D7366p-51 53 -0.5 53 +0 N N
+0 - 53 +0 53 -0x10C152382D7366p-52 53 +0.5 53 -0 N N
+0 + 53 +0 53 0x10C152382D7366p-52 53 +0.5 53 +0 N N
+0 0 53 +0 53 -0 53 +1 53 -0 N N
+0 0 53 +0 53 +0 53 +1 53 +0 N N
++ 0 53 0x1C34366179D427p-51 53 -0 53 +17 53 -0 N N
++ 0 53 0x1C34366179D427p-51 53 +0 53 +17 53 +0 N N
+
+# pure imaginary argument
+- + 53 0x1C37C174A83DEDp-51 53 -0x1921FB54442D18p-52 53 -0 53 -17 N N
+- + 53 0x1C37C174A83DEDp-51 53 -0x1921FB54442D18p-52 53 +0 53 -17 N N
++ + 53 0x1C34366179D427p-53 53 -0x1921FB54442D18p-52 53 -0 53 -1 N N
++ + 53 0x1C34366179D427p-53 53 -0x1921FB54442D18p-52 53 +0 53 -1 N N
++ + 53 0x1ECC2CAEC5160Ap-54 53 -0x1921FB54442D18p-52 53 -0 53 -0.5 N N
++ + 53 0x1ECC2CAEC5160Ap-54 53 -0x1921FB54442D18p-52 53 +0 53 -0.5 N N
++ - 53 0x1ECC2CAEC5160Ap-54 53 0x1921FB54442D18p-52 53 -0 53 +0.5 N N
++ - 53 0x1ECC2CAEC5160Ap-54 53 0x1921FB54442D18p-52 53 +0 53 +0.5 N N
++ - 53 0x1C34366179D427p-53 53 0x1921FB54442D18p-52 53 -0 53 +1 N N
++ - 53 0x1C34366179D427p-53 53 0x1921FB54442D18p-52 53 +0 53 +1 N N
+- - 53 0x1C37C174A83DEDp-51 53 0x1921FB54442D18p-52 53 -0 53 +17 N N
+- - 53 0x1C37C174A83DEDp-51 53 0x1921FB54442D18p-52 53 +0 53 +17 N N
+
+# IEEE-754 double precision
++ + 53 0x1D6D2CFA9F3F11p-52 53 0x74C141310E695p-53 53 0x3243F6A8885A3p-48 53 0x162E42FEFA39EFp-53 N N
diff --git a/mpc/tests/add.dat b/mpc/tests/add.dat
new file mode 100644
index 0000000000..73779f69e8
--- /dev/null
+++ b/mpc/tests/add.dat
@@ -0,0 +1,115 @@
+# Data file for mpc_add.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP1_RE OP1_RE PREC_OP1_IM OP1_IM PREC_OP2_RE OP2_RE PREC_OP2_IM OP2_IM RND_RE RND_IM
+#
+# where op1 = op1_re + i * op1_im, op2 = op2_re + i * op2_im, rop = rop_re + i * rop_im,
+# The data are read from the file and stored in variables op1, op2, rop using
+# rounding to nearest when needed, for instance: rop_re is ROP_RE rounded to
+# nearest to the precision of PREC_ROP_RE.
+# ROP_RE is checked against Re(op1 + op2) rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against Im(op1 + op2) rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
+0 0 53 -inf 53 -inf 53 -inf 53 -inf 53 -inf 53 -inf N Z
+0 0 53 -inf 53 nan 53 -inf 53 +inf 53 +1 53 -inf Z U
+0 0 53 +inf 53 -inf 53 +inf 53 -inf 53 +inf 53 +0 U D
+0 0 53 +inf 53 +inf 53 +inf 53 +inf 53 -0 53 -1 D N
+0 0 53 -inf 53 -inf 53 -inf 53 -inf 53 -0 53 -1 N U
+0 0 53 nan 53 nan 53 -inf 53 +inf 53 +inf 53 nan Z D # check this is true in ISO C99
+0 0 53 nan 53 -inf 53 +inf 53 -inf 53 nan 53 -1 U N
+0 0 53 +inf 53 nan 53 +inf 53 +inf 53 -0 53 nan D Z
+0 0 53 nan 53 nan 53 -inf 53 -inf 53 nan 53 nan N D
+
+0 0 53 +inf 53 -inf 53 -1 53 -inf 53 +inf 53 -1 N D
+0 0 53 nan 53 +1 53 -inf 53 +1 53 +inf 53 -0 Z N
+0 0 53 +1 53 -inf 53 +1 53 -inf 53 -0 53 +1 U Z
+0 0 53 +inf 53 +1 53 +inf 53 +1 53 -0 53 -0 D U
+0 0 53 +inf 53 nan 53 -1 53 -inf 53 +inf 53 nan N N
+0 0 53 nan 53 +2 53 -inf 53 +1 53 nan 53 +1 Z Z
+0 0 53 +1 53 nan 53 +1 53 -inf 53 -0 53 nan U U # check this
+0 0 53 nan 53 nan 53 +inf 53 +1 53 nan 53 nan D D
+
+0 0 53 -0 53 nan 53 -0 53 -inf 53 +0 53 +inf D D
+0 0 53 -inf 53 +0 53 -inf 53 +0 53 +1 53 -0 N Z
+0 0 53 +0 53 -inf 53 +0 53 -inf 53 -0 53 -0 Z U
+0 0 53 nan 53 nan 53 +inf 53 +0 53 -inf 53 nan U D # check
+0 0 53 nan 53 -inf 53 -0 53 -inf 53 nan 53 -1 D N
+0 0 53 -inf 53 nan 53 -inf 53 +0 53 +0 53 nan N U
+0 0 53 nan 53 nan 53 +0 53 -inf 53 nan 53 nan Z D
+
+0 0 53 +0 53 -0 53 +0 53 +1 53 -0 53 -1 Z D
+0 0 53 -1 53 -0 53 -1 53 -0 53 +0 53 -0 U N
+0 0 53 nan 53 +inf 53 -0 53 +1 53 nan 53 +inf D Z
+0 0 53 +0 53 nan 53 +1 53 -0 53 -1 53 nan N D
+0 0 53 nan 53 +1 53 +0 53 +1 53 nan 53 -0 Z N
+0 0 53 nan 53 nan 53 -1 53 -0 53 nan 53 nan U Z
+
+0 0 53 +0 53 +0 53 -0 53 +0 53 +0 53 -0 U Z
+0 0 53 nan 53 -inf 53 +0 53 -0 53 nan 53 -inf D U
+0 0 53 -1 53 nan 53 +0 53 +0 53 -1 53 nan N N
+0 0 53 nan 53 -0 53 -0 53 -0 53 nan 53 -0 Z Z
+0 0 53 nan 53 nan 53 -0 53 +0 53 nan 53 nan U U
+
+0 0 53 nan 53 nan 53 nan 53 -inf 53 nan 53 +inf U U # check
+0 0 53 +inf 53 nan 53 +inf 53 nan 53 -1 53 nan D D
+0 0 53 nan 53 -inf 53 nan 53 -inf 53 nan 53 -0 N Z
+0 0 53 nan 53 nan 53 -inf 53 nan 53 nan 53 nan Z U # check
+
+0 0 53 nan 53 nan 53 +1 53 nan 53 nan 53 -1 Z U
+0 0 53 nan 53 nan 53 nan 53 +1 53 -0 53 nan U D
+0 0 53 nan 53 nan 53 -1 53 nan 53 nan 53 nan D N
+
+0 0 53 nan 53 nan 53 nan 53 +0 53 +0 53 nan D N
+0 0 53 nan 53 nan 53 +0 53 nan 53 nan 53 nan N U
+
+0 0 53 nan 53 nan 53 nan 53 nan 53 nan 53 nan N U
+
+# pure real argument
++ 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 53 -0 N N
+- 0 53 0x10000000000000p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 53 -0 Z Z
++ 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 53 -0 U U
+- 0 53 0x10000000000000p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 53 -0 D D
+
+# pure imaginary argument
+0 + 53 -0 53 0x10000000000001p-52 53 -0 53 0x10000000000001p-105 53 -0 53 +1 N N
+0 - 53 +0 53 0x10000000000000p-52 53 +0 53 0x10000000000001p-105 53 -0 53 +1 Z Z
+0 + 53 +0 53 0x10000000000001p-52 53 +0 53 0x10000000000001p-105 53 -0 53 +1 U U
+0 - 53 -0 53 0x10000000000000p-52 53 -0 53 0x10000000000001p-105 53 -0 53 +1 D D
+
diff --git a/mpc/tests/add_fr.dat b/mpc/tests/add_fr.dat
new file mode 100644
index 0000000000..a07110c07c
--- /dev/null
+++ b/mpc/tests/add_fr.dat
@@ -0,0 +1,122 @@
+# Data file for mpc_add_fr.
+#
+# Copyright (C) 2008, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP1_RE OP1_RE PREC_OP1_IM OP1_IM PREC_OP2 OP2 RND_RE RND_IM
+#
+# where op1 = op1_re + i * op1_im, rop = rop_re + i * rop_im,
+# The data are read from the file and stored in variables op1, op2, rop using
+# rounding to nearest when needed, for instance: rop_re is ROP_RE rounded to
+# nearest to the precision of PREC_ROP_RE.
+# ROP_RE is checked against Re(op1 + op2) rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against Im(op1) rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
+0 0 53 -inf 53 -inf 53 -inf 53 -inf 53 -inf N Z
+0 0 53 -inf 53 +inf 53 -inf 53 +inf 53 -1 Z U
+0 0 53 -inf 53 -0 53 -inf 53 -0 53 -0 U D
+0 0 53 -inf 53 +0 53 -inf 53 +0 53 +0 D N
+0 0 53 -inf 53 -1 53 -inf 53 -1 53 +1 N U
+0 0 53 nan 53 +1 53 -inf 53 +1 53 +inf Z D
+0 0 53 nan 53 nan 53 -inf 53 nan 53 nan U N
+
+0 0 53 -inf 53 +inf 53 -1 53 +inf 53 -inf N Z
+0 0 53 -2 53 -0 53 -1 53 -0 53 -1 Z U
+0 0 53 -1 53 +0 53 -1 53 +0 53 -0 U D
+0 0 53 -1 53 -1 53 -1 53 -1 53 +0 D N
+0 0 53 +0 53 +1 53 -1 53 +1 53 +1 N U
+0 0 53 +inf 53 nan 53 -1 53 nan 53 +inf Z D
+0 0 53 nan 53 -inf 53 -1 53 -inf 53 nan U N
+
+0 0 53 -inf 53 -0 53 -0 53 -0 53 -inf N Z
+0 0 53 -1 53 +0 53 -0 53 +0 53 -1 Z U
+0 0 53 -0 53 -1 53 -0 53 -1 53 -0 U D
+0 0 53 -0 53 +1 53 -0 53 +1 53 +0 D N
+0 0 53 +1 53 nan 53 -0 53 nan 53 +1 N U
+0 0 53 +inf 53 -inf 53 -0 53 -inf 53 +inf Z D
+0 0 53 nan 53 +inf 53 -0 53 +inf 53 nan U N
+
+0 0 53 -inf 53 +0 53 +0 53 +0 53 -inf N Z
+0 0 53 -1 53 -1 53 +0 53 -1 53 -1 Z U
+0 0 53 +0 53 +1 53 +0 53 +1 53 -0 U D
+0 0 53 +0 53 nan 53 +0 53 nan 53 +0 D N
+0 0 53 +1 53 -inf 53 +0 53 -inf 53 +1 N U
+0 0 53 +inf 53 +inf 53 +0 53 +inf 53 +inf Z D
+0 0 53 nan 53 -0 53 +0 53 -0 53 nan U N
+
+0 0 53 -inf 53 -1 53 +1 53 -1 53 -inf N Z
+0 0 53 +0 53 +1 53 +1 53 +1 53 -1 Z U
+0 0 53 +1 53 nan 53 +1 53 nan 53 -0 U D
+0 0 53 +1 53 -inf 53 +1 53 -inf 53 +0 D N
+0 0 53 +2 53 +inf 53 +1 53 +inf 53 +1 N U
+0 0 53 +inf 53 -0 53 +1 53 -0 53 +inf Z D
+0 0 53 nan 53 +0 53 +1 53 +0 53 nan U N
+
+0 0 53 nan 53 +1 53 +inf 53 +1 53 -inf N Z
+0 0 53 +inf 53 nan 53 +inf 53 nan 53 -1 Z U
+0 0 53 +inf 53 -inf 53 +inf 53 -inf 53 -0 U D
+0 0 53 +inf 53 +inf 53 +inf 53 +inf 53 +0 D N
+0 0 53 +inf 53 -0 53 +inf 53 -0 53 +1 N U
+0 0 53 +inf 53 +0 53 +inf 53 +0 53 +inf Z D
+0 0 53 nan 53 -1 53 +inf 53 -1 53 nan U N
+
+0 0 53 nan 53 nan 53 nan 53 nan 53 -inf N Z
+0 0 53 nan 53 -inf 53 nan 53 -inf 53 -1 Z U
+0 0 53 nan 53 +inf 53 nan 53 +inf 53 -0 U D
+0 0 53 nan 53 -0 53 nan 53 -0 53 +0 D N
+0 0 53 nan 53 +0 53 nan 53 +0 53 +1 N U
+0 0 53 nan 53 -1 53 nan 53 -1 53 +inf Z D
+0 0 53 nan 53 +1 53 nan 53 +1 53 nan U N
+
+# pure real argument
+- 0 53 0x10000000000000p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-106 N N
++ 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 N N
+- 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-104 N N
+- 0 53 0x10000000000000p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 Z Z
++ 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 U U
+- 0 53 0x10000000000000p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 D D
+
+# pure imaginary argument
+0 0 53 +1 53 +1 53 -0 53 1 53 +1 N N
+0 0 53 +1 53 +1 53 +0 53 1 53 +1 Z Z
+0 0 53 +1 53 +1 53 +0 53 1 53 +1 U U
+0 0 53 +1 53 +1 53 -0 53 1 53 +1 D D
+
+# non-zero return values for imaginary part
+0 + 2 0 2 8 3 0 3 7 3 0 N N
+0 - 2 0 2 4 3 0 3 5 3 0 N N
diff --git a/mpc/tests/arg.dat b/mpc/tests/arg.dat
new file mode 100644
index 0000000000..55e151ddc5
--- /dev/null
+++ b/mpc/tests/arg.dat
@@ -0,0 +1,74 @@
+# Data file for mpc_arg.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX PREC_ROP ROP PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND
+#
+# where op = op_re + i * op_im.
+# See abs.dat for other details.
+
+# special values (following ISO C99 standard)
++ 53 -0x96CBE3F9990E9p-50 53 -inf 53 -inf N
++ 53 -0x3243F6A8885A3p-48 53 -inf 53 -1 N
++ 53 -0x3243F6A8885A3p-48 53 -inf 53 -0 N
+- 53 +0x3243F6A8885A3p-48 53 -inf 53 +0 N
+- 53 +0x3243F6A8885A3p-48 53 -inf 53 +1 N
+- 53 +0x96CBE3F9990E9p-50 53 -inf 53 +inf N
+0 53 nan 53 -inf 53 nan N
++ 53 -0x3243F6A8885A3p-49 53 -1 53 -inf N
++ 53 -0x3243F6A8885A3p-48 53 -1 53 -0 N
+- 53 +0x3243F6A8885A3p-48 53 -1 53 +0 N
+- 53 +0x3243F6A8885A3p-49 53 -1 53 +inf N
+0 53 nan 53 -1 53 nan N
++ 53 -0x3243F6A8885A3p-49 53 -0 53 -inf N
++ 53 -0x3243F6A8885A3p-49 53 -0 53 -1 N
++ 53 -0x3243F6A8885A3p-48 53 -0 53 -0 N
+- 53 +0x3243F6A8885A3p-48 53 -0 53 +0 N
+- 53 +0x3243F6A8885A3p-49 53 -0 53 +1 N
+- 53 +0x3243F6A8885A3p-49 53 -0 53 +inf N
+0 53 nan 53 -0 53 nan N
++ 53 -0x3243F6A8885A3p-49 53 +0 53 -inf N
++ 53 -0x3243F6A8885A3p-49 53 +0 53 -1 N
+0 53 -0 53 +0 53 -0 N
+0 53 +0 53 +0 53 +0 N
+- 53 +0x3243F6A8885A3p-49 53 +0 53 +1 N
+- 53 +0x3243F6A8885A3p-49 53 +0 53 +inf N
+0 53 nan 53 +0 53 nan N
++ 53 -0x3243F6A8885A3p-49 53 +1 53 -inf N
+0 53 -0 53 +1 53 -0 N
+0 53 +0 53 +1 53 +0 N
+- 53 +0x3243F6A8885A3p-49 53 +1 53 +inf N
+0 53 nan 53 +1 53 nan N
++ 53 -0x3243F6A8885A3p-50 53 +inf 53 -inf N
+0 53 -0 53 +inf 53 -1 N
+0 53 -0 53 +inf 53 -0 N
+0 53 +0 53 +inf 53 +0 N
+0 53 +0 53 +inf 53 +1 N
+- 53 +0x3243F6A8885A3p-50 53 +inf 53 +inf N
+0 53 nan 53 +inf 53 nan N
+0 53 nan 53 nan 53 -inf N
+0 53 nan 53 nan 53 -1 N
+0 53 nan 53 nan 53 -0 N
+0 53 nan 53 nan 53 +0 N
+0 53 nan 53 nan 53 +1 N
+0 53 nan 53 nan 53 +inf N
+0 53 nan 53 nan 53 nan N
+
diff --git a/mpc/tests/asin.dat b/mpc/tests/asin.dat
new file mode 100644
index 0000000000..9793fcc1c1
--- /dev/null
+++ b/mpc/tests/asin.dat
@@ -0,0 +1,126 @@
+# Data file for mpc_asin.
+#
+# Copyright (C) 2009 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# where op = op_re + i * op_im, rop = rop_re + i * rop_im,
+# rop_re is ROP_RE rounded to nearest to the precision of PREC_ROP_RE
+# rop_im is ROP_IM rounded to nearest to the precision of PREC_ROP_IM
+# op_re is OP_RE rounded to nearest to the precision of PREC_OP_RE
+# op_im is OP_IM rounded to nearest to the precision of PREC_OP_IM
+# ROP_RE is checked against Re(asin op) rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against Im(asin op) rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
++ 0 53 -0x1921FB54442D18p-53 53 -inf 53 -inf 53 -inf N N
++ 0 53 -0x1921FB54442D18p-52 53 -inf 53 -inf 53 -1 N N
++ 0 53 -0x1921FB54442D18p-52 53 -inf 53 -inf 53 -0 N N
++ 0 53 -0x1921FB54442D18p-52 53 +inf 53 -inf 53 +0 N N
++ 0 53 -0x1921FB54442D18p-52 53 +inf 53 -inf 53 +1 N N
++ 0 53 -0x1921FB54442D18p-53 53 +inf 53 -inf 53 +inf N N
+0 0 53 nan 53 inf 53 -inf 53 nan N N
+0 0 53 -0 53 -inf 53 -6 53 -inf N N
+0 0 53 -0 53 +inf 53 -6 53 +inf N N
+0 0 53 nan 53 nan 53 -6 53 nan N N
+0 0 53 -0 53 -inf 53 -0.5 53 -inf N N
+0 0 53 -0 53 +inf 53 -0.5 53 +inf N N
+0 0 53 nan 53 nan 53 -0.5 53 nan N N
+0 0 53 -0 53 -inf 53 -0 53 -inf N N
+0 0 53 -0 53 -0 53 -0 53 -0 N N
+0 0 53 -0 53 +0 53 -0 53 +0 N N
+0 0 53 -0 53 +inf 53 -0 53 +inf N N
+0 0 53 -0 53 nan 53 -0 53 nan N N
+0 0 53 +0 53 -inf 53 +0 53 -inf N N
+0 0 53 +0 53 -0 53 +0 53 -0 N N
+0 0 53 +0 53 +0 53 +0 53 +0 N N
+0 0 53 +0 53 +inf 53 +0 53 +inf N N
+0 0 53 +0 53 nan 53 +0 53 nan N N
+0 0 53 +0 53 -inf 53 +0.5 53 -inf N N
+0 0 53 +0 53 +inf 53 +0.5 53 +inf N N
+0 0 53 nan 53 nan 53 +0.5 53 nan N N
+0 0 53 +0 53 -inf 53 +6 53 -inf N N
+0 0 53 +0 53 +inf 53 +6 53 +inf N N
+0 0 53 nan 53 nan 53 +6 53 nan N N
+- 0 53 0x1921FB54442D18p-53 53 -inf 53 +inf 53 -inf N N
+- 0 53 0x1921FB54442D18p-52 53 -inf 53 +inf 53 -1 N N
+- 0 53 0x1921FB54442D18p-52 53 -inf 53 +inf 53 -0 N N
+- 0 53 0x1921FB54442D18p-52 53 +inf 53 +inf 53 +0 N N
+- 0 53 0x1921FB54442D18p-52 53 +inf 53 +inf 53 +1 N N
+- 0 53 0x1921FB54442D18p-53 53 +inf 53 +inf 53 +inf N N
+0 0 53 nan 53 inf 53 +inf 53 nan N N
+0 0 53 nan 53 -inf 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 nan 53 nan 53 -0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 0 53 nan 53 +inf 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# pure real argument
++ - 53 -0x1921FB54442D18p-52 53 -0x1ECC2CAEC5160Ap-53 53 -1.5 53 -0 N N
++ + 53 -0x1921FB54442D18p-52 53 0x1ECC2CAEC5160Ap-53 53 -1.5 53 +0 N N
++ 0 53 -0x1921FB54442D18p-52 53 -0 53 -1 53 -0 N N
++ 0 53 -0x1921FB54442D18p-52 53 +0 53 -1 53 +0 N N
+- 0 53 -0x10C152382D7366p-53 53 -0 53 -0.5 53 -0 N N
+- 0 53 -0x10C152382D7366p-53 53 +0 53 -0.5 53 +0 N N
++ 0 53 0x10C152382D7366p-53 53 -0 53 +0.5 53 -0 N N
++ 0 53 0x10C152382D7366p-53 53 +0 53 +0.5 53 +0 N N
+- 0 53 0x1921FB54442D18p-52 53 -0 53 +1 53 -0 N N
+- 0 53 0x1921FB54442D18p-52 53 +0 53 +1 53 +0 N N
+- - 53 0x1921FB54442D18p-52 53 -0x1ECC2CAEC5160Ap-53 53 +1.5 53 -0 N N
+- + 53 0x1921FB54442D18p-52 53 0x1ECC2CAEC5160Ap-53 53 +1.5 53 +0 N N
+
+# pure imaginary argument
+0 + 53 -0 53 -0x131DC0090B63D8p-52 53 -0 53 -1.5 N N
+0 + 53 +0 53 -0x131DC0090B63D8p-52 53 +0 53 -1.5 N N
+0 - 53 -0 53 -0x1C34366179D427p-53 53 -0 53 -1 N N
+0 - 53 +0 53 -0x1C34366179D427p-53 53 +0 53 -1 N N
+0 - 53 -0 53 -0x1ECC2CAEC5160Ap-54 53 -0 53 -0.5 N N
+0 - 53 +0 53 -0x1ECC2CAEC5160Ap-54 53 +0 53 -0.5 N N
+0 + 53 -0 53 0x1ECC2CAEC5160Ap-54 53 -0 53 +0.5 N N
+0 + 53 +0 53 0x1ECC2CAEC5160Ap-54 53 +0 53 +0.5 N N
+0 + 53 -0 53 0x1C34366179D427p-53 53 -0 53 +1 N N
+0 + 53 +0 53 0x1C34366179D427p-53 53 +0 53 +1 N N
+0 - 53 -0 53 0x131DC0090B63D8p-52 53 -0 53 +1.5 N N
+0 - 53 +0 53 0x131DC0090B63D8p-52 53 +0 53 +1.5 N N
+
+# IEEE-754 double precision and other precisions
++ - 53 0x189BF9EC7FCD5Bp-54 53 0x1206ECFA94614Bp-50 53 17 53 42 N N
+- + 2 1.5 2 6 2 96 2 0x1p-8 N N
+- - 8 0xC9p-7 8 0x15p-2 2 96 2 0x1p-8 N N
diff --git a/mpc/tests/asinh.dat b/mpc/tests/asinh.dat
new file mode 100644
index 0000000000..e9daf992eb
--- /dev/null
+++ b/mpc/tests/asinh.dat
@@ -0,0 +1,120 @@
+# Data file for mpc_asinh.
+#
+# Copyright (C) 2009 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# where op = op_re + i * op_im, rop = rop_re + i * rop_im,
+# rop_re is ROP_RE rounded to nearest to the precision of PREC_ROP_RE
+# rop_im is ROP_IM rounded to nearest to the precision of PREC_ROP_IM
+# op_re is OP_RE rounded to nearest to the precision of PREC_OP_RE
+# op_im is OP_IM rounded to nearest to the precision of PREC_OP_IM
+# ROP_RE is checked against Re(asin op) rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against Im(asin op) rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
+0 + 53 -inf 53 -0x1921FB54442D18p-53 53 -inf 53 -inf N N
+0 0 53 -inf 53 -0 53 -inf 53 -1 N N
+0 0 53 -inf 53 -0 53 -inf 53 -0 N N
+0 0 53 -inf 53 +0 53 -inf 53 +0 N N
+0 0 53 -inf 53 +0 53 -inf 53 +1 N N
+0 - 53 -inf 53 0x1921FB54442D18p-53 53 -inf 53 +inf N N
+0 0 53 -inf 53 nan 53 -inf 53 nan N N
+0 + 53 -inf 53 -0x1921FB54442D18p-52 53 -6 53 -inf N N
+0 - 53 -inf 53 0x1921FB54442D18p-52 53 -6 53 +inf N N
+0 0 53 nan 53 nan 53 -6 53 nan N N
+0 + 53 -inf 53 -0x1921FB54442D18p-52 53 -0 53 -inf N N
+0 0 53 -0 53 -0 53 -0 53 -0 N N
+0 0 53 -0 53 +0 53 -0 53 +0 N N
+0 - 53 -inf 53 0x1921FB54442D18p-52 53 -0 53 +inf N N
+0 0 53 nan 53 nan 53 -0 53 nan N N
+0 + 53 +inf 53 -0x1921FB54442D18p-52 53 +0 53 -inf N N
+0 0 53 +0 53 -0 53 +0 53 -0 N N
+0 0 53 +0 53 +0 53 +0 53 +0 N N
+0 - 53 +inf 53 0x1921FB54442D18p-52 53 +0 53 +inf N N
+0 0 53 nan 53 nan 53 +0 53 nan N N
+0 + 53 +inf 53 -0x1921FB54442D18p-52 53 +6 53 -inf N N
+0 - 53 +inf 53 0x1921FB54442D18p-52 53 +6 53 +inf N N
+0 0 53 nan 53 nan 53 +6 53 nan N N
+0 + 53 +inf 53 -0x1921FB54442D18p-53 53 +inf 53 -inf N N
+0 0 53 +inf 53 -0 53 +inf 53 -1 N N
+0 0 53 +inf 53 -0 53 +inf 53 -0 N N
+0 0 53 +inf 53 +0 53 +inf 53 +0 N N
+0 0 53 +inf 53 +0 53 +inf 53 +1 N N
+0 - 53 +inf 53 0x1921FB54442D18p-53 53 +inf 53 +inf N N
+0 0 53 +inf 53 nan 53 +inf 53 nan N N
+0 0 53 inf 53 nan 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 -0 53 nan 53 -0 N N
+0 0 53 nan 53 +0 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 0 53 inf 53 nan 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# pure real argument
++ 0 53 -0x131DC0090B63D8p-52 53 -0 53 -1.5 53 -0 N N
++ 0 53 -0x131DC0090B63D8p-52 53 +0 53 -1.5 53 +0 N N
+- 0 53 -0x1C34366179D427p-53 53 -0 53 -1 53 -0 N N
+- 0 53 -0x1C34366179D427p-53 53 +0 53 -1 53 +0 N N
+- 0 53 -0x1ECC2CAEC5160Ap-54 53 -0 53 -0.5 53 -0 N N
+- 0 53 -0x1ECC2CAEC5160Ap-54 53 +0 53 -0.5 53 +0 N N
++ 0 53 0x1ECC2CAEC5160Ap-54 53 -0 53 +0.5 53 -0 N N
++ 0 53 0x1ECC2CAEC5160Ap-54 53 +0 53 +0.5 53 +0 N N
++ 0 53 0x1C34366179D427p-53 53 -0 53 +1 53 -0 N N
++ 0 53 0x1C34366179D427p-53 53 +0 53 +1 53 +0 N N
+- 0 53 0x131DC0090B63D8p-52 53 -0 53 +1.5 53 -0 N N
+- 0 53 0x131DC0090B63D8p-52 53 +0 53 +1.5 53 +0 N N
+
+# pure imaginary argument
+- + 53 -0x1ECC2CAEC5160Ap-53 53 -0x1921FB54442D18p-52 53 -0 53 -1.5 N N
++ + 53 0x1ECC2CAEC5160Ap-53 53 -0x1921FB54442D18p-52 53 +0 53 -1.5 N N
+0 + 53 -0 53 -0x1921FB54442D18p-52 53 -0 53 -1 N N
+0 + 53 +0 53 -0x1921FB54442D18p-52 53 +0 53 -1 N N
+0 - 53 -0 53 -0x10C152382D7366p-53 53 -0 53 -0.5 N N
+0 - 53 +0 53 -0x10C152382D7366p-53 53 +0 53 -0.5 N N
+0 + 53 -0 53 0x10C152382D7366p-53 53 -0 53 +0.5 N N
+0 + 53 +0 53 0x10C152382D7366p-53 53 +0 53 +0.5 N N
+0 - 53 -0 53 0x1921FB54442D18p-52 53 -0 53 +1 N N
+0 - 53 +0 53 0x1921FB54442D18p-52 53 +0 53 +1 N N
+- - 53 -0x1ECC2CAEC5160Ap-53 53 0x1921FB54442D18p-52 53 -0 53 +1.5 N N
++ - 53 0x1ECC2CAEC5160Ap-53 53 0x1921FB54442D18p-52 53 +0 53 +1.5 N N
+
+# regular arguments
++ + 53 0x1E20C7792ECE6Bp-52 53 0x3526776219EEBp-52 53 0x3243F6A8885A3p-48 53 0x162E42FEFA39EFp-53 N N
+
+
diff --git a/mpc/tests/atan.dat b/mpc/tests/atan.dat
new file mode 100644
index 0000000000..871f7068a0
--- /dev/null
+++ b/mpc/tests/atan.dat
@@ -0,0 +1,148 @@
+# Data file for mpc_atan.
+#
+# Copyright (C) 2009, 2012, 2013 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# where op = op_re + i * op_im, rop = rop_re + i * rop_im,
+# rop_re is ROP_RE rounded to nearest to the precision of PREC_ROP_RE
+# rop_im is ROP_IM rounded to nearest to the precision of PREC_ROP_IM
+# op_re is OP_RE rounded to nearest to the precision of PREC_OP_RE
+# op_im is OP_IM rounded to nearest to the precision of PREC_OP_IM
+# ROP_RE is checked against Re(atan op) rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against Im(atan op) rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
++ 0 53 -0x1921FB54442D18p-52 53 -0 53 -inf 53 -inf N N
++ 0 53 -0x1921FB54442D18p-52 53 -0 53 -inf 53 -1 N N
++ 0 53 -0x1921FB54442D18p-52 53 -0 53 -inf 53 -0 N N
++ 0 53 -0x1921FB54442D18p-52 53 +0 53 -inf 53 +0 N N
++ 0 53 -0x1921FB54442D18p-52 53 +0 53 -inf 53 +1 N N
++ 0 53 -0x1921FB54442D18p-52 53 +0 53 -inf 53 +inf N N
++ 0 53 -0x1921FB54442D18p-52 53 0 53 -inf 53 nan N N
++ 0 53 -0x1921FB54442D18p-52 53 -0 53 -6 53 -inf N N
++ 0 53 -0x1921FB54442D18p-52 53 +0 53 -6 53 +inf N N
+0 0 53 nan 53 nan 53 -6 53 nan N N
++ 0 53 -0x1921FB54442D18p-52 53 -0 53 -0 53 -inf N N
+0 0 53 -0 53 -0 53 -0 53 -0 N N
+0 0 53 -0 53 +0 53 -0 53 +0 N N
++ 0 53 -0x1921FB54442D18p-52 53 +0 53 -0 53 +inf N N
+0 0 53 nan 53 nan 53 -0 53 nan N N
+- 0 53 +0x1921FB54442D18p-52 53 -0 53 +0 53 -inf N N
+0 0 53 +0 53 -0 53 +0 53 -0 N N
+0 0 53 +0 53 +0 53 +0 53 +0 N N
+- 0 53 +0x1921FB54442D18p-52 53 +0 53 +0 53 +inf N N
+0 0 53 nan 53 nan 53 +0 53 nan N N
+- 0 53 +0x1921FB54442D18p-52 53 -0 53 +6 53 -inf N N
+- 0 53 +0x1921FB54442D18p-52 53 +0 53 +6 53 +inf N N
+0 0 53 nan 53 nan 53 +6 53 nan N N
+- 0 53 +0x1921FB54442D18p-52 53 -0 53 +inf 53 -inf N N
+- 0 53 +0x1921FB54442D18p-52 53 -0 53 +inf 53 -1 N N
+- 0 53 +0x1921FB54442D18p-52 53 -0 53 +inf 53 -0 N N
+- 0 53 +0x1921FB54442D18p-52 53 +0 53 +inf 53 +0 N N
+- 0 53 +0x1921FB54442D18p-52 53 +0 53 +inf 53 +1 N N
+- 0 53 +0x1921FB54442D18p-52 53 +0 53 +inf 53 +inf N N
+- 0 53 +0x1921FB54442D18p-52 53 0 53 +inf 53 nan N N
+0 0 53 nan 53 -0 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 -0 53 nan 53 -0 N N
+0 0 53 nan 53 +0 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 0 53 nan 53 +0 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# pure real argument
+- 0 53 -0x16DCC57BB565FDp-52 53 -0 53 -7 53 -0 N N
+- 0 53 -0x16DCC57BB565FDp-52 53 +0 53 -7 53 +0 N N
++ 0 53 -0x1F730BD281F69Bp-53 53 -0 53 -1.5 53 -0 N N
++ 0 53 -0x1F730BD281F69Bp-53 53 +0 53 -1.5 53 +0 N N
++ 0 53 -0x1921FB54442D18p-53 53 -0 53 -1 53 -0 N N
++ 0 53 -0x1921FB54442D18p-53 53 +0 53 -1 53 +0 N N
+- 0 53 -0x1700A7C5784634p-53 53 -0 53 -0.875 53 -0 N N
+- 0 53 -0x1700A7C5784634p-53 53 +0 53 -0.875 53 +0 N N
+- 0 53 -0x1FD5BA9AAC2F6Ep-56 53 -0 53 -0.125 53 -0 N N
+- 0 53 -0x1FD5BA9AAC2F6Ep-56 53 +0 53 -0.125 53 +0 N N
++ 0 53 +0x1FD5BA9AAC2F6Ep-56 53 +0 53 +0.125 53 +0 N N
++ 0 53 +0x1FD5BA9AAC2F6Ep-56 53 -0 53 +0.125 53 -0 N N
++ 0 53 +0x1700A7C5784634p-53 53 +0 53 +0.875 53 +0 N N
++ 0 53 +0x1700A7C5784634p-53 53 -0 53 +0.875 53 -0 N N
+- 0 53 +0x1921FB54442D18p-53 53 +0 53 +1 53 +0 N N
+- 0 53 +0x1921FB54442D18p-53 53 -0 53 +1 53 -0 N N
+- 0 53 +0x1F730BD281F69Bp-53 53 +0 53 +1.5 53 +0 N N
+- 0 53 +0x1F730BD281F69Bp-53 53 -0 53 +1.5 53 -0 N N
++ 0 53 +0x16DCC57BB565FDp-52 53 +0 53 +7 53 +0 N N
++ 0 53 +0x16DCC57BB565FDp-52 53 -0 53 +7 53 -0 N N
+
+# pure imaginary argument
++ + 53 -0x1921FB54442D18p-52 53 -0x1269621134DB92p-55 53 -0 53 -7 N N
+- + 53 +0x1921FB54442D18p-52 53 -0x1269621134DB92p-55 53 +0 53 -7 N N
++ + 53 -0x1921FB54442D18p-52 53 -0x19C041F7ED8D33p-53 53 -0 53 -1.5 N N
+- + 53 +0x1921FB54442D18p-52 53 -0x19C041F7ED8D33p-53 53 +0 53 -1.5 N N
+0 0 53 -0 53 -inf 53 -0 53 -1 N N
+0 0 53 +0 53 -inf 53 +0 53 -1 N N
+0 + 53 -0 53 -0x15AA16394D481Fp-52 53 -0 53 -0.875 N N
+0 + 53 +0 53 -0x15AA16394D481Fp-52 53 +0 53 -0.875 N N
+0 + 53 -0 53 -0x1015891C9EAEF7p-55 53 -0 53 -0.125 N N
+0 + 53 +0 53 -0x1015891C9EAEF7p-55 53 +0 53 -0.125 N N
+0 - 53 +0 53 +0x1015891C9EAEF7p-55 53 +0 53 +0.125 N N
+0 - 53 -0 53 +0x1015891C9EAEF7p-55 53 -0 53 +0.125 N N
+0 - 53 +0 53 +0x15AA16394D481Fp-52 53 +0 53 +0.875 N N
+0 - 53 -0 53 +0x15AA16394D481Fp-52 53 -0 53 +0.875 N N
+0 0 53 +0 53 +inf 53 +0 53 +1 N N
+0 0 53 -0 53 +inf 53 -0 53 +1 N N
+- - 53 +0x1921FB54442D18p-52 53 +0x19C041F7ED8D33p-53 53 +0 53 +1.5 N N
++ - 53 -0x1921FB54442D18p-52 53 +0x19C041F7ED8D33p-53 53 -0 53 +1.5 N N
+- - 53 +0x1921FB54442D18p-52 53 +0x1269621134DB92p-55 53 +0 53 +7 N N
++ - 53 -0x1921FB54442D18p-52 53 +0x1269621134DB92p-55 53 -0 53 +7 N N
+0 + 53 +0 53 0x1FFFFFFFFFFF82p-52 53 +0 53 0x1ED9505E1BC3C2p-53 N N
++ - 512 0x6487ED5110B4611A62633145C06E0E68948127044533E63A0105DF531D89CD9128A5043CC71A026EF7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E123p-510 512 0x5D137113B914461DA3202D77346EE4980DA5FD0BAD68F5A7928DCA9F632750D9BFFA00654C523929F15DED554EC6BC476DB2C46FA433E569227085E0BDEA86FFp-509 512 0 512 0x1018734E311AB77B710F9212969B3C86E8F388BB7DA5BAF74ADE078F43D96456D088C8A0B2A370159DFB8D4A4BC51BCDA91F2DCD01B2EC610C62AA33FAD1688p-504 N Z
++ - 12 0xC91p-11 12 0x6F1p-50 12 +0 12 0x9380000000 N N
+
+# general inputs
++ - 72 0x91EA521228BFC46ACAp-118 72 -0x9E96A01DBAD6470974p-73 72 0x84C3E02A5C6DEE8410p-118 72 -0x99B43C52A95A21C220p-73 U N
+- - 72 0x91EA521228BFC46AC9p-118 72 -0x9E96A01DBAD6470974p-73 72 0x84C3E02A5C6DEE8410p-118 72 -0x99B43C52A95A21C220p-73 D D
+- + 72 0x91EA521228BFC46AC9p-118 72 -0x9E96A01DBAD6470973p-73 72 0x84C3E02A5C6DEE8410p-118 72 -0x99B43C52A95A21C220p-73 D U
++ + 72 0x91EA521228BFC46ACAp-118 72 0x9E96A01DBAD6470974p-73 72 0x84C3E02A5C6DEE8410p-118 72 0x99B43C52A95A21C220p-73 U N
+- + 72 0x91EA521228BFC46AC9p-118 72 0x9E96A01DBAD6470974p-73 72 0x84C3E02A5C6DEE8410p-118 72 0x99B43C52A95A21C220p-73 D U
+- - 72 0x91EA521228BFC46AC9p-118 72 0x9E96A01DBAD6470973p-73 72 0x84C3E02A5C6DEE8410p-118 72 0x99B43C52A95A21C220p-73 D D
++ - 156 -0xC90FDAA22167B20DB08A0C3B1FF415CABE49624p-155 156 0xEA84E971BD52E49CCEE036E303D5ECB2D9D9B9Ap-222 156 -0xF0CE58073F866A53F25DB85DE8D503FBDD81051p-109 156 0xCF81D7C76BB9754A52056CB0F144B0C6700CC8Cp-128 N N
+- - 2 0.75 2 -3 2 0x1p-7 2 -1 N N
+- + 2 0.75 2 3 2 0x1p-7 2 1 N N
+
+# improve test coverage
++ - 57 -0x1.921fb54442d184 57 -0x8.a7e33db93ecf18@-34 57 -0xa.529626a89a1960@23 57 -0x3.9a5472b5709e74@14 N N
diff --git a/mpc/tests/atanh.dat b/mpc/tests/atanh.dat
new file mode 100644
index 0000000000..c6517a8829
--- /dev/null
+++ b/mpc/tests/atanh.dat
@@ -0,0 +1,112 @@
+# Data file for mpc_atanh.
+#
+# Copyright (C) 2009, 2013 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# where op = op_re + i * op_im, rop = rop_re + i * rop_im,
+# rop_re is ROP_RE rounded to nearest to the precision of PREC_ROP_RE
+# rop_im is ROP_IM rounded to nearest to the precision of PREC_ROP_IM
+# op_re is OP_RE rounded to nearest to the precision of PREC_OP_RE
+# op_im is OP_IM rounded to nearest to the precision of PREC_OP_IM
+# ROP_RE is checked against Re(atan op) rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against Im(atan op) rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
+0 + 53 -0 53 -0x1921FB54442D18p-52 53 -inf 53 -inf N N
+0 + 53 -0 53 -0x1921FB54442D18p-52 53 -inf 53 -1 N N
+0 + 53 -0 53 -0x1921FB54442D18p-52 53 -inf 53 -0 N N
+0 - 53 -0 53 +0x1921FB54442D18p-52 53 -inf 53 +0 N N
+0 - 53 -0 53 +0x1921FB54442D18p-52 53 -inf 53 +1 N N
+0 - 53 -0 53 +0x1921FB54442D18p-52 53 -inf 53 +inf N N
+0 0 53 -0 53 nan 53 -inf 53 nan N N
+0 + 53 -0 53 -0x1921FB54442D18p-52 53 -6 53 -inf N N
+0 - 53 -0 53 +0x1921FB54442D18p-52 53 -6 53 +inf N N
+0 0 53 nan 53 nan 53 -6 53 nan N N
+0 + 53 -0 53 -0x1921FB54442D18p-52 53 -0 53 -inf N N
+0 0 53 -0 53 -0 53 -0 53 -0 N N
+0 0 53 -0 53 +0 53 -0 53 +0 N N
+0 - 53 -0 53 +0x1921FB54442D18p-52 53 -0 53 +inf N N
+0 0 53 -0 53 nan 53 -0 53 nan N N
+0 + 53 +0 53 -0x1921FB54442D18p-52 53 +0 53 -inf N N
+0 0 53 +0 53 -0 53 +0 53 -0 N N
+0 0 53 +0 53 +0 53 +0 53 +0 N N
+0 - 53 +0 53 +0x1921FB54442D18p-52 53 +0 53 +inf N N
+0 0 53 +0 53 nan 53 +0 53 nan N N
+0 + 53 +0 53 -0x1921FB54442D18p-52 53 +6 53 -inf N N
+0 - 53 +0 53 +0x1921FB54442D18p-52 53 +6 53 +inf N N
+0 0 53 nan 53 nan 53 +6 53 nan N N
+0 + 53 +0 53 -0x1921FB54442D18p-52 53 +inf 53 -inf N N
+0 + 53 +0 53 -0x1921FB54442D18p-52 53 +inf 53 -1 N N
+0 + 53 +0 53 -0x1921FB54442D18p-52 53 +inf 53 -0 N N
+0 - 53 +0 53 +0x1921FB54442D18p-52 53 +inf 53 +0 N N
+0 - 53 +0 53 +0x1921FB54442D18p-52 53 +inf 53 +1 N N
+0 - 53 +0 53 +0x1921FB54442D18p-52 53 +inf 53 +inf N N
+0 0 53 +0 53 nan 53 +inf 53 nan N N
+0 + 53 0 53 -0x1921FB54442D18p-52 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 nan 53 nan 53 -0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 - 53 0 53 +0x1921FB54442D18p-52 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+0 0 53 +inf 53 +0 53 1 53 +0 N N
+
+# pure real argument
+- + 53 -0x1E27076E2AF2E6p-57 53 -0x1921FB54442D18p-52 53 -17 53 -0 N N
+- - 53 -0x1E27076E2AF2E6p-57 53 +0x1921FB54442D18p-52 53 -17 53 +0 N N
++ + 53 +0x1E27076E2AF2E6p-57 53 -0x1921FB54442D18p-52 53 +17 53 -0 N N
++ - 53 +0x1E27076E2AF2E6p-57 53 +0x1921FB54442D18p-52 53 +17 53 +0 N N
++ 0 53 -0x1F2272AE325A57p-53 53 -0 53 -.75 53 -0 N N
++ 0 53 -0x1F2272AE325A57p-53 53 +0 53 -.75 53 +0 N N
+- 0 53 +0x1F2272AE325A57p-53 53 -0 53 +.75 53 -0 N N
+- 0 53 +0x1F2272AE325A57p-53 53 +0 53 +.75 53 +0 N N
+- + 12 0x6F1p-50 12 0xC91p-11 12 0x9380000000 12 +0 N N
+
+# pure imaginary argument
+0 - 53 -0 53 -0x167D8863BC99BDp-52 53 -0 53 -6 N N
+0 - 53 +0 53 -0x167D8863BC99BDp-52 53 +0 53 -6 N N
+0 + 53 -0 53 +0x167D8863BC99BDp-52 53 -0 53 +6 N N
+0 + 53 +0 53 +0x167D8863BC99BDp-52 53 +0 53 +6 N N
+0 + 53 -0 53 -0x1F5B75F92C80DDp-55 53 -0 53 -.25 N N
+0 + 53 +0 53 -0x1F5B75F92C80DDp-55 53 +0 53 -.25 N N
+0 - 53 -0 53 +0x1F5B75F92C80DDp-55 53 -0 53 +.25 N N
+0 - 53 +0 53 +0x1F5B75F92C80DDp-55 53 +0 53 +.25 N N
+
+# IEEE-754 double precision
+- + 53 0x13F3F785301CE9p-54 53 0xBFA43C2A868B3p-51 53 0x3243F6A8885A3p-48 53 0x162E42FEFA39EFp-53 N N
diff --git a/mpc/tests/comparisons.c b/mpc/tests/comparisons.c
new file mode 100644
index 0000000000..d10c878450
--- /dev/null
+++ b/mpc/tests/comparisons.c
@@ -0,0 +1,45 @@
+/* comparisons.c -- Comparison functions.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+/* comparisons, see description in mpc-tests.h */
+int
+same_mpfr_value (mpfr_ptr got, mpfr_ptr ref, int known_sign)
+{
+ /* The sign of zeroes and infinities is checked only when
+ known_sign is true. */
+ if (mpfr_nan_p (got))
+ return mpfr_nan_p (ref);
+ if (mpfr_inf_p (got))
+ return mpfr_inf_p (ref) &&
+ (!known_sign || mpfr_signbit (got) == mpfr_signbit (ref));
+ if (mpfr_zero_p (got))
+ return mpfr_zero_p (ref) &&
+ (!known_sign || mpfr_signbit (got) == mpfr_signbit (ref));
+ return mpfr_cmp (got, ref) == 0;
+}
+
+int
+same_mpc_value (mpc_ptr got, mpc_ptr ref, known_signs_t known_signs)
+{
+ return same_mpfr_value (mpc_realref (got), mpc_realref (ref), known_signs.re)
+ && same_mpfr_value (mpc_imagref (got), mpc_imagref (ref), known_signs.im);
+}
diff --git a/mpc/tests/conj.dat b/mpc/tests/conj.dat
new file mode 100644
index 0000000000..ecc249b48e
--- /dev/null
+++ b/mpc/tests/conj.dat
@@ -0,0 +1,114 @@
+# Data file for mpc_conj.
+#
+# Copyright (C) 2008, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# see sin.dat for precisions
+
+# special values (following ISO C99 standard)
+0 0 53 -inf 53 +inf 53 -inf 53 -inf N N
+0 0 53 -inf 53 +1 53 -inf 53 -1 N N
+0 0 53 -inf 53 +0 53 -inf 53 -0 N N
+0 0 53 -inf 53 -0 53 -inf 53 +0 N N
+0 0 53 -inf 53 -1 53 -inf 53 +1 N N
+0 0 53 -inf 53 -inf 53 -inf 53 +inf N N
+0 0 53 -inf 53 nan 53 -inf 53 nan N N
+0 0 53 -1 53 +inf 53 -1 53 -inf N N
+0 0 53 -1 53 +0 53 -1 53 -0 N N
+0 0 53 -1 53 -0 53 -1 53 +0 N N
+0 0 53 -1 53 -inf 53 -1 53 +inf N N
+0 0 53 -1 53 nan 53 -1 53 nan N N
+0 0 53 -0 53 +inf 53 -0 53 -inf N N
+0 0 53 -0 53 +1 53 -0 53 -1 N N
+0 0 53 -0 53 +0 53 -0 53 -0 N N
+0 0 53 -0 53 -0 53 -0 53 +0 N N
+0 0 53 -0 53 -1 53 -0 53 +1 N N
+0 0 53 -0 53 -inf 53 -0 53 +inf N N
+0 0 53 -0 53 nan 53 -0 53 nan N N
+0 0 53 +0 53 +inf 53 +0 53 -inf N N
+0 0 53 +0 53 +1 53 +0 53 -1 N N
+0 0 53 +0 53 +0 53 +0 53 -0 N N
+0 0 53 +0 53 -0 53 +0 53 +0 N N
+0 0 53 +0 53 -1 53 +0 53 +1 N N
+0 0 53 +0 53 -inf 53 +0 53 +inf N N
+0 0 53 +0 53 nan 53 +0 53 nan N N
+0 0 53 +1 53 +inf 53 +1 53 -inf N N
+0 0 53 +1 53 +0 53 +1 53 -0 N N
+0 0 53 +1 53 -0 53 +1 53 +0 N N
+0 0 53 +1 53 -inf 53 +1 53 +inf N N
+0 0 53 +1 53 nan 53 +1 53 nan N N
+0 0 53 +inf 53 +inf 53 +inf 53 -inf N N
+0 0 53 +inf 53 +1 53 +inf 53 -1 N N
+0 0 53 +inf 53 +0 53 +inf 53 -0 N N
+0 0 53 +inf 53 -0 53 +inf 53 +0 N N
+0 0 53 +inf 53 -1 53 +inf 53 +1 N N
+0 0 53 +inf 53 -inf 53 +inf 53 +inf N N
+0 0 53 +inf 53 nan 53 +inf 53 nan N N
+0 0 53 nan 53 +inf 53 nan 53 -inf N N
+0 0 53 nan 53 +1 53 nan 53 -1 N N
+0 0 53 nan 53 +0 53 nan 53 -0 N N
+0 0 53 nan 53 -0 53 nan 53 +0 N N
+0 0 53 nan 53 -1 53 nan 53 +1 N N
+0 0 53 nan 53 -inf 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# pure real argument
+0 0 53 0x123456789abcdep+52 2 -0 53 0x123456789abcdep+52 17 +0 N N
+0 0 53 -0x123456789abcdep+52 3 -0 54 -0x123456789abcdep+52 16 +0 Z N
+0 0 53 0x123456789abcdep+52 4 +0 55 0x123456789abcdep+52 15 -0 U N
+0 0 53 -0x123456789abcdep+52 5 +0 56 -0x123456789abcdep+52 14 -0 D N
+0 0 53 0x123456789abcdep+52 6 -0 57 0x123456789abcdep+52 13 +0 Z Z
+0 0 53 -0x123456789abcdep+52 7 -0 58 -0x123456789abcdep+52 12 +0 U Z
+0 0 53 0x123456789abcdep+52 8 +0 59 0x123456789abcdep+52 11 -0 D Z
+0 0 53 -0x123456789abcdep+52 9 +0 60 -0x123456789abcdep+52 10 -0 N Z
+0 0 53 0x123456789abcdep+52 10 -0 61 0x123456789abcdep+52 9 +0 U U
+0 0 53 -0x123456789abcdep+52 11 -0 62 -0x123456789abcdep+52 8 +0 D U
+0 0 53 0x123456789abcdep+52 12 +0 63 0x123456789abcdep+52 7 -0 N U
+0 0 53 -0x123456789abcdep+52 13 +0 64 -0x123456789abcdep+52 6 -0 Z U
+0 0 53 0x123456789abcdep+52 14 -0 65 0x123456789abcdep+52 5 +0 D D
+0 0 53 -0x123456789abcdep+52 15 -0 66 -0x123456789abcdep+52 4 +0 N D
+0 0 53 0x123456789abcdep+52 16 +0 67 0x123456789abcdep+52 3 -0 Z D
+0 0 53 -0x123456789abcdep+52 17 +0 68 -0x123456789abcdep+52 2 -0 U D
+
+# pure imaginary argument
+0 0 53 +0 53 -0x123456789abcdep+52 53 +0 53 0x123456789abcdep+52 N N
+0 0 53 -0 53 -0x123456789abcdep+52 51 -0 54 0x123456789abcdep+52 Z N
+0 0 53 +0 53 0x123456789abcdep+52 49 +0 55 -0x123456789abcdep+52 U N
+0 0 53 -0 53 0x123456789abcdep+52 47 -0 56 -0x123456789abcdep+52 D N
+0 0 53 +0 53 -0x123456789abcdep+52 45 +0 57 0x123456789abcdep+52 Z Z
+0 0 53 -0 53 -0x123456789abcdep+52 43 -0 58 0x123456789abcdep+52 U Z
+0 0 53 +0 53 0x123456789abcdep+52 41 +0 59 -0x123456789abcdep+52 D Z
+0 0 53 -0 53 0x123456789abcdep+52 39 -0 60 -0x123456789abcdep+52 N Z
+0 0 53 +0 53 -0x123456789abcdep+52 37 +0 61 0x123456789abcdep+52 U U
+0 0 53 -0 53 -0x123456789abcdep+52 35 -0 62 0x123456789abcdep+52 D U
+0 0 53 +0 53 0x123456789abcdep+52 33 +0 63 -0x123456789abcdep+52 N U
+0 0 53 -0 53 0x123456789abcdep+52 31 -0 64 -0x123456789abcdep+52 Z U
+0 0 53 +0 53 -0x123456789abcdep+52 29 +0 65 0x123456789abcdep+52 D D
+0 0 53 -0 53 -0x123456789abcdep+52 27 -0 66 0x123456789abcdep+52 N D
+0 0 53 +0 53 0x123456789abcdep+52 25 +0 67 -0x123456789abcdep+52 Z D
+0 0 53 -0 53 0x123456789abcdep+52 23 -0 68 -0x123456789abcdep+52 U D
+
+# non-exact return values
+- - 2 4 2 -8 3 5 3 7 N N
+- + 2 4 2 -6 3 5 3 7 D U
++ - 2 6 2 -8 3 5 3 7 U D
+- + 2 4 2 -6 3 5 3 7 Z Z
diff --git a/mpc/tests/cos.dat b/mpc/tests/cos.dat
new file mode 100644
index 0000000000..739409fa4c
--- /dev/null
+++ b/mpc/tests/cos.dat
@@ -0,0 +1,85 @@
+# Data file for mpc_cos.
+#
+# Copyright (C) 2008, 2010 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see sin.dat.
+
+# special values (following ISO C99 standard)
+0 0 7 inf 7 NaN 7 -inf 7 -inf N N
+0 0 7 NaN 7 NaN 7 -inf 7 -1 N N
+0 0 7 NaN 7 0 7 -inf 7 -0 N N
+0 0 7 NaN 7 0 7 -inf 7 +0 N N
+0 0 7 NaN 7 NaN 7 -inf 7 1 N N
+0 0 7 inf 7 NaN 7 -inf 7 +inf N N
+0 0 7 NaN 7 NaN 7 -inf 7 NaN N N
+0 0 7 +inf 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 +inf 7 -1 7 +inf N N
+0 0 7 NaN 7 NaN 7 -1 7 NaN N N
+0 0 7 +inf 7 -0 7 -0 7 -inf N N
+0 0 7 1 7 -0 7 -0 7 -0 N N
+0 0 7 1 7 +0 7 -0 7 +0 N N
+0 0 7 +inf 7 +0 7 -0 7 +inf N N
+0 0 7 NaN 7 0 7 -0 7 NaN N N
+0 0 7 +inf 7 +0 7 +0 7 -inf N N
+0 0 7 1 7 +0 7 +0 7 -0 N N
+0 0 7 1 7 -0 7 +0 7 +0 N N
+0 0 7 +inf 7 -0 7 +0 7 +inf N N
+0 0 7 NaN 7 0 7 +0 7 NaN N N
+0 0 7 +inf 7 +inf 7 1 7 -inf N N
+0 0 7 +inf 7 -inf 7 1 7 +inf N N
+0 0 7 NaN 7 NaN 7 1 7 NaN N N
+0 0 7 inf 7 NaN 7 +inf 7 -inf N N
+0 0 7 NaN 7 NaN 7 +inf 7 -1 N N
+0 0 7 NaN 7 0 7 +inf 7 -0 N N
+0 0 7 NaN 7 0 7 +inf 7 +0 N N
+0 0 7 NaN 7 NaN 7 +inf 7 1 N N
+0 0 7 inf 7 NaN 7 +inf 7 +inf N N
+0 0 7 NaN 7 NaN 7 +inf 7 NaN N N
+0 0 7 +inf 7 NaN 7 NaN 7 -inf N N
+0 0 7 NaN 7 NaN 7 NaN 7 -1 N N
+0 0 7 NaN 7 0 7 NaN 7 -0 N N
+0 0 7 NaN 7 0 7 NaN 7 +0 N N
+0 0 7 NaN 7 NaN 7 NaN 7 1 N N
+0 0 7 +inf 7 NaN 7 NaN 7 +inf N N
+0 0 7 NaN 7 NaN 7 NaN 7 NaN N N
+
+# purely real argument
+- 0 50 0x8a51407da8344p-52 50 -0 7 -1 7 -0 N N
+- 0 50 0x8a51407da8344p-52 50 +0 7 -1 7 +0 N N
+- 0 50 0x8a51407da8344p-52 50 +0 7 1 7 -0 N N
+- 0 50 0x8a51407da8344p-52 50 -0 7 1 7 +0 N N
+
+# purely imaginary argument
+- 0 50 0x18b07551d9f55p-48 50 -0 7 -0 7 -1 N N
+- 0 50 0x18b07551d9f55p-48 50 +0 7 -0 7 1 N N
+- 0 50 0x18b07551d9f55p-48 50 +0 7 +0 7 -1 N N
+- 0 50 0x18b07551d9f55p-48 50 -0 7 +0 7 1 N N
+
+# values with +1 and -1
+- + 50 0xd56f54b7a1accp-52 50 -0xfd28666957478p-52 7 -1 7 -1 N N
+- - 50 0xd56f54b7a1accp-52 50 0xfd28666957478p-52 7 -1 7 1 N N
+- - 50 0xd56f54b7a1accp-52 50 0xfd28666957478p-52 7 1 7 -1 N N
+- + 50 0xd56f54b7a1accp-52 50 -0xfd28666957478p-52 7 1 7 1 N N
+
+# IEEE-754 double precision
++ 0 53 514 53 -0 53 +0 53 0x1BBDD1808C59A3p-50 N N
+- 0 53 0x100FFFFFFFFFFFp-43 53 -0 53 +0 53 0x1BBDD1808C59A3p-50 D D
+
+# huge values
+- + 53 -inf 53 +inf 53 0x4580CBF242683p-3 53 -0x1B3E8A3660D279p-3 N N
++ + 53 +inf 53 +inf 53 -0x1B3E8A3660D279p-3 53 0x4580CBF242683p-3 N N
diff --git a/mpc/tests/cosh.dat b/mpc/tests/cosh.dat
new file mode 100644
index 0000000000..7a766a3f65
--- /dev/null
+++ b/mpc/tests/cosh.dat
@@ -0,0 +1,133 @@
+# Data test file for mpc_cosh.
+#
+# Copyright (C) 2008, 2010 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+# See file sin.dat for the format description.
+
+# Special values, following ISO C99 standard, Annex G,
+# more precisely Section G.6.2.4 "The ccosh functions".
+
+# Rule [conj]: cosh(conj(z)) = conj(cosh(z))
+# Rule [even]: cosh(-z) = cosh(z)
+
+# cosh(+0 + i*0) = 1 + i*0
+0 0 2 1 2 +0 2 +0 2 +0 N N
+# [conj]: cosh(+0 - i*0) = 1 - i*0
+0 0 2 1 2 -0 2 +0 2 -0 N N
+# [even]: cosh(-0 - i*0) = 1 + i*0
+0 0 2 1 2 +0 2 -0 2 -0 N N
+# [even+conj]: cosh(-0 + i*0) = 1 - i*0
+0 0 2 1 2 -0 2 -0 2 +0 N N
+
+# cosh(+0 + i*inf) = nan + i*0 (C99 says that the sign of the imaginary part
+# is left unspecified)
+0 0 2 nan 2 0 2 +0 2 +inf N N
+# [conj]: cosh(+0 - i*inf) = nan - i*0
+0 0 2 nan 2 0 2 +0 2 -inf N N
+# [even]: cosh(-0 - i*inf) = nan + i*0
+0 0 2 nan 2 0 2 -0 2 -inf N N
+# [even+conj]: cosh(-0 + i*inf) = nan - i*0
+0 0 2 nan 2 0 2 -0 2 +inf N N
+
+# cosh(+0 +i*nan) = nan + i*0 (C99 says that the sign of the imaginary part
+# is left unspecified)
+0 0 2 nan 2 0 2 +0 2 nan N N
+# [even]: cosh(-0 + i*nan) = nan + i*0
+0 0 2 nan 2 0 2 -0 2 nan N N
+
+# cosh(x + i*inf) = nan + i*nan for finite nonzero x
+0 0 2 nan 2 nan 2 1 2 inf N N
+0 0 2 nan 2 nan 2 -1 2 inf N N
+# [conj]: cosh(x - i*inf) = nan + i*nan
+0 0 2 nan 2 nan 2 1 2 -inf N N
+0 0 2 nan 2 nan 2 -1 2 -inf N N
+# [even] and [even+conj] are already considered for x=-1 < 0
+
+# cosh(x + i*nan) = nan + i*nan for finite nonzero x
+0 0 2 nan 2 nan 2 1 2 nan N N
+0 0 2 nan 2 nan 2 -1 2 nan N N
+# [conj] makes no sense since nan has no sign
+# [even] is already considered for x=-1 < 0
+
+# cosh(+inf + i*0) = +inf + i*0
+0 0 2 +inf 2 +0 2 +inf 2 +0 N N
+# [conj]: cosh(+inf - i*0) = +inf - i*0
+0 0 2 +inf 2 -0 2 +inf 2 -0 N N
+# [even]: cosh(-inf - i*0) = +inf + i*0
+0 0 2 +inf 2 +0 2 -inf 2 -0 N N
+# [even+conj]: cosh(-inf + i*0) = +inf - i*0
+0 0 2 +inf 2 -0 2 -inf 2 +0 N N
+
+# cosh(+inf + i*y) = +inf * (cos(y) + i*sin(y)) for finite non-zero y
+0 0 2 +inf 2 +inf 2 +inf 2 1 N N
+0 0 2 -inf 2 +inf 2 +inf 2 2 N N
+0 0 2 -inf 2 -inf 2 +inf 2 4 N N
+0 0 2 +inf 2 -inf 2 +inf 2 1024 N N
+# [conj]
+0 0 2 +inf 2 -inf 2 +inf 2 -1 N N
+0 0 2 -inf 2 -inf 2 +inf 2 -2 N N
+0 0 2 -inf 2 +inf 2 +inf 2 -4 N N
+0 0 2 +inf 2 +inf 2 +inf 2 -1024 N N
+# [even]
+0 0 2 +inf 2 +inf 2 -inf 2 -1 N N
+0 0 2 -inf 2 +inf 2 -inf 2 -2 N N
+0 0 2 -inf 2 -inf 2 -inf 2 -4 N N
+0 0 2 +inf 2 -inf 2 -inf 2 -1024 N N
+# [even+conj]
+0 0 2 +inf 2 -inf 2 -inf 2 1 N N
+0 0 2 -inf 2 -inf 2 -inf 2 2 N N
+0 0 2 -inf 2 +inf 2 -inf 2 4 N N
+0 0 2 +inf 2 +inf 2 -inf 2 1024 N N
+
+# cosh(+inf + i*inf) = +inf + i*nan (C99 leaves unspecified the sign of the
+# real part)
+0 0 2 inf 2 nan 2 +inf 2 +inf N N
+# [conj]: cosh(+inf - i*inf) = +inf + i*nan
+0 0 2 inf 2 nan 2 +inf 2 -inf N N
+# [even]: cosh(-inf - i*inf) = +inf + i*nan
+0 0 2 inf 2 nan 2 -inf 2 -inf N N
+# [even+conj]: cosh(-inf + i*inf) = +inf + i*nan
+0 0 2 inf 2 nan 2 -inf 2 +inf N N
+
+# cosh(+inf + i*nan) = +inf + i*nan
+0 0 2 +inf 2 nan 2 +inf 2 nan N N
+# [conj] makes no sense since NaN has no sign
+# [even]: cosh(-inf + i*nan) = +inf + i*nan
+0 0 2 +inf 2 nan 2 -inf 2 nan N N
+
+# cosh(nan + i*0) = nan - i*0 (C99 leaves unspecified the sign of the
+# imaginary part)
+0 0 2 nan 2 0 2 nan 2 +0 N N
+# [conj]: cosh(nan - i*0) = nan + i*0
+0 0 2 nan 2 0 2 nan 2 -0 N N
+
+# cosh(nan + i*y) = nan + i*nan for all nonzero y (including +/-inf)
+0 0 2 nan 2 nan 2 nan 2 1 N N
+0 0 2 nan 2 nan 2 nan 2 -1 N N
+0 0 2 nan 2 nan 2 nan 2 +inf N N
+0 0 2 nan 2 nan 2 nan 2 -inf N N
+
+# cosh(nan + i*nan) = nan + i*nan
+0 0 2 nan 2 nan 2 nan 2 nan N N
+
++ + 53 0x10000000000001p-53 53 0x10000000000001p-52 53 0x1DA2E1BD2C9EBCp-53 53 0x138AADEA15829Fp-52 N N
+
+
+# huge values
++ - 53 +inf 53 -inf 53 0x4580CBF242683p-3 53 -0x1B3E8A3660D279p-3 N N
+- - 53 -inf 53 -inf 53 -0x1B3E8A3660D279p-3 53 0x4580CBF242683p-3 N N
diff --git a/mpc/tests/div.dat b/mpc/tests/div.dat
new file mode 100644
index 0000000000..6f5e6009c7
--- /dev/null
+++ b/mpc/tests/div.dat
@@ -0,0 +1,2486 @@
+# Data file for mpc_div.
+#
+# Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see add.dat.
+
+# special values
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 nan 7 -inf 7 -inf 7 -1 7 -1 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -inf 7 -1 7 -0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -inf 7 -1 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 -inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -0 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 -inf 7 -0 7 -1 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -inf 7 -0 7 -0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 -inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +0 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 -inf 7 +0 7 -1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 +0 7 -0 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 -inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 1 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 -inf 7 1 7 -1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 1 7 -0 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 nan 7 -inf 7 -inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -1 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 -1 7 -1 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 -1 7 -1 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 -1 7 -1 7 +0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -1 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 -1 7 -0 7 -1 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -1 7 -0 7 -0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -1 7 -0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 -1 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 -1 7 +0 7 -1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -1 7 +0 7 -0 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -1 7 +0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 -1 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 1 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 -1 7 1 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 -1 7 1 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 -1 7 1 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 -1 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -1 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 -0 7 -1 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 -0 7 -1 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 -0 7 -1 7 +0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -0 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 -0 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 -0 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 -0 7 -0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 -0 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 -0 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 -0 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 -0 7 +0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 -0 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 1 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 -0 7 1 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 -0 7 1 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 -0 7 1 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 -0 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -1 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 +0 7 -1 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 +0 7 -1 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 +0 7 -1 7 +0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 +0 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 +0 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 +0 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 +0 7 -0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 +0 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 +0 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 +0 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 +0 7 +0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 +0 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 1 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 +0 7 1 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 +0 7 1 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 +0 7 1 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +0 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -1 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 1 7 -1 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 1 7 -1 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 1 7 -1 7 +0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 1 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 1 7 -0 7 -1 N N
+0 0 7 +inf 7 -inf 7 -inf 7 1 7 -0 7 -0 N N
+0 0 7 +inf 7 -inf 7 -inf 7 1 7 -0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 1 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 1 7 +0 7 -1 N N
+0 0 7 -inf 7 +inf 7 -inf 7 1 7 +0 7 -0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 1 7 +0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 1 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 1 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 1 7 1 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 1 7 1 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 1 7 1 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 1 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -1 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 +inf 7 -1 7 -1 N N
+0 0 7 +inf 7 -inf 7 -inf 7 +inf 7 -1 7 -0 N N
+0 0 7 +inf 7 -inf 7 -inf 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 nan 7 -inf 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -0 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 +inf 7 -0 7 -1 N N
+0 0 7 +inf 7 -inf 7 -inf 7 +inf 7 -0 7 -0 N N
+0 0 7 +inf 7 -inf 7 -inf 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +0 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 +inf 7 +0 7 -1 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 +0 7 -0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 1 7 -inf N N
+0 0 7 -inf 7 nan 7 -inf 7 +inf 7 1 7 -1 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 1 7 -0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 1 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -1 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 nan 7 -1 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 nan 7 -1 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 nan 7 -1 7 +0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 nan 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 nan 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 nan 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 1 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 nan 7 1 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 1 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 1 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 nan 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 +inf 7 -1 7 -inf 7 -1 7 -1 N N
+0 0 7 nan 7 +inf 7 -1 7 -inf 7 -1 7 -0 N N
+0 0 7 nan 7 +inf 7 -1 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 +inf 7 -1 7 -inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -0 7 -inf N N
+0 0 7 +inf 7 nan 7 -1 7 -inf 7 -0 7 -1 N N
+0 0 7 +inf 7 +inf 7 -1 7 -inf 7 -0 7 -0 N N
+0 0 7 +inf 7 +inf 7 -1 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 nan 7 -1 7 -inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +0 7 -inf N N
+0 0 7 +inf 7 nan 7 -1 7 -inf 7 +0 7 -1 N N
+0 0 7 -inf 7 -inf 7 -1 7 -inf 7 +0 7 -0 N N
+0 0 7 -inf 7 -inf 7 -1 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 nan 7 -1 7 -inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 1 7 -inf N N
+0 0 7 +inf 7 -inf 7 -1 7 -inf 7 1 7 -1 N N
+0 0 7 nan 7 -inf 7 -1 7 -inf 7 1 7 -0 N N
+0 0 7 nan 7 -inf 7 -1 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 -inf 7 -1 7 -inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 nan 7 nan N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 -inf 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 -inf 7 -1 N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 -inf 7 -0 N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 -inf 7 +0 N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 -inf 7 1 N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 -inf 7 +inf N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 -inf 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -1 7 -1 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 -1 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -1 7 -0 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 -0 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -1 7 +0 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 +0 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -1 7 1 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 1 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -1 7 +inf 7 -inf N N
+0 0 7 -0 7 -0 7 -1 7 -1 7 +inf 7 -1 N N
+0 0 7 -0 7 -0 7 -1 7 -1 7 +inf 7 -0 N N
+0 0 7 -0 7 -0 7 -1 7 -1 7 +inf 7 +0 N N
+0 0 7 -0 7 -0 7 -1 7 -1 7 +inf 7 1 N N
+0 0 7 -0 7 +0 7 -1 7 -1 7 +inf 7 +inf N N
+0 0 7 -0 7 -0 7 -1 7 -1 7 +inf 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 nan 7 1 N N
+0 0 7 -0 7 +0 7 -1 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 nan 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -0 7 -inf 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -inf 7 -1 N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -inf 7 -0 N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -inf 7 +0 N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -inf 7 1 N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -inf 7 +inf N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -inf 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -0 7 -1 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 -1 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -0 7 -0 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 -0 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -0 7 +0 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 +0 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -0 7 1 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 1 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 -0 7 +inf 7 -inf N N
+0 0 7 -0 7 -0 7 -1 7 -0 7 +inf 7 -1 N N
+0 0 7 -0 7 -0 7 -1 7 -0 7 +inf 7 -0 N N
+0 0 7 -0 7 +0 7 -1 7 -0 7 +inf 7 +0 N N
+0 0 7 -0 7 +0 7 -1 7 -0 7 +inf 7 1 N N
+0 0 7 -0 7 +0 7 -1 7 -0 7 +inf 7 +inf N N
+0 0 7 -0 7 +0 7 -1 7 -0 7 +inf 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 nan 7 1 N N
+0 0 7 -0 7 +0 7 -1 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 nan 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 +0 7 -inf 7 -inf N N
+0 0 7 +0 7 -0 7 -1 7 +0 7 -inf 7 -1 N N
+0 0 7 +0 7 -0 7 -1 7 +0 7 -inf 7 -0 N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 -inf 7 +0 N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 -inf 7 1 N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 -inf 7 +inf N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 -inf 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 +0 7 -1 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 -1 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 +0 7 -0 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 -0 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 +0 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 +0 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 +0 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 1 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 +0 7 +inf 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 +0 7 +inf 7 -1 N N
+0 0 7 -0 7 +0 7 -1 7 +0 7 +inf 7 -0 N N
+0 0 7 -0 7 +0 7 -1 7 +0 7 +inf 7 +0 N N
+0 0 7 -0 7 +0 7 -1 7 +0 7 +inf 7 1 N N
+0 0 7 -0 7 +0 7 -1 7 +0 7 +inf 7 +inf N N
+0 0 7 -0 7 +0 7 -1 7 +0 7 +inf 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 +0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 nan 7 1 N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 nan 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 1 7 -inf 7 -inf N N
+0 0 7 +0 7 -0 7 -1 7 1 7 -inf 7 -1 N N
+0 0 7 +0 7 -0 7 -1 7 1 7 -inf 7 -0 N N
+0 0 7 +0 7 -0 7 -1 7 1 7 -inf 7 +0 N N
+0 0 7 +0 7 -0 7 -1 7 1 7 -inf 7 1 N N
+0 0 7 +0 7 +0 7 -1 7 1 7 -inf 7 +inf N N
+0 0 7 +0 7 -0 7 -1 7 1 7 -inf 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 1 7 -1 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 1 7 -1 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 1 7 -0 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 1 7 -0 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 1 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 1 7 +0 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 1 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 1 7 1 7 nan N N
+0 0 7 -0 7 +0 7 -1 7 1 7 +inf 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 1 7 +inf 7 -1 N N
+0 0 7 -0 7 +0 7 -1 7 1 7 +inf 7 -0 N N
+0 0 7 -0 7 +0 7 -1 7 1 7 +inf 7 +0 N N
+0 0 7 -0 7 +0 7 -1 7 1 7 +inf 7 1 N N
+0 0 7 +0 7 +0 7 -1 7 1 7 +inf 7 +inf N N
+0 0 7 -0 7 +0 7 -1 7 1 7 +inf 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 1 7 nan 7 1 N N
+0 0 7 +0 7 +0 7 -1 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -1 7 -inf N N
+0 0 7 -inf 7 -inf 7 -1 7 +inf 7 -1 7 -1 N N
+0 0 7 nan 7 -inf 7 -1 7 +inf 7 -1 7 -0 N N
+0 0 7 nan 7 -inf 7 -1 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 -inf 7 -1 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -0 7 -inf N N
+0 0 7 -inf 7 nan 7 -1 7 +inf 7 -0 7 -1 N N
+0 0 7 +inf 7 -inf 7 -1 7 +inf 7 -0 7 -0 N N
+0 0 7 +inf 7 -inf 7 -1 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 nan 7 -1 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +0 7 -inf N N
+0 0 7 -inf 7 nan 7 -1 7 +inf 7 +0 7 -1 N N
+0 0 7 -inf 7 +inf 7 -1 7 +inf 7 +0 7 -0 N N
+0 0 7 -inf 7 +inf 7 -1 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 nan 7 -1 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 1 7 -inf N N
+0 0 7 -inf 7 +inf 7 -1 7 +inf 7 1 7 -1 N N
+0 0 7 nan 7 +inf 7 -1 7 +inf 7 1 7 -0 N N
+0 0 7 nan 7 +inf 7 -1 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 +inf 7 -1 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -1 7 nan 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 -1 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 -1 7 nan 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -1 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 +inf 7 -0 7 -inf 7 -1 7 -1 N N
+0 0 7 nan 7 +inf 7 -0 7 -inf 7 -1 7 -0 N N
+0 0 7 nan 7 +inf 7 -0 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 +inf 7 -0 7 -inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -0 7 -inf N N
+0 0 7 +inf 7 nan 7 -0 7 -inf 7 -0 7 -1 N N
+0 0 7 nan 7 +inf 7 -0 7 -inf 7 -0 7 -0 N N
+0 0 7 nan 7 +inf 7 -0 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 nan 7 -0 7 -inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +0 7 -inf N N
+0 0 7 +inf 7 nan 7 -0 7 -inf 7 +0 7 -1 N N
+0 0 7 nan 7 -inf 7 -0 7 -inf 7 +0 7 -0 N N
+0 0 7 nan 7 -inf 7 -0 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 nan 7 -0 7 -inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 1 7 -inf N N
+0 0 7 +inf 7 -inf 7 -0 7 -inf 7 1 7 -1 N N
+0 0 7 nan 7 -inf 7 -0 7 -inf 7 1 7 -0 N N
+0 0 7 nan 7 -inf 7 -0 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 -inf 7 -0 7 -inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 nan 7 nan N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -inf 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -inf 7 -1 N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -inf 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -inf 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -inf 7 1 N N
+0 0 7 -0 7 +0 7 -0 7 -1 7 -inf 7 +inf N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -inf 7 nan N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -1 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 -1 7 nan N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -0 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 -0 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -1 7 +0 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 +0 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -1 7 1 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 1 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -1 7 +inf 7 -inf N N
+0 0 7 +0 7 -0 7 -0 7 -1 7 +inf 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 -1 7 +inf 7 -0 N N
+0 0 7 -0 7 -0 7 -0 7 -1 7 +inf 7 +0 N N
+0 0 7 -0 7 -0 7 -0 7 -1 7 +inf 7 1 N N
+0 0 7 -0 7 -0 7 -0 7 -1 7 +inf 7 +inf N N
+0 0 7 -0 7 -0 7 -0 7 -1 7 +inf 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 nan 7 1 N N
+0 0 7 -0 7 +0 7 -0 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 nan 7 nan N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -inf 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -inf 7 -1 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -inf 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -inf 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -inf 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -inf 7 +inf N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -inf 7 nan N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -1 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 -1 7 nan N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -0 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 -0 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 +0 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 +0 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 1 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 1 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 +inf 7 -inf N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 +inf 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 +inf 7 -0 N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 +inf 7 +0 N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 +inf 7 1 N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 +inf 7 +inf N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 +inf 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 nan 7 1 N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 nan 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -inf 7 -inf N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -inf 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -inf 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 -inf 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 -inf 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 -inf 7 +inf N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 -inf 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -1 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 -1 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -0 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 -0 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 +0 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 1 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 +inf 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 +inf 7 -1 N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 +inf 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 +inf 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 +inf 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 +inf 7 +inf N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 +inf 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 nan 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 nan 7 nan N N
+0 0 7 -0 7 -0 7 -0 7 1 7 -inf 7 -inf N N
+0 0 7 +0 7 -0 7 -0 7 1 7 -inf 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 1 7 -inf 7 -0 N N
+0 0 7 +0 7 -0 7 -0 7 1 7 -inf 7 +0 N N
+0 0 7 +0 7 -0 7 -0 7 1 7 -inf 7 1 N N
+0 0 7 +0 7 -0 7 -0 7 1 7 -inf 7 +inf N N
+0 0 7 +0 7 -0 7 -0 7 1 7 -inf 7 nan N N
+0 0 7 -0 7 -0 7 -0 7 1 7 -1 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 1 7 -1 7 nan N N
+0 0 7 -0 7 -0 7 -0 7 1 7 -0 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 1 7 -0 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 1 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 1 7 +0 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 1 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 1 7 1 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 1 7 +inf 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 1 7 +inf 7 -1 N N
+0 0 7 -0 7 +0 7 -0 7 1 7 +inf 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 1 7 +inf 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 1 7 +inf 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 1 7 +inf 7 +inf N N
+0 0 7 +0 7 +0 7 -0 7 1 7 +inf 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 1 7 nan 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -1 7 -inf N N
+0 0 7 -inf 7 -inf 7 -0 7 +inf 7 -1 7 -1 N N
+0 0 7 nan 7 -inf 7 -0 7 +inf 7 -1 7 -0 N N
+0 0 7 nan 7 -inf 7 -0 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 -inf 7 -0 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -0 7 -inf N N
+0 0 7 -inf 7 nan 7 -0 7 +inf 7 -0 7 -1 N N
+0 0 7 nan 7 -inf 7 -0 7 +inf 7 -0 7 -0 N N
+0 0 7 nan 7 -inf 7 -0 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 nan 7 -0 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +0 7 -inf N N
+0 0 7 -inf 7 nan 7 -0 7 +inf 7 +0 7 -1 N N
+0 0 7 nan 7 +inf 7 -0 7 +inf 7 +0 7 -0 N N
+0 0 7 nan 7 +inf 7 -0 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 nan 7 -0 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 1 7 -inf N N
+0 0 7 -inf 7 +inf 7 -0 7 +inf 7 1 7 -1 N N
+0 0 7 nan 7 +inf 7 -0 7 +inf 7 1 7 -0 N N
+0 0 7 nan 7 +inf 7 -0 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 +inf 7 -0 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 +inf 7 +0 7 -inf 7 -1 7 -1 N N
+0 0 7 nan 7 +inf 7 +0 7 -inf 7 -1 7 -0 N N
+0 0 7 nan 7 +inf 7 +0 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 +inf 7 +0 7 -inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -0 7 -inf N N
+0 0 7 +inf 7 nan 7 +0 7 -inf 7 -0 7 -1 N N
+0 0 7 nan 7 +inf 7 +0 7 -inf 7 -0 7 -0 N N
+0 0 7 nan 7 +inf 7 +0 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 nan 7 +0 7 -inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +0 7 -inf N N
+0 0 7 +inf 7 nan 7 +0 7 -inf 7 +0 7 -1 N N
+0 0 7 nan 7 -inf 7 +0 7 -inf 7 +0 7 -0 N N
+0 0 7 nan 7 -inf 7 +0 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 nan 7 +0 7 -inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 1 7 -inf N N
+0 0 7 +inf 7 -inf 7 +0 7 -inf 7 1 7 -1 N N
+0 0 7 nan 7 -inf 7 +0 7 -inf 7 1 7 -0 N N
+0 0 7 nan 7 -inf 7 +0 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 -inf 7 +0 7 -inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 nan 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -1 7 -inf 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 -1 7 -inf 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 -1 7 -inf 7 -0 N N
+0 0 7 -0 7 +0 7 +0 7 -1 7 -inf 7 +0 N N
+0 0 7 -0 7 +0 7 +0 7 -1 7 -inf 7 1 N N
+0 0 7 -0 7 +0 7 +0 7 -1 7 -inf 7 +inf N N
+0 0 7 -0 7 +0 7 +0 7 -1 7 -inf 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -1 7 -1 7 -inf N N
+0 0 7 -0 7 +0 7 +0 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 -1 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -1 7 -0 7 -inf N N
+0 0 7 -0 7 +0 7 +0 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 -0 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -1 7 +0 7 -inf N N
+0 0 7 -0 7 -0 7 +0 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 +0 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -1 7 1 7 -inf N N
+0 0 7 -0 7 -0 7 +0 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 1 7 nan N N
+0 0 7 +0 7 -0 7 +0 7 -1 7 +inf 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 -1 7 +inf 7 -1 N N
+0 0 7 +0 7 -0 7 +0 7 -1 7 +inf 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 -1 7 +inf 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 -1 7 +inf 7 1 N N
+0 0 7 -0 7 -0 7 +0 7 -1 7 +inf 7 +inf N N
+0 0 7 +0 7 -0 7 +0 7 -1 7 +inf 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 nan 7 1 N N
+0 0 7 -0 7 -0 7 +0 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 nan 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 -inf 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 -inf 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 -inf 7 -0 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -inf 7 +0 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -inf 7 1 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -inf 7 +inf N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -inf 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 -1 7 -inf N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 -1 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 -0 7 -inf N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 -0 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 +0 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 +0 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 1 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 1 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 +inf 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 +inf 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 +inf 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +inf 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +inf 7 1 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +inf 7 +inf N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +inf 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 nan 7 1 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 nan 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 +0 7 -inf 7 -inf N N
+0 0 7 -0 7 +0 7 +0 7 +0 7 -inf 7 -1 N N
+0 0 7 -0 7 +0 7 +0 7 +0 7 -inf 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 +0 7 -inf 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 +0 7 -inf 7 1 N N
+0 0 7 +0 7 -0 7 +0 7 +0 7 -inf 7 +inf N N
+0 0 7 +0 7 -0 7 +0 7 +0 7 -inf 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 +0 7 -1 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 -1 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 +0 7 -0 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 -0 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 +0 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 1 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +inf 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +inf 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +inf 7 -0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +inf 7 +0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +inf 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +inf 7 +inf N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +inf 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 nan 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 nan 7 nan N N
+0 0 7 -0 7 -0 7 +0 7 1 7 -inf 7 -inf N N
+0 0 7 -0 7 -0 7 +0 7 1 7 -inf 7 -1 N N
+0 0 7 -0 7 -0 7 +0 7 1 7 -inf 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 1 7 -inf 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 1 7 -inf 7 1 N N
+0 0 7 +0 7 -0 7 +0 7 1 7 -inf 7 +inf N N
+0 0 7 +0 7 -0 7 +0 7 1 7 -inf 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 1 7 -1 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 1 7 -1 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 1 7 -0 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 1 7 -0 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 1 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 1 7 +0 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 1 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 1 7 1 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 1 7 +inf 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +inf 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +inf 7 -0 N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +inf 7 +0 N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +inf 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +inf 7 +inf N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +inf 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 1 7 nan 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -1 7 -inf N N
+0 0 7 -inf 7 -inf 7 +0 7 +inf 7 -1 7 -1 N N
+0 0 7 nan 7 -inf 7 +0 7 +inf 7 -1 7 -0 N N
+0 0 7 nan 7 -inf 7 +0 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 -inf 7 +0 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -0 7 -inf N N
+0 0 7 -inf 7 nan 7 +0 7 +inf 7 -0 7 -1 N N
+0 0 7 nan 7 -inf 7 +0 7 +inf 7 -0 7 -0 N N
+0 0 7 nan 7 -inf 7 +0 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 nan 7 +0 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +0 7 -inf N N
+0 0 7 -inf 7 nan 7 +0 7 +inf 7 +0 7 -1 N N
+0 0 7 nan 7 +inf 7 +0 7 +inf 7 +0 7 -0 N N
+0 0 7 nan 7 +inf 7 +0 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 nan 7 +0 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 1 7 -inf N N
+0 0 7 -inf 7 +inf 7 +0 7 +inf 7 1 7 -1 N N
+0 0 7 nan 7 +inf 7 +0 7 +inf 7 1 7 -0 N N
+0 0 7 nan 7 +inf 7 +0 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 +inf 7 +0 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 +inf 7 1 7 -inf 7 -1 7 -1 N N
+0 0 7 nan 7 +inf 7 1 7 -inf 7 -1 7 -0 N N
+0 0 7 nan 7 +inf 7 1 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 +inf 7 1 7 -inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -0 7 -inf N N
+0 0 7 +inf 7 nan 7 1 7 -inf 7 -0 7 -1 N N
+0 0 7 -inf 7 +inf 7 1 7 -inf 7 -0 7 -0 N N
+0 0 7 -inf 7 +inf 7 1 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 nan 7 1 7 -inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +0 7 -inf N N
+0 0 7 +inf 7 nan 7 1 7 -inf 7 +0 7 -1 N N
+0 0 7 +inf 7 -inf 7 1 7 -inf 7 +0 7 -0 N N
+0 0 7 +inf 7 -inf 7 1 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 nan 7 1 7 -inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 1 7 -inf N N
+0 0 7 +inf 7 -inf 7 1 7 -inf 7 1 7 -1 N N
+0 0 7 nan 7 -inf 7 1 7 -inf 7 1 7 -0 N N
+0 0 7 nan 7 -inf 7 1 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 -inf 7 1 7 -inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 nan 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -1 7 -inf 7 -inf N N
+0 0 7 -0 7 +0 7 1 7 -1 7 -inf 7 -1 N N
+0 0 7 -0 7 +0 7 1 7 -1 7 -inf 7 -0 N N
+0 0 7 -0 7 +0 7 1 7 -1 7 -inf 7 +0 N N
+0 0 7 -0 7 +0 7 1 7 -1 7 -inf 7 1 N N
+0 0 7 -0 7 +0 7 1 7 -1 7 -inf 7 +inf N N
+0 0 7 -0 7 +0 7 1 7 -1 7 -inf 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -1 7 -1 7 -inf N N
+0 0 7 -0 7 -0 7 1 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -1 7 -1 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -1 7 -0 7 -inf N N
+0 0 7 -0 7 -0 7 1 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -1 7 -0 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -1 7 +0 7 -inf N N
+0 0 7 -0 7 -0 7 1 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -1 7 +0 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -1 7 1 7 -inf N N
+0 0 7 -0 7 -0 7 1 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -1 7 1 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -1 7 +inf 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 -1 7 +inf 7 -1 N N
+0 0 7 +0 7 -0 7 1 7 -1 7 +inf 7 -0 N N
+0 0 7 +0 7 -0 7 1 7 -1 7 +inf 7 +0 N N
+0 0 7 +0 7 -0 7 1 7 -1 7 +inf 7 1 N N
+0 0 7 +0 7 -0 7 1 7 -1 7 +inf 7 +inf N N
+0 0 7 +0 7 -0 7 1 7 -1 7 +inf 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 -1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 -1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 -1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 -1 7 nan 7 1 N N
+0 0 7 -0 7 -0 7 1 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -1 7 nan 7 nan N N
+0 0 7 -0 7 +0 7 1 7 -0 7 -inf 7 -inf N N
+0 0 7 -0 7 +0 7 1 7 -0 7 -inf 7 -1 N N
+0 0 7 -0 7 +0 7 1 7 -0 7 -inf 7 -0 N N
+0 0 7 -0 7 +0 7 1 7 -0 7 -inf 7 +0 N N
+0 0 7 -0 7 +0 7 1 7 -0 7 -inf 7 1 N N
+0 0 7 -0 7 -0 7 1 7 -0 7 -inf 7 +inf N N
+0 0 7 -0 7 +0 7 1 7 -0 7 -inf 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -0 7 -1 7 -inf N N
+0 0 7 -0 7 -0 7 1 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -0 7 -1 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -0 7 -0 7 -inf N N
+0 0 7 -0 7 -0 7 1 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -0 7 -0 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -0 7 +0 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -0 7 +0 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -0 7 1 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -0 7 1 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -0 7 +inf 7 -inf N N
+0 0 7 +0 7 +0 7 1 7 -0 7 +inf 7 -1 N N
+0 0 7 +0 7 +0 7 1 7 -0 7 +inf 7 -0 N N
+0 0 7 +0 7 -0 7 1 7 -0 7 +inf 7 +0 N N
+0 0 7 +0 7 -0 7 1 7 -0 7 +inf 7 1 N N
+0 0 7 +0 7 -0 7 1 7 -0 7 +inf 7 +inf N N
+0 0 7 +0 7 -0 7 1 7 -0 7 +inf 7 nan N N
+0 0 7 +0 7 +0 7 1 7 -0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 -0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 -0 7 nan 7 1 N N
+0 0 7 +0 7 -0 7 1 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -0 7 nan 7 nan N N
+0 0 7 -0 7 +0 7 1 7 +0 7 -inf 7 -inf N N
+0 0 7 -0 7 +0 7 1 7 +0 7 -inf 7 -1 N N
+0 0 7 -0 7 +0 7 1 7 +0 7 -inf 7 -0 N N
+0 0 7 -0 7 -0 7 1 7 +0 7 -inf 7 +0 N N
+0 0 7 -0 7 -0 7 1 7 +0 7 -inf 7 1 N N
+0 0 7 -0 7 -0 7 1 7 +0 7 -inf 7 +inf N N
+0 0 7 -0 7 -0 7 1 7 +0 7 -inf 7 nan N N
+0 0 7 -0 7 +0 7 1 7 +0 7 -1 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +0 7 -1 7 nan N N
+0 0 7 -0 7 +0 7 1 7 +0 7 -0 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +0 7 -0 7 nan N N
+0 0 7 +0 7 +0 7 1 7 +0 7 +0 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +0 7 +0 7 nan N N
+0 0 7 +0 7 +0 7 1 7 +0 7 1 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +0 7 1 7 nan N N
+0 0 7 +0 7 +0 7 1 7 +0 7 +inf 7 -inf N N
+0 0 7 +0 7 +0 7 1 7 +0 7 +inf 7 -1 N N
+0 0 7 +0 7 +0 7 1 7 +0 7 +inf 7 -0 N N
+0 0 7 +0 7 +0 7 1 7 +0 7 +inf 7 +0 N N
+0 0 7 +0 7 +0 7 1 7 +0 7 +inf 7 1 N N
+0 0 7 +0 7 -0 7 1 7 +0 7 +inf 7 +inf N N
+0 0 7 +0 7 +0 7 1 7 +0 7 +inf 7 nan N N
+0 0 7 +0 7 +0 7 1 7 +0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 +0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 +0 7 nan 7 1 N N
+0 0 7 +0 7 -0 7 1 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +0 7 nan 7 nan N N
+0 0 7 -0 7 +0 7 1 7 1 7 -inf 7 -inf N N
+0 0 7 -0 7 -0 7 1 7 1 7 -inf 7 -1 N N
+0 0 7 -0 7 -0 7 1 7 1 7 -inf 7 -0 N N
+0 0 7 -0 7 -0 7 1 7 1 7 -inf 7 +0 N N
+0 0 7 -0 7 -0 7 1 7 1 7 -inf 7 1 N N
+0 0 7 +0 7 -0 7 1 7 1 7 -inf 7 +inf N N
+0 0 7 -0 7 -0 7 1 7 1 7 -inf 7 nan N N
+0 0 7 -0 7 +0 7 1 7 1 7 -1 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 1 7 -1 7 nan N N
+0 0 7 -0 7 +0 7 1 7 1 7 -0 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 1 7 -0 7 nan N N
+0 0 7 -0 7 +0 7 1 7 1 7 +0 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 1 7 +0 7 nan N N
+0 0 7 -0 7 +0 7 1 7 1 7 1 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 1 7 1 7 nan N N
+0 0 7 +0 7 +0 7 1 7 1 7 +inf 7 -inf N N
+0 0 7 +0 7 +0 7 1 7 1 7 +inf 7 -1 N N
+0 0 7 +0 7 +0 7 1 7 1 7 +inf 7 -0 N N
+0 0 7 +0 7 +0 7 1 7 1 7 +inf 7 +0 N N
+0 0 7 +0 7 +0 7 1 7 1 7 +inf 7 1 N N
+0 0 7 +0 7 +0 7 1 7 1 7 +inf 7 +inf N N
+0 0 7 +0 7 +0 7 1 7 1 7 +inf 7 nan N N
+0 0 7 -0 7 +0 7 1 7 1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 1 7 nan 7 1 N N
+0 0 7 +0 7 -0 7 1 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -1 7 -inf N N
+0 0 7 -inf 7 -inf 7 1 7 +inf 7 -1 7 -1 N N
+0 0 7 nan 7 -inf 7 1 7 +inf 7 -1 7 -0 N N
+0 0 7 nan 7 -inf 7 1 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 -inf 7 1 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -0 7 -inf N N
+0 0 7 -inf 7 nan 7 1 7 +inf 7 -0 7 -1 N N
+0 0 7 -inf 7 -inf 7 1 7 +inf 7 -0 7 -0 N N
+0 0 7 -inf 7 -inf 7 1 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 nan 7 1 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +0 7 -inf N N
+0 0 7 -inf 7 nan 7 1 7 +inf 7 +0 7 -1 N N
+0 0 7 +inf 7 +inf 7 1 7 +inf 7 +0 7 -0 N N
+0 0 7 +inf 7 +inf 7 1 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 nan 7 1 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 1 7 -inf N N
+0 0 7 -inf 7 +inf 7 1 7 +inf 7 1 7 -1 N N
+0 0 7 nan 7 +inf 7 1 7 +inf 7 1 7 -0 N N
+0 0 7 nan 7 +inf 7 1 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 +inf 7 1 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 1 7 nan 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 1 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 1 7 nan 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 1 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 1 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 1 7 1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 1 7 nan N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -1 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 -inf 7 -1 7 -1 N N
+0 0 7 -inf 7 +inf 7 +inf 7 -inf 7 -1 7 -0 N N
+0 0 7 -inf 7 +inf 7 +inf 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 nan 7 +inf 7 -inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -0 7 -inf N N
+0 0 7 +inf 7 +inf 7 +inf 7 -inf 7 -0 7 -1 N N
+0 0 7 -inf 7 +inf 7 +inf 7 -inf 7 -0 7 -0 N N
+0 0 7 -inf 7 +inf 7 +inf 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 -inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +0 7 -inf N N
+0 0 7 +inf 7 +inf 7 +inf 7 -inf 7 +0 7 -1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 +0 7 -0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 -inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 1 7 -inf N N
+0 0 7 +inf 7 nan 7 +inf 7 -inf 7 1 7 -1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 1 7 -0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 1 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 -inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -1 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 -1 7 -1 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 -1 7 -1 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 -1 7 -1 7 +0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 -1 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 -1 7 -0 7 -1 N N
+0 0 7 -inf 7 +inf 7 +inf 7 -1 7 -0 7 -0 N N
+0 0 7 -inf 7 +inf 7 +inf 7 -1 7 -0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 -1 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 -1 7 +0 7 -1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -1 7 +0 7 -0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -1 7 +0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 -1 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 1 7 -inf N N
+0 0 7 +inf 7 +inf 7 +inf 7 -1 7 1 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 -1 7 1 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 -1 7 1 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -1 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -1 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 -0 7 -1 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 -0 7 -1 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 -0 7 -1 7 +0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 -0 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 -0 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 -0 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 -0 7 -0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 -0 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 -0 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 -0 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 -0 7 +0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 -0 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 1 7 -inf N N
+0 0 7 +inf 7 +inf 7 +inf 7 -0 7 1 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 -0 7 1 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 -0 7 1 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -0 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -1 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 +0 7 -1 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 +0 7 -1 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 +0 7 -1 7 +0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 +0 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 +0 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 +0 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 +0 7 -0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 +0 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 +0 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 +0 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 +0 7 +0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 +0 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 1 7 -inf N N
+0 0 7 +inf 7 +inf 7 +inf 7 +0 7 1 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 +0 7 1 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 +0 7 1 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 +0 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -1 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 1 7 -1 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 1 7 -1 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 1 7 -1 7 +0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 1 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 1 7 -0 7 -1 N N
+0 0 7 -inf 7 -inf 7 +inf 7 1 7 -0 7 -0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 1 7 -0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 1 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 1 7 +0 7 -1 N N
+0 0 7 +inf 7 +inf 7 +inf 7 1 7 +0 7 -0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 1 7 +0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 1 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 1 7 -inf N N
+0 0 7 +inf 7 +inf 7 +inf 7 1 7 1 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 1 7 1 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 1 7 1 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 1 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -1 7 -inf N N
+0 0 7 -inf 7 nan 7 +inf 7 +inf 7 -1 7 -1 N N
+0 0 7 -inf 7 -inf 7 +inf 7 +inf 7 -1 7 -0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 +inf 7 -1 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -0 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 +inf 7 -0 7 -1 N N
+0 0 7 -inf 7 -inf 7 +inf 7 +inf 7 -0 7 -0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +0 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 +inf 7 +0 7 -1 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 +0 7 -0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 1 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 +inf 7 1 7 -1 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 1 7 -0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 nan 7 +inf 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -1 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 nan 7 -1 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 nan 7 -1 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 nan 7 -1 7 +0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 nan 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 nan 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 nan 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 1 7 -inf N N
+0 0 7 +inf 7 +inf 7 +inf 7 nan 7 1 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 1 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 1 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 nan 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 +inf 7 nan 7 -inf 7 -1 7 -1 N N
+0 0 7 nan 7 +inf 7 nan 7 -inf 7 -1 7 -0 N N
+0 0 7 nan 7 +inf 7 nan 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 +inf 7 nan 7 -inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -0 7 -inf N N
+0 0 7 +inf 7 nan 7 nan 7 -inf 7 -0 7 -1 N N
+0 0 7 nan 7 +inf 7 nan 7 -inf 7 -0 7 -0 N N
+0 0 7 nan 7 +inf 7 nan 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 nan 7 nan 7 -inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +0 7 -inf N N
+0 0 7 +inf 7 nan 7 nan 7 -inf 7 +0 7 -1 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 +0 7 -0 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 nan 7 nan 7 -inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 1 7 -inf N N
+0 0 7 +inf 7 -inf 7 nan 7 -inf 7 1 7 -1 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 1 7 -0 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 -inf 7 nan 7 -inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -0 7 -1 N N
+0 0 7 nan 7 +inf 7 nan 7 -1 7 -0 7 -0 N N
+0 0 7 nan 7 +inf 7 nan 7 -1 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +0 7 -1 N N
+0 0 7 nan 7 -inf 7 nan 7 -1 7 +0 7 -0 N N
+0 0 7 nan 7 -inf 7 nan 7 -1 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -0 7 -1 N N
+0 0 7 nan 7 -inf 7 nan 7 1 7 -0 7 -0 N N
+0 0 7 nan 7 -inf 7 nan 7 1 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +0 7 -1 N N
+0 0 7 nan 7 +inf 7 nan 7 1 7 +0 7 -0 N N
+0 0 7 nan 7 +inf 7 nan 7 1 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 1 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -1 7 -inf N N
+0 0 7 -inf 7 -inf 7 nan 7 +inf 7 -1 7 -1 N N
+0 0 7 nan 7 -inf 7 nan 7 +inf 7 -1 7 -0 N N
+0 0 7 nan 7 -inf 7 nan 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 -inf 7 nan 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -0 7 -inf N N
+0 0 7 -inf 7 nan 7 nan 7 +inf 7 -0 7 -1 N N
+0 0 7 nan 7 -inf 7 nan 7 +inf 7 -0 7 -0 N N
+0 0 7 nan 7 -inf 7 nan 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 nan 7 nan 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +0 7 -inf N N
+0 0 7 -inf 7 nan 7 nan 7 +inf 7 +0 7 -1 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 +0 7 -0 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 nan 7 nan 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 1 7 -inf N N
+0 0 7 -inf 7 +inf 7 nan 7 +inf 7 1 7 -1 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 1 7 -0 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 +inf 7 nan 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan 7 nan N N
+
+# finite values
+0 0 7 1 7 +0 7 -1 7 -1 7 -1 7 -1 N N
+0 0 7 1 7 1 7 -1 7 -1 7 -1 7 -0 N N
+0 0 7 1 7 1 7 -1 7 -1 7 -1 7 +0 N N
+0 0 7 +0 7 1 7 -1 7 -1 7 -1 7 1 N N
+0 0 7 1 7 -1 7 -1 7 -1 7 -0 7 -1 N N
+0 0 7 +inf 7 +inf 7 -1 7 -1 7 -0 7 -0 N N
+0 0 7 +inf 7 +inf 7 -1 7 -1 7 -0 7 +0 N N
+0 0 7 -1 7 1 7 -1 7 -1 7 -0 7 1 N N
+0 0 7 1 7 -1 7 -1 7 -1 7 +0 7 -1 N N
+0 0 7 -inf 7 -inf 7 -1 7 -1 7 +0 7 -0 N N
+0 0 7 -inf 7 -inf 7 -1 7 -1 7 +0 7 +0 N N
+0 0 7 -1 7 1 7 -1 7 -1 7 +0 7 1 N N
+0 0 7 +0 7 -1 7 -1 7 -1 7 1 7 -1 N N
+0 0 7 -1 7 -1 7 -1 7 -1 7 1 7 -0 N N
+0 0 7 -1 7 -1 7 -1 7 -1 7 1 7 +0 N N
+0 0 7 -1 7 +0 7 -1 7 -1 7 1 7 1 N N
+0 0 7 0.5 7 -0.5 7 -1 7 -0 7 -1 7 -1 N N
+0 0 7 1 7 +0 7 -1 7 -0 7 -1 7 -0 N N
+0 0 7 1 7 +0 7 -1 7 -0 7 -1 7 +0 N N
+0 0 7 0.5 7 0.5 7 -1 7 -0 7 -1 7 1 N N
+0 0 7 +0 7 -1 7 -1 7 -0 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -1 7 -0 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 -1 7 -0 7 -0 7 +0 N N
+0 0 7 +0 7 1 7 -1 7 -0 7 -0 7 1 N N
+0 0 7 +0 7 -1 7 -1 7 -0 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 -1 7 -0 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -1 7 -0 7 +0 7 +0 N N
+0 0 7 -0 7 1 7 -1 7 -0 7 +0 7 1 N N
+0 0 7 -0.5 7 -0.5 7 -1 7 -0 7 1 7 -1 N N
+0 0 7 -1 7 -0 7 -1 7 -0 7 1 7 -0 N N
+0 0 7 -1 7 +0 7 -1 7 -0 7 1 7 +0 N N
+0 0 7 -0.5 7 0.5 7 -1 7 -0 7 1 7 1 N N
+0 0 7 0.5 7 -0.5 7 -1 7 +0 7 -1 7 -1 N N
+0 0 7 1 7 -0 7 -1 7 +0 7 -1 7 -0 N N
+0 0 7 1 7 +0 7 -1 7 +0 7 -1 7 +0 N N
+0 0 7 0.5 7 0.5 7 -1 7 +0 7 -1 7 1 N N
+0 0 7 +0 7 -1 7 -1 7 +0 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -1 7 +0 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 -1 7 +0 7 -0 7 +0 N N
+0 0 7 +0 7 1 7 -1 7 +0 7 -0 7 1 N N
+0 0 7 -0 7 -1 7 -1 7 +0 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 -1 7 +0 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -1 7 +0 7 +0 7 +0 N N
+0 0 7 +0 7 1 7 -1 7 +0 7 +0 7 1 N N
+0 0 7 -0.5 7 -0.5 7 -1 7 +0 7 1 7 -1 N N
+0 0 7 -1 7 +0 7 -1 7 +0 7 1 7 -0 N N
+0 0 7 -1 7 +0 7 -1 7 +0 7 1 7 +0 N N
+0 0 7 -0.5 7 0.5 7 -1 7 +0 7 1 7 1 N N
+0 0 7 +0 7 -1 7 -1 7 1 7 -1 7 -1 N N
+0 0 7 1 7 -1 7 -1 7 1 7 -1 7 -0 N N
+0 0 7 1 7 -1 7 -1 7 1 7 -1 7 +0 N N
+0 0 7 1 7 +0 7 -1 7 1 7 -1 7 1 N N
+0 0 7 -1 7 -1 7 -1 7 1 7 -0 7 -1 N N
+0 0 7 +inf 7 -inf 7 -1 7 1 7 -0 7 -0 N N
+0 0 7 +inf 7 -inf 7 -1 7 1 7 -0 7 +0 N N
+0 0 7 1 7 1 7 -1 7 1 7 -0 7 1 N N
+0 0 7 -1 7 -1 7 -1 7 1 7 +0 7 -1 N N
+0 0 7 -inf 7 +inf 7 -1 7 1 7 +0 7 -0 N N
+0 0 7 -inf 7 +inf 7 -1 7 1 7 +0 7 +0 N N
+0 0 7 1 7 1 7 -1 7 1 7 +0 7 1 N N
+0 0 7 -1 7 +0 7 -1 7 1 7 1 7 -1 N N
+0 0 7 -1 7 1 7 -1 7 1 7 1 7 -0 N N
+0 0 7 -1 7 1 7 -1 7 1 7 1 7 +0 N N
+0 0 7 +0 7 1 7 -1 7 1 7 1 7 1 N N
+0 0 7 0.5 7 0.5 7 -0 7 -1 7 -1 7 -1 N N
+0 0 7 +0 7 1 7 -0 7 -1 7 -1 7 -0 N N
+0 0 7 +0 7 1 7 -0 7 -1 7 -1 7 +0 N N
+0 0 7 -0.5 7 0.5 7 -0 7 -1 7 -1 7 1 N N
+0 0 7 1 7 +0 7 -0 7 -1 7 -0 7 -1 N N
+0 0 7 nan 7 +inf 7 -0 7 -1 7 -0 7 -0 N N
+0 0 7 nan 7 +inf 7 -0 7 -1 7 -0 7 +0 N N
+0 0 7 -1 7 +0 7 -0 7 -1 7 -0 7 1 N N
+0 0 7 1 7 -0 7 -0 7 -1 7 +0 7 -1 N N
+0 0 7 nan 7 -inf 7 -0 7 -1 7 +0 7 -0 N N
+0 0 7 nan 7 -inf 7 -0 7 -1 7 +0 7 +0 N N
+0 0 7 -1 7 +0 7 -0 7 -1 7 +0 7 1 N N
+0 0 7 0.5 7 -0.5 7 -0 7 -1 7 1 7 -1 N N
+0 0 7 +0 7 -1 7 -0 7 -1 7 1 7 -0 N N
+0 0 7 -0 7 -1 7 -0 7 -1 7 1 7 +0 N N
+0 0 7 -0.5 7 -0.5 7 -0 7 -1 7 1 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -1 7 -1 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -1 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -1 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -1 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 -0 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -0 7 1 N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 +0 7 +0 N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 +0 7 1 N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 1 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 1 7 -0 N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 1 7 +0 N N
+0 0 7 -0 7 +0 7 -0 7 -0 7 1 7 1 N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -1 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -1 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 -1 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 -1 7 1 N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 -0 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 -0 7 1 N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 +0 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 +0 7 1 N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 1 7 -1 N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 1 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 1 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 1 7 1 N N
+0 0 7 -0.5 7 -0.5 7 -0 7 1 7 -1 7 -1 N N
+0 0 7 +0 7 -1 7 -0 7 1 7 -1 7 -0 N N
+0 0 7 +0 7 -1 7 -0 7 1 7 -1 7 +0 N N
+0 0 7 0.5 7 -0.5 7 -0 7 1 7 -1 7 1 N N
+0 0 7 -1 7 -0 7 -0 7 1 7 -0 7 -1 N N
+0 0 7 nan 7 -inf 7 -0 7 1 7 -0 7 -0 N N
+0 0 7 nan 7 -inf 7 -0 7 1 7 -0 7 +0 N N
+0 0 7 1 7 +0 7 -0 7 1 7 -0 7 1 N N
+0 0 7 -1 7 +0 7 -0 7 1 7 +0 7 -1 N N
+0 0 7 nan 7 +inf 7 -0 7 1 7 +0 7 -0 N N
+0 0 7 nan 7 +inf 7 -0 7 1 7 +0 7 +0 N N
+0 0 7 1 7 +0 7 -0 7 1 7 +0 7 1 N N
+0 0 7 -0.5 7 0.5 7 -0 7 1 7 1 7 -1 N N
+0 0 7 -0 7 1 7 -0 7 1 7 1 7 -0 N N
+0 0 7 +0 7 1 7 -0 7 1 7 1 7 +0 N N
+0 0 7 0.5 7 0.5 7 -0 7 1 7 1 7 1 N N
+0 0 7 0.5 7 0.5 7 +0 7 -1 7 -1 7 -1 N N
+0 0 7 +0 7 1 7 +0 7 -1 7 -1 7 -0 N N
+0 0 7 -0 7 1 7 +0 7 -1 7 -1 7 +0 N N
+0 0 7 -0.5 7 0.5 7 +0 7 -1 7 -1 7 1 N N
+0 0 7 1 7 +0 7 +0 7 -1 7 -0 7 -1 N N
+0 0 7 nan 7 +inf 7 +0 7 -1 7 -0 7 -0 N N
+0 0 7 nan 7 +inf 7 +0 7 -1 7 -0 7 +0 N N
+0 0 7 -1 7 +0 7 +0 7 -1 7 -0 7 1 N N
+0 0 7 1 7 +0 7 +0 7 -1 7 +0 7 -1 N N
+0 0 7 nan 7 -inf 7 +0 7 -1 7 +0 7 -0 N N
+0 0 7 nan 7 -inf 7 +0 7 -1 7 +0 7 +0 N N
+0 0 7 -1 7 -0 7 +0 7 -1 7 +0 7 1 N N
+0 0 7 0.5 7 -0.5 7 +0 7 -1 7 1 7 -1 N N
+0 0 7 +0 7 -1 7 +0 7 -1 7 1 7 -0 N N
+0 0 7 +0 7 -1 7 +0 7 -1 7 1 7 +0 N N
+0 0 7 -0.5 7 -0.5 7 +0 7 -1 7 1 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 -1 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 -1 7 -0 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -1 7 +0 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -1 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 -0 7 +0 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -0 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 +0 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +0 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 1 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 1 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 1 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 1 7 1 N N
+0 0 7 -0 7 +0 7 +0 7 +0 7 -1 7 -1 N N
+0 0 7 -0 7 +0 7 +0 7 +0 7 -1 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 +0 7 -1 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 +0 7 -1 7 1 N N
+0 0 7 -0 7 +0 7 +0 7 +0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 -0 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 +0 7 -0 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 +0 7 +0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +0 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 1 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 1 7 -0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 1 7 +0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 1 7 1 N N
+0 0 7 -0.5 7 -0.5 7 +0 7 1 7 -1 7 -1 N N
+0 0 7 -0 7 -1 7 +0 7 1 7 -1 7 -0 N N
+0 0 7 +0 7 -1 7 +0 7 1 7 -1 7 +0 N N
+0 0 7 0.5 7 -0.5 7 +0 7 1 7 -1 7 1 N N
+0 0 7 -1 7 +0 7 +0 7 1 7 -0 7 -1 N N
+0 0 7 nan 7 -inf 7 +0 7 1 7 -0 7 -0 N N
+0 0 7 nan 7 -inf 7 +0 7 1 7 -0 7 +0 N N
+0 0 7 1 7 -0 7 +0 7 1 7 -0 7 1 N N
+0 0 7 -1 7 +0 7 +0 7 1 7 +0 7 -1 N N
+0 0 7 nan 7 +inf 7 +0 7 1 7 +0 7 -0 N N
+0 0 7 nan 7 +inf 7 +0 7 1 7 +0 7 +0 N N
+0 0 7 1 7 +0 7 +0 7 1 7 +0 7 1 N N
+0 0 7 -0.5 7 0.5 7 +0 7 1 7 1 7 -1 N N
+0 0 7 +0 7 1 7 +0 7 1 7 1 7 -0 N N
+0 0 7 +0 7 1 7 +0 7 1 7 1 7 +0 N N
+0 0 7 0.5 7 0.5 7 +0 7 1 7 1 7 1 N N
+0 0 7 +0 7 1 7 1 7 -1 7 -1 7 -1 N N
+0 0 7 -1 7 1 7 1 7 -1 7 -1 7 -0 N N
+0 0 7 -1 7 1 7 1 7 -1 7 -1 7 +0 N N
+0 0 7 -1 7 +0 7 1 7 -1 7 -1 7 1 N N
+0 0 7 1 7 1 7 1 7 -1 7 -0 7 -1 N N
+0 0 7 -inf 7 +inf 7 1 7 -1 7 -0 7 -0 N N
+0 0 7 -inf 7 +inf 7 1 7 -1 7 -0 7 +0 N N
+0 0 7 -1 7 -1 7 1 7 -1 7 -0 7 1 N N
+0 0 7 1 7 1 7 1 7 -1 7 +0 7 -1 N N
+0 0 7 +inf 7 -inf 7 1 7 -1 7 +0 7 -0 N N
+0 0 7 +inf 7 -inf 7 1 7 -1 7 +0 7 +0 N N
+0 0 7 -1 7 -1 7 1 7 -1 7 +0 7 1 N N
+0 0 7 1 7 +0 7 1 7 -1 7 1 7 -1 N N
+0 0 7 1 7 -1 7 1 7 -1 7 1 7 -0 N N
+0 0 7 1 7 -1 7 1 7 -1 7 1 7 +0 N N
+0 0 7 +0 7 -1 7 1 7 -1 7 1 7 1 N N
+0 0 7 -0.5 7 0.5 7 1 7 -0 7 -1 7 -1 N N
+0 0 7 -1 7 +0 7 1 7 -0 7 -1 7 -0 N N
+0 0 7 -1 7 +0 7 1 7 -0 7 -1 7 +0 N N
+0 0 7 -0.5 7 -0.5 7 1 7 -0 7 -1 7 1 N N
+0 0 7 +0 7 1 7 1 7 -0 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 1 7 -0 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 1 7 -0 7 -0 7 +0 N N
+0 0 7 -0 7 -1 7 1 7 -0 7 -0 7 1 N N
+0 0 7 +0 7 1 7 1 7 -0 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 1 7 -0 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 1 7 -0 7 +0 7 +0 N N
+0 0 7 +0 7 -1 7 1 7 -0 7 +0 7 1 N N
+0 0 7 0.5 7 0.5 7 1 7 -0 7 1 7 -1 N N
+0 0 7 1 7 +0 7 1 7 -0 7 1 7 -0 N N
+0 0 7 1 7 -0 7 1 7 -0 7 1 7 +0 N N
+0 0 7 0.5 7 -0.5 7 1 7 -0 7 1 7 1 N N
+0 0 7 -0.5 7 0.5 7 1 7 +0 7 -1 7 -1 N N
+0 0 7 -1 7 +0 7 1 7 +0 7 -1 7 -0 N N
+0 0 7 -1 7 -0 7 1 7 +0 7 -1 7 +0 N N
+0 0 7 -0.5 7 -0.5 7 1 7 +0 7 -1 7 1 N N
+0 0 7 -0 7 1 7 1 7 +0 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 1 7 +0 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 1 7 +0 7 -0 7 +0 N N
+0 0 7 +0 7 -1 7 1 7 +0 7 -0 7 1 N N
+0 0 7 +0 7 1 7 1 7 +0 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 1 7 +0 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 1 7 +0 7 +0 7 +0 N N
+0 0 7 +0 7 -1 7 1 7 +0 7 +0 7 1 N N
+0 0 7 0.5 7 0.5 7 1 7 +0 7 1 7 -1 N N
+0 0 7 1 7 +0 7 1 7 +0 7 1 7 -0 N N
+0 0 7 1 7 +0 7 1 7 +0 7 1 7 +0 N N
+0 0 7 0.5 7 -0.5 7 1 7 +0 7 1 7 1 N N
+0 0 7 -1 7 +0 7 1 7 1 7 -1 7 -1 N N
+0 0 7 -1 7 -1 7 1 7 1 7 -1 7 -0 N N
+0 0 7 -1 7 -1 7 1 7 1 7 -1 7 +0 N N
+0 0 7 +0 7 -1 7 1 7 1 7 -1 7 1 N N
+0 0 7 -1 7 1 7 1 7 1 7 -0 7 -1 N N
+0 0 7 -inf 7 -inf 7 1 7 1 7 -0 7 -0 N N
+0 0 7 -inf 7 -inf 7 1 7 1 7 -0 7 +0 N N
+0 0 7 1 7 -1 7 1 7 1 7 -0 7 1 N N
+0 0 7 -1 7 1 7 1 7 1 7 +0 7 -1 N N
+0 0 7 +inf 7 +inf 7 1 7 1 7 +0 7 -0 N N
+0 0 7 +inf 7 +inf 7 1 7 1 7 +0 7 +0 N N
+0 0 7 1 7 -1 7 1 7 1 7 +0 7 1 N N
+0 0 7 +0 7 1 7 1 7 1 7 1 7 -1 N N
+0 0 7 1 7 1 7 1 7 1 7 1 7 -0 N N
+0 0 7 1 7 1 7 1 7 1 7 1 7 +0 N N
+0 0 7 1 7 +0 7 1 7 1 7 1 7 1 N N
+
+# small exact/inexact examples
+- - 10 0b1.01010001 10 -0b1.1000101@-6 10 973 10 964 10 725 10 745 N N
+0 0 10 -14 10 9 10 -837 10 637 10 63 10 -5 N N
+0 0 2 2 2 -1 2 4 2 3 2 1 2 2 N N
++ - 4 1.375 4 1.25 4 15 4 14 4 11 4 0 N N
+
+# Bug 20080923
++ + 4 0b11@527 4 -0b111@-489 4 -0b11@-206 4 0 4 -0b1@-733 4 -0b101@-1750 N Z
+
+# potential intermediate over- or underflow
+0 0 10 1 10 0 10 0 10 0b1@536870912 10 0 10 0b1@536870912 N N
+0 0 10 1 10 0 10 0b1@536870912 10 0 10 0b1@536870912 10 0 N N
+
+# overflow (reported by Emmanuel Thome)
+- + 250 -inf 250 +inf 250 1 250 0 250 -1e-164895850 250 -1e-164895850 N N
+
+# bug found by tgeneric of ui_div
++ + 2 0b1.1@256 2 0b1.1@-2758 34 52349199244 2 0 2 0b1.1@-221 2 -0b1@-3234 U N
+
+# cases that should yield 1, but cannot be handled due to intermediate
+# over- or underflows
+# current result: (@NaN@ 0)
+#0 0 10 1 10 0 10 1 10 0b1@536870912 10 1 10 0b1@536870912 N N
+# current result: (@Inf@ 0)
+#0 0 10 1 10 0 10 1 10 0b1@-536870913 10 1 10 0b1@-536870913 N N
+# current result: (@NaN@ 0)
+#0 0 10 1 10 0 10 0b1@536870912 10 0b1@536870912 10 0b1@536870912 10 0b1@536870912 N N
+# current result: (@NaN@ 0)
+#0 0 10 1 10 0 10 0b1@-536870913 10 0b1@-536870913 10 0b1@-536870913 10 0b1@-536870913 N N
+# current result: (@Inf@ 0)
+#0 0 10 1 10 0 10 0b1@536870912 10 0b1@-536870913 10 0b1@536870912 10 0b1@-536870913 N N
+# cases that should yield i, but cannot be handled due to intermediate
+# over- or underflows
+# current result: (0 @Inf@)
+#0 0 10 0 10 1 10 -0b1@536870912 10 1 10 1 10 0b1@536870912 N N
+# current result: (@NaN@ 1.0)
+#0 0 10 0 10 1 10 -0b1@-536870913 10 1 10 1 10 0b1@-536870913 N N
+# current result: (0 @Inf@)
+#0 0 10 0 10 1 10 -0b1@536870912 10 0b1@536870912 10 0b1@536870912 10 0b1@536870912 N N
+# current result: (@NaN@ 0)
+#0 0 10 0 10 1 10 -0b1@-536870913 10 0b1@-536870913 10 0b1@-536870913 10 0b1@-536870913 N N
+# current result: (@NaN@ @Inf@)
+#0 0 10 0 10 1 10 -0b1@-536870913 10 0b1@536870912 10 0b1@536870912 10 0b1@-536870913 N N
+
+# examples to exercise overflow (re)
+# positive overflow
++ 0 2 inf 2 0 10 0x3ffp1073741813 10 0x3ffp1073741813 10 0x2abp-10 10 0x2abp-10 N N
+# negative overflow
+- 0 2 -inf 2 0 10 -0x3ffp1073741813 10 -0x3ffp1073741813 10 0x2abp-10 10 0x2abp-10 N N
+# examples to exercise overflow (im)
+# positive overflow
+0 + 2 0 2 inf 10 0x3ffp1073741813 10 0x3ffp1073741813 10 0x2abp-10 10 -0x2abp-10 N N
+# negative overflow
+0 - 2 0 2 -inf 10 -0x3ffp1073741813 10 -0x3ffp1073741813 10 0x2abp-10 10 -0x2abp-10 N N
+
+# examples to exercise underflow
+# (1.5+i)*2^emin/(1-i) gives (0.25 + 1.25*i)*2^emin
+- - 2 0 2 0x1p-1073741823 2 0x3p-1073741824 2 0x1p-1073741823 2 1 2 -1 Z Z
+# (1.5+i)*2^emin/(1+i) gives (1.25 - 0.25*i)*2^emin
+- + 2 0x1p-1073741823 2 -0 2 0x3p-1073741824 2 0x1p-1073741823 2 1 2 1 Z Z
diff --git a/mpc/tests/div_fr.dat b/mpc/tests/div_fr.dat
new file mode 100644
index 0000000000..724d3611ef
--- /dev/null
+++ b/mpc/tests/div_fr.dat
@@ -0,0 +1,368 @@
+# Data file for mpc_div_fr.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see add_fr.dat.
+
+# special values
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -inf N N
+0 0 7 +inf 7 +inf 7 -inf 7 -inf 7 -1 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -inf 7 -0 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 +0 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 +0 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 1 7 -inf 7 -1 7 -1 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -1 7 -0 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 -1 7 -inf 7 -1 7 1 N N
+0 0 7 nan 7 -0 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 +0 7 -inf 7 -0 7 -inf N N
+0 0 7 +inf 7 +0 7 -inf 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 -0 7 -inf 7 -0 7 1 N N
+0 0 7 nan 7 -0 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 -0 7 -inf 7 +0 7 -inf N N
+0 0 7 +inf 7 -0 7 -inf 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 +0 7 -inf 7 +0 7 1 N N
+0 0 7 nan 7 +0 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 -0 7 -inf 7 1 7 -inf N N
+0 0 7 +inf 7 -1 7 -inf 7 1 7 -1 N N
+0 0 7 +inf 7 -inf 7 -inf 7 1 7 -0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 1 7 -inf 7 1 7 1 N N
+0 0 7 nan 7 +0 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 +inf 7 -1 N N
+0 0 7 +inf 7 -inf 7 -inf 7 +inf 7 -0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf N N
+0 0 7 +inf 7 nan 7 -inf 7 nan 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 nan 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 +0 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan N N
+0 0 7 +0 7 nan 7 -1 7 -inf 7 -inf N N
+0 0 7 1 7 +inf 7 -1 7 -inf 7 -1 N N
+0 0 7 +inf 7 +inf 7 -1 7 -inf 7 -0 N N
+0 0 7 -inf 7 -inf 7 -1 7 -inf 7 +0 N N
+0 0 7 -1 7 -inf 7 -1 7 -inf 7 1 N N
+0 0 7 -0 7 nan 7 -1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 nan N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 -inf N N
+0 0 7 -0 7 -0 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 nan N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -inf N N
+0 0 7 -0 7 -0 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 +0 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 1 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 1 7 nan N N
+0 0 7 +0 7 nan 7 -1 7 +inf 7 -inf N N
+0 0 7 1 7 -inf 7 -1 7 +inf 7 -1 N N
+0 0 7 +inf 7 -inf 7 -1 7 +inf 7 -0 N N
+0 0 7 -inf 7 +inf 7 -1 7 +inf 7 +0 N N
+0 0 7 -1 7 +inf 7 -1 7 +inf 7 1 N N
+0 0 7 -0 7 nan 7 -1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 nan N N
+0 0 7 +0 7 nan 7 -1 7 nan 7 -inf N N
+0 0 7 1 7 nan 7 -1 7 nan 7 -1 N N
+0 0 7 +inf 7 nan 7 -1 7 nan 7 -0 N N
+0 0 7 -inf 7 nan 7 -1 7 nan 7 +0 N N
+0 0 7 -1 7 nan 7 -1 7 nan 7 1 N N
+0 0 7 -0 7 nan 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan N N
+0 0 7 +0 7 nan 7 -0 7 -inf 7 -inf N N
+0 0 7 +0 7 +inf 7 -0 7 -inf 7 -1 N N
+0 0 7 nan 7 +inf 7 -0 7 -inf 7 -0 N N
+0 0 7 nan 7 -inf 7 -0 7 -inf 7 +0 N N
+0 0 7 -0 7 -inf 7 -0 7 -inf 7 1 N N
+0 0 7 -0 7 nan 7 -0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 nan N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -inf N N
+0 0 7 -0 7 -0 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 nan N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -inf N N
+0 0 7 -0 7 -0 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 1 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 1 7 nan N N
+0 0 7 +0 7 nan 7 -0 7 +inf 7 -inf N N
+0 0 7 +0 7 -inf 7 -0 7 +inf 7 -1 N N
+0 0 7 nan 7 -inf 7 -0 7 +inf 7 -0 N N
+0 0 7 nan 7 +inf 7 -0 7 +inf 7 +0 N N
+0 0 7 -0 7 +inf 7 -0 7 +inf 7 1 N N
+0 0 7 -0 7 nan 7 -0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 nan N N
+0 0 7 +0 7 nan 7 -0 7 nan 7 -inf N N
+0 0 7 +0 7 nan 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +0 N N
+0 0 7 -0 7 nan 7 -0 7 nan 7 1 N N
+0 0 7 -0 7 nan 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan N N
+0 0 7 -0 7 nan 7 +0 7 -inf 7 -inf N N
+0 0 7 -0 7 +inf 7 +0 7 -inf 7 -1 N N
+0 0 7 nan 7 +inf 7 +0 7 -inf 7 -0 N N
+0 0 7 nan 7 -inf 7 +0 7 -inf 7 +0 N N
+0 0 7 +0 7 -inf 7 +0 7 -inf 7 1 N N
+0 0 7 +0 7 nan 7 +0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 -1 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 nan N N
+0 0 7 -0 7 -0 7 +0 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 nan N N
+0 0 7 -0 7 -0 7 +0 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 1 7 nan N N
+0 0 7 -0 7 nan 7 +0 7 +inf 7 -inf N N
+0 0 7 -0 7 -inf 7 +0 7 +inf 7 -1 N N
+0 0 7 nan 7 -inf 7 +0 7 +inf 7 -0 N N
+0 0 7 nan 7 +inf 7 +0 7 +inf 7 +0 N N
+0 0 7 +0 7 +inf 7 +0 7 +inf 7 1 N N
+0 0 7 +0 7 nan 7 +0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 nan N N
+0 0 7 -0 7 nan 7 +0 7 nan 7 -inf N N
+0 0 7 -0 7 nan 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +0 N N
+0 0 7 +0 7 nan 7 +0 7 nan 7 1 N N
+0 0 7 +0 7 nan 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan N N
+0 0 7 -0 7 nan 7 1 7 -inf 7 -inf N N
+0 0 7 -1 7 +inf 7 1 7 -inf 7 -1 N N
+0 0 7 -inf 7 +inf 7 1 7 -inf 7 -0 N N
+0 0 7 +inf 7 -inf 7 1 7 -inf 7 +0 N N
+0 0 7 1 7 -inf 7 1 7 -inf 7 1 N N
+0 0 7 +0 7 nan 7 1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 nan N N
+0 0 7 -0 7 +0 7 1 7 -1 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -1 7 nan N N
+0 0 7 -0 7 +0 7 1 7 -0 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -0 7 nan N N
+0 0 7 -0 7 -0 7 1 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +0 7 nan N N
+0 0 7 -0 7 -0 7 1 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 1 7 nan N N
+0 0 7 -0 7 nan 7 1 7 +inf 7 -inf N N
+0 0 7 -1 7 -inf 7 1 7 +inf 7 -1 N N
+0 0 7 -inf 7 -inf 7 1 7 +inf 7 -0 N N
+0 0 7 +inf 7 +inf 7 1 7 +inf 7 +0 N N
+0 0 7 1 7 +inf 7 1 7 +inf 7 1 N N
+0 0 7 +0 7 nan 7 1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 nan N N
+0 0 7 -0 7 nan 7 1 7 nan 7 -inf N N
+0 0 7 -1 7 nan 7 1 7 nan 7 -1 N N
+0 0 7 -inf 7 nan 7 1 7 nan 7 -0 N N
+0 0 7 +inf 7 nan 7 1 7 nan 7 +0 N N
+0 0 7 1 7 nan 7 1 7 nan 7 1 N N
+0 0 7 +0 7 nan 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 -inf 7 -1 N N
+0 0 7 -inf 7 +inf 7 +inf 7 -inf 7 -0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan N N
+0 0 7 nan 7 +0 7 +inf 7 -1 7 -inf N N
+0 0 7 -inf 7 1 7 +inf 7 -1 7 -1 N N
+0 0 7 -inf 7 +inf 7 +inf 7 -1 7 -0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 -1 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 -0 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan N N
+0 0 7 nan 7 +0 7 +inf 7 -0 7 -inf N N
+0 0 7 -inf 7 +0 7 +inf 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 -0 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 -0 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan N N
+0 0 7 nan 7 -0 7 +inf 7 +0 7 -inf N N
+0 0 7 -inf 7 -0 7 +inf 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 +0 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 +0 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan N N
+0 0 7 nan 7 -0 7 +inf 7 1 7 -inf N N
+0 0 7 -inf 7 -1 7 +inf 7 1 7 -1 N N
+0 0 7 -inf 7 -inf 7 +inf 7 1 7 -0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 1 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 +0 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -inf N N
+0 0 7 -inf 7 -inf 7 +inf 7 +inf 7 -1 N N
+0 0 7 -inf 7 -inf 7 +inf 7 +inf 7 -0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 +0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -inf N N
+0 0 7 -inf 7 nan 7 +inf 7 nan 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 nan 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 +0 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 +inf 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 +inf 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 +0 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 +inf 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 -inf 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 -0 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 +0 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 +0 7 nan 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 -0 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 -0 7 nan 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 -0 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 -1 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 -inf 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 +inf 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 1 7 nan 7 1 7 1 N N
+0 0 7 nan 7 +0 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 -inf 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 -inf 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan N N
+
+# values with only 1, -1, +0, -0
+0 0 7 1 7 1 7 -1 7 -1 7 -1 N N
+0 0 7 +inf 7 +inf 7 -1 7 -1 7 -0 N N
+0 0 7 -inf 7 -inf 7 -1 7 -1 7 +0 N N
+0 0 7 -1 7 -1 7 -1 7 -1 7 1 N N
+0 0 7 1 7 +0 7 -1 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -1 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 -1 7 -0 7 +0 N N
+0 0 7 -1 7 -0 7 -1 7 -0 7 1 N N
+0 0 7 1 7 -0 7 -1 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 -1 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -1 7 +0 7 +0 N N
+0 0 7 -1 7 +0 7 -1 7 +0 7 1 N N
+0 0 7 1 7 -1 7 -1 7 1 7 -1 N N
+0 0 7 +inf 7 -inf 7 -1 7 1 7 -0 N N
+0 0 7 -inf 7 +inf 7 -1 7 1 7 +0 N N
+0 0 7 -1 7 1 7 -1 7 1 7 1 N N
+0 0 7 +0 7 1 7 -0 7 -1 7 -1 N N
+0 0 7 nan 7 +inf 7 -0 7 -1 7 -0 N N
+0 0 7 nan 7 -inf 7 -0 7 -1 7 +0 N N
+0 0 7 -0 7 -1 7 -0 7 -1 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 +0 N N
+0 0 7 -0 7 -0 7 -0 7 -0 7 1 N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 +0 N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 1 N N
+0 0 7 +0 7 -1 7 -0 7 1 7 -1 N N
+0 0 7 nan 7 -inf 7 -0 7 1 7 -0 N N
+0 0 7 nan 7 +inf 7 -0 7 1 7 +0 N N
+0 0 7 -0 7 1 7 -0 7 1 7 1 N N
+0 0 7 -0 7 1 7 +0 7 -1 7 -1 N N
+0 0 7 nan 7 +inf 7 +0 7 -1 7 -0 N N
+0 0 7 nan 7 -inf 7 +0 7 -1 7 +0 N N
+0 0 7 +0 7 -1 7 +0 7 -1 7 1 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 1 N N
+0 0 7 -0 7 -0 7 +0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 +0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 1 N N
+0 0 7 -0 7 -1 7 +0 7 1 7 -1 N N
+0 0 7 nan 7 -inf 7 +0 7 1 7 -0 N N
+0 0 7 nan 7 +inf 7 +0 7 1 7 +0 N N
+0 0 7 +0 7 1 7 +0 7 1 7 1 N N
+0 0 7 -1 7 1 7 1 7 -1 7 -1 N N
+0 0 7 -inf 7 +inf 7 1 7 -1 7 -0 N N
+0 0 7 +inf 7 -inf 7 1 7 -1 7 +0 N N
+0 0 7 1 7 -1 7 1 7 -1 7 1 N N
+0 0 7 -1 7 +0 7 1 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 1 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 1 7 -0 7 +0 N N
+0 0 7 1 7 -0 7 1 7 -0 7 1 N N
+0 0 7 -1 7 -0 7 1 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 1 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 1 7 +0 7 +0 N N
+0 0 7 1 7 +0 7 1 7 +0 7 1 N N
+0 0 7 -1 7 -1 7 1 7 1 7 -1 N N
+0 0 7 -inf 7 -inf 7 1 7 1 7 -0 N N
+0 0 7 +inf 7 +inf 7 1 7 1 7 +0 N N
+0 0 7 1 7 1 7 1 7 1 7 1 N N
+
diff --git a/mpc/tests/exp.dat b/mpc/tests/exp.dat
new file mode 100644
index 0000000000..04ed7636d8
--- /dev/null
+++ b/mpc/tests/exp.dat
@@ -0,0 +1,118 @@
+# Data file for mpc_exp.
+#
+# Copyright (C) 2008, 2010 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# see sin.dat for precisions
+
+# special values (following ISO C99 standard)
+0 0 53 0 53 0 53 -inf 53 -inf N N
+0 0 53 +0 53 +0 53 -inf 53 -6 N N
+0 0 53 -0 53 +0 53 -inf 53 -4 N N
+0 0 53 -0 53 -0 53 -inf 53 -2 N N
+0 0 53 +0 53 -0 53 -inf 53 -1 N N
+0 0 53 +0 53 -0 53 -inf 53 -0 N N
+0 0 53 +0 53 +0 53 -inf 53 +0 N N
+0 0 53 +0 53 +0 53 -inf 53 +1 N N
+0 0 53 -0 53 +0 53 -inf 53 +2 N N
+0 0 53 -0 53 -0 53 -inf 53 +4 N N
+0 0 53 +0 53 -0 53 -inf 53 +6 N N
+0 0 53 0 53 0 53 -inf 53 +inf N N
+0 0 53 0 53 0 53 -inf 53 nan N N
+0 0 53 nan 53 nan 53 -1 53 -inf N N
+0 0 53 nan 53 nan 53 -1 53 +inf N N
+0 0 53 nan 53 nan 53 -1 53 nan N N
+0 0 53 nan 53 nan 53 -0 53 -inf N N
+0 0 53 +1 53 -0 53 -0 53 -0 N N
+0 0 53 +1 53 +0 53 -0 53 +0 N N
+0 0 53 nan 53 nan 53 -0 53 +inf N N
+0 0 53 nan 53 nan 53 -0 53 nan N N
+0 0 53 nan 53 nan 53 +0 53 -inf N N
+0 0 53 +1 53 -0 53 +0 53 -0 N N
+0 0 53 +1 53 +0 53 +0 53 +0 N N
+0 0 53 nan 53 nan 53 +0 53 +inf N N
+0 0 53 nan 53 nan 53 +0 53 nan N N
+0 0 53 nan 53 nan 53 +1 53 -inf N N
+0 0 53 nan 53 nan 53 +1 53 +inf N N
+0 0 53 nan 53 nan 53 +1 53 nan N N
+0 0 53 inf 53 nan 53 +inf 53 -inf N N
+0 0 53 +inf 53 +inf 53 +inf 53 -6 N N
+0 0 53 -inf 53 +inf 53 +inf 53 -4 N N
+0 0 53 -inf 53 -inf 53 +inf 53 -2 N N
+0 0 53 +inf 53 -inf 53 +inf 53 -1 N N
+0 0 53 +inf 53 -0 53 +inf 53 -0 N N
+0 0 53 +inf 53 +0 53 +inf 53 +0 N N
+0 0 53 +inf 53 +inf 53 +inf 53 +1 N N
+0 0 53 -inf 53 +inf 53 +inf 53 +2 N N
+0 0 53 -inf 53 -inf 53 +inf 53 +4 N N
+0 0 53 +inf 53 -inf 53 +inf 53 +6 N N
+0 0 53 inf 53 nan 53 +inf 53 +inf N N
+0 0 53 inf 53 nan 53 +inf 53 nan N N
+0 0 53 nan 53 nan 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 -0 53 nan 53 -0 N N
+0 0 53 nan 53 +0 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 0 53 nan 53 nan 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# purely real argument
+- 0 53 0x1936dc5690c08fp-44 2 +0 53 6 17 +0 N N
+- 0 53 0x4b0556e084f3d0p-60 3 +0 54 -4 16 +0 Z N
++ 0 53 0xec7325c6a6ed70p-53 4 -0 55 2 15 -0 U N
+- 0 53 0x178b56362cef37p-54 5 -0 56 -1 14 -0 D N
+- 0 53 0x3699205c4e74b0p-48 6 +0 57 4 13 +0 Z Z
++ 0 53 0x454aaa8efe0730p-57 7 +0 58 -2 12 +0 U Z
+- 0 53 0x15bf0a8b145769p-51 8 -0 59 1 11 -0 D Z
++ 0 53 0xa2728f889ea6b0p-64 9 -0 60 -6 10 -0 N Z
++ 0 53 0xec7325c6a6ed70p-53 10 +0 61 2 9 +0 U U
+- 0 53 0x178b56362cef37p-54 11 +0 62 -1 8 +0 D U
+- 0 53 0x1936dc5690c08fp-44 12 -0 63 6 7 -0 N U
+- 0 53 0x4b0556e084f3d0p-60 13 -0 64 -4 6 -0 Z U
+- 0 53 0x15bf0a8b145769p-51 14 +0 65 1 5 +0 D D
++ 0 53 0xa2728f889ea6b0p-64 15 +0 66 -6 4 +0 N D
+- 0 53 0x3699205c4e74b0p-48 16 -0 67 4 3 -0 Z D
++ 0 53 0x454aaa8efe0730p-57 17 -0 68 -2 2 -0 U D
+
+# purely imaginary argument
+- + 53 0x1eb9b7097822f5p-53 53 -0x4787c62ac28b0p-52 53 +0 53 6 N N
++ + 53 -0x53aa981b6c9300p-55 53 -0xc1bdceeee0f57p-52 51 -0 54 4 Z N
++ - 53 -0x6a88995d4dc810p-56 53 -0xe8c7b7568da23p-52 49 +0 55 -2 U N
+- + 53 0x114a280fb5068bp-53 53 -0xd76aa47848677p-52 47 -0 56 -1 D N
++ + 53 -0x53aa981b6c9300p-55 53 -0xc1bdceeee0f57p-52 45 +0 57 4 Z Z
++ - 53 -0x6a88995d4dc810p-56 53 0x1d18f6ead1b445p-53 43 -0 58 2 U Z
+- + 53 0x114a280fb5068bp-53 53 -0xd76aa47848677p-52 41 +0 59 -1 D Z
+- - 53 0x1eb9b7097822f5p-53 53 0x4787c62ac28b0p-52 39 -0 60 -6 N Z
++ + 53 -0x6a88995d4dc810p-56 53 0xe8c7b7568da23p-52 37 +0 61 2 U U
+- + 53 0x114a280fb5068bp-53 53 0x1aed548f090cefp-53 35 -0 62 1 D U
+- + 53 0x1eb9b7097822f5p-53 53 0x11e1f18ab0a2c1p-54 33 +0 63 -6 N U
++ + 53 -0x53aa981b6c9300p-55 53 0x1837b9dddc1eafp-53 31 -0 64 -4 Z U
+- - 53 0x114a280fb5068bp-53 53 0xd76aa47848677p-52 29 +0 65 1 D D
+- - 53 0x1eb9b7097822f5p-53 53 -0x11e1f18ab0a2c1p-54 27 -0 66 6 N D
++ - 53 -0x53aa981b6c9300p-55 53 0xc1bdceeee0f57p-52 25 +0 67 -4 Z D
++ - 53 -0x6a88995d4dc810p-56 53 -0xe8c7b7568da23p-52 23 -0 68 -2 U D
+
+# overflow
+- - 2 -inf 2 -inf 53 0x3312ae437f94441ec@-9 53 0xe45f7bab0595dd700@-10 N N
+
+# input close to 0
+? ? 53 1 53 0x5D7A2148071Fp-7213522 53 0x1E02AE0D0F6Fp-7213521 53 0x5D7A2148071Fp-7213522 N N
diff --git a/mpc/tests/fma.dat b/mpc/tests/fma.dat
new file mode 100644
index 0000000000..6d0f682139
--- /dev/null
+++ b/mpc/tests/fma.dat
@@ -0,0 +1,32 @@
+# Data file for mpc_exp.
+#
+# Copyright (C) 2008, 2010, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP1_RE OP1_RE PREC_OP1_IM OP1_IM PREC_OP2_RE OP2_RE PREC_OP2_IM OP2_IM PREC_OP3_RE OP3_RE PREC_OP3_IM OP3_IM RND_RE RND_IM
+#
+# see sin.dat for precisions
+
++ - 53 -0x189281b52abc03p-55 53 0x178a1d3cd134e5p-49 53 0x16A09E667F3BCDp-52 53 0x9CC470A049097p-50 53 0x23C6EF372FE95p-48 53 0x9CC470A049097p-50 53 0xA953FD4E97C75p-50 53 0x16A09E667F3BCDp-51 N N
++ + 53 -0x178a1d3cd134e5p-49 53 -0x189281b52abc03p-55 53 -0x9CC470A049097p-50 53 0x16A09E667F3BCDp-52 53 0x23C6EF372FE95p-48 53 0x9CC470A049097p-50 53 -0x16A09E667F3BCDp-51 53 0xA953FD4E97C75p-50 N N
++ + 53 -0x178a1d3cd134e5p-49 53 -0x189281b52abc03p-55 53 -0x9CC470A049097p-50 53 0x16A09E667F3BCDp-52 53 0x23C6EF372FE95p-48 53 0x9CC470A049097p-50 53 -0x16A09E667F3BCDp-51 53 0xA953FD4E97C75p-50 U U
+0 0 10 0 10 0 10 7 10 5 10 3 10 -12 10 -81 10 69 N N
+0 0 10 0 10 0 10 7 10 5 10 3 10 -12 10 -81 10 69 Z D
+0 0 2 1 2 1 7 99 7 98 7 97 7 96 7 -194 15 -19009 N N
diff --git a/mpc/tests/fr_div.dat b/mpc/tests/fr_div.dat
new file mode 100644
index 0000000000..cb9a5a90da
--- /dev/null
+++ b/mpc/tests/fr_div.dat
@@ -0,0 +1,381 @@
+# Data file for mpc_fr_div.
+#
+# Copyright (C) 2008, 2009 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see add.dat, and take into
+# account the necessary modifications for one real argument.
+
+# special values
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 -1 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 -1 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 -1 7 +0 N N
+0 0 7 +inf 7 +inf 7 -inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -inf 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 -inf 7 -0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 -inf N N
+0 0 7 nan 7 -inf 7 -inf 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 +0 7 +0 N N
+0 0 7 nan 7 +inf 7 -inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 1 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 1 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -inf 7 -inf N N
+0 0 7 +0 7 -0 7 -1 7 -inf 7 -1 N N
+0 0 7 +0 7 -0 7 -1 7 -inf 7 -0 N N
+0 0 7 +0 7 +0 7 -1 7 -inf 7 +0 N N
+0 0 7 +0 7 +0 7 -1 7 -inf 7 1 N N
+0 0 7 +0 7 +0 7 -1 7 -inf 7 +inf N N
+0 0 7 +0 7 +0 7 -1 7 -inf 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -1 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 nan N N
+0 0 7 +0 7 -0 7 -1 7 -0 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 1 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 +inf 7 -inf N N
+0 0 7 -0 7 +0 7 -1 7 +inf 7 -1 N N
+0 0 7 -0 7 +0 7 -1 7 +inf 7 -0 N N
+0 0 7 -0 7 +0 7 -1 7 +inf 7 +0 N N
+0 0 7 -0 7 +0 7 -1 7 +inf 7 1 N N
+0 0 7 -0 7 +0 7 -1 7 +inf 7 +inf N N
+0 0 7 -0 7 +0 7 -1 7 +inf 7 nan N N
+0 0 7 -0 7 -0 7 -1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 1 N N
+0 0 7 +0 7 +0 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -inf 7 -inf N N
+0 0 7 +0 7 -0 7 -0 7 -inf 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 -inf 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 -inf 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 -inf 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 -inf 7 +inf N N
+0 0 7 +0 7 +0 7 -0 7 -inf 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -1 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 nan N N
+0 0 7 +0 7 -0 7 -0 7 -0 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 1 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 +inf 7 -inf N N
+0 0 7 -0 7 +0 7 -0 7 +inf 7 -1 N N
+0 0 7 -0 7 +0 7 -0 7 +inf 7 -0 N N
+0 0 7 +0 7 +0 7 -0 7 +inf 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 +inf 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 +inf 7 +inf N N
+0 0 7 +0 7 +0 7 -0 7 +inf 7 nan N N
+0 0 7 -0 7 +0 7 -0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 -inf 7 -inf N N
+0 0 7 -0 7 +0 7 +0 7 -inf 7 -1 N N
+0 0 7 -0 7 +0 7 +0 7 -inf 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 -inf 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 -inf 7 1 N N
+0 0 7 +0 7 -0 7 +0 7 -inf 7 +inf N N
+0 0 7 +0 7 -0 7 +0 7 -inf 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 -1 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 nan N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 1 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 1 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 +inf 7 -inf N N
+0 0 7 +0 7 +0 7 +0 7 +inf 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 +inf 7 -0 N N
+0 0 7 +0 7 +0 7 +0 7 +inf 7 +0 N N
+0 0 7 +0 7 +0 7 +0 7 +inf 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 +inf 7 +inf N N
+0 0 7 +0 7 +0 7 +0 7 +inf 7 nan N N
+0 0 7 +0 7 +0 7 +0 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 1 N N
+0 0 7 +0 7 +0 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan N N
+0 0 7 -0 7 +0 7 1 7 -inf 7 -inf N N
+0 0 7 -0 7 +0 7 1 7 -inf 7 -1 N N
+0 0 7 -0 7 +0 7 1 7 -inf 7 -0 N N
+0 0 7 -0 7 -0 7 1 7 -inf 7 +0 N N
+0 0 7 -0 7 -0 7 1 7 -inf 7 1 N N
+0 0 7 -0 7 -0 7 1 7 -inf 7 +inf N N
+0 0 7 -0 7 -0 7 1 7 -inf 7 nan N N
+0 0 7 -0 7 +0 7 1 7 -1 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -1 7 nan N N
+0 0 7 -0 7 +0 7 1 7 -0 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -0 7 nan N N
+0 0 7 +0 7 +0 7 1 7 +0 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +0 7 nan N N
+0 0 7 +0 7 +0 7 1 7 1 7 -inf N N
+0 0 7 +0 7 -0 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 1 7 nan N N
+0 0 7 +0 7 +0 7 1 7 +inf 7 -inf N N
+0 0 7 +0 7 +0 7 1 7 +inf 7 -1 N N
+0 0 7 +0 7 +0 7 1 7 +inf 7 -0 N N
+0 0 7 +0 7 +0 7 1 7 +inf 7 +0 N N
+0 0 7 +0 7 +0 7 1 7 +inf 7 1 N N
+0 0 7 +0 7 -0 7 1 7 +inf 7 +inf N N
+0 0 7 +0 7 +0 7 1 7 +inf 7 nan N N
+0 0 7 +0 7 +0 7 1 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 1 7 nan 7 1 N N
+0 0 7 +0 7 -0 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 -1 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 -1 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 -1 7 +0 N N
+0 0 7 -inf 7 -inf 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 +inf 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 +inf 7 -0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 -inf N N
+0 0 7 nan 7 +inf 7 +inf 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 +0 7 +0 N N
+0 0 7 nan 7 -inf 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 -inf N N
+0 0 7 +inf 7 +inf 7 +inf 7 1 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 1 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan N N
+
+# finite values
+0 0 7 0.5 7 -0.5 7 -1 7 -1 7 -1 N N
+0 0 7 1 7 -0 7 -1 7 -1 7 -0 N N
+# cf line 2206 of div.dat, revision 658:
+0 0 7 1 7 +0 7 -1 7 -1 7 +0 N N
+0 0 7 0.5 7 0.5 7 -1 7 -1 7 1 N N
+# cf line 2208 of div.dat, revision 658:
+0 0 7 +0 7 -1 7 -1 7 -0 7 -1 N N
+0 0 7 +inf 7 nan 7 -1 7 -0 7 -0 N N
+0 0 7 +inf 7 nan 7 -1 7 -0 7 +0 N N
+0 0 7 +0 7 1 7 -1 7 -0 7 1 N N
+0 0 7 -0 7 -1 7 -1 7 +0 7 -1 N N
+0 0 7 -inf 7 nan 7 -1 7 +0 7 -0 N N
+0 0 7 -inf 7 nan 7 -1 7 +0 7 +0 N N
+0 0 7 +0 7 1 7 -1 7 +0 7 1 N N
+0 0 7 -0.5 7 -0.5 7 -1 7 1 7 -1 N N
+0 0 7 -1 7 +0 7 -1 7 1 7 -0 N N
+0 0 7 -1 7 +0 7 -1 7 1 7 +0 N N
+0 0 7 -0.5 7 0.5 7 -1 7 1 7 1 N N
+0 0 7 0 7 -0 7 -0 7 -1 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 -1 7 -0 N N
+# cf line 2270 of div.dat, revision 658:
+0 0 7 +0 7 +0 7 -0 7 -1 7 +0 N N
+0 0 7 +0 7 0 7 -0 7 -1 7 1 N N
+# cf line 2272 of div.dat, revision 658:
+0 0 7 +0 7 -0 7 -0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 1 N N
+# cf line 2276 of div.dat, revision 658:
+0 0 7 -0 7 +0 7 -0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 +0 N N
+0 0 7 +0 7 +0 7 -0 7 +0 7 1 N N
+0 0 7 -0 7 0 7 -0 7 1 7 -1 N N
+0 0 7 -0 7 +0 7 -0 7 1 7 -0 N N
+# cf line 2282 of div.dat, revision 658:
+0 0 7 +0 7 +0 7 -0 7 1 7 +0 N N
+0 0 7 0 7 +0 7 -0 7 1 7 1 N N
+0 0 7 -0 7 0 7 +0 7 -1 7 -1 N N
+# cf line 2333 of div.dat, revision 658:
+0 0 7 -0 7 +0 7 +0 7 -1 7 -0 N N
+# cf line 2334 of div.dat, revision 658:
+0 0 7 +0 7 -0 7 +0 7 -1 7 +0 N N
+0 0 7 0 7 -0 7 +0 7 -1 7 1 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 1 N N
+# cf line 2340 of div.dat, revision 658:
+0 0 7 +0 7 +0 7 +0 7 +0 7 -1 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 -0 N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 +0 N N
+# cf line 2343 of div.dat, revision 658:
+0 0 7 +0 7 +0 7 +0 7 +0 7 1 N N
+0 0 7 0 7 +0 7 +0 7 1 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 1 7 -0 N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +0 N N
+0 0 7 +0 7 0 7 +0 7 1 7 1 N N
+0 0 7 -0.5 7 0.5 7 1 7 -1 7 -1 N N
+# cf line 2397 of div.dat, revision 658:
+0 0 7 -1 7 +0 7 1 7 -1 7 -0 N N
+0 0 7 -1 7 -0 7 1 7 -1 7 +0 N N
+0 0 7 -0.5 7 -0.5 7 1 7 -1 7 1 N N
+0 0 7 -0 7 1 7 1 7 -0 7 -1 N N
+0 0 7 -inf 7 nan 7 1 7 -0 7 -0 N N
+0 0 7 -inf 7 nan 7 1 7 -0 7 +0 N N
+0 0 7 +0 7 -1 7 1 7 -0 7 1 N N
+# cf line 2404 of div.dat, revision 658:
+0 0 7 +0 7 1 7 1 7 +0 7 -1 N N
+0 0 7 +inf 7 nan 7 1 7 +0 7 -0 N N
+0 0 7 +inf 7 nan 7 1 7 +0 7 +0 N N
+0 0 7 +0 7 -1 7 1 7 +0 7 1 N N
+0 0 7 0.5 7 0.5 7 1 7 1 7 -1 N N
+0 0 7 1 7 +0 7 1 7 1 7 -0 N N
+0 0 7 1 7 +0 7 1 7 1 7 +0 N N
+0 0 7 0.5 7 -0.5 7 1 7 1 7 1 N N
+
diff --git a/mpc/tests/fr_sub.dat b/mpc/tests/fr_sub.dat
new file mode 100644
index 0000000000..460e07d8da
--- /dev/null
+++ b/mpc/tests/fr_sub.dat
@@ -0,0 +1,373 @@
+# Data file for mpc_fr_sub.
+#
+# Copyright (C) 2008, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see add_fr.dat.
+
+# special values
+0 0 7 nan 7 +inf 7 -inf 7 -inf 7 -inf N N
+0 0 7 nan 7 1 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 +0 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 -0 7 -inf 7 -inf 7 +0 N N
+0 0 7 nan 7 -1 7 -inf 7 -inf 7 1 N N
+0 0 7 nan 7 -inf 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan N N
+0 0 7 -inf 7 +inf 7 -inf 7 -1 7 -inf N N
+0 0 7 -inf 7 1 7 -inf 7 -1 7 -1 N N
+0 0 7 -inf 7 +0 7 -inf 7 -1 7 -0 N N
+0 0 7 -inf 7 -0 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 -1 7 -inf 7 -1 7 1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -1 7 +inf N N
+0 0 7 -inf 7 nan 7 -inf 7 -1 7 nan N N
+0 0 7 -inf 7 +inf 7 -inf 7 -0 7 -inf N N
+0 0 7 -inf 7 1 7 -inf 7 -0 7 -1 N N
+0 0 7 -inf 7 +0 7 -inf 7 -0 7 -0 N N
+0 0 7 -inf 7 -0 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 -1 7 -inf 7 -0 7 1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -0 7 +inf N N
+0 0 7 -inf 7 nan 7 -inf 7 -0 7 nan N N
+0 0 7 -inf 7 +inf 7 -inf 7 +0 7 -inf N N
+0 0 7 -inf 7 1 7 -inf 7 +0 7 -1 N N
+0 0 7 -inf 7 +0 7 -inf 7 +0 7 -0 N N
+0 0 7 -inf 7 -0 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 -1 7 -inf 7 +0 7 1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 +0 7 +inf N N
+0 0 7 -inf 7 nan 7 -inf 7 +0 7 nan N N
+0 0 7 -inf 7 +inf 7 -inf 7 1 7 -inf N N
+0 0 7 -inf 7 1 7 -inf 7 1 7 -1 N N
+0 0 7 -inf 7 +0 7 -inf 7 1 7 -0 N N
+0 0 7 -inf 7 -0 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 -1 7 -inf 7 1 7 1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 1 7 +inf N N
+0 0 7 -inf 7 nan 7 -inf 7 1 7 nan N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 -inf N N
+0 0 7 -inf 7 1 7 -inf 7 +inf 7 -1 N N
+0 0 7 -inf 7 +0 7 -inf 7 +inf 7 -0 N N
+0 0 7 -inf 7 -0 7 -inf 7 +inf 7 +0 N N
+0 0 7 -inf 7 -1 7 -inf 7 +inf 7 1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 +inf 7 +inf N N
+0 0 7 -inf 7 nan 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 +inf 7 -inf 7 nan 7 -inf N N
+0 0 7 nan 7 1 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 +0 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 -0 7 -inf 7 nan 7 +0 N N
+0 0 7 nan 7 -1 7 -inf 7 nan 7 1 N N
+0 0 7 nan 7 -inf 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan N N
+0 0 7 +inf 7 +inf 7 -1 7 -inf 7 -inf N N
+0 0 7 +inf 7 1 7 -1 7 -inf 7 -1 N N
+0 0 7 +inf 7 +0 7 -1 7 -inf 7 -0 N N
+0 0 7 +inf 7 -0 7 -1 7 -inf 7 +0 N N
+0 0 7 +inf 7 -1 7 -1 7 -inf 7 1 N N
+0 0 7 +inf 7 -inf 7 -1 7 -inf 7 +inf N N
+0 0 7 +inf 7 nan 7 -1 7 -inf 7 nan N N
+0 0 7 0 7 +inf 7 -1 7 -1 7 -inf N N
+0 0 7 0 7 -inf 7 -1 7 -1 7 +inf N N
+0 0 7 0 7 nan 7 -1 7 -1 7 nan N N
+0 0 7 -1 7 +inf 7 -1 7 -0 7 -inf N N
+0 0 7 -1 7 -inf 7 -1 7 -0 7 +inf N N
+0 0 7 -1 7 nan 7 -1 7 -0 7 nan N N
+0 0 7 -1 7 +inf 7 -1 7 +0 7 -inf N N
+0 0 7 -1 7 -inf 7 -1 7 +0 7 +inf N N
+0 0 7 -1 7 nan 7 -1 7 +0 7 nan N N
+0 0 7 -2 7 +inf 7 -1 7 1 7 -inf N N
+0 0 7 -2 7 -inf 7 -1 7 1 7 +inf N N
+0 0 7 -2 7 nan 7 -1 7 1 7 nan N N
+0 0 7 -inf 7 +inf 7 -1 7 +inf 7 -inf N N
+0 0 7 -inf 7 1 7 -1 7 +inf 7 -1 N N
+0 0 7 -inf 7 +0 7 -1 7 +inf 7 -0 N N
+0 0 7 -inf 7 -0 7 -1 7 +inf 7 +0 N N
+0 0 7 -inf 7 -1 7 -1 7 +inf 7 1 N N
+0 0 7 -inf 7 -inf 7 -1 7 +inf 7 +inf N N
+0 0 7 -inf 7 nan 7 -1 7 +inf 7 nan N N
+0 0 7 nan 7 +inf 7 -1 7 nan 7 -inf N N
+0 0 7 nan 7 1 7 -1 7 nan 7 -1 N N
+0 0 7 nan 7 +0 7 -1 7 nan 7 -0 N N
+0 0 7 nan 7 -0 7 -1 7 nan 7 +0 N N
+0 0 7 nan 7 -1 7 -1 7 nan 7 1 N N
+0 0 7 nan 7 -inf 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan N N
+0 0 7 +inf 7 +inf 7 -0 7 -inf 7 -inf N N
+0 0 7 +inf 7 1 7 -0 7 -inf 7 -1 N N
+0 0 7 +inf 7 +0 7 -0 7 -inf 7 -0 N N
+0 0 7 +inf 7 -0 7 -0 7 -inf 7 +0 N N
+0 0 7 +inf 7 -1 7 -0 7 -inf 7 1 N N
+0 0 7 +inf 7 -inf 7 -0 7 -inf 7 +inf N N
+0 0 7 +inf 7 nan 7 -0 7 -inf 7 nan N N
+0 0 7 1 7 +inf 7 -0 7 -1 7 -inf N N
+0 0 7 1 7 -inf 7 -0 7 -1 7 +inf N N
+0 0 7 1 7 nan 7 -0 7 -1 7 nan N N
+0 0 7 0 7 +inf 7 -0 7 -0 7 -inf N N
+0 0 7 0 7 -inf 7 -0 7 -0 7 +inf N N
+0 0 7 0 7 nan 7 -0 7 -0 7 nan N N
+0 0 7 -0 7 +inf 7 -0 7 +0 7 -inf N N
+0 0 7 -0 7 -inf 7 -0 7 +0 7 +inf N N
+0 0 7 -0 7 nan 7 -0 7 +0 7 nan N N
+0 0 7 -1 7 +inf 7 -0 7 1 7 -inf N N
+0 0 7 -1 7 -inf 7 -0 7 1 7 +inf N N
+0 0 7 -1 7 nan 7 -0 7 1 7 nan N N
+0 0 7 -inf 7 +inf 7 -0 7 +inf 7 -inf N N
+0 0 7 -inf 7 1 7 -0 7 +inf 7 -1 N N
+0 0 7 -inf 7 +0 7 -0 7 +inf 7 -0 N N
+0 0 7 -inf 7 -0 7 -0 7 +inf 7 +0 N N
+0 0 7 -inf 7 -1 7 -0 7 +inf 7 1 N N
+0 0 7 -inf 7 -inf 7 -0 7 +inf 7 +inf N N
+0 0 7 -inf 7 nan 7 -0 7 +inf 7 nan N N
+0 0 7 nan 7 +inf 7 -0 7 nan 7 -inf N N
+0 0 7 nan 7 1 7 -0 7 nan 7 -1 N N
+0 0 7 nan 7 +0 7 -0 7 nan 7 -0 N N
+0 0 7 nan 7 -0 7 -0 7 nan 7 +0 N N
+0 0 7 nan 7 -1 7 -0 7 nan 7 1 N N
+0 0 7 nan 7 -inf 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan N N
+0 0 7 +inf 7 +inf 7 +0 7 -inf 7 -inf N N
+0 0 7 +inf 7 1 7 +0 7 -inf 7 -1 N N
+0 0 7 +inf 7 +0 7 +0 7 -inf 7 -0 N N
+0 0 7 +inf 7 -0 7 +0 7 -inf 7 +0 N N
+0 0 7 +inf 7 -1 7 +0 7 -inf 7 1 N N
+0 0 7 +inf 7 -inf 7 +0 7 -inf 7 +inf N N
+0 0 7 +inf 7 nan 7 +0 7 -inf 7 nan N N
+0 0 7 1 7 +inf 7 +0 7 -1 7 -inf N N
+0 0 7 1 7 -inf 7 +0 7 -1 7 +inf N N
+0 0 7 1 7 nan 7 +0 7 -1 7 nan N N
+0 0 7 +0 7 +inf 7 +0 7 -0 7 -inf N N
+0 0 7 +0 7 -inf 7 +0 7 -0 7 +inf N N
+0 0 7 +0 7 nan 7 +0 7 -0 7 nan N N
+0 0 7 0 7 +inf 7 +0 7 +0 7 -inf N N
+0 0 7 0 7 -inf 7 +0 7 +0 7 +inf N N
+0 0 7 0 7 nan 7 +0 7 +0 7 nan N N
+0 0 7 -1 7 +inf 7 +0 7 1 7 -inf N N
+0 0 7 -1 7 -inf 7 +0 7 1 7 +inf N N
+0 0 7 -1 7 nan 7 +0 7 1 7 nan N N
+0 0 7 -inf 7 +inf 7 +0 7 +inf 7 -inf N N
+0 0 7 -inf 7 1 7 +0 7 +inf 7 -1 N N
+0 0 7 -inf 7 +0 7 +0 7 +inf 7 -0 N N
+0 0 7 -inf 7 -0 7 +0 7 +inf 7 +0 N N
+0 0 7 -inf 7 -1 7 +0 7 +inf 7 1 N N
+0 0 7 -inf 7 -inf 7 +0 7 +inf 7 +inf N N
+0 0 7 -inf 7 nan 7 +0 7 +inf 7 nan N N
+0 0 7 nan 7 +inf 7 +0 7 nan 7 -inf N N
+0 0 7 nan 7 1 7 +0 7 nan 7 -1 N N
+0 0 7 nan 7 +0 7 +0 7 nan 7 -0 N N
+0 0 7 nan 7 -0 7 +0 7 nan 7 +0 N N
+0 0 7 nan 7 -1 7 +0 7 nan 7 1 N N
+0 0 7 nan 7 -inf 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan N N
+0 0 7 +inf 7 +inf 7 1 7 -inf 7 -inf N N
+0 0 7 +inf 7 1 7 1 7 -inf 7 -1 N N
+0 0 7 +inf 7 +0 7 1 7 -inf 7 -0 N N
+0 0 7 +inf 7 -0 7 1 7 -inf 7 +0 N N
+0 0 7 +inf 7 -1 7 1 7 -inf 7 1 N N
+0 0 7 +inf 7 -inf 7 1 7 -inf 7 +inf N N
+0 0 7 +inf 7 nan 7 1 7 -inf 7 nan N N
+0 0 7 2 7 +inf 7 1 7 -1 7 -inf N N
+0 0 7 2 7 -inf 7 1 7 -1 7 +inf N N
+0 0 7 2 7 nan 7 1 7 -1 7 nan N N
+0 0 7 1 7 +inf 7 1 7 -0 7 -inf N N
+0 0 7 1 7 -inf 7 1 7 -0 7 +inf N N
+0 0 7 1 7 nan 7 1 7 -0 7 nan N N
+0 0 7 1 7 +inf 7 1 7 +0 7 -inf N N
+0 0 7 1 7 -inf 7 1 7 +0 7 +inf N N
+0 0 7 1 7 nan 7 1 7 +0 7 nan N N
+0 0 7 0 7 +inf 7 1 7 1 7 -inf N N
+0 0 7 0 7 -inf 7 1 7 1 7 +inf N N
+0 0 7 0 7 nan 7 1 7 1 7 nan N N
+0 0 7 -inf 7 +inf 7 1 7 +inf 7 -inf N N
+0 0 7 -inf 7 1 7 1 7 +inf 7 -1 N N
+0 0 7 -inf 7 +0 7 1 7 +inf 7 -0 N N
+0 0 7 -inf 7 -0 7 1 7 +inf 7 +0 N N
+0 0 7 -inf 7 -1 7 1 7 +inf 7 1 N N
+0 0 7 -inf 7 -inf 7 1 7 +inf 7 +inf N N
+0 0 7 -inf 7 nan 7 1 7 +inf 7 nan N N
+0 0 7 nan 7 +inf 7 1 7 nan 7 -inf N N
+0 0 7 nan 7 1 7 1 7 nan 7 -1 N N
+0 0 7 nan 7 +0 7 1 7 nan 7 -0 N N
+0 0 7 nan 7 -0 7 1 7 nan 7 +0 N N
+0 0 7 nan 7 -1 7 1 7 nan 7 1 N N
+0 0 7 nan 7 -inf 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan N N
+0 0 7 +inf 7 +inf 7 +inf 7 -inf 7 -inf N N
+0 0 7 +inf 7 1 7 +inf 7 -inf 7 -1 N N
+0 0 7 +inf 7 +0 7 +inf 7 -inf 7 -0 N N
+0 0 7 +inf 7 -0 7 +inf 7 -inf 7 +0 N N
+0 0 7 +inf 7 -1 7 +inf 7 -inf 7 1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 +inf N N
+0 0 7 +inf 7 nan 7 +inf 7 -inf 7 nan N N
+0 0 7 +inf 7 +inf 7 +inf 7 -1 7 -inf N N
+0 0 7 +inf 7 1 7 +inf 7 -1 7 -1 N N
+0 0 7 +inf 7 +0 7 +inf 7 -1 7 -0 N N
+0 0 7 +inf 7 -0 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 -1 7 +inf 7 -1 7 1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -1 7 +inf N N
+0 0 7 +inf 7 nan 7 +inf 7 -1 7 nan N N
+0 0 7 +inf 7 +inf 7 +inf 7 -0 7 -inf N N
+0 0 7 +inf 7 1 7 +inf 7 -0 7 -1 N N
+0 0 7 +inf 7 +0 7 +inf 7 -0 7 -0 N N
+0 0 7 +inf 7 -0 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 -1 7 +inf 7 -0 7 1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -0 7 +inf N N
+0 0 7 +inf 7 nan 7 +inf 7 -0 7 nan N N
+0 0 7 +inf 7 +inf 7 +inf 7 +0 7 -inf N N
+0 0 7 +inf 7 1 7 +inf 7 +0 7 -1 N N
+0 0 7 +inf 7 +0 7 +inf 7 +0 7 -0 N N
+0 0 7 +inf 7 -0 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 -1 7 +inf 7 +0 7 1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 +0 7 +inf N N
+0 0 7 +inf 7 nan 7 +inf 7 +0 7 nan N N
+0 0 7 +inf 7 +inf 7 +inf 7 1 7 -inf N N
+0 0 7 +inf 7 1 7 +inf 7 1 7 -1 N N
+0 0 7 +inf 7 +0 7 +inf 7 1 7 -0 N N
+0 0 7 +inf 7 -0 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 -1 7 +inf 7 1 7 1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 1 7 +inf N N
+0 0 7 +inf 7 nan 7 +inf 7 1 7 nan N N
+0 0 7 nan 7 +inf 7 +inf 7 +inf 7 -inf N N
+0 0 7 nan 7 1 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 +0 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 -0 7 +inf 7 +inf 7 +0 N N
+0 0 7 nan 7 -1 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 -inf 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan N N
+0 0 7 nan 7 +inf 7 +inf 7 nan 7 -inf N N
+0 0 7 nan 7 1 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 +0 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 -0 7 +inf 7 nan 7 +0 N N
+0 0 7 nan 7 -1 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 -inf 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 -0 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 -0 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 +0 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 1 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan N N
+
+# values with only 1, -1, +0, -0
+0 0 7 0 7 1 7 -1 7 -1 7 -1 N N
+0 0 7 0 7 +0 7 -1 7 -1 7 -0 N N
+0 0 7 0 7 -0 7 -1 7 -1 7 +0 N N
+0 0 7 0 7 -1 7 -1 7 -1 7 1 N N
+0 0 7 -1 7 1 7 -1 7 -0 7 -1 N N
+0 0 7 -1 7 +0 7 -1 7 -0 7 -0 N N
+0 0 7 -1 7 -0 7 -1 7 -0 7 +0 N N
+0 0 7 -1 7 -1 7 -1 7 -0 7 1 N N
+0 0 7 -1 7 1 7 -1 7 +0 7 -1 N N
+0 0 7 -1 7 +0 7 -1 7 +0 7 -0 N N
+0 0 7 -1 7 -0 7 -1 7 +0 7 +0 N N
+0 0 7 -1 7 -1 7 -1 7 +0 7 1 N N
+0 0 7 -2 7 1 7 -1 7 1 7 -1 N N
+0 0 7 -2 7 +0 7 -1 7 1 7 -0 N N
+0 0 7 -2 7 -0 7 -1 7 1 7 +0 N N
+0 0 7 -2 7 -1 7 -1 7 1 7 1 N N
+0 0 7 1 7 1 7 -0 7 -1 7 -1 N N
+0 0 7 1 7 +0 7 -0 7 -1 7 -0 N N
+0 0 7 1 7 -0 7 -0 7 -1 7 +0 N N
+0 0 7 1 7 -1 7 -0 7 -1 7 1 N N
+0 0 7 0 7 1 7 -0 7 -0 7 -1 N N
+0 0 7 0 7 +0 7 -0 7 -0 7 -0 N N
+0 0 7 0 7 -0 7 -0 7 -0 7 +0 N N
+0 0 7 0 7 -1 7 -0 7 -0 7 1 N N
+0 0 7 -0 7 1 7 -0 7 +0 7 -1 N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 -0 N N
+0 0 7 -0 7 -0 7 -0 7 +0 7 +0 N N
+0 0 7 -0 7 -1 7 -0 7 +0 7 1 N N
+0 0 7 -1 7 1 7 -0 7 1 7 -1 N N
+0 0 7 -1 7 +0 7 -0 7 1 7 -0 N N
+0 0 7 -1 7 -0 7 -0 7 1 7 +0 N N
+0 0 7 -1 7 -1 7 -0 7 1 7 1 N N
+0 0 7 1 7 1 7 +0 7 -1 7 -1 N N
+0 0 7 1 7 +0 7 +0 7 -1 7 -0 N N
+0 0 7 1 7 -0 7 +0 7 -1 7 +0 N N
+0 0 7 1 7 -1 7 +0 7 -1 7 1 N N
+0 0 7 +0 7 1 7 +0 7 -0 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 -0 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +0 N N
+0 0 7 +0 7 -1 7 +0 7 -0 7 1 N N
+0 0 7 0 7 1 7 +0 7 +0 7 -1 N N
+0 0 7 0 7 +0 7 +0 7 +0 7 -0 N N
+0 0 7 0 7 -0 7 +0 7 +0 7 +0 N N
+0 0 7 0 7 -1 7 +0 7 +0 7 1 N N
+0 0 7 -1 7 1 7 +0 7 1 7 -1 N N
+0 0 7 -1 7 +0 7 +0 7 1 7 -0 N N
+0 0 7 -1 7 -0 7 +0 7 1 7 +0 N N
+0 0 7 -1 7 -1 7 +0 7 1 7 1 N N
+0 0 7 2 7 1 7 1 7 -1 7 -1 N N
+0 0 7 2 7 +0 7 1 7 -1 7 -0 N N
+0 0 7 2 7 -0 7 1 7 -1 7 +0 N N
+0 0 7 2 7 -1 7 1 7 -1 7 1 N N
+0 0 7 1 7 1 7 1 7 -0 7 -1 N N
+0 0 7 1 7 +0 7 1 7 -0 7 -0 N N
+0 0 7 1 7 -0 7 1 7 -0 7 +0 N N
+0 0 7 1 7 -1 7 1 7 -0 7 1 N N
+0 0 7 1 7 1 7 1 7 +0 7 -1 N N
+0 0 7 1 7 +0 7 1 7 +0 7 -0 N N
+0 0 7 1 7 -0 7 1 7 +0 7 +0 N N
+0 0 7 1 7 -1 7 1 7 +0 7 1 N N
+0 0 7 0 7 1 7 1 7 1 7 -1 N N
+0 0 7 0 7 +0 7 1 7 1 7 -0 N N
+0 0 7 0 7 -0 7 1 7 1 7 +0 N N
+0 0 7 0 7 -1 7 1 7 1 7 1 N N
+
+# inexact return values
+- - 2 -8 2 -8 3 1 3 8 3 7 D D
+- - 2 -8 2 -8 3 1 3 8 3 7 N N
++ + 2 -6 2 -6 3 1 3 8 3 7 U U
++ + 2 -6 2 -6 3 1 3 8 3 7 Z Z
diff --git a/mpc/tests/inp_str.dat b/mpc/tests/inp_str.dat
new file mode 100644
index 0000000000..b6cd79859a
--- /dev/null
+++ b/mpc/tests/inp_str.dat
@@ -0,0 +1,163 @@
+# Data file for mpc_inp_str.
+#
+# Copyright (C) 2009 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The format respects the parameter order in function prototype as follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM SIZE BASE RND_RE RND_IM "STRING"
+#
+# The string STRING is considered as a complex number rop = rop1 + i*rop2
+# written in base BASE as "rop1 " if rop is real or "(rop1 rop2)". Notice that
+# a least one whitespace is required after real part
+#
+# ROP_RE is checked against rop1 rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against rop2 rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "!" function should return error indicator -1
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# invalid strings
+! ! 53 nan 53 nan 3 10 N N "non "
+! ! 53 nan 53 nan 4 10 N N " NON "
+! ! 53 nan 53 nan 5 10 N N "nan(0 1) " #invalid space in brackets
+! ! 53 nan 53 nan 5 10 N N "nan(0-1) " #invalid char in brackets
+! ! 53 nan 53 nan 4 10 N N "NaN((keepout)) " #two levels of parenthesis
+! ! 53 nan 53 nan 4 10 N N "(1e1) " #one part missing
+! ! 53 nan 53 nan 1 10 N N ". " #no digit
+! ! 53 nan 53 nan 2 2 N N "+3 " #invalid binary digit
+! ! 53 nan 53 nan 6 10 N N "( +INF) " #one part missing
+! ! 53 nan 53 nan 2 10 N N "(1(1))" #too many levels of parentheses
+! ! 53 nan 53 nan 3 10 N N "(1 (1 (1 0)))"
+! ! 53 nan 53 nan 1 10 N N "((1 1)) "
+! ! 53 nan 53 nan 6 10 N N "(1 +1 " #closing parenthesis missing
+! ! 53 nan 53 nan 4 10 N N "(1+1) " #space needed
+! ! 53 nan 53 nan 5 10 N N "(1 + 1) " #space after sign
+! ! 53 nan 53 nan 17 10 N N "(@nan@(quiet) 0 " #closing parenthesis missing
+! ! 53 nan 53 nan 4 10 N N "zero " #invalid digits
+! ! 53 nan 53 nan 3 10 N N "&^+ " #invalid digits
+! ! 53 nan 53 nan 1 18 N N "i " #invalid digit
+! ! 53 nan 53 nan 1 18 N N "I " #invalid digit
+! ! 53 nan 53 nan 1 35 N N "z " #invalid digit
+! ! 53 nan 53 nan 1 35 N N "Z " #invalid digit
+! ! 53 nan 53 nan 5 18 N N "(i 0) " #invalid digit
+! ! 53 nan 53 nan 5 18 N N "(I 0) " #invalid digit
+! ! 53 nan 53 nan 5 35 N N "(z 0) " #invalid digit
+! ! 53 nan 53 nan 5 35 N N "(Z 0) " #invalid digit
+! ! 53 nan 53 nan 5 18 N N "(0 i) " #invalid digit
+! ! 53 nan 53 nan 5 18 N N "(0 I) " #invalid digit
+! ! 53 nan 53 nan 5 35 N N "(0 z) " #invalid digit
+! ! 53 nan 53 nan 5 35 N N "(0 Z) " #invalid digit
+! ! 53 nan 53 nan 7 10 N N "-25p+32 " #invalid exponent char in base 10
+! ! 53 nan 53 nan 6 10 N N "0xabcd " #invalid prefix in base 10
+! ! 53 nan 53 nan 6 10 N N "+0b010 " #invalid prefix in base 10
+
+# special values
+0 0 53 nan 53 +0 3 10 N N "nan "
+0 0 53 nan 53 +0 4 10 N N "+NAN "
+0 0 53 nan 53 +0 5 10 N N "@NAN@ "
+0 0 53 nan 53 nan 18 10 N N "(@nan@(QUIET) nan) "
+0 0 53 nan 53 +0 5 10 N N "@nan@ "
+0 0 53 nan 53 +0 12 10 N N "NaN(keepout) "
+0 0 53 nan 53 +0 122 10 N N "Nan(very_long_suffix_oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo) "
+0 0 53 nan 53 +0 8 10 N N "nan(0_1) "
+0 0 53 nan 53 +0 3 10 N N "nan "
+0 0 53 inf 53 +0 3 10 N N "inf "
+0 0 53 -inf 53 +0 4 10 N N "-inf "
+0 0 53 +inf 53 +0 8 10 N N "infinity "
+0 0 53 +inf 53 +0 4 10 N N "+INF "
+0 0 53 +0 53 +inf 8 10 N N "(0 +inf) "
+0 0 53 +0 53 +inf 12 10 N N "(+0 INF) "
+0 0 53 +0 53 -inf 13 10 N N "(0 -infinity) "
+0 0 53 +0 53 -inf 9 10 N N "(+0 -INF) "
+0 0 53 -inf 53 -0 11 10 N N "(-@inf@ -0) "
+0 0 53 +inf 53 nan 17 10 N N "(+inf nan(9u137)) "
+0 0 53 nan 53 +inf 12 10 N N "(NaN +inf ) "
+
+# pure real argument
+0 0 53 +0 53 +0 1 10 N N "0 "
+0 0 53 +0 53 +0 5 10 N N "00000 "
+0 0 53 +0 53 +0 2 10 N N "+0 "
+0 0 53 -0 53 +0 2 10 N N "-0 "
+0 0 53 +1 53 +0 1 10 N N "1 "
+0 0 53 +1 53 +0 3 10 N N "001 "
+0 0 53 +1 53 +0 6 10 N N "1.0000 "
+0 0 53 +1 53 +0 2 10 N N "+1) "
+- 0 53 +0x9D70A3D70A3D7p-51 53 +0 11 10 N N "(+1.23 0.0) "
+0 0 53 -10 53 +0 11 10 N N "(-10. 0000) "
+0 0 53 +0x5p-3 53 -0 12 10 N N "( .625 -0 )"
+- 0 53 +0x14E718D7D7625Ap+612 53 +0 10 10 N N "(1e200 0) "
++ 0 53 +0x14E718D7D7625Bp+612 53 +0 10 10 U N "(1e200 0) "
+- 0 53 +0x14E718D7D7625Ap+612 53 +0 10 10 D N "(1e200 0) "
+0 0 53 +0x7530 53 +0 8 10 N N "(3e+4 0) "
+- 0 53 +0x10C6F7A0B5ED8Dp-73 53 +0 5 10 N N ".5e-6 "
+- 0 53 +0x1B1C1E0D914133p-83 53 +0 12 10 N N "(7.89E-10 0) "
++ 0 53 -0x7B426FAB61F00Cp+56 53 +0 7 10 N N "-25@+32 "
+0 0 53 +43981 53 +0 6 16 N N "0xabcd "
+0 0 53 +2 53 +0 6 2 N N "+0b010 "
+0 0 53 +18 53 +0 1 20 N N "i "
+0 0 53 +18 53 +0 1 19 N N "i "
+0 0 53 +35 53 +0 1 36 N N "z "
+0 0 53 +35 53 +0 1 36 N N "Z "
+
+# pure imaginary argument
+0 0 53 +0 53 +1 5 10 N N "(0 1) "
+0 0 53 +0 53 +1 6 20 N N "(0 +1) "
+0 0 53 -0 53 -1 7 10 N N "(-0 -1) "
+0 0 53 -0 53 -2 7 10 N N "(-0 -2) "
+0 0 53 +0 53 +2 6 10 N N "(+0 2) "
+0 0 53 +0 53 +17 5 20 N N "(0 h) "
+0 0 53 +0 53 +18 5 20 N N "(0 i) "
+0 + 53 +0 53 -0x14F800008637BDp-44 19 10 N Z "(0 -33.55000005e+1) "
+0 + 53 +0 53 -0xA1765976008AFp-401 18 10 N U "(+0 -.550000E-105) "
+0 0 53 +0 53 +18 5 19 N N "(0 i) "
+0 0 53 +0 53 +18 5 19 N N "(0 I) "
+0 0 53 +0 53 +35 5 36 N N "(0 z) "
+0 0 53 +0 53 +35 5 36 N N "(0 Z) "
+
+# complex argument
+0 0 53 +1 53 +1 10 10 N N "( 1 +1) "
+0 0 53 +1 53 +1 8 10 N N "(1 +1) "
+0 0 53 +7 53 +14 7 10 N N "(7 14) "
+0 0 53 +17 53 +1 7 10 N N "(+17 1) "
+0 0 53 +27 53 +1 8 20 N N "(+17 +1) "
+0 0 53 -18 53 -1 7 20 N N "(-i -1) "
+0 0 53 +18 53 -1 6 20 N N "(i -1) "
+0 0 53 -18 53 +1 7 20 N N "(-i +1) "
+0 0 53 +18 53 +18 6 20 N N "(i +i) "
+0 0 53 -14643 53 +20328 10 36 N N "(-bar foo) "
+0 0 53 -1647190 53 -512315 13 36 N N "(-zaza -azaz) "
+0 0 53 +0b1010 53 +0xabcd 16 0 N N "(0b1010 +0xabcd) "
+0 0 53 +0xabcd 53 +0b1010 22 0 N N "(+0xa.bcd@+3 0b.101p4) "
+
+# white space before the closing ')'
+0 0 53 +1 53 +1 13 10 N N "( 1 +1 ) "
diff --git a/mpc/tests/log.dat b/mpc/tests/log.dat
new file mode 100644
index 0000000000..ee95025de8
--- /dev/null
+++ b/mpc/tests/log.dat
@@ -0,0 +1,190 @@
+# Data test file for mpc_log.
+#
+# Copyright (C) 2008, 2009, 2010, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+# See file sin.dat for the format description.
+
+# Special values, following ISO C99 standard, Annex G,
+# more precisely Section G.6.3.2 "The clog functions".
+
+# Rule [conj]: log(conj(z)) = conj(log(z))
+
+# log(-0 + i*0) = -inf + i*pi
+0 - 2 -inf 53 +0x3243F6A8885A3p-48 2 -0 2 +0 N N
+0 + 2 -inf 53 -0x3243F6A8885A3p-48 2 -0 2 -0 N N
+0 - 2 -inf 53 +0x3243F6A8885A3p-48 2 -0 2 +0 N D
+0 - 2 -inf 53 -0x3243F6A8885A32p-52 2 -0 2 -0 N D
+
+# log(+0 + i*0) = -inf + i*0
+0 0 2 -inf 2 +0 2 +0 2 +0 N N
+0 0 2 -inf 2 -0 2 +0 2 -0 N N
+
+# log(+1 +- i*0) = +0 +- i*0
+0 0 2 +0 2 +0 2 1 2 +0 N N
+0 0 2 +0 2 -0 2 1 2 -0 N N
+
+# log(-1 +- i*0) = +0 +- i*pi
+0 - 2 +0 53 +0x3243F6A8885A3p-48 2 -1 2 +0 N N
+0 + 2 +0 53 -0x3243F6A8885A3p-48 2 -1 2 -0 N N
+
+# log(x + i*inf) = +inf + i*pi/2 for finite x
+0 - 2 +inf 53 +0x3243F6A8885A3p-49 2 1 2 +inf N N
+0 - 2 +inf 53 +0x3243F6A8885A3p-49 2 +0 2 +inf N N
+0 - 2 +inf 53 +0x3243F6A8885A3p-49 2 -0 2 +inf N N
+0 - 2 +inf 53 +0x3243F6A8885A3p-49 2 -1 2 +inf N N
+# by [conj]: log(x - i*inf) = +inf - i*pi/2 for finite x
+0 + 2 +inf 53 -0x3243F6A8885A3p-49 2 1 2 -inf N N
+0 + 2 +inf 53 -0x3243F6A8885A3p-49 2 +0 2 -inf N N
+0 + 2 +inf 53 -0x3243F6A8885A3p-49 2 -0 2 -inf N N
+0 + 2 +inf 53 -0x3243F6A8885A3p-49 2 -1 2 -inf N N
+
+# log(x + i*nan) = nan+i*nan for finite x
+0 0 2 nan 2 nan 2 1 2 nan N N
+0 0 2 nan 2 nan 2 +0 2 nan N N
+0 0 2 nan 2 nan 2 -0 2 nan N N
+0 0 2 nan 2 nan 2 -1 2 nan N N
+
+# log(-inf + i*y) = +inf + i*pi for finite positive-signed y
+0 - 2 +inf 53 0x3243F6A8885A3p-48 2 -inf 2 1 N N
+0 - 2 +inf 53 0x3243F6A8885A3p-48 2 -inf 2 +0 N N
+# by [conj]: log(-inf + i*y) = +inf - i*pi for finite negative-signed y
+0 + 2 +inf 53 -0x3243F6A8885A3p-48 2 -inf 2 -1 N N
+0 + 2 +inf 53 -0x3243F6A8885A3p-48 2 -inf 2 -0 N N
+
+# log(+inf + i*y) = +inf + i*0 for finite positive-signed y
+0 0 2 +inf 2 +0 2 +inf 2 1 N N
+0 0 2 +inf 2 +0 2 +inf 2 +0 N N
+# by [conj]: log(+inf + i*y) = +inf - i*0 for finite negative-signed y
+0 0 2 +inf 2 -0 2 +inf 2 -1 N N
+0 0 2 +inf 2 -0 2 +inf 2 -0 N N
+
+# log(-inf + i*inf) = +inf + i*(3*pi/4)
+0 - 2 +inf 53 0x96CBE3F9990E9p-50 2 -inf 2 +inf N N
+# by [conj]: log(-inf - i*inf) = +inf - i*(3*pi/4)
+0 + 2 +inf 53 -0x96CBE3F9990E9p-50 2 -inf 2 -inf N N
+
+# log(+inf + i*inf) = +inf + i*(pi/4)
+0 - 2 +inf 53 0x3243F6A8885A3p-50 2 +inf 2 +inf N N
+# by [conj]: log(+inf - i*inf) = +inf - i*(pi/4)
+0 + 2 +inf 53 -0x3243F6A8885A3p-50 2 +inf 2 -inf N N
+
+# log(+/-inf + i*nan) = +inf + i*nan
+0 0 2 +inf 2 nan 2 +inf 2 nan N N
+0 0 2 +inf 2 nan 2 -inf 2 nan N N
+
+# log(nan + i*y) = nan + i*nan for finite y
+0 0 2 nan 2 nan 2 nan 2 1 N N
+0 0 2 nan 2 nan 2 nan 2 +0 N N
+0 0 2 nan 2 nan 2 nan 2 -0 N N
+0 0 2 nan 2 nan 2 nan 2 -1 N N
+
+# log(nan + i*inf) = +inf + i*nan
+0 0 2 +inf 2 nan 2 nan 2 +inf N N
+0 0 2 +inf 2 nan 2 nan 2 -inf N N
+
+# log(nan + i*nan) = nan + i*nan
+0 0 2 nan 2 nan 2 nan 2 nan N N
+
+# log(x + i*y) with either x or y zero and the other non-zero
++ 0 53 0xB5535E0FD3FBDp-50 2 0 5 0x11 2 0 N N
++ - 53 0xB5535E0FD3FBDp-50 53 0x3243F6A8885A3p-49 2 0 5 0x11 N N
+- - 53 0x5E38D81812CCBp-49 53 0x3243F6A8885A3p-48 5 -0x13 2 +0 N N
+- + 53 0x5E38D81812CCBp-49 53 -0x3243F6A8885A3p-48 5 -0x13 2 -0 N N
+- + 53 0x5E38D81812CCBp-49 53 -0x3243F6A8885A3p-49 2 0 5 -0x13 N N
+
+- + 53 0x19157DFDD1B3Fp-47 53 0x1921FB54442D19p-51 5 -0x17 2 +0 Z U
+- - 53 0x19157DFDD1B3Fp-47 53 -0x1921FB54442D19p-51 5 -0x17 2 -0 N D
++ - 53 0x19157DFDD1B3F1p-51 53 0x3243F6A8885A3p-48 5 -0x17 2 +0 U Z
+- + 53 0x19157DFDD1B3Fp-47 53 -0x3243F6A8885A3p-48 5 -0x17 2 -0 D N
+- - 53 0x8611A6D2511D3p-49 53 0x3243F6A8885A3p-48 7 -0x42 2 +0 Z D
+- + 53 0x8611A6D2511D3p-49 53 -0x3243F6A8885A3p-48 7 -0x42 2 -0 N Z
++ - 53 0x10C234DA4A23A7p-50 53 0x3243F6A8885A3p-48 7 -0x42 2 +0 U N
+- + 53 0x8611A6D2511D3p-49 53 -0x3243F6A8885A3p-48 7 -0x42 2 -0 D U
+
+# normal non-zero numbers
+- - 17 0x6701p-15 42 0x3b58ce0ac37p-43 2 2 2 1 N N
+- + 17 0x6701p-15 42 -0x3b58ce0ac37p-43 2 2 2 -1 N N
+- + 17 0x6701p-15 42 0x2ad8dce72ffp-40 2 -2 2 1 N N
+- - 17 0x6701p-15 42 -0x2ad8dce72ffp-40 2 -2 2 -1 N N
+- + 17 0x6701p-15 42 0x46db864bafp-38 2 1 2 2 N N
+- - 17 0x6701p-15 42 -0x46db864bafp-38 2 1 2 -2 N N
+- + 17 0x6701p-15 42 0x10468a8ace5p-39 2 -1 2 2 N N
+- - 17 0x6701p-15 42 -0x10468a8ace5p-39 2 -1 2 -2 N N
+
+# huge values
++ 0 53 0x162E42FEFA39Fp-39 2 0 2 0x1p1024 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-38 2 0 2 0x1p2048 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-37 2 0 2 0x1p4096 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-36 2 0 2 0x1p8192 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-35 2 0 2 0x1p16384 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-34 2 0 2 0x1p32768 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-33 2 0 2 0x1p65536 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-32 2 0 2 0x1p131072 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-31 2 0 2 0x1p262144 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-30 2 0 2 0x1p524288 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-29 2 0 2 0x1p1048576 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-28 2 0 2 0x1p2097152 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-27 2 0 2 0x1p4194304 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-26 2 0 2 0x1p8388608 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-25 2 0 2 0x1p16777216 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-24 2 0 2 0x1p33554432 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-23 2 0 2 0x1p67108864 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-22 2 0 2 0x1p134217728 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-21 2 0 2 0x1p268435456 2 +0 U U
++ 0 53 0x162E42FEFA39Fp-20 2 0 2 0x1p536870912 2 +0 U U
++ + 53 0x163108C75A1937p-43 53 0x1921FB54442D19p-53 2 0x1p1024 2 0x1p1024 U U
++ + 53 0x162FA5E32A2993p-42 53 0x1921FB54442D19p-53 2 0x1p2048 2 0x1p2048 U U
++ + 53 0xB177A388918E1p-40 53 0x1921FB54442D19p-53 2 0x1p4096 2 0x1p4096 U U
++ + 53 0x162E9BB80635D9p-40 53 0x1921FB54442D19p-53 2 0x1p8192 2 0x1p8192 U U
++ + 53 0x58B9BD6E00DF9p-37 53 0x1921FB54442D19p-53 2 0x1p16384 2 0x1p16384 U U
++ + 53 0xB172C969E9C75p-37 53 0x1921FB54442D19p-53 2 0x1p32768 2 0x1p32768 U U
++ + 53 0x162E4E161BB96Dp-37 53 0x1921FB54442D19p-53 2 0x1p65536 2 0x1p65536 U U
++ + 53 0xB172445457CD7p-35 2 0x1p0 2 0x1p131072 2 0x1p131072 U U
++ + 53 0x162E45C4C299CFp-35 2 0x1p0 2 0x1p262144 2 0x1p262144 U U
++ + 53 0x162E4461DE69DFp-34 2 0x1p0 2 0x1p524288 2 0x1p524288 U U
++ + 53 0x2C5C8760D8A3Dp-30 2 0x1p0 2 0x1p1048576 2 0x1p1048576 U U
++ + 53 0x58B90D5ECD17Bp-30 2 0x1p0 2 0x1p2097152 2 0x1p2097152 U U
++ + 53 0xB172195AB5FF7p-30 2 0x1p0 2 0x1p4194304 2 0x1p4194304 U U
++ + 53 0x162E4315287CEFp-30 2 0x1p0 2 0x1p8388608 2 0x1p8388608 U U
++ + 53 0x162E430A115B6Fp-29 2 0x1p0 2 0x1p16777216 2 0x1p16777216 U U
++ + 53 0x162E430485CAAFp-28 2 0x1p0 2 0x1p33554432 2 0x1p33554432 U U
++ + 53 0x162E4301C0025p-23 2 0x1p0 2 0x1p67108864 2 0x1p67108864 U U
++ + 53 0xB1721802E8F1p-21 2 0x1p0 2 0x1p134217728 2 0x1p134217728 U U
++ + 53 0x2C5C85FF57581p-22 2 0x1p0 2 0x1p268435456 2 0x1p268435456 U U
+
+# Example leading to intermediate overflow in x^2+y^2
++ + 53 0x58B90BFD4BCBFp-22 2 0x1p0 2 0x1p536870912 2 0x1p536870912 U U
++ + 53 0x58B90BFAA42A98p-25 2 0x1p0 2 0x3p1073741821 2 0x3p1073741821 U U
+# Example leading to intermediate underflow in x^2+y^2
+- - 53 -0x58B90BFB3775A8p-25 2 0x3p-2 2 0x1p-1073741824 2 0x1p-1073741824 D D
+
+# log (-1 + i*eps), looped in previous version
+- - 2 0 2 3 2 -1 2 0x1p-1073741813 N N
+- - 2 0 2 3 2 -1 2 0x1p-1073741813 D D
++ + 2 0x1p-1073741824 2 4 2 -1 2 0x1p-1073741813 U U
+# log(1 + i*eps), could cause similar problems
+- + 2 0 2 0x1p-1073741824 2 1 2 0x1p-1073741824 N N
+- - 2 0 2 0 2 1 2 0x1p-1073741824 D D
++ + 2 0x1p-1073741824 2 0x1p-1073741824 2 1 2 0x1p-1073741824 U U
+# log (eps + i)
+- - 2 0 2 0x3p-1 2 0x1p-1073741824 2 1 N N
+- - 2 0 2 0x3p-1 2 0x1p-1073741824 2 1 D D
++ + 2 0x1p-1073741824 2 2 2 0x1p-1073741824 2 1 U U
+
+# log (close to 1 + i*eps), improves test coverage
++ - 2 -0x1p-36 2 0x1p-1073741824 36 0x0.FFFFFFFFF 2 0x1p-1073741824 N N
diff --git a/mpc/tests/log10.dat b/mpc/tests/log10.dat
new file mode 100644
index 0000000000..9316c79f89
--- /dev/null
+++ b/mpc/tests/log10.dat
@@ -0,0 +1,179 @@
+# Data test file for mpc_log10.
+#
+# Copyright (C) 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+# See file sin.dat for the format description.
+
+# Special values, following ISO C99 standard, Annex G,
+# more precisely Section 7.26 "Future library directions"
+
+# Rule [conj]: log10(conj(z)) = conj(log10(z))
+
+# log10(nan + i*inf) = +inf + i*nan
+0 0 2 +inf 2 nan 2 nan 2 +inf N N
+0 0 2 +inf 2 nan 2 nan 2 -inf N N
+
+# log10(nan + i*nan) = nan + i*nan
+0 0 2 nan 2 nan 2 nan 2 nan N N
+
+# log10(nan + i*y) = nan + i*nan for finite y
+0 0 2 nan 2 nan 2 nan 2 1 N N
+0 0 2 nan 2 nan 2 nan 2 +0 N N
+0 0 2 nan 2 nan 2 nan 2 -0 N N
+0 0 2 nan 2 nan 2 nan 2 -1 N N
+
+# log10(+/-inf + i*nan) = +inf + i*nan
+0 0 2 +inf 2 nan 2 +inf 2 nan N N
+0 0 2 +inf 2 nan 2 -inf 2 nan N N
+
+# log10(x + i*nan) = nan+i*nan for finite x
+0 0 2 nan 2 nan 2 1 2 nan N N
+0 0 2 nan 2 nan 2 +0 2 nan N N
+0 0 2 nan 2 nan 2 -0 2 nan N N
+0 0 2 nan 2 nan 2 -1 2 nan N N
+
+# log10(x + i*inf) = +inf + i*pi/2/log(10) for finite x
+0 + 2 +inf 53 +0x15d47c4cb2fba1p-53 2 1 2 +inf N N
+0 + 2 +inf 53 +0x15d47c4cb2fba1p-53 2 +0 2 +inf N N
+0 + 2 +inf 53 +0x15d47c4cb2fba1p-53 2 -0 2 +inf N N
+0 + 2 +inf 53 +0x15d47c4cb2fba1p-53 2 -1 2 +inf N N
+# by [conj]: log10(x - i*inf) = +inf - i*pi/2/log(10) for finite x
+0 - 2 +inf 53 -0x15d47c4cb2fba1p-53 2 1 2 -inf N N
+0 - 2 +inf 53 -0x15d47c4cb2fba1p-53 2 +0 2 -inf N N
+0 - 2 +inf 53 -0x15d47c4cb2fba1p-53 2 -0 2 -inf N N
+0 - 2 +inf 53 -0x15d47c4cb2fba1p-53 2 -1 2 -inf N N
+
+# log10(-inf + i*y) = +inf + i*pi/log(10) for finite positive-signed y
+0 + 2 +inf 53 0x15d47c4cb2fba1p-52 2 -inf 2 1 N N
+0 + 2 +inf 53 0x15d47c4cb2fba1p-52 2 -inf 2 +0 N N
+# by [conj]: log10(-inf+i*y) = +inf - i*pi/log(10) for finite negative-signed y
+0 - 2 +inf 53 -0x15d47c4cb2fba1p-52 2 -inf 2 -1 N N
+0 - 2 +inf 53 -0x15d47c4cb2fba1p-52 2 -inf 2 -0 N N
+
+# log10(+inf + i*y) = +inf + i*0 for finite positive-signed y
+0 0 2 +inf 2 +0 2 +inf 2 1 N N
+0 0 2 +inf 2 +0 2 +inf 2 +0 N N
+# by [conj]: log10(+inf + i*y) = +inf - i*0 for finite negative-signed y
+0 0 2 +inf 2 -0 2 +inf 2 -1 N N
+0 0 2 +inf 2 -0 2 +inf 2 -0 N N
+
+# log10(-inf + i*inf) = +inf + i*(3*pi/4)/log(10)
+0 + 2 +inf 53 0x105f5d39863cb9p-52 2 -inf 2 +inf N N
+# by [conj]: log10(-inf - i*inf) = +inf - i*(3*pi/4)/log(10)
+0 - 2 +inf 53 -0x105f5d39863cb9p-52 2 -inf 2 -inf N N
+
+# log10(+inf + i*inf) = +inf + i*(pi/4)/log(10)
+0 + 2 +inf 53 0x15d47c4cb2fba1p-54 2 +inf 2 +inf N N
+# by [conj]: log10(+inf - i*inf) = +inf - i*(pi/4)/log(10)
+0 - 2 +inf 53 -0x15d47c4cb2fba1p-54 2 +inf 2 -inf N N
+
+# log10(-0 + i*0) = -inf + i*pi/log(10)
+0 + 2 -inf 53 +0x15d47c4cb2fba1p-52 2 -0 2 +0 N N
+0 - 2 -inf 53 -0x15d47c4cb2fba1p-52 2 -0 2 -0 N N
+0 + 2 -inf 53 +0x15d47c4cb2fba1p-52 2 -0 2 +0 N U
+0 + 2 -inf 53 -0xaea3e26597ddp-47 2 -0 2 -0 N U
+0 - 2 -inf 53 +0xaea3e26597ddp-47 2 -0 2 +0 N D
+0 - 2 -inf 53 -0x15d47c4cb2fba1p-52 2 -0 2 -0 N D
+
+# log10(+0 + i*0) = -inf + i*0
+0 0 2 -inf 2 +0 2 +0 2 +0 N N
+0 0 2 -inf 2 -0 2 +0 2 -0 N N
+
+# log10(+1 +- i*0) = +0 +- i*0
+0 0 2 +0 2 +0 2 1 2 +0 N N
+0 0 2 +0 2 -0 2 1 2 -0 N N
+
+# log10(10 +- i*0) = 1 +- i*0
+0 0 2 1 2 +0 4 10 2 +0 N N
+0 0 2 1 2 -0 4 10 2 -0 N N
+
+# log10(100 +- i*0) = 1 +- i*0
+0 0 2 2 2 +0 5 100 2 +0 N N
+0 0 2 2 2 -0 5 100 2 -0 N N
+
+# log10(-1 +- i*0) = +0 +- i*pi/log(10)
+0 + 2 +0 53 +0x15d47c4cb2fba1p-52 2 -1 2 +0 N N
+0 - 2 +0 53 -0x15d47c4cb2fba1p-52 2 -1 2 -0 N N
+
+# log10(x + i*y) with either x or y zero and the other non-zero
+- 0 53 0x13afeb354b7d97p-52 2 0 5 0x11 2 0 N N
+- + 53 0x13afeb354b7d97p-52 53 0x15d47c4cb2fba1p-53 2 0 5 0x11 N N
+- + 53 0x1475c655fbc11p-48 53 0x15d47c4cb2fba1p-52 5 -0x13 2 +0 N N
+- - 53 0x1475c655fbc11p-48 53 -0x15d47c4cb2fba1p-52 5 -0x13 2 -0 N N
+- - 53 0x1475c655fbc11p-48 53 -0x15d47c4cb2fba1p-53 2 0 5 -0x13 N N
+
+- + 53 0x15c9a3209bf97fp-52 53 0x15d47c4cb2fba1p-52 5 -0x17 2 +0 Z U
+- - 53 0x15c9a3209bf97fp-52 53 -0x15d47c4cb2fba1p-52 5 -0x17 2 -0 N D
++ - 53 0x2b93464137f3p-45 53 0xaea3e26597ddp-47 5 -0x17 2 +0 U Z
+- - 53 0x15c9a3209bf97fp-52 53 -0x15d47c4cb2fba1p-52 5 -0x17 2 -0 D N
+- - 53 0x1d1cda1a0c996dp-52 53 0xaea3e26597ddp-47 7 -0x42 2 +0 Z D
++ + 53 0xe8e6d0d064cb7p-51 53 -0xaea3e26597ddp-47 7 -0x42 2 -0 N Z
++ + 53 0xe8e6d0d064cb7p-51 53 0x15d47c4cb2fba1p-52 7 -0x42 2 +0 U N
+- + 53 0x1d1cda1a0c996dp-52 53 -0xaea3e26597ddp-47 7 -0x42 2 -0 D U
+
+# huge values
++ 0 53 0x134413509f79ffp-44 2 0 2 0x1p1024 2 +0 U U
++ 0 53 0x134413509f79ffp-43 2 0 2 0x1p2048 2 +0 U U
++ 0 53 0x134413509f79ffp-42 2 0 2 0x1p4096 2 +0 U U
++ 0 53 0x134413509f79ffp-41 2 0 2 0x1p8192 2 +0 U U
++ 0 53 0x134413509f79ffp-40 2 0 2 0x1p16384 2 +0 U U
++ 0 53 0x134413509f79ffp-39 2 0 2 0x1p32768 2 +0 U U
++ 0 53 0x134413509f79ffp-38 2 0 2 0x1p65536 2 +0 U U
++ 0 53 0x134413509f79ffp-37 2 0 2 0x1p131072 2 +0 U U
++ 0 53 0x134413509f79ffp-36 2 0 2 0x1p262144 2 +0 U U
++ 0 53 0x134413509f79ffp-35 2 0 2 0x1p524288 2 +0 U U
++ 0 53 0x134413509f79ffp-34 2 0 2 0x1p1048576 2 +0 U U
++ 0 53 0x134413509f79ffp-33 2 0 2 0x1p2097152 2 +0 U U
++ 0 53 0x134413509f79ffp-32 2 0 2 0x1p4194304 2 +0 U U
++ 0 53 0x134413509f79ffp-31 2 0 2 0x1p8388608 2 +0 U U
++ 0 53 0x134413509f79ffp-30 2 0 2 0x1p16777216 2 +0 U U
++ 0 53 0x134413509f79ffp-29 2 0 2 0x1p33554432 2 +0 U U
++ 0 53 0x134413509f79ffp-28 2 0 2 0x1p67108864 2 +0 U U
++ 0 53 0x134413509f79ffp-27 2 0 2 0x1p134217728 2 +0 U U
++ 0 53 0x134413509f79ffp-26 2 0 2 0x1p268435456 2 +0 U U
++ 0 53 0x134413509f79ffp-25 2 0 2 0x1p536870912 2 +0 U U
++ + 53 0x13467bd3098defp-44 53 0x15d47c4cb2fba1p-54 2 0x1p1024 2 0x1p1024 U U
++ + 53 0x13454791d483f7p-43 53 0x15d47c4cb2fba1p-54 2 0x1p2048 2 0x1p2048 U U
++ + 53 0x1344ad7139fefbp-42 53 0x15d47c4cb2fba1p-54 2 0x1p4096 2 0x1p4096 U U
++ + 53 0x13446060ecbc7dp-41 53 0x15d47c4cb2fba1p-54 2 0x1p8192 2 0x1p8192 U U
++ + 53 0x9a21cec630d9fp-39 53 0x15d47c4cb2fba1p-54 2 0x1p16384 2 0x1p16384 U U
++ + 53 0x13442694b2ca9fp-39 53 0x15d47c4cb2fba1p-54 2 0x1p32768 2 0x1p32768 U U
++ + 53 0x13441cf2a9224fp-38 53 0x15d47c4cb2fba1p-54 2 0x1p65536 2 0x1p65536 U U
++ + 53 0x13441821a44e27p-37 2 0x3p-3 2 0x1p131072 2 0x1p131072 U U
++ + 53 0x134415b921e413p-36 2 0x3p-3 2 0x1p262144 2 0x1p262144 U U
++ + 53 0x13441484e0af09p-35 2 0x3p-3 2 0x1p524288 2 0x1p524288 U U
++ + 53 0x4d104fab00521p-32 2 0x3p-3 2 0x1p1048576 2 0x1p1048576 U U
++ + 53 0x9a209ced7e3a1p-32 2 0x3p-3 2 0x1p2097152 2 0x1p2097152 U U
++ + 53 0x1344137727a0a1p-32 2 0x3p-3 2 0x1p4194304 2 0x1p4194304 U U
++ + 53 0x13441363e38d5p-27 2 0x3p-3 2 0x1p8388608 2 0x1p8388608 U U
++ + 53 0x268826b483075p-27 2 0x3p-3 2 0x1p16777216 2 0x1p16777216 U U
++ + 53 0x4d104d55c1fb5p-27 2 0x3p-3 2 0x1p33554432 2 0x1p33554432 U U
++ + 53 0x9a209a983fe35p-27 2 0x3p-3 2 0x1p67108864 2 0x1p67108864 U U
++ + 53 0x4d104d474eecdp-25 2 0x3p-3 2 0x1p134217728 2 0x1p134217728 U U
++ + 53 0x9a209a89ccd4dp-25 2 0x3p-3 2 0x1p268435456 2 0x1p268435456 U U
+# Due to intermediate overflow, the following result has wrong real part
+# instead of the correct result. Since this may happen in other parts of the
+# library as well, we do not consider it a bug for the moment.
+# + + 53 0x13441350ec8a4dp-25 2 0x3p-3 2 0x1p536870912 2 0x1p536870912 U U
+
+# log10(3+I) has an exact real part (from Joseph S. Myers)
+0 + 53 0.5 53 0x8f168ee8415e7p-54 2 3 2 1 N N
+
+# bug found by Mickael Gastineau on 29 Sep 2012
+0 + 2 +0 2 0.75 2 +0 2 1 N N
+0 - 2 +0 2 -0.75 2 +0 2 -1 N N
diff --git a/mpc/tests/mpc-tests.h b/mpc/tests/mpc-tests.h
new file mode 100644
index 0000000000..d1ce58690e
--- /dev/null
+++ b/mpc/tests/mpc-tests.h
@@ -0,0 +1,235 @@
+/* mpc-tests.h -- Tests helper functions.
+
+Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#ifndef __MPC_TESTS_H
+#define __MPC_TESTS_H
+
+#include "config.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "mpc.h"
+
+/* pieces copied from mpc-impl.h */
+#define MPC_PREC_RE(x) (mpfr_get_prec(mpc_realref(x)))
+#define MPC_PREC_IM(x) (mpfr_get_prec(mpc_imagref(x)))
+#define MPC_MAX_PREC(x) MPC_MAX(MPC_PREC_RE(x), MPC_PREC_IM(x))
+#define MPC_MAX(h,i) ((h) > (i) ? (h) : (i))
+
+#define MPC_ASSERT(expr) \
+ do { \
+ if (!(expr)) \
+ { \
+ fprintf (stderr, "%s:%d: MPC assertion failed: %s\n", \
+ __FILE__, __LINE__, #expr); \
+ abort(); \
+ } \
+ } while (0)
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+__MPC_DECLSPEC int mpc_mul_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_mul_karatsuba (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+__MPC_DECLSPEC int mpc_fma_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+#if defined (__cplusplus)
+}
+#endif
+/* end pieces copied from mpc-impl.h */
+
+#define MPC_OUT(x) \
+do { \
+ printf (#x "[%lu,%lu]=", (unsigned long int) MPC_PREC_RE (x), \
+ (unsigned long int) MPC_PREC_IM (x)); \
+ mpc_out_str (stdout, 2, 0, x, MPC_RNDNN); \
+ printf ("\n"); \
+} while (0)
+
+#define MPFR_OUT(x) \
+do { \
+ printf (#x "[%lu]=", (unsigned long int) mpfr_get_prec (x)); \
+ mpfr_out_str (stdout, 2, 0, x, GMP_RNDN); \
+ printf ("\n"); \
+} while (0)
+
+
+#define MPC_INEX_STR(inex) \
+ (inex) == 0 ? "(0, 0)" \
+ : (inex) == 1 ? "(+1, 0)" \
+ : (inex) == 2 ? "(-1, 0)" \
+ : (inex) == 4 ? "(0, +1)" \
+ : (inex) == 5 ? "(+1, +1)" \
+ : (inex) == 6 ? "(-1, +1)" \
+ : (inex) == 8 ? "(0, -1)" \
+ : (inex) == 9 ? "(+1, -1)" \
+ : (inex) == 10 ? "(-1, -1)" : "unknown"
+
+#define TEST_FAILED(func,op,got,expected,rnd) \
+ do { \
+ printf ("%s(op) failed [rnd=%d]\n with", func, rnd); \
+ MPC_OUT (op); \
+ printf (" "); \
+ MPC_OUT (got); \
+ MPC_OUT (expected); \
+ exit (1); \
+ } while (0)
+
+#define QUOTE(X) NAME(X)
+#define NAME(X) #X
+
+/** RANDOM FUNCTIONS **/
+/* the 3 following functions handle seed for random numbers. Usage:
+ - add test_start at the beginning of your test function
+ - use test_default_random (or use your random functions with
+ gmp_randstate_t rands) in your tests
+ - add test_end at the end the test function */
+extern gmp_randstate_t rands;
+
+extern void test_start (void);
+extern void test_end (void);
+extern void test_default_random (mpc_ptr, mp_exp_t, mp_exp_t, unsigned int, unsigned int);
+
+
+/** COMPARISON FUNCTIONS **/
+/* some sign are unspecified in ISO C99, thus we record in struct known_signs_t
+ whether the sign has to be checked */
+typedef struct
+{
+ int re; /* boolean value */
+ int im; /* boolean value */
+} known_signs_t;
+
+/* same_mpfr_value returns 1:
+ - if got and ref have the same value and known_sign is true,
+ or
+ - if they have the same absolute value, got = 0 or got = inf, and known_sign is
+ false.
+ returns 0 in other cases.
+ Unlike mpfr_cmp, same_mpfr_value(got, ref, x) return 1 when got and
+ ref are both NaNs. */
+extern int same_mpfr_value (mpfr_ptr got, mpfr_ptr ref, int known_sign);
+extern int same_mpc_value (mpc_ptr got, mpc_ptr ref, known_signs_t known_signs);
+
+
+/** GENERIC TESTS **/
+
+typedef int (*CC_func_ptr) (mpc_t, mpc_srcptr, mpc_rnd_t);
+typedef int (*C_CC_func_ptr) (mpc_t, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
+typedef int (*CCCC_func_ptr) (mpc_t, mpc_srcptr, mpc_srcptr, mpc_srcptr,
+ mpc_rnd_t);
+typedef int (*CCU_func_ptr) (mpc_t, mpc_srcptr, unsigned long, mpc_rnd_t);
+typedef int (*CCS_func_ptr) (mpc_t, mpc_srcptr, long, mpc_rnd_t);
+typedef int (*CCI_func_ptr) (mpc_t, mpc_srcptr, int, mpc_rnd_t);
+typedef int (*CCF_func_ptr) (mpc_t, mpc_srcptr, mpfr_srcptr, mpc_rnd_t);
+typedef int (*CFC_func_ptr) (mpc_t, mpfr_srcptr, mpc_srcptr, mpc_rnd_t);
+typedef int (*CUC_func_ptr) (mpc_t, unsigned long, mpc_srcptr, mpc_rnd_t);
+typedef int (*CUUC_func_ptr) (mpc_t, unsigned long, unsigned long, mpc_srcptr,
+ mpc_rnd_t);
+typedef int (*FC_func_ptr) (mpfr_t, mpc_srcptr, mpfr_rnd_t);
+typedef int (*CC_C_func_ptr) (mpc_t, mpc_t, mpc_srcptr, mpc_rnd_t, mpc_rnd_t);
+
+typedef union {
+ FC_func_ptr FC; /* output: mpfr_t, input: mpc_t */
+ CC_func_ptr CC; /* output: mpc_t, input: mpc_t */
+ C_CC_func_ptr C_CC; /* output: mpc_t, inputs: (mpc_t, mpc_t) */
+ CCCC_func_ptr CCCC; /* output: mpc_t, inputs: (mpc_t, mpc_t, mpc_t) */
+ CCU_func_ptr CCU; /* output: mpc_t, inputs: (mpc_t, unsigned long) */
+ CCS_func_ptr CCS; /* output: mpc_t, inputs: (mpc_t, long) */
+ CCI_func_ptr CCI; /* output: mpc_t, inputs: (mpc_t, int) */
+ CCF_func_ptr CCF; /* output: mpc_t, inputs: (mpc_t, mpfr_t) */
+ CFC_func_ptr CFC; /* output: mpc_t, inputs: (mpfr_t, mpc_t) */
+ CUC_func_ptr CUC; /* output: mpc_t, inputs: (unsigned long, mpc_t) */
+ CUUC_func_ptr CUUC; /* output: mpc_t, inputs: (ulong, ulong, mpc_t) */
+ CC_C_func_ptr CC_C; /* outputs: (mpc_t, mpc_t), input: mpc_t */
+} func_ptr;
+
+/* the rounding mode is implicit */
+typedef enum {
+ FC, /* output: mpfr_t, input: mpc_t */
+ CC, /* output: mpc_t, input: mpc_t */
+ C_CC, /* output: mpc_t, inputs: (mpc_t, mpc_t) */
+ CCCC, /* output: mpc_t, inputs: (mpc_t, mpc_t, mpc_t) */
+ CCU, /* output: mpc_t, inputs: (mpc_t, unsigned long) */
+ CCS, /* output: mpc_t, inputs: (mpc_t, long) */
+ CCI, /* output: mpc_t, inputs: (mpc_t, int) */
+ CCF, /* output: mpc_t, inputs: (mpc_t, mpfr_t) */
+ CFC, /* output: mpc_t, inputs: (mpfr_t, mpc_t) */
+ CUC, /* output: mpc_t, inputs: (unsigned long, mpc_t) */
+ CUUC, /* output: mpc_t, inputs: (ulong, ulong, mpc_t) */
+ CC_C /* outputs: (mpc_t, mpc_t), input: mpc_t */
+} func_type;
+
+/* properties */
+#define FUNC_PROP_NONE 0
+#define FUNC_PROP_SYMETRIC 1
+
+typedef struct
+{
+ func_ptr pointer;
+ func_type type;
+ const char * name;
+ int properties;
+} mpc_function;
+
+#define DECL_FUNC(_ftype, _fvar, _func) \
+ mpc_function _fvar; \
+ _fvar.pointer._ftype = _func; \
+ _fvar.type = _ftype; \
+ _fvar.name = QUOTE (_func); \
+ _fvar.properties = FUNC_PROP_NONE;
+
+
+/* tgeneric(mpc_function, prec_min, prec_max, step, exp_max) checks rounding
+ with random numbers:
+ - with precision ranging from prec_min to prec_max with an increment of
+ step,
+ - with exponent between -exp_max and exp_max.
+
+ It also checks parameter reuse (it is assumed here that either two mpc_t
+ variables are equal or they are different, in the sense that the real part of
+ one of them cannot be the imaginary part of the other). */
+void tgeneric (mpc_function, mpfr_prec_t, mpfr_prec_t, mpfr_prec_t, mp_exp_t);
+
+
+/** READ FILE WITH TEST DATA SET **/
+/* data_check (function, "data_file_name") checks function results against
+ precomputed data in a file.*/
+extern void data_check (mpc_function, const char *);
+
+extern FILE * open_data_file (const char *file_name);
+extern void close_data_file (FILE *fp);
+
+/* helper file reading functions */
+extern void skip_whitespace_comments (FILE *fp);
+extern void read_ternary (FILE *fp, int* ternary);
+extern void read_mpfr_rounding_mode (FILE *fp, mpfr_rnd_t* rnd);
+extern void read_mpc_rounding_mode (FILE *fp, mpc_rnd_t* rnd);
+extern mpfr_prec_t read_mpfr_prec (FILE *fp);
+extern void read_int (FILE *fp, int *n, const char *name);
+extern size_t read_string (FILE *fp, char **buffer_ptr, size_t buffer_length, const char *name);
+extern void read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign);
+extern void read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks);
+
+#define TERNARY_NOT_CHECKED 255
+ /* special value to indicate that the ternary value is not checked */
+#define TERNARY_ERROR 254
+ /* special value to indicate that an error occurred in an mpc function */
+
+#endif /* __MPC_TESTS_H */
diff --git a/mpc/tests/mul.dat b/mpc/tests/mul.dat
new file mode 100755
index 0000000000..13ea1e6ba5
--- /dev/null
+++ b/mpc/tests/mul.dat
@@ -0,0 +1,178 @@
+# Data file for mpc_mul
+#
+# Copyright (C) 2008, 2010, 2011, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP1_RE OP1_RE PREC_OP1_IM OP1_IM PREC_OP2_RE OP2_RE PREC_OP2_IM OP2_IM RND_RE RND_IM
+#
+# See add.dat for more details.
+
+# special values (following ISO C99 standard, G.5.1)
+0 0 53 nan 53 +inf 53 -inf 53 -inf 53 -inf 53 -inf N Z
+0 0 53 nan 53 +inf 53 -inf 53 +inf 53 +1 53 -inf Z U
+0 0 53 +inf 53 -inf 53 +inf 53 -inf 53 +inf 53 +0 U D
+0 0 53 +inf 53 -inf 53 +inf 53 +inf 53 -0 53 -1 D N
+0 0 53 -inf 53 +inf 53 -inf 53 -inf 53 -0 53 -1 N U
+0 0 53 -inf 53 +inf 53 -inf 53 +inf 53 +inf 53 nan Z D
+0 0 53 -inf 53 -inf 53 +inf 53 -inf 53 nan 53 -1 U N
+0 0 53 nan 53 nan 53 +inf 53 +inf 53 -0 53 nan D Z
+0 0 53 nan 53 nan 53 -inf 53 -inf 53 nan 53 nan N D
+
+0 0 53 -inf 53 -inf 53 -1 53 -inf 53 +inf 53 -1 N D
+0 0 53 -inf 53 nan 53 -inf 53 +1 53 +inf 53 -0 Z N
+0 0 53 +inf 53 nan 53 +1 53 -inf 53 -0 53 +1 U Z
+0 0 53 nan 53 nan 53 +inf 53 +1 53 -0 53 -0 D U
+0 0 53 nan 53 -inf 53 -1 53 -inf 53 +inf 53 nan N N
+0 0 53 nan 53 -inf 53 -inf 53 +1 53 nan 53 +1 Z Z
+0 0 53 nan 53 nan 53 +1 53 -inf 53 -0 53 nan U U
+0 0 53 nan 53 nan 53 +inf 53 +1 53 nan 53 nan D D
+
+0 0 53 +inf 53 nan 53 -0 53 -inf 53 +0 53 +inf D D
+0 0 53 -inf 53 nan 53 -inf 53 +0 53 +1 53 -0 N Z
+0 0 53 nan 53 nan 53 +0 53 -inf 53 -0 53 -0 Z U
+0 0 53 -inf 53 nan 53 +inf 53 +0 53 -inf 53 nan U D
+0 0 53 -inf 53 nan 53 -0 53 -inf 53 nan 53 -1 D N
+0 0 53 nan 53 nan 53 -inf 53 +0 53 +0 53 nan N U
+0 0 53 nan 53 nan 53 +0 53 -inf 53 nan 53 nan Z D
+
+0 0 53 +1 53 -0 53 +0 53 +1 53 -0 53 -1 Z D
+0 0 53 -0 53 +0 53 -1 53 -0 53 +0 53 -0 U N
+0 0 53 -inf 53 nan 53 -0 53 +1 53 nan 53 +inf D Z
+0 0 53 nan 53 nan 53 +1 53 -0 53 -1 53 nan N D
+0 0 53 nan 53 nan 53 +0 53 +1 53 nan 53 -0 Z N
+0 0 53 nan 53 nan 53 -1 53 -0 53 nan 53 nan U Z
+
+0 0 53 +0 53 +0 53 -0 53 +0 53 +0 53 -0 U Z
+0 0 53 nan 53 nan 53 +0 53 -0 53 nan 53 -inf D U
+0 0 53 nan 53 nan 53 +0 53 +0 53 -1 53 nan N N
+0 0 53 nan 53 nan 53 -0 53 -0 53 nan 53 -0 Z Z
+0 0 53 nan 53 nan 53 -0 53 +0 53 nan 53 nan U U
+
+0 0 53 +inf 53 nan 53 nan 53 -inf 53 nan 53 +inf U U
+0 0 53 -inf 53 nan 53 +inf 53 nan 53 -1 53 nan D D
+0 0 53 nan 53 nan 53 nan 53 -inf 53 nan 53 -0 N Z
+0 0 53 nan 53 nan 53 -inf 53 nan 53 nan 53 nan Z U
+
+0 0 53 nan 53 nan 53 +1 53 nan 53 nan 53 -1 Z U
+0 0 53 nan 53 nan 53 nan 53 +1 53 -0 53 nan U D
+0 0 53 nan 53 nan 53 -1 53 nan 53 nan 53 nan D N
+
+0 0 53 nan 53 nan 53 nan 53 +0 53 +0 53 nan D N
+0 0 53 nan 53 nan 53 +0 53 nan 53 nan 53 nan N U
+
+0 0 53 nan 53 nan 53 nan 53 nan 53 nan 53 nan N U
+
+# pure real arguments
+0 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-52 53 -0 N N
+0 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-52 53 -0 Z Z
+0 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-52 53 -0 U U
+0 0 53 -0x10000000000001p-52 53 -0 53 -1 53 -0 53 0x10000000000001p-52 53 -0 D D
+
+# one pure real argument
+0 0 53 0x10000000000001p-52 53 0x10000000000001p-52 53 +1 53 +1 53 0x10000000000001p-52 53 -0 N N
+0 0 53 0x10000000000001p-52 53 -0x10000000000001p-51 53 +1 53 -2 53 0x10000000000001p-52 53 -0 Z Z
+- + 53 -0x30000000000004p-52 53 0x30000000000004p-52 53 -3 53 +3 53 0x10000000000001p-52 53 +0 N N
++ - 53 -0x30000000000002p-52 53 0x30000000000002p-52 53 -3 53 +3 53 0x10000000000001p-52 53 +0 Z Z
++ + 53 -0x30000000000002p-52 53 0x30000000000004p-52 53 -3 53 +3 53 0x10000000000001p-52 53 +0 U U
+- - 53 -0x30000000000004p-52 53 0x30000000000002p-52 53 -3 53 +3 53 0x10000000000001p-52 53 +0 D D
+0 0 53 -0x10000000000001p-52 53 -0x10000000000001p-50 53 -1 53 -4 53 0x10000000000001p-52 53 +0 D D
+0 0 53 +0 53 +0 53 +0 53 +0 53 0x10000000000001p-52 53 -1 N N
+0 0 53 +0 53 -0 53 +0 53 -0 53 0x10000000000001p-52 53 -2 Z Z
+0 0 53 +0 53 +0 53 +0 53 +0 53 0x10000000000001p-52 53 +3 U U
+0 0 53 -0 53 -0 53 -0 53 -0 53 0x10000000000001p-52 53 +4 D D
+
+# pure imaginary arguments
+0 0 53 -0x10000000000001p-52 53 -0 53 -0 53 0x10000000000001p-52 53 -0 53 +1 N N
+0 0 53 -0x10000000000001p-52 53 +0 53 +0 53 0x10000000000001p-52 53 -0 53 +1 Z Z
+0 0 53 -0x10000000000001p-52 53 +0 53 +0 53 0x10000000000001p-52 53 -0 53 +1 U U
+0 0 53 -0x10000000000001p-52 53 -0 53 -0 53 0x10000000000001p-52 53 -0 53 +1 D D
+
+# one pure imaginary argument
+0 0 53 -0x10000000000001p-52 53 -0x10000000000001p-52 53 -0 53 0x10000000000001p-52 53 -1 53 +1 N N
+0 0 53 +0x10000000000001p-52 53 -0x10000000000001p-51 53 +0 53 0x10000000000001p-52 53 -2 53 -1 Z Z
++ - 53 0x30000000000004p-52 53 -0x30000000000004p-52 53 +0 53 0x10000000000001p-52 53 -3 53 -3 N N
+- + 53 0x30000000000002p-52 53 -0x30000000000002p-52 53 +0 53 0x10000000000001p-52 53 -3 53 -3 Z Z
++ + 53 0x30000000000004p-52 53 -0x30000000000002p-52 53 +0 53 0x10000000000001p-52 53 -3 53 -3 U U
+- - 53 0x30000000000002p-52 53 -0x30000000000004p-52 53 +0 53 0x10000000000001p-52 53 -3 53 -3 D D
+0 0 53 +0x10000000000001p-52 53 -0x10000000000001p-50 53 -0 53 0x10000000000001p-52 53 -4 53 -1 D D
+
+# big precision uses Karatsuba method
+0 0 4096 0x1420176785BD601FC018AD36471p-96 4096 -0x1ECCDBDA38B2611A32848E7ADF43p-100 53 0x6B2E363676587p-44 53 0x1AC20AAC49ED37p-47 53 0x12264C57B44C6Bp-53 53 -0x138639A4B8D8B3p-50 N N
+
+# Karatsuba case where x=0 since ad=bc: (1+i)^2 at artificially high
+# precision so that Karatsuba is actually used.
+0 0 4096 0 4096 2 4096 1 4096 1 4096 1 4096 1 N N
+# trigger the line reducing prec_x to prec_u
+0 0 4096 0 4096 2 40960 1 40960 1 40960 1 40960 1 N N
+# another particular cases
++ + 6 -0x9p-497 6 0x33p-315 6 -0x1dp-73 6 0x3p148 6 0x11p-463 6 0x3p-645 N N
++ - 6 0x33p-315 6 0x9p-497 6 0x3p148 6 0x1dp-73 6 0x11p-463 6 0x3p-645 N N
+0 0 4 0x1p-1902 4 0x3p-1085 4 -0x1p-892 4 -0x3p-75 4 -0x1p-1010 4 0 N N
+
+# a few particular values
+0 0 8 10 8 -5 8 4 8 3 8 1 8 -2 N N
++ + 27 0b1.10110000001100010010000000e-3 27 0b1.00111100000010100001011001e-1 27 0b1.11111011011000010101000000e-2 27 0b1.11010001010110111001110001e-3 27 0b1.10100101110110011011100100e-1 27 0b1.10111100011000001100110011e-1 N N
+0 0 15 2 15 0 15 -1 15 -1 15 -1 15 1 N N
+
+# check squares, copied from sqr.dat
++ - 53 0xfdbac097c8dc58p+2096 53 -0x7f6e5d4c3b2a2p+1036 53 -0xfedcba9876543p+1024 53 0x10000000000001p-42 53 -0xfedcba9876543p+1024 53 0x10000000000001p-42 U D
++ 0 30 309485009533114692573069312 30 18889465966662952943616 30 17592186044416 30 536870913 30 17592186044416 30 536870913 N N
+0 0 4 0 4 2 4 1 4 1 4 1 4 1 N N
++ + 8 0b1.1000111e-3 8 0b1.1100111e-3 27 0b1.11111011011000010101000000e-2 27 0b1.11010001010110111001110001e-3 27 0b1.11111011011000010101000000e-2 27 0b1.11010001010110111001110001e-3 N N
+? + 3464 inf 3464 inf 866 -0x2.5763c6519ef1510f8afa101a210b8030b1909cc17004db561a25d9b53e2c08c41c01e8bbac5af6299b9d8786030aa14943d841798c8c369287942e4d4cec42a60ab0922af931159805e631128e97f973754ad53972d5d320a651a3b4a667f0ef2b92dbd698d159c3642675140@192158913 866 -0xd.15f2d530934dd930d66e89d70762d2337a8f973dd6915eb6b532fd372fcc955df1d852632d4e46fe64154ceda991a1302caf1b0ec622497e3e5724dd05b1c89a06e28d7e18e8af58f5ff4c9998cb31714688867524f41e0b31e847c1bf40de5127f858069998efd7c3e599080@192158893 866 -0x2.5763c6519ef1510f8afa101a210b8030b1909cc17004db561a25d9b53e2c08c41c01e8bbac5af6299b9d8786030aa14943d841798c8c369287942e4d4cec42a60ab0922af931159805e631128e97f973754ad53972d5d320a651a3b4a667f0ef2b92dbd698d159c3642675140@192158913 866 -0xd.15f2d530934dd930d66e89d70762d2337a8f973dd6915eb6b532fd372fcc955df1d852632d4e46fe64154ceda991a1302caf1b0ec622497e3e5724dd05b1c89a06e28d7e18e8af58f5ff4c9998cb31714688867524f41e0b31e847c1bf40de5127f858069998efd7c3e599080@192158893 N N
+? + 2256 0 2256 -0 564 0xc.87999bfd1cb1a64288881e214b7cf1af979863b23c030b79c4a8bebb39177967608388a2e4df527977e7755a25df8af8f72fdd6dd2f42bd00de83088b4e9b59ce85caf2e6b0c0@-184298749 564 -0x2.5109af459d4daf357e09475ec991cdc9b02c8f7dfacdc060d2a24710d09c997f8aea6dbd46f10828c30b583fdcc90d7dcbb895689d594d3813db40784d2309e450d1fb6e38da8@-184298726 564 0xc.87999bfd1cb1a64288881e214b7cf1af979863b23c030b79c4a8bebb39177967608388a2e4df527977e7755a25df8af8f72fdd6dd2f42bd00de83088b4e9b59ce85caf2e6b0c0@-184298749 564 -0x2.5109af459d4daf357e09475ec991cdc9b02c8f7dfacdc060d2a24710d09c997f8aea6dbd46f10828c30b583fdcc90d7dcbb895689d594d3813db40784d2309e450d1fb6e38da8@-184298726 N N
+
+# intermediate over- and underflows
+- + 100 -inf 100 +inf 100 0x1@125000750 100 0x3@125000750 100 0x1@225000750 100 0x2@225000750 N N
+- + 100 -inf 100 +inf 100 0x1@225000750 100 0x2@225000750 100 0x1@125000750 100 0x3@125000750 N N
+- - 100 -inf 100 -inf 100 0x1@225000750 100 -0x2@225000750 100 0x1@125000750 100 -0x3@125000750 N N
++ - 100 -0 100 +0 100 0x1@-125000750 100 0x3@-125000750 100 0x1@-225000750 100 0x2@-225000750 N N
++ - 100 -0 100 +0 100 0x1@-225000750 100 0x2@-225000750 100 0x1@-125000750 100 0x3@-125000750 N N
+- - 100 +0 100 +0 100 0x3@-125000750 100 0x1@-125000750 100 0x1@-225000750 100 0x2@-225000750 N N
+- - 100 +0 100 +0 100 0x4@-125000750 100 0x1@-125000750 100 0x1@-225000750 100 0x2@-225000750 N N
++ - 100 -0 100 +0 100 0x2@-225000750 100 0x1@-225000750 100 0x1@-125000750 100 0x3@-125000750 N N
+0 - 100 +0 100 +0 100 0x1@-225000750 100 0x1@-225000750 100 0x1@-125000750 100 0x1@-125000750 N N
+0 + 100 +0 100 +inf 100 0x1@125000750 100 0x1@125000750 100 0x1@225000750 100 0x1@225000750 N N
++ 0 100 +inf 100 +0 100 0x1@125000750 100 0x1@125000750 100 0x1@225000750 100 -0x1@225000750 N N
+# the same with directed rounding
+- + 10 -inf 10 +inf 10 0x1@125000750 10 0x3@125000750 10 0x1@225000750 10 0x2@225000750 D U
++ - 10 -0b1.111111111e1073741822 10 0b1.111111111e1073741822 10 0x1@125000750 10 0x3@125000750 10 0x1@225000750 10 0x2@225000750 U D
++ - 10 -0 10 +0 10 0x1@-125000750 10 0x3@-125000750 10 0x1@-225000750 10 0x2@-225000750 U D
+- + 10 -0b1e-1073741824 10 0b1e-1073741824 10 0x1@-125000750 10 0x3@-125000750 10 0x1@-225000750 10 0x2@-225000750 D U
+# starting with Karatsuba
+- + 10000 -inf 100 +inf 100 0x1@125000750 100 0x3@125000750 100 0x1@225000750 100 0x2@225000750 N N
+- + 10000 -inf 100 +inf 100 0x1@225000750 100 0x2@225000750 100 0x1@125000750 100 0x3@125000750 N N
+- - 10000 -inf 100 -inf 100 0x1@225000750 100 -0x2@225000750 100 0x1@125000750 100 -0x3@125000750 N N
++ - 10000 -0 100 +0 100 0x1@-125000750 100 0x3@-125000750 100 0x1@-225000750 100 0x2@-225000750 N N
++ - 10000 -0 100 +0 100 0x1@-225000750 100 0x2@-225000750 100 0x1@-125000750 100 0x3@-125000750 N N
+- - 10000 +0 100 +0 100 0x3@-125000750 100 0x1@-125000750 100 0x1@-225000750 100 0x2@-225000750 N N
+- - 10000 +0 100 +0 100 0x4@-125000750 100 0x1@-125000750 100 0x1@-225000750 100 0x2@-225000750 N N
++ - 10000 -0 100 +0 100 0x2@-225000750 100 0x1@-225000750 100 0x1@-125000750 100 0x3@-125000750 N N
+0 - 10000 +0 100 +0 100 0x1@-225000750 100 0x1@-225000750 100 0x1@-125000750 100 0x1@-125000750 N N
+0 + 10000 +0 100 +inf 100 0x1@125000750 100 0x1@125000750 100 0x1@225000750 100 0x1@225000750 N N
++ 0 10000 +inf 100 +0 100 0x1@125000750 100 0x1@125000750 100 0x1@225000750 100 -0x1@225000750 N N
++ + 10000 +inf 100 +inf 100 0x1@125000750 100 0x3@125000750 100 0x1@143434706 100 0x2@143434705 N N
+
+# improve code coverage: case where sign_x==0 in mpc_mul_karatsuba
+0 0 2000 6 2000 8 2000 4 2000 2 2000 2 2000 1 N N
+0 0 2000 0 2000 4 2000 2 2000 2 2000 1 2000 1 N N
+
++ 0 2 1 2 0x2p-536870913 2 1 2 0x1p-536870913 2 1 2 0x1p-536870913 N N
+0 - 2 0 2 1 2 0x1p-536870913 2 1 2 1 2 0x1p-536870913 N N
diff --git a/mpc/tests/mul_fr.dat b/mpc/tests/mul_fr.dat
new file mode 100644
index 0000000000..e284093099
--- /dev/null
+++ b/mpc/tests/mul_fr.dat
@@ -0,0 +1,368 @@
+# Data file for mpc_mul_fr.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see add_fr.dat.
+
+# special values
+0 0 7 +inf 7 +inf 7 -inf 7 -inf 7 -inf N N
+0 0 7 +inf 7 +inf 7 -inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 +0 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -inf 7 nan N N
+0 0 7 +inf 7 +inf 7 -inf 7 -1 7 -inf N N
+0 0 7 +inf 7 1 7 -inf 7 -1 7 -1 N N
+0 0 7 nan 7 +0 7 -inf 7 -1 7 -0 N N
+0 0 7 nan 7 -0 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 -1 7 -inf 7 -1 7 1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -1 7 nan N N
+0 0 7 +inf 7 nan 7 -inf 7 -0 7 -inf N N
+0 0 7 +inf 7 +0 7 -inf 7 -0 7 -1 N N
+0 0 7 nan 7 +0 7 -inf 7 -0 7 -0 N N
+0 0 7 nan 7 -0 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 -0 7 -inf 7 -0 7 1 N N
+0 0 7 -inf 7 nan 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 -0 7 nan N N
+0 0 7 +inf 7 nan 7 -inf 7 +0 7 -inf N N
+0 0 7 +inf 7 -0 7 -inf 7 +0 7 -1 N N
+0 0 7 nan 7 -0 7 -inf 7 +0 7 -0 N N
+0 0 7 nan 7 +0 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 +0 7 -inf 7 +0 7 1 N N
+0 0 7 -inf 7 nan 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +0 7 nan N N
+0 0 7 +inf 7 -inf 7 -inf 7 1 7 -inf N N
+0 0 7 +inf 7 -1 7 -inf 7 1 7 -1 N N
+0 0 7 nan 7 -0 7 -inf 7 1 7 -0 N N
+0 0 7 nan 7 +0 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 1 7 -inf 7 1 7 1 N N
+0 0 7 -inf 7 +inf 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 1 7 nan N N
+0 0 7 +inf 7 -inf 7 -inf 7 +inf 7 -inf N N
+0 0 7 +inf 7 -inf 7 -inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 1 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 +inf 7 nan N N
+0 0 7 +inf 7 nan 7 -inf 7 nan 7 -inf N N
+0 0 7 +inf 7 nan 7 -inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 +0 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 1 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan N N
+0 0 7 +inf 7 +inf 7 -1 7 -inf 7 -inf N N
+0 0 7 1 7 +inf 7 -1 7 -inf 7 -1 N N
+0 0 7 +0 7 nan 7 -1 7 -inf 7 -0 N N
+0 0 7 -0 7 nan 7 -1 7 -inf 7 +0 N N
+0 0 7 -1 7 -inf 7 -1 7 -inf 7 1 N N
+0 0 7 -inf 7 -inf 7 -1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -inf 7 nan N N
+0 0 7 +inf 7 +inf 7 -1 7 -1 7 -inf N N
+0 0 7 -inf 7 -inf 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -1 7 nan N N
+0 0 7 +inf 7 nan 7 -1 7 -0 7 -inf N N
+0 0 7 -inf 7 nan 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 -0 7 nan N N
+0 0 7 +inf 7 nan 7 -1 7 +0 7 -inf N N
+0 0 7 -inf 7 nan 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +0 7 nan N N
+0 0 7 +inf 7 -inf 7 -1 7 1 7 -inf N N
+0 0 7 -inf 7 +inf 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 1 7 nan N N
+0 0 7 +inf 7 -inf 7 -1 7 +inf 7 -inf N N
+0 0 7 1 7 -inf 7 -1 7 +inf 7 -1 N N
+0 0 7 +0 7 nan 7 -1 7 +inf 7 -0 N N
+0 0 7 -0 7 nan 7 -1 7 +inf 7 +0 N N
+0 0 7 -1 7 +inf 7 -1 7 +inf 7 1 N N
+0 0 7 -inf 7 +inf 7 -1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 +inf 7 nan N N
+0 0 7 +inf 7 nan 7 -1 7 nan 7 -inf N N
+0 0 7 1 7 nan 7 -1 7 nan 7 -1 N N
+0 0 7 +0 7 nan 7 -1 7 nan 7 -0 N N
+0 0 7 -0 7 nan 7 -1 7 nan 7 +0 N N
+0 0 7 -1 7 nan 7 -1 7 nan 7 1 N N
+0 0 7 -inf 7 nan 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan N N
+0 0 7 nan 7 +inf 7 -0 7 -inf 7 -inf N N
+0 0 7 +0 7 +inf 7 -0 7 -inf 7 -1 N N
+0 0 7 +0 7 nan 7 -0 7 -inf 7 -0 N N
+0 0 7 -0 7 nan 7 -0 7 -inf 7 +0 N N
+0 0 7 -0 7 -inf 7 -0 7 -inf 7 1 N N
+0 0 7 nan 7 -inf 7 -0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -inf 7 nan N N
+0 0 7 nan 7 +inf 7 -0 7 -1 7 -inf N N
+0 0 7 nan 7 -inf 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +0 7 nan N N
+0 0 7 nan 7 -inf 7 -0 7 1 7 -inf N N
+0 0 7 nan 7 +inf 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 1 7 nan N N
+0 0 7 nan 7 -inf 7 -0 7 +inf 7 -inf N N
+0 0 7 +0 7 -inf 7 -0 7 +inf 7 -1 N N
+0 0 7 +0 7 nan 7 -0 7 +inf 7 -0 N N
+0 0 7 -0 7 nan 7 -0 7 +inf 7 +0 N N
+0 0 7 -0 7 +inf 7 -0 7 +inf 7 1 N N
+0 0 7 nan 7 +inf 7 -0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 -inf N N
+0 0 7 +0 7 nan 7 -0 7 nan 7 -1 N N
+0 0 7 +0 7 nan 7 -0 7 nan 7 -0 N N
+0 0 7 -0 7 nan 7 -0 7 nan 7 +0 N N
+0 0 7 -0 7 nan 7 -0 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan N N
+0 0 7 nan 7 +inf 7 +0 7 -inf 7 -inf N N
+0 0 7 -0 7 +inf 7 +0 7 -inf 7 -1 N N
+0 0 7 -0 7 nan 7 +0 7 -inf 7 -0 N N
+0 0 7 +0 7 nan 7 +0 7 -inf 7 +0 N N
+0 0 7 +0 7 -inf 7 +0 7 -inf 7 1 N N
+0 0 7 nan 7 -inf 7 +0 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -inf 7 nan N N
+0 0 7 nan 7 +inf 7 +0 7 -1 7 -inf N N
+0 0 7 nan 7 -inf 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 -inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +0 7 nan N N
+0 0 7 nan 7 -inf 7 +0 7 1 7 -inf N N
+0 0 7 nan 7 +inf 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 1 7 nan N N
+0 0 7 nan 7 -inf 7 +0 7 +inf 7 -inf N N
+0 0 7 -0 7 -inf 7 +0 7 +inf 7 -1 N N
+0 0 7 -0 7 nan 7 +0 7 +inf 7 -0 N N
+0 0 7 +0 7 nan 7 +0 7 +inf 7 +0 N N
+0 0 7 +0 7 +inf 7 +0 7 +inf 7 1 N N
+0 0 7 nan 7 +inf 7 +0 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 -inf N N
+0 0 7 -0 7 nan 7 +0 7 nan 7 -1 N N
+0 0 7 -0 7 nan 7 +0 7 nan 7 -0 N N
+0 0 7 +0 7 nan 7 +0 7 nan 7 +0 N N
+0 0 7 +0 7 nan 7 +0 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan N N
+0 0 7 -inf 7 +inf 7 1 7 -inf 7 -inf N N
+0 0 7 -1 7 +inf 7 1 7 -inf 7 -1 N N
+0 0 7 -0 7 nan 7 1 7 -inf 7 -0 N N
+0 0 7 +0 7 nan 7 1 7 -inf 7 +0 N N
+0 0 7 1 7 -inf 7 1 7 -inf 7 1 N N
+0 0 7 +inf 7 -inf 7 1 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -inf 7 nan N N
+0 0 7 -inf 7 +inf 7 1 7 -1 7 -inf N N
+0 0 7 +inf 7 -inf 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -1 7 nan N N
+0 0 7 -inf 7 nan 7 1 7 -0 7 -inf N N
+0 0 7 +inf 7 nan 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 -0 7 nan N N
+0 0 7 -inf 7 nan 7 1 7 +0 7 -inf N N
+0 0 7 +inf 7 nan 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +0 7 nan N N
+0 0 7 -inf 7 -inf 7 1 7 1 7 -inf N N
+0 0 7 +inf 7 +inf 7 1 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 1 7 nan N N
+0 0 7 -inf 7 -inf 7 1 7 +inf 7 -inf N N
+0 0 7 -1 7 -inf 7 1 7 +inf 7 -1 N N
+0 0 7 -0 7 nan 7 1 7 +inf 7 -0 N N
+0 0 7 +0 7 nan 7 1 7 +inf 7 +0 N N
+0 0 7 1 7 +inf 7 1 7 +inf 7 1 N N
+0 0 7 +inf 7 +inf 7 1 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 +inf 7 nan N N
+0 0 7 -inf 7 nan 7 1 7 nan 7 -inf N N
+0 0 7 -1 7 nan 7 1 7 nan 7 -1 N N
+0 0 7 -0 7 nan 7 1 7 nan 7 -0 N N
+0 0 7 +0 7 nan 7 1 7 nan 7 +0 N N
+0 0 7 1 7 nan 7 1 7 nan 7 1 N N
+0 0 7 +inf 7 nan 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan N N
+0 0 7 -inf 7 +inf 7 +inf 7 -inf 7 -inf N N
+0 0 7 -inf 7 +inf 7 +inf 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -inf 7 nan N N
+0 0 7 -inf 7 +inf 7 +inf 7 -1 7 -inf N N
+0 0 7 -inf 7 1 7 +inf 7 -1 7 -1 N N
+0 0 7 nan 7 +0 7 +inf 7 -1 7 -0 N N
+0 0 7 nan 7 -0 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 -1 7 +inf 7 -1 7 1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -1 7 nan N N
+0 0 7 -inf 7 nan 7 +inf 7 -0 7 -inf N N
+0 0 7 -inf 7 +0 7 +inf 7 -0 7 -1 N N
+0 0 7 nan 7 +0 7 +inf 7 -0 7 -0 N N
+0 0 7 nan 7 -0 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 -0 7 +inf 7 -0 7 1 N N
+0 0 7 +inf 7 nan 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 -0 7 nan N N
+0 0 7 -inf 7 nan 7 +inf 7 +0 7 -inf N N
+0 0 7 -inf 7 -0 7 +inf 7 +0 7 -1 N N
+0 0 7 nan 7 -0 7 +inf 7 +0 7 -0 N N
+0 0 7 nan 7 +0 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 +0 7 +inf 7 +0 7 1 N N
+0 0 7 +inf 7 nan 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +0 7 nan N N
+0 0 7 -inf 7 -inf 7 +inf 7 1 7 -inf N N
+0 0 7 -inf 7 -1 7 +inf 7 1 7 -1 N N
+0 0 7 nan 7 -0 7 +inf 7 1 7 -0 N N
+0 0 7 nan 7 +0 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 1 7 +inf 7 1 7 1 N N
+0 0 7 +inf 7 +inf 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 1 7 nan N N
+0 0 7 -inf 7 -inf 7 +inf 7 +inf 7 -inf N N
+0 0 7 -inf 7 -inf 7 +inf 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 +0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 1 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 +inf 7 nan N N
+0 0 7 -inf 7 nan 7 +inf 7 nan 7 -inf N N
+0 0 7 -inf 7 nan 7 +inf 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +0 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 1 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 +inf 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 +0 7 nan 7 -0 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 -0 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 -0 7 nan 7 +0 7 -1 N N
+0 0 7 nan 7 -0 7 nan 7 +0 7 -0 N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 -inf 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 -1 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 -0 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 +0 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 1 7 nan 7 1 7 1 N N
+0 0 7 nan 7 +inf 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 1 7 nan N N
+0 0 7 nan 7 -inf 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 -inf 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan N N
+
+# values with only 1, -1, +0, -0
+0 0 7 1 7 1 7 -1 7 -1 7 -1 N N
+0 0 7 +0 7 +0 7 -1 7 -1 7 -0 N N
+0 0 7 -0 7 -0 7 -1 7 -1 7 +0 N N
+0 0 7 -1 7 -1 7 -1 7 -1 7 1 N N
+0 0 7 1 7 +0 7 -1 7 -0 7 -1 N N
+0 0 7 +0 7 +0 7 -1 7 -0 7 -0 N N
+0 0 7 -0 7 -0 7 -1 7 -0 7 +0 N N
+0 0 7 -1 7 -0 7 -1 7 -0 7 1 N N
+0 0 7 1 7 -0 7 -1 7 +0 7 -1 N N
+0 0 7 +0 7 -0 7 -1 7 +0 7 -0 N N
+0 0 7 -0 7 +0 7 -1 7 +0 7 +0 N N
+0 0 7 -1 7 +0 7 -1 7 +0 7 1 N N
+0 0 7 1 7 -1 7 -1 7 1 7 -1 N N
+0 0 7 +0 7 -0 7 -1 7 1 7 -0 N N
+0 0 7 -0 7 +0 7 -1 7 1 7 +0 N N
+0 0 7 -1 7 1 7 -1 7 1 7 1 N N
+0 0 7 +0 7 1 7 -0 7 -1 7 -1 N N
+0 0 7 +0 7 +0 7 -0 7 -1 7 -0 N N
+0 0 7 -0 7 -0 7 -0 7 -1 7 +0 N N
+0 0 7 -0 7 -1 7 -0 7 -1 7 1 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -1 N N
+0 0 7 +0 7 +0 7 -0 7 -0 7 -0 N N
+0 0 7 -0 7 -0 7 -0 7 -0 7 +0 N N
+0 0 7 -0 7 -0 7 -0 7 -0 7 1 N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 +0 7 -0 N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 +0 N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 1 N N
+0 0 7 +0 7 -1 7 -0 7 1 7 -1 N N
+0 0 7 +0 7 -0 7 -0 7 1 7 -0 N N
+0 0 7 -0 7 +0 7 -0 7 1 7 +0 N N
+0 0 7 -0 7 1 7 -0 7 1 7 1 N N
+0 0 7 -0 7 1 7 +0 7 -1 7 -1 N N
+0 0 7 -0 7 +0 7 +0 7 -1 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 -1 7 +0 N N
+0 0 7 +0 7 -1 7 +0 7 -1 7 1 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -1 N N
+0 0 7 -0 7 +0 7 +0 7 -0 7 -0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 +0 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 1 N N
+0 0 7 -0 7 -0 7 +0 7 +0 7 -1 N N
+0 0 7 -0 7 -0 7 +0 7 +0 7 -0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 +0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 1 N N
+0 0 7 -0 7 -1 7 +0 7 1 7 -1 N N
+0 0 7 -0 7 -0 7 +0 7 1 7 -0 N N
+0 0 7 +0 7 +0 7 +0 7 1 7 +0 N N
+0 0 7 +0 7 1 7 +0 7 1 7 1 N N
+0 0 7 -1 7 1 7 1 7 -1 7 -1 N N
+0 0 7 -0 7 +0 7 1 7 -1 7 -0 N N
+0 0 7 +0 7 -0 7 1 7 -1 7 +0 N N
+0 0 7 1 7 -1 7 1 7 -1 7 1 N N
+0 0 7 -1 7 +0 7 1 7 -0 7 -1 N N
+0 0 7 -0 7 +0 7 1 7 -0 7 -0 N N
+0 0 7 +0 7 -0 7 1 7 -0 7 +0 N N
+0 0 7 1 7 -0 7 1 7 -0 7 1 N N
+0 0 7 -1 7 -0 7 1 7 +0 7 -1 N N
+0 0 7 -0 7 -0 7 1 7 +0 7 -0 N N
+0 0 7 +0 7 +0 7 1 7 +0 7 +0 N N
+0 0 7 1 7 +0 7 1 7 +0 7 1 N N
+0 0 7 -1 7 -1 7 1 7 1 7 -1 N N
+0 0 7 -0 7 -0 7 1 7 1 7 -0 N N
+0 0 7 +0 7 +0 7 1 7 1 7 +0 N N
+0 0 7 1 7 1 7 1 7 1 7 1 N N
+
diff --git a/mpc/tests/neg.dat b/mpc/tests/neg.dat
new file mode 100644
index 0000000000..0e036e6d9f
--- /dev/null
+++ b/mpc/tests/neg.dat
@@ -0,0 +1,109 @@
+# Data file for mpc_neg.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# see sin.dat for precisions
+
+# special values (following ISO C99 standard)
+0 0 53 +inf 53 +inf 53 -inf 53 -inf N N
+0 0 53 +inf 53 +1 53 -inf 53 -1 N N
+0 0 53 +inf 53 +0 53 -inf 53 -0 N N
+0 0 53 +inf 53 -0 53 -inf 53 +0 N N
+0 0 53 +inf 53 -1 53 -inf 53 +1 N N
+0 0 53 +inf 53 -inf 53 -inf 53 +inf N N
+0 0 53 +inf 53 nan 53 -inf 53 nan N N
+0 0 53 +1 53 +inf 53 -1 53 -inf N N
+0 0 53 +1 53 +0 53 -1 53 -0 N N
+0 0 53 +1 53 -0 53 -1 53 +0 N N
+0 0 53 +1 53 -inf 53 -1 53 +inf N N
+0 0 53 +1 53 nan 53 -1 53 nan N N
+0 0 53 +0 53 +inf 53 -0 53 -inf N N
+0 0 53 +0 53 +1 53 -0 53 -1 N N
+0 0 53 +0 53 +0 53 -0 53 -0 N N
+0 0 53 +0 53 -0 53 -0 53 +0 N N
+0 0 53 +0 53 -1 53 -0 53 +1 N N
+0 0 53 +0 53 -inf 53 -0 53 +inf N N
+0 0 53 +0 53 nan 53 -0 53 nan N N
+0 0 53 -0 53 +inf 53 +0 53 -inf N N
+0 0 53 -0 53 +1 53 +0 53 -1 N N
+0 0 53 -0 53 +0 53 +0 53 -0 N N
+0 0 53 -0 53 -0 53 +0 53 +0 N N
+0 0 53 -0 53 -1 53 +0 53 +1 N N
+0 0 53 -0 53 -inf 53 +0 53 +inf N N
+0 0 53 -0 53 nan 53 +0 53 nan N N
+0 0 53 -1 53 +inf 53 +1 53 -inf N N
+0 0 53 -1 53 +0 53 +1 53 -0 N N
+0 0 53 -1 53 -0 53 +1 53 +0 N N
+0 0 53 -1 53 -inf 53 +1 53 +inf N N
+0 0 53 -1 53 nan 53 +1 53 nan N N
+0 0 53 -inf 53 +inf 53 +inf 53 -inf N N
+0 0 53 -inf 53 +1 53 +inf 53 -1 N N
+0 0 53 -inf 53 +0 53 +inf 53 -0 N N
+0 0 53 -inf 53 -0 53 +inf 53 +0 N N
+0 0 53 -inf 53 -1 53 +inf 53 +1 N N
+0 0 53 -inf 53 -inf 53 +inf 53 +inf N N
+0 0 53 -inf 53 nan 53 +inf 53 nan N N
+0 0 53 nan 53 +inf 53 nan 53 -inf N N
+0 0 53 nan 53 +1 53 nan 53 -1 N N
+0 0 53 nan 53 +0 53 nan 53 -0 N N
+0 0 53 nan 53 -0 53 nan 53 +0 N N
+0 0 53 nan 53 -1 53 nan 53 +1 N N
+0 0 53 nan 53 -inf 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# pure real argument
+0 0 53 -0x123456789abcdep+52 2 -0 53 0x123456789abcdep+52 17 +0 N N
+0 0 53 0x123456789abcdep+52 3 -0 54 -0x123456789abcdep+52 16 +0 Z N
+0 0 53 -0x123456789abcdep+52 4 +0 55 0x123456789abcdep+52 15 -0 U N
+0 0 53 0x123456789abcdep+52 5 +0 56 -0x123456789abcdep+52 14 -0 D N
+0 0 53 -0x123456789abcdep+52 6 -0 57 0x123456789abcdep+52 13 +0 Z Z
+0 0 53 0x123456789abcdep+52 7 -0 58 -0x123456789abcdep+52 12 +0 U Z
+0 0 53 -0x123456789abcdep+52 8 +0 59 0x123456789abcdep+52 11 -0 D Z
+0 0 53 0x123456789abcdep+52 9 +0 60 -0x123456789abcdep+52 10 -0 N Z
+0 0 53 -0x123456789abcdep+52 10 -0 61 0x123456789abcdep+52 9 +0 U U
+0 0 53 0x123456789abcdep+52 11 -0 62 -0x123456789abcdep+52 8 +0 D U
+0 0 53 -0x123456789abcdep+52 12 +0 63 0x123456789abcdep+52 7 -0 N U
+0 0 53 0x123456789abcdep+52 13 +0 64 -0x123456789abcdep+52 6 -0 Z U
+0 0 53 -0x123456789abcdep+52 14 -0 65 0x123456789abcdep+52 5 +0 D D
+0 0 53 0x123456789abcdep+52 15 -0 66 -0x123456789abcdep+52 4 +0 N D
+0 0 53 -0x123456789abcdep+52 16 +0 67 0x123456789abcdep+52 3 -0 Z D
+0 0 53 0x123456789abcdep+52 17 +0 68 -0x123456789abcdep+52 2 -0 U D
+
+# pure imaginary argument
+0 0 53 -0 53 -0x123456789abcdep+52 53 +0 53 0x123456789abcdep+52 N N
+0 0 53 +0 53 -0x123456789abcdep+52 51 -0 54 0x123456789abcdep+52 Z N
+0 0 53 -0 53 0x123456789abcdep+52 49 +0 55 -0x123456789abcdep+52 U N
+0 0 53 +0 53 0x123456789abcdep+52 47 -0 56 -0x123456789abcdep+52 D N
+0 0 53 -0 53 -0x123456789abcdep+52 45 +0 57 0x123456789abcdep+52 Z Z
+0 0 53 +0 53 -0x123456789abcdep+52 43 -0 58 0x123456789abcdep+52 U Z
+0 0 53 -0 53 0x123456789abcdep+52 41 +0 59 -0x123456789abcdep+52 D Z
+0 0 53 +0 53 0x123456789abcdep+52 39 -0 60 -0x123456789abcdep+52 N Z
+0 0 53 -0 53 -0x123456789abcdep+52 37 +0 61 0x123456789abcdep+52 U U
+0 0 53 +0 53 -0x123456789abcdep+52 35 -0 62 0x123456789abcdep+52 D U
+0 0 53 -0 53 0x123456789abcdep+52 33 +0 63 -0x123456789abcdep+52 N U
+0 0 53 +0 53 0x123456789abcdep+52 31 -0 64 -0x123456789abcdep+52 Z U
+0 0 53 -0 53 -0x123456789abcdep+52 29 +0 65 0x123456789abcdep+52 D D
+0 0 53 +0 53 -0x123456789abcdep+52 27 -0 66 0x123456789abcdep+52 N D
+0 0 53 -0 53 0x123456789abcdep+52 25 +0 67 -0x123456789abcdep+52 Z D
+0 0 53 +0 53 0x123456789abcdep+52 23 -0 68 -0x123456789abcdep+52 U D
+
diff --git a/mpc/tests/norm.dat b/mpc/tests/norm.dat
new file mode 100644
index 0000000000..1a7e341cbe
--- /dev/null
+++ b/mpc/tests/norm.dat
@@ -0,0 +1,166 @@
+# Data file for mpc_norm.
+#
+# Copyright (C) 2008, 2010, 2011 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see abs.dat.
+
+# special values
+0 7 +inf 7 -inf 7 -inf N
+0 7 +inf 7 -inf 7 -1 N
+0 7 +inf 7 -inf 7 -0 N
+0 7 +inf 7 -inf 7 +0 N
+0 7 +inf 7 -inf 7 1 N
+0 7 +inf 7 -inf 7 +inf N
+0 7 +inf 7 -inf 7 nan N
+0 7 +inf 7 -1 7 -inf N
+0 7 +inf 7 -1 7 +inf N
+0 7 nan 7 -1 7 nan N
+0 7 +inf 7 -0 7 -inf N
+0 7 +inf 7 -0 7 +inf N
+0 7 nan 7 -0 7 nan N
+0 7 +inf 7 +0 7 -inf N
+0 7 +inf 7 +0 7 +inf N
+0 7 nan 7 +0 7 nan N
+0 7 +inf 7 1 7 -inf N
+0 7 +inf 7 1 7 +inf N
+0 7 nan 7 1 7 nan N
+0 7 +inf 7 +inf 7 -inf N
+0 7 +inf 7 +inf 7 -1 N
+0 7 +inf 7 +inf 7 -0 N
+0 7 +inf 7 +inf 7 +0 N
+0 7 +inf 7 +inf 7 1 N
+0 7 +inf 7 +inf 7 +inf N
+0 7 +inf 7 +inf 7 nan N
+0 7 +inf 7 nan 7 -inf N
+0 7 nan 7 nan 7 -1 N
+0 7 nan 7 nan 7 -0 N
+0 7 nan 7 nan 7 +0 N
+0 7 nan 7 nan 7 1 N
+0 7 +inf 7 nan 7 +inf N
+0 7 nan 7 nan 7 nan N
+
+# values with only 1, -1, +0, -0
+0 7 2 7 -1 7 -1 N
+0 7 1 7 -1 7 -0 N
+0 7 1 7 -1 7 +0 N
+0 7 2 7 -1 7 1 N
+0 7 1 7 -0 7 -1 N
+0 7 +0 7 -0 7 -0 N
+0 7 +0 7 -0 7 +0 N
+0 7 1 7 -0 7 1 N
+0 7 1 7 +0 7 -1 N
+0 7 +0 7 +0 7 -0 N
+0 7 +0 7 +0 7 +0 N
+0 7 1 7 +0 7 1 N
+0 7 2 7 1 7 -1 N
+0 7 1 7 1 7 -0 N
+0 7 1 7 1 7 +0 N
+0 7 2 7 1 7 1 N
+
+# overflow
++ 53 +inf 2 0x1p536870912 2 0x1p536870912 U
+
+# infinite loop reported by E. Thome
+- 250 +0 250 -0xf.fdda3457c3e69e5841461d505b42987feb42867a4a2d2872179c4efa20054c0@-136943039 250 -0xc.670d1beda685fdd771b6246e32ff49ec4fd70aec25367444e00933e6965d3c0@-136943040 N
+
+# inexact values: norm (2+i)=5, in the middle between two values at precision 2
+- 2 4 2 2 2 1 D
+- 2 4 2 2 2 1 Z
++ 2 6 2 2 2 1 U
+- 2 4 2 2 2 1 N
+
+# over- and underflows
++ 10 inf 10 0 10 0b1@536870912 N
++ 10 inf 10 0 10 0b1@536870912 U
+- 10 0b1.111111111@1073741822 10 0 10 0b1@536870912 D
+- 10 0b1.111111111@1073741822 10 0 10 0b1@536870912 Z
+- 10 0 10 0 10 0b1@-536870913 N
+- 10 0 10 0 10 0b1@-536870913 D
+- 10 0 10 0 10 0b1@-536870913 Z
++ 10 0b1.000000000e-1073741824 10 0 10 0b1@-536870913 U
+
++ 10 inf 10 0b1@536870912 10 0 N
++ 10 inf 10 0b1@536870912 10 0 U
+- 10 0b1.111111111@1073741822 10 0b1@536870912 10 0 D
+- 10 0b1.111111111@1073741822 10 0b1@536870912 10 0 Z
+- 10 0 10 0b1@-536870913 10 0 N
+- 10 0 10 0b1@-536870913 10 0 D
+- 10 0 10 0b1@-536870913 10 0 Z
++ 10 0b1.000000000e-1073741824 10 0b1@-536870913 10 0 U
+
++ 10 inf 10 1 10 0b1@536870912 N
++ 10 inf 10 1 10 0b1@536870912 U
+- 10 0b1.111111111@1073741822 10 1 10 0b1@536870912 D
+- 10 0b1.111111111@1073741822 10 1 10 0b1@536870912 Z
+- 10 1 10 1 10 0b1@-536870913 N
+- 10 1 10 1 10 0b1@-536870913 D
+- 10 1 10 1 10 0b1@-536870913 Z
++ 10 0b1.000000001 10 1 10 0b1@-536870913 U
+
++ 10 inf 10 0b1@536870912 10 1 N
++ 10 inf 10 0b1@536870912 10 1 U
+- 10 0b1.111111111@1073741822 10 0b1@536870912 10 1 D
+- 10 0b1.111111111@1073741822 10 0b1@536870912 10 1 Z
+- 10 1 10 0b1@-536870913 10 1 N
+- 10 1 10 0b1@-536870913 10 1 D
+- 10 1 10 0b1@-536870913 10 1 Z
++ 10 0b1.000000001 10 0b1@-536870913 10 1 U
+
++ 3 inf 10 0b1.1 10 0b1@536870912 N
++ 3 inf 10 0b1.1 10 0b1@536870912 U
+- 3 0b1.11@1073741822 10 0b1.1 10 0b1@536870912 D
+- 3 0b1.11@1073741822 10 0b1.1 10 0b1@536870912 Z
++ 3 2.5 10 0b1.1 10 0b1@-536870913 N
+- 3 2 10 0b1.1 10 0b1@-536870913 D
+- 3 2 10 0b1.1 10 0b1@-536870913 Z
++ 3 0b1.01@1 10 0b1.1 10 0b1@-536870913 U
+
++ 3 inf 10 0b1@536870912 10 0b1.1 N
++ 3 inf 10 0b1@536870912 10 0b1.1 U
+- 3 0b1.11@1073741822 10 0b1@536870912 10 0b1.1 D
+- 3 0b1.11@1073741822 10 0b1@536870912 10 0b1.1 Z
++ 3 2.5 10 0b1@-536870913 10 0b1.1 N
+- 3 2 10 0b1@-536870913 10 0b1.1 D
+- 3 2 10 0b1@-536870913 10 0b1.1 Z
++ 3 0b1.01@1 10 0b1@-536870913 10 0b1.1 U
+
++ 10 inf 10 0b1@-536870913 10 0b1@536870912 N
++ 10 inf 10 0b1@-536870913 10 0b1@536870912 U
+- 10 0b1.111111111@1073741822 10 0b1@-536870913 10 0b1@536870912 D
+- 10 0b1.111111111@1073741822 10 0b1@-536870912 10 0b1@536870912 Z
++ 10 inf 10 0b1@536870912 10 0b1@-536870913 N
++ 10 inf 10 0b1@536870912 10 0b1@-536870913 U
+- 10 0b1.111111111@1073741822 10 0b1@536870912 10 0b1@-536870913 D
+- 10 0b1.111111111@1073741822 10 0b1@536870912 10 0b1@-536870913 Z
++ 10 inf 10 0b1@536870912 10 0b1@536870912 N
++ 10 inf 10 0b1@536870912 10 0b1@536870912 U
+- 10 0b1.111111111@1073741822 10 0b1@536870912 10 0b1@536870912 D
+- 10 0b1.111111111@1073741822 10 0b1@536870912 10 0b1@536870912 Z
+- 10 0 10 0b1@-536870913 10 0b1@-536870913 N
+- 10 0 10 0b1@-536870913 10 0b1@-536870913 D
+- 10 0 10 0b1@-536870913 10 0b1@-536870913 Z
++ 10 0b1@-1073741824 10 0b1@-536870913 10 0b1@-536870913 U
+
+0 18 0b1.00100000000001001@-1073741811 2 0b1.1@-536870906 2 0b1.1@-536870913 N
+0 18 0b1.00100000000001001@-1073741811 2 0b1.1@-536870913 2 0b1.1@-536870906 N
+0 18 0b1.00100000000001001@-1073741811 2 0b1.1@-536870906 2 0b1.1@-536870913 Z
+0 18 0b1.00100000000001001@-1073741811 2 0b1.1@-536870913 2 0b1.1@-536870906 Z
+0 18 0b1.00100000000001001@-1073741811 2 0b1.1@-536870906 2 0b1.1@-536870913 D
+0 18 0b1.00100000000001001@-1073741811 2 0b1.1@-536870913 2 0b1.1@-536870906 D
+0 18 0b1.00100000000001001@-1073741811 2 0b1.1@-536870906 2 0b1.1@-536870913 U
+0 18 0b1.00100000000001001@-1073741811 2 0b1.1@-536870913 2 0b1.1@-536870906 U
diff --git a/mpc/tests/pow.dat b/mpc/tests/pow.dat
new file mode 100644
index 0000000000..1105f5987c
--- /dev/null
+++ b/mpc/tests/pow.dat
@@ -0,0 +1,469 @@
+# Data file for mpc_pow.
+#
+# Copyright (C) 2009, 2011, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see add.dat.
+
+0 0 53 +1 53 0 53 nan 53 +0 53 +0 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 +0 53 +1 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 +0 53 -1 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 +1 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 +1 53 +1 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 -1 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 +inf 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 +inf 53 +1 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 +inf 53 -1 N N
+0 0 53 nan 53 nan 53 nan 53 +0 53 -inf 53 +0 N N
+0 0 53 nan 53 nan 53 +inf 53 +0 53 +0 53 +1 N N
+0 0 53 nan 53 nan 53 +inf 53 +0 53 +0 53 -1 N N
+0 0 53 inf 53 nan 53 +inf 53 +0 53 +1 53 +0 N N
+0 0 53 +inf 53 nan 53 +inf 53 +0 53 +1 53 +1 N N
+0 0 53 +inf 53 nan 53 +inf 53 +0 53 +1 53 -1 N N
+0 0 53 0 53 0 53 +inf 53 +0 53 -1 53 +0 N N
+0 0 53 0 53 0 53 +inf 53 +0 53 -1 53 +1 N N
+0 0 53 0 53 0 53 +inf 53 +0 53 -1 53 -1 N N
+0 0 53 nan 53 nan 53 +inf 53 +0 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 +inf 53 +0 53 nan 53 +1 N N
+0 0 53 nan 53 nan 53 +inf 53 +0 53 nan 53 -1 N N
+0 0 53 +inf 53 nan 53 +inf 53 +0 53 +inf 53 +0 N N
+0 0 53 +inf 53 nan 53 +inf 53 +0 53 +inf 53 +1 N N
+0 0 53 +inf 53 nan 53 +inf 53 +0 53 +inf 53 -1 N N
+0 0 53 0 53 0 53 +inf 53 +0 53 -inf 53 +0 N N
+0 0 53 0 53 0 53 +inf 53 +0 53 -inf 53 +1 N N
+0 0 53 0 53 0 53 +inf 53 +0 53 -inf 53 -1 N N
+0 0 53 nan 53 nan 53 +inf 53 +1 53 +0 53 +1 N N
+0 0 53 nan 53 nan 53 +inf 53 +1 53 +0 53 -1 N N
+0 0 53 +inf 53 nan 53 +inf 53 +1 53 +1 53 +0 N N
+0 0 53 +inf 53 nan 53 +inf 53 +1 53 +1 53 +1 N N
+0 0 53 +inf 53 nan 53 +inf 53 +1 53 +1 53 -1 N N
+0 0 53 0 53 0 53 +inf 53 +1 53 -1 53 +0 N N
+0 0 53 0 53 0 53 +inf 53 +1 53 -1 53 +1 N N
+0 0 53 0 53 0 53 +inf 53 +1 53 -1 53 -1 N N
+0 0 53 nan 53 nan 53 +inf 53 +1 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 +inf 53 +1 53 nan 53 +1 N N
+0 0 53 nan 53 nan 53 +inf 53 +1 53 nan 53 -1 N N
+0 0 53 +inf 53 nan 53 +inf 53 +1 53 +inf 53 +0 N N
+0 0 53 +inf 53 nan 53 +inf 53 +1 53 +inf 53 +1 N N
+0 0 53 +inf 53 nan 53 +inf 53 +1 53 +inf 53 -1 N N
+0 0 53 0 53 0 53 +inf 53 +1 53 -inf 53 +0 N N
+0 0 53 0 53 0 53 +inf 53 +1 53 -inf 53 +1 N N
+0 0 53 0 53 0 53 +inf 53 +1 53 -inf 53 -1 N N
+0 0 53 nan 53 nan 53 +inf 53 -1 53 +0 53 +1 N N
+0 0 53 nan 53 nan 53 +inf 53 -1 53 +0 53 -1 N N
+0 0 53 +inf 53 nan 53 +inf 53 -1 53 +1 53 +0 N N
+0 0 53 +inf 53 nan 53 +inf 53 -1 53 +1 53 +1 N N
+0 0 53 +inf 53 nan 53 +inf 53 -1 53 +1 53 -1 N N
+0 0 53 0 53 0 53 +inf 53 -1 53 -1 53 +0 N N
+0 0 53 0 53 0 53 +inf 53 -1 53 -1 53 +1 N N
+0 0 53 0 53 0 53 +inf 53 -1 53 -1 53 -1 N N
+0 0 53 nan 53 nan 53 +inf 53 -1 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 +inf 53 -1 53 nan 53 +1 N N
+0 0 53 nan 53 nan 53 +inf 53 -1 53 nan 53 -1 N N
+0 0 53 +inf 53 nan 53 +inf 53 -1 53 +inf 53 +0 N N
+0 0 53 +inf 53 nan 53 +inf 53 -1 53 +inf 53 +1 N N
+0 0 53 +inf 53 nan 53 +inf 53 -1 53 +inf 53 -1 N N
+0 0 53 0 53 0 53 +inf 53 -1 53 -inf 53 +0 N N
+0 0 53 0 53 0 53 +inf 53 -1 53 -inf 53 +1 N N
+0 0 53 0 53 0 53 +inf 53 -1 53 -inf 53 -1 N N
+0 0 53 nan 53 nan 53 -inf 53 +0 53 +0 53 +1 N N
+0 0 53 nan 53 nan 53 -inf 53 +0 53 +0 53 -1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +0 53 +1 53 +0 N N
+0 0 53 +inf 53 nan 53 -inf 53 +0 53 +1 53 +1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +0 53 +1 53 -1 N N
+0 0 53 0 53 0 53 -inf 53 +0 53 -1 53 +0 N N
+0 0 53 0 53 0 53 -inf 53 +0 53 -1 53 +1 N N
+0 0 53 0 53 0 53 -inf 53 +0 53 -1 53 -1 N N
+0 0 53 nan 53 nan 53 -inf 53 +0 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 -inf 53 +0 53 nan 53 +1 N N
+0 0 53 nan 53 nan 53 -inf 53 +0 53 nan 53 -1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +0 53 +inf 53 +0 N N
+0 0 53 +inf 53 nan 53 -inf 53 +0 53 +inf 53 +1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +0 53 +inf 53 -1 N N
+0 0 53 0 53 0 53 -inf 53 +0 53 -inf 53 +0 N N
+0 0 53 0 53 0 53 -inf 53 +0 53 -inf 53 +1 N N
+0 0 53 0 53 0 53 -inf 53 +0 53 -inf 53 -1 N N
+0 0 53 nan 53 nan 53 -inf 53 +1 53 +0 53 +1 N N
+0 0 53 nan 53 nan 53 -inf 53 +1 53 +0 53 -1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +1 53 +1 53 +0 N N
+0 0 53 +inf 53 nan 53 -inf 53 +1 53 +1 53 +1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +1 53 +1 53 -1 N N
+0 0 53 0 53 0 53 -inf 53 +1 53 -1 53 +0 N N
+0 0 53 0 53 0 53 -inf 53 +1 53 -1 53 +1 N N
+0 0 53 0 53 0 53 -inf 53 +1 53 -1 53 -1 N N
+0 0 53 nan 53 nan 53 -inf 53 +1 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 -inf 53 +1 53 nan 53 +1 N N
+0 0 53 nan 53 nan 53 -inf 53 +1 53 nan 53 -1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +1 53 +inf 53 +0 N N
+0 0 53 +inf 53 nan 53 -inf 53 +1 53 +inf 53 +1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +1 53 +inf 53 -1 N N
+0 0 53 0 53 0 53 -inf 53 +1 53 -inf 53 +0 N N
+0 0 53 0 53 0 53 -inf 53 +1 53 -inf 53 +1 N N
+0 0 53 0 53 0 53 -inf 53 +1 53 -inf 53 -1 N N
+0 0 53 nan 53 nan 53 -inf 53 -1 53 +0 53 +1 N N
+0 0 53 nan 53 nan 53 -inf 53 -1 53 +0 53 -1 N N
+0 0 53 +inf 53 nan 53 -inf 53 -1 53 +1 53 +0 N N
+0 0 53 +inf 53 nan 53 -inf 53 -1 53 +1 53 +1 N N
+0 0 53 +inf 53 nan 53 -inf 53 -1 53 +1 53 -1 N N
+0 0 53 0 53 0 53 -inf 53 -1 53 -1 53 +0 N N
+0 0 53 0 53 0 53 -inf 53 -1 53 -1 53 +1 N N
+0 0 53 0 53 0 53 -inf 53 -1 53 -1 53 -1 N N
+0 0 53 nan 53 nan 53 -inf 53 -1 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 -inf 53 -1 53 nan 53 +1 N N
+0 0 53 nan 53 nan 53 -inf 53 -1 53 nan 53 -1 N N
+0 0 53 +inf 53 nan 53 -inf 53 -1 53 +inf 53 +0 N N
+0 0 53 +inf 53 nan 53 -inf 53 -1 53 +inf 53 +1 N N
+0 0 53 +inf 53 nan 53 -inf 53 -1 53 +inf 53 -1 N N
+0 0 53 0 53 0 53 -inf 53 -1 53 -inf 53 +0 N N
+0 0 53 0 53 0 53 -inf 53 -1 53 -inf 53 +1 N N
+0 0 53 0 53 0 53 -inf 53 -1 53 -inf 53 -1 N N
+
+0 0 53 1 53 +0 53 +0 53 +0 53 +0 53 +0 N N
+0 0 53 1 53 +0 53 +0 53 +0 53 -0 53 +0 N N
+0 0 53 1 53 +0 53 +0 53 -0 53 +0 53 +0 N N
+0 0 53 1 53 +0 53 +0 53 -0 53 -0 53 +0 N N
+0 0 53 1 53 +0 53 -0 53 +0 53 +0 53 +0 N N
+0 0 53 1 53 +0 53 -0 53 +0 53 -0 53 +0 N N
+0 0 53 1 53 +0 53 -0 53 -0 53 +0 53 +0 N N
+0 0 53 1 53 +0 53 -0 53 -0 53 -0 53 +0 N N
+0 0 53 1 53 +0 53 +0 53 +0 53 +0 53 -0 N N
+0 0 53 1 53 +0 53 +0 53 +0 53 -0 53 -0 N N
+0 0 53 1 53 +0 53 +0 53 -0 53 +0 53 -0 N N
+0 0 53 1 53 +0 53 +0 53 -0 53 -0 53 -0 N N
+0 0 53 1 53 +0 53 -0 53 +0 53 +0 53 -0 N N
+0 0 53 1 53 +0 53 -0 53 +0 53 -0 53 -0 N N
+0 0 53 1 53 +0 53 -0 53 -0 53 +0 53 -0 N N
+0 0 53 1 53 +0 53 -0 53 -0 53 -0 53 -0 N N
+0 0 53 nan 53 nan 53 +0 53 +0 53 +0 53 +1 N N
+0 0 53 nan 53 nan 53 +0 53 +0 53 +0 53 -1 N N
+0 0 53 0 53 0 53 +0 53 +0 53 +1 53 +0 N N
+0 0 53 0 53 0 53 +0 53 +0 53 +1 53 +1 N N
+0 0 53 0 53 0 53 +0 53 +0 53 +1 53 -1 N N
+0 0 53 +inf 53 nan 53 +0 53 +0 53 -1 53 +0 N N
+0 0 53 +inf 53 nan 53 +0 53 +0 53 -1 53 +1 N N
+0 0 53 +inf 53 nan 53 +0 53 +0 53 -1 53 -1 N N
+0 0 53 nan 53 nan 53 +0 53 +0 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 +0 53 +0 53 nan 53 +1 N N
+0 0 53 nan 53 nan 53 +0 53 +0 53 nan 53 -1 N N
+0 0 53 0 53 0 53 +0 53 +0 53 +inf 53 +0 N N
+0 0 53 0 53 0 53 +0 53 +0 53 +inf 53 +1 N N
+0 0 53 0 53 0 53 +0 53 +0 53 +inf 53 -1 N N
+0 0 53 +inf 53 nan 53 +0 53 +0 53 -inf 53 +0 N N
+0 0 53 +inf 53 nan 53 +0 53 +0 53 -inf 53 +1 N N
+0 0 53 +inf 53 nan 53 +0 53 +0 53 -inf 53 -1 N N
+
+# zeros with determined sign, see algorithms.tex
+# x^0 = +1 +sign(Im(x))*sign(Re(y))*0i when |x|=1
+0 0 53 +1 53 +0 53 +0 53 +1 53 +0 53 +0 N N
+0 0 53 +1 53 -0 53 +0 53 +1 53 +0 53 +0 N D #round toward -oo
+0 0 53 +1 53 +0 53 -0 53 +1 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 -1 53 +0 53 +0 53 +0 N N
+0 0 53 +1 53 -0 53 -1 53 -0 53 +0 53 +0 N N
+0 0 53 +1 53 -0 53 -0 53 -1 53 +0 53 +0 N N
+0 0 53 +1 53 -0 53 +0 53 -1 53 +0 53 +0 N N
+
+0 0 53 +1 53 +0 53 +0 53 +1 53 +0 53 -0 N N
+0 0 53 +1 53 +0 53 -0 53 +1 53 +0 53 -0 N N
+0 0 53 +1 53 +0 53 -1 53 +0 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 -1 53 -0 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 -0 53 -1 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 +0 53 -1 53 +0 53 -0 N N
+
+0 0 53 +1 53 -0 53 +0 53 +1 53 -0 53 +0 N N
+0 0 53 +1 53 -0 53 -0 53 +1 53 -0 53 +0 N N
+0 0 53 +1 53 -0 53 -1 53 +0 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 -1 53 -0 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 -0 53 -1 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 +0 53 -1 53 -0 53 +0 N N
+
+0 0 53 +1 53 -0 53 +0 53 +1 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 -0 53 +1 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 -1 53 +0 53 -0 53 -0 N N
+0 0 53 +1 53 +0 53 -1 53 -0 53 -0 53 -0 N N
+0 0 53 +1 53 +0 53 -0 53 -1 53 -0 53 -0 N N
+0 0 53 +1 53 +0 53 +0 53 -1 53 -0 53 -0 N N
+
+# x^0 = +1 +sign(Im(y))*0i when |x| > 1
+0 0 53 +1 53 +0 53 +inf 53 +2 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 +inf 53 -0 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 +2 53 +inf 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 +2 53 +0 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 +0 53 +2 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 +0 53 +inf 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 -0 53 +2 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 -0 53 +inf 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 -5 53 +inf 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 -2 53 +0 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 -inf 53 +0 53 +0 53 +0 N N
+0 0 53 +1 53 +0 53 -inf 53 +3 53 +0 53 +0 N N
+
+0 0 53 +1 53 -0 53 +inf 53 -inf 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 +inf 53 +0 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 +inf 53 -2 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 +2 53 -5 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 +5 53 +0 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 +0 53 -inf 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 -0 53 -inf 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 -5 53 -0 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 +inf 53 -0 53 +0 53 -0 N N
+0 0 53 +1 53 -0 53 +inf 53 -2 53 +0 53 -0 N N
+
+0 0 53 +1 53 +0 53 -inf 53 -inf 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 +inf 53 +0 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 +2 53 -5 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 +5 53 +0 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 +5 53 -0 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 +0 53 -2 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 -0 53 -2 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 -5 53 -0 53 -0 53 +0 N N
+0 0 53 +1 53 +0 53 -inf 53 -0 53 -0 53 +0 N N
+
+0 0 53 +1 53 -0 53 +inf 53 +inf 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 +2 53 +5 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 +2 53 +0 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 +2 53 -0 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 +0 53 +2 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 -0 53 +2 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 -5 53 +2 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 -5 53 +0 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 -inf 53 +inf 53 -0 53 -0 N N
+0 0 53 +1 53 -0 53 -inf 53 +inf 53 -0 53 -0 N N
+
+# x^0 = +1 -sign(Im(y))*0i when 1 > |x| > 0
+0 0 53 +1 53 -0 53 +0.5 53 -0.5 53 +0 53 +0 N N
+0 0 53 +1 53 -0 53 +0.5 53 +0 53 +0 53 +0 N N
+0 0 53 +1 53 -0 53 +0.5 53 -0 53 +0 53 +0 N N
+0 0 53 +1 53 -0 53 -0.5 53 -0 53 +0 53 +0 N N
+0 0 53 +1 53 -0 53 +0 53 -0.5 53 +0 53 +0 N N
+0 0 53 +1 53 -0 53 -0 53 -0.5 53 +0 53 +0 N N
+
+0 0 53 +1 53 +0 53 +0.5 53 +0.5 53 +0 53 -0 N N
+0 0 53 +1 53 +0 53 +0.5 53 +0 53 +0 53 -0 N N
+0 0 53 +1 53 +0 53 +0.5 53 -0 53 +0 53 -0 N N
+0 0 53 +1 53 +0 53 -0.5 53 +0 53 +0 53 -0 N N
+0 0 53 +1 53 +0 53 +0 53 +0.5 53 +0 53 -0 N N
+0 0 53 +1 53 +0 53 -0 53 +0.5 53 +0 53 -0 N N
+
+0 0 53 +1 53 -0 53 +0.5 53 +0.5 53 -0 53 +0 N N
+0 0 53 +1 53 -0 53 +0.5 53 +0 53 -0 53 +0 N N
+0 0 53 +1 53 -0 53 +0.5 53 -0 53 -0 53 +0 N N
+0 0 53 +1 53 -0 53 -0.5 53 -0 53 -0 53 +0 N N
+0 0 53 +1 53 -0 53 +0 53 +0.5 53 -0 53 +0 N N
+0 0 53 +1 53 -0 53 -0 53 +0.5 53 -0 53 +0 N N
+
+0 0 53 +1 53 +0 53 +0.5 53 -0.5 53 -0 53 -0 N N
+0 0 53 +1 53 +0 53 +0.5 53 +0 53 -0 53 -0 N N
+0 0 53 +1 53 +0 53 +0.5 53 -0 53 -0 53 -0 N N
+0 0 53 +1 53 +0 53 -0.5 53 -0 53 -0 53 -0 N N
+0 0 53 +1 53 +0 53 +0 53 -0.5 53 -0 53 -0 N N
+0 0 53 +1 53 +0 53 -0 53 -0.5 53 -0 53 -0 N N
+
+# determined sign of imaginary part in pure real powers
+0 0 53 +9 53 +0 53 +3 53 +0 53 +2 53 +0 N N
+0 0 53 +9 53 -0 53 +3 53 -0 53 +2 53 -0 N N
+0 0 53 0.25 53 +0 53 +2 53 -0 53 -2 53 +0 N N
+0 0 53 0.25 53 -0 53 +2 53 +0 53 -2 53 -0 N N
+0 0 53 +1 53 +0 53 +1 53 +0 53 +4 53 +0 N N
+0 0 53 +1 53 +0 53 +1 53 +0 53 +4 53 -0 N N
+0 0 53 +1 53 -0 53 +1 53 -0 53 +4 53 +0 N N
+0 0 53 +1 53 -0 53 +1 53 -0 53 +4 53 -0 N N
+0 0 53 +1 53 +0 53 +1 53 -0 53 -4 53 +0 N N
+0 0 53 +1 53 +0 53 +1 53 -0 53 -4 53 -0 N N
+0 0 53 +1 53 -0 53 +1 53 +0 53 -4 53 +0 N N
+0 0 53 +1 53 -0 53 +1 53 +0 53 -4 53 -0 N N
+0 0 53 0.25 53 +0 53 +0.5 53 +0 53 +2 53 -0 N N
+0 0 53 0.25 53 -0 53 +0.5 53 -0 53 +2 53 +0 N N
+0 0 53 +4 53 +0 53 +0.5 53 -0 53 -2 53 -0 N N
+0 0 53 +4 53 -0 53 +0.5 53 +0 53 -2 53 +0 N N
+
+
+# pure real power with nondetermined sign in imaginary part
+0 0 53 1 53 0 53 +2 53 -1 53 +0 53 +0 N N
+0 0 53 1 53 0 53 -2 53 -1 53 +0 53 +0 N N
+0 0 53 1 53 0 53 -2 53 -0 53 +0 53 +0 N N
+0 0 53 1 53 0 53 +0.5 53 +0.5 53 +0 53 +0 N N
+0 0 53 1 53 0 53 -0.5 53 +0.5 53 +0 53 +0 N N
+0 0 53 1 53 0 53 -0.5 53 +0 53 +0 53 +0 N N
+0 0 53 1 53 0 53 +0 53 +0.5 53 +0 53 +0 N N
+0 0 53 1 53 0 53 -0 53 +0.5 53 +0 53 +0 N N
+0 0 53 1 53 0 53 -0 53 -4 53 +0 53 +0 N N
+0 0 53 1 53 0 53 +0 53 -4 53 +0 53 +0 N N
+0 0 53 1 53 0 53 -1 53 -0 53 +0 53 +0 N N
+0 0 53 1 53 0 53 -1 53 +0 53 +0 53 +0 N N
+0 0 53 1 53 0 53 +2 53 -1 53 -0 53 -0 N N
+0 0 53 1 53 0 53 -2 53 -1 53 -0 53 -0 N N
+0 0 53 1 53 0 53 -2 53 -0 53 -0 53 -0 N N
+0 0 53 1 53 0 53 +0.5 53 +0.5 53 -0 53 -0 N N
+0 0 53 1 53 0 53 -0.5 53 +0.5 53 -0 53 -0 N N
+0 0 53 1 53 0 53 -0.5 53 +0 53 -0 53 -0 N N
+0 0 53 1 53 0 53 +0 53 +0.5 53 -0 53 -0 N N
+0 0 53 1 53 0 53 -0 53 +0.5 53 -0 53 -0 N N
+0 0 53 1 53 0 53 -0 53 -4 53 -0 53 -0 N N
+0 0 53 1 53 0 53 +0 53 -4 53 -0 53 -0 N N
+0 0 53 1 53 0 53 -1 53 -0 53 -0 53 -0 N N
+0 0 53 1 53 0 53 -1 53 +0 53 -0 53 -0 N N
+0 0 53 1 53 0 53 +2 53 +1 53 -0 53 +0 N N
+0 0 53 1 53 0 53 -2 53 +1 53 -0 53 +0 N N
+0 0 53 1 53 0 53 -2 53 +0 53 -0 53 +0 N N
+0 0 53 1 53 0 53 +0.5 53 -0.5 53 -0 53 +0 N N
+0 0 53 1 53 0 53 -0.5 53 -0.5 53 -0 53 +0 N N
+0 0 53 1 53 0 53 -0.5 53 -0 53 -0 53 +0 N N
+0 0 53 1 53 0 53 +0 53 +5 53 -0 53 +0 N N
+0 0 53 1 53 0 53 -0 53 +5 53 -0 53 +0 N N
+0 0 53 1 53 0 53 -0 53 -0.5 53 -0 53 +0 N N
+0 0 53 1 53 0 53 +0 53 -0.5 53 -0 53 +0 N N
+0 0 53 1 53 0 53 -1 53 -0 53 -0 53 +0 N N
+0 0 53 1 53 0 53 -1 53 +0 53 -0 53 +0 N N
+0 0 53 1 53 0 53 +2 53 +1 53 +0 53 -0 N N
+0 0 53 1 53 0 53 -2 53 +1 53 +0 53 -0 N N
+0 0 53 1 53 0 53 -2 53 +0 53 +0 53 -0 N N
+0 0 53 1 53 0 53 +0.5 53 -0.5 53 +0 53 -0 N N
+0 0 53 1 53 0 53 -0.5 53 -0.5 53 +0 53 -0 N N
+0 0 53 1 53 0 53 -0.5 53 -0 53 +0 53 -0 N N
+0 0 53 1 53 0 53 +0 53 +5 53 +0 53 -0 N N
+0 0 53 1 53 0 53 -0 53 +5 53 +0 53 -0 N N
+0 0 53 1 53 0 53 -0 53 -0.5 53 +0 53 -0 N N
+0 0 53 1 53 0 53 +0 53 -0.5 53 +0 53 -0 N N
+0 0 53 1 53 0 53 -1 53 -0 53 +0 53 -0 N N
+0 0 53 1 53 0 53 -1 53 +0 53 +0 53 -0 N N
+
+0 0 53 4 53 0 53 +2 53 -0 53 +2 53 +0 N N
+0 0 53 1 53 0 53 +1 53 +0 53 +2 53 +0 N N
+0 0 53 1 53 0 53 +1 53 +0 53 +2 53 -0 N N
+0 0 53 4 53 0 53 +2 53 +0 53 +2 53 -0 N N
+0 0 53 1 53 0 53 +1 53 -0 53 +2 53 +0 N N
+0 0 53 1 53 0 53 +1 53 -0 53 +2 53 -0 N N
+0 0 53 +.25 53 0 53 +2 53 +0 53 -2 53 +0 N N
+0 0 53 1 53 0 53 +1 53 +0 53 -2 53 +0 N N
+0 0 53 1 53 0 53 +1 53 +0 53 -2 53 -0 N N
+0 0 53 +.25 53 0 53 +2 53 -0 53 -2 53 -0 N N
+0 0 53 1 53 0 53 +1 53 -0 53 -2 53 +0 N N
+0 0 53 1 53 0 53 +1 53 -0 53 -2 53 -0 N N
+
+# when (+/-1 +/-0i)^y is pure real
+0 0 53 1 53 0 53 +1 53 -0 53 -2 53 +1 N N
+0 0 53 1 53 0 53 +1 53 -0 53 -1 53 +2 N N
+0 0 53 1 53 0 53 +1 53 -0 53 -0 53 +1 N N
+- 0 53 +0x10BBEEE9177E19p-43 53 0 53 -1 53 -0 53 -0 53 +2 N N
++ 0 53 +0x1E989F5D6DFF5Cp-62 53 0 53 -1 53 +0 53 +0 53 +2 N N
+0 0 53 1 53 0 53 +1 53 +0 53 +0 53 +2 N N
+0 0 53 1 53 0 53 +1 53 +0 53 +2 53 +2 N N
+0 0 53 1 53 0 53 +1 53 +0 53 +0 53 +2 N N
+0 0 53 1 53 0 53 +1 53 +0 53 -1 53 -1 N N
+0 0 53 1 53 0 53 +1 53 +0 53 -0 53 -1 N N
++ 0 53 +0x1724046EB0933Ap-48 53 0 53 -1 53 +0 53 -0 53 -1 N N
+0 0 53 1 53 0 53 +1 53 -0 53 +0 53 -1 N N
++ 0 53 +0x1620227B598EF9p-57 53 0 53 -1 53 -0 53 +0 53 -1 N N
+0 0 53 1 53 0 53 +1 53 -0 53 +2 53 -3 N N
++ 0 53 +0x1D4102BC3F7D4Cp-71 53 0 53 -1 53 +0 53 +0 53 +4 N N
++ 0 53 +0x1724046EB0933Ap-48 53 0 53 -1 53 -0 53 -0 53 +1 N N
+
+# when (0 +/-i)^y is pure real
++ 0 53 +0x1724046EB0933Ap-48 53 0 53 -0 53 -1 53 -0 53 +2 N N
+- 0 53 +0x1BD4567B975381p-46 53 0 53 +0 53 -1 53 -0 53 +3 N N
++ 0 53 +0x1620227B598EF9p-57 53 0 53 +0 53 +1 53 +0 53 +2 N N
+- 0 53 +0x1265D4E92B6B9Bp-59 53 0 53 -0 53 +1 53 +0 53 +3 N N
++ 0 53 +0x1724046EB0933Ap-48 53 0 53 +0 53 +1 53 -0 53 -2 N N
+- 0 53 +0x1BD4567B975381p-46 53 0 53 -0 53 +1 53 -0 53 -3 N N
+- 0 53 +0x1A9BCC46F767DFp-55 53 0 53 +0 53 -1 53 +0 53 -1 N N
++ 0 53 +0x1620227B598EF9p-57 53 0 53 -0 53 -1 53 +0 53 -2 N N
+
+# exact cases
+# (-1)^(1/2) = i
+0 0 2 0 2 1 2 -1 2 0 2 0x1p-1 2 0 N N
+# (-4)^(1/4) = 1+i
+0 0 2 1 2 1 2 -4 2 0 2 0x1p-2 2 0 N N
+# for an odd positive integer n, a positive integer m and an integer e:
+# (-4 m^4 16^e)^(n/4) = (1+i)^n m^n 2^(e n)
+# m=3 e=5 n=7
+0 0 12 0x88Bp38 12 -0x88Bp38 7 -0x51p22 7 0 3 0x7p-2 3 0 N N
+# (-4 16^e)^(-n/4) = (1-i)^n 2^(- (e+1) n)
+# e=3 n=5
+0 0 2 -0x1p-18 2 0x1p-18 2 -0x1p14 2 0 3 -0x5p-2 3 0 N N
+# e=2 n=5
+0 0 2 -0x1p-13 2 0x1p-13 2 -0x1p10 2 0 3 -0x5p-2 3 0 N N
+# (+2 +0)^(-3 -0) -> (-1/8 -0)
+# x = 2 + epsilon*i, y = -3 - delta*i
+# log(x) = log(2) + epsilon/2*i + O(epsilon^2)
+# y*log(x) = [-3*log(2) + o(1)] + [-3*epsilon/2-delta*log(2)]*i
+0 0 2 0x1p-3 2 -0 2 2 2 +0 2 -3 2 -0 N N
+# (-2 -0)^(3 +0) -> (-8 -0)
+# x = -2 - epsilon*i, y = 3 + delta*i
+# log(x) = log(2) - [Pi-epsilon/2]*i + O(epsilon^2)
+# y*log(x) ~ 3*log(2) + [-3*Pi+3*epsilon/2+delta*log(2)]*i
+0 0 2 -8 2 -0 2 -2 2 -0 2 3 2 +0 N N
+# (-2 -0)^(-3 -0) -> (-1/8 +0)
+# x = -2 - epsilon*i, y = -3 - delta*i
+# log(x) = log(2) - [Pi-epsilon/2]*i + O(epsilon^2)
+# y*log(x) ~ -3*log(2) + [3*Pi-3*epsilon/2-delta*log(2)]*i
+0 0 2 -0x1p-3 2 +0 2 -2 2 -0 2 -3 2 -0 N N
+0 0 2 +0 2 -2 2 +0 2 0x1p-1 2 -1 2 -0 N N
+0 0 2 +0 2 -2 2 +0 2 0x1p-1 65 -1 2 -0 N N
++ + 2 -0x3p-64 2 -2 2 +0 2 0x1p-1 65 -0x10000000000000001p-64 2 -0 N N
+
+0 - 2 +0 3 -5 2 +0 53 0xCCCCCCCCCCCCDp-54 2 -1 2 -0 N N
+# undefined zero sign in result
+- 0 5 -25 2 0 2 +0 53 0xCCCCCCCCCCCCDp-54 2 -2 2 -0 N N
+
+- - 53 -0x85649E3220691p-63 53 -0x14A25D455A9D0Dp-60 3 5 2 3 2 -3 2 +0 N N
++ 0 53 0xABCC77118461Dp-74 2 +0 3 5 3 5 2 -8 2 +0 N N
+
++ 0 53 -0x127DB86014739Dp-93 2 -0 2 -1 2 -0 2 1 4 -9 N N
++ + 24 0xC1F98Dp-21 24 0x12FF89p-2 24 -7 24 +0 24 0xCFFFF3p-21 24 +0 N N
+# underflow case
+- - 24 +0 24 +0 24 2 24 0x44CCCDp-20 24 -0x7FFFF200 24 -0x7FFFF200 N N
+- 0 53 0x14D55AFA6E0BB0p210433620 53 0 53 +0 53 0x44CCCCFFFFFFFp-48 53 0x5F5E100 53 +0 N N
+- 0 53 0x14D55B174EE67Ep210433620 53 0 53 +0 53 0x44CCCDp-20 53 0x5F5E100 53 +0 N N
+0 0 24 -10 24 198 24 5 24 3 24 3 24 +0 N N
++ - 113 0x1731C86FF8E8C7D80C8F1C83460B7p-38951 113 0x1CE5ECB8E88C769AF45FA662568CFp-38950 113 2 113 0x11333333333333333333333333333p-110 113 -10000 113 10000 N N
+- - 652 0x8E0380781E0124C92903E153123260CEF2C8821EDEC1D518A270FD55720DB5114D3D72CEE0E51CCEAA532FC6DA983707E66AE0E1A5E116D72AF5F2420D8402BE3E7FF03658E7ADFE2667C67291D74877383p-651 652 -0xB5FECD07C42E7AEE5A3489729B566DB4C6284C575E281585B0BFA711859D178BD8B07352B58BF615DD2DEC68798F0D2A644D5D18149D12BC53F851C5908F1EDE1C71F2B8D4934B1CE932AB94C0B8AE54C73p-665 163 0x5E9BDCC756D1E864413EA56F2A35C6D7D58DD117Bp-158 163 -0xE6BCC7A0E6EC5F2B1CBCF2707D829C2CB1A56FCFp-164 163 0x21A13BA8E157F23649FC27B031EAA12B826FB7E9Dp-166 163 0 N N
+0 0 2 0 2 1 2 -1 2 0 2 0x1p-1 2 0 N N
++ + 2 -0x3p-65 2 1 2 -1 2 0 65 0x10000000000000001p-65 2 0 N N
+0 0 2 1 2 +0 65 0x10000000000000001p-64 2 +0 2 +0 2 +0 N N
+0 0 2 1 2 -0 65 0xFFFFFFFFFFFFFFFFp-64 2 +0 2 +0 2 +0 N N
+0 + 2 +0 2 0.75 2 -0.5 2 0 2 0.5 2 0 N N
+0 0 2 0 2 2 2 1 2 1 2 2 2 +0 N N
+# I^2 = -1
+0 0 2 -1 2 +0 2 +0 2 1 2 2 2 +0 N N
++ 0 2 -1 2 +0 2 +0 65 0x10000000000000001p-64 2 2 2 +0 N N
+
+# overflow cases
+- - 2 -inf 2 -inf 2 3 2 1 28 744261116 2 +0 N N
+- + 2 -inf 2 +inf 2 3 2 -1 28 744261116 2 +0 N N
++ + 2 +inf 2 +inf 2 4 2 3 28 744261116 2 +0 N N
++ - 2 +inf 2 -inf 2 4 2 -3 28 744261116 2 +0 N N
+
+# underflow cases
++ - 2 -0 2 +0 2 3 2 1 28 -744261116 2 +0 N N
++ + 2 -0 2 -0 2 3 2 -1 28 -744261116 2 +0 N N
+- + 2 +0 2 -0 2 4 2 3 28 -744261116 2 +0 N N
+- - 2 +0 2 +0 2 4 2 -3 28 -744261116 2 +0 N N
+
+# exact powers with non-integer exponent
+0 0 2 1 2 1 2 0 2 2 2 0.5 2 0 N N
+0 0 2 -2 2 2 2 0 2 2 2 1.5 2 0 N N
+0 0 2 1 2 64 12 -4095 2 128 2 0.5 2 0 N N
+0 0 3 5 2 3 2 16 4 30 2 0.5 2 0 N N
+0 0 7 97 7 99 6 -392 14 19206 2 0.5 2 0 N N
+0 0 6 63 6 61 5 248 18 7686 2 0.5 2 0 N N
+0 0 6 63 6 61 24 -59013092 17 3812256 2 0.25 2 0 N N
+
+0 + 2 0 2 0x3p-6 2 -1 2 0 2 0.5 2 1 N N
++ + 2 6 2 1 41 -0x2ce019e6f1e 36 0x1878418ba20 2 0.0625 2 0 N N
++ + 4 11 2 1 111 -0x73558286726957f922819cbeffff 109 0x1c484a8b32dbf409e966a8c00000 2 0x1p-5 2 0 N N
++ + 5 21 2 1 282 -0x24ea91ddba938e750d999f1075444e15d6ca0fff6a19c8cbefe6260261fd57effffffff 278 0x390aa828a3d933391ab999b0b0aa71aafbfc7b127fe30c84d107634940ba8000000000 2 0x1p-6 2 0 N N
diff --git a/mpc/tests/pow_fr.dat b/mpc/tests/pow_fr.dat
new file mode 100644
index 0000000000..0816c1341c
--- /dev/null
+++ b/mpc/tests/pow_fr.dat
@@ -0,0 +1,74 @@
+# Data file for mpc_pow_fr.
+#
+# Copyright (C) 2011 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see add_fr.dat.
+
+0 0 5 -9 5 46 5 3 5 2 3 3 N N
+
+# (-0 -0.75)^4 = (0.31640625 -0) is rounded to (0.375 -0)
++ 0 2 0x3p-3 2 -0 2 -0 2 -0x3p-2 2 4 N N
+0 0 8 0x51p-8 2 -0 2 -0 2 -0x3p-2 2 4 N N
+# (+0 -0.75)^4 = (0.31640625 +0) is rounded to (0.375 +0)
++ 0 2 0x3p-3 2 +0 2 +0 2 -0x3p-2 2 4 N N
+0 0 8 0x51p-8 2 +0 2 +0 2 -0x3p-2 2 4 N N
+# (-0 0.75)^5 = (0.31640625 +0) is rounded to (0.375 +0)
++ 0 2 0x3p-3 2 +0 2 -0 2 0x3p-2 2 4 N N
+0 0 8 0x51p-8 2 +0 2 -0 2 0x3p-2 2 4 N N
+# (+0 0.75)^5 = (0.31640625 -0) is rounded to (0.375 -0)
++ 0 2 0x3p-3 2 -0 2 +0 2 0x3p-2 2 4 N N
+0 0 8 0x51p-8 2 -0 2 +0 2 0x3p-2 2 4 N N
+
+# (-0 -0.75)^5 = (-0 -0.2373046875) is rounded to (-0 -0.25)
+0 - 2 -0 2 -0x1p-2 2 -0 2 -0x3p-2 3 5 N N
+0 0 8 -0 8 -0xf3p-10 2 -0 2 -0x3p-2 3 5 N N
+# (+0 -0.75)^5 = (+0 -0.2373046875) is rounded to (+0 -0.25)
+0 - 2 +0 2 -0x1p-2 2 +0 2 -0x3p-2 3 5 N N
+0 0 8 +0 8 -0xf3p-10 2 +0 2 -0x3p-2 3 5 N N
+# (-0 0.75)^5 = (-0 0.2373046875) is rounded to (-0 0.25)
+0 + 2 -0 2 0x1p-2 2 -0 2 0x3p-2 3 5 N N
+0 0 8 -0 8 0xf3p-10 2 -0 2 0x3p-2 3 5 N N
+# (+0 0.75)^5 = (+0 0.2373046875) is rounded to (+0 0.25)
+0 + 2 +0 2 0x1p-2 2 +0 2 0x3p-2 3 5 N N
+0 0 8 +0 8 0xf3p-10 2 +0 2 0x3p-2 3 5 N N
+
+# (-0 -0.75)^6 = (-0.177978515625 +0) is rounded to (-0.1875 +0)
+- 0 2 -0x3p-4 2 +0 2 -0 2 -0x3p-2 3 6 N N
++ 0 8 -0x5bp-9 8 +0 2 -0 2 -0x3p-2 3 6 N N
+# (+0 -0.75)^6 = (-0.177978515625 -0) is rounded to (-0.1875 -0)
+- 0 2 -0x3p-4 2 -0 2 +0 2 -0x3p-2 3 6 N N
++ 0 8 -0x5bp-9 8 -0 2 +0 2 -0x3p-2 3 6 N N
+# (-0 0.75)^6 = (-0.177978515625 -0) is rounded to (-0.1875 -0)
+- 0 2 -0x3p-4 2 -0 2 -0 2 0x3p-2 3 6 N N
++ 0 8 -0x5bp-9 8 -0 2 -0 2 0x3p-2 3 6 N N
+# (+0 0.75)^6 = (-0.177978515625 +0) is rounded to (-0.1875 +0)
+- 0 2 -0x3p-4 2 +0 2 +0 2 0x3p-2 3 6 N N
++ 0 8 -0x5bp-9 8 +0 2 +0 2 0x3p-2 3 6 N N
+
+# (-0 -0.75)^7 = (+0 0.13348388671875) is rounded to (+0 0.125)
+0 - 2 +0 2 0x1p-3 2 -0 2 -0x3p-2 3 7 N N
+0 + 8 +0 8 0x89p-10 2 -0 2 -0x3p-2 3 7 N N
+# (+0 -0.75)^7 = (-0 0.13348388671875) is rounded to (-0 0.125)
+0 - 2 -0 2 0x1p-3 2 +0 2 -0x3p-2 3 7 N N
+0 + 8 -0 8 0x89p-10 2 +0 2 -0x3p-2 3 7 N N
+# (-0 0.75)^7 = (+0 -0.13348388671875) is rounded to (+0 -0.125)
+0 + 2 +0 2 -0x1p-3 2 -0 2 0x3p-2 3 7 N N
+0 - 8 +0 8 -0x89p-10 2 -0 2 0x3p-2 3 7 N N
+# (+0 0.75)^7 = (-0 -0.13348388671875) is rounded to (-0 -0.125)
+0 + 2 -0 2 -0x1p-3 2 +0 2 0x3p-2 3 7 N N
+0 - 8 -0 8 -0x89p-10 2 +0 2 0x3p-2 3 7 N N
diff --git a/mpc/tests/pow_si.dat b/mpc/tests/pow_si.dat
new file mode 100644
index 0000000000..a45d022147
--- /dev/null
+++ b/mpc/tests/pow_si.dat
@@ -0,0 +1,29 @@
+# Data file for mpc_pow_si.
+#
+# Copyright (C) 2011 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP1_RE OP1_RE PREC_OP1_IM OP1_IM OP2 RND_RE RND_IM
+#
+# For further details, see add_fr.dat.
+
+# special cases with exponents -1 and -2
+0 0 53 0.5 53 -0.5 53 1 53 1 -1 N N
+0 0 53 0 53 -0.5 53 1 53 1 -2 N N
diff --git a/mpc/tests/pow_ui.dat b/mpc/tests/pow_ui.dat
new file mode 100644
index 0000000000..d448a68874
--- /dev/null
+++ b/mpc/tests/pow_ui.dat
@@ -0,0 +1,102 @@
+# Data file for mpc_pow_ui.
+#
+# Copyright (C) 2010, 2011, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP1_RE OP1_RE PREC_OP1_IM OP1_IM OP2 RND_RE RND_IM
+#
+# For further details, see add_fr.dat.
+
+# special cases, copied from pow.dat
+0 0 53 +1 53 0 53 nan 53 +0 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 +1 N N
+0 0 53 inf 53 nan 53 +inf 53 +0 +1 N N
+0 0 53 +inf 53 nan 53 +inf 53 +1 +1 N N
+0 0 53 +inf 53 nan 53 +inf 53 -1 +1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +0 +1 N N
+0 0 53 +inf 53 nan 53 -inf 53 +1 +1 N N
+0 0 53 +inf 53 nan 53 -inf 53 -1 +1 N N
+
+0 0 53 +1 53 +0 53 +0 53 +0 +0 N N
+0 0 53 +0 53 +0 53 +0 53 +0 +1 N N
+
+0 0 53 +1 53 +0 53 +0 53 +1 +0 N N
+0 0 53 +1 53 -0 53 +0 53 +1 +0 N D
+0 0 53 +1 53 +0 53 -0 53 +1 +0 N N
+0 0 53 +1 53 +0 53 -1 53 +0 +0 N N
+0 0 53 +1 53 -0 53 -1 53 -0 +0 N N
+0 0 53 +1 53 -0 53 -0 53 -1 +0 N N
+0 0 53 +1 53 -0 53 +0 53 -1 +0 N N
+
+0 0 53 +1 53 +0 53 +inf 53 +2 +0 N N
+0 0 53 +1 53 +0 53 +inf 53 -0 +0 N N
+0 0 53 +1 53 +0 53 +2 53 +inf +0 N N
+0 0 53 +1 53 +0 53 +2 53 +0 +0 N N
+0 0 53 +1 53 +0 53 +0 53 +2 +0 N N
+0 0 53 +1 53 +0 53 +0 53 +inf +0 N N
+0 0 53 +1 53 +0 53 -0 53 +2 +0 N N
+0 0 53 +1 53 +0 53 -0 53 +inf +0 N N
+0 0 53 +1 53 +0 53 -5 53 +inf +0 N N
+0 0 53 +1 53 +0 53 -2 53 +0 +0 N N
+0 0 53 +1 53 +0 53 -inf 53 +0 +0 N N
+0 0 53 +1 53 +0 53 -inf 53 +3 +0 N N
+0 0 53 +1 53 -0 53 +0.5 53 -0.5 +0 N N
+0 0 53 +1 53 -0 53 +0.5 53 +0 +0 N N
+0 0 53 +1 53 -0 53 +0.5 53 -0 +0 N N
+0 0 53 +1 53 -0 53 -0.5 53 -0 +0 N N
+0 0 53 +1 53 -0 53 +0 53 -0.5 +0 N N
+0 0 53 +1 53 -0 53 -0 53 -0.5 +0 N N
+0 0 53 +9 53 +0 53 +3 53 +0 +2 N N
+0 0 53 +1 53 +0 53 +1 53 +0 +4 N N
+0 0 53 +1 53 -0 53 +1 53 -0 +4 N N
+0 0 53 0.25 53 -0 53 +0.5 53 -0 +2 N N
+
+0 0 53 1 53 0 53 +2 53 -1 +0 N N
+0 0 53 1 53 0 53 -2 53 -1 +0 N N
+0 0 53 1 53 0 53 -2 53 -0 +0 N N
+0 0 53 1 53 0 53 +0.5 53 +0.5 +0 N N
+0 0 53 1 53 0 53 -0.5 53 +0.5 +0 N N
+0 0 53 1 53 0 53 -0.5 53 +0 +0 N N
+0 0 53 1 53 0 53 +0 53 +0.5 +0 N N
+0 0 53 1 53 0 53 -0 53 +0.5 +0 N N
+0 0 53 1 53 0 53 -0 53 -4 +0 N N
+0 0 53 1 53 0 53 +0 53 -4 +0 N N
+0 0 53 1 53 0 53 -1 53 -0 +0 N N
+0 0 53 1 53 0 53 -1 53 +0 +0 N N
+
+0 0 53 4 53 0 53 +2 53 -0 +2 N N
+0 0 53 1 53 0 53 +1 53 +0 +2 N N
+0 0 53 1 53 0 53 +1 53 -0 +2 N N
+
+# overflow
+? ? 53 +inf 53 +inf 53 1e100000000 53 1e100000000 1000000000 N N
+# underflow
+? ? 53 0 53 0 53 1e-100000000 53 1e-100000000 1000000000 N N
+# cannot round after one loop
+? ? 420 -0x1.c3fb41a71665f9a144927e70cbc2dc899e9e30880c0b5aa924ad8a538b4cd06e503f38bdbb7cfcfded29f7504fe0c91ecd4230984@-187 420 -0xc.82a09ac98133eb05b2643c98eb1c8e1a1609e75f682b14098176abd6c8b4b3c6c72dadaf8929f9bd87f8c78d03361bacb9fb13140@-292 420 0x1.cf13ce58adc4e639fd1c3063ffc9291433647999951bc04ba6797ec4de0335336ad0a28df18573d3b6322ebab662c08eadaed4a8e@-8 420 0x3.cf71d602ca6f754ebd6af522154f3ee1c46da0a52deb1f60016fca4b1e0b4b447b752169e837bb1866aa3734850cd158a7e3ca33c@-9 24 N N
+# exact result
+0 0 5 -9 5 46 5 3 5 2 3 D U
+
+# special cases with exponents 1 and 2
+0 0 53 3 53 4 53 3 53 4 1 N N
+0 0 53 -7 53 24 53 3 53 4 2 N N
+
+# coverage test
++ - 2 1 2 1 100 0x8ac78f4e6aec091921cbdc891p-99 100 0x4a5f2972ea662e1cc0caebb81p-100 3 N N
diff --git a/mpc/tests/proj.dat b/mpc/tests/proj.dat
new file mode 100644
index 0000000000..f9ead72f68
--- /dev/null
+++ b/mpc/tests/proj.dat
@@ -0,0 +1,73 @@
+# Data file for mpc_proj.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_RE PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# see sin.dat for precisions
+
+# special values (following ISO C99 standard)
+0 0 53 +inf 53 -0 53 -inf 53 -inf N N
+0 0 53 +inf 53 -0 53 -inf 53 -1 N N
+0 0 53 +inf 53 -0 53 -inf 53 -0 N N
+0 0 53 +inf 53 +0 53 -inf 53 +0 N N
+0 0 53 +inf 53 +0 53 -inf 53 +1 N N
+0 0 53 +inf 53 +0 53 -inf 53 +inf N N
+0 0 53 +inf 53 0 53 -inf 53 nan N N
+0 0 53 +inf 53 -0 53 -1 53 -inf N N
+0 0 53 -1 53 -0 53 -1 53 -0 N N
+0 0 53 -1 53 +0 53 -1 53 +0 N N
+0 0 53 +inf 53 +0 53 -1 53 +inf N N
+0 0 53 -1 53 nan 53 -1 53 nan N N
+0 0 53 +inf 53 -0 53 -0 53 -inf N N
+0 0 53 -0 53 -1 53 -0 53 -1 N N
+0 0 53 -0 53 -0 53 -0 53 -0 N N
+0 0 53 -0 53 +0 53 -0 53 +0 N N
+0 0 53 -0 53 +1 53 -0 53 +1 N N
+0 0 53 +inf 53 +0 53 -0 53 +inf N N
+0 0 53 -0 53 nan 53 -0 53 nan N N
+0 0 53 +inf 53 -0 53 +0 53 -inf N N
+0 0 53 +0 53 -1 53 +0 53 -1 N N
+0 0 53 +0 53 -0 53 +0 53 -0 N N
+0 0 53 +0 53 +0 53 +0 53 +0 N N
+0 0 53 +0 53 +1 53 +0 53 +1 N N
+0 0 53 +inf 53 +0 53 +0 53 +inf N N
+0 0 53 +0 53 nan 53 +0 53 nan N N
+0 0 53 +inf 53 -0 53 +1 53 -inf N N
+0 0 53 +1 53 -0 53 +1 53 -0 N N
+0 0 53 +1 53 +0 53 +1 53 +0 N N
+0 0 53 +inf 53 +0 53 +1 53 +inf N N
+0 0 53 +1 53 nan 53 +1 53 nan N N
+0 0 53 +inf 53 -0 53 +inf 53 -inf N N
+0 0 53 +inf 53 -0 53 +inf 53 -1 N N
+0 0 53 +inf 53 -0 53 +inf 53 -0 N N
+0 0 53 +inf 53 +0 53 +inf 53 +0 N N
+0 0 53 +inf 53 +0 53 +inf 53 +1 N N
+0 0 53 +inf 53 +0 53 +inf 53 +inf N N
+0 0 53 +inf 53 0 53 +inf 53 nan N N
+0 0 53 +inf 53 -0 53 nan 53 -inf N N
+0 0 53 nan 53 -1 53 nan 53 -1 N N
+0 0 53 nan 53 -0 53 nan 53 -0 N N
+0 0 53 nan 53 +0 53 nan 53 +0 N N
+0 0 53 nan 53 +1 53 nan 53 +1 N N
+0 0 53 +inf 53 +0 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
diff --git a/mpc/tests/random.c b/mpc/tests/random.c
new file mode 100644
index 0000000000..aa06355d3f
--- /dev/null
+++ b/mpc/tests/random.c
@@ -0,0 +1,160 @@
+/* random.c -- Handle seed for random numbers.
+
+// Copyright (C) 2008, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+/* Put test_start at the beginning of your test function and
+ test_end at the end.
+ These are an adaptation of those of MPFR. */
+
+#include "config.h"
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+gmp_randstate_t rands;
+static char rands_initialized;
+
+void
+test_start (void)
+{
+ char *environment_seed;
+ unsigned long seed;
+
+ if (rands_initialized)
+ {
+ fprintf (stderr,
+ "Put test_start at the beginning of your test function.\n");
+ exit (1);
+ }
+
+ gmp_randinit_default (rands);
+ rands_initialized = 1;
+
+ environment_seed = getenv ("GMP_CHECK_RANDOMIZE");
+ if (environment_seed == NULL)
+ gmp_randseed_ui (rands, 0xfac11e);
+ else
+ {
+ seed = (unsigned long int) atoi (environment_seed);
+ if (seed == 0 || seed == 1)
+ {
+#if defined HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ seed = (unsigned long int) (tv.tv_sec + tv.tv_usec);
+#else
+ time_t tv;
+ time (&tv);
+ seed = (unsigned long int) tv;
+#endif
+ gmp_randseed_ui (rands, seed);
+ printf ("Seed GMP_CHECK_RANDOMIZE=%lu "
+ "(include this in bug reports)\n", seed);
+ }
+ else
+ {
+ printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed);
+ gmp_randseed_ui (rands, seed);
+ }
+ }
+}
+
+void
+test_end (void)
+{
+ if (rands_initialized)
+ {
+ rands_initialized = 0;
+ gmp_randclear (rands);
+ }
+ mpfr_free_cache ();
+}
+
+/* Set z to a non zero value random value with absolute values of Re(z) and
+ Im(z) either zero (but not both in the same time) or otherwise greater than
+ or equal to 2^{emin-1} and less than 2^emax.
+ Each part is negative with probability equal to NEGATIVE_PROBABILITY / 256.
+ The result has one zero part (but never the two of them) with probability
+ equal to ZERO_PROBABILITY / 256.
+*/
+void
+test_default_random (mpc_ptr z, mpfr_exp_t emin, mpfr_exp_t emax,
+ unsigned int negative_probability,
+ unsigned int zero_probability)
+{
+ const unsigned long range = (unsigned long int) (emax - emin) + 1;
+ unsigned long r;
+
+ if (!rands_initialized)
+ {
+ fprintf (stderr,
+ "Put test_start at the beginning of your test function.\n");
+ exit (1);
+ }
+
+ do
+ {
+ mpc_urandom (z, rands);
+ } while (mpfr_zero_p (mpc_realref (z)) || mpfr_zero_p (mpc_imagref (z)));
+
+ if (zero_probability > 256)
+ zero_probability = 256;
+ r = gmp_urandomb_ui (rands, 19);
+ if ((r & 0x1FF) < zero_probability
+ || ((r >> 9) & 0x1FF) < zero_probability)
+ {
+ int zero_re_p = (r & 0x1FF) < zero_probability;
+ int zero_im_p = ((r >> 9) & 0x1FF) < zero_probability;
+
+ if (zero_re_p && zero_im_p)
+ {
+ /* we just want one zero part. */
+ zero_re_p = (r >> 18) & 1;
+ zero_im_p = !zero_re_p;
+ }
+ if (zero_re_p)
+ mpfr_set_ui (mpc_realref (z), 0, GMP_RNDN);
+ if (zero_im_p)
+ mpfr_set_ui (mpc_imagref (z), 0, GMP_RNDN);
+ }
+ if (!mpfr_zero_p (mpc_realref (z)))
+ mpfr_set_exp (mpc_realref (z), (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin);
+
+ if (!mpfr_zero_p (mpc_imagref (z)))
+ mpfr_set_exp (mpc_imagref (z), (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin);
+
+ if (negative_probability > 256)
+ negative_probability = 256;
+ r = gmp_urandomb_ui (rands, 16);
+ if ((r & 0xFF) < negative_probability)
+ mpfr_neg (mpc_realref (z), mpc_realref (z), GMP_RNDN);
+ if (((r>>8) & 0xFF) < negative_probability)
+ mpfr_neg (mpc_imagref (z), mpc_imagref (z), GMP_RNDN);
+}
diff --git a/mpc/tests/read_data.c b/mpc/tests/read_data.c
new file mode 100644
index 0000000000..7f3d91f622
--- /dev/null
+++ b/mpc/tests/read_data.c
@@ -0,0 +1,1059 @@
+/* read_data,c -- Read data file and check function.
+
+Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include "mpc-tests.h"
+
+char *pathname;
+unsigned long line_number;
+ /* file name with complete path and currently read line;
+ kept globally to simplify parameter passing */
+unsigned long test_line_number;
+ /* start line of data test (which may extend over several lines) */
+int nextchar;
+ /* character appearing next in the file, may be EOF */
+
+#define MPC_INEX_CMP(r, i, c) \
+ (((r) == TERNARY_NOT_CHECKED || (r) == MPC_INEX_RE(c)) \
+ && ((i) == TERNARY_NOT_CHECKED || (i) == MPC_INEX_IM (c)))
+
+#define MPFR_INEX_STR(inex) \
+ (inex) == TERNARY_NOT_CHECKED ? "?" \
+ : (inex) == +1 ? "+1" \
+ : (inex) == -1 ? "-1" : "0"
+
+static const char *mpfr_rnd_mode [] =
+ { "GMP_RNDN", "GMP_RNDZ", "GMP_RNDU", "GMP_RNDD" };
+
+const char *rnd_mode[] =
+ { "MPC_RNDNN", "MPC_RNDZN", "MPC_RNDUN", "MPC_RNDDN",
+ "undefined", "undefined", "undefined", "undefined", "undefined",
+ "undefined", "undefined", "undefined", "undefined", "undefined",
+ "undefined", "undefined",
+ "MPC_RNDNZ", "MPC_RNDZZ", "MPC_RNDUZ", "MPC_RNDDZ",
+ "undefined", "undefined", "undefined", "undefined", "undefined",
+ "undefined", "undefined", "undefined", "undefined", "undefined",
+ "undefined", "undefined",
+ "MPC_RNDNU", "MPC_RNDZU", "MPC_RNDUU", "MPC_RNDDU",
+ "undefined", "undefined", "undefined", "undefined", "undefined",
+ "undefined", "undefined", "undefined", "undefined", "undefined",
+ "undefined", "undefined",
+ "MPC_RNDND", "MPC_RNDZD", "MPC_RNDUD", "MPC_RNDDD",
+ "undefined", "undefined", "undefined", "undefined", "undefined",
+ "undefined", "undefined", "undefined", "undefined", "undefined",
+ "undefined", "undefined",
+ };
+
+/* file functions */
+FILE *
+open_data_file (const char *file_name)
+{
+ FILE *fp;
+ char *src_dir;
+ char default_srcdir[] = ".";
+
+ src_dir = getenv ("srcdir");
+ if (src_dir == NULL)
+ src_dir = default_srcdir;
+
+ pathname = (char *) malloc ((strlen (src_dir)) + strlen (file_name) + 2);
+ if (pathname == NULL)
+ {
+ printf ("Cannot allocate memory\n");
+ exit (1);
+ }
+ sprintf (pathname, "%s/%s", src_dir, file_name);
+ fp = fopen (pathname, "r");
+ if (fp == NULL)
+ {
+ fprintf (stderr, "Unable to open %s\n", pathname);
+ exit (1);
+ }
+
+ return fp;
+}
+
+void
+close_data_file (FILE *fp)
+{
+ free (pathname);
+ fclose (fp);
+}
+
+/* read primitives */
+static void
+skip_line (FILE *fp)
+ /* skips characters until reaching '\n' or EOF; */
+ /* '\n' is skipped as well */
+{
+ while (nextchar != EOF && nextchar != '\n')
+ nextchar = getc (fp);
+ if (nextchar != EOF)
+ {
+ line_number ++;
+ nextchar = getc (fp);
+ }
+}
+
+static void
+skip_whitespace (FILE *fp)
+ /* skips over whitespace if any until reaching EOF */
+ /* or non-whitespace */
+{
+ while (isspace (nextchar))
+ {
+ if (nextchar == '\n')
+ line_number ++;
+ nextchar = getc (fp);
+ }
+}
+
+void
+skip_whitespace_comments (FILE *fp)
+ /* skips over all whitespace and comments, if any */
+{
+ skip_whitespace (fp);
+ while (nextchar == '#') {
+ skip_line (fp);
+ if (nextchar != EOF)
+ skip_whitespace (fp);
+ }
+}
+
+
+size_t
+read_string (FILE *fp, char **buffer_ptr, size_t buffer_length, const char *name)
+{
+ size_t pos;
+ char *buffer;
+
+ pos = 0;
+ buffer = *buffer_ptr;
+
+ if (nextchar == '"')
+ nextchar = getc (fp);
+ else
+ goto error;
+
+ while (nextchar != EOF && nextchar != '"')
+ {
+ if (nextchar == '\n')
+ line_number ++;
+ if (pos + 1 > buffer_length)
+ {
+ buffer = (char *) realloc (buffer, 2 * buffer_length);
+ if (buffer == NULL)
+ {
+ printf ("Cannot allocate memory\n");
+ exit (1);
+ }
+ buffer_length *= 2;
+ }
+ buffer[pos++] = (char) nextchar;
+ nextchar = getc (fp);
+ }
+
+ if (nextchar != '"')
+ goto error;
+
+ if (pos + 1 > buffer_length)
+ {
+ buffer = (char *) realloc (buffer, buffer_length + 1);
+ if (buffer == NULL)
+ {
+ printf ("Cannot allocate memory\n");
+ exit (1);
+ }
+ buffer_length *= 2;
+ }
+ buffer[pos] = '\0';
+
+ nextchar = getc (fp);
+ skip_whitespace_comments (fp);
+
+ *buffer_ptr = buffer;
+
+ return buffer_length;
+
+ error:
+ printf ("Error: Unable to read %s in file '%s' line '%lu'\n",
+ name, pathname, line_number);
+ exit (1);
+}
+
+/* All following read routines skip over whitespace and comments; */
+/* so after calling them, nextchar is either EOF or the beginning */
+/* of a non-comment token. */
+void
+read_ternary (FILE *fp, int* ternary)
+{
+ switch (nextchar)
+ {
+ case '!':
+ *ternary = TERNARY_ERROR;
+ break;
+ case '?':
+ *ternary = TERNARY_NOT_CHECKED;
+ break;
+ case '+':
+ *ternary = +1;
+ break;
+ case '0':
+ *ternary = 0;
+ break;
+ case '-':
+ *ternary = -1;
+ break;
+ default:
+ printf ("Error: Unexpected ternary value '%c' in file '%s' line %lu\n",
+ nextchar, pathname, line_number);
+ exit (1);
+ }
+
+ nextchar = getc (fp);
+ skip_whitespace_comments (fp);
+}
+
+void
+read_mpfr_rounding_mode (FILE *fp, mpfr_rnd_t* rnd)
+{
+ switch (nextchar)
+ {
+ case 'n': case 'N':
+ *rnd = GMP_RNDN;
+ break;
+ case 'z': case 'Z':
+ *rnd = GMP_RNDZ;
+ break;
+ case 'u': case 'U':
+ *rnd = GMP_RNDU;
+ break;
+ case 'd': case 'D':
+ *rnd = GMP_RNDD;
+ break;
+ default:
+ printf ("Error: Unexpected rounding mode '%c' in file '%s' line %lu\n",
+ nextchar, pathname, line_number);
+ exit (1);
+ }
+
+ nextchar = getc (fp);
+ if (nextchar != EOF && !isspace (nextchar)) {
+ printf ("Error: Rounding mode not followed by white space in file "
+ "'%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ skip_whitespace_comments (fp);
+}
+
+void
+read_mpc_rounding_mode (FILE *fp, mpc_rnd_t* rnd)
+{
+ mpfr_rnd_t re, im;
+ read_mpfr_rounding_mode (fp, &re);
+ read_mpfr_rounding_mode (fp, &im);
+ *rnd = MPC_RND (re, im);
+}
+
+void
+read_int (FILE *fp, int *nread, const char *name)
+{
+ int n = 0;
+
+ if (nextchar == EOF)
+ {
+ printf ("Error: Unexpected EOF when reading int "
+ "in file '%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ ungetc (nextchar, fp);
+ n = fscanf (fp, "%i", nread);
+ if (ferror (fp) || n == 0 || n == EOF)
+ {
+ printf ("Error: Cannot read %s in file '%s' line %lu\n",
+ name, pathname, line_number);
+ exit (1);
+ }
+ nextchar = getc (fp);
+ skip_whitespace_comments (fp);
+}
+
+static void
+read_uint (FILE *fp, unsigned long int *ui)
+{
+ int n = 0;
+
+ if (nextchar == EOF)
+ {
+ printf ("Error: Unexpected EOF when reading uint "
+ "in file '%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ ungetc (nextchar, fp);
+ n = fscanf (fp, "%lu", ui);
+ if (ferror (fp) || n == 0 || n == EOF)
+ {
+ printf ("Error: Cannot read uint in file '%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ nextchar = getc (fp);
+ skip_whitespace_comments (fp);
+}
+
+static void
+read_sint (FILE *fp, long int *si)
+{
+ int n = 0;
+
+ if (nextchar == EOF)
+ {
+ printf ("Error: Unexpected EOF when reading sint "
+ "in file '%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ ungetc (nextchar, fp);
+ n = fscanf (fp, "%li", si);
+ if (ferror (fp) || n == 0 || n == EOF)
+ {
+ printf ("Error: Cannot read sint in file '%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ nextchar = getc (fp);
+ skip_whitespace_comments (fp);
+}
+
+mpfr_prec_t
+read_mpfr_prec (FILE *fp)
+{
+ unsigned long prec;
+ int n;
+
+ if (nextchar == EOF) {
+ printf ("Error: Unexpected EOF when reading mpfr precision "
+ "in file '%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ ungetc (nextchar, fp);
+ n = fscanf (fp, "%lu", &prec);
+ if (ferror (fp)) /* then also n == EOF */
+ perror ("Error when reading mpfr precision");
+ if (n == 0 || n == EOF || prec < MPFR_PREC_MIN || prec > MPFR_PREC_MAX) {
+ printf ("Error: Impossible mpfr precision in file '%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ nextchar = getc (fp);
+ skip_whitespace_comments (fp);
+ return (mpfr_prec_t) prec;
+}
+
+static void
+read_mpfr_mantissa (FILE *fp, mpfr_ptr x)
+{
+ if (nextchar == EOF) {
+ printf ("Error: Unexpected EOF when reading mpfr mantissa "
+ "in file '%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ ungetc (nextchar, fp);
+ if (mpfr_inp_str (x, fp, 0, GMP_RNDN) == 0) {
+ printf ("Error: Impossible to read mpfr mantissa "
+ "in file '%s' line %lu\n",
+ pathname, line_number);
+ exit (1);
+ }
+ nextchar = getc (fp);
+ skip_whitespace_comments (fp);
+}
+
+void
+read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign)
+{
+ int sign;
+ mpfr_set_prec (x, read_mpfr_prec (fp));
+ sign = nextchar;
+ read_mpfr_mantissa (fp, x);
+
+ /* the sign always matters for regular values ('+' is implicit),
+ but when no sign appears before 0 or Inf in the data file, it means
+ that only absolute value must be checked. */
+ if (known_sign != NULL)
+ *known_sign =
+ (!mpfr_zero_p (x) && !mpfr_inf_p (x))
+ || sign == '+' || sign == '-';
+}
+
+void
+read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks)
+{
+ read_mpfr (fp, mpc_realref (z), ks == NULL ? NULL : &ks->re);
+ read_mpfr (fp, mpc_imagref (z), ks == NULL ? NULL : &ks->im);
+}
+
+static void
+check_compatible (int inex, mpfr_t expected, mpfr_rnd_t rnd, const char *s)
+{
+ if ((rnd == GMP_RNDU && inex == -1) ||
+ (rnd == GMP_RNDD && inex == +1) ||
+ (rnd == GMP_RNDZ && !mpfr_signbit (expected) && inex == +1) ||
+ (rnd == GMP_RNDZ && mpfr_signbit (expected) && inex == -1))
+ {
+ if (s != NULL)
+ printf ("Incompatible ternary value '%c' (%s part) in file '%s' line %lu\n",
+ (inex == 1) ? '+' : '-', s, pathname, test_line_number);
+ else
+ printf ("Incompatible ternary value '%c' in file '%s' line %lu\n",
+ (inex == 1) ? '+' : '-', pathname, test_line_number);
+ }
+}
+
+/* read lines of data */
+static void
+read_cc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
+ known_signs_t *signs, mpc_ptr op, mpc_rnd_t *rnd)
+{
+ test_line_number = line_number;
+ read_ternary (fp, inex_re);
+ read_ternary (fp, inex_im);
+ read_mpc (fp, expected, signs);
+ read_mpc (fp, op, NULL);
+ read_mpc_rounding_mode (fp, rnd);
+ check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
+ check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
+}
+
+static void
+read_fc (FILE *fp, int *inex, mpfr_ptr expected, int *sign, mpc_ptr op,
+ mpfr_rnd_t *rnd)
+{
+ test_line_number = line_number;
+ read_ternary (fp, inex);
+ read_mpfr (fp, expected, sign);
+ read_mpc (fp, op, NULL);
+ read_mpfr_rounding_mode (fp, rnd);
+ check_compatible (*inex, expected, *rnd, NULL);
+}
+
+static void
+read_ccc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
+ known_signs_t *signs, mpc_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd)
+{
+ test_line_number = line_number;
+ read_ternary (fp, inex_re);
+ read_ternary (fp, inex_im);
+ read_mpc (fp, expected, signs);
+ read_mpc (fp, op1, NULL);
+ read_mpc (fp, op2, NULL);
+ read_mpc_rounding_mode (fp, rnd);
+ check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
+ check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
+}
+
+/* read lines of data for function with three mpc_t inputs and one mpc_t
+ output like mpc_fma */
+static void
+read_cccc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
+ known_signs_t *signs, mpc_ptr op1, mpc_ptr op2, mpc_ptr op3,
+ mpc_rnd_t *rnd)
+{
+ test_line_number = line_number;
+ read_ternary (fp, inex_re);
+ read_ternary (fp, inex_im);
+ read_mpc (fp, expected, signs);
+ read_mpc (fp, op1, NULL);
+ read_mpc (fp, op2, NULL);
+ read_mpc (fp, op3, NULL);
+ read_mpc_rounding_mode (fp, rnd);
+ check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
+ check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
+}
+
+static void
+read_cfc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
+ known_signs_t *signs, mpfr_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd)
+{
+ test_line_number = line_number;
+ read_ternary (fp, inex_re);
+ read_ternary (fp, inex_im);
+ read_mpc (fp, expected, signs);
+ read_mpfr (fp, op1, NULL);
+ read_mpc (fp, op2, NULL);
+ read_mpc_rounding_mode (fp, rnd);
+ check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
+ check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
+}
+
+static void
+read_ccf (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
+ known_signs_t *signs, mpc_ptr op1, mpfr_ptr op2, mpc_rnd_t *rnd)
+{
+ test_line_number = line_number;
+ read_ternary (fp, inex_re);
+ read_ternary (fp, inex_im);
+ read_mpc (fp, expected, signs);
+ read_mpc (fp, op1, NULL);
+ read_mpfr (fp, op2, NULL);
+ read_mpc_rounding_mode (fp, rnd);
+ check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
+ check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
+}
+
+static void
+read_ccu (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
+ known_signs_t *signs, mpc_ptr op1, unsigned long int *op2, mpc_rnd_t *rnd)
+{
+ test_line_number = line_number;
+ read_ternary (fp, inex_re);
+ read_ternary (fp, inex_im);
+ read_mpc (fp, expected, signs);
+ read_mpc (fp, op1, NULL);
+ read_uint (fp, op2);
+ read_mpc_rounding_mode (fp, rnd);
+ check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
+ check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
+}
+
+static void
+read_ccs (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
+ known_signs_t *signs, mpc_ptr op1, long int *op2, mpc_rnd_t *rnd)
+{
+ test_line_number = line_number;
+ read_ternary (fp, inex_re);
+ read_ternary (fp, inex_im);
+ read_mpc (fp, expected, signs);
+ read_mpc (fp, op1, NULL);
+ read_sint (fp, op2);
+ read_mpc_rounding_mode (fp, rnd);
+ check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
+ check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
+}
+
+/* set MPFR flags to random values */
+static void
+set_mpfr_flags (int counter)
+{
+ if (counter & 1)
+ mpfr_set_underflow ();
+ else
+ mpfr_clear_underflow ();
+ if (counter & 2)
+ mpfr_set_overflow ();
+ else
+ mpfr_clear_overflow ();
+ /* the divide-by-0 flag was added in MPFR 3.1.0 */
+#ifdef mpfr_set_divby0
+ if (counter & 4)
+ mpfr_set_divby0 ();
+ else
+ mpfr_clear_divby0 ();
+#endif
+ if (counter & 8)
+ mpfr_set_nanflag ();
+ else
+ mpfr_clear_nanflag ();
+ if (counter & 16)
+ mpfr_set_inexflag ();
+ else
+ mpfr_clear_inexflag ();
+ if (counter & 32)
+ mpfr_set_erangeflag ();
+ else
+ mpfr_clear_erangeflag ();
+}
+
+/* Check MPFR flags: we allow that some flags are set internally by MPC,
+ for example if MPC does internal computations (using MPFR) which yield
+ an overflow, even if the final MPC result fits in the exponent range.
+ However we don't allow MPC to *clear* the MPFR flags */
+static void
+check_mpfr_flags (int counter)
+{
+ int old, neu;
+
+ old = (counter & 1) != 0;
+ neu = mpfr_underflow_p () != 0;
+ if (old && (neu == 0))
+ {
+ printf ("Error, underflow flag has been modified from %d to %d\n",
+ old, neu);
+ exit (1);
+ }
+ old = (counter & 2) != 0;
+ neu = mpfr_overflow_p () != 0;
+ if (old && (neu == 0))
+ {
+ printf ("Error, overflow flag has been modified from %d to %d\n",
+ old, neu);
+ exit (1);
+ }
+#ifdef mpfr_divby0_p
+ old = (counter & 4) != 0;
+ neu = mpfr_divby0_p () != 0;
+ if (old && (neu == 0))
+ {
+ printf ("Error, divby0 flag has been modified from %d to %d\n",
+ old, neu);
+ exit (1);
+ }
+#endif
+ old = (counter & 8) != 0;
+ neu = mpfr_nanflag_p () != 0;
+ if (old && (neu == 0))
+ {
+ printf ("Error, nanflag flag has been modified from %d to %d\n",
+ old, neu);
+ exit (1);
+ }
+ old = (counter & 16) != 0;
+ neu = mpfr_inexflag_p () != 0;
+ if (old && (neu == 0))
+ {
+ printf ("Error, inexflag flag has been modified from %d to %d\n",
+ old, neu);
+ exit (1);
+ }
+ old = (counter & 32) != 0;
+ neu = mpfr_erangeflag_p () != 0;
+ if (old && (neu == 0))
+ {
+ printf ("Error, erangeflag flag has been modified from %d to %d\n",
+ old, neu);
+ exit (1);
+ }
+}
+
+/* data_check (function, data_file_name) checks function results against
+ precomputed data in a file.*/
+void
+data_check (mpc_function function, const char *file_name)
+{
+ FILE *fp;
+
+ int inex_re;
+ mpfr_t x1, x2;
+ mpfr_rnd_t mpfr_rnd = GMP_RNDN;
+ int sign_real;
+
+ int inex_im;
+ mpc_t z1, z2, z3, z4, z5;
+ mpc_rnd_t rnd = MPC_RNDNN;
+
+ unsigned long int ui;
+ long int si;
+
+ known_signs_t signs;
+ int inex = 0;
+
+ static int rand_counter = 0;
+
+ fp = open_data_file (file_name);
+
+ /* 1. init needed variables */
+ mpc_init2 (z1, 2);
+ switch (function.type)
+ {
+ case FC:
+ mpfr_init (x1);
+ mpfr_init (x2);
+ break;
+ case CC: case CCU: case CCS:
+ mpc_init2 (z2, 2);
+ mpc_init2 (z3, 2);
+ break;
+ case C_CC:
+ mpc_init2 (z2, 2);
+ mpc_init2 (z3, 2);
+ mpc_init2 (z4, 2);
+ break;
+ case CCCC:
+ mpc_init2 (z2, 2);
+ mpc_init2 (z3, 2);
+ mpc_init2 (z4, 2);
+ mpc_init2 (z5, 2);
+ break;
+ case CFC: case CCF:
+ mpfr_init (x1);
+ mpc_init2 (z2, 2);
+ mpc_init2 (z3, 2);
+ break;
+ default:
+ ;
+ }
+
+ /* 2. read data file */
+ line_number = 1;
+ nextchar = getc (fp);
+ skip_whitespace_comments (fp);
+ while (nextchar != EOF) {
+ set_mpfr_flags (rand_counter);
+
+ /* for each kind of function prototype: */
+ /* 3.1 read a line of data: expected result, parameters, rounding mode */
+ /* 3.2 compute function at the same precision as the expected result */
+ /* 3.3 compare this result with the expected one */
+ switch (function.type)
+ {
+ case FC: /* example mpc_norm */
+ read_fc (fp, &inex_re, x1, &sign_real, z1, &mpfr_rnd);
+ mpfr_set_prec (x2, mpfr_get_prec (x1));
+ inex = function.pointer.FC (x2, z1, mpfr_rnd);
+ if ((inex_re != TERNARY_NOT_CHECKED && inex_re != inex)
+ || !same_mpfr_value (x1, x2, sign_real))
+ {
+ mpfr_t got, expected;
+ mpc_t op;
+ op[0] = z1[0];
+ got[0] = x2[0];
+ expected[0] = x1[0];
+ printf ("%s(op) failed (%s:%lu)\nwith rounding mode %s\n",
+ function.name, file_name, test_line_number,
+ mpfr_rnd_mode[mpfr_rnd]);
+ if (inex_re != TERNARY_NOT_CHECKED && inex_re != inex)
+ printf("ternary value: got %s, expected %s\n",
+ MPFR_INEX_STR (inex), MPFR_INEX_STR (inex_re));
+ MPC_OUT (op);
+ printf (" ");
+ MPFR_OUT (got);
+ MPFR_OUT (expected);
+
+ exit (1);
+ }
+ break;
+
+ case CC: /* example mpc_log */
+ read_cc (fp, &inex_re, &inex_im, z1, &signs, z2, &rnd);
+ mpfr_set_prec (mpc_realref (z3), MPC_PREC_RE (z1));
+ mpfr_set_prec (mpc_imagref (z3), MPC_PREC_IM (z1));
+ inex = function.pointer.CC (z3, z2, rnd);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex)
+ || !same_mpc_value (z3, z1, signs))
+ {
+ mpc_t op, got, expected; /* display sensible variable names */
+ op[0] = z2[0];
+ expected[0]= z1[0];
+ got[0] = z3[0];
+ printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
+ function.name, test_line_number, rnd_mode[rnd]);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex))
+ printf("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
+ MPC_OUT (op);
+ printf (" ");
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+ break;
+
+ case C_CC: /* example mpc_mul */
+ read_ccc (fp, &inex_re, &inex_im, z1, &signs, z2, z3, &rnd);
+ mpfr_set_prec (mpc_realref(z4), MPC_PREC_RE (z1));
+ mpfr_set_prec (mpc_imagref(z4), MPC_PREC_IM (z1));
+ inex = function.pointer.C_CC (z4, z2, z3, rnd);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex)
+ || !same_mpc_value (z4, z1, signs))
+ {
+ /* display sensible variable names */
+ mpc_t op1, op2, got, expected;
+ op1[0] = z2[0];
+ op2[0] = z3[0];
+ expected[0]= z1[0];
+ got[0] = z4[0];
+ printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
+ function.name, test_line_number, rnd_mode[rnd]);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex))
+ printf("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
+ MPC_OUT (op1);
+ MPC_OUT (op2);
+ printf (" ");
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+ if (function.properties & FUNC_PROP_SYMETRIC)
+ {
+ inex = function.pointer.C_CC (z4, z3, z2, rnd);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex)
+ || !same_mpc_value (z4, z1, signs))
+ {
+ /* display sensible variable names */
+ mpc_t op1, op2, got, expected;
+ op1[0] = z3[0];
+ op2[0] = z2[0];
+ expected[0]= z1[0];
+ got[0] = z4[0];
+ printf ("%s(op) failed (line %lu/symetric test)\n"
+ "with rounding mode %s\n",
+ function.name, test_line_number, rnd_mode[rnd]);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex))
+ printf("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
+ MPC_OUT (op1);
+ MPC_OUT (op2);
+ printf (" ");
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+ }
+ break;
+
+ case CCCC: /* example mpc_fma */
+ read_cccc (fp, &inex_re, &inex_im, z1, &signs, z2, z3, z4, &rnd);
+ /* z1 is the expected value, z2, z3, z4 are the inputs, and z5 is
+ the computed value */
+ mpfr_set_prec (mpc_realref(z5), MPC_PREC_RE (z1));
+ mpfr_set_prec (mpc_imagref(z5), MPC_PREC_IM (z1));
+ inex = function.pointer.CCCC (z5, z2, z3, z4, rnd);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex)
+ || !same_mpc_value (z5, z1, signs))
+ {
+ /* display sensible variable names */
+ mpc_t op1, op2, op3, got, expected;
+ op1[0] = z2[0];
+ op2[0] = z3[0];
+ op3[0] = z4[0];
+ expected[0]= z1[0];
+ got[0] = z5[0];
+ printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
+ function.name, test_line_number, rnd_mode[rnd]);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex))
+ printf("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
+ MPC_OUT (op1);
+ MPC_OUT (op2);
+ MPC_OUT (op3);
+ printf (" ");
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+ if (function.properties & FUNC_PROP_SYMETRIC)
+ {
+ inex = function.pointer.CCCC (z5, z3, z2, z4, rnd);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex)
+ || !same_mpc_value (z5, z1, signs))
+ {
+ /* display sensible variable names */
+ mpc_t op1, op2, op3, got, expected;
+ op1[0] = z3[0];
+ op2[0] = z2[0];
+ op3[0] = z4[0];
+ expected[0]= z1[0];
+ got[0] = z5[0];
+ printf ("%s(op) failed (line %lu/symetric test)\n"
+ "with rounding mode %s\n",
+ function.name, test_line_number, rnd_mode[rnd]);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex))
+ printf("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
+ MPC_OUT (op1);
+ MPC_OUT (op2);
+ MPC_OUT (op3);
+ printf (" ");
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+ }
+ break;
+
+ case CFC: /* example mpc_fr_div */
+ read_cfc (fp, &inex_re, &inex_im, z1, &signs, x1, z2, &rnd);
+ mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1));
+ mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1));
+ inex = function.pointer.CFC (z3, x1, z2, rnd);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex)
+ || !same_mpc_value (z3, z1, signs))
+ {
+ /* display sensible variable names */
+ mpc_t op2, got, expected;
+ mpfr_t op1;
+ op1[0] = x1[0];
+ op2[0] = z2[0];
+ expected[0]= z1[0];
+ got[0] = z3[0];
+ printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
+ function.name, test_line_number, rnd_mode[rnd]);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex))
+ printf("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
+ MPFR_OUT (op1);
+ MPC_OUT (op2);
+ printf (" ");
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+ break;
+
+ case CCF: /* example mpc_mul_fr */
+ read_ccf (fp, &inex_re, &inex_im, z1, &signs, z2, x1, &rnd);
+ mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1));
+ mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1));
+ inex = function.pointer.CCF (z3, z2, x1, rnd);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex)
+ || !same_mpc_value (z3, z1, signs))
+ {
+ /* display sensible variable names */
+ mpc_t op1, got, expected;
+ mpfr_t op2;
+ op1[0] = z2[0];
+ op2[0] = x1[0];
+ expected[0]= z1[0];
+ got[0] = z3[0];
+ printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
+ function.name, test_line_number, rnd_mode[rnd]);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex))
+ printf("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
+ MPC_OUT (op1);
+ MPFR_OUT (op2);
+ printf (" ");
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+ break;
+
+ case CCU: /* example mpc_pow_ui */
+ read_ccu (fp, &inex_re, &inex_im, z1, &signs, z2, &ui, &rnd);
+ mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1));
+ mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1));
+ inex = function.pointer.CCU (z3, z2, ui, rnd);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex)
+ || !same_mpc_value (z3, z1, signs))
+ {
+ /* display sensible variable names */
+ mpc_t op1, got, expected;
+ op1[0] = z2[0];
+ expected[0]= z1[0];
+ got[0] = z3[0];
+ printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
+ function.name, test_line_number, rnd_mode[rnd]);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex))
+ printf("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
+ MPC_OUT (op1);
+ printf ("op2 %lu\n ", ui);
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+ break;
+
+ case CCS: /* example mpc_pow_si */
+ read_ccs (fp, &inex_re, &inex_im, z1, &signs, z2, &si, &rnd);
+ mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1));
+ mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1));
+ inex = function.pointer.CCS (z3, z2, si, rnd);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex)
+ || !same_mpc_value (z3, z1, signs))
+ {
+ /* display sensible variable names */
+ mpc_t op1, got, expected;
+ op1[0] = z2[0];
+ expected[0]= z1[0];
+ got[0] = z3[0];
+ printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
+ function.name, test_line_number, rnd_mode[rnd]);
+ if (!MPC_INEX_CMP (inex_re, inex_im, inex))
+ printf("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
+ MPC_OUT (op1);
+ printf ("op2 %li\n ", si);
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+ break;
+
+ default:
+ printf ("Unhandled function prototype %i in 'data_check'\n", function.type);
+ exit (1);
+ }
+
+ /* check MPFR flags were not modified */
+ check_mpfr_flags (rand_counter);
+ rand_counter ++;
+ }
+
+ /* 3. Clear used variables */
+ mpc_clear (z1);
+ switch (function.type)
+ {
+ case FC:
+ mpfr_clear (x1);
+ mpfr_clear (x2);
+ break;
+ case CC: case CCU: case CCS:
+ mpc_clear (z2);
+ mpc_clear (z3);
+ break;
+ case C_CC:
+ mpc_clear (z2);
+ mpc_clear (z3);
+ mpc_clear (z4);
+ break;
+ case CCCC:
+ mpc_clear (z2);
+ mpc_clear (z3);
+ mpc_clear (z4);
+ mpc_clear (z5);
+ break;
+ case CFC: case CCF:
+ mpfr_clear (x1);
+ mpc_clear (z2);
+ mpc_clear (z3);
+ break;
+ default:
+ ;
+ }
+
+ close_data_file (fp);
+}
diff --git a/mpc/tests/sin.dat b/mpc/tests/sin.dat
new file mode 100644
index 0000000000..9831fa6590
--- /dev/null
+++ b/mpc/tests/sin.dat
@@ -0,0 +1,163 @@
+# Data file for mpc_sin.
+#
+# Copyright (C) 2008, 2010 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# where op = op_re + i * op_im, rop = rop_re + i * rop_im,
+# rop_re is ROP_RE rounded to nearest to the precision of PREC_ROP_RE
+# rop_im is ROP_IM rounded to nearest to the precision of PREC_ROP_IM
+# op_re is OP_RE rounded to nearest to the precision of PREC_OP_RE
+# op_im is OP_IM rounded to nearest to the precision of PREC_OP_IM
+# ROP_RE is checked against Re(sin op) rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against Im(sin op) rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# special values (following ISO C99 standard)
+0 0 53 nan 53 inf 53 -inf 53 -inf N N
+0 0 53 nan 53 nan 53 -inf 53 -1 N N
+0 0 53 nan 53 0 53 -inf 53 -0 N N
+0 0 53 nan 53 0 53 -inf 53 +0 N N
+0 0 53 nan 53 nan 53 -inf 53 +1 N N
+0 0 53 nan 53 inf 53 -inf 53 +inf N N
+0 0 53 nan 53 nan 53 -inf 53 nan N N
+0 0 53 +inf 53 -inf 53 -6 53 -inf N N
+0 0 53 +inf 53 +inf 53 -6 53 +inf N N
+0 0 53 nan 53 nan 53 -6 53 nan N N
+0 0 53 +inf 53 +inf 53 -4 53 -inf N N
+0 0 53 +inf 53 -inf 53 -4 53 +inf N N
+0 0 53 nan 53 nan 53 -4 53 nan N N
+0 0 53 -inf 53 +inf 53 -2 53 -inf N N
+0 0 53 -inf 53 -inf 53 -2 53 +inf N N
+0 0 53 nan 53 nan 53 -2 53 nan N N
+0 0 53 -inf 53 -inf 53 -1 53 -inf N N
+0 0 53 -inf 53 +inf 53 -1 53 +inf N N
+0 0 53 nan 53 nan 53 -1 53 nan N N
+0 0 53 -0 53 -inf 53 -0 53 -inf N N
+0 0 53 -0 53 -0 53 -0 53 -0 N N
+0 0 53 -0 53 +0 53 -0 53 +0 N N
+0 0 53 -0 53 +inf 53 -0 53 +inf N N
+0 0 53 -0 53 nan 53 -0 53 nan N N
+0 0 53 +0 53 -inf 53 +0 53 -inf N N
+0 0 53 +0 53 -0 53 +0 53 -0 N N
+0 0 53 +0 53 +0 53 +0 53 +0 N N
+0 0 53 +0 53 +inf 53 +0 53 +inf N N
+0 0 53 +0 53 nan 53 +0 53 nan N N
+0 0 53 +inf 53 -inf 53 +1 53 -inf N N
+0 0 53 +inf 53 +inf 53 +1 53 +inf N N
+0 0 53 nan 53 nan 53 +1 53 nan N N
+0 0 53 +inf 53 +inf 53 +2 53 -inf N N
+0 0 53 +inf 53 -inf 53 +2 53 +inf N N
+0 0 53 nan 53 nan 53 +2 53 nan N N
+0 0 53 -inf 53 +inf 53 +4 53 -inf N N
+0 0 53 -inf 53 -inf 53 +4 53 +inf N N
+0 0 53 nan 53 nan 53 +4 53 nan N N
+0 0 53 -inf 53 -inf 53 +6 53 -inf N N
+0 0 53 -inf 53 +inf 53 +6 53 +inf N N
+0 0 53 nan 53 nan 53 +6 53 nan N N
+0 0 53 nan 53 inf 53 +inf 53 -inf N N
+0 0 53 nan 53 nan 53 +inf 53 -1 N N
+0 0 53 nan 53 0 53 +inf 53 -0 N N
+0 0 53 nan 53 0 53 +inf 53 +0 N N
+0 0 53 nan 53 nan 53 +inf 53 +1 N N
+0 0 53 nan 53 inf 53 +inf 53 +inf N N
+0 0 53 nan 53 nan 53 +inf 53 nan N N
+0 0 53 nan 53 inf 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 0 53 nan 53 -0 N N
+0 0 53 nan 53 0 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 0 53 nan 53 inf 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# pure real argument
+- 0 53 0x4787C62AC28Bp-48 53 -0 53 -6 53 -0 N N
+- 0 53 0x4787C62AC28Bp-48 53 +0 53 -6 53 +0 N N
+- 0 53 0xC1BDCEEEE0F57p-52 53 +0 53 -4 53 -0 N N
+- 0 53 0xC1BDCEEEE0F57p-52 53 -0 53 -4 53 +0 N N
+- 0 53 -0xE8C7B7568DA23p-52 53 +0 53 -2 53 -0 N N
+- 0 53 -0xE8C7B7568DA23p-52 53 -0 53 -2 53 +0 N N
++ 0 53 -0xD76AA47848677p-52 53 -0 53 -1 53 -0 N N
++ 0 53 -0xD76AA47848677p-52 53 +0 53 -1 53 +0 N N
+- 0 53 0xD76AA47848677p-52 53 -0 53 +1 53 -0 N N
+- 0 53 0xD76AA47848677p-52 53 +0 53 +1 53 +0 N N
++ 0 53 0xE8C7B7568DA23p-52 53 +0 53 +2 53 -0 N N
++ 0 53 0xE8C7B7568DA23p-52 53 -0 53 +2 53 +0 N N
++ 0 53 -0xC1BDCEEEE0F57p-52 53 +0 53 +4 53 -0 N N
++ 0 53 -0xC1BDCEEEE0F57p-52 53 -0 53 +4 53 +0 N N
++ 0 53 -0x4787C62AC28Bp-48 53 -0 53 +6 53 -0 N N
++ 0 53 -0x4787C62AC28Bp-48 53 +0 53 +6 53 +0 N N
+
+# pure imaginary argument
+0 + 53 -0 53 -0x1936D22F67C805p-45 53 -0 53 -6 N N
+0 + 53 +0 53 -0x1936D22F67C805p-45 53 +0 53 -6 N N
+0 - 53 -0 53 -0x1B4A3803703631p-48 53 -0 53 -4 N N
+0 - 53 +0 53 -0x1B4A3803703631p-48 53 +0 53 -4 N N
+0 + 53 -0 53 -0x1D03CF63B6E19Fp-51 53 -0 53 -2 N N
+0 + 53 +0 53 -0x1D03CF63B6E19Fp-51 53 +0 53 -2 N N
+0 + 53 -0 53 -0x966CFE2275CC1p-51 53 -0 53 -1 N N
+0 + 53 +0 53 -0x966CFE2275CC1p-51 53 +0 53 -1 N N
+0 - 53 -0 53 0x966CFE2275CC1p-51 53 -0 53 +1 N N
+0 - 53 +0 53 0x966CFE2275CC1p-51 53 +0 53 +1 N N
+0 - 53 -0 53 0x1D03CF63B6E19Fp-51 53 -0 53 +2 N N
+0 - 53 +0 53 0x1D03CF63B6E19Fp-51 53 +0 53 +2 N N
+0 + 53 -0 53 0x1B4A3803703631p-48 53 -0 53 +4 N N
+0 + 53 +0 53 0x1B4A3803703631p-48 53 +0 53 +4 N N
+0 - 53 -0 53 0x1936D22F67C805p-45 53 -0 53 +6 N N
+0 - 53 +0 53 0x1936D22F67C805p-45 53 +0 53 +6 N N
+
+# IEEE-754 double precision
++ + 53 514 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 N N
++ + 53 514 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 N Z
++ + 53 514 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 N U
++ - 53 514 53 -0x8DBE5135A8CA9p-96 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 N D
+- + 53 0x100FFFFFFFFFFFp-43 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 Z N
+- + 53 0x100FFFFFFFFFFFp-43 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 Z Z
+- + 53 0x100FFFFFFFFFFFp-43 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 Z U
+- - 53 0x100FFFFFFFFFFFp-43 53 -0x8DBE5135A8CA9p-96 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 Z D
++ + 53 514 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 U N
++ + 53 514 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 U Z
++ + 53 514 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 U U
++ - 53 514 53 -0x8DBE5135A8CA9p-96 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 U D
+- + 53 0x100FFFFFFFFFFFp-43 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 D N
+- + 53 0x100FFFFFFFFFFFp-43 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 D Z
+- + 53 0x100FFFFFFFFFFFp-43 53 -0x11B7CA26B51951p-97 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 D U
+- - 53 0x100FFFFFFFFFFFp-43 53 -0x8DBE5135A8CA9p-96 53 0x3243F6A8885A3p-49 53 -0x1BBDD1808C59A3p-50 D D
+
+# huge values
++ + 53 +inf 53 +inf 53 0x4580CBF242683p-3 53 -0x1B3E8A3660D279p-3 N N
+- + 53 -inf 53 +inf 53 -0x1B3E8A3660D279p-3 53 0x4580CBF242683p-3 N N
diff --git a/mpc/tests/sinh.dat b/mpc/tests/sinh.dat
new file mode 100644
index 0000000000..51fd46e1fb
--- /dev/null
+++ b/mpc/tests/sinh.dat
@@ -0,0 +1,84 @@
+# Data file for mpc_sinh.
+#
+# Copyright (C) 2008, 2010 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see sin.dat.
+
+# special values (following ISO C99 standard)
+0 0 7 inf 7 NaN 7 -inf 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 -1 N N
+0 0 7 -inf 7 -0 7 -inf 7 -0 N N
+0 0 7 -inf 7 +0 7 -inf 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 1 N N
+0 0 7 inf 7 NaN 7 -inf 7 +inf N N
+0 0 7 inf 7 NaN 7 -inf 7 NaN N N
+0 0 7 NaN 7 NaN 7 -1 7 -inf N N
+0 0 7 NaN 7 NaN 7 -1 7 +inf N N
+0 0 7 NaN 7 NaN 7 -1 7 NaN N N
+0 0 7 0 7 NaN 7 -0 7 -inf N N
+0 0 7 -0 7 -0 7 -0 7 -0 N N
+0 0 7 -0 7 +0 7 -0 7 +0 N N
+0 0 7 0 7 NaN 7 -0 7 +inf N N
+0 0 7 0 7 NaN 7 -0 7 NaN N N
+0 0 7 0 7 NaN 7 +0 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 -0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 N N
+0 0 7 0 7 NaN 7 +0 7 +inf N N
+0 0 7 0 7 NaN 7 +0 7 NaN N N
+0 0 7 NaN 7 NaN 7 1 7 -inf N N
+0 0 7 NaN 7 NaN 7 1 7 +inf N N
+0 0 7 NaN 7 NaN 7 1 7 NaN N N
+0 0 7 inf 7 NaN 7 +inf 7 -inf N N
+0 0 7 +inf 7 -inf 7 +inf 7 -1 N N
+0 0 7 +inf 7 -0 7 +inf 7 -0 N N
+0 0 7 +inf 7 +0 7 +inf 7 +0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 1 N N
+0 0 7 inf 7 NaN 7 +inf 7 +inf N N
+0 0 7 inf 7 NaN 7 +inf 7 NaN N N
+0 0 7 NaN 7 NaN 7 NaN 7 -inf N N
+0 0 7 NaN 7 NaN 7 NaN 7 -1 N N
+0 0 7 NaN 7 -0 7 NaN 7 -0 N N
+0 0 7 NaN 7 +0 7 NaN 7 +0 N N
+0 0 7 NaN 7 NaN 7 NaN 7 1 N N
+0 0 7 NaN 7 NaN 7 NaN 7 +inf N N
+0 0 7 NaN 7 NaN 7 NaN 7 NaN N N
+
+# purely real argument
++ 0 50 -0x12cd9fc44eb98p-48 50 -0 7 -1 7 -0 N N
++ 0 50 -0x12cd9fc44eb98p-48 50 +0 7 -1 7 +0 N N
+- 0 50 0x12cd9fc44eb98p-48 50 -0 7 1 7 -0 N N
+- 0 50 0x12cd9fc44eb98p-48 50 +0 7 1 7 +0 N N
+
+# purely imaginary argument
+0 - 50 -0 50 -0xd76aa47848678p-52 7 -0 7 -1 N N
+0 + 50 -0 50 0xd76aa47848678p-52 7 -0 7 1 N N
+0 - 50 +0 50 -0xd76aa47848678p-52 7 +0 7 -1 N N
+0 + 50 +0 50 0xd76aa47848678p-52 7 +0 7 1 N N
+
+# values with +1 and -1
++ - 50 -0xa28cfec023fc8p-52 50 -0x14c67b74f6cc5p-48 7 -1 7 -1 N N
++ + 50 -0xa28cfec023fc8p-52 50 0x14c67b74f6cc5p-48 7 -1 7 1 N N
+- - 50 0xa28cfec023fc8p-52 50 -0x14c67b74f6cc5p-48 7 1 7 -1 N N
+- + 50 0xa28cfec023fc8p-52 50 0x14c67b74f6cc5p-48 7 1 7 1 N N
+
+# IEEE-754 double precision
+- - 53 0xF48D4FDF29C53p-105 53 2 53 0x15124271980435p-52 53 0x3243F6A8885A3p-49 N N
+
+# huge values
++ - 53 +inf 53 -inf 53 0x4580CBF242683p-3 53 -0x1B3E8A3660D279p-3 N N
++ + 53 +inf 53 +inf 53 -0x1B3E8A3660D279p-3 53 0x4580CBF242683p-3 N N
diff --git a/mpc/tests/sqr.dat b/mpc/tests/sqr.dat
new file mode 100644
index 0000000000..72bfe076fc
--- /dev/null
+++ b/mpc/tests/sqr.dat
@@ -0,0 +1,170 @@
+# Data file for mpc_sqr.
+#
+# Copyright (C) 2008, 2010, 2012 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# see sin.dat for precisions
+
+# special values (following ISO C99 standard)
+0 0 53 nan 53 +inf 53 -inf 53 -inf N N
+0 0 53 +inf 53 +inf 53 -inf 53 -1 N N
+0 0 53 +inf 53 nan 53 -inf 53 -0 N N
+0 0 53 +inf 53 nan 53 -inf 53 +0 N N
+0 0 53 +inf 53 -inf 53 -inf 53 +1 N N
+0 0 53 nan 53 -inf 53 -inf 53 +inf N N
+0 0 53 nan 53 nan 53 -inf 53 nan N N
+0 0 53 -inf 53 +inf 53 -1 53 -inf N N
+0 0 53 +1 53 +0 53 -1 53 -0 N N
+0 0 53 +1 53 -0 53 -1 53 +0 N N
+0 0 53 -inf 53 -inf 53 -1 53 +inf N N
+0 0 53 nan 53 nan 53 -1 53 nan N N
+0 0 53 -inf 53 nan 53 -0 53 -inf N N
+0 0 53 -1 53 +0 53 -0 53 -1 N N
+0 0 53 0 53 +0 53 -0 53 -0 N N
+0 0 53 0 53 -0 53 -0 53 +0 N N
+0 0 53 -1 53 -0 53 -0 53 +1 N N
+0 0 53 -inf 53 nan 53 -0 53 +inf N N
+0 0 53 nan 53 nan 53 -0 53 nan N N
+0 0 53 -inf 53 nan 53 +0 53 -inf N N
+0 0 53 -1 53 -0 53 +0 53 -1 N N
+0 0 53 0 53 -0 53 +0 53 -0 N N
+0 0 53 0 53 +0 53 +0 53 +0 N N
+0 0 53 -1 53 +0 53 +0 53 +1 N N
+0 0 53 -inf 53 nan 53 +0 53 +inf N N
+0 0 53 nan 53 nan 53 +0 53 nan N N
+0 0 53 -inf 53 -inf 53 +1 53 -inf N N
+0 0 53 +1 53 -0 53 +1 53 -0 N N
+0 0 53 +1 53 +0 53 +1 53 +0 N N
+0 0 53 -inf 53 +inf 53 +1 53 +inf N N
+0 0 53 nan 53 nan 53 +1 53 nan N N
+0 0 53 nan 53 -inf 53 +inf 53 -inf N N
+0 0 53 +inf 53 -inf 53 +inf 53 -1 N N
+0 0 53 +inf 53 nan 53 +inf 53 -0 N N
+0 0 53 +inf 53 nan 53 +inf 53 +0 N N
+0 0 53 +inf 53 +inf 53 +inf 53 +1 N N
+0 0 53 nan 53 +inf 53 +inf 53 +inf N N
+0 0 53 nan 53 nan 53 +inf 53 nan N N
+0 0 53 nan 53 nan 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 nan 53 nan 53 -0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 0 53 nan 53 nan 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# pure real argument
++ 0 53 0x12345676543230p+52 2 +0 53 0x1111111000000f 17 +0 N N
+- 0 53 0x1234567654322fp+52 3 -0 54 -0x1111111000000f 16 +0 Z N
++ 0 53 0x12345676543230p+52 4 -0 55 0x1111111000000f 15 -0 U N
+- 0 53 0x1234567654322fp+52 5 +0 56 -0x1111111000000f 14 -0 D N
+- 0 53 0x1234567654322fp+52 6 +0 57 0x1111111000000f 13 +0 Z Z
++ 0 53 0x12345676543230p+52 7 -0 58 -0x1111111000000f 12 +0 U Z
+- 0 53 0x1234567654322fp+52 8 -0 59 0x1111111000000f 11 -0 D Z
++ 0 53 0x12345676543230p+52 9 +0 60 -0x1111111000000f 10 -0 N Z
++ 0 53 0x12345676543230p+52 10 +0 61 0x1111111000000f 9 +0 U U
+- 0 53 0x1234567654322fp+52 11 -0 62 -0x1111111000000f 8 +0 D U
++ 0 53 0x12345676543230p+52 12 -0 63 0x1111111000000f 7 -0 N U
+- 0 53 0x1234567654322fp+52 13 +0 64 -0x1111111000000f 6 -0 Z U
+- 0 53 0x1234567654322fp+52 14 +0 65 0x1111111000000f 5 +0 D D
++ 0 53 0x12345676543230p+52 15 -0 66 -0x1111111000000f 4 +0 N D
+- 0 53 0x1234567654322fp+52 16 -0 67 0x1111111000000f 3 -0 Z D
++ 0 53 0x12345676543230p+52 17 +0 68 -0x1111111000000f 2 -0 U D
+
+# pure imaginary argument
+- 0 53 -0xE1000002000000p+56 53 +0 53 +0 53 0xf0000001111111 N N
++ 0 53 -0xe1000001fffff8p+56 52 -0 51 -0 54 0xf0000001111111 Z N
++ 0 53 -0xe1000001fffff8p+56 51 -0 49 +0 55 -0xf0000001111111 U N
+- 0 53 -0xe1000002000000p+56 50 +0 47 -0 56 -0xf0000001111111 D N
++ 0 53 -0xe1000001fffff8p+56 49 +0 45 +0 57 0xf0000001111111 Z Z
++ 0 53 -0xe1000001fffff8p+56 48 -0 43 -0 58 0xf0000001111111 U Z
+- 0 53 -0xe1000002000000p+56 47 -0 41 +0 59 -0xf0000001111111 D Z
+- 0 53 -0xe1000002000000p+56 46 +0 39 -0 60 -0xf0000001111111 N Z
++ 0 53 -0xe1000001fffff8p+56 45 +0 37 +0 61 0xf0000001111111 U U
+- 0 53 -0xe1000002000000p+56 44 -0 35 -0 62 0xf0000001111111 D U
+- 0 53 -0xe1000002000000p+56 43 -0 33 +0 63 -0xf0000001111111 N U
++ 0 53 -0xe1000001fffff8p+56 42 +0 31 -0 64 -0xf0000001111111 Z U
+- 0 53 -0xe1000002000000p+56 41 +0 29 +0 65 0xf0000001111111 D D
+- 0 53 -0xe1000002000000p+56 40 -0 27 -0 66 0xf0000001111111 N D
++ 0 53 -0xe1000001fffff8p+56 39 -0 25 +0 67 -0xf0000001111111 Z D
++ 0 53 -0xe1000001fffff8p+56 38 +0 23 -0 68 -0xf0000001111111 U D
+
+# IEEE-754 double precision
+- + 53 0x10000000020000p+04 53 0x10000000effff 53 0x400008000180fp-22 53 0x7ffff0077efcbp-32 N N
+- - 53 0x3ffffffffffffd 53 0x7ffffffffffff4p+52 53 0x1fffffffffffff 53 0x1ffffffffffffe Z N
++ + 53 0x1c16e5d4c4d5e7p-45 53 -0x7ffffff800007p-47 53 0xf 53 -0x1111111000000fp-53 U N
+- + 53 0xfdbac097c8dc50p+2096 53 0x7f6e5d4c3b2a2p+1036 53 0xfedcba9876543p+1024 53 0x10000000000001p-42 D N
++ - 53 -0x10000000020000p+04 53 0x10000000efffefp-04 53 0x7ffff0077efcbp-32 53 0x400008000180fp-22 Z Z
++ + 53 0x3ffffffffffffe 53 -0x7ffffffffffff4p+52 53 0x1fffffffffffff 53 -0x1ffffffffffffe U Z
+- - 53 0xe0b72ea626af3p-44 53 0x7ffffff800007p-47 53 0xf 53 0x1111111000000fp-53 D Z
+- - 53 -0xfdbac097c8dc58p+2096 53 0x7f6e5d4c3b2a1cp+1032 53 -0x10000000000001p-42 53 -0xfedcba9876543p+1024 N Z
++ + 53 0x10000000020001p+04 53 -0x10000000efffefp-04 53 0x400008000180fp-22 53 -0x7ffff0077efcbp-32 U U
+- + 53 -0x3ffffffffffffe 53 -0x7ffffffffffff4p+52 53 -0x1ffffffffffffe 53 0x1fffffffffffff D U
+- + 53 -0x1C16E5D4C4D5E7p-45 53 0x1ffffffe00001dp-49 53 -0x1111111000000fp-53 53 -0xf N U
++ + 53 -0xfdbac097c8dc50p+2096 53 -0x7f6e5d4c3b2a1cp+1032 53 0x10000000000001p-42 53 -0xfedcba9876543p+1024 Z U
+- - 53 -0x10000000020001p+04 53 -0x10000000effff 53 -0x7ffff0077efcbp-32 53 0x400008000180fp-22 D D
+- - 53 0x3ffffffffffffd 53 -0x7ffffffffffff8p+52 53 -0x1fffffffffffff 53 0x1ffffffffffffe N D
++ - 53 -0xE0B72EA626AF3p-44 53 -0x1FFFFFFE00001Dp-49 53 0x1111111000000fp-53 53 -0xf Z D
++ - 53 0xfdbac097c8dc58p+2096 53 -0x7f6e5d4c3b2a2p+1036 53 -0xfedcba9876543p+1024 53 0x10000000000001p-42 U D
+
+# improve test coverage:
+# For op=x+i*y, we need a case where x+y and x-y are inexact at the
+# higher computing precision, and where x and y do not have too
+# distinct exponents so that Karatsuba gets triggered...
+# (2^44 + i*(2^29 + 1))^2 \approx (2^88-2^58) + i*2^45*(2^29+1)
++ 0 30 309485009533114692573069312 30 18889465966662952943616 30 17592186044416 30 536870913 N N
+# ...and a case where x+y or x-y are 0.
+0 0 4 0 4 2 4 1 4 1 N N
+
+# a few values, previously hard-coded in tsqr.c
+0 0 8 7 8 24 8 4 8 3 N N
++ + 8 0b1.1000111e-3 8 0b1.1100111e-3 27 0b1.11111011011000010101000000e-2 27 0b1.11010001010110111001110001e-3 N N
+
+# bug 20090930, infinite loop
++ + 3464 inf 3464 inf 866 -0x2.5763c6519ef1510f8afa101a210b8030b1909cc17004db561a25d9b53e2c08c41c01e8bbac5af6299b9d8786030aa14943d841798c8c369287942e4d4cec42a60ab0922af931159805e631128e97f973754ad53972d5d320a651a3b4a667f0ef2b92dbd698d159c3642675140@192158913 866 -0xd.15f2d530934dd930d66e89d70762d2337a8f973dd6915eb6b532fd372fcc955df1d852632d4e46fe64154ceda991a1302caf1b0ec622497e3e5724dd05b1c89a06e28d7e18e8af58f5ff4c9998cb31714688867524f41e0b31e847c1bf40de5127f858069998efd7c3e599080@192158893 N N
+
+# bug 20091001, infinite loop
+? + 2256 0 2256 -0 564 0xc.87999bfd1cb1a64288881e214b7cf1af979863b23c030b79c4a8bebb39177967608388a2e4df527977e7755a25df8af8f72fdd6dd2f42bd00de83088b4e9b59ce85caf2e6b0c0@-184298749 564 -0x2.5109af459d4daf357e09475ec991cdc9b02c8f7dfacdc060d2a24710d09c997f8aea6dbd46f10828c30b583fdcc90d7dcbb895689d594d3813db40784d2309e450d1fb6e38da8@-184298726 N N
+
+# (x+x*i)^2 = 0+2*x^2*i with exact real part
+0 0 100 0 100 304831530559368 100 12345678 100 12345678 N N
+0 0 1000 0 100 304831530559368 100 12345678 100 12345678 N N
+# intermediate overflow- and underflows
+0 + 100 0 100 +inf 100 0x1@225000750 100 0x1@225000750 N N
+0 + 10000 0 10000 +inf 100 0x1@225000750 100 0x1@225000750 N N
+0 - 100 0 100 +0 100 0x1@-225000750 100 0x1@-225000750 N N
+0 + 100 0 100 -0 100 0x1@-225000750 100 -0x1@-225000750 N N
+0 - 10000 0 10000 +0 100 0x1@-225000750 100 0x1@-225000750 N N
+0 + 10000 0 10000 -0 100 0x1@-225000750 100 -0x1@-225000750 N N
+
+# intermediate overflow in Karatsuba found by hydra, simplified test case
+- - 100 -inf 100 -inf 593 -0xf@192058806 593 0x1@192058873 N N
+# another interesting one with not exactly the same behaviour
+- - 100 -inf 100 -inf 100 -0xf@192058806 100 0x1@192058873 N N
+0 + 100 0 100 inf 100 0x1@192058806 100 0x1@192058806 N N
+# Re(op)*Im(op) can be computed, but multiplication by 2 triggers overflow
+0 + 100 0 100 inf 100 0b1@536870911 100 0b1@536870911 N N
+0 - 10 0 10 0b1.111111111e1073741822 100 0b1@536870911 100 0b1@536870911 N D
+0 - 10 0 10 0b1.111111111e1073741822 100 0b1@536870912 100 0b1@536870912 N D
+0 0 10 0 10 0b1e-1073741823 100 0b1@-536870912 100 0b1@-536870912 N N
+0 - 10 0 10 0 100 0b1@-536870913 100 0b1@-536870913 N N
+0 + 10 0 10 0b1@-1073741824 100 0b1@-536870913 100 0b1@-536870913 N U
++ - 10 0b1e-1073741824 10 0 100 0b1@-536870912 100 0b1@-536870913 N N
diff --git a/mpc/tests/sqrt.dat b/mpc/tests/sqrt.dat
new file mode 100644
index 0000000000..076f2afadc
--- /dev/null
+++ b/mpc/tests/sqrt.dat
@@ -0,0 +1,139 @@
+# Data file for mpc_sqrt.
+#
+# Copyright (C) 2008, 2010 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP_RE OP_RE PREC_OP_IM OP_IM RND_RE RND_IM
+#
+# see sin.dat for precisions
+
+# special values (following ISO C99 standard)
+0 0 53 +inf 53 -inf 53 -inf 53 -inf N N
+0 0 53 +0 53 -inf 53 -inf 53 -1 N N
+0 0 53 +0 53 -inf 53 -inf 53 -0 N N
+0 0 53 +0 53 +inf 53 -inf 53 +0 N N
+0 0 53 +0 53 +inf 53 -inf 53 +1 N N
+0 0 53 +inf 53 +inf 53 -inf 53 +inf N N
+0 0 53 nan 53 inf 53 -inf 53 nan N N
+0 0 53 +inf 53 -inf 53 -1 53 -inf N N
+0 0 53 +0 53 -1 53 -1 53 -0 N N
+0 0 53 +0 53 +1 53 -1 53 +0 N N
+0 0 53 +inf 53 +inf 53 -1 53 +inf N N
+0 0 53 nan 53 nan 53 -1 53 nan N N
+0 0 53 +inf 53 -inf 53 -0 53 -inf N N
+0 0 53 +1 53 -1 53 -0 53 -2 N N
+0 0 53 +0 53 -0 53 -0 53 -0 N N
+0 0 53 +0 53 +0 53 -0 53 +0 N N
+0 0 53 +1 53 +1 53 -0 53 +2 N N
+0 0 53 +inf 53 +inf 53 -0 53 +inf N N
+0 0 53 nan 53 nan 53 -0 53 nan N N
+0 0 53 +inf 53 -inf 53 +0 53 -inf N N
+0 0 53 +1 53 -1 53 +0 53 -2 N N
+0 0 53 +0 53 -0 53 +0 53 -0 N N
+0 0 53 +0 53 +0 53 +0 53 +0 N N
+0 0 53 +1 53 +1 53 +0 53 +2 N N
+0 0 53 +inf 53 +inf 53 +0 53 +inf N N
+0 0 53 nan 53 nan 53 +0 53 nan N N
+0 0 53 +inf 53 -inf 53 +1 53 -inf N N
+0 0 53 +1 53 -0 53 +1 53 -0 N N
+0 0 53 +1 53 +0 53 +1 53 +0 N N
+0 0 53 +inf 53 +inf 53 +1 53 +inf N N
+0 0 53 nan 53 nan 53 +1 53 nan N N
+0 0 53 +inf 53 -inf 53 +inf 53 -inf N N
+0 0 53 +inf 53 -0 53 +inf 53 -1 N N
+0 0 53 +inf 53 -0 53 +inf 53 -0 N N
+0 0 53 +inf 53 +0 53 +inf 53 +0 N N
+0 0 53 +inf 53 +0 53 +inf 53 +1 N N
+0 0 53 +inf 53 +inf 53 +inf 53 +inf N N
+0 0 53 +inf 53 nan 53 +inf 53 nan N N
+0 0 53 +inf 53 -inf 53 nan 53 -inf N N
+0 0 53 nan 53 nan 53 nan 53 -1 N N
+0 0 53 nan 53 nan 53 nan 53 -0 N N
+0 0 53 nan 53 nan 53 nan 53 +0 N N
+0 0 53 nan 53 nan 53 nan 53 +1 N N
+0 0 53 +inf 53 +inf 53 nan 53 +inf N N
+0 0 53 nan 53 nan 53 nan 53 nan N N
+
+# purely real argument
+# sqrt(x +i*0) = sqrt(x) +i*0, when x>0
+# sqrt(x -i*0) = sqrt(x) -i*0, when x>0
+# sqrt(x +i*0) = +0 +i*sqrt(-x) +i*0, when x<0
+# sqrt(x -i*0) = +0 -i*sqrt(-x) +i*0, when x<0
++ 0 53 0x16a09e667f3bcdp-52 53 +0 53 2 17 +0 N N
+0 + 53 +0 53 0x16a09e667f3bcdp-52 54 -2 16 +0 Z N
++ 0 53 0x16a09e667f3bcdp-52 53 -0 55 2 15 -0 U N
+0 - 53 +0 53 -0x16a09e667f3bcdp-52 56 -2 14 -0 D N
+- 0 53 0x5a827999fcef30p-54 53 +0 57 2 13 +0 Z Z
+0 - 53 +0 53 0x5a827999fcef30p-54 58 -2 12 +0 U Z
+- 0 53 0x5a827999fcef30p-54 53 -0 59 2 11 -0 D Z
+0 + 53 +0 53 -0x5a827999fcef30p-54 60 -2 10 -0 N Z
++ 0 53 0x16a09e667f3bcdp-52 53 +0 61 2 9 +0 U U
+0 + 53 +0 53 0x16a09e667f3bcdp-52 62 -2 8 +0 D U
++ 0 53 0x16a09e667f3bcdp-52 53 -0 63 2 7 -0 N U
+0 + 53 +0 53 -0x5a827999fcef30p-54 64 -2 6 -0 Z U
+- 0 53 0x5a827999fcef30p-54 53 +0 65 2 5 +0 D D
+0 - 53 +0 53 0x5a827999fcef30p-54 66 -2 4 +0 N D
+- 0 53 0x5a827999fcef30p-54 53 -0 67 2 3 -0 Z D
+0 - 53 +0 53 -0x16a09e667f3bcdp-52 68 -2 2 -0 U D
+
+# purely imaginary argument
+# sqrt(+/-0 +i*y) = sqrt(y/2) * (1 +i), when y >0
+# sqrt(+/-0 +i*y) = sqrt(-y/2) * (1 -i), when y < 0
++ + 53 0x16a09e667f3bcdp-52 53 0x16a09e667f3bcdp-52 53 +0 53 4 N N
+- + 53 0x5a827999fcef30p-54 53 0x16a09e667f3bcdp-52 51 -0 54 4 Z N
++ - 53 0x16a09e667f3bcdp-52 53 -0x16a09e667f3bcdp-52 49 +0 55 -4 U N
+- - 53 0x5a827999fcef30p-54 53 -0x16a09e667f3bcdp-52 47 -0 56 -4 D N
+- - 53 0x5a827999fcef30p-54 53 0x5a827999fcef30p-54 45 +0 57 4 Z Z
++ - 53 0x16a09e667f3bcdp-52 53 0x5a827999fcef30p-54 43 -0 58 4 U Z
+- + 53 0x5a827999fcef30p-54 53 -0x5a827999fcef30p-54 41 +0 59 -4 D Z
++ + 53 0x16a09e667f3bcdp-52 53 -0x5a827999fcef30p-54 39 -0 60 -4 N Z
++ + 53 0x16a09e667f3bcdp-52 53 0x16a09e667f3bcdp-52 37 +0 61 4 U U
+- + 53 0x5a827999fcef30p-54 53 0x16a09e667f3bcdp-52 35 -0 62 4 D U
++ + 53 0x16a09e667f3bcdp-52 53 -0x5a827999fcef30p-54 33 +0 63 -4 N U
+- + 53 0x5a827999fcef30p-54 53 -0x5a827999fcef30p-54 31 -0 64 -4 Z U
+- - 53 0x5a827999fcef30p-54 53 0x5a827999fcef30p-54 29 +0 65 4 D D
++ - 53 0x16a09e667f3bcdp-52 53 0x5a827999fcef30p-54 27 -0 66 4 N D
+- - 53 0x5a827999fcef30p-54 53 -0x16a09e667f3bcdp-52 25 +0 67 -4 Z D
++ - 53 0x16a09e667f3bcdp-52 53 -0x16a09e667f3bcdp-52 23 -0 68 -4 U D
+
+# bugs fixed in r160 2008-07-15
+- + 19 0b11101001001001001100p+39 19 -0b1010110101100111011p-236 19 0b1.101010001010100000p+117 19 -0b1.001110111101100001p-158 N Z
+- + 2 0b11p+100 2 -0b11p+100 2 -0 2 -0b11p+203 N Z
+0 + 2 0 2 -0b10p+117 2 -0b11p+235 2 -0 N Z
+
+# close to infinite loop reported by Emmanuel Thome, 22 Oct 2010,
+# and all its variants of signs and directed roundings
+- + 375 1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281177 375 1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 N N
++ + 375 0x1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281177 375 1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 U U
+- - 375 1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef5fffffffffffffffffffffffffffffffffffffffffffep-202281177 375 1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 D D
+- + 375 1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef5fffffffffffffffffffffffffffffffffffffffffffep-202281177 375 1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 D U
+- - 375 1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef5fffffffffffffffffffffffffffffffffffffffffffep-202281177 375 1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 Z Z
+- - 375 1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281177 375 1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 N N
++ + 375 0x1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef5fffffffffffffffffffffffffffffffffffffffffffep-202281177 375 1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 U U
+- - 375 1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281177 375 1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 D D
+- + 375 1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef5fffffffffffffffffffffffffffffffffffffffffffep-202281177 375 1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 Z Z
++ - 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281177 375 1 375 -1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 N N
++ + 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281177 375 0x1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 375 -1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 U U
+- - 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef5fffffffffffffffffffffffffffffffffffffffffffep-202281177 375 1 375 -1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 D D
+- - 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef5fffffffffffffffffffffffffffffffffffffffffffep-202281177 375 1 375 -1 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 Z Z
++ + 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281177 375 -1 375 -1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 N N
++ + 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281177 375 -1 375 -1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 U U
+- - 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef5fffffffffffffffffffffffffffffffffffffffffffep-202281177 375 -0x1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 375 -1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 D D
+- + 375 0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef5fffffffffffffffffffffffffffffffffffffffffffep-202281177 375 -1 375 -1 375 -0xf.8a8aae3080b3dd665e316d262fd54c1ca22a83dc9acb92ef6p-202281176 Z Z
diff --git a/mpc/tests/strtoc.dat b/mpc/tests/strtoc.dat
new file mode 100644
index 0000000000..e69e4b6f3e
--- /dev/null
+++ b/mpc/tests/strtoc.dat
@@ -0,0 +1,168 @@
+# Data file for mpc_strtoc.
+#
+# Copyright (C) 2009 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The format respects the parameter order in function prototype as follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM "NSTRING" "RSTRING" BASE RND_RE RND_IM
+#
+# The string NSTRING is considered as a complex number rop = rop1 + i*rop2
+# written in base BASE. The remainder of the string, i.e. non-whitespace
+# characters being not part of the number, is equal to RSTRING.
+#
+# ROP_RE is checked against rop1 rounded to the precision PREC_ROP_RE
+# in the direction RND_RE
+# ROP_IM is checked against rop2 rounded to the precision PREC_ROP_IM
+# in the direction RND_IM
+# INEX_RE is the ternary value for the real part with the following notation:
+# "?" ternary value not checked
+# "!" function should return error indicator -1
+# "+" if ROP_RE is greater than the exact mathematical result
+# "0" if ROP_RE is exactly the mathematical result
+# "-" if ROP_RE is less than the exact mathematical result
+# (m.m. INEX_IM)
+# rounding modes notation:
+# "N" is rounding to nearest
+# "Z" is rounding towards zero
+# "U" is rounding towards plus infinity
+# "D" is rounding towards minus infinity
+# Use prefixes "0b" for values in base two, "0x" for values in base sixteen,
+# no prefix for value in base ten.
+# In all bases, "nan" is NaN, "inf" is infinity;
+# The sign of the result is checked with "+inf", "-inf", "-0", or "+0".
+
+# invalid base
+! ! 53 nan 53 nan "(1 1)" "(1 1)" 99 N N
+! ! 53 nan 53 nan "(1 1)" "(1 1)" 1 N N
+
+# invalid strings
+! ! 53 nan 53 nan "" "" 10 N N
+! ! 53 nan 53 nan "non" "non" 10 N N
+! ! 53 nan 53 nan "NON" "NON" 10 N N
+! ! 53 nan 53 nan "N A N" "N A N" 10 N N
+! ! 53 nan 53 nan "(1) 1" "(1) 1" 10 N N #no imaginary part
+! ! 53 nan 53 nan "." "." 10 N N
+! ! 53 nan 53 nan ". 1" ". 1" 10 N N #no space allowed here
+! ! 53 nan 53 nan "+ 1" "+ 1" 2 N N #no space allowed here
+! ! 53 nan 53 nan "+3 " "+3 " 2 N N #invalid digit
+! ! 53 nan 53 nan "+ INF " "+ INF " 10 N N #no space allowed here
+! ! 53 nan 53 nan "( +INF)" "( +INF)" 10 N N
+! ! 53 nan 53 nan "(1 +1 " "(1 +1 " 10 N N
+! ! 53 nan 53 nan "(1+1)" "(1+1)" 10 N N
+! ! 53 nan 53 nan "(1 + 1)" "(1 + 1)" 10 N N
+! ! 53 nan 53 nan "(@nan@(quiet)" "(@nan@(quiet)" 10 N N
+! ! 53 nan 53 nan "zero" "zero" 10 N N
+! ! 53 nan 53 nan "&^+" "&^+" 10 N N
+! ! 53 nan 53 nan "i" "i" 18 N N
+! ! 53 nan 53 nan "I" "I" 18 N N
+! ! 53 nan 53 nan "z" "z" 35 N N
+! ! 53 nan 53 nan "Z" "Z" 35 N N
+! ! 53 nan 53 nan "(i 0)" "(i 0)" 18 N N
+! ! 53 nan 53 nan "(I 0)" "(I 0)" 18 N N
+! ! 53 nan 53 nan "(z 0)" "(z 0)" 35 N N
+! ! 53 nan 53 nan "(Z 0)" "(Z 0)" 35 N N
+! ! 53 nan 53 nan "(0 i)" "(0 i)" 18 N N
+! ! 53 nan 53 nan "(0 I)" "(0 I)" 18 N N
+! ! 53 nan 53 nan "(0 z)" "(0 z)" 35 N N
+! ! 53 nan 53 nan "(0 Z)" "(0 Z)" 35 N N
+
+# special values
+0 0 53 nan 53 +0 "nan" "" 10 N N
+0 0 53 +nan 53 +0 "+NAN" "" 10 N N
+0 0 53 nan 53 +0 " @NAN@ " " " 10 N N
+0 0 53 nan 53 nan "(@nan@(QUIET) nan)" "" 10 N N
+0 0 53 nan 53 +0 "@nan@(quiet" "(quiet" 10 N N
+0 0 53 nan 53 +0 "NaN((keep out))" "((keep out))" 10 N N
+0 0 53 nan 53 +0 "nan(0 1)" "(0 1)" 10 N N
+0 0 53 nan 53 +0 "nan(0-1)" "(0-1)" 10 N N
+0 0 53 nan 53 +0 "nan(0_1)" "" 10 N N
+0 0 53 nan 53 +0 " nan nan nan nan" " nan nan nan" 10 N N
+0 0 53 inf 53 +0 "inf" "" 10 N N
+0 0 53 -inf 53 +0 "-inf" "" 10 N N
+0 0 53 +inf 53 +0 " infinity" "" 10 N N
+0 0 53 +inf 53 +0 "+INF x" " x" 10 N N
+0 0 53 +0 53 +inf "(0 +inf)" "" 10 N N
+0 0 53 +0 53 +inf " (+0 INF) " " " 10 N N
+0 0 53 +0 53 -inf "(0 -infinity)" "" 10 N N
+0 0 53 +0 53 -inf " (+0 -INF)" "" 10 N N
+0 0 53 -inf 53 -0 " (-@inf@ -0)" "" 10 N N
+0 0 53 +inf 53 nan "(+inf nan(9u137)) " " " 10 N N
+0 0 53 nan 53 +0 "NaN + inf" " + inf" 10 N N
+
+# pure real argument
+0 0 53 +0 53 +0 "0" "" 10 N N
+0 0 53 +0 53 +0 "00000" "" 10 N N
+0 0 53 +0 53 +0 "+0" "" 10 N N
+0 0 53 -0 53 +0 "-0" "" 10 N N
+0 0 53 +1 53 +0 "1" "" 10 N N
+0 0 53 +1 53 +0 "001" "" 10 N N
+0 0 53 +1 53 +0 "1 +1" " +1" 10 N N
+0 0 53 +1 53 +0 "1a" "a" 10 N N
+0 0 53 +1 53 +0 "1e-" "e-" 10 N N
+0 0 53 +1 53 +0 "1+2" "+2" 10 N N
+- 0 53 +0x9D70A3D70A3D7p-51 53 +0 "(+1.23 0.0)" "" 10 N N
+0 0 53 -10 53 +0 "(-10. 0000) " " " 10 N N
+0 0 53 +0x5p-3 53 -0 "(.625 -0)" "" 10 N N
+- 0 53 +0x14E718D7D7625Ap+612 53 +0 "(1e200 0)" "" 10 N N
+0 0 53 +0x7530 53 +0 " (3e+4 0)" "" 10 N N
+- 0 53 +0x10C6F7A0B5ED8Dp-73 53 +0 ".5e-6" "" 10 N N
+- 0 53 +0x1B1C1E0D914133p-83 53 +0 "(7.89E-10 0)" "" 10 N N
++ 0 53 -0x7B426FAB61F00Cp+56 53 +0 " -25@+32" "" 10 N N
+0 0 53 -25 53 +0 "-25p+32" "p+32" 10 N N
+0 0 53 +43981 53 +0 "0xabcd" "" 16 N N
+0 0 53 +0 53 +0 "0xabcd" "xabcd" 10 N N #no prefix in base ten
+0 0 53 +2 53 +0 "+0b010" "" 2 N N
+0 0 53 +0 53 +0 "+0b010" "b010" 10 N N #no prefix in base ten
+0 0 53 +1 53 +0 "1*i" "*i" 10 N N
+0 0 53 +18 53 +0 "i*i" "*i" 20 N N
+0 0 53 18 53 0 "i" "" 19 N N
+0 0 53 35 53 0 "z" "" 36 N N
+0 0 53 35 53 0 "Z" "" 36 N N
+
+# pure imaginary argument
+0 0 53 +0 53 +1 "(0 1)" "" 10 N N
+0 0 53 +0 53 +1 "(0 +1)" "" 20 N N
+0 0 53 -0 53 -1 " (-0 -1)" "" 10 N N
+0 0 53 -0 53 -2 "(-0 -2) " " " 10 N N
+0 0 53 +0 53 +2 "(+0 2)" "" 10 N N
+0 0 53 +0 53 +17 "(0 h)" "" 20 N N
+0 0 53 +0 53 +18 "(0 i)" "" 20 N N
+0 + 53 +0 53 -0x14F800008637BDp-44 "(0 -33.55000005e+1)" "" 10 N Z
+0 + 53 +0 53 -0xA1765976008AFp-401 "(+0 -.550000E-105) " " " 10 N U
+0 0 53 0 53 18 "(0 i)" "" 19 N N
+0 0 53 0 53 18 "(0 I)" "" 19 N N
+0 0 53 0 53 35 "(0 z)" "" 36 N N
+0 0 53 0 53 35 "(0 Z)" "" 36 N N
+
+# complex argument
+0 0 53 +1 53 +1 "( 1 +1)" "" 10 N N
+0 0 53 +1 53 +1 " (1 +1) " " " 10 N N
+0 0 53 +7 53 +14 "(7 14)" "" 10 N N
+0 0 53 +17 53 +1 "(+17 1)" "" 10 N N
+0 0 53 +27 53 +1 " (+17 +1)" "" 20 N N
+0 0 53 -18 53 -1 "(-i -1)" "" 20 N N
+0 0 53 +18 53 -1 "(i -1)" "" 20 N N
+0 0 53 -18 53 +1 "(-i +1)" "" 20 N N
+0 0 53 +18 53 +18 "(i +i)" "" 20 N N
+0 0 53 -14643 53 +20328 "(-bar foo)" "" 36 N N
+0 0 53 -1647190 53 -512315 "(-zaza -azaz)" "" 36 N N
+0 0 53 +0b1010 53 +0xabcd "(0b1010 +0xabcd)" "" 0 N N #base autodetection
+0 0 53 +0xabcd 53 +0b1010 "(+0xa.bcd@+3 0b.101p4)" "" 0 N N #base autodetection
+
+# white space before the closing ')'
+0 0 53 +1 53 +1 "( 1 +1 )1" "1" 10 N N
diff --git a/mpc/tests/sub.dat b/mpc/tests/sub.dat
new file mode 100644
index 0000000000..8d68dbb612
--- /dev/null
+++ b/mpc/tests/sub.dat
@@ -0,0 +1,94 @@
+# Data file for mpc_sub.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# The line format respects the parameter order in function prototype as
+# follow:
+#
+# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP1_RE OP1_RE PREC_OP1_IM OP1_IM PREC_OP2_RE OP2_RE PREC_OP2_IM OP2_IM RND_RE RND_IM
+#
+# see add.dat for details.
+
+# special values (following ISO C99 standard)
+0 0 53 nan 53 nan 53 -inf 53 -inf 53 -inf 53 -inf N Z
+0 0 53 -inf 53 +inf 53 -inf 53 +inf 53 +1 53 -inf Z U
+0 0 53 nan 53 -inf 53 +inf 53 -inf 53 +inf 53 +0 U D
+0 0 53 +inf 53 +inf 53 +inf 53 +inf 53 -0 53 -1 D N
+0 0 53 -inf 53 -inf 53 -inf 53 -inf 53 -0 53 -1 N U
+0 0 53 -inf 53 nan 53 -inf 53 +inf 53 +inf 53 nan Z D
+0 0 53 nan 53 -inf 53 +inf 53 -inf 53 nan 53 -1 U N
+0 0 53 +inf 53 nan 53 +inf 53 +inf 53 -0 53 nan D Z
+0 0 53 nan 53 nan 53 -inf 53 -inf 53 nan 53 nan N D
+
+0 0 53 -inf 53 -inf 53 -1 53 -inf 53 +inf 53 -1 N D
+0 0 53 -inf 53 +1 53 -inf 53 +1 53 +inf 53 -0 Z N
+0 0 53 +1 53 -inf 53 +1 53 -inf 53 -0 53 +1 U Z
+0 0 53 +inf 53 +1 53 +inf 53 +1 53 -0 53 -0 D U
+0 0 53 -inf 53 nan 53 -1 53 -inf 53 +inf 53 nan N N
+0 0 53 nan 53 +0 53 -inf 53 +1 53 nan 53 +1 Z Z
+0 0 53 +1 53 nan 53 +1 53 -inf 53 -0 53 nan U U
+0 0 53 nan 53 nan 53 +inf 53 +1 53 nan 53 nan D D
+
+0 0 53 -0 53 -inf 53 -0 53 -inf 53 +0 53 +inf D D
+0 0 53 -inf 53 +0 53 -inf 53 +0 53 +1 53 -0 N Z
+0 0 53 +0 53 -inf 53 +0 53 -inf 53 -0 53 -0 Z U
+0 0 53 +inf 53 nan 53 +inf 53 +0 53 -inf 53 nan U D
+0 0 53 nan 53 -inf 53 -0 53 -inf 53 nan 53 -1 D N
+0 0 53 -inf 53 nan 53 -inf 53 +0 53 +0 53 nan N U
+0 0 53 nan 53 nan 53 +0 53 -inf 53 nan 53 nan Z D
+
+0 0 53 +0 53 +2 53 +0 53 +1 53 -0 53 -1 Z D
+0 0 53 -1 53 +0 53 -1 53 -0 53 +0 53 -0 U N
+0 0 53 nan 53 -inf 53 -0 53 +1 53 nan 53 +inf D Z
+0 0 53 +2 53 nan 53 +1 53 -0 53 -1 53 nan N D
+0 0 53 nan 53 +1 53 +0 53 +1 53 nan 53 -0 Z N
+0 0 53 nan 53 nan 53 -1 53 -0 53 nan 53 nan U Z
+
+0 0 53 -0 53 +0 53 -0 53 +0 53 +0 53 -0 U Z
+0 0 53 nan 53 +inf 53 +0 53 -0 53 nan 53 -inf D U
+0 0 53 +1 53 nan 53 +0 53 +0 53 -1 53 nan N N
+0 0 53 nan 53 +0 53 -0 53 -0 53 nan 53 -0 Z Z
+0 0 53 nan 53 nan 53 -0 53 +0 53 nan 53 nan U U
+
+0 0 53 nan 53 -inf 53 nan 53 -inf 53 nan 53 +inf U U
+0 0 53 +inf 53 nan 53 +inf 53 nan 53 -1 53 nan D D
+0 0 53 nan 53 -inf 53 nan 53 -inf 53 nan 53 -0 N Z
+0 0 53 nan 53 nan 53 -inf 53 nan 53 nan 53 nan Z U
+
+0 0 53 nan 53 nan 53 +1 53 nan 53 nan 53 -1 Z U
+0 0 53 nan 53 nan 53 nan 53 +1 53 -0 53 nan U D
+0 0 53 nan 53 nan 53 -1 53 nan 53 nan 53 nan D N
+
+0 0 53 nan 53 nan 53 nan 53 +0 53 +0 53 nan D N
+0 0 53 nan 53 nan 53 +0 53 nan 53 nan 53 nan N U
+
+0 0 53 nan 53 nan 53 nan 53 nan 53 nan 53 nan N U
+
+# pure real argument
++ 0 53 0x10000000000000p-52 53 +0 53 +1 53 -0 53 0x1p-105 53 -0 N N
+- 0 53 0x1fffffffffffffp-53 53 +0 53 +1 53 -0 53 0x1p-105 53 -0 Z Z
++ 0 53 0x10000000000000p-52 53 +0 53 +1 53 -0 53 0x1p-105 53 -0 U U
+- 0 53 0x1fffffffffffffp-53 53 -0 53 +1 53 -0 53 0x1p-105 53 -0 D D
+
+# pure imaginary argument
+0 - 53 +0 53 -0x10000000000000p-52 53 -0 53 0x10000000000000p-106 53 -0 53 +1 N N
+0 + 53 +0 53 -0x1fffffffffffffp-53 53 -0 53 0x10000000000001p-106 53 -0 53 +1 N N
+0 + 53 +0 53 -0x1fffffffffffffp-53 53 +0 53 0x10000000000001p-106 53 -0 53 +1 Z Z
+0 + 53 +0 53 -0x1fffffffffffffp-53 53 +0 53 0x10000000000001p-106 53 -0 53 +1 U U
+0 - 53 -0 53 -0x10000000000000p-52 53 -0 53 0x10000000000001p-106 53 -0 53 +1 D D
+
diff --git a/mpc/tests/sub_fr.dat b/mpc/tests/sub_fr.dat
new file mode 100644
index 0000000000..06d58d1797
--- /dev/null
+++ b/mpc/tests/sub_fr.dat
@@ -0,0 +1,378 @@
+# Data file for mpc_sub_fr.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+# For explanations on the file format, see add_fr.dat.
+
+# special values
+0 0 7 nan 7 -inf 7 -inf 7 -inf 7 -inf N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 -1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 -0 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 +0 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 1 N N
+0 0 7 -inf 7 -inf 7 -inf 7 -inf 7 +inf N N
+0 0 7 nan 7 -inf 7 -inf 7 -inf 7 nan N N
+0 0 7 nan 7 -1 7 -inf 7 -1 7 -inf N N
+0 0 7 -inf 7 -1 7 -inf 7 -1 7 -1 N N
+0 0 7 -inf 7 -1 7 -inf 7 -1 7 -0 N N
+0 0 7 -inf 7 -1 7 -inf 7 -1 7 +0 N N
+0 0 7 -inf 7 -1 7 -inf 7 -1 7 1 N N
+0 0 7 -inf 7 -1 7 -inf 7 -1 7 +inf N N
+0 0 7 nan 7 -1 7 -inf 7 -1 7 nan N N
+0 0 7 nan 7 -0 7 -inf 7 -0 7 -inf N N
+0 0 7 -inf 7 -0 7 -inf 7 -0 7 -1 N N
+0 0 7 -inf 7 -0 7 -inf 7 -0 7 -0 N N
+0 0 7 -inf 7 -0 7 -inf 7 -0 7 +0 N N
+0 0 7 -inf 7 -0 7 -inf 7 -0 7 1 N N
+0 0 7 -inf 7 -0 7 -inf 7 -0 7 +inf N N
+0 0 7 nan 7 -0 7 -inf 7 -0 7 nan N N
+0 0 7 nan 7 +0 7 -inf 7 +0 7 -inf N N
+0 0 7 -inf 7 +0 7 -inf 7 +0 7 -1 N N
+0 0 7 -inf 7 +0 7 -inf 7 +0 7 -0 N N
+0 0 7 -inf 7 +0 7 -inf 7 +0 7 +0 N N
+0 0 7 -inf 7 +0 7 -inf 7 +0 7 1 N N
+0 0 7 -inf 7 +0 7 -inf 7 +0 7 +inf N N
+0 0 7 nan 7 +0 7 -inf 7 +0 7 nan N N
+0 0 7 nan 7 1 7 -inf 7 1 7 -inf N N
+0 0 7 -inf 7 1 7 -inf 7 1 7 -1 N N
+0 0 7 -inf 7 1 7 -inf 7 1 7 -0 N N
+0 0 7 -inf 7 1 7 -inf 7 1 7 +0 N N
+0 0 7 -inf 7 1 7 -inf 7 1 7 1 N N
+0 0 7 -inf 7 1 7 -inf 7 1 7 +inf N N
+0 0 7 nan 7 1 7 -inf 7 1 7 nan N N
+0 0 7 nan 7 +inf 7 -inf 7 +inf 7 -inf N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 -1 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 -0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 +0 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 1 N N
+0 0 7 -inf 7 +inf 7 -inf 7 +inf 7 +inf N N
+0 0 7 nan 7 +inf 7 -inf 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 -inf N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 -1 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 -0 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 +0 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 1 N N
+0 0 7 -inf 7 nan 7 -inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -inf 7 nan 7 nan N N
+0 0 7 +inf 7 -inf 7 -1 7 -inf 7 -inf N N
+0 0 7 0 7 -inf 7 -1 7 -inf 7 -1 N N
+0 0 7 -1 7 -inf 7 -1 7 -inf 7 -0 N N
+0 0 7 -1 7 -inf 7 -1 7 -inf 7 +0 N N
+0 0 7 -2 7 -inf 7 -1 7 -inf 7 1 N N
+0 0 7 -inf 7 -inf 7 -1 7 -inf 7 +inf N N
+0 0 7 nan 7 -inf 7 -1 7 -inf 7 nan N N
+0 0 7 +inf 7 -1 7 -1 7 -1 7 -inf N N
+0 0 7 -inf 7 -1 7 -1 7 -1 7 +inf N N
+0 0 7 nan 7 -1 7 -1 7 -1 7 nan N N
+0 0 7 +inf 7 -0 7 -1 7 -0 7 -inf N N
+0 0 7 -inf 7 -0 7 -1 7 -0 7 +inf N N
+0 0 7 nan 7 -0 7 -1 7 -0 7 nan N N
+0 0 7 +inf 7 +0 7 -1 7 +0 7 -inf N N
+0 0 7 -inf 7 +0 7 -1 7 +0 7 +inf N N
+0 0 7 nan 7 +0 7 -1 7 +0 7 nan N N
+0 0 7 +inf 7 1 7 -1 7 1 7 -inf N N
+0 0 7 -inf 7 1 7 -1 7 1 7 +inf N N
+0 0 7 nan 7 1 7 -1 7 1 7 nan N N
+0 0 7 +inf 7 +inf 7 -1 7 +inf 7 -inf N N
+0 0 7 0 7 +inf 7 -1 7 +inf 7 -1 N N
+0 0 7 -1 7 +inf 7 -1 7 +inf 7 -0 N N
+0 0 7 -1 7 +inf 7 -1 7 +inf 7 +0 N N
+0 0 7 -2 7 +inf 7 -1 7 +inf 7 1 N N
+0 0 7 -inf 7 +inf 7 -1 7 +inf 7 +inf N N
+0 0 7 nan 7 +inf 7 -1 7 +inf 7 nan N N
+0 0 7 +inf 7 nan 7 -1 7 nan 7 -inf N N
+0 0 7 0 7 nan 7 -1 7 nan 7 -1 N N
+0 0 7 -1 7 nan 7 -1 7 nan 7 -0 N N
+0 0 7 -1 7 nan 7 -1 7 nan 7 +0 N N
+0 0 7 -2 7 nan 7 -1 7 nan 7 1 N N
+0 0 7 -inf 7 nan 7 -1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -1 7 nan 7 nan N N
+0 0 7 +inf 7 -inf 7 -0 7 -inf 7 -inf N N
+0 0 7 1 7 -inf 7 -0 7 -inf 7 -1 N N
+0 0 7 0 7 -inf 7 -0 7 -inf 7 -0 N N
+0 0 7 -0 7 -inf 7 -0 7 -inf 7 +0 N N
+0 0 7 -1 7 -inf 7 -0 7 -inf 7 1 N N
+0 0 7 -inf 7 -inf 7 -0 7 -inf 7 +inf N N
+0 0 7 nan 7 -inf 7 -0 7 -inf 7 nan N N
+0 0 7 +inf 7 -1 7 -0 7 -1 7 -inf N N
+0 0 7 -inf 7 -1 7 -0 7 -1 7 +inf N N
+0 0 7 nan 7 -1 7 -0 7 -1 7 nan N N
+0 0 7 +inf 7 -0 7 -0 7 -0 7 -inf N N
+0 0 7 -inf 7 -0 7 -0 7 -0 7 +inf N N
+0 0 7 nan 7 -0 7 -0 7 -0 7 nan N N
+0 0 7 +inf 7 +0 7 -0 7 +0 7 -inf N N
+0 0 7 -inf 7 +0 7 -0 7 +0 7 +inf N N
+0 0 7 nan 7 +0 7 -0 7 +0 7 nan N N
+0 0 7 +inf 7 1 7 -0 7 1 7 -inf N N
+0 0 7 -inf 7 1 7 -0 7 1 7 +inf N N
+0 0 7 nan 7 1 7 -0 7 1 7 nan N N
+0 0 7 +inf 7 +inf 7 -0 7 +inf 7 -inf N N
+0 0 7 1 7 +inf 7 -0 7 +inf 7 -1 N N
+0 0 7 0 7 +inf 7 -0 7 +inf 7 -0 N N
+0 0 7 -0 7 +inf 7 -0 7 +inf 7 +0 N N
+0 0 7 -1 7 +inf 7 -0 7 +inf 7 1 N N
+0 0 7 -inf 7 +inf 7 -0 7 +inf 7 +inf N N
+0 0 7 nan 7 +inf 7 -0 7 +inf 7 nan N N
+0 0 7 +inf 7 nan 7 -0 7 nan 7 -inf N N
+0 0 7 1 7 nan 7 -0 7 nan 7 -1 N N
+0 0 7 0 7 nan 7 -0 7 nan 7 -0 N N
+0 0 7 -0 7 nan 7 -0 7 nan 7 +0 N N
+0 0 7 -1 7 nan 7 -0 7 nan 7 1 N N
+0 0 7 -inf 7 nan 7 -0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 -0 7 nan 7 nan N N
+0 0 7 +inf 7 -inf 7 +0 7 -inf 7 -inf N N
+0 0 7 1 7 -inf 7 +0 7 -inf 7 -1 N N
+0 0 7 +0 7 -inf 7 +0 7 -inf 7 -0 N N
+0 0 7 0 7 -inf 7 +0 7 -inf 7 +0 N N
+0 0 7 -1 7 -inf 7 +0 7 -inf 7 1 N N
+0 0 7 -inf 7 -inf 7 +0 7 -inf 7 +inf N N
+0 0 7 nan 7 -inf 7 +0 7 -inf 7 nan N N
+0 0 7 +inf 7 -1 7 +0 7 -1 7 -inf N N
+0 0 7 -inf 7 -1 7 +0 7 -1 7 +inf N N
+0 0 7 nan 7 -1 7 +0 7 -1 7 nan N N
+0 0 7 +inf 7 -0 7 +0 7 -0 7 -inf N N
+0 0 7 -inf 7 -0 7 +0 7 -0 7 +inf N N
+0 0 7 nan 7 -0 7 +0 7 -0 7 nan N N
+0 0 7 +inf 7 +0 7 +0 7 +0 7 -inf N N
+0 0 7 -inf 7 +0 7 +0 7 +0 7 +inf N N
+0 0 7 nan 7 +0 7 +0 7 +0 7 nan N N
+0 0 7 +inf 7 1 7 +0 7 1 7 -inf N N
+0 0 7 -inf 7 1 7 +0 7 1 7 +inf N N
+0 0 7 nan 7 1 7 +0 7 1 7 nan N N
+0 0 7 +inf 7 +inf 7 +0 7 +inf 7 -inf N N
+0 0 7 1 7 +inf 7 +0 7 +inf 7 -1 N N
+0 0 7 +0 7 +inf 7 +0 7 +inf 7 -0 N N
+0 0 7 0 7 +inf 7 +0 7 +inf 7 +0 N N
+0 0 7 -1 7 +inf 7 +0 7 +inf 7 1 N N
+0 0 7 -inf 7 +inf 7 +0 7 +inf 7 +inf N N
+0 0 7 nan 7 +inf 7 +0 7 +inf 7 nan N N
+0 0 7 +inf 7 nan 7 +0 7 nan 7 -inf N N
+0 0 7 1 7 nan 7 +0 7 nan 7 -1 N N
+0 0 7 +0 7 nan 7 +0 7 nan 7 -0 N N
+0 0 7 0 7 nan 7 +0 7 nan 7 +0 N N
+0 0 7 -1 7 nan 7 +0 7 nan 7 1 N N
+0 0 7 -inf 7 nan 7 +0 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +0 7 nan 7 nan N N
+0 0 7 +inf 7 -inf 7 1 7 -inf 7 -inf N N
+0 0 7 2 7 -inf 7 1 7 -inf 7 -1 N N
+0 0 7 1 7 -inf 7 1 7 -inf 7 -0 N N
+0 0 7 1 7 -inf 7 1 7 -inf 7 +0 N N
+0 0 7 0 7 -inf 7 1 7 -inf 7 1 N N
+0 0 7 -inf 7 -inf 7 1 7 -inf 7 +inf N N
+0 0 7 nan 7 -inf 7 1 7 -inf 7 nan N N
+0 0 7 +inf 7 -1 7 1 7 -1 7 -inf N N
+0 0 7 -inf 7 -1 7 1 7 -1 7 +inf N N
+0 0 7 nan 7 -1 7 1 7 -1 7 nan N N
+0 0 7 +inf 7 -0 7 1 7 -0 7 -inf N N
+0 0 7 -inf 7 -0 7 1 7 -0 7 +inf N N
+0 0 7 nan 7 -0 7 1 7 -0 7 nan N N
+0 0 7 +inf 7 +0 7 1 7 +0 7 -inf N N
+0 0 7 -inf 7 +0 7 1 7 +0 7 +inf N N
+0 0 7 nan 7 +0 7 1 7 +0 7 nan N N
+0 0 7 +inf 7 1 7 1 7 1 7 -inf N N
+0 0 7 -inf 7 1 7 1 7 1 7 +inf N N
+0 0 7 nan 7 1 7 1 7 1 7 nan N N
+0 0 7 +inf 7 +inf 7 1 7 +inf 7 -inf N N
+0 0 7 2 7 +inf 7 1 7 +inf 7 -1 N N
+0 0 7 1 7 +inf 7 1 7 +inf 7 -0 N N
+0 0 7 1 7 +inf 7 1 7 +inf 7 +0 N N
+0 0 7 0 7 +inf 7 1 7 +inf 7 1 N N
+0 0 7 -inf 7 +inf 7 1 7 +inf 7 +inf N N
+0 0 7 nan 7 +inf 7 1 7 +inf 7 nan N N
+0 0 7 +inf 7 nan 7 1 7 nan 7 -inf N N
+0 0 7 2 7 nan 7 1 7 nan 7 -1 N N
+0 0 7 1 7 nan 7 1 7 nan 7 -0 N N
+0 0 7 1 7 nan 7 1 7 nan 7 +0 N N
+0 0 7 0 7 nan 7 1 7 nan 7 1 N N
+0 0 7 -inf 7 nan 7 1 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 1 7 nan 7 nan N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 -inf N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 -1 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 -0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 +0 N N
+0 0 7 +inf 7 -inf 7 +inf 7 -inf 7 1 N N
+0 0 7 nan 7 -inf 7 +inf 7 -inf 7 +inf N N
+0 0 7 nan 7 -inf 7 +inf 7 -inf 7 nan N N
+0 0 7 +inf 7 -1 7 +inf 7 -1 7 -inf N N
+0 0 7 +inf 7 -1 7 +inf 7 -1 7 -1 N N
+0 0 7 +inf 7 -1 7 +inf 7 -1 7 -0 N N
+0 0 7 +inf 7 -1 7 +inf 7 -1 7 +0 N N
+0 0 7 +inf 7 -1 7 +inf 7 -1 7 1 N N
+0 0 7 nan 7 -1 7 +inf 7 -1 7 +inf N N
+0 0 7 nan 7 -1 7 +inf 7 -1 7 nan N N
+0 0 7 +inf 7 -0 7 +inf 7 -0 7 -inf N N
+0 0 7 +inf 7 -0 7 +inf 7 -0 7 -1 N N
+0 0 7 +inf 7 -0 7 +inf 7 -0 7 -0 N N
+0 0 7 +inf 7 -0 7 +inf 7 -0 7 +0 N N
+0 0 7 +inf 7 -0 7 +inf 7 -0 7 1 N N
+0 0 7 nan 7 -0 7 +inf 7 -0 7 +inf N N
+0 0 7 nan 7 -0 7 +inf 7 -0 7 nan N N
+0 0 7 +inf 7 +0 7 +inf 7 +0 7 -inf N N
+0 0 7 +inf 7 +0 7 +inf 7 +0 7 -1 N N
+0 0 7 +inf 7 +0 7 +inf 7 +0 7 -0 N N
+0 0 7 +inf 7 +0 7 +inf 7 +0 7 +0 N N
+0 0 7 +inf 7 +0 7 +inf 7 +0 7 1 N N
+0 0 7 nan 7 +0 7 +inf 7 +0 7 +inf N N
+0 0 7 nan 7 +0 7 +inf 7 +0 7 nan N N
+0 0 7 +inf 7 1 7 +inf 7 1 7 -inf N N
+0 0 7 +inf 7 1 7 +inf 7 1 7 -1 N N
+0 0 7 +inf 7 1 7 +inf 7 1 7 -0 N N
+0 0 7 +inf 7 1 7 +inf 7 1 7 +0 N N
+0 0 7 +inf 7 1 7 +inf 7 1 7 1 N N
+0 0 7 nan 7 1 7 +inf 7 1 7 +inf N N
+0 0 7 nan 7 1 7 +inf 7 1 7 nan N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 -inf N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 -1 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 -0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 +0 N N
+0 0 7 +inf 7 +inf 7 +inf 7 +inf 7 1 N N
+0 0 7 nan 7 +inf 7 +inf 7 +inf 7 +inf N N
+0 0 7 nan 7 +inf 7 +inf 7 +inf 7 nan N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 -inf N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 -1 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 -0 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 +0 N N
+0 0 7 +inf 7 nan 7 +inf 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 +inf 7 nan 7 nan N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 -inf N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 -1 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 -0 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 +0 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 1 N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 +inf N N
+0 0 7 nan 7 -inf 7 nan 7 -inf 7 nan N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 -inf N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 -1 N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 -0 N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 +0 N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 1 N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 +inf N N
+0 0 7 nan 7 -1 7 nan 7 -1 7 nan N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 -inf N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 -1 N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 -0 N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 +0 N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 1 N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 +inf N N
+0 0 7 nan 7 -0 7 nan 7 -0 7 nan N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 -inf N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 -1 N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 -0 N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 +0 N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 1 N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 +inf N N
+0 0 7 nan 7 +0 7 nan 7 +0 7 nan N N
+0 0 7 nan 7 1 7 nan 7 1 7 -inf N N
+0 0 7 nan 7 1 7 nan 7 1 7 -1 N N
+0 0 7 nan 7 1 7 nan 7 1 7 -0 N N
+0 0 7 nan 7 1 7 nan 7 1 7 +0 N N
+0 0 7 nan 7 1 7 nan 7 1 7 1 N N
+0 0 7 nan 7 1 7 nan 7 1 7 +inf N N
+0 0 7 nan 7 1 7 nan 7 1 7 nan N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 -inf N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 -1 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 -0 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 +0 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 1 N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 +inf N N
+0 0 7 nan 7 +inf 7 nan 7 +inf 7 nan N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 -0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +0 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 1 N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 +inf N N
+0 0 7 nan 7 nan 7 nan 7 nan 7 nan N N
+
+# values with only 1, -1, +0, -0
+0 0 7 0 7 -1 7 -1 7 -1 7 -1 N N
+0 0 7 -1 7 -1 7 -1 7 -1 7 -0 N N
+0 0 7 -1 7 -1 7 -1 7 -1 7 +0 N N
+0 0 7 -2 7 -1 7 -1 7 -1 7 1 N N
+0 0 7 0 7 -0 7 -1 7 -0 7 -1 N N
+0 0 7 -1 7 -0 7 -1 7 -0 7 -0 N N
+0 0 7 -1 7 -0 7 -1 7 -0 7 +0 N N
+0 0 7 -2 7 -0 7 -1 7 -0 7 1 N N
+0 0 7 0 7 +0 7 -1 7 +0 7 -1 N N
+0 0 7 -1 7 +0 7 -1 7 +0 7 -0 N N
+0 0 7 -1 7 +0 7 -1 7 +0 7 +0 N N
+0 0 7 -2 7 +0 7 -1 7 +0 7 1 N N
+0 0 7 0 7 1 7 -1 7 1 7 -1 N N
+0 0 7 -1 7 1 7 -1 7 1 7 -0 N N
+0 0 7 -1 7 1 7 -1 7 1 7 +0 N N
+0 0 7 -2 7 1 7 -1 7 1 7 1 N N
+0 0 7 1 7 -1 7 -0 7 -1 7 -1 N N
+0 0 7 0 7 -1 7 -0 7 -1 7 -0 N N
+0 0 7 -0 7 -1 7 -0 7 -1 7 +0 N N
+0 0 7 -1 7 -1 7 -0 7 -1 7 1 N N
+0 0 7 1 7 -0 7 -0 7 -0 7 -1 N N
+0 0 7 0 7 -0 7 -0 7 -0 7 -0 N N
+0 0 7 -0 7 -0 7 -0 7 -0 7 +0 N N
+0 0 7 -1 7 -0 7 -0 7 -0 7 1 N N
+0 0 7 1 7 +0 7 -0 7 +0 7 -1 N N
+0 0 7 0 7 +0 7 -0 7 +0 7 -0 N N
+0 0 7 -0 7 +0 7 -0 7 +0 7 +0 N N
+0 0 7 -1 7 +0 7 -0 7 +0 7 1 N N
+0 0 7 1 7 1 7 -0 7 1 7 -1 N N
+0 0 7 0 7 1 7 -0 7 1 7 -0 N N
+0 0 7 -0 7 1 7 -0 7 1 7 +0 N N
+0 0 7 -1 7 1 7 -0 7 1 7 1 N N
+0 0 7 1 7 -1 7 +0 7 -1 7 -1 N N
+0 0 7 +0 7 -1 7 +0 7 -1 7 -0 N N
+0 0 7 0 7 -1 7 +0 7 -1 7 +0 N N
+0 0 7 -1 7 -1 7 +0 7 -1 7 1 N N
+0 0 7 1 7 -0 7 +0 7 -0 7 -1 N N
+0 0 7 +0 7 -0 7 +0 7 -0 7 -0 N N
+0 0 7 0 7 -0 7 +0 7 -0 7 +0 N N
+0 0 7 -1 7 -0 7 +0 7 -0 7 1 N N
+0 0 7 1 7 +0 7 +0 7 +0 7 -1 N N
+0 0 7 +0 7 +0 7 +0 7 +0 7 -0 N N
+0 0 7 0 7 +0 7 +0 7 +0 7 +0 N N
+0 0 7 -1 7 +0 7 +0 7 +0 7 1 N N
+0 0 7 1 7 1 7 +0 7 1 7 -1 N N
+0 0 7 +0 7 1 7 +0 7 1 7 -0 N N
+0 0 7 0 7 1 7 +0 7 1 7 +0 N N
+0 0 7 -1 7 1 7 +0 7 1 7 1 N N
+0 0 7 2 7 -1 7 1 7 -1 7 -1 N N
+0 0 7 1 7 -1 7 1 7 -1 7 -0 N N
+0 0 7 1 7 -1 7 1 7 -1 7 +0 N N
+0 0 7 0 7 -1 7 1 7 -1 7 1 N N
+0 0 7 2 7 -0 7 1 7 -0 7 -1 N N
+0 0 7 1 7 -0 7 1 7 -0 7 -0 N N
+0 0 7 1 7 -0 7 1 7 -0 7 +0 N N
+0 0 7 0 7 -0 7 1 7 -0 7 1 N N
+0 0 7 2 7 +0 7 1 7 +0 7 -1 N N
+0 0 7 1 7 +0 7 1 7 +0 7 -0 N N
+0 0 7 1 7 +0 7 1 7 +0 7 +0 N N
+0 0 7 0 7 +0 7 1 7 +0 7 1 N N
+0 0 7 2 7 1 7 1 7 1 7 -1 N N
+0 0 7 1 7 1 7 1 7 1 7 -0 N N
+0 0 7 1 7 1 7 1 7 1 7 +0 N N
+0 0 7 0 7 1 7 1 7 1 7 1 N N
+
+# also check the imaginary part is correctly rounded
+0 - 2 nan 2 16 2 nan 5 17 2 nan N N
+0 + 2 nan 2 24 2 nan 5 17 2 nan N U
+0 - 2 nan 2 16 2 nan 5 17 2 nan N D
+0 - 2 nan 2 16 2 nan 5 17 2 nan N Z
+0 + 2 nan 2 -16 2 nan 5 -17 2 nan N N
+0 + 2 nan 2 -16 2 nan 5 -17 2 nan N U
+0 - 2 nan 2 -24 2 nan 5 -17 2 nan N D
+0 + 2 nan 2 -16 2 nan 5 -17 2 nan N Z
+
diff --git a/mpc/tests/tabs.c b/mpc/tests/tabs.c
new file mode 100644
index 0000000000..4651089478
--- /dev/null
+++ b/mpc/tests/tabs.c
@@ -0,0 +1,36 @@
+/* tabs -- test file for mpc_abs.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (FC, f, mpc_abs);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 1, 0);
+ data_check (f, "abs.dat");
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tacos.c b/mpc/tests/tacos.c
new file mode 100644
index 0000000000..38653a46f8
--- /dev/null
+++ b/mpc/tests/tacos.c
@@ -0,0 +1,36 @@
+/* tacos -- test file for mpc_acos.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_acos);
+
+ test_start ();
+
+ data_check (f, "acos.dat");
+ tgeneric (f, 2, 512, 7, 7);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tacosh.c b/mpc/tests/tacosh.c
new file mode 100644
index 0000000000..f8fbdc685d
--- /dev/null
+++ b/mpc/tests/tacosh.c
@@ -0,0 +1,57 @@
+/* tacosh.c -- test file for mpc_acosh.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+bug20091120 (void)
+{
+ mpc_t x, y;
+
+ mpc_init2 (x, 53);
+ mpc_init3 (y, 17, 42);
+ mpc_set_ui_ui (x, 1, 1, MPC_RNDNN);
+ mpc_acosh (y, x, MPC_RNDNN);
+ if (mpfr_get_prec (mpc_realref(y)) != 17 ||
+ mpfr_get_prec (mpc_imagref(y)) != 42)
+ {
+ printf ("Error, mpc_acosh changed the precisions!!!\n");
+ exit (1);
+ }
+ mpc_clear (x);
+ mpc_clear (y);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_acosh);
+
+ test_start ();
+
+ bug20091120 ();
+
+ data_check (f, "acosh.dat");
+ tgeneric (f, 2, 512, 7, 7);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tadd.c b/mpc/tests/tadd.c
new file mode 100644
index 0000000000..11a305bdb5
--- /dev/null
+++ b/mpc/tests/tadd.c
@@ -0,0 +1,70 @@
+/* tadd -- test file for mpc_add.
+
+Copyright (C) 2008, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+static void
+check_ternary_value (void)
+{
+ mpc_t x, y, z;
+ mpfr_prec_t prec;
+
+ mpc_init2 (x, 2);
+ mpc_init2 (y, 2);
+ mpc_init2 (z, 2);
+
+ for (prec = 2; prec <= 1000; prec++)
+ {
+ mpc_set_prec (x, prec);
+ mpc_set_prec (y, prec);
+
+ mpc_set_ui (x, 1, MPC_RNDNN);
+ mpc_mul_2ui (x, x, (unsigned long int) prec, MPC_RNDNN);
+ mpc_set_ui (y, 1, MPC_RNDNN);
+
+ if (mpc_add (z, x, y, MPC_RNDNN) == 0)
+ {
+ fprintf (stderr, "Error in mpc_add: 2^(-prec)+1 cannot be exact\n");
+ exit (1);
+ }
+ }
+
+ mpc_clear (x);
+ mpc_clear (y);
+ mpc_clear (z);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (C_CC, f, mpc_add);
+ f.properties = FUNC_PROP_SYMETRIC;
+
+ test_start ();
+
+ check_ternary_value();
+ data_check (f, "add.dat");
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tadd_fr.c b/mpc/tests/tadd_fr.c
new file mode 100644
index 0000000000..1f3b76a9a6
--- /dev/null
+++ b/mpc/tests/tadd_fr.c
@@ -0,0 +1,72 @@
+/* tadd_fr -- test file for mpc_add_fr.
+
+Copyright (C) 2008, 2010, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+static void
+check_ternary_value (mpfr_prec_t prec_max, mpfr_prec_t step)
+{
+ mpfr_prec_t prec;
+ mpc_t z;
+ mpfr_t f;
+
+ mpc_init2 (z, 2);
+ mpfr_init (f);
+
+ for (prec = 2; prec < prec_max; prec += step)
+ {
+ mpc_set_prec (z, prec);
+ mpfr_set_prec (f, prec);
+
+ mpc_set_ui (z, 1, MPC_RNDNN);
+ mpfr_set_ui (f, 1, GMP_RNDN);
+ if (mpc_add_fr (z, z, f, MPC_RNDNZ))
+ {
+ printf ("Error in mpc_add_fr: 1+1 should be exact\n");
+ exit (1);
+ }
+
+ mpc_set_ui (z, 1, MPC_RNDNN);
+ mpc_mul_2ui (z, z, (unsigned long int) prec, MPC_RNDNN);
+ if (mpc_add_fr (z, z, f, MPC_RNDNN) == 0)
+ {
+ fprintf (stderr, "Error in mpc_add_fr: 2^prec+1 cannot be exact\n");
+ exit (1);
+ }
+ }
+ mpc_clear (z);
+ mpfr_clear (f);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CCF, f, mpc_add_fr);
+ test_start ();
+
+ check_ternary_value (1024, 1);
+
+ data_check (f, "add_fr.dat");
+ tgeneric (f, 2, 1024, 7, 10);
+
+ test_end ();
+ return 0;
+}
diff --git a/mpc/tests/tadd_si.c b/mpc/tests/tadd_si.c
new file mode 100644
index 0000000000..da12a7a9ec
--- /dev/null
+++ b/mpc/tests/tadd_si.c
@@ -0,0 +1,68 @@
+/* tadd_si -- test file for mpc_add_si.
+
+Copyright (C) 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+static void
+check_ternary_value (void)
+{
+ mpfr_prec_t prec;
+ mpc_t z;
+ const long int s = -1;
+
+ mpc_init2 (z, 2);
+
+ for (prec=2; prec <= 1024; prec++) {
+ mpc_set_prec (z, prec);
+ mpc_set_ui (z, 3ul, MPC_RNDNN);
+ if (mpc_add_si (z, z, s, MPC_RNDDU)) {
+ printf ("Error in mpc_add_si: 3+(-1) should be exact\n");
+ exit (1);
+ }
+ else if (mpc_cmp_si (z, 2l) != 0) {
+ printf ("Error in mpc_add_si: 3+(-1) should be 2\n");
+ exit (1);
+ }
+
+ mpc_mul_2ui (z, z, (unsigned long int) prec, MPC_RNDNN);
+ if (mpc_add_si (z, z, s, MPC_RNDNN) == 0) {
+ printf ("Error in mpc_add_si: 2^(prec+1)-1 cannot be exact\n");
+ exit (1);
+ }
+ }
+
+ mpc_clear (z);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CCU, f, mpc_add_ui);
+
+ test_start ();
+
+ check_ternary_value ();
+ tgeneric (f, 2, 1024, 11, -2);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tadd_ui.c b/mpc/tests/tadd_ui.c
new file mode 100644
index 0000000000..4f8efea415
--- /dev/null
+++ b/mpc/tests/tadd_ui.c
@@ -0,0 +1,68 @@
+/* tadd_ui -- test file for mpc_add_ui.
+
+Copyright (C) 2008, 2010, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+static void
+check_ternary_value (void)
+{
+ mpfr_prec_t prec;
+ mpc_t z;
+
+ mpc_init2 (z, 2);
+
+ for (prec=2; prec <= 1024; prec++)
+ {
+ mpc_set_prec (z, prec);
+
+ mpc_set_ui (z, 1, MPC_RNDNN);
+ if (mpc_add_ui (z, z, 1, MPC_RNDNZ))
+ {
+ printf ("Error in mpc_add_ui: 1+1 should be exact\n");
+ exit (1);
+ }
+
+ mpc_set_ui (z, 1, MPC_RNDNN);
+ mpc_mul_2ui (z, z, (unsigned long int) prec, MPC_RNDNN);
+ if (mpc_add_ui (z, z, 1, MPC_RNDNN) == 0)
+ {
+ printf ("Error in mpc_add_ui: 2^prec+1 cannot be exact\n");
+ exit (1);
+ }
+ }
+
+ mpc_clear (z);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CCU, f, mpc_add_ui);
+
+ test_start ();
+
+ check_ternary_value ();
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tan.dat b/mpc/tests/tan.dat
new file mode 100644
index 0000000000..ce4c0973b7
--- /dev/null
+++ b/mpc/tests/tan.dat
@@ -0,0 +1,135 @@
+# Data test file for mpc_tan.
+#
+# Copyright (C) 2008, 2010, 2011 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+
+# See file sin.dat for the format description.
+
+# Special values, following ISO C99 standard, Annex G,
+# more precisely Section G.6.2.6 "The ctanh functions"
+# since G.6 defines ctan(z) as -i * ctanh(i*z)
+
+# Rule [conj]: tan(conj(z)) = conj(tan(z))
+# Rule [odd]: tan(-z) = -tan(z)
+
+# Note: for each rule, we cite the rule for tanh from C99,
+# and below the translated rule for tan, using tanh(z) = i tan(-iz),
+# thus tanh(a+i*b) = c+i*d translates to tan(b-i*a) = d-i*c
+
+# tanh(+0 + i*0) = +0 + i*0
+# tan (+0 - i*0) = +0 - i*0
+0 0 2 +0 2 -0 2 +0 2 -0 N N
+# [conj]: tan(+0 + i*0) = +0 + i*0
+0 0 2 +0 2 +0 2 +0 2 +0 N N
+# [odd]: tan(-0 + i*0) = -0 + i*0
+0 0 2 -0 2 +0 2 -0 2 +0 N N
+# [odd+conj]: tan(-0 - i*0) = -0 - i*0
+0 0 2 -0 2 -0 2 -0 2 -0 N N
+
+# tanh(x + i*inf) = nan + i*nan for finite x
+# tan (inf - i*x) = nan + i*nan for finite x
+0 0 2 nan 2 nan 2 +inf 2 +1 N N
+0 0 2 nan 2 nan 2 +inf 2 +0 N N
+0 0 2 nan 2 nan 2 +inf 2 -0 N N
+0 0 2 nan 2 nan 2 +inf 2 -1 N N
+# [conj] does not make sense since we already considered x < 0
+# [odd]: tan(-inf + i*x) = nan + i*nan for finite x
+0 0 2 nan 2 nan 2 -inf 2 +1 N N
+0 0 2 nan 2 nan 2 -inf 2 +0 N N
+0 0 2 nan 2 nan 2 -inf 2 -0 N N
+0 0 2 nan 2 nan 2 -inf 2 -1 N N
+
+# tanh(x + i*nan) = nan + i*nan for finite x
+# tan (nan + i*x) = nan + i*nan for finite x
+0 0 2 nan 2 nan 2 nan 2 1 N N
+0 0 2 nan 2 nan 2 nan 2 +0 N N
+0 0 2 nan 2 nan 2 nan 2 -0 N N
+0 0 2 nan 2 nan 2 nan 2 -1 N N
+# [conj] makes no sense since we already considered x < 0
+# idem for [odd] since nan has no sign
+
+# tanh(+inf + i*y) = 1 + i*0*sin(2y) for positive-signed finite y
+# tan (y - i*inf) = 0*sin(2*y) - i*1 for positive-signed finite y
+0 0 2 +0 2 -1 2 1 2 -inf N N
+0 0 2 -0 2 -1 2 2 2 -inf N N
+# [conj]: tan (y + i*inf) = 0*sin(2*y) + i*1
+0 0 2 +0 2 +1 2 1 2 +inf N N
+0 0 2 -0 2 +1 2 2 2 +inf N N
+# [odd]: tan (-y + i*inf) = -0*sin(2*y) + i*1
+0 0 2 -0 2 +1 2 -1 2 +inf N N
+0 0 2 +0 2 +1 2 -2 2 +inf N N
+# [odd+conj]: tan (-y - i*inf) = -0*sin(2*y) - i*1
+0 0 2 -0 2 -1 2 -1 2 -inf N N
+0 0 2 +0 2 -1 2 -2 2 -inf N N
+
+# tanh(+inf + i*inf) = 1 +/- i*0 (unspecified sign of zero for C99)
+# tan (+inf - i*inf) = +/-0 - i*1
+0 0 2 0 2 -1 2 +inf 2 -inf N N
+# [conj]: tan (+inf + i*inf) = +/-0 + i*1
+0 0 2 0 2 +1 2 +inf 2 +inf N N
+# [odd]: tan (-inf + i*inf) = +/-0 + i*1
+0 0 2 0 2 +1 2 -inf 2 +inf N N
+# [odd+conj]: tan (-inf - i*inf) = +/-0 - i*1
+0 0 2 0 2 -1 2 -inf 2 -inf N N
+
+# tanh(+inf + i*nan) = 1 +/- i*0 (unspecified sign of zero for C99)
+# tan (nan - i*inf) = +/-0 - i*1
+0 0 2 0 2 -1 2 nan 2 -inf N N
+# [conj]: tan (nan + i*inf) = +/-0 + i*1
+0 0 2 0 2 +1 2 nan 2 +inf N N
+# [odd] = [conj] since nan has no sign, and -(+/-0) = +/-0
+
+# tanh(nan + i*0) = nan + i*0
+# tan(+0 + i*nan) = +0 + i*nan
+0 0 2 +0 2 nan 2 +0 2 nan N N
+# [conj] gives the same identity since nan has no sign
+# [odd]: tan(-0 + i*nan) = -0 + i*nan
+0 0 2 -0 2 nan 2 -0 2 nan N N
+
+# tanh(nan + i*y) = nan + i*nan for all nonzero y
+# tan (y + i*nan) = nan + i*nan
+0 0 2 nan 2 nan 2 +inf 2 nan N N
+0 0 2 nan 2 nan 2 +1 2 nan N N
+0 0 2 nan 2 nan 2 -1 2 nan N N
+0 0 2 nan 2 nan 2 -inf 2 nan N N
+# [conj] gives no new relation since nan has no sign
+# [odd] gives no new relation since we already considered y < 0
+
+# tanh(nan + i*nan) = nan + i*nan
+0 0 2 nan 2 nan 2 nan 2 nan N N
+
+# corner case: op = atan (2^(-k) + i*2^k) for k=200 and k=1000
++ + 100 0x1@-50 100 0x1@50 1000 0x1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d4c76273644a29410f31c6809bbdf2a33679a748636605614dbe4be286e9fc26adadaa3848bc90b6aecc4bcfd8de89884d34c6fdad617feb96de80d6fdbdc70d7f6b5133f4b5d3e4822f8963fcc9250cca3d9c8b67b8400f97142c77e0b31b4906c38 1000 0x1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555548888888888888888888888888888888888888888888888888a@-50 N N
++ + 100 0x1@-250 100 0x1@250 4000 0x1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d4c76273644a29410f31c6809bbdf2a33679a748636605614dbe4be286e9fc26adadaa3848bc90b6aecc4bcfd8de89885d34c6fdad617feb96de80d6fdbdc70d7f6b5133f4b5d3e4822f8963fcc9250cca3d9c8b67b8400f97142c77e0b31b4906c38aba734d22c7f51fa499ebf06caba47b9475b2c38c5e6ac410aa5773daa520ee12d2cdace186a9c95793009e2e8d811943042f86520bc8c5c6d9c77c73cee58301d0c07364f0745d80f451f6b8abbe0de98a593bc5797ed2ab02e30732a92f9d52ad5ca2ba44c3131f40a202ae51cb51555885b5a662e1a08a0f46750aa4357be3974c9d9f70a08b1b7de1515d4e2aeba0c18fb672e1f0b4dc3c98f57eb5d19b61267ae3d1929c0944ac33b9dc7a44c35a5dcd7e25ff40db31410c9b0ec04e67d90d4c8a43e56302ef6401977c22eaef4c2bad8ee13118175b28dc411c49f40e9cb566287b6b7f9c1fa211c9705a2415242100234e478254f0fccaf10e334217b74b64d33864e30d5e9c4783528d0696c2a17b44b07d39455a899d1b77785b609bd1df25d1df8283f7d954c50f8b28e9cd780bb33652c9f412187444677430ca2b7cfda3ec252e19dc5af5f7037baec42e09039a00d224fab60b5532769d5311b1fbb830dff6fb9214d811e9be86b92680509246d87f56a 4000 0x1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555556@-250 N N
+
+# yet another absurd case: op = atan (2^200) + 2^(-200000)*I;
+# expensive to compute
+#- - 50 0x1@50 50 0x1@-49900 1000 0x1.921fb54442d18469898cc51701b839a252049c1114cf98e803177d4c76273644a29410f31c6809bbdf2a33679a748636605614dbe4be286e9fc26adadaa3848bc90b6aecc4bcfd8de8988628a1c5302b6d540ec33d62c53131c62d4c0a6894a0b2939d784deb9521e7a621f92f1e0bd0d9564ec6981cd3608709e5c18e 1000 0x1@-50000 N N
+
+# corner case
+- + 9 -0x9bp-51 9 -1 9 -0x16dp-8 9 -0x77p-3 N N
+
+# huge values
++ - 53 -0 53 -1 53 0x4580CBF242683p-3 53 -0x1B3E8A3660D279p-3 N N
+- - 53 +0 53 -1 53 -0x4580CBF242683p-3 53 -0x1B3E8A3660D279p-3 N N
++ + 53 -0 53 +1 53 -0x1B3E8A3660D279p-3 53 0x4580CBF242683p-3 N N
+
+# some values taken from ttan.c
++ + 53 0x1D02967C31CDB5 53 0x1D02967C31CDB5 53 0x3243F6A8885A30p-53 53 0x11A62633145C07p-106 N N
+- + 53 0x1D02967C31CDB4 53 0x1D02967C31CDB5 53 0x3243F6A8885A30p-53 53 0x11A62633145C07p-106 D U
+- - 53 0x1D02967C31CDB4 53 0x1D02967C31CDB4 53 0x3243F6A8885A30p-53 53 0x11A62633145C07p-106 Z D
+- + 53 -0xB0BD0AA4A3B3D 53 -0xB0BD0AA4A3B3D 53 0x1921FB54442D19p-52 53 -0x172CECE675D1FDp-105 N N
diff --git a/mpc/tests/tanh.dat b/mpc/tests/tanh.dat
new file mode 100644
index 0000000000..439fb260e5
--- /dev/null
+++ b/mpc/tests/tanh.dat
@@ -0,0 +1,81 @@
+# Data file for mpc_tanh.
+#
+# Copyright (C) 2008 INRIA
+#
+# This file is part of GNU MPC.
+#
+# GNU MPC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+#o ption) any later version.
+#
+# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+# more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see http://www.gnu.org/licenses/ .
+#
+# For explanations on the file format, see sin.dat.
+
+# special values (following ISO C99 standard)
+0 0 7 -1 7 0 7 -inf 7 -inf N N
+0 0 7 -1 7 -0 7 -inf 7 -1 N N
+0 0 7 -1 7 -0 7 -inf 7 -0 N N
+0 0 7 -1 7 +0 7 -inf 7 +0 N N
+0 0 7 -1 7 +0 7 -inf 7 1 N N
+0 0 7 -1 7 0 7 -inf 7 +inf N N
+0 0 7 -1 7 0 7 -inf 7 NaN N N
+0 0 7 NaN 7 NaN 7 -1 7 -inf N N
+0 0 7 NaN 7 NaN 7 -1 7 +inf N N
+0 0 7 NaN 7 NaN 7 -1 7 NaN N N
+0 0 7 NaN 7 NaN 7 -0 7 -inf N N
+0 0 7 -0 7 -0 7 -0 7 -0 N N
+0 0 7 -0 7 +0 7 -0 7 +0 N N
+0 0 7 NaN 7 NaN 7 -0 7 +inf N N
+0 0 7 NaN 7 NaN 7 -0 7 NaN N N
+0 0 7 NaN 7 NaN 7 +0 7 -inf N N
+0 0 7 +0 7 -0 7 +0 7 -0 N N
+0 0 7 +0 7 +0 7 +0 7 +0 N N
+0 0 7 NaN 7 NaN 7 +0 7 +inf N N
+0 0 7 NaN 7 NaN 7 +0 7 NaN N N
+0 0 7 NaN 7 NaN 7 1 7 -inf N N
+0 0 7 NaN 7 NaN 7 1 7 +inf N N
+0 0 7 NaN 7 NaN 7 1 7 NaN N N
+0 0 7 1 7 0 7 +inf 7 -inf N N
+0 0 7 1 7 -0 7 +inf 7 -1 N N
+0 0 7 1 7 -0 7 +inf 7 -0 N N
+0 0 7 1 7 +0 7 +inf 7 +0 N N
+0 0 7 1 7 +0 7 +inf 7 1 N N
+0 0 7 1 7 0 7 +inf 7 +inf N N
+0 0 7 1 7 0 7 +inf 7 NaN N N
+0 0 7 NaN 7 NaN 7 NaN 7 -inf N N
+0 0 7 NaN 7 NaN 7 NaN 7 -1 N N
+0 0 7 NaN 7 -0 7 NaN 7 -0 N N
+0 0 7 NaN 7 +0 7 NaN 7 +0 N N
+0 0 7 NaN 7 NaN 7 NaN 7 1 N N
+0 0 7 NaN 7 NaN 7 NaN 7 +inf N N
+0 0 7 NaN 7 NaN 7 NaN 7 NaN N N
+
+# purely real argument
+- 0 50 -0xc2f7d5a8a79ccp-52 50 -0 7 -1 7 -0 N N
+- 0 50 -0xc2f7d5a8a79ccp-52 50 +0 7 -1 7 +0 N N
++ 0 50 0xc2f7d5a8a79ccp-52 50 -0 7 1 7 -0 N N
++ 0 50 0xc2f7d5a8a79ccp-52 50 +0 7 1 7 +0 N N
+
+# purely imaginary argument
+0 - 50 -0 50 -0x18eb245cbee3a8p-52 7 -0 7 -1 N N
+0 + 50 -0 50 0x18eb245cbee3a8p-52 7 -0 7 1 N N
+0 - 50 +0 50 -0x18eb245cbee3a8p-52 7 +0 7 -1 N N
+0 + 50 +0 50 0x18eb245cbee3a8p-52 7 +0 7 1 N N
+
+# values with +1 and -1
+- - 50 -0x1157bffca4a8cp-48 50 -0x459193d28cfe2p-52 7 -1 7 -1 N N
+- + 50 -0x1157bffca4a8cp-48 50 0x459193d28cfe2p-52 7 -1 7 1 N N
++ - 50 0x1157bffca4a8cp-48 50 -0x459193d28cfe2p-52 7 1 7 -1 N N
++ + 50 0x1157bffca4a8cp-48 50 0x459193d28cfe2p-52 7 1 7 1 N N
+
+# IEEE-754 double precision
++ - 53 0x10000000000001p-53 53 0x1FFFFFFFFFFFFFp-53 53 0x1E938CBCEB16DFp-55 53 0x1B1F56FDEEF00Fp-53 N N
+
diff --git a/mpc/tests/targ.c b/mpc/tests/targ.c
new file mode 100644
index 0000000000..b84c292555
--- /dev/null
+++ b/mpc/tests/targ.c
@@ -0,0 +1,36 @@
+/* targ -- test file for mpc_arg.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (FC, f, mpc_arg);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 1, 4096);
+ data_check (f, "arg.dat");
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tasin.c b/mpc/tests/tasin.c
new file mode 100644
index 0000000000..3470408f40
--- /dev/null
+++ b/mpc/tests/tasin.c
@@ -0,0 +1,36 @@
+/* tasin -- test file for mpc_asin.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_asin);
+
+ test_start ();
+
+ data_check (f, "asin.dat");
+ tgeneric (f, 2, 512, 7, 7);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tasinh.c b/mpc/tests/tasinh.c
new file mode 100644
index 0000000000..c266829266
--- /dev/null
+++ b/mpc/tests/tasinh.c
@@ -0,0 +1,57 @@
+/* tasinh -- test file for mpc_asinh.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+bug20091120 (void)
+{
+ mpc_t x, y;
+
+ mpc_init2 (x, 53);
+ mpc_init3 (y, 17, 42);
+ mpc_set_ui_ui (x, 1, 1, MPC_RNDNN);
+ mpc_asinh (y, x, MPC_RNDNN);
+ if (mpfr_get_prec (mpc_realref(y)) != 17 ||
+ mpfr_get_prec (mpc_imagref(y)) != 42)
+ {
+ printf ("Error, mpc_asinh changed the precisions!!!\n");
+ exit (1);
+ }
+ mpc_clear (x);
+ mpc_clear (y);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_asinh);
+
+ test_start ();
+
+ bug20091120 ();
+
+ data_check (f, "asinh.dat");
+ tgeneric (f, 2, 512, 7, 7);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tatan.c b/mpc/tests/tatan.c
new file mode 100644
index 0000000000..8883588bd1
--- /dev/null
+++ b/mpc/tests/tatan.c
@@ -0,0 +1,68 @@
+/* tatan -- test file for mpc_atan.
+
+Copyright (C) 2009, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+#if 0
+/* tests intermediate underflow; WONTFIX */
+static int
+test_underflow (void)
+{
+ mpc_t z;
+ mpfr_exp_t emin = mpfr_get_emin ();
+
+ mpfr_set_emin (-10);
+ mpc_init2 (z, 21);
+ mpfr_set_si (mpc_realref(z), -1, GMP_RNDZ);
+ mpfr_set_ui_2exp (mpc_imagref(z), 1, 20, GMP_RNDZ);
+ mpfr_add_ui (mpc_imagref(z), mpc_imagref(z), 1, GMP_RNDZ);
+ mpfr_div_2exp (mpc_imagref(z), mpc_imagref(z), 20, GMP_RNDZ);
+ mpc_atan (z, z, MPC_RNDNN);
+ if (mpfr_cmp_si_2exp (mpc_realref(z), -1066635, 20) != 0 ||
+ mpfr_cmp_si_2exp (mpc_imagref(z), 1687619, 22))
+ {
+ printf ("Error in test_coverage\n");
+ printf ("expected (-1066635/2^20 1687619/2^22)\n");
+ printf ("got ");
+ mpc_out_str (stdout, 10, 20, z, MPC_RNDNN);
+ printf ("\n");
+ exit (1);
+ }
+ mpc_clear (z);
+ mpfr_set_emin (emin);
+}
+#endif
+
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_atan);
+
+ test_start ();
+
+ data_check (f, "atan.dat");
+ tgeneric (f, 2, 512, 5, 128);
+
+ test_end ();
+
+ return 0;
+}
+
diff --git a/mpc/tests/tatanh.c b/mpc/tests/tatanh.c
new file mode 100644
index 0000000000..ddba68c99a
--- /dev/null
+++ b/mpc/tests/tatanh.c
@@ -0,0 +1,57 @@
+/* tatanh -- test file for mpc_atanh.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+bug20091120 (void)
+{
+ mpc_t x, y;
+
+ mpc_init2 (x, 53);
+ mpc_init3 (y, 17, 42);
+ mpc_set_ui_ui (x, 1, 1, MPC_RNDNN);
+ mpc_atanh (y, x, MPC_RNDNN);
+ if (mpfr_get_prec (mpc_realref(y)) != 17 ||
+ mpfr_get_prec (mpc_imagref(y)) != 42)
+ {
+ printf ("Error, mpc_atanh changed the precisions!!!\n");
+ exit (1);
+ }
+ mpc_clear (x);
+ mpc_clear (y);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_atanh);
+
+ test_start ();
+
+ bug20091120 ();
+
+ data_check (f, "atanh.dat");
+ tgeneric (f, 2, 512, 5, 128);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tconj.c b/mpc/tests/tconj.c
new file mode 100644
index 0000000000..949a80bdd0
--- /dev/null
+++ b/mpc/tests/tconj.c
@@ -0,0 +1,36 @@
+/* tconj -- test file for mpc_conj.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_conj);
+
+ test_start ();
+
+ data_check (f, "conj.dat");
+ tgeneric (f, 2, 1024, 1, 0);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tcos.c b/mpc/tests/tcos.c
new file mode 100644
index 0000000000..66a85bacc2
--- /dev/null
+++ b/mpc/tests/tcos.c
@@ -0,0 +1,65 @@
+/* tcos -- test file for mpc_cos.
+
+Copyright (C) 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+bug20090105 (void)
+{
+ /* this bug appeared on 32-bits machines */
+ mpc_t op, expected, got;
+ mpc_init2 (op, 324);
+ mpc_init2 (expected, 324);
+ mpc_init2 (got, 324);
+
+ mpfr_set_str (mpc_realref(op), "-3.f1813b1487372434fea4414a520f65a343a16d0ec1ffb"
+ "b2b880154db8d63377ce788fc4215c450300@1", 16, GMP_RNDN);
+ mpfr_set_str (mpc_imagref(op), "-2.b7a0c80bcacf1ccbbac614bf53a58b672b1b503161bee"
+ "59a82e46a23570b652f7ba5f01ef766d1c50", 16,GMP_RNDN);
+ mpfr_set_str (mpc_realref(expected), "7.57c5b08a2b11b660d906a354289b0724b9c4b237"
+ "95abe33424e8d9858e534bd5d776ddd18e34b0240", 16, GMP_RNDN);
+ mpfr_set_str (mpc_imagref(expected), "-1.f41a389646d068e0263561cb3c5d1df763945ad"
+ "ed9339f2a98387a3c4f97dbfd8a08b7d0af2f11b46", 16,GMP_RNDN);
+
+ mpc_cos (got, op, MPC_RNDNN);
+ if (mpc_cmp (got, expected) != 0)
+ TEST_FAILED ("mpc_cos", op, got, expected, MPC_RNDNN);
+
+ mpc_clear (got);
+ mpc_clear(expected);
+ mpc_clear (op);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_cos);
+
+ test_start ();
+
+ data_check (f, "cos.dat");
+ tgeneric (f, 2, 512, 7, 7);
+
+ bug20090105 ();
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tcosh.c b/mpc/tests/tcosh.c
new file mode 100644
index 0000000000..57b5601e97
--- /dev/null
+++ b/mpc/tests/tcosh.c
@@ -0,0 +1,134 @@
+/* test file for mpc_cosh.
+
+Copyright (C) 2008, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+static void
+pure_real_argument (void)
+{
+ /* cosh(x -i*0) = cosh(x) +i*0 if x<0 */
+ /* cosh(x -i*0) = cosh(x) -i*0 if x>0 */
+ /* cosh(x +i*0) = cosh(x) -i*0 if x<0 */
+ /* cosh(x -i*0) = cosh(x) +i*0 if x>0 */
+ mpc_t u;
+ mpc_t z;
+ mpc_t cosh_z;
+
+ mpc_init2 (z, 2);
+ mpc_init2 (u, 100);
+ mpc_init2 (cosh_z, 100);
+
+ /* cosh(1 +i*0) = cosh(1) +i*0 */
+ mpc_set_ui_ui (z, 1, 0, MPC_RNDNN);
+ mpfr_cosh (mpc_realref (u), mpc_realref (z), GMP_RNDN);
+ mpfr_set_ui (mpc_imagref (u), 0, GMP_RNDN);
+ mpc_cosh (cosh_z, z, MPC_RNDNN);
+ if (mpc_cmp (cosh_z, u) != 0 || mpfr_signbit (mpc_imagref (cosh_z)))
+ TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN);
+
+ /* cosh(1 -i*0) = cosh(1) -i*0 */
+ mpc_conj (z, z, MPC_RNDNN);
+ mpc_conj (u, u, MPC_RNDNN);
+ mpc_cosh (cosh_z, z, MPC_RNDNN);
+ if (mpc_cmp (cosh_z, u) != 0 || !mpfr_signbit (mpc_imagref (cosh_z)))
+ TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN);
+
+ /* cosh(-1 +i*0) = cosh(1) -i*0 */
+ mpc_neg (z, z, MPC_RNDNN);
+ mpc_cosh (cosh_z, z, MPC_RNDNN);
+ if (mpc_cmp (cosh_z, u) != 0 || !mpfr_signbit (mpc_imagref (cosh_z)))
+ TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN);
+
+ /* cosh(-1 -i*0) = cosh(1) +i*0 */
+ mpc_conj (z, z, MPC_RNDNN);
+ mpc_conj (u, u, MPC_RNDNN);
+ mpc_cosh (cosh_z, z, MPC_RNDNN);
+ if (mpc_cmp (cosh_z, u) != 0 || mpfr_signbit (mpc_imagref (cosh_z)))
+ TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN);
+
+ mpc_clear (cosh_z);
+ mpc_clear (z);
+ mpc_clear (u);
+}
+
+static void
+pure_imaginary_argument (void)
+{
+ /* cosh(+0 +i*y) = cos y +i*0*sin y */
+ /* cosh(-0 +i*y) = cos y -i*0*sin y */
+ mpc_t u;
+ mpc_t z;
+ mpc_t cosh_z;
+
+ mpc_init2 (z, 2);
+ mpc_init2 (u, 100);
+ mpc_init2 (cosh_z, 100);
+
+ /* cosh(+0 +i) = cos(1) + i*0 */
+ mpc_set_ui_ui (z, 0, 1, MPC_RNDNN);
+ mpfr_cos (mpc_realref (u), mpc_imagref (z), GMP_RNDN);
+ mpfr_set_ui (mpc_imagref (u), 0, GMP_RNDN);
+ mpc_cosh (cosh_z, z, MPC_RNDNN);
+ if (mpc_cmp (cosh_z, u) != 0 || mpfr_signbit (mpc_imagref (cosh_z)))
+ TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN);
+
+ /* cosh(+0 -i) = cos(1) - i*0 */
+ mpc_conj (z, z, MPC_RNDNN);
+ mpc_conj (u, u, MPC_RNDNN);
+ mpc_cosh (cosh_z, z, MPC_RNDNN);
+ if (mpc_cmp (cosh_z, u) != 0 || !mpfr_signbit (mpc_imagref (cosh_z)))
+ TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN);
+
+ /* cosh(-0 +i) = cos(1) - i*0 */
+ mpc_neg (z, z, MPC_RNDNN);
+ mpc_cosh (cosh_z, z, MPC_RNDNN);
+ if (mpc_cmp (cosh_z, u) != 0 || !mpfr_signbit (mpc_imagref (cosh_z)))
+ TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN);
+
+ /* cosh(-0 -i) = cos(1) + i*0 */
+ mpc_conj (z, z, MPC_RNDNN);
+ mpc_conj (u, u, MPC_RNDNN);
+ mpc_cosh (cosh_z, z, MPC_RNDNN);
+ if (mpc_cmp (cosh_z, u) != 0 || mpfr_signbit (mpc_imagref (cosh_z)))
+ TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN);
+
+ mpc_clear (cosh_z);
+ mpc_clear (z);
+ mpc_clear (u);
+}
+
+int
+main (void)
+{
+ DECL_FUNC(CC, f,mpc_cosh);
+
+ test_start ();
+
+ data_check (f, "cosh.dat");
+ tgeneric (f, 2, 512, 7, 7);
+
+ pure_real_argument ();
+ pure_imaginary_argument ();
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tdiv.c b/mpc/tests/tdiv.c
new file mode 100644
index 0000000000..3b8340ff10
--- /dev/null
+++ b/mpc/tests/tdiv.c
@@ -0,0 +1,36 @@
+/* tdiv -- test file for mpc_div.
+
+Copyright (C) 2002, 2008, 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (C_CC, f, mpc_div);
+
+ test_start ();
+
+ data_check (f, "div.dat");
+ tgeneric (f, 2, 1024, 7, 4096);
+
+ test_end ();
+ return 0;
+}
diff --git a/mpc/tests/tdiv_2si.c b/mpc/tests/tdiv_2si.c
new file mode 100644
index 0000000000..5046201185
--- /dev/null
+++ b/mpc/tests/tdiv_2si.c
@@ -0,0 +1,35 @@
+/* tdiv_2si -- test file for mpc_div_2si.
+
+Copyright (C) 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCS, f, mpc_div_2si);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tdiv_2ui.c b/mpc/tests/tdiv_2ui.c
new file mode 100644
index 0000000000..6cc8f1455e
--- /dev/null
+++ b/mpc/tests/tdiv_2ui.c
@@ -0,0 +1,35 @@
+/* tdiv_2ui -- test file for mpc_div_2ui.
+
+Copyright (C) 2008, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCU, f, mpc_div_2ui);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tdiv_fr.c b/mpc/tests/tdiv_fr.c
new file mode 100644
index 0000000000..21e677e084
--- /dev/null
+++ b/mpc/tests/tdiv_fr.c
@@ -0,0 +1,36 @@
+/* test file for mpc_div_fr.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCF, f, mpc_div_fr);
+
+ test_start ();
+
+ data_check (f, "div_fr.dat");
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tdiv_ui.c b/mpc/tests/tdiv_ui.c
new file mode 100644
index 0000000000..5e62d57c0c
--- /dev/null
+++ b/mpc/tests/tdiv_ui.c
@@ -0,0 +1,35 @@
+/* test file for mpc_div_ui.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCU, f, mpc_div_ui);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/texp.c b/mpc/tests/texp.c
new file mode 100644
index 0000000000..0486cce910
--- /dev/null
+++ b/mpc/tests/texp.c
@@ -0,0 +1,36 @@
+/* texp -- test file for mpc_exp.
+
+Copyright (C) 2002, 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_exp);
+
+ test_start ();
+
+ data_check (f, "exp.dat");
+ tgeneric (f, 2, 512, 7, 256);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tfma.c b/mpc/tests/tfma.c
new file mode 100644
index 0000000000..81bc167fe4
--- /dev/null
+++ b/mpc/tests/tfma.c
@@ -0,0 +1,107 @@
+/* tfma -- test file for mpc_fma.
+
+Copyright (C) 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+cmpfma (mpc_srcptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
+ /* computes a*b+c with the naive and fast functions using the rounding
+ mode rnd and compares the results and return values.
+ In our current test suite, all input precisions are the same, and we
+ use this precision also for the result.
+ */
+{
+ mpc_t z, t;
+ int inex_z, inex_t;
+
+ mpc_init2 (z, MPC_MAX_PREC (a));
+ mpc_init2 (t, MPC_MAX_PREC (a));
+
+ inex_z = mpc_fma_naive (z, a, b, c, rnd);
+ inex_t = mpc_fma (t, a, b, c, rnd);
+
+ if (mpc_cmp (z, t) != 0 || inex_z != inex_t) {
+ fprintf (stderr, "fma_naive and fma differ for rnd=(%s,%s)\n",
+ mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
+ mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
+ MPC_OUT (a);
+ MPC_OUT (b);
+ MPC_OUT (c);
+ MPC_OUT (z);
+ MPC_OUT (t);
+ if (inex_z != inex_t) {
+ fprintf (stderr, "inex_re (z): %s\n", MPC_INEX_STR (inex_z));
+ fprintf (stderr, "inex_re (t): %s\n", MPC_INEX_STR (inex_t));
+ }
+ exit (1);
+ }
+
+ mpc_clear (z);
+ mpc_clear (t);
+}
+
+
+static void
+check_random (void)
+{
+ mpfr_prec_t prec;
+ int rnd_re, rnd_im;
+ mpc_t a, b, c;
+
+ mpc_init2 (a, 1000);
+ mpc_init2 (b, 1000);
+ mpc_init2 (c, 1000);
+
+ for (prec = 2; prec < 1000; prec = (mpfr_prec_t) (prec * 1.1 + 1)) {
+ mpc_set_prec (a, prec);
+ mpc_set_prec (b, prec);
+ mpc_set_prec (c, prec);
+
+ test_default_random (a, -1024, 1024, 128, 0);
+ test_default_random (b, -1024, 1024, 128, 0);
+ test_default_random (c, -1024, 1024, 128, 0);
+
+ for (rnd_re = 0; rnd_re < 4; rnd_re ++)
+ for (rnd_im = 0; rnd_im < 4; rnd_im ++)
+ cmpfma (a, b, c, MPC_RND (rnd_re, rnd_im));
+ }
+
+ mpc_clear (a);
+ mpc_clear (b);
+ mpc_clear (c);
+}
+
+
+int
+main (void)
+{
+ DECL_FUNC (CCCC, f, mpc_fma);
+
+ test_start ();
+
+ check_random ();
+
+ data_check (f, "fma.dat");
+ tgeneric (f, 2, 1024, 1, 256);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tfr_div.c b/mpc/tests/tfr_div.c
new file mode 100644
index 0000000000..bea8a21691
--- /dev/null
+++ b/mpc/tests/tfr_div.c
@@ -0,0 +1,34 @@
+/* tfr_div -- test file for mpc_fr_div.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CFC, f, mpc_fr_div);
+ test_start();
+
+ data_check (f, "fr_div.dat");
+ tgeneric (f, 2, 1024, 7, 65535);
+
+ test_end ();
+ return 0;
+}
diff --git a/mpc/tests/tfr_sub.c b/mpc/tests/tfr_sub.c
new file mode 100644
index 0000000000..e366bc68ac
--- /dev/null
+++ b/mpc/tests/tfr_sub.c
@@ -0,0 +1,35 @@
+/* tfr_div -- test file for mpc_fr_sub.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC(CFC, f, mpc_fr_sub);
+
+ test_start();
+
+ data_check (f, "fr_sub.dat");
+ tgeneric (f, 2, 4096, 7, 0);
+
+ test_end ();
+ return 0;
+}
diff --git a/mpc/tests/tgeneric.c b/mpc/tests/tgeneric.c
new file mode 100644
index 0000000000..a2bb460e74
--- /dev/null
+++ b/mpc/tests/tgeneric.c
@@ -0,0 +1,1412 @@
+/* tgeneric.c -- File for generic tests.
+
+Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+/* Warning: unlike the MPFR macro (defined in mpfr-impl.h), this one returns
+ true when b is singular */
+#define MPFR_CAN_ROUND(b,err,prec,rnd) \
+ (mpfr_zero_p (b) || mpfr_inf_p (b) \
+ || mpfr_can_round (b, (long)mpfr_get_prec (b) - (err), (rnd), \
+ GMP_RNDZ, (prec) + ((rnd)==GMP_RNDN)))
+
+/* functions with one input, one output */
+static void
+tgeneric_cc (mpc_function *function, mpc_ptr op, mpc_ptr rop,
+ mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ /* We compute the result with four times the precision and check whether the
+ rounding is correct. Error reports in this part of the algorithm might
+ still be wrong, though, since there are two consecutive roundings (but we
+ try to avoid them). */
+ function->pointer.CC (rop4, op, rnd);
+ function->pointer.CC (rop, op, rnd);
+
+ /* can't use the mpfr_can_round function when argument is singular,
+ use a custom macro instead. */
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ /* avoid double rounding error */
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ /* rounding failed */
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ MPC_OUT (op);
+
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+static void
+tgeneric_cc_c (mpc_function *function, mpc_ptr op, mpc_ptr rop1, mpc_ptr rop2,
+ mpc_ptr rop14, mpc_ptr rop24, mpc_ptr rop14rnd, mpc_ptr rop24rnd,
+ mpc_rnd_t rnd1, mpc_rnd_t rnd2)
+{
+ /* same as the previous function, but for mpc functions computing two
+ results from one argument */
+ known_signs_t ks = {1, 1};
+
+ function->pointer.CC_C (rop14, rop24, op, rnd1, rnd2);
+ function->pointer.CC_C (rop1, rop2, op, rnd1, rnd2);
+
+ if ( MPFR_CAN_ROUND (mpc_realref (rop14), 1, MPC_PREC_RE (rop1),
+ MPC_RND_RE (rnd1))
+ && MPFR_CAN_ROUND (mpc_imagref (rop14), 1, MPC_PREC_IM (rop1),
+ MPC_RND_IM (rnd1))
+ && MPFR_CAN_ROUND (mpc_realref (rop24), 1, MPC_PREC_RE (rop2),
+ MPC_RND_RE (rnd2))
+ && MPFR_CAN_ROUND (mpc_imagref (rop24), 1, MPC_PREC_IM (rop2),
+ MPC_RND_IM (rnd2))) {
+ mpc_set (rop14rnd, rop14, rnd1);
+ mpc_set (rop24rnd, rop24, rnd2);
+ }
+ else
+ return;
+
+ if (!same_mpc_value (rop1, rop14rnd, ks)) {
+ /* rounding failed for first result */
+ printf ("Rounding might be incorrect for the first result of %s at\n", function->name);
+ MPC_OUT (op);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd1)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd1)));
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop1);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop14);
+ printf ("and is rounded to ");
+ MPC_OUT (rop14rnd);
+ exit (1);
+ }
+ else if (!same_mpc_value (rop2, rop24rnd, ks)) {
+ /* rounding failed for second result */
+ printf ("Rounding might be incorrect for the second result of %s at\n", function->name);
+ MPC_OUT (op);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd2)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd2)));
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop2);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop24);
+ printf ("and is rounded to ");
+ MPC_OUT (rop24rnd);
+ exit (1);
+ }
+}
+
+static void
+tgeneric_fc (mpc_function *function, mpc_ptr op, mpfr_ptr rop,
+ mpfr_ptr rop4, mpfr_ptr rop4rnd, mpfr_rnd_t rnd)
+{
+ function->pointer.FC (rop4, op, rnd);
+ function->pointer.FC (rop, op, rnd);
+ if (MPFR_CAN_ROUND (rop4, 1, mpfr_get_prec (rop), rnd))
+ mpfr_set (rop4rnd, rop4, rnd);
+ else
+ return;
+
+ if (same_mpfr_value (rop, rop4rnd, 1))
+ return;
+
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ MPC_OUT (op);
+ printf ("with rounding mode %s", mpfr_print_rnd_mode (rnd));
+
+ printf ("\n%s gives ", function->name);
+ MPFR_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPFR_OUT (rop4);
+ printf ("and is rounded to ");
+ MPFR_OUT (rop4rnd);
+
+ exit (1);
+}
+
+static void
+tgeneric_cfc (mpc_function *function, mpfr_ptr op1, mpc_ptr op2,
+ mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ function->pointer.CFC (rop4, op1, op2, rnd);
+ function->pointer.CFC (rop, op1, op2, rnd);
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ MPFR_OUT (op1);
+ MPC_OUT (op2);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+static void
+tgeneric_ccf (mpc_function *function, mpc_ptr op1, mpfr_ptr op2,
+ mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ function->pointer.CCF (rop4, op1, op2, rnd);
+ function->pointer.CCF (rop, op1, op2, rnd);
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ MPC_OUT (op1);
+ MPFR_OUT (op2);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+/* for functions with one mpc_t output, two mpc_t inputs */
+static void
+tgeneric_c_cc (mpc_function *function, mpc_ptr op1, mpc_ptr op2,
+ mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ /* We compute the result with four times the precision and check whether the
+ rounding is correct. Error reports in this part of the algorithm might
+ still be wrong, though, since there are two consecutive roundings (but we
+ try to avoid them). */
+ function->pointer.C_CC (rop4, op1, op2, rnd);
+ function->pointer.C_CC (rop, op1, op2, rnd);
+
+ /* can't use mpfr_can_round when argument is singular */
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ /* avoid double rounding error */
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ /* rounding failed */
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ MPC_OUT (op1);
+ MPC_OUT (op2);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+static void
+tgeneric_cccc (mpc_function *function, mpc_ptr op1, mpc_ptr op2, mpc_ptr op3,
+ mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ /* We compute the result with four times the precision and check whether the
+ rounding is correct. Error reports in this part of the algorithm might
+ still be wrong, though, since there are two consecutive roundings (but we
+ try to avoid them). */
+ function->pointer.CCCC (rop4, op1, op2, op3, rnd);
+ function->pointer.CCCC (rop, op1, op2, op3, rnd);
+
+ /* can't use mpfr_can_round when argument is singular */
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ /* avoid double rounding error */
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ /* rounding failed */
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ MPC_OUT (op1);
+ MPC_OUT (op2);
+ MPC_OUT (op3);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+static void
+tgeneric_ccu (mpc_function *function, mpc_ptr op1, unsigned long int op2,
+ mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ function->pointer.CCU (rop4, op1, op2, rnd);
+ function->pointer.CCU (rop, op1, op2, rnd);
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ MPC_OUT (op1);
+ printf ("op2=%lu\n", op2);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+static void
+tgeneric_cuc (mpc_function *function, unsigned long int op1, mpc_ptr op2,
+ mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ function->pointer.CUC (rop4, op1, op2, rnd);
+ function->pointer.CUC (rop, op1, op2, rnd);
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ printf ("op1=%lu\n", op1);
+ MPC_OUT (op2);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+static void
+tgeneric_ccs (mpc_function *function, mpc_ptr op1, long int op2,
+ mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ function->pointer.CCS (rop4, op1, op2, rnd);
+ function->pointer.CCS (rop, op1, op2, rnd);
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ MPC_OUT (op1);
+ printf ("op2=%ld\n", op2);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+
+static void
+tgeneric_cci (mpc_function *function, mpc_ptr op1, int op2,
+ mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ function->pointer.CCI (rop4, op1, op2, rnd);
+ function->pointer.CCI (rop, op1, op2, rnd);
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ MPC_OUT (op1);
+ printf ("op2=%d\n", op2);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+static void
+tgeneric_cuuc (mpc_function *function, unsigned long int op1,
+ unsigned long int op2, mpc_ptr op3, mpc_ptr rop,
+ mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
+{
+ known_signs_t ks = {1, 1};
+
+ function->pointer.CUUC (rop4, op1, op2, op3, rnd);
+ function->pointer.CUUC (rop, op1, op2, op3, rnd);
+ if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
+ MPC_RND_RE (rnd))
+ && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
+ MPC_RND_IM (rnd)))
+ mpc_set (rop4rnd, rop4, rnd);
+ else
+ return;
+
+ if (same_mpc_value (rop, rop4rnd, ks))
+ return;
+
+ printf ("Rounding in %s might be incorrect for\n", function->name);
+ printf ("op1=%lu\n", op1);
+ printf ("op2=%lu\n", op2);
+ MPC_OUT (op3);
+ printf ("with rounding mode (%s, %s)",
+ mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
+ mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
+
+ printf ("\n%s gives ", function->name);
+ MPC_OUT (rop);
+ printf ("%s quadruple precision gives ", function->name);
+ MPC_OUT (rop4);
+ printf ("and is rounded to ");
+ MPC_OUT (rop4rnd);
+
+ exit (1);
+}
+
+
+/* Test parameter reuse: the function should not use its output parameter in
+ internal computations. */
+static void
+reuse_cc (mpc_function* function, mpc_srcptr z, mpc_ptr got, mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.CC (expected, z, MPC_RNDNN);
+ function->pointer.CC (got, got, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, z) for\n", function->name);
+ MPC_OUT (z);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+static void
+reuse_cc_c (mpc_function* function, mpc_srcptr z, mpc_ptr got1, mpc_ptr got2,
+ mpc_ptr exp1, mpc_ptr exp2)
+{
+ known_signs_t ks = {1, 1};
+
+ function->pointer.CC_C (exp1, exp2, z, MPC_RNDNN, MPC_RNDNN);
+ mpc_set (got1, z, MPC_RNDNN); /* exact */
+ function->pointer.CC_C (got1, got2, got1, MPC_RNDNN, MPC_RNDNN);
+ if ( !same_mpc_value (got1, exp1, ks)
+ || !same_mpc_value (got2, exp2, ks)) {
+ printf ("Reuse error in first result of %s for\n", function->name);
+ MPC_OUT (z);
+ MPC_OUT (exp1);
+ MPC_OUT (got1);
+ MPC_OUT (exp2);
+ MPC_OUT (got2);
+ exit (1);
+ }
+ mpc_set (got2, z, MPC_RNDNN); /* exact */
+ function->pointer.CC_C (got1, got2, got2, MPC_RNDNN, MPC_RNDNN);
+ if ( !same_mpc_value (got1, exp1, ks)
+ || !same_mpc_value (got2, exp2, ks)) {
+ printf ("Reuse error in second result of %s for\n", function->name);
+ MPC_OUT (z);
+ MPC_OUT (exp1);
+ MPC_OUT (got1);
+ MPC_OUT (exp2);
+ MPC_OUT (got2);
+ exit (1);
+ }
+}
+
+static void
+reuse_fc (mpc_function* function, mpc_ptr z, mpc_ptr x, mpfr_ptr expected)
+{
+ mpc_set (x, z, MPC_RNDNN); /* exact */
+ function->pointer.FC (expected, z, GMP_RNDN);
+ function->pointer.FC (mpc_realref (x), x, GMP_RNDN);
+ if (!same_mpfr_value (mpc_realref (x), expected, 1))
+ {
+ mpfr_t got;
+ got[0] = mpc_realref(x)[0]; /* display sensible name */
+ printf ("Reuse error for %s(mpc_realref(z), z) for\n", function->name);
+ MPC_OUT (z);
+ MPFR_OUT (expected);
+ MPFR_OUT (got);
+
+ exit (1);
+ }
+ mpc_set (x, z, MPC_RNDNN); /* exact */
+ function->pointer.FC (mpc_imagref (x), x, GMP_RNDN);
+ if (!same_mpfr_value (mpc_imagref (x), expected, 1))
+ {
+ mpfr_t got;
+ got[0] = mpc_imagref(x)[0]; /* display sensible name */
+ printf ("Reuse error for %s(mpc_imagref(z), z) for \n", function->name);
+ MPC_OUT (z);
+ MPFR_OUT (expected);
+ MPFR_OUT (got);
+
+ exit (1);
+ }
+}
+
+static void
+reuse_cfc (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got,
+ mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.CFC (expected, x, z, MPC_RNDNN);
+ function->pointer.CFC (got, x, got, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, x, z) for\n", function->name);
+ MPFR_OUT (x);
+ MPC_OUT (z);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+static void
+reuse_ccf (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got,
+ mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.CCF (expected, z, x, MPC_RNDNN);
+ function->pointer.CCF (got, got, x, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, z, x, RNDNN) for\n", function->name);
+ MPC_OUT (z);
+ MPFR_OUT (x);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+/* for functions with one mpc_t output, two mpc_t inputs */
+static void
+reuse_c_cc (mpc_function* function, mpc_srcptr z, mpc_srcptr x,
+ mpc_ptr got, mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.C_CC (expected, z, x, MPC_RNDNN);
+ function->pointer.C_CC (got, got, x, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, z, x) for\n", function->name);
+ MPC_OUT (z);
+ MPC_OUT (x);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+ mpc_set (got, x, MPC_RNDNN); /* exact */
+ function->pointer.C_CC (expected, z, x, MPC_RNDNN);
+ function->pointer.C_CC (got, z, got, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(x, z, x) for\n", function->name);
+ MPC_OUT (z);
+ MPC_OUT (x);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+ mpc_set (got, x, MPC_RNDNN); /* exact */
+ function->pointer.C_CC (expected, x, x, MPC_RNDNN);
+ function->pointer.C_CC (got, got, got, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(x, x, x) for\n", function->name);
+ MPC_OUT (x);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+static void
+reuse_cccc (mpc_function* function, mpc_srcptr z, mpc_srcptr x, mpc_srcptr y,
+ mpc_ptr got, mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.CCCC (expected, z, x, y, MPC_RNDNN);
+ function->pointer.CCCC (got, got, x, y, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, z, x, y) for\n", function->name);
+ MPC_OUT (z);
+ MPC_OUT (x);
+ MPC_OUT (y);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+
+ mpc_set (got, x, MPC_RNDNN); /* exact */
+ function->pointer.CCCC (expected, z, x, y, MPC_RNDNN);
+ function->pointer.CCCC (got, z, got, y, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(x, z, x, y) for\n", function->name);
+ MPC_OUT (z);
+ MPC_OUT (x);
+ MPC_OUT (y);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+
+ mpc_set (got, y, MPC_RNDNN); /* exact */
+ function->pointer.CCCC (expected, z, x, y, MPC_RNDNN);
+ function->pointer.CCCC (got, z, x, got, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(y, z, x, y) for\n", function->name);
+ MPC_OUT (z);
+ MPC_OUT (x);
+ MPC_OUT (y);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+
+ mpc_set (got, x, MPC_RNDNN); /* exact */
+ function->pointer.CCCC (expected, x, x, x, MPC_RNDNN);
+ function->pointer.CCCC (got, got, got, got, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(x, x, x, x) for\n", function->name);
+ MPC_OUT (x);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+static void
+reuse_ccu (mpc_function* function, mpc_srcptr z, unsigned long ul,
+ mpc_ptr got, mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.CCU (expected, z, ul, MPC_RNDNN);
+ function->pointer.CCU (got, got, ul, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, z, n) for\n", function->name);
+ MPC_OUT (z);
+ printf ("n=%lu\n", ul);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+static void
+reuse_cuc (mpc_function* function, unsigned long ul, mpc_srcptr z,
+ mpc_ptr got, mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.CUC (expected, ul, z,MPC_RNDNN);
+ function->pointer.CUC (got, ul, got, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, n, z) for\n", function->name);
+ printf ("n=%lu\n", ul);
+ MPC_OUT (z);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+static void
+reuse_ccs (mpc_function* function, mpc_srcptr z, long lo,
+ mpc_ptr got, mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.CCS (expected, z, lo, MPC_RNDNN);
+ function->pointer.CCS (got, got, lo, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, z, n) for\n", function->name);
+ MPC_OUT (z);
+ printf ("n=%ld\n", lo);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+static void
+reuse_cci (mpc_function* function, mpc_srcptr z, int i,
+ mpc_ptr got, mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.CCI (expected, z, i, MPC_RNDNN);
+ function->pointer.CCI (got, got, i, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, z, n) for\n", function->name);
+ MPC_OUT (z);
+ printf ("n=%d\n", i);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+static void
+reuse_cuuc (mpc_function* function, unsigned long ul1, unsigned long ul2,
+ mpc_srcptr z, mpc_ptr got, mpc_ptr expected)
+{
+ known_signs_t ks = {1, 1};
+
+ mpc_set (got, z, MPC_RNDNN); /* exact */
+ function->pointer.CUUC (expected, ul1, ul2, z,MPC_RNDNN);
+ function->pointer.CUUC (got, ul1, ul2, got, MPC_RNDNN);
+ if (!same_mpc_value (got, expected, ks))
+ {
+ printf ("Reuse error for %s(z, m, n, z) for\n", function->name);
+ printf ("m=%lu\n", ul1);
+ printf ("n=%lu\n", ul2);
+ MPC_OUT (z);
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+}
+
+
+/* helper functions for iterating over mpfr rounding modes */
+static mpfr_rnd_t
+first_rnd_mode (void)
+{
+ return GMP_RNDN;
+}
+
+static mpfr_rnd_t
+next_rnd_mode (mpfr_rnd_t curr)
+ /* assumes that all rounding modes are non-negative, and returns -1
+ when curr is the last rounding mode */
+{
+ switch (curr) {
+ case GMP_RNDN:
+ return GMP_RNDZ;
+ case GMP_RNDZ:
+ return GMP_RNDU;
+ case GMP_RNDU:
+ return GMP_RNDD;
+ default:
+ /* return invalid guard value in mpfr_rnd_t */
+#if MPFR_VERSION_MAJOR < 3
+ return GMP_RNDNA;
+#else
+ return MPFR_RNDA; /* valid rounding type, but not (yet) used in mpc */
+#endif
+ }
+}
+
+static int
+is_valid_rnd_mode (mpfr_rnd_t curr)
+ /* returns 1 if curr is a valid rounding mode, and 0otherwise */
+{
+ if ( curr == GMP_RNDN || curr == GMP_RNDZ
+ || curr == GMP_RNDU || curr == GMP_RNDD)
+ return 1;
+ else
+ return 0;
+}
+
+/* tgeneric(prec_min, prec_max, step, exp_max) checks rounding with random
+ numbers:
+ - with precision ranging from prec_min to prec_max with an increment of
+ step,
+ - with exponent between -exp_max and exp_max.
+
+ It also checks parameter reuse (it is assumed here that either two mpc_t
+ variables are equal or they are different, in the sense that the real part
+ of one of them cannot be the imaginary part of the other). */
+void
+tgeneric (mpc_function function, mpfr_prec_t prec_min,
+ mpfr_prec_t prec_max, mpfr_prec_t step, mpfr_exp_t exp_max)
+{
+ unsigned long ul1 = 0, ul2 = 0;
+ long lo = 0;
+ int i = 0;
+ mpfr_t x1, x2, xxxx;
+ mpc_t z1, z2, z3, z4, z5, zzzz, zzzz2;
+
+ mpfr_rnd_t rnd_re, rnd_im, rnd2_re, rnd2_im;
+ mpfr_prec_t prec;
+ mpfr_exp_t exp_min;
+ int special, special_cases;
+
+ mpc_init2 (z1, prec_max);
+ switch (function.type)
+ {
+ case C_CC:
+ mpc_init2 (z2, prec_max);
+ mpc_init2 (z3, prec_max);
+ mpc_init2 (z4, prec_max);
+ mpc_init2 (zzzz, 4*prec_max);
+ special_cases = 8;
+ break;
+ case CCCC:
+ mpc_init2 (z2, prec_max);
+ mpc_init2 (z3, prec_max);
+ mpc_init2 (z4, prec_max);
+ mpc_init2 (z5, prec_max);
+ mpc_init2 (zzzz, 4*prec_max);
+ special_cases = 8;
+ break;
+ case FC:
+ mpfr_init2 (x1, prec_max);
+ mpfr_init2 (x2, prec_max);
+ mpfr_init2 (xxxx, 4*prec_max);
+ mpc_init2 (z2, prec_max);
+ special_cases = 4;
+ break;
+ case CCF: case CFC:
+ mpfr_init2 (x1, prec_max);
+ mpc_init2 (z2, prec_max);
+ mpc_init2 (z3, prec_max);
+ mpc_init2 (zzzz, 4*prec_max);
+ special_cases = 6;
+ break;
+ case CCI: case CCS:
+ case CCU: case CUC:
+ mpc_init2 (z2, prec_max);
+ mpc_init2 (z3, prec_max);
+ mpc_init2 (zzzz, 4*prec_max);
+ special_cases = 5;
+ break;
+ case CUUC:
+ mpc_init2 (z2, prec_max);
+ mpc_init2 (z3, prec_max);
+ mpc_init2 (zzzz, 4*prec_max);
+ special_cases = 6;
+ break;
+ case CC_C:
+ mpc_init2 (z2, prec_max);
+ mpc_init2 (z3, prec_max);
+ mpc_init2 (z4, prec_max);
+ mpc_init2 (z5, prec_max);
+ mpc_init2 (zzzz, 4*prec_max);
+ mpc_init2 (zzzz2, 4*prec_max);
+ special_cases = 4;
+ break;
+ case CC:
+ default:
+ mpc_init2 (z2, prec_max);
+ mpc_init2 (z3, prec_max);
+ mpc_init2 (zzzz, 4*prec_max);
+ special_cases = 4;
+ }
+
+ exp_min = mpfr_get_emin ();
+ if (exp_max <= 0 || exp_max > mpfr_get_emax ())
+ exp_max = mpfr_get_emax();
+ if (-exp_max > exp_min)
+ exp_min = - exp_max;
+
+ if (step < 1)
+ step = 1;
+
+ for (prec = prec_min, special = 0;
+ prec <= prec_max || special <= special_cases;
+ prec+=step, special += (prec > prec_max ? 1 : 0)) {
+ /* In the end, test functions in special cases of purely real, purely
+ imaginary or infinite arguments. */
+
+ /* probability of one zero part in 256th (25 is almost 10%) */
+ const unsigned int zero_probability = special != 0 ? 0 : 25;
+
+ mpc_set_prec (z1, prec);
+ test_default_random (z1, exp_min, exp_max, 128, zero_probability);
+
+ switch (function.type)
+ {
+ case C_CC:
+ mpc_set_prec (z2, prec);
+ test_default_random (z2, exp_min, exp_max, 128, zero_probability);
+ mpc_set_prec (z3, prec);
+ mpc_set_prec (z4, prec);
+ mpc_set_prec (zzzz, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ case 5:
+ mpfr_set_ui (mpc_realref (z2), 0, GMP_RNDN);
+ break;
+ case 6:
+ mpfr_set_inf (mpc_realref (z2), -1);
+ break;
+ case 7:
+ mpfr_set_ui (mpc_imagref (z2), 0, GMP_RNDN);
+ break;
+ case 8:
+ mpfr_set_inf (mpc_imagref (z2), +1);
+ break;
+ }
+ break;
+ case CCCC:
+ mpc_set_prec (z2, prec);
+ test_default_random (z2, exp_min, exp_max, 128, zero_probability);
+ mpc_set_prec (z3, prec);
+ mpc_set_prec (z4, prec);
+ mpc_set_prec (z5, prec);
+ mpc_set_prec (zzzz, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ case 5:
+ mpfr_set_ui (mpc_realref (z2), 0, GMP_RNDN);
+ break;
+ case 6:
+ mpfr_set_inf (mpc_realref (z2), -1);
+ break;
+ case 7:
+ mpfr_set_ui (mpc_imagref (z2), 0, GMP_RNDN);
+ break;
+ case 8:
+ mpfr_set_inf (mpc_imagref (z2), +1);
+ break;
+ }
+ break;
+ case FC:
+ mpc_set_prec (z2, prec);
+ mpfr_set_prec (x1, prec);
+ mpfr_set_prec (x2, prec);
+ mpfr_set_prec (xxxx, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ }
+ break;
+ case CCU: case CUC:
+ mpc_set_prec (z2, 128);
+ do {
+ test_default_random (z2, 0, 64, 128, zero_probability);
+ } while (!mpfr_fits_ulong_p (mpc_realref (z2), GMP_RNDN));
+ ul1 = mpfr_get_ui (mpc_realref(z2), GMP_RNDN);
+ mpc_set_prec (z2, prec);
+ mpc_set_prec (z3, prec);
+ mpc_set_prec (zzzz, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ case 5:
+ ul1 = 0;
+ break;
+ }
+ break;
+ case CUUC:
+ mpc_set_prec (z2, 128);
+ do {
+ test_default_random (z2, 0, 64, 128, zero_probability);
+ } while (!mpfr_fits_ulong_p (mpc_realref (z2), GMP_RNDN)
+ ||!mpfr_fits_ulong_p (mpc_imagref (z2), GMP_RNDN));
+ ul1 = mpfr_get_ui (mpc_realref(z2), GMP_RNDN);
+ ul2 = mpfr_get_ui (mpc_imagref(z2), GMP_RNDN);
+ mpc_set_prec (z2, prec);
+ mpc_set_prec (z3, prec);
+ mpc_set_prec (zzzz, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ case 5:
+ ul1 = 0;
+ break;
+ case 6:
+ ul2 = 0;
+ break;
+ }
+ break;
+ case CCS:
+ mpc_set_prec (z2, 128);
+ do {
+ test_default_random (z2, 0, 64, 128, zero_probability);
+ } while (!mpfr_fits_slong_p (mpc_realref (z2), GMP_RNDN));
+ lo = mpfr_get_si (mpc_realref(z2), GMP_RNDN);
+ mpc_set_prec (z2, prec);
+ mpc_set_prec (z3, prec);
+ mpc_set_prec (zzzz, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ case 5:
+ lo = 0;
+ break;
+ }
+ break;
+ case CCI:
+ mpc_set_prec (z2, 128);
+ do {
+ test_default_random (z2, 0, 64, 128, zero_probability);
+ } while (!mpfr_fits_slong_p (mpc_realref (z2), GMP_RNDN));
+ i = (int)mpfr_get_si (mpc_realref(z2), GMP_RNDN);
+ mpc_set_prec (z2, prec);
+ mpc_set_prec (z3, prec);
+ mpc_set_prec (zzzz, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ case 5:
+ i = 0;
+ break;
+ }
+ break;
+ case CCF: case CFC:
+ mpfr_set_prec (x1, prec);
+ mpfr_set (x1, mpc_realref (z1), GMP_RNDN);
+ test_default_random (z1, exp_min, exp_max, 128, zero_probability);
+ mpc_set_prec (z2, prec);
+ mpc_set_prec (z3, prec);
+ mpc_set_prec (zzzz, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ case 5:
+ mpfr_set_ui (x1, 0, GMP_RNDN);
+ break;
+ case 6:
+ mpfr_set_inf (x1, +1);
+ break;
+ }
+ break;
+ case CC_C:
+ mpc_set_prec (z2, prec);
+ mpc_set_prec (z3, prec);
+ mpc_set_prec (z4, prec);
+ mpc_set_prec (z5, prec);
+ mpc_set_prec (zzzz, 4*prec);
+ mpc_set_prec (zzzz2, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ }
+ break;
+ case CC:
+ default:
+ mpc_set_prec (z2, prec);
+ mpc_set_prec (z3, prec);
+ mpc_set_prec (zzzz, 4*prec);
+ switch (special)
+ {
+ case 1:
+ mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
+ break;
+ case 2:
+ mpfr_set_inf (mpc_realref (z1), +1);
+ break;
+ case 3:
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ break;
+ case 4:
+ mpfr_set_inf (mpc_imagref (z1), -1);
+ break;
+ }
+ }
+
+ for (rnd_re = first_rnd_mode (); is_valid_rnd_mode (rnd_re); rnd_re = next_rnd_mode (rnd_re))
+ switch (function.type)
+ {
+ case C_CC:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_c_cc (&function, z1, z2, z3, zzzz, z4,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_c_cc (&function, z1, z2, z3, z4);
+ break;
+ case CCCC:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_cccc (&function, z1, z2, z3, z4, zzzz, z5,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_cccc (&function, z1, z2, z3, z4, z5);
+ break;
+ case FC:
+ tgeneric_fc (&function, z1, x1, xxxx, x2, rnd_re);
+ reuse_fc (&function, z1, z2, x1);
+ break;
+ case CC:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_cc (&function, z1, z2, zzzz, z3,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_cc (&function, z1, z2, z3);
+ break;
+ case CC_C:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ for (rnd2_re = first_rnd_mode (); is_valid_rnd_mode (rnd2_re); rnd2_re = next_rnd_mode (rnd2_re))
+ for (rnd2_im = first_rnd_mode (); is_valid_rnd_mode (rnd2_im); rnd2_im = next_rnd_mode (rnd2_im))
+ tgeneric_cc_c (&function, z1, z2, z3, zzzz, zzzz2, z4, z5,
+ MPC_RND (rnd_re, rnd_im), MPC_RND (rnd2_re, rnd2_im));
+ reuse_cc_c (&function, z1, z2, z3, z4, z5);
+ break;
+ case CFC:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_cfc (&function, x1, z1, z2, zzzz, z3,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_cfc (&function, z1, x1, z2, z3);
+ break;
+ case CCF:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_ccf (&function, z1, x1, z2, zzzz, z3,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_ccf (&function, z1, x1, z2, z3);
+ break;
+ case CCU:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_ccu (&function, z1, ul1, z2, zzzz, z3,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_ccu (&function, z1, ul1, z2, z3);
+ break;
+ case CUC:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_cuc (&function, ul1, z1, z2, zzzz, z3,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_cuc (&function, ul1, z1, z2, z3);
+ break;
+ case CCS:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_ccs (&function, z1, lo, z2, zzzz, z3,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_ccs (&function, z1, lo, z2, z3);
+ break;
+ case CCI:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_cci (&function, z1, i, z2, zzzz, z3,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_cci (&function, z1, i, z2, z3);
+ break;
+ case CUUC:
+ for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im))
+ tgeneric_cuuc (&function, ul1, ul2, z1, z2, zzzz, z3,
+ MPC_RND (rnd_re, rnd_im));
+ reuse_cuuc (&function, ul1, ul2, z1, z2, z3);
+ break;
+ default:
+ printf ("tgeneric not yet implemented for this kind of"
+ "function\n");
+ exit (1);
+ }
+ }
+
+ mpc_clear (z1);
+ switch (function.type)
+ {
+ case C_CC:
+ mpc_clear (z2);
+ mpc_clear (z3);
+ mpc_clear (z4);
+ mpc_clear (zzzz);
+ break;
+ case CCCC:
+ mpc_clear (z2);
+ mpc_clear (z3);
+ mpc_clear (z4);
+ mpc_clear (z5);
+ mpc_clear (zzzz);
+ break;
+ case FC:
+ mpc_clear (z2);
+ mpfr_clear (x1);
+ mpfr_clear (x2);
+ mpfr_clear (xxxx);
+ break;
+ case CCF: case CFC:
+ mpfr_clear (x1);
+ mpc_clear (z2);
+ mpc_clear (z3);
+ mpc_clear (zzzz);
+ break;
+ case CC_C:
+ mpc_clear (z2);
+ mpc_clear (z3);
+ mpc_clear (z4);
+ mpc_clear (z5);
+ mpc_clear (zzzz);
+ mpc_clear (zzzz2);
+ break;
+ case CUUC:
+ case CCI: case CCS:
+ case CCU: case CUC:
+ case CC:
+ default:
+ mpc_clear (z2);
+ mpc_clear (z3);
+ mpc_clear (zzzz);
+ }
+}
diff --git a/mpc/tests/tget_version.c b/mpc/tests/tget_version.c
new file mode 100644
index 0000000000..2d42f3f848
--- /dev/null
+++ b/mpc/tests/tget_version.c
@@ -0,0 +1,62 @@
+/* tget_version -- Test file for mpc_get_version
+
+Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+#ifdef __MPIR_VERSION
+ printf ("MPIR: include %d.%d.%d, lib %s\n",
+ __MPIR_VERSION, __MPIR_VERSION_MINOR, __MPIR_VERSION_PATCHLEVEL,
+ mpir_version);
+#else
+ printf ("GMP: include %d.%d.%d, lib %s\n",
+ __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL,
+ gmp_version);
+#endif
+ printf ("MPFR: include %s, lib %s\n",
+ MPFR_VERSION_STRING,
+ mpfr_get_version ());
+ printf ("MPC: include %s, lib %s\n", MPC_VERSION_STRING,
+ mpc_get_version ());
+
+ if (strcmp (mpc_get_version (), MPC_VERSION_STRING) != 0)
+ {
+ printf ("Error: header and library do not match\n"
+ "mpc_get_version: \"%s\"\nMPC_VERSION_STRING: \"%s\"\n",
+ mpc_get_version(), MPC_VERSION_STRING);
+ exit (1);
+ }
+
+#ifdef MPC_CC
+ printf ("C compiler: %s\n", MPC_CC);
+#endif
+#ifdef MPC_GCC
+ printf ("GCC: %s\n", MPC_GCC);
+#endif
+#ifdef MPC_GCC_VERSION
+ printf ("GCC version: %s\n", MPC_GCC_VERSION);
+#endif
+
+ return 0;
+}
diff --git a/mpc/tests/timag.c b/mpc/tests/timag.c
new file mode 100644
index 0000000000..47cf52c875
--- /dev/null
+++ b/mpc/tests/timag.c
@@ -0,0 +1,35 @@
+/* timag -- test file for mpc_imag.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (FC, f, mpc_imag);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 1, 4096);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tio_str.c b/mpc/tests/tio_str.c
new file mode 100644
index 0000000000..af5a6693e2
--- /dev/null
+++ b/mpc/tests/tio_str.c
@@ -0,0 +1,252 @@
+/* tio_str-- Test file for mpc_inp_str and mpc_out_str.
+
+Copyright (C) 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+#ifdef HAVE_UNISTD_H
+#define _POSIX_C_SOURCE 1 /* apparently needed on Darwin */
+#include <unistd.h> /* for dup, dup2, STDIN_FILENO and STDOUT_FILENO */
+#else
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#endif
+
+extern unsigned long line_number;
+/* character appearing next in the file, may be EOF */
+extern int nextchar;
+extern const char *rnd_mode[];
+
+static void
+check_file (const char* file_name)
+{
+ FILE *fp;
+
+ int tmp;
+ int base;
+ int inex_re;
+ int inex_im;
+ mpc_t expected, got;
+ mpc_rnd_t rnd = MPC_RNDNN;
+ int inex = 0, expected_inex;
+ size_t expected_size, size;
+ known_signs_t ks = {1, 1};
+
+ fp = open_data_file (file_name);
+
+ mpc_init2 (expected, 53);
+ mpc_init2 (got, 53);
+
+ /* read data file */
+ line_number = 1;
+ nextchar = getc (fp);
+ skip_whitespace_comments (fp);
+
+ while (nextchar != EOF)
+ {
+ /* 1. read a line of data: expected result, base, rounding mode */
+ read_ternary (fp, &inex_re);
+ read_ternary (fp, &inex_im);
+ read_mpc (fp, expected, &ks);
+ if (inex_re == TERNARY_ERROR || inex_im == TERNARY_ERROR)
+ expected_inex = -1;
+ else
+ expected_inex = MPC_INEX (inex_re, inex_im);
+ read_int (fp, &tmp, "size");
+ expected_size = (size_t)tmp;
+ read_int (fp, &base, "base");
+ read_mpc_rounding_mode (fp, &rnd);
+
+ /* 2. read string at the same precision as the expected result */
+ while (nextchar != '"')
+ nextchar = getc (fp);
+ mpfr_set_prec (mpc_realref (got), MPC_PREC_RE (expected));
+ mpfr_set_prec (mpc_imagref (got), MPC_PREC_IM (expected));
+ inex = mpc_inp_str (got, fp, &size, base, rnd);
+
+ /* 3. compare this result with the expected one */
+ if (inex != expected_inex || !same_mpc_value (got, expected, ks)
+ || size != expected_size)
+ {
+ printf ("mpc_inp_str failed (line %lu) with rounding mode %s\n",
+ line_number, rnd_mode[rnd]);
+ if (inex != expected_inex)
+ printf(" got inexact value: %d\nexpected inexact value: %d\n",
+ inex, expected_inex);
+ if (size != expected_size)
+ printf (" got size: %lu\nexpected size: %lu\n ",
+ (unsigned long int) size, (unsigned long int) expected_size);
+ printf (" ");
+ MPC_OUT (got);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+
+ while ((nextchar = getc (fp)) != '"');
+ nextchar = getc (fp);
+
+ skip_whitespace_comments (fp);
+ }
+
+ mpc_clear (expected);
+ mpc_clear (got);
+ close_data_file (fp);
+}
+
+static void
+check_io_str (mpc_ptr read_number, mpc_ptr expected)
+{
+ char tmp_file[] = "mpc_test";
+ FILE *fp;
+ size_t sz;
+
+ if (!(fp = fopen (tmp_file, "w")))
+ {
+ printf ("Error: Could not open file %s in write mode\n", tmp_file);
+ exit (1);
+ }
+
+ mpc_out_str (fp, 10, 0, expected, MPC_RNDNN);
+ fclose (fp);
+
+ if (!(fp = fopen (tmp_file, "r")))
+ {
+ printf ("Error: Could not open file %s in read mode\n", tmp_file);
+ exit (1);
+ };
+ if (mpc_inp_str (read_number, fp, &sz, 10, MPC_RNDNN) == -1)
+ {
+ printf ("Error: mpc_inp_str cannot correctly re-read number "
+ "in file %s\n", tmp_file);
+
+ exit (1);
+ }
+ fclose (fp);
+
+ /* mpc_cmp set erange flag when an operand is a NaN */
+ mpfr_clear_flags ();
+ if (mpc_cmp (read_number, expected) != 0 || mpfr_erangeflag_p())
+ {
+ printf ("Error: inp_str o out_str <> Id\n");
+ MPC_OUT (read_number);
+ MPC_OUT (expected);
+
+ exit (1);
+ }
+}
+
+#ifndef MPC_NO_STREAM_REDIRECTION
+/* test out_str with stream=NULL */
+static void
+check_stdout (mpc_ptr read_number, mpc_ptr expected)
+{
+ char tmp_file[] = "mpc_test";
+ int fd;
+ size_t sz;
+
+ fflush (stdout);
+ fd = dup (STDOUT_FILENO);
+ if (freopen (tmp_file, "w", stdout) == NULL)
+ {
+ printf ("mpc_inp_str cannot redirect stdout\n");
+ exit (1);
+ }
+ mpc_out_str (NULL, 2, 0, expected, MPC_RNDNN);
+ fflush (stdout);
+ dup2 (fd, STDOUT_FILENO);
+ close (fd);
+ clearerr (stdout);
+
+ fflush (stdin);
+ fd = dup (STDIN_FILENO);
+ if (freopen (tmp_file, "r", stdin) == NULL)
+ {
+ printf ("mpc_inp_str cannot redirect stdout\n");
+ exit (1);
+ }
+ if (mpc_inp_str (read_number, NULL, &sz, 2, MPC_RNDNN) == -1)
+ {
+ printf ("mpc_inp_str cannot correctly re-read number "
+ "in file %s\n", tmp_file);
+ exit (1);
+ }
+ mpfr_clear_flags (); /* mpc_cmp set erange flag when an operand is
+ a NaN */
+ if (mpc_cmp (read_number, expected) != 0 || mpfr_erangeflag_p())
+ {
+ printf ("mpc_inp_str did not read the number which was written by "
+ "mpc_out_str\n");
+ MPC_OUT (read_number);
+ MPC_OUT (expected);
+ exit (1);
+ }
+ fflush (stdin);
+ dup2 (fd, STDIN_FILENO);
+ close (fd);
+ clearerr (stdin);
+}
+#endif /* MPC_NO_STREAM_REDIRECTION */
+
+int
+main (void)
+{
+ mpc_t z, x;
+ mpfr_prec_t prec;
+
+ test_start ();
+
+ mpc_init2 (z, 1000);
+ mpc_init2 (x, 1000);
+
+ check_file ("inp_str.dat");
+
+ for (prec = 2; prec <= 1000; prec+=7)
+ {
+ mpc_set_prec (z, prec);
+ mpc_set_prec (x, prec);
+
+ mpc_set_si_si (x, 1, 1, MPC_RNDNN);
+ check_io_str (z, x);
+
+ mpc_set_si_si (x, -1, 1, MPC_RNDNN);
+ check_io_str (z, x);
+
+ mpfr_set_inf (mpc_realref(x), -1);
+ mpfr_set_inf (mpc_imagref(x), +1);
+ check_io_str (z, x);
+
+ test_default_random (x, -1024, 1024, 128, 25);
+ check_io_str (z, x);
+ }
+
+#ifndef MPC_NO_STREAM_REDIRECTION
+ mpc_set_si_si (x, 1, -4, MPC_RNDNN);
+ mpc_div_ui (x, x, 3, MPC_RNDDU);
+
+ check_stdout(z, x);
+#endif
+
+ mpc_clear (z);
+ mpc_clear (x);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tlog.c b/mpc/tests/tlog.c
new file mode 100644
index 0000000000..83f528dfdd
--- /dev/null
+++ b/mpc/tests/tlog.c
@@ -0,0 +1,37 @@
+/* tlog -- test file for mpc_log.
+
+Copyright (C) 2008, 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_log);
+
+ test_start ();
+
+ data_check (f, "log.dat");
+ tgeneric (f, 2, 512, 7, 128);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tlog10.c b/mpc/tests/tlog10.c
new file mode 100644
index 0000000000..5591b0622b
--- /dev/null
+++ b/mpc/tests/tlog10.c
@@ -0,0 +1,37 @@
+/* tlog10 -- test file for mpc_log10.
+
+Copyright (C) 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_log10);
+
+ test_start ();
+
+ data_check (f, "log10.dat");
+ tgeneric (f, 2, 512, 7, 128);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tmul.c b/mpc/tests/tmul.c
new file mode 100644
index 0000000000..46d3bb3244
--- /dev/null
+++ b/mpc/tests/tmul.c
@@ -0,0 +1,201 @@
+/* tmul -- test file for mpc_mul.
+
+Copyright (C) 2002, 2005, 2008, 2009, 2010, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#ifdef TIMING
+#include <sys/times.h>
+#endif
+#include "mpc-tests.h"
+
+static void
+cmpmul (mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd)
+ /* computes the product of x and y with the naive and Karatsuba methods */
+ /* using the rounding mode rnd and compares the results and return */
+ /* values. */
+ /* In our current test suite, the real and imaginary parts of x and y */
+ /* all have the same precision, and we use this precision also for the */
+ /* result. */
+{
+ mpc_t z, t;
+ int inex_z, inex_t;
+
+ mpc_init2 (z, MPC_MAX_PREC (x));
+ mpc_init2 (t, MPC_MAX_PREC (x));
+
+ inex_z = mpc_mul_naive (z, x, y, rnd);
+ inex_t = mpc_mul_karatsuba (t, x, y, rnd);
+
+ if (mpc_cmp (z, t) != 0 || inex_z != inex_t) {
+ fprintf (stderr, "mul_naive and mul_karatsuba differ for rnd=(%s,%s)\n",
+ mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
+ mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
+ MPC_OUT (x);
+ MPC_OUT (y);
+ MPC_OUT (z);
+ MPC_OUT (t);
+ if (inex_z != inex_t) {
+ fprintf (stderr, "inex_re (z): %s\n", MPC_INEX_STR (inex_z));
+ fprintf (stderr, "inex_re (t): %s\n", MPC_INEX_STR (inex_t));
+ }
+ exit (1);
+ }
+
+ mpc_clear (z);
+ mpc_clear (t);
+}
+
+
+static void
+testmul (long a, long b, long c, long d, mpfr_prec_t prec, mpc_rnd_t rnd)
+{
+ mpc_t x, y;
+
+ mpc_init2 (x, prec);
+ mpc_init2 (y, prec);
+
+ mpc_set_si_si (x, a, b, rnd);
+ mpc_set_si_si (y, c, d, rnd);
+
+ cmpmul (x, y, rnd);
+
+ mpc_clear (x);
+ mpc_clear (y);
+}
+
+
+static void
+check_regular (void)
+{
+ mpc_t x, y;
+ int rnd_re, rnd_im;
+ mpfr_prec_t prec;
+
+ testmul (247, -65, -223, 416, 8, 24);
+ testmul (5, -896, 5, -32, 3, 2);
+ testmul (-3, -512, -1, -1, 2, 16);
+ testmul (266013312, 121990769, 110585572, 116491059, 27, 0);
+ testmul (170, 9, 450, 251, 8, 0);
+ testmul (768, 85, 169, 440, 8, 16);
+ testmul (145, 1816, 848, 169, 8, 24);
+
+ mpc_init2 (x, 1000);
+ mpc_init2 (y, 1000);
+
+ /* Bug 20081114: mpc_mul_karatsuba returned wrong inexact value for
+ imaginary part */
+ mpc_set_prec (x, 7);
+ mpc_set_prec (y, 7);
+ mpfr_set_str (mpc_realref (x), "0xB4p+733", 16, GMP_RNDN);
+ mpfr_set_str (mpc_imagref (x), "0x90p+244", 16, GMP_RNDN);
+ mpfr_set_str (mpc_realref (y), "0xECp-146", 16, GMP_RNDN);
+ mpfr_set_str (mpc_imagref (y), "0xACp-471", 16, GMP_RNDN);
+ cmpmul (x, y, MPC_RNDNN);
+ mpfr_set_str (mpc_realref (x), "0xB4p+733", 16, GMP_RNDN);
+ mpfr_set_str (mpc_imagref (x), "0x90p+244", 16, GMP_RNDN);
+ mpfr_set_str (mpc_realref (y), "0xACp-471", 16, GMP_RNDN);
+ mpfr_set_str (mpc_imagref (y), "-0xECp-146", 16, GMP_RNDN);
+ cmpmul (x, y, MPC_RNDNN);
+
+ for (prec = 2; prec < 1000; prec = (mpfr_prec_t) (prec * 1.1 + 1))
+ {
+ mpc_set_prec (x, prec);
+ mpc_set_prec (y, prec);
+
+ test_default_random (x, -1024, 1024, 128, 0);
+ test_default_random (y, -1024, 1024, 128, 0);
+
+ for (rnd_re = 0; rnd_re < 4; rnd_re ++)
+ for (rnd_im = 0; rnd_im < 4; rnd_im ++)
+ cmpmul (x, y, MPC_RND (rnd_re, rnd_im));
+ }
+
+ mpc_clear (x);
+ mpc_clear (y);
+}
+
+
+#ifdef TIMING
+static void
+timemul (void)
+{
+ /* measures the time needed with different precisions for naive and */
+ /* Karatsuba multiplication */
+
+ mpc_t x, y, z;
+ unsigned long int i, j;
+ const unsigned long int tests = 10000;
+ struct tms time_old, time_new;
+ double passed1, passed2;
+
+ mpc_init (x);
+ mpc_init (y);
+ mpc_init_set_ui_ui (z, 1, 0, MPC_RNDNN);
+
+ for (i = 1; i < 50; i++)
+ {
+ mpc_set_prec (x, i * BITS_PER_MP_LIMB);
+ mpc_set_prec (y, i * BITS_PER_MP_LIMB);
+ mpc_set_prec (z, i * BITS_PER_MP_LIMB);
+ test_default_random (x, -1, 1, 128, 25);
+ test_default_random (y, -1, 1, 128, 25);
+
+ times (&time_old);
+ for (j = 0; j < tests; j++)
+ mpc_mul_naive (z, x, y, MPC_RNDNN);
+ times (&time_new);
+ passed1 = ((double) (time_new.tms_utime - time_old.tms_utime)) / 100;
+
+ times (&time_old);
+ for (j = 0; j < tests; j++)
+ mpc_mul_karatsuba (z, x, y, MPC_RNDNN);
+ times (&time_new);
+ passed2 = ((double) (time_new.tms_utime - time_old.tms_utime)) / 100;
+
+ printf ("Time for %3li limbs naive/Karatsuba: %5.2f %5.2f\n", i,
+ passed1, passed2);
+ }
+
+ mpc_clear (x);
+ mpc_clear (y);
+ mpc_clear (z);
+}
+#endif
+
+
+int
+main (void)
+{
+ DECL_FUNC (C_CC, f, mpc_mul);
+ f.properties = FUNC_PROP_SYMETRIC;
+
+ test_start ();
+
+#ifdef TIMING
+ timemul ();
+#endif
+
+ check_regular ();
+
+ data_check (f, "mul.dat");
+ tgeneric (f, 2, 4096, 41, 100);
+
+ test_end ();
+ return 0;
+}
diff --git a/mpc/tests/tmul_2si.c b/mpc/tests/tmul_2si.c
new file mode 100644
index 0000000000..bf86f18715
--- /dev/null
+++ b/mpc/tests/tmul_2si.c
@@ -0,0 +1,35 @@
+/* tmul_2si -- test file for mpc_mul_2si.
+
+Copyright (C) 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCS, f, mpc_mul_2si);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tmul_2ui.c b/mpc/tests/tmul_2ui.c
new file mode 100644
index 0000000000..97073db773
--- /dev/null
+++ b/mpc/tests/tmul_2ui.c
@@ -0,0 +1,35 @@
+/* tmul_2ui -- test file for mpc_mul_2ui.
+
+Copyright (C) 2008, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCU, f, mpc_mul_2ui);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tmul_fr.c b/mpc/tests/tmul_fr.c
new file mode 100644
index 0000000000..796ab28b55
--- /dev/null
+++ b/mpc/tests/tmul_fr.c
@@ -0,0 +1,36 @@
+/* tmul_fr -- test file for mpc_mul_fr.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCF, f, mpc_mul_fr);
+
+ test_start ();
+
+ data_check (f, "mul_fr.dat");
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tmul_i.c b/mpc/tests/tmul_i.c
new file mode 100644
index 0000000000..3cde4acf59
--- /dev/null
+++ b/mpc/tests/tmul_i.c
@@ -0,0 +1,96 @@
+/* tmul_i -- test file for mpc_mul_i.
+
+Copyright (C) 2008, 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+check_different_precisions(void)
+{
+ /* check reuse when real and imaginary part have different precisions. */
+ mpc_t z, expected, got;
+ int res;
+
+ mpc_init2(z, 128);
+ mpc_init2(expected, 128);
+ mpc_init2(got, 128);
+
+ /* change precision of one part */
+ mpfr_set_prec (mpc_imagref (z), 32);
+ mpfr_set_prec (mpc_imagref (expected), 32);
+ mpfr_set_prec (mpc_imagref (got), 32);
+
+ mpfr_set_str (mpc_realref (z), "0x100000000fp-32", 16, GMP_RNDN);
+ mpfr_set_str (mpc_imagref (z), "-1", 2, GMP_RNDN);
+ mpfr_set_str (mpc_realref (expected), "+1", 2, GMP_RNDN);
+ mpfr_set_str (mpc_imagref (expected), "0x100000000fp-32", 16, GMP_RNDN);
+
+ mpc_set (got, z, MPC_RNDNN);
+ res = mpc_mul_i (got, got, +1, MPC_RNDNN);
+ if (MPC_INEX_RE(res) != 0 || MPC_INEX_IM(res) >=0)
+ {
+ printf("Wrong inexact flag for mpc_mul_i(z, z, n)\n"
+ " got (re=%2d, im=%2d)\nexpected (re= 0, im=-1)\n",
+ MPC_INEX_RE(res), MPC_INEX_IM(res));
+ exit(1);
+ }
+ if (mpc_cmp(got, expected) != 0)
+ {
+ printf ("Error for mpc_mul_i(z, z, n) for\n");
+ MPC_OUT (z);
+ printf ("n=+1\n");
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+
+ mpc_neg (expected, expected, MPC_RNDNN);
+ mpc_set (got, z, MPC_RNDNN);
+ mpc_mul_i (got, got, -1, MPC_RNDNN);
+ if (mpc_cmp(got, expected) != 0)
+ {
+ printf ("Error for mpc_mul_i(z, z, n) for\n");
+ MPC_OUT (z);
+ printf ("n=-1\n");
+ MPC_OUT (expected);
+ MPC_OUT (got);
+
+ exit (1);
+ }
+
+ mpc_clear (z);
+ mpc_clear (expected);
+ mpc_clear (got);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CCI, f, mpc_mul_i);
+
+ test_start ();
+
+ check_different_precisions ();
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tmul_si.c b/mpc/tests/tmul_si.c
new file mode 100644
index 0000000000..1d0e0d7ab6
--- /dev/null
+++ b/mpc/tests/tmul_si.c
@@ -0,0 +1,34 @@
+/* tmul_si -- test file for mpc_mul_si.
+
+Copyright (C) 2002, 2005, 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCS, f, mpc_mul_si);
+ test_start ();
+
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tmul_ui.c b/mpc/tests/tmul_ui.c
new file mode 100644
index 0000000000..e7f62f2600
--- /dev/null
+++ b/mpc/tests/tmul_ui.c
@@ -0,0 +1,35 @@
+/* tmul_ui -- test file for mpc_mul_ui.
+
+Copyright (C) 2002, 2005, 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCU, f, mpc_mul_ui);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tneg.c b/mpc/tests/tneg.c
new file mode 100644
index 0000000000..be1c90a85a
--- /dev/null
+++ b/mpc/tests/tneg.c
@@ -0,0 +1,35 @@
+/* tneg -- test file for mpc_neg.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_neg);
+ test_start ();
+
+ data_check (f, "neg.dat");
+ tgeneric (f, 2, 1024, 1, 0);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tnorm.c b/mpc/tests/tnorm.c
new file mode 100644
index 0000000000..3f4dccdcd0
--- /dev/null
+++ b/mpc/tests/tnorm.c
@@ -0,0 +1,110 @@
+/* tnorm -- test file for mpc_norm.
+
+Copyright (C) 2008, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+test_underflow (void)
+{
+ mpfr_exp_t emin = mpfr_get_emin ();
+ mpc_t z;
+ mpfr_t f;
+ int inex;
+
+ mpfr_set_emin (-1); /* smallest positive number is 0.5*2^emin = 0.25 */
+ mpc_init2 (z, 10);
+ mpfr_set_ui_2exp (mpc_realref (z), 1023, -11, GMP_RNDN); /* exact */
+ mpfr_set_ui_2exp (mpc_imagref (z), 1023, -11, GMP_RNDN); /* exact */
+ mpfr_init2 (f, 10);
+
+ inex = mpc_norm (f, z, GMP_RNDZ); /* should give 511/1024 */
+ if (inex >= 0)
+ {
+ printf ("Error in underflow case (1)\n");
+ printf ("expected inex < 0, got %d\n", inex);
+ exit (1);
+ }
+ if (mpfr_cmp_ui_2exp (f, 511, -10) != 0)
+ {
+ printf ("Error in underflow case (1)\n");
+ printf ("got ");
+ mpfr_dump (f);
+ printf ("expected ");
+ mpfr_set_ui_2exp (f, 511, -10, GMP_RNDZ);
+ mpfr_dump (f);
+ exit (1);
+ }
+
+ inex = mpc_norm (f, z, GMP_RNDN); /* should give 511/1024 */
+ if (inex >= 0)
+ {
+ printf ("Error in underflow case (2)\n");
+ printf ("expected inex < 0, got %d\n", inex);
+ exit (1);
+ }
+ if (mpfr_cmp_ui_2exp (f, 511, -10) != 0)
+ {
+ printf ("Error in underflow case (2)\n");
+ printf ("got ");
+ mpfr_dump (f);
+ printf ("expected ");
+ mpfr_set_ui_2exp (f, 511, -10, GMP_RNDZ);
+ mpfr_dump (f);
+ exit (1);
+ }
+
+ inex = mpc_norm (f, z, GMP_RNDU); /* should give 1023/2048 */
+ if (inex <= 0)
+ {
+ printf ("Error in underflow case (3)\n");
+ printf ("expected inex > 0, got %d\n", inex);
+ exit (1);
+ }
+ if (mpfr_cmp_ui_2exp (f, 1023, -11) != 0)
+ {
+ printf ("Error in underflow case (3)\n");
+ printf ("got ");
+ mpfr_dump (f);
+ printf ("expected ");
+ mpfr_set_ui_2exp (f, 1023, -11, GMP_RNDZ);
+ mpfr_dump (f);
+ exit (1);
+ }
+
+ mpc_clear (z);
+ mpfr_clear (f);
+ mpfr_set_emin (emin);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (FC, f, mpc_norm);
+
+ test_start ();
+
+ data_check (f, "norm.dat");
+ tgeneric (f, 2, 1024, 1, 4096);
+ test_underflow ();
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tpow.c b/mpc/tests/tpow.c
new file mode 100644
index 0000000000..3592209303
--- /dev/null
+++ b/mpc/tests/tpow.c
@@ -0,0 +1,71 @@
+/* tpow -- test file for mpc_pow.
+
+Copyright (C) 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+reuse_bug (void)
+{
+ /* bug found by the automatic builds on
+ http://hydra.nixos.org/build/1469029/log/raw */
+ mpc_t x, y, z;
+ mp_prec_t prec = 2;
+
+ for (prec = 2; prec <= 20; prec ++)
+ {
+ mpc_init2 (x, prec);
+ mpc_init2 (y, prec);
+ mpc_init2 (z, prec);
+
+ mpfr_set_ui (mpc_realref (x), 0ul, GMP_RNDN);
+ mpfr_set_ui_2exp (mpc_imagref (x), 3ul, -2, GMP_RNDN);
+ mpc_set_ui (y, 8ul, MPC_RNDNN);
+
+ mpc_pow (z, x, y, MPC_RNDNN);
+ mpc_pow (y, x, y, MPC_RNDNN);
+ if (mpfr_signbit (mpc_imagref (y)) != mpfr_signbit (mpc_imagref (z)))
+ {
+ printf ("Error: regression, reuse_bug reproduced\n");
+ exit (1);
+ }
+
+ mpc_clear (x);
+ mpc_clear (y);
+ mpc_clear (z);
+ }
+}
+
+
+int
+main (void)
+{
+ DECL_FUNC (C_CC, f, mpc_pow);
+
+ test_start ();
+
+ reuse_bug ();
+
+ data_check (f, "pow.dat");
+ tgeneric (f, 2, 1024, 7, 10);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tpow_d.c b/mpc/tests/tpow_d.c
new file mode 100644
index 0000000000..22de27ed86
--- /dev/null
+++ b/mpc/tests/tpow_d.c
@@ -0,0 +1,61 @@
+/* tpow_d -- test file for mpc_pow_d.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ mpc_t z;
+
+ test_start ();
+
+ mpc_init2 (z, 11);
+
+ mpc_set_ui_ui (z, 2, 3, MPC_RNDNN);
+ mpc_pow_d (z, z, 3.0, MPC_RNDNN);
+ if (mpc_cmp_si_si (z, -46, 9) != 0)
+ {
+ printf ("Error for mpc_pow_d (1)\n");
+ exit (1);
+ }
+
+ mpc_set_si_si (z, -3, 4, MPC_RNDNN);
+ mpc_pow_d (z, z, 0.5, MPC_RNDNN);
+ if (mpc_cmp_si_si (z, 1, 2) != 0)
+ {
+ printf ("Error for mpc_pow_d (2)\n");
+ exit (1);
+ }
+
+ mpc_set_ui_ui (z, 2, 3, MPC_RNDNN);
+ mpc_pow_d (z, z, 6.0, MPC_RNDNN);
+ if (mpc_cmp_si_si (z, 2035, -828) != 0)
+ {
+ printf ("Error for mpc_pow_d (3)\n");
+ exit (1);
+ }
+
+ mpc_clear (z);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tpow_fr.c b/mpc/tests/tpow_fr.c
new file mode 100644
index 0000000000..47ef071292
--- /dev/null
+++ b/mpc/tests/tpow_fr.c
@@ -0,0 +1,63 @@
+/* tpow_fr -- test file for mpc_pow_fr.
+
+Copyright (C) 2009, 2011, 2012 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+test_reuse (void)
+{
+ mpc_t z;
+ mpfr_t y;
+ int inex;
+
+ mpfr_init2 (y, 2);
+ mpc_init2 (z, 2);
+ mpc_set_si_si (z, 0, -1, MPC_RNDNN);
+ mpfr_neg (mpc_realref (z), mpc_realref (z), GMP_RNDN);
+ mpc_div_2ui (z, z, 4, MPC_RNDNN);
+ mpfr_set_ui (y, 512, GMP_RNDN);
+ inex = mpc_pow_fr (z, z, y, MPC_RNDNN);
+ if (MPC_INEX_RE(inex) != 0 || MPC_INEX_IM(inex) != 0 ||
+ mpfr_cmp_ui_2exp (mpc_realref(z), 1, -2048) != 0 ||
+ mpfr_cmp_ui (mpc_imagref(z), 0) != 0 || mpfr_signbit (mpc_imagref(z)) == 0)
+ {
+ printf ("Error in test_reuse, wrong ternary value or output\n");
+ printf ("inex=(%d %d)\n", MPC_INEX_RE(inex), MPC_INEX_IM(inex));
+ printf ("z="); mpc_out_str (stdout, 2, 0, z, MPC_RNDNN); printf ("\n");
+ exit (1);
+ }
+ mpfr_clear (y);
+ mpc_clear (z);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CCF, f, mpc_pow_fr);
+ test_start ();
+
+ test_reuse ();
+ data_check (f, "pow_fr.dat");
+ tgeneric (f, 2, 1024, 7, 10);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tpow_ld.c b/mpc/tests/tpow_ld.c
new file mode 100644
index 0000000000..a02ea6ee90
--- /dev/null
+++ b/mpc/tests/tpow_ld.c
@@ -0,0 +1,43 @@
+/* tpow_ld -- test file for mpc_pow_ld.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ mpc_t z;
+
+ test_start ();
+
+ mpc_init2 (z, 5);
+ mpc_set_ui_ui (z, 3, 2, MPC_RNDNN);
+ mpc_pow_ld (z, z, (long double) 3.0, MPC_RNDNN);
+ if (mpc_cmp_si_si (z, -9, 46) != 0)
+ {
+ printf ("Error for mpc_pow_ld (1)\n");
+ exit (1);
+ }
+ mpc_clear (z);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tpow_si.c b/mpc/tests/tpow_si.c
new file mode 100644
index 0000000000..a3cbfb784d
--- /dev/null
+++ b/mpc/tests/tpow_si.c
@@ -0,0 +1,89 @@
+/* tpow_si -- test file for mpc_pow_si.
+
+Copyright (C) 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <limits.h> /* for CHAR_BIT */
+#include "mpc-tests.h"
+
+static void
+compare_mpc_pow (mpfr_prec_t pmax, int iter, unsigned long nbits)
+ /* copied from tpow_ui.c and replaced unsigned by signed */
+{
+ mpfr_prec_t p;
+ mpc_t x, y, z, t;
+ long n;
+ int i, inex_pow, inex_pow_si;
+ mpc_rnd_t rnd;
+
+ mpc_init3 (y, sizeof (unsigned long) * CHAR_BIT, MPFR_PREC_MIN);
+ for (p = MPFR_PREC_MIN; p <= pmax; p++)
+ for (i = 0; i < iter; i++)
+ {
+ mpc_init2 (x, p);
+ mpc_init2 (z, p);
+ mpc_init2 (t, p);
+ mpc_urandom (x, rands);
+ n = (signed long) gmp_urandomb_ui (rands, nbits);
+ mpc_set_si (y, n, MPC_RNDNN);
+ for (rnd = 0; rnd < 16; rnd ++)
+ {
+ inex_pow = mpc_pow (z, x, y, rnd);
+ inex_pow_si = mpc_pow_si (t, x, n, rnd);
+ if (mpc_cmp (z, t) != 0)
+ {
+ printf ("mpc_pow and mpc_pow_si differ for x=");
+ mpc_out_str (stdout, 10, 0, x, MPC_RNDNN);
+ printf (" n=%li\n", n);
+ printf ("mpc_pow gives ");
+ mpc_out_str (stdout, 10, 0, z, MPC_RNDNN);
+ printf ("\nmpc_pow_si gives ");
+ mpc_out_str (stdout, 10, 0, t, MPC_RNDNN);
+ printf ("\n");
+ exit (1);
+ }
+ if (inex_pow != inex_pow_si)
+ {
+ printf ("mpc_pow and mpc_pow_si give different flags for x=");
+ mpc_out_str (stdout, 10, 0, x, MPC_RNDNN);
+ printf (" n=%li\n", n);
+ printf ("mpc_pow gives %d\n", inex_pow);
+ printf ("mpc_pow_si gives %d\n", inex_pow_si);
+ exit (1);
+ }
+ }
+ mpc_clear (x);
+ mpc_clear (z);
+ mpc_clear (t);
+ }
+ mpc_clear (y);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CCS, f, mpc_pow_si);
+ test_start ();
+ data_check (f, "pow_si.dat");
+
+ compare_mpc_pow (100, 5, 19);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tpow_ui.c b/mpc/tests/tpow_ui.c
new file mode 100644
index 0000000000..4e8cd31000
--- /dev/null
+++ b/mpc/tests/tpow_ui.c
@@ -0,0 +1,118 @@
+/* tpow_ui -- test file for mpc_pow_ui.
+
+Copyright (C) 2009, 2010 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <limits.h> /* for CHAR_BIT */
+#include "mpc-tests.h"
+
+static void
+compare_mpc_pow (mpfr_prec_t pmax, int iter, unsigned long nbits)
+{
+ mpfr_prec_t p;
+ mpc_t x, y, z, t;
+ unsigned long n;
+ int i, inex_pow, inex_pow_ui;
+ mpc_rnd_t rnd;
+
+ mpc_init3 (y, sizeof (unsigned long) * CHAR_BIT, MPFR_PREC_MIN);
+ for (p = MPFR_PREC_MIN; p <= pmax; p++)
+ for (i = 0; i < iter; i++)
+ {
+ mpc_init2 (x, p);
+ mpc_init2 (z, p);
+ mpc_init2 (t, p);
+ mpc_urandom (x, rands);
+ n = gmp_urandomb_ui (rands, nbits); /* 0 <= n < 2^nbits */
+ mpc_set_ui (y, n, MPC_RNDNN);
+ for (rnd = 0; rnd < 16; rnd ++)
+ {
+ inex_pow = mpc_pow (z, x, y, rnd);
+ inex_pow_ui = mpc_pow_ui (t, x, n, rnd);
+ if (mpc_cmp (z, t) != 0)
+ {
+ printf ("mpc_pow and mpc_pow_ui differ for x=");
+ mpc_out_str (stdout, 10, 0, x, MPC_RNDNN);
+ printf (" n=%lu\n", n);
+ printf ("mpc_pow gives ");
+ mpc_out_str (stdout, 10, 0, z, MPC_RNDNN);
+ printf ("\nmpc_pow_ui gives ");
+ mpc_out_str (stdout, 10, 0, t, MPC_RNDNN);
+ printf ("\n");
+ exit (1);
+ }
+ if (inex_pow != inex_pow_ui)
+ {
+ printf ("mpc_pow and mpc_pow_ui give different flags for x=");
+ mpc_out_str (stdout, 10, 0, x, MPC_RNDNN);
+ printf (" n=%lu\n", n);
+ printf ("mpc_pow gives %d\n", inex_pow);
+ printf ("mpc_pow_ui gives %d\n", inex_pow_ui);
+ exit (1);
+ }
+ }
+ mpc_clear (x);
+ mpc_clear (z);
+ mpc_clear (t);
+ }
+ mpc_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpc_t z;
+
+ DECL_FUNC (CCU, f, mpc_pow_ui);
+
+ if (argc != 1)
+ {
+ mpfr_prec_t p;
+ long int n, k;
+ mpc_t res;
+ if (argc != 3 && argc != 4)
+ {
+ printf ("Usage: tpow_ui precision exponent [k]\n");
+ exit (1);
+ }
+ p = atoi (argv[1]);
+ n = atoi (argv[2]);
+ MPC_ASSERT (n >= 0);
+ k = (argc > 3) ? atoi (argv[3]) : 1;
+ MPC_ASSERT (k >= 0);
+ mpc_init2 (z, p);
+ mpc_init2 (res, p);
+ mpfr_const_pi (mpc_realref (z), GMP_RNDN);
+ mpfr_div_2exp (mpc_realref (z), mpc_realref (z), 2, GMP_RNDN);
+ mpfr_const_log2 (mpc_imagref (z), GMP_RNDN);
+ while (k--)
+ mpc_pow_ui (res, z, (unsigned long int) n, MPC_RNDNN);
+ mpc_clear (z);
+ mpc_clear (res);
+ return 0;
+ }
+
+ test_start ();
+ data_check (f, "pow_ui.dat");
+
+ compare_mpc_pow (100, 5, 19);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tpow_z.c b/mpc/tests/tpow_z.c
new file mode 100644
index 0000000000..2a897e6bee
--- /dev/null
+++ b/mpc/tests/tpow_z.c
@@ -0,0 +1,62 @@
+/* tpow_z -- test file for mpc_pow_z.
+
+Copyright (C) 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <limits.h> /* for CHAR_BIT */
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ mpc_t z;
+ mpz_t t;
+
+ test_start ();
+
+ mpc_init2 (z, 5);
+ mpz_init_set_ui (t, 1ul);
+ mpc_set_ui_ui (z, 17ul, 42ul, MPC_RNDNN);
+ mpc_pow_z (z, z, t, MPC_RNDNN);
+ if (mpc_cmp_si_si (z, 17l, 42l) != 0) {
+ printf ("Error for mpc_pow_z (1)\n");
+ exit (1);
+ }
+ mpz_set_si (t, -1l);
+ mpc_set_ui_ui (z, 1ul, 1ul, MPC_RNDNN);
+ mpc_pow_z (z, z, t, MPC_RNDNN);
+ mpc_mul_ui (z, z, 2ul, MPC_RNDNN);
+ if (mpc_cmp_si_si (z, 1l, -1l) != 0) {
+ printf ("Error for mpc_pow_z (-1)\n");
+ exit (1);
+ }
+ mpz_set_ui (t, 1ul);
+ mpz_mul_2exp (t, t, sizeof (long) * CHAR_BIT);
+ mpc_set_ui_ui (z, 0ul, 1ul, MPC_RNDNN);
+ mpc_pow_z (z, z, t, MPC_RNDNN);
+ if (mpc_cmp_si_si (z, 1l, 0l) != 0) {
+ printf ("Error for mpc_pow_z (4*large)\n");
+ exit (1);
+ }
+ mpc_clear (z);
+ mpz_clear (t);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tprec.c b/mpc/tests/tprec.c
new file mode 100644
index 0000000000..18bba4e502
--- /dev/null
+++ b/mpc/tests/tprec.c
@@ -0,0 +1,69 @@
+/* tprec -- Test file for mpc_set_prec, mpc_get_prec and mpc_get_prec2.
+
+Copyright (C) 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ mpc_t z;
+ mpfr_prec_t prec, pr, pi;
+
+ mpc_init2 (z, 1000);
+
+ for (prec = 2; prec <= 1000; prec++)
+ {
+ /* check set_prec/get_prec */
+ mpfr_set_prec (mpc_realref (z), prec);
+ mpfr_set_prec (mpc_imagref (z), prec + 1);
+ if (mpc_get_prec (z) != 0)
+ {
+ printf ("Error in mpc_get_prec for prec (re) = %lu, "
+ "prec (im) = %lu\n", (unsigned long int) prec,
+ (unsigned long int) prec + 1ul);
+
+ exit (1);
+ }
+
+ mpc_get_prec2 (&pr, &pi, z);
+ if (pr != prec || pi != prec + 1)
+ {
+ printf ("Error in mpc_get_prec2 for prec (re) = %lu, "
+ "prec (im) = %lu\n", (unsigned long int) prec,
+ (unsigned long int) prec + 1ul);
+
+ exit (1);
+ }
+
+ mpc_set_prec (z, prec);
+ if (mpc_get_prec (z) != prec)
+ {
+ printf ("Error in mpc_get_prec for prec = %lu\n",
+ (unsigned long int) prec);
+
+ exit (1);
+ }
+ }
+
+ mpc_clear (z);
+
+ return 0;
+}
diff --git a/mpc/tests/tproj.c b/mpc/tests/tproj.c
new file mode 100644
index 0000000000..222b697d98
--- /dev/null
+++ b/mpc/tests/tproj.c
@@ -0,0 +1,36 @@
+/* tproj -- test file for mpc_proj.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_proj);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 1, 4096);
+ data_check (f, "proj.dat");
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/treal.c b/mpc/tests/treal.c
new file mode 100644
index 0000000000..c3ab95fe46
--- /dev/null
+++ b/mpc/tests/treal.c
@@ -0,0 +1,35 @@
+/* treal -- test file for mpc_real.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (FC, f, mpc_real);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 1, 4096);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/treimref.c b/mpc/tests/treimref.c
new file mode 100644
index 0000000000..230d34c6df
--- /dev/null
+++ b/mpc/tests/treimref.c
@@ -0,0 +1,48 @@
+/* treimref -- test file for mpc_realref and mpc_imagref.
+
+Copyright (C) 2009 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ mpc_t z;
+
+ test_start ();
+ test_end ();
+
+ mpc_init2 (z, 6);
+ mpc_set_ui_ui (z, 17, 42, MPC_RNDNN);
+ mpfr_set_ui (mpc_realref (z), 18, GMP_RNDN);
+ if (mpfr_get_ui (mpc_realref (z), GMP_RNDN) != 18)
+ {
+ fprintf (stderr, "Error in mpfr_set_ui/mpc_realref\n");
+ exit (1);
+ }
+ mpfr_set_ui (mpc_imagref (z), 43, GMP_RNDN);
+ if (mpfr_get_ui (mpc_imagref (z), GMP_RNDN) != 43)
+ {
+ fprintf (stderr, "Error in mpfr_set_ui/mpc_imagref\n");
+ exit (1);
+ }
+ mpc_clear (z);
+
+ return 0;
+}
diff --git a/mpc/tests/tset.c b/mpc/tests/tset.c
new file mode 100644
index 0000000000..004943691b
--- /dev/null
+++ b/mpc/tests/tset.c
@@ -0,0 +1,447 @@
+/* tset -- Test file for mpc_set_x and mpc_set_x_x functions.
+
+Copyright (C) 2009, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "config.h"
+#include <limits.h> /* for LONG_MAX */
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h> /* for intmax_t */
+#else
+# ifdef HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+
+#ifdef HAVE_COMPLEX_H
+# include <complex.h>
+#endif
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include "mpc-tests.h"
+
+#define PRINT_ERROR(function_name, precision, a) \
+ do { \
+ printf ("Error in "function_name" for prec = %lu\n", \
+ (unsigned long int) precision); \
+ MPC_OUT(a); \
+ exit (1); \
+ } while (0)
+
+/* test MPC_SET_X_Y through some functions */
+static int
+mpc_set_ui_fr (mpc_ptr z, unsigned long int a, mpfr_srcptr b, mpc_rnd_t rnd)
+ MPC_SET_X_Y (ui, fr, z, a, b, rnd)
+
+static int
+mpc_set_fr_ui (mpc_ptr z, mpfr_srcptr a, unsigned long int b, mpc_rnd_t rnd)
+ MPC_SET_X_Y (fr, ui, z, a, b, rnd)
+
+static int
+mpc_set_f_si (mpc_ptr z, mpf_t a, long int b, mpc_rnd_t rnd)
+ MPC_SET_X_Y (f, si, z, a, b, rnd)
+
+
+static void
+check_set (void)
+{
+ long int lo;
+ mpz_t mpz;
+ mpq_t mpq;
+ mpf_t mpf;
+ mpfr_t fr;
+ mpc_t x, z;
+ mpfr_prec_t prec;
+
+ mpz_init (mpz);
+ mpq_init (mpq);
+ mpf_init2 (mpf, 1000);
+ mpfr_init2 (fr, 1000);
+ mpc_init2 (x, 1000);
+ mpc_init2 (z, 1000);
+
+ mpz_set_ui (mpz, 0x4217);
+ mpq_set_si (mpq, -1, 0x4321);
+ mpf_set_q (mpf, mpq);
+
+ for (prec = 2; prec <= 1000; prec++)
+ {
+ unsigned long int u = (unsigned long int) prec;
+
+ mpc_set_prec (z, prec);
+ mpfr_set_prec (fr, prec);
+
+ lo = -prec;
+
+ mpfr_set_d (fr, 1.23456789, GMP_RNDN);
+
+ mpc_set_d (z, 1.23456789, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp_si (mpc_imagref(z), 0) != 0)
+ PRINT_ERROR ("mpc_set_d", prec, z);
+
+#if defined HAVE_COMPLEX_H
+ mpc_set_dc (z, I*1.23456789+1.23456789, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp (mpc_imagref(z), fr) != 0)
+ PRINT_ERROR ("mpc_set_c", prec, z);
+#endif
+
+ mpc_set_ui (z, u, MPC_RNDNN);
+ if (mpfr_cmp_ui (mpc_realref(z), u) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
+ PRINT_ERROR ("mpc_set_ui", prec, z);
+
+ mpc_set_d_d (z, 1.23456789, 1.23456789, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp (mpc_imagref(z), fr) != 0)
+ PRINT_ERROR ("mpc_set_d_d", prec, z);
+
+ mpc_set_si (z, lo, MPC_RNDNN);
+ if (mpfr_cmp_si (mpc_realref(z), lo) != 0 || mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
+ PRINT_ERROR ("mpc_set_si", prec, z);
+
+ mpfr_set_ld (fr, 1.23456789L, GMP_RNDN);
+
+ mpc_set_ld_ld (z, 1.23456789L, 1.23456789L, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp (mpc_imagref(z), fr) != 0)
+ PRINT_ERROR ("mpc_set_ld_ld", prec, z);
+
+#if defined HAVE_COMPLEX_H
+ mpc_set_ldc (z, I*1.23456789L+1.23456789L, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp (mpc_imagref(z), fr) != 0)
+ PRINT_ERROR ("mpc_set_lc", prec, z);
+#endif
+ mpc_set_ui_ui (z, u, u, MPC_RNDNN);
+ if (mpfr_cmp_ui (mpc_realref(z), u) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), u) != 0)
+ PRINT_ERROR ("mpc_set_ui_ui", prec, z);
+
+ mpc_set_ld (z, 1.23456789L, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref(z), fr) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_ld", prec, z);
+
+ mpc_set_prec (x, prec);
+ mpfr_set_ui(fr, 1, GMP_RNDN);
+ mpfr_div_ui(fr, fr, 3, GMP_RNDN);
+ mpfr_set(mpc_realref(x), fr, GMP_RNDN);
+ mpfr_set(mpc_imagref(x), fr, GMP_RNDN);
+
+ mpc_set (z, x, MPC_RNDNN);
+ mpfr_clear_flags (); /* mpc_cmp set erange flag when an operand is a
+ NaN */
+ if (mpc_cmp (z, x) != 0 || mpfr_erangeflag_p())
+ {
+ printf ("Error in mpc_set for prec = %lu\n",
+ (unsigned long int) prec);
+ MPC_OUT(z);
+ MPC_OUT(x);
+ exit (1);
+ }
+
+ mpc_set_si_si (z, lo, lo, MPC_RNDNN);
+ if (mpfr_cmp_si (mpc_realref(z), lo) != 0
+ || mpfr_cmp_si (mpc_imagref(z), lo) != 0)
+ PRINT_ERROR ("mpc_set_si_si", prec, z);
+
+ mpc_set_fr (z, fr, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref(z), fr) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_fr", prec, z);
+
+ mpfr_set_z (fr, mpz, GMP_RNDN);
+ mpc_set_z_z (z, mpz, mpz, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref(z), fr) != 0
+ || mpfr_cmp (mpc_imagref(z), fr) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_z_z", prec, z);
+
+ mpc_set_fr_fr (z, fr, fr, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref(z), fr) != 0
+ || mpfr_cmp (mpc_imagref(z), fr) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_fr_fr", prec, z);
+
+ mpc_set_z (z, mpz, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref(z), fr) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_z", prec, z);
+
+ mpfr_set_q (fr, mpq, GMP_RNDN);
+ mpc_set_q_q (z, mpq, mpq, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref(z), fr) != 0
+ || mpfr_cmp (mpc_imagref(z), fr) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_q_q", prec, z);
+
+ mpc_set_ui_fr (z, u, fr, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp_ui (mpc_realref (z), u) != 0
+ || mpfr_cmp (mpc_imagref (z), fr) != 0
+ || mpfr_erangeflag_p ())
+ PRINT_ERROR ("mpc_set_ui_fr", prec, z);
+
+ mpc_set_fr_ui (z, fr, u, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref (z), fr) != 0
+ || mpfr_cmp_ui (mpc_imagref (z), u) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_fr_ui", prec, z);
+
+ mpc_set_q (z, mpq, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref(z), fr) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_q", prec, z);
+
+ mpfr_set_f (fr, mpf, GMP_RNDN);
+ mpc_set_f_f (z, mpf, mpf, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref(z), fr) != 0
+ || mpfr_cmp (mpc_imagref(z), fr) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_f_f", prec, z);
+
+ mpc_set_f (z, mpf, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref(z), fr) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
+ || mpfr_erangeflag_p())
+ PRINT_ERROR ("mpc_set_f", prec, z);
+
+ mpc_set_f_si (z, mpf, lo, MPC_RNDNN);
+ mpfr_clear_flags ();
+ if (mpfr_cmp (mpc_realref (z), fr) != 0
+ || mpfr_cmp_si (mpc_imagref (z), lo) != 0
+ || mpfr_erangeflag_p ())
+ PRINT_ERROR ("mpc_set_f", prec, z);
+
+ mpc_set_nan (z);
+ if (!mpfr_nan_p (mpc_realref(z)) || !mpfr_nan_p (mpc_imagref(z)))
+ PRINT_ERROR ("mpc_set_nan", prec, z);
+
+#ifdef _MPC_H_HAVE_INTMAX_T
+ {
+ uintmax_t uim = (uintmax_t) prec;
+ intmax_t im = (intmax_t) prec;
+
+ mpc_set_uj (z, uim, MPC_RNDNN);
+ if (mpfr_cmp_ui (mpc_realref(z), u) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
+ PRINT_ERROR ("mpc_set_uj", prec, z);
+
+ mpc_set_sj (z, im, MPC_RNDNN);
+ if (mpfr_cmp_ui (mpc_realref(z), u) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
+ PRINT_ERROR ("mpc_set_sj (1)", prec, z);
+
+ mpc_set_uj_uj (z, uim, uim, MPC_RNDNN);
+ if (mpfr_cmp_ui (mpc_realref(z), u) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), u) != 0)
+ PRINT_ERROR ("mpc_set_uj_uj", prec, z);
+
+ mpc_set_sj_sj (z, im, im, MPC_RNDNN);
+ if (mpfr_cmp_ui (mpc_realref(z), u) != 0
+ || mpfr_cmp_ui (mpc_imagref(z), u) != 0)
+ PRINT_ERROR ("mpc_set_sj_sj (1)", prec, z);
+
+ im = LONG_MAX;
+ if (sizeof (intmax_t) == 2 * sizeof (unsigned long))
+ im = 2 * im * im + 4 * im + 1; /* gives 2^(2n-1)-1 from 2^(n-1)-1 */
+
+ mpc_set_sj (z, im, MPC_RNDNN);
+ if (mpfr_get_sj (mpc_realref(z), GMP_RNDN) != im ||
+ mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
+ PRINT_ERROR ("mpc_set_sj (2)", im, z);
+
+ mpc_set_sj_sj (z, im, im, MPC_RNDNN);
+ if (mpfr_get_sj (mpc_realref(z), GMP_RNDN) != im ||
+ mpfr_get_sj (mpc_imagref(z), GMP_RNDN) != im)
+ PRINT_ERROR ("mpc_set_sj_sj (2)", im, z);
+ }
+#endif /* _MPC_H_HAVE_INTMAX_T */
+
+#if defined HAVE_COMPLEX_H
+ {
+ double _Complex c = 1.0 - 2.0*I, d;
+ long double _Complex lc = c, ld;
+
+ mpc_set_dc (z, c, MPC_RNDNN);
+ if ((d = mpc_get_dc (z, MPC_RNDNN)) != c)
+ {
+ printf ("expected (%f,%f)\n", creal (c), cimag (c));
+ printf ("got (%f,%f)\n", creal (d), cimag (d));
+ PRINT_ERROR ("mpc_get_dc", prec, z);
+ }
+ mpc_set_ldc (z, lc, MPC_RNDNN);
+ if ((ld = mpc_get_ldc (z, MPC_RNDNN)) != lc)
+ {
+ printf ("expected (%Lf,%Lf)\n", creall (lc), cimagl (lc));
+ printf ("got (%Lf,%Lf)\n", creall (ld), cimagl (ld));
+ PRINT_ERROR ("mpc_get_ldc", prec, z);
+ }
+ }
+#endif
+ }
+
+ mpz_clear (mpz);
+ mpq_clear (mpq);
+ mpf_clear (mpf);
+ mpfr_clear (fr);
+ mpc_clear (x);
+ mpc_clear (z);
+}
+
+static void
+check_set_str (mpfr_exp_t exp_max)
+{
+ mpc_t expected;
+ mpc_t got;
+ char *str;
+
+ mpfr_prec_t prec;
+ mpfr_exp_t exp_min;
+ int base;
+
+ mpc_init2 (expected, 1024);
+ mpc_init2 (got, 1024);
+
+ exp_min = mpfr_get_emin ();
+ if (exp_max <= 0)
+ exp_max = mpfr_get_emax ();
+ else if (exp_max > mpfr_get_emax ())
+ exp_max = mpfr_get_emax();
+ if (-exp_max > exp_min)
+ exp_min = - exp_max;
+
+ for (prec = 2; prec < 1024; prec += 7)
+ {
+ mpc_set_prec (got, prec);
+ mpc_set_prec (expected, prec);
+
+ base = 2 + (int) gmp_urandomm_ui (rands, 35);
+ /* uses external variable rands from random.c */
+
+ mpfr_set_nan (mpc_realref (expected));
+ mpfr_set_inf (mpc_imagref (expected), prec % 2 - 1);
+ str = mpc_get_str (base, 0, expected, MPC_RNDNN);
+ if (mpfr_nan_p (mpc_realref (got)) == 0
+ || mpfr_cmp (mpc_imagref (got), mpc_imagref (expected)) != 0)
+ {
+ printf ("Error: mpc_set_str o mpc_get_str != Id\n"
+ "in base %u with str=\"%s\"\n", base, str);
+ MPC_OUT (expected);
+ printf (" ");
+ MPC_OUT (got);
+ exit (1);
+ }
+ mpc_free_str (str);
+
+ test_default_random (expected, exp_min, exp_max, 128, 25);
+ str = mpc_get_str (base, 0, expected, MPC_RNDNN);
+ if (mpc_set_str (got, str, base, MPC_RNDNN) == -1
+ || mpc_cmp (got, expected) != 0)
+ {
+ printf ("Error: mpc_set_str o mpc_get_str != Id\n"
+ "in base %u with str=\"%s\"\n", base, str);
+ MPC_OUT (expected);
+ printf (" ");
+ MPC_OUT (got);
+ exit (1);
+ }
+ mpc_free_str (str);
+ }
+
+#ifdef HAVE_SETLOCALE
+ {
+ /* Check with ',' as a decimal point */
+ char *old_locale;
+
+ old_locale = setlocale (LC_ALL, "de_DE");
+ if (old_locale != NULL)
+ {
+ str = mpc_get_str (10, 0, expected, MPC_RNDNN);
+ if (mpc_set_str (got, str, 10, MPC_RNDNN) == -1
+ || mpc_cmp (got, expected) != 0)
+ {
+ printf ("Error: mpc_set_str o mpc_get_str != Id\n"
+ "with str=\"%s\"\n", str);
+ MPC_OUT (expected);
+ printf (" ");
+ MPC_OUT (got);
+ exit (1);
+ }
+ mpc_free_str (str);
+
+ setlocale (LC_ALL, old_locale);
+ }
+ }
+#endif /* HAVE_SETLOCALE */
+
+ /* the real part has a zero exponent in base ten (fixed in r439) */
+ mpc_set_prec (expected, 37);
+ mpc_set_prec (got, 37);
+ mpc_set_str (expected, "921FC04EDp-35 ", 16, GMP_RNDN);
+ str = mpc_get_str (10, 0, expected, MPC_RNDNN);
+ if (mpc_set_str (got, str, 10, MPC_RNDNN) == -1
+ || mpc_cmp (got, expected) != 0)
+ {
+ printf ("Error: mpc_set_str o mpc_get_str != Id\n"
+ "with str=\"%s\"\n", str);
+ MPC_OUT (expected);
+ printf (" ");
+ MPC_OUT (got);
+ exit (1);
+ }
+ mpc_free_str (str);
+
+ str = mpc_get_str (1, 0, expected, MPC_RNDNN);
+ if (str != NULL)
+ {
+ printf ("Error: mpc_get_str with base==1 should fail\n");
+ exit (1);
+ }
+
+ mpc_clear (expected);
+ mpc_clear (got);
+}
+
+int
+main (void)
+{
+ test_start ();
+
+ check_set ();
+ check_set_str (1024);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tsin.c b/mpc/tests/tsin.c
new file mode 100644
index 0000000000..3b09c78dfe
--- /dev/null
+++ b/mpc/tests/tsin.c
@@ -0,0 +1,36 @@
+/* tsin -- test file for mpc_sin.
+
+Copyright (C) 2007, 2008, 2010 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_sin);
+
+ test_start ();
+
+ data_check (f, "sin.dat");
+ tgeneric (f, 2, 512, 7, 7);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tsin_cos.c b/mpc/tests/tsin_cos.c
new file mode 100644
index 0000000000..a1e74241df
--- /dev/null
+++ b/mpc/tests/tsin_cos.c
@@ -0,0 +1,35 @@
+/* tsin_cos -- test file for mpc_sin_cos.
+
+Copyright (C) 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC_C, f, mpc_sin_cos);
+
+ test_start ();
+
+ tgeneric (f, 2, 512, 13, 7);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tsinh.c b/mpc/tests/tsinh.c
new file mode 100644
index 0000000000..c12f0367e7
--- /dev/null
+++ b/mpc/tests/tsinh.c
@@ -0,0 +1,36 @@
+/* tsinh -- test file for mpc_sinh.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_sinh);
+
+ test_start ();
+
+ data_check (f, "sinh.dat");
+ tgeneric (f, 2, 512, 7, 7);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tsqr.c b/mpc/tests/tsqr.c
new file mode 100644
index 0000000000..02fea7ed50
--- /dev/null
+++ b/mpc/tests/tsqr.c
@@ -0,0 +1,191 @@
+/* tsqr -- test file for mpc_sqr.
+
+Copyright (C) 2002, 2005, 2008, 2010, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+static void
+cmpsqr (mpc_srcptr x, mpc_rnd_t rnd)
+ /* computes the square of x with the specific function or by simple */
+ /* multiplication using the rounding mode rnd and compares the results */
+ /* and return values. */
+ /* In our current test suite, the real and imaginary parts of x have */
+ /* the same precision, and we use this precision also for the result. */
+ /* Furthermore, we check whether computing the square in the same */
+ /* place yields the same result. */
+ /* We also compute the result with four times the precision and check */
+ /* whether the rounding is correct. Error reports in this part of the */
+ /* algorithm might still be wrong, though, since there are two */
+ /* consecutive roundings. */
+{
+ mpc_t z, t, u;
+ int inexact_z, inexact_t;
+
+ mpc_init2 (z, MPC_MAX_PREC (x));
+ mpc_init2 (t, MPC_MAX_PREC (x));
+ mpc_init2 (u, 4 * MPC_MAX_PREC (x));
+
+ inexact_z = mpc_sqr (z, x, rnd);
+ inexact_t = mpc_mul (t, x, x, rnd);
+
+ if (mpc_cmp (z, t))
+ {
+ fprintf (stderr, "sqr and mul differ for rnd=(%s,%s) \nx=",
+ mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
+ mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
+ mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
+ fprintf (stderr, "\nmpc_sqr gives ");
+ mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
+ fprintf (stderr, "\nmpc_mul gives ");
+ mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+ if (inexact_z != inexact_t)
+ {
+ fprintf (stderr, "The return values of sqr and mul differ for rnd=(%s,%s) \nx= ",
+ mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
+ mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
+ mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
+ fprintf (stderr, "\nx^2=");
+ mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
+ fprintf (stderr, "\nmpc_sqr gives %i", inexact_z);
+ fprintf (stderr, "\nmpc_mul gives %i", inexact_t);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+
+ mpc_set (t, x, MPC_RNDNN);
+ inexact_t = mpc_sqr (t, t, rnd);
+ if (mpc_cmp (z, t))
+ {
+ fprintf (stderr, "sqr and sqr in place differ for rnd=(%s,%s) \nx=",
+ mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
+ mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
+ mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
+ fprintf (stderr, "\nmpc_sqr gives ");
+ mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
+ fprintf (stderr, "\nmpc_sqr in place gives ");
+ mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+ if (inexact_z != inexact_t)
+ {
+ fprintf (stderr, "The return values of sqr and sqr in place differ for rnd=(%s,%s) \nx= ",
+ mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
+ mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
+ mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
+ fprintf (stderr, "\nx^2=");
+ mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
+ fprintf (stderr, "\nmpc_sqr gives %i", inexact_z);
+ fprintf (stderr, "\nmpc_sqr in place gives %i", inexact_t);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+
+ mpc_sqr (u, x, rnd);
+ mpc_set (t, u, rnd);
+ if (mpc_cmp (z, t))
+ {
+ fprintf (stderr, "rounding in sqr might be incorrect for rnd=(%s,%s) \nx=",
+ mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
+ mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
+ mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
+ fprintf (stderr, "\nmpc_sqr gives ");
+ mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
+ fprintf (stderr, "\nmpc_sqr quadruple precision gives ");
+ mpc_out_str (stderr, 2, 0, u, MPC_RNDNN);
+ fprintf (stderr, "\nand is rounded to ");
+ mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+
+ mpc_clear (z);
+ mpc_clear (t);
+ mpc_clear (u);
+}
+
+
+static void
+testsqr (long a, long b, mpfr_prec_t prec, mpc_rnd_t rnd)
+{
+ mpc_t x;
+
+ mpc_init2 (x, prec);
+
+ mpc_set_si_si (x, a, b, rnd);
+
+ cmpsqr (x, rnd);
+
+ mpc_clear (x);
+}
+
+
+static void
+reuse_bug (void)
+{
+ mpc_t z1;
+
+ /* reuse bug found by Paul Zimmermann 20081021 */
+ mpc_init2 (z1, 2);
+ /* RE (z1^2) overflows, IM(z^2) = -0 */
+ mpfr_set_str (mpc_realref (z1), "0.11", 2, GMP_RNDN);
+ mpfr_mul_2si (mpc_realref (z1), mpc_realref (z1), mpfr_get_emax (), GMP_RNDN);
+ mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
+ mpc_conj (z1, z1, MPC_RNDNN);
+ mpc_sqr (z1, z1, MPC_RNDNN);
+ if (!mpfr_inf_p (mpc_realref (z1)) || mpfr_signbit (mpc_realref (z1))
+ ||!mpfr_zero_p (mpc_imagref (z1)) || !mpfr_signbit (mpc_imagref (z1)))
+ {
+ printf ("Error: Regression, bug 20081021 reproduced\n");
+ MPC_OUT (z1);
+ exit (1);
+ }
+
+ mpc_clear (z1);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_sqr);
+ test_start ();
+
+ testsqr (247, -65, 8, 24);
+ testsqr (5, -896, 3, 2);
+ testsqr (-3, -512, 2, 16);
+ testsqr (266013312, 121990769, 27, 0);
+ testsqr (170, 9, 8, 0);
+ testsqr (768, 85, 8, 16);
+ testsqr (145, 1816, 8, 24);
+ testsqr (0, 1816, 8, 24);
+ testsqr (145, 0, 8, 24);
+
+ data_check (f, "sqr.dat");
+ tgeneric (f, 2, 1024, 1, 0);
+
+ reuse_bug ();
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tsqrt.c b/mpc/tests/tsqrt.c
new file mode 100644
index 0000000000..2da6842add
--- /dev/null
+++ b/mpc/tests/tsqrt.c
@@ -0,0 +1,36 @@
+/* tsqrt -- test file for mpc_sqrt.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_sqrt);
+
+ test_start ();
+
+ data_check (f, "sqrt.dat");
+ tgeneric (f, 2, 1024, 7, 256);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tstrtoc.c b/mpc/tests/tstrtoc.c
new file mode 100644
index 0000000000..77e34ee350
--- /dev/null
+++ b/mpc/tests/tstrtoc.c
@@ -0,0 +1,166 @@
+/* tstrtoc -- test file for mpc_strtoc.
+
+Copyright (C) 2009, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "mpc-tests.h"
+
+extern unsigned long line_number;
+extern int nextchar;
+extern char *pathname;
+
+/* names of rounding modes */
+extern const char *rnd_mode[];
+
+static void
+check_file (const char* file_name)
+{
+ FILE *fp;
+ unsigned long test_line_number;
+
+ size_t str_len = 255;
+ char *str = NULL;
+ size_t rstr_len = 255;
+ char *rstr = NULL;
+ char *end = NULL;
+
+ int base;
+ int inex_re;
+ int inex_im;
+ mpc_t expected, got;
+ mpc_rnd_t rnd = MPC_RNDNN;
+ int inex = 0, inex_expected;
+ known_signs_t ks = {1, 1};
+
+
+ fp = open_data_file (file_name);
+
+ /* initializations */
+ str = (char *) malloc (str_len);
+ if (str == NULL)
+ {
+ printf ("Cannot allocate memory\n");
+ exit (1);
+ }
+ rstr = (char *) malloc (rstr_len);
+ if (rstr == NULL)
+ {
+ printf ("Cannot allocate memory\n");
+ exit (1);
+ }
+ mpc_init2 (expected, 53);
+ mpc_init2 (got, 53);
+
+ /* read data file */
+ line_number = 1;
+ nextchar = getc (fp);
+ while (nextchar != EOF)
+ {
+ skip_whitespace_comments (fp);
+
+ /* 1. read a line of data: expected result, base, rounding mode */
+ test_line_number = line_number;
+ read_ternary (fp, &inex_re);
+ read_ternary (fp, &inex_im);
+ read_mpc (fp, expected, NULL);
+ if (inex_re == TERNARY_ERROR || inex_im == TERNARY_ERROR)
+ inex_expected = -1;
+ else
+ inex_expected = MPC_INEX (inex_re, inex_im);
+
+ str_len = read_string (fp, &str, str_len, "number string");
+ rstr_len = read_string (fp, &rstr, rstr_len, "string remainder");
+ read_int (fp, &base, "base");
+ read_mpc_rounding_mode (fp, &rnd);
+
+ /* 2. convert string at the same precision as the expected result */
+ mpfr_set_prec (mpc_realref (got), MPC_PREC_RE (expected));
+ mpfr_set_prec (mpc_imagref (got), MPC_PREC_IM (expected));
+ inex = mpc_strtoc (got, str, &end, base, rnd);
+
+ /* 3. compare this result with the expected one */
+ if (inex != inex_expected
+ || !same_mpc_value (got, expected, ks)
+ || strcmp (end, rstr) != 0)
+ {
+ printf ("mpc_strtoc(str) failed (line %lu)\nwith base=%d and "
+ "rounding mode %s\n", test_line_number, base,
+ rnd_mode[rnd]);
+ if (inex != MPC_INEX (inex_re, inex_im))
+ printf ("ternary value: got %s, expected (%s, %s)\n",
+ MPC_INEX_STR (inex),
+ (inex_re == +1 ? "+1" : (inex_re == -1 ? "-1" : "0")),
+ (inex_im == +1 ? "+1" : (inex_im == -1 ? "-1" : "0")));
+ printf ("str = \"%s\"\n", str);
+ if (strcmp (end, rstr) != 0)
+ printf ("string remainder expected \"%s\"\n"
+ " got \"%s\"\n",
+ rstr, end);
+ else
+ {
+ printf (" ");
+ MPC_OUT (got);
+ MPC_OUT (expected);
+ }
+ exit (1);
+ }
+
+ end = NULL;
+ }
+
+ mpc_clear (expected);
+ mpc_clear (got);
+ if (str != NULL)
+ free (str);
+ if (rstr != NULL)
+ free (rstr);
+ close_data_file (fp);
+}
+
+static void
+check_null (void)
+{
+ int inex;
+ char *end;
+ mpc_t z;
+
+ mpc_init2 (z, 53);
+
+ inex = mpc_strtoc (z, NULL, &end, 10, MPC_RNDNN);
+ if (end != NULL || inex != -1 || mpfr_nan_p (mpc_realref (z)) == 0
+ || mpfr_nan_p (mpc_imagref (z)) == 0)
+ {
+ printf ("Error: mpc_strtoc(z, NULL) with a NULL pointer should fail"
+ " and the z value should be set to NaN +I*NaN\ngot ");
+ MPC_OUT (z);
+ exit (1);
+ }
+
+ mpc_clear (z);
+}
+
+int
+main (void)
+{
+ check_null ();
+ check_file ("strtoc.dat");
+ return 0;
+}
diff --git a/mpc/tests/tsub.c b/mpc/tests/tsub.c
new file mode 100644
index 0000000000..658c81e2db
--- /dev/null
+++ b/mpc/tests/tsub.c
@@ -0,0 +1,36 @@
+/* tsub -- test file for mpc_sub.
+
+Copyright (C) 2008, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (C_CC, f, mpc_sub);
+
+ test_start ();
+
+ data_check (f, "sub.dat");
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tsub_fr.c b/mpc/tests/tsub_fr.c
new file mode 100644
index 0000000000..495fdeea75
--- /dev/null
+++ b/mpc/tests/tsub_fr.c
@@ -0,0 +1,36 @@
+/* tsub_fr -- test file for mpc_sub_fr.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCF, f, mpc_sub_fr);
+
+ test_start ();
+
+ data_check (f, "sub_fr.dat");
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tsub_ui.c b/mpc/tests/tsub_ui.c
new file mode 100644
index 0000000000..567ead5747
--- /dev/null
+++ b/mpc/tests/tsub_ui.c
@@ -0,0 +1,35 @@
+/* tsub_ui -- test file for mpc_sub_ui.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CCU, f, mpc_sub_ui);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tswap.c b/mpc/tests/tswap.c
new file mode 100644
index 0000000000..948c7f7e3e
--- /dev/null
+++ b/mpc/tests/tswap.c
@@ -0,0 +1,54 @@
+/* tswap -- Test file for mpc_swap.
+
+Copyright (C) 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ mpc_t x, y, x2, y2;
+
+ mpc_init2 (x, 50);
+ mpc_init2 (x2, 50);
+ mpc_init2 (y, 100);
+ mpc_init2 (y2, 100);
+
+ mpc_set_ui_ui (x, 1ul, 2ul, MPC_RNDNN);
+ mpc_set_ui_ui (x2, 1ul, 2ul, MPC_RNDNN);
+ mpc_set_ui_ui (y, 3ul, 4ul, MPC_RNDNN);
+ mpc_set_ui_ui (y2, 3ul, 4ul, MPC_RNDNN);
+
+ mpc_swap (x, y);
+
+ if ( mpfr_get_prec (mpc_realref (x)) != mpfr_get_prec (mpc_realref (y2))
+ || mpfr_get_prec (mpc_imagref (x)) != mpfr_get_prec (mpc_imagref (y2))
+ || mpfr_get_prec (mpc_realref (y)) != mpfr_get_prec (mpc_realref (x2))
+ || mpfr_get_prec (mpc_imagref (y)) != mpfr_get_prec (mpc_imagref (x2))
+ || mpc_cmp (x, y2) != 0
+ || mpc_cmp (y, x2) != 0)
+ exit (1);
+
+ mpc_clear (x);
+ mpc_clear (x2);
+ mpc_clear (y);
+ mpc_clear (y2);
+
+ return 0;
+}
diff --git a/mpc/tests/ttan.c b/mpc/tests/ttan.c
new file mode 100644
index 0000000000..f1d826a233
--- /dev/null
+++ b/mpc/tests/ttan.c
@@ -0,0 +1,216 @@
+/* ttan -- test file for mpc_tan.
+
+Copyright (C) 2008, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include <stdlib.h>
+#include "mpc-tests.h"
+
+static void
+pure_real_argument (void)
+{
+ /* tan(x -i*0) = tan(x) -i*0 */
+ /* tan(x +i*0) = tan(x) +i*0 */
+ mpfr_t x;
+ mpfr_t tan_x;
+ mpc_t z;
+ mpc_t tan_z;
+
+ mpfr_init2 (x, 79);
+ mpfr_init2 (tan_x, 113);
+ mpc_init2 (z, 79);
+ mpc_init2 (tan_z, 113);
+
+ /* tan(1 +i*0) = tan(1) +i*0 */
+ mpc_set_ui_ui (z, 1, 0, MPC_RNDNN);
+ mpfr_set_ui (x, 1, GMP_RNDN);
+ mpfr_tan (tan_x, x, GMP_RNDN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref (tan_z), tan_x) != 0
+ || !mpfr_zero_p (mpc_imagref (tan_z)) || mpfr_signbit (mpc_imagref (tan_z)))
+ {
+ printf ("mpc_tan(1 + i * 0) failed\n");
+ exit (1);
+ }
+
+ /* tan(1 -i*0) = tan(1) -i*0 */
+ mpc_conj (z, z, MPC_RNDNN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref (tan_z), tan_x) != 0
+ || !mpfr_zero_p (mpc_imagref (tan_z)) || !mpfr_signbit (mpc_imagref (tan_z)))
+ {
+ printf ("mpc_tan(1 - i * 0) failed\n");
+ exit (1);
+ }
+
+ /* tan(Pi/2 +i*0) = +Inf +i*0 */
+ mpfr_const_pi (x, GMP_RNDN);
+ mpfr_div_2ui (x, x, 1, GMP_RNDN);
+ mpfr_set (mpc_realref (z), x, GMP_RNDN);
+ mpfr_set_ui (mpc_imagref (z), 0, GMP_RNDN);
+ mpfr_tan (tan_x, x, GMP_RNDN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref (tan_z), tan_x) != 0
+ || !mpfr_zero_p (mpc_imagref (tan_z)) || mpfr_signbit (mpc_imagref (tan_z)))
+ {
+ printf ("mpc_tan(Pi/2 + i * 0) failed\n");
+ exit (1);
+ }
+
+ /* tan(Pi/2 -i*0) = +Inf -i*0 */
+ mpc_conj (z, z, MPC_RNDNN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref (tan_z), tan_x) != 0
+ || !mpfr_zero_p (mpc_imagref (tan_z)) || !mpfr_signbit (mpc_imagref (tan_z)))
+ {
+ printf ("mpc_tan(Pi/2 - i * 0) failed\n");
+ exit (1);
+ }
+
+ /* tan(-Pi/2 +i*0) = -Inf +i*0 */
+ mpfr_neg (x, x, GMP_RNDN);
+ mpc_neg (z, z, MPC_RNDNN);
+ mpfr_tan (tan_x, x, GMP_RNDN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref (tan_z), tan_x) != 0
+ || !mpfr_zero_p (mpc_imagref (tan_z)) || mpfr_signbit (mpc_imagref (tan_z)))
+ {
+ printf ("mpc_tan(-Pi/2 + i * 0) failed\n");
+ exit (1);
+ }
+
+ /* tan(-Pi/2 -i*0) = -Inf -i*0 */
+ mpc_conj (z, z, MPC_RNDNN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_realref (tan_z), tan_x) != 0
+ || !mpfr_zero_p (mpc_imagref (tan_z)) || !mpfr_signbit (mpc_imagref (tan_z)))
+ {
+ printf ("mpc_tan(-Pi/2 - i * 0) failed\n");
+ exit (1);
+ }
+
+ mpc_clear (tan_z);
+ mpc_clear (z);
+ mpfr_clear (tan_x);
+ mpfr_clear (x);
+}
+
+static void
+pure_imaginary_argument (void)
+{
+ /* tan(-0 +i*y) = -0 +i*tanh(y) */
+ /* tan(+0 +i*y) = +0 +i*tanh(y) */
+ mpfr_t y;
+ mpfr_t tanh_y;
+ mpc_t z;
+ mpc_t tan_z;
+ mpfr_prec_t prec = (mpfr_prec_t) 111;
+
+ mpfr_init2 (y, 2);
+ mpfr_init2 (tanh_y, prec);
+ mpc_init2 (z, 2);
+ mpc_init2 (tan_z, prec);
+
+ /* tan(0 +i) = +0 +i*tanh(1) */
+ mpc_set_ui_ui (z, 0, 1, MPC_RNDNN);
+ mpfr_set_ui (y, 1, GMP_RNDN);
+ mpfr_tanh (tanh_y, y, GMP_RNDN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_imagref (tan_z), tanh_y) != 0
+ || !mpfr_zero_p (mpc_realref (tan_z)) || mpfr_signbit (mpc_realref (tan_z)))
+ {
+ mpc_t c99;
+
+ mpc_init2 (c99, prec);
+ mpfr_set_ui (mpc_realref (c99), 0, GMP_RNDN);
+ mpfr_set (mpc_imagref (c99), tanh_y, GMP_RNDN);
+
+ TEST_FAILED ("mpc_tan", z, tan_z, c99, MPC_RNDNN);
+ }
+
+ /* tan(0 -i) = +0 +i*tanh(-1) */
+ mpc_conj (z, z, MPC_RNDNN);
+ mpfr_neg (tanh_y, tanh_y, GMP_RNDN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_imagref (tan_z), tanh_y) != 0
+ || !mpfr_zero_p (mpc_realref (tan_z)) || mpfr_signbit (mpc_realref (tan_z)))
+ {
+ mpc_t c99;
+
+ mpc_init2 (c99, prec);
+ mpfr_set_ui (mpc_realref (c99), 0, GMP_RNDN);
+ mpfr_set (mpc_imagref (c99), tanh_y, GMP_RNDN);
+
+ TEST_FAILED ("mpc_tan", z, tan_z, c99, MPC_RNDNN);
+ }
+
+ /* tan(-0 +i) = -0 +i*tanh(1) */
+ mpc_neg (z, z, MPC_RNDNN);
+ mpfr_neg (tanh_y, tanh_y, GMP_RNDN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_imagref (tan_z), tanh_y) != 0
+ || !mpfr_zero_p (mpc_realref (tan_z)) || !mpfr_signbit (mpc_realref (tan_z)))
+ {
+ mpc_t c99;
+
+ mpc_init2 (c99, prec);
+ mpfr_set_ui (mpc_realref (c99), 0, GMP_RNDN);
+ mpfr_set (mpc_imagref (c99), tanh_y, GMP_RNDN);
+
+ TEST_FAILED ("mpc_tan", z, tan_z, c99, MPC_RNDNN);
+ }
+
+ /* tan(-0 -i) = -0 +i*tanh(-1) */
+ mpc_conj (z, z, MPC_RNDNN);
+ mpfr_neg (tanh_y, tanh_y, GMP_RNDN);
+ mpc_tan (tan_z, z, MPC_RNDNN);
+ if (mpfr_cmp (mpc_imagref (tan_z), tanh_y) != 0
+ || !mpfr_zero_p (mpc_realref (tan_z)) || !mpfr_signbit (mpc_realref (tan_z)))
+ {
+ mpc_t c99;
+
+ mpc_init2 (c99, prec);
+ mpfr_set_ui (mpc_realref (c99), 0, GMP_RNDN);
+ mpfr_set (mpc_imagref (c99), tanh_y, GMP_RNDN);
+
+ TEST_FAILED ("mpc_tan", z, tan_z, c99, MPC_RNDNN);
+ }
+
+ mpc_clear (tan_z);
+ mpc_clear (z);
+ mpfr_clear (tanh_y);
+ mpfr_clear (y);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_tan);
+
+ test_start ();
+
+ data_check (f, "tan.dat");
+ tgeneric (f, 2, 512, 7, 4);
+
+ pure_real_argument ();
+ pure_imaginary_argument ();
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/ttanh.c b/mpc/tests/ttanh.c
new file mode 100644
index 0000000000..26d9fbe160
--- /dev/null
+++ b/mpc/tests/ttanh.c
@@ -0,0 +1,36 @@
+/* ttanh -- test file for mpc_tanh.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CC, f, mpc_tanh);
+
+ test_start ();
+
+ data_check (f, "tanh.dat");
+ tgeneric (f, 2, 512, 7, 4);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tui_div.c b/mpc/tests/tui_div.c
new file mode 100644
index 0000000000..c109189265
--- /dev/null
+++ b/mpc/tests/tui_div.c
@@ -0,0 +1,102 @@
+/* tui_div -- test file for mpc_ui_div.
+
+Copyright (C) 2008, 2011 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+static void
+special (void)
+{
+ mpc_t a, b;
+
+ mpc_init2 (a, 10);
+ mpc_init2 (b, 10);
+
+ mpc_set_ui_ui (a, 2, 4, MPC_RNDNN);
+ mpc_ui_div (b, 10, a, MPC_RNDNN);
+ if (mpc_cmp_si_si (b, 1, -2) != 0)
+ {
+ printf ("10/(2,4) failed\n");
+ printf ("expected (1,-2)\n");
+ printf ("got ");
+ mpc_out_str (stdout, 10, 0, b, MPC_RNDNN);
+ printf ("\n");
+ exit (1);
+ }
+
+ /* 0/(-1-0*I) should give (-0, +0) */
+ mpfr_set_str (mpc_realref(a), "-1", 10, GMP_RNDN);
+ mpfr_set_str (mpc_imagref(a), "-0", 10, GMP_RNDN);
+ mpc_ui_div (b, 0, a, MPC_RNDNN);
+ if ((mpc_cmp_si_si (b, 0, 0) != 0) || (MPFR_SIGN (mpc_realref(b)) > 0)
+ || (MPFR_SIGN (mpc_imagref(b)) < 0))
+ {
+ printf ("0/(-1,-0) failed\n");
+ printf ("expected (-0,+0)\n");
+ printf ("got ");
+ mpc_out_str (stdout, 10, 0, b, MPC_RNDNN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpc_set_ui_ui (a, 1, 0, MPC_RNDNN);
+ mpc_ui_div (b, 1, a, MPC_RNDNN);
+ if (mpc_cmp_si_si (b, 1, 0) != 0)
+ {
+ printf ("1/(1,0) failed\n");
+ printf ("expected (1,0)\n");
+ printf ("got ");
+ mpc_out_str (stdout, 10, 0, b, MPC_RNDNN);
+ printf ("\n");
+ exit (1);
+ }
+
+ /* problem reported by Timo Hartmann with mpc-0.7, 21 Oct 2009 */
+ mpc_set_ui_ui (a, 4, 0, MPC_RNDNN);
+ mpc_ui_div (b, 1, a, MPC_RNDNN);
+ if (mpfr_cmp_ui_2exp (mpc_realref(b), 1, -2) != 0 ||
+ mpfr_cmp_ui (mpc_imagref(b), 0) != 0 || mpfr_signbit (mpc_imagref(b)) != 0)
+ {
+ printf ("1/(4,0) failed\n");
+ printf ("expected (1/4,0)\n");
+ printf ("got ");
+ mpc_out_str (stdout, 10, 0, b, MPC_RNDNN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpc_clear (a);
+ mpc_clear (b);
+}
+
+int
+main (void)
+{
+ DECL_FUNC (CUC, f, mpc_ui_div);
+
+ test_start ();
+
+ special ();
+
+ tgeneric (f, 2, 1024, 7, 4096);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpc/tests/tui_ui_sub.c b/mpc/tests/tui_ui_sub.c
new file mode 100644
index 0000000000..67c9071cdc
--- /dev/null
+++ b/mpc/tests/tui_ui_sub.c
@@ -0,0 +1,35 @@
+/* tui_ui_sub -- test file for mpc_ui_ui_sub.
+
+Copyright (C) 2008 INRIA
+
+This file is part of GNU MPC.
+
+GNU MPC is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/ .
+*/
+
+#include "mpc-tests.h"
+
+int
+main (void)
+{
+ DECL_FUNC (CUUC, f, mpc_ui_ui_sub);
+
+ test_start ();
+
+ tgeneric (f, 2, 1024, 7, -1);
+
+ test_end ();
+
+ return 0;
+}
diff --git a/mpfr/AUTHORS b/mpfr/AUTHORS
new file mode 100644
index 0000000000..5cd6c87be3
--- /dev/null
+++ b/mpfr/AUTHORS
@@ -0,0 +1,23 @@
+Authors of MPFR (in chronological order of initial contribution):
+
+Guillaume Hanrot Main author
+Fabrice Rouillier Original version of mul_ui.c, gmp_op.c
+Paul Zimmermann Main author
+Sylvie Boldo Original version of agm.c and log.c
+Jean-Luc Rémy Original version of zeta.c
+Emmanuel Jeandel Original version of exp3.c, const_pi.c, sincos.c
+Mathieu Dutour acos.c, asin.c, atan.c and early gamma.c
+Vincent Lefèvre Main author
+David Daney Hyperbolic and inverse hyperbolic functions, base-2
+ and base-10 exponential and logarithm, factorial
+Alain Delplanque Rewritten get_str.c
+Ludovic Meunier Error function (erf.c)
+Patrick Pélissier Main author
+Laurent Fousse Original version of sum.c
+Damien Stehlé Function mpfr_get_ld_2exp
+Philippe Théveny Main author
+Sylvain Chevillard Original version of ai.c
+
+The main authors are included in the MPFR mailing-list <mpfr@inria.fr>.
+This is the preferred way to contact us. For further information, please
+look at the MPFR web page <http://www.mpfr.org/>.
diff --git a/mpfr/BUGS b/mpfr/BUGS
new file mode 100644
index 0000000000..bfc3677dd8
--- /dev/null
+++ b/mpfr/BUGS
@@ -0,0 +1,73 @@
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+##############################################################################
+
+Known bugs:
+
+* The overflow/underflow exceptions may be badly handled in some functions;
+ specially when the intermediary internal results have exponent which
+ exceeds the hardware limit (2^30 for a 32 bits CPU, and 2^62 for a 64 bits
+ CPU) or the exact result is close to an overflow/underflow threshold.
+
+* Under Linux/x86 with the traditional FPU, some functions do not work
+ if the FPU rounding precision has been changed to single (this is a
+ bad practice and should be useless, but one never knows what other
+ software will do).
+
+* Some functions do not use MPFR_SAVE_EXPO_* macros, thus do not behave
+ correctly in a reduced exponent range.
+
+* Function hypot gives incorrect result when on the one hand the difference
+ between parameters' exponents is near 2*MPFR_EMAX_MAX and on the other hand
+ the output precision or the precision of the parameter with greatest
+ absolute value is greater than 2*MPFR_EMAX_MAX-4.
+
+Potential bugs:
+
+* Possible incorrect results due to internal underflow, which can lead to
+ a huge loss of accuracy while the error analysis doesn't take that into
+ account. If the underflow occurs at the last function call (just before
+ the MPFR_CAN_ROUND), the result should be correct (or MPFR gets into an
+ infinite loop). TODO: check the code and the error analysis.
+
+* Possible integer overflows on some machines.
+
+* Possible bugs with huge precisions (> 2^30).
+
+* Possible bugs if the chosen exponent range does not allow to represent
+ the range [1/16, 16].
+
+* Possible infinite loop in some functions for particular cases: when
+ the exact result is an exactly representable number or the middle of
+ consecutive two such numbers. However for non-algebraic functions, it is
+ believed that no such case exists, except the well-known cases like cos(0)=1,
+ exp(0)=1, and so on, and the x^y function when y is an integer or y=1/2^k.
+
+* The mpfr_set_ld function may be quite slow if the long double type has an
+ exponent of more than 15 bits.
+
+* mpfr_set_d may give wrong results on some non-IEEE architectures.
+
+* Error analysis for some functions may be incorrect (out-of-date due
+ to modifications in the code?).
+
+* Possible use of non-portable feature (pre-C99) of the integer division
+ with negative result.
diff --git a/mpfr/COPYING b/mpfr/COPYING
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/mpfr/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/mpfr/COPYING.LESSER b/mpfr/COPYING.LESSER
new file mode 100644
index 0000000000..fc8a5de7ed
--- /dev/null
+++ b/mpfr/COPYING.LESSER
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/mpfr/ChangeLog b/mpfr/ChangeLog
new file mode 100644
index 0000000000..b4438c00ca
--- /dev/null
+++ b/mpfr/ChangeLog
@@ -0,0 +1,65716 @@
+------------------------------------------------------------------------
+r8482 | vlefevre | 2013-03-13 15:29:32 +0000 (Wed, 13 Mar 2013) | 1 line
+Changed paths:
+ M /branches/3.1/VERSION
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/version.c
+
+Updated version to 3.1.2.
+------------------------------------------------------------------------
+r8480 | vlefevre | 2013-03-13 01:00:16 +0000 (Wed, 13 Mar 2013) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/configure.ac
+
+[configure.ac] Corrected comment on clock_gettime.
+(merged changeset r8446 from the trunk)
+------------------------------------------------------------------------
+r8479 | zimmerma | 2013-03-12 09:37:20 +0000 (Tue, 12 Mar 2013) | 4 lines
+Changed paths:
+ M /branches/3.1/configure.ac
+ M /branches/3.1/tune/Makefile.am
+
+(merged changeset 8443-8445 from the trunk)
+Tuning: reverted changeset r8444 and applied patch by Patrick Pélissier
+for GMP 5.1.0 to link against librt conditionally.
+
+------------------------------------------------------------------------
+r8478 | vlefevre | 2013-03-12 02:20:01 +0000 (Tue, 12 Mar 2013) | 2 lines
+Changed paths:
+ M /branches/3.1/INSTALL
+
+[INSTALL] Added a paragraph about Cygwin and threading.
+(merged changeset r8477 from the trunk)
+------------------------------------------------------------------------
+r8476 | vlefevre | 2013-03-12 00:11:18 +0000 (Tue, 12 Mar 2013) | 3 lines
+Changed paths:
+ M /branches/3.1/INSTALL
+
+[INSTALL] Improved information on patches.
+(merged changeset r8475 from the trunk, after temporarily reverted
+to 3.2.0-dev with tools/update-version for the merge)
+------------------------------------------------------------------------
+r8471 | vlefevre | 2013-03-08 12:06:54 +0000 (Fri, 08 Mar 2013) | 1 line
+Changed paths:
+ M /branches/3.1/ChangeLog
+
+ChangeLog update with "TZ=UTC svn log -rHEAD:0 -v" (in UTF-8 locales).
+------------------------------------------------------------------------
+r8470 | vlefevre | 2013-03-08 11:59:32 +0000 (Fri, 08 Mar 2013) | 2 lines
+Changed paths:
+ M /branches/3.1/VERSION
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/Makefile.am
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/version.c
+
+Updated version to 3.1.2-rc1 and updated libmpfr_la_LDFLAGS in
+src/Makefile.am for the next release.
+------------------------------------------------------------------------
+r8468 | vlefevre | 2013-03-08 11:44:47 +0000 (Fri, 08 Mar 2013) | 1 line
+Changed paths:
+ M /branches/3.1/NEWS
+
+[NEWS] Update for GNU MPFR 3.1.2.
+------------------------------------------------------------------------
+r8466 | vlefevre | 2013-03-08 00:34:36 +0000 (Fri, 08 Mar 2013) | 1 line
+Changed paths:
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r8465 | vlefevre | 2013-03-08 00:33:22 +0000 (Fri, 08 Mar 2013) | 5 lines
+Changed paths:
+ M /branches/3.1/BUGS
+ M /branches/3.1/INSTALL
+ M /branches/3.1/Makefile.am
+ M /branches/3.1/NEWS
+ M /branches/3.1/README
+ M /branches/3.1/TODO
+ M /branches/3.1/acinclude.m4
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/FAQ.html
+ M /branches/3.1/doc/Makefile.am
+ M /branches/3.1/doc/README.dev
+ M /branches/3.1/doc/faq.xsl
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/examples/divworst.c
+ M /branches/3.1/examples/rndo-add.c
+ M /branches/3.1/examples/sample.c
+ M /branches/3.1/examples/version.c
+ M /branches/3.1/src/Makefile.am
+ M /branches/3.1/src/abort_prec_max.c
+ M /branches/3.1/src/acos.c
+ M /branches/3.1/src/acosh.c
+ M /branches/3.1/src/add.c
+ M /branches/3.1/src/add1.c
+ M /branches/3.1/src/add1sp.c
+ M /branches/3.1/src/add_d.c
+ M /branches/3.1/src/add_ui.c
+ M /branches/3.1/src/agm.c
+ M /branches/3.1/src/ai.c
+ M /branches/3.1/src/amd/amdfam10/mparam.h
+ M /branches/3.1/src/amd/athlon/mparam.h
+ M /branches/3.1/src/amd/k8/mparam.h
+ M /branches/3.1/src/arm/mparam.h
+ M /branches/3.1/src/asin.c
+ M /branches/3.1/src/asinh.c
+ M /branches/3.1/src/atan.c
+ M /branches/3.1/src/atan2.c
+ M /branches/3.1/src/atanh.c
+ M /branches/3.1/src/bernoulli.c
+ M /branches/3.1/src/buildopt.c
+ M /branches/3.1/src/cache.c
+ M /branches/3.1/src/cbrt.c
+ M /branches/3.1/src/check.c
+ M /branches/3.1/src/clear.c
+ M /branches/3.1/src/clears.c
+ M /branches/3.1/src/cmp.c
+ M /branches/3.1/src/cmp2.c
+ M /branches/3.1/src/cmp_abs.c
+ M /branches/3.1/src/cmp_d.c
+ M /branches/3.1/src/cmp_ld.c
+ M /branches/3.1/src/cmp_si.c
+ M /branches/3.1/src/cmp_ui.c
+ M /branches/3.1/src/comparisons.c
+ M /branches/3.1/src/const_catalan.c
+ M /branches/3.1/src/const_euler.c
+ M /branches/3.1/src/const_log2.c
+ M /branches/3.1/src/const_pi.c
+ M /branches/3.1/src/constant.c
+ M /branches/3.1/src/copysign.c
+ M /branches/3.1/src/cos.c
+ M /branches/3.1/src/cosh.c
+ M /branches/3.1/src/cot.c
+ M /branches/3.1/src/coth.c
+ M /branches/3.1/src/csc.c
+ M /branches/3.1/src/csch.c
+ M /branches/3.1/src/d_div.c
+ M /branches/3.1/src/d_sub.c
+ M /branches/3.1/src/digamma.c
+ M /branches/3.1/src/dim.c
+ M /branches/3.1/src/div.c
+ M /branches/3.1/src/div_2exp.c
+ M /branches/3.1/src/div_2si.c
+ M /branches/3.1/src/div_2ui.c
+ M /branches/3.1/src/div_d.c
+ M /branches/3.1/src/div_ui.c
+ M /branches/3.1/src/dump.c
+ M /branches/3.1/src/eint.c
+ M /branches/3.1/src/eq.c
+ M /branches/3.1/src/erf.c
+ M /branches/3.1/src/erfc.c
+ M /branches/3.1/src/exceptions.c
+ M /branches/3.1/src/exp.c
+ M /branches/3.1/src/exp10.c
+ M /branches/3.1/src/exp2.c
+ M /branches/3.1/src/exp3.c
+ M /branches/3.1/src/exp_2.c
+ M /branches/3.1/src/expm1.c
+ M /branches/3.1/src/extract.c
+ M /branches/3.1/src/factorial.c
+ M /branches/3.1/src/fits_intmax.c
+ M /branches/3.1/src/fits_s.h
+ M /branches/3.1/src/fits_sint.c
+ M /branches/3.1/src/fits_slong.c
+ M /branches/3.1/src/fits_sshort.c
+ M /branches/3.1/src/fits_u.h
+ M /branches/3.1/src/fits_uint.c
+ M /branches/3.1/src/fits_uintmax.c
+ M /branches/3.1/src/fits_ulong.c
+ M /branches/3.1/src/fits_ushort.c
+ M /branches/3.1/src/fma.c
+ M /branches/3.1/src/fms.c
+ M /branches/3.1/src/frac.c
+ M /branches/3.1/src/free_cache.c
+ M /branches/3.1/src/frexp.c
+ M /branches/3.1/src/gamma.c
+ M /branches/3.1/src/gammaonethird.c
+ M /branches/3.1/src/gen_inverse.h
+ M /branches/3.1/src/generic/mparam.h
+ M /branches/3.1/src/get_d.c
+ M /branches/3.1/src/get_d64.c
+ M /branches/3.1/src/get_exp.c
+ M /branches/3.1/src/get_f.c
+ M /branches/3.1/src/get_flt.c
+ M /branches/3.1/src/get_ld.c
+ M /branches/3.1/src/get_si.c
+ M /branches/3.1/src/get_sj.c
+ M /branches/3.1/src/get_str.c
+ M /branches/3.1/src/get_ui.c
+ M /branches/3.1/src/get_uj.c
+ M /branches/3.1/src/get_z.c
+ M /branches/3.1/src/get_z_exp.c
+ M /branches/3.1/src/gmp_op.c
+ M /branches/3.1/src/grandom.c
+ M /branches/3.1/src/hppa/mparam.h
+ M /branches/3.1/src/hypot.c
+ M /branches/3.1/src/ia64/mparam.h
+ M /branches/3.1/src/ieee_floats.h
+ M /branches/3.1/src/init.c
+ M /branches/3.1/src/init2.c
+ M /branches/3.1/src/inits.c
+ M /branches/3.1/src/inits2.c
+ M /branches/3.1/src/inp_str.c
+ M /branches/3.1/src/int_ceil_log2.c
+ M /branches/3.1/src/isinf.c
+ M /branches/3.1/src/isinteger.c
+ M /branches/3.1/src/isnan.c
+ M /branches/3.1/src/isnum.c
+ M /branches/3.1/src/isqrt.c
+ M /branches/3.1/src/isregular.c
+ M /branches/3.1/src/iszero.c
+ M /branches/3.1/src/jn.c
+ M /branches/3.1/src/jyn_asympt.c
+ M /branches/3.1/src/li2.c
+ M /branches/3.1/src/lngamma.c
+ M /branches/3.1/src/log.c
+ M /branches/3.1/src/log10.c
+ M /branches/3.1/src/log1p.c
+ M /branches/3.1/src/log2.c
+ M /branches/3.1/src/logging.c
+ M /branches/3.1/src/min_prec.c
+ M /branches/3.1/src/minmax.c
+ M /branches/3.1/src/modf.c
+ M /branches/3.1/src/mp_clz_tab.c
+ M /branches/3.1/src/mparam_h.in
+ M /branches/3.1/src/mpf2mpfr.h
+ M /branches/3.1/src/mpfr-gmp.c
+ M /branches/3.1/src/mpfr-gmp.h
+ M /branches/3.1/src/mpfr-impl.h
+ M /branches/3.1/src/mpfr-intmax.h
+ M /branches/3.1/src/mpfr-longlong.h
+ M /branches/3.1/src/mpfr-thread.h
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/mpn_exp.c
+ M /branches/3.1/src/mul.c
+ M /branches/3.1/src/mul_2exp.c
+ M /branches/3.1/src/mul_2si.c
+ M /branches/3.1/src/mul_2ui.c
+ M /branches/3.1/src/mul_d.c
+ M /branches/3.1/src/mul_ui.c
+ M /branches/3.1/src/mulders.c
+ M /branches/3.1/src/neg.c
+ M /branches/3.1/src/next.c
+ M /branches/3.1/src/out_raw.c
+ M /branches/3.1/src/out_str.c
+ M /branches/3.1/src/pow.c
+ M /branches/3.1/src/pow_si.c
+ M /branches/3.1/src/pow_ui.c
+ M /branches/3.1/src/pow_z.c
+ M /branches/3.1/src/powerof2.c
+ M /branches/3.1/src/powerpc32/mparam.h
+ M /branches/3.1/src/powerpc64/mparam.h
+ M /branches/3.1/src/print_raw.c
+ M /branches/3.1/src/print_rnd_mode.c
+ M /branches/3.1/src/printf.c
+ M /branches/3.1/src/rec_sqrt.c
+ M /branches/3.1/src/reldiff.c
+ M /branches/3.1/src/rem1.c
+ M /branches/3.1/src/rint.c
+ M /branches/3.1/src/root.c
+ M /branches/3.1/src/round_near_x.c
+ M /branches/3.1/src/round_p.c
+ M /branches/3.1/src/round_prec.c
+ M /branches/3.1/src/round_raw_generic.c
+ M /branches/3.1/src/scale2.c
+ M /branches/3.1/src/sec.c
+ M /branches/3.1/src/sech.c
+ M /branches/3.1/src/set.c
+ M /branches/3.1/src/set_d.c
+ M /branches/3.1/src/set_d64.c
+ M /branches/3.1/src/set_dfl_prec.c
+ M /branches/3.1/src/set_exp.c
+ M /branches/3.1/src/set_f.c
+ M /branches/3.1/src/set_flt.c
+ M /branches/3.1/src/set_inf.c
+ M /branches/3.1/src/set_ld.c
+ M /branches/3.1/src/set_nan.c
+ M /branches/3.1/src/set_prc_raw.c
+ M /branches/3.1/src/set_prec.c
+ M /branches/3.1/src/set_q.c
+ M /branches/3.1/src/set_rnd.c
+ M /branches/3.1/src/set_si.c
+ M /branches/3.1/src/set_si_2exp.c
+ M /branches/3.1/src/set_sj.c
+ M /branches/3.1/src/set_str.c
+ M /branches/3.1/src/set_str_raw.c
+ M /branches/3.1/src/set_ui.c
+ M /branches/3.1/src/set_ui_2exp.c
+ M /branches/3.1/src/set_uj.c
+ M /branches/3.1/src/set_z.c
+ M /branches/3.1/src/set_z_exp.c
+ M /branches/3.1/src/set_zero.c
+ M /branches/3.1/src/setmax.c
+ M /branches/3.1/src/setmin.c
+ M /branches/3.1/src/setsign.c
+ M /branches/3.1/src/sgn.c
+ M /branches/3.1/src/si_op.c
+ M /branches/3.1/src/signbit.c
+ M /branches/3.1/src/sin.c
+ M /branches/3.1/src/sin_cos.c
+ M /branches/3.1/src/sinh.c
+ M /branches/3.1/src/sinh_cosh.c
+ M /branches/3.1/src/sparc64/mparam.h
+ M /branches/3.1/src/sqr.c
+ M /branches/3.1/src/sqrt.c
+ M /branches/3.1/src/sqrt_ui.c
+ M /branches/3.1/src/stack_interface.c
+ M /branches/3.1/src/strtofr.c
+ M /branches/3.1/src/sub.c
+ M /branches/3.1/src/sub1.c
+ M /branches/3.1/src/sub1sp.c
+ M /branches/3.1/src/sub_d.c
+ M /branches/3.1/src/sub_ui.c
+ M /branches/3.1/src/subnormal.c
+ M /branches/3.1/src/sum.c
+ M /branches/3.1/src/swap.c
+ M /branches/3.1/src/tan.c
+ M /branches/3.1/src/tanh.c
+ M /branches/3.1/src/uceil_exp2.c
+ M /branches/3.1/src/uceil_log2.c
+ M /branches/3.1/src/ufloor_log2.c
+ M /branches/3.1/src/ui_div.c
+ M /branches/3.1/src/ui_pow.c
+ M /branches/3.1/src/ui_pow_ui.c
+ M /branches/3.1/src/ui_sub.c
+ M /branches/3.1/src/urandom.c
+ M /branches/3.1/src/urandomb.c
+ M /branches/3.1/src/vasprintf.c
+ M /branches/3.1/src/version.c
+ M /branches/3.1/src/volatile.c
+ M /branches/3.1/src/x86/core2/mparam.h
+ M /branches/3.1/src/x86/mparam.h
+ M /branches/3.1/src/x86_64/core2/mparam.h
+ M /branches/3.1/src/x86_64/pentium4/mparam.h
+ M /branches/3.1/src/yn.c
+ M /branches/3.1/src/zeta.c
+ M /branches/3.1/src/zeta_ui.c
+ M /branches/3.1/tests/Makefile.am
+ M /branches/3.1/tests/cmp_str.c
+ M /branches/3.1/tests/data/digamma
+ M /branches/3.1/tests/data/li2
+ M /branches/3.1/tests/memory.c
+ M /branches/3.1/tests/mpf_compat.c
+ M /branches/3.1/tests/mpf_compat.h
+ M /branches/3.1/tests/mpfr-test.h
+ M /branches/3.1/tests/mpfr_compat.c
+ M /branches/3.1/tests/random2.c
+ M /branches/3.1/tests/reuse.c
+ M /branches/3.1/tests/rnd_mode.c
+ M /branches/3.1/tests/tabs.c
+ M /branches/3.1/tests/tacos.c
+ M /branches/3.1/tests/tacosh.c
+ M /branches/3.1/tests/tadd.c
+ M /branches/3.1/tests/tadd1sp.c
+ M /branches/3.1/tests/tadd_d.c
+ M /branches/3.1/tests/tadd_ui.c
+ M /branches/3.1/tests/tagm.c
+ M /branches/3.1/tests/tai.c
+ M /branches/3.1/tests/tasin.c
+ M /branches/3.1/tests/tasinh.c
+ M /branches/3.1/tests/tatan.c
+ M /branches/3.1/tests/tatanh.c
+ M /branches/3.1/tests/taway.c
+ M /branches/3.1/tests/tbuildopt.c
+ M /branches/3.1/tests/tcan_round.c
+ M /branches/3.1/tests/tcbrt.c
+ M /branches/3.1/tests/tcheck.c
+ M /branches/3.1/tests/tcmp.c
+ M /branches/3.1/tests/tcmp2.c
+ M /branches/3.1/tests/tcmp_d.c
+ M /branches/3.1/tests/tcmp_ld.c
+ M /branches/3.1/tests/tcmp_ui.c
+ M /branches/3.1/tests/tcmpabs.c
+ M /branches/3.1/tests/tcomparisons.c
+ M /branches/3.1/tests/tconst_catalan.c
+ M /branches/3.1/tests/tconst_euler.c
+ M /branches/3.1/tests/tconst_log2.c
+ M /branches/3.1/tests/tconst_pi.c
+ M /branches/3.1/tests/tcopysign.c
+ M /branches/3.1/tests/tcos.c
+ M /branches/3.1/tests/tcosh.c
+ M /branches/3.1/tests/tcot.c
+ M /branches/3.1/tests/tcoth.c
+ M /branches/3.1/tests/tcsc.c
+ M /branches/3.1/tests/tcsch.c
+ M /branches/3.1/tests/td_div.c
+ M /branches/3.1/tests/td_sub.c
+ M /branches/3.1/tests/tdigamma.c
+ M /branches/3.1/tests/tdim.c
+ M /branches/3.1/tests/tdiv.c
+ M /branches/3.1/tests/tdiv_d.c
+ M /branches/3.1/tests/tdiv_ui.c
+ M /branches/3.1/tests/teint.c
+ M /branches/3.1/tests/teq.c
+ M /branches/3.1/tests/terf.c
+ M /branches/3.1/tests/tests.c
+ M /branches/3.1/tests/texceptions.c
+ M /branches/3.1/tests/texp.c
+ M /branches/3.1/tests/texp10.c
+ M /branches/3.1/tests/texp2.c
+ M /branches/3.1/tests/texpm1.c
+ M /branches/3.1/tests/tfactorial.c
+ M /branches/3.1/tests/tfits.c
+ M /branches/3.1/tests/tfma.c
+ M /branches/3.1/tests/tfmod.c
+ M /branches/3.1/tests/tfms.c
+ M /branches/3.1/tests/tfprintf.c
+ M /branches/3.1/tests/tfrac.c
+ M /branches/3.1/tests/tfrexp.c
+ M /branches/3.1/tests/tgamma.c
+ M /branches/3.1/tests/tgeneric.c
+ M /branches/3.1/tests/tgeneric_ui.c
+ M /branches/3.1/tests/tget_d.c
+ M /branches/3.1/tests/tget_d_2exp.c
+ M /branches/3.1/tests/tget_f.c
+ M /branches/3.1/tests/tget_flt.c
+ M /branches/3.1/tests/tget_ld_2exp.c
+ M /branches/3.1/tests/tget_set_d64.c
+ M /branches/3.1/tests/tget_sj.c
+ M /branches/3.1/tests/tget_str.c
+ M /branches/3.1/tests/tget_z.c
+ M /branches/3.1/tests/tgmpop.c
+ M /branches/3.1/tests/tgrandom.c
+ M /branches/3.1/tests/thyperbolic.c
+ M /branches/3.1/tests/thypot.c
+ M /branches/3.1/tests/tinits.c
+ M /branches/3.1/tests/tinp_str.c
+ M /branches/3.1/tests/tinternals.c
+ M /branches/3.1/tests/tisnan.c
+ M /branches/3.1/tests/tisqrt.c
+ M /branches/3.1/tests/tj0.c
+ M /branches/3.1/tests/tj1.c
+ M /branches/3.1/tests/tjn.c
+ M /branches/3.1/tests/tl2b.c
+ M /branches/3.1/tests/tlgamma.c
+ M /branches/3.1/tests/tli2.c
+ M /branches/3.1/tests/tlngamma.c
+ M /branches/3.1/tests/tlog.c
+ M /branches/3.1/tests/tlog10.c
+ M /branches/3.1/tests/tlog1p.c
+ M /branches/3.1/tests/tlog2.c
+ M /branches/3.1/tests/tmin_prec.c
+ M /branches/3.1/tests/tminmax.c
+ M /branches/3.1/tests/tmodf.c
+ M /branches/3.1/tests/tmul.c
+ M /branches/3.1/tests/tmul_2exp.c
+ M /branches/3.1/tests/tmul_d.c
+ M /branches/3.1/tests/tmul_ui.c
+ M /branches/3.1/tests/tnext.c
+ M /branches/3.1/tests/tout_str.c
+ M /branches/3.1/tests/toutimpl.c
+ M /branches/3.1/tests/tpow.c
+ M /branches/3.1/tests/tpow3.c
+ M /branches/3.1/tests/tpow_all.c
+ M /branches/3.1/tests/tpow_z.c
+ M /branches/3.1/tests/tprintf.c
+ M /branches/3.1/tests/trandom.c
+ M /branches/3.1/tests/trec_sqrt.c
+ M /branches/3.1/tests/tremquo.c
+ M /branches/3.1/tests/trint.c
+ M /branches/3.1/tests/troot.c
+ M /branches/3.1/tests/tround_prec.c
+ M /branches/3.1/tests/tsec.c
+ M /branches/3.1/tests/tsech.c
+ M /branches/3.1/tests/tset.c
+ M /branches/3.1/tests/tset_d.c
+ M /branches/3.1/tests/tset_exp.c
+ M /branches/3.1/tests/tset_f.c
+ M /branches/3.1/tests/tset_ld.c
+ M /branches/3.1/tests/tset_q.c
+ M /branches/3.1/tests/tset_si.c
+ M /branches/3.1/tests/tset_sj.c
+ M /branches/3.1/tests/tset_str.c
+ M /branches/3.1/tests/tset_z.c
+ M /branches/3.1/tests/tset_z_exp.c
+ M /branches/3.1/tests/tsgn.c
+ M /branches/3.1/tests/tsi_op.c
+ M /branches/3.1/tests/tsin.c
+ M /branches/3.1/tests/tsin_cos.c
+ M /branches/3.1/tests/tsinh.c
+ M /branches/3.1/tests/tsinh_cosh.c
+ M /branches/3.1/tests/tsprintf.c
+ M /branches/3.1/tests/tsqr.c
+ M /branches/3.1/tests/tsqrt.c
+ M /branches/3.1/tests/tsqrt_ui.c
+ M /branches/3.1/tests/tstckintc.c
+ M /branches/3.1/tests/tstdint.c
+ M /branches/3.1/tests/tstrtofr.c
+ M /branches/3.1/tests/tsub.c
+ M /branches/3.1/tests/tsub1sp.c
+ M /branches/3.1/tests/tsub_d.c
+ M /branches/3.1/tests/tsub_ui.c
+ M /branches/3.1/tests/tsubnormal.c
+ M /branches/3.1/tests/tsum.c
+ M /branches/3.1/tests/tswap.c
+ M /branches/3.1/tests/ttan.c
+ M /branches/3.1/tests/ttanh.c
+ M /branches/3.1/tests/ttrunc.c
+ M /branches/3.1/tests/tui_div.c
+ M /branches/3.1/tests/tui_pow.c
+ M /branches/3.1/tests/tui_sub.c
+ M /branches/3.1/tests/turandom.c
+ M /branches/3.1/tests/tvalist.c
+ M /branches/3.1/tests/tversion.c
+ M /branches/3.1/tests/ty0.c
+ M /branches/3.1/tests/ty1.c
+ M /branches/3.1/tests/tyn.c
+ M /branches/3.1/tests/tzeta.c
+ M /branches/3.1/tests/tzeta_ui.c
+ M /branches/3.1/tools/ck-copyright-notice
+ M /branches/3.1/tools/ck-mparam
+ M /branches/3.1/tools/ck-version-info
+ M /branches/3.1/tools/get_patches.sh
+ M /branches/3.1/tune/Makefile.am
+ M /branches/3.1/tune/bidimensional_sample.c
+ M /branches/3.1/tune/speed.c
+ M /branches/3.1/tune/tuneup.c
+
+Copyright notice update: added 2013 with
+ perl -pi -e 's/2012 Free Software/2012, 2013 Free Software/' **/*(^/)
+under zsh, reverting the ChangeLog file (the m4 and tools/mbench
+directories were not modified).
+Removed 2012 from the example in the doc/README.dev file.
+------------------------------------------------------------------------
+r8464 | vlefevre | 2013-03-08 00:28:01 +0000 (Fri, 08 Mar 2013) | 3 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/examples/ReadMe
+ M /branches/3.1/examples/divworst.c
+ M /branches/3.1/examples/rndo-add.c
+ M /branches/3.1/examples/sample.c
+ M /branches/3.1/examples/version.c
+
+[examples] Replaced the old rounding mode macros (GMP_RNDN, etc.) by the
+new ones (MPFR_RNDN, etc.) in the *.c files; updated ReadMe file.
+(merged changeset r8461 from the trunk)
+------------------------------------------------------------------------
+r8463 | vlefevre | 2013-03-08 00:26:52 +0000 (Fri, 08 Mar 2013) | 5 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/faq.xsl
+ M /branches/3.1/doc/update-faq
+
+[doc] Slightly modified faq.xsl to avoid libxslt bug 377440, and
+moved the addition of special CSS comments for XML compatibility
+from update-faq to faq.xsl file. Removed the now useless
+s/GMP_RND/MPFR_RND/ rewriting in update-faq.
+(merged changesets r8458,8460 from the trunk)
+------------------------------------------------------------------------
+r8454 | vlefevre | 2013-02-22 12:11:37 +0000 (Fri, 22 Feb 2013) | 3 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/get_f.c
+ M /branches/3.1/src/mpfr-gmp.h
+ M /branches/3.1/tests/tadd.c
+ M /branches/3.1/tests/tgeneric.c
+
+Compatibility with GMP 5.1.0 and later when gmp-impl.h is included,
+i.e. with --with-gmp-build (thanks to Rob for the fix); clean-up.
+(merged changeset r8439 from the trunk)
+------------------------------------------------------------------------
+r8399 | vlefevre | 2012-08-29 13:54:55 +0000 (Wed, 29 Aug 2012) | 8 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/strtofr.c
+ M /branches/3.1/tests/tstrtofr.c
+
+[src/strtofr.c] Fixed bug in mpfr_strtofr in case:
+ (1) the input string was used entirely
+ (2) the conversion was done by a division
+ (3) and the division was exact
+ In such a case the "reconstruction" of the ternary value was inexact.
+[tests/tstrtofr.c] Added various testcases (for this bug and for bugs
+ in intermediate revisions).
+(merged changesets r8371,8384,8389-8398 from the trunk)
+------------------------------------------------------------------------
+r8387 | vlefevre | 2012-08-28 15:06:27 +0000 (Tue, 28 Aug 2012) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/FAQ.html
+
+[doc] Updated FAQ.html (changeset r8386 from the trunk).
+------------------------------------------------------------------------
+r8380 | vlefevre | 2012-08-16 09:12:57 +0000 (Thu, 16 Aug 2012) | 5 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/get_d64.c
+ M /branches/3.1/tests/tget_set_d64.c
+
+[src/get_d64.c] mpfr_get_decimal64 was buggy in MPFR_RNDN on some
+ values x such that 0.5e-398 < |x| < 1e-398 (smallest subnormal):
+ it was returning 0 instead of +/- 1e-398.
+[tests/tget_set_d64.c] Added testcases.
+(merged changesets r8370,8379 from the trunk)
+------------------------------------------------------------------------
+r8378 | vlefevre | 2012-08-15 23:41:21 +0000 (Wed, 15 Aug 2012) | 7 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/get_d64.c
+ M /branches/3.1/tests/tget_set_d64.c
+
+[src/get_d64.c] Fixed get_decimal64_max by simplifying it completely,
+and changed get_decimal64_min in the same way.
+Thanks to Rob (Sisyphus) for the idea.
+[tests/tget_set_d64.c] Added some tests for large numbers and overflow
+tests (they cover the two bad tests fixed in r8373 and trigger the bug
+in get_decimal64_max fixed here).
+(merged changesets r8375-8377 from the trunk)
+------------------------------------------------------------------------
+r8373 | vlefevre | 2012-08-14 10:37:10 +0000 (Tue, 14 Aug 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/get_d64.c
+
+[src/get_d64.c] Fixed overflow cases.
+(merged changeset r8372 from the trunk)
+------------------------------------------------------------------------
+r8361 | vlefevre | 2012-07-26 14:21:40 +0000 (Thu, 26 Jul 2012) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/configure.ac
+
+[configure.ac] Replaced "sed" by "$SED" and "grep" by "$EGREP".
+------------------------------------------------------------------------
+r8330 | vlefevre | 2012-07-05 10:44:31 +0000 (Thu, 05 Jul 2012) | 2 lines
+Changed paths:
+ M /branches/3.1/tools/coverage
+
+[tools/coverage] Added a comment about the non-reproducibility of the
+coverage results.
+------------------------------------------------------------------------
+r8318 | vlefevre | 2012-07-04 09:30:08 +0000 (Wed, 04 Jul 2012) | 1 line
+Changed paths:
+ M /branches/3.1/INSTALL
+ M /branches/3.1/VERSION
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/version.c
+
+Updated version to 3.1.2-dev.
+------------------------------------------------------------------------
+r8309 | vlefevre | 2012-07-03 14:23:23 +0000 (Tue, 03 Jul 2012) | 1 line
+Changed paths:
+ M /branches/3.1/ChangeLog
+
+ChangeLog update with "TZ=UTC svn log -rHEAD:0 -v" (in UTF-8 locales).
+------------------------------------------------------------------------
+r8307 | vlefevre | 2012-07-03 14:19:10 +0000 (Tue, 03 Jul 2012) | 1 line
+Changed paths:
+ M /branches/3.1/NEWS
+
+[NEWS] Added test coverage for MPFR 3.1.1.
+------------------------------------------------------------------------
+r8306 | vlefevre | 2012-07-03 14:17:16 +0000 (Tue, 03 Jul 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tools/coverage
+
+[tools/coverage] Some changes from the trunk (r8263,8275,8277,8305),
+in particular detailed coverage.
+------------------------------------------------------------------------
+r8303 | vlefevre | 2012-07-03 13:52:02 +0000 (Tue, 03 Jul 2012) | 1 line
+Changed paths:
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r8301 | vlefevre | 2012-07-03 13:49:45 +0000 (Tue, 03 Jul 2012) | 1 line
+Changed paths:
+ M /branches/3.1/VERSION
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/version.c
+
+Updated version to 3.1.1.
+------------------------------------------------------------------------
+r8300 | vlefevre | 2012-07-03 13:47:34 +0000 (Tue, 03 Jul 2012) | 4 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/td_div.c
+ M /branches/3.1/tests/tests.c
+ M /branches/3.1/tests/tget_d.c
+
+[tests/tests.c] Improved an error message.
+[tests/{td_div.c,tget_d.c}] Disable tests with a division by 0 if
+ MPFR_ERRDIVZERO is defined.
+(merged changesets r8298-8299 from the trunk)
+------------------------------------------------------------------------
+r8290 | vlefevre | 2012-06-27 12:00:38 +0000 (Wed, 27 Jun 2012) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+
+[mpfr.texi] added support by ERC grant of Andreas
+------------------------------------------------------------------------
+r8288 | vlefevre | 2012-06-27 09:15:26 +0000 (Wed, 27 Jun 2012) | 1 line
+Changed paths:
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Document MPFR_WANT_DECIMAL_FLOATS.
+------------------------------------------------------------------------
+r8284 | vlefevre | 2012-06-27 08:37:21 +0000 (Wed, 27 Jun 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/tgrandom.c
+
+[tests/tgrandom.c] Replaced GMP_RNDN by MPFR_RNDN.
+(merged changeset r8283 from the trunk)
+------------------------------------------------------------------------
+r8282 | vlefevre | 2012-06-27 08:33:41 +0000 (Wed, 27 Jun 2012) | 1 line
+Changed paths:
+ M /branches/3.1/NEWS
+
+[NEWS] Update.
+------------------------------------------------------------------------
+r8281 | vlefevre | 2012-06-27 08:23:11 +0000 (Wed, 27 Jun 2012) | 4 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/tests/tgrandom.c
+
+[doc/mpfr.texi] Completed spec of mpfr_grandom.
+[tests/tgrandom.c] Improved a test and added a new one for
+ mpfr_grandom(x, NULL, ...).
+(merged changesets r8279-8280 from the trunk)
+------------------------------------------------------------------------
+r8278 | vlefevre | 2012-06-27 08:10:45 +0000 (Wed, 27 Jun 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/NEWS
+
+[NEWS] Update: test coverage.
+(merged changeset r8276 from the trunk)
+------------------------------------------------------------------------
+r8259 | vlefevre | 2012-06-26 15:02:18 +0000 (Tue, 26 Jun 2012) | 1 line
+Changed paths:
+ M /branches/3.1/ChangeLog
+
+ChangeLog update with "TZ=UTC svn log -rHEAD:0 -v" (in UTF-8 locales).
+------------------------------------------------------------------------
+r8257 | vlefevre | 2012-06-26 14:51:13 +0000 (Tue, 26 Jun 2012) | 1 line
+Changed paths:
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r8256 | vlefevre | 2012-06-26 14:50:17 +0000 (Tue, 26 Jun 2012) | 2 lines
+Changed paths:
+ M /branches/3.1/VERSION
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/Makefile.am
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/version.c
+
+Updated version to 3.1.1-rc1 and updated libmpfr_la_LDFLAGS in
+src/Makefile.am for the next release.
+------------------------------------------------------------------------
+r8255 | vlefevre | 2012-06-26 14:41:27 +0000 (Tue, 26 Jun 2012) | 1 line
+Changed paths:
+ M /branches/3.1/NEWS
+
+[NEWS] Update for GNU MPFR 3.1.1.
+------------------------------------------------------------------------
+r8254 | vlefevre | 2012-06-26 14:03:44 +0000 (Tue, 26 Jun 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/tinternals.c
+
+[tests/tinternals.c] mpfr_set_prec_raw missing tests (thanks to Patrick).
+(merged changeset r8253 from the trunk)
+------------------------------------------------------------------------
+r8252 | vlefevre | 2012-06-26 13:57:32 +0000 (Tue, 26 Jun 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/tset_si.c
+
+[tests/tset_si.c] Also test the mpfr_set_ui function (instead of macro).
+(merged changeset r8251 from the trunk)
+------------------------------------------------------------------------
+r8220 | vlefevre | 2012-06-21 23:03:44 +0000 (Thu, 21 Jun 2012) | 3 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/tset_ld.c
+
+[tests/tset_ld.c] For _GMP_IEEE_FLOATS, use #if instead of #ifdef
+since mpfr-impl.h defines it to 0 if it was undefined.
+(merged changeset r8219 from the trunk)
+------------------------------------------------------------------------
+r8205 | vlefevre | 2012-05-09 00:07:18 +0000 (Wed, 09 May 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/configure.ac
+ M /branches/3.1/tests/Makefile.am
+
+Patch from Nitin A Kamble for automake 1.12
+(merged changeset r8204 from the trunk)
+------------------------------------------------------------------------
+r8202 | vlefevre | 2012-05-07 18:13:13 +0000 (Mon, 07 May 2012) | 5 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/AUTHORS
+ M /branches/3.1/INSTALL
+ M /branches/3.1/doc/mpfr.texi
+
+[AUTHORS,INSTALL,doc/mpfr.texi] Updated the e-mail address of the
+MPFR mailing-list to match the List-* headers written by the new
+mailing-list server (the old one still works, but may lead to bad
+interaction with MUA's that attempt to honor the List-Post header
+when replying to the list(s)).
+------------------------------------------------------------------------
+r8200 | vlefevre | 2012-05-07 17:58:04 +0000 (Mon, 07 May 2012) | 6 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/gamma.c
+ M /branches/3.1/src/lngamma.c
+ M /branches/3.1/tests/tgamma.c
+
+[src/lngamma.c] Added mpfr_explgamma internal function to handle
+ overflows/underflows (intermediate or not) in mpfr_gamma. Added
+ general overflow detection.
+[src/gamma.c] Added general underflow detection.
+[tests/tgamma.c] Added testcases for 32-bit and 64-bit machines.
+(merged changesets r8174,8179,8182-8183,8185-8189,8191-8199 from the trunk)
+------------------------------------------------------------------------
+r8184 | vlefevre | 2012-05-03 14:44:57 +0000 (Thu, 03 May 2012) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/gamma.c
+
+[src/gamma.c] Reverted changeset r8180, which seems incorrect.
+------------------------------------------------------------------------
+r8180 | vlefevre | 2012-05-03 13:46:22 +0000 (Thu, 03 May 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/gamma.c
+
+[gamma.c] tentative fix for the underflow problem
+(merged changesets r8174,8179 from the trunk)
+------------------------------------------------------------------------
+r8178 | vlefevre | 2012-05-03 13:26:40 +0000 (Thu, 03 May 2012) | 1 line
+Changed paths:
+ M /branches/3.1/ChangeLog
+
+ChangeLog update with "TZ=UTC svn log -rHEAD:0 -v" (in UTF-8 locales).
+------------------------------------------------------------------------
+r8176 | vlefevre | 2012-05-03 13:08:51 +0000 (Thu, 03 May 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/TODO
+ M /branches/3.1/doc/README.dev
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/mpfr-impl.h
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/subnormal.c
+ M /branches/3.1/tests/Makefile.am
+ M /branches/3.1/tests/tatan.c
+ M /branches/3.1/tests/tsin_cos.c
+ M /branches/3.1/tests/tsqr.c
+
+Merged changesets r8172-8173,8175 from the trunk to update URL's of
+mailing-list archives/messages.
+------------------------------------------------------------------------
+r8165 | vlefevre | 2012-04-27 12:39:54 +0000 (Fri, 27 Apr 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/tgamma.c
+
+[tests/tgamma.c] Improved testcase test20100709.
+(merged changeset r8164 from the trunk)
+------------------------------------------------------------------------
+r8163 | vlefevre | 2012-04-27 12:29:02 +0000 (Fri, 27 Apr 2012) | 3 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/tgamma.c
+
+[tests/tgamma.c] Updated testcase test20100709 for 64-bit machines,
+as this bug reappeared in r8160 (r8159 from the trunk).
+(merged changeset r8162 from the trunk)
+------------------------------------------------------------------------
+r8160 | vlefevre | 2012-04-27 01:08:44 +0000 (Fri, 27 Apr 2012) | 5 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/gamma.c
+ M /branches/3.1/tests/tgamma.c
+
+[src/gamma.c] Fixed bug in the underflow detection code of mpfr_gamma,
+ found by Giridhar Tammana: some results may incorrectly be regarded
+ as underflow.
+[tests/tgamma.c] Added testcase.
+(merged changeset r8159 from the trunk)
+------------------------------------------------------------------------
+r8127 | vlefevre | 2012-03-26 12:25:58 +0000 (Mon, 26 Mar 2012) | 3 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/Makefile.am
+ M /branches/3.1/tests/tests.c
+
+[tests/{Makefile.am,tests.c}] Fixed src_fopen to be able to run test
+programs directly (without "make check") when objdir != srcdir.
+(merged changesets r8122,8126 from the trunk)
+------------------------------------------------------------------------
+r8084 | vlefevre | 2012-03-09 12:03:59 +0000 (Fri, 09 Mar 2012) | 4 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Improved macros from the changeset r8080, in
+particular to avoid an error with the --enable-assert configure
+option and the -ansi -pedantic-errors gcc compiler flags.
+(merged changesets r7910,8082,8083 from the trunk)
+------------------------------------------------------------------------
+r8080 | vlefevre | 2012-03-08 14:11:02 +0000 (Thu, 08 Mar 2012) | 8 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/add1.c
+ M /branches/3.1/src/add1sp.c
+ M /branches/3.1/src/agm.c
+ M /branches/3.1/src/eq.c
+ M /branches/3.1/src/exp.c
+ M /branches/3.1/src/get_d.c
+ M /branches/3.1/src/get_flt.c
+ M /branches/3.1/src/get_str.c
+ M /branches/3.1/src/init2.c
+ M /branches/3.1/src/lngamma.c
+ M /branches/3.1/src/mpfr-impl.h
+ M /branches/3.1/src/mul.c
+ M /branches/3.1/src/pow.c
+ M /branches/3.1/src/print_raw.c
+ M /branches/3.1/src/round_prec.c
+ M /branches/3.1/src/round_raw_generic.c
+ M /branches/3.1/src/set.c
+ M /branches/3.1/src/set_f.c
+ M /branches/3.1/src/set_prec.c
+ M /branches/3.1/src/setmax.c
+ M /branches/3.1/src/sqr.c
+ M /branches/3.1/src/stack_interface.c
+ M /branches/3.1/src/strtofr.c
+ M /branches/3.1/src/sub1sp.c
+ M /branches/3.1/src/urandomb.c
+ M /branches/3.1/tests/tinits.c
+
+Avoid potential integer overflows and improve consistency. This should
+fix bug #13918 "Segfault with precision = MPFR_PREC_MAX on 32-bit".
+Note: this problem appeared in MPFR 3.0.0 when the precision type (now
+mpfr_prec_t) was changed to a signed integer.
+Added a large precision test in tests/tinits.c (enabled by setting
+MPFR_CHECK_LARGEMEM=1) to trigger the bug mentioned above on 32-bit
+machines (or when MPFR is built with -m32).
+(merged changesets r8025,8026,8029,8031,8077 from the trunk)
+------------------------------------------------------------------------
+r8069 | vlefevre | 2012-03-07 15:02:17 +0000 (Wed, 07 Mar 2012) | 5 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/mpfr.h
+
+[src/mpfr.h] Simple temporary fix following GMP's internal __gmp_const
+macro removal in <http://gmplib.org:8000/gmp/rev/d287cfaf6732> (and its
+replacement by const): if __gmp_const isn't define, let's define it to
+const.
+(merged changeset r8061 from the trunk)
+------------------------------------------------------------------------
+r8059 | vlefevre | 2012-03-03 03:00:29 +0000 (Sat, 03 Mar 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/NEWS
+
+[NEWS] Mention the mpfr_exp bug fix (from r6964 in exp_2.c).
+(merged changeset r8058 from the trunk)
+------------------------------------------------------------------------
+r8049 | vlefevre | 2012-02-24 13:45:11 +0000 (Fri, 24 Feb 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Use %.*Rg instead of %.*Rf for MPFR_LOG_VAR.
+(merged changeset r8048 from the trunk)
+------------------------------------------------------------------------
+r8047 | vlefevre | 2012-02-24 12:38:46 +0000 (Fri, 24 Feb 2012) | 6 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/add_d.c
+ M /branches/3.1/src/add_ui.c
+ M /branches/3.1/src/mul_d.c
+
+Corrected a typo in MPFR_LOG_FUNC of add_d.c, add_ui.c and mul_d.c
+(mpfr_get_prec → mpfr_log_prec), fixing bug 13933.
+The consequence was random freezes (on the same binary) with dynamic
+linking (and just more memory with static linking to the MPFR library)
+when logging was used.
+(merged changeset r8043 from the trunk)
+------------------------------------------------------------------------
+r8045 | vlefevre | 2012-02-24 12:22:24 +0000 (Fri, 24 Feb 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/NEWS
+
+[NEWS] Mention an internal change in MPFR 3.1.0.
+(merged changeset r8044 from the trunk)
+------------------------------------------------------------------------
+r8017 | vlefevre | 2012-01-27 08:36:16 +0000 (Fri, 27 Jan 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/mparam_h.in
+ M /branches/3.1/src/x86_64/core2/mparam.h
+
+Use the core2 tuning parameters for nocona as timings are very similar.
+[Merged r8013 through r8016 from the trunk]
+------------------------------------------------------------------------
+r8012 | vlefevre | 2012-01-23 01:28:48 +0000 (Mon, 23 Jan 2012) | 3 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/mparam_h.in
+
+[mparam_h.in] swap tests for 32-bit and 64-bit powerpc, since on powerpc64
+ the parameters for 32-bit are used!
+(merged changeset r8010 from the trunk)
+------------------------------------------------------------------------
+r7999 | vlefevre | 2012-01-10 12:51:46 +0000 (Tue, 10 Jan 2012) | 1 line
+Changed paths:
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7997 | vlefevre | 2012-01-10 12:49:58 +0000 (Tue, 10 Jan 2012) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Mention the AriC project-team.
+------------------------------------------------------------------------
+r7995 | vlefevre | 2012-01-10 12:47:05 +0000 (Tue, 10 Jan 2012) | 3 lines
+Changed paths:
+ M /branches/3.1/BUGS
+ M /branches/3.1/INSTALL
+ M /branches/3.1/NEWS
+ M /branches/3.1/README
+ M /branches/3.1/TODO
+ M /branches/3.1/acinclude.m4
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/FAQ.html
+ M /branches/3.1/doc/README.dev
+ M /branches/3.1/doc/faq.xsl
+ M /branches/3.1/examples/divworst.c
+ M /branches/3.1/examples/rndo-add.c
+ M /branches/3.1/examples/sample.c
+ M /branches/3.1/examples/version.c
+ M /branches/3.1/src/abort_prec_max.c
+ M /branches/3.1/src/acos.c
+ M /branches/3.1/src/acosh.c
+ M /branches/3.1/src/add.c
+ M /branches/3.1/src/add1.c
+ M /branches/3.1/src/add1sp.c
+ M /branches/3.1/src/add_d.c
+ M /branches/3.1/src/add_ui.c
+ M /branches/3.1/src/agm.c
+ M /branches/3.1/src/ai.c
+ M /branches/3.1/src/asin.c
+ M /branches/3.1/src/asinh.c
+ M /branches/3.1/src/atan.c
+ M /branches/3.1/src/atan2.c
+ M /branches/3.1/src/atanh.c
+ M /branches/3.1/src/bernoulli.c
+ M /branches/3.1/src/buildopt.c
+ M /branches/3.1/src/cache.c
+ M /branches/3.1/src/cbrt.c
+ M /branches/3.1/src/check.c
+ M /branches/3.1/src/clear.c
+ M /branches/3.1/src/clears.c
+ M /branches/3.1/src/cmp.c
+ M /branches/3.1/src/cmp2.c
+ M /branches/3.1/src/cmp_abs.c
+ M /branches/3.1/src/cmp_d.c
+ M /branches/3.1/src/cmp_ld.c
+ M /branches/3.1/src/cmp_si.c
+ M /branches/3.1/src/cmp_ui.c
+ M /branches/3.1/src/comparisons.c
+ M /branches/3.1/src/const_catalan.c
+ M /branches/3.1/src/const_euler.c
+ M /branches/3.1/src/const_log2.c
+ M /branches/3.1/src/const_pi.c
+ M /branches/3.1/src/constant.c
+ M /branches/3.1/src/copysign.c
+ M /branches/3.1/src/cos.c
+ M /branches/3.1/src/cosh.c
+ M /branches/3.1/src/cot.c
+ M /branches/3.1/src/coth.c
+ M /branches/3.1/src/csc.c
+ M /branches/3.1/src/csch.c
+ M /branches/3.1/src/d_div.c
+ M /branches/3.1/src/d_sub.c
+ M /branches/3.1/src/digamma.c
+ M /branches/3.1/src/dim.c
+ M /branches/3.1/src/div.c
+ M /branches/3.1/src/div_2exp.c
+ M /branches/3.1/src/div_2si.c
+ M /branches/3.1/src/div_2ui.c
+ M /branches/3.1/src/div_d.c
+ M /branches/3.1/src/div_ui.c
+ M /branches/3.1/src/dump.c
+ M /branches/3.1/src/eint.c
+ M /branches/3.1/src/eq.c
+ M /branches/3.1/src/erf.c
+ M /branches/3.1/src/erfc.c
+ M /branches/3.1/src/exceptions.c
+ M /branches/3.1/src/exp.c
+ M /branches/3.1/src/exp10.c
+ M /branches/3.1/src/exp2.c
+ M /branches/3.1/src/exp3.c
+ M /branches/3.1/src/exp_2.c
+ M /branches/3.1/src/expm1.c
+ M /branches/3.1/src/extract.c
+ M /branches/3.1/src/factorial.c
+ M /branches/3.1/src/fits_intmax.c
+ M /branches/3.1/src/fits_s.h
+ M /branches/3.1/src/fits_sint.c
+ M /branches/3.1/src/fits_slong.c
+ M /branches/3.1/src/fits_sshort.c
+ M /branches/3.1/src/fits_u.h
+ M /branches/3.1/src/fits_uint.c
+ M /branches/3.1/src/fits_uintmax.c
+ M /branches/3.1/src/fits_ulong.c
+ M /branches/3.1/src/fits_ushort.c
+ M /branches/3.1/src/fma.c
+ M /branches/3.1/src/fms.c
+ M /branches/3.1/src/frac.c
+ M /branches/3.1/src/free_cache.c
+ M /branches/3.1/src/frexp.c
+ M /branches/3.1/src/gamma.c
+ M /branches/3.1/src/gammaonethird.c
+ M /branches/3.1/src/gen_inverse.h
+ M /branches/3.1/src/get_d.c
+ M /branches/3.1/src/get_d64.c
+ M /branches/3.1/src/get_exp.c
+ M /branches/3.1/src/get_f.c
+ M /branches/3.1/src/get_flt.c
+ M /branches/3.1/src/get_ld.c
+ M /branches/3.1/src/get_si.c
+ M /branches/3.1/src/get_sj.c
+ M /branches/3.1/src/get_str.c
+ M /branches/3.1/src/get_ui.c
+ M /branches/3.1/src/get_uj.c
+ M /branches/3.1/src/get_z.c
+ M /branches/3.1/src/get_z_exp.c
+ M /branches/3.1/src/gmp_op.c
+ M /branches/3.1/src/grandom.c
+ M /branches/3.1/src/hypot.c
+ M /branches/3.1/src/ieee_floats.h
+ M /branches/3.1/src/init.c
+ M /branches/3.1/src/init2.c
+ M /branches/3.1/src/inits.c
+ M /branches/3.1/src/inits2.c
+ M /branches/3.1/src/inp_str.c
+ M /branches/3.1/src/int_ceil_log2.c
+ M /branches/3.1/src/isinf.c
+ M /branches/3.1/src/isinteger.c
+ M /branches/3.1/src/isnan.c
+ M /branches/3.1/src/isnum.c
+ M /branches/3.1/src/isqrt.c
+ M /branches/3.1/src/isregular.c
+ M /branches/3.1/src/iszero.c
+ M /branches/3.1/src/jn.c
+ M /branches/3.1/src/jyn_asympt.c
+ M /branches/3.1/src/li2.c
+ M /branches/3.1/src/lngamma.c
+ M /branches/3.1/src/log.c
+ M /branches/3.1/src/log10.c
+ M /branches/3.1/src/log1p.c
+ M /branches/3.1/src/log2.c
+ M /branches/3.1/src/logging.c
+ M /branches/3.1/src/min_prec.c
+ M /branches/3.1/src/minmax.c
+ M /branches/3.1/src/modf.c
+ M /branches/3.1/src/mpf2mpfr.h
+ M /branches/3.1/src/mpfr-gmp.c
+ M /branches/3.1/src/mpfr-gmp.h
+ M /branches/3.1/src/mpfr-impl.h
+ M /branches/3.1/src/mpfr-intmax.h
+ M /branches/3.1/src/mpfr-thread.h
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/mpn_exp.c
+ M /branches/3.1/src/mul.c
+ M /branches/3.1/src/mul_2exp.c
+ M /branches/3.1/src/mul_2si.c
+ M /branches/3.1/src/mul_2ui.c
+ M /branches/3.1/src/mul_d.c
+ M /branches/3.1/src/mul_ui.c
+ M /branches/3.1/src/mulders.c
+ M /branches/3.1/src/neg.c
+ M /branches/3.1/src/next.c
+ M /branches/3.1/src/out_raw.c
+ M /branches/3.1/src/out_str.c
+ M /branches/3.1/src/pow.c
+ M /branches/3.1/src/pow_si.c
+ M /branches/3.1/src/pow_ui.c
+ M /branches/3.1/src/pow_z.c
+ M /branches/3.1/src/powerof2.c
+ M /branches/3.1/src/print_raw.c
+ M /branches/3.1/src/print_rnd_mode.c
+ M /branches/3.1/src/printf.c
+ M /branches/3.1/src/rec_sqrt.c
+ M /branches/3.1/src/reldiff.c
+ M /branches/3.1/src/rem1.c
+ M /branches/3.1/src/rint.c
+ M /branches/3.1/src/root.c
+ M /branches/3.1/src/round_near_x.c
+ M /branches/3.1/src/round_p.c
+ M /branches/3.1/src/round_prec.c
+ M /branches/3.1/src/round_raw_generic.c
+ M /branches/3.1/src/scale2.c
+ M /branches/3.1/src/sec.c
+ M /branches/3.1/src/sech.c
+ M /branches/3.1/src/set.c
+ M /branches/3.1/src/set_d.c
+ M /branches/3.1/src/set_d64.c
+ M /branches/3.1/src/set_dfl_prec.c
+ M /branches/3.1/src/set_exp.c
+ M /branches/3.1/src/set_f.c
+ M /branches/3.1/src/set_flt.c
+ M /branches/3.1/src/set_inf.c
+ M /branches/3.1/src/set_ld.c
+ M /branches/3.1/src/set_nan.c
+ M /branches/3.1/src/set_prc_raw.c
+ M /branches/3.1/src/set_prec.c
+ M /branches/3.1/src/set_q.c
+ M /branches/3.1/src/set_rnd.c
+ M /branches/3.1/src/set_si.c
+ M /branches/3.1/src/set_si_2exp.c
+ M /branches/3.1/src/set_sj.c
+ M /branches/3.1/src/set_str.c
+ M /branches/3.1/src/set_str_raw.c
+ M /branches/3.1/src/set_ui.c
+ M /branches/3.1/src/set_ui_2exp.c
+ M /branches/3.1/src/set_uj.c
+ M /branches/3.1/src/set_z.c
+ M /branches/3.1/src/set_z_exp.c
+ M /branches/3.1/src/set_zero.c
+ M /branches/3.1/src/setmax.c
+ M /branches/3.1/src/setmin.c
+ M /branches/3.1/src/setsign.c
+ M /branches/3.1/src/sgn.c
+ M /branches/3.1/src/si_op.c
+ M /branches/3.1/src/signbit.c
+ M /branches/3.1/src/sin.c
+ M /branches/3.1/src/sin_cos.c
+ M /branches/3.1/src/sinh.c
+ M /branches/3.1/src/sinh_cosh.c
+ M /branches/3.1/src/sqr.c
+ M /branches/3.1/src/sqrt.c
+ M /branches/3.1/src/sqrt_ui.c
+ M /branches/3.1/src/stack_interface.c
+ M /branches/3.1/src/strtofr.c
+ M /branches/3.1/src/sub.c
+ M /branches/3.1/src/sub1.c
+ M /branches/3.1/src/sub1sp.c
+ M /branches/3.1/src/sub_d.c
+ M /branches/3.1/src/sub_ui.c
+ M /branches/3.1/src/subnormal.c
+ M /branches/3.1/src/sum.c
+ M /branches/3.1/src/swap.c
+ M /branches/3.1/src/tan.c
+ M /branches/3.1/src/tanh.c
+ M /branches/3.1/src/uceil_exp2.c
+ M /branches/3.1/src/uceil_log2.c
+ M /branches/3.1/src/ufloor_log2.c
+ M /branches/3.1/src/ui_div.c
+ M /branches/3.1/src/ui_pow.c
+ M /branches/3.1/src/ui_pow_ui.c
+ M /branches/3.1/src/ui_sub.c
+ M /branches/3.1/src/urandom.c
+ M /branches/3.1/src/urandomb.c
+ M /branches/3.1/src/vasprintf.c
+ M /branches/3.1/src/version.c
+ M /branches/3.1/src/volatile.c
+ M /branches/3.1/src/yn.c
+ M /branches/3.1/src/zeta.c
+ M /branches/3.1/src/zeta_ui.c
+ M /branches/3.1/tests/cmp_str.c
+ M /branches/3.1/tests/data/digamma
+ M /branches/3.1/tests/data/li2
+ M /branches/3.1/tests/memory.c
+ M /branches/3.1/tests/mpf_compat.c
+ M /branches/3.1/tests/mpf_compat.h
+ M /branches/3.1/tests/mpfr-test.h
+ M /branches/3.1/tests/mpfr_compat.c
+ M /branches/3.1/tests/random2.c
+ M /branches/3.1/tests/reuse.c
+ M /branches/3.1/tests/rnd_mode.c
+ M /branches/3.1/tests/tabs.c
+ M /branches/3.1/tests/tacos.c
+ M /branches/3.1/tests/tacosh.c
+ M /branches/3.1/tests/tadd.c
+ M /branches/3.1/tests/tadd1sp.c
+ M /branches/3.1/tests/tadd_d.c
+ M /branches/3.1/tests/tadd_ui.c
+ M /branches/3.1/tests/tagm.c
+ M /branches/3.1/tests/tai.c
+ M /branches/3.1/tests/tasin.c
+ M /branches/3.1/tests/tasinh.c
+ M /branches/3.1/tests/tatan.c
+ M /branches/3.1/tests/tatanh.c
+ M /branches/3.1/tests/taway.c
+ M /branches/3.1/tests/tbuildopt.c
+ M /branches/3.1/tests/tcan_round.c
+ M /branches/3.1/tests/tcbrt.c
+ M /branches/3.1/tests/tcheck.c
+ M /branches/3.1/tests/tcmp.c
+ M /branches/3.1/tests/tcmp2.c
+ M /branches/3.1/tests/tcmp_d.c
+ M /branches/3.1/tests/tcmp_ld.c
+ M /branches/3.1/tests/tcmp_ui.c
+ M /branches/3.1/tests/tcmpabs.c
+ M /branches/3.1/tests/tcomparisons.c
+ M /branches/3.1/tests/tconst_catalan.c
+ M /branches/3.1/tests/tconst_euler.c
+ M /branches/3.1/tests/tconst_log2.c
+ M /branches/3.1/tests/tconst_pi.c
+ M /branches/3.1/tests/tcopysign.c
+ M /branches/3.1/tests/tcos.c
+ M /branches/3.1/tests/tcosh.c
+ M /branches/3.1/tests/tcot.c
+ M /branches/3.1/tests/tcoth.c
+ M /branches/3.1/tests/tcsc.c
+ M /branches/3.1/tests/tcsch.c
+ M /branches/3.1/tests/td_div.c
+ M /branches/3.1/tests/td_sub.c
+ M /branches/3.1/tests/tdigamma.c
+ M /branches/3.1/tests/tdim.c
+ M /branches/3.1/tests/tdiv.c
+ M /branches/3.1/tests/tdiv_d.c
+ M /branches/3.1/tests/tdiv_ui.c
+ M /branches/3.1/tests/teint.c
+ M /branches/3.1/tests/teq.c
+ M /branches/3.1/tests/terf.c
+ M /branches/3.1/tests/tests.c
+ M /branches/3.1/tests/texceptions.c
+ M /branches/3.1/tests/texp.c
+ M /branches/3.1/tests/texp10.c
+ M /branches/3.1/tests/texp2.c
+ M /branches/3.1/tests/texpm1.c
+ M /branches/3.1/tests/tfactorial.c
+ M /branches/3.1/tests/tfits.c
+ M /branches/3.1/tests/tfma.c
+ M /branches/3.1/tests/tfmod.c
+ M /branches/3.1/tests/tfms.c
+ M /branches/3.1/tests/tfprintf.c
+ M /branches/3.1/tests/tfrac.c
+ M /branches/3.1/tests/tfrexp.c
+ M /branches/3.1/tests/tgamma.c
+ M /branches/3.1/tests/tgeneric.c
+ M /branches/3.1/tests/tgeneric_ui.c
+ M /branches/3.1/tests/tget_d.c
+ M /branches/3.1/tests/tget_d_2exp.c
+ M /branches/3.1/tests/tget_f.c
+ M /branches/3.1/tests/tget_flt.c
+ M /branches/3.1/tests/tget_ld_2exp.c
+ M /branches/3.1/tests/tget_set_d64.c
+ M /branches/3.1/tests/tget_sj.c
+ M /branches/3.1/tests/tget_str.c
+ M /branches/3.1/tests/tget_z.c
+ M /branches/3.1/tests/tgmpop.c
+ M /branches/3.1/tests/tgrandom.c
+ M /branches/3.1/tests/thyperbolic.c
+ M /branches/3.1/tests/thypot.c
+ M /branches/3.1/tests/tinits.c
+ M /branches/3.1/tests/tinp_str.c
+ M /branches/3.1/tests/tinternals.c
+ M /branches/3.1/tests/tisnan.c
+ M /branches/3.1/tests/tisqrt.c
+ M /branches/3.1/tests/tj0.c
+ M /branches/3.1/tests/tj1.c
+ M /branches/3.1/tests/tjn.c
+ M /branches/3.1/tests/tl2b.c
+ M /branches/3.1/tests/tlgamma.c
+ M /branches/3.1/tests/tli2.c
+ M /branches/3.1/tests/tlngamma.c
+ M /branches/3.1/tests/tlog.c
+ M /branches/3.1/tests/tlog10.c
+ M /branches/3.1/tests/tlog1p.c
+ M /branches/3.1/tests/tlog2.c
+ M /branches/3.1/tests/tmin_prec.c
+ M /branches/3.1/tests/tminmax.c
+ M /branches/3.1/tests/tmodf.c
+ M /branches/3.1/tests/tmul.c
+ M /branches/3.1/tests/tmul_2exp.c
+ M /branches/3.1/tests/tmul_d.c
+ M /branches/3.1/tests/tmul_ui.c
+ M /branches/3.1/tests/tnext.c
+ M /branches/3.1/tests/tout_str.c
+ M /branches/3.1/tests/toutimpl.c
+ M /branches/3.1/tests/tpow.c
+ M /branches/3.1/tests/tpow3.c
+ M /branches/3.1/tests/tpow_all.c
+ M /branches/3.1/tests/tpow_z.c
+ M /branches/3.1/tests/tprintf.c
+ M /branches/3.1/tests/trandom.c
+ M /branches/3.1/tests/trec_sqrt.c
+ M /branches/3.1/tests/tremquo.c
+ M /branches/3.1/tests/trint.c
+ M /branches/3.1/tests/troot.c
+ M /branches/3.1/tests/tround_prec.c
+ M /branches/3.1/tests/tsec.c
+ M /branches/3.1/tests/tsech.c
+ M /branches/3.1/tests/tset.c
+ M /branches/3.1/tests/tset_d.c
+ M /branches/3.1/tests/tset_exp.c
+ M /branches/3.1/tests/tset_f.c
+ M /branches/3.1/tests/tset_ld.c
+ M /branches/3.1/tests/tset_q.c
+ M /branches/3.1/tests/tset_si.c
+ M /branches/3.1/tests/tset_sj.c
+ M /branches/3.1/tests/tset_str.c
+ M /branches/3.1/tests/tset_z.c
+ M /branches/3.1/tests/tset_z_exp.c
+ M /branches/3.1/tests/tsgn.c
+ M /branches/3.1/tests/tsi_op.c
+ M /branches/3.1/tests/tsin.c
+ M /branches/3.1/tests/tsin_cos.c
+ M /branches/3.1/tests/tsinh.c
+ M /branches/3.1/tests/tsinh_cosh.c
+ M /branches/3.1/tests/tsprintf.c
+ M /branches/3.1/tests/tsqr.c
+ M /branches/3.1/tests/tsqrt.c
+ M /branches/3.1/tests/tsqrt_ui.c
+ M /branches/3.1/tests/tstckintc.c
+ M /branches/3.1/tests/tstdint.c
+ M /branches/3.1/tests/tstrtofr.c
+ M /branches/3.1/tests/tsub.c
+ M /branches/3.1/tests/tsub1sp.c
+ M /branches/3.1/tests/tsub_d.c
+ M /branches/3.1/tests/tsub_ui.c
+ M /branches/3.1/tests/tsubnormal.c
+ M /branches/3.1/tests/tsum.c
+ M /branches/3.1/tests/tswap.c
+ M /branches/3.1/tests/ttan.c
+ M /branches/3.1/tests/ttanh.c
+ M /branches/3.1/tests/ttrunc.c
+ M /branches/3.1/tests/tui_div.c
+ M /branches/3.1/tests/tui_pow.c
+ M /branches/3.1/tests/tui_sub.c
+ M /branches/3.1/tests/turandom.c
+ M /branches/3.1/tests/tvalist.c
+ M /branches/3.1/tests/tversion.c
+ M /branches/3.1/tests/ty0.c
+ M /branches/3.1/tests/ty1.c
+ M /branches/3.1/tests/tyn.c
+ M /branches/3.1/tests/tzeta.c
+ M /branches/3.1/tests/tzeta_ui.c
+ M /branches/3.1/tools/get_patches.sh
+ M /branches/3.1/tune/bidimensional_sample.c
+ M /branches/3.1/tune/speed.c
+ M /branches/3.1/tune/tuneup.c
+
+Changed Arenaire to AriC with:
+ perl -pi -e 's/Contributed by the Arenaire/Contributed by the AriC/' **/*(^/)
+under zsh, reverting the ChangeLog file.
+------------------------------------------------------------------------
+r7992 | vlefevre | 2012-01-10 12:30:53 +0000 (Tue, 10 Jan 2012) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/FAQ.html
+ M /branches/3.1/doc/faq.xsl
+
+[doc] In faq.xsl, remove only the top-level comments from the HTML file.
+Updated FAQ.html with update-faq.
+------------------------------------------------------------------------
+r7987 | vlefevre | 2012-01-10 11:54:24 +0000 (Tue, 10 Jan 2012) | 5 lines
+Changed paths:
+ M /branches/3.1/BUGS
+ M /branches/3.1/INSTALL
+ M /branches/3.1/Makefile.am
+ M /branches/3.1/NEWS
+ M /branches/3.1/README
+ M /branches/3.1/TODO
+ M /branches/3.1/acinclude.m4
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/FAQ.html
+ M /branches/3.1/doc/Makefile.am
+ M /branches/3.1/doc/README.dev
+ M /branches/3.1/doc/faq.xsl
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/examples/divworst.c
+ M /branches/3.1/examples/rndo-add.c
+ M /branches/3.1/examples/sample.c
+ M /branches/3.1/examples/version.c
+ M /branches/3.1/src/Makefile.am
+ M /branches/3.1/src/abort_prec_max.c
+ M /branches/3.1/src/acos.c
+ M /branches/3.1/src/acosh.c
+ M /branches/3.1/src/add.c
+ M /branches/3.1/src/add1.c
+ M /branches/3.1/src/add1sp.c
+ M /branches/3.1/src/add_d.c
+ M /branches/3.1/src/add_ui.c
+ M /branches/3.1/src/agm.c
+ M /branches/3.1/src/ai.c
+ M /branches/3.1/src/amd/amdfam10/mparam.h
+ M /branches/3.1/src/amd/athlon/mparam.h
+ M /branches/3.1/src/amd/k8/mparam.h
+ M /branches/3.1/src/arm/mparam.h
+ M /branches/3.1/src/asin.c
+ M /branches/3.1/src/asinh.c
+ M /branches/3.1/src/atan.c
+ M /branches/3.1/src/atan2.c
+ M /branches/3.1/src/atanh.c
+ M /branches/3.1/src/bernoulli.c
+ M /branches/3.1/src/buildopt.c
+ M /branches/3.1/src/cache.c
+ M /branches/3.1/src/cbrt.c
+ M /branches/3.1/src/check.c
+ M /branches/3.1/src/clear.c
+ M /branches/3.1/src/clears.c
+ M /branches/3.1/src/cmp.c
+ M /branches/3.1/src/cmp2.c
+ M /branches/3.1/src/cmp_abs.c
+ M /branches/3.1/src/cmp_d.c
+ M /branches/3.1/src/cmp_ld.c
+ M /branches/3.1/src/cmp_si.c
+ M /branches/3.1/src/cmp_ui.c
+ M /branches/3.1/src/comparisons.c
+ M /branches/3.1/src/const_catalan.c
+ M /branches/3.1/src/const_euler.c
+ M /branches/3.1/src/const_log2.c
+ M /branches/3.1/src/const_pi.c
+ M /branches/3.1/src/constant.c
+ M /branches/3.1/src/copysign.c
+ M /branches/3.1/src/cos.c
+ M /branches/3.1/src/cosh.c
+ M /branches/3.1/src/cot.c
+ M /branches/3.1/src/coth.c
+ M /branches/3.1/src/csc.c
+ M /branches/3.1/src/csch.c
+ M /branches/3.1/src/d_div.c
+ M /branches/3.1/src/d_sub.c
+ M /branches/3.1/src/digamma.c
+ M /branches/3.1/src/dim.c
+ M /branches/3.1/src/div.c
+ M /branches/3.1/src/div_2exp.c
+ M /branches/3.1/src/div_2si.c
+ M /branches/3.1/src/div_2ui.c
+ M /branches/3.1/src/div_d.c
+ M /branches/3.1/src/div_ui.c
+ M /branches/3.1/src/dump.c
+ M /branches/3.1/src/eint.c
+ M /branches/3.1/src/eq.c
+ M /branches/3.1/src/erf.c
+ M /branches/3.1/src/erfc.c
+ M /branches/3.1/src/exceptions.c
+ M /branches/3.1/src/exp.c
+ M /branches/3.1/src/exp10.c
+ M /branches/3.1/src/exp2.c
+ M /branches/3.1/src/exp3.c
+ M /branches/3.1/src/exp_2.c
+ M /branches/3.1/src/expm1.c
+ M /branches/3.1/src/extract.c
+ M /branches/3.1/src/factorial.c
+ M /branches/3.1/src/fits_intmax.c
+ M /branches/3.1/src/fits_s.h
+ M /branches/3.1/src/fits_sint.c
+ M /branches/3.1/src/fits_slong.c
+ M /branches/3.1/src/fits_sshort.c
+ M /branches/3.1/src/fits_u.h
+ M /branches/3.1/src/fits_uint.c
+ M /branches/3.1/src/fits_uintmax.c
+ M /branches/3.1/src/fits_ulong.c
+ M /branches/3.1/src/fits_ushort.c
+ M /branches/3.1/src/fma.c
+ M /branches/3.1/src/fms.c
+ M /branches/3.1/src/frac.c
+ M /branches/3.1/src/free_cache.c
+ M /branches/3.1/src/frexp.c
+ M /branches/3.1/src/gamma.c
+ M /branches/3.1/src/gammaonethird.c
+ M /branches/3.1/src/gen_inverse.h
+ M /branches/3.1/src/generic/mparam.h
+ M /branches/3.1/src/get_d.c
+ M /branches/3.1/src/get_d64.c
+ M /branches/3.1/src/get_exp.c
+ M /branches/3.1/src/get_f.c
+ M /branches/3.1/src/get_flt.c
+ M /branches/3.1/src/get_ld.c
+ M /branches/3.1/src/get_si.c
+ M /branches/3.1/src/get_sj.c
+ M /branches/3.1/src/get_str.c
+ M /branches/3.1/src/get_ui.c
+ M /branches/3.1/src/get_uj.c
+ M /branches/3.1/src/get_z.c
+ M /branches/3.1/src/get_z_exp.c
+ M /branches/3.1/src/gmp_op.c
+ M /branches/3.1/src/grandom.c
+ M /branches/3.1/src/hppa/mparam.h
+ M /branches/3.1/src/hypot.c
+ M /branches/3.1/src/ia64/mparam.h
+ M /branches/3.1/src/ieee_floats.h
+ M /branches/3.1/src/init.c
+ M /branches/3.1/src/init2.c
+ M /branches/3.1/src/inits.c
+ M /branches/3.1/src/inits2.c
+ M /branches/3.1/src/inp_str.c
+ M /branches/3.1/src/int_ceil_log2.c
+ M /branches/3.1/src/isinf.c
+ M /branches/3.1/src/isinteger.c
+ M /branches/3.1/src/isnan.c
+ M /branches/3.1/src/isnum.c
+ M /branches/3.1/src/isqrt.c
+ M /branches/3.1/src/isregular.c
+ M /branches/3.1/src/iszero.c
+ M /branches/3.1/src/jn.c
+ M /branches/3.1/src/jyn_asympt.c
+ M /branches/3.1/src/li2.c
+ M /branches/3.1/src/lngamma.c
+ M /branches/3.1/src/log.c
+ M /branches/3.1/src/log10.c
+ M /branches/3.1/src/log1p.c
+ M /branches/3.1/src/log2.c
+ M /branches/3.1/src/logging.c
+ M /branches/3.1/src/min_prec.c
+ M /branches/3.1/src/minmax.c
+ M /branches/3.1/src/modf.c
+ M /branches/3.1/src/mp_clz_tab.c
+ M /branches/3.1/src/mparam_h.in
+ M /branches/3.1/src/mpf2mpfr.h
+ M /branches/3.1/src/mpfr-gmp.c
+ M /branches/3.1/src/mpfr-gmp.h
+ M /branches/3.1/src/mpfr-impl.h
+ M /branches/3.1/src/mpfr-intmax.h
+ M /branches/3.1/src/mpfr-longlong.h
+ M /branches/3.1/src/mpfr-thread.h
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/mpn_exp.c
+ M /branches/3.1/src/mul.c
+ M /branches/3.1/src/mul_2exp.c
+ M /branches/3.1/src/mul_2si.c
+ M /branches/3.1/src/mul_2ui.c
+ M /branches/3.1/src/mul_d.c
+ M /branches/3.1/src/mul_ui.c
+ M /branches/3.1/src/mulders.c
+ M /branches/3.1/src/neg.c
+ M /branches/3.1/src/next.c
+ M /branches/3.1/src/out_raw.c
+ M /branches/3.1/src/out_str.c
+ M /branches/3.1/src/pow.c
+ M /branches/3.1/src/pow_si.c
+ M /branches/3.1/src/pow_ui.c
+ M /branches/3.1/src/pow_z.c
+ M /branches/3.1/src/powerof2.c
+ M /branches/3.1/src/powerpc32/mparam.h
+ M /branches/3.1/src/powerpc64/mparam.h
+ M /branches/3.1/src/print_raw.c
+ M /branches/3.1/src/print_rnd_mode.c
+ M /branches/3.1/src/printf.c
+ M /branches/3.1/src/rec_sqrt.c
+ M /branches/3.1/src/reldiff.c
+ M /branches/3.1/src/rem1.c
+ M /branches/3.1/src/rint.c
+ M /branches/3.1/src/root.c
+ M /branches/3.1/src/round_near_x.c
+ M /branches/3.1/src/round_p.c
+ M /branches/3.1/src/round_prec.c
+ M /branches/3.1/src/round_raw_generic.c
+ M /branches/3.1/src/scale2.c
+ M /branches/3.1/src/sec.c
+ M /branches/3.1/src/sech.c
+ M /branches/3.1/src/set.c
+ M /branches/3.1/src/set_d.c
+ M /branches/3.1/src/set_d64.c
+ M /branches/3.1/src/set_dfl_prec.c
+ M /branches/3.1/src/set_exp.c
+ M /branches/3.1/src/set_f.c
+ M /branches/3.1/src/set_flt.c
+ M /branches/3.1/src/set_inf.c
+ M /branches/3.1/src/set_ld.c
+ M /branches/3.1/src/set_nan.c
+ M /branches/3.1/src/set_prc_raw.c
+ M /branches/3.1/src/set_prec.c
+ M /branches/3.1/src/set_q.c
+ M /branches/3.1/src/set_rnd.c
+ M /branches/3.1/src/set_si.c
+ M /branches/3.1/src/set_si_2exp.c
+ M /branches/3.1/src/set_sj.c
+ M /branches/3.1/src/set_str.c
+ M /branches/3.1/src/set_str_raw.c
+ M /branches/3.1/src/set_ui.c
+ M /branches/3.1/src/set_ui_2exp.c
+ M /branches/3.1/src/set_uj.c
+ M /branches/3.1/src/set_z.c
+ M /branches/3.1/src/set_z_exp.c
+ M /branches/3.1/src/set_zero.c
+ M /branches/3.1/src/setmax.c
+ M /branches/3.1/src/setmin.c
+ M /branches/3.1/src/setsign.c
+ M /branches/3.1/src/sgn.c
+ M /branches/3.1/src/si_op.c
+ M /branches/3.1/src/signbit.c
+ M /branches/3.1/src/sin.c
+ M /branches/3.1/src/sin_cos.c
+ M /branches/3.1/src/sinh.c
+ M /branches/3.1/src/sinh_cosh.c
+ M /branches/3.1/src/sparc64/mparam.h
+ M /branches/3.1/src/sqr.c
+ M /branches/3.1/src/sqrt.c
+ M /branches/3.1/src/sqrt_ui.c
+ M /branches/3.1/src/stack_interface.c
+ M /branches/3.1/src/strtofr.c
+ M /branches/3.1/src/sub.c
+ M /branches/3.1/src/sub1.c
+ M /branches/3.1/src/sub1sp.c
+ M /branches/3.1/src/sub_d.c
+ M /branches/3.1/src/sub_ui.c
+ M /branches/3.1/src/subnormal.c
+ M /branches/3.1/src/sum.c
+ M /branches/3.1/src/swap.c
+ M /branches/3.1/src/tan.c
+ M /branches/3.1/src/tanh.c
+ M /branches/3.1/src/uceil_exp2.c
+ M /branches/3.1/src/uceil_log2.c
+ M /branches/3.1/src/ufloor_log2.c
+ M /branches/3.1/src/ui_div.c
+ M /branches/3.1/src/ui_pow.c
+ M /branches/3.1/src/ui_pow_ui.c
+ M /branches/3.1/src/ui_sub.c
+ M /branches/3.1/src/urandom.c
+ M /branches/3.1/src/urandomb.c
+ M /branches/3.1/src/vasprintf.c
+ M /branches/3.1/src/version.c
+ M /branches/3.1/src/volatile.c
+ M /branches/3.1/src/x86/core2/mparam.h
+ M /branches/3.1/src/x86/mparam.h
+ M /branches/3.1/src/x86_64/core2/mparam.h
+ M /branches/3.1/src/x86_64/pentium4/mparam.h
+ M /branches/3.1/src/yn.c
+ M /branches/3.1/src/zeta.c
+ M /branches/3.1/src/zeta_ui.c
+ M /branches/3.1/tests/Makefile.am
+ M /branches/3.1/tests/cmp_str.c
+ M /branches/3.1/tests/data/digamma
+ M /branches/3.1/tests/data/li2
+ M /branches/3.1/tests/memory.c
+ M /branches/3.1/tests/mpf_compat.c
+ M /branches/3.1/tests/mpf_compat.h
+ M /branches/3.1/tests/mpfr-test.h
+ M /branches/3.1/tests/mpfr_compat.c
+ M /branches/3.1/tests/random2.c
+ M /branches/3.1/tests/reuse.c
+ M /branches/3.1/tests/rnd_mode.c
+ M /branches/3.1/tests/tabs.c
+ M /branches/3.1/tests/tacos.c
+ M /branches/3.1/tests/tacosh.c
+ M /branches/3.1/tests/tadd.c
+ M /branches/3.1/tests/tadd1sp.c
+ M /branches/3.1/tests/tadd_d.c
+ M /branches/3.1/tests/tadd_ui.c
+ M /branches/3.1/tests/tagm.c
+ M /branches/3.1/tests/tai.c
+ M /branches/3.1/tests/tasin.c
+ M /branches/3.1/tests/tasinh.c
+ M /branches/3.1/tests/tatan.c
+ M /branches/3.1/tests/tatanh.c
+ M /branches/3.1/tests/taway.c
+ M /branches/3.1/tests/tbuildopt.c
+ M /branches/3.1/tests/tcan_round.c
+ M /branches/3.1/tests/tcbrt.c
+ M /branches/3.1/tests/tcheck.c
+ M /branches/3.1/tests/tcmp.c
+ M /branches/3.1/tests/tcmp2.c
+ M /branches/3.1/tests/tcmp_d.c
+ M /branches/3.1/tests/tcmp_ld.c
+ M /branches/3.1/tests/tcmp_ui.c
+ M /branches/3.1/tests/tcmpabs.c
+ M /branches/3.1/tests/tcomparisons.c
+ M /branches/3.1/tests/tconst_catalan.c
+ M /branches/3.1/tests/tconst_euler.c
+ M /branches/3.1/tests/tconst_log2.c
+ M /branches/3.1/tests/tconst_pi.c
+ M /branches/3.1/tests/tcopysign.c
+ M /branches/3.1/tests/tcos.c
+ M /branches/3.1/tests/tcosh.c
+ M /branches/3.1/tests/tcot.c
+ M /branches/3.1/tests/tcoth.c
+ M /branches/3.1/tests/tcsc.c
+ M /branches/3.1/tests/tcsch.c
+ M /branches/3.1/tests/td_div.c
+ M /branches/3.1/tests/td_sub.c
+ M /branches/3.1/tests/tdigamma.c
+ M /branches/3.1/tests/tdim.c
+ M /branches/3.1/tests/tdiv.c
+ M /branches/3.1/tests/tdiv_d.c
+ M /branches/3.1/tests/tdiv_ui.c
+ M /branches/3.1/tests/teint.c
+ M /branches/3.1/tests/teq.c
+ M /branches/3.1/tests/terf.c
+ M /branches/3.1/tests/tests.c
+ M /branches/3.1/tests/texceptions.c
+ M /branches/3.1/tests/texp.c
+ M /branches/3.1/tests/texp10.c
+ M /branches/3.1/tests/texp2.c
+ M /branches/3.1/tests/texpm1.c
+ M /branches/3.1/tests/tfactorial.c
+ M /branches/3.1/tests/tfits.c
+ M /branches/3.1/tests/tfma.c
+ M /branches/3.1/tests/tfmod.c
+ M /branches/3.1/tests/tfms.c
+ M /branches/3.1/tests/tfprintf.c
+ M /branches/3.1/tests/tfrac.c
+ M /branches/3.1/tests/tfrexp.c
+ M /branches/3.1/tests/tgamma.c
+ M /branches/3.1/tests/tgeneric.c
+ M /branches/3.1/tests/tgeneric_ui.c
+ M /branches/3.1/tests/tget_d.c
+ M /branches/3.1/tests/tget_d_2exp.c
+ M /branches/3.1/tests/tget_f.c
+ M /branches/3.1/tests/tget_flt.c
+ M /branches/3.1/tests/tget_ld_2exp.c
+ M /branches/3.1/tests/tget_set_d64.c
+ M /branches/3.1/tests/tget_sj.c
+ M /branches/3.1/tests/tget_str.c
+ M /branches/3.1/tests/tget_z.c
+ M /branches/3.1/tests/tgmpop.c
+ M /branches/3.1/tests/tgrandom.c
+ M /branches/3.1/tests/thyperbolic.c
+ M /branches/3.1/tests/thypot.c
+ M /branches/3.1/tests/tinits.c
+ M /branches/3.1/tests/tinp_str.c
+ M /branches/3.1/tests/tinternals.c
+ M /branches/3.1/tests/tisnan.c
+ M /branches/3.1/tests/tisqrt.c
+ M /branches/3.1/tests/tj0.c
+ M /branches/3.1/tests/tj1.c
+ M /branches/3.1/tests/tjn.c
+ M /branches/3.1/tests/tl2b.c
+ M /branches/3.1/tests/tlgamma.c
+ M /branches/3.1/tests/tli2.c
+ M /branches/3.1/tests/tlngamma.c
+ M /branches/3.1/tests/tlog.c
+ M /branches/3.1/tests/tlog10.c
+ M /branches/3.1/tests/tlog1p.c
+ M /branches/3.1/tests/tlog2.c
+ M /branches/3.1/tests/tmin_prec.c
+ M /branches/3.1/tests/tminmax.c
+ M /branches/3.1/tests/tmodf.c
+ M /branches/3.1/tests/tmul.c
+ M /branches/3.1/tests/tmul_2exp.c
+ M /branches/3.1/tests/tmul_d.c
+ M /branches/3.1/tests/tmul_ui.c
+ M /branches/3.1/tests/tnext.c
+ M /branches/3.1/tests/tout_str.c
+ M /branches/3.1/tests/toutimpl.c
+ M /branches/3.1/tests/tpow.c
+ M /branches/3.1/tests/tpow3.c
+ M /branches/3.1/tests/tpow_all.c
+ M /branches/3.1/tests/tpow_z.c
+ M /branches/3.1/tests/tprintf.c
+ M /branches/3.1/tests/trandom.c
+ M /branches/3.1/tests/trec_sqrt.c
+ M /branches/3.1/tests/tremquo.c
+ M /branches/3.1/tests/trint.c
+ M /branches/3.1/tests/troot.c
+ M /branches/3.1/tests/tround_prec.c
+ M /branches/3.1/tests/tsec.c
+ M /branches/3.1/tests/tsech.c
+ M /branches/3.1/tests/tset.c
+ M /branches/3.1/tests/tset_d.c
+ M /branches/3.1/tests/tset_exp.c
+ M /branches/3.1/tests/tset_f.c
+ M /branches/3.1/tests/tset_ld.c
+ M /branches/3.1/tests/tset_q.c
+ M /branches/3.1/tests/tset_si.c
+ M /branches/3.1/tests/tset_sj.c
+ M /branches/3.1/tests/tset_str.c
+ M /branches/3.1/tests/tset_z.c
+ M /branches/3.1/tests/tset_z_exp.c
+ M /branches/3.1/tests/tsgn.c
+ M /branches/3.1/tests/tsi_op.c
+ M /branches/3.1/tests/tsin.c
+ M /branches/3.1/tests/tsin_cos.c
+ M /branches/3.1/tests/tsinh.c
+ M /branches/3.1/tests/tsinh_cosh.c
+ M /branches/3.1/tests/tsprintf.c
+ M /branches/3.1/tests/tsqr.c
+ M /branches/3.1/tests/tsqrt.c
+ M /branches/3.1/tests/tsqrt_ui.c
+ M /branches/3.1/tests/tstckintc.c
+ M /branches/3.1/tests/tstdint.c
+ M /branches/3.1/tests/tstrtofr.c
+ M /branches/3.1/tests/tsub.c
+ M /branches/3.1/tests/tsub1sp.c
+ M /branches/3.1/tests/tsub_d.c
+ M /branches/3.1/tests/tsub_ui.c
+ M /branches/3.1/tests/tsubnormal.c
+ M /branches/3.1/tests/tsum.c
+ M /branches/3.1/tests/tswap.c
+ M /branches/3.1/tests/ttan.c
+ M /branches/3.1/tests/ttanh.c
+ M /branches/3.1/tests/ttrunc.c
+ M /branches/3.1/tests/tui_div.c
+ M /branches/3.1/tests/tui_pow.c
+ M /branches/3.1/tests/tui_sub.c
+ M /branches/3.1/tests/turandom.c
+ M /branches/3.1/tests/tvalist.c
+ M /branches/3.1/tests/tversion.c
+ M /branches/3.1/tests/ty0.c
+ M /branches/3.1/tests/ty1.c
+ M /branches/3.1/tests/tyn.c
+ M /branches/3.1/tests/tzeta.c
+ M /branches/3.1/tests/tzeta_ui.c
+ M /branches/3.1/tools/ck-copyright-notice
+ M /branches/3.1/tools/ck-mparam
+ M /branches/3.1/tools/ck-version-info
+ M /branches/3.1/tools/get_patches.sh
+ M /branches/3.1/tune/Makefile.am
+ M /branches/3.1/tune/bidimensional_sample.c
+ M /branches/3.1/tune/speed.c
+ M /branches/3.1/tune/tuneup.c
+
+Copyright notice update: added 2012 with
+ perl -pi -e 's/2011 Free Software/2011, 2012 Free Software/' **/*(^/)
+under zsh, reverting the ChangeLog file (the m4 and tools/mbench
+directories were not modified).
+Removed 2011 from the example in the doc/README.dev file.
+------------------------------------------------------------------------
+r7980 | vlefevre | 2011-12-09 13:43:03 +0000 (Fri, 09 Dec 2011) | 4 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/INSTALL
+ M /branches/3.1/configure.ac
+
+Merged changesets r7976-7978 from the trunk:
+[INSTALL] Added information about system/compiler bugs related to TLS
+ or optimizations.
+[configure.ac] Mention --disable-thread-safe.
+------------------------------------------------------------------------
+r7972 | vlefevre | 2011-11-28 12:20:46 +0000 (Mon, 28 Nov 2011) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/turandom.c
+
+[tests/turandom.c] Removed an obsolete comment.
+------------------------------------------------------------------------
+r7969 | vlefevre | 2011-11-28 11:36:10 +0000 (Mon, 28 Nov 2011) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7968 | vlefevre | 2011-11-28 11:34:34 +0000 (Mon, 28 Nov 2011) | 5 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/tests/trandom.c
+ M /branches/3.1/tests/turandom.c
+
+Merged changesets r7965-7966 from the trunk:
+[doc/mpfr.texi] Mentioned the difference between GMP 4.1 and 4.2 about
+the changes of mpfr_urandom and mpfr_urandomb in MPFR 3.1.
+[tests/trandom.c,tests/turandom.c] Fixed compatibility with GMP 4.1.x
+(since the default PRNG has changed between GMP 4.1 and 4.2).
+------------------------------------------------------------------------
+r7945 | vlefevre | 2011-11-03 16:11:08 +0000 (Thu, 03 Nov 2011) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/vasprintf.c
+
+[src/vasprintf.c] Corrected a comment.
+------------------------------------------------------------------------
+r7942 | vlefevre | 2011-11-03 14:49:58 +0000 (Thu, 03 Nov 2011) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/tests/tsprintf.c
+
+[tests/tsprintf.c] Coding style.
+------------------------------------------------------------------------
+r7940 | vlefevre | 2011-11-03 14:10:49 +0000 (Thu, 03 Nov 2011) | 3 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/vasprintf.c
+ M /branches/3.1/tests/tsprintf.c
+
+[src/vasprintf.c] Fixed bug reported by Pavel Holoborodko.
+[tests/tsprintf.c] Added testcases.
+(Merged changesets r7931 (except src/mpn_exp.c) and r7933-7936.)
+------------------------------------------------------------------------
+r7921 | vlefevre | 2011-10-14 10:18:30 +0000 (Fri, 14 Oct 2011) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/INSTALL
+ M /branches/3.1/tests/Makefile.am
+
+[tests/Makefile.am] Added -L$(top_builddir)/src/.libs to AM_LDFLAGS.
+[INSTALL] Removed the notes on HP-UX (obsolete after the above change).
+------------------------------------------------------------------------
+r7919 | vlefevre | 2011-10-13 11:30:54 +0000 (Thu, 13 Oct 2011) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/INSTALL
+
+[INSTALL] Corrected notes for HP-UX.
+------------------------------------------------------------------------
+r7917 | vlefevre | 2011-10-13 11:20:23 +0000 (Thu, 13 Oct 2011) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/INSTALL
+
+[INSTALL] Added notes for HP-UX after a bug report. See discussion:
+https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00042.html
+------------------------------------------------------------------------
+r7908 | vlefevre | 2011-10-04 11:14:48 +0000 (Tue, 04 Oct 2011) | 3 lines
+Changed paths:
+ M /branches/3.1/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Fixed a bug in the MPFR_UNLIKELY macro for GCC
+(found under Mac OS X / PowerPC with the mode32 GMP ABI, and MPFR
+built with --enable-assert=full).
+------------------------------------------------------------------------
+r7907 | vlefevre | 2011-10-04 10:04:11 +0000 (Tue, 04 Oct 2011) | 1 line
+Changed paths:
+ M /branches/3.1/INSTALL
+ M /branches/3.1/VERSION
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/version.c
+
+Updated version to 3.1.1-dev.
+------------------------------------------------------------------------
+r7897 | vlefevre | 2011-10-03 08:16:03 +0000 (Mon, 03 Oct 2011) | 1 line
+Changed paths:
+ M /branches/3.1/ChangeLog
+
+ChangeLog update with "TZ=UTC svn log -rHEAD:0 -v" (in UTF-8 locales).
+------------------------------------------------------------------------
+r7896 | vlefevre | 2011-10-03 08:10:45 +0000 (Mon, 03 Oct 2011) | 1 line
+Changed paths:
+ M /branches/3.1/VERSION
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/version.c
+
+Updated version to 3.1.0.
+------------------------------------------------------------------------
+r7895 | vlefevre | 2011-10-03 08:09:19 +0000 (Mon, 03 Oct 2011) | 1 line
+Changed paths:
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7893 | vlefevre | 2011-09-29 22:25:41 +0000 (Thu, 29 Sep 2011) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] added reference and comment for eint
+(Merged changeset r7892 from the trunk.)
+------------------------------------------------------------------------
+r7890 | vlefevre | 2011-09-25 00:17:05 +0000 (Sun, 25 Sep 2011) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Rephrased mpfr_frexp description.
+(Merged changeset r7889 from the trunk.)
+------------------------------------------------------------------------
+r7887 | vlefevre | 2011-09-24 10:01:07 +0000 (Sat, 24 Sep 2011) | 5 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/NEWS
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/log1p.c
+ M /branches/3.1/tests/tagm.c
+ M /branches/3.1/tests/tgeneric.c
+
+Renamed "division-by-zero" to "divide-by-zero" (term used by the
+ISO C99 standard, the IEEE 754-2008 standard using divideByZero,
+and the old IEEE 754-1985 standard using both "divide by zero"
+and "division by zero").
+(Merged changeset r7886 from the trunk.)
+------------------------------------------------------------------------
+r7885 | vlefevre | 2011-09-24 09:40:03 +0000 (Sat, 24 Sep 2011) | 3 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/gmp_op.c
+ M /branches/3.1/tests/tgmpop.c
+
+[tests/tgmpop.c] Improved division-by-zero tests.
+[src/gmp_op.c] Forgot to update the flags in some functions.
+(Merged changesets r7882 and r7883 from the trunk.)
+------------------------------------------------------------------------
+r7884 | vlefevre | 2011-09-24 09:39:02 +0000 (Sat, 24 Sep 2011) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/faq.xsl
+
+[doc/faq.xsl] Added a comment about the MPFR logo.
+(Merged changeset r7881 from the trunk.)
+------------------------------------------------------------------------
+r7880 | vlefevre | 2011-09-22 10:38:10 +0000 (Thu, 22 Sep 2011) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Improved mpfr_frexp description.
+------------------------------------------------------------------------
+r7878 | vlefevre | 2011-09-22 10:09:40 +0000 (Thu, 22 Sep 2011) | 1 line
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Corrected typo in the mpfr_frexp description.
+------------------------------------------------------------------------
+r7874 | vlefevre | 2011-09-20 08:50:37 +0000 (Tue, 20 Sep 2011) | 1 line
+Changed paths:
+ M /branches/3.1/ChangeLog
+
+ChangeLog update with "TZ=UTC svn log -rHEAD:0 -v" (in UTF-8 locales).
+------------------------------------------------------------------------
+r7872 | vlefevre | 2011-09-20 07:37:01 +0000 (Tue, 20 Sep 2011) | 1 line
+Changed paths:
+ M /branches/3.1/VERSION
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/version.c
+
+Updated version to 3.1.0-rc2.
+------------------------------------------------------------------------
+r7871 | vlefevre | 2011-09-20 07:35:18 +0000 (Tue, 20 Sep 2011) | 18 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/NEWS
+ M /branches/3.1/TODO
+ M /branches/3.1/doc/README.dev
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/examples/version.c
+ M /branches/3.1/src/agm.c
+ M /branches/3.1/src/buildopt.c
+ M /branches/3.1/src/gmp_op.c
+ M /branches/3.1/src/mpfr-gmp.h
+ M /branches/3.1/src/mpfr-impl.h
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/tests/tbuildopt.c
+ M /branches/3.1/tests/tgmpop.c
+
+Merged r7857 through r7870 from the trunk:
+ * [src/mpfr-gmp.h] Fixed a prototype (mpfr_limb_ptr isn't available
+ yet) and added missing prototype for __gmpn_sbpi1_divappr_q.
+ * [src/mpfr-impl.h] Define new macros MPFR_EXT_EMIN and MPFR_EXT_EMAX.
+ * [src/agm.c] Replaced __gmpfr_emin and __gmpfr_emax by MPFR_EXT_EMIN
+ and MPFR_EXT_EMAX respectively (this should be a bit faster with TLS
+ and also is a workaround to a bug occurring with TLS and GCC 4.3.2
+ on a Linux/Sparc machine, gcc54.fsffrance.org).
+ * [tests/tgmpop.c] Check for erange flag in mpfr_cmp_[f,q,z].
+ * [src/gmp_op.c] Handle the special cases in mpfr_cmp_q and mpfr_cmp_f
+ (fixing the problem with the erange flag in particular).
+ * [src/buildopt.c,src/mpfr.h,tests/tbuildopt.c,doc/mpfr.texi,NEWS]
+ Added mpfr_buildopt_gmpinternals_p function.
+ * [examples/version.c] Output mpfr_buildopt_gmpinternals_p() and
+ mpfr_buildopt_tune_case() values with MPFR 3.1 or later.
+ * [doc/README.dev] Updated "To make a release". Document how to
+ specify the minimum exponent or the maximum exponent.
+ * [TODO] Added an item about the minimum and maximum exponents.
+------------------------------------------------------------------------
+r7857 | vlefevre | 2011-09-19 08:22:17 +0000 (Mon, 19 Sep 2011) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Correction: "5 exception types" → "6 exception types"
+(thanks to Case Vanhorsen for the report).
+------------------------------------------------------------------------
+r7854 | vlefevre | 2011-09-17 11:58:18 +0000 (Sat, 17 Sep 2011) | 1 line
+Changed paths:
+ M /branches/3.1/ChangeLog
+
+ChangeLog update with "TZ=UTC svn log -rHEAD:0 -v" (in UTF-8 locales).
+------------------------------------------------------------------------
+r7853 | vlefevre | 2011-09-14 21:38:49 +0000 (Wed, 14 Sep 2011) | 4 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Define LONGLONG_STANDALONE before including
+mpfr-longlong.h so that udiv_qrnnd_preinv is defined (this is
+useful at least on IA64 when compiling without gmp-impl.h).
+Thanks to Patrick Pélissier for the fix.
+------------------------------------------------------------------------
+r7851 | vlefevre | 2011-09-11 09:21:52 +0000 (Sun, 11 Sep 2011) | 3 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/NEWS
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated "API Compatibility" section. Documented
+ function mpfr_buildopt_tune_case. Minor consistency changes.
+[NEWS] Function mpfr_buildopt_tune_case is new in MPFR 3.1.
+------------------------------------------------------------------------
+r7844 | vlefevre | 2011-09-11 07:49:03 +0000 (Sun, 11 Sep 2011) | 2 lines
+Changed paths:
+ M /branches/3.1
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] MPFR_RNDA was introduced in MPFR 3.0.0 and should
+no longer be considered experimental.
+------------------------------------------------------------------------
+r7842 | vlefevre | 2011-09-10 21:25:45 +0000 (Sat, 10 Sep 2011) | 1 line
+Changed paths:
+ M /branches/3.1/ChangeLog
+
+ChangeLog update with "TZ=UTC svn log -rHEAD:0 -v" (in UTF-8 locales).
+------------------------------------------------------------------------
+r7841 | vlefevre | 2011-09-10 21:24:05 +0000 (Sat, 10 Sep 2011) | 1 line
+Changed paths:
+ M /branches/3.1/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7840 | vlefevre | 2011-09-10 21:23:08 +0000 (Sat, 10 Sep 2011) | 1 line
+Changed paths:
+ M /branches/3.1/INSTALL
+ M /branches/3.1/VERSION
+ M /branches/3.1/configure.ac
+ M /branches/3.1/doc/mpfr.texi
+ M /branches/3.1/src/mpfr.h
+ M /branches/3.1/src/version.c
+
+Updated version to 3.1.0-rc1.
+------------------------------------------------------------------------
+r7839 | vlefevre | 2011-09-10 21:21:59 +0000 (Sat, 10 Sep 2011) | 1 line
+Changed paths:
+ A /branches/3.1 (from /trunk:7838)
+
+Recreated 3.1 branch from the trunk.
+------------------------------------------------------------------------
+r7836 | vlefevre | 2011-09-10 21:15:45 +0000 (Sat, 10 Sep 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/trec_sqrt.c
+
+[tests/trec_sqrt.c] Fixed bug introduced in r7711 (build failure
+with a C++ compiler).
+------------------------------------------------------------------------
+r7835 | vlefevre | 2011-09-10 20:13:19 +0000 (Sat, 10 Sep 2011) | 1 line
+Changed paths:
+ M /trunk
+ M /trunk/NEWS
+ M /trunk/doc/mpfr.texi
+
+Removed now useless svn:mergeinfo properties.
+------------------------------------------------------------------------
+r7832 | vlefevre | 2011-09-10 20:04:07 +0000 (Sat, 10 Sep 2011) | 1 line
+Changed paths:
+ M /trunk/TODO
+
+[TODO] Replaced "configure.in" by "configure.ac".
+------------------------------------------------------------------------
+r7831 | vlefevre | 2011-09-10 20:02:56 +0000 (Sat, 10 Sep 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Removed obsolete paragraph about AM_MAINTAINER_MODE.
+------------------------------------------------------------------------
+r7826 | vlefevre | 2011-09-10 19:08:42 +0000 (Sat, 10 Sep 2011) | 1 line
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Correction after r7825.
+------------------------------------------------------------------------
+r7825 | vlefevre | 2011-09-10 19:07:39 +0000 (Sat, 10 Sep 2011) | 1 line
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Run tools/ck-mparam.
+------------------------------------------------------------------------
+r7824 | vlefevre | 2011-09-10 19:04:57 +0000 (Sat, 10 Sep 2011) | 2 lines
+Changed paths:
+ A /trunk/tools/ck-mparam
+
+Added tools/ck-mparam sh script to check the mparam.h files
+(gcc is needed).
+------------------------------------------------------------------------
+r7823 | zimmerma | 2011-09-10 07:15:46 +0000 (Sat, 10 Sep 2011) | 2 lines
+Changed paths:
+ M /trunk/src/amd/k8/mparam.h
+
+[src/amd/k8/mparam.h] removed spurious end of comment
+
+------------------------------------------------------------------------
+r7821 | vlefevre | 2011-09-09 17:19:39 +0000 (Fri, 09 Sep 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] For the valgrind example, use the same arguments
+as in gnulib's valgrind-tests.m4 file.
+------------------------------------------------------------------------
+r7818 | vlefevre | 2011-09-09 13:48:33 +0000 (Fri, 09 Sep 2011) | 1 line
+Changed paths:
+ M /trunk/ChangeLog
+
+ChangeLog update with "LC_ALL=en_US.UTF8 TZ=UTC svn log -rHEAD:0 -v".
+------------------------------------------------------------------------
+r7817 | vlefevre | 2011-09-09 13:32:55 +0000 (Fri, 09 Sep 2011) | 5 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/tools/ck-copyright-notice
+
+[Makefile.am] Added tools/ck-copyright-notice to EXTRA_DIST as it is
+ used in dist-hook.
+[tools/ck-copyright-notice] Added copyright notice (since this file is
+ distributed in the tarballs). Note: the first year is 2008 as a part
+ of the code comes from r5370 in mpfrlint.
+------------------------------------------------------------------------
+r7816 | vlefevre | 2011-09-09 11:40:33 +0000 (Fri, 09 Sep 2011) | 2 lines
+Changed paths:
+ M /trunk/tools/ck-copyright-notice
+
+[tools/ck-copyright-notice] Skip src/mpfr-longlong.h as this file
+(which comes from GMP) has a specific copyright notice.
+------------------------------------------------------------------------
+r7815 | vlefevre | 2011-09-09 11:37:01 +0000 (Fri, 09 Sep 2011) | 1 line
+Changed paths:
+ M /trunk/src/mp_clz_tab.c
+
+[src/mp_clz_tab.c] Updated the copyright notice.
+------------------------------------------------------------------------
+r7814 | vlefevre | 2011-09-09 11:31:07 +0000 (Fri, 09 Sep 2011) | 2 lines
+Changed paths:
+ M /trunk/tools/ck-copyright-notice
+
+[tools/ck-copyright-notice] Check that the first copyright year for
+the mparam.h files is 2005.
+------------------------------------------------------------------------
+r7813 | vlefevre | 2011-09-09 11:26:02 +0000 (Fri, 09 Sep 2011) | 2 lines
+Changed paths:
+ M /trunk/src/amd/amdfam10/mparam.h
+ M /trunk/src/amd/athlon/mparam.h
+ M /trunk/src/amd/k8/mparam.h
+ M /trunk/src/arm/mparam.h
+ M /trunk/src/generic/mparam.h
+ M /trunk/src/hppa/mparam.h
+ M /trunk/src/ia64/mparam.h
+ M /trunk/src/powerpc32/mparam.h
+ M /trunk/src/powerpc64/mparam.h
+ M /trunk/src/sparc64/mparam.h
+ M /trunk/src/x86/core2/mparam.h
+ M /trunk/src/x86/mparam.h
+ M /trunk/src/x86_64/core2/mparam.h
+ M /trunk/src/x86_64/pentium4/mparam.h
+
+Added copyright notice to the mparam.h files (with the same years
+as in the template).
+------------------------------------------------------------------------
+r7812 | vlefevre | 2011-09-09 11:20:25 +0000 (Fri, 09 Sep 2011) | 5 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/tools/ck-copyright-notice
+ M /trunk/tools/mpfrlint
+
+Added tools/ck-copyright-notice sh script from mpfrlint (updated) to
+check that copyright notices exist and appear to be correct. Updated
+tools/mpfrlint to run tools/ck-copyright-notice instead of its old
+test. In Makefile.am, run tools/ck-copyright-notice in dist-hook for
+"make dist".
+------------------------------------------------------------------------
+r7811 | vlefevre | 2011-09-09 10:57:23 +0000 (Fri, 09 Sep 2011) | 1 line
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] More files under src and tests directories.
+------------------------------------------------------------------------
+r7809 | vlefevre | 2011-09-08 09:13:50 +0000 (Thu, 08 Sep 2011) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Update for MPFR 3.1.x.
+------------------------------------------------------------------------
+r7808 | vlefevre | 2011-09-08 09:07:08 +0000 (Thu, 08 Sep 2011) | 7 lines
+Changed paths:
+ M /trunk/doc/README.dev
+ M /trunk/tests/Makefile.am
+
+[tests/Makefile.am]
+ * Added "AM_LDFLAGS = -no-install" to prevent libtool from generating
+ wrapper scripts for the tests (according to discussions and tests,
+ there should be no negative effects); useful for gdb and valgrind.
+ * Added $(VALGRIND) to TESTS_ENVIRONMENT in order to easily run the
+ tests under valgrind with: VALGRIND="valgrind -q" make check
+[doc/README.dev] Update for gdb and valgrind.
+------------------------------------------------------------------------
+r7807 | vlefevre | 2011-08-31 08:55:56 +0000 (Wed, 31 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Improved the specification of mpfr_get_f.
+------------------------------------------------------------------------
+r7805 | zimmerma | 2011-08-30 12:01:16 +0000 (Tue, 30 Aug 2011) | 2 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] added comment about minimal GMP version
+
+------------------------------------------------------------------------
+r7804 | zimmerma | 2011-08-30 08:23:16 +0000 (Tue, 30 Aug 2011) | 3 lines
+Changed paths:
+ M /trunk/src/add.c
+
+dummy change to check if GMP_CHECK_RANDOMIZE is now used in the Hydra
+builds on http://hydra.nixos.org/jobset/gnu/mpfr-trunk
+
+------------------------------------------------------------------------
+r7803 | vlefevre | 2011-08-19 10:03:19 +0000 (Fri, 19 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Added some references to the ternary definition.
+------------------------------------------------------------------------
+r7802 | zimmerma | 2011-08-19 09:01:58 +0000 (Fri, 19 Aug 2011) | 3 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] improved the documentation of mpfr_set_str, as suggested by
+ Vincent Lefevre
+
+------------------------------------------------------------------------
+r7801 | vlefevre | 2011-08-19 08:45:07 +0000 (Fri, 19 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Added "Ternary value" to the concept index.
+------------------------------------------------------------------------
+r7800 | vlefevre | 2011-08-15 12:34:40 +0000 (Mon, 15 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added information on how to update the FAQ.
+------------------------------------------------------------------------
+r7798 | vlefevre | 2011-08-15 11:55:59 +0000 (Mon, 15 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/doc/FAQ.html
+
+[doc] Updated FAQ.html with update-faq.
+------------------------------------------------------------------------
+r7796 | vlefevre | 2011-08-12 11:39:06 +0000 (Fri, 12 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+[tune/tuneup.c] Untabified.
+------------------------------------------------------------------------
+r7795 | vlefevre | 2011-08-12 11:35:51 +0000 (Fri, 12 Aug 2011) | 3 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[src/mulders.c] Replaced MPFR_ASSERTD by MPFR_ASSERTN on constant
+expressions (this is a temporary change, as they should later be
+replaced by static assertions).
+------------------------------------------------------------------------
+r7794 | vlefevre | 2011-08-12 11:33:09 +0000 (Fri, 12 Aug 2011) | 2 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[src/mulders.c] Replaced mp_ptr and mp_srcptr (internal to GMP) by
+mpfr_limb_ptr and mpfr_limb_srcptr.
+------------------------------------------------------------------------
+r7793 | vlefevre | 2011-08-12 11:25:25 +0000 (Fri, 12 Aug 2011) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr-gmp.h
+
+[src/mpfr-gmp.h] Avoid potential identifier collision by using an
+underscore for variable names declared in the invert_pi1 macro.
+------------------------------------------------------------------------
+r7792 | vlefevre | 2011-08-12 11:18:12 +0000 (Fri, 12 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-gmp.h
+
+[src/mpfr-gmp.h] Untabified.
+------------------------------------------------------------------------
+r7791 | vlefevre | 2011-08-12 11:14:38 +0000 (Fri, 12 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7790 | zimmerma | 2011-08-06 13:30:28 +0000 (Sat, 06 Aug 2011) | 2 lines
+Changed paths:
+ M /trunk/src/amd/k8/mparam.h
+
+[k8/mparam.h] added comment
+
+------------------------------------------------------------------------
+r7789 | zimmerma | 2011-08-06 12:01:58 +0000 (Sat, 06 Aug 2011) | 3 lines
+Changed paths:
+ M /trunk/src/amd/amdfam10/mparam.h
+ M /trunk/src/x86/mparam.h
+
+[x86/mparam.h] new tuning contributed by Jim Cloos
+[amd/amdfam10/mparam.h] added GMP version
+
+------------------------------------------------------------------------
+r7788 | zimmerma | 2011-08-06 11:52:12 +0000 (Sat, 06 Aug 2011) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr-gmp.h
+ M /trunk/src/mulders.c
+
+[mpfr-gmp.h] use mpfr_pi1_t instead of gmp_pi1_t to avoid using GMP's namespace
+
+------------------------------------------------------------------------
+r7787 | zimmerma | 2011-08-05 14:22:26 +0000 (Fri, 05 Aug 2011) | 5 lines
+Changed paths:
+ M /trunk/configure.ac
+ M /trunk/src/mparam_h.in
+ M /trunk/src/mpfr-gmp.h
+ M /trunk/src/mulders.c
+ M /trunk/tune/tuneup.c
+
+[src/mulders.c] use mpn_sbpi1_divappr_q if available and WANT_GMP_INTERNALS
+ is defined
+[src/mpfr-gmp.h] defined macros needed for mpfr_divhigh_n_basecase
+[configure.ac] check for mpn_sbpi1_divappr_q
+
+------------------------------------------------------------------------
+r7786 | vlefevre | 2011-08-05 13:17:23 +0000 (Fri, 05 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/VERSION
+ M /trunk/configure.ac
+ M /trunk/doc/mpfr.texi
+ M /trunk/src/mpfr.h
+ M /trunk/src/version.c
+
+Updated version to 3.2.0-dev.
+------------------------------------------------------------------------
+r7784 | zimmerma | 2011-08-05 12:56:08 +0000 (Fri, 05 Aug 2011) | 2 lines
+Changed paths:
+ A /trunk/src/amd/amdfam10
+ A /trunk/src/amd/amdfam10/mparam.h
+
+[amdfam10/mparam.h] tuning parameters contributed by Jim Cloos
+
+------------------------------------------------------------------------
+r7783 | zimmerma | 2011-08-05 03:08:42 +0000 (Fri, 05 Aug 2011) | 4 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/src/Makefile.am
+ M /trunk/src/mulders.c
+ M /trunk/tune/tuneup.c
+
+[mulders.c] added a basecase code for Mulders' short division
+[tuneup.c] added corresponding tuning code
+[TODO] added an item
+
+------------------------------------------------------------------------
+r7782 | vlefevre | 2011-08-04 14:36:42 +0000 (Thu, 04 Aug 2011) | 4 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] In the INTMAX_MAX test, no longer hardcode the
+"#include <stdint.h>" (for instance, this doesn't work under
+Solaris 9: INTMAX_MAX is defined only via <inttypes.h>), but
+include "mpfr-intmax.h" instead (needs a temporary CPPFLAGS).
+------------------------------------------------------------------------
+r7781 | vlefevre | 2011-08-01 14:39:08 +0000 (Mon, 01 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Much faster formatted output (mpfr_printf, etc.) with %Rg and similar.
+------------------------------------------------------------------------
+r7780 | vlefevre | 2011-08-01 13:56:27 +0000 (Mon, 01 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added copyright notice in case the file is distributed.
+------------------------------------------------------------------------
+r7779 | vlefevre | 2011-08-01 13:50:17 +0000 (Mon, 01 Aug 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added information on how to run the MPFR test suite
+under valgrind.
+------------------------------------------------------------------------
+r7778 | vlefevre | 2011-08-01 12:36:04 +0000 (Mon, 01 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/src/div.c
+ M /trunk/src/rec_sqrt.c
+ M /trunk/tests/trec_sqrt.c
+
+Untabified and removed trailing spaces.
+------------------------------------------------------------------------
+r7777 | vlefevre | 2011-08-01 12:13:50 +0000 (Mon, 01 Aug 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tversion.c
+
+[tests/tversion.c] Improved output information.
+------------------------------------------------------------------------
+r7776 | zimmerma | 2011-07-31 19:44:32 +0000 (Sun, 31 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/src/hppa/mparam.h
+
+[hppa/mparam.h] updated for new Mulders' division
+
+------------------------------------------------------------------------
+r7775 | zimmerma | 2011-07-31 19:40:23 +0000 (Sun, 31 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/src/sparc64/mparam.h
+
+[sparc64/mparam.h] updated for new Mulders' division
+
+------------------------------------------------------------------------
+r7774 | zimmerma | 2011-07-31 15:43:40 +0000 (Sun, 31 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/src/powerpc64/mparam.h
+
+[powerpc64/mparam.h] updated for new Mulders' division
+
+------------------------------------------------------------------------
+r7773 | zimmerma | 2011-07-31 15:08:43 +0000 (Sun, 31 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/src/ia64/mparam.h
+
+[ia64/mparam.h] updated for new Mulders' division
+
+------------------------------------------------------------------------
+r7772 | zimmerma | 2011-07-31 12:43:03 +0000 (Sun, 31 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/src/amd/k8/mparam.h
+
+[amd/k8/mparam.h] updated for new Mulders' division
+
+------------------------------------------------------------------------
+r7771 | zimmerma | 2011-07-31 12:39:57 +0000 (Sun, 31 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/src/x86/core2/mparam.h
+
+[x86/core2/mparam.h] updated thresholds for new Mulders' division
+
+------------------------------------------------------------------------
+r7770 | zimmerma | 2011-07-31 10:54:38 +0000 (Sun, 31 Jul 2011) | 5 lines
+Changed paths:
+ M /trunk/src/mparam_h.in
+ M /trunk/tests/tversion.c
+
+[mparam_h.in] changed the detection of 64-bit Core 2, and added
+ MPFR_TUNE_CASE for default case
+[tversion.c] print GMP version (header and library), and file for tuning
+ parameters
+
+------------------------------------------------------------------------
+r7769 | zimmerma | 2011-07-31 10:29:31 +0000 (Sun, 31 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/src/x86_64/core2/mparam.h
+
+[x86_64/core2/mparam.h] updated for Mulders' division
+
+------------------------------------------------------------------------
+r7768 | zimmerma | 2011-07-31 08:59:53 +0000 (Sun, 31 Jul 2011) | 3 lines
+Changed paths:
+ M /trunk/src/div.c
+ M /trunk/src/generic/mparam.h
+ M /trunk/tune/tuneup.c
+
+Added tuning for MPFR_DIV_THRESHOLD, and default value.
+It now remains to do the tuning on the architectures in mparam_in.h.
+
+------------------------------------------------------------------------
+r7767 | zimmerma | 2011-07-29 20:46:45 +0000 (Fri, 29 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] added speed improvement in mpfr_div
+
+------------------------------------------------------------------------
+r7765 | zimmerma | 2011-07-29 20:15:02 +0000 (Fri, 29 Jul 2011) | 39 lines
+Changed paths:
+ M /trunk/src/div.c
+ M /trunk/src/mulders.c
+
+[mulders.c] fixed bug in mpfr_divhigh_n (this routine was not used yet)
+[div.c] now use Mulders' short product for large division. It remains to
+ do the automatic tuning of MPFR_DIV_THRESHOLD. The speedup is nice,
+ for example on my Core 2 Duo laptop we got with MPFR 3.0.0:
+
+[zimmerma@coing tests]$ ./timings-mpfr 1000
+Using MPFR-3.0.0 with GMP-5.0.2
+[precision is 3322 bits]
+x*y took 0.004543 ms (262143 eval in 1191 ms)
+x*x took 0.003616 ms (524287 eval in 1896 ms)
+x/y took 0.009087 ms (131071 eval in 1191 ms)
+sqrt(x) took 0.007004 ms (262143 eval in 1836 ms)
+exp(x) took 0.293040 ms (4095 eval in 1200 ms)
+log(x) took 0.253724 ms (4095 eval in 1039 ms)
+sin(x) took 0.306960 ms (4095 eval in 1257 ms)
+cos(x) took 0.290842 ms (4095 eval in 1191 ms)
+arccos(x) took 0.590620 ms (2047 eval in 1209 ms)
+arctan(x) took 0.560332 ms (2047 eval in 1147 ms)
+
+and now we get:
+
+[zimmerma@coing tests]$ ./timings-mpfr 1000
+Using MPFR-3.1.0-dev with GMP-5.0.2
+[precision is 3322 bits]
+x*y took 0.004444 ms (262143 eval in 1165 ms)
+x*x took 0.002686 ms (524287 eval in 1408 ms)
+x/y took 0.006989 ms (262143 eval in 1832 ms)
+sqrt(x) took 0.007084 ms (262143 eval in 1857 ms)
+exp(x) took 0.292063 ms (4095 eval in 1196 ms)
+log(x) took 0.246886 ms (4095 eval in 1011 ms)
+sin(x) took 0.259096 ms (4095 eval in 1061 ms)
+cos(x) took 0.244933 ms (4095 eval in 1003 ms)
+arccos(x) took 0.556424 ms (2047 eval in 1139 ms)
+arctan(x) took 0.526624 ms (2047 eval in 1078 ms)
+
+We see that other routines also benefit from the speedup in mpfr_sqr and
+mpfr_div (log, sin, cos, arccos, arctan).
+
+
+------------------------------------------------------------------------
+r7764 | zimmerma | 2011-07-29 15:21:09 +0000 (Fri, 29 Jul 2011) | 3 lines
+Changed paths:
+ M /trunk/doc/algorithms.bib
+ M /trunk/doc/algorithms.tex
+
+[algorithms.tex] added algorithm for division with Mulders' short product
+ (can anybody check the algorithm is ok?)
+
+------------------------------------------------------------------------
+r7763 | vlefevre | 2011-07-29 12:48:21 +0000 (Fri, 29 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/src/vasprintf.c
+
+[src/vasprintf.c] Added a comment.
+------------------------------------------------------------------------
+r7762 | vlefevre | 2011-07-29 12:24:18 +0000 (Fri, 29 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/src/get_str.c
+
+[src/get_str.c] Added a comment about the use of mpfr_ceil_mul
+(exported and declared in mpfr-impl.h since r7760).
+------------------------------------------------------------------------
+r7761 | thevenyp | 2011-07-28 23:01:52 +0000 (Thu, 28 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/src/vasprintf.c
+ M /trunk/tests/tsprintf.c
+
+Avoid expensive calls to mpfr_get_prec() using mpfr_ceil_mul() instead.
+------------------------------------------------------------------------
+r7760 | thevenyp | 2011-07-28 22:59:01 +0000 (Thu, 28 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/src/get_str.c
+ M /trunk/src/mpfr-impl.h
+
+Make ceil_mul() public as mpfr_ceil_mul() in mpfr-impl.h
+------------------------------------------------------------------------
+r7759 | vlefevre | 2011-07-28 18:50:21 +0000 (Thu, 28 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/src/mulders.c
+
+[src/mulders.c] MPFR coding conventions for r7752.
+------------------------------------------------------------------------
+r7758 | zimmerma | 2011-07-28 17:17:24 +0000 (Thu, 28 Jul 2011) | 3 lines
+Changed paths:
+ M /trunk/src/amd/k8/mparam.h
+ M /trunk/src/arm/mparam.h
+ M /trunk/src/hppa/mparam.h
+ M /trunk/src/ia64/mparam.h
+ M /trunk/src/mulders.c
+ M /trunk/src/powerpc32/mparam.h
+ M /trunk/src/powerpc64/mparam.h
+ M /trunk/src/sparc64/mparam.h
+ M /trunk/src/x86/core2/mparam.h
+ M /trunk/src/x86/mparam.h
+ M /trunk/src/x86_64/core2/mparam.h
+ M /trunk/src/x86_64/pentium4/mparam.h
+
+modified the default tuning parameters so they are within the bounds of the
+ARITH-20 paper "Short Division of Long Integers"
+
+------------------------------------------------------------------------
+r7757 | zimmerma | 2011-07-28 16:38:55 +0000 (Thu, 28 Jul 2011) | 3 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[src/mulders.c] declare mpfr_mullow_n as non-static since it might be useful
+ elsewhere
+
+------------------------------------------------------------------------
+r7756 | zimmerma | 2011-07-28 16:36:50 +0000 (Thu, 28 Jul 2011) | 3 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+[tuneup.c] fix tuning bounds of short product and division according to the
+ ARITH-20 paper
+
+------------------------------------------------------------------------
+r7755 | zimmerma | 2011-07-28 16:36:01 +0000 (Thu, 28 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] detect long double format in m68k
+
+------------------------------------------------------------------------
+r7754 | zimmerma | 2011-07-28 16:35:25 +0000 (Thu, 28 Jul 2011) | 3 lines
+Changed paths:
+ M /trunk/tests/tget_flt.c
+
+[tget_flt.c] added test to check FLT_MAX + FLT_MAX gives INFP
+ (to early detect compiler bugs)
+
+------------------------------------------------------------------------
+r7753 | zimmerma | 2011-07-28 16:30:38 +0000 (Thu, 28 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/tools/nightly-test
+
+[nightly-test] changed -pedantic-errors into -pedantic
+
+------------------------------------------------------------------------
+r7752 | zimmerma | 2011-07-28 16:29:51 +0000 (Thu, 28 Jul 2011) | 4 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[mulders.c] added some code for short division (FoldDiv, not used),
+ added comments and fixed bounds in accordance with the
+ ARITH-20 paper
+
+------------------------------------------------------------------------
+r7751 | thevenyp | 2011-07-28 16:16:36 +0000 (Thu, 28 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/src/vasprintf.c
+
+Use a buffer in order to avoid a double call to mpfr_get_str.
+------------------------------------------------------------------------
+r7750 | vlefevre | 2011-07-26 13:12:46 +0000 (Tue, 26 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/src/log.c
+
+[src/log.c] Replaced TMP_* by MPFR_GROUP_* (patch by Patrick).
+------------------------------------------------------------------------
+r7749 | vlefevre | 2011-07-22 10:24:38 +0000 (Fri, 22 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Added a comment about TLS variable initialization.
+------------------------------------------------------------------------
+r7748 | vlefevre | 2011-07-22 10:15:04 +0000 (Fri, 22 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Added information about TLS variable initialization.
+------------------------------------------------------------------------
+r7747 | vlefevre | 2011-07-22 10:09:28 +0000 (Fri, 22 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Split Chapter "MPFR Basics" into nodes as it is now
+quite large (thus references to particular sections are now possible).
+------------------------------------------------------------------------
+r7744 | zimmerma | 2011-07-18 19:03:25 +0000 (Mon, 18 Jul 2011) | 7 lines
+Changed paths:
+ M /trunk/src/vasprintf.c
+
+[vasprintf.c] simplified and improved round_to_10_power(), also contributed
+ a negative number of lines of code :-)
+ Still not optimal, since round_to_10_power() is still called
+ twice for printing say pi with mpfr_printf ("%Rg\n", x), once
+ from partition_number(), once from regular_fg(), and thus
+ mpfr_get_str is called at least 3 times!
+
+------------------------------------------------------------------------
+r7743 | zimmerma | 2011-07-18 12:21:29 +0000 (Mon, 18 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] improve error message when libgmp is not found
+
+------------------------------------------------------------------------
+r7742 | zimmerma | 2011-07-18 11:24:40 +0000 (Mon, 18 Jul 2011) | 3 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[mpfr.texi] added note about threads for mpfr_set_default_prec and
+ mpfr_get_default_prec
+
+------------------------------------------------------------------------
+r7740 | vlefevre | 2011-07-06 15:57:22 +0000 (Wed, 06 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7738 | vlefevre | 2011-07-06 13:47:35 +0000 (Wed, 06 Jul 2011) | 1 line
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/doc/mpfr.texi
+
+[NEWS, doc/mpfr.texi] mpfr_min_prec was a new function in MPFR 3.0.0.
+------------------------------------------------------------------------
+r7736 | vlefevre | 2011-07-01 15:17:47 +0000 (Fri, 01 Jul 2011) | 3 lines
+Changed paths:
+ M /trunk/tests/tget_flt.c
+
+[tests/tget_flt.c] Replaced FLT_MAX + FLT_MAX by (float) DBL_POS_INF,
+which should trigger fewer compiler bugs. See:
+ https://sympa.inria.fr/sympa/arc/mpfr/2011-07/msg00002.html
+------------------------------------------------------------------------
+r7734 | vlefevre | 2011-07-01 08:07:35 +0000 (Fri, 01 Jul 2011) | 2 lines
+Changed paths:
+ M /trunk/src/ieee_floats.h
+
+[src/ieee_floats.h] Added a comment about the NaN format when
+_GMP_IEEE_FLOATS is defined.
+------------------------------------------------------------------------
+r7733 | zimmerma | 2011-07-01 08:04:50 +0000 (Fri, 01 Jul 2011) | 3 lines
+Changed paths:
+ M /trunk/tests/tget_flt.c
+
+[tget_flt.c] check for compiler bug
+ (https://sympa.inria.fr/sympa/arc/mpfr/2011-07/msg00000.html)
+
+------------------------------------------------------------------------
+r7731 | vlefevre | 2011-06-30 00:17:40 +0000 (Thu, 30 Jun 2011) | 3 lines
+Changed paths:
+ M /trunk/AUTHORS
+ M /trunk/BUGS
+ M /trunk/COPYING
+ M /trunk/COPYING.LESSER
+ M /trunk/ChangeLog
+ M /trunk/INSTALL
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/PATCHES
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/VERSION
+ M /trunk/acinclude.m4
+ M /trunk/configure.ac
+ M /trunk/doc/FAQ.html
+ M /trunk/doc/README.dev
+ M /trunk/doc/algorithms.bib
+ M /trunk/doc/algorithms.tex
+ M /trunk/doc/faq.xsl
+ M /trunk/doc/fdl.texi
+ M /trunk/doc/mpfr.texi
+ M /trunk/doc/update-faq
+ M /trunk/examples/divworst.c
+ M /trunk/examples/rndo-add.c
+ M /trunk/examples/sample.c
+ M /trunk/examples/version.c
+ M /trunk/other/cputime.h
+ M /trunk/other/div-short.c
+ M /trunk/src/Makefile.am
+ M /trunk/src/abort_prec_max.c
+ M /trunk/src/acos.c
+ M /trunk/src/acosh.c
+ M /trunk/src/add.c
+ M /trunk/src/add1.c
+ M /trunk/src/add1sp.c
+ M /trunk/src/add_d.c
+ M /trunk/src/add_ui.c
+ M /trunk/src/agm.c
+ M /trunk/src/ai.c
+ M /trunk/src/asin.c
+ M /trunk/src/asinh.c
+ M /trunk/src/atan.c
+ M /trunk/src/atan2.c
+ M /trunk/src/atanh.c
+ M /trunk/src/bernoulli.c
+ M /trunk/src/buildopt.c
+ M /trunk/src/cache.c
+ M /trunk/src/cbrt.c
+ M /trunk/src/check.c
+ M /trunk/src/clear.c
+ M /trunk/src/clears.c
+ M /trunk/src/cmp.c
+ M /trunk/src/cmp2.c
+ M /trunk/src/cmp_abs.c
+ M /trunk/src/cmp_d.c
+ M /trunk/src/cmp_ld.c
+ M /trunk/src/cmp_si.c
+ M /trunk/src/cmp_ui.c
+ M /trunk/src/comparisons.c
+ M /trunk/src/const_catalan.c
+ M /trunk/src/const_euler.c
+ M /trunk/src/const_log2.c
+ M /trunk/src/const_pi.c
+ M /trunk/src/constant.c
+ M /trunk/src/copysign.c
+ M /trunk/src/cos.c
+ M /trunk/src/cosh.c
+ M /trunk/src/cot.c
+ M /trunk/src/coth.c
+ M /trunk/src/csc.c
+ M /trunk/src/csch.c
+ M /trunk/src/d_div.c
+ M /trunk/src/d_sub.c
+ M /trunk/src/digamma.c
+ M /trunk/src/dim.c
+ M /trunk/src/div.c
+ M /trunk/src/div_2exp.c
+ M /trunk/src/div_2si.c
+ M /trunk/src/div_2ui.c
+ M /trunk/src/div_d.c
+ M /trunk/src/div_ui.c
+ M /trunk/src/dump.c
+ M /trunk/src/eint.c
+ M /trunk/src/eq.c
+ M /trunk/src/erf.c
+ M /trunk/src/erfc.c
+ M /trunk/src/exceptions.c
+ M /trunk/src/exp.c
+ M /trunk/src/exp10.c
+ M /trunk/src/exp2.c
+ M /trunk/src/exp3.c
+ M /trunk/src/exp_2.c
+ M /trunk/src/expm1.c
+ M /trunk/src/extract.c
+ M /trunk/src/factorial.c
+ M /trunk/src/fits_intmax.c
+ M /trunk/src/fits_s.h
+ M /trunk/src/fits_sint.c
+ M /trunk/src/fits_slong.c
+ M /trunk/src/fits_sshort.c
+ M /trunk/src/fits_u.h
+ M /trunk/src/fits_uint.c
+ M /trunk/src/fits_uintmax.c
+ M /trunk/src/fits_ulong.c
+ M /trunk/src/fits_ushort.c
+ M /trunk/src/fma.c
+ M /trunk/src/fms.c
+ M /trunk/src/frac.c
+ M /trunk/src/free_cache.c
+ M /trunk/src/gamma.c
+ M /trunk/src/gammaonethird.c
+ M /trunk/src/gen_inverse.h
+ M /trunk/src/get_d.c
+ M /trunk/src/get_d64.c
+ M /trunk/src/get_exp.c
+ M /trunk/src/get_f.c
+ M /trunk/src/get_flt.c
+ M /trunk/src/get_ld.c
+ M /trunk/src/get_si.c
+ M /trunk/src/get_sj.c
+ M /trunk/src/get_str.c
+ M /trunk/src/get_ui.c
+ M /trunk/src/get_uj.c
+ M /trunk/src/get_z.c
+ M /trunk/src/get_z_exp.c
+ M /trunk/src/gmp_op.c
+ M /trunk/src/hypot.c
+ M /trunk/src/ieee_floats.h
+ M /trunk/src/init.c
+ M /trunk/src/init2.c
+ M /trunk/src/inits.c
+ M /trunk/src/inits2.c
+ M /trunk/src/inp_str.c
+ M /trunk/src/int_ceil_log2.c
+ M /trunk/src/isinf.c
+ M /trunk/src/isinteger.c
+ M /trunk/src/isnan.c
+ M /trunk/src/isnum.c
+ M /trunk/src/isqrt.c
+ M /trunk/src/isregular.c
+ M /trunk/src/iszero.c
+ M /trunk/src/jn.c
+ M /trunk/src/jyn_asympt.c
+ M /trunk/src/li2.c
+ M /trunk/src/lngamma.c
+ M /trunk/src/log.c
+ M /trunk/src/log10.c
+ M /trunk/src/log1p.c
+ M /trunk/src/log2.c
+ M /trunk/src/logging.c
+ M /trunk/src/min_prec.c
+ M /trunk/src/minmax.c
+ M /trunk/src/modf.c
+ M /trunk/src/mp_clz_tab.c
+ M /trunk/src/mparam_h.in
+ M /trunk/src/mpf2mpfr.h
+ M /trunk/src/mpfr-gmp.c
+ M /trunk/src/mpfr-gmp.h
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mpfr-longlong.h
+ M /trunk/src/mpfr-thread.h
+ M /trunk/src/mpfr.h
+ M /trunk/src/mpn_exp.c
+ M /trunk/src/mul.c
+ M /trunk/src/mul_2exp.c
+ M /trunk/src/mul_2si.c
+ M /trunk/src/mul_2ui.c
+ M /trunk/src/mul_d.c
+ M /trunk/src/mul_ui.c
+ M /trunk/src/mulders.c
+ M /trunk/src/neg.c
+ M /trunk/src/next.c
+ M /trunk/src/out_str.c
+ M /trunk/src/pow.c
+ M /trunk/src/pow_si.c
+ M /trunk/src/pow_ui.c
+ M /trunk/src/pow_z.c
+ M /trunk/src/powerof2.c
+ M /trunk/src/print_raw.c
+ M /trunk/src/print_rnd_mode.c
+ M /trunk/src/printf.c
+ M /trunk/src/rec_sqrt.c
+ M /trunk/src/reldiff.c
+ M /trunk/src/rem1.c
+ M /trunk/src/rint.c
+ M /trunk/src/root.c
+ M /trunk/src/round_near_x.c
+ M /trunk/src/round_p.c
+ M /trunk/src/round_prec.c
+ M /trunk/src/round_raw_generic.c
+ M /trunk/src/scale2.c
+ M /trunk/src/sec.c
+ M /trunk/src/sech.c
+ M /trunk/src/set.c
+ M /trunk/src/set_d.c
+ M /trunk/src/set_d64.c
+ M /trunk/src/set_dfl_prec.c
+ M /trunk/src/set_exp.c
+ M /trunk/src/set_f.c
+ M /trunk/src/set_flt.c
+ M /trunk/src/set_inf.c
+ M /trunk/src/set_ld.c
+ M /trunk/src/set_nan.c
+ M /trunk/src/set_prc_raw.c
+ M /trunk/src/set_prec.c
+ M /trunk/src/set_q.c
+ M /trunk/src/set_rnd.c
+ M /trunk/src/set_si.c
+ M /trunk/src/set_si_2exp.c
+ M /trunk/src/set_sj.c
+ M /trunk/src/set_str.c
+ M /trunk/src/set_str_raw.c
+ M /trunk/src/set_ui.c
+ M /trunk/src/set_ui_2exp.c
+ M /trunk/src/set_uj.c
+ M /trunk/src/set_z.c
+ M /trunk/src/set_z_exp.c
+ M /trunk/src/set_zero.c
+ M /trunk/src/setmax.c
+ M /trunk/src/setmin.c
+ M /trunk/src/setsign.c
+ M /trunk/src/sgn.c
+ M /trunk/src/si_op.c
+ M /trunk/src/signbit.c
+ M /trunk/src/sin.c
+ M /trunk/src/sin_cos.c
+ M /trunk/src/sinh.c
+ M /trunk/src/sinh_cosh.c
+ M /trunk/src/sqr.c
+ M /trunk/src/sqrt.c
+ M /trunk/src/sqrt_ui.c
+ M /trunk/src/stack_interface.c
+ M /trunk/src/strtofr.c
+ M /trunk/src/sub.c
+ M /trunk/src/sub1.c
+ M /trunk/src/sub1sp.c
+ M /trunk/src/sub_d.c
+ M /trunk/src/sub_ui.c
+ M /trunk/src/subnormal.c
+ M /trunk/src/sum.c
+ M /trunk/src/swap.c
+ M /trunk/src/tan.c
+ M /trunk/src/tanh.c
+ M /trunk/src/uceil_exp2.c
+ M /trunk/src/uceil_log2.c
+ M /trunk/src/ufloor_log2.c
+ M /trunk/src/ui_div.c
+ M /trunk/src/ui_pow.c
+ M /trunk/src/ui_pow_ui.c
+ M /trunk/src/ui_sub.c
+ M /trunk/src/urandom.c
+ M /trunk/src/urandomb.c
+ M /trunk/src/vasprintf.c
+ M /trunk/src/version.c
+ M /trunk/src/volatile.c
+ M /trunk/src/yn.c
+ M /trunk/src/zeta.c
+ M /trunk/src/zeta_ui.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/RRTest.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/inp_str.data
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/random2.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tai.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tbuildopt.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdigamma.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_flt.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tisqrt.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmin_prec.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tset_z_exp.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstdint.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/turandom.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tools/check_inits_clears
+ M /trunk/tools/ck-version-info
+ M /trunk/tools/coverage
+ M /trunk/tools/get_patches.sh
+ M /trunk/tools/mbench/generate.c
+ M /trunk/tools/mbench/mfv5.h
+ M /trunk/tools/mbench/mpfr-gfx.c
+ M /trunk/tools/mbench/mpfr-v4.c
+ M /trunk/tools/mbench/mpfr-v6.c
+ M /trunk/tools/mbench/timp.h
+ M /trunk/tools/update-patchv
+ M /trunk/tools/update-version
+ M /trunk/tune/speed.c
+ M /trunk/tune/tuneup.c
+
+Removed all the svn:eol-style properties (they were set to "native"),
+and in doc/README.dev, explained why svn:eol-style native should not
+be used.
+------------------------------------------------------------------------
+r7729 | vlefevre | 2011-06-28 22:55:59 +0000 (Tue, 28 Jun 2011) | 2 lines
+Changed paths:
+ M /trunk/tools/ck-version-info
+
+[tools/ck-version-info] Check DLL version in LIBMPFR_LDFLAGS line from
+configure.ac (patch by Stefan Graff, with minor changes).
+------------------------------------------------------------------------
+r7726 | vlefevre | 2011-06-26 09:44:11 +0000 (Sun, 26 Jun 2011) | 5 lines
+Changed paths:
+ M /trunk/tools/ck-version-info
+
+[tools/ck-version-info] 2 corrections:
+ * update due to the change of the libmpfr_la_LDFLAGS line in r7724;
+ * to support the CRLF end-of-line sometimes used under MS-Windows
+ (perl should normally take care of that, but Windows software is
+ not always consistent).
+------------------------------------------------------------------------
+r7725 | vlefevre | 2011-06-26 09:30:05 +0000 (Sun, 26 Jun 2011) | 4 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Due to the "@unnumbered Function and Type Index",
+replaced the other "Function Index" by "Function and Type Index"
+(note: the function index and the type index are merged thanks to
+the "@synindex tp fn" line at the beginning of mpfr.texi).
+------------------------------------------------------------------------
+r7724 | vlefevre | 2011-06-25 16:08:39 +0000 (Sat, 25 Jun 2011) | 4 lines
+Changed paths:
+ M /trunk/configure.ac
+ M /trunk/src/Makefile.am
+
+Ported patch r7723 (changes suggested by Stefan Graff to be able
+to build Windows DLLs with GCC 4.6[*]) to the trunk, not tested
+(something more may be needed due to the source reorganization).
+[*] https://sympa.inria.fr/sympa/arc/mpfr/2011-06/msg00013.html
+------------------------------------------------------------------------
+r7722 | vlefevre | 2011-06-21 20:45:27 +0000 (Tue, 21 Jun 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7721 | vlefevre | 2011-06-21 20:41:51 +0000 (Tue, 21 Jun 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Corrected a note about mpfr_set_*, due to the addition
+of mpfr_set_decimal64.
+------------------------------------------------------------------------
+r7720 | vlefevre | 2011-06-20 14:38:24 +0000 (Mon, 20 Jun 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Removed comment added in r7181, as it is no longer
+necessary since r7182 (new option --enable-gmp-internals).
+------------------------------------------------------------------------
+r7719 | vlefevre | 2011-06-20 14:36:28 +0000 (Mon, 20 Jun 2011) | 2 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] Updated comment concerning __gmpn_rootrem (mention
+WANT_GMP_INTERNALS).
+------------------------------------------------------------------------
+r7718 | vlefevre | 2011-06-20 14:10:04 +0000 (Mon, 20 Jun 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added a note about logging and timeout.
+------------------------------------------------------------------------
+r7717 | vlefevre | 2011-06-20 13:59:31 +0000 (Mon, 20 Jun 2011) | 1 line
+Changed paths:
+ M /trunk/src/atan2.c
+ M /trunk/src/pow.c
+
+[src] Conversion into UTF-8 (only comments were concerned).
+------------------------------------------------------------------------
+r7716 | vlefevre | 2011-06-20 13:57:40 +0000 (Mon, 20 Jun 2011) | 1 line
+Changed paths:
+ M /trunk/TODO
+
+[TODO] Conversion into UTF-8.
+------------------------------------------------------------------------
+r7715 | vlefevre | 2011-06-20 13:56:51 +0000 (Mon, 20 Jun 2011) | 2 lines
+Changed paths:
+ M /trunk/src/pow.c
+
+[src/pow.c] Made the code more robust concerning the scaling (a bug was
+very unlikely, though), and updated the comments (partial proof).
+------------------------------------------------------------------------
+r7714 | vlefevre | 2011-06-01 01:32:26 +0000 (Wed, 01 Jun 2011) | 1 line
+Changed paths:
+ M /trunk/examples/version.c
+
+[examples/version.c] Output MPFR features and size of MPFR types.
+------------------------------------------------------------------------
+r7711 | zimmerma | 2011-05-22 19:13:25 +0000 (Sun, 22 May 2011) | 3 lines
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+ M /trunk/tests/trec_sqrt.c
+
+[src/rec_sqrt.c] continued review; I can now prove that cu=0 in all cases
+[tests/trec_sqrt.c] added tests for corner cases
+
+------------------------------------------------------------------------
+r7710 | zimmerma | 2011-05-20 05:51:22 +0000 (Fri, 20 May 2011) | 2 lines
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[rec_sqrt.c] more review of codes, following comments from Vincent
+
+------------------------------------------------------------------------
+r7709 | zimmerma | 2011-05-19 08:37:24 +0000 (Thu, 19 May 2011) | 2 lines
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[rec_sqrt.c] removed tabs
+
+------------------------------------------------------------------------
+r7708 | zimmerma | 2011-05-19 06:44:00 +0000 (Thu, 19 May 2011) | 4 lines
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[rec_sqrt.c] review and small change of changeset 7651: most probably cu=0
+ when th=0 (and maybe cu=0 always, I cannot find an example where
+ cu <> 0) but considering the case th=0 is more natural.
+
+------------------------------------------------------------------------
+r7707 | vlefevre | 2011-05-18 15:02:52 +0000 (Wed, 18 May 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] List the contributors in the alphabetic order, like
+the main authors.
+------------------------------------------------------------------------
+r7706 | vlefevre | 2011-05-18 14:52:18 +0000 (Wed, 18 May 2011) | 1 line
+Changed paths:
+ M /trunk/AUTHORS
+ M /trunk/doc/mpfr.texi
+
+Made AUTHORS and doc/mpfr.texi consistent.
+------------------------------------------------------------------------
+r7705 | vlefevre | 2011-05-18 14:44:37 +0000 (Wed, 18 May 2011) | 1 line
+Changed paths:
+ M /trunk/AUTHORS
+ M /trunk/src/acos.c
+ M /trunk/src/asin.c
+ M /trunk/src/atan.c
+ M /trunk/src/atan2.c
+ M /trunk/src/erf.c
+ M /trunk/src/get_str.c
+ M /trunk/src/mpn_exp.c
+ M /trunk/src/round_near_x.c
+ M /trunk/src/zeta.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tbuildopt.c
+ M /trunk/tests/tdigamma.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tzeta.c
+
+Updated AUTHORS file and copyright notices (for more consistency).
+------------------------------------------------------------------------
+r7704 | vlefevre | 2011-05-18 14:26:30 +0000 (Wed, 18 May 2011) | 1 line
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+[tests/thyperbolic.c] Fixed copyright notice.
+------------------------------------------------------------------------
+r7703 | vlefevre | 2011-05-18 14:25:11 +0000 (Wed, 18 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/inp_str.c
+
+[src/inp_str.c] Improved comment.
+------------------------------------------------------------------------
+r7702 | vlefevre | 2011-05-18 14:18:41 +0000 (Wed, 18 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/fits_s.h
+
+[src/fits_s.h] Improved comment.
+------------------------------------------------------------------------
+r7701 | vlefevre | 2011-05-18 14:09:54 +0000 (Wed, 18 May 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7700 | vlefevre | 2011-05-18 14:09:05 +0000 (Wed, 18 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Avoid a warning from mpfrlint.
+------------------------------------------------------------------------
+r7699 | vlefevre | 2011-05-18 13:09:33 +0000 (Wed, 18 May 2011) | 1 line
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] Consistency change in the copyright notice.
+------------------------------------------------------------------------
+r7698 | vlefevre | 2011-05-18 11:09:30 +0000 (Wed, 18 May 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tsqr.c
+
+[tests/tsqr.c] Added a note in the check_mpn_sqr error message.
+------------------------------------------------------------------------
+r7697 | vlefevre | 2011-05-18 10:59:48 +0000 (Wed, 18 May 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqr.c
+
+[tests/tsqr.c] Added a test of mpn_sqr concerning a bug seen
+with GCC 4.5.2 and GMP 5.0.1 on m68k (m68000 target).
+------------------------------------------------------------------------
+r7696 | vlefevre | 2011-05-17 14:25:37 +0000 (Tue, 17 May 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added a note about a texinfo bug.
+------------------------------------------------------------------------
+r7695 | vlefevre | 2011-05-13 15:58:57 +0000 (Fri, 13 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/Makefile.am
+ M /trunk/src/fits_intmax.c
+ M /trunk/src/fits_uintmax.c
+ M /trunk/src/get_sj.c
+ M /trunk/src/get_uj.c
+ M /trunk/src/mpfr-impl.h
+ A /trunk/src/mpfr-intmax.h
+ M /trunk/src/set_sj.c
+ M /trunk/src/set_uj.c
+ M /trunk/src/vasprintf.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tset_sj.c
+
+Added mpfr-intmax.h header.
+------------------------------------------------------------------------
+r7694 | vlefevre | 2011-05-13 15:19:50 +0000 (Fri, 13 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mpfr.h
+ M /trunk/tests/tstdint.c
+ M /trunk/tests/tvalist.c
+
+Started to support mpfr_exp_t defined as intmax_t (_MPFR_EXP_FORMAT==4).
+------------------------------------------------------------------------
+r7693 | vlefevre | 2011-05-13 11:52:28 +0000 (Fri, 13 May 2011) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Added that the mpfr.h header can be included several times,
+while still supporting optional functions.
+------------------------------------------------------------------------
+r7692 | vlefevre | 2011-05-13 11:48:13 +0000 (Fri, 13 May 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Document what to do if mpfr.h can be included
+multiple times (fixes MPFR bug #9653).
+------------------------------------------------------------------------
+r7690 | vlefevre | 2011-05-12 15:29:24 +0000 (Thu, 12 May 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added a note to run tests with -D_MPFR_PREC_FORMAT=2.
+------------------------------------------------------------------------
+r7689 | vlefevre | 2011-05-12 14:10:39 +0000 (Thu, 12 May 2011) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Exponent properties: corrected comments and removed
+obsolete mp_exp_unsigned_t definition (was internal only).
+------------------------------------------------------------------------
+r7688 | vlefevre | 2011-05-12 13:57:02 +0000 (Thu, 12 May 2011) | 4 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mpfr.h
+ M /trunk/src/vasprintf.c
+
+[src/{mpfr.h,mpfr-impl.h,vasprintf.c}] Clean-up and improvement
+of definitions related to mpfr_exp_t. MPFR can now be built with
+-D_MPFR_PREC_FORMAT=2 to have mpfr_prec_t and mpfr_exp_t defined
+as an int.
+------------------------------------------------------------------------
+r7687 | vlefevre | 2011-05-12 12:40:39 +0000 (Thu, 12 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Fixed spaces in a comment.
+------------------------------------------------------------------------
+r7686 | vlefevre | 2011-05-12 12:36:13 +0000 (Thu, 12 May 2011) | 3 lines
+Changed paths:
+ M /trunk
+ M /trunk/src/add1sp.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/turandom.c
+
+Fixed printf's calls: support the case where mpfr_prec_t is not a long
+(or unsigned long).
+[merged changeset r7643 from the exp-int branch]
+------------------------------------------------------------------------
+r7685 | vlefevre | 2011-05-12 12:30:41 +0000 (Thu, 12 May 2011) | 5 lines
+Changed paths:
+ M /trunk
+ M /trunk/src/strtofr.c
+
+[src/strtofr.c] Support the case where mpfr_exp_t < long; mpfr_exp_t is
+currently defined as mp_exp_t, which comes from GMP, and GMP currently
+defines mp_exp_t as a long, except on Cray (never tested for MPFR). But
+this may change in the future (possibly as an option)...
+[merged changeset r7642 from the exp-int branch]
+------------------------------------------------------------------------
+r7684 | vlefevre | 2011-05-12 12:21:49 +0000 (Thu, 12 May 2011) | 2 lines
+Changed paths:
+ M /trunk
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Added missing parentheses in MPFR_SADD_OVERFLOW
+(fortunately the current MPFR code was not affected).
+------------------------------------------------------------------------
+r7683 | vlefevre | 2011-05-12 12:18:38 +0000 (Thu, 12 May 2011) | 1 line
+Changed paths:
+ M /trunk
+ M /trunk/tests/tpow_z.c
+
+[tests/tpow_z.c] More details for a test in case of failure.
+------------------------------------------------------------------------
+r7682 | vlefevre | 2011-05-12 12:16:01 +0000 (Thu, 12 May 2011) | 5 lines
+Changed paths:
+ M /trunk
+ M /trunk/src/sub1.c
+
+[src/sub1.c] Fixed several bugs: integer overflows and potential
+out-of-bound pointers. They might be visible on particular platforms,
+with a particular configuration (e.g. 64-bit limbs and 32-bit exponent
+type) or particular compiler options (to check such overflows).
+[merged changesets r7637-7638 from the exp-int branch]
+------------------------------------------------------------------------
+r7679 | vlefevre | 2011-05-11 13:50:01 +0000 (Wed, 11 May 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tsin.c
+
+[tests/tsin.c] Added a test (it failed before the fix in r7308).
+------------------------------------------------------------------------
+r7678 | vlefevre | 2011-05-11 00:07:05 +0000 (Wed, 11 May 2011) | 10 lines
+Changed paths:
+ M /trunk/src/const_log2.c
+ M /trunk/src/const_pi.c
+ M /trunk/src/free_cache.c
+ M /trunk/src/mpfr-impl.h
+
+Fixed constants pi and log(2) computation when logging is used: When
+MPFR is built with logging support, these two constants are used by
+the logging functions (via mpfr_fprintf, then mpfr_log, for the base
+conversion). Since the mpfr_cache function isn't re-entrant when
+working on the same cache, we need to define two caches for each
+constant. Otherwise the constants could be incorrect; for instance,
+"MPFR_LOG_ALL=1 ./tconst_pi" was failing.
+Note: the bug was introduced with the new logging system from r7575
+for MPFR 3.1.0, based on mpfr_fprintf instead of mpfr_out_str (which
+doesn't depend on mpfr_log).
+------------------------------------------------------------------------
+r7676 | vlefevre | 2011-05-09 12:03:20 +0000 (Mon, 09 May 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+[tests/tests.c] Replaced atoi by strtoul to read the seed from
+GMP_CHECK_RANDOMIZE, as it is an unsigned long.
+------------------------------------------------------------------------
+r7674 | vlefevre | 2011-05-09 11:17:43 +0000 (Mon, 09 May 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+[tests/texp.c] Fixed the test comparing mpfr_exp_2 and mpfr_exp_3:
+filter out 0, as it is handled correctly only by mpfr_exp.
+------------------------------------------------------------------------
+r7672 | vlefevre | 2011-05-06 13:30:28 +0000 (Fri, 06 May 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Completed the note to run tests under gdb.
+------------------------------------------------------------------------
+r7671 | vlefevre | 2011-05-06 12:50:43 +0000 (Fri, 06 May 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added a note to run tests under gdb.
+------------------------------------------------------------------------
+r7670 | zimmerma | 2011-05-06 12:31:24 +0000 (Fri, 06 May 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/README.dev
+
+[README.dev] added hint for logging
+
+------------------------------------------------------------------------
+r7667 | vlefevre | 2011-05-04 23:46:17 +0000 (Wed, 04 May 2011) | 6 lines
+Changed paths:
+ M /trunk/src/atan.c
+
+[src/atan.c] Fixed bug in mpfr_atan: mpfr_check_range was called on the
+unrounded result (no longer allocated) instead of the rounded result.
+Consequence of this bug: possible incorrect or invalid result and/or
+incorrect flags if either the unrounded result or rounded result is not
+in the current exponent range. Or possibly worse if the memory used by
+the unrounded result is modified before the return of the function.
+------------------------------------------------------------------------
+r7666 | vlefevre | 2011-05-04 23:25:24 +0000 (Wed, 04 May 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tatan.c
+
+[tests/tatan.c] Corrected a comment.
+------------------------------------------------------------------------
+r7665 | vlefevre | 2011-05-04 23:20:18 +0000 (Wed, 04 May 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+[tests/tatan.c] Added a testcase showing a failure of mpfr_atan
+in a reduced exponent range.
+------------------------------------------------------------------------
+r7664 | vlefevre | 2011-05-04 22:04:17 +0000 (Wed, 04 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/const_pi.c
+
+[src/const_pi.c] Removed useless assignment.
+------------------------------------------------------------------------
+r7663 | zimmerma | 2011-05-04 21:58:12 +0000 (Wed, 04 May 2011) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[mpfr-impl.h] fixed typo
+
+------------------------------------------------------------------------
+r7661 | vlefevre | 2011-05-03 17:26:31 +0000 (Tue, 03 May 2011) | 5 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mul.c
+
+[src/mpfr-impl.h] In MPFR_RNDRAW_GEN, do not try to compute the
+ sticky bit when not necessary (directed mode with rb = 1).
+[src/mul.c] FIXME comment: with the change in MPFR_RNDRAW_GEN,
+ uninitialized data are no longer read; there's still something
+ wrong, at least with the code documentation, though.
+------------------------------------------------------------------------
+r7660 | vlefevre | 2011-05-03 13:59:19 +0000 (Tue, 03 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/mul.c
+
+[src/mul.c] Updated the FIXME comment.
+------------------------------------------------------------------------
+r7659 | vlefevre | 2011-05-03 13:51:52 +0000 (Tue, 03 May 2011) | 6 lines
+Changed paths:
+ M /trunk/src/mul.c
+ M /trunk/tests/tmul.c
+
+Bug in mpfr_mul: a call mpfr_mulhigh_n(pointers..., n) where n is some
+size is done, but the mpfr_mul code assumes a result whose size can be
+arbitrarily larger, thus may depend on uninitialised data.
+ * [src/mul.c] Added a FIXME comment.
+ * [tests/tmul.c] Added a corresponding test. The result is not checked
+ but valgrind complains of the use of uninitialised value(s).
+------------------------------------------------------------------------
+r7658 | vlefevre | 2011-05-03 13:17:04 +0000 (Tue, 03 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] MPFR_RNDRAW_GEN: added other missing parentheses.
+------------------------------------------------------------------------
+r7657 | vlefevre | 2011-05-03 13:14:25 +0000 (Tue, 03 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] MPFR_RNDRAW_GEN: added missing parentheses.
+------------------------------------------------------------------------
+r7656 | vlefevre | 2011-05-03 12:38:50 +0000 (Tue, 03 May 2011) | 3 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Logging: do not take into account the Ziv loops due
+to logging (i.e. used by the MPFR functions called by the mpfr_fprintf
+in LOG_PRINT).
+------------------------------------------------------------------------
+r7655 | vlefevre | 2011-05-03 12:23:23 +0000 (Tue, 03 May 2011) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Avoid recursive logging for MPFR_ZIV_* macros too,
+and fixed type for the output of the precision.
+------------------------------------------------------------------------
+r7654 | vlefevre | 2011-05-03 11:11:47 +0000 (Tue, 03 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Avoid recursive logging (not wanted and freezes MPFR).
+------------------------------------------------------------------------
+r7652 | vlefevre | 2011-05-03 07:34:04 +0000 (Tue, 03 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[src/rec_sqrt.c] Improved the comment added in r7651.
+------------------------------------------------------------------------
+r7651 | vlefevre | 2011-05-02 13:46:38 +0000 (Mon, 02 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[src/rec_sqrt.c] Fixed the buffer overflow (bug 12553).
+------------------------------------------------------------------------
+r7650 | vlefevre | 2011-05-02 13:26:29 +0000 (Mon, 02 May 2011) | 4 lines
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[src/rec_sqrt.c] Added an assertion to avoid a buffer overflow
+(mpn_add_1 and mpn_sub_1 don't support size = 0). It sometimes
+fails, and this is the following bug:
+https://gforge.inria.fr/tracker/index.php?func=detail&aid=12553&group_id=136&atid=619
+------------------------------------------------------------------------
+r7649 | vlefevre | 2011-05-02 13:01:30 +0000 (Mon, 02 May 2011) | 2 lines
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[src/rec_sqrt.c] Added a comment about a buffer overflow. Bug report:
+https://gforge.inria.fr/tracker/index.php?func=detail&aid=12553&group_id=136&atid=619
+------------------------------------------------------------------------
+r7648 | vlefevre | 2011-05-02 10:49:33 +0000 (Mon, 02 May 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tvalist.c
+
+[tests/tvalist.c] Make sure that fct is used (avoid a warning).
+------------------------------------------------------------------------
+r7647 | vlefevre | 2011-05-02 10:36:08 +0000 (Mon, 02 May 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+[tests/tsin_cos.c] status_f and status were not read (compared) in
+coverage_01032011, yielding a warning.
+------------------------------------------------------------------------
+r7646 | vlefevre | 2011-05-02 10:34:06 +0000 (Mon, 02 May 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Avoid a spurious warning with some use of MPFR_BLOCK.
+------------------------------------------------------------------------
+r7645 | vlefevre | 2011-05-02 10:13:17 +0000 (Mon, 02 May 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added command to test with valgrind.
+------------------------------------------------------------------------
+r7644 | vlefevre | 2011-05-01 01:45:29 +0000 (Sun, 01 May 2011) | 6 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/configure.ac
+
+Added "make dist" support for -dev MPFR versions by distributing the
+tests/data files in the tarball for such MPFR versions ("make check"
+fails if some data file couldn't be read for such versions).
+ * configure.ac: add a Makefile variable DATAFILES, which contains the
+ list of the tests/data files if the MPFR version ends with "-dev".
+ * Makefile.am: add $(DATAFILES) to EXTRA_DIST.
+------------------------------------------------------------------------
+r7640 | vlefevre | 2011-04-29 11:33:48 +0000 (Fri, 29 Apr 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/trint.c
+
+[tests/trint.c] Removed a useless pointer cast (in general, such casts
+are either useless or incorrect, as breaking aliasing rules).
+------------------------------------------------------------------------
+r7636 | vlefevre | 2011-04-28 12:54:20 +0000 (Thu, 28 Apr 2011) | 1 line
+Changed paths:
+ M /trunk/src/cmp2.c
+
+[src/cmp2.c] Added an assertion.
+------------------------------------------------------------------------
+r7634 | vlefevre | 2011-04-18 14:53:03 +0000 (Mon, 18 Apr 2011) | 5 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] Correction of problems triggering the warning
+ "warning: AC_LANG_CONFTEST: no AC_LANG_SOURCE call detected in body"
+with autoconf 2.68:
+* Fixed missing quoting in an AC_RUN_IFELSE.
+* Added an AC_LANG_SOURCE in another AC_RUN_IFELSE.
+------------------------------------------------------------------------
+r7633 | vlefevre | 2011-04-18 12:11:10 +0000 (Mon, 18 Apr 2011) | 1 line
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] s/can not/cannot/
+------------------------------------------------------------------------
+r7632 | vlefevre | 2011-04-18 12:09:25 +0000 (Mon, 18 Apr 2011) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] Added comment about the warning:
+ warning: AC_LANG_CONFTEST: no AC_LANG_SOURCE call detected in body
+------------------------------------------------------------------------
+r7631 | vlefevre | 2011-04-15 12:35:11 +0000 (Fri, 15 Apr 2011) | 1 line
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] Use conventional quotes.
+------------------------------------------------------------------------
+r7630 | vlefevre | 2011-04-15 12:15:16 +0000 (Fri, 15 Apr 2011) | 1 line
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] Added a comment.
+------------------------------------------------------------------------
+r7625 | vlefevre | 2011-04-12 08:17:39 +0000 (Tue, 12 Apr 2011) | 3 lines
+Changed paths:
+ M /trunk/src/asin.c
+ M /trunk/tests/tasin.c
+
+[src/asin.c] Fixed bug in mpfr_asin for x = 1 or -1 in extremely reduced
+ exponent range (when pi is not representable, but pi/2 is).
+[tests/tasin.c] Added testcase.
+------------------------------------------------------------------------
+r7624 | vlefevre | 2011-04-08 15:32:40 +0000 (Fri, 08 Apr 2011) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] Removed "allow generic tests to run with a restricted
+exponent range" (this was done in r7470).
+------------------------------------------------------------------------
+r7623 | zimmerma | 2011-04-08 13:18:37 +0000 (Fri, 08 Apr 2011) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added item
+
+------------------------------------------------------------------------
+r7621 | vlefevre | 2011-04-05 08:47:39 +0000 (Tue, 05 Apr 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7620 | vlefevre | 2011-04-05 08:45:37 +0000 (Tue, 05 Apr 2011) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/doc/mpfr.texi
+
+[INSTALL,doc/mpfr.texi] Say that mpfr@loria.fr is the MPFR mailing-list.
+------------------------------------------------------------------------
+r7611 | vlefevre | 2011-04-01 14:28:45 +0000 (Fri, 01 Apr 2011) | 4 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] Removed the -Wno-format GCC option, which was added
+when logging was used, as it is no longer needed after the changes
+done in r7575,7578 (mpfr_fprintf is now used for logging instead of
+fprintf with the Glibc register_printf_function extension).
+------------------------------------------------------------------------
+r7607 | vlefevre | 2011-03-29 11:49:11 +0000 (Tue, 29 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/reuse.c
+
+[tests/reuse.c] Added a comment.
+------------------------------------------------------------------------
+r7606 | vlefevre | 2011-03-29 11:45:40 +0000 (Tue, 29 Mar 2011) | 4 lines
+Changed paths:
+ M /trunk/src/pow.c
+
+[src/pow.c] Fixed a bug in mpfr_pow_general when an argument is reused
+(e.g. mpfr_pow(x,x,y,rnd) or mpfr_pow(y,x,y,rnd)) and the result is
+negative, thus when x is negative and y is a huge odd integer ("huge"
+because not-too-large integers are currently handled by mpfr_pow_z).
+------------------------------------------------------------------------
+r7605 | vlefevre | 2011-03-29 11:36:49 +0000 (Tue, 29 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+[tests/reuse.c] Added a mpfr_pow(x,x,y,rnd) test showing a failure
+when x is negative and y is a huge odd integer.
+------------------------------------------------------------------------
+r7604 | vlefevre | 2011-03-29 11:10:29 +0000 (Tue, 29 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/subnormal.c
+
+[src/subnormal.c] Improved a comment.
+------------------------------------------------------------------------
+r7603 | vlefevre | 2011-03-29 11:01:33 +0000 (Tue, 29 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/reuse.c
+
+[tests/reuse.c] Test also negative numbers.
+------------------------------------------------------------------------
+r7602 | vlefevre | 2011-03-29 10:52:35 +0000 (Tue, 29 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/reuse.c
+
+[tests/reuse.c] GNU coding style.
+------------------------------------------------------------------------
+r7601 | vlefevre | 2011-03-29 10:27:45 +0000 (Tue, 29 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/mul.c
+
+[src/mul.c] Updated a comment.
+------------------------------------------------------------------------
+r7600 | vlefevre | 2011-03-29 10:20:58 +0000 (Tue, 29 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/powerof2.c
+
+[src/powerof2.c] Updated comment.
+------------------------------------------------------------------------
+r7599 | vlefevre | 2011-03-29 09:30:11 +0000 (Tue, 29 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/powerof2.c
+
+[src/powerof2.c] More detailed comment.
+------------------------------------------------------------------------
+r7595 | zimmerma | 2011-03-21 10:52:35 +0000 (Mon, 21 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/tools/cfarm.sh
+
+[cfarm.sh] complete tests with mpfr-3.0.1-rc1
+
+------------------------------------------------------------------------
+r7592 | vlefevre | 2011-03-21 02:43:09 +0000 (Mon, 21 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/pow_z.c
+
+[src/pow_z.c] Fixed bug bug20110320, that occurs in extremely reduced
+exponent range (more precisely, if 1 is out of range, i.e. emin > 1).
+------------------------------------------------------------------------
+r7591 | vlefevre | 2011-03-21 02:32:07 +0000 (Mon, 21 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tpow.c
+
+[tests/tpow.c] Added testcase bug20110320.
+------------------------------------------------------------------------
+r7590 | vlefevre | 2011-03-21 02:13:16 +0000 (Mon, 21 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tests/tgeneric.c] Added debug information.
+------------------------------------------------------------------------
+r7589 | zimmerma | 2011-03-20 19:24:24 +0000 (Sun, 20 Mar 2011) | 2 lines
+Changed paths:
+ A /trunk/tools/cfarm.sh
+
+[cfarm.sh] shell script to test MPFR on the GCC Compile Farm
+
+------------------------------------------------------------------------
+r7587 | zimmerma | 2011-03-18 12:30:22 +0000 (Fri, 18 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/digamma.c
+
+[digamma.c] fixed compiler warning (ISO C90 forbids mixed declarations and code)
+
+------------------------------------------------------------------------
+r7581 | vlefevre | 2011-03-17 15:44:58 +0000 (Thu, 17 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Added a note about the fix in the mpfr_subnormalize
+implementation, in case users would think the old behavior
+was chosen on purpose.
+------------------------------------------------------------------------
+r7578 | vlefevre | 2011-03-17 09:30:32 +0000 (Thu, 17 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/src/div_ui.c
+
+Completed r7575 (Get rid of deprecated register_printf_function
+function in logging system): there was a remaining old MPFR_LOG_FUNC
+in "src/div_ui.c". Now, the MPFR source no longer contains '%#R'.
+------------------------------------------------------------------------
+r7577 | vlefevre | 2011-03-17 08:45:21 +0000 (Thu, 17 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/mul_2si.c
+
+[src/mul_2si.c] Removed trailing whitespace.
+------------------------------------------------------------------------
+r7576 | vlefevre | 2011-03-17 08:43:54 +0000 (Thu, 17 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Fixed variable name from r7575.
+------------------------------------------------------------------------
+r7575 | thevenyp | 2011-03-17 06:30:11 +0000 (Thu, 17 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+ M /trunk/src/acos.c
+ M /trunk/src/acosh.c
+ M /trunk/src/add.c
+ M /trunk/src/add_d.c
+ M /trunk/src/add_ui.c
+ M /trunk/src/agm.c
+ M /trunk/src/ai.c
+ M /trunk/src/asin.c
+ M /trunk/src/asinh.c
+ M /trunk/src/atan.c
+ M /trunk/src/atan2.c
+ M /trunk/src/atanh.c
+ M /trunk/src/cbrt.c
+ M /trunk/src/const_catalan.c
+ M /trunk/src/const_log2.c
+ M /trunk/src/const_pi.c
+ M /trunk/src/cos.c
+ M /trunk/src/cosh.c
+ M /trunk/src/d_div.c
+ M /trunk/src/d_sub.c
+ M /trunk/src/digamma.c
+ M /trunk/src/div.c
+ M /trunk/src/div_2si.c
+ M /trunk/src/div_2ui.c
+ M /trunk/src/div_d.c
+ M /trunk/src/div_ui.c
+ M /trunk/src/eint.c
+ M /trunk/src/erf.c
+ M /trunk/src/erfc.c
+ M /trunk/src/exp.c
+ M /trunk/src/exp2.c
+ M /trunk/src/exp3.c
+ M /trunk/src/exp_2.c
+ M /trunk/src/expm1.c
+ M /trunk/src/fma.c
+ M /trunk/src/fms.c
+ M /trunk/src/gamma.c
+ M /trunk/src/hypot.c
+ M /trunk/src/jn.c
+ M /trunk/src/li2.c
+ M /trunk/src/lngamma.c
+ M /trunk/src/log.c
+ M /trunk/src/log10.c
+ M /trunk/src/log1p.c
+ M /trunk/src/log2.c
+ M /trunk/src/logging.c
+ M /trunk/src/modf.c
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mul.c
+ M /trunk/src/mul_2si.c
+ M /trunk/src/mul_2ui.c
+ M /trunk/src/mul_d.c
+ M /trunk/src/pow.c
+ M /trunk/src/pow_si.c
+ M /trunk/src/pow_ui.c
+ M /trunk/src/pow_z.c
+ M /trunk/src/rec_sqrt.c
+ M /trunk/src/root.c
+ M /trunk/src/sin.c
+ M /trunk/src/sin_cos.c
+ M /trunk/src/sinh.c
+ M /trunk/src/sinh_cosh.c
+ M /trunk/src/sqr.c
+ M /trunk/src/sqrt.c
+ M /trunk/src/sub.c
+ M /trunk/src/sub_d.c
+ M /trunk/src/sub_ui.c
+ M /trunk/src/tan.c
+ M /trunk/src/tanh.c
+ M /trunk/src/ui_div.c
+ M /trunk/src/ui_sub.c
+ M /trunk/src/yn.c
+ M /trunk/src/zeta.c
+
+Get rid of deprecated register_printf_function function in logging system.
+------------------------------------------------------------------------
+r7573 | vlefevre | 2011-03-15 15:15:22 +0000 (Tue, 15 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/src/erfc.c
+
+[src/erfc.c] Fixed a problem (incorrect flags or possible crash) in
+extremely reduced exponent range. Support the case where mpfr_prec_t
+is larger than a long.
+------------------------------------------------------------------------
+r7572 | vlefevre | 2011-03-15 15:10:40 +0000 (Tue, 15 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/terf.c
+
+[tests/terf.c] Added some tests of the flags (no failure in them,
+thanks to the mpfr_cmp_si (x, -27282) in erfc.c, for 1b).
+------------------------------------------------------------------------
+r7571 | vlefevre | 2011-03-15 11:23:25 +0000 (Tue, 15 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tests/tgeneric.c] In failure messages, output the name of the
+tested function. This is useful for programs that have generic
+tests for several functions, such as terf.
+------------------------------------------------------------------------
+r7570 | vlefevre | 2011-03-15 10:01:59 +0000 (Tue, 15 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/terf.c
+
+[tests/terf.c] Added a testcase showing a failure due to bad flags
+in a reduced exponent range.
+------------------------------------------------------------------------
+r7568 | vlefevre | 2011-03-14 09:44:21 +0000 (Mon, 14 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/terf.c
+
+[tests/terf.c] Changed mp_exp_t (r7564) to mpfr_exp_t.
+------------------------------------------------------------------------
+r7567 | vlefevre | 2011-03-11 15:45:48 +0000 (Fri, 11 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/erfc.c
+
+[src/erfc.c] Added an assertion for future platforms (e.g. with 128-bit
+exponent type).
+------------------------------------------------------------------------
+r7566 | vlefevre | 2011-03-11 15:37:07 +0000 (Fri, 11 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/erfc.c
+
+[src/erfc.c] Fixed r7564 (comparison must really be signed).
+------------------------------------------------------------------------
+r7565 | vlefevre | 2011-03-11 15:23:59 +0000 (Fri, 11 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/terf.c
+
+[tests/terf.c] Fixed test added in r7564 for 32-bit machines.
+------------------------------------------------------------------------
+r7564 | zimmerma | 2011-03-11 15:09:06 +0000 (Fri, 11 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/src/erfc.c
+ M /trunk/tests/terf.c
+
+[erfc.c] fixed bug found by Pascal Molin: when we increase the exponent range
+ on 64-bit machines, erfc() wrongly underflows for x >= 27282
+
+------------------------------------------------------------------------
+r7561 | vlefevre | 2011-03-10 14:48:28 +0000 (Thu, 10 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Fixed the MPFR_FAST_COMPUTE_IF_SMALL_INPUT test for n == 1
+in underflow cases.
+------------------------------------------------------------------------
+r7560 | vlefevre | 2011-03-10 13:46:23 +0000 (Thu, 10 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] No need for mpfr_clear_flags (already done in MPFR_BLOCK).
+------------------------------------------------------------------------
+r7559 | vlefevre | 2011-03-10 13:44:47 +0000 (Thu, 10 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Check that no intermediate underflow or overflow occurs.
+------------------------------------------------------------------------
+r7558 | vlefevre | 2011-03-10 13:30:33 +0000 (Thu, 10 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/algorithms.tex
+
+[doc/algorithms.tex] For the Bessel function, say that the algorithm
+assumes that no underflows/overflows occur.
+------------------------------------------------------------------------
+r7556 | vlefevre | 2011-03-09 15:54:42 +0000 (Wed, 09 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/gamma.c
+
+[src/gamma.c] More robust code (for the change in r7551).
+------------------------------------------------------------------------
+r7555 | vlefevre | 2011-03-09 15:52:33 +0000 (Wed, 09 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tsin_cos.c
+
+Removed trailing spaces.
+------------------------------------------------------------------------
+r7553 | vlefevre | 2011-03-09 15:38:58 +0000 (Wed, 09 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tests/tgeneric.c] Added feature for MPFR_SUSPICIOUS_OVERFLOW to avoid
+spurious failures by defining TGENERIC_SO_TEST to some well-chosen test.
+------------------------------------------------------------------------
+r7552 | vlefevre | 2011-03-09 15:35:17 +0000 (Wed, 09 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Added a comment about MPFR_SUSPICIOUS_OVERFLOW.
+------------------------------------------------------------------------
+r7551 | vlefevre | 2011-03-09 15:30:46 +0000 (Wed, 09 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/gamma.c
+
+[src/gamma.c] Fixed the special code for tiny values.
+------------------------------------------------------------------------
+r7550 | vlefevre | 2011-03-09 15:29:44 +0000 (Wed, 09 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Corrected a test and added other tests for tiny x > 0.
+------------------------------------------------------------------------
+r7549 | vlefevre | 2011-03-09 14:57:05 +0000 (Wed, 09 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Updated a comment.
+------------------------------------------------------------------------
+r7548 | vlefevre | 2011-03-09 14:07:54 +0000 (Wed, 09 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Restore emax.
+------------------------------------------------------------------------
+r7547 | vlefevre | 2011-03-09 14:03:40 +0000 (Wed, 09 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Do not initialize x twice.
+------------------------------------------------------------------------
+r7546 | vlefevre | 2011-03-09 13:44:02 +0000 (Wed, 09 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Do not run the same test twice if emin = MPFR_EMIN_MIN.
+------------------------------------------------------------------------
+r7545 | vlefevre | 2011-03-09 13:41:51 +0000 (Wed, 09 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Added tests for tiny values, showing bugs in special
+code for such values. Run tgamma with at least an argument to get all
+the failures.
+------------------------------------------------------------------------
+r7542 | vlefevre | 2011-03-07 15:17:24 +0000 (Mon, 07 Mar 2011) | 8 lines
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Fixed mpfr_jn_k0() internal function:
+ * The prototype was incorrect: one needs "unsigned long" for n
+ (actually absn), in case absn is equal to - LONG_MIN.
+ * The formula and the code were incorrect for n = 0, due to the
+ division by n; it was yielding k0 = ULONG_MAX. The case n = 0
+ is now handled separately.
+ * Small optimization: division by log(2) -> multiplication by
+ 1/log(2).
+------------------------------------------------------------------------
+r7541 | vlefevre | 2011-03-07 14:07:47 +0000 (Mon, 07 Mar 2011) | 4 lines
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Avoid integer overflow in the computation of the initial
+working precision. This makes several tests fail, but logging shows
+that previous non-failure was due to undefined behavior due to huge
+k0 computed by mpfr_jn_k0.
+------------------------------------------------------------------------
+r7539 | vlefevre | 2011-03-07 13:03:30 +0000 (Mon, 07 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Added a comment for mpfrlint.
+------------------------------------------------------------------------
+r7538 | vlefevre | 2011-03-07 13:01:36 +0000 (Mon, 07 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Change of r7515: any mpfr_clear_* can be mentioned.
+------------------------------------------------------------------------
+r7537 | vlefevre | 2011-03-07 11:08:08 +0000 (Mon, 07 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Added comments and fixed a bug.
+------------------------------------------------------------------------
+r7536 | vlefevre | 2011-03-07 10:57:44 +0000 (Mon, 07 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Detect incorrect error analysis (that may have been the goal
+of the assertion corrected in r7534, but this wasn't documented). Added
+a FIXME comment.
+------------------------------------------------------------------------
+r7534 | vlefevre | 2011-03-07 10:40:24 +0000 (Mon, 07 Mar 2011) | 5 lines
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Fixed incorrect assertion. It could occur only
+in precision >= 2^(1+s/2), where s is the bitsize of a
+"long", e.g. p >= 2^17 = 131072 on most 32-bit machines and
+p >= 2^33 = 8,589,934,592 on most 64-bit machines. Only some
+arguments are affected (|z| between around 2^(s/2) and p/2).
+------------------------------------------------------------------------
+r7533 | vlefevre | 2011-03-07 10:13:34 +0000 (Mon, 07 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+[tests/Makefile.am] Added a comment.
+------------------------------------------------------------------------
+r7532 | vlefevre | 2011-03-07 10:07:44 +0000 (Mon, 07 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Corrected a typo.
+------------------------------------------------------------------------
+r7530 | vlefevre | 2011-03-06 10:03:21 +0000 (Sun, 06 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Improved underflow detection. Still not complete, though.
+------------------------------------------------------------------------
+r7529 | vlefevre | 2011-03-06 09:51:13 +0000 (Sun, 06 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Comments: English usage.
+------------------------------------------------------------------------
+r7528 | vlefevre | 2011-03-05 00:19:31 +0000 (Sat, 05 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/trint.c
+
+[tests/trint.c] mantissa -> significand (standard and correct term).
+------------------------------------------------------------------------
+r7527 | vlefevre | 2011-03-05 00:17:45 +0000 (Sat, 05 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/trint.c
+
+[tests/trint.c] Do not use snprintf (C99).
+------------------------------------------------------------------------
+r7526 | vlefevre | 2011-03-04 23:20:51 +0000 (Fri, 04 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Added a test to check that the snprintf function (C99)
+is not used.
+------------------------------------------------------------------------
+r7525 | demengeo | 2011-03-04 17:57:53 +0000 (Fri, 04 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/trint.c
+
+Previous extented coverage test in trint.c now self generate tests in and compare values
+------------------------------------------------------------------------
+r7524 | demengeo | 2011-03-04 14:14:13 +0000 (Fri, 04 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/trint.c
+
+Extend test coverage of mpfr_rint to 100%
+------------------------------------------------------------------------
+r7523 | zimmerma | 2011-03-03 19:27:37 +0000 (Thu, 03 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/add1sp.c
+
+[src/add1sp.c] same as previous commits
+
+------------------------------------------------------------------------
+r7522 | zimmerma | 2011-03-03 19:26:07 +0000 (Thu, 03 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/sub1sp.c
+
+[src/sub1sp.c] ibidem (see previous commit log)
+
+------------------------------------------------------------------------
+r7521 | zimmerma | 2011-03-03 19:24:25 +0000 (Thu, 03 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/add1.c
+
+[add1.c] ibidem (see previous commit log)
+
+------------------------------------------------------------------------
+r7520 | vlefevre | 2011-03-03 18:54:10 +0000 (Thu, 03 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/src/add.c
+ M /trunk/src/sub.c
+
+[src/add.c,src/sub.c] Split assertions for C90 compilers, to avoid
+too long strings generated by #expr. Problem seen with:
+ gcc -ansi -pedantic-errors
+------------------------------------------------------------------------
+r7518 | vlefevre | 2011-03-03 16:18:16 +0000 (Thu, 03 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/yn.c
+
+[src/yn.c] Minor change.
+------------------------------------------------------------------------
+r7517 | vlefevre | 2011-03-03 16:17:36 +0000 (Thu, 03 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/yn.c
+
+[src/yn.c] Extend the exponent range (code not checked concerning
+internal exceptions, such as overflows, underflows and divby0).
+------------------------------------------------------------------------
+r7516 | vlefevre | 2011-03-03 15:41:28 +0000 (Thu, 03 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/agm.c
+
+[src/agm.c] Added comments (for mpfrlint, in particular).
+------------------------------------------------------------------------
+r7515 | vlefevre | 2011-03-03 15:40:58 +0000 (Thu, 03 Mar 2011) | 4 lines
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] The use of mpfr_overflow_p, etc. is allowed if
+mpfr_clear_flags is mentioned (useful for checking purpose at the
+end of a function, but this needs an explicit mpfr_clear_flags;
+otherwise MPFR_BLOCK should still be used).
+------------------------------------------------------------------------
+r7514 | vlefevre | 2011-03-03 15:29:10 +0000 (Thu, 03 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/agm.c
+
+[src/agm.c] Completed scaling to avoid intermediate overflow/underflow.
+------------------------------------------------------------------------
+r7513 | vlefevre | 2011-03-03 12:09:34 +0000 (Thu, 03 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/src/agm.c
+
+[src/agm.c] Bug fix in error computation: in Ziv's iteration, err kept
+its value from the previous iteration instead of being reset to 0.
+Consequence: a possible loss of performance in rare cases.
+------------------------------------------------------------------------
+r7512 | vlefevre | 2011-03-03 11:30:29 +0000 (Thu, 03 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/cmp2.c
+
+[src/cmp2.c] Removed a useless assertion and updated comments.
+------------------------------------------------------------------------
+r7511 | vlefevre | 2011-03-02 14:05:39 +0000 (Wed, 02 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/agm.c
+
+[src/agm.c] Added a FIXME comment.
+------------------------------------------------------------------------
+r7510 | vlefevre | 2011-03-02 13:58:05 +0000 (Wed, 02 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/src/agm.c
+
+[src/agm.c] Updated exception checking (more informative).
+------------------------------------------------------------------------
+r7509 | vlefevre | 2011-03-02 13:54:18 +0000 (Wed, 02 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/agm.c
+
+[src/agm.c] Check internal exceptions: the error analysis may be
+incorrect in case of exception.
+------------------------------------------------------------------------
+r7508 | vlefevre | 2011-03-02 13:41:36 +0000 (Wed, 02 Mar 2011) | 2 lines
+Changed paths:
+ M /trunk/src/agm.c
+
+[src/agm.c] Implemented scaling to avoid intermediate overflow/underflow
+(but the tagm test still fails, due to a rounding error this time).
+------------------------------------------------------------------------
+r7507 | vlefevre | 2011-03-02 10:03:40 +0000 (Wed, 02 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tagm.c
+
+[tests/tagm.c] Added tests triggering intermediate underflow/overflow.
+------------------------------------------------------------------------
+r7506 | vlefevre | 2011-03-02 09:15:24 +0000 (Wed, 02 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tagm.c
+
+[tests/tagm.c] Also test the ternary value and the flags.
+------------------------------------------------------------------------
+r7505 | vlefevre | 2011-03-02 08:57:31 +0000 (Wed, 02 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tagm.c
+
+[tests/tagm.c] Corrected values (using Pari).
+------------------------------------------------------------------------
+r7504 | vlefevre | 2011-03-02 08:36:00 +0000 (Wed, 02 Mar 2011) | 3 lines
+Changed paths:
+ M /trunk/src/agm.c
+
+[src/agm.c] Extend the exponent range. This doesn't make the algorithm
+correct yet, as intermediate underflow or overflow is still possible in
+the first multiplication.
+------------------------------------------------------------------------
+r7503 | demengeo | 2011-03-01 18:10:07 +0000 (Tue, 01 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+Change some functions called in test tsin_cos.c
+------------------------------------------------------------------------
+r7502 | demengeo | 2011-03-01 17:08:11 +0000 (Tue, 01 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+Extend coverage test of mpfr_sincos_fast to 100%
+------------------------------------------------------------------------
+r7501 | demengeo | 2011-03-01 15:47:36 +0000 (Tue, 01 Mar 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tstckintc.c
+
+Extend coverage test of mpfr_custom_get_kind to 100%
+------------------------------------------------------------------------
+r7500 | vlefevre | 2011-02-25 16:39:22 +0000 (Fri, 25 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Fix: support reduced exponent ranges for small inputs.
+------------------------------------------------------------------------
+r7499 | vlefevre | 2011-02-25 16:23:48 +0000 (Fri, 25 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/src/gamma.c
+
+[src/gamma.c] Added a comment about an overflow case.
+------------------------------------------------------------------------
+r7498 | vlefevre | 2011-02-25 16:20:41 +0000 (Fri, 25 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Added tests in maximum exponent range.
+------------------------------------------------------------------------
+r7497 | vlefevre | 2011-02-25 16:15:10 +0000 (Fri, 25 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/src/gamma.c
+
+[src/gamma.c] Fixed flags when x if very small (protect from
+intermediate overflow).
+------------------------------------------------------------------------
+r7496 | vlefevre | 2011-02-25 16:08:03 +0000 (Fri, 25 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Corrected test number.
+------------------------------------------------------------------------
+r7495 | vlefevre | 2011-02-25 16:07:17 +0000 (Fri, 25 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Added a test in maximum exponent range.
+------------------------------------------------------------------------
+r7494 | vlefevre | 2011-02-25 16:02:48 +0000 (Fri, 25 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/src/gamma.c
+
+[src/gamma.c] Fixed inexact flag when x if very small.
+------------------------------------------------------------------------
+r7493 | vlefevre | 2011-02-25 16:02:04 +0000 (Fri, 25 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Added tests.
+------------------------------------------------------------------------
+r7492 | vlefevre | 2011-02-25 15:17:44 +0000 (Fri, 25 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/src/gamma.c
+ M /trunk/tests/tgamma.c
+
+[src/gamma.c] Fixed a bug occurring in reduced exponent range.
+[tests/tgamma.c] Added corresponding testcase.
+------------------------------------------------------------------------
+r7491 | vlefevre | 2011-02-25 14:50:37 +0000 (Fri, 25 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/src/lngamma.c
+
+[src/lngamma.c] Do not use MPFR_EXP after a mpfr_clear (even though
+this currently work).
+------------------------------------------------------------------------
+r7490 | vlefevre | 2011-02-25 14:23:20 +0000 (Fri, 25 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/src/rem1.c
+
+[src/rem1.c] Fixed mpfr_rem1 in reduced exponent range (the function
+is actually simplified).
+------------------------------------------------------------------------
+r7487 | zimmerma | 2011-02-25 07:49:00 +0000 (Fri, 25 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added an item
+
+------------------------------------------------------------------------
+r7486 | vlefevre | 2011-02-25 02:45:40 +0000 (Fri, 25 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/src/div_2si.c
+ M /trunk/src/div_2ui.c
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mul_2si.c
+
+Fixed mpfr_div_2si, mpfr_div_2ui and mpfr_mul_2si in some corner cases.
+------------------------------------------------------------------------
+r7485 | vlefevre | 2011-02-25 02:38:25 +0000 (Fri, 25 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+[tests/tmul_2exp.c] Small correction in output (in case of failure).
+------------------------------------------------------------------------
+r7484 | vlefevre | 2011-02-21 23:41:20 +0000 (Mon, 21 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tset_q.c
+
+[tests/tset_q.c] Corrections in function prototypes.
+------------------------------------------------------------------------
+r7483 | demengeo | 2011-02-21 16:17:14 +0000 (Mon, 21 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tgmpop.c
+
+Remove the use of mpfr_get_default_prec in some coverage test
+------------------------------------------------------------------------
+r7482 | demengeo | 2011-02-21 15:59:32 +0000 (Mon, 21 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tset_q.c
+
+Add some coverage test in tests/tset_q.c
+------------------------------------------------------------------------
+r7481 | demengeo | 2011-02-21 13:07:44 +0000 (Mon, 21 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tgmpop.c
+
+fixed coding convention of 2 tests functions
+------------------------------------------------------------------------
+r7480 | zimmerma | 2011-02-19 08:18:28 +0000 (Sat, 19 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+[tget_d.c] fixed some compiler errors and warnings
+
+------------------------------------------------------------------------
+r7479 | vlefevre | 2011-02-18 15:27:22 +0000 (Fri, 18 Feb 2011) | 3 lines
+Changed paths:
+ M /trunk/tests/tversion.c
+
+[tests/tversion.c] Split a printf into several ones to reduce the
+string length below the 509-byte limit from C90 (useful to avoid
+an error when testing with gcc -ansi -pedantic-errors).
+------------------------------------------------------------------------
+r7478 | demengeo | 2011-02-18 15:13:38 +0000 (Fri, 18 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+Extend test coverage to 100% on mpfr_z_sub and mpfr_mul_q function
+------------------------------------------------------------------------
+r7477 | demengeo | 2011-02-18 14:53:44 +0000 (Fri, 18 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+Extend test coverage on mpfr_get_d_2exp function
+------------------------------------------------------------------------
+r7476 | vlefevre | 2011-02-18 11:43:30 +0000 (Fri, 18 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+[tests/tmul_2exp.c] Also test mpfr_div_2si and mpfr_div_2ui (same bug).
+------------------------------------------------------------------------
+r7475 | vlefevre | 2011-02-18 11:37:39 +0000 (Fri, 18 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+[tests/tmul_2exp.c] Added a testcase showing a bug in mpfr_mul_2si
+(possible intermediate overflow).
+------------------------------------------------------------------------
+r7474 | vlefevre | 2011-02-18 10:29:13 +0000 (Fri, 18 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/src/zeta.c
+
+[src/zeta.c] Support zeta(eps) with |eps| very small or 0
+in extremely reduced exponent range.
+------------------------------------------------------------------------
+r7473 | vlefevre | 2011-02-18 09:54:09 +0000 (Fri, 18 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/src/atan2.c
+
+[src/atan2.c] Fix: the overflow or underflow flag was set in the case
+x = power of two and y/x overflows or underflows.
+------------------------------------------------------------------------
+r7472 | vlefevre | 2011-02-18 09:48:15 +0000 (Fri, 18 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/src/atan2.c
+
+[src/atan2.c] Support special cases in extremely reduced exponent range.
+------------------------------------------------------------------------
+r7471 | vlefevre | 2011-02-18 09:17:14 +0000 (Fri, 18 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/src/acos.c
+
+[src/acos.c] Support acos(0) in extremely reduced exponent range.
+------------------------------------------------------------------------
+r7470 | vlefevre | 2011-02-17 13:44:57 +0000 (Thu, 17 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tests/tgeneric.c] Added generic tests in a reduced exponent range.
+This currently makes 10 tests fail on a 64-bit machine.
+------------------------------------------------------------------------
+r7469 | vlefevre | 2011-02-17 13:43:31 +0000 (Thu, 17 Feb 2011) | 3 lines
+Changed paths:
+ M /trunk/tests/mpfr-test.h
+
+[tests/mpfr-test.h] Defined a SAME_VAL(X,Y) macro to test whether two
+floating-point data have the same value, seen as an element of the set
+of the floating-point data (Level 2 in the IEEE 754-2008 standard).
+------------------------------------------------------------------------
+r7468 | vlefevre | 2011-02-17 13:41:12 +0000 (Thu, 17 Feb 2011) | 3 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Defined a MPFR_EXP_FSPEC macro containing the
+format specifier for mpfr_eexp_t, to output an exponent with:
+ printf ("%" MPFR_EXP_FSPEC "d", (mpfr_eexp_t) exponent);
+------------------------------------------------------------------------
+r7467 | vlefevre | 2011-02-17 12:01:57 +0000 (Thu, 17 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tests/tgeneric.c] Reformat.
+------------------------------------------------------------------------
+r7465 | vlefevre | 2011-02-17 11:33:30 +0000 (Thu, 17 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added a warning about whitespace in the mpfr.texi file.
+------------------------------------------------------------------------
+r7463 | vlefevre | 2011-02-17 11:10:58 +0000 (Thu, 17 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Fixed spacing for the mpfr.info file.
+------------------------------------------------------------------------
+r7460 | vlefevre | 2011-02-10 01:31:16 +0000 (Thu, 10 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Detect the use of mp_ptr and mp_srcptr.
+------------------------------------------------------------------------
+r7459 | vlefevre | 2011-02-10 01:26:13 +0000 (Thu, 10 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7458 | vlefevre | 2011-02-10 01:25:00 +0000 (Thu, 10 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/src/gmp_op.c
+
+[src/gmp_op.c] Added a blank line.
+------------------------------------------------------------------------
+r7457 | demengeo | 2011-02-09 17:34:50 +0000 (Wed, 09 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/TODO
+ M /trunk/doc/mpfr.texi
+ M /trunk/src/gmp_op.c
+ M /trunk/src/mpfr.h
+ M /trunk/tests/tgmpop.c
+
+Added mpfr_z_sub (function/test/doc)
+------------------------------------------------------------------------
+r7455 | vlefevre | 2011-02-09 14:15:10 +0000 (Wed, 09 Feb 2011) | 3 lines
+Changed paths:
+ M /trunk/src/div.c
+ M /trunk/src/eq.c
+ M /trunk/src/init2.c
+ M /trunk/src/mpfr-gmp.h
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mulders.c
+ M /trunk/src/rec_sqrt.c
+ M /trunk/src/round_prec.c
+ M /trunk/src/set_d.c
+ M /trunk/src/set_prec.c
+ M /trunk/src/sqrt.c
+ M /trunk/src/urandom.c
+ M /trunk/src/urandomb.c
+ M /trunk/src/vasprintf.c
+ M /trunk/tests/random2.c
+ M /trunk/tune/speed.c
+ M /trunk/tune/tuneup.c
+
+Added new types mpfr_limb_ptr and mpfr_limb_srcptr to src/mpfr-impl.h,
+and replaced mp_ptr and mp_srcptr (GMP internals) by these 2 new types
+respectively.
+------------------------------------------------------------------------
+r7453 | vlefevre | 2011-02-08 11:43:39 +0000 (Tue, 08 Feb 2011) | 3 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Fix for Intel's compiler (ICC) under MS Windows:
+MPFR was incorrectly assuming that ICC had some extensions like
+under GNU/Linux. This made the MPFR compilation fail.
+------------------------------------------------------------------------
+r7452 | vlefevre | 2011-02-08 02:48:01 +0000 (Tue, 08 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Corrected a typo in a comment.
+------------------------------------------------------------------------
+r7451 | vlefevre | 2011-02-05 13:37:55 +0000 (Sat, 05 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] Removed incorrect note.
+------------------------------------------------------------------------
+r7450 | zimmerma | 2011-02-05 08:15:42 +0000 (Sat, 05 Feb 2011) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] added hint for VS2008 and Intel compiler v11.1
+
+------------------------------------------------------------------------
+r7448 | vlefevre | 2011-02-03 09:02:05 +0000 (Thu, 03 Feb 2011) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/configure.ac
+
+[configure.ac,Makefile.am] Clean-up and depend on GNU Automake 1.11.
+------------------------------------------------------------------------
+r7443 | vlefevre | 2011-01-31 01:53:11 +0000 (Mon, 31 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/zeta_ui.c
+ M /trunk/tests/tzeta_ui.c
+
+[src/zeta_ui.c,tests/tzeta_ui.c] Patch from Patrick Pélissier for
+the division-by-zero support in mpfr_zeta_ui (and test):
+------------------------------------------------------------------------
+r7442 | zimmerma | 2011-01-30 09:33:00 +0000 (Sun, 30 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/zeta.c
+ M /trunk/tests/tzeta.c
+
+[src/zeta.c] patch from Patrick Pelissier (problem with division by zero flag)
+
+------------------------------------------------------------------------
+r7440 | zimmerma | 2011-01-28 16:19:45 +0000 (Fri, 28 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] removed division by zero item (done)
+
+------------------------------------------------------------------------
+r7439 | zimmerma | 2011-01-28 16:18:25 +0000 (Fri, 28 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/src/get_str.c
+
+[src/get_str.c,TODO] updated comments, mpfr_get_str already supports base <= 62
+
+------------------------------------------------------------------------
+r7438 | vlefevre | 2011-01-27 17:53:35 +0000 (Thu, 27 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tj0.c
+
+[tests/tj0.c] GMP_RNDN → MPFR_RNDN.
+------------------------------------------------------------------------
+r7437 | vlefevre | 2011-01-27 17:07:48 +0000 (Thu, 27 Jan 2011) | 4 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+ M /trunk/src/subnormal.c
+ M /trunk/tests/tsubnormal.c
+
+[src/subnormal.c] Set the inexact and underflow flags when needed. Fixes
+ https://gforge.inria.fr/tracker/index.php?func=detail&aid=7958&group_id=136&atid=622
+[tests/tsubnormal.c] Improved the tests, in particular for the flags.
+[doc/mpfr.texi] Documented the change.
+------------------------------------------------------------------------
+r7436 | vlefevre | 2011-01-27 16:38:35 +0000 (Thu, 27 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Corrected order in Section "Changed Functions".
+------------------------------------------------------------------------
+r7435 | vlefevre | 2011-01-27 14:17:49 +0000 (Thu, 27 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tj0.c
+
+[tests/tj0.c] Added case for which s = 0 occurs in mpfr_jn.
+------------------------------------------------------------------------
+r7434 | vlefevre | 2011-01-27 13:54:45 +0000 (Thu, 27 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Added a log message.
+------------------------------------------------------------------------
+r7433 | vlefevre | 2011-01-27 13:47:11 +0000 (Thu, 27 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/div_ui.c
+
+[src/div_ui.c] Added logging support.
+------------------------------------------------------------------------
+r7431 | vlefevre | 2011-01-26 14:06:39 +0000 (Wed, 26 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tsum.c
+
+[tests/tsum.c] Fixed bug in test (do not set the exponent on 0).
+------------------------------------------------------------------------
+r7430 | vlefevre | 2011-01-26 13:58:44 +0000 (Wed, 26 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tsum.c
+
+[tests/tsum.c] Formatting.
+------------------------------------------------------------------------
+r7429 | vlefevre | 2011-01-26 13:58:21 +0000 (Wed, 26 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/tests/tsum.c
+
+[tests/tsum.c] Fixed get_prec_max and added some checks.
+Current failure: tab[1] is not valid.
+------------------------------------------------------------------------
+r7428 | vlefevre | 2011-01-26 13:28:10 +0000 (Wed, 26 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/sum.c
+
+[src/sum.c] Added an assertion.
+------------------------------------------------------------------------
+r7427 | vlefevre | 2011-01-26 13:12:06 +0000 (Wed, 26 Jan 2011) | 4 lines
+Changed paths:
+ M /trunk/src/check.c
+
+[src/check.c] Replaced MPFR_IS_PURE_FP by !MPFR_IS_SINGULAR, the
+former macro now has a check for validity in debug mode (r7426).
+The goal of mpfr_check is to test the validity, so that we don't
+want this check here.
+------------------------------------------------------------------------
+r7426 | vlefevre | 2011-01-26 13:05:53 +0000 (Wed, 26 Jan 2011) | 4 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] In the MPFR_IS_PURE_FP test, if positive, check that
+the number is normalized (debug mode only). This makes 2 tests fail:
+tcheck and tsum. Note: with logging active, tsum was already triggering
+an assertion failure in mpfr_get_str (via mpfr_add).
+------------------------------------------------------------------------
+r7425 | vlefevre | 2011-01-26 12:51:41 +0000 (Wed, 26 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/add.c
+
+[src/add.c] Formatting.
+------------------------------------------------------------------------
+r7423 | vlefevre | 2011-01-26 12:02:31 +0000 (Wed, 26 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/li2.c
+
+[src/li2.c] Fixed crash in mpfr_li2 when logging is used.
+------------------------------------------------------------------------
+r7421 | vlefevre | 2011-01-24 16:37:43 +0000 (Mon, 24 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Corrected a comment.
+------------------------------------------------------------------------
+r7420 | zimmerma | 2011-01-24 16:14:18 +0000 (Mon, 24 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] added notes for correctness of the algorithm used
+
+------------------------------------------------------------------------
+r7419 | vlefevre | 2011-01-24 12:41:28 +0000 (Mon, 24 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] C90 compatibility fix (empty macro arguments are undefined).
+------------------------------------------------------------------------
+r7418 | vlefevre | 2011-01-24 10:17:50 +0000 (Mon, 24 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Added an assaertion against a potential overflow (which
+probably never occurs, but this should be proved...).
+------------------------------------------------------------------------
+r7417 | zimmerma | 2011-01-24 07:21:27 +0000 (Mon, 24 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] patch from Patrick Pelissier
+
+------------------------------------------------------------------------
+r7416 | vlefevre | 2011-01-23 04:04:08 +0000 (Sun, 23 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Forgot to change an MPFR_EXP to MPFR_GET_EXP.
+------------------------------------------------------------------------
+r7415 | vlefevre | 2011-01-23 04:02:09 +0000 (Sun, 23 Jan 2011) | 3 lines
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Replaced MPFR_EXP by MPFR_GET_EXP when the value should
+really be an exponent. Removed incorrect and useless casts. Added
+an assertion to protect against potentially incorrect code.
+------------------------------------------------------------------------
+r7414 | vlefevre | 2011-01-23 03:41:39 +0000 (Sun, 23 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/jn.c
+
+[src/jn.c] Patch from Patrick Pélissier (mpfr_check_range and other).
+------------------------------------------------------------------------
+r7413 | vlefevre | 2011-01-21 14:19:35 +0000 (Fri, 21 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Update the check for mpfr_printf-like functions
+in the tests.
+------------------------------------------------------------------------
+r7412 | vlefevre | 2011-01-21 14:15:39 +0000 (Fri, 21 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+[tests/tprintf.c] Consistency.
+------------------------------------------------------------------------
+r7411 | vlefevre | 2011-01-21 13:59:12 +0000 (Fri, 21 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgrandom.c
+
+[tests/tgrandom.c] Added a comment.
+------------------------------------------------------------------------
+r7410 | vlefevre | 2011-01-21 13:54:50 +0000 (Fri, 21 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgrandom.c
+
+[tests/tgrandom.c] Protection of the mpfr_printf by #ifdef HAVE_STDARG.
+------------------------------------------------------------------------
+r7408 | vlefevre | 2011-01-20 12:13:58 +0000 (Thu, 20 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/eint.c
+
+[src/eint.c] Added a FIXME.
+------------------------------------------------------------------------
+r7406 | zimmerma | 2011-01-18 16:50:28 +0000 (Tue, 18 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/out_raw.c
+
+[src/out_raw.c] added pointer to discussion
+
+------------------------------------------------------------------------
+r7405 | vlefevre | 2011-01-17 13:11:15 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tvalist.c
+
+[tests/tvalist.c] Correction for C++ compilers.
+------------------------------------------------------------------------
+r7403 | vlefevre | 2011-01-17 04:01:56 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Added division-by-zero exception.
+------------------------------------------------------------------------
+r7402 | vlefevre | 2011-01-17 03:55:51 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Updated "To make a release".
+------------------------------------------------------------------------
+r7401 | vlefevre | 2011-01-17 03:52:41 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Update for MPFR 3.1.x.
+------------------------------------------------------------------------
+r7400 | vlefevre | 2011-01-17 03:39:24 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/grandom.c
+
+[src/grandom.c] Reformat.
+------------------------------------------------------------------------
+r7399 | vlefevre | 2011-01-17 03:36:24 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] tests/tvalist.c can use mpfr_printf-like functions.
+------------------------------------------------------------------------
+r7398 | vlefevre | 2011-01-17 03:34:40 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgrandom.c
+
+[tests/tgrandom.c] Added a FIXME: do not use mpfr_printf in the tests.
+------------------------------------------------------------------------
+r7397 | vlefevre | 2011-01-17 03:33:17 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tai.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tfrexp.c
+ M /trunk/tests/tgrandom.c
+
+[tests] Untabified and removed trailing spaces.
+------------------------------------------------------------------------
+r7396 | vlefevre | 2011-01-17 03:31:25 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/grandom.c
+ M /trunk/src/mpfr.h
+
+[src/grandom.c,src/mpfr.h] Untabified and removed trailing spaces.
+------------------------------------------------------------------------
+r7395 | vlefevre | 2011-01-17 03:29:36 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/frexp.c
+
+[src/frexp.c] Corrections.
+------------------------------------------------------------------------
+r7394 | vlefevre | 2011-01-17 03:25:50 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/out_raw.c
+
+[src/out_raw.c] Untabified.
+------------------------------------------------------------------------
+r7393 | vlefevre | 2011-01-17 03:25:07 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/out_raw.c
+
+[src/out_raw.c] Fixed some bugs on the incomplete code.
+------------------------------------------------------------------------
+r7392 | vlefevre | 2011-01-17 03:06:09 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/atan2.c
+
+[src/atan2.c] MPFR_EXP -> MPFR_GET_EXP and reformat.
+------------------------------------------------------------------------
+r7391 | vlefevre | 2011-01-17 03:05:33 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/ai.c
+
+[src/ai.c] Removed trailing spaces.
+------------------------------------------------------------------------
+r7390 | vlefevre | 2011-01-17 03:02:39 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7389 | vlefevre | 2011-01-17 03:01:30 +0000 (Mon, 17 Jan 2011) | 4 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/INSTALL
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/acinclude.m4
+ M /trunk/configure.ac
+ M /trunk/doc/FAQ.html
+ M /trunk/doc/Makefile.am
+ M /trunk/doc/faq.xsl
+ M /trunk/doc/mpfr.texi
+ M /trunk/examples/divworst.c
+ M /trunk/examples/rndo-add.c
+ M /trunk/examples/sample.c
+ M /trunk/examples/version.c
+ M /trunk/src/Makefile.am
+ M /trunk/src/abort_prec_max.c
+ M /trunk/src/acos.c
+ M /trunk/src/acosh.c
+ M /trunk/src/add.c
+ M /trunk/src/add1.c
+ M /trunk/src/add1sp.c
+ M /trunk/src/add_d.c
+ M /trunk/src/add_ui.c
+ M /trunk/src/agm.c
+ M /trunk/src/ai.c
+ M /trunk/src/asin.c
+ M /trunk/src/asinh.c
+ M /trunk/src/atan.c
+ M /trunk/src/atan2.c
+ M /trunk/src/atanh.c
+ M /trunk/src/bernoulli.c
+ M /trunk/src/buildopt.c
+ M /trunk/src/cache.c
+ M /trunk/src/cbrt.c
+ M /trunk/src/check.c
+ M /trunk/src/clear.c
+ M /trunk/src/clears.c
+ M /trunk/src/cmp.c
+ M /trunk/src/cmp2.c
+ M /trunk/src/cmp_abs.c
+ M /trunk/src/cmp_d.c
+ M /trunk/src/cmp_ld.c
+ M /trunk/src/cmp_si.c
+ M /trunk/src/cmp_ui.c
+ M /trunk/src/comparisons.c
+ M /trunk/src/const_catalan.c
+ M /trunk/src/const_euler.c
+ M /trunk/src/const_log2.c
+ M /trunk/src/const_pi.c
+ M /trunk/src/constant.c
+ M /trunk/src/copysign.c
+ M /trunk/src/cos.c
+ M /trunk/src/cosh.c
+ M /trunk/src/cot.c
+ M /trunk/src/coth.c
+ M /trunk/src/csc.c
+ M /trunk/src/csch.c
+ M /trunk/src/d_div.c
+ M /trunk/src/d_sub.c
+ M /trunk/src/digamma.c
+ M /trunk/src/dim.c
+ M /trunk/src/div.c
+ M /trunk/src/div_2exp.c
+ M /trunk/src/div_2si.c
+ M /trunk/src/div_2ui.c
+ M /trunk/src/div_d.c
+ M /trunk/src/div_ui.c
+ M /trunk/src/dump.c
+ M /trunk/src/eint.c
+ M /trunk/src/eq.c
+ M /trunk/src/erf.c
+ M /trunk/src/erfc.c
+ M /trunk/src/exceptions.c
+ M /trunk/src/exp.c
+ M /trunk/src/exp10.c
+ M /trunk/src/exp2.c
+ M /trunk/src/exp3.c
+ M /trunk/src/exp_2.c
+ M /trunk/src/expm1.c
+ M /trunk/src/extract.c
+ M /trunk/src/factorial.c
+ M /trunk/src/fits_intmax.c
+ M /trunk/src/fits_s.h
+ M /trunk/src/fits_sint.c
+ M /trunk/src/fits_slong.c
+ M /trunk/src/fits_sshort.c
+ M /trunk/src/fits_u.h
+ M /trunk/src/fits_uint.c
+ M /trunk/src/fits_uintmax.c
+ M /trunk/src/fits_ulong.c
+ M /trunk/src/fits_ushort.c
+ M /trunk/src/fma.c
+ M /trunk/src/fms.c
+ M /trunk/src/frac.c
+ M /trunk/src/free_cache.c
+ M /trunk/src/gamma.c
+ M /trunk/src/gammaonethird.c
+ M /trunk/src/gen_inverse.h
+ M /trunk/src/get_d.c
+ M /trunk/src/get_d64.c
+ M /trunk/src/get_exp.c
+ M /trunk/src/get_f.c
+ M /trunk/src/get_flt.c
+ M /trunk/src/get_ld.c
+ M /trunk/src/get_si.c
+ M /trunk/src/get_sj.c
+ M /trunk/src/get_str.c
+ M /trunk/src/get_ui.c
+ M /trunk/src/get_uj.c
+ M /trunk/src/get_z.c
+ M /trunk/src/get_z_exp.c
+ M /trunk/src/gmp_op.c
+ M /trunk/src/hypot.c
+ M /trunk/src/ieee_floats.h
+ M /trunk/src/init.c
+ M /trunk/src/init2.c
+ M /trunk/src/inits.c
+ M /trunk/src/inits2.c
+ M /trunk/src/inp_str.c
+ M /trunk/src/int_ceil_log2.c
+ M /trunk/src/isinf.c
+ M /trunk/src/isinteger.c
+ M /trunk/src/isnan.c
+ M /trunk/src/isnum.c
+ M /trunk/src/isqrt.c
+ M /trunk/src/isregular.c
+ M /trunk/src/iszero.c
+ M /trunk/src/jn.c
+ M /trunk/src/jyn_asympt.c
+ M /trunk/src/li2.c
+ M /trunk/src/lngamma.c
+ M /trunk/src/log.c
+ M /trunk/src/log10.c
+ M /trunk/src/log1p.c
+ M /trunk/src/log2.c
+ M /trunk/src/logging.c
+ M /trunk/src/min_prec.c
+ M /trunk/src/minmax.c
+ M /trunk/src/modf.c
+ M /trunk/src/mp_clz_tab.c
+ M /trunk/src/mparam_h.in
+ M /trunk/src/mpf2mpfr.h
+ M /trunk/src/mpfr-gmp.c
+ M /trunk/src/mpfr-gmp.h
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mpfr-longlong.h
+ M /trunk/src/mpfr-thread.h
+ M /trunk/src/mpfr.h
+ M /trunk/src/mpn_exp.c
+ M /trunk/src/mul.c
+ M /trunk/src/mul_2exp.c
+ M /trunk/src/mul_2si.c
+ M /trunk/src/mul_2ui.c
+ M /trunk/src/mul_d.c
+ M /trunk/src/mul_ui.c
+ M /trunk/src/mulders.c
+ M /trunk/src/neg.c
+ M /trunk/src/next.c
+ M /trunk/src/out_str.c
+ M /trunk/src/pow.c
+ M /trunk/src/pow_si.c
+ M /trunk/src/pow_ui.c
+ M /trunk/src/pow_z.c
+ M /trunk/src/powerof2.c
+ M /trunk/src/print_raw.c
+ M /trunk/src/print_rnd_mode.c
+ M /trunk/src/printf.c
+ M /trunk/src/rec_sqrt.c
+ M /trunk/src/reldiff.c
+ M /trunk/src/rem1.c
+ M /trunk/src/rint.c
+ M /trunk/src/root.c
+ M /trunk/src/round_near_x.c
+ M /trunk/src/round_p.c
+ M /trunk/src/round_prec.c
+ M /trunk/src/round_raw_generic.c
+ M /trunk/src/scale2.c
+ M /trunk/src/sec.c
+ M /trunk/src/sech.c
+ M /trunk/src/set.c
+ M /trunk/src/set_d.c
+ M /trunk/src/set_d64.c
+ M /trunk/src/set_dfl_prec.c
+ M /trunk/src/set_exp.c
+ M /trunk/src/set_f.c
+ M /trunk/src/set_flt.c
+ M /trunk/src/set_inf.c
+ M /trunk/src/set_ld.c
+ M /trunk/src/set_nan.c
+ M /trunk/src/set_prc_raw.c
+ M /trunk/src/set_prec.c
+ M /trunk/src/set_q.c
+ M /trunk/src/set_rnd.c
+ M /trunk/src/set_si.c
+ M /trunk/src/set_si_2exp.c
+ M /trunk/src/set_sj.c
+ M /trunk/src/set_str.c
+ M /trunk/src/set_str_raw.c
+ M /trunk/src/set_ui.c
+ M /trunk/src/set_ui_2exp.c
+ M /trunk/src/set_uj.c
+ M /trunk/src/set_z.c
+ M /trunk/src/set_z_exp.c
+ M /trunk/src/set_zero.c
+ M /trunk/src/setmax.c
+ M /trunk/src/setmin.c
+ M /trunk/src/setsign.c
+ M /trunk/src/sgn.c
+ M /trunk/src/si_op.c
+ M /trunk/src/signbit.c
+ M /trunk/src/sin.c
+ M /trunk/src/sin_cos.c
+ M /trunk/src/sinh.c
+ M /trunk/src/sinh_cosh.c
+ M /trunk/src/sqr.c
+ M /trunk/src/sqrt.c
+ M /trunk/src/sqrt_ui.c
+ M /trunk/src/stack_interface.c
+ M /trunk/src/strtofr.c
+ M /trunk/src/sub.c
+ M /trunk/src/sub1.c
+ M /trunk/src/sub1sp.c
+ M /trunk/src/sub_d.c
+ M /trunk/src/sub_ui.c
+ M /trunk/src/subnormal.c
+ M /trunk/src/sum.c
+ M /trunk/src/swap.c
+ M /trunk/src/tan.c
+ M /trunk/src/tanh.c
+ M /trunk/src/uceil_exp2.c
+ M /trunk/src/uceil_log2.c
+ M /trunk/src/ufloor_log2.c
+ M /trunk/src/ui_div.c
+ M /trunk/src/ui_pow.c
+ M /trunk/src/ui_pow_ui.c
+ M /trunk/src/ui_sub.c
+ M /trunk/src/urandom.c
+ M /trunk/src/urandomb.c
+ M /trunk/src/vasprintf.c
+ M /trunk/src/version.c
+ M /trunk/src/volatile.c
+ M /trunk/src/yn.c
+ M /trunk/src/zeta.c
+ M /trunk/src/zeta_ui.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/data/digamma
+ M /trunk/tests/data/li2
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/random2.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tai.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tbuildopt.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdigamma.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_flt.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tisqrt.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmin_prec.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tset_z_exp.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstdint.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/turandom.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tools/ck-version-info
+ M /trunk/tools/get_patches.sh
+ M /trunk/tune/Makefile.am
+ M /trunk/tune/bidimensional_sample.c
+ M /trunk/tune/speed.c
+ M /trunk/tune/tuneup.c
+
+Copyright notice update: added 2011 with
+ perl -pi -e 's/2010 Free Software/2010, 2011 Free Software/' **/*(^/)
+under zsh, reverting the ChangeLog file and the m4 and tools/mbench
+directories.
+------------------------------------------------------------------------
+r7388 | vlefevre | 2011-01-17 02:57:17 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Updated year in example.
+------------------------------------------------------------------------
+r7387 | vlefevre | 2011-01-17 02:51:54 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests
+
+tests: updated svn:ignore property.
+------------------------------------------------------------------------
+r7386 | vlefevre | 2011-01-17 02:26:55 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/pow.c
+
+[src/pow.c] Added an assertion.
+------------------------------------------------------------------------
+r7385 | vlefevre | 2011-01-17 02:20:19 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/td_div.c
+
+[tests/td_div.c] Consistency change.
+------------------------------------------------------------------------
+r7384 | vlefevre | 2011-01-17 02:19:11 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tdiv_d.c
+
+[tests/tdiv_d.c] Updated test of special cases.
+------------------------------------------------------------------------
+r7383 | vlefevre | 2011-01-17 02:13:23 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/log1p.c
+
+[src/log1p.c] Added support for the division-by-zero exception.
+------------------------------------------------------------------------
+r7382 | vlefevre | 2011-01-17 02:10:32 +0000 (Mon, 17 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tlog1p.c
+
+[tests/tlog1p.c] Test the flags for special cases.
+------------------------------------------------------------------------
+r7381 | vlefevre | 2011-01-17 02:04:11 +0000 (Mon, 17 Jan 2011) | 4 lines
+Changed paths:
+ M /trunk/src/atanh.c
+ M /trunk/src/cot.c
+ M /trunk/src/coth.c
+ M /trunk/src/csc.c
+ M /trunk/src/csch.c
+ M /trunk/src/digamma.c
+ M /trunk/src/eint.c
+ M /trunk/src/gamma.c
+ M /trunk/src/lngamma.c
+ M /trunk/src/log.c
+ M /trunk/src/log10.c
+ M /trunk/src/log2.c
+
+Added support for the division-by-zero exception in functions
+mpfr_atanh, mpfr_cot, mpfr_coth, mpfr_csc, mpfr_csch,
+mpfr_digamma, mpfr_eint, mpfr_gamma, mpfr_lgamma, mpfr_lngamma,
+mpfr_log, mpfr_log2 and mpfr_log10.
+------------------------------------------------------------------------
+r7380 | lfousse | 2011-01-16 21:13:28 +0000 (Sun, 16 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgrandom.c
+
+[tests/tgrandom.c] Add missing cast for malloc.
+------------------------------------------------------------------------
+r7379 | vlefevre | 2011-01-16 14:00:34 +0000 (Sun, 16 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/yn.c
+
+[src/yn.c] Added support for the division-by-zero exception.
+------------------------------------------------------------------------
+r7378 | vlefevre | 2011-01-16 13:57:55 +0000 (Sun, 16 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[src/rec_sqrt.c] Added support for the division-by-zero exception.
+------------------------------------------------------------------------
+r7377 | vlefevre | 2011-01-16 13:55:41 +0000 (Sun, 16 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/pow_si.c
+
+[src/pow_si.c] Improved robustness (in case of future changes).
+------------------------------------------------------------------------
+r7376 | vlefevre | 2011-01-16 13:51:36 +0000 (Sun, 16 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/pow.c
+ M /trunk/src/pow_si.c
+ M /trunk/src/pow_z.c
+ M /trunk/tests/tpow.c
+
+Added support for the division-by-zero exception for the power functions
+(with additional tests). (Corrected patch from Patrick.)
+------------------------------------------------------------------------
+r7375 | lfousse | 2011-01-16 00:25:40 +0000 (Sun, 16 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+ M /trunk/src/Makefile.am
+ A /trunk/src/grandom.c (from /trunk/src/urandom_gaussian.c:7374)
+ M /trunk/src/mpfr.h
+ D /trunk/src/urandom_gaussian.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tgrandom.c (from /trunk/tests/turandom_gaussian.c:7374)
+ D /trunk/tests/turandom_gaussian.c
+
+Rename mpfr_urandom_gaussian to mpfr_grandom.
+------------------------------------------------------------------------
+r7374 | vlefevre | 2011-01-15 14:33:25 +0000 (Sat, 15 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Corrections for mpfr_urandom_gaussian.
+------------------------------------------------------------------------
+r7373 | vlefevre | 2011-01-15 14:28:43 +0000 (Sat, 15 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/turandom_gaussian.c
+
+[tests/turandom_gaussian.c] Fixed C99-only code.
+------------------------------------------------------------------------
+r7372 | zimmerma | 2011-01-15 08:14:51 +0000 (Sat, 15 Jan 2011) | 5 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/TODO
+ M /trunk/doc/mpfr.texi
+ M /trunk/src/Makefile.am
+ A /trunk/src/frexp.c
+ M /trunk/src/mpfr.h
+ M /trunk/src/out_raw.c
+ M /trunk/src/urandom_gaussian.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tfrexp.c
+
+[src/frexp.c,tests/tfrexp.c] added new function mpfr_frexp
+[src/urandom_gaussian.c] fixed copyright line
+[src/out_raw.c] started writing code (work in progress, please continue if
+ you are interested)
+
+------------------------------------------------------------------------
+r7371 | lfousse | 2011-01-14 22:11:44 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Document urandom_gaussian.
+------------------------------------------------------------------------
+r7370 | lfousse | 2011-01-14 22:10:58 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+[tests/Makefile.am] Include turandom_gaussian in tests.
+------------------------------------------------------------------------
+r7369 | lfousse | 2011-01-14 22:10:44 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ A /trunk/tests/turandom_gaussian.c
+
+[tests/turandom_gaussian.c] Add tests for urandom_gaussian.
+------------------------------------------------------------------------
+r7368 | vlefevre | 2011-01-14 19:54:38 +0000 (Fri, 14 Jan 2011) | 3 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+[tests/tdiv.c] Added consistency tests between mpfr_div, mpfr_ui_div,
+mpfr_si_div, mpfr_div_ui and mpfr_div_si (check the ternary value,
+the flags and the result of the division).
+------------------------------------------------------------------------
+r7367 | vlefevre | 2011-01-14 19:52:06 +0000 (Fri, 14 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/div_ui.c
+ M /trunk/src/ui_div.c
+
+[src/ui_div.c] Fixed prototype formatting.
+[src/div_ui.c] Fixed prototype formatting. Set division-by-zero flag.
+------------------------------------------------------------------------
+r7366 | lfousse | 2011-01-14 17:46:07 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/urandom_gaussian.c
+
+[src/urandom_gaussian.c] Fix x -> xp, and scaling.
+------------------------------------------------------------------------
+r7365 | lfousse | 2011-01-14 17:15:32 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/urandom_gaussian.c
+
+[src/urandom_gaussian.c] Pick the signs of the outputs at random.
+------------------------------------------------------------------------
+r7364 | lfousse | 2011-01-14 16:52:35 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/urandom_gaussian.c
+
+[src/urandom_gaussian.c] Fix precision of temporary results.
+------------------------------------------------------------------------
+r7363 | lfousse | 2011-01-14 16:34:48 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/urandom_gaussian.c
+
+[src/urandom_gaussian.c] Add missing inits/clears.
+------------------------------------------------------------------------
+r7360 | lfousse | 2011-01-14 15:54:39 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Declare urandom_gaussian.
+------------------------------------------------------------------------
+r7359 | lfousse | 2011-01-14 15:54:38 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/Makefile.am
+
+[src/Makefile.am] Add urandom_gaussian.c to the sources.
+------------------------------------------------------------------------
+r7358 | lfousse | 2011-01-14 15:54:37 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ A /trunk/src/urandom_gaussian.c
+
+[src/urandom_gaussian] Start work on gaussian distribution.
+------------------------------------------------------------------------
+r7357 | vlefevre | 2011-01-14 15:49:37 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tests/tgeneric.c] Fixed code introduced in r7346, again.
+------------------------------------------------------------------------
+r7356 | zimmerma | 2011-01-14 15:48:46 +0000 (Fri, 14 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/sin_cos.c
+
+[sin_cos.c] moved macros to mpfr-impl.h, added README
+
+------------------------------------------------------------------------
+r7355 | zimmerma | 2011-01-14 15:40:49 +0000 (Fri, 14 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/sin_cos.c
+
+[sin_cos.c] new inexact flags computed by mpfr_check_range were lost
+
+------------------------------------------------------------------------
+r7354 | vlefevre | 2011-01-14 15:28:45 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tests/tgeneric.c] Fixed code introduced in r7346.
+------------------------------------------------------------------------
+r7353 | vlefevre | 2011-01-14 15:21:45 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tools/coverage
+
+[tools/coverage] Update from Patrick.
+------------------------------------------------------------------------
+r7352 | vlefevre | 2011-01-14 15:10:42 +0000 (Fri, 14 Jan 2011) | 4 lines
+Changed paths:
+ M /trunk/src/ui_div.c
+ M /trunk/tests/tui_div.c
+
+[src/ui_div.c] Set the division-by-zero flag.
+[tests/tui_div.c] Updated and improved the test of special cases.
+Note: tpow_all currently fails since the support of the division-by-zero
+exception is not complete yet.
+------------------------------------------------------------------------
+r7351 | vlefevre | 2011-01-14 13:43:28 +0000 (Fri, 14 Jan 2011) | 3 lines
+Changed paths:
+ M /trunk/src/div.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/tdiv.c
+
+[src/div.c] Set the division-by-zero flag.
+[tests/tdiv.c, tests/td_div.c] Updated and improved the test of special
+cases.
+------------------------------------------------------------------------
+r7348 | vlefevre | 2011-01-14 11:44:41 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tset.c
+
+[tests/tset.c] Tests didn't fail in case of error from PRINT_ERROR_IF.
+------------------------------------------------------------------------
+r7347 | vlefevre | 2011-01-14 11:37:11 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tests/tgeneric.c] Added comments.
+------------------------------------------------------------------------
+r7346 | vlefevre | 2011-01-14 11:35:27 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tests/tgeneric.c] Check the division-by-zero flag.
+------------------------------------------------------------------------
+r7345 | vlefevre | 2011-01-14 11:10:43 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/texceptions.c
+
+Improved tests/texceptions.c (mpfr_clear_*, mpfr_set_*).
+------------------------------------------------------------------------
+r7344 | vlefevre | 2011-01-14 11:03:30 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/exceptions.c
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mpfr.h
+ M /trunk/tests/texceptions.c
+
+Added support for the division-by-zero exception.
+------------------------------------------------------------------------
+r7343 | vlefevre | 2011-01-14 10:54:28 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/exceptions.c
+
+[src/exceptions.c] Fixed bad #undef's (with currently no consequences).
+------------------------------------------------------------------------
+r7342 | zimmerma | 2011-01-14 10:49:44 +0000 (Fri, 14 Jan 2011) | 3 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] removed item about inlined mpfr_neg: Patrick Pelissier tried it but it
+ does not speed things
+
+------------------------------------------------------------------------
+r7341 | vlefevre | 2011-01-14 10:47:04 +0000 (Fri, 14 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Removed an obsolete comment.
+------------------------------------------------------------------------
+r7338 | lfousse | 2011-01-13 18:39:57 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/atan2.c
+
+[src/atan2.c] "Exact" division can be inexact because of the exponent range.
+------------------------------------------------------------------------
+r7337 | zimmerma | 2011-01-13 18:14:26 +0000 (Thu, 13 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/out_raw.c
+
+[out_raw.c] exchanged bits for precision and exponent
+
+------------------------------------------------------------------------
+r7336 | zimmerma | 2011-01-13 18:13:39 +0000 (Thu, 13 Jan 2011) | 2 lines
+Changed paths:
+ A /trunk/src/out_raw.c
+
+[out_raw.c] first proposal for external format
+
+------------------------------------------------------------------------
+r7334 | vlefevre | 2011-01-13 17:05:35 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] MPFR_IS_POWER_OF_2: added parentheses.
+------------------------------------------------------------------------
+r7333 | lfousse | 2011-01-13 16:24:48 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tatan.c
+
+Add tests for special case of atan2 (x power of 2).
+------------------------------------------------------------------------
+r7332 | lfousse | 2011-01-13 16:24:41 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/atan2.c
+
+Add special case for atan2(x,y) when x is a power of 2.
+------------------------------------------------------------------------
+r7331 | lfousse | 2011-01-13 16:24:35 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+New macro MPFR_IS_POWER_OF_2.
+------------------------------------------------------------------------
+r7329 | vlefevre | 2011-01-13 16:20:48 +0000 (Thu, 13 Jan 2011) | 3 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/NEWS
+ M /trunk/acinclude.m4
+ M /trunk/configure.ac
+
+TLS support is now detected automatically. If TLS is supported, MPFR is
+built as thread safe by default. To disable TLS explicitly, configure
+MPFR with --disable-thread-safe.
+------------------------------------------------------------------------
+r7328 | lfousse | 2011-01-13 15:50:37 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tai.c
+
+Add tests for mpfr_ai special case x=0.
+------------------------------------------------------------------------
+r7327 | lfousse | 2011-01-13 15:50:30 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/ai.c
+
+Add special case for x=0 in mpfr_ai1.
+------------------------------------------------------------------------
+r7325 | zimmerma | 2011-01-13 15:38:23 +0000 (Thu, 13 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/doc/algorithms.tex
+
+[algorithms.tex] extended Lemma 2 to the case of terms of the form 1/(1+delta)
+
+------------------------------------------------------------------------
+r7323 | vlefevre | 2011-01-13 15:27:13 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tstdint.c
+ M /trunk/tests/tvalist.c
+
+tests: return 77 for skipped tests (see GNU Automake manual).
+------------------------------------------------------------------------
+r7322 | vlefevre | 2011-01-13 15:20:24 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/tests
+
+tests: updated svn:ignore property.
+------------------------------------------------------------------------
+r7321 | vlefevre | 2011-01-13 15:19:32 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/TODO
+
+TODO update after r7317 and r7320.
+------------------------------------------------------------------------
+r7320 | vlefevre | 2011-01-13 15:17:16 +0000 (Thu, 13 Jan 2011) | 3 lines
+Changed paths:
+ M /trunk/src/mpfr.h
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tvalist.c
+
+Support multiple inclusions of mpfr.h w.r.t. <stdio.h> and <stdarg.h>
+(MPFR_USE_FILE and/or MPFR_USE_VA_LIST are needed until GMP is fixed).
+Added test "tests/tvalist.c".
+------------------------------------------------------------------------
+r7319 | zimmerma | 2011-01-13 14:46:07 +0000 (Thu, 13 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr-longlong.h
+
+[src/mpfr-longlong.h] idem as previous commit for other 2 FIXME's
+
+------------------------------------------------------------------------
+r7318 | zimmerma | 2011-01-13 14:43:29 +0000 (Thu, 13 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr-longlong.h
+
+[mpfr-longlong.h] resolved one FIXME, by adding a new one :-)
+
+------------------------------------------------------------------------
+r7317 | vlefevre | 2011-01-13 14:42:53 +0000 (Thu, 13 Jan 2011) | 1 line
+Changed paths:
+ M /trunk/src/mpfr.h
+ M /trunk/tests/Makefile.am
+
+Support multiple inclusions of mpfr.h w.r.t. <stdint.h> / <inttypes.h>.
+------------------------------------------------------------------------
+r7314 | zimmerma | 2011-01-06 16:53:07 +0000 (Thu, 06 Jan 2011) | 2 lines
+Changed paths:
+ M /trunk/tools/mbench/mfv5-mpfr.cc
+ M /trunk/tools/mbench/mfv5.cc
+ M /trunk/tools/mbench/mfv5.h
+
+another patch from Patrick Pelissier to test get_ld (with export of data used)
+
+------------------------------------------------------------------------
+r7313 | zimmerma | 2011-01-06 16:44:13 +0000 (Thu, 06 Jan 2011) | 6 lines
+Changed paths:
+ M /trunk/tools/mbench/Makefile
+ M /trunk/tools/mbench/timp.h
+
+patch from Patrick Pelissier to use clock_getime instead of rdtsc
+(use "make rt" instead of "make")
+References:
+http://stackoverflow.com/questions/3388134/rdtsc-accuracy-across-cpu-cores
+http://en.wikipedia.org/wiki/Time_Stamp_Counter
+
+------------------------------------------------------------------------
+r7312 | vlefevre | 2010-12-25 17:24:58 +0000 (Sat, 25 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/get_ld.c
+
+[src/get_ld.c] Updated a comment about the last change.
+------------------------------------------------------------------------
+r7311 | vlefevre | 2010-12-25 17:08:16 +0000 (Sat, 25 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/get_ld.c
+
+[src/get_ld.c] Minor performance improvement.
+------------------------------------------------------------------------
+r7310 | vlefevre | 2010-12-19 02:00:52 +0000 (Sun, 19 Dec 2010) | 2 lines
+Changed paths:
+ M /trunk/tools/mbench/Makefile
+
+[tools/mbench/Makefile] Update due to source reorganization (r7087):
+patch from Patrick Pelissier.
+------------------------------------------------------------------------
+r7309 | vlefevre | 2010-12-17 16:29:47 +0000 (Fri, 17 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/TODO
+
+[TODO] Update (exp-int branch, internal macro).
+------------------------------------------------------------------------
+r7308 | vlefevre | 2010-12-17 16:22:37 +0000 (Fri, 17 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/sin.c
+
+[src/sin.c] Fixed failure in debug mode (missing MPFR_IS_ZERO test).
+------------------------------------------------------------------------
+r7307 | vlefevre | 2010-12-17 16:08:54 +0000 (Fri, 17 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[src/rec_sqrt.c] Improved comment.
+------------------------------------------------------------------------
+r7305 | zimmerma | 2010-12-17 15:54:55 +0000 (Fri, 17 Dec 2010) | 2 lines
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[rec_sqrt.c] put back some information lost in commit 7302
+
+------------------------------------------------------------------------
+r7304 | vlefevre | 2010-12-17 15:31:24 +0000 (Fri, 17 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/cmp2.c
+
+[src/cmp2.c] Corrected a comment.
+------------------------------------------------------------------------
+r7303 | vlefevre | 2010-12-17 15:25:04 +0000 (Fri, 17 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/cos.c
+ M /trunk/src/sin.c
+ M /trunk/src/zeta.c
+
+Replaced some MPFR_EXP by MPFR_GET_EXP.
+------------------------------------------------------------------------
+r7302 | vlefevre | 2010-12-17 13:15:46 +0000 (Fri, 17 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/rec_sqrt.c
+
+[src/rec_sqrt.c] Removed a variable that was used only once.
+------------------------------------------------------------------------
+r7301 | vlefevre | 2010-12-17 11:40:51 +0000 (Fri, 17 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Changed comment for mpfrlint.
+------------------------------------------------------------------------
+r7300 | vlefevre | 2010-12-17 11:38:36 +0000 (Fri, 17 Dec 2010) | 2 lines
+Changed paths:
+ M /trunk/src/add1.c
+ M /trunk/src/add1sp.c
+ M /trunk/src/div.c
+ M /trunk/src/div_ui.c
+ M /trunk/src/get_str.c
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mpn_exp.c
+ M /trunk/src/mul.c
+ M /trunk/src/mul_ui.c
+ M /trunk/src/mulders.c
+ M /trunk/src/rec_sqrt.c
+ M /trunk/src/round_prec.c
+ M /trunk/src/set_f.c
+ M /trunk/src/sqr.c
+ M /trunk/src/sqrt.c
+ M /trunk/src/strtofr.c
+ M /trunk/src/sub1.c
+ M /trunk/src/sub1sp.c
+ M /trunk/tools/mpfrlint
+
+Added MPFR_TMP_LIMBS_ALLOC macro and updated the source to use it.
+tools/mpfrlint: check its use instead of MPFR_TMP_ALLOC.
+------------------------------------------------------------------------
+r7299 | vlefevre | 2010-12-17 11:31:08 +0000 (Fri, 17 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/sum.c
+
+[src/sum.c] Improved readability.
+------------------------------------------------------------------------
+r7298 | vlefevre | 2010-12-17 09:40:03 +0000 (Fri, 17 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Formatting.
+------------------------------------------------------------------------
+r7297 | vlefevre | 2010-12-14 14:36:06 +0000 (Tue, 14 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/TODO
+
+[TODO] Added year on a date (the item was added on 2007-07-28 in r4707).
+------------------------------------------------------------------------
+r7296 | vlefevre | 2010-12-13 00:02:38 +0000 (Mon, 13 Dec 2010) | 2 lines
+Changed paths:
+ M /trunk/src
+
+Added configure.lineno (generated by configure) to the svn:ignore
+property of the src directory.
+------------------------------------------------------------------------
+r7295 | vlefevre | 2010-12-12 23:39:43 +0000 (Sun, 12 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Update concerning the --with-gmp-build configure option.
+------------------------------------------------------------------------
+r7294 | vlefevre | 2010-12-12 23:36:38 +0000 (Sun, 12 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] Corrected a typo from r7293.
+------------------------------------------------------------------------
+r7293 | vlefevre | 2010-12-12 23:35:04 +0000 (Sun, 12 Dec 2010) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Updated INSTALL file after the recent changes in configure.ac concerning
+the --with-gmp-build configure option.
+------------------------------------------------------------------------
+r7292 | vlefevre | 2010-12-12 23:29:50 +0000 (Sun, 12 Dec 2010) | 2 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] With --with-gmp-build, do not duplicate the include
+search paths if the GMP source and build directories are the same.
+------------------------------------------------------------------------
+r7291 | vlefevre | 2010-12-12 22:31:51 +0000 (Sun, 12 Dec 2010) | 3 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] Fixed another bug in r7289. This new version now seems
+to work with GMP's srcdir pointing to a relative directory or to an
+absolute one.
+------------------------------------------------------------------------
+r7290 | vlefevre | 2010-12-12 22:28:53 +0000 (Sun, 12 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] Fixed bug in r7289.
+------------------------------------------------------------------------
+r7289 | vlefevre | 2010-12-12 22:17:16 +0000 (Sun, 12 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] Corrected Patrick Pelissier's patch (not tested).
+------------------------------------------------------------------------
+r7288 | zimmerma | 2010-12-12 20:47:23 +0000 (Sun, 12 Dec 2010) | 4 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] patch from Patrick Pelissier to solve the problem with
+ --with-gmp-build when the GMP build directory and the GMP
+ source directory differ
+
+------------------------------------------------------------------------
+r7287 | vlefevre | 2010-12-12 11:02:00 +0000 (Sun, 12 Dec 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+[tests/Makefile.am] tversion is also run at the end (after a discussion
+with Patrick and Paul).
+------------------------------------------------------------------------
+r7286 | vlefevre | 2010-12-12 09:55:44 +0000 (Sun, 12 Dec 2010) | 4 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] Fixed two problems with --with-gmp-build:
+ * "grep -w" isn't POSIX (an error shouldn't matter with recent GMP
+ versions, as CFLAGS and CC would then be retrieved from gmp.h).
+ * "sed" was used instead of "$SED".
+------------------------------------------------------------------------
+r7279 | vlefevre | 2010-12-07 13:59:45 +0000 (Tue, 07 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] Added a section "If 'gmp.h' and 'libgmp' do not match".
+------------------------------------------------------------------------
+r7278 | vlefevre | 2010-12-07 12:51:14 +0000 (Tue, 07 Dec 2010) | 2 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] Improved warning message in case of unmatched 'gmp.h'
+and 'libgmp'.
+------------------------------------------------------------------------
+r7277 | vlefevre | 2010-12-07 11:41:09 +0000 (Tue, 07 Dec 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] Update concerning "configure".
+------------------------------------------------------------------------
+r7276 | zimmerma | 2010-12-06 20:54:14 +0000 (Mon, 06 Dec 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] fixed news for 3.0.0
+
+------------------------------------------------------------------------
+r7275 | vlefevre | 2010-12-03 08:55:24 +0000 (Fri, 03 Dec 2010) | 3 lines
+Changed paths:
+ M /trunk/tests/tversion.c
+
+[tests/tversion.c] Now fail if the versions of gmp.h and libgmp do not
+match (error message improved); previously, the warning could remain
+unnoticed, in particular with automatic installations.
+------------------------------------------------------------------------
+r7274 | schevill | 2010-11-30 16:41:38 +0000 (Tue, 30 Nov 2010) | 3 lines
+Changed paths:
+ A /trunk/tools/metaMPFR
+ A /trunk/tools/metaMPFR/metaMPFR_common.mpl
+ A /trunk/tools/metaMPFR/metaMPFR_straightforwardAlgo.mpl
+ A /trunk/tools/metaMPFR/metaMPFR_tests.mpl
+
+Added metaMPFR in the tools directory of MPFR.
+
+
+------------------------------------------------------------------------
+r7273 | vlefevre | 2010-11-29 15:35:52 +0000 (Mon, 29 Nov 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Defined MPFR_DEPRECATED to mark MPFR functions, types
+or variables as deprecated.
+------------------------------------------------------------------------
+r7272 | vlefevre | 2010-11-25 07:52:24 +0000 (Thu, 25 Nov 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tui_pow.c
+
+[tests/tui_pow.c] Updated a comment.
+------------------------------------------------------------------------
+r7271 | vlefevre | 2010-11-23 08:28:00 +0000 (Tue, 23 Nov 2010) | 1 line
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Support BSD sed.
+------------------------------------------------------------------------
+r7270 | vlefevre | 2010-11-19 08:53:09 +0000 (Fri, 19 Nov 2010) | 2 lines
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Detect the use of __mpfr_struct structure members
+in .c files.
+------------------------------------------------------------------------
+r7269 | vlefevre | 2010-11-19 08:46:38 +0000 (Fri, 19 Nov 2010) | 1 line
+Changed paths:
+ M /trunk/src/min_prec.c
+
+[src/min_prec.c] Replaced x->_mpfr_d by MPFR_MANT(x).
+------------------------------------------------------------------------
+r7268 | vlefevre | 2010-11-18 23:41:50 +0000 (Thu, 18 Nov 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Commented out the declaration of mpfr_round_raw_3
+(since this function is no longer defined).
+------------------------------------------------------------------------
+r7267 | vlefevre | 2010-11-18 23:20:59 +0000 (Thu, 18 Nov 2010) | 2 lines
+Changed paths:
+ M /trunk/src/min_prec.c
+
+[src/min_prec.c] Major simplification of mpfr_min_prec by using
+mpn_scan1 (suggestion by Andreas Enge).
+------------------------------------------------------------------------
+r7266 | vlefevre | 2010-11-15 15:20:03 +0000 (Mon, 15 Nov 2010) | 1 line
+Changed paths:
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Added a comment about mpn_sqr_n.
+------------------------------------------------------------------------
+r7265 | zimmerma | 2010-11-15 13:56:51 +0000 (Mon, 15 Nov 2010) | 2 lines
+Changed paths:
+ M /trunk/doc/algorithms.tex
+
+[algorithms.tex] replaced reference to Graillat05 by earlier one (Higham02)
+
+------------------------------------------------------------------------
+r7263 | vlefevre | 2010-11-12 11:38:42 +0000 (Fri, 12 Nov 2010) | 1 line
+Changed paths:
+ M /trunk/tools/nightly-test
+
+[tools/nightly-test] Added a comment about the use of -pedantic-errors.
+------------------------------------------------------------------------
+r7262 | vlefevre | 2010-11-10 23:17:02 +0000 (Wed, 10 Nov 2010) | 1 line
+Changed paths:
+ M /trunk/src/sub1.c
+
+[src/sub1.c] Minor simplification.
+------------------------------------------------------------------------
+r7261 | vlefevre | 2010-11-10 22:48:27 +0000 (Wed, 10 Nov 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tpow.c
+
+[tests/tpow.c] Avoid warnings if mpfr_exp_t < long.
+------------------------------------------------------------------------
+r7260 | zimmerma | 2010-11-10 20:17:17 +0000 (Wed, 10 Nov 2010) | 3 lines
+Changed paths:
+ M /trunk/src/mul.c
+
+[mul.c] fixed bug introduced in revision 7183, and reported by Brian Gladman
+ on Windows, where mpfr_exp_t has 32 bits and mpfr_limb_t has 64 bits
+
+------------------------------------------------------------------------
+r7257 | vlefevre | 2010-11-09 14:24:34 +0000 (Tue, 09 Nov 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Use only mpfr_* types in __MPFR_EXP_* macro definitions
+(should have been done in r7236).
+------------------------------------------------------------------------
+r7255 | vlefevre | 2010-11-09 13:43:29 +0000 (Tue, 09 Nov 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Changed a "void" into a "mpfr_void" in a macro definition
+(should have been done in r7236).
+------------------------------------------------------------------------
+r7254 | vlefevre | 2010-11-09 12:37:23 +0000 (Tue, 09 Nov 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+[tests/tset_si.c] Added testcase for problem fixed in r7236.
+------------------------------------------------------------------------
+r7251 | vlefevre | 2010-11-08 13:22:04 +0000 (Mon, 08 Nov 2010) | 3 lines
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Removed some useless casts that where added in r7121 and
+r7236 (such casts prevented the compiler from emitting diagnostics in
+incorrect calls).
+------------------------------------------------------------------------
+r7250 | vlefevre | 2010-11-08 12:55:16 +0000 (Mon, 08 Nov 2010) | 1 line
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+[tests/Makefile.am] Added a comment (warning about LOADLIBES).
+------------------------------------------------------------------------
+r7247 | zimmerma | 2010-10-25 13:53:16 +0000 (Mon, 25 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/taway.c
+
+[taway.c] reduced time of the test
+
+------------------------------------------------------------------------
+r7246 | vlefevre | 2010-10-25 10:00:45 +0000 (Mon, 25 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/NEWS
+
+Mentioned --enable-gmp-internals in INSTALL and NEWS.
+------------------------------------------------------------------------
+r7244 | vlefevre | 2010-10-24 13:27:47 +0000 (Sun, 24 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/tests/taway.c
+
+[tests/taway.c] Added a FIXME (test is too long on old machines).
+------------------------------------------------------------------------
+r7243 | vlefevre | 2010-10-24 12:41:01 +0000 (Sun, 24 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] Corrected comment for PowerPC.
+------------------------------------------------------------------------
+r7242 | zimmerma | 2010-10-24 08:01:49 +0000 (Sun, 24 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/src/Makefile.am
+ A /trunk/src/hppa
+ A /trunk/src/hppa/mparam.h
+ M /trunk/src/mparam_h.in
+
+added tuning parameters for HPPA (on HP-UX machine kindly provided by David
+Kirkby)
+
+------------------------------------------------------------------------
+r7241 | zimmerma | 2010-10-23 16:45:32 +0000 (Sat, 23 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/src/powerpc32/mparam.h
+
+[powerpc32/mparam.h] added more info on processor and operating system used
+
+------------------------------------------------------------------------
+r7240 | zimmerma | 2010-10-23 09:18:12 +0000 (Sat, 23 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/src/Makefile.am
+ M /trunk/src/mparam_h.in
+
+needed stuff to use src/powerpc32/mparam.h file
+(note that long double is IEEE double on PowerPC32)
+
+------------------------------------------------------------------------
+r7239 | zimmerma | 2010-10-23 09:07:33 +0000 (Sat, 23 Oct 2010) | 2 lines
+Changed paths:
+ A /trunk/src/powerpc32
+ A /trunk/src/powerpc32/mparam.h
+
+[powerpc32/mparam.h] param file for powerpc32 (made on PowerPC 604 under AIX)
+
+------------------------------------------------------------------------
+r7238 | zimmerma | 2010-10-22 14:54:43 +0000 (Fri, 22 Oct 2010) | 5 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+[tuneup.c] added cast from time_t to long, after warning under HP-UX:
+tuneup.c:1131: warning: format '%ld' expects type 'long int', but argument 3 has type 'time_t'
+tuneup.c:1133: warning: format '%ld' expects type 'long int', but argument 2 has type 'time_t'
+(I don't know if it is because time_t is unsigned, or has a different width)
+
+------------------------------------------------------------------------
+r7237 | vlefevre | 2010-10-22 13:30:50 +0000 (Fri, 22 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Added a space.
+------------------------------------------------------------------------
+r7236 | vlefevre | 2010-10-22 13:27:59 +0000 (Fri, 22 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Avoid some problems with macro expansion if the user
+defines macros with the same name as keywords.
+[doc/mpfr.texi] Document the use of macros.
+------------------------------------------------------------------------
+r7235 | schevill | 2010-10-22 10:10:37 +0000 (Fri, 22 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/src/Makefile.am
+
+Included the new /arch/mparam.h files into the dist.
+
+
+------------------------------------------------------------------------
+r7231 | schevill | 2010-10-20 16:08:04 +0000 (Wed, 20 Oct 2010) | 6 lines
+Changed paths:
+ M /trunk/src/amd/athlon/mparam.h
+ M /trunk/src/amd/k8/mparam.h
+ M /trunk/src/arm/mparam.h
+ M /trunk/src/ia64/mparam.h
+ M /trunk/src/mparam_h.in
+ M /trunk/src/powerpc64/mparam.h
+ M /trunk/src/sparc64/mparam.h
+ M /trunk/src/x86/core2/mparam.h
+ M /trunk/src/x86/mparam.h
+ M /trunk/src/x86_64/core2/mparam.h
+ M /trunk/src/x86_64/pentium4/mparam.h
+ M /trunk/tune/tuneup.c
+
+Cosmetic change: the constant MPFR_TUNE_CASE is now defined in mparam_h.in.
+Hence the files src/some-architecture/mparam.h are now simply obtained by
+performing 'make tune' on some architecture and copying the resulting
+src/mparam.h to src/some-architecture/mparam.h.
+
+
+------------------------------------------------------------------------
+r7230 | schevill | 2010-10-20 13:16:51 +0000 (Wed, 20 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+Typo.
+
+
+------------------------------------------------------------------------
+r7229 | schevill | 2010-10-20 11:40:52 +0000 (Wed, 20 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/src/amd/athlon/mparam.h
+ M /trunk/src/amd/k8/mparam.h
+ M /trunk/src/arm/mparam.h
+ M /trunk/src/ia64/mparam.h
+ M /trunk/src/mparam_h.in
+ M /trunk/src/powerpc64/mparam.h
+ M /trunk/src/sparc64/mparam.h
+ M /trunk/src/x86/core2/mparam.h
+ M /trunk/src/x86/mparam.h
+ M /trunk/src/x86_64/core2/mparam.h
+ M /trunk/src/x86_64/pentium4/mparam.h
+ M /trunk/tune/tuneup.c
+
+Up-to-date thresholds.
+
+
+------------------------------------------------------------------------
+r7228 | vlefevre | 2010-10-20 01:23:23 +0000 (Wed, 20 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tsub.c
+
+[tests/tsub.c] mp_prec_t -> mpfr_prec_t
+------------------------------------------------------------------------
+r7227 | vlefevre | 2010-10-20 01:22:38 +0000 (Wed, 20 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/src/sub1.c
+
+[src/sub1.c] Removed trailing spaces.
+------------------------------------------------------------------------
+r7226 | vlefevre | 2010-10-19 16:21:41 +0000 (Tue, 19 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_z_exp.c
+ M /trunk/tests/tsprintf.c
+
+[tests/*.c] Support the case where mpfr_exp_t is not a long int
+(but with such a future extension, one should probably provide
+a MPFR_PRIexp macro, similar to what <inttypes.h> does).
+------------------------------------------------------------------------
+r7225 | vlefevre | 2010-10-19 15:56:24 +0000 (Tue, 19 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/tests/texceptions.c
+
+[tests/texceptions.c] Added casts, in case mpfr_exp_t is not a long int.
+------------------------------------------------------------------------
+r7224 | zimmerma | 2010-10-19 15:03:32 +0000 (Tue, 19 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+[tset_ld.c] replaced hexadecimal long double constants by decimal constants
+
+------------------------------------------------------------------------
+r7223 | vlefevre | 2010-10-19 14:43:12 +0000 (Tue, 19 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+[tests/tset_ld.c] Added a FIXME for r7222 change.
+------------------------------------------------------------------------
+r7222 | zimmerma | 2010-10-19 14:22:09 +0000 (Tue, 19 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/src/set_ld.c
+ M /trunk/tests/tset_ld.c
+
+[set_ld.c] fixed bug #11300 on bug tracker
+[tset_ld.c] added corresponding tests
+
+------------------------------------------------------------------------
+r7221 | zimmerma | 2010-10-19 12:24:21 +0000 (Tue, 19 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/doc/algorithms.tex
+
+[algorithms.tex] modified proof of mpfr_sub in accordance with source code
+
+------------------------------------------------------------------------
+r7220 | zimmerma | 2010-10-19 12:06:00 +0000 (Tue, 19 Oct 2010) | 13 lines
+Changed paths:
+ A /trunk/doc/sub_tree.pdf
+
+this is a tree of all possible cases that can happen for rounding in mpfr_sub
+(file sub1.c) for rounding to nearest.
+
+The nodes at depth 1 of the tree correspond to the 3 possible cases before
+rounding: (1) sh=0, (2) sh>0 and the low sh bits are 1/2 ulp, (3) sh>0 and
+the low sh bits are 0.
+
+The nodes at depth 2 represent the possible subcases for k=0 in the rounding
+loop.
+
+The nodes at depth 3 represent the possible subcases for k=1 in the rounding
+loop.
+
+------------------------------------------------------------------------
+r7219 | zimmerma | 2010-10-19 11:12:07 +0000 (Tue, 19 Oct 2010) | 7 lines
+Changed paths:
+ M /trunk/src/sub1.c
+ M /trunk/tests/tsub.c
+
+[src/sub1.c] fixed another remaining issue in case 1d1
+ (case sh=0, i.e., the result uses a full number of limbs,
+ the first neglected limbs of b and c match,
+ and for the next limbs, low(b) > low(c)).
+ This case was incorrectly rounded up (add_one_ulp).
+[tests/tsub.c] added more test cases
+
+------------------------------------------------------------------------
+r7218 | zimmerma | 2010-10-19 11:06:38 +0000 (Tue, 19 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+[tgmpop.c] in case of error, print mpz_t in decimal instead of binary
+
+------------------------------------------------------------------------
+r7217 | zimmerma | 2010-10-19 06:36:56 +0000 (Tue, 19 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+[tuneup.c] increase maximal number of calls to speed_measure from 5 to 30
+ (seems to solve problems on gcc15)
+
+------------------------------------------------------------------------
+r7215 | vlefevre | 2010-10-18 23:51:35 +0000 (Mon, 18 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/tests/tcan_round.c
+
+[tests/tcan_round.c] Removed an incorrect cast, fixing a bug (in the
+test) that was producing a failure for GMP_CHECK_RANDOMIZE=1287710095
+on 64-bit machines (visible since mpfr_prec_t is now signed).
+------------------------------------------------------------------------
+r7214 | vlefevre | 2010-10-18 22:21:33 +0000 (Mon, 18 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/src/sub1.c
+
+[src/sub1.c] Removed trailing whitespace.
+------------------------------------------------------------------------
+r7213 | zimmerma | 2010-10-18 21:02:22 +0000 (Mon, 18 Oct 2010) | 4 lines
+Changed paths:
+ M /trunk/src/sub1.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tsub.c
+
+[sub1.c] previous fix was not incorrect (but strangely our tests cases did
+ not exhibit that)
+[tfma.c] added more test cases from Jakub Jelinek
+
+------------------------------------------------------------------------
+r7212 | zimmerma | 2010-10-18 18:54:56 +0000 (Mon, 18 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/src/sub1.c
+
+[sub1.c] fixed bug found by Jakub Jelinek (#11301 on tracker)
+
+------------------------------------------------------------------------
+r7211 | vlefevre | 2010-10-18 17:17:11 +0000 (Mon, 18 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7209 | vlefevre | 2010-10-18 16:16:39 +0000 (Mon, 18 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tsub.c
+
+[tests/tsub.c] Fixed inex test in bug20101017.
+------------------------------------------------------------------------
+r7208 | schevill | 2010-10-18 14:14:49 +0000 (Mon, 18 Oct 2010) | 9 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Mention the warning message displayed by gcc when the ABI of gcc and MPFR
+differ.
+
+Note: the message does not automatically imply the problem; however, if the
+message appears, the ABI somehow differ, so it is worth mentioning it.
+Users might look for the message in INSTALL in order to see if their problem is
+mentioned.
+
+
+------------------------------------------------------------------------
+r7206 | zimmerma | 2010-10-18 13:01:12 +0000 (Mon, 18 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] added "Notes about ABI" section
+
+------------------------------------------------------------------------
+r7205 | vlefevre | 2010-10-18 12:18:11 +0000 (Mon, 18 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tsub.c
+
+[tests/tsub.c] Updated comment of bug20101017.
+------------------------------------------------------------------------
+r7204 | vlefevre | 2010-10-18 11:59:39 +0000 (Mon, 18 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+[tests/tsub.c] Added testcase for bug found by Jakub Jelinek
+(bug 11301 on INRIAGforge).
+------------------------------------------------------------------------
+r7203 | zimmerma | 2010-10-18 09:41:37 +0000 (Mon, 18 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+[tuneup.c] print size when speed_measure fails
+
+------------------------------------------------------------------------
+r7202 | zimmerma | 2010-10-17 19:33:37 +0000 (Sun, 17 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[mpfr.texi] added that the 'N' mode rounds ties to even in the mpfr*printf
+ functions
+
+------------------------------------------------------------------------
+r7201 | schevill | 2010-10-15 15:18:18 +0000 (Fri, 15 Oct 2010) | 4 lines
+Changed paths:
+ A /trunk/src/amd
+ A /trunk/src/amd/athlon
+ A /trunk/src/amd/athlon/mparam.h
+ A /trunk/src/amd/k8
+ A /trunk/src/amd/k8/mparam.h
+ A /trunk/src/arm
+ A /trunk/src/arm/mparam.h
+ M /trunk/src/buildopt.c
+ A /trunk/src/generic
+ A /trunk/src/generic/mparam.h
+ A /trunk/src/ia64
+ A /trunk/src/ia64/mparam.h
+ M /trunk/src/mparam_h.in
+ M /trunk/src/mpfr.h
+ A /trunk/src/powerpc64
+ A /trunk/src/powerpc64/mparam.h
+ A /trunk/src/sparc64
+ A /trunk/src/sparc64/mparam.h
+ A /trunk/src/x86
+ A /trunk/src/x86/core2
+ A /trunk/src/x86/core2/mparam.h
+ A /trunk/src/x86/mparam.h
+ A /trunk/src/x86_64
+ A /trunk/src/x86_64/core2
+ A /trunk/src/x86_64/core2/mparam.h
+ A /trunk/src/x86_64/pentium4
+ A /trunk/src/x86_64/pentium4/mparam.h
+ M /trunk/tune/tuneup.c
+
+Reorganized mparam_h.in in separate files.
+Added mpfr_buildopt_tune_case function.
+
+
+------------------------------------------------------------------------
+r7200 | schevill | 2010-10-14 15:31:16 +0000 (Thu, 14 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+Modified the number of iterations in the loop of mpfr_speed_measure.
+
+
+------------------------------------------------------------------------
+r7199 | zimmerma | 2010-10-14 10:55:09 +0000 (Thu, 14 Oct 2010) | 4 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+[tuneup.c] new function mpfr_speed_measure, which calls speed_measure() several
+ times (currently 30) until there is no failure.
+ In case all 30 calls fail, give some hints to the user.
+
+------------------------------------------------------------------------
+r7198 | zimmerma | 2010-10-13 19:58:28 +0000 (Wed, 13 Oct 2010) | 5 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+[tuneup.c] try again when speed_measure returns -1.0 (i.e. fails)
+ also check return value of speed_measure in all cases
+ (was not done for mulhigh, sqrhigh and divhigh, reported
+ by Sylvain Chevillard)
+
+------------------------------------------------------------------------
+r7197 | schevill | 2010-10-12 15:39:21 +0000 (Tue, 12 Oct 2010) | 3 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+Small indication explaining what is the negative threshold for Ai.
+
+
+------------------------------------------------------------------------
+r7196 | vlefevre | 2010-10-10 20:48:51 +0000 (Sun, 10 Oct 2010) | 4 lines
+Changed paths:
+ M /trunk/src/add1.c
+ M /trunk/src/mpfr-impl.h
+
+[src/mpfr-impl.h] Added MPFR_UEXP macro to check (in debug mode) that
+a value is nonnegative before a cast to mpfr_uexp_t.
+[src/add1.c] Use the MPFR_UEXP macro to make sure that the avoided
+warning doesn't hide a real bug.
+------------------------------------------------------------------------
+r7195 | zimmerma | 2010-10-10 17:28:05 +0000 (Sun, 10 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/reuse.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tsprintf.c
+
+avoid several compiler warnings with g++
+
+------------------------------------------------------------------------
+r7194 | zimmerma | 2010-10-10 17:00:18 +0000 (Sun, 10 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/tools/nightly-test
+
+[nightly-test] added -Wno-sign-compare for g++, to avoid spurious warnings
+
+------------------------------------------------------------------------
+r7193 | zimmerma | 2010-10-10 09:04:53 +0000 (Sun, 10 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/tools/nightly-test
+
+[nightly-test] do not use -Wmissing-prototypes for g++
+
+------------------------------------------------------------------------
+r7192 | zimmerma | 2010-10-10 08:54:37 +0000 (Sun, 10 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/src/add1.c
+
+[add1.c] fixed compiler warning (from g++)
+
+------------------------------------------------------------------------
+r7191 | zimmerma | 2010-10-08 18:29:16 +0000 (Fri, 08 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[src/mulders.c] fixed comment
+
+------------------------------------------------------------------------
+r7189 | zimmerma | 2010-10-03 07:39:44 +0000 (Sun, 03 Oct 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mulders.c
+ M /trunk/src/sqrt.c
+
+[sqrt.c,mulders.c] added missing cast (detected by nightly builds with g++)
+
+------------------------------------------------------------------------
+r7188 | vlefevre | 2010-10-01 15:58:44 +0000 (Fri, 01 Oct 2010) | 1 line
+Changed paths:
+ M /trunk/src/mulders.c
+
+[src/mulders.c] Untabified.
+------------------------------------------------------------------------
+r7187 | zimmerma | 2010-09-30 19:14:00 +0000 (Thu, 30 Sep 2010) | 3 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[src/mulders.c] fixed comments about error analysis in short product,
+ and improved short division code
+
+------------------------------------------------------------------------
+r7186 | vlefevre | 2010-09-30 16:46:23 +0000 (Thu, 30 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/src/mparam_h.in
+ M /trunk/src/mpfr-gmp.h
+ M /trunk/src/mul.c
+ M /trunk/tune/tuneup.c
+
+Removed trailing spaces and untabified several files.
+------------------------------------------------------------------------
+r7185 | vlefevre | 2010-09-30 16:40:04 +0000 (Thu, 30 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/src/mul.c
+
+[src/mul.c] Added comments concerning the latest changes about mulhigh.
+------------------------------------------------------------------------
+r7184 | zimmerma | 2010-09-30 07:10:37 +0000 (Thu, 30 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[src/mulders.c] removed leftover debug stuff
+
+------------------------------------------------------------------------
+r7183 | zimmerma | 2010-09-29 16:03:04 +0000 (Wed, 29 Sep 2010) | 11 lines
+Changed paths:
+ M /trunk/src/mparam_h.in
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/mul.c
+ M /trunk/src/mulders.c
+ M /trunk/src/round_p.c
+ M /trunk/src/sqrt.c
+ M /trunk/tune/tuneup.c
+
+[src/mulders.c] added new function mpfr_divhigh_n() for short division
+ (not used yet), fixed comments and added error analysis
+ in mpfr_mulhigh_n() and mpfr_sqrhigh_n()
+[src/sqrt.c] fixed ill-placed MPFR_TMP_MARK
+[src/mparam_h.in] added default MPFR_DIVHIGH_TAB for mpfr_divhigh_n()
+[src/round_p.c] typo
+[src/mpfr-impl.h] added prototype for mpfr_divhigh_n
+[src/mul.c] added comment, simplified code
+[tune/tuneup.c] added tuning for mpfr_divhigh_n(), increased MAX_STEPS to get
+ a better tuning (will take longer), set tolerance to 1.0
+
+------------------------------------------------------------------------
+r7182 | zimmerma | 2010-09-29 13:15:33 +0000 (Wed, 29 Sep 2010) | 3 lines
+Changed paths:
+ M /trunk/configure.ac
+ M /trunk/src/mpfr-gmp.h
+ M /trunk/src/sqrt.c
+
+added new option --enable-gmp-internals to use GMP undocumented function
+(at user's own risk). So far only mpn_rootrem is used in mpfr_sqrt.
+
+------------------------------------------------------------------------
+r7181 | zimmerma | 2010-09-29 10:07:00 +0000 (Wed, 29 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/doc/README.dev
+ M /trunk/src/mpfr-gmp.h
+ M /trunk/src/sqrt.c
+
+[doc/README.dev] added comment about mpn_rootrem
+
+------------------------------------------------------------------------
+r7180 | vlefevre | 2010-09-28 23:09:34 +0000 (Tue, 28 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] Added a FIXME note about incorrect use of an internal
+GMP symbol (__gmpn_rootrem).
+------------------------------------------------------------------------
+r7179 | zimmerma | 2010-09-28 15:40:36 +0000 (Tue, 28 Sep 2010) | 4 lines
+Changed paths:
+ M /trunk/src/sqrt.c
+
+[src/sqrt.c] followup to previous commit: only compute an extra limb of the
+ square root for rounding to nearest (for directed rounding, it
+ suffices to know if the remainder is zero or not)
+
+------------------------------------------------------------------------
+r7178 | zimmerma | 2010-09-28 15:08:34 +0000 (Tue, 28 Sep 2010) | 5 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/configure.ac
+ M /trunk/src/mpfr-gmp.h
+ M /trunk/src/mpfr-impl.h
+ M /trunk/src/sqrt.c
+ M /trunk/tests/reuse.c
+
+[src/sqrt.c] now uses mpn_rootrem (if available) instead of mpn_sqrtrem since
+ mpn_rootrem is faster. Also refactored the code: now compute one
+ more limb of the square root when the target precision is a
+ multiple of GMP_NUMB_LIMB. This greatly simplifies the code.
+
+------------------------------------------------------------------------
+r7177 | zimmerma | 2010-09-28 11:40:08 +0000 (Tue, 28 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/src/sqrt.c
+
+[src/sqrt.c] simplified computation of sticky bit
+
+------------------------------------------------------------------------
+r7176 | zimmerma | 2010-09-27 11:34:08 +0000 (Mon, 27 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[mulders.c] fixed typo
+
+------------------------------------------------------------------------
+r7175 | vlefevre | 2010-09-27 10:25:08 +0000 (Mon, 27 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[src/mulders.c] Replaced MPFR_ASSERTD with constant expression
+by MPFR_ASSERTN.
+------------------------------------------------------------------------
+r7174 | vlefevre | 2010-09-27 10:21:17 +0000 (Mon, 27 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Added a test:
+Constant checking should use MPFR_ASSERTN, not MPFR_ASSERTD.
+------------------------------------------------------------------------
+r7173 | zimmerma | 2010-09-27 08:17:11 +0000 (Mon, 27 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[mulders.c] modified mpfr_sqrhigh_n threshold so that it is > n/2
+
+------------------------------------------------------------------------
+r7172 | vlefevre | 2010-09-27 00:54:13 +0000 (Mon, 27 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] Added a FIXME concerning autoconf 2.68.
+------------------------------------------------------------------------
+r7171 | zimmerma | 2010-09-25 03:57:06 +0000 (Sat, 25 Sep 2010) | 4 lines
+Changed paths:
+ M /trunk/src/mulders.c
+
+[mulders.c] use mpn_lshift instead of mpn_add_n, and improved the default
+ Mulders cutoff k beyond 1024 limbs (extrapolated from the cutoff
+ k for n=1023 on Core 2, and checked experimentally it is faster)
+
+------------------------------------------------------------------------
+r7170 | zimmerma | 2010-09-24 19:57:30 +0000 (Fri, 24 Sep 2010) | 4 lines
+Changed paths:
+ M /trunk/tune/tuneup.c
+
+[tuneup.c] changed lower bound for exp_2 threshold from MPFR_PREC_MIN (2) to
+ GMP_NUMB_BITS. Seems to be better (since for p=2 the 2nd routine
+ was sometimes already faster).
+
+------------------------------------------------------------------------
+r7169 | zimmerma | 2010-09-24 19:12:08 +0000 (Fri, 24 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mul.c
+
+[mul.c] another changes for Mulders' algorithm in case of a square
+
+------------------------------------------------------------------------
+r7168 | vlefevre | 2010-09-24 18:51:54 +0000 (Fri, 24 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/src/mul.c
+
+[src/mul.c] Change in r7166 was incomplete. Fixed suspicious code.
+------------------------------------------------------------------------
+r7167 | zimmerma | 2010-09-24 18:35:00 +0000 (Fri, 24 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mparam_h.in
+
+[mparam_h.in] updated for 64-bit Core2
+
+------------------------------------------------------------------------
+r7166 | zimmerma | 2010-09-24 18:27:25 +0000 (Fri, 24 Sep 2010) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/src/mparam_h.in
+ M /trunk/src/mul.c
+ M /trunk/src/sqr.c
+ M /trunk/tune/tuneup.c
+
+now use Mulders' algorithm also for mpfr_sqr, provides nice speed improvement
+in all functions that perform squarings
+
+------------------------------------------------------------------------
+r7165 | vlefevre | 2010-09-21 10:57:23 +0000 (Tue, 21 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] API compatibility section: noted that mpfr_urandom
+and mpfr_urandomb changed for MPFR 3.1.
+------------------------------------------------------------------------
+r7164 | zimmerma | 2010-09-21 08:50:50 +0000 (Tue, 21 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] update about "make tune"
+
+------------------------------------------------------------------------
+r7163 | vlefevre | 2010-09-21 08:43:47 +0000 (Tue, 21 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/doc/FAQ.html
+
+[doc] Updated FAQ.html with update-faq.
+------------------------------------------------------------------------
+r7159 | schevill | 2010-09-20 15:47:36 +0000 (Mon, 20 Sep 2010) | 3 lines
+Changed paths:
+ M /trunk/README
+
+Indicated the location of README.dev.
+
+
+------------------------------------------------------------------------
+r7158 | vlefevre | 2010-09-19 17:58:10 +0000 (Sun, 19 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Minor update.
+------------------------------------------------------------------------
+r7157 | zimmerma | 2010-09-19 12:32:22 +0000 (Sun, 19 Sep 2010) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] inform the users that mpfr_add_one_ulp and mpfr_sub_one_ulp will be
+ removed
+
+------------------------------------------------------------------------
+r7156 | zimmerma | 2010-09-18 19:50:36 +0000 (Sat, 18 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added efficiency item
+
+------------------------------------------------------------------------
+r7150 | zimmerma | 2010-09-16 02:56:41 +0000 (Thu, 16 Sep 2010) | 3 lines
+Changed paths:
+ M /trunk/tests/tget_flt.c
+ M /trunk/tests/tset_z_exp.c
+
+replaced calls to mpfr_printf by calls to mpfr_dump
+(mpfr_printf might not be defined)
+
+------------------------------------------------------------------------
+r7149 | zimmerma | 2010-09-16 00:41:32 +0000 (Thu, 16 Sep 2010) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/doc/mpfr.texi
+
+[NEWS,doc/mpfr.texi] updated: the GMP random functions do not depend on the
+ computer word size
+
+------------------------------------------------------------------------
+r7145 | vlefevre | 2010-09-15 15:17:09 +0000 (Wed, 15 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/tools/mpfrlint
+
+[tools/mpfrlint] Check for mpfr_printf-like functions in the tests.
+------------------------------------------------------------------------
+r7144 | vlefevre | 2010-09-15 15:15:06 +0000 (Wed, 15 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] Updated the month.
+------------------------------------------------------------------------
+r7143 | zimmerma | 2010-09-15 13:26:39 +0000 (Wed, 15 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/doc/mpfr.texi
+
+[doc/mpfr.texi] added notes for mpfr_urandom and mpfr_urandomb
+
+------------------------------------------------------------------------
+r7142 | zimmerma | 2010-09-15 09:27:38 +0000 (Wed, 15 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+[Makefile.am] updated LOADLIBES with reorganization of the sources
+
+------------------------------------------------------------------------
+r7141 | zimmerma | 2010-09-15 09:15:57 +0000 (Wed, 15 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/doc/algorithms.tex
+
+[algorithms.tex] added sections for pow_ui and root
+
+------------------------------------------------------------------------
+r7140 | zimmerma | 2010-09-15 08:30:10 +0000 (Wed, 15 Sep 2010) | 4 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/src/urandom.c
+ M /trunk/tests/turandom.c
+
+[src/urandom.c] now mpfr_urandom also returns identical values on 32-bit and
+ 64-bit machines
+[tests/turandom.c] modified corresponding test
+
+------------------------------------------------------------------------
+r7139 | zimmerma | 2010-09-15 07:47:50 +0000 (Wed, 15 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+ M /trunk/tests/turandom.c
+
+replaced mpfr_printf in tests by calls to mpfr_out_str
+
+------------------------------------------------------------------------
+r7138 | vlefevre | 2010-09-15 07:35:16 +0000 (Wed, 15 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Updated the paragraph added in r7137.
+------------------------------------------------------------------------
+r7137 | vlefevre | 2010-09-15 07:30:13 +0000 (Wed, 15 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/doc/README.dev
+
+[doc/README.dev] Added a paragraph about the use of system-dependent
+functions in the test suite.
+------------------------------------------------------------------------
+r7136 | vlefevre | 2010-09-15 07:28:34 +0000 (Wed, 15 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/src/init2.c
+ M /trunk/src/set_ld.c
+ M /trunk/src/vasprintf.c
+
+Some minor corrections in comments.
+------------------------------------------------------------------------
+r7135 | vlefevre | 2010-09-15 07:24:05 +0000 (Wed, 15 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/src/printf.c
+
+[src/printf.c] Typo in a comment.
+------------------------------------------------------------------------
+r7134 | vlefevre | 2010-09-15 07:23:25 +0000 (Wed, 15 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/src/printf.c
+
+[src/printf.c] Slight modification of a comment.
+------------------------------------------------------------------------
+r7133 | zimmerma | 2010-09-15 02:50:32 +0000 (Wed, 15 Sep 2010) | 8 lines
+Changed paths:
+ M /trunk/src/urandom.c
+ M /trunk/src/urandomb.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/turandom.c
+
+[urandomb.c] modified to leave the GMP random generator in the same state,
+ independent of GMP_NUMB_BITS
+[trandom.c] test of the above
+[urandom.c] added FIXME's
+[turandom.c] check we leave the GMP random generator in the same state,
+ independent of GMP_NUMB_BITS. Currently this fails on 64-bit
+ computers.
+
+------------------------------------------------------------------------
+r7132 | zimmerma | 2010-09-15 01:57:46 +0000 (Wed, 15 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/src/urandomb.c
+
+[urandomb.c] added comment + slight change
+
+------------------------------------------------------------------------
+r7121 | vlefevre | 2010-09-01 11:30:22 +0000 (Wed, 01 Sep 2010) | 4 lines
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Added casts to improve robustness in case of undefined
+behavior and compiler extensions based on UB (in particular -fwrapv).
+MPFR doesn't use such extensions, but these macros will be used by
+3rd-party code, where such extensions may be required.
+------------------------------------------------------------------------
+r7120 | vlefevre | 2010-09-01 11:06:07 +0000 (Wed, 01 Sep 2010) | 1 line
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Updated a comment concerning -Wconversion.
+------------------------------------------------------------------------
+r7118 | vlefevre | 2010-09-01 10:42:55 +0000 (Wed, 01 Sep 2010) | 6 lines
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Added casts to unsigned long in mpfr_cmp_si and mpfr_set_si
+macros for GCC, in order to avoid warnings in programs that use MPFR and
+are compiled with -Wconversion (suggestion by Andreas Enge); such casts
+are OK since if X is a constant expression, then (unsigned long) X is
+also a constant expression, so that the optimizations still work.
+Reformatted these macros.
+------------------------------------------------------------------------
+r7116 | vlefevre | 2010-09-01 09:25:27 +0000 (Wed, 01 Sep 2010) | 4 lines
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Fixed bug in the mpfr_cmp_ui macro for GCC (also used
+by mpfr_cmp_si), when the evaluation of the first argument yields
+side effects and the second argument is a constant expression with
+the value 0.
+------------------------------------------------------------------------
+r7115 | vlefevre | 2010-09-01 09:19:43 +0000 (Wed, 01 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+
+[tests/tcmp_ui.c] Added side-effect tests similar to those in tset_si.c,
+showing a bug in the mpfr_cmp_ui and mpfr_cmp_si macros.
+------------------------------------------------------------------------
+r7114 | vlefevre | 2010-09-01 09:07:59 +0000 (Wed, 01 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+
+[tests/tcmp_ui.c] Check mpfr_cmp_ui and mpfr_cmp_si macros against
+side effects in the arguments.
+------------------------------------------------------------------------
+r7113 | vlefevre | 2010-09-01 08:58:22 +0000 (Wed, 01 Sep 2010) | 2 lines
+Changed paths:
+ M /trunk/src/mpfr.h
+
+[src/mpfr.h] Added a comment about the macros that use
+__builtin_constant_p.
+------------------------------------------------------------------------
+r7112 | zimmerma | 2010-08-30 09:04:00 +0000 (Mon, 30 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+[tsqrt.c] improved comment, and added test sqrt(+0) == +0
+
+------------------------------------------------------------------------
+r7111 | vlefevre | 2010-08-29 19:26:00 +0000 (Sun, 29 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+[tests/tsqrt.c] Renamed check_nan() to check_singular().
+------------------------------------------------------------------------
+r7110 | vlefevre | 2010-08-29 19:23:52 +0000 (Sun, 29 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+[tests/tsqrt.c] Check that sqrt(-0) has a negative sign.
+------------------------------------------------------------------------
+r7108 | vlefevre | 2010-08-26 14:44:41 +0000 (Thu, 26 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] Replaced "patches" by "allpatches".
+------------------------------------------------------------------------
+r7107 | zimmerma | 2010-08-25 20:15:24 +0000 (Wed, 25 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/configure.ac
+
+[configure.ac] fixed typo
+
+------------------------------------------------------------------------
+r7106 | vlefevre | 2010-08-23 15:24:10 +0000 (Mon, 23 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/src/gmp_op.c
+
+[src/gmp_op.c] Extend the exponent range in mpfr_cmp_q and mpfr_cmp_f.
+------------------------------------------------------------------------
+r7105 | vlefevre | 2010-08-23 15:03:37 +0000 (Mon, 23 Aug 2010) | 5 lines
+Changed paths:
+ M /trunk/src/gmp_op.c
+
+[src/gmp_op.c] In mpfr_add_q / mpfr_sub_q, check with MPFR_ASSERTN
+that an internal overflow/underflow doesn't occur. In theory, such
+an exception is possible, but only if q has a huge numerator or
+denominator. This is not supported (note: other problems may occur
+first, such as insufficient memory).
+------------------------------------------------------------------------
+r7104 | vlefevre | 2010-08-23 14:46:44 +0000 (Mon, 23 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+[tests/tgmpop.c] Added overflow tests for mpfr_add_q / mpfr_sub_q.
+------------------------------------------------------------------------
+r7103 | vlefevre | 2010-08-23 14:03:07 +0000 (Mon, 23 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/tests.c
+
+[tests/{mpfr-test.h,tests.c}] Added flags_out function to output flags.
+------------------------------------------------------------------------
+r7102 | vlefevre | 2010-08-23 13:34:08 +0000 (Mon, 23 Aug 2010) | 3 lines
+Changed paths:
+ M /trunk/src/gmp_op.c
+ M /trunk/tests/tgmpop.c
+
+[src/gmp_op.c] Extend the exponent range in mpfr_add_q / mpfr_sub_q
+ (overflow/underflow exceptions are not supported yet).
+[tests/tgmpop.c] Added corresponding testcases.
+------------------------------------------------------------------------
+r7101 | vlefevre | 2010-08-19 12:08:41 +0000 (Thu, 19 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/src/gmp_op.c
+ M /trunk/tests/tgmpop.c
+
+[src/gmp_op.c] Fixed the Inf +/- Inf cases for mpfr_add_q / mpfr_sub_q.
+[tests/tgmpop.c] Added Inf +/- Inf tests.
+------------------------------------------------------------------------
+r7100 | thevenyp | 2010-08-19 08:56:31 +0000 (Thu, 19 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+[tests/tgmpop.c] Fix rounding mode in overflow tests
+------------------------------------------------------------------------
+r7099 | vlefevre | 2010-08-19 01:26:16 +0000 (Thu, 19 Aug 2010) | 3 lines
+Changed paths:
+ M /trunk/src/gmp_op.c
+ M /trunk/tests/tgmpop.c
+
+[src/gmp_op.c] The function mpfr_cmp_z could fail in a reduced
+exponent range.
+[tests/tgmpop.c] Added a corresponding testcase.
+------------------------------------------------------------------------
+r7098 | vlefevre | 2010-08-19 01:00:53 +0000 (Thu, 19 Aug 2010) | 3 lines
+Changed paths:
+ M /trunk/src/gmp_op.c
+ M /trunk/tests/tgmpop.c
+
+[src/gmp_op.c] The functions mpfr_mul_z, mpfr_div_z, mpfr_add_z and
+mpfr_sub_z could fail in a reduced exponent range. Fixed.
+[tests/tgmpop.c] Added corresponding testcase.
+------------------------------------------------------------------------
+r7097 | vlefevre | 2010-08-18 21:19:07 +0000 (Wed, 18 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+[tests/tgmpop.c] Disabled buggy tests.
+------------------------------------------------------------------------
+r7096 | vlefevre | 2010-08-18 13:24:30 +0000 (Wed, 18 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/src/gmp_op.c
+
+[src/gmp_op.c] Fixed the intermediate overflow case in mpfr_muldiv_z
+(for mpfr_mul_q and mpfr_div_q).
+------------------------------------------------------------------------
+r7095 | vlefevre | 2010-08-18 11:55:19 +0000 (Wed, 18 Aug 2010) | 5 lines
+Changed paths:
+ M /trunk/src/gmp_op.c
+
+[src/gmp_op.c] Added function mpfr_muldiv_z (currently static -- should
+it be in the API?) that computes y = RND(x*n/d), where n and d are mpz
+integers. Changed mpfr_mul_q and mpfr_div_q to use this function.
+Note: the code of the general case is currently the same as the old
+mpfr_mul_q/mpfr_div_q code, thus needs to be fixed.
+------------------------------------------------------------------------
+r7094 | vlefevre | 2010-08-18 08:59:58 +0000 (Wed, 18 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+[tests/tgmpop.c] Replaced GMP_RNDN by MPFR_RNDN.
+------------------------------------------------------------------------
+r7093 | vlefevre | 2010-08-18 08:29:03 +0000 (Wed, 18 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+[tests/tgmpop.c] Added testcase for mpfr_mul_q/mpfr_div_q bug noted
+in src/gmp_op.c (due to intermediate overflow).
+------------------------------------------------------------------------
+r7092 | vlefevre | 2010-08-17 15:32:53 +0000 (Tue, 17 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/src/logging.c
+
+[src/logging.c] Added a comment about register_printf_function.
+------------------------------------------------------------------------
+r7091 | vlefevre | 2010-08-17 12:45:22 +0000 (Tue, 17 Aug 2010) | 6 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/tools/ck-version-info
+
+Added tools/ck-version-info Perl script with the same license as
+Makefile.am, to check consistency concerning -version-info and
+that the -version-info value is up-to-date.
+Updated Makefile.am:
+ * In dist-hook, replaced complex sh code by a call to ck-version-info.
+ * Distribute ck-version-info (EXTRA_DIST).
+------------------------------------------------------------------------
+r7090 | vlefevre | 2010-08-17 12:30:02 +0000 (Tue, 17 Aug 2010) | 1 line
+Changed paths:
+ M /trunk
+ M /trunk/doc
+ M /trunk/src
+ M /trunk/tune
+
+Updated svn:ignore properties.
+------------------------------------------------------------------------
+r7089 | vlefevre | 2010-08-17 09:31:09 +0000 (Tue, 17 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+
+[Makefile.am] Put tools/get_patches.sh back to EXTRA_DIST.
+------------------------------------------------------------------------
+r7088 | vlefevre | 2010-08-17 09:25:39 +0000 (Tue, 17 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/src/Makefile.am
+
+[src/Makefile.am] Fixed -version-info (I forgot to increment CURRENT).
+------------------------------------------------------------------------
+r7087 | vlefevre | 2010-08-17 09:10:13 +0000 (Tue, 17 Aug 2010) | 38 lines
+Changed paths:
+ D /trunk/FAQ.html
+ M /trunk/INSTALL
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/README
+ D /trunk/README.dev
+ M /trunk/TODO
+ D /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ D /trunk/acos.c
+ D /trunk/acosh.c
+ D /trunk/add.c
+ D /trunk/add1.c
+ D /trunk/add1sp.c
+ D /trunk/add_d.c
+ D /trunk/add_ui.c
+ D /trunk/agm.c
+ D /trunk/ai.c
+ D /trunk/algorithm2e.sty
+ D /trunk/algorithms.bib
+ D /trunk/algorithms.tex
+ D /trunk/asin.c
+ D /trunk/asinh.c
+ D /trunk/atan.c
+ D /trunk/atan2.c
+ D /trunk/atanh.c
+ D /trunk/bernoulli.c
+ D /trunk/bidimensional_sample.c
+ D /trunk/buildopt.c
+ D /trunk/cache.c
+ D /trunk/cbrt.c
+ D /trunk/check.c
+ D /trunk/check_inits_clears
+ D /trunk/clear.c
+ D /trunk/clears.c
+ D /trunk/cmp.c
+ D /trunk/cmp2.c
+ D /trunk/cmp_abs.c
+ D /trunk/cmp_d.c
+ D /trunk/cmp_ld.c
+ D /trunk/cmp_si.c
+ D /trunk/cmp_ui.c
+ D /trunk/comparisons.c
+ A /trunk/configure.ac (from /trunk/configure.in:7086)
+ D /trunk/configure.in
+ D /trunk/const_catalan.c
+ D /trunk/const_euler.c
+ D /trunk/const_log2.c
+ D /trunk/const_pi.c
+ D /trunk/constant.c
+ D /trunk/copysign.c
+ D /trunk/cos.c
+ D /trunk/cosh.c
+ D /trunk/cot.c
+ D /trunk/coth.c
+ D /trunk/coverage
+ D /trunk/cputime.h
+ D /trunk/csc.c
+ D /trunk/csch.c
+ D /trunk/d_div.c
+ D /trunk/d_sub.c
+ D /trunk/digamma.c
+ D /trunk/dim.c
+ D /trunk/div-short.c
+ D /trunk/div.c
+ D /trunk/div_2exp.c
+ D /trunk/div_2si.c
+ D /trunk/div_2ui.c
+ D /trunk/div_d.c
+ D /trunk/div_ui.c
+ A /trunk/doc
+ A /trunk/doc/FAQ.html (from /trunk/FAQ.html:7086)
+ A /trunk/doc/Makefile.am
+ A /trunk/doc/README.dev (from /trunk/README.dev:7086)
+ A /trunk/doc/algorithm2e.sty (from /trunk/algorithm2e.sty:7086)
+ A /trunk/doc/algorithms.bib (from /trunk/algorithms.bib:7086)
+ A /trunk/doc/algorithms.tex (from /trunk/algorithms.tex:7086)
+ A /trunk/doc/faq.xsl (from /trunk/faq.xsl:7086)
+ A /trunk/doc/fdl.texi (from /trunk/fdl.texi:7086)
+ A /trunk/doc/mpfr.texi (from /trunk/mpfr.texi:7086)
+ A /trunk/doc/update-faq (from /trunk/update-faq:7086)
+ D /trunk/dump.c
+ D /trunk/eint.c
+ D /trunk/eq.c
+ D /trunk/erf.c
+ D /trunk/erfc.c
+ D /trunk/exceptions.c
+ D /trunk/exp.c
+ D /trunk/exp10.c
+ D /trunk/exp2.c
+ D /trunk/exp3.c
+ D /trunk/exp_2.c
+ D /trunk/expm1.c
+ D /trunk/extract.c
+ D /trunk/factorial.c
+ D /trunk/faq.xsl
+ D /trunk/fdl.texi
+ D /trunk/fits_intmax.c
+ D /trunk/fits_s.h
+ D /trunk/fits_sint.c
+ D /trunk/fits_slong.c
+ D /trunk/fits_sshort.c
+ D /trunk/fits_u.h
+ D /trunk/fits_uint.c
+ D /trunk/fits_uintmax.c
+ D /trunk/fits_ulong.c
+ D /trunk/fits_ushort.c
+ D /trunk/fma.c
+ D /trunk/fms.c
+ D /trunk/frac.c
+ D /trunk/free_cache.c
+ D /trunk/gamma.c
+ D /trunk/gammaonethird.c
+ D /trunk/gen_inverse.h
+ D /trunk/get_d.c
+ D /trunk/get_d64.c
+ D /trunk/get_exp.c
+ D /trunk/get_f.c
+ D /trunk/get_flt.c
+ D /trunk/get_ld.c
+ D /trunk/get_patches.sh
+ D /trunk/get_si.c
+ D /trunk/get_sj.c
+ D /trunk/get_str.c
+ D /trunk/get_ui.c
+ D /trunk/get_uj.c
+ D /trunk/get_z.c
+ D /trunk/get_z_exp.c
+ D /trunk/gmp_op.c
+ D /trunk/hypot.c
+ D /trunk/ieee_floats.h
+ D /trunk/init.c
+ D /trunk/init2.c
+ D /trunk/inits.c
+ D /trunk/inits2.c
+ D /trunk/inp_str.c
+ D /trunk/int_ceil_log2.c
+ D /trunk/isinf.c
+ D /trunk/isinteger.c
+ D /trunk/isnan.c
+ D /trunk/isnum.c
+ D /trunk/isqrt.c
+ D /trunk/isregular.c
+ D /trunk/iszero.c
+ D /trunk/jn.c
+ D /trunk/jyn_asympt.c
+ D /trunk/li2.c
+ D /trunk/lngamma.c
+ D /trunk/log.c
+ D /trunk/log10.c
+ D /trunk/log1p.c
+ D /trunk/log2.c
+ D /trunk/logging.c
+ D /trunk/mbench
+ D /trunk/min_prec.c
+ D /trunk/minmax.c
+ D /trunk/modf.c
+ D /trunk/mp_clz_tab.c
+ D /trunk/mparam_h.in
+ D /trunk/mpf2mpfr.h
+ D /trunk/mpfr-gmp.c
+ D /trunk/mpfr-gmp.h
+ D /trunk/mpfr-impl.h
+ D /trunk/mpfr-longlong.h
+ D /trunk/mpfr-thread.h
+ D /trunk/mpfr.h
+ D /trunk/mpfr.texi
+ D /trunk/mpfrlint
+ D /trunk/mpn_exp.c
+ D /trunk/mul.c
+ D /trunk/mul_2exp.c
+ D /trunk/mul_2si.c
+ D /trunk/mul_2ui.c
+ D /trunk/mul_d.c
+ D /trunk/mul_ui.c
+ D /trunk/mulders.c
+ D /trunk/neg.c
+ D /trunk/next.c
+ D /trunk/nightly-test
+ A /trunk/other
+ A /trunk/other/cputime.h (from /trunk/cputime.h:7086)
+ A /trunk/other/div-short.c (from /trunk/div-short.c:7086)
+ D /trunk/out_str.c
+ D /trunk/pow.c
+ D /trunk/pow_si.c
+ D /trunk/pow_ui.c
+ D /trunk/pow_z.c
+ D /trunk/powerof2.c
+ D /trunk/print_raw.c
+ D /trunk/print_rnd_mode.c
+ D /trunk/printf.c
+ D /trunk/rec_sqrt.c
+ D /trunk/reldiff.c
+ D /trunk/rem1.c
+ D /trunk/replace_all
+ D /trunk/rint.c
+ D /trunk/root.c
+ D /trunk/round_near_x.c
+ D /trunk/round_p.c
+ D /trunk/round_prec.c
+ D /trunk/round_raw_generic.c
+ D /trunk/scale2.c
+ D /trunk/sec.c
+ D /trunk/sech.c
+ D /trunk/set.c
+ D /trunk/set_d.c
+ D /trunk/set_d64.c
+ D /trunk/set_dfl_prec.c
+ D /trunk/set_exp.c
+ D /trunk/set_f.c
+ D /trunk/set_flt.c
+ D /trunk/set_inf.c
+ D /trunk/set_ld.c
+ D /trunk/set_nan.c
+ D /trunk/set_prc_raw.c
+ D /trunk/set_prec.c
+ D /trunk/set_q.c
+ D /trunk/set_rnd.c
+ D /trunk/set_si.c
+ D /trunk/set_si_2exp.c
+ D /trunk/set_sj.c
+ D /trunk/set_str.c
+ D /trunk/set_str_raw.c
+ D /trunk/set_ui.c
+ D /trunk/set_ui_2exp.c
+ D /trunk/set_uj.c
+ D /trunk/set_z.c
+ D /trunk/set_z_exp.c
+ D /trunk/set_zero.c
+ D /trunk/setmax.c
+ D /trunk/setmin.c
+ D /trunk/setsign.c
+ D /trunk/sgn.c
+ D /trunk/si_op.c
+ D /trunk/signbit.c
+ D /trunk/sin.c
+ D /trunk/sin_cos.c
+ D /trunk/sinh.c
+ D /trunk/sinh_cosh.c
+ D /trunk/speed.c
+ D /trunk/sqr.c
+ D /trunk/sqrt.c
+ D /trunk/sqrt_ui.c
+ A /trunk/src
+ A /trunk/src/Makefile.am (from /trunk/Makefile.am:7086)
+ A /trunk/src/abort_prec_max.c (from /trunk/abort_prec_max.c:7086)
+ A /trunk/src/acos.c (from /trunk/acos.c:7086)
+ A /trunk/src/acosh.c (from /trunk/acosh.c:7086)
+ A /trunk/src/add.c (from /trunk/add.c:7086)
+ A /trunk/src/add1.c (from /trunk/add1.c:7086)
+ A /trunk/src/add1sp.c (from /trunk/add1sp.c:7086)
+ A /trunk/src/add_d.c (from /trunk/add_d.c:7086)
+ A /trunk/src/add_ui.c (from /trunk/add_ui.c:7086)
+ A /trunk/src/agm.c (from /trunk/agm.c:7086)
+ A /trunk/src/ai.c (from /trunk/ai.c:7086)
+ A /trunk/src/asin.c (from /trunk/asin.c:7086)
+ A /trunk/src/asinh.c (from /trunk/asinh.c:7086)
+ A /trunk/src/atan.c (from /trunk/atan.c:7086)
+ A /trunk/src/atan2.c (from /trunk/atan2.c:7086)
+ A /trunk/src/atanh.c (from /trunk/atanh.c:7086)
+ A /trunk/src/bernoulli.c (from /trunk/bernoulli.c:7086)
+ A /trunk/src/buildopt.c (from /trunk/buildopt.c:7086)
+ A /trunk/src/cache.c (from /trunk/cache.c:7086)
+ A /trunk/src/cbrt.c (from /trunk/cbrt.c:7086)
+ A /trunk/src/check.c (from /trunk/check.c:7086)
+ A /trunk/src/clear.c (from /trunk/clear.c:7086)
+ A /trunk/src/clears.c (from /trunk/clears.c:7086)
+ A /trunk/src/cmp.c (from /trunk/cmp.c:7086)
+ A /trunk/src/cmp2.c (from /trunk/cmp2.c:7086)
+ A /trunk/src/cmp_abs.c (from /trunk/cmp_abs.c:7086)
+ A /trunk/src/cmp_d.c (from /trunk/cmp_d.c:7086)
+ A /trunk/src/cmp_ld.c (from /trunk/cmp_ld.c:7086)
+ A /trunk/src/cmp_si.c (from /trunk/cmp_si.c:7086)
+ A /trunk/src/cmp_ui.c (from /trunk/cmp_ui.c:7086)
+ A /trunk/src/comparisons.c (from /trunk/comparisons.c:7086)
+ A /trunk/src/const_catalan.c (from /trunk/const_catalan.c:7086)
+ A /trunk/src/const_euler.c (from /trunk/const_euler.c:7086)
+ A /trunk/src/const_log2.c (from /trunk/const_log2.c:7086)
+ A /trunk/src/const_pi.c (from /trunk/const_pi.c:7086)
+ A /trunk/src/constant.c (from /trunk/constant.c:7086)
+ A /trunk/src/copysign.c (from /trunk/copysign.c:7086)
+ A /trunk/src/cos.c (from /trunk/cos.c:7086)
+ A /trunk/src/cosh.c (from /trunk/cosh.c:7086)
+ A /trunk/src/cot.c (from /trunk/cot.c:7086)
+ A /trunk/src/coth.c (from /trunk/coth.c:7086)
+ A /trunk/src/csc.c (from /trunk/csc.c:7086)
+ A /trunk/src/csch.c (from /trunk/csch.c:7086)
+ A /trunk/src/d_div.c (from /trunk/d_div.c:7086)
+ A /trunk/src/d_sub.c (from /trunk/d_sub.c:7086)
+ A /trunk/src/digamma.c (from /trunk/digamma.c:7086)
+ A /trunk/src/dim.c (from /trunk/dim.c:7086)
+ A /trunk/src/div.c (from /trunk/div.c:7086)
+ A /trunk/src/div_2exp.c (from /trunk/div_2exp.c:7086)
+ A /trunk/src/div_2si.c (from /trunk/div_2si.c:7086)
+ A /trunk/src/div_2ui.c (from /trunk/div_2ui.c:7086)
+ A /trunk/src/div_d.c (from /trunk/div_d.c:7086)
+ A /trunk/src/div_ui.c (from /trunk/div_ui.c:7086)
+ A /trunk/src/dump.c (from /trunk/dump.c:7086)
+ A /trunk/src/eint.c (from /trunk/eint.c:7086)
+ A /trunk/src/eq.c (from /trunk/eq.c:7086)
+ A /trunk/src/erf.c (from /trunk/erf.c:7086)
+ A /trunk/src/erfc.c (from /trunk/erfc.c:7086)
+ A /trunk/src/exceptions.c (from /trunk/exceptions.c:7086)
+ A /trunk/src/exp.c (from /trunk/exp.c:7086)
+ A /trunk/src/exp10.c (from /trunk/exp10.c:7086)
+ A /trunk/src/exp2.c (from /trunk/exp2.c:7086)
+ A /trunk/src/exp3.c (from /trunk/exp3.c:7086)
+ A /trunk/src/exp_2.c (from /trunk/exp_2.c:7086)
+ A /trunk/src/expm1.c (from /trunk/expm1.c:7086)
+ A /trunk/src/extract.c (from /trunk/extract.c:7086)
+ A /trunk/src/factorial.c (from /trunk/factorial.c:7086)
+ A /trunk/src/fits_intmax.c (from /trunk/fits_intmax.c:7086)
+ A /trunk/src/fits_s.h (from /trunk/fits_s.h:7086)
+ A /trunk/src/fits_sint.c (from /trunk/fits_sint.c:7086)
+ A /trunk/src/fits_slong.c (from /trunk/fits_slong.c:7086)
+ A /trunk/src/fits_sshort.c (from /trunk/fits_sshort.c:7086)
+ A /trunk/src/fits_u.h (from /trunk/fits_u.h:7086)
+ A /trunk/src/fits_uint.c (from /trunk/fits_uint.c:7086)
+ A /trunk/src/fits_uintmax.c (from /trunk/fits_uintmax.c:7086)
+ A /trunk/src/fits_ulong.c (from /trunk/fits_ulong.c:7086)
+ A /trunk/src/fits_ushort.c (from /trunk/fits_ushort.c:7086)
+ A /trunk/src/fma.c (from /trunk/fma.c:7086)
+ A /trunk/src/fms.c (from /trunk/fms.c:7086)
+ A /trunk/src/frac.c (from /trunk/frac.c:7086)
+ A /trunk/src/free_cache.c (from /trunk/free_cache.c:7086)
+ A /trunk/src/gamma.c (from /trunk/gamma.c:7086)
+ A /trunk/src/gammaonethird.c (from /trunk/gammaonethird.c:7086)
+ A /trunk/src/gen_inverse.h (from /trunk/gen_inverse.h:7086)
+ A /trunk/src/get_d.c (from /trunk/get_d.c:7086)
+ A /trunk/src/get_d64.c (from /trunk/get_d64.c:7086)
+ A /trunk/src/get_exp.c (from /trunk/get_exp.c:7086)
+ A /trunk/src/get_f.c (from /trunk/get_f.c:7086)
+ A /trunk/src/get_flt.c (from /trunk/get_flt.c:7086)
+ A /trunk/src/get_ld.c (from /trunk/get_ld.c:7086)
+ A /trunk/src/get_si.c (from /trunk/get_si.c:7086)
+ A /trunk/src/get_sj.c (from /trunk/get_sj.c:7086)
+ A /trunk/src/get_str.c (from /trunk/get_str.c:7086)
+ A /trunk/src/get_ui.c (from /trunk/get_ui.c:7086)
+ A /trunk/src/get_uj.c (from /trunk/get_uj.c:7086)
+ A /trunk/src/get_z.c (from /trunk/get_z.c:7086)
+ A /trunk/src/get_z_exp.c (from /trunk/get_z_exp.c:7086)
+ A /trunk/src/gmp_op.c (from /trunk/gmp_op.c:7086)
+ A /trunk/src/hypot.c (from /trunk/hypot.c:7086)
+ A /trunk/src/ieee_floats.h (from /trunk/ieee_floats.h:7086)
+ A /trunk/src/init.c (from /trunk/init.c:7086)
+ A /trunk/src/init2.c (from /trunk/init2.c:7086)
+ A /trunk/src/inits.c (from /trunk/inits.c:7086)
+ A /trunk/src/inits2.c (from /trunk/inits2.c:7086)
+ A /trunk/src/inp_str.c (from /trunk/inp_str.c:7086)
+ A /trunk/src/int_ceil_log2.c (from /trunk/int_ceil_log2.c:7086)
+ A /trunk/src/isinf.c (from /trunk/isinf.c:7086)
+ A /trunk/src/isinteger.c (from /trunk/isinteger.c:7086)
+ A /trunk/src/isnan.c (from /trunk/isnan.c:7086)
+ A /trunk/src/isnum.c (from /trunk/isnum.c:7086)
+ A /trunk/src/isqrt.c (from /trunk/isqrt.c:7086)
+ A /trunk/src/isregular.c (from /trunk/isregular.c:7086)
+ A /trunk/src/iszero.c (from /trunk/iszero.c:7086)
+ A /trunk/src/jn.c (from /trunk/jn.c:7086)
+ A /trunk/src/jyn_asympt.c (from /trunk/jyn_asympt.c:7086)
+ A /trunk/src/li2.c (from /trunk/li2.c:7086)
+ A /trunk/src/lngamma.c (from /trunk/lngamma.c:7086)
+ A /trunk/src/log.c (from /trunk/log.c:7086)
+ A /trunk/src/log10.c (from /trunk/log10.c:7086)
+ A /trunk/src/log1p.c (from /trunk/log1p.c:7086)
+ A /trunk/src/log2.c (from /trunk/log2.c:7086)
+ A /trunk/src/logging.c (from /trunk/logging.c:7086)
+ A /trunk/src/min_prec.c (from /trunk/min_prec.c:7086)
+ A /trunk/src/minmax.c (from /trunk/minmax.c:7086)
+ A /trunk/src/modf.c (from /trunk/modf.c:7086)
+ A /trunk/src/mp_clz_tab.c (from /trunk/mp_clz_tab.c:7086)
+ A /trunk/src/mparam_h.in (from /trunk/mparam_h.in:7086)
+ A /trunk/src/mpf2mpfr.h (from /trunk/mpf2mpfr.h:7086)
+ A /trunk/src/mpfr-gmp.c (from /trunk/mpfr-gmp.c:7086)
+ A /trunk/src/mpfr-gmp.h (from /trunk/mpfr-gmp.h:7086)
+ A /trunk/src/mpfr-impl.h (from /trunk/mpfr-impl.h:7086)
+ A /trunk/src/mpfr-longlong.h (from /trunk/mpfr-longlong.h:7086)
+ A /trunk/src/mpfr-thread.h (from /trunk/mpfr-thread.h:7086)
+ A /trunk/src/mpfr.h (from /trunk/mpfr.h:7086)
+ A /trunk/src/mpn_exp.c (from /trunk/mpn_exp.c:7086)
+ A /trunk/src/mul.c (from /trunk/mul.c:7086)
+ A /trunk/src/mul_2exp.c (from /trunk/mul_2exp.c:7086)
+ A /trunk/src/mul_2si.c (from /trunk/mul_2si.c:7086)
+ A /trunk/src/mul_2ui.c (from /trunk/mul_2ui.c:7086)
+ A /trunk/src/mul_d.c (from /trunk/mul_d.c:7086)
+ A /trunk/src/mul_ui.c (from /trunk/mul_ui.c:7086)
+ A /trunk/src/mulders.c (from /trunk/mulders.c:7086)
+ A /trunk/src/neg.c (from /trunk/neg.c:7086)
+ A /trunk/src/next.c (from /trunk/next.c:7086)
+ A /trunk/src/out_str.c (from /trunk/out_str.c:7086)
+ A /trunk/src/pow.c (from /trunk/pow.c:7086)
+ A /trunk/src/pow_si.c (from /trunk/pow_si.c:7086)
+ A /trunk/src/pow_ui.c (from /trunk/pow_ui.c:7086)
+ A /trunk/src/pow_z.c (from /trunk/pow_z.c:7086)
+ A /trunk/src/powerof2.c (from /trunk/powerof2.c:7086)
+ A /trunk/src/print_raw.c (from /trunk/print_raw.c:7086)
+ A /trunk/src/print_rnd_mode.c (from /trunk/print_rnd_mode.c:7086)
+ A /trunk/src/printf.c (from /trunk/printf.c:7086)
+ A /trunk/src/rec_sqrt.c (from /trunk/rec_sqrt.c:7086)
+ A /trunk/src/reldiff.c (from /trunk/reldiff.c:7086)
+ A /trunk/src/rem1.c (from /trunk/rem1.c:7086)
+ A /trunk/src/rint.c (from /trunk/rint.c:7086)
+ A /trunk/src/root.c (from /trunk/root.c:7086)
+ A /trunk/src/round_near_x.c (from /trunk/round_near_x.c:7086)
+ A /trunk/src/round_p.c (from /trunk/round_p.c:7086)
+ A /trunk/src/round_prec.c (from /trunk/round_prec.c:7086)
+ A /trunk/src/round_raw_generic.c (from /trunk/round_raw_generic.c:7086)
+ A /trunk/src/scale2.c (from /trunk/scale2.c:7086)
+ A /trunk/src/sec.c (from /trunk/sec.c:7086)
+ A /trunk/src/sech.c (from /trunk/sech.c:7086)
+ A /trunk/src/set.c (from /trunk/set.c:7086)
+ A /trunk/src/set_d.c (from /trunk/set_d.c:7086)
+ A /trunk/src/set_d64.c (from /trunk/set_d64.c:7086)
+ A /trunk/src/set_dfl_prec.c (from /trunk/set_dfl_prec.c:7086)
+ A /trunk/src/set_exp.c (from /trunk/set_exp.c:7086)
+ A /trunk/src/set_f.c (from /trunk/set_f.c:7086)
+ A /trunk/src/set_flt.c (from /trunk/set_flt.c:7086)
+ A /trunk/src/set_inf.c (from /trunk/set_inf.c:7086)
+ A /trunk/src/set_ld.c (from /trunk/set_ld.c:7086)
+ A /trunk/src/set_nan.c (from /trunk/set_nan.c:7086)
+ A /trunk/src/set_prc_raw.c (from /trunk/set_prc_raw.c:7086)
+ A /trunk/src/set_prec.c (from /trunk/set_prec.c:7086)
+ A /trunk/src/set_q.c (from /trunk/set_q.c:7086)
+ A /trunk/src/set_rnd.c (from /trunk/set_rnd.c:7086)
+ A /trunk/src/set_si.c (from /trunk/set_si.c:7086)
+ A /trunk/src/set_si_2exp.c (from /trunk/set_si_2exp.c:7086)
+ A /trunk/src/set_sj.c (from /trunk/set_sj.c:7086)
+ A /trunk/src/set_str.c (from /trunk/set_str.c:7086)
+ A /trunk/src/set_str_raw.c (from /trunk/set_str_raw.c:7086)
+ A /trunk/src/set_ui.c (from /trunk/set_ui.c:7086)
+ A /trunk/src/set_ui_2exp.c (from /trunk/set_ui_2exp.c:7086)
+ A /trunk/src/set_uj.c (from /trunk/set_uj.c:7086)
+ A /trunk/src/set_z.c (from /trunk/set_z.c:7086)
+ A /trunk/src/set_z_exp.c (from /trunk/set_z_exp.c:7086)
+ A /trunk/src/set_zero.c (from /trunk/set_zero.c:7086)
+ A /trunk/src/setmax.c (from /trunk/setmax.c:7086)
+ A /trunk/src/setmin.c (from /trunk/setmin.c:7086)
+ A /trunk/src/setsign.c (from /trunk/setsign.c:7086)
+ A /trunk/src/sgn.c (from /trunk/sgn.c:7086)
+ A /trunk/src/si_op.c (from /trunk/si_op.c:7086)
+ A /trunk/src/signbit.c (from /trunk/signbit.c:7086)
+ A /trunk/src/sin.c (from /trunk/sin.c:7086)
+ A /trunk/src/sin_cos.c (from /trunk/sin_cos.c:7086)
+ A /trunk/src/sinh.c (from /trunk/sinh.c:7086)
+ A /trunk/src/sinh_cosh.c (from /trunk/sinh_cosh.c:7086)
+ A /trunk/src/sqr.c (from /trunk/sqr.c:7086)
+ A /trunk/src/sqrt.c (from /trunk/sqrt.c:7086)
+ A /trunk/src/sqrt_ui.c (from /trunk/sqrt_ui.c:7086)
+ A /trunk/src/stack_interface.c (from /trunk/stack_interface.c:7086)
+ A /trunk/src/strtofr.c (from /trunk/strtofr.c:7086)
+ A /trunk/src/sub.c (from /trunk/sub.c:7086)
+ A /trunk/src/sub1.c (from /trunk/sub1.c:7086)
+ A /trunk/src/sub1sp.c (from /trunk/sub1sp.c:7086)
+ A /trunk/src/sub_d.c (from /trunk/sub_d.c:7086)
+ A /trunk/src/sub_ui.c (from /trunk/sub_ui.c:7086)
+ A /trunk/src/subnormal.c (from /trunk/subnormal.c:7086)
+ A /trunk/src/sum.c (from /trunk/sum.c:7086)
+ A /trunk/src/swap.c (from /trunk/swap.c:7086)
+ A /trunk/src/tan.c (from /trunk/tan.c:7086)
+ A /trunk/src/tanh.c (from /trunk/tanh.c:7086)
+ A /trunk/src/uceil_exp2.c (from /trunk/uceil_exp2.c:7086)
+ A /trunk/src/uceil_log2.c (from /trunk/uceil_log2.c:7086)
+ A /trunk/src/ufloor_log2.c (from /trunk/ufloor_log2.c:7086)
+ A /trunk/src/ui_div.c (from /trunk/ui_div.c:7086)
+ A /trunk/src/ui_pow.c (from /trunk/ui_pow.c:7086)
+ A /trunk/src/ui_pow_ui.c (from /trunk/ui_pow_ui.c:7086)
+ A /trunk/src/ui_sub.c (from /trunk/ui_sub.c:7086)
+ A /trunk/src/urandom.c (from /trunk/urandom.c:7086)
+ A /trunk/src/urandomb.c (from /trunk/urandomb.c:7086)
+ A /trunk/src/vasprintf.c (from /trunk/vasprintf.c:7086)
+ A /trunk/src/version.c (from /trunk/version.c:7086)
+ A /trunk/src/volatile.c (from /trunk/volatile.c:7086)
+ A /trunk/src/yn.c (from /trunk/yn.c:7086)
+ A /trunk/src/zeta.c (from /trunk/zeta.c:7086)
+ A /trunk/src/zeta_ui.c (from /trunk/zeta_ui.c:7086)
+ D /trunk/stack_interface.c
+ D /trunk/strtofr.c
+ D /trunk/sub.c
+ D /trunk/sub1.c
+ D /trunk/sub1sp.c
+ D /trunk/sub_d.c
+ D /trunk/sub_ui.c
+ D /trunk/subnormal.c
+ D /trunk/sum.c
+ D /trunk/swap.c
+ D /trunk/tan.c
+ D /trunk/tanh.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tools
+ A /trunk/tools/check_inits_clears (from /trunk/check_inits_clears:7086)
+ A /trunk/tools/coverage (from /trunk/coverage:7086)
+ A /trunk/tools/get_patches.sh (from /trunk/get_patches.sh:7086)
+ A /trunk/tools/mbench (from /trunk/mbench:7086)
+ A /trunk/tools/mpfrlint (from /trunk/mpfrlint:7086)
+ A /trunk/tools/nightly-test (from /trunk/nightly-test:7086)
+ A /trunk/tools/update-patchv (from /trunk/update-patchv:7086)
+ A /trunk/tools/update-version (from /trunk/update-version:7086)
+ A /trunk/tune
+ A /trunk/tune/Makefile.am
+ A /trunk/tune/bidimensional_sample.c (from /trunk/bidimensional_sample.c:7086)
+ A /trunk/tune/speed.c (from /trunk/speed.c:7086)
+ A /trunk/tune/tuneup.c (from /trunk/tuneup.c:7086)
+ D /trunk/tuneup.c
+ D /trunk/uceil_exp2.c
+ D /trunk/uceil_log2.c
+ D /trunk/ufloor_log2.c
+ D /trunk/ui_div.c
+ D /trunk/ui_pow.c
+ D /trunk/ui_pow_ui.c
+ D /trunk/ui_sub.c
+ D /trunk/update-faq
+ D /trunk/update-patchv
+ D /trunk/update-version
+ D /trunk/urandom.c
+ D /trunk/urandomb.c
+ D /trunk/vasprintf.c
+ D /trunk/version.c
+ D /trunk/volatile.c
+ D /trunk/yn.c
+ D /trunk/zeta.c
+ D /trunk/zeta_ui.c
+
+Source reorganization. In short:
+ * Added directories and moved related files into them:
+ - src for the MPFR source files (to build the library).
+ - doc for documentation files (except INSTALL, README...).
+ - tools for various tools (scripts) and mbench.
+ - tune for tuneup-related source files.
+ - other for other source files (not distributed in tarballs).
+ Existing directories:
+ - tests for the source files of the test suite (make check).
+ - examples for examples.
+ - m4 for m4 files.
+ * Renamed configure.in to configure.ac.
+ * Added/updated Makefile.am files where needed.
+ * Updated acinclude.m4 and configure.ac (AC_CONFIG_FILES line).
+ * Updated the documentation (INSTALL, README, doc/README.dev and
+ doc/mpfr.texi).
+ * Updated NEWS and TODO.
+ * Updated the scripts now in tools.
+
+The following script was used:
+
+#!/usr/bin/env zsh
+svn mkdir doc other src tools tune
+svn mv ${${(M)$(sed -n '/libmpfr_la_SOURCES/,/[^\]$/p' \
+ Makefile.am):#*.[ch]}:#get_patches.c} mparam_h.in \
+ round_raw_generic.c jyn_asympt.c src
+svn mv mbench check_inits_clears coverage get_patches.sh mpfrlint \
+ nightly-test update-patchv update-version tools
+svn mv bidimensional_sample.c speed.c tuneup.c tune
+svn mv *.{c,h} other
+svn mv FAQ.html README.dev algorithm* faq.xsl fdl.texi mpfr.texi \
+ update-faq doc
+svn mv configure.in configure.ac
+svn cp Makefile.am src/Makefile.am
+svn rm replace_all
+[Modifying some files, see above]
+svn add doc/Makefile.am
+svn add tune/Makefile.am
+------------------------------------------------------------------------
+r7086 | vlefevre | 2010-08-16 13:09:20 +0000 (Mon, 16 Aug 2010) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+[Makefile.am] Updated -version-info (the interface hasn't really been
+changed yet -- though the future bug fix / rewrite of mpfr_mul_q and
+mpfr_div_q could be seen as an addition -- but this eases maintenance
+and avoids -version-info conflict with the 3.0 branch).
+------------------------------------------------------------------------
+r7085 | vlefevre | 2010-08-16 12:40:14 +0000 (Mon, 16 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/bidimensional_sample.c
+
+[bidimensional_sample.c] Added copyright notice.
+------------------------------------------------------------------------
+r7084 | vlefevre | 2010-08-16 12:37:37 +0000 (Mon, 16 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/ai.c
+
+[ai.c] Prototype clean-up.
+------------------------------------------------------------------------
+r7083 | vlefevre | 2010-08-16 09:21:21 +0000 (Mon, 16 Aug 2010) | 12 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/acinclude.m4
+ M /trunk/fits_intmax.c
+ M /trunk/fits_uintmax.c
+ M /trunk/get_sj.c
+ M /trunk/get_uj.c
+ M /trunk/m4/size_max.m4
+ M /trunk/set_sj.c
+ M /trunk/set_uj.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/vasprintf.c
+
+Avoid a compilation failure on OSF/1 (Tru64) 5.1 due to non-C99
+conformance though <inttypes.h> is available. In various source
+files and m4 files, use the following form only:
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+Updated README.dev to mention this form.
+------------------------------------------------------------------------
+r7078 | vlefevre | 2010-08-13 14:46:58 +0000 (Fri, 13 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/random2.c
+
+Deleted old svn:mergeinfo property on tests/random2.c
+------------------------------------------------------------------------
+r7077 | vlefevre | 2010-08-13 10:11:25 +0000 (Fri, 13 Aug 2010) | 10 lines
+Changed paths:
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tzeta_ui.c
+
+[tests] Avoid warning due to -Wunused-but-set-variable (from future
+GCC 4.6). Only let the one from tsubnormal.c because it's a TODO.
+ * mpf_compat.h: use the variables, that are there for prototype
+ checking.
+ * tpow.c, tpow_z.c: test the ternary value.
+ * tremquo.c: removed inex variables (the bug due to the MPFR value).
+ * tset.c: test the ternary value.
+ * tset_ld.c: removed the long double variable (it cannot be tested
+ in a portable way and the bug was an assertion failure).
+ * tzeta_ui.c: removed the inexact variable (not really useful here).
+------------------------------------------------------------------------
+r7076 | vlefevre | 2010-08-13 09:44:19 +0000 (Fri, 13 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/get_f.c
+
+[get_f.c] Avoid warning due to -Wunused-but-set-variable (from
+future GCC 4.6).
+------------------------------------------------------------------------
+r7075 | vlefevre | 2010-08-13 09:41:27 +0000 (Fri, 13 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+[gamma.c] Avoid warning due to -Wunused-but-set-variable (from
+future GCC 4.6).
+------------------------------------------------------------------------
+r7074 | vlefevre | 2010-08-13 09:38:28 +0000 (Fri, 13 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+
+[gmp_op.c] Avoid warning due to -Wunused-but-set-variable (from
+future GCC 4.6).
+------------------------------------------------------------------------
+r7073 | vlefevre | 2010-08-13 09:32:58 +0000 (Fri, 13 Aug 2010) | 3 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] No longer define qn and sizer, which are no longer used since
+r6919. This was detected by gcc-snapshot (4.6.0 prerelease) under Debian
+(-Wunused-but-set-variable).
+------------------------------------------------------------------------
+r7072 | vlefevre | 2010-08-13 08:12:06 +0000 (Fri, 13 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Update.
+------------------------------------------------------------------------
+r7071 | vlefevre | 2010-08-13 08:11:16 +0000 (Fri, 13 Aug 2010) | 3 lines
+Changed paths:
+ M /trunk/ieee_floats.h
+
+[ieee_floats.h] Avoid breaking aliasing-rules when _GMP_IEEE_FLOATS is
+defined (e.g. with --with-gmp-build), by replacing a struct by a union
+like in r6381 for long double.
+------------------------------------------------------------------------
+r7070 | vlefevre | 2010-08-13 07:58:14 +0000 (Fri, 13 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+[configure.in] Removed useless slash.
+------------------------------------------------------------------------
+r7069 | vlefevre | 2010-08-12 14:28:59 +0000 (Thu, 12 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Prepare for new version.
+------------------------------------------------------------------------
+r7067 | vlefevre | 2010-08-12 14:13:48 +0000 (Thu, 12 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] Removed obsolete paragraph about the old prepare script.
+------------------------------------------------------------------------
+r7066 | vlefevre | 2010-08-12 13:46:41 +0000 (Thu, 12 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/update-version
+
+[update-version] Detect errors.
+------------------------------------------------------------------------
+r7065 | vlefevre | 2010-08-12 10:51:17 +0000 (Thu, 12 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/FAQ.html
+
+Updated FAQ.html with update-faq.
+------------------------------------------------------------------------
+r7064 | vlefevre | 2010-08-12 10:50:56 +0000 (Thu, 12 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/faq.xsl
+
+[faq.xsl] Do not copy XML comments.
+------------------------------------------------------------------------
+r7063 | vlefevre | 2010-08-12 10:48:45 +0000 (Thu, 12 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/FAQ.html
+
+Updated FAQ.html with update-faq.
+------------------------------------------------------------------------
+r7059 | vlefevre | 2010-08-12 08:52:54 +0000 (Thu, 12 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] INRIAGforge -> INRIAGForge.
+------------------------------------------------------------------------
+r7058 | vlefevre | 2010-08-12 08:49:23 +0000 (Thu, 12 Aug 2010) | 5 lines
+Changed paths:
+ M /trunk/README
+
+[README] Update:
+ * InriaGforge -> INRIAGForge (official typography).
+ * Updated URL of the Subversion FAQ (now on apache.org).
+ * README.dev provided via SVN only.
+ * Removed the old note about the old CVS repository.
+------------------------------------------------------------------------
+r7057 | vlefevre | 2010-08-11 13:56:25 +0000 (Wed, 11 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/gmp_op.c
+
+[gmp_op.c] mpfr_mul_q and mpfr_div_q are still buggy; added comment.
+------------------------------------------------------------------------
+r7056 | vlefevre | 2010-08-11 13:39:05 +0000 (Wed, 11 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+[tests/tgmpop.c] Added missing "static".
+------------------------------------------------------------------------
+r7055 | thevenyp | 2010-08-11 10:48:45 +0000 (Wed, 11 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/tests/tgmpop.c
+
+gmp_op.c: Fix ternary value returned by mpfr_mul_q and mpfr_div_q in overflow cases.
+------------------------------------------------------------------------
+r7051 | vlefevre | 2010-08-04 23:51:21 +0000 (Wed, 04 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated "To make a release" (test of FP division by 0).
+------------------------------------------------------------------------
+r7050 | vlefevre | 2010-08-04 23:45:25 +0000 (Wed, 04 Aug 2010) | 10 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_flt.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_ld.c
+
+Support implementations where the floating-point division by 0 fails.
+ * acinclude.m4: added a test to check whether the FP division by 0
+ fails, and define MPFR_ERRDIVZERO in such a case.
+ * tests/tests.c: if MPFR_TEST_DIVBYZERO is defined, test whether
+ there has been a floating-point division by 0 (FE_DIVBYZERO or
+ FE_INVALID exception).
+ * tests/tgeneric.c: if MPFR_ERRDIVZERO is defined, disable the
+ huge and tiny cases.
+ * tests/t*_{flt,d,ld}.c: if MPFR_ERRDIVZERO is defined, disable
+ tests involving NaN and infinities.
+------------------------------------------------------------------------
+r7049 | vlefevre | 2010-08-04 22:09:17 +0000 (Wed, 04 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] Update about the compilers.
+------------------------------------------------------------------------
+r7048 | vlefevre | 2010-08-04 14:50:54 +0000 (Wed, 04 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] Mention clang.
+------------------------------------------------------------------------
+r7047 | vlefevre | 2010-08-04 14:25:17 +0000 (Wed, 04 Aug 2010) | 7 lines
+Changed paths:
+ M /trunk/get_sj.c
+
+[get_sj.c] Fixed bug found by John Regehr:
+https://gforge.inria.fr/tracker/index.php?func=detail&aid=10839&group_id=136&atid=619
+Note: the problem was an undefined behavior that could occur when
+sizeof(mp_limb_t) < sizeof(intmax_t) and |x| was small enough,
+because a right shift was >= the type width. However as the shifted
+value was 0, most platforms should not be affected by this bug. This
+problem was detected with clang -fcatch-undefined-ansic-behavior.
+------------------------------------------------------------------------
+r7046 | vlefevre | 2010-08-04 14:05:09 +0000 (Wed, 04 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tget_sj.c
+
+[tests/tget_sj.c] Added tests of 1 and -1.
+------------------------------------------------------------------------
+r7045 | vlefevre | 2010-08-04 13:35:48 +0000 (Wed, 04 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/get_sj.c
+
+[get_sj.c] Added assertions concerning
+https://gforge.inria.fr/tracker/?func=detail&atid=619&aid=10839&group_id=136
+------------------------------------------------------------------------
+r7044 | vlefevre | 2010-08-04 10:59:01 +0000 (Wed, 04 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+[configure.in] When logging is enabled, remove the possible -pedantic
+from GMP's CFLAGS to avoid warnings about C conformance.
+------------------------------------------------------------------------
+r7043 | vlefevre | 2010-08-04 10:17:14 +0000 (Wed, 04 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+[mpfr-impl.h] Reverse-merged changeset r7042. The code was not
+incorrect: the warning is due to the -pedantic from GMP's CFLAGS.
+------------------------------------------------------------------------
+r7042 | vlefevre | 2010-08-04 09:58:06 +0000 (Wed, 04 Aug 2010) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+[mpfr-impl.h] Correction to avoid GCC warnings
+ warning: invalid storage class for function 'x_f'
+ warning: invalid storage class for function '__mpfr_log_cleanup'
+when building MPFR with logging support.
+------------------------------------------------------------------------
+r7041 | vlefevre | 2010-08-03 15:16:22 +0000 (Tue, 03 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+[mpfrlint] Correction for the future MPFR source structure.
+------------------------------------------------------------------------
+r7040 | vlefevre | 2010-08-03 15:08:22 +0000 (Tue, 03 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+[mpfrlint] Execute check_inits_clears.
+------------------------------------------------------------------------
+r7039 | vlefevre | 2010-08-03 15:06:58 +0000 (Tue, 03 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/check_inits_clears
+
+[check_inits_clears] Correction.
+------------------------------------------------------------------------
+r7038 | vlefevre | 2010-08-02 15:07:51 +0000 (Mon, 02 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+
+[Makefile.am] Moved ieee_floats.h from EXTRA_DIST to libmpfr_la_SOURCES.
+------------------------------------------------------------------------
+r7037 | vlefevre | 2010-08-02 15:03:24 +0000 (Mon, 02 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+[Makefile.am] Clean-up: removed gen_inverse.h from EXTRA_DIST because
+it is already in libmpfr_la_SOURCES.
+------------------------------------------------------------------------
+r7036 | vlefevre | 2010-08-01 19:47:36 +0000 (Sun, 01 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] Removed the comment about the dependency bug.
+(svn merge -r7032:7031 mparam_h.in)
+------------------------------------------------------------------------
+r7033 | vlefevre | 2010-08-01 19:26:12 +0000 (Sun, 01 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+[Makefile.am] Added "BUILT_SOURCES = mparam.h", fixing bug
+https://gforge.inria.fr/tracker/index.php?func=detail&aid=10810&group_id=136&atid=619
+------------------------------------------------------------------------
+r7032 | vlefevre | 2010-08-01 18:45:45 +0000 (Sun, 01 Aug 2010) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] Added a comment concerning the bug in the mparam.h dependency rule:
+https://gforge.inria.fr/tracker/index.php?func=detail&aid=10810&group_id=136&atid=619
+------------------------------------------------------------------------
+r7031 | vlefevre | 2010-08-01 18:39:52 +0000 (Sun, 01 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] Enable C mode for Emacs.
+------------------------------------------------------------------------
+r7030 | vlefevre | 2010-08-01 17:09:24 +0000 (Sun, 01 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] Deleted trailing whitespace.
+------------------------------------------------------------------------
+r7029 | vlefevre | 2010-08-01 17:08:36 +0000 (Sun, 01 Aug 2010) | 1 line
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] Bug fix: added a newline at the end of the file.
+------------------------------------------------------------------------
+r7026 | vlefevre | 2010-07-30 15:44:24 +0000 (Fri, 30 Jul 2010) | 4 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/FAQ.html
+ M /trunk/INSTALL
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/README.dev
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_d.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/ai.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/bernoulli.c
+ M /trunk/buildopt.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/digamma.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_d.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erfc.c
+ M /trunk/examples/divworst.c
+ M /trunk/examples/rndo-add.c
+ M /trunk/examples/sample.c
+ M /trunk/examples/version.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gammaonethird.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_flt.c
+ M /trunk/get_ld.c
+ M /trunk/get_patches.sh
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/ieee_floats.h
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/isregular.c
+ M /trunk/iszero.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/min_prec.c
+ M /trunk/minmax.c
+ M /trunk/modf.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-thread.h
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_d.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/printf.c
+ M /trunk/rec_sqrt.c
+ M /trunk/reldiff.c
+ M /trunk/rem1.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/scale2.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_flt.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/set_z_exp.c
+ M /trunk/set_zero.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/setsign.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/signbit.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/speed.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_d.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/data/digamma
+ M /trunk/tests/data/li2
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/random2.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tai.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tbuildopt.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdigamma.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_flt.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tisqrt.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmin_prec.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tset_z_exp.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstdint.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/turandom.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandom.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/yn.c
+ M /trunk/zeta_ui.c
+
+Replaced
+ Contributed by the Arenaire and Cacao projects
+by
+ Contributed by the Arenaire and Caramel projects
+------------------------------------------------------------------------
+r7024 | vlefevre | 2010-07-30 15:26:12 +0000 (Fri, 30 Jul 2010) | 1 line
+Changed paths:
+ M /trunk/AUTHORS
+
+[AUTHORS] Updated a sentence.
+------------------------------------------------------------------------
+r7021 | vlefevre | 2010-07-30 09:36:55 +0000 (Fri, 30 Jul 2010) | 1 line
+Changed paths:
+ M /trunk
+
+Added configure.lineno (generated by configure) to svn:ignore property.
+------------------------------------------------------------------------
+r7016 | vlefevre | 2010-07-29 16:01:45 +0000 (Thu, 29 Jul 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] For announces, changed mpfr into mpfr-announce.
+------------------------------------------------------------------------
+r7014 | vlefevre | 2010-07-26 11:12:22 +0000 (Mon, 26 Jul 2010) | 1 line
+Changed paths:
+ M /trunk/ai.c
+
+[ai.c] Replaced mp_exp_t by mpfr_exp_t.
+------------------------------------------------------------------------
+r7013 | vlefevre | 2010-07-25 19:31:31 +0000 (Sun, 25 Jul 2010) | 1 line
+Changed paths:
+ M /trunk/ai.c
+
+[ai.c] Fixed several bugs in mpfr_ai.
+------------------------------------------------------------------------
+r7010 | schevill | 2010-07-20 13:18:42 +0000 (Tue, 20 Jul 2010) | 3 lines
+Changed paths:
+ M /trunk/bidimensional_sample.c
+
+Updated bidimensional_sample to take into account the fact the mpfr_ai1 and mpfr_ai2 are now statically defined.
+
+
+------------------------------------------------------------------------
+r7009 | schevill | 2010-07-20 12:49:26 +0000 (Tue, 20 Jul 2010) | 3 lines
+Changed paths:
+ M /trunk/ai.c
+ M /trunk/mpfr.h
+
+mpfr_ai1 and mpfr_ai2 are now declared static. Only mpfr_ai is global.
+
+
+------------------------------------------------------------------------
+r7008 | schevill | 2010-07-20 12:38:44 +0000 (Tue, 20 Jul 2010) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Forgot a declaration in the previous commit.
+
+
+------------------------------------------------------------------------
+r7007 | schevill | 2010-07-20 12:32:42 +0000 (Tue, 20 Jul 2010) | 9 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/ai.c
+ D /trunk/ai2.c
+ M /trunk/bidimensional_sample.c
+ M /trunk/mparam_h.in
+ M /trunk/mpfr-impl.h
+ M /trunk/tuneup.c
+
+Added automatic tuning of mpfr_ai.
+
+More precisely:
+* removed ai2.c: both implementations are now in the same file ai.c
+* added thresholds and automatic choice of the method to use in function of the thresholds.
+* added procedures for tuning functions like ai into tuneup.c
+* added a tuning procedure into tuneup.c
+
+
+------------------------------------------------------------------------
+r7005 | vlefevre | 2010-07-19 08:29:11 +0000 (Mon, 19 Jul 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tget_flt.c
+
+[tests/tget_flt.c] Fixed printf strings (missing backslash).
+------------------------------------------------------------------------
+r7004 | zimmerma | 2010-07-15 12:54:15 +0000 (Thu, 15 Jul 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_flt.c
+
+[tget_flt.c] completed previous commit
+
+------------------------------------------------------------------------
+r7003 | zimmerma | 2010-07-15 12:49:09 +0000 (Thu, 15 Jul 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_flt.c
+
+[tget_flt.c] print more information in case a test fails
+
+------------------------------------------------------------------------
+r6999 | vlefevre | 2010-07-09 23:59:50 +0000 (Fri, 09 Jul 2010) | 1 line
+Changed paths:
+ M /trunk/gamma.c
+
+[gamma.c] Added an assert concerning the mpfr_exp_t size.
+------------------------------------------------------------------------
+r6998 | vlefevre | 2010-07-09 23:48:40 +0000 (Fri, 09 Jul 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+[tests/tgamma.c] Use mpfr_set_str instead of mpfr_set_d.
+------------------------------------------------------------------------
+r6997 | vlefevre | 2010-07-09 23:33:24 +0000 (Fri, 09 Jul 2010) | 1 line
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] Untabified.
+------------------------------------------------------------------------
+r6996 | zimmerma | 2010-07-09 20:09:08 +0000 (Fri, 09 Jul 2010) | 6 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+[gamma.c] fixed bug reported on MPFR list:
+ https://sympa.inria.fr/sympa/arc/mpfr/2010-07/msg00001.html
+ In the underflow detection:
+ * we took log instead of log2
+ * at the end, we added the wrong terms
+
+------------------------------------------------------------------------
+r6995 | vlefevre | 2010-07-01 12:58:19 +0000 (Thu, 01 Jul 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+[mpfr-impl.h] Added a comment concerning the 'noreturn' property.
+------------------------------------------------------------------------
+r6994 | zimmerma | 2010-06-28 15:32:21 +0000 (Mon, 28 Jun 2010) | 6 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] added 3 more bits to initial working precision. On a sample of 20247
+ tests by Sylvain Chevillard with precisions in [50, 100], the number
+ of Ziv's failures decreased from 1184 to 144, which is less than 1%
+ (to reduce to zero, we would have to increase the number of extra
+ bits from 8 to 17).
+
+------------------------------------------------------------------------
+r6993 | vlefevre | 2010-06-28 13:10:28 +0000 (Mon, 28 Jun 2010) | 3 lines
+Changed paths:
+ M /trunk/round_prec.c
+
+[round_prec.c] Applied a patch from Patrick Pélissier (with
+slightly modified comments) to make mpfr_prec_round compatible
+with non-mpfr_init allocation methods when no realloc is needed.
+------------------------------------------------------------------------
+r6989 | vlefevre | 2010-06-25 12:46:50 +0000 (Fri, 25 Jun 2010) | 4 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-gmp.h
+
+[acinclude.m4] Use AC_FUNC_ALLOCA to have HAVE_ALLOCA_H defined
+when available. This problem was introduced when AC_FUNC_ALLOCA
+was removed from configure.in in r6765. Note: building MPFR with
+--with-gmp-build is not affected as GMP's config.h is used.
+------------------------------------------------------------------------
+r6988 | vlefevre | 2010-06-25 11:44:00 +0000 (Fri, 25 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+[mpfr-gmp.h] Reverted incorrect changeset r6987 (see code about alloca).
+------------------------------------------------------------------------
+r6987 | zimmerma | 2010-06-25 10:00:44 +0000 (Fri, 25 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+[mpfr-gmp.h] include alloca.h
+
+------------------------------------------------------------------------
+r6986 | zimmerma | 2010-06-25 08:20:10 +0000 (Fri, 25 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] added comment about config.log
+
+------------------------------------------------------------------------
+r6985 | zimmerma | 2010-06-24 20:39:09 +0000 (Thu, 24 Jun 2010) | 3 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] fixed problem reported by Sylvain Chevillard for large x, where the
+ cancelled bits were counted twice
+
+------------------------------------------------------------------------
+r6983 | vlefevre | 2010-06-24 06:11:32 +0000 (Thu, 24 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tfprintf.c
+
+[tests/tfprintf.c] Cosmetic improvement suggested by Denis Excoffier.
+------------------------------------------------------------------------
+r6982 | vlefevre | 2010-06-23 13:47:19 +0000 (Wed, 23 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] Minor change to match a filename on the website.
+------------------------------------------------------------------------
+r6979 | vlefevre | 2010-06-23 10:13:07 +0000 (Wed, 23 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+[tests/tout_str.c] Fixed bug introduced in r6976: changed size_t into
+unsigned int for printf (the size of unsigned int is sufficient here).
+------------------------------------------------------------------------
+r6978 | vlefevre | 2010-06-22 15:59:16 +0000 (Tue, 22 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/out_str.c
+
+[out_str.c] Handle the output errors.
+------------------------------------------------------------------------
+r6977 | vlefevre | 2010-06-22 15:27:34 +0000 (Tue, 22 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/out_str.c
+
+[out_str.c] Handle output error in the special cases of mpfr_out_str
+(and use MPFR_IS_SINGULAR like in the other functions).
+------------------------------------------------------------------------
+r6976 | thevenyp | 2010-06-22 14:59:21 +0000 (Tue, 22 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/out_str.c
+ M /trunk/tests/tout_str.c
+
+Fix wrong return value of mpfr_out_str on special values.
+------------------------------------------------------------------------
+r6974 | vlefevre | 2010-06-22 13:24:56 +0000 (Tue, 22 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/VERSION
+ M /trunk/configure.in
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/version.c
+
+Updated version to 3.1.0-dev.
+------------------------------------------------------------------------
+r6973 | vlefevre | 2010-06-22 13:23:33 +0000 (Tue, 22 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] Added a paragraph about the precision, rounding mode and
+exponent types.
+------------------------------------------------------------------------
+r6972 | vlefevre | 2010-06-22 13:17:29 +0000 (Tue, 22 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/ai2.c
+ M /trunk/bidimensional_sample.c
+ M /trunk/gammaonethird.c
+ M /trunk/get_f.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfrlint
+
+In mpfrlint, detect the use of mp_exp_t and mp_prec_t.
+Fixed the files that were generating warnings.
+------------------------------------------------------------------------
+r6971 | schevill | 2010-06-22 13:12:09 +0000 (Tue, 22 Jun 2010) | 3 lines
+Changed paths:
+ M /trunk/ai2.c
+
+I forgot to replace one occurence of isqrt.
+
+
+------------------------------------------------------------------------
+r6968 | schevill | 2010-06-22 08:45:00 +0000 (Tue, 22 Jun 2010) | 4 lines
+Changed paths:
+ M /trunk/ai2.c
+
+Use of __gmpfr_isqrt instead of my own isqrt wrapper.
+
+
+
+------------------------------------------------------------------------
+r6967 | schevill | 2010-06-22 08:43:18 +0000 (Tue, 22 Jun 2010) | 6 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/bidimensional_sample.c
+
+Added a tool for nicely displaying which method is the best in function of x
+and prec when several method can be used for evaluating a given function f in x
+at precision prec.
+
+
+
+------------------------------------------------------------------------
+r6965 | vlefevre | 2010-06-21 12:32:44 +0000 (Mon, 21 Jun 2010) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+[Makefile.am] Fixed dist-hook for -dev versions (I assumed that ||
+and && were right associative, while they are left associative).
+Thanks to Laurent Rineau for noticing this problem.
+------------------------------------------------------------------------
+r6964 | zimmerma | 2010-06-21 09:40:15 +0000 (Mon, 21 Jun 2010) | 9 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] fixed inefficiency for large x: the initial precision was too small,
+ which had the effect that the first Ziv iteration did fail with
+ non-negligible probability (problem reported by Sylvain Chevillard).
+ Also in case of 2 iterations or more the K variable was corrupted.
+Note (2012-03-03): huge inefficiency has been noticed when evaluating
+mpfr_exp on an argument close to log(2^n) in RNDU:
+ https://sympa.inria.fr/sympa/arc/mpfr/2012-03/msg00000.html
+One has an obvious hard-to-round case, meaning that several iterations
+are needed and that K is corrupted. This changeset fixes this bug.
+------------------------------------------------------------------------
+r6962 | zimmerma | 2010-06-15 21:14:08 +0000 (Tue, 15 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] added note about problem with MSVC runtime (seems to be fixed)
+
+------------------------------------------------------------------------
+r6961 | zimmerma | 2010-06-15 20:46:21 +0000 (Tue, 15 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/mbench/Makefile
+
+[Makefile] alternate patch to r6959 from Patrick Pelissier
+
+------------------------------------------------------------------------
+r6960 | zimmerma | 2010-06-15 16:56:09 +0000 (Tue, 15 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] comments from Vincent Lefevre
+
+------------------------------------------------------------------------
+r6959 | zimmerma | 2010-06-15 12:14:12 +0000 (Tue, 15 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/mbench/Makefile
+ M /trunk/mbench/mfv5.h
+
+[mbench] fixes to make mbench work again (tested with GCC 4.4.3)
+
+------------------------------------------------------------------------
+r6958 | zimmerma | 2010-06-15 11:18:50 +0000 (Tue, 15 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] updated notes on Windows (contributed by Brian Gladman)
+
+------------------------------------------------------------------------
+r6955 | vlefevre | 2010-06-10 14:10:03 +0000 (Thu, 10 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+[tests/Makefile.am] Reordered check_PROGRAMS.
+------------------------------------------------------------------------
+r6953 | vlefevre | 2010-06-10 11:49:55 +0000 (Thu, 10 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] Untabified.
+------------------------------------------------------------------------
+r6951 | vlefevre | 2010-06-10 11:26:38 +0000 (Thu, 10 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/BUGS
+
+[BUGS] Update.
+------------------------------------------------------------------------
+r6943 | vlefevre | 2010-06-09 11:26:02 +0000 (Wed, 09 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] Added a note on Mac OS X; thanks to FX Coudert and Fumihiro
+Chiba: https://sympa.inria.fr/sympa/arc/mpfr/2010-06/msg00011.html
+------------------------------------------------------------------------
+r6940 | vlefevre | 2010-06-08 16:17:48 +0000 (Tue, 08 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] Update concerning CC/CFLAGS and the --with-gmp-build option.
+------------------------------------------------------------------------
+r6938 | vlefevre | 2010-06-07 08:20:58 +0000 (Mon, 07 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Added an item about the --with-gmp-build configure option and
+the use of GMP's internal header files.
+------------------------------------------------------------------------
+r6933 | vlefevre | 2010-06-06 11:21:26 +0000 (Sun, 06 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] Reverted incorrect optimization patch r6922 (added a comment).
+There were failures on 32-bit machines.
+------------------------------------------------------------------------
+r6932 | vlefevre | 2010-06-06 11:17:06 +0000 (Sun, 06 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+[mpfr-impl.h] Added log messages for the MPFR_GROUP_* macros.
+------------------------------------------------------------------------
+r6930 | vlefevre | 2010-06-06 10:16:01 +0000 (Sun, 06 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+[mpfrlint] Detect incorrect use of MPFR_LOG_MSG.
+------------------------------------------------------------------------
+r6929 | vlefevre | 2010-06-06 10:06:40 +0000 (Sun, 06 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/ai2.c
+
+[ai2.c] Fixed build failure with --enable-logging, due to incorrect
+MPFR_LOG_MSG usage (see README.dev).
+------------------------------------------------------------------------
+r6927 | vlefevre | 2010-06-06 10:00:50 +0000 (Sun, 06 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated "To make a release".
+------------------------------------------------------------------------
+r6925 | vlefevre | 2010-06-06 09:47:32 +0000 (Sun, 06 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/ai.c
+
+[ai.c] Fixed build failure with --enable-logging, due to incorrect
+MPFR_LOG_MSG usage (see README.dev).
+------------------------------------------------------------------------
+r6922 | zimmerma | 2010-06-04 18:32:18 +0000 (Fri, 04 Jun 2010) | 9 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] speed improvement using MPFR_GROUP_* (from Patrick Pelissier):
+Pass 69
+ mpfr_add: 63 / 102.97 / 126
+ mpfr_exp: 430 / 11861.26 / 46588
+Was before we removed MY_MPZ_INIT:
+Pass 50
+ mpfr_add: 63 / 103.09 / 126
+ mpfr_exp: 430 / 10911.86 / 44215
+
+------------------------------------------------------------------------
+r6920 | vlefevre | 2010-06-04 08:37:54 +0000 (Fri, 04 Jun 2010) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] Removed useless and possibly incorrect cast
+(in case -q doesn't necessarily fit in an int).
+------------------------------------------------------------------------
+r6919 | zimmerma | 2010-06-04 07:51:27 +0000 (Fri, 04 Jun 2010) | 14 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] got rid of MY_INIT_MPZ, small slowdown, but code should be more
+ robust. Below are timings from Patrick Pelissier with mbench:
+mpz_init:
+Pass 78
+ mpfr_add: 63 / 102.86 / 126
+ mpfr_exp: 441 / 12067.81 / 47355
+
+MY_MPZ_INIT
+Pass 50
+ mpfr_add: 63 / 103.09 / 126
+ mpfr_exp: 430 / 10911.86 / 44215
+
+Prec=53 bits (core 2 duo 64 bits)
+
+------------------------------------------------------------------------
+r6918 | zimmerma | 2010-06-03 16:18:31 +0000 (Thu, 03 Jun 2010) | 22 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] fixed problem reported by Sylvain Chevillard with following code
+ and MPFR_EXP_2_THRESHOLD=36 (valgrind complains).
+ It was due to the fact that GMP might allocate extra limbs,
+ see http://gmplib.org/list-archives/gmp-devel/2010-June/001577.html.
+ The fix is not optimal in the sense that GMP does not give a bound
+ on the allocated memory, thus we can only guess.
+
+#include "mpfr.h"
+int main(void) {
+ mpfr_t x,w;
+
+ mpfr_init2(x, 37);
+ mpfr_init2(w, 37);
+ mpfr_set_str(x, "-1.000001100100100001111110110101010001p+20", 2, MPFR_RNDN);
+ mpfr_exp (w, x, MPFR_RNDN);
+
+ mpfr_clear (w);
+ mpfr_clear (x);
+
+ return 0;
+}
+
+------------------------------------------------------------------------
+r6915 | vlefevre | 2010-06-03 15:07:52 +0000 (Thu, 03 Jun 2010) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] Math library check: removed rule specific to HP-UX
+(only -lM was tested while this library may not be available; so,
+let's use the default rule as -lm works).
+------------------------------------------------------------------------
+r6912 | vlefevre | 2010-06-03 08:24:49 +0000 (Thu, 03 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Arenaire -> Arénaire.
+------------------------------------------------------------------------
+r6909 | vlefevre | 2010-06-02 11:02:34 +0000 (Wed, 02 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] 3.0 -> 3.0.0.
+------------------------------------------------------------------------
+r6907 | vlefevre | 2010-06-02 11:01:18 +0000 (Wed, 02 Jun 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Added test coverage for MPFR 3.0.0.
+------------------------------------------------------------------------
+r6904 | vlefevre | 2010-05-31 22:43:23 +0000 (Mon, 31 May 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] Added missing blank lines (consistency).
+------------------------------------------------------------------------
+r6901 | vlefevre | 2010-05-31 22:27:56 +0000 (Mon, 31 May 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tset_z_exp.c
+
+[tests/tset_z_exp.c] Fixed type in a printf.
+------------------------------------------------------------------------
+r6900 | zimmerma | 2010-05-31 20:10:06 +0000 (Mon, 31 May 2010) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] added instructions for "make tune"
+
+------------------------------------------------------------------------
+r6899 | zimmerma | 2010-05-31 20:01:03 +0000 (Mon, 31 May 2010) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] completed missing instructions for "make tune"
+
+------------------------------------------------------------------------
+r6898 | zimmerma | 2010-05-31 19:36:42 +0000 (Mon, 31 May 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_z_exp.c
+
+[tset_z_exp.c] fixed two FIXME
+
+------------------------------------------------------------------------
+r6897 | vlefevre | 2010-05-31 14:29:44 +0000 (Mon, 31 May 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tset_z_exp.c
+
+[tests/tset_z_exp.c] Added 2 FIXME in the test.
+------------------------------------------------------------------------
+r6896 | vlefevre | 2010-05-31 14:20:24 +0000 (Mon, 31 May 2010) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_z_exp.c
+
+[tests/tset_z_exp.c] Removed testcase bug20100531 (this was a bug in
+the test, which didn't detect overflow cases due to too large random
+exponent).
+------------------------------------------------------------------------
+r6895 | vlefevre | 2010-05-31 14:12:27 +0000 (Mon, 31 May 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tset_z_exp.c
+
+[tests/tset_z_exp.c] Added testcase bug20100531.
+------------------------------------------------------------------------
+r6893 | vlefevre | 2010-05-31 13:44:36 +0000 (Mon, 31 May 2010) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.texi
+
+[mpfr.texi, NEWS] Update related to r6879: "Made defined the previously
+undefined cases of mpfr_get_si, mpfr_get_ui, mpfr_get_sj, mpfr_get_uj,
+mpfr_get_z and mpfr_get_z_2exp. In such cases, the erange flag is set.".
+------------------------------------------------------------------------
+r6892 | vlefevre | 2010-05-31 13:08:17 +0000 (Mon, 31 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Corrected mpfr_atan2 range (added in r6831).
+------------------------------------------------------------------------
+r6891 | vlefevre | 2010-05-28 15:07:49 +0000 (Fri, 28 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Made an example fit on 80 columns for the info manual.
+------------------------------------------------------------------------
+r6890 | vlefevre | 2010-05-28 14:29:08 +0000 (Fri, 28 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Changed some @math into @var in the mpfr_fmod description
+(for consistency).
+------------------------------------------------------------------------
+r6889 | vlefevre | 2010-05-28 10:54:55 +0000 (Fri, 28 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Corrected a paragraph.
+------------------------------------------------------------------------
+r6888 | vlefevre | 2010-05-28 10:33:21 +0000 (Fri, 28 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Added an example to get the MPFR version (and at the same
+time, check whether MPFR is already installed).
+------------------------------------------------------------------------
+r6886 | vlefevre | 2010-05-28 09:52:37 +0000 (Fri, 28 May 2010) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/examples/version.c
+
+Added examples/version.c (and updated Makefile.am).
+------------------------------------------------------------------------
+r6885 | vlefevre | 2010-05-28 09:25:36 +0000 (Fri, 28 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Correction (English usage).
+------------------------------------------------------------------------
+r6883 | vlefevre | 2010-05-28 08:16:16 +0000 (Fri, 28 May 2010) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+
+[Makefile.am] Improved dist-hook rule.
+------------------------------------------------------------------------
+r6882 | thevenyp | 2010-05-27 09:14:02 +0000 (Thu, 27 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix typo.
+------------------------------------------------------------------------
+r6881 | zimmerma | 2010-05-26 19:39:02 +0000 (Wed, 26 May 2010) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] removed one item, added one
+
+------------------------------------------------------------------------
+r6880 | zimmerma | 2010-05-26 19:35:30 +0000 (Wed, 26 May 2010) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] removed FIXME (resolved: Philippe confirmed that gmp_printf does
+ not work with mpf2mpfr.h)
+
+------------------------------------------------------------------------
+r6879 | vlefevre | 2010-05-25 16:19:48 +0000 (Tue, 25 May 2010) | 3 lines
+Changed paths:
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tset_si.c
+
+Made defined the previously undefined cases of mpfr_get_si, mpfr_get_ui,
+mpfr_get_sj, mpfr_get_uj, mpfr_get_z and mpfr_get_z_2exp. In such cases,
+the erange flag is set.
+------------------------------------------------------------------------
+r6878 | schevill | 2010-05-25 14:27:57 +0000 (Tue, 25 May 2010) | 3 lines
+Changed paths:
+ M /trunk/ai.c
+ M /trunk/ai2.c
+
+* 80 columns.
+
+
+------------------------------------------------------------------------
+r6877 | schevill | 2010-05-25 14:14:37 +0000 (Tue, 25 May 2010) | 3 lines
+Changed paths:
+ M /trunk/gammaonethird.c
+
+do ... while(0) style for macros.
+
+
+------------------------------------------------------------------------
+r6875 | vlefevre | 2010-05-25 13:20:34 +0000 (Tue, 25 May 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Correction.
+------------------------------------------------------------------------
+r6873 | vlefevre | 2010-05-25 11:05:42 +0000 (Tue, 25 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Minor changes.
+------------------------------------------------------------------------
+r6872 | vlefevre | 2010-05-25 10:43:08 +0000 (Tue, 25 May 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] Reverted incorrect changeset r6870.
+------------------------------------------------------------------------
+r6871 | vlefevre | 2010-05-25 10:41:44 +0000 (Tue, 25 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Added a comment about non-ASCII characters.
+------------------------------------------------------------------------
+r6870 | thevenyp | 2010-05-25 10:38:51 +0000 (Tue, 25 May 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/mpfr.texi
+
+More explicit documentation on the use of specifiers in printf function.
+------------------------------------------------------------------------
+r6869 | vlefevre | 2010-05-25 10:34:07 +0000 (Tue, 25 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Encoding correction for ±.
+------------------------------------------------------------------------
+r6868 | vlefevre | 2010-05-25 10:26:12 +0000 (Tue, 25 May 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.texi
+
+[NEWS, mpfr.texi] mpfr_custom_get_mantissa was renamed to
+mpfr_custom_get_significand.
+------------------------------------------------------------------------
+r6867 | vlefevre | 2010-05-25 10:15:30 +0000 (Tue, 25 May 2010) | 3 lines
+Changed paths:
+ M /trunk/tests/tstckintc.c
+
+[tests/tstckintc.c] Changed mpfr_custom_get_mantissa into
+mpfr_custom_get_significand (but mpfr_custom_get_mantissa
+was still working thanks to the #define).
+------------------------------------------------------------------------
+r6866 | vlefevre | 2010-05-25 10:13:26 +0000 (Tue, 25 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/stack_interface.c
+
+[mpfr.h, stack_interface.c] Changed mpfr_custom_get_mantissa into
+mpfr_custom_get_significand (r6862 was incomplete).
+------------------------------------------------------------------------
+r6865 | vlefevre | 2010-05-25 09:29:40 +0000 (Tue, 25 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+[mpfr.h] <stdint.h> support: also test _STDINT (for MS Visual Studio).
+Thanks to Brian Gladman for the information.
+------------------------------------------------------------------------
+r6863 | vlefevre | 2010-05-25 07:24:18 +0000 (Tue, 25 May 2010) | 3 lines
+Changed paths:
+ M /trunk/buildopt.c
+ M /trunk/mpfrlint
+
+[buildopt.c] Missing #include "mpfr-impl.h" for cygwin builds.
+[mpfrlint] Detect such errors (mpfr-impl.h may be needed because it
+ includes config.h when there is one).
+------------------------------------------------------------------------
+r6862 | zimmerma | 2010-05-24 16:56:52 +0000 (Mon, 24 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+[mpfr.texi] more changes after answers by Vincent to my questions
+
+------------------------------------------------------------------------
+r6860 | vlefevre | 2010-05-24 10:54:03 +0000 (Mon, 24 May 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Reformat / fixed typography.
+------------------------------------------------------------------------
+r6855 | vlefevre | 2010-05-24 00:01:40 +0000 (Mon, 24 May 2010) | 6 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+[sub1sp.c] Fixed a problem that appeared after mpfr_prec_t has been
+made signed. It was visible on PowerPC (tested on Linux 32 bits and
+on Mac OS X 32 & 64 bits), but could potentially affect any platform
+as a negative shift count was generated. As the faulty expressions
+were in a MPFR_ASSERTD, the failure could occur only when assertion
+checking had been enabled.
+------------------------------------------------------------------------
+r6852 | vlefevre | 2010-05-22 23:08:17 +0000 (Sat, 22 May 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] Removed trailing spaces.
+------------------------------------------------------------------------
+r6851 | vlefevre | 2010-05-22 23:06:49 +0000 (Sat, 22 May 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] Added information about intmax_t and corresponding macros.
+------------------------------------------------------------------------
+r6849 | vlefevre | 2010-05-22 22:42:05 +0000 (Sat, 22 May 2010) | 6 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/fits_intmax.c
+ M /trunk/fits_uintmax.c
+ M /trunk/get_sj.c
+ M /trunk/get_uj.c
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tset_sj.c
+
+Detect when the intmax_t type is available but INTMAX_MAX doesn't work
+(e.g. with gcc -ansi -pedantic-errors in 32-bit mode under GNU/Linux).
+New macros MPFR_UINTMAX_MAX, MPFR_INTMAX_MAX and MPFR_INTMAX_MIN are
+defined and used internally instead of UINTMAX_MAX, INTMAX_MAX and
+INTMAX_MIN. If these C99 macros work, then the MPFR_* macros use them,
+otherwise MPFR uses its own definitions.
+------------------------------------------------------------------------
+r6846 | vlefevre | 2010-05-22 19:41:07 +0000 (Sat, 22 May 2010) | 1 line
+Changed paths:
+ M /trunk/gammaonethird.c
+ M /trunk/mpfr-impl.h
+
+mpfr_div_ui8 and mpfr_mul_ui5 didn't have to be exported.
+------------------------------------------------------------------------
+r6845 | vlefevre | 2010-05-22 19:33:22 +0000 (Sat, 22 May 2010) | 1 line
+Changed paths:
+ M /trunk/ai.c
+ M /trunk/ai2.c
+ M /trunk/bernoulli.c
+ M /trunk/buildopt.c
+ M /trunk/digamma.c
+ M /trunk/gammaonethird.c
+ M /trunk/get_flt.c
+ M /trunk/ieee_floats.h
+ M /trunk/isregular.c
+ M /trunk/mbench/mfv5.h
+ M /trunk/mbench/timp.h
+ M /trunk/min_prec.c
+ M /trunk/scale2.c
+ M /trunk/set_flt.c
+ M /trunk/set_z_exp.c
+ M /trunk/set_zero.c
+ M /trunk/speed.c
+ M /trunk/tests/tai.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tbuildopt.c
+ M /trunk/tests/tdigamma.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tget_flt.c
+ M /trunk/tests/tmin_prec.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tset_z_exp.c
+ M /trunk/tests/tstdint.c
+
+Updated Subversion properties.
+------------------------------------------------------------------------
+r6844 | vlefevre | 2010-05-22 19:13:37 +0000 (Sat, 22 May 2010) | 1 line
+Changed paths:
+ M /trunk/ai2.c
+
+[ai2.c] GNU style.
+------------------------------------------------------------------------
+r6843 | vlefevre | 2010-05-22 16:04:13 +0000 (Sat, 22 May 2010) | 1 line
+Changed paths:
+ M /trunk/ai2.c
+
+[ai2.c] Style correction (necessary for ansi2knr, if still useful).
+------------------------------------------------------------------------
+r6842 | vlefevre | 2010-05-22 13:55:22 +0000 (Sat, 22 May 2010) | 1 line
+Changed paths:
+ M /trunk/ai.c
+ M /trunk/ai2.c
+
+[ai.c, ai2.c] Untabified / removed trailing spaces.
+------------------------------------------------------------------------
+r6841 | vlefevre | 2010-05-22 13:53:19 +0000 (Sat, 22 May 2010) | 1 line
+Changed paths:
+ M /trunk/ai.c
+
+[ai.c] GNU style.
+------------------------------------------------------------------------
+r6840 | vlefevre | 2010-05-22 10:21:11 +0000 (Sat, 22 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Corrected the paragraph about whether MPFR is installed.
+------------------------------------------------------------------------
+r6839 | vlefevre | 2010-05-22 00:12:31 +0000 (Sat, 22 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Corrections and answers to PZ comments from r6831.
+The document encoding is now UTF-8.
+------------------------------------------------------------------------
+r6838 | vlefevre | 2010-05-21 21:06:07 +0000 (Fri, 21 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] n-char-sequence was changed into n-char-sequence-opt
+in r6132, but I forgot to update all the occurrences.
+------------------------------------------------------------------------
+r6837 | schevill | 2010-05-21 09:47:13 +0000 (Fri, 21 May 2010) | 5 lines
+Changed paths:
+ M /trunk/ai.c
+ M /trunk/ai2.c
+
+* Removed double precision numbers.
+* Handle +0 and -0 the same way.
+* Use MPFR_GET_EXP in ai2.c
+
+
+------------------------------------------------------------------------
+r6836 | schevill | 2010-05-20 14:19:47 +0000 (Thu, 20 May 2010) | 3 lines
+Changed paths:
+ M /trunk/ai.c
+
+* Corrected a bug when x=0 (MPFR_GET_EXP requires to assert that x!=0).
+
+
+------------------------------------------------------------------------
+r6835 | schevill | 2010-05-20 13:34:26 +0000 (Thu, 20 May 2010) | 3 lines
+Changed paths:
+ M /trunk/ai.c
+ M /trunk/ai2.c
+ M /trunk/gammaonethird.c
+ M /trunk/mpfr-impl.h
+
+Corrected some warnings.
+
+
+------------------------------------------------------------------------
+r6834 | schevill | 2010-05-20 12:39:34 +0000 (Thu, 20 May 2010) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Corrected an error that prevented the doc from compiling.
+
+
+------------------------------------------------------------------------
+r6833 | vlefevre | 2010-05-20 09:47:02 +0000 (Thu, 20 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: corrections.
+------------------------------------------------------------------------
+r6832 | zimmerma | 2010-05-20 09:35:06 +0000 (Thu, 20 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] explain why mpfr_sum uses an array of pointers to mpfr_t
+
+------------------------------------------------------------------------
+r6831 | zimmerma | 2010-05-20 09:10:47 +0000 (Thu, 20 May 2010) | 4 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/fdl.texi
+ M /trunk/mpfr.texi
+
+[mpfr.texi] changes after a complete reading of the documentation.
+ There are some issues left that I don't know how to solve,
+ they are marked with @c PZ in mpfr.texi.
+
+------------------------------------------------------------------------
+r6829 | vlefevre | 2010-05-19 23:07:54 +0000 (Wed, 19 May 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.texi
+
+[mpfr.texi, NEWS] Noted that the mpfr_ai implementation is incomplete
+and experimental.
+------------------------------------------------------------------------
+r6827 | vlefevre | 2010-05-19 23:04:40 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/ai.c
+
+[ai.c] Use MPFR_IS_SINGULAR. Added a FIXME comment for Ai(0).
+------------------------------------------------------------------------
+r6825 | vlefevre | 2010-05-19 22:41:29 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/turandom.c
+
+Type corrections for C++ compilers (in particular, mpfr_rnd_t vs int).
+------------------------------------------------------------------------
+r6822 | vlefevre | 2010-05-19 14:30:02 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/ai.c
+
+[ai.c] Fixed possible problem in reduced exponent range.
+------------------------------------------------------------------------
+r6821 | vlefevre | 2010-05-19 14:25:02 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/ai.c
+ M /trunk/ai2.c
+
+Removed trailing spaces.
+------------------------------------------------------------------------
+r6820 | schevill | 2010-05-19 13:48:46 +0000 (Wed, 19 May 2010) | 4 lines
+Changed paths:
+ M /trunk/ai.c
+ M /trunk/ai2.c
+ M /trunk/gammaonethird.c
+
+* Removed some warnings.
+* More conform to GNU coding standards.
+
+
+------------------------------------------------------------------------
+r6818 | vlefevre | 2010-05-19 13:09:29 +0000 (Wed, 19 May 2010) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ D /trunk/patch-aclocal-icc
+
+Removed obsolete patch-aclocal-icc and updated README.dev (about
+"To make a release").
+------------------------------------------------------------------------
+r6813 | vlefevre | 2010-05-19 12:38:01 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+
+[Makefile.am] Added a comment concerning -version-info and MPFR 3.0.x.
+------------------------------------------------------------------------
+r6812 | vlefevre | 2010-05-19 11:53:33 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/ChangeLog
+
+ChangeLog update with "LC_ALL=en_US.UTF8 TZ=UTC svn log -rHEAD:0 -v".
+------------------------------------------------------------------------
+r6811 | vlefevre | 2010-05-19 10:18:37 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Preliminary interfaces are no longer preliminary.
+------------------------------------------------------------------------
+r6810 | vlefevre | 2010-05-19 10:13:39 +0000 (Wed, 19 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] API Compatibility: mention the detection of the availability
+of intmax_t with C++ compilers.
+------------------------------------------------------------------------
+r6809 | vlefevre | 2010-05-19 09:07:33 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] signness -> signedness (thanks to Philippe).
+------------------------------------------------------------------------
+r6808 | vlefevre | 2010-05-19 00:11:39 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Missing @code.
+------------------------------------------------------------------------
+r6807 | vlefevre | 2010-05-19 00:09:11 +0000 (Wed, 19 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Corrected C terminology (table -> array).
+------------------------------------------------------------------------
+r6806 | vlefevre | 2010-05-18 14:40:36 +0000 (Tue, 18 May 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.texi
+
+[mpfr.texi, NEWS] Mention that mpfr_ai is a new function in MPFR 3.0.
+------------------------------------------------------------------------
+r6805 | vlefevre | 2010-05-18 14:36:05 +0000 (Tue, 18 May 2010) | 1 line
+Changed paths:
+ D /trunk/prepare
+
+Removed obsolete prepare script (autoreconf does the same thing).
+------------------------------------------------------------------------
+r6804 | schevill | 2010-05-18 14:34:57 +0000 (Tue, 18 May 2010) | 21 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/ai.c
+ A /trunk/ai2.c
+ A /trunk/gammaonethird.c
+ M /trunk/mpfr.h
+
+* I added a new implementation of Airy Ai. This implementation uses Smith's
+algorithm.
+Currently, it is provided as a separate implementation mpfr_ai2.
+
+* Please note that both mpfr_ai and mpfr_ai2 need to efficiently evaluate
+Gamma(1/3) and Gamma(2/3). This is provided by functions in the file
+gammaonethird.c
+
+* There is no test file for mpfr_ai2 since it should quickly disappear behind
+a single implementation using the best of mpfr_ai and mpfr_ai2.
+However, if necessary, a test file can be obtained by copying tai.c and
+replacing mpfr_ai by mpfr_ai2 everywhere.
+
+* I do not know if gammaonethird.c will remain like that in the future. Should
+we make this implementation available as a public MPFR function? In this case,
+I have to write a wrapper for providing a correctly rounded implementation.
+Moreover, it contains functions that could be interesting for the
+implementation of other functions (the functions mpfr_div_ui*). Maybe, it
+could be worth providing a file specially for this purpose.
+
+
+------------------------------------------------------------------------
+r6803 | vlefevre | 2010-05-18 14:32:07 +0000 (Tue, 18 May 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Added release name.
+------------------------------------------------------------------------
+r6802 | vlefevre | 2010-05-18 14:30:38 +0000 (Tue, 18 May 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] Updated "Changes from versions 2.3.* to version 2.4.0"
+from MPFR 2.4.2.
+------------------------------------------------------------------------
+r6801 | vlefevre | 2010-05-18 14:25:20 +0000 (Tue, 18 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Completed Section 6.1 "Type and Macro Changes".
+------------------------------------------------------------------------
+r6800 | vlefevre | 2010-05-18 14:07:26 +0000 (Tue, 18 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Updated Section 6.1 "Type and Macro Changes".
+------------------------------------------------------------------------
+r6799 | vlefevre | 2010-05-18 13:57:03 +0000 (Tue, 18 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Missing space.
+------------------------------------------------------------------------
+r6798 | vlefevre | 2010-05-18 13:54:47 +0000 (Tue, 18 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Updated Section 6.1 "Type and Macro Changes".
+------------------------------------------------------------------------
+r6797 | vlefevre | 2010-05-18 13:53:06 +0000 (Tue, 18 May 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] A bit less ambiguous...
+------------------------------------------------------------------------
+r6796 | vlefevre | 2010-05-18 13:12:49 +0000 (Tue, 18 May 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] More details for mp_rnd_t/mpfr_rnd_t, like mp_prec_t/mpfr_prec_t.
+------------------------------------------------------------------------
+r6795 | vlefevre | 2010-05-17 15:51:28 +0000 (Mon, 17 May 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.texi
+
+Added "API Compatibility" section to the MPFR manual.
+TODO: Section 6.1 "Type and Macro Changes".
+------------------------------------------------------------------------
+r6794 | vlefevre | 2010-05-17 13:31:19 +0000 (Mon, 17 May 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] mpfr_strtofr now accepts bases from 37 to 62 (r5965).
+------------------------------------------------------------------------
+r6793 | vlefevre | 2010-05-10 09:25:01 +0000 (Mon, 10 May 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: updated section about MS Windows.
+------------------------------------------------------------------------
+r6792 | vlefevre | 2010-05-10 09:05:12 +0000 (Mon, 10 May 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: updated section about MS Windows.
+------------------------------------------------------------------------
+r6791 | vlefevre | 2010-05-08 17:17:18 +0000 (Sat, 08 May 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tests.c
+
+[tests/tests.c] Fixed code when _MPFR_PREC_FORMAT != 3.
+------------------------------------------------------------------------
+r6790 | zimmerma | 2010-05-08 08:01:05 +0000 (Sat, 08 May 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+[tests/tests.c] fixed compiler warning (found by nightly tests)
+
+------------------------------------------------------------------------
+r6789 | vlefevre | 2010-05-07 15:13:02 +0000 (Fri, 07 May 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/README.dev
+ M /trunk/TODO
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/ai.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/cmp.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/const_euler.c
+ M /trunk/cos.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/digamma.c
+ M /trunk/div.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_u.h
+ M /trunk/fits_uintmax.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/gamma.c
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_flt.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/isinteger.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/mbench/mfv5.cc
+ M /trunk/mbench/mpfr-v6.c
+ M /trunk/modf.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_z.c
+ M /trunk/print_raw.c
+ M /trunk/rem1.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/set_d.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_ld.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_z_exp.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tanh.c
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/random2.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tset_z_exp.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/turandom.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/urandom.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+
+New exponent type mpfr_exp_t for MPFR (replacing GMP's mp_exp_t).
+------------------------------------------------------------------------
+r6788 | vlefevre | 2010-05-07 14:18:54 +0000 (Fri, 07 May 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] Updated a paragraph concerning signed and unsigned types.
+------------------------------------------------------------------------
+r6787 | vlefevre | 2010-05-07 13:57:28 +0000 (Fri, 07 May 2010) | 12 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/tests/tcheck.c
+
+Changed the precision type mpfr_prec_t from an unsigned integer type
+into the corresponding signed integer type, in order to avoid problems
+due to the usual arithmetic conversions when mixing mpfr_prec_t and
+mp_exp_t in an expression.
+* NEWS: mentioned this change.
+* mpfr-impl.h: removed MPFR_INTPREC_MAX (which wasn't used) and updated
+ the MPFR_UNSIGNED_MINUS_MODULO(S,A) macro, which assumed that A was
+ unsigned; this macro now works even when A is signed.
+* mpfr.h: added mpfr_uprec_t; updated mpfr_prec_t and MPFR_PREC_MAX.
+* tests/tcheck.c: disabled a test on MPFR_PREC_MAX+1 with MPFR >= 3
+ (this test doesn't work with a signed mpfr_prec_t and isn't needed).
+Note: all tests pass under GNU Linux x86 and x86_64.
+------------------------------------------------------------------------
+r6786 | vlefevre | 2010-05-07 12:36:55 +0000 (Fri, 07 May 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tcheck.c
+
+[tests/tcheck.c] Forgot to remove a printf (added during testing).
+------------------------------------------------------------------------
+r6785 | vlefevre | 2010-05-07 12:33:57 +0000 (Fri, 07 May 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tcheck.c
+
+[tests/tcheck.c] Support signed mpfr_prec_t (avoid integer overflow).
+------------------------------------------------------------------------
+r6784 | vlefevre | 2010-05-07 12:31:53 +0000 (Fri, 07 May 2010) | 1 line
+Changed paths:
+ M /trunk/tests/mpf_compat.h
+
+[tests/mpf_compat.h] Fixed prototype of function main.
+------------------------------------------------------------------------
+r6783 | vlefevre | 2010-05-07 12:23:22 +0000 (Fri, 07 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.h
+
+[mpfr.h] Added a comment concerning the definition of MPFR_PREC_MAX.
+------------------------------------------------------------------------
+r6782 | vlefevre | 2010-05-06 10:10:52 +0000 (Thu, 06 May 2010) | 2 lines
+Changed paths:
+ M /trunk/print_rnd_mode.c
+
+print_rnd_mode.c: added an assertion so that we do not forget to update
+this file after a new rounding mode is added.
+------------------------------------------------------------------------
+r6780 | vlefevre | 2010-05-03 14:26:06 +0000 (Mon, 03 May 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Added a paragraph about multiple inclusions of mpfr.h and/or
+gmp.h header files.
+------------------------------------------------------------------------
+r6779 | thevenyp | 2010-05-03 14:19:20 +0000 (Mon, 03 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update documentation for mpfr_print_rnd_mode.
+------------------------------------------------------------------------
+r6778 | vlefevre | 2010-05-03 13:15:15 +0000 (Mon, 03 May 2010) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+To avoid breaking the ABI when faithful rounding gets implemented, added
+MPFR_RNDF to the mpfr_rnd_t enum type now, and removed MPFR_RND_MAX from
+the enumeration (it is now defined as a macro in mpfr-impl.h).
+------------------------------------------------------------------------
+r6777 | vlefevre | 2010-05-03 12:52:28 +0000 (Mon, 03 May 2010) | 1 line
+Changed paths:
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+
+fits_* (signed version): corrections and optimizations.
+------------------------------------------------------------------------
+r6776 | vlefevre | 2010-05-03 12:30:46 +0000 (Mon, 03 May 2010) | 5 lines
+Changed paths:
+ M /trunk/fits_u.h
+ M /trunk/fits_uintmax.c
+
+[fits_uintmax.c, fits_u.h] Some casts could be incorrect in the case
+mp_exp_t > mpfr_prec_t. Set prec to the int type since in practice,
+prec will be small enough to fit in an int. The fact that prec is now
+signed allows us to remove a useless test (also note that prec should
+be computed at compile time, so that this should be at least as fast).
+------------------------------------------------------------------------
+r6775 | vlefevre | 2010-05-03 12:04:56 +0000 (Mon, 03 May 2010) | 1 line
+Changed paths:
+ M /trunk/fits_u.h
+ M /trunk/fits_uintmax.c
+
+[fits_uintmax.c, fits_u.h] Comments: doesn't -> don't
+------------------------------------------------------------------------
+r6774 | vlefevre | 2010-05-03 11:10:41 +0000 (Mon, 03 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r6773 | thevenyp | 2010-05-03 09:20:38 +0000 (Mon, 03 May 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+Add specifier 'Y' for the rounding away from zero mode in printf-like functions.
+------------------------------------------------------------------------
+r6772 | zimmerma | 2010-04-30 16:10:44 +0000 (Fri, 30 Apr 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] removed obsolete mpfr_round_prec
+
+------------------------------------------------------------------------
+r6770 | vlefevre | 2010-04-30 15:57:34 +0000 (Fri, 30 Apr 2010) | 1 line
+Changed paths:
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+
+[fits_intmax.c,fits_s.h] Added FIXME comments.
+------------------------------------------------------------------------
+r6769 | vlefevre | 2010-04-30 15:50:27 +0000 (Fri, 30 Apr 2010) | 2 lines
+Changed paths:
+ M /trunk/fits_u.h
+ M /trunk/fits_uintmax.c
+
+Optimized fits_u.h and made fits_uintmax.c like fits_u.h for the
+special numbers.
+------------------------------------------------------------------------
+r6768 | vlefevre | 2010-04-30 15:44:39 +0000 (Fri, 30 Apr 2010) | 1 line
+Changed paths:
+ M /trunk/fits_uintmax.c
+
+Optimized mpfr_fits_uintmax_p.
+------------------------------------------------------------------------
+r6767 | vlefevre | 2010-04-30 14:37:47 +0000 (Fri, 30 Apr 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/README.dev
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/cmp2.c
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/digamma.c
+ M /trunk/eint.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/examples/rndo-add.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/factorial.c
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_u.h
+ M /trunk/fits_uintmax.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_f.c
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init2.c
+ M /trunk/inits2.c
+ M /trunk/isinteger.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/mbench/mpfr-gfx.c
+ M /trunk/mbench/mpfr-v4.c
+ M /trunk/mbench/mpfr-v6.c
+ M /trunk/modf.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/print_raw.c
+ M /trunk/rec_sqrt.c
+ M /trunk/root.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_z_exp.c
+ M /trunk/setmax.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/speed.c
+ M /trunk/sqr.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/turandom.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tuneup.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/urandom.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Changed mp_prec_t into mpfr_prec_t.
+------------------------------------------------------------------------
+r6766 | vlefevre | 2010-04-19 14:35:35 +0000 (Mon, 19 Apr 2010) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+[configure.in] r6765 introduced non-POSIX syntax. Fixed.
+------------------------------------------------------------------------
+r6765 | zimmerma | 2010-04-19 11:26:12 +0000 (Mon, 19 Apr 2010) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+[configure.in] check for GMP internal files only with --with-gmp-build
+
+------------------------------------------------------------------------
+r6764 | vlefevre | 2010-04-12 00:11:48 +0000 (Mon, 12 Apr 2010) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] New function mpfr_regular_p (was added in r6417, 2009-09-14).
+------------------------------------------------------------------------
+r6762 | vlefevre | 2010-04-07 02:15:06 +0000 (Wed, 07 Apr 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+[mpfr-gmp.h] Fixed alloca prototype (bug detected by tcc 0.9.25
+under Linux/x86_64).
+------------------------------------------------------------------------
+r6753 | vlefevre | 2010-03-24 12:45:47 +0000 (Wed, 24 Mar 2010) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Improved/corrected the documentation of functions
+mpfr_lgamma, mpfr_digamma, mpfr_j0/j1/jn, mpfr_y0/y1/yn, mpfr_agm,
+mpfr_hypot and mpfr_min_prec.
+------------------------------------------------------------------------
+r6752 | vlefevre | 2010-03-24 12:24:28 +0000 (Wed, 24 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Removed a "currently" that is no longer needed.
+------------------------------------------------------------------------
+r6751 | vlefevre | 2010-03-24 12:20:41 +0000 (Wed, 24 Mar 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Updated description of mpfr_atan2, now that IEEE 754-2008
+has been published and follows the same conventions as C99 for atan2.
+------------------------------------------------------------------------
+r6750 | vlefevre | 2010-03-24 12:12:00 +0000 (Wed, 24 Mar 2010) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Updated description of mpfr_pow, now that IEEE 754-2008
+has been published and follows the same conventions as C99 for pow.
+(IEEE 754-2008 doesn't currently specify pow(±inf,non-zero), but
+I've suggested a correction for the errata page.)
+------------------------------------------------------------------------
+r6747 | vlefevre | 2010-03-23 15:28:41 +0000 (Tue, 23 Mar 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Improved documentation of mpfr_print_rnd_mode (from a
+suggestion by Chris Saunders).
+------------------------------------------------------------------------
+r6746 | vlefevre | 2010-03-22 10:59:28 +0000 (Mon, 22 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Various corrections and other improvements.
+------------------------------------------------------------------------
+r6745 | vlefevre | 2010-03-22 10:38:59 +0000 (Mon, 22 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Improved the documentation of mpfr_dim too.
+------------------------------------------------------------------------
+r6744 | zimmerma | 2010-03-22 10:04:29 +0000 (Mon, 22 Mar 2010) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] improved the documentation of mpfr_rec_sqrt and mpfr_cbrt
+ (thanks Vincent)
+
+------------------------------------------------------------------------
+r6743 | zimmerma | 2010-03-22 09:30:44 +0000 (Mon, 22 Mar 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] improved documentation of mpfr_sqrt and mpfr_sqrt_ui
+
+------------------------------------------------------------------------
+r6741 | vlefevre | 2010-03-21 18:17:12 +0000 (Sun, 21 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.h
+
+[mpfr.h] Added a comment about integer overflows in macros.
+------------------------------------------------------------------------
+r6740 | zimmerma | 2010-03-19 14:48:17 +0000 (Fri, 19 Mar 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tai.c
+
+[tai.c] enable first test of check_large, and reduced total time
+
+------------------------------------------------------------------------
+r6739 | schevill | 2010-03-19 14:15:23 +0000 (Fri, 19 Mar 2010) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Added a mention about the current limitation of mpfr_ai in mpfr.texi.
+
+
+------------------------------------------------------------------------
+r6738 | schevill | 2010-03-19 13:43:13 +0000 (Fri, 19 Mar 2010) | 6 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/tests/tai.c
+
+Removed check of ai.c for large arguments. I added in algorithms.tex a
+mention about the fact that mpfr_ai is currently not made for large
+arguments.
+
+
+
+------------------------------------------------------------------------
+r6737 | schevill | 2010-03-19 12:16:12 +0000 (Fri, 19 Mar 2010) | 3 lines
+Changed paths:
+ M /trunk/ai.c
+
+* Corrected problems regarding the GNU recommendations for formatting source code.
+
+
+------------------------------------------------------------------------
+r6735 | vlefevre | 2010-03-18 12:55:37 +0000 (Thu, 18 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/tests
+
+tests: added tai to the svn:ignore property.
+------------------------------------------------------------------------
+r6734 | zimmerma | 2010-03-18 12:37:13 +0000 (Thu, 18 Mar 2010) | 3 lines
+Changed paths:
+ M /trunk/tests/tai.c
+
+[tai.c] reduce the maximal exponents in test_generic()
+ also reduce the number of random tests to decrease the test time
+
+------------------------------------------------------------------------
+r6733 | vlefevre | 2010-03-18 12:26:19 +0000 (Thu, 18 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: in the tests, use mpfr_equal_p rather than mpfr_cmp.
+------------------------------------------------------------------------
+r6732 | zimmerma | 2010-03-18 12:23:43 +0000 (Thu, 18 Mar 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tai.c
+
+[tai.c] replace mpfr_cmp by mpfr_equal_p
+
+------------------------------------------------------------------------
+r6731 | vlefevre | 2010-03-18 12:11:29 +0000 (Thu, 18 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tset_z_exp.c
+
+tests/tset_z_exp.c untabified.
+------------------------------------------------------------------------
+r6730 | vlefevre | 2010-03-18 12:11:13 +0000 (Thu, 18 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: removed trailing whitespace.
+------------------------------------------------------------------------
+r6729 | vlefevre | 2010-03-18 11:59:57 +0000 (Thu, 18 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r6728 | vlefevre | 2010-03-18 11:54:24 +0000 (Thu, 18 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/AUTHORS
+
+Untabified AUTHORS (consistency).
+------------------------------------------------------------------------
+r6727 | schevill | 2010-03-18 11:50:39 +0000 (Thu, 18 Mar 2010) | 4 lines
+Changed paths:
+ M /trunk/ai.c
+
+* Corrected problems regarding the GNU recommendations for formatting source code.
+* Corrected the date of the copyright.
+
+
+------------------------------------------------------------------------
+r6726 | zimmerma | 2010-03-18 09:50:20 +0000 (Thu, 18 Mar 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tai.c
+
+[tai.c] added test for large inputs
+
+------------------------------------------------------------------------
+r6725 | zimmerma | 2010-03-18 09:22:02 +0000 (Thu, 18 Mar 2010) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+[AUTHORS] added Sylvain Chevillard
+
+------------------------------------------------------------------------
+r6724 | zimmerma | 2010-03-17 21:12:09 +0000 (Wed, 17 Mar 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] added Sylvain as contributor
+
+------------------------------------------------------------------------
+r6723 | schevill | 2010-03-17 17:35:59 +0000 (Wed, 17 Mar 2010) | 18 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/README.dev
+ A /trunk/ai.c
+ A /trunk/algorithm2e.sty
+ M /trunk/algorithms.tex
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tai.c
+
+* Added function mpfr_ai. The implementation is the most naive: it evaluates
+ the series step by step until it can stop.
+ A special strategy is used to detect possible problems when Ai(x) is very
+ close to 0.
+
+* Updated algorithms.tex with the technical description of the implementation
+ of mpfr_ai.
+
+* Added algorithm2e.sty and algorithm2e-compatibility.sty (necessary to
+ compile algorithms.tex now).
+
+* Updated mpfr.texi to let it know this new function.
+
+* Added a basic test file for mpfr_ai. I will add other test cases later.
+
+* Added a small HOWTO to README.dev about how to add a new test file for new
+ functions.
+
+------------------------------------------------------------------------
+r6720 | vlefevre | 2010-03-11 09:43:53 +0000 (Thu, 11 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tstrtofr.c
+
+GMP_RNDx -> MPFR_RNDx
+------------------------------------------------------------------------
+r6719 | zimmerma | 2010-03-11 09:24:00 +0000 (Thu, 11 Mar 2010) | 3 lines
+Changed paths:
+ M /trunk/tests/tstrtofr.c
+
+[tstrtofr.c] added test for 1.23e, cf
+ http://gmplib.org/list-archives/gmp-bugs/2010-March/001898.html
+
+------------------------------------------------------------------------
+r6718 | vlefevre | 2010-03-11 01:02:58 +0000 (Thu, 11 Mar 2010) | 4 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+[tests/tsqrt.c] Add the test -1 <= x/sqrt(x^2) <= 1, which corresponds
+to -1 <= x/sqrt(x^2+y^2) <= 1 with y = 0. I don't think the test with
+random y is still necessary, though, since even a bad sqrt accuracy
+would not be detected.
+------------------------------------------------------------------------
+r6717 | vlefevre | 2010-03-10 10:07:46 +0000 (Wed, 10 Mar 2010) | 1 line
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+[tests/tsqrt.c] Added a comment about the x/sqrt(x^2+y^2) test.
+------------------------------------------------------------------------
+r6716 | zimmerma | 2010-03-10 09:00:47 +0000 (Wed, 10 Mar 2010) | 4 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+[tsqrt.c] fixed bug reported by Sam Rawlins
+ (https://sympa.inria.fr/sympa/arc/mpfr/2010-03/msg00007.html)
+Note: this "bug" had no noticeable consequences; this can just be seen
+as an incomplete test.
+------------------------------------------------------------------------
+r6715 | zimmerma | 2010-02-26 08:27:10 +0000 (Fri, 26 Feb 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] added item
+
+------------------------------------------------------------------------
+r6714 | zimmerma | 2010-02-24 15:49:04 +0000 (Wed, 24 Feb 2010) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] now also recognize "IEEE double, little endian" long-double
+ format (not tested, should happen on ARM)
+
+------------------------------------------------------------------------
+r6713 | zimmerma | 2010-02-24 15:07:39 +0000 (Wed, 24 Feb 2010) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] added recognition of "IEEE double big endian" long double format
+ (tested on gcc40.fsffrance.org and gcc53, both PowerPC's)
+
+------------------------------------------------------------------------
+r6712 | vlefevre | 2010-02-24 12:59:19 +0000 (Wed, 24 Feb 2010) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] Added test for long double = double-double (GCC/PowerPC).
+This test cannot currently be reliable, so we just output a warning.
+------------------------------------------------------------------------
+r6711 | zimmerma | 2010-02-23 16:39:02 +0000 (Tue, 23 Feb 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] minor grammar fix
+
+------------------------------------------------------------------------
+r6710 | zimmerma | 2010-02-23 16:27:08 +0000 (Tue, 23 Feb 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] be more precise about API compatibility
+
+------------------------------------------------------------------------
+r6709 | zimmerma | 2010-02-23 15:54:30 +0000 (Tue, 23 Feb 2010) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.h
+
+[mpfr.h] added #define mpfr_get_z_exp mpfr_get_z_2exp for compatibility
+
+------------------------------------------------------------------------
+r6708 | vlefevre | 2010-02-23 01:35:39 +0000 (Tue, 23 Feb 2010) | 1 line
+Changed paths:
+ M /trunk/tests
+
+tests: added tset_z_exp to the svn:ignore property.
+------------------------------------------------------------------------
+r6707 | zimmerma | 2010-02-22 17:23:27 +0000 (Mon, 22 Feb 2010) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/atan.c
+ M /trunk/cbrt.c
+ M /trunk/cos.c
+ M /trunk/eint.c
+ M /trunk/exp_2.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/pow.c
+ M /trunk/rem1.c
+ M /trunk/root.c
+ M /trunk/set_z.c
+ M /trunk/set_z_exp.c
+ M /trunk/sin_cos.c
+ M /trunk/tests/tset_z_exp.c
+
+changed mpfr_get_z_exp -> mpfr_get_z_2exp (old function)
+ mpfr_set_z_exp -> mpfr_set_z_2exp (new function)
+
+------------------------------------------------------------------------
+r6706 | zimmerma | 2010-02-22 15:45:30 +0000 (Mon, 22 Feb 2010) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/set_z.c
+ A /trunk/set_z_exp.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tset_z_exp.c
+
+added new function mpfr_set_z_exp (companion to mpfr_get_z_exp)
+
+------------------------------------------------------------------------
+r6705 | vlefevre | 2010-02-18 17:05:48 +0000 (Thu, 18 Feb 2010) | 6 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/tests
+ A /trunk/tests/tstdint.c
+
+* Added tests/tstdint.c to test the double inclusion of mpfr.h when only
+ the second occurrence needs <stdint.h> (this can happen when one uses
+ several libraries that use MPFR under different conditions).
+* Added tstdint to the svn:ignore property of "tests".
+* TODO: mentions that tstdint should be added to check_PROGRAMS in
+ the tests/Makefile.am file once this is fixed.
+------------------------------------------------------------------------
+r6701 | vlefevre | 2010-02-18 02:02:55 +0000 (Thu, 18 Feb 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated Section "Internals".
+------------------------------------------------------------------------
+r6700 | vlefevre | 2010-02-16 17:43:28 +0000 (Tue, 16 Feb 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r6699 | vlefevre | 2010-02-16 17:02:40 +0000 (Tue, 16 Feb 2010) | 5 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+mpfr.h: disable the INTMAX_C / UINTMAX_C test with C++ compilers as it
+doesn't work well in this case (e.g. possible failure with Boost); see
+ https://sympa.inria.fr/sympa/arc/mpfr/2010-02/msg00025.html
+and the whole discussion.
+mpfr.texi: update.
+------------------------------------------------------------------------
+r6696 | zimmerma | 2010-02-05 07:13:10 +0000 (Fri, 05 Feb 2010) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+
+[configure.in] removed check for C++ and Fortran compiler (comment said to
+ remove it for libtool >= 2.0)
+
+------------------------------------------------------------------------
+r6695 | zimmerma | 2010-02-01 09:25:46 +0000 (Mon, 01 Feb 2010) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] dummy change to check if we still get commit mails
+
+------------------------------------------------------------------------
+r6694 | zimmerma | 2010-01-29 13:44:58 +0000 (Fri, 29 Jan 2010) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] added note about mpfr_set_str
+
+------------------------------------------------------------------------
+r6691 | vlefevre | 2010-01-25 10:54:30 +0000 (Mon, 25 Jan 2010) | 3 lines
+Changed paths:
+ M /trunk/get_patches.sh
+
+Simplified get_patches.sh; minor consequence: the trailing space in
+the string returned by mpfr_get_patches() when there are patches is
+no longer present (this trailing space wasn't desired anyway).
+------------------------------------------------------------------------
+r6687 | vlefevre | 2010-01-25 00:33:37 +0000 (Mon, 25 Jan 2010) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: updated message for different gmp.h and libgmp versions.
+See <https://sympa.inria.fr/sympa/arc/mpfr/2010-01/msg00051.html>.
+------------------------------------------------------------------------
+r6686 | vlefevre | 2010-01-20 12:09:45 +0000 (Wed, 20 Jan 2010) | 6 lines
+Changed paths:
+ M /trunk/FAQ.html
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/faq.xsl
+
+FAQ.html, faq.xsl, README, TODO: slightly changed the copyright notice
+to make it consistent with the one of the other files. In short, "and
+the GNU General Public License" has been removed, but it was ambiguous
+(we did not say which version of the GNU GPL) and useless (for GPLv3)
+because the LGPLv3 is compatible with the GPLv3:
+ http://www.fsf.org/licensing/licenses/gpl-faq.html#WhatDoesCompatMean
+------------------------------------------------------------------------
+r6685 | vlefevre | 2010-01-20 11:56:23 +0000 (Wed, 20 Jan 2010) | 3 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL:
+ * added copyright notice (at the top, like GMP);
+ * replaced "Installing MPFR" by "Installing GNU MPFR".
+------------------------------------------------------------------------
+r6684 | vlefevre | 2010-01-20 11:48:25 +0000 (Wed, 20 Jan 2010) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/FAQ.html
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_d.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/bernoulli.c
+ M /trunk/buildopt.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/digamma.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_d.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/examples/divworst.c
+ M /trunk/examples/rndo-add.c
+ M /trunk/examples/sample.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_flt.c
+ M /trunk/get_ld.c
+ M /trunk/get_patches.sh
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/ieee_floats.h
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/isregular.c
+ M /trunk/iszero.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/min_prec.c
+ M /trunk/minmax.c
+ M /trunk/modf.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mparam_h.in
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-longlong.h
+ M /trunk/mpfr-thread.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_d.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/printf.c
+ M /trunk/rec_sqrt.c
+ M /trunk/reldiff.c
+ M /trunk/rem1.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/scale2.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_flt.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/set_zero.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/setsign.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/signbit.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/speed.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_d.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/data/digamma
+ M /trunk/tests/data/li2
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/random2.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tbuildopt.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdigamma.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_flt.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tisqrt.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmin_prec.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/turandom.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandom.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Copyright notice update: added 2010 with
+ perl -pi -e 's/2009 Free Software/2009, 2010 Free Software/' **/*(^/)
+under zsh, reverting the ChangeLog file and the mbench directory.
+------------------------------------------------------------------------
+r6683 | vlefevre | 2010-01-20 11:35:49 +0000 (Wed, 20 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/tests
+
+tests: added turandom to the svn:ignore property.
+------------------------------------------------------------------------
+r6682 | vlefevre | 2010-01-20 11:33:30 +0000 (Wed, 20 Jan 2010) | 3 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: updated paragraphs about the search paths (in particular,
+--with-gmp=/usr/local is no longer chosen as an example as it does
+not work as expected; a note has been added about that).
+------------------------------------------------------------------------
+r6681 | vlefevre | 2010-01-20 09:57:24 +0000 (Wed, 20 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: rewrote a paragraph about search paths.
+------------------------------------------------------------------------
+r6680 | thevenyp | 2010-01-18 18:30:44 +0000 (Mon, 18 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+[urandom.c] Fix case emin > 0.
+------------------------------------------------------------------------
+r6679 | zimmerma | 2010-01-18 15:28:50 +0000 (Mon, 18 Jan 2010) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added more details for random distribution functions
+
+------------------------------------------------------------------------
+r6678 | zimmerma | 2010-01-18 14:30:15 +0000 (Mon, 18 Jan 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+[tprintf.c, tfprintf.c] cleaned up previous commit
+
+------------------------------------------------------------------------
+r6677 | vlefevre | 2010-01-18 13:50:17 +0000 (Mon, 18 Jan 2010) | 2 lines
+Changed paths:
+ M /trunk/tests/turandom.c
+
+tests/turandom.c: updated a test (if emin > 1 and rnd == MPFR_RNDN,
+then the result is necessarily 0).
+------------------------------------------------------------------------
+r6676 | vlefevre | 2010-01-18 13:39:17 +0000 (Mon, 18 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/tests/turandom.c
+
+tests/turandom.c: more tests in restricted exponent range.
+------------------------------------------------------------------------
+r6675 | vlefevre | 2010-01-18 13:27:04 +0000 (Mon, 18 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+urandom.c: corrected a comment.
+------------------------------------------------------------------------
+r6674 | zimmerma | 2010-01-18 12:37:30 +0000 (Mon, 18 Jan 2010) | 3 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+[tprintf.c,tfprintf.c] print obtained chain in test #8
+ (https://sympa.inria.fr/sympa/arc/mpfr/2009-12/msg00035.html)
+
+------------------------------------------------------------------------
+r6673 | thevenyp | 2010-01-18 09:48:47 +0000 (Mon, 18 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+[urandom.c] Fix bug in setting random exponent.
+------------------------------------------------------------------------
+r6672 | vlefevre | 2010-01-16 10:13:53 +0000 (Sat, 16 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+urandom.c: added a FIXME comment.
+------------------------------------------------------------------------
+r6671 | vlefevre | 2010-01-15 17:11:08 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+urandom.c: removed unused variable k; updated a comment.
+------------------------------------------------------------------------
+r6670 | thevenyp | 2010-01-15 16:38:11 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+[urandom.c] Improve generation of random exponent.
+------------------------------------------------------------------------
+r6669 | thevenyp | 2010-01-15 16:36:42 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+[urandom.c] Fix bug introduced in r6667.
+------------------------------------------------------------------------
+r6668 | zimmerma | 2010-01-15 15:17:18 +0000 (Fri, 15 Jan 2010) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added item
+
+------------------------------------------------------------------------
+r6667 | thevenyp | 2010-01-15 14:25:06 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+[urandom.c] Fix case nextabove(0) in reduced exponent range.
+------------------------------------------------------------------------
+r6666 | thevenyp | 2010-01-15 10:06:20 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/tests/turandom.c
+
+[tests/turandom.c] Change accumulation of ternary value in the loop, it was not portable in system with sign and magnitude representation for integers.
+------------------------------------------------------------------------
+r6665 | thevenyp | 2010-01-15 09:51:31 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+[urandom.c] Move generation of a random rounding bit in a separate function.
+------------------------------------------------------------------------
+r6664 | thevenyp | 2010-01-15 09:49:14 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+[urandom.c] Remove trailing whitespace.
+------------------------------------------------------------------------
+r6663 | thevenyp | 2010-01-15 09:32:43 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+[urandom.c] Call mpfr_nextabove in maximum exponent range.
+------------------------------------------------------------------------
+r6662 | vlefevre | 2010-01-15 04:21:01 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+urandom.c: added a FIXME so that it is not forgotten.
+------------------------------------------------------------------------
+r6661 | vlefevre | 2010-01-15 02:01:52 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r6659 | vlefevre | 2010-01-15 01:57:05 +0000 (Fri, 15 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: require bash.
+------------------------------------------------------------------------
+r6658 | vlefevre | 2010-01-14 16:03:37 +0000 (Thu, 14 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/urandom.c
+
+urandom.c: clean-up (avoid a useless goto).
+------------------------------------------------------------------------
+r6657 | vlefevre | 2010-01-14 15:22:37 +0000 (Thu, 14 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added a paragraph (use MPFR_ASSERTN, not printf + exit).
+------------------------------------------------------------------------
+r6656 | thevenyp | 2010-01-14 12:16:15 +0000 (Thu, 14 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Cosmetic change.
+------------------------------------------------------------------------
+r6655 | thevenyp | 2010-01-14 11:55:05 +0000 (Thu, 14 Jan 2010) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/tests/turandom.c
+ M /trunk/urandom.c
+
+[urandom.c, mpfr.texi] Change the behavior of mpfr_urandom to the usual mpfr function interface (wrt the ternary value and the out-of-range behavior).
+[tests/turandom.c] Check new behavior and add a test for the inclusion in [0, 1].
+
+------------------------------------------------------------------------
+r6654 | thevenyp | 2010-01-13 18:12:54 +0000 (Wed, 13 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/turandom.c (from /trunk/tests/trandom.c:6653)
+ A /trunk/urandom.c (from /trunk/urandomb.c:6653)
+
+New function mpfr_urandom.
+------------------------------------------------------------------------
+r6652 | vlefevre | 2010-01-11 15:42:05 +0000 (Mon, 11 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added a note about patches and the autotools.
+------------------------------------------------------------------------
+r6650 | vlefevre | 2010-01-10 23:24:54 +0000 (Sun, 10 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+Added mpfrlint test for the required autoconf versions (see r6649).
+------------------------------------------------------------------------
+r6649 | zimmerma | 2010-01-10 10:27:09 +0000 (Sun, 10 Jan 2010) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/acinclude.m4
+
+[README.dev] required version of autoconf did not agree with acinclude.m4
+
+------------------------------------------------------------------------
+r6648 | vlefevre | 2010-01-08 21:44:07 +0000 (Fri, 08 Jan 2010) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: replaced BITS_PER_MP_LIMB by GMP_NUMB_BITS (should have
+been done in r6645).
+------------------------------------------------------------------------
+r6647 | vlefevre | 2010-01-08 21:37:05 +0000 (Fri, 08 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: check that GMP_LIMB_BITS isn't used.
+------------------------------------------------------------------------
+r6646 | vlefevre | 2010-01-08 21:36:26 +0000 (Fri, 08 Jan 2010) | 1 line
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/algorithms.tex
+ M /trunk/atan.c
+ M /trunk/check.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/configure.in
+ M /trunk/div-short.c
+ M /trunk/div.c
+ M /trunk/div_ui.c
+ M /trunk/eq.c
+ M /trunk/exp.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/extract.c
+ M /trunk/frac.c
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_f.c
+ M /trunk/get_flt.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/gmp_op.c
+ M /trunk/init2.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinteger.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/min_prec.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/rec_sqrt.c
+ M /trunk/rint.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_f.c
+ M /trunk/set_ld.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sin_cos.c
+ M /trunk/speed.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_ui.c
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/random2.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tuneup.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/zeta_ui.c
+
+Replaced GMP_LIMB_BITS by GMP_NUMB_BITS to use only one of these macros.
+------------------------------------------------------------------------
+r6645 | zimmerma | 2010-01-08 20:04:27 +0000 (Fri, 08 Jan 2010) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+
+[configure.in] put back test BITS_PER_MP_LIMB == BYTES_PER_MP_LIMB * CHAR_BIT
+ (this is done only with --with-gmp-build, and BYTES_PER_MP_LIMB
+ is defined in this case in gmp-impl.h, at least in GMP 5)
+
+------------------------------------------------------------------------
+r6644 | zimmerma | 2010-01-08 19:13:48 +0000 (Fri, 08 Jan 2010) | 4 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/algorithms.tex
+ M /trunk/atan.c
+ M /trunk/check.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/configure.in
+ M /trunk/div-short.c
+ M /trunk/div.c
+ M /trunk/div_ui.c
+ M /trunk/eq.c
+ M /trunk/exp.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/extract.c
+ M /trunk/frac.c
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_f.c
+ M /trunk/get_flt.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/gmp_op.c
+ M /trunk/init2.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinteger.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/min_prec.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/rec_sqrt.c
+ M /trunk/rint.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_f.c
+ M /trunk/set_ld.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/speed.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_ui.c
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/random2.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tuneup.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/zeta_ui.c
+
+BITS_PER_MP_LIMB -> GMP_LIMB_BITS
+got rid of BYTES_PER_MP_LIMB in configure.in (no longer defined by GMP)
+Note[VL] (mpfr-impl.h): a mpn_sqr_n() macro is defined to use mpn_mul
+if it is not already defined (in gmp-impl.h from GMP 4.x).
+------------------------------------------------------------------------
+r6643 | vlefevre | 2009-12-23 19:10:15 +0000 (Wed, 23 Dec 2009) | 2 lines
+Changed paths:
+ M /trunk/mbench/Makefile
+
+[mbench/Makefile] Patch from Patrick Pelissier to solve the -I problem
+with GCC.
+------------------------------------------------------------------------
+r6642 | vlefevre | 2009-12-21 00:44:35 +0000 (Mon, 21 Dec 2009) | 1 line
+Changed paths:
+ M /trunk/mbench/Makefile
+
+[mbench/Makefile] Added a comment (warning about the use of -I).
+------------------------------------------------------------------------
+r6641 | zimmerma | 2009-12-20 10:26:22 +0000 (Sun, 20 Dec 2009) | 2 lines
+Changed paths:
+ M /trunk/mbench/Makefile
+
+patch from Patrick Pelissier
+
+------------------------------------------------------------------------
+r6640 | zimmerma | 2009-12-18 14:57:19 +0000 (Fri, 18 Dec 2009) | 8 lines
+Changed paths:
+ M /trunk/exp_2.c
+ M /trunk/mparam_h.in
+ M /trunk/scale2.c
+ M /trunk/tuneup.c
+
+[scale2.c] added missing include (compilation with --with-gmp-build did fail)
+[exp_2.c] small improvements in Smith method: compute x^{2i} as (x^i)^2 instead
+ of x^{i-1} * x. The error analysis is unchanged.
+[tuneup.c] fix for sin_cos threshold (we had a problem since mpfr_sin_cos
+ was calling mpfr_cos, which was calling mpfr_sincos_fast in some
+ cases
+[mparam_h.in] put new thresholds for Core 2 64-bit
+
+------------------------------------------------------------------------
+r6633 | zimmerma | 2009-12-11 09:41:47 +0000 (Fri, 11 Dec 2009) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] reversed order for case "quad, mais en little endian" for
+ coherence with other cases
+
+------------------------------------------------------------------------
+r6632 | zimmerma | 2009-12-10 21:05:50 +0000 (Thu, 10 Dec 2009) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-impl.h
+
+patch to recognize IEEE quad, little endian format for "long double"
+
+------------------------------------------------------------------------
+r6631 | zimmerma | 2009-12-10 15:43:28 +0000 (Thu, 10 Dec 2009) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/get_d.c
+ M /trunk/get_flt.c
+ M /trunk/mpfr-impl.h
+ M /trunk/scale2.c
+
+[scale2.c] now mpfr_scale2 is included in mpfr-impl.h, instead of #including
+ "scale2.c" twice (thus it was compiled twice)
+
+------------------------------------------------------------------------
+r6628 | vlefevre | 2009-12-07 11:53:04 +0000 (Mon, 07 Dec 2009) | 7 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+sin_cos.c: in case of tiny inputs, keep the flags. In practice, this
+fixes the following bug in mpfr_sin_cos (shown by the latest additions
+to tsin_cos.c): if emin is the minimal exponent (MPFR_EMIN_MIN), the
+absolute value of the input is the minimum positive number and the
+rounding mode is toward 0 (or equivalent), then the underflow flag is
+dropped. The other exception cases (e.g., in case of reduced exponent
+range) are handled by mpfr_check_range().
+------------------------------------------------------------------------
+r6627 | vlefevre | 2009-12-07 11:21:51 +0000 (Mon, 07 Dec 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: in consistency(), better error message.
+------------------------------------------------------------------------
+r6626 | vlefevre | 2009-12-07 11:15:46 +0000 (Mon, 07 Dec 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: in consistency(), improved testing on underflow case.
+------------------------------------------------------------------------
+r6625 | vlefevre | 2009-12-07 10:29:57 +0000 (Mon, 07 Dec 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: in consistency(), added testing on underflow case.
+------------------------------------------------------------------------
+r6624 | vlefevre | 2009-12-07 10:22:33 +0000 (Mon, 07 Dec 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: in consistency(), fixed flags testing.
+------------------------------------------------------------------------
+r6623 | vlefevre | 2009-12-07 10:16:17 +0000 (Mon, 07 Dec 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: in consistency(), test also the flags.
+------------------------------------------------------------------------
+r6622 | vlefevre | 2009-12-07 10:10:13 +0000 (Mon, 07 Dec 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: in consistency(), test also the returned value
+(the one that gives inexact-related information).
+------------------------------------------------------------------------
+r6619 | zimmerma | 2009-11-30 15:12:30 +0000 (Mon, 30 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfits.c
+
+[tfits.c] converted to GNU coding style
+
+------------------------------------------------------------------------
+r6612 | vlefevre | 2009-11-30 11:57:07 +0000 (Mon, 30 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated "To make a release".
+------------------------------------------------------------------------
+r6602 | vlefevre | 2009-11-30 02:17:23 +0000 (Mon, 30 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/uceil_exp2.c
+
+uceil_exp2.c: fixed indentation.
+------------------------------------------------------------------------
+r6599 | vlefevre | 2009-11-29 03:17:53 +0000 (Sun, 29 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: got rid of broken code when _GMP_IEEE_FLOATS was defined
+(broken aliasing rules, yielding failures with GCC 4.5.0 20091119).
+------------------------------------------------------------------------
+r6598 | zimmerma | 2009-11-27 06:38:45 +0000 (Fri, 27 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+[tset_ld.c] now perform tests even if old gcc bug is present
+
+------------------------------------------------------------------------
+r6597 | zimmerma | 2009-11-26 16:38:26 +0000 (Thu, 26 Nov 2009) | 4 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+[tget_d.c] removed workaround for old gcc bug. Comment was:
+ /* workaround for gcc bug on m68040-unknown-netbsd1.4.1,
+ where DBL_MIN gives (1-2^(-52))/2^1022 */
+
+------------------------------------------------------------------------
+r6596 | zimmerma | 2009-11-26 16:26:06 +0000 (Thu, 26 Nov 2009) | 9 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tmul.c
+
+[tadd.c, tmul.c] got rid of workaround for old gcc bug. Comment was:
+/* Parameter "z1" of check() used to be last in the argument list, but that
+ tickled a bug in 32-bit sparc gcc 2.95.2. A "double" in that position is
+ passed on the stack at an address which is 4mod8, but the generated code
+ didn't take into account that alignment, resulting in bus errors. The
+ easiest workaround is to move it to the start of the arg list (where it's
+ passed in registers), this macro does that. FIXME: Change the actual
+ calls to check(), rather than using a macro. */
+
+------------------------------------------------------------------------
+r6595 | zimmerma | 2009-11-26 15:58:02 +0000 (Thu, 26 Nov 2009) | 3 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+[strtofr.c] removed patch for old FreeBsd/Alpha bug
+ (http://www.freebsd.org/cgi/query-pr.cgi?pr=72024)
+
+------------------------------------------------------------------------
+r6594 | vlefevre | 2009-11-26 14:15:51 +0000 (Thu, 26 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+[pow_si.c] Updated comment added in r4355 concerning a bug
+in Sun's compiler for Solaris/x86.
+------------------------------------------------------------------------
+r6593 | vlefevre | 2009-11-26 13:38:38 +0000 (Thu, 26 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/pow_si.c
+ M /trunk/strtofr.c
+
+Updated comments concerning the old FreeBSD bug 72024 on LONG_MIN / 1.
+------------------------------------------------------------------------
+r6587 | vlefevre | 2009-11-25 12:16:22 +0000 (Wed, 25 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+[tfprintf.c,tprintf.c] Fixed other types in function with variable
+arguments (even though there were no warnings on the tested machine).
+------------------------------------------------------------------------
+r6586 | vlefevre | 2009-11-25 12:00:43 +0000 (Wed, 25 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+[tfprintf.c,tprintf.c] Fixed types in function with variable arguments.
+------------------------------------------------------------------------
+r6585 | zimmerma | 2009-11-25 11:03:20 +0000 (Wed, 25 Nov 2009) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+[tfprintf.c,tprintf.c] applied patch from Philippe Theveny
+[acinclude.m4] removed check for %zu, no longer needed
+
+------------------------------------------------------------------------
+r6582 | zimmerma | 2009-11-25 10:20:53 +0000 (Wed, 25 Nov 2009) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+[acinclude.m4] added test for %zu
+[tfprintf.c,tprintf.c] added #ifdef's for NPRINTF_ZU
+
+------------------------------------------------------------------------
+r6580 | vlefevre | 2009-11-25 10:16:29 +0000 (Wed, 25 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: corrected a comment.
+------------------------------------------------------------------------
+r6577 | vlefevre | 2009-11-25 09:46:52 +0000 (Wed, 25 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tstckintc.c
+
+tests/tstckintc.c: fixed types for the printf %p format specifier.
+------------------------------------------------------------------------
+r6576 | zimmerma | 2009-11-25 08:33:58 +0000 (Wed, 25 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_flt.c
+
+[tget_flt.c] replaced %a by %.8e
+
+------------------------------------------------------------------------
+r6575 | zimmerma | 2009-11-25 08:23:23 +0000 (Wed, 25 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_ld_2exp.c
+
+[tget_d.c,tget_ld_2exp.c] replaced %a and %La by %.16e and %.16Le
+
+------------------------------------------------------------------------
+r6574 | zimmerma | 2009-11-25 08:05:41 +0000 (Wed, 25 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+[tget_d.c] removed C99-specific instruction
+
+------------------------------------------------------------------------
+r6573 | zimmerma | 2009-11-25 07:51:47 +0000 (Wed, 25 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+[nightly-test] added -ansi -pedantic-errors
+
+------------------------------------------------------------------------
+r6571 | vlefevre | 2009-11-24 17:59:14 +0000 (Tue, 24 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: completed the GMP CC/CFLAGS detection.
+------------------------------------------------------------------------
+r6570 | vlefevre | 2009-11-24 17:52:04 +0000 (Tue, 24 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: added a test to check for CC and CFLAGS in gmp.h only
+when the user doesn't redefine them and he isn't cross-compiling.
+------------------------------------------------------------------------
+r6569 | vlefevre | 2009-11-24 17:32:43 +0000 (Tue, 24 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: improved the GMP CC/CFLAGS detection.
+------------------------------------------------------------------------
+r6568 | vlefevre | 2009-11-24 16:52:57 +0000 (Tue, 24 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: try to fix the GMP CC/CFLAGS detection. Not finished.
+------------------------------------------------------------------------
+r6567 | vlefevre | 2009-11-24 15:48:35 +0000 (Tue, 24 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: replaced "test ... -o ..." (obsolete in POSIX)
+by "test ... || test ...".
+------------------------------------------------------------------------
+r6566 | vlefevre | 2009-11-24 15:44:44 +0000 (Tue, 24 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: replaced "test ... -a ..." (obsolete in POSIX)
+by "test ... && test ...".
+------------------------------------------------------------------------
+r6564 | vlefevre | 2009-11-24 15:23:00 +0000 (Tue, 24 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: made instructions more clear.
+------------------------------------------------------------------------
+r6561 | vlefevre | 2009-11-23 13:55:54 +0000 (Mon, 23 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated "To make a release".
+------------------------------------------------------------------------
+r6560 | vlefevre | 2009-11-23 13:51:21 +0000 (Mon, 23 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: last things to do when making a release.
+------------------------------------------------------------------------
+r6557 | vlefevre | 2009-11-22 23:29:45 +0000 (Sun, 22 Nov 2009) | 10 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+sin_cos.c: fixed a potential bug by changing a rnd_mode into MPFR_RNDZ
+in mpfr_can_round. Indeed, in r4574, the change from
+ if (!mpfr_can_round (c, m, GMP_RNDZ, rnd_mode, MPFR_PREC (z)))
+to
+ if (!mpfr_can_round (c, m, GMP_RNDN, rnd_mode,
+ MPFR_PREC (z) + (rnd_mode == GMP_RNDN)))
+looks wrong to me: in RNDN, the extra bit due to rnd_mode == GMP_RNDN
+changes a RNDN worst case into a RNDZ worst case.
+Note: The second mpfr_can_round with the same problem has been fixed
+in r6513.
+------------------------------------------------------------------------
+r6556 | vlefevre | 2009-11-22 22:44:40 +0000 (Sun, 22 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: ported bug20091122 from the 2.4 branch to the trunk.
+But no failure in the trunk.
+------------------------------------------------------------------------
+r6550 | vlefevre | 2009-11-20 21:40:00 +0000 (Fri, 20 Nov 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tconst_pi.c
+
+tests/tconst_pi.c: fixed types for C++.
+------------------------------------------------------------------------
+r6545 | vlefevre | 2009-11-20 12:48:49 +0000 (Fri, 20 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+Changeset r6162 broke Solaris builds. Fixed that by no longer checking
+INTMAX_MAX and UINTMAX_MAX to detect use of <stdint.h> / <inttypes.h>.
+------------------------------------------------------------------------
+r6535 | zimmerma | 2009-11-01 21:22:16 +0000 (Sun, 01 Nov 2009) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+[cos.c] fixed case where reduced argument is zero
+
+------------------------------------------------------------------------
+r6534 | vlefevre | 2009-10-30 15:13:05 +0000 (Fri, 30 Oct 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+
+tcos.c: added a testcase yielding an assertion failure (this bug makes
+tsin_cos fail).
+------------------------------------------------------------------------
+r6533 | vlefevre | 2009-10-30 15:05:28 +0000 (Fri, 30 Oct 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: ported the consistency test from the 2.4 branch.
+This yields an assertion failure (Linux/x86_64).
+------------------------------------------------------------------------
+r6527 | zimmerma | 2009-10-30 10:09:56 +0000 (Fri, 30 Oct 2009) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/cache.c
+ M /trunk/tests/tconst_pi.c
+
+[cache.c] fixed bug with directed rounding
+[tconst_pi.c] added test for bug with directed rounding
+
+------------------------------------------------------------------------
+r6524 | vlefevre | 2009-10-21 13:38:30 +0000 (Wed, 21 Oct 2009) | 1 line
+Changed paths:
+ M /trunk/exceptions.c
+
+exceptions.c: improved a comment.
+------------------------------------------------------------------------
+r6523 | vlefevre | 2009-10-21 13:21:04 +0000 (Wed, 21 Oct 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: added an overflow test.
+------------------------------------------------------------------------
+r6522 | vlefevre | 2009-10-21 13:13:54 +0000 (Wed, 21 Oct 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: added an overflow test in RNDZ.
+------------------------------------------------------------------------
+r6521 | zimmerma | 2009-10-20 07:21:23 +0000 (Tue, 20 Oct 2009) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added efficiency item
+
+------------------------------------------------------------------------
+r6520 | zimmerma | 2009-10-19 08:16:45 +0000 (Mon, 19 Oct 2009) | 3 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+[lngamma.c] fixed typo, added comments about argument reduction, and replaced
+ code using doubles
+
+------------------------------------------------------------------------
+r6519 | zimmerma | 2009-10-19 06:57:02 +0000 (Mon, 19 Oct 2009) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added efficiency item
+
+------------------------------------------------------------------------
+r6518 | zimmerma | 2009-10-15 11:19:20 +0000 (Thu, 15 Oct 2009) | 4 lines
+Changed paths:
+ M /trunk/exp.c
+
+[exp.c] binary splitting is now used for prec >= MPFR_EXP_THRESHOLD
+ (instead of prec > MPFR_EXP_THRESHOLD before). This is more
+ consistent with the other thresholds.
+
+------------------------------------------------------------------------
+r6517 | zimmerma | 2009-10-15 11:07:26 +0000 (Thu, 15 Oct 2009) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added efficiency item
+
+------------------------------------------------------------------------
+r6516 | zimmerma | 2009-10-15 10:30:55 +0000 (Thu, 15 Oct 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] added /* bits */ for MPFR_EXP_THRESHOLD and MPFR_EXP_2_THRESHOLD
+
+------------------------------------------------------------------------
+r6514 | zimmerma | 2009-10-13 08:11:10 +0000 (Tue, 13 Oct 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+[tsin_cos.c] removed useless instruction, and added comments
+
+------------------------------------------------------------------------
+r6513 | zimmerma | 2009-10-13 06:57:06 +0000 (Tue, 13 Oct 2009) | 3 lines
+Changed paths:
+ M /trunk/sin_cos.c
+ M /trunk/tests/tsin_cos.c
+
+[sin_cos.c] fixed call to mpfr_can_round (rounding mode was wrong)
+[tsin_cos.c] added new test
+
+------------------------------------------------------------------------
+r6512 | zimmerma | 2009-10-13 06:37:15 +0000 (Tue, 13 Oct 2009) | 3 lines
+Changed paths:
+ M /trunk/li2.c
+ M /trunk/tests/tli2.c
+
+[li2.c] fixed bug when x is near 0
+[tli2.c] added new test
+
+------------------------------------------------------------------------
+r6510 | vlefevre | 2009-10-09 07:29:54 +0000 (Fri, 09 Oct 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: mp_rnd_t -> mpfr_rnd_t.
+------------------------------------------------------------------------
+r6509 | vlefevre | 2009-10-09 07:27:36 +0000 (Fri, 09 Oct 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: added a comment about bug20091008, corresponding to
+r6507; in fact, the bug concerns only the return value (see r6444).
+------------------------------------------------------------------------
+r6507 | zimmerma | 2009-10-08 07:51:49 +0000 (Thu, 08 Oct 2009) | 3 lines
+Changed paths:
+ M /trunk/sin_cos.c
+ M /trunk/tests/tsin_cos.c
+
+[sin_cos.c] fixed error analysis
+[tsin_cos.c] added new test
+
+------------------------------------------------------------------------
+r6506 | vlefevre | 2009-10-07 14:18:35 +0000 (Wed, 07 Oct 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: mp_rnd_t -> mpfr_rnd_t.
+------------------------------------------------------------------------
+r6505 | vlefevre | 2009-10-07 12:06:35 +0000 (Wed, 07 Oct 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tests/tsin_cos.c: removed trailing spaces.
+------------------------------------------------------------------------
+r6504 | zimmerma | 2009-10-07 08:58:51 +0000 (Wed, 07 Oct 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+[tsin_cos.c] changed binary to hexadecimal string (was too long for C89)
+
+------------------------------------------------------------------------
+r6503 | zimmerma | 2009-10-07 07:05:13 +0000 (Wed, 07 Oct 2009) | 3 lines
+Changed paths:
+ M /trunk/sin_cos.c
+ M /trunk/tests/tsin_cos.c
+
+[sin_cos.c] fixed bug introduced in r6447 (some variables had their precision not updated in Ziv's loop)
+[tsin_cos.c] added a new test
+
+------------------------------------------------------------------------
+r6498 | vlefevre | 2009-09-29 14:44:22 +0000 (Tue, 29 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update.
+------------------------------------------------------------------------
+r6497 | zimmerma | 2009-09-29 11:28:00 +0000 (Tue, 29 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/round_prec.c
+ M /trunk/tests/tcan_round.c
+
+[mpfr.texi] added note about mpfr_can_round
+[tcan_round.c] added more tests
+
+------------------------------------------------------------------------
+r6490 | zimmerma | 2009-09-24 06:16:52 +0000 (Thu, 24 Sep 2009) | 4 lines
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] added item for new releases: we should say if they are binary
+ and/or API compatible with previous releases (we often forgot
+ to say it in the past)
+
+------------------------------------------------------------------------
+r6489 | vlefevre | 2009-09-23 15:09:42 +0000 (Wed, 23 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests
+
+tests: added tget_flt to the svn:ignore property.
+------------------------------------------------------------------------
+r6488 | vlefevre | 2009-09-23 15:08:39 +0000 (Wed, 23 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+tests/Makefile.am: added information about LOADLIBES.
+------------------------------------------------------------------------
+r6487 | zimmerma | 2009-09-23 13:32:35 +0000 (Wed, 23 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+[tests/Makefile.am] put back LOADLIBES=... (enables to compile a program foo.c
+ in the test directory by simply doing "make foo")
+
+------------------------------------------------------------------------
+r6486 | zimmerma | 2009-09-23 06:21:27 +0000 (Wed, 23 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+[atan.c] updated the comments
+
+------------------------------------------------------------------------
+r6485 | vlefevre | 2009-09-22 15:56:16 +0000 (Tue, 22 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/atan.c
+
+atan.c: added a FIXME comment.
+------------------------------------------------------------------------
+r6484 | vlefevre | 2009-09-22 15:51:15 +0000 (Tue, 22 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/atan.c
+
+atan.c: added some assertions.
+------------------------------------------------------------------------
+r6483 | zimmerma | 2009-09-22 13:58:25 +0000 (Tue, 22 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/algorithms.tex
+ M /trunk/atan.c
+
+[atan.c] implemented argument reduction (cf error analysis in algorithms.tex)
+
+------------------------------------------------------------------------
+r6482 | zimmerma | 2009-09-21 07:34:07 +0000 (Mon, 21 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+[tests/Makefile.am] removed LOADLIBES=...
+
+------------------------------------------------------------------------
+r6480 | vlefevre | 2009-09-20 23:31:37 +0000 (Sun, 20 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: check that lines aren't too long.
+------------------------------------------------------------------------
+r6478 | vlefevre | 2009-09-20 19:07:03 +0000 (Sun, 20 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Makefile.am: line-wrap libmpfr_la_SOURCES (M-q with Emacs) for
+compatibility with some vendor grep.
+------------------------------------------------------------------------
+r6476 | vlefevre | 2009-09-20 19:00:11 +0000 (Sun, 20 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/tests/Makefile.am
+
+Makefile.am, tests/Makefile.am: patch from Ralf Wildenhues.
+http://lists.gnu.org/archive/html/bug-automake/2009-09/msg00033.html
+------------------------------------------------------------------------
+r6475 | vlefevre | 2009-09-18 15:00:09 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/sin_cos.c
+ M /trunk/tests/tsin_cos.c
+
+mpfr-impl.h, sin_cos.c, tests/tsin_cos.c: mp_rnd_t -> mpfr_rnd_t.
+------------------------------------------------------------------------
+r6474 | vlefevre | 2009-09-18 14:55:57 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/sin_cos.c
+
+sin_cos.c: GMP_RNDx -> MPFR_RNDx.
+------------------------------------------------------------------------
+r6473 | vlefevre | 2009-09-18 14:54:38 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/sin_cos.c
+
+sin_cos.c: untabified.
+------------------------------------------------------------------------
+r6471 | vlefevre | 2009-09-18 14:45:47 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/frac.c
+ M /trunk/tests/tfrac.c
+
+frac.c, tests/tfrac.c: fixed underflow case in mpfr_frac and added
+testcase.
+------------------------------------------------------------------------
+r6470 | zimmerma | 2009-09-18 14:03:56 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/atan.c
+
+[acos.c] initial working precision was too small
+
+------------------------------------------------------------------------
+r6469 | vlefevre | 2009-09-18 13:56:21 +0000 (Fri, 18 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/modf.c
+
+modf.c: no longer extend the exponent range at all, since there are
+no intermediate computations (note: the mpfr_frac bug that has just
+been fixed affected this change in modf.c).
+------------------------------------------------------------------------
+r6467 | vlefevre | 2009-09-18 13:50:21 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/frac.c
+
+[frac.c] Patch r6456 was incorrect: the problem with the non-significant
+bits had to be dealt with only in the case t = r. This is now fixed.
+------------------------------------------------------------------------
+r6466 | vlefevre | 2009-09-18 13:47:10 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+tests/tfrac.c: reverted overflow case test (was incorrect because the
+input was too large).
+------------------------------------------------------------------------
+r6465 | vlefevre | 2009-09-18 13:42:12 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+tests/tfrac.c: also test the overflow case.
+------------------------------------------------------------------------
+r6464 | vlefevre | 2009-09-18 13:33:43 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+tests/tfrac.c: more tests (case where the fractional part rounds to 1).
+------------------------------------------------------------------------
+r6463 | zimmerma | 2009-09-18 13:31:56 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] added item
+
+------------------------------------------------------------------------
+r6461 | zimmerma | 2009-09-18 13:10:35 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.texi
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/tuneup.c
+
+[sin.c,cos.c] use mpfr_sincos_fast when prec >= MPFR_SINCOS_THRESHOLD
+
+------------------------------------------------------------------------
+r6460 | vlefevre | 2009-09-18 12:03:38 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+tests/tfrac.c: more tests (there are also problems in rounding away
+from zero or equivalent).
+------------------------------------------------------------------------
+r6459 | zimmerma | 2009-09-18 11:59:23 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+ M /trunk/sin_cos.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tuneup.c
+
+added tuning mechanism for mpfr_sin_cos
+
+------------------------------------------------------------------------
+r6458 | vlefevre | 2009-09-18 11:46:28 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+tests/tfrac.c: also test the ternary value (it is incorrect too).
+------------------------------------------------------------------------
+r6456 | vlefevre | 2009-09-18 11:27:48 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/frac.c
+
+frac.c: fixed bug in mpfr_frac (the non-significant bits in low limb
+were not cleared).
+------------------------------------------------------------------------
+r6455 | vlefevre | 2009-09-18 11:19:11 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+tests/tfrac.c: improved the testcase so that it triggers the bug for
+both 32 bits and 64 bits.
+------------------------------------------------------------------------
+r6454 | vlefevre | 2009-09-18 11:16:00 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+tests/tfrac.c: added a comment for latest testcase.
+------------------------------------------------------------------------
+r6453 | vlefevre | 2009-09-18 11:09:03 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+tests/tfrac.c: added testcase for bug in mpfr_frac.
+------------------------------------------------------------------------
+r6451 | vlefevre | 2009-09-18 10:38:19 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tmodf.c
+
+tests/tmodf.c: typo in error message.
+------------------------------------------------------------------------
+r6450 | vlefevre | 2009-09-18 10:26:26 +0000 (Fri, 18 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/modf.c
+
+modf.c: extending the exponent range in the first two cases is useless
+because there are no intermediate computations (just a mpfr_set). Let's
+do that only for the general case.
+------------------------------------------------------------------------
+r6449 | vlefevre | 2009-09-18 10:23:07 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tmodf.c
+
+tests/tmodf.c: added overflow tests.
+------------------------------------------------------------------------
+r6448 | vlefevre | 2009-09-18 09:27:10 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/modf.c
+
+modf.c: corrected a comment (rounding can yield an overflow, but not
+an underflow).
+------------------------------------------------------------------------
+r6447 | zimmerma | 2009-09-18 09:08:01 +0000 (Fri, 18 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/sin_cos.c
+ M /trunk/tests/tsin_cos.c
+
+[sin_cos.c] added asymptotically fast code, with threshold currently hardcoded
+ at 20000 bits, should be determined by tuneup.c
+
+------------------------------------------------------------------------
+r6446 | vlefevre | 2009-09-18 09:00:24 +0000 (Fri, 18 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_flt.c
+
+Deleted trailing spaces.
+------------------------------------------------------------------------
+r6445 | zimmerma | 2009-09-18 08:13:43 +0000 (Fri, 18 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/modf.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tmodf.c
+
+[modf.c] changed semantics of return value in accordance with mpfr_sin_cos
+
+------------------------------------------------------------------------
+r6444 | zimmerma | 2009-09-17 11:30:18 +0000 (Thu, 17 Sep 2009) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/sin_cos.c
+ M /trunk/sinh_cosh.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tsin_cos.c
+
+[sin_cos.c] more precise meaning of the return value
+[sinh_cosh.c] idem as above
+[taway.c] fixed to check the more precise return value
+
+------------------------------------------------------------------------
+r6443 | zimmerma | 2009-09-16 06:17:47 +0000 (Wed, 16 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] t was not initialized in Newton's example
+
+------------------------------------------------------------------------
+r6442 | zimmerma | 2009-09-15 13:48:15 +0000 (Tue, 15 Sep 2009) | 5 lines
+Changed paths:
+ M /trunk/Makefile.am
+ D /trunk/get_binary32.c
+ A /trunk/get_flt.c (from /trunk/get_binary32.c:6441)
+ D /trunk/set_binary32.c
+ A /trunk/set_flt.c (from /trunk/set_binary32.c:6441)
+ M /trunk/tests/Makefile.am
+ D /trunk/tests/tget_binary32.c
+ A /trunk/tests/tget_flt.c (from /trunk/tests/tget_binary32.c:6441)
+
+changed _binary32 into _flt for file names too:
+ svn mv get_binary32.c get_flt.c
+ svn mv set_binary32.c set_flt.c
+ svn mv tests/tget_binary32.c tests/tget_flt.c
+
+------------------------------------------------------------------------
+r6441 | zimmerma | 2009-09-15 13:42:49 +0000 (Tue, 15 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/mpfr.texi
+
+[TODO] removed an item
+[mpfr.texi] added an example for mpfr_prec_round
+
+------------------------------------------------------------------------
+r6440 | zimmerma | 2009-09-15 13:26:11 +0000 (Tue, 15 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+[NEWS] added mpfr_set_flt and mpfr_get_flt
+
+------------------------------------------------------------------------
+r6439 | zimmerma | 2009-09-15 13:17:40 +0000 (Tue, 15 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/get_binary32.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/set_binary32.c
+ M /trunk/tests/tget_binary32.c
+
+changed suffix _binary32 -> _flt
+[get_binary32.c] fixed a bug in subnormal range
+
+------------------------------------------------------------------------
+r6437 | vlefevre | 2009-09-15 13:15:23 +0000 (Tue, 15 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: bug fix.
+------------------------------------------------------------------------
+r6435 | vlefevre | 2009-09-15 13:13:28 +0000 (Tue, 15 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r6433 | vlefevre | 2009-09-15 13:12:38 +0000 (Tue, 15 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: execute svn in C locale.
+------------------------------------------------------------------------
+r6431 | vlefevre | 2009-09-15 13:10:50 +0000 (Tue, 15 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: check mpfr.texi's UPDATED-MONTH.
+------------------------------------------------------------------------
+r6428 | zimmerma | 2009-09-15 12:21:15 +0000 (Tue, 15 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+[tget_d.c] fixed FIXME
+
+------------------------------------------------------------------------
+r6427 | vlefevre | 2009-09-15 12:12:35 +0000 (Tue, 15 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+tget_d.c code is C99-only (bug introduced in r6424). Please fix!
+------------------------------------------------------------------------
+r6426 | zimmerma | 2009-09-15 11:42:27 +0000 (Tue, 15 Sep 2009) | 2 lines
+Changed paths:
+ A /trunk/get_binary32.c
+
+[get_binary32.c] also forgot in previous commit
+
+------------------------------------------------------------------------
+r6425 | zimmerma | 2009-09-15 11:41:52 +0000 (Tue, 15 Sep 2009) | 2 lines
+Changed paths:
+ A /trunk/set_binary32.c
+
+[set_binary32.c] file forgot in previous commit
+
+------------------------------------------------------------------------
+r6424 | zimmerma | 2009-09-15 11:37:40 +0000 (Tue, 15 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ A /trunk/ieee_floats.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/scale2.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tget_binary32.c
+ M /trunk/tests/tget_d.c
+
+added new functions mpfr_set_binary32 and mpfr_get_binary32
+fixed bug in mpfr_get_d and mpfr_get_decimal64 for RNDA
+
+------------------------------------------------------------------------
+r6423 | zimmerma | 2009-09-15 08:27:20 +0000 (Tue, 15 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] improved description of mpfr_sum, and fixed typo
+
+------------------------------------------------------------------------
+r6421 | vlefevre | 2009-09-14 16:29:44 +0000 (Mon, 14 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: added mpfr_regular_p macro.
+------------------------------------------------------------------------
+r6419 | zimmerma | 2009-09-14 14:12:03 +0000 (Mon, 14 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/sum.c
+
+[sum.c] added reference
+
+------------------------------------------------------------------------
+r6418 | zimmerma | 2009-09-14 13:10:57 +0000 (Mon, 14 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/get_ld.c
+ M /trunk/tests/tget_ld_2exp.c
+
+[get_ld.c] fixed bug reported by Nelson Beebe
+ https://sympa.inria.fr/sympa/arc/mpfr/2009-05/msg00061.html
+
+------------------------------------------------------------------------
+r6417 | zimmerma | 2009-09-14 09:29:55 +0000 (Mon, 14 Sep 2009) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/isregular.c
+ M /trunk/iszero.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tisnan.c
+
+[isregular.c] new function mpfr_regular_p
+[iszero.c] fixed typo in comment
+[tests/tisnan.c] added tests for mpfr_regular_p
+
+------------------------------------------------------------------------
+r6415 | vlefevre | 2009-09-11 22:03:10 +0000 (Fri, 11 Sep 2009) | 6 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: changeset r6414 was incorrect, in particular under Linux
+(at least some platforms), where wint_t is an unsigned int, not an int.
+Instead, let's detect whether integer promotion will occur or not, even
+though the ISO C99 standard requires a wint_t type that doesn't yield
+an integer promotion (7.24.1#2), because mingw32 defines wint_t as an
+unsigned short (thus with integer promotion).
+------------------------------------------------------------------------
+r6414 | zimmerma | 2009-09-11 07:52:33 +0000 (Fri, 11 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+[vasprintf.c] https://sympa.inria.fr/sympa/arc/mpfr/2009-09/msg00012.html
+ (changed __wint_type into int)
+
+------------------------------------------------------------------------
+r6413 | vlefevre | 2009-09-08 08:49:33 +0000 (Tue, 08 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tdigamma.c
+
+tests/tdigamma.c: added missing void in prototype.
+------------------------------------------------------------------------
+r6412 | zimmerma | 2009-09-08 08:35:04 +0000 (Tue, 08 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/digamma.c
+ M /trunk/tests/tdigamma.c
+
+[digamma.c] forgot to set sign for Psi(+Inf)
+
+------------------------------------------------------------------------
+r6411 | zimmerma | 2009-09-04 12:29:27 +0000 (Fri, 04 Sep 2009) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/bernoulli.c
+ M /trunk/digamma.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/mpfr-impl.h
+
+changed function into bernoulli.c (which was static, included 3 times) into
+an internal function mpfr_bernoulli_internal
+
+------------------------------------------------------------------------
+r6410 | zimmerma | 2009-09-03 06:45:11 +0000 (Thu, 03 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] removed psi(=digamma)
+
+------------------------------------------------------------------------
+r6409 | vlefevre | 2009-09-02 23:17:32 +0000 (Wed, 02 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/data/digamma
+
+tests/data/digamma: for the special values, use the new mode '*'
+(exact cases) instead of 'n'.
+------------------------------------------------------------------------
+r6408 | vlefevre | 2009-09-02 23:16:03 +0000 (Wed, 02 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: added special support for exact cases in data_check (to test
+all the rounding modes and check the ternary value).
+------------------------------------------------------------------------
+r6407 | vlefevre | 2009-09-02 23:02:29 +0000 (Wed, 02 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/atan2.c
+ M /trunk/div.c
+ M /trunk/exp2.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-longlong.h
+ M /trunk/mpn_exp.c
+ M /trunk/pow.c
+ M /trunk/pow_z.c
+ M /trunk/rec_sqrt.c
+ M /trunk/rint.c
+ M /trunk/round_near_x.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tsqrt.c
+
+towards -> toward (consistency).
+------------------------------------------------------------------------
+r6404 | vlefevre | 2009-09-02 12:13:23 +0000 (Wed, 02 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/tests
+
+tests: added tdigamma to svn:ignore property.
+------------------------------------------------------------------------
+r6403 | vlefevre | 2009-09-02 12:11:05 +0000 (Wed, 02 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/digamma.c
+
+digamma.c: moved a comment.
+------------------------------------------------------------------------
+r6402 | zimmerma | 2009-09-02 12:08:05 +0000 (Wed, 02 Sep 2009) | 4 lines
+Changed paths:
+ M /trunk/digamma.c
+ M /trunk/tests/data/digamma
+ M /trunk/tests/tests.c
+
+[digamma.c] fixed bug (emin/emax were not restored)
+[data/digamma] added special values
+[tests/tests.c] fix to allow putting nan in data/* files
+
+------------------------------------------------------------------------
+r6401 | zimmerma | 2009-09-02 11:56:48 +0000 (Wed, 02 Sep 2009) | 3 lines
+Changed paths:
+ A /trunk/tests/data/digamma
+ M /trunk/tests/tdigamma.c
+
+[data/digamma] unitary test file for mpfr_digamma
+[tdigamma.c] now use data/digamma
+
+------------------------------------------------------------------------
+r6400 | vlefevre | 2009-09-02 11:54:53 +0000 (Wed, 02 Sep 2009) | 1 line
+Changed paths:
+ M /trunk/digamma.c
+
+Removed trailing whitespace.
+------------------------------------------------------------------------
+r6399 | zimmerma | 2009-09-02 11:39:14 +0000 (Wed, 02 Sep 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+bernoulli.c goes into EXTRA_DIST
+
+------------------------------------------------------------------------
+r6398 | zimmerma | 2009-09-02 11:38:07 +0000 (Wed, 02 Sep 2009) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/algorithms.tex
+ A /trunk/bernoulli.c
+ A /trunk/digamma.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tdigamma.c
+
+[digamma.c] new function mpfr_digamma
+[lngamma.c,li2.c] factored computation of Bernoulli numbers in new file
+ bernoulli.c (also used by digamma.c)
+
+------------------------------------------------------------------------
+r6397 | zimmerma | 2009-08-27 09:27:10 +0000 (Thu, 27 Aug 2009) | 8 lines
+Changed paths:
+ M /trunk/cbrt.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/cos.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/get_z.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/pow.c
+ M /trunk/rem1.c
+ M /trunk/root.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/urandomb.c
+ M /trunk/zeta_ui.c
+
+replaced obsolete GMP functions (suggested by Brian Gladman):
+1. mpz_div_2exp ==> mpz_fdiv_q_2exp
+2. mpz_div_ui ==> mpz_fdiv_q_ui
+3. gmp_randinit (state, GMP_RAND_ALG_LC, 128) ==> gmp_randinit_lc_2exp_size (state, 128)
+(Didn't replace mpn_divrem by mpn_tdiv_qr since the parameters differ, and also
+for efficiency reasons.)
+
+
+------------------------------------------------------------------------
+r6396 | vlefevre | 2009-08-26 23:30:06 +0000 (Wed, 26 Aug 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: fixed locale_da_DK test.
+------------------------------------------------------------------------
+r6394 | zimmerma | 2009-08-26 20:13:50 +0000 (Wed, 26 Aug 2009) | 3 lines
+Changed paths:
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+
+[csch.c,coth.c,csc.c,cot.c] fixed bug for tiny input and RNDA (result was
+ rounded to zero instead of away)
+
+------------------------------------------------------------------------
+r6393 | vlefevre | 2009-08-26 17:01:54 +0000 (Wed, 26 Aug 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: bug fix (uncommented an "exit(1);").
+------------------------------------------------------------------------
+r6390 | zimmerma | 2009-08-26 15:28:25 +0000 (Wed, 26 Aug 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tgeneric.c] revert previous change, bug is elsewhere
+
+------------------------------------------------------------------------
+r6389 | zimmerma | 2009-08-26 15:23:51 +0000 (Wed, 26 Aug 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+[tgeneric.c] temporary fix in mpfr_can_round call (mpfr_can_round does not
+ correctly handle MPFR_RNDA)
+
+------------------------------------------------------------------------
+r6381 | vlefevre | 2009-08-26 08:48:37 +0000 (Wed, 26 Aug 2009) | 5 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+set_ld.c: replaced a struct by a union. The struct was triggering the
+following warning with GCC 4.4:
+ dereferencing type-punned pointer will break strict-aliasing rules
+(possibly due to possible memory alignment problems). The old code
+looked strange anyway and unions are exactly for such kind of things.
+------------------------------------------------------------------------
+r6380 | zimmerma | 2009-08-26 08:10:51 +0000 (Wed, 26 Aug 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tset.c
+
+[tset.c] removed unused variables
+
+------------------------------------------------------------------------
+r6378 | vlefevre | 2009-08-25 12:23:42 +0000 (Tue, 25 Aug 2009) | 4 lines
+Changed paths:
+ M /trunk/tests/tcmp_ld.c
+
+tcmp_ld.c: use "long double" constants.
+Note: this might solve the tcmp_ld failure reported on
+http://www.linuxquestions.org/questions/linux-from-scratch-13/mpfr-2.4.1-check-failures-in-lfs-6.5-rc2-746538/
+(not tested).
+------------------------------------------------------------------------
+r6376 | vlefevre | 2009-08-24 13:21:03 +0000 (Mon, 24 Aug 2009) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: update (new function mpfr_set_zero, added in r6339).
+------------------------------------------------------------------------
+r6375 | vlefevre | 2009-08-24 13:01:15 +0000 (Mon, 24 Aug 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: NaN has a sign bit (in its binary representation),
+but as a FP datum, it does not have a sign.
+------------------------------------------------------------------------
+r6374 | zimmerma | 2009-08-24 12:48:30 +0000 (Mon, 24 Aug 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] added mention of unspecified NaN sign bit for mpfr_set_nan
+
+------------------------------------------------------------------------
+r6372 | vlefevre | 2009-08-21 21:58:15 +0000 (Fri, 21 Aug 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: do not use @code for roundTiesToAway and binary64 as this is
+not code and the IEEE 754-2008 standard doesn't use special typography.
+------------------------------------------------------------------------
+r6369 | vlefevre | 2009-08-21 21:43:16 +0000 (Fri, 21 Aug 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: the sign bit of a NaN is unspecified.
+------------------------------------------------------------------------
+r6368 | vlefevre | 2009-08-18 15:51:08 +0000 (Tue, 18 Aug 2009) | 7 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/README
+ A /trunk/examples
+ A /trunk/examples/ReadMe
+ A /trunk/examples/divworst.c
+ A /trunk/examples/rndo-add.c
+ A /trunk/examples/sample.c
+
+Add examples into $docdir (without using a subdir, as this would be
+a bit bloated just to add a few files).
+ * Added "examples" directory with a ReadMe file and 3 examples.
+ * Makefile.am: added files from the "examples" directory and changed
+ dist_doc_DATA into nobase_dist_doc_DATA so that the "examples"
+ directory is not stripped in the target directory $docdir.
+ * README: added "examples/".
+------------------------------------------------------------------------
+r6367 | vlefevre | 2009-08-18 13:46:15 +0000 (Tue, 18 Aug 2009) | 1 line
+Changed paths:
+ M /trunk/get_str.c
+
+get_str.c: corrected copyright notice, incorrectly modified in r6364.
+------------------------------------------------------------------------
+r6366 | thevenyp | 2009-08-12 14:30:48 +0000 (Wed, 12 Aug 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: Fix typo.
+
+------------------------------------------------------------------------
+r6365 | thevenyp | 2009-08-12 14:10:33 +0000 (Wed, 12 Aug 2009) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+get_str.c: Format a comment.
+
+------------------------------------------------------------------------
+r6364 | thevenyp | 2009-08-12 14:07:24 +0000 (Wed, 12 Aug 2009) | 4 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+get_str.c vasprintf.c: Add support for the rounding away from zero mode.
+mpfr.texi: MPFR_RNDA mode support in printf functions.
+tests/tsprintf.c tests/tget_str.c: Test MPFR_RNDA support.
+
+------------------------------------------------------------------------
+r6363 | vlefevre | 2009-08-06 00:21:17 +0000 (Thu, 06 Aug 2009) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: update.
+------------------------------------------------------------------------
+r6362 | vlefevre | 2009-08-06 00:18:37 +0000 (Thu, 06 Aug 2009) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.texi
+
+Install some documentation files.
+------------------------------------------------------------------------
+r6360 | vlefevre | 2009-08-05 11:39:30 +0000 (Wed, 05 Aug 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated section "Installing MPFR".
+------------------------------------------------------------------------
+r6358 | vlefevre | 2009-08-05 10:39:20 +0000 (Wed, 05 Aug 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: corrected a spelling mistake.
+------------------------------------------------------------------------
+r6356 | vlefevre | 2009-08-05 10:24:16 +0000 (Wed, 05 Aug 2009) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/configure.in
+
+Since GNU Automake 1.11 is available on too few platforms, removed its
+requirement (reverted to 1.10 requirement: 1.10.1 was needed only for
+dist-lzma, which has been removed). Instead, added hardcoded dist-xz
+support (tested with both Automake 1.10.2 and Automake 1.11).
+------------------------------------------------------------------------
+r6354 | vlefevre | 2009-08-04 00:55:30 +0000 (Tue, 04 Aug 2009) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: replaced dist-lzma by dist-xz (the xz format is the
+successor of the lzma format); as a consequence, automake 1.11 is
+needed.
+------------------------------------------------------------------------
+r6353 | vlefevre | 2009-07-30 18:06:49 +0000 (Thu, 30 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/tests/Makefile.am
+
+Makefile.am, tests/Makefile.am: added copyright notice (similar to
+the one of the generated Makefile.in file).
+------------------------------------------------------------------------
+r6352 | vlefevre | 2009-07-30 17:59:36 +0000 (Thu, 30 Jul 2009) | 3 lines
+Changed paths:
+ M /trunk/COPYING
+ M /trunk/README
+
+Since COPYING.LESSER makes a reference to the GPLv3, updated COPYING
+to the GPLv3. Autotool files are now distributed under the same licence
+of MPFR (to avoid any reference to the GPLv2).
+------------------------------------------------------------------------
+r6351 | vlefevre | 2009-07-30 17:47:39 +0000 (Thu, 30 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ A /trunk/COPYING.LESSER (from /trunk/COPYING.LIB:6350)
+ D /trunk/COPYING.LIB
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_d.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/buildopt.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_d.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_patches.sh
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/mbench/Makefile
+ M /trunk/mbench/generate.c
+ M /trunk/mbench/mfv5-arprec.cc
+ M /trunk/mbench/mfv5-cln.cc
+ M /trunk/mbench/mfv5-crlibm.cc
+ M /trunk/mbench/mfv5-libc.cc
+ M /trunk/mbench/mfv5-lidia.cc
+ M /trunk/mbench/mfv5-mpf.cc
+ M /trunk/mbench/mfv5-mpfr.cc
+ M /trunk/mbench/mfv5-ntl.cc
+ M /trunk/mbench/mfv5-pari.cc
+ M /trunk/mbench/mfv5-void.cc
+ M /trunk/mbench/mfv5.cc
+ M /trunk/mbench/mfv5.h
+ M /trunk/mbench/mpfr-gfx.c
+ M /trunk/mbench/mpfr-v4.c
+ M /trunk/mbench/mpfr-v6.c
+ M /trunk/mbench/timp.h
+ M /trunk/min_prec.c
+ M /trunk/minmax.c
+ M /trunk/modf.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mparam_h.in
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-thread.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_d.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/printf.c
+ M /trunk/rec_sqrt.c
+ M /trunk/reldiff.c
+ M /trunk/rem1.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/set_zero.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/setsign.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/signbit.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/speed.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_d.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/data/li2
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/random2.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tbuildopt.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tisqrt.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmin_prec.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Renamed COPYING.LIB as COPYING.LESSER (GNU Coding Standards, #7.3)
+and updated all the references (except in ChangeLog).
+------------------------------------------------------------------------
+r6350 | vlefevre | 2009-07-30 17:38:46 +0000 (Thu, 30 Jul 2009) | 1 line
+Changed paths:
+ M /trunk
+
+Added algorithms.fdb_latexmk to svn:ignore property.
+------------------------------------------------------------------------
+r6349 | thevenyp | 2009-07-30 16:30:24 +0000 (Thu, 30 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tset.c
+
+tests/tset.c: With revision 6339, some tests were moved and added in the function check_special but this one was not called.
+
+------------------------------------------------------------------------
+r6348 | thevenyp | 2009-07-30 16:22:55 +0000 (Thu, 30 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+tests/Makefile.am: Strech check_PROGRAMS list to ease insertion of new tests.
+
+------------------------------------------------------------------------
+r6347 | thevenyp | 2009-07-30 16:03:04 +0000 (Thu, 30 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+Makefile.am: Sort tests in alphabetical order except the very first ones which are needed by the test suite itself.
+
+------------------------------------------------------------------------
+r6340 | thevenyp | 2009-07-20 14:40:40 +0000 (Mon, 20 Jul 2009) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c mpfr.texi: Change behavior with %Rf and an empty precision field. The default precision is now 6 with %Rf and %Rg.
+tests/tprintf.c tests/tfprintf.c tests/tsprintf.c: Change tests with empty precision field and %Rf.
+
+------------------------------------------------------------------------
+r6339 | thevenyp | 2009-07-20 09:22:08 +0000 (Mon, 20 Jul 2009) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/set_zero.c
+ M /trunk/tests/tset.c
+
+Makefile.am mpfr.h mpfr.texi set_zero.c: New function mpfr_set_zero.
+tests/tset.c: Replace all MPFR_ASSERTN with verbose message. Add tests for mpfr_set_zero.
+
+------------------------------------------------------------------------
+r6336 | zimmerma | 2009-07-15 00:30:44 +0000 (Wed, 15 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] hint about patch command
+
+------------------------------------------------------------------------
+r6335 | zimmerma | 2009-07-14 08:37:32 +0000 (Tue, 14 Jul 2009) | 3 lines
+Changed paths:
+ M /trunk/mpn_exp.c
+
+[mpn_exp.c] reverted previous change (MPN_ZERO is a macro for memset, which
+ does not forbid zero size)
+
+------------------------------------------------------------------------
+r6334 | zimmerma | 2009-07-14 07:47:57 +0000 (Tue, 14 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/coth.c
+ M /trunk/tests/tcoth.c
+
+[coth.c, tcoth.c] fixed coth(+/0) which was wrong (reported by Christopher Creutzig)
+
+------------------------------------------------------------------------
+r6333 | zimmerma | 2009-07-14 07:39:38 +0000 (Tue, 14 Jul 2009) | 3 lines
+Changed paths:
+ M /trunk/mpn_exp.c
+
+[mpn_exp.c] fixed bug reported by David Kirkby on Solaris (GMP compiled with
+ Solaris compiler)
+
+------------------------------------------------------------------------
+r6330 | vlefevre | 2009-07-08 13:35:34 +0000 (Wed, 08 Jul 2009) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: typo in a comment.
+------------------------------------------------------------------------
+r6329 | thevenyp | 2009-07-08 13:24:46 +0000 (Wed, 08 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: Fix bug with %Rf, non-zero precision and a value rounded up to the next power of ten.
+
+------------------------------------------------------------------------
+r6328 | vlefevre | 2009-07-08 10:44:31 +0000 (Wed, 08 Jul 2009) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: deleted trailing spaces.
+------------------------------------------------------------------------
+r6326 | vlefevre | 2009-07-08 10:42:02 +0000 (Wed, 08 Jul 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: added tests of some halfway cases.
+------------------------------------------------------------------------
+r6325 | thevenyp | 2009-07-08 09:46:52 +0000 (Wed, 08 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: Fix bug in precision 0 with format %.0Rf (0.5 rounds to 0).
+
+------------------------------------------------------------------------
+r6322 | vlefevre | 2009-07-08 07:39:56 +0000 (Wed, 08 Jul 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: added a test that triggers an assertion failure.
+------------------------------------------------------------------------
+r6319 | vlefevre | 2009-07-08 07:17:20 +0000 (Wed, 08 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: fixed a test and added more tests for %.0Rf with the even
+rounding rule (shows a bug added in the latest corrections).
+------------------------------------------------------------------------
+r6316 | vlefevre | 2009-07-07 08:18:45 +0000 (Tue, 07 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: completed the test on emax (for %Ra and %Rb).
+Everything is OK.
+------------------------------------------------------------------------
+r6315 | vlefevre | 2009-07-07 07:55:06 +0000 (Tue, 07 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: my test was incorrect (I forgot the R), sorry.
+Still completing it...
+------------------------------------------------------------------------
+r6314 | vlefevre | 2009-07-07 07:40:22 +0000 (Tue, 07 Jul 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: comment (so that the test can be ported to the 2.4 branch).
+------------------------------------------------------------------------
+r6313 | vlefevre | 2009-07-07 07:38:00 +0000 (Tue, 07 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: started to write a test for emax, showing a bug (random
+output).
+------------------------------------------------------------------------
+r6311 | vlefevre | 2009-07-06 12:44:41 +0000 (Mon, 06 Jul 2009) | 1 line
+Changed paths:
+ M /trunk/ChangeLog
+
+ChangeLog update with "LC_ALL=en_US.UTF8 TZ=UTC svn log -rHEAD:0 -v".
+------------------------------------------------------------------------
+r6307 | vlefevre | 2009-07-06 11:17:09 +0000 (Mon, 06 Jul 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r6305 | vlefevre | 2009-07-06 11:15:38 +0000 (Mon, 06 Jul 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi consistency: @var{stdout} -> @code{stdout}.
+------------------------------------------------------------------------
+r6303 | vlefevre | 2009-07-06 11:04:50 +0000 (Mon, 06 Jul 2009) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: do not use a potential function call in SAFE_ABS macro.
+------------------------------------------------------------------------
+r6301 | thevenyp | 2009-07-06 08:36:59 +0000 (Mon, 06 Jul 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c tests/tsprintf.c: deleted trailing spaces.
+
+------------------------------------------------------------------------
+r6298 | thevenyp | 2009-06-29 13:09:42 +0000 (Mon, 29 Jun 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: Fix bug when the value to be printed is rounded to the next power of ten with %Rf or %Rg (continuation of fix in r6278).
+tests/tsprintf.c: Add tests for rounding to next power of ten bug with %Rf or %Rg.
+
+------------------------------------------------------------------------
+r6297 | vlefevre | 2009-06-26 15:47:03 +0000 (Fri, 26 Jun 2009) | 1 line
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/cmp2.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/get_z_exp.c
+ M /trunk/hypot.c
+ M /trunk/mpn_exp.c
+ M /trunk/round_prec.c
+ M /trunk/strtofr.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/vasprintf.c
+
+mp_exp_unsigned_t -> mpfr_uexp_t (internal type only).
+------------------------------------------------------------------------
+r6296 | vlefevre | 2009-06-26 15:40:06 +0000 (Fri, 26 Jun 2009) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: check the use of the obsolete mp_rnd_t type.
+------------------------------------------------------------------------
+r6295 | vlefevre | 2009-06-26 15:35:01 +0000 (Fri, 26 Jun 2009) | 1 line
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/README.dev
+ M /trunk/TODO
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_d.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_d.c
+ M /trunk/div_ui.c
+ M /trunk/eint.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/factorial.c
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_u.h
+ M /trunk/fits_uintmax.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_z.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/inp_str.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/minmax.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_d.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/rec_sqrt.c
+ M /trunk/reldiff.c
+ M /trunk/rem1.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_f.c
+ M /trunk/set_ld.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setsign.c
+ M /trunk/si_op.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_d.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/vasprintf.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+mp_rnd_t -> mpfr_rnd_t
+------------------------------------------------------------------------
+r6294 | vlefevre | 2009-06-26 15:19:14 +0000 (Fri, 26 Jun 2009) | 1 line
+Changed paths:
+ M /trunk/add.c
+ M /trunk/agm.c
+ M /trunk/div.c
+ M /trunk/div_ui.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/frac.c
+ M /trunk/hypot.c
+ M /trunk/inp_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/next.c
+ M /trunk/pow_si.c
+ M /trunk/rec_sqrt.c
+ M /trunk/set_d.c
+ M /trunk/set_f.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+ M /trunk/tests/random2.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tui_div.c
+ M /trunk/urandomb.c
+
+Suppressed MPFR_CLEAR_FLAGS (no longer did anything).
+------------------------------------------------------------------------
+r6290 | vlefevre | 2009-06-23 02:17:04 +0000 (Tue, 23 Jun 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r6287 | vlefevre | 2009-06-23 02:06:27 +0000 (Tue, 23 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: fixed description of mpfr_get_str (clash with variables,
+inconsistent cases in the info format).
+------------------------------------------------------------------------
+r6286 | vlefevre | 2009-06-23 01:56:01 +0000 (Tue, 23 Jun 2009) | 1 line
+Changed paths:
+ M /trunk/get_str.c
+
+get_str.c: added a space.
+------------------------------------------------------------------------
+r6283 | vlefevre | 2009-06-21 20:54:34 +0000 (Sun, 21 Jun 2009) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: corrected comments.
+------------------------------------------------------------------------
+r6282 | thevenyp | 2009-06-19 19:55:18 +0000 (Fri, 19 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: convert GMP_RNDx to MPFR_RNDx.
+
+------------------------------------------------------------------------
+r6280 | thevenyp | 2009-06-19 16:40:57 +0000 (Fri, 19 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: Add brace to disambiguate nested if, and remove unused variable.
+
+------------------------------------------------------------------------
+r6279 | thevenyp | 2009-06-19 15:57:09 +0000 (Fri, 19 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+tests/tfprintf.c tests/tprintf.c: Do not test very small values with %f.
+
+------------------------------------------------------------------------
+r6278 | thevenyp | 2009-06-19 15:55:57 +0000 (Fri, 19 Jun 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: Fix bug when the value to be printed is rounded to the next power of ten with %Rf or %Rg.
+tests/tsprintf.c: Add tests for rounding to next power of ten bug.
+
+------------------------------------------------------------------------
+r6277 | zimmerma | 2009-06-18 12:34:24 +0000 (Thu, 18 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added new functions to implement
+
+------------------------------------------------------------------------
+r6276 | thevenyp | 2009-06-16 11:14:48 +0000 (Tue, 16 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/sinh_cosh.c
+
+sinh_cosh.c: precision of intermediate computation no more depends on precision of input variables.
+
+------------------------------------------------------------------------
+r6275 | vlefevre | 2009-06-15 01:58:34 +0000 (Mon, 15 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: new MPFR_VALUE_OF macro, now used by mpfr_get_prec and
+mpfr_get_exp macros (this is cleaner than the old hack).
+------------------------------------------------------------------------
+r6274 | vlefevre | 2009-06-14 11:57:18 +0000 (Sun, 14 Jun 2009) | 5 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: Make sure results of calculations on constants used with
+the fesetround() test are not precomputed by GCC (occurs on MIPS).
+Patch from Maciej W. Rozycki.
+ https://sympa.inria.fr/sympa/arc/mpfr/2009-06/msg00036.html
+ http://article.gmane.org/gmane.comp.lib.mpfr.general/174
+------------------------------------------------------------------------
+r6272 | zimmerma | 2009-06-13 02:00:58 +0000 (Sat, 13 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+[algorithms.tex] bounds for get_str were checked by Mark Dickinson
+
+------------------------------------------------------------------------
+r6271 | zimmerma | 2009-06-12 04:25:44 +0000 (Fri, 12 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+[algorithms.tex] fixed typo
+
+------------------------------------------------------------------------
+r6270 | zimmerma | 2009-06-12 04:17:46 +0000 (Fri, 12 Jun 2009) | 4 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/mpfr.texi
+
+[algorithms.tex] fixed and completed up to b=62 table of bounds for get_str
+[mpfr.texi] fixed description of case n=0 for get_str (case of powers of two
+ bases was not coherent with the code)
+
+------------------------------------------------------------------------
+r6269 | zimmerma | 2009-06-10 18:52:10 +0000 (Wed, 10 Jun 2009) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/get_str.c
+ M /trunk/mpfr.texi
+
+[algorithms.tex] analyzed precisely the cases where the value is m+1 instead
+ of m
+
+------------------------------------------------------------------------
+r6268 | vlefevre | 2009-06-10 05:21:05 +0000 (Wed, 10 Jun 2009) | 11 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: reverted incorrect patch r6267 that makes the test
+no longer work on x86 (with traditional FPU, no SSE), where one
+should get
+ checking for gcc float-conversion bug... yes, use -ffloat-store
+instead of
+ checking for gcc float-conversion bug... no
+Indeed the "volatile" has the effect to have all the intermediate
+results x stored into memory, i.e. it is more or less equivalent
+to the -ffloat-store option, so that it does not allow one to test
+whether -ffloat-store is needed or not (which is the goal of this
+test).
+------------------------------------------------------------------------
+r6267 | zimmerma | 2009-06-09 22:02:10 +0000 (Tue, 09 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+[acinclude.m4] patch from Maciej W. Rozycki on mpfr mailing-list, 9 Jun 2009
+
+------------------------------------------------------------------------
+r6266 | zimmerma | 2009-06-09 18:42:04 +0000 (Tue, 09 Jun 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/data/j0
+ M /trunk/tests/data/j1
+ M /trunk/tests/data/y0
+ M /trunk/tests/data/y1
+
+added more test cases for the Bessel functions (from John Harrison paper at
+Arith19)
+
+------------------------------------------------------------------------
+r6265 | thevenyp | 2009-06-04 17:15:24 +0000 (Thu, 04 Jun 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: Binary output with no digit after the decimal point is now supported. Fix bug when the binary or hexadecimal output value is rounded to the next power of the base. This also change outputs like 0xf.f with format string "%.0Ra" from 8p+1 to 1p+4 (as does gnu libc's printf).
+tests/tsprintf.c: add check for rounding to the next base power and fix some test value with %.0Ra (now output 1p+4 instead of 8p+3).
+
+------------------------------------------------------------------------
+r6264 | thevenyp | 2009-06-03 09:01:22 +0000 (Wed, 03 Jun 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr-longlong.h
+
+mpfr-longlong.h: Update to newer GMP version (changeset 12418:12a1d0bf21f0 Sun Mar 01 23:47:31 2009 +0100), merging modifications from r4657.
+
+------------------------------------------------------------------------
+r6263 | vlefevre | 2009-05-29 13:53:06 +0000 (Fri, 29 May 2009) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: do not use GMP's namespace for identifiers defined in MPFR.
+------------------------------------------------------------------------
+r6261 | vlefevre | 2009-05-29 13:05:24 +0000 (Fri, 29 May 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added: do not use the GMP namespaces...
+------------------------------------------------------------------------
+r6259 | vlefevre | 2009-05-29 12:27:38 +0000 (Fri, 29 May 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: rewrote a comment.
+------------------------------------------------------------------------
+r6258 | thevenyp | 2009-05-29 07:37:23 +0000 (Fri, 29 May 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: Fix bug, "%%" was not correctly displayed when used alone or before a mpfr_t output.
+tests/tfprintf.c tests/tprintf.c: Fix expected values for tests with "%%".
+
+------------------------------------------------------------------------
+r6257 | thevenyp | 2009-05-29 06:56:02 +0000 (Fri, 29 May 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: Restate subsection Formatted Output Functions/Format String.
+
+------------------------------------------------------------------------
+r6256 | thevenyp | 2009-05-28 07:33:43 +0000 (Thu, 28 May 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: details on use of 'P' type in mpfr_printf.
+
+------------------------------------------------------------------------
+r6252 | thevenyp | 2009-05-27 14:59:54 +0000 (Wed, 27 May 2009) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: remind bug fixes since version 2.4.0.
+
+------------------------------------------------------------------------
+r6248 | thevenyp | 2009-05-27 13:17:03 +0000 (Wed, 27 May 2009) | 2 lines
+Changed paths:
+ M /trunk/set_d64.c
+
+set_d64.c: Partial revert of r6190 to fix problem in a simpler way: the decimal digits can be stored in array of char (no need to be unsigned).
+
+------------------------------------------------------------------------
+r6245 | vlefevre | 2009-05-27 02:26:50 +0000 (Wed, 27 May 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r6241 | vlefevre | 2009-05-27 02:20:51 +0000 (Wed, 27 May 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfmod.c
+
+tests/tfmod.c: deleted trailing whitespace.
+------------------------------------------------------------------------
+r6240 | thevenyp | 2009-05-22 10:44:03 +0000 (Fri, 22 May 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+tests/tatan.c: Add test triggering underflow (test coverage is now 100%).
+
+------------------------------------------------------------------------
+r6237 | vlefevre | 2009-05-20 21:54:03 +0000 (Wed, 20 May 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tests/tgeneric.c: for the second computation, increase the precision
+of the inputs in order to trigger the mpfr_fmod bug fixed in r6230
+(and potentially other bugs). Thanks to Eric Veach for the idea.
+------------------------------------------------------------------------
+r6236 | vlefevre | 2009-05-20 21:34:52 +0000 (Wed, 20 May 2009) | 1 line
+Changed paths:
+ M /trunk/tests
+
+Added tbuildopt to svn:ignore property of tests.
+------------------------------------------------------------------------
+r6234 | thevenyp | 2009-05-20 15:28:07 +0000 (Wed, 20 May 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfmod.c
+
+tests/tfmod.c: complete tests with special values.
+
+------------------------------------------------------------------------
+r6233 | thevenyp | 2009-05-20 15:26:47 +0000 (Wed, 20 May 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfmod.c
+
+tests/tfmod.c: code simplification + check ternary value too.
+
+------------------------------------------------------------------------
+r6232 | vlefevre | 2009-05-20 10:34:33 +0000 (Wed, 20 May 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfmod.c
+
+tests/tfmod.c: replaced NULL by (mpfr_ptr) 0 in mpfr_inits2/mpfr_clears.
+------------------------------------------------------------------------
+r6231 | vlefevre | 2009-05-20 10:32:07 +0000 (Wed, 20 May 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/tfmod.c
+
+tests/mpfr-test.h: added mpfr_cmp_ui0 macro (check that x is not a NaN).
+tests/tfmod.c (bug20090519): check that the results are not NaN's and
+replaced GMP_RNDN by MPFR_RNDN.
+------------------------------------------------------------------------
+r6230 | zimmerma | 2009-05-20 10:17:17 +0000 (Wed, 20 May 2009) | 3 lines
+Changed paths:
+ M /trunk/rem1.c
+ M /trunk/tests/tfmod.c
+
+[tests/tfmod.c] added testcase for bug reported by Eric Veach
+[rem1.c] fixed bug reported by Eric Veach
+
+------------------------------------------------------------------------
+r6229 | zimmerma | 2009-05-19 08:20:15 +0000 (Tue, 19 May 2009) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added one item
+
+------------------------------------------------------------------------
+r6220 | lfousse | 2009-05-13 20:33:03 +0000 (Wed, 13 May 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Clarify the fact that mpfr_sum guarantees correct rounding.
+
+------------------------------------------------------------------------
+r6211 | vlefevre | 2009-05-13 15:40:36 +0000 (Wed, 13 May 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: updated a comment.
+------------------------------------------------------------------------
+r6210 | thevenyp | 2009-05-13 15:37:35 +0000 (Wed, 13 May 2009) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: Add a warning comment (removed in r6026).
+[merge -c 6209 from branch 2.4]
+
+------------------------------------------------------------------------
+r6196 | vlefevre | 2009-05-13 00:02:10 +0000 (Wed, 13 May 2009) | 2 lines
+Changed paths:
+ M /trunk/fms.c
+
+fms.c: improve the performance of memory allocations in small precision
+(almost identical to changeset 6195 for fma.c).
+------------------------------------------------------------------------
+r6195 | vlefevre | 2009-05-12 23:54:31 +0000 (Tue, 12 May 2009) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+fma.c: patch by Patrick Pélissier to improve the performance of
+memory allocations in small precision.
+------------------------------------------------------------------------
+r6192 | thevenyp | 2009-05-05 17:13:37 +0000 (Tue, 05 May 2009) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/dump.c
+ M /trunk/get_d64.c
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/out_str.c
+ M /trunk/printf.c
+ M /trunk/set_d.c
+ M /trunk/strtofr.c
+ M /trunk/swap.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tversion.c
+ M /trunk/vasprintf.c
+
+Put '#include <string.h>' in mpfr-impl.h, remove it elsewhere.
+Other cleanup of header inclusion.
+Other change (by mistake): corrections in algorithms.tex
+------------------------------------------------------------------------
+r6191 | vlefevre | 2009-05-05 15:42:32 +0000 (Tue, 05 May 2009) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: corrections / limit to 80 characters per line.
+------------------------------------------------------------------------
+r6190 | thevenyp | 2009-05-05 14:37:42 +0000 (Tue, 05 May 2009) | 2 lines
+Changed paths:
+ M /trunk/get_d64.c
+ M /trunk/set_d64.c
+
+get_d64.c set_d64.c: Fix types.
+
+------------------------------------------------------------------------
+r6189 | thevenyp | 2009-05-05 14:34:41 +0000 (Tue, 05 May 2009) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+ M /trunk/tests/tpow_all.c
+
+printf.c tests/tpow_all.c: <string.h> is not automatically included when compiling with --with-gmp-build option.
+
+------------------------------------------------------------------------
+r6188 | thevenyp | 2009-05-05 14:06:43 +0000 (Tue, 05 May 2009) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ A /trunk/buildopt.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tbuildopt.c
+
+NEWS Makefile.am mpfr.h mpfr.texi buildopt.c: New functions mpfr_buildopt_tls_p and mpfr_buildopt_decimal_p.
+tests/Makefile.am tests/tbuildopt.c: Add tests for mpfr_buildopt_tls_p and mpfr_buildopt_decimal_p.
+
+------------------------------------------------------------------------
+r6187 | vlefevre | 2009-05-05 13:55:21 +0000 (Tue, 05 May 2009) | 1 line
+Changed paths:
+ M /trunk/atan.c
+
+atan.c: added comments after checking r6186.
+------------------------------------------------------------------------
+r6186 | thevenyp | 2009-05-05 10:07:47 +0000 (Tue, 05 May 2009) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/tests/tatan.c
+
+atan.c: expand exponent range when computing arctan(Inf) and arctan(+-1).
+tests/tatan.c: Check underflow of arctan(Inf) and arctan(1) with reduced exponent range.
+
+------------------------------------------------------------------------
+r6185 | vlefevre | 2009-05-04 16:27:56 +0000 (Mon, 04 May 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tatan.c
+
+tests/tatan.c: replaced GMP_RNDN by MPFR_RNDN.
+------------------------------------------------------------------------
+r6182 | vlefevre | 2009-04-29 16:19:26 +0000 (Wed, 29 Apr 2009) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/tests/tget_f.c
+
+Removed trailing spaces.
+------------------------------------------------------------------------
+r6181 | zimmerma | 2009-04-29 16:07:29 +0000 (Wed, 29 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+[atan.c] fixed bug when x is very near but differs from 1
+
+------------------------------------------------------------------------
+r6180 | vlefevre | 2009-04-29 15:41:23 +0000 (Wed, 29 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+tests/tatan.c: added testcase for bug found by Christopher Creutzig
+(atan2_different_prec).
+------------------------------------------------------------------------
+r6177 | vlefevre | 2009-04-22 12:46:41 +0000 (Wed, 22 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c (data_check): try to open the data file first from the
+build directory, then from the source directory.
+------------------------------------------------------------------------
+r6176 | vlefevre | 2009-04-22 12:00:23 +0000 (Wed, 22 Apr 2009) | 4 lines
+Changed paths:
+ M /trunk/init2.c
+
+init2.c: check that mp_bits_per_limb == BITS_PER_MP_LIMB (useful
+in case GMP is upgraded with a different ABI, e.g. 32 vs mode32
+on PowerPC 64). Without such a check, MPFR can give incorrect
+results if the ABI's don't match.
+------------------------------------------------------------------------
+r6175 | vlefevre | 2009-04-22 08:33:57 +0000 (Wed, 22 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tmul.c
+
+Improved fix for problem dealt with in r6174: use function src_fopen()
+(from tests.c) instead of a macro MPFR_SRCDIR.
+------------------------------------------------------------------------
+r6174 | vlefevre | 2009-04-22 08:13:40 +0000 (Wed, 22 Apr 2009) | 10 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tmul.c
+
+Fixed problem when the srcdir value contains a word that is #define'd
+by the C implementation (test failure) or a comma (worse, the build of
+the tests terminates with an error). This can happen only when objdir
+and srcdir are different directories.
+ * tests/Makefile.am (tmul_CPPFLAGS): Put srcdir pathname in quotes.
+ * tests/tmul.c (MPFR_SRCDIR): Make the default a string.
+ (QUOTE, NAME): Delete.
+ (check_regression): Don't QUOTE MPFR_SRCDIR.
+Thanks to Sandra Loosemore for the patch.
+https://sympa.inria.fr/sympa/arc/mpfr/2009-04/msg00038.html
+------------------------------------------------------------------------
+r6173 | thevenyp | 2009-04-15 17:07:42 +0000 (Wed, 15 Apr 2009) | 3 lines
+Changed paths:
+ M /trunk/get_f.c
+ M /trunk/tests/tget_f.c
+
+get_f.c: remove dead code (x and z always have the same number of limbs).
+tests/tget_f.c: Add tests with every rounding mode, add tests with random values.
+
+------------------------------------------------------------------------
+r6172 | thevenyp | 2009-04-15 09:34:54 +0000 (Wed, 15 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_f.c
+
+tests/tget_f.c: Fix typos, better error messages.
+
+------------------------------------------------------------------------
+r6171 | thevenyp | 2009-04-14 14:34:20 +0000 (Tue, 14 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/get_f.c
+ M /trunk/tests/tget_f.c
+
+tests/tget_f.c get_f.c: Set result to the maximum value when the mpfr_t is plus infinity and set correct ternary value.
+
+------------------------------------------------------------------------
+r6170 | thevenyp | 2009-04-14 14:29:16 +0000 (Tue, 14 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_f.c
+
+tests/tget_f.c: Fix typo, increase size of y so that x and y have different limb size (they had the same size on MacOS X-32bits).
+
+------------------------------------------------------------------------
+r6168 | vlefevre | 2009-04-10 08:29:47 +0000 (Fri, 10 Apr 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: update concerning intmax_t after the change in r6166.
+------------------------------------------------------------------------
+r6166 | vlefevre | 2009-04-10 08:23:33 +0000 (Fri, 10 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: for intmax_t, also test _STDINT_H and _STDINT_H_.
+[merged changeset r6165 from the 2.4 branch]
+------------------------------------------------------------------------
+r6164 | vlefevre | 2009-04-10 08:10:37 +0000 (Fri, 10 Apr 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r6162 | vlefevre | 2009-04-10 08:09:47 +0000 (Fri, 10 Apr 2009) | 5 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+mpfr.h: for the intmax_t detection, also test INTMAX_MAX / UINTMAX_MAX
+(this may be useful for users of C++ compilers, if they have defined
+__STDC_LIMIT_MACROS but not __STDC_CONSTANT_MACROS).
+mpfr.texi: improvement concerning the use of intmax_t and uintmax_t.
+[merged changesets r6160 and r6161 from the 2.4 branch]
+------------------------------------------------------------------------
+r6159 | zimmerma | 2009-04-09 07:40:14 +0000 (Thu, 09 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] updated Notes on AIX/PowerPC
+
+------------------------------------------------------------------------
+r6158 | thevenyp | 2009-04-08 14:59:21 +0000 (Wed, 08 Apr 2009) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/get_f.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_f.c
+
+NEWS mpfr.texi get_f.c: mpfr_get_f now returns the usual ternary value.
+tests/tget_f.c: test the ternary value and the erange flag.
+
+------------------------------------------------------------------------
+r6157 | vlefevre | 2009-04-08 14:25:26 +0000 (Wed, 08 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/get_z.c
+ M /trunk/tests/tget_z.c
+
+tests/tget_z.c: do not assume specific values of the ternary value.
+get_z.c: simplified code.
+------------------------------------------------------------------------
+r6156 | vlefevre | 2009-04-08 14:19:23 +0000 (Wed, 08 Apr 2009) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: s/an inexact value/a ternary value/
+------------------------------------------------------------------------
+r6155 | thevenyp | 2009-04-08 12:53:37 +0000 (Wed, 08 Apr 2009) | 4 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/get_z.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_z.c
+
+NEWS mpfr.texi get_z.c: mpfr_get_z now returns an inexact value.
+mpfr.h: change prototype of mpfr_get_z.
+tests/tget_z.c: test inexact value.
+
+------------------------------------------------------------------------
+r6154 | zimmerma | 2009-04-08 11:10:46 +0000 (Wed, 08 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+[mpf2mpfr.h] added comment for #endif
+
+------------------------------------------------------------------------
+r6153 | thevenyp | 2009-04-08 11:09:14 +0000 (Wed, 08 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+mpf2mpfr.h: fix typo
+
+------------------------------------------------------------------------
+r6152 | vlefevre | 2009-04-02 16:03:05 +0000 (Thu, 02 Apr 2009) | 1 line
+Changed paths:
+ M /trunk/get_z.c
+
+get_z.c: fixed title in comment.
+------------------------------------------------------------------------
+r6151 | vlefevre | 2009-04-01 14:22:03 +0000 (Wed, 01 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/get_z.c
+
+get_z.c: detect out-of-range precision (such a detection could be missed
+if mpfr_exp_t > mpfr_prec_t).
+------------------------------------------------------------------------
+r6150 | vlefevre | 2009-04-01 14:07:29 +0000 (Wed, 01 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/get_z.c
+ M /trunk/mpfr.h
+
+Removed the comment from mpfr.h added in r6149, and patched get_z.c
+(safer code is better than a comment).
+------------------------------------------------------------------------
+r6149 | vlefevre | 2009-04-01 14:02:14 +0000 (Wed, 01 Apr 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: important comment to validate the change done in r6147.
+------------------------------------------------------------------------
+r6148 | vlefevre | 2009-04-01 13:46:30 +0000 (Wed, 01 Apr 2009) | 1 line
+Changed paths:
+ M /trunk/get_z_exp.c
+
+get_z_exp.c: updated comments.
+------------------------------------------------------------------------
+r6147 | zimmerma | 2009-04-01 13:26:42 +0000 (Wed, 01 Apr 2009) | 3 lines
+Changed paths:
+ M /trunk/get_z.c
+ M /trunk/tests/tget_z.c
+
+[get_z.c] simplified the code, removed the FIXME
+[tget_z.c] added new test
+
+------------------------------------------------------------------------
+r6146 | zimmerma | 2009-04-01 13:11:13 +0000 (Wed, 01 Apr 2009) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_z.c
+
+[mpfr.texi] completed documentation of mpfr_get_z_exp (was incomplete for 0)
+[tget_z.c] added test case for 0 with emin > 0 (should give 100% coverage for
+ get_z.c)
+
+------------------------------------------------------------------------
+r6145 | thevenyp | 2009-03-30 14:47:28 +0000 (Mon, 30 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/strtofr.c
+ M /trunk/tests/tset_str.c
+ M /trunk/vasprintf.c
+
+strtofr.c tests/tset_str.c: Code simplification (sizeof (char) is always 1).
+vasprintf.c: Cast into size_t (just in case).
+
+------------------------------------------------------------------------
+r6144 | thevenyp | 2009-03-30 12:15:40 +0000 (Mon, 30 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: Code simplification (sizeof (char) is always 1).
+
+------------------------------------------------------------------------
+r6143 | thevenyp | 2009-03-27 09:34:03 +0000 (Fri, 27 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/printf.c
+ M /trunk/vasprintf.c
+
+acinclude.m4: remove definition of va_copy, just detect its presence.
+printf.c vasprintf.c: #define a replacement of va_copy if needed (in the same way as gmp).
+
+------------------------------------------------------------------------
+r6142 | thevenyp | 2009-03-26 15:09:38 +0000 (Thu, 26 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: Change MPFR_FUNC_PRINTF_SPEC (renamed MPFR_FUNC_GMP_PRINTF_SPEC) so that it actually checks output.
+
+------------------------------------------------------------------------
+r6141 | thevenyp | 2009-03-25 17:53:50 +0000 (Wed, 25 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.texi
+ M /trunk/mpn_exp.c
+ M /trunk/out_str.c
+ M /trunk/tests/inp_str.data
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tset_str.c
+
+Change base upper limit in string conversion up to 62.
+
+------------------------------------------------------------------------
+r6140 | zimmerma | 2009-03-25 12:13:58 +0000 (Wed, 25 Mar 2009) | 4 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_str.c
+
+[mpfr.texi] fixed documentation of mpfr_get_str which was wrong
+[tget_str.c] added test cases for odd base and tie breaking case
+[get_str.c] fixed typos in comments
+
+------------------------------------------------------------------------
+r6139 | zimmerma | 2009-03-25 08:54:17 +0000 (Wed, 25 Mar 2009) | 5 lines
+Changed paths:
+ M /trunk/tests/random2.c
+
+[tests/random2.c] added missing mpfr-test.h (revealed by nightly tests), and
+ removed mpfr-impl.h (already included in mpfr-test.h)
+ I have also removed MPFR_NEED_LONGLONG_H: I don't see why it
+ is needed, and all tests pass.
+
+------------------------------------------------------------------------
+r6138 | thevenyp | 2009-03-24 17:19:55 +0000 (Tue, 24 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: Add a note on mpfr_printf output in binary with precision one.
+
+------------------------------------------------------------------------
+r6137 | thevenyp | 2009-03-24 16:51:17 +0000 (Tue, 24 Mar 2009) | 4 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/random2.c
+ M /trunk/tests/tests.c
+ M /trunk/urandomb.c
+
+urandomb.c mpfr-gmp.c mpfr-gmp.h: mpfr_rand_raw is now in urandom.c.
+mpfr-impl.h: mpfr_rand_raw is now always build as an internal function.
+TODO tests/tests.c tests/random2.c: Use mpfr_rand_raw instead of _gmp_rand
+
+------------------------------------------------------------------------
+r6136 | thevenyp | 2009-03-24 15:10:52 +0000 (Tue, 24 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ D /trunk/random2.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ A /trunk/tests/random2.c (from /trunk/random2.c:6135)
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+
+Move mpfr_random2 to tests directory, remove it from API.
+
+------------------------------------------------------------------------
+r6135 | thevenyp | 2009-03-24 14:29:04 +0000 (Tue, 24 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: Improve documentation in Formatted Output Functions/Format String subsection.
+
+------------------------------------------------------------------------
+r6134 | vlefevre | 2009-03-24 11:33:41 +0000 (Tue, 24 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/sin.c
+
+cos.c, sin.c: added MPFR_ASSERTN for huge expx.
+------------------------------------------------------------------------
+r6132 | vlefevre | 2009-03-21 00:52:31 +0000 (Sat, 21 Mar 2009) | 6 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/tests/tstrtofr.c
+
+mpfr.texi: corrected mpfr_strtofr documentation ("NAN()" is accepted).
+tests/tstrtofr.c: added a test for "NAN()".
+Note: the code follows the ISO C99 standard for strtod, as explained
+in the mpfr_strtofr documentation, so that the code was correct.
+[merged changeset 6131 from the 2.4 branch and changed GMP_RNDN into
+MPFR_RNDN]
+------------------------------------------------------------------------
+r6130 | vlefevre | 2009-03-19 02:11:38 +0000 (Thu, 19 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: added some tests for acinclude.m4 and configure.in (sh).
+------------------------------------------------------------------------
+r6128 | vlefevre | 2009-03-19 02:03:29 +0000 (Thu, 19 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Applied patch from Ralf Wildenhues.
+ * configure.in: Avoid unportable (and unneeded) shell quoting.
+ * acinclude.m4: Avoid non-POSIX shell construct.
+------------------------------------------------------------------------
+r6126 | vlefevre | 2009-03-18 11:15:05 +0000 (Wed, 18 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tmin_prec.c
+
+tests/tmin_prec.c: replaced GMP_RNDN by MPFR_RNDN.
+------------------------------------------------------------------------
+r6125 | vlefevre | 2009-03-16 18:38:03 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+tests/tset_ld.c: removed unused variable.
+------------------------------------------------------------------------
+r6124 | thevenyp | 2009-03-16 17:46:18 +0000 (Mon, 16 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+tests/tset_ld.c: Add test case for the bug fixed with r6101.
+
+------------------------------------------------------------------------
+r6123 | vlefevre | 2009-03-16 15:50:58 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tmin_prec.c
+
+tests/tmin_prec.c: added tests.
+------------------------------------------------------------------------
+r6122 | vlefevre | 2009-03-16 15:43:39 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests
+
+tests: updated svn:ignore property.
+------------------------------------------------------------------------
+r6121 | vlefevre | 2009-03-16 15:40:48 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/min_prec.c
+
+min_prec.c: fixed another bug (the code was incorrect with >= 2 limbs).
+------------------------------------------------------------------------
+r6120 | vlefevre | 2009-03-16 15:37:10 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tmin_prec.c
+
+tests/tmin_prec.c: bug fix (side effects in MPFR_ASSERTN), new tests.
+------------------------------------------------------------------------
+r6119 | vlefevre | 2009-03-16 15:28:11 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added a note about assertions and code with side effects.
+------------------------------------------------------------------------
+r6118 | thevenyp | 2009-03-16 15:23:46 +0000 (Mon, 16 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+
+tests/tfprintf.c: Use a value less than 2^31-1 compatible (thus < LONG_MAX) in bug_20090316 (cf r6112).
+
+------------------------------------------------------------------------
+r6117 | vlefevre | 2009-03-16 15:07:50 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tmin_prec.c
+
+Replaced GMP_RND* by MPFR_RND*.
+------------------------------------------------------------------------
+r6116 | zimmerma | 2009-03-16 12:50:24 +0000 (Mon, 16 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tmin_prec.c
+
+[tests/tmin_prec.c] new file contributed from Laurent Fousse
+[tests/Makefile.am] added tmin_prec
+
+------------------------------------------------------------------------
+r6115 | vlefevre | 2009-03-16 12:35:27 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/min_prec.c
+
+min_prec.c: removed a useless test.
+------------------------------------------------------------------------
+r6114 | vlefevre | 2009-03-16 12:30:20 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/min_prec.c
+
+min_prec.c: fixed another bug.
+------------------------------------------------------------------------
+r6113 | thevenyp | 2009-03-16 12:26:29 +0000 (Mon, 16 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: Add more debug assertion on the buffer size.
+
+------------------------------------------------------------------------
+r6112 | thevenyp | 2009-03-16 12:03:43 +0000 (Mon, 16 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: Fix bug_20090316 (in buffer_cat, the buffer was 1 character too small in some cases).
+tests/tfprintf.c: Add test for bug_20090316.
+
+------------------------------------------------------------------------
+r6111 | vlefevre | 2009-03-16 11:57:41 +0000 (Mon, 16 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+tests/tadd.c: changed GMP_RND* (from r6071) into MPFR_RND*; this should
+have been done when porting the patch from the 2.4 branch.
+------------------------------------------------------------------------
+r6110 | thevenyp | 2009-03-16 10:25:16 +0000 (Mon, 16 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c: Use new environment variable MPFR_CHECK_LARGEMEM for memory expensive test.
+
+------------------------------------------------------------------------
+r6109 | vlefevre | 2009-03-16 10:12:57 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/min_prec.c
+
+min_prec.c: bug fixed by Laurent.
+------------------------------------------------------------------------
+r6108 | thevenyp | 2009-03-16 10:01:24 +0000 (Mon, 16 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: Fix typo.
+
+------------------------------------------------------------------------
+r6107 | vlefevre | 2009-03-16 09:32:21 +0000 (Mon, 16 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/min_prec.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+Fixed the prototype of mpfr_min_prec (should return a mpfr_prec_t)
+and its description.
+------------------------------------------------------------------------
+r6106 | vlefevre | 2009-03-16 09:26:54 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/min_prec.c
+
+min_prec.c: fixed a bug (but the code should be improved).
+------------------------------------------------------------------------
+r6105 | vlefevre | 2009-03-16 09:23:46 +0000 (Mon, 16 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/min_prec.c
+
+min_prec.c: simplified the singular cases (see other functions).
+------------------------------------------------------------------------
+r6104 | lfousse | 2009-03-15 20:44:23 +0000 (Sun, 15 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Add protoype for mpfr_min_prec in mpfr.h.
+
+------------------------------------------------------------------------
+r6103 | lfousse | 2009-03-15 20:34:33 +0000 (Sun, 15 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add documentation for mpfr_min_prec.
+
+------------------------------------------------------------------------
+r6102 | lfousse | 2009-03-15 20:34:00 +0000 (Sun, 15 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/min_prec.c
+
+New function mpfr_min_prec.
+
+------------------------------------------------------------------------
+r6101 | vlefevre | 2009-03-15 03:17:06 +0000 (Sun, 15 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/get_ld.c
+
+get_ld.c: fixed bugs in the case HAVE_LDOUBLE_IEEE_EXT_LITTLE (one found
+by Steve Kargl, and another one concerning the mpfr_set_emax value).
+------------------------------------------------------------------------
+r6100 | thevenyp | 2009-03-13 17:58:59 +0000 (Fri, 13 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: This is probably dead code, but being uncertain, put an assert here.
+
+------------------------------------------------------------------------
+r6099 | thevenyp | 2009-03-13 17:55:13 +0000 (Fri, 13 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: As the buffer helper functions are not used in the current code with a zero parameter len, do not handle this case anymore, check that these cases do not happend in MPFR_ASSERTD macros, add some additional assert to ensure consistency.
+
+------------------------------------------------------------------------
+r6098 | thevenyp | 2009-03-13 17:47:57 +0000 (Fri, 13 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: make clear that string_buffer.curr is a pointer to the null terminating character, fix the only place where it was not handle so.
+
+------------------------------------------------------------------------
+r6097 | thevenyp | 2009-03-13 17:36:20 +0000 (Fri, 13 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: Fix bug.
+
+------------------------------------------------------------------------
+r6096 | thevenyp | 2009-03-13 17:30:10 +0000 (Fri, 13 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+tests/tprintf.c: Add an expensive test where the output number has more than INT_MAX characters.
+vasprintf.c: Fix the bug triggered by the new test in tsprintf.c.
+
+------------------------------------------------------------------------
+r6095 | thevenyp | 2009-03-13 17:17:42 +0000 (Fri, 13 Mar 2009) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsprintf.c
+
+mpfr.texi: Do cosmetic changes and add some details on printf behavior when the precision field is empty.
+tests/tsprintf.c: improve code coverage.
+tests/tprintf.c: improve code coverage, check the behavior describe in mpfr.texi.
+
+------------------------------------------------------------------------
+r6091 | vlefevre | 2009-03-12 12:54:29 +0000 (Thu, 12 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/zeta_ui.c
+
+zeta_ui.c: correction r6090 was incorrect as there was another problem:
+the 3rd argument of mpz_divexact_ui is an unsigned long, not a limb.
+So, fixed the shift count (assuming no padding bits in unsigned long).
+------------------------------------------------------------------------
+r6090 | vlefevre | 2009-03-12 12:45:21 +0000 (Thu, 12 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/zeta_ui.c
+
+zeta_ui.c bug fix: a shift count could be >= width of type (if a limb is
+a long long and long long is twice the size of a long). This problem was
+detected by a warning on gcc40 with CFLAGS="-mpowerpc64 -mcpu=970 -O2".
+------------------------------------------------------------------------
+r6088 | vlefevre | 2009-03-10 01:11:36 +0000 (Tue, 10 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c: added missing cast to void * for %p.
+------------------------------------------------------------------------
+r6086 | vlefevre | 2009-03-09 15:51:27 +0000 (Mon, 09 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfprintf.c
+
+tests/tfprintf.c: added missing cast to void * for %p.
+------------------------------------------------------------------------
+r6084 | vlefevre | 2009-03-09 15:42:51 +0000 (Mon, 09 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: fixed bug in CONSUME_VA_ARG for case MP_LIMB_ARG (%Mu).
+------------------------------------------------------------------------
+r6082 | vlefevre | 2009-03-09 14:09:10 +0000 (Mon, 09 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: GMP with ABI=mode32 should be tested on 64-bit PowerPC.
+------------------------------------------------------------------------
+r6081 | thevenyp | 2009-03-06 18:07:12 +0000 (Fri, 06 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: now return -1 when the format string is invalid (undefined behavior in standard C99)
+tests/tprintf.c: Additional checks with invalid format strings.
+
+------------------------------------------------------------------------
+r6080 | thevenyp | 2009-03-06 18:01:24 +0000 (Fri, 06 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: Add missing conversion specifier accepted with mpfr_t variable.
+
+------------------------------------------------------------------------
+r6079 | vlefevre | 2009-03-06 13:03:44 +0000 (Fri, 06 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/add1.c
+
+add1.c: assertions on the argument values should use MPFR_ASSERTN.
+------------------------------------------------------------------------
+r6077 | zimmerma | 2009-03-06 11:50:19 +0000 (Fri, 06 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/cache.c
+
+[cache.c] improved comment for mpfr_init_cache
+
+------------------------------------------------------------------------
+r6076 | zimmerma | 2009-03-06 11:44:10 +0000 (Fri, 06 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+
+[add1.c] transformed switch() into if-then-else, to get 100% coverage
+
+------------------------------------------------------------------------
+r6074 | vlefevre | 2009-03-06 00:45:57 +0000 (Fri, 06 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/cache.c
+
+untabify
+------------------------------------------------------------------------
+r6073 | vlefevre | 2009-03-06 00:40:20 +0000 (Fri, 06 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/update-faq
+
+update-faq: change GMP_RND into MPFR_RND from the version on the web
+(since MPFR 3.0 hasn't been released yet, the FAQ still uses the 2.x
+API).
+------------------------------------------------------------------------
+r6071 | vlefevre | 2009-03-05 23:46:45 +0000 (Thu, 05 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tadd.c
+
+tests/tadd.c: completed the code coverage (case bk == 0 in add1.c).
+------------------------------------------------------------------------
+r6070 | zimmerma | 2009-03-05 19:44:05 +0000 (Thu, 05 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/cache.c
+ M /trunk/mpfr-impl.h
+
+[mpfr-impl.h,cache.c] commented out mpfr_init_cache
+
+------------------------------------------------------------------------
+r6069 | zimmerma | 2009-03-05 16:37:19 +0000 (Thu, 05 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/const_catalan.c
+
+[const_catalan.c] decreased initial Ziv precision to get 100% coverage
+
+------------------------------------------------------------------------
+r6068 | zimmerma | 2009-03-05 16:28:13 +0000 (Thu, 05 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/cmp2.c
+ M /trunk/tests/tcmp2.c
+
+[cmp2.c] added comments
+[tcmp2.c] added test to improve coverage to 100%
+
+------------------------------------------------------------------------
+r6067 | zimmerma | 2009-03-05 14:12:32 +0000 (Thu, 05 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/atan2.c
+ M /trunk/tests/tatan.c
+
+[atan2.c,tatan.c] reduced Ziv's initial precision and added test to have
+ 100% coverage of atan2.c
+
+------------------------------------------------------------------------
+r6066 | zimmerma | 2009-03-05 13:43:18 +0000 (Thu, 05 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+[atan.c] coverage should now be 100%
+
+------------------------------------------------------------------------
+r6065 | zimmerma | 2009-03-04 17:09:02 +0000 (Wed, 04 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+[algorithms.bib] added new reference
+[TODO] added pointers
+
+------------------------------------------------------------------------
+r6059 | vlefevre | 2009-03-04 12:59:50 +0000 (Wed, 04 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.c
+
+mpfr-gmp.c (mpfr_assert_fail): output "MPFR" too in assertion failure
+messages.
+------------------------------------------------------------------------
+r6057 | vlefevre | 2009-03-04 01:33:17 +0000 (Wed, 04 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/mpfrlint
+
+Updated mpfrlint script.
+------------------------------------------------------------------------
+r6056 | vlefevre | 2009-03-04 01:06:47 +0000 (Wed, 04 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated month.
+------------------------------------------------------------------------
+r6055 | vlefevre | 2009-03-04 01:02:26 +0000 (Wed, 04 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: say that the license has changed.
+------------------------------------------------------------------------
+r6054 | vlefevre | 2009-03-03 17:32:00 +0000 (Tue, 03 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+Updated NEWS (function mpfr_random has been removed).
+------------------------------------------------------------------------
+r6053 | zimmerma | 2009-03-03 16:51:07 +0000 (Tue, 03 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/TODO
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/div.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/eint.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/factorial.c
+ M /trunk/fits_intmax.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_ld.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/modf.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+ M /trunk/mul_2si.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/rec_sqrt.c
+ M /trunk/reldiff.c
+ M /trunk/rem1.c
+ M /trunk/replace_all
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sech.c
+ M /trunk/set_ld.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/speed.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/vasprintf.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+GMP_RNDX -> MPFR_RNDX
+
+------------------------------------------------------------------------
+r6051 | vlefevre | 2009-03-03 14:05:38 +0000 (Tue, 03 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/tests
+
+tests: added taway to svn:ignore property.
+------------------------------------------------------------------------
+r6050 | vlefevre | 2009-03-03 14:03:06 +0000 (Tue, 03 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/COPYING.LIB
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_d.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_d.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_patches.sh
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/mbench/Makefile
+ M /trunk/mbench/README
+ M /trunk/mbench/generate.c
+ M /trunk/mbench/mfv5-arprec.cc
+ M /trunk/mbench/mfv5-cln.cc
+ M /trunk/mbench/mfv5-crlibm.cc
+ M /trunk/mbench/mfv5-libc.cc
+ M /trunk/mbench/mfv5-lidia.cc
+ M /trunk/mbench/mfv5-mpf.cc
+ M /trunk/mbench/mfv5-mpfr.cc
+ M /trunk/mbench/mfv5-ntl.cc
+ M /trunk/mbench/mfv5-pari.cc
+ M /trunk/mbench/mfv5-void.cc
+ M /trunk/mbench/mfv5.cc
+ M /trunk/mbench/mfv5.h
+ M /trunk/mbench/mpfr-gfx.c
+ M /trunk/mbench/mpfr-v4.c
+ M /trunk/mbench/mpfr-v6.c
+ M /trunk/mbench/timp.h
+ M /trunk/minmax.c
+ M /trunk/modf.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mparam_h.in
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-longlong.h
+ M /trunk/mpfr-thread.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_d.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/printf.c
+ M /trunk/random2.c
+ M /trunk/rec_sqrt.c
+ M /trunk/reldiff.c
+ M /trunk/rem1.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/setsign.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/signbit.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/speed.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_d.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/data/li2
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tisqrt.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Update to LGPL v3+, as decided by the main MPFR developers.
+------------------------------------------------------------------------
+r6043 | vlefevre | 2009-02-27 15:46:06 +0000 (Fri, 27 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/add.c
+ M /trunk/div_ui.c
+ M /trunk/exp.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/rem1.c
+ M /trunk/round_near_x.c
+ M /trunk/set_z.c
+ M /trunk/tests/taway.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Untabified and deleted trailing spaces (for patches).
+------------------------------------------------------------------------
+r6041 | zimmerma | 2009-02-27 14:33:12 +0000 (Fri, 27 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/rint.c
+ M /trunk/tests/tget_sj.c
+
+[rint.c] fixed a bug incorporated with the round away mode
+[tget_sj.c] fixed the tests for round away
+
+------------------------------------------------------------------------
+r6040 | zimmerma | 2009-02-27 14:11:22 +0000 (Fri, 27 Feb 2009) | 5 lines
+Changed paths:
+ M /trunk/rint.c
+ M /trunk/set_z.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/taway.c
+
+[rint.c] fixed bug with round away
+[taway.c] new test file for round away (with random values)
+[tests/Makefile.am] added taway
+[set_z.c] GNU style
+
+------------------------------------------------------------------------
+r6037 | thevenyp | 2009-02-27 13:38:30 +0000 (Fri, 27 Feb 2009) | 5 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: Change test5rm (formerly test4rm) so that it checks the new
+GMP_RNDA rounding mode, and that the corresponding rounding towards infinity
+is checked with GMP_RNDZ or with GMP_RNDA in one-pass mode (now, two-pass
+mode). Remove a comment about a warning from gcc solved with r5057.
+
+------------------------------------------------------------------------
+r6036 | zimmerma | 2009-02-27 13:27:41 +0000 (Fri, 27 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/rem1.c
+ M /trunk/tests/tremquo.c
+
+[rem1.c] fixed bug found in adding tests for round away
+
+------------------------------------------------------------------------
+r6035 | zimmerma | 2009-02-27 06:36:54 +0000 (Fri, 27 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+[add.c] added comment for 0 + 0 with round away
+
+------------------------------------------------------------------------
+r6034 | vlefevre | 2009-02-26 23:02:57 +0000 (Thu, 26 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/tests/texceptions.c
+
+tests/texceptions.c: removed obsolete comments from r2427.
+------------------------------------------------------------------------
+r6033 | zimmerma | 2009-02-26 21:28:42 +0000 (Thu, 26 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/tsub.c
+
+[mpfr.h] added comment about order of rounding modes
+[texceptions.c] added comments, fixed typo
+[tsub.c] added test, fixed typo
+
+------------------------------------------------------------------------
+r6032 | thevenyp | 2009-02-26 18:21:14 +0000 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+
+Add tests with round away mode.
+
+------------------------------------------------------------------------
+r6031 | vlefevre | 2009-02-26 17:25:26 +0000 (Thu, 26 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/VERSION
+ M /trunk/configure.in
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/version.c
+
+Updated version to 3.0.0-dev.
+------------------------------------------------------------------------
+r6030 | zimmerma | 2009-02-26 15:47:06 +0000 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/TODO
+ M /trunk/add1.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/div_ui.c
+ M /trunk/erf.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/hypot.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/print_rnd_mode.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/set_rnd.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+added round to away (still experimental)
+
+------------------------------------------------------------------------
+r6026 | zimmerma | 2009-02-26 10:31:39 +0000 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+[mpfr.h] added comments for rounding modes
+
+------------------------------------------------------------------------
+r6022 | vlefevre | 2009-02-26 01:41:26 +0000 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/m4
+
+Added svn:ignore property on the m4 directory (these .m4 files are
+generated automatically).
+------------------------------------------------------------------------
+r6021 | vlefevre | 2009-02-26 01:36:06 +0000 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Makefile.am: updated -version-info (since mpfr_random has been removed,
+we already know its value).
+------------------------------------------------------------------------
+r6019 | vlefevre | 2009-02-26 01:26:45 +0000 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Makefile.am: do not check libtool -version-info value if the VERSION
+file contains "-dev".
+------------------------------------------------------------------------
+r6018 | vlefevre | 2009-02-26 01:16:02 +0000 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Makefile.am: In a "make dist", check that libtool -version-info value
+is up-to-date (this is a heuristic only).
+------------------------------------------------------------------------
+r6016 | vlefevre | 2009-02-26 00:36:25 +0000 (Thu, 26 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated "To make a release" -- it is important to read
+this section entirely before making any release (even if some steps
+may be skipped for some particular releases).
+------------------------------------------------------------------------
+r6010 | vlefevre | 2009-02-25 22:06:27 +0000 (Wed, 25 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: do not use VLA's (C99 only).
+------------------------------------------------------------------------
+r6003 | vlefevre | 2009-02-25 14:24:06 +0000 (Wed, 25 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: update about patches.
+------------------------------------------------------------------------
+r5999 | vlefevre | 2009-02-25 12:44:51 +0000 (Wed, 25 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: coding style: removed spurious spaces.
+------------------------------------------------------------------------
+r5997 | vlefevre | 2009-02-25 12:16:17 +0000 (Wed, 25 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated month.
+------------------------------------------------------------------------
+r5996 | vlefevre | 2009-02-25 12:14:38 +0000 (Wed, 25 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/printf.c
+
+printf.c: fixed assertion failures in the case buffer == NULL and
+size == 0 (see r5995). Also replaced MPFR_ASSERTD(buf != NULL) by
+MPFR_ASSERTN(buf != NULL) since buf is provided as an argument.
+------------------------------------------------------------------------
+r5995 | vlefevre | 2009-02-25 12:12:52 +0000 (Wed, 25 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: added mpfr_snprintf/mpfr_vsnprintf tests with
+buffer == NULL and size == 0 (as allowed in C99 snprintf/vsnprintf
+and by the MPFR documentation).
+------------------------------------------------------------------------
+r5994 | thevenyp | 2009-02-25 09:58:15 +0000 (Wed, 25 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: Fix typos.
+
+------------------------------------------------------------------------
+r5993 | vlefevre | 2009-02-24 19:40:06 +0000 (Tue, 24 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/tuneup.c
+
+tuneup.c: untabified.
+------------------------------------------------------------------------
+r5992 | thevenyp | 2009-02-24 18:04:04 +0000 (Tue, 24 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/printf.c
+ M /trunk/tests/tsprintf.c
+
+printf.c: Fix wrong return value, mpfr_snprintf and mpfr_vsnprintf functions must always return the number of character that would be written if the parameter n had been sufficiently large (it previously returned zero when n == 0).
+tests/tsprintf.c: Fix test of mpfr_snprintf and mpfr_vsnprintf (the wrong return value was checked).
+
+------------------------------------------------------------------------
+r5991 | vlefevre | 2009-02-24 15:38:37 +0000 (Tue, 24 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/printf.c
+
+printf.c: fix buffer overflow in mpfr_snprintf and mpfr_vsnprintf.
+------------------------------------------------------------------------
+r5990 | vlefevre | 2009-02-24 15:37:33 +0000 (Tue, 24 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: added a test showing a buffer overflow in mpfr_vsnprintf.
+------------------------------------------------------------------------
+r5989 | vlefevre | 2009-02-24 15:30:06 +0000 (Tue, 24 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: added a test showing a buffer overflow in mpfr_snprintf.
+------------------------------------------------------------------------
+r5985 | vlefevre | 2009-02-23 12:21:47 +0000 (Mon, 23 Feb 2009) | 12 lines
+Changed paths:
+ M /trunk/tests/tests.c
+ M /trunk/tests/tversion.c
+ M /trunk/update-version
+
+Changed how the test of MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR and
+MPFR_VERSION_PATCHLEVEL vs MPFR_VERSION_STRING is performed.
+Detailed explanations:
+ The test was enabled only in release tarballs (suffix not present),
+ where tests/tversion.c normally contained a "#if 1" (though this
+ is not the case in the MPFR 2.4.0 tarball). In patches, this test
+ should be disabled by changing the "#if 1" into "#if 0", due to
+ the suffix. But as one should be able to apply any patches (in any
+ order), this method was not satisfactory. The test has been moved
+ from tests/tversion.c to tests/tests.c (in function test_version),
+ and the suffix is now ignored in this test; the change of #if has
+ been removed from the update-version script.
+------------------------------------------------------------------------
+r5981 | vlefevre | 2009-02-20 21:51:01 +0000 (Fri, 20 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: corrected update-version usage for patches.
+------------------------------------------------------------------------
+r5978 | vlefevre | 2009-02-20 16:04:19 +0000 (Fri, 20 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update.
+------------------------------------------------------------------------
+r5975 | zimmerma | 2009-02-20 15:11:17 +0000 (Fri, 20 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/mparam_h.in
+ M /trunk/tuneup.c
+
+[mparam_h.in] added default thresholds for sparc64
+[tuneup.c] print gcc patchlevel
+
+------------------------------------------------------------------------
+r5970 | vlefevre | 2009-02-19 01:10:31 +0000 (Thu, 19 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/speed.c
+ M /trunk/tests/texp.c
+
+speed.c, tests/texp.c: untabified.
+------------------------------------------------------------------------
+r5969 | vlefevre | 2009-02-19 01:08:00 +0000 (Thu, 19 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: improved mpfr_strtofr documentation (completing r5965).
+------------------------------------------------------------------------
+r5967 | zimmerma | 2009-02-18 21:31:24 +0000 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] added tuning for powerpc64
+
+------------------------------------------------------------------------
+r5966 | thevenyp | 2009-02-18 17:06:02 +0000 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+strtofr.c: fix typo.
+
+------------------------------------------------------------------------
+r5965 | thevenyp | 2009-02-18 16:55:21 +0000 (Wed, 18 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/strtofr.c
+ M /trunk/tests/tstrtofr.c
+
+strtofr.c: accept bases up to 62.
+mpfr.texi: modify mpfr_strtofr documentation accordingly.
+tests/tstrtofr.c: add tests for bases 62, 60, and 61.
+
+------------------------------------------------------------------------
+r5964 | thevenyp | 2009-02-17 16:52:33 +0000 (Tue, 17 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+mparam_h.in: Change core2/64bit parameters.
+
+------------------------------------------------------------------------
+r5963 | vlefevre | 2009-02-17 16:46:56 +0000 (Tue, 17 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+Checks whether C99 length modifiers 'hh' and 'll' are supported by the
+system ('hh' is absent on alpha-OSF1-V5, bug reported by Kate Minola).
+[Merged changeset 5956 from the 2.4 branch.]
+------------------------------------------------------------------------
+r5962 | zimmerma | 2009-02-17 16:31:46 +0000 (Tue, 17 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+[texp.c] yet another better fix
+
+------------------------------------------------------------------------
+r5961 | zimmerma | 2009-02-17 16:23:41 +0000 (Tue, 17 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+[texp.c] fixed previous patch and added comment
+
+------------------------------------------------------------------------
+r5960 | zimmerma | 2009-02-17 16:19:25 +0000 (Tue, 17 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+[texp.c] fixed corner case test
+
+------------------------------------------------------------------------
+r5958 | vlefevre | 2009-02-16 14:27:52 +0000 (Mon, 16 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: improved latest change.
+------------------------------------------------------------------------
+r5957 | vlefevre | 2009-02-16 14:25:10 +0000 (Mon, 16 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: mentioned update-version for patches.
+------------------------------------------------------------------------
+r5955 | zimmerma | 2009-02-11 10:09:36 +0000 (Wed, 11 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mbench/mpfr-gfx.c
+
+[mpfr-gfx.c] added -p option to produce a Postscript file
+
+------------------------------------------------------------------------
+r5954 | zimmerma | 2009-02-10 21:02:22 +0000 (Tue, 10 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] added thresholds for ARM
+
+------------------------------------------------------------------------
+r5953 | zimmerma | 2009-02-10 17:39:27 +0000 (Tue, 10 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] added description of how to tune MPFR
+
+------------------------------------------------------------------------
+r5952 | zimmerma | 2009-02-10 15:52:48 +0000 (Tue, 10 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] added another example of using mpfr-gfx
+
+------------------------------------------------------------------------
+r5951 | zimmerma | 2009-02-10 15:50:40 +0000 (Tue, 10 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/mbench/Makefile
+
+[Makefile] modified Makefile to compile statically, and to allow also
+ build directories of GMP/MPFR
+
+------------------------------------------------------------------------
+r5950 | thevenyp | 2009-02-10 14:21:45 +0000 (Tue, 10 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mbench/mpfr-gfx.c
+
+mbench/mpfr-gfx.c: add option -rPREC_RATIO for geometric progression.
+
+------------------------------------------------------------------------
+r5949 | zimmerma | 2009-02-10 12:10:46 +0000 (Tue, 10 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] updated Itanium parameters (now for Itanium2)
+
+------------------------------------------------------------------------
+r5948 | zimmerma | 2009-02-10 11:26:25 +0000 (Tue, 10 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] added symbol __itanium__ for Itanium[12]
+
+------------------------------------------------------------------------
+r5947 | zimmerma | 2009-02-09 21:50:22 +0000 (Mon, 09 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/mbench/mpfr-gfx.c
+
+[README.dev] fixed typo
+[mpfr-gfx.c] added comments in the code (might be useful)
+
+------------------------------------------------------------------------
+r5946 | zimmerma | 2009-02-09 20:25:42 +0000 (Mon, 09 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] added pointer to mbench to check the thresholds
+
+------------------------------------------------------------------------
+r5945 | zimmerma | 2009-02-09 20:17:46 +0000 (Mon, 09 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mbench/mpfr-gfx.c
+
+[mpfr-gfx.c] now also produces a plot.gnuplot file together with plot.data
+
+------------------------------------------------------------------------
+r5944 | zimmerma | 2009-02-09 16:18:50 +0000 (Mon, 09 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] updated default thresholds with gmp-4.2.4
+
+------------------------------------------------------------------------
+r5943 | zimmerma | 2009-02-09 16:16:33 +0000 (Mon, 09 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/tuneup.c
+
+[tuneup.c] fixed typo
+
+------------------------------------------------------------------------
+r5942 | zimmerma | 2009-02-09 14:34:34 +0000 (Mon, 09 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+[Makefile.am] added stuff to compile speed program
+
+------------------------------------------------------------------------
+r5941 | zimmerma | 2009-02-09 14:22:20 +0000 (Mon, 09 Feb 2009) | 5 lines
+Changed paths:
+ A /trunk/speed.c
+
+[speed.c] preliminary program to check the tuning of mpfr (based on tuneup.c)
+ So far it only measures mpfr_mul up to 1000 bits, with increment
+ ratio of 1.1. Requires --with-gmp-build like tuneup.
+ Feel free to improve!
+
+------------------------------------------------------------------------
+r5940 | zimmerma | 2009-02-09 13:26:07 +0000 (Mon, 09 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] allow __tune_ia64__ in addition to __ia64
+
+------------------------------------------------------------------------
+r5937 | zimmerma | 2009-02-09 08:16:08 +0000 (Mon, 09 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+[mparam_h.in] replaced __pentium4 by __tune_pentium4__, ...
+
+------------------------------------------------------------------------
+r5936 | zimmerma | 2009-02-08 21:58:11 +0000 (Sun, 08 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mparam_h.in
+
+[acinclude.m4] removed detection of HAVE_HOST_CORE2
+[mparam_h.in] replaced HAVE_HOST_CORE2 by __tune_core2__
+
+------------------------------------------------------------------------
+r5930 | thevenyp | 2009-02-06 14:06:54 +0000 (Fri, 06 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/mpf_compat.h
+
+tests/mpf_compat.h: complete r5922 adding missing mpz_init/mpz_clear.
+
+------------------------------------------------------------------------
+r5927 | vlefevre | 2009-02-06 11:57:57 +0000 (Fri, 06 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/TODO
+
+TODO: updated efficiency items.
+------------------------------------------------------------------------
+r5926 | zimmerma | 2009-02-06 11:18:48 +0000 (Fri, 06 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added 2 efficiency items
+
+------------------------------------------------------------------------
+r5925 | vlefevre | 2009-02-06 00:02:35 +0000 (Fri, 06 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: moved MPFR_DECL_INIT specification into Section
+"Initialization Functions" (now in the standard MPFR API),
+and removed now empty Section "Advanced Functions".
+------------------------------------------------------------------------
+r5924 | vlefevre | 2009-02-05 14:40:38 +0000 (Thu, 05 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/mparam_h.in
+
+mparam_h.in: updated comment to mention -march=native and -mtune=native.
+------------------------------------------------------------------------
+r5923 | vlefevre | 2009-02-05 11:42:26 +0000 (Thu, 05 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: updated a comment concerning MPFR_DECL_INIT.
+------------------------------------------------------------------------
+r5922 | zimmerma | 2009-02-05 08:01:46 +0000 (Thu, 05 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+ M /trunk/tests/mpf_compat.h
+
+[mpf2mpfr.h] added mpz_set_f (reported by Francois Morain)
+
+------------------------------------------------------------------------
+r5921 | zimmerma | 2009-02-05 07:26:51 +0000 (Thu, 05 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/mpfr.texi
+
+[mpfr.texi] moved mpfr_inits, mpfr_inits2, mpfr_clears to supported functions
+[TODO] added new info about MPIR
+
+------------------------------------------------------------------------
+r5920 | zimmerma | 2009-02-04 19:46:50 +0000 (Wed, 04 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+[TODO] added info to distinguish GMP and MPIR
+
+------------------------------------------------------------------------
+r5893 | vlefevre | 2009-01-26 17:04:26 +0000 (Mon, 26 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/VERSION
+ M /trunk/configure.in
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/version.c
+
+Updated the version on the trunk.
+------------------------------------------------------------------------
+r5888 | zimmerma | 2009-01-25 12:50:42 +0000 (Sun, 25 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+[nightly-test] removed --disable-alloca (GMP option)
+
+------------------------------------------------------------------------
+r5887 | vlefevre | 2009-01-25 00:19:30 +0000 (Sun, 25 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: --disable-alloca is a GMP configure option.
+------------------------------------------------------------------------
+r5886 | thevenyp | 2009-01-21 15:01:25 +0000 (Wed, 21 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: remove tests against libc's printf with "%a" (not in ISO C90), and with "%p" (implementation defined).
+[merge -c 5885 from branches/2.4]
+
+------------------------------------------------------------------------
+r5883 | vlefevre | 2009-01-21 12:43:57 +0000 (Wed, 21 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: avoid a compiler bug under Mac OS X Tiger + Xcode (&x == &x
+is false) that makes tset_d fail; this problem was introduced in r5880.
+------------------------------------------------------------------------
+r5880 | vlefevre | 2009-01-20 22:12:11 +0000 (Tue, 20 Jan 2009) | 6 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/tset_ld.c
+
+Fixed bug reported by Chris Saunders: if _GMP_IEEE_FLOATS is defined,
+the build of tset_ld.c fails because DOUBLE_ISNAN expects a lvalue.
+* mpfr-impl.h: documented that for such macros, the argument must
+ be a lvalue, and always make sure that it is a lvalue (so that
+ a failure doesn't depend on the environment).
+* tests/tset_ld.c: fixed the bug.
+------------------------------------------------------------------------
+r5879 | vlefevre | 2009-01-20 15:08:45 +0000 (Tue, 20 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tversion.c
+
+tests/tversion.c: be more tolerant when checking whether gmp.h version
+and libgmp version are the same (in case patch level is 0).
+------------------------------------------------------------------------
+r5878 | vlefevre | 2009-01-20 12:47:05 +0000 (Tue, 20 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+tests/tset_ld.c: added explanation of NaN-related failures in case
+MPFR_NANISNAN is defined.
+------------------------------------------------------------------------
+r5875 | vlefevre | 2009-01-20 00:43:20 +0000 (Tue, 20 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tstrtofr.c
+
+Added missing void's.
+------------------------------------------------------------------------
+r5874 | vlefevre | 2009-01-20 00:35:41 +0000 (Tue, 20 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: removed a blank line (for consistency with the
+2.4 branch).
+------------------------------------------------------------------------
+r5873 | vlefevre | 2009-01-20 00:33:09 +0000 (Tue, 20 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: deleted trailing spaces.
+------------------------------------------------------------------------
+r5869 | vlefevre | 2009-01-19 23:57:53 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: comment for DOUBLE_ISNAN with MPFR_NANISNAN defined.
+------------------------------------------------------------------------
+r5868 | vlefevre | 2009-01-19 23:42:33 +0000 (Mon, 19 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_d.c
+
+tests/tset_d.c: fixed test of mpfr_set_d on -0 with gcc -ffast-math
+(the -d for d = 0.0 was giving 0.0, hence a spurious failure).
+------------------------------------------------------------------------
+r5867 | vlefevre | 2009-01-19 23:34:54 +0000 (Mon, 19 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/tset_ld.c
+
+mpfr-impl.h: the DOUBLE_ISNAN macro wasn't working with gcc -ffast-math
+(at least on x86_64); fixed that by adding another test.
+tests/tset_ld.c: Isnan_ld wasn't working either; also the NaN test was
+incorrect. Now, the failure on NaN is correctly reported.
+------------------------------------------------------------------------
+r5866 | vlefevre | 2009-01-19 22:44:45 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tset_d.c
+
+tests/tcmp_d.c, tests/tcmp_ld.c, tests/tset_d.c: corrected message.
+------------------------------------------------------------------------
+r5865 | vlefevre | 2009-01-19 22:37:27 +0000 (Mon, 19 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tset_d.c
+
+tests/tcmp_d.c, tests/tcmp_ld.c, tests/tset_d.c: added explanations
+of NaN-related failures in case MPFR_NANISNAN is defined.
+Note: in tset_d.c, moved the NaN test before the signed-zero test
+to catch the failure on the NaN first.
+------------------------------------------------------------------------
+r5864 | vlefevre | 2009-01-19 22:23:26 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: improved warning message.
+------------------------------------------------------------------------
+r5863 | vlefevre | 2009-01-19 22:16:15 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: updated "In case of problem".
+------------------------------------------------------------------------
+r5862 | vlefevre | 2009-01-19 22:12:09 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: added a warning message for the NAN != NAN test.
+------------------------------------------------------------------------
+r5860 | thevenyp | 2009-01-19 19:59:12 +0000 (Mon, 19 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tset_d.c
+
+tcmp_d.c tset_d.c tcmp_ld.c: Remove tests with NaN when MPFR_NANISNAN is defined.
+tests.c: Add a warning in a comment that Isnan always returns 0 on systems where MPFR_NANISNAN is defined.
+
+------------------------------------------------------------------------
+r5855 | thevenyp | 2009-01-19 18:14:55 +0000 (Mon, 19 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: do not support 't' when NPRINTF_T is defined, HAVE_STDINT_H -> _MPFR_H_HAVE_INTMAX_T.
+
+------------------------------------------------------------------------
+r5853 | thevenyp | 2009-01-19 17:05:13 +0000 (Mon, 19 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+
+tests/tfprintf.c: renumber tests (there was two tests #9).
+
+------------------------------------------------------------------------
+r5852 | vlefevre | 2009-01-19 16:56:17 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tfprintf.c
+
+tests/tfprintf.c: %c takes an int argument, not a char (see C standard).
+------------------------------------------------------------------------
+r5851 | vlefevre | 2009-01-19 16:53:56 +0000 (Mon, 19 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsprintf.c
+
+tests/tprintf.c, tests/tsprintf.c:
+ * %c takes an int argument, not a char (see C standard), even though
+ this may be equivalent due to integer promotion.
+ * Add void in prototypes of functions taking no arguments.
+------------------------------------------------------------------------
+r5844 | vlefevre | 2009-01-19 15:46:41 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated references to the GMP manual.
+------------------------------------------------------------------------
+r5843 | vlefevre | 2009-01-19 15:31:54 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: typo in comment.
+------------------------------------------------------------------------
+r5842 | vlefevre | 2009-01-19 15:30:52 +0000 (Mon, 19 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added .info extension in cross-references, to avoid the bug
+reported here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=484740
+------------------------------------------------------------------------
+r5841 | vlefevre | 2009-01-19 14:34:22 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added a reference to a texinfo bug in a comment.
+------------------------------------------------------------------------
+r5840 | vlefevre | 2009-01-19 14:02:49 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added missing @code{}.
+------------------------------------------------------------------------
+r5839 | vlefevre | 2009-01-19 14:01:13 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: don't -> do not, doesn't -> does not, won't -> will not.
+------------------------------------------------------------------------
+r5838 | vlefevre | 2009-01-19 13:58:50 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: improved Section "Format String".
+------------------------------------------------------------------------
+r5837 | thevenyp | 2009-01-19 13:51:45 +0000 (Mon, 19 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: check if native types are really processed by libc printf.
+
+------------------------------------------------------------------------
+r5836 | vlefevre | 2009-01-19 13:31:27 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: no longer mentions HAVE_QUAD_T since it is no longer used.
+------------------------------------------------------------------------
+r5835 | thevenyp | 2009-01-19 12:50:08 +0000 (Mon, 19 Jan 2009) | 5 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr.texi
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+mpfr.texi: Explicit list of type supported by mpfr_printf functions.
+acinclude.m4: Remove detection of type modifier 'q'.
+vasprintf.c: Remove support of type modifier 'q'.
+tests/tfprintf.c tests/tprintf.c: Remove tests with type modifier 'q'.
+
+------------------------------------------------------------------------
+r5834 | thevenyp | 2009-01-19 11:05:10 +0000 (Mon, 19 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/configure.in
+
+INSTALL: Warn that --with-gmp, --with-gmp-include/--with-gmp-lib, and --with-gmp-build options are mutually exclusive.
+configure.in: Check and fail if --with-gmp, --with-gmp-include/--with-gmp-lib, or --with-gmp-build are use simultaneously.
+
+------------------------------------------------------------------------
+r5833 | vlefevre | 2009-01-19 10:08:58 +0000 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: include <sys/fpu.h> only if need be.
+------------------------------------------------------------------------
+r5831 | zimmerma | 2009-01-16 15:32:11 +0000 (Fri, 16 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] made difference between mpfr_set_str and mpfr_strtofr clearer
+ (after remark from Luis Rivera)
+
+------------------------------------------------------------------------
+r5830 | zimmerma | 2009-01-16 15:24:45 +0000 (Fri, 16 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] fixed order -> kind (typo found by Luis Rivera, thanks)
+
+------------------------------------------------------------------------
+r5828 | thevenyp | 2009-01-16 13:35:04 +0000 (Fri, 16 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+tfprintf.c tprintf.c: Test double with "%f" instead of "%e" so as to avoid failure due to exponent "e+000" on MS Windows.
+
+------------------------------------------------------------------------
+r5827 | thevenyp | 2009-01-16 13:06:27 +0000 (Fri, 16 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+tests/tfprintf.c tests/tsprintf.c tests/tprintf.c acinclude.m4 vasprintf.c: No longer check libc's printf.
+
+------------------------------------------------------------------------
+r5826 | thevenyp | 2009-01-16 09:53:15 +0000 (Fri, 16 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsprintf.c
+
+acinclude.m4: Check if %Ld specification is supported (not always the case with MS Windows)
+tests/tfprintf.c tests/tprintf.c tests/tsprintf.c: do not check %Ld specification when not available.
+
+------------------------------------------------------------------------
+r5825 | thevenyp | 2009-01-16 09:26:18 +0000 (Fri, 16 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/fits_intmax.c
+ M /trunk/fits_uintmax.c
+ M /trunk/get_sj.c
+ M /trunk/get_uj.c
+ M /trunk/set_sj.c
+ M /trunk/set_uj.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/vasprintf.c
+
+get_uj.c get_sj.c tests/tset_sj.c tests/tfits.c fits_intmax.c fits_uintmax.c set_uj.c set_sj.c: make #include-s for intmax_t uniform.
+vasprintf.c: make #include-s for intmax_t uniform and use _MPFR_H_HAVE_INTMAX_T instead of HAVE_INTMAX_T.
+
+------------------------------------------------------------------------
+r5823 | thevenyp | 2009-01-15 13:24:35 +0000 (Thu, 15 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+tfprintf.c tprintf.c: Remove tests with u_quad_t (on Solaris 10, quad_t exists but u_quad_t doesn't, bug reported by Michael Abshoff).
+
+------------------------------------------------------------------------
+r5822 | thevenyp | 2009-01-15 13:17:14 +0000 (Thu, 15 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+tfprintf.c tprintf.c: Fix included headers, type intmax_t may be defined in inttypes.h or in stdint.h (see autoconf manual 5.6.1 Portability of Headers).
+
+------------------------------------------------------------------------
+r5821 | vlefevre | 2009-01-15 10:13:44 +0000 (Thu, 15 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/ChangeLog
+
+ChangeLog update with "LC_ALL=en_US.UTF8 TZ=UTC svn log -rHEAD:0 -v".
+------------------------------------------------------------------------
+r5817 | vlefevre | 2009-01-15 02:22:45 +0000 (Thu, 15 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: deleted trailing spaces.
+------------------------------------------------------------------------
+r5816 | vlefevre | 2009-01-15 02:21:57 +0000 (Thu, 15 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: be more tolerant when checking whether gmp.h version
+and libgmp version are the same (in case patch level is 0).
+------------------------------------------------------------------------
+r5814 | vlefevre | 2009-01-15 01:56:55 +0000 (Thu, 15 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/ChangeLog
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_d.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_d.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_patches.sh
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/mbench/Makefile
+ M /trunk/mbench/generate.c
+ M /trunk/mbench/mfv5-arprec.cc
+ M /trunk/mbench/mfv5-cln.cc
+ M /trunk/mbench/mfv5-crlibm.cc
+ M /trunk/mbench/mfv5-libc.cc
+ M /trunk/mbench/mfv5-lidia.cc
+ M /trunk/mbench/mfv5-mpf.cc
+ M /trunk/mbench/mfv5-mpfr.cc
+ M /trunk/mbench/mfv5-ntl.cc
+ M /trunk/mbench/mfv5-pari.cc
+ M /trunk/mbench/mfv5-void.cc
+ M /trunk/mbench/mfv5.cc
+ M /trunk/mbench/mfv5.h
+ M /trunk/mbench/mpfr-gfx.c
+ M /trunk/mbench/mpfr-v4.c
+ M /trunk/mbench/mpfr-v6.c
+ M /trunk/mbench/timp.h
+ M /trunk/minmax.c
+ M /trunk/modf.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mparam_h.in
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-thread.h
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_d.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/printf.c
+ M /trunk/random2.c
+ M /trunk/rec_sqrt.c
+ M /trunk/reldiff.c
+ M /trunk/rem1.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/setsign.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/signbit.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_d.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/data/li2
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tisqrt.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Copyright notice update: added 2009 with
+ perl -pi -e 's/2008 Free Software/2008, 2009 Free Software/' **/*(^/)
+under zsh.
+------------------------------------------------------------------------
+r5813 | vlefevre | 2009-01-14 00:46:45 +0000 (Wed, 14 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tsqrt.c
+
+Fixed remaining printf format strings.
+------------------------------------------------------------------------
+r5812 | vlefevre | 2009-01-14 00:27:06 +0000 (Wed, 14 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tsub1sp.c
+
+tests/tadd1sp.c, tests/tsub1sp.c: fixed function prototypes.
+------------------------------------------------------------------------
+r5811 | vlefevre | 2009-01-14 00:23:44 +0000 (Wed, 14 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/tests/teq.c
+ M /trunk/tests/tests.c
+
+tests/teq.c, tests/tests.c: fixed printf format strings.
+------------------------------------------------------------------------
+r5810 | vlefevre | 2009-01-14 00:06:00 +0000 (Wed, 14 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+tests/tcmp2.c: fixed printf format strings.
+------------------------------------------------------------------------
+r5809 | vlefevre | 2009-01-13 23:59:17 +0000 (Tue, 13 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+tests/tset_str.c: fixed printf format string.
+------------------------------------------------------------------------
+r5804 | vlefevre | 2009-01-12 17:30:00 +0000 (Mon, 12 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: consistency changes and corrections concerning the "erange"
+flag (do not use @code{} as this is not an identifier, @emph{} is used
+as this is not an English word -- but @emph{} should probably be used
+too for the other flag names).
+------------------------------------------------------------------------
+r5803 | vlefevre | 2009-01-12 17:18:45 +0000 (Mon, 12 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: typo.
+------------------------------------------------------------------------
+r5801 | thevenyp | 2009-01-12 16:01:14 +0000 (Mon, 12 Jan 2009) | 5 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+acinclude.m4: New macro MPFR_CHECK_PRINTF_SPEC looking for support of the "%jd", "%qd", and "%td" conversion specifications in printf and gmp_printf.
+configure.in: Call MPFR_CHECK_PRINTF_SPEC when we can link against a suitable gmp library and run test programs at compile time, otherwise (for instance, when cross compiling), everything is enable by default.
+vasprintf.c: Disable support for length modifiers not supported by libc's printf ('j' and 'q' for this time).
+tests/tprintf.c, tests/tfprintf.c: Disable tests for length modifiers not supported by gmp_printf ('j', 'q', and 't' for this time).
+
+------------------------------------------------------------------------
+r5800 | thevenyp | 2009-01-12 14:16:22 +0000 (Mon, 12 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: Fix typo.
+
+------------------------------------------------------------------------
+r5795 | vlefevre | 2009-01-08 15:36:55 +0000 (Thu, 08 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: update to January 2009.
+------------------------------------------------------------------------
+r5794 | vlefevre | 2009-01-08 15:34:27 +0000 (Thu, 08 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tsprintf.c
+
+Removed useless #include of gmp.h from tests/tfprintf.c and
+tests/tsprintf.c for consistency.
+------------------------------------------------------------------------
+r5788 | thevenyp | 2009-01-08 11:56:10 +0000 (Thu, 08 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/tests/tfprintf.c
+ M /trunk/vasprintf.c
+
+tests/tfprintf.c: Make tests with 'M' specifier optional.
+mpfr.texi: Add a warning that gmp may not support 'M' specifier.
+vasprintf.c: Add warning comment about 'M' specifier.
+
+------------------------------------------------------------------------
+r5787 | thevenyp | 2009-01-08 11:52:52 +0000 (Thu, 08 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: Fix wrong definition of rounding specifiers.
+
+------------------------------------------------------------------------
+r5786 | vlefevre | 2008-12-30 13:57:11 +0000 (Tue, 30 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/out_str.c
+
+out_str.c: added assert (check that base is in the required range).
+------------------------------------------------------------------------
+r5785 | vlefevre | 2008-12-26 14:10:24 +0000 (Fri, 26 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: suggest "-Wformat=2".
+------------------------------------------------------------------------
+r5784 | vlefevre | 2008-12-26 14:02:55 +0000 (Fri, 26 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/zeta.c
+
+zeta.c: fixed types for printf when DEBUG is defined.
+------------------------------------------------------------------------
+r5783 | vlefevre | 2008-12-26 13:57:32 +0000 (Fri, 26 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+sub1sp.c: fixed types for printf when WANT_ASSERT >= 2 and
+when DEBUG is defined.
+------------------------------------------------------------------------
+r5782 | vlefevre | 2008-12-26 13:50:14 +0000 (Fri, 26 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/sub1.c
+
+sub1.c: fixed types for printf when DEBUG is defined.
+------------------------------------------------------------------------
+r5781 | vlefevre | 2008-12-26 13:44:28 +0000 (Fri, 26 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/set_d64.c
+
+set_d64.c: set T[] to unsigned int (instead of int) since its values
+are printed with %u.
+------------------------------------------------------------------------
+r5780 | vlefevre | 2008-12-26 13:36:13 +0000 (Fri, 26 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/add1sp.c
+
+add1sp.c: fixed types for printf when DEBUG is defined.
+------------------------------------------------------------------------
+r5779 | vlefevre | 2008-12-26 13:33:05 +0000 (Fri, 26 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: fixed MPFR_UNSIGNED_MINUS_MODULO logic and added missing
+parentheses.
+------------------------------------------------------------------------
+r5778 | vlefevre | 2008-12-26 13:06:14 +0000 (Fri, 26 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/div.c
+
+div.c: fixed types for fprintf when DEBUG and/or DEBUG2 is defined.
+------------------------------------------------------------------------
+r5777 | vlefevre | 2008-12-26 12:56:09 +0000 (Fri, 26 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/div.c
+
+div.c: fixed #ifdef.
+------------------------------------------------------------------------
+r5775 | vlefevre | 2008-12-26 12:39:03 +0000 (Fri, 26 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/round_p.c
+
+round_p.c: fixed types for fprintf when WANT_ASSERT >= 2 (since
+mp_prec_t is unsigned, it's better to use unsigned long).
+------------------------------------------------------------------------
+r5774 | vlefevre | 2008-12-26 12:02:07 +0000 (Fri, 26 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/round_p.c
+
+round_p.c: fixed types for fprintf when WANT_ASSERT >= 2.
+------------------------------------------------------------------------
+r5772 | zimmerma | 2008-12-22 10:40:24 +0000 (Mon, 22 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.tex] improve documentation of %P
+
+------------------------------------------------------------------------
+r5768 | vlefevre | 2008-12-18 15:59:55 +0000 (Thu, 18 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+Deleted trailing spaces.
+------------------------------------------------------------------------
+r5762 | thevenyp | 2008-12-17 16:07:32 +0000 (Wed, 17 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: clean-up code, improve comment, and put optional tests in tail so that they fail last.
+
+------------------------------------------------------------------------
+r5761 | thevenyp | 2008-12-17 15:55:20 +0000 (Wed, 17 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: Add two regression tests.
+
+------------------------------------------------------------------------
+r5760 | thevenyp | 2008-12-16 15:56:42 +0000 (Tue, 16 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr.texi
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+acinclude.m4, vasprintf.c, tests/tfprintf.c, tests/tprintf.c, mpfr.texi: quad_t support
+
+------------------------------------------------------------------------
+r5759 | thevenyp | 2008-12-16 15:51:59 +0000 (Tue, 16 Dec 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+tests/tfprintf.c: code clean-up and output improvement.
+tests/tprintf.c: code clean-up.
+Note that unsigned long long variable is not set to 1 instead of -1 which was architecture dependant.
+
+------------------------------------------------------------------------
+r5758 | vlefevre | 2008-12-16 13:56:28 +0000 (Tue, 16 Dec 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c:
+ * stdout_redirect is a boolean (i.e., 0 or 1).
+ * output freopen(..., stdout) error message to stderr.
+------------------------------------------------------------------------
+r5757 | thevenyp | 2008-12-16 13:10:05 +0000 (Tue, 16 Dec 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+tfprintf.c: more user-friendly messages.
+tprintf.c: more user-friendly messages. Warning: because stdout might be redirected, error messages are printed to stderr.
+
+------------------------------------------------------------------------
+r5756 | vlefevre | 2008-12-15 23:38:21 +0000 (Mon, 15 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: more explanations on the precision field for mpfr_printf.
+------------------------------------------------------------------------
+r5755 | vlefevre | 2008-12-15 17:37:05 +0000 (Mon, 15 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/tests/tsprintf.c
+
+untabify and remove trailing spaces
+------------------------------------------------------------------------
+r5754 | thevenyp | 2008-12-15 17:07:40 +0000 (Mon, 15 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: more explanations on the precision field.
+
+------------------------------------------------------------------------
+r5753 | thevenyp | 2008-12-15 16:19:26 +0000 (Mon, 15 Dec 2008) | 5 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr.texi
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+mpfr.texi: Clearly mention that the length modifier 'q' is unsupported by mpfr-*printf.
+vasprintf.c: Do not take quad_t as a long long but as an insupported length modifier.
+acinclude.m4: Remove check for quad_t.
+tests/tprintf.c tests/tfprintf.c: Remove tests with 'q' length modifier.
+
+------------------------------------------------------------------------
+r5751 | vlefevre | 2008-12-15 14:52:54 +0000 (Mon, 15 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tstrtofr.c
+
+tests/tstrtofr.c: fixed a test (in case |res| > 1).
+------------------------------------------------------------------------
+r5750 | vlefevre | 2008-12-15 14:35:01 +0000 (Mon, 15 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tstrtofr.c
+
+tests/tstrtofr.c: fixed alignment bug in error message.
+------------------------------------------------------------------------
+r5749 | zimmerma | 2008-12-15 13:44:25 +0000 (Mon, 15 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+[nightly-test] added MPFR_CHECK_LIBC_PRINTF
+
+------------------------------------------------------------------------
+r5748 | thevenyp | 2008-12-15 13:43:52 +0000 (Mon, 15 Dec 2008) | 4 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/acinclude.m4
+ M /trunk/vasprintf.c
+
+acinclude.m4: Check for quad_t.
+vasprintf.c: Accept length modifier 'q' if HAVE_QUAD_T is defined (instead of HAVE_LONG_LONG).
+README.dev: Add notice for new HAVE_QUAD_T macro.
+
+------------------------------------------------------------------------
+r5747 | zimmerma | 2008-12-15 13:43:40 +0000 (Mon, 15 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] added warning about usage of mpfr_init
+
+------------------------------------------------------------------------
+r5746 | vlefevre | 2008-12-15 13:39:35 +0000 (Mon, 15 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c: _MPFR_H_HAVE_INTMAX_T -> HAVE_STDINT_H for <stdint.h>.
+------------------------------------------------------------------------
+r5745 | thevenyp | 2008-12-15 13:33:22 +0000 (Mon, 15 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: Tests against libc's sprintf function are no more executed unless the MPFR_CHECK_LIBC_PRINTF is defined.
+
+------------------------------------------------------------------------
+r5744 | thevenyp | 2008-12-15 13:27:49 +0000 (Mon, 15 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: move bugs 20080610 and 20081214 outside the function random_double.
+
+------------------------------------------------------------------------
+r5743 | vlefevre | 2008-12-15 12:49:58 +0000 (Mon, 15 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: completed comment about the sign of a null exponent.
+------------------------------------------------------------------------
+r5742 | vlefevre | 2008-12-15 12:44:09 +0000 (Mon, 15 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: added a note saying the L modifier was added in C89 (source:
+C99 rationale, Section 7.19.6.1).
+------------------------------------------------------------------------
+r5741 | zimmerma | 2008-12-15 12:17:46 +0000 (Mon, 15 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] more Windows-related changes
+
+------------------------------------------------------------------------
+r5740 | zimmerma | 2008-12-15 11:02:17 +0000 (Mon, 15 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] update on Windows (from Brian Gladman)
+
+------------------------------------------------------------------------
+r5739 | zimmerma | 2008-12-15 09:47:46 +0000 (Mon, 15 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+[configure.in] removed useless comment
+
+------------------------------------------------------------------------
+r5738 | vlefevre | 2008-12-14 15:28:17 +0000 (Sun, 14 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: references to ISO (international) instead of ANSI (American).
+------------------------------------------------------------------------
+r5737 | vlefevre | 2008-12-14 15:18:54 +0000 (Sun, 14 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: corrected a comment.
+------------------------------------------------------------------------
+r5736 | zimmerma | 2008-12-14 09:43:40 +0000 (Sun, 14 Dec 2008) | 3 lines
+Changed paths:
+ M /trunk/printf.c
+ M /trunk/vasprintf.c
+
+[printf.c,vasprintf.c] include config.h if HAVE_CONFIG_H is defined, to
+ solve problem noticed by Brian Gladman
+
+------------------------------------------------------------------------
+r5735 | vlefevre | 2008-12-14 09:37:05 +0000 (Sun, 14 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: untabified.
+------------------------------------------------------------------------
+r5734 | zimmerma | 2008-12-14 09:27:08 +0000 (Sun, 14 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] added hint for using the MinGW runtime
+
+------------------------------------------------------------------------
+r5733 | zimmerma | 2008-12-14 08:36:37 +0000 (Sun, 14 Dec 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+[tsprintf.c] added new hard-coded test (needs work to overcome error in
+ system asprintf)
+
+------------------------------------------------------------------------
+r5732 | zimmerma | 2008-12-14 08:24:42 +0000 (Sun, 14 Dec 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+[tsprintf.c] fixed hard-coded test (spec was missing), and print values of
+ xi,yi,spec in case of error
+
+------------------------------------------------------------------------
+r5731 | vlefevre | 2008-12-14 00:05:20 +0000 (Sun, 14 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: corrections on r5730.
+------------------------------------------------------------------------
+r5730 | zimmerma | 2008-12-13 10:19:25 +0000 (Sat, 13 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] added notes on Windows Vista 64 problem
+
+------------------------------------------------------------------------
+r5727 | vlefevre | 2008-12-12 15:00:33 +0000 (Fri, 12 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/README
+
+README: added "compile" since it is distributed in the tarball.
+------------------------------------------------------------------------
+r5723 | vlefevre | 2008-12-12 14:07:19 +0000 (Fri, 12 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk
+
+Added "compile" to svn:ignore property (this file is installed by
+"automake --add-missing" due to AM_PROG_CC_C_O, added in r5710).
+------------------------------------------------------------------------
+r5722 | vlefevre | 2008-12-12 14:01:33 +0000 (Fri, 12 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: avoid an abort if field width or precision is > INT_MAX.
+------------------------------------------------------------------------
+r5721 | thevenyp | 2008-12-12 14:00:33 +0000 (Fri, 12 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tset_ld.c
+
+tests.c, tset_ld.c, tgeneric.c: Code clean-up based on icc warnings (as in r5492): Use #ifdef BOOL_MACRO instead of #if BOOL_MACRO.
+
+------------------------------------------------------------------------
+r5720 | thevenyp | 2008-12-12 13:54:37 +0000 (Fri, 12 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: remove line 'GCC=' in icc tests which seems to confuse libtool.
+
+------------------------------------------------------------------------
+r5719 | vlefevre | 2008-12-12 12:54:10 +0000 (Fri, 12 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/set_ld.c
+
+set_ld.c: rewrote exp computation.
+------------------------------------------------------------------------
+r5718 | vlefevre | 2008-12-12 12:12:11 +0000 (Fri, 12 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: avoid a possible gcc 4.1.2 bug with -ftrapv.
+------------------------------------------------------------------------
+r5717 | vlefevre | 2008-12-12 11:57:37 +0000 (Fri, 12 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: revert incorrect change in r5713.
+------------------------------------------------------------------------
+r5716 | zimmerma | 2008-12-12 11:47:52 +0000 (Fri, 12 Dec 2008) | 8 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+[set_ld.c] fixed problem with CC=g++ on 64-bit computer:
+$ g++ -v
+Using built-in specs.
+Target: x86_64-linux-gnu
+Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release x86_64-linux-gnu
+Thread model: posix
+gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
+
+------------------------------------------------------------------------
+r5713 | zimmerma | 2008-12-12 10:05:49 +0000 (Fri, 12 Dec 2008) | 3 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+[vasprintf.c] patch to MPFR_ASSERTN(...) call to avoid failure with gcc -ftrapv
+ with gcc 4.1.2 (probably compiler error)
+
+------------------------------------------------------------------------
+r5712 | thevenyp | 2008-12-12 09:20:14 +0000 (Fri, 12 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tmul.c
+
+Makefile.am, tmul.c: Rename macro __SRCDIR to MPFR_SRCDIR.
+
+------------------------------------------------------------------------
+r5710 | thevenyp | 2008-12-11 15:20:56 +0000 (Thu, 11 Dec 2008) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tmul.c
+
+configure.in: Add AM_PROG_CC_C_O needed by tmul_CPPFLAGS.
+tests/Makefile.am: Add tmul.dat in EXTRA_DIST and pass srcdir to tmul.c through tmul_CPPFLAGS.
+tests/tmul.c: Add path to tmul.dat.
+
+------------------------------------------------------------------------
+r5703 | vlefevre | 2008-12-09 16:46:13 +0000 (Tue, 09 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: TLS on darwin may work, but I don't know anything more.
+See thread <http://gcc.gnu.org/ml/gcc/2008-12/msg00107.html>.
+------------------------------------------------------------------------
+r5702 | vlefevre | 2008-12-08 16:02:29 +0000 (Mon, 08 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/README
+
+README: CVS -> Subversion.
+------------------------------------------------------------------------
+r5701 | vlefevre | 2008-12-03 12:40:01 +0000 (Wed, 03 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: format --enable-decimal-float description on 80 columns.
+------------------------------------------------------------------------
+r5700 | vlefevre | 2008-12-03 12:38:06 +0000 (Wed, 03 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: for --enable-thread-safe, say that the system must support
+it (like what has been done for --enable-logging, just above).
+------------------------------------------------------------------------
+r5699 | vlefevre | 2008-12-03 12:31:28 +0000 (Wed, 03 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: added details about ---enable-thread-safe and TLS support.
+------------------------------------------------------------------------
+r5698 | vlefevre | 2008-11-28 12:09:08 +0000 (Fri, 28 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/urandomb.c
+
+urandomb.c: added comments and cleaned up code.
+mpfr.texi: improved description of mpfr_urandomb.
+------------------------------------------------------------------------
+r5697 | vlefevre | 2008-11-26 14:39:22 +0000 (Wed, 26 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: changed URL added in r5696 to avoid a redirection.
+------------------------------------------------------------------------
+r5696 | zimmerma | 2008-11-26 14:22:37 +0000 (Wed, 26 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] added official url on ftp.gnu.org
+
+------------------------------------------------------------------------
+r5695 | vlefevre | 2008-11-26 09:16:40 +0000 (Wed, 26 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tmul.c
+
+tests/tmul.c: removed useless variable.
+------------------------------------------------------------------------
+r5694 | vlefevre | 2008-11-26 09:14:38 +0000 (Wed, 26 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tmul.c
+
+tests/tmul.c: made reading a string from file more robust.
+------------------------------------------------------------------------
+r5693 | zimmerma | 2008-11-26 08:14:13 +0000 (Wed, 26 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+ A /trunk/tests/tmul.dat
+
+[tmul.c] moved long strings to file tmul.dat, so that gcc -ansi
+ -pedantic-errors works (ISO C90 does not support strings of length
+ > 509)
+
+------------------------------------------------------------------------
+r5692 | vlefevre | 2008-11-26 00:55:32 +0000 (Wed, 26 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/tinternals.c
+
+tests/tinternals.c: updated tests for guaranteed C90 support, e.g. with
+gcc -ansi -pedantic-errors (avoid error "string length 'nnn' is greater
+than the length '509' ISO C90 compilers are required to support" because
+expression for #expr in ASSERT_FAIL macro is too long).
+------------------------------------------------------------------------
+r5691 | vlefevre | 2008-11-26 00:48:12 +0000 (Wed, 26 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: in Section "To make a release", suggest -pedantic-errors.
+------------------------------------------------------------------------
+r5690 | vlefevre | 2008-11-22 15:49:07 +0000 (Sat, 22 Nov 2008) | 5 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/agm.c
+ M /trunk/atan.c
+ M /trunk/cos.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/gamma.c
+ M /trunk/get_str.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/modf.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/mulders.c
+ M /trunk/rec_sqrt.c
+ M /trunk/root.c
+ M /trunk/tanh.c
+ M /trunk/vasprintf.c
+ M /trunk/yn.c
+
+r5689 undone: some casts were incorrect (mp_exp_t may be greater than
+mp_prec_t, so that casting a mp_exp_t into a mp_prec_t can introduce a
+bug). There may be bugs in some cases, but the casts fix the symptom,
+not the bug (unless one casts the unsigned type to a signed type that
+is *strictly* larger, which is not possible here).
+------------------------------------------------------------------------
+r5689 | zimmerma | 2008-11-22 09:55:42 +0000 (Sat, 22 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/agm.c
+ M /trunk/atan.c
+ M /trunk/cos.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/gamma.c
+ M /trunk/get_str.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/modf.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/mulders.c
+ M /trunk/rec_sqrt.c
+ M /trunk/root.c
+ M /trunk/tanh.c
+ M /trunk/vasprintf.c
+ M /trunk/yn.c
+
+fixed some signed/unsigned warnings with g++ (please review)
+
+------------------------------------------------------------------------
+r5688 | zimmerma | 2008-11-21 12:53:47 +0000 (Fri, 21 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/nightly-test
+
+[nightly-test] removed MPFR_CHECK_ALL (no longer used)
+ added possibility to choose compiler (e.g., g++)
+
+------------------------------------------------------------------------
+r5687 | zimmerma | 2008-11-21 12:44:39 +0000 (Fri, 21 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] better check ./configure CC=g++
+
+------------------------------------------------------------------------
+r5686 | thevenyp | 2008-11-21 10:07:53 +0000 (Fri, 21 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+Fix inclusion order: the limit of integer types like size_t are defined in C++ only when __STDC_LIMIT_MACROS is defined before <stdint.h> is included (from ISO C99 7.18.3).
+
+------------------------------------------------------------------------
+r5685 | vlefevre | 2008-11-21 08:27:07 +0000 (Fri, 21 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/README
+
+README: added m4 directory (since it is distributed in the tarball).
+------------------------------------------------------------------------
+r5684 | vlefevre | 2008-11-20 19:29:58 +0000 (Thu, 20 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+
+Forgot to update Makefile.am too (for r5680).
+------------------------------------------------------------------------
+r5683 | vlefevre | 2008-11-20 19:20:18 +0000 (Thu, 20 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: added AC_CONFIG_MACRO_DIR([m4]) for r5680.
+------------------------------------------------------------------------
+r5682 | zimmerma | 2008-11-20 17:14:35 +0000 (Thu, 20 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.c
+
+[mpfr-gmp.c] added comment on recent bug fix on MacOS
+
+------------------------------------------------------------------------
+r5681 | zimmerma | 2008-11-20 10:53:02 +0000 (Thu, 20 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/texp.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tpow_all.c
+
+[tests] changes to make compilation work with g++ (only fixed errors,
+ several warnings remain)
+
+------------------------------------------------------------------------
+r5680 | vlefevre | 2008-11-20 10:42:50 +0000 (Thu, 20 Nov 2008) | 1 line
+Changed paths:
+ A /trunk/m4
+ A /trunk/m4/size_max.m4
+
+Added m4/size_max.m4 file (from gettext).
+------------------------------------------------------------------------
+r5679 | vlefevre | 2008-11-20 10:26:32 +0000 (Thu, 20 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: paragraph on tentative definitions.
+------------------------------------------------------------------------
+r5678 | zimmerma | 2008-11-20 09:13:09 +0000 (Thu, 20 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr-gmp.c
+
+[mpfr-gmp.c] replace tentative definitions by real definitions, solves
+ configure problems with mpc (see http://lists.gforge.inria.fr/pipermail/mpc-discuss/2008-November/000048.html)
+
+------------------------------------------------------------------------
+r5677 | vlefevre | 2008-11-18 01:01:33 +0000 (Tue, 18 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/hypot.c
+
+hypot.c: updated a comment.
+------------------------------------------------------------------------
+r5676 | vlefevre | 2008-11-18 00:40:13 +0000 (Tue, 18 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/tests/thypot.c
+
+tests/thypot.c: added a test.
+------------------------------------------------------------------------
+r5675 | vlefevre | 2008-11-18 00:21:09 +0000 (Tue, 18 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/hypot.c
+
+hypot.c: simplified an expression; cosmetic changes.
+------------------------------------------------------------------------
+r5674 | thevenyp | 2008-11-17 08:43:59 +0000 (Mon, 17 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+hypot.c: Fix underflow problem when diff_exp<=MPFR_EMAX_MAX-2 using fma (provided that mpfr_fma is immune to it).
+
+------------------------------------------------------------------------
+r5673 | thevenyp | 2008-11-17 08:40:52 +0000 (Mon, 17 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: Fix one typo in dilogarithm section.
+
+------------------------------------------------------------------------
+r5672 | vlefevre | 2008-11-12 14:53:07 +0000 (Wed, 12 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.texi
+
+mpfr.texi, NEWS: update concerning mpfr_eq.
+------------------------------------------------------------------------
+r5671 | vlefevre | 2008-11-12 14:09:45 +0000 (Wed, 12 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: improved mpfr_eq documentation.
+------------------------------------------------------------------------
+r5670 | thevenyp | 2008-11-12 12:33:37 +0000 (Wed, 12 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tstrtofr.c
+
+tests/tstrtofr.c: Add more information when test bug20081028 fails.
+
+------------------------------------------------------------------------
+r5669 | thevenyp | 2008-11-07 10:19:42 +0000 (Fri, 07 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/strtofr.c
+ M /trunk/tests/tstrtofr.c
+
+strtofr.c: Replace non-zero digits look up by a simpler test, using the fact that parse_string did remove zeros at end of pstr->mant.
+tests/tstrtofr.c: Add other test values around 1 for the bug20081028 non regression test.
+
+------------------------------------------------------------------------
+r5668 | vlefevre | 2008-11-07 01:12:36 +0000 (Fri, 07 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/strtofr.c
+
+strtofr.c: improved style ("exact" is a boolean).
+------------------------------------------------------------------------
+r5667 | zimmerma | 2008-11-06 16:53:17 +0000 (Thu, 06 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/strtofr.c
+ M /trunk/tests/tstrtofr.c
+
+[strtofr.c] new patch (ternary value was still wrong in some cases), should
+ be ok now
+[tstrtofr.c] added new test
+
+------------------------------------------------------------------------
+r5666 | zimmerma | 2008-11-05 17:10:10 +0000 (Wed, 05 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/mpn_exp.c
+ M /trunk/strtofr.c
+
+[strtofr.c] review of patch added in revision 5660, and added comments
+
+------------------------------------------------------------------------
+r5665 | vlefevre | 2008-10-29 14:31:20 +0000 (Wed, 29 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+Updated NEWS file.
+------------------------------------------------------------------------
+r5662 | vlefevre | 2008-10-29 13:52:17 +0000 (Wed, 29 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+strtofr.c: in r5660, as pstr_size and pstr->prec both have type size_t,
+changed the type of i from mp_size_t to size_t for consistency.
+------------------------------------------------------------------------
+r5661 | vlefevre | 2008-10-29 13:43:14 +0000 (Wed, 29 Oct 2008) | 3 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+strtofr.c: reverted the change done in r3008, which led to a trivial
+assertion. I think the goal is to make sure that pstr_size (of type
+size_t) can be represented in a mp_exp_t (as required in the code).
+------------------------------------------------------------------------
+r5660 | thevenyp | 2008-10-29 12:05:11 +0000 (Wed, 29 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+strtofr.c: fix bug '[#6604] incorrect directed rounding in mpfr_strtofr'.
+
+------------------------------------------------------------------------
+r5659 | vlefevre | 2008-10-29 02:31:21 +0000 (Wed, 29 Oct 2008) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: replaced $(...) quoting style by "`...`" since the former
+is not supported everywhere (and indeed is not used by the autotools):
+http://swox.com/list-archives/gmp-bugs/2008-October/001185.html
+------------------------------------------------------------------------
+r5658 | vlefevre | 2008-10-29 01:21:29 +0000 (Wed, 29 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tstrtofr.c
+
+tests/tstrtofr.c: added bug20081028 (bug found by Christoph Lauter
+in mpfr_set_str; this is the corresponding bug in mpfr_strtofr).
+------------------------------------------------------------------------
+r5657 | vlefevre | 2008-10-29 01:10:36 +0000 (Wed, 29 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tstrtofr.c
+
+tests/tstrtofr.c: corrections related to C usage.
+------------------------------------------------------------------------
+r5656 | vlefevre | 2008-10-29 00:59:00 +0000 (Wed, 29 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+tests/tset_str.c: added bug20081028 (bug found by Christoph Lauter).
+------------------------------------------------------------------------
+r5655 | vlefevre | 2008-10-27 03:55:33 +0000 (Mon, 27 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated @dircategory (request by Karl Berry).
+------------------------------------------------------------------------
+r5654 | vlefevre | 2008-10-27 03:27:10 +0000 (Mon, 27 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_d.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_d.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_patches.sh
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/minmax.c
+ M /trunk/modf.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mparam_h.in
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-thread.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpfrlint
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_d.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/printf.c
+ M /trunk/random2.c
+ M /trunk/rec_sqrt.c
+ M /trunk/reldiff.c
+ M /trunk/rem1.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/setsign.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/signbit.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_d.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/data/li2
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tisqrt.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_all.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+This is now GNU MPFR!
+------------------------------------------------------------------------
+r5653 | vlefevre | 2008-10-27 03:10:36 +0000 (Mon, 27 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/README
+
+README: CVS -> Subversion.
+------------------------------------------------------------------------
+r5652 | thevenyp | 2008-10-23 18:40:33 +0000 (Thu, 23 Oct 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: Fix bug with '#' and 'g' flag combination, see also defect report at http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_233.htm.
+tests/tsprintf.c: Fix wrong test value accordingly, add non-regression tests.
+
+------------------------------------------------------------------------
+r5651 | zimmerma | 2008-10-23 07:29:29 +0000 (Thu, 23 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/get_d64.c
+ M /trunk/set_d64.c
+
+[get_d64.c,set_d64.c] added reference to TR 24732
+
+------------------------------------------------------------------------
+r5650 | vlefevre | 2008-10-16 08:17:35 +0000 (Thu, 16 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: added a comment about MPFR_SIGN.
+------------------------------------------------------------------------
+r5649 | zimmerma | 2008-10-05 08:51:41 +0000 (Sun, 05 Oct 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+[mpfr.h] fixed typo, and added warning about MPFR_SIGN.
+ Shouldn't we move it in mpfr-impl.h?
+
+------------------------------------------------------------------------
+r5647 | vlefevre | 2008-10-03 11:45:14 +0000 (Fri, 03 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/configure.in
+
+INSTALL, configure.in: corrected documentation of --with-gmp* options.
+------------------------------------------------------------------------
+r5645 | vlefevre | 2008-10-02 11:40:42 +0000 (Thu, 02 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: gave more details about --with-gmp-build.
+------------------------------------------------------------------------
+r5644 | zimmerma | 2008-10-02 11:17:49 +0000 (Thu, 02 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+[INSTALL] added warning about usage of --with-gmp-build
+
+------------------------------------------------------------------------
+r5643 | vlefevre | 2008-09-21 11:56:06 +0000 (Sun, 21 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: updated LIA-2 terminology ("pole" was in the latest public draft,
+"infinitary" in the final standard).
+------------------------------------------------------------------------
+r5642 | thevenyp | 2008-09-19 08:50:01 +0000 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tstrtofr.c
+
+tests/tstrtofr.c: Remove underflow test unintentionally commited with revision 5640.
+
+------------------------------------------------------------------------
+r5640 | thevenyp | 2008-09-18 16:33:16 +0000 (Thu, 18 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ D /trunk/random.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+
+Remove obsolete mpfr_random function and replace it by mpfr_urandomb in tests.
+
+------------------------------------------------------------------------
+r5639 | thevenyp | 2008-09-18 16:25:31 +0000 (Thu, 18 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/exceptions.c
+
+Add void in prototype.
+
+------------------------------------------------------------------------
+r5638 | vlefevre | 2008-09-18 13:40:11 +0000 (Thu, 18 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: added comments about the MPFR_FPU_PREC macro.
+------------------------------------------------------------------------
+r5636 | zimmerma | 2008-09-18 12:48:28 +0000 (Thu, 18 Sep 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+[tget_str.c] replaced 'double' input by 'char*' to avoid problems with single
+ precision (partially solves #3353)
+
+------------------------------------------------------------------------
+r5634 | zimmerma | 2008-09-17 12:28:22 +0000 (Wed, 17 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+[README.dev] added item about coverage of releases
+
+------------------------------------------------------------------------
+r5632 | zimmerma | 2008-09-16 12:48:29 +0000 (Tue, 16 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+ M /trunk/Makefile.am
+ M /trunk/algorithms.tex
+ M /trunk/atan.c
+ M /trunk/extract.c
+ M /trunk/mpfr.texi
+
+final got rid of generic.c (bug 6199)
+
+------------------------------------------------------------------------
+r5631 | zimmerma | 2008-09-16 12:37:11 +0000 (Tue, 16 Sep 2008) | 2 lines
+Changed paths:
+ D /trunk/generic.c
+
+[generic.c] removed unused file
+
+------------------------------------------------------------------------
+r5630 | vlefevre | 2008-09-16 09:53:59 +0000 (Tue, 16 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.texi
+
+NEWS, mpfr.texi: documented the fact that mpfr_random and mpfr_random2
+will be suppressed in the next release.
+------------------------------------------------------------------------
+r5629 | vlefevre | 2008-09-16 08:53:00 +0000 (Tue, 16 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/ChangeLog
+
+ChangeLog update with "LC_ALL=en_US.UTF8 TZ=UTC svn log -rHEAD:0 -v".
+------------------------------------------------------------------------
+r5623 | thevenyp | 2008-09-10 10:00:31 +0000 (Wed, 10 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow_z.c
+
+tests/tpow_z.c: Check test for bug20080904 with the minimum possible negative exponent so as not to underflow with (future) 128 bits machine.
+
+------------------------------------------------------------------------
+r5620 | vlefevre | 2008-09-06 10:19:10 +0000 (Sat, 06 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: fixed bug20080904 (from tpow_z.c).
+------------------------------------------------------------------------
+r5619 | vlefevre | 2008-09-06 10:08:37 +0000 (Sat, 06 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: added log messages.
+------------------------------------------------------------------------
+r5618 | thevenyp | 2008-09-05 10:10:41 +0000 (Fri, 05 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow_z.c
+
+tests/tpow_z.c: Add a test that underflows.
+
+------------------------------------------------------------------------
+r5616 | vlefevre | 2008-09-05 09:05:25 +0000 (Fri, 05 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: updated a comment (for the next automake version).
+------------------------------------------------------------------------
+r5614 | vlefevre | 2008-09-05 08:56:53 +0000 (Fri, 05 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: added a note about mpfr_init_gmp_rand (removed in r4953).
+------------------------------------------------------------------------
+r5613 | vlefevre | 2008-09-04 02:44:04 +0000 (Thu, 04 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: update (about AM_MAINTAINER_MODE).
+------------------------------------------------------------------------
+r5609 | vlefevre | 2008-09-02 15:09:20 +0000 (Tue, 02 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/README
+
+Updated README file.
+------------------------------------------------------------------------
+r5607 | vlefevre | 2008-09-01 11:51:00 +0000 (Mon, 01 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+ D /trunk/patch-libtool
+
+Removed patch-libtool and updated README.dev as libtool has been fixed.
+------------------------------------------------------------------------
+r5606 | vlefevre | 2008-09-01 11:47:16 +0000 (Mon, 01 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+NEWS file update (get default $CC and $CFLAGS from gmp.h).
+------------------------------------------------------------------------
+r5605 | vlefevre | 2008-09-01 11:46:24 +0000 (Mon, 01 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: removed a useless blank line.
+------------------------------------------------------------------------
+r5604 | vlefevre | 2008-09-01 11:40:36 +0000 (Mon, 01 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: reverse-merged r5440 (about __GMP_CC/__GMP_CFLAGS) as said.
+------------------------------------------------------------------------
+r5602 | zimmerma | 2008-08-27 11:43:31 +0000 (Wed, 27 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+[algorithms.tex] the truncation error for rec_sqrt was correct, but the
+reasoning was not detailed enough
+
+------------------------------------------------------------------------
+r5600 | vlefevre | 2008-08-27 10:58:23 +0000 (Wed, 27 Aug 2008) | 3 lines
+Changed paths:
+ A /trunk/patch-aclocal-icc
+
+Added patch-aclocal-icc; this is a port of the patch posted on
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=485421
+for aclocal.m4 when libtool 1.5.26-4 from Debian has been used.
+------------------------------------------------------------------------
+r5599 | zimmerma | 2008-08-27 10:00:35 +0000 (Wed, 27 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/rec_sqrt.c
+ M /trunk/round_p.c
+
+[rec_sqrt.c] fixed bug "bad_case1" (truncation error was forgotten, when
+output precision was smaller than input precision)
+
+------------------------------------------------------------------------
+r5595 | vlefevre | 2008-08-27 08:40:53 +0000 (Wed, 27 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+------------------------------------------------------------------------
+r5593 | vlefevre | 2008-08-26 13:56:06 +0000 (Tue, 26 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/trec_sqrt.c
+
+tests/trec_sqrt.c: enable the tests only with MPFR 2.4.0+.
+------------------------------------------------------------------------
+r5592 | vlefevre | 2008-08-26 13:32:45 +0000 (Tue, 26 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: noted when some changes were applied in 2.3.* versions.
+------------------------------------------------------------------------
+r5590 | vlefevre | 2008-08-25 13:26:32 +0000 (Mon, 25 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: completed information about integer types.
+------------------------------------------------------------------------
+r5589 | vlefevre | 2008-08-25 10:55:38 +0000 (Mon, 25 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added information about mixing signed and unsigned types.
+------------------------------------------------------------------------
+r5588 | vlefevre | 2008-08-25 10:40:09 +0000 (Mon, 25 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/li2.c
+
+li2.c: avoid even more mixing between signed and unsigned types, by
+casting mpfr_prec_t to mp_exp_t in expressions involving mp_exp_t.
+This time the bug is fixed: tli2 no longer freezes in 64 bits.
+------------------------------------------------------------------------
+r5587 | vlefevre | 2008-08-25 10:26:54 +0000 (Mon, 25 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/li2.c
+
+li2.c: use an "int" instead of "unsigned int" in li2_series() to avoid
+mixing signed and unsigned types, which can yield implicit conversions
+from signed into unsigned, and maybe problems on some platforms. This
+doesn't fix the current freeze of tli2 on 64-bit machines, though.
+------------------------------------------------------------------------
+r5585 | vlefevre | 2008-08-24 23:07:45 +0000 (Sun, 24 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tests/tgeneric.c: changed the way a warning with gcc 4.2+ is avoided
+(r5335), as suggested by Manuel López-Ibáñez on GCC bug 36299.
+------------------------------------------------------------------------
+r5584 | vlefevre | 2008-08-21 10:27:58 +0000 (Thu, 21 Aug 2008) | 2 lines
+Changed paths:
+ A /trunk/tests/data/sqr
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+
+Added data_check support to mpfr_sqr.
+Added bad_cases support to mpfr_sqr and mpfr_sqrt.
+------------------------------------------------------------------------
+r5582 | vlefevre | 2008-08-21 10:17:19 +0000 (Thu, 21 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tsqr.c
+
+tests/tsqr.c: corrected function definitions.
+------------------------------------------------------------------------
+r5581 | vlefevre | 2008-08-21 10:12:49 +0000 (Thu, 21 Aug 2008) | 1 line
+Changed paths:
+ A /trunk/tests/data/rec_sqrt
+ M /trunk/tests/trec_sqrt.c
+
+Added data_check & bad_cases support to mpfr_rec_sqrt.
+------------------------------------------------------------------------
+r5580 | vlefevre | 2008-08-21 10:09:34 +0000 (Thu, 21 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/trec_sqrt.c
+
+tests/trec_sqrt.c: added bad case that makes mpfr_rec_sqrt fail.
+------------------------------------------------------------------------
+r5579 | vlefevre | 2008-08-21 03:03:23 +0000 (Thu, 21 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: as not all ICC versions define the __ICC macro (only
+the __INTEL_COMPILER macro can be defined), define the __MPFR_ICC
+and __MPFR_GNUC macros in another way.
+------------------------------------------------------------------------
+r5578 | vlefevre | 2008-08-21 02:48:41 +0000 (Thu, 21 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: fixed compilation failure when HAVE_DENORMS isn't
+defined, such as with icc 10.1 on Itanium.
+------------------------------------------------------------------------
+r5577 | vlefevre | 2008-08-21 02:43:45 +0000 (Thu, 21 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c: to allow random values to be reproducible,
+do not call randlimb several times in a same expression,
+because the evaluation order is unspecified.
+------------------------------------------------------------------------
+r5576 | vlefevre | 2008-08-21 02:38:07 +0000 (Thu, 21 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: added test of mpfr_rec_sqrt (only with MPFR 2.4.0+).
+------------------------------------------------------------------------
+r5575 | vlefevre | 2008-08-21 02:35:37 +0000 (Thu, 21 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: removed useless parentheses.
+------------------------------------------------------------------------
+r5574 | vlefevre | 2008-08-21 02:27:56 +0000 (Thu, 21 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/rec_sqrt.c
+
+rec_sqrt.c: added logging support.
+------------------------------------------------------------------------
+r5572 | vlefevre | 2008-08-21 01:27:38 +0000 (Thu, 21 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: replaced "towards" by "toward" for consistency with
+the MPFR manual and the standards.
+------------------------------------------------------------------------
+r5570 | vlefevre | 2008-08-21 01:22:42 +0000 (Thu, 21 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: corrected English usage, spelling and typography
+in the section on mpfr_hypot.
+------------------------------------------------------------------------
+r5566 | vlefevre | 2008-08-20 22:17:34 +0000 (Wed, 20 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/thypot.c
+
+tests/thypot.c: added a test for tiny x and y (already done by the
+generic tests, but not yet in the 2.3 branch in extended exponent
+range).
+------------------------------------------------------------------------
+r5565 | vlefevre | 2008-08-20 21:43:34 +0000 (Wed, 20 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tests/tgeneric.c: for the special cases tested in precision p1
+for n <= 3, set the extended exponent range.
+------------------------------------------------------------------------
+r5564 | vlefevre | 2008-08-20 21:10:29 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/thypot.c
+
+tests/thypot.c: improved error messages.
+------------------------------------------------------------------------
+r5563 | vlefevre | 2008-08-20 20:48:44 +0000 (Wed, 20 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/thypot.c
+
+tests/thypot.c: perform some tests both in the current exponent range
+and in the extended exponent range, so that the lost-overflow bug of
+MPFR 2.3.1 can be triggered on 64-bit machines too.
+------------------------------------------------------------------------
+r5561 | vlefevre | 2008-08-20 19:43:57 +0000 (Wed, 20 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c:
+ * In cmpres(), if z1 and z2 were both zeros, their sign wasn't tested.
+ * Added test of mpfr_sqr and mpfr_sqrt.
+------------------------------------------------------------------------
+r5559 | vlefevre | 2008-08-20 16:24:24 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added a paragraph on MPFR internal data.
+------------------------------------------------------------------------
+r5557 | vlefevre | 2008-08-20 14:11:18 +0000 (Wed, 20 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+pow_si.c: fixed the underflow/overflow detection for n < 0 by using
+a method similar to mpfr_pow_z.
+------------------------------------------------------------------------
+r5556 | vlefevre | 2008-08-20 13:21:00 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/pow_si.c
+
+pow_si.c: added logging support.
+------------------------------------------------------------------------
+r5555 | vlefevre | 2008-08-20 12:58:21 +0000 (Wed, 20 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: fixed bug in mpfr_pow_general by computing correct bounds
+on exp(y*ln|x|). ==> tpow no longer fails in bug20080820.
+Note: this bug could affect only underflow cases and possibly cases
+near overflow.
+------------------------------------------------------------------------
+r5554 | vlefevre | 2008-08-20 12:48:53 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: updated comment for bug20080820().
+------------------------------------------------------------------------
+r5553 | vlefevre | 2008-08-20 12:47:40 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: added testcase for bug mentioned in r5552.
+------------------------------------------------------------------------
+r5552 | vlefevre | 2008-08-20 11:41:13 +0000 (Wed, 20 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: solves the underflow problem in round-to-nearest by using
+mpfr_pow_general in precision 2 (like in mpfr_pow_pos_z), but this
+currently fails due to a more general bug from r4940 (the rounding
+modes to compute an upper bound on exp(y*ln|x|) are incorrect).
+------------------------------------------------------------------------
+r5551 | vlefevre | 2008-08-20 06:42:16 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: formatting.
+------------------------------------------------------------------------
+r5550 | vlefevre | 2008-08-20 06:36:59 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: moved a log message.
+------------------------------------------------------------------------
+r5549 | vlefevre | 2008-08-20 06:34:52 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: added log messages.
+------------------------------------------------------------------------
+r5548 | vlefevre | 2008-08-20 05:55:56 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: added an underflow test of x^y with y integer < 0.
+------------------------------------------------------------------------
+r5547 | vlefevre | 2008-08-20 04:17:03 +0000 (Wed, 20 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: no longer take care of the possibly lost overflow flag, as
+the other functions do not do this either; this general problem has
+been fixed in mpfr_check_range (r5545).
+------------------------------------------------------------------------
+r5545 | vlefevre | 2008-08-20 04:07:16 +0000 (Wed, 20 Aug 2008) | 7 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/exceptions.c
+ M /trunk/mpfr.texi
+
+Fixed the following problem:
+ The overflow flag can be lost in many functions called with the
+ maximum exponent equal to MPFR_EMAX_MAX (this is the default on
+ 32-bit machines) when the temporary result (in a higher precision)
+ is representable but once rounded, it yields an overflow.
+This needed a slight change of behavior of the mpfr_check_range function
+(defined in exceptions.c). Described this change in mpfr.texi and NEWS.
+------------------------------------------------------------------------
+r5544 | vlefevre | 2008-08-20 02:59:16 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: fixed some of the underflow/overflow problems for z < 0.
+------------------------------------------------------------------------
+r5543 | vlefevre | 2008-08-20 02:56:38 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: fixed mpfr_clear in overflow_inv.
+------------------------------------------------------------------------
+r5542 | vlefevre | 2008-08-20 02:50:02 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: more detailed error messages.
+------------------------------------------------------------------------
+r5541 | vlefevre | 2008-08-20 01:23:30 +0000 (Wed, 20 Aug 2008) | 5 lines
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: improved overflow_inv tests to trigger a bug
+in mpfr_pow_z due to incorrect rounding mode settings in r5315:
+on a 64-bit Linux machine, "./tpow_all 1" ends with:
+Bad overflow flag in overflow_inv for mpfr_pow, extended exponent range,
+s = 1, t = 1, GMP_RNDZ
+------------------------------------------------------------------------
+r5540 | vlefevre | 2008-08-20 00:32:17 +0000 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: in overflow_inv, reduced t to [0,5] and added tests.
+------------------------------------------------------------------------
+r5539 | vlefevre | 2008-08-19 23:48:19 +0000 (Tue, 19 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: improved error messages.
+------------------------------------------------------------------------
+r5538 | vlefevre | 2008-08-19 23:39:35 +0000 (Tue, 19 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: changed the precisions in overflow_inv for clearer
+output (the reported failures are the same).
+------------------------------------------------------------------------
+r5537 | vlefevre | 2008-08-19 23:34:23 +0000 (Tue, 19 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: information about extended exponent range wasn't
+always output. For simplicity to provide such an information, made
+ext a global variable.
+------------------------------------------------------------------------
+r5536 | vlefevre | 2008-08-19 23:23:10 +0000 (Tue, 19 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: added overflow tests for x^(-1). -> Failure.
+------------------------------------------------------------------------
+r5535 | vlefevre | 2008-08-19 00:35:49 +0000 (Tue, 19 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/pow.c
+
+Fixed basic underflow checking in mpfr_pow.
+------------------------------------------------------------------------
+r5534 | vlefevre | 2008-08-18 23:30:59 +0000 (Mon, 18 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/lngamma.c
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: defined macro INITIALIZED to declare that some variable
+ is initialized before being used.
+README.dev: described the use of this macro.
+lngamma.c: replaced the dummy initialization by this macro.
+------------------------------------------------------------------------
+r5533 | vlefevre | 2008-08-16 01:04:05 +0000 (Sat, 16 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: updated comments.
+------------------------------------------------------------------------
+r5532 | vlefevre | 2008-08-16 00:48:58 +0000 (Sat, 16 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: added tests -> assertion failed in pow.c line 603.
+------------------------------------------------------------------------
+r5531 | vlefevre | 2008-08-15 23:56:47 +0000 (Fri, 15 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: added test of mpfr_ui_div.
+------------------------------------------------------------------------
+r5530 | vlefevre | 2008-08-15 23:28:46 +0000 (Fri, 15 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: improved comments.
+------------------------------------------------------------------------
+r5527 | vlefevre | 2008-08-14 16:34:58 +0000 (Thu, 14 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: additions related to MPFR caches.
+ * Added Section "Memory Handling" mentioning caches.
+ * Added call to mpfr_free_cache in the first example.
+ * Updated description of function mpfr_free_cache.
+------------------------------------------------------------------------
+r5525 | vlefevre | 2008-08-14 10:17:24 +0000 (Thu, 14 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: improved an underflow test to trigger the bug fixed
+in r5453 on 32-bit machines too.
+------------------------------------------------------------------------
+r5524 | vlefevre | 2008-08-14 09:39:24 +0000 (Thu, 14 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/log.c
+
+log.c: fixed a log message.
+------------------------------------------------------------------------
+r5523 | vlefevre | 2008-08-14 09:38:04 +0000 (Thu, 14 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/exp_2.c
+
+exp_2.c: fixed other log messages.
+------------------------------------------------------------------------
+r5522 | vlefevre | 2008-08-14 09:20:14 +0000 (Thu, 14 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+exp_2.c: fixed a log message (the format didn't correspond to the types)
+and improved it.
+------------------------------------------------------------------------
+r5519 | vlefevre | 2008-08-12 22:27:44 +0000 (Tue, 12 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+tests/tdiv.c: completed underflow test by testing negative results too.
+------------------------------------------------------------------------
+r5517 | vlefevre | 2008-08-12 22:03:37 +0000 (Tue, 12 Aug 2008) | 5 lines
+Changed paths:
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/mul_2si.c
+ M /trunk/tests/tmul_2exp.c
+
+mul_2si.c, div_2si.c, div_2ui.c: fixed double-rounding problem in
+rounding to nearest when the rounded result in unbounded exponent
+range is 2^(emin - 2).
+tests/tmul_2exp.c: test x = 15/16 too. Now tmul_2exp no longer fails
+(with the correction in div.c from r5515).
+------------------------------------------------------------------------
+r5516 | vlefevre | 2008-08-12 21:56:55 +0000 (Tue, 12 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+tests/tdiv.c correction: the underflow bug was in case when the
+result had to be zero.
+------------------------------------------------------------------------
+r5515 | vlefevre | 2008-08-12 21:52:25 +0000 (Tue, 12 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+div.c: fixed underflow bug that occurs in rounding to nearest when
+the rounded result in unbounded exponent range is 2^(emin - 2) and
+inex > 0: one got a non-zero result instead of +/-0.
+------------------------------------------------------------------------
+r5514 | vlefevre | 2008-08-12 21:47:44 +0000 (Tue, 12 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+tests/tdiv.c: added a test that triggers a bug in mpfr_div in case of
+underflow in rounding to nearest when the result must be non-zero.
+------------------------------------------------------------------------
+r5513 | vlefevre | 2008-08-12 14:43:50 +0000 (Tue, 12 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/div.c
+
+div.c: added logging support.
+------------------------------------------------------------------------
+r5512 | vlefevre | 2008-08-12 13:54:40 +0000 (Tue, 12 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+tests/tmul_2exp.c: test mpfr_div_2ui too.
+------------------------------------------------------------------------
+r5511 | vlefevre | 2008-08-12 13:37:03 +0000 (Tue, 12 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+tests/tmul_2exp.c: test mpfr_div_2si too.
+------------------------------------------------------------------------
+r5510 | vlefevre | 2008-08-12 13:28:20 +0000 (Tue, 12 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+tests/tmul_2exp.c: updated underflow() test to trigger a double-rounding
+bug in case of underflow.
+------------------------------------------------------------------------
+r5509 | vlefevre | 2008-08-12 13:11:19 +0000 (Tue, 12 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: updated comment (the double-rounding bug triggered by
+underflow_up() is in mpfr_mul_2si).
+------------------------------------------------------------------------
+r5508 | vlefevre | 2008-08-12 13:02:08 +0000 (Tue, 12 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: updated underflow_up() test: added case exp(eps) ~= 1/2,
+which fails due to a double-rounding problem in rescaling the result.
+------------------------------------------------------------------------
+r5507 | vlefevre | 2008-08-12 12:08:10 +0000 (Tue, 12 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: improved comments in underflow_up().
+------------------------------------------------------------------------
+r5505 | vlefevre | 2008-08-11 08:09:14 +0000 (Mon, 11 Aug 2008) | 33 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/pow.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/tests/tpow_all.c
+
+Merged vlefevre branch:
+ svn merge -c-5445 .
+ svn merge -r5436:HEAD .../mpfr/branches/vlefevre
+* pow.c:
+ - Moved the general case from mpfr_pow() to a new internal function
+ mpfr_pow_general().
+ - In this function (from old code), avoid unnecessary overflow test
+ if the intermediate result is not an infinity (which was the case
+ of underflow with non-zero result, thus not an overflow).
+ - Fixed a double-rounding problem that occurred in this function in
+ some underflow cases when rescaling the result.
+ - Added log messages.
+* mpfr-impl.h: added mpfr_pow_general prototype.
+* pow_z.c:
+ - The underflow case of mpfr_pow_pos_z() in rounding to nearest,
+ which was incorrect, is now handled by calling mpfr_pow_general(),
+ which can scale the result thus decide whether the rounded result
+ should be 0 or nextabove(0). To avoid the exact cases of x^y with
+ y integer (not supported by mpfr_pow_general()), rounding is done
+ in precision 2 (this is also faster!).
+ - Fixed underflow-related bug (case exact result = 2^(emin-2), in
+ rounding to nearest).
+ - Added log messages.
+* pow_ui.c:
+ - Swapped parameters x and y for consistency (-> y = x^n).
+ - Fixed the internal overflows and underflows (which could yield
+ spurious overflows/underflows and incorrect results) by using
+ mpfr_pow_z.
+* tests/tpow_all.c:
+ - Test flags in test_others and cmpres; cmpres argument z1 can now
+ be a null pointer (if unknown pure FP value, thus not tested).
+ - Added a test of 2^(emin - i/4) with 0 <= i <= 12, that triggered
+ the bugs mentioned above (and now fixed).
+------------------------------------------------------------------------
+r5503 | vlefevre | 2008-08-11 07:02:01 +0000 (Mon, 11 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+tests/tmul_2exp.c: added underflow tests.
+------------------------------------------------------------------------
+r5502 | vlefevre | 2008-08-11 07:00:17 +0000 (Mon, 11 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+
+Added logging support to mpfr_{mul,div}_2{si,ui}.
+------------------------------------------------------------------------
+r5498 | vlefevre | 2008-08-08 14:29:03 +0000 (Fri, 08 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: added a space for MPFR_LOG_MSG.
+------------------------------------------------------------------------
+r5496 | vlefevre | 2008-08-08 14:20:45 +0000 (Fri, 08 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: corrected MPFR_LOG_MSG example.
+------------------------------------------------------------------------
+r5494 | vlefevre | 2008-08-08 07:27:23 +0000 (Fri, 08 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: added a comment concerning ICC.
+------------------------------------------------------------------------
+r5493 | vlefevre | 2008-08-07 21:56:50 +0000 (Thu, 07 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/atan2.c
+ M /trunk/get_d64.c
+ M /trunk/li2.c
+ M /trunk/set_d64.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/yn.c
+
+Final code clean-up based on icc warnings.
+------------------------------------------------------------------------
+r5492 | vlefevre | 2008-08-07 21:17:14 +0000 (Thu, 07 Aug 2008) | 7 lines
+Changed paths:
+ M /trunk/cache.c
+ M /trunk/clears.c
+ M /trunk/cos.c
+ M /trunk/fits_intmax.c
+ M /trunk/fits_uintmax.c
+ M /trunk/frac.c
+ M /trunk/get_ld.c
+ M /trunk/get_sj.c
+ M /trunk/get_uj.c
+ M /trunk/hypot.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/set_sj.c
+ M /trunk/set_uj.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/volatile.c
+
+Further code clean-up (and consistency) based on icc warnings:
+ * Removed useless code.
+ * Avoid hiding variable declarations.
+ * Use #ifdef BOOL_MACRO instead of #if BOOL_MACRO.
+ * In MPFR_RNDRAW_GEN macro definition, variables declared locally now
+ start with an underscore to avoid possible conflits with parameters
+ (and modified macro calls that use these variables).
+------------------------------------------------------------------------
+r5491 | vlefevre | 2008-08-07 17:13:16 +0000 (Thu, 07 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/round_prec.c
+
+round_prec.c: avoid hiding variable declaration (detected by icc).
+------------------------------------------------------------------------
+r5490 | vlefevre | 2008-08-07 16:30:13 +0000 (Thu, 07 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+pow_si.c: fixed Ziv's iteration (code from r3305) by using MPFR_ZIV_NEXT
+(problem detected by icc, because variable "loop" was never used).
+------------------------------------------------------------------------
+r5489 | vlefevre | 2008-08-07 16:15:28 +0000 (Thu, 07 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+mul_ui.c: removed variable that was set but never used (detected by icc,
+but not by gcc, probably because of early optimization).
+------------------------------------------------------------------------
+r5488 | vlefevre | 2008-08-07 16:08:45 +0000 (Thu, 07 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/inp_str.c
+
+inp_str.c: fixed possible implementation-defined behavior (a value
+from the unsigned char range -- from getc -- was stored in a char,
+and if the char type is signed and the value cannot be represented
+in a char, this is implementation-defined).
+------------------------------------------------------------------------
+r5487 | vlefevre | 2008-08-07 15:36:59 +0000 (Thu, 07 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/get_str.c
+
+get_str.c: avoid hiding variable declaration (detected by icc).
+------------------------------------------------------------------------
+r5486 | vlefevre | 2008-08-07 14:44:18 +0000 (Thu, 07 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/div.c
+
+div.c: avoid hiding variable declaration (detected by icc).
+------------------------------------------------------------------------
+r5485 | vlefevre | 2008-08-07 14:33:44 +0000 (Thu, 07 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+mpfr.h, mpfr-impl.h: avoid warnings with icc (at least icc 10.1).
+README.dev: added a paragraph on the test of "boolean" macros.
+------------------------------------------------------------------------
+r5483 | vlefevre | 2008-08-05 08:02:07 +0000 (Tue, 05 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: dist-lzma needs automake 1.10.1.
+------------------------------------------------------------------------
+r5481 | vlefevre | 2008-08-04 08:39:47 +0000 (Mon, 04 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: "make dist" generates lzma-compressed tarball too.
+------------------------------------------------------------------------
+r5480 | zimmerma | 2008-08-02 09:36:31 +0000 (Sat, 02 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] fixed case where cancel is negative, added comments and improved
+code when initial n is known to be 0
+
+------------------------------------------------------------------------
+r5479 | vlefevre | 2008-08-01 21:18:06 +0000 (Fri, 01 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/exp_2.c
+
+exp_2.c: MPFR_EXP -> MPFR_GET_EXP.
+------------------------------------------------------------------------
+r5478 | zimmerma | 2008-08-01 16:45:45 +0000 (Fri, 01 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+[exp_2.c] fixed bug20080731
+
+------------------------------------------------------------------------
+r5477 | vlefevre | 2008-07-31 16:30:31 +0000 (Thu, 31 Jul 2008) | 1 line
+Changed paths:
+ M /trunk
+
+Added algorithms.out to svn:ignore property.
+------------------------------------------------------------------------
+r5476 | vlefevre | 2008-07-31 16:27:42 +0000 (Thu, 31 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: added testcase for new bug found in mpfr_exp_2.
+------------------------------------------------------------------------
+r5475 | vlefevre | 2008-07-31 16:02:54 +0000 (Thu, 31 Jul 2008) | 3 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/exp_2.c
+
+exp.c, exp_2.c: fixed the overflow/underflow detection. The underflow_up
+test in texp.c still fails for mpfr_exp_2 only, but this seems to be due
+to a bug in this function (incorrect error bound?).
+------------------------------------------------------------------------
+r5474 | vlefevre | 2008-07-31 15:03:49 +0000 (Thu, 31 Jul 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: added underflow tests to underflow_up; currently fail due
+to incorrect underflow detection in mpfr_exp (and if this detection is
+disabled, mpfr_exp_3 behaves correctly, but not mpfr_exp_2).
+------------------------------------------------------------------------
+r5473 | thevenyp | 2008-07-31 14:08:09 +0000 (Thu, 31 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+Fix typos, improve wording.
+
+------------------------------------------------------------------------
+r5472 | vlefevre | 2008-07-31 13:01:16 +0000 (Thu, 31 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/exp_2.c
+
+Added logging support to mpfr_exp_2 (exp_2.c).
+------------------------------------------------------------------------
+r5471 | vlefevre | 2008-07-31 11:36:01 +0000 (Thu, 31 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: updated comment concerning the bug fixed in r5469.
+------------------------------------------------------------------------
+r5470 | vlefevre | 2008-07-31 10:24:28 +0000 (Thu, 31 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/exp.c
+
+exp.c: updated comment about the exp3.c routine.
+------------------------------------------------------------------------
+r5469 | vlefevre | 2008-07-31 10:22:48 +0000 (Thu, 31 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/exp3.c
+
+exp3.c: fixed internal underflow.
+------------------------------------------------------------------------
+r5468 | vlefevre | 2008-07-31 09:59:53 +0000 (Thu, 31 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/fma.c
+ M /trunk/fms.c
+
+fma.c, fms.c: added a comment about apparently incorrect scaling.
+------------------------------------------------------------------------
+r5466 | vlefevre | 2008-07-31 09:46:43 +0000 (Thu, 31 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+
+Added logging support to mpfr_sqr and mpfr_sqrt.
+------------------------------------------------------------------------
+r5465 | thevenyp | 2008-07-31 08:31:11 +0000 (Thu, 31 Jul 2008) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/hypot.c
+
+hypot.c: Fix comment.
+BUGS: Add known bug for mpfr_hypot.
+
+------------------------------------------------------------------------
+r5464 | thevenyp | 2008-07-30 15:13:42 +0000 (Wed, 30 Jul 2008) | 5 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/hypot.c
+ M /trunk/tests/thypot.c
+
+algorithms.tex: Prove the correctness of the algorithm used for mpfr_hypot
+when the difference of inputs' exponents is less then exp_max - 2.
+hypot.c: Change algorithm according to its description in algorithms.tex
+tests/thypot.c: Fix tests (some were present but didn't trigger any error).
+
+------------------------------------------------------------------------
+r5463 | vlefevre | 2008-07-30 14:01:45 +0000 (Wed, 30 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: completed a comment.
+------------------------------------------------------------------------
+r5462 | vlefevre | 2008-07-30 11:26:52 +0000 (Wed, 30 Jul 2008) | 6 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: updated underflow_up test of log(2^(emin - 1)) + eps:
+ * In the old test (- log(2) < eps < 0 in GMP_RNDN), do not test
+ the flags, as this may be incorrect on some platforms (though
+ unlikely). Better tests will be provided later.
+ * Added test for case eps > 0, which triggers a bug in mpfr_exp_3
+ (underflow flag sometimes set while it shouldn't be set).
+------------------------------------------------------------------------
+r5461 | vlefevre | 2008-07-30 08:33:51 +0000 (Wed, 30 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+exp.c: completed a comment, describing how rigorous underflow/overflow
+detection can be done.
+------------------------------------------------------------------------
+r5460 | vlefevre | 2008-07-30 08:18:01 +0000 (Wed, 30 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+exp.c: removed an incorrect comment (corresponds to exp_2.c and already
+in exp_2.c).
+------------------------------------------------------------------------
+r5459 | vlefevre | 2008-07-29 14:34:10 +0000 (Tue, 29 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/exp.c
+
+exp.c: underflow/overflow detection is still a bit incorrect.
+------------------------------------------------------------------------
+r5458 | vlefevre | 2008-07-29 14:17:18 +0000 (Tue, 29 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/TODO
+
+TODO: added "test underflow/overflow detection...".
+------------------------------------------------------------------------
+r5457 | vlefevre | 2008-07-29 14:13:11 +0000 (Tue, 29 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/exp.c
+
+exp.c: fixed underflow/overflow detection.
+------------------------------------------------------------------------
+r5456 | vlefevre | 2008-07-29 13:24:19 +0000 (Tue, 29 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/exp_2.c
+
+exp_2.c: GNU style.
+------------------------------------------------------------------------
+r5455 | vlefevre | 2008-07-29 12:23:04 +0000 (Tue, 29 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: make sure that mpfr_get_exp_t and mpfr_set_exp_t are
+correctly defined.
+------------------------------------------------------------------------
+r5454 | vlefevre | 2008-07-26 10:46:26 +0000 (Sat, 26 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: updated comment of underflow_up.
+------------------------------------------------------------------------
+r5453 | vlefevre | 2008-07-26 10:44:22 +0000 (Sat, 26 Jul 2008) | 3 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+exp_2.c: solved the assertion failure by detecting a zero due to a
+cancellation and increasing the precision via Ziv's loop in such a
+case.
+------------------------------------------------------------------------
+r5452 | vlefevre | 2008-07-26 10:29:57 +0000 (Sat, 26 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+exp_2.c: added another assertion, that is checked independently of
+the value of MPFR_EXP_2_THRESHOLD (better for debugging).
+------------------------------------------------------------------------
+r5451 | vlefevre | 2008-07-26 10:21:09 +0000 (Sat, 26 Jul 2008) | 3 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+exp_2.c: added an assertion (more explicit than a similar assertion
+that would fail later) in mpfr_exp2_aux, caught by the underflow_up
+test in texp.c for prec = 16 on a 64-bit Linux machine.
+------------------------------------------------------------------------
+r5450 | vlefevre | 2008-07-25 21:02:13 +0000 (Fri, 25 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+tests/texp.c: added a test that shows incorrect underflow detection
+in mpfr_exp, with possible assertion failure.
+------------------------------------------------------------------------
+r5445 | vlefevre | 2008-07-25 11:52:07 +0000 (Fri, 25 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: added test of mpfr_exp2 and mpfr_exp10.
+------------------------------------------------------------------------
+r5443 | vlefevre | 2008-07-25 10:31:19 +0000 (Fri, 25 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/TODO
+
+TODO: update.
+------------------------------------------------------------------------
+r5442 | vlefevre | 2008-07-25 10:28:41 +0000 (Fri, 25 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/TODO
+
+TODO: added "option to use a 32-bit exponent type on LP64 machines".
+------------------------------------------------------------------------
+r5441 | vlefevre | 2008-07-23 13:52:09 +0000 (Wed, 23 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: updated AC_PREREQ line due to the use of AC_PROG_SED.
+------------------------------------------------------------------------
+r5440 | zimmerma | 2008-07-23 13:29:50 +0000 (Wed, 23 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+added reminder
+
+------------------------------------------------------------------------
+r5439 | zimmerma | 2008-07-23 13:26:26 +0000 (Wed, 23 Jul 2008) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+
+patch from Patrick to get __GMP_CC and __GMP_CFLAGS from gmp.h
+(future undocumented feature for GMP 4.2.3) -> we need to check
+those are the names chosen by GMP 4.2.3 when it will be out
+
+------------------------------------------------------------------------
+r5434 | vlefevre | 2008-07-21 23:03:36 +0000 (Mon, 21 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: fixed incorrect rounding in the general case when the result
+is negative and rnd = GMP_RNDD or GMP_RNDU (bug20080721 in tpow.c).
+------------------------------------------------------------------------
+r5433 | vlefevre | 2008-07-21 22:44:32 +0000 (Mon, 21 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: completed test bug20080721.
+------------------------------------------------------------------------
+r5432 | vlefevre | 2008-07-21 22:01:11 +0000 (Mon, 21 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: fixed the non-trivial cases with large integer y.
+------------------------------------------------------------------------
+r5431 | vlefevre | 2008-07-21 17:17:51 +0000 (Mon, 21 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: added comment for bug20080721.
+------------------------------------------------------------------------
+r5430 | vlefevre | 2008-07-21 16:54:18 +0000 (Mon, 21 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: found another bug in mpfr_pow with large integers.
+------------------------------------------------------------------------
+r5429 | vlefevre | 2008-07-21 13:06:51 +0000 (Mon, 21 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: added a test that detects a bug in an underflow case.
+------------------------------------------------------------------------
+r5428 | vlefevre | 2008-07-21 09:48:22 +0000 (Mon, 21 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow_all.c
+
+tests/tpow_all.c: made the comparisons between the power functions
+generic to be able to add other tests.
+------------------------------------------------------------------------
+r5427 | vlefevre | 2008-07-20 23:34:50 +0000 (Sun, 20 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: use MPFR_IS_POS(x) instead of MPFR_SIGN(x) > 0.
+------------------------------------------------------------------------
+r5425 | vlefevre | 2008-07-20 00:36:23 +0000 (Sun, 20 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/pow_si.c
+
+pow_si.c: corrected a comment.
+------------------------------------------------------------------------
+r5424 | vlefevre | 2008-07-20 00:22:50 +0000 (Sun, 20 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tpow_z.c
+
+tests/tpow_z.c: fixed NaN^0 test.
+------------------------------------------------------------------------
+r5423 | vlefevre | 2008-07-20 00:17:02 +0000 (Sun, 20 Jul 2008) | 4 lines
+Changed paths:
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/tests
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tpow_all.c
+
+Fixed a bug in pow_ui.c and pow_z.c: NaN^0 returned NaN instead of 1
+(see documentation). Affected functions: mpfr_pow_ui, mpfr_pow_si and
+mpfr_pow_z (but not mpfr_pow). Added new test file tests/tpow_all.c
+to test all the MPFR power functions on simple and special values.
+------------------------------------------------------------------------
+r5418 | vlefevre | 2008-07-19 16:09:13 +0000 (Sat, 19 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: forgot the case x^(±0).
+------------------------------------------------------------------------
+r5417 | vlefevre | 2008-07-19 15:36:57 +0000 (Sat, 19 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: updated comments.
+------------------------------------------------------------------------
+r5416 | vlefevre | 2008-07-19 15:21:30 +0000 (Sat, 19 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow_z.c
+
+tests/tpow_z.c: test bug20080223() didn't check that the result wasn't
+a NaN. Fixed.
+------------------------------------------------------------------------
+r5413 | vlefevre | 2008-07-19 13:52:27 +0000 (Sat, 19 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tests/tsprintf.c: removed trailing whitespace.
+------------------------------------------------------------------------
+r5412 | vlefevre | 2008-07-11 01:52:47 +0000 (Fri, 11 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: potential problem with integer division and pre-C99 compilers,
+noted by Philippe.
+------------------------------------------------------------------------
+r5411 | thevenyp | 2008-07-08 12:44:59 +0000 (Tue, 08 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/generic.c
+ M /trunk/vasprintf.c
+
+Fix typos
+------------------------------------------------------------------------
+r5410 | thevenyp | 2008-06-30 12:31:54 +0000 (Mon, 30 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+Fix typo (gmp macro TMP_ALLOC instead of MPFR_TMP_ALLOC).
+
+------------------------------------------------------------------------
+r5409 | vlefevre | 2008-06-27 09:26:43 +0000 (Fri, 27 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: fixed comment from r5408.
+------------------------------------------------------------------------
+r5408 | thevenyp | 2008-06-27 08:36:34 +0000 (Fri, 27 Jun 2008) | 6 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+acinclude.m4: add a check defining va_copy macro when needed.
+vasprintf.c: use TMP_ALLOC instead of variable-length array (C99).
+tests/tfprintf.c tests/tsprintf.c: #define length of array instead of const int so as to avoid variable-length array (C99).
+tests/tprintf.c: #define length of array instead of const int so as to avoid variable-length array (C99).
+ remove use of function dup (dependency with <unistd.h>).
+
+------------------------------------------------------------------------
+r5407 | vlefevre | 2008-06-25 09:08:26 +0000 (Wed, 25 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated "To make a release" (mention various compilers).
+------------------------------------------------------------------------
+r5406 | vlefevre | 2008-06-23 02:27:02 +0000 (Mon, 23 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: added comments about icc.
+------------------------------------------------------------------------
+r5405 | vlefevre | 2008-06-22 12:16:43 +0000 (Sun, 22 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: added "replace the *_THRESHOLD macros by global (TLS) variables
+that can be changed at run time [...]".
+------------------------------------------------------------------------
+r5400 | vlefevre | 2008-06-16 22:06:11 +0000 (Mon, 16 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: updated GMP's URL (the old one no longer worked), using
+http://www.gnu.org/software/gmp/ as suggested by Karl Berry (see
+GNU policies).
+
+------------------------------------------------------------------------
+r5398 | vlefevre | 2008-06-13 13:54:37 +0000 (Fri, 13 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: changed the license for the inclusion of the manual in Debian
+(see <http://www.debian.org/vote/2006/vote_001>).
+
+------------------------------------------------------------------------
+r5396 | vlefevre | 2008-06-11 13:09:33 +0000 (Wed, 11 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+AUTHORS: converted from ISO-8859-1 to UTF-8 (this is the standard
+nowadays and this is the encoding declared on InriaGforge).
+
+------------------------------------------------------------------------
+r5395 | thevenyp | 2008-06-11 10:06:56 +0000 (Wed, 11 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix typo in mpfr_printf documentation.
+
+------------------------------------------------------------------------
+r5394 | vlefevre | 2008-06-11 09:25:01 +0000 (Wed, 11 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: removed a misleading and now useless comment.
+
+------------------------------------------------------------------------
+r5393 | vlefevre | 2008-06-11 09:21:26 +0000 (Wed, 11 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: improved a comment.
+
+------------------------------------------------------------------------
+r5392 | vlefevre | 2008-06-11 09:20:53 +0000 (Wed, 11 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+tsprintf.c: typo in a comment.
+
+------------------------------------------------------------------------
+r5391 | thevenyp | 2008-06-11 08:57:47 +0000 (Wed, 11 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+Fix comparison between mpfr string and libc string.
+
+------------------------------------------------------------------------
+r5390 | zimmerma | 2008-06-10 21:12:32 +0000 (Tue, 10 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+added test for bug(?) found by Vincent with icc
+
+------------------------------------------------------------------------
+r5389 | thevenyp | 2008-06-10 14:18:37 +0000 (Tue, 10 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+Change #include <stdio.h> to #include <cstdio> when compiled with a C++ compiler.
+Assume that mpfr_rnd_t and wchar_t arguments in a variadic functions are converted to 'int' by C++ compilers.
+
+------------------------------------------------------------------------
+r5387 | vlefevre | 2008-06-10 14:13:59 +0000 (Tue, 10 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: generate an error (with a clear error message) with g++ and
+--enable-logging since compilation fails (--enable-logging is mainly for
+testing and is already incompatible with threading support anyway).
+
+------------------------------------------------------------------------
+r5386 | zimmerma | 2008-06-10 08:47:11 +0000 (Tue, 10 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+ M /trunk/exp_2.c
+
+the O(l^{1/2}) method to evaluate power series is due to
+Paterson and Stockmeyer and not Brent/Kung
+
+------------------------------------------------------------------------
+r5385 | vlefevre | 2008-06-09 16:21:34 +0000 (Mon, 09 Jun 2008) | 9 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/acinclude.m4
+ M /trunk/get_str.c
+ M /trunk/mpfr-gmp.c
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/vasprintf.c
+
+Clean-up and various changes to be able to build MPFR with g++.
+But the following 3 tests currently fail with g++ 4.3.1:
+ FAIL: tprintf
+ FAIL: tsprintf
+ FAIL: tfprintf
+This is an "Illegal instruction" error, so probably a bug in g++.
+[Edit: acinclude.m4 now uses gl_SIZE_MAX, typically from size_max.m4,
+but which is not installed on all machines; this will be added to the
+MPFR repository in changesets 5680 and 5683.]
+------------------------------------------------------------------------
+r5384 | vlefevre | 2008-06-09 14:09:34 +0000 (Mon, 09 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: do not use pointer arithmetic on void *.
+
+------------------------------------------------------------------------
+r5383 | vlefevre | 2008-06-09 13:55:05 +0000 (Mon, 09 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: added -Wpointer-arith to gcc options (this warning
+is useful as pointer arithmetic on void * is a gcc extension and
+doesn't work with g++).
+
+------------------------------------------------------------------------
+r5382 | vlefevre | 2008-06-09 12:26:26 +0000 (Mon, 09 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: mentioned a libtool bug with recent versions of icc.
+
+------------------------------------------------------------------------
+r5381 | vlefevre | 2008-06-09 08:47:58 +0000 (Mon, 09 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/sum.c
+
+sum.c:
+ * Completed a comment about T ** and const T ** mismatch.
+ * Removed a useless and misleading const that makes icc complain.
+
+------------------------------------------------------------------------
+r5380 | zimmerma | 2008-06-08 12:14:11 +0000 (Sun, 08 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/log.c
+
+fixed typos
+
+------------------------------------------------------------------------
+r5379 | zimmerma | 2008-06-07 21:45:24 +0000 (Sat, 07 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+use DeclareMathOperator for erf and erfc
+
+------------------------------------------------------------------------
+r5378 | zimmerma | 2008-06-07 11:34:59 +0000 (Sat, 07 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/atan.c
+
+fixed typo, added argument reduction for atan (we should try it since I believe
+atan is slow wrt exp, log, sin, cos for large precisions)
+
+------------------------------------------------------------------------
+r5377 | zimmerma | 2008-06-07 11:21:14 +0000 (Sat, 07 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/log1p.c
+
+simplified error analysis of log1p (did not match the code), and improved the
+code (in particular when 1+x is exact, directly call mpfr_log and avoid Ziv).
+
+------------------------------------------------------------------------
+r5376 | vlefevre | 2008-06-06 12:01:17 +0000 (Fri, 06 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/rec_sqrt.c
+
+rec_sqrt.c: removed execution bit.
+
+------------------------------------------------------------------------
+r5375 | vlefevre | 2008-06-06 11:47:19 +0000 (Fri, 06 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: update about build problems and the FAQ.
+
+------------------------------------------------------------------------
+r5374 | vlefevre | 2008-06-06 02:10:19 +0000 (Fri, 06 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added a comment about why the cross reference to GNU Libtool
+doesn't work from MPFR's directory.
+
+------------------------------------------------------------------------
+r5373 | vlefevre | 2008-06-06 01:33:49 +0000 (Fri, 06 Jun 2008) | 5 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added Section 4.1 "Headers and Libraries" partly based on
+GMP's. Note: in the generated mpfr.info file, the cross reference to
+libtool does not work (though GMP's info manual has exactly the same
+one and it works there). I couldn't figure out why.
+
+------------------------------------------------------------------------
+r5372 | vlefevre | 2008-06-06 01:17:08 +0000 (Fri, 06 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: make cross reference in HTML similar to texinfo's default one
+in PDF.
+
+------------------------------------------------------------------------
+r5371 | vlefevre | 2008-06-04 11:57:28 +0000 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the month.
+
+------------------------------------------------------------------------
+r5370 | vlefevre | 2008-06-04 11:51:25 +0000 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: check the LGPL license version.
+
+------------------------------------------------------------------------
+r5369 | vlefevre | 2008-06-04 11:34:10 +0000 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated paragraph on the license in "Introduction to MPFR".
+
+------------------------------------------------------------------------
+r5368 | vlefevre | 2008-06-04 11:25:59 +0000 (Wed, 04 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated GFDL version from 1.1 to 1.2 to match fdl.texi
+(this should have been done in r4059).
+
+------------------------------------------------------------------------
+r5367 | vlefevre | 2008-06-04 11:24:37 +0000 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: check GFDL versions.
+
+------------------------------------------------------------------------
+r5366 | vlefevre | 2008-06-04 11:13:23 +0000 (Wed, 04 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/update-version
+
+mpfr.texi, update-version: in the MPFR manual, replaced two
+http://www.mpfr.org/ by the URL corresponding to the version,
+which can be updated by update-version.
+
+------------------------------------------------------------------------
+r5365 | vlefevre | 2008-06-04 10:30:48 +0000 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: completed paragraph on MPFR vs double-precision numbers.
+
+------------------------------------------------------------------------
+r5364 | vlefevre | 2008-06-04 10:22:02 +0000 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: replaced each @code{mpfr} by MPFR (for consistency).
+
+------------------------------------------------------------------------
+r5362 | vlefevre | 2008-06-03 09:06:48 +0000 (Tue, 03 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: fixed a comment.
+
+------------------------------------------------------------------------
+r5361 | vlefevre | 2008-05-23 13:44:59 +0000 (Fri, 23 May 2008) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+tests: added tprintf to svn:ignore property.
+
+------------------------------------------------------------------------
+r5360 | vlefevre | 2008-05-23 11:00:28 +0000 (Fri, 23 May 2008) | 3 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/lngamma.c
+ M /trunk/sub1sp.c
+
+Added documentation about "'var' may be used uninitialized in this
+function" warnings.
+
+------------------------------------------------------------------------
+r5359 | zimmerma | 2008-05-22 11:05:19 +0000 (Thu, 22 May 2008) | 3 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/sub1sp.c
+
+Added comments about int i = i trick to avoid warning about uninitialized
+variables. This has the advantage to generate no code, but works for gcc only.
+
+------------------------------------------------------------------------
+r5358 | zimmerma | 2008-05-21 08:23:21 +0000 (Wed, 21 May 2008) | 4 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+initialize bbcp and bbcp1 to -1 (should be invalid)
+added MPFR_ASSERTN to check they are not -1 before reads
+simplified a test: (rnd == RNDN) || (rnd != RNDZ) ==> rnd != RNDZ
+
+------------------------------------------------------------------------
+r5357 | zimmerma | 2008-05-21 07:01:17 +0000 (Wed, 21 May 2008) | 4 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/sub1sp.c
+
+got rid of false (?) compiler warnings for uninitialized values
+-> we might want to revert this change if we find a better solution and/or
+ if the problem is fixed in gcc
+
+------------------------------------------------------------------------
+r5356 | vlefevre | 2008-05-20 09:38:38 +0000 (Tue, 20 May 2008) | 4 lines
+Changed paths:
+ M /trunk/cache.c
+ M /trunk/hypot.c
+ M /trunk/mpfr-impl.h
+ M /trunk/round_near_x.c
+
+Reverted changeset r5355. Better patch to avoid the warnings
+"warning: label 'addoneulp_doit' defined but not used" in
+MPFR_RNDRAW_GEN by adding the dummy code in the macro itself.
+
+------------------------------------------------------------------------
+r5355 | vlefevre | 2008-05-20 09:31:17 +0000 (Tue, 20 May 2008) | 4 lines
+Changed paths:
+ M /trunk/cache.c
+ M /trunk/hypot.c
+ M /trunk/mpfr-impl.h
+ M /trunk/round_near_x.c
+
+Avoid warnings "warning: label 'addoneulp_doit' defined but not used"
+due to the use of MPFR_RNDRAW_GEN. Dummy source code is inserted, but
+this is safe, clean (optimized away) and IMHO not too obtrusive.
+
+------------------------------------------------------------------------
+r5353 | vlefevre | 2008-05-08 01:12:42 +0000 (Thu, 08 May 2008) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: locally add -I$srcdir to CPPFLAGS for the thread-safe test
+(fixes bug #5556).
+
+------------------------------------------------------------------------
+r5351 | vlefevre | 2008-04-10 08:13:11 +0000 (Thu, 10 Apr 2008) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: added a paragraph about -ffast-math / -fast compiler options.
+
+------------------------------------------------------------------------
+r5350 | vlefevre | 2008-04-07 09:13:52 +0000 (Mon, 07 Apr 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+
+tcmp.c: fixed some tests (if mpfr_cmp2 returns an incorrect result,
+the bug may be some non-reproducible behavior, so don't compute it
+a second time to say what the value was!) and clean-up.
+
+------------------------------------------------------------------------
+r5349 | zimmerma | 2008-04-07 08:54:32 +0000 (Mon, 07 Apr 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+
+fixed compiler warning
+
+------------------------------------------------------------------------
+r5348 | zimmerma | 2008-04-06 21:14:07 +0000 (Sun, 06 Apr 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/memory.c
+ M /trunk/tests/tcmp2.c
+
+some other changes suggested by Patrick Pelissier for 16-bit portability
+
+------------------------------------------------------------------------
+r5347 | zimmerma | 2008-04-06 20:03:47 +0000 (Sun, 06 Apr 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tui_sub.c
+
+a few patches suggested by Patrick Pelissier to ease porting to 16-bit
+architectures: removed useless #include <time.h>, changed 1024 to 1024L,
+int i to lng i
+
+------------------------------------------------------------------------
+r5346 | zimmerma | 2008-03-17 12:14:38 +0000 (Mon, 17 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item about frac_* functions
+
+------------------------------------------------------------------------
+r5345 | zimmerma | 2008-03-16 12:45:07 +0000 (Sun, 16 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/modf.c
+
+fixed typo
+
+------------------------------------------------------------------------
+r5344 | thevenyp | 2008-03-11 12:35:57 +0000 (Tue, 11 Mar 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tprintf.c
+
+tests/tfprintf.c: set output to stdout when invocked with one command-line
+ parameter.
+tests/tprintf.c: add IO errors processing.
+
+------------------------------------------------------------------------
+r5343 | thevenyp | 2008-03-10 16:33:41 +0000 (Mon, 10 Mar 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tprintf.c
+
+tests/tprintf.c: add tests for mpfr_printf and mpfr_vprintf.
+Makefile.am: add tprintf.c to check_PROGRAMS.
+
+------------------------------------------------------------------------
+r5342 | thevenyp | 2008-03-10 16:18:45 +0000 (Mon, 10 Mar 2008) | 6 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/tests/tfprintf.c
+ M /trunk/vasprintf.c
+
+TODO: remove newly added functions
+vasprintf.c: change type of some variables taking care of signed/unsigned
+ comparisons, improve conditional tests, improve buffer
+ allocation, improve comments.
+tests/tfprintf.c: remove silly code.
+
+------------------------------------------------------------------------
+r5341 | thevenyp | 2008-03-10 15:41:09 +0000 (Mon, 10 Mar 2008) | 5 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/tests/tfprintf.c
+ M /trunk/vasprintf.c
+
+acinclude.m4: add check for long long compiler support, define HAVE_LONG_LONG.
+vasprintf.c: raise an error when it encounter an unsupported format in format
+ string.
+tests/tfprintf.c: HAVE_SDTINT_H -> _MPFR_H_HAVE_INTMAX_T
+
+------------------------------------------------------------------------
+r5340 | thevenyp | 2008-03-10 14:14:12 +0000 (Mon, 10 Mar 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: fix rounding bit bug with %RNa.
+tests/tsprintf.c: add tests for %RNa (rounding bit bug, tie case, trailing
+zeros in fractional part.
+
+------------------------------------------------------------------------
+r5339 | thevenyp | 2008-03-10 13:56:46 +0000 (Mon, 10 Mar 2008) | 5 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: fix bug in macro CONSUME_VA_ARG with a mp_limb_t or mp_limb_t array argument
+vasprintf.c: clean code storing the number of character in a pointer and fix bug with a mp_limb_t or mp_limb_t array argument
+tests/tfprintf.c: add tests for %n with all kinds of type, get rid of machine dependent limits of type (use +1/-1 instead)
+
+
+------------------------------------------------------------------------
+r5338 | thevenyp | 2008-03-10 10:56:03 +0000 (Mon, 10 Mar 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: fix bug of forgotten decimal point with %#.0Rf
+tests/tsprintf.c: add test with %#Rf and an integer mpfr_t
+
+------------------------------------------------------------------------
+r5337 | thevenyp | 2008-03-10 10:06:48 +0000 (Mon, 10 Mar 2008) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/li2.c
+
+li2.c: improve error estimation in Ziv loop.
+algorithm.tex:improve proof of mpfr_li2 algorithm.
+
+------------------------------------------------------------------------
+r5336 | thevenyp | 2008-03-10 09:53:18 +0000 (Mon, 10 Mar 2008) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/hypot.c
+
+hypot.c: change shift amount for exponents so as to avoid overflow in Ziv loop.
+algorithm.tex: improve proof for mpfr_hypot algorithm (unfinished).
+
+------------------------------------------------------------------------
+r5335 | vlefevre | 2008-03-07 15:08:07 +0000 (Fri, 07 Mar 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tgeneric.c: avoid a warning with gcc 4.2+ about a test that is always
+true (the style of the code is now a bit better too).
+
+------------------------------------------------------------------------
+r5334 | thevenyp | 2008-02-29 14:29:15 +0000 (Fri, 29 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+add mpfr_hypot
+
+------------------------------------------------------------------------
+r5333 | thevenyp | 2008-02-29 12:30:07 +0000 (Fri, 29 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+fix wrong arguments (set in r5332)
+
+------------------------------------------------------------------------
+r5332 | thevenyp | 2008-02-29 12:16:26 +0000 (Fri, 29 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+add missing functions
+
+------------------------------------------------------------------------
+r5331 | thevenyp | 2008-02-29 10:23:46 +0000 (Fri, 29 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+cosmetic changes
+
+------------------------------------------------------------------------
+r5330 | thevenyp | 2008-02-28 16:11:33 +0000 (Thu, 28 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+
+add mixed format tests (with different types and different sizes)
+
+------------------------------------------------------------------------
+r5329 | thevenyp | 2008-02-28 16:05:50 +0000 (Thu, 28 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: fix "%%" bug
+tests/tsprintf.c: add a test setting "%%" bug off
+
+------------------------------------------------------------------------
+r5328 | thevenyp | 2008-02-28 15:17:52 +0000 (Thu, 28 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+cosmetic changes
+
+------------------------------------------------------------------------
+r5327 | thevenyp | 2008-02-28 15:16:09 +0000 (Thu, 28 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+use system number of bits in the significant of a double (instead of 53)
+
+------------------------------------------------------------------------
+r5326 | thevenyp | 2008-02-27 15:19:55 +0000 (Wed, 27 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/cosh.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+
+add handle for the case exp(x) overflows but sinh(x) is representable
+
+------------------------------------------------------------------------
+r5325 | thevenyp | 2008-02-27 13:42:35 +0000 (Wed, 27 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/add_d.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/div_d.c
+ M /trunk/mul_d.c
+ M /trunk/sub_d.c
+
+further code simplification
+
+------------------------------------------------------------------------
+r5324 | thevenyp | 2008-02-27 12:57:24 +0000 (Wed, 27 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mul_d.c
+
+code simplification (same as in r5323)
+
+------------------------------------------------------------------------
+r5323 | thevenyp | 2008-02-27 12:55:12 +0000 (Wed, 27 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/add_d.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/div_d.c
+ M /trunk/sub_d.c
+
+code simplification.
+
+------------------------------------------------------------------------
+r5322 | thevenyp | 2008-02-27 11:13:18 +0000 (Wed, 27 Feb 2008) | 4 lines
+Changed paths:
+ M /trunk/add_d.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/div_d.c
+ M /trunk/sub_d.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tsub_d.c
+
+add_d.c, div_d.c, sub_d.c, d_div.c, d_sub.c: restore flags in case of exception. This fixes the bug revealed by MPFR_SUSPICIOUS_OVERFLOW
+tests/tadd_d.c, tests/tsub_d.c, tests/tdiv_d.c, tests/tmul_d.c, tests/td_sub.c, tests/td_div.c, test/tmul_d.c: add checks for exception flags and ternary value
+
+
+------------------------------------------------------------------------
+r5321 | thevenyp | 2008-02-27 10:00:11 +0000 (Wed, 27 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/mul_d.c
+ M /trunk/tests/tmul_d.c
+
+mul_d.c: restore flags set by mpfr_mul. This fixes the bug revealed by MPFR_SUSPICIOUS_OVERFLOW
+test/tmul_d.c: add checks for exception flags
+
+------------------------------------------------------------------------
+r5320 | vlefevre | 2008-02-27 09:43:38 +0000 (Wed, 27 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated the section about new functions (added a paragraph
+on exception handling).
+
+------------------------------------------------------------------------
+r5319 | thevenyp | 2008-02-26 17:45:53 +0000 (Tue, 26 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+improve proof for euclidean distance algorithm (unfinished)
+
+------------------------------------------------------------------------
+r5318 | vlefevre | 2008-02-26 16:20:04 +0000 (Tue, 26 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: rewrote an ambiguous comment.
+
+------------------------------------------------------------------------
+r5317 | vlefevre | 2008-02-26 16:10:28 +0000 (Tue, 26 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: removed obsolete comments and updated a comment.
+
+------------------------------------------------------------------------
+r5316 | vlefevre | 2008-02-26 15:57:53 +0000 (Tue, 26 Feb 2008) | 4 lines
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: the same variable was used with two different meanings.
+Changed the type and the name of the one inside the Ziv loop
+(unsigned is theoretically more correct due to the bitwise OR).
+
+------------------------------------------------------------------------
+r5315 | zimmerma | 2008-02-24 18:17:18 +0000 (Sun, 24 Feb 2008) | 8 lines
+Changed paths:
+ M /trunk/pow_z.c
+ M /trunk/tests/tpow_z.c
+
+fixed bug reported by Carl Witty (on 32-bit computers):
+sage: RR(1.99999999)^RR(-(2^30))
+5.11264311088393e-323228495
+sage: RR(1.999999999)^RR(-(2^30))
+0.000000000000000
+sage: RR(2.0)^RR(-(2^30))
+2.38256490488795e-323228497
+
+------------------------------------------------------------------------
+r5314 | zimmerma | 2008-02-23 22:52:30 +0000 (Sat, 23 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow_z.c
+
+added bug reported by Carl Witty
+
+------------------------------------------------------------------------
+r5313 | thevenyp | 2008-02-22 16:04:09 +0000 (Fri, 22 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tli2.c
+
+remove commented code
+
+------------------------------------------------------------------------
+r5312 | thevenyp | 2008-02-22 15:59:35 +0000 (Fri, 22 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tli2.c
+
+add worst cases for RNDZ and RNDU with inexact flag checking
+
+------------------------------------------------------------------------
+r5311 | vlefevre | 2008-02-22 15:49:36 +0000 (Fri, 22 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+hypot.c: added a FIXME comment.
+
+------------------------------------------------------------------------
+r5310 | vlefevre | 2008-02-22 15:45:27 +0000 (Fri, 22 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: one can have a better upper bound on \sqrt{x^2+y^2}-|x|
+(added as a comment in case this can be useful).
+
+------------------------------------------------------------------------
+r5309 | vlefevre | 2008-02-22 15:17:19 +0000 (Fri, 22 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: use hyperref.
+
+------------------------------------------------------------------------
+r5308 | thevenyp | 2008-02-21 16:42:13 +0000 (Thu, 21 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+add more details in mpfr_hypot description
+
+------------------------------------------------------------------------
+r5307 | thevenyp | 2008-02-21 16:40:40 +0000 (Thu, 21 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+cosmetic change: display "EXP" in small capitals
+no more use of {\rm \EXP}, use macro \Exp everywhere
+
+------------------------------------------------------------------------
+r5306 | thevenyp | 2008-02-20 14:04:46 +0000 (Wed, 20 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tli2.c
+
+add worst case test
+
+------------------------------------------------------------------------
+r5305 | thevenyp | 2008-02-20 11:54:26 +0000 (Wed, 20 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+add test with locale da_DK
+
+------------------------------------------------------------------------
+r5304 | thevenyp | 2008-02-20 10:33:33 +0000 (Wed, 20 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfms.c
+
+actually trigger overflow on all architectures
+
+------------------------------------------------------------------------
+r5303 | zimmerma | 2008-02-20 08:36:44 +0000 (Wed, 20 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+added MPFR_SUSPICIOUS_OVERFLOW in nightly tests
+
+------------------------------------------------------------------------
+r5302 | vlefevre | 2008-02-20 03:08:46 +0000 (Wed, 20 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/hypot.c
+
+hypot.c: fixed overflow flag problem in RNDD/RNDZ modes (testcase was
+added in r5301, and another check in r5300).
+
+------------------------------------------------------------------------
+r5301 | vlefevre | 2008-02-20 02:51:30 +0000 (Wed, 20 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/thypot.c
+
+tests/thypot.c: added check_overflow test (currently fails in 32 bits).
+
+------------------------------------------------------------------------
+r5300 | vlefevre | 2008-02-20 02:38:05 +0000 (Wed, 20 Feb 2008) | 7 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tests/tgeneric.c: added a test that detects suspicious overflows and
+fails when the overflow flag is not set. This test is enabled only if
+the MPFR_SUSPICIOUS_OVERFLOW environment variable is set, and shows a
+bug in mpfr_hypot on 32-bit machines (i.e. when the current exponent
+range is the maximum exponent range, so that mpfr_check_range() has
+no effect).
+
+------------------------------------------------------------------------
+r5299 | thevenyp | 2008-02-19 15:54:49 +0000 (Tue, 19 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+restore flag overflow dropped by MPFR_SAVE_EXPO
+
+------------------------------------------------------------------------
+r5298 | thevenyp | 2008-02-18 17:30:02 +0000 (Mon, 18 Feb 2008) | 5 lines
+Changed paths:
+ M /trunk/tests/tests.c
+ M /trunk/tests/tsum.c
+
+use of (*__gmp_allocate_func)/(*__gmp_free_func) instead of
+mpfr_allocate_func/mpfr_free_func;
+the modification in r5281 doesn't work when mpfr is compiled with --gmp_build
+option.
+
+------------------------------------------------------------------------
+r5297 | vlefevre | 2008-02-18 16:37:03 +0000 (Mon, 18 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+hypot.c: it's better to scale by (Ex + Ey) / 2.
+
+------------------------------------------------------------------------
+r5296 | vlefevre | 2008-02-18 16:06:20 +0000 (Mon, 18 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: now, the ChangeLog file should be in UTF-8, like in other
+software (not much difference in practice).
+
+------------------------------------------------------------------------
+r5295 | thevenyp | 2008-02-18 15:58:36 +0000 (Mon, 18 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+improve code coverage
+
+------------------------------------------------------------------------
+r5294 | thevenyp | 2008-02-18 15:39:45 +0000 (Mon, 18 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+ M /trunk/tests/tsprintf.c
+
+code simplification
+
+------------------------------------------------------------------------
+r5293 | thevenyp | 2008-02-18 13:48:11 +0000 (Mon, 18 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+take trailing zeros into account when separating thousands
+
+------------------------------------------------------------------------
+r5292 | zimmerma | 2008-02-18 13:24:47 +0000 (Mon, 18 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+fixed problem when x and y are very small
+
+------------------------------------------------------------------------
+r5291 | thevenyp | 2008-02-18 12:37:31 +0000 (Mon, 18 Feb 2008) | 4 lines
+Changed paths:
+ M /trunk/hypot.c
+ M /trunk/tests/thypot.c
+
+hypot.c: set flags when returning
+tests/thypot.c: change custom random tests to tgeneric ones
+
+
+------------------------------------------------------------------------
+r5290 | vlefevre | 2008-02-15 17:38:31 +0000 (Fri, 15 Feb 2008) | 12 lines
+Changed paths:
+ M /trunk/add1sp.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/li2.c
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+ M /trunk/pow.c
+ M /trunk/sub1sp.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsprintf.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+
+For the terminating null pointer of the functions mpfr_inits,
+mpfr_inits2, mpfr_clears, always use the type mpfr_ptr (no longer
+void *). Updated the description of these functions in the manual
+(mpfr.texi). The reason is that the C standard does not guarantee
+that (void *) 0 has the same representation as a null pointer to
+a structure (and even the same size). In most C implementations,
+the representations are the same, but one never knows (dynamical
+checking is also always possible)...
+The change has been done with: perl -pi -e \
+ 's/(mpfr_(clear|init)s.*)\(void *\*\) *0\)/$1(mpfr_ptr) 0)/' **/*.c
+under zsh.
+
+------------------------------------------------------------------------
+r5289 | thevenyp | 2008-02-15 15:58:21 +0000 (Fri, 15 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+fix typo
+
+------------------------------------------------------------------------
+r5288 | thevenyp | 2008-02-15 15:30:06 +0000 (Fri, 15 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: fix buffer_sandwich (use for thousands separator)
+tests/tsprintf.c: add tests with "da_DK" locale
+
+------------------------------------------------------------------------
+r5287 | thevenyp | 2008-02-15 14:04:11 +0000 (Fri, 15 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tset.c
+
+add generic tests
+
+------------------------------------------------------------------------
+r5286 | thevenyp | 2008-02-15 12:49:53 +0000 (Fri, 15 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+cosmetic changes
+
+------------------------------------------------------------------------
+r5285 | thevenyp | 2008-02-15 09:10:03 +0000 (Fri, 15 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+fix incorrect function call
+
+------------------------------------------------------------------------
+r5284 | thevenyp | 2008-02-14 17:09:35 +0000 (Thu, 14 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/tests/tsprintf.c
+ M /trunk/vasprintf.c
+
+fix "%P" case, add test for it.
+
+------------------------------------------------------------------------
+r5283 | thevenyp | 2008-02-13 17:21:27 +0000 (Wed, 13 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+
+avoid style 'f' with large numbers
+
+------------------------------------------------------------------------
+r5282 | vlefevre | 2008-02-13 13:43:01 +0000 (Wed, 13 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+tests: updated svn:ignore property.
+
+------------------------------------------------------------------------
+r5281 | thevenyp | 2008-02-12 15:32:22 +0000 (Tue, 12 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+ M /trunk/tests/tsum.c
+
+use of mpfr_allocate_func/mpfr_free_func instead of malloc/free
+
+------------------------------------------------------------------------
+r5280 | thevenyp | 2008-02-12 14:46:22 +0000 (Tue, 12 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+remove unneeded free and mpfr_clear
+
+------------------------------------------------------------------------
+r5279 | thevenyp | 2008-02-12 14:40:34 +0000 (Tue, 12 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+add tests for mpfr_snprintf and mpfr_vsnprintf
+
+------------------------------------------------------------------------
+r5278 | vlefevre | 2008-02-12 14:21:21 +0000 (Tue, 12 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added a note about freeing the memory in the tests.
+
+------------------------------------------------------------------------
+r5277 | thevenyp | 2008-02-12 13:50:14 +0000 (Tue, 12 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tout_str.c
+
+move tests of mpfr_get_str function from tout_str.c to tget_str.c
+
+------------------------------------------------------------------------
+r5276 | thevenyp | 2008-02-12 13:46:16 +0000 (Tue, 12 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tsprintf.c
+
+initialize fmt[] size
+
+------------------------------------------------------------------------
+r5275 | thevenyp | 2008-02-12 13:30:39 +0000 (Tue, 12 Feb 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/tfprintf.c
+ M /trunk/tests/tsprintf.c
+
+tfprintf.c: fix comment.
+tsprintf.c: fix comment and get rid of libc rand().
+
+
+------------------------------------------------------------------------
+r5274 | thevenyp | 2008-02-12 12:52:35 +0000 (Tue, 12 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tfprintf.c
+ D /trunk/tests/tprintf.c
+ A /trunk/tests/tsprintf.c (from /trunk/tests/tprintf.c:5272)
+
+rename tprintf.c as tsprintf.c, because it does not deal with mpfr_printf.
+add tests for mpfr_fprintf functions
+
+------------------------------------------------------------------------
+r5273 | thevenyp | 2008-02-12 08:43:02 +0000 (Tue, 12 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/printf.c
+
+remove errno setting in snprintf, it is already done in vasprintf
+correct grammatical faults in comment
+
+------------------------------------------------------------------------
+r5272 | vlefevre | 2008-02-08 16:25:37 +0000 (Fri, 08 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: undo r5270.
+
+------------------------------------------------------------------------
+r5271 | vlefevre | 2008-02-08 16:23:31 +0000 (Fri, 08 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: fixed assertion failure introduced in r5265.
+
+------------------------------------------------------------------------
+r5270 | thevenyp | 2008-02-08 16:19:41 +0000 (Fri, 08 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+remove exponent checking
+
+------------------------------------------------------------------------
+r5269 | thevenyp | 2008-02-08 13:53:09 +0000 (Fri, 08 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+ M /trunk/set_uj.c
+
+mpfr-gmp.h: Cancel r5261 changes removing the overload due to added test.
+set_uj.c: Don't call memset when len is zero.
+
+------------------------------------------------------------------------
+r5268 | thevenyp | 2008-02-08 13:20:24 +0000 (Fri, 08 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+improve assertion.
+
+------------------------------------------------------------------------
+r5267 | thevenyp | 2008-02-08 09:59:57 +0000 (Fri, 08 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+add support of thousands separator option (' flag, defined in Single UNIX Specification v2)
+
+------------------------------------------------------------------------
+r5266 | thevenyp | 2008-02-08 09:41:25 +0000 (Fri, 08 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+better string buffer management
+
+------------------------------------------------------------------------
+r5265 | vlefevre | 2008-02-07 14:40:53 +0000 (Thu, 07 Feb 2008) | 9 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tgeneric.c
+
+In tests_default_random, allow emin and emax to be outside of the
+current exponent range, so that underflow/overflow checks can be
+done on 64-bit machines. If the resulting random number is outside
+of the current range, the exponent range is extended, and restored
+by the caller once the test has been done.
+In tests/tacosh.c, changed TEST_RANDOM_EMIN and TEST_RANDOM_EMAX
+to MPFR_EMAX_MAX for test_generic_huge, so that the intermediate
+overflow case in mpfr_acosh is tested on 64-bit machines.
+
+------------------------------------------------------------------------
+r5264 | thevenyp | 2008-02-07 14:17:36 +0000 (Thu, 07 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+fix comment.
+In fact, GNU libc4 accept '%F', libc5, glibc 2.0, and glibc 2.1 don't, and glibc 2.2 accept it with C99 semantics.
+
+------------------------------------------------------------------------
+r5263 | vlefevre | 2008-02-06 14:17:26 +0000 (Wed, 06 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: added a comment about the mpfr_rnd_t enum.
+
+------------------------------------------------------------------------
+r5262 | vlefevre | 2008-02-06 13:48:33 +0000 (Wed, 06 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: removed MPFR_CHECK* macros as they are not used.
+
+------------------------------------------------------------------------
+r5261 | thevenyp | 2008-02-05 17:08:25 +0000 (Tue, 05 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+MPN_ZERO (dst, n) doesn't call memset when n==0, it prevents warning when compiled with gcc -D_FORTIFY_SOURCE
+
+------------------------------------------------------------------------
+r5260 | zimmerma | 2008-02-04 16:39:56 +0000 (Mon, 04 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added suggestion from Keith Briggs
+
+------------------------------------------------------------------------
+r5259 | thevenyp | 2008-02-04 16:15:06 +0000 (Mon, 04 Feb 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: add code for %n specifier with any type
+tests/tprintf.c: add test for %n specifier
+
+------------------------------------------------------------------------
+r5258 | thevenyp | 2008-02-04 16:10:17 +0000 (Mon, 04 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+improve mention on format string restriction
+
+------------------------------------------------------------------------
+r5257 | thevenyp | 2008-02-04 15:28:16 +0000 (Mon, 04 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mention restriction on type field in the format string.
+
+------------------------------------------------------------------------
+r5256 | thevenyp | 2008-02-04 14:28:14 +0000 (Mon, 04 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+check possible overflows in exponent part, improve comments.
+
+------------------------------------------------------------------------
+r5255 | thevenyp | 2008-02-04 13:46:52 +0000 (Mon, 04 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+
+ensure null-terminated string for (v)snprintf.
+
+------------------------------------------------------------------------
+r5254 | thevenyp | 2008-02-01 16:07:40 +0000 (Fri, 01 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+improve mpfr_printf documentation
+
+------------------------------------------------------------------------
+r5253 | vlefevre | 2008-02-01 14:08:37 +0000 (Fri, 01 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: fixed perror argument in data_check.
+
+------------------------------------------------------------------------
+r5252 | thevenyp | 2008-02-01 14:02:52 +0000 (Fri, 01 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+improve error handling
+
+------------------------------------------------------------------------
+r5251 | thevenyp | 2008-02-01 12:05:07 +0000 (Fri, 01 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+check fscanf return value, manage error case
+
+------------------------------------------------------------------------
+r5249 | zimmerma | 2008-02-01 11:02:22 +0000 (Fri, 01 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added parentheses to avoid ambiguity (suggested by Keith Briggs)
+
+------------------------------------------------------------------------
+r5248 | thevenyp | 2008-02-01 09:48:38 +0000 (Fri, 01 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+
+add some "%s" format string to prevent format string attack
+
+------------------------------------------------------------------------
+r5247 | thevenyp | 2008-01-31 08:41:14 +0000 (Thu, 31 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+fix typo
+
+------------------------------------------------------------------------
+r5246 | thevenyp | 2008-01-30 13:19:36 +0000 (Wed, 30 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+homogeneous use of logical variable
+
+------------------------------------------------------------------------
+r5245 | vlefevre | 2008-01-30 12:48:51 +0000 (Wed, 30 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/rec_sqrt.c
+
+rec_sqrt.c: use MPFR_GET_EXP instead of MPFR_EXP, and avoid the
+bitwise AND on a signed integer.
+
+------------------------------------------------------------------------
+r5244 | vlefevre | 2008-01-30 12:39:02 +0000 (Wed, 30 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/rec_sqrt.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trec_sqrt.c
+
+Reformat.
+
+------------------------------------------------------------------------
+r5242 | vlefevre | 2008-01-30 12:29:13 +0000 (Wed, 30 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/mpfr.texi
+
+Document how to produce PDF and HTML versions of the manual.
+
+------------------------------------------------------------------------
+r5241 | thevenyp | 2008-01-30 10:06:38 +0000 (Wed, 30 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+change to values acceptable by 32-bits machines
+
+------------------------------------------------------------------------
+r5240 | thevenyp | 2008-01-30 09:34:21 +0000 (Wed, 30 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+fix wrong statement in MPFR_ASSERTD
+
+------------------------------------------------------------------------
+r5239 | zimmerma | 2008-01-30 08:19:41 +0000 (Wed, 30 Jan 2008) | 5 lines
+Changed paths:
+ M /trunk/nightly-test
+
+added compilation options suggested by Debian:
+http://alioth.debian.org/projects/hardening/
+http://lists.debian.org/debian-devel/2007/12/msg00090.html
+(except -Wl,zrelro which does not seem to work)
+
+------------------------------------------------------------------------
+r5238 | thevenyp | 2008-01-29 17:59:18 +0000 (Tue, 29 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+So as to avoid conversion error, get rid of mpfr_set_d/mpf_set_d except in random_double().
+Skip conversion error in random_double().
+
+------------------------------------------------------------------------
+r5237 | thevenyp | 2008-01-29 17:01:24 +0000 (Tue, 29 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+fix typo in comment
+
+------------------------------------------------------------------------
+r5236 | thevenyp | 2008-01-29 17:00:31 +0000 (Tue, 29 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+get rid of limitation on number of character by specifier
+
+------------------------------------------------------------------------
+r5235 | thevenyp | 2008-01-29 15:42:47 +0000 (Tue, 29 Jan 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: fix %Rg case
+tests/tprintf.c: add %Re, %Rf, and %Rg tests
+tests/tprintf.c: add random checking against libc
+
+------------------------------------------------------------------------
+r5231 | thevenyp | 2008-01-28 10:46:20 +0000 (Mon, 28 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+remove (undocumented) integer conversion support for mpfr_t
+
+------------------------------------------------------------------------
+r5230 | thevenyp | 2008-01-28 10:34:46 +0000 (Mon, 28 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+ M /trunk/vasprintf.c
+
+set errno to EOVERFLOW when printf-like functions should return value exceeding INT_MAX
+
+------------------------------------------------------------------------
+r5229 | thevenyp | 2008-01-28 10:19:09 +0000 (Mon, 28 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+change internal name of printf-like functions under preprocessor conditionals, add explanation in comment.
+
+------------------------------------------------------------------------
+r5228 | vlefevre | 2008-01-25 15:09:21 +0000 (Fri, 25 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: added a possible class of tests.
+
+------------------------------------------------------------------------
+r5225 | vlefevre | 2008-01-23 17:01:24 +0000 (Wed, 23 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: remove a blank line in an error message.
+
+------------------------------------------------------------------------
+r5224 | vlefevre | 2008-01-23 16:51:02 +0000 (Wed, 23 Jan 2008) | 4 lines
+Changed paths:
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/tests.c
+ M /trunk/tests/tversion.c
+
+Test that the MPFR library version matches the mpfr.h version in any
+test file (this should avoid some bug reports that don't mention the
+real problem).
+
+------------------------------------------------------------------------
+r5222 | vlefevre | 2008-01-23 16:24:59 +0000 (Wed, 23 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tversion.c
+
+tversion.c: improved an error message.
+
+------------------------------------------------------------------------
+r5219 | vlefevre | 2008-01-23 13:36:21 +0000 (Wed, 23 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: fixed configure test for TLS support.
+
+------------------------------------------------------------------------
+r5217 | vlefevre | 2008-01-23 12:29:30 +0000 (Wed, 23 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS file update (configure test for TLS support).
+
+------------------------------------------------------------------------
+r5213 | vlefevre | 2008-01-23 12:17:51 +0000 (Wed, 23 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/add_d.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/div_d.c
+ M /trunk/li2.c
+ M /trunk/mbench/generate.c
+ M /trunk/mbench/mpfr-gfx.c
+ M /trunk/mbench/mpfr-v4.c
+ M /trunk/mbench/mpfr-v6.c
+ M /trunk/modf.c
+ M /trunk/mul_d.c
+ M /trunk/printf.c
+ M /trunk/rec_sqrt.c
+ M /trunk/rem1.c
+ M /trunk/sinh_cosh.c
+ M /trunk/sub_d.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trec_sqrt.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/vasprintf.c
+
+Added svn:keywords and svn:eol-style properties on new .c files.
+
+------------------------------------------------------------------------
+r5212 | vlefevre | 2008-01-23 11:46:10 +0000 (Wed, 23 Jan 2008) | 9 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-impl.h
+ A /trunk/mpfr-thread.h
+
+Changes related to thread-local variables / TLS support.
+ * Moved the MPFR_THREAD_ATTR definition from mpfr-impl.h into a new
+ header file mpfr-thread.h, and updated Makefile.am accordingly.
+ * Removed the compiler check __MPFR_GNUC(3,3) || __MPFR_ICC(8,1,0)
+ as this test leaded to both false positives and false negatives
+ concerning TLS support. Assume that __thread should be used for
+ thread-local variables (except for the MS compiler).
+ * Added a configure test to acinclude.m4 (in MPFR_CONFIGS).
+
+------------------------------------------------------------------------
+r5211 | zimmerma | 2008-01-22 12:13:08 +0000 (Tue, 22 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+added item about timings for a new release
+
+------------------------------------------------------------------------
+r5210 | zimmerma | 2008-01-22 12:09:19 +0000 (Tue, 22 Jan 2008) | 3 lines
+Changed paths:
+ A /trunk/mbench
+ A /trunk/mbench/Makefile
+ A /trunk/mbench/README
+ A /trunk/mbench/generate.c
+ A /trunk/mbench/mfv5-arprec.cc
+ A /trunk/mbench/mfv5-cln.cc
+ A /trunk/mbench/mfv5-crlibm.cc
+ A /trunk/mbench/mfv5-libc.cc
+ A /trunk/mbench/mfv5-lidia.cc
+ A /trunk/mbench/mfv5-mpf.cc
+ A /trunk/mbench/mfv5-mpfr.cc
+ A /trunk/mbench/mfv5-ntl.cc
+ A /trunk/mbench/mfv5-pari.cc
+ A /trunk/mbench/mfv5-void.cc
+ A /trunk/mbench/mfv5.cc
+ A /trunk/mbench/mfv5.h
+ A /trunk/mbench/mpfr-gfx.c
+ A /trunk/mbench/mpfr-v4.c
+ A /trunk/mbench/mpfr-v6.c
+ A /trunk/mbench/timp.h
+
+mbench program written by Patrick Pelissier to measure clock cycles of MPFR
+(and other libraries) for small precision
+
+------------------------------------------------------------------------
+r5207 | vlefevre | 2008-01-22 09:51:00 +0000 (Tue, 22 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: noted the changes concerning mpfr_strtofr (changesets 5146, 5147,
+5148, 5149, 5167, 5172, 5173).
+
+------------------------------------------------------------------------
+r5205 | vlefevre | 2008-01-22 09:21:37 +0000 (Tue, 22 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+mpfr-gmp.h: small fix of a macro.
+
+------------------------------------------------------------------------
+r5204 | vlefevre | 2008-01-21 12:42:57 +0000 (Mon, 21 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+mpfr-gmp.h: for temporary allocations, use alloca() if size < 16384.
+
+------------------------------------------------------------------------
+r5203 | vlefevre | 2008-01-19 10:43:38 +0000 (Sat, 19 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: inverse square root -> reciprocal square root.
+
+------------------------------------------------------------------------
+r5202 | zimmerma | 2008-01-18 16:20:48 +0000 (Fri, 18 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added mpfr_rec_sqrt in mpfr.texi (forgot in last commit)
+
+------------------------------------------------------------------------
+r5201 | vlefevre | 2008-01-18 15:47:39 +0000 (Fri, 18 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: added mpfr_rec_sqrt for MPFR 2.4.*.
+
+------------------------------------------------------------------------
+r5200 | zimmerma | 2008-01-18 14:03:27 +0000 (Fri, 18 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed rec_sqrt (done)
+
+------------------------------------------------------------------------
+r5199 | thevenyp | 2008-01-17 17:46:53 +0000 (Thu, 17 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: merge code for "%Ra" and "%Rb"
+
+------------------------------------------------------------------------
+r5198 | thevenyp | 2008-01-16 12:54:47 +0000 (Wed, 16 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+cosmetic change: replace "enum _arg_type" by "enum arg_t"
+
+------------------------------------------------------------------------
+r5197 | thevenyp | 2008-01-16 10:58:11 +0000 (Wed, 16 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: fix %g case; merge %e, %f, %g code
+tests/tprintf.c: add tests for %Rg
+
+------------------------------------------------------------------------
+r5196 | thevenyp | 2008-01-16 10:50:42 +0000 (Wed, 16 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+add MPFR_SAVE_EXPO macros
+
+------------------------------------------------------------------------
+r5195 | thevenyp | 2008-01-16 10:44:18 +0000 (Wed, 16 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+cosmetic changes: only one leading underscore for an identifier with file scope
+
+------------------------------------------------------------------------
+r5194 | thevenyp | 2008-01-16 10:29:58 +0000 (Wed, 16 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+add needed va_list argument in READ_INT macro
+
+------------------------------------------------------------------------
+r5193 | vlefevre | 2008-01-16 09:30:15 +0000 (Wed, 16 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+tests: added trec_sqrt to svn:ignore property.
+
+------------------------------------------------------------------------
+r5191 | vlefevre | 2008-01-16 09:05:22 +0000 (Wed, 16 Jan 2008) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: when building MPFR with the GMP build directory,
+use TMP_ALLOC(s) instead of TMP_SALLOC(s), as we don't know
+whether allocations are small or big (see gmp-impl.h).
+
+------------------------------------------------------------------------
+r5190 | zimmerma | 2008-01-16 07:57:24 +0000 (Wed, 16 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/rec_sqrt.c
+
+moved from ASSERTD to ASSERTN an assertion which does not depend on MPFR
+
+------------------------------------------------------------------------
+r5189 | zimmerma | 2008-01-15 17:16:35 +0000 (Tue, 15 Jan 2008) | 2 lines
+Changed paths:
+ A /trunk/tests/trec_sqrt.c
+
+this file might be useful to test mpfr_rec_sqrt...
+
+------------------------------------------------------------------------
+r5188 | zimmerma | 2008-01-15 17:10:17 +0000 (Tue, 15 Jan 2008) | 5 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/algorithms.tex
+ M /trunk/mpfr.h
+ M /trunk/rec_sqrt.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tests.c
+
+rec_sqrt.c: complete rewrite, to allow to use directly the MPFR internal
+ representation as input (without shift), and to allow different
+ input and output precisions, without loss of efficiency
+other files: added new function mpfr_rec_sqrt
+
+------------------------------------------------------------------------
+r5187 | vlefevre | 2008-01-14 17:23:44 +0000 (Mon, 14 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/rec_sqrt.c
+
+rec_sqrt.c: deleted trailing whitespace.
+
+------------------------------------------------------------------------
+r5186 | vlefevre | 2008-01-14 17:22:35 +0000 (Mon, 14 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+
+mpfr-gmp.{c,h}: no longer use alloca() for the temporary allocations as
+this can make MPFR crash in some high precisions, due to limited stack.
+
+------------------------------------------------------------------------
+r5185 | thevenyp | 2008-01-14 10:41:19 +0000 (Mon, 14 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+add bug found by Paul Zimmermann
+
+------------------------------------------------------------------------
+r5184 | thevenyp | 2008-01-14 10:33:01 +0000 (Mon, 14 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: fix wrong computation of digit number with %Rf when 0 < op < 1
+tests/tprintf.c: simpler 10^-n case
+
+------------------------------------------------------------------------
+r5182 | vlefevre | 2008-01-14 08:34:00 +0000 (Mon, 14 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: typo.
+
+------------------------------------------------------------------------
+r5181 | vlefevre | 2008-01-11 21:54:06 +0000 (Fri, 11 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated month.
+
+------------------------------------------------------------------------
+r5180 | vlefevre | 2008-01-11 21:45:08 +0000 (Fri, 11 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added a warning concerning huge precisions.
+
+------------------------------------------------------------------------
+r5179 | thevenyp | 2008-01-10 17:18:23 +0000 (Thu, 10 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+fix %f case
+
+------------------------------------------------------------------------
+r5178 | thevenyp | 2008-01-10 17:06:11 +0000 (Thu, 10 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+cosmetic changes
+
+------------------------------------------------------------------------
+r5177 | zimmerma | 2008-01-08 07:36:23 +0000 (Tue, 08 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+small changes for acos/asin/atan/atan2 rounded outside their output range
+
+------------------------------------------------------------------------
+r5176 | zimmerma | 2008-01-07 21:11:03 +0000 (Mon, 07 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added note about output of acos/asin/atan/atan2 which might be outside the
+function domain
+
+------------------------------------------------------------------------
+r5175 | zimmerma | 2008-01-05 09:20:12 +0000 (Sat, 05 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/rec_sqrt.c
+
+new version with improved tables, use macros from mpfr-impl.h, removed tabs
+
+------------------------------------------------------------------------
+r5173 | vlefevre | 2008-01-04 21:57:08 +0000 (Fri, 04 Jan 2008) | 4 lines
+Changed paths:
+ M /trunk/strtofr.c
+ M /trunk/tests/tstrtofr.c
+
+Fixed return value of mpfr_strtofr in case of invalid data (it was -1,
+but it should be 0 since it is a ternary value and the result is 0,
+which is exact). Added test of the ternary value in this case.
+
+------------------------------------------------------------------------
+r5172 | vlefevre | 2008-01-04 21:33:19 +0000 (Fri, 04 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: better description of mpfr_strtofr.
+
+------------------------------------------------------------------------
+r5171 | vlefevre | 2008-01-04 13:11:46 +0000 (Fri, 04 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS update (new functions in the trunk).
+
+------------------------------------------------------------------------
+r5167 | vlefevre | 2008-01-04 12:07:14 +0000 (Fri, 04 Jan 2008) | 15 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/strtofr.c
+ M /trunk/tests/tstrtofr.c
+
+Changes related to mpfr_strtofr.
+ * strtofr.c: for mpfr_strtofr, data corresponding to NaN can now have
+ an optional sign (since the documentation said that parsing followed
+ the standard C strtod function and this change makes invalid data
+ now valid, so that there should be no compatibility problems).
+ * tests/tstrtofr.c: changed the test for -42P17 in base 16 (this was
+ eventually regarded as a documentation bug); added tests.
+ * mpfr.texi: almost completely rewrote the specification of the
+ mpfr_strtofr function. Changes:
+ - the binary exponent is now accepted even without the 0b or 0x
+ prefix;
+ - data corresponding to NaN can now have an optional sign (this was
+ a bit ambiguous);
+ - many other ambiguities avoided.
+
+------------------------------------------------------------------------
+r5166 | zimmerma | 2008-01-04 10:35:04 +0000 (Fri, 04 Jan 2008) | 5 lines
+Changed paths:
+ A /trunk/rec_sqrt.c
+
+the function mpfr_mpn_rec_sqrt() provides a faithful approximation of the
+inverse square root. Some improvements can still be made, but the interface
+should not change, thus we can start writing the mpfr_rec_sqrt function that
+calls it.
+
+------------------------------------------------------------------------
+r5164 | vlefevre | 2008-01-02 17:19:42 +0000 (Wed, 02 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update.
+
+------------------------------------------------------------------------
+r5161 | vlefevre | 2008-01-01 12:31:06 +0000 (Tue, 01 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+tgamma.c: completed test in r5159 with another one that was failing
+in the default exponent range.
+
+------------------------------------------------------------------------
+r5160 | vlefevre | 2008-01-01 12:07:21 +0000 (Tue, 01 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+ M /trunk/vasprintf.c
+
+delete trailing spaces.
+
+------------------------------------------------------------------------
+r5159 | zimmerma | 2008-01-01 09:44:28 +0000 (Tue, 01 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+fixed bug in case of underflow (wrong sign)
+
+------------------------------------------------------------------------
+r5157 | vlefevre | 2008-01-01 03:57:20 +0000 (Tue, 01 Jan 2008) | 4 lines
+Changed paths:
+ M /trunk/gen_inverse.h
+
+gen_inverse.h: fixed the bug reported by Kevin Rauch a few hours ago
+(and that was detected by the generic tests and by mpfrlint after the
+latest changes).
+
+------------------------------------------------------------------------
+r5154 | vlefevre | 2008-01-01 03:47:50 +0000 (Tue, 01 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/mpfrlint
+
+mpfrlint: incorrect use of mpfr_<flag>_p is also checked in .h files.
+
+------------------------------------------------------------------------
+r5151 | vlefevre | 2008-01-01 03:26:37 +0000 (Tue, 01 Jan 2008) | 4 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_d.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/d_div.c
+ M /trunk/d_sub.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_d.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_patches.sh
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/minmax.c
+ M /trunk/modf.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mparam_h.in
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_d.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/printf.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rem1.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/setsign.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/signbit.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_d.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/data/li2
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tfms.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tisqrt.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/vasprintf.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/yn.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Copyright notice update: added 2008 with
+ perl -pi -e 's/2007 Free Software/2007, 2008 Free Software/' **/*(^/)
+under zsh.
+
+------------------------------------------------------------------------
+r5150 | vlefevre | 2008-01-01 03:17:56 +0000 (Tue, 01 Jan 2008) | 5 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tgeneric.c: in the bug detection with flags set before the function
+call, the erange flag was set, so that no checks were performed on
+the return value. Fixed that by not setting the erange flag.
+-> Now, 7 tests fail!
+
+------------------------------------------------------------------------
+r5149 | vlefevre | 2007-12-31 02:32:11 +0000 (Mon, 31 Dec 2007) | 5 lines
+Changed paths:
+ M /trunk/tests/tstrtofr.c
+
+tstrtofr.c: added test of -42P17 with base = 0 and 16. This currently
+fails with base = 16 (-42P17 is parsed as -0x42P17 instead of -42 with
+the remaining characters "P17"), but we could alternatively regard the
+mpfr_strtofr specification (in mpfr.texi) as incorrect.
+
+------------------------------------------------------------------------
+r5148 | vlefevre | 2007-12-30 18:20:34 +0000 (Sun, 30 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: corrections in the specification of mpfr_strtofr (see FIXME).
+
+------------------------------------------------------------------------
+r5147 | vlefevre | 2007-12-30 17:48:06 +0000 (Sun, 30 Dec 2007) | 5 lines
+Changed paths:
+ M /trunk/strtofr.c
+ M /trunk/tests/tset_str.c
+
+strtofr.c: base arguments different from 0 and 2..36 have never been
+accepted. So, instead of returning the confusing -1 (it's a ternary
+value), let's add an assert for the moment. An alternative solution
+is to return 0 and set the erange flag.
+
+------------------------------------------------------------------------
+r5146 | vlefevre | 2007-12-30 17:17:36 +0000 (Sun, 30 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+strtofr.c: minor change (in the style); a comment was ambiguous.
+
+------------------------------------------------------------------------
+r5145 | vlefevre | 2007-12-29 22:02:14 +0000 (Sat, 29 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO update (tests: generic bad cases).
+
+------------------------------------------------------------------------
+r5144 | vlefevre | 2007-12-29 21:46:50 +0000 (Sat, 29 Dec 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsub_d.c
+
+Added #if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) conditionals to be
+able to test MPFR 2.3.* with the (more complete) tests from the trunk.
+
+------------------------------------------------------------------------
+r5143 | vlefevre | 2007-12-29 17:07:10 +0000 (Sat, 29 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated item 6 of "To make a release".
+
+------------------------------------------------------------------------
+r5138 | vlefevre | 2007-12-28 02:37:11 +0000 (Fri, 28 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated month.
+
+------------------------------------------------------------------------
+r5136 | vlefevre | 2007-12-27 16:12:57 +0000 (Thu, 27 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tsubnormal.c
+
+tests: check the exponent range, in particular at the end of each test.
+
+------------------------------------------------------------------------
+r5135 | vlefevre | 2007-12-27 16:00:56 +0000 (Thu, 27 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/texceptions.c
+
+texceptions.c: GNU coding style.
+
+------------------------------------------------------------------------
+r5134 | vlefevre | 2007-12-27 15:59:46 +0000 (Thu, 27 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/texceptions.c
+
+texceptions.c: restore the exponent range.
+
+------------------------------------------------------------------------
+r5132 | vlefevre | 2007-12-27 03:10:01 +0000 (Thu, 27 Dec 2007) | 3 lines
+Changed paths:
+ M /trunk/exp2.c
+
+exp2.c: removed incorrect comment (the overflow test was OK due to the
+mpfr_clear_flags above, but the new test is slightly better anyway).
+
+------------------------------------------------------------------------
+r5127 | zimmerma | 2007-12-21 15:31:55 +0000 (Fri, 21 Dec 2007) | 3 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+added tuning parameters for 32-bit Core 2
+(thanks to Patrick Pelissier and Emmanuel Thome)
+
+------------------------------------------------------------------------
+r5124 | vlefevre | 2007-12-20 08:53:50 +0000 (Thu, 20 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: enable testcase bug20071218.
+
+------------------------------------------------------------------------
+r5123 | vlefevre | 2007-12-19 18:15:03 +0000 (Wed, 19 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: possible incorrect results due to internal underflow.
+
+------------------------------------------------------------------------
+r5122 | vlefevre | 2007-12-19 18:00:59 +0000 (Wed, 19 Dec 2007) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: detect all underflow cases (some of them were leading to
+an infinite loop, see bug20071218 in tpow.c).
+
+------------------------------------------------------------------------
+r5121 | vlefevre | 2007-12-19 15:04:43 +0000 (Wed, 19 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: updated description of MPFR_CAN_ROUND.
+
+------------------------------------------------------------------------
+r5120 | vlefevre | 2007-12-19 14:49:34 +0000 (Wed, 19 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/round_p.c
+
+round_p.c: in comment, "round to zero" -> "round toward zero".
+
+------------------------------------------------------------------------
+r5119 | vlefevre | 2007-12-19 14:27:30 +0000 (Wed, 19 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: formatting.
+
+------------------------------------------------------------------------
+r5118 | vlefevre | 2007-12-19 14:25:10 +0000 (Wed, 19 Dec 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: added testcase for another bug found by Kevin P. Rauch.
+Execute tpow with an argument to enable it.
+
+------------------------------------------------------------------------
+r5117 | thevenyp | 2007-12-19 10:32:52 +0000 (Wed, 19 Dec 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: add sprnt_fp_e for "%e" processing
+tests/tprintf.c: change tests for decimal output (but need further tests)
+
+------------------------------------------------------------------------
+r5116 | thevenyp | 2007-12-19 09:26:37 +0000 (Wed, 19 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+add checks for zero
+
+------------------------------------------------------------------------
+r5115 | vlefevre | 2007-12-18 15:51:00 +0000 (Tue, 18 Dec 2007) | 11 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/atan2.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/gamma.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfrlint
+ M /trunk/pow.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/rint.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/yn.c
+
+Merged the feature-block branch to the trunk:
+* New MPFR_BLOCK* macros (see mpfr-impl.h) and mpfrlint check to test
+ exception flags in a more reliable way and detect possible problems
+ with mpfrlint.
+* Improved the generic tests (tests/tgeneric.c): for the second
+ function call, sometimes set all the flags since risk of failures
+ are known when some flags are already set.
+* Modified code to use these new MPFR_BLOCK* macros. This fixed bugs
+ related to exceptions (where flags are set before the call); in
+ particular, tcot and ty1 failed with the improved generic tests.
+
+------------------------------------------------------------------------
+r5113 | thevenyp | 2007-12-18 15:09:30 +0000 (Tue, 18 Dec 2007) | 4 lines
+Changed paths:
+ M /trunk/printf.c
+ M /trunk/vasprintf.c
+
+printf.c: each mpfr_printf-like function return -1 and set erange flag in error case
+vasprintf.c: change types in struct char_fp
+vasprintf.c: add many size checking
+
+------------------------------------------------------------------------
+r5112 | thevenyp | 2007-12-18 13:48:07 +0000 (Tue, 18 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+simplify code, improve comments
+
+------------------------------------------------------------------------
+r5110 | vlefevre | 2007-12-18 12:54:25 +0000 (Tue, 18 Dec 2007) | 6 lines
+Changed paths:
+ M /trunk/pow_z.c
+ M /trunk/tests/tpow_z.c
+
+Fixed bug in mpfr_pow_z: if x = y (same mpfr_t argument), the input
+argument is negative and not a power of two, z is positive and odd,
+an overflow or underflow occurs, and the temporary result res is
+positive, then the result gets a wrong sign (positive instead of
+negative). Testcase.
+
+------------------------------------------------------------------------
+r5108 | vlefevre | 2007-12-18 12:08:42 +0000 (Tue, 18 Dec 2007) | 5 lines
+Changed paths:
+ M /trunk/pow_ui.c
+ M /trunk/tests/tpow.c
+
+Fixed bug in mpfr_pow_ui (introduced in r3214): if x = y (same mpfr_t
+argument), the input argument is negative, n is odd, an overflow or
+underflow occurs, and the temporary result res is positive, then the
+result gets a wrong sign (positive instead of negative). Testcase.
+
+------------------------------------------------------------------------
+r5107 | vlefevre | 2007-12-18 11:24:53 +0000 (Tue, 18 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/pow_ui.c
+
+pow_ui.c: fixed an assertion.
+
+------------------------------------------------------------------------
+r5106 | vlefevre | 2007-12-18 10:27:28 +0000 (Tue, 18 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: update concerning overflow/underflow exceptions.
+
+------------------------------------------------------------------------
+r5105 | thevenyp | 2007-12-18 10:08:21 +0000 (Tue, 18 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+exponent continuity with one hexadecimal digit ouput
+
+------------------------------------------------------------------------
+r5104 | thevenyp | 2007-12-17 14:41:58 +0000 (Mon, 17 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+#define CASE_INT_MAX_ARG to nil when HAVE_STDINT_H is not defined
+
+------------------------------------------------------------------------
+r5103 | thevenyp | 2007-12-17 13:52:26 +0000 (Mon, 17 Dec 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: add sprnt_fp_b for "%b" processing
+tests/tprintf.c: add tests for binary output
+
+------------------------------------------------------------------------
+r5102 | thevenyp | 2007-12-17 13:49:11 +0000 (Mon, 17 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+fix count of characters in exponent part
+
+------------------------------------------------------------------------
+r5101 | thevenyp | 2007-12-17 13:46:24 +0000 (Mon, 17 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+simplify code, remove trailing spaces and improve comment
+
+------------------------------------------------------------------------
+r5100 | vlefevre | 2007-12-17 12:04:53 +0000 (Mon, 17 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: added note about the successive calls to strcat in vasprintf.c.
+
+------------------------------------------------------------------------
+r5099 | thevenyp | 2007-12-17 10:16:34 +0000 (Mon, 17 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+add tests for 1 hexa digit output
+
+------------------------------------------------------------------------
+r5093 | vlefevre | 2007-12-16 00:15:25 +0000 (Sun, 16 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: fixed indentation.
+
+------------------------------------------------------------------------
+r5092 | zimmerma | 2007-12-15 14:29:06 +0000 (Sat, 15 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/reldiff.c
+
+fixed typo
+
+------------------------------------------------------------------------
+r5091 | zimmerma | 2007-12-15 09:42:13 +0000 (Sat, 15 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+ M /trunk/tests/tasin.c
+
+fixed bug reported by Kevin Rauch
+
+------------------------------------------------------------------------
+r5090 | thevenyp | 2007-12-14 17:12:05 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+change display with just one hexadecimal digit
+
+------------------------------------------------------------------------
+r5089 | zimmerma | 2007-12-14 14:26:21 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+simplified MPFR_FAST_COMPUTE_IF_SMALL_INPUT part (in case of overlap)
+
+------------------------------------------------------------------------
+r5088 | thevenyp | 2007-12-14 14:08:28 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+fix wrong call
+
+------------------------------------------------------------------------
+r5087 | zimmerma | 2007-12-14 13:24:44 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/round_near_x.c
+
+added comments, got rid of compiler warnings
+
+------------------------------------------------------------------------
+r5086 | zimmerma | 2007-12-14 13:10:41 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/sinh_cosh.c
+
+added warning
+
+------------------------------------------------------------------------
+r5085 | vlefevre | 2007-12-14 12:36:25 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+sin_cos.c: improved changeset 5084; in particular, added a missing cast.
+
+------------------------------------------------------------------------
+r5084 | zimmerma | 2007-12-14 09:24:11 +0000 (Fri, 14 Dec 2007) | 4 lines
+Changed paths:
+ M /trunk/sin_cos.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tsin_cos.c
+
+sin_cos.c, tsin_cos.c: fixed bug occurring when arguments overlap and
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT fails
+reuse.c: improved output in case of error
+
+------------------------------------------------------------------------
+r5083 | thevenyp | 2007-12-14 09:20:36 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+improve one digit case, add comment
+
+------------------------------------------------------------------------
+r5082 | vlefevre | 2007-12-14 09:06:26 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: added a FIXME comment. Bug?
+
+------------------------------------------------------------------------
+r5081 | vlefevre | 2007-12-14 09:05:30 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/vasprintf.c
+
+Minor changes concerning num_to_text. The ending \0 isn't needed.
+
+------------------------------------------------------------------------
+r5080 | thevenyp | 2007-12-14 08:56:31 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsinh_cosh.c
+
+simplify error output code
+
+------------------------------------------------------------------------
+r5079 | thevenyp | 2007-12-14 08:45:48 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+add num_to_text array for hexadecimal digits
+
+------------------------------------------------------------------------
+r5078 | thevenyp | 2007-12-14 08:17:43 +0000 (Fri, 14 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tsinh_cosh.c
+
+output errors to stdout
+
+------------------------------------------------------------------------
+r5077 | thevenyp | 2007-12-13 17:20:42 +0000 (Thu, 13 Dec 2007) | 4 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+ M /trunk/vasprintf.c
+
+vasprintf.c: group hexadecimal output processing in a new sprnt_fp_a function.
+tests/tprintf.c: add tests for %a case
+tests/tprintf.c: factorize error message output
+
+------------------------------------------------------------------------
+r5076 | vlefevre | 2007-12-13 17:08:44 +0000 (Thu, 13 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/get_d64.c
+
+get_d64.c: fixed comment.
+
+------------------------------------------------------------------------
+r5075 | vlefevre | 2007-12-13 17:03:19 +0000 (Thu, 13 Dec 2007) | 3 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: added missing #include <string.h> (useful if MPFR is built
+with the GMP build directory, as mpfr-gmp.h isn't used in this case).
+
+------------------------------------------------------------------------
+r5074 | thevenyp | 2007-12-13 16:59:31 +0000 (Thu, 13 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix typos.
+
+------------------------------------------------------------------------
+r5073 | thevenyp | 2007-12-13 16:58:01 +0000 (Thu, 13 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+
+Add handle for null size case in mpfr_snprintf
+
+------------------------------------------------------------------------
+r5072 | thevenyp | 2007-12-13 16:53:24 +0000 (Thu, 13 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+Add some comments and assertions.
+
+------------------------------------------------------------------------
+r5071 | thevenyp | 2007-12-13 16:42:19 +0000 (Thu, 13 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+#define's for nan and inf strings
+
+------------------------------------------------------------------------
+r5070 | thevenyp | 2007-12-13 16:20:30 +0000 (Thu, 13 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+short documentation of printf-like functions.
+
+------------------------------------------------------------------------
+r5069 | vlefevre | 2007-12-12 23:02:12 +0000 (Wed, 12 Dec 2007) | 3 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added information about my tool "eet" to be able to see the
+warnings more easily.
+
+------------------------------------------------------------------------
+r5068 | vlefevre | 2007-12-12 14:46:26 +0000 (Wed, 12 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: updated comment concerning the case nbchar > INT_MAX.
+
+------------------------------------------------------------------------
+r5067 | zimmerma | 2007-11-30 17:26:38 +0000 (Fri, 30 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/jn.c
+
+changed default return value in mpfr_jn_k0
+
+------------------------------------------------------------------------
+r5066 | zimmerma | 2007-11-30 17:09:03 +0000 (Fri, 30 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/exp3.c
+ M /trunk/tests/texp.c
+
+fixed underflow problem in mpfr_exp_3
+
+------------------------------------------------------------------------
+r5065 | zimmerma | 2007-11-30 15:03:56 +0000 (Fri, 30 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/jn.c
+ M /trunk/tests/tset_str.c
+
+tests/tset_str.c: added command-line argument for output base
+jn.c: replaced double-precision LOG2 constant by binary string (more portable)
+
+------------------------------------------------------------------------
+r5064 | zimmerma | 2007-11-30 13:50:23 +0000 (Fri, 30 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+fixed underflow problem
+
+------------------------------------------------------------------------
+r5063 | zimmerma | 2007-11-30 12:05:02 +0000 (Fri, 30 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mparam_h.in
+
+experimental code to distinguish Core2 from AMD64
+
+------------------------------------------------------------------------
+r5062 | zimmerma | 2007-11-30 10:43:43 +0000 (Fri, 30 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/pow_ui.c
+
+removed manual change to __gmpfr_emin outside the allowed range
+
+------------------------------------------------------------------------
+r5061 | zimmerma | 2007-11-30 10:02:38 +0000 (Fri, 30 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+added suggestion from Patrick Pelissier
+
+------------------------------------------------------------------------
+r5059 | zimmerma | 2007-11-29 21:34:15 +0000 (Thu, 29 Nov 2007) | 5 lines
+Changed paths:
+ M /trunk/pow_z.c
+ M /trunk/tests/tpow.c
+
+Fixed another bug reported by Kevin Rauch (__gmpfr_emin was set smaller
+than the minimum allowed value, which produced an exponent wrap-around
+and a wrong result in mpfr_mul). Not sure if all problems are solved,
+nevertheless __gmpfr_emin is now in the allowed range.
+
+------------------------------------------------------------------------
+r5058 | vlefevre | 2007-11-29 18:03:50 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+Fixed indentation.
+
+------------------------------------------------------------------------
+r5057 | vlefevre | 2007-11-29 17:55:42 +0000 (Thu, 29 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: in test4rm, initialize rndnext with an invalid value (meaning
+that rndnext will really be initialized later), and added an assert to
+check that this value isn't propagated to rnd.
+
+------------------------------------------------------------------------
+r5056 | vlefevre | 2007-11-29 17:45:03 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: added a comment about rndnext in test4rm.
+
+------------------------------------------------------------------------
+r5055 | vlefevre | 2007-11-29 17:28:34 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: added an assertion.
+
+------------------------------------------------------------------------
+r5054 | zimmerma | 2007-11-29 17:00:34 +0000 (Thu, 29 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+ M /trunk/tests/tpow.c
+
+fixed bug reported by Kevin Rauch (wrong sign in case of underflow for
+large negative x and large odd negative y)
+
+------------------------------------------------------------------------
+r5053 | thevenyp | 2007-11-29 14:02:23 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+untabify and remove trailing spaces
+
+------------------------------------------------------------------------
+r5052 | thevenyp | 2007-11-29 12:54:29 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+fix padding error in sprnt_inf
+
+------------------------------------------------------------------------
+r5051 | thevenyp | 2007-11-29 12:50:50 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+factorization of special numbers output in sprnt_nan and sprnt_inf functions
+
+------------------------------------------------------------------------
+r5050 | thevenyp | 2007-11-29 12:43:47 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+fix comment about the size of format string buffer
+
+------------------------------------------------------------------------
+r5049 | thevenyp | 2007-11-29 12:32:02 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+replace memory management functions mpfr_default_* by __gmp_*_func
+
+------------------------------------------------------------------------
+r5048 | zimmerma | 2007-11-29 10:16:37 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+updated Core 2 thresholds (obtained with gmp-4.2.2 and Gaudry's patch)
+
+------------------------------------------------------------------------
+r5047 | vlefevre | 2007-11-29 09:21:01 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+Typo in comment.
+
+------------------------------------------------------------------------
+r5046 | thevenyp | 2007-11-29 08:36:49 +0000 (Thu, 29 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+
+fix typo pointed out in revision 5044
+
+------------------------------------------------------------------------
+r5045 | vlefevre | 2007-11-28 14:36:21 +0000 (Wed, 28 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+
+printf.c: more comments about snprintf.
+
+------------------------------------------------------------------------
+r5044 | vlefevre | 2007-11-28 14:00:33 +0000 (Wed, 28 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+
+printf.c: added a comment concerning a warning (a bug, IMHO).
+
+------------------------------------------------------------------------
+r5043 | vlefevre | 2007-11-28 13:35:22 +0000 (Wed, 28 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: added FIXME comment concerning the case nbchar > INT_MAX,
+with a reference to POSIX.
+
+------------------------------------------------------------------------
+r5042 | thevenyp | 2007-11-28 13:32:24 +0000 (Wed, 28 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+add explanations about buffer size
+
+------------------------------------------------------------------------
+r5041 | thevenyp | 2007-11-28 12:53:15 +0000 (Wed, 28 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/printf.c
+ M /trunk/vasprintf.c
+
+change __gmp_const into const
+
+------------------------------------------------------------------------
+r5040 | vlefevre | 2007-11-28 10:29:33 +0000 (Wed, 28 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: added an assert.
+
+------------------------------------------------------------------------
+r5039 | thevenyp | 2007-11-28 10:13:55 +0000 (Wed, 28 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+fix output with space flag
+
+------------------------------------------------------------------------
+r5038 | thevenyp | 2007-11-28 10:09:19 +0000 (Wed, 28 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+add MPFR_ASSERTD to prevent buffer overflow
+
+------------------------------------------------------------------------
+r5037 | thevenyp | 2007-11-28 10:00:42 +0000 (Wed, 28 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+replace use of ptrdiff_t by size_t where possible
+
+------------------------------------------------------------------------
+r5032 | thevenyp | 2007-11-27 15:13:44 +0000 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+factorisation of temp string alloc in buffer_pad function
+
+------------------------------------------------------------------------
+r5031 | thevenyp | 2007-11-27 14:47:30 +0000 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+cosmetic changes
+
+------------------------------------------------------------------------
+r5030 | thevenyp | 2007-11-27 14:05:29 +0000 (Tue, 27 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+compatibility of types between nbc fields and mp_exp_t
+fix wrong size of buffer string exp_fmt
+
+------------------------------------------------------------------------
+r5026 | vlefevre | 2007-11-27 12:55:31 +0000 (Tue, 27 Nov 2007) | 3 lines
+Changed paths:
+ A /trunk/mpfrlint
+
+Added initial mpfrlint sh script to check possible problems in
+the MPFR source.
+
+------------------------------------------------------------------------
+r5025 | thevenyp | 2007-11-27 09:53:31 +0000 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+change 'g'/'G' to 'e'/'E' or 'f'/'F' according to C99 rules
+
+------------------------------------------------------------------------
+r5024 | thevenyp | 2007-11-26 17:44:10 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+replace mpfr_default_(re)allocate by __gmp_(re)allocate for the returned string (freed by mpfr_free_str)
+
+------------------------------------------------------------------------
+r5023 | thevenyp | 2007-11-26 17:38:17 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tprintf.c: replace __gmp_const by const
+
+------------------------------------------------------------------------
+r5022 | vlefevre | 2007-11-26 15:27:56 +0000 (Mon, 26 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/printf.c
+
+printf.c: added FIXME comment: snprintf is new in C99. It must be
+checked with a configure test.
+
+------------------------------------------------------------------------
+r5021 | vlefevre | 2007-11-26 15:19:46 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+tests: updated svn:ignore property.
+
+------------------------------------------------------------------------
+r5020 | vlefevre | 2007-11-26 15:16:09 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: reformat.
+
+------------------------------------------------------------------------
+r5019 | vlefevre | 2007-11-26 15:14:23 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/out_str.c
+ M /trunk/strtofr.c
+
+MPFR_DECIMAL_POINT now needs to have type char (because of vasprintf.c).
+
+------------------------------------------------------------------------
+r5018 | vlefevre | 2007-11-26 15:11:53 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c: changeset 4996 was incorrect. Fixed.
+
+------------------------------------------------------------------------
+r5017 | vlefevre | 2007-11-26 14:42:46 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: Avoid variable names "l", "I" and "O".
+
+------------------------------------------------------------------------
+r5016 | vlefevre | 2007-11-26 14:09:52 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added a note about the locales.
+
+------------------------------------------------------------------------
+r5015 | thevenyp | 2007-11-26 13:55:28 +0000 (Mon, 26 Nov 2007) | 6 lines
+Changed paths:
+ M /trunk/printf.c
+ M /trunk/vasprintf.c
+
+printf.c: fix use of pointer of string
+vasprintf.c: add conditional compilation directives for wchar and wint_t
+vasprintf.c: add padding for special values
+vasprintf.c: fix output for value 1.0 and format "%Rf"
+vasprintf.c: replace __gmp_const by const
+
+------------------------------------------------------------------------
+r5014 | vlefevre | 2007-11-26 09:57:47 +0000 (Mon, 26 Nov 2007) | 9 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/vasprintf.c
+
+acinclude.m4: check wchar.h header (see below).
+vasprintf.c:
+ * No longer depend on toupper (which returns locale-dependent results)
+ to generate 'A'..'F' (see C standard).
+ * Removed #include <ctype.h> which was hiding a bug (see below).
+ * Added missing #include <wchar.h> if HAVE_WCHAR_H is defined. But
+ the compilation fails if <wchar.h> doesn't exist due to the use of
+ wchar_t and wint_t.
+
+------------------------------------------------------------------------
+r5013 | vlefevre | 2007-11-26 09:44:24 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: updated comments.
+
+------------------------------------------------------------------------
+r5012 | vlefevre | 2007-11-26 09:37:47 +0000 (Mon, 26 Nov 2007) | 5 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c:
+ * Removed #include <stdlib.h> now useless.
+ * Added FIXME comment.
+ * Replaced _MP_EXP_FORMAT_SPEC (reserved) by MPFR_EXP_FORMAT_SPEC.
+
+------------------------------------------------------------------------
+r5011 | vlefevre | 2007-11-26 09:32:20 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: added FIXME comments.
+
+------------------------------------------------------------------------
+r5010 | vlefevre | 2007-11-26 09:18:06 +0000 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: fixed a typo in a comment and improved another comment.
+
+------------------------------------------------------------------------
+r5009 | vlefevre | 2007-11-24 01:46:30 +0000 (Sat, 24 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: moved function declarations out of "#ifdef _MPFR_H_HAVE_VA_LIST"
+and/or "#ifdef _MPFR_H_HAVE_FILE" when this makes sense.
+
+------------------------------------------------------------------------
+r5008 | vlefevre | 2007-11-24 01:41:33 +0000 (Sat, 24 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c: added missing "void" in function declarations.
+
+------------------------------------------------------------------------
+r5007 | vlefevre | 2007-11-24 01:36:47 +0000 (Sat, 24 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tprintf.c
+ M /trunk/tests/tset_f.c
+ M /trunk/vasprintf.c
+
+Untabified and removed trailing spaces.
+
+------------------------------------------------------------------------
+r5006 | vlefevre | 2007-11-24 01:33:00 +0000 (Sat, 24 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/mpfr.texi
+
+mpfr.texi: corrections (English usage and texinfo). Added corresponding
+notes at the end of the README.dev file.
+
+------------------------------------------------------------------------
+r5005 | vlefevre | 2007-11-24 01:24:05 +0000 (Sat, 24 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: s/rounding to the nearest mode/rounding to nearest mode/
+
+------------------------------------------------------------------------
+r5004 | vlefevre | 2007-11-24 01:22:31 +0000 (Sat, 24 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi consistency changes: "towards" -> "toward" (because this
+is what the IEEE-754 standard uses, and we have mpfr_nexttoward).
+
+------------------------------------------------------------------------
+r5003 | vlefevre | 2007-11-24 01:17:08 +0000 (Sat, 24 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: English typography corrections (no space before ":").
+
+------------------------------------------------------------------------
+r5002 | vlefevre | 2007-11-24 01:15:22 +0000 (Sat, 24 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: the use of the abs function was incorrect as its argument
+has type int, which may be smaller than an mp_exp_t. Fixed that and
+replaced uceil_log10 by uceil_log10_exp_p2.
+
+------------------------------------------------------------------------
+r5001 | vlefevre | 2007-11-24 00:55:50 +0000 (Sat, 24 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+vasprintf.c: fixed uceil_log10 for x close to ULONG_MAX.
+
+------------------------------------------------------------------------
+r5000 | zimmerma | 2007-11-23 20:22:10 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/vasprintf.c
+
+got rid of math.h
+
+------------------------------------------------------------------------
+r4999 | vlefevre | 2007-11-23 19:20:38 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c: include <stdarg.h>.
+
+------------------------------------------------------------------------
+r4998 | vlefevre | 2007-11-23 19:19:04 +0000 (Fri, 23 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/printf.c
+ M /trunk/vasprintf.c
+
+stdarg-related corrections, as HAVE_STDARG is not standard thus must not
+be tested in mpfr.h!
+
+------------------------------------------------------------------------
+r4997 | vlefevre | 2007-11-23 19:07:54 +0000 (Fri, 23 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c: enable the tests only if HAVE_STDARG is defined,
+i.e. if the printf-like functions are defined.
+
+------------------------------------------------------------------------
+r4996 | vlefevre | 2007-11-23 19:02:46 +0000 (Fri, 23 Nov 2007) | 7 lines
+Changed paths:
+ M /trunk/tests/tprintf.c
+
+tests/tprintf.c:
+ * Non-standard headers should be included after the standard headers
+ (when possible).
+ * The setlocale function is used only if <locale.h> has been included.
+ * Use tests_start_mpfr / tests_end_mpfr; this shows a bug:
+ tests_free(): attempt to free bad pointer 0x1801200
+
+------------------------------------------------------------------------
+r4995 | vlefevre | 2007-11-23 18:54:37 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: setlocale is used only if <locale.h> has been included.
+
+------------------------------------------------------------------------
+r4994 | vlefevre | 2007-11-23 18:48:52 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/out_str.c
+
+out_str.c: remove other occurrence of <locale.h>.
+
+------------------------------------------------------------------------
+r4993 | thevenyp | 2007-11-23 17:35:46 +0000 (Fri, 23 Nov 2007) | 12 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/printf.c
+ M /trunk/strtofr.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tests.c
+ A /trunk/tests/tprintf.c
+ A /trunk/vasprintf.c
+
+Makefile.am: add mpfr_printf-like functions
+mpfr.h: add mpfr_printf-like functions
+printf.c: printf, sprintf, snprintf, asprintf and 'v' variants
+vasprintf.c: vasprintf functions used by its likes
+mpfr.texi: add description for printf family functions
+tests/Makefile.am: add test for printf
+tests/tprintf.c: tests for printf-like functions
+acinclude.m4: define HAVE_LOCALE_H
+mpfr-impl.h: define MPFR_DECIMAL_POINT even if no locale.h
+strtofr.c: remove locale.h inclusion (done by mpfr-impl.h )
+tests/tests.c: use HAVE_LOCALE_H
+
+------------------------------------------------------------------------
+r4991 | vlefevre | 2007-11-23 16:55:03 +0000 (Fri, 23 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/tests/tisqrt.c
+
+tests/tisqrt.c: test the 32-bit __gmpfr_cuberoot bound cases (9 per
+value) exhaustively (running tisqrt is still immediate on a recent
+machine).
+
+------------------------------------------------------------------------
+r4990 | vlefevre | 2007-11-23 16:49:45 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tisqrt.c
+
+tests/tisqrt.c: test the 32-bit __gmpfr_isqrt bound cases exhaustively.
+
+------------------------------------------------------------------------
+r4989 | vlefevre | 2007-11-23 15:10:56 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: test the availability of <string.h>.
+
+------------------------------------------------------------------------
+r4988 | vlefevre | 2007-11-23 14:30:36 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: test the availability of <locale.h>.
+
+------------------------------------------------------------------------
+r4987 | vlefevre | 2007-11-23 14:26:39 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: updated comment concerning the checked functions.
+
+------------------------------------------------------------------------
+r4986 | vlefevre | 2007-11-23 14:24:50 +0000 (Fri, 23 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: added memmove to the checked functions (though this test
+is currently useless, except for the corresponding information).
+
+------------------------------------------------------------------------
+r4985 | vlefevre | 2007-11-23 14:19:40 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+acinclude.m4: updated a comment concerning the function checking.
+
+------------------------------------------------------------------------
+r4984 | vlefevre | 2007-11-23 13:46:04 +0000 (Fri, 23 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/gmp_op.c
+
+gmp_op.c: removed old "#include <stddef.h>" line (seems to be useless
+now, and note that <stdio.h> is included by default in mpfr-impl.h).
+
+------------------------------------------------------------------------
+r4982 | vlefevre | 2007-11-23 13:09:39 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tj0.c
+
+tests/tj0.c: fixed test.
+
+------------------------------------------------------------------------
+r4980 | vlefevre | 2007-11-23 12:58:53 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/jn.c
+
+jn.c: added integer overflow checking.
+
+------------------------------------------------------------------------
+r4978 | vlefevre | 2007-11-23 10:06:07 +0000 (Fri, 23 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/memory.c
+
+tests/memory.c: fixed copyright notice.
+
+------------------------------------------------------------------------
+r4969 | vlefevre | 2007-11-21 14:50:18 +0000 (Wed, 21 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+tests/tzeta.c: completed test of mpfr_zeta bug fixed in r4920 (the value
+of zeta(large negative) was also wrong in GMP_RNDU: -Inf instead of the
+largest negative MPFR number).
+
+------------------------------------------------------------------------
+r4957 | zimmerma | 2007-11-20 14:43:14 +0000 (Tue, 20 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tinp_str.c
+
+reverted back to rev. 4951 (otherwise we would have to free memory for all
+exit calls)
+
+------------------------------------------------------------------------
+r4956 | thevenyp | 2007-11-20 11:21:10 +0000 (Tue, 20 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_f.c
+
+use of RANDS instead of __gmp_rands
+tset_f.c add checking with random values
+
+------------------------------------------------------------------------
+r4955 | thevenyp | 2007-11-19 11:07:49 +0000 (Mon, 19 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/tests/tests.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_f.c
+
+tli2.c: fix wrong assertion in copyright motice
+test.c: fixed seed for reproducable errors
+trandom.c tpow_z.c tset_f.c: integration with GMP_CHECK_RANDOMIZE process
+
+------------------------------------------------------------------------
+r4954 | zimmerma | 2007-11-17 12:15:53 +0000 (Sat, 17 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tasin.c
+
+added missing call to tests_end_mpfr
+
+------------------------------------------------------------------------
+r4953 | zimmerma | 2007-11-17 09:59:19 +0000 (Sat, 17 Nov 2007) | 5 lines
+Changed paths:
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tli2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/tsub_ui.c
+
+got rid of mpfr_init_gmp_rand/MPFR_TEST_USE_RANDS and not-reentrant gmp
+random functions (mpn_random*, mpz_random*, mpf_random*). Now all tests use
+either RANDS (which is cleared by tests_rand_end called by tests_end_mpfr),
+or the gmp_randstate_t mechanism.
+
+------------------------------------------------------------------------
+r4952 | zimmerma | 2007-11-16 17:09:12 +0000 (Fri, 16 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tinp_str.c
+
+added missing mpfr_clear and tests_end_mpfr (thanks Michael Abshoff)
+
+------------------------------------------------------------------------
+r4951 | zimmerma | 2007-11-16 14:28:29 +0000 (Fri, 16 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+fixed problem reported by valgrind (thanks to Michael Abshoff)
+
+------------------------------------------------------------------------
+r4950 | zimmerma | 2007-11-06 22:07:31 +0000 (Tue, 06 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+ M /trunk/tests/tdiv_ui.c
+
+fixed bug in div_ui for x=0 and u<>0 (sign of result was not set)
+
+------------------------------------------------------------------------
+r4949 | thevenyp | 2007-11-06 10:53:43 +0000 (Tue, 06 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+algorithms.tex: fix bibtex references for dilogarithm function
+algorithms.bib: add references for dilogarithm function
+
+
+------------------------------------------------------------------------
+r4948 | vlefevre | 2007-11-05 11:18:46 +0000 (Mon, 05 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: removed trailing spaces.
+
+------------------------------------------------------------------------
+r4947 | zimmerma | 2007-11-05 10:53:21 +0000 (Mon, 05 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/pow.c
+
+added new macro MPFR_ALIAS
+
+------------------------------------------------------------------------
+r4946 | zimmerma | 2007-11-04 11:10:23 +0000 (Sun, 04 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/expm1.c
+
+removed unused label
+
+------------------------------------------------------------------------
+r4945 | vlefevre | 2007-11-04 00:46:45 +0000 (Sun, 04 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/pow_z.c
+
+pow_z.c: fixed bug that occurs when x is a power of 2 and the result
+overflows (wrong sign); this bug has always been present (from r3215).
+
+------------------------------------------------------------------------
+r4944 | vlefevre | 2007-11-04 00:44:04 +0000 (Sun, 04 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow_z.c
+
+tpow.c, tpow_z.c: removed a printf that was left by mistake.
+
+------------------------------------------------------------------------
+r4943 | vlefevre | 2007-11-04 00:36:23 +0000 (Sun, 04 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tpow_z.c
+
+tpow_z.c: added testcase for the latest mpfr_pow bug (rev 4942),
+which is in fact a bug in mpfr_pow_z.
+
+------------------------------------------------------------------------
+r4942 | vlefevre | 2007-11-04 00:28:20 +0000 (Sun, 04 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: added testcase for new bug found by Kevin P. Rauch; removed a
+mpfr_dump that was left by mistake.
+
+------------------------------------------------------------------------
+r4941 | vlefevre | 2007-11-03 09:28:23 +0000 (Sat, 03 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: removed FIXME comment.
+
+------------------------------------------------------------------------
+r4940 | zimmerma | 2007-11-03 08:45:17 +0000 (Sat, 03 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+fixed case x < 0, y large integer
+
+------------------------------------------------------------------------
+r4939 | vlefevre | 2007-11-03 02:05:04 +0000 (Sat, 03 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: added FIXME comment.
+
+------------------------------------------------------------------------
+r4938 | vlefevre | 2007-11-03 01:59:23 +0000 (Sat, 03 Nov 2007) | 5 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: added testcase for new bug found by Kevin P. Rauch. The problem
+occurs on x^y with x negative and y an integer whose exponent is > 256
+(so that mpfr_pow_z isn't used, and the generic code is used instead and
+fails because x is negative).
+
+------------------------------------------------------------------------
+r4937 | vlefevre | 2007-11-02 15:02:50 +0000 (Fri, 02 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+ M /trunk/tests/tpow.c
+
+Fixed several bugs in mpfr_pow (from rev 3592 and 4932); added testcase.
+
+------------------------------------------------------------------------
+r4936 | vlefevre | 2007-11-02 14:29:21 +0000 (Fri, 02 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: added an overflow test in reduced exponent range
+(-> assertion failure in the current pow.c code).
+
+------------------------------------------------------------------------
+r4935 | vlefevre | 2007-11-02 13:02:45 +0000 (Fri, 02 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: added a comment concerning __gmpfr_one, __gmpfr_two and
+__gmpfr_four.
+
+------------------------------------------------------------------------
+r4934 | vlefevre | 2007-11-02 12:54:14 +0000 (Fri, 02 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/cmp_abs.c
+
+Bug fix: in cmp_abs.c, changed MPFR_GET_EXP into MPFR_EXP to allow
+exponents outside the current exponent range (needed for mpfr_pow).
+
+------------------------------------------------------------------------
+r4933 | vlefevre | 2007-10-31 15:46:57 +0000 (Wed, 31 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/erfc.c
+ M /trunk/li2.c
+ M /trunk/lngamma.c
+ M /trunk/mpfr.texi
+ M /trunk/pow.c
+ M /trunk/rem1.c
+ M /trunk/tests/tfmod.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tzeta.c
+
+Untabified and removed trailing spaces.
+
+------------------------------------------------------------------------
+r4932 | zimmerma | 2007-10-30 16:29:46 +0000 (Tue, 30 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/pow.c
+ M /trunk/tests/tpow.c
+
+pow.c, tpow.c: fixed bugs reported by Kevin Rauch
+mpfr-impl.h: fixed typo
+
+------------------------------------------------------------------------
+r4931 | zimmerma | 2007-10-30 14:35:24 +0000 (Tue, 30 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+cosmetic changes
+
+------------------------------------------------------------------------
+r4930 | zimmerma | 2007-10-30 14:00:30 +0000 (Tue, 30 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added missing \Li2
+
+------------------------------------------------------------------------
+r4929 | zimmerma | 2007-10-28 15:18:03 +0000 (Sun, 28 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/li2.c
+ M /trunk/tests/data/li2
+ M /trunk/tests/tli2.c
+
+added more test cases for mpfr_li2
+improved MPFR_FAST_COMPUTE_IF_SMALL_INPUT case for x > 0
+
+------------------------------------------------------------------------
+r4928 | zimmerma | 2007-10-28 13:16:02 +0000 (Sun, 28 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/tests/tlgamma.c
+
+fixed bug mentioned by Kevin Rauch: mpfr_lgamma was hanging for tiny input
+(had to implement a complete loop in that case)
+
+------------------------------------------------------------------------
+r4927 | zimmerma | 2007-10-28 12:29:01 +0000 (Sun, 28 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/jn.c
+ M /trunk/jyn_asympt.c
+ M /trunk/tests/tj0.c
+
+fixed bug reported by Kevin Rauch: wrong sign for jn(n even, large negative x)
+
+------------------------------------------------------------------------
+r4926 | zimmerma | 2007-10-28 12:18:04 +0000 (Sun, 28 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/TODO
+
+removed item on mpfr_sinh_cosh (done)
+added more info on item on efficiency of mpfr_sin
+
+------------------------------------------------------------------------
+r4925 | zimmerma | 2007-10-28 11:53:51 +0000 (Sun, 28 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added comment about function/macro in custom interface
+
+------------------------------------------------------------------------
+r4924 | zimmerma | 2007-10-28 11:11:13 +0000 (Sun, 28 Oct 2007) | 4 lines
+Changed paths:
+ M /trunk/jn.c
+ M /trunk/tests/tjn.c
+
+jn.c: improved choice of initial precision in Taylor series (takes into
+ account cancellation)
+tests/tjn.c: now "tjn p n z" evaluates j(n,z) to precision p
+
+------------------------------------------------------------------------
+r4923 | vlefevre | 2007-10-27 12:59:35 +0000 (Sat, 27 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/factorial.c
+
+factorial.c: added FIXME comment.
+
+------------------------------------------------------------------------
+r4922 | vlefevre | 2007-10-27 12:23:43 +0000 (Sat, 27 Oct 2007) | 4 lines
+Changed paths:
+ M /trunk/gamma.c
+
+gamma.c: attempt to fix wrong fix in 4918 (the maximum exponent can
+be > 2^30 on 64-bit machines). There may still be problems in huge
+precisions.
+
+------------------------------------------------------------------------
+r4921 | zimmerma | 2007-10-27 11:17:24 +0000 (Sat, 27 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added note about efficiency of special functions
+corrected typo
+
+------------------------------------------------------------------------
+r4920 | zimmerma | 2007-10-27 11:07:33 +0000 (Sat, 27 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+ M /trunk/zeta.c
+
+fixed bug in zeta(large negative) reported by Kevin Rauch [wrong inexact flag]
+
+------------------------------------------------------------------------
+r4919 | zimmerma | 2007-10-27 08:15:57 +0000 (Sat, 27 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/erfc.c
+ M /trunk/tests/terf.c
+
+fixed inefficiency reported by Kevin Rauch when x large negative (erfc -> 2)
+
+------------------------------------------------------------------------
+r4918 | zimmerma | 2007-10-26 19:12:24 +0000 (Fri, 26 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+fixed another bug found by Kevin Rauch: gamma(huge integer) failed on 64-bit
+
+------------------------------------------------------------------------
+r4917 | zimmerma | 2007-10-26 18:34:54 +0000 (Fri, 26 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/tests/tlgamma.c
+
+fixed bug found by Kevin Rauch (emin/emax not restored for x=1,2)
+
+------------------------------------------------------------------------
+r4916 | zimmerma | 2007-10-26 18:05:43 +0000 (Fri, 26 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tli2.c
+
+added test for reference values
+
+------------------------------------------------------------------------
+r4915 | zimmerma | 2007-10-26 18:05:12 +0000 (Fri, 26 Oct 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/li2
+
+reference values for li2
+
+------------------------------------------------------------------------
+r4914 | thevenyp | 2007-10-26 17:32:19 +0000 (Fri, 26 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/li2.c
+
+algorithms.tex: description of dilogarithm algorithm
+li2.c: conformity with description in algorithm.tex
+
+------------------------------------------------------------------------
+r4913 | vlefevre | 2007-10-23 10:16:22 +0000 (Tue, 23 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: small change in the description of mpfr_subnormalize.
+
+------------------------------------------------------------------------
+r4912 | zimmerma | 2007-10-23 09:02:35 +0000 (Tue, 23 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added more details in the description of subnormalize
+
+------------------------------------------------------------------------
+r4908 | vlefevre | 2007-10-23 02:43:39 +0000 (Tue, 23 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/subnormal.c
+
+subnormal.c: fixed the bugs when old_inex is INT_MIN or INT_MAX.
+
+------------------------------------------------------------------------
+r4907 | vlefevre | 2007-10-23 02:35:00 +0000 (Tue, 23 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tsubnormal.c
+
+tsubnormal.c: added some tests showing bugs when old_inex is INT_MIN
+or INT_MAX.
+
+------------------------------------------------------------------------
+r4906 | vlefevre | 2007-10-23 02:31:48 +0000 (Tue, 23 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/subnormal.c
+
+subnormal.c: corrected comment.
+
+------------------------------------------------------------------------
+r4905 | vlefevre | 2007-10-23 01:52:28 +0000 (Tue, 23 Oct 2007) | 8 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/subnormal.c
+
+Changeset r4904 introduced an assertion failure, but the assertion
+emax - emin >= PREC(x) wasn't necessary: the value of emax doesn't
+matter, except when the exponent is increased due to the rounding.
+So, we just document that if the result cannot be represented in the
+current exponent range, the behavior is undefined (updated mpfr.texi
+accordingly). Removed the assertion from subnormal.c and added a new
+one to have an abort if such an undefined behavior occurs.
+
+------------------------------------------------------------------------
+r4904 | zimmerma | 2007-10-22 18:38:49 +0000 (Mon, 22 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/subnormal.c
+ M /trunk/tests/tsubnormal.c
+
+fixed 2 bugs reported by Kevin Rauch
+
+------------------------------------------------------------------------
+r4903 | vlefevre | 2007-10-22 16:41:45 +0000 (Mon, 22 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/subnormal.c
+
+subnormal.c: replaced incorrect comment.
+
+------------------------------------------------------------------------
+r4902 | vlefevre | 2007-10-22 15:22:24 +0000 (Mon, 22 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+tests: updated svn:ignore property.
+
+------------------------------------------------------------------------
+r4901 | zimmerma | 2007-10-22 08:55:51 +0000 (Mon, 22 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+
+added new references
+
+------------------------------------------------------------------------
+r4899 | zimmerma | 2007-10-20 09:18:37 +0000 (Sat, 20 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/li2.c
+
+added asymptotic expansions
+
+------------------------------------------------------------------------
+r4898 | thevenyp | 2007-10-19 16:08:27 +0000 (Fri, 19 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/li2.c
+ M /trunk/tests/tli2.c
+
+li2.c: add Ziv's loop in li2_series
+tli2.c: add a function for fixed value checking
+
+------------------------------------------------------------------------
+r4897 | thevenyp | 2007-10-17 16:10:03 +0000 (Wed, 17 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/li2.c
+ M /trunk/tests/tli2.c
+
+li2.c: fix a typo and fix use of taylor series
+tests/tli2.c: use default random function
+
+------------------------------------------------------------------------
+r4896 | thevenyp | 2007-10-16 17:02:02 +0000 (Tue, 16 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/li2.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/reuse.c
+ A /trunk/tests/tli2.c
+
+add dilogarithm function
+
+------------------------------------------------------------------------
+r4895 | zimmerma | 2007-10-15 14:11:22 +0000 (Mon, 15 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item in Efficiency section
+
+------------------------------------------------------------------------
+r4894 | zimmerma | 2007-10-15 13:14:30 +0000 (Mon, 15 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/TODO
+
+added table of contents
+removed last section (mpf/mpfr integration)
+
+------------------------------------------------------------------------
+r4893 | vlefevre | 2007-10-15 01:58:45 +0000 (Mon, 15 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/algorithms.tex
+
+Fixed acosh(x) with x slightly larger than 1, using sqrt(2(x-1)) and
+a complete error analysis.
+
+------------------------------------------------------------------------
+r4892 | vlefevre | 2007-10-15 00:46:10 +0000 (Mon, 15 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+
+tests/tacosh.c: added another test with x a bit larger than 1 and
+prec(y) << prec(x).
+
+------------------------------------------------------------------------
+r4891 | vlefevre | 2007-10-12 16:07:23 +0000 (Fri, 12 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+
+acosh.c: added a comment about the fix I did in r4814.
+
+------------------------------------------------------------------------
+r4890 | zimmerma | 2007-10-09 20:22:47 +0000 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added extra reference for slowness of mpfr_root
+
+------------------------------------------------------------------------
+r4888 | vlefevre | 2007-10-09 11:48:52 +0000 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update (added Question 8).
+
+------------------------------------------------------------------------
+r4887 | vlefevre | 2007-10-09 11:03:16 +0000 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: another small change in Contributors section.
+
+------------------------------------------------------------------------
+r4886 | vlefevre | 2007-10-09 10:35:28 +0000 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: small change in Contributors section.
+
+------------------------------------------------------------------------
+r4885 | vlefevre | 2007-10-09 09:59:18 +0000 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: mention Fiable and AOC actions in the Contributors section.
+
+------------------------------------------------------------------------
+r4884 | zimmerma | 2007-10-09 07:50:42 +0000 (Tue, 09 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added reference to ACM TOMS paper
+updated other references, and Contributors section
+
+------------------------------------------------------------------------
+r4883 | zimmerma | 2007-10-09 06:11:31 +0000 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed typo in sectioning
+
+------------------------------------------------------------------------
+r4882 | zimmerma | 2007-10-08 17:16:51 +0000 (Mon, 08 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+removed mpfr_get_d1 from documented functions
+removed old commented functions
+
+------------------------------------------------------------------------
+r4881 | zimmerma | 2007-10-08 14:48:38 +0000 (Mon, 08 Oct 2007) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+renamed "Rounding Mode Related Functions" to "Rounding Related Functions"
+put mpfr_can_round in "Rounding Related Functions" (now exported)
+exchanged order of sections "Miscellaneous Functions" and "Rounding Related Functions"
+
+------------------------------------------------------------------------
+r4880 | zimmerma | 2007-10-08 11:04:34 +0000 (Mon, 08 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added hint for mpfr_can_round to get ternary value
+
+------------------------------------------------------------------------
+r4879 | zimmerma | 2007-10-08 10:09:56 +0000 (Mon, 08 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+changed mpfr_can_round() call into MPFR_CAN_ROUND() call
+
+------------------------------------------------------------------------
+r4878 | vlefevre | 2007-10-05 12:18:17 +0000 (Fri, 05 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/update-version
+
+Updated update-version to make patches easier to produce.
+
+------------------------------------------------------------------------
+r4876 | vlefevre | 2007-10-04 01:57:35 +0000 (Thu, 04 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/atan2.c
+ M /trunk/tests/tatan.c
+
+Fixed a bug (found by Robert Bajema) in mpfr_atan2, which can occur if
+the underflow flag is set before the call and x > 0; added testcase.
+
+------------------------------------------------------------------------
+r4875 | vlefevre | 2007-10-03 15:13:06 +0000 (Wed, 03 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: improved mpfr_set_exp description too.
+
+------------------------------------------------------------------------
+r4874 | vlefevre | 2007-10-03 15:09:49 +0000 (Wed, 03 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: improved mpfr_get_exp documentation.
+
+------------------------------------------------------------------------
+r4873 | vlefevre | 2007-10-03 15:05:31 +0000 (Wed, 03 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: mantissa -> significand (to use the terminology from IEEE 754
+and ISO C99).
+
+------------------------------------------------------------------------
+r4872 | vlefevre | 2007-10-03 14:36:38 +0000 (Wed, 03 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: better error message if libgmp is not found.
+
+------------------------------------------------------------------------
+r4871 | thevenyp | 2007-10-02 16:08:02 +0000 (Tue, 02 Oct 2007) | 1 line
+Changed paths:
+ M /trunk/algorithms.tex
+
+fix some typos
+------------------------------------------------------------------------
+r4870 | zimmerma | 2007-09-28 16:14:03 +0000 (Fri, 28 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added references
+
+------------------------------------------------------------------------
+r4869 | thevenyp | 2007-09-28 12:08:56 +0000 (Fri, 28 Sep 2007) | 5 lines
+Changed paths:
+ M /trunk/Makefile.am
+ D /trunk/fmod.c
+ M /trunk/mpfr.texi
+ A /trunk/rem1.c
+ D /trunk/remquo.c
+ M /trunk/tests/tfmod.c
+
+merge fmod, remaider and remquo into a single file rem1.c.
+merge code into a single internal function mpfr_rem1.
+fix false statement in mpfr.texi: rop and op1 have the same sign for mpfr_fmod
+but not for mpfr_remainder and mpfr_remquo.
+
+------------------------------------------------------------------------
+r4868 | vlefevre | 2007-09-26 16:20:35 +0000 (Wed, 26 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfmod.c
+
+tests/tfmod.c: added static.
+
+------------------------------------------------------------------------
+r4867 | thevenyp | 2007-09-26 11:30:29 +0000 (Wed, 26 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/fmod.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/reuse.c
+ A /trunk/tests/tfmod.c
+
+new fmod function
+
+------------------------------------------------------------------------
+r4866 | vlefevre | 2007-09-22 00:17:11 +0000 (Sat, 22 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+tests: updated svn:ignore property.
+
+------------------------------------------------------------------------
+r4865 | vlefevre | 2007-09-22 00:15:49 +0000 (Sat, 22 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/add_d.c
+ M /trunk/modf.c
+ M /trunk/mpfr.texi
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sinh_cosh.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tmodf.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tsinh_cosh.c
+ M /trunk/tests/tsub_d.c
+ M /trunk/tests/ttrunc.c
+
+GNU coding style, reformatting, exit (-1) -> exit (1).
+
+------------------------------------------------------------------------
+r4864 | thevenyp | 2007-09-21 08:29:01 +0000 (Fri, 21 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/sinh_cosh.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/reuse.c
+ A /trunk/tests/tsinh_cosh.c
+
+new mpfr_sinh_cosh function
+
+------------------------------------------------------------------------
+r4863 | vlefevre | 2007-09-19 02:24:31 +0000 (Wed, 19 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: removed __gmpfr_isqrt bug.
+
+------------------------------------------------------------------------
+r4862 | vlefevre | 2007-09-19 02:12:09 +0000 (Wed, 19 Sep 2007) | 3 lines
+Changed paths:
+ M /trunk/isqrt.c
+ M /trunk/tests/tisqrt.c
+
+isqrt.c: quick fix of __gmpfr_cuberoot (a full proof is needed).
+tests/tisqrt.c: added much more tests for __gmpfr_cuberoot.
+
+------------------------------------------------------------------------
+r4861 | vlefevre | 2007-09-19 01:46:58 +0000 (Wed, 19 Sep 2007) | 7 lines
+Changed paths:
+ M /trunk/tests/tisqrt.c
+
+tisqrt.c: improved tests. When doing
+ touch tests.c tisqrt.c
+ make tisqrt CFLAGS="-g -O2 -ffloat-store -DMPFR_FPU_PREC=_FPU_SINGLE"
+ ./tisqrt
+with gcc 4.2.1 on a Linux/x86 machine, on gets:
+ Error in __gmpfr_cuberoot (4251527999): got 1620 instead of 1619
+
+------------------------------------------------------------------------
+r4860 | vlefevre | 2007-09-19 01:12:33 +0000 (Wed, 19 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tisqrt.c
+
+tisqrt.c: added __gmpfr_cuberoot() tests.
+
+------------------------------------------------------------------------
+r4859 | vlefevre | 2007-09-19 01:03:11 +0000 (Wed, 19 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/isqrt.c
+
+isqrt.c: corrected the explanation.
+
+------------------------------------------------------------------------
+r4858 | vlefevre | 2007-09-19 00:57:46 +0000 (Wed, 19 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/isqrt.c
+
+isqrt.c: fixed __gmpfr_isqrt.
+
+------------------------------------------------------------------------
+r4857 | vlefevre | 2007-09-18 14:54:59 +0000 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+tests: updated svn:ignore property.
+
+------------------------------------------------------------------------
+r4856 | vlefevre | 2007-09-18 14:52:23 +0000 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tisqrt.c
+
+tests: added tisqrt.c (test file for __gmpfr_isqrt internal function).
+
+------------------------------------------------------------------------
+r4855 | vlefevre | 2007-09-18 14:37:59 +0000 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: added __gmpfr_isqrt bug.
+
+------------------------------------------------------------------------
+r4854 | vlefevre | 2007-09-18 14:26:48 +0000 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/isqrt.c
+
+isqrt.c: fixed a cast and added a FIXME comment.
+
+------------------------------------------------------------------------
+r4853 | vlefevre | 2007-09-18 14:16:46 +0000 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/isqrt.c
+
+isqrt.c: GNU coding style.
+
+------------------------------------------------------------------------
+r4852 | vlefevre | 2007-09-18 12:21:14 +0000 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+sin.c: extend the exponent range.
+
+------------------------------------------------------------------------
+r4851 | vlefevre | 2007-09-18 12:14:15 +0000 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/sqr.c
+
+sqr.c: set the global inexact flag.
+
+------------------------------------------------------------------------
+r4850 | vlefevre | 2007-09-18 12:09:13 +0000 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+sqrt.c: avoid the exponent range extension.
+
+------------------------------------------------------------------------
+r4849 | vlefevre | 2007-09-18 12:02:07 +0000 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqr.c
+
+tsqr.c: added generic tests (shows that the inexact flag isn't set).
+
+------------------------------------------------------------------------
+r4848 | vlefevre | 2007-09-18 11:55:32 +0000 (Tue, 18 Sep 2007) | 3 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+sqrt.c: extend exponent range (this also fixes the fact that the global
+inexact flag wasn't set).
+
+------------------------------------------------------------------------
+r4847 | vlefevre | 2007-09-18 11:51:23 +0000 (Tue, 18 Sep 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+tsqrt.c: added generic tests (shows that the inexact flag isn't set,
+which is a bug reported by Guillaume Revy).
+
+------------------------------------------------------------------------
+r4846 | thevenyp | 2007-09-17 11:05:18 +0000 (Mon, 17 Sep 2007) | 1 line
+Changed paths:
+ M /trunk/modf.c
+ M /trunk/tests/tmodf.c
+
+modf.c: take care of user exponent range (possible underflow/overflow)
+------------------------------------------------------------------------
+r4845 | vlefevre | 2007-09-16 09:44:33 +0000 (Sun, 16 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tsin_cos.c: fixed the tiny() test.
+
+------------------------------------------------------------------------
+r4844 | vlefevre | 2007-09-16 09:43:04 +0000 (Sun, 16 Sep 2007) | 4 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+sin_cos.c: fixed the overflow and cancellation problems by using
+MPFR_FAST_COMPUTE_IF_SMALL_INPUT from the mpfr_sin and mpfr_cos
+functions (I'll fix the test later).
+
+------------------------------------------------------------------------
+r4843 | vlefevre | 2007-09-16 09:09:39 +0000 (Sun, 16 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+tsin_cos.c: added test on tiny values.
+
+------------------------------------------------------------------------
+r4842 | zimmerma | 2007-09-16 08:28:27 +0000 (Sun, 16 Sep 2007) | 4 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+Put back previous patch, now avoids overflow, and added more explanations.
+This is still not a definitive solution, but more efficient than 2.3.0
+in the case x is small.
+
+------------------------------------------------------------------------
+r4841 | vlefevre | 2007-09-15 08:30:36 +0000 (Sat, 15 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+Efficiency regression wasn't fixed correctly -> commented out the code.
+
+------------------------------------------------------------------------
+r4840 | zimmerma | 2007-09-15 08:15:15 +0000 (Sat, 15 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+fixed efficiency regression pointed out by Andreas Enge
+
+------------------------------------------------------------------------
+r4839 | zimmerma | 2007-09-13 19:08:25 +0000 (Thu, 13 Sep 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/sin_cos.c
+ M /trunk/tests/reuse.c
+
+fixed bug in mpfr_sin_cos found by Philippe: z (to save the cosine) was not
+allowed to be identical to the input x
+
+------------------------------------------------------------------------
+r4838 | thevenyp | 2007-09-13 16:48:49 +0000 (Thu, 13 Sep 2007) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/TODO
+ A /trunk/modf.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/sin_cos.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/reuse.c
+ A /trunk/tests/tmodf.c
+
+new function mpfr_modf and add restrictions on mpfr_sin_cos' variables
+------------------------------------------------------------------------
+r4837 | thevenyp | 2007-09-11 13:01:54 +0000 (Tue, 11 Sep 2007) | 1 line
+Changed paths:
+ M /trunk/tests/tadd_d.c
+ M /trunk/tests/td_div.c
+ M /trunk/tests/td_sub.c
+ M /trunk/tests/tdiv_d.c
+ M /trunk/tests/tmul_d.c
+ M /trunk/tests/tsub_d.c
+
+add some simple test cases in tadd_d.c and friends
+------------------------------------------------------------------------
+r4836 | vlefevre | 2007-09-10 07:55:58 +0000 (Mon, 10 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/prepare
+
+prepare: output a message saying that this script is obsolete.
+
+------------------------------------------------------------------------
+r4835 | zimmerma | 2007-09-09 19:08:17 +0000 (Sun, 09 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added restrictions to mpfr_add_d and friends
+
+------------------------------------------------------------------------
+r4834 | zimmerma | 2007-09-08 06:41:22 +0000 (Sat, 08 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed functions mpfr_add_d ... which are done
+
+------------------------------------------------------------------------
+r4833 | zimmerma | 2007-09-07 15:35:49 +0000 (Fri, 07 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+added Philippe Theveny
+
+------------------------------------------------------------------------
+r4832 | thevenyp | 2007-09-07 14:47:34 +0000 (Fri, 07 Sep 2007) | 1 line
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/add_d.c
+ A /trunk/d_div.c
+ A /trunk/d_sub.c
+ A /trunk/div_d.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/mul_d.c
+ A /trunk/sub_d.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tadd_d.c
+ A /trunk/tests/td_div.c
+ A /trunk/tests/td_sub.c
+ A /trunk/tests/tdiv_d.c
+ M /trunk/tests/tgeneric.c
+ A /trunk/tests/tmul_d.c
+ A /trunk/tests/tsub_d.c
+
+new arithmetic functions with a double argument
+------------------------------------------------------------------------
+r4831 | vlefevre | 2007-09-07 13:04:09 +0000 (Fri, 07 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+
+tacosh.c: added generic tests for the overflow case.
+
+------------------------------------------------------------------------
+r4830 | vlefevre | 2007-09-07 13:03:32 +0000 (Fri, 07 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+
+acosh.c: reduce the precision for ln(2); smaller error bound.
+
+------------------------------------------------------------------------
+r4829 | vlefevre | 2007-09-07 13:02:13 +0000 (Fri, 07 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tgeneric.c: undefine some macros at the end.
+
+------------------------------------------------------------------------
+r4828 | vlefevre | 2007-09-07 12:30:36 +0000 (Fri, 07 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+
+acosh.c: fixed overflow bug.
+
+------------------------------------------------------------------------
+r4827 | vlefevre | 2007-09-07 11:54:53 +0000 (Fri, 07 Sep 2007) | 3 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/tests/tacosh.c
+
+acosh.c: mentioned bug due to overflow in mpfr_mul.
+tests/tacosh.c: added corresponding testcase (for 32-bit machines).
+
+------------------------------------------------------------------------
+r4826 | vlefevre | 2007-09-07 11:26:30 +0000 (Fri, 07 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+
+tacosh.c: use tests_default_random().
+
+------------------------------------------------------------------------
+r4825 | vlefevre | 2007-09-07 11:25:42 +0000 (Fri, 07 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: improved tests_default_random().
+
+------------------------------------------------------------------------
+r4823 | vlefevre | 2007-09-02 23:17:48 +0000 (Sun, 02 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Makefile.am: fixed get_patches rule.
+
+------------------------------------------------------------------------
+r4821 | vlefevre | 2007-09-02 22:29:28 +0000 (Sun, 02 Sep 2007) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Makefile.am: cd $(srcdir) before executing get_patches.sh (thanks to
+Daniel Jacobowitz for noticing this); for more information, see the
+note just before the get_patches.c rule.
+
+------------------------------------------------------------------------
+r4819 | vlefevre | 2007-08-31 17:09:15 +0000 (Fri, 31 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+
+acosh.c: added MPFR_UNLIKELY.
+
+------------------------------------------------------------------------
+r4817 | vlefevre | 2007-08-31 15:50:48 +0000 (Fri, 31 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+
+Added generic bad case tests.
+
+------------------------------------------------------------------------
+r4816 | vlefevre | 2007-08-31 15:34:23 +0000 (Fri, 31 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: deleted trailing spaces.
+
+------------------------------------------------------------------------
+r4815 | vlefevre | 2007-08-31 15:33:34 +0000 (Fri, 31 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: correction in section on mpfr_asinh: acosh -> asinh.
+
+------------------------------------------------------------------------
+r4814 | vlefevre | 2007-08-31 15:31:37 +0000 (Fri, 31 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/algorithms.tex
+ M /trunk/tests/tacosh.c
+
+Fixed bug in mpfr_acosh for arguments slightly larger than 1;
+updated algorithms.tex; fixed testcase.
+
+------------------------------------------------------------------------
+r4813 | vlefevre | 2007-08-31 13:06:59 +0000 (Fri, 31 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+
+tacosh.c: added testcase for bug in mpfr_acosh (assertion failure).
+
+------------------------------------------------------------------------
+r4812 | vlefevre | 2007-08-31 12:02:37 +0000 (Fri, 31 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tasin.c
+
+tasin.c: increased the number of generic tests.
+
+------------------------------------------------------------------------
+r4811 | vlefevre | 2007-08-31 11:33:53 +0000 (Fri, 31 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/tzeta.c
+
+Improved generic tests by limiting the exponent range of the random
+numbers for some functions.
+
+------------------------------------------------------------------------
+r4810 | vlefevre | 2007-08-30 15:09:11 +0000 (Thu, 30 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/mpfr-test.h
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tpow.c
+
+Generic tests: adjust the proportion of negative numbers returned
+by the random function in order to get fewer NaN cases.
+
+------------------------------------------------------------------------
+r4809 | vlefevre | 2007-08-30 14:26:54 +0000 (Thu, 30 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tgeneric.c: output a warning when too few normal cases are tested
+(so that the random function can be improved...).
+
+------------------------------------------------------------------------
+r4808 | vlefevre | 2007-08-30 13:50:59 +0000 (Thu, 30 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: function split (for future addition).
+
+------------------------------------------------------------------------
+r4806 | vlefevre | 2007-08-30 10:37:17 +0000 (Thu, 30 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: updated copyright notice (for consistency).
+
+------------------------------------------------------------------------
+r4803 | vlefevre | 2007-08-30 10:29:54 +0000 (Thu, 30 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/mpfr-test.h
+
+Bug fix: added missing _MPFR_PROTO in mpfr-test.h.
+
+------------------------------------------------------------------------
+r4802 | vlefevre | 2007-08-30 10:12:22 +0000 (Thu, 30 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tgeneric.c: updated description line.
+
+------------------------------------------------------------------------
+r4800 | vlefevre | 2007-08-29 19:59:07 +0000 (Wed, 29 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/acinclude.m4
+ M /trunk/comparisons.c
+ M /trunk/exp.c
+ M /trunk/faq.xsl
+ M /trunk/neg.c
+
+Updated copyright notice (for an unknown reason, some files were missing
+from the change done in r4350).
+
+------------------------------------------------------------------------
+r4795 | vlefevre | 2007-08-28 15:37:59 +0000 (Tue, 28 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/atan2.c
+
+atan2.c: as we supposed some property, let's add an assertion (which
+can be evaluated at compile time).
+
+------------------------------------------------------------------------
+r4794 | vlefevre | 2007-08-28 15:27:17 +0000 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/atan2.c
+
+atan2.c: improved comment.
+
+------------------------------------------------------------------------
+r4793 | vlefevre | 2007-08-28 15:24:27 +0000 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/atan2.c
+
+atan2.c: completed the underflow case.
+
+------------------------------------------------------------------------
+r4792 | vlefevre | 2007-08-28 14:19:37 +0000 (Tue, 28 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/atan2.c
+
+atan2.c: fixed the underflow case except in GMP_RNDN with
+2^(-emin-2) < |y/x| < 2^(-emin-1).
+
+------------------------------------------------------------------------
+r4791 | vlefevre | 2007-08-28 14:18:35 +0000 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+tatan.c: added small-value tests in the other rounding modes.
+
+------------------------------------------------------------------------
+r4790 | vlefevre | 2007-08-28 13:51:04 +0000 (Tue, 28 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/atan2.c
+
+atan2.c: implemented the special case where x is positive and y/x is
+computed exactly (solving the underflow problems in this case).
+
+------------------------------------------------------------------------
+r4789 | vlefevre | 2007-08-28 13:49:02 +0000 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+tatan.c: added a similar test, but with an exact division result.
+
+------------------------------------------------------------------------
+r4788 | vlefevre | 2007-08-28 13:35:40 +0000 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+tatan.c: fixed test.
+
+------------------------------------------------------------------------
+r4786 | vlefevre | 2007-08-28 13:16:16 +0000 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added a paragraph concerning Ziv loops.
+
+------------------------------------------------------------------------
+r4785 | vlefevre | 2007-08-28 09:34:36 +0000 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+tatan.c: updated comment.
+
+------------------------------------------------------------------------
+r4784 | vlefevre | 2007-08-28 08:59:09 +0000 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+tatan.c: extended the latest testcase to any platform (e.g. 64 bits).
+
+------------------------------------------------------------------------
+r4783 | vlefevre | 2007-08-28 08:49:00 +0000 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+tatan.c: added testcase from a bug reported by Christopher Creutzig.
+
+------------------------------------------------------------------------
+r4781 | vlefevre | 2007-08-27 14:27:34 +0000 (Mon, 27 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk
+ M /trunk/tests
+
+Updated svn:ignore properties.
+
+------------------------------------------------------------------------
+r4779 | vlefevre | 2007-08-27 11:55:00 +0000 (Mon, 27 Aug 2007) | 7 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update:
+ * The question numbers are now hardcoded instead of being generated
+ with CSS rules.
+ * Added the list of questions at the top.
+ * CSS styles: a grey bar is displayed on the left of the target answer
+ (if the browser supports the ":target" pseudo-class from CSS3).
+
+------------------------------------------------------------------------
+r4778 | vlefevre | 2007-08-27 10:56:11 +0000 (Mon, 27 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/faq.xsl
+
+faq.xsl: added a comment.
+
+------------------------------------------------------------------------
+r4776 | vlefevre | 2007-08-27 10:44:17 +0000 (Mon, 27 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update.
+
+------------------------------------------------------------------------
+r4774 | vlefevre | 2007-08-22 15:51:41 +0000 (Wed, 22 Aug 2007) | 6 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: added another warning concerning the --with-gmp options.
+For instance, under Linux, "cpp -I/usr/include -v < /dev/null" says:
+ ignoring duplicate directory "/usr/include"
+ as it is a non-system directory that duplicates a system directory
+and does not modify the include search path as wanted.
+
+------------------------------------------------------------------------
+r4772 | vlefevre | 2007-08-15 17:29:44 +0000 (Wed, 15 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: improved description of mpfr_setsign.
+
+------------------------------------------------------------------------
+r4770 | vlefevre | 2007-08-14 11:41:37 +0000 (Tue, 14 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Added to NEWS: Thread-safe support with Microsoft Visual compiler.
+
+------------------------------------------------------------------------
+r4768 | vlefevre | 2007-08-14 11:34:22 +0000 (Tue, 14 Aug 2007) | 5 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: if MPFR_USE_THREAD_SAFE is defined (--enable-thread-safe):
+ * Added support for MSC (thanks to Brian Gladman).
+ * Define MPFR_THREAD_ATTR even after #error to make the error more
+ visible (see comment in the source).
+
+------------------------------------------------------------------------
+r4765 | vlefevre | 2007-08-13 10:41:51 +0000 (Mon, 13 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tstckintc.c
+
+tstckintc.c: fixed bus error on Solaris (the address of Buffer was not
+a multiple of 4).
+
+------------------------------------------------------------------------
+r4761 | vlefevre | 2007-08-13 05:05:39 +0000 (Mon, 13 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: new functions mpfr_signbit, mpfr_setsign, mpfr_copysign.
+
+------------------------------------------------------------------------
+r4759 | vlefevre | 2007-08-13 04:53:32 +0000 (Mon, 13 Aug 2007) | 8 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/TODO
+ M /trunk/copysign.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/setsign.c
+ A /trunk/signbit.c
+ M /trunk/tests/tcopysign.c
+
+Implemented changes suggested in
+<https://sympa.inria.fr/sympa/arc/mpfr/2007-07/msg00123.html>.
+* Made mpfr_copysign() like the corresponding function in IEEE 754
+ (was an internal function until now).
+* Added mpfr_signbit() and mpfr_setsign().
+* Documented these three functions.
+* Updated TODO.
+
+------------------------------------------------------------------------
+r4757 | vlefevre | 2007-08-13 04:34:33 +0000 (Mon, 13 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/jyn_asympt.c
+ M /trunk/remquo.c
+ M /trunk/tests/texp10.c
+ M /trunk/tests/tl2b.c
+
+Make svn properties consistent.
+
+------------------------------------------------------------------------
+r4752 | vlefevre | 2007-08-11 22:41:05 +0000 (Sat, 11 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+Fixed mpfr_inits and mpfr_clears calls in tests/tatan.c.
+
+------------------------------------------------------------------------
+r4751 | vlefevre | 2007-08-11 22:38:54 +0000 (Sat, 11 Aug 2007) | 3 lines
+Changed paths:
+ A /trunk/check_inits_clears
+
+Added check_inits_clears Perl script to check that a cast is performed
+for the last argument of mpfr_inits, mpfr_inits2 and mpfr_clears.
+
+------------------------------------------------------------------------
+r4747 | vlefevre | 2007-08-10 02:19:57 +0000 (Fri, 10 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/VERSION
+ M /trunk/configure.in
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/version.c
+
+Updated version to 2.4.0-dev.
+
+------------------------------------------------------------------------
+r4744 | vlefevre | 2007-08-10 02:11:05 +0000 (Fri, 10 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS update.
+
+------------------------------------------------------------------------
+r4743 | vlefevre | 2007-08-10 02:06:56 +0000 (Fri, 10 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+ChangeLog update with "TZ=UTC svn log -v".
+
+------------------------------------------------------------------------
+r4742 | vlefevre | 2007-08-10 01:41:01 +0000 (Fri, 10 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/asinh.c
+
+asinh.c: fixed assertion failure (see test 4 in tasinh.c, added
+in r4740), that was due to an exception.
+
+------------------------------------------------------------------------
+r4741 | vlefevre | 2007-08-10 01:38:25 +0000 (Fri, 10 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tasinh.c
+
+tasinh.c: fixed test.
+
+------------------------------------------------------------------------
+r4740 | vlefevre | 2007-08-10 01:18:46 +0000 (Fri, 10 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tasinh.c
+
+tasinh.c: added worst case that yields an assertion failure.
+
+------------------------------------------------------------------------
+r4739 | vlefevre | 2007-08-09 17:21:32 +0000 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/cbrt
+ M /trunk/tests/tcbrt.c
+
+Added data_check support to cbrt.
+
+------------------------------------------------------------------------
+r4738 | vlefevre | 2007-08-09 15:45:47 +0000 (Thu, 09 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/log.c
+
+log.c: fixed assertion failure (see test x_near_one in tlog.c, added
+in r4736), that was due to an exception.
+
+------------------------------------------------------------------------
+r4737 | vlefevre | 2007-08-09 12:12:56 +0000 (Thu, 09 Aug 2007) | 6 lines
+Changed paths:
+ M /trunk/pow.c
+
+pow.c: added MPFR_SMALL_INPUT_AFTER_SAVE_EXPO for the case where
+|y * log(x)| is very small (I can't really test because this code
+currently fails due to a bug in mpfr_log: see test x_near_one
+added to tlog.c as changeset 4736; this bug is also present in
+the 2.2 branch).
+
+------------------------------------------------------------------------
+r4736 | vlefevre | 2007-08-09 11:58:59 +0000 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+tlog.c: added a test leading to an assertion failure in mpfr_log.
+
+------------------------------------------------------------------------
+r4735 | vlefevre | 2007-08-09 11:45:19 +0000 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: added a test where x is close to 1.
+
+------------------------------------------------------------------------
+r4734 | vlefevre | 2007-08-09 11:02:28 +0000 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/exp10
+
+Added empty file tests/data/exp10 to avoid an error with -dev versions.
+
+------------------------------------------------------------------------
+r4733 | vlefevre | 2007-08-09 10:18:50 +0000 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/round_near_x.c
+
+Added a TODO concerning the description of mpfr_round_near_x.
+
+------------------------------------------------------------------------
+r4732 | vlefevre | 2007-08-09 09:48:59 +0000 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/expm1
+ A /trunk/tests/data/log1p
+ A /trunk/tests/data/log2
+
+Added empty files in tests/data to avoid errors with -dev versions.
+
+------------------------------------------------------------------------
+r4731 | vlefevre | 2007-08-09 09:39:43 +0000 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/ui_pow.c
+
+mpfr_ui_pow fix: added a MPFR_SAVE_EXPO_UPDATE_FLAGS.
+
+------------------------------------------------------------------------
+r4730 | vlefevre | 2007-08-09 02:52:27 +0000 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/texp10.c
+
+Added texp10.c (texp10 currently fails).
+
+------------------------------------------------------------------------
+r4729 | vlefevre | 2007-08-09 02:26:33 +0000 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/texp2.c
+
+texp2.c: reformat and added some tests which were missing.
+
+------------------------------------------------------------------------
+r4728 | vlefevre | 2007-08-08 15:12:56 +0000 (Wed, 08 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tl2b.c
+ M /trunk/tests/tremquo.c
+
+Updated svn:keywords and svn:eol-style properties in tests.
+
+------------------------------------------------------------------------
+r4727 | vlefevre | 2007-08-08 15:11:15 +0000 (Wed, 08 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+
+Added data_check calls to texpm1, tlog1p and tlog2.
+
+------------------------------------------------------------------------
+r4726 | vlefevre | 2007-08-08 14:37:28 +0000 (Wed, 08 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: in data_check(), mode 'Z', do not test GMP_RNDN if
+the precision for the directed rounding modes is MPFR_PREC_MIN.
+
+------------------------------------------------------------------------
+r4725 | vlefevre | 2007-08-04 23:13:52 +0000 (Sat, 04 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: more on mpfr_sin (and mpfr_cos).
+
+------------------------------------------------------------------------
+r4724 | vlefevre | 2007-08-04 22:58:01 +0000 (Sat, 04 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: update concerning sin/cos/tan.
+
+------------------------------------------------------------------------
+r4723 | vlefevre | 2007-08-03 02:45:32 +0000 (Fri, 03 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: in data_check(), check the 4 rounding modes if rnd is 'Z'
+(in order to test the worst cases).
+
+------------------------------------------------------------------------
+r4722 | vlefevre | 2007-08-03 01:30:20 +0000 (Fri, 03 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+Fixed coding style (for ansi2knr in particular).
+
+------------------------------------------------------------------------
+r4721 | vlefevre | 2007-08-02 10:19:44 +0000 (Thu, 02 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Makefile.am: added a comment about "get_patches.c".
+
+------------------------------------------------------------------------
+r4720 | vlefevre | 2007-08-02 10:07:48 +0000 (Thu, 02 Aug 2007) | 8 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+No longer set "CLEANFILES = get_patches.c" in Makefile.am so that a
+"make clean" doesn't remove the get_patches.c file, as rebuilding it
+needs a Unix shell (and some standard utilities). Anyway the update
+of this file should be regarded as part of the patch process, then
+this file is just like any other .c files. Note: "make dist" includes
+this file in the archives, so that concerning the build, everything
+is like before as long as no patches are applied.
+
+------------------------------------------------------------------------
+r4719 | zimmerma | 2007-08-01 18:07:32 +0000 (Wed, 01 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item about sNaN/qNaN
+
+------------------------------------------------------------------------
+r4718 | vlefevre | 2007-07-31 14:28:20 +0000 (Tue, 31 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/copysign.c
+
+copysign.c: reformat, updated comment (but this function is still not
+documented in mpfr.texi).
+
+------------------------------------------------------------------------
+r4717 | vlefevre | 2007-07-31 14:12:15 +0000 (Tue, 31 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/VERSION
+ M /trunk/configure.in
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/version.c
+
+Updated version back to 2.3.0-dev since the 2.3 branch will be recreated
+from the trunk (too many changes!).
+
+------------------------------------------------------------------------
+r4716 | vlefevre | 2007-07-31 13:34:37 +0000 (Tue, 31 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tl2b.c
+
+tl2b.c: enable output even when the constants are correct.
+
+------------------------------------------------------------------------
+r4715 | vlefevre | 2007-07-31 13:25:24 +0000 (Tue, 31 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk
+
+Added get_patches.c to the svn:ignore property, as this file is
+generated.
+
+------------------------------------------------------------------------
+r4714 | vlefevre | 2007-07-31 13:23:37 +0000 (Tue, 31 Jul 2007) | 13 lines
+Changed paths:
+ M /trunk/free_cache.c
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/tests
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tl2b.c
+
+Replaced l2b cache by constants, as suggested by Patrick Pelissier,
+to avoid efficiency problems with the stack interface and heavily
+threaded applications.
+ * Added tests/tl2b.c to generate / check the constants.
+ * tests/Makefile.am: added tl2b to check_PROGRAMS.
+ * tests directory: added tl2b to the svn:ignore property.
+ * mpfr-impl.h: updated the __gmpfr_l2b declaration.
+ * free_cache.c: disabled free_l2b (since there's no longer a cache).
+ * get_str.c: added the code generated by tl2b; for the bootstrap, one
+ can just write:
+ const __mpfr_struct __gmpfr_l2b[BASE_MAX-1][2] = { { { 0 } } };
+ Removed the code (in ceil_mul) that computed these constants.
+
+------------------------------------------------------------------------
+r4713 | vlefevre | 2007-07-30 22:37:30 +0000 (Mon, 30 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the documentation of the mpfr_get_d function family.
+
+------------------------------------------------------------------------
+r4712 | vlefevre | 2007-07-30 11:12:45 +0000 (Mon, 30 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/TODO
+
+Patch tracking: updated README.dev and TODO files.
+
+------------------------------------------------------------------------
+r4711 | vlefevre | 2007-07-30 10:45:01 +0000 (Mon, 30 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ A /trunk/PATCHES
+ A /trunk/get_patches.sh
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+Added support for tracking applied patches with new function
+mpfr_get_patches().
+
+------------------------------------------------------------------------
+r4710 | vlefevre | 2007-07-30 09:41:55 +0000 (Mon, 30 Jul 2007) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the example concerning mpfr_get_version() vs
+MPFR_VERSION_STRING ("Warning" instead of "Error", make sure that
+the example fits on 80 columns in the info file).
+
+------------------------------------------------------------------------
+r4709 | vlefevre | 2007-07-30 09:37:06 +0000 (Mon, 30 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated description of mpfr_get_version().
+
+------------------------------------------------------------------------
+r4708 | vlefevre | 2007-07-30 09:31:58 +0000 (Mon, 30 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated description of mpfr_get_version().
+
+------------------------------------------------------------------------
+r4707 | zimmerma | 2007-07-28 15:03:05 +0000 (Sat, 28 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added files that are not 100% covered by tests
+
+------------------------------------------------------------------------
+r4706 | vlefevre | 2007-07-27 22:04:24 +0000 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/coverage
+
+coverage: added --disable-shared --enable-static to configure.
+
+------------------------------------------------------------------------
+r4705 | vlefevre | 2007-07-27 21:59:04 +0000 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: added more casts for g++.
+
+------------------------------------------------------------------------
+r4704 | vlefevre | 2007-07-27 21:54:22 +0000 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Reformat.
+
+------------------------------------------------------------------------
+r4703 | vlefevre | 2007-07-27 21:48:03 +0000 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/const_log2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+
+Applied patch from Patrick to be able to build MPFR with g++.
+
+------------------------------------------------------------------------
+r4702 | zimmerma | 2007-07-26 12:02:24 +0000 (Thu, 26 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+added default thresholds for Core 2
+
+------------------------------------------------------------------------
+r4701 | vlefevre | 2007-07-25 15:34:52 +0000 (Wed, 25 Jul 2007) | 5 lines
+Changed paths:
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+
+No longer use MPFR_CHECK_ALL in tests. In '-dev' versions, assume
+that the data files exist and return an error whenever a file cannot
+be opened. In the other versions, return silently if the file cannot
+be opened.
+
+------------------------------------------------------------------------
+r4700 | vlefevre | 2007-07-25 15:18:45 +0000 (Wed, 25 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ D /trunk/mpfr-test.h
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/mpfr-test.h (from /trunk/mpfr-test.h:4698)
+
+Moved mpfr-test.h into the tests directory.
+
+------------------------------------------------------------------------
+r4699 | zimmerma | 2007-07-25 15:15:55 +0000 (Wed, 25 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+fixed "efficiency bug" (argument reduction was broken)
+
+------------------------------------------------------------------------
+r4698 | vlefevre | 2007-07-25 14:45:13 +0000 (Wed, 25 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: in data_check(), made whitespace skipping consistent and
+check that the result value is immediately followed by a \n.
+
+------------------------------------------------------------------------
+r4697 | vlefevre | 2007-07-25 14:02:23 +0000 (Wed, 25 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+[tests.c] Fixed some types (the result of getc() is not necessarily
+representable in a char).
+
+------------------------------------------------------------------------
+r4696 | vlefevre | 2007-07-25 13:45:10 +0000 (Wed, 25 Jul 2007) | 5 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests.c: changes in the error messages (BTW, we decided to output
+everything to stdout for consistency, even though messages for
+assertion failure are written to stderr) and replaced an abort ()
+by an exit (1).
+
+------------------------------------------------------------------------
+r4695 | vlefevre | 2007-07-25 10:58:54 +0000 (Wed, 25 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/jyn_asympt.c
+ M /trunk/tests/tests.c
+
+Delete trailing spaces.
+
+------------------------------------------------------------------------
+r4694 | zimmerma | 2007-07-25 10:01:45 +0000 (Wed, 25 Jul 2007) | 5 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/jn.c
+ A /trunk/jyn_asympt.c
+ M /trunk/tests/tests.c
+ M /trunk/yn.c
+
+jyn_asympt.c: new common file for asymptotic expansion in jn/yn
+tests/tests.c: print precisions in case of failure
+jn.c: now use jyn_asympt.c
+yn.c: now implement asymptotic expansion (jyn_asympt.c)
+
+------------------------------------------------------------------------
+r4693 | zimmerma | 2007-07-25 09:58:31 +0000 (Wed, 25 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/data/y0
+ M /trunk/tests/data/y1
+
+fixed more wrong entries in Gonnet's test suite
+
+------------------------------------------------------------------------
+r4692 | zimmerma | 2007-07-24 15:12:39 +0000 (Tue, 24 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/jn.c
+
+contribution of first neglected term to error was wrong
+
+------------------------------------------------------------------------
+r4691 | zimmerma | 2007-07-24 15:08:51 +0000 (Tue, 24 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/data/y0
+
+fixed wrong entry (not enough precision was used in Maple)
+
+------------------------------------------------------------------------
+r4690 | zimmerma | 2007-07-24 13:42:35 +0000 (Tue, 24 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/jn.c
+ M /trunk/tests/data/j0
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+
+implemented asymptotic expansion for large argument in j0/j1/jn
+
+------------------------------------------------------------------------
+r4689 | zimmerma | 2007-07-20 16:12:03 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+define MPFR_CHECK_ALL for nightly tests
+
+------------------------------------------------------------------------
+r4688 | zimmerma | 2007-07-20 16:11:15 +0000 (Fri, 20 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tlgamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+
+Added code to check mpfr against Gonnet's tables when the environment variable
+MPFR_CHECK_ALL is defined (some table entries were checked by MuPAD)
+
+------------------------------------------------------------------------
+r4687 | zimmerma | 2007-07-20 16:04:38 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/data/gonnet.mpl
+
+added comment
+
+------------------------------------------------------------------------
+r4686 | zimmerma | 2007-07-20 15:58:20 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/y0
+ A /trunk/tests/data/y1
+
+test data files mpfr mpfr_y0 and mpfr_y1, ***not*** checked with MuPAD
+
+------------------------------------------------------------------------
+r4685 | zimmerma | 2007-07-20 15:55:03 +0000 (Fri, 20 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/data/CheckData.mu
+
+added auxiliary MuPAD functions
+improved Ziv's strategy: add half of DIGITS each time
+
+------------------------------------------------------------------------
+r4684 | zimmerma | 2007-07-20 15:52:52 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/tanh
+
+test data file for mpfr_tanh, checked by MuPAD
+
+------------------------------------------------------------------------
+r4683 | zimmerma | 2007-07-20 15:51:28 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/tan
+
+test data file for mpfr_tan, checked with MuPAD (except 3 indicated entries)
+
+------------------------------------------------------------------------
+r4682 | zimmerma | 2007-07-20 15:39:23 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/sqrt
+
+test data file for mpfr_sqrt, checked with MuPAD
+
+------------------------------------------------------------------------
+r4681 | zimmerma | 2007-07-20 15:28:32 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/sinh
+
+test data file for mpfr_sinh, checked by MuPAD (except indicated lines)
+
+------------------------------------------------------------------------
+r4680 | zimmerma | 2007-07-20 15:17:58 +0000 (Fri, 20 Jul 2007) | 3 lines
+Changed paths:
+ A /trunk/tests/data/sin
+
+test data file for mpfr_sin, checked by MuPAD (except tiny inputs indicated
+in file)
+
+------------------------------------------------------------------------
+r4679 | zimmerma | 2007-07-20 13:45:40 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/pow275
+
+test data file for x^(11/4), checked with MuPAD
+
+------------------------------------------------------------------------
+r4678 | zimmerma | 2007-07-20 13:41:01 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/data/log10
+
+finally, I was able to check it with MuPAD
+
+------------------------------------------------------------------------
+r4677 | zimmerma | 2007-07-20 13:36:16 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/exp2
+
+test data file for 2^x, checked with MuPAD
+
+------------------------------------------------------------------------
+r4676 | zimmerma | 2007-07-20 13:28:30 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/mulpi
+
+test data file for Pi*x, checked with MuPAD
+
+------------------------------------------------------------------------
+r4675 | zimmerma | 2007-07-20 12:56:27 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/log
+
+test data file for mpfr_log, checked with MuPAD
+
+------------------------------------------------------------------------
+r4674 | zimmerma | 2007-07-20 12:54:43 +0000 (Fri, 20 Jul 2007) | 3 lines
+Changed paths:
+ A /trunk/tests/data/j0
+ A /trunk/tests/data/j1
+ A /trunk/tests/data/lgamma
+ A /trunk/tests/data/log10
+
+test data files for mpfr_j0, mpfr_j1, mpfr_lgamma, mpfr_log10,
+***not*** tested with MuPAD (not Dom::Interval interface)
+
+------------------------------------------------------------------------
+r4673 | zimmerma | 2007-07-20 12:52:25 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/inv
+
+test data file for 1/x, i.e., mpfr_ui_div(1,x), checked with MuPAD
+
+------------------------------------------------------------------------
+r4672 | zimmerma | 2007-07-20 12:45:10 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/gamma
+
+test data file for mpfr_gamma, ***not*** checked by MuPAD
+
+------------------------------------------------------------------------
+r4671 | zimmerma | 2007-07-20 12:44:09 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/exp
+
+test data file for mpfr_exp, checked with MuPAD
+
+------------------------------------------------------------------------
+r4670 | zimmerma | 2007-07-20 12:43:34 +0000 (Fri, 20 Jul 2007) | 3 lines
+Changed paths:
+ A /trunk/tests/data/erf
+ A /trunk/tests/data/erfc
+
+test data files for erf and erfc (not checked by MuPAD, since Dom::Interval
+does not have an interface for those functions in MuPAD 3.2.0)
+
+------------------------------------------------------------------------
+r4669 | zimmerma | 2007-07-20 12:35:54 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/cosh
+
+test data file for mpfr_cosh, checked with MuPAD
+
+------------------------------------------------------------------------
+r4668 | zimmerma | 2007-07-20 12:33:31 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/cos
+
+test data file for mpfr_cos, checked by MuPAD
+
+------------------------------------------------------------------------
+r4667 | zimmerma | 2007-07-20 12:02:36 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/atanh
+
+test data file for mpfr_atanh, checked with MuPAD
+
+------------------------------------------------------------------------
+r4666 | zimmerma | 2007-07-20 11:42:54 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/atan
+
+test data file for atan, checked with MuPAD
+
+------------------------------------------------------------------------
+r4665 | zimmerma | 2007-07-20 11:06:48 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/asinh
+
+test file for mpfr_asinh, checked with MuPAD
+
+------------------------------------------------------------------------
+r4664 | zimmerma | 2007-07-20 11:04:14 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/asin
+
+data file for mpfr_asin, checked with MuPAD using CheckData.mu
+
+------------------------------------------------------------------------
+r4663 | zimmerma | 2007-07-20 10:13:10 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/acosh
+
+data file for mpfr_acosh, checked with MuPAD using CheckData.mu
+
+------------------------------------------------------------------------
+r4662 | zimmerma | 2007-07-20 10:12:37 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/data/CheckData.mu
+
+improved output
+
+------------------------------------------------------------------------
+r4661 | zimmerma | 2007-07-20 10:05:11 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data/CheckData.mu
+
+MuPAD file to check a data file
+
+------------------------------------------------------------------------
+r4658 | vlefevre | 2007-07-20 00:18:14 +0000 (Fri, 20 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/free_cache.c
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+
+Renamed mpfr_l2b as __gmpfr_l2b for consistency.
+
+------------------------------------------------------------------------
+r4657 | zimmerma | 2007-07-19 19:49:15 +0000 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-longlong.h
+
+patch from Brian Gladman to build mpfr.dll
+
+------------------------------------------------------------------------
+r4656 | zimmerma | 2007-07-19 16:07:58 +0000 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/data/acos
+ M /trunk/tests/data/gonnet.mpl
+
+added copyright information about Gonnet's package
+
+------------------------------------------------------------------------
+r4655 | zimmerma | 2007-07-19 16:03:38 +0000 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+modified data_check() to allow comment lines starting with #
+
+------------------------------------------------------------------------
+r4654 | zimmerma | 2007-07-19 14:55:47 +0000 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tests.c
+
+new (experimental) mechanism to check data files (see example in tacos.c)
+
+------------------------------------------------------------------------
+r4653 | zimmerma | 2007-07-19 14:54:49 +0000 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ A /trunk/tests/data
+ A /trunk/tests/data/acos
+ A /trunk/tests/data/gonnet.mpl
+
+new directory for test data
+
+------------------------------------------------------------------------
+r4652 | zimmerma | 2007-07-19 10:52:00 +0000 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+
+added test for inexact flag (bug fixed in r4630)
+
+------------------------------------------------------------------------
+r4651 | vlefevre | 2007-07-18 23:09:35 +0000 (Wed, 18 Jul 2007) | 4 lines
+Changed paths:
+ M /trunk/atan2.c
+ M /trunk/erfc.c
+
+erfc.c, atan2.c: added missing "MPFR_SAVE_EXPO_FREE (expo);" before
+ "return mpfr_underflow (...);".
+erfc.c: replaced a goto by an else.
+
+------------------------------------------------------------------------
+r4650 | zimmerma | 2007-07-18 16:24:08 +0000 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/atan2.c
+
+now deal with underflow in y/x (remains to deal with overflow)
+
+------------------------------------------------------------------------
+r4649 | zimmerma | 2007-07-18 16:19:31 +0000 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+now can specify output base when argc > 1
+
+------------------------------------------------------------------------
+r4648 | zimmerma | 2007-07-18 16:18:14 +0000 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tlgamma.c
+
+MPFR_EQUAL -> mpfr_equal_p
+
+------------------------------------------------------------------------
+r4647 | zimmerma | 2007-07-18 15:48:57 +0000 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/erfc.c
+ M /trunk/tests/terf.c
+
+fixed problem with erfc() near underflow region
+
+------------------------------------------------------------------------
+r4646 | zimmerma | 2007-07-18 13:51:07 +0000 (Wed, 18 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/atan2.c
+ M /trunk/tests/tatan.c
+
+atan2.c: quick-and-dirty fix for atan2(y,1)
+tests/tatan.c: fix tests from Christopher [x and y were interchanged]
+
+------------------------------------------------------------------------
+r4645 | zimmerma | 2007-07-18 12:19:22 +0000 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+added test from Ch. Creutzig
+
+------------------------------------------------------------------------
+r4644 | zimmerma | 2007-07-18 08:23:30 +0000 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+apply patch suggested in bug #3604
+
+------------------------------------------------------------------------
+r4643 | zimmerma | 2007-07-17 14:30:00 +0000 (Tue, 17 Jul 2007) | 4 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/tests/tlgamma.c
+
+previous bug fix for tiny negative inputs in mpfr_lgamma was incorrect:
+result was NaN, but this was not detected by the tests since mpfr_cmp (y, NaN)
+is always true!
+
+------------------------------------------------------------------------
+r4642 | vlefevre | 2007-07-17 13:14:21 +0000 (Tue, 17 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/strtofr.c
+
+Added comments and fixed an indentation bug.
+
+------------------------------------------------------------------------
+r4641 | zimmerma | 2007-07-17 06:26:24 +0000 (Tue, 17 Jul 2007) | 4 lines
+Changed paths:
+ M /trunk/cos.c
+
+in reconstruction after computation of cos(x/2^k) for reduced argument,
+it may be that cos(x) is zero to the working precision. Then restart Ziv's
+algorithm with a larger precision.
+
+------------------------------------------------------------------------
+r4640 | zimmerma | 2007-07-16 12:51:17 +0000 (Mon, 16 Jul 2007) | 4 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/tests/tlgamma.c
+
+lngamma.c: fix for small inputs
+tlgamma.c: added more tests from Kaveh Ghazi
+
+
+------------------------------------------------------------------------
+r4639 | zimmerma | 2007-07-16 11:22:13 +0000 (Mon, 16 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/sin_cos.c
+ M /trunk/tests/ttan.c
+
+sin_cos.c: 2nd arg of 1st mpfr_can_round call was wrong
+ttan.c: fixed wrong reference value
+
+------------------------------------------------------------------------
+r4638 | zimmerma | 2007-07-16 06:58:08 +0000 (Mon, 16 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added comment about sinpi, etc.
+
+------------------------------------------------------------------------
+r4637 | zimmerma | 2007-07-15 09:09:10 +0000 (Sun, 15 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/ttan.c
+
+added new test, and re-enabled test that was too slow
+
+------------------------------------------------------------------------
+r4636 | zimmerma | 2007-07-14 07:30:37 +0000 (Sat, 14 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+removed MPFR_CHECK_TINY, added MPFR_CHECK_MAX
+
+------------------------------------------------------------------------
+r4635 | vlefevre | 2007-07-10 08:52:50 +0000 (Tue, 10 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/terf.c
+
+terf.c: added testcase for bug reported by Christopher Creutzig.
+
+------------------------------------------------------------------------
+r4633 | vlefevre | 2007-07-09 11:41:04 +0000 (Mon, 09 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/init2.c
+
+Removed a #include that was probably added by mistake in r2590.
+
+------------------------------------------------------------------------
+r4632 | vlefevre | 2007-07-09 11:39:29 +0000 (Mon, 09 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/abort_prec_max.c
+ M /trunk/cos.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/fma.c
+ M /trunk/fms.c
+ M /trunk/free_cache.c
+ M /trunk/get_d64.c
+ M /trunk/get_si.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/init2.c
+ M /trunk/inp_str.c
+ M /trunk/logging.c
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-impl.h
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/print_raw.c
+ M /trunk/remquo.c
+ M /trunk/set_d64.c
+ M /trunk/set_uj.c
+ M /trunk/strtofr.c
+ M /trunk/tuneup.c
+ M /trunk/ui_pow.c
+ M /trunk/zeta.c
+
+<stdio.h> and <limits.h> are now included unconditionally in mpfr-impl.h
+(removed their inclusion from the C files for consistency).
+
+------------------------------------------------------------------------
+r4630 | zimmerma | 2007-07-04 10:07:31 +0000 (Wed, 04 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+ternary flag was wrong in case s=1 or -1 and rounding up/nearest
+
+------------------------------------------------------------------------
+r4629 | zimmerma | 2007-07-04 09:32:23 +0000 (Wed, 04 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/tan.c
+
+updated algorithms.tex with new additive argument reduction for sin/cos/tan
+
+------------------------------------------------------------------------
+r4628 | vlefevre | 2007-07-03 23:35:05 +0000 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+lngamma.c: reformat and replaced mpfr_cmp(...) == 0 by mpfr_equal_p.
+
+------------------------------------------------------------------------
+r4626 | zimmerma | 2007-07-03 19:12:40 +0000 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/free_cache.c
+
+changed stdlib to stdio for NULL (see README.dev)
+
+------------------------------------------------------------------------
+r4625 | zimmerma | 2007-07-03 19:10:33 +0000 (Tue, 03 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/tests/tlgamma.c
+
+fixed bug in tlgamma and added test (need to implement Ziv's strategy in
+tiny case)
+
+------------------------------------------------------------------------
+r4624 | zimmerma | 2007-07-03 18:45:28 +0000 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/free_cache.c
+
+added missing include
+
+------------------------------------------------------------------------
+r4622 | vlefevre | 2007-07-03 16:11:39 +0000 (Tue, 03 Jul 2007) | 7 lines
+Changed paths:
+ M /trunk/free_cache.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tests.c
+
+Fixed the bug reported by David Billinghurst to the MPFR mailing-list
+on 2007-07-03 (memory leaks under some conditions):
+ * moved the free_l2b() function from tests/tests.c to free_cache.c;
+ * mpfr_free_cache() (from free_cache.c) now calls free_l2b();
+ * as a consequence, no longer call free_l2b() in tests_end_mpfr();
+ * documented the behavior in mpfr.texi (under mpfr_free_cache).
+
+------------------------------------------------------------------------
+r4620 | vlefevre | 2007-07-03 15:05:01 +0000 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tj0.c
+
+tj0.c: added testcase from Sisyphus (assertion failed).
+
+------------------------------------------------------------------------
+r4618 | vlefevre | 2007-07-03 13:03:22 +0000 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: explain how to test the library interface compatibility.
+
+------------------------------------------------------------------------
+r4616 | vlefevre | 2007-07-02 23:30:52 +0000 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: mentions patch-libtool and how to apply it.
+
+------------------------------------------------------------------------
+r4615 | vlefevre | 2007-07-02 23:26:01 +0000 (Mon, 02 Jul 2007) | 3 lines
+Changed paths:
+ A /trunk/patch-libtool
+
+Added patch-libtool (patch for aclocal.m4 and configure that comes from
+<http://thread.gmane.org/gmane.comp.gnu.libtool.bugs/5771/focus=5776>).
+
+------------------------------------------------------------------------
+r4614 | vlefevre | 2007-07-02 12:17:08 +0000 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: mention that the shared library is now enabled by default on 2.3.
+
+------------------------------------------------------------------------
+r4610 | vlefevre | 2007-07-02 10:44:17 +0000 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated item 2 of "To make a release".
+
+------------------------------------------------------------------------
+r4608 | vlefevre | 2007-07-02 10:39:46 +0000 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/mpfr.texi
+
+Reformat.
+
+------------------------------------------------------------------------
+r4607 | vlefevre | 2007-07-02 00:41:32 +0000 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/VERSION
+ M /trunk/configure.in
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/version.c
+
+Updated version to 2.4.0-dev.
+
+------------------------------------------------------------------------
+r4605 | vlefevre | 2007-07-02 00:32:27 +0000 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+ChangeLog update.
+
+------------------------------------------------------------------------
+r4604 | vlefevre | 2007-07-02 00:31:13 +0000 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: update.
+
+------------------------------------------------------------------------
+r4603 | vlefevre | 2007-07-01 23:17:57 +0000 (Sun, 01 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Makefile.am: updated comment concerning -version-info.
+
+------------------------------------------------------------------------
+r4602 | vlefevre | 2007-07-01 23:01:10 +0000 (Sun, 01 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/TODO
+ A /trunk/fms.c (from /trunk/fma.c:4598)
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tfms.c (from /trunk/tests/tfma.c:4601)
+
+Added mpfr_fms based on mpfr_fma.
+
+------------------------------------------------------------------------
+r4601 | vlefevre | 2007-07-01 22:45:08 +0000 (Sun, 01 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: added a space.
+
+------------------------------------------------------------------------
+r4600 | vlefevre | 2007-07-01 22:38:39 +0000 (Sun, 01 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: typo.
+
+------------------------------------------------------------------------
+r4599 | vlefevre | 2007-07-01 22:20:09 +0000 (Sun, 01 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+Reformat.
+
+------------------------------------------------------------------------
+r4598 | vlefevre | 2007-07-01 22:14:15 +0000 (Sun, 01 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+fma.c: minor changes for consistency with the future fms.
+
+------------------------------------------------------------------------
+r4597 | vlefevre | 2007-07-01 21:52:21 +0000 (Sun, 01 Jul 2007) | 5 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/fma.c
+ M /trunk/tests/tfma.c
+
+Completed the implementation of mpfr_fma (except in some corner cases
+where overflows/underflows and huge precisions are involved at the
+same time). Added underflow tests. Removed item from the BUGS file
+(the remaining problems more or less correspond to the first item).
+
+------------------------------------------------------------------------
+r4596 | vlefevre | 2007-07-01 03:10:06 +0000 (Sun, 01 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+
+Untabified.
+
+------------------------------------------------------------------------
+r4595 | vlefevre | 2007-07-01 01:58:17 +0000 (Sun, 01 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: added overflow test to test_underflow.
+
+------------------------------------------------------------------------
+r4594 | vlefevre | 2007-07-01 01:36:04 +0000 (Sun, 01 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/fma.c
+ M /trunk/tests/tfma.c
+
+fma.c: implemented the main cases where x * y underflows.
+tests/tfma.c: fixed overflow tests and added underflow tests.
+
+------------------------------------------------------------------------
+r4593 | vlefevre | 2007-06-30 02:11:43 +0000 (Sat, 30 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+NEWS: update.
+
+------------------------------------------------------------------------
+r4592 | vlefevre | 2007-06-29 23:36:34 +0000 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: updated item on mpfr_fma.
+
+------------------------------------------------------------------------
+r4591 | vlefevre | 2007-06-29 23:32:29 +0000 (Fri, 29 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/fma.c
+
+fma.c: completed the cases where x*y/4 needs to be used, except the very
+particular cases where an underflow occurs, that remain to be done.
+
+------------------------------------------------------------------------
+r4590 | vlefevre | 2007-06-29 13:35:03 +0000 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: fixed a printf.
+
+------------------------------------------------------------------------
+r4589 | vlefevre | 2007-06-29 13:32:20 +0000 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+fma.c: added an assertion.
+
+------------------------------------------------------------------------
+r4588 | vlefevre | 2007-06-29 13:30:30 +0000 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: fixed overflow tests.
+
+------------------------------------------------------------------------
+r4587 | vlefevre | 2007-06-29 12:24:40 +0000 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: check NaN in test_overflow2.
+
+------------------------------------------------------------------------
+r4586 | vlefevre | 2007-06-29 12:19:09 +0000 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+fma.c: updated a comment.
+
+------------------------------------------------------------------------
+r4585 | vlefevre | 2007-06-29 12:14:55 +0000 (Fri, 29 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: added more overflow tests (needed to distinguish the cases
+where z/4 underflows or not -- see fma.c).
+
+------------------------------------------------------------------------
+r4584 | vlefevre | 2007-06-29 12:06:13 +0000 (Fri, 29 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: added tests (-> assertion failed because mpfr_fma implementation
+isn't complete).
+
+------------------------------------------------------------------------
+r4583 | vlefevre | 2007-06-28 23:01:22 +0000 (Thu, 28 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/acos.c
+
+acos.c: disabled change from r3145 ("Optimize mpfr_acos by choosing
+a better initial precision.") that was buggy.
+BUGS: removed mpfr_acos bug.
+
+------------------------------------------------------------------------
+r4582 | vlefevre | 2007-06-28 22:40:59 +0000 (Thu, 28 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: updated item on the mpfr_acos bug.
+
+------------------------------------------------------------------------
+r4581 | vlefevre | 2007-06-28 22:38:10 +0000 (Thu, 28 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: updated item on the mpfr_acos test (the bug wasn't visible on
+32-bit machines due to an integer overflow, but the result should
+have been correct anyway).
+
+------------------------------------------------------------------------
+r4580 | vlefevre | 2007-06-28 22:27:09 +0000 (Thu, 28 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/acos.c
+
+acos.c: fixed integer overflows; to avoid undefined behavior, I had
+to add an assertion that is not always satisfied (the code needs to
+be rewritten to take tiny arguments into account).
+
+------------------------------------------------------------------------
+r4579 | vlefevre | 2007-06-28 17:30:39 +0000 (Thu, 28 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: update (mpfr_cot has just been fixed).
+
+------------------------------------------------------------------------
+r4578 | vlefevre | 2007-06-28 17:29:27 +0000 (Thu, 28 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/cot.c
+ M /trunk/tests/tcot.c
+
+cot.c: implemented the case |x| = 2^emin.
+tests/tcot.c: added tests for this case, in 3 exponent ranges
+(as this is an overflow limit).
+
+------------------------------------------------------------------------
+r4577 | vlefevre | 2007-06-28 17:00:15 +0000 (Thu, 28 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+Fixed bug in div.c: rnd_mode could be modified (MPFR_INVERT_RND), but
+the original value was assumed in case of underflow or overflow.
+
+------------------------------------------------------------------------
+r4576 | vlefevre | 2007-06-28 16:40:26 +0000 (Thu, 28 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+tdiv.c: added a test showing another bug in mpfr_div.
+
+------------------------------------------------------------------------
+r4575 | vlefevre | 2007-06-28 11:54:41 +0000 (Thu, 28 Jun 2007) | 5 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/cot.c
+
+cot.c: use MPFR_SAVE_EXPO_UPDATE_FLAGS, but the case +/- 2^emin could
+still be buggy with the current code; added a MPFR_ASSERTN (0) until
+it is implemented.
+BUGS: updated item on mpfr_cot.
+
+------------------------------------------------------------------------
+r4574 | zimmerma | 2007-06-28 07:59:28 +0000 (Thu, 28 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/tan.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/ttan.c
+
+fixed several problems with huge arguments in periodic functions
+mpfr_sin: complete rewrite, using mpfr_remainder for argument reduction
+mpfr_sin_cos: ditto
+
+------------------------------------------------------------------------
+r4573 | zimmerma | 2007-06-25 13:29:38 +0000 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/tests/tcos.c
+
+fixed stupid bug (subtraction of unsigned longs)
+
+------------------------------------------------------------------------
+r4572 | zimmerma | 2007-06-25 09:48:43 +0000 (Mon, 25 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tgeneric.c
+
+cos.c: implemented argument reduction by 2Pi
+tcos.c/tgeneric.c: reduce large exponent used when MPFR_CHECK_MAX is defined
+
+------------------------------------------------------------------------
+r4571 | vlefevre | 2007-06-22 14:45:28 +0000 (Fri, 22 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: added bugs.
+
+------------------------------------------------------------------------
+r4570 | vlefevre | 2007-06-22 12:15:03 +0000 (Fri, 22 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/coth.c
+ M /trunk/sech.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tsech.c
+
+coth.c, sech.c: a rounding mode was incorrect.
+tests/tcoth.c: added underflowed_cothinf test.
+tests/tsech.c: added overflowed_sech0 test.
+
+------------------------------------------------------------------------
+r4569 | vlefevre | 2007-06-22 00:12:18 +0000 (Fri, 22 Jun 2007) | 8 lines
+Changed paths:
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/gen_inverse.h
+ M /trunk/sec.c
+ M /trunk/tests/tsec.c
+
+* gen_inverse.h: ACTION_TINY must be called after MPFR_SAVE_EXPO_MARK
+ (this is necessary for some functions). Moved MPFR_SAVE_EXPO_FREE
+ after the "end:" label.
+* coth.c, csc.c, csch.c: as a consequence, MPFR_SAVE_EXPO_UPDATE_FLAGS
+ had to be added before "goto end;".
+* sec.c: a rounding mode was incorrect.
+* tests/tsec.c: added overflowed_sec0 test.
+
+------------------------------------------------------------------------
+r4568 | vlefevre | 2007-06-21 23:36:19 +0000 (Thu, 21 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/sin_cos.c
+ M /trunk/tests/tsin_cos.c
+
+sin_cos.c: fixed a bug for x = 0 in reduced exponent range.
+tests/tsin_cos.c: added overflowed_sin_cos0 test.
+
+------------------------------------------------------------------------
+r4567 | vlefevre | 2007-06-21 14:32:14 +0000 (Thu, 21 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: Some functions do not use MPFR_SAVE_EXPO_* macros, thus do not
+behave correctly in a reduced exponent range.
+
+------------------------------------------------------------------------
+r4566 | vlefevre | 2007-06-21 14:28:13 +0000 (Thu, 21 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/factorial.c
+ M /trunk/tests/tfactorial.c
+
+factorial.c: a rounding mode was incorrect.
+tests/tfactorial.c: added overflowed_fac0 test.
+
+------------------------------------------------------------------------
+r4565 | vlefevre | 2007-06-21 14:16:17 +0000 (Thu, 21 Jun 2007) | 5 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/tests/texp2.c
+
+exp2.c: use MPFR_SMALL_INPUT_AFTER_SAVE_EXPO instead of
+MPFR_FAST_COMPUTE_IF_SMALL_INPUT since 1 (__gmpfr_one) isn't
+necessarily representable.
+tests/texp2.c: added overflowed_exp2_0 test.
+
+------------------------------------------------------------------------
+r4564 | vlefevre | 2007-06-21 13:59:38 +0000 (Thu, 21 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/tests/texp.c
+
+exp.c: fixed problems in reduced exponent range.
+tests/texp.c: added overflowed_exp0 test.
+
+------------------------------------------------------------------------
+r4563 | vlefevre | 2007-06-21 13:43:03 +0000 (Thu, 21 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+exp.c bug fix: a rounding mode was incorrect.
+
+------------------------------------------------------------------------
+r4562 | vlefevre | 2007-06-21 13:40:55 +0000 (Thu, 21 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+
+tcos.c: fixed error message in overflowed_cos0 test.
+
+------------------------------------------------------------------------
+r4561 | vlefevre | 2007-06-21 13:38:44 +0000 (Thu, 21 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+
+tcos.c: removed an obsolete comment from the overflowed_cos0 test.
+
+------------------------------------------------------------------------
+r4560 | vlefevre | 2007-06-21 13:35:45 +0000 (Thu, 21 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+
+tcos.c: improved overflowed_cos0 test.
+
+------------------------------------------------------------------------
+r4559 | vlefevre | 2007-06-21 12:49:03 +0000 (Thu, 21 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/tests/tget_str.c
+
+get_str.c: use MPFR_SAVE_EXPO.
+tests/tget_str.c: enabled the test with a reduced exponent range.
+
+------------------------------------------------------------------------
+r4558 | vlefevre | 2007-06-21 12:13:06 +0000 (Thu, 21 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+tget_str.c: added a test (disabled by default) with emax = 0.
+
+------------------------------------------------------------------------
+r4557 | vlefevre | 2007-06-21 11:53:16 +0000 (Thu, 21 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/add1sp.c
+ M /trunk/mul.c
+ M /trunk/sub1sp.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+
+Corrected mpfr_inits, mpfr_inits2 and mpfr_clears calls with NULL
+argument (-> (void *) 0).
+
+------------------------------------------------------------------------
+r4556 | vlefevre | 2007-06-21 11:38:33 +0000 (Thu, 21 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+tget_str.c: reformatted/corrected a function.
+
+------------------------------------------------------------------------
+r4555 | vlefevre | 2007-06-21 11:30:38 +0000 (Thu, 21 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/ttanh.c
+
+Tests: when restoring the exponent range, save emin/emax first instead
+of using MPFR_EMIN_MIN/MPFR_EMAX_MAX (which have no longer corresponded
+to the default exponent range since quite a long time).
+
+------------------------------------------------------------------------
+r4554 | vlefevre | 2007-06-21 11:01:46 +0000 (Thu, 21 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: update.
+
+------------------------------------------------------------------------
+r4553 | vlefevre | 2007-06-20 13:22:49 +0000 (Wed, 20 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/atan.c
+ M /trunk/exp3.c
+ M /trunk/gen_inverse.h
+ M /trunk/jn.c
+ M /trunk/lngamma.c
+ M /trunk/mpfr.h
+ M /trunk/remquo.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sqr.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tremquo.c
+ M /trunk/tests/tyn.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/zeta_ui.c
+
+Untabified and removed trailing spaces.
+
+------------------------------------------------------------------------
+r4552 | vlefevre | 2007-06-20 13:12:41 +0000 (Wed, 20 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/generic.c
+ M /trunk/mpfr-gmp.h
+
+Bug fix: preprocessor # must be in the first column.
+
+------------------------------------------------------------------------
+r4551 | vlefevre | 2007-06-20 12:29:26 +0000 (Wed, 20 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/remquo.c
+
+remquo.c bug fix: preprocessor # must be in the first column.
+
+------------------------------------------------------------------------
+r4550 | vlefevre | 2007-06-20 11:58:25 +0000 (Wed, 20 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+
+tcos.c: fixed and improved the overflowed_cos0 test.
+
+------------------------------------------------------------------------
+r4549 | vlefevre | 2007-06-20 11:38:47 +0000 (Wed, 20 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+cos.c bug fix: a rounding mode was incorrect.
+
+------------------------------------------------------------------------
+r4548 | vlefevre | 2007-06-20 11:32:56 +0000 (Wed, 20 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+
+cos.c: use MPFR_SMALL_INPUT_AFTER_SAVE_EXPO instead of
+MPFR_FAST_COMPUTE_IF_SMALL_INPUT.
+
+------------------------------------------------------------------------
+r4547 | vlefevre | 2007-06-20 11:27:41 +0000 (Wed, 20 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+cos.c: untabified.
+
+------------------------------------------------------------------------
+r4546 | vlefevre | 2007-06-20 10:55:52 +0000 (Wed, 20 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+
+tcos.c: added tests for x very small and emax = 0 (some of them
+currently fail).
+
+------------------------------------------------------------------------
+r4545 | vlefevre | 2007-06-20 10:06:56 +0000 (Wed, 20 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Added a comment concerning the MPFR_SMALL_INPUT_AFTER_SAVE_EXPO macro.
+
+------------------------------------------------------------------------
+r4544 | vlefevre | 2007-06-20 10:03:03 +0000 (Wed, 20 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/expm1.c
+ M /trunk/mpfr-impl.h
+
+Added MPFR_SMALL_INPUT_AFTER_SAVE_EXPO macro; updated expm1.c to use
+this variant (and moved MPFR_SAVE_EXPO_MARK after the test ex < 0).
+
+------------------------------------------------------------------------
+r4543 | vlefevre | 2007-06-19 15:17:21 +0000 (Tue, 19 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Documented log(-0).
+
+------------------------------------------------------------------------
+r4542 | vlefevre | 2007-06-19 15:11:21 +0000 (Tue, 19 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+
+Added a few tests of log functions.
+
+------------------------------------------------------------------------
+r4541 | vlefevre | 2007-06-18 13:01:03 +0000 (Mon, 18 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated Section "Floating-Point Values on Special Numbers".
+
+------------------------------------------------------------------------
+r4540 | vlefevre | 2007-06-12 10:54:06 +0000 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: allow generic tests to run with a restricted exponent range.
+
+------------------------------------------------------------------------
+r4539 | vlefevre | 2007-06-12 10:51:17 +0000 (Tue, 12 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/expm1.c
+
+expm1.c: fixed bug for x = -max_value due to an intermediate overflow
+(flags were incorrect); at the same time, potential problems due to a
+restricted exponent range are also fixed.
+
+------------------------------------------------------------------------
+r4538 | vlefevre | 2007-06-12 09:17:33 +0000 (Tue, 12 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tgeneric.c: check the function on large arguments (±maximum_value)
+when the MPFR_CHECK_MAX environment variable is defined.
+
+------------------------------------------------------------------------
+r4537 | vlefevre | 2007-06-11 13:40:14 +0000 (Mon, 11 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tlgamma.c
+
+tests/tlgamma.c: re-enabled sign checking.
+
+------------------------------------------------------------------------
+r4536 | zimmerma | 2007-06-11 09:30:08 +0000 (Mon, 11 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/tests/tlgamma.c
+
+fixed problem with mpfr_lgamma for tiny negative input (and fixed use of
+generic test)
+
+------------------------------------------------------------------------
+r4535 | vlefevre | 2007-06-05 20:50:07 +0000 (Tue, 05 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+[mpfr.texi] Small change in new Section "Floating-Point Values on
+Special Numbers" (suggested by Paul).
+
+------------------------------------------------------------------------
+r4534 | zimmerma | 2007-06-05 19:41:43 +0000 (Tue, 05 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+ M /trunk/zeta.c
+
+fixed bug for tiny negative input (and added corresponding test)
+
+------------------------------------------------------------------------
+r4533 | vlefevre | 2007-06-05 11:06:57 +0000 (Tue, 05 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: Mulder -> Mulders.
+
+------------------------------------------------------------------------
+r4532 | zimmerma | 2007-06-04 11:26:10 +0000 (Mon, 04 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added test for "Witty's bug" on 64-bit machines
+
+------------------------------------------------------------------------
+r4531 | vlefevre | 2007-06-04 11:19:33 +0000 (Mon, 04 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+div.c: GNU coding style.
+
+------------------------------------------------------------------------
+r4530 | zimmerma | 2007-06-04 11:04:30 +0000 (Mon, 04 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/tests/tdiv.c
+
+tdiv.c: added missing mpfr_clear's, and spaces before function calls
+div.c: fixed bug found by Carl Witty, and added more comments
+
+------------------------------------------------------------------------
+r4529 | vlefevre | 2007-06-04 10:55:47 +0000 (Mon, 04 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+tdiv.c: oops... the result should be 1.
+
+------------------------------------------------------------------------
+r4528 | vlefevre | 2007-06-04 10:50:42 +0000 (Mon, 04 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+tdiv.c: added test from Carl Witty's bug report on 2007-06-03.
+
+------------------------------------------------------------------------
+r4527 | vlefevre | 2007-06-01 13:48:35 +0000 (Fri, 01 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated Section "Floating-Point Values on Special Numbers".
+
+------------------------------------------------------------------------
+r4526 | vlefevre | 2007-06-01 13:31:14 +0000 (Fri, 01 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated Section "Floating-Point Values on Special Numbers".
+
+------------------------------------------------------------------------
+r4525 | vlefevre | 2007-06-01 13:29:33 +0000 (Fri, 01 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated month.
+
+------------------------------------------------------------------------
+r4524 | vlefevre | 2007-06-01 13:01:20 +0000 (Fri, 01 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added @: after "resp." (when it was missing).
+
+------------------------------------------------------------------------
+r4523 | vlefevre | 2007-05-31 15:51:37 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Started a new section "Floating-Point Values on Special Numbers".
+
+------------------------------------------------------------------------
+r4522 | vlefevre | 2007-05-31 15:47:00 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: inf -> Inf for consistency.
+
+------------------------------------------------------------------------
+r4521 | vlefevre | 2007-05-31 15:05:19 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi @deftypefun correction: void * -> {void *} (for the PDF).
+
+------------------------------------------------------------------------
+r4520 | vlefevre | 2007-05-31 15:02:11 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: consistency changes in section titles; made titles unique.
+
+------------------------------------------------------------------------
+r4519 | vlefevre | 2007-05-31 12:16:06 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/set_d64.c
+
+set_d64.c: replaced an "if" by a "#if" to avoid a gcc warning.
+
+------------------------------------------------------------------------
+r4518 | vlefevre | 2007-05-31 12:11:03 +0000 (Thu, 31 May 2007) | 4 lines
+Changed paths:
+ M /trunk/get_d64.c
+ M /trunk/set_d64.c
+
+get_d64.c: use BITS_PER_MP_LIMB instead of GMP_BITS_PER_LIMB (which
+does not seem to exist).
+set_d64.c: use BITS_PER_MP_LIMB instead of mp_bits_per_limb.
+
+------------------------------------------------------------------------
+r4517 | vlefevre | 2007-05-31 11:50:08 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/get_d64.c
+ M /trunk/set_d64.c
+
+get_d64.c, set_d64.c: improved code to avoid some warnings.
+
+------------------------------------------------------------------------
+r4516 | vlefevre | 2007-05-31 11:39:23 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/get_d64.c
+ M /trunk/set_d64.c
+
+Untabified get_d64.c and set_d64.c.
+
+------------------------------------------------------------------------
+r4515 | vlefevre | 2007-05-31 11:33:55 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/get_d64.c
+
+get_d64.c: added missing #include.
+
+------------------------------------------------------------------------
+r4514 | vlefevre | 2007-05-31 09:20:43 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: update.
+
+------------------------------------------------------------------------
+r4513 | vlefevre | 2007-05-31 09:16:38 +0000 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: improved error message when thread safe is not supported.
+
+------------------------------------------------------------------------
+r4512 | vlefevre | 2007-05-30 15:27:10 +0000 (Wed, 30 May 2007) | 3 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: say that relative paths in configure options are not supported
+(autoconf doesn't seem to have support for them).
+
+------------------------------------------------------------------------
+r4511 | vlefevre | 2007-05-30 12:04:22 +0000 (Wed, 30 May 2007) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/mpfr.texi
+ M /trunk/tests/tsgn.c
+
+Documented the new behavior of mpfr_sgn (in fact, it was already partly
+required by the tsgn.c tests!) and added new mpfr_sgn tests.
+
+------------------------------------------------------------------------
+r4510 | vlefevre | 2007-05-30 11:21:32 +0000 (Wed, 30 May 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: added an item about the behavior of mpfr_sgn on NaN.
+
+------------------------------------------------------------------------
+r4509 | vlefevre | 2007-05-30 11:13:23 +0000 (Wed, 30 May 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tgeneric.c: no longer check the MPFR_CHECK_TINY environment variable
+as all the bugs related to tiny arguments have been fixed.
+
+------------------------------------------------------------------------
+r4508 | vlefevre | 2007-05-30 10:17:09 +0000 (Wed, 30 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: corrections following the remarks by Nathalie Revol.
+
+------------------------------------------------------------------------
+r4507 | vlefevre | 2007-05-29 23:11:06 +0000 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/yn.c
+
+yn.c: untabify.
+
+------------------------------------------------------------------------
+r4506 | zimmerma | 2007-05-29 22:02:35 +0000 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/yn.c
+
+fix for small inputs in y1
+
+------------------------------------------------------------------------
+r4505 | vlefevre | 2007-05-29 21:31:22 +0000 (Tue, 29 May 2007) | 4 lines
+Changed paths:
+ M /trunk/erf.c
+ M /trunk/lngamma.c
+ M /trunk/mpfr-impl.h
+
+Defined new macros SIGN and SAME_SIGN in mpfr-impl.h to canonicalize
+the ternary value and to compare such values. Use SAME_SIGN in erf.c
+and lngamma.c.
+
+------------------------------------------------------------------------
+r4504 | zimmerma | 2007-05-29 21:04:57 +0000 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/yn.c
+
+fixed problem of tiny arguments for y0
+
+------------------------------------------------------------------------
+r4503 | zimmerma | 2007-05-29 16:44:02 +0000 (Tue, 29 May 2007) | 4 lines
+Changed paths:
+ M /trunk/erf.c
+ M /trunk/lngamma.c
+
+lngamma.c: fixed problem of tiny inputs in lngamma (still remains lgamma
+ to deal with)
+erf.c: small correction (inexact flags might have been inexact :-)
+
+------------------------------------------------------------------------
+r4502 | zimmerma | 2007-05-29 12:24:20 +0000 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/csch.c
+ M /trunk/jn.c
+
+fixed tiny input problem with csch, j0, j1
+
+------------------------------------------------------------------------
+r4501 | zimmerma | 2007-05-29 10:09:00 +0000 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/cot.c
+
+added special code for tiny inputs
+
+------------------------------------------------------------------------
+r4500 | vlefevre | 2007-05-29 09:52:12 +0000 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tgeneric_ui.c
+
+tgeneric_ui.c: no longer check the MPFR_CHECK_TINY environment variable.
+
+------------------------------------------------------------------------
+r4499 | vlefevre | 2007-05-29 09:33:56 +0000 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/erf.c
+
+erf.c: removed workaround to mpfr_div_ui bug, as the bug is now fixed.
+
+------------------------------------------------------------------------
+r4498 | vlefevre | 2007-05-29 09:29:02 +0000 (Tue, 29 May 2007) | 5 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+div_ui.c:
+ * Cleaned up the use of the sh variable (there was a useless sh = 0,
+ so I'm not sure that there isn't a bug...).
+ * Added underflow check.
+
+------------------------------------------------------------------------
+r4497 | vlefevre | 2007-05-29 08:48:49 +0000 (Tue, 29 May 2007) | 4 lines
+Changed paths:
+ M /trunk/tests/tgeneric_ui.c
+
+Added check of tiny arguments to tgeneric_ui.c (if MPFR_CHECK_TINY is
+defined, like in tgeneric.c); mpfr_div_ui currently fails due to the
+lack of underflow checking.
+
+------------------------------------------------------------------------
+r4496 | zimmerma | 2007-05-29 08:12:30 +0000 (Tue, 29 May 2007) | 5 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/erf.c
+
+README.dev: fixed typo
+erf.c: implemented special case for tiny x, and partially get rid of double
+ usage
+implemented
+
+------------------------------------------------------------------------
+r4495 | vlefevre | 2007-05-28 23:11:56 +0000 (Mon, 28 May 2007) | 4 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/cos.c
+ M /trunk/exp2.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/sinh.c
+
+MPFR_RET (mpfr_check_range (...)) -> return mpfr_check_range (...)
+as mpfr_check_range already handles the inexact flag.
+Reformatting (removed trailing spaces, untabified).
+
+------------------------------------------------------------------------
+r4494 | zimmerma | 2007-05-28 21:51:11 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/sech.c
+
+fixed problem of tiny input
+
+------------------------------------------------------------------------
+r4493 | zimmerma | 2007-05-28 21:44:37 +0000 (Mon, 28 May 2007) | 3 lines
+Changed paths:
+ M /trunk/coth.c
+ M /trunk/csc.c
+
+fixed problem of tiny input for coth (and new fix again for csc, which
+takes into account the sign of the input)
+
+------------------------------------------------------------------------
+r4492 | zimmerma | 2007-05-28 21:23:23 +0000 (Mon, 28 May 2007) | 3 lines
+Changed paths:
+ M /trunk/csc.c
+ M /trunk/gen_inverse.h
+ M /trunk/sec.c
+
+fixed problem of tiny inputs in mpfr_sec and mpfr_csc,
+by adding a SPECIAL_TINY macro in gen_inverse.h
+
+------------------------------------------------------------------------
+r4491 | zimmerma | 2007-05-28 20:56:41 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+ M /trunk/zeta.c
+
+the test for the tiny input case was too optimistic: fixed and added test.
+
+------------------------------------------------------------------------
+r4490 | zimmerma | 2007-05-28 20:24:23 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+fixed case of tiny input
+
+------------------------------------------------------------------------
+r4489 | zimmerma | 2007-05-28 19:54:27 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+fixed problem for tiny arguments
+
+------------------------------------------------------------------------
+r4488 | zimmerma | 2007-05-28 18:33:26 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/cosh.c
+
+added MPFR_FAST_COMPUTE_IF_SMALL_INPUT call
+
+------------------------------------------------------------------------
+r4487 | zimmerma | 2007-05-28 18:19:08 +0000 (Mon, 28 May 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/round_near_x.c
+
+changed 1st-order Taylor term from x to v to avoid confusion with the
+argument x of the function f(x), and fixed some typos
+
+------------------------------------------------------------------------
+r4486 | zimmerma | 2007-05-28 17:15:11 +0000 (Mon, 28 May 2007) | 3 lines
+Changed paths:
+ M /trunk/exp2.c
+
+fixed direction of rounding for MPFR_FAST_COMPUTE_IF_SMALL_INPUT
+(was wrong for x < 0)
+
+------------------------------------------------------------------------
+r4485 | zimmerma | 2007-05-28 17:02:57 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+fixed typo
+
+------------------------------------------------------------------------
+r4484 | zimmerma | 2007-05-28 16:19:06 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/tests/texp2.c
+
+added call to MPFR_FAST_COMPUTE_IF_SMALL_INPUT in exp2
+
+------------------------------------------------------------------------
+r4483 | zimmerma | 2007-05-28 15:51:00 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+re-enabled MPFR_CHECK_TINY
+
+------------------------------------------------------------------------
+r4482 | zimmerma | 2007-05-28 15:34:10 +0000 (Mon, 28 May 2007) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/mpfr.texi
+
+improved documentation of mpfr_set/get_decimal64 functions
+fixed problem in configure.in (_Decimal64 was tested too early)
+
+------------------------------------------------------------------------
+r4481 | vlefevre | 2007-05-28 15:17:44 +0000 (Mon, 28 May 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: fixed two bugs concerning the timeout (including an
+old one: we need to call getrlimit to initialize rlim_max).
+
+------------------------------------------------------------------------
+r4480 | zimmerma | 2007-05-28 15:07:05 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+new syntax for timeouts
+
+------------------------------------------------------------------------
+r4479 | zimmerma | 2007-05-28 15:06:30 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+fixed typo
+
+------------------------------------------------------------------------
+r4478 | vlefevre | 2007-05-28 13:57:32 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk
+
+Added mkinstalldirs to svn:ignore property.
+
+------------------------------------------------------------------------
+r4477 | vlefevre | 2007-05-28 13:56:33 +0000 (Mon, 28 May 2007) | 5 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/tests/tests.c
+
+Changed --with-tests-timeout into --enable-tests-timeout as documented
+in the autoconf manual (--with-* are for external packages only). When
+this is enabled, environment variable MPFR_TESTS_TIMEOUT allows to
+override the default timeout (use the value 0 to disable timeouts).
+
+------------------------------------------------------------------------
+r4476 | vlefevre | 2007-05-28 11:29:45 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Updated NEWS file.
+
+------------------------------------------------------------------------
+r4475 | vlefevre | 2007-05-28 11:04:00 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: small improvement.
+
+------------------------------------------------------------------------
+r4474 | vlefevre | 2007-05-28 10:37:07 +0000 (Mon, 28 May 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/sgn.c
+ M /trunk/tests/tcmp_ui.c
+
+Fixed a bug in the mpfr_cmp_ui macro occurring on NaN and the constant 0
+by specifying the behavior of mpfr_sgn on NaN.
+
+------------------------------------------------------------------------
+r4473 | vlefevre | 2007-05-28 09:26:07 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: typography corrections concerning "i.e.".
+
+------------------------------------------------------------------------
+r4472 | vlefevre | 2007-05-28 09:17:37 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: consistency changes.
+
+------------------------------------------------------------------------
+r4471 | vlefevre | 2007-05-28 09:11:39 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: more details in Section "Exceptions".
+
+------------------------------------------------------------------------
+r4470 | vlefevre | 2007-05-28 02:12:05 +0000 (Mon, 28 May 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+tgeneric.c: check the function on tiny arguments (±2^(emin-1)) when
+the MPFR_CHECK_TINY environment variable is defined.
+
+------------------------------------------------------------------------
+r4469 | vlefevre | 2007-05-28 00:54:09 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Typo.
+
+------------------------------------------------------------------------
+r4468 | vlefevre | 2007-05-28 00:27:16 +0000 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cos.c
+ M /trunk/erfc.c
+ M /trunk/expm1.c
+ M /trunk/log1p.c
+ M /trunk/mpfr-impl.h
+ M /trunk/round_near_x.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/zeta.c
+
+Avoid integer overflow in MPFR_FAST_COMPUTE_IF_SMALL_INPUT.
+
+------------------------------------------------------------------------
+r4467 | zimmerma | 2007-05-25 21:03:43 +0000 (Fri, 25 May 2007) | 3 lines
+Changed paths:
+ M /trunk/remquo.c
+ M /trunk/tests/tremquo.c
+
+completed implementation of Vincent's algorithm for mpfr_remquo
+all tests now pass again
+
+------------------------------------------------------------------------
+r4466 | zimmerma | 2007-05-24 21:45:25 +0000 (Thu, 24 May 2007) | 3 lines
+Changed paths:
+ M /trunk/remquo.c
+
+new version of mpfr_remainder, using Vincent's algorithm
+(still remains to deal with special arguments, and make mpfr_remquo call it)
+
+------------------------------------------------------------------------
+r4465 | zimmerma | 2007-05-23 22:09:57 +0000 (Wed, 23 May 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added note about fms
+
+------------------------------------------------------------------------
+r4464 | zimmerma | 2007-05-23 21:55:55 +0000 (Wed, 23 May 2007) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+fixed typo
+
+------------------------------------------------------------------------
+r4463 | zimmerma | 2007-05-23 21:26:14 +0000 (Wed, 23 May 2007) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+fixed problem for x integer and rounding to nearest
+
+------------------------------------------------------------------------
+r4462 | zimmerma | 2007-05-23 18:33:35 +0000 (Wed, 23 May 2007) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+workaround for bug when x is very small (check_tiny in tsin)
+
+------------------------------------------------------------------------
+r4461 | vlefevre | 2007-05-22 12:06:00 +0000 (Tue, 22 May 2007) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Updated BUGS (again).
+
+------------------------------------------------------------------------
+r4460 | vlefevre | 2007-05-22 11:50:06 +0000 (Tue, 22 May 2007) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/TODO
+
+Updated BUGS and TODO (mpfr_lgamma has been implemented, but see BUGS,
+and gamma(-integer) with integer >= 1 is defined as NaN).
+
+------------------------------------------------------------------------
+r4459 | vlefevre | 2007-05-22 08:41:00 +0000 (Tue, 22 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+
+tsin.c: check sin on +/- 2^(emin-1) (test by Christopher Creutzig).
+
+------------------------------------------------------------------------
+r4458 | vlefevre | 2007-05-22 08:25:20 +0000 (Tue, 22 May 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+tgamma.c: added test of gamma on some integral values (from Christopher
+Creutzig); this test is enabled only when an argument is provided.
+
+------------------------------------------------------------------------
+r4457 | vlefevre | 2007-05-22 00:29:16 +0000 (Tue, 22 May 2007) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+fma.c: improved comments and simplified the code.
+
+------------------------------------------------------------------------
+r4456 | vlefevre | 2007-05-22 00:11:18 +0000 (Tue, 22 May 2007) | 5 lines
+Changed paths:
+ M /trunk/fma.c
+
+fma.c: implemented exponent range expansion and the main part when the
+multiplication overflows. The following remains to do:
+ * when the multiplication overflows: some corner cases;
+ * when the multiplication underflows: everything.
+
+------------------------------------------------------------------------
+r4455 | vlefevre | 2007-05-21 11:52:33 +0000 (Mon, 21 May 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tlgamma.c
+
+tlgamma.c: I re-enable the generic tests of mpfr_lgamma now, to make
+sure that it is fixed before the 2.3.0 release candidate.
+
+------------------------------------------------------------------------
+r4454 | vlefevre | 2007-05-21 11:49:41 +0000 (Mon, 21 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: added an overflow test (currently fails).
+
+------------------------------------------------------------------------
+r4453 | vlefevre | 2007-05-21 08:44:22 +0000 (Mon, 21 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: whitespace change.
+
+------------------------------------------------------------------------
+r4452 | vlefevre | 2007-05-21 08:43:41 +0000 (Mon, 21 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+tfma.c: added tests on special and exact values.
+
+------------------------------------------------------------------------
+r4451 | zimmerma | 2007-05-17 22:05:42 +0000 (Thu, 17 May 2007) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/lngamma.c
+
+fixed error analysis in mpfr_lngamma
+added mpfr_inp_raw/mpfr_out_raw in TODO
+
+------------------------------------------------------------------------
+r4450 | vlefevre | 2007-05-16 14:52:57 +0000 (Wed, 16 May 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: fixed mpfr_fms formula to match the one on Itanium and PowerPC.
+
+------------------------------------------------------------------------
+r4449 | vlefevre | 2007-05-07 09:01:39 +0000 (Mon, 07 May 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: improved the description of mpfr_remquo.
+
+------------------------------------------------------------------------
+r4448 | zimmerma | 2007-05-06 13:25:55 +0000 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+improved description of remainder and remquo
+
+------------------------------------------------------------------------
+r4447 | vlefevre | 2007-05-06 11:16:12 +0000 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+My latest change was not completely correct...
+
+------------------------------------------------------------------------
+r4446 | vlefevre | 2007-05-06 11:13:41 +0000 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+Updated description of algorithm for mpfr_remainder.
+
+------------------------------------------------------------------------
+r4445 | zimmerma | 2007-05-06 08:18:50 +0000 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added description of algorithm for mpfr_remainder
+
+------------------------------------------------------------------------
+r4444 | vlefevre | 2007-05-04 14:25:31 +0000 (Fri, 04 May 2007) | 2 lines
+Changed paths:
+ M /trunk/remquo.c
+
+remquo.c: suggest to use mpz_powm.
+
+------------------------------------------------------------------------
+r4443 | vlefevre | 2007-05-04 13:19:27 +0000 (Fri, 04 May 2007) | 3 lines
+Changed paths:
+ M /trunk/remquo.c
+
+remquo.c: added a comment (idea to compute the remainder much more
+efficiently in the case x much larger than y).
+
+------------------------------------------------------------------------
+r4442 | zimmerma | 2007-05-04 12:45:36 +0000 (Fri, 04 May 2007) | 2 lines
+Changed paths:
+ M /trunk/remquo.c
+
+added assert and ideas for native implementation
+
+------------------------------------------------------------------------
+r4441 | zimmerma | 2007-05-04 06:27:38 +0000 (Fri, 04 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tremquo.c
+
+put back test (disabled for test)
+
+------------------------------------------------------------------------
+r4440 | zimmerma | 2007-05-04 06:26:56 +0000 (Fri, 04 May 2007) | 2 lines
+Changed paths:
+ M /trunk/remquo.c
+ M /trunk/tests/tremquo.c
+
+fixed problem when rem and x are the same variable
+
+------------------------------------------------------------------------
+r4439 | vlefevre | 2007-05-04 00:36:01 +0000 (Fri, 04 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tremquo.c
+
+tremquo.c: added a test that leads to a segmentation fault.
+
+------------------------------------------------------------------------
+r4438 | vlefevre | 2007-05-04 00:29:47 +0000 (Fri, 04 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tremquo.c
+
+tremquo.c: fixed tests (= -> ==).
+
+------------------------------------------------------------------------
+r4437 | zimmerma | 2007-05-03 20:07:20 +0000 (Thu, 03 May 2007) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/remquo.c
+ M /trunk/tests/tremquo.c
+
+fixed two issues found by Kaveh Ghazi:
+* remainder was wrong for |x/y| < 1
+* remainder had wrong sign when zero
+
+------------------------------------------------------------------------
+r4436 | zimmerma | 2007-05-03 15:56:03 +0000 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+more details of error analysis
+
+------------------------------------------------------------------------
+r4435 | vlefevre | 2007-05-03 13:30:34 +0000 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+Updated svn:ignore property.
+
+------------------------------------------------------------------------
+r4434 | vlefevre | 2007-05-03 13:28:31 +0000 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk
+
+Updated svn:ignore property.
+
+------------------------------------------------------------------------
+r4433 | zimmerma | 2007-05-03 13:16:34 +0000 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tremquo.c
+
+fixed precision for command-line usage
+
+------------------------------------------------------------------------
+r4432 | vlefevre | 2007-05-03 13:15:49 +0000 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added mpfr_lgamma.
+
+------------------------------------------------------------------------
+r4431 | zimmerma | 2007-05-03 13:10:31 +0000 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tremquo.c
+
+added code to use tremquo with command-line arguments (tremquo x y)
+
+------------------------------------------------------------------------
+r4430 | vlefevre | 2007-05-02 16:03:52 +0000 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: improved comment.
+
+------------------------------------------------------------------------
+r4429 | vlefevre | 2007-05-02 15:52:51 +0000 (Wed, 02 May 2007) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: added a comment on the AC_ARG_ENABLE(decimal-float...)
+part. The addition of this code was the cause of the test_CFLAGS problem
+(see r4425 log), but this code is still wrong.
+
+------------------------------------------------------------------------
+r4428 | zimmerma | 2007-05-02 15:41:18 +0000 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tremquo.c
+
+modified test (2147483648 is not representable as 32-bit long in C90)
+
+------------------------------------------------------------------------
+r4427 | vlefevre | 2007-05-02 15:20:50 +0000 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/remquo.c
+ M /trunk/yn.c
+
+Removed unused variables.
+
+------------------------------------------------------------------------
+r4426 | vlefevre | 2007-05-02 15:18:18 +0000 (Wed, 02 May 2007) | 4 lines
+Changed paths:
+ M /trunk/get_str.c
+
+get_str.c:
+ * Removed useless prototype declaration (function no longer defined).
+ * Fixed initializer.
+
+------------------------------------------------------------------------
+r4425 | vlefevre | 2007-05-02 15:14:44 +0000 (Wed, 02 May 2007) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: moved the definition of test_CFLAGS upward (it was
+always set to "set", either because of things added to configure.in
+or because of new autoconf).
+
+------------------------------------------------------------------------
+r4424 | vlefevre | 2007-05-02 14:54:47 +0000 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr.h: added mpfr_lgamma prototype.
+
+------------------------------------------------------------------------
+r4423 | zimmerma | 2007-05-02 14:23:11 +0000 (Wed, 02 May 2007) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/remquo.c
+ M /trunk/tests/tremquo.c
+
+argument quo of remquo is now a pointer to long instead of int
+added new functions in NEWS
+
+------------------------------------------------------------------------
+r4422 | zimmerma | 2007-05-02 12:21:24 +0000 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/remquo.c
+ M /trunk/tests/tremquo.c
+
+changed order of arguments: now mpfr_remquo (r, q, x, y, rnd).
+
+------------------------------------------------------------------------
+r4421 | vlefevre | 2007-05-02 11:53:58 +0000 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/remquo.c
+
+remquo.c: fixed variable name for MPFR_LOG_FUNC.
+
+------------------------------------------------------------------------
+r4420 | zimmerma | 2007-05-02 10:12:11 +0000 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/TODO
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/remquo.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tremquo.c
+
+added mpfr_remquo and mpfr_remainder
+
+------------------------------------------------------------------------
+r4419 | zimmerma | 2007-04-27 12:48:01 +0000 (Fri, 27 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+fixed error analysis (error was over-estimated)
+
+------------------------------------------------------------------------
+r4418 | vlefevre | 2007-04-26 10:12:51 +0000 (Thu, 26 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+lngamma.c: a bit more details in the error analysis for z0 < 1.
+
+------------------------------------------------------------------------
+r4417 | vlefevre | 2007-04-26 09:20:37 +0000 (Thu, 26 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+lngamma.c: a bit more details in the error analysis for z0 < 1.
+
+------------------------------------------------------------------------
+r4416 | zimmerma | 2007-04-26 08:26:39 +0000 (Thu, 26 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+u was used for two different meanings in the error analysis for z0 < 1
+
+------------------------------------------------------------------------
+r4415 | vlefevre | 2007-04-25 12:52:09 +0000 (Wed, 25 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/get_d64.c
+ M /trunk/jn.c
+ M /trunk/set_d64.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+ M /trunk/tests/tjn.c
+ M /trunk/tests/ty0.c
+ M /trunk/tests/ty1.c
+ M /trunk/tests/tyn.c
+ M /trunk/yn.c
+
+Updated Subversion properties on .c files (now consistent).
+
+------------------------------------------------------------------------
+r4414 | vlefevre | 2007-04-25 12:49:47 +0000 (Wed, 25 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+Updated svn:ignore property.
+
+------------------------------------------------------------------------
+r4413 | vlefevre | 2007-04-25 12:48:05 +0000 (Wed, 25 Apr 2007) | 4 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tlgamma.c
+ M /trunk/tests/tlngamma.c
+
+Added preliminary support for mpfr_lngamma and tests.
+TODO: add support for negative numbers with small exponent.
+Re-enable the generic tests when this is done.
+
+------------------------------------------------------------------------
+r4412 | vlefevre | 2007-04-25 10:58:14 +0000 (Wed, 25 Apr 2007) | 3 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+lngamma.c: There was an assertion failed, probably because the error
+was too large; fixed that by restarting with a larger precision.
+
+------------------------------------------------------------------------
+r4411 | vlefevre | 2007-04-25 10:51:03 +0000 (Wed, 25 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+lngamma.c: fixed -2k-1 <= x <= -2k test.
+
+------------------------------------------------------------------------
+r4410 | vlefevre | 2007-04-25 09:07:03 +0000 (Wed, 25 Apr 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tlngamma.c
+
+tests/tlngamma.c: added a test showing a bug in lngamma (due to the
+use of mpfr_get_si even when the number doesn't fit in a long).
+
+------------------------------------------------------------------------
+r4409 | zimmerma | 2007-04-22 08:58:35 +0000 (Sun, 22 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/jn.c
+ M /trunk/tests/tjn.c
+
+fixed bug for negative even index in mpfr_jn (wrong sign)
+
+------------------------------------------------------------------------
+r4408 | zimmerma | 2007-04-12 12:16:04 +0000 (Thu, 12 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+added warning
+
+------------------------------------------------------------------------
+r4407 | zimmerma | 2007-04-12 08:24:19 +0000 (Thu, 12 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+added Bit Twiddling Hacks
+
+------------------------------------------------------------------------
+r4406 | vlefevre | 2007-04-05 12:01:07 +0000 (Thu, 05 Apr 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+MPFR manual: added a brief description of mpfr_t (this may be needed
+to write correct code) and mpfr_ptr (used by mpfr_sum).
+
+------------------------------------------------------------------------
+r4405 | vlefevre | 2007-04-02 15:32:00 +0000 (Mon, 02 Apr 2007) | 4 lines
+Changed paths:
+ M /trunk/jn.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tjn.c
+ M /trunk/tests/tyn.c
+ M /trunk/yn.c
+
+Changed mpfr_{jn,yn}_si (mpfr_t res, mpfr_t x, long n, ...) into
+mpfr_{jn,yn} (mpfr_t res, long n, mpfr_t x, ...), as discussed by
+mail; fixed a typo in mpfr.texi in mpfr_{y0,y1,yn} description.
+
+------------------------------------------------------------------------
+r4404 | zimmerma | 2007-03-31 21:23:00 +0000 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added url of GSL manual
+
+------------------------------------------------------------------------
+r4403 | zimmerma | 2007-03-31 21:15:26 +0000 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+fixed misunderstanding about definition of Bessel functions
+
+------------------------------------------------------------------------
+r4402 | zimmerma | 2007-03-31 17:59:23 +0000 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed Bessel functions J_n and Y_n
+
+------------------------------------------------------------------------
+r4401 | zimmerma | 2007-03-31 14:01:00 +0000 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+ M /trunk/jn.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/ty0.c
+ A /trunk/tests/ty1.c
+ A /trunk/tests/tyn.c
+ A /trunk/yn.c
+
+added Bessel functions of second kind (y0, y1, yn_si)
+
+------------------------------------------------------------------------
+r4400 | zimmerma | 2007-03-31 13:55:06 +0000 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tj0.c
+ M /trunk/tests/tj1.c
+
+now test_generic calls respectively j0 and j1, not zeta!
+
+------------------------------------------------------------------------
+r4399 | vlefevre | 2007-03-30 14:35:56 +0000 (Fri, 30 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: INF -> Inf for consistency.
+
+------------------------------------------------------------------------
+r4398 | vlefevre | 2007-03-30 14:34:00 +0000 (Fri, 30 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: PI -> Pi for consistency.
+
+------------------------------------------------------------------------
+r4397 | vlefevre | 2007-03-29 02:33:02 +0000 (Thu, 29 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: -0 -> @minus{}0.
+
+------------------------------------------------------------------------
+r4396 | vlefevre | 2007-03-29 02:28:46 +0000 (Thu, 29 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: fixed bug introduced in rev 4377, which made TeX fail.
+
+------------------------------------------------------------------------
+r4395 | vlefevre | 2007-03-29 02:00:04 +0000 (Thu, 29 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+Added tj0, tj1 and tjn to svn:ignore property of "tests" directory.
+
+------------------------------------------------------------------------
+r4393 | zimmerma | 2007-03-26 09:29:40 +0000 (Mon, 26 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/jn.c
+
+mpfr_jn -> mpfr_jn_si
+
+------------------------------------------------------------------------
+r4392 | zimmerma | 2007-03-23 20:30:20 +0000 (Fri, 23 Mar 2007) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/jn.c
+ M /trunk/tests/tjn.c
+
+now check underflow for large n in mpfr_jn_si
+added more tests
+
+------------------------------------------------------------------------
+r4391 | zimmerma | 2007-03-23 16:37:16 +0000 (Fri, 23 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tjn.c
+
+added more tests (large values of n)
+
+------------------------------------------------------------------------
+r4390 | zimmerma | 2007-03-23 16:22:01 +0000 (Fri, 23 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/jn.c
+
+fixed another stupid bug
+
+------------------------------------------------------------------------
+r4389 | zimmerma | 2007-03-23 15:49:35 +0000 (Fri, 23 Mar 2007) | 3 lines
+Changed paths:
+ M /trunk/jn.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tjn.c
+
+mpfr_jn -> mpfr_jn_si, with 'int' argument changed to 'long'
+fixed bug in mpfr_jn_si (forgot to increase working precision)
+
+------------------------------------------------------------------------
+r4388 | vlefevre | 2007-03-23 15:47:17 +0000 (Fri, 23 Mar 2007) | 3 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added a warning about the meaning of the output "inexact"
+value in the function logging code.
+
+------------------------------------------------------------------------
+r4387 | vlefevre | 2007-03-23 15:38:20 +0000 (Fri, 23 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/sub.c
+
+Added log support for mpfr_add and mpfr_sub.
+
+------------------------------------------------------------------------
+r4386 | lfousse | 2007-03-23 13:43:18 +0000 (Fri, 23 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+Correction: added missing $b_n$.
+
+------------------------------------------------------------------------
+r4385 | zimmerma | 2007-03-22 17:12:00 +0000 (Thu, 22 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/algorithms.tex
+ A /trunk/jn.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/reuse.c
+ A /trunk/tests/tj0.c
+ A /trunk/tests/tj1.c
+ A /trunk/tests/tjn.c
+
+added Bessel functions of first kind: j0, j1, jn
+
+------------------------------------------------------------------------
+r4384 | vlefevre | 2007-03-19 09:11:17 +0000 (Mon, 19 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+MPFR manual: improved description of mpfr_get_str.
+
+------------------------------------------------------------------------
+r4383 | zimmerma | 2007-03-19 07:43:16 +0000 (Mon, 19 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed typos in comments
+
+------------------------------------------------------------------------
+r4382 | zimmerma | 2007-03-18 20:16:15 +0000 (Sun, 18 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+documented restriction to n in mpfr_get_str
+
+------------------------------------------------------------------------
+r4380 | vlefevre | 2007-03-13 15:46:08 +0000 (Tue, 13 Mar 2007) | 3 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Updated INSTALL based on AIX/PowerPC tests and results from Julie Kurpa
+and information on <http://www.ess.uci.edu/esmf/FAQ.html#gcc-errors>.
+
+------------------------------------------------------------------------
+r4379 | vlefevre | 2007-03-03 01:55:32 +0000 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated "To make a release" section.
+
+------------------------------------------------------------------------
+r4378 | vlefevre | 2007-03-02 11:16:59 +0000 (Fri, 02 Mar 2007) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Made modified paragraph on mpfr_get_str more correct from a logical
+point of view.
+
+------------------------------------------------------------------------
+r4377 | zimmerma | 2007-03-02 09:15:04 +0000 (Fri, 02 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+modified paragraph on mpfr_get_str (size of allocated string)
+
+------------------------------------------------------------------------
+r4376 | zimmerma | 2007-02-25 13:04:13 +0000 (Sun, 25 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added tentative implementation of fmod
+
+------------------------------------------------------------------------
+r4375 | zimmerma | 2007-02-20 02:58:16 +0000 (Tue, 20 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added suggestion about remquo
+
+------------------------------------------------------------------------
+r4374 | zimmerma | 2007-02-19 21:50:26 +0000 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added comment
+
+------------------------------------------------------------------------
+r4373 | zimmerma | 2007-02-19 21:43:23 +0000 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added C99 rationale for remquo
+
+------------------------------------------------------------------------
+r4372 | zimmerma | 2007-02-19 03:52:30 +0000 (Mon, 19 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/algorithms.tex
+ M /trunk/asinh.c
+ M /trunk/atanh.c
+ M /trunk/const_catalan.c
+ M /trunk/log1p.c
+
+fixed error in generic error for the logarithm, and propagated new bound
+in algorithms.tex and source files
+
+------------------------------------------------------------------------
+r4371 | zimmerma | 2007-02-18 20:10:20 +0000 (Sun, 18 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added new item
+
+------------------------------------------------------------------------
+r4370 | vlefevre | 2007-02-15 23:35:25 +0000 (Thu, 15 Feb 2007) | 3 lines
+Changed paths:
+ A /trunk/update-patchv (from /branches/2.2/update-patchv:4367)
+
+Added update-patchv script to update some files before a patch is built
+(script from 2.2 branch).
+
+------------------------------------------------------------------------
+r4365 | vlefevre | 2007-02-14 09:31:19 +0000 (Wed, 14 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated paragraph on the underflow before/after rounding.
+
+------------------------------------------------------------------------
+r4364 | zimmerma | 2007-02-14 03:34:21 +0000 (Wed, 14 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added reference
+
+------------------------------------------------------------------------
+r4363 | vlefevre | 2007-02-12 16:34:21 +0000 (Mon, 12 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: added Exceptions section.
+
+------------------------------------------------------------------------
+r4361 | vlefevre | 2007-02-12 12:18:19 +0000 (Mon, 12 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated month.
+
+------------------------------------------------------------------------
+r4359 | vlefevre | 2007-02-12 12:04:14 +0000 (Mon, 12 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.texi
+
+Note that the mpfr.info file is now installed in the share subdirectory.
+
+------------------------------------------------------------------------
+r4358 | vlefevre | 2007-02-10 11:30:18 +0000 (Sat, 10 Feb 2007) | 4 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: removed comment since there are other <limits.h> macros
+in the file (and this is an old bug: the first one was introduced in
+rev 2783).
+
+------------------------------------------------------------------------
+r4357 | zimmerma | 2007-02-10 08:05:30 +0000 (Sat, 10 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+added missing include
+
+------------------------------------------------------------------------
+r4356 | vlefevre | 2007-02-09 14:17:32 +0000 (Fri, 09 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/pow_si.c
+ M /trunk/tests/tpow.c
+
+Fixed an integer overflow in pow_si.c (detected with -ftrapv) and
+added a corresponding testcase in tests/tpow.c.
+
+------------------------------------------------------------------------
+r4355 | vlefevre | 2007-02-09 13:30:57 +0000 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+pow_si.c: another comment about the overflow detection.
+
+------------------------------------------------------------------------
+r4354 | vlefevre | 2007-02-09 13:14:07 +0000 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+pow_si.c: added the proof of overflow checking.
+
+------------------------------------------------------------------------
+r4353 | vlefevre | 2007-02-09 11:55:51 +0000 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: added a comment about the exponent limits for MPFR numbers.
+
+------------------------------------------------------------------------
+r4352 | vlefevre | 2007-02-08 15:47:13 +0000 (Thu, 08 Feb 2007) | 7 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/tests/tset_si.c
+
+Reimplemented mpfr_set_si_2exp and mpfr_set_ui_2exp, and mpfr_set_si
+and mpfr_set_ui using the 2exp versions with e = 0. This fixes a bug
+in corner cases (emin >= 4 and some other constraints) in mpfr_set_si
+and mpfr_set_ui that incorrectly lead to an underflow flag set, and
+fixes mpfr_set_si_2exp and mpfr_set_ui_2exp in case of overflow or
+underflow (replacing the r4346 fix). Added corresponding testcases.
+
+------------------------------------------------------------------------
+r4350 | vlefevre | 2007-02-07 01:48:01 +0000 (Wed, 07 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/abort_prec_max.c
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/minmax.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/zeta_ui.c
+
+Added "Contributed by the Arenaire and Cacao projects, INRIA." to the
+copyright notices and removed a few old things.
+
+------------------------------------------------------------------------
+r4347 | zimmerma | 2007-02-01 13:15:34 +0000 (Thu, 01 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added missing macro (thanks to Izhar Wallach <izharw@keddem.com>)
+
+------------------------------------------------------------------------
+r4346 | vlefevre | 2007-01-20 13:45:20 +0000 (Sat, 20 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/set_si_2exp.c
+
+Fixed mpfr_set_si_2exp in case of overflow or underflow.
+
+------------------------------------------------------------------------
+r4345 | vlefevre | 2007-01-19 08:31:32 +0000 (Fri, 19 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+pow_si.c: fixed the overflow detection for x power of 2 and n negative.
+
+------------------------------------------------------------------------
+r4344 | vlefevre | 2007-01-19 07:24:26 +0000 (Fri, 19 Jan 2007) | 3 lines
+Changed paths:
+ M /trunk/tests/tget_f.c
+
+tests/tget_f.c: fixed a test that had an integer overflow (detected
+with -ftrapv).
+
+------------------------------------------------------------------------
+r4343 | vlefevre | 2007-01-19 07:07:10 +0000 (Fri, 19 Jan 2007) | 6 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+pow_si.c: Before fixing the bug corresponding to the testcase added in
+rev 4342, let's fix another one that can be detected with -ftrapv when
+n = LONG_MIN (since -n is not representable in this case).
+With wrapping, we always got the correct result because mp_exp_t is
+currently at most a long *and* because of side effects!
+
+------------------------------------------------------------------------
+r4342 | vlefevre | 2007-01-19 06:51:13 +0000 (Fri, 19 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: added a test which fails (undetected integer overflow).
+
+------------------------------------------------------------------------
+r4341 | vlefevre | 2007-01-19 06:44:09 +0000 (Fri, 19 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: new test was wrong; fixed.
+
+------------------------------------------------------------------------
+r4340 | vlefevre | 2007-01-19 06:39:23 +0000 (Fri, 19 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: corrected tests and added another test.
+
+------------------------------------------------------------------------
+r4339 | vlefevre | 2007-01-19 05:10:16 +0000 (Fri, 19 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: added tests.
+
+------------------------------------------------------------------------
+r4338 | vlefevre | 2007-01-19 04:23:17 +0000 (Fri, 19 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+pow_si.c: added an assertion.
+
+------------------------------------------------------------------------
+r4337 | vlefevre | 2007-01-18 01:28:02 +0000 (Thu, 18 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: merged both requests for mpfr_sinh_cosh.
+
+------------------------------------------------------------------------
+r4335 | zimmerma | 2007-01-17 19:38:49 +0000 (Wed, 17 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/dim.c
+ M /trunk/mpfr.texi
+
+added documentation for mpfr_dim (was missing)
+
+------------------------------------------------------------------------
+r4334 | zimmerma | 2007-01-17 19:26:47 +0000 (Wed, 17 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item
+
+------------------------------------------------------------------------
+r4333 | vlefevre | 2007-01-17 17:34:09 +0000 (Wed, 17 Jan 2007) | 4 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/tests.c
+
+Replaced some computations using the type double by computations using
+MPFR, for mpfr_get_str, allowing it to work with an x86 processor set
+up in single-precision mode.
+
+------------------------------------------------------------------------
+r4332 | vlefevre | 2007-01-16 23:15:29 +0000 (Tue, 16 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+Updated comment concerning LONG_MIN / 1.
+
+------------------------------------------------------------------------
+r4331 | vlefevre | 2007-01-15 00:40:17 +0000 (Mon, 15 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated "To make a release" section.
+
+------------------------------------------------------------------------
+r4329 | vlefevre | 2007-01-10 16:35:27 +0000 (Wed, 10 Jan 2007) | 2 lines
+Changed paths:
+ D /trunk/mpzroot.c
+ D /trunk/rootrem.c
+
+Removed mpzroot.c and rootrem.c from the repository.
+
+------------------------------------------------------------------------
+r4328 | vlefevre | 2007-01-10 16:32:46 +0000 (Wed, 10 Jan 2007) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ D /trunk/log_b2.h
+
+Removed log_b2.h (has never been used) from the repository and from
+libmpfr_la_SOURCES in Makefile.am.
+
+------------------------------------------------------------------------
+r4327 | vlefevre | 2007-01-10 15:40:05 +0000 (Wed, 10 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ.html: Added details to MPF-related Q&A's.
+
+------------------------------------------------------------------------
+r4326 | vlefevre | 2007-01-10 12:51:56 +0000 (Wed, 10 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_d64.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/minmax.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mparam_h.in
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/mpzroot.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/rootrem.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_d64.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_set_d64.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Copyright notice update: added 2007.
+
+------------------------------------------------------------------------
+r4325 | vlefevre | 2007-01-10 12:37:05 +0000 (Wed, 10 Jan 2007) | 6 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/README.dev
+ M /trunk/tests/tests.c
+
+* tests/tests.c: under Linux/x86, the FPU precision can be set before
+doing the tests (see MPFR_FPU_PREC), so that MPFR can be tested under
+various FP environments (2 tests currently fail with _FPU_SINGLE).
+* README.dev: updated "To make a release" section.
+* BUGS: mentioned the above bug.
+
+------------------------------------------------------------------------
+r4323 | vlefevre | 2007-01-08 16:36:00 +0000 (Mon, 08 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi -> January 2007.
+
+------------------------------------------------------------------------
+r4321 | zimmerma | 2007-01-08 16:03:52 +0000 (Mon, 08 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added support from LIP, and different INRIA project-teams
+
+------------------------------------------------------------------------
+r4320 | vlefevre | 2007-01-03 16:19:45 +0000 (Wed, 03 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+Minor change.
+
+------------------------------------------------------------------------
+r4319 | vlefevre | 2006-12-29 03:42:39 +0000 (Fri, 29 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: macros/functions to get/set the sign of a MPFR number.
+
+------------------------------------------------------------------------
+r4318 | zimmerma | 2006-12-21 14:10:51 +0000 (Thu, 21 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/root.c
+
+remove new rootrem implementation (unclear copyright status)
+
+------------------------------------------------------------------------
+r4317 | vlefevre | 2006-12-19 22:32:09 +0000 (Tue, 19 Dec 2006) | 3 lines
+Changed paths:
+ M /trunk/const_catalan.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/eint.c
+ M /trunk/erfc.c
+ M /trunk/gamma.c
+ M /trunk/lngamma.c
+ M /trunk/zeta.c
+
+Replaced mpfr_mul_2exp and mpfr_div_2exp by mpfr_mul_2ui and
+mpfr_div_2ui respectively (when this makes sense, of course).
+
+------------------------------------------------------------------------
+r4316 | zimmerma | 2006-12-19 13:59:59 +0000 (Tue, 19 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/zeta_ui.c
+
+mpfr_div_2exp -> mpfr_div_2ui
+
+------------------------------------------------------------------------
+r4315 | zimmerma | 2006-12-19 07:08:13 +0000 (Tue, 19 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/algorithms.tex
+ M /trunk/zeta_ui.c
+
+improved efficiency of zeta_ui(s) for 3^(-s) < 1/2*ulp(1)
+
+------------------------------------------------------------------------
+r4314 | vlefevre | 2006-12-18 17:09:43 +0000 (Mon, 18 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: update concerning MPFR_USE_EXTENSION.
+
+------------------------------------------------------------------------
+r4313 | zimmerma | 2006-12-18 16:03:26 +0000 (Mon, 18 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/rootrem.c
+
+added copyright header
+
+------------------------------------------------------------------------
+r4312 | zimmerma | 2006-12-18 12:04:19 +0000 (Mon, 18 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item
+
+------------------------------------------------------------------------
+r4311 | vlefevre | 2006-12-15 14:28:53 +0000 (Fri, 15 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+Implemented MPFR_USE_EXTENSION support.
+
+------------------------------------------------------------------------
+r4310 | zimmerma | 2006-12-15 08:42:21 +0000 (Fri, 15 Dec 2006) | 4 lines
+Changed paths:
+ M /trunk/zeta_ui.c
+
+improved efficiency for zeta(m) in precision p when m is large
+but still smaller than p, for example m=1024 and p=2048 gives a
+speedup of about 23 (thanks to Jim White for reporting the problem)
+
+------------------------------------------------------------------------
+r4309 | zimmerma | 2006-12-14 15:19:17 +0000 (Thu, 14 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/zeta_ui.c
+
+added MPFR_ZIV_INIT stuff
+
+------------------------------------------------------------------------
+r4308 | zimmerma | 2006-12-07 07:17:58 +0000 (Thu, 07 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+fixed typo
+
+------------------------------------------------------------------------
+r4307 | vlefevre | 2006-12-05 09:42:22 +0000 (Tue, 05 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: to be added: MPFR_USE_EXTENSION macro.
+
+------------------------------------------------------------------------
+r4306 | vlefevre | 2006-11-29 09:50:57 +0000 (Wed, 29 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: update.
+
+------------------------------------------------------------------------
+r4300 | vlefevre | 2006-11-29 08:54:24 +0000 (Wed, 29 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: update of the "Notes on Windows 32" section.
+
+------------------------------------------------------------------------
+r4299 | zimmerma | 2006-11-27 08:56:12 +0000 (Mon, 27 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/set_uj.c
+
+added comment about last change
+
+------------------------------------------------------------------------
+r4298 | zimmerma | 2006-11-27 08:26:02 +0000 (Mon, 27 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/set_uj.c
+
+fixed warning on 64-bit machines
+
+------------------------------------------------------------------------
+r4297 | vlefevre | 2006-11-26 18:58:05 +0000 (Sun, 26 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tests/tpow.c: added worst cases.
+
+------------------------------------------------------------------------
+r4296 | vlefevre | 2006-11-26 18:52:26 +0000 (Sun, 26 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/troot.c
+
+tests/troot.c: two more worst cases.
+
+------------------------------------------------------------------------
+r4295 | vlefevre | 2006-11-25 20:05:15 +0000 (Sat, 25 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/troot.c
+
+tests/troot.c: added a worst case.
+
+------------------------------------------------------------------------
+r4293 | vlefevre | 2006-11-25 19:46:42 +0000 (Sat, 25 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: removed obsolete "compiler bugs" section.
+
+------------------------------------------------------------------------
+r4292 | zimmerma | 2006-11-25 09:51:07 +0000 (Sat, 25 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+added worst case
+
+------------------------------------------------------------------------
+r4286 | vlefevre | 2006-11-25 00:15:30 +0000 (Sat, 25 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Partially rewrote the INSTALL file.
+
+------------------------------------------------------------------------
+r4284 | vlefevre | 2006-11-24 14:46:41 +0000 (Fri, 24 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Makefile.am: fixed libtool's -version-info flag (and comment).
+
+------------------------------------------------------------------------
+r4279 | vlefevre | 2006-11-24 00:44:20 +0000 (Fri, 24 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: check for gmp.h a bit earlier.
+
+------------------------------------------------------------------------
+r4278 | zimmerma | 2006-11-23 14:10:10 +0000 (Thu, 23 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+added --with-tests-timeout=60 for nightly tests
+
+------------------------------------------------------------------------
+r4277 | zimmerma | 2006-11-23 14:08:47 +0000 (Thu, 23 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/tests/tests.c
+
+test timeout is now a configure option (e.g. --with-tests-timeout=60)
+
+------------------------------------------------------------------------
+r4276 | zimmerma | 2006-11-23 13:25:35 +0000 (Thu, 23 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+replaced set_d by set_str_binary (more portable)
+
+------------------------------------------------------------------------
+r4274 | vlefevre | 2006-11-23 00:34:58 +0000 (Thu, 23 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: several additions.
+
+------------------------------------------------------------------------
+r4272 | vlefevre | 2006-11-22 17:25:20 +0000 (Wed, 22 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: small update.
+
+------------------------------------------------------------------------
+r4270 | vlefevre | 2006-11-22 15:25:22 +0000 (Wed, 22 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update (added a CSS counter).
+
+------------------------------------------------------------------------
+r4268 | vlefevre | 2006-11-22 15:23:30 +0000 (Wed, 22 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/update-faq
+
+update-faq: added a workaround for the libxslt bug 377440.
+
+------------------------------------------------------------------------
+r4267 | vlefevre | 2006-11-22 11:48:44 +0000 (Wed, 22 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: update concerning the patches information.
+
+------------------------------------------------------------------------
+r4266 | zimmerma | 2006-11-22 08:03:59 +0000 (Wed, 22 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+set GMP_CHECK_RANDOMIZE to get random tests
+
+------------------------------------------------------------------------
+r4263 | vlefevre | 2006-11-21 18:01:15 +0000 (Tue, 21 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/README
+
+Updated README file.
+
+------------------------------------------------------------------------
+r4259 | vlefevre | 2006-11-20 16:32:36 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: mention the version suffix.
+
+------------------------------------------------------------------------
+r4258 | vlefevre | 2006-11-20 16:25:47 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/VERSION
+ M /trunk/configure.in
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/version.c
+
+Updated version to 2.3.0-dev.
+
+------------------------------------------------------------------------
+r4257 | vlefevre | 2006-11-20 16:24:20 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tversion.c
+ M /trunk/update-version
+
+Added version suffix support (useful for dev and rc versions).
+
+------------------------------------------------------------------------
+r4256 | vlefevre | 2006-11-20 14:45:50 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+Rewrote nightly-test in sh and fixed a security hole.
+
+------------------------------------------------------------------------
+r4255 | zimmerma | 2006-11-20 14:08:00 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+added cpu time limit of 60 seconds in tests
+
+------------------------------------------------------------------------
+r4254 | vlefevre | 2006-11-20 13:44:04 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: update.
+
+------------------------------------------------------------------------
+r4252 | zimmerma | 2006-11-20 12:59:26 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+added an argument to give the branch (use trunk or branches/2.2 for example)
+
+------------------------------------------------------------------------
+r4250 | vlefevre | 2006-11-20 11:36:25 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+tests/tgamma.c: restore emin and emax to their default values.
+
+------------------------------------------------------------------------
+r4249 | zimmerma | 2006-11-20 11:00:45 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+fixed bug in overflow test
+
+------------------------------------------------------------------------
+r4248 | zimmerma | 2006-11-20 09:52:45 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+fixed bug in mpfr_gamma for exact result
+
+------------------------------------------------------------------------
+r4246 | zimmerma | 2006-11-20 07:39:36 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/nightly-test
+
+added two configure options
+
+------------------------------------------------------------------------
+r4245 | zimmerma | 2006-11-20 07:32:36 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/erfc.c
+
+simplified test :-)
+
+------------------------------------------------------------------------
+r4244 | vlefevre | 2006-11-20 05:40:58 +0000 (Mon, 20 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: unset GMP_CFLAGS and GMP_CC in case the user has set such
+environment variables for another use.
+
+------------------------------------------------------------------------
+r4243 | vlefevre | 2006-11-20 04:45:11 +0000 (Mon, 20 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/tests/texp2.c
+
+tests/texp2.c: fixed a problem with a value that is not necessarily
+representable (on platforms without long long).
+
+------------------------------------------------------------------------
+r4242 | vlefevre | 2006-11-20 00:27:53 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: removed item on mpfr_eint (now fixed).
+
+------------------------------------------------------------------------
+r4241 | vlefevre | 2006-11-20 00:25:10 +0000 (Mon, 20 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/erfc.c
+
+Untabify.
+
+------------------------------------------------------------------------
+r4240 | zimmerma | 2006-11-19 21:27:33 +0000 (Sun, 19 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+replaced double by mpfr_t (problem on 64-bit machines)
+
+------------------------------------------------------------------------
+r4239 | zimmerma | 2006-11-19 18:22:51 +0000 (Sun, 19 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/terf.c
+
+added more tests
+
+------------------------------------------------------------------------
+r4238 | zimmerma | 2006-11-19 18:08:38 +0000 (Sun, 19 Nov 2006) | 2 lines
+Changed paths:
+ A /trunk/nightly-test
+
+script for nightly tests
+
+------------------------------------------------------------------------
+r4237 | zimmerma | 2006-11-19 14:35:02 +0000 (Sun, 19 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/erfc.c
+ M /trunk/pow.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/ttan.c
+
+fixed bug in pow (isodd -> assertion failed)
+fixed problem in erfc for large input
+reduced tests that took too much time
+
+------------------------------------------------------------------------
+r4236 | vlefevre | 2006-11-19 11:34:06 +0000 (Sun, 19 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated description of mpfr_eint, as the whole input domain
+is now supported.
+
+------------------------------------------------------------------------
+r4235 | vlefevre | 2006-11-19 11:17:03 +0000 (Sun, 19 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/eint.c
+ M /trunk/erfc.c
+
+Untabify.
+
+------------------------------------------------------------------------
+r4234 | vlefevre | 2006-11-19 11:01:25 +0000 (Sun, 19 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: added a comment about MPFR_WARNING.
+
+------------------------------------------------------------------------
+r4233 | zimmerma | 2006-11-19 09:28:35 +0000 (Sun, 19 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/eint.c
+ M /trunk/erfc.c
+
+fixed bug in erfc (forgot to compare result of cmp_si)
+fixed infinite loop in eint (test for use of asympt was not tight enough)
+
+------------------------------------------------------------------------
+r4232 | zimmerma | 2006-11-19 08:48:17 +0000 (Sun, 19 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/eint.c
+ M /trunk/tests/teint.c
+
+added asymptotic expansion for mpfr_eint (don't need MPFR_WARNING any more)
+
+------------------------------------------------------------------------
+r4231 | vlefevre | 2006-11-18 20:55:17 +0000 (Sat, 18 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/tests/terf.c
+
+Added a mpfr_erfc test that shows a bug and updated BUGS file.
+
+------------------------------------------------------------------------
+r4229 | vlefevre | 2006-11-17 09:07:23 +0000 (Fri, 17 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: Added a comment concerning GMP version checking.
+
+------------------------------------------------------------------------
+r4228 | vlefevre | 2006-11-17 08:58:29 +0000 (Fri, 17 Nov 2006) | 5 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: Before testing GMP header and library versions, set
+LD_RUN_PATH locally if a --with-gmp* option is used, so that the
+right version of the GMP library is used. There is no need to do
+something similar for "make check" as libtool does the job.
+
+------------------------------------------------------------------------
+r4227 | vlefevre | 2006-11-17 08:15:24 +0000 (Fri, 17 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Updated mpfr_erfc documentation (now supported in whole domain).
+
+------------------------------------------------------------------------
+r4226 | vlefevre | 2006-11-17 03:16:16 +0000 (Fri, 17 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: removed mpfr_pow_z bug.
+
+------------------------------------------------------------------------
+r4225 | vlefevre | 2006-11-17 03:13:24 +0000 (Fri, 17 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tests.c
+ M /trunk/tests/tgeneric.c
+
+Merged the new generic tests.
+
+------------------------------------------------------------------------
+r4224 | vlefevre | 2006-11-17 02:55:09 +0000 (Fri, 17 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+Partially fixed a bug in mpfr_pow_si (overflow/underflow detection for
+n < 0).
+
+------------------------------------------------------------------------
+r4223 | vlefevre | 2006-11-17 02:46:56 +0000 (Fri, 17 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow_z.c
+
+tests/tpow_z.c: various corrections.
+
+------------------------------------------------------------------------
+r4222 | vlefevre | 2006-11-17 02:27:06 +0000 (Fri, 17 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/pow_z.c
+ M /trunk/tests/tpow.c
+
+Partially fixed another bug in mpfr_pow_z (overflow/underflow detection
+for z < 0) and added corresponding testcases.
+
+------------------------------------------------------------------------
+r4221 | vlefevre | 2006-11-17 01:56:31 +0000 (Fri, 17 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/pow_z.c
+ M /trunk/tests/tpow.c
+
+Fixed a bug in mpfr_pow_z concerning the underflow flag and added the
+corresponding testcase (but the case z < 0 is still buggy concerning
+the flags).
+
+------------------------------------------------------------------------
+r4219 | zimmerma | 2006-11-16 15:02:08 +0000 (Thu, 16 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/algorithms.tex
+ M /trunk/erfc.c
+ M /trunk/tests/terf.c
+
+implemented asymptotic formula for erfc (fixed both slowness for large
+arguments, and call to MPFR_WARNING with return value NaN for huge arguments)
+
+------------------------------------------------------------------------
+r4218 | zimmerma | 2006-11-16 10:19:19 +0000 (Thu, 16 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/terf.c
+
+added new test
+
+------------------------------------------------------------------------
+r4216 | zimmerma | 2006-11-14 16:42:46 +0000 (Tue, 14 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/erfc.c
+ M /trunk/tests/terf.c
+
+fixed problem for large negative input
+
+------------------------------------------------------------------------
+r4215 | vlefevre | 2006-11-14 14:26:02 +0000 (Tue, 14 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: slight change in the proposed mpfr_lgamma prototype (arg order).
+
+------------------------------------------------------------------------
+r4214 | vlefevre | 2006-11-13 09:07:20 +0000 (Mon, 13 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/mpfr.texi
+
+About mpfr_lngamma/mpfr_lgamma: added mpfr_lgamma to TODO and updated
+mpfr_lngamma description in mpfr.texi.
+
+------------------------------------------------------------------------
+r4213 | vlefevre | 2006-11-13 08:39:16 +0000 (Mon, 13 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: update.
+
+------------------------------------------------------------------------
+r4212 | vlefevre | 2006-11-13 07:26:31 +0000 (Mon, 13 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/terf.c
+
+tests/terf.c: added a test that yields a segfault (execute "terf 1").
+
+------------------------------------------------------------------------
+r4211 | zimmerma | 2006-11-10 16:05:07 +0000 (Fri, 10 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+moved the [gs]et_decimal64 functions after the [gs]et_ld functions
+
+------------------------------------------------------------------------
+r4210 | vlefevre | 2006-11-10 15:14:58 +0000 (Fri, 10 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: changed @code{--enable-decimal-float} into @samp{...}
+for consistency with the other configure options.
+
+------------------------------------------------------------------------
+r4209 | vlefevre | 2006-11-10 15:13:30 +0000 (Fri, 10 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: updated the note concerning mpfr_eint and mpfr_erfc.
+
+------------------------------------------------------------------------
+r4208 | vlefevre | 2006-11-10 14:54:19 +0000 (Fri, 10 Nov 2006) | 9 lines
+Changed paths:
+ M /branches/new-generic-tests/tests/Makefile.am
+ M /trunk/configure.in
+ M /trunk/eint.c
+ M /trunk/erfc.c
+ M /trunk/mpfr-impl.h
+
+Added warnings support.
+ * configure.in: added --enable-warnings configure option.
+ * mpfr-impl.h: defined MPFR_WARNING(W) macro.
+ * eint.c, erfc.c: use MPFR_WARNING instead of fprintf.
+ * tests/Makefile.am (new-generic-tests branch): run the tests with
+ MPFR_QUIET=1 to avoid output of useless warnings, as some tests
+ (with large arguments) can generate such warnings, which are all
+ expected.
+
+------------------------------------------------------------------------
+r4206 | vlefevre | 2006-11-10 13:28:54 +0000 (Fri, 10 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests
+
+Added tget_set_d64 to svn:ignore property of "tests" directory.
+
+------------------------------------------------------------------------
+r4205 | vlefevre | 2006-11-10 09:05:56 +0000 (Fri, 10 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: "add a configure test for --enable-logging..."
+
+------------------------------------------------------------------------
+r4204 | vlefevre | 2006-11-10 01:30:10 +0000 (Fri, 10 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+More information for --enable-logging configure option.
+
+------------------------------------------------------------------------
+r4203 | vlefevre | 2006-11-10 01:24:33 +0000 (Fri, 10 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/logging.c
+ M /trunk/mpfr-impl.h
+
+Fixed test of logging support.
+
+------------------------------------------------------------------------
+r4202 | vlefevre | 2006-11-10 01:01:24 +0000 (Fri, 10 Nov 2006) | 5 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/configure.in
+
+Removed --with-irix64 configure option and "case $OS_TYPE" code from
+configure.in; see
+ http://sympa.loria.fr/wwsympa/arc/mpfr/2006-11/msg00009.html
+for the reasons.
+
+------------------------------------------------------------------------
+r4201 | zimmerma | 2006-11-09 14:25:48 +0000 (Thu, 09 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_set_d64.c
+
+added more checks with native format
+
+------------------------------------------------------------------------
+r4200 | zimmerma | 2006-11-09 13:37:33 +0000 (Thu, 09 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/tests/tget_set_d64.c
+
+added detection of decimal format in configure (DPD or BID)
+
+------------------------------------------------------------------------
+r4199 | vlefevre | 2006-11-09 11:39:34 +0000 (Thu, 09 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+strtofr.c: removed a useless cast (ISO C99 standard 6.2.5#3) and updated
+a comment as isdigit is no longer used.
+
+------------------------------------------------------------------------
+r4198 | vlefevre | 2006-11-09 11:13:48 +0000 (Thu, 09 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+strtofr.c fix: no longer use isdigit, as MPFR requires non-localized
+digits.
+
+------------------------------------------------------------------------
+r4197 | zimmerma | 2006-11-09 11:05:05 +0000 (Thu, 09 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/get_d64.c
+ M /trunk/set_d64.c
+ M /trunk/tests/tget_set_d64.c
+
+modified to work on 64-bit machines too
+
+------------------------------------------------------------------------
+r4196 | vlefevre | 2006-11-09 09:31:09 +0000 (Thu, 09 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/get_d64.c
+
+get_d64.c: fixed problems related to signed/unsigned values.
+
+------------------------------------------------------------------------
+r4195 | vlefevre | 2006-11-09 09:03:17 +0000 (Thu, 09 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+strtofr.c: fixed a bug that could occur on platforms with signed chars,
+when the user provides a string with negative characters (e.g. accented
+characters, in practice).
+
+------------------------------------------------------------------------
+r4194 | zimmerma | 2006-11-09 07:29:15 +0000 (Thu, 09 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/get_d64.c
+ M /trunk/set_d64.c
+ M /trunk/tests/tget_set_d64.c
+
+complete rewrite of mpfr_set_decimal64 and mpfr_get_decimal64: now use
+internal string <-> _Decimal64 conversion functions, which perform native
+conversion from/to BID or DPD
+
+------------------------------------------------------------------------
+r4193 | zimmerma | 2006-11-08 09:32:52 +0000 (Wed, 08 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added mpfr_set_decimal64 and mpfr_get_decimal64
+
+------------------------------------------------------------------------
+r4192 | vlefevre | 2006-11-08 08:55:33 +0000 (Wed, 08 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+mpfr-impl.h: fixed a compile error if _Decimal64 is unknown.
+
+------------------------------------------------------------------------
+r4191 | zimmerma | 2006-11-08 07:47:07 +0000 (Wed, 08 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/get_d64.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/set_d64.c
+ M /trunk/tests/tget_set_d64.c
+
+added new configure option --enable-decimal-float to build mpfr_set_decimal64
+and mpfr_get_decimal64 (checks _Decimal64, and _GMP_IEEE_FLOATS is defined)
+
+------------------------------------------------------------------------
+r4190 | zimmerma | 2006-11-07 16:47:45 +0000 (Tue, 07 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/get_d64.c
+ M /trunk/mpfr.h
+ M /trunk/set_d64.c
+ M /trunk/tests/tget_set_d64.c
+
+added --enable-decimal-float in configure, and corresponding macro
+WANT_DECIMAL_FLOATS
+
+------------------------------------------------------------------------
+r4189 | vlefevre | 2006-11-07 15:09:16 +0000 (Tue, 07 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tversion.c
+
+tests/tversion.c: improved error message and added gmp.h/libgmp test.
+
+------------------------------------------------------------------------
+r4188 | vlefevre | 2006-11-07 14:38:42 +0000 (Tue, 07 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tversion.c
+
+Fixed a small bug in tests/tversion.c (should never occur anyway).
+
+------------------------------------------------------------------------
+r4187 | vlefevre | 2006-11-06 01:23:37 +0000 (Mon, 06 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/logging.c
+
+logging.c: clean-up.
+
+------------------------------------------------------------------------
+r4186 | vlefevre | 2006-11-05 16:12:16 +0000 (Sun, 05 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: updated things to do before a release.
+
+------------------------------------------------------------------------
+r4185 | zimmerma | 2006-11-05 15:41:27 +0000 (Sun, 05 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/get_d64.c
+ M /trunk/get_str.c
+ M /trunk/mpfr.h
+ A /trunk/set_d64.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tget_set_d64.c
+
+added new (preliminary) conversions functions to/from decimal64
+
+------------------------------------------------------------------------
+r4184 | zimmerma | 2006-11-05 15:17:30 +0000 (Sun, 05 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/erfc.c
+
+changed header file: stdlib.h -> stdio.h
+
+------------------------------------------------------------------------
+r4183 | vlefevre | 2006-11-03 18:38:05 +0000 (Fri, 03 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Fixed a bug related to signed/unsigned types.
+
+------------------------------------------------------------------------
+r4182 | vlefevre | 2006-11-03 10:05:51 +0000 (Fri, 03 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+tgamma.c: avoid useless mpfr_get_d.
+
+------------------------------------------------------------------------
+r4181 | vlefevre | 2006-11-03 09:54:24 +0000 (Fri, 03 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+tpow.c: replaced a mpfr_cmp_d by a mpfr_cmp_str1.
+
+------------------------------------------------------------------------
+r4180 | vlefevre | 2006-11-03 09:50:45 +0000 (Fri, 03 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+lngamma.c: added a comment.
+
+------------------------------------------------------------------------
+r4179 | vlefevre | 2006-11-03 09:42:31 +0000 (Fri, 03 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tlngamma.c
+
+tlngamma.c: avoid useless mpfr_get_d.
+
+------------------------------------------------------------------------
+r4178 | vlefevre | 2006-10-27 21:21:56 +0000 (Fri, 27 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/eint.c
+
+eint.c: better overflow checking; fix: all allocated memory now freed.
+
+------------------------------------------------------------------------
+r4177 | vlefevre | 2006-10-27 17:03:32 +0000 (Fri, 27 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/eint.c
+
+eint.c: forgot 2 mpfr_clear's.
+
+------------------------------------------------------------------------
+r4174 | vlefevre | 2006-10-27 16:12:34 +0000 (Fri, 27 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/eint.c
+
+eint.c fix: and changed the #if into if.
+
+------------------------------------------------------------------------
+r4173 | vlefevre | 2006-10-27 16:10:22 +0000 (Fri, 27 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/eint.c
+
+eint.c fix: replaced BITS_PER_MP_LIMB by sizeof(mp_exp_t) * CHAR_BIT.
+
+------------------------------------------------------------------------
+r4172 | vlefevre | 2006-10-27 12:39:20 +0000 (Fri, 27 Oct 2006) | 4 lines
+Changed paths:
+ M /trunk/erfc.c
+ M /trunk/mpfr.texi
+
+The current implementation of mpfr_erfc cannot compute the result for
+large inputs. Return NaN with the erange flag set instead of aborting.
+Documented this behavior in mpfr.texi.
+
+------------------------------------------------------------------------
+r4171 | zimmerma | 2006-10-27 11:56:14 +0000 (Fri, 27 Oct 2006) | 3 lines
+Changed paths:
+ M /trunk/eint.c
+
+improved bound for x with BITS_PER_MP_LIMB=32
+ added bound for BITS_PER_MP_LIMB=64
+
+------------------------------------------------------------------------
+r4169 | vlefevre | 2006-10-27 01:30:32 +0000 (Fri, 27 Oct 2006) | 4 lines
+Changed paths:
+ M /trunk/eint.c
+ M /trunk/mpfr.texi
+
+The current implementation of mpfr_eint cannot compute the result for
+large inputs. Return NaN with the erange flag set instead of aborting.
+Documented this behavior in mpfr.texi.
+
+------------------------------------------------------------------------
+r4168 | vlefevre | 2006-10-27 00:59:33 +0000 (Fri, 27 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+tzeta.c patch 4166 should have been committed to the trunk. Fixing...
+
+------------------------------------------------------------------------
+r4167 | zimmerma | 2006-10-26 17:17:01 +0000 (Thu, 26 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/eint.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+
+added tests for overflows or underflows
+
+------------------------------------------------------------------------
+r4166 | zimmerma | 2006-10-26 15:19:43 +0000 (Thu, 26 Oct 2006) | 2 lines
+Changed paths:
+ M /branches/new-generic-tests/tests/tzeta.c
+ M /trunk/zeta.c
+
+fixed problem for large negative s (return +Inf or -Inf)
+
+------------------------------------------------------------------------
+r4165 | zimmerma | 2006-10-26 13:55:26 +0000 (Thu, 26 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/coth.c
+
+fixed dummy error in last commit
+
+------------------------------------------------------------------------
+r4164 | vlefevre | 2006-10-26 08:52:01 +0000 (Thu, 26 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/eint.c
+
+In latest change, replaced exit(1) by abort().
+
+------------------------------------------------------------------------
+r4163 | zimmerma | 2006-10-26 08:18:23 +0000 (Thu, 26 Oct 2006) | 4 lines
+Changed paths:
+ M /trunk/eint.c
+ M /trunk/tests/teint.c
+
+added test for eint()
+added error message when input is too large in eint(), waiting for asymptotic
+ expansion
+
+------------------------------------------------------------------------
+r4162 | vlefevre | 2006-10-26 01:40:17 +0000 (Thu, 26 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/coth.c
+ M /trunk/gen_inverse.h
+
+Untabified and added a FIXME.
+
+------------------------------------------------------------------------
+r4161 | zimmerma | 2006-10-25 17:49:57 +0000 (Wed, 25 Oct 2006) | 3 lines
+Changed paths:
+ M /trunk/coth.c
+ M /trunk/csch.c
+ M /trunk/gen_inverse.h
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/tsech.c
+
+fixed overflow/underflow problems in csch and sech
+fixed problem for huge argument in coth
+
+------------------------------------------------------------------------
+r4159 | vlefevre | 2006-10-25 17:01:07 +0000 (Wed, 25 Oct 2006) | 9 lines
+Changed paths:
+ M /trunk/FAQ.html
+ M /trunk/faq.xsl
+ M /trunk/update-faq
+
+FAQ-related updates:
+ * faq.xsl: Include styles from http://www.mpfr.org/styles/visual.css
+ by using a system entity (but GNOME libxslt bug 345147 is still
+ present in Debian, so don't use /*<![CDATA[*/ and /*]]>*/ yet).
+ * update-faq: add /*<![CDATA[*/ and /*]]>*/ after calling xsltproc.
+ * FAQ.html: update from the MPFR web site: various changes, including:
+ + added id attributes on dt elements (FAQ items) to allow anchors;
+ + updated FAQ for undefined references.
+
+------------------------------------------------------------------------
+r4157 | vlefevre | 2006-10-25 14:18:59 +0000 (Wed, 25 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: mention the MPFR FAQ.
+
+------------------------------------------------------------------------
+r4155 | vlefevre | 2006-10-23 02:10:13 +0000 (Mon, 23 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/set_uj.c
+
+Added a comment about a warning (this confused a user).
+
+------------------------------------------------------------------------
+r4153 | vlefevre | 2006-10-11 11:43:07 +0000 (Wed, 11 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: added an item about version information.
+
+------------------------------------------------------------------------
+r4152 | vlefevre | 2006-10-05 14:40:39 +0000 (Thu, 05 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: updated item.
+
+------------------------------------------------------------------------
+r4151 | zimmerma | 2006-10-05 10:52:30 +0000 (Thu, 05 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item
+
+------------------------------------------------------------------------
+r4149 | zimmerma | 2006-10-02 19:55:09 +0000 (Mon, 02 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed wrong emax in example for mpfr_subnormalize
+
+------------------------------------------------------------------------
+r4147 | vlefevre | 2006-09-07 09:27:11 +0000 (Thu, 07 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+MPFR manual: say that errno may be set to non-zero.
+
+------------------------------------------------------------------------
+r4145 | vlefevre | 2006-08-31 12:26:29 +0000 (Thu, 31 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+tests/tests.c: typo.
+
+------------------------------------------------------------------------
+r4143 | vlefevre | 2006-08-28 12:09:10 +0000 (Mon, 28 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/texp2.c
+
+Fixed texp2 overflow tests on 64-bit machines.
+
+------------------------------------------------------------------------
+r4142 | vlefevre | 2006-08-28 11:58:54 +0000 (Mon, 28 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+tests/reuse.c: avoid a warning; code reformatted (GNU style).
+
+------------------------------------------------------------------------
+r4140 | vlefevre | 2006-08-23 14:08:12 +0000 (Wed, 23 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: minor update.
+
+------------------------------------------------------------------------
+r4138 | vlefevre | 2006-08-21 12:51:49 +0000 (Mon, 21 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: updated "known bugs" section.
+
+------------------------------------------------------------------------
+r4136 | vlefevre | 2006-08-21 12:40:20 +0000 (Mon, 21 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+Fixed an exponent/flags-related bug in lngamma.c.
+
+------------------------------------------------------------------------
+r4134 | vlefevre | 2006-08-21 11:12:25 +0000 (Mon, 21 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk
+
+Updated svn:ignore property.
+
+------------------------------------------------------------------------
+r4133 | vlefevre | 2006-08-20 08:34:40 +0000 (Sun, 20 Aug 2006) | 5 lines
+Changed paths:
+ M /trunk/pow.c
+ M /trunk/tests/tpow.c
+
+Fixed several problems in pow.c concerning underflows, overflows and
+flags (including the inexact flag, which could be incorrectly set in
+case of NaN), and added some testcases. Problems in pow_z.c have not
+been fixed yet.
+
+------------------------------------------------------------------------
+r4131 | vlefevre | 2006-08-20 00:44:26 +0000 (Sun, 20 Aug 2006) | 5 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+
+Partial fix: The inexact flag was not always set in some functions.
+In particular, it is now set by mpfr_check_range (if t is not zero)
+since mpfr_check_range usually comes just after MPFR_SAVE_EXPO_FREE
+(which restores the previous flags).
+
+------------------------------------------------------------------------
+r4129 | vlefevre | 2006-08-19 14:33:23 +0000 (Sat, 19 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/tests/texp2.c
+
+Added an assertion for mpfr_exp2 and a test.
+
+------------------------------------------------------------------------
+r4127 | vlefevre | 2006-08-16 20:09:49 +0000 (Wed, 16 Aug 2006) | 5 lines
+Changed paths:
+ M /trunk/expm1.c
+
+Optimized mpfr_expm1 for large (in absolute value) negative values in
+order to avoid the TMD (the result is very close to -1). Without this
+patch, mpfr_expm1 could take dozens of MBs and the new generic tests
+for texpm1 could take several hours instead of less than 1 second.
+
+------------------------------------------------------------------------
+r4125 | vlefevre | 2006-08-16 16:31:25 +0000 (Wed, 16 Aug 2006) | 7 lines
+Changed paths:
+ M /trunk/expm1.c
+
+Fixed a bug in expm1 for very small negative arguments (and perhaps
+some very small positive arguments too); this bug is similar to the
+one in log1p that was recently found and fixed. It was detected by
+the new generic tests (not committed yet), therefore no testcases
+are provided. Note: the mpfr_expm1 function is still buggy (freezes
+on -0.10E18, prec 2 -> prec 13); this is a different bug.
+
+------------------------------------------------------------------------
+r4123 | vlefevre | 2006-08-16 09:20:00 +0000 (Wed, 16 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/tests/texp2.c
+
+In mpfr_exp2, the overflow flag was not set if mpfr_exp2 overflowed
+with x < emax. Added testcase.
+
+------------------------------------------------------------------------
+r4121 | vlefevre | 2006-08-15 17:52:21 +0000 (Tue, 15 Aug 2006) | 4 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/tests/texp2.c
+
+The latest mpfr_exp2 fix contained a bug. Partially rewrote mpfr_exp2
+to fix this bug and another one (and added a corresponding testcase:
+exp2(10000000000.5), which was freezing).
+
+------------------------------------------------------------------------
+r4119 | vlefevre | 2006-08-15 11:37:20 +0000 (Tue, 15 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+Better fix for exp2 exponent range bug.
+
+------------------------------------------------------------------------
+r4117 | vlefevre | 2006-08-15 10:44:34 +0000 (Tue, 15 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/tests/texp2.c
+
+Fixed bug in mpfr_exp2 when the argument is an integer and emin > 1.
+Added a testcase to texp2.
+
+------------------------------------------------------------------------
+r4116 | vlefevre | 2006-08-14 23:00:39 +0000 (Mon, 14 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/tests
+
+Added tget_ld_2exp to svn:ignore property of "tests" directory
+(should have been done in rev 4028).
+
+------------------------------------------------------------------------
+r4114 | vlefevre | 2006-08-14 22:23:01 +0000 (Mon, 14 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/log1p.c
+ M /trunk/tests/tlog1p.c
+
+Fixed bug in log1p for small negative values of x and added testcase.
+
+------------------------------------------------------------------------
+r4112 | vlefevre | 2006-08-14 17:39:01 +0000 (Mon, 14 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+Code style correction for ansi2knr.
+
+------------------------------------------------------------------------
+r4110 | vlefevre | 2006-07-25 21:10:21 +0000 (Tue, 25 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: more information.
+
+------------------------------------------------------------------------
+r4108 | vlefevre | 2006-07-25 20:36:23 +0000 (Tue, 25 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: added a note about include/library paths.
+
+------------------------------------------------------------------------
+r4106 | vlefevre | 2006-07-21 08:22:40 +0000 (Fri, 21 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+INSTALL: added information about setup after the library installation.
+
+------------------------------------------------------------------------
+r4104 | vlefevre | 2006-07-20 07:23:06 +0000 (Thu, 20 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Improved linker flag settings on darwin.
+
+------------------------------------------------------------------------
+r4103 | vlefevre | 2006-07-18 07:51:58 +0000 (Tue, 18 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: fixed a linking problem on darwin.
+
+------------------------------------------------------------------------
+r4101 | vlefevre | 2006-07-16 02:52:18 +0000 (Sun, 16 Jul 2006) | 5 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/tests/Makefile.am
+
+One needs automake 1.6; autoreconf fails with automake 1.4. Adding
+the 1.6 automake option will make the error message less obfuscated,
+but unfortunately, one won't have the necessary automake version
+automatically called, even if it is installed.
+
+------------------------------------------------------------------------
+r4099 | zimmerma | 2006-07-05 14:35:36 +0000 (Wed, 05 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item
+
+------------------------------------------------------------------------
+r4098 | zimmerma | 2006-07-05 14:23:57 +0000 (Wed, 05 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/root.c
+
+fixed wrong comment (thanks Keith Briggs)
+
+------------------------------------------------------------------------
+r4097 | zimmerma | 2006-07-05 14:23:16 +0000 (Wed, 05 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/root.c
+
+new mpn_rootrem is still not in gmp-4.2
+
+------------------------------------------------------------------------
+r4096 | zimmerma | 2006-06-20 12:55:55 +0000 (Tue, 20 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+replaced <= by =
+
+------------------------------------------------------------------------
+r4095 | zimmerma | 2006-06-19 13:57:32 +0000 (Mon, 19 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+changed <= into =
+
+------------------------------------------------------------------------
+r4094 | zimmerma | 2006-06-19 09:10:38 +0000 (Mon, 19 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+comments from Keith Briggs
+
+------------------------------------------------------------------------
+r4093 | vlefevre | 2006-06-09 13:36:30 +0000 (Fri, 09 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: corrected several English mistakes and typography.
+
+------------------------------------------------------------------------
+r4092 | zimmerma | 2006-06-09 12:41:47 +0000 (Fri, 09 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+fixed typo
+
+------------------------------------------------------------------------
+r4091 | zimmerma | 2006-06-09 09:51:59 +0000 (Fri, 09 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+replaced error() by \error()
+
+------------------------------------------------------------------------
+r4090 | vlefevre | 2006-06-09 08:17:58 +0000 (Fri, 09 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: another fixed notation for roundings.
+
+------------------------------------------------------------------------
+r4089 | zimmerma | 2006-06-09 08:07:29 +0000 (Fri, 09 Jun 2006) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added section on Notations
+fixed notations for roundings
+
+------------------------------------------------------------------------
+r4088 | vlefevre | 2006-06-09 07:49:43 +0000 (Fri, 09 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+algorithms.tex: changed the page style to plain (for page numbers).
+
+------------------------------------------------------------------------
+r4086 | vlefevre | 2006-06-07 23:48:43 +0000 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update.
+
+------------------------------------------------------------------------
+r4083 | vlefevre | 2006-05-29 19:00:31 +0000 (Mon, 29 May 2006) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Define HAVE_ATTRIBUTE_MODE if supported; useful for s390, but incomplete
+and will fail on platforms with gcc and CHAR_BIT != 8.
+
+------------------------------------------------------------------------
+r4081 | vlefevre | 2006-05-19 16:43:35 +0000 (Fri, 19 May 2006) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Add compiler flags (CPPFLAGS, LDFLAGS) in a consistent order.
+
+------------------------------------------------------------------------
+r4079 | vlefevre | 2006-05-18 00:10:06 +0000 (Thu, 18 May 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+MPFR manual consistency: Custom interface -> Custom Interface.
+
+------------------------------------------------------------------------
+r4075 | vlefevre | 2006-05-17 23:20:38 +0000 (Wed, 17 May 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: added a note about the change 4049 in div.c.
+
+------------------------------------------------------------------------
+r4072 | vlefevre | 2006-04-18 15:08:52 +0000 (Tue, 18 Apr 2006) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+
+Removed the #ifndef __hpux from mul.c (after a test on a HP-UX machine,
+I got no failures, even with the old mpfr-longlong.h).
+
+------------------------------------------------------------------------
+r4071 | vlefevre | 2006-04-18 14:38:10 +0000 (Tue, 18 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added a point on mpfr-longlong.h in "To make a release".
+
+------------------------------------------------------------------------
+r4070 | vlefevre | 2006-04-18 14:37:19 +0000 (Tue, 18 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr-longlong.h
+
+Updated mpfr-longlong.h from the GMP 4.2 longlong.h file.
+
+------------------------------------------------------------------------
+r4068 | vlefevre | 2006-04-18 13:30:52 +0000 (Tue, 18 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr.texi: removed dot from a section title.
+
+------------------------------------------------------------------------
+r4066 | vlefevre | 2006-04-11 13:54:39 +0000 (Tue, 11 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update.
+
+------------------------------------------------------------------------
+r4065 | vlefevre | 2006-04-06 13:58:46 +0000 (Thu, 06 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+div.c: removed the bad use of MPFR_LIMB_ZERO.
+
+------------------------------------------------------------------------
+r4064 | vlefevre | 2006-04-06 12:52:24 +0000 (Thu, 06 Apr 2006) | 3 lines
+Changed paths:
+ M /trunk/get_f.c
+
+In get_f.c, updated the case precy + sh > precx: this one was correct,
+but added a comment, assertions and simplified a MPN_ZERO.
+
+------------------------------------------------------------------------
+r4063 | vlefevre | 2006-04-05 16:32:23 +0000 (Wed, 05 Apr 2006) | 4 lines
+Changed paths:
+ M /trunk/tests/tget_f.c
+
+tget_f.c: test that there is no lost of accuracy when converting
+a mpfr_t number into a mpf_t number (test with various precisions
+and exponents).
+
+------------------------------------------------------------------------
+r4062 | vlefevre | 2006-04-05 15:52:26 +0000 (Wed, 05 Apr 2006) | 3 lines
+Changed paths:
+ M /trunk/get_f.c
+
+The fix of get_f.c was wrong. This should be now OK for the case
+precy + sh <= precx.
+
+------------------------------------------------------------------------
+r4061 | vlefevre | 2006-04-05 09:31:34 +0000 (Wed, 05 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/get_f.c
+ M /trunk/tests/tget_f.c
+
+Fixed bug in mpfr_get_f (reported by Yury Lukach) and added test.
+
+------------------------------------------------------------------------
+r4059 | vlefevre | 2006-03-31 16:47:40 +0000 (Fri, 31 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/fdl.texi
+
+Updated FDL to version 1.2.
+
+------------------------------------------------------------------------
+r4057 | vlefevre | 2006-03-31 16:30:52 +0000 (Fri, 31 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+ M /trunk/lngamma.c
+ M /trunk/mparam_h.in
+ M /trunk/mpzroot.c
+ M /trunk/tests/mpf_compat.h
+
+Updated FSF address.
+
+------------------------------------------------------------------------
+r4055 | vlefevre | 2006-03-31 14:19:52 +0000 (Fri, 31 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/minmax.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-longlong.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_ld_2exp.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Fixed FSF address.
+
+------------------------------------------------------------------------
+r4053 | vlefevre | 2006-03-30 14:41:30 +0000 (Thu, 30 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+Another FAQ update (taking GMP 4.2 into account).
+
+------------------------------------------------------------------------
+r4051 | vlefevre | 2006-03-30 14:22:52 +0000 (Thu, 30 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+FAQ update.
+
+------------------------------------------------------------------------
+r4050 | vlefevre | 2006-03-24 14:46:54 +0000 (Fri, 24 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-impl.h
+
+Removed all code related to mpn_sub_nc (no longer used).
+
+------------------------------------------------------------------------
+r4049 | vlefevre | 2006-03-24 13:51:52 +0000 (Fri, 24 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+div.c: fixed a bug and no longer use mpn_sub_nc.
+
+------------------------------------------------------------------------
+r4048 | vlefevre | 2006-03-24 12:43:41 +0000 (Fri, 24 Mar 2006) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+Some clean-up in div.c; do not steal GMP's namespace (could lead to
+clashes if future GMP versions define the corresponding macros).
+
+------------------------------------------------------------------------
+r4047 | vlefevre | 2006-03-24 08:49:28 +0000 (Fri, 24 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/configure.in
+
+Build shared libraries by default.
+
+------------------------------------------------------------------------
+r4046 | vlefevre | 2006-03-23 10:57:46 +0000 (Thu, 23 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+
+random2.c: minor change suggested by Patrick.
+
+------------------------------------------------------------------------
+r4044 | vlefevre | 2006-03-23 09:18:54 +0000 (Thu, 23 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+configure.in: typography consistency.
+
+------------------------------------------------------------------------
+r4043 | vlefevre | 2006-03-23 09:16:34 +0000 (Thu, 23 Mar 2006) | 4 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Mention --enable-thread-safe and --enable-shared in the INSTALL file
+since users may need them and could be confused otherwise (just seen
+that). Untabified the file.
+
+------------------------------------------------------------------------
+r4041 | vlefevre | 2006-03-16 18:10:24 +0000 (Thu, 16 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+TODO: new exception "division by zero" / "pole".
+
+------------------------------------------------------------------------
+r4040 | vlefevre | 2006-03-16 18:04:36 +0000 (Thu, 16 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: added "Do not use C99-only features, such as...".
+
+------------------------------------------------------------------------
+r4038 | zimmerma | 2006-03-16 14:49:50 +0000 (Thu, 16 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/expm1.c
+ M /trunk/log1p.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/zeta.c
+
+replaced 6th empty argument of MPFR_FAST_COMPUTE_IF_SMALL_INPUT by {}
+
+------------------------------------------------------------------------
+r4037 | vlefevre | 2006-03-14 16:07:28 +0000 (Tue, 14 Mar 2006) | 3 lines
+Changed paths:
+ M /trunk/random2.c
+
+In random2.c, replaced NULL by 0 (more general) and removed the
+now unnecessary #include <stdio.h>.
+
+------------------------------------------------------------------------
+r4036 | zimmerma | 2006-03-14 15:33:31 +0000 (Tue, 14 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+
+added missing include file
+
+------------------------------------------------------------------------
+r4035 | vlefevre | 2006-03-14 14:59:00 +0000 (Tue, 14 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Tests: added new worst case for x^(3/2).
+
+------------------------------------------------------------------------
+r4034 | zimmerma | 2006-03-02 17:28:41 +0000 (Thu, 02 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+added reference to INRIA report for Zeta
+
+------------------------------------------------------------------------
+r4033 | zimmerma | 2006-03-02 11:05:35 +0000 (Thu, 02 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+added another reference
+
+------------------------------------------------------------------------
+r4032 | zimmerma | 2006-03-02 11:02:23 +0000 (Thu, 02 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+added reference
+
+------------------------------------------------------------------------
+r4031 | vlefevre | 2006-02-28 23:20:24 +0000 (Tue, 28 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+More details concerning mpfr_eq.
+
+------------------------------------------------------------------------
+r4030 | zimmerma | 2006-02-28 10:46:59 +0000 (Tue, 28 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+removed "but does not make much sense"
+
+------------------------------------------------------------------------
+r4029 | zimmerma | 2006-02-28 09:39:25 +0000 (Tue, 28 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added contribution from Damien
+
+------------------------------------------------------------------------
+r4028 | zimmerma | 2006-02-28 09:18:17 +0000 (Tue, 28 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tget_ld_2exp.c
+
+new test file for mpfr_get_ld_2exp
+
+------------------------------------------------------------------------
+r4027 | zimmerma | 2006-02-27 10:15:24 +0000 (Mon, 27 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+ M /trunk/get_ld.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+added mpfr_get_ld_2exp (contributed by Damien Stehle)
+
+------------------------------------------------------------------------
+r4026 | vlefevre | 2006-02-20 14:40:28 +0000 (Mon, 20 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Updated mpfr_random2 user documentation.
+
+------------------------------------------------------------------------
+r4024 | vlefevre | 2006-02-20 10:12:06 +0000 (Mon, 20 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+ M /trunk/tests/trandom.c
+
+Fixed bug in mpfr_random2 when size == 0 and added testcase.
+
+------------------------------------------------------------------------
+r4023 | vlefevre | 2006-02-20 10:07:41 +0000 (Mon, 20 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+
+trandom.c: reformat.
+
+------------------------------------------------------------------------
+r4022 | vlefevre | 2006-02-20 10:06:47 +0000 (Mon, 20 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+
+trandom.c: use calloc instead of malloc and check return value.
+
+------------------------------------------------------------------------
+r4021 | vlefevre | 2006-02-20 09:42:13 +0000 (Mon, 20 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+
+mpfr_random2_raw -> static.
+
+------------------------------------------------------------------------
+r4019 | vlefevre | 2006-02-17 08:17:46 +0000 (Fri, 17 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Added mpfr_remainder to TODO.
+
+------------------------------------------------------------------------
+r4018 | zimmerma | 2006-02-15 14:40:35 +0000 (Wed, 15 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+
+fixed wrong url
+
+------------------------------------------------------------------------
+r4017 | vlefevre | 2006-02-15 13:41:51 +0000 (Wed, 15 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+Fixed various spelling mistakes, typos... in algorithms.tex.
+
+------------------------------------------------------------------------
+r4016 | vlefevre | 2006-02-15 13:20:41 +0000 (Wed, 15 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+In algorithms.tex, \em -> \emph.
+
+------------------------------------------------------------------------
+r4015 | vlefevre | 2006-02-15 13:17:33 +0000 (Wed, 15 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+Typography corrections in algorithms.tex.
+
+------------------------------------------------------------------------
+r4014 | vlefevre | 2006-02-15 13:04:22 +0000 (Wed, 15 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+In algorithms.tex, added a missing blackslash.
+
+------------------------------------------------------------------------
+r4013 | vlefevre | 2006-02-15 13:02:07 +0000 (Wed, 15 Feb 2006) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+In algorithms.tex, removed \date (was incorrectly used) and added the
+web site as a footnote.
+
+------------------------------------------------------------------------
+r4012 | vlefevre | 2006-02-13 17:25:19 +0000 (Mon, 13 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+ M /trunk/tests/trandom.c
+
+Code reformatted. C99 comment replaced by traditional comment.
+
+------------------------------------------------------------------------
+r4011 | hanrot | 2006-02-13 15:03:43 +0000 (Mon, 13 Feb 2006) | 6 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/random2.c
+ M /trunk/tests/trandom.c
+
+* Added comments on all random number generator functions ;
+* Inlined the mpn_random2 code in mpfr_random2, to avoid the use of the
+same internal randstate ; added a mpfr_random2_raw (not exported at the
+time) to allow specification of a randstate ;
+* Checked normalization of the result of random2 in trandom.c
+
+------------------------------------------------------------------------
+r4009 | vlefevre | 2006-01-31 09:53:51 +0000 (Tue, 31 Jan 2006) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Changed a part of the documentation of mpfr_get_d_2exp, introduced in
+rev 4008, to specify a behavior very similar to the ISO C standard.
+
+------------------------------------------------------------------------
+r4008 | zimmerma | 2006-01-31 07:28:05 +0000 (Tue, 31 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed documentation bug
+
+------------------------------------------------------------------------
+r4006 | vlefevre | 2006-01-19 15:00:18 +0000 (Thu, 19 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+ M /trunk/tests/tset_ld.c
+
+Reverted comments on <float.h> (that were added in r3976).
+
+------------------------------------------------------------------------
+r4005 | vlefevre | 2006-01-19 14:53:44 +0000 (Thu, 19 Jan 2006) | 6 lines
+Changed paths:
+ M /trunk/get_d.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set_d.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tset_ld.c
+
+Replaced -0.0 by a new macro DBL_NEG_ZERO. With MSVC, the negative zero
+no longer depends on the non-standard _chgsign function, as
+ static double double_zero = 0.0;
+ # define DBL_NEG_ZERO (-double_zero)
+has been reported to work.
+
+------------------------------------------------------------------------
+r4004 | vlefevre | 2006-01-17 12:31:26 +0000 (Tue, 17 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Added comments.
+
+------------------------------------------------------------------------
+r4002 | vlefevre | 2006-01-13 14:37:25 +0000 (Fri, 13 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/get_f.c
+
+Type clean-up.
+
+------------------------------------------------------------------------
+r4001 | vlefevre | 2006-01-13 14:11:41 +0000 (Fri, 13 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_f.c
+
+The problem with the conversion was not completely fixed... Now OK.
+
+------------------------------------------------------------------------
+r4000 | vlefevre | 2006-01-13 14:04:31 +0000 (Fri, 13 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_f.c
+
+Fixed conversion with a non-representable value.
+
+------------------------------------------------------------------------
+r3999 | vlefevre | 2006-01-13 13:31:23 +0000 (Fri, 13 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_f.c
+
+Untabify.
+
+------------------------------------------------------------------------
+r3997 | vlefevre | 2006-01-12 10:27:27 +0000 (Thu, 12 Jan 2006) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+
+More reliable tests for mpfr_set_f (x, y, GMP_RNDN) for
+y = 2^emax and y = 2^(emax-1).
+
+------------------------------------------------------------------------
+r3996 | vlefevre | 2006-01-12 10:15:33 +0000 (Thu, 12 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+
+Use mpfr_get_emax() instead of obsolete __mpfr_emax.
+
+------------------------------------------------------------------------
+r3995 | vlefevre | 2006-01-12 10:12:29 +0000 (Thu, 12 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+
+More reliable test for mpfr_set_f (x, y, GMP_RNDN) for y=2^ULONG_MAX.
+
+------------------------------------------------------------------------
+r3994 | vlefevre | 2006-01-12 10:00:45 +0000 (Thu, 12 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+
+Untabified.
+
+------------------------------------------------------------------------
+r3993 | vlefevre | 2006-01-12 09:56:13 +0000 (Thu, 12 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+
+Fixed a bug related to exponent range.
+
+------------------------------------------------------------------------
+r3992 | vlefevre | 2006-01-12 09:47:53 +0000 (Thu, 12 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+
+Replaced obsolete __mpfr_emax by __gmpfr_emax.
+
+------------------------------------------------------------------------
+r3990 | vlefevre | 2006-01-11 16:50:15 +0000 (Wed, 11 Jan 2006) | 2 lines
+Changed paths:
+ D /trunk/add_one_ulp.c
+ D /trunk/sub_one_ulp.c
+
+Removed add_one_ulp.c and sub_one_ulp.c (no longer used).
+
+------------------------------------------------------------------------
+r3987 | vlefevre | 2006-01-10 13:49:26 +0000 (Tue, 10 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+MPFR manual: changes from Paul concerning the ulps.
+
+------------------------------------------------------------------------
+r3986 | vlefevre | 2006-01-10 09:32:17 +0000 (Tue, 10 Jan 2006) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+In the manual, replaced "exact rounding" by "correct rounding",
+and added a sentence on the consequence of correct rounding (as
+suggested by Paul).
+
+------------------------------------------------------------------------
+r3985 | vlefevre | 2006-01-05 02:20:28 +0000 (Thu, 05 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/expm1.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/gamma.c
+ M /trunk/generic.c
+ M /trunk/get_exp.c
+ M /trunk/isinf.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/iszero.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mpfr-gmp.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/powerof2.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/set.c
+ M /trunk/set_exp.c
+ M /trunk/set_inf.c
+ M /trunk/set_nan.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/tanh.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Added ', Inc.' when missing after 'Free Software Foundation'.
+
+------------------------------------------------------------------------
+r3984 | vlefevre | 2006-01-05 02:14:39 +0000 (Thu, 05 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: Added a note about copyright notices.
+
+------------------------------------------------------------------------
+r3983 | vlefevre | 2006-01-05 02:02:47 +0000 (Thu, 05 Jan 2006) | 7 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/FAQ.html
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/abort_prec_max.c
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_one_ulp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/faq.xsl
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/lngamma.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/minmax.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mparam_h.in
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-longlong.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpn_exp.c
+ M /trunk/mpzroot.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/rootrem.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/stack_interface.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlngamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstckintc.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsubnormal.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tests/tzeta_ui.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/zeta.c
+ M /trunk/zeta_ui.c
+
+Updated the copyright notices according to the new GNU rules on:
+ http://www.gnu.org/prep/maintain/maintain.html#Copyright-Notices
+i.e. added 2006 to every MPFR file.
+Note: the copyright notices (currently 336) should match the regexp
+ Copyright.* 2006 Free Software
+so that it will be easier to update them for the next year...
+
+------------------------------------------------------------------------
+r3982 | zimmerma | 2006-01-03 11:49:03 +0000 (Tue, 03 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added suggestion from K. Briggs
+
+------------------------------------------------------------------------
+r3981 | vlefevre | 2006-01-01 22:22:53 +0000 (Sun, 01 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+
+Updated copyright line (we are now in 2006!).
+
+------------------------------------------------------------------------
+r3980 | zimmerma | 2006-01-01 21:09:01 +0000 (Sun, 01 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+
+use mpfr_overflow
+
+------------------------------------------------------------------------
+r3979 | zimmerma | 2005-12-29 17:48:46 +0000 (Thu, 29 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+ M /trunk/tests/tset_f.c
+
+fixed bug in mpfr_set_f for huge argument
+
+------------------------------------------------------------------------
+r3978 | zimmerma | 2005-12-26 11:04:31 +0000 (Mon, 26 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/get_f.c
+ M /trunk/tests/tget_f.c
+
+bug fix in mpfr_get_f
+
+------------------------------------------------------------------------
+r3976 | zimmerma | 2005-12-23 15:45:17 +0000 (Fri, 23 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+ M /trunk/tests/tset_ld.c
+
+updated comment for float.h (_chgsign)
+
+------------------------------------------------------------------------
+r3975 | zimmerma | 2005-12-23 15:33:43 +0000 (Fri, 23 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+fixed bug found by Vincent (worst-case)
+
+------------------------------------------------------------------------
+r3974 | zimmerma | 2005-12-23 12:28:00 +0000 (Fri, 23 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+ M /trunk/tests/tset_ld.c
+
+patch for Visual C (does not compile -0.0 properly)
+
+------------------------------------------------------------------------
+r3973 | zimmerma | 2005-12-23 12:17:45 +0000 (Fri, 23 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+patch for Visual C (-0.0)
+
+------------------------------------------------------------------------
+r3972 | zimmerma | 2005-12-20 21:09:41 +0000 (Tue, 20 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+fixed typo
+
+------------------------------------------------------------------------
+r3971 | vlefevre | 2005-12-16 16:58:24 +0000 (Fri, 16 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+Better definition for mpf_set_prec_raw (so that the value is kept).
+
+------------------------------------------------------------------------
+r3970 | vlefevre | 2005-12-08 11:56:03 +0000 (Thu, 08 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+
+Updated a comment.
+
+------------------------------------------------------------------------
+r3969 | vlefevre | 2005-12-08 11:51:41 +0000 (Thu, 08 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+
+Added test cases for a bug introduced on 2005-01-29 in sin.c rev 3248.
+
+------------------------------------------------------------------------
+r3968 | vlefevre | 2005-12-08 02:12:03 +0000 (Thu, 08 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+README.dev: remember to test MPFR on the worst cases.
+
+------------------------------------------------------------------------
+r3967 | zimmerma | 2005-11-29 20:56:16 +0000 (Tue, 29 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+added lemma + reference
+
+------------------------------------------------------------------------
+r3966 | vlefevre | 2005-11-25 01:36:29 +0000 (Fri, 25 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Removed mpfr_div bug from BUGS (as it has been fixed).
+
+------------------------------------------------------------------------
+r3964 | vlefevre | 2005-11-25 00:59:13 +0000 (Fri, 25 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+Added consistency tests for mpfr_div (e.g. to test small-size divisors).
+
+------------------------------------------------------------------------
+r3963 | zimmerma | 2005-11-24 20:39:23 +0000 (Thu, 24 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+fixed efficiency bug for small divisor (division had same cost than for
+divisor of the same size than the result)
+
+------------------------------------------------------------------------
+r3960 | vlefevre | 2005-11-23 14:35:54 +0000 (Wed, 23 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+
+Updated FAQ.
+
+------------------------------------------------------------------------
+r3959 | vlefevre | 2005-11-23 14:35:38 +0000 (Wed, 23 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/faq.xsl
+
+faq.xsl: add copyright information to the downloaded FAQ.
+
+------------------------------------------------------------------------
+r3957 | vlefevre | 2005-11-23 10:53:04 +0000 (Wed, 23 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/README.dev
+ M /trunk/update-version
+
+Added information about the patches to the INSTALL file.
+
+------------------------------------------------------------------------
+r3956 | vlefevre | 2005-11-23 08:38:39 +0000 (Wed, 23 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+
+BUGS: Noted the slow division when the precision of the divisor
+is small compared to the precision of the target.
+
+------------------------------------------------------------------------
+r3955 | vlefevre | 2005-11-21 20:31:47 +0000 (Mon, 21 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/rootrem.c
+
+Fixed a bug preventing the compilation of MPFR with GMP 4.1.90
+(non-public development version) without the build directory.
+
+------------------------------------------------------------------------
+r3954 | vlefevre | 2005-11-21 14:43:49 +0000 (Mon, 21 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/rootrem.c
+
+Fixed memory leak in mpfr_mpn_rootrem().
+
+------------------------------------------------------------------------
+r3953 | vlefevre | 2005-11-09 16:34:09 +0000 (Wed, 09 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Added a note about running the trunk tests in a branch.
+
+------------------------------------------------------------------------
+r3952 | vlefevre | 2005-11-09 16:18:35 +0000 (Wed, 09 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tinternals.c
+ M /trunk/tests/tzeta_ui.c
+
+Make trunk tests work with MPFR 2.2 (branch), by testing the version.
+
+------------------------------------------------------------------------
+r3951 | vlefevre | 2005-11-09 16:09:16 +0000 (Wed, 09 Nov 2005) | 2 lines
+Changed paths:
+ D /trunk/tests/.cvsignore
+
+Removed .cvsignore file (useless after the switch to Subversion).
+
+------------------------------------------------------------------------
+r3948 | vlefevre | 2005-11-09 15:42:41 +0000 (Wed, 09 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/cache.c
+
+Added a MPFR_UNLIKELY.
+
+------------------------------------------------------------------------
+r3947 | vlefevre | 2005-11-09 14:41:46 +0000 (Wed, 09 Nov 2005) | 5 lines
+Changed paths:
+ M /trunk/round_near_x.c
+
+In mpfr_round_near_x, use the new MPFR_RNDRAW_GEN with a correct middle
+handler instead of MPFR_RNDRAW_EVEN so that the correction of the wrong
+rounding is no longer necessary (BTW, the wrong rounding could have lead
+to problems in case of intermediate underflow/overflow -- not checked).
+
+------------------------------------------------------------------------
+r3946 | vlefevre | 2005-11-09 14:05:46 +0000 (Wed, 09 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tinternals.c
+
+mpfr_round_near_x test completed.
+
+------------------------------------------------------------------------
+r3945 | vlefevre | 2005-11-09 11:57:03 +0000 (Wed, 09 Nov 2005) | 9 lines
+Changed paths:
+ M /trunk/tests/tcbrt.c
+
+Added a test for mpfr_cbrt, from the following failure with MPFR 2.2
+and gcc 4.0.2 under Linux/m68k:
+ Seed GMP_CHECK_RANDOMIZE=1131612275 (include this in bug reports)
+ results differ for x=1.1000e-2 prec=5 rnd_mode=GMP_RNDN
+ got 1.1000e-1
+ expected 1.0111e-1
+ approx 0.101110001001100E0
+ FAIL: tcbrt
+
+------------------------------------------------------------------------
+r3943 | vlefevre | 2005-11-04 22:11:53 +0000 (Fri, 04 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Improved note r3493 concerning mpfr_set_d/ld.
+
+------------------------------------------------------------------------
+r3941 | vlefevre | 2005-11-04 14:26:49 +0000 (Fri, 04 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+More information in the "Reporting Bugs" section.
+
+------------------------------------------------------------------------
+r3940 | vlefevre | 2005-11-04 01:28:04 +0000 (Fri, 04 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Added a comment about the macros MPFR_RNDRAW* and the labels.
+
+------------------------------------------------------------------------
+r3939 | vlefevre | 2005-11-04 00:58:23 +0000 (Fri, 04 Nov 2005) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+Moved definitions of struct __gmpfr_cache_s and mpfr_cache_t, and
+declarations of mpfr_init_cache, mpfr_clear_cache and mpfr_cache
+from mpfr.h to mpfr-impl.h as they are internal (not documented).
+
+------------------------------------------------------------------------
+r3938 | vlefevre | 2005-11-03 16:39:31 +0000 (Thu, 03 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tinternals.c
+
+Eliminated the case inex == 0.
+
+------------------------------------------------------------------------
+r3937 | vlefevre | 2005-11-03 16:26:38 +0000 (Thu, 03 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tinternals.c
+
+Started to write code to test mpfr_round_near_x.
+
+------------------------------------------------------------------------
+r3936 | vlefevre | 2005-11-03 14:32:01 +0000 (Thu, 03 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/strtofr.c
+
+Typos & English usage.
+
+------------------------------------------------------------------------
+r3935 | vlefevre | 2005-11-03 14:27:26 +0000 (Thu, 03 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/round_near_x.c
+
+Fixed typos.
+
+------------------------------------------------------------------------
+r3934 | zimmerma | 2005-11-03 09:24:43 +0000 (Thu, 03 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+added hint on forbidden variable name
+
+------------------------------------------------------------------------
+r3932 | zimmerma | 2005-11-03 07:35:53 +0000 (Thu, 03 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+added "tune" item for new releases
+
+------------------------------------------------------------------------
+r3931 | zimmerma | 2005-11-03 07:24:38 +0000 (Thu, 03 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+done make tune for amd64 with gmp-4.1.4
+
+------------------------------------------------------------------------
+r3929 | vlefevre | 2005-11-02 17:22:13 +0000 (Wed, 02 Nov 2005) | 15 lines
+Changed paths:
+ M /trunk/cache.c
+ M /trunk/hypot.c
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/thypot.c
+
+Merged the changes from branch vlefevre:
+ * mpfr-impl.h: Added MPFR_RNDRAW_GEN based on MPFR_RNDRAW and
+ MPFR_RNDRAW_EVEN codes, but taking an additional argument: a
+ handler executed in rounding to nearest mode when the value
+ is the middle of two consecutive numbers in dest precision.
+ MPFR_RNDRAW and MPFR_RNDRAW_EVEN are now defined by a "call"
+ to MPFR_RNDRAW_GEN.
+ * cache.c: Clean-up and use MPFR_RNDRAW_GEN instead of
+ MPFR_RNDRAW_EVEN to avoid an unnecessary correction in the
+ halfway case.
+ * hypot.c: Fixed mpfr_hypot when the rounding mode is to nearest,
+ x is "much larger" than y, and x is the middle of two consecutive
+ numbers in the target precision.
+ * tests/thypot.c: Added the corresponding testcase.
+
+------------------------------------------------------------------------
+r3928 | vlefevre | 2005-11-02 17:09:25 +0000 (Wed, 02 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk
+ M /trunk/tests
+
+Updated svn:ignore property.
+
+------------------------------------------------------------------------
+r3926 | zimmerma | 2005-11-02 16:12:59 +0000 (Wed, 02 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+fixed remaining problems
+
+------------------------------------------------------------------------
+r3924 | zimmerma | 2005-11-02 13:49:00 +0000 (Wed, 02 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+
+declared variables as mp_prec_t instead of int
+use MPFR_MPZ_SIZEINBASE2 instead of mpz_sizeinbase
+
+------------------------------------------------------------------------
+r3919 | vlefevre | 2005-11-02 09:27:53 +0000 (Wed, 02 Nov 2005) | 5 lines
+Changed paths:
+ M /trunk/constant.c
+ M /trunk/mpfr-impl.h
+
+Reverted the latest change to constant.c: removed MPFR_THREAD_ATTR as
+these constants can be shared. Removed MPFR_THREAD_ATTR from mpfr-impl.h
+too (this should have been the right correction for rev 3838 concerning
+the type mismatch). Thanks to Patrick for noticing this.
+
+------------------------------------------------------------------------
+r3918 | vlefevre | 2005-10-31 21:27:08 +0000 (Mon, 31 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/int_ceil_log2.c
+ M /trunk/mpfr-impl.h
+
+Added an MPFR_UNLIKELY (suggested by Patrick) and an MPFR_ASSERTN.
+
+------------------------------------------------------------------------
+r3917 | zimmerma | 2005-10-31 18:55:13 +0000 (Mon, 31 Oct 2005) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/exp3.c
+
+factored calls to gmp_alloc
+removed unused variables
+
+------------------------------------------------------------------------
+r3916 | zimmerma | 2005-10-31 14:49:45 +0000 (Mon, 31 Oct 2005) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/atan.c
+ M /trunk/tanh.c
+
+improved atan (now can cut series before 2^m)
+revised error analysis and code of tanh
+
+------------------------------------------------------------------------
+r3915 | vlefevre | 2005-10-31 12:17:09 +0000 (Mon, 31 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/log10.c
+
+Reformat (GNU coding style).
+
+------------------------------------------------------------------------
+r3914 | vlefevre | 2005-10-31 12:08:13 +0000 (Mon, 31 Oct 2005) | 5 lines
+Changed paths:
+ M /trunk/div_ui.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul_ui.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tinternals.c
+
+Fixed MPFR_INT_CEIL_LOG2 (in mpfr-impl.h) and __gmpfr_int_ceil_log2
+(in int_ceil_log2.c) when the argument is a power of 2, and added a
+test (new test file tests/tinternals.c). This made a bug appear in
+div_ui.c and mul_ui.c; fixed that too.
+
+------------------------------------------------------------------------
+r3913 | vlefevre | 2005-10-31 11:43:58 +0000 (Mon, 31 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+Added a test that fails after fixing MPFR_INT_CEIL_LOG2.
+
+------------------------------------------------------------------------
+r3912 | zimmerma | 2005-10-30 20:07:45 +0000 (Sun, 30 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/exp3.c
+ M /trunk/tests/texp.c
+
+improved exp_3 (binary-splitting algorithm)
+
+------------------------------------------------------------------------
+r3911 | vlefevre | 2005-10-30 14:50:52 +0000 (Sun, 30 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Fixed padding-bit test.
+
+------------------------------------------------------------------------
+r3910 | vlefevre | 2005-10-30 13:20:46 +0000 (Sun, 30 Oct 2005) | 5 lines
+Changed paths:
+ M /trunk/cos.c
+
+3 corrections in cos.c concerning maxi:
+ * corrected a comment;
+ * failed if sizeof(int) <= sizeof(long) / 2;
+ * now take possible padding bits into account.
+
+------------------------------------------------------------------------
+r3909 | zimmerma | 2005-10-29 21:07:36 +0000 (Sat, 29 Oct 2005) | 4 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/exp3.c
+ M /trunk/root.c
+ M /trunk/rootrem.c
+
+patched root.c to use rootrem.c with gmp-4.1.90
+added comment in exp3.c
+added more initial guard bits in agm
+
+------------------------------------------------------------------------
+r3908 | zimmerma | 2005-10-29 13:14:20 +0000 (Sat, 29 Oct 2005) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mulders.c
+ M /trunk/sqr.c
+ M /trunk/tuneup.c
+
+now tune Mulders short square (not yet used)
+improved mpfr_cos
+
+------------------------------------------------------------------------
+r3907 | zimmerma | 2005-10-26 15:45:42 +0000 (Wed, 26 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/root.c
+ M /trunk/rootrem.c
+
+updated code for gmp-dev
+
+------------------------------------------------------------------------
+r3906 | vlefevre | 2005-10-26 11:28:36 +0000 (Wed, 26 Oct 2005) | 2 lines
+Changed paths:
+ D /trunk/.cvsignore
+
+Removed .cvsignore file (useless after the switch to Subversion).
+
+------------------------------------------------------------------------
+r3903 | vlefevre | 2005-10-25 01:33:31 +0000 (Tue, 25 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/update-version
+
+More portable update-version script (use perl instead of sed).
+
+------------------------------------------------------------------------
+r3889 | vlefevre | 2005-10-24 13:43:07 +0000 (Mon, 24 Oct 2005) | 4 lines
+Changed paths:
+ M /trunk/README
+ M /trunk/README.dev
+ D /trunk/fixperm
+
+First revision after the switch to Subversion:
+ * Removed fixperm as it is now useless.
+ * Updated README and README.dev files.
+
+------------------------------------------------------------------------
+r3888 | vlefevre | 2005-10-24 11:29:40 +0000 (Mon, 24 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3887 | zimmerma | 2005-10-19 20:23:44 +0000 (Wed, 19 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/algorithms.tex
+
+documented algorithm used in mpfr_agm and fixed code accordingly
+
+------------------------------------------------------------------------
+r3886 | zimmerma | 2005-10-10 09:43:26 +0000 (Mon, 10 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added efficiency item
+
+------------------------------------------------------------------------
+r3885 | zimmerma | 2005-10-10 09:16:44 +0000 (Mon, 10 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/mpzroot.c
+ M /trunk/root.c
+ M /trunk/rootrem.c
+
+now mpzroot/rootrem compile without gmp internal headers
+
+------------------------------------------------------------------------
+r3884 | vlefevre | 2005-10-07 16:43:40 +0000 (Fri, 07 Oct 2005) | 3 lines
+Changed paths:
+ M /trunk/root.c
+
+Disabled new rootrem/mpz_root as compilation fails (headers can't
+be found).
+
+------------------------------------------------------------------------
+r3883 | vlefevre | 2005-10-07 16:30:45 +0000 (Fri, 07 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Temporary optimization (patch from Patrick Pelissier).
+
+------------------------------------------------------------------------
+r3882 | vlefevre | 2005-10-06 10:03:56 +0000 (Thu, 06 Oct 2005) | 4 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+One of the tests was using the fabs function, but -lm isn't given when
+generating the executable, making the linking fail under HP-UX. Fixed
+by not using this fabs function.
+
+------------------------------------------------------------------------
+r3880 | zimmerma | 2005-10-05 21:57:48 +0000 (Wed, 05 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+small improvement in sign detection
+
+------------------------------------------------------------------------
+r3879 | zimmerma | 2005-10-05 20:36:56 +0000 (Wed, 05 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/mpzroot.c
+ M /trunk/root.c
+ A /trunk/rootrem.c
+
+improved mpfr_root, using the new mpn_rootrem code written with Torbjo"rn
+
+------------------------------------------------------------------------
+r3876 | vlefevre | 2005-09-29 09:52:33 +0000 (Thu, 29 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3875 | vlefevre | 2005-09-29 09:47:08 +0000 (Thu, 29 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/tests/tset_si.c
+
+Fixed bug in mpfr_set_ui macro when parameters are expressions
+with side effects.
+
+------------------------------------------------------------------------
+r3874 | zimmerma | 2005-09-29 06:40:15 +0000 (Thu, 29 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+fixed missing accent
+
+------------------------------------------------------------------------
+r3873 | vlefevre | 2005-09-28 15:30:17 +0000 (Wed, 28 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+Small optimization.
+
+------------------------------------------------------------------------
+r3872 | vlefevre | 2005-09-28 14:28:19 +0000 (Wed, 28 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tlngamma.c
+
+Test the sign of 0.
+
+------------------------------------------------------------------------
+r3871 | zimmerma | 2005-09-28 14:14:42 +0000 (Wed, 28 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+ M /trunk/tests/tlngamma.c
+
+fixed infinite loop for lngamma(2)
+
+------------------------------------------------------------------------
+r3870 | vlefevre | 2005-09-28 00:45:27 +0000 (Wed, 28 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Updated libmpfr_la_LDFLAGS (note: it shouldn't be incremented again
+before the 2.3.0 release).
+
+------------------------------------------------------------------------
+r3869 | zimmerma | 2005-09-26 16:28:47 +0000 (Mon, 26 Sep 2005) | 2 lines
+Changed paths:
+ A /trunk/zeta_ui.c
+
+new function: Zeta with integer argument
+
+------------------------------------------------------------------------
+r3868 | zimmerma | 2005-09-23 21:35:03 +0000 (Fri, 23 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tzeta_ui.c
+
+new function mpfr_zeta_ui for integer argument
+
+------------------------------------------------------------------------
+r3867 | zimmerma | 2005-09-21 13:51:34 +0000 (Wed, 21 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added brief description of algorithm for mpfr_zeta
+
+------------------------------------------------------------------------
+r3863 | vlefevre | 2005-09-18 23:36:44 +0000 (Sun, 18 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Mentioned problems with the Tru64 make and other minor changes.
+
+------------------------------------------------------------------------
+r3861 | vlefevre | 2005-09-17 10:24:43 +0000 (Sat, 17 Sep 2005) | 5 lines
+Changed paths:
+ M /trunk/configure.in
+
+Fixed the GMP linking test: replaced __gmp_version, which corresponds
+to a variable, by __gmpz_init (suggested by the GMP documentation),
+which corresponds to a function, as the auto tools assume the symbol
+corresponds to a function. It was failing with the AIX linker.
+
+------------------------------------------------------------------------
+r3857 | vlefevre | 2005-09-16 14:22:40 +0000 (Fri, 16 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/const_euler.c
+
+Untabify.
+
+------------------------------------------------------------------------
+r3856 | vlefevre | 2005-09-16 13:22:53 +0000 (Fri, 16 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3854 | vlefevre | 2005-09-16 10:58:41 +0000 (Fri, 16 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Untabify.
+
+------------------------------------------------------------------------
+r3852 | zimmerma | 2005-09-16 09:41:47 +0000 (Fri, 16 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added missing documentation for mpfr_get_f and mpfr_pow_z
+
+------------------------------------------------------------------------
+r3851 | vlefevre | 2005-09-16 08:02:15 +0000 (Fri, 16 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fixed typos found by Tomonori Kouya.
+
+------------------------------------------------------------------------
+r3850 | zimmerma | 2005-09-16 07:38:22 +0000 (Fri, 16 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/coth.c
+ M /trunk/tests/tcoth.c
+
+fixed stupid bug (coth was computing 1/tan instead of 1/tanh)
+
+------------------------------------------------------------------------
+r3849 | zimmerma | 2005-09-15 21:55:08 +0000 (Thu, 15 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/const_euler.c
+
+fixed overflow problem for large precision
+
+------------------------------------------------------------------------
+r3848 | zimmerma | 2005-09-15 21:11:25 +0000 (Thu, 15 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+added log(precz) in initial precision
+
+------------------------------------------------------------------------
+r3844 | zimmerma | 2005-09-13 12:57:38 +0000 (Tue, 13 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/tests/texp.c
+
+fixed bug in exp(-eps) for rounding toward zero (test was also wrong...)
+
+------------------------------------------------------------------------
+r3843 | vlefevre | 2005-09-13 02:05:56 +0000 (Tue, 13 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Updated "To make a release".
+
+------------------------------------------------------------------------
+r3839 | vlefevre | 2005-09-13 01:32:41 +0000 (Tue, 13 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Minor update.
+
+------------------------------------------------------------------------
+r3838 | vlefevre | 2005-09-13 01:28:09 +0000 (Tue, 13 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/constant.c
+
+Added missing MPFR_THREAD_ATTR.
+
+------------------------------------------------------------------------
+r3835 | vlefevre | 2005-09-11 22:50:06 +0000 (Sun, 11 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tuneup.c
+
+Avoid a conflict with GMP.
+
+------------------------------------------------------------------------
+r3834 | vlefevre | 2005-09-11 22:37:58 +0000 (Sun, 11 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/mparam_h.in
+ M /trunk/mul.c
+ M /trunk/tuneup.c
+
+Reverted to previous mparam_h.in and mul.c, and applied Patrick's
+patch instead.
+
+------------------------------------------------------------------------
+r3832 | vlefevre | 2005-09-11 22:15:29 +0000 (Sun, 11 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3830 | vlefevre | 2005-09-11 21:59:31 +0000 (Sun, 11 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tstckintc.c
+
+Added #include <string.h> for memmove (see ISO C99 standard).
+
+------------------------------------------------------------------------
+r3829 | vlefevre | 2005-09-11 21:56:32 +0000 (Sun, 11 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Minor change.
+
+------------------------------------------------------------------------
+r3828 | vlefevre | 2005-09-11 21:55:20 +0000 (Sun, 11 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/trint.c
+
+Fixed uninitialized variable (with gcc -std=c99).
+
+------------------------------------------------------------------------
+r3827 | vlefevre | 2005-09-11 21:43:14 +0000 (Sun, 11 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Fixed a #ifdef (when --enable-assert isn't used).
+
+------------------------------------------------------------------------
+r3824 | vlefevre | 2005-09-11 18:21:02 +0000 (Sun, 11 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3823 | vlefevre | 2005-09-11 17:56:43 +0000 (Sun, 11 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/int_ceil_log2.c
+ M /trunk/mpfr-impl.h
+
+Changed the MPFR_ASSERTD into a MPFR_ASSERTN for MPFR_INT_CEIL_LOG2
+since the assertion cannot be guaranteed for every C implementation.
+
+------------------------------------------------------------------------
+r3822 | pelissip | 2005-09-10 15:20:48 +0000 (Sat, 10 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Fix spelling mistake.
+
+------------------------------------------------------------------------
+r3821 | pelissip | 2005-09-10 15:17:54 +0000 (Sat, 10 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Add new note about MPFR_TMP_DECL
+
+------------------------------------------------------------------------
+r3819 | zimmerma | 2005-09-09 14:45:54 +0000 (Fri, 09 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+reduced default of MPFR_MUL_THRESHOLD by 1, since now MPFR_MUL_THRESHOLD+1
+is considered in mul.c
+
+------------------------------------------------------------------------
+r3818 | vlefevre | 2005-09-09 14:37:51 +0000 (Fri, 09 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+Fixed another LaTeX error.
+
+------------------------------------------------------------------------
+r3817 | vlefevre | 2005-09-09 14:26:08 +0000 (Fri, 09 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3816 | vlefevre | 2005-09-09 12:09:47 +0000 (Fri, 09 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Updated "To make a release".
+
+------------------------------------------------------------------------
+r3815 | vlefevre | 2005-09-09 10:21:11 +0000 (Fri, 09 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+Use (mpz_t *) 0 instead of NULL (this is not less clear and this
+works with the native SunOS 4 C compiler).
+
+------------------------------------------------------------------------
+r3814 | zimmerma | 2005-09-09 09:33:04 +0000 (Fri, 09 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+
+avoid . in mpf_set_str (locale-sensitive)
+
+------------------------------------------------------------------------
+r3813 | zimmerma | 2005-09-09 09:26:22 +0000 (Fri, 09 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/lngamma.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tlngamma.c
+
+cleanup of gamma and lngamma
+
+------------------------------------------------------------------------
+r3812 | zimmerma | 2005-09-08 09:37:46 +0000 (Thu, 08 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+
+MUL_THRESHOLD -> MUL_THRESHOLD+1 (to allow MUL_THRESHOLD=0, needed for
+tuneup.c)
+
+------------------------------------------------------------------------
+r3811 | zimmerma | 2005-09-08 09:21:02 +0000 (Thu, 08 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+fixed LaTeX error
+
+------------------------------------------------------------------------
+r3809 | vlefevre | 2005-09-08 09:12:20 +0000 (Thu, 08 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Fix.
+
+------------------------------------------------------------------------
+r3808 | vlefevre | 2005-09-08 09:08:46 +0000 (Thu, 08 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3804 | vlefevre | 2005-09-08 09:02:58 +0000 (Thu, 08 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ A /trunk/fixperm
+
+Added fixperm script to fix the file permissions broken by CVS.
+
+------------------------------------------------------------------------
+r3803 | vlefevre | 2005-09-08 09:01:50 +0000 (Thu, 08 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Update.
+
+------------------------------------------------------------------------
+r3798 | zimmerma | 2005-09-08 06:48:10 +0000 (Thu, 08 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one item
+
+------------------------------------------------------------------------
+r3797 | vlefevre | 2005-09-08 06:45:52 +0000 (Thu, 08 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3795 | vlefevre | 2005-09-08 02:51:45 +0000 (Thu, 08 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+Fix: readded dependencies.
+
+------------------------------------------------------------------------
+r3793 | vlefevre | 2005-09-06 14:37:32 +0000 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tversion.c
+
+More detailed error message.
+
+------------------------------------------------------------------------
+r3791 | vlefevre | 2005-09-06 13:54:57 +0000 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+Change for ansi2knr.
+
+------------------------------------------------------------------------
+r3790 | vlefevre | 2005-09-06 13:42:02 +0000 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+Code clean-up (again).
+
+------------------------------------------------------------------------
+r3789 | vlefevre | 2005-09-06 13:31:12 +0000 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+Use GMP's allocate functions instead of C's. Code clean-up.
+
+------------------------------------------------------------------------
+r3788 | vlefevre | 2005-09-06 13:02:37 +0000 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/lngamma.c
+
+Reformat.
+
+------------------------------------------------------------------------
+r3787 | zimmerma | 2005-09-06 12:42:39 +0000 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+missing set_emin
+
+------------------------------------------------------------------------
+r3786 | zimmerma | 2005-09-06 12:25:03 +0000 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+added missing call to MPFR_TEST_USE_RANDS() [3 blocks non-freed]
+
+------------------------------------------------------------------------
+r3784 | vlefevre | 2005-09-06 12:00:54 +0000 (Tue, 06 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+Fixed a bug (detected after mpfr_set_str_binary has been fixed)
+in tests/tsub.c introduced in 1.6 (2001-10-19).
+
+------------------------------------------------------------------------
+r3783 | vlefevre | 2005-09-06 11:50:09 +0000 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+mpfr_set_str_binary was buggy and inefficient. Let's use mpfr_strtofr.
+
+------------------------------------------------------------------------
+r3781 | vlefevre | 2005-09-06 11:30:40 +0000 (Tue, 06 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Replaced unsigned long bit-fields (GCC extension) by insigned int
+bit-fields.
+
+------------------------------------------------------------------------
+r3779 | vlefevre | 2005-09-05 13:28:20 +0000 (Mon, 05 Sep 2005) | 4 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+MPN_COPY now calls memcpy only if dst != src (otherwise this is an
+undefined behavior), and if WANT_ASSERT is defined, it checks that
+there is no overlap.
+
+------------------------------------------------------------------------
+r3776 | vlefevre | 2005-09-02 14:08:09 +0000 (Fri, 02 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Avoid MIPSpro / IRIX64 (incorrect) optimizations for DOUBLE_ISNAN.
+
+------------------------------------------------------------------------
+r3775 | vlefevre | 2005-09-02 13:25:32 +0000 (Fri, 02 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-impl.h
+
+More portable DOUBLE_ISNAN (useful for MIPSpro under IRIX64).
+
+------------------------------------------------------------------------
+r3774 | zimmerma | 2005-09-02 12:55:37 +0000 (Fri, 02 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+improved trade-off between fac_ui and gamma when argument is integer
+
+------------------------------------------------------------------------
+r3773 | vlefevre | 2005-09-02 12:33:24 +0000 (Fri, 02 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Reformat.
+
+------------------------------------------------------------------------
+r3772 | zimmerma | 2005-09-02 09:52:07 +0000 (Fri, 02 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+fixed remaining problem in gamma
+removed LogGamma from TODO
+
+------------------------------------------------------------------------
+r3771 | vlefevre | 2005-09-02 08:17:37 +0000 (Fri, 02 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/add1sp.c
+ M /trunk/sub1sp.c
+
+Do not put expressions with side effects in MPFR_ASSERTN.
+
+------------------------------------------------------------------------
+r3770 | zimmerma | 2005-09-01 21:44:42 +0000 (Thu, 01 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+now uses lngamma code for x < 1 too
+added new tests from Kenneth Wilder
+
+------------------------------------------------------------------------
+r3769 | zimmerma | 2005-09-01 11:54:57 +0000 (Thu, 01 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+added another test
+
+------------------------------------------------------------------------
+r3768 | zimmerma | 2005-09-01 08:59:19 +0000 (Thu, 01 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+removed useless prototype
+
+------------------------------------------------------------------------
+r3764 | vlefevre | 2005-08-31 23:57:06 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/sum.c
+
+Fixed memory leak (missing MPFR_TMP_FREE in a particular case).
+
+------------------------------------------------------------------------
+r3763 | vlefevre | 2005-08-31 23:52:53 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/sum.c
+
+Fixed the code formatting.
+
+------------------------------------------------------------------------
+r3762 | vlefevre | 2005-08-31 23:38:13 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Updated Point 6 of "To make a release".
+
+------------------------------------------------------------------------
+r3761 | vlefevre | 2005-08-31 23:27:29 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Fixed memory leak (missing MPFR_TMP_FREE in a particular case).
+
+------------------------------------------------------------------------
+r3759 | zimmerma | 2005-08-31 20:32:03 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added lngamma
+
+------------------------------------------------------------------------
+r3758 | zimmerma | 2005-08-31 20:29:36 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added new test (emax)
+
+------------------------------------------------------------------------
+r3757 | zimmerma | 2005-08-31 20:28:25 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+now random tests also use x >= 1
+
+------------------------------------------------------------------------
+r3756 | zimmerma | 2005-08-31 20:26:33 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+added SAVE_EXPO stuff
+
+------------------------------------------------------------------------
+r3754 | zimmerma | 2005-08-31 20:25:36 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ A /trunk/lngamma.c
+ M /trunk/mpfr.h
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tlngamma.c
+
+new function lngamma
+
+------------------------------------------------------------------------
+r3753 | zimmerma | 2005-08-31 20:24:16 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+now uses lngamma code for x > 1
+
+------------------------------------------------------------------------
+r3752 | zimmerma | 2005-08-31 20:23:06 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added lngamma
+
+------------------------------------------------------------------------
+r3750 | vlefevre | 2005-08-31 12:21:14 +0000 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/VERSION
+ M /trunk/configure.in
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/version.c
+
+Updated version to 2.3.0.
+
+------------------------------------------------------------------------
+r3749 | vlefevre | 2005-08-31 12:18:31 +0000 (Wed, 31 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+
+Fix for the following problem: #error is not sufficient with cc
+on IRIX64, and autoconf 2.59 doesn't cope with that.
+
+------------------------------------------------------------------------
+r3745 | vlefevre | 2005-08-30 13:23:51 +0000 (Tue, 30 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk
+ A /trunk/.cvsignore
+ M /trunk/tests
+ A /trunk/tests/.cvsignore
+
+Added .cvsignore files.
+
+------------------------------------------------------------------------
+r3744 | vlefevre | 2005-08-30 12:08:42 +0000 (Tue, 30 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Unobfuscated 2 assertions.
+
+------------------------------------------------------------------------
+r3743 | vlefevre | 2005-08-30 11:59:12 +0000 (Tue, 30 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Fixed indentation and some comments.
+
+------------------------------------------------------------------------
+r3742 | vlefevre | 2005-08-30 11:49:24 +0000 (Tue, 30 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Recommitted the patch (without discarding previous modifications).
+
+------------------------------------------------------------------------
+r3741 | vlefevre | 2005-08-30 11:46:58 +0000 (Tue, 30 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+
+Reverted to the previous version, as the patch discarded previous
+modifications.
+
+------------------------------------------------------------------------
+r3740 | zimmerma | 2005-08-30 10:27:11 +0000 (Tue, 30 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+added two new tests
+
+------------------------------------------------------------------------
+r3739 | zimmerma | 2005-08-30 10:09:59 +0000 (Tue, 30 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+
+patch from Patrick to solve efficiency problem when one operand is sparse
+(e.g. from ui_pow_ui)
+
+------------------------------------------------------------------------
+r3738 | zimmerma | 2005-08-29 14:07:51 +0000 (Mon, 29 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/gamma.c
+ M /trunk/mpfr-impl.h
+ M /trunk/pow.c
+ M /trunk/tests/tgamma.c
+
+check for overflow/underflow in pow and gamma
+
+------------------------------------------------------------------------
+r3737 | vlefevre | 2005-08-24 15:37:36 +0000 (Wed, 24 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/add1sp.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/print_raw.c
+ M /trunk/sub1sp.c
+
+When WANT_ASSERT >= 2: the corresponding messages are now output
+to stderr instead of stdout.
+
+------------------------------------------------------------------------
+r3736 | vlefevre | 2005-08-24 14:23:41 +0000 (Wed, 24 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3735 | vlefevre | 2005-08-24 14:16:04 +0000 (Wed, 24 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/set_uj.c
+
+Improved C compliance when mp_limb_t and uintmax_t have the same size
+(concerning >> BITS_PER_MP_LIMB); some other small improvements.
+
+------------------------------------------------------------------------
+r3734 | vlefevre | 2005-08-24 13:27:12 +0000 (Wed, 24 Aug 2005) | 5 lines
+Changed paths:
+ M /trunk/round_p.c
+ M /trunk/tests/tcan_round.c
+
+No longer assume that a mp_limb_t fits in an unsigned long (this
+is not true under IRIX, where a mp_limb_t has 64 bits and a long
+has 32 bits by default). In round_p.c, error messages are output
+to stderr instead of stdout.
+
+------------------------------------------------------------------------
+r3733 | vlefevre | 2005-08-23 17:21:45 +0000 (Tue, 23 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3732 | vlefevre | 2005-08-23 15:57:21 +0000 (Tue, 23 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+This was wrong. Let's do it even more like the 2.1 branch.
+
+------------------------------------------------------------------------
+r3731 | vlefevre | 2005-08-23 15:41:39 +0000 (Tue, 23 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3730 | vlefevre | 2005-08-23 15:37:53 +0000 (Tue, 23 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+Patch 1.25 didn't work under OSF1 with cc. Let's do it like
+the 2.1 branch (it now does work under OSF1 with cc).
+
+------------------------------------------------------------------------
+r3729 | vlefevre | 2005-08-21 22:57:15 +0000 (Sun, 21 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.texi
+ M /trunk/out_str.c
+ M /trunk/strtofr.c
+
+Better locale support (for the decimal point in string conversions
+and input/output).
+
+------------------------------------------------------------------------
+r3728 | vlefevre | 2005-08-18 17:17:02 +0000 (Thu, 18 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3727 | vlefevre | 2005-08-18 17:08:30 +0000 (Thu, 18 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Misc changes (spelling, typography...).
+
+------------------------------------------------------------------------
+r3726 | vlefevre | 2005-08-18 17:03:17 +0000 (Thu, 18 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1sp.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/coth.c
+ M /trunk/div-short.c
+ M /trunk/div.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/expm1.c
+ M /trunk/factorial.c
+ M /trunk/fits_intmax.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uintmax.c
+ M /trunk/fma.c
+ M /trunk/frac.c
+ M /trunk/gamma.c
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_str.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/gmp_op.c
+ M /trunk/inp_str.c
+ M /trunk/isinteger.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/log_b2.h
+ M /trunk/minmax.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/out_str.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/print_raw.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/root.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_q.c
+ M /trunk/set_si.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_z.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sqrt.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/swap.c
+ M /trunk/tanh.c
+ M /trunk/tests/memory.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/urandomb.c
+
+Removed trailing spaces (better for future patches, as such spaces
+are sometimes stripped).
+
+------------------------------------------------------------------------
+r3725 | vlefevre | 2005-08-18 16:35:19 +0000 (Thu, 18 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1sp.c
+ M /trunk/add_one_ulp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/dim.c
+ M /trunk/div-short.c
+ M /trunk/div.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/factorial.c
+ M /trunk/fits_intmax.c
+ M /trunk/fma.c
+ M /trunk/gamma.c
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_ld.c
+ M /trunk/get_str.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/init2.c
+ M /trunk/inp_str.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/minmax.c
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/print_raw.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_f.c
+ M /trunk/set_q.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/RRTest.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/zeta.c
+
+Converted tabs to spaces with expand.
+
+------------------------------------------------------------------------
+r3724 | vlefevre | 2005-08-18 15:27:33 +0000 (Thu, 18 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/extract.c
+ M /trunk/fits_u.h
+ M /trunk/free_cache.c
+ M /trunk/generic.c
+ M /trunk/get_si.c
+ M /trunk/init2.c
+ M /trunk/mpfr-test.h
+ M /trunk/next.c
+ M /trunk/print_raw.c
+ M /trunk/set_f.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/tversion.c
+
+Updated copyright line.
+
+------------------------------------------------------------------------
+r3723 | vlefevre | 2005-08-18 14:51:33 +0000 (Thu, 18 Aug 2005) | 4 lines
+Changed paths:
+ M /trunk/set_ld.c
+ M /trunk/tests/tset_ld.c
+
+Support C implementations giving an incorrect value for the precision
+of long double or where long doubles are implemented with FP expansions
+(like under Mac OS X), as in the 2.1 branch.
+
+------------------------------------------------------------------------
+r3722 | vlefevre | 2005-08-18 13:46:30 +0000 (Thu, 18 Aug 2005) | 5 lines
+Changed paths:
+ M /trunk/get_ld.c
+ M /trunk/mpfr-impl.h
+
+Updated mpfr_get_ld: removed useless and non-portable hacks, fixed
+bugs, and slightly changed the behavior for the x87 extended format
+(we shouldn't return long double's with more precision than really
+supported, e.g. on FreeBSD and NetBSD).
+
+------------------------------------------------------------------------
+r3721 | vlefevre | 2005-08-18 13:08:07 +0000 (Thu, 18 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/get_ld.c
+
+Added an assertion.
+
+------------------------------------------------------------------------
+r3720 | vlefevre | 2005-08-17 16:45:18 +0000 (Wed, 17 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+Reformatted (GNU style).
+
+------------------------------------------------------------------------
+r3719 | pelissip | 2005-08-17 16:26:10 +0000 (Wed, 17 Aug 2005) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+
+Improve the warning message by adding the lines:
+"we cannot run a program linked with GMP (if you cannot
+see the version numbers above)."
+
+------------------------------------------------------------------------
+r3718 | zimmerma | 2005-08-16 14:26:05 +0000 (Tue, 16 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added pointer for gamma
+
+------------------------------------------------------------------------
+r3717 | zimmerma | 2005-08-16 14:24:15 +0000 (Tue, 16 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+fixed comments (code did not change)
+
+------------------------------------------------------------------------
+r3716 | zimmerma | 2005-08-16 14:01:22 +0000 (Tue, 16 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+ M /trunk/gamma.c
+
+added formula for gamma function
+
+------------------------------------------------------------------------
+r3715 | zimmerma | 2005-08-16 13:20:14 +0000 (Tue, 16 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+fixed last test (expected result was wrong)
+
+------------------------------------------------------------------------
+r3714 | zimmerma | 2005-08-16 13:19:09 +0000 (Tue, 16 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+fixed bug for tiny input
+
+------------------------------------------------------------------------
+r3713 | zimmerma | 2005-08-16 09:36:05 +0000 (Tue, 16 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+added test case
+
+------------------------------------------------------------------------
+r3712 | pelissip | 2005-08-12 15:11:37 +0000 (Fri, 12 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Reintroduce the computing of the dependencies.
+
+------------------------------------------------------------------------
+r3711 | vlefevre | 2005-08-11 14:56:47 +0000 (Thu, 11 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tset_d.c
+
+Added MPFR_DOUBLE_SPEC (not used yet, except for warning messages).
+
+------------------------------------------------------------------------
+r3710 | vlefevre | 2005-08-10 20:41:16 +0000 (Wed, 10 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Completed the documentation of mpfr_strtofr (concerning the exponent).
+
+------------------------------------------------------------------------
+r3709 | vlefevre | 2005-08-10 20:32:41 +0000 (Wed, 10 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Removed double spaces in mpfr_strtofr description (this matters
+for the info format).
+
+------------------------------------------------------------------------
+r3708 | vlefevre | 2005-08-10 01:02:57 +0000 (Wed, 10 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+Added a temporary test for non-IEEE-754 double's.
+
+------------------------------------------------------------------------
+r3707 | pelissip | 2005-08-09 08:17:14 +0000 (Tue, 09 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/tests/tstckintc.c
+
+Fix bug for pre-ansi compiler.
+
+------------------------------------------------------------------------
+r3706 | pelissip | 2005-08-09 08:16:46 +0000 (Tue, 09 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Remove redundant entries.
+
+------------------------------------------------------------------------
+r3705 | zimmerma | 2005-08-08 13:01:31 +0000 (Mon, 08 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/TODO
+ M /trunk/sin.c
+ M /trunk/tests/tsin.c
+
+fixed bug in mpfr_sin (possible wrong inexact flag for rounding to nearest)
+added items in NEWS and TODO
+
+------------------------------------------------------------------------
+r3704 | pelissip | 2005-08-05 23:09:58 +0000 (Fri, 05 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update information
+
+------------------------------------------------------------------------
+r3703 | pelissip | 2005-08-05 23:08:29 +0000 (Fri, 05 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/stack_interface.c
+ M /trunk/tests/tstckintc.c
+
+Rename mpfr_stack to mpfr_custom_
+
+------------------------------------------------------------------------
+r3695 | vlefevre | 2005-08-03 10:35:59 +0000 (Wed, 03 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/FAQ.html
+ M /trunk/README
+
+Added/updated copyright information.
+
+------------------------------------------------------------------------
+r3694 | vlefevre | 2005-08-03 10:13:41 +0000 (Wed, 03 Aug 2005) | 2 lines
+Changed paths:
+ M /branches/mpfr-2-1-branch/NEWS
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3693 | pelissip | 2005-08-02 08:28:22 +0000 (Tue, 02 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Remove "Stack Interface" from TODO.
+
+------------------------------------------------------------------------
+r3692 | pelissip | 2005-08-01 15:23:51 +0000 (Mon, 01 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/subnormal.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tsubnormal.c
+
+Add test file for mpfr_subnormalize
+
+------------------------------------------------------------------------
+r3691 | pelissip | 2005-08-01 15:23:07 +0000 (Mon, 01 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add documentation for MPFR stack interface
+
+------------------------------------------------------------------------
+r3690 | pelissip | 2005-08-01 14:04:35 +0000 (Mon, 01 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tstckintc.c
+
+Add a new test to avoid potential problems if mp_limb_t != long.
+
+------------------------------------------------------------------------
+r3689 | vlefevre | 2005-08-01 10:04:33 +0000 (Mon, 01 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3685 | pelissip | 2005-07-26 16:08:02 +0000 (Tue, 26 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/stack_interface.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tstckintc.c
+
+Add first version of MPFR stack interface.
+Need to check if everything is ok, specially the test.
+
+------------------------------------------------------------------------
+r3684 | pelissip | 2005-07-26 14:07:18 +0000 (Tue, 26 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Fix and clean up logging for GCC 4.0.x
+
+------------------------------------------------------------------------
+r3683 | pelissip | 2005-07-26 13:02:30 +0000 (Tue, 26 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Clean up code.
+
+------------------------------------------------------------------------
+r3682 | pelissip | 2005-07-26 12:26:08 +0000 (Tue, 26 Jul 2005) | 4 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/logging.c
+ M /trunk/mpfr-impl.h
+
+Improve logging:
+ + The file is not created if there is nothing to log.
+ + Add new ENVIRONMENT variables: MPFR_LOG_ALL and MPFR_LOG_STAT.
+
+------------------------------------------------------------------------
+r3681 | pelissip | 2005-07-26 12:06:11 +0000 (Tue, 26 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Add experimental code (Disabled).
+
+------------------------------------------------------------------------
+r3680 | pelissip | 2005-07-26 12:05:45 +0000 (Tue, 26 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+Fix comment
+
+------------------------------------------------------------------------
+r3679 | pelissip | 2005-07-26 12:05:03 +0000 (Tue, 26 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+
+Add a new regression test (to fix).
+
+------------------------------------------------------------------------
+r3678 | pelissip | 2005-07-22 14:01:30 +0000 (Fri, 22 Jul 2005) | 4 lines
+Changed paths:
+ M /trunk/erfc.c
+
+Fix bug for high values of input (assertion failed)
+because erf(x) ~ 1, so 1-erf(x) ~ 0, and we can't
+get the EXP of tmp.
+
+------------------------------------------------------------------------
+r3677 | pelissip | 2005-07-18 12:55:30 +0000 (Mon, 18 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/update-version
+
+Fix bug (AC_INIT version wasn't updated).
+Display a note about libtool version before quitting.
+
+------------------------------------------------------------------------
+r3676 | pelissip | 2005-07-18 12:54:45 +0000 (Mon, 18 Jul 2005) | 4 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Clean up.
+Add comment.
+Add a new test: check if the charset has consecutive values.
+
+------------------------------------------------------------------------
+r3675 | vlefevre | 2005-07-12 21:27:55 +0000 (Tue, 12 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Updated documentation of mpfr_strtofr.
+
+------------------------------------------------------------------------
+r3674 | pelissip | 2005-07-12 09:48:36 +0000 (Tue, 12 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/exp3.c
+
+Fix an overflow bug (use of int instead of unsigned long).
+Optimize code (5% faster).
+
+------------------------------------------------------------------------
+r3671 | vlefevre | 2005-07-11 16:13:27 +0000 (Mon, 11 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-impl.h
+ D /trunk/strcasecmp.c
+ D /trunk/strncasecmp.c
+ M /trunk/strtofr.c
+
+Fixed locale bug. Function strncasecmp is no longer used.
+
+------------------------------------------------------------------------
+r3670 | vlefevre | 2005-07-09 17:52:53 +0000 (Sat, 09 Jul 2005) | 5 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/acinclude.m4
+ M /trunk/tests/tests.c
+
+In the tests, set the locale to the current one. This allows to test
+MPFR under various locales, showing a bug in the parse_string function
+due to the use of the strncasecmp function ('i' and 'I' don't match
+with LC_ALL="tr_TR.ISO8859-9").
+
+------------------------------------------------------------------------
+r3669 | pelissip | 2005-07-07 07:38:02 +0000 (Thu, 07 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Improve displayed warning if GMP versions differ.
+
+------------------------------------------------------------------------
+r3668 | pelissip | 2005-07-06 08:45:47 +0000 (Wed, 06 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Add a solution for a problem.
+
+------------------------------------------------------------------------
+r3667 | vlefevre | 2005-07-05 13:47:37 +0000 (Tue, 05 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+Added in-place tests for atan(+/-0).
+
+------------------------------------------------------------------------
+r3665 | pelissip | 2005-07-05 08:04:21 +0000 (Tue, 05 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+
+Fix bug of signed 0.
+Optimize code. (20% for 53 bits).
+
+------------------------------------------------------------------------
+r3664 | pelissip | 2005-07-05 08:03:38 +0000 (Tue, 05 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+Improve test for signed 0.
+
+------------------------------------------------------------------------
+r3663 | pelissip | 2005-06-28 16:46:42 +0000 (Tue, 28 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+
+Simplify a condition which was always true.
+(p is always negative).
+
+------------------------------------------------------------------------
+r3662 | pelissip | 2005-06-28 16:13:03 +0000 (Tue, 28 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Add assertion.
+
+------------------------------------------------------------------------
+r3661 | pelissip | 2005-06-28 16:09:00 +0000 (Tue, 28 Jun 2005) | 4 lines
+Changed paths:
+ M /trunk/atan.c
+
+Simplify code for final step (when i== n0):
+since we do n0-i=0 steps, atan(Ak/2^k) ~= Ak/2^k.
+So we could speed up the final computation (9% faster).
+
+------------------------------------------------------------------------
+r3660 | pelissip | 2005-06-28 15:52:32 +0000 (Tue, 28 Jun 2005) | 4 lines
+Changed paths:
+ M /trunk/atan.c
+
+Optimize: when computing arctan(p/2^r) simplify
+p/2^r if p is even.
+Clean up and remove tabi table. It was useless.
+
+------------------------------------------------------------------------
+r3659 | pelissip | 2005-06-22 08:58:50 +0000 (Wed, 22 Jun 2005) | 6 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Clean up configure and acinclude:
+ + Remove useless test in MPFR_CONFIGS (Check for valid NAN).
+ Its result is not use by MPFR.
+ + Remove useless macros (AC_CHECK_OS, AC_CHECK_MACH and AC_MY_HEADERS).
+ + Move detection of math/rint,round,floor,ceil to MPFR_CONFIGS.
+
+------------------------------------------------------------------------
+r3658 | vlefevre | 2005-06-20 09:30:34 +0000 (Mon, 20 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/sum.c
+
+GNU coding style.
+
+------------------------------------------------------------------------
+r3657 | zimmerma | 2005-06-16 13:48:23 +0000 (Thu, 16 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+improved m=0 case when b is a power of 2
+
+------------------------------------------------------------------------
+r3656 | pelissip | 2005-06-15 16:12:27 +0000 (Wed, 15 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+
+Replace mpfr_div_2ui call by SET_EXP/GET_EXP
+since it can't overflow.
+
+------------------------------------------------------------------------
+r3655 | pelissip | 2005-06-15 15:47:16 +0000 (Wed, 15 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Speed up a few (from 10822 to 10600).
+
+------------------------------------------------------------------------
+r3654 | pelissip | 2005-06-15 13:56:23 +0000 (Wed, 15 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Update
+
+------------------------------------------------------------------------
+r3653 | pelissip | 2005-06-14 11:42:25 +0000 (Tue, 14 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/powerof2.c
+
+Replace check for a power of 2 for the high limb by a check
+for "high bit limb" for the high limb.
+
+------------------------------------------------------------------------
+r3652 | pelissip | 2005-06-14 11:30:10 +0000 (Tue, 14 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+Fix bug in mul_ui (always alloc buffer instead of trying to reuse it).
+
+------------------------------------------------------------------------
+r3651 | pelissip | 2005-06-14 11:27:56 +0000 (Tue, 14 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+Add new test (failed).
+
+------------------------------------------------------------------------
+r3650 | pelissip | 2005-06-14 11:17:55 +0000 (Tue, 14 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/div_ui.c
+ M /trunk/mul_ui.c
+
+Add Fast case for u==1
+Add Fast case for u a power of 2 (Call mul/div_2si).
+
+------------------------------------------------------------------------
+r3649 | pelissip | 2005-06-14 09:04:44 +0000 (Tue, 14 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Fix bug (use of GCC specific attribute).
+
+------------------------------------------------------------------------
+r3648 | pelissip | 2005-06-13 12:19:30 +0000 (Mon, 13 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/root.c
+ M /trunk/tests/troot.c
+
+Rechnage the meaning of root for k=0.
+
+------------------------------------------------------------------------
+r3647 | pelissip | 2005-06-13 12:03:30 +0000 (Mon, 13 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/root.c
+ M /trunk/tests/troot.c
+
+Fix bug with x<0 and k even
+
+------------------------------------------------------------------------
+r3646 | pelissip | 2005-06-13 11:45:50 +0000 (Mon, 13 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/root.c
+ M /trunk/tests/troot.c
+
+Add special case for k==0
+Add test for special case k==0
+
+------------------------------------------------------------------------
+r3645 | zimmerma | 2005-06-13 11:33:57 +0000 (Mon, 13 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+
+added assertion
+
+------------------------------------------------------------------------
+r3644 | pelissip | 2005-06-13 11:23:37 +0000 (Mon, 13 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/cache.c
+
+Improve efficiency of initial call to mpfr_cache.
+
+------------------------------------------------------------------------
+r3643 | pelissip | 2005-06-13 08:51:44 +0000 (Mon, 13 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsum.c
+
+Add new check (+INF -INF --> NAN).
+
+------------------------------------------------------------------------
+r3642 | pelissip | 2005-06-10 15:11:02 +0000 (Fri, 10 Jun 2005) | 6 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/sum.c
+ M /trunk/tests/tsum.c
+
+Fix bug of NAN and INF.
+Fix bug in documentation (mpfr_sum wasn't exactly what is decribed).
+Improve test.
+Change internal names.
+Clean up.
+
+------------------------------------------------------------------------
+r3641 | pelissip | 2005-06-10 15:05:54 +0000 (Fri, 10 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/eint.c
+
+Fix bug: check if mpfr_log returns 0.
+
+------------------------------------------------------------------------
+r3640 | pelissip | 2005-06-08 12:35:31 +0000 (Wed, 08 Jun 2005) | 5 lines
+Changed paths:
+ M /trunk/eint.c
+
+Replace MPFR_EXP to MPFR_GET_EXP
+Use GROUP function
+Use MPFR_MPZ_SIZEINBASE2
+Factorize the mpfr_mul_2exp chain.
+
+------------------------------------------------------------------------
+r3639 | pelissip | 2005-06-08 12:34:47 +0000 (Wed, 08 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+Replace int to mp_prec_t for precision...
+
+------------------------------------------------------------------------
+r3638 | pelissip | 2005-06-08 12:34:21 +0000 (Wed, 08 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/const_euler.c
+ M /trunk/mulders.c
+ M /trunk/zeta.c
+
+Fix warning due to comparison of unsigned and signed integers.
+
+------------------------------------------------------------------------
+r3637 | pelissip | 2005-06-08 11:45:06 +0000 (Wed, 08 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/extract.c
+ M /trunk/strtofr.c
+
+Fix warnings due to comparaison between signed and unsigned.
+Reinclude string.h for strtofr.
+
+------------------------------------------------------------------------
+r3635 | vlefevre | 2005-06-08 10:18:24 +0000 (Wed, 08 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+
+Fixed bug introduced with the new internal format on 2003-10-27.
+
+------------------------------------------------------------------------
+r3634 | vlefevre | 2005-06-08 10:02:28 +0000 (Wed, 08 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+
+Updated comments.
+
+------------------------------------------------------------------------
+r3633 | pelissip | 2005-06-08 10:00:21 +0000 (Wed, 08 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Fix introduced bug due to missing NULL.
+
+------------------------------------------------------------------------
+r3632 | pelissip | 2005-06-08 09:58:57 +0000 (Wed, 08 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/clear.c
+
+Fix introduced bug (NULL not defined).
+
+------------------------------------------------------------------------
+r3631 | pelissip | 2005-06-08 09:53:48 +0000 (Wed, 08 Jun 2005) | 4 lines
+Changed paths:
+ M /trunk/add1sp.c
+ M /trunk/atan.c
+ M /trunk/clear.c
+ M /trunk/div.c
+ M /trunk/gamma.c
+ M /trunk/get_f.c
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/round_p.c
+ M /trunk/set_z.c
+ M /trunk/sin.c
+ M /trunk/strtofr.c
+ M /trunk/sub1sp.c
+ M /trunk/subnormal.c
+ M /trunk/zeta.c
+
+Clean up use of stdio.h:
+ it is now included by mpfr-impl iff DEBUG is defined or WANT_ASSERT is
+defined.
+
+------------------------------------------------------------------------
+r3630 | pelissip | 2005-06-08 09:53:05 +0000 (Wed, 08 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsum.c
+
+Fix warnings.
+
+------------------------------------------------------------------------
+r3629 | pelissip | 2005-06-08 09:13:41 +0000 (Wed, 08 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+Clean up code.
+
+------------------------------------------------------------------------
+r3628 | pelissip | 2005-06-08 09:08:27 +0000 (Wed, 08 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/add1sp.c
+
+Improve checking if WANT_ASSERT >= 2
+
+------------------------------------------------------------------------
+r3627 | pelissip | 2005-06-07 16:06:38 +0000 (Tue, 07 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+Fix wrong assertion.
+
+------------------------------------------------------------------------
+r3626 | pelissip | 2005-06-07 16:03:24 +0000 (Tue, 07 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsum.c
+
+Improve test by adding special cases.
+
+------------------------------------------------------------------------
+r3625 | pelissip | 2005-06-07 16:02:48 +0000 (Tue, 07 Jun 2005) | 5 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+MPFR_GET_EXP was wrongly defined and does nothing due to recursive
+macro (mpfr_get_exp is also defined to be a fast macro). Fix this
+by removing the macro call in MPFR_GET_EXP in case of ASSERT >= 1.
+2 tests failed now!
+
+------------------------------------------------------------------------
+r3624 | pelissip | 2005-06-07 15:42:17 +0000 (Tue, 07 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsum.c
+
+Clean up and improve check.
+
+------------------------------------------------------------------------
+r3623 | pelissip | 2005-06-07 15:41:57 +0000 (Tue, 07 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/sum.c
+
+Handle case n==0 and n==1 as special cases.
+
+------------------------------------------------------------------------
+r3622 | pelissip | 2005-06-07 14:27:34 +0000 (Tue, 07 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/const_catalan.c
+ M /trunk/tests/tconst_catalan.c
+
+Simplify test to use tgeneric.
+Add note about Worst Case of const_catalan up to 100,000,000
+
+------------------------------------------------------------------------
+r3621 | pelissip | 2005-06-07 14:26:45 +0000 (Tue, 07 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Use GROUP functions.
+
+------------------------------------------------------------------------
+r3620 | pelissip | 2005-06-07 09:52:04 +0000 (Tue, 07 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tconst_pi.c
+
+Improve coverage.
+
+------------------------------------------------------------------------
+r3619 | pelissip | 2005-06-07 09:51:49 +0000 (Tue, 07 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Fix bug in MPFR_GROUP_REPREC_3.
+
+------------------------------------------------------------------------
+r3618 | pelissip | 2005-06-06 14:49:55 +0000 (Mon, 06 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/ui_pow_ui.c
+
+Improve coverage
+
+------------------------------------------------------------------------
+r3617 | pelissip | 2005-06-06 14:13:47 +0000 (Mon, 06 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+
+Improve coverage test
+
+------------------------------------------------------------------------
+r3616 | pelissip | 2005-06-06 13:52:29 +0000 (Mon, 06 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tzeta.c
+
+Remove mpfr_sub_one_ulp from MPFR library.
+Keep the C file until we are sure it not needed anymore.
+
+------------------------------------------------------------------------
+r3615 | pelissip | 2005-06-06 13:42:40 +0000 (Mon, 06 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tnext.c
+
+Improve coverage.
+
+------------------------------------------------------------------------
+r3614 | pelissip | 2005-06-06 13:39:40 +0000 (Mon, 06 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/div_ui.c
+ M /trunk/hypot.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tzeta.c
+
+Remove mpfr_add_one_ulp from MPFR library.
+The function is still in the CVS.
+
+------------------------------------------------------------------------
+r3613 | pelissip | 2005-06-06 12:06:15 +0000 (Mon, 06 Jun 2005) | 4 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Add experimental code (disabled).
+For 5000 bits, gamma(12.5) takes 4s instead of 18s.
+But it changes the error analysis...
+
+------------------------------------------------------------------------
+r3612 | pelissip | 2005-06-06 11:27:08 +0000 (Mon, 06 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Reduce use of intermediary variables.
+
+------------------------------------------------------------------------
+r3611 | pelissip | 2005-06-06 09:42:16 +0000 (Mon, 06 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+Improve comment of previous change.
+
+------------------------------------------------------------------------
+r3610 | pelissip | 2005-06-06 09:30:13 +0000 (Mon, 06 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/zeta.c
+
+Use FastCompute if x is positive and big, ie it uses
+Zeta(x)=1+1/2^X+O(1/3^x)
+
+------------------------------------------------------------------------
+r3609 | pelissip | 2005-06-03 11:15:05 +0000 (Fri, 03 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/ui_pow_ui.c
+
+Add new and faster trivial case for y <= 1 and n <= 1
+
+------------------------------------------------------------------------
+r3608 | pelissip | 2005-06-02 16:20:05 +0000 (Thu, 02 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/COPYING
+ M /trunk/COPYING.LIB
+
+Forget thoses two. Update from FSF site.
+
+------------------------------------------------------------------------
+r3607 | pelissip | 2005-06-02 16:16:17 +0000 (Thu, 02 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+
+Finish updating files.
+
+------------------------------------------------------------------------
+r3606 | pelissip | 2005-06-02 16:12:06 +0000 (Thu, 02 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/abort_prec_max.c
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_one_ulp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atan2.c
+ M /trunk/atanh.c
+ M /trunk/cache.c
+ M /trunk/cbrt.c
+ M /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_ld.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/const_catalan.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/constant.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/cot.c
+ M /trunk/coth.c
+ M /trunk/csc.c
+ M /trunk/csch.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eint.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/erfc.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/fits_intmax.c
+ M /trunk/fits_s.h
+ M /trunk/fits_sint.c
+ M /trunk/fits_slong.c
+ M /trunk/fits_sshort.c
+ M /trunk/fits_u.h
+ M /trunk/fits_uint.c
+ M /trunk/fits_uintmax.c
+ M /trunk/fits_ulong.c
+ M /trunk/fits_ushort.c
+ M /trunk/fma.c
+ M /trunk/frac.c
+ M /trunk/free_cache.c
+ M /trunk/gamma.c
+ M /trunk/gen_inverse.h
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_exp.c
+ M /trunk/get_f.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/get_z.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/int_ceil_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/isqrt.c
+ M /trunk/iszero.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/logging.c
+ M /trunk/minmax.c
+ M /trunk/mp_clz_tab.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-longlong.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/mulders.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/powerof2.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/root.c
+ M /trunk/round_near_x.c
+ M /trunk/round_p.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/sec.c
+ M /trunk/sech.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_ld.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_sj.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sgn.c
+ M /trunk/si_op.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/strcasecmp.c
+ M /trunk/strncasecmp.c
+ M /trunk/strtofr.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/sub_ui.c
+ M /trunk/subnormal.c
+ M /trunk/sum.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcopysign.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tcot.c
+ M /trunk/tests/tcoth.c
+ M /trunk/tests/tcsc.c
+ M /trunk/tests/tcsch.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teint.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfits.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_f.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tminmax.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/troot.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tsec.c
+ M /trunk/tests/tsech.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tstrtofr.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tversion.c
+ M /trunk/tests/tzeta.c
+ M /trunk/tuneup.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+ M /trunk/zeta.c
+
+Change the address of the FSF.
+
+------------------------------------------------------------------------
+r3605 | pelissip | 2005-06-02 15:55:58 +0000 (Thu, 02 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Optimize it a few by avoiding calling fac_ui for each iteration
+of the main loop.
+
+------------------------------------------------------------------------
+r3604 | pelissip | 2005-06-02 15:16:19 +0000 (Thu, 02 Jun 2005) | 4 lines
+Changed paths:
+ M /trunk/zeta.c
+
+Reduce # of vars inside the main loop.
+Use GROUP function.
+Improve overflow problems (Use of int instead of mp_prec_t).
+
+------------------------------------------------------------------------
+r3603 | pelissip | 2005-06-02 15:15:44 +0000 (Thu, 02 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Improve efficiency by removing 2 variables (Loop uses only 4 vars).
+Use GROUP.
+
+------------------------------------------------------------------------
+r3602 | pelissip | 2005-06-02 15:15:02 +0000 (Thu, 02 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/abort_prec_max.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/sinh.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+
+Add support for MPFR_GROUP functions.
+
+------------------------------------------------------------------------
+r3601 | pelissip | 2005-06-02 15:14:15 +0000 (Thu, 02 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Add attribute const and noreturn for function (via macros).
+Add new macros GROUP_INIT_6 and GROUP_REPREC_6 for zeta and gamma.
+
+------------------------------------------------------------------------
+r3600 | zimmerma | 2005-06-02 10:17:09 +0000 (Thu, 02 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added missing functions from gnumeric
+
+------------------------------------------------------------------------
+r3599 | pelissip | 2005-06-02 09:22:55 +0000 (Thu, 02 Jun 2005) | 5 lines
+Changed paths:
+ M /trunk/TODO
+
+Update stack-interface.
+Remove round_near_x item.
+Add new functions to implement.
+Reformat file.
+
+------------------------------------------------------------------------
+r3598 | pelissip | 2005-06-02 07:40:56 +0000 (Thu, 02 Jun 2005) | 4 lines
+Changed paths:
+ M /trunk/tests/tconst_pi.c
+
+Fix input precision of mp_prec_t.
+May be outside 'int' range. So it uses 'long' instead and
+a proper check.
+
+------------------------------------------------------------------------
+r3597 | vlefevre | 2005-05-25 14:32:37 +0000 (Wed, 25 May 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Added coding recommendations concerning C++ compilers.
+
+------------------------------------------------------------------------
+r3596 | pelissip | 2005-05-23 12:31:57 +0000 (Mon, 23 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Final version of MPFR_GROUP macros.
+
+------------------------------------------------------------------------
+r3595 | pelissip | 2005-05-23 12:31:43 +0000 (Mon, 23 May 2005) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+ M /trunk/tests/tstrtofr.c
+
+Improve coverage test.
+
+------------------------------------------------------------------------
+r3594 | pelissip | 2005-05-20 09:30:19 +0000 (Fri, 20 May 2005) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+Remove variable t which wasn't used!
+
+------------------------------------------------------------------------
+r3593 | pelissip | 2005-05-18 15:57:10 +0000 (Wed, 18 May 2005) | 6 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/agm.c
+ M /trunk/cos.c
+ M /trunk/div-short.c
+ M /trunk/div.c
+ M /trunk/div_ui.c
+ M /trunk/exp_2.c
+ M /trunk/generic.c
+ M /trunk/get_str.c
+ M /trunk/init2.c
+ M /trunk/log.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/round_prec.c
+ M /trunk/set_f.c
+ M /trunk/sqr.c
+ M /trunk/sqrt.c
+ M /trunk/strtofr.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sum.c
+ M /trunk/tests/tsum.c
+ M /trunk/tuneup.c
+
+Replace TMP_ALLOC by MPFR_TMP_ALLOC
+Replace TMP_DECL by MPFR_TMP_DECL
+Replace TMP_MARK by MPFR_TMP_MARK
+Replace TMP_FREE by MPFR_TMP_FREE
+Add support for GMP's TMP_SALLOC.
+
+------------------------------------------------------------------------
+r3592 | pelissip | 2005-05-18 13:17:40 +0000 (Wed, 18 May 2005) | 5 lines
+Changed paths:
+ M /trunk/pow.c
+
+New way of handling exact value.
+Fix bug of wrong rounding and wrong ternary value if the power
+is exact, but at an upper precision than the working precision.
+Now it computes the power exactly if it detects it is exact.
+
+------------------------------------------------------------------------
+r3591 | pelissip | 2005-05-18 13:13:15 +0000 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Precise that 1 is not the only value.
+
+------------------------------------------------------------------------
+r3590 | vlefevre | 2005-05-18 13:03:10 +0000 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+an 1 -> a 1.
+
+------------------------------------------------------------------------
+r3589 | pelissip | 2005-05-18 09:42:00 +0000 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add a note about special case 1
+
+------------------------------------------------------------------------
+r3588 | pelissip | 2005-05-18 09:01:41 +0000 (Wed, 18 May 2005) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+
+Add assertions
+Remove useless function is_odd_even.
+
+------------------------------------------------------------------------
+r3587 | pelissip | 2005-05-18 08:53:39 +0000 (Wed, 18 May 2005) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+
+Fix bug: returning 1 didn't take the rounding mode into account.
+Simplify dependencies of mpfr_pow.
+
+------------------------------------------------------------------------
+r3586 | pelissip | 2005-05-18 08:42:54 +0000 (Wed, 18 May 2005) | 4 lines
+Changed paths:
+ M /trunk/expm1.c
+ M /trunk/tests/texpm1.c
+
+Fix bug of overflow
+Fix bug of wrong ternary value in case of overflow
+Add test cases.
+
+------------------------------------------------------------------------
+r3585 | pelissip | 2005-05-18 08:22:55 +0000 (Wed, 18 May 2005) | 3 lines
+Changed paths:
+ M /trunk/cosh.c
+ M /trunk/tests/tcosh.c
+
+Fix bug of overflow.
+Fix bug of ternary value in case of overflow.
+
+------------------------------------------------------------------------
+r3584 | pelissip | 2005-05-18 08:22:28 +0000 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tanh.c
+
+Clean up previous patch.
+
+------------------------------------------------------------------------
+r3583 | pelissip | 2005-05-18 07:30:01 +0000 (Wed, 18 May 2005) | 4 lines
+Changed paths:
+ M /trunk/sinh.c
+ M /trunk/tests/tsinh.c
+
+Fix bug of overflow.
+Fix bug of ternary value in case of overflow.
+Still some bugs...
+
+------------------------------------------------------------------------
+r3582 | pelissip | 2005-05-17 16:17:12 +0000 (Tue, 17 May 2005) | 4 lines
+Changed paths:
+ M /trunk/tanh.c
+ M /trunk/tests/ttanh.c
+
+Rewrite the way of handling overflow.
+Fix bug due to overflow.
+Fix bug due to wrong ternary value.
+
+------------------------------------------------------------------------
+r3581 | pelissip | 2005-05-17 16:15:15 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Typo.
+
+------------------------------------------------------------------------
+r3580 | pelissip | 2005-05-17 15:37:02 +0000 (Tue, 17 May 2005) | 3 lines
+Changed paths:
+ M /trunk/sinh.c
+ M /trunk/tests/tsinh.c
+
+Fix bug of overflow.
+Still a problem if exp(x) is near the limit of EMAX_MAX.
+
+------------------------------------------------------------------------
+r3579 | pelissip | 2005-05-17 15:35:38 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Add new macro MPFR_SAVE_DECL_UPDATE_FLAGS
+
+------------------------------------------------------------------------
+r3578 | pelissip | 2005-05-17 15:17:32 +0000 (Tue, 17 May 2005) | 3 lines
+Changed paths:
+ M /trunk/sinh.c
+ M /trunk/tests/tsinh.c
+
+Improve way of handling overflow (still not perfect but far better).
+Improve coverage test.
+
+------------------------------------------------------------------------
+r3577 | pelissip | 2005-05-17 15:14:53 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/get_si.c
+ M /trunk/tests/tset_si.c
+
+Improve coverage test.
+
+------------------------------------------------------------------------
+r3576 | vlefevre | 2005-05-17 15:14:37 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/thypot.c
+
+hypot(±oo, NaN) now returns +oo, as in ISO C99 (wasn't documented).
+
+------------------------------------------------------------------------
+r3575 | pelissip | 2005-05-17 14:09:21 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tasin.c
+
+Improve coverage test.
+
+------------------------------------------------------------------------
+r3574 | pelissip | 2005-05-17 14:09:10 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+
+Remove useless test.
+
+------------------------------------------------------------------------
+r3573 | pelissip | 2005-05-17 13:28:02 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Improve coverage test.
+
+------------------------------------------------------------------------
+r3572 | pelissip | 2005-05-17 13:06:26 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/set_z.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tset_z.c
+
+Improve coverage
+
+------------------------------------------------------------------------
+r3571 | pelissip | 2005-05-17 12:58:43 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmpabs.c
+
+Improve coverage test.
+
+------------------------------------------------------------------------
+r3570 | pelissip | 2005-05-17 12:58:30 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/coverage
+
+Add CFLAGS -g.
+
+------------------------------------------------------------------------
+r3569 | pelissip | 2005-05-17 12:27:39 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+Clean up
+
+------------------------------------------------------------------------
+r3568 | pelissip | 2005-05-17 12:13:44 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tfits.c
+
+Improve coverage tests.
+
+------------------------------------------------------------------------
+r3567 | pelissip | 2005-05-17 11:45:11 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+Improve coverage test.
+
+------------------------------------------------------------------------
+r3566 | pelissip | 2005-05-17 11:34:11 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tanh.c
+
+Special a condition by the simplified one.
+
+------------------------------------------------------------------------
+r3565 | pelissip | 2005-05-17 10:31:34 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_catalan.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tget_d.c
+
+Improve coverage test (Forget to test tiny functions).
+
+------------------------------------------------------------------------
+r3564 | pelissip | 2005-05-17 10:12:30 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/coverage
+
+Typo
+
+------------------------------------------------------------------------
+r3563 | pelissip | 2005-05-17 10:04:14 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ A /trunk/coverage
+
+Add 'coverage' script.
+
+------------------------------------------------------------------------
+r3562 | pelissip | 2005-05-17 10:03:54 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/constant.c
+
+Add 'static'
+
+------------------------------------------------------------------------
+r3561 | pelissip | 2005-05-17 08:52:13 +0000 (Tue, 17 May 2005) | 5 lines
+Changed paths:
+ M /trunk/cos.c
+
+Reformating code.
+Fix potential (?) overflow for very large precision.
+Various tiny optimizations
+Improve the initial estimation of the needed precision.
+
+------------------------------------------------------------------------
+r3560 | pelissip | 2005-05-17 08:46:45 +0000 (Tue, 17 May 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/constant.c
+ M /trunk/log.c
+ M /trunk/mpfr-impl.h
+
+Extract constants (__gmpfr_one, two and four) from log.c to constant.c
+Fix bug in MPFR_SET_ONE.
+
+------------------------------------------------------------------------
+r3559 | pelissip | 2005-05-17 08:45:00 +0000 (Tue, 17 May 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+Remove a space.
+
+------------------------------------------------------------------------
+r3558 | vlefevre | 2005-05-16 14:29:49 +0000 (Mon, 16 May 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Typography + spelling.
+
+------------------------------------------------------------------------
+r3557 | vlefevre | 2005-05-16 14:26:20 +0000 (Mon, 16 May 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Note that mpfr_out_str has slightly changed.
+
+------------------------------------------------------------------------
+r3556 | pelissip | 2005-05-16 07:34:04 +0000 (Mon, 16 May 2005) | 3 lines
+Changed paths:
+ M /trunk/TODO
+
+asin, atan, atanh are not slow anymore for small input.
+Remove it in the TODO.
+
+------------------------------------------------------------------------
+r3555 | vlefevre | 2005-05-14 17:53:00 +0000 (Sat, 14 May 2005) | 4 lines
+Changed paths:
+ M /trunk/atanh.c
+
+Fixed a bug due to a typo on a variable name. It produced a
+segmentation fault in the tests on Linux/ppc (uninitialized data were
+read), not always reproducible when stepping with gdb.
+
+------------------------------------------------------------------------
+r3553 | pelissip | 2005-05-13 11:49:46 +0000 (Fri, 13 May 2005) | 2 lines
+Changed paths:
+ M /trunk/expm1.c
+ M /trunk/log1p.c
+
+Add support for MPFR_FAST_COMPUTE_IS_SMALL_INPUT
+
+------------------------------------------------------------------------
+r3552 | pelissip | 2005-05-13 11:41:39 +0000 (Fri, 13 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+
+Add support for FAST_COMPUTE_IS_SMALL_INPUT.
+
+------------------------------------------------------------------------
+r3551 | pelissip | 2005-05-13 10:58:38 +0000 (Fri, 13 May 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Add round_near_x support for small arguments.
+
+------------------------------------------------------------------------
+r3550 | pelissip | 2005-05-13 10:58:20 +0000 (Fri, 13 May 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/round_near_x.c
+
+Add new internal function mpfr_round_near_x.
+
+------------------------------------------------------------------------
+r3549 | zimmerma | 2005-05-13 09:37:42 +0000 (Fri, 13 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added missing documentation for mpfr_hypot
+
+------------------------------------------------------------------------
+r3548 | pelissip | 2005-05-13 09:12:07 +0000 (Fri, 13 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/texceptions.c
+
+Add a \n for all error strings.
+
+------------------------------------------------------------------------
+r3547 | pelissip | 2005-05-13 09:11:48 +0000 (Fri, 13 May 2005) | 2 lines
+Changed paths:
+ M /trunk/version.c
+
+Fix copyright date.
+
+------------------------------------------------------------------------
+r3546 | pelissip | 2005-05-13 09:11:11 +0000 (Fri, 13 May 2005) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/texp.c
+
+Fix some problems when you define mpfr_prec_t to be an unsigned short.
+Now all tests passed when mpfr_prec_t is defined to be an unsigned short
+on a 32 bit CPU!
+
+------------------------------------------------------------------------
+r3542 | vlefevre | 2005-05-12 09:21:49 +0000 (Thu, 12 May 2005) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+Detect/avoid potential integer overflows.
+
+------------------------------------------------------------------------
+r3541 | pelissip | 2005-05-12 08:55:27 +0000 (Thu, 12 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+Fix typos.
+
+------------------------------------------------------------------------
+r3540 | pelissip | 2005-05-11 15:43:40 +0000 (Wed, 11 May 2005) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+ M /trunk/tests/texp.c
+
+Same patch for exp_3.
+
+------------------------------------------------------------------------
+r3539 | pelissip | 2005-05-11 15:24:48 +0000 (Wed, 11 May 2005) | 5 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/exp_2.c
+ M /trunk/tests/texp.c
+
+Fix bug when exp(x) is near the limit of an overflow or an
+underflow (mpfr_exp_2 didn't allow an overflow/underflow in its
+internal loop).
+Add corresponding test case. exp_3 may need similar patchs.
+
+------------------------------------------------------------------------
+r3538 | vlefevre | 2005-05-11 11:03:55 +0000 (Wed, 11 May 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update (with reformatting so that the logs are readable on 80 columns).
+
+------------------------------------------------------------------------
+r3537 | pelissip | 2005-05-11 07:42:05 +0000 (Wed, 11 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+ M /trunk/tests/tmul.c
+
+Fix bug due to wrong assertion.
+
+------------------------------------------------------------------------
+r3536 | pelissip | 2005-05-10 11:49:58 +0000 (Tue, 10 May 2005) | 9 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+
+1. Change the prototype of mpfr_can_round to use const.
+2. Change the prototype of mpfr_round_raw_2 (remove first argument since it is
+ useless).
+3. Change round_raw_generic to use preprocessor if rather than compiler
+ to detect if flag == 1 or 0
+4. mpfr_round_raw_xxx use const attribute too.
+5. Remove mpfr_round_raw_3 since it is unused by MPFR.
+6. Add first prototype of MPFR_FAST_COMPUTE_IF_SMALL.
+
+------------------------------------------------------------------------
+r3535 | pelissip | 2005-05-10 09:52:11 +0000 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Update.
+
+------------------------------------------------------------------------
+r3534 | pelissip | 2005-05-10 09:34:22 +0000 (Tue, 10 May 2005) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+ M /trunk/tests/tmul.c
+
+Fix a bug in the product of 2limbs per 2 limbs.
+Add new regression test.
+
+------------------------------------------------------------------------
+r3533 | pelissip | 2005-05-10 07:28:06 +0000 (Tue, 10 May 2005) | 5 lines
+Changed paths:
+ M /trunk/configure.in
+
+Fix problem with mingw: if the configure detects MS-Windows, it skips the
+tests which try to link against GMP within the configure, hoping the Makefile
+works. The main problem is that we need libtool inside the configure to link
+against GMP.
+
+------------------------------------------------------------------------
+r3532 | pelissip | 2005-05-09 09:09:37 +0000 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+Improve random tests.
+
+------------------------------------------------------------------------
+r3531 | pelissip | 2005-05-04 16:20:06 +0000 (Wed, 04 May 2005) | 4 lines
+Changed paths:
+ M /trunk/cos.c
+
+Replace initial estimation of K0 from sqrt (p/2)
+to sqrt(p/16). It seems to be 30% faster for 5000 bits, and 5% faster
+for 50 bits.
+
+------------------------------------------------------------------------
+r3529 | vlefevre | 2005-05-04 15:59:49 +0000 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+Reformatted the code.
+
+------------------------------------------------------------------------
+r3528 | zimmerma | 2005-05-04 15:20:17 +0000 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv_ui.c
+
+fixed dummy init2 followed by set_prec
+
+------------------------------------------------------------------------
+r3527 | vlefevre | 2005-05-04 13:42:36 +0000 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Added LIA-2 functions to implement.
+
+------------------------------------------------------------------------
+r3526 | pelissip | 2005-05-04 09:51:10 +0000 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/TODO
+ A /trunk/coth.c
+ A /trunk/csch.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/sech.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tcot.c
+ A /trunk/tests/tcoth.c
+ A /trunk/tests/tcsch.c
+ M /trunk/tests/tsec.c
+ A /trunk/tests/tsech.c
+
+Add functions mpfr_sech, mpfr_coth and mpfr_csch.
+
+------------------------------------------------------------------------
+r3525 | pelissip | 2005-05-04 09:49:51 +0000 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/gen_inverse.h
+
+init2 alloc what is needed, not 2 (more efficient).
+
+------------------------------------------------------------------------
+r3524 | zimmerma | 2005-05-04 09:27:48 +0000 (Wed, 04 May 2005) | 4 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/algorithms.tex
+ M /trunk/asinh.c
+ M /trunk/const_euler.c
+ M /trunk/cosh.c
+ M /trunk/eint.c
+ M /trunk/exp2.c
+ M /trunk/expm1.c
+ M /trunk/hypot.c
+ M /trunk/log10.c
+ M /trunk/log2.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/tanh.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+
+improved const_euler and eint
+removed dependency from input precision in several functions
+fixed two bugs in pow (detection of exact cases)
+
+------------------------------------------------------------------------
+r3523 | pelissip | 2005-05-04 08:35:23 +0000 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Update to reflect the current state.
+
+------------------------------------------------------------------------
+r3522 | pelissip | 2005-05-03 16:39:04 +0000 (Tue, 03 May 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Fix computing of `sup` to reflect what is decribed in algorithms.tex.
+
+------------------------------------------------------------------------
+r3521 | pelissip | 2005-05-03 14:57:04 +0000 (Tue, 03 May 2005) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+
+Tiny optimization of mpfr_atan.
+On opteron with p=53, from 9231 / 18049.89 / 81758 to 9004 / 17522.76 / 78601.
+
+------------------------------------------------------------------------
+r3520 | vlefevre | 2005-05-03 12:42:01 +0000 (Tue, 03 May 2005) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+Fixed a problem in test_small (already done in the 2.1 branch)
+when long double = double.
+
+------------------------------------------------------------------------
+r3519 | pelissip | 2005-05-03 10:42:41 +0000 (Tue, 03 May 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Improve detection again (use callback).
+
+------------------------------------------------------------------------
+r3518 | pelissip | 2005-05-03 10:15:46 +0000 (Tue, 03 May 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Improve previous change.
+
+------------------------------------------------------------------------
+r3517 | pelissip | 2005-05-03 09:51:50 +0000 (Tue, 03 May 2005) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/tests/trint.c
+
+Add detection of function round, rint, ceil, floor and nearbyint at configure
+time so that spe206 which defines itself as C99 compliant can build the
+trint test.
+
+------------------------------------------------------------------------
+r3516 | pelissip | 2005-05-03 08:55:18 +0000 (Tue, 03 May 2005) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Update (Move bugs to potential).
+
+------------------------------------------------------------------------
+r3515 | vlefevre | 2005-05-03 08:08:50 +0000 (Tue, 03 May 2005) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/hypot.c
+ M /trunk/tests/thypot.c
+
+Fixed the mpfr_hypot bug, and re-enabled the test_large_small test.
+
+------------------------------------------------------------------------
+r3514 | vlefevre | 2005-05-02 23:17:44 +0000 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3512 | vlefevre | 2005-05-02 22:57:16 +0000 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Mention the mpfr_hypot bug.
+
+------------------------------------------------------------------------
+r3511 | vlefevre | 2005-05-02 22:46:56 +0000 (Mon, 02 May 2005) | 3 lines
+Changed paths:
+ M /trunk/tests/thypot.c
+
+Added a test showing a bug, enabled when TEST_LARGE_SMALL is defined
+(to avoid a freeze with make check).
+
+------------------------------------------------------------------------
+r3510 | pelissip | 2005-05-02 15:05:43 +0000 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix bug.
+
+------------------------------------------------------------------------
+r3509 | pelissip | 2005-05-02 15:05:30 +0000 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Remove useless function f.
+
+------------------------------------------------------------------------
+r3508 | pelissip | 2005-05-02 13:11:39 +0000 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/subnormal.c
+
+Fix a bug: the test to detect EVEN_rounding was wrong.
+
+------------------------------------------------------------------------
+r3507 | pelissip | 2005-05-02 13:11:07 +0000 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update example of use of mpfr_subnormalize.
+
+------------------------------------------------------------------------
+r3506 | pelissip | 2005-05-02 13:10:44 +0000 (Mon, 02 May 2005) | 3 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/cmp_str.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmpabs.c
+
+mpfr_cmp_str checks for NAN.
+Add macro mpfr_cmp0 in mpfr-test.
+
+------------------------------------------------------------------------
+r3505 | pelissip | 2005-05-02 13:09:35 +0000 (Mon, 02 May 2005) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/troot.c
+
+Undo previous change for tgeneric.
+troot uses tgeneric_ui instead.
+
+------------------------------------------------------------------------
+r3504 | pelissip | 2005-05-01 09:21:43 +0000 (Sun, 01 May 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+Add new funcions in reuse test.
+
+------------------------------------------------------------------------
+r3503 | zimmerma | 2005-04-30 11:03:47 +0000 (Sat, 30 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added efficiency item
+
+------------------------------------------------------------------------
+r3502 | zimmerma | 2005-04-30 10:36:21 +0000 (Sat, 30 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/TODO
+ M /trunk/algorithms.tex
+ A /trunk/eint.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/teint.c
+
+added mpfr_eint
+
+------------------------------------------------------------------------
+r3501 | pelissip | 2005-04-29 17:24:30 +0000 (Fri, 29 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Add something to do :)
+
+------------------------------------------------------------------------
+r3500 | zimmerma | 2005-04-29 08:19:01 +0000 (Fri, 29 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added comment about efficiency of atan
+
+------------------------------------------------------------------------
+r3499 | vlefevre | 2005-04-29 07:42:30 +0000 (Fri, 29 Apr 2005) | 3 lines
+Changed paths:
+ A /trunk/FAQ.html
+ M /trunk/Makefile.am
+ M /trunk/README
+ M /trunk/README.dev
+ A /trunk/faq.xsl
+ A /trunk/update-faq
+
+The FAQ is now distributed with MPFR. Use update-faq to update it
+from the MPFR web site.
+
+------------------------------------------------------------------------
+r3498 | zimmerma | 2005-04-29 07:30:29 +0000 (Fri, 29 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+commented out argument reduction analysis for arctan (was wrong)
+
+------------------------------------------------------------------------
+r3496 | zimmerma | 2005-04-28 09:47:32 +0000 (Thu, 28 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+wrong commit, put revision 1.37 back
+
+------------------------------------------------------------------------
+r3495 | zimmerma | 2005-04-28 09:45:05 +0000 (Thu, 28 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+wrong commit, put back revision 1.47
+
+------------------------------------------------------------------------
+r3494 | zimmerma | 2005-04-28 09:38:45 +0000 (Thu, 28 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/cos.c
+ M /trunk/sin.c
+
+added error analysis for Geoff's argument reduction for arctan
+
+------------------------------------------------------------------------
+r3493 | vlefevre | 2005-04-27 20:56:08 +0000 (Wed, 27 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Added a note about mpfr_set_d and mpfr_set_ld.
+
+------------------------------------------------------------------------
+r3492 | vlefevre | 2005-04-27 13:51:06 +0000 (Wed, 27 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/update-version
+
+Define MPFR_VERSION_STRING using the update-version script
+(works with any compiler).
+
+------------------------------------------------------------------------
+r3491 | zimmerma | 2005-04-26 10:46:13 +0000 (Tue, 26 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added internal interface
+
+------------------------------------------------------------------------
+r3490 | zimmerma | 2005-04-26 10:02:01 +0000 (Tue, 26 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added suggestion from Geoff
+
+------------------------------------------------------------------------
+r3489 | zimmerma | 2005-04-26 09:37:28 +0000 (Tue, 26 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tversion.c
+
+added MPFR_VERSION_STRING
+
+------------------------------------------------------------------------
+r3488 | zimmerma | 2005-04-25 13:06:11 +0000 (Mon, 25 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added new item
+
+------------------------------------------------------------------------
+r3487 | zimmerma | 2005-04-25 12:51:56 +0000 (Mon, 25 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/expm1.c
+ M /trunk/log1p.c
+
+improved expm1/log1p for small argument
+
+------------------------------------------------------------------------
+r3486 | zimmerma | 2005-04-25 12:16:12 +0000 (Mon, 25 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/expm1.c
+
+improved to taken account of case |x| small (reported by Keith Briggs)
+
+------------------------------------------------------------------------
+r3485 | vlefevre | 2005-04-25 12:12:17 +0000 (Mon, 25 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Added a missing "-" and replaced a few "-" by @minus{}.
+
+------------------------------------------------------------------------
+r3484 | vlefevre | 2005-04-25 11:53:56 +0000 (Mon, 25 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Added a note for mpfr_cmp functions.
+
+------------------------------------------------------------------------
+r3483 | zimmerma | 2005-04-25 05:41:27 +0000 (Mon, 25 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+ M /trunk/tests/tset_ld.c
+
+fixed bug with tiny number
+
+------------------------------------------------------------------------
+r3482 | zimmerma | 2005-04-22 22:23:09 +0000 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed done item
+
+------------------------------------------------------------------------
+r3481 | pelissip | 2005-04-22 15:20:22 +0000 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Add a macro for mpfr_const_catalan for internal use.
+
+------------------------------------------------------------------------
+r3480 | pelissip | 2005-04-22 15:18:33 +0000 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix typos.
+
+------------------------------------------------------------------------
+r3479 | zimmerma | 2005-04-22 10:38:21 +0000 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed Root, updated eint*
+
+------------------------------------------------------------------------
+r3478 | zimmerma | 2005-04-22 10:13:05 +0000 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/TODO
+ A /trunk/cot.c
+ A /trunk/csc.c
+ A /trunk/gen_inverse.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/sec.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tcot.c
+ A /trunk/tests/tcsc.c
+ A /trunk/tests/tsec.c
+
+added sec, csc, cot
+
+------------------------------------------------------------------------
+r3477 | zimmerma | 2005-04-22 08:48:44 +0000 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+proposal for exponential integral definition
+
+------------------------------------------------------------------------
+r3476 | zimmerma | 2005-04-22 05:38:41 +0000 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/TODO
+ M /trunk/tests/Makefile.am
+
+added mpfr_root, removed from TODO
+
+------------------------------------------------------------------------
+r3475 | zimmerma | 2005-04-22 05:32:01 +0000 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/cbrt.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/root.c
+ M /trunk/tests/tgeneric.c
+ A /trunk/tests/troot.c
+
+added mpfr_root
+
+------------------------------------------------------------------------
+r3474 | vlefevre | 2005-04-21 15:21:40 +0000 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3469 | vlefevre | 2005-04-21 13:05:42 +0000 (Thu, 21 Apr 2005) | 4 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+Added the ability to change the control word when compiling tset_ld
+with -DWITH_FPU_CONTROL=1 and executing tset_ld with an argument
+(not used in the automatical tests yet).
+
+------------------------------------------------------------------------
+r3465 | vlefevre | 2005-04-21 09:32:22 +0000 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+Added test_small (the same as in the 2.1 branch).
+
+------------------------------------------------------------------------
+r3463 | vlefevre | 2005-04-21 09:14:46 +0000 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+Updated a comment and reformatted the code.
+
+------------------------------------------------------------------------
+r3460 | zimmerma | 2005-04-21 06:33:22 +0000 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added explanation
+
+------------------------------------------------------------------------
+r3457 | zimmerma | 2005-04-20 07:59:38 +0000 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/const_catalan.c
+ M /trunk/tests/Makefile.am
+
+adjusted initial guard digits for const_catalan to avoid failure for prec<=10^4
+
+------------------------------------------------------------------------
+r3456 | zimmerma | 2005-04-20 05:53:17 +0000 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/const_catalan.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tconst_catalan.c
+
+updated documentation and improved tests for mpfr_const_catalan
+
+------------------------------------------------------------------------
+r3455 | zimmerma | 2005-04-20 03:43:06 +0000 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed Catalan's constant (done)
+
+------------------------------------------------------------------------
+r3454 | zimmerma | 2005-04-20 03:40:24 +0000 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ A /trunk/const_catalan.c
+ M /trunk/free_cache.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ A /trunk/tests/tconst_catalan.c
+
+added Catalan's constant
+
+------------------------------------------------------------------------
+r3453 | zimmerma | 2005-04-20 01:23:23 +0000 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added efficiency items suggested by Geoff Bailey
+
+------------------------------------------------------------------------
+r3452 | zimmerma | 2005-04-20 00:12:45 +0000 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/atan2.c
+
+fixed minor problem (wrong rounding mode for x=0, y<0), thanks Geoff Bailey
+
+------------------------------------------------------------------------
+r3451 | zimmerma | 2005-04-19 09:23:28 +0000 (Tue, 19 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one efficiency item
+
+------------------------------------------------------------------------
+r3450 | zimmerma | 2005-04-19 09:01:03 +0000 (Tue, 19 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+completely rewritten algorithm and error analysis for acosh
+(did not match those in acosh.c)
+
+------------------------------------------------------------------------
+r3449 | zimmerma | 2005-04-19 08:59:31 +0000 (Tue, 19 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+
+algorithm and error bound did not match those of algorithm.tex!!!
+
+------------------------------------------------------------------------
+r3448 | zimmerma | 2005-04-19 07:50:22 +0000 (Tue, 19 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added missing functions for Magma
+
+------------------------------------------------------------------------
+r3447 | zimmerma | 2005-04-19 07:17:54 +0000 (Tue, 19 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr.texi
+
+changed semantics of mpfr_get_str for ndigits=0
+
+------------------------------------------------------------------------
+r3446 | zimmerma | 2005-04-14 13:44:58 +0000 (Thu, 14 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one item (efficiency)
+
+------------------------------------------------------------------------
+r3445 | pelissip | 2005-04-14 13:29:06 +0000 (Thu, 14 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/atan2.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tatan.c
+
+Fix atan2 to fit C99 semantic.
+
+------------------------------------------------------------------------
+r3444 | pelissip | 2005-04-14 09:20:24 +0000 (Thu, 14 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix typos.
+
+------------------------------------------------------------------------
+r3443 | pelissip | 2005-04-14 09:20:13 +0000 (Thu, 14 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/atan2.c
+
+Add TODO.
+
+------------------------------------------------------------------------
+r3442 | pelissip | 2005-04-14 08:48:54 +0000 (Thu, 14 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add documentation for mpfr_subnormalize.
+
+------------------------------------------------------------------------
+r3441 | pelissip | 2005-04-14 08:14:49 +0000 (Thu, 14 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/subnormal.c
+
+Fix bugs.
+
+------------------------------------------------------------------------
+r3440 | pelissip | 2005-04-13 17:23:03 +0000 (Wed, 13 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/div_ui.c
+ M /trunk/tests/tsi_op.c
+
+Apply Guillaume's patch about mpfr_div_ui.
+Fix a bug in tsi_op (forget to clean memory).
+
+------------------------------------------------------------------------
+r3439 | pelissip | 2005-04-13 16:05:02 +0000 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ A /trunk/subnormal.c
+
+Add function mpfr_subnormalize (To Test!!!!!)
+
+------------------------------------------------------------------------
+r3438 | pelissip | 2005-04-13 15:48:51 +0000 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/atan2.c
+
+Add TODO.
+
+------------------------------------------------------------------------
+r3437 | pelissip | 2005-04-13 15:46:45 +0000 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/expm1.c
+
+Fix wrong comment.
+
+------------------------------------------------------------------------
+r3436 | pelissip | 2005-04-07 13:35:38 +0000 (Thu, 07 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/terf.c
+
+Reenable tests.
+
+------------------------------------------------------------------------
+r3435 | pelissip | 2005-04-07 11:58:52 +0000 (Thu, 07 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add documentation about mpfr_atan2.
+
+------------------------------------------------------------------------
+r3434 | pelissip | 2005-04-07 11:34:05 +0000 (Thu, 07 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tsi_op.c
+ M /trunk/tests/tsub_ui.c
+
+Improve test suite by adding new random values.
+
+------------------------------------------------------------------------
+r3433 | pelissip | 2005-04-07 07:44:14 +0000 (Thu, 07 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tsub.c
+
+Add random tests (tgeneric + random2).
+
+------------------------------------------------------------------------
+r3432 | vlefevre | 2005-04-05 09:03:29 +0000 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Test with -ansi when making a release.
+
+------------------------------------------------------------------------
+r3431 | vlefevre | 2005-04-05 08:57:29 +0000 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Typo.
+
+------------------------------------------------------------------------
+r3430 | zimmerma | 2005-04-05 07:11:53 +0000 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/div-short.c
+ M /trunk/tests/terf.c
+
+replaced // comments by /* ... */
+
+------------------------------------------------------------------------
+r3428 | pelissip | 2005-04-04 10:12:29 +0000 (Mon, 04 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Add note about mpfr_neg
+
+------------------------------------------------------------------------
+r3427 | pelissip | 2005-04-04 08:54:42 +0000 (Mon, 04 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/NEWS
+ M /trunk/TODO
+ A /trunk/atan2.c
+ M /trunk/mpfr.h
+ M /trunk/tests/tatan.c
+
+Add function mpfr_atan2
+
+------------------------------------------------------------------------
+r3426 | pelissip | 2005-03-31 16:13:11 +0000 (Thu, 31 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+ M /trunk/mpfr-gmp.h
+ M /trunk/mulders.c
+
+Change to add future function mpfr_sqrhigh_n.
+
+------------------------------------------------------------------------
+r3425 | pelissip | 2005-03-31 14:52:03 +0000 (Thu, 31 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add documentation for mpfr_erfc.
+
+------------------------------------------------------------------------
+r3424 | pelissip | 2005-03-31 13:26:32 +0000 (Thu, 31 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Add items.
+
+------------------------------------------------------------------------
+r3423 | pelissip | 2005-03-31 13:13:58 +0000 (Thu, 31 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/TODO
+ A /trunk/erfc.c
+ M /trunk/mpfr.h
+ M /trunk/tests/terf.c
+ M /trunk/tests/tgeneric.c
+
+Add function mpfr_erfc.
+Add a note about auto-checking correctness of MPFR.
+
+------------------------------------------------------------------------
+r3422 | vlefevre | 2005-03-30 14:49:03 +0000 (Wed, 30 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Added a testcase (the one added to the 2.1 branch).
+
+------------------------------------------------------------------------
+r3420 | pelissip | 2005-03-30 14:14:46 +0000 (Wed, 30 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Use random2 instead of random.
+
+------------------------------------------------------------------------
+r3419 | vlefevre | 2005-03-30 13:38:59 +0000 (Wed, 30 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/round_p.c
+
+Weaker conditions for return 0 in mpfr_round_p.
+
+------------------------------------------------------------------------
+r3418 | pelissip | 2005-03-30 13:13:20 +0000 (Wed, 30 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tgeneric.c
+ A /trunk/tests/tgeneric_ui.c
+ M /trunk/tests/tpow.c
+
+Add generic test for functions which looks
+ inexact = MPFR_TOTO (rop, op, INTEGER, RND);
+
+------------------------------------------------------------------------
+r3417 | pelissip | 2005-03-30 12:58:45 +0000 (Wed, 30 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+
+Add ceil(log2(size)) bits to initial precision to avoid
+commiting in error for huge operands.
+
+------------------------------------------------------------------------
+r3416 | vlefevre | 2005-03-30 12:21:53 +0000 (Wed, 30 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Added a test (corresp. to the one added on 2005-03-25 in tpow_z.c).
+
+------------------------------------------------------------------------
+r3415 | vlefevre | 2005-03-29 10:25:12 +0000 (Tue, 29 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+
+Reformatted code (GNU style, untabify...).
+
+------------------------------------------------------------------------
+r3414 | pelissip | 2005-03-29 08:42:07 +0000 (Tue, 29 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Tiny update.
+Add group functions macros.
+
+------------------------------------------------------------------------
+r3413 | pelissip | 2005-03-29 07:51:18 +0000 (Tue, 29 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/tests/tpow_z.c
+
+Replace test ('p <= i') by assertion ('p > i).
+
+------------------------------------------------------------------------
+r3412 | zimmerma | 2005-03-25 21:35:57 +0000 (Fri, 25 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/mpfr.texi
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tpow_z.c
+
+fixed bug in pow_ui (and pow_z): missing factor 2 in error bound
+fixed bug in gamma of negative integer
+
+------------------------------------------------------------------------
+r3411 | pelissip | 2005-03-25 15:03:13 +0000 (Fri, 25 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/div-short.c
+
+Add info.
+
+------------------------------------------------------------------------
+r3410 | pelissip | 2005-03-25 15:02:36 +0000 (Fri, 25 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/print_raw.c
+
+Add new internal function for debugging reasons.
+
+------------------------------------------------------------------------
+r3409 | pelissip | 2005-03-25 08:43:12 +0000 (Fri, 25 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow_z.c
+
+Forget to free x and y
+
+------------------------------------------------------------------------
+r3408 | pelissip | 2005-03-25 08:38:26 +0000 (Fri, 25 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow_z.c
+
+Add failed regression test.
+
+------------------------------------------------------------------------
+r3407 | pelissip | 2005-03-25 08:38:10 +0000 (Fri, 25 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/div-short.c
+
+Improved version.
+
+------------------------------------------------------------------------
+r3406 | pelissip | 2005-03-25 08:32:09 +0000 (Fri, 25 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+ M /trunk/tests/tmul.c
+
+Undo previous change (I was wrong).
+Add new regression test.
+
+------------------------------------------------------------------------
+r3405 | pelissip | 2005-03-24 10:47:41 +0000 (Thu, 24 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+
+Fix wrong extimated precision.
+It is log2(n+2) ulps so that log2(log2(n+2)) bits!
+
+------------------------------------------------------------------------
+r3404 | pelissip | 2005-03-24 10:01:31 +0000 (Thu, 24 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/div-short.c
+
+Add checking.
+
+------------------------------------------------------------------------
+r3403 | zimmerma | 2005-03-23 19:55:06 +0000 (Wed, 23 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added new test
+
+------------------------------------------------------------------------
+r3402 | pelissip | 2005-03-23 14:42:35 +0000 (Wed, 23 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_f.c
+
+Remove an signed integer trap overflow (GCC 4 + '-ftrapv').
+
+------------------------------------------------------------------------
+r3401 | pelissip | 2005-03-23 13:04:37 +0000 (Wed, 23 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Don't use Mulder at n+1 for MPFR_MUL_THRESHOLD+1
+
+------------------------------------------------------------------------
+r3400 | pelissip | 2005-03-23 13:03:55 +0000 (Wed, 23 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+Reduce the threshold for AMD64.
+
+------------------------------------------------------------------------
+r3399 | pelissip | 2005-03-22 13:58:19 +0000 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ A /trunk/div-short.c
+
+Initial version of Short Division.
+
+------------------------------------------------------------------------
+r3398 | pelissip | 2005-03-22 12:18:33 +0000 (Tue, 22 Mar 2005) | 4 lines
+Changed paths:
+ M /trunk/mul.c
+
+Fix bug on HP-UX.
+longlong's umul_ppmm seems to be buggy on such a system.
+Don't use it under HP-UX.
+
+------------------------------------------------------------------------
+r3396 | pelissip | 2005-03-21 10:34:12 +0000 (Mon, 21 Mar 2005) | 5 lines
+Changed paths:
+ M /trunk/mul.c
+ M /trunk/tests/tmul.c
+ M /trunk/tuneup.c
+
+Add case where bn == 1 and bn == 2 by using longlong.h.
+Modify tuneup to start with prec=2*BITS_PER_MP_LIMB+1
+Fix bug in computing the estimated precision when you switch from N limbs to N+1 limbs.
+Add regression tests.
+
+------------------------------------------------------------------------
+r3395 | vlefevre | 2005-03-19 01:27:54 +0000 (Sat, 19 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/isqrt.c
+
+Typo.
+
+------------------------------------------------------------------------
+r3394 | zimmerma | 2005-03-18 07:44:55 +0000 (Fri, 18 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one efficiency item
+
+------------------------------------------------------------------------
+r3393 | zimmerma | 2005-03-17 12:54:56 +0000 (Thu, 17 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added two property-tests
+
+------------------------------------------------------------------------
+r3391 | vlefevre | 2005-03-17 00:15:18 +0000 (Thu, 17 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/atanh.c
+ M /trunk/tests/tatanh.c
+
+Fixed a bug for mpfr_atanh(x) with 1 < |x| < 2 (found by Matt Reddick).
+
+------------------------------------------------------------------------
+r3390 | pelissip | 2005-03-14 10:07:14 +0000 (Mon, 14 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Update
+
+------------------------------------------------------------------------
+r3389 | pelissip | 2005-03-14 10:05:56 +0000 (Mon, 14 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tcan_round.c
+
+Improve test: compare between mpfr_round_p and mpfr_can_round.
+
+------------------------------------------------------------------------
+r3388 | pelissip | 2005-03-14 09:50:29 +0000 (Mon, 14 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/const_euler.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/erf.c
+ M /trunk/exp2.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/mul.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/sinh.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/zeta.c
+
+Replace mpfr_can_round (..., GMP_RNDN, GMP_RNDZ, ...) to fast replacement
+mpfr_round_p.
+
+------------------------------------------------------------------------
+r3387 | pelissip | 2005-03-14 09:49:36 +0000 (Mon, 14 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/round_prec.c
+
+Remove a FIXME.
+
+------------------------------------------------------------------------
+r3386 | pelissip | 2005-03-14 09:48:45 +0000 (Mon, 14 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr-impl.h
+ A /trunk/round_p.c
+
+Add new internal function mpfr_round_p which is a fast replacement
+to mpfr_can_round (x, y, GMP_RNDN, GMP_RNDZ, ...)
+
+------------------------------------------------------------------------
+r3385 | pelissip | 2005-03-14 09:47:44 +0000 (Mon, 14 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+Improve an error message.
+
+------------------------------------------------------------------------
+r3384 | pelissip | 2005-03-10 10:46:06 +0000 (Thu, 10 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+
+Fix bug: tmp may have changed in mulhigh code.
+Restore it before calling mpn_mul.
+
+------------------------------------------------------------------------
+r3383 | pelissip | 2005-03-09 15:53:12 +0000 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+Better defaults threshold.
+
+------------------------------------------------------------------------
+r3381 | pelissip | 2005-03-09 14:24:09 +0000 (Wed, 09 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+
+Handle case where Prec(a) ~ estimated prec of mulhigh.
+Add one extra limb, and still uses mulhigh.
+
+------------------------------------------------------------------------
+r3380 | pelissip | 2005-03-09 14:23:19 +0000 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tuneup.c
+
+Fix bug: compute Mulder Threshold from n/2+1 instead of (n+1)/2
+
+------------------------------------------------------------------------
+r3379 | pelissip | 2005-03-09 12:25:47 +0000 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Forget ';;' in switch.
+
+------------------------------------------------------------------------
+r3378 | pelissip | 2005-03-09 11:13:31 +0000 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Add '-v' for tuneup.
+
+------------------------------------------------------------------------
+r3377 | pelissip | 2005-03-09 11:10:56 +0000 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+ M /trunk/mulders.c
+
+Add assertion.
+
+------------------------------------------------------------------------
+r3376 | pelissip | 2005-03-09 10:49:38 +0000 (Wed, 09 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/mul.c
+ M /trunk/tests/tmul.c
+
+Improve checking
+Add test. Short Mulder product failed for this.
+
+------------------------------------------------------------------------
+r3375 | pelissip | 2005-03-09 10:20:51 +0000 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/mul.c
+ M /trunk/sub1sp.c
+
+Improve full assertion mode (Check mpfr_mul).
+
+------------------------------------------------------------------------
+r3373 | pelissip | 2005-03-08 16:06:36 +0000 (Tue, 08 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/logging.c
+ M /trunk/mpfr-impl.h
+
+Move GLIBC detection from mpfr-impl to logging.c
+
+------------------------------------------------------------------------
+r3372 | pelissip | 2005-03-08 16:06:18 +0000 (Tue, 08 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Add log info.
+
+------------------------------------------------------------------------
+r3371 | pelissip | 2005-03-08 16:06:01 +0000 (Tue, 08 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+Improve default threshold.
+
+------------------------------------------------------------------------
+r3370 | pelissip | 2005-03-08 14:32:09 +0000 (Tue, 08 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/mul.c
+ M /trunk/tuneup.c
+
+Add Mulder Short product for mpfr_mul.
+Update algorithm.tex to describe the estimated error.
+
+------------------------------------------------------------------------
+r3369 | pelissip | 2005-03-08 14:14:49 +0000 (Tue, 08 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/mulders.c
+
+Add an assert.
+Cosmetic change.
+
+------------------------------------------------------------------------
+r3368 | pelissip | 2005-03-08 14:14:08 +0000 (Tue, 08 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+Update default values.
+
+------------------------------------------------------------------------
+r3367 | pelissip | 2005-03-08 14:13:35 +0000 (Tue, 08 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Clean up macro namespace.
+
+------------------------------------------------------------------------
+r3366 | pelissip | 2005-03-08 14:13:07 +0000 (Tue, 08 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tsqrt.c
+
+Cosmetics change.
+
+------------------------------------------------------------------------
+r3365 | zimmerma | 2005-03-08 13:24:44 +0000 (Tue, 08 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/get_f.c
+ M /trunk/mpfr.h
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tget_f.c
+
+new function mpfr_get_f
+
+------------------------------------------------------------------------
+r3364 | pelissip | 2005-03-08 08:57:00 +0000 (Tue, 08 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/add1sp.c
+ M /trunk/tests/tadd1sp.c
+
+Fix bug in case of reuse of variable (a,b,a) with Exp(b)=Exp(a)+Prec(b).
+Move copy of mantissa after test.
+
+------------------------------------------------------------------------
+r3363 | pelissip | 2005-03-07 11:40:39 +0000 (Mon, 07 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/configure.in
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mulders.c
+ M /trunk/tuneup.c
+
+Add tune for mpfr_mulhigh
+Add --with-mulhigh-size option at configure time.
+
+------------------------------------------------------------------------
+r3362 | pelissip | 2005-03-04 17:40:53 +0000 (Fri, 04 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/exp_2.c
+ M /trunk/tests/texp.c
+
+Fix bug due to wrong estimation of (get_d (x) / LOG2).
+TODO: Rexamine the algorithm of mpfr_exp_2!
+
+------------------------------------------------------------------------
+r3361 | pelissip | 2005-03-04 17:32:13 +0000 (Fri, 04 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+Transform DEBUG message to LOG message.
+
+------------------------------------------------------------------------
+r3360 | pelissip | 2005-03-04 17:14:03 +0000 (Fri, 04 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mulders.c
+
+Improve it.
+
+------------------------------------------------------------------------
+r3359 | pelissip | 2005-03-04 17:13:42 +0000 (Fri, 04 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+ M /trunk/mparam_h.in
+ M /trunk/tuneup.c
+
+Tune mpfr_exp_2 now!
+
+------------------------------------------------------------------------
+r3358 | pelissip | 2005-03-03 14:59:25 +0000 (Thu, 03 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mulders.c
+
+Fix bugs.
+
+------------------------------------------------------------------------
+r3357 | pelissip | 2005-03-03 14:25:20 +0000 (Thu, 03 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/mulders.c
+
+Update it.
+New code for mpfr_mul.
+
+------------------------------------------------------------------------
+r3356 | pelissip | 2005-03-02 10:46:39 +0000 (Wed, 02 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/mparam_h.in
+
+Add new default threshold for different CPU.
+
+------------------------------------------------------------------------
+r3355 | pelissip | 2005-03-02 10:23:31 +0000 (Wed, 02 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Update for tune.
+
+------------------------------------------------------------------------
+r3354 | pelissip | 2005-03-02 08:57:26 +0000 (Wed, 02 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/tests/tatan.c
+
+Fix bug in estimated error (See previous ChangeLog).
+
+------------------------------------------------------------------------
+r3353 | pelissip | 2005-02-24 17:32:25 +0000 (Thu, 24 Feb 2005) | 6 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/configure.in
+ A /trunk/mparam_h.in
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/Makefile.am
+ A /trunk/tuneup.c
+
+Add tune program for MPFR.
+Do make tune instead of make.
+BUT you need to have configure MPFR with --with-gmp-build=...
+(It uses internal libspeed.la of GMP).
+Tuning is slow...
+
+------------------------------------------------------------------------
+r3352 | pelissip | 2005-02-24 17:08:27 +0000 (Thu, 24 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/mulders.c
+
+Add note.
+
+------------------------------------------------------------------------
+r3349 | pelissip | 2005-02-22 16:40:41 +0000 (Tue, 22 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/fits_s.h
+ M /trunk/fits_u.h
+
+Tiny optimization
+
+------------------------------------------------------------------------
+r3348 | pelissip | 2005-02-22 12:30:56 +0000 (Tue, 22 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Update
+
+------------------------------------------------------------------------
+r3347 | pelissip | 2005-02-22 12:12:18 +0000 (Tue, 22 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+
+Add logging.
+
+------------------------------------------------------------------------
+r3346 | pelissip | 2005-02-22 10:50:14 +0000 (Tue, 22 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/div_ui.c
+ M /trunk/mul_ui.c
+ M /trunk/si_op.c
+ M /trunk/ui_div.c
+
+Reduce InterObject dependency by moving mul_si, div_si and si_div
+to the unique function they used.
+Improve mul_ui by inlining the rounding.
+
+------------------------------------------------------------------------
+r3345 | pelissip | 2005-02-21 13:48:23 +0000 (Mon, 21 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+Improve test to 1.
+
+------------------------------------------------------------------------
+r3344 | vlefevre | 2005-02-21 13:08:46 +0000 (Mon, 21 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tsin.c
+
+Updated copyright lines.
+
+------------------------------------------------------------------------
+r3342 | vlefevre | 2005-02-21 12:13:00 +0000 (Mon, 21 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/sub_ui.c
+
+Code reindented / reformatted.
+
+------------------------------------------------------------------------
+r3341 | vlefevre | 2005-02-21 12:09:47 +0000 (Mon, 21 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/tests/tui_sub.c
+ M /trunk/ui_sub.c
+
+Fixed a bug for u == 0 and x == +0 introduced in ui_sub.c 1.23,
+when 0 was taken into account as a special case: the sign of the
+result 0 was incorrect. -> Consider the case u == 0 first.
+
+------------------------------------------------------------------------
+r3340 | zimmerma | 2005-02-19 22:04:01 +0000 (Sat, 19 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/RRTest.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tsin.c
+
+added generic tests in tpow
+
+------------------------------------------------------------------------
+r3339 | zimmerma | 2005-02-18 22:09:19 +0000 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+ M /trunk/tests/tsqrt.c
+
+fixed bug (variable used twice for different things)
+
+------------------------------------------------------------------------
+r3338 | zimmerma | 2005-02-18 20:19:44 +0000 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+ M /trunk/mpfr-test.h
+ M /trunk/tests/RRTest.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+
+more changes for interface with NTL
+
+------------------------------------------------------------------------
+r3337 | pelissip | 2005-02-18 16:33:39 +0000 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/round_prec.c
+
+Likely a test.
+
+------------------------------------------------------------------------
+r3336 | pelissip | 2005-02-18 16:33:25 +0000 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/mulders.c
+
+Update
+
+------------------------------------------------------------------------
+r3335 | zimmerma | 2005-02-18 15:28:25 +0000 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ A /trunk/tests/RRTest.c
+ M /trunk/tests/tadd.c
+
+added interface for NTL
+
+------------------------------------------------------------------------
+r3334 | vlefevre | 2005-02-16 17:08:25 +0000 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3333 | vlefevre | 2005-02-16 17:05:19 +0000 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Suppress some spaces.
+
+------------------------------------------------------------------------
+r3332 | pelissip | 2005-02-16 16:04:54 +0000 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Reenable underflow tests.
+
+------------------------------------------------------------------------
+r3331 | pelissip | 2005-02-16 15:58:48 +0000 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Update
+
+------------------------------------------------------------------------
+r3330 | vlefevre | 2005-02-16 13:27:24 +0000 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ D /trunk/texinfo.tex
+
+Removed texinfo.tex, as it can be installed by autoreconf -i.
+
+------------------------------------------------------------------------
+r3329 | pelissip | 2005-02-16 13:19:25 +0000 (Wed, 16 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+Fix LOADLIBES so that it works (it doesn't due to libtool change). But it
+still needs to have s static version of MPFR.
+
+------------------------------------------------------------------------
+r3328 | vlefevre | 2005-02-16 12:54:27 +0000 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+autoreconf -> autoreconf -i
+
+------------------------------------------------------------------------
+r3327 | pelissip | 2005-02-16 12:49:40 +0000 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asinh.c
+ M /trunk/exp3.c
+ M /trunk/mpfr-impl.h
+ M /trunk/sin_cos.c
+ M /trunk/tan.c
+
+Fix wrong integer types.
+
+------------------------------------------------------------------------
+r3324 | vlefevre | 2005-02-16 11:03:35 +0000 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+ M /trunk/mul.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+
+Spelling mistakes & reformatted code.
+
+------------------------------------------------------------------------
+r3322 | vlefevre | 2005-02-15 16:28:31 +0000 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/sub1.c
+
+Reformatted code.
+
+------------------------------------------------------------------------
+r3321 | pelissip | 2005-02-15 14:56:00 +0000 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/tanh.c
+
+Improve initial prec.
+
+------------------------------------------------------------------------
+r3319 | pelissip | 2005-02-15 14:52:06 +0000 (Tue, 15 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/tanh.c
+
+Remove code.
+Add special case if t=1.
+
+------------------------------------------------------------------------
+r3318 | pelissip | 2005-02-15 14:51:51 +0000 (Tue, 15 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/sub1.c
+
+mpfr_set doesn't produce an EVEN inexact flag.
+Fix this.
+
+------------------------------------------------------------------------
+r3317 | pelissip | 2005-02-15 14:51:23 +0000 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+USe of mpfr_nexttozero.
+
+------------------------------------------------------------------------
+r3316 | pelissip | 2005-02-15 14:32:16 +0000 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/atanh.c
+
+Fix bug: use x instead of xf in LOG.
+
+------------------------------------------------------------------------
+r3315 | pelissip | 2005-02-15 10:29:31 +0000 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cosh.c
+ M /trunk/erf.c
+ M /trunk/exp.c
+ M /trunk/gamma.c
+ M /trunk/log.c
+ M /trunk/pow.c
+ M /trunk/sinh.c
+ M /trunk/tanh.c
+ M /trunk/zeta.c
+
+Log input and ouput of functions.
+
+------------------------------------------------------------------------
+r3314 | pelissip | 2005-02-15 10:06:39 +0000 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/tan.c
+
+Fix bug of overflow in tan.
+
+------------------------------------------------------------------------
+r3313 | pelissip | 2005-02-15 09:54:23 +0000 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/tan.c
+
+Use of MPFR_LOG_FUNC.
+
+------------------------------------------------------------------------
+r3312 | pelissip | 2005-02-15 09:53:44 +0000 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Do not print final log message if there was no call.
+
+------------------------------------------------------------------------
+r3311 | pelissip | 2005-02-15 09:39:57 +0000 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+Add ZivLoop for sign
+
+------------------------------------------------------------------------
+r3310 | pelissip | 2005-02-14 16:02:59 +0000 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/logging.c
+
+Fix bug: during the display of a logged var, logging is turn off.
+
+------------------------------------------------------------------------
+r3309 | pelissip | 2005-02-14 15:55:12 +0000 (Mon, 14 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/mpfr-impl.h
+
+Add MPFR_LOG_FUNC
+Use mpfr_cos as testing example.
+
+------------------------------------------------------------------------
+r3308 | pelissip | 2005-02-14 14:38:06 +0000 (Mon, 14 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/cache.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+
+Add ZivLoop controller for constantes.
+Augment exponent range in the cache.
+Remove it in const_pi.
+
+------------------------------------------------------------------------
+r3307 | pelissip | 2005-02-14 14:23:13 +0000 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+Add generic ZivLoop controller.
+
+------------------------------------------------------------------------
+r3306 | fousse | 2005-02-14 14:21:50 +0000 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Document mpfr_sum returned int value.
+
+------------------------------------------------------------------------
+r3305 | pelissip | 2005-02-14 14:18:40 +0000 (Mon, 14 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/strtofr.c
+ M /trunk/sum.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/zeta.c
+
+Clean up code.
+Add generic ZivLoop controller.
+
+------------------------------------------------------------------------
+r3303 | fousse | 2005-02-14 13:33:31 +0000 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/sum.c
+
+Consider return value's precision for rounding in mpfr_sum.
+
+------------------------------------------------------------------------
+r3302 | zimmerma | 2005-02-14 12:41:16 +0000 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+
+removed garbage
+
+------------------------------------------------------------------------
+r3301 | pelissip | 2005-02-14 11:26:45 +0000 (Mon, 14 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/expm1.c
+ M /trunk/factorial.c
+ M /trunk/gamma.c
+ M /trunk/hypot.c
+
+Clean up
+Add ZivLoop
+
+------------------------------------------------------------------------
+r3300 | pelissip | 2005-02-14 10:55:09 +0000 (Mon, 14 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/const_log2.c
+
+Remove malloc/free.
+Use of MPFR_INT_CEIL_LOG2
+Add ZivLoop controller.
+
+------------------------------------------------------------------------
+r3299 | pelissip | 2005-02-14 10:54:42 +0000 (Mon, 14 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/erf.c
+
+Clean up code.
+Fix bug with Exponent range.
+Add ZivLoop controller.
+
+------------------------------------------------------------------------
+r3298 | pelissip | 2005-02-14 10:54:06 +0000 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/cbrt.c
+
+Cleanup code.
+
+------------------------------------------------------------------------
+r3297 | zimmerma | 2005-02-14 10:38:04 +0000 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/const_log2.c
+
+further efficiency improvement (avoid mpz_init/mpz_clear)
+
+------------------------------------------------------------------------
+r3296 | pelissip | 2005-02-14 10:11:17 +0000 (Mon, 14 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/asinh.c
+ M /trunk/atanh.c
+
+Add ZivLoop controller.
+Clean up code.
+Optimize it by removing the # of used vars.
+
+------------------------------------------------------------------------
+r3295 | pelissip | 2005-02-14 10:10:51 +0000 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/asin.c
+ M /trunk/atan.c
+
+Add ZivLoop controler.
+
+------------------------------------------------------------------------
+r3294 | zimmerma | 2005-02-12 16:01:39 +0000 (Sat, 12 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/const_log2.c
+ M /trunk/mpfr-impl.h
+
+new faster algorithm for log(2)
+
+------------------------------------------------------------------------
+r3293 | pelissip | 2005-02-11 13:08:25 +0000 (Fri, 11 Feb 2005) | 6 lines
+Changed paths:
+ M /trunk/configure.in
+
+Remove detection of C++ and Fortran due to libtool.
+----
+Note (VL, 2010-02-08): this removal by an always false test was working
+with libtool 1.5.26, but doesn't work with libtool 2.2 to 2.2.6b (used
+by the MPFR 2.4.{0,1,2} tarballs).
+http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=568520
+------------------------------------------------------------------------
+r3292 | pelissip | 2005-02-11 11:28:00 +0000 (Fri, 11 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/configure.in
+ M /trunk/tests/Makefile.am
+
+Clean up configure (more simplier).
+Still a bug with CXXCPP to solve.
+
+------------------------------------------------------------------------
+r3291 | pelissip | 2005-02-11 11:27:36 +0000 (Fri, 11 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/const_log2.c
+ M /trunk/mpfr-impl.h
+
+Clean up const_log2 code.
+
+------------------------------------------------------------------------
+r3290 | pelissip | 2005-02-10 15:43:41 +0000 (Thu, 10 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/cosh.c
+ M /trunk/exp.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/log.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+
+Add log for other functions.
+Add ZivLoop too.
+Cleanup exp3.
+
+------------------------------------------------------------------------
+r3289 | pelissip | 2005-02-09 16:24:18 +0000 (Wed, 09 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Update for ICC (disable shared since it doesn't work).
+
+------------------------------------------------------------------------
+r3288 | pelissip | 2005-02-09 15:05:45 +0000 (Wed, 09 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+The previous fixs don't work. New one which works but is VERY ugly.
+
+------------------------------------------------------------------------
+r3287 | pelissip | 2005-02-09 14:26:29 +0000 (Wed, 09 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Fix again to avoid fail on laurent5...
+
+------------------------------------------------------------------------
+r3286 | pelissip | 2005-02-09 14:21:48 +0000 (Wed, 09 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Set CXXCPP to "g++ -E" to avoid detection (which may fail on some systems).
+
+------------------------------------------------------------------------
+r3285 | pelissip | 2005-02-09 14:11:13 +0000 (Wed, 09 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Reduce the tested compiler for C++ and Fortran to the minimum.
+
+------------------------------------------------------------------------
+r3284 | pelissip | 2005-02-09 13:19:17 +0000 (Wed, 09 Feb 2005) | 6 lines
+Changed paths:
+ M /trunk/configure.in
+
+Update GMP detection to be much more libtool compatible.
+As a consequence some tests using AC_RUN_IFELSE may fail due to ugly things
+like LD_LIBRARY_PATH no set or wrong selection of libgmp.
+So they just produce a warning, not a fatal error.
+TODO: Check if we can avoid thoses problems...
+
+------------------------------------------------------------------------
+r3283 | pelissip | 2005-02-08 15:49:12 +0000 (Tue, 08 Feb 2005) | 3 lines
+Changed paths:
+ D /trunk/ansi2knr.1
+ D /trunk/ansi2knr.c
+ D /trunk/config.guess
+ D /trunk/config.sub
+ D /trunk/depcomp
+ D /trunk/install-sh
+ D /trunk/missing
+ D /trunk/mkinstalldirs
+ M /trunk/prepare
+
+Remove automake and libtool files.
+Use `automake --add-missing --copy -i` to generate them.
+
+------------------------------------------------------------------------
+r3282 | pelissip | 2005-02-08 13:57:04 +0000 (Tue, 08 Feb 2005) | 2 lines
+Changed paths:
+ A /trunk/ansi2knr.1
+ A /trunk/ansi2knr.c
+
+Add support for ansi2knr
+
+------------------------------------------------------------------------
+r3281 | pelissip | 2005-02-08 13:54:10 +0000 (Tue, 08 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/README.dev
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/prepare
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tests.c
+ M /trunk/update-version
+
+Add support for Shared Library in MPFR (both Unix and Windows) by using libtool.
+Improve configure (remove unused macros, make dist produce .zip and .bz2)
+Update update-version to modify configure.in too.
+
+------------------------------------------------------------------------
+r3280 | pelissip | 2005-02-08 13:51:09 +0000 (Tue, 08 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Update NEWS.
+
+------------------------------------------------------------------------
+r3279 | vlefevre | 2005-02-04 12:15:25 +0000 (Fri, 04 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3278 | pelissip | 2005-02-04 10:25:10 +0000 (Fri, 04 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+Add forgotten functions to reuse test.
+
+------------------------------------------------------------------------
+r3277 | pelissip | 2005-02-04 10:10:37 +0000 (Fri, 04 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+Improve reuse tests (Include 1, -1, 1/2, 2, PI and PI/2 now).
+
+------------------------------------------------------------------------
+r3276 | pelissip | 2005-02-04 09:14:37 +0000 (Fri, 04 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/tests/tatan.c
+
+Fix bug of atan(-1) (wrong sign).
+
+------------------------------------------------------------------------
+r3275 | pelissip | 2005-02-03 16:03:50 +0000 (Thu, 03 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Remove unused option --disable-cache.
+
+------------------------------------------------------------------------
+r3274 | pelissip | 2005-02-03 15:59:28 +0000 (Thu, 03 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/exceptions.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_rnd.c
+
+Add option "thread-safe" to configure.
+Limited to use with GCC and ICC (using extension __thread).
+
+------------------------------------------------------------------------
+r3273 | pelissip | 2005-02-03 15:18:17 +0000 (Thu, 03 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add description of added functions.
+
+------------------------------------------------------------------------
+r3272 | pelissip | 2005-02-03 15:09:51 +0000 (Thu, 03 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+mpfr.h doesn't export anymore any globals.
+It doesn't define MPFR_FLAGS too.
+
+------------------------------------------------------------------------
+r3271 | pelissip | 2005-02-03 14:59:39 +0000 (Thu, 03 Feb 2005) | 7 lines
+Changed paths:
+ M /trunk/cache.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+Change user interface for mpfr_const_pi, mpfr_const_log2 and
+mpfr_const_euler. No more access to the cache itself.
+Create dummy functions which call the cache, and rename old
+functions to "_internal".
+Internally, it doesn't change at all (You still call directly
+the cache instead of the dummy function which calls the cache).
+
+------------------------------------------------------------------------
+r3270 | pelissip | 2005-02-03 14:43:20 +0000 (Thu, 03 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/exceptions.c
+ M /trunk/mpfr.h
+ M /trunk/tests/texceptions.c
+
+Add functions mpfr_set_overflow, mpfr_set_underflow, mpfr_set_erangeflag,
+mpfr_set_inexflag, mpfr_set_nanflag
+
+------------------------------------------------------------------------
+r3269 | pelissip | 2005-02-03 14:33:31 +0000 (Thu, 03 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/add1sp.c
+ M /trunk/add_one_ulp.c
+ M /trunk/cache.c
+ M /trunk/div.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/pow.c
+ M /trunk/pow_ui.c
+ M /trunk/pow_z.c
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/set.c
+ M /trunk/set_q.c
+ M /trunk/set_si.c
+ M /trunk/set_sj.c
+ M /trunk/set_ui.c
+ M /trunk/set_uj.c
+ M /trunk/set_z.c
+ M /trunk/sqr.c
+ M /trunk/strtofr.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/tests/texceptions.c
+
+Rename internal functions mpfr_set_overflow in mpfr_overflow and
+ mpfr_set_underflow in mpfr_underflow so that we can add new functions
+mpfr_set_underflow and mpfr_set_overflow (which set the global flags).
+
+------------------------------------------------------------------------
+r3268 | pelissip | 2005-02-03 12:46:18 +0000 (Thu, 03 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/sin.c
+
+Add support for logging.
+Add support for ZivLoop.
+Improve efficiency if prec(op) >> prec(rop), and rop ~= 0
+
+------------------------------------------------------------------------
+r3267 | pelissip | 2005-02-03 12:44:51 +0000 (Thu, 03 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Fix wrong place for MPFR_LOG_BEGIN.
+
+------------------------------------------------------------------------
+r3266 | pelissip | 2005-02-03 12:44:15 +0000 (Thu, 03 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/logging.c
+
+Rename MPFR_LOG_BADCASE in MPFR_LOG_ZIV
+
+------------------------------------------------------------------------
+r3265 | pelissip | 2005-02-03 12:43:44 +0000 (Thu, 03 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Reduce the size of some lines (more than 80 chars).
+
+------------------------------------------------------------------------
+r3264 | pelissip | 2005-02-02 16:30:05 +0000 (Wed, 02 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/mpf_compat.h
+
+Fix again. My previous fix was incorrect.
+
+------------------------------------------------------------------------
+r3262 | pelissip | 2005-02-02 15:55:38 +0000 (Wed, 02 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/logging.c
+
+Fix wrong order of include system files.
+(printf.h is not available everywhere).
+
+------------------------------------------------------------------------
+r3261 | zimmerma | 2005-02-02 15:50:51 +0000 (Wed, 02 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+inexact flag was inexact :-)
+
+------------------------------------------------------------------------
+r3260 | pelissip | 2005-02-02 15:49:20 +0000 (Wed, 02 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/next.c
+ M /trunk/sin.c
+ M /trunk/sub1.c
+
+Move mpfr_nexttozero and mpfr_nexttoinf from static to mpfr-impl.
+Use them in sub1 and sin.
+
+------------------------------------------------------------------------
+r3259 | pelissip | 2005-02-02 14:58:36 +0000 (Wed, 02 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/README.dev
+ A /trunk/logging.c
+
+Add forgotten logging file.
+Add description of new macros in README.dev
+
+------------------------------------------------------------------------
+r3258 | pelissip | 2005-02-02 14:14:01 +0000 (Wed, 02 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/tests/tcos.c
+
+Add support for ZivLoop controler and logging.
+
+------------------------------------------------------------------------
+r3257 | pelissip | 2005-02-02 14:13:39 +0000 (Wed, 02 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/configure.in
+ M /trunk/mpfr-impl.h
+
+Add experimental logging feature.
+Add ZivLoop controler.
+
+------------------------------------------------------------------------
+r3256 | pelissip | 2005-02-02 14:09:18 +0000 (Wed, 02 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/tests/mpf_compat.h
+
+Forget that mpf doesn't have mpf_free_str.
+Fix this.
+
+------------------------------------------------------------------------
+r3255 | pelissip | 2005-02-02 13:50:45 +0000 (Wed, 02 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/sub1.c
+ M /trunk/tests/tsin.c
+
+Fix bug of sub1 if dest=src2 and src1 >> src2
+=> Fix problem of mpfr_sin
+
+------------------------------------------------------------------------
+r3254 | zimmerma | 2005-02-02 13:45:48 +0000 (Wed, 02 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tui_sub.c
+
+added two tests
+
+------------------------------------------------------------------------
+r3253 | pelissip | 2005-02-01 14:50:19 +0000 (Tue, 01 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Now MPFR tries to get GMP's CC and CFLAGS from its build directory.
+
+------------------------------------------------------------------------
+r3252 | pelissip | 2005-02-01 09:58:43 +0000 (Tue, 01 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+
+Add AC_COPYRIGHT
+Clean up AC_ARG_ENABLE handling
+Add `--enable-logging` option.
+
+------------------------------------------------------------------------
+r3251 | zimmerma | 2005-01-31 09:37:09 +0000 (Mon, 31 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item
+
+------------------------------------------------------------------------
+r3250 | pelissip | 2005-01-31 08:47:04 +0000 (Mon, 31 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+Fix a wrong assertion when double == long double.
+
+------------------------------------------------------------------------
+r3249 | pelissip | 2005-01-31 08:44:16 +0000 (Mon, 31 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/sin.c
+
+Add loop counter
+Check if the result is 0 (Due to new algorithm, it may be 0)
+and in that case, increase a lot the precision.
+
+------------------------------------------------------------------------
+r3248 | zimmerma | 2005-01-29 20:40:51 +0000 (Sat, 29 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/sin.c
+
+changed algorithm for mpfr_sin (to get inexact flag)
+
+------------------------------------------------------------------------
+r3246 | vlefevre | 2005-01-29 11:32:17 +0000 (Sat, 29 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/tests/texp.c
+
+Fixed a sign bug in mpfr_exp (found by Mark J Watkins).
+
+------------------------------------------------------------------------
+r3245 | zimmerma | 2005-01-28 16:57:22 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+solved efficiency problem in mpfr_sin_sign for x near Pi
+
+------------------------------------------------------------------------
+r3243 | vlefevre | 2005-01-28 14:22:34 +0000 (Fri, 28 Jan 2005) | 3 lines
+Changed paths:
+ D /trunk/tests/tdump.c
+
+Removed tests/tdump.c (was no longer used and mpfr_dump is already
+tested in toutimpl.c).
+
+------------------------------------------------------------------------
+r3242 | vlefevre | 2005-01-28 14:20:09 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+Updated copyright line.
+
+------------------------------------------------------------------------
+r3240 | pelissip | 2005-01-28 13:49:30 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Clean up code (due to mix with Paul changes).
+
+------------------------------------------------------------------------
+r3239 | pelissip | 2005-01-28 13:43:11 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+Improve inexact code since sin & cos can't be exact if x != 0
+
+------------------------------------------------------------------------
+r3238 | vlefevre | 2005-01-28 13:28:30 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Removed a useless test in macro MPFR_UNSIGNED_MINUS_MODULO.
+
+------------------------------------------------------------------------
+r3237 | pelissip | 2005-01-28 13:10:04 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+
+Much faster worst case (ie result near 0 or 1).
+
+------------------------------------------------------------------------
+r3236 | zimmerma | 2005-01-28 13:08:20 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+speed-up special case where approximation is 1 or -1
+
+------------------------------------------------------------------------
+r3235 | vlefevre | 2005-01-28 13:04:10 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/rint.c
+
+Updated comments about the rounding modes.
+
+------------------------------------------------------------------------
+r3234 | pelissip | 2005-01-28 12:23:55 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/reldiff.c
+
+Fix bug and optimize code.
+
+------------------------------------------------------------------------
+r3233 | pelissip | 2005-01-28 11:00:34 +0000 (Fri, 28 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/get_str.c
+
+FIx a warning (Wrong proto between declaration and implementation :
+ forget some const).
+
+------------------------------------------------------------------------
+r3232 | vlefevre | 2005-01-28 10:58:01 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Updated copyright line.
+
+------------------------------------------------------------------------
+r3231 | vlefevre | 2005-01-28 10:56:19 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/cmp_si.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/div.c
+ M /trunk/erf.c
+ M /trunk/exp_2.c
+ M /trunk/get_d.c
+ M /trunk/get_ld.c
+ M /trunk/get_str.c
+ M /trunk/get_z_exp.c
+ M /trunk/mpfr.h
+ M /trunk/mpn_exp.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/rint.c
+ M /trunk/set_str.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr_compat.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tzeta.c
+
+Updated copyright lines.
+
+------------------------------------------------------------------------
+r3230 | zimmerma | 2005-01-28 10:43:30 +0000 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+fixed efficiency problem in case of cos(Pi)
+
+------------------------------------------------------------------------
+r3229 | pelissip | 2005-01-28 09:58:28 +0000 (Fri, 28 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/rint.c
+ M /trunk/tests/trint.c
+
+Fix bug if dest==src.
+Transform some MPFR_ASSERTN to MPFR_ASSERTD.
+
+------------------------------------------------------------------------
+r3227 | pelissip | 2005-01-27 16:02:23 +0000 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+Fix a buffer overflow.
+
+------------------------------------------------------------------------
+r3226 | pelissip | 2005-01-27 15:40:39 +0000 (Thu, 27 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/get_ld.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set_ld.c
+ M /trunk/tests/tset_ld.c
+
+New version of mpfr_set_ld and mpfr_get_ld for IEEE Extended Little Endian.
+(Due to problem on x86 with extended precision).
+
+------------------------------------------------------------------------
+r3225 | zimmerma | 2005-01-27 13:58:24 +0000 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/mpf_compat.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/mpfr_compat.c
+
+partially fixed memory leak
+
+------------------------------------------------------------------------
+r3224 | zimmerma | 2005-01-27 13:40:13 +0000 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+test for huge cancellation was misplaced
+
+------------------------------------------------------------------------
+r3223 | zimmerma | 2005-01-27 13:28:49 +0000 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tsum.c
+
+fixed memory leak
+
+------------------------------------------------------------------------
+r3222 | zimmerma | 2005-01-27 12:53:45 +0000 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+fixed inefficiency problem for x near from Pi
+
+------------------------------------------------------------------------
+r3221 | zimmerma | 2005-01-27 10:56:44 +0000 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmpabs.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/toutimpl.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tpow_z.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsqr.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsum.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tzeta.c
+
+casts to allow compilation with g++
+
+------------------------------------------------------------------------
+r3220 | zimmerma | 2005-01-27 09:35:41 +0000 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+added missing cast
+
+------------------------------------------------------------------------
+r3219 | zimmerma | 2005-01-27 09:28:29 +0000 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+added missing casts
+
+------------------------------------------------------------------------
+r3218 | zimmerma | 2005-01-25 18:23:38 +0000 (Tue, 25 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+fixed bug (overlap in mpn_divrem)
+
+------------------------------------------------------------------------
+r3217 | vlefevre | 2005-01-24 16:23:29 +0000 (Mon, 24 Jan 2005) | 2 lines
+Changed paths:
+ D /trunk/tests/Makefile.in
+
+Removed tests/Makefile.in from CVS.
+
+------------------------------------------------------------------------
+r3216 | pelissip | 2005-01-24 15:48:34 +0000 (Mon, 24 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+
+Fix bug reported by Eric Buchlin by using new function
+mpfr_pow_z.
+
+------------------------------------------------------------------------
+r3215 | pelissip | 2005-01-24 15:36:49 +0000 (Mon, 24 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ A /trunk/pow_z.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tpow_z.c
+
+Add new function mpfr_pow_z and its test file.
+
+------------------------------------------------------------------------
+r3214 | pelissip | 2005-01-24 15:35:08 +0000 (Mon, 24 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/tests/tpow.c
+
+Fix overflows problems.
+Clean up overflow handling.
+Maybe some bugs remain...
+
+------------------------------------------------------------------------
+r3213 | vlefevre | 2005-01-24 15:04:05 +0000 (Mon, 24 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3212 | pelissip | 2005-01-24 14:19:20 +0000 (Mon, 24 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+Add an explicit reference to mpfr_dump so that
+you can use this function inside the tests with GDB, even if
+you don't use it in the tests.
+
+------------------------------------------------------------------------
+r3211 | zimmerma | 2005-01-24 13:45:38 +0000 (Mon, 24 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+added check before mpz_get_si() call
+
+------------------------------------------------------------------------
+r3210 | vlefevre | 2005-01-24 10:43:16 +0000 (Mon, 24 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Update.
+
+------------------------------------------------------------------------
+r3209 | vlefevre | 2005-01-24 10:31:26 +0000 (Mon, 24 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Corrections on the typography.
+
+------------------------------------------------------------------------
+r3208 | vlefevre | 2005-01-24 10:16:51 +0000 (Mon, 24 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Corrected English usage.
+
+------------------------------------------------------------------------
+r3207 | vlefevre | 2005-01-24 00:03:59 +0000 (Mon, 24 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Typos.
+
+------------------------------------------------------------------------
+r3206 | zimmerma | 2005-01-21 12:20:54 +0000 (Fri, 21 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added LOADLIBES=...
+
+------------------------------------------------------------------------
+r3201 | vlefevre | 2005-01-21 10:20:17 +0000 (Fri, 21 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/sum.c
+
+Updated Copyright line.
+
+------------------------------------------------------------------------
+r3195 | pelissip | 2005-01-20 14:32:20 +0000 (Thu, 20 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/sub1.c
+
+Fix again this previous patch!
+
+------------------------------------------------------------------------
+r3194 | zimmerma | 2005-01-20 11:23:51 +0000 (Thu, 20 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpn_exp.c
+
+fixed problems in get_str for huge exponent
+
+------------------------------------------------------------------------
+r3193 | pelissip | 2005-01-20 09:53:45 +0000 (Thu, 20 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-longlong.h
+
+Update longlong from GMP 4.1.4 (problem with opteron).
+
+------------------------------------------------------------------------
+r3192 | pelissip | 2005-01-18 13:30:50 +0000 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/sum.c
+
+Fix bug in case n==0 or n==1 (Reported and fixed by Laurent Fousse).
+
+------------------------------------------------------------------------
+r3191 | pelissip | 2005-01-14 15:02:15 +0000 (Fri, 14 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/sub1.c
+
+Add comments
+Fix bug in my patch (Need tests).
+
+------------------------------------------------------------------------
+r3190 | pelissip | 2005-01-14 13:50:09 +0000 (Fri, 14 Jan 2005) | 7 lines
+Changed paths:
+ M /trunk/atan.c
+
+Optimize mpfr_atan_aux by removing all power of 2 in the sum to
+reduce the size of the multiplication, normalize the input to extract
+as many zeros as possible and add a special case if the input is 1
+(after normalisation). But it doesn't optimize too much...
+I need to invertigate a few more too understand what is still costly.
+It seems that mpz_mul is the most called function.
+
+------------------------------------------------------------------------
+r3189 | pelissip | 2005-01-14 13:28:45 +0000 (Fri, 14 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/tanh.c
+
+Improve and fix tanh for big floats.
+
+------------------------------------------------------------------------
+r3188 | pelissip | 2005-01-14 13:28:03 +0000 (Fri, 14 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/sub1.c
+
+Fix bug in some corner case (Just hope it doesn't add new bugs).
+It should be much faster in these cases too.
+
+------------------------------------------------------------------------
+r3187 | pelissip | 2005-01-14 13:26:55 +0000 (Fri, 14 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+
+Remove warning
+
+------------------------------------------------------------------------
+r3186 | pelissip | 2005-01-14 11:40:22 +0000 (Fri, 14 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Tiny update
+
+------------------------------------------------------------------------
+r3185 | pelissip | 2005-01-14 08:20:35 +0000 (Fri, 14 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+
+Fix bug (Forget a debug line).
+
+------------------------------------------------------------------------
+r3184 | pelissip | 2005-01-13 16:21:47 +0000 (Thu, 13 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/sinh.c
+
+Fix overflow bug
+Optimize code
+
+------------------------------------------------------------------------
+r3183 | pelissip | 2005-01-13 08:22:09 +0000 (Thu, 13 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Fix bug in mpn_sub_nc in case the compiler optimize too much.
+
+------------------------------------------------------------------------
+r3182 | pelissip | 2005-01-12 10:00:52 +0000 (Wed, 12 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+
+Add forgotten 2005 copyright line.
+
+------------------------------------------------------------------------
+r3181 | pelissip | 2005-01-12 09:57:57 +0000 (Wed, 12 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+
+Fix problem of `mpn_sub_nc' which may or may not be defined in libgmp.a
+ (Add a test in the configure and a new macro MPFR_HAVE_MPN_SUB_NC)
+Add MPFR_LOG2_BIT_PER_MP_LIMB macro
+
+------------------------------------------------------------------------
+r3180 | pelissip | 2005-01-12 09:22:37 +0000 (Wed, 12 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/atan.c
+
+Massive optimization of mpfr_atan (20x faster than 2.1.0 at 53 bits!)
+Minor optimization of mpfr_acos
+
+------------------------------------------------------------------------
+r3179 | pelissip | 2005-01-11 16:27:42 +0000 (Tue, 11 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/mulders.c
+
+Fix typo
+
+------------------------------------------------------------------------
+r3178 | pelissip | 2005-01-11 08:42:16 +0000 (Tue, 11 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/gmp_op.c
+
+Reduce size of code
+Optimize a few too.
+
+------------------------------------------------------------------------
+r3177 | pelissip | 2005-01-11 08:40:51 +0000 (Tue, 11 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Forget 2005 !
+
+------------------------------------------------------------------------
+r3176 | pelissip | 2005-01-11 08:39:49 +0000 (Tue, 11 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Improve and fix detection of NAN and GCC bug.
+
+------------------------------------------------------------------------
+r3175 | pelissip | 2005-01-04 15:04:18 +0000 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+
+new version (completely rewritten) by Paul Zimmermann.
+
+------------------------------------------------------------------------
+r3174 | pelissip | 2005-01-04 14:52:28 +0000 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/tests/tatan.c
+
+Fix forgotten '2005' Line.
+
+------------------------------------------------------------------------
+r3173 | pelissip | 2005-01-04 14:41:09 +0000 (Tue, 04 Jan 2005) | 5 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/tests/tatan.c
+
+Fix wrong inexact value (regression).
+FIXME: It seems that adding MPFR_GET_EXP (xp) bits is too much
+ (since previously it always add 0, but the results were quite
+ always exact - this bug was only discovered under rare case).
+
+------------------------------------------------------------------------
+r3172 | zimmerma | 2005-01-04 12:23:41 +0000 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item (mpfr_printf)
+
+------------------------------------------------------------------------
+r3171 | pelissip | 2005-01-04 10:34:17 +0000 (Tue, 04 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/exp_2.c
+ M /trunk/mpfr-impl.h
+
+Optimize mpfr_exp2 by inlining some code, and by avoiding using
+mpz_sizeinbase.
+
+------------------------------------------------------------------------
+r3170 | pelissip | 2005-01-04 10:33:18 +0000 (Tue, 04 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/erf.c
+
+Remove unused code.
+Remove _MPFR_PROTO for static functions.
+Other cosmetic change.
+
+------------------------------------------------------------------------
+r3169 | pelissip | 2005-01-04 10:32:01 +0000 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/get_str.c
+
+Remove _MPFR_PROTO for static functions.
+
+------------------------------------------------------------------------
+r3168 | pelissip | 2005-01-04 10:29:14 +0000 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Remove unused code.
+
+------------------------------------------------------------------------
+r3167 | pelissip | 2005-01-04 10:28:41 +0000 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+
+Optimize mpfr_get_d.
+
+------------------------------------------------------------------------
+r3166 | pelissip | 2005-01-04 10:28:03 +0000 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Add a new configuration to check before releasing MPFR.
+
+------------------------------------------------------------------------
+r3165 | pelissip | 2005-01-04 10:26:44 +0000 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/sum.c
+
+Fix problem of tab with ncurses.
+
+------------------------------------------------------------------------
+r3164 | pelissip | 2005-01-04 10:26:14 +0000 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/cmp_si.c
+ M /trunk/get_z_exp.c
+
+Likely some tests
+
+------------------------------------------------------------------------
+r3163 | pelissip | 2005-01-04 10:25:40 +0000 (Tue, 04 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+
+Fix bug if not gmp-impl.h (mpn_sub_nc is internal).
+Move MPFR_SET_EXP after checking the exponent range.
+Minor change in the way to return the ternary value.
+
+------------------------------------------------------------------------
+r3162 | zimmerma | 2005-01-01 12:17:16 +0000 (Sat, 01 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/sum.c
+
+changed tab[] into *tab (and removed 'tab' in mpfr.h)
+
+------------------------------------------------------------------------
+r3161 | zimmerma | 2004-12-24 10:41:39 +0000 (Fri, 24 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+new version (completely rewritten)
+
+------------------------------------------------------------------------
+r3160 | zimmerma | 2004-12-24 10:28:47 +0000 (Fri, 24 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+ M /trunk/tests/tsqrt.c
+
+improved coverage (and fixed bug)
+
+------------------------------------------------------------------------
+r3159 | pelissip | 2004-12-21 15:54:00 +0000 (Tue, 21 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+ M /trunk/tests/trint.c
+
+Fixed errors reported by Nelson H. F. Beebe
+(forget to include sys/fpu.h if defined and math.h if std=c99).
+
+------------------------------------------------------------------------
+r3158 | pelissip | 2004-12-20 12:54:45 +0000 (Mon, 20 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+Fix wrong integer type and a test.
+
+------------------------------------------------------------------------
+r3157 | pelissip | 2004-12-20 12:53:46 +0000 (Mon, 20 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Add some assertion.
+
+------------------------------------------------------------------------
+r3156 | pelissip | 2004-12-20 12:53:20 +0000 (Mon, 20 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+Unlikely one test.
+Fix wrong integer type
+
+------------------------------------------------------------------------
+r3155 | pelissip | 2004-12-20 12:52:47 +0000 (Mon, 20 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+ M /trunk/sub1.c
+
+Reindent the code.
+
+------------------------------------------------------------------------
+r3154 | pelissip | 2004-12-17 14:18:49 +0000 (Fri, 17 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+ M /trunk/tan.c
+
+Optimize mpfr_tan
+
+------------------------------------------------------------------------
+r3153 | pelissip | 2004-12-17 13:36:51 +0000 (Fri, 17 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+
+Optimize the computing of the sign of sinus if GET_EXP(x) < 0
+
+------------------------------------------------------------------------
+r3152 | pelissip | 2004-12-17 13:20:13 +0000 (Fri, 17 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+
+Optimize mpfr_cos.
+From 3363 / 21663.99 / 79727 to 3139 / 18920.58 / 69624 (opteron).
+
+------------------------------------------------------------------------
+r3151 | pelissip | 2004-12-17 13:13:50 +0000 (Fri, 17 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+Fix precision used to test long double.
+Now it is sizeof(long_double)*CHAR_BIT instead of fixed 113.
+
+------------------------------------------------------------------------
+r3150 | pelissip | 2004-12-17 11:14:56 +0000 (Fri, 17 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/extract.c
+
+FIx wrong integer types
+Add an assertion.
+
+------------------------------------------------------------------------
+r3149 | pelissip | 2004-12-17 11:14:23 +0000 (Fri, 17 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+Likely / Unlikely some code.
+
+------------------------------------------------------------------------
+r3148 | pelissip | 2004-12-17 11:13:53 +0000 (Fri, 17 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/get_ld.c
+ M /trunk/set_d.c
+ M /trunk/set_ld.c
+ M /trunk/tests/tset_ld.c
+
+Fix problem with long double with ICC (Wrong x86 processor flag).
+
+------------------------------------------------------------------------
+r3147 | pelissip | 2004-12-16 13:41:21 +0000 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+
+Fix wrong integer types.
+
+------------------------------------------------------------------------
+r3146 | pelissip | 2004-12-16 13:37:23 +0000 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Fix bug.
+
+------------------------------------------------------------------------
+r3145 | pelissip | 2004-12-16 13:27:11 +0000 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+
+Optimize mpfr_acos by choosing a better initial precision.
+
+------------------------------------------------------------------------
+r3144 | pelissip | 2004-12-16 13:12:42 +0000 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+
+Optimize mpfr_asin by improving the choice of the initial precision.
+
+------------------------------------------------------------------------
+r3143 | pelissip | 2004-12-16 12:04:10 +0000 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Optimize mpfr_atan.
+
+------------------------------------------------------------------------
+r3142 | pelissip | 2004-12-15 16:32:57 +0000 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/inp_str.c
+ M /trunk/tests/tinp_str.c
+
+Fix problem with GCC 4.0 20041212.
+
+------------------------------------------------------------------------
+r3141 | pelissip | 2004-12-15 14:22:50 +0000 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Remove thread attribut until I found a good way to use it.
+
+------------------------------------------------------------------------
+r3140 | pelissip | 2004-12-15 10:49:11 +0000 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Test
+
+------------------------------------------------------------------------
+r3139 | pelissip | 2004-12-15 10:47:42 +0000 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/strtofr.c
+
+Add 'const' attribute to table.
+
+------------------------------------------------------------------------
+r3138 | pelissip | 2004-12-15 10:46:00 +0000 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ D /trunk/save_expo.c
+
+Remove unused file.
+
+------------------------------------------------------------------------
+r3137 | pelissip | 2004-12-15 09:04:07 +0000 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+New way of detecting GMP libraray, which should be more portable.
+
+------------------------------------------------------------------------
+r3136 | pelissip | 2004-12-14 12:30:30 +0000 (Tue, 14 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-test.h
+ M /trunk/tests/Makefile.am
+ D /trunk/tests/amd64.asm
+ M /trunk/tests/tests.c
+ M /trunk/tests/tset_ld.c
+ D /trunk/tests/x86.asm
+
+Remove useless assembly code.
+
+------------------------------------------------------------------------
+r3135 | pelissip | 2004-12-14 10:54:47 +0000 (Tue, 14 Dec 2004) | 6 lines
+Changed paths:
+ M /trunk/cmp.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/set.c
+
+Add "MPFR_USE_NO_MACRO" user macro: it allows the user to link
+directly with MPFR functions rather than using Macros to access
+them. It doesn't define MPFR variable inside mpfr.h too.
+Fix set.c and cmp.c in consequences.
+Fix mpf2mpfr.h to use mpfr_get_default_rounding_mode () if needed.
+
+------------------------------------------------------------------------
+r3134 | pelissip | 2004-12-13 14:32:26 +0000 (Mon, 13 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/mulders.c
+
+Improved prototype.
+
+------------------------------------------------------------------------
+r3133 | pelissip | 2004-12-13 14:31:11 +0000 (Mon, 13 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/set_q.c
+
+Fix bug of overflow (I hope).
+
+------------------------------------------------------------------------
+r3132 | pelissip | 2004-12-13 10:23:33 +0000 (Mon, 13 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/mpfr.texi
+ M /trunk/set_q.c
+
+Update mpfr_set_q overflow problem.
+
+------------------------------------------------------------------------
+r3131 | pelissip | 2004-12-13 08:24:58 +0000 (Mon, 13 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/generic.c
+
+Fix wrong integer types.
+
+------------------------------------------------------------------------
+r3130 | pelissip | 2004-12-10 16:02:03 +0000 (Fri, 10 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Optimize by increasing with BITS_PER_MP_LIMB instead of log2(prec)
+
+------------------------------------------------------------------------
+r3129 | pelissip | 2004-12-10 15:59:15 +0000 (Fri, 10 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+
+Clean up code (Fix integer types + rewrite some code).
+Optimize the code by reducing the number of used variables inside the loop.
+
+------------------------------------------------------------------------
+r3128 | pelissip | 2004-12-10 15:58:13 +0000 (Fri, 10 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+
+Replace mpfr_neg to MPFR_CHANGE_SIGN.
+
+------------------------------------------------------------------------
+r3127 | pelissip | 2004-12-10 15:57:48 +0000 (Fri, 10 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/add1sp.c
+
+Cosmetic changes.
+
+------------------------------------------------------------------------
+r3126 | pelissip | 2004-12-10 14:45:54 +0000 (Fri, 10 Dec 2004) | 4 lines
+Changed paths:
+ M /trunk/acos.c
+
+Clean the code.
+Avoid mixing integer types.
+Fix bug of overflow if Pi is in the range but not Pi/2.
+
+------------------------------------------------------------------------
+r3125 | pelissip | 2004-12-10 14:22:49 +0000 (Fri, 10 Dec 2004) | 5 lines
+Changed paths:
+ M /trunk/asin.c
+
+Clean up the code (Removing useless variables and avoid mixing wrong integer types).
+Optimize the code by improving memory allocation scheme and by incrementating by
+BITS_PER_MP_LIMB in case of an error instead of MPFR_INT_CEIL_LOG2 (prec).
+Fix an overflow bug for X=+/-1 (If PI is inside the exponent range, but not PI/2).
+
+------------------------------------------------------------------------
+r3124 | pelissip | 2004-12-09 14:34:47 +0000 (Thu, 09 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Simplify MPFR_SIGN by removing unnecessary ( ).
+
+------------------------------------------------------------------------
+r3123 | pelissip | 2004-12-09 14:31:23 +0000 (Thu, 09 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Add support for new attribut sentinel in incoming GCC 4.0
+
+------------------------------------------------------------------------
+r3122 | pelissip | 2004-12-09 13:23:25 +0000 (Thu, 09 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+
+Optimize initial precision in case of EXP(x) < 0.
+
+------------------------------------------------------------------------
+r3121 | pelissip | 2004-12-09 10:13:55 +0000 (Thu, 09 Dec 2004) | 6 lines
+Changed paths:
+ M /trunk/cache.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_sj.c
+
+Optimize mpfr_set4.
+Inline rounding in mpfr_set4 and mpfr_cache
+mpfr_set4 dosn't return MPFR_EVEN_INEX (It was undocumented before).
+Fix problems with tests (Avoid mixing MPFR_EVEN_INEX and 1).
+Add MPFR_RNDRAW_EVEN for rounding with MPFR_EVEN_INEX inexact support
+
+------------------------------------------------------------------------
+r3120 | pelissip | 2004-12-08 14:08:45 +0000 (Wed, 08 Dec 2004) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/tests/tsqr.c
+
+Optimize mpfr_mul by inlining and rewriting the rounding.
+It seems that GCC option `-frename-registers` for mpfr_mul / Athlon XP
+improves its performance (But it decreases it on Pentium4)...
+
+------------------------------------------------------------------------
+r3119 | zimmerma | 2004-12-01 11:34:21 +0000 (Wed, 01 Dec 2004) | 2 lines
+Changed paths:
+ A /trunk/mulders.c
+
+first try to implement Mulders' algorithm
+
+------------------------------------------------------------------------
+r3118 | pelissip | 2004-11-29 15:10:29 +0000 (Mon, 29 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Update TODO.
+
+------------------------------------------------------------------------
+r3117 | zimmerma | 2004-11-29 13:58:14 +0000 (Mon, 29 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added new tests for corner cases
+
+------------------------------------------------------------------------
+r3116 | zimmerma | 2004-11-29 13:52:35 +0000 (Mon, 29 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+added algo for pi
+
+------------------------------------------------------------------------
+r3115 | pelissip | 2004-11-25 10:28:32 +0000 (Thu, 25 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/tan.c
+
+Change initial term if exp(a)<0.
+
+------------------------------------------------------------------------
+r3114 | pelissip | 2004-11-25 10:28:13 +0000 (Thu, 25 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+Simplify the inner loop.
+
+------------------------------------------------------------------------
+r3113 | pelissip | 2004-11-25 10:11:07 +0000 (Thu, 25 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+Change initial precision if EXP(op) < 0.
+
+------------------------------------------------------------------------
+r3112 | pelissip | 2004-11-23 12:49:15 +0000 (Tue, 23 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/set_z.c
+
+Optimize code and rewrite the rounding part.
+FIXME: It seems that the previous rounding code was buggy. Still I am not sure.
+
+------------------------------------------------------------------------
+r3111 | pelissip | 2004-11-23 12:48:00 +0000 (Tue, 23 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tgmpop.c
+
+Improve tests.
+
+------------------------------------------------------------------------
+r3110 | pelissip | 2004-11-19 14:38:28 +0000 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+Improve the initial value of prec: 10% improvement (?) on average.
+
+------------------------------------------------------------------------
+r3109 | pelissip | 2004-11-19 14:36:11 +0000 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+
+Improve coverage test.
+
+------------------------------------------------------------------------
+r3108 | pelissip | 2004-11-19 13:02:04 +0000 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_pow.c
+ M /trunk/ui_pow_ui.c
+
+Fix bug for mpfr_ui_pow_ui (Wrong inexact flag).
+
+------------------------------------------------------------------------
+r3107 | pelissip | 2004-11-19 12:39:10 +0000 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/get_z.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/tget_z.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_sj.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsqr.c
+ M /trunk/ufloor_log2.c
+
+Improve coverage tests.
+
+------------------------------------------------------------------------
+r3106 | pelissip | 2004-11-19 10:28:33 +0000 (Fri, 19 Nov 2004) | 4 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/README.dev
+ M /trunk/mpfr-impl.h
+
+Fix typos in INSTALL.
+Sort README.dev, and add a new section about How to write a MPFR function.
+Add a link to README.dev in mpfr-impl.h.
+
+------------------------------------------------------------------------
+r3105 | pelissip | 2004-11-19 08:35:48 +0000 (Fri, 19 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+
+Fix a bug on some compilators:
+ First MPFR_SAVE_EXPO_DECL, then TMP_DECL.
+
+------------------------------------------------------------------------
+r3104 | pelissip | 2004-11-18 15:53:55 +0000 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+ M /trunk/tests/tpow.c
+
+Fix an overflow bug.
+
+------------------------------------------------------------------------
+r3103 | pelissip | 2004-11-18 15:15:27 +0000 (Thu, 18 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/set_si_2exp.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/tests/tset_si.c
+
+Fix bug with inexact flag.
+FIXME: Maybe still a bug with inexact flag if overflow in mpfr_mul_2exp ?
+
+------------------------------------------------------------------------
+r3102 | pelissip | 2004-11-18 15:00:06 +0000 (Thu, 18 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr-impl.h
+ M /trunk/pow_ui.c
+
+Remove mpfr_save_emin_emax and mpfr_restore_emin_emax
+from MPFR library since they are useless.
+
+------------------------------------------------------------------------
+r3101 | pelissip | 2004-11-18 14:55:08 +0000 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+Forget to remove rndraw.c test.
+
+------------------------------------------------------------------------
+r3100 | pelissip | 2004-11-18 14:52:59 +0000 (Thu, 18 Nov 2004) | 4 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add_ui.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/gamma.c
+ M /trunk/hypot.c
+ M /trunk/mpfr-impl.h
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/rint.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_ld.c
+ M /trunk/set_q.c
+ M /trunk/set_si_2exp.c
+ M /trunk/set_ui_2exp.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub_ui.c
+ M /trunk/tanh.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+
+Replace use of mpfr_save_emin_emax () / mpfr_restore_emin_emax()
+by MPFR_SAVE_EXPO macros (DECL, MARK and FREE) which are faster
+and thread safe.
+
+------------------------------------------------------------------------
+r3098 | pelissip | 2004-11-18 14:04:52 +0000 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+Enable fast computing.
+
+------------------------------------------------------------------------
+r3097 | vlefevre | 2004-11-18 14:04:50 +0000 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix: GMP -> MPFR Copying Conditions (noted by Patrick).
+
+------------------------------------------------------------------------
+r3096 | pelissip | 2004-11-18 10:08:49 +0000 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Reorder the file and put sections to make it cleaner and more readable.
+
+------------------------------------------------------------------------
+r3095 | pelissip | 2004-11-18 09:11:19 +0000 (Thu, 18 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/log.c
+
+Reduce number of used variables.
+Optimize code and clean it.
+
+------------------------------------------------------------------------
+r3093 | vlefevre | 2004-11-18 08:56:06 +0000 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+In HTML, suppress the non-existing link to GMP.
+
+------------------------------------------------------------------------
+r3092 | pelissip | 2004-11-18 08:32:01 +0000 (Thu, 18 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/init2.c
+ M /trunk/mpfr-impl.h
+
+Add a prototype of own TMP_ALLOC. Don't know if it is a good idea.
+To enable it, just build MPFR with MPFR_USE_OWN_TMP_ALLOC.
+
+------------------------------------------------------------------------
+r3091 | pelissip | 2004-11-17 16:22:14 +0000 (Wed, 17 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+ M /trunk/strtofr.c
+ M /trunk/sum.c
+
+Fix bug with TMP_MARK.
+
+------------------------------------------------------------------------
+r3090 | pelissip | 2004-11-16 16:14:43 +0000 (Tue, 16 Nov 2004) | 4 lines
+Changed paths:
+ M /trunk/pow_ui.c
+
+Optimize the code:
+ + Special case for n == 2
+ + The first squaring is done using the original input.
+
+------------------------------------------------------------------------
+r3089 | pelissip | 2004-11-16 16:13:30 +0000 (Tue, 16 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/init2.c
+
+Add new assertion to check.
+
+------------------------------------------------------------------------
+r3088 | pelissip | 2004-11-16 16:13:01 +0000 (Tue, 16 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/cmp2.c
+
+Likely / Unlikely some tests.
+
+------------------------------------------------------------------------
+r3087 | pelissip | 2004-11-15 11:44:26 +0000 (Mon, 15 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+Add unused code (Still needs a proof).
+
+------------------------------------------------------------------------
+r3086 | pelissip | 2004-11-15 11:43:33 +0000 (Mon, 15 Nov 2004) | 4 lines
+Changed paths:
+ M /trunk/get_exp.c
+ M /trunk/mpfr.h
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_prec.c
+ M /trunk/set_rnd.c
+ M /trunk/set_ui.c
+
+Add macro version for small functions:
+ mpfr_get_prec, mpfr_get_exp, mpfr_get_default_rounding_mode,
+ mpfr_get_default_prec and mpfr_set_ui
+
+------------------------------------------------------------------------
+r3085 | pelissip | 2004-11-15 08:38:36 +0000 (Mon, 15 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Refix another bug (The same).
+
+------------------------------------------------------------------------
+r3084 | pelissip | 2004-11-15 08:32:23 +0000 (Mon, 15 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Fix a bug (Use __gmpfr_ceil_log2 instead of MPFR_INT_CEIL_LOG2).
+
+------------------------------------------------------------------------
+r3083 | zimmerma | 2004-11-12 17:29:54 +0000 (Fri, 12 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added algorithm for mpfr_sqrt
+improved algorithm for mpfr_div
+
+------------------------------------------------------------------------
+r3082 | zimmerma | 2004-11-12 17:22:57 +0000 (Fri, 12 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+use MPFR_SET_EXP/MPFR_GET_EXP instead of MPFR_EXP(r)++
+
+------------------------------------------------------------------------
+r3081 | vlefevre | 2004-11-12 16:03:43 +0000 (Fri, 12 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+Bug fix: delayed all the initializations after the singular test.
+
+------------------------------------------------------------------------
+r3080 | vlefevre | 2004-11-11 11:30:46 +0000 (Thu, 11 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+Untabified the source.
+
+------------------------------------------------------------------------
+r3079 | vlefevre | 2004-11-11 11:26:51 +0000 (Thu, 11 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+The test MPFR_GET_EXP(u) != MPFR_EMAX_MAX is no longer necessary
+since we decided to lower MPFR_EMAX_MAX to avoid such tests.
+
+------------------------------------------------------------------------
+r3078 | pelissip | 2004-11-10 16:12:53 +0000 (Wed, 10 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/sqrt.c
+
+Remove use of CNST_LIMB and TMP_ALLOC_LIMB which are GMP internal.
+Add MPFR_LIMB_ZERO.
+
+------------------------------------------------------------------------
+r3077 | zimmerma | 2004-11-10 12:10:16 +0000 (Wed, 10 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+ M /trunk/tests/tsqrt.c
+
+new simpler and faster code
+
+------------------------------------------------------------------------
+r3076 | pelissip | 2004-11-10 12:05:20 +0000 (Wed, 10 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cosh.c
+ M /trunk/erf.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/expm1.c
+ M /trunk/factorial.c
+ M /trunk/gamma.c
+ M /trunk/get_str.c
+ M /trunk/hypot.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sum.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+
+Replace __gmpfr_ceil_log2 by MPFR_INT_CEIL_LOG2 when possible.
+
+------------------------------------------------------------------------
+r3075 | pelissip | 2004-11-10 12:02:34 +0000 (Wed, 10 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Add __extension__ to avoid warning useless in GCC.
+
+------------------------------------------------------------------------
+r3074 | vlefevre | 2004-11-03 16:14:38 +0000 (Wed, 03 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/README
+
+Update.
+
+------------------------------------------------------------------------
+r3069 | pelissip | 2004-11-03 09:11:31 +0000 (Wed, 03 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Fix wrong Visual C++ code.
+
+------------------------------------------------------------------------
+r3068 | vlefevre | 2004-11-02 17:01:49 +0000 (Tue, 02 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Code checking for GMP library wasn't working (always returning "yes"?).
+
+------------------------------------------------------------------------
+r3066 | vlefevre | 2004-10-27 16:34:33 +0000 (Wed, 27 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Updated copyright line.
+
+------------------------------------------------------------------------
+r3064 | vlefevre | 2004-10-27 14:13:24 +0000 (Wed, 27 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Added a bug and updated copyright line.
+
+------------------------------------------------------------------------
+r3062 | vlefevre | 2004-10-27 13:06:42 +0000 (Wed, 27 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3061 | vlefevre | 2004-10-27 13:04:10 +0000 (Wed, 27 Oct 2004) | 7 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/set_d.c
+
+Removed the definitions of DBL_POS_INF/DBL_NEG_INF/DBL_NAN for
+Visual C++ as they were incorrect. Modified DOUBLE_ISINF(x) so
+that infinities are no longer used (this should fix a part of
+the problem for Visual C++). If IEEE 754 is not supported, one
+should probably use the standard INFINITY macro instead of
+(1.0/0.0), since (1.0/0.0) is specific to IEEE 754.
+
+------------------------------------------------------------------------
+r3060 | vlefevre | 2004-10-27 11:55:05 +0000 (Wed, 27 Oct 2004) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/tests/tests.c
+
+Applied patch by Steve M. Robbins for non-IRIX MIPS systems
+(originally for MPFR 2.0.3).
+
+------------------------------------------------------------------------
+r3059 | vlefevre | 2004-10-26 02:11:43 +0000 (Tue, 26 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tsub1sp.c
+
+Reformatted the code.
+
+------------------------------------------------------------------------
+r3058 | vlefevre | 2004-10-26 01:49:26 +0000 (Tue, 26 Oct 2004) | 5 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/ttanh.c
+
+Replaced mpfr_set_emin/emax by set_emin/emax in tests to check
+the return value; defined set_emin/emax in "tests/tests.c".
+Fix: added missing #include <string.h> in "tests/tests.c".
+Removed variable names in prototypes in "mpfr-test.h".
+
+------------------------------------------------------------------------
+r3057 | vlefevre | 2004-10-22 13:19:48 +0000 (Fri, 22 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/mpf_compat.h
+
+Reformatted the code -> GNU style.
+
+------------------------------------------------------------------------
+r3054 | vlefevre | 2004-10-22 12:49:32 +0000 (Fri, 22 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3053 | pelissip | 2004-10-22 08:00:56 +0000 (Fri, 22 Oct 2004) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+Declaration of "tests_rand_start" and "tests_rand_end" with the same storage class specifier
+in tests.c (static missing line 65 and 109).
+
+------------------------------------------------------------------------
+r3052 | vlefevre | 2004-10-21 11:53:26 +0000 (Thu, 21 Oct 2004) | 4 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+Bug fixed: cast to unsigned char instead of int for isspace (no,
+these are not "psycho" systems, just systems with signed chars).
+Untabified the source.
+
+------------------------------------------------------------------------
+r3051 | pelissip | 2004-10-20 13:27:25 +0000 (Wed, 20 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Improve ICC CFLAGS by removins meaningless warnings.
+
+------------------------------------------------------------------------
+r3050 | pelissip | 2004-10-20 12:52:33 +0000 (Wed, 20 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+Remove some warnings on some "psycho" systems.
+
+------------------------------------------------------------------------
+r3049 | pelissip | 2004-10-20 09:37:55 +0000 (Wed, 20 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Update the chapter "Make a release".
+
+------------------------------------------------------------------------
+r3048 | pelissip | 2004-10-20 09:36:18 +0000 (Wed, 20 Oct 2004) | 4 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/tests.c
+ M /trunk/tests/tinp_str.c
+
+Fix bug when you build MPFR outside source directory.
+Add function src_fopen to open a file in the source directory, which
+may be different from the current directory.
+
+------------------------------------------------------------------------
+r3047 | pelissip | 2004-10-20 07:12:08 +0000 (Wed, 20 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Fix a typo.
+
+------------------------------------------------------------------------
+r3046 | vlefevre | 2004-10-19 13:07:28 +0000 (Tue, 19 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Another correction (English).
+
+------------------------------------------------------------------------
+r3045 | vlefevre | 2004-10-19 13:05:34 +0000 (Tue, 19 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Minor correction.
+
+------------------------------------------------------------------------
+r3044 | pelissip | 2004-10-19 12:49:15 +0000 (Tue, 19 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Update NEWS to reflect the change in mpfr_set_str.
+
+------------------------------------------------------------------------
+r3043 | pelissip | 2004-10-19 12:45:45 +0000 (Tue, 19 Oct 2004) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/set_str.c
+ M /trunk/tests/tset_str.c
+
+Update mpfr_set_str to be much more like strtofr.
+Update the documentation to reflect the changes.
+
+------------------------------------------------------------------------
+r3042 | zimmerma | 2004-10-19 10:18:14 +0000 (Tue, 19 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+changed contributors section
+
+------------------------------------------------------------------------
+r3041 | pelissip | 2004-10-19 09:53:00 +0000 (Tue, 19 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Add a line about binary compatibility.
+
+------------------------------------------------------------------------
+r3040 | zimmerma | 2004-10-19 09:24:10 +0000 (Tue, 19 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+changed "contributors" section
+
+------------------------------------------------------------------------
+r3039 | zimmerma | 2004-10-19 09:02:46 +0000 (Tue, 19 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+changed rights (remove executable permission)
+
+------------------------------------------------------------------------
+r3038 | vlefevre | 2004-10-18 15:07:09 +0000 (Mon, 18 Oct 2004) | 7 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Misc corrections:
+ + spelling mistakes
+ + consistency: in direction @var{rnd} -> in the direction @var{rnd}
+ + @code{NULL} pointer -> null pointer (as in the C standard)
+ + in the example for mpfr_inits2 / mpfr_clears: NULL -> (void *) 0
+ as NULL isn't necessarily a pointer.
+
+------------------------------------------------------------------------
+r3037 | pelissip | 2004-10-18 14:23:01 +0000 (Mon, 18 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/README
+
+Update
+
+------------------------------------------------------------------------
+r3036 | pelissip | 2004-10-18 13:28:28 +0000 (Mon, 18 Oct 2004) | 7 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/set_str.c
+ M /trunk/strtofr.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tstrtofr.c
+
+Change "unsigned int" to "int" for base in proto of strtofr.
+Change set_str to use strtofr (Fix a bug too).
+Limit base to 36 in strtofr (since get_str is limited to 36).
+Update documentation to reflect the changes.
+mpfr_get_d1 is moved to section internal in the documentation.
+Update the tests.
+
+------------------------------------------------------------------------
+r3035 | pelissip | 2004-10-18 13:21:55 +0000 (Mon, 18 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Hard code NAN, +INF and -INF values for MVC.
+
+------------------------------------------------------------------------
+r3034 | pelissip | 2004-10-18 09:47:37 +0000 (Mon, 18 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/tout_str.c
+
+Fix problem on systems where "/dev/null" doesn't exist.
+
+------------------------------------------------------------------------
+r3033 | vlefevre | 2004-10-16 10:48:15 +0000 (Sat, 16 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+ M /trunk/mpfr.texi
+
+Misc corrections.
+
+------------------------------------------------------------------------
+r3032 | vlefevre | 2004-10-15 14:06:28 +0000 (Fri, 15 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Updated the section "To make a release".
+
+------------------------------------------------------------------------
+r3031 | vlefevre | 2004-10-15 13:58:37 +0000 (Fri, 15 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/VERSION
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/version.c
+
+Updated the version on the trunk.
+
+------------------------------------------------------------------------
+r3030 | vlefevre | 2004-10-15 12:52:20 +0000 (Fri, 15 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r3029 | vlefevre | 2004-10-15 12:49:05 +0000 (Fri, 15 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Update for 2.1.0.
+
+------------------------------------------------------------------------
+r3028 | vlefevre | 2004-10-13 08:35:11 +0000 (Wed, 13 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Added a comment about autoreconf and a bug in Debian (now fixed).
+
+------------------------------------------------------------------------
+r3027 | pelissip | 2004-10-12 07:24:51 +0000 (Tue, 12 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Add a note about Windows 64.
+
+------------------------------------------------------------------------
+r3026 | pelissip | 2004-10-11 13:52:42 +0000 (Mon, 11 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update documentation.
+
+------------------------------------------------------------------------
+r3025 | pelissip | 2004-10-11 13:52:29 +0000 (Mon, 11 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Improve Windows installation.
+
+------------------------------------------------------------------------
+r3024 | pelissip | 2004-10-11 13:52:07 +0000 (Mon, 11 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Add a line about "near" and "far".
+
+------------------------------------------------------------------------
+r3023 | pelissip | 2004-10-07 11:53:27 +0000 (Thu, 07 Oct 2004) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+ M /trunk/tests/tget_str.c
+
+Add support for ".lib" since it seems to work.
+Display GMP version inside the configure.
+
+------------------------------------------------------------------------
+r3022 | zimmerma | 2004-10-05 09:45:29 +0000 (Tue, 05 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added one new test
+
+------------------------------------------------------------------------
+r3021 | vlefevre | 2004-10-04 13:40:35 +0000 (Mon, 04 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+Added worst cases.
+
+------------------------------------------------------------------------
+r3020 | zimmerma | 2004-10-02 07:28:07 +0000 (Sat, 02 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+added new tests (worst-case)
+
+------------------------------------------------------------------------
+r3019 | zimmerma | 2004-10-01 12:31:46 +0000 (Fri, 01 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added new worst-cases (directed rounding)
+
+------------------------------------------------------------------------
+r3018 | zimmerma | 2004-10-01 07:35:34 +0000 (Fri, 01 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added new function to implement (dilog)
+
+------------------------------------------------------------------------
+r3017 | zimmerma | 2004-09-30 16:11:13 +0000 (Thu, 30 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed bug in get_str_aux when one extra digit
+
+------------------------------------------------------------------------
+r3016 | vlefevre | 2004-09-30 16:06:25 +0000 (Thu, 30 Sep 2004) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/rint.c
+ M /trunk/tests/trint.c
+
+Added functions mpfr_rint_round, mpfr_rint_trunc, mpfr_rint_ceil,
+mpfr_rint_floor.
+
+------------------------------------------------------------------------
+r3015 | pelissip | 2004-09-30 13:03:52 +0000 (Thu, 30 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+Add new test (One failed).
+
+------------------------------------------------------------------------
+r3014 | vlefevre | 2004-09-30 09:21:11 +0000 (Thu, 30 Sep 2004) | 3 lines
+Changed paths:
+ M /trunk/get_sj.c
+
+The cast to uintmax_t wasn't really useful, so I removed it.
+Added a comment.
+
+------------------------------------------------------------------------
+r3013 | vlefevre | 2004-09-30 09:06:37 +0000 (Thu, 30 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_sj.c
+
+The real fix for sizeof(intmax_t) == sizeof(mp_limb_t).
+
+------------------------------------------------------------------------
+r3012 | pelissip | 2004-09-30 08:08:59 +0000 (Thu, 30 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_sj.c
+
+Fix a bug if sizeof(intmax_t) == sizeof(mp_limb_t)
+
+------------------------------------------------------------------------
+r3011 | zimmerma | 2004-09-29 16:05:01 +0000 (Wed, 29 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added worst-case
+
+------------------------------------------------------------------------
+r3010 | pelissip | 2004-09-29 13:58:06 +0000 (Wed, 29 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/cmp.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ld.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcmpabs.c
+
+cmp(x,y) if x=NAN or y=NAN returns 0 and erange flag.
+
+------------------------------------------------------------------------
+r3009 | pelissip | 2004-09-29 12:54:47 +0000 (Wed, 29 Sep 2004) | 3 lines
+Changed paths:
+ M /trunk/NEWS
+ M /trunk/mpfr.texi
+
+Update documentation and NEWS to reflect new functions
+and functionnality.
+
+------------------------------------------------------------------------
+r3008 | pelissip | 2004-09-29 12:28:17 +0000 (Wed, 29 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_z.c
+ M /trunk/strtofr.c
+
+Improve assertion.
+
+------------------------------------------------------------------------
+r3007 | pelissip | 2004-09-29 12:27:36 +0000 (Wed, 29 Sep 2004) | 6 lines
+Changed paths:
+ M /trunk/exceptions.c
+ M /trunk/get_si.c
+ M /trunk/get_sj.c
+ M /trunk/get_ui.c
+ M /trunk/get_uj.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set_sj.c
+ M /trunk/set_uj.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/tget_sj.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_sj.c
+
+Add mpfr_clear_erangeflag and mpfr_erangeflag_p.
+Add test for theses two functions.
+mpfr_get_[s/u][i/j] have a deterministic behavior in case of OVERFLOW.
+(Return the MINIMUM or the MAXIMUM in the current type, and set
+ERANGE_flag).
+
+------------------------------------------------------------------------
+r3006 | pelissip | 2004-09-29 12:23:54 +0000 (Wed, 29 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/fits_intmax.c
+ A /trunk/fits_uintmax.c
+ M /trunk/mpfr.h
+ M /trunk/tests/tfits.c
+
+Add mpfr_uintmax_p and mpfr_intmax_p.
+
+------------------------------------------------------------------------
+r3005 | pelissip | 2004-09-29 12:21:03 +0000 (Wed, 29 Sep 2004) | 3 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/TODO
+
+Update INSTALL about C++
+Update TODO and VERSION.
+
+------------------------------------------------------------------------
+r3004 | pelissip | 2004-09-29 08:59:58 +0000 (Wed, 29 Sep 2004) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+Move mpfr_inits from mpfr-impl to mpfr.h.
+Add doc too.
+
+------------------------------------------------------------------------
+r3003 | pelissip | 2004-09-28 10:09:18 +0000 (Tue, 28 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_sj.c
+ M /trunk/get_uj.c
+
+Reindent the sources (again).
+
+------------------------------------------------------------------------
+r3002 | pelissip | 2004-09-28 09:26:34 +0000 (Tue, 28 Sep 2004) | 5 lines
+Changed paths:
+ M /trunk/mpn_exp.c
+
+Fix how to detect overflow so that it can be build with GCC -ftrapv
+option without any bugs (In the previous code, the overflow was
+detected afterwards, whereas, now, it is detected before).
+Fix also another real problem of overflow (Addition of two signed integers).
+
+------------------------------------------------------------------------
+r3001 | pelissip | 2004-09-28 08:24:07 +0000 (Tue, 28 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+Rename this variable again.
+
+------------------------------------------------------------------------
+r3000 | pelissip | 2004-09-28 07:53:46 +0000 (Tue, 28 Sep 2004) | 4 lines
+Changed paths:
+ M /trunk/div.c
+
+Replace variable 'near' to 'the_real_near' since MSVC incorreclty
+recognize "far" and "near" as obsolete keywords (100% incorrect, and
+clearly MSVC fault but it doesn't cost many things to change the name).
+
+------------------------------------------------------------------------
+r2999 | pelissip | 2004-09-27 14:59:46 +0000 (Mon, 27 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix typo in the documentation about get_ functions.
+
+------------------------------------------------------------------------
+r2998 | pelissip | 2004-09-27 14:58:37 +0000 (Mon, 27 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_sj.c
+ M /trunk/get_uj.c
+
+Retab the sources.
+
+------------------------------------------------------------------------
+r2997 | vlefevre | 2004-09-27 13:58:21 +0000 (Mon, 27 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Added mpfr_get_uj and mpfr_get_sj in the changes 2.0.3 -> 2.1.0.
+
+------------------------------------------------------------------------
+r2996 | vlefevre | 2004-09-27 13:38:24 +0000 (Mon, 27 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Added an item about the future MPFR_FLAGS_ERANGE flag.
+
+------------------------------------------------------------------------
+r2995 | vlefevre | 2004-09-27 13:21:12 +0000 (Mon, 27 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/get_sj.c
+ A /trunk/get_uj.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tget_sj.c
+
+New functions mpfr_get_sj and mpfr_get_uj, with tests.
+
+------------------------------------------------------------------------
+r2994 | pelissip | 2004-09-27 08:35:25 +0000 (Mon, 27 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/set_sj.c
+
+Remove MPFR_NEED_LONGLONG_H macro.
+
+------------------------------------------------------------------------
+r2993 | vlefevre | 2004-09-26 22:18:46 +0000 (Sun, 26 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/set_sj.c
+
+Added a cast to avoid an integer overflow.
+
+------------------------------------------------------------------------
+r2992 | vlefevre | 2004-09-24 14:53:05 +0000 (Fri, 24 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_si.c
+
+Fixed integer overflow.
+
+------------------------------------------------------------------------
+r2991 | vlefevre | 2004-09-24 14:13:20 +0000 (Fri, 24 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_si.c
+
+Fixed bugs (like those in mpfr_get_ui).
+
+------------------------------------------------------------------------
+r2990 | vlefevre | 2004-09-24 13:38:39 +0000 (Fri, 24 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+The standard autoreconf script should now be used instead of prepare.
+
+------------------------------------------------------------------------
+r2989 | zimmerma | 2004-09-24 11:43:47 +0000 (Fri, 24 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_ui.c
+
+forgot to check for 0
+
+------------------------------------------------------------------------
+r2988 | zimmerma | 2004-09-24 11:15:45 +0000 (Fri, 24 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_ui.c
+
+now use mpfr_rint()
+
+------------------------------------------------------------------------
+r2987 | pelissip | 2004-09-24 08:32:31 +0000 (Fri, 24 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update doc of mpfr_get_str (Minimum space is 7).
+
+------------------------------------------------------------------------
+r2986 | zimmerma | 2004-09-24 07:21:04 +0000 (Fri, 24 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/get_ui.c
+ M /trunk/tests/tset_si.c
+
+fixed double-rounding bug in get_ui
+
+------------------------------------------------------------------------
+r2985 | pelissip | 2004-09-23 15:28:35 +0000 (Thu, 23 Sep 2004) | 3 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+Prevent from multiple inclusion.
+mpf_init inits to 0 rather than NAN.
+
+------------------------------------------------------------------------
+r2984 | pelissip | 2004-09-23 13:54:41 +0000 (Thu, 23 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Fix some tiny problems.
+
+------------------------------------------------------------------------
+r2983 | zimmerma | 2004-09-23 10:16:45 +0000 (Thu, 23 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added item on rounding to odd
+
+------------------------------------------------------------------------
+r2982 | pelissip | 2004-09-21 12:42:37 +0000 (Tue, 21 Sep 2004) | 3 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+Fix a bug in FreeBsd 5.20 / Alpha / Gcc 3.3.3.
+Not a MPFR bug, but add some code to avoid it.
+Reference: http://www.freebsd.org/cgi/query-pr.cgi?pr=72024
+------------------------------------------------------------------------
+r2981 | pelissip | 2004-09-21 11:46:11 +0000 (Tue, 21 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+ M /trunk/tests/tstrtofr.c
+
+Add a new test and clarify a comment.
+
+------------------------------------------------------------------------
+r2980 | pelissip | 2004-09-21 09:52:54 +0000 (Tue, 21 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/strtofr.c
+
+Update Assertion for pow2.
+
+------------------------------------------------------------------------
+r2979 | pelissip | 2004-09-20 15:38:19 +0000 (Mon, 20 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Update NEWS.
+
+------------------------------------------------------------------------
+r2978 | pelissip | 2004-09-20 15:13:51 +0000 (Mon, 20 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Update TODO due to new function mpfr_strtofr
+
+------------------------------------------------------------------------
+r2977 | pelissip | 2004-09-20 14:45:32 +0000 (Mon, 20 Sep 2004) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/get_d.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/set_d.c
+ M /trunk/strtofr.c
+ M /trunk/tests/memory.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tstrtofr.c
+
+Add ICC detection && support.
+Remove some potential warnings in the test files.
+
+------------------------------------------------------------------------
+r2976 | pelissip | 2004-09-20 08:57:28 +0000 (Mon, 20 Sep 2004) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.texi
+ A /trunk/strtofr.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tstrtofr.c
+
+Add mpfr_strtofr function.
+Add mpfr_strtofr test file.
+Add mpfr_strtofr documentation.
+
+------------------------------------------------------------------------
+r2975 | pelissip | 2004-09-20 08:55:56 +0000 (Mon, 20 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Improve GMP.h vs libgmp.a version checking.
+
+------------------------------------------------------------------------
+r2974 | zimmerma | 2004-09-17 16:26:22 +0000 (Fri, 17 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one entry (new function 1/sqrt(x))
+
+------------------------------------------------------------------------
+r2973 | pelissip | 2004-09-17 09:49:50 +0000 (Fri, 17 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+ M /trunk/tests/Makefile.am
+
+Use LIBS instead of LDADD for libraries (GMP).
+
+------------------------------------------------------------------------
+r2972 | pelissip | 2004-09-17 07:21:31 +0000 (Fri, 17 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Min GMP version is 4.1.0 now.
+
+------------------------------------------------------------------------
+r2971 | pelissip | 2004-09-16 11:12:09 +0000 (Thu, 16 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Add a check if both gmp.h and libgmp.a have the same version.
+
+------------------------------------------------------------------------
+r2970 | pelissip | 2004-09-16 11:11:23 +0000 (Thu, 16 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Fix a typo.
+
+------------------------------------------------------------------------
+r2969 | pelissip | 2004-09-15 08:50:55 +0000 (Wed, 15 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+Add a forgotten regression test "1.2.3"
+
+------------------------------------------------------------------------
+r2968 | vlefevre | 2004-09-15 08:38:08 +0000 (Wed, 15 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/config.guess
+ M /trunk/config.sub
+
+Update from the autotools-dev Debian package.
+
+------------------------------------------------------------------------
+r2967 | vlefevre | 2004-09-15 08:27:38 +0000 (Wed, 15 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r2966 | pelissip | 2004-09-14 15:11:07 +0000 (Tue, 14 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Add 2 new macros for handling correctly overflow.
+
+------------------------------------------------------------------------
+r2965 | zimmerma | 2004-09-13 14:00:36 +0000 (Mon, 13 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+fixed bug (several '.' allowed in mantissa)
+
+------------------------------------------------------------------------
+r2964 | zimmerma | 2004-09-03 09:06:13 +0000 (Fri, 03 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+added notes for Windows
+
+------------------------------------------------------------------------
+r2963 | pelissip | 2004-09-02 07:06:39 +0000 (Thu, 02 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Add a line about Dynamic Version of MPFR.
+
+------------------------------------------------------------------------
+r2962 | zimmerma | 2004-09-01 16:42:07 +0000 (Wed, 01 Sep 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added warnings about init functions (mpf wrt mpfr)
+
+------------------------------------------------------------------------
+r2961 | pelissip | 2004-08-31 13:01:00 +0000 (Tue, 31 Aug 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update documentations.
+
+------------------------------------------------------------------------
+r2960 | pelissip | 2004-08-31 13:00:15 +0000 (Tue, 31 Aug 2004) | 3 lines
+Changed paths:
+ M /trunk/get_z.c
+ M /trunk/mpfr.h
+ M /trunk/tests/tget_z.c
+
+Rename mpz_set_fr to mpfr_get_z.
+Provide a conditionnal macro for mpz_set_fr.
+
+------------------------------------------------------------------------
+r2959 | pelissip | 2004-08-31 09:20:41 +0000 (Tue, 31 Aug 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add doc for mpfr_sqr.
+
+------------------------------------------------------------------------
+r2958 | pelissip | 2004-08-31 08:58:29 +0000 (Tue, 31 Aug 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix month.
+
+------------------------------------------------------------------------
+r2957 | pelissip | 2004-08-26 09:05:32 +0000 (Thu, 26 Aug 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+Add a new test to check overflow.
+
+------------------------------------------------------------------------
+r2956 | pelissip | 2004-08-24 14:00:42 +0000 (Tue, 24 Aug 2004) | 3 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+Try to retype correctly the functions (replace int by the correct type).
+Still some works to do.
+
+------------------------------------------------------------------------
+r2955 | pelissip | 2004-08-23 09:32:27 +0000 (Mon, 23 Aug 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Add description of what does MPFR_INT_CEIL_LOG2.
+
+------------------------------------------------------------------------
+r2954 | pelissip | 2004-08-23 09:31:32 +0000 (Mon, 23 Aug 2004) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/exp_2.c
+ A /trunk/isqrt.c
+
+Move __gmpfr_isqrt and __gmpfr_cuberoot to another file.
+Clean up the code of mpfr_exp_2: remove DEBUG condition to use TRACE, ASSERT and DUMP.
+Use MPFR_INT_CEIL_LOG2 instead of __gmpfr_ceil_log2.
+
+------------------------------------------------------------------------
+r2953 | pelissip | 2004-08-23 09:29:55 +0000 (Mon, 23 Aug 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Improve a comment.
+
+------------------------------------------------------------------------
+r2952 | pelissip | 2004-08-23 09:01:18 +0000 (Mon, 23 Aug 2004) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/int_ceil_log2.c
+ M /trunk/mpfr-impl.h
+
+Add MPFR_INT_CEIL_LOG2 macro and __gmpfr_int_ceil_log2 function
+(don't use function but macro).
+
+------------------------------------------------------------------------
+r2951 | pelissip | 2004-08-23 08:58:24 +0000 (Mon, 23 Aug 2004) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Fix 2 typos.
+
+------------------------------------------------------------------------
+r2950 | pelissip | 2004-08-19 15:02:18 +0000 (Thu, 19 Aug 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Fix a bug on 64-bits introduced due to huger MPFR_EMAX_MAX.
+
+------------------------------------------------------------------------
+r2949 | pelissip | 2004-08-19 14:42:03 +0000 (Thu, 19 Aug 2004) | 5 lines
+Changed paths:
+ M /trunk/exceptions.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+Add new functions: mpfr_get_emin_min, mpfr_get_emax_max, mpfr_get_emin_max and
+mpfr_get_emax_min.
+Add documentation and explanation about potential portability problem when
+you mpfr_set_emin and mpfr_set_emax.
+
+------------------------------------------------------------------------
+r2948 | vlefevre | 2004-07-28 15:10:23 +0000 (Wed, 28 Jul 2004) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Added mpfr-longlong.h to libmpfr_a_SOURCES so that it is distributed
+with make dist.
+
+------------------------------------------------------------------------
+r2947 | vlefevre | 2004-07-28 15:06:29 +0000 (Wed, 28 Jul 2004) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Added mpfr-gmp.h to libmpfr_a_SOURCES so that it is distributed
+with make dist.
+
+------------------------------------------------------------------------
+r2946 | pelissip | 2004-07-26 14:38:56 +0000 (Mon, 26 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Add a new section.
+
+------------------------------------------------------------------------
+r2945 | pelissip | 2004-07-20 09:09:34 +0000 (Tue, 20 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ A /trunk/sqr.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tsqr.c
+
+Add function mpfr_sqr (TODO: Make doc)
+
+------------------------------------------------------------------------
+r2944 | pelissip | 2004-07-19 11:48:10 +0000 (Mon, 19 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+Fix an unsigned/signed comparison.
+
+------------------------------------------------------------------------
+r2943 | pelissip | 2004-07-19 11:39:27 +0000 (Mon, 19 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+Improve the emulation of mpn_sqr_n and fix some typos.
+
+------------------------------------------------------------------------
+r2942 | pelissip | 2004-07-16 11:33:34 +0000 (Fri, 16 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+Remove unused item "rnd_mode" in cache struct.
+
+------------------------------------------------------------------------
+r2941 | pelissip | 2004-07-16 08:59:40 +0000 (Fri, 16 Jul 2004) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tversion.c
+ M /trunk/version.c
+
+Renamme mpfr_version to mpfr_get_version to be more GMP compatible.
+Add macro mpfr_version.
+
+------------------------------------------------------------------------
+r2940 | pelissip | 2004-07-16 08:54:53 +0000 (Fri, 16 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/cmp_ui.c
+ M /trunk/round_raw_generic.c
+
+Likely some tests.
+
+------------------------------------------------------------------------
+r2939 | pelissip | 2004-07-15 07:58:02 +0000 (Thu, 15 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/set_si.c
+
+Add a speciliation for set_si for GCC.
+
+------------------------------------------------------------------------
+r2938 | pelissip | 2004-07-09 09:42:26 +0000 (Fri, 09 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+Try to optimize a few agm by rewriting a few the loop.
+
+------------------------------------------------------------------------
+r2937 | pelissip | 2004-07-09 09:41:45 +0000 (Fri, 09 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+Likely / Unlikely some tests using gcov.
+
+------------------------------------------------------------------------
+r2936 | pelissip | 2004-07-06 12:16:52 +0000 (Tue, 06 Jul 2004) | 5 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Remove some unused code.
+Add MPFR_LMIB_PER_DOUBLE
+Add MPFR_DUMP
+Add MPFR_TRACE
+
+------------------------------------------------------------------------
+r2935 | pelissip | 2004-07-06 12:14:44 +0000 (Tue, 06 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Likely some tests.
+
+------------------------------------------------------------------------
+r2934 | pelissip | 2004-07-06 12:14:11 +0000 (Tue, 06 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+
+Used static precision for the array of limb for double.
+
+------------------------------------------------------------------------
+r2933 | pelissip | 2004-07-06 12:10:24 +0000 (Tue, 06 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+Likely some tests / Other minor optimisations.
+
+------------------------------------------------------------------------
+r2932 | pelissip | 2004-07-06 12:09:31 +0000 (Tue, 06 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/ui_div.c
+
+Minor modifications.
+
+------------------------------------------------------------------------
+r2931 | pelissip | 2004-07-06 12:08:13 +0000 (Tue, 06 Jul 2004) | 3 lines
+Changed paths:
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+
+Unlikely a test so that it is faster when you call theses functions
+with the same dest and source which is the common case in MPFR.
+
+------------------------------------------------------------------------
+r2930 | pelissip | 2004-07-06 12:04:08 +0000 (Tue, 06 Jul 2004) | 3 lines
+Changed paths:
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+
+Likely a test to optimize when dest and src are the same
+(which is very likely inside MPFR).
+
+------------------------------------------------------------------------
+r2929 | pelissip | 2004-07-06 12:02:59 +0000 (Tue, 06 Jul 2004) | 2 lines
+Changed paths:
+ M /trunk/cache.c
+
+Likely a test (since cache should always work fine).
+
+------------------------------------------------------------------------
+r2928 | pelissip | 2004-06-28 12:11:44 +0000 (Mon, 28 Jun 2004) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+ M /trunk/get_d.c
+
+Add some likely, and use a static table instead of a dynamic one.
+
+------------------------------------------------------------------------
+r2927 | pelissip | 2004-06-16 12:08:30 +0000 (Wed, 16 Jun 2004) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+ M /trunk/atan.c
+
+Unlikely some tests.
+
+------------------------------------------------------------------------
+r2926 | pelissip | 2004-06-10 15:10:12 +0000 (Thu, 10 Jun 2004) | 2 lines
+Changed paths:
+ M /trunk/set_z.c
+
+Likely / Unlikely the code.
+
+------------------------------------------------------------------------
+r2925 | pelissip | 2004-06-10 14:03:10 +0000 (Thu, 10 Jun 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Respace some macro.
+
+------------------------------------------------------------------------
+r2924 | pelissip | 2004-06-10 14:02:30 +0000 (Thu, 10 Jun 2004) | 2 lines
+Changed paths:
+ M /trunk/save_expo.c
+
+Retab some lines.
+
+------------------------------------------------------------------------
+r2923 | pelissip | 2004-06-10 14:01:33 +0000 (Thu, 10 Jun 2004) | 2 lines
+Changed paths:
+ M /trunk/get_z.c
+
+Optimize a bit.
+
+------------------------------------------------------------------------
+r2922 | pelissip | 2004-06-10 13:59:50 +0000 (Thu, 10 Jun 2004) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+ M /trunk/tests/tsin.c
+
+Fix an overflow bug.
+
+------------------------------------------------------------------------
+r2921 | zimmerma | 2004-06-08 07:27:40 +0000 (Tue, 08 Jun 2004) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+ M /trunk/tests/texp.c
+
+fixed bug in mpfr_exp_3 (wrong assert)
+
+------------------------------------------------------------------------
+r2920 | pelissip | 2004-05-27 14:39:34 +0000 (Thu, 27 May 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Fix typos.
+
+------------------------------------------------------------------------
+r2919 | pelissip | 2004-05-27 09:52:44 +0000 (Thu, 27 May 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update doc.
+
+------------------------------------------------------------------------
+r2918 | zimmerma | 2004-05-18 16:00:28 +0000 (Tue, 18 May 2004) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+
+fixed problem for x near from Pi/2 (the internal precision should take
+into account the cancellation)
+
+------------------------------------------------------------------------
+r2917 | pelissip | 2004-05-18 15:26:19 +0000 (Tue, 18 May 2004) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+ M /trunk/tests/tsin.c
+
+Improve tests for sin.
+
+------------------------------------------------------------------------
+r2916 | zimmerma | 2004-05-18 14:29:55 +0000 (Tue, 18 May 2004) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+mpfr_sin_sign() should use at least MPFR_GET_EXP() bits
+
+------------------------------------------------------------------------
+r2915 | pelissip | 2004-05-17 07:57:34 +0000 (Mon, 17 May 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Remove an item.
+
+------------------------------------------------------------------------
+r2914 | pelissip | 2004-05-12 14:57:36 +0000 (Wed, 12 May 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+ M /trunk/tests/ttan.c
+
+Add a potential test (Too slow).
+
+------------------------------------------------------------------------
+r2913 | pelissip | 2004-05-12 14:57:10 +0000 (Wed, 12 May 2004) | 2 lines
+Changed paths:
+ M /trunk/tan.c
+
+Simplify the code.
+
+------------------------------------------------------------------------
+r2912 | pelissip | 2004-05-11 07:21:45 +0000 (Tue, 11 May 2004) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Remove a C++ comment.
+
+------------------------------------------------------------------------
+r2911 | pelissip | 2004-05-10 07:03:28 +0000 (Mon, 10 May 2004) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Remove a forgotten "assertd" which isn't usefull anymore.
+
+------------------------------------------------------------------------
+r2910 | pelissip | 2004-05-07 15:04:30 +0000 (Fri, 07 May 2004) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/mpfr-impl.h
+
+Optimize cos.
+
+------------------------------------------------------------------------
+r2909 | zimmerma | 2004-05-07 13:00:11 +0000 (Fri, 07 May 2004) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+
+improved initial value of working precision (did not take into account
+2K lost bits for large arguments)
+
+------------------------------------------------------------------------
+r2908 | pelissip | 2004-05-06 12:37:21 +0000 (Thu, 06 May 2004) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/asin.c
+ M /trunk/atan.c
+ M /trunk/exp2.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/ttanh.c
+
+Fix overflow and add corresponding tests.
+
+------------------------------------------------------------------------
+r2907 | pelissip | 2004-05-06 10:42:56 +0000 (Thu, 06 May 2004) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Fix a bug in a formula.
+
+------------------------------------------------------------------------
+r2906 | pelissip | 2004-05-06 10:42:44 +0000 (Thu, 06 May 2004) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+Optimize it a bit.
+
+------------------------------------------------------------------------
+r2905 | pelissip | 2004-05-06 09:56:48 +0000 (Thu, 06 May 2004) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/exp_2.c
+ M /trunk/gamma.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tgamma.c
+
+Fix overflow problems.
+
+------------------------------------------------------------------------
+r2904 | pelissip | 2004-05-06 09:11:20 +0000 (Thu, 06 May 2004) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tcosh.c
+
+Fix overflow bug.
+
+------------------------------------------------------------------------
+r2903 | pelissip | 2004-05-05 15:34:06 +0000 (Wed, 05 May 2004) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Remove the double vars. (Use fixed instead).
+
+------------------------------------------------------------------------
+r2902 | pelissip | 2004-05-05 15:14:07 +0000 (Wed, 05 May 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Add a note about tanh.
+
+------------------------------------------------------------------------
+r2901 | pelissip | 2004-05-05 15:10:43 +0000 (Wed, 05 May 2004) | 2 lines
+Changed paths:
+ M /trunk/tanh.c
+ M /trunk/tests/ttanh.c
+
+Fix a bug in cas of overflow in tanh.
+
+------------------------------------------------------------------------
+r2900 | pelissip | 2004-05-05 13:02:20 +0000 (Wed, 05 May 2004) | 2 lines
+Changed paths:
+ M /trunk/tanh.c
+
+Optimize a few by reducing the # of used vars.
+
+------------------------------------------------------------------------
+r2899 | pelissip | 2004-05-05 12:29:28 +0000 (Wed, 05 May 2004) | 2 lines
+Changed paths:
+ M /trunk/cosh.c
+ M /trunk/tests/tcosh.c
+
+Fix critical bugs due to different kind of overflow in cosh.
+
+------------------------------------------------------------------------
+r2898 | pelissip | 2004-05-05 12:28:38 +0000 (Wed, 05 May 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Add MPFR_TMP_INIT_ABS macro.
+
+------------------------------------------------------------------------
+r2897 | pelissip | 2004-05-05 09:39:23 +0000 (Wed, 05 May 2004) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+ M /trunk/cosh.c
+
+Optimize cosh a few by removing an unused intermedary var.
+
+------------------------------------------------------------------------
+r2896 | pelissip | 2004-05-05 07:49:22 +0000 (Wed, 05 May 2004) | 2 lines
+Changed paths:
+ M /trunk/const_log2.c
+
+Fix a critical bug in case of overflow.
+
+------------------------------------------------------------------------
+r2895 | pelissip | 2004-05-04 15:46:42 +0000 (Tue, 04 May 2004) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tlog.c
+
+Fix a critical bug in cos in case you have set the float range for the exponents.
+
+------------------------------------------------------------------------
+r2894 | pelissip | 2004-05-04 14:17:54 +0000 (Tue, 04 May 2004) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+Optimize a few cos.
+
+------------------------------------------------------------------------
+r2893 | pelissip | 2004-05-04 13:34:15 +0000 (Tue, 04 May 2004) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+Optimize the way of computing initial precision.
+
+------------------------------------------------------------------------
+r2892 | pelissip | 2004-05-04 12:52:01 +0000 (Tue, 04 May 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+Add a test to check an overflow in const_pi (called by log in case of emulation of the float type).
+
+------------------------------------------------------------------------
+r2891 | pelissip | 2004-05-04 12:50:59 +0000 (Tue, 04 May 2004) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+
+Move to ASSERT mode some code.
+
+------------------------------------------------------------------------
+r2890 | pelissip | 2004-05-04 12:46:13 +0000 (Tue, 04 May 2004) | 3 lines
+Changed paths:
+ M /trunk/const_pi.c
+
+Push/Pop emin/emax so that an overflow can't occur in mpfr_set_z(x,pi,r)
+Add test too.
+
+------------------------------------------------------------------------
+r2889 | pelissip | 2004-05-04 09:06:04 +0000 (Tue, 04 May 2004) | 2 lines
+Changed paths:
+ M /trunk/mul_2ui.c
+
+Add some UNLIKELY to the while.
+
+------------------------------------------------------------------------
+r2888 | pelissip | 2004-05-04 09:05:30 +0000 (Tue, 04 May 2004) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+Add some UNLIKELY to the tests.
+
+------------------------------------------------------------------------
+r2887 | pelissip | 2004-05-04 09:05:00 +0000 (Tue, 04 May 2004) | 2 lines
+Changed paths:
+ M /trunk/add1sp.c
+ M /trunk/tests/tadd1sp.c
+
+Fix an overflow bug in add1sp.
+
+------------------------------------------------------------------------
+r2885 | pelissip | 2004-04-29 07:31:09 +0000 (Thu, 29 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Fix a typo in AC_MY_LIBS.
+
+------------------------------------------------------------------------
+r2884 | pelissip | 2004-04-28 07:47:59 +0000 (Wed, 28 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+ M /trunk/mpfr.h
+
+Add mpfr_cmp as a real function, not only a macro.
+
+------------------------------------------------------------------------
+r2883 | pelissip | 2004-04-28 07:43:36 +0000 (Wed, 28 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/set.c
+
+Add mpfr_set and mpfr_abs as real functions.
+
+------------------------------------------------------------------------
+r2882 | pelissip | 2004-04-27 13:35:45 +0000 (Tue, 27 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+When using GCC, optimize certain common comparisons.
+
+------------------------------------------------------------------------
+r2881 | zimmerma | 2004-04-27 11:40:47 +0000 (Tue, 27 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one item
+
+------------------------------------------------------------------------
+r2880 | pelissip | 2004-04-27 09:04:14 +0000 (Tue, 27 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+Minor Optimizations.
+
+------------------------------------------------------------------------
+r2879 | pelissip | 2004-04-27 09:03:17 +0000 (Tue, 27 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/cache.c
+
+Fix a bug (Use nextbeloz instead of sub_one_ulp).
+
+------------------------------------------------------------------------
+r2878 | pelissip | 2004-04-21 13:07:50 +0000 (Wed, 21 Apr 2004) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/mpfr-impl.h
+
+Add option in configure: --disable-cache
+to disable the use of the cache for the const.
+
+------------------------------------------------------------------------
+r2877 | pelissip | 2004-04-21 12:47:53 +0000 (Wed, 21 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix a typo.
+
+------------------------------------------------------------------------
+r2876 | pelissip | 2004-04-21 12:36:30 +0000 (Wed, 21 Apr 2004) | 5 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/cache.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/free_cache.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+
+Add preliminary generic code to handle cached const.
+Move const_pi, const_log2 to use this generic cache,
+which fix bugs of the previous implementation.
+const_euler is now cached too.
+
+------------------------------------------------------------------------
+r2875 | pelissip | 2004-04-21 12:34:00 +0000 (Wed, 21 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/round_prec.c
+
+Fix a bug (If x = Nan, the new new precision wasn't set).
+
+------------------------------------------------------------------------
+r2874 | pelissip | 2004-04-21 12:33:29 +0000 (Wed, 21 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/cputime.h
+
+Fix a typo bug.
+
+------------------------------------------------------------------------
+r2873 | pelissip | 2004-04-20 12:13:51 +0000 (Tue, 20 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tconst_log2.c
+
+Add new test about the cache: new bug to fix.
+
+------------------------------------------------------------------------
+r2872 | pelissip | 2004-04-20 12:03:40 +0000 (Tue, 20 Apr 2004) | 2 lines
+Changed paths:
+ A /trunk/iszero.c
+
+Add forgotten file for mpfr_zero_p.
+
+------------------------------------------------------------------------
+r2871 | pelissip | 2004-04-20 09:32:20 +0000 (Tue, 20 Apr 2004) | 6 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/isinf.c
+ M /trunk/isnan.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/sgn.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tsgn.c
+
+Add mpfr_zero_p.
+Add macros for mpfr_inf_p, mpfr_nan_p and mpfr_zero_p.
+Add macro for mpfr_sgn.
+Update doc.
+Add new tests.
+
+------------------------------------------------------------------------
+r2870 | pelissip | 2004-04-20 09:30:56 +0000 (Tue, 20 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+Fix a bug in a proto.
+
+------------------------------------------------------------------------
+r2869 | pelissip | 2004-04-20 09:29:48 +0000 (Tue, 20 Apr 2004) | 3 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/tests/tagm.c
+
+Fix a bug when both op are < 0 (It seems it was my fault).
+Add a test to check it.
+
+------------------------------------------------------------------------
+r2868 | pelissip | 2004-04-09 08:38:02 +0000 (Fri, 09 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.c
+
+Fix a bug (Remove useless function).
+
+------------------------------------------------------------------------
+r2867 | pelissip | 2004-04-08 09:12:08 +0000 (Thu, 08 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+Fix another bug (Maybe the last?).
+
+------------------------------------------------------------------------
+r2866 | pelissip | 2004-04-08 09:09:45 +0000 (Thu, 08 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.h
+
+Fix a tiny bug.
+
+------------------------------------------------------------------------
+r2865 | pelissip | 2004-04-08 09:07:10 +0000 (Thu, 08 Apr 2004) | 4 lines
+Changed paths:
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-test.h
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_f.c
+
+Update memory allocations scheme without gmp-impl.h.
+Now the semantic of the memory allocation scheme is the same
+with and without gmp-impl, as it should be.
+
+------------------------------------------------------------------------
+r2864 | pelissip | 2004-04-07 14:42:32 +0000 (Wed, 07 Apr 2004) | 3 lines
+Changed paths:
+ M /trunk/add_ui.c
+ M /trunk/gmp_op.c
+ M /trunk/mpfr.texi
+ M /trunk/sub_ui.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/ui_sub.c
+
+For add/sub_type functions where type is a type without signed zeros,
+specify the expected result when both operands are 0.
+
+------------------------------------------------------------------------
+r2863 | pelissip | 2004-04-07 14:40:47 +0000 (Wed, 07 Apr 2004) | 4 lines
+Changed paths:
+ M /trunk/init2.c
+ M /trunk/mpfr-gmp.c
+ M /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+Modify a few the allocation scheme without gmp-impl.h
+Add pseudo-constants __MPFR_EXP_NAN, __MPFR_EXP_ZERO and __MPFR_EXP_INF
+for future (?) inlining of some functions.
+
+------------------------------------------------------------------------
+r2862 | zimmerma | 2004-04-07 14:19:44 +0000 (Wed, 07 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/mpn_exp.c
+ M /trunk/set_str.c
+ M /trunk/tests/tset_str.c
+
+fixed problem when overflow in destination exponent happens
+
+------------------------------------------------------------------------
+r2861 | pelissip | 2004-04-07 13:31:54 +0000 (Wed, 07 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/tests/tgmpop.c
+
+Fix a bug in case a mpz_t == 0 (mpz_sizeinbase(0Z,2)==0 and MPFR_PREC_MIN=2).
+
+------------------------------------------------------------------------
+r2860 | pelissip | 2004-04-07 13:12:41 +0000 (Wed, 07 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+ M /trunk/tests/tpow.c
+
+Fix a bug in case of pow(2E1000000,-10);
+
+------------------------------------------------------------------------
+r2859 | zimmerma | 2004-04-05 08:53:04 +0000 (Mon, 05 Apr 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_sub.c
+
+fixed problem (cmpabs doesn't work for x=0)
+
+------------------------------------------------------------------------
+r2858 | pelissip | 2004-03-26 13:27:16 +0000 (Fri, 26 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/add_one_ulp.c
+ M /trunk/check.c
+ M /trunk/cmp2.c
+ M /trunk/div_ui.c
+ M /trunk/exp.c
+ M /trunk/next.c
+ M /trunk/random2.c
+ M /trunk/round_prec.c
+ M /trunk/set_d.c
+ M /trunk/set_z.c
+ M /trunk/sqrt.c
+ M /trunk/sub1.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/trandom.c
+ M /trunk/urandomb.c
+
+Change from MP_LIMB_T_ONE to MPFR_LIMB_ONE and/or MPFR_LIMB_MASK.
+
+------------------------------------------------------------------------
+r2857 | pelissip | 2004-03-26 13:26:29 +0000 (Fri, 26 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/init2.c
+
+Improve comments.
+
+------------------------------------------------------------------------
+r2856 | pelissip | 2004-03-26 13:24:58 +0000 (Fri, 26 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/tests/tgmpop.c
+
+Fix a bug.
+
+------------------------------------------------------------------------
+r2855 | pelissip | 2004-03-26 13:24:14 +0000 (Fri, 26 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+Move detecting macros (__MPFR_GCC, __MPFR_STDC, __MPFR_GLIBC and __MPFR_GMP) from mpfr to mpfr-impl
+
+------------------------------------------------------------------------
+r2854 | zimmerma | 2004-03-22 10:54:28 +0000 (Mon, 22 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+removed blank
+
+------------------------------------------------------------------------
+r2853 | vlefevre | 2004-03-22 10:20:16 +0000 (Mon, 22 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+
+Test write access to CVS.
+
+------------------------------------------------------------------------
+r2852 | pelissip | 2004-03-18 09:57:51 +0000 (Thu, 18 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-gmp.c
+
+Fix a bug in a string.
+
+------------------------------------------------------------------------
+r2851 | pelissip | 2004-03-17 15:50:27 +0000 (Wed, 17 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add documentation of 'j' functions.
+
+------------------------------------------------------------------------
+r2850 | pelissip | 2004-03-17 12:40:01 +0000 (Wed, 17 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Fix (?) definition of MPFR_PREC_MAX.
+
+------------------------------------------------------------------------
+r2849 | pelissip | 2004-03-17 09:45:26 +0000 (Wed, 17 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+Change the order of the tests.
+
+------------------------------------------------------------------------
+r2848 | pelissip | 2004-03-17 08:45:08 +0000 (Wed, 17 Mar 2004) | 4 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/exp3.c
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/texp.c
+
+Rename mpfr_exp3 in mpfr_exp_3.
+Update THRESHOLD for mpfr_exp.
+Add MPFR_EXP_THRESHOLD.
+
+------------------------------------------------------------------------
+r2847 | pelissip | 2004-03-16 15:24:50 +0000 (Tue, 16 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Add new option "--with-gmp-build="
+
+------------------------------------------------------------------------
+r2846 | pelissip | 2004-03-16 15:24:26 +0000 (Tue, 16 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Update INSTALL
+
+------------------------------------------------------------------------
+r2845 | pelissip | 2004-03-16 13:44:38 +0000 (Tue, 16 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Fix a bug (Forget to cast to mp_exp_t).
+
+------------------------------------------------------------------------
+r2844 | pelissip | 2004-03-16 10:45:49 +0000 (Tue, 16 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/swap.c
+
+Update comment
+
+------------------------------------------------------------------------
+r2843 | pelissip | 2004-03-16 10:43:24 +0000 (Tue, 16 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/get_z.c
+ M /trunk/mpfr.h
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tget_z.c
+
+Add mpz_set_fr function and its test.
+
+------------------------------------------------------------------------
+r2842 | pelissip | 2004-03-15 14:09:49 +0000 (Mon, 15 Mar 2004) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ A /trunk/set_sj.c
+ A /trunk/set_uj.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tset_sj.c
+
+Add new functions:
+ mpfr_set_sj_2exp, mpfr_set_sj
+ mpfr_set_uj_2exp, mpfr_set_uj
+
+------------------------------------------------------------------------
+r2841 | pelissip | 2004-03-15 14:08:54 +0000 (Mon, 15 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/sub1sp.c
+
+Fix a compiler bug (limb !=0 instead of limb).
+
+------------------------------------------------------------------------
+r2840 | pelissip | 2004-03-15 13:26:42 +0000 (Mon, 15 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/print_raw.c
+
+Fix a cast problem on some systems (sizeof(mp_limb_t) > sizeof(unsigned long)).
+
+------------------------------------------------------------------------
+r2839 | pelissip | 2004-03-12 17:45:07 +0000 (Fri, 12 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd1sp.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tsub1sp.c
+
+Remove use of abort (They can create core dump on some systems).
+
+------------------------------------------------------------------------
+r2838 | pelissip | 2004-03-12 13:17:53 +0000 (Fri, 12 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/tests/tacos.c
+
+Fix bug of inexact flag for acos(0).
+
+------------------------------------------------------------------------
+r2837 | pelissip | 2004-03-12 12:51:09 +0000 (Fri, 12 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/tests/memory.c
+
+Update.
+
+------------------------------------------------------------------------
+r2836 | pelissip | 2004-03-11 12:39:08 +0000 (Thu, 11 Mar 2004) | 3 lines
+Changed paths:
+ M /trunk/si_op.c
+ M /trunk/tests/tsi_op.c
+
+Fix bug about forgotten MPFR_INVERT_RND.
+Add test too.
+
+------------------------------------------------------------------------
+r2835 | pelissip | 2004-03-11 12:38:33 +0000 (Thu, 11 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Add doc about HAVE_STDINT_H
+
+------------------------------------------------------------------------
+r2834 | pelissip | 2004-03-10 16:16:28 +0000 (Wed, 10 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix doc about MPFR_DECL_INIT.
+
+------------------------------------------------------------------------
+r2833 | pelissip | 2004-03-10 15:31:42 +0000 (Wed, 10 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Fix the declaration of 'MPFR_DECL_INIT'
+
+------------------------------------------------------------------------
+r2832 | pelissip | 2004-03-10 14:58:16 +0000 (Wed, 10 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/init2.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+Add 'MPFR_DECL_INIT' macro.
+
+------------------------------------------------------------------------
+r2831 | pelissip | 2004-03-10 10:16:51 +0000 (Wed, 10 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/rint.c
+
+Rename NEAREST_AWAY in GMP_RNDNA.
+
+------------------------------------------------------------------------
+r2830 | pelissip | 2004-03-10 09:35:45 +0000 (Wed, 10 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add the description of mpfr_set_ui_2exp and mpfr_set_si_2exp.
+
+------------------------------------------------------------------------
+r2829 | pelissip | 2004-03-09 17:31:29 +0000 (Tue, 09 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ A /trunk/set_si_2exp.c
+ A /trunk/set_ui_2exp.c
+ M /trunk/tests/tset_si.c
+
+Add mpfr_set_si_2exp and mpfr_set_ui_2exp and their tests.
+
+------------------------------------------------------------------------
+r2828 | pelissip | 2004-03-09 15:20:01 +0000 (Tue, 09 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add doc about mpfr_cmp_f function
+
+------------------------------------------------------------------------
+r2827 | pelissip | 2004-03-09 15:18:17 +0000 (Tue, 09 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/mpfr.h
+ M /trunk/set_f.c
+ M /trunk/tests/tgmpop.c
+
+Add mpfr_cmp_f and its test.
+
+------------------------------------------------------------------------
+r2826 | pelissip | 2004-03-09 14:11:27 +0000 (Tue, 09 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/cmp_ld.c
+ M /trunk/mpfr.h
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tcmp_d.c
+ A /trunk/tests/tcmp_ld.c
+
+Add mpfr_cmp_ld and its test
+
+------------------------------------------------------------------------
+r2825 | pelissip | 2004-03-09 13:58:39 +0000 (Tue, 09 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Add doc of 2 macros.
+
+------------------------------------------------------------------------
+r2824 | pelissip | 2004-03-09 13:51:50 +0000 (Tue, 09 Mar 2004) | 3 lines
+Changed paths:
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/mpfr.h
+
+Add mpfr_cmp_ui and mpfr_cmp_si as real functions
+(The macros are still defined and used).
+
+------------------------------------------------------------------------
+r2823 | pelissip | 2004-03-09 13:43:31 +0000 (Tue, 09 Mar 2004) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/si_op.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tsi_op.c
+
+Add mpfr_add_si, mpfr_sub_si, mpfr_si_sub, mpfr_mul_si, mpfr_div_si and
+mpfr_si_div.
+Add the corresponding test.
+
+------------------------------------------------------------------------
+r2822 | pelissip | 2004-03-09 11:02:34 +0000 (Tue, 09 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tgmpop.c
+
+Add `mpfr_cmp_q` and `mpfr_cmp_z`.
+
+------------------------------------------------------------------------
+r2821 | pelissip | 2004-03-09 10:06:01 +0000 (Tue, 09 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Clean up configure
+
+------------------------------------------------------------------------
+r2820 | pelissip | 2004-03-09 09:51:08 +0000 (Tue, 09 Mar 2004) | 2 lines
+Changed paths:
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+
+Add ASSERT for NAN.
+
+------------------------------------------------------------------------
+r2819 | pelissip | 2004-02-27 12:41:37 +0000 (Fri, 27 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add documentation for MPFR_VERSION
+
+------------------------------------------------------------------------
+r2818 | pelissip | 2004-02-26 11:20:49 +0000 (Thu, 26 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Optimize a few mpfr_mul.
+
+------------------------------------------------------------------------
+r2817 | pelissip | 2004-02-26 10:05:12 +0000 (Thu, 26 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+Add Laurent Fousse in the AUTHORS file.
+
+------------------------------------------------------------------------
+r2816 | vlefevre | 2004-02-26 09:56:02 +0000 (Thu, 26 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Fixed a bug in check2b and added a test; add1.c coverage is now
+complete.
+
+------------------------------------------------------------------------
+r2815 | vlefevre | 2004-02-25 16:30:33 +0000 (Wed, 25 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Improved coverage.
+
+------------------------------------------------------------------------
+r2814 | vlefevre | 2004-02-25 16:00:58 +0000 (Wed, 25 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Improved coverage.
+
+------------------------------------------------------------------------
+r2813 | vlefevre | 2004-02-25 15:44:56 +0000 (Wed, 25 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Bugs fixed in a test function -> improved coverage.
+
+------------------------------------------------------------------------
+r2812 | pelissip | 2004-02-25 15:02:22 +0000 (Wed, 25 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/round_raw_generic.c
+
+Optimize mpfr_round_raw_?
+
+------------------------------------------------------------------------
+r2811 | pelissip | 2004-02-25 10:57:16 +0000 (Wed, 25 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/add1sp.c
+ M /trunk/sgn.c
+ M /trunk/sub1sp.c
+
+Simplify the code.
+
+------------------------------------------------------------------------
+r2808 | vlefevre | 2004-02-24 14:51:42 +0000 (Tue, 24 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+Avoid integer overflow.
+
+------------------------------------------------------------------------
+r2807 | vlefevre | 2004-02-24 14:44:38 +0000 (Tue, 24 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+Ported code clean-up to trunk.
+
+------------------------------------------------------------------------
+r2802 | pelissip | 2004-02-24 13:23:35 +0000 (Tue, 24 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/add1sp.c
+ M /trunk/div.c
+ M /trunk/eq.c
+ M /trunk/frac.c
+ M /trunk/log10.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/set_d.c
+ M /trunk/set_str.c
+ M /trunk/sin.c
+ M /trunk/sqrt.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sum.c
+ M /trunk/tests/tests.c
+
+Remove some warnings.
+MPFR can be compiled (but not checked!) with a C++ compiler.
+
+------------------------------------------------------------------------
+r2797 | pelissip | 2004-02-24 09:12:03 +0000 (Tue, 24 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tzeta.c
+
+Improve test coverage.
+
+------------------------------------------------------------------------
+r2796 | zimmerma | 2004-02-24 08:14:39 +0000 (Tue, 24 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+further simplification of the code (replaced one in-place shift and copy
+by out-of-place shift or copy)
+
+------------------------------------------------------------------------
+r2795 | zimmerma | 2004-02-23 16:47:46 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tui_div.c
+
+use GMP_RND_MAX instead of hard-coded constant
+
+------------------------------------------------------------------------
+r2794 | zimmerma | 2004-02-23 16:23:59 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/tests/tdiv.c
+
+simplified the code of div.c and improved coverage
+
+------------------------------------------------------------------------
+r2792 | pelissip | 2004-02-23 14:20:32 +0000 (Mon, 23 Feb 2004) | 3 lines
+Changed paths:
+ D /trunk/longlong.h
+ M /trunk/mpfr-impl.h
+ A /trunk/mpfr-longlong.h
+
+Rename 'longlong.h' in 'mpfr-longlong.h' so that when MPFR is built
+within GMP it uses GMP's 'longlong.h' rather than MPFR's copy.
+
+------------------------------------------------------------------------
+r2791 | vlefevre | 2004-02-23 14:19:02 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r2789 | pelissip | 2004-02-23 14:09:10 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ A /trunk/free_cache.c
+
+Add mpfr_free_cache (2).
+
+------------------------------------------------------------------------
+r2788 | pelissip | 2004-02-23 14:08:44 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tests.c
+
+Add mpfr_free_cache.
+
+------------------------------------------------------------------------
+r2787 | pelissip | 2004-02-23 13:51:41 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_str.c
+
+Add mpfr_free_str function.
+
+------------------------------------------------------------------------
+r2786 | pelissip | 2004-02-23 12:14:40 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Remove a warning.
+
+------------------------------------------------------------------------
+r2785 | pelissip | 2004-02-23 12:14:29 +0000 (Mon, 23 Feb 2004) | 4 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Reorder the declarations of the functions.
+Remove duplicate declarations.
+Remove mpfr_factorial.
+
+------------------------------------------------------------------------
+r2784 | zimmerma | 2004-02-23 10:01:42 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+patch from Guillaume Hanrot
+
+------------------------------------------------------------------------
+r2783 | pelissip | 2004-02-23 09:43:29 +0000 (Mon, 23 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/pow_ui.c
+ M /trunk/set_str.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+
+Improve coverage tests.
+Fix 2 underflow bugs.
+
+------------------------------------------------------------------------
+r2782 | pelissip | 2004-02-23 09:42:29 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+Update comment
+
+------------------------------------------------------------------------
+r2781 | pelissip | 2004-02-23 09:42:04 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Improve comments.
+
+------------------------------------------------------------------------
+r2780 | pelissip | 2004-02-23 09:41:28 +0000 (Mon, 23 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Add a comment.
+
+------------------------------------------------------------------------
+r2779 | vlefevre | 2004-02-22 01:48:32 +0000 (Sun, 22 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Added tests.
+
+------------------------------------------------------------------------
+r2775 | fousse | 2004-02-20 13:15:44 +0000 (Fri, 20 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/sum.c
+ M /trunk/tests/tsum.c
+
+Changed mpfr_sum to use unsigned long instead of unsigned int. More tests.
+
+------------------------------------------------------------------------
+r2774 | pelissip | 2004-02-20 12:58:30 +0000 (Fri, 20 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/neg.c
+ M /trunk/tests/tset.c
+
+mpfr_neg (b, b, r) for b=NAN didnt' set NAN flag.
+
+------------------------------------------------------------------------
+r2773 | pelissip | 2004-02-20 10:49:34 +0000 (Fri, 20 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr_sgn is no longer a macro.
+
+------------------------------------------------------------------------
+r2770 | pelissip | 2004-02-19 12:33:47 +0000 (Thu, 19 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/tests/tgmpop.c
+
+Fix bug with exact rationnal arguments (0.5+3/2 freezes).
+
+------------------------------------------------------------------------
+r2767 | vlefevre | 2004-02-18 12:47:00 +0000 (Wed, 18 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/config.guess
+ M /trunk/config.sub
+
+Update from the autotools-dev Debian package (2004-01-05).
+
+------------------------------------------------------------------------
+r2761 | vlefevre | 2004-02-18 10:41:00 +0000 (Wed, 18 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+ M /trunk/tests/tset_f.c
+
+Fixed a bug in mpfr_set_f for 0 (wrong sign) and added the test.
+
+------------------------------------------------------------------------
+r2760 | pelissip | 2004-02-18 10:29:40 +0000 (Wed, 18 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+Fix bug if you build MPFR with ASSERT.
+
+------------------------------------------------------------------------
+r2759 | pelissip | 2004-02-17 14:39:16 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Reduce the number of used variables.
+
+------------------------------------------------------------------------
+r2758 | zimmerma | 2004-02-17 14:29:28 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/round_raw_generic.c
+
+improved again documentation
+
+------------------------------------------------------------------------
+r2757 | zimmerma | 2004-02-17 14:27:06 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+simplified rounding
+
+------------------------------------------------------------------------
+r2756 | zimmerma | 2004-02-17 14:17:31 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/round_raw_generic.c
+
+improved documentation of *inexp
+
+------------------------------------------------------------------------
+r2752 | pelissip | 2004-02-17 12:12:21 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub1sp.c
+
+Simplify the random code.
+
+------------------------------------------------------------------------
+r2751 | pelissip | 2004-02-17 12:12:02 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+Optimize it a few.
+
+------------------------------------------------------------------------
+r2750 | pelissip | 2004-02-17 12:11:49 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/round_raw_generic.c
+
+Add 2004 in copyright line.
+
+------------------------------------------------------------------------
+r2749 | pelissip | 2004-02-17 12:11:26 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Add a section which describes the needed macros for building MPFR.
+
+------------------------------------------------------------------------
+r2747 | zimmerma | 2004-02-17 11:21:04 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+added comment about probability of normalized product
+
+------------------------------------------------------------------------
+r2744 | vlefevre | 2004-02-17 10:36:11 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Added a note about the ternary value, important in practice.
+
+------------------------------------------------------------------------
+r2743 | zimmerma | 2004-02-17 10:02:29 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+ M /trunk/tests/tset_f.c
+
+fixed 2 bugs and added test
+
+------------------------------------------------------------------------
+r2742 | zimmerma | 2004-02-17 10:01:18 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/round_raw_generic.c
+
+added comment about return value
+
+------------------------------------------------------------------------
+r2741 | pelissip | 2004-02-17 08:57:19 +0000 (Tue, 17 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Try so support GMP as a Shared Library.
+
+------------------------------------------------------------------------
+r2740 | zimmerma | 2004-02-16 18:23:49 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+improved error message
+
+------------------------------------------------------------------------
+r2739 | pelissip | 2004-02-16 18:02:42 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+
+Fix the computing of the error for mpq_add and mpq_sub.
+
+------------------------------------------------------------------------
+r2738 | vlefevre | 2004-02-16 17:57:38 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Added more tests (improved tadd1.c coverage).
+
+------------------------------------------------------------------------
+r2737 | zimmerma | 2004-02-16 17:47:59 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+added cancellation test for add_q
+
+------------------------------------------------------------------------
+r2736 | vlefevre | 2004-02-16 17:37:59 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Added tests (improved tadd1.c coverage).
+
+------------------------------------------------------------------------
+r2735 | pelissip | 2004-02-16 17:35:26 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/tests/tgmpop.c
+
+Fix bug of add_q and sub_q with special values (NAN, INF and ZERO).
+
+------------------------------------------------------------------------
+r2734 | zimmerma | 2004-02-16 17:12:45 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/set_d.c
+ M /trunk/set_q.c
+
+deal with overflow/underflow in mpfr_div
+
+------------------------------------------------------------------------
+r2733 | zimmerma | 2004-02-16 17:04:34 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tgmpop.c
+
+added hard-coded tests
+
+------------------------------------------------------------------------
+r2732 | vlefevre | 2004-02-16 16:50:31 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+When the precisions are the same, test both mpfr_add1sp and mpfr_add1.
+
+------------------------------------------------------------------------
+r2731 | vlefevre | 2004-02-16 16:34:39 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Added overflow check.
+
+------------------------------------------------------------------------
+r2730 | pelissip | 2004-02-16 16:17:38 +0000 (Mon, 16 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/add1sp.c
+ M /trunk/div.c
+ M /trunk/sub1sp.c
+ M /trunk/tests/tsub1sp.c
+
+Optimize add1sp, sub1sp and div.
+Improve coverage test for sub1sp.
+
+------------------------------------------------------------------------
+r2729 | vlefevre | 2004-02-16 16:06:11 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+Removed unused label.
+
+------------------------------------------------------------------------
+r2727 | vlefevre | 2004-02-16 15:05:18 +0000 (Mon, 16 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+
+Really reverted to rev. 1.54 + kept optimization + commented out
+is_odd_even.
+
+------------------------------------------------------------------------
+r2725 | zimmerma | 2004-02-16 14:30:43 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+ M /trunk/set_ld.c
+
+take into account possible out-of-range exponent
+
+------------------------------------------------------------------------
+r2724 | zimmerma | 2004-02-16 14:24:48 +0000 (Mon, 16 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+
+revert to rev 1.54 code for case x infinite
+(was less efficient but simpler)
+
+------------------------------------------------------------------------
+r2723 | zimmerma | 2004-02-16 13:56:42 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+fixed bug with in-place computation
+
+------------------------------------------------------------------------
+r2722 | vlefevre | 2004-02-16 13:55:27 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tsqrt.c
+
+Code clean-up and fix to avoid warnings.
+
+------------------------------------------------------------------------
+r2721 | zimmerma | 2004-02-16 13:35:20 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/pow.c
+ M /trunk/tests/tpow.c
+
+changed back to C99 standard for special values of x^y
+
+------------------------------------------------------------------------
+r2720 | zimmerma | 2004-02-16 11:33:24 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/trint.c
+
+added test for *function* mpfr_round
+
+------------------------------------------------------------------------
+r2719 | zimmerma | 2004-02-16 11:06:06 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tinp_str.c
+ M /trunk/tests/tout_str.c
+
+check return value of fopen
+
+------------------------------------------------------------------------
+r2718 | vlefevre | 2004-02-16 11:01:38 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+Removed the no longer used label "fin" and fixed the indentation.
+
+------------------------------------------------------------------------
+r2717 | vlefevre | 2004-02-16 10:55:36 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+Fix: MPFR_NOT_ZERO -> MPFR_NOTZERO.
+
+------------------------------------------------------------------------
+r2716 | vlefevre | 2004-02-16 10:52:40 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+Commented out the now useless "double uo, vo;".
+
+------------------------------------------------------------------------
+r2715 | zimmerma | 2004-02-16 10:41:02 +0000 (Mon, 16 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tzeta.c
+ M /trunk/zeta.c
+
+improved coverage tests
+
+------------------------------------------------------------------------
+r2714 | zimmerma | 2004-02-14 23:05:51 +0000 (Sat, 14 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/mpfr.texi
+ M /trunk/set_d.c
+ M /trunk/set_q.c
+ M /trunk/set_str_raw.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tset_d.c
+ A /trunk/tests/tset_exp.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+
+new coverage tests
+
+------------------------------------------------------------------------
+r2713 | zimmerma | 2004-02-14 11:11:31 +0000 (Sat, 14 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+ M /trunk/inp_str.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/mpfr.texi
+ M /trunk/mpn_exp.c
+ M /trunk/mul_ui.c
+ M /trunk/next.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/set.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/inp_str.data
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/thypot.c
+ A /trunk/tests/tinp_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset.c
+
+improved coverage test
+
+------------------------------------------------------------------------
+r2712 | zimmerma | 2004-02-13 17:39:02 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tset_si.c
+
+improved coverage test
+
+------------------------------------------------------------------------
+r2711 | zimmerma | 2004-02-13 17:17:52 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/tests/tget_str.c
+
+improved test coverage
+
+------------------------------------------------------------------------
+r2710 | zimmerma | 2004-02-13 16:00:10 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+improved test coverage
+
+------------------------------------------------------------------------
+r2709 | zimmerma | 2004-02-13 15:35:19 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+ M /trunk/tests/texp.c
+
+improved test coverage
+
+------------------------------------------------------------------------
+r2708 | pelissip | 2004-02-13 15:05:42 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd1sp.c
+
+Fix a bug in taddsp (Forget to check if random does not generate zero).
+
+------------------------------------------------------------------------
+r2707 | zimmerma | 2004-02-13 13:57:24 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/teq.c
+
+improved editing style
+
+------------------------------------------------------------------------
+r2706 | zimmerma | 2004-02-13 13:44:41 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/div_ui.c
+ M /trunk/tests/tdiv_ui.c
+
+improved test coverage
+
+------------------------------------------------------------------------
+r2705 | zimmerma | 2004-02-13 13:43:27 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/eq.c
+ M /trunk/tests/teq.c
+
+partly rewritten, and improved test coverage
+
+------------------------------------------------------------------------
+r2704 | vlefevre | 2004-02-13 13:33:10 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+Added tests for mpfr_mul_2si and mpfr_div_2si + corrections.
+
+------------------------------------------------------------------------
+r2703 | vlefevre | 2004-02-13 12:31:49 +0000 (Fri, 13 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+Replaced mpfr_mul_2exp and mpfr_div_2exp by mpfr_mul_2ui and
+mpfr_div_2ui as the 2exp form is obsolete.
+
+------------------------------------------------------------------------
+r2702 | zimmerma | 2004-02-13 12:25:14 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tfactorial.c
+
+removed warnings
+
+------------------------------------------------------------------------
+r2701 | pelissip | 2004-02-13 11:30:05 +0000 (Fri, 13 Feb 2004) | 5 lines
+Changed paths:
+ M /trunk/check.c
+ M /trunk/cmp_abs.c
+ M /trunk/set.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tcmpabs.c
+ M /trunk/tests/texceptions.c
+ A /trunk/tests/tfits.c
+ A /trunk/tests/toutimpl.c
+
+Add test for mpfr_cmpabs
+Add test for mpfr_fits_
+Add test for internal dumping functions.
+Improve coverage test for exceptions / set / check.
+
+------------------------------------------------------------------------
+r2700 | zimmerma | 2004-02-13 10:52:11 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+ M /trunk/tests/tconst_pi.c
+
+improved coverage
+
+------------------------------------------------------------------------
+r2699 | zimmerma | 2004-02-13 10:31:42 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+removed Kevin, added missing accent
+
+------------------------------------------------------------------------
+r2698 | zimmerma | 2004-02-13 09:33:55 +0000 (Fri, 13 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_ui.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/uceil_exp2.c
+
+improved coverage test
+
+------------------------------------------------------------------------
+r2697 | pelissip | 2004-02-12 18:02:28 +0000 (Thu, 12 Feb 2004) | 4 lines
+Changed paths:
+ M /trunk/dump.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr.h
+
+Rewrite (simplify) mpfr_dump.
+Change its proto.
+Fix mpf_dump macro in mpf2mpfr.
+
+------------------------------------------------------------------------
+r2696 | pelissip | 2004-02-12 17:58:40 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/div.c
+ M /trunk/mul.c
+ M /trunk/sub.c
+
+Remove MPFR_ASSERTN(0) and add MPFR_ASSERTD(last condition) instead.
+
+------------------------------------------------------------------------
+r2695 | zimmerma | 2004-02-12 16:54:28 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+improved coverage
+
+------------------------------------------------------------------------
+r2694 | zimmerma | 2004-02-12 16:38:06 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+
+improved coverage
+
+------------------------------------------------------------------------
+r2693 | zimmerma | 2004-02-12 16:25:29 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+improved cov. test
+
+------------------------------------------------------------------------
+r2692 | zimmerma | 2004-02-12 16:08:00 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+improved cov. test
+
+------------------------------------------------------------------------
+r2691 | zimmerma | 2004-02-12 16:01:26 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+ M /trunk/tests/tfma.c
+
+improved coverage test
+
+------------------------------------------------------------------------
+r2690 | zimmerma | 2004-02-12 15:05:14 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/factorial.c
+ M /trunk/tests/tfactorial.c
+
+improved coverage test
+
+------------------------------------------------------------------------
+r2689 | zimmerma | 2004-02-12 14:30:20 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/expm1.c
+ M /trunk/tests/texpm1.c
+
+improved test coverage
+
+------------------------------------------------------------------------
+r2688 | pelissip | 2004-02-12 14:20:43 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+
+Improve coverage of const_pi and const_log2 (Test for prec > 20000).
+
+------------------------------------------------------------------------
+r2687 | zimmerma | 2004-02-12 14:08:06 +0000 (Thu, 12 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/tests/texp.c
+
+fixed tiny bugs for corner cases
+improved test coverage
+
+------------------------------------------------------------------------
+r2686 | pelissip | 2004-02-12 13:49:44 +0000 (Thu, 12 Feb 2004) | 6 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/add.c
+ A /trunk/add1sp.c
+ M /trunk/copysign.c
+ M /trunk/div_2ui.c
+ M /trunk/mpfr-impl.h
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tadd1sp.c
+ A /trunk/tests/tcopysign.c
+ M /trunk/tests/tdim.c
+ M /trunk/tests/texp.c
+ A /trunk/tests/tminmax.c
+ M /trunk/tests/tmul_2exp.c
+
++ Add mpfr_add1sp which provides addition when all the operands have the same precision.
++ Add new test files for mpfr_copysign and mpfr_min and mpfr_max.
++ Add test for mpfr_exp10 in tests/texp.c
++ Improve coverage of div_2ui.c and mul_2ui.c
++ Add a forgotten ASSERT in mpfr_sqrt
+
+------------------------------------------------------------------------
+r2685 | zimmerma | 2004-02-12 13:20:50 +0000 (Thu, 12 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/tests/texp2.c
+
+improved test coverage
+replaced mpfr_get_d1 by mpfr_get_si
+
+------------------------------------------------------------------------
+r2684 | zimmerma | 2004-02-12 12:54:48 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/erf.c
+ M /trunk/tests/terf.c
+
+improved coverage test
+
+------------------------------------------------------------------------
+r2683 | zimmerma | 2004-02-12 12:38:17 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+added new coverage test
+
+------------------------------------------------------------------------
+r2682 | pelissip | 2004-02-12 11:42:34 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Fix some mistakes.
+
+------------------------------------------------------------------------
+r2681 | pelissip | 2004-02-12 11:38:49 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Add a description of the gcov tool.
+
+------------------------------------------------------------------------
+r2680 | zimmerma | 2004-02-12 11:35:50 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+now 100% of coverage of sub1.c
+
+------------------------------------------------------------------------
+r2679 | zimmerma | 2004-02-12 11:06:02 +0000 (Thu, 12 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/dim.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tdim.c
+
+new test file for mpfr_dim
+
+------------------------------------------------------------------------
+r2672 | pelissip | 2004-02-06 15:57:28 +0000 (Fri, 06 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Replace AS_HELP_STRING to AC_HELP_STRING (obsolete)
+
+------------------------------------------------------------------------
+r2671 | pelissip | 2004-02-06 15:37:40 +0000 (Fri, 06 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/add1.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asinh.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/const_pi.c
+ M /trunk/copysign.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/dump.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/fma.c
+ M /trunk/get_exp.c
+ M /trunk/get_z_exp.c
+ M /trunk/init.c
+ M /trunk/inits.c
+ M /trunk/inp_str.c
+ M /trunk/isinf.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/log1p.c
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/powerof2.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/set.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_inf.c
+ M /trunk/set_q.c
+ M /trunk/set_si.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sgn.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub_ui.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/volatile.c
+
+Add forgotten copyright 2004 line.
+Add a small documentation about mpfr_sum.
+
+------------------------------------------------------------------------
+r2668 | pelissip | 2004-02-06 13:59:56 +0000 (Fri, 06 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ A /trunk/sum.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tsum.c
+
+Added mpfr_sum function.
+
+------------------------------------------------------------------------
+r2665 | pelissip | 2004-02-06 13:27:05 +0000 (Fri, 06 Feb 2004) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/acinclude.m4
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add_one_ulp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/clear.c
+ M /trunk/clears.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_d.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/comparisons.c
+ M /trunk/configure.in
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp10.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/fits_s.h
+ M /trunk/fits_u.h
+ M /trunk/fma.c
+ M /trunk/frac.c
+ M /trunk/gamma.c
+ M /trunk/get_d.c
+ M /trunk/get_exp.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_z_exp.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+ M /trunk/inp_str.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ A /trunk/longlong.h
+ M /trunk/minmax.c
+ A /trunk/mp_clz_tab.c
+ A /trunk/mpfr-gmp.c
+ A /trunk/mpfr-gmp.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpn_exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/next.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/powerof2.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/save_expo.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sgn.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub1sp.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/sub_ui.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/memory.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/uceil_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/version.c
+ M /trunk/volatile.c
+
++ Better support of non IEEE doubles.
++ You can compile MPFR without gmp internal files (ie gmp-impl.h, gmp-mparam.h, and config.h). You only need gmp.h and libgmp.a. But you can still compile with GMP internal files (configure detects them).
+
+------------------------------------------------------------------------
+r2664 | vlefevre | 2004-02-06 13:06:36 +0000 (Fri, 06 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r2660 | vlefevre | 2004-02-06 10:54:26 +0000 (Fri, 06 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Updated MPFR URL.
+
+------------------------------------------------------------------------
+r2659 | vlefevre | 2004-02-06 10:49:54 +0000 (Fri, 06 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+Added the changes from version 2.0.1 to version 2.0.2.
+
+------------------------------------------------------------------------
+r2657 | vlefevre | 2004-02-06 10:14:00 +0000 (Fri, 06 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Added: "3) Update the NEWS file.".
+
+------------------------------------------------------------------------
+r2655 | zimmerma | 2004-02-03 10:06:53 +0000 (Tue, 03 Feb 2004) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_str.c
+
+fixed bug in get_str (case pow2, rnd=up or down)
+
+------------------------------------------------------------------------
+r2654 | zimmerma | 2004-01-30 16:27:35 +0000 (Fri, 30 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+ M /trunk/zeta.c
+
+fixed problem (s1 = s-1 inexact)
+
+------------------------------------------------------------------------
+r2653 | zimmerma | 2004-01-30 15:06:42 +0000 (Fri, 30 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/factorial.c
+ M /trunk/gamma.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tgamma.c
+
+fixed problem in gamma/factorial
+
+------------------------------------------------------------------------
+r2652 | zimmerma | 2004-01-30 12:51:58 +0000 (Fri, 30 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/hypot.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/thypot.c
+
+added new tests for agm and hypot (+ fixed bugs)
+
+------------------------------------------------------------------------
+r2651 | pelissip | 2004-01-29 16:12:42 +0000 (Thu, 29 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Add GMP_RND_MAX so that a for loop of the rounding modes looks like:
+ for(int r = 0 ; r < GMP_RND_MAX ; r++)
+
+------------------------------------------------------------------------
+r2650 | pelissip | 2004-01-28 14:22:05 +0000 (Wed, 28 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set_d.c
+ M /trunk/set_ld.c
+ M /trunk/sub1sp.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+ M /trunk/uceil_exp2.c
+ M /trunk/ufloor_log2.c
+
+Better supports of non IEEE-754 floats (don't use anymore ieee_double_extract if _GMP_IEEE is not set).
+
+------------------------------------------------------------------------
+r2649 | vlefevre | 2004-01-28 11:32:57 +0000 (Wed, 28 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/frac.c
+
+Added comments and a temporary fix.
+
+------------------------------------------------------------------------
+r2648 | zimmerma | 2004-01-27 08:00:00 +0000 (Tue, 27 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/cbrt.c
+ M /trunk/erf.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tzeta.c
+
+fixed bugs in atan cbrt erf
+added new hard-coded tests
+
+------------------------------------------------------------------------
+r2647 | zimmerma | 2004-01-26 13:14:55 +0000 (Mon, 26 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+removed argument reduction in sin(Pi*s/2) [delegated to mpfr_sin]
+
+------------------------------------------------------------------------
+r2646 | zimmerma | 2004-01-26 13:11:54 +0000 (Mon, 26 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+print inputs of test2 in binary form
+commented out test for 0.8 (input is not exactly representable)
+
+------------------------------------------------------------------------
+r2645 | pelissip | 2004-01-26 11:45:21 +0000 (Mon, 26 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+ M /trunk/zeta.c
+
++ Internal functions of zeta are now declared as static.
++ Add new tests which fail.
+
+------------------------------------------------------------------------
+r2644 | zimmerma | 2004-01-22 22:30:52 +0000 (Thu, 22 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/algorithms.tex
+ M /trunk/asin.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/erf.c
+ M /trunk/exp_2.c
+ M /trunk/frac.c
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/trint.c
+
+added several hard-coded tests (and fixed bugs found)
+
+------------------------------------------------------------------------
+r2643 | pelissip | 2004-01-20 13:08:53 +0000 (Tue, 20 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fix tiny bug of Concept Index / Rounding Modes.
+
+------------------------------------------------------------------------
+r2642 | pelissip | 2004-01-20 13:04:30 +0000 (Tue, 20 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update minor things.
+
+------------------------------------------------------------------------
+r2641 | zimmerma | 2004-01-20 11:07:48 +0000 (Tue, 20 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+minor change in contributions
+
+------------------------------------------------------------------------
+r2640 | zimmerma | 2004-01-20 10:56:59 +0000 (Tue, 20 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added Patrick in the main contributors
+
+------------------------------------------------------------------------
+r2639 | vlefevre | 2004-01-20 10:08:27 +0000 (Tue, 20 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Fixed spelling mistake.
+
+------------------------------------------------------------------------
+r2638 | pelissip | 2004-01-20 09:15:19 +0000 (Tue, 20 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Reorder the documentation.
+
+------------------------------------------------------------------------
+r2637 | ryde | 2004-01-19 23:51:46 +0000 (Mon, 19 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+# Add a remark to mpf_strto.
+
+------------------------------------------------------------------------
+r2636 | ryde | 2004-01-19 23:31:56 +0000 (Mon, 19 Jan 2004) | 4 lines
+Changed paths:
+ M /trunk/TODO
+
+# Drop my thought about addmul instead of fma. The latter takes a
+# separate destination and is hence not the same as what mpn and mpz
+# addmul do.
+
+------------------------------------------------------------------------
+r2635 | pelissip | 2004-01-19 16:06:34 +0000 (Mon, 19 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tset_d.c
+
+Update tests to remove the use of double when possible.
+
+------------------------------------------------------------------------
+r2634 | pelissip | 2004-01-19 16:05:24 +0000 (Mon, 19 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+Reenable the cmp between inexact flags.
+
+------------------------------------------------------------------------
+r2633 | pelissip | 2004-01-19 16:03:30 +0000 (Mon, 19 Jan 2004) | 4 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/set_rnd.c
+ M /trunk/tests/texceptions.c
+
+Add mpfr_get_default_rounding_mode.
+Add the tests for mpfr_get/set_default_rounding_mode.
+Fix mpfr_set_default_rounding_mode.
+
+------------------------------------------------------------------------
+r2632 | vlefevre | 2004-01-19 03:01:10 +0000 (Mon, 19 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+_mpfr_ceil -> mpfr_ceil_double + check for overflow.
+
+------------------------------------------------------------------------
+r2631 | vlefevre | 2004-01-19 02:39:21 +0000 (Mon, 19 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/get_str.c
+ A /trunk/mpn_exp.c
+
+Moved the mpfr_mpn_exp function to a new file "mpn_exp.c" as it is
+used by both "get_str.c" and "set_str.c".
+
+------------------------------------------------------------------------
+r2630 | pelissip | 2004-01-16 15:55:15 +0000 (Fri, 16 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+Update it to remove the use of float/double.
+
+------------------------------------------------------------------------
+r2629 | pelissip | 2004-01-15 16:57:35 +0000 (Thu, 15 Jan 2004) | 2 lines
+Changed paths:
+ D /trunk/from_Torbjorn
+ M /trunk/get_str.c
+ M /trunk/tests/tget_str.c
+
+Add a new check in tget_str.c.
+
+------------------------------------------------------------------------
+r2628 | pelissip | 2004-01-15 16:56:48 +0000 (Thu, 15 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Add new macros.
+
+------------------------------------------------------------------------
+r2627 | pelissip | 2004-01-15 16:55:45 +0000 (Thu, 15 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+Readd stdio.h in case of DEBUG mode.
+
+------------------------------------------------------------------------
+r2626 | pelissip | 2004-01-15 16:55:25 +0000 (Thu, 15 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+Optimize a few sub1sp by removing the normalisation in case of exact rounding and by removing the calcul of the rounding mode in case of exact rounding.
+
+------------------------------------------------------------------------
+r2625 | zimmerma | 2004-01-15 14:43:17 +0000 (Thu, 15 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed problem in case m=0 and b=2^k (lost bits from 1st digit were not taken
+into account)
+
+------------------------------------------------------------------------
+r2624 | zimmerma | 2004-01-15 12:09:25 +0000 (Thu, 15 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set_str.c
+
+mpn_exp -> mpfr_mpn_exp
+
+------------------------------------------------------------------------
+r2623 | vlefevre | 2004-01-15 08:49:34 +0000 (Thu, 15 Jan 2004) | 2 lines
+Changed paths:
+ D /trunk/gammaPiAGMformula.c
+
+Removed gammaPiAGMformula.c (old version, no longer used).
+
+------------------------------------------------------------------------
+r2622 | vlefevre | 2004-01-14 17:18:34 +0000 (Wed, 14 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/cbrt.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/div_ui.c
+ M /trunk/eq.c
+ M /trunk/exp.c
+ M /trunk/exp_2.c
+ M /trunk/get_ld.c
+ M /trunk/hypot.c
+ M /trunk/init2.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log2.c
+ M /trunk/reldiff.c
+ M /trunk/save_expo.c
+ M /trunk/set_f.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_str.c
+ M /trunk/ui_div.c
+ M /trunk/zeta.c
+
+Changed some error messages into assertions.
+Removed some useless #include's.
+
+------------------------------------------------------------------------
+r2621 | pelissip | 2004-01-14 12:42:22 +0000 (Wed, 14 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+
+Continue to port tests so that they don't use double.
+
+------------------------------------------------------------------------
+r2620 | pelissip | 2004-01-09 16:00:54 +0000 (Fri, 09 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/cmp_str.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tgmpop.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+Update the tests to reduce the use of floats.
+
+------------------------------------------------------------------------
+r2619 | pelissip | 2004-01-09 10:15:51 +0000 (Fri, 09 Jan 2004) | 2 lines
+Changed paths:
+ D /trunk/mpfi.c
+ D /trunk/mpfi.h
+
+Remove unused files mpfi.c and mpfi.h
+
+------------------------------------------------------------------------
+r2618 | pelissip | 2004-01-09 09:51:23 +0000 (Fri, 09 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+
+Update test.
+Don't use floats anymore.
+
+------------------------------------------------------------------------
+r2617 | pelissip | 2004-01-09 09:50:45 +0000 (Fri, 09 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+Add RND_RAND
+Add SIGN_RAND
+
+------------------------------------------------------------------------
+r2616 | pelissip | 2004-01-09 08:58:24 +0000 (Fri, 09 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/isinteger.c
+
++ Simplify the signular code.
++ Fix potential type errors. (Used mpfr_prec_t instead of mpfr_uexp_t).
+
+------------------------------------------------------------------------
+r2615 | pelissip | 2004-01-08 16:51:51 +0000 (Thu, 08 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tgmpop.c
+
++ Add a new test file for checking functions mpfr_add/sub/mul/div_q/z (from gmp_op.c).
++ Fix bugs of mpfr_add/sub/mul/div_q/z.
+
+------------------------------------------------------------------------
+r2614 | vlefevre | 2004-01-07 19:58:45 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+-0 -> @minus{}0.
+
+------------------------------------------------------------------------
+r2613 | vlefevre | 2004-01-07 19:54:53 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Specifications for mpfr_min and mpfr_max.
+
+------------------------------------------------------------------------
+r2612 | vlefevre | 2004-01-07 17:21:06 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Updated MPFR_INTPREC_MAX definition, as mpfr_prec_t has changed.
+
+------------------------------------------------------------------------
+r2611 | pelissip | 2004-01-07 16:37:09 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub1sp.c
+
+Add a new test between sub1 and sub1sp.
+
+------------------------------------------------------------------------
+r2610 | pelissip | 2004-01-07 16:28:42 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/minmax.c
+
+Fix copyright line.
+
+------------------------------------------------------------------------
+r2609 | zimmerma | 2004-01-07 16:27:09 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/sub1.c
+ M /trunk/tests/tsub.c
+
+fixed wrong sign of inexact flag
+
+------------------------------------------------------------------------
+r2608 | vlefevre | 2004-01-07 16:11:04 +0000 (Wed, 07 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Added casts to size_t so that integers representing a size get
+this type as soon as possible.
+
+------------------------------------------------------------------------
+r2607 | pelissip | 2004-01-07 14:48:33 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+Use MPFR_ASSERTN(0) instead of abort.
+
+------------------------------------------------------------------------
+r2606 | pelissip | 2004-01-07 14:48:10 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Fix the definition of MPFR_PREC_MAX
+
+------------------------------------------------------------------------
+r2605 | zimmerma | 2004-01-07 14:46:09 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+added new test to check bug repair
+
+------------------------------------------------------------------------
+r2604 | zimmerma | 2004-01-07 14:45:21 +0000 (Wed, 07 Jan 2004) | 3 lines
+Changed paths:
+ M /trunk/sub1.c
+
+fixed bug (wrong inexact flag) for rounding to nearest when sh=0 and
+first trailing limbs coincide
+
+------------------------------------------------------------------------
+r2603 | pelissip | 2004-01-07 14:27:34 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/sub.c
+
+Fix copyright lines (2004).
+
+------------------------------------------------------------------------
+r2602 | pelissip | 2004-01-07 14:05:30 +0000 (Wed, 07 Jan 2004) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/add.c
+ M /trunk/sub.c
+ M /trunk/sub1sp.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tsub1sp.c
+
+Fix bug of sub1sp.c on sparck.
+Add new tests for sub1sp.
+Reenable sub1sp for mpfr_add / mpfr_sub.
+
+------------------------------------------------------------------------
+r2601 | pelissip | 2004-01-07 14:04:30 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/print_raw.c
+
+Change output format of mpfr_print_mant_binary.
+
+------------------------------------------------------------------------
+r2600 | vlefevre | 2004-01-07 13:27:29 +0000 (Wed, 07 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/cmp2.c
+
+Clarified comment.
+
+------------------------------------------------------------------------
+r2599 | vlefevre | 2004-01-06 14:17:50 +0000 (Tue, 06 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Updated copyright line.
+
+------------------------------------------------------------------------
+r2598 | vlefevre | 2004-01-06 14:06:48 +0000 (Tue, 06 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tversion.c
+ M /trunk/update-version
+ A /trunk/version.c
+
+Added mpfr_version function and test.
+
+------------------------------------------------------------------------
+r2597 | vlefevre | 2004-01-06 13:46:32 +0000 (Tue, 06 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+The mpfr_print_rnd_mode return type is const char *, not char *.
+
+------------------------------------------------------------------------
+r2596 | pelissip | 2004-01-06 13:06:37 +0000 (Tue, 06 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_z.c
+
+Update the copyright line of the source files to 2004.
+
+------------------------------------------------------------------------
+r2595 | pelissip | 2004-01-06 12:30:41 +0000 (Tue, 06 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_z.c
+
+Add the tests to check if 0 for signed class with unsigned 0 is set to 0+.
+
+------------------------------------------------------------------------
+r2594 | zimmerma | 2004-01-05 16:35:08 +0000 (Mon, 05 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+specified sign of zero in mpfr_set_*
+
+------------------------------------------------------------------------
+r2593 | zimmerma | 2004-01-05 14:32:56 +0000 (Mon, 05 Jan 2004) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+removed test using denorms
+
+------------------------------------------------------------------------
+r2592 | pelissip | 2003-12-22 17:08:57 +0000 (Mon, 22 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/add.c
+ M /trunk/sub.c
+
+Disable sub1sp in add.c and in sub.c since it provides some bugs on spark (Log/acos/asin and atan tests failed but not tsub or tsub1sp).
+
+------------------------------------------------------------------------
+r2591 | pelissip | 2003-12-22 17:08:01 +0000 (Mon, 22 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Change comment.
+
+------------------------------------------------------------------------
+r2590 | pelissip | 2003-12-22 14:13:24 +0000 (Mon, 22 Dec 2003) | 3 lines
+Changed paths:
+ M /trunk/init2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
++ Rearrange the code to be more "compatible" with broken systems.
++ Preprocessing checks are done in init2.c since GMP constants can't be used in preprocessing #if.
+
+------------------------------------------------------------------------
+r2589 | pelissip | 2003-12-22 13:56:15 +0000 (Mon, 22 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/sub1sp.c
+
+Use MPFR_UNSIGNED_MINUS_MODULO when needed.
+
+------------------------------------------------------------------------
+r2588 | pelissip | 2003-12-22 10:57:56 +0000 (Mon, 22 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/clears.c
+ M /trunk/inits.c
+ M /trunk/inits2.c
+
+Explicit support for K&R C since ansi2knr can't be used.
+
+------------------------------------------------------------------------
+r2587 | ryde | 2003-12-20 00:02:38 +0000 (Sat, 20 Dec 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+(tests_rand_start): Use gmp_randinit_default not the
+RANDS macro, to cope with new non-seeding MT setup by RANDS.
+
+------------------------------------------------------------------------
+r2586 | pelissip | 2003-12-19 16:29:48 +0000 (Fri, 19 Dec 2003) | 3 lines
+Changed paths:
+ M /trunk/get_ui.c
+ M /trunk/init2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+Support of MPFR_PREC_FORMAT.
+Fix a bug in case mp_prec_t = unsigned short.
+
+------------------------------------------------------------------------
+r2585 | vlefevre | 2003-12-19 14:19:53 +0000 (Fri, 19 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/update-version
+
+Update due to a change in mpfr.h.
+
+------------------------------------------------------------------------
+r2584 | pelissip | 2003-12-19 11:56:42 +0000 (Fri, 19 Dec 2003) | 4 lines
+Changed paths:
+ M /trunk/VERSION
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
++ Modify Version to 2.1.0.
++ Add MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR and MPFR_VERSION_PATCHLEVEL in mpfr.h
++ Add MPFR_VERSION_NUM and MPFR_VERSION to check Mpfr version.
+
+------------------------------------------------------------------------
+r2583 | pelissip | 2003-12-19 11:54:48 +0000 (Fri, 19 Dec 2003) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/sub1sp.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+
+Remove one warning in mpf_compat.h
+Create a new macro: MPFR_RET_NEVER_GO_HERE
+Modify ui_sub/div to use it to make Insure++ happy.
+
+------------------------------------------------------------------------
+r2582 | zimmerma | 2003-12-19 11:44:42 +0000 (Fri, 19 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+updated mpfr_root entry
+
+------------------------------------------------------------------------
+r2581 | vlefevre | 2003-12-19 11:41:10 +0000 (Fri, 19 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ A /trunk/update-version
+
+Added update-version script to update the MPFR version.
+
+------------------------------------------------------------------------
+r2580 | zimmerma | 2003-12-19 10:06:10 +0000 (Fri, 19 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed one item, added one
+
+------------------------------------------------------------------------
+r2579 | zimmerma | 2003-12-16 12:46:28 +0000 (Tue, 16 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+removed unused target "tests"
+
+------------------------------------------------------------------------
+r2578 | zimmerma | 2003-12-16 12:38:36 +0000 (Tue, 16 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+removed AC_DEFINE(hpux) [not used any more]
+
+------------------------------------------------------------------------
+r2577 | ryde | 2003-12-15 22:01:21 +0000 (Mon, 15 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+(EXTRA_DIST): Add round_raw_generic.c.
+
+------------------------------------------------------------------------
+r2576 | pelissip | 2003-12-15 14:39:35 +0000 (Mon, 15 Dec 2003) | 8 lines
+Changed paths:
+ M /trunk/asin.c
+ M /trunk/atan.c
+ M /trunk/cbrt.c
+ M /trunk/div.c
+ M /trunk/fits_u.h
+ M /trunk/gamma.c
+ M /trunk/get_d.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/round_prec.c
+ M /trunk/round_raw_generic.c
+ M /trunk/set_ld.c
+ M /trunk/set_ui.c
+ M /trunk/sub1sp.c
+ M /trunk/tests/memory.c
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/reuse.c
+ M /trunk/tests/rnd_mode.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcomparisons.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_d_2exp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tinits.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tnext.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsgn.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub1sp.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+
++ Optimize a few div.c
++ Remove some warnings in asin.c, atan.c.
++ Include limits.h before gmp-impl.h in mpfr-impl.h
++ mpfr-tests.h doesn't include anumore standard include files.
++ Test files include only standard includes and mpfr-tests.h.
++ Add some forgotten mpfr_clear in mpf[r]_compat.
++ Remove some warnings in the tests.
+
+------------------------------------------------------------------------
+r2575 | zimmerma | 2003-12-15 09:11:37 +0000 (Mon, 15 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+removed unused arguments
+
+------------------------------------------------------------------------
+r2574 | zimmerma | 2003-12-15 09:00:22 +0000 (Mon, 15 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+removed AC_DEFINE(__STDC__) for OSF
+
+------------------------------------------------------------------------
+r2573 | zimmerma | 2003-12-15 08:48:24 +0000 (Mon, 15 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+removed MISCFLAGS (not used any more)
+
+------------------------------------------------------------------------
+r2572 | ryde | 2003-12-14 00:42:04 +0000 (Sun, 14 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Quote AC_DEFUN names, for automake 1.8.
+
+------------------------------------------------------------------------
+r2571 | pelissip | 2003-12-10 13:40:52 +0000 (Wed, 10 Dec 2003) | 3 lines
+Changed paths:
+ M /trunk/powerof2.c
+ M /trunk/sub1sp.c
+ M /trunk/tests/tsub1sp.c
+
++ Add a new test in case of underflow.
++ Fix bug in case of underflow for sub1 / sub1sp (mpfr_powerof2 could be called with inalid numbers).
+
+------------------------------------------------------------------------
+r2570 | pelissip | 2003-12-09 14:58:26 +0000 (Tue, 09 Dec 2003) | 3 lines
+Changed paths:
+ M /trunk/print_raw.c
+ M /trunk/sub1sp.c
+
++ Fixed bugs of mpfr_print_mant_binary on 64 bits CPU (1L instead of 1).
++ Fixed bugs of mpfr_sub1sp on 64-bits CPU (mp_limb_t instead of int).
+
+------------------------------------------------------------------------
+r2569 | pelissip | 2003-12-09 13:52:50 +0000 (Tue, 09 Dec 2003) | 8 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/add.c
+ M /trunk/clear.c
+ M /trunk/init2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/print_raw.c
+ M /trunk/round_prec.c
+ M /trunk/set_prec.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ A /trunk/sub1sp.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ A /trunk/tests/tsub1sp.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_pow.c
+
++ Add function mpfr_print_mantissa_binary, for debugging reason.
++ Rename MPFR_ALLOC_SIZE in MPFR_MALLOC_SIZE.
++ Add conditionnal -DSMALL directive in mpfr-impl.h.
++ Add new function: sub1sp.
+ Substraction in case of all the ops have the same prec.
++ Add its test (tsub1sp).
++ Modify a few the tests to avoid comparing mpfr results with double, for portability reason.
+
+------------------------------------------------------------------------
+r2568 | vlefevre | 2003-12-05 17:47:09 +0000 (Fri, 05 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/exp10.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+Added mpfr_exp10 function.
+
+------------------------------------------------------------------------
+r2567 | pelissip | 2003-12-01 10:25:01 +0000 (Mon, 01 Dec 2003) | 3 lines
+Changed paths:
+ M /trunk/exceptions.c
+ M /trunk/get_d.c
+ M /trunk/mpfr-impl.h
+ M /trunk/neg.c
+ M /trunk/powerof2.c
+ M /trunk/set_d.c
+ M /trunk/set_ld.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+
+Port all the IEEE dependent remaining functions so that it uses a generic way to compute the result if it detects that the double is not in IEEE format ( _GMP_IEEE_FLOATS == 0).
+MPFR now should work well on non-IEEE machines.
+
+------------------------------------------------------------------------
+r2566 | zimmerma | 2003-12-01 10:20:37 +0000 (Mon, 01 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added suggestion for 2 new functions
+
+------------------------------------------------------------------------
+r2565 | zimmerma | 2003-12-01 09:17:41 +0000 (Mon, 01 Dec 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added entry (portability)
+
+------------------------------------------------------------------------
+r2564 | pelissip | 2003-11-25 17:22:31 +0000 (Tue, 25 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/cmp.c
+ M /trunk/mpfr-impl.h
+ M /trunk/sub1.c
+
+Optmize a few add1.c/sub1.c by using MPFR_LIKELY / MPFR_UNLIKELY.
+
+------------------------------------------------------------------------
+r2563 | pelissip | 2003-11-21 16:26:19 +0000 (Fri, 21 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/eq.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/factorial.c
+ M /trunk/fits_s.h
+ M /trunk/fits_u.h
+ M /trunk/gamma.c
+ M /trunk/inp_str.c
+ M /trunk/isinteger.c
+ M /trunk/mul.c
+ M /trunk/pow.c
+ M /trunk/pow_ui.c
+ M /trunk/round_prec.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/sub1.c
+ M /trunk/zeta.c
+
+Remove some warnings and potential errors (Comparaison between signed and unsigned).
+
+------------------------------------------------------------------------
+r2562 | pelissip | 2003-11-21 15:27:35 +0000 (Fri, 21 Nov 2003) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/check.c
+ M /trunk/clear.c
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tcbrt.c
+ A /trunk/tests/tcheck.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_pow.c
+
++ Add new internal function: mpfr_check.
++ Add the corresponding test file.
++ Translate mpfr_set_d to mpfr_set_str / mpfr_set_ui in the tests for portability reasons.
+
+------------------------------------------------------------------------
+r2558 | zimmerma | 2003-11-21 10:16:17 +0000 (Fri, 21 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_pow.c
+
+use integers instead of double's
+
+------------------------------------------------------------------------
+r2557 | vlefevre | 2003-11-21 08:05:29 +0000 (Fri, 21 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/TODO
+
+Notes about not using mpfr_set_d in the tests.
+
+------------------------------------------------------------------------
+r2554 | pelissip | 2003-11-19 10:01:34 +0000 (Wed, 19 Nov 2003) | 4 lines
+Changed paths:
+ M /trunk/mul.c
+ M /trunk/pow.c
+ M /trunk/set_ui.c
+
+ Optimization of mpfr_mul.
+ Tiny optimization of mpfr_pow (The case y=0 has been put inside the MPFR_ARE_SINGULAR block).
+ Tiny optimisation of mpfr_set_ui.
+
+------------------------------------------------------------------------
+r2553 | zimmerma | 2003-11-18 16:07:12 +0000 (Tue, 18 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+fixed bug in case exact result
+
+------------------------------------------------------------------------
+r2552 | zimmerma | 2003-11-18 16:05:36 +0000 (Tue, 18 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_pow.c
+
+added new tests
+
+------------------------------------------------------------------------
+r2551 | pelissip | 2003-11-18 11:46:34 +0000 (Tue, 18 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/round_raw_generic.c
+
+ Optimize round_raw_generic by reducing the number of redundant tests.
+
+------------------------------------------------------------------------
+r2550 | pelissip | 2003-11-17 14:43:54 +0000 (Mon, 17 Nov 2003) | 9 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/exceptions.c
+ M /trunk/get_d.c
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/round_prec.c
+ A /trunk/round_raw_generic.c
+ M /trunk/set_str.c
+ M /trunk/sub1.c
+ M /trunk/tests/Makefile.am
+
+* Optimize a few div.c and mul.c.
+* Reorder the tests.
+* Remove mpfr_round_raw_generic and create 4 new functions which replace it, for efficiency reasons.
+* Add round_raw_generic.c which is the generic file to create the 4 new functions.
+* Add new MACRO: MPFR_RNDUTEST_OR_RNDDNOTTEST which is a faster way to check if (rnd_mode==GMP_RNDU && test) || (rnd_mode==GMP_RNDD && !test).
+* Add new MACRO: MPFR_UNSIGNED_MINUS_MODULO.
+* Optimize mpfr_can_round_raw.
+* Some new defines in mpfr.h to increase compatibility with MPFR v2.0.1 and above.
+
+------------------------------------------------------------------------
+r2548 | zimmerma | 2003-11-14 12:47:01 +0000 (Fri, 14 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+ M /trunk/tests/tpow.c
+
+fixed bug in pow_si (exact result, case z = x)
+
+------------------------------------------------------------------------
+r2546 | zimmerma | 2003-11-14 10:44:53 +0000 (Fri, 14 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+added test to check bug fix (bug was in mpfr_pow)
+
+------------------------------------------------------------------------
+r2545 | zimmerma | 2003-11-14 10:43:40 +0000 (Fri, 14 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_pow.c
+
+added new test to check for bug fix (output precision > input precisions)
+
+------------------------------------------------------------------------
+r2544 | zimmerma | 2003-11-14 10:42:30 +0000 (Fri, 14 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+just improved editing style
+
+------------------------------------------------------------------------
+r2543 | zimmerma | 2003-11-14 10:41:35 +0000 (Fri, 14 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+fixed bug for output precision > max(input precisions)
+
+------------------------------------------------------------------------
+r2542 | vlefevre | 2003-11-14 10:40:26 +0000 (Fri, 14 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+Ported the gcc-3.3 bug detection patch to the trunk.
+
+------------------------------------------------------------------------
+r2539 | pelissip | 2003-11-07 16:15:45 +0000 (Fri, 07 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+
+Fix a stupid bug (diff_exp is not equal to the difference of prec)
+
+------------------------------------------------------------------------
+r2538 | vlefevre | 2003-11-07 13:25:18 +0000 (Fri, 07 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/init2.c
+
+Initialize the exp field.
+
+------------------------------------------------------------------------
+r2537 | pelissip | 2003-11-07 10:08:57 +0000 (Fri, 07 Nov 2003) | 4 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/copysign.c
+ M /trunk/div.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/exceptions.c
+ M /trunk/extract.c
+ M /trunk/get_d.c
+ M /trunk/get_exp.c
+ M /trunk/get_str.c
+ M /trunk/init2.c
+ M /trunk/isinteger.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/set_prec.c
+ M /trunk/set_str_raw.c
+ M /trunk/sub1.c
+ M /trunk/swap.c
+
+Some minor optimizations.
+Optimization of mul.c / sub1.c.
+Some clean up in the header files.
+
+------------------------------------------------------------------------
+r2536 | pelissip | 2003-11-05 16:18:16 +0000 (Wed, 05 Nov 2003) | 3 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add_one_ulp.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/cmp.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_ui.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/div.c
+ M /trunk/div_ui.c
+ M /trunk/erf.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/expm1.c
+ M /trunk/fma.c
+ M /trunk/gamma.c
+ M /trunk/gammaPiAGMformula.c
+ M /trunk/get_z_exp.c
+ M /trunk/hypot.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/rint.c
+ M /trunk/set.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/zeta.c
+
+Fix some bugs (Use MPFR_ASSERT(1) instead of MPFR_ASSERT(0))
+Optimize swap.c and copysign.c.
+
+------------------------------------------------------------------------
+r2535 | pelissip | 2003-11-05 12:11:47 +0000 (Wed, 05 Nov 2003) | 4 lines
+Changed paths:
+ M /trunk/cmp2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/round_prec.c
+ M /trunk/set.c
+ M /trunk/sub1.c
+
+Optimize mpfr_prec_round.
+Optimize mpfr_set (Case of both src & dest have the same precision).
+Start optimizing mpfr_sub1.
+
+------------------------------------------------------------------------
+r2534 | pelissip | 2003-11-05 09:00:03 +0000 (Wed, 05 Nov 2003) | 7 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/cmp_ui.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/set.c
+ M /trunk/set_ui.c
+ A /trunk/sgn.c
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tsgn.c
+
+Add a real function for mpfr_sgn (not a call to mpfr_cmp_ui_2exp).
+Add a test for mpfr_sgn.
+Change the proto of mpfr_add1 and mpfr_sub1 by removing the last arg.
+Simplify the logic of the sign in mpfr_sub1.
+Tiny speed up for cmp/set/sqrt.
+mpfr-impl auto include all the needed local header files (gmp, gmp-impl, mpfr).
+
+------------------------------------------------------------------------
+r2533 | vlefevre | 2003-11-04 16:14:47 +0000 (Tue, 04 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/pow_ui.c
+
+Merged the mpfr-2-0-2-branch pow_ui.c changes to the trunk.
+
+------------------------------------------------------------------------
+r2530 | vlefevre | 2003-11-04 13:51:03 +0000 (Tue, 04 Nov 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+
+The check_inf test wasn't called. Added 2 missing mpfr_clear and \n.
+
+------------------------------------------------------------------------
+r2529 | pelissip | 2003-11-04 13:15:26 +0000 (Tue, 04 Nov 2003) | 10 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/cputime.h
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_ui.c
+ M /trunk/erf.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/fma.c
+ M /trunk/gamma.c
+ M /trunk/gammaPiAGMformula.c
+ M /trunk/get_str.c
+ M /trunk/hypot.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/minmax.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/set_inf.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/sin_cos.c
+ M /trunk/sub.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/zeta.c
+
++ Remove MPFR_CLEAR_NAN and MPFR_CLEAR_INF. Only use MPFR_CLEAR_FLAGS.
+ MPFR_SET_INF, MPFR_SET_ZERO and MPFR_SET_ZERO must clear the flags before setting them.
++ Add a new test in tacosh.c : check Inf / Nan flags.
++ Use MPFR_IS_SINGULAR in all the remaining files.
++ Fix the use of MPFR_CLEAR_FLAGS.
++ mpfr-impl.h auto include gmp.h, gmp-impl.h, mpfr.h and limits.h.
++ Rename _PROTO to _MPFR_PROTO, and remove _GMP_PROTO.
++ Add MPFR_INT_SIGN macro.
++ Encapsulate a few more the sign.
+
+------------------------------------------------------------------------
+r2526 | vlefevre | 2003-10-30 00:03:26 +0000 (Thu, 30 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/log1p.c
+
+MPFR_RET_NAN -> MPFR_RET(0).
+
+------------------------------------------------------------------------
+r2525 | pelissip | 2003-10-28 16:31:13 +0000 (Tue, 28 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add_one_ulp.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/div.c
+ M /trunk/eq.c
+ M /trunk/erf.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/expm1.c
+ M /trunk/fma.c
+ M /trunk/frac.c
+ M /trunk/gamma.c
+ M /trunk/gammaPiAGMformula.c
+ M /trunk/hypot.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/minmax.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/next.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/round_prec.c
+ M /trunk/set.c
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/tpow.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/zeta.c
+
+Use of MPFR_UNLIKELY and MPFR_IS_SINGULAR for fast detection of special values (Nan, Inf or Zero).
+Start to encapsulate the sign to be independant of the reprensation (Must be 1 or -1).
+
+------------------------------------------------------------------------
+r2524 | pelissip | 2003-10-27 15:15:04 +0000 (Mon, 27 Oct 2003) | 8 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/clear.c
+ M /trunk/div.c
+ M /trunk/exceptions.c
+ M /trunk/extract.c
+ M /trunk/get_d.c
+ M /trunk/get_si.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/init2.c
+ M /trunk/log.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub_ui.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+
+Change the internal format of MPFR: ZERO, INF and NAN have special values of exp.
+Rename MPFR_ESIZE in MPFR_LIMB_SIZE.
+Rename MPFR_ABSZISE in MPFR_ALLOC_SIZE.
+Rename MPFR_INIT in MPFR_TMP_INIT (INIT1 too).
+"mpfr.h" includes <gmp.h> if GMP isn't detected.
+Change the way of detecting stdio.h (To check).
+Use mpfr namespace for new definitions in "mpfr.h".
+
+------------------------------------------------------------------------
+r2522 | vlefevre | 2003-10-27 13:06:22 +0000 (Mon, 27 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+Another fix, for acosh(-INF).
+
+------------------------------------------------------------------------
+r2521 | vlefevre | 2003-10-27 12:57:27 +0000 (Mon, 27 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+Fixed exit status.
+
+------------------------------------------------------------------------
+r2519 | vlefevre | 2003-10-21 12:33:17 +0000 (Tue, 21 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/mpfr.h
+ M /trunk/tests/trint.c
+
+Merged the mpfr-2-0-2-branch changes to the trunk.
+
+------------------------------------------------------------------------
+r2514 | vlefevre | 2003-10-20 15:47:10 +0000 (Mon, 20 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/gmp_op.c
+ M /trunk/mpfr.texi
+ M /trunk/rint.c
+ M /trunk/tests/trint.c
+
+Merged the mpfr-2-0-2-branch changes to the trunk.
+
+------------------------------------------------------------------------
+r2511 | vlefevre | 2003-10-17 13:34:46 +0000 (Fri, 17 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/erf.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/trint.c
+
+Merged the mpfr-2-0-2-branch changes to the trunk.
+
+------------------------------------------------------------------------
+r2505 | vlefevre | 2003-10-16 12:48:40 +0000 (Thu, 16 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Update.
+
+------------------------------------------------------------------------
+r2504 | vlefevre | 2003-10-16 11:54:20 +0000 (Thu, 16 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/VERSION
+
+Updated version on trunk.
+
+------------------------------------------------------------------------
+r2503 | vlefevre | 2003-10-16 11:48:31 +0000 (Thu, 16 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r2502 | vlefevre | 2003-10-16 09:55:46 +0000 (Thu, 16 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+ M /trunk/set_d.c
+
+Fixed several bugs.
+
+------------------------------------------------------------------------
+r2501 | vlefevre | 2003-10-16 09:32:26 +0000 (Thu, 16 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+
+Added XDEBUG support (like in set_d.c).
+
+------------------------------------------------------------------------
+r2500 | vlefevre | 2003-10-15 09:46:52 +0000 (Wed, 15 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Replaced all non-ASCII characters by an equivalent 7-bit sequence
+to support unpatched texinfo.tex files.
+
+------------------------------------------------------------------------
+r2499 | zimmerma | 2003-10-15 09:32:21 +0000 (Wed, 15 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+removed #define DEBUG (turned on accidentally)
+
+------------------------------------------------------------------------
+r2498 | vlefevre | 2003-10-15 09:15:19 +0000 (Wed, 15 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Bug on the ternary value was fixed by Paul Zimmermann on 2003-10-14.
+
+------------------------------------------------------------------------
+r2497 | zimmerma | 2003-10-14 12:29:45 +0000 (Tue, 14 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added preamble about ternary flag for special functions
+
+------------------------------------------------------------------------
+r2496 | zimmerma | 2003-10-14 12:13:37 +0000 (Tue, 14 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tzeta.c
+
+now uses #include "tgeneric.c" everywhere
+(and modified test_generic to check also the inexact flag)
+
+------------------------------------------------------------------------
+r2495 | zimmerma | 2003-10-14 12:12:10 +0000 (Tue, 14 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_div.c
+
+check_nan() is back
+
+------------------------------------------------------------------------
+r2494 | zimmerma | 2003-10-14 12:08:37 +0000 (Tue, 14 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+removed old unused code
+
+------------------------------------------------------------------------
+r2493 | zimmerma | 2003-10-14 12:05:25 +0000 (Tue, 14 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+fixed tests for x=0
+removed composition tests (were already in-between #if 0 ... #endif)
+
+------------------------------------------------------------------------
+r2492 | zimmerma | 2003-10-14 11:49:06 +0000 (Tue, 14 Oct 2003) | 4 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/erf.c
+ M /trunk/exp2.c
+ M /trunk/expm1.c
+ M /trunk/factorial.c
+ M /trunk/gamma.c
+ M /trunk/hypot.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/zeta.c
+
+replaced mpfr_can_round (approx, err, rnd1, GMP_RNDN, prec)
+by mpfr_can_round (approx, err, rnd1, GMP_RNDZ, prec + 1)
+which in addition guarantees a correct inexact flag
+
+------------------------------------------------------------------------
+r2491 | zimmerma | 2003-10-14 11:42:51 +0000 (Tue, 14 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added new items (version number, rounding modes)
+
+------------------------------------------------------------------------
+r2490 | zimmerma | 2003-10-14 11:42:00 +0000 (Tue, 14 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+added comment about --enable-alloca=debug
+
+------------------------------------------------------------------------
+r2489 | zimmerma | 2003-10-13 13:12:46 +0000 (Mon, 13 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+added section "Problems due to compiler bugs"
+
+------------------------------------------------------------------------
+r2488 | zimmerma | 2003-10-13 08:03:14 +0000 (Mon, 13 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+
+change in can_round calls to get correct inexact flag for rounding to nearest
+
+------------------------------------------------------------------------
+r2487 | zimmerma | 2003-10-10 09:05:15 +0000 (Fri, 10 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+ M /trunk/tests/tpow.c
+
+fixed bug in mpfr_pow found by Ming J. Tsai (overflow)
+
+------------------------------------------------------------------------
+r2486 | vlefevre | 2003-10-08 15:43:13 +0000 (Wed, 08 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/asin.c
+ M /trunk/atan.c
+
+Removed useless inclusion of standard headers and some #ifdef DEBUG
+code. Partial reindentation.
+
+------------------------------------------------------------------------
+r2485 | vlefevre | 2003-10-08 15:22:05 +0000 (Wed, 08 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/strncasecmp.c
+
+Added a #include <stddef.h> because size_t is used.
+
+------------------------------------------------------------------------
+r2484 | zimmerma | 2003-10-07 08:37:28 +0000 (Tue, 07 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tzeta.c
+
+reduced test time
+
+------------------------------------------------------------------------
+r2483 | zimmerma | 2003-10-07 07:41:55 +0000 (Tue, 07 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+
+reduced test time
+
+------------------------------------------------------------------------
+r2482 | zimmerma | 2003-10-07 07:36:12 +0000 (Tue, 07 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+reduced test time
+
+------------------------------------------------------------------------
+r2481 | zimmerma | 2003-10-06 16:11:15 +0000 (Mon, 06 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/round_prec.c
+
+fixed comment of mpfr_round_raw_generic
+
+------------------------------------------------------------------------
+r2480 | zimmerma | 2003-10-06 15:53:46 +0000 (Mon, 06 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/extract.c
+ M /trunk/get_si.c
+ M /trunk/get_ui.c
+
+replaced ABSSIZE by ESIZE (ABSSIZE is the allocated size, and should be
+used only in functions init, set_prec, round_prec)
+
+------------------------------------------------------------------------
+r2479 | zimmerma | 2003-10-06 15:52:25 +0000 (Mon, 06 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+fixed bug in allocation for in-place operation
+
+------------------------------------------------------------------------
+r2478 | zimmerma | 2003-10-06 14:44:18 +0000 (Mon, 06 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/asin.c
+ M /trunk/atan.c
+
+inexact flag should now be correct for directed rounding
+fixed a bug for mpfr_atan(-Inf) [gave +Pi/2 instead of -Pi/2]
+
+------------------------------------------------------------------------
+r2477 | zimmerma | 2003-10-06 14:43:00 +0000 (Mon, 06 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+added test for atan(-Inf)
+
+------------------------------------------------------------------------
+r2476 | zimmerma | 2003-10-06 13:32:02 +0000 (Mon, 06 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+use macros to avoid possible problem with float input
+
+------------------------------------------------------------------------
+r2475 | zimmerma | 2003-10-06 13:31:20 +0000 (Mon, 06 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+new proposal for mpfr_can_round
+
+------------------------------------------------------------------------
+r2474 | zimmerma | 2003-10-06 08:35:42 +0000 (Mon, 06 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr_mul_2exp/mpfr_div_2exp are not obsolete
+
+------------------------------------------------------------------------
+r2473 | vlefevre | 2003-10-05 23:11:12 +0000 (Sun, 05 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Clearer mpfr_eq documentation (thanks to Kevin Ryde for the remark).
+
+------------------------------------------------------------------------
+r2472 | vlefevre | 2003-10-03 13:00:41 +0000 (Fri, 03 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+MPFR_ASSERTN rewritten to avoid "statement with no effect" warnings
+with gcc when the assertion is always true.
+
+------------------------------------------------------------------------
+r2471 | vlefevre | 2003-10-03 12:49:59 +0000 (Fri, 03 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/add1.c
+
+Optimization (thanks to Patrick Pelissier), as the allocated size
+may be larger than the size used by the significant bits.
+
+------------------------------------------------------------------------
+r2470 | vlefevre | 2003-10-03 12:30:14 +0000 (Fri, 03 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/mpfr.texi
+
+Updated installation notes.
+
+------------------------------------------------------------------------
+r2469 | vlefevre | 2003-10-03 08:01:45 +0000 (Fri, 03 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/cmp_abs.c
+ M /trunk/mpfr.texi
+
+Infinities are now accepted in mpfr_cmpabs. Updated its definition
+in the source (no longer sign(abs(b) - abs(c))).
+
+------------------------------------------------------------------------
+r2468 | vlefevre | 2003-10-02 22:30:16 +0000 (Thu, 02 Oct 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Use @url{} for URLs.
+
+------------------------------------------------------------------------
+r2467 | vlefevre | 2003-10-02 21:57:39 +0000 (Thu, 02 Oct 2003) | 6 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+As suggested by PZ:
+ o documentation of mpfr_fits_* functions moved to the section
+ on conversions;
+ o grouped some mpfr_pow special cases;
+ o explanation concerning the meaning of rnd in mpfr_frac.
+
+------------------------------------------------------------------------
+r2466 | vlefevre | 2003-10-02 17:17:59 +0000 (Thu, 02 Oct 2003) | 8 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/print_raw.c
+ M /trunk/set_str_raw.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+
+Updated documentation. In particular, mpfr_set_str_raw renamed
+as mpfr_set_str_binary. This function and mpfr_print_binary are
+now internal functions. mpfr_print_binary no longer prints the
+non-significant 0 bits. Updated the source to match the manual.
+mpfr_print_binary has been completely rewritten (now directly
+prints to stdout, without using an intermediate string). In
+mpfr_set_str_binary, replaced atol by strtol + error checking.
+
+------------------------------------------------------------------------
+r2465 | zimmerma | 2003-10-02 14:14:08 +0000 (Thu, 02 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added paragraph on support/grants
+added help for mpfr_erf
+
+------------------------------------------------------------------------
+r2464 | vlefevre | 2003-10-02 14:05:59 +0000 (Thu, 02 Oct 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Make node titles match section titles, and updated menus and xrefs.
+Added a line break after @samp{uninstall}.
+
+------------------------------------------------------------------------
+r2463 | vlefevre | 2003-10-01 15:06:25 +0000 (Wed, 01 Oct 2003) | 4 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/zeta.c
+
+Corrections in the MPFR manual (PZ & VL). Functions mpfr_const_pi,
+mpfr_const_log2 and mpfr_zeta now return a ternary value. Updated
+TODO file.
+
+------------------------------------------------------------------------
+r2462 | vlefevre | 2003-09-30 16:50:58 +0000 (Tue, 30 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Added a bug related to the ternary value and worst cases.
+
+------------------------------------------------------------------------
+r2461 | vlefevre | 2003-09-30 16:29:01 +0000 (Tue, 30 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+
+Added exponent range support.
+
+------------------------------------------------------------------------
+r2460 | vlefevre | 2003-09-30 10:34:39 +0000 (Tue, 30 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Corrections up to Section 5.6 (PZ & VL).
+
+------------------------------------------------------------------------
+r2459 | vlefevre | 2003-09-30 10:12:24 +0000 (Tue, 30 Sep 2003) | 7 lines
+Changed paths:
+ M /trunk/get_z_exp.c
+
+Re-added the assert on the exponent, but replacing MPFR_EMIN_MIN by
+MP_EXP_T_MIN (this makes more sense): an assertion failed would mean
+that the exponent is not representable (an undefined behavior in the
+ISO C standard). If need be, we could choose to return MP_EXP_T_MIN
+in such a case, or perhaps MP_EXP_T_MAX to signal an error. The
+mantissa would still be meaningful.
+
+------------------------------------------------------------------------
+r2458 | pelissip | 2003-09-30 07:47:49 +0000 (Tue, 30 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Update TODO & mpfr_set_prec.
+
+------------------------------------------------------------------------
+r2457 | vlefevre | 2003-09-29 14:40:11 +0000 (Mon, 29 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Corrections up to Section 4.
+
+------------------------------------------------------------------------
+r2456 | vlefevre | 2003-09-29 08:00:19 +0000 (Mon, 29 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+Added authors Kevin Ryde and Patrick Pelissier.
+
+------------------------------------------------------------------------
+r2455 | vlefevre | 2003-09-29 07:48:10 +0000 (Mon, 29 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Removed "known problems" that are no longer problems.
+
+------------------------------------------------------------------------
+r2454 | vlefevre | 2003-09-26 12:39:37 +0000 (Fri, 26 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+
+Removed bugs related to the tests and to the exponents
+as they no longer occur. Updated some potentials bugs.
+
+------------------------------------------------------------------------
+r2453 | vlefevre | 2003-09-25 16:50:34 +0000 (Thu, 25 Sep 2003) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tinits.c
+
+Removed mpfr_inits, mpfr_inits2, mpfr_clears from the documentation.
+Moved their prototypes to mpfr-impl.h (internal functions until
+decided otherwise).
+
+------------------------------------------------------------------------
+r2452 | pelissip | 2003-09-25 12:03:36 +0000 (Thu, 25 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/generic.c
+
+Modify 'r' arg of GENERIC from int to long (min 32 bits).
+
+------------------------------------------------------------------------
+r2451 | vlefevre | 2003-09-25 10:31:23 +0000 (Thu, 25 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+8-bit ISO-8859-1 characters + consistent spelling.
+
+------------------------------------------------------------------------
+r2450 | vlefevre | 2003-09-25 10:17:00 +0000 (Thu, 25 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r2449 | vlefevre | 2003-09-25 08:15:42 +0000 (Thu, 25 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/mpf_compat.h
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_d.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tfrac.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trandom.c
+
+Changed the remaining stderr to stdout.
+
+------------------------------------------------------------------------
+r2448 | vlefevre | 2003-09-24 22:32:40 +0000 (Wed, 24 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+
+Changed some stderr to stdout.
+
+------------------------------------------------------------------------
+r2447 | vlefevre | 2003-09-24 21:05:42 +0000 (Wed, 24 Sep 2003) | 4 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/comparisons.c
+ M /trunk/mpfr.texi
+
+Added documentation for mpfr_greater_p, mpfr_greaterequal_p,
+mpfr_less_p, mpfr_lessequal_p, mpfr_lessgreater_p, mpfr_equal_p
+and mpfr_unordered_p.
+
+------------------------------------------------------------------------
+r2446 | vlefevre | 2003-09-24 20:26:48 +0000 (Wed, 24 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tcomparisons.c
+
+Added tests for mpfr_greater_p, mpfr_greaterequal_p, mpfr_less_p,
+mpfr_lessequal_p, mpfr_lessgreater_p, mpfr_equal_p, mpfr_unordered_p.
+
+------------------------------------------------------------------------
+r2445 | vlefevre | 2003-09-24 16:31:11 +0000 (Wed, 24 Sep 2003) | 4 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/tests/tnext.c
+
+Added a few more tests (involving mpfr_nexttoward). The tests for
+the mpfr_nextabove, mpfr_nextbelow and mpfr_nexttoward functions
+should now be sufficient.
+
+------------------------------------------------------------------------
+r2444 | vlefevre | 2003-09-24 13:19:30 +0000 (Wed, 24 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/next.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tnext.c
+
+Added generic tests for mpfr_nextabove and mpfr_nextbelow.
+Fixed a bug in next.c related to assertion checks.
+
+------------------------------------------------------------------------
+r2443 | vlefevre | 2003-09-24 12:02:45 +0000 (Wed, 24 Sep 2003) | 5 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/set_str.c
+ M /trunk/tests/tset_str.c
+
+Accept (case-insensitive) NaN and Inf in input for bases <= 16 for
+backward compatibility in these bases (for bases > 16, we cannot
+guaranty backward compatibility with the current wanted behavior).
+Added tests.
+
+------------------------------------------------------------------------
+r2442 | zimmerma | 2003-09-24 10:33:20 +0000 (Wed, 24 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one item from Kevin
+
+------------------------------------------------------------------------
+r2441 | vlefevre | 2003-09-24 09:26:34 +0000 (Wed, 24 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/texinfo.tex
+
+Added support for some top-bit-set characters in the .texi source.
+
+------------------------------------------------------------------------
+r2440 | vlefevre | 2003-09-24 08:40:04 +0000 (Wed, 24 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Added information on special values for mpfr_pow.
+
+------------------------------------------------------------------------
+r2439 | zimmerma | 2003-09-24 08:35:06 +0000 (Wed, 24 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added MAKEINFOFLAGS = --enable-encoding to get 8-bit characters in mpfr.info
+
+------------------------------------------------------------------------
+r2438 | zimmerma | 2003-09-24 08:05:50 +0000 (Wed, 24 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/AUTHORS
+ M /trunk/mpfr.texi
+
+used ISO-8859-1 in AUTHORS
+and @`e, @"o in mpfr.texi (waiting for code for ISO-8859-1 compatibility)
+
+------------------------------------------------------------------------
+r2437 | ryde | 2003-09-24 00:40:24 +0000 (Wed, 24 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(MPFR_C_LONG_DOUBLE_FORMAT): Remove conftest* temporary
+files.
+
+------------------------------------------------------------------------
+r2436 | vlefevre | 2003-09-24 00:36:19 +0000 (Wed, 24 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Fixed comparisons (cases @NaN@ and @Inf@).
+
+------------------------------------------------------------------------
+r2435 | zimmerma | 2003-09-23 09:19:22 +0000 (Tue, 23 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+two updates
+
+------------------------------------------------------------------------
+r2434 | vlefevre | 2003-09-22 15:03:30 +0000 (Mon, 22 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Updated mpfr_pow description.
+
+------------------------------------------------------------------------
+r2433 | zimmerma | 2003-09-22 13:50:46 +0000 (Mon, 22 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/print_rnd_mode.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+
+changed __gmp_const into const in *.c
+[Torbjo"rn: Please use __gmp_const just in user header files, plain C const in other files.]
+
+------------------------------------------------------------------------
+r2432 | vlefevre | 2003-09-22 13:30:46 +0000 (Mon, 22 Sep 2003) | 6 lines
+Changed paths:
+ M /trunk/TODO
+
+Removed
+
+- allow the ISO C "P" exponent separator for base 16 in input functions
+
+(already done).
+
+------------------------------------------------------------------------
+r2431 | vlefevre | 2003-09-22 13:09:16 +0000 (Mon, 22 Sep 2003) | 4 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/tests/tset_ld.c
+
+Implemented the following:
+- use (LDBL_MAX/2)+(LDBL_MAX/4*LDBL_EPSILON) instead of loop in tset_ld
+ to get largest power of 2 that fits in a long double
+
+------------------------------------------------------------------------
+r2430 | vlefevre | 2003-09-22 11:23:09 +0000 (Mon, 22 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/sub1.c
+
+Added some MPFR_ASSERTN and improved a comment.
+
+------------------------------------------------------------------------
+r2429 | vlefevre | 2003-09-22 07:56:47 +0000 (Mon, 22 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+
+Avoid string literals longer than 509 characters (ISO C89 limit).
+
+------------------------------------------------------------------------
+r2428 | vlefevre | 2003-09-22 07:53:16 +0000 (Mon, 22 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/texceptions.c
+
+(test_set_underflow, test_set_overflow): Cleaner fix (for pre-C99
+compilers).
+
+------------------------------------------------------------------------
+r2427 | ryde | 2003-09-22 01:45:07 +0000 (Mon, 22 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/texceptions.c
+
+(test_set_underflow, test_set_overflow): Use
+"static" on "r" to allow non-constant initializers.
+
+------------------------------------------------------------------------
+r2426 | ryde | 2003-09-21 00:37:17 +0000 (Sun, 21 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+(Converting Floats): In mpfr_get_d_2exp, the rounding mode
+is given, it doesn't use the default mode.
+
+------------------------------------------------------------------------
+r2425 | ryde | 2003-09-21 00:14:49 +0000 (Sun, 21 Sep 2003) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+(Assigning Floats): In mpfr_set_str and mpfr_set_str_raw,
+show "const" not "__gmp_const".
+(Simultaneous Float Init & Assign): In mpfr_init_set_str, ditto.
+
+------------------------------------------------------------------------
+r2424 | ryde | 2003-09-21 00:07:26 +0000 (Sun, 21 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+(Rounding Modes): Add blank line around @itemize.
+
+------------------------------------------------------------------------
+r2423 | ryde | 2003-09-21 00:06:03 +0000 (Sun, 21 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+(Miscellaneous Float Functions): In mpfr_urandomb and
+mpfr_random, use @math and @le.
+
+------------------------------------------------------------------------
+r2422 | ryde | 2003-09-20 23:51:49 +0000 (Sat, 20 Sep 2003) | 6 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+(Assigning Floats): In mpfr_set_*, remove remarks about
+long being rounded (this should be clear already), about rounding of
+decimal double constants like 0.1 (too basic to appear here),
+(Converting Floats): In mpfr_get_d_2exp, remove remark about exp
+exceeding IEEE exponent range (should be clear already).
+
+------------------------------------------------------------------------
+r2421 | zimmerma | 2003-09-19 14:25:15 +0000 (Fri, 19 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+updated items: removed conversion from/to float (obsolete)
+
+------------------------------------------------------------------------
+r2420 | zimmerma | 2003-09-19 14:09:51 +0000 (Fri, 19 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/zeta.c
+
+got rid of <math.h> dependency in mpfr_zeta
+
+------------------------------------------------------------------------
+r2419 | zimmerma | 2003-09-19 13:41:10 +0000 (Fri, 19 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/exp_2.c
+ M /trunk/get_str.c
+ M /trunk/log_b2.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/round_prec.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tzeta.c
+
+mpfr_round_prec is now obsolete
+new function mpfr_prec_round replaces it
+
+------------------------------------------------------------------------
+r2418 | vlefevre | 2003-09-18 10:33:57 +0000 (Thu, 18 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Fix for C implementations with 16-bit int.
+
+------------------------------------------------------------------------
+r2417 | pelissip | 2003-09-18 08:37:38 +0000 (Thu, 18 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+ Optimization of macros MPFR_IS_INF, MPFR_IS_NAN and MPFR_IS_FP
+
+------------------------------------------------------------------------
+r2416 | vlefevre | 2003-09-18 06:50:14 +0000 (Thu, 18 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+Removed a comment that should have been removed in revision 1.8.
+
+------------------------------------------------------------------------
+r2415 | zimmerma | 2003-09-15 15:55:00 +0000 (Mon, 15 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+No longer perform the pre-check for exactness when first division step was
+actually a complete division. This introduced way too much overhead.
+
+------------------------------------------------------------------------
+r2414 | zimmerma | 2003-09-15 15:30:31 +0000 (Mon, 15 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/inp_str.c
+
+replaced test stream==0 by stream==NULL
+
+------------------------------------------------------------------------
+r2413 | vlefevre | 2003-09-15 13:55:30 +0000 (Mon, 15 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/round_prec.c
+ M /trunk/tests/tcan_round.c
+
+Fixed a bug in mpfr_can_round_raw and added other mpfr_can_round
+tests.
+
+------------------------------------------------------------------------
+r2412 | vlefevre | 2003-09-15 13:05:05 +0000 (Mon, 15 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/round_prec.c
+ M /trunk/tests/tcan_round.c
+
+Added a test to tests/tcan_round.c and assertions to round_prec.c.
+
+------------------------------------------------------------------------
+r2411 | vlefevre | 2003-09-14 08:52:44 +0000 (Sun, 14 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/tests/texceptions.c
+
+Fixed mpfr_set_overflow, added tests for mpfr_set_underflow
+and mpfr_set_overflow, and reverted exp.c.
+
+------------------------------------------------------------------------
+r2410 | zimmerma | 2003-09-13 08:46:47 +0000 (Sat, 13 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+overflow with round to zero was incorrect
+
+------------------------------------------------------------------------
+r2409 | vlefevre | 2003-09-11 16:49:11 +0000 (Thu, 11 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/clears.c
+ A /trunk/inits.c
+ A /trunk/inits2.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tinits.c
+
+New functions mpfr_inits, mpfr_inits2 and mpfr_clears to initialize or
+free several floating-point numbers (written by Patrick Pélissier).
+
+------------------------------------------------------------------------
+r2408 | vlefevre | 2003-09-09 16:09:42 +0000 (Tue, 09 Sep 2003) | 4 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/zeta.c
+
+Replaced malloc/free by __gmp_allocate_func/__gmp_free_func in
+mpfr_zeta_pos. zeta.c still uses math (libm) functions -> TODO:
+remove this dependence.
+
+------------------------------------------------------------------------
+r2407 | vlefevre | 2003-09-09 15:13:38 +0000 (Tue, 09 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_pow.c
+
+Added a test that makes MPFR crash (coming from the mpfr_zeta crash).
+
+------------------------------------------------------------------------
+r2406 | vlefevre | 2003-09-09 14:28:47 +0000 (Tue, 09 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+Case that crashes MPFR (coming from test_generic) -> function test1.
+
+------------------------------------------------------------------------
+r2405 | vlefevre | 2003-09-09 11:33:45 +0000 (Tue, 09 Sep 2003) | 6 lines
+Changed paths:
+ M /trunk/ui_pow.c
+
+Ended up by simplifying mpfr_ui_pow to fix it completely (with a
+call to mpfr_pow, in a way similar to other ui functions). There
+isn't significant differences with the old code anyway, and the
+case integer^integer wasn't optimized like in mpfr_pow.
+The test tui_pow now passes, but the test tzeta now fails!
+
+------------------------------------------------------------------------
+r2404 | vlefevre | 2003-09-09 10:39:01 +0000 (Tue, 09 Sep 2003) | 4 lines
+Changed paths:
+ M /trunk/tests/tui_pow.c
+ M /trunk/ui_pow.c
+
+Code clean-up and reindented. Replaced a 8 by CHAR_BIT,
+as CHAR_BIT isn't necessarily equal to 8. The bug seems
+to occur on all machines.
+
+------------------------------------------------------------------------
+r2403 | vlefevre | 2003-09-08 16:22:08 +0000 (Mon, 08 Sep 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tui_pow.c
+
+Added a test to reproduce a bug (to be fixed later) on all 64-bit
+machines.
+
+------------------------------------------------------------------------
+r2402 | vlefevre | 2003-09-08 15:50:30 +0000 (Mon, 08 Sep 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+Added a cast (useful under Linux/alpha).
+
+------------------------------------------------------------------------
+r2401 | vlefevre | 2003-09-01 15:20:39 +0000 (Mon, 01 Sep 2003) | 4 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/print_rnd_mode.c
+
+Changes (Patrick Pelissier's suggestions):
+ _ mpfr_print_rnd_mode now has __gmp_const char * return type;
+ _ some corrections in mpfr.texi, documentencoding set.
+
+------------------------------------------------------------------------
+r2400 | ryde | 2003-08-30 23:25:43 +0000 (Sat, 30 Aug 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/amd64.asm
+
+#Corrections to initial checkin.
+
+------------------------------------------------------------------------
+r2399 | ryde | 2003-08-30 02:13:55 +0000 (Sat, 30 Aug 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+(EXTRA_libfrtests_a_SOURCES): Add amd64.asm.
+
+------------------------------------------------------------------------
+r2398 | ryde | 2003-08-30 02:13:34 +0000 (Sat, 30 Aug 2003) | 2 lines
+Changed paths:
+ A /trunk/tests/amd64.asm
+
+New file.
+
+------------------------------------------------------------------------
+r2397 | ryde | 2003-08-30 02:13:18 +0000 (Sat, 30 Aug 2003) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Correction to:
+(MPFR_CONFIGS): Add amd64-*-* to x86 test objects.
+
+------------------------------------------------------------------------
+r2396 | ryde | 2003-08-30 01:42:49 +0000 (Sat, 30 Aug 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+(tests_machine_prec_long_double): Add amd64 to the
+comments.
+
+------------------------------------------------------------------------
+r2395 | ryde | 2003-08-30 01:41:08 +0000 (Sat, 30 Aug 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(MPFR_CONFIGS): Add amd64-*-* to x86 test objects.
+
+------------------------------------------------------------------------
+r2394 | ryde | 2003-08-30 01:39:32 +0000 (Sat, 30 Aug 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+(check_set_get): Improve error messages.
+
+------------------------------------------------------------------------
+r2393 | ryde | 2003-08-30 01:38:46 +0000 (Sat, 30 Aug 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tests.c
+
+(ld_trace): New function.
+
+------------------------------------------------------------------------
+r2392 | ryde | 2003-08-30 01:37:40 +0000 (Sat, 30 Aug 2003) | 3 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+(ldbl_max_struct): Use octal character constants, since hex
+is an ANSI-ism.
+
+------------------------------------------------------------------------
+r2391 | vlefevre | 2003-08-07 07:56:08 +0000 (Thu, 07 Aug 2003) | 2 lines
+Changed paths:
+ M /trunk/ui_pow_ui.c
+
+Avoid a potential overflow.
+
+------------------------------------------------------------------------
+r2390 | zimmerma | 2003-08-04 11:13:04 +0000 (Mon, 04 Aug 2003) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/tests/tagm.c
+
+fixed pb found by Damien Fisher
+
+------------------------------------------------------------------------
+r2389 | vlefevre | 2003-07-24 15:47:17 +0000 (Thu, 24 Jul 2003) | 3 lines
+Changed paths:
+ M /trunk/get_d.c
+
+If the exponent of the number is meaningless (src = NaN, inf or 0),
+0 is stored in expptr (behavior similar to the ISO C frexp function).
+
+------------------------------------------------------------------------
+r2388 | zimmerma | 2003-07-21 13:16:54 +0000 (Mon, 21 Jul 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one item
+
+------------------------------------------------------------------------
+r2387 | ryde | 2003-07-19 00:17:02 +0000 (Sat, 19 Jul 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+(check_PROGRAMS): Add tget_d_2exp.c.
+
+------------------------------------------------------------------------
+r2386 | ryde | 2003-07-19 00:15:46 +0000 (Sat, 19 Jul 2003) | 2 lines
+Changed paths:
+ A /trunk/tests/tget_d_2exp.c
+
+New file, partly derived from tget_d.c.
+
+------------------------------------------------------------------------
+r2385 | ryde | 2003-07-19 00:12:19 +0000 (Sat, 19 Jul 2003) | 3 lines
+Changed paths:
+ M /trunk/get_d.c
+
+(mpfr_get_d_2exp): Ensure 0.5 <= abs(ret) < 1.0 is respected
+when rounding away from zero.
+
+------------------------------------------------------------------------
+r2384 | ryde | 2003-07-19 00:07:32 +0000 (Sat, 19 Jul 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tests.c
+
+(d_trace): New function.
+
+------------------------------------------------------------------------
+r2383 | ryde | 2003-07-19 00:06:15 +0000 (Sat, 19 Jul 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+(Converting Floats): mpfr_get_d_2exp stores to a long.
+
+------------------------------------------------------------------------
+r2382 | ryde | 2003-07-19 00:00:24 +0000 (Sat, 19 Jul 2003) | 3 lines
+Changed paths:
+ M /trunk/get_d.c
+ M /trunk/mpfr.h
+
+(mpfr_get_d_2exp): Store exp in a long, same as
+mpz_get_d_2exp and mpf_get_d_2exp.
+
+------------------------------------------------------------------------
+r2381 | vlefevre | 2003-07-15 14:42:08 +0000 (Tue, 15 Jul 2003) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+
+Updated comment.
+
+------------------------------------------------------------------------
+r2380 | vlefevre | 2003-07-08 14:31:44 +0000 (Tue, 08 Jul 2003) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+
+Correction in a comment (patch by Torbjorn).
+
+------------------------------------------------------------------------
+r2379 | zimmerma | 2003-07-01 14:47:05 +0000 (Tue, 01 Jul 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/round_prec.c
+
+can_round returns 0 for NaN/Inf
+
+------------------------------------------------------------------------
+r2378 | zimmerma | 2003-07-01 10:49:04 +0000 (Tue, 01 Jul 2003) | 3 lines
+Changed paths:
+ M /trunk/round_prec.c
+
+fixed Uninitialized memory read in mpfr_can_round
+(when b is NaN or Inf)
+
+------------------------------------------------------------------------
+r2377 | zimmerma | 2003-06-30 15:59:19 +0000 (Mon, 30 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+fixed array bound write (need 6+1 characters in s1 to represent -@inf@ + \0)
+
+------------------------------------------------------------------------
+r2376 | ryde | 2003-06-28 00:17:24 +0000 (Sat, 28 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+
+Add "const" to IEEE byte sequence data.
+
+------------------------------------------------------------------------
+r2375 | ryde | 2003-06-28 00:15:04 +0000 (Sat, 28 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+(tests_rand_end): Remove explicit __gmp_rands
+clearing, it's what RANDS_CLEAR does already.
+
+------------------------------------------------------------------------
+r2374 | ryde | 2003-06-26 23:01:02 +0000 (Thu, 26 Jun 2003) | 4 lines
+Changed paths:
+ M /trunk/TODO
+
+# Clarify nan/inf bits under efficiency.
+# Add mpfr_get_d3 ieee portability.
+# Add mpfr_random not wanted in mpf integration.
+
+------------------------------------------------------------------------
+r2373 | zimmerma | 2003-06-26 13:40:08 +0000 (Thu, 26 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/cmp_d.c
+ M /trunk/get_d.c
+ M /trunk/get_ld.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_ld.c
+
+moved macros for [L]DBL_MANT_DIG in mpfr-impl.h
+
+------------------------------------------------------------------------
+r2372 | zimmerma | 2003-06-25 10:16:43 +0000 (Wed, 25 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/urandomb.c
+
+fixed several problems noticed by Kevin
+
+------------------------------------------------------------------------
+r2371 | zimmerma | 2003-06-25 07:47:53 +0000 (Wed, 25 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+changed test for 2^1024, using LDBL_MAX_EXP
+
+------------------------------------------------------------------------
+r2370 | ryde | 2003-06-25 00:47:56 +0000 (Wed, 25 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+# Add efficiency of separate flag bit operations.
+
+------------------------------------------------------------------------
+r2369 | ryde | 2003-06-24 23:57:33 +0000 (Tue, 24 Jun 2003) | 2 lines
+Changed paths:
+ D /trunk/mpfr-math.h
+
+Remove file, no longer used.
+
+------------------------------------------------------------------------
+r2368 | ryde | 2003-06-24 23:56:41 +0000 (Tue, 24 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+(libmpfr_a_SOURCES): Remove mpfr-math.h.
+
+------------------------------------------------------------------------
+r2367 | ryde | 2003-06-24 23:55:52 +0000 (Tue, 24 Jun 2003) | 5 lines
+Changed paths:
+ M /trunk/get_d.c
+
+(MPFR_DBL_INFP, MPFR_DBL_INFM, MPFR_DBL_NAN): Make private
+definitions based on IEEE byte sequences, in particular avoid HUGE_VAL
+from mpfr-math.h since that's not infinity on hppa1.1-hp-hpux10.
+Remove includes of mpfr-math.h, math.h and stddef.h.
+
+------------------------------------------------------------------------
+r2366 | ryde | 2003-06-24 23:50:03 +0000 (Tue, 24 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+(check_inf_nan): New test.
+
+------------------------------------------------------------------------
+r2365 | ryde | 2003-06-24 23:45:21 +0000 (Tue, 24 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(MPFR_C_LONG_DOUBLE_FORMAT): Use octal char constants,
+'\xHH' is an ANSI-ism.
+
+------------------------------------------------------------------------
+r2364 | zimmerma | 2003-06-24 10:21:38 +0000 (Tue, 24 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+check 2^1024 only when sizeof(long double) > sizeof(double)
+
+------------------------------------------------------------------------
+r2363 | zimmerma | 2003-06-24 08:20:41 +0000 (Tue, 24 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+correction to previous patch
+
+------------------------------------------------------------------------
+r2362 | zimmerma | 2003-06-24 08:14:39 +0000 (Tue, 24 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+correction to previous patch: problem was that x and u can be 0,
+then MPFR_PREC() undefined
+
+------------------------------------------------------------------------
+r2361 | ryde | 2003-06-24 00:32:32 +0000 (Tue, 24 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+(tests_start_mpfr): Make stdout and stderr unbuffered.
+
+------------------------------------------------------------------------
+r2360 | ryde | 2003-06-24 00:30:25 +0000 (Tue, 24 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+(check_inexact): For pz, use at least MPFR_PREC_MIN
+since this is required by mpfr_set_prec.
+
+------------------------------------------------------------------------
+r2359 | ryde | 2003-06-24 00:29:32 +0000 (Tue, 24 Jun 2003) | 4 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+# Correction to:
+# (check_inexact): For pz, use at least MPFR_PREC_MIN
+# since this is required by mpfr_set_prec.
+
+------------------------------------------------------------------------
+r2358 | ryde | 2003-06-24 00:20:41 +0000 (Tue, 24 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+(check_inexact): For pz, use at least MPFR_PREC_MIN
+since this is required by mpfr_set_prec.
+
+------------------------------------------------------------------------
+r2357 | ryde | 2003-06-23 23:58:03 +0000 (Mon, 23 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Remove mingw portability of random/rand48, no longer used.
+
+------------------------------------------------------------------------
+r2356 | ryde | 2003-06-23 23:55:24 +0000 (Mon, 23 Jun 2003) | 5 lines
+Changed paths:
+ M /trunk/TODO
+
+Remove __setfpucw, no longer used.
+Remove mpfr_integer_p, done.
+Remove gmp rand functions in test programs, done.
+Remove MPFR_CHECK_RANDOMIZE, done (as GMP_CHECK_RANDOMIZE).
+
+------------------------------------------------------------------------
+r2355 | vlefevre | 2003-06-21 07:56:50 +0000 (Sat, 21 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr_random is deprecated.
+
+------------------------------------------------------------------------
+r2354 | zimmerma | 2003-06-20 15:01:01 +0000 (Fri, 20 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tui_div.c
+
+changed since mpfr_random now can return 0
+
+------------------------------------------------------------------------
+r2353 | vlefevre | 2003-06-20 14:21:36 +0000 (Fri, 20 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/random.c
+
+The distribution should now be uniform (mpfr_random implemented
+by calling mpfr_urandomb).
+
+------------------------------------------------------------------------
+r2352 | vlefevre | 2003-06-20 12:30:42 +0000 (Fri, 20 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/urandomb.c
+
+Take the current exponent range into account in mpfr_urandomb
+(which now returns an int).
+
+------------------------------------------------------------------------
+r2351 | vlefevre | 2003-06-20 10:37:26 +0000 (Fri, 20 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/urandomb.c
+
+Bug fix.
+
+------------------------------------------------------------------------
+r2350 | zimmerma | 2003-06-20 10:30:35 +0000 (Fri, 20 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+moved _gmp_rands_initialized stuff from tests_end_mpfr() to tests_rand_end()
+
+------------------------------------------------------------------------
+r2349 | zimmerma | 2003-06-20 09:58:46 +0000 (Fri, 20 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_z.c
+
+reduced default number of tests
+improved style
+
+------------------------------------------------------------------------
+r2348 | zimmerma | 2003-06-20 09:53:15 +0000 (Fri, 20 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+reduced default number of tests
+improved style
+
+------------------------------------------------------------------------
+r2347 | zimmerma | 2003-06-19 17:17:48 +0000 (Thu, 19 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+fixed bug in mpfr_exp2_aux2 (spe175.testdrive.hp.com)
+
+------------------------------------------------------------------------
+r2346 | zimmerma | 2003-06-19 15:40:52 +0000 (Thu, 19 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+
+improved style
+
+------------------------------------------------------------------------
+r2345 | zimmerma | 2003-06-19 14:57:05 +0000 (Thu, 19 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added more information in case of failure
+
+------------------------------------------------------------------------
+r2344 | zimmerma | 2003-06-19 09:12:26 +0000 (Thu, 19 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+
+removed randseed() stuff [obsolete now we use the GMP mechanism]
+
+------------------------------------------------------------------------
+r2343 | zimmerma | 2003-06-19 08:55:03 +0000 (Thu, 19 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+added memory test mechanism
+
+------------------------------------------------------------------------
+r2342 | zimmerma | 2003-06-19 08:54:42 +0000 (Thu, 19 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added new test from Parks
+
+------------------------------------------------------------------------
+r2341 | zimmerma | 2003-06-19 08:54:07 +0000 (Thu, 19 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+fixed allocation problem (forgot to clear)
+
+------------------------------------------------------------------------
+r2340 | vlefevre | 2003-06-19 01:01:38 +0000 (Thu, 19 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+Removed drand48/lrand48/srand48 prototypes.
+
+------------------------------------------------------------------------
+r2339 | ryde | 2003-06-18 22:57:32 +0000 (Wed, 18 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_z.c
+
+Don't use mpz_get_d1, since a 53-bit double is not
+enough when long is 64-bits.
+
+------------------------------------------------------------------------
+r2338 | ryde | 2003-06-18 22:50:59 +0000 (Wed, 18 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+Don't use mpz_get_d1, since a 53-bit double is not
+enough when long is 64-bits.
+
+------------------------------------------------------------------------
+r2337 | ryde | 2003-06-13 22:43:53 +0000 (Fri, 13 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+Use autoconf recommended style for time.h with
+sys/time.h.
+
+------------------------------------------------------------------------
+r2336 | ryde | 2003-06-13 22:40:44 +0000 (Fri, 13 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(MPFR_CONFIGS): Require AC_HEADER_TIME, add
+AC_CHECK_HEADERS of sys/time.h.
+
+------------------------------------------------------------------------
+r2335 | ryde | 2003-06-13 22:33:50 +0000 (Fri, 13 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(MPFR_CONFIGS): Add AC_CHECK_FUNCS of gettimeofday.
+
+------------------------------------------------------------------------
+r2334 | zimmerma | 2003-06-13 15:19:12 +0000 (Fri, 13 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+moved disabled test to "special" code
+
+------------------------------------------------------------------------
+r2333 | zimmerma | 2003-06-13 11:50:07 +0000 (Fri, 13 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+added reference to Higham
+
+------------------------------------------------------------------------
+r2332 | zimmerma | 2003-06-13 08:22:53 +0000 (Fri, 13 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/erf.c
+ M /trunk/exp.c
+
+improved error analysis on erf
+
+------------------------------------------------------------------------
+r2331 | zimmerma | 2003-06-13 07:52:01 +0000 (Fri, 13 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+improved indentation
+
+------------------------------------------------------------------------
+r2330 | zimmerma | 2003-06-12 16:29:34 +0000 (Thu, 12 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+added support for random see
+(when env. variable GMP_CHECK_RANDOMIZE set)
+
+------------------------------------------------------------------------
+r2329 | vlefevre | 2003-06-12 16:13:49 +0000 (Thu, 12 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/terf.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+
+Replaced misc random functions by GMP ones.
+
+------------------------------------------------------------------------
+r2328 | vlefevre | 2003-06-12 13:52:56 +0000 (Thu, 12 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tests.c
+
+Added function randlimb().
+
+------------------------------------------------------------------------
+r2327 | vlefevre | 2003-06-12 11:37:31 +0000 (Thu, 12 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/erf.c
+
+Fixed a few bugs concerning special values, code simplified.
+
+------------------------------------------------------------------------
+r2326 | zimmerma | 2003-06-12 09:10:34 +0000 (Thu, 12 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/algorithms.tex
+ A /trunk/erf.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/terf.c
+
+added error function
+
+------------------------------------------------------------------------
+r2325 | vlefevre | 2003-06-11 23:38:43 +0000 (Wed, 11 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+
+Make x positive + some minor changes.
+
+------------------------------------------------------------------------
+r2324 | vlefevre | 2003-06-11 23:31:05 +0000 (Wed, 11 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+
+New version written by Torbjorn Granlund.
+
+------------------------------------------------------------------------
+r2323 | zimmerma | 2003-06-10 15:24:16 +0000 (Tue, 10 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+updated formular for erf
+added url for Abramowitz & Stegun
+
+------------------------------------------------------------------------
+r2322 | vlefevre | 2003-06-10 13:22:52 +0000 (Tue, 10 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+
+Added a comment concerning NO_MATH_DEFS.
+
+------------------------------------------------------------------------
+r2321 | zimmerma | 2003-06-10 08:43:05 +0000 (Tue, 10 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+made test faster
+
+------------------------------------------------------------------------
+r2320 | zimmerma | 2003-06-10 08:41:47 +0000 (Tue, 10 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+reduced test time
+
+------------------------------------------------------------------------
+r2319 | zimmerma | 2003-06-10 08:38:54 +0000 (Tue, 10 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+reduced time of test
+
+------------------------------------------------------------------------
+r2318 | zimmerma | 2003-06-10 08:20:21 +0000 (Tue, 10 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tfrac.c
+
+reduced time
+
+------------------------------------------------------------------------
+r2317 | ryde | 2003-06-09 22:48:18 +0000 (Mon, 09 Jun 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+
+Patch by Torbjorn: use puts not putchar, to avoid GNUPro compiler bug.
+
+------------------------------------------------------------------------
+r2316 | ryde | 2003-06-08 23:56:47 +0000 (Sun, 08 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+Disable "8093416094703476*2^(-1075)" because mips64
+SGI cc doesn't seem to like the value (a denorm).
+
+------------------------------------------------------------------------
+r2315 | ryde | 2003-06-08 22:44:59 +0000 (Sun, 08 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/get_d.c
+
+Include <stddef.h> before <math.h>, to avoid problems with
+gcc 3.2 on hppa2.0w-hp-hpux11.11.
+
+------------------------------------------------------------------------
+r2314 | ryde | 2003-06-08 22:35:03 +0000 (Sun, 08 Jun 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+(random): Remove prototype, since it conflicts with
+stdlib.h on osf4.
+
+------------------------------------------------------------------------
+r2313 | vlefevre | 2003-05-28 14:04:50 +0000 (Wed, 28 May 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tzeta.c
+
+Added prototypes of non-standard functions that weren't always defined.
+
+------------------------------------------------------------------------
+r2312 | vlefevre | 2003-05-28 08:44:17 +0000 (Wed, 28 May 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+MPFR_EXP_CHECK is now defined when WANT_ASSERT is defined.
+
+------------------------------------------------------------------------
+r2311 | vlefevre | 2003-05-26 20:31:56 +0000 (Mon, 26 May 2003) | 3 lines
+Changed paths:
+ M /trunk/zeta.c
+
+The special case s = 1 is taken into account (the previous code
+seemed to work, but perhaps not for rigorous reasons).
+
+------------------------------------------------------------------------
+r2310 | vlefevre | 2003-05-26 20:31:38 +0000 (Mon, 26 May 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+Added test for case s = 1.
+
+------------------------------------------------------------------------
+r2309 | vlefevre | 2003-05-26 15:34:17 +0000 (Mon, 26 May 2003) | 3 lines
+Changed paths:
+ M /trunk/round_prec.c
+
+(mpfr_round_prec): Bug fixed (case zero wasn't taken into account)
+and 'assertion failed' avoided.
+
+------------------------------------------------------------------------
+r2308 | vlefevre | 2003-05-26 15:20:27 +0000 (Mon, 26 May 2003) | 2 lines
+Changed paths:
+ M /trunk/add_one_ulp.c
+ M /trunk/div_ui.c
+ M /trunk/sub_one_ulp.c
+
+Update related to MPFR_GET_EXP and MPFR_SET_EXP.
+
+------------------------------------------------------------------------
+r2307 | vlefevre | 2003-05-26 14:46:42 +0000 (Mon, 26 May 2003) | 2 lines
+Changed paths:
+ M /trunk/rint.c
+
+MPFR_GET_EXP (r) -> exp.
+
+------------------------------------------------------------------------
+r2306 | vlefevre | 2003-05-26 13:20:54 +0000 (Mon, 26 May 2003) | 2 lines
+Changed paths:
+ M /trunk/swap.c
+
+Function mpfr_swap rewritten using memcpy.
+
+------------------------------------------------------------------------
+r2305 | vlefevre | 2003-05-26 12:03:59 +0000 (Mon, 26 May 2003) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+Updates/optimizations related to MPFR_GET_EXP and MPFR_SET_EXP.
+
+------------------------------------------------------------------------
+r2304 | vlefevre | 2003-05-26 11:47:04 +0000 (Mon, 26 May 2003) | 2 lines
+Changed paths:
+ M /trunk/add_ui.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub_ui.c
+
+Updates/optimizations related to MPFR_GET_EXP and MPFR_SET_EXP.
+
+------------------------------------------------------------------------
+r2303 | vlefevre | 2003-05-23 10:28:12 +0000 (Fri, 23 May 2003) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+
+Code clean-up. Assertion failed avoided.
+
+------------------------------------------------------------------------
+r2302 | vlefevre | 2003-05-22 22:11:01 +0000 (Thu, 22 May 2003) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r2301 | vlefevre | 2003-05-22 21:39:40 +0000 (Thu, 22 May 2003) | 8 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add_one_ulp.c
+ M /trunk/add_ui.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/div.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/eq.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/frac.c
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_exp.c
+ M /trunk/get_ld.c
+ M /trunk/get_si.c
+ M /trunk/get_str.c
+ M /trunk/get_ui.c
+ M /trunk/get_z_exp.c
+ M /trunk/hypot.c
+ M /trunk/isinteger.c
+ M /trunk/log.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/next.c
+ M /trunk/pow.c
+ M /trunk/print_raw.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_exp.c
+ M /trunk/set_f.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/sub_ui.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/zeta.c
+
+Macros MPFR_EXP_INVALID (invalid exponent value) and MPFR_EXP_CHECK
+added. Code update to use MPFR_GET_EXP and MPFR_SET_EXP instead of
+MPFR_EXP to allow more bug detection related to special values.
+Macros MPFR_SET_NAN, MPFR_SET_INF, MPFR_SET_ZERO and MPFR_INIT set
+the exponent of the number to MPFR_EXP_INVALID if MPFR_EXP_CHECK
+is defined. Compile with -DMPFR_EXP_CHECK and make check to see
+the potential problems; currently, 40 of 76 tests fail.
+
+------------------------------------------------------------------------
+r2300 | vlefevre | 2003-05-21 15:16:49 +0000 (Wed, 21 May 2003) | 2 lines
+Changed paths:
+ M /trunk/pow_ui.c
+ M /trunk/tests/tacos.c
+
+#include "gmp-impl.h" added.
+
+------------------------------------------------------------------------
+r2299 | vlefevre | 2003-05-21 14:49:03 +0000 (Wed, 21 May 2003) | 5 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+MPFR_ASSERTD: use MPFR_ASSERTN instead of ASSERT_ALWAYS so that
+it can be used as an expression.
+New macros MPFR_GET_EXP and MPFR_SET_EXP (they should almost
+completely replace MPFR_EXP).
+
+------------------------------------------------------------------------
+r2298 | zimmerma | 2003-05-19 15:04:20 +0000 (Mon, 19 May 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/teq.c
+
+added test 'special'
+
+------------------------------------------------------------------------
+r2297 | zimmerma | 2003-05-19 15:03:11 +0000 (Mon, 19 May 2003) | 2 lines
+Changed paths:
+ M /trunk/eq.c
+
+fixed bug when n_bits larger than size*BITS_PER_MP_LIMB
+
+------------------------------------------------------------------------
+r2296 | vlefevre | 2003-05-18 00:11:11 +0000 (Sun, 18 May 2003) | 2 lines
+Changed paths:
+ M /trunk/eq.c
+
+Bugs fixed (special cases).
+
+------------------------------------------------------------------------
+r2295 | zimmerma | 2003-05-13 16:02:44 +0000 (Tue, 13 May 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+removed dummy test tdump
+
+------------------------------------------------------------------------
+r2294 | zimmerma | 2003-05-13 16:00:44 +0000 (Tue, 13 May 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+compatibility with mpf is done
+
+------------------------------------------------------------------------
+r2293 | zimmerma | 2003-05-13 15:52:30 +0000 (Tue, 13 May 2003) | 3 lines
+Changed paths:
+ M /trunk/cmp_d.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr.texi
+
+updated mpfr_cmp_d
+added mpfr_cmp_d in mpf2mpfr.h and mpfr.texi
+
+------------------------------------------------------------------------
+r2292 | hanrot | 2003-05-13 15:03:49 +0000 (Tue, 13 May 2003) | 2 lines
+Changed paths:
+ A /trunk/cmp_d.c
+ A /trunk/tests/tcmp_d.c
+
+Added cmp_d.c, tcmp_d.c.
+
+------------------------------------------------------------------------
+r2291 | hanrot | 2003-05-13 15:03:07 +0000 (Tue, 13 May 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/mpf_compat.h
+
+Added cmp_d/tcmp_d.
+
+------------------------------------------------------------------------
+r2290 | zimmerma | 2003-04-11 10:08:39 +0000 (Fri, 11 Apr 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+ M /trunk/zeta.c
+
+moved test for NaN/Inf
+
+------------------------------------------------------------------------
+r2289 | zimmerma | 2003-04-11 09:54:23 +0000 (Fri, 11 Apr 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tzeta.c
+ M /trunk/zeta.c
+
+added Riemann Zeta function (contribution from Jean-Luc Re'my)
+
+------------------------------------------------------------------------
+r2288 | ryde | 2003-04-08 23:50:59 +0000 (Tue, 08 Apr 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Move macros down below @copying.
+
+------------------------------------------------------------------------
+r2287 | ryde | 2003-04-08 23:43:51 +0000 (Tue, 08 Apr 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Add @: after various abbreviations.
+
+------------------------------------------------------------------------
+r2286 | zimmerma | 2003-04-01 11:49:34 +0000 (Tue, 01 Apr 2003) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+fixed pb with count_leading_zeros (n=0)
+
+------------------------------------------------------------------------
+r2285 | zimmerma | 2003-04-01 10:39:48 +0000 (Tue, 01 Apr 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added test for bug found by Franky Backeljauw
+
+------------------------------------------------------------------------
+r2284 | zimmerma | 2003-04-01 10:39:14 +0000 (Tue, 01 Apr 2003) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+fixed bug found by Franky
+
+------------------------------------------------------------------------
+r2283 | vlefevre | 2003-03-28 12:56:46 +0000 (Fri, 28 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+
+Added some asserts.
+
+------------------------------------------------------------------------
+r2282 | zimmerma | 2003-03-28 09:22:37 +0000 (Fri, 28 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tconst_pi.c
+
+fixed pb found by Will Galway <galway@pims.math.ca> (continued)
+
+------------------------------------------------------------------------
+r2281 | hanrot | 2003-03-28 09:13:19 +0000 (Fri, 28 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+ M /trunk/tests/tconst_pi.c
+
+Patches from W. Galway.
+
+------------------------------------------------------------------------
+r2280 | zimmerma | 2003-03-28 08:40:59 +0000 (Fri, 28 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed reference to Plouffe/Bailey/Borwein formula
+
+------------------------------------------------------------------------
+r2279 | hanrot | 2003-03-27 09:37:37 +0000 (Thu, 27 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/const_pi.c
+
+Credits for the pi formula modified.
+
+------------------------------------------------------------------------
+r2278 | zimmerma | 2003-03-26 10:01:02 +0000 (Wed, 26 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+
+changed back "unsigned char *" to "char *"
+
+------------------------------------------------------------------------
+r2277 | zimmerma | 2003-03-25 09:17:50 +0000 (Tue, 25 Mar 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+
+char * -> const unsigned char * for mpfr_set_str, mpfr_set_str_raw,
+and mpfr_init_set_str
+
+------------------------------------------------------------------------
+r2276 | zimmerma | 2003-03-24 13:24:54 +0000 (Mon, 24 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/get_ld.c
+
+removed unused variable
+
+------------------------------------------------------------------------
+r2275 | zimmerma | 2003-03-18 10:55:37 +0000 (Tue, 18 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed documentation bug in mpfr_log2 (exact results)
+
+------------------------------------------------------------------------
+r2274 | zimmerma | 2003-03-18 09:05:42 +0000 (Tue, 18 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+changed new test in 'check4' style
+
+------------------------------------------------------------------------
+r2273 | vlefevre | 2003-03-17 02:08:03 +0000 (Mon, 17 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/mpfr.texi
+
+Update concerning underflow problems.
+
+------------------------------------------------------------------------
+r2272 | ryde | 2003-03-17 00:20:46 +0000 (Mon, 17 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+(main): Comment out underflows(), until it works.
+
+------------------------------------------------------------------------
+r2271 | ryde | 2003-03-17 00:04:41 +0000 (Mon, 17 Mar 2003) | 3 lines
+Changed paths:
+ M /trunk/get_z_exp.c
+
+Comment out an assert tickled for an f with exponent
+near MPFR_EMIN_MIN.
+
+------------------------------------------------------------------------
+r2270 | ryde | 2003-03-16 23:32:38 +0000 (Sun, 16 Mar 2003) | 7 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+(LONGDOUBLE_NAN_ACTION): New version for IEEE quad big
+endian, fixing HP cc.
+(WANT_LONGDOUBLE_VOLATILE): New define for when LONGDOUBLE_VOLATILE is
+wanted.
+(WANT_GMPFR_LONGDOUBLE_VOLATILE): New define for when
+__gmpfr_longdouble_volatile is wanted.
+
+------------------------------------------------------------------------
+r2269 | ryde | 2003-03-16 23:32:05 +0000 (Sun, 16 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/volatile.c
+
+Use WANT_GMPFR_LONGDOUBLE_VOLATILE.
+
+------------------------------------------------------------------------
+r2268 | ryde | 2003-03-16 23:29:27 +0000 (Sun, 16 Mar 2003) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(MPFR_C_LONG_DOUBLE_FORMAT): Add IEEE quad big endian,
+check long double exists before testing.
+
+------------------------------------------------------------------------
+r2267 | vlefevre | 2003-03-14 11:55:34 +0000 (Fri, 14 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Added underflow test showing a bug in mpfr_pow.
+
+------------------------------------------------------------------------
+r2266 | zimmerma | 2003-03-14 08:22:36 +0000 (Fri, 14 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+fixed bug for x=1
+
+------------------------------------------------------------------------
+r2265 | vlefevre | 2003-03-14 01:50:48 +0000 (Fri, 14 Mar 2003) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/pow.c
+
+This wasn't a compiler bug; mpfr_pow is really buggy.
+Added some asserts to show that.
+
+------------------------------------------------------------------------
+r2264 | vlefevre | 2003-03-14 01:12:44 +0000 (Fri, 14 Mar 2003) | 5 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/tests/tpow.c
+
+The infinite loop concerning 1^0.5 was probably due to a bug in the
+compiler [cc (GCC) 3.2.3 20030309 (Debian prerelease)]: adding some
+printf's changes the values of the variables and the correct result
+is returned.
+
+------------------------------------------------------------------------
+r2263 | zimmerma | 2003-03-13 17:11:52 +0000 (Thu, 13 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+fixed sign problem in particular_cases()
+
+------------------------------------------------------------------------
+r2262 | zimmerma | 2003-03-13 17:10:45 +0000 (Thu, 13 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/ui_pow.c
+
+declared mpfr_ui_pow_is_exact as static
+
+------------------------------------------------------------------------
+r2261 | zimmerma | 2003-03-13 17:10:02 +0000 (Thu, 13 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+
+gnu-style
+
+------------------------------------------------------------------------
+r2260 | vlefevre | 2003-03-13 00:26:48 +0000 (Thu, 13 Mar 2003) | 4 lines
+Changed paths:
+ M /trunk/tests/tpow3.c
+
+Removed some useless and inaccurate tests on NaN, infinities, zeros
+(as the behavior of mpfr_pow on such particular cases has changed);
+similar tests were added to "tests/tpow.c".
+
+------------------------------------------------------------------------
+r2259 | vlefevre | 2003-03-13 00:15:19 +0000 (Thu, 13 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/tests/tpow.c
+
+Test of mpfr_pow: particular cases. Bugs.
+
+------------------------------------------------------------------------
+r2258 | vlefevre | 2003-03-12 18:19:59 +0000 (Wed, 12 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+ M /trunk/tests/tpow3.c
+
+Special cases for mpfr_pow().
+
+------------------------------------------------------------------------
+r2257 | zimmerma | 2003-03-11 17:32:46 +0000 (Tue, 11 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/out_str.c
+
+when stream=NULL, use stdout (as indicated in the documentation)
+
+------------------------------------------------------------------------
+r2256 | vlefevre | 2003-03-03 06:04:29 +0000 (Mon, 03 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+mpfr_sin_sign -> static.
+
+------------------------------------------------------------------------
+r2255 | vlefevre | 2003-03-03 06:03:24 +0000 (Mon, 03 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+Useless declaration removed.
+
+------------------------------------------------------------------------
+r2254 | vlefevre | 2003-03-03 05:51:30 +0000 (Mon, 03 Mar 2003) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+
+Special cases for mpfr_pow: like Section F.9.4.4 of the
+ISO C99 standard.
+
+------------------------------------------------------------------------
+r2253 | vlefevre | 2003-03-03 05:14:18 +0000 (Mon, 03 Mar 2003) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+Prototype fixed.
+
+------------------------------------------------------------------------
+r2252 | vlefevre | 2003-02-27 10:20:34 +0000 (Thu, 27 Feb 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/set_str.c
+ M /trunk/tests/tset_str.c
+
+mpfr_set_str now accepts a binary exponent for base 16
+(as defined by the ISO C99 standard).
+
+------------------------------------------------------------------------
+r2251 | vlefevre | 2003-02-27 05:32:01 +0000 (Thu, 27 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Comment concerning the installation of MPFR: done.
+
+------------------------------------------------------------------------
+r2250 | vlefevre | 2003-02-27 05:18:56 +0000 (Thu, 27 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/mpfr.texi
+
+New recommendation to install MPFR.
+
+------------------------------------------------------------------------
+r2249 | hanrot | 2003-02-24 12:32:56 +0000 (Mon, 24 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/dump.c
+ M /trunk/get_str.c
+ M /trunk/out_str.c
+ M /trunk/print_raw.c
+ M /trunk/set_str.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tset_str.c
+
+Replaced NaN, Inf by @NaN@, @Inf@ [for bases > 24].
+
+------------------------------------------------------------------------
+r2248 | zimmerma | 2003-02-21 15:06:24 +0000 (Fri, 21 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/thypot.c
+
+added one test
+
+------------------------------------------------------------------------
+r2247 | vlefevre | 2003-02-21 15:04:06 +0000 (Fri, 21 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/get_ui.c
+
+Fixed cast (though unnecessary).
+
+------------------------------------------------------------------------
+r2246 | zimmerma | 2003-02-21 13:07:46 +0000 (Fri, 21 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added one test
+
+------------------------------------------------------------------------
+r2245 | zimmerma | 2003-02-13 15:31:51 +0000 (Thu, 13 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added mpf_compat, mpfr_compat
+
+------------------------------------------------------------------------
+r2244 | zimmerma | 2003-02-13 15:30:41 +0000 (Thu, 13 Feb 2003) | 2 lines
+Changed paths:
+ A /trunk/tests/mpf_compat.c
+ A /trunk/tests/mpf_compat.h
+ A /trunk/tests/mpfr_compat.c
+
+test files for mpf-mpfr compatibility
+
+------------------------------------------------------------------------
+r2243 | zimmerma | 2003-02-13 15:29:27 +0000 (Thu, 13 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+added mpfr_init_set_str
+
+------------------------------------------------------------------------
+r2242 | zimmerma | 2003-02-13 14:50:37 +0000 (Thu, 13 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added "const" to char* arg. of mpfr_init_set_str
+
+------------------------------------------------------------------------
+r2241 | zimmerma | 2003-02-13 14:49:47 +0000 (Thu, 13 Feb 2003) | 3 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+added macros for new mpfr functions
+changed some old macros
+
+------------------------------------------------------------------------
+r2240 | zimmerma | 2003-02-13 08:57:19 +0000 (Thu, 13 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/frac.c
+ M /trunk/isinteger.c
+ M /trunk/log10.c
+ M /trunk/pow.c
+ M /trunk/tests/tpow3.c
+
+mpfr_isinteger -> mpfr_integer_p
+
+------------------------------------------------------------------------
+r2239 | zimmerma | 2003-02-13 08:56:34 +0000 (Thu, 13 Feb 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+document new functions (fits_*, get_ui, get_si, get_d_2exp)
+added integer_p that was not documented
+
+------------------------------------------------------------------------
+r2238 | zimmerma | 2003-02-13 08:55:23 +0000 (Thu, 13 Feb 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr_isinteger -> mpfr_integer_p
+new functions: mpfr_fits_*, mpfr_get_ui, mpfr_get_si, mpfr_get_d_2exp
+
+------------------------------------------------------------------------
+r2237 | zimmerma | 2003-02-13 08:53:54 +0000 (Thu, 13 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+
+added mpfr_get_d_2exp
+
+------------------------------------------------------------------------
+r2236 | zimmerma | 2003-02-13 08:52:15 +0000 (Thu, 13 Feb 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+new functions mpfr_fits_* and mpfr_get_ui/si
+
+------------------------------------------------------------------------
+r2235 | zimmerma | 2003-02-13 08:51:29 +0000 (Thu, 13 Feb 2003) | 2 lines
+Changed paths:
+ A /trunk/fits_s.h
+ A /trunk/fits_sint.c
+ A /trunk/fits_slong.c
+ A /trunk/fits_sshort.c
+ A /trunk/fits_u.h
+ A /trunk/fits_uint.c
+ A /trunk/fits_ulong.c
+ A /trunk/fits_ushort.c
+ A /trunk/get_si.c
+ A /trunk/get_ui.c
+
+new functions mpfr_fits_* and mpfr_get_[us]i
+
+------------------------------------------------------------------------
+r2234 | zimmerma | 2003-01-27 10:13:37 +0000 (Mon, 27 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+check for +/-0.0 after variable set to NaN
+
+------------------------------------------------------------------------
+r2233 | vlefevre | 2003-01-25 02:44:06 +0000 (Sat, 25 Jan 2003) | 4 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Suppressed the underscores of AC_CHECK_LIBM in comments, otherwise
+aclocal 1.4-p6 includes libtool code in aclocal.m4 and this leads
+to compilation problems.
+
+------------------------------------------------------------------------
+r2232 | ryde | 2003-01-25 00:44:05 +0000 (Sat, 25 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+(_MPFR_H_HAVE_FILE): Copy FILE define tests from gmp.h, adds
+Borland, Microsoft and Apple MPW.
+
+------------------------------------------------------------------------
+r2231 | ryde | 2003-01-25 00:28:59 +0000 (Sat, 25 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+(libmpfr_a_SOURCES): Add volatile.c.
+
+------------------------------------------------------------------------
+r2230 | ryde | 2003-01-25 00:28:30 +0000 (Sat, 25 Jan 2003) | 2 lines
+Changed paths:
+ A /trunk/volatile.c
+
+New file.
+
+------------------------------------------------------------------------
+r2229 | ryde | 2003-01-25 00:28:04 +0000 (Sat, 25 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+(Isnan_ld): New function based on LONGDOUBLE_NAN_ACTION, use it
+instead of LONGDOUBLE_ISNAN.
+
+------------------------------------------------------------------------
+r2228 | ryde | 2003-01-25 00:21:21 +0000 (Sat, 25 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+(LONGDOUBLE_ISNAN): Remove.
+
+------------------------------------------------------------------------
+r2227 | ryde | 2003-01-25 00:21:02 +0000 (Sat, 25 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+(LONGDOUBLE_ISNAN): Remove this, use LONGDOUBLE_NAN_ACTION instead.
+
+------------------------------------------------------------------------
+r2226 | ryde | 2003-01-25 00:20:07 +0000 (Sat, 25 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+(LONGDOUBLE_NAN_ACTION): New macro.
+
+------------------------------------------------------------------------
+r2225 | ryde | 2003-01-24 21:47:56 +0000 (Fri, 24 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Allow "e" exponent in base<=10 not <10. Restrict "E"
+exponent to base<=10 too, since digits are not case sensitive.
+
+------------------------------------------------------------------------
+r2224 | vlefevre | 2003-01-24 19:08:07 +0000 (Fri, 24 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+
+Prototypes: use static. Some code reformatting.
+
+------------------------------------------------------------------------
+r2223 | vlefevre | 2003-01-24 16:49:54 +0000 (Fri, 24 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+The sign wasn't set when the result was zero.
+
+------------------------------------------------------------------------
+r2222 | ryde | 2003-01-24 16:17:04 +0000 (Fri, 24 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Reject "", "+" and "-", also fixing an attempt to allocate a 0 length
+block in these cases.
+
+------------------------------------------------------------------------
+r2221 | ryde | 2003-01-24 16:03:35 +0000 (Fri, 24 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Clear NAN and INF flags when setting result to zero.
+
+------------------------------------------------------------------------
+r2220 | vlefevre | 2003-01-24 11:29:42 +0000 (Fri, 24 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/tui_sub.c
+
+Fixed prototypes (use static...).
+
+------------------------------------------------------------------------
+r2219 | vlefevre | 2003-01-24 11:28:34 +0000 (Fri, 24 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tcbrt.c
+
+Missing #include.
+
+------------------------------------------------------------------------
+r2218 | zimmerma | 2003-01-23 13:16:00 +0000 (Thu, 23 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+workaround for gcc bug on m68040-unknown-netbsd1.4.1
+
+------------------------------------------------------------------------
+r2217 | zimmerma | 2003-01-23 12:41:31 +0000 (Thu, 23 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+added cast to double
+
+------------------------------------------------------------------------
+r2216 | ryde | 2003-01-23 00:00:29 +0000 (Thu, 23 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Use mpfr_set_nan and mpfr_set_inf for NaN and Inf tests,
+not "double" nans and infs.
+
+------------------------------------------------------------------------
+r2215 | ryde | 2003-01-22 23:40:43 +0000 (Wed, 22 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+Use mpfr_set_nan and mpfr_set_inf for NaN and Inf tests,
+not "double" nans and infs.
+
+------------------------------------------------------------------------
+r2214 | ryde | 2003-01-22 23:32:19 +0000 (Wed, 22 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_sub.c
+
+Use mpfr_set_nan and mpfr_set_inf for NaN and Inf tests,
+not "double" nans and infs.
+
+------------------------------------------------------------------------
+r2213 | ryde | 2003-01-22 22:59:46 +0000 (Wed, 22 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tgamma.c
+
+Use tests_start_mpfr / tests_end_mpfr.
+
+------------------------------------------------------------------------
+r2212 | ryde | 2003-01-22 22:39:38 +0000 (Wed, 22 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tcbrt.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tzeta.c
+
+Use tests_start_mpfr / tests_end_mpfr.
+
+------------------------------------------------------------------------
+r2211 | ryde | 2003-01-22 22:34:54 +0000 (Wed, 22 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+Use tests_start_mpfr / tests_end_mpfr.
+(check_large): Use __gmp_free_func to free mpfr_get_str result.
+
+------------------------------------------------------------------------
+r2210 | ryde | 2003-01-22 22:27:46 +0000 (Wed, 22 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+Use mpfr_set_nan and mpfr_set_inf for NaN and Inf tests,
+not "double" nans and infs. Use tests_start_mpfr / tests_end_mpfr.
+
+------------------------------------------------------------------------
+r2209 | ryde | 2003-01-22 22:24:50 +0000 (Wed, 22 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+Use mpfr_set_nan and mpfr_set_inf for NaN and Inf tests,
+not "double" nans and infs.
+
+------------------------------------------------------------------------
+r2208 | ryde | 2003-01-22 22:18:09 +0000 (Wed, 22 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+Remove tests involving "double" nans and infs, covered by check_nan.
+
+------------------------------------------------------------------------
+r2207 | ryde | 2003-01-22 22:15:49 +0000 (Wed, 22 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/ttan.c
+
+Use mpfr_set_nan and mpfr_set_inf for NaN and Inf tests,
+not "double" nans and infs.
+
+------------------------------------------------------------------------
+r2206 | ryde | 2003-01-18 00:31:30 +0000 (Sat, 18 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Move log_b2.h from include_HEADERS to libmpfr_a_SOURCES, it doesn't
+want to be installed.
+
+------------------------------------------------------------------------
+r2205 | ryde | 2003-01-18 00:14:32 +0000 (Sat, 18 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Correction to memory leak fix, need "result" for final rounding.
+
+------------------------------------------------------------------------
+r2204 | ryde | 2003-01-17 23:50:10 +0000 (Fri, 17 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Fix two memory leaks.
+
+------------------------------------------------------------------------
+r2203 | ryde | 2003-01-17 23:08:05 +0000 (Fri, 17 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+(LDADD): Add $(MPFR_LIBM).
+
+------------------------------------------------------------------------
+r2202 | ryde | 2003-01-17 23:00:42 +0000 (Fri, 17 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Remove -lm setups, now handled by MPFR_CHECK_LIBM.
+
+------------------------------------------------------------------------
+r2201 | ryde | 2003-01-17 22:59:51 +0000 (Fri, 17 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(MPFR_CHECK_LIBM): New macro.
+(MPFR_CONFIGS): Use it.
+
+------------------------------------------------------------------------
+r2200 | zimmerma | 2003-01-17 14:59:48 +0000 (Fri, 17 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/NEWS
+ M /trunk/README
+ M /trunk/TODO
+ M /trunk/acinclude.m4
+
+added copyright notices and license statements
+
+------------------------------------------------------------------------
+r2199 | zimmerma | 2003-01-17 08:58:45 +0000 (Fri, 17 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+now use __gmpfr_floor_log2 instead of floor/log to get rid of math.h
+
+------------------------------------------------------------------------
+r2198 | zimmerma | 2003-01-17 08:52:49 +0000 (Fri, 17 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+removed unused function dagm(), and get rid of math.h
+added tests for NaN, Inf's
+
+------------------------------------------------------------------------
+r2197 | vlefevre | 2003-01-17 00:55:13 +0000 (Fri, 17 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Re-added $OBJEXT, using AC_REQUIRE([AC_OBJEXT]) for old autoconf.
+
+------------------------------------------------------------------------
+r2196 | zimmerma | 2003-01-16 17:46:17 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+put back math.h
+
+------------------------------------------------------------------------
+r2195 | zimmerma | 2003-01-16 17:44:13 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+added back math.h (for sqrt)
+
+------------------------------------------------------------------------
+r2194 | zimmerma | 2003-01-16 17:32:19 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added log_b2.h in include_HEADERS
+
+------------------------------------------------------------------------
+r2193 | zimmerma | 2003-01-16 17:28:18 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added tsin_cos
+
+------------------------------------------------------------------------
+r2192 | zimmerma | 2003-01-16 17:23:25 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added #ifdef HAVE_DENORMS for denormalized test
+
+------------------------------------------------------------------------
+r2191 | zimmerma | 2003-01-16 17:18:07 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tsub.c
+
+removed math.h
+
+------------------------------------------------------------------------
+r2190 | zimmerma | 2003-01-16 17:13:43 +0000 (Thu, 16 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+
+added year 2003 in copyright line
+removed math.h
+
+------------------------------------------------------------------------
+r2189 | zimmerma | 2003-01-16 17:01:07 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+added 2003, removed math.h
+
+------------------------------------------------------------------------
+r2188 | zimmerma | 2003-01-16 16:58:56 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/memory.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tset_str.c
+
+added 2003
+
+------------------------------------------------------------------------
+r2187 | zimmerma | 2003-01-16 16:57:37 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+ M /trunk/tests/trandom.c
+
+removed math.h
+
+------------------------------------------------------------------------
+r2186 | zimmerma | 2003-01-16 16:52:51 +0000 (Thu, 16 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added year 2003
+removed math.h
+
+------------------------------------------------------------------------
+r2185 | zimmerma | 2003-01-16 16:40:46 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+patch for compiler bug on hppa2.0w-hp-hpux11.11
+
+------------------------------------------------------------------------
+r2184 | vlefevre | 2003-01-16 16:33:05 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+Macro LONGDOUBLE_ISNAN wasn't defined.
+
+------------------------------------------------------------------------
+r2183 | zimmerma | 2003-01-16 16:04:04 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+now always define Isnan
+
+------------------------------------------------------------------------
+r2182 | zimmerma | 2003-01-16 16:03:34 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+moved LONGDOUBLE_ISNAN to mpfr-test.h
+
+------------------------------------------------------------------------
+r2181 | zimmerma | 2003-01-16 16:03:04 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+removed check from isnan
+
+------------------------------------------------------------------------
+r2180 | zimmerma | 2003-01-16 16:01:55 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tests.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_ld.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+replaced isnan() by Isnan()
+
+------------------------------------------------------------------------
+r2179 | vlefevre | 2003-01-16 13:58:55 +0000 (Thu, 16 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+AC_PREREQ(2.50) added (useful when both autoconf 2.13 and autoconf
+2.50 are installed, with a wrapper to select the required version).
+
+------------------------------------------------------------------------
+r2178 | vlefevre | 2003-01-16 13:30:03 +0000 (Thu, 16 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+Comment in mpfr_test_init: s/preprocessor/compiler/.
+
+------------------------------------------------------------------------
+r2177 | zimmerma | 2003-01-16 13:26:53 +0000 (Thu, 16 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+fixed pb in mpfr_test_init with the compiler optimizing too much
+(this happened on Alpha with -O1 or higher)
+
+------------------------------------------------------------------------
+r2176 | vlefevre | 2003-01-15 20:43:58 +0000 (Wed, 15 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+Standard prototype only. Particular cases added.
+
+------------------------------------------------------------------------
+r2175 | zimmerma | 2003-01-15 17:29:10 +0000 (Wed, 15 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/set_str.c
+
+moved common prototype for mpn_exp in mpfr-impl.h
+
+------------------------------------------------------------------------
+r2174 | zimmerma | 2003-01-15 17:28:33 +0000 (Wed, 15 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+removed spurious ; after MPFR_ESIZE
+added prototype for mpn_exp
+
+------------------------------------------------------------------------
+r2173 | zimmerma | 2003-01-15 17:17:17 +0000 (Wed, 15 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed items done
+
+------------------------------------------------------------------------
+r2172 | zimmerma | 2003-01-15 17:14:32 +0000 (Wed, 15 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+new tests from Alain Delplanque
+
+------------------------------------------------------------------------
+r2171 | zimmerma | 2003-01-15 17:13:50 +0000 (Wed, 15 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/set_str.c
+
+new version using mpn_set_str
+[written by Alain Delplanque, edited by Paul Zimmermann]
+
+------------------------------------------------------------------------
+r2170 | vlefevre | 2003-01-15 13:05:06 +0000 (Wed, 15 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Replace $OBJEXT by o (as $OBJEXT isn't defined everywhere).
+
+------------------------------------------------------------------------
+r2169 | vlefevre | 2003-01-15 12:50:13 +0000 (Wed, 15 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+A ` must be quoted to avoid an error with Autoconf 2.13.
+
+------------------------------------------------------------------------
+r2168 | vlefevre | 2003-01-15 11:40:35 +0000 (Wed, 15 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Use type mp_prec_t for precisions.
+
+------------------------------------------------------------------------
+r2167 | vlefevre | 2003-01-15 11:29:46 +0000 (Wed, 15 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Source re-indented.
+
+------------------------------------------------------------------------
+r2166 | vlefevre | 2003-01-15 11:22:26 +0000 (Wed, 15 Jan 2003) | 4 lines
+Changed paths:
+ M /trunk/gamma.c
+
+Several bugs fixed concerning the particular cases.
+<stdio.h> and <stdlib.h> not included by default.
+int mpfr_gamma _PROTO ... removed (was useless).
+
+------------------------------------------------------------------------
+r2165 | zimmerma | 2003-01-15 09:54:12 +0000 (Wed, 15 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+
+get rid of ceil() call, that requires -lm
+
+------------------------------------------------------------------------
+r2164 | ryde | 2003-01-14 23:02:26 +0000 (Tue, 14 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/get_ld.c
+
+Force LDBL_MANT_DIG on IEEE extended, to avoid problems with
+some i386 gcc.
+
+------------------------------------------------------------------------
+r2163 | ryde | 2003-01-14 22:48:03 +0000 (Tue, 14 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+Avoid problems with bad LDBL_MAX and LDBL_MANT_DIG on some i386 gcc.
+
+------------------------------------------------------------------------
+r2162 | ryde | 2003-01-14 22:43:24 +0000 (Tue, 14 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(MPFR_C_LONG_DOUBLE_FORMAT): New macro.
+(MPFR_CONFIGS): Use it.
+
+------------------------------------------------------------------------
+r2161 | vlefevre | 2003-01-11 19:32:47 +0000 (Sat, 11 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/memory.c
+
+Required casts added (and switch from uint to ulong);
+in particular, useful on Alpha.
+
+------------------------------------------------------------------------
+r2160 | ryde | 2003-01-10 21:42:53 +0000 (Fri, 10 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/get_ld.c
+ M /trunk/set_ld.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/trandom.c
+
+# Add a copyright year.
+
+------------------------------------------------------------------------
+r2159 | ryde | 2003-01-10 21:31:31 +0000 (Fri, 10 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+
+Tolerate empty argv[1], which can arise from ancient bash executing
+the libtool shared library wrapper script.
+
+------------------------------------------------------------------------
+r2158 | ryde | 2003-01-10 20:59:19 +0000 (Fri, 10 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tconst_pi.c
+
+Tolerate empty argv[1], which can arise from ancient bash executing
+the libtool shared library wrapper script.
+
+------------------------------------------------------------------------
+r2157 | ryde | 2003-01-10 15:39:03 +0000 (Fri, 10 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/get_ld.c
+
+Avoid unnecessary extra power of 2 squaring, so as not to provoke an
+overflow exception when result is in range.
+
+------------------------------------------------------------------------
+r2156 | vlefevre | 2003-01-10 13:41:42 +0000 (Fri, 10 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+Extended precision detection fixed.
+
+------------------------------------------------------------------------
+r2155 | zimmerma | 2003-01-09 14:06:37 +0000 (Thu, 09 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/get_ld.c
+
+fixed possible overflow when EXP=1024
+
+------------------------------------------------------------------------
+r2154 | zimmerma | 2003-01-09 14:05:30 +0000 (Thu, 09 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+rewritten to avoid overflows
+
+------------------------------------------------------------------------
+r2153 | zimmerma | 2003-01-09 09:56:04 +0000 (Thu, 09 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+added one test
+
+------------------------------------------------------------------------
+r2152 | ryde | 2003-01-08 23:14:50 +0000 (Wed, 08 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/tests.c
+ M /trunk/tests/tset_ld.c
+
+# Add a copyright year.
+
+------------------------------------------------------------------------
+r2151 | ryde | 2003-01-08 23:09:51 +0000 (Wed, 08 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr-test.h
+
+#Add a copyright year.
+
+------------------------------------------------------------------------
+r2150 | ryde | 2003-01-08 23:04:40 +0000 (Wed, 08 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/get_str.c
+
+(mpn_exp): Don't store -1 in a uint then return it as a long.
+Fixes systems such as alpha where sizeof(uint)!=sizeof(long).
+
+------------------------------------------------------------------------
+r2149 | ryde | 2003-01-08 22:07:59 +0000 (Wed, 08 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(AC_CHECK_HEADERS): Remove fpu_control.h, no longer required.
+
+------------------------------------------------------------------------
+r2148 | ryde | 2003-01-08 21:17:29 +0000 (Wed, 08 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+Use tests_machine_prec_long_double.
+Use LDBL_MAX for largest value and to find largest power of 2.
+
+------------------------------------------------------------------------
+r2147 | ryde | 2003-01-08 21:03:01 +0000 (Wed, 08 Jan 2003) | 4 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+(__setfpucw, _FPU_EXTENDED, etc): Remove these setups.
+(tests_machine_prec_double, tests_machine_prec_long_double,
+x86_fstcw, x86_fldcw): Add prototypes.
+
+------------------------------------------------------------------------
+r2146 | ryde | 2003-01-08 21:00:32 +0000 (Wed, 08 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/tests/tests.c
+
+(tests_machine_prec_double, tests_machine_prec_long_double): New functions.
+(mpfr_test_init): Replace __setfpucw with tests_machine_prec_double.
+
+------------------------------------------------------------------------
+r2145 | ryde | 2003-01-08 20:52:04 +0000 (Wed, 08 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(MPFR_CONFIGS): Add tests/x86.asm support.
+
+------------------------------------------------------------------------
+r2144 | ryde | 2003-01-08 20:48:47 +0000 (Wed, 08 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+(X86_PATTERN): New define, supporting acinclude.m4.
+
+------------------------------------------------------------------------
+r2143 | ryde | 2003-01-08 20:43:02 +0000 (Wed, 08 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+Add x86.asm support.
+
+------------------------------------------------------------------------
+r2142 | ryde | 2003-01-08 20:35:33 +0000 (Wed, 08 Jan 2003) | 2 lines
+Changed paths:
+ A /trunk/tests/x86.asm
+
+New file.
+
+------------------------------------------------------------------------
+r2141 | zimmerma | 2003-01-07 10:31:43 +0000 (Tue, 07 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+fixed pb for underflow and rounding to nearest
+
+------------------------------------------------------------------------
+r2140 | zimmerma | 2003-01-07 09:25:47 +0000 (Tue, 07 Jan 2003) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/set_ld.c
+
+added macro LONGDOUBLE_ISNAN
+use LONGDOUBLE_ISNAN in set_ld instead of cast to double and DOUBLE_ISNAN
+(did raise exception under freebsd)
+
+------------------------------------------------------------------------
+r2139 | vlefevre | 2003-01-07 01:46:51 +0000 (Tue, 07 Jan 2003) | 4 lines
+Changed paths:
+ M /trunk/exp2.c
+
+Added assertions that can be resolved at compile time: the exponents
+must be representable in a long int (IMHO, this limitation should be
+avoided in a clean way).
+
+------------------------------------------------------------------------
+r2138 | ryde | 2003-01-06 21:56:38 +0000 (Mon, 06 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Remove mpfr_get_ld, done.
+
+------------------------------------------------------------------------
+r2137 | ryde | 2003-01-06 21:53:01 +0000 (Mon, 06 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Remove mpfr_set_machine_rnd_mode, done.
+
+------------------------------------------------------------------------
+r2136 | vlefevre | 2003-01-06 21:48:33 +0000 (Mon, 06 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+Bug fix: __mpfr_emax -> __gmpfr_emax.
+
+------------------------------------------------------------------------
+r2135 | ryde | 2003-01-06 21:47:37 +0000 (Mon, 06 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Use separate function calls to second strncasecmp and strncmp
+for consistency and to avoid gcc warnings.
+
+------------------------------------------------------------------------
+r2134 | zimmerma | 2003-01-06 19:28:25 +0000 (Mon, 06 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/tests/texp2.c
+
+fixed infinite loop for 2^integer
+
+------------------------------------------------------------------------
+r2133 | vlefevre | 2003-01-06 10:30:52 +0000 (Mon, 06 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Use digit_value_in_base for the part after the '.'.
+
+------------------------------------------------------------------------
+r2132 | vlefevre | 2003-01-06 10:11:15 +0000 (Mon, 06 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Static function digit_value_in_base is now compatible with any locale.
+
+------------------------------------------------------------------------
+r2131 | ryde | 2003-01-03 23:07:37 +0000 (Fri, 03 Jan 2003) | 3 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tests.c
+
+(<sys/fpu.h>) [__mips]: Move from mpfr-test.h to tests/tests.c,
+and conditionalize with HAVE_SYS_FPU_H.
+
+------------------------------------------------------------------------
+r2130 | ryde | 2003-01-03 23:03:35 +0000 (Fri, 03 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(AC_CHECK_HEADERS): Add sys/fpu.h.
+
+------------------------------------------------------------------------
+r2129 | ryde | 2003-01-03 23:02:12 +0000 (Fri, 03 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+(HAVE_DENORMS) [__mips]: Remove this, let the configure test decide.
+
+------------------------------------------------------------------------
+r2128 | ryde | 2003-01-03 21:47:20 +0000 (Fri, 03 Jan 2003) | 4 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Use separate function calls to strncasecmp and strncmp, rather than
+?: on function pointers, since the latter demands declarations not
+present on SunOS. Both forms are optimized the same by gcc.
+
+------------------------------------------------------------------------
+r2127 | vlefevre | 2003-01-03 21:38:33 +0000 (Fri, 03 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Added some potential bugs (mpfr_exp2 is known to have such a bug).
+
+------------------------------------------------------------------------
+r2126 | ryde | 2003-01-02 23:48:32 +0000 (Thu, 02 Jan 2003) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tset_str.c
+
+Add gmp-impl.h for __gmp_free_func.
+
+------------------------------------------------------------------------
+r2125 | vlefevre | 2002-12-16 00:56:03 +0000 (Mon, 16 Dec 2002) | 15 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add1.c
+ M /trunk/add_one_ulp.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/factorial.c
+ M /trunk/gamma.c
+ M /trunk/gammaPiAGMformula.c
+ M /trunk/get_d.c
+ M /trunk/get_str.c
+ M /trunk/get_z_exp.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/next.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/save_expo.c
+ M /trunk/set.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_exp.c
+ M /trunk/set_nan.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sub1.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tests.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_pow.c
+
+Suppress some #define and fix symbol names (makes code cleaner):
+perl -pi -e 's/__mpfr_flags/__gmpfr_flags/g' **/*.{c,h}
+perl -pi -e 's/__mpfr_emin/__gmpfr_emin/g' **/*.{c,h}
+perl -pi -e 's/__mpfr_emax/__gmpfr_emax/g' **/*.{c,h}
+perl -pi -e 's/__mpfr_default_fp_bit_precision/__gmpfr_default_fp_bit_precision/g' **/*.{c,h}
+perl -pi -e 's/__gmp_default_rounding_mode/__gmpfr_default_rounding_mode/g' **/*.{c,h}
+perl -pi -e 's/__mpfr_const_log2_prec/__gmpfr_const_log2_prec/g' **/*.{c,h}
+perl -pi -e 's/__mpfr_const_pi_prec/__gmpfr_const_pi_prec/g' **/*.{c,h}
+perl -pi -e 's/_mpfr_ceil_log2/__gmpfr_ceil_log2/g' **/*.{c,h}
+perl -pi -e 's/_mpfr_floor_log2/__gmpfr_floor_log2/g' **/*.{c,h}
+perl -pi -e 's/_mpfr_ceil_exp2/__gmpfr_ceil_exp2/g' **/*.{c,h}
+perl -pi -e 's/_mpfr_isqrt/__gmpfr_isqrt/g' **/*.{c,h}
+perl -pi -e 's/_mpfr_cuberoot/__gmpfr_cuberoot/g' **/*.{c,h}
+perl -pi -e 's/^#define __gmpfr_.*\n//' *.h
+
+------------------------------------------------------------------------
+r2124 | vlefevre | 2002-12-13 18:06:58 +0000 (Fri, 13 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r2123 | vlefevre | 2002-12-13 18:01:04 +0000 (Fri, 13 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+IEEE 754 / IEEE P754 -> IEEE 754-1985.
+
+------------------------------------------------------------------------
+r2122 | vlefevre | 2002-12-13 11:20:28 +0000 (Fri, 13 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Correction.
+
+------------------------------------------------------------------------
+r2121 | vlefevre | 2002-12-13 11:19:25 +0000 (Fri, 13 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Added a note about the signed zero.
+
+------------------------------------------------------------------------
+r2120 | vlefevre | 2002-12-13 02:35:45 +0000 (Fri, 13 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Assertion re-added.
+
+------------------------------------------------------------------------
+r2119 | vlefevre | 2002-12-13 02:34:50 +0000 (Fri, 13 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/missing
+
+Update for new version of automake/autoconf.
+
+------------------------------------------------------------------------
+r2118 | vlefevre | 2002-12-13 02:23:23 +0000 (Fri, 13 Dec 2002) | 2 lines
+Changed paths:
+ A /trunk/depcomp
+
+depcomp script added for new version of automake.
+
+------------------------------------------------------------------------
+r2117 | ryde | 2002-12-12 22:30:05 +0000 (Thu, 12 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Don't -D define PACKAGE_VERSION etc, to avoid conflict with gmp config.h.
+
+------------------------------------------------------------------------
+r2116 | zimmerma | 2002-12-12 16:41:43 +0000 (Thu, 12 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added paragraph about accuracy
+
+------------------------------------------------------------------------
+r2115 | zimmerma | 2002-12-12 15:32:52 +0000 (Thu, 12 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+rewritten unclear paragraph about precision
+
+------------------------------------------------------------------------
+r2114 | zimmerma | 2002-12-12 14:42:42 +0000 (Thu, 12 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one item
+
+------------------------------------------------------------------------
+r2113 | zimmerma | 2002-12-12 14:38:03 +0000 (Thu, 12 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+use MPN_NORMALIZE_NOT_ZERO instead of loop
+
+------------------------------------------------------------------------
+r2112 | vlefevre | 2002-12-11 14:31:28 +0000 (Wed, 11 Dec 2002) | 3 lines
+Changed paths:
+ M /trunk/tests/memory.c
+
+Added #include "mpfr.h" (needed by mpfr-test.h as it uses
+mp_rnd_t in one of the prototypes).
+
+------------------------------------------------------------------------
+r2111 | vlefevre | 2002-12-10 22:23:04 +0000 (Tue, 10 Dec 2002) | 5 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Patch by Torbjorn Granlund <tege@swox.com>: Don't use TMP_ allocation
+mechanism for fixed size objects. Resulting streamlining. Misc
+addressing changes to work around GNUPro bugs.
+Patch by VL: Some other changes in mpfr_set_d.
+
+------------------------------------------------------------------------
+r2110 | vlefevre | 2002-12-07 12:26:11 +0000 (Sat, 07 Dec 2002) | 3 lines
+Changed paths:
+ M /trunk/const_euler.c
+
+(mpfr_const_euler_S, mpfr_const_euler_R)
+Make declaration match prototype (patch by Torbjorn Granlund).
+
+------------------------------------------------------------------------
+r2109 | vlefevre | 2002-12-04 11:22:24 +0000 (Wed, 04 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/config.guess
+ M /trunk/config.sub
+
+Update from ftp://ftp.gnu.org/pub/gnu/config/
+
+------------------------------------------------------------------------
+r2108 | zimmerma | 2002-12-03 13:32:21 +0000 (Tue, 03 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Use @ifnottex/@end iffnotex instead of @ifinfo/@end ifinfo
+
+------------------------------------------------------------------------
+r2107 | vlefevre | 2002-12-02 11:44:35 +0000 (Mon, 02 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/rnd_mode.c
+
+Fix rnd_mode.c (again).
+
+------------------------------------------------------------------------
+r2106 | zimmerma | 2002-12-02 09:44:41 +0000 (Mon, 02 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+put redefinitions of external symbols just before prototypes
+
+------------------------------------------------------------------------
+r2105 | zimmerma | 2002-12-02 09:23:47 +0000 (Mon, 02 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+updated
+
+------------------------------------------------------------------------
+r2104 | zimmerma | 2002-12-02 09:21:40 +0000 (Mon, 02 Dec 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+added new known bugs
+
+------------------------------------------------------------------------
+r2103 | ryde | 2002-11-29 23:05:47 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Add notes on mpf_t maintaining actual size for efficiency.
+
+------------------------------------------------------------------------
+r2102 | ryde | 2002-11-29 22:52:20 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Remove mpfr_set_machine_rnd_mode task.
+
+------------------------------------------------------------------------
+r2101 | ryde | 2002-11-29 22:51:58 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Tweak some math formatting for tex.
+
+------------------------------------------------------------------------
+r2100 | ryde | 2002-11-29 22:45:40 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+
+(mpfr_set_machine_rnd_mode): Move prototype to mpfr-test.h.
+
+------------------------------------------------------------------------
+r2099 | ryde | 2002-11-29 22:42:19 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+(libfrtests_a_SOURCES): Add rnd_mode.c.
+
+------------------------------------------------------------------------
+r2098 | ryde | 2002-11-29 22:41:57 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+(libmpfr_a_SOURCES): Remove rnd_mode.c.
+
+------------------------------------------------------------------------
+r2097 | ryde | 2002-11-29 22:40:40 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ D /trunk/rnd_mode.c
+
+Remove file, moved to tests directory.
+
+------------------------------------------------------------------------
+r2096 | ryde | 2002-11-29 22:40:01 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ A /trunk/tests/rnd_mode.c
+
+New file, moved from top-level directory.
+
+------------------------------------------------------------------------
+r2095 | ryde | 2002-11-29 22:22:40 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+(Rounding Modes): Remove mpfr_set_machine_rnd_mode.
+
+------------------------------------------------------------------------
+r2094 | ryde | 2002-11-29 21:42:11 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/setmin.c
+
+Use GNU style code layout.
+
+------------------------------------------------------------------------
+r2093 | ryde | 2002-11-29 21:35:59 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/setmax.c
+
+Use GNU style code layout.
+
+------------------------------------------------------------------------
+r2092 | zimmerma | 2002-11-29 17:26:31 +0000 (Fri, 29 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+redefined external symbols in the __gmpfr namespace
+
+------------------------------------------------------------------------
+r2091 | zimmerma | 2002-11-25 17:04:36 +0000 (Mon, 25 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+added one fprintf in case of error
+
+------------------------------------------------------------------------
+r2090 | vlefevre | 2002-11-25 16:11:33 +0000 (Mon, 25 Nov 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/rnd_mode.c
+
+mpfr_set_machine_rnd_mode fixed to compile on some architectures
+(e.g. ARM). Now returns an int.
+
+------------------------------------------------------------------------
+r2089 | vlefevre | 2002-11-25 15:30:56 +0000 (Mon, 25 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+Bug fixed.
+
+------------------------------------------------------------------------
+r2088 | zimmerma | 2002-11-25 12:54:49 +0000 (Mon, 25 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+removed all tests that compare to libm
+
+------------------------------------------------------------------------
+r2087 | zimmerma | 2002-11-25 10:54:35 +0000 (Mon, 25 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+changed to distinguish mpfr failures from libm failures
+
+------------------------------------------------------------------------
+r2086 | zimmerma | 2002-11-25 10:37:43 +0000 (Mon, 25 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added 3 tests that make libm fail under HP-PA
+
+------------------------------------------------------------------------
+r2085 | vlefevre | 2002-11-23 23:47:18 +0000 (Sat, 23 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r2084 | zimmerma | 2002-11-22 10:40:05 +0000 (Fri, 22 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/ui_pow.c
+
+forgot to remove debug statement
+
+------------------------------------------------------------------------
+r2083 | zimmerma | 2002-11-22 10:26:38 +0000 (Fri, 22 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/ui_pow.c
+
+fixed bug (infinite loop) for exact powers
+
+------------------------------------------------------------------------
+r2082 | ryde | 2002-11-21 22:28:44 +0000 (Thu, 21 Nov 2002) | 3 lines
+Changed paths:
+ M /trunk/TODO
+
+More on tuned thresholds, more on config.h etc, new section on mpf/mpfr
+integration.
+
+------------------------------------------------------------------------
+r2081 | vlefevre | 2002-11-20 14:34:08 +0000 (Wed, 20 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+Code clean-up.
+
+------------------------------------------------------------------------
+r2080 | zimmerma | 2002-11-20 13:08:23 +0000 (Wed, 20 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/log.c
+ M /trunk/set_ld.c
+
+fixed some problems found by insure
+
+------------------------------------------------------------------------
+r2079 | zimmerma | 2002-11-20 11:03:21 +0000 (Wed, 20 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+forgotten fclose() call
+
+------------------------------------------------------------------------
+r2078 | zimmerma | 2002-11-20 10:13:01 +0000 (Wed, 20 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+fixed array bound write
+
+------------------------------------------------------------------------
+r2077 | zimmerma | 2002-11-19 16:46:45 +0000 (Tue, 19 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed non-ansi features
+
+------------------------------------------------------------------------
+r2076 | zimmerma | 2002-11-19 16:26:22 +0000 (Tue, 19 Nov 2002) | 2 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/div_ui.c
+
+added explicit cast
+
+------------------------------------------------------------------------
+r2075 | zimmerma | 2002-10-24 12:04:59 +0000 (Thu, 24 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added mpfr_cbrt
+
+------------------------------------------------------------------------
+r2074 | vlefevre | 2002-10-20 09:46:03 +0000 (Sun, 20 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Update.
+
+------------------------------------------------------------------------
+r2073 | zimmerma | 2002-10-20 07:43:07 +0000 (Sun, 20 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+fixed bug with wrong sign detection
+
+------------------------------------------------------------------------
+r2072 | vlefevre | 2002-10-19 10:25:49 +0000 (Sat, 19 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+Some fixes to avoid overflows.
+
+------------------------------------------------------------------------
+r2071 | zimmerma | 2002-10-19 08:08:47 +0000 (Sat, 19 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+fixed bug for large arguments
+
+------------------------------------------------------------------------
+r2070 | zimmerma | 2002-10-19 08:08:15 +0000 (Sat, 19 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/cbrt.c
+
+improved code for rounding to nearest
+
+------------------------------------------------------------------------
+r2069 | zimmerma | 2002-10-19 08:05:45 +0000 (Sat, 19 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/asinh.c
+
+fixed bug for EXP(x) > EMAX/2
+
+------------------------------------------------------------------------
+r2068 | zimmerma | 2002-10-19 08:04:51 +0000 (Sat, 19 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+modified description of hypot and cbrt
+
+------------------------------------------------------------------------
+r2067 | vlefevre | 2002-10-18 14:57:01 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Update.
+
+------------------------------------------------------------------------
+r2066 | vlefevre | 2002-10-18 14:53:53 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+
+Added test showing bug in sign detection.
+
+------------------------------------------------------------------------
+r2065 | vlefevre | 2002-10-18 13:45:02 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/thypot.c
+
+Added newline.
+
+------------------------------------------------------------------------
+r2064 | vlefevre | 2002-10-18 12:39:07 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Bug in mpfr_hypot.
+
+------------------------------------------------------------------------
+r2063 | vlefevre | 2002-10-18 12:26:16 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/thypot.c
+
+Added test that makes mpfr_hypot fail.
+
+------------------------------------------------------------------------
+r2062 | vlefevre | 2002-10-18 12:06:17 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+Precision Nt: int -> mp_prec_t.
+
+------------------------------------------------------------------------
+r2061 | vlefevre | 2002-10-18 10:21:31 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tcbrt.c
+
+Added some tests.
+
+------------------------------------------------------------------------
+r2060 | vlefevre | 2002-10-18 09:58:41 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tcbrt.c
+
+main () -> main (void).
+
+------------------------------------------------------------------------
+r2059 | zimmerma | 2002-10-18 07:00:18 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tcbrt.c
+
+added tcbrt.c, test file for mpfr_cbrt
+
+------------------------------------------------------------------------
+r2058 | zimmerma | 2002-10-18 06:58:51 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+fixed overflow problem
+
+------------------------------------------------------------------------
+r2057 | zimmerma | 2002-10-18 06:58:08 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/cbrt.c
+
+completely rewritten using mpz_root
+
+------------------------------------------------------------------------
+r2056 | zimmerma | 2002-10-18 06:57:14 +0000 (Fri, 18 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added cbrt
+
+------------------------------------------------------------------------
+r2055 | vlefevre | 2002-10-17 16:48:10 +0000 (Thu, 17 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+C9X -> ISO/IEC 9899:1999 (ISO C99).
+
+------------------------------------------------------------------------
+r2054 | vlefevre | 2002-10-17 16:03:57 +0000 (Thu, 17 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+Cases NaN and -0.0 taken into account.
+
+------------------------------------------------------------------------
+r2053 | zimmerma | 2002-10-17 15:37:00 +0000 (Thu, 17 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+added check for +0 and -0
+
+------------------------------------------------------------------------
+r2052 | zimmerma | 2002-10-17 15:13:09 +0000 (Thu, 17 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+added one test (2^1024)
+
+------------------------------------------------------------------------
+r2051 | zimmerma | 2002-10-17 15:11:54 +0000 (Thu, 17 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+fixed bug when overflow for double type
+
+------------------------------------------------------------------------
+r2050 | zimmerma | 2002-10-17 12:56:49 +0000 (Thu, 17 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added mpfr_set_ld and mpfr_get_ld
+
+------------------------------------------------------------------------
+r2049 | vlefevre | 2002-10-16 18:37:48 +0000 (Wed, 16 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/get_ld.c
+
+Fix for -0.0.
+
+------------------------------------------------------------------------
+r2048 | zimmerma | 2002-10-16 18:21:54 +0000 (Wed, 16 Oct 2002) | 2 lines
+Changed paths:
+ A /trunk/log_b2.h
+
+constants for mpfr_get_str and mpfr_set_str
+
+------------------------------------------------------------------------
+r2047 | vlefevre | 2002-10-16 16:25:56 +0000 (Wed, 16 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+Obsolete comment removed.
+
+------------------------------------------------------------------------
+r2046 | vlefevre | 2002-10-16 16:23:35 +0000 (Wed, 16 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+Removed log_b2.h as it doesn't seem to be necessary.
+
+------------------------------------------------------------------------
+r2045 | zimmerma | 2002-10-16 15:41:24 +0000 (Wed, 16 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for mpfr_get_ld
+
+------------------------------------------------------------------------
+r2044 | zimmerma | 2002-10-16 15:40:19 +0000 (Wed, 16 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/get_ld.c
+ M /trunk/tests/tset_ld.c
+
+added mpfr_get_ld and tests for set_ld/get_ld
+
+------------------------------------------------------------------------
+r2043 | zimmerma | 2002-10-16 15:38:46 +0000 (Wed, 16 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+added cast to long double
+
+------------------------------------------------------------------------
+r2042 | vlefevre | 2002-10-16 10:08:09 +0000 (Wed, 16 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Update (tset_ld).
+
+------------------------------------------------------------------------
+r2041 | vlefevre | 2002-10-16 08:13:25 +0000 (Wed, 16 Oct 2002) | 4 lines
+Changed paths:
+ M /trunk/tests/tset_ld.c
+
+Test removed as the minimal precision for a long double is something
+like 10 decimal digits. Anyway, there are implementations for which
+long double = double = IEEE double precision.
+
+------------------------------------------------------------------------
+r2040 | vlefevre | 2002-10-16 07:38:15 +0000 (Wed, 16 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/set_ld.c
+
+DBL_MANT_DIG and LDBL_MANT_DIG are normally defined by <float.h>.
+
+------------------------------------------------------------------------
+r2039 | zimmerma | 2002-10-15 14:58:26 +0000 (Tue, 15 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ A /trunk/set_ld.c
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tset_ld.c
+
+added mpfr_set_ld and test file
+
+------------------------------------------------------------------------
+r2038 | vlefevre | 2002-10-13 14:12:46 +0000 (Sun, 13 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Bug in mpfr_sin (and perhaps other functions): error analysis.
+
+------------------------------------------------------------------------
+r2037 | vlefevre | 2002-10-13 13:54:45 +0000 (Sun, 13 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Bug fixed (found by Dmitrii Baksheyev): atan(1) cannot be exact.
+
+------------------------------------------------------------------------
+r2036 | ryde | 2002-10-08 01:41:21 +0000 (Tue, 08 Oct 2002) | 5 lines
+Changed paths:
+ M /trunk/TODO
+
+Remove mpfr_get_str using mpn_get_str (done).
+Remove no grepping for __setfpucw, done (near enough).
+New thread-safety section, add const_pi and const_log2 caching.
+New portability section, add mingw random and _mpfr_ceil_log2 IEEE-ism.
+
+------------------------------------------------------------------------
+r2035 | ryde | 2002-10-08 01:38:34 +0000 (Tue, 08 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+(AC_MY_LIBS): Show the filename in the error message.
+
+------------------------------------------------------------------------
+r2034 | zimmerma | 2002-10-04 14:32:53 +0000 (Fri, 04 Oct 2002) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+mpfr_get_default_prec was missing (thanks to F. Morain)
+
+------------------------------------------------------------------------
+r2033 | vlefevre | 2002-09-30 12:22:28 +0000 (Mon, 30 Sep 2002) | 3 lines
+Changed paths:
+ M /trunk/BUGS
+
+Removed get_str.c bug, as the mpfr_get_str function has
+completely been rewritten.
+
+------------------------------------------------------------------------
+r2032 | zimmerma | 2002-09-26 08:15:34 +0000 (Thu, 26 Sep 2002) | 3 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed wrong inexact flag for a - b where a and b are of different signs
+and EXP(a) < EXP(b)
+
+------------------------------------------------------------------------
+r2031 | zimmerma | 2002-09-26 08:00:09 +0000 (Thu, 26 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+added test for inexact flag (bug found by Andreas Enge)
+
+------------------------------------------------------------------------
+r2030 | ryde | 2002-09-23 22:51:26 +0000 (Mon, 23 Sep 2002) | 3 lines
+Changed paths:
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/set_prec.c
+
+(mpfr_init, mpfr_init2, mpfr_set_prec): Make void return, these always
+succeed.
+
+------------------------------------------------------------------------
+r2029 | zimmerma | 2002-09-23 12:25:52 +0000 (Mon, 23 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/urandomb.c
+
+fixed various tiny problems
+
+------------------------------------------------------------------------
+r2028 | zimmerma | 2002-09-23 12:19:24 +0000 (Mon, 23 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+
+added more tests for mpfr_urandomb, and for small precision
+
+------------------------------------------------------------------------
+r2027 | zimmerma | 2002-09-23 08:45:25 +0000 (Mon, 23 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+ M /trunk/tests/trandom.c
+
+fixed bugs in mpfr_random2 (wrong exponent, invalid numbers)
+
+------------------------------------------------------------------------
+r2026 | zimmerma | 2002-09-23 08:42:28 +0000 (Mon, 23 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+
+added checks for mpfr_random2
+
+------------------------------------------------------------------------
+r2025 | zimmerma | 2002-09-23 08:20:31 +0000 (Mon, 23 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/cmp_abs.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/pow.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tsub.c
+
+cmp_abs -> cmpabs (for compatibility with mpz)
+
+------------------------------------------------------------------------
+r2024 | ryde | 2002-09-21 22:57:26 +0000 (Sat, 21 Sep 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+(Converting Floats): Don't refer to the internal _mp_free_func with
+mpfr_get_str.
+
+------------------------------------------------------------------------
+r2023 | ryde | 2002-09-21 22:51:58 +0000 (Sat, 21 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+(Special Functions, Internals): Make these into nodes.
+
+------------------------------------------------------------------------
+r2022 | zimmerma | 2002-09-20 16:11:47 +0000 (Fri, 20 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+now accept uppercase letters too
+
+------------------------------------------------------------------------
+r2021 | zimmerma | 2002-09-20 16:07:35 +0000 (Fri, 20 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+added test for uppercase letters
+
+------------------------------------------------------------------------
+r2020 | zimmerma | 2002-09-18 15:11:33 +0000 (Wed, 18 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+now mpfr_agm returns an int (inexact flag)
+
+------------------------------------------------------------------------
+r2019 | vlefevre | 2002-09-13 10:11:33 +0000 (Fri, 13 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/prepare
+
+Some more information.
+
+------------------------------------------------------------------------
+r2018 | vlefevre | 2002-09-12 11:50:34 +0000 (Thu, 12 Sep 2002) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+
+On HP-UX, use the +allowunsats switch for ld, otherwise ld complains
+that some GMP symbols are unsatisfied.
+
+------------------------------------------------------------------------
+r2017 | zimmerma | 2002-09-12 09:54:44 +0000 (Thu, 12 Sep 2002) | 2 lines
+Changed paths:
+ M /trunk/gamma.c
+ M /trunk/tests/tgamma.c
+
+fixed bug in reflection formula for x<1
+
+------------------------------------------------------------------------
+r2016 | vlefevre | 2002-08-23 22:05:08 +0000 (Fri, 23 Aug 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/mpfr.texi
+
+MPFR now needs GMP 4.1 or higher.
+
+------------------------------------------------------------------------
+r2015 | ryde | 2002-08-22 00:56:07 +0000 (Thu, 22 Aug 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-math.h
+
+(__mpfr_nan): Clarify comments about HP C and alpha.
+
+------------------------------------------------------------------------
+r2014 | ryde | 2002-08-22 00:47:22 +0000 (Thu, 22 Aug 2002) | 4 lines
+Changed paths:
+ M /trunk/mpfr-math.h
+
+(_MPFR_NAN_BYTES, _MPFR_INFP_BYTES, _MPFR_INFM_BYTES):
+Use HAVE_DOUBLE_IEEE_LITTLE_ENDIAN etc to select endianness, not a big
+block of #ifdefs.
+
+------------------------------------------------------------------------
+r2013 | vlefevre | 2002-08-12 00:35:25 +0000 (Mon, 12 Aug 2002) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/strcasecmp.c
+ A /trunk/strncasecmp.c
+
+strcasecmp.c -> strcasecmp.c & strncasecmp.c
+
+------------------------------------------------------------------------
+r2012 | ryde | 2002-08-07 01:47:30 +0000 (Wed, 07 Aug 2002) | 3 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+Use $(top_builddir) consistently with libmpfr.a, for the benefit of
+srcdir!=builddir.
+
+------------------------------------------------------------------------
+r2011 | vlefevre | 2002-08-02 23:36:46 +0000 (Fri, 02 Aug 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Don't touch user specified flags (CFLAGS). [patch by Kevin Ryde]
+
+------------------------------------------------------------------------
+r2010 | vlefevre | 2002-07-30 03:19:37 +0000 (Tue, 30 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-impl.h
+ M /trunk/set_str.c
+
+Better check for strcasecmp and strncasecmp. Bug fixed.
+
+------------------------------------------------------------------------
+r2009 | vlefevre | 2002-07-28 23:48:20 +0000 (Sun, 28 Jul 2002) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/TODO
+ A /trunk/comparisons.c
+ M /trunk/mpfr.h
+
+Functions mpfr_greater_p, mpfr_greaterequal_p, mpfr_less_p,
+mpfr_lessequal_p, mpfr_lessgreater_p, mpfr_equal_p, mpfr_unordered_p.
+
+------------------------------------------------------------------------
+r2008 | vlefevre | 2002-07-28 01:58:32 +0000 (Sun, 28 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/prepare
+ M /trunk/tests/Makefile.am
+
+Use AUTOMAKE_OPTIONS = gnu [suggested by Kevin Ryde]
+
+------------------------------------------------------------------------
+r2007 | vlefevre | 2002-07-28 01:43:29 +0000 (Sun, 28 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+check target -> TESTS = $(check_PROGRAMS) [suggested by Kevin Ryde]
+
+------------------------------------------------------------------------
+r2006 | vlefevre | 2002-07-28 01:28:54 +0000 (Sun, 28 Jul 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/strcasecmp.c
+
+strcasecmp and strncasecmp -> mpfr_strcasecmp and mpfr_strncasecmp
+if they are provided by MPFR.
+
+------------------------------------------------------------------------
+r2005 | vlefevre | 2002-07-28 00:50:51 +0000 (Sun, 28 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+TMP_MARK missing (patch by Kevin Ryde).
+
+------------------------------------------------------------------------
+r2004 | vlefevre | 2002-07-26 17:53:53 +0000 (Fri, 26 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r2003 | vlefevre | 2002-07-26 17:49:03 +0000 (Fri, 26 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/README
+ M /trunk/README.dev
+
+Update (mainly concerning CVS use).
+
+------------------------------------------------------------------------
+r2002 | vlefevre | 2002-07-26 15:52:58 +0000 (Fri, 26 Jul 2002) | 5 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/mpfr-impl.h
+ M /trunk/next.c
+ M /trunk/setmax.c
+ M /trunk/setmin.c
+
+Prototype of mpfr_setmax and mpfr_setmin changed (exponent given).
+In mpfr_exp for x ~= 0, add_one_ulp and sub_one_ulp are no longer
+used (sub_one_ulp was incorrect). These cases should now be faster.
+Small fix in mpfr_nextabove, mpfr_nextbelow and mpfr_nexttoward.
+
+------------------------------------------------------------------------
+r2001 | vlefevre | 2002-07-26 15:21:45 +0000 (Fri, 26 Jul 2002) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/TODO
+ M /trunk/exceptions.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/next.c
+ A /trunk/setmax.c
+ A /trunk/setmin.c
+ M /trunk/sub_one_ulp.c
+
+New internal functions mpfr_setmin and mpfr_setmax.
+New functions mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward.
+Small fix in mpfr_sub_one_ulp.
+
+------------------------------------------------------------------------
+r2000 | zimmerma | 2002-07-26 13:24:45 +0000 (Fri, 26 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+improved the computation of g = ceil((e-1)/log_2(beta)), using two tables
+
+------------------------------------------------------------------------
+r1999 | vlefevre | 2002-07-25 15:43:49 +0000 (Thu, 25 Jul 2002) | 5 lines
+Changed paths:
+ M /trunk/add_ui.c
+ M /trunk/exceptions.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.texi
+ M /trunk/save_expo.c
+ M /trunk/set_q.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub_ui.c
+ M /trunk/ui_pow_ui.c
+
+Function mpfr_check_range now propagates the inexact ternary value.
+Function mpfr_restore_emin_emax OR's the saved flags with the current
+flags, as this is more useful in general.
+Macro MPFR_RESTORE_RET removed (no longer useful).
+
+------------------------------------------------------------------------
+r1998 | vlefevre | 2002-07-24 17:38:21 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/frac.c
+
+Change concerning an assertion, due to GMP limitation.
+
+------------------------------------------------------------------------
+r1997 | zimmerma | 2002-07-24 16:35:02 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+gnu indentation
+
+------------------------------------------------------------------------
+r1996 | zimmerma | 2002-07-24 16:32:49 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tgamma.c
+
+reduce range of tests (did take too much time)
+
+------------------------------------------------------------------------
+r1995 | zimmerma | 2002-07-24 16:31:00 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added plenty of new cases, now covers all lines of get_str.c
+
+------------------------------------------------------------------------
+r1994 | zimmerma | 2002-07-24 16:29:40 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+updated documentation of mpfr_get_str
+
+------------------------------------------------------------------------
+r1993 | zimmerma | 2002-07-24 16:28:21 +0000 (Wed, 24 Jul 2002) | 4 lines
+Changed paths:
+ M /trunk/get_str.c
+
+completely new version, written by Alain Delplanque and Paul Zimmermann.
+It now directly uses mpn_get_str, with subquadratic complexity.
+About 3 times faster than previous version in most cases.
+
+------------------------------------------------------------------------
+r1992 | vlefevre | 2002-07-24 16:23:27 +0000 (Wed, 24 Jul 2002) | 3 lines
+Changed paths:
+ M /trunk/frac.c
+
+Bug fixed: unsigned int variables changed to int to avoid operations
+with mixed signed/unsigned variables and unwanted casts.
+
+------------------------------------------------------------------------
+r1991 | vlefevre | 2002-07-24 16:04:16 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/frac.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tfrac.c
+
+Function mpfr_frac and tests added.
+
+------------------------------------------------------------------------
+r1990 | vlefevre | 2002-07-24 15:05:51 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+Bug fixed (0 was forgotten).
+
+------------------------------------------------------------------------
+r1989 | vlefevre | 2002-07-24 11:11:07 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/isinteger.c
+
+Optimization: mpfr_trunc no longer used!
+
+------------------------------------------------------------------------
+r1988 | vlefevre | 2002-07-24 10:13:00 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/isinteger.c
+
+mpfr_isinteger extended to non-fp numbers and to zero.
+
+------------------------------------------------------------------------
+r1987 | vlefevre | 2002-07-24 09:59:01 +0000 (Wed, 24 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/isnum.c
+
+Simpler test.
+
+------------------------------------------------------------------------
+r1986 | vlefevre | 2002-07-23 17:19:47 +0000 (Tue, 23 Jul 2002) | 2 lines
+Changed paths:
+ A /trunk/mul.c
+
+Re-adding mul.c with fixed permissions.
+
+------------------------------------------------------------------------
+r1985 | vlefevre | 2002-07-23 17:18:56 +0000 (Tue, 23 Jul 2002) | 2 lines
+Changed paths:
+ D /trunk/mul.c
+
+Temporarily removing mul.c in order to try to fix its permissions.
+
+------------------------------------------------------------------------
+r1984 | vlefevre | 2002-07-23 16:22:08 +0000 (Tue, 23 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Fixed permissions.
+
+------------------------------------------------------------------------
+r1983 | vlefevre | 2002-07-23 16:02:30 +0000 (Tue, 23 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/exceptions.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+ M /trunk/tests/texceptions.c
+
+Function mpfr_check_range improved in the underflow case.
+
+------------------------------------------------------------------------
+r1982 | vlefevre | 2002-07-22 15:52:33 +0000 (Mon, 22 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r1981 | zimmerma | 2002-07-22 15:22:13 +0000 (Mon, 22 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/dump.c
+
+now dump in base 2
+
+------------------------------------------------------------------------
+r1980 | zimmerma | 2002-07-22 15:11:50 +0000 (Mon, 22 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+forgot one free() call
+
+------------------------------------------------------------------------
+r1979 | vlefevre | 2002-07-22 13:57:15 +0000 (Mon, 22 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+mpfr_pow bug removed.
+
+------------------------------------------------------------------------
+r1978 | vlefevre | 2002-07-22 13:54:55 +0000 (Mon, 22 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+Reindentation.
+
+------------------------------------------------------------------------
+r1977 | vlefevre | 2002-07-22 13:51:20 +0000 (Mon, 22 Jul 2002) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+ M /trunk/tests/tpow.c
+
+pow.c: bug fixed (in the call to mpfr_can_round).
+tpow.c: mpfr_clear added.
+
+------------------------------------------------------------------------
+r1976 | vlefevre | 2002-07-22 13:26:54 +0000 (Mon, 22 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Modified the two tests to make the bug appear.
+
+------------------------------------------------------------------------
+r1975 | zimmerma | 2002-07-22 09:37:31 +0000 (Mon, 22 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+added two tests
+
+------------------------------------------------------------------------
+r1974 | vlefevre | 2002-07-19 15:31:23 +0000 (Fri, 19 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Updated note concerning rcs2log.
+
+------------------------------------------------------------------------
+r1973 | vlefevre | 2002-07-19 11:31:30 +0000 (Fri, 19 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Line mpfr_get_exp / mpfr_set_exp removed.
+
+------------------------------------------------------------------------
+r1972 | zimmerma | 2002-07-16 15:33:31 +0000 (Tue, 16 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added function check_large
+
+------------------------------------------------------------------------
+r1971 | vlefevre | 2002-07-15 13:16:15 +0000 (Mon, 15 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/config.guess
+ M /trunk/config.sub
+
+Update from ftp://ftp.gnu.org/pub/gnu/config/
+
+------------------------------------------------------------------------
+r1970 | vlefevre | 2002-07-14 23:44:41 +0000 (Sun, 14 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-math.h
+
+Add __sparc__ (patch by Nix <nix@esperi.demon.co.uk>).
+
+------------------------------------------------------------------------
+r1969 | vlefevre | 2002-07-14 23:39:13 +0000 (Sun, 14 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Note about randomized tests.
+
+------------------------------------------------------------------------
+r1968 | vlefevre | 2002-07-04 15:09:17 +0000 (Thu, 04 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Bug concerning the rounding of pow().
+
+------------------------------------------------------------------------
+r1967 | vlefevre | 2002-07-04 14:26:00 +0000 (Thu, 04 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+mpfr_pow() didn't work when the exponent was a negative integer.
+
+------------------------------------------------------------------------
+r1966 | vlefevre | 2002-07-04 14:25:40 +0000 (Thu, 04 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/get_z_exp.c
+
+mpfr_get_z_exp() didn't work when the MPFR number was negative.
+
+------------------------------------------------------------------------
+r1965 | vlefevre | 2002-07-04 11:59:27 +0000 (Thu, 04 Jul 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/get_exp.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ A /trunk/set_exp.c
+
+New functions mpfr_get_exp and mpfr_set_exp.
+
+------------------------------------------------------------------------
+r1964 | zimmerma | 2002-06-27 14:07:06 +0000 (Thu, 27 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed duplicated entry (thread-safe)
+
+------------------------------------------------------------------------
+r1963 | zimmerma | 2002-06-27 13:57:23 +0000 (Thu, 27 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added new items
+
+------------------------------------------------------------------------
+r1962 | zimmerma | 2002-06-27 12:55:03 +0000 (Thu, 27 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+added special cases
+
+------------------------------------------------------------------------
+r1961 | zimmerma | 2002-06-27 12:50:36 +0000 (Thu, 27 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added one reference (nocite)
+
+------------------------------------------------------------------------
+r1960 | zimmerma | 2002-06-27 12:50:15 +0000 (Thu, 27 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+
+added one reference
+
+------------------------------------------------------------------------
+r1959 | zimmerma | 2002-06-27 12:49:01 +0000 (Thu, 27 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/inp_str.c
+
+fixed bug in return value
+
+------------------------------------------------------------------------
+r1958 | zimmerma | 2002-06-27 12:30:03 +0000 (Thu, 27 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+new additions
+
+------------------------------------------------------------------------
+r1957 | zimmerma | 2002-06-27 09:31:01 +0000 (Thu, 27 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added pointer to mpfr_inp_str in mpfr_set_str
+
+------------------------------------------------------------------------
+r1956 | vlefevre | 2002-06-26 23:55:24 +0000 (Wed, 26 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r1955 | vlefevre | 2002-06-26 23:51:49 +0000 (Wed, 26 Jun 2002) | 3 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/add_one_ulp.c
+ M /trunk/div.c
+ M /trunk/exceptions.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/print_raw.c
+ M /trunk/rint.c
+ M /trunk/round_prec.c
+ M /trunk/set.c
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+ M /trunk/sqrt.c
+ M /trunk/sub1.c
+
+MP_LIMB_T_HIGHBIT -> MPFR_LIMB_HIGHBIT.
+MPFR is now compatible with GMP 4.1.
+
+------------------------------------------------------------------------
+r1954 | vlefevre | 2002-06-15 10:50:23 +0000 (Sat, 15 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Added: make MPFR thread-safe.
+
+------------------------------------------------------------------------
+r1953 | zimmerma | 2002-06-14 13:14:34 +0000 (Fri, 14 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/set_q.c
+
+fixed bug found by Gerardo Ballabio
+
+------------------------------------------------------------------------
+r1952 | zimmerma | 2002-06-14 13:14:08 +0000 (Fri, 14 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_q.c
+
+added one test (bug in mpfr-2.0.1 found by Gerardo Ballabio)
+
+------------------------------------------------------------------------
+r1951 | zimmerma | 2002-06-13 12:44:16 +0000 (Thu, 13 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added mpfr_modf
+
+------------------------------------------------------------------------
+r1950 | vlefevre | 2002-06-12 22:30:26 +0000 (Wed, 12 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Added modf (to implement).
+
+------------------------------------------------------------------------
+r1949 | vlefevre | 2002-06-08 22:58:28 +0000 (Sat, 08 Jun 2002) | 3 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tmul.c
+
+check: Apply a hack to the parameter order to make sparc gcc 2.95.2
+happy (patch by Kevin Ryde) + static added.
+
+------------------------------------------------------------------------
+r1948 | vlefevre | 2002-06-08 22:45:57 +0000 (Sat, 08 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Patch by Kevin Ryde.
+
+------------------------------------------------------------------------
+r1947 | vlefevre | 2002-06-08 02:45:27 +0000 (Sat, 08 Jun 2002) | 3 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+
+Suppress tests if sqrt is not affected by mpfr_set_machine_rnd_mode
+(patch by Kevin Ryde).
+
+------------------------------------------------------------------------
+r1946 | vlefevre | 2002-06-08 02:25:49 +0000 (Sat, 08 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r1945 | vlefevre | 2002-06-08 02:20:00 +0000 (Sat, 08 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/README
+
+fdl.texi added.
+
+------------------------------------------------------------------------
+r1944 | vlefevre | 2002-06-08 02:16:07 +0000 (Sat, 08 Jun 2002) | 9 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/README.dev
+ A /trunk/fdl.texi
+ M /trunk/mpfr.texi
+ M /trunk/texinfo.tex
+
+Patch by Kevin Ryde (and Vincent Lefevre).
+mpfr.texi: Change license to FDL, use @copying per texinfo 4.2.
+Use @dircategory, @direntry, @documentdescription.
+Move @contents to start of file.
+(VERSION, UPDATED): New variables.
+(m, GMPtimes, times): New macros.
+(Float Arithmetic): Fix html output. Reported by Richard Dawe.
+(GNU Free Documentation License): New appendix.
+
+------------------------------------------------------------------------
+r1943 | vlefevre | 2002-06-06 11:08:47 +0000 (Thu, 06 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+Use gmp-impl.h to get MPFR_HAVE_FESETROUND (reported by Kevin Ryde).
+
+------------------------------------------------------------------------
+r1942 | zimmerma | 2002-06-05 15:27:23 +0000 (Wed, 05 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+patch for mpfr.texi
+
+------------------------------------------------------------------------
+r1941 | zimmerma | 2002-06-05 15:24:46 +0000 (Wed, 05 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+patch from Richard Dawe <richdawe@bigfoot.com> to generate HTML
+
+------------------------------------------------------------------------
+r1940 | zimmerma | 2002-06-05 15:05:21 +0000 (Wed, 05 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/gamma.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tgamma.c
+
+added mpfr_gamma in libmpfr
+
+------------------------------------------------------------------------
+r1939 | vlefevre | 2002-06-05 01:01:42 +0000 (Wed, 05 Jun 2002) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tests.c
+
+Check for isnan.
+
+------------------------------------------------------------------------
+r1938 | vlefevre | 2002-05-29 13:08:04 +0000 (Wed, 29 May 2002) | 2 lines
+Changed paths:
+ M /trunk/rint.c
+
+Bug fixed (possible integer overflow).
+
+------------------------------------------------------------------------
+r1937 | vlefevre | 2002-05-29 12:48:06 +0000 (Wed, 29 May 2002) | 2 lines
+Changed paths:
+ M /trunk/add_one_ulp.c
+ M /trunk/sub_one_ulp.c
+
+Bug fixed (possible integer overflow).
+
+------------------------------------------------------------------------
+r1936 | vlefevre | 2002-05-29 12:41:19 +0000 (Wed, 29 May 2002) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/sub1.c
+
+Bug fixed (possible integer overflow).
+
+------------------------------------------------------------------------
+r1935 | vlefevre | 2002-05-29 12:21:32 +0000 (Wed, 29 May 2002) | 2 lines
+Changed paths:
+ M /trunk/exceptions.c
+
+Note added for mpfr_check_range. Bug fixed.
+
+------------------------------------------------------------------------
+r1934 | vlefevre | 2002-05-29 11:37:31 +0000 (Wed, 29 May 2002) | 3 lines
+Changed paths:
+ M /trunk/urandomb.c
+
+Sign wasn't set (reported by Dmitrii Baksheyev).
+Types fixed and code clean-up.
+
+------------------------------------------------------------------------
+r1933 | vlefevre | 2002-05-29 10:56:51 +0000 (Wed, 29 May 2002) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+Types fixed and code clean-up.
+
+------------------------------------------------------------------------
+r1932 | vlefevre | 2002-05-27 13:48:56 +0000 (Mon, 27 May 2002) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/memory.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ A /trunk/tests/tests.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+
+Patch by Kevin Ryde for memory leak checking + misc declaration fixes.
+Code moved from mpfr-test.h to tests.c.
+
+------------------------------------------------------------------------
+r1931 | vlefevre | 2002-05-14 23:14:53 +0000 (Tue, 14 May 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Ternary flag for mpfr_agm.
+
+------------------------------------------------------------------------
+r1930 | vlefevre | 2002-05-14 23:03:08 +0000 (Tue, 14 May 2002) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/add.c
+ M /trunk/asin.c
+ M /trunk/atan.c
+ M /trunk/cmp2.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/div.c
+ M /trunk/exceptions.c
+ M /trunk/gamma.c
+ M /trunk/generic.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/isinteger.c
+ M /trunk/mpfi.h
+ M /trunk/out_str.c
+ M /trunk/set_si.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/sub.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tzeta.c
+ M /trunk/ui_div.c
+ M /trunk/zeta.c
+
+Copyright line updated.
+
+------------------------------------------------------------------------
+r1929 | zimmerma | 2002-05-14 14:47:35 +0000 (Tue, 14 May 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+ternary flag for mpfr_agm?
+
+------------------------------------------------------------------------
+r1928 | zimmerma | 2002-05-14 14:37:20 +0000 (Tue, 14 May 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+update wrt mpfr_set_machine_rnd_mode
+
+------------------------------------------------------------------------
+r1927 | zimmerma | 2002-05-14 09:44:27 +0000 (Tue, 14 May 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added mathematical description of arithmetico-geometric mean
+
+------------------------------------------------------------------------
+r1926 | vlefevre | 2002-05-08 00:13:28 +0000 (Wed, 08 May 2002) | 4 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/acinclude.m4
+
+The problem on a G4 PowerPC was a bug in gcc; this is now tested
+in configure (float-conversion bug) and -ffloat-store is used if
+need be.
+
+------------------------------------------------------------------------
+r1925 | vlefevre | 2002-05-06 08:37:34 +0000 (Mon, 06 May 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Problem on the G4 PowerPC.
+
+------------------------------------------------------------------------
+r1924 | zimmerma | 2002-04-30 18:49:21 +0000 (Tue, 30 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/pow.c
+ M /trunk/tests/tpow.c
+
+fixed problem (infinite loop) in mpfr_pow for exact powers
+
+------------------------------------------------------------------------
+r1923 | zimmerma | 2002-04-30 09:54:12 +0000 (Tue, 30 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed errors found by Sylvain Pion
+
+------------------------------------------------------------------------
+r1922 | vlefevre | 2002-04-27 23:13:33 +0000 (Sat, 27 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+not relevant -> undefined.
+
+------------------------------------------------------------------------
+r1921 | vlefevre | 2002-04-27 23:07:29 +0000 (Sat, 27 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Some changes concerning the internals and zeros
+(including remarks by Kevin Ryde).
+
+------------------------------------------------------------------------
+r1920 | vlefevre | 2002-04-25 15:40:13 +0000 (Thu, 25 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/mpfr-math.h
+
+Check if HUGE_VAL is supported.
+
+------------------------------------------------------------------------
+r1919 | vlefevre | 2002-04-25 14:03:17 +0000 (Thu, 25 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Changes in mpfr_set_str.
+
+------------------------------------------------------------------------
+r1918 | zimmerma | 2002-04-25 13:45:07 +0000 (Thu, 25 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+update
+
+------------------------------------------------------------------------
+r1917 | zimmerma | 2002-04-25 09:04:20 +0000 (Thu, 25 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/set_str.c
+
+mpfr_set_str doesn't require any more a final '\0'
+ and return the number of characters read
+
+------------------------------------------------------------------------
+r1916 | zimmerma | 2002-04-25 09:02:31 +0000 (Thu, 25 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+modified tests for special values
+
+------------------------------------------------------------------------
+r1915 | vlefevre | 2002-04-24 10:25:02 +0000 (Wed, 24 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/cmp_abs.c
+
+Description updated.
+
+------------------------------------------------------------------------
+r1914 | vlefevre | 2002-04-24 10:23:42 +0000 (Wed, 24 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+mpfr_cmp_abs no longer an internal function and described in mpfr.texi.
+In mpfr.texi, a @var{} was forgotten.
+
+------------------------------------------------------------------------
+r1913 | vlefevre | 2002-04-24 10:21:15 +0000 (Wed, 24 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/cmp_abs.c
+
+mpfr_cmp_abs can now be called on zero numbers.
+
+------------------------------------------------------------------------
+r1912 | vlefevre | 2002-04-24 00:21:46 +0000 (Wed, 24 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-math.h
+
+Structures are used to get correct alignment.
+
+------------------------------------------------------------------------
+r1911 | vlefevre | 2002-04-23 23:32:28 +0000 (Tue, 23 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr-math.h
+
+_MPFR_INF*_BYTES fix. On alpha, use a "double" for the bytes,
+to avoid a mis-conversion on alpha gcc 3.0.2. (Kevin Ryde)
+
+------------------------------------------------------------------------
+r1910 | vlefevre | 2002-04-23 20:00:42 +0000 (Tue, 23 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/exceptions.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mul.c
+ M /trunk/mul_2si.c
+ A /trunk/powerof2.c
+ M /trunk/set_z.c
+ M /trunk/sub1.c
+ M /trunk/sub_one_ulp.c
+
+Underflow semantics changed (not tested).
+
+------------------------------------------------------------------------
+r1909 | vlefevre | 2002-04-23 09:35:26 +0000 (Tue, 23 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Code simplified due to change in the maximum exponent range.
+
+------------------------------------------------------------------------
+r1908 | zimmerma | 2002-04-23 09:08:33 +0000 (Tue, 23 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+modifs from Andreas
+
+------------------------------------------------------------------------
+r1907 | vlefevre | 2002-04-22 22:23:26 +0000 (Mon, 22 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-math.h
+
+Union -> array + cast because of the HP compiler.
+
+------------------------------------------------------------------------
+r1906 | vlefevre | 2002-04-20 13:17:37 +0000 (Sat, 20 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/get_d.c
+
+Avoid constant floating expression, as this doesn't give the correct
+result with gcc on some Alpha machines. (patch by Paul Zimmermann)
+
+------------------------------------------------------------------------
+r1905 | vlefevre | 2002-04-19 23:19:31 +0000 (Fri, 19 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+RAND_MAX defined if not already defined (as it should be).
+
+------------------------------------------------------------------------
+r1904 | vlefevre | 2002-04-19 23:10:09 +0000 (Fri, 19 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+Include config.h, for the benefit of test programs not using
+gmp-impl.h (Kevin Ryde).
+
+------------------------------------------------------------------------
+r1903 | zimmerma | 2002-04-19 18:16:53 +0000 (Fri, 19 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+added tests in mpfr_test_init for denorms and extended precision
+
+------------------------------------------------------------------------
+r1902 | zimmerma | 2002-04-19 17:22:46 +0000 (Fri, 19 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+mpfr_init and mpfr_init2 now return an int
+
+------------------------------------------------------------------------
+r1901 | vlefevre | 2002-04-19 16:37:15 +0000 (Fri, 19 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/set_q.c
+
+Exponent range saved/restored. Returns NaN when the numerator
+or the denominator is too large for MPFR.
+
+------------------------------------------------------------------------
+r1900 | vlefevre | 2002-04-19 12:26:06 +0000 (Fri, 19 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/add_ui.c
+ M /trunk/div_ui.c
+ M /trunk/mul_ui.c
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub_ui.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+
+Added some assertions (any unsigned long must be representable
+in a mp_limb_t).
+
+------------------------------------------------------------------------
+r1899 | vlefevre | 2002-04-19 12:01:16 +0000 (Fri, 19 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/cmp_si.c
+ M /trunk/mpfr-impl.h
+ M /trunk/set_si.c
+
+SAFE_ABS changed so that it can be used for any unsigned type.
+
+------------------------------------------------------------------------
+r1898 | vlefevre | 2002-04-18 15:36:36 +0000 (Thu, 18 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/set_z.c
+
+Added code to prevent possible integer overflow when the input number
+is very large.
+
+------------------------------------------------------------------------
+r1897 | vlefevre | 2002-04-18 15:22:56 +0000 (Thu, 18 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+New values for exponent range.
+
+------------------------------------------------------------------------
+r1896 | zimmerma | 2002-04-18 14:28:31 +0000 (Thu, 18 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+call get_d with rounding mode in check2, to avoid problems near +Inf
+
+------------------------------------------------------------------------
+r1895 | zimmerma | 2002-04-18 12:10:49 +0000 (Thu, 18 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+2147483647 -> INT_MAX
+
+------------------------------------------------------------------------
+r1894 | zimmerma | 2002-04-18 09:47:02 +0000 (Thu, 18 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/tests/tadd.c
+
+improved ulp() to deal with infinities
+and fixed tadd/check2 to deal with infinities
+
+------------------------------------------------------------------------
+r1893 | zimmerma | 2002-04-17 12:04:21 +0000 (Wed, 17 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+improved documentation of mpfr_set_precset_prec.
+
+------------------------------------------------------------------------
+r1892 | zimmerma | 2002-04-16 16:31:42 +0000 (Tue, 16 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed documentation of cosh/sinh/tanh
+
+------------------------------------------------------------------------
+r1891 | vlefevre | 2002-04-16 13:26:15 +0000 (Tue, 16 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/cmp_si.c
+ M /trunk/cmp_ui.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+mpfr_cmp_ui_2exp and mpfr_cmp_si_2exp rewritten.
+Prototype changed.
+
+------------------------------------------------------------------------
+r1890 | vlefevre | 2002-04-16 00:56:54 +0000 (Tue, 16 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Use AC_CANONICAL_HOST and $host instead of $OS_TYPE and $MACHTYPE
+(patch suggested by Kevin Ryde).
+
+------------------------------------------------------------------------
+r1889 | vlefevre | 2002-04-16 00:51:21 +0000 (Tue, 16 Apr 2002) | 2 lines
+Changed paths:
+ A /trunk/config.guess
+ A /trunk/config.sub
+
+Added files from ftp.gnu.org for automake and AC_CANONICAL_HOST.
+
+------------------------------------------------------------------------
+r1888 | zimmerma | 2002-04-15 17:45:46 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_sub.c
+
+replaced 2.2e-307 by DBL_MIN
+
+------------------------------------------------------------------------
+r1887 | vlefevre | 2002-04-15 16:23:49 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/README
+
+Typo: Gnu -> GNU.
+
+------------------------------------------------------------------------
+r1886 | vlefevre | 2002-04-15 15:43:26 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/VERSION
+ M /trunk/mpfr.texi
+
+Update for future 2.0.2.
+
+------------------------------------------------------------------------
+r1884 | vlefevre | 2002-04-15 15:33:49 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for mpfr 2.0.1.
+
+------------------------------------------------------------------------
+r1883 | vlefevre | 2002-04-15 15:32:21 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/VERSION
+ M /trunk/mpfr.texi
+
+Back to version 2.0.1, updated documentation.
+
+------------------------------------------------------------------------
+r1882 | vlefevre | 2002-04-15 14:48:58 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+ M /trunk/VERSION
+
+Post-release commit.
+
+------------------------------------------------------------------------
+r1881 | vlefevre | 2002-04-15 14:38:45 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for mpfr 2.0.1.
+
+------------------------------------------------------------------------
+r1880 | vlefevre | 2002-04-15 14:16:20 +0000 (Mon, 15 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/cmp_ui.c
+
+mpfr_cmp_ui_2exp and mpfr_cmp_si_2exp can no longer be called with a NaN.
+Misc bugs fixed.
+
+------------------------------------------------------------------------
+r1879 | zimmerma | 2002-04-15 14:08:47 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+added main changes in version 2.0.1
+
+------------------------------------------------------------------------
+r1878 | vlefevre | 2002-04-15 13:47:24 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/README
+
+Update for "make dist".
+
+------------------------------------------------------------------------
+r1877 | vlefevre | 2002-04-15 13:26:56 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/COPYING
+ A /trunk/COPYING.LIB
+ M /trunk/README
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add_one_ulp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_ui.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eq.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/fma.c
+ M /trunk/gamma.c
+ M /trunk/gammaPiAGMformula.c
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_str.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inp_str.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/minmax.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfi.c
+ M /trunk/mpfi.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-math.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/rnd_mode.c
+ M /trunk/round_prec.c
+ M /trunk/save_expo.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/sub_ui.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/zeta.c
+
+COPYING -> COPYING.LIB and GPL re-added.
+
+------------------------------------------------------------------------
+r1876 | vlefevre | 2002-04-15 12:34:08 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Update.
+
+------------------------------------------------------------------------
+r1875 | vlefevre | 2002-04-15 12:13:27 +0000 (Mon, 15 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Removed switches -g -O2 as already done by configure.
+
+------------------------------------------------------------------------
+r1874 | vlefevre | 2002-04-14 22:55:55 +0000 (Sun, 14 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Update.
+
+------------------------------------------------------------------------
+r1873 | vlefevre | 2002-04-14 15:53:55 +0000 (Sun, 14 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Removed useless @iftex...
+
+------------------------------------------------------------------------
+r1872 | vlefevre | 2002-04-14 11:14:31 +0000 (Sun, 14 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Update.
+
+------------------------------------------------------------------------
+r1871 | vlefevre | 2002-04-14 10:24:27 +0000 (Sun, 14 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/set_q.c
+
+When q = 0, +0 is returned.
+
+------------------------------------------------------------------------
+r1870 | vlefevre | 2002-04-13 18:32:56 +0000 (Sat, 13 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1869 | vlefevre | 2002-04-13 18:27:39 +0000 (Sat, 13 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/acinclude.m4
+ M /trunk/set_str.c
+ A /trunk/strcasecmp.c
+ M /trunk/tests/tset_str.c
+
+Support for NaN and Inf (case insensitive) in mpfr_set_str. Tests.
+
+------------------------------------------------------------------------
+r1868 | vlefevre | 2002-04-13 01:40:03 +0000 (Sat, 13 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+
+Bug fixed.
+
+------------------------------------------------------------------------
+r1867 | vlefevre | 2002-04-13 01:22:51 +0000 (Sat, 13 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1866 | vlefevre | 2002-04-13 01:18:54 +0000 (Sat, 13 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Misc changes. Use of AC_CACHE_CHECK.
+
+------------------------------------------------------------------------
+r1865 | vlefevre | 2002-04-12 16:11:14 +0000 (Fri, 12 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/texp.c
+
+Code clean-up.
+
+------------------------------------------------------------------------
+r1864 | vlefevre | 2002-04-12 14:51:26 +0000 (Fri, 12 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1863 | vlefevre | 2002-04-12 14:29:58 +0000 (Fri, 12 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+New tests.
+
+------------------------------------------------------------------------
+r1862 | vlefevre | 2002-04-12 14:29:49 +0000 (Fri, 12 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/get_d.c
+
+mpfr_get_d* fixed.
+
+------------------------------------------------------------------------
+r1861 | vlefevre | 2002-04-12 10:25:34 +0000 (Fri, 12 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/const_log2.c
+
+Types fixed in const_log2.c (this fixes the tconst_log2 crash).
+
+------------------------------------------------------------------------
+r1860 | vlefevre | 2002-04-12 09:58:11 +0000 (Fri, 12 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Added a note about the native SunOS 4 C compiler.
+
+------------------------------------------------------------------------
+r1859 | vlefevre | 2002-04-11 22:37:48 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tconst_log2.c
+
+Type fixed.
+
+------------------------------------------------------------------------
+r1858 | vlefevre | 2002-04-11 16:42:20 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/set_d.c
+
+mpfr_set_d bug fixed, but other bugs still remain...
+
+------------------------------------------------------------------------
+r1857 | vlefevre | 2002-04-11 16:21:50 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/print_rnd_mode.c
+
+NULL was undeclared on some architectures (reported by Torbjorn Granlund).
+
+------------------------------------------------------------------------
+r1856 | vlefevre | 2002-04-11 13:00:43 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+ M /trunk/mpfr-math.h
+
+#include ordering changed for Windows + Cygwin 32.
+
+------------------------------------------------------------------------
+r1855 | vlefevre | 2002-04-11 12:41:54 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+LDFLAGS changed on HP-UX.
+
+------------------------------------------------------------------------
+r1854 | vlefevre | 2002-04-11 03:35:40 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1853 | vlefevre | 2002-04-11 03:29:44 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+Subnormal test in different rounding modes + fix.
+
+------------------------------------------------------------------------
+r1852 | vlefevre | 2002-04-11 02:49:49 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/configure.in
+
+Function MPFR_CONFIGS.
+
+------------------------------------------------------------------------
+r1851 | vlefevre | 2002-04-11 01:54:09 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+Tests added.
+
+------------------------------------------------------------------------
+r1850 | vlefevre | 2002-04-11 01:53:57 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/get_d.c
+
+get_d.c partly rewritten (Paul Zimmermann).
+
+------------------------------------------------------------------------
+r1849 | vlefevre | 2002-04-11 01:36:49 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/set_q.c
+
+#include ordering fixed.
+
+------------------------------------------------------------------------
+r1848 | vlefevre | 2002-04-11 01:24:20 +0000 (Thu, 11 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Check for gcc float-conversion bug.
+
+------------------------------------------------------------------------
+r1847 | vlefevre | 2002-04-10 23:21:41 +0000 (Wed, 10 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/round_prec.c
+
+Added comment for mpfr_round_raw_generic (about using 1-bit precision).
+
+------------------------------------------------------------------------
+r1846 | vlefevre | 2002-04-10 14:05:52 +0000 (Wed, 10 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update (thanks to Nathalie Revol).
+
+------------------------------------------------------------------------
+r1845 | vlefevre | 2002-04-10 12:20:13 +0000 (Wed, 10 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1844 | vlefevre | 2002-04-10 12:13:25 +0000 (Wed, 10 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/rnd_mode.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+HAVE_FESETROUND renamed to MPFR_HAVE_FESETROUND to avoid possible
+name conflict.
+
+------------------------------------------------------------------------
+r1843 | vlefevre | 2002-04-10 00:12:01 +0000 (Wed, 10 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ D /trunk/srandom.h
+
+Added missing headers in libmpfr_a_SOURCES.
+
+------------------------------------------------------------------------
+r1842 | vlefevre | 2002-04-09 23:53:57 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1841 | vlefevre | 2002-04-09 23:48:30 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Possible tconst_log2 crash under Solaris.
+
+------------------------------------------------------------------------
+r1840 | vlefevre | 2002-04-09 23:30:08 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Under OSF, use option -ffloat-store only when the compiler is gcc.
+
+------------------------------------------------------------------------
+r1839 | vlefevre | 2002-04-09 23:11:46 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+include_HEADERS should contain only mpfr.h and mpf2mpfr.h.
+
+------------------------------------------------------------------------
+r1838 | vlefevre | 2002-04-09 13:47:16 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Added code to support fesetround under Solaris.
+
+------------------------------------------------------------------------
+r1837 | vlefevre | 2002-04-09 12:49:54 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+"In case of problem" update.
+
+------------------------------------------------------------------------
+r1836 | vlefevre | 2002-04-09 12:40:11 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Old URL removed.
+
+------------------------------------------------------------------------
+r1835 | vlefevre | 2002-04-09 11:33:14 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Renaming: DIR -> GMPINSTALL, GMPDIR -> GMPBUILD. Bug on IRIX updated.
+
+------------------------------------------------------------------------
+r1834 | vlefevre | 2002-04-09 11:04:42 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Removed note about stack-alloc.h.
+
+------------------------------------------------------------------------
+r1833 | vlefevre | 2002-04-09 10:50:01 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/rnd_mode.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+Check for fenv.h -> check for fesetround.
+
+------------------------------------------------------------------------
+r1832 | vlefevre | 2002-04-09 00:12:01 +0000 (Tue, 09 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/README.dev
+
+Added note concerning patch submission.
+
+------------------------------------------------------------------------
+r1831 | vlefevre | 2002-04-08 21:23:50 +0000 (Mon, 08 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Note about overflows. Functions mpfr_{div,mul}_{si,ui} described.
+
+------------------------------------------------------------------------
+r1830 | vlefevre | 2002-04-07 23:22:34 +0000 (Sun, 07 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next (and last?) pre-release.
+
+------------------------------------------------------------------------
+r1829 | vlefevre | 2002-04-07 23:11:04 +0000 (Sun, 07 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Stricter test for HAVE_INFS.
+
+------------------------------------------------------------------------
+r1828 | vlefevre | 2002-04-07 20:20:15 +0000 (Sun, 07 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Update.
+
+------------------------------------------------------------------------
+r1827 | vlefevre | 2002-04-07 20:10:31 +0000 (Sun, 07 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Added note about IRIX.
+
+------------------------------------------------------------------------
+r1826 | vlefevre | 2002-04-07 01:01:01 +0000 (Sun, 07 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1825 | vlefevre | 2002-04-07 00:38:47 +0000 (Sun, 07 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/exp.c
+ M /trunk/exp_2.c
+ M /trunk/get_d.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+ M /trunk/zeta.c
+
+mpfr_get_d -> mpfr_get_d1 and mpfr_get_d2 -> mpfr_get_d.
+
+------------------------------------------------------------------------
+r1824 | vlefevre | 2002-04-06 01:01:29 +0000 (Sat, 06 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1823 | vlefevre | 2002-04-06 00:54:50 +0000 (Sat, 06 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+Update.
+
+------------------------------------------------------------------------
+r1822 | vlefevre | 2002-04-05 23:56:33 +0000 (Fri, 05 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+New file from Paul.
+
+------------------------------------------------------------------------
+r1821 | vlefevre | 2002-04-05 12:31:59 +0000 (Fri, 05 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+COPYING.LIB removed.
+
+------------------------------------------------------------------------
+r1820 | vlefevre | 2002-04-05 12:29:11 +0000 (Fri, 05 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/COPYING
+ D /trunk/COPYING.LIB
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add_one_ulp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/cbrt.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_ui.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eq.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/fma.c
+ M /trunk/gamma.c
+ M /trunk/gammaPiAGMformula.c
+ M /trunk/generic.c
+ M /trunk/get_d.c
+ M /trunk/get_str.c
+ M /trunk/get_z_exp.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inp_str.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/minmax.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfi.c
+ M /trunk/mpfi.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-math.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/rnd_mode.c
+ M /trunk/round_prec.c
+ M /trunk/save_expo.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_f.c
+ M /trunk/set_inf.c
+ M /trunk/set_nan.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+ M /trunk/sin.c
+ M /trunk/sin_cos.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/srandom.h
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/sub_ui.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+ M /trunk/uceil_exp2.c
+ M /trunk/uceil_log2.c
+ M /trunk/ufloor_log2.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/zeta.c
+
+COPYING.LIB -> COPYING.
+
+------------------------------------------------------------------------
+r1819 | vlefevre | 2002-04-05 12:14:11 +0000 (Fri, 05 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/README
+ A /trunk/README.dev
+
+README.dev added.
+
+------------------------------------------------------------------------
+r1818 | zimmerma | 2002-04-05 12:08:31 +0000 (Fri, 05 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+put back label removed by error
+
+------------------------------------------------------------------------
+r1817 | zimmerma | 2002-04-05 12:05:35 +0000 (Fri, 05 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+removed _FPU_RC_NEAREST ... for x86 (not used any more, now use fenv.h)
+
+------------------------------------------------------------------------
+r1816 | zimmerma | 2002-04-05 12:04:40 +0000 (Fri, 05 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/sqrt.c
+
+removed nested TMP_MARK's (problems when configuring gmp with --disable-alloca)
+
+------------------------------------------------------------------------
+r1815 | zimmerma | 2002-04-05 11:47:25 +0000 (Fri, 05 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+fixed pb with two markers (with --disable-alloca)
+
+------------------------------------------------------------------------
+r1814 | vlefevre | 2002-04-05 11:40:58 +0000 (Fri, 05 Apr 2002) | 2 lines
+Changed paths:
+ D /trunk/shortmul.c
+
+Removed (not used).
+
+------------------------------------------------------------------------
+r1813 | zimmerma | 2002-04-05 07:21:21 +0000 (Fri, 05 Apr 2002) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/mpfr-test.h
+ M /trunk/rnd_mode.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+use AC_CHECK_HEADERS to check for fenv.h
+and AC_CHECK_FUNCS to check for lrand48
+
+------------------------------------------------------------------------
+r1812 | vlefevre | 2002-04-04 23:44:27 +0000 (Thu, 04 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/README
+
+Added "VERSION" and "prepare" descriptions.
+
+------------------------------------------------------------------------
+r1811 | zimmerma | 2002-04-04 14:20:19 +0000 (Thu, 04 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed bugs found by Nathalie
+
+------------------------------------------------------------------------
+r1810 | vlefevre | 2002-04-04 13:50:20 +0000 (Thu, 04 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1809 | vlefevre | 2002-04-04 13:46:23 +0000 (Thu, 04 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Removed check for extended precision, as no longer used.
+
+------------------------------------------------------------------------
+r1808 | zimmerma | 2002-04-04 11:46:32 +0000 (Thu, 04 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+added check for denormalized numbers
+
+------------------------------------------------------------------------
+r1807 | zimmerma | 2002-04-04 10:19:32 +0000 (Thu, 04 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added new functions to implement
+
+------------------------------------------------------------------------
+r1806 | vlefevre | 2002-04-03 16:28:40 +0000 (Wed, 03 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update for the next pre-release.
+
+------------------------------------------------------------------------
+r1805 | vlefevre | 2002-04-03 13:52:42 +0000 (Wed, 03 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+-ffloat-store is a gcc option.
+
+------------------------------------------------------------------------
+r1804 | vlefevre | 2002-04-03 13:40:49 +0000 (Wed, 03 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Added 4th argument to AC_TRY_RUN.
+
+------------------------------------------------------------------------
+r1803 | vlefevre | 2002-04-03 12:12:45 +0000 (Wed, 03 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Re-fix.
+
+------------------------------------------------------------------------
+r1802 | zimmerma | 2002-04-03 10:11:59 +0000 (Wed, 03 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/mpfr-test.h
+
+added check for fpu_control.h
+
+------------------------------------------------------------------------
+r1801 | zimmerma | 2002-04-03 10:02:27 +0000 (Wed, 03 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added missing cast to double
+
+------------------------------------------------------------------------
+r1800 | vlefevre | 2002-04-02 23:42:48 +0000 (Tue, 02 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+[ ] used around error message.
+
+------------------------------------------------------------------------
+r1799 | vlefevre | 2002-04-02 15:44:50 +0000 (Tue, 02 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+Update.
+
+------------------------------------------------------------------------
+r1798 | vlefevre | 2002-04-02 15:36:51 +0000 (Tue, 02 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Check BITS_PER_MP_LIMB and BYTES_PER_MP_LIMB.
+
+------------------------------------------------------------------------
+r1797 | vlefevre | 2002-04-02 12:30:24 +0000 (Tue, 02 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr-impl.h
+ D /trunk/sqrtrem.c
+
+sqrtrem.c removed.
+
+------------------------------------------------------------------------
+r1796 | vlefevre | 2002-04-02 11:50:27 +0000 (Tue, 02 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/ChangeLog
+
+New ChangeLog file (generated by rcs2log).
+
+------------------------------------------------------------------------
+r1795 | vlefevre | 2002-04-02 11:42:03 +0000 (Tue, 02 Apr 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Suppress PACKAGE and VERSION definitions for the compiler.
+
+------------------------------------------------------------------------
+r1794 | zimmerma | 2002-04-01 17:28:42 +0000 (Mon, 01 Apr 2002) | 2 lines
+Changed paths:
+ D /trunk/Configure
+
+old file
+
+------------------------------------------------------------------------
+r1793 | zimmerma | 2002-03-31 14:58:47 +0000 (Sun, 31 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+more "internal" changes suggested by Vincent
+
+------------------------------------------------------------------------
+r1792 | zimmerma | 2002-03-31 14:48:14 +0000 (Sun, 31 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added suggestions from Kevin in "internals"
+
+------------------------------------------------------------------------
+r1791 | zimmerma | 2002-03-28 09:01:28 +0000 (Thu, 28 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_d.c
+
+added test for denorms
+
+------------------------------------------------------------------------
+r1790 | zimmerma | 2002-03-28 09:01:06 +0000 (Thu, 28 Mar 2002) | 3 lines
+Changed paths:
+ M /trunk/set_d.c
+
+on a 32-bit machine, denormalized numbers with high 32 bits to 0
+were flushed to zero
+
+------------------------------------------------------------------------
+r1789 | zimmerma | 2002-03-27 15:26:18 +0000 (Wed, 27 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+
+sign of sin(-1) was not set
+
+------------------------------------------------------------------------
+r1788 | zimmerma | 2002-03-27 15:25:54 +0000 (Wed, 27 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tasin.c
+
+added check for asin(-1)
+
+------------------------------------------------------------------------
+r1787 | zimmerma | 2002-03-27 14:38:50 +0000 (Wed, 27 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/texp2.c
+
+added one test
+
+------------------------------------------------------------------------
+r1786 | zimmerma | 2002-03-27 14:38:29 +0000 (Wed, 27 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+previous fix was completely wrong
+
+------------------------------------------------------------------------
+r1785 | zimmerma | 2002-03-27 14:37:39 +0000 (Wed, 27 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/cmp_ui.c
+
+fixed pb in cmp_si when i = -2^31 (then beware that -1 * i < 0 !!!)
+
+------------------------------------------------------------------------
+r1784 | zimmerma | 2002-03-27 14:09:35 +0000 (Wed, 27 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+added check for underflow
+
+------------------------------------------------------------------------
+r1783 | zimmerma | 2002-03-26 18:39:57 +0000 (Tue, 26 Mar 2002) | 4 lines
+Changed paths:
+ A /trunk/tests/Makefile.in
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+- use mpfr_test_init to initialize harware floats
+- use #ifdef HAVE_INFS when using DBL_NAN, ...
+- fixed some problems with wrongly converted f-p values (esp. under IRIX)
+
+------------------------------------------------------------------------
+r1782 | zimmerma | 2002-03-26 18:36:49 +0000 (Tue, 26 Mar 2002) | 3 lines
+Changed paths:
+ M /trunk/configure.in
+
+use AC_TRY_CPP instead of AC_TRY_RUN for fenv.h
+(otherwise fails on Itanium)
+
+------------------------------------------------------------------------
+r1781 | zimmerma | 2002-03-26 18:35:56 +0000 (Tue, 26 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+added function mpfr_test_init to initialize full IEEE behaviour
+
+------------------------------------------------------------------------
+r1780 | zimmerma | 2002-03-26 18:34:54 +0000 (Tue, 26 Mar 2002) | 3 lines
+Changed paths:
+ M /trunk/fma.c
+
+put back simple algorithm that computes x*y exactly and then
+directly calls mpfr_add, to avoid wrong inexact flags
+
+------------------------------------------------------------------------
+r1779 | zimmerma | 2002-03-26 09:40:54 +0000 (Tue, 26 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tdump.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+
+added 2002 in copyright line
+
+------------------------------------------------------------------------
+r1778 | zimmerma | 2002-03-26 09:40:06 +0000 (Tue, 26 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+fixed problem on x86 (set precision to double to avoid double rounding)
+
+------------------------------------------------------------------------
+r1777 | zimmerma | 2002-03-26 09:36:52 +0000 (Tue, 26 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+added check for valid 1/0, denormalized, and extended precision
+
+------------------------------------------------------------------------
+r1776 | vlefevre | 2002-03-26 09:29:34 +0000 (Tue, 26 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+New-style comment removed.
+
+------------------------------------------------------------------------
+r1775 | zimmerma | 2002-03-26 09:19:05 +0000 (Tue, 26 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added a description of the mpfr_t type in "Internals"
+
+------------------------------------------------------------------------
+r1774 | vlefevre | 2002-03-26 01:50:35 +0000 (Tue, 26 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_sub.c
+
+#include <unistd.h> removed. Redefined macros ABS removed.
+
+------------------------------------------------------------------------
+r1773 | vlefevre | 2002-03-26 01:35:24 +0000 (Tue, 26 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tui_div.c
+
+Patch by Kevin Ryde + misc fixes.
+
+------------------------------------------------------------------------
+r1772 | zimmerma | 2002-03-25 17:10:50 +0000 (Mon, 25 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+replaced getpid() by time(NULL)
+
+------------------------------------------------------------------------
+r1771 | zimmerma | 2002-03-25 14:56:28 +0000 (Mon, 25 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+MPFR_SIZE and sign were incorrectly set [thanks Kevin]
+
+------------------------------------------------------------------------
+r1770 | zimmerma | 2002-03-25 13:53:31 +0000 (Mon, 25 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added check_nan (from Kevin)
+
+------------------------------------------------------------------------
+r1769 | zimmerma | 2002-03-25 13:52:26 +0000 (Mon, 25 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+fixed bug for sqrt(-0) found by Kevin [NaN flag not cleared]
+
+------------------------------------------------------------------------
+r1768 | vlefevre | 2002-03-22 15:28:29 +0000 (Fri, 22 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+Error message now copes with extended precision.
+
+------------------------------------------------------------------------
+r1767 | zimmerma | 2002-03-22 14:41:46 +0000 (Fri, 22 Mar 2002) | 5 lines
+Changed paths:
+ M /trunk/configure.in
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.texi
+ M /trunk/rnd_mode.c
+ M /trunk/tests/tget_d.c
+
+added test in configure for checking rand48 functions (HAVE_RAND48)
+and fenv.h (HAVE_FENV)
+added mpfr_set_machine_rnd_mode (if fenv.h exists)
+replaced TEST by HAVE_FENV
+
+------------------------------------------------------------------------
+r1766 | vlefevre | 2002-03-22 01:48:18 +0000 (Fri, 22 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+Missing #include.
+
+------------------------------------------------------------------------
+r1765 | vlefevre | 2002-03-22 01:25:57 +0000 (Fri, 22 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/set_nan.c
+
+MPFR_RETNAN shouldn't be used as no value is returned.
+
+------------------------------------------------------------------------
+r1764 | vlefevre | 2002-03-22 01:22:29 +0000 (Fri, 22 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/set_inf.c
+
+Regarde 0 as positive rather than negative (though it's better not to use it).
+
+------------------------------------------------------------------------
+r1763 | vlefevre | 2002-03-22 01:09:58 +0000 (Fri, 22 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/isinteger.c
+
+Memory leak (patch by Kevin Ryde).
+
+------------------------------------------------------------------------
+r1762 | zimmerma | 2002-03-21 15:35:48 +0000 (Thu, 21 Mar 2002) | 4 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+replaced rand/lrand48, drand48, srand/srand48 by macros
+ LONG_RAND, DBL_RAND, SEED_RAND
+and time(NULL) by getpid()
+
+------------------------------------------------------------------------
+r1761 | zimmerma | 2002-03-21 15:34:18 +0000 (Thu, 21 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+added macros LONG_RAND, DBL_RAND, SEED_RAND
+
+------------------------------------------------------------------------
+r1760 | zimmerma | 2002-03-21 10:04:49 +0000 (Thu, 21 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added VERSION and mpfr-math.h for "make dist"
+
+------------------------------------------------------------------------
+r1759 | zimmerma | 2002-03-19 16:45:01 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ A /trunk/set_inf.c
+ A /trunk/set_nan.c
+
+new functions
+
+------------------------------------------------------------------------
+r1758 | zimmerma | 2002-03-19 16:44:32 +0000 (Tue, 19 Mar 2002) | 3 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+now use macros DBL_NAN, DBL_POS_INF, DBL_NEG_INF,
+and functions mpfr_set_nan, mpfr_set_inf
+
+------------------------------------------------------------------------
+r1757 | zimmerma | 2002-03-19 16:42:26 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+defined macros for 0/0, 1/0, -1/0
+
+------------------------------------------------------------------------
+r1756 | zimmerma | 2002-03-19 16:40:41 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+added new functions mpfr_set_nan and mpfr_set_inf
+
+------------------------------------------------------------------------
+r1755 | vlefevre | 2002-03-19 15:09:16 +0000 (Tue, 19 Mar 2002) | 3 lines
+Changed paths:
+ A /trunk/VERSION
+ M /trunk/configure.in
+
+File VERSION added. Contains the next version (currently 2.0.1).
+configure.in updated accordingly.
+
+------------------------------------------------------------------------
+r1754 | vlefevre | 2002-03-19 08:47:22 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+ A /trunk/mpfr-math.h
+ M /trunk/tests/tadd.c
+
+Macros MPFR_DBL_NAN, MPFR_DBL_INFP and MPFR_DBL_INFM.
+
+------------------------------------------------------------------------
+r1753 | zimmerma | 2002-03-19 02:11:56 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+MP_LIMB_T_HIGHBIT -> ULONG_HIGHBIT
+
+------------------------------------------------------------------------
+r1752 | zimmerma | 2002-03-19 02:11:30 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+moved code under #ifdef
+
+------------------------------------------------------------------------
+r1751 | zimmerma | 2002-03-19 02:10:50 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+moved code under #ifdef TEST
+
+------------------------------------------------------------------------
+r1750 | zimmerma | 2002-03-19 02:10:13 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+remove variable sizer (not used)
+
+------------------------------------------------------------------------
+r1749 | zimmerma | 2002-03-19 02:09:11 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/cbrt.c
+
+Library GPL -> Lesser GPL
+
+------------------------------------------------------------------------
+r1748 | zimmerma | 2002-03-19 02:00:53 +0000 (Tue, 19 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+updated
+
+------------------------------------------------------------------------
+r1747 | vlefevre | 2002-03-17 22:13:03 +0000 (Sun, 17 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+Some changes in the types.
+
+------------------------------------------------------------------------
+r1746 | zimmerma | 2002-03-17 22:13:02 +0000 (Sun, 17 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+changed Nt variable to signed
+
+------------------------------------------------------------------------
+r1745 | vlefevre | 2002-03-17 22:03:14 +0000 (Sun, 17 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log2.c
+
+Bugs fixed.
+
+------------------------------------------------------------------------
+r1744 | zimmerma | 2002-03-17 17:53:04 +0000 (Sun, 17 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+added back mpfr_sin_cos
+
+------------------------------------------------------------------------
+r1743 | zimmerma | 2002-03-17 17:50:27 +0000 (Sun, 17 Mar 2002) | 2 lines
+Changed paths:
+ A /trunk/sin_cos.c
+
+new version (adapted from sin.c)
+
+------------------------------------------------------------------------
+r1742 | zimmerma | 2002-03-17 17:49:08 +0000 (Sun, 17 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/ttan.c
+
+added tests for tan(3*Pi/4) and tan(7*Pi/4)
+
+------------------------------------------------------------------------
+r1741 | zimmerma | 2002-03-17 17:48:38 +0000 (Sun, 17 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tan.c
+
+fixed bug for tan(3*Pi/4) [wrong sign]
+
+------------------------------------------------------------------------
+r1740 | zimmerma | 2002-03-17 17:27:42 +0000 (Sun, 17 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog10.c
+
+added test for log(10^n)
+
+------------------------------------------------------------------------
+r1739 | zimmerma | 2002-03-17 17:21:31 +0000 (Sun, 17 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/log10.c
+
+fixed infinite loop problem for log(10^n)
+
+------------------------------------------------------------------------
+r1738 | vlefevre | 2002-03-13 01:16:23 +0000 (Wed, 13 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+Fix (patch by Kevin Ryde).
+
+------------------------------------------------------------------------
+r1737 | vlefevre | 2002-03-13 00:44:20 +0000 (Wed, 13 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/get_d.c
+
+Do not read the exponent if it has no meaning.
+
+------------------------------------------------------------------------
+r1736 | vlefevre | 2002-03-12 23:58:10 +0000 (Tue, 12 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr_random update (patch by Kevin Ryde).
+
+------------------------------------------------------------------------
+r1735 | vlefevre | 2002-03-12 23:53:47 +0000 (Tue, 12 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+2 more known bugs.
+
+------------------------------------------------------------------------
+r1734 | vlefevre | 2002-03-12 23:48:06 +0000 (Tue, 12 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr_a{cos,sin,tan} documentation at a better place.
+
+------------------------------------------------------------------------
+r1733 | vlefevre | 2002-03-12 23:43:10 +0000 (Tue, 12 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+
+Some mpfr_clear added (patch by Kevin Ryde).
+
+------------------------------------------------------------------------
+r1732 | vlefevre | 2002-03-11 16:54:55 +0000 (Mon, 11 Mar 2002) | 3 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/get_d.c
+ M /trunk/tests/tget_d.c
+
+mpfr_get_d3 partially rewritten (to follow the new specifications).
+tget_d.c updated because of changes in get_d.c.
+
+------------------------------------------------------------------------
+r1731 | vlefevre | 2002-03-11 13:52:30 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/print_rnd_mode.c
+
+Return a null pointer if rnd_mode is an invalid rounding mode.
+
+------------------------------------------------------------------------
+r1730 | zimmerma | 2002-03-11 13:43:18 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+set sign before calling mpfr_check_range
+
+------------------------------------------------------------------------
+r1729 | zimmerma | 2002-03-11 13:40:02 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+stupid typo in previous commit
+
+------------------------------------------------------------------------
+r1728 | zimmerma | 2002-03-11 13:36:40 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+removed expx (not used)
+
+------------------------------------------------------------------------
+r1727 | zimmerma | 2002-03-11 13:35:12 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+ M /trunk/tests/tset_si.c
+
+fixed typo (ai [potentially unsigned] replaced by i)
+
+------------------------------------------------------------------------
+r1726 | vlefevre | 2002-03-11 13:16:54 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/get_d.c
+ M /trunk/get_str.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/tests/tget_d.c
+
+New mpfr_get_d, mpfr_get_d2, mpfr_get_d3.
+
+------------------------------------------------------------------------
+r1725 | zimmerma | 2002-03-11 13:00:29 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/print_rnd_mode.c
+
+added return
+
+------------------------------------------------------------------------
+r1724 | vlefevre | 2002-03-11 12:41:00 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/get_d.c
+ M /trunk/set_d.c
+
+set_d.c split into get_d.c and set_d.c
+
+------------------------------------------------------------------------
+r1723 | daney | 2002-03-11 12:38:44 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ A /trunk/cbrt.c
+
+add cbrt in fonctionnality
+
+------------------------------------------------------------------------
+r1722 | vlefevre | 2002-03-11 10:53:10 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Bug removed.
+
+------------------------------------------------------------------------
+r1721 | vlefevre | 2002-03-11 05:44:18 +0000 (Mon, 11 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/extract.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+#include changes.
+
+------------------------------------------------------------------------
+r1720 | zimmerma | 2002-03-07 16:42:57 +0000 (Thu, 07 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/sinh.c
+
+fixed problem when te=ti=1 (i.e. t=0) found by Kevin Ryde
+
+------------------------------------------------------------------------
+r1719 | zimmerma | 2002-03-07 16:04:54 +0000 (Thu, 07 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+simplified test4()
+
+------------------------------------------------------------------------
+r1718 | vlefevre | 2002-03-06 17:56:06 +0000 (Wed, 06 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/TODO
+
+Update.
+
+------------------------------------------------------------------------
+r1717 | vlefevre | 2002-03-06 17:05:26 +0000 (Wed, 06 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Update.
+
+------------------------------------------------------------------------
+r1716 | vlefevre | 2002-03-06 16:32:50 +0000 (Wed, 06 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Patch by Kevin Ryde concerning nodes/menus.
+
+------------------------------------------------------------------------
+r1715 | vlefevre | 2002-03-05 00:13:20 +0000 (Tue, 05 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+Casts fixed.
+
+------------------------------------------------------------------------
+r1714 | vlefevre | 2002-03-04 23:35:05 +0000 (Mon, 04 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/get_z_exp.c
+ D /trunk/internal_ceil_exp2.c
+ D /trunk/internal_ceil_log2.c
+ D /trunk/internal_floor_log2.c
+ D /trunk/mpz_set_fr.c
+ A /trunk/uceil_exp2.c
+ A /trunk/uceil_log2.c
+ A /trunk/ufloor_log2.c
+
+File renaming.
+
+------------------------------------------------------------------------
+r1713 | vlefevre | 2002-03-04 23:05:20 +0000 (Mon, 04 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add_one_ulp.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_ui.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_2si.c
+ M /trunk/div_2ui.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eq.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/fma.c
+ M /trunk/gamma.c
+ M /trunk/gammaPiAGMformula.c
+ M /trunk/generic.c
+ M /trunk/get_str.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/init2.c
+ M /trunk/inp_str.c
+ M /trunk/internal_ceil_exp2.c
+ M /trunk/internal_ceil_log2.c
+ M /trunk/internal_floor_log2.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/minmax.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfi.c
+ M /trunk/mpfi.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_2si.c
+ M /trunk/mul_2ui.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rint.c
+ M /trunk/rnd_mode.c
+ M /trunk/round_prec.c
+ M /trunk/save_expo.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_f.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sqrtrem.c
+ M /trunk/srandom.h
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub_one_ulp.c
+ M /trunk/sub_ui.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tconst_euler.c
+ M /trunk/tests/tconst_log2.c
+ M /trunk/tests/tconst_pi.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/trint.c
+ M /trunk/tests/tround_prec.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/zeta.c
+
+Copyright line changed.
+
+------------------------------------------------------------------------
+r1712 | zimmerma | 2002-03-01 13:03:11 +0000 (Fri, 01 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+updated
+
+------------------------------------------------------------------------
+r1711 | zimmerma | 2002-03-01 13:02:03 +0000 (Fri, 01 Mar 2002) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/exp_2.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpz_set_fr.c
+ M /trunk/pow.c
+
+changed name of mpz_set_fr to mpfr_get_z_exp
+
+------------------------------------------------------------------------
+r1710 | vlefevre | 2002-02-28 14:21:20 +0000 (Thu, 28 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+
+Removed some <math.h> dependencies.
+
+------------------------------------------------------------------------
+r1709 | vlefevre | 2002-02-28 00:19:56 +0000 (Thu, 28 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+Fixed.
+
+------------------------------------------------------------------------
+r1708 | vlefevre | 2002-02-28 00:19:46 +0000 (Thu, 28 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+mpfr_get_d rewritten (still needs to be fixed when the result is a subnormal).
+
+------------------------------------------------------------------------
+r1707 | vlefevre | 2002-02-27 18:16:29 +0000 (Wed, 27 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+
+mpfr_get_d2 tested.
+
+------------------------------------------------------------------------
+r1706 | vlefevre | 2002-02-27 14:29:18 +0000 (Wed, 27 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+Update.
+
+------------------------------------------------------------------------
+r1705 | vlefevre | 2002-02-27 14:02:18 +0000 (Wed, 27 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tset_d.c
+
+New tests.
+
+------------------------------------------------------------------------
+r1704 | vlefevre | 2002-02-27 14:00:16 +0000 (Wed, 27 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/configure.in
+
+Additional flags for gcc + minor changes.
+
+------------------------------------------------------------------------
+r1703 | vlefevre | 2002-02-27 13:57:51 +0000 (Wed, 27 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+Minor update.
+
+------------------------------------------------------------------------
+r1702 | vlefevre | 2002-02-25 14:50:14 +0000 (Mon, 25 Feb 2002) | 7 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/set_d.c
+
+mpfr_get_d2 prototype changed (mp_exp_t instead of long).
+__mpfr_scale2 fixes: checks for integer overflows, signed zeros, exact
+rounding for subnormals in the rounding to the nearest mode (problems
+due to multiple roundings avoided).
+mpfr_get_d2: signed zeros taken into account. This function still needs
+to be rewritten (because of multiple roundings).
+
+------------------------------------------------------------------------
+r1701 | vlefevre | 2002-02-21 15:43:40 +0000 (Thu, 21 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/agm.c
+ A /trunk/internal_ceil_exp2.c
+ A /trunk/internal_ceil_log2.c
+ A /trunk/internal_floor_log2.c
+
+_mpfr_ceil_log2, _mpfr_floor_log2, _mpfr_ceil_exp2 in separate files.
+
+------------------------------------------------------------------------
+r1700 | vlefevre | 2002-02-19 16:05:52 +0000 (Tue, 19 Feb 2002) | 3 lines
+Changed paths:
+ M /trunk/get_str.c
+
+Fixes, code clean-up and some asserts against integer overflows.
+Code need to be checked.
+
+------------------------------------------------------------------------
+r1699 | vlefevre | 2002-02-14 11:36:40 +0000 (Thu, 14 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/acos.c
+ M /trunk/agm.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/const_euler.c
+ M /trunk/const_log2.c
+ M /trunk/const_pi.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/gamma.c
+ M /trunk/generic.c
+ M /trunk/get_str.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/tanh.c
+ M /trunk/zeta.c
+
+mpfr_{div,mul}_2exp -> mpfr_{div,mul}_2ui.
+
+------------------------------------------------------------------------
+r1698 | vlefevre | 2002-02-14 02:35:35 +0000 (Thu, 14 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+Partial code clean-up and some asserts against integer overflows (2).
+
+------------------------------------------------------------------------
+r1697 | vlefevre | 2002-02-13 13:53:46 +0000 (Wed, 13 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+Partial code clean-up and some asserts against integer overflows.
+
+------------------------------------------------------------------------
+r1696 | vlefevre | 2002-02-13 13:18:12 +0000 (Wed, 13 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+MP_EXP_T_MAX and MP_EXP_T_MIN defined.
+
+------------------------------------------------------------------------
+r1695 | vlefevre | 2002-02-13 10:49:09 +0000 (Wed, 13 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Macros IS_POW2 and NOT_POW2.
+
+------------------------------------------------------------------------
+r1694 | vlefevre | 2002-02-12 17:11:50 +0000 (Tue, 12 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/ui_pow_ui.c
+
+Use mpfr_save_emin_emax and MPFR_RESTORE_RET.
+
+------------------------------------------------------------------------
+r1693 | vlefevre | 2002-02-12 16:41:50 +0000 (Tue, 12 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tdump.c
+
+Update due to changes in mpfr_get_str.
+
+------------------------------------------------------------------------
+r1692 | vlefevre | 2002-02-12 16:41:36 +0000 (Tue, 12 Feb 2002) | 4 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpz_set_fr.c
+ M /trunk/out_str.c
+
+mpfr_get_str: the returned exponent for 0 is 0 (like in frexp()).
+mpz_set_fr.c: comment added.
+out_str.c: minor changes.
+
+------------------------------------------------------------------------
+r1691 | vlefevre | 2002-02-12 15:59:02 +0000 (Tue, 12 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Update.
+
+------------------------------------------------------------------------
+r1690 | vlefevre | 2002-02-12 14:42:23 +0000 (Tue, 12 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/ui_pow_ui.c
+
+Bug fixed and other changes.
+
+------------------------------------------------------------------------
+r1689 | vlefevre | 2002-02-12 14:08:25 +0000 (Tue, 12 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+NULL -> null pointer and other small changes.
+
+------------------------------------------------------------------------
+r1688 | vlefevre | 2002-02-12 14:03:02 +0000 (Tue, 12 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr.texi
+
+mpfr_get_str: null pointer returned in case of error, NaN taken into account.
+
+------------------------------------------------------------------------
+r1687 | vlefevre | 2002-02-11 14:59:18 +0000 (Mon, 11 Feb 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/set_str.c
+
+mpfr_set_str partially rewritten to cope with integer overflows.
+The rounding code hasn't been fixed yet.
+
+------------------------------------------------------------------------
+r1686 | vlefevre | 2002-02-08 17:04:01 +0000 (Fri, 08 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Typo.
+
+------------------------------------------------------------------------
+r1685 | vlefevre | 2002-02-08 17:01:49 +0000 (Fri, 08 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/set_str.c
+
+mpfr_set_str: base must be between 2 and 36.
+
+------------------------------------------------------------------------
+r1684 | daney | 2002-02-06 15:34:46 +0000 (Wed, 06 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+
+chnage the return values
+
+------------------------------------------------------------------------
+r1683 | daney | 2002-02-06 15:34:15 +0000 (Wed, 06 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+Change the test return values
+
+------------------------------------------------------------------------
+r1682 | vlefevre | 2002-02-06 02:57:55 +0000 (Wed, 06 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+Some optimizations.
+
+------------------------------------------------------------------------
+r1681 | vlefevre | 2002-02-04 01:04:59 +0000 (Mon, 04 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/pow_ui.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_sub.c
+
+Misc bug fixes and code clean-up.
+
+------------------------------------------------------------------------
+r1680 | vlefevre | 2002-02-04 00:16:27 +0000 (Mon, 04 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/pow.c
+
+Misc bug fixes and code clean-up.
+
+------------------------------------------------------------------------
+r1679 | vlefevre | 2002-02-03 02:59:44 +0000 (Sun, 03 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/mpz_set_fr.c
+
+For the value 0, return __mpfr_emin instead of 0.
+
+------------------------------------------------------------------------
+r1678 | vlefevre | 2002-02-01 21:35:34 +0000 (Fri, 01 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/agm.c
+ M /trunk/asinh.c
+ M /trunk/atanh.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/dim.c
+ M /trunk/div_ui.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/expm1.c
+ M /trunk/hypot.c
+ M /trunk/log.c
+ M /trunk/log10.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/pow_si.c
+
+Misc bug fixes and code clean-up.
+
+------------------------------------------------------------------------
+r1677 | hanrot | 2002-02-01 18:17:56 +0000 (Fri, 01 Feb 2002) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+Patch.
+
+------------------------------------------------------------------------
+r1676 | vlefevre | 2002-01-30 14:57:31 +0000 (Wed, 30 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/trint.c
+
+Bux fixed.
+
+------------------------------------------------------------------------
+r1675 | vlefevre | 2002-01-30 14:57:24 +0000 (Wed, 30 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/set_z.c
+
+mpfr_set_z rewritten.
+
+------------------------------------------------------------------------
+r1674 | vlefevre | 2002-01-30 12:37:04 +0000 (Wed, 30 Jan 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Update concerning mpfr_round_prec, mpfr_rint, mpfr_ceil, mpfr_floor,
+mpfr_round and mpfr_trunc.
+
+------------------------------------------------------------------------
+r1673 | vlefevre | 2002-01-30 04:57:52 +0000 (Wed, 30 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/reuse.c
+ A /trunk/tests/trint.c
+
+Tests added (mpfr_trunc, mpfr_floor, mpfr_ceil, mpfr_round).
+
+------------------------------------------------------------------------
+r1672 | vlefevre | 2002-01-30 04:57:10 +0000 (Wed, 30 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr.h
+ A /trunk/rint.c
+ D /trunk/trunc.c
+
+mpfr_rint, mpfr_trunc, mpfr_floor, mpfr_ceil, mpfr_round rewritten.
+
+------------------------------------------------------------------------
+r1671 | vlefevre | 2002-01-25 14:00:37 +0000 (Fri, 25 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/cos.c
+ M /trunk/get_str.c
+ M /trunk/mpfr.h
+ D /trunk/round.c
+ A /trunk/round_prec.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/tacos.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tgamma.c
+ D /trunk/tests/tround.c
+ A /trunk/tests/tround_prec.c
+
+mpfr_round -> mpfr_round_prec.
+
+------------------------------------------------------------------------
+r1670 | vlefevre | 2002-01-25 13:43:31 +0000 (Fri, 25 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+Code reformatted.
+
+------------------------------------------------------------------------
+r1669 | vlefevre | 2002-01-23 00:08:52 +0000 (Wed, 23 Jan 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+MAX, MIN, ABS macros undefined before being redefined.
+Fix in ABS macro.
+
+------------------------------------------------------------------------
+r1668 | vlefevre | 2002-01-22 02:29:47 +0000 (Tue, 22 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+Example with high bit set.
+
+------------------------------------------------------------------------
+r1667 | vlefevre | 2002-01-22 02:29:35 +0000 (Tue, 22 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+Fix (Kevin Ryde).
+
+------------------------------------------------------------------------
+r1666 | vlefevre | 2002-01-22 00:45:44 +0000 (Tue, 22 Jan 2002) | 4 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/sqrt.c
+
+MPFR_PREC_MAX redefined.
+MPFR_INTPREC_MAX defined (internal maximum precision).
+Some integer overflow detection.
+
+------------------------------------------------------------------------
+r1665 | vlefevre | 2002-01-21 11:37:41 +0000 (Mon, 21 Jan 2002) | 3 lines
+Changed paths:
+ M /trunk/sqrt_ui.c
+
+Set sign of sqrt(0).
+Support for exponent range.
+
+------------------------------------------------------------------------
+r1664 | vlefevre | 2002-01-21 10:38:37 +0000 (Mon, 21 Jan 2002) | 3 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+can_round type changed: char -> int.
+Case sqrt(0) improved.
+
+------------------------------------------------------------------------
+r1663 | vlefevre | 2002-01-21 10:26:13 +0000 (Mon, 21 Jan 2002) | 4 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+Bug fixes:
+ * return 1 -> MPFR_RET_NAN
+ * a MPFR_CLEAR_INF was missing.
+
+------------------------------------------------------------------------
+r1662 | vlefevre | 2002-01-20 00:17:27 +0000 (Sun, 20 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/add_ui.c
+ M /trunk/mpfr-impl.h
+ M /trunk/sub_ui.c
+
+New macro MPFR_RESTORE_RET.
+
+------------------------------------------------------------------------
+r1661 | vlefevre | 2002-01-18 16:13:33 +0000 (Fri, 18 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+Code clean-up (goto suppressed).
+
+------------------------------------------------------------------------
+r1660 | vlefevre | 2002-01-18 15:40:30 +0000 (Fri, 18 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+Cases 0 * 0 + 0.
+
+------------------------------------------------------------------------
+r1659 | vlefevre | 2002-01-18 11:33:22 +0000 (Fri, 18 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+Nt: int -> mp_prec_t
+
+------------------------------------------------------------------------
+r1658 | vlefevre | 2002-01-18 11:15:54 +0000 (Fri, 18 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+ M /trunk/tests/tacosh.c
+
+<> changed back to "".
+
+------------------------------------------------------------------------
+r1657 | daney | 2002-01-18 09:58:00 +0000 (Fri, 18 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+
+change "" -> <> in headers
+
+------------------------------------------------------------------------
+r1656 | daney | 2002-01-18 09:51:03 +0000 (Fri, 18 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+Change indendation + replace "" -> <> in header
+
+------------------------------------------------------------------------
+r1655 | vlefevre | 2002-01-17 21:45:41 +0000 (Thu, 17 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+Particular cases rewritten.
+
+------------------------------------------------------------------------
+r1654 | vlefevre | 2002-01-17 20:33:21 +0000 (Thu, 17 Jan 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+Test "__hpux", not "hpux". Mask off mrand48 return value to 31 bits
+to work around sloppy mpfr #include practices. (Torbjorn Granlund)
+
+------------------------------------------------------------------------
+r1653 | vlefevre | 2002-01-17 20:29:58 +0000 (Thu, 17 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tlog10.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/tui_pow.c
+
+#include fixes (Torbjorn Granlund).
+
+------------------------------------------------------------------------
+r1652 | vlefevre | 2002-01-16 15:14:09 +0000 (Wed, 16 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+Comments were incorrect.
+
+------------------------------------------------------------------------
+r1651 | vlefevre | 2002-01-15 11:23:34 +0000 (Tue, 15 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Note concerning mpfr_trunc, mpfr_floor and mpfr_ceil.
+
+------------------------------------------------------------------------
+r1650 | vlefevre | 2002-01-14 13:09:42 +0000 (Mon, 14 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+Special cases.
+
+------------------------------------------------------------------------
+r1649 | vlefevre | 2002-01-12 01:27:53 +0000 (Sat, 12 Jan 2002) | 3 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/shortmul.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+
+Patches by Kevin Ryde for K&R compilers
+and other fixes in prototypes.
+
+------------------------------------------------------------------------
+r1648 | vlefevre | 2002-01-10 22:20:28 +0000 (Thu, 10 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+Test check_min added.
+
+------------------------------------------------------------------------
+r1647 | vlefevre | 2002-01-10 21:45:00 +0000 (Thu, 10 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+Test check_max added.
+
+------------------------------------------------------------------------
+r1646 | vlefevre | 2002-01-10 13:42:21 +0000 (Thu, 10 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+ M /trunk/cmp2.c
+ M /trunk/log.c
+
+Spelling: "canceled"
+
+------------------------------------------------------------------------
+r1645 | zimmerma | 2002-01-10 13:05:58 +0000 (Thu, 10 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+GMP_PROTO change was already done by Vincent
+
+------------------------------------------------------------------------
+r1644 | zimmerma | 2002-01-10 12:58:47 +0000 (Thu, 10 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+prepare change PROTO -> GMP_PROTO
+
+------------------------------------------------------------------------
+r1643 | vlefevre | 2002-01-04 14:41:33 +0000 (Fri, 04 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/sub_one_ulp.c
+
+The precision can no longer be 1.
+
+------------------------------------------------------------------------
+r1642 | vlefevre | 2002-01-04 03:07:23 +0000 (Fri, 04 Jan 2002) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+__GMP_PROTO defined if not already defined.
+
+------------------------------------------------------------------------
+r1641 | vlefevre | 2002-01-04 02:57:08 +0000 (Fri, 04 Jan 2002) | 5 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/agm.c
+ M /trunk/cmp2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+
+Optimization: mpfr_cmp2 now accepts any combination of real arguments
+and computes the sign of |b| - |c| (in addition to the number of
+cancelled bits); mpfr_add, mpfr_sub, mpfr_sub1, mpfr_agm and some
+tests updated to take this change into account.
+
+------------------------------------------------------------------------
+r1640 | zimmerma | 2001-12-21 16:33:10 +0000 (Fri, 21 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+
+added check for sin(3*Pi/2)
+
+------------------------------------------------------------------------
+r1639 | zimmerma | 2001-12-21 16:33:02 +0000 (Fri, 21 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+
+fixed bug for sin(3*Pi/2)
+
+------------------------------------------------------------------------
+r1638 | vlefevre | 2001-12-19 15:50:01 +0000 (Wed, 19 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+Global NaN flag set when result is NaN.
+
+------------------------------------------------------------------------
+r1637 | zimmerma | 2001-12-19 14:41:04 +0000 (Wed, 19 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+forgot to clear nan flag for Inf
+
+------------------------------------------------------------------------
+r1636 | zimmerma | 2001-12-19 13:32:05 +0000 (Wed, 19 Dec 2001) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+changed description of mpfr_cmp to correspond to the implementation:
+NaNs are not allowed
+
+------------------------------------------------------------------------
+r1635 | zimmerma | 2001-12-19 12:39:49 +0000 (Wed, 19 Dec 2001) | 6 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+fixed mpfr_cmp2 : there was a bug noticed by Nicolas Magaud and Didier
+Bondyfalat for inputs:
+100 011 111
+100 010 110
+where it gave 8 instead of 5.
+
+------------------------------------------------------------------------
+r1634 | vlefevre | 2001-12-19 10:44:15 +0000 (Wed, 19 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/sub1.c
+
+Better comments.
+
+------------------------------------------------------------------------
+r1633 | zimmerma | 2001-12-10 09:20:59 +0000 (Mon, 10 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+ M /trunk/algorithms.tex
+
+added "PI and the AGM"
+
+------------------------------------------------------------------------
+r1632 | vlefevre | 2001-12-06 17:25:46 +0000 (Thu, 06 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tlog10.c
+ A /trunk/tests/tlog2.c
+ D /trunk/tests/tlog_base_10.c
+ D /trunk/tests/tlog_base_2.c
+
+Files renamed (log in base 2 and 10).
+
+------------------------------------------------------------------------
+r1631 | vlefevre | 2001-12-06 17:22:14 +0000 (Thu, 06 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tconst_euler.c
+ A /trunk/tests/tconst_log2.c
+ A /trunk/tests/tconst_pi.c
+ D /trunk/tests/teuler.c
+ D /trunk/tests/tlog2.c
+ D /trunk/tests/tpi.c
+
+Files renamed (constants).
+
+------------------------------------------------------------------------
+r1630 | vlefevre | 2001-12-06 17:12:59 +0000 (Thu, 06 Dec 2001) | 2 lines
+Changed paths:
+ D /trunk/aclocal.m4
+
+File aclocal.m4 removed, as generated by aclocal (called by prepare).
+
+------------------------------------------------------------------------
+r1629 | vlefevre | 2001-12-06 17:02:18 +0000 (Thu, 06 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/log10.c
+ A /trunk/log2.c
+ D /trunk/log_base_10.c
+ D /trunk/log_base_2.c
+
+Files log_base_*.c renamed.
+
+------------------------------------------------------------------------
+r1628 | vlefevre | 2001-12-06 16:53:25 +0000 (Thu, 06 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/const_euler.c
+ A /trunk/const_log2.c
+ A /trunk/const_pi.c
+ D /trunk/euler.c
+ D /trunk/log2.c
+ D /trunk/pi.c
+
+Functions (constants) renamed.
+
+------------------------------------------------------------------------
+r1627 | vlefevre | 2001-12-06 16:33:10 +0000 (Thu, 06 Dec 2001) | 3 lines
+Changed paths:
+ D /trunk/Makefile.in
+ D /trunk/configure
+ D /trunk/tests/Makefile.in
+
+Files configure, Makefile.in, tests/Makefile.in removed.
+Use the `prepare' script to generate them.
+
+------------------------------------------------------------------------
+r1626 | vlefevre | 2001-12-06 12:37:05 +0000 (Thu, 06 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+Removed 2 bugs.
+
+------------------------------------------------------------------------
+r1625 | vlefevre | 2001-12-06 12:12:43 +0000 (Thu, 06 Dec 2001) | 2 lines
+Changed paths:
+ A /trunk/prepare
+
+Initial release.
+
+------------------------------------------------------------------------
+r1624 | zimmerma | 2001-12-05 17:06:03 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added arc-tangent (from Mathieu)
+
+------------------------------------------------------------------------
+r1623 | zimmerma | 2001-12-05 16:29:15 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added paragraph on asin and acos from Mathieu Dutour
+
+------------------------------------------------------------------------
+r1622 | zimmerma | 2001-12-05 16:28:31 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ A /trunk/tests/tacos.c
+
+added tacos
+
+------------------------------------------------------------------------
+r1621 | zimmerma | 2001-12-05 16:27:44 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+in check5, test NaNs before calling mpfr_cmp
+
+------------------------------------------------------------------------
+r1620 | zimmerma | 2001-12-05 16:26:56 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+added acos
+
+------------------------------------------------------------------------
+r1619 | zimmerma | 2001-12-05 16:26:34 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added acos.c
+
+------------------------------------------------------------------------
+r1618 | zimmerma | 2001-12-05 16:26:02 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ A /trunk/acos.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+added acos (from Mathieu Dutour)
+
+------------------------------------------------------------------------
+r1617 | zimmerma | 2001-12-05 16:25:10 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+use now new sqrtrem from gmp-4.0
+
+------------------------------------------------------------------------
+r1616 | zimmerma | 2001-12-05 16:08:30 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv_ui.c
+
+improved test (avoid mpfr_get_d)
+
+------------------------------------------------------------------------
+r1615 | zimmerma | 2001-12-05 15:15:47 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_d.c
+
+removed isnan prototype
+
+------------------------------------------------------------------------
+r1614 | zimmerma | 2001-12-05 15:11:47 +0000 (Wed, 05 Dec 2001) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+added stdlib.h for exit
+
+------------------------------------------------------------------------
+r1613 | zimmerma | 2001-11-30 17:55:16 +0000 (Fri, 30 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/dump.c
+ M /trunk/tests/tdump.c
+
+test NaN before Inf
+changed precision to 2 for test
+
+------------------------------------------------------------------------
+r1612 | vlefevre | 2001-11-30 15:57:22 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/set_prc_raw.c
+
+Cast added.
+
+------------------------------------------------------------------------
+r1611 | zimmerma | 2001-11-30 14:48:45 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+added a new test (worst case)
+
+------------------------------------------------------------------------
+r1610 | zimmerma | 2001-11-30 14:48:12 +0000 (Fri, 30 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/atan.c
+
+nouvelle version de Mathieu Dutour,
+corrigeant certains bugs avec les pires cas de Vincent
+
+------------------------------------------------------------------------
+r1609 | vlefevre | 2001-11-30 14:37:25 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpz_set_fr.c
+ M /trunk/set_d.c
+
+#include order changed.
+
+------------------------------------------------------------------------
+r1608 | vlefevre | 2001-11-30 14:29:38 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/set_prec.c
+
+Misc fixes.
+
+------------------------------------------------------------------------
+r1607 | vlefevre | 2001-11-30 13:44:59 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+Unused variables.
+
+------------------------------------------------------------------------
+r1606 | zimmerma | 2001-11-30 13:37:37 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teuler.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tlog_base_10.c
+ M /trunk/tests/tlog_base_2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+
+start tests with precision 2 instead of 1
+
+------------------------------------------------------------------------
+r1605 | zimmerma | 2001-11-30 13:29:57 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+
+start from precision 2
+
+------------------------------------------------------------------------
+r1604 | zimmerma | 2001-11-30 13:29:06 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+big rewrite to fix problems when the estimate base exponent is too small
+
+------------------------------------------------------------------------
+r1603 | zimmerma | 2001-11-30 13:28:04 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+fixed detection of exact cases (in particular 0)
+
+------------------------------------------------------------------------
+r1602 | zimmerma | 2001-11-30 13:27:30 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+now use MPFR_PREC_MIN
+
+------------------------------------------------------------------------
+r1601 | zimmerma | 2001-11-30 13:27:01 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+exptol is now of type mp_exp_t
+
+------------------------------------------------------------------------
+r1600 | zimmerma | 2001-11-30 13:26:03 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/log2.c
+
+rewritten part with Taylor series
+
+------------------------------------------------------------------------
+r1599 | zimmerma | 2001-11-30 13:03:07 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+changed MPFR_PREC_MIN to 2
+
+------------------------------------------------------------------------
+r1598 | zimmerma | 2001-11-30 13:02:45 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/set_prc_raw.c
+
+updated wrt MPFR_PREC_MIN/MPFR_PREC_MAX
+
+------------------------------------------------------------------------
+r1597 | zimmerma | 2001-11-30 12:53:16 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpz_set_fr.c
+
+case x=0 was forgotten
+
+------------------------------------------------------------------------
+r1596 | zimmerma | 2001-11-30 12:52:07 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/set_prec.c
+
+now use MPFR_PREC_MIN
+
+------------------------------------------------------------------------
+r1595 | zimmerma | 2001-11-30 12:51:26 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/sub1.c
+
+added comment
+
+------------------------------------------------------------------------
+r1594 | vlefevre | 2001-11-30 02:41:36 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/set_z.c
+
+mpfr_set_z rewritten to support overflows/underflows and ternary value.
+
+------------------------------------------------------------------------
+r1593 | vlefevre | 2001-11-30 00:10:52 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/set_z.c
+
+0 -> set to +0.
+
+------------------------------------------------------------------------
+r1592 | vlefevre | 2001-11-30 00:07:36 +0000 (Fri, 30 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Better sign comparison.
+
+------------------------------------------------------------------------
+r1591 | vlefevre | 2001-11-29 23:56:56 +0000 (Thu, 29 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+
+Use MPFR_SET_POS.
+
+------------------------------------------------------------------------
+r1590 | vlefevre | 2001-11-29 14:23:12 +0000 (Thu, 29 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/trunc.c
+
+Bug fixed concerning integer overflows.
+
+------------------------------------------------------------------------
+r1589 | zimmerma | 2001-11-29 09:43:55 +0000 (Thu, 29 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/init2.c
+
+added comment
+
+------------------------------------------------------------------------
+r1588 | zimmerma | 2001-11-29 09:43:35 +0000 (Thu, 29 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+
+fixed bug for small precision, where r can be >= 1
+
+------------------------------------------------------------------------
+r1587 | vlefevre | 2001-11-29 03:15:54 +0000 (Thu, 29 Nov 2001) | 4 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/div_2exp.c
+ A /trunk/div_2si.c
+ A /trunk/div_2ui.c
+ M /trunk/log.c
+ M /trunk/mpfr.h
+ M /trunk/mul_2exp.c
+ A /trunk/mul_2si.c
+ A /trunk/mul_2ui.c
+
+Functions mpfr_{mul,div}_2{si,ui} added.
+Functions mpfr_{mul,div}_2exp still exist for backward compatibility;
+they are obsolete and should not be used any longer.
+
+------------------------------------------------------------------------
+r1586 | vlefevre | 2001-11-28 17:57:53 +0000 (Wed, 28 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/minmax.c
+
+Particular cases (NaN and signed zeros).
+
+------------------------------------------------------------------------
+r1585 | vlefevre | 2001-11-28 17:12:35 +0000 (Wed, 28 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/init2.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/thyperbolic.c
+
+Init variables to NaN instead of 0.
+
+------------------------------------------------------------------------
+r1584 | vlefevre | 2001-11-28 17:09:37 +0000 (Wed, 28 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+
+Possible integer overflow fixed.
+
+------------------------------------------------------------------------
+r1583 | vlefevre | 2001-11-28 16:54:20 +0000 (Wed, 28 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+ M /trunk/atan.c
+
+Particular cases fixed.
+
+------------------------------------------------------------------------
+r1582 | vlefevre | 2001-11-25 15:24:31 +0000 (Sun, 25 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/trunc.c
+
+Overflow support.
+
+------------------------------------------------------------------------
+r1581 | vlefevre | 2001-11-25 14:44:49 +0000 (Sun, 25 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/trunc.c
+
+K&R -> ISO C prototype.
+
+------------------------------------------------------------------------
+r1580 | vlefevre | 2001-11-25 08:04:07 +0000 (Sun, 25 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/div_2exp.c
+
+mpfr_div_2exp rewritten.
+
+------------------------------------------------------------------------
+r1579 | vlefevre | 2001-11-25 07:49:47 +0000 (Sun, 25 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mul_2exp.c
+
+mpfr_mul_2exp rewritten.
+
+------------------------------------------------------------------------
+r1578 | vlefevre | 2001-11-25 06:53:41 +0000 (Sun, 25 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+Overflow support.
+
+------------------------------------------------------------------------
+r1577 | vlefevre | 2001-11-25 06:20:35 +0000 (Sun, 25 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/init2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/round.c
+
+Casts to size_t added (safer and could be required in the future).
+
+------------------------------------------------------------------------
+r1576 | vlefevre | 2001-11-23 16:39:25 +0000 (Fri, 23 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Minor change.
+
+------------------------------------------------------------------------
+r1575 | vlefevre | 2001-11-23 16:28:08 +0000 (Fri, 23 Nov 2001) | 5 lines
+Changed paths:
+ M /trunk/mul.c
+
+mpfr_mul partially rewritten:
+ * Integer overflows almost completely avoided.
+ * Now supports signed zeros and overflows.
+Not tested yet.
+
+------------------------------------------------------------------------
+r1574 | vlefevre | 2001-11-22 17:21:08 +0000 (Thu, 22 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+mpfr_can_round_raw: integer overflows checked and code duplication avoided.
+
+------------------------------------------------------------------------
+r1573 | vlefevre | 2001-11-22 15:32:44 +0000 (Thu, 22 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+More bugs.
+
+------------------------------------------------------------------------
+r1572 | vlefevre | 2001-11-22 12:48:20 +0000 (Thu, 22 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/round.c
+
+mpfr_can_round and mpfr_can_round_raw: prototypes changed.
+
+------------------------------------------------------------------------
+r1571 | vlefevre | 2001-11-21 20:40:47 +0000 (Wed, 21 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/exceptions.c
+
+Bug fixed.
+
+------------------------------------------------------------------------
+r1570 | vlefevre | 2001-11-21 20:07:35 +0000 (Wed, 21 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ A /trunk/add_one_ulp.c
+ D /trunk/add_ulp.c
+ M /trunk/div_ui.c
+ M /trunk/exp.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/set_z.c
+ A /trunk/sub_one_ulp.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tsqrt.c
+
+mpfr_add_one_ulp and mpfr_sub_one_ulp changed.
+
+------------------------------------------------------------------------
+r1569 | vlefevre | 2001-11-21 15:50:45 +0000 (Wed, 21 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/init2.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/round.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_rnd.c
+
+Added MPFR_PREC_MIN and MPFR_PREC_MAX.
+
+------------------------------------------------------------------------
+r1568 | vlefevre | 2001-11-21 14:06:36 +0000 (Wed, 21 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/init2.c
+
+Error test -> assert.
+mp_prec_t -> mp_size_t.
+
+------------------------------------------------------------------------
+r1567 | vlefevre | 2001-11-20 14:10:05 +0000 (Tue, 20 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tround.c
+
+Test added.
+
+------------------------------------------------------------------------
+r1566 | vlefevre | 2001-11-20 14:09:55 +0000 (Tue, 20 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/round.c
+
+mpfr_round rewritten.
+mpfr_round_raw_generic: NULL changed to 0 as not necessarily defined.
+
+------------------------------------------------------------------------
+r1565 | vlefevre | 2001-11-20 13:41:41 +0000 (Tue, 20 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Added macro MPFR_SET_ABSSIZE.
+
+------------------------------------------------------------------------
+r1564 | vlefevre | 2001-11-20 02:17:32 +0000 (Tue, 20 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+mpfr_round: Check for overflow.
+
+------------------------------------------------------------------------
+r1563 | vlefevre | 2001-11-17 03:58:19 +0000 (Sat, 17 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/sub1.c
+
+Some type changes.
+
+------------------------------------------------------------------------
+r1562 | vlefevre | 2001-11-16 17:58:50 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/add1.c
+ M /trunk/mpz_set_fr.c
+
+Integer overflows checked.
+
+------------------------------------------------------------------------
+r1561 | vlefevre | 2001-11-16 17:16:31 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpz_set_fr.c
+
+MPFR_ASSERTN instead of fprintf + exit.
+
+------------------------------------------------------------------------
+r1560 | vlefevre | 2001-11-16 17:10:30 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+GMP assert mechanism: macros changed until GMP is fixed.
+
+------------------------------------------------------------------------
+r1559 | zimmerma | 2001-11-16 17:04:15 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+version -> 2002
+removed executable flag
+
+------------------------------------------------------------------------
+r1558 | zimmerma | 2001-11-16 14:38:24 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/exp_2.c
+ M /trunk/log.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/print_raw.c
+ M /trunk/sub1.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/teuler.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+
+mpfr_print_raw -> mpfr_print_binary
+
+------------------------------------------------------------------------
+r1557 | zimmerma | 2001-11-16 14:15:57 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/init2.c
+
+split from init.c
+
+------------------------------------------------------------------------
+r1556 | daney | 2001-11-16 14:14:10 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/expm1.c
+ M /trunk/log1p.c
+ M /trunk/tanh.c
+
+remove math.h
+
+------------------------------------------------------------------------
+r1555 | daney | 2001-11-16 14:04:13 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/sinh.c
+
+remve math.h
+
+------------------------------------------------------------------------
+r1554 | zimmerma | 2001-11-16 14:04:06 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added one test
+
+------------------------------------------------------------------------
+r1553 | daney | 2001-11-16 14:00:29 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/atanh.c
+
+remove math.h
+
+------------------------------------------------------------------------
+r1552 | zimmerma | 2001-11-16 13:54:55 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/init.c
+
+init -> init + init2.
+
+------------------------------------------------------------------------
+r1551 | daney | 2001-11-16 13:54:32 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/asinh.c
+
+remove math.h
+
+------------------------------------------------------------------------
+r1550 | hanrot | 2001-11-16 13:27:50 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+Ajoute retours chariots dans div.c, etc.
+
+------------------------------------------------------------------------
+r1549 | hanrot | 2001-11-16 13:23:43 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+if () remplace par if ( ==0) ou if ( != 0)
+
+------------------------------------------------------------------------
+r1548 | zimmerma | 2001-11-16 13:22:13 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/TODO
+ M /trunk/add_ui.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atanh.c
+ M /trunk/clear.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/dim.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/fma.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/isinteger.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/log_base_10.c
+ M /trunk/log_base_2.c
+ M /trunk/minmax.c
+ M /trunk/mul.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/print_raw.c
+ M /trunk/rnd_mode.c
+ M /trunk/set_rnd.c
+ M /trunk/set_str_raw.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/Makefile.in
+ M /trunk/ui_pow.c
+
+removed K&R function headers
+
+------------------------------------------------------------------------
+r1547 | hanrot | 2001-11-16 13:19:50 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+Beuh ?
+
+------------------------------------------------------------------------
+r1546 | hanrot | 2001-11-16 13:19:42 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/inp_str.c
+
+return -> MPFR_RET, patch d'un leak dans inp_str.c
+
+------------------------------------------------------------------------
+r1545 | zimmerma | 2001-11-16 13:09:07 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+changed to use GMP assert mechanism
+
+------------------------------------------------------------------------
+r1544 | daney | 2001-11-16 12:55:53 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+
+remove stdio.h math.h
+
+------------------------------------------------------------------------
+r1543 | zimmerma | 2001-11-16 12:54:09 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/euler.c
+
+assert -> MPFR_ASSERT
+
+------------------------------------------------------------------------
+r1542 | daney | 2001-11-16 12:52:55 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+remove stdio math .h
+
+------------------------------------------------------------------------
+r1541 | daney | 2001-11-16 12:50:31 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/isinteger.c
+
+remove stdio.h math.h
+
+------------------------------------------------------------------------
+r1540 | zimmerma | 2001-11-16 12:49:36 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+ M /trunk/sub1.c
+
+ASSERT_ALWAYS -> MPFR_ASSERTN
+
+------------------------------------------------------------------------
+r1539 | zimmerma | 2001-11-16 12:39:30 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added COPYING.LIB
+
+------------------------------------------------------------------------
+r1538 | zimmerma | 2001-11-16 12:38:56 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/COPYING
+
+replaced by GPL
+
+------------------------------------------------------------------------
+r1537 | daney | 2001-11-16 12:34:00 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/factorial.c
+
+remove limits.h
+
+------------------------------------------------------------------------
+r1536 | zimmerma | 2001-11-16 12:32:48 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/add.c
+ M /trunk/add1.c
+ M /trunk/add_ui.c
+ M /trunk/add_ulp.c
+ M /trunk/agm.c
+ M /trunk/asin.c
+ M /trunk/asinh.c
+ M /trunk/atan.c
+ M /trunk/atanh.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp2.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_ui.c
+ M /trunk/copysign.c
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/dim.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eq.c
+ M /trunk/euler.c
+ M /trunk/exceptions.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/expm1.c
+ M /trunk/extract.c
+ M /trunk/factorial.c
+ M /trunk/fma.c
+ M /trunk/gamma.c
+ M /trunk/gammaPiAGMformula.c
+ M /trunk/generic.c
+ M /trunk/get_str.c
+ M /trunk/gmp_op.c
+ M /trunk/hypot.c
+ M /trunk/init.c
+ M /trunk/inp_str.c
+ M /trunk/isinf.c
+ M /trunk/isinteger.c
+ M /trunk/isnan.c
+ M /trunk/isnum.c
+ M /trunk/log.c
+ M /trunk/log1p.c
+ M /trunk/log2.c
+ M /trunk/log_base_10.c
+ M /trunk/log_base_2.c
+ M /trunk/minmax.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfi.c
+ M /trunk/mpfi.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pi.c
+ M /trunk/pow.c
+ M /trunk/pow_si.c
+ M /trunk/pow_ui.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/rnd_mode.c
+ M /trunk/round.c
+ M /trunk/save_expo.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_f.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sqrtrem.c
+ M /trunk/srandom.h
+ M /trunk/sub.c
+ M /trunk/sub1.c
+ M /trunk/sub_ui.c
+ M /trunk/swap.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tasin.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatan.c
+ M /trunk/tests/tatanh.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/teuler.c
+ M /trunk/tests/texceptions.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/texpm1.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tfma.c
+ M /trunk/tests/tgamma.c
+ M /trunk/tests/tgeneric.c
+ M /trunk/tests/tget_d.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/thypot.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog1p.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tlog_base_10.c
+ M /trunk/tests/tlog_base_2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpi.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tpow3.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tround.c
+ M /trunk/tests/tset.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_pow.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+ M /trunk/trunc.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/zeta.c
+
+changed Library GPL to Lesser GPL
+
+------------------------------------------------------------------------
+r1535 | zimmerma | 2001-11-16 12:31:12 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/COPYING.LIB
+
+GNU Lesser General Public License, version 2.1
+
+------------------------------------------------------------------------
+r1534 | daney | 2001-11-16 12:30:42 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/ui_pow.c
+
+remove limits.h math.h
+
+------------------------------------------------------------------------
+r1533 | zimmerma | 2001-11-16 12:27:02 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/replace_all
+
+now treats all *.h
+
+------------------------------------------------------------------------
+r1532 | daney | 2001-11-16 12:25:25 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+remove the proto, remove math.h
+
+------------------------------------------------------------------------
+r1531 | zimmerma | 2001-11-16 12:21:07 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+removed DEBUG's
+
+------------------------------------------------------------------------
+r1530 | zimmerma | 2001-11-16 12:19:39 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+removed old patch for GMP 2.xx
+
+------------------------------------------------------------------------
+r1529 | zimmerma | 2001-11-16 12:17:56 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/eq.c
+ M /trunk/swap.c
+ M /trunk/urandomb.c
+
+GNU MP -> MPFR
+
+------------------------------------------------------------------------
+r1528 | zimmerma | 2001-11-16 12:08:08 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/add_ulp.c
+
+added year 2001 in copyright line
+
+------------------------------------------------------------------------
+r1527 | zimmerma | 2001-11-16 11:18:52 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/thyperbolic.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpi.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+
+added year 2001 in copyright line
+
+------------------------------------------------------------------------
+r1526 | zimmerma | 2001-11-16 11:18:00 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/cmp.c
+ M /trunk/cmp_abs.c
+ M /trunk/cmp_ui.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/dump.c
+ M /trunk/exp3.c
+ M /trunk/exp_2.c
+ M /trunk/get_str.c
+ M /trunk/init.c
+ M /trunk/inp_str.c
+ M /trunk/log.c
+ M /trunk/log2.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr-test.h
+ M /trunk/mpfr.h
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_ui.c
+ M /trunk/out_str.c
+ M /trunk/pow_ui.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/round.c
+ M /trunk/save_expo.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_f.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_str.c
+ M /trunk/set_z.c
+ M /trunk/sqrtrem.c
+ M /trunk/sub_ui.c
+ M /trunk/trunc.c
+ M /trunk/ui_div.c
+ M /trunk/ui_pow_ui.c
+ M /trunk/ui_sub.c
+
+added year 2001 in copyright line
+removed #if __STDC__
+
+------------------------------------------------------------------------
+r1525 | zimmerma | 2001-11-16 11:15:29 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ D /trunk/sin_cos.c
+
+now two separate files cos.c and sin.c
+
+------------------------------------------------------------------------
+r1524 | zimmerma | 2001-11-16 10:43:04 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/clear.c
+ M /trunk/pi.c
+ M /trunk/urandomb.c
+
+added year 2001 in copyright line
+
+------------------------------------------------------------------------
+r1523 | zimmerma | 2001-11-16 10:38:25 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+
+updated
+
+------------------------------------------------------------------------
+r1522 | zimmerma | 2001-11-16 10:26:46 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ D /trunk/div2.c
+
+old version, removed
+
+------------------------------------------------------------------------
+r1521 | zimmerma | 2001-11-16 10:16:37 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added isinf and isnum (split from isnan)
+
+------------------------------------------------------------------------
+r1520 | zimmerma | 2001-11-16 10:16:21 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/isinf.c
+ A /trunk/isnum.c
+
+new files (split from isnan.c)
+
+------------------------------------------------------------------------
+r1519 | zimmerma | 2001-11-16 10:14:44 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/asinh.c
+ M /trunk/atanh.c
+ M /trunk/copysign.c
+ M /trunk/cosh.c
+
+removed prototype already in mpfr.h
+
+------------------------------------------------------------------------
+r1518 | zimmerma | 2001-11-16 10:14:27 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+translated french comments to english
+
+------------------------------------------------------------------------
+r1517 | zimmerma | 2001-11-16 10:14:08 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added mpfr_sub
+
+------------------------------------------------------------------------
+r1516 | zimmerma | 2001-11-16 10:13:12 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/atan.c
+ M /trunk/cos.c
+ M /trunk/exp_2.c
+
+added static to local functions
+
+------------------------------------------------------------------------
+r1515 | zimmerma | 2001-11-16 10:12:42 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp2.c
+
+1 -> MP_LIMB_T_ONE
+
+------------------------------------------------------------------------
+r1514 | zimmerma | 2001-11-16 10:11:20 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/div_ui.c
+
+1 -> BITS_PER_MP_LIMB
+
+------------------------------------------------------------------------
+r1513 | zimmerma | 2001-11-16 10:10:48 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/euler.c
+
+added static to local functions
+removed prototype already in mpfr.h
+
+------------------------------------------------------------------------
+r1512 | zimmerma | 2001-11-16 10:10:29 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+removed mpfr_exp2_si (not used)
+
+------------------------------------------------------------------------
+r1511 | zimmerma | 2001-11-16 10:10:07 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/exp3.c
+
+added static to local functions
+translated french comments to english
+
+------------------------------------------------------------------------
+r1510 | zimmerma | 2001-11-16 10:09:29 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/expm1.c
+ M /trunk/log1p.c
+
+translated french comments to english
+removed prototype already in mpfr.h
+
+------------------------------------------------------------------------
+r1509 | zimmerma | 2001-11-16 10:09:09 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/factorial.c
+
+initialized inexact to 0
+
+------------------------------------------------------------------------
+r1508 | zimmerma | 2001-11-16 10:08:47 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/generic.c
+
+used TMP_ALLOC
+translated french comments to english
+
+------------------------------------------------------------------------
+r1507 | zimmerma | 2001-11-16 10:08:18 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+simplified test
+
+------------------------------------------------------------------------
+r1506 | zimmerma | 2001-11-16 10:08:04 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/isnan.c
+
+moved inf_p and number_p to different files
+
+------------------------------------------------------------------------
+r1505 | zimmerma | 2001-11-16 10:06:38 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/log2.c
+
+added static to local functions
+explained threshold
+
+------------------------------------------------------------------------
+r1504 | zimmerma | 2001-11-16 10:06:03 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/minmax.c
+
+removed prototypes already in mpfr.h
+
+------------------------------------------------------------------------
+r1503 | zimmerma | 2001-11-16 10:05:45 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+does not include stdio.h any more
+
+------------------------------------------------------------------------
+r1502 | zimmerma | 2001-11-16 10:05:01 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpz_set_fr.c
+
+added stdio.h
+
+------------------------------------------------------------------------
+r1501 | zimmerma | 2001-11-16 10:04:07 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/add_ulp.c
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/print_raw.c
+ M /trunk/round.c
+ M /trunk/set_z.c
+ M /trunk/sqrt.c
+ M /trunk/trunc.c
+
+1 -> BITS_PER_MP_LIMB
+1 << (BITS_PER_MP_LIMB - 1) -> MP_LIMB_T_HIGHBIT
+
+------------------------------------------------------------------------
+r1500 | zimmerma | 2001-11-16 09:40:02 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/out_str.c
+ M /trunk/reldiff.c
+
+removed french comment
+
+------------------------------------------------------------------------
+r1499 | zimmerma | 2001-11-16 09:39:45 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/pi.c
+
+added static to local functions
+
+------------------------------------------------------------------------
+r1498 | zimmerma | 2001-11-16 09:39:26 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/pow_si.c
+ M /trunk/sinh.c
+ M /trunk/tanh.c
+
+removed prototype already in mpfr.h
+
+------------------------------------------------------------------------
+r1497 | zimmerma | 2001-11-16 09:39:11 +0000 (Fri, 16 Nov 2001) | 4 lines
+Changed paths:
+ M /trunk/print_raw.c
+
+1 -> BITS_PER_MP_LIMB
+translated french comments to english
+added static to local functions
+
+------------------------------------------------------------------------
+r1496 | zimmerma | 2001-11-16 09:38:47 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/set_z.c
+ M /trunk/sqrt.c
+ M /trunk/sub1.c
+ M /trunk/trunc.c
+
+1 -> BITS_PER_MP_LIMB
+
+------------------------------------------------------------------------
+r1495 | zimmerma | 2001-11-16 09:37:52 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/round.c
+
+1 -> BITS_PER_MP_LIMB
+translated french comments to english
+
+------------------------------------------------------------------------
+r1494 | zimmerma | 2001-11-16 09:37:15 +0000 (Fri, 16 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/set_d.c
+ M /trunk/sqrtrem.c
+
+1 -> BITS_PER_MP_LIMB
+added static to local functions
+
+------------------------------------------------------------------------
+r1493 | zimmerma | 2001-11-16 09:33:57 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/ui_pow.c
+
+removed proto already in mpfr.h
+
+------------------------------------------------------------------------
+r1492 | zimmerma | 2001-11-16 09:33:33 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/urandomb.c
+
+1 -> MP_LIMB_T_ONE
+
+------------------------------------------------------------------------
+r1491 | zimmerma | 2001-11-16 09:32:45 +0000 (Fri, 16 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teuler.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tpi.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+
+added stdio.h
+
+------------------------------------------------------------------------
+r1490 | vlefevre | 2001-11-15 18:11:07 +0000 (Thu, 15 Nov 2001) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/add.c
+ A /trunk/add1.c
+ M /trunk/sub.c
+ A /trunk/sub1.c
+
+add.c -> add.c & add1.c
+sub.c -> sub.c & sub1.c + some changes.
+
+------------------------------------------------------------------------
+r1489 | zimmerma | 2001-11-13 09:33:07 +0000 (Tue, 13 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+iff the results are exact -> iff the result is exact
+
+------------------------------------------------------------------------
+r1488 | vlefevre | 2001-11-10 01:45:36 +0000 (Sat, 10 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/cmp.c
+ M /trunk/cmp_abs.c
+ M /trunk/exceptions.c
+ M /trunk/neg.c
+ M /trunk/round.c
+ M /trunk/save_expo.c
+ M /trunk/set.c
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+
+GNU coding style. K&R function headers removed.
+
+------------------------------------------------------------------------
+r1487 | vlefevre | 2001-11-10 00:47:44 +0000 (Sat, 10 Nov 2001) | 5 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+MP_LIMB_T_ONE defined.
+mp_size_unsigned_t defined.
+Important bugs fixed (in particular when int has fewer than 32 bits).
+Still unavoidable possible bugs due to the fact that mp_size_t is signed.
+
+------------------------------------------------------------------------
+r1486 | daney | 2001-11-09 11:24:05 +0000 (Fri, 09 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tgamma.c
+
+add tests file for gamma
+
+------------------------------------------------------------------------
+r1485 | daney | 2001-11-09 11:23:33 +0000 (Fri, 09 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/gammaPiAGMformula.c
+
+add gamma function an other version
+
+------------------------------------------------------------------------
+r1484 | daney | 2001-11-09 11:23:04 +0000 (Fri, 09 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/gamma.c
+
+add gamma function
+
+------------------------------------------------------------------------
+r1483 | zimmerma | 2001-11-09 06:24:52 +0000 (Fri, 09 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mis a` jour valeur de retour de mpfr_tan
+
+------------------------------------------------------------------------
+r1482 | vlefevre | 2001-11-09 01:38:45 +0000 (Fri, 09 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+Some -'s missing in floating-point.
+
+------------------------------------------------------------------------
+r1481 | zimmerma | 2001-11-08 23:15:59 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+modifs suite aux remarques de Nathalie
+
+------------------------------------------------------------------------
+r1480 | daney | 2001-11-08 17:48:33 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+remove some name of variables
+
+------------------------------------------------------------------------
+r1479 | vlefevre | 2001-11-08 17:14:01 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp2.c
+ D /trunk/pow2.c
+
+cmp2.c: Integer overflows checked.
+
+------------------------------------------------------------------------
+r1478 | vlefevre | 2001-11-08 17:11:36 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/isinteger.c
+ M /trunk/mpfr.h
+ M /trunk/pow.c
+
+Update.
+
+------------------------------------------------------------------------
+r1477 | vlefevre | 2001-11-08 16:42:30 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Fix.
+
+------------------------------------------------------------------------
+r1476 | daney | 2001-11-08 16:37:47 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+suppress variable name in dim min max
+
+------------------------------------------------------------------------
+r1475 | daney | 2001-11-08 16:23:29 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/isinteger.c
+
+export isinteger in the file isinteger.c
+
+------------------------------------------------------------------------
+r1474 | daney | 2001-11-08 16:21:56 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/pow_si.c
+
+exporte pow_si from pow2.c to pow_si.c
+
+------------------------------------------------------------------------
+r1473 | daney | 2001-11-08 16:21:06 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+rename pow2.c in pow.c (source for mpfr_pow)
+
+------------------------------------------------------------------------
+r1472 | daney | 2001-11-08 16:19:49 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/ui_pow_ui.c
+
+add ui_pow_ui.c (initially in pow.c)
+
+------------------------------------------------------------------------
+r1471 | daney | 2001-11-08 16:19:18 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ A /trunk/pow_ui.c
+
+add pow_ui.c file (initially in pow.c)
+
+------------------------------------------------------------------------
+r1470 | vlefevre | 2001-11-08 15:56:09 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp2.c
+ M /trunk/mpfr-impl.h
+
+mpfr_cmp2: return type changed to mp_prec_t.
+
+------------------------------------------------------------------------
+r1469 | daney | 2001-11-08 14:53:54 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+add function test4 for 3 input test + fma tests
+
+------------------------------------------------------------------------
+r1468 | vlefevre | 2001-11-08 03:04:00 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Macros added.
+
+------------------------------------------------------------------------
+r1467 | vlefevre | 2001-11-08 02:15:36 +0000 (Thu, 08 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+MP_LIMB_T_MAX instead of (mp_limb_t) -1 (a little nicer...).
+
+------------------------------------------------------------------------
+r1466 | vlefevre | 2001-11-06 17:05:41 +0000 (Tue, 06 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Code clean-up.
+
+------------------------------------------------------------------------
+r1465 | vlefevre | 2001-11-05 15:44:24 +0000 (Mon, 05 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/exceptions.c
+
+Prototypes for K&R C.
+
+------------------------------------------------------------------------
+r1464 | vlefevre | 2001-11-05 09:58:14 +0000 (Mon, 05 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+mpfr_round_raw_generic prototype fixed.
+
+------------------------------------------------------------------------
+r1463 | daney | 2001-11-01 14:15:23 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/asin.c
+
+clear xp for Nan Inf or 0 are returned
+
+------------------------------------------------------------------------
+r1462 | daney | 2001-11-01 14:11:48 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+clear variable if an error is return
+
+------------------------------------------------------------------------
+r1461 | daney | 2001-11-01 14:10:50 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/atanh.c
+
+clear x for Nan inf 0 return
+
+------------------------------------------------------------------------
+r1460 | daney | 2001-11-01 14:10:10 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/asinh.c
+
+clear x for Nan Inf 0 return
+
+------------------------------------------------------------------------
+r1459 | daney | 2001-11-01 14:05:15 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/expm1.c
+
+clear te
+
+------------------------------------------------------------------------
+r1458 | vlefevre | 2001-11-01 12:20:32 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+Added prototype.
+
+------------------------------------------------------------------------
+r1457 | vlefevre | 2001-11-01 11:53:58 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Bug fixed.
+
+------------------------------------------------------------------------
+r1456 | zimmerma | 2001-11-01 10:05:27 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+fixed MLK's
+
+------------------------------------------------------------------------
+r1455 | zimmerma | 2001-11-01 09:44:03 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/pow2.c
+
+fixed MLK's in mpfr_isinteger
+
+------------------------------------------------------------------------
+r1454 | zimmerma | 2001-11-01 09:43:32 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow3.c
+
+fixed MLK's
+
+------------------------------------------------------------------------
+r1453 | zimmerma | 2001-11-01 09:04:19 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_pow.c
+
+fixed missing mpfr_clear's
+
+------------------------------------------------------------------------
+r1452 | zimmerma | 2001-11-01 08:02:00 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+
+added missing mpfr_clear
+
+------------------------------------------------------------------------
+r1451 | zimmerma | 2001-11-01 07:20:30 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+added clear's in bug_ddefour
+
+------------------------------------------------------------------------
+r1450 | zimmerma | 2001-11-01 00:42:47 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+added mpfr_clear's
+
+------------------------------------------------------------------------
+r1449 | zimmerma | 2001-11-01 00:10:46 +0000 (Thu, 01 Nov 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+fixed MLK's
+
+------------------------------------------------------------------------
+r1448 | zimmerma | 2001-10-31 23:12:41 +0000 (Wed, 31 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+fixed MLK for Inf or Nan
+
+------------------------------------------------------------------------
+r1447 | zimmerma | 2001-10-31 22:52:06 +0000 (Wed, 31 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+fixed MLK in check_case_2
+
+------------------------------------------------------------------------
+r1446 | daney | 2001-10-31 10:16:21 +0000 (Wed, 31 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+rename factorial -> fac_ui
+
+------------------------------------------------------------------------
+r1445 | rouillie | 2001-10-30 15:26:27 +0000 (Tue, 30 Oct 2001) | 4 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/gmp_op.c
+ M /trunk/mpfr.h
+ M /trunk/tests/Makefile.in
+
+Change mpfr_<op>_mpz to mpfr_<op>_z
+Change mpfr_<op>_mpq to mpfr_<op>_q
+where <op> is mul,div,add,sub
+
+------------------------------------------------------------------------
+r1444 | daney | 2001-10-30 10:30:48 +0000 (Tue, 30 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/factorial.c
+
+correct factorial -> fac_ui in comments
+
+------------------------------------------------------------------------
+r1443 | daney | 2001-10-30 10:24:08 +0000 (Tue, 30 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tfactorial.c
+
+rename tfactorial -> fac_ui
+
+------------------------------------------------------------------------
+r1442 | daney | 2001-10-30 10:23:25 +0000 (Tue, 30 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/factorial.c
+ M /trunk/mpfr.h
+
+rename factorial -> fac_ui
+
+------------------------------------------------------------------------
+r1441 | vlefevre | 2001-10-27 11:16:02 +0000 (Sat, 27 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Bug fixed.
+
+------------------------------------------------------------------------
+r1440 | zimmerma | 2001-10-26 16:01:03 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tsub_ui.c
+
+drand -> drand48
+
+------------------------------------------------------------------------
+r1439 | zimmerma | 2001-10-26 15:49:21 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+put MAX_PREC back to 100
+
+------------------------------------------------------------------------
+r1438 | zimmerma | 2001-10-26 15:46:37 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+added test for inexact flag
+
+------------------------------------------------------------------------
+r1437 | zimmerma | 2001-10-26 15:45:42 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+use MPFR_RET_NAN and MPFR_RET
+
+------------------------------------------------------------------------
+r1436 | zimmerma | 2001-10-26 15:42:23 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+removed MPFR_DEBUG_LEVEL definition
+
+------------------------------------------------------------------------
+r1435 | zimmerma | 2001-10-26 15:39:21 +0000 (Fri, 26 Oct 2001) | 5 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+mpfr_set_q and mpfr_abs now return an int
+mpfr_pow_ui and mpfr_ui_pow_ui now implement exact rounding
+updated the documentation of the mpfr_*pow* functions
+removed some internal functions
+
+------------------------------------------------------------------------
+r1434 | zimmerma | 2001-10-26 15:32:23 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+implemented exact rounding (but no ternary flag)
+
+------------------------------------------------------------------------
+r1433 | daney | 2001-10-26 15:31:42 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+add some flags
+
+------------------------------------------------------------------------
+r1432 | daney | 2001-10-26 15:29:28 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+mixed version beetwen DD and Pau => (gestion des flag inexacte dirige)
+
+------------------------------------------------------------------------
+r1431 | daney | 2001-10-26 15:28:31 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+rien
+
+------------------------------------------------------------------------
+r1430 | zimmerma | 2001-10-26 13:48:33 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+MAX_PREC included
+
+------------------------------------------------------------------------
+r1429 | zimmerma | 2001-10-26 13:31:55 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set_q.c
+
+implemented inexact flag
+
+------------------------------------------------------------------------
+r1428 | hanrot | 2001-10-26 13:28:00 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+Clearing high part of rem2.
+
+------------------------------------------------------------------------
+r1427 | rouillie | 2001-10-26 13:24:02 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+adds gmp_op.c
+
+------------------------------------------------------------------------
+r1426 | zimmerma | 2001-10-26 13:23:12 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr_set_q now returns an int
+
+------------------------------------------------------------------------
+r1425 | zimmerma | 2001-10-26 13:22:22 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_q.c
+
+added test for inexact flag
+
+------------------------------------------------------------------------
+r1424 | rouillie | 2001-10-26 13:19:40 +0000 (Fri, 26 Oct 2001) | 3 lines
+Changed paths:
+ A /trunk/gmp_op.c
+
+Adds the file gmp_op.c containing the implementations of operations between
+mpfr and mpz/mpq data
+
+------------------------------------------------------------------------
+r1423 | daney | 2001-10-26 13:05:58 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+err <0 => is now tester
+
+------------------------------------------------------------------------
+r1422 | hanrot | 2001-10-26 13:00:54 +0000 (Fri, 26 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+Patch for bits shifted out when the high word of the quotient is nonzero.
+Induced error on inexact flag (and hence on rounding in some cases).
+
+------------------------------------------------------------------------
+r1421 | daney | 2001-10-26 12:46:30 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/copysign.c
+
+add copysign.c
+
+------------------------------------------------------------------------
+r1420 | zimmerma | 2001-10-26 12:41:45 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added one test
+
+------------------------------------------------------------------------
+r1419 | daney | 2001-10-26 12:37:43 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/dim.c
+
+simplify dim
+
+------------------------------------------------------------------------
+r1418 | daney | 2001-10-26 12:32:57 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/thypot.c
+
+add exact flag
+
+------------------------------------------------------------------------
+r1417 | daney | 2001-10-26 12:24:00 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/log_base_10.c
+ M /trunk/log_base_2.c
+ M /trunk/pow2.c
+
+err => long int
+
+------------------------------------------------------------------------
+r1416 | zimmerma | 2001-10-26 12:22:28 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset.c
+
+added one test
+
+------------------------------------------------------------------------
+r1415 | zimmerma | 2001-10-26 12:21:46 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log1p.c
+
+cosmetic changes
+
+------------------------------------------------------------------------
+r1414 | zimmerma | 2001-10-26 12:21:08 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+can_round return 0 for b=0
+
+------------------------------------------------------------------------
+r1413 | daney | 2001-10-26 12:17:06 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+add thypot
+
+------------------------------------------------------------------------
+r1412 | daney | 2001-10-26 11:51:19 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+add coopysign
+
+------------------------------------------------------------------------
+r1411 | daney | 2001-10-26 11:50:27 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+add copysign
+
+------------------------------------------------------------------------
+r1410 | daney | 2001-10-26 11:47:46 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/expm1.c
+
+correct mp_prec_t err => long int
+
+------------------------------------------------------------------------
+r1409 | daney | 2001-10-26 11:47:09 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log1p.c
+
+correst mp_prec_t err => long int
+
+------------------------------------------------------------------------
+r1408 | rouillie | 2001-10-26 11:34:26 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+Add multiplication/division/addition/substraction by mpz and mpq
+
+------------------------------------------------------------------------
+r1407 | zimmerma | 2001-10-26 10:56:14 +0000 (Fri, 26 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added two tests
+fixed bug in generic tests (one more bit is needed to get an exact result)
+
+------------------------------------------------------------------------
+r1406 | zimmerma | 2001-10-26 10:55:36 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+fixed pb with exact results not detected (ck was < 0)
+
+------------------------------------------------------------------------
+r1405 | hanrot | 2001-10-26 09:12:13 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+Rien.
+
+------------------------------------------------------------------------
+r1404 | hanrot | 2001-10-26 09:11:07 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+Patch for the computation of the u_lo + r part of the remainder when u_lo = 0.
+
+------------------------------------------------------------------------
+r1403 | zimmerma | 2001-10-26 08:43:09 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tsub.c
+ M /trunk/tests/tui_div.c
+
+added test for inexact flag
+
+------------------------------------------------------------------------
+r1402 | zimmerma | 2001-10-26 08:41:29 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed pbs with inexact flag
+
+------------------------------------------------------------------------
+r1401 | zimmerma | 2001-10-26 08:41:05 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+now mpfr_div and mpfr_ui_div return an int
+
+------------------------------------------------------------------------
+r1400 | zimmerma | 2001-10-26 08:40:13 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/ui_div.c
+
+implemented ternary flag in mpfr_ui_div
+
+------------------------------------------------------------------------
+r1399 | zimmerma | 2001-10-26 08:39:28 +0000 (Fri, 26 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/log_base_2.c
+
+removed unnecessary CLEAR_FLAGS
+used MPFR_RET_NAN
+
+------------------------------------------------------------------------
+r1398 | zimmerma | 2001-10-26 08:38:58 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog_base_2.c
+
+reduced number of tests
+
+------------------------------------------------------------------------
+r1397 | zimmerma | 2001-10-26 08:31:58 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log_base_10.c
+
+removed unnecessary CLEAR_FLAGS
+
+------------------------------------------------------------------------
+r1396 | zimmerma | 2001-10-26 08:30:00 +0000 (Fri, 26 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+improved mpfr_compare
+fixed wrong function name for mpfr_log2
+
+------------------------------------------------------------------------
+r1395 | zimmerma | 2001-10-26 08:23:51 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+rewritten to implement ternary inexact flag
+
+------------------------------------------------------------------------
+r1394 | zimmerma | 2001-10-26 08:15:24 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+fixed generic test (pb with double rounding)
+
+------------------------------------------------------------------------
+r1393 | zimmerma | 2001-10-26 07:46:30 +0000 (Fri, 26 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+increased MAX_PREC
+
+------------------------------------------------------------------------
+r1392 | hanrot | 2001-10-25 22:03:55 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+
+Changed the type of err from mp_prec_t (unsigned) to int.
+
+------------------------------------------------------------------------
+r1391 | hanrot | 2001-10-25 21:32:42 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.in
+ M /trunk/tests/tdiv.c
+
+Added tests for inexact flag.
+
+------------------------------------------------------------------------
+r1390 | hanrot | 2001-10-25 21:32:33 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/algorithms.tex
+ M /trunk/configure
+ M /trunk/div.c
+
+Patch for even rounding.
+
+------------------------------------------------------------------------
+r1389 | daney | 2001-10-25 17:12:26 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log_base_2.c
+
+rien
+
+------------------------------------------------------------------------
+r1388 | daney | 2001-10-25 17:05:29 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log_base_10.c
+
+rien
+
+------------------------------------------------------------------------
+r1387 | vlefevre | 2001-10-25 17:00:10 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+Warning avoided.
+
+------------------------------------------------------------------------
+r1386 | zimmerma | 2001-10-25 17:00:06 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added tfma
+
+------------------------------------------------------------------------
+r1385 | zimmerma | 2001-10-25 16:53:36 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tfma.c
+
+slong -> t
+
+------------------------------------------------------------------------
+r1384 | zimmerma | 2001-10-25 16:53:05 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+nouvelew version (without loop)
+
+------------------------------------------------------------------------
+r1383 | daney | 2001-10-25 16:51:56 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/pow2.c
+
+rien
+
+------------------------------------------------------------------------
+r1382 | daney | 2001-10-25 16:50:31 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/pow2.c
+ M /trunk/tests/reuse.c
+
+rien
+
+------------------------------------------------------------------------
+r1381 | daney | 2001-10-25 16:45:27 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+change
+
+------------------------------------------------------------------------
+r1380 | vlefevre | 2001-10-25 16:45:20 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Bug fixed.
+
+------------------------------------------------------------------------
+r1379 | daney | 2001-10-25 16:34:55 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/pow2.c
+
+correct bugs with reuse
+
+------------------------------------------------------------------------
+r1378 | daney | 2001-10-25 16:34:05 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+test for log2 log10 pow
+
+------------------------------------------------------------------------
+r1377 | hanrot | 2001-10-25 16:29:46 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/mpfr.h
+
+La division nouvelle est arrivee.
+
+------------------------------------------------------------------------
+r1376 | zimmerma | 2001-10-25 16:04:18 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+ajoute' nouveau test
+
+------------------------------------------------------------------------
+r1375 | vlefevre | 2001-10-25 15:34:17 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Bug fixed.
+
+------------------------------------------------------------------------
+r1374 | hanrot | 2001-10-25 15:26:36 +0000 (Thu, 25 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/round.c
+
+round_raw, round_raw2 -> round_raw_generic. Macros to simulate previous
+behaviour. Even rounding returns +- MPFR_EVEN_INEX.
+
+------------------------------------------------------------------------
+r1373 | zimmerma | 2001-10-25 15:24:11 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log_base_10.c
+
+fixed pb with mpfr_log10(a, a) with a=-Inf
+
+------------------------------------------------------------------------
+r1372 | zimmerma | 2001-10-25 15:14:01 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added two tests
+
+------------------------------------------------------------------------
+r1371 | zimmerma | 2001-10-25 15:06:12 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+
+added one test
+
+------------------------------------------------------------------------
+r1370 | daney | 2001-10-25 15:03:13 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+add log2 and log10
+
+------------------------------------------------------------------------
+r1369 | daney | 2001-10-25 15:02:59 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log_base_10.c
+
+correction for reuse
+
+------------------------------------------------------------------------
+r1368 | daney | 2001-10-25 15:02:45 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log_base_2.c
+
+coorection for reuse
+
+------------------------------------------------------------------------
+r1367 | zimmerma | 2001-10-25 14:53:19 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/texceptions.c
+
+test file for testing exceptions
+
+------------------------------------------------------------------------
+r1366 | vlefevre | 2001-10-25 14:32:20 +0000 (Thu, 25 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/add.c
+
+mpfr_add1 completely rewritten. Overflows are checked.
+The ternary value should now be supported (but it hasn't been tested yet).
+
+------------------------------------------------------------------------
+r1365 | daney | 2001-10-25 14:04:09 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/fma.c
+
+new version
+
+------------------------------------------------------------------------
+r1364 | zimmerma | 2001-10-25 13:54:46 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+added one test
+
+------------------------------------------------------------------------
+r1363 | zimmerma | 2001-10-25 13:54:27 +0000 (Thu, 25 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/tests/tgeneric.c
+
+add possibility to define a random function (default is mpfr_random)
+to get random variables in specific ranges
+
+------------------------------------------------------------------------
+r1362 | zimmerma | 2001-10-25 13:53:19 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tacosh.c
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatanh.c
+
+now use tgeneric.c
+
+------------------------------------------------------------------------
+r1361 | zimmerma | 2001-10-25 13:50:49 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added texceptions
+
+------------------------------------------------------------------------
+r1360 | zimmerma | 2001-10-25 13:49:56 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+documented exception mechanism (with Vincent Lefe`vre)
+
+------------------------------------------------------------------------
+r1359 | zimmerma | 2001-10-25 13:48:28 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tfactorial.c
+
+changed stupid test (was computing only 200!)
+
+------------------------------------------------------------------------
+r1358 | zimmerma | 2001-10-25 13:47:27 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/factorial.c
+
+implemented inexact flag
+
+------------------------------------------------------------------------
+r1357 | zimmerma | 2001-10-25 13:45:42 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/exceptions.c
+
+1999 -> 2001
+
+------------------------------------------------------------------------
+r1356 | zimmerma | 2001-10-25 13:45:14 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+check overflow
+
+------------------------------------------------------------------------
+r1355 | zimmerma | 2001-10-25 13:39:35 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_sub.c
+
+added two tests
+
+------------------------------------------------------------------------
+r1354 | zimmerma | 2001-10-25 13:37:24 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+implemented overflow/underflow
+
+------------------------------------------------------------------------
+r1353 | daney | 2001-10-25 13:36:56 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/atanh.c
+
+correct atanh(INF)=INF exact
+
+------------------------------------------------------------------------
+r1352 | daney | 2001-10-25 13:14:54 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+correct test inf for atanh
+
+------------------------------------------------------------------------
+r1351 | zimmerma | 2001-10-25 12:52:08 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added warning for mpfr_set_d
+
+------------------------------------------------------------------------
+r1350 | daney | 2001-10-25 09:19:06 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+correct bug in tests file (test of atanh for + or - Inf)
+
+------------------------------------------------------------------------
+r1349 | zimmerma | 2001-10-25 08:37:39 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added tadd_ui (forgotten?)
+
+------------------------------------------------------------------------
+r1348 | zimmerma | 2001-10-25 08:37:19 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd_ui.c
+
+added special test
+
+------------------------------------------------------------------------
+r1347 | zimmerma | 2001-10-25 08:36:55 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+fixed bug in rounding part when rounding towards 0 (infinite loop due to bn<an)
+
+------------------------------------------------------------------------
+r1346 | zimmerma | 2001-10-25 08:34:51 +0000 (Thu, 25 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tasinh.c
+
+added one special test
+
+------------------------------------------------------------------------
+r1345 | daney | 2001-10-24 17:33:12 +0000 (Wed, 24 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/minmax.c
+
+correct the Nan case
+
+------------------------------------------------------------------------
+r1344 | daney | 2001-10-24 17:23:08 +0000 (Wed, 24 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/dim.c
+
+add the function mpfr_dim
+
+------------------------------------------------------------------------
+r1343 | daney | 2001-10-24 17:22:36 +0000 (Wed, 24 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/minmax.c
+
+add function mpfr_min and mpfr_max
+
+------------------------------------------------------------------------
+r1342 | daney | 2001-10-24 16:12:27 +0000 (Wed, 24 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tasinh.c
+ M /trunk/tests/tatanh.c
+
+correct these tesats files
+
+------------------------------------------------------------------------
+r1341 | daney | 2001-10-24 16:11:23 +0000 (Wed, 24 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/asinh.c
+ M /trunk/atanh.c
+ M /trunk/cosh.c
+ M /trunk/sinh.c
+ M /trunk/tanh.c
+
+correct some bugs
+
+------------------------------------------------------------------------
+r1340 | zimmerma | 2001-10-24 15:47:48 +0000 (Wed, 24 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added EXTRA_DIST= tgeneric.c
+
+------------------------------------------------------------------------
+r1339 | daney | 2001-10-24 15:32:28 +0000 (Wed, 24 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+remove tfma
+
+------------------------------------------------------------------------
+r1338 | daney | 2001-10-24 15:29:56 +0000 (Wed, 24 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tfma.c
+
+add tfma
+
+------------------------------------------------------------------------
+r1337 | daney | 2001-10-24 09:34:27 +0000 (Wed, 24 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+
+acosh revue et corrige...+beau
+
+------------------------------------------------------------------------
+r1336 | daney | 2001-10-23 16:57:30 +0000 (Tue, 23 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+add mpfr_log10
+
+------------------------------------------------------------------------
+r1335 | daney | 2001-10-23 16:56:22 +0000 (Tue, 23 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ A /trunk/log_base_10.c
+
+add log_base_10
+
+------------------------------------------------------------------------
+r1334 | daney | 2001-10-23 16:55:58 +0000 (Tue, 23 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+add tlog_base_10
+
+------------------------------------------------------------------------
+r1333 | daney | 2001-10-23 16:55:25 +0000 (Tue, 23 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tlog_base_10.c
+
+add test file for log_base_10 function
+
+------------------------------------------------------------------------
+r1332 | daney | 2001-10-23 16:54:12 +0000 (Tue, 23 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+correct a bug in mpfr_log10 section
+
+------------------------------------------------------------------------
+r1331 | daney | 2001-10-23 13:14:13 +0000 (Tue, 23 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+add help of log10 + fma
+
+------------------------------------------------------------------------
+r1330 | daney | 2001-10-23 12:38:15 +0000 (Tue, 23 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log_base_2.c
+
+correct particular cases
+
+------------------------------------------------------------------------
+r1329 | daney | 2001-10-23 12:33:00 +0000 (Tue, 23 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/log_base_2.c
+
+improve the clear flags
+
+------------------------------------------------------------------------
+r1328 | daney | 2001-10-23 09:41:29 +0000 (Tue, 23 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow3.c
+
+correction dans l'entete
+
+------------------------------------------------------------------------
+r1327 | vlefevre | 2001-10-21 07:56:29 +0000 (Sun, 21 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tdiv.c
+
+Some changes to avoid warnings.
+
+------------------------------------------------------------------------
+r1326 | vlefevre | 2001-10-21 07:12:18 +0000 (Sun, 21 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+Bug fixed (char -> int).
+
+------------------------------------------------------------------------
+r1325 | vlefevre | 2001-10-19 20:47:39 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/tests/Makefile.in
+
+Update.
+
+------------------------------------------------------------------------
+r1324 | vlefevre | 2001-10-19 20:45:12 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add_ui.c
+ M /trunk/sub_ui.c
+
+Bugs fixed concerning the "inexact" ternary value.
+
+------------------------------------------------------------------------
+r1323 | daney | 2001-10-19 16:56:51 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+suppress thypot tgeneric
+
+------------------------------------------------------------------------
+r1322 | daney | 2001-10-19 16:53:12 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+suppress sample
+
+------------------------------------------------------------------------
+r1321 | zimmerma | 2001-10-19 16:26:47 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+void -> int as return value for mpfr_add_ui
+
+------------------------------------------------------------------------
+r1320 | zimmerma | 2001-10-19 16:26:19 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add_ui.c
+
+added ternary flag
+
+------------------------------------------------------------------------
+r1319 | zimmerma | 2001-10-19 16:24:50 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+void -> int for mpfr_add and mpfr_add_ui
+
+------------------------------------------------------------------------
+r1318 | daney | 2001-10-19 16:21:08 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/thypot.c
+
+add test for hypot
+
+------------------------------------------------------------------------
+r1317 | daney | 2001-10-19 16:15:16 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+add some test
+
+------------------------------------------------------------------------
+r1316 | daney | 2001-10-19 16:13:56 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+add some functions
+
+------------------------------------------------------------------------
+r1315 | daney | 2001-10-19 16:12:44 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+add some proto
+
+------------------------------------------------------------------------
+r1314 | daney | 2001-10-19 16:09:34 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tpow3.c
+
+add test file for pow
+
+------------------------------------------------------------------------
+r1313 | daney | 2001-10-19 16:09:01 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+add the help for pow and pow_si
+
+------------------------------------------------------------------------
+r1312 | daney | 2001-10-19 16:08:29 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/pow2.c
+
+add the function pow and pow_si
+
+------------------------------------------------------------------------
+r1311 | zimmerma | 2001-10-19 16:02:34 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+added two tests for 0-c and c-0 with prec(c) > prec(a)
+
+------------------------------------------------------------------------
+r1310 | vlefevre | 2001-10-19 15:53:17 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/neg.c
+
+Removed #include <stdio.h>, "return 0;" replaced by "MPFR_RET(0);".
+
+------------------------------------------------------------------------
+r1309 | vlefevre | 2001-10-19 15:45:18 +0000 (Fri, 19 Oct 2001) | 4 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/sub.c
+
+mpfr_add1 and mpfr_sub1 prototypes moved to mpfr-impl.h (to detect clashes).
+Bug fix concerning the inexact ternary value in mpfr_sub.
+mpfr_add now returns an int (inexact ternary value unsupported if true add).
+
+------------------------------------------------------------------------
+r1308 | vlefevre | 2001-10-19 14:49:44 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+
+Update.
+
+------------------------------------------------------------------------
+r1307 | vlefevre | 2001-10-19 14:13:10 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+Underflow/overflow check.
+
+------------------------------------------------------------------------
+r1306 | vlefevre | 2001-10-19 14:02:01 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Documentation updated.
+
+------------------------------------------------------------------------
+r1305 | vlefevre | 2001-10-19 13:57:06 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set_ui.c
+
+Comment added.
+
+------------------------------------------------------------------------
+r1304 | vlefevre | 2001-10-19 13:41:41 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+MPFR_RET(0) replaced by MPFR_RET_NAN.
+
+------------------------------------------------------------------------
+r1303 | vlefevre | 2001-10-19 13:28:41 +0000 (Fri, 19 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Macro MPFR_RET_NAN.
+
+------------------------------------------------------------------------
+r1302 | vlefevre | 2001-10-18 17:29:45 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Code clean-up in mpfr_round_raw (well... IMHO).
+
+------------------------------------------------------------------------
+r1301 | daney | 2001-10-18 15:30:04 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/ui_pow.c
+
+take in account of CHAR_BIT in ui_pow
+
+------------------------------------------------------------------------
+r1300 | zimmerma | 2001-10-18 15:21:45 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+cast to mp_limb_t was missing
+
+------------------------------------------------------------------------
+r1299 | vlefevre | 2001-10-18 15:05:45 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/acosh.c
+ M /trunk/asinh.c
+ M /trunk/atanh.c
+ M /trunk/factorial.c
+
+BITS_PER_CHAR replaced by the standard CHAR_BIT.
+
+------------------------------------------------------------------------
+r1298 | hanrot | 2001-10-18 14:58:14 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r1297 | daney | 2001-10-18 13:55:26 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tui_pow.c
+
+add test of ui_pow
+
+------------------------------------------------------------------------
+r1296 | daney | 2001-10-18 13:54:47 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+add the help of ui_pow
+
+------------------------------------------------------------------------
+r1295 | daney | 2001-10-18 13:54:21 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/ui_pow.c
+
+add the function pow(unsign long int, mpfr_t)
+
+------------------------------------------------------------------------
+r1294 | vlefevre | 2001-10-18 13:52:48 +0000 (Thu, 18 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/configure
+ M /trunk/configure.in
+
+Improved configure.in.
+configure generated by Autoconf 2.52.
+
+------------------------------------------------------------------------
+r1293 | daney | 2001-10-18 12:09:08 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+ajout du flag inexact
+
+------------------------------------------------------------------------
+r1292 | vlefevre | 2001-10-18 11:27:38 +0000 (Thu, 18 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/configure
+
+fixed and improved check for gmp.h/gmp-impl.h/config.h/gmp-mparam.h/longlong.h
+and corresponding error message
+
+------------------------------------------------------------------------
+r1291 | daney | 2001-10-18 10:38:10 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+add the help on log2
+
+------------------------------------------------------------------------
+r1290 | daney | 2001-10-18 10:36:00 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tlog_base_2.c
+
+add the test file of the log2 (log in base 2)
+
+------------------------------------------------------------------------
+r1289 | daney | 2001-10-18 10:35:11 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/log_base_2.c
+
+ajout de log2 (log en base 2)
+
+------------------------------------------------------------------------
+r1288 | daney | 2001-10-18 10:24:43 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tanh.c
+
+correst tanh(0)
+
+------------------------------------------------------------------------
+r1287 | zimmerma | 2001-10-18 10:20:41 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+added two more tests
+
+------------------------------------------------------------------------
+r1286 | zimmerma | 2001-10-18 10:20:09 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+wrong sign passed to mpfr_can_round (mp_limb_t may be unsigned)
+
+------------------------------------------------------------------------
+r1285 | daney | 2001-10-18 10:10:49 +0000 (Thu, 18 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sinh.c
+
+correct a bug for sinh(Inf)
+
+------------------------------------------------------------------------
+r1284 | daney | 2001-10-17 15:49:52 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tanh.c
+
+correct syntax of tanh.c
+
+------------------------------------------------------------------------
+r1283 | daney | 2001-10-17 15:47:03 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sinh.c
+
+correct an error
+
+------------------------------------------------------------------------
+r1282 | daney | 2001-10-17 15:42:10 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/cosh.c
+
+correct few things
+
+------------------------------------------------------------------------
+r1281 | daney | 2001-10-17 15:29:50 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/cosh.c
+
+little patch for cosh
+
+------------------------------------------------------------------------
+r1280 | daney | 2001-10-17 15:04:43 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/texpm1.c
+
+add the test function of expm1
+
+------------------------------------------------------------------------
+r1279 | daney | 2001-10-17 15:04:06 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tlog1p.c
+
+add the test of the function log1p
+
+------------------------------------------------------------------------
+r1278 | daney | 2001-10-17 15:03:04 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/expm1.c
+
+add the function expm1
+
+------------------------------------------------------------------------
+r1277 | daney | 2001-10-17 15:02:30 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/log1p.c
+
+add the function log1p
+
+------------------------------------------------------------------------
+r1276 | daney | 2001-10-17 12:50:15 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+add to mpfr.texi log1p and expm1
+
+------------------------------------------------------------------------
+r1275 | daney | 2001-10-17 12:37:46 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+actualisation de exp2.c
+
+------------------------------------------------------------------------
+r1274 | daney | 2001-10-17 12:36:51 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+actualisation de exp2
+
+------------------------------------------------------------------------
+r1273 | hanrot | 2001-10-17 10:28:27 +0000 (Wed, 17 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.in
+ M /trunk/tests/tdiv.c
+
+New tests in tdiv.c.
+
+------------------------------------------------------------------------
+r1272 | hanrot | 2001-10-17 10:28:14 +0000 (Wed, 17 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/div.c
+ A /trunk/div2.c
+
+New division in div.c, old one renamed in mpfr_div2. Remains to implement
+exact/inexact flag. Should not be *that* hard.
+
+------------------------------------------------------------------------
+r1271 | daney | 2001-10-16 16:02:21 +0000 (Tue, 16 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+ajout de functions pow, fma, hypot etc etc
+
+------------------------------------------------------------------------
+r1270 | zimmerma | 2001-10-16 15:48:48 +0000 (Tue, 16 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added fma.c
+
+------------------------------------------------------------------------
+r1269 | zimmerma | 2001-10-16 15:48:34 +0000 (Tue, 16 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototypes for mpfr_fma and mpfr_hypot
+
+------------------------------------------------------------------------
+r1268 | zimmerma | 2001-10-16 15:48:12 +0000 (Tue, 16 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/hypot.c
+
+small changes for inexact flag
+
+------------------------------------------------------------------------
+r1267 | zimmerma | 2001-10-16 15:41:38 +0000 (Tue, 16 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/fma.c
+
+added some cases for Inf
+implement (partly) inexact flag
+
+------------------------------------------------------------------------
+r1266 | daney | 2001-10-16 15:09:29 +0000 (Tue, 16 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/hypot.c
+
+ajout hypot
+
+------------------------------------------------------------------------
+r1265 | daney | 2001-10-16 15:06:29 +0000 (Tue, 16 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/fma.c
+
+ajout de fma
+
+------------------------------------------------------------------------
+r1264 | vlefevre | 2001-10-16 10:13:02 +0000 (Tue, 16 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+Comment: // --> /* ... */
+
+------------------------------------------------------------------------
+r1263 | zimmerma | 2001-10-15 14:19:10 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tgeneric.c
+
+generic test file
+
+------------------------------------------------------------------------
+r1262 | zimmerma | 2001-10-15 14:16:50 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+added cast to (void*) for new functions returning an int
+
+------------------------------------------------------------------------
+r1261 | zimmerma | 2001-10-15 14:16:25 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+
+added test for inexact flag
+
+------------------------------------------------------------------------
+r1260 | zimmerma | 2001-10-15 14:15:49 +0000 (Mon, 15 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/tests/tcos.c
+
+now use tgeneric.c
+added more tests
+
+------------------------------------------------------------------------
+r1259 | zimmerma | 2001-10-15 14:15:27 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tcosh.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/texp2.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsinh.c
+ M /trunk/tests/ttan.c
+ M /trunk/tests/ttanh.c
+
+now use tgeneric.c
+
+------------------------------------------------------------------------
+r1258 | zimmerma | 2001-10-15 14:14:38 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+fixed test of return values for infinities: foo(+/-Inf) is *exact*
+
+------------------------------------------------------------------------
+r1257 | zimmerma | 2001-10-15 14:13:33 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset.c
+
+now also try with negative numbers
+
+------------------------------------------------------------------------
+r1256 | zimmerma | 2001-10-15 14:09:24 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/cos.c
+ M /trunk/cosh.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp_2.c
+ M /trunk/log.c
+
+implement ternary inexact flag
+
+------------------------------------------------------------------------
+r1255 | zimmerma | 2001-10-15 14:08:57 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/div_2exp.c
+ M /trunk/exp3.c
+ M /trunk/mul_2exp.c
+
+implement inexact flag
+
+------------------------------------------------------------------------
+r1254 | zimmerma | 2001-10-15 14:06:46 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+return type is now int for mpfr_mul_2exp and mpfr_div_2exp
+
+------------------------------------------------------------------------
+r1253 | zimmerma | 2001-10-15 14:06:17 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+return type is now int for more functions
+
+------------------------------------------------------------------------
+r1252 | zimmerma | 2001-10-15 14:05:10 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+sign was not set
+
+------------------------------------------------------------------------
+r1251 | zimmerma | 2001-10-15 14:04:24 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+rewritten completely mpfr_can_round_raw
+
+------------------------------------------------------------------------
+r1250 | zimmerma | 2001-10-15 14:02:37 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+documented mpfr_set4
+
+------------------------------------------------------------------------
+r1249 | zimmerma | 2001-10-15 14:02:13 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set_prec.c
+
+return non-zero if malloc failed
+
+------------------------------------------------------------------------
+r1248 | zimmerma | 2001-10-15 14:01:42 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/set_q.c
+
+cosmetic changes
+
+------------------------------------------------------------------------
+r1247 | zimmerma | 2001-10-15 14:01:18 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sin.c
+ M /trunk/sinh.c
+ M /trunk/tan.c
+ M /trunk/tanh.c
+
+implement ternary inexact flag
+
+------------------------------------------------------------------------
+r1246 | zimmerma | 2001-10-15 14:00:45 +0000 (Mon, 15 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sqrt_ui.c
+
+avoid one variable
+
+------------------------------------------------------------------------
+r1245 | daney | 2001-10-12 15:19:02 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+correction d'erreurs sur les notations + correction de la regle 9
+
+------------------------------------------------------------------------
+r1244 | zimmerma | 2001-10-12 12:56:24 +0000 (Fri, 12 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+fixed MPFR_ASSERT
+documented MPFR_ASSERTN and MPFR_ASSERTD
+
+------------------------------------------------------------------------
+r1243 | zimmerma | 2001-10-12 12:24:18 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+
+added test for mpfr_init_set_f prototype
+
+------------------------------------------------------------------------
+r1242 | zimmerma | 2001-10-12 12:23:50 +0000 (Fri, 12 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+added test for inexact flag
+corrected a wrong test
+
+------------------------------------------------------------------------
+r1241 | zimmerma | 2001-10-12 12:23:11 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+cosmetic change
+
+------------------------------------------------------------------------
+r1240 | zimmerma | 2001-10-12 12:22:36 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added tsub_ui (did exist but forgotten in Makefile) and tset (new file)
+
+------------------------------------------------------------------------
+r1239 | zimmerma | 2001-10-12 12:21:40 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tset.c
+
+test file for mpfr_set, initial version
+
+------------------------------------------------------------------------
+r1238 | zimmerma | 2001-10-12 12:20:53 +0000 (Fri, 12 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+void -> int as return value for several functions
+and explained the ternary return value
+
+------------------------------------------------------------------------
+r1237 | zimmerma | 2001-10-12 12:19:49 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/neg.c
+ M /trunk/set_f.c
+ M /trunk/ui_sub.c
+
+implemented inexact flag
+
+------------------------------------------------------------------------
+r1236 | zimmerma | 2001-10-12 12:18:46 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+void -> int as return value for new functions implementing inexact flag
+
+------------------------------------------------------------------------
+r1235 | zimmerma | 2001-10-12 12:18:10 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+implemeted inexact flag in mpfr_set_d
+
+------------------------------------------------------------------------
+r1234 | zimmerma | 2001-10-12 12:17:24 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+implemented inexact flag in mpfr_round
+
+------------------------------------------------------------------------
+r1233 | zimmerma | 2001-10-12 12:16:13 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+completely rewritten
+
+------------------------------------------------------------------------
+r1232 | zimmerma | 2001-10-12 12:15:46 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+computation of inexact flag now directly uses mpfr_round_raw
+
+------------------------------------------------------------------------
+r1231 | zimmerma | 2001-10-12 12:13:27 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+added 'if' in MPFR_ASSERT to avoid compiler warning
+
+------------------------------------------------------------------------
+r1230 | zimmerma | 2001-10-12 12:12:07 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+put initial value in variables which may be used without being initialized
+
+------------------------------------------------------------------------
+r1229 | zimmerma | 2001-10-12 12:11:23 +0000 (Fri, 12 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+updated things done, added Rounding section
+
+------------------------------------------------------------------------
+r1228 | daney | 2001-10-11 16:47:30 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+ajout de log1p et expm1
+
+------------------------------------------------------------------------
+r1227 | zimmerma | 2001-10-11 15:26:57 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tatan.c
+
+reduced number of random tests (took too much time)
+
+------------------------------------------------------------------------
+r1226 | zimmerma | 2001-10-11 15:19:04 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+added random tests for inexact flag
+
+------------------------------------------------------------------------
+r1225 | zimmerma | 2001-10-11 15:18:22 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+ M /trunk/sub_ui.c
+
+implemented inexact flag
+
+------------------------------------------------------------------------
+r1224 | zimmerma | 2001-10-11 15:05:13 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_sub.c
+
+added random tests for inexact flag
+
+------------------------------------------------------------------------
+r1223 | daney | 2001-10-11 14:51:03 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+ajout du log generic et de fma
+
+------------------------------------------------------------------------
+r1222 | zimmerma | 2001-10-11 12:33:08 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+inexact flag was wrong in some cases
+
+------------------------------------------------------------------------
+r1221 | zimmerma | 2001-10-11 12:31:37 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added random tests for inexact flag
+
+------------------------------------------------------------------------
+r1220 | zimmerma | 2001-10-11 12:28:53 +0000 (Thu, 11 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/tests/tasin.c
+
+reduced number of loops per precision from 100 to 10
+(test was too long)
+
+------------------------------------------------------------------------
+r1219 | zimmerma | 2001-10-11 08:25:55 +0000 (Thu, 11 Oct 2001) | 3 lines
+Changed paths:
+ M /trunk/configure
+
+improved check for gmp-impl.h/config.h/gmp-mparam.h/longlong.h
+and corresponding error message
+
+------------------------------------------------------------------------
+r1218 | zimmerma | 2001-10-11 08:25:03 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+stack-alloc.h no longer needed (will be included in gmp-impl.h)
+
+------------------------------------------------------------------------
+r1217 | zimmerma | 2001-10-11 08:24:35 +0000 (Thu, 11 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+stack-alloc.h is no longer needed (will be included in gmp-impl.h)
+
+------------------------------------------------------------------------
+r1216 | zimmerma | 2001-10-09 13:25:20 +0000 (Tue, 09 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added proof of rules
+
+------------------------------------------------------------------------
+r1215 | zimmerma | 2001-10-09 11:38:44 +0000 (Tue, 09 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+fixed buggy test
+
+------------------------------------------------------------------------
+r1214 | zimmerma | 2001-10-05 07:35:10 +0000 (Fri, 05 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+fixed bug for b + d where b=2^900+2^500+2^110, d=2^900-2^500-2^110
+
+------------------------------------------------------------------------
+r1213 | zimmerma | 2001-10-03 10:24:47 +0000 (Wed, 03 Oct 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+fixed bug in mpfr_set_d on 64-bit machines
+
+------------------------------------------------------------------------
+r1212 | zimmerma | 2001-09-28 12:13:30 +0000 (Fri, 28 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+fixed a few problems in mpfr_set_d for sizer < MPFR_LIMBS_PER_DOUBLE
+
+------------------------------------------------------------------------
+r1211 | zimmerma | 2001-09-28 10:15:12 +0000 (Fri, 28 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.bib
+
+added paper of Brent and McMillan
+
+------------------------------------------------------------------------
+r1210 | zimmerma | 2001-09-28 10:11:04 +0000 (Fri, 28 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+does not call compare_exp2_exp3 when argc=4
+
+------------------------------------------------------------------------
+r1209 | zimmerma | 2001-09-28 10:09:06 +0000 (Fri, 28 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one item
+
+------------------------------------------------------------------------
+r1208 | zimmerma | 2001-09-28 09:42:22 +0000 (Fri, 28 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/set_prec.c
+
+now mpfr_set_prec returns 1 instead of producing an error in case prec=0
+
+------------------------------------------------------------------------
+r1207 | daney | 2001-09-27 13:03:29 +0000 (Thu, 27 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+New version with new generic function + / * etc
+
+------------------------------------------------------------------------
+r1206 | vlefevre | 2001-09-20 15:08:05 +0000 (Thu, 20 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/BUGS
+ M /trunk/INSTALL
+ M /trunk/README
+
+BUGS updated.
+
+------------------------------------------------------------------------
+r1205 | vlefevre | 2001-09-13 16:35:18 +0000 (Thu, 13 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttan.c
+
+Prototype changes.
+
+------------------------------------------------------------------------
+r1204 | vlefevre | 2001-09-13 13:20:40 +0000 (Thu, 13 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/dump.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+
+<strings.h> -> <string.h> (ISO C).
+
+------------------------------------------------------------------------
+r1203 | vlefevre | 2001-09-13 13:12:21 +0000 (Thu, 13 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/set_prc_raw.c
+
+#include added.
+
+------------------------------------------------------------------------
+r1202 | vlefevre | 2001-09-13 12:32:44 +0000 (Thu, 13 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/agm.c
+ M /trunk/euler.c
+ M /trunk/init.c
+ M /trunk/pi.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/set_prec.c
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tcos.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/tests/tisnan.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/tsin.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttan.c
+
+#include added/removed.
+
+------------------------------------------------------------------------
+r1201 | vlefevre | 2001-09-13 12:16:12 +0000 (Thu, 13 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/configure
+ M /trunk/configure.in
+ M /trunk/mpfr-impl.h
+
+GCC option -Wno-implicit removed and prototype added to mpfr-impl.h
+
+------------------------------------------------------------------------
+r1200 | vlefevre | 2001-09-12 15:51:26 +0000 (Wed, 12 Sep 2001) | 8 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/Makefile.in
+
+INCLUDES in Makefile.am: -I$(top_srcdir) and @INCLUDES@ swapped.
+This defines the following precedence for the tests:
+ 1) MPFR directories
+ 2) User-defined directory
+ 3) GMP include directory
+This allows the user to override the GMP longlong.h file with the
+gcc-3 one, by using: INCLUDES="-I.../include" ./configure ...
+
+------------------------------------------------------------------------
+r1199 | vlefevre | 2001-09-12 13:50:42 +0000 (Wed, 12 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/log2.c
+
+#include order fixed.
+
+------------------------------------------------------------------------
+r1198 | vlefevre | 2001-09-12 12:19:27 +0000 (Wed, 12 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+Tests added (in particular, inex value).
+
+------------------------------------------------------------------------
+r1197 | vlefevre | 2001-09-12 12:19:06 +0000 (Wed, 12 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+Bug fixed.
+
+------------------------------------------------------------------------
+r1196 | vlefevre | 2001-09-11 15:21:52 +0000 (Tue, 11 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+MPFR_RET: definition changed to avoid warning.
+
+------------------------------------------------------------------------
+r1195 | vlefevre | 2001-09-11 14:02:32 +0000 (Tue, 11 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/set.c
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+
+Inexact ternary value for mpfr_set4, mpfr_set_ui and mpfr_set_si.
+
+------------------------------------------------------------------------
+r1194 | vlefevre | 2001-09-11 13:55:08 +0000 (Tue, 11 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Macro SAFE_ABS.
+
+------------------------------------------------------------------------
+r1193 | vlefevre | 2001-09-11 13:16:51 +0000 (Tue, 11 Sep 2001) | 3 lines
+Changed paths:
+ M /trunk/exceptions.c
+ M /trunk/mpfr-impl.h
+
+Inexact ternary value and flag for mpfr_set_underflow, mpfr_set_overflow
+and mpfr_check_range.
+
+------------------------------------------------------------------------
+r1192 | vlefevre | 2001-09-11 03:20:42 +0000 (Tue, 11 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/set.c
+
+Macro MPFR_RET added. Ternary value for mpfr_set4.
+
+------------------------------------------------------------------------
+r1191 | vlefevre | 2001-09-11 01:02:15 +0000 (Tue, 11 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/exceptions.c
+ M /trunk/mpfr.h
+
+New flags.
+
+------------------------------------------------------------------------
+r1190 | vlefevre | 2001-09-10 23:58:12 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/div.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/round.c
+ M /trunk/set.c
+ M /trunk/set_f.c
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+ M /trunk/sqrt.c
+ M /trunk/tests/Makefile.in
+
+Parameter added to mpfr_round_raw: pointer to inexact ternary value.
+
+------------------------------------------------------------------------
+r1189 | hanrot | 2001-09-10 16:30:21 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Zqwiuyt
+
+------------------------------------------------------------------------
+r1188 | hanrot | 2001-09-10 16:21:42 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Zorgs.
+
+------------------------------------------------------------------------
+r1187 | hanrot | 2001-09-10 15:42:12 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Gleurbs.
+
+------------------------------------------------------------------------
+r1186 | hanrot | 2001-09-10 15:40:57 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Patch grotesque.
+
+------------------------------------------------------------------------
+r1185 | hanrot | 2001-09-10 15:20:08 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Patch for the case SIZE(r) < MPFR_LIMBS_PER_DOUBLE.
+
+------------------------------------------------------------------------
+r1184 | zimmerma | 2001-09-10 07:47:29 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/ttan.c
+
+test file for mpfr_tan
+
+------------------------------------------------------------------------
+r1183 | zimmerma | 2001-09-10 07:47:15 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin.c
+
+fixed a few typos
+
+------------------------------------------------------------------------
+r1182 | zimmerma | 2001-09-10 07:46:56 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/tests/reuse.c
+
+added mpfr_tan
+
+------------------------------------------------------------------------
+r1181 | zimmerma | 2001-09-10 07:46:37 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added ttan
+
+------------------------------------------------------------------------
+r1180 | zimmerma | 2001-09-10 07:45:54 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added the tangent
+
+------------------------------------------------------------------------
+r1179 | zimmerma | 2001-09-10 07:45:14 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added tan.c
+
+------------------------------------------------------------------------
+r1178 | zimmerma | 2001-09-10 07:44:05 +0000 (Mon, 10 Sep 2001) | 2 lines
+Changed paths:
+ A /trunk/tan.c
+
+tangent function
+
+------------------------------------------------------------------------
+r1177 | zimmerma | 2001-09-07 12:46:54 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+removed mpfr_sin and mpfr_cos (now separate implementations)
+
+------------------------------------------------------------------------
+r1176 | zimmerma | 2001-09-07 12:45:52 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+removed sin_cos
+
+------------------------------------------------------------------------
+r1175 | zimmerma | 2001-09-07 12:41:15 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added sine and cosine
+
+------------------------------------------------------------------------
+r1174 | zimmerma | 2001-09-07 12:40:29 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+removed sin_cos, added sin and cos
+
+------------------------------------------------------------------------
+r1173 | zimmerma | 2001-09-07 12:37:21 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+removed mpfr_sin_cos
+
+------------------------------------------------------------------------
+r1172 | zimmerma | 2001-09-07 12:32:28 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+removed sin_cos, added sin and cos
+
+------------------------------------------------------------------------
+r1171 | zimmerma | 2001-09-07 12:32:07 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+removed tsin_cos, added tsin and tcos
+
+------------------------------------------------------------------------
+r1170 | zimmerma | 2001-09-07 12:30:42 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tcos.c
+ A /trunk/tests/tsin.c
+
+test files for mpfr_cos and mpfr_sin
+
+------------------------------------------------------------------------
+r1169 | zimmerma | 2001-09-07 12:30:14 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ A /trunk/sin.c
+
+new implementation of mpfr_sin, using mpfr_cos
+
+------------------------------------------------------------------------
+r1168 | zimmerma | 2001-09-07 12:29:52 +0000 (Fri, 07 Sep 2001) | 2 lines
+Changed paths:
+ A /trunk/cos.c
+
+new (faster) implementation of mpfr_cos
+
+------------------------------------------------------------------------
+r1167 | vlefevre | 2001-09-06 15:59:15 +0000 (Thu, 06 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/exceptions.c
+
+Fix: flags set in mpfr_set_{under,over}flow().
+
+------------------------------------------------------------------------
+r1166 | vlefevre | 2001-09-06 12:49:53 +0000 (Thu, 06 Sep 2001) | 3 lines
+Changed paths:
+ M /trunk/sub.c
+
+Cases where the result is 0 fixed.
+Integer overflow checked in mpfr_sub.
+
+------------------------------------------------------------------------
+r1165 | vlefevre | 2001-09-06 11:35:12 +0000 (Thu, 06 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/add.c
+
+In add.c: use mpfr_cmp_abs instead of mpfr_cmp3; x - x fixed for GMP_RNDD.
+
+------------------------------------------------------------------------
+r1164 | vlefevre | 2001-09-06 10:27:57 +0000 (Thu, 06 Sep 2001) | 2 lines
+Changed paths:
+ A /trunk/cmp_abs.c
+
+Compare the absolute values of two nonzero FP numbers.
+
+------------------------------------------------------------------------
+r1163 | vlefevre | 2001-09-05 15:40:47 +0000 (Wed, 05 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+ M /trunk/mpfr.h
+
+mpfr_cmp3 changed and integer overflows checked.
+
+------------------------------------------------------------------------
+r1162 | zimmerma | 2001-09-05 09:52:50 +0000 (Wed, 05 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added efficiency item
+
+------------------------------------------------------------------------
+r1161 | vlefevre | 2001-09-03 14:52:45 +0000 (Mon, 03 Sep 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Cases [+-]0 + [+-]0 fixed (depending on the rounding mode).
+
+------------------------------------------------------------------------
+r1160 | vlefevre | 2001-08-29 15:29:46 +0000 (Wed, 29 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+Optimization + overflow support.
+
+------------------------------------------------------------------------
+r1159 | vlefevre | 2001-08-29 14:10:30 +0000 (Wed, 29 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/mpfr-impl.h
+
+Case +0 + -0 fixed.
+
+------------------------------------------------------------------------
+r1158 | zimmerma | 2001-08-29 12:30:24 +0000 (Wed, 29 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added one test
+
+------------------------------------------------------------------------
+r1157 | zimmerma | 2001-08-29 09:24:30 +0000 (Wed, 29 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+another test from Norbert
+
+------------------------------------------------------------------------
+r1156 | zimmerma | 2001-08-29 09:24:10 +0000 (Wed, 29 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+another fix (final copy when xsize > ysize was wrong)
+
+------------------------------------------------------------------------
+r1155 | zimmerma | 2001-08-28 16:15:02 +0000 (Tue, 28 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added several tests for case (1b)
+
+------------------------------------------------------------------------
+r1154 | zimmerma | 2001-08-28 15:57:47 +0000 (Tue, 28 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+another fix (previous one was incomplete)
+
+------------------------------------------------------------------------
+r1153 | zimmerma | 2001-08-28 15:56:22 +0000 (Tue, 28 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+added one more test (from Norbert)
+
+------------------------------------------------------------------------
+r1152 | vlefevre | 2001-08-28 14:20:50 +0000 (Tue, 28 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Bug fixed.
+
+------------------------------------------------------------------------
+r1151 | vlefevre | 2001-08-28 10:28:50 +0000 (Tue, 28 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Bug fixed and update to check the exponents.
+
+------------------------------------------------------------------------
+r1150 | zimmerma | 2001-08-27 14:54:28 +0000 (Mon, 27 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv_ui.c
+
+added test for 53 <= xprec, yprec <= 128
+
+------------------------------------------------------------------------
+r1149 | zimmerma | 2001-08-27 14:10:03 +0000 (Mon, 27 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+added multiple tests for 53 <= xprec, yprec <= 128
+
+------------------------------------------------------------------------
+r1148 | zimmerma | 2001-08-27 14:09:13 +0000 (Mon, 27 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+was completely wrong for ysize > xsize
+
+------------------------------------------------------------------------
+r1147 | zimmerma | 2001-08-27 12:47:37 +0000 (Mon, 27 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added faster formula in exp(-8*n) for Euler's constant
+
+------------------------------------------------------------------------
+r1146 | vlefevre | 2001-08-25 09:58:24 +0000 (Sat, 25 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Assertion support with debug level.
+
+------------------------------------------------------------------------
+r1145 | vlefevre | 2001-08-25 09:11:18 +0000 (Sat, 25 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/add_ui.c
+ A /trunk/exceptions.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ A /trunk/save_expo.c
+ M /trunk/sub_ui.c
+
+Some support for exponent change and exceptions.
+
+------------------------------------------------------------------------
+r1144 | zimmerma | 2001-08-23 14:57:09 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+added constant ALPHA (for mpfr_const_euler)
+
+------------------------------------------------------------------------
+r1143 | zimmerma | 2001-08-23 14:56:36 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/tests/Makefile.in
+
+added euler/teuler
+
+------------------------------------------------------------------------
+r1142 | zimmerma | 2001-08-23 14:53:23 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added teuler
+
+------------------------------------------------------------------------
+r1141 | zimmerma | 2001-08-23 14:47:41 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added euler.c
+
+------------------------------------------------------------------------
+r1140 | zimmerma | 2001-08-23 14:45:58 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+fixed pb with c2 = c2old << dif with dif negative
+
+------------------------------------------------------------------------
+r1139 | zimmerma | 2001-08-23 14:25:50 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed bug for (2^53+4) - 1
+
+------------------------------------------------------------------------
+r1138 | zimmerma | 2001-08-23 13:51:31 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+added new test from Norbert Mueller
+
+------------------------------------------------------------------------
+r1137 | zimmerma | 2001-08-23 13:41:17 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+fixed pb: sh becomes "negative"
+
+------------------------------------------------------------------------
+r1136 | zimmerma | 2001-08-23 11:13:44 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+included Euler's constant
+
+------------------------------------------------------------------------
+r1135 | zimmerma | 2001-08-23 11:13:10 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ A /trunk/algorithms.bib
+
+bibtex file for algorithms.tex
+
+------------------------------------------------------------------------
+r1134 | zimmerma | 2001-08-23 11:07:19 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/teuler.c
+
+test file for mpfr_const_euler
+
+------------------------------------------------------------------------
+r1133 | zimmerma | 2001-08-23 11:06:52 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ A /trunk/euler.c
+
+computation of Euler's constant 0.577...
+
+------------------------------------------------------------------------
+r1132 | zimmerma | 2001-08-23 11:06:23 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+added missing prototype
+
+------------------------------------------------------------------------
+r1131 | zimmerma | 2001-08-23 11:01:31 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr_const_euler returns an int
+
+------------------------------------------------------------------------
+r1130 | zimmerma | 2001-08-23 11:00:34 +0000 (Thu, 23 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+added mpfr_const_euler
+
+------------------------------------------------------------------------
+r1129 | vlefevre | 2001-08-22 16:01:37 +0000 (Wed, 22 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+Tests added.
+
+------------------------------------------------------------------------
+r1128 | vlefevre | 2001-08-22 16:01:28 +0000 (Wed, 22 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+Bugs fixed (particular cases).
+
+------------------------------------------------------------------------
+r1127 | vlefevre | 2001-08-22 15:18:06 +0000 (Wed, 22 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+"mant(c) != 1/2" test was broken.
+
+------------------------------------------------------------------------
+r1126 | vlefevre | 2001-08-22 15:05:23 +0000 (Wed, 22 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+check fixed. Check added: 2^53 + 1 --> 2^53.
+
+------------------------------------------------------------------------
+r1125 | vlefevre | 2001-08-22 14:24:02 +0000 (Wed, 22 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/tests/Makefile.in
+
+Update.
+
+------------------------------------------------------------------------
+r1124 | zimmerma | 2001-08-21 15:02:19 +0000 (Tue, 21 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv_ui.c
+
+added one test
+
+------------------------------------------------------------------------
+r1123 | zimmerma | 2001-08-21 15:02:05 +0000 (Tue, 21 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+fixed stupid bug when dif < 0
+
+------------------------------------------------------------------------
+r1122 | zimmerma | 2001-08-14 14:15:25 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+
+added mpfr_asin
+
+------------------------------------------------------------------------
+r1121 | zimmerma | 2001-08-14 14:14:57 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added missing cast
+
+------------------------------------------------------------------------
+r1120 | zimmerma | 2001-08-14 13:50:47 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tasin.c
+
+test file for mpfr_asin
+
+------------------------------------------------------------------------
+r1119 | zimmerma | 2001-08-14 13:47:32 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ A /trunk/asin.c
+
+arc-sine, contributed by Mathieu Dutour
+
+------------------------------------------------------------------------
+r1118 | zimmerma | 2001-08-14 13:37:06 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+added mpfr_asin
+
+------------------------------------------------------------------------
+r1117 | zimmerma | 2001-08-14 13:36:50 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tatan.c
+
+new name for file tarctan.c
+
+------------------------------------------------------------------------
+r1116 | zimmerma | 2001-08-14 13:36:37 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ D /trunk/tests/tarctan.c
+
+renamed to tatan.c
+
+------------------------------------------------------------------------
+r1115 | zimmerma | 2001-08-14 13:36:10 +0000 (Tue, 14 Aug 2001) | 3 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+renamed tarctan.c into tatan.c
+added tasin.c
+
+------------------------------------------------------------------------
+r1114 | zimmerma | 2001-08-14 13:32:47 +0000 (Tue, 14 Aug 2001) | 3 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+renamed arctan.c to atan.c
+added asin.c
+
+------------------------------------------------------------------------
+r1113 | zimmerma | 2001-08-14 13:32:20 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ A /trunk/atan.c
+
+new name for file arctan.c
+
+------------------------------------------------------------------------
+r1112 | zimmerma | 2001-08-14 13:32:04 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ D /trunk/arctan.c
+
+moved to atan.c
+
+------------------------------------------------------------------------
+r1111 | zimmerma | 2001-08-14 13:15:56 +0000 (Tue, 14 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+low significant bit is in ap[0] and not in ap[an-1] !!!
+
+------------------------------------------------------------------------
+r1110 | vlefevre | 2001-08-13 17:56:06 +0000 (Mon, 13 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Cleaner MPFR_SET_SAME_SIGN.
+
+------------------------------------------------------------------------
+r1109 | vlefevre | 2001-08-13 04:48:05 +0000 (Mon, 13 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Macros MPFR_SET_SAME_SIGN, MPFR_INIT and MPFR_INIT1 changed to expressions.
+
+------------------------------------------------------------------------
+r1108 | vlefevre | 2001-08-10 15:40:56 +0000 (Fri, 10 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+ M /trunk/set_ui.c
+ M /trunk/set_z.c
+
+Bugs fixed (wrong types).
+
+------------------------------------------------------------------------
+r1107 | vlefevre | 2001-08-10 12:35:30 +0000 (Fri, 10 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Macros mpfr_init_set_* changed to expressions.
+
+------------------------------------------------------------------------
+r1106 | vlefevre | 2001-08-10 12:04:17 +0000 (Fri, 10 Aug 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+
+Makefile.in update.
+
+------------------------------------------------------------------------
+r1105 | zimmerma | 2001-07-06 14:02:40 +0000 (Fri, 06 Jul 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+edited wrt GNU style
+
+------------------------------------------------------------------------
+r1104 | zimmerma | 2001-07-06 13:56:34 +0000 (Fri, 06 Jul 2001) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed stupid bug: ceil(a/b) isn't (a+b-1)/a but simply a/b for a negative!
+
+------------------------------------------------------------------------
+r1103 | zimmerma | 2001-07-06 13:04:04 +0000 (Fri, 06 Jul 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed array bound write (bn < an + cancel1 + 1)
+
+------------------------------------------------------------------------
+r1102 | zimmerma | 2001-07-06 12:32:13 +0000 (Fri, 06 Jul 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+macros MPFR_NOTZERO and MPFR_ISZERO did not work properly with 64-bit words
+
+------------------------------------------------------------------------
+r1101 | zimmerma | 2001-06-29 16:21:05 +0000 (Fri, 29 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed bug for output base 2^k
+
+------------------------------------------------------------------------
+r1100 | zimmerma | 2001-06-29 16:19:30 +0000 (Fri, 29 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added one test
+
+------------------------------------------------------------------------
+r1099 | zimmerma | 2001-06-29 16:17:20 +0000 (Fri, 29 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added a section for the exponential
+
+------------------------------------------------------------------------
+r1098 | zimmerma | 2001-06-29 11:56:51 +0000 (Fri, 29 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+ M /trunk/tests/tdiv_ui.c
+
+fixed bug when dividend is 0
+
+------------------------------------------------------------------------
+r1097 | zimmerma | 2001-06-28 12:45:27 +0000 (Thu, 28 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/exp_2.c
+
+moved TMP_FREE
+
+------------------------------------------------------------------------
+r1096 | zimmerma | 2001-06-28 12:39:45 +0000 (Thu, 28 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added 2 things
+
+------------------------------------------------------------------------
+r1095 | zimmerma | 2001-06-27 09:40:24 +0000 (Wed, 27 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added mpfr.info to files to remove for "make distclean"
+
+------------------------------------------------------------------------
+r1094 | vlefevre | 2001-06-23 01:41:08 +0000 (Sat, 23 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/Makefile.in
+
+Non-existent C source references removed.
+
+------------------------------------------------------------------------
+r1093 | vlefevre | 2001-06-23 01:13:41 +0000 (Sat, 23 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+Macros MPFR_INIT and MPFR_INIT1 fixed.
+
+------------------------------------------------------------------------
+r1092 | zimmerma | 2001-06-18 13:52:58 +0000 (Mon, 18 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/sqrt.c
+
+nested double TMP_DECL's
+
+------------------------------------------------------------------------
+r1091 | daney | 2001-06-14 15:55:36 +0000 (Thu, 14 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/arctan.c
+ M /trunk/mpfr.h
+ M /trunk/out_str.c
+ M /trunk/sin_cos.c
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/Makefile.in
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tarctan.c
+ M /trunk/tests/tfactorial.c
+ M /trunk/ui_sub.c
+
+A few patches.
+
+------------------------------------------------------------------------
+r1090 | zimmerma | 2001-06-07 14:22:08 +0000 (Thu, 07 Jun 2001) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/sin_cos.c
+
+added mpfr_sin and mpfr_cos
+corrected in the documentation some exact values
+
+------------------------------------------------------------------------
+r1089 | zimmerma | 2001-06-01 16:15:23 +0000 (Fri, 01 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+removed 2 tabs
+
+------------------------------------------------------------------------
+r1088 | zimmerma | 2001-06-01 16:03:15 +0000 (Fri, 01 Jun 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added change explaining the LGPL with non-free programs
+
+------------------------------------------------------------------------
+r1087 | hanrot | 2001-05-31 16:56:11 +0000 (Thu, 31 May 2001) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+Patch for the case b = 0 or c = 0.
+
+------------------------------------------------------------------------
+r1086 | hanrot | 2001-05-23 16:57:20 +0000 (Wed, 23 May 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+Added DDefour's bug.
+
+------------------------------------------------------------------------
+r1085 | hanrot | 2001-05-22 10:29:32 +0000 (Tue, 22 May 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+Patch in the case MPFR_PREC(b) > MPFR_PREC(a)+cancel.
+
+------------------------------------------------------------------------
+r1084 | vlefevre | 2001-05-10 12:31:23 +0000 (Thu, 10 May 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/mpfr.texi
+ M /trunk/tests/Makefile.in
+
+fixed bug in mpfr.texi
+
+------------------------------------------------------------------------
+r1083 | daney | 2001-05-10 09:19:25 +0000 (Thu, 10 May 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+correction du bug donne par vincent + ajout des aides des fonctions hyperbolic
+
+------------------------------------------------------------------------
+r1082 | daney | 2001-05-09 15:26:28 +0000 (Wed, 09 May 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r1081 | zimmerma | 2001-04-20 08:49:45 +0000 (Fri, 20 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+log(0) now returns 0 (exact infinity)
+
+------------------------------------------------------------------------
+r1080 | zimmerma | 2001-04-18 16:05:20 +0000 (Wed, 18 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+fixed pbs with NaN/Inf
+
+------------------------------------------------------------------------
+r1079 | zimmerma | 2001-04-18 11:56:09 +0000 (Wed, 18 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed new bug found by Nathalie Revol (case when add_one_ulp produces a carry)
+
+------------------------------------------------------------------------
+r1078 | zimmerma | 2001-04-18 11:51:51 +0000 (Wed, 18 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsub.c
+
+added new bug found by Nathalie Revol
+
+------------------------------------------------------------------------
+r1077 | zimmerma | 2001-04-18 11:40:26 +0000 (Wed, 18 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed bug for 1.0000... - 0.000001 for rounding up or nearest
+
+------------------------------------------------------------------------
+r1076 | revol | 2001-04-17 18:23:18 +0000 (Tue, 17 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+Case where argument < 0 included, NR 17-04-2001
+
+------------------------------------------------------------------------
+r1075 | zimmerma | 2001-04-12 21:38:29 +0000 (Thu, 12 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_sub.c
+
+added new (special) tests
+
+------------------------------------------------------------------------
+r1074 | zimmerma | 2001-04-12 21:38:02 +0000 (Thu, 12 Apr 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tsub.c
+
+test file for mpfr_sub
+
+------------------------------------------------------------------------
+r1073 | zimmerma | 2001-04-12 21:37:47 +0000 (Thu, 12 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added tsub
+
+------------------------------------------------------------------------
+r1072 | daney | 2001-04-06 09:30:15 +0000 (Fri, 06 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+change old exp2 (conflict with 2^x) to exp_2
+
+------------------------------------------------------------------------
+r1071 | zimmerma | 2001-04-05 18:29:54 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+0 -> GMP_RNDN
+
+------------------------------------------------------------------------
+r1070 | zimmerma | 2001-04-05 18:29:03 +0000 (Thu, 05 Apr 2001) | 3 lines
+Changed paths:
+ M /trunk/cmp2.c
+
+check apart the case c=0 (otherwise some low significant limbs may be
+non zero, which may produce a wrong result)
+
+------------------------------------------------------------------------
+r1069 | zimmerma | 2001-04-05 18:18:14 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+mpfr_exp2 -> mpfr_exp_2
+
+------------------------------------------------------------------------
+r1068 | zimmerma | 2001-04-05 17:52:36 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+mpfr_exp2 -> mpfr_exp_2
+
+------------------------------------------------------------------------
+r1067 | daney | 2001-04-05 17:42:31 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+reactualise .h
+
+------------------------------------------------------------------------
+r1066 | daney | 2001-04-05 17:42:09 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/thyperbolic.c
+
+change header
+
+------------------------------------------------------------------------
+r1065 | daney | 2001-04-05 17:39:30 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+change reuse to suppress factorial
+
+------------------------------------------------------------------------
+r1064 | daney | 2001-04-05 17:33:16 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+suppress of timing in makefile
+
+------------------------------------------------------------------------
+r1063 | daney | 2001-04-05 17:22:23 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ A /trunk/exp_2.c
+
+add the old exp2 function and file renamed by exp_2
+
+------------------------------------------------------------------------
+r1062 | daney | 2001-04-05 17:20:11 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+change makefile for new functions
+
+------------------------------------------------------------------------
+r1061 | daney | 2001-04-05 17:19:21 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+change make file test for hyperbolic function exp2 and factorial
+
+------------------------------------------------------------------------
+r1060 | daney | 2001-04-05 17:17:38 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tacosh.c
+ A /trunk/tests/tasinh.c
+ A /trunk/tests/tatanh.c
+ A /trunk/tests/tcosh.c
+ A /trunk/tests/tsinh.c
+ A /trunk/tests/ttanh.c
+
+add new test file for hyperbolic function
+
+------------------------------------------------------------------------
+r1059 | daney | 2001-04-05 17:16:37 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/texp2.c
+ A /trunk/tests/tfactorial.c
+ A /trunk/tests/thyperbolic.c
+
+add test file for new function
+
+------------------------------------------------------------------------
+r1058 | daney | 2001-04-05 17:15:37 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+ A /trunk/factorial.c
+
+add function
+
+------------------------------------------------------------------------
+r1057 | daney | 2001-04-05 17:14:44 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ A /trunk/acosh.c
+ A /trunk/asinh.c
+ A /trunk/atanh.c
+ A /trunk/sinh.c
+ A /trunk/tanh.c
+
+new file function
+
+------------------------------------------------------------------------
+r1056 | daney | 2001-04-05 17:13:11 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ A /trunk/cosh.c
+
+new function file
+
+------------------------------------------------------------------------
+r1055 | zimmerma | 2001-04-05 17:07:35 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+
+new version with cmp2.c
+
+------------------------------------------------------------------------
+r1054 | zimmerma | 2001-04-05 15:53:49 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+fixed pb with inexact flag when 'int' and 'mp_limb_t' has different sizes
+
+------------------------------------------------------------------------
+r1053 | daney | 2001-04-05 15:31:42 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp_ui.c
+ M /trunk/tests/tcmp_ui.c
+
+fixed bug for mpfr_cmp_ui (Inf, 0)
+
+------------------------------------------------------------------------
+r1052 | daney | 2001-04-05 15:29:31 +0000 (Thu, 05 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/set_ui.c
+ M /trunk/tests/tset_si.c
+
+fixed bug for mpfr_set_ui (x, 0) [was giving -0]
+
+------------------------------------------------------------------------
+r1051 | zimmerma | 2001-04-03 17:36:03 +0000 (Tue, 03 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/algorithms.tex
+
+added algorithm for mpfr_cmp2
+
+------------------------------------------------------------------------
+r1050 | zimmerma | 2001-04-03 17:35:37 +0000 (Tue, 03 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added cmp2.c
+
+------------------------------------------------------------------------
+r1049 | zimmerma | 2001-04-03 17:35:03 +0000 (Tue, 03 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp2.c
+
+fixed bug when diff_exp >= BITS_PER_MP_LIMB
+
+------------------------------------------------------------------------
+r1048 | zimmerma | 2001-04-03 17:34:03 +0000 (Tue, 03 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+added new test for worst cases: 1 - 1/2^i and (1 + 1/2^i) - 1/2^i
+
+------------------------------------------------------------------------
+r1047 | zimmerma | 2001-04-03 17:11:08 +0000 (Tue, 03 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+changed return value of mpfr_cmp2
+
+------------------------------------------------------------------------
+r1046 | zimmerma | 2001-04-03 17:10:39 +0000 (Tue, 03 Apr 2001) | 2 lines
+Changed paths:
+ A /trunk/cmp2.c
+
+new file for mpfr_cmp2
+
+------------------------------------------------------------------------
+r1045 | zimmerma | 2001-04-03 17:10:23 +0000 (Tue, 03 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+moved mpfr_cmp2 to separate file cmp2.c
+
+------------------------------------------------------------------------
+r1044 | zimmerma | 2001-04-03 17:09:44 +0000 (Tue, 03 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+added several tests, and a routine that generates worst cases
+
+------------------------------------------------------------------------
+r1043 | zimmerma | 2001-04-03 10:21:10 +0000 (Tue, 03 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/trunc.c
+
+two changes suggested by Kevin Ryde
+
+------------------------------------------------------------------------
+r1042 | zimmerma | 2001-04-02 17:46:07 +0000 (Mon, 02 Apr 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+
+new version from new Makefile.am
+
+------------------------------------------------------------------------
+r1041 | zimmerma | 2001-03-27 20:23:12 +0000 (Tue, 27 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added new test
+
+------------------------------------------------------------------------
+r1040 | zimmerma | 2001-03-27 20:22:57 +0000 (Tue, 27 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+fixed new bug in mpfr_cmp2 found by Fabrice
+
+------------------------------------------------------------------------
+r1039 | zimmerma | 2001-03-21 22:07:04 +0000 (Wed, 21 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+added new test
+
+------------------------------------------------------------------------
+r1038 | zimmerma | 2001-03-21 22:05:54 +0000 (Wed, 21 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+fixed bug found by Nathalie Revol
+
+------------------------------------------------------------------------
+r1037 | zimmerma | 2001-03-20 14:32:26 +0000 (Tue, 20 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added 2 items
+
+------------------------------------------------------------------------
+r1036 | zimmerma | 2001-03-20 10:03:08 +0000 (Tue, 20 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+
+added test for mpfr_cmp_ui (-0, 0)
+
+------------------------------------------------------------------------
+r1035 | zimmerma | 2001-03-20 10:02:27 +0000 (Tue, 20 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/out_str.c
+
+now prints -0 for -0
+
+------------------------------------------------------------------------
+r1034 | revol | 2001-03-19 18:11:09 +0000 (Mon, 19 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp_ui.c
+
+Comparison between 0- and 0 now returns 0, NR 19-03-2001
+
+------------------------------------------------------------------------
+r1033 | vlefevre | 2001-03-16 13:50:18 +0000 (Fri, 16 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+added cast to avoid a warning
+
+------------------------------------------------------------------------
+r1032 | zimmerma | 2001-03-13 09:32:53 +0000 (Tue, 13 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+added tests for inexact return value
+
+------------------------------------------------------------------------
+r1031 | zimmerma | 2001-03-13 09:32:28 +0000 (Tue, 13 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+tiny bug in inexact value determination
+
+------------------------------------------------------------------------
+r1030 | zimmerma | 2001-03-13 08:55:46 +0000 (Tue, 13 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+
+mpfr_mul now returns an int
+
+------------------------------------------------------------------------
+r1029 | zimmerma | 2001-03-09 17:52:21 +0000 (Fri, 09 Mar 2001) | 2 lines
+Changed paths:
+ A /trunk/algorithms.tex
+
+description of algorithms
+
+------------------------------------------------------------------------
+r1028 | zimmerma | 2001-03-09 17:14:53 +0000 (Fri, 09 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+reorganized
+
+------------------------------------------------------------------------
+r1027 | zimmerma | 2001-03-08 13:26:07 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added few things
+
+------------------------------------------------------------------------
+r1026 | zimmerma | 2001-03-08 13:25:39 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/mpfr.h
+
+added arc-tangent
+
+------------------------------------------------------------------------
+r1025 | zimmerma | 2001-03-08 13:24:57 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added tarctan
+
+------------------------------------------------------------------------
+r1024 | zimmerma | 2001-03-08 13:24:29 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+
+added test to mpfr_arctan
+
+------------------------------------------------------------------------
+r1023 | zimmerma | 2001-03-08 13:23:34 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tarctan.c
+
+added header
+
+------------------------------------------------------------------------
+r1022 | zimmerma | 2001-03-08 13:22:20 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tarctan.c
+
+test file for mpfr_arctan
+
+------------------------------------------------------------------------
+r1021 | zimmerma | 2001-03-08 13:14:26 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/arctan.c
+
+removed math.h
+
+------------------------------------------------------------------------
+r1020 | zimmerma | 2001-03-08 13:08:25 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ A /trunk/arctan.c
+
+arctangent function (contributed by Mathieu Dutour, done slight changes)
+
+------------------------------------------------------------------------
+r1019 | zimmerma | 2001-03-08 13:07:32 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added Mathieu Dutour in contributors
+
+------------------------------------------------------------------------
+r1018 | zimmerma | 2001-03-08 13:06:20 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added mpfr_arctan
+
+------------------------------------------------------------------------
+r1017 | zimmerma | 2001-03-08 11:21:31 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tcan_round.c
+
+added one test
+
+------------------------------------------------------------------------
+r1016 | zimmerma | 2001-03-08 11:21:14 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+fixed bug in mpfr_can_round_raw, when err > bn*BITS_PER_MP_LIMB
+
+------------------------------------------------------------------------
+r1015 | zimmerma | 2001-03-08 09:35:03 +0000 (Thu, 08 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+now tset_str <number> <prec> is possible
+
+------------------------------------------------------------------------
+r1014 | zimmerma | 2001-03-06 16:41:25 +0000 (Tue, 06 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/out_str.c
+
+fixed bug for Infinity (was testing zero before)
+
+------------------------------------------------------------------------
+r1013 | zimmerma | 2001-03-01 10:32:32 +0000 (Thu, 01 Mar 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+replaced (mp_limb_t) 4294967295 by CNST_LIMB(0xFFFFFFFF)
+
+------------------------------------------------------------------------
+r1012 | zimmerma | 2001-02-22 13:40:32 +0000 (Thu, 22 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+forgot to declare q in mpfr_get_d2 when BITS_PER_MP_LIMB=64
+
+------------------------------------------------------------------------
+r1011 | zimmerma | 2001-02-21 10:40:35 +0000 (Wed, 21 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+removed fprintf() when unexpected end of string
+
+------------------------------------------------------------------------
+r1010 | zimmerma | 2001-02-21 10:39:04 +0000 (Wed, 21 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+added undef's to avoid warnings at compilation
+
+------------------------------------------------------------------------
+r1009 | zimmerma | 2001-02-19 12:46:07 +0000 (Mon, 19 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+removed mpfr_set_machine_rnd_mode
+
+------------------------------------------------------------------------
+r1008 | zimmerma | 2001-02-18 12:16:14 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/reuse.c
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpi.c
+ M /trunk/tests/tpow.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tswap.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+changed "int main(..)" to two lines
+
+------------------------------------------------------------------------
+r1007 | zimmerma | 2001-02-18 12:13:55 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+now initialize str_is_null correctly
+
+------------------------------------------------------------------------
+r1006 | zimmerma | 2001-02-18 12:13:41 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tround.c
+
+added more tests
+
+------------------------------------------------------------------------
+r1005 | zimmerma | 2001-02-18 12:13:16 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+don't change MPFR_SIZE when allocated size is enough
+
+------------------------------------------------------------------------
+r1004 | zimmerma | 2001-02-18 12:12:52 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+updated specification of mpfr_sgn
+
+------------------------------------------------------------------------
+r1003 | zimmerma | 2001-02-18 12:12:35 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+changed definition of mpfr_sgn to get rid of MPFR_NOTZERO
+
+------------------------------------------------------------------------
+r1002 | zimmerma | 2001-02-18 12:12:21 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/out_str.c
+
+size of freed block by __gmp_free_func was wrong
+
+------------------------------------------------------------------------
+r1001 | zimmerma | 2001-02-18 12:11:59 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added tisnan and tget_d
+
+------------------------------------------------------------------------
+r1000 | zimmerma | 2001-02-18 12:11:40 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/isnan.c
+
+fixed bug for Inf (recognized as an ordinary number)
+
+------------------------------------------------------------------------
+r999 | zimmerma | 2001-02-18 12:11:25 +0000 (Sun, 18 Feb 2001) | 2 lines
+Changed paths:
+ A /trunk/tests/tget_d.c
+ A /trunk/tests/tisnan.c
+
+new test file
+
+------------------------------------------------------------------------
+r998 | zimmerma | 2001-02-16 10:18:33 +0000 (Fri, 16 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+check overflow in _mpfr_ceil_exp2
+
+------------------------------------------------------------------------
+r997 | zimmerma | 2001-02-15 22:19:58 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+added prototype for Ulp
+
+------------------------------------------------------------------------
+r996 | zimmerma | 2001-02-15 22:19:42 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/isnan.c
+
+changed _d to _p, added mpfr_number_p
+
+------------------------------------------------------------------------
+r995 | zimmerma | 2001-02-15 22:19:16 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+changed MPN_COPY into MPN_COPY_INCR/MPN_COPY_DECR in mpfr_round_raw
+
+------------------------------------------------------------------------
+r994 | zimmerma | 2001-02-15 22:18:55 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+added tests for one of arguments NULL
+
+------------------------------------------------------------------------
+r993 | zimmerma | 2001-02-15 22:18:16 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+moved mpfr_sgn to mpfr.h (defined in manual)
+
+------------------------------------------------------------------------
+r992 | zimmerma | 2001-02-15 22:17:58 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/mpz_set_fr.c
+
+use MPZ_REALLOC
+
+------------------------------------------------------------------------
+r991 | zimmerma | 2001-02-15 22:17:41 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/set_str.c
+
+added const to 2nd argument of mpfr_set_str
+
+------------------------------------------------------------------------
+r990 | zimmerma | 2001-02-15 22:17:10 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added set_ui.c
+
+------------------------------------------------------------------------
+r989 | zimmerma | 2001-02-15 22:16:44 +0000 (Thu, 15 Feb 2001) | 3 lines
+Changed paths:
+ M /trunk/set_si.c
+ A /trunk/set_ui.c
+
+added cast to "unsigned long" for ai = ABS(i)
+moved mpfr_set_ui to separate file
+
+------------------------------------------------------------------------
+r988 | zimmerma | 2001-02-15 22:16:04 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/mpfr.texi
+
+now when str==NULL return a block which is exactly strlen(str)+1 bytes long
+
+------------------------------------------------------------------------
+r987 | zimmerma | 2001-02-15 22:15:38 +0000 (Thu, 15 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/agm.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/generic.c
+ M /trunk/log2.c
+ M /trunk/pi.c
+ M /trunk/print_raw.c
+ M /trunk/set_d.c
+ M /trunk/sin_cos.c
+ M /trunk/sub.c
+
+fixed problems with old K&R compilers (_PROTO missing)
+
+------------------------------------------------------------------------
+r986 | zimmerma | 2001-02-08 12:56:50 +0000 (Thu, 08 Feb 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added more items
+
+------------------------------------------------------------------------
+r985 | zimmerma | 2001-01-23 16:11:30 +0000 (Tue, 23 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+fixed ulp computation
+
+------------------------------------------------------------------------
+r984 | zimmerma | 2001-01-19 16:20:33 +0000 (Fri, 19 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+changed behaviour for "tlog N": prints only differences with increasing ulps
+
+------------------------------------------------------------------------
+r983 | zimmerma | 2001-01-19 09:55:11 +0000 (Fri, 19 Jan 2001) | 4 lines
+Changed paths:
+ M /trunk/set_d.c
+
+fixed pb in mpfr_get_d2 for 64-bit machines: in q + res/MP_BASE_AS_DOUBLE,
+q seems first to be cast into a double, which gives more than one ulp of
+error
+
+------------------------------------------------------------------------
+r982 | zimmerma | 2001-01-18 16:08:34 +0000 (Thu, 18 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added guard to prevent multiple inclusion
+
+------------------------------------------------------------------------
+r981 | zimmerma | 2001-01-18 08:42:27 +0000 (Thu, 18 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+fixed bug in mpfr_cmp2 (found on the IA64)
+
+------------------------------------------------------------------------
+r980 | zimmerma | 2001-01-11 17:26:02 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+added tests for 0 in mpfr_set_str_raw
+
+------------------------------------------------------------------------
+r979 | zimmerma | 2001-01-11 17:25:28 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+fixed bug for +0000E0
+
+------------------------------------------------------------------------
+r978 | zimmerma | 2001-01-11 16:53:48 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/sqrtrem.c
+
+incorporated changes from Kevin/Torbjorn for GMP 3.2
+
+------------------------------------------------------------------------
+r977 | zimmerma | 2001-01-11 16:46:03 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+truncate the last uk (when the precision is not a power of 2)
+
+------------------------------------------------------------------------
+r976 | zimmerma | 2001-01-11 16:45:01 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+_mp_allocate_func -> _gmp_allocate_func
+
+------------------------------------------------------------------------
+r975 | zimmerma | 2001-01-11 16:44:24 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/set_prec.c
+
+_mp_reallocate_func -> _gmp_reallocate_func
+
+------------------------------------------------------------------------
+r974 | zimmerma | 2001-01-11 16:44:04 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/set_dfl_prec.c
+
+__gmp_default_fp_bit_precision -> __mpfr_default_fp_bit_precision
+
+------------------------------------------------------------------------
+r973 | zimmerma | 2001-01-11 16:43:37 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/print_raw.c
+ M /trunk/round.c
+
+_mp_xxx_func -> _gmp_xxx_func
+
+------------------------------------------------------------------------
+r972 | zimmerma | 2001-01-11 16:43:16 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+removed mpfr_srandom
+
+------------------------------------------------------------------------
+r971 | zimmerma | 2001-01-11 16:42:09 +0000 (Thu, 11 Jan 2001) | 3 lines
+Changed paths:
+ M /trunk/out_str.c
+
+sprintf -> fprintf
+_mp_free_func -> _gmp_free_func
+
+------------------------------------------------------------------------
+r970 | zimmerma | 2001-01-11 16:41:33 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/mpz_set_fr.c
+
+_mp_reallocate_func -> __gmp_reallocate_func
+
+------------------------------------------------------------------------
+r969 | zimmerma | 2001-01-11 16:41:09 +0000 (Thu, 11 Jan 2001) | 4 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added paragraph on NaN and infinities, docu on mpfr_nan_d and mpfr_inf_d
+removed mpfr_srandom
+some renamings
+
+------------------------------------------------------------------------
+r968 | zimmerma | 2001-01-11 16:39:50 +0000 (Thu, 11 Jan 2001) | 4 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+removed srandom
+__gmp_default_fp_bit_precision -> __mpfr_default_fp_bit_precision
+added protocols for mpfr_get_default_prec, mpfr_nan_d and mpfr_inf_d
+
+------------------------------------------------------------------------
+r967 | zimmerma | 2001-01-11 16:38:40 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+removed superfluous TMP_FREE(marker)
+
+------------------------------------------------------------------------
+r966 | zimmerma | 2001-01-11 16:37:52 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/generic.c
+ M /trunk/get_str.c
+ M /trunk/init.c
+ M /trunk/inp_str.c
+
+_mp_xxx_func -> _gmp_xxx_func
+
+------------------------------------------------------------------------
+r965 | zimmerma | 2001-01-11 16:22:41 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/clear.c
+ M /trunk/dump.c
+
+_mp_free_func -> _gmp_free_func
+
+------------------------------------------------------------------------
+r964 | zimmerma | 2001-01-11 16:21:43 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ A /trunk/isnan.c
+
+functions to check for NaN and infinities
+
+------------------------------------------------------------------------
+r963 | zimmerma | 2001-01-11 16:21:14 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added isnan.c, removed srandom.h
+
+------------------------------------------------------------------------
+r962 | zimmerma | 2001-01-11 16:19:06 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added two items from Kevin
+
+------------------------------------------------------------------------
+r961 | zimmerma | 2001-01-11 16:17:44 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+add 2 items
+
+------------------------------------------------------------------------
+r960 | zimmerma | 2001-01-11 16:17:31 +0000 (Thu, 11 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+0.4 -> 1.0
+
+------------------------------------------------------------------------
+r959 | zimmerma | 2001-01-05 16:24:25 +0000 (Fri, 05 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added one test for large operands
+
+------------------------------------------------------------------------
+r958 | zimmerma | 2001-01-05 16:23:34 +0000 (Fri, 05 Jan 2001) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+fixed bug in _mpfr_ceil_exp2 (underflow when exp < -1022)
+
+------------------------------------------------------------------------
+r957 | zimmerma | 2000-12-22 16:49:12 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+remove what was done
+
+------------------------------------------------------------------------
+r956 | zimmerma | 2000-12-22 16:48:24 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/README
+
+added mpfr-test.h
+
+------------------------------------------------------------------------
+r955 | zimmerma | 2000-12-22 16:44:51 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+added Vincent
+
+------------------------------------------------------------------------
+r954 | zimmerma | 2000-12-22 16:41:28 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/NEWS
+
+1.1 -> 2001
+
+------------------------------------------------------------------------
+r953 | zimmerma | 2000-12-22 16:17:45 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+cast for _mpfr_floor_log2 was on the wrong side
+
+------------------------------------------------------------------------
+r952 | zimmerma | 2000-12-22 16:17:09 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+added one test
+
+------------------------------------------------------------------------
+r951 | zimmerma | 2000-12-22 16:16:54 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+simplified _mpfr_floor_log2
+
+------------------------------------------------------------------------
+r950 | zimmerma | 2000-12-22 16:16:35 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+code was wrong for infinity
+
+------------------------------------------------------------------------
+r949 | zimmerma | 2000-12-22 15:45:22 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+only editing
+
+------------------------------------------------------------------------
+r948 | zimmerma | 2000-12-22 15:45:04 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added special() cases
+
+------------------------------------------------------------------------
+r947 | zimmerma | 2000-12-22 15:42:49 +0000 (Fri, 22 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/log2.c
+
+removed #if 0 (on Alpha with cc the enclosed code was still used
+since the # was not in the first column)
+
+------------------------------------------------------------------------
+r946 | zimmerma | 2000-12-22 14:55:42 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+changes for version 1.1
+
+------------------------------------------------------------------------
+r945 | zimmerma | 2000-12-22 14:52:02 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added one test (exp2 vs exp3)
+
+------------------------------------------------------------------------
+r944 | zimmerma | 2000-12-22 14:51:00 +0000 (Fri, 22 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/exp2.c
+
+changed c from mp_limb_t into unsigned long in mpfr_exp2_aux2
+(otherwise bugs on IRIX -n32)
+
+------------------------------------------------------------------------
+r943 | zimmerma | 2000-12-22 12:22:13 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tpow.c
+
+added one test
+
+------------------------------------------------------------------------
+r942 | zimmerma | 2000-12-22 12:21:56 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+fixed wrong combination of conditions for Infinity
+
+------------------------------------------------------------------------
+r941 | zimmerma | 2000-12-22 12:10:49 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+added mpfr-test.h for MIPS
+
+------------------------------------------------------------------------
+r940 | hanrot | 2000-12-22 10:47:43 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.in
+
+Modified macro calls
+
+------------------------------------------------------------------------
+r939 | zimmerma | 2000-12-22 09:29:05 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+added cast (int) to random() to avoid warning on Solaris
+
+------------------------------------------------------------------------
+r938 | zimmerma | 2000-12-22 09:07:59 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+added <string.h>
+
+------------------------------------------------------------------------
+r937 | zimmerma | 2000-12-22 08:57:57 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrtrem.c
+
+tiny change at the end of main routine (suggested by Guillaume)
+
+------------------------------------------------------------------------
+r936 | zimmerma | 2000-12-22 08:54:56 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+added one test
+
+------------------------------------------------------------------------
+r935 | zimmerma | 2000-12-22 08:53:59 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added two more tests
+
+------------------------------------------------------------------------
+r934 | zimmerma | 2000-12-22 08:53:25 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed bug when c does not overlap with a, b is negative and GMP_RNDN
+
+------------------------------------------------------------------------
+r933 | zimmerma | 2000-12-22 08:52:20 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+
+moved prototypes for mpfr_set4 and mpfr_cmp3 to mpfr.h
+
+------------------------------------------------------------------------
+r932 | zimmerma | 2000-12-22 08:51:40 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+fixed bug in mpfr_cmp2 when d=0 and lots of bits match
+
+------------------------------------------------------------------------
+r931 | zimmerma | 2000-12-22 08:50:43 +0000 (Fri, 22 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/NEWS
+
+updated for version 1.1
+
+------------------------------------------------------------------------
+r930 | zimmerma | 2000-12-21 17:23:51 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/tpow.c
+
+test file for power functions
+
+------------------------------------------------------------------------
+r929 | zimmerma | 2000-12-21 17:22:42 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/reuse.c
+
+test file for in-place operations
+
+------------------------------------------------------------------------
+r928 | zimmerma | 2000-12-21 17:17:51 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+unsigned char (or int) -> mp_rnd_t
+
+------------------------------------------------------------------------
+r927 | zimmerma | 2000-12-21 17:12:14 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+unsigned char -> mp_rnd_t
+
+------------------------------------------------------------------------
+r926 | zimmerma | 2000-12-21 17:11:31 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+unsigned int -> mp_rnd_t
+
+------------------------------------------------------------------------
+r925 | zimmerma | 2000-12-21 17:08:38 +0000 (Thu, 21 Dec 2000) | 4 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/add_ui.c
+ M /trunk/agm.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/div.c
+ M /trunk/div_ui.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/get_str.c
+ M /trunk/inp_str.c
+ M /trunk/log.c
+ M /trunk/log2.c
+ M /trunk/out_str.c
+ M /trunk/pi.c
+ M /trunk/pow.c
+ M /trunk/print_raw.c
+ M /trunk/reldiff.c
+ M /trunk/set_d.c
+ M /trunk/sin_cos.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub.c
+ M /trunk/sub_ui.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/trunc.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+
+k2r -> ansi style
+removed #include <math.h> by defining auxiliary functions
+fixed several tiny remaining bugs with NaN/Inf
+
+------------------------------------------------------------------------
+r924 | zimmerma | 2000-12-21 17:07:12 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+updated description of mpfr_cmp* and mpfr_sin_cos
+
+------------------------------------------------------------------------
+r923 | zimmerma | 2000-12-21 17:06:15 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added MPFR_SIGN
+
+------------------------------------------------------------------------
+r922 | zimmerma | 2000-12-21 17:05:49 +0000 (Thu, 21 Dec 2000) | 5 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+added MPFR_CLEAR_NAN
+MPFR_RESET_INF -> MPFR_CLEAR_INF
+moved MPFR_SIGN to mpfr.h
+added prototypes for log2/isqrt/cuberoot functions
+
+------------------------------------------------------------------------
+r921 | zimmerma | 2000-12-21 17:04:24 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added reuse, tcmp2, teq, tpow, trandom, ttrunc
+
+------------------------------------------------------------------------
+r920 | zimmerma | 2000-12-21 17:02:25 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+removed isnan(), ...
+
+------------------------------------------------------------------------
+r919 | zimmerma | 2000-12-21 17:00:59 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt_ui.c
+
+removed gmp-impl.h, isnan(), ...
+
+------------------------------------------------------------------------
+r918 | zimmerma | 2000-12-21 17:00:21 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+removed gmp-impl, isnan(), ...
+
+------------------------------------------------------------------------
+r917 | zimmerma | 2000-12-21 16:59:24 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+removed cputime stuff
+
+------------------------------------------------------------------------
+r916 | zimmerma | 2000-12-21 16:58:24 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tset_z.c
+
+k&r -> ansi style
+
+------------------------------------------------------------------------
+r915 | zimmerma | 2000-12-21 16:57:08 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tout_str.c
+
+removed isnan() decl.
+
+------------------------------------------------------------------------
+r914 | zimmerma | 2000-12-21 16:55:30 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+MINNORM -> mpfr-test.h
+
+------------------------------------------------------------------------
+r913 | zimmerma | 2000-12-21 16:52:57 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+ulp -> mpfr-test.h
+
+------------------------------------------------------------------------
+r912 | zimmerma | 2000-12-21 16:51:36 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv_ui.c
+
+removed isnan() declaration
+
+------------------------------------------------------------------------
+r911 | zimmerma | 2000-12-21 16:50:48 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+now use MINNORM and MAXNORM
+
+------------------------------------------------------------------------
+r910 | zimmerma | 2000-12-21 16:49:00 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+max, min -> macros
+
+------------------------------------------------------------------------
+r909 | zimmerma | 2000-12-21 12:10:49 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added new tests
+
+------------------------------------------------------------------------
+r908 | zimmerma | 2000-12-21 12:07:52 +0000 (Thu, 21 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+added MINNORM, MAXNORM, MIN, MAX, ABS
+
+------------------------------------------------------------------------
+r907 | hanrot | 2000-12-20 16:36:05 +0000 (Wed, 20 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+ M /trunk/tests/tset_str.c
+
+A few basic patches.
+
+------------------------------------------------------------------------
+r906 | hanrot | 2000-12-20 16:35:55 +0000 (Wed, 20 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+Added support for PPC/Linux
+
+------------------------------------------------------------------------
+r905 | hanrot | 2000-12-20 14:54:10 +0000 (Wed, 20 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr-test.h
+
+Patch for wrong prototype.
+
+------------------------------------------------------------------------
+r904 | hanrot | 2000-12-20 10:49:00 +0000 (Wed, 20 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/configure
+ M /trunk/cputime.h
+ M /trunk/mpfr-test.h
+ M /trunk/tests/Makefile.in
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+Added prototypes for all test files.
+
+------------------------------------------------------------------------
+r903 | vlefevre | 2000-12-18 15:07:51 +0000 (Mon, 18 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/add_ulp.c
+ M /trunk/extract.c
+ M /trunk/mpz_set_fr.c
+ M /trunk/set_d.c
+ M /trunk/set_q.c
+ M /trunk/set_z.c
+
+Warnings suppressed on Alpha/OSF1.
+
+------------------------------------------------------------------------
+r902 | zimmerma | 2000-12-18 09:44:06 +0000 (Mon, 18 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added mpfr-test.h
+
+------------------------------------------------------------------------
+r901 | zimmerma | 2000-12-18 09:40:46 +0000 (Mon, 18 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/aclocal.m4
+
+back to 1.3
+
+------------------------------------------------------------------------
+r900 | zimmerma | 2000-12-18 09:06:50 +0000 (Mon, 18 Dec 2000) | 2 lines
+Changed paths:
+ A /trunk/mpfr-test.h
+
+auxiliary test files
+
+------------------------------------------------------------------------
+r899 | zimmerma | 2000-12-18 09:06:34 +0000 (Mon, 18 Dec 2000) | 2 lines
+Changed paths:
+ D /trunk/tests/mpfr-test.h
+
+moved to main directory
+
+------------------------------------------------------------------------
+r898 | zimmerma | 2000-12-18 09:02:54 +0000 (Mon, 18 Dec 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/mpfr-test.h
+
+auxiliary test functions
+
+------------------------------------------------------------------------
+r897 | zimmerma | 2000-12-18 09:02:00 +0000 (Mon, 18 Dec 2000) | 5 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/aclocal.m4
+ M /trunk/add.c
+ M /trunk/add_ui.c
+ M /trunk/add_ulp.c
+ M /trunk/agm.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/configure
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eq.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/extract.c
+ M /trunk/generic.c
+ M /trunk/get_str.c
+ M /trunk/init.c
+ M /trunk/log.c
+ M /trunk/log2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pi.c
+ M /trunk/pow.c
+ M /trunk/print_raw.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/round.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_f.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_z.c
+ M /trunk/sin_cos.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sqrtrem.c
+ M /trunk/sub.c
+ M /trunk/sub_ui.c
+ M /trunk/swap.c
+ M /trunk/tests/Makefile.in
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/trunc.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+
+changed name of mpfr struct fields: _mp_d -> _mpfr_d
+ (to detect conflicts with mpf)
+fixed a few problems in non-STDC headers
+moved definitions of mpfr-impl.h to mpfr-test.h and created a real mpfr-impl.h
+
+------------------------------------------------------------------------
+r896 | zimmerma | 2000-12-15 17:46:34 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+removed tzeta
+
+------------------------------------------------------------------------
+r895 | zimmerma | 2000-12-15 17:42:59 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+explained how to enter NaN/Inf with mpfr_set_str_raw
+
+------------------------------------------------------------------------
+r894 | zimmerma | 2000-12-15 17:42:21 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+removed zeta.c
+
+------------------------------------------------------------------------
+r893 | zimmerma | 2000-12-15 17:40:47 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+added 'to do' for NaN/Inf flags
+
+------------------------------------------------------------------------
+r892 | zimmerma | 2000-12-15 17:39:14 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/urandomb.c
+
+clear NaN/Inf flags of result
+
+------------------------------------------------------------------------
+r891 | zimmerma | 2000-12-15 17:37:33 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/ui_sub.c
+
+improved indentation
+
+------------------------------------------------------------------------
+r890 | zimmerma | 2000-12-15 17:35:00 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/trunc.c
+ M /trunk/ui_div.c
+
+adapted to NaN/Inf
+
+------------------------------------------------------------------------
+r889 | zimmerma | 2000-12-15 17:29:01 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sub_ui.c
+
+nothing (only better indenting)
+
+------------------------------------------------------------------------
+r888 | zimmerma | 2000-12-15 17:27:03 +0000 (Fri, 15 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/sub.c
+
+adapted to NaN/Inf
+removed warnings
+
+------------------------------------------------------------------------
+r887 | zimmerma | 2000-12-15 17:21:32 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrt_ui.c
+
+adapted to NaN/Inf
+
+------------------------------------------------------------------------
+r886 | zimmerma | 2000-12-15 17:20:55 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/generic.c
+ M /trunk/sin_cos.c
+
+removed warnings
+
+------------------------------------------------------------------------
+r885 | zimmerma | 2000-12-15 17:11:49 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+clear NaN/Inf flags in normal case
+
+------------------------------------------------------------------------
+r884 | zimmerma | 2000-12-15 17:06:11 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+ M /trunk/set_z.c
+
+adapted to NaN/Inf
+
+------------------------------------------------------------------------
+r883 | zimmerma | 2000-12-15 16:55:19 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for mpfr_srandom
+
+------------------------------------------------------------------------
+r882 | zimmerma | 2000-12-15 16:54:50 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+now uses directly mpn_random, to avoid all problems with include files
+
+------------------------------------------------------------------------
+r881 | zimmerma | 2000-12-15 16:45:41 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsin_cos.c
+
+added 4 tests
+
+------------------------------------------------------------------------
+r880 | zimmerma | 2000-12-15 16:45:05 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub_ui.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+
+_mp_d -> MPFR_MANT
+
+------------------------------------------------------------------------
+r879 | zimmerma | 2000-12-15 16:41:07 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/set_prec.c
+ M /trunk/set_str_raw.c
+
+added error message when memory allocation fails
+
+------------------------------------------------------------------------
+r878 | zimmerma | 2000-12-15 16:27:51 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/inp_str.c
+ M /trunk/mpz_set_fr.c
+ M /trunk/print_raw.c
+ M /trunk/round.c
+
+added error message when memory allocation fails
+
+------------------------------------------------------------------------
+r877 | zimmerma | 2000-12-15 16:26:53 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/eq.c
+ M /trunk/log.c
+
+_mp_d -> MPFR_MANT
+
+------------------------------------------------------------------------
+r876 | zimmerma | 2000-12-15 16:26:09 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/init.c
+
+0 -> NULL
+
+------------------------------------------------------------------------
+r875 | zimmerma | 2000-12-15 16:25:14 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/generic.c
+
+added error message if memory allocation fails
+
+------------------------------------------------------------------------
+r874 | zimmerma | 2000-12-15 16:24:35 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+_mp_d -> PTR
+
+------------------------------------------------------------------------
+r873 | zimmerma | 2000-12-15 16:23:08 +0000 (Fri, 15 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/agm.c
+
+_mp_prec -> MPFR_PREC
+_mp_d -> MPFR_MANT
+
+------------------------------------------------------------------------
+r872 | zimmerma | 2000-12-15 16:18:53 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+ M /trunk/mpfr.h
+
+added mpfr_swap
+
+------------------------------------------------------------------------
+r871 | zimmerma | 2000-12-15 15:09:30 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+removed MPFR_SET_IS_FP (not used)
+
+------------------------------------------------------------------------
+r870 | hanrot | 2000-12-15 14:42:57 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/init.c
+ M /trunk/log.c
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/pow.c
+
+A few patches.
+
+------------------------------------------------------------------------
+r869 | vlefevre | 2000-12-15 14:36:22 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+MPFR_CHANGE_SIGN modified to avoid a possible side effect.
+
+------------------------------------------------------------------------
+r868 | zimmerma | 2000-12-15 14:24:11 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+
+warning: x is a MPF not a MPFR!
+
+------------------------------------------------------------------------
+r867 | hanrot | 2000-12-15 14:12:30 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+Modification of the order of includes in random.c
+
+------------------------------------------------------------------------
+r866 | vlefevre | 2000-12-15 12:56:19 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/configure
+ M /trunk/configure.in
+ M /trunk/tests/Makefile.in
+
+Added some warning flags for GCC.
+
+------------------------------------------------------------------------
+r865 | hanrot | 2000-12-15 12:50:28 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ A /trunk/srandom.h
+
+Header file for srandom()
+
+------------------------------------------------------------------------
+r864 | hanrot | 2000-12-15 12:21:35 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/add_ulp.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/mpfr.h
+ M /trunk/pow.c
+ M /trunk/random.c
+
+Patches for compiler warnings.
+
+------------------------------------------------------------------------
+r863 | hanrot | 2000-12-15 11:16:40 +0000 (Fri, 15 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/add_ui.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/div.c
+ M /trunk/get_str.c
+ M /trunk/log2.c
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul_ui.c
+ M /trunk/pi.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/set_d.c
+ M /trunk/set_f.c
+ M /trunk/set_q.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_z.c
+ M /trunk/sub_ui.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/zeta.c
+
+Yet another patch for include files.
+
+------------------------------------------------------------------------
+r862 | hanrot | 2000-12-15 11:05:55 +0000 (Fri, 15 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/add_ui.c
+ M /trunk/add_ulp.c
+ M /trunk/agm.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eq.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/extract.c
+ M /trunk/get_str.c
+ M /trunk/init.c
+ M /trunk/inp_str.c
+ M /trunk/log.c
+ M /trunk/log2.c
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pi.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/round.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_f.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_z.c
+ M /trunk/sin_cos.c
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+ M /trunk/sub_ui.c
+ M /trunk/swap.c
+ M /trunk/trunc.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/zeta.c
+
+Permutation of includes to avoid warnings due to careless multiple definition
+of ULONG_MAX.
+
+------------------------------------------------------------------------
+r861 | vlefevre | 2000-12-14 17:47:12 +0000 (Thu, 14 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+ M /trunk/set.c
+ M /trunk/set_f.c
+
+Bug fixed concerning the flags.
+
+------------------------------------------------------------------------
+r860 | vlefevre | 2000-12-14 17:28:41 +0000 (Thu, 14 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/set_str.c
+
+Bugs fixed (in case char is signed and accented characters are given).
+
+------------------------------------------------------------------------
+r859 | vlefevre | 2000-12-14 17:02:11 +0000 (Thu, 14 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+Include "urandom.h". Old code removed.
+
+------------------------------------------------------------------------
+r858 | vlefevre | 2000-12-14 15:28:28 +0000 (Thu, 14 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/reldiff.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_f.c
+ M /trunk/set_q.c
+ M /trunk/set_si.c
+
+Take into account Inf, Nans ; clear the flags of the return variable
+in most function calls.
+
+------------------------------------------------------------------------
+r857 | vlefevre | 2000-12-14 14:36:09 +0000 (Thu, 14 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+Use urandom().
+
+------------------------------------------------------------------------
+r856 | vlefevre | 2000-12-14 14:29:04 +0000 (Thu, 14 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+
+Take into account Inf, Nans ; clear the flags of the return variable
+in most function calls.
+
+------------------------------------------------------------------------
+r855 | hanrot | 2000-12-14 12:14:57 +0000 (Thu, 14 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+Yet another random patch.
+
+------------------------------------------------------------------------
+r854 | hanrot | 2000-12-14 12:08:44 +0000 (Thu, 14 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+Replaced random by rand.
+
+------------------------------------------------------------------------
+r853 | zimmerma | 2000-12-13 14:55:24 +0000 (Wed, 13 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+fixed pb with mp_ptr vs mp_srcptr
+
+------------------------------------------------------------------------
+r852 | hanrot | 2000-12-13 14:50:26 +0000 (Wed, 13 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/tests/Makefile.in
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tsin_cos.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+Take into account Inf, Nans ; clear the flags of the return variable
+in most function calls. Tests updated accordingly
+
+------------------------------------------------------------------------
+r851 | hanrot | 2000-12-13 14:50:13 +0000 (Wed, 13 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/eq.c
+ M /trunk/generic.c
+ M /trunk/inp_str.c
+ M /trunk/log.c
+ M /trunk/log2.c
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/pi.c
+ M /trunk/pow.c
+ M /trunk/set_d.c
+ M /trunk/sub_ui.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+
+Take into account Inf, Nans ; clear the flags of the return variable
+in most function calls.
+
+------------------------------------------------------------------------
+r850 | zimmerma | 2000-12-13 08:42:38 +0000 (Wed, 13 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+check that we can round the cosine too
+
+------------------------------------------------------------------------
+r849 | zimmerma | 2000-12-12 16:40:05 +0000 (Tue, 12 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/exp3.c
+
+removed TIMING stuff
+ensures prec_x >= 0
+
+------------------------------------------------------------------------
+r848 | zimmerma | 2000-12-12 16:38:47 +0000 (Tue, 12 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+we need m >= 2 in mpfr_exp2_aux2
+
+------------------------------------------------------------------------
+r847 | zimmerma | 2000-12-12 13:57:34 +0000 (Tue, 12 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sub_ui.c
+
+forgot TMP_MARK(marker)
+
+------------------------------------------------------------------------
+r846 | zimmerma | 2000-12-12 13:50:44 +0000 (Tue, 12 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+
+forgot TMP_MARK(marker) or free'd in wrong order
+
+------------------------------------------------------------------------
+r845 | zimmerma | 2000-12-12 13:44:07 +0000 (Tue, 12 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+
+forgot TMP_MARK(marker)
+
+------------------------------------------------------------------------
+r844 | zimmerma | 2000-12-12 11:49:13 +0000 (Tue, 12 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+fixed mpf_reldiff, mpf_urandomb and mpf_t
+
+------------------------------------------------------------------------
+r843 | zimmerma | 2000-12-12 11:41:28 +0000 (Tue, 12 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+added stack-alloc.h when --disable-alloca
+
+------------------------------------------------------------------------
+r842 | vlefevre | 2000-12-11 12:47:11 +0000 (Mon, 11 Dec 2000) | 4 lines
+Changed paths:
+ M /trunk/out_str.c
+ M /trunk/set_d.c
+
+out_str.c: <string.h> included
+set_d.c: (0./0.) instead of sqrt(-1) for NaN (doesn't need <math.h>)
+set_d.c: () added for macros Infp and Infm
+
+------------------------------------------------------------------------
+r841 | zimmerma | 2000-12-07 13:11:32 +0000 (Thu, 07 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+
+shortened string in mpfr_set_str_raw which was greater than precision
+
+------------------------------------------------------------------------
+r840 | zimmerma | 2000-12-07 11:25:37 +0000 (Thu, 07 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/set_d.c
+
+replaced isnan/isinf/math.h (not portable, for example isinf does not exist
+on Sparc) by new macros from mpfr.h
+
+------------------------------------------------------------------------
+r839 | zimmerma | 2000-12-07 11:24:31 +0000 (Thu, 07 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/set_str_raw.c
+
+added an error message when the mantissa is larger than the precision
+(in mpfr_set_str_raw)
+
+------------------------------------------------------------------------
+r838 | zimmerma | 2000-12-07 11:23:24 +0000 (Thu, 07 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added macros to recognize doubles that are NaNs and infinities
+(isinf is not portable and requires math.h)
+
+------------------------------------------------------------------------
+r837 | zimmerma | 2000-12-07 11:22:04 +0000 (Thu, 07 Dec 2000) | 5 lines
+Changed paths:
+ M /trunk/div.c
+
+in case the destination precision is less than that of the operands,
+and the 1st iteration fails, increase directly the precision to the maximum
+of that of the operands, otherwise divisions by 1.0 may need lots of
+iterations
+
+------------------------------------------------------------------------
+r836 | zimmerma | 2000-12-07 10:44:28 +0000 (Thu, 07 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+added 'return' after dealing with infinities
+
+------------------------------------------------------------------------
+r835 | zimmerma | 2000-12-07 10:37:08 +0000 (Thu, 07 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added wish from JC Fauge`re
+
+------------------------------------------------------------------------
+r834 | zimmerma | 2000-12-05 13:47:05 +0000 (Tue, 05 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/init.c
+ M /trunk/mpfr.texi
+
+mpfr_init/mpfr_init2 initialize to 0 (compatibility with mpf)
+
+------------------------------------------------------------------------
+r833 | zimmerma | 2000-12-05 13:24:43 +0000 (Tue, 05 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+fixed bug in mpfr_cmp2 when return value is k*BITS_PER_MP_LIMB-1
+
+------------------------------------------------------------------------
+r832 | zimmerma | 2000-12-05 13:23:58 +0000 (Tue, 05 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+
+added new test for mpfr_cmp2
+
+------------------------------------------------------------------------
+r831 | zimmerma | 2000-12-05 12:37:14 +0000 (Tue, 05 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+now ABSSIZE uses only 29 bits
+
+------------------------------------------------------------------------
+r830 | zimmerma | 2000-12-04 14:36:36 +0000 (Mon, 04 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added some explanations how to free the memory space allocated by mpfr_get_str
+
+------------------------------------------------------------------------
+r829 | zimmerma | 2000-12-04 13:45:14 +0000 (Mon, 04 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+fixed one bug found by N. Mueller (MPFR_ABSSIZE(u) was used instead of usize)
+
+------------------------------------------------------------------------
+r828 | zimmerma | 2000-12-04 13:44:24 +0000 (Mon, 04 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added one more test from N. Mueller
+
+------------------------------------------------------------------------
+r827 | zimmerma | 2000-12-01 17:30:41 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+ M /trunk/sin_cos.c
+
+cleaned calls to mpfr_extract
+
+------------------------------------------------------------------------
+r826 | zimmerma | 2000-12-01 17:29:33 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added new line
+
+------------------------------------------------------------------------
+r825 | zimmerma | 2000-12-01 17:29:05 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/init.c
+
+added error message when _mp_allocate_func returns 0
+
+------------------------------------------------------------------------
+r824 | zimmerma | 2000-12-01 17:28:22 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added header for mpfr_extract
+
+------------------------------------------------------------------------
+r823 | zimmerma | 2000-12-01 17:27:54 +0000 (Fri, 01 Dec 2000) | 4 lines
+Changed paths:
+ M /trunk/extract.c
+
+- documented what function does
+- cleaned code
+- added header about license...
+
+------------------------------------------------------------------------
+r822 | zimmerma | 2000-12-01 16:25:53 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/get_str.c
+ M /trunk/log2.c
+ M /trunk/mpfr.h
+ M /trunk/pi.c
+ M /trunk/pow.c
+ M /trunk/sin_cos.c
+
+replaced log(2.0) by LOG2 [first step in getting rid of math.h]
+
+------------------------------------------------------------------------
+r821 | zimmerma | 2000-12-01 15:57:33 +0000 (Fri, 01 Dec 2000) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added extern "C" { ... } for inclusion in C++
+removed old KARATSUBA threshold for gmp 2.0.2
+
+------------------------------------------------------------------------
+r820 | zimmerma | 2000-12-01 14:58:32 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+ M /trunk/cmp.c
+ M /trunk/tests/tcmp.c
+
+fixed bug in mpfr_cmp3 (when b=0, s not taken into account)
+
+------------------------------------------------------------------------
+r819 | zimmerma | 2000-12-01 14:30:41 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/tests/Makefile.am
+
+added swap/tswap
+
+------------------------------------------------------------------------
+r818 | zimmerma | 2000-12-01 14:29:36 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/tswap.c
+
+test file for new function mpfr_swap
+
+------------------------------------------------------------------------
+r817 | zimmerma | 2000-12-01 14:29:28 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ A /trunk/swap.c
+
+added new function mpfr_swap
+
+------------------------------------------------------------------------
+r816 | zimmerma | 2000-12-01 13:59:45 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/add_ui.c
+ M /trunk/add_ulp.c
+ M /trunk/agm.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_ui.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/generic.c
+ M /trunk/get_str.c
+ M /trunk/init.c
+ M /trunk/log.c
+ M /trunk/log2.c
+ M /trunk/mpfi.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pi.c
+ M /trunk/pow.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/reldiff.c
+ M /trunk/rnd_mode.c
+ M /trunk/round.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_f.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_rnd.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_z.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sqrtrem.c
+ M /trunk/sub.c
+ M /trunk/sub_ui.c
+ M /trunk/tests/Makefile.in
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/tdump.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpi.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/tround.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/ttrunc.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+ M /trunk/tests/tzeta.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/zeta.c
+
+changed copyright to Free Software Foundation
+
+------------------------------------------------------------------------
+r815 | zimmerma | 2000-12-01 13:57:39 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added possible bug in mpfr_get_str
+
+------------------------------------------------------------------------
+r814 | zimmerma | 2000-12-01 13:55:36 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ D /trunk/init_set.h
+
+now all is in mpfr.h
+
+------------------------------------------------------------------------
+r813 | zimmerma | 2000-12-01 13:00:22 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+return value was wrong for input non-zero (should return 1 = inexact)
+
+------------------------------------------------------------------------
+r812 | zimmerma | 2000-12-01 12:59:15 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed/improved doc. of mpfr_sin_cos and mpfr_urandomb
+
+------------------------------------------------------------------------
+r811 | zimmerma | 2000-12-01 12:58:38 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+removed macro for mpfr_init_set_str_raw
+
+------------------------------------------------------------------------
+r810 | zimmerma | 2000-12-01 12:21:43 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for mpfr_sin_cos
+
+------------------------------------------------------------------------
+r809 | zimmerma | 2000-12-01 11:06:39 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+sign of result was not correctly (re)set
+
+------------------------------------------------------------------------
+r808 | zimmerma | 2000-12-01 11:05:29 +0000 (Fri, 01 Dec 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added test to check sign of square root
+
+------------------------------------------------------------------------
+r807 | zimmerma | 2000-11-29 16:36:15 +0000 (Wed, 29 Nov 2000) | 3 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+gained a factor of 2 in most cases (replaced initial constant factor=2
+for additional bits for cos(x) by log(n))
+
+------------------------------------------------------------------------
+r806 | zimmerma | 2000-11-29 16:34:14 +0000 (Wed, 29 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added tsin_cos
+
+------------------------------------------------------------------------
+r805 | zimmerma | 2000-11-29 16:29:28 +0000 (Wed, 29 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed potential problem in mpfr_sub1 (k=0 and kc<0)
+
+------------------------------------------------------------------------
+r804 | zimmerma | 2000-11-29 16:28:21 +0000 (Wed, 29 Nov 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/tsin_cos.c
+
+test file for sin/cos
+
+------------------------------------------------------------------------
+r803 | zimmerma | 2000-11-28 10:42:05 +0000 (Tue, 28 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+forgot cast to int before comparison between imax (can be negative) and an
+
+------------------------------------------------------------------------
+r802 | zimmerma | 2000-11-28 10:41:12 +0000 (Tue, 28 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+returned value was one too small in case d=1
+
+------------------------------------------------------------------------
+r801 | zimmerma | 2000-11-28 10:40:33 +0000 (Tue, 28 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added new test from N. Mueller
+
+------------------------------------------------------------------------
+r800 | zimmerma | 2000-11-28 10:40:09 +0000 (Tue, 28 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+added return for case of infinities
+
+------------------------------------------------------------------------
+r799 | zimmerma | 2000-11-28 10:27:07 +0000 (Tue, 28 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added macro MPFR_RESET_INF
+
+------------------------------------------------------------------------
+r798 | zimmerma | 2000-11-28 10:25:04 +0000 (Tue, 28 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+don't forget to reset infinity flag if set!
+
+------------------------------------------------------------------------
+r797 | zimmerma | 2000-11-28 08:28:28 +0000 (Tue, 28 Nov 2000) | 3 lines
+Changed paths:
+ M /trunk/cmp.c
+
+fixed bug in mpfr_cmp2: wrong limb considered after cp[cn--] when
+ cp[cn] was not 111...111
+
+------------------------------------------------------------------------
+r796 | zimmerma | 2000-11-28 08:25:14 +0000 (Tue, 28 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed bug when imax>an
+
+------------------------------------------------------------------------
+r795 | zimmerma | 2000-11-27 17:39:00 +0000 (Mon, 27 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added macro MPFR_IS_ZERO
+
+------------------------------------------------------------------------
+r794 | hanrot | 2000-11-21 15:21:39 +0000 (Tue, 21 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+
+Infinis, premiere tentative (tests)
+
+------------------------------------------------------------------------
+r793 | hanrot | 2000-11-21 15:21:33 +0000 (Tue, 21 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/add_ulp.c
+ M /trunk/agm.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/configure
+ M /trunk/div.c
+ M /trunk/div_ui.c
+ M /trunk/dump.c
+ M /trunk/eq.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/extract.c
+ M /trunk/generic.c
+ M /trunk/get_str.c
+ M /trunk/log.c
+ M /trunk/mpfr.h
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/out_str.c
+ M /trunk/pow.c
+ M /trunk/print_raw.c
+ M /trunk/reldiff.c
+ M /trunk/round.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_str_raw.c
+ M /trunk/sin_cos.c
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+ M /trunk/zeta.c
+
+Infinis, premiere tentative.
+
+------------------------------------------------------------------------
+r792 | zimmerma | 2000-11-13 17:13:51 +0000 (Mon, 13 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added one remark from GH
+
+------------------------------------------------------------------------
+r791 | zimmerma | 2000-11-13 17:05:34 +0000 (Mon, 13 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+removed mpfr_cmp2
+
+------------------------------------------------------------------------
+r790 | hanrot | 2000-11-13 15:13:32 +0000 (Mon, 13 Nov 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/aclocal.m4
+
+Added support for Inf. Modified zeta.
+
+------------------------------------------------------------------------
+r789 | zimmerma | 2000-10-26 12:22:07 +0000 (Thu, 26 Oct 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+protection of macros done
+
+------------------------------------------------------------------------
+r788 | zimmerma | 2000-10-26 12:11:59 +0000 (Thu, 26 Oct 2000) | 2 lines
+Changed paths:
+ A /trunk/replace_all
+
+shell-script to replace xxx by yyy in all source files
+
+------------------------------------------------------------------------
+r787 | zimmerma | 2000-10-26 12:11:11 +0000 (Thu, 26 Oct 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/ttrunc.c
+
+protected macros: xxx -> MPFR_xxx
+
+------------------------------------------------------------------------
+r786 | zimmerma | 2000-10-26 11:59:59 +0000 (Thu, 26 Oct 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/add.c
+ M /trunk/add_ui.c
+ M /trunk/add_ulp.c
+ M /trunk/agm.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_ui.c
+ M /trunk/eq.c
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ M /trunk/exp3.c
+ M /trunk/extract.c
+ M /trunk/generic.c
+ M /trunk/get_str.c
+ M /trunk/init.c
+ M /trunk/log.c
+ M /trunk/log2.c
+ M /trunk/mpfi.c
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mpz_set_fr.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pi.c
+ M /trunk/print_raw.c
+ M /trunk/random.c
+ M /trunk/random2.c
+ M /trunk/reldiff.c
+ M /trunk/round.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_f.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/set_q.c
+ M /trunk/set_si.c
+ M /trunk/set_str.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_z.c
+ M /trunk/sin_cos.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt_ui.c
+ M /trunk/sub.c
+ M /trunk/sub_ui.c
+ M /trunk/trunc.c
+ M /trunk/ui_div.c
+ M /trunk/ui_sub.c
+ M /trunk/urandomb.c
+ M /trunk/zeta.c
+
+protected all macros: xxx -> MPFR_xxx
+
+------------------------------------------------------------------------
+r785 | zimmerma | 2000-10-24 11:59:35 +0000 (Tue, 24 Oct 2000) | 2 lines
+Changed paths:
+ A /trunk/mpfi.h
+
+fichier d'include pour mpfi.c
+
+------------------------------------------------------------------------
+r784 | zimmerma | 2000-10-24 11:47:10 +0000 (Tue, 24 Oct 2000) | 2 lines
+Changed paths:
+ A /trunk/mpfi.c
+
+interval arithmetic level (1st version)
+
+------------------------------------------------------------------------
+r783 | zimmerma | 2000-10-24 08:14:07 +0000 (Tue, 24 Oct 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added two suggestions from Ben Hinkle
+
+------------------------------------------------------------------------
+r782 | hanrot | 2000-10-19 12:54:17 +0000 (Thu, 19 Oct 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.in
+
+Bof.
+
+------------------------------------------------------------------------
+r781 | hanrot | 2000-10-19 12:53:54 +0000 (Thu, 19 Oct 2000) | 2 lines
+Changed paths:
+ D /trunk/.pure
+ D /trunk/mmpfr
+ M /trunk/mpfr.h
+
+Suppression de vieilleries.
+
+------------------------------------------------------------------------
+r780 | hanrot | 2000-10-19 09:11:50 +0000 (Thu, 19 Oct 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+1 << 31 -> ((unsigned int)1) << 31.
+
+------------------------------------------------------------------------
+r779 | hanrot | 2000-10-19 08:56:24 +0000 (Thu, 19 Oct 2000) | 2 lines
+Changed paths:
+ M /trunk/dump.c
+ M /trunk/log.c
+ M /trunk/round.c
+ M /trunk/set_d.c
+ M /trunk/set_str.c
+
+Correction de prototypes faux dans le cas ou on n'est pas -D__STDC__.
+
+------------------------------------------------------------------------
+r778 | zimmerma | 2000-10-02 08:44:58 +0000 (Mon, 02 Oct 2000) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+ M /trunk/extract.c
+ M /trunk/generic.c
+ M /trunk/print_raw.c
+ M /trunk/set_str_raw.c
+
+malloc -> *_mp_allocate_func or TMP_ALLOC
+
+------------------------------------------------------------------------
+r777 | zimmerma | 2000-10-02 08:15:41 +0000 (Mon, 02 Oct 2000) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+ M /trunk/init.c
+ M /trunk/mpfr.h
+ M /trunk/round.c
+ M /trunk/set_d.c
+ M /trunk/set_prc_raw.c
+ M /trunk/set_prec.c
+ M /trunk/urandomb.c
+
+mpfr_t -> mpfr_ptr or mpfr_srcptr
+
+------------------------------------------------------------------------
+r776 | zimmerma | 2000-09-29 16:07:46 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ D /trunk/tests/texp2.c
+
+removed -> all is in texp.c
+
+------------------------------------------------------------------------
+r775 | zimmerma | 2000-09-29 16:06:55 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added comparison between exp2 and exp3
+
+------------------------------------------------------------------------
+r774 | zimmerma | 2000-09-29 16:04:47 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+
+take also the target precision into account for the guard bits
+
+------------------------------------------------------------------------
+r773 | zimmerma | 2000-09-29 16:04:19 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/exp2.c
+
+new faster version with O(n^(1/3)*M(n)) algorithm
+
+------------------------------------------------------------------------
+r772 | zimmerma | 2000-09-29 16:03:51 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+adjusted exp2-exp3 threshold for new faster version of mpfr_exp2
+
+------------------------------------------------------------------------
+r771 | zimmerma | 2000-09-29 14:23:59 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added mpz_set_fr.c
+
+------------------------------------------------------------------------
+r770 | zimmerma | 2000-09-29 13:03:23 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+added tdump
+
+------------------------------------------------------------------------
+r769 | zimmerma | 2000-09-29 13:02:47 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed pb for op=0 (added \0 at the end of string)
+
+------------------------------------------------------------------------
+r768 | zimmerma | 2000-09-29 13:02:01 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/dump.c
+
+use strlen to determine memory to free
+
+------------------------------------------------------------------------
+r767 | zimmerma | 2000-09-29 13:01:17 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/tdump.c
+
+test file for mpfr_dump
+
+------------------------------------------------------------------------
+r766 | zimmerma | 2000-09-29 12:30:55 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+removed karasqrt.c, added sqrtrem.c
+
+------------------------------------------------------------------------
+r765 | zimmerma | 2000-09-29 12:30:15 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+kara_sqrtrem -> mpn_sqrtrem_new
+
+------------------------------------------------------------------------
+r764 | zimmerma | 2000-09-29 12:29:56 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ D /trunk/karasqrt.c
+
+now replaced by new code in sqrtrem.c
+
+------------------------------------------------------------------------
+r763 | zimmerma | 2000-09-29 12:29:24 +0000 (Fri, 29 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+now uses new code mpn_sqrtrem_new
+
+------------------------------------------------------------------------
+r762 | zimmerma | 2000-09-29 12:29:02 +0000 (Fri, 29 Sep 2000) | 3 lines
+Changed paths:
+ A /trunk/sqrtrem.c
+
+new version of fast MPN square root
+(should be integrated in a future release of GNU MP)
+
+------------------------------------------------------------------------
+r761 | zimmerma | 2000-09-28 14:06:55 +0000 (Thu, 28 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added another example from N. Mueller
+
+------------------------------------------------------------------------
+r760 | zimmerma | 2000-09-28 14:03:44 +0000 (Thu, 28 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed another ABW bug
+
+------------------------------------------------------------------------
+r759 | zimmerma | 2000-09-28 09:37:20 +0000 (Thu, 28 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed two Array Bound Writes
+
+------------------------------------------------------------------------
+r758 | zimmerma | 2000-09-28 09:36:56 +0000 (Thu, 28 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+fixed one Array Bound Read (to_nearest, bp=cp and k>=cn)
+
+------------------------------------------------------------------------
+r757 | zimmerma | 2000-09-28 09:35:54 +0000 (Thu, 28 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added 2 new tests from Norbert Mueller
+
+------------------------------------------------------------------------
+r756 | zimmerma | 2000-09-27 13:10:43 +0000 (Wed, 27 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added new test
+
+------------------------------------------------------------------------
+r755 | zimmerma | 2000-09-27 13:06:39 +0000 (Wed, 27 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed Array Bound Write
+
+------------------------------------------------------------------------
+r754 | zimmerma | 2000-09-20 11:31:42 +0000 (Wed, 20 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added some words about the inclusion of mpfr.h
+
+------------------------------------------------------------------------
+r753 | zimmerma | 2000-09-20 11:31:11 +0000 (Wed, 20 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+we need to better protect macros
+
+------------------------------------------------------------------------
+r752 | zimmerma | 2000-09-20 10:38:15 +0000 (Wed, 20 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+removed MPFR_OBJECTS (does not work)
+
+------------------------------------------------------------------------
+r751 | zimmerma | 2000-09-20 10:33:16 +0000 (Wed, 20 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added $(MPFR_OBJECTS) in libmpfr_a_LIBADD
+
+------------------------------------------------------------------------
+r750 | zimmerma | 2000-09-20 10:28:29 +0000 (Wed, 20 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+
+added $(MPFR_OBJECTS) in libmpfr_a_DEPENDENCIES
+
+------------------------------------------------------------------------
+r749 | zimmerma | 2000-09-20 10:08:07 +0000 (Wed, 20 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added contributions from Emmanuel Jeandel and Thom Mulders
+
+------------------------------------------------------------------------
+r748 | zimmerma | 2000-09-20 10:03:32 +0000 (Wed, 20 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+added Thom Mulders
+
+------------------------------------------------------------------------
+r747 | zimmerma | 2000-09-20 10:00:31 +0000 (Wed, 20 Sep 2000) | 3 lines
+Changed paths:
+ A /trunk/shortmul.c
+
+routines for naive/fast short multiplication,
+contributed by Thom Mulders (ETH Zu"rich)
+
+------------------------------------------------------------------------
+r746 | zimmerma | 2000-09-19 14:06:06 +0000 (Tue, 19 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv_ui.c
+
+added new test for overlapping x, y
+
+------------------------------------------------------------------------
+r745 | zimmerma | 2000-09-19 14:05:37 +0000 (Tue, 19 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+fixed problem when x=y
+
+------------------------------------------------------------------------
+r744 | zimmerma | 2000-09-14 12:35:42 +0000 (Thu, 14 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added pb from Norbert Muller
+
+------------------------------------------------------------------------
+r743 | zimmerma | 2000-09-14 12:35:16 +0000 (Thu, 14 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed SEGV (mpn_lshift doesn't seem to like src_size=0)
+
+------------------------------------------------------------------------
+r742 | zimmerma | 2000-09-14 12:32:38 +0000 (Thu, 14 Sep 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+now prints "failed" when test file doesn't return 0
+
+------------------------------------------------------------------------
+r741 | zimmerma | 2000-08-29 18:14:19 +0000 (Tue, 29 Aug 2000) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+replaced mpn_divrem by mpn_tdiv_qr for gmp 3 or later
+and avoid copy of one operand when possible
+
+------------------------------------------------------------------------
+r740 | zimmerma | 2000-08-29 12:38:57 +0000 (Tue, 29 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+updated (make check, make install)
+
+------------------------------------------------------------------------
+r739 | zimmerma | 2000-08-29 12:07:24 +0000 (Tue, 29 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/README
+
+described each file
+
+------------------------------------------------------------------------
+r738 | zimmerma | 2000-08-29 11:53:09 +0000 (Tue, 29 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/NEWS
+
+News for version 1.0
+
+------------------------------------------------------------------------
+r737 | zimmerma | 2000-08-25 17:04:05 +0000 (Fri, 25 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed bug for 0.9999999999...
+
+------------------------------------------------------------------------
+r736 | zimmerma | 2000-08-25 16:58:23 +0000 (Fri, 25 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+added test for 0.99999999999999999
+
+------------------------------------------------------------------------
+r735 | zimmerma | 2000-08-24 16:46:56 +0000 (Thu, 24 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added mpfr_swap
+
+------------------------------------------------------------------------
+r734 | zimmerma | 2000-08-24 09:13:21 +0000 (Thu, 24 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/log2.c
+
+now store last computed value together with last rounding mode
+
+------------------------------------------------------------------------
+r733 | zimmerma | 2000-08-23 16:29:19 +0000 (Wed, 23 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+target ps -> mpfr.ps
+
+------------------------------------------------------------------------
+r732 | zimmerma | 2000-08-23 09:56:15 +0000 (Wed, 23 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+added $(srcdir) to trunc.c for sub-directory compilation
+
+------------------------------------------------------------------------
+r731 | zimmerma | 2000-08-16 15:27:56 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/sin_cos.c
+
+removed some memory leaks
+
+------------------------------------------------------------------------
+r730 | zimmerma | 2000-08-16 14:50:40 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/generic.c
+
+solved memory leaks with T[i] and qtoj[i]
+
+------------------------------------------------------------------------
+r729 | zimmerma | 2000-08-16 14:47:22 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+updated (done autoconf, faster mpfr_exp, sin/cos)
+
+------------------------------------------------------------------------
+r728 | zimmerma | 2000-08-16 14:37:43 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+updated for version 1.0
+
+------------------------------------------------------------------------
+r727 | zimmerma | 2000-08-16 14:21:30 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+COPYING.LIB -> COPYING
+
+------------------------------------------------------------------------
+r726 | zimmerma | 2000-08-16 14:20:59 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ A /trunk/COPYING
+
+renamed back (wanted for "make dist")
+
+------------------------------------------------------------------------
+r725 | zimmerma | 2000-08-16 14:20:42 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ D /trunk/COPYING.LIB
+
+renamed back to COPYING (wanted for "make dist")
+
+------------------------------------------------------------------------
+r724 | zimmerma | 2000-08-16 14:18:57 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ A /trunk/COPYING.LIB
+
+GNU Library General Public License
+
+------------------------------------------------------------------------
+r723 | zimmerma | 2000-08-16 14:18:22 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ D /trunk/COPYING
+
+renamed to COPYING.LIB, according to mpfr.texi
+
+------------------------------------------------------------------------
+r722 | zimmerma | 2000-08-16 14:12:40 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/log2.c
+
+result was free'd twice when good=1
+
+------------------------------------------------------------------------
+r721 | zimmerma | 2000-08-16 14:10:10 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/AUTHORS
+
+put information about authors
+
+------------------------------------------------------------------------
+r720 | zimmerma | 2000-08-16 13:50:37 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/configure
+
+PACKAGE and VERSION are not defined any more
+
+------------------------------------------------------------------------
+r719 | zimmerma | 2000-08-16 13:48:39 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+gmp-mparam.h is required too
+
+------------------------------------------------------------------------
+r718 | zimmerma | 2000-08-16 13:33:49 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+IRIX make does not recognize $< (MISCFLAGS)
+
+------------------------------------------------------------------------
+r717 | zimmerma | 2000-08-16 13:00:20 +0000 (Wed, 16 Aug 2000) | 4 lines
+Changed paths:
+ M /trunk/configure.in
+
+do not define PACKAGE and VERSION in AM_INIT_AUTOMAKE,
+this avoids conflicts with GMP 3.1 config.h
+[thanks to Kevin Ryde]
+
+------------------------------------------------------------------------
+r716 | zimmerma | 2000-08-16 12:59:04 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+updated for GMP 3.1
+
+------------------------------------------------------------------------
+r715 | zimmerma | 2000-08-16 12:56:06 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+MP_BASE_AS_DOUBLE already defined in gmp-impl.h
+
+------------------------------------------------------------------------
+r714 | zimmerma | 2000-08-16 11:26:15 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+
+nb_terms[0] was not initialized
+
+------------------------------------------------------------------------
+r713 | zimmerma | 2000-08-16 10:55:11 +0000 (Wed, 16 Aug 2000) | 3 lines
+Changed paths:
+ M /trunk/log2.c
+
+fixed some FNH (free not in heap) problems for binary splitting method
+(prec >= 30000)
+
+------------------------------------------------------------------------
+r712 | zimmerma | 2000-08-16 09:53:54 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+
+gmp.info -> mpfr.info
+
+------------------------------------------------------------------------
+r711 | zimmerma | 2000-08-16 09:46:59 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+
+set_dfl_rnd.* -> set_rnd.* (to avoid conflict with set_dfl_prec.* on DOS 8.3)
+
+------------------------------------------------------------------------
+r710 | zimmerma | 2000-08-16 09:42:43 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ D /trunk/tests/Makefile
+
+now automatically generated by configure
+
+------------------------------------------------------------------------
+r709 | zimmerma | 2000-08-16 09:40:47 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+added if (__GNU_MP_VERSION < 3) for mpn_divrem_1-bug patch
+
+------------------------------------------------------------------------
+r708 | zimmerma | 2000-08-16 09:26:18 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+
+set_dfl_rnd -> set_rnd
+
+------------------------------------------------------------------------
+r707 | zimmerma | 2000-08-16 09:24:15 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ A /trunk/set_rnd.c
+
+new name of set_dfl_rnd.c (avoids clash with set_dfl_prec.c on DOS 8.3)
+
+------------------------------------------------------------------------
+r706 | zimmerma | 2000-08-16 09:23:43 +0000 (Wed, 16 Aug 2000) | 3 lines
+Changed paths:
+ D /trunk/set_dfl_rnd.c
+
+renamed to set_rnd.c (otherwise truncates like set_dfl_prec.c on
+a DOS 8.3 filesystem)
+
+------------------------------------------------------------------------
+r705 | zimmerma | 2000-08-16 09:20:29 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+setfilename: gmp.info -> mpfr.info
+
+------------------------------------------------------------------------
+r704 | zimmerma | 2000-08-16 09:19:17 +0000 (Wed, 16 Aug 2000) | 4 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+replaced path for libmpfr.a by $(top_builddir)
+test files are now in check_PROGRAMS instead of bin_PROGRAMS (they don't need
+ to be installed)
+
+------------------------------------------------------------------------
+r703 | zimmerma | 2000-08-16 09:14:44 +0000 (Wed, 16 Aug 2000) | 3 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tset_si.c
+
+replaced back BITS_PER_MP_LIMB by mp_bits_per_limb
+(not important in test files)
+
+------------------------------------------------------------------------
+r702 | zimmerma | 2000-08-16 09:09:03 +0000 (Wed, 16 Aug 2000) | 10 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+replaced macros for mpfr_init_set_si by "do { ... } while (0)" so
+they'll work in an if/else like
+
+ if (foo)
+ mpfr_init_set_si (f, -123, GMP_RNDN);
+ else
+ bar ();
+
+[thanks to Kevin Ryde]
+
+------------------------------------------------------------------------
+r701 | zimmerma | 2000-08-16 09:05:15 +0000 (Wed, 16 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/div_ui.c
+ M /trunk/exp2.c
+ M /trunk/mpf2mpfr.h
+ M /trunk/mul.c
+ M /trunk/print_raw.c
+ M /trunk/set_si.c
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+ M /trunk/tests/Makefile
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tset_si.c
+
+replaced mp_bits_per_limb by BITS_PER_MP_LIMB (constant)
+
+------------------------------------------------------------------------
+r700 | zimmerma | 2000-08-14 14:25:50 +0000 (Mon, 14 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+
+added mpf2mpfr.h
+
+------------------------------------------------------------------------
+r699 | zimmerma | 2000-08-14 13:11:09 +0000 (Mon, 14 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+define check2 only with -DTEST
+
+------------------------------------------------------------------------
+r698 | zimmerma | 2000-08-14 12:39:38 +0000 (Mon, 14 Aug 2000) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+updated for new configure from Emmanuel Jeandel, to GMP 3.xxx
+and removed errors with texinfo
+
+------------------------------------------------------------------------
+r697 | zimmerma | 2000-08-14 12:12:49 +0000 (Mon, 14 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+solaris --> __sparc__
+
+------------------------------------------------------------------------
+r696 | zimmerma | 2000-08-14 11:53:15 +0000 (Mon, 14 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+ A /trunk/tests/Makefile
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+ M /trunk/tests/tsub_ui.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+ifdef IRIX64 -> ifdef __mips
+
+------------------------------------------------------------------------
+r695 | zimmerma | 2000-08-14 11:31:36 +0000 (Mon, 14 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+
+IRIX/make does not understand $< : expanded to trunc.c
+
+------------------------------------------------------------------------
+r694 | zimmerma | 2000-08-14 11:20:29 +0000 (Mon, 14 Aug 2000) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+use standard macro for Alpha
+
+------------------------------------------------------------------------
+r693 | jeandel | 2000-07-13 12:40:25 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+autoconf options described
+
+------------------------------------------------------------------------
+r692 | jeandel | 2000-07-13 12:30:53 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.in
+
+timestamp modified
+
+------------------------------------------------------------------------
+r691 | jeandel | 2000-07-13 12:28:31 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/configure
+
+timestamp changed
+
+------------------------------------------------------------------------
+r690 | jeandel | 2000-07-13 12:27:04 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/tests/Makefile.am
+
+nothing to say
+
+------------------------------------------------------------------------
+r689 | jeandel | 2000-07-13 12:24:13 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/acinclude.m4
+ M /trunk/aclocal.m4
+
+Timestamp
+
+------------------------------------------------------------------------
+r688 | jeandel | 2000-07-13 12:21:50 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/tests/Makefile.in
+
+Small bug fixed
+
+------------------------------------------------------------------------
+r687 | jeandel | 2000-07-13 12:15:36 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/configure
+ M /trunk/configure.in
+
+Timestamp modified ?
+
+------------------------------------------------------------------------
+r686 | jeandel | 2000-07-13 12:13:18 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/tests/Makefile.in
+
+Timestamp modified
+
+------------------------------------------------------------------------
+r685 | jeandel | 2000-07-13 11:54:18 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/configure
+ M /trunk/configure.in
+
+Nothing
+
+------------------------------------------------------------------------
+r684 | jeandel | 2000-07-13 11:43:45 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/Makefile.in
+
+New release
+
+------------------------------------------------------------------------
+r683 | jeandel | 2000-07-13 09:52:17 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/Makefile.in
+
+Bugs fixed
+
+------------------------------------------------------------------------
+r682 | jeandel | 2000-07-13 09:39:27 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.in
+
+Bug fixed
+
+------------------------------------------------------------------------
+r681 | jeandel | 2000-07-13 09:21:09 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+sin_cos added
+
+------------------------------------------------------------------------
+r680 | jeandel | 2000-07-13 08:54:06 +0000 (Thu, 13 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/log2.c
+ M /trunk/pi.c
+
+New algorithm, new wrapper
+
+------------------------------------------------------------------------
+r679 | zimmerma | 2000-07-12 12:50:50 +0000 (Wed, 12 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tround.c
+
+replaced 0 by GMP_RNDN
+
+------------------------------------------------------------------------
+r678 | zimmerma | 2000-07-12 12:47:37 +0000 (Wed, 12 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+fixed (hopefully) bug for 1/1 in precision 32, 64, ...
+
+------------------------------------------------------------------------
+r677 | zimmerma | 2000-07-12 12:46:05 +0000 (Wed, 12 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added test for 1/1 in precision 32 or 64
+
+------------------------------------------------------------------------
+r676 | zimmerma | 2000-07-11 13:31:50 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+use mpfr_print_rnd_mode now
+
+------------------------------------------------------------------------
+r675 | jeandel | 2000-07-11 11:44:56 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+ M /trunk/Makefile.in
+ M /trunk/configure
+ M /trunk/configure.in
+
+Bug Fixed, and installation guide made
+
+------------------------------------------------------------------------
+r674 | jeandel | 2000-07-11 11:17:19 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/configure
+ M /trunk/configure.in
+
+Fixed bug
+
+------------------------------------------------------------------------
+r673 | jeandel | 2000-07-11 11:06:59 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.am
+ M /trunk/Makefile.in
+
+Bug Fixed with Solaris make
+
+------------------------------------------------------------------------
+r672 | jeandel | 2000-07-11 10:55:36 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/extract.c
+
+strings.h added
+
+------------------------------------------------------------------------
+r671 | jeandel | 2000-07-11 10:54:00 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/Makefile.in
+ M /trunk/tests/Makefile.in
+
+Deps included
+
+------------------------------------------------------------------------
+r670 | jeandel | 2000-07-11 09:55:31 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+ M /trunk/tests/Makefile.in
+
+Bug Fixed
+
+------------------------------------------------------------------------
+r669 | jeandel | 2000-07-11 09:52:32 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.in
+
+Bug fixed
+
+------------------------------------------------------------------------
+r668 | jeandel | 2000-07-11 09:52:17 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile.am
+
+Bug Fixed
+
+------------------------------------------------------------------------
+r667 | jeandel | 2000-07-11 09:47:24 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ A /trunk/Makefile.am
+ A /trunk/Makefile.in
+ A /trunk/acinclude.m4
+ A /trunk/aclocal.m4
+ A /trunk/configure
+ A /trunk/configure.in
+ A /trunk/install-sh
+ A /trunk/missing
+ A /trunk/mkinstalldirs
+ A /trunk/tests/Makefile.am
+ A /trunk/tests/Makefile.in
+ A /trunk/texinfo.tex
+
+First Release
+
+------------------------------------------------------------------------
+r666 | jeandel | 2000-07-11 09:42:34 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ D /trunk/COPYING.LIB
+ A /trunk/NEWS
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r665 | jeandel | 2000-07-11 09:41:38 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ A /trunk/COPYING
+ A /trunk/ChangeLog
+ A /trunk/README
+
+First Release
+
+------------------------------------------------------------------------
+r664 | jeandel | 2000-07-11 09:40:32 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ A /trunk/AUTHORS
+
+First release
+
+------------------------------------------------------------------------
+r663 | jeandel | 2000-07-11 09:37:43 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Added sin_cos
+
+------------------------------------------------------------------------
+r662 | jeandel | 2000-07-11 09:33:53 +0000 (Tue, 11 Jul 2000) | 2 lines
+Changed paths:
+ A /trunk/generic.c
+ A /trunk/sin_cos.c
+
+First Release
+
+------------------------------------------------------------------------
+r661 | jeandel | 2000-06-29 14:35:36 +0000 (Thu, 29 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/extract.c
+
+Memory problems fixed
+
+------------------------------------------------------------------------
+r660 | jeandel | 2000-06-29 14:35:19 +0000 (Thu, 29 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/exp3.c
+
+Memory Leaks Fixed
+
+------------------------------------------------------------------------
+r659 | zimmerma | 2000-06-29 13:22:57 +0000 (Thu, 29 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for mpfr_sub_ui
+
+------------------------------------------------------------------------
+r658 | zimmerma | 2000-06-29 13:22:34 +0000 (Thu, 29 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/init.c
+
+now use mpfr macros
+
+------------------------------------------------------------------------
+r657 | zimmerma | 2000-06-29 13:18:58 +0000 (Thu, 29 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+be careful not to call mpn_sub_n/mpn_sub_1 with a size 0
+
+------------------------------------------------------------------------
+r656 | zimmerma | 2000-06-29 13:16:45 +0000 (Thu, 29 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/clear.c
+
+fixed to free an entire number of limbs
+
+------------------------------------------------------------------------
+r655 | zimmerma | 2000-06-29 13:14:38 +0000 (Thu, 29 Jun 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/tsub_ui.c
+
+test file for sub_ui
+
+------------------------------------------------------------------------
+r654 | jeandel | 2000-06-28 08:35:07 +0000 (Wed, 28 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+mpfr_exp3 and mpfr_extract added to Makefile
+
+------------------------------------------------------------------------
+r653 | jeandel | 2000-06-28 08:33:06 +0000 (Wed, 28 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/exp2.c
+ A /trunk/exp3.c
+ A /trunk/extract.c
+
+First Release
+
+------------------------------------------------------------------------
+r652 | zimmerma | 2000-06-21 15:56:25 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt_ui.c
+
+distinguish between mpfr failure and difference with sqrt()
+
+------------------------------------------------------------------------
+r651 | zimmerma | 2000-06-21 15:55:35 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+ensures random numbers given to sqrt() are positive
+
+------------------------------------------------------------------------
+r650 | zimmerma | 2000-06-21 15:52:43 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+adapted for freebsd
+
+------------------------------------------------------------------------
+r649 | zimmerma | 2000-06-21 15:52:05 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+modified drand to avoid false NaNs (makes SEGV under FreeBSD)
+
+------------------------------------------------------------------------
+r648 | zimmerma | 2000-06-21 15:51:17 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added entry for FreeBSD, removed -pedantic option
+
+------------------------------------------------------------------------
+r647 | zimmerma | 2000-06-21 14:54:08 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_sub.c
+
+added one test
+
+------------------------------------------------------------------------
+r646 | zimmerma | 2000-06-21 14:47:02 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added new tests
+
+------------------------------------------------------------------------
+r645 | zimmerma | 2000-06-21 14:40:38 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for mpfr_set_prec_raw
+
+------------------------------------------------------------------------
+r644 | zimmerma | 2000-06-21 14:40:17 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed work done
+
+------------------------------------------------------------------------
+r643 | zimmerma | 2000-06-21 13:54:05 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed several bugs
+
+------------------------------------------------------------------------
+r642 | zimmerma | 2000-06-21 13:52:24 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+merged different roundings in case diff_exp<PREC(a), dif<=PREC(c)
+
+------------------------------------------------------------------------
+r641 | zimmerma | 2000-06-21 09:58:17 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+
+removed printf for argc=1
+
+------------------------------------------------------------------------
+r640 | zimmerma | 2000-06-21 09:54:31 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tui_sub.c
+
+added one test
+
+------------------------------------------------------------------------
+r639 | zimmerma | 2000-06-21 09:52:32 +0000 (Wed, 21 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+make ceil.o,floor.o,trunc.o depend on trunc.c
+
+------------------------------------------------------------------------
+r638 | hanrot | 2000-06-20 08:50:47 +0000 (Tue, 20 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/teq.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/trandom.c
+ M /trunk/tests/ttrunc.c
+
+Various patches for leaks, UMR and (one) BUS.
+
+------------------------------------------------------------------------
+r637 | hanrot | 2000-06-19 16:20:54 +0000 (Mon, 19 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tset_str.c
+
+This patch suppresses a few mem leaks.
+
+------------------------------------------------------------------------
+r636 | hanrot | 2000-06-19 15:38:44 +0000 (Mon, 19 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tsqrt.c
+
+Suppressed memory leaks.
+
+------------------------------------------------------------------------
+r635 | hanrot | 2000-06-19 10:15:32 +0000 (Mon, 19 Jun 2000) | 3 lines
+Changed paths:
+ M /trunk/div.c
+ M /trunk/mul_ui.c
+ M /trunk/sqrt.c
+
+Patch for 1 << (BITS_PER_MP_LIMB - x) when x is 0 (produces inexact results
+on PPCs).
+
+------------------------------------------------------------------------
+r634 | zimmerma | 2000-06-16 15:23:35 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+
+arguments of gmp_randinit were in wrong order
+
+------------------------------------------------------------------------
+r633 | hanrot | 2000-06-16 15:13:13 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/eq.c
+
+Patch in the case when n_bits is a multiple of 32.
+
+------------------------------------------------------------------------
+r632 | zimmerma | 2000-06-16 15:05:34 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+
+added patch to get denorms on IRIX64
+
+------------------------------------------------------------------------
+r631 | zimmerma | 2000-06-16 15:02:04 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+put instruction to get denormalized numbers on IRIX64 out of #ifdef TEST
+
+------------------------------------------------------------------------
+r630 | zimmerma | 2000-06-16 14:37:23 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+fixed bug occurring on LinuxPPC (1 << 32)
+
+------------------------------------------------------------------------
+r629 | zimmerma | 2000-06-16 14:35:00 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added one test (bug on LinuxPPC)
+
+------------------------------------------------------------------------
+r628 | zimmerma | 2000-06-16 13:47:32 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+added one test
+
+------------------------------------------------------------------------
+r627 | zimmerma | 2000-06-16 12:54:05 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/trunc.c
+
+fixed several problems
+
+------------------------------------------------------------------------
+r626 | zimmerma | 2000-06-16 12:53:22 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/ttrunc.c
+
+added more tests
+
+------------------------------------------------------------------------
+r625 | hanrot | 2000-06-16 10:02:43 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Patches for the case where the precision is a multiple of the word size.
+
+------------------------------------------------------------------------
+r624 | zimmerma | 2000-06-16 08:28:40 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed another bug
+
+------------------------------------------------------------------------
+r623 | zimmerma | 2000-06-16 08:26:45 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tui_sub.c
+
+added one test
+
+------------------------------------------------------------------------
+r622 | zimmerma | 2000-06-16 08:22:28 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for mpz_set_fr
+
+------------------------------------------------------------------------
+r621 | zimmerma | 2000-06-16 08:21:53 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+improved choice of initial precision
+
+------------------------------------------------------------------------
+r620 | zimmerma | 2000-06-16 08:21:03 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+ A /trunk/mpz_set_fr.c
+
+added mpz_set_fr (conversion from mpfr to mpz)
+
+------------------------------------------------------------------------
+r619 | zimmerma | 2000-06-16 08:16:49 +0000 (Fri, 16 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tround.c
+
+added return type 'int' for main
+
+------------------------------------------------------------------------
+r618 | hanrot | 2000-06-15 17:42:09 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Added TESTFLAGS to the main Makefile. Added ttrunc.
+
+------------------------------------------------------------------------
+r617 | hanrot | 2000-06-15 17:26:03 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/trunc.c
+
+Minor patch (put to 0 the nonsignificant bits).
+
+------------------------------------------------------------------------
+r616 | hanrot | 2000-06-15 17:16:02 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Added declaration of trunc, ceil, floor.
+
+------------------------------------------------------------------------
+r615 | hanrot | 2000-06-15 17:15:40 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/ttrunc.c
+
+Tests for trunc, ceil, floor.
+
+------------------------------------------------------------------------
+r614 | hanrot | 2000-06-15 16:43:40 +0000 (Thu, 15 Jun 2000) | 3 lines
+Changed paths:
+ M /trunk/Configure
+
+Added TESTFLAGS variable to the compile instruction, for use as
+make "TESTFLAGS=-DTEST"
+
+------------------------------------------------------------------------
+r613 | zimmerma | 2000-06-15 16:00:28 +0000 (Thu, 15 Jun 2000) | 3 lines
+Changed paths:
+ M /trunk/tests/teq.c
+
+1 -> (mp_limb_t) 1 [pb on 64-bit machines]
+reduced number of tests to 1000
+
+------------------------------------------------------------------------
+r612 | hanrot | 2000-06-15 10:32:04 +0000 (Thu, 15 Jun 2000) | 3 lines
+Changed paths:
+ M /trunk/tests/trandom.c
+
+Display of statistics is only toggled if a number of tests to be performed
+is given. Shameful hack, but is getopt really portable ?
+
+------------------------------------------------------------------------
+r611 | hanrot | 2000-06-15 10:25:51 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Added trandom, teq
+
+------------------------------------------------------------------------
+r610 | hanrot | 2000-06-15 10:25:20 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Added random2, urandomb
+
+------------------------------------------------------------------------
+r609 | hanrot | 2000-06-15 10:15:58 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+Added div_2exp to the (very rough) test.
+
+------------------------------------------------------------------------
+r608 | hanrot | 2000-06-15 10:13:37 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/trandom.c
+
+Very basic statistical tests for random, random2, urandomb.
+
+------------------------------------------------------------------------
+r607 | hanrot | 2000-06-15 10:13:19 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+Patch for random (libc's random() is on 31 bits only)
+
+------------------------------------------------------------------------
+r606 | hanrot | 2000-06-15 08:12:10 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/teq.c
+
+Test for mpfr_eq.
+
+------------------------------------------------------------------------
+r605 | hanrot | 2000-06-15 08:11:54 +0000 (Thu, 15 Jun 2000) | 2 lines
+Changed paths:
+ M /trunk/eq.c
+
+Patch a few incoherences of eq.c wrt the manual + adapt to mpfr usual semantics
+
+------------------------------------------------------------------------
+r604 | zimmerma | 2000-06-07 09:50:41 +0000 (Wed, 07 Jun 2000) | 2 lines
+Changed paths:
+ A /trunk/cputime.h
+
+header file providing cputime() function
+
+------------------------------------------------------------------------
+r603 | zimmerma | 2000-06-07 09:45:23 +0000 (Wed, 07 Jun 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/texp2.c
+
+test file comparing mpfr_exp and mpfr_exp2
+
+------------------------------------------------------------------------
+r602 | zimmerma | 2000-06-07 09:44:40 +0000 (Wed, 07 Jun 2000) | 4 lines
+Changed paths:
+ A /trunk/exp2.c
+
+O(n^(1/3)*log(n)) algorithm using Brent's method
+and Brent-Kung's O(sqrt(t)) algorithm to evaluate
+a power series of order t [exact rounding not yet finished]
+
+------------------------------------------------------------------------
+r601 | zimmerma | 2000-05-29 15:37:53 +0000 (Mon, 29 May 2000) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+fixed bug in mpfr_round (wrong sign)
+
+------------------------------------------------------------------------
+r600 | zimmerma | 2000-05-29 15:09:51 +0000 (Mon, 29 May 2000) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+fixed bug in mpfr_round: did not check allocated space was large enough
+
+------------------------------------------------------------------------
+r599 | zimmerma | 2000-05-29 14:02:08 +0000 (Mon, 29 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+
+main -> int main
+
+------------------------------------------------------------------------
+r598 | zimmerma | 2000-05-29 13:54:39 +0000 (Mon, 29 May 2000) | 3 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+added #ifdef TEST: if not defined (default), then function
+mpfr_set_machine_rnd_mode is not defined
+
+------------------------------------------------------------------------
+r597 | zimmerma | 2000-05-29 13:53:43 +0000 (Mon, 29 May 2000) | 3 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+ M /trunk/tests/tadd_ui.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tset_q.c
+ M /trunk/tests/tui_div.c
+ M /trunk/tests/tui_sub.c
+
+added #ifdef TEST to disable comparison with machine arithmetic
+by default (i.e. calls to mpfr_set_machine_rnd_mode)
+
+------------------------------------------------------------------------
+r596 | zimmerma | 2000-05-29 13:46:24 +0000 (Mon, 29 May 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+removed longlong.h (not needed)
+
+------------------------------------------------------------------------
+r595 | zimmerma | 2000-05-29 13:45:51 +0000 (Mon, 29 May 2000) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+now deals with NaN
+
+------------------------------------------------------------------------
+r594 | zimmerma | 2000-05-29 13:45:17 +0000 (Mon, 29 May 2000) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+RND_MODE -> rnd_mode
+
+------------------------------------------------------------------------
+r593 | zimmerma | 2000-05-29 13:44:13 +0000 (Mon, 29 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+mpfr_init is now a function (no more a macro)
+
+------------------------------------------------------------------------
+r592 | zimmerma | 2000-05-29 13:43:39 +0000 (Mon, 29 May 2000) | 3 lines
+Changed paths:
+ M /trunk/init.c
+
+printf -> fprintf
+added mpfr_init as function
+
+------------------------------------------------------------------------
+r591 | zimmerma | 2000-05-29 13:42:10 +0000 (Mon, 29 May 2000) | 3 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+changed (x) -> x
+fixed several typos
+
+------------------------------------------------------------------------
+r590 | zimmerma | 2000-05-29 11:28:48 +0000 (Mon, 29 May 2000) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+removed printf
+
+------------------------------------------------------------------------
+r589 | zimmerma | 2000-05-26 16:38:44 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+added ifdef TEST
+
+------------------------------------------------------------------------
+r588 | zimmerma | 2000-05-26 16:28:09 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+removed debug line
+
+------------------------------------------------------------------------
+r587 | zimmerma | 2000-05-26 16:25:37 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_sub.c
+
+added one test
+
+------------------------------------------------------------------------
+r586 | zimmerma | 2000-05-26 16:25:13 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added 2 new tests
+
+------------------------------------------------------------------------
+r585 | zimmerma | 2000-05-26 16:24:25 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+little change
+
+------------------------------------------------------------------------
+r584 | zimmerma | 2000-05-26 16:20:49 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+more changes
+
+------------------------------------------------------------------------
+r583 | zimmerma | 2000-05-26 15:44:03 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tsqrt_ui.c
+
+added ifdef TEST
+
+------------------------------------------------------------------------
+r582 | zimmerma | 2000-05-26 15:43:31 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+
+does not use machine rounding mode any more
+
+------------------------------------------------------------------------
+r581 | zimmerma | 2000-05-26 15:24:40 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added 7 new tests
+
+------------------------------------------------------------------------
+r580 | zimmerma | 2000-05-26 15:24:16 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_sub.c
+
+fixed typo in printf format
+
+------------------------------------------------------------------------
+r579 | zimmerma | 2000-05-26 15:22:37 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/sub.c
+
+fixed several rounding problems
+
+------------------------------------------------------------------------
+r578 | zimmerma | 2000-05-26 12:52:45 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+rewritten case dif<=0 and PREC(b)>PREC(a) (merged all roundings)
+
+------------------------------------------------------------------------
+r577 | zimmerma | 2000-05-26 10:11:04 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+removed DEBUG, VERBOSE ifdef's
+
+------------------------------------------------------------------------
+r576 | zimmerma | 2000-05-26 10:07:43 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed (hopefully) the case dif<=0, PREC(b)>PREC(a), directed rounding
+
+------------------------------------------------------------------------
+r575 | zimmerma | 2000-05-26 08:59:28 +0000 (Fri, 26 May 2000) | 3 lines
+Changed paths:
+ M /trunk/sub.c
+
+replaced (mp_limb_t)1 by macro ONE
+fixed bug for GMP_RNDN with overlap=1
+
+------------------------------------------------------------------------
+r574 | zimmerma | 2000-05-26 08:58:32 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+removed misplaced comment
+
+------------------------------------------------------------------------
+r573 | zimmerma | 2000-05-26 08:20:16 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added one test
+
+------------------------------------------------------------------------
+r572 | zimmerma | 2000-05-26 08:16:19 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+does not use rnd_mode.c by default
+
+------------------------------------------------------------------------
+r571 | zimmerma | 2000-05-26 07:41:46 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+removed unused label
+
+------------------------------------------------------------------------
+r570 | zimmerma | 2000-05-26 07:40:31 +0000 (Fri, 26 May 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+fixed more tiny bugs
+
+------------------------------------------------------------------------
+r569 | zimmerma | 2000-05-25 17:00:04 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt_ui.c
+
+use mpfr_print_rnd_mode now
+
+------------------------------------------------------------------------
+r568 | zimmerma | 2000-05-25 16:59:43 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tui_sub.c
+
+added one test
+
+------------------------------------------------------------------------
+r567 | zimmerma | 2000-05-25 16:59:08 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tadd_ui.c
+
+added more tests
+
+------------------------------------------------------------------------
+r566 | zimmerma | 2000-05-25 16:55:19 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/add_ui.c
+
+removed TMP_ALLOC stuff
+
+------------------------------------------------------------------------
+r565 | zimmerma | 2000-05-25 16:54:29 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed new bug when a <- b - c with tiny c
+
+------------------------------------------------------------------------
+r564 | zimmerma | 2000-05-25 16:30:10 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed bug in a <- b-c when c very small but does not overlap with a
+
+------------------------------------------------------------------------
+r563 | zimmerma | 2000-05-25 15:45:33 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/random2.c
+
+removed 'inline' (does not compile on Alpha with gcc 2.8.1)
+
+------------------------------------------------------------------------
+r562 | zimmerma | 2000-05-25 15:35:48 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tout_str.c
+
+added include file unistd.h
+
+------------------------------------------------------------------------
+r561 | zimmerma | 2000-05-25 15:35:08 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+
+fixed warning with long arguments
+
+------------------------------------------------------------------------
+r560 | zimmerma | 2000-05-25 15:28:50 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ A /trunk/inp_str.c
+ A /trunk/set_str.c
+
+initial version
+
+------------------------------------------------------------------------
+r559 | zimmerma | 2000-05-25 15:26:11 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+added tests for mpfr_set_str
+
+------------------------------------------------------------------------
+r558 | zimmerma | 2000-05-25 15:25:13 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+
+now returns 0 if all works
+
+------------------------------------------------------------------------
+r557 | zimmerma | 2000-05-25 15:24:42 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+changed to return the error in ulps
+
+------------------------------------------------------------------------
+r556 | zimmerma | 2000-05-25 15:24:06 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added new functions mpfr_set_str and mpfr_inp_str
+
+------------------------------------------------------------------------
+r555 | zimmerma | 2000-05-25 14:58:04 +0000 (Thu, 25 May 2000) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototypes for set_str, inp_str
+changed return value for mpfr*pow*
+
+------------------------------------------------------------------------
+r554 | zimmerma | 2000-05-25 14:56:51 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+separated functions with/without rounding argument
+
+------------------------------------------------------------------------
+r553 | zimmerma | 2000-05-25 14:56:19 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added tabs
+
+------------------------------------------------------------------------
+r552 | zimmerma | 2000-05-25 14:22:08 +0000 (Thu, 25 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added set_str.o and inp_str.o
+
+------------------------------------------------------------------------
+r551 | zimmerma | 2000-05-24 17:01:52 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ A /trunk/sub_ui.c
+
+initial version
+
+------------------------------------------------------------------------
+r550 | zimmerma | 2000-05-24 17:01:01 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added rule for sub_ui.o
+
+------------------------------------------------------------------------
+r549 | zimmerma | 2000-05-24 16:51:55 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+use only one file (trunc.c) for ceil, floor, trunc
+
+------------------------------------------------------------------------
+r548 | zimmerma | 2000-05-24 16:51:22 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ D /trunk/ceil.c
+ D /trunk/floor.c
+
+now use trunc.c for all 3 functions (ceil, floor, trunc)
+
+------------------------------------------------------------------------
+r547 | zimmerma | 2000-05-24 16:42:00 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/trunc.c
+
+added ifdef to avoid warning at compilation
+
+------------------------------------------------------------------------
+r546 | zimmerma | 2000-05-24 16:41:30 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/reldiff.c
+
+removed unused variable
+
+------------------------------------------------------------------------
+r545 | zimmerma | 2000-05-24 16:41:09 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+fixed output type for mpfr_ui_div
+
+------------------------------------------------------------------------
+r544 | zimmerma | 2000-05-24 16:37:13 +0000 (Wed, 24 May 2000) | 3 lines
+Changed paths:
+ M /trunk/urandomb.c
+
+removed 3rd argument (use PREC(rop) instead)
+added include longlong.h
+
+------------------------------------------------------------------------
+r543 | zimmerma | 2000-05-24 16:35:23 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/set_prc_raw.c
+
+stupid typo: ABSSIZE -> ABSSIZE(x)
+
+------------------------------------------------------------------------
+r542 | zimmerma | 2000-05-24 16:32:06 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+change due to new semantics of mpfr_init_set* macros
+
+------------------------------------------------------------------------
+r541 | zimmerma | 2000-05-24 16:31:18 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/set_prc_raw.c
+
+now makes an error when precision too large wrt allocated space
+
+------------------------------------------------------------------------
+r540 | zimmerma | 2000-05-24 16:28:41 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added new implemented functions
+
+------------------------------------------------------------------------
+r539 | zimmerma | 2000-05-24 16:26:30 +0000 (Wed, 24 May 2000) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+- added macro for mpfr_sgn
+- removed argument 'p' in mpfr_init_set* macros for compatibility with mpf
+
+------------------------------------------------------------------------
+r538 | zimmerma | 2000-05-24 16:25:20 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpf2mpfr.h
+
+updated wrt new functions
+
+------------------------------------------------------------------------
+r537 | zimmerma | 2000-05-24 16:24:57 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added sub_ui
+
+------------------------------------------------------------------------
+r536 | zimmerma | 2000-05-24 15:29:24 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added new test files
+
+------------------------------------------------------------------------
+r535 | zimmerma | 2000-05-24 15:28:52 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/tadd_ui.c
+ A /trunk/tests/tset_q.c
+ A /trunk/tests/tsqrt_ui.c
+ A /trunk/tests/tui_div.c
+ A /trunk/tests/tui_sub.c
+
+new test files
+
+------------------------------------------------------------------------
+r534 | zimmerma | 2000-05-24 15:24:28 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added new tests
+
+------------------------------------------------------------------------
+r533 | zimmerma | 2000-05-24 15:23:54 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tabs.c
+
+improved tests
+
+------------------------------------------------------------------------
+r532 | zimmerma | 2000-05-24 15:22:08 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ A /trunk/add_ui.c
+ A /trunk/reldiff.c
+ A /trunk/sqrt_ui.c
+ A /trunk/ui_div.c
+ A /trunk/ui_sub.c
+
+new functions (compatibility with mpf)
+
+------------------------------------------------------------------------
+r531 | zimmerma | 2000-05-24 15:20:16 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+added 4th arg (was missing in non-stdc def)
+
+------------------------------------------------------------------------
+r530 | zimmerma | 2000-05-24 15:19:10 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added new functions (compatibility with mpf)
+
+------------------------------------------------------------------------
+r529 | zimmerma | 2000-05-24 15:18:37 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added several prototypes
+
+------------------------------------------------------------------------
+r528 | zimmerma | 2000-05-24 15:18:04 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+fixed remaining bug (case overlap=5, dif>0)
+
+------------------------------------------------------------------------
+r527 | zimmerma | 2000-05-24 15:16:52 +0000 (Wed, 24 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added add_ui, sqrt_ui, ui_div, ui_sub, reldiff
+
+------------------------------------------------------------------------
+r526 | hanrot | 2000-05-21 16:47:02 +0000 (Sun, 21 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+ A /trunk/ceil.c
+ A /trunk/floor.c
+ A /trunk/trunc.c
+
+Compatibility mpf/mpfr, second part. Ceil, floor, trunc. Yet untested.
+
+------------------------------------------------------------------------
+r525 | hanrot | 2000-05-21 16:38:07 +0000 (Sun, 21 May 2000) | 2 lines
+Changed paths:
+ A /trunk/mpf2mpfr.h
+
+Include file for compatibility module mpf -> mpfr.
+
+------------------------------------------------------------------------
+r524 | hanrot | 2000-05-21 16:35:52 +0000 (Sun, 21 May 2000) | 3 lines
+Changed paths:
+ M /trunk/Configure
+ A /trunk/dump.c
+ A /trunk/eq.c
+ A /trunk/random2.c
+ A /trunk/set_prc_raw.c
+ A /trunk/urandomb.c
+
+Compatibility with mpf. WARNING: THESE FUNCTIONS ARE UNTESTED IN THEIR PRESENT
+FORM. THEY *DO* COMPILE HOWEVER.
+
+------------------------------------------------------------------------
+r523 | zimmerma | 2000-05-18 13:41:24 +0000 (Thu, 18 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+removed unused variables
+
+------------------------------------------------------------------------
+r522 | zimmerma | 2000-05-18 13:38:53 +0000 (Thu, 18 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+removed ';'
+
+------------------------------------------------------------------------
+r521 | zimmerma | 2000-05-18 13:29:55 +0000 (Thu, 18 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tround.c
+
+added return
+
+------------------------------------------------------------------------
+r520 | zimmerma | 2000-05-18 12:57:08 +0000 (Thu, 18 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+
+added calls to mpf[r]_clear, and rewrote to avoid memory leaks
+
+------------------------------------------------------------------------
+r519 | zimmerma | 2000-05-18 12:56:14 +0000 (Thu, 18 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added calls to free
+
+------------------------------------------------------------------------
+r518 | zimmerma | 2000-05-18 12:55:17 +0000 (Thu, 18 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+corrected comment about field mp_size
+
+------------------------------------------------------------------------
+r517 | zimmerma | 2000-05-12 08:07:56 +0000 (Fri, 12 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+added tests for negative numbers
+
+------------------------------------------------------------------------
+r516 | zimmerma | 2000-05-12 08:07:35 +0000 (Fri, 12 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added one test
+
+------------------------------------------------------------------------
+r515 | zimmerma | 2000-05-12 08:07:02 +0000 (Fri, 12 May 2000) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed pb with rounding of negative numbers
+
+------------------------------------------------------------------------
+r514 | zimmerma | 2000-05-11 15:39:48 +0000 (Thu, 11 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added mpfr_abs
+
+------------------------------------------------------------------------
+r513 | zimmerma | 2000-05-11 15:38:12 +0000 (Thu, 11 May 2000) | 2 lines
+Changed paths:
+ A /trunk/tests/tabs.c
+
+test file for mpfr_abs
+
+------------------------------------------------------------------------
+r512 | zimmerma | 2000-05-11 15:37:48 +0000 (Thu, 11 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added mpfr_abs (macro using mpfr_set4)
+
+------------------------------------------------------------------------
+r511 | zimmerma | 2000-05-11 10:08:54 +0000 (Thu, 11 May 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+updated wrt done/new tasks
+
+------------------------------------------------------------------------
+r510 | zimmerma | 2000-05-05 13:59:56 +0000 (Fri, 05 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added two tests
+
+------------------------------------------------------------------------
+r509 | zimmerma | 2000-05-05 13:59:25 +0000 (Fri, 05 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_d.c
+
+split mpfr_init2 into mpfr_init and mpfr_set_prec
+
+------------------------------------------------------------------------
+r508 | zimmerma | 2000-05-05 13:57:33 +0000 (Fri, 05 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+removed karadiv.o
+
+------------------------------------------------------------------------
+r507 | zimmerma | 2000-05-05 13:57:08 +0000 (Fri, 05 May 2000) | 2 lines
+Changed paths:
+ M /trunk/karasqrt.c
+
+replaced mpn_divrem_n by mpn_divrem (efficient in GMP 3.0)
+
+------------------------------------------------------------------------
+r506 | zimmerma | 2000-05-05 13:55:49 +0000 (Fri, 05 May 2000) | 2 lines
+Changed paths:
+ D /trunk/karadiv.c
+
+not needed any more with GMP 3.0
+
+------------------------------------------------------------------------
+r505 | zimmerma | 2000-05-05 13:49:02 +0000 (Fri, 05 May 2000) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+removed mpn_divrem_n stuff, now that Burnikel/Ziegler algorithm is in GMP 3.0
+
+------------------------------------------------------------------------
+r504 | zimmerma | 2000-05-05 13:29:21 +0000 (Fri, 05 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tout_str.c
+
+added one test
+
+------------------------------------------------------------------------
+r503 | zimmerma | 2000-05-04 15:18:31 +0000 (Thu, 04 May 2000) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+completely rewritten (changed semantics)
+
+------------------------------------------------------------------------
+r502 | zimmerma | 2000-05-04 15:17:07 +0000 (Thu, 04 May 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+initialized variable bh to avoid warning at compilation
+
+------------------------------------------------------------------------
+r501 | zimmerma | 2000-05-04 15:16:11 +0000 (Thu, 04 May 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for mpfr_set_default_rounding_mode
+
+------------------------------------------------------------------------
+r500 | zimmerma | 2000-05-04 15:05:34 +0000 (Thu, 04 May 2000) | 2 lines
+Changed paths:
+ M /trunk/cmp_ui.c
+
+fixed pb in mpfr_cmp_ui_2exp for i=0
+
+------------------------------------------------------------------------
+r499 | zimmerma | 2000-05-04 13:40:09 +0000 (Thu, 04 May 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+updated according to meeting from May 4, 2000
+
+------------------------------------------------------------------------
+r498 | zimmerma | 2000-05-04 12:24:56 +0000 (Thu, 04 May 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+updated for AIX
+
+------------------------------------------------------------------------
+r497 | zimmerma | 2000-05-04 12:23:28 +0000 (Thu, 04 May 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+ M /trunk/rnd_mode.c
+
+updated for AIX (thanks to Gerardo Ballabio)
+
+------------------------------------------------------------------------
+r496 | zimmerma | 2000-05-02 16:38:27 +0000 (Tue, 02 May 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+
+added one test
+
+------------------------------------------------------------------------
+r495 | zimmerma | 2000-05-02 16:37:52 +0000 (Tue, 02 May 2000) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+fixed bug found by G. Ballabio for b=0 and 0<c<1
+
+------------------------------------------------------------------------
+r494 | zimmerma | 2000-05-02 16:37:01 +0000 (Tue, 02 May 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+added info for GMP2 vs GMP3
+
+------------------------------------------------------------------------
+r493 | zimmerma | 2000-04-19 19:20:27 +0000 (Wed, 19 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added -ffloat-store for Alpha/OSF
+
+------------------------------------------------------------------------
+r492 | zimmerma | 2000-04-19 18:31:13 +0000 (Wed, 19 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+added cast to mp_limb_t (bug on Alpha in tadd with -O2)
+
+------------------------------------------------------------------------
+r491 | zimmerma | 2000-04-19 18:30:19 +0000 (Wed, 19 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+added one test
+
+------------------------------------------------------------------------
+r490 | zimmerma | 2000-04-19 14:46:00 +0000 (Wed, 19 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/karasqrt.c
+
+removed #if 0
+
+------------------------------------------------------------------------
+r489 | zimmerma | 2000-04-19 14:45:27 +0000 (Wed, 19 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+swapped gmp-impl.h and longlong.h for GMP 3.0
+
+------------------------------------------------------------------------
+r488 | zimmerma | 2000-04-14 07:34:19 +0000 (Fri, 14 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+added more tests
+
+------------------------------------------------------------------------
+r487 | zimmerma | 2000-04-14 07:33:46 +0000 (Fri, 14 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+fixed pb when target precision is less than integer length
+
+------------------------------------------------------------------------
+r486 | zimmerma | 2000-04-14 07:32:36 +0000 (Fri, 14 Apr 2000) | 3 lines
+Changed paths:
+ M /trunk/add.c
+
+fixed problem not solved so far, i.e. when adding round bit
+produces a change of exponent
+
+------------------------------------------------------------------------
+r485 | zimmerma | 2000-04-13 17:05:48 +0000 (Thu, 13 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+fixed computation of ulps
+
+------------------------------------------------------------------------
+r484 | zimmerma | 2000-04-13 17:03:32 +0000 (Thu, 13 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+removed variable xrw in mpfr_round_raw (not used)
+
+------------------------------------------------------------------------
+r483 | zimmerma | 2000-04-13 17:02:20 +0000 (Thu, 13 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+replaced 1st my by my+sh in mpfr_round_raw call
+
+------------------------------------------------------------------------
+r482 | zimmerma | 2000-04-13 17:00:16 +0000 (Thu, 13 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+added 2 more tests
+
+------------------------------------------------------------------------
+r481 | hanrot | 2000-04-13 16:49:33 +0000 (Thu, 13 Apr 2000) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+Correction d'un bug quand le carry contient tous les bits significatifs.
+
+------------------------------------------------------------------------
+r480 | zimmerma | 2000-02-11 17:24:38 +0000 (Fri, 11 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+improved indentation
+mpfr_pi -> mpfr_const_pi
+
+------------------------------------------------------------------------
+r479 | zimmerma | 2000-02-11 17:23:36 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_z.c
+
+added one test
+
+------------------------------------------------------------------------
+r478 | zimmerma | 2000-02-11 17:23:09 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+ M /trunk/tests/tpi.c
+
+mpfr_pi -> mpfr_const_pi
+
+------------------------------------------------------------------------
+r477 | zimmerma | 2000-02-11 17:22:34 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+use mpfr_cmp_ui instead of SIGN
+
+------------------------------------------------------------------------
+r476 | zimmerma | 2000-02-11 17:22:03 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog2.c
+
+mpfr_log2 -> mpfr_const_log2
+
+------------------------------------------------------------------------
+r475 | zimmerma | 2000-02-11 17:20:57 +0000 (Fri, 11 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/Configure
+
+added -O2 compilation flag
+added set_q
+
+------------------------------------------------------------------------
+r474 | zimmerma | 2000-02-11 17:20:19 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ A /trunk/set_q.c
+
+convert rational (mpz_q) to floating-point (mpfr_t)
+
+------------------------------------------------------------------------
+r473 | zimmerma | 2000-02-11 17:19:15 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+removed things which were done
+
+------------------------------------------------------------------------
+r472 | zimmerma | 2000-02-11 17:18:40 +0000 (Fri, 11 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/agm.c
+ M /trunk/div_ui.c
+ M /trunk/exp.c
+ M /trunk/get_str.c
+ M /trunk/log.c
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+
+unsigned char -> mp_rnd_t
+SIGN -> MPFR_SIGN
+
+------------------------------------------------------------------------
+r471 | zimmerma | 2000-02-11 17:17:47 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/clear.c
+
+use PREC() macro instead of _mp_prec, and corrected size to free
+
+------------------------------------------------------------------------
+r470 | zimmerma | 2000-02-11 17:16:36 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+
+SIGN -> MPFR_SIGN
+
+------------------------------------------------------------------------
+r469 | zimmerma | 2000-02-11 17:15:35 +0000 (Fri, 11 Feb 2000) | 4 lines
+Changed paths:
+ M /trunk/div.c
+
+unsigned char -> mp_rnd_t
+SIGN -> MPFR_SIGN
+added non standard C header
+
+------------------------------------------------------------------------
+r468 | zimmerma | 2000-02-11 17:13:54 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/div_2exp.c
+
+unsigned char -> mp_rnd_t
+
+------------------------------------------------------------------------
+r467 | zimmerma | 2000-02-11 17:11:45 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/init.c
+
+unsigned long int -> mp_prec_t
+
+------------------------------------------------------------------------
+r466 | zimmerma | 2000-02-11 17:11:01 +0000 (Fri, 11 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/log2.c
+
+renamed to mpfr_const_log2
+unsigned char -> mp_rnd_t
+
+------------------------------------------------------------------------
+r465 | zimmerma | 2000-02-11 17:10:24 +0000 (Fri, 11 Feb 2000) | 4 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+unsigned char -> mp_rnd_t
+SIGN -> MPFR_SIGN
+unsigned long int -> mp_prec_t
+
+------------------------------------------------------------------------
+r464 | zimmerma | 2000-02-11 17:10:04 +0000 (Fri, 11 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+unsigned char -> mp_rnd_t
+unsigned long int -> mp_prec_t
+
+------------------------------------------------------------------------
+r463 | zimmerma | 2000-02-11 17:08:37 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/mul_2exp.c
+ M /trunk/out_str.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/rnd_mode.c
+
+unsigned char -> mp_rnd_t
+
+------------------------------------------------------------------------
+r462 | zimmerma | 2000-02-11 17:06:41 +0000 (Fri, 11 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/pi.c
+
+renamed to mpfr_const_pi
+unsigned char -> mp_rnd_t
+
+------------------------------------------------------------------------
+r461 | zimmerma | 2000-02-11 17:06:06 +0000 (Fri, 11 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/pow.c
+
+unsigned char -> mp_rnd_t
+added non standard C header
+
+------------------------------------------------------------------------
+r460 | zimmerma | 2000-02-11 17:04:40 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/print_raw.c
+
+SIGN -> MPFR_SIGN
+
+------------------------------------------------------------------------
+r459 | zimmerma | 2000-02-11 17:03:46 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+added non standard C header
+
+------------------------------------------------------------------------
+r458 | zimmerma | 2000-02-11 17:01:46 +0000 (Fri, 11 Feb 2000) | 4 lines
+Changed paths:
+ M /trunk/round.c
+
+unsigned char -> mp_rnd_t
+SIGN -> MPFR_SIGN
+unsigned long int -> mp_prec_t
+
+------------------------------------------------------------------------
+r457 | zimmerma | 2000-02-11 17:01:15 +0000 (Fri, 11 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_f.c
+ M /trunk/set_si.c
+ M /trunk/set_z.c
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+
+unsigned char -> mp_rnd_t
+SIGN -> MPFR_SIGN
+
+------------------------------------------------------------------------
+r456 | zimmerma | 2000-02-11 17:00:21 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_prec.c
+
+unsigned long int -> mp_prec_t
+
+------------------------------------------------------------------------
+r455 | zimmerma | 2000-02-11 16:59:45 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/set_dfl_rnd.c
+
+har -> mp_rnd_t
+
+------------------------------------------------------------------------
+r454 | zimmerma | 2000-02-11 16:55:07 +0000 (Fri, 11 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+changed rounding mode to mp_rnd_t
+
+------------------------------------------------------------------------
+r453 | zimmerma | 2000-02-04 17:04:06 +0000 (Fri, 04 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+now distinguish between true mpfr errors and possible errors from libm.a
+
+------------------------------------------------------------------------
+r452 | zimmerma | 2000-02-04 17:03:21 +0000 (Fri, 04 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+now use print_rnd_mode
+
+------------------------------------------------------------------------
+r451 | zimmerma | 2000-02-04 17:02:42 +0000 (Fri, 04 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added suggestion from JP Merlet
+
+------------------------------------------------------------------------
+r450 | zimmerma | 2000-02-04 17:02:15 +0000 (Fri, 04 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added print_rnd_mode.c
+
+------------------------------------------------------------------------
+r449 | zimmerma | 2000-02-04 14:55:01 +0000 (Fri, 04 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+
+added more tests
+
+------------------------------------------------------------------------
+r448 | zimmerma | 2000-02-04 14:54:37 +0000 (Fri, 04 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/set_f.c
+
+fixed bug(s) found by Jean-Pierre Merlet
+
+------------------------------------------------------------------------
+r447 | zimmerma | 2000-02-04 14:45:43 +0000 (Fri, 04 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+changed prototype of mpfr_set_f (takes now only 3 arguments)
+
+------------------------------------------------------------------------
+r446 | zimmerma | 2000-02-03 08:59:19 +0000 (Thu, 03 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added karasqrt.o
+
+------------------------------------------------------------------------
+r445 | zimmerma | 2000-02-03 08:58:49 +0000 (Thu, 03 Feb 2000) | 4 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for kara_sqrtrem
+added redefinition of KARATSUBA_MUL_THRESHOLD (if not defined)
+removed definition of LOG_MP_BITS_PER_LIMB (was not used)
+
+------------------------------------------------------------------------
+r444 | zimmerma | 2000-02-03 08:57:40 +0000 (Thu, 03 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/karasqrt.c
+
+changed return type to mp_size_t and included mpfr.h
+
+------------------------------------------------------------------------
+r443 | zimmerma | 2000-02-03 08:56:58 +0000 (Thu, 03 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/karadiv.c
+
+moved definition of KARATSUBA_MUL_THRESHOLD (if not defined) to mpfr.h
+
+------------------------------------------------------------------------
+r442 | zimmerma | 2000-02-03 08:48:45 +0000 (Thu, 03 Feb 2000) | 2 lines
+Changed paths:
+ A /trunk/karasqrt.c
+
+implements Katatsuba square root
+
+------------------------------------------------------------------------
+r441 | zimmerma | 2000-02-03 08:45:55 +0000 (Thu, 03 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+now use kara_sqrtrem instead of mpn_sqrtrem
+
+------------------------------------------------------------------------
+r440 | zimmerma | 2000-02-03 08:41:35 +0000 (Thu, 03 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+fixed bug when high limb of quotient is zero
+
+------------------------------------------------------------------------
+r439 | zimmerma | 2000-02-02 18:17:30 +0000 (Wed, 02 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added one test [did fail on alpha]
+
+------------------------------------------------------------------------
+r438 | zimmerma | 2000-02-02 18:01:29 +0000 (Wed, 02 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+added cast to mp_limb_t in front of 1<<sh
+
+------------------------------------------------------------------------
+r437 | zimmerma | 2000-02-02 17:57:24 +0000 (Wed, 02 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/karadiv.c
+
+modified to be compatible with gmp-2.0.2
+
+------------------------------------------------------------------------
+r436 | zimmerma | 2000-02-02 17:54:04 +0000 (Wed, 02 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+added further sqrt pb on alpha
+
+------------------------------------------------------------------------
+r435 | zimmerma | 2000-02-02 17:53:12 +0000 (Wed, 02 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+swapped longlong.h and gmp-impl.h (pb on alpha)
+
+------------------------------------------------------------------------
+r434 | zimmerma | 2000-02-02 16:02:47 +0000 (Wed, 02 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added test for bug in sub.c found by JP Merlet on Solaris
+
+------------------------------------------------------------------------
+r433 | zimmerma | 2000-02-02 15:52:54 +0000 (Wed, 02 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed mpn_rshift which could have 0 as shift argument
+(caused bug in exp on Solaris found by JP Merlet)
+
+------------------------------------------------------------------------
+r432 | zimmerma | 2000-02-02 15:49:49 +0000 (Wed, 02 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+moved debug messages to stdout
+
+------------------------------------------------------------------------
+r431 | zimmerma | 2000-02-01 16:31:42 +0000 (Tue, 01 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for mpn_divrem_n (Burnikel-Ziegler algorithm)
+
+------------------------------------------------------------------------
+r430 | zimmerma | 2000-02-01 16:31:05 +0000 (Tue, 01 Feb 2000) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+use mpn_divrem_n (Burnikel-Ziegler algorithm) instead of mpn_divrem
+when rsize=rrsize
+
+------------------------------------------------------------------------
+r429 | zimmerma | 2000-02-01 16:30:17 +0000 (Tue, 01 Feb 2000) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added karadiv.c (to be removed when incorporated in GMP)
+
+------------------------------------------------------------------------
+r428 | zimmerma | 2000-02-01 16:29:32 +0000 (Tue, 01 Feb 2000) | 2 lines
+Changed paths:
+ A /trunk/karadiv.c
+
+Burnikel-Ziegler division
+
+------------------------------------------------------------------------
+r427 | zimmerma | 2000-01-31 13:09:12 +0000 (Mon, 31 Jan 2000) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added further examples from V. Lefe`vre
+
+------------------------------------------------------------------------
+r426 | zimmerma | 1999-12-16 13:14:21 +0000 (Thu, 16 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added macri VERSION for target dist
+
+------------------------------------------------------------------------
+r425 | zimmerma | 1999-12-16 11:00:44 +0000 (Thu, 16 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added new tests from V. Lefe`vre
+
+------------------------------------------------------------------------
+r424 | zimmerma | 1999-12-16 11:00:14 +0000 (Thu, 16 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+improved interface: tdiv N for doing N random tests
+
+------------------------------------------------------------------------
+r423 | zimmerma | 1999-12-16 10:59:26 +0000 (Thu, 16 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+added one test
+
+------------------------------------------------------------------------
+r422 | zimmerma | 1999-12-16 10:58:50 +0000 (Thu, 16 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+DEBUG2 -> DEBUG
+
+------------------------------------------------------------------------
+r421 | zimmerma | 1999-12-16 10:58:21 +0000 (Thu, 16 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+added debug instructions
+
+------------------------------------------------------------------------
+r420 | zimmerma | 1999-12-16 10:57:44 +0000 (Thu, 16 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+fixed nasty bug in mpfr_cmp2 (case cc=1)
+
+------------------------------------------------------------------------
+r419 | zimmerma | 1999-12-16 10:54:57 +0000 (Thu, 16 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+replaced printf by fprintf for error
+
+------------------------------------------------------------------------
+r418 | zimmerma | 1999-12-10 20:32:36 +0000 (Fri, 10 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added new tests for large input
+
+------------------------------------------------------------------------
+r417 | zimmerma | 1999-12-10 20:32:07 +0000 (Fri, 10 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+fixed bug for large input
+
+------------------------------------------------------------------------
+r416 | zimmerma | 1999-12-10 13:29:54 +0000 (Fri, 10 Dec 1999) | 4 lines
+Changed paths:
+ M /trunk/log.c
+
+rewritten the error analysis:
+- now analyzes the cancellation a posteriori
+- takes into account errors from rounding and initial approximation
+
+------------------------------------------------------------------------
+r415 | zimmerma | 1999-12-10 13:27:42 +0000 (Fri, 10 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added tests from Vincent Lefe`vre
+
+------------------------------------------------------------------------
+r414 | zimmerma | 1999-12-10 13:04:09 +0000 (Fri, 10 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+no warning any more for negative exponent (thanks to V. Lefe`vre)
+
+------------------------------------------------------------------------
+r413 | zimmerma | 1999-12-08 12:12:07 +0000 (Wed, 08 Dec 1999) | 3 lines
+Changed paths:
+ M /trunk/exp.c
+
+fixed bug found by V. Lefe`vre (when n<0, we have to compute
+an upper bound of log(2) instead of a lower bound)
+
+------------------------------------------------------------------------
+r412 | zimmerma | 1999-12-08 12:10:29 +0000 (Wed, 08 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added new test (bug found by V. Lefe`vre)
+
+------------------------------------------------------------------------
+r411 | zimmerma | 1999-12-07 16:01:25 +0000 (Tue, 07 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added suggestion from V. Lefe`vre
+
+------------------------------------------------------------------------
+r410 | zimmerma | 1999-12-07 10:31:45 +0000 (Tue, 07 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/TODO
+
+added several remarks from Vincent Lefe`vre
+
+------------------------------------------------------------------------
+r409 | zimmerma | 1999-12-07 10:27:05 +0000 (Tue, 07 Dec 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+corrected many typos found by Vincent Lefe`vre
+
+------------------------------------------------------------------------
+r408 | zimmerma | 1999-11-27 08:10:56 +0000 (Sat, 27 Nov 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+
+removed executable rights
+
+------------------------------------------------------------------------
+r407 | zimmerma | 1999-11-27 08:09:46 +0000 (Sat, 27 Nov 1999) | 3 lines
+Changed paths:
+ M /trunk/INSTALL
+
+improved GMP link (thanks to Vincent Lefe`vre)
+added pointer to Alpha-Linux f-p problems
+
+------------------------------------------------------------------------
+r406 | zimmerma | 1999-11-27 08:08:35 +0000 (Sat, 27 Nov 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_d.c
+
+removed executable right on file
+
+------------------------------------------------------------------------
+r405 | zimmerma | 1999-10-20 14:17:01 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+put back test for x=y
+
+------------------------------------------------------------------------
+r404 | zimmerma | 1999-10-20 14:11:34 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+modified to avoid y=-0.0
+
+------------------------------------------------------------------------
+r403 | zimmerma | 1999-10-20 13:31:20 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+modified test procedure to return 53 when x=y
+
+------------------------------------------------------------------------
+r402 | zimmerma | 1999-10-20 13:25:13 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+mpfr_cmp2(b,c) now returns PREC(b) if b=c, even if c=0
+
+------------------------------------------------------------------------
+r401 | zimmerma | 1999-10-20 13:06:11 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added one test
+
+------------------------------------------------------------------------
+r400 | zimmerma | 1999-10-20 13:05:43 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+added test under Cygwin
+
+------------------------------------------------------------------------
+r399 | zimmerma | 1999-10-20 11:16:09 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+$make -> $MAKE
+
+------------------------------------------------------------------------
+r398 | zimmerma | 1999-10-20 10:21:22 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_z.c
+
+removed *rand48 prototypes (pb under Cygwin)
+
+------------------------------------------------------------------------
+r397 | zimmerma | 1999-10-20 10:20:37 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+removed *rand48 prototypes
+
+------------------------------------------------------------------------
+r396 | zimmerma | 1999-10-20 10:20:12 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+removed lrand48 prototype (pb under Cygwin)
+
+------------------------------------------------------------------------
+r395 | zimmerma | 1999-10-20 10:19:30 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+added rounding instructions for Cygnus compiler under Windows
+
+------------------------------------------------------------------------
+r394 | zimmerma | 1999-10-20 10:18:14 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added dummy *rand48 functions for CYGWIN
+
+------------------------------------------------------------------------
+r393 | zimmerma | 1999-10-20 10:17:38 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+added info about gmp-mparam.h
+
+------------------------------------------------------------------------
+r392 | zimmerma | 1999-10-20 10:16:28 +0000 (Wed, 20 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+incorporated data for CYGWIN
+
+------------------------------------------------------------------------
+r391 | zimmerma | 1999-10-15 09:51:16 +0000 (Fri, 15 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added one test
+
+------------------------------------------------------------------------
+r390 | zimmerma | 1999-10-15 09:41:12 +0000 (Fri, 15 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tsqrt.c
+
+added boundary cases from paper from Michael Parks
+
+------------------------------------------------------------------------
+r389 | zimmerma | 1999-10-14 13:32:09 +0000 (Thu, 14 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+now set sign correctly
+
+------------------------------------------------------------------------
+r388 | zimmerma | 1999-10-14 13:31:45 +0000 (Thu, 14 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+added test to check sign is correctly set
+
+------------------------------------------------------------------------
+r387 | zimmerma | 1999-10-14 13:31:15 +0000 (Thu, 14 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added worst case for arg. reduction
+
+------------------------------------------------------------------------
+r386 | zimmerma | 1999-10-14 13:26:40 +0000 (Thu, 14 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+fixed bug when initial approx. floor(x/log(2)) is too large
+
+------------------------------------------------------------------------
+r385 | zimmerma | 1999-10-08 15:25:42 +0000 (Fri, 08 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+now use macros for Linux case, and added ifdef for _ISOC9X_SOURCE
+
+------------------------------------------------------------------------
+r384 | zimmerma | 1999-10-08 10:03:45 +0000 (Fri, 08 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+changed target dist to create archive in a directory
+
+------------------------------------------------------------------------
+r383 | zimmerma | 1999-10-07 15:12:09 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added targets doc and dist
+
+------------------------------------------------------------------------
+r382 | zimmerma | 1999-10-07 15:11:43 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/INSTALL
+
+added documentation and contact for problems
+
+------------------------------------------------------------------------
+r381 | zimmerma | 1999-10-07 14:54:54 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ A /trunk/INSTALL
+
+file for installation of mpfr
+
+------------------------------------------------------------------------
+r380 | zimmerma | 1999-10-07 14:09:58 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tout_str.c
+
+added more tests
+
+------------------------------------------------------------------------
+r379 | zimmerma | 1999-10-07 14:06:17 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+now deal with 0 and fixed bug on 64-bit machine
+
+------------------------------------------------------------------------
+r378 | zimmerma | 1999-10-07 08:15:21 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ D /trunk/sqrt3.c
+
+moved to sqrt.c
+
+------------------------------------------------------------------------
+r377 | zimmerma | 1999-10-07 08:14:56 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+now use directly mpn_sqrtrem (previously sqrt3.c)
+
+------------------------------------------------------------------------
+r376 | zimmerma | 1999-10-07 08:14:13 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+updated prototypes of mpfr_div/mpfr_sqrt
+
+------------------------------------------------------------------------
+r375 | zimmerma | 1999-10-07 08:11:25 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+ M /trunk/mpfr.h
+
+removed div3 and sqrt3
+
+------------------------------------------------------------------------
+r374 | zimmerma | 1999-10-07 08:10:06 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+div3 -> div
+
+------------------------------------------------------------------------
+r373 | zimmerma | 1999-10-07 08:09:41 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ D /trunk/div3.c
+
+moved to div.c
+
+------------------------------------------------------------------------
+r372 | zimmerma | 1999-10-07 08:08:48 +0000 (Thu, 07 Oct 1999) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+replaced implementation using Goldschmidt's algorithm
+by that using directly mpn_divrem (previously div3.c)
+
+------------------------------------------------------------------------
+r371 | zimmerma | 1999-10-07 08:07:46 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+sqrt3 -> sqrt
+
+------------------------------------------------------------------------
+r370 | zimmerma | 1999-10-07 08:05:54 +0000 (Thu, 07 Oct 1999) | 2 lines
+Changed paths:
+ A /trunk/COPYING.LIB
+
+GNU Library Public License
+
+------------------------------------------------------------------------
+r369 | zimmerma | 1999-08-31 08:56:55 +0000 (Tue, 31 Aug 1999) | 2 lines
+Changed paths:
+ M /trunk/set_z.c
+
+removed printf statement
+
+------------------------------------------------------------------------
+r368 | zimmerma | 1999-08-31 08:46:21 +0000 (Tue, 31 Aug 1999) | 2 lines
+Changed paths:
+ M /trunk/set_z.c
+
+added ABS for SIZ(z) when z<0
+
+------------------------------------------------------------------------
+r367 | zimmerma | 1999-08-31 08:45:45 +0000 (Tue, 31 Aug 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+removed special 'exact' stuff for n=0
+
+------------------------------------------------------------------------
+r366 | zimmerma | 1999-08-31 08:18:25 +0000 (Tue, 31 Aug 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+fixed prototype of random
+
+------------------------------------------------------------------------
+r365 | zimmerma | 1999-07-30 16:48:33 +0000 (Fri, 30 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+replaced GNU MPFR by MPFR (not yet the GNU label)
+
+------------------------------------------------------------------------
+r364 | zimmerma | 1999-07-30 16:47:40 +0000 (Fri, 30 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/add_ulp.c
+ M /trunk/agm.c
+ M /trunk/clear.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/div.c
+ M /trunk/div3.c
+ M /trunk/div_2exp.c
+ M /trunk/div_ui.c
+ M /trunk/exp.c
+ M /trunk/get_str.c
+ M /trunk/init.c
+ M /trunk/init_set.h
+ M /trunk/log.c
+ M /trunk/log2.c
+ M /trunk/mpfr-impl.h
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pi.c
+ M /trunk/pow.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/rnd_mode.c
+ M /trunk/round.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_dfl_prec.c
+ M /trunk/set_dfl_rnd.c
+ M /trunk/set_f.c
+ M /trunk/set_prec.c
+ M /trunk/set_si.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_z.c
+ M /trunk/sqrt.c
+ M /trunk/sqrt3.c
+ M /trunk/sub.c
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tcan_round.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tcmp2.c
+ M /trunk/tests/tcmp_ui.c
+ M /trunk/tests/tdiv.c
+ M /trunk/tests/tdiv_ui.c
+ M /trunk/tests/texp.c
+ M /trunk/tests/tget_str.c
+ M /trunk/tests/tlog.c
+ M /trunk/tests/tlog2.c
+ M /trunk/tests/tmul.c
+ M /trunk/tests/tmul_2exp.c
+ M /trunk/tests/tmul_ui.c
+ M /trunk/tests/tout_str.c
+ M /trunk/tests/tpi.c
+ M /trunk/tests/tround.c
+ M /trunk/tests/tset_d.c
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+ M /trunk/tests/tset_z.c
+ M /trunk/tests/tsqrt.c
+ M /trunk/tests/tzeta.c
+ M /trunk/zeta.c
+
+added copyright notice
+
+------------------------------------------------------------------------
+r363 | zimmerma | 1999-07-09 18:02:58 +0000 (Fri, 09 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_z.c
+
+added one test with prec=160
+
+------------------------------------------------------------------------
+r362 | zimmerma | 1999-07-09 18:02:08 +0000 (Fri, 09 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/pi.c
+
+error term is N+1 and not N
+
+------------------------------------------------------------------------
+r361 | zimmerma | 1999-07-09 18:00:39 +0000 (Fri, 09 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/set_z.c
+
+fixed bug in case sh=0
+
+------------------------------------------------------------------------
+r360 | zimmerma | 1999-07-08 16:28:56 +0000 (Thu, 08 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/round.c
+
+completely rewritten mpfr_can_round_raw, which costs now O(1)
+--- or more probably O(log n) --- instead of O(n)
+
+------------------------------------------------------------------------
+r359 | zimmerma | 1999-07-07 16:47:31 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+
+changed mpfr_init2 to mpfr_set_prec
+
+------------------------------------------------------------------------
+r358 | zimmerma | 1999-07-07 16:44:53 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added one test
+
+------------------------------------------------------------------------
+r357 | zimmerma | 1999-07-07 16:08:19 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+added prototype for mpfr_add1
+
+------------------------------------------------------------------------
+r356 | zimmerma | 1999-07-07 16:04:13 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcan_round.c
+
+added mpfr_clear
+
+------------------------------------------------------------------------
+r355 | hanrot | 1999-07-07 15:53:23 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt3.c
+
+sqrt3 now returns an exact / inexact flag.
+
+------------------------------------------------------------------------
+r354 | hanrot | 1999-07-07 15:52:58 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+sqrt3 now returns an exact/inexact flag.
+
+------------------------------------------------------------------------
+r353 | zimmerma | 1999-07-07 15:49:50 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+fix UMR (missing 0 terminating string)
+
+------------------------------------------------------------------------
+r352 | zimmerma | 1999-07-07 15:26:07 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/init.c
+
+put initialization of exponent back (avoids some UMRs)
+
+------------------------------------------------------------------------
+r351 | zimmerma | 1999-07-07 15:11:20 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed array bound write bug
+
+------------------------------------------------------------------------
+r350 | zimmerma | 1999-07-07 13:12:18 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added one test
+
+------------------------------------------------------------------------
+r349 | zimmerma | 1999-07-07 13:10:57 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+added several tests, and does not print on stdout when no argument
+
+------------------------------------------------------------------------
+r348 | zimmerma | 1999-07-07 13:09:37 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+fixed several bugs
+
+------------------------------------------------------------------------
+r347 | hanrot | 1999-07-07 11:37:10 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+Added an example which causes an ABW in mpz_get_str.
+
+------------------------------------------------------------------------
+r346 | zimmerma | 1999-07-07 11:35:17 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+moved drand to mpfr-impl.h and added test in large precision
+
+------------------------------------------------------------------------
+r345 | zimmerma | 1999-07-07 11:24:34 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added tout_str
+
+------------------------------------------------------------------------
+r344 | hanrot | 1999-07-07 10:12:23 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt3.c
+
+Problem with the exponents in the destructive case.
+
+------------------------------------------------------------------------
+r343 | zimmerma | 1999-07-07 10:04:22 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div3.c
+
+more changes from G. Hanrot
+
+------------------------------------------------------------------------
+r342 | zimmerma | 1999-07-07 10:00:45 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+use now drand48 instead of drand
+
+------------------------------------------------------------------------
+r341 | zimmerma | 1999-07-07 09:49:04 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+simply set to zero the non-significant bits, don't call mpfr_round_raw
+
+------------------------------------------------------------------------
+r340 | zimmerma | 1999-07-07 09:44:15 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div3.c
+
+upgrade from bug fixes from Guillaume Hanrot
+
+------------------------------------------------------------------------
+r339 | zimmerma | 1999-07-07 09:38:44 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/pi.c
+
+stores now last computed value together with its rounding mode
+
+------------------------------------------------------------------------
+r338 | zimmerma | 1999-07-07 09:23:24 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+checks now destructive version
+
+------------------------------------------------------------------------
+r337 | boldo | 1999-07-07 08:07:16 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+ M /trunk/tests/tlog.c
+
+changes on random
+
+------------------------------------------------------------------------
+r336 | boldo | 1999-07-07 08:00:29 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+using div3
+
+------------------------------------------------------------------------
+r335 | boldo | 1999-07-07 08:00:09 +0000 (Wed, 07 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+using sqrt3
+
+------------------------------------------------------------------------
+r334 | hanrot | 1999-07-06 16:56:56 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+HPUX support, 2nd try.
+
+------------------------------------------------------------------------
+r333 | hanrot | 1999-07-06 15:24:27 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div3.c
+ M /trunk/sqrt3.c
+
+Patch for the (very seldom encountered) case of even rounding.
+
+------------------------------------------------------------------------
+r332 | zimmerma | 1999-07-06 15:09:07 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+ M /trunk/tests/tset_si.c
+ M /trunk/tests/tset_str.c
+
+added def. for random/srandom, which do not exist under HPUX
+
+------------------------------------------------------------------------
+r331 | zimmerma | 1999-07-06 15:06:16 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/pi.c
+
+store now computed values
+
+------------------------------------------------------------------------
+r330 | zimmerma | 1999-07-06 15:05:42 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/log2.c
+
+_mpfr_log2_* -> __mpfr_log2_*
+
+------------------------------------------------------------------------
+r329 | zimmerma | 1999-07-06 14:48:33 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+merged machine rounding instructions for Sun and HP
+
+------------------------------------------------------------------------
+r328 | zimmerma | 1999-07-06 14:46:38 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+patch for HPUX (no random function)
+
+------------------------------------------------------------------------
+r327 | zimmerma | 1999-07-06 14:44:30 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added print_rnd_mode
+
+------------------------------------------------------------------------
+r326 | zimmerma | 1999-07-06 14:41:38 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+fixed prototype of mpfr_print_rnd_mode
+
+------------------------------------------------------------------------
+r325 | zimmerma | 1999-07-06 14:40:54 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+improved ulp to deal with case a=0.0
+
+------------------------------------------------------------------------
+r324 | zimmerma | 1999-07-06 14:40:13 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added return 0 to main
+
+------------------------------------------------------------------------
+r323 | hanrot | 1999-07-06 14:00:29 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div3.c
+
+Forgotten casts.
+
+------------------------------------------------------------------------
+r322 | hanrot | 1999-07-06 12:55:14 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Added sqrt3 + tentative support for Alpha linux.
+
+------------------------------------------------------------------------
+r321 | hanrot | 1999-07-06 12:40:17 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt3.c
+
+The word added when the exponent is odd was sometimes unitialized.
+
+------------------------------------------------------------------------
+r320 | hanrot | 1999-07-06 09:39:42 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ A /trunk/sqrt3.c
+
+Initial version.
+
+------------------------------------------------------------------------
+r319 | hanrot | 1999-07-06 09:39:20 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Added mpfr_sqrt3.
+
+------------------------------------------------------------------------
+r318 | zimmerma | 1999-07-06 09:23:25 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added several functions, and updated others
+
+------------------------------------------------------------------------
+r317 | zimmerma | 1999-07-06 09:19:09 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+changed prototype of mpfr_log
+
+------------------------------------------------------------------------
+r316 | zimmerma | 1999-07-06 09:17:28 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+returns now an int instead of void
+
+------------------------------------------------------------------------
+r315 | zimmerma | 1999-07-06 09:16:41 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/init.c
+
+removed initialization of exponent
+
+------------------------------------------------------------------------
+r314 | zimmerma | 1999-07-06 09:16:03 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+
+special case for exp(0)
+
+------------------------------------------------------------------------
+r313 | zimmerma | 1999-07-06 09:15:40 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added test for exp(0)
+
+------------------------------------------------------------------------
+r312 | hanrot | 1999-07-06 08:31:45 +0000 (Tue, 06 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+config.in -> ./config.in
+
+------------------------------------------------------------------------
+r311 | boldo | 1999-07-05 18:55:08 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+new, quick & clean
+
+------------------------------------------------------------------------
+r310 | zimmerma | 1999-07-05 16:35:27 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added two tests and converted to double's
+
+------------------------------------------------------------------------
+r309 | boldo | 1999-07-05 16:27:31 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+more checking ways
+
+------------------------------------------------------------------------
+r308 | zimmerma | 1999-07-05 15:24:16 +0000 (Mon, 05 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+distinguishes now between true errors and differences with libm.a
+(which may fail too)
+
+------------------------------------------------------------------------
+r307 | zimmerma | 1999-07-05 14:55:12 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+removed mpf stuff in check
+
+------------------------------------------------------------------------
+r306 | zimmerma | 1999-07-05 14:49:59 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_d.c
+
+added some mpfr_clear's
+
+------------------------------------------------------------------------
+r305 | zimmerma | 1999-07-05 14:45:58 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+changed defs of random/srandom to work on Alpha
+
+------------------------------------------------------------------------
+r304 | zimmerma | 1999-07-05 14:45:12 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+mpfr_init2 -> mpfr_set_prec in check64
+
+------------------------------------------------------------------------
+r303 | zimmerma | 1999-07-05 14:30:48 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+added function dbl
+
+------------------------------------------------------------------------
+r302 | zimmerma | 1999-07-05 14:30:19 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototypes for mpfr_cmp3 and mpfr_set4
+
+------------------------------------------------------------------------
+r301 | zimmerma | 1999-07-05 14:06:18 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/neg.c
+
+use mpfr_set4 now (no modification of const parameters any more)
+
+------------------------------------------------------------------------
+r300 | zimmerma | 1999-07-05 14:05:33 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+return 0 in mpfr_can_round_raw
+
+------------------------------------------------------------------------
+r299 | zimmerma | 1999-07-05 14:04:38 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+introduced auxiliary function mpfr_set4
+
+------------------------------------------------------------------------
+r298 | zimmerma | 1999-07-05 14:01:07 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+fixed possible bug (testing sign of unsigned long) in mpfr_mul_ui
+
+------------------------------------------------------------------------
+r297 | zimmerma | 1999-07-05 14:00:11 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div3.c
+
+replaced PREC(r) by prec (which was defined but not used)
+
+------------------------------------------------------------------------
+r296 | zimmerma | 1999-07-05 13:59:08 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv_ui.c
+
+moved drand and ulp to mpfr-impl
+
+------------------------------------------------------------------------
+r295 | zimmerma | 1999-07-05 13:55:23 +0000 (Mon, 05 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+moved ulp to mpfr-impl.h
+and used input routine 'dbl' in some tests
+
+------------------------------------------------------------------------
+r294 | zimmerma | 1999-07-05 13:32:55 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+modified one test to avoid rounding from double input routines
+
+------------------------------------------------------------------------
+r293 | zimmerma | 1999-07-05 13:18:06 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+introduced auxiliary function mpfr_cmp3(x,y,sign) to compare x and sign*y
+
+------------------------------------------------------------------------
+r292 | zimmerma | 1999-07-05 13:16:55 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+moved drand and ulp to mpfr-impl.h
+
+------------------------------------------------------------------------
+r291 | zimmerma | 1999-07-05 13:15:48 +0000 (Mon, 05 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/sub.c
+
+mpfr_sub now calls directly mpfr_add1/mpfr_sub1 (no modification of
+const parameters any more)
+
+------------------------------------------------------------------------
+r290 | zimmerma | 1999-07-05 13:14:13 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp.c
+
+moved drand to mpfr-implh.h
+
+------------------------------------------------------------------------
+r289 | zimmerma | 1999-07-05 13:12:55 +0000 (Mon, 05 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/add.c
+
+use mpfr_cmp3 instead of mpfr_cmp (avoids warning due to modification of
+const parameters)
+
+------------------------------------------------------------------------
+r288 | zimmerma | 1999-07-05 13:11:42 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+moved drand to mpfr-impl.h and removed warnings
+
+------------------------------------------------------------------------
+r287 | zimmerma | 1999-07-05 12:34:27 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/zeta.c
+
+use the result of mpfr_can_round
+
+------------------------------------------------------------------------
+r286 | zimmerma | 1999-07-05 11:05:32 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+moved drand and ulp to mpfr-impl.h
+
+------------------------------------------------------------------------
+r285 | zimmerma | 1999-07-05 11:03:46 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_d.c
+
+moved drand to mpfr-impl.h
+
+------------------------------------------------------------------------
+r284 | zimmerma | 1999-07-05 10:56:30 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+moved drand to mpfr-impl and removed warnings
+
+------------------------------------------------------------------------
+r283 | zimmerma | 1999-07-05 10:55:30 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr-impl.h
+
+added include of math.h
+
+------------------------------------------------------------------------
+r282 | zimmerma | 1999-07-05 10:52:07 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+moved drand and ulp to mpfr-impl.h
+
+------------------------------------------------------------------------
+r281 | zimmerma | 1999-07-05 10:51:37 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ A /trunk/mpfr-impl.h
+
+include file for mpfr developers only
+
+------------------------------------------------------------------------
+r280 | zimmerma | 1999-07-05 10:45:52 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+long -> int in drand
+
+------------------------------------------------------------------------
+r279 | zimmerma | 1999-07-05 10:43:11 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+adapted drand to sizeof(long)=64
+
+------------------------------------------------------------------------
+r278 | zimmerma | 1999-07-05 10:12:44 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+config.in -> ./config.in (otherwise don't work under IRIX)
+
+------------------------------------------------------------------------
+r277 | zimmerma | 1999-07-05 09:42:53 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv_ui.c
+
+removed warnings
+
+------------------------------------------------------------------------
+r276 | zimmerma | 1999-07-05 09:42:20 +0000 (Mon, 05 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+patch for GMP bug when UDIV_NEEDS_NORMALIZATION=1
+
+------------------------------------------------------------------------
+r275 | hanrot | 1999-07-02 17:51:54 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div3.c
+
+Correction of a typo.
+
+------------------------------------------------------------------------
+r274 | zimmerma | 1999-07-02 16:13:14 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div_ui.c
+
+fixed horrible hack yp[-1]
+
+------------------------------------------------------------------------
+r273 | hanrot | 1999-07-02 15:47:18 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Support of IRIX64 (n32/64 modes) plus cosmetic modifications.
+
+------------------------------------------------------------------------
+r272 | zimmerma | 1999-07-02 12:29:31 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added one test, and adapted to ANSI C
+
+------------------------------------------------------------------------
+r271 | hanrot | 1999-07-02 12:28:06 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Yet Another Backslash Forgotten...
+
+------------------------------------------------------------------------
+r270 | hanrot | 1999-07-02 12:26:33 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div3.c
+
+Bug le plus stupide de tous les temps corrige. Ca marchait sous Solaris...
+
+------------------------------------------------------------------------
+r269 | zimmerma | 1999-07-02 12:25:39 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+added one test and removed warnings
+
+------------------------------------------------------------------------
+r268 | hanrot | 1999-07-02 12:22:02 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Added mpfr_div3.
+
+------------------------------------------------------------------------
+r267 | hanrot | 1999-07-02 12:21:42 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Added div3.c
+
+------------------------------------------------------------------------
+r266 | zimmerma | 1999-07-02 12:19:59 +0000 (Fri, 02 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/add.c
+
+fixed bug when sizeof(long) <> sizeof(mp_limb_t)
+and removed DEBUG2 stuff
+
+------------------------------------------------------------------------
+r265 | zimmerma | 1999-07-02 12:19:03 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added one test, and removed warnings
+
+------------------------------------------------------------------------
+r264 | hanrot | 1999-07-02 12:18:47 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ A /trunk/div3.c
+
+Added div3.c, initial release.
+
+------------------------------------------------------------------------
+r263 | hanrot | 1999-07-02 11:45:22 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Patch of the patch :)
+
+------------------------------------------------------------------------
+r262 | hanrot | 1999-07-02 11:27:38 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Pattern matching rules in tests Makefile for non-GNU make (eg Solaris)
+
+------------------------------------------------------------------------
+r261 | zimmerma | 1999-07-02 11:24:09 +0000 (Fri, 02 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+adapted to enable denormalized numbers on IRIX64, added one test and
+removed warnings
+
+------------------------------------------------------------------------
+r260 | zimmerma | 1999-07-02 11:21:42 +0000 (Fri, 02 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/round.c
+
+changed type of 3rd arg. 'neg' of mpfr_can_round_raw from char to int
+(pb with signed char's on some machines, e.g. IRIX64)
+
+------------------------------------------------------------------------
+r259 | zimmerma | 1999-07-02 10:09:00 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+adapted to IRIX64 (enable denorm. numbers) and removed warnings
+
+------------------------------------------------------------------------
+r258 | zimmerma | 1999-07-02 10:06:05 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+adapted to IRIX64 (enable denormalized numbers) and removed warnings
+
+------------------------------------------------------------------------
+r257 | zimmerma | 1999-07-02 10:03:28 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+adapted to IRIX64 (no denormalized by default) and removed warnings
+
+------------------------------------------------------------------------
+r256 | zimmerma | 1999-07-02 09:55:41 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+unsigned long -> mp_limb_t
+
+------------------------------------------------------------------------
+r255 | boldo | 1999-07-02 09:51:06 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+unused variables
+
+------------------------------------------------------------------------
+r254 | boldo | 1999-07-02 09:50:16 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+unused variable
+
+------------------------------------------------------------------------
+r253 | zimmerma | 1999-07-02 09:43:38 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+added ifdef to avoid warning "unused variable" on 64-bit machine
+
+------------------------------------------------------------------------
+r252 | zimmerma | 1999-07-02 09:42:58 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/rnd_mode.c
+
+added def. of swapRM to avoid warning on IRIX64
+
+------------------------------------------------------------------------
+r251 | zimmerma | 1999-07-02 09:36:03 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/print_raw.c
+ M /trunk/round.c
+
+1UL -> ((mp_limb_t) 1)
+
+------------------------------------------------------------------------
+r250 | zimmerma | 1999-07-02 09:32:47 +0000 (Fri, 02 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+changed type of mask to mp_limb_t in mpfr_round_raw2
+
+------------------------------------------------------------------------
+r249 | zimmerma | 1999-07-02 09:26:13 +0000 (Fri, 02 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_d.c
+
+adapted for denormalized on IRIX64
+now test NaNs too
+
+------------------------------------------------------------------------
+r248 | hanrot | 1999-07-01 17:20:43 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+Due to the representation of 0 it might have happened that 0 != 0.
+
+------------------------------------------------------------------------
+r247 | hanrot | 1999-07-01 17:09:00 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+Patch mpfr_set -> MPN_COPY
+
+------------------------------------------------------------------------
+r246 | hanrot | 1999-07-01 17:08:12 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+Patch when prec < 32.
+
+------------------------------------------------------------------------
+r245 | zimmerma | 1999-07-01 17:00:58 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+fixed bugs for 64-bit machines
+
+------------------------------------------------------------------------
+r244 | zimmerma | 1999-07-01 16:59:36 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+added casts to mp_limb_t
+
+------------------------------------------------------------------------
+r243 | zimmerma | 1999-07-01 16:54:40 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+added cast to mp_limb_t for shifts
+
+------------------------------------------------------------------------
+r242 | boldo | 1999-07-01 14:35:42 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+prints nothing is everything is allright
+
+------------------------------------------------------------------------
+r241 | boldo | 1999-07-01 14:20:32 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+memory gestion
+
+------------------------------------------------------------------------
+r240 | boldo | 1999-07-01 14:19:36 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+one single bug
+
+------------------------------------------------------------------------
+r239 | boldo | 1999-07-01 14:19:12 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+more bad cases
+
+------------------------------------------------------------------------
+r238 | zimmerma | 1999-07-01 14:08:04 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added some certified tests
+
+------------------------------------------------------------------------
+r237 | zimmerma | 1999-07-01 12:47:55 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+added one test to check that 1*y = y
+
+------------------------------------------------------------------------
+r236 | hanrot | 1999-07-01 12:19:09 +0000 (Thu, 01 Jul 1999) | 3 lines
+Changed paths:
+ M /trunk/div.c
+
+Patch of an MLK due to multiple initialization of the same variables without
+freeing them inbetween.
+
+------------------------------------------------------------------------
+r235 | hanrot | 1999-07-01 12:09:49 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+Same as in sqrt (allocation problem).
+
+------------------------------------------------------------------------
+r234 | zimmerma | 1999-07-01 11:58:48 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+fixed bug due to shift=0 in mpn_rshift
+
+------------------------------------------------------------------------
+r233 | hanrot | 1999-07-01 10:43:19 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+(Temporary) patch for memory gestion in sqrt.c
+
+------------------------------------------------------------------------
+r232 | zimmerma | 1999-07-01 09:40:55 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+mpfr_init -> mpfr_init2
+
+------------------------------------------------------------------------
+r231 | zimmerma | 1999-07-01 09:39:56 +0000 (Thu, 01 Jul 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+initialize temporary variables with current precision
+
+------------------------------------------------------------------------
+r230 | hanrot | 1999-06-30 15:47:13 +0000 (Wed, 30 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/clear.c
+
+Unbelievably stupid bug fixed.
+
+------------------------------------------------------------------------
+r229 | hanrot | 1999-06-30 15:14:47 +0000 (Wed, 30 Jun 1999) | 3 lines
+Changed paths:
+ M /trunk/round.c
+
+Two patches : one for an UMR which actually had no effect, one for an FNH in
+old code..
+
+------------------------------------------------------------------------
+r228 | boldo | 1999-06-30 14:55:48 +0000 (Wed, 30 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+new bug
+
+------------------------------------------------------------------------
+r227 | boldo | 1999-06-30 13:30:46 +0000 (Wed, 30 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+there were some conflicts
+
+------------------------------------------------------------------------
+r226 | boldo | 1999-06-30 13:30:25 +0000 (Wed, 30 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+ther were some conflicts
+
+------------------------------------------------------------------------
+r225 | boldo | 1999-06-30 13:29:47 +0000 (Wed, 30 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/log.c
+
+memory gestion
+
+------------------------------------------------------------------------
+r224 | zimmerma | 1999-06-29 17:53:45 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tzeta.c
+
+replaced outputs by direct comparison when no argument
+
+------------------------------------------------------------------------
+r223 | zimmerma | 1999-06-29 17:46:38 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+modified to do only certified test when no argument
+
+------------------------------------------------------------------------
+r222 | zimmerma | 1999-06-29 17:27:34 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+modified to do only tests with precomputed values when no argument
+
+------------------------------------------------------------------------
+r221 | zimmerma | 1999-06-29 16:13:33 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+does exact rounding only for n=0
+
+------------------------------------------------------------------------
+r220 | remy | 1999-06-29 15:59:22 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added zeta/tzeta
+
+------------------------------------------------------------------------
+r219 | remy | 1999-06-29 15:58:51 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototypes for mpfr_exp and mpfr_zeta
+
+------------------------------------------------------------------------
+r218 | remy | 1999-06-29 15:58:05 +0000 (Tue, 29 Jun 1999) | 3 lines
+Changed paths:
+ A /trunk/zeta.c
+
+computes Riemann function Zeta(s)
+first version: only works for s=2 with PREC(result)=53 and rnd_mode=nearest
+
+------------------------------------------------------------------------
+r217 | remy | 1999-06-29 15:57:01 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/tests/tzeta.c
+
+test file for mpfr_zeta
+
+------------------------------------------------------------------------
+r216 | remy | 1999-06-29 15:49:15 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added prototype for mpfr_set_default_prec
+
+------------------------------------------------------------------------
+r215 | remy | 1999-06-29 15:40:28 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ D /trunk/zeta2.c
+
+file renamed zeta.c
+
+------------------------------------------------------------------------
+r214 | remy | 1999-06-29 15:26:33 +0000 (Tue, 29 Jun 1999) | 3 lines
+Changed paths:
+ A /trunk/zeta2.c
+
+first version: computes Zeta(2) with fixed precision 53 bits and round
+to nearest
+
+------------------------------------------------------------------------
+r213 | hanrot | 1999-06-29 14:48:29 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Patch in the case when the number of bits is a multiple of the word size.
+
+------------------------------------------------------------------------
+r212 | hanrot | 1999-06-29 14:47:58 +0000 (Tue, 29 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+Patch in the case when the low words of the product are zero.
+
+------------------------------------------------------------------------
+r211 | zimmerma | 1999-06-28 13:51:15 +0000 (Mon, 28 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+changed arguments of mpfr_round_raw (continued)
+
+------------------------------------------------------------------------
+r210 | zimmerma | 1999-06-28 13:48:44 +0000 (Mon, 28 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+ M /trunk/mpfr.texi
+ M /trunk/mul.c
+ M /trunk/mul_ui.c
+ M /trunk/random.c
+ M /trunk/round.c
+ M /trunk/set.c
+
+changed arguments of mpfr_round_raw (now uses precision instead of size)
+
+------------------------------------------------------------------------
+r209 | zimmerma | 1999-06-28 11:50:04 +0000 (Mon, 28 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tpi.c
+
+modified wrt warnings at compilation
+
+------------------------------------------------------------------------
+r208 | zimmerma | 1999-06-28 11:49:08 +0000 (Mon, 28 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+modified description of mpfr_get_str for n_digits=0
+
+------------------------------------------------------------------------
+r207 | zimmerma | 1999-06-28 11:48:15 +0000 (Mon, 28 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+now performs an exact output when n_digits=0
+
+------------------------------------------------------------------------
+r206 | hanrot | 1999-06-28 07:37:06 +0000 (Mon, 28 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+Yet another corrected prototype.
+
+------------------------------------------------------------------------
+r205 | hanrot | 1999-06-25 17:36:57 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/add_ulp.c
+ M /trunk/agm.c
+ M /trunk/cmp.c
+ M /trunk/cmp_ui.c
+ M /trunk/div.c
+ M /trunk/div_2exp.c
+ M /trunk/div_ui.c
+ M /trunk/exp.c
+ M /trunk/get_str.c
+ M /trunk/log.c
+ M /trunk/log2.c
+ M /trunk/mpfr.h
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/out_str.c
+ M /trunk/pi.c
+ M /trunk/pow.c
+ M /trunk/print_raw.c
+ M /trunk/print_rnd_mode.c
+ M /trunk/random.c
+ M /trunk/rnd_mode.c
+ M /trunk/round.c
+ M /trunk/set.c
+ M /trunk/set_d.c
+ M /trunk/set_f.c
+ M /trunk/set_si.c
+ M /trunk/set_str_raw.c
+ M /trunk/set_z.c
+ M /trunk/sqrt.c
+ M /trunk/sub.c
+
+Prototypes et quelques causes de warnings corriges.
+
+------------------------------------------------------------------------
+r204 | hanrot | 1999-06-25 17:20:06 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Modifs cosmetiques.
+
+------------------------------------------------------------------------
+r203 | hanrot | 1999-06-25 17:19:55 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ D /trunk/set_str.c
+
+Fichier vide.
+
+------------------------------------------------------------------------
+r202 | zimmerma | 1999-06-25 16:30:07 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog2.c
+
+do not print anything when no argument
+
+------------------------------------------------------------------------
+r201 | zimmerma | 1999-06-25 16:20:11 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/out_str.c
+
+use GMP allocate/free functions instead of malloc/free
+
+------------------------------------------------------------------------
+r200 | zimmerma | 1999-06-25 16:08:32 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcan_round.c
+
+do not print anything on stdout
+
+------------------------------------------------------------------------
+r199 | zimmerma | 1999-06-25 16:07:34 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+put correctly sign with macro CHANGE_SIGN
+
+------------------------------------------------------------------------
+r198 | hanrot | 1999-06-25 16:00:38 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Ajoute la dependance de libmpfr.a pour le Makefile des tests.
+
+------------------------------------------------------------------------
+r197 | zimmerma | 1999-06-25 15:54:04 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+correctly handle case sizer=1 in mpfr_set_d
+
+------------------------------------------------------------------------
+r196 | zimmerma | 1999-06-25 15:53:19 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+corrected allocated size in mpfr_round
+
+------------------------------------------------------------------------
+r195 | zimmerma | 1999-06-25 15:51:49 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+make clean does not remove config.in any more
+
+------------------------------------------------------------------------
+r194 | hanrot | 1999-06-25 15:16:10 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+Correction d'un UMR en inversant le while (sans incidence tres probablement).
+
+------------------------------------------------------------------------
+r193 | zimmerma | 1999-06-25 15:12:04 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added four tests
+
+------------------------------------------------------------------------
+r192 | zimmerma | 1999-06-25 15:07:31 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+adapted mpfr_set_d to case where allocated limbs > significant limbs
+
+------------------------------------------------------------------------
+r191 | zimmerma | 1999-06-25 15:05:10 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed bug for b=2^n and c very small
+
+------------------------------------------------------------------------
+r190 | hanrot | 1999-06-25 14:36:27 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Some limbs of the result where not set to zero as they should.
+
+------------------------------------------------------------------------
+r189 | zimmerma | 1999-06-25 13:32:39 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+added prototypes, and errors to stderr
+
+------------------------------------------------------------------------
+r188 | zimmerma | 1999-06-25 13:17:23 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ D /trunk/tests/tset_i
+
+binary file -> remove it
+
+------------------------------------------------------------------------
+r187 | zimmerma | 1999-06-25 13:16:04 +0000 (Fri, 25 Jun 1999) | 3 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+use PREC(x) instead of ABSSIZE(x) to get number of significant limbs
+adapted to different numbers of significant limbs for x and y
+
+------------------------------------------------------------------------
+r186 | zimmerma | 1999-06-25 13:05:45 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+fixed pbs with ABSSIZE(x) wrt PREC(x) in mpfr_round
+
+------------------------------------------------------------------------
+r185 | zimmerma | 1999-06-25 13:01:20 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+added pointer to exponent, removed test with sprintf
+
+------------------------------------------------------------------------
+r184 | zimmerma | 1999-06-25 13:00:05 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+removed DEBUG stuff
+
+------------------------------------------------------------------------
+r183 | zimmerma | 1999-06-25 12:57:10 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+use PREC(x) instead of ABSSIZE(x) to get the number of significant limbs
+
+------------------------------------------------------------------------
+r182 | zimmerma | 1999-06-25 12:56:22 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_si.c
+
+do 10^6 tests if no argument
+
+------------------------------------------------------------------------
+r181 | hanrot | 1999-06-25 12:30:43 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+J'avais oublie -g...
+
+------------------------------------------------------------------------
+r180 | hanrot | 1999-06-25 12:23:51 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Ajoute des flags de paranoiaque schizophrene.
+
+------------------------------------------------------------------------
+r179 | zimmerma | 1999-06-25 11:43:25 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+now prints nothing with no argument
+
+------------------------------------------------------------------------
+r178 | zimmerma | 1999-06-25 11:22:28 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added texp and tdiv_ui
+
+------------------------------------------------------------------------
+r177 | zimmerma | 1999-06-25 11:21:30 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/tests/tdiv_ui.c
+
+test file for div_ui, initial revision
+
+------------------------------------------------------------------------
+r176 | zimmerma | 1999-06-25 10:19:42 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+commented out "avant arrondi..."
+
+------------------------------------------------------------------------
+r175 | zimmerma | 1999-06-25 10:17:40 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+clear res1/res2
+
+------------------------------------------------------------------------
+r174 | hanrot | 1999-06-25 10:17:26 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Patches an ABR.
+
+------------------------------------------------------------------------
+r173 | hanrot | 1999-06-25 10:15:54 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+Patch of an ABR.
+
+------------------------------------------------------------------------
+r172 | hanrot | 1999-06-25 10:15:21 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/pow.c
+
+Patch in the case n = 0.
+
+------------------------------------------------------------------------
+r171 | hanrot | 1999-06-25 10:14:45 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/out_str.c
+
+Patch for a memory leak.
+
+------------------------------------------------------------------------
+r170 | zimmerma | 1999-06-25 10:13:14 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added two tests for exact roots
+
+------------------------------------------------------------------------
+r169 | zimmerma | 1999-06-25 10:12:11 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+removed DEBUG stuff and fixed pb with exact root and GMP_RNDZ
+
+------------------------------------------------------------------------
+r168 | hanrot | 1999-06-25 09:42:53 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+Correction d'un ABR.
+
+------------------------------------------------------------------------
+r167 | zimmerma | 1999-06-25 09:38:52 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tpi.c
+
+added test for prec=53 bits, removed output for argc==1
+
+------------------------------------------------------------------------
+r166 | hanrot | 1999-06-25 09:28:43 +0000 (Fri, 25 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/tests/tcan_round.c
+
+Initial revision.
+
+------------------------------------------------------------------------
+r165 | hanrot | 1999-06-24 12:22:57 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/sub.c
+
+Patched an Array Bound Read.
+
+------------------------------------------------------------------------
+r164 | hanrot | 1999-06-24 12:10:00 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Corrected an Array Bound Read when all the bits are significative.
+
+------------------------------------------------------------------------
+r163 | zimmerma | 1999-06-24 12:00:31 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp_ui.c
+
+i -> s in tests on mpfr_cmp_si
+
+------------------------------------------------------------------------
+r162 | zimmerma | 1999-06-24 11:59:05 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp_ui.c
+
+fixed pb in mpfr_cmp_si_2exp (case b=0 or i=0)
+
+------------------------------------------------------------------------
+r161 | zimmerma | 1999-06-24 11:55:25 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+& -> &&
+
+------------------------------------------------------------------------
+r160 | zimmerma | 1999-06-24 11:40:48 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tcmp.c
+ M /trunk/tests/tset_str.c
+
+removed 3rd arg. of mpfr_set_prec
+
+------------------------------------------------------------------------
+r159 | zimmerma | 1999-06-24 11:37:54 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+treats case b=c in mpfr_sub(a,b,c)
+
+------------------------------------------------------------------------
+r158 | zimmerma | 1999-06-24 11:36:43 +0000 (Thu, 24 Jun 1999) | 3 lines
+Changed paths:
+ M /trunk/set_prec.c
+
+removed 3rd argument in mpfr_set_prec
+reallocates only when more limbs are needed
+
+------------------------------------------------------------------------
+r157 | zimmerma | 1999-06-24 11:34:22 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/exp.c
+ M /trunk/log2.c
+
+removed 3rd arg. of mpfr_set_prec
+
+------------------------------------------------------------------------
+r156 | zimmerma | 1999-06-24 11:32:11 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+added some mpfr_clear's that were missing
+
+------------------------------------------------------------------------
+r155 | zimmerma | 1999-06-24 10:16:54 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+removed 3rd argument from mpfr_set_prec
+
+------------------------------------------------------------------------
+r154 | zimmerma | 1999-06-24 10:12:43 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+ M /trunk/sqrt.c
+
+removed 3rd argument of mpfr_set_prec
+
+------------------------------------------------------------------------
+r153 | zimmerma | 1999-06-24 10:09:40 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+changed prototype of mpfr_set_prec (no rounding mode needed any more)
+
+------------------------------------------------------------------------
+r152 | zimmerma | 1999-06-24 07:57:30 +0000 (Thu, 24 Jun 1999) | 3 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+added test for case of missing exponent
+and if one argument, print it as a double
+
+------------------------------------------------------------------------
+r151 | zimmerma | 1999-06-24 07:56:19 +0000 (Thu, 24 Jun 1999) | 3 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+fixed bug when exponent was missing (wrong result when part before
+binary point is not zero)
+
+------------------------------------------------------------------------
+r150 | zimmerma | 1999-06-24 07:47:59 +0000 (Thu, 24 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added tests from JM Muller and V Lefevre
+
+------------------------------------------------------------------------
+r149 | zimmerma | 1999-06-23 16:37:03 +0000 (Wed, 23 Jun 1999) | 4 lines
+Changed paths:
+ M /trunk/round.c
+
+corrected bad case in mpfr_can_round_raw where rnd1=GMP_RNDN
+and err is a multiple of BITS_PER_MP_LIMB (was modifying an
+extra limb perhaps not allocated)
+
+------------------------------------------------------------------------
+r148 | boldo | 1999-06-23 16:02:24 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+qq bugs d'arrondis
+
+------------------------------------------------------------------------
+r147 | zimmerma | 1999-06-23 15:57:14 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added exp and div_ui
+
+------------------------------------------------------------------------
+r146 | zimmerma | 1999-06-23 15:56:35 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/texp.c
+
+added test of exp(Pi*sqrt(163)/3)-640320 [texp 0.0 prec]
+
+------------------------------------------------------------------------
+r145 | zimmerma | 1999-06-23 15:44:33 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/tests/texp.c
+
+test file for mpfr_exp, initial revision
+
+------------------------------------------------------------------------
+r144 | zimmerma | 1999-06-23 13:02:11 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+added two tests
+
+------------------------------------------------------------------------
+r143 | zimmerma | 1999-06-23 12:57:56 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_str.c
+
+removed printf's and added one test for leading '+'
+
+------------------------------------------------------------------------
+r142 | zimmerma | 1999-06-23 12:56:26 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_str_raw.c
+
+now allows leading '+'
+
+------------------------------------------------------------------------
+r141 | boldo | 1999-06-23 11:34:03 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+nettoye
+
+------------------------------------------------------------------------
+r140 | zimmerma | 1999-06-23 10:00:37 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tset_f.c
+
+removed printf
+
+------------------------------------------------------------------------
+r139 | zimmerma | 1999-06-23 10:00:05 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+ M /trunk/tests/tmul_ui.c
+
+removed printf's
+
+------------------------------------------------------------------------
+r138 | zimmerma | 1999-06-23 09:59:31 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+added tests for large precision (tlog x prec rnd)
+
+------------------------------------------------------------------------
+r137 | zimmerma | 1999-06-23 09:58:29 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added test for exact division
+
+------------------------------------------------------------------------
+r136 | zimmerma | 1999-06-23 09:57:57 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tcmp2.c
+
+mpfr_cmp -> mpfr_cmp2
+
+------------------------------------------------------------------------
+r135 | zimmerma | 1999-06-23 09:57:23 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+removed printf, added exit on error
+
+------------------------------------------------------------------------
+r134 | zimmerma | 1999-06-23 09:55:43 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/exp.c
+
+initial revision
+
+------------------------------------------------------------------------
+r133 | zimmerma | 1999-06-23 09:50:41 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+cleaned local variables
+
+------------------------------------------------------------------------
+r132 | zimmerma | 1999-06-23 09:49:07 +0000 (Wed, 23 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+changed prototype of mpfr_div (now returns int)
+
+------------------------------------------------------------------------
+r131 | zimmerma | 1999-06-23 09:47:12 +0000 (Wed, 23 Jun 1999) | 4 lines
+Changed paths:
+ M /trunk/div.c
+
+now deals correctly with exact division
+removed DEBUG stuff
+returns 0/1 according to exact division
+
+------------------------------------------------------------------------
+r130 | zimmerma | 1999-06-22 17:12:20 +0000 (Tue, 22 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+fixed bug found by F. Rouillier: x * Z(2/x) -> 0 [carry from mpfr_round_raw]
+
+------------------------------------------------------------------------
+r129 | hanrot | 1999-06-22 13:33:35 +0000 (Tue, 22 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_prec.c
+
+Fill with 0 the part added in case of a larger reallocation.
+
+------------------------------------------------------------------------
+r128 | hanrot | 1999-06-22 12:39:01 +0000 (Tue, 22 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+Rajoute le bug report de Fabrice.
+
+------------------------------------------------------------------------
+r127 | zimmerma | 1999-06-22 12:18:25 +0000 (Tue, 22 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+fixed bug in mpfr_can_round when prec or err are multiples of BITS_PER_MP_LIMB
+
+------------------------------------------------------------------------
+r126 | zimmerma | 1999-06-22 12:16:28 +0000 (Tue, 22 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul.c
+
+added test to check sign of result
+
+------------------------------------------------------------------------
+r125 | zimmerma | 1999-06-22 12:14:44 +0000 (Tue, 22 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+fixed bug: wrong sign when SIGN(a)<0 at beginning
+
+------------------------------------------------------------------------
+r124 | boldo | 1999-06-22 09:51:16 +0000 (Tue, 22 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+avec plein de cas d'erreurs
+
+------------------------------------------------------------------------
+r123 | boldo | 1999-06-22 09:47:20 +0000 (Tue, 22 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/log.c
+
+marche bien
+
+------------------------------------------------------------------------
+r122 | boldo | 1999-06-22 09:47:04 +0000 (Tue, 22 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+Marche bien
+
+------------------------------------------------------------------------
+r121 | hanrot | 1999-06-21 16:00:30 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Corrected prototype of mpfr_can_round_raw.
+
+------------------------------------------------------------------------
+r120 | hanrot | 1999-06-21 16:00:11 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Various patches.
+
+------------------------------------------------------------------------
+r119 | hanrot | 1999-06-21 15:39:24 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Added prototype for mpfr_can_round_raw
+
+------------------------------------------------------------------------
+r118 | hanrot | 1999-06-21 15:34:57 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Added mpfr_can_round_raw ; mpfr_can_round just calls it.
+
+------------------------------------------------------------------------
+r117 | hanrot | 1999-06-21 15:26:56 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Declaration mpfr_print_rnd_mode.c
+
+------------------------------------------------------------------------
+r116 | hanrot | 1999-06-21 15:26:39 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/print_rnd_mode.c
+
+print_rnd_mode.c -> mpfr_print_rnd_mode.c
+
+------------------------------------------------------------------------
+r115 | hanrot | 1999-06-21 15:07:36 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/print_rnd_mode.c
+
+Print the rounding mode.
+
+------------------------------------------------------------------------
+r114 | hanrot | 1999-06-21 13:45:56 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_prec.c
+
+Changement de semantique (plus d'arrondi) et alloc + free -> realloc.
+
+------------------------------------------------------------------------
+r113 | zimmerma | 1999-06-21 11:28:36 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/div_ui.c
+
+initial revision
+
+------------------------------------------------------------------------
+r112 | zimmerma | 1999-06-21 11:27:29 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_ui.c
+
+added one test
+
+------------------------------------------------------------------------
+r111 | zimmerma | 1999-06-21 11:24:33 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set.c
+
+now deal with carry from mpfr_round_raw
+
+------------------------------------------------------------------------
+r110 | zimmerma | 1999-06-21 11:17:13 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+fixed problem with count_leading_zeros undefined for 0
+
+------------------------------------------------------------------------
+r109 | zimmerma | 1999-06-21 11:16:02 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/log2.c
+
+store computed value and try to reuse it for next calls
+
+------------------------------------------------------------------------
+r108 | zimmerma | 1999-06-21 11:14:46 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+added test cn>= in mpfr_cmp2
+
+------------------------------------------------------------------------
+r107 | zimmerma | 1999-06-21 11:12:33 +0000 (Mon, 21 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add_ulp.c
+
+added mpfr_sub_one_ulp
+
+------------------------------------------------------------------------
+r106 | boldo | 1999-06-18 11:53:03 +0000 (Fri, 18 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tagm.c
+
+tests par rapport aux doubles
+
+------------------------------------------------------------------------
+r105 | boldo | 1999-06-18 11:52:31 +0000 (Fri, 18 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tlog.c
+
+pour decouvrir les erreurs
+
+------------------------------------------------------------------------
+r104 | boldo | 1999-06-18 11:51:52 +0000 (Fri, 18 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/log.c
+
+version qui marche
+
+------------------------------------------------------------------------
+r103 | zimmerma | 1999-06-18 10:15:11 +0000 (Fri, 18 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mul.c
+
+special cases NaN and 0
+
+------------------------------------------------------------------------
+r102 | zimmerma | 1999-06-18 09:56:15 +0000 (Fri, 18 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+fixed a few errors
+
+------------------------------------------------------------------------
+r101 | zimmerma | 1999-06-17 14:26:21 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+added tests for n=0 and d=0
+
+------------------------------------------------------------------------
+r100 | zimmerma | 1999-06-17 14:25:49 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added test for 0.0/1.0
+
+------------------------------------------------------------------------
+r99 | zimmerma | 1999-06-17 12:48:38 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+SET_NAN(q) -> SET_NAN(Q)
+
+------------------------------------------------------------------------
+r98 | zimmerma | 1999-06-17 12:48:05 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added one exact root with rounding towards zero
+
+------------------------------------------------------------------------
+r97 | zimmerma | 1999-06-17 12:45:54 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tout_str.c
+
+added one test
+
+------------------------------------------------------------------------
+r96 | zimmerma | 1999-06-17 12:45:00 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added two tests
+
+------------------------------------------------------------------------
+r95 | zimmerma | 1999-06-17 12:36:52 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+patch to detect exact roots (otherwise problem with rounding to zero)
+
+------------------------------------------------------------------------
+r94 | zimmerma | 1999-06-17 10:14:11 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+changed way zero is represented : most sign. limb is zero
+
+------------------------------------------------------------------------
+r93 | zimmerma | 1999-06-17 09:56:49 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_si.c
+
+added special case for zero
+
+------------------------------------------------------------------------
+r92 | zimmerma | 1999-06-17 09:56:06 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/print_raw.c
+
+special case for zero
+
+------------------------------------------------------------------------
+r91 | zimmerma | 1999-06-17 09:55:24 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/out_str.c
+
+special cases for NaN and zero
+
+------------------------------------------------------------------------
+r90 | zimmerma | 1999-06-17 09:54:47 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+special case when one of the arguments is zero
+
+------------------------------------------------------------------------
+r89 | zimmerma | 1999-06-17 09:25:41 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added bug found by S. Boldo and fixed (pb in mpfr_round_raw2)
+
+------------------------------------------------------------------------
+r88 | zimmerma | 1999-06-17 09:24:51 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+fixed bug in mpfr_round_raw2 which was returning other values than 0 or 1
+
+------------------------------------------------------------------------
+r87 | hanrot | 1999-06-17 09:07:25 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+
+Corrected a potential problem in add(a, a, a);
+
+------------------------------------------------------------------------
+r86 | hanrot | 1999-06-17 09:06:26 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+Corrected a potential problem in sub(a, a, a);
+
+------------------------------------------------------------------------
+r85 | zimmerma | 1999-06-17 08:56:14 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+SET_NAN(x) -> SET_NAN(X)
+
+------------------------------------------------------------------------
+r84 | hanrot | 1999-06-17 08:49:43 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp.c
+
+Patch in cmp2 for some dirty cases (2^a + 2^b <-> 2^a + z, z << 2^a, b << a)
+
+------------------------------------------------------------------------
+r83 | zimmerma | 1999-06-17 08:23:06 +0000 (Thu, 17 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added test to check bug found by JL Remy
+
+------------------------------------------------------------------------
+r82 | zimmerma | 1999-06-17 08:22:11 +0000 (Thu, 17 Jun 1999) | 3 lines
+Changed paths:
+ M /trunk/sub.c
+
+added TMP_DECL/TMP_MARK/TMP_FREE in mpfr_sub1 to deal with case
+where destination=source
+
+------------------------------------------------------------------------
+r81 | hanrot | 1999-06-16 18:07:21 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+Bug dans set_d(0) ; la mantisse n'est pas initialisee a 0 correctement.
+
+------------------------------------------------------------------------
+r80 | hanrot | 1999-06-16 14:05:13 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/mul.c
+
+Gere differemment les problemes d'egalite entre destinations et arguments.
+
+------------------------------------------------------------------------
+r79 | hanrot | 1999-06-16 11:42:18 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Rajoute log.o et tlog
+
+------------------------------------------------------------------------
+r78 | hanrot | 1999-06-16 11:06:37 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ D /trunk/tests/mon_fichier
+
+Vire fichier inutile.
+
+------------------------------------------------------------------------
+r77 | zimmerma | 1999-06-16 10:56:24 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added new tests
+
+------------------------------------------------------------------------
+r76 | zimmerma | 1999-06-16 10:55:39 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+fixed bug for overlap=k*mp_bits_per_limb, k>=1
+
+------------------------------------------------------------------------
+r75 | hanrot | 1999-06-16 09:54:52 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ D /trunk/tests/Makefile
+
+Vire Makefile de CVS.
+
+------------------------------------------------------------------------
+r74 | hanrot | 1999-06-16 09:54:15 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ D /trunk/Makefile
+ D /trunk/Makefile.exp
+ D /trunk/Makefile.msb
+
+Vire les Makefile de CVS.
+
+------------------------------------------------------------------------
+r73 | zimmerma | 1999-06-16 09:48:59 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+added one test and random init.
+
+------------------------------------------------------------------------
+r72 | zimmerma | 1999-06-16 09:48:17 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tdiv.c
+
+added one test
+
+------------------------------------------------------------------------
+r71 | zimmerma | 1999-06-16 09:47:18 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tadd.c
+
+added tests for cases where destination = source
+
+------------------------------------------------------------------------
+r70 | zimmerma | 1999-06-16 09:46:10 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/sub.c
+
+cases NaN and destination=source
+
+------------------------------------------------------------------------
+r69 | zimmerma | 1999-06-16 09:45:22 +0000 (Wed, 16 Jun 1999) | 3 lines
+Changed paths:
+ M /trunk/sqrt.c
+
+now iterates if one cannot round after 1st try,
+and deals with case destination = source
+
+------------------------------------------------------------------------
+r68 | zimmerma | 1999-06-16 09:43:32 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+mpfr_can_round again and again
+
+------------------------------------------------------------------------
+r67 | zimmerma | 1999-06-16 09:42:45 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/print_raw.c
+
+added case of NaN
+
+------------------------------------------------------------------------
+r66 | zimmerma | 1999-06-16 09:41:54 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added macro SET_ZERO
+
+------------------------------------------------------------------------
+r65 | zimmerma | 1999-06-16 09:40:52 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/div.c
+
+now allows destination = source
+
+------------------------------------------------------------------------
+r64 | hanrot | 1999-06-16 08:05:44 +0000 (Wed, 16 Jun 1999) | 2 lines
+Changed paths:
+ D /trunk/tests/tget_str
+ D /trunk/tests/tmul
+ D /trunk/tests/tmul_2exp
+ D /trunk/tests/tmul_ui
+ D /trunk/tests/tround
+ D /trunk/tests/tset_d
+ D /trunk/tests/tset_f
+ D /trunk/tests/tset_str
+ D /trunk/tests/tsqrt
+
+Vire les tests de cvs.
+
+------------------------------------------------------------------------
+r63 | zimmerma | 1999-06-15 16:44:19 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/div.c
+
+printf -> fprintf
+
+------------------------------------------------------------------------
+r62 | zimmerma | 1999-06-15 16:32:41 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/add.c
+ M /trunk/div.c
+
+error message when destination equals source (case not yet treated)
+
+------------------------------------------------------------------------
+r61 | zimmerma | 1999-06-15 16:27:26 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+now uses the given rounding mode internally instead of always GMP_RNDZ
+
+------------------------------------------------------------------------
+r60 | zimmerma | 1999-06-15 16:26:06 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/pi.c
+
+now rounding to nearest should be correct
+
+------------------------------------------------------------------------
+r59 | hanrot | 1999-06-15 16:19:56 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Encore et toujours mpfr_can_round...
+
+------------------------------------------------------------------------
+r58 | hanrot | 1999-06-15 15:38:51 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ D /trunk/o.solaris
+ D /trunk/tests/tadd
+ D /trunk/tests/tagm
+ D /trunk/tests/tcmp
+ D /trunk/tests/tcmp2
+ D /trunk/tests/tcmp_ui
+ D /trunk/tests/tdiv
+
+Nettoyage.
+
+------------------------------------------------------------------------
+r57 | hanrot | 1999-06-15 14:43:14 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Patch pour mpfr_can_round.
+
+------------------------------------------------------------------------
+r56 | boldo | 1999-06-15 14:40:51 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+sans instructions de debuggage
+
+------------------------------------------------------------------------
+r55 | boldo | 1999-06-15 13:53:11 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Makefile
+
+rajout de log.o et tlog
+
+------------------------------------------------------------------------
+r54 | boldo | 1999-06-15 13:52:43 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile
+
+rajout de tlog
+
+------------------------------------------------------------------------
+r53 | boldo | 1999-06-15 13:41:24 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+ajout du log
+
+------------------------------------------------------------------------
+r52 | boldo | 1999-06-15 13:24:51 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/tests/tlog.c
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r51 | boldo | 1999-06-15 13:22:09 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/log.c
+
+premiere version du log
+
+------------------------------------------------------------------------
+r50 | zimmerma | 1999-06-15 13:11:10 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/div.c
+
+now recognizes division by exact power of 2
+
+------------------------------------------------------------------------
+r49 | zimmerma | 1999-06-15 13:10:21 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/cmp_ui.c
+
+added mpfr_cmp_[us]i_2exp
+
+------------------------------------------------------------------------
+r48 | zimmerma | 1999-06-15 12:53:07 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added mpfr_[us]i_2exp
+
+------------------------------------------------------------------------
+r47 | zimmerma | 1999-06-15 12:52:33 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added mpfr_cmp_[us]i_2exp
+
+------------------------------------------------------------------------
+r46 | hanrot | 1999-06-15 12:06:32 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/random.c
+
+Correction de bug (pas msb normalise).
+
+------------------------------------------------------------------------
+r45 | zimmerma | 1999-06-15 10:04:12 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/pi.c
+
+fixed mistake in error analysis (does not change code)
+
+------------------------------------------------------------------------
+r44 | hanrot | 1999-06-15 09:26:56 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+Ajout de random.o dans les objets.
+
+------------------------------------------------------------------------
+r43 | hanrot | 1999-06-15 09:26:26 +0000 (Tue, 15 Jun 1999) | 3 lines
+Changed paths:
+ A /trunk/random.c
+
+random.c : engendre un mpfr_t dans [0, 1[. GH, 15/06
+TODO : un random qui engendre un mpfr_t avec exposant gaussien centre.
+
+------------------------------------------------------------------------
+r42 | remy | 1999-06-15 09:17:44 +0000 (Tue, 15 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/log2.c
+ M /trunk/pi.c
+
+changed return value to void
+
+------------------------------------------------------------------------
+r41 | hanrot | 1999-06-14 16:35:25 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/round.c
+
+Ajoute les modes d'arrondi RNDN et RNDD.
+
+------------------------------------------------------------------------
+r40 | hanrot | 1999-06-14 13:14:43 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mul_ui.c
+
+Correction du prototype de mpfr_mul_ui
+
+------------------------------------------------------------------------
+r39 | hanrot | 1999-06-14 11:11:55 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+Correction du prototype de mpfr_mul_ui
+
+------------------------------------------------------------------------
+r38 | boldo | 1999-06-14 10:18:01 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r37 | zimmerma | 1999-06-14 07:51:59 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Configure
+
+added several files
+
+------------------------------------------------------------------------
+r36 | zimmerma | 1999-06-14 07:51:28 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added several prototypes
+
+------------------------------------------------------------------------
+r35 | zimmerma | 1999-06-14 07:50:36 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.texi
+
+added set_z, add_one_ulp
+
+------------------------------------------------------------------------
+r34 | zimmerma | 1999-06-14 07:49:06 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/set_d.c
+
+added mpfr_get_d2 which only considers the mantissa
+
+------------------------------------------------------------------------
+r33 | zimmerma | 1999-06-14 07:48:10 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+now uses mpfr_get_d2 (no side effect on arguments)
+
+------------------------------------------------------------------------
+r32 | zimmerma | 1999-06-14 07:46:10 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/tests/tlog2.c
+
+test file for mpfr_log2
+
+------------------------------------------------------------------------
+r31 | zimmerma | 1999-06-14 07:45:27 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/tests/tset_z.c
+
+test file for mpfr_set_z
+
+------------------------------------------------------------------------
+r30 | zimmerma | 1999-06-14 07:44:42 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/tests/tpi.c
+
+test file for mpfr_pi
+
+------------------------------------------------------------------------
+r29 | zimmerma | 1999-06-14 07:43:57 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/log2.c
+
+computes log(2)
+
+------------------------------------------------------------------------
+r28 | zimmerma | 1999-06-14 07:43:22 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/add_ulp.c
+
+add one ulp
+
+------------------------------------------------------------------------
+r27 | zimmerma | 1999-06-14 07:42:12 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/set_z.c
+
+set a mpfr from an integer
+
+------------------------------------------------------------------------
+r26 | zimmerma | 1999-06-14 07:41:33 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/pi.c
+
+computes Pi to n bits
+
+------------------------------------------------------------------------
+r25 | boldo | 1999-06-14 07:41:29 +0000 (Mon, 14 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r24 | zimmerma | 1999-06-11 08:08:35 +0000 (Fri, 11 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/mpfr.texi
+
+Initial revision of mpfr documentation
+
+------------------------------------------------------------------------
+r23 | hanrot | 1999-06-10 18:47:44 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tsqrt.c
+
+Patch d'un mpfr_set_d dans tsqrt.c ; GH, 100699
+
+------------------------------------------------------------------------
+r22 | hanrot | 1999-06-10 18:47:09 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tget_str.c
+
+Patch d'un mpfr_set_d dans get_str.c ; GH, 100699
+
+------------------------------------------------------------------------
+r21 | hanrot | 1999-06-10 18:46:03 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/Configure
+
+Tentative de configuration automatique, v. initiale. GH, 100699
+
+------------------------------------------------------------------------
+r20 | boldo | 1999-06-10 16:36:13 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/agm.c
+ M /trunk/tests/tagm.c
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r19 | zimmerma | 1999-06-10 09:20:04 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Makefile
+
+added tout_str
+
+------------------------------------------------------------------------
+r18 | zimmerma | 1999-06-10 09:19:38 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/tests/tout_str.c
+
+Initial revision.
+
+------------------------------------------------------------------------
+r17 | zimmerma | 1999-06-10 09:13:55 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/Makefile
+
+added out_str.c and pow.c
+
+------------------------------------------------------------------------
+r16 | zimmerma | 1999-06-10 09:13:26 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added proto for mpfr_pow_ui and mpfr_ui_pow_ui
+
+------------------------------------------------------------------------
+r15 | zimmerma | 1999-06-10 09:09:09 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/pow.c
+
+Initial revision.
+
+------------------------------------------------------------------------
+r14 | zimmerma | 1999-06-10 09:05:05 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/clear.c
+ M /trunk/div_2exp.c
+ M /trunk/mul.c
+ M /trunk/mul_2exp.c
+ M /trunk/mul_ui.c
+ M /trunk/neg.c
+ M /trunk/round.c
+ M /trunk/set.c
+ M /trunk/set_f.c
+ M /trunk/set_si.c
+
+added include <stdio.h> (needed for FILE in mpfr.h)
+
+------------------------------------------------------------------------
+r13 | zimmerma | 1999-06-10 08:59:38 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+added proto for mpfr_out_str
+
+------------------------------------------------------------------------
+r12 | zimmerma | 1999-06-10 08:58:23 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/out_str.c
+
+function to print a mpfr to a stream. Initial revision.
+
+------------------------------------------------------------------------
+r11 | zimmerma | 1999-06-10 08:56:27 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mpfr.h
+
+changed proto of mpfr_get_str: 2nd arg is mp_exp_t*, not char*
+
+------------------------------------------------------------------------
+r10 | zimmerma | 1999-06-10 08:53:22 +0000 (Thu, 10 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/get_str.c
+
+now conforms to the specification
+
+------------------------------------------------------------------------
+r9 | hanrot | 1999-06-09 18:37:25 +0000 (Wed, 09 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/Makefile
+
+tset_i -> tset_si dans le Makefile de tests.
+
+------------------------------------------------------------------------
+r8 | hanrot | 1999-06-09 18:36:50 +0000 (Wed, 09 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/mmpfr
+
+Version corrigee de mmpfr.
+
+------------------------------------------------------------------------
+r7 | hanrot | 1999-06-09 18:36:28 +0000 (Wed, 09 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/Makefile
+
+Makefile qui devrait fonctionner pour tous.
+
+------------------------------------------------------------------------
+r6 | hanrot | 1999-06-09 18:33:34 +0000 (Wed, 09 Jun 1999) | 2 lines
+Changed paths:
+ M /trunk/tests/tmul_2exp.c
+
+Correction de warnings dans tmul_2exp.c
+
+------------------------------------------------------------------------
+r2 | hanrot | 1999-06-09 18:03:33 +0000 (Wed, 09 Jun 1999) | 2 lines
+Changed paths:
+ A /trunk/.pure
+ A /trunk/BUGS
+ A /trunk/Makefile.exp
+ A /trunk/Makefile.msb
+ A /trunk/TODO
+ A /trunk/add.c
+ A /trunk/agm.c
+ A /trunk/clear.c
+ A /trunk/cmp.c
+ A /trunk/cmp_ui.c
+ A /trunk/div.c
+ A /trunk/div_2exp.c
+ A /trunk/from_Torbjorn
+ A /trunk/get_str.c
+ A /trunk/init.c
+ A /trunk/init_set.h
+ A /trunk/mmpfr
+ A /trunk/mpfr.h
+ A /trunk/mul.c
+ A /trunk/mul_2exp.c
+ A /trunk/mul_ui.c
+ A /trunk/neg.c
+ A /trunk/o.solaris
+ A /trunk/o.solaris/.pure
+ A /trunk/print_raw.c
+ A /trunk/rnd_mode.c
+ A /trunk/round.c
+ A /trunk/set.c
+ A /trunk/set_d.c
+ A /trunk/set_dfl_prec.c
+ A /trunk/set_dfl_rnd.c
+ A /trunk/set_f.c
+ A /trunk/set_prec.c
+ A /trunk/set_si.c
+ A /trunk/set_str.c
+ A /trunk/set_str_raw.c
+ A /trunk/sqrt.c
+ A /trunk/sub.c
+ A /trunk/tests
+ A /trunk/tests/Makefile
+ A /trunk/tests/mon_fichier
+ A /trunk/tests/tadd
+ A /trunk/tests/tadd.c
+ A /trunk/tests/tagm
+ A /trunk/tests/tagm.c
+ A /trunk/tests/tcmp
+ A /trunk/tests/tcmp.c
+ A /trunk/tests/tcmp2
+ A /trunk/tests/tcmp2.c
+ A /trunk/tests/tcmp_ui
+ A /trunk/tests/tcmp_ui.c
+ A /trunk/tests/tdiv
+ A /trunk/tests/tdiv.c
+ A /trunk/tests/tget_str
+ A /trunk/tests/tget_str.c
+ A /trunk/tests/tmul
+ A /trunk/tests/tmul.c
+ A /trunk/tests/tmul_2exp
+ A /trunk/tests/tmul_2exp.c
+ A /trunk/tests/tmul_ui
+ A /trunk/tests/tmul_ui.c
+ A /trunk/tests/tround
+ A /trunk/tests/tround.c
+ A /trunk/tests/tset_d
+ A /trunk/tests/tset_d.c
+ A /trunk/tests/tset_f
+ A /trunk/tests/tset_f.c
+ A /trunk/tests/tset_i
+ A /trunk/tests/tset_si.c
+ A /trunk/tests/tset_str
+ A /trunk/tests/tset_str.c
+ A /trunk/tests/tsqrt
+ A /trunk/tests/tsqrt.c
+
+Initial revision
+
+------------------------------------------------------------------------
+r1 | (no author) | 1999-06-09 18:03:33 +0000 (Wed, 09 Jun 1999) | 1 line
+Changed paths:
+ A /branches
+ A /tags
+ A /trunk
+
+New repository initialized by cvs2svn.
+------------------------------------------------------------------------
diff --git a/mpfr/INSTALL b/mpfr/INSTALL
new file mode 100644
index 0000000000..88060806cf
--- /dev/null
+++ b/mpfr/INSTALL
@@ -0,0 +1,651 @@
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+
+ Installing GNU MPFR
+ ===================
+
+Note: In case of problem, please read this INSTALL file carefully before
+reporting a bug, in particular Section "In case of problem" below. Some
+problems are due to bad configuration on the user side (not specific to
+MPFR).
+
+0. You first need to install GMP. See <http://www.gnu.org/software/gmp/>.
+ MPFR requires GMP version 4.1 or later.
+
+1. Extract the files from the archive.
+
+2. It is strongly advised to apply the latest patches if this has
+ not been done yet and if patches are available. You can check
+ on the release page:
+
+ http://www.mpfr.org/mpfr-3.1.2/
+
+ which may have additional information. The patches can be applied
+ with commands like:
+
+ wget http://www.mpfr.org/mpfr-3.1.2/allpatches
+ patch -N -Z -p1 < allpatches
+
+ or
+
+ curl http://www.mpfr.org/mpfr-3.1.2/allpatches | patch -N -Z -p1
+
+ (Those instructions are for the GNU patch command, for example
+ /usr/bin/gpatch on Solaris.)
+
+3. In the MPFR directory, to detect your system, type:
+ ./configure
+ possibly with options (see below, in particular if this step or
+ one of the following fails). You should also check whether WARNING
+ lines have been output (such a problem may cause a failure in one
+ of the following steps).
+ Note: paths provided in configure options must always be absolute
+ (relative paths are not supported).
+
+4. To build the library, type:
+ make
+
+ [optional] if you want to tune MPFR for your specific architecture, see
+ the section "Tuning MPFR" below. Note that for most common architectures,
+ MPFR includes some default tuning parameters which should be near from
+ optimal.
+
+5. To check the built library (runs the test files), type:
+ make check
+
+6. To install it (default "/usr/local" | see "--prefix" option), type:
+ make install
+
+If you installed MPFR (header and library) in directories that are
+not searched by default by the compiler and/or linking tools, then,
+like with other libraries, you may need to set up some environment
+variables such as C_INCLUDE_PATH (to find the header mpfr.h),
+LIBRARY_PATH (to find the library), and if the shared library has
+been installed, LD_LIBRARY_PATH (before execution) or LD_RUN_PATH
+(before linking); this list is not exhaustive and some environment
+variables may be specific to your system. "make install" gives some
+instructions; please read them. You can also find more information
+in the manuals of your compiler and linker. The MPFR FAQ may also
+give some information.
+
+Remember that if you have several MPFR (or GMP) versions installed
+(e.g., one with the system, and one, newer, by you), you will not
+necessarily get a compilation/linking error if a wrong library is
+used (e.g., because LD_LIBRARY_PATH has not been set correctly).
+But unexpected results may occur.
+
+Under Mac OS X, if the shared library was not installed and you use
+Apple's linker (this is the default), you will also need to provide
+the -search_paths_first linker flag ("-Wl,-search_paths_first" when
+you link via gcc) to make sure that the right library is selected,
+as by default, Apple's linker selects a shared library preferably,
+even when it is farther in the library paths. We recall that if a
+wrong library is selected due to this behavior, unexpected results
+may occur.
+
+
+Building the documentation
+==========================
+
+To build the documentation in various formats, you may first need to
+install recent versions of some utilities such as texinfo.
+
+* Type "make info" to produce the documentation in the info format.
+
+* Type "make pdf" to produce the documentation in the PDF format.
+
+* Type "make dvi" to produce the documentation in the DVI format.
+
+* Type "make ps" to produce the documentation in the Postscript format.
+
+* Type "make html" to produce the documentation in the HTML format
+ (in several pages); if you want only one output HTML file, then
+ type "makeinfo --html --no-split mpfr.texi" from the doc directory
+ instead.
+
+
+Building MPFR with internal GMP header files
+============================================
+
+MPFR built with internal GMP header files is a bit faster, so you may want
+to build it with them. Just do this in step 1:
+
+ ./configure --with-gmp-build=GMPBUILD
+
+where GMPBUILD is the GMP build directory. The needed header files are:
+gmp-impl.h, longlong.h and all the necessary headers to use them, which
+may be located either in the GMP source directory or in the GMP build
+directory, in case they are different (MPFR takes care of that, as of
+MPFR 3.1.0).
+
+Warning: the library obtained in this way may use some internal GMP
+symbols, and thus dynamically linking your software with a different
+version of GMP might fail, even though it is declared as compatible
+by Libtool's versioning system.
+
+
+Tuning MPFR
+===========
+
+For this, you need to build MPFR with a GMP build directory (see above).
+In the GMP build directory, you also need to go into the "tune" subdirectory
+and type "make speed". This will build the GMP speed library, which is used
+by the MPFR tuning mechanism.
+
+Then go back to the MPFR build directory, go into the "tune" subdirectory and
+type "make tune". This will build an optimized file "mparam.h" for your
+specific architecture.
+
+
+./configure options
+===================
+
+--prefix=DIR installs MPFR headers and library in DIR/include and
+ DIR/lib respectively (the default is "/usr/local").
+
+--with-gmp-include=DIR assumes that DIR contains gmp.h
+--with-gmp-lib=DIR assumes that DIR contains the GMP library
+--with-gmp=DIR assumes that DIR is where you have installed GMP.
+ same as --with-gmp-lib=DIR/lib
+ and --with-gmp-include=DIR/include
+ (use either --with-gmp alone or one or both of
+ --with-gmp-lib/--with-gmp-include)
+ Warning! Do not use these options if you have
+ CPPFLAGS and/or LDFLAGS containing a -I or -L
+ option with a directory that contains a GMP
+ header or library file, as these options just
+ add -I and -L options to CPPFLAGS and LDFLAGS
+ *after* the ones that are currently declared,
+ so that DIR will have a lower precedence. Also,
+ this may not work if DIR is a system directory
+ (typically /usr or /usr/local); see below.
+
+--with-gmp-build=DIR assumes that DIR contains the GMP build directory,
+ and enables the use of GMP internals (see above).
+ Warning! This option and the group of options
+ --with-gmp are mutually exclusive.
+
+--enable-assert build MPFR with assertions.
+
+--enable-thread-safe build MPFR as thread safe, using compiler-level
+ Thread Local Storage (TLS). Note: TLS support is
+ roughly tested by configure. If configure detects
+ that TLS does not work (because of the compiler,
+ linker or system libraries), it will output an
+ error message, telling you to build MPFR without
+ thread safe. For instance, though Mac OS X uses
+ GCC, it may not currently support GCC's __thread
+ storage class.
+
+--disable-thread-safe build MPFR without TLS. By default, TLS support
+ is detected automatically, and MPFR is built as
+ thread safe if supported. However this detection
+ is only a heuristic: TLS can be detected as
+ supported while its support is incomplete or
+ buggy (MPFR tests may fail). In such a case,
+ this option is useful.
+
+--enable-gmp-internals allows the MPFR build to use GMP's undocumented
+ functions (not from the public API). Note that
+ library versioning is not guaranteed to work if
+ this option is used. Thus it must not be used in
+ binary distributions.
+
+Note: By default, the configure script tries to set CC/CFLAGS to GMP's
+ones (this feature needs GMP 4.3.0 or later, or the --with-gmp-build
+option). However this is not guaranteed to work as the configure script
+does some compiler tests earlier, and the change may be too late. Also,
+the values obtained from GMP may be incorrect if GMP has been built
+on a different machine. In such a case, the user may need to specify
+CC/CFLAGS as explained below.
+
+Run "./configure --help" to see the other options (autoconf default options).
+
+
+If 'gmp.h' and 'libgmp' do not match
+====================================
+
+Under some circumstances, the configure script may output a message
+saying:
+
+ 'gmp.h' and 'libgmp' seem to have different versions or
+ we cannot run a program linked with GMP (if you cannot
+ see the version numbers above). [...]
+
+Even though the configure script does not fail in such a case, this
+message most often indicates a real error, which needs to be avoided.
+Possible causes are:
+
+* The wanted GMP library does not have the same ABI as the one chosen
+ to build MPFR. The consequences may be:
+
+ - A different GMP library (with the correct ABI) has been found,
+ but does not have the same version as 'gmp.h'.
+
+ - No other GMP libraries have been found (in this case, no version
+ numbers should be printed above the warning message).
+
+ This is incorrect and one of the following steps (make, make check)
+ will probably fail. GMP (actually gmp.h) now provides CC and CFLAGS
+ information to select the correct ABI, so that this problem should
+ no longer occur; but if GMP was provided by a binary package, such
+ information may not be valid. See the
+
+ checking for CC and CFLAGS in gmp.h...
+
+ line in the configure output (about the 11th line) and the following
+ few ones for more information. You may need to reinstall GMP or to
+ provide your own CC and/or CFLAGS. See also the remaining of this
+ INSTALL file.
+
+* A configure option like --with-gmp or --with-gmp-include was used
+ with a system include directory, e.g. one of the following:
+
+ --with-gmp=/usr
+ --with-gmp=/usr/local
+ --with-gmp-include=/usr/include
+ --with-gmp-include=/usr/local/include
+
+ GCC (and possibly other compilers) will ignore such a directive for
+ include directories (but this rule is not applied for the library
+ itself!). This means that the library search paths will be reordered
+ as declared, but the specified include directory will still be near
+ the end of the include search paths (thus with a low precedence).
+ This is not a problem if only one GMP version is installed, but
+ otherwise, a wrong gmp.h may be chosen, so that the versions of
+ gmp.h and libgmp may not match. The suggestions are the following:
+
+ - If you want to use the GMP version under /usr, then you should
+ uninstall all the other GMP versions (header and library files)
+ that may be seen in the search paths, in particular those under
+ /usr/local.
+
+ - If you want to use the GMP version under /usr/local, then you
+ should uninstall all the other GMP versions (header and library
+ files) that may be seen in the search paths, but *NOT* the one
+ under /usr (the version under /usr is provided by the OS vendor,
+ and changing/removing anything related to it may break your
+ system, and /usr should have a lower precedence than /usr/local
+ anyway).
+
+ To find where GMP versions have been installed:
+
+ $ locate libgmp (if you have a locate database)
+
+ and if the compiler is GCC:
+
+ $ gcc -print-file-name=libgmp.so (under most systems)
+ $ gcc -print-file-name=libgmp.dylib (under Mac OS X)
+
+ and if this does not work, you may try:
+
+ $ gcc -print-search-dirs
+
+* An official GCC version was used under Debian GNU/Linux. Problems
+ may come from the fact that Debian chose a different convention
+ for library search paths concerning 32-bit and 64-bit libraries.
+ A possible problem can be, for instance:
+
+ [Debian's GCC, correct library path]
+ $ gcc -print-file-name=libgmp.so
+ /home/vlefevre/gmp/athlon64/lib/../lib/libgmp.so
+
+ [Official GCC, incorrect library path]
+ $ gcc-4.3.1 -print-file-name=libgmp.so
+ /usr/lib/../lib64/libgmp.so
+
+ The solution: use a GCC provided by Debian or add symbolic links
+ such as lib64 -> lib (on 64-bit machines) for your library paths.
+
+* The problem may also be temporary and only due to the fact that
+ libtool could not be used at this time. This is unlikely, though.
+
+
+In case of problem
+==================
+
+First, look for any warning message in the configure output.
+
+Several documents may help you to solve the problem:
+ * this INSTALL file, in particular information given below;
+ * the FAQ (either the FAQ.html file distributed with MPFR, or the
+ on-line version <http://www.mpfr.org/faq.html>, which may be more
+ up-to-date);
+ * the MPFR web page for this version <http://www.mpfr.org/mpfr-3.1.2/>,
+ which lists bugs found in this version and provides some patches.
+
+If the "configure" fails, please check that the C compiler and its
+options are the same as those for the GMP build (specially the ABI).
+You can see the latter with the following command:
+
+ grep "^CC\|^CFLAGS" GMPBUILD/Makefile
+
+if the GMP build directory is available. Then type:
+
+ ./configure <configure options> CC=<C compiler> CFLAGS="<compiler options>"
+
+(quotes are needed when there are spaces or other special characters
+in the CC/CFLAGS value) and continue the install. On some platforms,
+you should provide further options to match those used by GMP, or set
+some environment variables. For instance, see the "Notes on AIX/PowerPC"
+section below.
+
+Warning! Do NOT use optimization options that can change the semantics
+of math operations, such as GCC's -ffast-math or Sun CC's -fast.
+Otherwise conversions from/to double's may be incorrect on infinities,
+NaN's and signed zeros. Since native FP arithmetic is used in a few
+places only, such options would not make MPFR faster anyway.
+
+If some "make check" tests fail, you can try the --disable-thread-safe
+configure option (see the configure options above): it has been reported
+that some platforms have buggy TLS support. Before trying this option,
+you may want to check in the configure output whether MPFR was built
+with TLS support; if yes, you will have a line:
+ checking for TLS support... yes
+Alternatively "grep MPFR_USE_THREAD_SAFE config.log" will show that
+MPFR_USE_THREAD_SAFE is defined to 1. If it is "no" (or the variable
+is not defined), the --disable-thread-safe option would be useless.
+
+Some tests failure may be due to other compiler bugs, in particular
+in optimization code. You can try to build MPFR without compiler
+optimizations by giving -O0 (letter O, digit 0) in CFLAGS. If the
+MPFR tests no longer fail, this was probably due to a compiler bug,
+though we cannot exclude a bug in MPFR. You may want to contact us
+(see below), possibly after looking at:
+ http://www.loria.fr/~zimmerma/software/compilerbugs.html
+
+On some platforms, try with "gmake" (GNU make) instead of "make".
+Problems have been reported with the Tru64 make.
+
+If the configure script reports that gmp.h version and libgmp version
+are different, or if the build was OK, but the tests failed to link
+with GMP or gave an error like
+
+ undefined reference to `__gmp_get_memory_functions'
+
+meaning that the GMP library was not found or a wrong GMP library was
+selected by the linker, then your library search paths are probably
+not correctly set (some paths are missing or they are specified in an
+incorrect order).
+
+Such problems commonly occur under some GNU/Linux machines, where the
+default header and library search paths may be inconsistent: GCC is
+configured to search /usr/local/include and /usr/local/lib by default,
+while the dynamic linker ignores /usr/local/lib. If you have a GMP
+version installed in /usr (provided by the OS vendor) and a new one
+installed in /usr/local, then the header of the new GMP version and
+the library of the old GMP version will be used! The best solution
+is to make sure that the dynamic linker configuration is consistent
+with GCC's behavior, for instance by having /usr/local/lib in
+/etc/ld.so.conf or in some file from /etc/ld.so.conf.d (as Debian
+did: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=395177). See
+also http://gcc.gnu.org/ml/gcc-help/2010-01/msg00171.html for more
+information. Alternatively you can use:
+ * environment variables. This may sometimes be necessary. If DIR
+ is the installation directory of GMP, add DIR/include to your
+ CPATH or C_INCLUDE_PATH (for compilers other than GCC, please
+ check the manual of your compiler), and add DIR/lib to your
+ LIBRARY_PATH and LD_LIBRARY_PATH (and/or LD_RUN_PATH);
+ * --with-gmp* configure options (described above), e.g.
+ --with-gmp=/opt/local (to use /opt/local/include for headers and
+ /opt/local/lib for libraries), but other software that uses GMP
+ and/or MPFR will need correct paths too, and environment variables
+ allow one to set such search paths in a global way.
+ Note about "--with-gmp=/usr/local". This option may appear to
+ solve the above inconsistency problem, but does not work as you
+ expect. Indeed it affects the library search path, in particular,
+ the one used by the dynamic linker (thus adding the missing
+ /usr/local/lib directory as wanted), but since /usr/local/include
+ is a "standard system include directory" for GCC, the include
+ search patch is not changed; this is often not a problem in this
+ particular case because usually, /usr/local/include is already
+ last in the include search patch, but this may fail under some
+ occasions and may trigger obscure errors.
+
+For instance, under Unix, where paths are separated by a colon:
+
+ * With POSIX sh-compatible shells (e.g. sh, ksh, bash, zsh):
+ export C_INCLUDE_PATH="/usr/local/include:/other/path/include"
+ export LIBRARY_PATH="/usr/local/lib:/other/path/lib"
+ export LD_LIBRARY_PATH="$LIBRARY_PATH"
+
+ * With csh or tcsh:
+ setenv C_INCLUDE_PATH "/usr/local/include:/other/path/include"
+ setenv LIBRARY_PATH "/usr/local/lib:/other/path/lib"
+ setenv LD_LIBRARY_PATH "$LIBRARY_PATH"
+
+If you can't solve your problem, you should contact us via the MPFR
+mailing-list <mpfr@inria.fr>, indicating the machine and operating system
+used (uname -a), the compiler and version used (gcc -v if you use gcc),
+the configure options used if any (including variables such as CC and
+CFLAGS), the version of GMP and MPFR used, and a description of the
+problem encountered. Please send us also the log of the "configure"
+(config.log).
+
+Note that even if you can build MPFR with a C++ compiler, you can't run
+the test suite: C and C++ are not the same language! You should use a C
+compiler instead.
+
+
+Notes about ABI
+===============
+
+On 64-bit computers, it may happen that the default ABI (Application Binary
+Interface) chosen by MPFR does not correspond to the default one chosen by
+the compiler.
+
+In particular, this kind of message may indicate the problem:
+/usr/bin/ld: skipping incompatible mpfr/src/.libs/libmpfr.a when searching for -lmpfr
+
+In fact, since MPFR relies on GMP, it uses the same ABI as GMP.
+To be sure that your program compiles and links correctly, use the same
+compiler flags as MPFR does (look for CFLAGS in config.log).
+
+You might also recompile GMP with a different ABI, with for example
+./configure ABI=32.
+
+
+Notes on Mac OS X
+=================
+
+If you get an error of the form
+
+ ld: pointer in read-only segment not allowed in slidable image...
+
+this can mean that the link is done against a static (GMP) library.
+In such a case, you should configure MPFR with --disable-shared to
+disable the build of the shared library.
+
+
+Notes on FreeBSD 4.3
+====================
+
+FreeBSD 4.3 is provided with an incorrect <float.h> header file, and
+MPFR tests related to long double's may fail. If you cannot upgrade
+the system, you can still use MPFR with FreeBSD 4.3, but you should
+not use conversions with the long double type.
+
+
+Notes on AIX/PowerPC
+====================
+
+The following has been tested on AIX 5.3 (powerpc-ibm-aix5.3.0.0) with
+gcc 3.3.2 and GMP 4.2.1.
+
+If GMP was built with the 64-bit ABI, before building and testing MPFR,
+you should set the OBJECT_MODE environment variable to 64, e.g., with:
+
+ export OBJECT_MODE=64
+
+(in a sh-compatible shell). But you should also provide a correct CFLAGS
+value to the "configure" script: using --with-gmp-build is not sufficient
+due to the early compiler tests, as gcc will not compile any program if
+OBJECT_MODE is 64 and the -maix64 option is not provided.
+
+
+MPFR for use with 32-bit Windows Applications (win32)
+=====================================================
+
+There are several ways of building MPFR on Windows, the most appropriate
+approach depending on how you intend to use the resulting libraries.
+
+a. Using MinGW
+==============
+
+1 - We advise to use MinGW (http://www.mingw.org/), which is simpler and
+ less demanding than Cygwin. Contrary to Cygwin, it also provides native
+ Windows code.
+
+2 - If you just want to make a binary with gcc, there is nothing to do:
+ GMP, MPFR and the program compile exactly as under Linux.
+ But if you want to generate a library for MinGW from a Cygwin
+ environment, you may need the -mno-cygwin gcc option (otherwise
+ a typical error is _P_WAIT being undeclared).
+
+3 - If you want to make libraries work under another Windows compiler
+ like Visual C / C++, since the unix-like *.a library files are compatible
+ with Windows *.lib files, you can simply rename all *.a libraries to *.lib.
+
+ With gmp-4.1.3, the only remaining problem seems to be the "alloca" calls
+ in GMP. Configuring GMP and MPFR with --enable-alloca=malloc-reentrant
+ should work (if you build MPFR with GMP internal files).
+
+ Or you could add the library
+ "$MINGWIN$/lib/gcc-lib/mingw32/$VERSION$/libgcc.a"
+ to your project: it contains all the extra-functions needed by a program
+ compiled by gcc (division of 64-bit integer, bcopy, alloca...).
+ Of course, include it if and only if your compiler is not gcc.
+
+4 - On Windows32 / MinGW, if all the tests fail, try to run the test suite
+ with "make check EXEEXT=".
+
+5 - To avoid using the Microsoft runtime (which might not be conform to ISO C),
+ you can use the MinGW runtime package (which is an integral part of MinGW).
+ For example, with MinGW versions 3.15 and later you can get an
+ ISO-compliant printf() if you compile your application with either
+ '-ansi', '-posix' or '-D__USE_MINGW_ANSI_STDIO'. For example, you can
+ compile and test MPFR with CC="gcc -D__USE_MINGW_ANSI_STDIO".
+
+ For example under Win32, the following problem has been experienced with
+ MPFR 2.4.0 RC1 and the MSVC runtime (msvcrt.dll):
+
+ Error in mpfr_vsprintf (s, "%.*Zi, %R*e, %Lf%n", ...);
+ expected: "00000010610209857723, -1.2345678875e+07, 0.032258"
+ got: "00000010610209857723, -1.2345678875e+07, -0.000000"
+ FAIL: tsprintf.exe
+
+ This error is due to the MSVC runtime not supporting the L length modifier
+ for formatted output (e.g. printf with %Lf). You can check this with the
+ following program:
+
+ #include <stdio.h>
+ int main (void)
+ {
+ long double d = 1. / 31.;
+ printf ("%Lf\n", d);
+ return 0;
+ }
+
+ The expected output is 0.032258.
+
+ Note: The L modifier has been standard for a long time (it was added
+ in ISO C89).
+
+ Note 2: this now works correctly with Visual C++ 2008 and 2010
+ (tested on Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
+ 15.00.21022.08 for 80x86, Microsoft (R) C/C++ Optimizing Compiler
+ Version 15.00.21022.08 for x64, Microsoft (R) 32-bit C/C++ Optimizing
+ Compiler Version 16.00.30319.01 for 80x86, Microsoft (R) C/C++ Optimizing
+ Compiler Version 16.00.30319.01 for x64).
+
+b. Using Cygwin
+===============
+
+This build should be similar to that for MinGW except that the resulting
+library depends on the Cygwin DLL and cannot therefore be used with
+Visual Studio as with MinGW. Indeed, the binaries compiled with Cygwin
+require a dynamic library (cygwin.dll) to work; there is a Cygwin option
+-mno-cygwin to build native code, but it may require some non-portable tricks.
+
+In case of failure, you may need to pass LDFLAGS='-shared-libgcc' at the
+end of the configure line due to a bug in GCC. Otherwise, if threading
+support is not needed, you can configure MPFR with --disable-thread-safe.
+
+c. Using Visual C++ 2008/2010
+=============================
+
+Win32 versions of the MPFR library can be built using Microsoft Visual
+C++ 2008 or 2010 using the build projects available here:
+
+http://gladman.plushost.co.uk/oldsite/computing/gmp4win.php
+
+These build projects contain both win32 and x64 builds but the latter
+will give errors if your version of Visual C++ lacks the 64-bit
+compiler and tools. The 32-bit build projects should however work
+on Visual C++ 2008, Visual C++ Express 2008 (SP1), Visual C++ 2010
+and Visual C++ Express 2010.
+
+MPFR for use with 64-bit Windows Applications (x64)
+===================================================
+
+There are two ways of building MPFR for use with 64-bit Windows
+applications.
+
+a. Using MinGW64
+================
+
+The MinGW64 version of the GCC compiler is now available here:
+
+http://sourceforge.net/projects/mingw-w64/
+
+It can build both GMP and MPFR for 64-bit Windows applications.
+
+b. Using Visual C++ 2008/2010
+=============================
+
+x64 versions of the MPFR library can be built using Microsoft Visual
+C++ 2008 or 2010 using the build projects available here:
+
+http://gladman.plushost.co.uk/oldsite/computing/gmp4win.php
+
+These build projects contain both win32 and x64 builds but the latter
+can only be built if your version of Visual C++ contains the 64-bit
+compiler and tools. On Visual C++ 2008, the 64-bit tools are an
+option during installation so if you don't have them you will need
+to start the Visual Studio installer and add them to your IDE
+configuration. On Visual C++ 2010 they are installed by default.
+
+As delivered, Visual C++ Express 2008 SP1 cannot build x64 projects
+but the Windows SDK can be added to it to allow this. The IDE then
+needs to be configured as described here:
+
+http://msdn.microsoft.com/en-us/library/9yb4317s(VS.80).aspx
+
+to allow x64 builds.
+
+Visual C++ Express 2010 requires the Windows 7 SDK to be installed
+in order to build x64 projects. This SDK is available here:
+
+http://tinyurl.com/25zz8r6
+
+In this case, once this SDK has been installed, Visual C++ Express 2010
+will build x64 projects without further changes.
diff --git a/mpfr/Makefile.am b/mpfr/Makefile.am
new file mode 100644
index 0000000000..54e5c71882
--- /dev/null
+++ b/mpfr/Makefile.am
@@ -0,0 +1,32 @@
+# Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+
+
+AUTOMAKE_OPTIONS = gnu
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = doc src tests tune
+
+nobase_dist_doc_DATA = AUTHORS BUGS COPYING COPYING.LESSER NEWS TODO \
+ examples/ReadMe examples/divworst.c examples/rndo-add.c examples/sample.c \
+ examples/version.c
+
+EXTRA_DIST = PATCHES VERSION \
+ tools/ck-copyright-notice tools/ck-version-info tools/get_patches.sh \
+ $(DATAFILES)
+
+# Various checks for "make dist".
+# * Check consistency concerning -version-info. Moreover if the VERSION
+# file doesn't end with "-dev", check that the -version-info value is
+# up-to-date. Note: this is a heuristic, to detect some mistakes.
+# * Check that copyright notices exist and appear to be correct.
+dist-hook:
+ cd $(srcdir) && tools/ck-version-info
+ cd $(srcdir) && tools/ck-copyright-notice
diff --git a/mpfr/Makefile.in b/mpfr/Makefile.in
new file mode 100644
index 0000000000..508e029ac4
--- /dev/null
+++ b/mpfr/Makefile.in
@@ -0,0 +1,844 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(nobase_dist_doc_DATA) \
+ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/configure AUTHORS COPYING COPYING.LESSER \
+ ChangeLog INSTALL NEWS TODO compile config.guess config.sub \
+ depcomp install-sh ltmain.sh missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+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__installdirs = "$(DESTDIR)$(docdir)"
+DATA = $(nobase_dist_doc_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).tar.xz \
+ $(distdir).zip
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATAFILES = @DATAFILES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBMPFR_LDFLAGS = @LIBMPFR_LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPFR_LDFLAGS = @MPFR_LDFLAGS@
+MPFR_LIBM = @MPFR_LIBM@
+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@
+STRIP = @STRIP@
+TUNE_LIBS = @TUNE_LIBS@
+VERSION = @VERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+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@
+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@
+AUTOMAKE_OPTIONS = gnu
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = doc src tests tune
+nobase_dist_doc_DATA = AUTHORS BUGS COPYING COPYING.LESSER NEWS TODO \
+ examples/ReadMe examples/divworst.c examples/rndo-add.c examples/sample.c \
+ examples/version.c
+
+EXTRA_DIST = PATCHES VERSION \
+ tools/ck-copyright-notice tools/ck-version-info tools/get_patches.sh \
+ $(DATAFILES)
+
+all: all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-nobase_dist_docDATA: $(nobase_dist_doc_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(nobase_dist_doc_DATA)'; test -n "$(docdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \
+ fi; \
+ $(am__nobase_list) | while read dir files; do \
+ xfiles=; for file in $$files; do \
+ if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+ test -z "$$xfiles" || { \
+ test "x$$dir" = x. || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)/$$dir'"; \
+ $(MKDIR_P) "$(DESTDIR)$(docdir)/$$dir"; }; \
+ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(docdir)/$$dir'"; \
+ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(docdir)/$$dir" || exit $$?; }; \
+ done
+
+uninstall-nobase_dist_docDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nobase_dist_doc_DATA)'; test -n "$(docdir)" || list=; \
+ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @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
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod u+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(DATA)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(docdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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:
+
+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-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-nobase_dist_docDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-nobase_dist_docDATA
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am am--refresh check check-am clean clean-generic \
+ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
+ dist-gzip dist-hook dist-lzip dist-lzma dist-shar dist-tarZ \
+ dist-xz dist-zip distcheck distclean distclean-generic \
+ distclean-libtool distclean-tags distcleancheck distdir \
+ distuninstallcheck 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-nobase_dist_docDATA install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-nobase_dist_docDATA
+
+
+# Various checks for "make dist".
+# * Check consistency concerning -version-info. Moreover if the VERSION
+# file doesn't end with "-dev", check that the -version-info value is
+# up-to-date. Note: this is a heuristic, to detect some mistakes.
+# * Check that copyright notices exist and appear to be correct.
+dist-hook:
+ cd $(srcdir) && tools/ck-version-info
+ cd $(srcdir) && tools/ck-copyright-notice
+
+# 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/mpfr/NEWS b/mpfr/NEWS
new file mode 100644
index 0000000000..ce0faa385d
--- /dev/null
+++ b/mpfr/NEWS
@@ -0,0 +1,314 @@
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+##############################################################################
+
+Changes from version 3.1.1 to version 3.1.2:
+- Bug fixes (see <http://www.mpfr.org/mpfr-3.1.1/#fixed> or ChangeLog file).
+- Updated examples to the MPFR 3.x API.
+- Note: The official tarballs for MPFR up to 3.1.1 were affected by a
+ vulnerability for "make distcheck" due to a bug in old GNU Automake
+ versions: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3386
+
+Changes from version 3.1.0 to version 3.1.1:
+- Improved MPFR manual.
+- Test coverage: 96.5% lines of code.
+- Bug fixes (see <http://www.mpfr.org/mpfr-3.1.0/#fixed> or ChangeLog file).
+
+Changes from versions 3.0.* to version 3.1.0:
+- The "canard à l'orange" release.
+- The MPFR source has been reorganized.
+- Dropped ansi2knr support.
+- TLS support is now detected automatically. If TLS is supported, MPFR is
+ built as thread safe by default. To disable TLS explicitly, configure
+ MPFR with --disable-thread-safe.
+- New --enable-gmp-internals configure option to use GMP's undocumented
+ functions (not from the public API). Note that library versioning is
+ not guaranteed to work if this option is used.
+- The mpfr_urandom and mpfr_urandomb functions now return identical values
+ on processors with different word size (assuming the same random seed, and
+ since the GMP random generator does not depend itself on the word size,
+ cf http://gmplib.org/list-archives/gmp-devel/2010-September/001642.html).
+- The mpfr_add_one_ulp and mpfr_sub_one_ulp macros (which are obsolete and
+ no more documented) will be removed in a future release.
+- Speed improvement for the mpfr_sqr and mpfr_div functions using Mulders'
+ algorithm. As a consequence, other functions using those routines are
+ also faster.
+- Much faster formatted output (mpfr_printf, etc.) with %Rg and similar.
+- The --with-gmp-build configure option can now be used when the GMP
+ source directory and the GMP build directory are different (without
+ having to copy header files manually as before).
+- New functions mpfr_buildopt_gmpinternals_p, mpfr_buildopt_tune_case,
+ mpfr_frexp, mpfr_grandom and mpfr_z_sub.
+- New divide-by-zero exception (flag) and associated functions.
+- The mpfr.h header can be included several times, while still supporting
+ optional functions (see Section "Headers and Libraries" in the manual).
+- Updated tuning parameters.
+- Improved MPFR manual.
+- MPFR tests: libtool no longer generates wrapper scripts with "make check"
+ (so that running the tests under valgrind or gdb is easier).
+- Internal change: the logging mechanism has been improved.
+- Test coverage: 95.2% lines of code.
+- Bug fixes, in particular a huge inefficiency in mpfr_exp (when the
+ target precision is less than MPFR_EXP_THRESHOLD) on hard-to-round
+ cases, which can take several minutes.
+ Note: The mpfr_subnormalize implementation up to MPFR 3.0.0 did not change
+ the flags. In particular, it did not follow the generic rule concerning
+ the inexact flag (and no special behavior was specified). The case of the
+ underflow flag was more a lack of specification.
+
+Changes from versions 2.4.* to version 3.0.0:
+- The "boudin aux pommes" release.
+- MPFR 3.0.0 is binary incompatible with previous versions but (almost)
+ API compatible. More precisely the obsolete functions mpfr_random
+ and mpfr_random2 have been removed, the meaning of the return type
+ of the function mpfr_get_f has changed, and the return type of the
+ function mpfr_get_z is now int instead of void. In practice, this
+ should not break any existing code.
+- MPFR is now distributed under the GNU Lesser General Public License
+ version 3 or later (LGPL v3+).
+- Rounding modes GMP_RNDx are now MPFR_RNDx (GMP_RNDx kept for
+ compatibility).
+- A new rounding mode (MPFR_RNDA) is available to round away from zero.
+- The rounding mode type is now mpfr_rnd_t (as in previous versions,
+ both mpfr_rnd_t and mp_rnd_t are accepted, but mp_rnd_t may be
+ removed in the future).
+- The precision type is now mpfr_prec_t (as in previous versions, both
+ mpfr_prec_t and mp_prec_t are accepted, but mp_prec_t may be removed
+ in the future) and it is now signed (it was unsigned in MPFR 2.*, but
+ this was not documented). In practice, this change should not affect
+ existing code that assumed nothing on the precision type.
+- MPFR now has its own exponent type mpfr_exp_t, which is currently
+ the same as GMP's mp_exp_t.
+- Functions mpfr_random and mpfr_random2 have been removed.
+- mpfr_get_f and mpfr_get_z now return a ternary value.
+- mpfr_strtofr now accepts bases from 37 to 62.
+- mpfr_custom_get_mantissa was renamed to mpfr_custom_get_significand
+ (mpfr_custom_get_mantissa is still available via a #define).
+- Functions mpfr_get_si, mpfr_get_ui, mpfr_get_sj, mpfr_get_uj,
+ mpfr_get_z and mpfr_get_z_2exp no longer have cases with undefined
+ behavior; in these cases, the behavior is now specified, and in
+ particular, the erange flag is set.
+- New functions mpfr_buildopt_tls_p and mpfr_buildopt_decimal_p giving
+ information about options used at MPFR build time.
+- New function mpfr_regular_p.
+- New function mpfr_set_zero.
+- New function mpfr_digamma.
+- New function mpfr_ai (incomplete, experimental).
+- New functions mpfr_set_flt and mpfr_get_flt to convert from/to the
+ float type.
+- New function mpfr_urandom.
+- New function mpfr_set_z_2exp (companion to mpfr_get_z_2exp, which
+ was renamed from mpfr_get_z_exp in previous versions).
+- New function mpfr_min_prec.
+- Speed improvement for large precisions in the trigonometric functions
+ (mpfr_sin, mpfr_cos, mpfr_tan, mpfr_sin_cos): speedup of about 2.5
+ for 10^5 digits, of about 5 for 10^6 digits.
+- Speed improvement for large precisions of the inverse trigonometric
+ functions (arcsin, arccos, arctan): about 2 for 10^3 digits, up to
+ 2.7 for 10^6 digits.
+- Some documentation files are installed in $docdir.
+- The detection of a GMP build directory (more precisely, the internal
+ header files of GMP) was previously done separately from the use of
+ the --with-gmp-build configure option. This was not consistent with
+ the documentation and with other parts of the configure script. So,
+ as of MPFR 3.0.0, the internal header files of GMP are now used if
+ and only if the --with-gmp-build configure option is given.
+- The configure script recognizes some extra "long double" formats
+ (double big endian, double little endian, double-double big endian).
+- MPFR manual: added "API Compatibility" section.
+- Test coverage: 97.1% lines of code.
+- Bug fixes.
+
+Changes from versions 2.3.* to version 2.4.0:
+- The "andouillette sauce moutarde" release.
+- MPFR is now a GNU package.
+- Changes in the behavior of mpfr_strtofr and in its documentation
+ concerning particular cases where the code and the documentation
+ did not match; this change is also present in MPFR 2.3.1.
+- Behavior of mpfr_check_range changed: if the value is an inexact
+ infinity, the overflow flag is set (in case it was lost); this
+ change is also present in MPFR 2.3.2.
+- Function mpfr_init_gmp_rand (only defined when building MPFR without
+ the --with-gmp-build configure option) is no longer defined at all.
+ This function was private and not documented, and was used only in
+ the MPFR test suite. User code that calls it is regarded as broken
+ and may fail as a consequence. Running the old test suite against
+ MPFR 2.4.0 may also fail.
+- New functions:
+ * between a MPFR number and a double: mpfr_add_d, mpfr_sub_d,
+ mpfr_d_sub, mpfr_mul_d, mpfr_div_d, mpfr_d_div,
+ * formatted input/output:
+ mpfr_printf, mpfr_fprintf, mpfr_vprintf, mpfr_vfprintf,
+ mpfr_sprintf, mpfr_snprintf, mpfr_vsprintf, mpfr_vsnprintf,
+ mpfr_asprintf, mpfr_vasprintf.
+ * mpfr_sinh_cosh, mpfr_li2, mpfr_modf, mpfr_fmod, mpfr_rec_sqrt.
+- Configure test for TLS support.
+- Get default $CC and $CFLAGS from gmp.h (__GMP_CC / __GMP_CFLAGS,
+ which are available as of GMP 4.2.3).
+- Documented the fact that mpfr_random and mpfr_random2 will be
+ suppressed in the next release, and that the specification of
+ mpfr_eq may change in the next release (for compatibility with
+ the mpf layer of GMP).
+- Test coverage: 96.7% lines of code.
+- Bug fixes.
+
+Changes from versions 2.2.* to version 2.3.0:
+- The mpfr.info file is now installed in the share subdirectory
+ (as required by the Filesystem Hierarchy Standard); see output
+ of "./configure --help".
+- The shared library is now enabled by default. If the MPFR build
+ fails on your platform, try the --disable-shared configure option
+ to disable the shared library.
+- Thread-safe support with Microsoft Visual compiler.
+- New functions mpfr_j0, mpfr_j1, mpfr_jn, mpfr_y0, mpfr_y1, mpfr_yn,
+ mpfr_lgamma, mpfr_remainder, mpfr_remquo, mpfr_fms, mpfr_signbit,
+ mpfr_setsign, mpfr_copysign, mpfr_get_patches.
+- Functions mpfr_sin, mpfr_cos and mpfr_sin_cos improved (argument
+ reduction).
+- More detailed MPFR manual.
+- Improved tests (make check).
+- Bug fixes.
+
+Changes from versions 2.1.* to version 2.2.0:
+- Bug fixes.
+- new functions mpfr_set_overflow, mpfr_set_underflow, mpfr_set_inexflag,
+ mpfr_set_erangeflag, mpfr_set_nanflag, mpfr_erfc, mpfr_atan2, mpfr_pow_z,
+ mpfr_subnormalize, mpfr_const_catalan, mpfr_sec, mpfr_csc, mpfr_cot,
+ mpfr_root, mpfr_eint, mpfr_get_f, mpfr_sech, mpfr_csch, mpfr_coth,
+ mpfr_lngamma.
+- new macro: MPFR_VERSION_STRING
+- Remove the exported MPFR variables from mpfr.h to mpfr-impl.h.
+ (They were undocumented, so programs which respect the API still work).
+- Grep CC and CFLAGS from GMP Makefile if possible.
+- Math functions are faster (both average and worst cases).
+- Better support for long double.
+- Shared library of MPFR.
+- Binary compatible with previous versions if you do not use undocumented
+ features.
+- Thread safe (if built with --enable-thread-safe).
+- Logging facility.
+- Change in the semantics of mpfr_out_str/mpfr_get_str when n_digits=0.
+- Better locale support.
+
+Changes from version 2.1.0 to version 2.1.1:
+- Better way to detect the GMP library.
+- Bug fixes.
+
+Changes from version 2.0.3 to version 2.1.0:
+- Bug fixes.
+- new functions mpfr_strtofr, mpfr_set_uj, mpfr_set_sj, mpfr_set_ui_2exp,
+ mpfr_set_si_2exp, mpfr_set_sj_2exp, mpfr_set_uj_2exp, mpfr_get_uj,
+ mpfr_get_sj, mpfr_get_z, mpfr_free_str, mpfr_si_sub, mpfr_sub_si,
+ mpfr_mul_si, mpfr_si_div, mpfr_div_si, mpfr_sqr, mpfr_cmp_z, mpfr_cmp_q,
+ mpfr_zero_p, mpfr_free_cache, mpfr_sum, mpfr_get_version,
+ mpfr_get_default_rounding_mode, mpfr_get_emin_min, mpfr_get_emin_max,
+ mpfr_get_emax_min, mpfr_get_emax_max, mpfr_inits, mpfr_inits2, mpfr_clears,
+ mpfr_fits_intmax_p, mpfr_fits_uintmax_p, mpfr_clear_erangeflag,
+ mpfr_erangeflag_p, mpfr_rint_round, mpfr_rint_trunc, mpfr_rint_ceil,
+ mpfr_rint_floor.
+- new macros MPFR_DECL_INIT, MPFR_VERSION, MPFR_VERSION_NUM,
+ MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL.
+- improved documentation.
+- improved configure.
+- improved portability (library and test suite).
+- It handles correctly non IEEE-754 double.
+- GMP internal files are not needed to install MPFR.
+- It is faster with low-precision floating point.
+- New global flag: ERANGE_FLAG.
+- Binary incompatible with previous versions, but API compatible.
+- mpfr_set_str doesn't allow anymore "@NAN@garbagechar" and "@INF@garbagechar",
+ allows base 0 (detection of the base), prefix (0x, 0b), leading whitespace.
+
+Changes from version 2.0.2 to version 2.0.3:
+- Bug fixes.
+- Support GMP as a shared library (not fully tested).
+
+Changes from version 2.0.1 to version 2.0.2:
+- many bug fixes and other improvements.
+- new functions mpfr_prec_round (replaces mpfr_round_prec), mpfr_get_exp,
+ mpfr_set_exp, mpfr_get_ld, mpfr_set_ld, mpfr_get_d_2exp, mpfr_get_si,
+ mpfr_get_ui, mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward, mpfr_frac,
+ mpfr_fits_*, mpfr_cmp_d, mpfr_cmpabs, mpfr_erf, mpfr_gamma, mpfr_zeta,
+ mpfr_greater_p, mpfr_greaterequal_p, mpfr_less_p, mpfr_lessequal_p,
+ mpfr_lessgreater_p, mpfr_equal_p, mpfr_unordered_p.
+- removed functions: mpfr_print_binary, mpfr_round_prec (replaced by
+ mpfr_prec_round), mpfr_set_str_raw, mpfr_set_machine_rnd_mode.
+- function mpfr_isinteger renamed mpfr_integer_p.
+- return type of some functions changed from void to int, for consistency.
+- return type of mpfr_set_prec changed from int to void.
+- new values for exponent range.
+- rename internal variables.
+
+Changes from version 2001 to version 2.0.1:
+- new mathematical functions: acos, acosh, asin, asinh, atan, atanh, cosh,
+ base-2 exponential and logarithm, base-10 logarithm, expm1, factorial,
+ pow, pow_si, pow_ui, sinh, tan, tanh, ui_pow, ui_pow_ui
+- other new functions: mpfr_const_euler, mpfr_dim, mpfr_fma, mpfr_hypot,
+ mpfr_min, mpfr_max, mpfr_rint, mpfr_set_inf, mpfr_set_nan
+- new operations with MPZ or MPQ: mpfr_{add,sub,mul,div}_[zq]
+- new predicates: mpfr_inf_p, mpfr_nan_p, mpfr_number_p, mpfr_isinteger,
+- add mechanism to set/check exponent range (overflow, underflow), partially
+ implemented in the mpfr functions.
+- efficiency: mpfr_div is now faster when the divisor has a few limbs
+- rounding: now mpfr_pow implements exact rounding, and most functions return a
+ ternary value indicating the position of the returned value wrt the exact one
+ (thus the return value is now 'int' instead of 'void')
+- complete rewrite of the configuration files
+- mpfr_get_d, mpfr_{add,sub}_one_ulp now get a rounding mode as 2nd argument
+- some function names did change: mpz_set_fr is now mpfr_get_z_exp,
+ mpfr_print_raw is now mpfr_print_binary.
+
+Changes from version 1.0 to version 2001:
+- the default installation does not provide any more access to machine
+ rounding mode, and as a consequence does not compare MPFR results with
+ precision=53 to machine results. Add option -DTEST if you want to have
+ access to machine rounding mode, and to check MPFR results against.
+- the MPFR files do not need <math.h> any more
+- the header file <mpfr.h> was split into <mpfr.h> for exported functions
+ and <mpfr-impl.h> for internal functions. The user should not use functions
+ or macros from <mpfr-impl.h>, since those may change in further releases.
+- <mpfr.h> was modified in order to make easy a C++ interface
+- MPFR now deals with infinities (+infinity and -infinity) and NaN
+- the missing function mpfr_swap is now available
+- mpfr_zeta was removed (was incomplete)
+- mpfr_init and mpfr_init2 now initialize the corresponding variable to 0
+ (like in other initialization functions from GNU MP)
+- in case memory allocation fails, an error message is output
+- several bugs of version 1.0 were fixed
+
+Changes from version 0.4 to version 1.0:
+
+- Version 1.0 now uses a standard configure/make installation.
+- Version 1.0 implements all functions that are available in the MPF class
+ from GMP 3.1 (except mpf_swap) and a header file mpf2mpfr.h is included in
+ the distribution for easy change from MPF to MPFR.
+- Version 1.0 implements new elementary functions: mpfr_sincos
+- Some functions and macros have been renamed: mpfr_log2 is now
+ mpfr_const_log2, mpfr_pi is now mpfr_const_pi, SIGN is now MPFR_SIGN.
+- Version 1.0 uses faster algorithms for mpfr_exp, mpfr_const_pi,
+ mpfr_const_log2. Compare the timings from version 1.0 and version 0.4.
+- Version 1.0 corrects some bugs of version 0.4.
+- The precision of MPFR variables is now named mpfr_prec, which makes it
+ easier to change it, to say unsigned long long. Same for the rounding mode
+ which is called mp_rnd_t.
+
+You'll find other news concerning the GNU MPFR library on the web
+page <http://www.mpfr.org/>.
diff --git a/mpfr/PATCHES b/mpfr/PATCHES
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/mpfr/PATCHES
diff --git a/mpfr/README b/mpfr/README
new file mode 100644
index 0000000000..6d10adbb9e
--- /dev/null
+++ b/mpfr/README
@@ -0,0 +1,84 @@
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+##############################################################################
+
+The GNU MPFR distribution contains the following files:
+(This does not apply to code retrieved by Subversion.)
+
+AUTHORS - the authors of the library
+BUGS - bugs in MPFR - please read this file!
+COPYING - the GNU General Public License, version 3
+COPYING.LESSER - the GNU Lesser General Public License, version 3
+ChangeLog - the log of changes
+INSTALL - how to install MPFR (see also mpfr.texi)
+Makefile* - files for building the library
+NEWS - new features with respect to previous versions
+PATCHES - empty file (until patches are applied)
+README - this file
+TODO - what remains to do (any help is welcome!)
+VERSION - version of MPFR (next release version if taken by Subversion)
+ac*.m4 - automatic configuration files
+compile - auxiliary installation file
+config.* - auxiliary installation files
+configure* - configuration files
+depcomp - auxiliary installation file
+doc/ - directory containing the documentation (manual, FAQ)
+examples/ - directory containing examples
+install-sh - installation file
+ltmain.sh - auxiliary installation file
+m4/ - directory containing additional configuration files
+missing - auxiliary installation file
+src/ - directory containing the MPFR source
+tests/ - directory containing the testsuite (for "make check")
+tools/ - directory containing various tools
+tune/ - directory containing files for tuning MPFR
+
+According to the special exception to the GNU General Public License,
+the autotools files compile, config.sub, config.guess, ltmain.sh,
+m4/libtool.m4 and missing are distributed under the same licence of
+GNU MPFR.
+
+
+You can get the latest source code by Subversion at INRIAGForge:
+
+ svn checkout svn://scm.gforge.inria.fr/svn/mpfr/trunk mpfr
+
+or
+
+ svn checkout https://scm.gforge.inria.fr/svn/mpfr/trunk mpfr
+
+(the last argument can be any directory name). You can use
+
+ svn ls svn://scm.gforge.inria.fr/svn/mpfr/branches
+ svn ls svn://scm.gforge.inria.fr/svn/mpfr/tags
+
+to get the list of branches or tags (releases), then checkout a
+particular branch or tag instead of the trunk. Alternatively, you
+can now use the "https:" scheme (a.k.a. DAV) instead of "svn:".
+For more information about Subversion, please see:
+
+ * http://svnbook.red-bean.com/ (the official Subversion book);
+ * http://gcc.gnu.org/wiki/SvnHelp (written for GCC developers,
+ but interesting general information can be found there);
+ * http://subversion.apache.org/faq.html (the Subversion FAQ).
+
+Subversion users should read the file "doc/README.dev" (provided via
+SVN only).
diff --git a/mpfr/TODO b/mpfr/TODO
new file mode 100644
index 0000000000..b7075726d6
--- /dev/null
+++ b/mpfr/TODO
@@ -0,0 +1,434 @@
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+Table of contents:
+1. Documentation
+2. Installation
+3. Changes in existing functions
+4. New functions to implement
+5. Efficiency
+6. Miscellaneous
+7. Portability
+
+##############################################################################
+1. Documentation
+##############################################################################
+
+- add a description of the algorithms used + proof of correctness
+
+##############################################################################
+2. Installation
+##############################################################################
+
+- if we want to distinguish GMP and MPIR, we can check at configure time
+ the following symbols which are only defined in MPIR:
+
+ #define __MPIR_VERSION 0
+ #define __MPIR_VERSION_MINOR 9
+ #define __MPIR_VERSION_PATCHLEVEL 0
+
+ There is also a library symbol mpir_version, which should match VERSION, set
+ by configure, for example 0.9.0.
+
+##############################################################################
+3. Changes in existing functions
+##############################################################################
+
+- export mpfr_overflow and mpfr_underflow as public functions
+
+- many functions currently taking into account the precision of the *input*
+ variable to set the initial working precison (acosh, asinh, cosh, ...).
+ This is nonsense since the "average" working precision should only depend
+ on the precision of the *output* variable (and maybe on the *value* of
+ the input in case of cancellation).
+ -> remove those dependencies from the input precision.
+
+- mpfr_can_round:
+ change the meaning of the 2nd argument (err). Currently the error is
+ at most 2^(MPFR_EXP(b)-err), i.e. err is the relative shift wrt the
+ most significant bit of the approximation. I propose that the error
+ is now at most 2^err ulps of the approximation, i.e.
+ 2^(MPFR_EXP(b)-MPFR_PREC(b)+err).
+
+- mpfr_set_q first tries to convert the numerator and the denominator
+ to mpfr_t. But this convertion may fail even if the correctly rounded
+ result is representable. New way to implement:
+ Function q = a/b. nq = PREC(q) na = PREC(a) nb = PREC(b)
+ If na < nb
+ a <- a*2^(nb-na)
+ n <- na-nb+ (HIGH(a,nb) >= b)
+ if (n >= nq)
+ bb <- b*2^(n-nq)
+ a = q*bb+r --> q has exactly n bits.
+ else
+ aa <- a*2^(nq-n)
+ aa = q*b+r --> q has exactly n bits.
+ If RNDN, takes nq+1 bits. (See also the new division function).
+
+
+##############################################################################
+4. New functions to implement
+##############################################################################
+
+- implement mpfr_q_sub, mpfr_z_div, mpfr_q_div?
+- implement functions for random distributions, see for example
+ https://sympa.inria.fr/sympa/arc/mpfr/2010-01/msg00034.html
+ (suggested by Charles Karney <ckarney@Sarnoff.com>, 18 Jan 2010):
+ * a Bernoulli distribution with prob p/q (exact)
+ * a general discrete distribution (i with prob w[i]/sum(w[i]) (Walker
+ algorithm, but make it exact)
+ * a uniform distribution in (a,b)
+ * exponential distribution (mean lambda) (von Neumann's method?)
+ * normal distribution (mean m, s.d. sigma) (ratio method?)
+- wanted for Magma [John Cannon <john@maths.usyd.edu.au>, Tue, 19 Apr 2005]:
+ HypergeometricU(a,b,s) = 1/gamma(a)*int(exp(-su)*u^(a-1)*(1+u)^(b-a-1),
+ u=0..infinity)
+ JacobiThetaNullK
+ PolylogP, PolylogD, PolylogDold: see http://arxiv.org/abs/math.CA/0702243
+ and the references herein.
+ JBessel(n, x) = BesselJ(n+1/2, x)
+ IncompleteGamma [also wanted by <keith.briggs@bt.com> 4 Feb 2008: Gamma(a,x),
+ gamma(a,x), P(a,x), Q(a,x); see A&S 6.5, ref. [Smith01] in algorithms.bib]
+ KBessel, KBessel2 [2nd kind]
+ JacobiTheta
+ LogIntegral
+ ExponentialIntegralE1
+ E1(z) = int(exp(-t)/t, t=z..infinity), |arg z| < Pi
+ mpfr_eint1: implement E1(x) for x > 0, and Ei(-x) for x < 0
+ E1(NaN) = NaN
+ E1(+Inf) = +0
+ E1(-Inf) = -Inf
+ E1(+0) = +Inf
+ E1(-0) = -Inf
+ DawsonIntegral
+ GammaD(x) = Gamma(x+1/2)
+- functions defined in the LIA-2 standard
+ + minimum and maximum (5.2.2): max, min, max_seq, min_seq, mmax_seq
+ and mmin_seq (mpfr_min and mpfr_max correspond to mmin and mmax);
+ + rounding_rest, floor_rest, ceiling_rest (5.2.4);
+ + remr (5.2.5): x - round(x/y) y;
+ + error functions from 5.2.7 (if useful in MPFR);
+ + power1pm1 (5.3.6.7): (1 + x)^y - 1;
+ + logbase (5.3.6.12): \log_x(y);
+ + logbase1p1p (5.3.6.13): \log_{1+x}(1+y);
+ + rad (5.3.9.1): x - round(x / (2 pi)) 2 pi = remr(x, 2 pi);
+ + axis_rad (5.3.9.1) if useful in MPFR;
+ + cycle (5.3.10.1): rad(2 pi x / u) u / (2 pi) = remr(x, u);
+ + axis_cycle (5.3.10.1) if useful in MPFR;
+ + sinu, cosu, tanu, cotu, secu, cscu, cossinu, arcsinu, arccosu,
+ arctanu, arccotu, arcsecu, arccscu (5.3.10.{2..14}):
+ sin(x 2 pi / u), etc.;
+ [from which sinpi(x) = sin(Pi*x), ... are trivial to implement, with u=2.]
+ + arcu (5.3.10.15): arctan2(y,x) u / (2 pi);
+ + rad_to_cycle, cycle_to_rad, cycle_to_cycle (5.3.11.{1..3}).
+- From GSL, missing special functions (if useful in MPFR):
+ (cf http://www.gnu.org/software/gsl/manual/gsl-ref.html#Special-Functions)
+ + The Airy functions Ai(x) and Bi(x) defined by the integral representations:
+ * Ai(x) = (1/\pi) \int_0^\infty \cos((1/3) t^3 + xt) dt
+ * Bi(x) = (1/\pi) \int_0^\infty (e^(-(1/3) t^3) + \sin((1/3) t^3 + xt)) dt
+ * Derivatives of Airy Functions
+ + The Bessel functions for n integer and n fractional:
+ * Regular Modified Cylindrical Bessel Functions I_n
+ * Irregular Modified Cylindrical Bessel Functions K_n
+ * Regular Spherical Bessel Functions j_n: j_0(x) = \sin(x)/x,
+ j_1(x)= (\sin(x)/x-\cos(x))/x & j_2(x)= ((3/x^2-1)\sin(x)-3\cos(x)/x)/x
+ Note: the "spherical" Bessel functions are solutions of
+ x^2 y'' + 2 x y' + [x^2 - n (n+1)] y = 0 and satisfy
+ j_n(x) = sqrt(Pi/(2x)) J_{n+1/2}(x). They should not be mixed with the
+ classical Bessel Functions, also noted j0, j1, jn, y0, y1, yn in C99
+ and mpfr.
+ Cf http://en.wikipedia.org/wiki/Bessel_function#Spherical_Bessel_functions
+ *Irregular Spherical Bessel Functions y_n: y_0(x) = -\cos(x)/x,
+ y_1(x)= -(\cos(x)/x+\sin(x))/x &
+ y_2(x)= (-3/x^3+1/x)\cos(x)-(3/x^2)\sin(x)
+ * Regular Modified Spherical Bessel Functions i_n:
+ i_l(x) = \sqrt{\pi/(2x)} I_{l+1/2}(x)
+ * Irregular Modified Spherical Bessel Functions:
+ k_l(x) = \sqrt{\pi/(2x)} K_{l+1/2}(x).
+ + Clausen Function:
+ Cl_2(x) = - \int_0^x dt \log(2 \sin(t/2))
+ Cl_2(\theta) = \Im Li_2(\exp(i \theta)) (dilogarithm).
+ + Dawson Function: \exp(-x^2) \int_0^x dt \exp(t^2).
+ + Debye Functions: D_n(x) = n/x^n \int_0^x dt (t^n/(e^t - 1))
+ + Elliptic Integrals:
+ * Definition of Legendre Forms:
+ F(\phi,k) = \int_0^\phi dt 1/\sqrt((1 - k^2 \sin^2(t)))
+ E(\phi,k) = \int_0^\phi dt \sqrt((1 - k^2 \sin^2(t)))
+ P(\phi,k,n) = \int_0^\phi dt 1/((1 + n \sin^2(t))\sqrt(1 - k^2 \sin^2(t)))
+ * Complete Legendre forms are denoted by
+ K(k) = F(\pi/2, k)
+ E(k) = E(\pi/2, k)
+ * Definition of Carlson Forms
+ RC(x,y) = 1/2 \int_0^\infty dt (t+x)^(-1/2) (t+y)^(-1)
+ RD(x,y,z) = 3/2 \int_0^\infty dt (t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-3/2)
+ RF(x,y,z) = 1/2 \int_0^\infty dt (t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2)
+ RJ(x,y,z,p) = 3/2 \int_0^\infty dt
+ (t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2) (t+p)^(-1)
+ + Elliptic Functions (Jacobi)
+ + N-relative exponential:
+ exprel_N(x) = N!/x^N (\exp(x) - \sum_{k=0}^{N-1} x^k/k!)
+ + exponential integral:
+ E_2(x) := \Re \int_1^\infty dt \exp(-xt)/t^2.
+ Ei_3(x) = \int_0^x dt \exp(-t^3) for x >= 0.
+ Ei(x) := - PV(\int_{-x}^\infty dt \exp(-t)/t)
+ + Hyperbolic/Trigonometric Integrals
+ Shi(x) = \int_0^x dt \sinh(t)/t
+ Chi(x) := Re[ \gamma_E + \log(x) + \int_0^x dt (\cosh[t]-1)/t]
+ Si(x) = \int_0^x dt \sin(t)/t
+ Ci(x) = -\int_x^\infty dt \cos(t)/t for x > 0
+ AtanInt(x) = \int_0^x dt \arctan(t)/t
+ [ \gamma_E is the Euler constant ]
+ + Fermi-Dirac Function:
+ F_j(x) := (1/r\Gamma(j+1)) \int_0^\infty dt (t^j / (\exp(t-x) + 1))
+ + Pochhammer symbol (a)_x := \Gamma(a + x)/\Gamma(a) : see [Smith01] in
+ algorithms.bib
+ logarithm of the Pochhammer symbol
+ + Gegenbauer Functions
+ + Laguerre Functions
+ + Eta Function: \eta(s) = (1-2^{1-s}) \zeta(s)
+ Hurwitz zeta function: \zeta(s,q) = \sum_0^\infty (k+q)^{-s}.
+ + Lambert W Functions, W(x) are defined to be solutions of the equation:
+ W(x) \exp(W(x)) = x.
+ This function has multiple branches for x < 0 (2 funcs W0(x) and Wm1(x))
+ + Trigamma Function psi'(x).
+ and Polygamma Function: psi^{(m)}(x) for m >= 0, x > 0.
+
+- from gnumeric (www.gnome.org/projects/gnumeric/doc/function-reference.html):
+ - beta
+ - betaln
+ - degrees
+ - radians
+ - sqrtpi
+
+- mpfr_inp_raw, mpfr_out_raw (cf mail "Serialization of mpfr_t" from Alexey
+ and answer from Granlund on mpfr list, May 2007)
+- [maybe useful for SAGE] implement companion frac_* functions to the rint_*
+ functions. For example mpfr_frac_floor(x) = x - floor(x). (The current
+ mpfr_frac function corresponds to mpfr_rint_trunc.)
+- scaled erfc (https://sympa.inria.fr/sympa/arc/mpfr/2009-05/msg00054.html)
+- asec, acsc, acot, asech, acsch and acoth (mail from Björn Terelius on mpfr
+ list, 18 June 2009)
+
+##############################################################################
+5. Efficiency
+##############################################################################
+
+- implement a mpfr_sqrthigh algorithm based on Mulders' algorithm, with a
+ basecase variant
+- use mpn_div_q to speed up mpfr_div. However mpn_div_q, which is new in
+ GMP 5, is not documented in the GMP manual, thus we are not sure it
+ guarantees to return the same quotient as mpn_tdiv_qr.
+ Also mpfr_div uses the remainder computed by mpn_divrem. A workaround would
+ be to first try with mpn_div_q, and if we cannot (easily) compute the
+ rounding, then use the current code with mpn_divrem.
+- compute exp by using the series for cosh or sinh, which has half the terms
+ (see Exercise 4.11 from Modern Computer Arithmetic, version 0.3)
+ The same method can be used for log, using the series for atanh, i.e.,
+ atanh(x) = 1/2*log((1+x)/(1-x)).
+- improve mpfr_gamma (see http://code.google.com/p/fastfunlib/). A possible
+ idea is to implement a fast algorithm for the argument reconstruction
+ gamma(x+k). One could also use the series for 1/gamma(x), see for example
+ http://dlmf.nist.gov/5/7/ or formula (36) from
+ http://mathworld.wolfram.com/GammaFunction.html
+- fix regression with mpfr_mpz_root (from Keith Briggs, 5 July 2006), for
+ example on 3Ghz P4 with gmp-4.2, x=12.345:
+ prec=50000 k=2 k=3 k=10 k=100
+ mpz_root 0.036 0.072 0.476 7.628
+ mpfr_mpz_root 0.004 0.004 0.036 12.20
+ See also mail from Carl Witty on mpfr list, 09 Oct 2007.
+- implement Mulders algorithm for squaring and division
+- for sparse input (say x=1 with 2 bits), mpfr_exp is not faster than for
+ full precision when precision <= MPFR_EXP_THRESHOLD. The reason is
+ that argument reduction kills sparsity. Maybe avoid argument reduction
+ for sparse input?
+- speed up const_euler for large precision [for x=1.1, prec=16610, it takes
+ 75% of the total time of eint(x)!]
+- speed up mpfr_atan for large arguments (to speed up mpc_log)
+ [from Mark Watkins on Fri, 18 Mar 2005]
+ Also mpfr_atan(x) seems slower (by a factor of 2) for x near from 1.
+ Example on a Athlon for 10^5 bits: x=1.1 takes 3s, whereas 2.1 takes 1.8s.
+ The current implementation does not give monotonous timing for the following:
+ mpfr_random (x); for (i = 0; i < k; i++) mpfr_atan (y, x, MPFR_RNDN);
+ for precision 300 and k=1000, we get 1070ms, and 500ms only for p=400!
+- improve mpfr_sin on values like ~pi (do not compute sin from cos, because
+ of the cancellation). For instance, reduce the input modulo pi/2 in
+ [-pi/4,pi/4], and define auxiliary functions for which the argument is
+ assumed to be already reduced (so that the sin function can avoid
+ unnecessary computations by calling the auxiliary cos function instead of
+ the full cos function). This will require a native code for sin, for
+ example using the reduction sin(3x)=3sin(x)-4sin(x)^3.
+ See https://sympa.inria.fr/sympa/arc/mpfr/2007-08/msg00001.html and
+ the following messages.
+- improve generic.c to work for number of terms <> 2^k
+- rewrite mpfr_greater_p... as native code.
+
+- mpf_t uses a scheme where the number of limbs actually present can
+ be less than the selected precision, thereby allowing low precision
+ values (for instance small integers) to be stored and manipulated in
+ an mpf_t efficiently.
+
+ Perhaps mpfr should get something similar, especially if looking to
+ replace mpf with mpfr, though it'd be a major change. Alternately
+ perhaps those mpfr routines like mpfr_mul where optimizations are
+ possible through stripping low zero bits or limbs could check for
+ that (this would be less efficient but easier).
+
+- try the idea of the paper "Reduced Cancellation in the Evaluation of Entire
+ Functions and Applications to the Error Function" by W. Gawronski, J. Mueller
+ and M. Reinhard, to be published in SIAM Journal on Numerical Analysis: to
+ avoid cancellation in say erfc(x) for x large, they compute the Taylor
+ expansion of erfc(x)*exp(x^2/2) instead (which has less cancellation),
+ and then divide by exp(x^2/2) (which is simpler to compute).
+
+- replace the *_THRESHOLD macros by global (TLS) variables that can be
+ changed at run time (via a function, like other variables)? One benefit
+ is that users could use a single MPFR binary on several machines (e.g.,
+ a library provided by binary packages or shared via NFS) with different
+ thresholds. On the default values, this would be a bit less efficient
+ than the current code, but this isn't probably noticeable (this should
+ be tested). Something like:
+ long *mpfr_tune_get(void) to get the current values (the first value
+ is the size of the array).
+ int mpfr_tune_set(long *array) to set the tune values.
+ int mpfr_tune_run(long level) to find the best values (the support
+ for this feature is optional, this can also be done with an
+ external function).
+
+- better distinguish different processors (for example Opteron and Core 2)
+ and use corresponding default tuning parameters (as in GMP). This could be
+ done in configure.ac to avoid hacking config.guess, for example define
+ MPFR_HAVE_CORE2.
+ Note (VL): the effect on cross-compilation (that can be a processor
+ with the same architecture, e.g. compilation on a Core 2 for an
+ Opteron) is not clear. The choice should be consistent with the
+ build target (e.g. -march or -mtune value with gcc).
+ Also choose better default values. For instance, the default value of
+ MPFR_MUL_THRESHOLD is 40, while the best values that have been found
+ are between 11 and 19 for 32 bits and between 4 and 10 for 64 bits!
+
+- during the Many Digits competition, we noticed that (our implantation of)
+ Mulders short product was slower than a full product for large sizes.
+ This should be precisely analyzed and fixed if needed.
+
+##############################################################################
+6. Miscellaneous
+##############################################################################
+
+- [suggested by Tobias Burnus <burnus(at)net-b.de> and
+ Asher Langton <langton(at)gcc.gnu.org>, Wed, 01 Aug 2007]
+ support quiet and signaling NaNs in mpfr:
+ * functions to set/test a quiet/signaling NaN: mpfr_set_snan, mpfr_snan_p,
+ mpfr_set_qnan, mpfr_qnan_p
+ * correctly convert to/from double (if encoding of s/qNaN is fixed in 754R)
+
+- check again coverage: on 2007-07-27, Patrick Pelissier reports that the
+ following files are not tested at 100%: add1.c, atan.c, atan2.c,
+ cache.c, cmp2.c, const_catalan.c, const_euler.c, const_log2.c, cos.c,
+ gen_inverse.h, div_ui.c, eint.c, exp3.c, exp_2.c, expm1.c, fma.c, fms.c,
+ lngamma.c, gamma.c, get_d.c, get_f.c, get_ld.c, get_str.c, get_z.c,
+ inp_str.c, jn.c, jyn_asympt.c, lngamma.c, mpfr-gmp.c, mul.c, mul_ui.c,
+ mulders.c, out_str.c, pow.c, print_raw.c, rint.c, root.c, round_near_x.c,
+ round_raw_generic.c, set_d.c, set_ld.c, set_q.c, set_uj.c, set_z.c, sin.c,
+ sin_cos.c, sinh.c, sqr.c, stack_interface.c, sub1.c, sub1sp.c, subnormal.c,
+ uceil_exp2.c, uceil_log2.c, ui_pow_ui.c, urandomb.c, yn.c, zeta.c, zeta_ui.c.
+
+- check the constants mpfr_set_emin (-16382-63) and mpfr_set_emax (16383) in
+ get_ld.c and the other constants, and provide a testcase for large and
+ small numbers.
+
+- from Kevin Ryde <user42@zip.com.au>:
+ Also for pi.c, a pre-calculated compiled-in pi to a few thousand
+ digits would be good value I think. After all, say 10000 bits using
+ 1250 bytes would still be small compared to the code size!
+ Store pi in round to zero mode (to recover other modes).
+
+- add a new rounding mode: round to nearest, with ties away from zero
+ (this is roundTiesToAway in 754-2008, could be used by mpfr_round)
+- add a new roundind mode: round to odd. If the result is not exactly
+ representable, then round to the odd mantissa. This rounding
+ has the nice property that for k > 1, if:
+ y = round(x, p+k, TO_ODD)
+ z = round(y, p, TO_NEAREST_EVEN), then
+ z = round(x, p, TO_NEAREST_EVEN)
+ so it avoids the double-rounding problem.
+
+- add tests of the ternary value for constants
+
+- When doing Extensive Check (--enable-assert=full), since all the
+ functions use a similar use of MACROS (ZivLoop, ROUND_P), it should
+ be possible to do such a scheme:
+ For the first call to ROUND_P when we can round.
+ Mark it as such and save the approximated rounding value in
+ a temporary variable.
+ Then after, if the mark is set, check if:
+ - we still can round.
+ - The rounded value is the same.
+ It should be a complement to tgeneric tests.
+
+- in div.c, try to find a case for which cy != 0 after the line
+ cy = mpn_sub_1 (sp + k, sp + k, qsize, cy);
+ (which should be added to the tests), e.g. by having {vp, k} = 0, or
+ prove that this cannot happen.
+
+- add a configure test for --enable-logging to ignore the option if
+ it cannot be supported. Modify the "configure --help" description
+ to say "on systems that support it".
+
+- add generic bad cases for functions that don't have an inverse
+ function that is implemented (use a single Newton iteration).
+
+- add bad cases for the internal error bound (by using a dichotomy
+ between a bad case for the correct rounding and some input value
+ with fewer Ziv iterations?).
+
+- add an option to use a 32-bit exponent type (int) on LP64 machines,
+ mainly for developers, in order to be able to test the case where the
+ extended exponent range is the same as the default exponent range, on
+ such platforms.
+ Tests can be done with the exp-int branch (added on 2010-12-17, and
+ many tests fail at this time).
+
+- test underflow/overflow detection of various functions (in particular
+ mpfr_exp) in reduced exponent ranges, including ranges that do not
+ contain 0.
+
+- add an internal macro that does the equivalent of the following?
+ MPFR_IS_ZERO(x) || MPFR_GET_EXP(x) <= value
+
+- check whether __gmpfr_emin and __gmpfr_emax could be replaced by
+ a constant (see README.dev). Also check the use of MPFR_EMIN_MIN
+ and MPFR_EMAX_MAX.
+
+
+##############################################################################
+7. Portability
+##############################################################################
+
+- add a web page with results of builds on different architectures
+
+- support the decimal64 function without requiring --with-gmp-build
+
+- [Kevin about texp.c long strings]
+ For strings longer than c99 guarantees, it might be cleaner to
+ introduce a "tests_strdupcat" or something to concatenate literal
+ strings into newly allocated memory. I thought I'd done that in a
+ couple of places already. Arrays of chars are not much fun.
+
+- use http://gcc.gnu.org/viewcvs/trunk/config/stdint.m4 for mpfr-gmp.h
diff --git a/mpfr/VERSION b/mpfr/VERSION
new file mode 100644
index 0000000000..ef538c2810
--- /dev/null
+++ b/mpfr/VERSION
@@ -0,0 +1 @@
+3.1.2
diff --git a/mpfr/acinclude.m4 b/mpfr/acinclude.m4
new file mode 100644
index 0000000000..d4122734dd
--- /dev/null
+++ b/mpfr/acinclude.m4
@@ -0,0 +1,918 @@
+dnl MPFR specific autoconf macros
+
+dnl Copyright 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+dnl Contributed by the AriC and Caramel projects, INRIA.
+dnl
+dnl This file is part of the GNU MPFR Library.
+dnl
+dnl The GNU MPFR Library is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU Lesser General Public License as published
+dnl by the Free Software Foundation; either version 3 of the License, or (at
+dnl your option) any later version.
+dnl
+dnl The GNU MPFR Library is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+dnl License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public License
+dnl along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+dnl http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+dnl 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+dnl autoconf 2.60 is necessary because of the use of AC_PROG_SED.
+dnl The following line allows the autoconf wrapper (when installed)
+dnl to work as expected.
+dnl If you change the required version, please update README.dev too!
+AC_PREREQ(2.60)
+
+dnl ------------------------------------------------------------
+dnl You must put in MPFR_CONFIGS everything which configure MPFR
+dnl except:
+dnl -everything dealing with CC and CFLAGS in particular the ABI
+dnl but the IEEE-754 specific flags must be set here.
+dnl -GMP's linkage.
+dnl -Libtool stuff.
+dnl -Handling of special arguments of MPFR's configure.
+AC_DEFUN([MPFR_CONFIGS],
+[
+AC_REQUIRE([AC_OBJEXT])
+AC_REQUIRE([MPFR_CHECK_LIBM])
+AC_REQUIRE([AC_HEADER_TIME])
+AC_REQUIRE([AC_CANONICAL_HOST])
+
+AC_CHECK_HEADER([limits.h],, AC_MSG_ERROR([limits.h not found]))
+AC_CHECK_HEADER([float.h],, AC_MSG_ERROR([float.h not found]))
+AC_CHECK_HEADER([string.h],, AC_MSG_ERROR([string.h not found]))
+
+dnl Check for locales
+AC_CHECK_HEADERS([locale.h])
+
+dnl Check for wide characters (wchar_t and wint_t)
+AC_CHECK_HEADERS([wchar.h])
+
+dnl Check for stdargs
+AC_CHECK_HEADER([stdarg.h],[AC_DEFINE([HAVE_STDARG],1,[Define if stdarg])],
+ [AC_CHECK_HEADER([varargs.h],,
+ AC_MSG_ERROR([stdarg.h or varargs.h not found]))])
+
+dnl sys/fpu.h - MIPS specific
+AC_CHECK_HEADERS([sys/time.h sys/fpu.h])
+
+dnl Check how to get `alloca'
+AC_FUNC_ALLOCA
+
+dnl SIZE_MAX macro
+gl_SIZE_MAX
+
+dnl va_copy macro
+AC_MSG_CHECKING([how to copy va_list])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <stdarg.h>
+]], [[
+ va_list ap1, ap2;
+ va_copy(ap1, ap2);
+]])], [
+ AC_MSG_RESULT([va_copy])
+ AC_DEFINE(HAVE_VA_COPY)
+], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <stdarg.h>
+]], [[
+ va_list ap1, ap2;
+ __va_copy(ap1, ap2);
+]])], [AC_DEFINE([HAVE___VA_COPY]) AC_MSG_RESULT([__va_copy])],
+ [AC_MSG_RESULT([memcpy])])])
+
+dnl FIXME: The functions memmove, memset and strtol are really needed by
+dnl MPFR, but if they are implemented as macros, this is also OK (in our
+dnl case). So, we do not return an error, but their tests are currently
+dnl useless.
+dnl gettimeofday is not defined for MinGW
+AC_CHECK_FUNCS([memmove memset setlocale strtol gettimeofday])
+
+dnl Check for IEEE-754 switches on Alpha
+case $host in
+alpha*-*-*)
+ saved_CFLAGS="$CFLAGS"
+ AC_CACHE_CHECK([for IEEE-754 switches], mpfr_cv_ieee_switches, [
+ if test -n "$GCC"; then
+ mpfr_cv_ieee_switches="-mfp-rounding-mode=d -mieee-with-inexact"
+ else
+ mpfr_cv_ieee_switches="-fprm d -ieee_with_inexact"
+ fi
+ CFLAGS="$CFLAGS $mpfr_cv_ieee_switches"
+ AC_TRY_COMPILE(,,, mpfr_cv_ieee_switches="none")
+ ])
+ if test "$mpfr_cv_ieee_switches" = "none"; then
+ CFLAGS="$saved_CFLAGS"
+ else
+ CFLAGS="$saved_CFLAGS $mpfr_cv_ieee_switches"
+ fi
+esac
+
+dnl check for long long
+AC_CHECK_TYPE([long long int],
+ AC_DEFINE(HAVE_LONG_LONG, 1, [Define if compiler supports long long]),,)
+
+dnl intmax_t is C99
+AC_CHECK_TYPES([intmax_t])
+if test "$ac_cv_type_intmax_t" = yes; then
+ AC_CACHE_CHECK([for working INTMAX_MAX], mpfr_cv_have_intmax_max, [
+ saved_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I$srcdir/src"
+ AC_TRY_COMPILE([#include "mpfr-intmax.h"], [intmax_t x = INTMAX_MAX;],
+ mpfr_cv_have_intmax_max=yes, mpfr_cv_have_intmax_max=no)
+ CPPFLAGS="$saved_CPPFLAGS"
+ ])
+ if test "$mpfr_cv_have_intmax_max" = "yes"; then
+ AC_DEFINE(MPFR_HAVE_INTMAX_MAX,1,[Define if you have a working INTMAX_MAX.])
+ fi
+fi
+
+AC_CHECK_TYPE( [union fpc_csr],
+ AC_DEFINE(HAVE_FPC_CSR,1,[Define if union fpc_csr is available]), ,
+[
+#if HAVE_SYS_FPU_H
+# include <sys/fpu.h>
+#endif
+])
+
+dnl Check for fesetround
+AC_CACHE_CHECK([for fesetround], mpfr_cv_have_fesetround, [
+saved_LIBS="$LIBS"
+LIBS="$LIBS $MPFR_LIBM"
+AC_TRY_LINK([#include <fenv.h>], [fesetround(FE_TONEAREST);],
+ mpfr_cv_have_fesetround=yes, mpfr_cv_have_fesetround=no)
+LIBS="$saved_LIBS"
+])
+if test "$mpfr_cv_have_fesetround" = "yes"; then
+ AC_DEFINE(MPFR_HAVE_FESETROUND,1,[Define if you have the `fesetround' function via the <fenv.h> header file.])
+fi
+
+dnl Check for gcc float-conversion bug; if need be, -ffloat-store is used to
+dnl force the conversion to the destination type when a value is stored to
+dnl a variable (see ISO C99 standard 5.1.2.3#13, 6.3.1.5#2, 6.3.1.8#2). This
+dnl is important concerning the exponent range. Note that this doesn't solve
+dnl the double-rounding problem.
+if test -n "$GCC"; then
+ AC_CACHE_CHECK([for gcc float-conversion bug], mpfr_cv_gcc_floatconv_bug, [
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $MPFR_LIBM"
+ AC_TRY_RUN([
+#include <float.h>
+#ifdef MPFR_HAVE_FESETROUND
+#include <fenv.h>
+#endif
+static double get_max (void);
+int main() {
+ double x = 0.5;
+ double y;
+ int i;
+ for (i = 1; i <= 11; i++)
+ x *= x;
+ if (x != 0)
+ return 1;
+#ifdef MPFR_HAVE_FESETROUND
+ /* Useful test for the G4 PowerPC */
+ fesetround(FE_TOWARDZERO);
+ x = y = get_max ();
+ x *= 2.0;
+ if (x != y)
+ return 1;
+#endif
+ return 0;
+}
+static double get_max (void) { static volatile double d = DBL_MAX; return d; }
+ ], [mpfr_cv_gcc_floatconv_bug="no"],
+ [mpfr_cv_gcc_floatconv_bug="yes, use -ffloat-store"],
+ [mpfr_cv_gcc_floatconv_bug="cannot test, use -ffloat-store"])
+ LIBS="$saved_LIBS"
+ ])
+ if test "$mpfr_cv_gcc_floatconv_bug" != "no"; then
+ CFLAGS="$CFLAGS -ffloat-store"
+ fi
+fi
+
+dnl Check if denormalized numbers are supported
+AC_CACHE_CHECK([for denormalized numbers], mpfr_cv_have_denorms, [
+AC_TRY_RUN([
+#include <math.h>
+#include <stdio.h>
+int main() {
+ double x = 2.22507385850720138309e-308;
+ fprintf (stderr, "%e\n", x / 2.0);
+ return 2.0 * (x / 2.0) != x;
+}
+], mpfr_cv_have_denorms=yes, mpfr_cv_have_denorms=no, mpfr_cv_have_denorms=no)
+])
+if test "$mpfr_cv_have_denorms" = "yes"; then
+ AC_DEFINE(HAVE_DENORMS,1,[Define if denormalized floats work.])
+fi
+
+dnl Check the FP division by 0 fails (e.g. on a non-IEEE-754 platform).
+dnl In such a case, MPFR_ERRDIVZERO is defined to disable the tests
+dnl involving a FP division by 0.
+dnl For the developers: to check whether all these tests are disabled,
+dnl configure MPFR with "-DMPFR_TEST_DIVBYZERO=1 -DMPFR_ERRDIVZERO=1".
+AC_CACHE_CHECK([if the FP division by 0 fails], mpfr_cv_errdivzero, [
+AC_TRY_RUN([
+int main() {
+ volatile double d = 0.0, x;
+ x = 0.0 / d;
+ x = 1.0 / d;
+ return 0;
+}
+], [mpfr_cv_errdivzero="no"],
+ [mpfr_cv_errdivzero="yes"],
+ [mpfr_cv_errdivzero="cannot test, assume no"])
+])
+if test "$mpfr_cv_errdivzero" = "yes"; then
+ AC_DEFINE(MPFR_ERRDIVZERO,1,[Define if the FP division by 0 fails.])
+ AC_MSG_WARN([The floating-point division by 0 fails instead of])
+ AC_MSG_WARN([returning a special value: NaN or infinity. Tests])
+ AC_MSG_WARN([involving a FP division by 0 will be disabled.])
+fi
+
+dnl Check whether NAN != NAN (as required by the IEEE-754 standard,
+dnl but not by the ISO C standard). For instance, this is false with
+dnl MIPSpro 7.3.1.3m under IRIX64. By default, assume this is true.
+AC_CACHE_CHECK([if NAN == NAN], mpfr_cv_nanisnan, [
+AC_TRY_RUN([
+#include <stdio.h>
+#include <math.h>
+#ifndef NAN
+# define NAN (0.0/0.0)
+#endif
+int main() {
+ double d;
+ d = NAN;
+ return d != d;
+}
+], [mpfr_cv_nanisnan="yes"],
+ [mpfr_cv_nanisnan="no"],
+ [mpfr_cv_nanisnan="cannot test, assume no"])
+])
+if test "$mpfr_cv_nanisnan" = "yes"; then
+ AC_DEFINE(MPFR_NANISNAN,1,[Define if NAN == NAN.])
+ AC_MSG_WARN([The test NAN != NAN is false. The probable reason is that])
+ AC_MSG_WARN([your compiler optimizes floating-point expressions in an])
+ AC_MSG_WARN([unsafe way because some option, such as -ffast-math or])
+ AC_MSG_WARN([-fast (depending on the compiler), has been used. You])
+ AC_MSG_WARN([should NOT use such an option, otherwise MPFR functions])
+ AC_MSG_WARN([such as mpfr_get_d and mpfr_set_d may return incorrect])
+ AC_MSG_WARN([results on special FP numbers (e.g. NaN or signed zeros).])
+ AC_MSG_WARN([If you did not use such an option, please send us a bug])
+ AC_MSG_WARN([report so that we can try to find a workaround for your])
+ AC_MSG_WARN([platform and/or document the behavior.])
+fi
+
+dnl Check if the chars '0' to '9' are consecutive values
+AC_MSG_CHECKING([if charset has consecutive values])
+AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+char *number = "0123456789";
+char *lower = "abcdefghijklmnopqrstuvwxyz";
+char *upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+]],[[
+ int i;
+ unsigned char *p;
+ for (p = (unsigned char*) number, i = 0; i < 9; i++)
+ if ( (*p)+1 != *(p+1) ) return 1;
+ for (p = (unsigned char*) lower, i = 0; i < 25; i++)
+ if ( (*p)+1 != *(p+1) ) return 1;
+ for (p = (unsigned char*) upper, i = 0; i < 25; i++)
+ if ( (*p)+1 != *(p+1) ) return 1;
+]])], [AC_MSG_RESULT(yes)],[
+ AC_MSG_RESULT(no)
+ AC_DEFINE(MPFR_NO_CONSECUTIVE_CHARSET,1,[Charset is not consecutive])
+], [AC_MSG_RESULT(cannot test)])
+
+dnl Must be checked with the LIBM
+dnl but we don't want to add the LIBM to MPFR dependency.
+dnl Can't use AC_CHECK_FUNCS since the function may be in LIBM but
+dnl not exported in math.h
+saved_LIBS="$LIBS"
+LIBS="$LIBS $MPFR_LIBM"
+dnl AC_CHECK_FUNCS([round trunc floor ceil nearbyint])
+AC_MSG_CHECKING(for math/round)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+]], [[
+ double a = 17.42;
+ a = f (round);
+ return 0;
+]])], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_ROUND, 1,[Have ISO-C99 round function])
+],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(for math/trunc)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+]], [[
+ double a = 17.42;
+ a = f(trunc);
+ return 0;
+]])], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_TRUNC, 1,[Have ISO-C99 trunc function])
+],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(for math/floor)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+]], [[
+ double a = 17.42;
+ a = f(floor);
+ return 0;
+]])], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_FLOOR, 1,[Have ISO-C99 floor function])
+],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(for math/ceil)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+]], [[
+ double a = 17.42;
+ a = f(ceil);
+ return 0;
+]])], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CEIL, 1,[Have ISO-C99 ceil function])
+],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(for math/rint)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+]], [[
+ double a = 17.42;
+ a = f(nearbyint);
+ return 0;
+]])], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_NEARBYINT, 1,[Have ISO-C99 rint function])
+],[AC_MSG_RESULT(no)])
+
+LIBS="$saved_LIBS"
+
+dnl Now try to check the long double format
+MPFR_C_LONG_DOUBLE_FORMAT
+
+if test "$enable_logging" = yes; then
+ if test "$enable_thread_safe" = yes; then
+ AC_MSG_ERROR([Enable either `Logging' or `thread-safe', not both])
+ else
+ enable_thread_safe=no
+ fi
+fi
+
+dnl Check if thread-local variables are supported.
+dnl At least two problems can occur in practice:
+dnl 1. The compilation fails, e.g. because the compiler doesn't know
+dnl about the __thread keyword.
+dnl 2. The compilation succeeds, but the system doesn't support TLS or
+dnl there is some ld configuration problem. One of the effects can
+dnl be that thread-local variables always evaluate to 0. So, it is
+dnl important to run the test below.
+if test "$enable_thread_safe" != no; then
+AC_MSG_CHECKING(for TLS support)
+saved_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -I$srcdir/src"
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#define MPFR_USE_THREAD_SAFE 1
+#include "mpfr-thread.h"
+MPFR_THREAD_ATTR int x = 17;
+int main() {
+ return x != 17;
+}
+ ]])],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE([MPFR_USE_THREAD_SAFE],1,[Build MPFR as thread safe])
+ ],
+ [AC_MSG_RESULT(no)
+ if test "$enable_thread_safe" = yes; then
+ AC_MSG_ERROR([please configure with --disable-thread-safe])
+ fi
+ ],
+ [if test "$enable_thread_safe" = yes; then
+ AC_MSG_RESULT([cannot test, assume yes])
+ AC_DEFINE([MPFR_USE_THREAD_SAFE],1,[Build MPFR as thread safe])
+ else
+ AC_MSG_RESULT([cannot test, assume no])
+ fi
+ ])
+CPPFLAGS="$saved_CPPFLAGS"
+fi
+])
+dnl end of MPFR_CONFIGS
+
+
+dnl MPFR_C_LONG_DOUBLE_FORMAT
+dnl -------------------------
+dnl Determine the format of a long double.
+dnl
+dnl The object file is grepped, so as to work when cross compiling. A
+dnl start and end sequence is included to avoid false matches, and
+dnl allowance is made for the desired data crossing an "od -b" line
+dnl boundary. The test number is a small integer so it should appear
+dnl exactly, no rounding or truncation etc.
+dnl
+dnl "od -b" is supported even by Unix V7, and the awk script used doesn't
+dnl have functions or anything, so even an "old" awk should suffice.
+dnl
+dnl The 10-byte IEEE extended format is generally padded to either 12 or 16
+dnl bytes for alignment purposes. The SVR4 i386 ABI is 12 bytes, or i386
+dnl gcc -m128bit-long-double selects 16 bytes. IA-64 is 16 bytes in LP64
+dnl mode, or 12 bytes in ILP32 mode. The first 10 bytes is the relevant
+dnl part in all cases (big and little endian).
+dnl
+dnl Enhancements:
+dnl
+dnl Could match more formats, but no need to worry until there's code
+dnl wanting to use them.
+dnl
+dnl Don't want to duplicate the double matching from GMP_C_DOUBLE_FORMAT,
+dnl perhaps we should merge with that macro, to match data formats
+dnl irrespective of the C type in question. Or perhaps just let the code
+dnl use DOUBLE macros when sizeof(double)==sizeof(long double).
+
+AC_DEFUN([MPFR_C_LONG_DOUBLE_FORMAT],
+[AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_PROG_AWK])
+AC_REQUIRE([AC_OBJEXT])
+AC_CHECK_TYPES([long double])
+AC_CACHE_CHECK([format of `long double' floating point],
+ mpfr_cv_c_long_double_format,
+[mpfr_cv_c_long_double_format=unknown
+if test "$ac_cv_type_long_double" != yes; then
+ mpfr_cv_c_long_double_format="not available"
+else
+ cat >conftest.c <<\EOF
+[
+/* "before" is 16 bytes to ensure there's no padding between it and "x".
+ We're not expecting any "long double" bigger than 16 bytes or with
+ alignment requirements stricter than 16 bytes. */
+struct {
+ char before[16];
+ long double x;
+ char after[8];
+} foo = {
+ { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
+ -123456789.0,
+ { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
+};
+]
+EOF
+ mpfr_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >&AC_FD_CC 2>&1"
+ if AC_TRY_EVAL(mpfr_compile); then
+ cat >conftest.awk <<\EOF
+[
+BEGIN {
+ found = 0
+}
+
+# got[] holds a sliding window of bytes read the input. got[0] is the most
+# recent byte read, and got[31] the oldest byte read, so when looking to
+# match some data the indices are "reversed".
+#
+{
+ for (f = 2; f <= NF; f++)
+ {
+ # new byte, shift others up
+ for (i = 31; i >= 0; i--)
+ got[i+1] = got[i];
+ got[0] = $f;
+
+ # end sequence
+ if (got[7] != "376") continue
+ if (got[6] != "334") continue
+ if (got[5] != "272") continue
+ if (got[4] != "230") continue
+ if (got[3] != "166") continue
+ if (got[2] != "124") continue
+ if (got[1] != "062") continue
+ if (got[0] != "020") continue
+
+ # start sequence, with 8-byte body
+ if (got[23] == "001" && \
+ got[22] == "043" && \
+ got[21] == "105" && \
+ got[20] == "147" && \
+ got[19] == "211" && \
+ got[18] == "253" && \
+ got[17] == "315" && \
+ got[16] == "357")
+ {
+ saw = " (" got[15] \
+ " " got[14] \
+ " " got[13] \
+ " " got[12] \
+ " " got[11] \
+ " " got[10] \
+ " " got[9] \
+ " " got[8] ")"
+
+ if (got[15] == "301" && \
+ got[14] == "235" && \
+ got[13] == "157" && \
+ got[12] == "064" && \
+ got[11] == "124" && \
+ got[10] == "000" && \
+ got[9] == "000" && \
+ got[8] == "000")
+ {
+ print "IEEE double, big endian"
+ found = 1
+ exit
+ }
+
+ if (got[15] == "000" && \
+ got[14] == "000" && \
+ got[13] == "000" && \
+ got[12] == "124" && \
+ got[11] == "064" && \
+ got[10] == "157" && \
+ got[9] == "235" && \
+ got[8] == "301")
+ {
+ print "IEEE double, little endian"
+ found = 1
+ exit
+ }
+ }
+
+ # start sequence, with 12-byte body
+ if (got[27] == "001" && \
+ got[26] == "043" && \
+ got[25] == "105" && \
+ got[24] == "147" && \
+ got[23] == "211" && \
+ got[22] == "253" && \
+ got[21] == "315" && \
+ got[20] == "357")
+ {
+ saw = " (" got[19] \
+ " " got[18] \
+ " " got[17] \
+ " " got[16] \
+ " " got[15] \
+ " " got[14] \
+ " " got[13] \
+ " " got[12] \
+ " " got[11] \
+ " " got[10] \
+ " " got[9] \
+ " " got[8] ")"
+
+ if (got[19] == "000" && \
+ got[18] == "000" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "240" && \
+ got[14] == "242" && \
+ got[13] == "171" && \
+ got[12] == "353" && \
+ got[11] == "031" && \
+ got[10] == "300")
+ {
+ print "IEEE extended, little endian"
+ found = 1
+ exit
+ }
+
+ if (got[19] == "300" && \
+ got[18] == "031" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "353" && \
+ got[14] == "171" && \
+ got[13] == "242" && \
+ got[12] == "240" && \
+ got[11] == "000" && \
+ got[10] == "000" && \
+ got[09] == "000" && \
+ got[08] == "000")
+ {
+ # format found on m68k
+ print "IEEE extended, big endian"
+ found = 1
+ exit
+ }
+ }
+
+ # start sequence, with 16-byte body
+ if (got[31] == "001" && \
+ got[30] == "043" && \
+ got[29] == "105" && \
+ got[28] == "147" && \
+ got[27] == "211" && \
+ got[26] == "253" && \
+ got[25] == "315" && \
+ got[24] == "357")
+ {
+ saw = " (" got[23] \
+ " " got[22] \
+ " " got[21] \
+ " " got[20] \
+ " " got[19] \
+ " " got[18] \
+ " " got[17] \
+ " " got[16] \
+ " " got[15] \
+ " " got[14] \
+ " " got[13] \
+ " " got[12] \
+ " " got[11] \
+ " " got[10] \
+ " " got[9] \
+ " " got[8] ")"
+
+ if (got[23] == "000" && \
+ got[22] == "000" && \
+ got[21] == "000" && \
+ got[20] == "000" && \
+ got[19] == "240" && \
+ got[18] == "242" && \
+ got[17] == "171" && \
+ got[16] == "353" && \
+ got[15] == "031" && \
+ got[14] == "300")
+ {
+ print "IEEE extended, little endian"
+ found = 1
+ exit
+ }
+
+ if (got[23] == "300" && \
+ got[22] == "031" && \
+ got[21] == "326" && \
+ got[20] == "363" && \
+ got[19] == "105" && \
+ got[18] == "100" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "000" && \
+ got[14] == "000" && \
+ got[13] == "000" && \
+ got[12] == "000" && \
+ got[11] == "000" && \
+ got[10] == "000" && \
+ got[9] == "000" && \
+ got[8] == "000")
+ {
+ # format used on HP 9000/785 under HP-UX
+ print "IEEE quad, big endian"
+ found = 1
+ exit
+ }
+
+ if (got[23] == "000" && \
+ got[22] == "000" && \
+ got[21] == "000" && \
+ got[20] == "000" && \
+ got[19] == "000" && \
+ got[18] == "000" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "000" && \
+ got[14] == "000" && \
+ got[13] == "100" && \
+ got[12] == "105" && \
+ got[11] == "363" && \
+ got[10] == "326" && \
+ got[9] == "031" && \
+ got[8] == "300")
+ {
+ print "IEEE quad, little endian"
+ found = 1
+ exit
+ }
+
+ if (got[23] == "301" && \
+ got[22] == "235" && \
+ got[21] == "157" && \
+ got[20] == "064" && \
+ got[19] == "124" && \
+ got[18] == "000" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "000" && \
+ got[14] == "000" && \
+ got[13] == "000" && \
+ got[12] == "000" && \
+ got[11] == "000" && \
+ got[10] == "000" && \
+ got[9] == "000" && \
+ got[8] == "000")
+ {
+ # format used on 32-bit PowerPC (Mac OS X and Debian GNU/Linux)
+ print "possibly double-double, big endian"
+ found = 1
+ exit
+ }
+ }
+ }
+}
+
+END {
+ if (! found)
+ print "unknown", saw
+}
+]
+EOF
+ mpfr_cv_c_long_double_format=`od -b conftest.$OBJEXT | $AWK -f conftest.awk`
+ case $mpfr_cv_c_long_double_format in
+ unknown*)
+ echo "cannot match anything, conftest.$OBJEXT contains" >&AC_FD_CC
+ od -b conftest.$OBJEXT >&AC_FD_CC
+ ;;
+ esac
+ else
+ AC_MSG_WARN([oops, cannot compile test program])
+ fi
+fi
+rm -f conftest*
+])
+
+AH_VERBATIM([HAVE_LDOUBLE],
+[/* Define one of the following to 1 for the format of a `long double'.
+ If your format is not among these choices, or you don't know what it is,
+ then leave all undefined.
+ IEEE_EXT is the 10-byte IEEE extended precision format.
+ IEEE_QUAD is the 16-byte IEEE quadruple precision format.
+ LITTLE or BIG is the endianness. */
+#undef HAVE_LDOUBLE_IEEE_EXT_LITTLE
+#undef HAVE_LDOUBLE_IEEE_QUAD_BIG])
+
+case $mpfr_cv_c_long_double_format in
+ "IEEE extended, little endian")
+ AC_DEFINE(HAVE_LDOUBLE_IEEE_EXT_LITTLE, 1)
+ ;;
+ "IEEE quad, big endian")
+ AC_DEFINE(HAVE_LDOUBLE_IEEE_QUAD_BIG, 1)
+ ;;
+ "IEEE quad, little endian")
+ AC_DEFINE(HAVE_LDOUBLE_IEEE_QUAD_LITTLE, 1)
+ ;;
+ "possibly double-double, big endian")
+ AC_MSG_WARN([This format is known on GCC/PowerPC platforms,])
+ AC_MSG_WARN([but due to GCC PR26374, we can't test further.])
+ AC_MSG_WARN([You can safely ignore this warning, though.])
+ # Since we are not sure, we do not want to define a macro.
+ ;;
+ unknown* | "not available")
+ ;;
+ *)
+ AC_MSG_WARN([oops, unrecognised float format: $mpfr_cv_c_long_double_format])
+ ;;
+esac
+])
+
+
+dnl MPFR_CHECK_LIBM
+dnl ---------------
+dnl Determine a math library -lm to use.
+
+AC_DEFUN([MPFR_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_SUBST(MPFR_LIBM,'')
+case $host in
+ *-*-beos* | *-*-cygwin* | *-*-pw32*)
+ # According to libtool AC CHECK LIBM, these systems don't have libm
+ ;;
+ *-*-solaris*)
+ # On Solaris the math functions new in C99 are in -lm9x.
+ # FIXME: Do we need -lm9x as well as -lm, or just instead of?
+ AC_CHECK_LIB(m9x, main, MPFR_LIBM="-lm9x")
+ AC_CHECK_LIB(m, main, MPFR_LIBM="$MPFR_LIBM -lm")
+ ;;
+ *-ncr-sysv4.3*)
+ # FIXME: What does -lmw mean? Libtool AC CHECK LIBM does it this way.
+ AC_CHECK_LIB(mw, _mwvalidcheckl, MPFR_LIBM="-lmw")
+ AC_CHECK_LIB(m, main, MPFR_LIBM="$MPFR_LIBM -lm")
+ ;;
+ *)
+ AC_CHECK_LIB(m, main, MPFR_LIBM="-lm")
+ ;;
+esac
+])
+
+
+dnl MPFR_LD_SEARCH_PATHS_FIRST
+dnl --------------------------
+
+AC_DEFUN([MPFR_LD_SEARCH_PATHS_FIRST],
+[case "$LD $LDFLAGS" in
+ *-Wl,-search_paths_first*) ;;
+ *) AC_MSG_CHECKING([if the compiler understands -Wl,-search_paths_first])
+ saved_LDFLAGS="$LDFLAGS"
+ LDFLAGS="-Wl,-search_paths_first $LDFLAGS"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [AC_MSG_RESULT(yes)],
+ [AC_MSG_RESULT(no)]
+ LDFLAGS="$saved_LDFLAGS")
+ ;;
+ esac
+])
+
+
+dnl GMP_C_ATTRIBUTE_MODE
+dnl --------------------
+dnl Introduced in gcc 2.2, but perhaps not in all Apple derived versions.
+dnl Needed for mpfr-longlong.h; this is currently necessary for s390.
+dnl
+dnl TODO: Replace this with a cleaner type size detection, as this
+dnl solution only works with gcc and assumes CHAR_BIT == 8. Probably use
+dnl <stdint.h>, and <http://gcc.gnu.org/viewcvs/trunk/config/stdint.m4>
+dnl as a fallback.
+
+AC_DEFUN([GMP_C_ATTRIBUTE_MODE],
+[AC_CACHE_CHECK([whether gcc __attribute__ ((mode (XX))) works],
+ gmp_cv_c_attribute_mode,
+[AC_TRY_COMPILE([typedef int SItype __attribute__ ((mode (SI)));], ,
+ gmp_cv_c_attribute_mode=yes, gmp_cv_c_attribute_mode=no)
+])
+if test $gmp_cv_c_attribute_mode = yes; then
+ AC_DEFINE(HAVE_ATTRIBUTE_MODE, 1,
+ [Define to 1 if the compiler accepts gcc style __attribute__ ((mode (XX)))])
+fi
+])
+
+
+dnl MPFR_FUNC_GMP_PRINTF_SPEC
+dnl ------------------------------------
+dnl MPFR_FUNC_GMP_PRINTF_SPEC(spec, type, [includes], [if-true], [if-false])
+dnl Check if gmp_sprintf supports the conversion specification 'spec'
+dnl with type 'type'.
+dnl Expand 'if-true' if printf supports 'spec', 'if-false' otherwise.
+
+AC_DEFUN([MPFR_FUNC_GMP_PRINTF_SPEC],[
+AC_MSG_CHECKING(if gmp_printf supports "%$1")
+AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+$3
+#include <gmp.h>
+]], [[
+ char s[256];
+ $2 a = 17;
+
+ if (gmp_sprintf (s, "(%0.0$1)(%d)", a, 42) == -1) return 1;
+ return (strcmp (s, "(17)(42)") != 0);
+]])],
+ [AC_MSG_RESULT(yes)
+ $4],
+ [AC_MSG_RESULT(no)
+ $5])
+])
+
+
+dnl MPFR_CHECK_PRINTF_SPEC
+dnl ----------------------
+dnl Check if gmp_printf supports some optional length modifiers.
+dnl Defined symbols are negative to shorten the gcc command line.
+
+AC_DEFUN([MPFR_CHECK_PRINTF_SPEC], [
+AC_REQUIRE([MPFR_CONFIGS])dnl
+if test "$ac_cv_type_intmax_t" = yes; then
+ MPFR_FUNC_GMP_PRINTF_SPEC([jd], [intmax_t], [
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+ ],,
+ [AC_DEFINE([NPRINTF_J], 1, [gmp_printf cannot read intmax_t])])
+fi
+
+MPFR_FUNC_GMP_PRINTF_SPEC([hhd], [char], [
+#include <gmp.h>
+ ],,
+ [AC_DEFINE([NPRINTF_HH], 1, [gmp_printf cannot use `hh' length modifier])])
+
+MPFR_FUNC_GMP_PRINTF_SPEC([lld], [long long int], [
+#include <gmp.h>
+ ],,
+ [AC_DEFINE([NPRINTF_LL], 1, [gmp_printf cannot read long long int])])
+
+MPFR_FUNC_GMP_PRINTF_SPEC([Lf], [long double], [
+#include <gmp.h>
+ ],,
+ [AC_DEFINE([NPRINTF_L], 1, [gmp_printf cannot read long double])])
+
+MPFR_FUNC_GMP_PRINTF_SPEC([td], [ptrdiff_t], [
+#if defined (__cplusplus)
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+#include "gmp.h"
+ ],,
+ [AC_DEFINE([NPRINTF_T], 1, [gmp_printf cannot read ptrdiff_t])])
+])
diff --git a/mpfr/aclocal.m4 b/mpfr/aclocal.m4
new file mode 100644
index 0000000000..698f1dcbc6
--- /dev/null
+++ b/mpfr/aclocal.m4
@@ -0,0 +1,1053 @@
+# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+# Inc.
+# This file 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.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
+# Foundation, Inc.
+#
+# This file 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.
+
+# serial 1
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11.6], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.6])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 1
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
+# 2010, 2011 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 12
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
+# Inc.
+#
+# This file 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.
+
+# serial 1
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
+# 2011 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 6
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+ [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
+# Inc.
+#
+# This file 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.
+
+# serial 1
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
+# Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 1
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 3
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/size_max.m4])
+m4_include([acinclude.m4])
diff --git a/mpfr/compile b/mpfr/compile
new file mode 100755
index 0000000000..862a14e8c8
--- /dev/null
+++ b/mpfr/compile
@@ -0,0 +1,343 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-03-05.13; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free
+# Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mpfr/config.guess b/mpfr/config.guess
new file mode 100755
index 0000000000..d622a44e55
--- /dev/null
+++ b/mpfr/config.guess
@@ -0,0 +1,1530 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012 Free Software Foundation, Inc.
+
+timestamp='2012-02-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ i386)
+ eval $set_cc_for_build
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ UNAME_PROCESSOR="x86_64"
+ fi
+ fi ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/mpfr/config.sub b/mpfr/config.sub
new file mode 100755
index 0000000000..6205f8423d
--- /dev/null
+++ b/mpfr/config.sub
@@ -0,0 +1,1782 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012 Free Software Foundation, Inc.
+
+timestamp='2012-04-18'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | open8 \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i386-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/mpfr/configure b/mpfr/configure
new file mode 100755
index 0000000000..89d34330be
--- /dev/null
+++ b/mpfr/configure
@@ -0,0 +1,17228 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for MPFR 3.1.2.
+#
+#
+# Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# Contributed by the AriC and Caramel projects, INRIA.
+#
+# This file is part of the GNU MPFR Library.
+#
+# The GNU MPFR Library is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# The GNU MPFR Library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+# http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='MPFR'
+PACKAGE_TARNAME='mpfr'
+PACKAGE_VERSION='3.1.2'
+PACKAGE_STRING='MPFR 3.1.2'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+DATAFILES
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+LIBTOOL
+OBJDUMP
+DLLTOOL
+AS
+LIBMPFR_LDFLAGS
+MPFR_LDFLAGS
+TUNE_LIBS
+ALLOCA
+MPFR_LIBM
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+SED
+EGREP
+GREP
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+with_gmp_include
+with_gmp_lib
+with_gmp
+with_gmp_build
+with_mulhigh_size
+enable_gmp_internals
+enable_assert
+enable_logging
+enable_thread_safe
+enable_warnings
+enable_tests_timeout
+enable_dependency_tracking
+enable_decimal_float
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures MPFR 3.1.2 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/mpfr]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of MPFR 3.1.2:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-maintainer-mode disable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --enable-gmp-internals enable use of GMP undocumented functions [default=no]
+ --enable-assert enable ASSERT checking [default=no]
+ --enable-logging enable MPFR logging (the system must support it)
+ [default=no]
+ --disable-thread-safe explicitly disable TLS support
+ --enable-thread-safe build MPFR as thread safe, i.e. with TLS support
+ (the system must support it) [default=autodetect]
+ --enable-warnings allow MPFR to output warnings to stderr [default=no]
+ --enable-tests-timeout=NUM enable timeout (NUM seconds) for test programs
+ (NUM <= 9999) [default=no]; if enabled, env variable
+ $MPFR_TESTS_TIMEOUT overrides NUM (0: no timeout).
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-decimal-float build conversion functions from/to decimal floats
+ [default=no]
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-gmp-include=DIR GMP include directory
+ --with-gmp-lib=DIR GMP lib directory
+ --with-gmp=DIR GMP install directory
+ --with-gmp-build=DIR GMP build directory (please read INSTALL file)
+ --with-mulhigh-size=NUM internal threshold table for mulhigh
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot=DIR Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+MPFR configure 3.1.2
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation; either version 3 of the License, or (at
+your option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by MPFR $as_me 3.1.2, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+am__api_version='1.11'
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='mpfr'
+ VERSION='3.1.2'
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=yes
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+
+
+test_CFLAGS=${CFLAGS+set}
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+
+
+unset gmp_lib_path GMP_CFLAGS GMP_CC
+
+# Check whether --with-gmp_include was given.
+if test "${with_gmp_include+set}" = set; then :
+ withval=$with_gmp_include; CPPFLAGS="$CPPFLAGS -I$withval"
+fi
+
+
+# Check whether --with-gmp_lib was given.
+if test "${with_gmp_lib+set}" = set; then :
+ withval=$with_gmp_lib;
+ LDFLAGS="$LDFLAGS -L$withval"
+ gmp_lib_path="$withval"
+
+fi
+
+
+# Check whether --with-gmp was given.
+if test "${with_gmp+set}" = set; then :
+ withval=$with_gmp;
+ if test -z "$with_gmp_lib" && test -z "$with_gmp_include" ; then
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ gmp_lib_path="$withval/lib"
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Do not use --with-gmp and --with-gmp-include/--with-gmp-lib options simultaneously.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+
+fi
+
+
+
+# Check whether --with-gmp_build was given.
+if test "${with_gmp_build+set}" = set; then :
+ withval=$with_gmp_build;
+ if test -z "$gmp_lib_path" && test -z "$with_gmp_include" ; then
+ CPPFLAGS="$CPPFLAGS -I$withval -I$withval/tune"
+ LDFLAGS="$LDFLAGS -L$withval -L$withval/.libs -L$withval/tune"
+ gmp_lib_path="$withval$PATH_SEPARATOR$withval/.libs$PATH_SEPARATOR$withval/tune"
+ if test -r $withval/Makefile ; then
+ GMP_CFLAGS=`$SED -n 's/^CFLAGS = //p' $withval/Makefile`
+ GMP_CC=`$SED -n 's/^CC = //p' $withval/Makefile`
+ GMP_SOURCE=`$SED -n 's/^srcdir = *//p' $withval/Makefile`
+ case "$GMP_SOURCE" in
+ .) GMP_SOURCE="" ;;
+ /*) ;;
+ ?*) GMP_SOURCE="$withval/$GMP_SOURCE" ;;
+ esac
+ if test -d "$GMP_SOURCE" ; then
+ CPPFLAGS="$CPPFLAGS -I$GMP_SOURCE -I$GMP_SOURCE/tune"
+ fi
+ fi
+ use_gmp_build=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Do not use --with-gmp-build and other --with-gmp options simultaneously.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+
+fi
+
+
+
+# Check whether --with-mulhigh_size was given.
+if test "${with_mulhigh_size+set}" = set; then :
+ withval=$with_mulhigh_size;
+cat >>confdefs.h <<_ACEOF
+#define MPFR_MULHIGH_SIZE $withval
+_ACEOF
+
+fi
+
+
+# Check whether --enable-gmp-internals was given.
+if test "${enable_gmp_internals+set}" = set; then :
+ enableval=$enable_gmp_internals; case $enableval in
+ yes)
+$as_echo "#define WANT_GMP_INTERNALS 1" >>confdefs.h
+ ;;
+ no) ;;
+ *) as_fn_error $? "bad value for --enable-gmp-internals: yes or no" "$LINENO" 5 ;;
+ esac
+fi
+
+
+# Check whether --enable-assert was given.
+if test "${enable_assert+set}" = set; then :
+ enableval=$enable_assert; case $enableval in
+ yes)
+$as_echo "#define WANT_ASSERT 1" >>confdefs.h
+ ;;
+ no) ;;
+ full)
+$as_echo "#define WANT_ASSERT 2" >>confdefs.h
+ ;;
+ *) as_fn_error $? "bad value for --enable-assert: yes, no or full" "$LINENO" 5 ;;
+ esac
+fi
+
+# Check whether --enable-logging was given.
+if test "${enable_logging+set}" = set; then :
+ enableval=$enable_logging; case $enableval in
+ yes)
+$as_echo "#define MPFR_USE_LOGGING 1" >>confdefs.h
+ ;;
+ no) ;;
+ *) as_fn_error $? "bad value for --enable-logging: yes or no" "$LINENO" 5 ;;
+ esac
+fi
+
+# Check whether --enable-thread-safe was given.
+if test "${enable_thread_safe+set}" = set; then :
+ enableval=$enable_thread_safe; case $enableval in
+ yes) ;;
+ no) ;;
+ *) as_fn_error $? "bad value for --enable-thread-safe: yes or no" "$LINENO" 5 ;;
+ esac
+fi
+
+# Check whether --enable-warnings was given.
+if test "${enable_warnings+set}" = set; then :
+ enableval=$enable_warnings; case $enableval in
+ yes)
+$as_echo "#define MPFR_USE_WARNINGS 1" >>confdefs.h
+ ;;
+ no) ;;
+ *) as_fn_error $? "bad value for --enable-warnings: yes or no" "$LINENO" 5 ;;
+ esac
+fi
+
+
+# Check whether --enable-tests-timeout was given.
+if test "${enable_tests_timeout+set}" = set; then :
+ enableval=$enable_tests_timeout; case $enableval in
+ no) ;;
+ yes)
+$as_echo "#define MPFR_TESTS_TIMEOUT 0" >>confdefs.h
+ ;;
+ [0-9]|[0-9][0-9]|[0-9][0-9][0-9]|[0-9][0-9][0-9][0-9])
+
+cat >>confdefs.h <<_ACEOF
+#define MPFR_TESTS_TIMEOUT $enableval
+_ACEOF
+ ;;
+ *) as_fn_error $? "bad value for --enable-tests-timeout" "$LINENO" 5 ;;
+ esac
+fi
+
+
+
+
+if test -n "$CFLAGS" || test -n "$CC" ; then
+ user_redefine_cc=yes
+fi
+
+
+if test -z "$user_redefine_cc" && test "$cross_compiling" != yes ; then
+
+if test -z "$GMP_CC$GMP_CFLAGS" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CC and CFLAGS in gmp.h" >&5
+$as_echo_n "checking for CC and CFLAGS in gmp.h... " >&6; }
+ GMP_CC=__GMP_CC
+ GMP_CFLAGS=__GMP_CFLAGS
+ for cpp in /lib/cpp gcc cc c99
+ do
+ test $cpp = /lib/cpp || cpp="$cpp -E"
+ echo foo > conftest.c
+ if $cpp $CPPFLAGS conftest.c > /dev/null 2> /dev/null ; then
+ # Get CC
+ echo "#include \"gmp.h\"" > conftest.c
+ echo "MPFR_OPTION __GMP_CC" >> conftest.c
+ GMP_CC=`$cpp $CPPFLAGS conftest.c 2> /dev/null | $EGREP MPFR_OPTION | $SED -e 's/MPFR_OPTION //g;s/ *" *//g'`
+ # Get CFLAGS
+ echo "#include \"gmp.h\"" > conftest.c
+ echo "MPFR_OPTION __GMP_CFLAGS" >> conftest.c
+ unset rmpedantic
+ test "$enable_logging" = yes && rmpedantic='s/[ "]-pedantic[ "]/ /g;'
+ GMP_CFLAGS=`$cpp $CPPFLAGS conftest.c 2> /dev/null | $EGREP MPFR_OPTION | $SED -e "$rmpedantic"'s/MPFR_OPTION //g;s/ *" *//g'`
+ break
+ fi
+ done
+ rm -f conftest*
+ if test "x$GMP_CC" = "x__GMP_CC" || test "x$GMP_CFLAGS" = "x__GMP_CFLAGS" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ GMP_CFLAGS=
+ GMP_CC=
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes CC=$GMP_CC CFLAGS=$GMP_CFLAGS" >&5
+$as_echo "yes CC=$GMP_CC CFLAGS=$GMP_CFLAGS" >&6; }
+ fi
+fi
+
+if test -n "$GMP_CC$GMP_CFLAGS" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CC=$GMP_CC and CFLAGS=$GMP_CFLAGS" >&5
+$as_echo_n "checking for CC=$GMP_CC and CFLAGS=$GMP_CFLAGS... " >&6; }
+ echo "int main (void) { return 0; }" > conftest.c
+ if $GMP_CC $GMP_CFLAGS -o conftest conftest.c 2> /dev/null ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CFLAGS=$GMP_CFLAGS
+ CC=$GMP_CC
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ rm -f conftest*
+fi
+
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Check whether --enable-decimal-float was given.
+if test "${enable_decimal_float+set}" = set; then :
+ enableval=$enable_decimal_float; case $enableval in
+ yes)
+$as_echo "#define MPFR_WANT_DECIMAL_FLOATS 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler knows _Decimal64" >&5
+$as_echo_n "checking if compiler knows _Decimal64... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+_Decimal64 x;
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ if test "$use_gmp_build" != yes ; then
+ as_fn_error $? "decimal float support requires --with-gmp-build" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if _GMP_IEEE_FLOATS is defined" >&5
+$as_echo_n "checking if _GMP_IEEE_FLOATS is defined... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#ifndef _GMP_IEEE_FLOATS
+#error "_GMP_IEEE_FLOATS is not defined"
+#endif
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "decimal float support requires _GMP_IEEE_FLOATS" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+else
+ as_fn_error $? "Compiler doesn't know _Decimal64; try GCC >= 4.2, configured with --enable-decimal-float
+ " "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking decimal float format" >&5
+$as_echo_n "checking decimal float format... " >&6; }
+ if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming DPD" >&5
+$as_echo "assuming DPD" >&6; }
+ $as_echo "#define DPD_FORMAT 1" >>confdefs.h
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdlib.h>
+
+int
+main ()
+{
+
+union { double d; _Decimal64 d64; } y;
+y.d64 = 1234567890123456.0dd;
+return y.d == 0.14894469406741037E-123 ? 0 :
+ y.d == 0.59075095508629822E-68 ? 1 : 2;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: DPD" >&5
+$as_echo "DPD" >&6; }
+ $as_echo "#define DPD_FORMAT 1" >>confdefs.h
+
+else
+ if test "$?" != 1 ; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "neither DPD nor BID
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: BID" >&5
+$as_echo "BID" >&6; }
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ ;;
+ no) ;;
+ *) as_fn_error $? "bad value for --enable-decimal-float: yes or no" "$LINENO" 5 ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICC" >&5
+$as_echo_n "checking for ICC... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if !defined(__ICC)
+# error "ICC Not Found"
+error
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CFLAGS="-fp_port -mp -wd1572 -wd265 -wd186 -wd239 $CFLAGS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test "$test_CFLAGS" != set && test -n "$GCC"; then
+ CFLAGS="-Wall -Wmissing-prototypes -Wpointer-arith $CFLAGS"
+fi
+
+if test "x$CC" != xcc; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+ sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } &&
+ test -f conftest2.$ac_objext && { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; };
+then
+ eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+ if test "x$CC" != xcc; then
+ # Test first that cc exists at all.
+ if { ac_try='cc -c conftest.$ac_ext >&5'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+ rm -f conftest2.*
+ if { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } &&
+ test -f conftest2.$ac_objext && { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; };
+ then
+ # cc works too.
+ :
+ else
+ # cc exists but doesn't like -o.
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+ fi
+ fi
+ fi
+else
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+
+
+
+case $host in
+ *-apple-darwin*)
+ case "$LD $LDFLAGS" in
+ *-Wl,-search_paths_first*) ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -Wl,-search_paths_first" >&5
+$as_echo_n "checking if the compiler understands -Wl,-search_paths_first... " >&6; }
+ saved_LDFLAGS="$LDFLAGS"
+ LDFLAGS="-Wl,-search_paths_first $LDFLAGS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ LDFLAGS="$saved_LDFLAGS"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ;;
+ esac
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this sort of thing. */
+ typedef int charset[2];
+ const charset cs = { 0, 0 };
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5
+$as_echo_n "checking for working volatile... " >&6; }
+if ${ac_cv_c_volatile+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+volatile int x;
+int * volatile y = (int *) 0;
+return !x && !y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_volatile=yes
+else
+ ac_cv_c_volatile=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5
+$as_echo "$ac_cv_c_volatile" >&6; }
+if test $ac_cv_c_volatile = no; then
+
+$as_echo "#define volatile /**/" >>confdefs.h
+
+fi
+
+
+
+MPFR_LIBM=''
+
+case $host in
+ *-*-beos* | *-*-cygwin* | *-*-pw32*)
+ # According to libtool AC CHECK LIBM, these systems don't have libm
+ ;;
+ *-*-solaris*)
+ # On Solaris the math functions new in C99 are in -lm9x.
+ # FIXME: Do we need -lm9x as well as -lm, or just instead of?
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm9x" >&5
+$as_echo_n "checking for main in -lm9x... " >&6; }
+if ${ac_cv_lib_m9x_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm9x $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m9x_main=yes
+else
+ ac_cv_lib_m9x_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m9x_main" >&5
+$as_echo "$ac_cv_lib_m9x_main" >&6; }
+if test "x$ac_cv_lib_m9x_main" = xyes; then :
+ MPFR_LIBM="-lm9x"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5
+$as_echo_n "checking for main in -lm... " >&6; }
+if ${ac_cv_lib_m_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_main=yes
+else
+ ac_cv_lib_m_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5
+$as_echo "$ac_cv_lib_m_main" >&6; }
+if test "x$ac_cv_lib_m_main" = xyes; then :
+ MPFR_LIBM="$MPFR_LIBM -lm"
+fi
+
+ ;;
+ *-ncr-sysv4.3*)
+ # FIXME: What does -lmw mean? Libtool AC CHECK LIBM does it this way.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mwvalidcheckl in -lmw" >&5
+$as_echo_n "checking for _mwvalidcheckl in -lmw... " >&6; }
+if ${ac_cv_lib_mw__mwvalidcheckl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmw $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _mwvalidcheckl ();
+int
+main ()
+{
+return _mwvalidcheckl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_mw__mwvalidcheckl=yes
+else
+ ac_cv_lib_mw__mwvalidcheckl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mw__mwvalidcheckl" >&5
+$as_echo "$ac_cv_lib_mw__mwvalidcheckl" >&6; }
+if test "x$ac_cv_lib_mw__mwvalidcheckl" = xyes; then :
+ MPFR_LIBM="-lmw"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5
+$as_echo_n "checking for main in -lm... " >&6; }
+if ${ac_cv_lib_m_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_main=yes
+else
+ ac_cv_lib_m_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5
+$as_echo "$ac_cv_lib_m_main" >&6; }
+if test "x$ac_cv_lib_m_main" = xyes; then :
+ MPFR_LIBM="$MPFR_LIBM -lm"
+fi
+
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5
+$as_echo_n "checking for main in -lm... " >&6; }
+if ${ac_cv_lib_m_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_main=yes
+else
+ ac_cv_lib_m_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5
+$as_echo "$ac_cv_lib_m_main" >&6; }
+if test "x$ac_cv_lib_m_main" = xyes; then :
+ MPFR_LIBM="-lm"
+fi
+
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_time=yes
+else
+ ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes; then :
+
+else
+ as_fn_error $? "limits.h not found" "$LINENO" 5
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
+if test "x$ac_cv_header_float_h" = xyes; then :
+
+else
+ as_fn_error $? "float.h not found" "$LINENO" 5
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes; then :
+
+else
+ as_fn_error $? "string.h not found" "$LINENO" 5
+fi
+
+
+
+for ac_header in locale.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default"
+if test "x$ac_cv_header_locale_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LOCALE_H 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in wchar.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default"
+if test "x$ac_cv_header_wchar_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_WCHAR_H 1
+_ACEOF
+
+fi
+
+done
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdarg_h" = xyes; then :
+
+$as_echo "#define HAVE_STDARG 1" >>confdefs.h
+
+else
+ ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default"
+if test "x$ac_cv_header_varargs_h" = xyes; then :
+
+else
+ as_fn_error $? "stdarg.h or varargs.h not found" "$LINENO" 5
+fi
+
+
+fi
+
+
+
+for ac_header in sys/time.h sys/fpu.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+$as_echo_n "checking for working alloca.h... " >&6; }
+if ${ac_cv_working_alloca_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+ if (p) return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_working_alloca_h=yes
+else
+ ac_cv_working_alloca_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
+$as_echo "$ac_cv_working_alloca_h" >&6; }
+if test $ac_cv_working_alloca_h = yes; then
+
+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
+$as_echo_n "checking for alloca... " >&6; }
+if ${ac_cv_func_alloca_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+void *alloca (size_t);
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+ if (p) return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_func_alloca_works=yes
+else
+ ac_cv_func_alloca_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
+$as_echo "$ac_cv_func_alloca_works" >&6; }
+
+if test $ac_cv_func_alloca_works = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+else
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble. Some versions do not even contain alloca or
+# contain a buggy version. If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+
+$as_echo "#define C_ALLOCA 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
+if ${ac_cv_os_cray+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "webecray" >/dev/null 2>&1; then :
+ ac_cv_os_cray=yes
+else
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
+$as_echo "$ac_cv_os_cray" >&6; }
+if test $ac_cv_os_cray = yes; then
+ for ac_func in _getb67 GETB67 getb67; do
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+ break
+fi
+
+ done
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
+$as_echo_n "checking stack direction for C alloca... " >&6; }
+if ${ac_cv_c_stack_direction+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_c_stack_direction=0
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+find_stack_direction (int *addr, int depth)
+{
+ int dir, dummy = 0;
+ if (! addr)
+ addr = &dummy;
+ *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
+ dir = depth ? find_stack_direction (addr, depth - 1) : 0;
+ return dir + dummy;
+}
+
+int
+main (int argc, char **argv)
+{
+ return find_stack_direction (0, argc + !argv + 20) < 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_stack_direction=1
+else
+ ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
+$as_echo "$ac_cv_c_stack_direction" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+
+
+ for ac_header in stdint.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdint_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STDINT_H 1
+_ACEOF
+
+fi
+
+done
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SIZE_MAX" >&5
+$as_echo_n "checking for SIZE_MAX... " >&6; }
+ if ${gl_cv_size_max+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_cv_size_max=
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <limits.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef SIZE_MAX
+Found it
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "Found it" >/dev/null 2>&1; then :
+ gl_cv_size_max=yes
+fi
+rm -f conftest*
+
+ if test -z "$gl_cv_size_max"; then
+ if ac_fn_c_compute_int "$LINENO" "sizeof (size_t) * CHAR_BIT - 1" "size_t_bits_minus_1" "#include <stddef.h>
+#include <limits.h>"; then :
+
+else
+ size_t_bits_minus_1=
+fi
+
+ if ac_fn_c_compute_int "$LINENO" "sizeof (size_t) <= sizeof (unsigned int)" "fits_in_uint" "#include <stddef.h>"; then :
+
+else
+ fits_in_uint=
+fi
+
+ if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then
+ if test $fits_in_uint = 1; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stddef.h>
+ extern size_t foo;
+ extern unsigned long foo;
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ fits_in_uint=0
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $fits_in_uint = 1; then
+ gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)"
+ else
+ gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)"
+ fi
+ else
+ gl_cv_size_max='((size_t)~(size_t)0)'
+ fi
+ fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_size_max" >&5
+$as_echo "$gl_cv_size_max" >&6; }
+ if test "$gl_cv_size_max" != yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define SIZE_MAX $gl_cv_size_max
+_ACEOF
+
+ fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to copy va_list" >&5
+$as_echo_n "checking how to copy va_list... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdarg.h>
+
+int
+main ()
+{
+
+ va_list ap1, ap2;
+ va_copy(ap1, ap2);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: va_copy" >&5
+$as_echo "va_copy" >&6; }
+ $as_echo "#define HAVE_VA_COPY 1" >>confdefs.h
+
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdarg.h>
+
+int
+main ()
+{
+
+ va_list ap1, ap2;
+ __va_copy(ap1, ap2);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ $as_echo "#define HAVE___VA_COPY 1" >>confdefs.h
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: __va_copy" >&5
+$as_echo "__va_copy" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: memcpy" >&5
+$as_echo "memcpy" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+for ac_func in memmove memset setlocale strtol gettimeofday
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+case $host in
+alpha*-*-*)
+ saved_CFLAGS="$CFLAGS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IEEE-754 switches" >&5
+$as_echo_n "checking for IEEE-754 switches... " >&6; }
+if ${mpfr_cv_ieee_switches+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ if test -n "$GCC"; then
+ mpfr_cv_ieee_switches="-mfp-rounding-mode=d -mieee-with-inexact"
+ else
+ mpfr_cv_ieee_switches="-fprm d -ieee_with_inexact"
+ fi
+ CFLAGS="$CFLAGS $mpfr_cv_ieee_switches"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ mpfr_cv_ieee_switches="none"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpfr_cv_ieee_switches" >&5
+$as_echo "$mpfr_cv_ieee_switches" >&6; }
+ if test "$mpfr_cv_ieee_switches" = "none"; then
+ CFLAGS="$saved_CFLAGS"
+ else
+ CFLAGS="$saved_CFLAGS $mpfr_cv_ieee_switches"
+ fi
+esac
+
+ac_fn_c_check_type "$LINENO" "long long int" "ac_cv_type_long_long_int" "$ac_includes_default"
+if test "x$ac_cv_type_long_long_int" = xyes; then :
+
+$as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_intmax_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INTMAX_T 1
+_ACEOF
+
+
+fi
+
+if test "$ac_cv_type_intmax_t" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working INTMAX_MAX" >&5
+$as_echo_n "checking for working INTMAX_MAX... " >&6; }
+if ${mpfr_cv_have_intmax_max+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ saved_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I$srcdir/src"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include "mpfr-intmax.h"
+int
+main ()
+{
+intmax_t x = INTMAX_MAX;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ mpfr_cv_have_intmax_max=yes
+else
+ mpfr_cv_have_intmax_max=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CPPFLAGS="$saved_CPPFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpfr_cv_have_intmax_max" >&5
+$as_echo "$mpfr_cv_have_intmax_max" >&6; }
+ if test "$mpfr_cv_have_intmax_max" = "yes"; then
+
+$as_echo "#define MPFR_HAVE_INTMAX_MAX 1" >>confdefs.h
+
+ fi
+fi
+
+ac_fn_c_check_type "$LINENO" "union fpc_csr" "ac_cv_type_union_fpc_csr" "
+#if HAVE_SYS_FPU_H
+# include <sys/fpu.h>
+#endif
+
+"
+if test "x$ac_cv_type_union_fpc_csr" = xyes; then :
+
+$as_echo "#define HAVE_FPC_CSR 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fesetround" >&5
+$as_echo_n "checking for fesetround... " >&6; }
+if ${mpfr_cv_have_fesetround+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+saved_LIBS="$LIBS"
+LIBS="$LIBS $MPFR_LIBM"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <fenv.h>
+int
+main ()
+{
+fesetround(FE_TONEAREST);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ mpfr_cv_have_fesetround=yes
+else
+ mpfr_cv_have_fesetround=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS="$saved_LIBS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpfr_cv_have_fesetround" >&5
+$as_echo "$mpfr_cv_have_fesetround" >&6; }
+if test "$mpfr_cv_have_fesetround" = "yes"; then
+
+$as_echo "#define MPFR_HAVE_FESETROUND 1" >>confdefs.h
+
+fi
+
+if test -n "$GCC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc float-conversion bug" >&5
+$as_echo_n "checking for gcc float-conversion bug... " >&6; }
+if ${mpfr_cv_gcc_floatconv_bug+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $MPFR_LIBM"
+ if test "$cross_compiling" = yes; then :
+ mpfr_cv_gcc_floatconv_bug="cannot test, use -ffloat-store"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <float.h>
+#ifdef MPFR_HAVE_FESETROUND
+#include <fenv.h>
+#endif
+static double get_max (void);
+int main() {
+ double x = 0.5;
+ double y;
+ int i;
+ for (i = 1; i <= 11; i++)
+ x *= x;
+ if (x != 0)
+ return 1;
+#ifdef MPFR_HAVE_FESETROUND
+ /* Useful test for the G4 PowerPC */
+ fesetround(FE_TOWARDZERO);
+ x = y = get_max ();
+ x *= 2.0;
+ if (x != y)
+ return 1;
+#endif
+ return 0;
+}
+static double get_max (void) { static volatile double d = DBL_MAX; return d; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ mpfr_cv_gcc_floatconv_bug="no"
+else
+ mpfr_cv_gcc_floatconv_bug="yes, use -ffloat-store"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ LIBS="$saved_LIBS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpfr_cv_gcc_floatconv_bug" >&5
+$as_echo "$mpfr_cv_gcc_floatconv_bug" >&6; }
+ if test "$mpfr_cv_gcc_floatconv_bug" != "no"; then
+ CFLAGS="$CFLAGS -ffloat-store"
+ fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for denormalized numbers" >&5
+$as_echo_n "checking for denormalized numbers... " >&6; }
+if ${mpfr_cv_have_denorms+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+if test "$cross_compiling" = yes; then :
+ mpfr_cv_have_denorms=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <math.h>
+#include <stdio.h>
+int main() {
+ double x = 2.22507385850720138309e-308;
+ fprintf (stderr, "%e\n", x / 2.0);
+ return 2.0 * (x / 2.0) != x;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ mpfr_cv_have_denorms=yes
+else
+ mpfr_cv_have_denorms=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpfr_cv_have_denorms" >&5
+$as_echo "$mpfr_cv_have_denorms" >&6; }
+if test "$mpfr_cv_have_denorms" = "yes"; then
+
+$as_echo "#define HAVE_DENORMS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the FP division by 0 fails" >&5
+$as_echo_n "checking if the FP division by 0 fails... " >&6; }
+if ${mpfr_cv_errdivzero+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+if test "$cross_compiling" = yes; then :
+ mpfr_cv_errdivzero="cannot test, assume no"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int main() {
+ volatile double d = 0.0, x;
+ x = 0.0 / d;
+ x = 1.0 / d;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ mpfr_cv_errdivzero="no"
+else
+ mpfr_cv_errdivzero="yes"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpfr_cv_errdivzero" >&5
+$as_echo "$mpfr_cv_errdivzero" >&6; }
+if test "$mpfr_cv_errdivzero" = "yes"; then
+
+$as_echo "#define MPFR_ERRDIVZERO 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The floating-point division by 0 fails instead of" >&5
+$as_echo "$as_me: WARNING: The floating-point division by 0 fails instead of" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: returning a special value: NaN or infinity. Tests" >&5
+$as_echo "$as_me: WARNING: returning a special value: NaN or infinity. Tests" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: involving a FP division by 0 will be disabled." >&5
+$as_echo "$as_me: WARNING: involving a FP division by 0 will be disabled." >&2;}
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if NAN == NAN" >&5
+$as_echo_n "checking if NAN == NAN... " >&6; }
+if ${mpfr_cv_nanisnan+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+if test "$cross_compiling" = yes; then :
+ mpfr_cv_nanisnan="cannot test, assume no"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <math.h>
+#ifndef NAN
+# define NAN (0.0/0.0)
+#endif
+int main() {
+ double d;
+ d = NAN;
+ return d != d;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ mpfr_cv_nanisnan="yes"
+else
+ mpfr_cv_nanisnan="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpfr_cv_nanisnan" >&5
+$as_echo "$mpfr_cv_nanisnan" >&6; }
+if test "$mpfr_cv_nanisnan" = "yes"; then
+
+$as_echo "#define MPFR_NANISNAN 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The test NAN != NAN is false. The probable reason is that" >&5
+$as_echo "$as_me: WARNING: The test NAN != NAN is false. The probable reason is that" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: your compiler optimizes floating-point expressions in an" >&5
+$as_echo "$as_me: WARNING: your compiler optimizes floating-point expressions in an" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unsafe way because some option, such as -ffast-math or" >&5
+$as_echo "$as_me: WARNING: unsafe way because some option, such as -ffast-math or" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: -fast (depending on the compiler), has been used. You" >&5
+$as_echo "$as_me: WARNING: -fast (depending on the compiler), has been used. You" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: should NOT use such an option, otherwise MPFR functions" >&5
+$as_echo "$as_me: WARNING: should NOT use such an option, otherwise MPFR functions" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: such as mpfr_get_d and mpfr_set_d may return incorrect" >&5
+$as_echo "$as_me: WARNING: such as mpfr_get_d and mpfr_set_d may return incorrect" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: results on special FP numbers (e.g. NaN or signed zeros)." >&5
+$as_echo "$as_me: WARNING: results on special FP numbers (e.g. NaN or signed zeros)." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: If you did not use such an option, please send us a bug" >&5
+$as_echo "$as_me: WARNING: If you did not use such an option, please send us a bug" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: report so that we can try to find a workaround for your" >&5
+$as_echo "$as_me: WARNING: report so that we can try to find a workaround for your" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: platform and/or document the behavior." >&5
+$as_echo "$as_me: WARNING: platform and/or document the behavior." >&2;}
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if charset has consecutive values" >&5
+$as_echo_n "checking if charset has consecutive values... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: cannot test" >&5
+$as_echo "cannot test" >&6; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+char *number = "0123456789";
+char *lower = "abcdefghijklmnopqrstuvwxyz";
+char *upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+int
+main ()
+{
+
+ int i;
+ unsigned char *p;
+ for (p = (unsigned char*) number, i = 0; i < 9; i++)
+ if ( (*p)+1 != *(p+1) ) return 1;
+ for (p = (unsigned char*) lower, i = 0; i < 25; i++)
+ if ( (*p)+1 != *(p+1) ) return 1;
+ for (p = (unsigned char*) upper, i = 0; i < 25; i++)
+ if ( (*p)+1 != *(p+1) ) return 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define MPFR_NO_CONSECUTIVE_CHARSET 1" >>confdefs.h
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+saved_LIBS="$LIBS"
+LIBS="$LIBS $MPFR_LIBM"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for math/round" >&5
+$as_echo_n "checking for math/round... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+
+int
+main ()
+{
+
+ double a = 17.42;
+ a = f (round);
+ return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_ROUND 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for math/trunc" >&5
+$as_echo_n "checking for math/trunc... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+
+int
+main ()
+{
+
+ double a = 17.42;
+ a = f(trunc);
+ return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_TRUNC 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for math/floor" >&5
+$as_echo_n "checking for math/floor... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+
+int
+main ()
+{
+
+ double a = 17.42;
+ a = f(floor);
+ return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_FLOOR 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for math/ceil" >&5
+$as_echo_n "checking for math/ceil... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+
+int
+main ()
+{
+
+ double a = 17.42;
+ a = f(ceil);
+ return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CEIL 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for math/rint" >&5
+$as_echo_n "checking for math/rint... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <math.h>
+int f (double (*func)(double)) { return 0;}
+
+int
+main ()
+{
+
+ double a = 17.42;
+ a = f(nearbyint);
+ return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_NEARBYINT 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+LIBS="$saved_LIBS"
+
+
+
+
+ac_fn_c_check_type "$LINENO" "long double" "ac_cv_type_long_double" "$ac_includes_default"
+if test "x$ac_cv_type_long_double" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONG_DOUBLE 1
+_ACEOF
+
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking format of \`long double' floating point" >&5
+$as_echo_n "checking format of \`long double' floating point... " >&6; }
+if ${mpfr_cv_c_long_double_format+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ mpfr_cv_c_long_double_format=unknown
+if test "$ac_cv_type_long_double" != yes; then
+ mpfr_cv_c_long_double_format="not available"
+else
+ cat >conftest.c <<\EOF
+
+/* "before" is 16 bytes to ensure there's no padding between it and "x".
+ We're not expecting any "long double" bigger than 16 bytes or with
+ alignment requirements stricter than 16 bytes. */
+struct {
+ char before[16];
+ long double x;
+ char after[8];
+} foo = {
+ { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
+ -123456789.0,
+ { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
+};
+
+EOF
+ mpfr_compile="$CC $CFLAGS $CPPFLAGS -c conftest.c >&5 2>&1"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$mpfr_compile\""; } >&5
+ (eval $mpfr_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ cat >conftest.awk <<\EOF
+
+BEGIN {
+ found = 0
+}
+
+# got[] holds a sliding window of bytes read the input. got[0] is the most
+# recent byte read, and got[31] the oldest byte read, so when looking to
+# match some data the indices are "reversed".
+#
+{
+ for (f = 2; f <= NF; f++)
+ {
+ # new byte, shift others up
+ for (i = 31; i >= 0; i--)
+ got[i+1] = got[i];
+ got[0] = $f;
+
+ # end sequence
+ if (got[7] != "376") continue
+ if (got[6] != "334") continue
+ if (got[5] != "272") continue
+ if (got[4] != "230") continue
+ if (got[3] != "166") continue
+ if (got[2] != "124") continue
+ if (got[1] != "062") continue
+ if (got[0] != "020") continue
+
+ # start sequence, with 8-byte body
+ if (got[23] == "001" && \
+ got[22] == "043" && \
+ got[21] == "105" && \
+ got[20] == "147" && \
+ got[19] == "211" && \
+ got[18] == "253" && \
+ got[17] == "315" && \
+ got[16] == "357")
+ {
+ saw = " (" got[15] \
+ " " got[14] \
+ " " got[13] \
+ " " got[12] \
+ " " got[11] \
+ " " got[10] \
+ " " got[9] \
+ " " got[8] ")"
+
+ if (got[15] == "301" && \
+ got[14] == "235" && \
+ got[13] == "157" && \
+ got[12] == "064" && \
+ got[11] == "124" && \
+ got[10] == "000" && \
+ got[9] == "000" && \
+ got[8] == "000")
+ {
+ print "IEEE double, big endian"
+ found = 1
+ exit
+ }
+
+ if (got[15] == "000" && \
+ got[14] == "000" && \
+ got[13] == "000" && \
+ got[12] == "124" && \
+ got[11] == "064" && \
+ got[10] == "157" && \
+ got[9] == "235" && \
+ got[8] == "301")
+ {
+ print "IEEE double, little endian"
+ found = 1
+ exit
+ }
+ }
+
+ # start sequence, with 12-byte body
+ if (got[27] == "001" && \
+ got[26] == "043" && \
+ got[25] == "105" && \
+ got[24] == "147" && \
+ got[23] == "211" && \
+ got[22] == "253" && \
+ got[21] == "315" && \
+ got[20] == "357")
+ {
+ saw = " (" got[19] \
+ " " got[18] \
+ " " got[17] \
+ " " got[16] \
+ " " got[15] \
+ " " got[14] \
+ " " got[13] \
+ " " got[12] \
+ " " got[11] \
+ " " got[10] \
+ " " got[9] \
+ " " got[8] ")"
+
+ if (got[19] == "000" && \
+ got[18] == "000" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "240" && \
+ got[14] == "242" && \
+ got[13] == "171" && \
+ got[12] == "353" && \
+ got[11] == "031" && \
+ got[10] == "300")
+ {
+ print "IEEE extended, little endian"
+ found = 1
+ exit
+ }
+
+ if (got[19] == "300" && \
+ got[18] == "031" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "353" && \
+ got[14] == "171" && \
+ got[13] == "242" && \
+ got[12] == "240" && \
+ got[11] == "000" && \
+ got[10] == "000" && \
+ got[09] == "000" && \
+ got[08] == "000")
+ {
+ # format found on m68k
+ print "IEEE extended, big endian"
+ found = 1
+ exit
+ }
+ }
+
+ # start sequence, with 16-byte body
+ if (got[31] == "001" && \
+ got[30] == "043" && \
+ got[29] == "105" && \
+ got[28] == "147" && \
+ got[27] == "211" && \
+ got[26] == "253" && \
+ got[25] == "315" && \
+ got[24] == "357")
+ {
+ saw = " (" got[23] \
+ " " got[22] \
+ " " got[21] \
+ " " got[20] \
+ " " got[19] \
+ " " got[18] \
+ " " got[17] \
+ " " got[16] \
+ " " got[15] \
+ " " got[14] \
+ " " got[13] \
+ " " got[12] \
+ " " got[11] \
+ " " got[10] \
+ " " got[9] \
+ " " got[8] ")"
+
+ if (got[23] == "000" && \
+ got[22] == "000" && \
+ got[21] == "000" && \
+ got[20] == "000" && \
+ got[19] == "240" && \
+ got[18] == "242" && \
+ got[17] == "171" && \
+ got[16] == "353" && \
+ got[15] == "031" && \
+ got[14] == "300")
+ {
+ print "IEEE extended, little endian"
+ found = 1
+ exit
+ }
+
+ if (got[23] == "300" && \
+ got[22] == "031" && \
+ got[21] == "326" && \
+ got[20] == "363" && \
+ got[19] == "105" && \
+ got[18] == "100" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "000" && \
+ got[14] == "000" && \
+ got[13] == "000" && \
+ got[12] == "000" && \
+ got[11] == "000" && \
+ got[10] == "000" && \
+ got[9] == "000" && \
+ got[8] == "000")
+ {
+ # format used on HP 9000/785 under HP-UX
+ print "IEEE quad, big endian"
+ found = 1
+ exit
+ }
+
+ if (got[23] == "000" && \
+ got[22] == "000" && \
+ got[21] == "000" && \
+ got[20] == "000" && \
+ got[19] == "000" && \
+ got[18] == "000" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "000" && \
+ got[14] == "000" && \
+ got[13] == "100" && \
+ got[12] == "105" && \
+ got[11] == "363" && \
+ got[10] == "326" && \
+ got[9] == "031" && \
+ got[8] == "300")
+ {
+ print "IEEE quad, little endian"
+ found = 1
+ exit
+ }
+
+ if (got[23] == "301" && \
+ got[22] == "235" && \
+ got[21] == "157" && \
+ got[20] == "064" && \
+ got[19] == "124" && \
+ got[18] == "000" && \
+ got[17] == "000" && \
+ got[16] == "000" && \
+ got[15] == "000" && \
+ got[14] == "000" && \
+ got[13] == "000" && \
+ got[12] == "000" && \
+ got[11] == "000" && \
+ got[10] == "000" && \
+ got[9] == "000" && \
+ got[8] == "000")
+ {
+ # format used on 32-bit PowerPC (Mac OS X and Debian GNU/Linux)
+ print "possibly double-double, big endian"
+ found = 1
+ exit
+ }
+ }
+ }
+}
+
+END {
+ if (! found)
+ print "unknown", saw
+}
+
+EOF
+ mpfr_cv_c_long_double_format=`od -b conftest.$OBJEXT | $AWK -f conftest.awk`
+ case $mpfr_cv_c_long_double_format in
+ unknown*)
+ echo "cannot match anything, conftest.$OBJEXT contains" >&5
+ od -b conftest.$OBJEXT >&5
+ ;;
+ esac
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: oops, cannot compile test program" >&5
+$as_echo "$as_me: WARNING: oops, cannot compile test program" >&2;}
+ fi
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpfr_cv_c_long_double_format" >&5
+$as_echo "$mpfr_cv_c_long_double_format" >&6; }
+
+
+
+case $mpfr_cv_c_long_double_format in
+ "IEEE extended, little endian")
+ $as_echo "#define HAVE_LDOUBLE_IEEE_EXT_LITTLE 1" >>confdefs.h
+
+ ;;
+ "IEEE quad, big endian")
+ $as_echo "#define HAVE_LDOUBLE_IEEE_QUAD_BIG 1" >>confdefs.h
+
+ ;;
+ "IEEE quad, little endian")
+ $as_echo "#define HAVE_LDOUBLE_IEEE_QUAD_LITTLE 1" >>confdefs.h
+
+ ;;
+ "possibly double-double, big endian")
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: This format is known on GCC/PowerPC platforms," >&5
+$as_echo "$as_me: WARNING: This format is known on GCC/PowerPC platforms," >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: but due to GCC PR26374, we can't test further." >&5
+$as_echo "$as_me: WARNING: but due to GCC PR26374, we can't test further." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You can safely ignore this warning, though." >&5
+$as_echo "$as_me: WARNING: You can safely ignore this warning, though." >&2;}
+ # Since we are not sure, we do not want to define a macro.
+ ;;
+ unknown* | "not available")
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: oops, unrecognised float format: $mpfr_cv_c_long_double_format" >&5
+$as_echo "$as_me: WARNING: oops, unrecognised float format: $mpfr_cv_c_long_double_format" >&2;}
+ ;;
+esac
+
+
+if test "$enable_logging" = yes; then
+ if test "$enable_thread_safe" = yes; then
+ as_fn_error $? "Enable either \`Logging' or \`thread-safe', not both" "$LINENO" 5
+ else
+ enable_thread_safe=no
+ fi
+fi
+
+if test "$enable_thread_safe" != no; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TLS support" >&5
+$as_echo_n "checking for TLS support... " >&6; }
+saved_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -I$srcdir/src"
+if test "$cross_compiling" = yes; then :
+ if test "$enable_thread_safe" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: cannot test, assume yes" >&5
+$as_echo "cannot test, assume yes" >&6; }
+
+$as_echo "#define MPFR_USE_THREAD_SAFE 1" >>confdefs.h
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: cannot test, assume no" >&5
+$as_echo "cannot test, assume no" >&6; }
+ fi
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define MPFR_USE_THREAD_SAFE 1
+#include "mpfr-thread.h"
+MPFR_THREAD_ATTR int x = 17;
+int main() {
+ return x != 17;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define MPFR_USE_THREAD_SAFE 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ if test "$enable_thread_safe" = yes; then
+ as_fn_error $? "please configure with --disable-thread-safe" "$LINENO" 5
+ fi
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+CPPFLAGS="$saved_CPPFLAGS"
+fi
+
+
+# (Based on GMP 5.1)
+# clock_gettime is in librt on *-*-osf5.1 and on glibc < 2.17, so add -lrt to
+# TUNE_LIBS if needed (e.g. if clock_gettime is not already in the C library).
+# On linux (tested on x86_32, 2.6.26), clock_getres reports ns accuracy,
+# while in a quick test on osf, clock_getres said only 1 millisecond.
+old_LIBS="$LIBS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
+$as_echo_n "checking for library containing clock_gettime... " >&6; }
+if ${ac_cv_search_clock_gettime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' rt; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_clock_gettime=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_clock_gettime+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_clock_gettime+:} false; then :
+
+else
+ ac_cv_search_clock_gettime=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
+$as_echo "$ac_cv_search_clock_gettime" >&6; }
+ac_res=$ac_cv_search_clock_gettime
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+
+$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
+
+fi
+
+TUNE_LIBS="$LIBS"
+LIBS="$old_LIBS"
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmp.h" >&5
+$as_echo_n "checking for gmp.h... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "gmp.h"
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "gmp.h can't be found, or is unusable." "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+ ac_ct_AS=$AS
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AS"; then
+ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AS="as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AS" = x; then
+ AS="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AS=$ac_ct_AS
+ fi
+else
+ AS="$ac_cv_prog_AS"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+ ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DLL/static GMP" >&5
+$as_echo_n "checking for DLL/static GMP... " >&6; }
+ if test "$enable_shared" = yes; then
+ MPFR_LDFLAGS="$MPFR_LDFLAGS -no-undefined"
+ LIBMPFR_LDFLAGS="$LIBMPFR_LDFLAGS -Wl,--output-def,.libs/libmpfr-4.dll.def"
+ dont_link_with_gmp="yes"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "gmp.h"
+#if !__GMP_LIBGMP_DLL
+# error "Dead man"
+error
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: DLL" >&5
+$as_echo "DLL" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
+ as_fn_error $? "gmp.h isn't a DLL: use --enable-static --disable-shared" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "gmp.h"
+#if __GMP_LIBGMP_DLL
+# error "Dead man"
+error
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: DLL" >&5
+$as_echo "DLL" >&6; }
+ as_fn_error $? "gmp.h is a DLL: use --disable-static --enable-shared" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ ;;
+esac
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case "$ECHO" in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ # When it learns to make shared objects, it will
+ # presumably use -fPIC.
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ link_all_deplibs=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ link_all_deplibs=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc __attribute__ ((mode (XX))) works" >&5
+$as_echo_n "checking whether gcc __attribute__ ((mode (XX))) works... " >&6; }
+if ${gmp_cv_c_attribute_mode+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+typedef int SItype __attribute__ ((mode (SI)));
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gmp_cv_c_attribute_mode=yes
+else
+ gmp_cv_c_attribute_mode=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gmp_cv_c_attribute_mode" >&5
+$as_echo "$gmp_cv_c_attribute_mode" >&6; }
+if test $gmp_cv_c_attribute_mode = yes; then
+
+$as_echo "#define HAVE_ATTRIBUTE_MODE 1" >>confdefs.h
+
+fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for recent GMP" >&5
+$as_echo_n "checking for recent GMP... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include "gmp.h"
+#if (__GNU_MP_VERSION*100+__GNU_MP_VERSION_MINOR*10 < 410)
+# error "min GMP version is 4.1.0"
+error
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "GMP 4.1.0 min required" "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test "$use_gmp_build" = yes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmp internal files" >&5
+$as_echo_n "checking for gmp internal files... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include "gmp.h"
+ #include "gmp-impl.h"
+ #include "longlong.h"
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define MPFR_HAVE_GMP_IMPL 1" >>confdefs.h
+
+
+else
+
+ as_fn_error $? "header files gmp-impl.h and longlong.h not found" "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test "$use_gmp_build" = yes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for valid GMP_NUMB_BITS" >&5
+$as_echo_n "checking for valid GMP_NUMB_BITS... " >&6; }
+ if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: can't test" >&5
+$as_echo "can't test" >&6; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <limits.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+main ()
+{
+
+ return GMP_NUMB_BITS == BYTES_PER_MP_LIMB * CHAR_BIT
+ && sizeof(mp_limb_t) == BYTES_PER_MP_LIMB ? 0 : 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "GMP_NUMB_BITS is incorrect.
+You probably need to change some of the GMP or MPFR compile options." "$LINENO" 5
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+
+
+if test "$dont_link_with_gmp" = yes ; then
+LIBS="-lgmp $LIBS"
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpz_init in -lgmp" >&5
+$as_echo_n "checking for __gmpz_init in -lgmp... " >&6; }
+if ${ac_cv_lib_gmp___gmpz_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __gmpz_init ();
+int
+main ()
+{
+return __gmpz_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gmp___gmpz_init=yes
+else
+ ac_cv_lib_gmp___gmpz_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp___gmpz_init" >&5
+$as_echo "$ac_cv_lib_gmp___gmpz_init" >&6; }
+if test "x$ac_cv_lib_gmp___gmpz_init" = xyes; then :
+ LIBS="-lgmp $LIBS"
+else
+ as_fn_error $? "libgmp not found or uses a different ABI (including static vs shared).
+Please read the INSTALL file -- see \"In case of problem\"." "$LINENO" 5
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if gmp.h version and libgmp version are the same" >&5
+$as_echo_n "checking if gmp.h version and libgmp version are the same... " >&6; }
+saved_LD_RUN_PATH="$LD_RUN_PATH"
+LD_RUN_PATH="${LD_RUN_PATH:+$LD_RUN_PATH$PATH_SEPARATOR}$gmp_lib_path"
+export LD_RUN_PATH
+if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: can not test" >&5
+$as_echo "can not test" >&6; }
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <string.h>
+#include "gmp.h"
+
+int
+main ()
+{
+
+ char buffer[100];
+ sprintf (buffer, "%d.%d.%d", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR,
+ __GNU_MP_VERSION_PATCHLEVEL);
+ printf ("(%s/%s) ", buffer, gmp_version);
+ if (strcmp (buffer, gmp_version) == 0)
+ return 0;
+ if (__GNU_MP_VERSION_PATCHLEVEL != 0)
+ return 1;
+ sprintf (buffer, "%d.%d", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR);
+ return (strcmp (buffer, gmp_version) != 0) ? 1 : 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+if test "$ac_cv_type_intmax_t" = yes; then
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if gmp_printf supports \"%jd\"" >&5
+$as_echo_n "checking if gmp_printf supports \"%jd\"... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include <gmp.h>
+
+int
+main ()
+{
+
+ char s[256];
+ intmax_t a = 17;
+
+ if (gmp_sprintf (s, "(%0.0jd)(%d)", a, 42) == -1) return 1;
+ return (strcmp (s, "(17)(42)") != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NPRINTF_J 1" >>confdefs.h
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if gmp_printf supports \"%hhd\"" >&5
+$as_echo_n "checking if gmp_printf supports \"%hhd\"... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+
+#include <gmp.h>
+
+#include <gmp.h>
+
+int
+main ()
+{
+
+ char s[256];
+ char a = 17;
+
+ if (gmp_sprintf (s, "(%0.0hhd)(%d)", a, 42) == -1) return 1;
+ return (strcmp (s, "(17)(42)") != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NPRINTF_HH 1" >>confdefs.h
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if gmp_printf supports \"%lld\"" >&5
+$as_echo_n "checking if gmp_printf supports \"%lld\"... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+
+#include <gmp.h>
+
+#include <gmp.h>
+
+int
+main ()
+{
+
+ char s[256];
+ long long int a = 17;
+
+ if (gmp_sprintf (s, "(%0.0lld)(%d)", a, 42) == -1) return 1;
+ return (strcmp (s, "(17)(42)") != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NPRINTF_LL 1" >>confdefs.h
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if gmp_printf supports \"%Lf\"" >&5
+$as_echo_n "checking if gmp_printf supports \"%Lf\"... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+
+#include <gmp.h>
+
+#include <gmp.h>
+
+int
+main ()
+{
+
+ char s[256];
+ long double a = 17;
+
+ if (gmp_sprintf (s, "(%0.0Lf)(%d)", a, 42) == -1) return 1;
+ return (strcmp (s, "(17)(42)") != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NPRINTF_L 1" >>confdefs.h
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if gmp_printf supports \"%td\"" >&5
+$as_echo_n "checking if gmp_printf supports \"%td\"... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+
+#if defined (__cplusplus)
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+#include "gmp.h"
+
+#include <gmp.h>
+
+int
+main ()
+{
+
+ char s[256];
+ ptrdiff_t a = 17;
+
+ if (gmp_sprintf (s, "(%0.0td)(%d)", a, 42) == -1) return 1;
+ return (strcmp (s, "(17)(42)") != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NPRINTF_T 1" >>confdefs.h
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ==========================================================" >&5
+$as_echo "$as_me: WARNING: ==========================================================" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'gmp.h' and 'libgmp' seem to have different versions or" >&5
+$as_echo "$as_me: WARNING: 'gmp.h' and 'libgmp' seem to have different versions or" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: we cannot run a program linked with GMP (if you cannot" >&5
+$as_echo "$as_me: WARNING: we cannot run a program linked with GMP (if you cannot" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: see the version numbers above). A cause may be different" >&5
+$as_echo "$as_me: WARNING: see the version numbers above). A cause may be different" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GMP versions with different ABI's or the use of --with-gmp" >&5
+$as_echo "$as_me: WARNING: GMP versions with different ABI's or the use of --with-gmp" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: or --with-gmp-include with a system include directory" >&5
+$as_echo "$as_me: WARNING: or --with-gmp-include with a system include directory" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: (such as /usr/include or /usr/local/include)." >&5
+$as_echo "$as_me: WARNING: (such as /usr/include or /usr/local/include)." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: However since we can't use 'libtool' inside the configure," >&5
+$as_echo "$as_me: WARNING: However since we can't use 'libtool' inside the configure," >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: we can't be sure. See 'config.log' for details." >&5
+$as_echo "$as_me: WARNING: we can't be sure. See 'config.log' for details." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ==========================================================" >&5
+$as_echo "$as_me: WARNING: ==========================================================" >&2;}
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+LD_RUN_PATH="$saved_LD_RUN_PATH"
+
+for ac_func in __gmpn_rootrem __gmpn_sbpi1_divappr_q
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+fi
+
+if test -f confdefs.h; then
+ $SED '/#define PACKAGE_/d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_STRING/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_ALLOCA /d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_DLFCN_H/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_MEM/d' <confdefs.h >confdefs.tmp
+ $SED '/#define STDC_HEADERS/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_STRTOL/d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_STDLIB_H/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_UNISTD_H/d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_STDC_HEADERS/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_LONG_DOUBLE/d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_SYS_STAT_H/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_SYS_TYPES_H/d' <confdefs.h >confdefs.tmp
+ $SED '/#define PROTOTYPES/d' <confdefs.tmp >confdefs.h
+ $SED '/#define __PROTOTYPES/d' <confdefs.h >confdefs.tmp
+
+ mv confdefs.tmp confdefs.h
+fi
+
+if $EGREP -q -e '-dev$' $srcdir/VERSION; then
+ DATAFILES=`echo \`$SED -n \
+ 's/^ *data_check *("\(data\/[^"]*\)".*/tests\/\1/p' \
+ $srcdir/tests/*.c\``
+fi
+
+ac_config_files="$ac_config_files Makefile doc/Makefile src/Makefile tests/Makefile tune/Makefile src/mparam.h:src/mparam_h.in"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by MPFR $as_me 3.1.2, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+MPFR config.status 3.1.2
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in AS \
+DLLTOOL \
+OBJDUMP \
+SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+ "tune/Makefile") CONFIG_FILES="$CONFIG_FILES tune/Makefile" ;;
+ "src/mparam.h") CONFIG_FILES="$CONFIG_FILES src/mparam.h:src/mparam_h.in" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Assembler program.
+AS=$lt_AS
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$lt_OBJDUMP
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ if test x"$xsi_shell" = xyes; then
+ sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\ # positional parameters, so assign one to ordinary parameter first.\
+\ func_stripname_result=${3}\
+\ func_stripname_result=${func_stripname_result#"${1}"}\
+\ func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\ func_split_long_opt_name=${1%%=*}\
+\ func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\ func_split_short_opt_arg=${1#??}\
+\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\ case ${1} in\
+\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\ *) func_lo2o_result=${1} ;;\
+\ esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+ func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+ func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+ func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+ eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\ func_quote_for_eval "${2}"\
+\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
diff --git a/mpfr/configure.ac b/mpfr/configure.ac
new file mode 100644
index 0000000000..48493d1580
--- /dev/null
+++ b/mpfr/configure.ac
@@ -0,0 +1,561 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_COPYRIGHT([
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation; either version 3 of the License, or (at
+your option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+dnl Add check-news when it checks for more than 15 lines
+AC_INIT([MPFR],[3.1.2])
+
+AM_INIT_AUTOMAKE([1.11 no-define dist-bzip2 dist-xz dist-zip])
+AM_MAINTAINER_MODE(enable)
+
+AC_CONFIG_MACRO_DIR([m4])
+
+dnl FIXME: The AC_ARG_ENABLE(decimal-float...) part does things too
+dnl early, even when this option is not used. In particular, it must
+dnl be put after AC_PROG_CC; another problem is that the GMP CFLAGS
+dnl and CC check may modify the compiler.
+
+test_CFLAGS=${CFLAGS+set}
+
+AC_CANONICAL_HOST
+
+AC_PROG_EGREP
+AC_PROG_SED
+
+dnl To use a separate config header.
+dnl There is still some problem with GMP's HAVE_CONFIG
+dnl AC_CONFIG_HEADERS([mpfrconf.h:mpfrconf.in])
+
+dnl Extra arguments to configure
+unset gmp_lib_path GMP_CFLAGS GMP_CC
+AC_ARG_WITH(gmp_include,
+ [ --with-gmp-include=DIR GMP include directory ],
+ CPPFLAGS="$CPPFLAGS -I$withval")
+AC_ARG_WITH(gmp_lib,
+ [ --with-gmp-lib=DIR GMP lib directory ], [
+ LDFLAGS="$LDFLAGS -L$withval"
+ gmp_lib_path="$withval"
+ ])
+AC_ARG_WITH(gmp,
+ [ --with-gmp=DIR GMP install directory ], [
+ if test -z "$with_gmp_lib" && test -z "$with_gmp_include" ; then
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ gmp_lib_path="$withval/lib"
+ else
+ AC_MSG_FAILURE([Do not use --with-gmp and --with-gmp-include/--with-gmp-lib options simultaneously.])
+ fi
+ ])
+
+AC_ARG_WITH(gmp_build,
+ [ --with-gmp-build=DIR GMP build directory (please read INSTALL file)],
+ [
+ if test -z "$gmp_lib_path" && test -z "$with_gmp_include" ; then
+ CPPFLAGS="$CPPFLAGS -I$withval -I$withval/tune"
+ LDFLAGS="$LDFLAGS -L$withval -L$withval/.libs -L$withval/tune"
+ gmp_lib_path="$withval$PATH_SEPARATOR$withval/.libs$PATH_SEPARATOR$withval/tune"
+ if test -r $withval/Makefile ; then
+ GMP_CFLAGS=`$SED -n 's/^CFLAGS = //p' $withval/Makefile`
+ GMP_CC=`$SED -n 's/^CC = //p' $withval/Makefile`
+ GMP_SOURCE=`$SED -n 's/^srcdir = *//p' $withval/Makefile`
+ case "$GMP_SOURCE" in
+ .) GMP_SOURCE="" ;;
+ /*) ;;
+ ?*) GMP_SOURCE="$withval/$GMP_SOURCE" ;;
+ esac
+ if test -d "$GMP_SOURCE" ; then
+ CPPFLAGS="$CPPFLAGS -I$GMP_SOURCE -I$GMP_SOURCE/tune"
+ fi
+ fi
+ use_gmp_build=yes
+ else
+ AC_MSG_FAILURE([Do not use --with-gmp-build and other --with-gmp options simultaneously.])
+ fi
+ ])
+
+AC_ARG_WITH(mulhigh_size,
+ [ --with-mulhigh-size=NUM internal threshold table for mulhigh],
+ AC_DEFINE_UNQUOTED([MPFR_MULHIGH_SIZE],$withval, [Mulhigh size]))
+
+AC_ARG_ENABLE(gmp-internals,
+ [ --enable-gmp-internals enable use of GMP undocumented functions [[default=no]]],
+ [ case $enableval in
+ yes) AC_DEFINE([WANT_GMP_INTERNALS],1,[Want GMP internals]) ;;
+ no) ;;
+ *) AC_MSG_ERROR([bad value for --enable-gmp-internals: yes or no]) ;;
+ esac])
+
+AC_ARG_ENABLE(assert,
+ [ --enable-assert enable ASSERT checking [[default=no]]],
+ [ case $enableval in
+ yes) AC_DEFINE([WANT_ASSERT],1,[Want assertion]) ;;
+ no) ;;
+ full) AC_DEFINE([WANT_ASSERT],2,[Want assertion]) ;;
+ *) AC_MSG_ERROR([bad value for --enable-assert: yes, no or full]) ;;
+ esac])
+AC_ARG_ENABLE(logging,
+ [ --enable-logging enable MPFR logging (the system must support it)
+ [[default=no]]],
+ [ case $enableval in
+ yes) AC_DEFINE([MPFR_USE_LOGGING],1,[Log what MPFR does]) ;;
+ no) ;;
+ *) AC_MSG_ERROR([bad value for --enable-logging: yes or no]) ;;
+ esac])
+AC_ARG_ENABLE(thread-safe,
+ [ --disable-thread-safe explicitly disable TLS support
+ --enable-thread-safe build MPFR as thread safe, i.e. with TLS support
+ (the system must support it) [[default=autodetect]]],
+ [ case $enableval in
+ yes) ;;
+ no) ;;
+ *) AC_MSG_ERROR([bad value for --enable-thread-safe: yes or no]) ;;
+ esac])
+AC_ARG_ENABLE(warnings,
+ [ --enable-warnings allow MPFR to output warnings to stderr [[default=no]]],
+ [ case $enableval in
+ yes) AC_DEFINE([MPFR_USE_WARNINGS],1,[Allow MPFR to output warnings to stderr]) ;;
+ no) ;;
+ *) AC_MSG_ERROR([bad value for --enable-warnings: yes or no]) ;;
+ esac])
+
+AC_ARG_ENABLE(tests-timeout,
+ [ --enable-tests-timeout=NUM enable timeout (NUM seconds) for test programs
+ (NUM <= 9999) [[default=no]]; if enabled, env variable
+ $MPFR_TESTS_TIMEOUT overrides NUM (0: no timeout).],
+ [ case $enableval in
+ no) ;;
+ yes) AC_DEFINE([MPFR_TESTS_TIMEOUT], 0, [timeout limit]) ;;
+ [[0-9]]|[[0-9]][[0-9]]|[[0-9]][[0-9]][[0-9]]|[[0-9]][[0-9]][[0-9]][[0-9]])
+ AC_DEFINE_UNQUOTED([MPFR_TESTS_TIMEOUT], $enableval, [timeout limit]) ;;
+ *) AC_MSG_ERROR([bad value for --enable-tests-timeout]) ;;
+ esac])
+
+
+dnl
+dnl Setup CC and CFLAGS
+dnl
+
+dnl Check if user request its CC and CFLAGS
+if test -n "$CFLAGS" || test -n "$CC" ; then
+ user_redefine_cc=yes
+fi
+
+dnl ********************************************************************
+dnl Check for CC and CFLAGS in gmp.h
+
+if test -z "$user_redefine_cc" && test "$cross_compiling" != yes ; then
+
+dnl We need to guess the C preprocessor instead of using AC_PROG_CPP,
+dnl since AC_PROG_CPP implies AC_PROG_CC, which chooses a compiler
+dnl (before we have the chance to get it from gmp.h) and does some
+dnl checking related to this compiler (such as dependency tracking
+dnl options); if the compiler changes due to __GMP_CC in gmp.h, one
+dnl would have incorrect settings.
+dnl FIXME: Move this in aclocal ?
+if test -z "$GMP_CC$GMP_CFLAGS" ; then
+ AC_MSG_CHECKING(for CC and CFLAGS in gmp.h)
+ GMP_CC=__GMP_CC
+ GMP_CFLAGS=__GMP_CFLAGS
+ for cpp in /lib/cpp gcc cc c99
+ do
+ test $cpp = /lib/cpp || cpp="$cpp -E"
+ echo foo > conftest.c
+ if $cpp $CPPFLAGS conftest.c > /dev/null 2> /dev/null ; then
+ # Get CC
+ echo "#include \"gmp.h\"" > conftest.c
+ echo "MPFR_OPTION __GMP_CC" >> conftest.c
+ GMP_CC=`$cpp $CPPFLAGS conftest.c 2> /dev/null | $EGREP MPFR_OPTION | $SED -e 's/MPFR_OPTION //g;s/ *" *//g'`
+ # Get CFLAGS
+ echo "#include \"gmp.h\"" > conftest.c
+ echo "MPFR_OPTION __GMP_CFLAGS" >> conftest.c
+ unset rmpedantic
+ [test "$enable_logging" = yes && rmpedantic='s/[ "]-pedantic[ "]/ /g;']
+ GMP_CFLAGS=`$cpp $CPPFLAGS conftest.c 2> /dev/null | $EGREP MPFR_OPTION | $SED -e "$rmpedantic"'s/MPFR_OPTION //g;s/ *" *//g'`
+ break
+ fi
+ done
+ rm -f conftest*
+ if test "x$GMP_CC" = "x__GMP_CC" || test "x$GMP_CFLAGS" = "x__GMP_CFLAGS" ; then
+ AC_MSG_RESULT(no)
+ GMP_CFLAGS=
+ GMP_CC=
+ else
+ AC_MSG_RESULT(yes [CC=$GMP_CC CFLAGS=$GMP_CFLAGS])
+ fi
+fi
+
+dnl But these variables may be invalid, so we must check them first.
+dnl Note: we do not use AC_RUN_IFELSE, as it implies AC_PROG_CC.
+if test -n "$GMP_CC$GMP_CFLAGS" ; then
+ AC_MSG_CHECKING(for CC=$GMP_CC and CFLAGS=$GMP_CFLAGS)
+ echo "int main (void) { return 0; }" > conftest.c
+ if $GMP_CC $GMP_CFLAGS -o conftest conftest.c 2> /dev/null ; then
+ AC_MSG_RESULT(yes)
+ CFLAGS=$GMP_CFLAGS
+ CC=$GMP_CC
+ else
+ AC_MSG_RESULT(no)
+ fi
+ rm -f conftest*
+fi
+
+fi
+
+dnl ********************************************************************
+
+AC_PROG_CC
+AC_PROG_CPP
+AC_LANG(C)
+
+AC_ARG_ENABLE(decimal-float,
+ [ --enable-decimal-float build conversion functions from/to decimal floats
+ [[default=no]]],
+ [ case $enableval in
+ yes) AC_DEFINE([MPFR_WANT_DECIMAL_FLOATS],1,
+ [Build decimal float functions])
+ AC_MSG_CHECKING(if compiler knows _Decimal64)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[_Decimal64 x;]])],
+ [AC_MSG_RESULT(yes)
+ if test "$use_gmp_build" != yes ; then
+ AC_MSG_ERROR([decimal float support requires --with-gmp-build])
+ fi
+ AC_MSG_CHECKING(if _GMP_IEEE_FLOATS is defined)
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#include "gmp.h"
+#include "gmp-impl.h"
+#ifndef _GMP_IEEE_FLOATS
+#error "_GMP_IEEE_FLOATS is not defined"
+#endif]])],[AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)
+ AC_MSG_ERROR([decimal float support requires _GMP_IEEE_FLOATS])])
+ ],
+ [AC_MSG_ERROR([Compiler doesn't know _Decimal64; try GCC >= 4.2, configured with --enable-decimal-float]
+ )])
+ AC_MSG_CHECKING(decimal float format)
+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <stdlib.h>
+]], [[
+union { double d; _Decimal64 d64; } y;
+y.d64 = 1234567890123456.0dd;
+return y.d == 0.14894469406741037E-123 ? 0 :
+ y.d == 0.59075095508629822E-68 ? 1 : 2;
+]])], [AC_MSG_RESULT(DPD)
+ AC_DEFINE([DPD_FORMAT],1,[])],
+ [if test "$?" != 1 ; then
+ AC_MSG_FAILURE(neither DPD nor BID)
+ fi
+ AC_MSG_RESULT(BID)],
+ [AC_MSG_RESULT(assuming DPD)
+ AC_DEFINE([DPD_FORMAT],1,[])])
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR([bad value for --enable-decimal-float: yes or no]) ;;
+ esac])
+
+dnl Check if compiler is ICC, and if such a case, disable GCC
+dnl And add some specific flags.
+dnl Don't add Warnings Flags (Otherwise you'll get more than 20000 warnings).
+dnl Add -long_double flags? Don't use -pc64 !
+dnl Notes (VL):
+dnl * With icc 10.1 20080212 on itanium, the __ICC macro is not defined,
+dnl even when the -icc option is used (contrary to what is documented
+dnl on the icc man page).
+dnl * When ICC is correctly detected (__ICC macro defined), unsetting
+dnl the GCC variable confuses libtool. See:
+dnl http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=485421
+dnl * If need be, the gcc predefined macros __GNUC_* can be disabled
+dnl thanks to the -no-gcc option.
+AC_MSG_CHECKING(for ICC)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if !defined(__ICC)
+# error "ICC Not Found"
+error
+#endif
+]], [[]])],[
+ AC_MSG_RESULT(yes)
+ CFLAGS="-fp_port -mp -wd1572 -wd265 -wd186 -wd239 $CFLAGS"
+],[AC_MSG_RESULT(no)])
+
+dnl If compiler is gcc, then use some specific flags.
+dnl But don't touch user other flags.
+if test "$test_CFLAGS" != set && test -n "$GCC"; then
+ CFLAGS="-Wall -Wmissing-prototypes -Wpointer-arith $CFLAGS"
+fi
+
+AM_PROG_CC_C_O
+
+case $host in
+ *-apple-darwin*)
+dnl This allows to take the first GMP library in the library paths,
+dnl whether it is dynamic or static. This behavior is more sensible,
+dnl in particular because it is the only way to link with a version
+dnl only available in static form when another version is available
+dnl in dynamic, and also for consistency, because the compiler will
+dnl take the first gmp.h found in the include paths (so, we need to
+dnl take a library that corresponds to this header file). This is a
+dnl common problem with darwin.
+ MPFR_LD_SEARCH_PATHS_FIRST ;;
+esac
+
+AC_C_CONST
+AC_C_VOLATILE
+MPFR_CONFIGS
+
+# (Based on GMP 5.1)
+# clock_gettime is in librt on *-*-osf5.1 and on glibc < 2.17, so add -lrt to
+# TUNE_LIBS if needed (e.g. if clock_gettime is not already in the C library).
+# On linux (tested on x86_32, 2.6.26), clock_getres reports ns accuracy,
+# while in a quick test on osf, clock_getres said only 1 millisecond.
+old_LIBS="$LIBS"
+AC_SEARCH_LIBS(clock_gettime, rt, [
+ AC_DEFINE([HAVE_CLOCK_GETTIME],1,[Define to 1 if you have the `clock_gettime' function])])
+TUNE_LIBS="$LIBS"
+LIBS="$old_LIBS"
+AC_SUBST(TUNE_LIBS)
+
+dnl
+dnl Setup GMP detection
+dnl
+
+dnl Check GMP Header
+AC_MSG_CHECKING(for gmp.h)
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#include "gmp.h"
+]])],[AC_MSG_RESULT(yes)],[
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([gmp.h can't be found, or is unusable.])
+])
+
+dnl Configs for Windows DLLs.
+dnl libtool requires "-no-undefined" for win32 dll
+dnl It also disables the tests involving the linking with LIBGMP if DLL
+dnl
+dnl "-Wl,output-def" is used to get a .def file for use by MS lib to make
+dnl a .lib import library, described in the manual.
+dnl
+dnl Incidentally, libtool does generate an import library libmpfr.dll.a,
+dnl but it's "ar" format and cannot be used by the MS linker. There
+dnl doesn't seem to be any GNU tool for generating or converting to .lib.
+AC_SUBST(MPFR_LDFLAGS)
+AC_SUBST(LIBMPFR_LDFLAGS)
+AC_LIBTOOL_WIN32_DLL
+case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ AC_MSG_CHECKING(for DLL/static GMP)
+ if test "$enable_shared" = yes; then
+ MPFR_LDFLAGS="$MPFR_LDFLAGS -no-undefined"
+ LIBMPFR_LDFLAGS="$LIBMPFR_LDFLAGS -Wl,--output-def,.libs/libmpfr-4.dll.def"
+ dont_link_with_gmp="yes"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include "gmp.h"
+#if !__GMP_LIBGMP_DLL
+# error "Dead man"
+error
+#endif
+ ]], [[]])],[AC_MSG_RESULT(DLL)],[
+ AC_MSG_RESULT(static)
+ AC_MSG_ERROR([gmp.h isn't a DLL: use --enable-static --disable-shared]) ])
+ else
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include "gmp.h"
+#if __GMP_LIBGMP_DLL
+# error "Dead man"
+error
+#endif
+ ]], [[]])],[AC_MSG_RESULT(static)],[
+ AC_MSG_RESULT(DLL)
+ AC_MSG_ERROR([gmp.h is a DLL: use --disable-static --enable-shared]) ])
+ fi
+ ;;
+esac
+dnl Finally set up LibTool
+AC_PROG_LIBTOOL
+
+
+dnl
+dnl For mpfr-longlong.h - TODO: should be replaced (see acinclude.m4).
+dnl
+
+GMP_C_ATTRIBUTE_MODE
+
+
+dnl
+dnl Setup GMP detection (continued)
+dnl
+
+dnl Check minimal GMP version
+dnl We only guarantee that with a *functional* and recent enough GMP version,
+dnl MPFR will compile; we do not guarantee that GMP will compile.
+dnl In particular fat builds are broken in GMP 4.3.2 and GMP 5.0.0
+dnl (at least on 64-bit Core 2 under Linux),
+dnl see http://gmplib.org/list-archives/gmp-bugs/2011-August/002345.html.
+AC_MSG_CHECKING(for recent GMP)
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#include "gmp.h"
+#if (__GNU_MP_VERSION*100+__GNU_MP_VERSION_MINOR*10 < 410)
+# error "min GMP version is 4.1.0"
+error
+#endif
+]])],[AC_MSG_RESULT(yes)],[
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([GMP 4.1.0 min required])
+])
+
+dnl Check if we can use internal header files of GMP (only --with-gmp-build)
+if test "$use_gmp_build" = yes ; then
+ AC_MSG_CHECKING(for gmp internal files)
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+ #include "gmp.h"
+ #include "gmp-impl.h"
+ #include "longlong.h"
+ ]])],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE([MPFR_HAVE_GMP_IMPL],1,[Use GMP Internal Files])
+ ],[
+ AC_MSG_ERROR([header files gmp-impl.h and longlong.h not found])
+ ])
+fi
+
+dnl Check for valid GMP_NUMB_BITS and BYTES_PER_MP_LIMB
+dnl This test doesn't need to link with libgmp (at least it shouldn't).
+if test "$use_gmp_build" = yes ; then
+ AC_MSG_CHECKING(for valid GMP_NUMB_BITS)
+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <limits.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+]], [[
+ return GMP_NUMB_BITS == BYTES_PER_MP_LIMB * CHAR_BIT
+ && sizeof(mp_limb_t) == BYTES_PER_MP_LIMB ? 0 : 1;
+]])], [AC_MSG_RESULT(yes)], [
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([GMP_NUMB_BITS is incorrect.
+You probably need to change some of the GMP or MPFR compile options.])],
+ [AC_MSG_RESULT([can't test])])
+fi
+
+
+dnl We really need to link using libtool. But it is impossible with the current
+dnl libtool.
+dnl The practical problems appear only under MS Windows since the library name
+dnl is libgmp-3 (due to libtool versionning). The best solution
+dnl is to believe it works under MS-Windows.
+if test "$dont_link_with_gmp" = yes ; then
+LIBS="-lgmp $LIBS"
+else
+
+dnl Check if we can link with GMP
+AC_CHECK_LIB(gmp, __gmpz_init, [LIBS="-lgmp $LIBS"],
+ [AC_MSG_ERROR(libgmp not found or uses a different ABI (including static vs shared).
+Please read the INSTALL file -- see "In case of problem".)])
+
+dnl Check for corresponding 'gmp.h' and libgmp.a
+AC_MSG_CHECKING(if gmp.h version and libgmp version are the same)
+dnl We do not set LD_LIBRARY_PATH, as it is not possible to set it just
+dnl before the test program is run, and we do not want to affect other
+dnl programs (such as the compiler), because the behavior could be
+dnl incorrect and even have security implications.
+saved_LD_RUN_PATH="$LD_RUN_PATH"
+LD_RUN_PATH="${LD_RUN_PATH:+$LD_RUN_PATH$PATH_SEPARATOR}$gmp_lib_path"
+export LD_RUN_PATH
+AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <string.h>
+#include "gmp.h"
+]], [[
+ char buffer[100];
+ sprintf (buffer, "%d.%d.%d", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR,
+ __GNU_MP_VERSION_PATCHLEVEL);
+ printf ("(%s/%s) ", buffer, gmp_version);
+ if (strcmp (buffer, gmp_version) == 0)
+ return 0;
+ if (__GNU_MP_VERSION_PATCHLEVEL != 0)
+ return 1;
+ sprintf (buffer, "%d.%d", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR);
+ return (strcmp (buffer, gmp_version) != 0) ? 1 : 0;
+]])],
+ [AC_MSG_RESULT(yes)
+ MPFR_CHECK_PRINTF_SPEC],
+ [AC_MSG_RESULT(no)
+ AC_MSG_WARN([==========================================================])
+ AC_MSG_WARN(['gmp.h' and 'libgmp' seem to have different versions or])
+ AC_MSG_WARN([we cannot run a program linked with GMP (if you cannot])
+ AC_MSG_WARN([see the version numbers above). A cause may be different])
+ AC_MSG_WARN([GMP versions with different ABI's or the use of --with-gmp])
+ AC_MSG_WARN([or --with-gmp-include with a system include directory])
+ AC_MSG_WARN([(such as /usr/include or /usr/local/include).])
+ AC_MSG_WARN([However since we can't use 'libtool' inside the configure,])
+ AC_MSG_WARN([we can't be sure. See 'config.log' for details.])
+ AC_MSG_WARN([==========================================================])
+ ],AC_MSG_RESULT([can not test])
+)
+LD_RUN_PATH="$saved_LD_RUN_PATH"
+
+dnl Warning! __gmpn_rootrem is an internal GMP symbol; thus its behavior
+dnl may change or this symbol may be removed in the future (without being
+dnl handled by the library versioning system, which is even worse, as this
+dnl can mean undetected incompatibilities in case of GMP library upgrade,
+dnl without rebuilding MPFR). So, this symbol must not be used, unless
+dnl WANT_GMP_INTERNALS is defined. Only the GMP public API should be used
+dnl by default, in particular by binary distributions. Moreover the check
+dnl below may yield an incorrect result as libtool isn't used in configure
+dnl (see above).
+dnl Same for __gmpn_sbpi1_divappr_q.
+AC_CHECK_FUNCS([__gmpn_rootrem __gmpn_sbpi1_divappr_q])
+
+dnl End of tests which need to link with GMP.
+fi
+
+dnl Remove also many MACROS (AC_DEFINE) which are unused by MPFR
+dnl and polluate (and slow down because libtool has to parse them) the build.
+if test -f confdefs.h; then
+ $SED '/#define PACKAGE_/d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_STRING/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_ALLOCA /d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_DLFCN_H/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_MEM/d' <confdefs.h >confdefs.tmp
+ $SED '/#define STDC_HEADERS/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_STRTOL/d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_STDLIB_H/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_UNISTD_H/d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_STDC_HEADERS/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_LONG_DOUBLE/d' <confdefs.h >confdefs.tmp
+ $SED '/#define HAVE_SYS_STAT_H/d' <confdefs.tmp >confdefs.h
+ $SED '/#define HAVE_SYS_TYPES_H/d' <confdefs.h >confdefs.tmp
+ $SED '/#define PROTOTYPES/d' <confdefs.tmp >confdefs.h
+ $SED '/#define __PROTOTYPES/d' <confdefs.h >confdefs.tmp
+
+ mv confdefs.tmp confdefs.h
+fi
+
+if $EGREP -q -e '-dev$' $srcdir/VERSION; then
+ AC_SUBST([DATAFILES])dnl
+ DATAFILES=`echo \`$SED -n \
+ 's/^ *data_check *("\(data\/[[^"]]*\)".*/tests\/\1/p' \
+ $srcdir/tests/*.c\``
+fi
+
+dnl Output
+AC_CONFIG_FILES([Makefile doc/Makefile src/Makefile tests/Makefile tune/Makefile src/mparam.h:src/mparam_h.in])
+AC_OUTPUT
+
+dnl NEWS README AUTHORS Changelog
diff --git a/mpfr/depcomp b/mpfr/depcomp
new file mode 100755
index 0000000000..25a39e6cd5
--- /dev/null
+++ b/mpfr/depcomp
@@ -0,0 +1,708 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2012-03-27.16; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
+# 2011, 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' "$nl" < "$tmpdepfile" |
+## Some versions of gcc put a space before the ':'. On the theory
+## that the space means something, we add a space to the output as
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like '#:fec' to the end of the
+ # dependency line.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts '$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # '$object: dependent.h' and one to simply 'dependent.h:'.
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
+ # However on
+ # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using '\':
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+ # tcc 0.9.26 (FIXME still under development at the moment of writing)
+ # will emit a similar output, but also prepend the continuation lines
+ # with horizontal tabulation characters.
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form 'foo.o: dependent.h',
+ # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # '$object: dependent.h' and one to simply 'dependent.h:'.
+ sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
+ < "$tmpdepfile" > "$depfile"
+ sed '
+ s/[ '"$tab"'][ '"$tab"']*/ /g
+ s/^ *//
+ s/ *\\*$//
+ s/^[^:]*: *//
+ /^$/d
+ /:$/d
+ s/$/ :/
+ ' < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mechanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test "$stat" = 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for ':'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' "$nl" < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mpfr/doc/FAQ.html b/mpfr/doc/FAQ.html
new file mode 100644
index 0000000000..447e79775e
--- /dev/null
+++ b/mpfr/doc/FAQ.html
@@ -0,0 +1,389 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!--
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title>Frequently Asked Questions about GNU MPFR</title>
+<style type="text/css">/*<![CDATA[*/
+/* Global stylesheet for visual media */
+
+html, body
+{
+ background: white;
+ color: black;
+}
+
+div.logo { float: right }
+div.logo img { border: 0 }
+
+div.footer img { border: 0 }
+
+dt
+{
+ margin-top: 2ex;
+ margin-bottom: 1ex;
+ font-weight: bolder;
+}
+
+/* For testing: dd { background: #ddddff } */
+
+table { margin: 0.5ex auto }
+
+li { margin-top: 0.5ex; margin-bottom: 0.5ex }
+
+dd + dd
+{
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 0.5ex;
+ padding-bottom: 0;
+}
+
+li > p, dd > p
+{
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 0.5ex;
+ padding-bottom: 0.5ex;
+}
+
+.block-code code, code.block-code,
+.block-code samp, samp.block-code
+{
+ display: block;
+ padding: 0.5ex 0;
+ margin-left: 2em;
+}
+
+.nowrap { white-space: nowrap }
+
+/*
+dl.faq { counter-reset: faq }
+
+dl.faq dt:before
+{
+ counter-increment: faq;
+ content: counter(faq) ". ";
+}
+*/
+
+dl.faq dt { background: #dddddd }
+
+dl.faq dd
+{
+ border-left: 4px solid;
+ border-color: transparent;
+ margin-left: 0em;
+ padding-left: 1.5em;
+}
+
+dl.faq dt:target + dd
+{
+ border-left-color: #aaaaaa;
+}
+
+var.env { font-style: normal }
+/*]]>*/</style>
+</head>
+
+<body>
+
+<h1>Frequently Asked Questions about <cite><acronym>GNU</acronym> <acronym>MPFR</acronym></cite></h1>
+
+<p><strong>Important notice: Problems with a particular version of
+<cite><acronym>MPFR</acronym></cite> are discussed in the corresponding
+bugs page.</strong></p>
+
+<p>The latest version of this <acronym>FAQ</acronym> is available at
+<a href="http://www.mpfr.org/faq.html">http://www.mpfr.org/faq.html</a>.
+Please look at this version if possible.</p>
+
+<ol>
+<li><a href="#mpfr_vs_mpf">What are the differences between
+<cite><acronym>MPF</acronym></cite> from <cite><acronym>GMP</acronym></cite>
+and <cite><acronym>MPFR</acronym></cite>?</a></li>
+<li><a href="#mpf2mpfr">How to convert my program written using
+<cite><acronym>MPF</acronym></cite> to
+<cite><acronym>MPFR</acronym></cite>?</a></li>
+<li><a href="#no_libgmp">At configure time, I get the error: <q>libgmp not found or uses a different ABI.</q></a></li>
+<li><a href="#undef_ref1">I get undefined reference to <code>__gmp_get_memory_functions</code>.</a></li>
+<li><a href="#undef_ref2">When I link my program with
+<cite><acronym>MPFR</acronym></cite>, I get undefined reference
+to <code>__gmpXXXX</code>.</a></li>
+<li><a href="#crash_high_prec">My program crashes with high precisions.</a></li>
+<li><a href="#accuracy">Though I have increased the precision, the results
+are not more accurate.</a></li>
+<li><a href="#detect_mpfr">How can I detect <cite><acronym>MPFR</acronym></cite>
+installation using <cite>autoconf</cite> or <cite>pkg-config</cite>?</a></li>
+<li><a href="#cite">How to cite <cite><acronym>MPFR</acronym></cite> in a
+scientific publication?</a></li>
+<li><a href="#fpic">When I build <cite><acronym>MPFR</acronym></cite>, I get
+an error asking me to recompile with <samp>-fPIC</samp>.</a></li>
+</ol>
+
+<dl class="faq">
+
+<dt id="mpfr_vs_mpf">1. What are the differences between
+<cite><acronym>MPF</acronym></cite> from <cite><acronym>GMP</acronym></cite>
+and <cite><acronym>MPFR</acronym></cite>?</dt>
+
+<dd><p>The main differences are:</p>
+<ul>
+<li><p>The precision of a <cite><acronym>MPFR</acronym></cite> variable
+is the <em>exact</em> number of bits used for its mantissa, whereas in
+<cite><acronym>MPF</acronym></cite>, the precision requested by the user
+is a minimum value (<cite><acronym>MPF</acronym></cite> generally uses a
+higher precision). With the additional difference below, this implies that
+the <cite><acronym>MPFR</acronym></cite> results do not depend on the
+number of bits (16, 32, 64 or more) of the underlying architecture.</p></li>
+<li><p>As a consequence, <cite><acronym>MPFR</acronym></cite> uses a
+base-2 exponent, whereas in <cite><acronym>MPF</acronym></cite>, this
+is a base-2<sup>32</sup> or base-2<sup>64</sup> exponent, depending on
+the limb size. For this reason (and other internal ones), the maximum
+exponent range in <cite><acronym>MPFR</acronym></cite> is different
+(and smaller, if the exponent is represented by the same type as in
+<cite><acronym>MPF</acronym></cite>).</p></li>
+<li><p><cite><acronym>MPFR</acronym></cite> provides an additional rounding
+mode argument to its functions; furthermore, it is guaranteed that the
+result of any operation is the nearest possible floating-point value from
+the exact result (considering the input variables as exact values), taking
+into account the precision of the destination variable and the rounding
+mode. <cite><acronym>MPFR</acronym></cite> also says whether the rounded
+result is above or below the exact result.</p></li>
+<li><p><cite><acronym>MPFR</acronym></cite> supports much more functions
+(in particular transcendental functions such as exponentials, logarithms,
+trigonometric functions and so on) and special values: signed zeros,
+infinities, not-a-number (NaN).</p></li>
+</ul></dd>
+
+<dt id="mpf2mpfr">2. How to convert my program written using
+<cite><acronym>MPF</acronym></cite> to
+<cite><acronym>MPFR</acronym></cite>?</dt>
+
+<dd><p>You need to add <q><code>r</code></q> to the function names, and to
+specify the rounding mode (<code>MPFR_RNDN</code> for rounding to nearest,
+<code>MPFR_RNDZ</code> for rounding toward zero, <code>MPFR_RNDU</code>
+for rounding toward plus infinity, <code>MPFR_RNDD</code> for rounding
+toward minus infinity). You can also define macros as follows:
+<code class="block-code">#define mpf_add(a, b, c) mpfr_add(a, b, c, MPFR_RNDN)</code></p>
+<p>The header file <samp>mpf2mpfr.h</samp> from the
+<cite><acronym>MPFR</acronym></cite> distribution automatically
+redefines all <cite><acronym>MPF</acronym></cite> functions in this
+way, using the default <cite><acronym>MPFR</acronym></cite> rounding
+mode. Thus you simply need to add the following line in all your files
+using <cite><acronym>MPF</acronym></cite> functions:
+<code class="block-code">#include &lt;mpf2mpfr.h&gt;</code>
+just after the <samp>gmp.h</samp> and <samp>mpfr.h</samp>
+header files. If the program uses <cite><acronym>MPF</acronym></cite>
+internals (such as direct access to <code>__mpf_struct</code> members),
+additional changes will be needed.</p></dd>
+
+<dt id="no_libgmp">3. At configure time, I get the error: <q>libgmp not found or uses a different ABI.</q></dt>
+
+<dd><p>This test (<samp>checking for __gmpz_init in -lgmp</samp>) comes
+after the <samp>gmp.h</samp> detection. The failure occurs either because
+the <cite><acronym>GMP</acronym></cite> library could not be found
+(as it is not in the provided library search paths) or because the
+<cite><acronym>GMP</acronym></cite> library that was found does not have
+the expected <acronym title="Application Binary Interface">ABI</acronym>
+(<abbr>e.g.</abbr> 32-bit <abbr>vs</abbr> 64-bit). The former problem can be
+due to the fact that a static build of <cite><acronym>MPFR</acronym></cite>
+was requested while only a shared <cite><acronym>GMP</acronym></cite> library
+is installed (or the opposite, but another error can also show up in this
+case, see the <a href="#fpic">question about <samp>-fPIC</samp></a>). The
+latter problem can have several causes:</p>
+<ul>
+<li>A wrong libgmp library has been picked up. This can occur if you have
+several <cite><acronym>GMP</acronym></cite> versions installed on the
+machine and something is wrong with the provided library search paths.</li>
+<li>Wrong compiler options (<samp>CFLAGS</samp>) were given. In general, the
+presence or absence of the <samp>-m64</samp> compiler option must match the
+library <acronym title="Application Binary Interface">ABI</acronym>.</li>
+<li>A wrong <samp>gmp.h</samp> file has been picked up (if you have several
+<cite><acronym>GMP</acronym></cite> versions installed). Indeed, by default,
+<cite><acronym>MPFR</acronym></cite> gets the compiler options from the
+<samp>gmp.h</samp> file (with <cite><acronym>GMP</acronym></cite> 4.2.3
+or later); this is needed because <cite><acronym>GMP</acronym></cite> does
+not necessarily use the default <acronym>ABI</acronym>. The consequence is
+that if the <samp>gmp.h</samp> file is associated with a library using a
+different <acronym>ABI</acronym>, the <acronym>ABI</acronym>-related options
+will be incorrect. Hence the failure.</li>
+</ul>
+<p>Note: The <samp>config.log</samp> output gives more information
+than the error message. In particular, see the output of the test:
+<samp>checking for CC and CFLAGS in gmp.h</samp>; it should give you
+the default compiler options (from <samp>gmp.h</samp>).</p>
+
+<p>See also the answer to the <a href="#undef_ref1">next question</a>.</p></dd>
+
+<dt id="undef_ref1">4. I get undefined reference to <code>__gmp_get_memory_functions</code>.</dt>
+
+<dd><p>Note: this was mainly a problem when upgrading from
+<cite><acronym>GMP</acronym></cite> 4.1.4 to a later version,
+but information given below may still be useful in other cases,
+when several <cite><acronym>GMP</acronym></cite> libraries are
+installed on the same machine.</p>
+
+<p>If you get such an error, in particular when running
+<samp>make check</samp>, then this probably means that you are using
+the header file from <cite><acronym>GMP</acronym></cite> 4.2.x but the
+<cite><acronym>GMP</acronym></cite> 4.1.4 library. This can happen if
+several <cite><acronym>GMP</acronym></cite> versions are installed on
+your machine (<abbr>e.g.</abbr>, one provided by the system in
+<samp>/usr/{include,lib}</samp> and a new one installed by the owner or
+administrator of the machine in <samp>/usr/local/{include,lib}</samp>)
+and your include and library search paths are inconsistent. On various
+<acronym>GNU</acronym>/Linux machines, this is unfortunately the case
+by default (<samp>/usr/local/include</samp> is in the default include
+search path, but <samp>/usr/local/lib</samp> is <em>not</em> in the
+default library search path). Typical errors are:
+<samp class="block-code">undefined reference to `__gmp_get_memory_functions'</samp>
+in <samp>make check</samp>. The best solution is to add
+<samp>/usr/local/include</samp> to your <var class="env">C_INCLUDE_PATH</var>
+environment variable and to add <samp>/usr/local/lib</samp> to your
+<var class="env">LIBRARY_PATH</var> and <var class="env">LD_LIBRARY_PATH</var>
+environment variables (and/or <var class="env">LD_RUN_PATH</var>).
+Alternatively, you can use <samp>--with-gmp*</samp> configure options,
+<abbr>e.g.</abbr> <samp>--with-gmp=/usr/local</samp>, but <strong>this is
+not guaranteed to work</strong> (in particular with <samp>gcc</samp> and
+system directories such as <samp>/usr</samp> or <samp>/usr/local</samp>),
+and other software that uses <cite><acronym>GMP</acronym></cite> and/or
+<cite><acronym>MPFR</acronym></cite> will need correct paths too;
+environment variables allow you to set them in a global way.</p>
+<p>Other information can be given in the <samp>INSTALL</samp> file and
+<samp>ld</samp> manual. Please look at them for more details. See also
+the <a href="#undef_ref2">next question</a>.</p></dd>
+
+<dt id="undef_ref2">5. When I link my program with
+<cite><acronym>MPFR</acronym></cite>, I get undefined reference
+to <code>__gmpXXXX</code>.</dt>
+
+<dd><p>Link your program with <cite><acronym>GMP</acronym></cite>. Assuming
+that your program is <samp>foo.c</samp>, you should link it using:
+<samp class="block-code">cc link.c -lmpfr -lgmp</samp>
+<cite><acronym>MPFR</acronym></cite> library reference (<samp>-lmpfr</samp>)
+should be before <cite><acronym>GMP</acronym></cite>'s one
+(<samp>-lgmp</samp>). Another solution is, with <acronym>GNU</acronym>
+<samp>ld</samp>, to give all the libraries inside a group:
+<samp class="block-code">gcc link.c -Wl,--start-group libgmp.a libmpfr.a -Wl,--end-group</samp>
+See <samp>INSTALL</samp> file and <samp>ld</samp> manual for more
+details.</p>
+<p>If you used correct link options, but still get an error, this may mean
+that your include and library search paths are inconsistent. Please see the
+<a href="#undef_ref1">previous question</a>.</p></dd>
+
+<dt id="crash_high_prec">6. My program crashes with high precisions.</dt>
+
+<dd><p>Your stack size limit may be too small; indeed, by default,
+<cite><acronym>GMP</acronym></cite> 4.1.4 and below allocates all
+temporary results on the stack, and in very high precisions, this
+limit may be reached. You can solve this problem in different ways:</p>
+<ul>
+<li><p>You can upgrade to <cite><acronym>GMP</acronym></cite> 4.2 (or above),
+which now makes temporary allocations on the stack only when they are
+small.</p></li>
+<li><p>You can increase the stack size limit with the <samp>limit</samp>,
+<samp>unlimit</samp> or <samp>ulimit</samp> command, depending on your
+shell. This may fail on some systems, where the maximum stack size cannot
+be increased above some value.</p></li>
+<li><p>You can rebuild both <cite><acronym>GMP</acronym></cite> and
+<cite><acronym>MPFR</acronym></cite> to use another allocation method.</p></li>
+</ul></dd>
+
+<dt id="accuracy">7. Though I have increased the precision, the results
+are not more accurate.</dt>
+
+<dd><p>The reason may be the use of C floating-point numbers. If you want
+to store a floating-point constant to a <code>mpfr_t</code>, you should use
+<code>mpfr_set_str</code> (or one of the <cite><acronym>MPFR</acronym></cite>
+constant functions, such as <code>mpfr_const_pi</code> for &#960;) instead
+of <code>mpfr_set_d</code> or <code>mpfr_set_ld</code>. Otherwise the
+floating-point constant will be first converted into a reduced-precision
+(<abbr>e.g.</abbr>, 53-bit) binary number before
+<cite><acronym>MPFR</acronym></cite> can work with it. This is the case
+in particular for most exact decimal numbers, such as 0.17, which are
+not exactly representable in binary.</p>
+<p>Also remember that <cite><acronym>MPFR</acronym></cite> does not track
+the accuracy of the results: copying a value <var>x</var> to <var>y</var>
+with <code>mpfr_set (y, x, MPFR_RNDN)</code> where the variable <var>y</var>
+is more precise than the variable <var>x</var> will not make it more
+accurate; the (binary) value will remain unchanged.</p></dd>
+
+<dt id="detect_mpfr">8. How can I detect <cite><acronym>MPFR</acronym></cite>
+installation using <cite>autoconf</cite> or <cite>pkg-config</cite>?</dt>
+
+<dd><p>The <cite><acronym>MPFR</acronym></cite> team does not currently
+recommend any <cite>autoconf</cite> code, but a section will later
+be added to the <cite><acronym>MPFR</acronym></cite> manual. The
+<cite><acronym>MPFR</acronym></cite> team does not wish to support
+<cite>pkg-config</cite> yet.</p></dd>
+
+<dt id="cite">9. How to cite <cite><acronym>MPFR</acronym></cite> in a
+scientific publication?</dt>
+
+<dd><p>To properly cite <cite><acronym>MPFR</acronym></cite> in a scientific
+publication, please cite the
+<a href="http://doi.acm.org/10.1145/1236463.1236468"><acronym title="Association for Computing Machinery">ACM</acronym>
+<acronym title="Transactions on Mathematical Software">TOMS</acronym>
+paper</a>
+(<a href="http://toms.acm.org/cgi/TOMSbibget.cgi?Fousse:2007:MMP">BibTeX</a>)
+and/or the library web page
+<a href="http://www.mpfr.org/">http://www.mpfr.org</a>. If your publication
+is related to a particular release of <cite><acronym>MPFR</acronym></cite>,
+for example if you report timings, please also indicate the release number
+for future reference.</p></dd>
+
+<dt id="fpic">10. When I build <cite><acronym>MPFR</acronym></cite>, I get
+an error asking me to recompile with <samp>-fPIC</samp>.</dt>
+
+<dd><p>A typical error looks like:</p>
+<p><tt>/usr/bin/ld: <em>/path/to/</em>libgmp.a(realloc.o): relocation
+R_X86_64_32 against `.rodata.str1.1' can not be used when making a
+shared object; recompile with -fPIC<br />
+<em>/path/to/</em>libgmp.a: could not read symbols: Bad value<br />
+collect2: ld returned 1 exit status</tt></p>
+<p>The probable reason is that you tried to build
+<cite><acronym>MPFR</acronym></cite> with the shared library enabled (this
+is the default), while only a static <cite><acronym>GMP</acronym></cite>
+library could be found. To solve this problem, either rebuild and reinstall
+<cite><acronym>GMP</acronym></cite> without the <samp>--disable-shared</samp>
+configure option, or configure <cite><acronym>MPFR</acronym></cite> with
+<samp>--disable-shared</samp>. If you did this and still get the above
+error, the cause may be conflicting <cite><acronym>GMP</acronym></cite>
+versions installed on your system; please check that your search path
+settings are correct.</p>
+<p>Additional note about the last sentence: Under <acronym>GNU</acronym>/Linux
+(for instance), the linker takes the first library found in the library search
+path, whether it is dynamic or static. The default behavior under darwin is
+different, but <cite><acronym>MPFR</acronym></cite> will change it.</p></dd>
+<!-- Reference concerning darwin: see MPFR_LD_SEARCH_PATHS_FIRST
+ in MPFR's configure.{ac,in} and acinclude.m4 -->
+
+</dl>
+
+</body>
+
+</html>
diff --git a/mpfr/doc/Makefile.am b/mpfr/doc/Makefile.am
new file mode 100644
index 0000000000..57af60e2a0
--- /dev/null
+++ b/mpfr/doc/Makefile.am
@@ -0,0 +1,18 @@
+# Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+
+
+dist_doc_DATA = FAQ.html
+
+info_TEXINFOS = mpfr.texi
+
+mpfr_TEXINFOS = fdl.texi
+
+MAKEINFOFLAGS = --enable-encoding
diff --git a/mpfr/doc/Makefile.in b/mpfr/doc/Makefile.in
new file mode 100644
index 0000000000..d0910601d7
--- /dev/null
+++ b/mpfr/doc/Makefile.in
@@ -0,0 +1,716 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = doc
+DIST_COMMON = $(dist_doc_DATA) $(mpfr_TEXINFOS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in texinfo.tex
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+INFO_DEPS = $(srcdir)/mpfr.info
+am__TEXINFO_TEX_DIR = $(srcdir)
+DVIS = mpfr.dvi
+PDFS = mpfr.pdf
+PSS = mpfr.ps
+HTMLS = mpfr.html
+TEXINFOS = mpfr.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(docdir)"
+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; }; \
+ }
+DATA = $(dist_doc_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATAFILES = @DATAFILES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBMPFR_LDFLAGS = @LIBMPFR_LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPFR_LDFLAGS = @MPFR_LDFLAGS@
+MPFR_LIBM = @MPFR_LIBM@
+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@
+STRIP = @STRIP@
+TUNE_LIBS = @TUNE_LIBS@
+VERSION = @VERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+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@
+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@
+dist_doc_DATA = FAQ.html
+info_TEXINFOS = mpfr.texi
+mpfr_TEXINFOS = fdl.texi
+MAKEINFOFLAGS = --enable-encoding
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .html .info .pdf .ps .texi
+$(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 doc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu doc/Makefile
+.PRECIOUS: 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):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+.texi.info:
+ restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ am__cwd=`pwd` && $(am__cd) $(srcdir) && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+ done; \
+ else :; fi && \
+ cd "$$am__cwd"; \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<; \
+ then \
+ rc=0; \
+ $(am__cd) $(srcdir); \
+ else \
+ rc=$$?; \
+ $(am__cd) $(srcdir) && \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) $<
+
+.texi.pdf:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) $<
+
+.texi.html:
+ rm -rf $(@:.html=.htp)
+ if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ else \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+ exit 1; \
+ fi
+$(srcdir)/mpfr.info: mpfr.texi $(mpfr_TEXINFOS)
+mpfr.dvi: mpfr.texi $(mpfr_TEXINFOS)
+mpfr.pdf: mpfr.texi $(mpfr_TEXINFOS)
+mpfr.html: mpfr.texi $(mpfr_TEXINFOS)
+.dvi.ps:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) -o $@ $<
+
+uninstall-dvi-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
+ rm -f "$(DESTDIR)$(dvidir)/$$f"; \
+ done
+
+uninstall-html-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-info-am:
+ @$(PRE_UNINSTALL)
+ @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
+ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+uninstall-pdf-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
+
+uninstall-ps-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(psdir)/$$f"; \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+ if test -f $$file; then \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f "$(distdir)/$$relfile" || \
+ cp -p $$file "$(distdir)/$$relfile"; \
+ else :; fi; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf mpfr.aux mpfr.cp mpfr.cps mpfr.fn mpfr.fns mpfr.ky mpfr.kys \
+ mpfr.log mpfr.pg mpfr.pgs mpfr.tmp mpfr.toc mpfr.tp mpfr.vr \
+ mpfr.vrs
+
+clean-aminfo:
+ -test -z "mpfr.dvi mpfr.pdf mpfr.ps mpfr.html" \
+ || rm -rf mpfr.dvi mpfr.pdf mpfr.ps mpfr.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+install-dist_docDATA: $(dist_doc_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \
+ done
+
+uninstall-dist_docDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir)
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+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
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-info
+check-am: all-am
+check: check-am
+all-am: Makefile $(INFO_DEPS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(docdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+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:
+
+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-aminfo clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-dist_docDATA install-info-am
+
+install-dvi: install-dvi-am
+
+install-dvi-am: $(DVIS)
+ @$(NORMAL_INSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
+ done
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am: $(HTMLS)
+ @$(NORMAL_INSTALL)
+ @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__strip_dir) \
+ d2=$$d$$p; \
+ if test -d "$$d2"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+ echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+ else \
+ list2="$$list2 $$d2"; \
+ fi; \
+ done; \
+ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
+ done; }
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \
+ fi; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ echo "$$ifile"; \
+ else : ; fi; \
+ done; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
+ @$(POST_INSTALL)
+ @if $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am: $(PDFS)
+ @$(NORMAL_INSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
+install-ps: install-ps-am
+
+install-ps-am: $(PSS)
+ @$(NORMAL_INSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+ maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-dist_docDATA uninstall-dvi-am \
+ uninstall-html-am uninstall-info-am uninstall-pdf-am \
+ uninstall-ps-am
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-aminfo clean-generic \
+ clean-libtool dist-info distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am \
+ install-dist_docDATA 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-aminfo maintainer-clean-generic mostlyclean \
+ mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool pdf \
+ pdf-am ps ps-am uninstall uninstall-am uninstall-dist_docDATA \
+ uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+
+# 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/mpfr/doc/fdl.texi b/mpfr/doc/fdl.texi
new file mode 100644
index 0000000000..694e23e919
--- /dev/null
+++ b/mpfr/doc/fdl.texi
@@ -0,0 +1,454 @@
+@c MPFR tweak: Have this in mpfr.texi to help texinfo-mode
+@c @node GNU Free Documentation License
+@c @appendixsec GNU Free Documentation License
+
+@cindex GNU Free Documentation License
+@center Version 1.2, November 2002
+
+@display
+Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+@sc{ascii} without markup, Texinfo input format, La@TeX{} input
+format, @acronym{SGML} or @acronym{XML} using a publicly available
+@acronym{DTD}, and standard-conforming simple @acronym{HTML},
+PostScript or @acronym{PDF} designed for human modification. Examples
+of transparent image formats include @acronym{PNG}, @acronym{XCF} and
+@acronym{JPG}. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, @acronym{SGML} or
+@acronym{XML} for which the @acronym{DTD} and/or processing tools are
+not generally available, and the machine-generated @acronym{HTML},
+PostScript or @acronym{PDF} produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+@end enumerate
+
+@page
+@c MPFR tweak: Use @appendixsec
+@c @appendixsubsec ADDENDUM: How to use this License for your documents
+@appendixsec ADDENDUM: How to Use This License For Your Documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with...Texts.'' line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
+
diff --git a/mpfr/doc/mpfr.info b/mpfr/doc/mpfr.info
new file mode 100644
index 0000000000..ef69621641
--- /dev/null
+++ b/mpfr/doc/mpfr.info
@@ -0,0 +1,4266 @@
+This is mpfr.info, produced by makeinfo version 4.13 from mpfr.texi.
+
+This manual documents how to install and use the Multiple Precision
+Floating-Point Reliable Library, version 3.1.2.
+
+ Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
+2013 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation License, Version
+1.2 or any later version published by the Free Software Foundation;
+with no Invariant Sections, with no Front-Cover Texts, and with no
+Back-Cover Texts. A copy of the license is included in *note GNU Free
+Documentation License::.
+
+INFO-DIR-SECTION Software libraries
+START-INFO-DIR-ENTRY
+* mpfr: (mpfr). Multiple Precision Floating-Point Reliable Library.
+END-INFO-DIR-ENTRY
+
+
+File: mpfr.info, Node: Top, Next: Copying, Prev: (dir), Up: (dir)
+
+GNU MPFR
+********
+
+ This manual documents how to install and use the Multiple Precision
+Floating-Point Reliable Library, version 3.1.2.
+
+ Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
+2013 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation License, Version
+1.2 or any later version published by the Free Software Foundation;
+with no Invariant Sections, with no Front-Cover Texts, and with no
+Back-Cover Texts. A copy of the license is included in *note GNU Free
+Documentation License::.
+
+
+* Menu:
+
+* Copying:: MPFR Copying Conditions (LGPL).
+* Introduction to MPFR:: Brief introduction to GNU MPFR.
+* Installing MPFR:: How to configure and compile the MPFR library.
+* Reporting Bugs:: How to usefully report bugs.
+* MPFR Basics:: What every MPFR user should now.
+* MPFR Interface:: MPFR functions and macros.
+* API Compatibility:: API compatibility with previous MPFR versions.
+* Contributors::
+* References::
+* GNU Free Documentation License::
+* Concept Index::
+* Function and Type Index::
+
+
+File: mpfr.info, Node: Copying, Next: Introduction to MPFR, Prev: Top, Up: Top
+
+MPFR Copying Conditions
+***********************
+
+The GNU MPFR library (or MPFR for short) is "free"; this means that
+everyone is free to use it and free to redistribute it on a free basis.
+The library is not in the public domain; it is copyrighted and there
+are restrictions on its distribution, but these restrictions are
+designed to permit everything that a good cooperating citizen would
+want to do. What is not allowed is to try to prevent others from
+further sharing any version of this library that they might get from
+you.
+
+ Specifically, we want to make sure that you have the right to give
+away copies of the library, that you receive source code or else can
+get it if you want it, that you can change this library or use pieces
+of it in new free programs, and that you know you can do these things.
+
+ To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights. For example, if you distribute
+copies of the GNU MPFR library, you must give the recipients all the
+rights that you have. You must make sure that they, too, receive or
+can get the source code. And you must tell them their rights.
+
+ Also, for our own protection, we must make certain that everyone
+finds out that there is no warranty for the GNU MPFR library. If it is
+modified by someone else and passed on, we want their recipients to
+know that what they have is not what we distributed, so that any
+problems introduced by others will not reflect on our reputation.
+
+ The precise conditions of the license for the GNU MPFR library are
+found in the Lesser General Public License that accompanies the source
+code. See the file COPYING.LESSER.
+
+
+File: mpfr.info, Node: Introduction to MPFR, Next: Installing MPFR, Prev: Copying, Up: Top
+
+1 Introduction to MPFR
+**********************
+
+MPFR is a portable library written in C for arbitrary precision
+arithmetic on floating-point numbers. It is based on the GNU MP library.
+It aims to provide a class of floating-point numbers with precise
+semantics. The main characteristics of MPFR, which make it differ from
+most arbitrary precision floating-point software tools, are:
+
+ * the MPFR code is portable, i.e., the result of any operation does
+ not depend on the machine word size `mp_bits_per_limb' (64 on most
+ current processors);
+
+ * the precision in bits can be set _exactly_ to any valid value for
+ each variable (including very small precision);
+
+ * MPFR provides the four rounding modes from the IEEE 754-1985
+ standard, plus away-from-zero, as well as for basic operations as
+ for other mathematical functions.
+
+ In particular, with a precision of 53 bits, MPFR is able to exactly
+reproduce all computations with double-precision machine floating-point
+numbers (e.g., `double' type in C, with a C implementation that
+rigorously follows Annex F of the ISO C99 standard and `FP_CONTRACT'
+pragma set to `OFF') on the four arithmetic operations and the square
+root, except the default exponent range is much wider and subnormal
+numbers are not implemented (but can be emulated).
+
+ This version of MPFR is released under the GNU Lesser General Public
+License, version 3 or any later version. It is permitted to link MPFR
+to most non-free programs, as long as when distributing them the MPFR
+source code and a means to re-link with a modified MPFR library is
+provided.
+
+1.1 How to Use This Manual
+==========================
+
+Everyone should read *note MPFR Basics::. If you need to install the
+library yourself, you need to read *note Installing MPFR::, too. To
+use the library you will need to refer to *note MPFR Interface::.
+
+ The rest of the manual can be used for later reference, although it
+is probably a good idea to glance through it.
+
+
+File: mpfr.info, Node: Installing MPFR, Next: Reporting Bugs, Prev: Introduction to MPFR, Up: Top
+
+2 Installing MPFR
+*****************
+
+The MPFR library is already installed on some GNU/Linux distributions,
+but the development files necessary to the compilation such as `mpfr.h'
+are not always present. To check that MPFR is fully installed on your
+computer, you can check the presence of the file `mpfr.h' in
+`/usr/include', or try to compile a small program having `#include
+<mpfr.h>' (since `mpfr.h' may be installed somewhere else). For
+instance, you can try to compile:
+
+ #include <stdio.h>
+ #include <mpfr.h>
+ int main (void)
+ {
+ printf ("MPFR library: %-12s\nMPFR header: %s (based on %d.%d.%d)\n",
+ mpfr_get_version (), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR,
+ MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL);
+ return 0;
+ }
+
+with
+
+ cc -o version version.c -lmpfr -lgmp
+
+and if you get errors whose first line looks like
+
+ version.c:2:19: error: mpfr.h: No such file or directory
+
+then MPFR is probably not installed. Running this program will give you
+the MPFR version.
+
+ If MPFR is not installed on your computer, or if you want to install
+a different version, please follow the steps below.
+
+2.1 How to Install
+==================
+
+Here are the steps needed to install the library on Unix systems (more
+details are provided in the `INSTALL' file):
+
+ 1. To build MPFR, you first have to install GNU MP (version 4.1 or
+ higher) on your computer. You need a C compiler, preferably GCC,
+ but any reasonable compiler should work. And you need the
+ standard Unix `make' command, plus some other standard Unix
+ utility commands.
+
+ Then, in the MPFR build directory, type the following commands.
+
+ 2. `./configure'
+
+ This will prepare the build and setup the options according to
+ your system. You can give options to specify the install
+ directories (instead of the default `/usr/local'), threading
+ support, and so on. See the `INSTALL' file and/or the output of
+ `./configure --help' for more information, in particular if you
+ get error messages.
+
+ 3. `make'
+
+ This will compile MPFR, and create a library archive file
+ `libmpfr.a'. On most platforms, a dynamic library will be
+ produced too.
+
+ 4. `make check'
+
+ This will make sure MPFR was built correctly. If you get error
+ messages, please report this to the MPFR mailing-list
+ `mpfr@inria.fr'. (*Note Reporting Bugs::, for information on what
+ to include in useful bug reports.)
+
+ 5. `make install'
+
+ This will copy the files `mpfr.h' and `mpf2mpfr.h' to the directory
+ `/usr/local/include', the library files (`libmpfr.a' and possibly
+ others) to the directory `/usr/local/lib', the file `mpfr.info' to
+ the directory `/usr/local/share/info', and some other documentation
+ files to the directory `/usr/local/share/doc/mpfr' (or if you
+ passed the `--prefix' option to `configure', using the prefix
+ directory given as argument to `--prefix' instead of `/usr/local').
+
+2.2 Other `make' Targets
+========================
+
+There are some other useful make targets:
+
+ * `mpfr.info' or `info'
+
+ Create or update an info version of the manual, in `mpfr.info'.
+
+ This file is already provided in the MPFR archives.
+
+ * `mpfr.pdf' or `pdf'
+
+ Create a PDF version of the manual, in `mpfr.pdf'.
+
+ * `mpfr.dvi' or `dvi'
+
+ Create a DVI version of the manual, in `mpfr.dvi'.
+
+ * `mpfr.ps' or `ps'
+
+ Create a Postscript version of the manual, in `mpfr.ps'.
+
+ * `mpfr.html' or `html'
+
+ Create a HTML version of the manual, in several pages in the
+ directory `doc/mpfr.html'; if you want only one output HTML file,
+ then type `makeinfo --html --no-split mpfr.texi' from the `doc'
+ directory instead.
+
+ * `clean'
+
+ Delete all object files and archive files, but not the
+ configuration files.
+
+ * `distclean'
+
+ Delete all generated files not included in the distribution.
+
+ * `uninstall'
+
+ Delete all files copied by `make install'.
+
+2.3 Build Problems
+==================
+
+In case of problem, please read the `INSTALL' file carefully before
+reporting a bug, in particular section "In case of problem". Some
+problems are due to bad configuration on the user side (not specific to
+MPFR). Problems are also mentioned in the FAQ
+`http://www.mpfr.org/faq.html'.
+
+ Please report problems to the MPFR mailing-list `mpfr@inria.fr'.
+*Note Reporting Bugs::. Some bug fixes are available on the MPFR 3.1.2
+web page `http://www.mpfr.org/mpfr-3.1.2/'.
+
+2.4 Getting the Latest Version of MPFR
+======================================
+
+The latest version of MPFR is available from
+`ftp://ftp.gnu.org/gnu/mpfr/' or `http://www.mpfr.org/'.
+
+
+File: mpfr.info, Node: Reporting Bugs, Next: MPFR Basics, Prev: Installing MPFR, Up: Top
+
+3 Reporting Bugs
+****************
+
+If you think you have found a bug in the MPFR library, first have a look
+on the MPFR 3.1.2 web page `http://www.mpfr.org/mpfr-3.1.2/' and the
+FAQ `http://www.mpfr.org/faq.html': perhaps this bug is already known,
+in which case you may find there a workaround for it. You might also
+look in the archives of the MPFR mailing-list:
+`https://sympa.inria.fr/sympa/arc/mpfr'. Otherwise, please investigate
+and report it. We have made this library available to you, and it is
+not to ask too much from you, to ask you to report the bugs that you
+find.
+
+ There are a few things you should think about when you put your bug
+report together.
+
+ You have to send us a test case that makes it possible for us to
+reproduce the bug, i.e., a small self-content program, using no other
+library than MPFR. Include instructions on how to run the test case.
+
+ You also have to explain what is wrong; if you get a crash, or if
+the results you get are incorrect and in that case, in what way.
+
+ Please include compiler version information in your bug report. This
+can be extracted using `cc -V' on some machines, or, if you're using
+GCC, `gcc -v'. Also, include the output from `uname -a' and the MPFR
+version (the GMP version may be useful too). If you get a failure
+while running `make' or `make check', please include the `config.log'
+file in your bug report.
+
+ If your bug report is good, we will do our best to help you to get a
+corrected version of the library; if the bug report is poor, we will
+not do anything about it (aside of chiding you to send better bug
+reports).
+
+ Send your bug report to the MPFR mailing-list `mpfr@inria.fr'.
+
+ If you think something in this manual is unclear, or downright
+incorrect, or if the language needs to be improved, please send a note
+to the same address.
+
+
+File: mpfr.info, Node: MPFR Basics, Next: MPFR Interface, Prev: Reporting Bugs, Up: Top
+
+4 MPFR Basics
+*************
+
+* Menu:
+
+* Headers and Libraries::
+* Nomenclature and Types::
+* MPFR Variable Conventions::
+* Rounding Modes::
+* Floating-Point Values on Special Numbers::
+* Exceptions::
+* Memory Handling::
+
+
+File: mpfr.info, Node: Headers and Libraries, Next: Nomenclature and Types, Prev: MPFR Basics, Up: MPFR Basics
+
+4.1 Headers and Libraries
+=========================
+
+All declarations needed to use MPFR are collected in the include file
+`mpfr.h'. It is designed to work with both C and C++ compilers. You
+should include that file in any program using the MPFR library:
+
+ #include <mpfr.h>
+
+ Note however that prototypes for MPFR functions with `FILE *'
+parameters are provided only if `<stdio.h>' is included too (before
+`mpfr.h'):
+
+ #include <stdio.h>
+ #include <mpfr.h>
+
+ Likewise `<stdarg.h>' (or `<varargs.h>') is required for prototypes
+with `va_list' parameters, such as `mpfr_vprintf'.
+
+ And for any functions using `intmax_t', you must include
+`<stdint.h>' or `<inttypes.h>' before `mpfr.h', to allow `mpfr.h' to
+define prototypes for these functions. Moreover, users of C++ compilers
+under some platforms may need to define `MPFR_USE_INTMAX_T' (and should
+do it for portability) before `mpfr.h' has been included; of course, it
+is possible to do that on the command line, e.g., with
+`-DMPFR_USE_INTMAX_T'.
+
+ Note: If `mpfr.h' and/or `gmp.h' (used by `mpfr.h') are included
+several times (possibly from another header file), `<stdio.h>' and/or
+`<stdarg.h>' (or `<varargs.h>') should be included *before the first
+inclusion* of `mpfr.h' or `gmp.h'. Alternatively, you can define
+`MPFR_USE_FILE' (for MPFR I/O functions) and/or `MPFR_USE_VA_LIST' (for
+MPFR functions with `va_list' parameters) anywhere before the last
+inclusion of `mpfr.h'. As a consequence, if your file is a public
+header that includes `mpfr.h', you need to use the latter method.
+
+ When calling a MPFR macro, it is not allowed to have previously
+defined a macro with the same name as some keywords (currently `do',
+`while' and `sizeof').
+
+ You can avoid the use of MPFR macros encapsulating functions by
+defining the `MPFR_USE_NO_MACRO' macro before `mpfr.h' is included. In
+general this should not be necessary, but this can be useful when
+debugging user code: with some macros, the compiler may emit spurious
+warnings with some warning options, and macros can prevent some
+prototype checking.
+
+ All programs using MPFR must link against both `libmpfr' and
+`libgmp' libraries. On a typical Unix-like system this can be done
+with `-lmpfr -lgmp' (in that order), for example:
+
+ gcc myprogram.c -lmpfr -lgmp
+
+ MPFR is built using Libtool and an application can use that to link
+if desired, *note GNU Libtool: (libtool.info)Top.
+
+ If MPFR has been installed to a non-standard location, then it may be
+necessary to set up environment variables such as `C_INCLUDE_PATH' and
+`LIBRARY_PATH', or use `-I' and `-L' compiler options, in order to
+point to the right directories. For a shared library, it may also be
+necessary to set up some sort of run-time library path (e.g.,
+`LD_LIBRARY_PATH') on some systems. Please read the `INSTALL' file for
+additional information.
+
+
+File: mpfr.info, Node: Nomenclature and Types, Next: MPFR Variable Conventions, Prev: Headers and Libraries, Up: MPFR Basics
+
+4.2 Nomenclature and Types
+==========================
+
+A "floating-point number", or "float" for short, is an arbitrary
+precision significand (also called mantissa) with a limited precision
+exponent. The C data type for such objects is `mpfr_t' (internally
+defined as a one-element array of a structure, and `mpfr_ptr' is the C
+data type representing a pointer to this structure). A floating-point
+number can have three special values: Not-a-Number (NaN) or plus or
+minus Infinity. NaN represents an uninitialized object, the result of
+an invalid operation (like 0 divided by 0), or a value that cannot be
+determined (like +Infinity minus +Infinity). Moreover, like in the IEEE
+754 standard, zero is signed, i.e., there are both +0 and -0; the
+behavior is the same as in the IEEE 754 standard and it is generalized
+to the other functions supported by MPFR. Unless documented otherwise,
+the sign bit of a NaN is unspecified.
+
+The "precision" is the number of bits used to represent the significand
+of a floating-point number; the corresponding C data type is
+`mpfr_prec_t'. The precision can be any integer between
+`MPFR_PREC_MIN' and `MPFR_PREC_MAX'. In the current implementation,
+`MPFR_PREC_MIN' is equal to 2.
+
+ Warning! MPFR needs to increase the precision internally, in order to
+provide accurate results (and in particular, correct rounding). Do not
+attempt to set the precision to any value near `MPFR_PREC_MAX',
+otherwise MPFR will abort due to an assertion failure. Moreover, you
+may reach some memory limit on your platform, in which case the program
+may abort, crash or have undefined behavior (depending on your C
+implementation).
+
+The "rounding mode" specifies the way to round the result of a
+floating-point operation, in case the exact result can not be
+represented exactly in the destination significand; the corresponding C
+data type is `mpfr_rnd_t'.
+
+
+File: mpfr.info, Node: MPFR Variable Conventions, Next: Rounding Modes, Prev: Nomenclature and Types, Up: MPFR Basics
+
+4.3 MPFR Variable Conventions
+=============================
+
+Before you can assign to an MPFR variable, you need to initialize it by
+calling one of the special initialization functions. When you're done
+with a variable, you need to clear it out, using one of the functions
+for that purpose. A variable should only be initialized once, or at
+least cleared out between each initialization. After a variable has
+been initialized, it may be assigned to any number of times. For
+efficiency reasons, avoid to initialize and clear out a variable in
+loops. Instead, initialize it before entering the loop, and clear it
+out after the loop has exited. You do not need to be concerned about
+allocating additional space for MPFR variables, since any variable has
+a significand of fixed size. Hence unless you change its precision, or
+clear and reinitialize it, a floating-point variable will have the same
+allocated space during all its life.
+
+ As a general rule, all MPFR functions expect output arguments before
+input arguments. This notation is based on an analogy with the
+assignment operator. MPFR allows you to use the same variable for both
+input and output in the same expression. For example, the main
+function for floating-point multiplication, `mpfr_mul', can be used
+like this: `mpfr_mul (x, x, x, rnd)'. This computes the square of X
+with rounding mode `rnd' and puts the result back in X.
+
+
+File: mpfr.info, Node: Rounding Modes, Next: Floating-Point Values on Special Numbers, Prev: MPFR Variable Conventions, Up: MPFR Basics
+
+4.4 Rounding Modes
+==================
+
+The following five rounding modes are supported:
+
+ * `MPFR_RNDN': round to nearest (roundTiesToEven in IEEE 754-2008),
+
+ * `MPFR_RNDZ': round toward zero (roundTowardZero in IEEE 754-2008),
+
+ * `MPFR_RNDU': round toward plus infinity (roundTowardPositive in
+ IEEE 754-2008),
+
+ * `MPFR_RNDD': round toward minus infinity (roundTowardNegative in
+ IEEE 754-2008),
+
+ * `MPFR_RNDA': round away from zero.
+
+ The `round to nearest' mode works as in the IEEE 754 standard: in
+case the number to be rounded lies exactly in the middle of two
+representable numbers, it is rounded to the one with the least
+significant bit set to zero. For example, the number 2.5, which is
+represented by (10.1) in binary, is rounded to (10.0)=2 with a
+precision of two bits, and not to (11.0)=3. This rule avoids the
+"drift" phenomenon mentioned by Knuth in volume 2 of The Art of
+Computer Programming (Section 4.2.2).
+
+ Most MPFR functions take as first argument the destination variable,
+as second and following arguments the input variables, as last argument
+a rounding mode, and have a return value of type `int', called the
+"ternary value". The value stored in the destination variable is
+correctly rounded, i.e., MPFR behaves as if it computed the result with
+an infinite precision, then rounded it to the precision of this
+variable. The input variables are regarded as exact (in particular,
+their precision does not affect the result).
+
+ As a consequence, in case of a non-zero real rounded result, the
+error on the result is less or equal to 1/2 ulp (unit in the last
+place) of that result in the rounding to nearest mode, and less than 1
+ulp of that result in the directed rounding modes (a ulp is the weight
+of the least significant represented bit of the result after rounding).
+
+ Unless documented otherwise, functions returning an `int' return a
+ternary value. If the ternary value is zero, it means that the value
+stored in the destination variable is the exact result of the
+corresponding mathematical function. If the ternary value is positive
+(resp. negative), it means the value stored in the destination variable
+is greater (resp. lower) than the exact result. For example with the
+`MPFR_RNDU' rounding mode, the ternary value is usually positive,
+except when the result is exact, in which case it is zero. In the case
+of an infinite result, it is considered as inexact when it was obtained
+by overflow, and exact otherwise. A NaN result (Not-a-Number) always
+corresponds to an exact return value. The opposite of a returned
+ternary value is guaranteed to be representable in an `int'.
+
+ Unless documented otherwise, functions returning as result the value
+`1' (or any other value specified in this manual) for special cases
+(like `acos(0)') yield an overflow or an underflow if that value is not
+representable in the current exponent range.
+
+
+File: mpfr.info, Node: Floating-Point Values on Special Numbers, Next: Exceptions, Prev: Rounding Modes, Up: MPFR Basics
+
+4.5 Floating-Point Values on Special Numbers
+============================================
+
+This section specifies the floating-point values (of type `mpfr_t')
+returned by MPFR functions (where by "returned" we mean here the
+modified value of the destination object, which should not be mixed
+with the ternary return value of type `int' of those functions). For
+functions returning several values (like `mpfr_sin_cos'), the rules
+apply to each result separately.
+
+ Functions can have one or several input arguments. An input point is
+a mapping from these input arguments to the set of the MPFR numbers.
+When none of its components are NaN, an input point can also be seen as
+a tuple in the extended real numbers (the set of the real numbers with
+both infinities).
+
+ When the input point is in the domain of the mathematical function,
+the result is rounded as described in Section "Rounding Modes" (but see
+below for the specification of the sign of an exact zero). Otherwise
+the general rules from this section apply unless stated otherwise in
+the description of the MPFR function (*note MPFR Interface::).
+
+ When the input point is not in the domain of the mathematical
+function but is in its closure in the extended real numbers and the
+function can be extended by continuity, the result is the obtained
+limit. Examples: `mpfr_hypot' on (+Inf,0) gives +Inf. But `mpfr_pow'
+cannot be defined on (1,+Inf) using this rule, as one can find
+sequences (X_N,Y_N) such that X_N goes to 1, Y_N goes to +Inf and X_N
+to the Y_N goes to any positive value when N goes to the infinity.
+
+ When the input point is in the closure of the domain of the
+mathematical function and an input argument is +0 (resp. -0), one
+considers the limit when the corresponding argument approaches 0 from
+above (resp. below). If the limit is not defined (e.g., `mpfr_log' on
+-0), the behavior is specified in the description of the MPFR function.
+
+ When the result is equal to 0, its sign is determined by considering
+the limit as if the input point were not in the domain: If one
+approaches 0 from above (resp. below), the result is +0 (resp. -0); for
+example, `mpfr_sin' on +0 gives +0. In the other cases, the sign is
+specified in the description of the MPFR function; for example
+`mpfr_max' on -0 and +0 gives +0.
+
+ When the input point is not in the closure of the domain of the
+function, the result is NaN. Example: `mpfr_sqrt' on -17 gives NaN.
+
+ When an input argument is NaN, the result is NaN, possibly except
+when a partial function is constant on the finite floating-point
+numbers; such a case is always explicitly specified in *note MPFR
+Interface::. Example: `mpfr_hypot' on (NaN,0) gives NaN, but
+`mpfr_hypot' on (NaN,+Inf) gives +Inf (as specified in *note Special
+Functions::), since for any finite input X, `mpfr_hypot' on (X,+Inf)
+gives +Inf.
+
+
+File: mpfr.info, Node: Exceptions, Next: Memory Handling, Prev: Floating-Point Values on Special Numbers, Up: MPFR Basics
+
+4.6 Exceptions
+==============
+
+MPFR supports 6 exception types:
+
+ * Underflow: An underflow occurs when the exact result of a function
+ is a non-zero real number and the result obtained after the
+ rounding, assuming an unbounded exponent range (for the rounding),
+ has an exponent smaller than the minimum value of the current
+ exponent range. (In the round-to-nearest mode, the halfway case is
+ rounded toward zero.)
+
+ Note: This is not the single possible definition of the underflow.
+ MPFR chooses to consider the underflow _after_ rounding. The
+ underflow before rounding can also be defined. For instance,
+ consider a function that has the exact result 7 multiplied by two
+ to the power E-4, where E is the smallest exponent (for a
+ significand between 1/2 and 1), with a 2-bit target precision and
+ rounding toward plus infinity. The exact result has the exponent
+ E-1. With the underflow before rounding, such a function call
+ would yield an underflow, as E-1 is outside the current exponent
+ range. However, MPFR first considers the rounded result assuming
+ an unbounded exponent range. The exact result cannot be
+ represented exactly in precision 2, and here, it is rounded to 0.5
+ times 2 to E, which is representable in the current exponent
+ range. As a consequence, this will not yield an underflow in MPFR.
+
+ * Overflow: An overflow occurs when the exact result of a function
+ is a non-zero real number and the result obtained after the
+ rounding, assuming an unbounded exponent range (for the rounding),
+ has an exponent larger than the maximum value of the current
+ exponent range. In the round-to-nearest mode, the result is
+ infinite. Note: unlike the underflow case, there is only one
+ possible definition of overflow here.
+
+ * Divide-by-zero: An exact infinite result is obtained from finite
+ inputs.
+
+ * NaN: A NaN exception occurs when the result of a function is NaN.
+
+ * Inexact: An inexact exception occurs when the result of a function
+ cannot be represented exactly and must be rounded.
+
+ * Range error: A range exception occurs when a function that does
+ not return a MPFR number (such as comparisons and conversions to
+ an integer) has an invalid result (e.g., an argument is NaN in
+ `mpfr_cmp', or a conversion to an integer cannot be represented in
+ the target type).
+
+
+ MPFR has a global flag for each exception, which can be cleared, set
+or tested by functions described in *note Exception Related Functions::.
+
+ Differences with the ISO C99 standard:
+
+ * In C, only quiet NaNs are specified, and a NaN propagation does not
+ raise an invalid exception. Unless explicitly stated otherwise,
+ MPFR sets the NaN flag whenever a NaN is generated, even when a
+ NaN is propagated (e.g., in NaN + NaN), as if all NaNs were
+ signaling.
+
+ * An invalid exception in C corresponds to either a NaN exception or
+ a range error in MPFR.
+
+
+
+File: mpfr.info, Node: Memory Handling, Prev: Exceptions, Up: MPFR Basics
+
+4.7 Memory Handling
+===================
+
+MPFR functions may create caches, e.g., when computing constants such
+as Pi, either because the user has called a function like
+`mpfr_const_pi' directly or because such a function was called
+internally by the MPFR library itself to compute some other function.
+
+ At any time, the user can free the various caches with
+`mpfr_free_cache'. It is strongly advised to do that before terminating
+a thread, or before exiting when using tools like `valgrind' (to avoid
+memory leaks being reported).
+
+ MPFR internal data such as flags, the exponent range, the default
+precision and rounding mode, and caches (i.e., data that are not
+accessed via parameters) are either global (if MPFR has not been
+compiled as thread safe) or per-thread (thread local storage, TLS).
+The initial values of TLS data after a thread is created entirely
+depend on the compiler and thread implementation (MPFR simply does a
+conventional variable initialization, the variables being declared with
+an implementation-defined TLS specifier).
+
+
+File: mpfr.info, Node: MPFR Interface, Next: API Compatibility, Prev: MPFR Basics, Up: Top
+
+5 MPFR Interface
+****************
+
+The floating-point functions expect arguments of type `mpfr_t'.
+
+ The MPFR floating-point functions have an interface that is similar
+to the GNU MP functions. The function prefix for floating-point
+operations is `mpfr_'.
+
+ The user has to specify the precision of each variable. A
+computation that assigns a variable will take place with the precision
+of the assigned variable; the cost of that computation should not
+depend on the precision of variables used as input (on average).
+
+ The semantics of a calculation in MPFR is specified as follows:
+Compute the requested operation exactly (with "infinite accuracy"), and
+round the result to the precision of the destination variable, with the
+given rounding mode. The MPFR floating-point functions are intended to
+be a smooth extension of the IEEE 754 arithmetic. The results obtained
+on a given computer are identical to those obtained on a computer with
+a different word size, or with a different compiler or operating system.
+
+ MPFR _does not keep track_ of the accuracy of a computation. This is
+left to the user or to a higher layer (for example the MPFI library for
+interval arithmetic). As a consequence, if two variables are used to
+store only a few significant bits, and their product is stored in a
+variable with large precision, then MPFR will still compute the result
+with full precision.
+
+ The value of the standard C macro `errno' may be set to non-zero by
+any MPFR function or macro, whether or not there is an error.
+
+* Menu:
+
+* Initialization Functions::
+* Assignment Functions::
+* Combined Initialization and Assignment Functions::
+* Conversion Functions::
+* Basic Arithmetic Functions::
+* Comparison Functions::
+* Special Functions::
+* Input and Output Functions::
+* Formatted Output Functions::
+* Integer Related Functions::
+* Rounding Related Functions::
+* Miscellaneous Functions::
+* Exception Related Functions::
+* Compatibility with MPF::
+* Custom Interface::
+* Internals::
+
+
+File: mpfr.info, Node: Initialization Functions, Next: Assignment Functions, Prev: MPFR Interface, Up: MPFR Interface
+
+5.1 Initialization Functions
+============================
+
+An `mpfr_t' object must be initialized before storing the first value in
+it. The functions `mpfr_init' and `mpfr_init2' are used for that
+purpose.
+
+ -- Function: void mpfr_init2 (mpfr_t X, mpfr_prec_t PREC)
+ Initialize X, set its precision to be *exactly* PREC bits and its
+ value to NaN. (Warning: the corresponding MPF function initializes
+ to zero instead.)
+
+ Normally, a variable should be initialized once only or at least
+ be cleared, using `mpfr_clear', between initializations. To
+ change the precision of a variable which has already been
+ initialized, use `mpfr_set_prec'. The precision PREC must be an
+ integer between `MPFR_PREC_MIN' and `MPFR_PREC_MAX' (otherwise the
+ behavior is undefined).
+
+ -- Function: void mpfr_inits2 (mpfr_prec_t PREC, mpfr_t X, ...)
+ Initialize all the `mpfr_t' variables of the given variable
+ argument `va_list', set their precision to be *exactly* PREC bits
+ and their value to NaN. See `mpfr_init2' for more details. The
+ `va_list' is assumed to be composed only of type `mpfr_t' (or
+ equivalently `mpfr_ptr'). It begins from X, and ends when it
+ encounters a null pointer (whose type must also be `mpfr_ptr').
+
+ -- Function: void mpfr_clear (mpfr_t X)
+ Free the space occupied by the significand of X. Make sure to
+ call this function for all `mpfr_t' variables when you are done
+ with them.
+
+ -- Function: void mpfr_clears (mpfr_t X, ...)
+ Free the space occupied by all the `mpfr_t' variables of the given
+ `va_list'. See `mpfr_clear' for more details. The `va_list' is
+ assumed to be composed only of type `mpfr_t' (or equivalently
+ `mpfr_ptr'). It begins from X, and ends when it encounters a null
+ pointer (whose type must also be `mpfr_ptr').
+
+ Here is an example of how to use multiple initialization functions
+(since `NULL' is not necessarily defined in this context, we use
+`(mpfr_ptr) 0' instead, but `(mpfr_ptr) NULL' is also correct).
+
+ {
+ mpfr_t x, y, z, t;
+ mpfr_inits2 (256, x, y, z, t, (mpfr_ptr) 0);
+ ...
+ mpfr_clears (x, y, z, t, (mpfr_ptr) 0);
+ }
+
+ -- Function: void mpfr_init (mpfr_t X)
+ Initialize X, set its precision to the default precision, and set
+ its value to NaN. The default precision can be changed by a call
+ to `mpfr_set_default_prec'.
+
+ Warning! In a given program, some other libraries might change the
+ default precision and not restore it. Thus it is safer to use
+ `mpfr_init2'.
+
+ -- Function: void mpfr_inits (mpfr_t X, ...)
+ Initialize all the `mpfr_t' variables of the given `va_list', set
+ their precision to the default precision and their value to NaN.
+ See `mpfr_init' for more details. The `va_list' is assumed to be
+ composed only of type `mpfr_t' (or equivalently `mpfr_ptr'). It
+ begins from X, and ends when it encounters a null pointer (whose
+ type must also be `mpfr_ptr').
+
+ Warning! In a given program, some other libraries might change the
+ default precision and not restore it. Thus it is safer to use
+ `mpfr_inits2'.
+
+ -- Macro: MPFR_DECL_INIT (NAME, PREC)
+ This macro declares NAME as an automatic variable of type `mpfr_t',
+ initializes it and sets its precision to be *exactly* PREC bits
+ and its value to NaN. NAME must be a valid identifier. You must
+ use this macro in the declaration section. This macro is much
+ faster than using `mpfr_init2' but has some drawbacks:
+
+ * You *must not* call `mpfr_clear' with variables created with
+ this macro (the storage is allocated at the point of
+ declaration and deallocated when the brace-level is exited).
+
+ * You *cannot* change their precision.
+
+ * You *should not* create variables with huge precision with
+ this macro.
+
+ * Your compiler must support `Non-Constant Initializers'
+ (standard in C++ and ISO C99) and `Token Pasting' (standard
+ in ISO C89). If PREC is not a constant expression, your
+ compiler must support `variable-length automatic arrays'
+ (standard in ISO C99). GCC 2.95.3 and above supports all
+ these features. If you compile your program with GCC in C89
+ mode and with `-pedantic', you may want to define the
+ `MPFR_USE_EXTENSION' macro to avoid warnings due to the
+ `MPFR_DECL_INIT' implementation.
+
+ -- Function: void mpfr_set_default_prec (mpfr_prec_t PREC)
+ Set the default precision to be *exactly* PREC bits, where PREC
+ can be any integer between `MPFR_PREC_MIN' and `MPFR_PREC_MAX'.
+ The precision of a variable means the number of bits used to store
+ its significand. All subsequent calls to `mpfr_init' or
+ `mpfr_inits' will use this precision, but previously initialized
+ variables are unaffected. The default precision is set to 53 bits
+ initially.
+
+ Note: when MPFR is built with the `--enable-thread-safe' configure
+ option, the default precision is local to each thread. *Note
+ Memory Handling::, for more information.
+
+ -- Function: mpfr_prec_t mpfr_get_default_prec (void)
+ Return the current default MPFR precision in bits. See the
+ documentation of `mpfr_set_default_prec'.
+
+ Here is an example on how to initialize floating-point variables:
+
+ {
+ mpfr_t x, y;
+ mpfr_init (x); /* use default precision */
+ mpfr_init2 (y, 256); /* precision _exactly_ 256 bits */
+ ...
+ /* When the program is about to exit, do ... */
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_free_cache (); /* free the cache for constants like pi */
+ }
+
+ The following functions are useful for changing the precision during
+a calculation. A typical use would be for adjusting the precision
+gradually in iterative algorithms like Newton-Raphson, making the
+computation precision closely match the actual accurate part of the
+numbers.
+
+ -- Function: void mpfr_set_prec (mpfr_t X, mpfr_prec_t PREC)
+ Reset the precision of X to be *exactly* PREC bits, and set its
+ value to NaN. The previous value stored in X is lost. It is
+ equivalent to a call to `mpfr_clear(x)' followed by a call to
+ `mpfr_init2(x, prec)', but more efficient as no allocation is done
+ in case the current allocated space for the significand of X is
+ enough. The precision PREC can be any integer between
+ `MPFR_PREC_MIN' and `MPFR_PREC_MAX'. In case you want to keep the
+ previous value stored in X, use `mpfr_prec_round' instead.
+
+ -- Function: mpfr_prec_t mpfr_get_prec (mpfr_t X)
+ Return the precision of X, i.e., the number of bits used to store
+ its significand.
+
+
+File: mpfr.info, Node: Assignment Functions, Next: Combined Initialization and Assignment Functions, Prev: Initialization Functions, Up: MPFR Interface
+
+5.2 Assignment Functions
+========================
+
+These functions assign new values to already initialized floats (*note
+Initialization Functions::).
+
+ -- Function: int mpfr_set (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_ui (mpfr_t ROP, unsigned long int OP,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_set_si (mpfr_t ROP, long int OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_uj (mpfr_t ROP, uintmax_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_sj (mpfr_t ROP, intmax_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_flt (mpfr_t ROP, float OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_d (mpfr_t ROP, double OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_ld (mpfr_t ROP, long double OP, mpfr_rnd_t
+ RND)
+ -- Function: int mpfr_set_decimal64 (mpfr_t ROP, _Decimal64 OP,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_set_z (mpfr_t ROP, mpz_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_q (mpfr_t ROP, mpq_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_f (mpfr_t ROP, mpf_t OP, mpfr_rnd_t RND)
+ Set the value of ROP from OP, rounded toward the given direction
+ RND. Note that the input 0 is converted to +0 by `mpfr_set_ui',
+ `mpfr_set_si', `mpfr_set_uj', `mpfr_set_sj', `mpfr_set_z',
+ `mpfr_set_q' and `mpfr_set_f', regardless of the rounding mode.
+ If the system does not support the IEEE 754 standard,
+ `mpfr_set_flt', `mpfr_set_d', `mpfr_set_ld' and
+ `mpfr_set_decimal64' might not preserve the signed zeros. The
+ `mpfr_set_decimal64' function is built only with the configure
+ option `--enable-decimal-float', which also requires
+ `--with-gmp-build', and when the compiler or system provides the
+ `_Decimal64' data type (recent versions of GCC support this data
+ type); to use `mpfr_set_decimal64', one should define the macro
+ `MPFR_WANT_DECIMAL_FLOATS' before including `mpfr.h'.
+ `mpfr_set_q' might fail if the numerator (or the denominator) can
+ not be represented as a `mpfr_t'.
+
+ Note: If you want to store a floating-point constant to a `mpfr_t',
+ you should use `mpfr_set_str' (or one of the MPFR constant
+ functions, such as `mpfr_const_pi' for Pi) instead of
+ `mpfr_set_flt', `mpfr_set_d', `mpfr_set_ld' or
+ `mpfr_set_decimal64'. Otherwise the floating-point constant will
+ be first converted into a reduced-precision (e.g., 53-bit) binary
+ (or decimal, for `mpfr_set_decimal64') number before MPFR can work
+ with it.
+
+ -- Function: int mpfr_set_ui_2exp (mpfr_t ROP, unsigned long int OP,
+ mpfr_exp_t E, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_si_2exp (mpfr_t ROP, long int OP, mpfr_exp_t
+ E, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_uj_2exp (mpfr_t ROP, uintmax_t OP, intmax_t
+ E, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_sj_2exp (mpfr_t ROP, intmax_t OP, intmax_t
+ E, mpfr_rnd_t RND)
+ -- Function: int mpfr_set_z_2exp (mpfr_t ROP, mpz_t OP, mpfr_exp_t E,
+ mpfr_rnd_t RND)
+ Set the value of ROP from OP multiplied by two to the power E,
+ rounded toward the given direction RND. Note that the input 0 is
+ converted to +0.
+
+ -- Function: int mpfr_set_str (mpfr_t ROP, const char *S, int BASE,
+ mpfr_rnd_t RND)
+ Set ROP to the value of the string S in base BASE, rounded in the
+ direction RND. See the documentation of `mpfr_strtofr' for a
+ detailed description of the valid string formats. Contrary to
+ `mpfr_strtofr', `mpfr_set_str' requires the _whole_ string to
+ represent a valid floating-point number.
+
+ The meaning of the return value differs from other MPFR functions:
+ it is 0 if the entire string up to the final null character is a
+ valid number in base BASE; otherwise it is -1, and ROP may have
+ changed (users interested in the *note ternary value:: should use
+ `mpfr_strtofr' instead).
+
+ Note: it is preferable to use `mpfr_set_str' if one wants to
+ distinguish between an infinite ROP value coming from an infinite
+ S or from an overflow.
+
+ -- Function: int mpfr_strtofr (mpfr_t ROP, const char *NPTR, char
+ **ENDPTR, int BASE, mpfr_rnd_t RND)
+ Read a floating-point number from a string NPTR in base BASE,
+ rounded in the direction RND; BASE must be either 0 (to detect the
+ base, as described below) or a number from 2 to 62 (otherwise the
+ behavior is undefined). If NPTR starts with valid data, the result
+ is stored in ROP and `*ENDPTR' points to the character just after
+ the valid data (if ENDPTR is not a null pointer); otherwise ROP is
+ set to zero (for consistency with `strtod') and the value of NPTR
+ is stored in the location referenced by ENDPTR (if ENDPTR is not a
+ null pointer). The usual ternary value is returned.
+
+ Parsing follows the standard C `strtod' function with some
+ extensions. After optional leading whitespace, one has a subject
+ sequence consisting of an optional sign (`+' or `-'), and either
+ numeric data or special data. The subject sequence is defined as
+ the longest initial subsequence of the input string, starting with
+ the first non-whitespace character, that is of the expected form.
+
+ The form of numeric data is a non-empty sequence of significand
+ digits with an optional decimal point, and an optional exponent
+ consisting of an exponent prefix followed by an optional sign and
+ a non-empty sequence of decimal digits. A significand digit is
+ either a decimal digit or a Latin letter (62 possible characters),
+ with `A' = 10, `B' = 11, ..., `Z' = 35; case is ignored in bases
+ less or equal to 36, in bases larger than 36, `a' = 36, `b' = 37,
+ ..., `z' = 61. The value of a significand digit must be strictly
+ less than the base. The decimal point can be either the one
+ defined by the current locale or the period (the first one is
+ accepted for consistency with the C standard and the practice, the
+ second one is accepted to allow the programmer to provide MPFR
+ numbers from strings in a way that does not depend on the current
+ locale). The exponent prefix can be `e' or `E' for bases up to
+ 10, or `@' in any base; it indicates a multiplication by a power
+ of the base. In bases 2 and 16, the exponent prefix can also be
+ `p' or `P', in which case the exponent, called _binary exponent_,
+ indicates a multiplication by a power of 2 instead of the base
+ (there is a difference only for base 16); in base 16 for example
+ `1p2' represents 4 whereas `1@2' represents 256. The value of an
+ exponent is always written in base 10.
+
+ If the argument BASE is 0, then the base is automatically detected
+ as follows. If the significand starts with `0b' or `0B', base 2 is
+ assumed. If the significand starts with `0x' or `0X', base 16 is
+ assumed. Otherwise base 10 is assumed.
+
+ Note: The exponent (if present) must contain at least a digit.
+ Otherwise the possible exponent prefix and sign are not part of
+ the number (which ends with the significand). Similarly, if `0b',
+ `0B', `0x' or `0X' is not followed by a binary/hexadecimal digit,
+ then the subject sequence stops at the character `0', thus 0 is
+ read.
+
+ Special data (for infinities and NaN) can be `@inf@' or
+ `@nan@(n-char-sequence-opt)', and if BASE <= 16, it can also be
+ `infinity', `inf', `nan' or `nan(n-char-sequence-opt)', all case
+ insensitive. A `n-char-sequence-opt' is a possibly empty string
+ containing only digits, Latin letters and the underscore (0, 1, 2,
+ ..., 9, a, b, ..., z, A, B, ..., Z, _). Note: one has an optional
+ sign for all data, even NaN. For example,
+ `-@nAn@(This_Is_Not_17)' is a valid representation for NaN in base
+ 17.
+
+
+ -- Function: void mpfr_set_nan (mpfr_t X)
+ -- Function: void mpfr_set_inf (mpfr_t X, int SIGN)
+ -- Function: void mpfr_set_zero (mpfr_t X, int SIGN)
+ Set the variable X to NaN (Not-a-Number), infinity or zero
+ respectively. In `mpfr_set_inf' or `mpfr_set_zero', X is set to
+ plus infinity or plus zero iff SIGN is nonnegative; in
+ `mpfr_set_nan', the sign bit of the result is unspecified.
+
+ -- Function: void mpfr_swap (mpfr_t X, mpfr_t Y)
+ Swap the values X and Y efficiently. Warning: the precisions are
+ exchanged too; in case the precisions are different, `mpfr_swap'
+ is thus not equivalent to three `mpfr_set' calls using a third
+ auxiliary variable.
+
+
+File: mpfr.info, Node: Combined Initialization and Assignment Functions, Next: Conversion Functions, Prev: Assignment Functions, Up: MPFR Interface
+
+5.3 Combined Initialization and Assignment Functions
+====================================================
+
+ -- Macro: int mpfr_init_set (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Macro: int mpfr_init_set_ui (mpfr_t ROP, unsigned long int OP,
+ mpfr_rnd_t RND)
+ -- Macro: int mpfr_init_set_si (mpfr_t ROP, long int OP, mpfr_rnd_t
+ RND)
+ -- Macro: int mpfr_init_set_d (mpfr_t ROP, double OP, mpfr_rnd_t RND)
+ -- Macro: int mpfr_init_set_ld (mpfr_t ROP, long double OP, mpfr_rnd_t
+ RND)
+ -- Macro: int mpfr_init_set_z (mpfr_t ROP, mpz_t OP, mpfr_rnd_t RND)
+ -- Macro: int mpfr_init_set_q (mpfr_t ROP, mpq_t OP, mpfr_rnd_t RND)
+ -- Macro: int mpfr_init_set_f (mpfr_t ROP, mpf_t OP, mpfr_rnd_t RND)
+ Initialize ROP and set its value from OP, rounded in the direction
+ RND. The precision of ROP will be taken from the active default
+ precision, as set by `mpfr_set_default_prec'.
+
+ -- Function: int mpfr_init_set_str (mpfr_t X, const char *S, int BASE,
+ mpfr_rnd_t RND)
+ Initialize X and set its value from the string S in base BASE,
+ rounded in the direction RND. See `mpfr_set_str'.
+
+
+File: mpfr.info, Node: Conversion Functions, Next: Basic Arithmetic Functions, Prev: Combined Initialization and Assignment Functions, Up: MPFR Interface
+
+5.4 Conversion Functions
+========================
+
+ -- Function: float mpfr_get_flt (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: double mpfr_get_d (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: long double mpfr_get_ld (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: _Decimal64 mpfr_get_decimal64 (mpfr_t OP, mpfr_rnd_t RND)
+ Convert OP to a `float' (respectively `double', `long double' or
+ `_Decimal64'), using the rounding mode RND. If OP is NaN, some
+ fixed NaN (either quiet or signaling) or the result of 0.0/0.0 is
+ returned. If OP is ±Inf, an infinity of the same sign or the
+ result of ±1.0/0.0 is returned. If OP is zero, these functions
+ return a zero, trying to preserve its sign, if possible. The
+ `mpfr_get_decimal64' function is built only under some conditions:
+ see the documentation of `mpfr_set_decimal64'.
+
+ -- Function: long mpfr_get_si (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: unsigned long mpfr_get_ui (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: intmax_t mpfr_get_sj (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: uintmax_t mpfr_get_uj (mpfr_t OP, mpfr_rnd_t RND)
+ Convert OP to a `long', an `unsigned long', an `intmax_t' or an
+ `uintmax_t' (respectively) after rounding it with respect to RND.
+ If OP is NaN, 0 is returned and the _erange_ flag is set. If OP
+ is too big for the return type, the function returns the maximum
+ or the minimum of the corresponding C type, depending on the
+ direction of the overflow; the _erange_ flag is set too. See also
+ `mpfr_fits_slong_p', `mpfr_fits_ulong_p', `mpfr_fits_intmax_p' and
+ `mpfr_fits_uintmax_p'.
+
+ -- Function: double mpfr_get_d_2exp (long *EXP, mpfr_t OP, mpfr_rnd_t
+ RND)
+ -- Function: long double mpfr_get_ld_2exp (long *EXP, mpfr_t OP,
+ mpfr_rnd_t RND)
+ Return D and set EXP (formally, the value pointed to by EXP) such
+ that 0.5<=abs(D)<1 and D times 2 raised to EXP equals OP rounded
+ to double (resp. long double) precision, using the given rounding
+ mode. If OP is zero, then a zero of the same sign (or an unsigned
+ zero, if the implementation does not have signed zeros) is
+ returned, and EXP is set to 0. If OP is NaN or an infinity, then
+ the corresponding double precision (resp. long-double precision)
+ value is returned, and EXP is undefined.
+
+ -- Function: int mpfr_frexp (mpfr_exp_t *EXP, mpfr_t Y, mpfr_t X,
+ mpfr_rnd_t RND)
+ Set EXP (formally, the value pointed to by EXP) and Y such that
+ 0.5<=abs(Y)<1 and Y times 2 raised to EXP equals X rounded to the
+ precision of Y, using the given rounding mode. If X is zero, then
+ Y is set to a zero of the same sign and EXP is set to 0. If X is
+ NaN or an infinity, then Y is set to the same value and EXP is
+ undefined.
+
+ -- Function: mpfr_exp_t mpfr_get_z_2exp (mpz_t ROP, mpfr_t OP)
+ Put the scaled significand of OP (regarded as an integer, with the
+ precision of OP) into ROP, and return the exponent EXP (which may
+ be outside the current exponent range) such that OP exactly equals
+ ROP times 2 raised to the power EXP. If OP is zero, the minimal
+ exponent `emin' is returned. If OP is NaN or an infinity, the
+ _erange_ flag is set, ROP is set to 0, and the the minimal
+ exponent `emin' is returned. The returned exponent may be less
+ than the minimal exponent `emin' of MPFR numbers in the current
+ exponent range; in case the exponent is not representable in the
+ `mpfr_exp_t' type, the _erange_ flag is set and the minimal value
+ of the `mpfr_exp_t' type is returned.
+
+ -- Function: int mpfr_get_z (mpz_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Convert OP to a `mpz_t', after rounding it with respect to RND. If
+ OP is NaN or an infinity, the _erange_ flag is set, ROP is set to
+ 0, and 0 is returned.
+
+ -- Function: int mpfr_get_f (mpf_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Convert OP to a `mpf_t', after rounding it with respect to RND.
+ The _erange_ flag is set if OP is NaN or an infinity, which do not
+ exist in MPF. If OP is NaN, then ROP is undefined. If OP is an
+ +Inf (resp. -Inf), then ROP is set to the maximum (resp. minimum)
+ value in the precision of the MPF number; if a future MPF version
+ supports infinities, this behavior will be considered incorrect
+ and will change (portable programs should assume that ROP is set
+ either to this finite number or to an infinite number). Note that
+ since MPFR currently has the same exponent type as MPF (but not
+ with the same radix), the range of values is much larger in MPF
+ than in MPFR, so that an overflow or underflow is not possible.
+
+ -- Function: char * mpfr_get_str (char *STR, mpfr_exp_t *EXPPTR, int
+ B, size_t N, mpfr_t OP, mpfr_rnd_t RND)
+ Convert OP to a string of digits in base B, with rounding in the
+ direction RND, where N is either zero (see below) or the number of
+ significant digits output in the string; in the latter case, N
+ must be greater or equal to 2. The base may vary from 2 to 62. If
+ the input number is an ordinary number, the exponent is written
+ through the pointer EXPPTR (for input 0, the current minimal
+ exponent is written).
+
+ The generated string is a fraction, with an implicit radix point
+ immediately to the left of the first digit. For example, the
+ number -3.1416 would be returned as "-31416" in the string and 1
+ written at EXPPTR. If RND is to nearest, and OP is exactly in the
+ middle of two consecutive possible outputs, the one with an even
+ significand is chosen, where both significands are considered with
+ the exponent of OP. Note that for an odd base, this may not
+ correspond to an even last digit: for example with 2 digits in
+ base 7, (14) and a half is rounded to (15) which is 12 in decimal,
+ (16) and a half is rounded to (20) which is 14 in decimal, and
+ (26) and a half is rounded to (26) which is 20 in decimal.
+
+ If N is zero, the number of digits of the significand is chosen
+ large enough so that re-reading the printed value with the same
+ precision, assuming both output and input use rounding to nearest,
+ will recover the original value of OP. More precisely, in most
+ cases, the chosen precision of STR is the minimal precision m
+ depending only on P = PREC(OP) and B that satisfies the above
+ property, i.e., m = 1 + ceil(P*log(2)/log(B)), with P replaced by
+ P-1 if B is a power of 2, but in some very rare cases, it might be
+ m+1 (the smallest case for bases up to 62 is when P equals
+ 186564318007 for bases 7 and 49).
+
+ If STR is a null pointer, space for the significand is allocated
+ using the current allocation function, and a pointer to the string
+ is returned. To free the returned string, you must use
+ `mpfr_free_str'.
+
+ If STR is not a null pointer, it should point to a block of storage
+ large enough for the significand, i.e., at least `max(N + 2, 7)'.
+ The extra two bytes are for a possible minus sign, and for the
+ terminating null character, and the value 7 accounts for `-@Inf@'
+ plus the terminating null character.
+
+ A pointer to the string is returned, unless there is an error, in
+ which case a null pointer is returned.
+
+ -- Function: void mpfr_free_str (char *STR)
+ Free a string allocated by `mpfr_get_str' using the current
+ unallocation function. The block is assumed to be `strlen(STR)+1'
+ bytes. For more information about how it is done: *note Custom
+ Allocation: (gmp.info)Custom Allocation.
+
+ -- Function: int mpfr_fits_ulong_p (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_fits_slong_p (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_fits_uint_p (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_fits_sint_p (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_fits_ushort_p (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_fits_sshort_p (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_fits_uintmax_p (mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_fits_intmax_p (mpfr_t OP, mpfr_rnd_t RND)
+ Return non-zero if OP would fit in the respective C data type,
+ respectively `unsigned long', `long', `unsigned int', `int',
+ `unsigned short', `short', `uintmax_t', `intmax_t', when rounded
+ to an integer in the direction RND.
+
+
+File: mpfr.info, Node: Basic Arithmetic Functions, Next: Comparison Functions, Prev: Conversion Functions, Up: MPFR Interface
+
+5.5 Basic Arithmetic Functions
+==============================
+
+ -- Function: int mpfr_add (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_add_ui (mpfr_t ROP, mpfr_t OP1, unsigned long
+ int OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_add_si (mpfr_t ROP, mpfr_t OP1, long int OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_add_d (mpfr_t ROP, mpfr_t OP1, double OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_add_z (mpfr_t ROP, mpfr_t OP1, mpz_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_add_q (mpfr_t ROP, mpfr_t OP1, mpq_t OP2,
+ mpfr_rnd_t RND)
+ Set ROP to OP1 + OP2 rounded in the direction RND. For types
+ having no signed zero, it is considered unsigned (i.e., (+0) + 0 =
+ (+0) and (-0) + 0 = (-0)). The `mpfr_add_d' function assumes that
+ the radix of the `double' type is a power of 2, with a precision
+ at most that declared by the C implementation (macro
+ `IEEE_DBL_MANT_DIG', and if not defined 53 bits).
+
+ -- Function: int mpfr_sub (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_ui_sub (mpfr_t ROP, unsigned long int OP1,
+ mpfr_t OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_sub_ui (mpfr_t ROP, mpfr_t OP1, unsigned long
+ int OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_si_sub (mpfr_t ROP, long int OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_sub_si (mpfr_t ROP, mpfr_t OP1, long int OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_d_sub (mpfr_t ROP, double OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_sub_d (mpfr_t ROP, mpfr_t OP1, double OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_z_sub (mpfr_t ROP, mpz_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_sub_z (mpfr_t ROP, mpfr_t OP1, mpz_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_sub_q (mpfr_t ROP, mpfr_t OP1, mpq_t OP2,
+ mpfr_rnd_t RND)
+ Set ROP to OP1 - OP2 rounded in the direction RND. For types
+ having no signed zero, it is considered unsigned (i.e., (+0) - 0 =
+ (+0), (-0) - 0 = (-0), 0 - (+0) = (-0) and 0 - (-0) = (+0)). The
+ same restrictions than for `mpfr_add_d' apply to `mpfr_d_sub' and
+ `mpfr_sub_d'.
+
+ -- Function: int mpfr_mul (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_mul_ui (mpfr_t ROP, mpfr_t OP1, unsigned long
+ int OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_mul_si (mpfr_t ROP, mpfr_t OP1, long int OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_mul_d (mpfr_t ROP, mpfr_t OP1, double OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_mul_z (mpfr_t ROP, mpfr_t OP1, mpz_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_mul_q (mpfr_t ROP, mpfr_t OP1, mpq_t OP2,
+ mpfr_rnd_t RND)
+ Set ROP to OP1 times OP2 rounded in the direction RND. When a
+ result is zero, its sign is the product of the signs of the
+ operands (for types having no signed zero, it is considered
+ positive). The same restrictions than for `mpfr_add_d' apply to
+ `mpfr_mul_d'.
+
+ -- Function: int mpfr_sqr (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the square of OP rounded in the direction RND.
+
+ -- Function: int mpfr_div (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_ui_div (mpfr_t ROP, unsigned long int OP1,
+ mpfr_t OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_div_ui (mpfr_t ROP, mpfr_t OP1, unsigned long
+ int OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_si_div (mpfr_t ROP, long int OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_div_si (mpfr_t ROP, mpfr_t OP1, long int OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_d_div (mpfr_t ROP, double OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_div_d (mpfr_t ROP, mpfr_t OP1, double OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_div_z (mpfr_t ROP, mpfr_t OP1, mpz_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_div_q (mpfr_t ROP, mpfr_t OP1, mpq_t OP2,
+ mpfr_rnd_t RND)
+ Set ROP to OP1/OP2 rounded in the direction RND. When a result is
+ zero, its sign is the product of the signs of the operands (for
+ types having no signed zero, it is considered positive). The same
+ restrictions than for `mpfr_add_d' apply to `mpfr_d_div' and
+ `mpfr_div_d'.
+
+ -- Function: int mpfr_sqrt (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_sqrt_ui (mpfr_t ROP, unsigned long int OP,
+ mpfr_rnd_t RND)
+ Set ROP to the square root of OP rounded in the direction RND (set
+ ROP to -0 if OP is -0, to be consistent with the IEEE 754
+ standard). Set ROP to NaN if OP is negative.
+
+ -- Function: int mpfr_rec_sqrt (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the reciprocal square root of OP rounded in the
+ direction RND. Set ROP to +Inf if OP is ±0, +0 if OP is +Inf, and
+ NaN if OP is negative.
+
+ -- Function: int mpfr_cbrt (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_root (mpfr_t ROP, mpfr_t OP, unsigned long int
+ K, mpfr_rnd_t RND)
+ Set ROP to the cubic root (resp. the Kth root) of OP rounded in
+ the direction RND. For K odd (resp. even) and OP negative
+ (including -Inf), set ROP to a negative number (resp. NaN). The
+ Kth root of -0 is defined to be -0, whatever the parity of K.
+
+ -- Function: int mpfr_pow (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_pow_ui (mpfr_t ROP, mpfr_t OP1, unsigned long
+ int OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_pow_si (mpfr_t ROP, mpfr_t OP1, long int OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_pow_z (mpfr_t ROP, mpfr_t OP1, mpz_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_ui_pow_ui (mpfr_t ROP, unsigned long int OP1,
+ unsigned long int OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_ui_pow (mpfr_t ROP, unsigned long int OP1,
+ mpfr_t OP2, mpfr_rnd_t RND)
+ Set ROP to OP1 raised to OP2, rounded in the direction RND.
+ Special values are handled as described in the ISO C99 and IEEE
+ 754-2008 standards for the `pow' function:
+ * `pow(±0, Y)' returns plus or minus infinity for Y a negative
+ odd integer.
+
+ * `pow(±0, Y)' returns plus infinity for Y negative and not an
+ odd integer.
+
+ * `pow(±0, Y)' returns plus or minus zero for Y a positive odd
+ integer.
+
+ * `pow(±0, Y)' returns plus zero for Y positive and not an odd
+ integer.
+
+ * `pow(-1, ±Inf)' returns 1.
+
+ * `pow(+1, Y)' returns 1 for any Y, even a NaN.
+
+ * `pow(X, ±0)' returns 1 for any X, even a NaN.
+
+ * `pow(X, Y)' returns NaN for finite negative X and finite
+ non-integer Y.
+
+ * `pow(X, -Inf)' returns plus infinity for 0 < abs(x) < 1, and
+ plus zero for abs(x) > 1.
+
+ * `pow(X, +Inf)' returns plus zero for 0 < abs(x) < 1, and plus
+ infinity for abs(x) > 1.
+
+ * `pow(-Inf, Y)' returns minus zero for Y a negative odd
+ integer.
+
+ * `pow(-Inf, Y)' returns plus zero for Y negative and not an
+ odd integer.
+
+ * `pow(-Inf, Y)' returns minus infinity for Y a positive odd
+ integer.
+
+ * `pow(-Inf, Y)' returns plus infinity for Y positive and not
+ an odd integer.
+
+ * `pow(+Inf, Y)' returns plus zero for Y negative, and plus
+ infinity for Y positive.
+
+ -- Function: int mpfr_neg (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_abs (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to -OP and the absolute value of OP respectively, rounded
+ in the direction RND. Just changes or adjusts the sign if ROP and
+ OP are the same variable, otherwise a rounding might occur if the
+ precision of ROP is less than that of OP.
+
+ -- Function: int mpfr_dim (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ Set ROP to the positive difference of OP1 and OP2, i.e., OP1 - OP2
+ rounded in the direction RND if OP1 > OP2, +0 if OP1 <= OP2, and
+ NaN if OP1 or OP2 is NaN.
+
+ -- Function: int mpfr_mul_2ui (mpfr_t ROP, mpfr_t OP1, unsigned long
+ int OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_mul_2si (mpfr_t ROP, mpfr_t OP1, long int OP2,
+ mpfr_rnd_t RND)
+ Set ROP to OP1 times 2 raised to OP2 rounded in the direction RND.
+ Just increases the exponent by OP2 when ROP and OP1 are identical.
+
+ -- Function: int mpfr_div_2ui (mpfr_t ROP, mpfr_t OP1, unsigned long
+ int OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_div_2si (mpfr_t ROP, mpfr_t OP1, long int OP2,
+ mpfr_rnd_t RND)
+ Set ROP to OP1 divided by 2 raised to OP2 rounded in the direction
+ RND. Just decreases the exponent by OP2 when ROP and OP1 are
+ identical.
+
+
+File: mpfr.info, Node: Comparison Functions, Next: Special Functions, Prev: Basic Arithmetic Functions, Up: MPFR Interface
+
+5.6 Comparison Functions
+========================
+
+ -- Function: int mpfr_cmp (mpfr_t OP1, mpfr_t OP2)
+ -- Function: int mpfr_cmp_ui (mpfr_t OP1, unsigned long int OP2)
+ -- Function: int mpfr_cmp_si (mpfr_t OP1, long int OP2)
+ -- Function: int mpfr_cmp_d (mpfr_t OP1, double OP2)
+ -- Function: int mpfr_cmp_ld (mpfr_t OP1, long double OP2)
+ -- Function: int mpfr_cmp_z (mpfr_t OP1, mpz_t OP2)
+ -- Function: int mpfr_cmp_q (mpfr_t OP1, mpq_t OP2)
+ -- Function: int mpfr_cmp_f (mpfr_t OP1, mpf_t OP2)
+ Compare OP1 and OP2. Return a positive value if OP1 > OP2, zero
+ if OP1 = OP2, and a negative value if OP1 < OP2. Both OP1 and OP2
+ are considered to their full own precision, which may differ. If
+ one of the operands is NaN, set the _erange_ flag and return zero.
+
+ Note: These functions may be useful to distinguish the three
+ possible cases. If you need to distinguish two cases only, it is
+ recommended to use the predicate functions (e.g., `mpfr_equal_p'
+ for the equality) described below; they behave like the IEEE 754
+ comparisons, in particular when one or both arguments are NaN. But
+ only floating-point numbers can be compared (you may need to do a
+ conversion first).
+
+ -- Function: int mpfr_cmp_ui_2exp (mpfr_t OP1, unsigned long int OP2,
+ mpfr_exp_t E)
+ -- Function: int mpfr_cmp_si_2exp (mpfr_t OP1, long int OP2,
+ mpfr_exp_t E)
+ Compare OP1 and OP2 multiplied by two to the power E. Similar as
+ above.
+
+ -- Function: int mpfr_cmpabs (mpfr_t OP1, mpfr_t OP2)
+ Compare |OP1| and |OP2|. Return a positive value if |OP1| >
+ |OP2|, zero if |OP1| = |OP2|, and a negative value if |OP1| <
+ |OP2|. If one of the operands is NaN, set the _erange_ flag and
+ return zero.
+
+ -- Function: int mpfr_nan_p (mpfr_t OP)
+ -- Function: int mpfr_inf_p (mpfr_t OP)
+ -- Function: int mpfr_number_p (mpfr_t OP)
+ -- Function: int mpfr_zero_p (mpfr_t OP)
+ -- Function: int mpfr_regular_p (mpfr_t OP)
+ Return non-zero if OP is respectively NaN, an infinity, an ordinary
+ number (i.e., neither NaN nor an infinity), zero, or a regular
+ number (i.e., neither NaN, nor an infinity nor zero). Return zero
+ otherwise.
+
+ -- Macro: int mpfr_sgn (mpfr_t OP)
+ Return a positive value if OP > 0, zero if OP = 0, and a negative
+ value if OP < 0. If the operand is NaN, set the _erange_ flag and
+ return zero. This is equivalent to `mpfr_cmp_ui (op, 0)', but
+ more efficient.
+
+ -- Function: int mpfr_greater_p (mpfr_t OP1, mpfr_t OP2)
+ -- Function: int mpfr_greaterequal_p (mpfr_t OP1, mpfr_t OP2)
+ -- Function: int mpfr_less_p (mpfr_t OP1, mpfr_t OP2)
+ -- Function: int mpfr_lessequal_p (mpfr_t OP1, mpfr_t OP2)
+ -- Function: int mpfr_equal_p (mpfr_t OP1, mpfr_t OP2)
+ Return non-zero if OP1 > OP2, OP1 >= OP2, OP1 < OP2, OP1 <= OP2,
+ OP1 = OP2 respectively, and zero otherwise. Those functions
+ return zero whenever OP1 and/or OP2 is NaN.
+
+ -- Function: int mpfr_lessgreater_p (mpfr_t OP1, mpfr_t OP2)
+ Return non-zero if OP1 < OP2 or OP1 > OP2 (i.e., neither OP1, nor
+ OP2 is NaN, and OP1 <> OP2), zero otherwise (i.e., OP1 and/or OP2
+ is NaN, or OP1 = OP2).
+
+ -- Function: int mpfr_unordered_p (mpfr_t OP1, mpfr_t OP2)
+ Return non-zero if OP1 or OP2 is a NaN (i.e., they cannot be
+ compared), zero otherwise.
+
+
+File: mpfr.info, Node: Special Functions, Next: Input and Output Functions, Prev: Comparison Functions, Up: MPFR Interface
+
+5.7 Special Functions
+=====================
+
+All those functions, except explicitly stated (for example
+`mpfr_sin_cos'), return a *note ternary value::, i.e., zero for an
+exact return value, a positive value for a return value larger than the
+exact result, and a negative value otherwise.
+
+ Important note: in some domains, computing special functions (either
+with correct or incorrect rounding) is expensive, even for small
+precision, for example the trigonometric and Bessel functions for large
+argument.
+
+ -- Function: int mpfr_log (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_log2 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_log10 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the natural logarithm of OP, log2(OP) or log10(OP),
+ respectively, rounded in the direction RND. Set ROP to -Inf if OP
+ is -0 (i.e., the sign of the zero has no influence on the result).
+
+ -- Function: int mpfr_exp (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_exp2 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_exp10 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the exponential of OP, to 2 power of OP or to 10 power
+ of OP, respectively, rounded in the direction RND.
+
+ -- Function: int mpfr_cos (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_sin (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_tan (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the cosine of OP, sine of OP, tangent of OP, rounded in
+ the direction RND.
+
+ -- Function: int mpfr_sin_cos (mpfr_t SOP, mpfr_t COP, mpfr_t OP,
+ mpfr_rnd_t RND)
+ Set simultaneously SOP to the sine of OP and COP to the cosine of
+ OP, rounded in the direction RND with the corresponding precisions
+ of SOP and COP, which must be different variables. Return 0 iff
+ both results are exact, more precisely it returns s+4c where s=0
+ if SOP is exact, s=1 if SOP is larger than the sine of OP, s=2 if
+ SOP is smaller than the sine of OP, and similarly for c and the
+ cosine of OP.
+
+ -- Function: int mpfr_sec (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_csc (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_cot (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the secant of OP, cosecant of OP, cotangent of OP,
+ rounded in the direction RND.
+
+ -- Function: int mpfr_acos (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_asin (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_atan (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the arc-cosine, arc-sine or arc-tangent of OP, rounded
+ in the direction RND. Note that since `acos(-1)' returns the
+ floating-point number closest to Pi according to the given
+ rounding mode, this number might not be in the output range 0 <=
+ ROP < \pi of the arc-cosine function; still, the result lies in
+ the image of the output range by the rounding function. The same
+ holds for `asin(-1)', `asin(1)', `atan(-Inf)', `atan(+Inf)' or for
+ `atan(op)' with large OP and small precision of ROP.
+
+ -- Function: int mpfr_atan2 (mpfr_t ROP, mpfr_t Y, mpfr_t X,
+ mpfr_rnd_t RND)
+ Set ROP to the arc-tangent2 of Y and X, rounded in the direction
+ RND: if `x > 0', `atan2(y, x) = atan (y/x)'; if `x < 0', `atan2(y,
+ x) = sign(y)*(Pi - atan (abs(y/x)))', thus a number from -Pi to Pi.
+ As for `atan', in case the exact mathematical result is +Pi or -Pi,
+ its rounded result might be outside the function output range.
+
+ `atan2(y, 0)' does not raise any floating-point exception.
+ Special values are handled as described in the ISO C99 and IEEE
+ 754-2008 standards for the `atan2' function:
+ * `atan2(+0, -0)' returns +Pi.
+
+ * `atan2(-0, -0)' returns -Pi.
+
+ * `atan2(+0, +0)' returns +0.
+
+ * `atan2(-0, +0)' returns -0.
+
+ * `atan2(+0, x)' returns +Pi for x < 0.
+
+ * `atan2(-0, x)' returns -Pi for x < 0.
+
+ * `atan2(+0, x)' returns +0 for x > 0.
+
+ * `atan2(-0, x)' returns -0 for x > 0.
+
+ * `atan2(y, 0)' returns -Pi/2 for y < 0.
+
+ * `atan2(y, 0)' returns +Pi/2 for y > 0.
+
+ * `atan2(+Inf, -Inf)' returns +3*Pi/4.
+
+ * `atan2(-Inf, -Inf)' returns -3*Pi/4.
+
+ * `atan2(+Inf, +Inf)' returns +Pi/4.
+
+ * `atan2(-Inf, +Inf)' returns -Pi/4.
+
+ * `atan2(+Inf, x)' returns +Pi/2 for finite x.
+
+ * `atan2(-Inf, x)' returns -Pi/2 for finite x.
+
+ * `atan2(y, -Inf)' returns +Pi for finite y > 0.
+
+ * `atan2(y, -Inf)' returns -Pi for finite y < 0.
+
+ * `atan2(y, +Inf)' returns +0 for finite y > 0.
+
+ * `atan2(y, +Inf)' returns -0 for finite y < 0.
+
+ -- Function: int mpfr_cosh (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_sinh (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_tanh (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the hyperbolic cosine, sine or tangent of OP, rounded
+ in the direction RND.
+
+ -- Function: int mpfr_sinh_cosh (mpfr_t SOP, mpfr_t COP, mpfr_t OP,
+ mpfr_rnd_t RND)
+ Set simultaneously SOP to the hyperbolic sine of OP and COP to the
+ hyperbolic cosine of OP, rounded in the direction RND with the
+ corresponding precision of SOP and COP, which must be different
+ variables. Return 0 iff both results are exact (see
+ `mpfr_sin_cos' for a more detailed description of the return
+ value).
+
+ -- Function: int mpfr_sech (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_csch (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_coth (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the hyperbolic secant of OP, cosecant of OP, cotangent
+ of OP, rounded in the direction RND.
+
+ -- Function: int mpfr_acosh (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_asinh (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_atanh (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the inverse hyperbolic cosine, sine or tangent of OP,
+ rounded in the direction RND.
+
+ -- Function: int mpfr_fac_ui (mpfr_t ROP, unsigned long int OP,
+ mpfr_rnd_t RND)
+ Set ROP to the factorial of OP, rounded in the direction RND.
+
+ -- Function: int mpfr_log1p (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the logarithm of one plus OP, rounded in the direction
+ RND.
+
+ -- Function: int mpfr_expm1 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the exponential of OP followed by a subtraction by one,
+ rounded in the direction RND.
+
+ -- Function: int mpfr_eint (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the exponential integral of OP, rounded in the
+ direction RND. For positive OP, the exponential integral is the
+ sum of Euler's constant, of the logarithm of OP, and of the sum
+ for k from 1 to infinity of OP to the power k, divided by k and
+ factorial(k). For negative OP, ROP is set to NaN (this definition
+ for negative argument follows formula 5.1.2 from the Handbook of
+ Mathematical Functions from Abramowitz and Stegun, a future
+ version might use another definition).
+
+ -- Function: int mpfr_li2 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to real part of the dilogarithm of OP, rounded in the
+ direction RND. MPFR defines the dilogarithm function as the
+ integral of -log(1-t)/t from 0 to OP.
+
+ -- Function: int mpfr_gamma (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the value of the Gamma function on OP, rounded in the
+ direction RND. When OP is a negative integer, ROP is set to NaN.
+
+ -- Function: int mpfr_lngamma (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the value of the logarithm of the Gamma function on OP,
+ rounded in the direction RND. When -2K-1 <= OP <= -2K, K being a
+ non-negative integer, ROP is set to NaN. See also `mpfr_lgamma'.
+
+ -- Function: int mpfr_lgamma (mpfr_t ROP, int *SIGNP, mpfr_t OP,
+ mpfr_rnd_t RND)
+ Set ROP to the value of the logarithm of the absolute value of the
+ Gamma function on OP, rounded in the direction RND. The sign (1 or
+ -1) of Gamma(OP) is returned in the object pointed to by SIGNP.
+ When OP is an infinity or a non-positive integer, set ROP to +Inf.
+ When OP is NaN, -Inf or a negative integer, *SIGNP is undefined,
+ and when OP is ±0, *SIGNP is the sign of the zero.
+
+ -- Function: int mpfr_digamma (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the value of the Digamma (sometimes also called Psi)
+ function on OP, rounded in the direction RND. When OP is a
+ negative integer, set ROP to NaN.
+
+ -- Function: int mpfr_zeta (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_zeta_ui (mpfr_t ROP, unsigned long OP,
+ mpfr_rnd_t RND)
+ Set ROP to the value of the Riemann Zeta function on OP, rounded
+ in the direction RND.
+
+ -- Function: int mpfr_erf (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_erfc (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the value of the error function on OP (resp. the
+ complementary error function on OP) rounded in the direction RND.
+
+ -- Function: int mpfr_j0 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_j1 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_jn (mpfr_t ROP, long N, mpfr_t OP, mpfr_rnd_t
+ RND)
+ Set ROP to the value of the first kind Bessel function of order 0,
+ (resp. 1 and N) on OP, rounded in the direction RND. When OP is
+ NaN, ROP is always set to NaN. When OP is plus or minus Infinity,
+ ROP is set to +0. When OP is zero, and N is not zero, ROP is set
+ to +0 or -0 depending on the parity and sign of N, and the sign of
+ OP.
+
+ -- Function: int mpfr_y0 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_y1 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_yn (mpfr_t ROP, long N, mpfr_t OP, mpfr_rnd_t
+ RND)
+ Set ROP to the value of the second kind Bessel function of order 0
+ (resp. 1 and N) on OP, rounded in the direction RND. When OP is
+ NaN or negative, ROP is always set to NaN. When OP is +Inf, ROP is
+ set to +0. When OP is zero, ROP is set to +Inf or -Inf depending
+ on the parity and sign of N.
+
+ -- Function: int mpfr_fma (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2, mpfr_t
+ OP3, mpfr_rnd_t RND)
+ -- Function: int mpfr_fms (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2, mpfr_t
+ OP3, mpfr_rnd_t RND)
+ Set ROP to (OP1 times OP2) + OP3 (resp. (OP1 times OP2) - OP3)
+ rounded in the direction RND.
+
+ -- Function: int mpfr_agm (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ Set ROP to the arithmetic-geometric mean of OP1 and OP2, rounded
+ in the direction RND. The arithmetic-geometric mean is the common
+ limit of the sequences U_N and V_N, where U_0=OP1, V_0=OP2,
+ U_(N+1) is the arithmetic mean of U_N and V_N, and V_(N+1) is the
+ geometric mean of U_N and V_N. If any operand is negative, set
+ ROP to NaN.
+
+ -- Function: int mpfr_hypot (mpfr_t ROP, mpfr_t X, mpfr_t Y,
+ mpfr_rnd_t RND)
+ Set ROP to the Euclidean norm of X and Y, i.e., the square root of
+ the sum of the squares of X and Y, rounded in the direction RND.
+ Special values are handled as described in Section F.9.4.3 of the
+ ISO C99 and IEEE 754-2008 standards: If X or Y is an infinity,
+ then +Inf is returned in ROP, even if the other number is NaN.
+
+ -- Function: int mpfr_ai (mpfr_t ROP, mpfr_t X, mpfr_rnd_t RND)
+ Set ROP to the value of the Airy function Ai on X, rounded in the
+ direction RND. When X is NaN, ROP is always set to NaN. When X is
+ +Inf or -Inf, ROP is +0. The current implementation is not
+ intended to be used with large arguments. It works with abs(X)
+ typically smaller than 500. For larger arguments, other methods
+ should be used and will be implemented in a future version.
+
+ -- Function: int mpfr_const_log2 (mpfr_t ROP, mpfr_rnd_t RND)
+ -- Function: int mpfr_const_pi (mpfr_t ROP, mpfr_rnd_t RND)
+ -- Function: int mpfr_const_euler (mpfr_t ROP, mpfr_rnd_t RND)
+ -- Function: int mpfr_const_catalan (mpfr_t ROP, mpfr_rnd_t RND)
+ Set ROP to the logarithm of 2, the value of Pi, of Euler's
+ constant 0.577..., of Catalan's constant 0.915..., respectively,
+ rounded in the direction RND. These functions cache the computed
+ values to avoid other calculations if a lower or equal precision
+ is requested. To free these caches, use `mpfr_free_cache'.
+
+ -- Function: void mpfr_free_cache (void)
+ Free various caches used by MPFR internally, in particular the
+ caches used by the functions computing constants
+ (`mpfr_const_log2', `mpfr_const_pi', `mpfr_const_euler' and
+ `mpfr_const_catalan'). You should call this function before
+ terminating a thread, even if you did not call these functions
+ directly (they could have been called internally).
+
+ -- Function: int mpfr_sum (mpfr_t ROP, mpfr_ptr const TAB[], unsigned
+ long int N, mpfr_rnd_t RND)
+ Set ROP to the sum of all elements of TAB, whose size is N,
+ rounded in the direction RND. Warning: for efficiency reasons, TAB
+ is an array of pointers to `mpfr_t', not an array of `mpfr_t'. If
+ the returned `int' value is zero, ROP is guaranteed to be the
+ exact sum; otherwise ROP might be smaller than, equal to, or
+ larger than the exact sum (in accordance to the rounding mode).
+ However, `mpfr_sum' does guarantee the result is correctly rounded.
+
+
+File: mpfr.info, Node: Input and Output Functions, Next: Formatted Output Functions, Prev: Special Functions, Up: MPFR Interface
+
+5.8 Input and Output Functions
+==============================
+
+This section describes functions that perform input from an input/output
+stream, and functions that output to an input/output stream. Passing a
+null pointer for a `stream' to any of these functions will make them
+read from `stdin' and write to `stdout', respectively.
+
+ When using any of these functions, you must include the `<stdio.h>'
+standard header before `mpfr.h', to allow `mpfr.h' to define prototypes
+for these functions.
+
+ -- Function: size_t mpfr_out_str (FILE *STREAM, int BASE, size_t N,
+ mpfr_t OP, mpfr_rnd_t RND)
+ Output OP on stream STREAM, as a string of digits in base BASE,
+ rounded in the direction RND. The base may vary from 2 to 62.
+ Print N significant digits exactly, or if N is 0, enough digits so
+ that OP can be read back exactly (see `mpfr_get_str').
+
+ In addition to the significant digits, a decimal point (defined by
+ the current locale) at the right of the first digit and a trailing
+ exponent in base 10, in the form `eNNN', are printed. If BASE is
+ greater than 10, `@' will be used instead of `e' as exponent
+ delimiter.
+
+ Return the number of characters written, or if an error occurred,
+ return 0.
+
+ -- Function: size_t mpfr_inp_str (mpfr_t ROP, FILE *STREAM, int BASE,
+ mpfr_rnd_t RND)
+ Input a string in base BASE from stream STREAM, rounded in the
+ direction RND, and put the read float in ROP.
+
+ This function reads a word (defined as a sequence of characters
+ between whitespace) and parses it using `mpfr_set_str'. See the
+ documentation of `mpfr_strtofr' for a detailed description of the
+ valid string formats.
+
+ Return the number of bytes read, or if an error occurred, return 0.
+
+
+File: mpfr.info, Node: Formatted Output Functions, Next: Integer Related Functions, Prev: Input and Output Functions, Up: MPFR Interface
+
+5.9 Formatted Output Functions
+==============================
+
+5.9.1 Requirements
+------------------
+
+The class of `mpfr_printf' functions provides formatted output in a
+similar manner as the standard C `printf'. These functions are defined
+only if your system supports ISO C variadic functions and the
+corresponding argument access macros.
+
+ When using any of these functions, you must include the `<stdio.h>'
+standard header before `mpfr.h', to allow `mpfr.h' to define prototypes
+for these functions.
+
+5.9.2 Format String
+-------------------
+
+The format specification accepted by `mpfr_printf' is an extension of
+the `printf' one. The conversion specification is of the form:
+ % [flags] [width] [.[precision]] [type] [rounding] conv
+ `flags', `width', and `precision' have the same meaning as for the
+standard `printf' (in particular, notice that the `precision' is
+related to the number of digits displayed in the base chosen by `conv'
+and not related to the internal precision of the `mpfr_t' variable).
+`mpfr_printf' accepts the same `type' specifiers as GMP (except the
+non-standard and deprecated `q', use `ll' instead), namely the length
+modifiers defined in the C standard:
+
+ `h' `short'
+ `hh' `char'
+ `j' `intmax_t' or `uintmax_t'
+ `l' `long' or `wchar_t'
+ `ll' `long long'
+ `L' `long double'
+ `t' `ptrdiff_t'
+ `z' `size_t'
+
+ and the `type' specifiers defined in GMP plus `R' and `P' specific
+to MPFR (the second column in the table below shows the type of the
+argument read in the argument list and the kind of `conv' specifier to
+use after the `type' specifier):
+
+ `F' `mpf_t', float conversions
+ `Q' `mpq_t', integer conversions
+ `M' `mp_limb_t', integer conversions
+ `N' `mp_limb_t' array, integer conversions
+ `Z' `mpz_t', integer conversions
+ `P' `mpfr_prec_t', integer conversions
+ `R' `mpfr_t', float conversions
+
+ The `type' specifiers have the same restrictions as those mentioned
+in the GMP documentation: *note Formatted Output Strings:
+(gmp.info)Formatted Output Strings. In particular, the `type'
+specifiers (except `R' and `P') are supported only if they are
+supported by `gmp_printf' in your GMP build; this implies that the
+standard specifiers, such as `t', must _also_ be supported by your C
+library if you want to use them.
+
+ The `rounding' field is specific to `mpfr_t' arguments and should
+not be used with other types.
+
+ With conversion specification not involving `P' and `R' types,
+`mpfr_printf' behaves exactly as `gmp_printf'.
+
+ The `P' type specifies that a following `o', `u', `x', or `X'
+conversion specifier applies to a `mpfr_prec_t' argument. It is needed
+because the `mpfr_prec_t' type does not necessarily correspond to an
+`unsigned int' or any fixed standard type. The `precision' field
+specifies the minimum number of digits to appear. The default
+`precision' is 1. For example:
+ mpfr_t x;
+ mpfr_prec_t p;
+ mpfr_init (x);
+ ...
+ p = mpfr_get_prec (x);
+ mpfr_printf ("variable x with %Pu bits", p);
+
+ The `R' type specifies that a following `a', `A', `b', `e', `E',
+`f', `F', `g', `G', or `n' conversion specifier applies to a `mpfr_t'
+argument. The `R' type can be followed by a `rounding' specifier
+denoted by one of the following characters:
+
+ `U' round toward plus infinity
+ `D' round toward minus infinity
+ `Y' round away from zero
+ `Z' round toward zero
+ `N' round to nearest (with ties to even)
+ `*' rounding mode indicated by the
+ `mpfr_rnd_t' argument just before the
+ corresponding `mpfr_t' variable.
+
+ The default rounding mode is rounding to nearest. The following
+three examples are equivalent:
+ mpfr_t x;
+ mpfr_init (x);
+ ...
+ mpfr_printf ("%.128Rf", x);
+ mpfr_printf ("%.128RNf", x);
+ mpfr_printf ("%.128R*f", MPFR_RNDN, x);
+
+ Note that the rounding away from zero mode is specified with `Y'
+because ISO C reserves the `A' specifier for hexadecimal output (see
+below).
+
+ The output `conv' specifiers allowed with `mpfr_t' parameter are:
+
+ `a' `A' hex float, C99 style
+ `b' binary output
+ `e' `E' scientific format float
+ `f' `F' fixed point float
+ `g' `G' fixed or scientific float
+
+ The conversion specifier `b' which displays the argument in binary is
+specific to `mpfr_t' arguments and should not be used with other types.
+Other conversion specifiers have the same meaning as for a `double'
+argument.
+
+ In case of non-decimal output, only the significand is written in the
+specified base, the exponent is always displayed in decimal. Special
+values are always displayed as `nan', `-inf', and `inf' for `a', `b',
+`e', `f', and `g' specifiers and `NAN', `-INF', and `INF' for `A', `E',
+`F', and `G' specifiers.
+
+ If the `precision' field is not empty, the `mpfr_t' number is
+rounded to the given precision in the direction specified by the
+rounding mode. If the precision is zero with rounding to nearest mode
+and one of the following `conv' specifiers: `a', `A', `b', `e', `E',
+tie case is rounded to even when it lies between two consecutive values
+at the wanted precision which have the same exponent, otherwise, it is
+rounded away from zero. For instance, 85 is displayed as "8e+1" and 95
+is displayed as "1e+2" with the format specification `"%.0RNe"'. This
+also applies when the `g' (resp. `G') conversion specifier uses the `e'
+(resp. `E') style. If the precision is set to a value greater than the
+maximum value for an `int', it will be silently reduced down to
+`INT_MAX'.
+
+ If the `precision' field is empty (as in `%Re' or `%.RE') with
+`conv' specifier `e' and `E', the number is displayed with enough
+digits so that it can be read back exactly, assuming that the input and
+output variables have the same precision and that the input and output
+rounding modes are both rounding to nearest (as for `mpfr_get_str').
+The default precision for an empty `precision' field with `conv'
+specifiers `f', `F', `g', and `G' is 6.
+
+5.9.3 Functions
+---------------
+
+For all the following functions, if the number of characters which
+ought to be written appears to exceed the maximum limit for an `int',
+nothing is written in the stream (resp. to `stdout', to BUF, to STR),
+the function returns -1, sets the _erange_ flag, and (in POSIX system
+only) `errno' is set to `EOVERFLOW'.
+
+ -- Function: int mpfr_fprintf (FILE *STREAM, const char *TEMPLATE, ...)
+ -- Function: int mpfr_vfprintf (FILE *STREAM, const char *TEMPLATE,
+ va_list AP)
+ Print to the stream STREAM the optional arguments under the
+ control of the template string TEMPLATE. Return the number of
+ characters written or a negative value if an error occurred.
+
+ -- Function: int mpfr_printf (const char *TEMPLATE, ...)
+ -- Function: int mpfr_vprintf (const char *TEMPLATE, va_list AP)
+ Print to `stdout' the optional arguments under the control of the
+ template string TEMPLATE. Return the number of characters written
+ or a negative value if an error occurred.
+
+ -- Function: int mpfr_sprintf (char *BUF, const char *TEMPLATE, ...)
+ -- Function: int mpfr_vsprintf (char *BUF, const char *TEMPLATE,
+ va_list AP)
+ Form a null-terminated string corresponding to the optional
+ arguments under the control of the template string TEMPLATE, and
+ print it in BUF. No overlap is permitted between BUF and the other
+ arguments. Return the number of characters written in the array
+ BUF _not counting_ the terminating null character or a negative
+ value if an error occurred.
+
+ -- Function: int mpfr_snprintf (char *BUF, size_t N, const char
+ *TEMPLATE, ...)
+ -- Function: int mpfr_vsnprintf (char *BUF, size_t N, const char
+ *TEMPLATE, va_list AP)
+ Form a null-terminated string corresponding to the optional
+ arguments under the control of the template string TEMPLATE, and
+ print it in BUF. If N is zero, nothing is written and BUF may be a
+ null pointer, otherwise, the N-1 first characters are written in
+ BUF and the N-th is a null character. Return the number of
+ characters that would have been written had N be sufficiently
+ large, _not counting_ the terminating null character, or a
+ negative value if an error occurred.
+
+ -- Function: int mpfr_asprintf (char **STR, const char *TEMPLATE, ...)
+ -- Function: int mpfr_vasprintf (char **STR, const char *TEMPLATE,
+ va_list AP)
+ Write their output as a null terminated string in a block of
+ memory allocated using the current allocation function. A pointer
+ to the block is stored in STR. The block of memory must be freed
+ using `mpfr_free_str'. The return value is the number of
+ characters written in the string, excluding the null-terminator,
+ or a negative value if an error occurred.
+
+
+File: mpfr.info, Node: Integer Related Functions, Next: Rounding Related Functions, Prev: Formatted Output Functions, Up: MPFR Interface
+
+5.10 Integer and Remainder Related Functions
+============================================
+
+ -- Function: int mpfr_rint (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_ceil (mpfr_t ROP, mpfr_t OP)
+ -- Function: int mpfr_floor (mpfr_t ROP, mpfr_t OP)
+ -- Function: int mpfr_round (mpfr_t ROP, mpfr_t OP)
+ -- Function: int mpfr_trunc (mpfr_t ROP, mpfr_t OP)
+ Set ROP to OP rounded to an integer. `mpfr_rint' rounds to the
+ nearest representable integer in the given direction RND,
+ `mpfr_ceil' rounds to the next higher or equal representable
+ integer, `mpfr_floor' to the next lower or equal representable
+ integer, `mpfr_round' to the nearest representable integer,
+ rounding halfway cases away from zero (as in the roundTiesToAway
+ mode of IEEE 754-2008), and `mpfr_trunc' to the next representable
+ integer toward zero.
+
+ The returned value is zero when the result is exact, positive when
+ it is greater than the original value of OP, and negative when it
+ is smaller. More precisely, the returned value is 0 when OP is an
+ integer representable in ROP, 1 or -1 when OP is an integer that
+ is not representable in ROP, 2 or -2 when OP is not an integer.
+
+ Note that `mpfr_round' is different from `mpfr_rint' called with
+ the rounding to nearest mode (where halfway cases are rounded to
+ an even integer or significand). Note also that no double rounding
+ is performed; for instance, 10.5 (1010.1 in binary) is rounded by
+ `mpfr_rint' with rounding to nearest to 12 (1100 in binary) in
+ 2-bit precision, because the two enclosing numbers representable
+ on two bits are 8 and 12, and the closest is 12. (If one first
+ rounded to an integer, one would round 10.5 to 10 with even
+ rounding, and then 10 would be rounded to 8 again with even
+ rounding.)
+
+ -- Function: int mpfr_rint_ceil (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_rint_floor (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t
+ RND)
+ -- Function: int mpfr_rint_round (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t
+ RND)
+ -- Function: int mpfr_rint_trunc (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t
+ RND)
+ Set ROP to OP rounded to an integer. `mpfr_rint_ceil' rounds to
+ the next higher or equal integer, `mpfr_rint_floor' to the next
+ lower or equal integer, `mpfr_rint_round' to the nearest integer,
+ rounding halfway cases away from zero, and `mpfr_rint_trunc' to
+ the next integer toward zero. If the result is not representable,
+ it is rounded in the direction RND. The returned value is the
+ ternary value associated with the considered round-to-integer
+ function (regarded in the same way as any other mathematical
+ function). Contrary to `mpfr_rint', those functions do perform a
+ double rounding: first OP is rounded to the nearest integer in the
+ direction given by the function name, then this nearest integer
+ (if not representable) is rounded in the given direction RND. For
+ example, `mpfr_rint_round' with rounding to nearest and a precision
+ of two bits rounds 6.5 to 7 (halfway cases away from zero), then 7
+ is rounded to 8 by the round-even rule, despite the fact that 6 is
+ also representable on two bits, and is closer to 6.5 than 8.
+
+ -- Function: int mpfr_frac (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the fractional part of OP, having the same sign as OP,
+ rounded in the direction RND (unlike in `mpfr_rint', RND affects
+ only how the exact fractional part is rounded, not how the
+ fractional part is generated).
+
+ -- Function: int mpfr_modf (mpfr_t IOP, mpfr_t FOP, mpfr_t OP,
+ mpfr_rnd_t RND)
+ Set simultaneously IOP to the integral part of OP and FOP to the
+ fractional part of OP, rounded in the direction RND with the
+ corresponding precision of IOP and FOP (equivalent to
+ `mpfr_trunc(IOP, OP, RND)' and `mpfr_frac(FOP, OP, RND)'). The
+ variables IOP and FOP must be different. Return 0 iff both results
+ are exact (see `mpfr_sin_cos' for a more detailed description of
+ the return value).
+
+ -- Function: int mpfr_fmod (mpfr_t R, mpfr_t X, mpfr_t Y, mpfr_rnd_t
+ RND)
+ -- Function: int mpfr_remainder (mpfr_t R, mpfr_t X, mpfr_t Y,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_remquo (mpfr_t R, long* Q, mpfr_t X, mpfr_t Y,
+ mpfr_rnd_t RND)
+ Set R to the value of X - NY, rounded according to the direction
+ RND, where N is the integer quotient of X divided by Y, defined as
+ follows: N is rounded toward zero for `mpfr_fmod', and to the
+ nearest integer (ties rounded to even) for `mpfr_remainder' and
+ `mpfr_remquo'.
+
+ Special values are handled as described in Section F.9.7.1 of the
+ ISO C99 standard: If X is infinite or Y is zero, R is NaN. If Y
+ is infinite and X is finite, R is X rounded to the precision of R.
+ If R is zero, it has the sign of X. The return value is the
+ ternary value corresponding to R.
+
+ Additionally, `mpfr_remquo' stores the low significant bits from
+ the quotient N in *Q (more precisely the number of bits in a
+ `long' minus one), with the sign of X divided by Y (except if
+ those low bits are all zero, in which case zero is returned).
+ Note that X may be so large in magnitude relative to Y that an
+ exact representation of the quotient is not practical. The
+ `mpfr_remainder' and `mpfr_remquo' functions are useful for
+ additive argument reduction.
+
+ -- Function: int mpfr_integer_p (mpfr_t OP)
+ Return non-zero iff OP is an integer.
+
+
+File: mpfr.info, Node: Rounding Related Functions, Next: Miscellaneous Functions, Prev: Integer Related Functions, Up: MPFR Interface
+
+5.11 Rounding Related Functions
+===============================
+
+ -- Function: void mpfr_set_default_rounding_mode (mpfr_rnd_t RND)
+ Set the default rounding mode to RND. The default rounding mode
+ is to nearest initially.
+
+ -- Function: mpfr_rnd_t mpfr_get_default_rounding_mode (void)
+ Get the default rounding mode.
+
+ -- Function: int mpfr_prec_round (mpfr_t X, mpfr_prec_t PREC,
+ mpfr_rnd_t RND)
+ Round X according to RND with precision PREC, which must be an
+ integer between `MPFR_PREC_MIN' and `MPFR_PREC_MAX' (otherwise the
+ behavior is undefined). If PREC is greater or equal to the
+ precision of X, then new space is allocated for the significand,
+ and it is filled with zeros. Otherwise, the significand is
+ rounded to precision PREC with the given direction. In both cases,
+ the precision of X is changed to PREC.
+
+ Here is an example of how to use `mpfr_prec_round' to implement
+ Newton's algorithm to compute the inverse of A, assuming X is
+ already an approximation to N bits:
+ mpfr_set_prec (t, 2 * n);
+ mpfr_set (t, a, MPFR_RNDN); /* round a to 2n bits */
+ mpfr_mul (t, t, x, MPFR_RNDN); /* t is correct to 2n bits */
+ mpfr_ui_sub (t, 1, t, MPFR_RNDN); /* high n bits cancel with 1 */
+ mpfr_prec_round (t, n, MPFR_RNDN); /* t is correct to n bits */
+ mpfr_mul (t, t, x, MPFR_RNDN); /* t is correct to n bits */
+ mpfr_prec_round (x, 2 * n, MPFR_RNDN); /* exact */
+ mpfr_add (x, x, t, MPFR_RNDN); /* x is correct to 2n bits */
+
+ -- Function: int mpfr_can_round (mpfr_t B, mpfr_exp_t ERR, mpfr_rnd_t
+ RND1, mpfr_rnd_t RND2, mpfr_prec_t PREC)
+ Assuming B is an approximation of an unknown number X in the
+ direction RND1 with error at most two to the power E(b)-ERR where
+ E(b) is the exponent of B, return a non-zero value if one is able
+ to round correctly X to precision PREC with the direction RND2,
+ and 0 otherwise (including for NaN and Inf). This function *does
+ not modify* its arguments.
+
+ If RND1 is `MPFR_RNDN', then the sign of the error is unknown, but
+ its absolute value is the same, so that the possible range is
+ twice as large as with a directed rounding for RND1.
+
+ Note: if one wants to also determine the correct *note ternary
+ value:: when rounding B to precision PREC with rounding mode RND,
+ a useful trick is the following: if (mpfr_can_round (b, err, MPFR_RNDN, MPFR_RNDZ, prec + (rnd == MPFR_RNDN)))
+ ...
+ Indeed, if RND is `MPFR_RNDN', this will check if one can round
+ to PREC+1 bits with a directed rounding: if so, one can surely
+ round to nearest to PREC bits, and in addition one can determine
+ the correct ternary value, which would not be the case when B is
+ near from a value exactly representable on PREC bits.
+
+ -- Function: mpfr_prec_t mpfr_min_prec (mpfr_t X)
+ Return the minimal number of bits required to store the
+ significand of X, and 0 for special values, including 0. (Warning:
+ the returned value can be less than `MPFR_PREC_MIN'.)
+
+ The function name is subject to change.
+
+ -- Function: const char * mpfr_print_rnd_mode (mpfr_rnd_t RND)
+ Return a string ("MPFR_RNDD", "MPFR_RNDU", "MPFR_RNDN",
+ "MPFR_RNDZ", "MPFR_RNDA") corresponding to the rounding mode RND,
+ or a null pointer if RND is an invalid rounding mode.
+
+
+File: mpfr.info, Node: Miscellaneous Functions, Next: Exception Related Functions, Prev: Rounding Related Functions, Up: MPFR Interface
+
+5.12 Miscellaneous Functions
+============================
+
+ -- Function: void mpfr_nexttoward (mpfr_t X, mpfr_t Y)
+ If X or Y is NaN, set X to NaN. If X and Y are equal, X is
+ unchanged. Otherwise, if X is different from Y, replace X by the
+ next floating-point number (with the precision of X and the
+ current exponent range) in the direction of Y (the infinite values
+ are seen as the smallest and largest floating-point numbers). If
+ the result is zero, it keeps the same sign. No underflow or
+ overflow is generated.
+
+ -- Function: void mpfr_nextabove (mpfr_t X)
+ -- Function: void mpfr_nextbelow (mpfr_t X)
+ Equivalent to `mpfr_nexttoward' where Y is plus infinity (resp.
+ minus infinity).
+
+ -- Function: int mpfr_min (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_max (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ Set ROP to the minimum (resp. maximum) of OP1 and OP2. If OP1 and
+ OP2 are both NaN, then ROP is set to NaN. If OP1 or OP2 is NaN,
+ then ROP is set to the numeric value. If OP1 and OP2 are zeros of
+ different signs, then ROP is set to -0 (resp. +0).
+
+ -- Function: int mpfr_urandomb (mpfr_t ROP, gmp_randstate_t STATE)
+ Generate a uniformly distributed random float in the interval 0 <=
+ ROP < 1. More precisely, the number can be seen as a float with a
+ random non-normalized significand and exponent 0, which is then
+ normalized (thus if E denotes the exponent after normalization,
+ then the least -E significant bits of the significand are always
+ 0).
+
+ Return 0, unless the exponent is not in the current exponent
+ range, in which case ROP is set to NaN and a non-zero value is
+ returned (this should never happen in practice, except in very
+ specific cases). The second argument is a `gmp_randstate_t'
+ structure which should be created using the GMP `gmp_randinit'
+ function (see the GMP manual).
+
+ Note: for a given version of MPFR, the returned value of ROP and
+ the new value of STATE (which controls further random values) do
+ not depend on the machine word size.
+
+ -- Function: int mpfr_urandom (mpfr_t ROP, gmp_randstate_t STATE,
+ mpfr_rnd_t RND)
+ Generate a uniformly distributed random float. The floating-point
+ number ROP can be seen as if a random real number is generated
+ according to the continuous uniform distribution on the interval
+ [0, 1] and then rounded in the direction RND.
+
+ The second argument is a `gmp_randstate_t' structure which should
+ be created using the GMP `gmp_randinit' function (see the GMP
+ manual).
+
+ Note: the note for `mpfr_urandomb' holds too. In addition, the
+ exponent range and the rounding mode might have a side effect on
+ the next random state.
+
+ -- Function: int mpfr_grandom (mpfr_t ROP1, mpfr_t ROP2,
+ gmp_randstate_t STATE, mpfr_rnd_t RND)
+ Generate two random floats according to a standard normal gaussian
+ distribution. If ROP2 is a null pointer, then only one value is
+ generated and stored in ROP1.
+
+ The floating-point number ROP1 (and ROP2) can be seen as if a
+ random real number were generated according to the standard normal
+ gaussian distribution and then rounded in the direction RND.
+
+ The third argument is a `gmp_randstate_t' structure, which should
+ be created using the GMP `gmp_randinit' function (see the GMP
+ manual).
+
+ The combination of the ternary values is returned like with
+ `mpfr_sin_cos'. If ROP2 is a null pointer, the second ternary
+ value is assumed to be 0 (note that the encoding of the only
+ ternary value is not the same as the usual encoding for functions
+ that return only one result). Otherwise the ternary value of a
+ random number is always non-zero.
+
+ Note: the note for `mpfr_urandomb' holds too. In addition, the
+ exponent range and the rounding mode might have a side effect on
+ the next random state.
+
+ -- Function: mpfr_exp_t mpfr_get_exp (mpfr_t X)
+ Return the exponent of X, assuming that X is a non-zero ordinary
+ number and the significand is considered in [1/2,1). The behavior
+ for NaN, infinity or zero is undefined.
+
+ -- Function: int mpfr_set_exp (mpfr_t X, mpfr_exp_t E)
+ Set the exponent of X if E is in the current exponent range, and
+ return 0 (even if X is not a non-zero ordinary number); otherwise,
+ return a non-zero value. The significand is assumed to be in
+ [1/2,1).
+
+ -- Function: int mpfr_signbit (mpfr_t OP)
+ Return a non-zero value iff OP has its sign bit set (i.e., if it is
+ negative, -0, or a NaN whose representation has its sign bit set).
+
+ -- Function: int mpfr_setsign (mpfr_t ROP, mpfr_t OP, int S,
+ mpfr_rnd_t RND)
+ Set the value of ROP from OP, rounded toward the given direction
+ RND, then set (resp. clear) its sign bit if S is non-zero (resp.
+ zero), even when OP is a NaN.
+
+ -- Function: int mpfr_copysign (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ Set the value of ROP from OP1, rounded toward the given direction
+ RND, then set its sign bit to that of OP2 (even when OP1 or OP2 is
+ a NaN). This function is equivalent to `mpfr_setsign (ROP, OP1,
+ mpfr_signbit (OP2), RND)'.
+
+ -- Function: const char * mpfr_get_version (void)
+ Return the MPFR version, as a null-terminated string.
+
+ -- Macro: MPFR_VERSION
+ -- Macro: MPFR_VERSION_MAJOR
+ -- Macro: MPFR_VERSION_MINOR
+ -- Macro: MPFR_VERSION_PATCHLEVEL
+ -- Macro: MPFR_VERSION_STRING
+ `MPFR_VERSION' is the version of MPFR as a preprocessing constant.
+ `MPFR_VERSION_MAJOR', `MPFR_VERSION_MINOR' and
+ `MPFR_VERSION_PATCHLEVEL' are respectively the major, minor and
+ patch level of MPFR version, as preprocessing constants.
+ `MPFR_VERSION_STRING' is the version (with an optional suffix, used
+ in development and pre-release versions) as a string constant,
+ which can be compared to the result of `mpfr_get_version' to check
+ at run time the header file and library used match:
+ if (strcmp (mpfr_get_version (), MPFR_VERSION_STRING))
+ fprintf (stderr, "Warning: header and library do not match\n");
+ Note: Obtaining different strings is not necessarily an error, as
+ in general, a program compiled with some old MPFR version can be
+ dynamically linked with a newer MPFR library version (if allowed
+ by the library versioning system).
+
+ -- Macro: long MPFR_VERSION_NUM (MAJOR, MINOR, PATCHLEVEL)
+ Create an integer in the same format as used by `MPFR_VERSION'
+ from the given MAJOR, MINOR and PATCHLEVEL. Here is an example of
+ how to check the MPFR version at compile time:
+ #if (!defined(MPFR_VERSION) || (MPFR_VERSION<MPFR_VERSION_NUM(3,0,0)))
+ # error "Wrong MPFR version."
+ #endif
+
+ -- Function: const char * mpfr_get_patches (void)
+ Return a null-terminated string containing the ids of the patches
+ applied to the MPFR library (contents of the `PATCHES' file),
+ separated by spaces. Note: If the program has been compiled with
+ an older MPFR version and is dynamically linked with a new MPFR
+ library version, the identifiers of the patches applied to the old
+ (compile-time) MPFR version are not available (however this
+ information should not have much interest in general).
+
+ -- Function: int mpfr_buildopt_tls_p (void)
+ Return a non-zero value if MPFR was compiled as thread safe using
+ compiler-level Thread Local Storage (that is, MPFR was built with
+ the `--enable-thread-safe' configure option, see `INSTALL' file),
+ return zero otherwise.
+
+ -- Function: int mpfr_buildopt_decimal_p (void)
+ Return a non-zero value if MPFR was compiled with decimal float
+ support (that is, MPFR was built with the `--enable-decimal-float'
+ configure option), return zero otherwise.
+
+ -- Function: int mpfr_buildopt_gmpinternals_p (void)
+ Return a non-zero value if MPFR was compiled with GMP internals
+ (that is, MPFR was built with either `--with-gmp-build' or
+ `--enable-gmp-internals' configure option), return zero otherwise.
+
+ -- Function: const char * mpfr_buildopt_tune_case (void)
+ Return a string saying which thresholds file has been used at
+ compile time. This file is normally selected from the processor
+ type.
+
+
+File: mpfr.info, Node: Exception Related Functions, Next: Compatibility with MPF, Prev: Miscellaneous Functions, Up: MPFR Interface
+
+5.13 Exception Related Functions
+================================
+
+ -- Function: mpfr_exp_t mpfr_get_emin (void)
+ -- Function: mpfr_exp_t mpfr_get_emax (void)
+ Return the (current) smallest and largest exponents allowed for a
+ floating-point variable. The smallest positive value of a
+ floating-point variable is one half times 2 raised to the smallest
+ exponent and the largest value has the form (1 - epsilon) times 2
+ raised to the largest exponent, where epsilon depends on the
+ precision of the considered variable.
+
+ -- Function: int mpfr_set_emin (mpfr_exp_t EXP)
+ -- Function: int mpfr_set_emax (mpfr_exp_t EXP)
+ Set the smallest and largest exponents allowed for a
+ floating-point variable. Return a non-zero value when EXP is not
+ in the range accepted by the implementation (in that case the
+ smallest or largest exponent is not changed), and zero otherwise.
+ If the user changes the exponent range, it is her/his
+ responsibility to check that all current floating-point variables
+ are in the new allowed range (for example using
+ `mpfr_check_range'), otherwise the subsequent behavior will be
+ undefined, in the sense of the ISO C standard.
+
+ -- Function: mpfr_exp_t mpfr_get_emin_min (void)
+ -- Function: mpfr_exp_t mpfr_get_emin_max (void)
+ -- Function: mpfr_exp_t mpfr_get_emax_min (void)
+ -- Function: mpfr_exp_t mpfr_get_emax_max (void)
+ Return the minimum and maximum of the exponents allowed for
+ `mpfr_set_emin' and `mpfr_set_emax' respectively. These values
+ are implementation dependent, thus a program using
+ `mpfr_set_emax(mpfr_get_emax_max())' or
+ `mpfr_set_emin(mpfr_get_emin_min())' may not be portable.
+
+ -- Function: int mpfr_check_range (mpfr_t X, int T, mpfr_rnd_t RND)
+ This function assumes that X is the correctly-rounded value of some
+ real value Y in the direction RND and some extended exponent
+ range, and that T is the corresponding *note ternary value::. For
+ example, one performed `t = mpfr_log (x, u, rnd)', and Y is the
+ exact logarithm of U. Thus T is negative if X is smaller than Y,
+ positive if X is larger than Y, and zero if X equals Y. This
+ function modifies X if needed to be in the current range of
+ acceptable values: It generates an underflow or an overflow if the
+ exponent of X is outside the current allowed range; the value of T
+ may be used to avoid a double rounding. This function returns zero
+ if the new value of X equals the exact one Y, a positive value if
+ that new value is larger than Y, and a negative value if it is
+ smaller than Y. Note that unlike most functions, the new result X
+ is compared to the (unknown) exact one Y, not the input value X,
+ i.e., the ternary value is propagated.
+
+ Note: If X is an infinity and T is different from zero (i.e., if
+ the rounded result is an inexact infinity), then the overflow flag
+ is set. This is useful because `mpfr_check_range' is typically
+ called (at least in MPFR functions) after restoring the flags that
+ could have been set due to internal computations.
+
+ -- Function: int mpfr_subnormalize (mpfr_t X, int T, mpfr_rnd_t RND)
+ This function rounds X emulating subnormal number arithmetic: if X
+ is outside the subnormal exponent range, it just propagates the
+ *note ternary value:: T; otherwise, it rounds X to precision
+ `EXP(x)-emin+1' according to rounding mode RND and previous
+ ternary value T, avoiding double rounding problems. More
+ precisely in the subnormal domain, denoting by E the value of
+ `emin', X is rounded in fixed-point arithmetic to an integer
+ multiple of two to the power E-1; as a consequence, 1.5 multiplied
+ by two to the power E-1 when T is zero is rounded to two to the
+ power E with rounding to nearest.
+
+ `PREC(x)' is not modified by this function. RND and T must be the
+ rounding mode and the returned ternary value used when computing X
+ (as in `mpfr_check_range'). The subnormal exponent range is from
+ `emin' to `emin+PREC(x)-1'. If the result cannot be represented
+ in the current exponent range (due to a too small `emax'), the
+ behavior is undefined. Note that unlike most functions, the
+ result is compared to the exact one, not the input value X, i.e.,
+ the ternary value is propagated.
+
+ As usual, if the returned ternary value is non zero, the inexact
+ flag is set. Moreover, if a second rounding occurred (because the
+ input X was in the subnormal range), the underflow flag is set.
+
+ This is an example of how to emulate binary double IEEE 754
+arithmetic (binary64 in IEEE 754-2008) using MPFR:
+
+ {
+ mpfr_t xa, xb; int i; volatile double a, b;
+
+ mpfr_set_default_prec (53);
+ mpfr_set_emin (-1073); mpfr_set_emax (1024);
+
+ mpfr_init (xa); mpfr_init (xb);
+
+ b = 34.3; mpfr_set_d (xb, b, MPFR_RNDN);
+ a = 0x1.1235P-1021; mpfr_set_d (xa, a, MPFR_RNDN);
+
+ a /= b;
+ i = mpfr_div (xa, xa, xb, MPFR_RNDN);
+ i = mpfr_subnormalize (xa, i, MPFR_RNDN); /* new ternary value */
+
+ mpfr_clear (xa); mpfr_clear (xb);
+ }
+
+ Warning: this emulates a double IEEE 754 arithmetic with correct
+rounding in the subnormal range, which may not be the case for your
+hardware.
+
+ -- Function: void mpfr_clear_underflow (void)
+ -- Function: void mpfr_clear_overflow (void)
+ -- Function: void mpfr_clear_divby0 (void)
+ -- Function: void mpfr_clear_nanflag (void)
+ -- Function: void mpfr_clear_inexflag (void)
+ -- Function: void mpfr_clear_erangeflag (void)
+ Clear the underflow, overflow, divide-by-zero, invalid, inexact
+ and _erange_ flags.
+
+ -- Function: void mpfr_set_underflow (void)
+ -- Function: void mpfr_set_overflow (void)
+ -- Function: void mpfr_set_divby0 (void)
+ -- Function: void mpfr_set_nanflag (void)
+ -- Function: void mpfr_set_inexflag (void)
+ -- Function: void mpfr_set_erangeflag (void)
+ Set the underflow, overflow, divide-by-zero, invalid, inexact and
+ _erange_ flags.
+
+ -- Function: void mpfr_clear_flags (void)
+ Clear all global flags (underflow, overflow, divide-by-zero,
+ invalid, inexact, _erange_).
+
+ -- Function: int mpfr_underflow_p (void)
+ -- Function: int mpfr_overflow_p (void)
+ -- Function: int mpfr_divby0_p (void)
+ -- Function: int mpfr_nanflag_p (void)
+ -- Function: int mpfr_inexflag_p (void)
+ -- Function: int mpfr_erangeflag_p (void)
+ Return the corresponding (underflow, overflow, divide-by-zero,
+ invalid, inexact, _erange_) flag, which is non-zero iff the flag
+ is set.
+
+
+File: mpfr.info, Node: Compatibility with MPF, Next: Custom Interface, Prev: Exception Related Functions, Up: MPFR Interface
+
+5.14 Compatibility With MPF
+===========================
+
+A header file `mpf2mpfr.h' is included in the distribution of MPFR for
+compatibility with the GNU MP class MPF. By inserting the following
+two lines after the `#include <gmp.h>' line,
+#include <mpfr.h>
+#include <mpf2mpfr.h>
+ any program written for MPF can be compiled directly with MPFR without
+any changes (except the `gmp_printf' functions will not work for
+arguments of type `mpfr_t'). All operations are then performed with
+the default MPFR rounding mode, which can be reset with
+`mpfr_set_default_rounding_mode'.
+
+ Warning: the `mpf_init' and `mpf_init2' functions initialize to
+zero, whereas the corresponding MPFR functions initialize to NaN: this
+is useful to detect uninitialized values, but is slightly incompatible
+with MPF.
+
+ -- Function: void mpfr_set_prec_raw (mpfr_t X, mpfr_prec_t PREC)
+ Reset the precision of X to be *exactly* PREC bits. The only
+ difference with `mpfr_set_prec' is that PREC is assumed to be
+ small enough so that the significand fits into the current
+ allocated memory space for X. Otherwise the behavior is undefined.
+
+ -- Function: int mpfr_eq (mpfr_t OP1, mpfr_t OP2, unsigned long int
+ OP3)
+ Return non-zero if OP1 and OP2 are both non-zero ordinary numbers
+ with the same exponent and the same first OP3 bits, both zero, or
+ both infinities of the same sign. Return zero otherwise. This
+ function is defined for compatibility with MPF, we do not recommend
+ to use it otherwise. Do not use it either if you want to know
+ whether two numbers are close to each other; for instance,
+ 1.011111 and 1.100000 are regarded as different for any value of
+ OP3 larger than 1.
+
+ -- Function: void mpfr_reldiff (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+ Compute the relative difference between OP1 and OP2 and store the
+ result in ROP. This function does not guarantee the correct
+ rounding on the relative difference; it just computes
+ |OP1-OP2|/OP1, using the precision of ROP and the rounding mode
+ RND for all operations.
+
+ -- Function: int mpfr_mul_2exp (mpfr_t ROP, mpfr_t OP1, unsigned long
+ int OP2, mpfr_rnd_t RND)
+ -- Function: int mpfr_div_2exp (mpfr_t ROP, mpfr_t OP1, unsigned long
+ int OP2, mpfr_rnd_t RND)
+ These functions are identical to `mpfr_mul_2ui' and `mpfr_div_2ui'
+ respectively. These functions are only kept for compatibility
+ with MPF, one should prefer `mpfr_mul_2ui' and `mpfr_div_2ui'
+ otherwise.
+
+
+File: mpfr.info, Node: Custom Interface, Next: Internals, Prev: Compatibility with MPF, Up: MPFR Interface
+
+5.15 Custom Interface
+=====================
+
+Some applications use a stack to handle the memory and their objects.
+However, the MPFR memory design is not well suited for such a thing. So
+that such applications are able to use MPFR, an auxiliary memory
+interface has been created: the Custom Interface.
+
+ The following interface allows one to use MPFR in two ways:
+ * Either directly store a floating-point number as a `mpfr_t' on the
+ stack.
+
+ * Either store its own representation on the stack and construct a
+ new temporary `mpfr_t' each time it is needed.
+ Nothing has to be done to destroy the floating-point numbers except
+garbaging the used memory: all the memory management (allocating,
+destroying, garbaging) is left to the application.
+
+ Each function in this interface is also implemented as a macro for
+efficiency reasons: for example `mpfr_custom_init (s, p)' uses the
+macro, while `(mpfr_custom_init) (s, p)' uses the function.
+
+ Note 1: MPFR functions may still initialize temporary floating-point
+numbers using `mpfr_init' and similar functions. See Custom Allocation
+(GNU MP).
+
+ Note 2: MPFR functions may use the cached functions (`mpfr_const_pi'
+for example), even if they are not explicitly called. You have to call
+`mpfr_free_cache' each time you garbage the memory iff `mpfr_init',
+through GMP Custom Allocation, allocates its memory on the application
+stack.
+
+ -- Function: size_t mpfr_custom_get_size (mpfr_prec_t PREC)
+ Return the needed size in bytes to store the significand of a
+ floating-point number of precision PREC.
+
+ -- Function: void mpfr_custom_init (void *SIGNIFICAND, mpfr_prec_t
+ PREC)
+ Initialize a significand of precision PREC, where SIGNIFICAND must
+ be an area of `mpfr_custom_get_size (prec)' bytes at least and be
+ suitably aligned for an array of `mp_limb_t' (GMP type, *note
+ Internals::).
+
+ -- Function: void mpfr_custom_init_set (mpfr_t X, int KIND, mpfr_exp_t
+ EXP, mpfr_prec_t PREC, void *SIGNIFICAND)
+ Perform a dummy initialization of a `mpfr_t' and set it to:
+ * if `ABS(kind) == MPFR_NAN_KIND', X is set to NaN;
+
+ * if `ABS(kind) == MPFR_INF_KIND', X is set to the infinity of
+ sign `sign(kind)';
+
+ * if `ABS(kind) == MPFR_ZERO_KIND', X is set to the zero of
+ sign `sign(kind)';
+
+ * if `ABS(kind) == MPFR_REGULAR_KIND', X is set to a regular
+ number: `x = sign(kind)*significand*2^exp'.
+ In all cases, it uses SIGNIFICAND directly for further computing
+ involving X. It will not allocate anything. A floating-point
+ number initialized with this function cannot be resized using
+ `mpfr_set_prec' or `mpfr_prec_round', or cleared using
+ `mpfr_clear'! The SIGNIFICAND must have been initialized with
+ `mpfr_custom_init' using the same precision PREC.
+
+ -- Function: int mpfr_custom_get_kind (mpfr_t X)
+ Return the current kind of a `mpfr_t' as created by
+ `mpfr_custom_init_set'. The behavior of this function for any
+ `mpfr_t' not initialized with `mpfr_custom_init_set' is undefined.
+
+ -- Function: void * mpfr_custom_get_significand (mpfr_t X)
+ Return a pointer to the significand used by a `mpfr_t' initialized
+ with `mpfr_custom_init_set'. The behavior of this function for
+ any `mpfr_t' not initialized with `mpfr_custom_init_set' is
+ undefined.
+
+ -- Function: mpfr_exp_t mpfr_custom_get_exp (mpfr_t X)
+ Return the exponent of X, assuming that X is a non-zero ordinary
+ number. The return value for NaN, Infinity or zero is unspecified
+ but does not produce any trap. The behavior of this function for
+ any `mpfr_t' not initialized with `mpfr_custom_init_set' is
+ undefined.
+
+ -- Function: void mpfr_custom_move (mpfr_t X, void *NEW_POSITION)
+ Inform MPFR that the significand of X has moved due to a garbage
+ collect and update its new position to `new_position'. However
+ the application has to move the significand and the `mpfr_t'
+ itself. The behavior of this function for any `mpfr_t' not
+ initialized with `mpfr_custom_init_set' is undefined.
+
+
+File: mpfr.info, Node: Internals, Prev: Custom Interface, Up: MPFR Interface
+
+5.16 Internals
+==============
+
+A "limb" means the part of a multi-precision number that fits in a
+single word. Usually a limb contains 32 or 64 bits. The C data type
+for a limb is `mp_limb_t'.
+
+ The `mpfr_t' type is internally defined as a one-element array of a
+structure, and `mpfr_ptr' is the C data type representing a pointer to
+this structure. The `mpfr_t' type consists of four fields:
+
+ * The `_mpfr_prec' field is used to store the precision of the
+ variable (in bits); this is not less than `MPFR_PREC_MIN'.
+
+ * The `_mpfr_sign' field is used to store the sign of the variable.
+
+ * The `_mpfr_exp' field stores the exponent. An exponent of 0 means
+ a radix point just above the most significant limb. Non-zero
+ values n are a multiplier 2^n relative to that point. A NaN, an
+ infinity and a zero are indicated by special values of the exponent
+ field.
+
+ * Finally, the `_mpfr_d' field is a pointer to the limbs, least
+ significant limbs stored first. The number of limbs in use is
+ controlled by `_mpfr_prec', namely
+ ceil(`_mpfr_prec'/`mp_bits_per_limb'). Non-singular (i.e.,
+ different from NaN, Infinity or zero) values always have the most
+ significant bit of the most significant limb set to 1. When the
+ precision does not correspond to a whole number of limbs, the
+ excess bits at the low end of the data are zeros.
+
+
+
+File: mpfr.info, Node: API Compatibility, Next: Contributors, Prev: MPFR Interface, Up: Top
+
+6 API Compatibility
+*******************
+
+The goal of this section is to describe some API changes that occurred
+from one version of MPFR to another, and how to write code that can be
+compiled and run with older MPFR versions. The minimum MPFR version
+that is considered here is 2.2.0 (released on 20 September 2005).
+
+ API changes can only occur between major or minor versions. Thus the
+patchlevel (the third number in the MPFR version) will be ignored in
+the following. If a program does not use MPFR internals, changes in
+the behavior between two versions differing only by the patchlevel
+should only result from what was regarded as a bug or unspecified
+behavior.
+
+ As a general rule, a program written for some MPFR version should
+work with later versions, possibly except at a new major version, where
+some features (described as obsolete for some time) can be removed. In
+such a case, a failure should occur during compilation or linking. If
+a result becomes incorrect because of such a change, please look at the
+various changes below (they are minimal, and most software should be
+unaffected), at the FAQ and at the MPFR web page for your version (a
+bug could have been introduced and be already fixed); and if the
+problem is not mentioned, please send us a bug report (*note Reporting
+Bugs::).
+
+ However, a program written for the current MPFR version (as
+documented by this manual) may not necessarily work with previous
+versions of MPFR. This section should help developers to write
+portable code.
+
+ Note: Information given here may be incomplete. API changes are
+also described in the NEWS file (for each version, instead of being
+classified like here), together with other changes.
+
+* Menu:
+
+* Type and Macro Changes::
+* Added Functions::
+* Changed Functions::
+* Removed Functions::
+* Other Changes::
+
+
+File: mpfr.info, Node: Type and Macro Changes, Next: Added Functions, Prev: API Compatibility, Up: API Compatibility
+
+6.1 Type and Macro Changes
+==========================
+
+The official type for exponent values changed from `mp_exp_t' to
+`mpfr_exp_t' in MPFR 3.0. The type `mp_exp_t' will remain available as
+it comes from GMP (with a different meaning). These types are
+currently the same (`mpfr_exp_t' is defined as `mp_exp_t' with
+`typedef'), so that programs can still use `mp_exp_t'; but this may
+change in the future. Alternatively, using the following code after
+including `mpfr.h' will work with official MPFR versions, as
+`mpfr_exp_t' was never defined in MPFR 2.x:
+ #if MPFR_VERSION_MAJOR < 3
+ typedef mp_exp_t mpfr_exp_t;
+ #endif
+
+ The official types for precision values and for rounding modes
+respectively changed from `mp_prec_t' and `mp_rnd_t' to `mpfr_prec_t'
+and `mpfr_rnd_t' in MPFR 3.0. This change was actually done a long
+time ago in MPFR, at least since MPFR 2.2.0, with the following code in
+`mpfr.h':
+ #ifndef mp_rnd_t
+ # define mp_rnd_t mpfr_rnd_t
+ #endif
+ #ifndef mp_prec_t
+ # define mp_prec_t mpfr_prec_t
+ #endif
+ This means that it is safe to use the new official types
+`mpfr_prec_t' and `mpfr_rnd_t' in your programs. The types `mp_prec_t'
+and `mp_rnd_t' (defined in MPFR only) may be removed in the future, as
+the prefix `mp_' is reserved by GMP.
+
+ The precision type `mpfr_prec_t' (`mp_prec_t') was unsigned before
+MPFR 3.0; it is now signed. `MPFR_PREC_MAX' has not changed, though.
+Indeed the MPFR code requires that `MPFR_PREC_MAX' be representable in
+the exponent type, which may have the same size as `mpfr_prec_t' but
+has always been signed. The consequence is that valid code that does
+not assume anything about the signedness of `mpfr_prec_t' should work
+with past and new MPFR versions. This change was useful as the use of
+unsigned types tends to convert signed values to unsigned ones in
+expressions due to the usual arithmetic conversions, which can yield
+incorrect results if a negative value is converted in such a way.
+Warning! A program assuming (intentionally or not) that `mpfr_prec_t'
+is signed may be affected by this problem when it is built and run
+against MPFR 2.x.
+
+ The rounding modes `GMP_RNDx' were renamed to `MPFR_RNDx' in MPFR
+3.0. However the old names `GMP_RNDx' have been kept for compatibility
+(this might change in future versions), using:
+ #define GMP_RNDN MPFR_RNDN
+ #define GMP_RNDZ MPFR_RNDZ
+ #define GMP_RNDU MPFR_RNDU
+ #define GMP_RNDD MPFR_RNDD
+ The rounding mode "round away from zero" (`MPFR_RNDA') was added in
+MPFR 3.0 (however no rounding mode `GMP_RNDA' exists).
+
+
+File: mpfr.info, Node: Added Functions, Next: Changed Functions, Prev: Type and Macro Changes, Up: API Compatibility
+
+6.2 Added Functions
+===================
+
+We give here in alphabetical order the functions that were added after
+MPFR 2.2, and in which MPFR version.
+
+ * `mpfr_add_d' in MPFR 2.4.
+
+ * `mpfr_ai' in MPFR 3.0 (incomplete, experimental).
+
+ * `mpfr_asprintf' in MPFR 2.4.
+
+ * `mpfr_buildopt_decimal_p' and `mpfr_buildopt_tls_p' in MPFR 3.0.
+
+ * `mpfr_buildopt_gmpinternals_p' and `mpfr_buildopt_tune_case' in
+ MPFR 3.1.
+
+ * `mpfr_clear_divby0' in MPFR 3.1 (new divide-by-zero exception).
+
+ * `mpfr_copysign' in MPFR 2.3. Note: MPFR 2.2 had a `mpfr_copysign'
+ function that was available, but not documented, and with a slight
+ difference in the semantics (when the second input operand is a
+ NaN).
+
+ * `mpfr_custom_get_significand' in MPFR 3.0. This function was
+ named `mpfr_custom_get_mantissa' in previous versions;
+ `mpfr_custom_get_mantissa' is still available via a macro in
+ `mpfr.h':
+ #define mpfr_custom_get_mantissa mpfr_custom_get_significand
+ Thus code that needs to work with both MPFR 2.x and MPFR 3.x should
+ use `mpfr_custom_get_mantissa'.
+
+ * `mpfr_d_div' and `mpfr_d_sub' in MPFR 2.4.
+
+ * `mpfr_digamma' in MPFR 3.0.
+
+ * `mpfr_divby0_p' in MPFR 3.1 (new divide-by-zero exception).
+
+ * `mpfr_div_d' in MPFR 2.4.
+
+ * `mpfr_fmod' in MPFR 2.4.
+
+ * `mpfr_fms' in MPFR 2.3.
+
+ * `mpfr_fprintf' in MPFR 2.4.
+
+ * `mpfr_frexp' in MPFR 3.1.
+
+ * `mpfr_get_flt' in MPFR 3.0.
+
+ * `mpfr_get_patches' in MPFR 2.3.
+
+ * `mpfr_get_z_2exp' in MPFR 3.0. This function was named
+ `mpfr_get_z_exp' in previous versions; `mpfr_get_z_exp' is still
+ available via a macro in `mpfr.h':
+ #define mpfr_get_z_exp mpfr_get_z_2exp
+ Thus code that needs to work with both MPFR 2.x and MPFR 3.x should
+ use `mpfr_get_z_exp'.
+
+ * `mpfr_grandom' in MPFR 3.1.
+
+ * `mpfr_j0', `mpfr_j1' and `mpfr_jn' in MPFR 2.3.
+
+ * `mpfr_lgamma' in MPFR 2.3.
+
+ * `mpfr_li2' in MPFR 2.4.
+
+ * `mpfr_min_prec' in MPFR 3.0.
+
+ * `mpfr_modf' in MPFR 2.4.
+
+ * `mpfr_mul_d' in MPFR 2.4.
+
+ * `mpfr_printf' in MPFR 2.4.
+
+ * `mpfr_rec_sqrt' in MPFR 2.4.
+
+ * `mpfr_regular_p' in MPFR 3.0.
+
+ * `mpfr_remainder' and `mpfr_remquo' in MPFR 2.3.
+
+ * `mpfr_set_divby0' in MPFR 3.1 (new divide-by-zero exception).
+
+ * `mpfr_set_flt' in MPFR 3.0.
+
+ * `mpfr_set_z_2exp' in MPFR 3.0.
+
+ * `mpfr_set_zero' in MPFR 3.0.
+
+ * `mpfr_setsign' in MPFR 2.3.
+
+ * `mpfr_signbit' in MPFR 2.3.
+
+ * `mpfr_sinh_cosh' in MPFR 2.4.
+
+ * `mpfr_snprintf' and `mpfr_sprintf' in MPFR 2.4.
+
+ * `mpfr_sub_d' in MPFR 2.4.
+
+ * `mpfr_urandom' in MPFR 3.0.
+
+ * `mpfr_vasprintf', `mpfr_vfprintf', `mpfr_vprintf',
+ `mpfr_vsprintf' and `mpfr_vsnprintf' in MPFR 2.4.
+
+ * `mpfr_y0', `mpfr_y1' and `mpfr_yn' in MPFR 2.3.
+
+ * `mpfr_z_sub' in MPFR 3.1.
+
+
+
+File: mpfr.info, Node: Changed Functions, Next: Removed Functions, Prev: Added Functions, Up: API Compatibility
+
+6.3 Changed Functions
+=====================
+
+The following functions have changed after MPFR 2.2. Changes can affect
+the behavior of code written for some MPFR version when built and run
+against another MPFR version (older or newer), as described below.
+
+ * `mpfr_check_range' changed in MPFR 2.3.2 and MPFR 2.4. If the
+ value is an inexact infinity, the overflow flag is now set (in
+ case it was lost), while it was previously left unchanged. This
+ is really what is expected in practice (and what the MPFR code was
+ expecting), so that the previous behavior was regarded as a bug.
+ Hence the change in MPFR 2.3.2.
+
+ * `mpfr_get_f' changed in MPFR 3.0. This function was returning
+ zero, except for NaN and Inf, which do not exist in MPF. The
+ _erange_ flag is now set in these cases, and `mpfr_get_f' now
+ returns the usual ternary value.
+
+ * `mpfr_get_si', `mpfr_get_sj', `mpfr_get_ui' and `mpfr_get_uj'
+ changed in MPFR 3.0. In previous MPFR versions, the cases where
+ the _erange_ flag is set were unspecified.
+
+ * `mpfr_get_z' changed in MPFR 3.0. The return type was `void'; it
+ is now `int', and the usual ternary value is returned. Thus
+ programs that need to work with both MPFR 2.x and 3.x must not use
+ the return value. Even in this case, C code using `mpfr_get_z' as
+ the second or third term of a conditional operator may also be
+ affected. For instance, the following is correct with MPFR 3.0,
+ but not with MPFR 2.x:
+ bool ? mpfr_get_z(...) : mpfr_add(...);
+ On the other hand, the following is correct with MPFR 2.x, but not
+ with MPFR 3.0:
+ bool ? mpfr_get_z(...) : (void) mpfr_add(...);
+ Portable code should cast `mpfr_get_z(...)' to `void' to use the
+ type `void' for both terms of the conditional operator, as in:
+ bool ? (void) mpfr_get_z(...) : (void) mpfr_add(...);
+ Alternatively, `if ... else' can be used instead of the
+ conditional operator.
+
+ Moreover the cases where the _erange_ flag is set were unspecified
+ in MPFR 2.x.
+
+ * `mpfr_get_z_exp' changed in MPFR 3.0. In previous MPFR versions,
+ the cases where the _erange_ flag is set were unspecified. Note:
+ this function has been renamed to `mpfr_get_z_2exp' in MPFR 3.0,
+ but `mpfr_get_z_exp' is still available for compatibility reasons.
+
+ * `mpfr_strtofr' changed in MPFR 2.3.1 and MPFR 2.4. This was
+ actually a bug fix since the code and the documentation did not
+ match. But both were changed in order to have a more consistent
+ and useful behavior. The main changes in the code are as follows.
+ The binary exponent is now accepted even without the `0b' or `0x'
+ prefix. Data corresponding to NaN can now have an optional sign
+ (such data were previously invalid).
+
+ * `mpfr_strtofr' changed in MPFR 3.0. This function now accepts
+ bases from 37 to 62 (no changes for the other bases). Note: if an
+ unsupported base is provided to this function, the behavior is
+ undefined; more precisely, in MPFR 2.3.1 and later, providing an
+ unsupported base yields an assertion failure (this behavior may
+ change in the future).
+
+ * `mpfr_subnormalize' changed in MPFR 3.1. This was actually
+ regarded as a bug fix. The `mpfr_subnormalize' implementation up
+ to MPFR 3.0.0 did not change the flags. In particular, it did not
+ follow the generic rule concerning the inexact flag (and no
+ special behavior was specified). The case of the underflow flag
+ was more a lack of specification.
+
+ * `mpfr_urandom' and `mpfr_urandomb' changed in MPFR 3.1. Their
+ behavior no longer depends on the platform (assuming this is also
+ true for GMP's random generator, which is not the case between GMP
+ 4.1 and 4.2 if `gmp_randinit_default' is used). As a consequence,
+ the returned values can be different between MPFR 3.1 and previous
+ MPFR versions. Note: as the reproducibility of these functions
+ was not specified before MPFR 3.1, the MPFR 3.1 behavior is _not_
+ regarded as backward incompatible with previous versions.
+
+
+
+File: mpfr.info, Node: Removed Functions, Next: Other Changes, Prev: Changed Functions, Up: API Compatibility
+
+6.4 Removed Functions
+=====================
+
+Functions `mpfr_random' and `mpfr_random2' have been removed in MPFR
+3.0 (this only affects old code built against MPFR 3.0 or later). (The
+function `mpfr_random' had been deprecated since at least MPFR 2.2.0,
+and `mpfr_random2' since MPFR 2.4.0.)
+
+
+File: mpfr.info, Node: Other Changes, Prev: Removed Functions, Up: API Compatibility
+
+6.5 Other Changes
+=================
+
+For users of a C++ compiler, the way how the availability of `intmax_t'
+is detected has changed in MPFR 3.0. In MPFR 2.x, if a macro
+`INTMAX_C' or `UINTMAX_C' was defined (e.g. when the
+`__STDC_CONSTANT_MACROS' macro had been defined before `<stdint.h>' or
+`<inttypes.h>' has been included), `intmax_t' was assumed to be defined.
+However this was not always the case (more precisely, `intmax_t' can be
+defined only in the namespace `std', as with Boost), so that
+compilations could fail. Thus the check for `INTMAX_C' or `UINTMAX_C'
+is now disabled for C++ compilers, with the following consequences:
+
+ * Programs written for MPFR 2.x that need `intmax_t' may no longer
+ be compiled against MPFR 3.0: a `#define MPFR_USE_INTMAX_T' may be
+ necessary before `mpfr.h' is included.
+
+ * The compilation of programs that work with MPFR 3.0 may fail with
+ MPFR 2.x due to the problem described above. Workarounds are
+ possible, such as defining `intmax_t' and `uintmax_t' in the global
+ namespace, though this is not clean.
+
+
+ The divide-by-zero exception is new in MPFR 3.1. However it should
+not introduce incompatible changes for programs that strictly follow
+the MPFR API since the exception can only be seen via new functions.
+
+ As of MPFR 3.1, the `mpfr.h' header can be included several times,
+while still supporting optional functions (*note Headers and
+Libraries::).
+
+
+File: mpfr.info, Node: Contributors, Next: References, Prev: API Compatibility, Up: Top
+
+Contributors
+************
+
+The main developers of MPFR are Guillaume Hanrot, Vincent Lefèvre,
+Patrick Pélissier, Philippe Théveny and Paul Zimmermann.
+
+ Sylvie Boldo from ENS-Lyon, France, contributed the functions
+`mpfr_agm' and `mpfr_log'. Sylvain Chevillard contributed the
+`mpfr_ai' function. David Daney contributed the hyperbolic and inverse
+hyperbolic functions, the base-2 exponential, and the factorial
+function. Alain Delplanque contributed the new version of the
+`mpfr_get_str' function. Mathieu Dutour contributed the functions
+`mpfr_acos', `mpfr_asin' and `mpfr_atan', and a previous version of
+`mpfr_gamma'. Laurent Fousse contributed the `mpfr_sum' function.
+Emmanuel Jeandel, from ENS-Lyon too, contributed the generic
+hypergeometric code, as well as the internal function `mpfr_exp3', a
+first implementation of the sine and cosine, and improved versions of
+`mpfr_const_log2' and `mpfr_const_pi'. Ludovic Meunier helped in the
+design of the `mpfr_erf' code. Jean-Luc Rémy contributed the
+`mpfr_zeta' code. Fabrice Rouillier contributed the `mpfr_xxx_z' and
+`mpfr_xxx_q' functions, and helped to the Microsoft Windows porting.
+Damien Stehlé contributed the `mpfr_get_ld_2exp' function.
+
+ We would like to thank Jean-Michel Muller and Joris van der Hoeven
+for very fruitful discussions at the beginning of that project,
+Torbjörn Granlund and Kevin Ryde for their help about design issues,
+and Nathalie Revol for her careful reading of a previous version of
+this documentation. In particular Kevin Ryde did a tremendous job for
+the portability of MPFR in 2002-2004.
+
+ The development of the MPFR library would not have been possible
+without the continuous support of INRIA, and of the LORIA (Nancy,
+France) and LIP (Lyon, France) laboratories. In particular the main
+authors were or are members of the PolKA, Spaces, Cacao and Caramel
+project-teams at LORIA and of the Arénaire and AriC project-teams at
+LIP. This project was started during the Fiable (reliable in French)
+action supported by INRIA, and continued during the AOC action. The
+development of MPFR was also supported by a grant (202F0659 00 MPN 121)
+from the Conseil Régional de Lorraine in 2002, from INRIA by an
+"associate engineer" grant (2003-2005), an "opération de développement
+logiciel" grant (2007-2009), and the post-doctoral grant of Sylvain
+Chevillard in 2009-2010. The MPFR-MPC workshop in June 2012 was partly
+supported by the ERC grant ANTICS of Andreas Enge.
+
+
+File: mpfr.info, Node: References, Next: GNU Free Documentation License, Prev: Contributors, Up: Top
+
+References
+**********
+
+ * Richard Brent and Paul Zimmermann, "Modern Computer Arithmetic",
+ Cambridge University Press (to appear), also available from the
+ authors' web pages.
+
+ * Laurent Fousse, Guillaume Hanrot, Vincent Lefèvre, Patrick
+ Pélissier and Paul Zimmermann, "MPFR: A Multiple-Precision Binary
+ Floating-Point Library With Correct Rounding", ACM Transactions on
+ Mathematical Software, volume 33, issue 2, article 13, 15 pages,
+ 2007, `http://doi.acm.org/10.1145/1236463.1236468'.
+
+ * Torbjörn Granlund, "GNU MP: The GNU Multiple Precision Arithmetic
+ Library", version 5.0.1, 2010, `http://gmplib.org'.
+
+ * IEEE standard for binary floating-point arithmetic, Technical
+ Report ANSI-IEEE Standard 754-1985, New York, 1985. Approved
+ March 21, 1985: IEEE Standards Board; approved July 26, 1985:
+ American National Standards Institute, 18 pages.
+
+ * IEEE Standard for Floating-Point Arithmetic, ANSI-IEEE Standard
+ 754-2008, 2008. Revision of ANSI-IEEE Standard 754-1985, approved
+ June 12, 2008: IEEE Standards Board, 70 pages.
+
+ * Donald E. Knuth, "The Art of Computer Programming", vol 2,
+ "Seminumerical Algorithms", 2nd edition, Addison-Wesley, 1981.
+
+ * Jean-Michel Muller, "Elementary Functions, Algorithms and
+ Implementation", Birkhäuser, Boston, 2nd edition, 2006.
+
+ * Jean-Michel Muller, Nicolas Brisebarre, Florent de Dinechin,
+ Claude-Pierre Jeannerod, Vincent Lefèvre, Guillaume Melquiond,
+ Nathalie Revol, Damien Stehlé and Serge Torrès, "Handbook of
+ Floating-Point Arithmetic", Birkhäuser, Boston, 2009.
+
+
+
+File: mpfr.info, Node: GNU Free Documentation License, Next: Concept Index, Prev: References, Up: Top
+
+Appendix A GNU Free Documentation License
+*****************************************
+
+ Version 1.2, November 2002
+
+ Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML or
+ XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of
+ previous versions (which should, if there were any, be listed
+ in the History section of the Document). You may use the
+ same title as a previous version if the original publisher of
+ that version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on
+ the Title Page. If there is no section Entitled "History" in
+ the Document, create one stating the title, year, authors,
+ and publisher of the Document as given on its Title Page,
+ then add an item describing the Modified Version as stated in
+ the previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a
+ work that was published at least four years before the
+ Document itself, or if the original publisher of the version
+ it refers to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the
+ section all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section
+ titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided for under this License. Any other
+ attempt to copy, modify, sublicense or distribute the Document is
+ void, and will automatically terminate your rights under this
+ License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses
+ terminated so long as such parties remain in full compliance.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ `http://www.gnu.org/copyleft/'.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation.
+
+A.1 ADDENDUM: How to Use This License For Your Documents
+========================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+
+File: mpfr.info, Node: Concept Index, Next: Function and Type Index, Prev: GNU Free Documentation License, Up: Top
+
+Concept Index
+*************
+
+
+* Menu:
+
+* Accuracy: MPFR Interface. (line 25)
+* Arithmetic functions: Basic Arithmetic Functions.
+ (line 3)
+* Assignment functions: Assignment Functions. (line 3)
+* Basic arithmetic functions: Basic Arithmetic Functions.
+ (line 3)
+* Combined initialization and assignment functions: Combined Initialization and Assignment Functions.
+ (line 3)
+* Comparison functions: Comparison Functions. (line 3)
+* Compatibility with MPF: Compatibility with MPF.
+ (line 3)
+* Conditions for copying MPFR: Copying. (line 6)
+* Conversion functions: Conversion Functions. (line 3)
+* Copying conditions: Copying. (line 6)
+* Custom interface: Custom Interface. (line 3)
+* Exception related functions: Exception Related Functions.
+ (line 3)
+* Float arithmetic functions: Basic Arithmetic Functions.
+ (line 3)
+* Float comparisons functions: Comparison Functions. (line 3)
+* Float functions: MPFR Interface. (line 6)
+* Float input and output functions: Input and Output Functions.
+ (line 3)
+* Float output functions: Formatted Output Functions.
+ (line 3)
+* Floating-point functions: MPFR Interface. (line 6)
+* Floating-point number: Nomenclature and Types.
+ (line 6)
+* GNU Free Documentation License: GNU Free Documentation License.
+ (line 6)
+* I/O functions <1>: Formatted Output Functions.
+ (line 3)
+* I/O functions: Input and Output Functions.
+ (line 3)
+* Initialization functions: Initialization Functions.
+ (line 3)
+* Input functions: Input and Output Functions.
+ (line 3)
+* Installation: Installing MPFR. (line 6)
+* Integer related functions: Integer Related Functions.
+ (line 3)
+* Internals: Internals. (line 3)
+* intmax_t: Headers and Libraries.
+ (line 22)
+* inttypes.h: Headers and Libraries.
+ (line 22)
+* libmpfr: Headers and Libraries.
+ (line 50)
+* Libraries: Headers and Libraries.
+ (line 50)
+* Libtool: Headers and Libraries.
+ (line 56)
+* Limb: Internals. (line 6)
+* Linking: Headers and Libraries.
+ (line 50)
+* Miscellaneous float functions: Miscellaneous Functions.
+ (line 3)
+* mpfr.h: Headers and Libraries.
+ (line 6)
+* Output functions <1>: Formatted Output Functions.
+ (line 3)
+* Output functions: Input and Output Functions.
+ (line 3)
+* Precision <1>: MPFR Interface. (line 17)
+* Precision: Nomenclature and Types.
+ (line 20)
+* Reporting bugs: Reporting Bugs. (line 6)
+* Rounding mode related functions: Rounding Related Functions.
+ (line 3)
+* Rounding Modes: Nomenclature and Types.
+ (line 34)
+* Special functions: Special Functions. (line 3)
+* stdarg.h: Headers and Libraries.
+ (line 19)
+* stdint.h: Headers and Libraries.
+ (line 22)
+* stdio.h: Headers and Libraries.
+ (line 12)
+* Ternary value: Rounding Modes. (line 29)
+* uintmax_t: Headers and Libraries.
+ (line 22)
+
+
+File: mpfr.info, Node: Function and Type Index, Prev: Concept Index, Up: Top
+
+Function and Type Index
+***********************
+
+
+* Menu:
+
+* mpfr_abs: Basic Arithmetic Functions.
+ (line 175)
+* mpfr_acos: Special Functions. (line 52)
+* mpfr_acosh: Special Functions. (line 136)
+* mpfr_add: Basic Arithmetic Functions.
+ (line 8)
+* mpfr_add_d: Basic Arithmetic Functions.
+ (line 14)
+* mpfr_add_q: Basic Arithmetic Functions.
+ (line 18)
+* mpfr_add_si: Basic Arithmetic Functions.
+ (line 12)
+* mpfr_add_ui: Basic Arithmetic Functions.
+ (line 10)
+* mpfr_add_z: Basic Arithmetic Functions.
+ (line 16)
+* mpfr_agm: Special Functions. (line 232)
+* mpfr_ai: Special Functions. (line 248)
+* mpfr_asin: Special Functions. (line 53)
+* mpfr_asinh: Special Functions. (line 137)
+* mpfr_asprintf: Formatted Output Functions.
+ (line 194)
+* mpfr_atan: Special Functions. (line 54)
+* mpfr_atan2: Special Functions. (line 65)
+* mpfr_atanh: Special Functions. (line 138)
+* mpfr_buildopt_decimal_p: Miscellaneous Functions.
+ (line 163)
+* mpfr_buildopt_gmpinternals_p: Miscellaneous Functions.
+ (line 168)
+* mpfr_buildopt_tls_p: Miscellaneous Functions.
+ (line 157)
+* mpfr_buildopt_tune_case: Miscellaneous Functions.
+ (line 173)
+* mpfr_can_round: Rounding Related Functions.
+ (line 37)
+* mpfr_cbrt: Basic Arithmetic Functions.
+ (line 109)
+* mpfr_ceil: Integer Related Functions.
+ (line 8)
+* mpfr_check_range: Exception Related Functions.
+ (line 38)
+* mpfr_clear: Initialization Functions.
+ (line 31)
+* mpfr_clear_divby0: Exception Related Functions.
+ (line 113)
+* mpfr_clear_erangeflag: Exception Related Functions.
+ (line 116)
+* mpfr_clear_flags: Exception Related Functions.
+ (line 129)
+* mpfr_clear_inexflag: Exception Related Functions.
+ (line 115)
+* mpfr_clear_nanflag: Exception Related Functions.
+ (line 114)
+* mpfr_clear_overflow: Exception Related Functions.
+ (line 112)
+* mpfr_clear_underflow: Exception Related Functions.
+ (line 111)
+* mpfr_clears: Initialization Functions.
+ (line 36)
+* mpfr_cmp: Comparison Functions.
+ (line 7)
+* mpfr_cmp_d: Comparison Functions.
+ (line 10)
+* mpfr_cmp_f: Comparison Functions.
+ (line 14)
+* mpfr_cmp_ld: Comparison Functions.
+ (line 11)
+* mpfr_cmp_q: Comparison Functions.
+ (line 13)
+* mpfr_cmp_si: Comparison Functions.
+ (line 9)
+* mpfr_cmp_si_2exp: Comparison Functions.
+ (line 31)
+* mpfr_cmp_ui: Comparison Functions.
+ (line 8)
+* mpfr_cmp_ui_2exp: Comparison Functions.
+ (line 29)
+* mpfr_cmp_z: Comparison Functions.
+ (line 12)
+* mpfr_cmpabs: Comparison Functions.
+ (line 35)
+* mpfr_const_catalan: Special Functions. (line 259)
+* mpfr_const_euler: Special Functions. (line 258)
+* mpfr_const_log2: Special Functions. (line 256)
+* mpfr_const_pi: Special Functions. (line 257)
+* mpfr_copysign: Miscellaneous Functions.
+ (line 111)
+* mpfr_cos: Special Functions. (line 30)
+* mpfr_cosh: Special Functions. (line 115)
+* mpfr_cot: Special Functions. (line 48)
+* mpfr_coth: Special Functions. (line 132)
+* mpfr_csc: Special Functions. (line 47)
+* mpfr_csch: Special Functions. (line 131)
+* mpfr_custom_get_exp: Custom Interface. (line 78)
+* mpfr_custom_get_kind: Custom Interface. (line 67)
+* mpfr_custom_get_significand: Custom Interface. (line 72)
+* mpfr_custom_get_size: Custom Interface. (line 36)
+* mpfr_custom_init: Custom Interface. (line 41)
+* mpfr_custom_init_set: Custom Interface. (line 48)
+* mpfr_custom_move: Custom Interface. (line 85)
+* mpfr_d_div: Basic Arithmetic Functions.
+ (line 84)
+* mpfr_d_sub: Basic Arithmetic Functions.
+ (line 37)
+* MPFR_DECL_INIT: Initialization Functions.
+ (line 75)
+* mpfr_digamma: Special Functions. (line 187)
+* mpfr_dim: Basic Arithmetic Functions.
+ (line 182)
+* mpfr_div: Basic Arithmetic Functions.
+ (line 74)
+* mpfr_div_2exp: Compatibility with MPF.
+ (line 51)
+* mpfr_div_2si: Basic Arithmetic Functions.
+ (line 197)
+* mpfr_div_2ui: Basic Arithmetic Functions.
+ (line 195)
+* mpfr_div_d: Basic Arithmetic Functions.
+ (line 86)
+* mpfr_div_q: Basic Arithmetic Functions.
+ (line 90)
+* mpfr_div_si: Basic Arithmetic Functions.
+ (line 82)
+* mpfr_div_ui: Basic Arithmetic Functions.
+ (line 78)
+* mpfr_div_z: Basic Arithmetic Functions.
+ (line 88)
+* mpfr_divby0_p: Exception Related Functions.
+ (line 135)
+* mpfr_eint: Special Functions. (line 154)
+* mpfr_eq: Compatibility with MPF.
+ (line 30)
+* mpfr_equal_p: Comparison Functions.
+ (line 61)
+* mpfr_erangeflag_p: Exception Related Functions.
+ (line 138)
+* mpfr_erf: Special Functions. (line 198)
+* mpfr_erfc: Special Functions. (line 199)
+* mpfr_exp: Special Functions. (line 24)
+* mpfr_exp10: Special Functions. (line 26)
+* mpfr_exp2: Special Functions. (line 25)
+* mpfr_expm1: Special Functions. (line 150)
+* mpfr_fac_ui: Special Functions. (line 143)
+* mpfr_fits_intmax_p: Conversion Functions.
+ (line 146)
+* mpfr_fits_sint_p: Conversion Functions.
+ (line 142)
+* mpfr_fits_slong_p: Conversion Functions.
+ (line 140)
+* mpfr_fits_sshort_p: Conversion Functions.
+ (line 144)
+* mpfr_fits_uint_p: Conversion Functions.
+ (line 141)
+* mpfr_fits_uintmax_p: Conversion Functions.
+ (line 145)
+* mpfr_fits_ulong_p: Conversion Functions.
+ (line 139)
+* mpfr_fits_ushort_p: Conversion Functions.
+ (line 143)
+* mpfr_floor: Integer Related Functions.
+ (line 9)
+* mpfr_fma: Special Functions. (line 225)
+* mpfr_fmod: Integer Related Functions.
+ (line 79)
+* mpfr_fms: Special Functions. (line 227)
+* mpfr_fprintf: Formatted Output Functions.
+ (line 158)
+* mpfr_frac: Integer Related Functions.
+ (line 62)
+* mpfr_free_cache: Special Functions. (line 266)
+* mpfr_free_str: Conversion Functions.
+ (line 133)
+* mpfr_frexp: Conversion Functions.
+ (line 47)
+* mpfr_gamma: Special Functions. (line 169)
+* mpfr_get_d: Conversion Functions.
+ (line 8)
+* mpfr_get_d_2exp: Conversion Functions.
+ (line 34)
+* mpfr_get_decimal64: Conversion Functions.
+ (line 10)
+* mpfr_get_default_prec: Initialization Functions.
+ (line 114)
+* mpfr_get_default_rounding_mode: Rounding Related Functions.
+ (line 11)
+* mpfr_get_emax: Exception Related Functions.
+ (line 8)
+* mpfr_get_emax_max: Exception Related Functions.
+ (line 31)
+* mpfr_get_emax_min: Exception Related Functions.
+ (line 30)
+* mpfr_get_emin: Exception Related Functions.
+ (line 7)
+* mpfr_get_emin_max: Exception Related Functions.
+ (line 29)
+* mpfr_get_emin_min: Exception Related Functions.
+ (line 28)
+* mpfr_get_exp: Miscellaneous Functions.
+ (line 89)
+* mpfr_get_f: Conversion Functions.
+ (line 73)
+* mpfr_get_flt: Conversion Functions.
+ (line 7)
+* mpfr_get_ld: Conversion Functions.
+ (line 9)
+* mpfr_get_ld_2exp: Conversion Functions.
+ (line 36)
+* mpfr_get_patches: Miscellaneous Functions.
+ (line 148)
+* mpfr_get_prec: Initialization Functions.
+ (line 147)
+* mpfr_get_si: Conversion Functions.
+ (line 20)
+* mpfr_get_sj: Conversion Functions.
+ (line 22)
+* mpfr_get_str: Conversion Functions.
+ (line 87)
+* mpfr_get_ui: Conversion Functions.
+ (line 21)
+* mpfr_get_uj: Conversion Functions.
+ (line 23)
+* mpfr_get_version: Miscellaneous Functions.
+ (line 117)
+* mpfr_get_z: Conversion Functions.
+ (line 68)
+* mpfr_get_z_2exp: Conversion Functions.
+ (line 55)
+* mpfr_grandom: Miscellaneous Functions.
+ (line 65)
+* mpfr_greater_p: Comparison Functions.
+ (line 57)
+* mpfr_greaterequal_p: Comparison Functions.
+ (line 58)
+* mpfr_hypot: Special Functions. (line 241)
+* mpfr_inexflag_p: Exception Related Functions.
+ (line 137)
+* mpfr_inf_p: Comparison Functions.
+ (line 42)
+* mpfr_init: Initialization Functions.
+ (line 54)
+* mpfr_init2: Initialization Functions.
+ (line 11)
+* mpfr_init_set: Combined Initialization and Assignment Functions.
+ (line 7)
+* mpfr_init_set_d: Combined Initialization and Assignment Functions.
+ (line 12)
+* mpfr_init_set_f: Combined Initialization and Assignment Functions.
+ (line 17)
+* mpfr_init_set_ld: Combined Initialization and Assignment Functions.
+ (line 14)
+* mpfr_init_set_q: Combined Initialization and Assignment Functions.
+ (line 16)
+* mpfr_init_set_si: Combined Initialization and Assignment Functions.
+ (line 11)
+* mpfr_init_set_str: Combined Initialization and Assignment Functions.
+ (line 23)
+* mpfr_init_set_ui: Combined Initialization and Assignment Functions.
+ (line 9)
+* mpfr_init_set_z: Combined Initialization and Assignment Functions.
+ (line 15)
+* mpfr_inits: Initialization Functions.
+ (line 63)
+* mpfr_inits2: Initialization Functions.
+ (line 23)
+* mpfr_inp_str: Input and Output Functions.
+ (line 33)
+* mpfr_integer_p: Integer Related Functions.
+ (line 105)
+* mpfr_j0: Special Functions. (line 203)
+* mpfr_j1: Special Functions. (line 204)
+* mpfr_jn: Special Functions. (line 206)
+* mpfr_less_p: Comparison Functions.
+ (line 59)
+* mpfr_lessequal_p: Comparison Functions.
+ (line 60)
+* mpfr_lessgreater_p: Comparison Functions.
+ (line 66)
+* mpfr_lgamma: Special Functions. (line 179)
+* mpfr_li2: Special Functions. (line 164)
+* mpfr_lngamma: Special Functions. (line 173)
+* mpfr_log: Special Functions. (line 17)
+* mpfr_log10: Special Functions. (line 19)
+* mpfr_log1p: Special Functions. (line 146)
+* mpfr_log2: Special Functions. (line 18)
+* mpfr_max: Miscellaneous Functions.
+ (line 24)
+* mpfr_min: Miscellaneous Functions.
+ (line 22)
+* mpfr_min_prec: Rounding Related Functions.
+ (line 59)
+* mpfr_modf: Integer Related Functions.
+ (line 69)
+* mpfr_mul: Basic Arithmetic Functions.
+ (line 53)
+* mpfr_mul_2exp: Compatibility with MPF.
+ (line 49)
+* mpfr_mul_2si: Basic Arithmetic Functions.
+ (line 190)
+* mpfr_mul_2ui: Basic Arithmetic Functions.
+ (line 188)
+* mpfr_mul_d: Basic Arithmetic Functions.
+ (line 59)
+* mpfr_mul_q: Basic Arithmetic Functions.
+ (line 63)
+* mpfr_mul_si: Basic Arithmetic Functions.
+ (line 57)
+* mpfr_mul_ui: Basic Arithmetic Functions.
+ (line 55)
+* mpfr_mul_z: Basic Arithmetic Functions.
+ (line 61)
+* mpfr_nan_p: Comparison Functions.
+ (line 41)
+* mpfr_nanflag_p: Exception Related Functions.
+ (line 136)
+* mpfr_neg: Basic Arithmetic Functions.
+ (line 174)
+* mpfr_nextabove: Miscellaneous Functions.
+ (line 16)
+* mpfr_nextbelow: Miscellaneous Functions.
+ (line 17)
+* mpfr_nexttoward: Miscellaneous Functions.
+ (line 7)
+* mpfr_number_p: Comparison Functions.
+ (line 43)
+* mpfr_out_str: Input and Output Functions.
+ (line 17)
+* mpfr_overflow_p: Exception Related Functions.
+ (line 134)
+* mpfr_pow: Basic Arithmetic Functions.
+ (line 118)
+* mpfr_pow_si: Basic Arithmetic Functions.
+ (line 122)
+* mpfr_pow_ui: Basic Arithmetic Functions.
+ (line 120)
+* mpfr_pow_z: Basic Arithmetic Functions.
+ (line 124)
+* mpfr_prec_round: Rounding Related Functions.
+ (line 15)
+* mpfr_prec_t: Nomenclature and Types.
+ (line 20)
+* mpfr_print_rnd_mode: Rounding Related Functions.
+ (line 66)
+* mpfr_printf: Formatted Output Functions.
+ (line 165)
+* mpfr_rec_sqrt: Basic Arithmetic Functions.
+ (line 104)
+* mpfr_regular_p: Comparison Functions.
+ (line 45)
+* mpfr_reldiff: Compatibility with MPF.
+ (line 41)
+* mpfr_remainder: Integer Related Functions.
+ (line 81)
+* mpfr_remquo: Integer Related Functions.
+ (line 83)
+* mpfr_rint: Integer Related Functions.
+ (line 7)
+* mpfr_rint_ceil: Integer Related Functions.
+ (line 38)
+* mpfr_rint_floor: Integer Related Functions.
+ (line 40)
+* mpfr_rint_round: Integer Related Functions.
+ (line 42)
+* mpfr_rint_trunc: Integer Related Functions.
+ (line 44)
+* mpfr_rnd_t: Nomenclature and Types.
+ (line 34)
+* mpfr_root: Basic Arithmetic Functions.
+ (line 111)
+* mpfr_round: Integer Related Functions.
+ (line 10)
+* mpfr_sec: Special Functions. (line 46)
+* mpfr_sech: Special Functions. (line 130)
+* mpfr_set: Assignment Functions.
+ (line 10)
+* mpfr_set_d: Assignment Functions.
+ (line 17)
+* mpfr_set_decimal64: Assignment Functions.
+ (line 21)
+* mpfr_set_default_prec: Initialization Functions.
+ (line 101)
+* mpfr_set_default_rounding_mode: Rounding Related Functions.
+ (line 7)
+* mpfr_set_divby0: Exception Related Functions.
+ (line 122)
+* mpfr_set_emax: Exception Related Functions.
+ (line 17)
+* mpfr_set_emin: Exception Related Functions.
+ (line 16)
+* mpfr_set_erangeflag: Exception Related Functions.
+ (line 125)
+* mpfr_set_exp: Miscellaneous Functions.
+ (line 94)
+* mpfr_set_f: Assignment Functions.
+ (line 24)
+* mpfr_set_flt: Assignment Functions.
+ (line 16)
+* mpfr_set_inexflag: Exception Related Functions.
+ (line 124)
+* mpfr_set_inf: Assignment Functions.
+ (line 147)
+* mpfr_set_ld: Assignment Functions.
+ (line 19)
+* mpfr_set_nan: Assignment Functions.
+ (line 146)
+* mpfr_set_nanflag: Exception Related Functions.
+ (line 123)
+* mpfr_set_overflow: Exception Related Functions.
+ (line 121)
+* mpfr_set_prec: Initialization Functions.
+ (line 137)
+* mpfr_set_prec_raw: Compatibility with MPF.
+ (line 23)
+* mpfr_set_q: Assignment Functions.
+ (line 23)
+* mpfr_set_si: Assignment Functions.
+ (line 13)
+* mpfr_set_si_2exp: Assignment Functions.
+ (line 53)
+* mpfr_set_sj: Assignment Functions.
+ (line 15)
+* mpfr_set_sj_2exp: Assignment Functions.
+ (line 57)
+* mpfr_set_str: Assignment Functions.
+ (line 65)
+* mpfr_set_ui: Assignment Functions.
+ (line 12)
+* mpfr_set_ui_2exp: Assignment Functions.
+ (line 51)
+* mpfr_set_uj: Assignment Functions.
+ (line 14)
+* mpfr_set_uj_2exp: Assignment Functions.
+ (line 55)
+* mpfr_set_underflow: Exception Related Functions.
+ (line 120)
+* mpfr_set_z: Assignment Functions.
+ (line 22)
+* mpfr_set_z_2exp: Assignment Functions.
+ (line 59)
+* mpfr_set_zero: Assignment Functions.
+ (line 148)
+* mpfr_setsign: Miscellaneous Functions.
+ (line 105)
+* mpfr_sgn: Comparison Functions.
+ (line 51)
+* mpfr_si_div: Basic Arithmetic Functions.
+ (line 80)
+* mpfr_si_sub: Basic Arithmetic Functions.
+ (line 33)
+* mpfr_signbit: Miscellaneous Functions.
+ (line 100)
+* mpfr_sin: Special Functions. (line 31)
+* mpfr_sin_cos: Special Functions. (line 37)
+* mpfr_sinh: Special Functions. (line 116)
+* mpfr_sinh_cosh: Special Functions. (line 122)
+* mpfr_snprintf: Formatted Output Functions.
+ (line 182)
+* mpfr_sprintf: Formatted Output Functions.
+ (line 171)
+* mpfr_sqr: Basic Arithmetic Functions.
+ (line 70)
+* mpfr_sqrt: Basic Arithmetic Functions.
+ (line 97)
+* mpfr_sqrt_ui: Basic Arithmetic Functions.
+ (line 99)
+* mpfr_strtofr: Assignment Functions.
+ (line 83)
+* mpfr_sub: Basic Arithmetic Functions.
+ (line 27)
+* mpfr_sub_d: Basic Arithmetic Functions.
+ (line 39)
+* mpfr_sub_q: Basic Arithmetic Functions.
+ (line 45)
+* mpfr_sub_si: Basic Arithmetic Functions.
+ (line 35)
+* mpfr_sub_ui: Basic Arithmetic Functions.
+ (line 31)
+* mpfr_sub_z: Basic Arithmetic Functions.
+ (line 43)
+* mpfr_subnormalize: Exception Related Functions.
+ (line 61)
+* mpfr_sum: Special Functions. (line 275)
+* mpfr_swap: Assignment Functions.
+ (line 154)
+* mpfr_t: Nomenclature and Types.
+ (line 6)
+* mpfr_tan: Special Functions. (line 32)
+* mpfr_tanh: Special Functions. (line 117)
+* mpfr_trunc: Integer Related Functions.
+ (line 11)
+* mpfr_ui_div: Basic Arithmetic Functions.
+ (line 76)
+* mpfr_ui_pow: Basic Arithmetic Functions.
+ (line 128)
+* mpfr_ui_pow_ui: Basic Arithmetic Functions.
+ (line 126)
+* mpfr_ui_sub: Basic Arithmetic Functions.
+ (line 29)
+* mpfr_underflow_p: Exception Related Functions.
+ (line 133)
+* mpfr_unordered_p: Comparison Functions.
+ (line 71)
+* mpfr_urandom: Miscellaneous Functions.
+ (line 50)
+* mpfr_urandomb: Miscellaneous Functions.
+ (line 30)
+* mpfr_vasprintf: Formatted Output Functions.
+ (line 196)
+* MPFR_VERSION: Miscellaneous Functions.
+ (line 120)
+* MPFR_VERSION_MAJOR: Miscellaneous Functions.
+ (line 121)
+* MPFR_VERSION_MINOR: Miscellaneous Functions.
+ (line 122)
+* MPFR_VERSION_NUM: Miscellaneous Functions.
+ (line 140)
+* MPFR_VERSION_PATCHLEVEL: Miscellaneous Functions.
+ (line 123)
+* MPFR_VERSION_STRING: Miscellaneous Functions.
+ (line 124)
+* mpfr_vfprintf: Formatted Output Functions.
+ (line 160)
+* mpfr_vprintf: Formatted Output Functions.
+ (line 166)
+* mpfr_vsnprintf: Formatted Output Functions.
+ (line 184)
+* mpfr_vsprintf: Formatted Output Functions.
+ (line 173)
+* mpfr_y0: Special Functions. (line 214)
+* mpfr_y1: Special Functions. (line 215)
+* mpfr_yn: Special Functions. (line 217)
+* mpfr_z_sub: Basic Arithmetic Functions.
+ (line 41)
+* mpfr_zero_p: Comparison Functions.
+ (line 44)
+* mpfr_zeta: Special Functions. (line 192)
+* mpfr_zeta_ui: Special Functions. (line 194)
+
+
+
+Tag Table:
+Node: Top892
+Node: Copying2243
+Node: Introduction to MPFR4003
+Node: Installing MPFR6092
+Node: Reporting Bugs10914
+Node: MPFR Basics12843
+Node: Headers and Libraries13159
+Node: Nomenclature and Types16143
+Node: MPFR Variable Conventions18147
+Node: Rounding Modes19677
+Ref: ternary value20774
+Node: Floating-Point Values on Special Numbers22727
+Node: Exceptions25703
+Node: Memory Handling28855
+Node: MPFR Interface29987
+Node: Initialization Functions32083
+Node: Assignment Functions38997
+Node: Combined Initialization and Assignment Functions47651
+Node: Conversion Functions48944
+Node: Basic Arithmetic Functions57496
+Node: Comparison Functions66504
+Node: Special Functions69986
+Node: Input and Output Functions83739
+Node: Formatted Output Functions85662
+Node: Integer Related Functions94781
+Node: Rounding Related Functions100543
+Node: Miscellaneous Functions104157
+Node: Exception Related Functions112724
+Node: Compatibility with MPF119478
+Node: Custom Interface122166
+Node: Internals126411
+Node: API Compatibility127895
+Node: Type and Macro Changes129825
+Node: Added Functions132546
+Node: Changed Functions135489
+Node: Removed Functions139770
+Node: Other Changes140182
+Node: Contributors141711
+Node: References144285
+Node: GNU Free Documentation License146026
+Node: Concept Index168469
+Node: Function and Type Index174388
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/mpfr/doc/mpfr.texi b/mpfr/doc/mpfr.texi
new file mode 100644
index 0000000000..e9b74b1efe
--- /dev/null
+++ b/mpfr/doc/mpfr.texi
@@ -0,0 +1,3658 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename mpfr.info
+@documentencoding UTF-8
+@set VERSION 3.1.2
+@set UPDATED-MONTH March 2013
+@settitle GNU MPFR @value{VERSION}
+@synindex tp fn
+@iftex
+@afourpaper
+@end iftex
+@comment %**end of header
+
+@c Note: avoid using non-ASCII characters directly when possible,
+@c as the "info" utility cannot currently handle them.
+@c http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=212549
+
+@copying
+This manual documents how to install and use the Multiple Precision
+Floating-Point Reliable Library, version @value{VERSION}.
+
+Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document under
+the terms of the GNU Free Documentation License, Version 1.2 or any later
+version published by the Free Software Foundation; with no Invariant Sections,
+with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the
+license is included in @ref{GNU Free Documentation License}.
+@end copying
+
+
+@c Texinfo version 4.2 or up will be needed to process this file.
+@c
+@c A suitable texinfo.tex is supplied, a newer one should work
+@c equally well.
+@c
+@c The edition number is in the VERSION variable above and should be
+@c updated where appropriate. Also, update the month and year in
+@c UPDATED-MONTH.
+
+
+@dircategory Software libraries
+@direntry
+* mpfr: (mpfr). Multiple Precision Floating-Point Reliable Library.
+@end direntry
+
+@c html <meta name=description content="...">
+@documentdescription
+How to install and use GNU MPFR, a library for reliable multiple precision
+floating-point arithmetic, version @value{VERSION}.
+@end documentdescription
+
+@c smallbook
+@finalout
+@setchapternewpage on
+
+@ifnottex
+@node Top, Copying, (dir), (dir)
+@top GNU MPFR
+@end ifnottex
+
+@iftex
+@titlepage
+@title GNU MPFR
+@subtitle The Multiple Precision Floating-Point Reliable Library
+@subtitle Edition @value{VERSION}
+@subtitle @value{UPDATED-MONTH}
+
+@author The MPFR team
+@email{mpfr@@inria.fr}
+
+@c Include the Distribution inside the titlepage so
+@c that headings are turned off.
+
+@tex
+\global\parindent=0pt
+\global\parskip=8pt
+\global\baselineskip=13pt
+@end tex
+
+@page
+@vskip 0pt plus 1filll
+@end iftex
+
+@insertcopying
+@ifnottex
+@sp 1
+@end ifnottex
+
+@iftex
+@end titlepage
+@headings double
+@end iftex
+
+@c Don't bother with contents for html, the menus seem adequate.
+@ifnothtml
+@contents
+@end ifnothtml
+
+@menu
+* Copying:: MPFR Copying Conditions (LGPL).
+* Introduction to MPFR:: Brief introduction to GNU MPFR.
+* Installing MPFR:: How to configure and compile the MPFR library.
+* Reporting Bugs:: How to usefully report bugs.
+* MPFR Basics:: What every MPFR user should now.
+* MPFR Interface:: MPFR functions and macros.
+* API Compatibility:: API compatibility with previous MPFR versions.
+* Contributors::
+* References::
+* GNU Free Documentation License::
+* Concept Index::
+* Function and Type Index::
+@end menu
+
+
+@c @m{T,N} is $T$ in tex or @math{N} otherwise. This is an easy way to give
+@c different forms for math in tex and info. Commas in N or T don't work,
+@c but @C{} can be used instead. \, works in info but not in tex.
+@iftex
+@macro m {T,N}
+@tex$\T\$@end tex
+@end macro
+@end iftex
+@ifnottex
+@macro m {T,N}
+@math{\N\}
+@end macro
+@end ifnottex
+
+@c Usage: @GMPabs{x}
+@c Give either |x| in tex, or abs(x) in info or html.
+@tex
+\gdef\GMPabs#1{|#1|}
+@end tex
+@ifnottex
+@macro GMPabs {X}
+@abs{}(\X\)
+@end macro
+@end ifnottex
+
+@c Usage: @GMPtimes{}
+@c Give either \times or the word "times".
+@tex
+\gdef\GMPtimes{\times}
+@end tex
+@ifnottex
+@macro GMPtimes
+times
+@end macro
+@end ifnottex
+
+@c New math operators.
+@c @abs{} can be used in both tex and info, or just \abs in tex.
+@tex
+\gdef\abs{\mathop{\rm abs}}
+@end tex
+@ifnottex
+@macro abs
+abs
+@end macro
+@end ifnottex
+
+@c @times{} made available as a "*" in info and html (already works in tex).
+@ifnottex
+@macro times
+*
+@end macro
+@end ifnottex
+
+@c Math operators already available in tex, made available in info too.
+@c For example @log{} can be used in both tex and info.
+@ifnottex
+@macro le
+<=
+@end macro
+@macro ge
+>=
+@end macro
+@macro ne
+<>
+@end macro
+@macro log
+log
+@end macro
+@end ifnottex
+
+@c @pom{} definition
+@tex
+\gdef\pom{\ifmmode\pm\else$\pm$\fi}
+@end tex
+@ifnottex
+@macro pom
+±
+@end macro
+@end ifnottex
+
+@c The following macro have been copied from gmp.texi
+@c
+@c Usage: @MPFRpxreftop{info,title}
+@c
+@c Like @pxref{}, but designed for a reference to the top of a document, not
+@c a particular section.
+@c
+@c The texinfo manual recommends putting a likely section name in references
+@c like this, eg. "Introduction", but it seems better to just give the title.
+@c
+@iftex
+@macro MPFRpxreftop{info,title}
+see @cite{\title\}.
+@end macro
+@end iftex
+@ifhtml
+@macro MPFRpxreftop{info,title}
+see @cite{\title\}.
+@end macro
+@end ifhtml
+@ifnottex
+@ifnothtml
+@macro MPFRpxreftop{info,title}
+@pxref{Top,\title\,\title\,\info\,\title\}
+@end macro
+@end ifnothtml
+@end ifnottex
+
+@node Copying, Introduction to MPFR, Top, Top
+@comment node-name, next, previous, up
+@unnumbered MPFR Copying Conditions
+@cindex Copying conditions
+@cindex Conditions for copying MPFR
+
+The GNU MPFR library (or MPFR for short)
+is @dfn{free}; this means that everyone is free to use it and
+free to redistribute it on a free basis. The library is not in the public
+domain; it is copyrighted and there are restrictions on its distribution, but
+these restrictions are designed to permit everything that a good cooperating
+citizen would want to do. What is not allowed is to try to prevent others
+from further sharing any version of this library that they might get from
+you.@refill
+
+Specifically, we want to make sure that you have the right to give away copies
+of the library, that you receive source code or else can get it if you want
+it, that you can change this library or use pieces of it in new free programs,
+and that you know you can do these things.@refill
+
+To make sure that everyone has such rights, we have to forbid you to deprive
+anyone else of these rights. For example, if you distribute copies of the
+GNU MPFR library, you must give the recipients all the rights that you have.
+You must make sure that they, too, receive or can get the source code. And you
+must tell them their rights.@refill
+
+Also, for our own protection, we must make certain that everyone finds out
+that there is no warranty for the GNU MPFR library. If it is modified by
+someone else and passed on, we want their recipients to know that what they
+have is not what we distributed, so that any problems introduced by others
+will not reflect on our reputation.@refill
+
+The precise conditions of the license for the GNU MPFR library are found in the
+Lesser General Public License that accompanies the source code.
+See the file COPYING.LESSER.@refill
+
+@node Introduction to MPFR, Installing MPFR, Copying, Top
+@comment node-name, next, previous, up
+@chapter Introduction to MPFR
+
+
+MPFR is a portable library written in C for arbitrary precision arithmetic
+on floating-point numbers. It is based on the GNU MP library.
+It aims to provide a class of floating-point numbers with
+precise semantics. The main characteristics of MPFR, which make it differ
+from most arbitrary precision floating-point software tools, are:
+
+@itemize @bullet
+@item the MPFR code is portable, i.e., the result of any operation
+does not depend on the machine word size
+@code{mp_bits_per_limb} (64 on most current processors);
+@item the precision in bits can be set @emph{exactly} to any valid value
+for each variable (including very small precision);
+@item MPFR provides the four rounding modes from the IEEE 754-1985
+standard, plus away-from-zero, as well as for basic operations as for other
+mathematical functions.
+@end itemize
+
+In particular, with a precision of 53 bits, MPFR is able to
+exactly reproduce all computations with double-precision machine
+floating-point numbers (e.g., @code{double} type in C, with a C
+implementation that rigorously follows Annex F of the ISO C99 standard
+and @code{FP_CONTRACT} pragma set to @code{OFF}) on the four arithmetic
+operations and the square root, except the default exponent range is much
+wider and subnormal numbers are not implemented (but can be emulated).
+
+This version of MPFR is released under the GNU Lesser General Public
+License, version 3 or any later version.
+It is permitted to link MPFR to most non-free programs, as long as when
+distributing them the MPFR source code and a means to re-link with a
+modified MPFR library is provided.
+
+@section How to Use This Manual
+
+Everyone should read @ref{MPFR Basics}. If you need to install the library
+yourself, you need to read @ref{Installing MPFR}, too.
+To use the library you will need to refer to @ref{MPFR Interface}.
+
+The rest of the manual can be used for later reference, although it is
+probably a good idea to glance through it.
+
+@node Installing MPFR, Reporting Bugs, Introduction to MPFR, Top
+@comment node-name, next, previous, up
+@chapter Installing MPFR
+@cindex Installation
+
+The MPFR library is already installed on some GNU/Linux distributions,
+but the development files necessary to the compilation such as
+@file{mpfr.h} are not always present. To check that MPFR is fully
+installed on your computer, you can check the presence of the file
+@file{mpfr.h} in @file{/usr/include}, or try to compile a small program
+having @code{#include <mpfr.h>} (since @file{mpfr.h} may be installed
+somewhere else). For instance, you can try to compile:
+
+@example
+#include <stdio.h>
+#include <mpfr.h>
+int main (void)
+@{
+ printf ("MPFR library: %-12s\nMPFR header: %s (based on %d.%d.%d)\n",
+ mpfr_get_version (), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR,
+ MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL);
+ return 0;
+@}
+@end example
+
+@noindent
+with
+
+@example
+cc -o version version.c -lmpfr -lgmp
+@end example
+
+@noindent
+and if you get errors whose first line looks like
+
+@example
+version.c:2:19: error: mpfr.h: No such file or directory
+@end example
+
+@noindent
+then MPFR is probably not installed. Running this program will give you
+the MPFR version.
+
+If MPFR is not installed on your computer, or if you want to install a
+different version, please follow the steps below.
+
+@section How to Install
+
+Here are the steps needed to install the library on Unix systems
+(more details are provided in the @file{INSTALL} file):
+
+@enumerate
+@item
+To build MPFR, you first have to install GNU MP
+(version 4.1 or higher) on your computer.
+You need a C compiler, preferably GCC, but any reasonable compiler should
+work. And you need the standard Unix @samp{make} command, plus some other
+standard Unix utility commands.
+
+Then, in the MPFR build directory, type the following commands.
+
+@item
+@samp{./configure}
+
+This will prepare the build and setup the options according to your system.
+You can give options to specify the install directories (instead of
+the default @file{/usr/local}), threading support, and so on. See
+the @file{INSTALL} file and/or the output of @samp{./configure --help}
+for more information, in particular if you get error messages.
+
+@item
+@samp{make}
+
+This will compile MPFR, and create a library archive file @file{libmpfr.a}.
+On most platforms, a dynamic library will be produced too.
+@item
+@samp{make check}
+
+This will make sure MPFR was built correctly.
+If you get error messages, please report this to the MPFR mailing-list
+@samp{mpfr@@inria.fr}. (@xref{Reporting Bugs}, for
+information on what to include in useful bug reports.)
+
+@item
+@samp{make install}
+
+This will copy the files @file{mpfr.h} and @file{mpf2mpfr.h} to the directory
+@file{/usr/local/include}, the library files (@file{libmpfr.a} and possibly
+others) to the directory @file{/usr/local/lib}, the file @file{mpfr.info}
+to the directory @file{/usr/local/share/info}, and some other documentation
+files to the directory @file{/usr/local/share/doc/mpfr} (or if you passed the
+@samp{--prefix} option to @file{configure}, using the prefix directory given
+as argument to @samp{--prefix} instead of @file{/usr/local}).
+@end enumerate
+
+@section Other `make' Targets
+
+There are some other useful make targets:
+
+@itemize @bullet
+@item
+@samp{mpfr.info} or @samp{info}
+
+Create or update an info version of the manual, in @file{mpfr.info}.
+
+This file is already provided in the MPFR archives.
+
+@item
+@samp{mpfr.pdf} or @samp{pdf}
+
+Create a PDF version of the manual, in @file{mpfr.pdf}.
+
+@item
+@samp{mpfr.dvi} or @samp{dvi}
+
+Create a DVI version of the manual, in @file{mpfr.dvi}.
+
+@item
+@samp{mpfr.ps} or @samp{ps}
+
+Create a Postscript version of the manual, in @file{mpfr.ps}.
+
+@item
+@samp{mpfr.html} or @samp{html}
+
+Create a HTML version of the manual, in several pages in the directory
+@file{doc/mpfr.html}; if you want only one output HTML file, then type
+@samp{makeinfo --html --no-split mpfr.texi} from the @samp{doc} directory
+instead.
+
+@item
+@samp{clean}
+
+Delete all object files and archive files, but not the configuration files.
+
+@item
+@samp{distclean}
+
+Delete all generated files not included in the distribution.
+
+@item
+@samp{uninstall}
+
+Delete all files copied by @samp{make install}.
+@end itemize
+
+
+@section Build Problems
+
+In case of problem, please read the @file{INSTALL} file carefully
+before reporting a bug, in particular section ``In case of problem''.
+Some problems are due to bad configuration on the user side (not
+specific to MPFR). Problems are also mentioned in the FAQ
+@url{http://www.mpfr.org/faq.html}.
+
+@comment Warning! Do not split "MPFR ... @url{...}" across several lines
+@comment as this needs to be updated with update-version.
+Please report problems to the MPFR mailing-list @samp{mpfr@@inria.fr}.
+@xref{Reporting Bugs}.
+Some bug fixes are available on the
+MPFR 3.1.2 web page @url{http://www.mpfr.org/mpfr-3.1.2/}.
+
+@section Getting the Latest Version of MPFR
+
+The latest version of MPFR is available from
+@url{ftp://ftp.gnu.org/gnu/mpfr/} or @url{http://www.mpfr.org/}.
+
+@node Reporting Bugs, MPFR Basics, Installing MPFR, Top
+@comment node-name, next, previous, up
+@chapter Reporting Bugs
+@cindex Reporting bugs
+
+@comment Warning! Do not split "MPFR ... @url{...}" across several lines
+@comment as this needs to be updated with update-version.
+If you think you have found a bug in the MPFR library, first have a look
+on the MPFR 3.1.2 web page @url{http://www.mpfr.org/mpfr-3.1.2/} and the
+FAQ @url{http://www.mpfr.org/faq.html}:
+perhaps this bug is already known, in which case you may find there
+a workaround for it.
+You might also look in the archives of the MPFR mailing-list:
+@url{https://sympa.inria.fr/sympa/arc/mpfr}.
+Otherwise, please investigate and report it.
+We have made this library available to you, and it is not to ask too
+much from you, to ask you to report the bugs that you find.
+
+There are a few things you should think about when you put your bug report
+together.
+
+You have to send us a test case that makes it possible for us to reproduce the
+bug, i.e., a small self-content program, using no other library than MPFR.
+Include instructions on how to run the test case.
+
+You also have to explain what is wrong; if you get a crash, or if the results
+you get are incorrect and in that case, in what way.
+
+Please include compiler version information in your bug report. This can
+be extracted using @samp{cc -V} on some machines, or, if you're using GCC,
+@samp{gcc -v}. Also, include the output from @samp{uname -a} and the MPFR
+version (the GMP version may be useful too).
+If you get a failure while running @samp{make} or @samp{make check}, please
+include the @samp{config.log} file in your bug report.
+
+If your bug report is good, we will do our best to help you to get a corrected
+version of the library; if the bug report is poor, we will not do anything
+about it (aside of chiding you to send better bug reports).
+
+Send your bug report to the MPFR mailing-list @samp{mpfr@@inria.fr}.
+
+If you think something in this manual is unclear, or downright incorrect, or if
+the language needs to be improved, please send a note to the same address.
+
+@node MPFR Basics, MPFR Interface, Reporting Bugs, Top
+@comment node-name, next, previous, up
+@chapter MPFR Basics
+
+@menu
+* Headers and Libraries::
+* Nomenclature and Types::
+* MPFR Variable Conventions::
+* Rounding Modes::
+* Floating-Point Values on Special Numbers::
+* Exceptions::
+* Memory Handling::
+@end menu
+
+@node Headers and Libraries, Nomenclature and Types, MPFR Basics, MPFR Basics
+@comment node-name, next, previous, up
+@section Headers and Libraries
+
+@cindex @file{mpfr.h}
+All declarations needed to use MPFR are collected in the include file
+@file{mpfr.h}. It is designed to work with both C and C++ compilers.
+You should include that file in any program using the MPFR library:
+
+@example
+#include <mpfr.h>
+@end example
+
+@cindex @code{stdio.h}
+Note however that prototypes for MPFR functions with @code{FILE *} parameters
+are provided only if @code{<stdio.h>} is included too (before @file{mpfr.h}):
+
+@example
+#include <stdio.h>
+#include <mpfr.h>
+@end example
+
+@cindex @code{stdarg.h}
+Likewise @code{<stdarg.h>} (or @code{<varargs.h>}) is required for prototypes
+with @code{va_list} parameters, such as @code{mpfr_vprintf}.
+
+@cindex @code{stdint.h}
+@cindex @code{inttypes.h}
+@cindex @code{intmax_t}
+@cindex @code{uintmax_t}
+And for any functions using @code{intmax_t}, you must include
+@code{<stdint.h>} or @code{<inttypes.h>} before @file{mpfr.h}, to
+allow @file{mpfr.h} to define prototypes for these functions. Moreover,
+users of C++ compilers under some platforms may need to define
+@code{MPFR_USE_INTMAX_T} (and should do it for portability) before
+@file{mpfr.h} has been included; of course, it is possible to do that
+on the command line, e.g., with @code{-DMPFR_USE_INTMAX_T}.
+
+Note: If @file{mpfr.h} and/or @file{gmp.h} (used by @file{mpfr.h})
+are included several times (possibly from another header file),
+@code{<stdio.h>} and/or @code{<stdarg.h>} (or @code{<varargs.h>})
+should be included @strong{before the first inclusion} of
+@file{mpfr.h} or @file{gmp.h}. Alternatively, you can define
+@code{MPFR_USE_FILE} (for MPFR I/O functions) and/or
+@code{MPFR_USE_VA_LIST} (for MPFR functions with @code{va_list}
+parameters) anywhere before the last inclusion of @file{mpfr.h}.
+As a consequence, if your file is a public header that includes
+@file{mpfr.h}, you need to use the latter method.
+
+When calling a MPFR macro, it is not allowed to have previously defined
+a macro with the same name as some keywords (currently @code{do},
+@code{while} and @code{sizeof}).
+
+You can avoid the use of MPFR macros encapsulating functions by defining
+the @code{MPFR_USE_NO_MACRO} macro before @file{mpfr.h} is included. In
+general this should not be necessary, but this can be useful when debugging
+user code: with some macros, the compiler may emit spurious warnings with
+some warning options, and macros can prevent some prototype checking.
+
+@cindex Libraries
+@cindex Linking
+@cindex @code{libmpfr}
+All programs using MPFR must link against both @file{libmpfr} and
+@file{libgmp} libraries. On a typical Unix-like system this can be
+done with @samp{-lmpfr -lgmp} (in that order), for example:
+
+@example
+gcc myprogram.c -lmpfr -lgmp
+@end example
+
+@cindex Libtool
+MPFR is built using Libtool and an application can use that to link if
+desired, @MPFRpxreftop{libtool.info, GNU Libtool}
+@c Note: the .info extension has been added to avoid the following bug:
+@c http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=484740
+@c which occurs when reading the info file from the build directory:
+@c info ./mpfr or info -f ./mpfr.info
+@c Due to a poor design, the "info" utility will not find the correct
+@c libtool info file if the .info extension is not provided, because of
+@c the "libtool" script in MPFR's directory!
+
+If MPFR has been installed to a non-standard location, then it may be
+necessary to set up environment variables such as @samp{C_INCLUDE_PATH}
+and @samp{LIBRARY_PATH}, or use @samp{-I} and @samp{-L} compiler options,
+in order to point to the right directories. For a shared library, it may
+also be necessary to set up some sort of run-time library path (e.g.,
+@samp{LD_LIBRARY_PATH}) on some systems. Please read the @file{INSTALL}
+file for additional information.
+
+@node Nomenclature and Types, MPFR Variable Conventions, Headers and Libraries, MPFR Basics
+@comment node-name, next, previous, up
+@section Nomenclature and Types
+
+@cindex Floating-point number
+@tindex @code{mpfr_t}
+@noindent
+A @dfn{floating-point number}, or @dfn{float} for short, is an arbitrary
+precision significand (also called mantissa) with a limited precision
+exponent. The C data type
+for such objects is @code{mpfr_t} (internally defined as a one-element
+array of a structure, and @code{mpfr_ptr} is the C data type representing
+a pointer to this structure). A floating-point number can have
+three special values: Not-a-Number (NaN) or plus or minus Infinity. NaN
+represents an uninitialized object, the result of an invalid operation
+(like 0 divided by 0), or a value that cannot be determined (like
++Infinity minus +Infinity). Moreover, like in the IEEE 754 standard,
+zero is signed, i.e., there are both +0 and @minus{}0; the behavior
+is the same as in the IEEE 754 standard and it is generalized to
+the other functions supported by MPFR. Unless documented otherwise,
+the sign bit of a NaN is unspecified.
+@c VL: re-added how mpfr_t is defined, due to some questions from users
+@c in the past (the fact that the result was returned in an argument
+@c seemed strange); also, mpfr_ptr needs to be defined here, as it is
+@c used in the API.
+
+@cindex Precision
+@tindex @code{mpfr_prec_t}
+@noindent
+The @dfn{precision} is the number of bits used to represent the significand
+of a floating-point number;
+the corresponding C data type is @code{mpfr_prec_t}.
+The precision can be any integer between @code{MPFR_PREC_MIN} and
+@code{MPFR_PREC_MAX}. In the current implementation, @code{MPFR_PREC_MIN}
+is equal to 2.
+
+Warning! MPFR needs to increase the precision internally, in order to
+provide accurate results (and in particular, correct rounding). Do not
+attempt to set the precision to any value near @code{MPFR_PREC_MAX},
+otherwise MPFR will abort due to an assertion failure. Moreover, you
+may reach some memory limit on your platform, in which case the program
+may abort, crash or have undefined behavior (depending on your C
+implementation).
+
+@cindex Rounding Modes
+@tindex @code{mpfr_rnd_t}
+@noindent
+The @dfn{rounding mode} specifies the way to round the result of a
+floating-point operation, in case the exact result can not be represented
+exactly in the destination significand;
+the corresponding C data type is @code{mpfr_rnd_t}.
+
+@node MPFR Variable Conventions, Rounding Modes, Nomenclature and Types, MPFR Basics
+@comment node-name, next, previous, up
+@section MPFR Variable Conventions
+
+Before you can assign to an MPFR variable, you need to initialize it by calling
+one of the special initialization functions. When you're done with a
+variable, you need to clear it out, using one of the functions for that
+purpose.
+A variable should only be initialized once, or at least cleared out between
+each initialization. After a variable has been initialized, it may be
+assigned to any number of times.
+For efficiency reasons, avoid to initialize and clear out a variable in loops.
+Instead, initialize it before entering the loop, and clear it out after the
+loop has exited.
+You do not need to be concerned about allocating additional space for MPFR
+variables, since any variable has a significand of fixed size.
+Hence unless you change its precision, or clear and reinitialize it,
+a floating-point variable will have the same allocated space during all its
+life.
+
+As a general rule, all MPFR functions expect output arguments before input
+arguments. This notation is based on an analogy with the assignment operator.
+MPFR allows you to use the same variable for both input and output in the same
+expression. For example, the main function for floating-point multiplication,
+@code{mpfr_mul}, can be used like this: @code{mpfr_mul (x, x, x, rnd)}.
+This
+computes the square of @var{x} with rounding mode @code{rnd}
+and puts the result back in @var{x}.
+
+@node Rounding Modes, Floating-Point Values on Special Numbers, MPFR Variable Conventions, MPFR Basics
+@comment node-name, next, previous, up
+@section Rounding Modes
+
+The following five rounding modes are supported:
+
+@itemize @bullet
+@item @code{MPFR_RNDN}: round to nearest (roundTiesToEven in IEEE 754-2008),
+@item @code{MPFR_RNDZ}: round toward zero (roundTowardZero in IEEE 754-2008),
+@item @code{MPFR_RNDU}: round toward plus infinity (roundTowardPositive in IEEE 754-2008),
+@item @code{MPFR_RNDD}: round toward minus infinity (roundTowardNegative in IEEE 754-2008),
+@item @code{MPFR_RNDA}: round away from zero.
+@end itemize
+
+The @samp{round to nearest} mode works as in the IEEE 754 standard: in
+case the number to be rounded lies exactly in the middle of two representable
+numbers, it is rounded to the one with the least significant bit set to zero.
+For example, the number 2.5, which is represented by (10.1) in binary, is
+rounded to (10.0)=2 with a precision of two bits, and not to (11.0)=3.
+This rule avoids the @dfn{drift} phenomenon mentioned by Knuth in volume 2
+of The Art of Computer Programming (Section 4.2.2).
+
+@anchor{ternary value}@cindex Ternary value
+Most MPFR functions take as first argument the destination variable, as
+second and following arguments the input variables, as last argument a
+rounding mode, and have a return value of type @code{int}, called the
+@dfn{ternary value}. The value stored in the destination variable is
+correctly rounded, i.e., MPFR behaves as if it computed the result with
+an infinite precision, then rounded it to the precision of this variable.
+The input variables are regarded as exact (in particular, their precision
+does not affect the result).
+
+As a consequence, in case of a non-zero real rounded result, the error
+on the result is less or equal to 1/2 ulp (unit in the last place) of
+that result in the rounding to nearest mode, and less than 1 ulp of that
+result in the directed rounding modes (a ulp is the weight of the least
+significant represented bit of the result after rounding).
+@c Since subnormals are not supported, we must take into account the ulp of
+@c the rounded result, not the one of the exact result, for full generality.
+
+Unless documented otherwise, functions returning an @code{int} return
+a ternary value.
+If the ternary value is zero, it means that the value stored in the
+destination variable is the exact result of the corresponding mathematical
+function. If the ternary value is positive (resp.@: negative), it means
+the value stored in the destination variable is greater (resp.@: lower)
+than the exact result. For example with the @code{MPFR_RNDU} rounding mode,
+the ternary value is usually positive, except when the result is exact, in
+which case it is zero. In the case of an infinite result, it is considered
+as inexact when it was obtained by overflow, and exact otherwise. A NaN
+result (Not-a-Number) always corresponds to an exact return value.
+The opposite of a returned ternary value is guaranteed to be representable
+in an @code{int}.
+
+Unless documented otherwise, functions returning as result the value @code{1}
+(or any other value specified in this manual)
+for special cases (like @code{acos(0)}) yield an overflow or
+an underflow if that value is not representable in the current exponent range.
+
+@node Floating-Point Values on Special Numbers, Exceptions, Rounding Modes, MPFR Basics
+@comment node-name, next, previous, up
+@section Floating-Point Values on Special Numbers
+
+This section specifies the floating-point values (of type @code{mpfr_t})
+returned by MPFR functions (where by ``returned'' we mean here the modified
+value of the destination object, which should not be mixed with the ternary
+return value of type @code{int} of those functions).
+For functions returning several values (like
+@code{mpfr_sin_cos}), the rules apply to each result separately.
+
+Functions can have one or several input arguments. An input point is
+a mapping from these input arguments to the set of the MPFR numbers.
+When none of its components are NaN, an input point can also be seen
+as a tuple in the extended real numbers (the set of the real numbers
+with both infinities).
+
+When the input point is in the domain of the mathematical function, the
+result is rounded as described in Section ``Rounding Modes'' (but see
+below for the specification of the sign of an exact zero). Otherwise
+the general rules from this section apply unless stated otherwise in
+the description of the MPFR function (@ref{MPFR Interface}).
+
+When the input point is not in the domain of the mathematical function
+but is in its closure in the extended real numbers and the function can
+be extended by continuity, the result is the obtained limit.
+Examples: @code{mpfr_hypot} on (+Inf,0) gives +Inf. But @code{mpfr_pow}
+cannot be defined on (1,+Inf) using this rule, as one can find
+sequences (@m{x_n,@var{x}_@var{n}},@m{y_n,@var{y}_@var{n}}) such that
+@m{x_n,@var{x}_@var{n}} goes to 1, @m{y_n,@var{y}_@var{n}} goes to +Inf
+and @m{(x_n)^{y_n},@var{x}_@var{n} to the @var{y}_@var{n}} goes to any
+positive value when @var{n} goes to the infinity.
+
+When the input point is in the closure of the domain of the mathematical
+function and an input argument is +0 (resp.@: @minus{}0), one considers
+the limit when the corresponding argument approaches 0 from above
+(resp.@: below). If the limit is not defined (e.g., @code{mpfr_log} on
+@minus{}0), the behavior is specified in the description of the MPFR function.
+
+When the result is equal to 0, its sign is determined by considering the
+limit as if the input point were not in the domain: If one approaches 0
+from above (resp.@: below), the result is +0 (resp.@: @minus{}0);
+for example, @code{mpfr_sin} on +0 gives +0.
+In the other cases, the sign is specified in the description of the MPFR
+function; for example @code{mpfr_max} on @minus{}0 and +0 gives +0.
+
+When the input point is not in the closure of the domain of the function,
+the result is NaN. Example: @code{mpfr_sqrt} on @minus{}17 gives NaN.
+
+When an input argument is NaN, the result is NaN, possibly except when
+a partial function is constant on the finite floating-point numbers;
+such a case is always explicitly specified in @ref{MPFR Interface}.
+@c Said otherwise, if such a case is not specified, this is a bug, thus
+@c we may change the returned value after documenting it without having
+@c to change the libtool interface number (this would have more drawbacks
+@c that advantages in practice), like for any bug fix.
+Example: @code{mpfr_hypot} on (NaN,0) gives NaN, but @code{mpfr_hypot}
+on (NaN,+Inf) gives +Inf (as specified in @ref{Special Functions}),
+since for any finite input @var{x}, @code{mpfr_hypot} on (@var{x},+Inf)
+gives +Inf.
+
+@node Exceptions, Memory Handling, Floating-Point Values on Special Numbers, MPFR Basics
+@comment node-name, next, previous, up
+@section Exceptions
+
+MPFR supports 6 exception types:
+
+@itemize @bullet
+
+@item Underflow:
+An underflow occurs when the exact result of a function is a non-zero
+real number and the result obtained after the rounding, assuming an
+unbounded exponent range (for the rounding), has an exponent smaller
+than the minimum value of the current exponent range. (In the round-to-nearest
+mode, the halfway case is rounded toward zero.)
+
+Note: This is not the single possible definition of the underflow. MPFR chooses
+to consider the underflow @emph{after} rounding. The underflow before rounding
+can also be defined. For instance, consider a function that has the
+exact result @m{7 \times 2^{e-4}, 7 multiplied by two to the power
+@var{e}@minus{}4}, where @var{e} is the smallest exponent (for a
+significand between 1/2 and 1),
+with a 2-bit target precision and rounding toward plus infinity.
+The exact result has the exponent @var{e}@minus{}1. With the underflow
+before rounding, such a function call would yield an underflow, as
+@var{e}@minus{}1 is outside the current exponent range. However, MPFR
+first considers the rounded result assuming an unbounded exponent range.
+The exact result cannot be represented exactly in precision 2, and here,
+it is rounded to @m{0.5 @times 2^e, 0.5 times 2 to @var{e}}, which is
+representable in the current exponent range. As a consequence, this will
+not yield an underflow in MPFR.
+
+@item Overflow:
+An overflow occurs when the exact result of a function is a non-zero
+real number and the result obtained after the rounding, assuming an
+unbounded exponent range (for the rounding), has an exponent larger
+than the maximum value of the current exponent range. In the round-to-nearest
+mode, the result is infinite.
+Note: unlike the underflow case, there is only one possible definition of
+overflow here.
+
+@item Divide-by-zero:
+An exact infinite result is obtained from finite inputs.
+
+@item NaN:
+A NaN exception occurs when the result of a function is NaN.
+@c NaN is defined above. So, we don't say anything more.
+
+@item Inexact:
+An inexact exception occurs when the result of a function cannot be
+represented exactly and must be rounded.
+
+@item Range error:
+A range exception occurs when a function that does not return a MPFR
+number (such as comparisons and conversions to an integer) has an
+invalid result (e.g., an argument is NaN in @code{mpfr_cmp}, or a
+conversion to an integer cannot be represented in the target type).
+
+@end itemize
+
+MPFR has a global flag for each exception, which can be cleared, set
+or tested by functions described in @ref{Exception Related Functions}.
+
+Differences with the ISO C99 standard:
+
+@itemize @bullet
+
+@item In C, only quiet NaNs are specified, and a NaN propagation does not
+raise an invalid exception. Unless explicitly stated otherwise, MPFR sets
+the NaN flag whenever a NaN is generated, even when a NaN is propagated
+(e.g., in NaN + NaN), as if all NaNs were signaling.
+
+@item An invalid exception in C corresponds to either a NaN exception or
+a range error in MPFR.
+
+@end itemize
+
+@node Memory Handling, , Exceptions, MPFR Basics
+@comment node-name, next, previous, up
+@section Memory Handling
+
+MPFR functions may create caches, e.g., when computing constants such
+as @m{\pi,Pi}, either because the user has called a function like
+@code{mpfr_const_pi} directly or because such a function was called
+internally by the MPFR library itself to compute some other function.
+
+At any time, the user can free the various caches with
+@code{mpfr_free_cache}. It is strongly advised to do that before
+terminating a thread, or before exiting when using tools like
+@samp{valgrind} (to avoid memory leaks being reported).
+
+MPFR internal data such as flags, the exponent range, the default
+precision and rounding mode, and caches (i.e., data that are not
+accessed via parameters) are either global (if MPFR has not been
+compiled as thread safe) or per-thread (thread local storage, TLS).
+The initial values of TLS data after a thread is created entirely
+depend on the compiler and thread implementation (MPFR simply does
+a conventional variable initialization, the variables being declared
+with an implementation-defined TLS specifier).
+@c References to TLS specification or documentation can be given here.
+@c Concerning some thread implementations under Unix, POSIX specifies
+@c the thread interface only; TLS variables (with the __thread specifier)
+@c is just a GCC extension. There is currently no clear documentation
+@c about TLS variable initialization.
+
+@node MPFR Interface, API Compatibility, MPFR Basics, Top
+@comment node-name, next, previous, up
+@chapter MPFR Interface
+@cindex Floating-point functions
+@cindex Float functions
+
+The floating-point functions expect arguments of type @code{mpfr_t}.
+
+The MPFR floating-point functions have an interface that is similar to the
+GNU MP
+functions. The function prefix for floating-point operations is @code{mpfr_}.
+
+The user has
+to specify the precision of each variable. A computation that assigns a
+variable will take place with the precision of the assigned variable; the
+cost of that computation should not depend on the
+precision of variables used as input (on average).
+
+@cindex Precision
+The semantics of a calculation in MPFR is specified as follows: Compute the
+requested operation exactly (with ``infinite accuracy''), and round the result
+to the precision of the destination variable, with the given rounding mode.
+The MPFR floating-point functions are intended to be a smooth extension
+of the IEEE 754 arithmetic. The results obtained on a given computer are
+identical to those obtained on a computer with a different word size,
+or with a different compiler or operating system.
+
+@cindex Accuracy
+MPFR @emph{does not keep track} of the accuracy of a computation. This is left
+to the user or to a higher layer (for example the MPFI library for interval
+arithmetic).
+As a consequence, if two variables are used to store
+only a few significant bits, and their product is stored in a variable with large
+precision, then MPFR will still compute the result with full precision.
+
+The value of the standard C macro @code{errno} may be set to non-zero by
+any MPFR function or macro, whether or not there is an error.
+
+@menu
+* Initialization Functions::
+* Assignment Functions::
+* Combined Initialization and Assignment Functions::
+* Conversion Functions::
+* Basic Arithmetic Functions::
+* Comparison Functions::
+* Special Functions::
+* Input and Output Functions::
+* Formatted Output Functions::
+* Integer Related Functions::
+* Rounding Related Functions::
+* Miscellaneous Functions::
+* Exception Related Functions::
+* Compatibility with MPF::
+* Custom Interface::
+* Internals::
+@end menu
+
+@node Initialization Functions, Assignment Functions, MPFR Interface, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Initialization functions
+@section Initialization Functions
+
+An @code{mpfr_t} object must be initialized before storing the first value in
+it. The functions @code{mpfr_init} and @code{mpfr_init2} are used for that
+purpose.
+
+@deftypefun void mpfr_init2 (mpfr_t @var{x}, mpfr_prec_t @var{prec})
+Initialize @var{x}, set its precision to be @strong{exactly}
+@var{prec} bits and its value to NaN. (Warning: the corresponding
+MPF function initializes to zero instead.)
+
+Normally, a variable should be initialized once only or at
+least be cleared, using @code{mpfr_clear}, between initializations.
+To change the precision of a variable which has already been initialized,
+use @code{mpfr_set_prec}.
+The precision @var{prec} must be an integer between @code{MPFR_PREC_MIN} and
+@code{MPFR_PREC_MAX} (otherwise the behavior is undefined).
+@end deftypefun
+
+@deftypefun void mpfr_inits2 (mpfr_prec_t @var{prec}, mpfr_t @var{x}, ...)
+Initialize all the @code{mpfr_t} variables of the given variable
+argument @code{va_list}, set their precision to be @strong{exactly}
+@var{prec} bits and their value to NaN.
+See @code{mpfr_init2} for more details.
+The @code{va_list} is assumed to be composed only of type @code{mpfr_t}
+(or equivalently @code{mpfr_ptr}).
+It begins from @var{x}, and ends when it encounters a null pointer (whose
+type must also be @code{mpfr_ptr}).
+@end deftypefun
+
+@deftypefun void mpfr_clear (mpfr_t @var{x})
+Free the space occupied by the significand of
+@var{x}. Make sure to call this function for all
+@code{mpfr_t} variables when you are done with them.
+@end deftypefun
+
+@deftypefun void mpfr_clears (mpfr_t @var{x}, ...)
+Free the space occupied by all the @code{mpfr_t} variables of the given
+@code{va_list}. See @code{mpfr_clear} for more details.
+The @code{va_list} is assumed to be composed only of type @code{mpfr_t}
+(or equivalently @code{mpfr_ptr}).
+It begins from @var{x}, and ends when it encounters a null pointer (whose
+type must also be @code{mpfr_ptr}).
+@end deftypefun
+
+Here is an example of how to use multiple initialization functions
+(since @code{NULL} is not necessarily defined in this context, we use
+@code{(mpfr_ptr) 0} instead, but @code{(mpfr_ptr) NULL} is also correct).
+
+@example
+@{
+ mpfr_t x, y, z, t;
+ mpfr_inits2 (256, x, y, z, t, (mpfr_ptr) 0);
+ @dots{}
+ mpfr_clears (x, y, z, t, (mpfr_ptr) 0);
+@}
+@end example
+
+@deftypefun void mpfr_init (mpfr_t @var{x})
+Initialize @var{x}, set its precision to the default precision,
+and set its value to NaN.
+The default precision can be changed by a call to @code{mpfr_set_default_prec}.
+
+Warning! In a given program, some other libraries might change the default
+precision and not restore it. Thus it is safer to use @code{mpfr_init2}.
+@end deftypefun
+
+@deftypefun void mpfr_inits (mpfr_t @var{x}, ...)
+Initialize all the @code{mpfr_t} variables of the given @code{va_list},
+set their precision to the default precision and their value to NaN.
+See @code{mpfr_init} for more details.
+The @code{va_list} is assumed to be composed only of type @code{mpfr_t}
+(or equivalently @code{mpfr_ptr}).
+It begins from @var{x}, and ends when it encounters a null pointer (whose
+type must also be @code{mpfr_ptr}).
+
+Warning! In a given program, some other libraries might change the default
+precision and not restore it. Thus it is safer to use @code{mpfr_inits2}.
+@end deftypefun
+
+@defmac MPFR_DECL_INIT (@var{name}, @var{prec})
+This macro declares @var{name} as an automatic variable of type @code{mpfr_t},
+initializes it and sets its precision to be @strong{exactly} @var{prec} bits
+and its value to NaN. @var{name} must be a valid identifier.
+You must use this macro in the declaration section.
+This macro is much faster than using @code{mpfr_init2} but has some
+drawbacks:
+
+@itemize @bullet
+@item You @strong{must not} call @code{mpfr_clear} with variables
+created with this macro (the storage is allocated at the point of declaration
+and deallocated when the brace-level is exited).
+@item You @strong{cannot} change their precision.
+@item You @strong{should not} create variables with huge precision with this
+macro.
+@item Your compiler must support @samp{Non-Constant Initializers} (standard
+in C++ and ISO C99) and @samp{Token Pasting}
+(standard in ISO C89). If @var{prec} is not a constant expression, your
+compiler must support @samp{variable-length automatic arrays} (standard
+in ISO C99). GCC 2.95.3 and above supports all these features.
+If you compile your program with GCC in C89 mode and with @samp{-pedantic},
+you may want to define the @code{MPFR_USE_EXTENSION} macro to avoid warnings
+due to the @code{MPFR_DECL_INIT} implementation.
+@end itemize
+@end defmac
+
+@deftypefun void mpfr_set_default_prec (mpfr_prec_t @var{prec})
+Set the default precision to be @strong{exactly} @var{prec} bits, where
+@var{prec} can be any integer between @code{MPFR_PREC_MIN} and
+@code{MPFR_PREC_MAX}.
+The
+precision of a variable means the number of bits used to store its significand.
+All
+subsequent calls to @code{mpfr_init} or @code{mpfr_inits}
+will use this precision, but previously
+initialized variables are unaffected.
+The default precision is set to 53 bits initially.
+
+Note: when MPFR is built with the @code{--enable-thread-safe} configure option,
+the default precision is local to each thread. @xref{Memory Handling}, for
+more information.
+@end deftypefun
+
+@deftypefun mpfr_prec_t mpfr_get_default_prec (void)
+Return the current default MPFR precision in bits.
+See the documentation of @code{mpfr_set_default_prec}.
+@end deftypefun
+
+@need 2000
+Here is an example on how to initialize floating-point variables:
+
+@example
+@{
+ mpfr_t x, y;
+ mpfr_init (x); /* use default precision */
+ mpfr_init2 (y, 256); /* precision @emph{exactly} 256 bits */
+ @dots{}
+ /* When the program is about to exit, do ... */
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_free_cache (); /* free the cache for constants like pi */
+@}
+@end example
+
+The following functions are useful for changing the precision during a
+calculation. A typical use would be for adjusting the precision gradually in
+iterative algorithms like Newton-Raphson, making the computation precision
+closely match the actual accurate part of the numbers.
+
+@deftypefun void mpfr_set_prec (mpfr_t @var{x}, mpfr_prec_t @var{prec})
+Reset the precision of @var{x} to be @strong{exactly} @var{prec} bits,
+and set its value to NaN.
+The previous value stored in @var{x} is lost. It is equivalent to
+a call to @code{mpfr_clear(x)} followed by a call to
+@code{mpfr_init2(x, prec)}, but more efficient as no allocation is done in
+case the current allocated space for the significand of @var{x} is enough.
+The precision @var{prec} can be any integer between @code{MPFR_PREC_MIN} and
+@code{MPFR_PREC_MAX}.
+In case you want to keep the previous value stored in @var{x},
+use @code{mpfr_prec_round} instead.
+@end deftypefun
+
+@deftypefun mpfr_prec_t mpfr_get_prec (mpfr_t @var{x})
+Return the precision of @var{x}, i.e., the
+number of bits used to store its significand.
+@end deftypefun
+
+@node Assignment Functions, Combined Initialization and Assignment Functions, Initialization Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Assignment functions
+@section Assignment Functions
+
+These functions assign new values to already initialized floats
+(@pxref{Initialization Functions}).
+
+@deftypefun int mpfr_set (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_ui (mpfr_t @var{rop}, unsigned long int @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_si (mpfr_t @var{rop}, long int @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_uj (mpfr_t @var{rop}, uintmax_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_sj (mpfr_t @var{rop}, intmax_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_flt (mpfr_t @var{rop}, float @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_d (mpfr_t @var{rop}, double @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_ld (mpfr_t @var{rop}, long double @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_decimal64 (mpfr_t @var{rop}, _Decimal64 @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_z (mpfr_t @var{rop}, mpz_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_q (mpfr_t @var{rop}, mpq_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_f (mpfr_t @var{rop}, mpf_t @var{op}, mpfr_rnd_t @var{rnd})
+Set the value of @var{rop} from @var{op}, rounded
+toward the given direction @var{rnd}.
+Note that the input 0 is converted to +0 by @code{mpfr_set_ui},
+@code{mpfr_set_si}, @code{mpfr_set_uj}, @code{mpfr_set_sj},
+@code{mpfr_set_z}, @code{mpfr_set_q} and
+@code{mpfr_set_f}, regardless of the rounding mode.
+If the system does not support the IEEE 754 standard,
+@code{mpfr_set_flt}, @code{mpfr_set_d}, @code{mpfr_set_ld} and
+@code{mpfr_set_decimal64} might not preserve the signed zeros.
+The @code{mpfr_set_decimal64} function is built only with the configure
+option @samp{--enable-decimal-float}, which also requires
+@samp{--with-gmp-build}, and when the compiler or
+system provides the @samp{_Decimal64} data type
+(recent versions of GCC support this data type);
+to use @code{mpfr_set_decimal64}, one should define the macro
+@code{MPFR_WANT_DECIMAL_FLOATS} before including @file{mpfr.h}.
+@c GCC 4.2.0 required to be configured with --enable-decimal-float
+@c but GCC 4.4.3 seems to have decimal support by default
+@code{mpfr_set_q} might fail if the numerator (or the
+denominator) can not be represented as a @code{mpfr_t}.
+
+Note: If you want to store a floating-point constant to a @code{mpfr_t},
+you should use @code{mpfr_set_str} (or one of the MPFR constant functions,
+such as @code{mpfr_const_pi} for @m{\pi,Pi}) instead of
+@code{mpfr_set_flt}, @code{mpfr_set_d},
+@code{mpfr_set_ld} or @code{mpfr_set_decimal64}.
+Otherwise the floating-point constant will be first
+converted into a reduced-precision (e.g., 53-bit) binary
+(or decimal, for @code{mpfr_set_decimal64}) number before
+MPFR can work with it.
+@end deftypefun
+
+@deftypefun int mpfr_set_ui_2exp (mpfr_t @var{rop}, unsigned long int @var{op}, mpfr_exp_t @var{e}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_si_2exp (mpfr_t @var{rop}, long int @var{op}, mpfr_exp_t @var{e}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_uj_2exp (mpfr_t @var{rop}, uintmax_t @var{op}, intmax_t @var{e}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_sj_2exp (mpfr_t @var{rop}, intmax_t @var{op}, intmax_t @var{e}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_set_z_2exp (mpfr_t @var{rop}, mpz_t @var{op}, mpfr_exp_t @var{e}, mpfr_rnd_t @var{rnd})
+Set the value of @var{rop} from @m{@var{op} \times 2^e, @var{op} multiplied by
+two to the power @var{e}}, rounded toward the given direction @var{rnd}.
+Note that the input 0 is converted to +0.
+@end deftypefun
+
+@deftypefun int mpfr_set_str (mpfr_t @var{rop}, const char *@var{s}, int @var{base}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the string @var{s} in base @var{base},
+rounded in the direction @var{rnd}.
+See the documentation of @code{mpfr_strtofr} for a detailed description
+of the valid string formats.
+Contrary to @code{mpfr_strtofr}, @code{mpfr_set_str} requires the
+@emph{whole} string to represent a valid floating-point number.
+@c Additionally, special values
+@c @code{@@NaN@@}, @code{@@Inf@@}, @code{+@@Inf@@} and @code{-@@Inf@@},
+@c all case insensitive, without leading whitespace and possibly followed by
+@c other characters, are accepted too (it may change).
+
+The meaning of the return value differs from other MPFR functions:
+it is 0 if the entire string up to the final null character
+is a valid number in base @var{base}; otherwise it is @minus{}1, and
+@var{rop} may have changed (users interested in the @ref{ternary value}
+should use @code{mpfr_strtofr} instead).
+
+Note: it is preferable to use @code{mpfr_set_str} if one wants to distinguish
+between an infinite @var{rop} value coming from an infinite @var{s} or from
+an overflow.
+@end deftypefun
+
+@deftypefun int mpfr_strtofr (mpfr_t @var{rop}, const char *@var{nptr}, char **@var{endptr}, int @var{base}, mpfr_rnd_t @var{rnd})
+
+Read a floating-point number from a string @var{nptr} in base @var{base},
+rounded in the direction @var{rnd}; @var{base} must be either 0 (to
+detect the base, as described below) or a number from 2 to 62 (otherwise
+the behavior is undefined). If @var{nptr} starts with valid data, the
+result is stored in @var{rop} and @code{*@var{endptr}} points to the
+character just after the valid data (if @var{endptr} is not a null pointer);
+otherwise @var{rop} is set to zero (for consistency with @code{strtod})
+and the value of @var{nptr} is stored
+in the location referenced by @var{endptr} (if @var{endptr} is not a null
+pointer). The usual ternary value is returned.
+
+Parsing follows the standard C @code{strtod} function with some extensions.
+After optional leading whitespace, one has a subject sequence consisting of an
+optional sign (@code{+} or @code{-}), and either numeric data or special
+data. The subject sequence is defined as the longest initial subsequence of
+the input string, starting with the first non-whitespace character, that is of
+the expected form.
+
+The form of numeric data is a non-empty sequence of significand digits with an
+optional decimal point, and an optional exponent consisting of an exponent
+prefix followed by an optional sign and a non-empty sequence of decimal
+digits. A significand digit is either a decimal digit or a Latin letter (62
+possible characters), with @code{A} = 10, @code{B} = 11, @dots{}, @code{Z} =
+35; case is ignored in bases less or equal to 36, in bases larger than 36,
+@code{a} = 36, @code{b} = 37, @dots{}, @code{z} = 61.
+The value of a
+significand digit must be strictly less than the base. The decimal point can
+be either the one defined by the current locale or the period (the first one
+is accepted for consistency with the C standard and the practice, the second
+one is accepted to allow the programmer to provide MPFR numbers from strings
+in a way that does not depend on the current locale).
+The exponent prefix can be @code{e} or @code{E} for bases up to 10, or
+@code{@@} in any base; it indicates a multiplication by a power of the
+base. In bases 2 and 16, the exponent prefix can also be @code{p} or @code{P},
+in which case the exponent, called @emph{binary exponent}, indicates a
+multiplication by a power of 2 instead of the base (there is a difference
+only for base 16); in base 16 for example @code{1p2} represents 4 whereas
+@code{1@@2} represents 256. The value of an exponent is always written in
+base 10.
+
+If the argument @var{base} is 0, then the base is automatically detected
+as follows. If the significand starts with @code{0b} or @code{0B}, base 2
+is assumed. If the significand starts with @code{0x} or @code{0X}, base 16
+is assumed. Otherwise base 10 is assumed.
+
+Note: The exponent (if present)
+must contain at least a digit. Otherwise the possible
+exponent prefix and sign are not part of the number (which ends with the
+significand). Similarly, if @code{0b}, @code{0B}, @code{0x} or @code{0X}
+is not followed by a binary/hexadecimal digit, then the subject sequence
+stops at the character @code{0}, thus 0 is read.
+
+Special data (for infinities and NaN) can be @code{@@inf@@} or
+@code{@@nan@@(n-char-sequence-opt)}, and if @math{@var{base} @le{} 16},
+it can also be @code{infinity}, @code{inf}, @code{nan} or
+@code{nan(n-char-sequence-opt)}, all case insensitive.
+A @code{n-char-sequence-opt} is a possibly empty string containing only digits,
+Latin letters and the underscore (0, 1, 2, @dots{}, 9, a, b, @dots{}, z,
+A, B, @dots{}, Z, _). Note: one has an optional sign for all data, even
+NaN.
+For example, @code{-@@nAn@@(This_Is_Not_17)} is a valid representation for NaN
+in base 17.
+
+@end deftypefun
+
+@deftypefun void mpfr_set_nan (mpfr_t @var{x})
+@deftypefunx void mpfr_set_inf (mpfr_t @var{x}, int @var{sign})
+@deftypefunx void mpfr_set_zero (mpfr_t @var{x}, int @var{sign})
+Set the variable @var{x} to NaN (Not-a-Number), infinity or zero respectively.
+In @code{mpfr_set_inf} or @code{mpfr_set_zero}, @var{x} is set to plus
+infinity or plus zero iff @var{sign} is nonnegative;
+in @code{mpfr_set_nan}, the sign bit of the result is unspecified.
+@end deftypefun
+
+@deftypefun void mpfr_swap (mpfr_t @var{x}, mpfr_t @var{y})
+Swap the values @var{x} and @var{y} efficiently. Warning: the
+precisions are exchanged too; in case the precisions are different,
+@code{mpfr_swap} is thus not equivalent to three @code{mpfr_set} calls
+using a third auxiliary variable.
+@end deftypefun
+
+@node Combined Initialization and Assignment Functions, Conversion Functions, Assignment Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Combined initialization and assignment functions
+@section Combined Initialization and Assignment Functions
+
+@deftypefn Macro int mpfr_init_set (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefnx Macro int mpfr_init_set_ui (mpfr_t @var{rop}, unsigned long int @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefnx Macro int mpfr_init_set_si (mpfr_t @var{rop}, long int @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefnx Macro int mpfr_init_set_d (mpfr_t @var{rop}, double @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefnx Macro int mpfr_init_set_ld (mpfr_t @var{rop}, long double @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefnx Macro int mpfr_init_set_z (mpfr_t @var{rop}, mpz_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefnx Macro int mpfr_init_set_q (mpfr_t @var{rop}, mpq_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefnx Macro int mpfr_init_set_f (mpfr_t @var{rop}, mpf_t @var{op}, mpfr_rnd_t @var{rnd})
+Initialize @var{rop} and set its value from @var{op}, rounded in the direction
+@var{rnd}.
+The precision of @var{rop} will be taken from the active default precision,
+as set by @code{mpfr_set_default_prec}.
+@end deftypefn
+
+@deftypefun int mpfr_init_set_str (mpfr_t @var{x}, const char *@var{s}, int @var{base}, mpfr_rnd_t @var{rnd})
+Initialize @var{x} and set its value from
+the string @var{s} in base @var{base},
+rounded in the direction @var{rnd}.
+See @code{mpfr_set_str}.
+@end deftypefun
+
+@node Conversion Functions, Basic Arithmetic Functions, Combined Initialization and Assignment Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Conversion functions
+@section Conversion Functions
+
+@deftypefun float mpfr_get_flt (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx double mpfr_get_d (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx {long double} mpfr_get_ld (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx _Decimal64 mpfr_get_decimal64 (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Convert @var{op} to a @code{float} (respectively @code{double},
+@code{long double} or @code{_Decimal64}), using the rounding mode @var{rnd}.
+If @var{op} is NaN, some fixed NaN (either quiet or signaling) or the result
+of 0.0/0.0 is returned. If @var{op} is @pom{}Inf, an infinity of the same
+sign or the result of @pom{}1.0/0.0 is returned. If @var{op} is zero, these
+functions return a zero, trying to preserve its sign, if possible.
+The @code{mpfr_get_decimal64} function is built only under some conditions:
+see the documentation of @code{mpfr_set_decimal64}.
+@end deftypefun
+
+@deftypefun long mpfr_get_si (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx {unsigned long} mpfr_get_ui (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx intmax_t mpfr_get_sj (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx uintmax_t mpfr_get_uj (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Convert @var{op} to a @code{long}, an @code{unsigned long},
+an @code{intmax_t} or an @code{uintmax_t} (respectively) after rounding
+it with respect to @var{rnd}.
+If @var{op} is NaN, 0 is returned and the @emph{erange} flag is set.
+If @var{op} is too big for the return type, the function returns the maximum
+or the minimum of the corresponding C type, depending on the direction
+of the overflow; the @emph{erange} flag is set too.
+See also @code{mpfr_fits_slong_p}, @code{mpfr_fits_ulong_p},
+@code{mpfr_fits_intmax_p} and @code{mpfr_fits_uintmax_p}.
+@end deftypefun
+
+@deftypefun double mpfr_get_d_2exp (long *@var{exp}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx {long double} mpfr_get_ld_2exp (long *@var{exp}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Return @var{d} and set @var{exp}
+(formally, the value pointed to by @var{exp})
+such that @math{0.5@le{}@GMPabs{@var{d}}<1}
+and @m{@var{d}\times 2^{exp}, @var{d} times 2 raised to @var{exp}} equals
+@var{op} rounded to double (resp.@: long double)
+precision, using the given rounding mode.
+@comment See ISO C standard, frexp function.
+If @var{op} is zero, then a zero of the same sign (or an unsigned zero,
+if the implementation does not have signed zeros) is returned, and
+@var{exp} is set to 0.
+If @var{op} is NaN or an infinity, then the corresponding double precision
+(resp.@: long-double precision)
+value is returned, and @var{exp} is undefined.
+@end deftypefun
+
+@deftypefun int mpfr_frexp (mpfr_exp_t *@var{exp}, mpfr_t @var{y}, mpfr_t @var{x}, mpfr_rnd_t @var{rnd})
+Set @var{exp}
+(formally, the value pointed to by @var{exp}) and @var{y}
+such that @math{0.5@le{}@GMPabs{@var{y}}<1}
+and @m{@var{y}\times 2^{exp}, @var{y} times 2 raised to @var{exp}} equals
+@var{x} rounded to the precision of @var{y}, using the given rounding mode.
+@comment See ISO C standard, frexp function.
+If @var{x} is zero, then @var{y} is set to a zero of the same sign and
+@var{exp} is set to 0.
+If @var{x} is NaN or an infinity, then @var{y} is set to the same value
+and @var{exp} is undefined.
+@end deftypefun
+
+@deftypefun mpfr_exp_t mpfr_get_z_2exp (mpz_t @var{rop}, mpfr_t @var{op})
+Put the scaled significand of @var{op} (regarded as an integer, with the
+precision of @var{op}) into @var{rop}, and return the exponent @var{exp}
+(which may be outside the current exponent range) such that @var{op}
+exactly equals
+@ifnottex
+@var{rop} times 2 raised to the power @var{exp}.
+@end ifnottex
+@tex
+$rop \times 2^{\rm exp}$.
+@end tex
+If @var{op} is zero, the minimal exponent @code{emin} is returned.
+If @var{op} is NaN or an infinity, the @emph{erange} flag is set, @var{rop}
+is set to 0, and the the minimal exponent @code{emin} is returned.
+The returned exponent may be less than the minimal exponent @code{emin}
+of MPFR numbers in the current exponent range; in case the exponent is
+not representable in the @code{mpfr_exp_t} type, the @emph{erange} flag
+is set and the minimal value of the @code{mpfr_exp_t} type is returned.
+@end deftypefun
+
+@deftypefun int mpfr_get_z (mpz_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Convert @var{op} to a @code{mpz_t}, after rounding it with respect to
+@var{rnd}. If @var{op} is NaN or an infinity, the @emph{erange} flag is
+set, @var{rop} is set to 0, and 0 is returned.
+@end deftypefun
+
+@deftypefun int mpfr_get_f (mpf_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Convert @var{op} to a @code{mpf_t}, after rounding it with respect to
+@var{rnd}.
+The @emph{erange} flag is set if @var{op} is NaN or an infinity, which
+do not exist in MPF. If @var{op} is NaN, then @var{rop} is undefined.
+If @var{op} is an +Inf (resp.@: @minus{}Inf), then @var{rop} is set to
+the maximum (resp.@: minimum) value in the precision of the MPF number;
+if a future MPF version supports infinities, this behavior will be
+considered incorrect and will change (portable programs should assume
+that @var{rop} is set either to this finite number or to an infinite
+number).
+Note that since MPFR currently has the same exponent type as MPF (but
+not with the same radix), the range of values is much larger in MPF
+than in MPFR, so that an overflow or underflow is not possible.
+@end deftypefun
+
+@deftypefun {char *} mpfr_get_str (char *@var{str}, mpfr_exp_t *@var{expptr}, int @var{b}, size_t @var{n}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Convert @var{op} to a string of digits in base @var{b}, with rounding in
+the direction @var{rnd}, where @var{n} is either zero (see below) or the
+number of significant digits output in the string;
+in the latter case, @var{n} must be greater
+or equal to 2. The base may vary from 2 to 62.
+If the input number is an ordinary number, the exponent is written through
+the pointer @var{expptr} (for input 0, the current minimal exponent is
+written).
+
+The generated string is a fraction, with an implicit radix point immediately
+to the left of the first digit. For example, the number @minus{}3.1416 would
+be returned as "@minus{}31416" in the string and 1 written at @var{expptr}.
+If @var{rnd} is to nearest, and @var{op} is exactly in the middle of two
+consecutive possible outputs, the one with an even significand is chosen,
+where both significands are considered with the exponent of @var{op}.
+Note that for an odd base, this may not correspond to an even last digit:
+for example with 2 digits in base 7, (14) and a half is rounded to (15)
+which is 12 in decimal, (16) and a half is rounded to
+(20) which is 14 in decimal,
+@c The following example duplicates (16) and a half
+@c (36) and a half is rounded to (40) which is 28 in decimal,
+and (26) and a half is rounded to (26) which is 20 in decimal.
+
+If @var{n} is zero, the number of digits of the significand is chosen
+large enough so that re-reading the printed value with the same precision,
+assuming both output and input use rounding to nearest, will recover
+the original value of @var{op}.
+More precisely, in most cases, the chosen precision of @var{str} is the
+minimal precision @math{m} depending only on @var{p} = PREC(@var{op}) and
+@var{b} that satisfies the above property, i.e.,
+@ifnottex
+m = 1 + ceil(@var{p}*log(2)/log(@var{b})),
+@end ifnottex
+@tex
+$m = 1 + \lceil p {\log 2 \over \log b} \rceil$,
+@end tex
+with @var{p} replaced by @var{p}@minus{}1 if @var{b} is a power of 2,
+but in some very rare cases, it might be @math{m+1}
+(the smallest case for bases up to 62 is when @var{p} equals 186564318007
+for bases 7 and 49).
+
+If @var{str} is a null pointer, space for the significand is allocated using
+the current allocation function, and a pointer to the string is returned.
+To free the returned string, you must use @code{mpfr_free_str}.
+
+If @var{str} is not a null pointer, it should point to a block of storage
+large enough for the significand, i.e., at least @code{max(@var{n} + 2, 7)}.
+The extra two bytes are for a possible minus sign, and for the terminating null
+character, and the value 7 accounts for @code{-@@Inf@@}
+plus the terminating null character.
+
+A pointer to the string is returned, unless there is an error, in which
+case a null pointer is returned.
+@end deftypefun
+
+@deftypefun void mpfr_free_str (char *@var{str})
+Free a string allocated by @code{mpfr_get_str} using the current unallocation
+function.
+The block is assumed to be @code{strlen(@var{str})+1} bytes.
+For more information about how it is done:
+@ifinfo
+@pxref{Custom Allocation,,, gmp.info,GNU MP}.
+@end ifinfo
+@ifnotinfo
+see Section ``Custom Allocation'' in @cite{GNU MP}.
+@end ifnotinfo
+@end deftypefun
+
+@deftypefun int mpfr_fits_ulong_p (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_fits_slong_p (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_fits_uint_p (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_fits_sint_p (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_fits_ushort_p (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_fits_sshort_p (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_fits_uintmax_p (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_fits_intmax_p (mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Return non-zero if @var{op} would fit in the respective C data type,
+respectively @code{unsigned long}, @code{long}, @code{unsigned int},
+@code{int}, @code{unsigned short}, @code{short}, @code{uintmax_t},
+@code{intmax_t}, when rounded to an integer in the direction @var{rnd}.
+@end deftypefun
+
+@node Basic Arithmetic Functions, Comparison Functions, Conversion Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Basic arithmetic functions
+@cindex Float arithmetic functions
+@cindex Arithmetic functions
+@section Basic Arithmetic Functions
+
+@deftypefun int mpfr_add (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_add_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_add_si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_add_d (mpfr_t @var{rop}, mpfr_t @var{op1}, double @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_add_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_add_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @math{@var{op1} + @var{op2}} rounded in the direction
+@var{rnd}. For types having no signed zero, it is considered unsigned
+(i.e., (+0) + 0 = (+0) and (@minus{}0) + 0 = (@minus{}0)).
+The @code{mpfr_add_d} function assumes that the radix of the @code{double} type
+is a power of 2, with a precision at most that declared by the C implementation
+(macro @code{IEEE_DBL_MANT_DIG}, and if not defined 53 bits).
+@end deftypefun
+
+@deftypefun int mpfr_sub (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_ui_sub (mpfr_t @var{rop}, unsigned long int @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_sub_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_si_sub (mpfr_t @var{rop}, long int @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_sub_si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_d_sub (mpfr_t @var{rop}, double @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_sub_d (mpfr_t @var{rop}, mpfr_t @var{op1}, double @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_z_sub (mpfr_t @var{rop}, mpz_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_sub_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_sub_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @math{@var{op1} - @var{op2}} rounded in the direction
+@var{rnd}. For types having no signed zero, it is considered unsigned
+(i.e., (+0) @minus{} 0 = (+0), (@minus{}0) @minus{} 0 = (@minus{}0),
+0 @minus{} (+0) = (@minus{}0) and 0 @minus{} (@minus{}0) = (+0)).
+The same restrictions than for @code{mpfr_add_d} apply to @code{mpfr_d_sub}
+and @code{mpfr_sub_d}.
+@end deftypefun
+
+@deftypefun int mpfr_mul (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_mul_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_mul_si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_mul_d (mpfr_t @var{rop}, mpfr_t @var{op1}, double @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_mul_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_mul_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @math{@var{op1} @GMPtimes{} @var{op2}} rounded in the
+direction @var{rnd}.
+When a result is zero, its sign is the product of the signs of the operands
+(for types having no signed zero, it is considered positive).
+The same restrictions than for @code{mpfr_add_d} apply to @code{mpfr_mul_d}.
+@end deftypefun
+
+@deftypefun int mpfr_sqr (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @m{@var{op}^{2}, the square of @var{op}}
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_div (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_ui_div (mpfr_t @var{rop}, unsigned long int @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_div_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_si_div (mpfr_t @var{rop}, long int @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_div_si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_d_div (mpfr_t @var{rop}, double @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_div_d (mpfr_t @var{rop}, mpfr_t @var{op1}, double @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_div_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_div_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @math{@var{op1}/@var{op2}} rounded in the direction @var{rnd}.
+When a result is zero, its sign is the product of the signs of the operands
+(for types having no signed zero, it is considered positive).
+The same restrictions than for @code{mpfr_add_d} apply to @code{mpfr_d_div}
+and @code{mpfr_div_d}.
+@end deftypefun
+
+@deftypefun int mpfr_sqrt (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_sqrt_ui (mpfr_t @var{rop}, unsigned long int @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @m{\sqrt{@var{op}}, the square root of @var{op}}
+rounded in the direction @var{rnd} (set @var{rop} to @minus{}0 if @var{op} is
+@minus{}0, to be consistent with the IEEE 754 standard).
+Set @var{rop} to NaN if @var{op} is negative.
+@end deftypefun
+
+@deftypefun int mpfr_rec_sqrt (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @m{1/\sqrt{@var{op}}, the reciprocal square root of @var{op}}
+rounded in the direction @var{rnd}. Set @var{rop} to +Inf if @var{op} is
+@pom{}0, +0 if @var{op} is +Inf, and NaN if @var{op} is negative.
+@end deftypefun
+
+@deftypefun int mpfr_cbrt (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_root (mpfr_t @var{rop}, mpfr_t @var{op}, unsigned long int @var{k}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the cubic root (resp.@: the @var{k}th root)
+of @var{op} rounded in the direction @var{rnd}.
+For @var{k} odd (resp.@: even) and @var{op} negative (including @minus{}Inf),
+set @var{rop} to a negative number (resp.@: NaN).
+The @var{k}th root of @minus{}0 is defined to be @minus{}0,
+whatever the parity of @var{k}.
+@end deftypefun
+
+@deftypefun int mpfr_pow (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_pow_ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_pow_si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_pow_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_ui_pow_ui (mpfr_t @var{rop}, unsigned long int @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_ui_pow (mpfr_t @var{rop}, unsigned long int @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @m{@var{op1}^{op2}, @var{op1} raised to @var{op2}},
+rounded in the direction @var{rnd}.
+Special values are handled as described in the ISO C99 and IEEE 754-2008
+standards for the @code{pow} function:
+@itemize @bullet
+@item @code{pow(@pom{}0, @var{y})} returns plus or minus infinity for @var{y} a negative odd integer.
+@item @code{pow(@pom{}0, @var{y})} returns plus infinity for @var{y} negative and not an odd integer.
+@item @code{pow(@pom{}0, @var{y})} returns plus or minus zero for @var{y} a positive odd integer.
+@item @code{pow(@pom{}0, @var{y})} returns plus zero for @var{y} positive and not an odd integer.
+@item @code{pow(-1, @pom{}Inf)} returns 1.
+@item @code{pow(+1, @var{y})} returns 1 for any @var{y}, even a NaN.
+@item @code{pow(@var{x}, @pom{}0)} returns 1 for any @var{x}, even a NaN.
+@item @code{pow(@var{x}, @var{y})} returns NaN for finite negative @var{x} and finite non-integer @var{y}.
+@item @code{pow(@var{x}, -Inf)} returns plus infinity for @math{0 < @GMPabs{x} < 1}, and plus zero for @math{@GMPabs{x} > 1}.
+@item @code{pow(@var{x}, +Inf)} returns plus zero for @math{0 < @GMPabs{x} < 1}, and plus infinity for @math{@GMPabs{x} > 1}.
+@item @code{pow(-Inf, @var{y})} returns minus zero for @var{y} a negative odd integer.
+@item @code{pow(-Inf, @var{y})} returns plus zero for @var{y} negative and not an odd integer.
+@item @code{pow(-Inf, @var{y})} returns minus infinity for @var{y} a positive odd integer.
+@item @code{pow(-Inf, @var{y})} returns plus infinity for @var{y} positive and not an odd integer.
+@item @code{pow(+Inf, @var{y})} returns plus zero for @var{y} negative, and plus infinity for @var{y} positive.
+@end itemize
+@end deftypefun
+
+@deftypefun int mpfr_neg (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_abs (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @math{-@var{op}} and the absolute value of @var{op}
+respectively, rounded in the direction @var{rnd}.
+Just changes or adjusts
+the sign if @var{rop} and @var{op} are the same variable,
+otherwise a rounding might occur if the precision of @var{rop} is less than
+that of @var{op}.
+@end deftypefun
+
+@deftypefun int mpfr_dim (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the positive difference of @var{op1} and @var{op2}, i.e.,
+@math{@var{op1} - @var{op2}} rounded in the direction @var{rnd}
+if @math{@var{op1} > @var{op2}}, +0 if @math{@var{op1} @le{} @var{op2}},
+and NaN if @var{op1} or @var{op2} is NaN.
+@end deftypefun
+
+@deftypefun int mpfr_mul_2ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_mul_2si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @m{@var{op1} \times 2^{op2}, @var{op1} times 2 raised
+to @var{op2}}
+rounded in the direction @var{rnd}. Just increases the exponent by @var{op2}
+when @var{rop} and @var{op1} are identical.
+@end deftypefun
+
+@deftypefun int mpfr_div_2ui (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_div_2si (mpfr_t @var{rop}, mpfr_t @var{op1}, long int @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @m{@var{op1}/2^{op2}, @var{op1} divided by 2 raised
+to @var{op2}}
+rounded in the direction @var{rnd}. Just decreases the exponent by @var{op2}
+when @var{rop} and @var{op1} are identical.
+@end deftypefun
+
+@node Comparison Functions, Special Functions, Basic Arithmetic Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Float comparisons functions
+@cindex Comparison functions
+@section Comparison Functions
+
+@deftypefun int mpfr_cmp (mpfr_t @var{op1}, mpfr_t @var{op2})
+@deftypefunx int mpfr_cmp_ui (mpfr_t @var{op1}, unsigned long int @var{op2})
+@deftypefunx int mpfr_cmp_si (mpfr_t @var{op1}, long int @var{op2})
+@deftypefunx int mpfr_cmp_d (mpfr_t @var{op1}, double @var{op2})
+@deftypefunx int mpfr_cmp_ld (mpfr_t @var{op1}, long double @var{op2})
+@deftypefunx int mpfr_cmp_z (mpfr_t @var{op1}, mpz_t @var{op2})
+@deftypefunx int mpfr_cmp_q (mpfr_t @var{op1}, mpq_t @var{op2})
+@deftypefunx int mpfr_cmp_f (mpfr_t @var{op1}, mpf_t @var{op2})
+Compare @var{op1} and @var{op2}. Return a positive value if @math{@var{op1} >
+@var{op2}}, zero if @math{@var{op1} = @var{op2}}, and a negative value if
+@math{@var{op1} < @var{op2}}.
+Both @var{op1} and @var{op2} are considered to their full own precision,
+which may differ.
+If one of the operands is NaN, set the @emph{erange} flag and return zero.
+
+Note: These functions may be useful to distinguish the three possible cases.
+If you need to distinguish two cases only, it is recommended to use the
+predicate functions (e.g., @code{mpfr_equal_p} for the equality) described
+below; they behave like the IEEE 754 comparisons, in particular when one
+or both arguments are NaN. But only floating-point numbers can be compared
+(you may need to do a conversion first).
+@end deftypefun
+
+@deftypefun int mpfr_cmp_ui_2exp (mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_exp_t @var{e})
+@deftypefunx int mpfr_cmp_si_2exp (mpfr_t @var{op1}, long int @var{op2}, mpfr_exp_t @var{e})
+Compare @var{op1} and @m{@var{op2} \times 2^e, @var{op2} multiplied by two to
+the power @var{e}}. Similar as above.
+@end deftypefun
+
+@deftypefun int mpfr_cmpabs (mpfr_t @var{op1}, mpfr_t @var{op2})
+Compare @math{|@var{op1}|} and @math{|@var{op2}|}. Return a positive value if
+@math{|@var{op1}| > |@var{op2}|}, zero if @math{|@var{op1}| = |@var{op2}|}, and
+a negative value if @math{|@var{op1}| < |@var{op2}|}.
+If one of the operands is NaN, set the @emph{erange} flag and return zero.
+@end deftypefun
+
+@deftypefun int mpfr_nan_p (mpfr_t @var{op})
+@deftypefunx int mpfr_inf_p (mpfr_t @var{op})
+@deftypefunx int mpfr_number_p (mpfr_t @var{op})
+@deftypefunx int mpfr_zero_p (mpfr_t @var{op})
+@deftypefunx int mpfr_regular_p (mpfr_t @var{op})
+Return non-zero if @var{op} is respectively NaN, an infinity, an ordinary
+number (i.e., neither NaN nor an infinity), zero, or a regular number
+(i.e., neither NaN, nor an infinity nor zero). Return zero otherwise.
+@end deftypefun
+
+@deftypefn Macro int mpfr_sgn (mpfr_t @var{op})
+Return a positive value if @math{@var{op} > 0}, zero if @math{@var{op} = 0},
+and a negative value if @math{@var{op} < 0}.
+If the operand is NaN, set the @emph{erange} flag and return zero.
+This is equivalent to @code{mpfr_cmp_ui (op, 0)}, but more efficient.
+@end deftypefn
+
+@deftypefun int mpfr_greater_p (mpfr_t @var{op1}, mpfr_t @var{op2})
+@deftypefunx int mpfr_greaterequal_p (mpfr_t @var{op1}, mpfr_t @var{op2})
+@deftypefunx int mpfr_less_p (mpfr_t @var{op1}, mpfr_t @var{op2})
+@deftypefunx int mpfr_lessequal_p (mpfr_t @var{op1}, mpfr_t @var{op2})
+@deftypefunx int mpfr_equal_p (mpfr_t @var{op1}, mpfr_t @var{op2})
+Return non-zero if
+@math{@var{op1} > @var{op2}},
+@math{@var{op1} @ge{} @var{op2}},
+@math{@var{op1} < @var{op2}},
+@math{@var{op1} @le{} @var{op2}},
+@math{@var{op1} = @var{op2}} respectively,
+and zero otherwise.
+Those functions return zero whenever @var{op1} and/or @var{op2} is NaN.
+@end deftypefun
+
+@deftypefun int mpfr_lessgreater_p (mpfr_t @var{op1}, mpfr_t @var{op2})
+Return non-zero if @math{@var{op1} < @var{op2}} or
+@math{@var{op1} > @var{op2}} (i.e., neither @var{op1}, nor @var{op2} is
+NaN, and @math{@var{op1} @ne{} @var{op2}}), zero otherwise (i.e., @var{op1}
+and/or @var{op2} is NaN, or @math{@var{op1} = @var{op2}}).
+@end deftypefun
+
+@deftypefun int mpfr_unordered_p (mpfr_t @var{op1}, mpfr_t @var{op2})
+Return non-zero if @var{op1} or @var{op2} is a NaN (i.e., they cannot be
+compared), zero otherwise.
+@end deftypefun
+
+@node Special Functions, Input and Output Functions, Comparison Functions, MPFR Interface
+@cindex Special functions
+@section Special Functions
+
+All those functions, except explicitly stated (for example
+@code{mpfr_sin_cos}), return a @ref{ternary value}, i.e., zero for an
+exact return value, a positive value for a return value larger than the
+exact result, and a negative value otherwise.
+
+Important note: in some domains, computing special functions (either with
+correct or incorrect rounding) is expensive, even for small precision,
+for example the trigonometric and Bessel functions for large argument.
+
+@deftypefun int mpfr_log (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_log2 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_log10 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the natural logarithm of @var{op},
+@m{\log_2 @var{op}, log2(@var{op})} or
+@m{\log_{10} @var{op}, log10(@var{op})}, respectively,
+rounded in the direction @var{rnd}.
+Set @var{rop} to @minus{}Inf if @var{op} is @minus{}0
+(i.e., the sign of the zero has no influence on the result).
+@end deftypefun
+
+@deftypefun int mpfr_exp (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_exp2 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_exp10 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the exponential of @var{op},
+ to @m{2^{op}, 2 power of @var{op}}
+or to @m{10^{op}, 10 power of @var{op}}, respectively,
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_cos (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_sin (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_tan (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the cosine of @var{op}, sine of @var{op},
+tangent of @var{op}, rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_sin_cos (mpfr_t @var{sop}, mpfr_t @var{cop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set simultaneously @var{sop} to the sine of @var{op} and @var{cop} to the
+cosine of @var{op}, rounded in the direction @var{rnd} with the corresponding
+precisions of @var{sop} and @var{cop}, which must be different variables.
+Return 0 iff both results are exact, more precisely it returns @math{s+4c}
+where @math{s=0} if @var{sop} is exact, @math{s=1} if @var{sop} is larger
+than the sine of @var{op}, @math{s=2} if @var{sop} is smaller than the sine
+of @var{op}, and similarly for @math{c} and the cosine of @var{op}.
+@end deftypefun
+
+@deftypefun int mpfr_sec (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_csc (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_cot (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the secant of @var{op}, cosecant of @var{op},
+cotangent of @var{op}, rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_acos (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_asin (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_atan (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the arc-cosine, arc-sine or arc-tangent of @var{op},
+rounded in the direction @var{rnd}.
+Note that since @code{acos(-1)} returns the floating-point number closest to
+@m{\pi,Pi} according to the given rounding mode, this number might not be
+in the output range @math{0 @le{} @var{rop} < \pi}
+of the arc-cosine function;
+still, the result lies in the image of the output range
+by the rounding function.
+The same holds for @code{asin(-1)}, @code{asin(1)}, @code{atan(-Inf)},
+@code{atan(+Inf)} or for @code{atan(op)} with large @var{op} and
+small precision of @var{rop}.
+@c PZ: check the above is correct
+@end deftypefun
+
+@deftypefun int mpfr_atan2 (mpfr_t @var{rop}, mpfr_t @var{y}, mpfr_t @var{x}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the arc-tangent2 of @var{y} and @var{x},
+rounded in the direction @var{rnd}:
+if @code{x > 0}, @code{atan2(y, x) = atan (y/x)};
+if @code{x < 0}, @code{atan2(y, x) = sign(y)*(Pi - atan (@GMPabs{y/x}))},
+thus a number from @m{-\pi,-Pi} to @m{\pi,Pi}.
+As for @code{atan}, in case the exact mathematical result is @m{+\pi,+Pi} or
+@m{-\pi,-Pi},
+its rounded result might be outside the function output range.
+
+@code{atan2(y, 0)} does not raise any floating-point exception.
+Special values are handled as described in the ISO C99 and IEEE 754-2008
+standards for the @code{atan2} function:
+@itemize @bullet
+@item @code{atan2(+0, -0)} returns @m{+\pi,+Pi}.
+@item @code{atan2(-0, -0)} returns @m{-\pi,-Pi}.
+@item @code{atan2(+0, +0)} returns +0.
+@item @code{atan2(-0, +0)} returns @minus{}0.
+@item @code{atan2(+0, x)} returns @m{+\pi,+Pi} for @math{x < 0}.
+@item @code{atan2(-0, x)} returns @m{-\pi,-Pi} for @math{x < 0}.
+@item @code{atan2(+0, x)} returns +0 for @math{x > 0}.
+@item @code{atan2(-0, x)} returns @minus{}0 for @math{x > 0}.
+@item @code{atan2(y, 0)} returns @m{-\pi/2,-Pi/2} for @math{y < 0}.
+@item @code{atan2(y, 0)} returns @m{+\pi/2,+Pi/2} for @math{y > 0}.
+@item @code{atan2(+Inf, -Inf)} returns @m{+3\pi/4,+3*Pi/4}.
+@item @code{atan2(-Inf, -Inf)} returns @m{-3\pi/4,-3*Pi/4}.
+@item @code{atan2(+Inf, +Inf)} returns @m{+\pi/4,+Pi/4}.
+@item @code{atan2(-Inf, +Inf)} returns @m{-\pi/4,-Pi/4}.
+@item @code{atan2(+Inf, x)} returns @m{+\pi/2,+Pi/2} for finite @math{x}.
+@item @code{atan2(-Inf, x)} returns @m{-\pi/2,-Pi/2} for finite @math{x}.
+@item @code{atan2(y, -Inf)} returns @m{+\pi,+Pi} for finite @math{y > 0}.
+@item @code{atan2(y, -Inf)} returns @m{-\pi,-Pi} for finite @math{y < 0}.
+@item @code{atan2(y, +Inf)} returns +0 for finite @math{y > 0}.
+@item @code{atan2(y, +Inf)} returns @minus{}0 for finite @math{y < 0}.
+@end itemize
+@end deftypefun
+
+@deftypefun int mpfr_cosh (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_sinh (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_tanh (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the hyperbolic cosine, sine or tangent of @var{op},
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_sinh_cosh (mpfr_t @var{sop}, mpfr_t @var{cop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set simultaneously @var{sop} to the hyperbolic sine of @var{op} and
+@var{cop} to the hyperbolic cosine of @var{op},
+rounded in the direction @var{rnd} with the corresponding precision of
+@var{sop} and @var{cop}, which must be different variables.
+Return 0 iff both results are exact (see @code{mpfr_sin_cos} for a more
+detailed description of the return value).
+@end deftypefun
+
+@deftypefun int mpfr_sech (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_csch (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_coth (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the hyperbolic secant of @var{op}, cosecant of @var{op},
+cotangent of @var{op}, rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_acosh (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_asinh (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_atanh (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the inverse hyperbolic cosine, sine or tangent of @var{op},
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_fac_ui (mpfr_t @var{rop}, unsigned long int @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the factorial of @var{op}, rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_log1p (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the logarithm of one plus @var{op},
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_expm1 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @m{e^{op}-1,the exponential of @var{op} followed by a
+subtraction by one}, rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_eint (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the exponential integral of @var{op},
+rounded in the direction @var{rnd}.
+For positive @var{op},
+the exponential integral is the sum of Euler's constant, of the logarithm
+of @var{op}, and of the sum for k from 1 to infinity of
+@ifnottex
+@var{op} to the power k, divided by k and factorial(k).
+@end ifnottex
+@tex
+$@var{op}^k/(k \cdot k!)$.
+@end tex
+For negative @var{op}, @var{rop} is set to NaN
+(this definition for negative argument follows formula 5.1.2 from the
+Handbook of Mathematical Functions from Abramowitz and Stegun, a future
+version might use another definition).
+@end deftypefun
+
+@deftypefun int mpfr_li2 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to real part of the dilogarithm of @var{op}, rounded in the
+direction @var{rnd}. MPFR defines the dilogarithm function as
+@m{-\int_{t=0}^{op} \log(1-t)/t\ dt,the integral of -log(1-t)/t from 0
+to @var{op}}.
+@c FIXME: It should be {@var{op}} instead of {op} above, but pdftex fails
+@c on the correct form.
+@end deftypefun
+
+@deftypefun int mpfr_gamma (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the Gamma function on @var{op}, rounded in the
+direction @var{rnd}. When @var{op} is a negative integer, @var{rop} is set
+to NaN.
+@end deftypefun
+
+@deftypefun int mpfr_lngamma (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the logarithm of the Gamma function on @var{op},
+rounded in the direction @var{rnd}.
+When @math{@minus{}2@var{k}@minus{}1 @le{} @var{op} @le{} @minus{}2@var{k}},
+@var{k} being a non-negative integer, @var{rop} is set to NaN.
+See also @code{mpfr_lgamma}.
+@end deftypefun
+
+@deftypefun int mpfr_lgamma (mpfr_t @var{rop}, int *@var{signp}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the logarithm of the absolute value of the
+Gamma function on @var{op}, rounded in the direction @var{rnd}. The sign
+(1 or @minus{}1) of Gamma(@var{op}) is returned in the object pointed to
+by @var{signp}. When @var{op} is an infinity or a non-positive integer, set
+@var{rop} to +Inf. When @var{op} is NaN, @minus{}Inf or a negative integer,
+*@var{signp} is undefined, and when @var{op} is @pom{}0, *@var{signp} is
+the sign of the zero.
+@end deftypefun
+
+@deftypefun int mpfr_digamma (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the Digamma (sometimes also called Psi)
+function on @var{op}, rounded in the direction @var{rnd}.
+When @var{op} is a negative integer, set @var{rop} to NaN.
+@end deftypefun
+
+@deftypefun int mpfr_zeta (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_zeta_ui (mpfr_t @var{rop}, unsigned long @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the Riemann Zeta function on @var{op},
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_erf (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_erfc (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the error function on @var{op}
+(resp.@: the complementary error function on @var{op})
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_j0 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_j1 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_jn (mpfr_t @var{rop}, long @var{n}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the first kind Bessel function of order 0,
+(resp.@: 1 and @var{n})
+on @var{op}, rounded in the direction @var{rnd}. When @var{op} is
+NaN, @var{rop} is always set to NaN. When @var{op} is plus or minus Infinity,
+@var{rop} is set to +0. When @var{op} is zero, and @var{n} is not zero,
+@var{rop} is set to +0 or @minus{}0 depending on the parity and sign of @var{n},
+and the sign of @var{op}.
+@end deftypefun
+
+@deftypefun int mpfr_y0 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_y1 (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_yn (mpfr_t @var{rop}, long @var{n}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the second kind Bessel function of order 0
+(resp.@: 1 and @var{n})
+on @var{op}, rounded in the direction @var{rnd}. When @var{op} is
+NaN or negative, @var{rop} is always set to NaN. When @var{op} is +Inf,
+@var{rop} is set to +0. When @var{op} is zero, @var{rop} is set to +Inf
+or @minus{}Inf depending on the parity and sign of @var{n}.
+@end deftypefun
+
+@deftypefun int mpfr_fma (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_t @var{op3}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_fms (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_t @var{op3}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @math{(@var{op1} @GMPtimes{} @var{op2}) + @var{op3}}
+(resp.@: @math{(@var{op1} @GMPtimes{} @var{op2}) - @var{op3}})
+rounded in the direction @var{rnd}.
+@end deftypefun
+
+@deftypefun int mpfr_agm (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the arithmetic-geometric mean of @var{op1} and @var{op2},
+rounded in the direction @var{rnd}.
+The arithmetic-geometric mean is the common limit of the sequences
+@m{u_n,@var{u}_@var{n}} and @m{v_n,@var{v}_@var{n}},
+where @m{u_0,@var{u}_@var{0}}=@var{op1}, @m{v_0,@var{v}_@var{0}}=@var{op2},
+@m{u_{n+1},@var{u}_(@var{n}+1)} is the
+arithmetic mean of @m{u_n,@var{u}_@var{n}} and @m{v_n,@var{v}_@var{n}},
+and @m{v_{n+1},@var{v}_(@var{n}+1)} is the geometric mean of
+@m{u_n,@var{u}_@var{n}} and @m{v_n,@var{v}_@var{n}}.
+If any operand is negative, set @var{rop} to NaN.
+@end deftypefun
+
+@deftypefun int mpfr_hypot (mpfr_t @var{rop}, mpfr_t @var{x}, mpfr_t @var{y}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the Euclidean norm of @var{x} and @var{y},
+@ifnottex
+i.e., the square root of the sum of the squares of @var{x} and @var{y},
+@end ifnottex
+@tex
+i.e., $\sqrt{x^2+y^2}$,
+@end tex
+rounded in the direction @var{rnd}.
+Special values are handled as described in Section F.9.4.3 of
+the ISO C99 and IEEE 754-2008 standards:
+If @var{x} or @var{y} is an infinity, then +Inf is returned in @var{rop},
+even if the other number is NaN.
+@end deftypefun
+
+@deftypefun int mpfr_ai (mpfr_t @var{rop}, mpfr_t @var{x}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the value of the Airy function Ai
+ on @var{x}, rounded in the direction @var{rnd}.
+When @var{x} is
+NaN,
+@var{rop} is always set to NaN. When @var{x} is +Inf or @minus{}Inf,
+@var{rop} is +0.
+The current implementation is not intended to be used with large arguments.
+It works with @GMPabs{@var{x}} typically smaller than 500. For larger arguments,
+other methods should be used and will be implemented in a future version.
+@end deftypefun
+
+@deftypefun int mpfr_const_log2 (mpfr_t @var{rop}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_const_pi (mpfr_t @var{rop}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_const_euler (mpfr_t @var{rop}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_const_catalan (mpfr_t @var{rop}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the logarithm of 2, the value of @m{\pi,Pi},
+of Euler's constant 0.577@dots{}, of Catalan's constant 0.915@dots{},
+respectively, rounded in the direction
+@var{rnd}. These functions cache the computed values to avoid other
+calculations if a lower or equal precision is requested. To free these caches,
+use @code{mpfr_free_cache}.
+@end deftypefun
+
+@deftypefun void mpfr_free_cache (void)
+Free various caches used by MPFR internally, in particular the
+caches used by the functions computing constants (@code{mpfr_const_log2},
+@code{mpfr_const_pi},
+@code{mpfr_const_euler} and @code{mpfr_const_catalan}).
+You should call this function before terminating a thread, even if you did
+not call these functions directly (they could have been called internally).
+@end deftypefun
+
+@deftypefun int mpfr_sum (mpfr_t @var{rop}, mpfr_ptr const @var{tab}[], unsigned long int @var{n}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the sum of all elements of @var{tab}, whose size is @var{n},
+rounded in the direction @var{rnd}. Warning: for efficiency reasons,
+@var{tab} is an array of pointers
+to @code{mpfr_t}, not an array of @code{mpfr_t}.
+If the returned @code{int} value is zero, @var{rop} is guaranteed to be the
+exact sum; otherwise @var{rop} might be smaller than, equal to, or larger than
+the exact sum (in accordance to the rounding mode).
+However, @code{mpfr_sum} does guarantee the result is correctly rounded.
+@end deftypefun
+
+@node Input and Output Functions, Formatted Output Functions, Special Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Float input and output functions
+@cindex Input functions
+@cindex Output functions
+@cindex I/O functions
+@section Input and Output Functions
+
+This section describes functions that perform input from an input/output
+stream, and functions that output to an input/output stream.
+Passing a null pointer for a @code{stream} to any of these functions will make
+them read from @code{stdin} and write to @code{stdout}, respectively.
+
+When using any of these functions, you must include the @code{<stdio.h>}
+standard header before @file{mpfr.h}, to allow @file{mpfr.h} to define
+prototypes for these functions.
+
+@deftypefun size_t mpfr_out_str (FILE *@var{stream}, int @var{base}, size_t @var{n}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Output @var{op} on stream @var{stream}, as a string of digits in
+base @var{base}, rounded in the direction @var{rnd}.
+The base may vary from 2 to 62. Print @var{n} significant digits exactly,
+or if @var{n} is 0, enough digits so that @var{op} can be read back
+exactly (see @code{mpfr_get_str}).
+
+In addition to the significant digits, a decimal point (defined by the
+current locale) at the right of the
+first digit and a trailing exponent in base 10, in the form @samp{eNNN},
+are printed. If @var{base} is greater than 10, @samp{@@} will be used
+instead of @samp{e} as exponent delimiter.
+
+Return the number of characters written, or if an error occurred, return 0.
+@end deftypefun
+
+@deftypefun size_t mpfr_inp_str (mpfr_t @var{rop}, FILE *@var{stream}, int @var{base}, mpfr_rnd_t @var{rnd})
+Input a string in base @var{base} from stream @var{stream},
+rounded in the direction @var{rnd}, and put the
+read float in @var{rop}.
+@c The argument @var{base} must be in the range 2 to 62.
+
+@c The string is of the form @samp{M@@N} or, if the
+@c base is 10 or less, alternatively @samp{MeN} or @samp{MEN}, or, if the base
+@c is 16, alternatively @samp{MpB} or @samp{MPB}.
+@c @samp{M} is the significand in the specified base, @samp{N} is the exponent
+@c written in decimal for the specified base, and in base 16, @samp{B} is the
+@c binary exponent written in decimal (i.e., it indicates the power of 2 by
+@c which the significand is to be scaled).
+This function reads a word (defined as a sequence of characters between
+whitespace) and parses it using @code{mpfr_set_str}.
+See the documentation of @code{mpfr_strtofr} for a detailed description
+of the valid string formats.
+@c Special values can be read as follows (the case does not matter):
+@c @code{@@NaN@@}, @code{@@Inf@@}, @code{+@@Inf@@} and @code{-@@Inf@@},
+@c possibly followed by other characters; if the base is smaller or equal
+@c to 16, the following strings are accepted too: @code{NaN}, @code{Inf},
+@c @code{+Inf} and @code{-Inf}.
+
+Return the number of bytes read, or if an error occurred, return 0.
+@end deftypefun
+
+@c @deftypefun void mpfr_inp_raw (mpfr_t @var{float}, FILE *@var{stream})
+@c Input from stdio stream @var{stream} in the format written by
+@c @code{mpfr_out_raw}, and put the result in @var{float}.
+@c @end deftypefun
+
+@node Formatted Output Functions, Integer Related Functions, Input and Output Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Float output functions
+@cindex Output functions
+@cindex I/O functions
+@section Formatted Output Functions
+
+@subsection Requirements
+The class of @code{mpfr_printf} functions provides formatted output in a
+similar manner as the standard C @code{printf}. These functions are defined
+only if your system supports ISO C variadic functions and the corresponding
+argument access macros.
+
+When using any of these functions, you must include the @code{<stdio.h>}
+standard header before @file{mpfr.h}, to allow @file{mpfr.h} to define
+prototypes for these functions.
+
+@subsection Format String
+The format specification accepted by @code{mpfr_printf} is an extension of the
+@code{printf} one. The conversion specification is of the form:
+@example
+% [flags] [width] [.[precision]] [type] [rounding] conv
+@end example
+@samp{flags}, @samp{width}, and @samp{precision} have the same meaning as for
+the standard @code{printf} (in particular, notice that the @samp{precision} is
+related to the number of digits displayed in the base chosen by @samp{conv}
+and not related to the internal precision of the @code{mpfr_t} variable).
+@code{mpfr_printf} accepts the same @samp{type} specifiers as GMP (except the
+non-standard and deprecated @samp{q}, use @samp{ll} instead), namely the
+length modifiers defined in the C standard:
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @samp{h} @tab @code{short}
+@item @samp{hh} @tab @code{char}
+@item @samp{j} @tab @code{intmax_t} or @code{uintmax_t}
+@item @samp{l} @tab @code{long} or @code{wchar_t}
+@item @samp{ll} @tab @code{long long}
+@item @samp{L} @tab @code{long double}
+@item @samp{t} @tab @code{ptrdiff_t}
+@item @samp{z} @tab @code{size_t}
+@end multitable
+@end quotation
+
+and the @samp{type} specifiers defined in GMP plus @samp{R} and @samp{P}
+specific to MPFR (the second column in the table below shows the type of the
+argument read in the argument list and the kind of @samp{conv} specifier to
+use after the @samp{type} specifier):
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @samp{F} @tab @code{mpf_t}, float conversions
+@item @samp{Q} @tab @code{mpq_t}, integer conversions
+@item @samp{M} @tab @code{mp_limb_t}, integer conversions
+@item @samp{N} @tab @code{mp_limb_t} array, integer conversions
+@item @samp{Z} @tab @code{mpz_t}, integer conversions
+
+@item @samp{P} @tab @code{mpfr_prec_t}, integer conversions
+@item @samp{R} @tab @code{mpfr_t}, float conversions
+@end multitable
+@end quotation
+
+The @samp{type} specifiers have the same restrictions as those
+mentioned in the GMP documentation:
+@ifinfo
+@pxref{Formatted Output Strings,,, gmp.info,GNU MP}.
+@end ifinfo
+@ifnotinfo
+see Section ``Formatted Output Strings'' in @cite{GNU MP}.
+@end ifnotinfo
+In particular, the @samp{type} specifiers (except @samp{R} and @samp{P}) are
+supported only if they are supported by @code{gmp_printf} in your GMP build;
+this implies that the standard specifiers, such as @samp{t}, must @emph{also}
+be supported by your C library if you want to use them.
+
+The @samp{rounding} field is specific to @code{mpfr_t} arguments and should
+not be used with other types.
+
+With conversion specification not involving @samp{P} and @samp{R} types,
+@code{mpfr_printf} behaves exactly as @code{gmp_printf}.
+
+The @samp{P} type specifies that a following @samp{o}, @samp{u}, @samp{x}, or
+@samp{X} conversion specifier applies to a @code{mpfr_prec_t} argument.
+It is needed because the @code{mpfr_prec_t} type does not necessarily
+correspond to an @code{unsigned int} or any fixed standard type.
+The @samp{precision} field specifies the minimum number of digits to
+appear. The default @samp{precision} is 1.
+For example:
+@example
+mpfr_t x;
+mpfr_prec_t p;
+mpfr_init (x);
+@dots{}
+p = mpfr_get_prec (x);
+mpfr_printf ("variable x with %Pu bits", p);
+@end example
+
+The @samp{R} type specifies that a following @samp{a}, @samp{A}, @samp{b},
+@samp{e}, @samp{E}, @samp{f}, @samp{F}, @samp{g}, @samp{G}, or @samp{n}
+conversion specifier applies to a @code{mpfr_t} argument.
+The @samp{R} type can be followed by a @samp{rounding} specifier denoted by
+one of the following characters:
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @samp{U} @tab round toward plus infinity
+@item @samp{D} @tab round toward minus infinity
+@item @samp{Y} @tab round away from zero
+@item @samp{Z} @tab round toward zero
+@item @samp{N} @tab round to nearest (with ties to even)
+@item @samp{*} @tab rounding mode indicated by the @code{mpfr_rnd_t} argument
+just before the corresponding @code{mpfr_t} variable.
+@end multitable
+@end quotation
+
+The default rounding mode is rounding to nearest.
+The following three examples are equivalent:
+@example
+mpfr_t x;
+mpfr_init (x);
+@dots{}
+mpfr_printf ("%.128Rf", x);
+mpfr_printf ("%.128RNf", x);
+mpfr_printf ("%.128R*f", MPFR_RNDN, x);
+@end example
+
+Note that the rounding away from zero mode is specified with @samp{Y}
+because ISO C reserves the @samp{A} specifier for hexadecimal output (see
+below).
+
+The output @samp{conv} specifiers allowed with @code{mpfr_t} parameter are:
+
+@quotation
+@multitable {(space)} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @samp{a} @samp{A} @tab hex float, C99 style
+@item @samp{b} @tab binary output
+@item @samp{e} @samp{E} @tab scientific format float
+@item @samp{f} @samp{F} @tab fixed point float
+@item @samp{g} @samp{G} @tab fixed or scientific float
+@end multitable
+@end quotation
+
+The conversion specifier @samp{b} which displays the argument in binary is
+specific to @code{mpfr_t} arguments and should not be used with other types.
+Other conversion specifiers have the same meaning as for a @code{double}
+argument.
+
+In case of non-decimal output, only the significand is written in the
+specified base, the exponent is always displayed in decimal.
+Special values are always displayed as @code{nan}, @code{-inf}, and @code{inf}
+for @samp{a}, @samp{b}, @samp{e}, @samp{f}, and @samp{g} specifiers and
+@code{NAN}, @code{-INF}, and @code{INF} for @samp{A}, @samp{E}, @samp{F}, and
+@samp{G} specifiers.
+
+If the @samp{precision} field is not empty, the @code{mpfr_t} number is
+rounded to the given precision in the direction specified by the rounding
+mode.
+If the precision is zero with rounding to nearest mode and one of the
+following @samp{conv} specifiers: @samp{a}, @samp{A}, @samp{b}, @samp{e},
+@samp{E}, tie case is rounded to even when it lies between two consecutive
+values at the
+wanted precision which have the same exponent, otherwise, it is rounded away
+from zero.
+For instance, 85 is displayed as "8e+1" and 95 is displayed as "1e+2" with the
+format specification @code{"%.0RNe"}.
+This also applies when the @samp{g} (resp. @samp{G}) conversion specifier uses
+the @samp{e} (resp. @samp{E}) style.
+If the precision is set to a value greater than the maximum value for an
+@code{int}, it will be silently reduced down to @code{INT_MAX}.
+
+If the @samp{precision} field is empty (as in @code{%Re} or @code{%.RE}) with
+@samp{conv} specifier @samp{e} and @samp{E}, the number is displayed with
+enough digits so that it can be read back exactly, assuming that the input and
+output variables have the same precision and that the input and output
+rounding modes are both rounding to nearest (as for @code{mpfr_get_str}).
+The default precision for an empty @samp{precision} field with @samp{conv}
+specifiers @samp{f}, @samp{F}, @samp{g}, and @samp{G} is 6.
+
+
+@subsection Functions
+
+For all the following functions, if the number of characters which ought to be
+written appears to exceed the maximum limit for an @code{int}, nothing is
+written in the stream (resp.@: to @code{stdout}, to @var{buf}, to @var{str}),
+the function returns @minus{}1, sets the @emph{erange} flag, and (in
+POSIX system only) @code{errno} is set to @code{EOVERFLOW}.
+
+@deftypefun int mpfr_fprintf (FILE *@var{stream}, const char *@var{template}, @dots{})
+@deftypefunx int mpfr_vfprintf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap})
+Print to the stream @var{stream} the optional arguments under the control of
+the template string @var{template}.
+Return the number of characters written or a negative value if an error
+occurred.
+@c If the number of characters which ought to be written appears
+@c to exceed the maximum limit for an @code{int}, nothing is written in the
+@c stream, the function returns @minus{}1, sets the @emph{erange} flag, and (in
+@c POSIX system only) @code{errno} is set to @code{EOVERFLOW}.
+@end deftypefun
+
+@deftypefun int mpfr_printf (const char *@var{template}, @dots{})
+@deftypefunx int mpfr_vprintf (const char *@var{template}, va_list @var{ap})
+Print to @code{stdout} the optional arguments under the control of the
+template string @var{template}.
+Return the number of characters written or a negative value if an error
+occurred.
+@c If the number of characters which ought to be written appears
+@c to exceed the maximum limit for an @code{int}, nothing is written in
+@c @code{stdout}, the function returns @minus{}1, sets the @emph{erange} flag,
+@c and (in POSIX system only) @code{errno} is set to @code{EOVERFLOW}.
+@end deftypefun
+
+@deftypefun int mpfr_sprintf (char *@var{buf}, const char *@var{template}, @dots{})
+@deftypefunx int mpfr_vsprintf (char *@var{buf}, const char *@var{template}, va_list @var{ap})
+Form a null-terminated string corresponding to the optional arguments under
+the control of the template string @var{template}, and print it in
+@var{buf}. No overlap is permitted between
+@var{buf} and the other arguments.
+Return the number of characters written in the array @var{buf}
+@emph{not counting}
+the terminating null character or a negative value if an error occurred.
+@c If the number of characters which ought to be written appears to exceed the
+@c maximum limit for an @code{int}, nothing is written in @var{buf}, the function
+@c returns @minus{}1, sets the @emph{erange} flag, and (in POSIX system only)
+@c code{errno} is set to @code{EOVERFLOW}.
+@end deftypefun
+
+@deftypefun int mpfr_snprintf (char *@var{buf}, size_t @var{n}, const char *@var{template}, @dots{})
+@deftypefunx int mpfr_vsnprintf (char *@var{buf}, size_t @var{n}, const char *@var{template}, va_list @var{ap})
+Form a null-terminated string corresponding to the optional arguments under
+the control of the template string @var{template}, and print it in
+@var{buf}. If @var{n} is zero, nothing is
+written and @var{buf} may be a null pointer, otherwise, the @var{n}@minus{}1
+first characters are written in @var{buf} and the @var{n}-th is a null character.
+Return the number of characters that would have been written had @var{n} be
+sufficiently large, @emph{not counting}
+the terminating null character, or a negative value if an error occurred.
+@c If the number of characters produced by the
+@c optional arguments under the control of the template string @var{template}
+@c appears to exceed the maximum limit for an @code{int}, nothing is written in
+@c @var{buf}, the function returns @minus{}1, sets the @emph{erange} flag, and
+@c (in POSIX system only) @code{errno} is set to @code{EOVERFLOW}.
+@end deftypefun
+
+@deftypefun int mpfr_asprintf (char **@var{str}, const char *@var{template}, @dots{})
+@deftypefunx int mpfr_vasprintf (char **@var{str}, const char *@var{template}, va_list @var{ap})
+Write their output as a null terminated string in a block of memory allocated
+using the current allocation function. A pointer to the block is stored in
+@var{str}. The block of memory must be freed using @code{mpfr_free_str}.
+The return value is the number of characters written in the string, excluding
+the null-terminator, or a negative value if an error occurred.
+@c If the number of
+@c characters produced by the optional arguments under the control of the
+@c template string @var{template} appears to exceed the maximum limit for an
+@c @code{int}, @var{str} is a null pointer, the function returns @minus{}1, sets
+@c the @emph{erange} flag, and (in POSIX system only) @code{errno} is set to
+@c @code{EOVERFLOW}.
+@end deftypefun
+
+@node Integer Related Functions, Rounding Related Functions, Formatted Output Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Integer related functions
+@section Integer and Remainder Related Functions
+
+@deftypefun int mpfr_rint (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_ceil (mpfr_t @var{rop}, mpfr_t @var{op})
+@deftypefunx int mpfr_floor (mpfr_t @var{rop}, mpfr_t @var{op})
+@deftypefunx int mpfr_round (mpfr_t @var{rop}, mpfr_t @var{op})
+@deftypefunx int mpfr_trunc (mpfr_t @var{rop}, mpfr_t @var{op})
+Set @var{rop} to @var{op} rounded to an integer.
+@code{mpfr_rint} rounds to the nearest representable integer in the
+given direction @var{rnd}, @code{mpfr_ceil} rounds
+to the next higher or equal representable integer, @code{mpfr_floor} to
+the next lower or equal representable integer, @code{mpfr_round} to the
+nearest representable integer, rounding halfway cases away from zero
+(as in the roundTiesToAway mode of IEEE 754-2008),
+and @code{mpfr_trunc} to the next representable integer toward zero.
+
+The returned value is zero when the result is exact, positive when it is
+greater than the original value of @var{op}, and negative when it is smaller.
+More precisely, the returned value is 0 when @var{op} is an integer
+representable in @var{rop}, 1 or @minus{}1 when @var{op} is an integer
+that is not representable in @var{rop}, 2 or @minus{}2 when @var{op} is
+not an integer.
+
+Note that @code{mpfr_round} is different from @code{mpfr_rint} called with
+the rounding to nearest mode (where halfway cases are rounded to an even
+integer or significand). Note also that no double rounding is performed; for
+instance, 10.5 (1010.1 in binary) is rounded by @code{mpfr_rint} with
+rounding to nearest to 12 (1100
+in binary) in 2-bit precision, because the two enclosing numbers representable
+on two bits are 8 and 12, and the closest is 12.
+(If one first rounded to an integer, one would round 10.5 to 10 with
+even rounding, and then 10 would be rounded to 8 again with even rounding.)
+@end deftypefun
+
+@deftypefun int mpfr_rint_ceil (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_rint_floor (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_rint_round (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_rint_trunc (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to @var{op} rounded to an integer.
+@code{mpfr_rint_ceil} rounds to the next higher or equal integer,
+@code{mpfr_rint_floor} to the next lower or equal integer,
+@code{mpfr_rint_round} to the nearest integer, rounding halfway cases away
+from zero, and @code{mpfr_rint_trunc} to the next integer toward zero.
+If the result is not representable, it is rounded in the direction @var{rnd}.
+The returned value is the ternary value associated with the considered
+round-to-integer function (regarded in the same way as any other
+mathematical function).
+Contrary to @code{mpfr_rint}, those functions do perform a double rounding:
+first @var{op} is rounded to the nearest integer in the direction given by
+the function name, then this nearest integer (if not representable) is
+rounded in the given direction @var{rnd}.
+For example, @code{mpfr_rint_round} with rounding to nearest and a precision
+of two bits rounds 6.5 to 7 (halfway cases away from zero), then 7 is
+rounded to 8 by the round-even rule, despite the fact that 6 is also
+representable on two bits, and is closer to 6.5 than 8.
+@end deftypefun
+
+@deftypefun int mpfr_frac (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the fractional part of @var{op}, having the same sign as
+@var{op}, rounded in the direction @var{rnd} (unlike in @code{mpfr_rint},
+@var{rnd} affects only how the exact fractional part is rounded, not how
+the fractional part is generated).
+@end deftypefun
+
+@deftypefun int mpfr_modf (mpfr_t @var{iop}, mpfr_t @var{fop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+Set simultaneously @var{iop} to the integral part of @var{op} and @var{fop} to
+the fractional part of @var{op}, rounded in the direction @var{rnd} with the
+corresponding precision of @var{iop} and @var{fop} (equivalent to
+@code{mpfr_trunc(@var{iop}, @var{op}, @var{rnd})} and
+@code{mpfr_frac(@var{fop}, @var{op}, @var{rnd})}). The variables @var{iop} and
+@var{fop} must be different. Return 0 iff both results are exact (see
+@code{mpfr_sin_cos} for a more detailed description of the return value).
+@end deftypefun
+
+@deftypefun int mpfr_fmod (mpfr_t @var{r}, mpfr_t @var{x}, mpfr_t @var{y}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_remainder (mpfr_t @var{r}, mpfr_t @var{x}, mpfr_t @var{y}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_remquo (mpfr_t @var{r}, long* @var{q}, mpfr_t @var{x}, mpfr_t @var{y}, mpfr_rnd_t @var{rnd})
+Set @var{r} to the value of @math{@var{x} - @var{n}@var{y}}, rounded
+according to the direction @var{rnd}, where @var{n} is the integer quotient
+of @var{x} divided by @var{y}, defined as follows: @var{n} is rounded
+toward zero for @code{mpfr_fmod}, and to the nearest integer (ties rounded
+to even) for @code{mpfr_remainder} and @code{mpfr_remquo}.
+
+Special values are handled as described in Section F.9.7.1 of
+the ISO C99 standard:
+If @var{x} is infinite or @var{y} is zero, @var{r} is NaN.
+If @var{y} is infinite and @var{x} is finite, @var{r} is @var{x} rounded
+to the precision of @var{r}.
+If @var{r} is zero, it has the sign of @var{x}.
+The return value is the ternary value corresponding to @var{r}.
+
+Additionally, @code{mpfr_remquo} stores
+the low significant bits from the quotient @var{n} in @var{*q}
+(more precisely the number of bits in a @code{long} minus one),
+with the sign of @var{x} divided by @var{y}
+(except if those low bits are all zero, in which case zero is returned).
+Note that @var{x} may be so large in magnitude relative to @var{y} that an
+exact representation of the quotient is not practical.
+The @code{mpfr_remainder} and @code{mpfr_remquo} functions are useful for
+additive argument reduction.
+@end deftypefun
+
+@deftypefun int mpfr_integer_p (mpfr_t @var{op})
+Return non-zero iff @var{op} is an integer.
+@end deftypefun
+
+@node Rounding Related Functions, Miscellaneous Functions, Integer Related Functions, MPFR Interface
+@cindex Rounding mode related functions
+@section Rounding Related Functions
+
+@deftypefun void mpfr_set_default_rounding_mode (mpfr_rnd_t @var{rnd})
+Set the default rounding mode to @var{rnd}.
+The default rounding mode is to nearest initially.
+@end deftypefun
+
+@deftypefun mpfr_rnd_t mpfr_get_default_rounding_mode (void)
+Get the default rounding mode.
+@end deftypefun
+
+@deftypefun int mpfr_prec_round (mpfr_t @var{x}, mpfr_prec_t @var{prec}, mpfr_rnd_t @var{rnd})
+Round @var{x} according to @var{rnd} with precision @var{prec}, which
+must be an integer between @code{MPFR_PREC_MIN} and @code{MPFR_PREC_MAX}
+(otherwise the behavior is undefined).
+If @var{prec} is greater or equal to the precision of @var{x}, then new
+space is allocated for the significand, and it is filled with zeros.
+Otherwise, the significand is rounded to precision @var{prec} with the given
+direction. In both cases, the precision of @var{x} is changed to @var{prec}.
+
+Here is an example of how to use @code{mpfr_prec_round} to implement
+Newton's algorithm to compute the inverse of @var{a}, assuming @var{x} is
+already an approximation to @var{n} bits:
+@example
+ mpfr_set_prec (t, 2 * n);
+ mpfr_set (t, a, MPFR_RNDN); /* round a to 2n bits */
+ mpfr_mul (t, t, x, MPFR_RNDN); /* t is correct to 2n bits */
+ mpfr_ui_sub (t, 1, t, MPFR_RNDN); /* high n bits cancel with 1 */
+ mpfr_prec_round (t, n, MPFR_RNDN); /* t is correct to n bits */
+ mpfr_mul (t, t, x, MPFR_RNDN); /* t is correct to n bits */
+ mpfr_prec_round (x, 2 * n, MPFR_RNDN); /* exact */
+ mpfr_add (x, x, t, MPFR_RNDN); /* x is correct to 2n bits */
+@end example
+@end deftypefun
+
+@deftypefun int mpfr_can_round (mpfr_t @var{b}, mpfr_exp_t @var{err}, mpfr_rnd_t @var{rnd1}, mpfr_rnd_t @var{rnd2}, mpfr_prec_t @var{prec})
+Assuming @var{b} is an approximation of an unknown number
+@var{x} in the direction @var{rnd1} with error at most two to the power
+E(b)-@var{err} where E(b) is the exponent of @var{b}, return a non-zero
+value if one is able to round correctly @var{x} to precision
+@var{prec} with the direction @var{rnd2},
+and 0 otherwise (including for NaN and Inf).
+This function @strong{does not modify} its arguments.
+
+If @var{rnd1} is @code{MPFR_RNDN}, then the sign of the error is
+unknown, but its absolute value is the same, so that the possible range
+is twice as large as with a directed rounding for @var{rnd1}.
+
+Note: if one wants to also determine the correct @ref{ternary value} when
+rounding @var{b} to precision @var{prec} with rounding mode @var{rnd},
+a useful trick is the following:
+@verbatim
+if (mpfr_can_round (b, err, MPFR_RNDN, MPFR_RNDZ, prec + (rnd == MPFR_RNDN)))
+ ...
+@end verbatim
+Indeed, if @var{rnd} is @code{MPFR_RNDN}, this will check if one can
+round to @var{prec}+1 bits with a directed rounding:
+if so, one can surely round to nearest to @var{prec} bits,
+and in addition one can determine the correct ternary value, which would not
+be the case when @var{b} is near from a value exactly representable on
+@var{prec} bits.
+@end deftypefun
+
+@deftypefun mpfr_prec_t mpfr_min_prec (mpfr_t @var{x})
+Return the minimal number of bits required to store the significand of
+@var{x}, and 0 for special values, including 0. (Warning: the returned
+value can be less than @code{MPFR_PREC_MIN}.)
+
+The function name is subject to change.
+@end deftypefun
+
+@deftypefun {const char *} mpfr_print_rnd_mode (mpfr_rnd_t @var{rnd})
+Return a string ("MPFR_RNDD", "MPFR_RNDU", "MPFR_RNDN", "MPFR_RNDZ",
+"MPFR_RNDA") corresponding to the rounding mode @var{rnd}, or a null pointer
+if @var{rnd} is an invalid rounding mode.
+@end deftypefun
+
+@node Miscellaneous Functions, Exception Related Functions, Rounding Related Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Miscellaneous float functions
+@section Miscellaneous Functions
+
+@deftypefun void mpfr_nexttoward (mpfr_t @var{x}, mpfr_t @var{y})
+If @var{x} or @var{y} is NaN, set @var{x} to NaN. If @var{x} and @var{y}
+are equal, @var{x} is unchanged. Otherwise, if @var{x}
+is different from @var{y}, replace @var{x} by the next floating-point
+number (with the precision of @var{x} and the current exponent range)
+in the direction of @var{y}
+(the infinite values are seen as the smallest and largest floating-point
+numbers). If the result is zero, it keeps the same sign. No underflow or
+overflow is generated.
+@end deftypefun
+
+@deftypefun void mpfr_nextabove (mpfr_t @var{x})
+@deftypefunx void mpfr_nextbelow (mpfr_t @var{x})
+Equivalent to @code{mpfr_nexttoward} where @var{y} is plus infinity
+(resp.@: minus infinity).
+@end deftypefun
+
+@deftypefun int mpfr_min (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_max (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+Set @var{rop} to the minimum (resp.@: maximum)
+of @var{op1} and @var{op2}. If @var{op1}
+and @var{op2} are both NaN, then @var{rop} is set to NaN. If @var{op1}
+or @var{op2} is NaN, then @var{rop} is set to the numeric value. If
+@var{op1} and @var{op2} are zeros of different signs, then @var{rop}
+is set to @minus{}0 (resp.@: +0).
+@end deftypefun
+
+@deftypefun int mpfr_urandomb (mpfr_t @var{rop}, gmp_randstate_t @var{state})
+Generate a uniformly distributed random float in the interval
+@math{0 @le{} @var{rop} < 1}. More precisely, the number can be seen as a
+float with a random non-normalized significand and exponent 0, which is then
+normalized (thus if @var{e} denotes the exponent after normalization, then
+the least @math{-@var{e}} significant bits of the significand are always 0).
+
+Return 0, unless the exponent is not in the current exponent range, in
+which case @var{rop} is set to NaN and a non-zero value is returned (this
+should never happen in practice, except in very specific cases). The
+second argument is a @code{gmp_randstate_t} structure which should be
+created using the GMP @code{gmp_randinit} function (see the GMP manual).
+
+Note: for a given version of MPFR, the returned value of @var{rop} and the
+new value of @var{state} (which controls further random values) do not depend
+on the machine word size.
+@end deftypefun
+
+@deftypefun int mpfr_urandom (mpfr_t @var{rop}, gmp_randstate_t @var{state}, mpfr_rnd_t @var{rnd})
+Generate a uniformly distributed random float.
+The floating-point number @var{rop} can be seen as if a random real number is
+generated according to the continuous uniform distribution on the interval
+[0, 1] and then rounded in the direction @var{rnd}.
+
+The second argument is a @code{gmp_randstate_t} structure which should be
+created using the GMP @code{gmp_randinit} function (see the GMP manual).
+
+Note: the note for @code{mpfr_urandomb} holds too. In addition, the exponent
+range and the rounding mode might have a side effect on the next random state.
+@end deftypefun
+
+@deftypefun int mpfr_grandom (mpfr_t @var{rop1}, mpfr_t @var{rop2}, gmp_randstate_t @var{state}, mpfr_rnd_t @var{rnd})
+Generate two random floats according to a standard normal gaussian
+distribution. If @var{rop2} is a null pointer, then only one value is generated
+and stored in @var{rop1}.
+
+The floating-point number @var{rop1} (and @var{rop2}) can be seen as if a
+random real number were generated according to the standard normal gaussian
+distribution and then rounded in the direction @var{rnd}.
+
+The third argument is a @code{gmp_randstate_t} structure, which should be
+created using the GMP @code{gmp_randinit} function (see the GMP manual).
+
+The combination of the ternary values is returned like with
+@code{mpfr_sin_cos}. If @var{rop2} is a null pointer, the second ternary
+value is assumed to be 0 (note that the encoding of the only ternary value
+is not the same as the usual encoding for functions that return only one
+result). Otherwise the ternary value of a random number is always non-zero.
+
+Note: the note for @code{mpfr_urandomb} holds too. In addition, the exponent
+range and the rounding mode might have a side effect on the next random state.
+@end deftypefun
+
+@deftypefun mpfr_exp_t mpfr_get_exp (mpfr_t @var{x})
+Return the exponent of @var{x}, assuming that @var{x} is a non-zero ordinary
+number and the significand is considered in [1/2,1). The behavior for NaN,
+infinity or zero is undefined.
+@end deftypefun
+
+@deftypefun int mpfr_set_exp (mpfr_t @var{x}, mpfr_exp_t @var{e})
+Set the exponent of @var{x} if @var{e} is in the current exponent range,
+and return 0 (even if @var{x} is not a non-zero ordinary number);
+otherwise, return a non-zero value.
+The significand is assumed to be in [1/2,1).
+@end deftypefun
+
+@deftypefun int mpfr_signbit (mpfr_t @var{op})
+Return a non-zero value iff @var{op} has its sign bit set (i.e., if it is
+negative, @minus{}0, or a NaN whose representation has its sign bit set).
+@end deftypefun
+
+@deftypefun int mpfr_setsign (mpfr_t @var{rop}, mpfr_t @var{op}, int @var{s}, mpfr_rnd_t @var{rnd})
+Set the value of @var{rop} from @var{op}, rounded toward the given
+direction @var{rnd}, then set (resp.@: clear) its sign bit if @var{s}
+is non-zero (resp.@: zero), even when @var{op} is a NaN.
+@end deftypefun
+
+@deftypefun int mpfr_copysign (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+Set the value of @var{rop} from @var{op1}, rounded toward the given
+direction @var{rnd}, then set its sign bit to that of @var{op2} (even
+when @var{op1} or @var{op2} is a NaN). This function is equivalent to
+@code{mpfr_setsign (@var{rop}, @var{op1}, mpfr_signbit (@var{op2}), @var{rnd})}.
+@end deftypefun
+
+@c By definition, a C string is always null-terminated, so that we
+@c could just say "string" or "null-terminated character array",
+@c but "null-terminated string" is not an error and probably better
+@c for most users.
+@deftypefun {const char *} mpfr_get_version (void)
+Return the MPFR version, as a null-terminated string.
+@end deftypefun
+
+@defmac MPFR_VERSION
+@defmacx MPFR_VERSION_MAJOR
+@defmacx MPFR_VERSION_MINOR
+@defmacx MPFR_VERSION_PATCHLEVEL
+@defmacx MPFR_VERSION_STRING
+@code{MPFR_VERSION} is the version of MPFR as a preprocessing constant.
+@code{MPFR_VERSION_MAJOR}, @code{MPFR_VERSION_MINOR} and
+@code{MPFR_VERSION_PATCHLEVEL} are respectively the major, minor and patch
+level of MPFR version, as preprocessing constants.
+@code{MPFR_VERSION_STRING} is the version (with an optional suffix, used
+in development and pre-release versions) as a string constant, which can
+be compared to the result of @code{mpfr_get_version} to check at run time
+the header file and library used match:
+@example
+if (strcmp (mpfr_get_version (), MPFR_VERSION_STRING))
+ fprintf (stderr, "Warning: header and library do not match\n");
+@end example
+Note: Obtaining different strings is not necessarily an error, as
+in general, a program compiled with some old MPFR version can be
+dynamically linked with a newer MPFR library version (if allowed
+by the library versioning system).
+@end defmac
+
+@deftypefn Macro long MPFR_VERSION_NUM (@var{major}, @var{minor}, @var{patchlevel})
+Create an integer in the same format as used by @code{MPFR_VERSION} from the
+given @var{major}, @var{minor} and @var{patchlevel}.
+Here is an example of how to check the MPFR version at compile time:
+@example
+#if (!defined(MPFR_VERSION) || (MPFR_VERSION<MPFR_VERSION_NUM(3,0,0)))
+# error "Wrong MPFR version."
+#endif
+@end example
+@end deftypefn
+
+@deftypefun {const char *} mpfr_get_patches (void)
+Return a null-terminated string containing the ids of the patches applied to
+the MPFR library (contents of the @file{PATCHES} file), separated by spaces.
+Note: If the program has been compiled with an older MPFR version and is
+dynamically linked with a new MPFR library version, the identifiers of the
+patches applied to the old (compile-time) MPFR version are not available
+(however this information should not have much interest in general).
+@end deftypefun
+
+@deftypefun int mpfr_buildopt_tls_p (void)
+Return a non-zero value if MPFR was compiled as thread safe using
+compiler-level Thread Local Storage (that is, MPFR was built with the
+@code{--enable-thread-safe} configure option, see @code{INSTALL} file), return
+zero otherwise.
+@end deftypefun
+
+@deftypefun int mpfr_buildopt_decimal_p (void)
+Return a non-zero value if MPFR was compiled with decimal float support (that
+is, MPFR was built with the @code{--enable-decimal-float} configure option),
+return zero otherwise.
+@end deftypefun
+
+@deftypefun int mpfr_buildopt_gmpinternals_p (void)
+Return a non-zero value if MPFR was compiled with GMP internals
+(that is, MPFR was built with either @code{--with-gmp-build} or
+@code{--enable-gmp-internals} configure option), return zero otherwise.
+@end deftypefun
+
+@deftypefun {const char *} mpfr_buildopt_tune_case (void)
+Return a string saying which thresholds file has been used at compile time.
+This file is normally selected from the processor type.
+@end deftypefun
+
+@node Exception Related Functions, Compatibility with MPF, Miscellaneous Functions, MPFR Interface
+@comment node-name, next, previous, up
+@cindex Exception related functions
+@section Exception Related Functions
+
+@deftypefun mpfr_exp_t mpfr_get_emin (void)
+@deftypefunx mpfr_exp_t mpfr_get_emax (void)
+Return the (current) smallest and largest exponents allowed for a
+floating-point variable. The smallest positive value of a floating-point
+variable is @m{1/2 \times 2^{\rm emin}, one half times 2 raised to the
+smallest exponent} and the largest value has the form @m{(1 - \varepsilon)
+\times 2^{\rm emax}, (1 - epsilon) times 2 raised to the largest exponent},
+where @m{\varepsilon,epsilon} depends on the precision of the considered
+variable.
+@end deftypefun
+
+@deftypefun int mpfr_set_emin (mpfr_exp_t @var{exp})
+@deftypefunx int mpfr_set_emax (mpfr_exp_t @var{exp})
+Set the smallest and largest exponents allowed for a floating-point variable.
+Return a non-zero value when @var{exp} is not in the range accepted by the
+implementation (in that case the smallest or largest exponent is not changed),
+and zero otherwise.
+If the user changes the exponent range, it is her/his responsibility to check
+that all current floating-point variables are in the new allowed range
+(for example using @code{mpfr_check_range}), otherwise the subsequent
+behavior will be undefined, in the sense of the ISO C standard.
+@c It is also her/his responsibility to check that @m {emin <= emax}.
+@end deftypefun
+
+@deftypefun mpfr_exp_t mpfr_get_emin_min (void)
+@deftypefunx mpfr_exp_t mpfr_get_emin_max (void)
+@deftypefunx mpfr_exp_t mpfr_get_emax_min (void)
+@deftypefunx mpfr_exp_t mpfr_get_emax_max (void)
+Return the minimum and maximum of the exponents
+allowed for @code{mpfr_set_emin} and @code{mpfr_set_emax} respectively.
+These values are implementation dependent, thus a program using
+@code{mpfr_set_emax(mpfr_get_emax_max())}
+or @code{mpfr_set_emin(mpfr_get_emin_min())} may not be portable.
+@end deftypefun
+
+@deftypefun int mpfr_check_range (mpfr_t @var{x}, int @var{t}, mpfr_rnd_t @var{rnd})
+This function assumes that @var{x} is the correctly-rounded value of some
+real value @var{y} in the direction @var{rnd} and some extended exponent
+range, and that @var{t} is the corresponding @ref{ternary value}.
+For example, one performed @code{t = mpfr_log (x, u, rnd)}, and @var{y} is the
+exact logarithm of @var{u}.
+Thus @var{t} is negative if @var{x} is smaller than @var{y},
+positive if @var{x} is larger than @var{y}, and zero if @var{x} equals @var{y}.
+This function modifies @var{x} if needed
+to be in the current range of acceptable values: It
+generates an underflow or an overflow if the exponent of @var{x} is
+outside the current allowed range; the value of @var{t} may be used
+to avoid a double rounding. This function returns zero if the new value of
+@var{x} equals the exact one @var{y}, a positive value if that new value
+is larger than @var{y}, and a negative value if it is smaller than @var{y}.
+Note that unlike most functions,
+the new result @var{x} is compared to the (unknown) exact one @var{y},
+not the input value @var{x}, i.e., the ternary value is propagated.
+
+Note: If @var{x} is an infinity and @var{t} is different from zero (i.e.,
+if the rounded result is an inexact infinity), then the overflow flag is
+set. This is useful because @code{mpfr_check_range} is typically called
+(at least in MPFR functions) after restoring the flags that could have
+been set due to internal computations.
+@end deftypefun
+
+@deftypefun int mpfr_subnormalize (mpfr_t @var{x}, int @var{t}, mpfr_rnd_t @var{rnd})
+This function rounds @var{x} emulating subnormal number arithmetic:
+if @var{x} is outside the subnormal exponent range, it just propagates the
+@ref{ternary value} @var{t}; otherwise, it rounds @var{x} to precision
+@code{EXP(x)-emin+1} according to rounding mode @var{rnd} and previous
+ternary value @var{t}, avoiding double rounding problems.
+More precisely in the subnormal domain, denoting by @var{e} the value of
+@code{emin}, @var{x} is rounded in fixed-point
+arithmetic to an integer multiple of @m{2^{e-1}, two to the power
+@var{e}@minus{}1}; as a consequence, @m{1.5 \times 2^{e-1},
+1.5 multiplied by two to the power @var{e}@minus{}1} when @var{t} is zero
+is rounded to @m{2^e, two to the power @var{e}} with rounding to nearest.
+
+@code{PREC(x)} is not modified by this function.
+@var{rnd} and @var{t} must be the rounding mode
+and the returned ternary value used when computing @var{x}
+(as in @code{mpfr_check_range}).
+The subnormal exponent range is from @code{emin} to @code{emin+PREC(x)-1}.
+If the result cannot be represented in the current exponent range
+(due to a too small @code{emax}), the behavior is undefined.
+Note that unlike most functions, the result is compared to the exact one,
+not the input value @var{x}, i.e., the ternary value is propagated.
+
+As usual, if the returned ternary value is non zero, the inexact flag is set.
+Moreover, if a second rounding occurred (because the input @var{x} was in the
+subnormal range), the underflow flag is set.
+@end deftypefun
+
+This is an example of how to emulate binary double IEEE 754 arithmetic
+(binary64 in IEEE 754-2008) using MPFR:
+
+@example
+@{
+ mpfr_t xa, xb; int i; volatile double a, b;
+
+ mpfr_set_default_prec (53);
+ mpfr_set_emin (-1073); mpfr_set_emax (1024);
+
+ mpfr_init (xa); mpfr_init (xb);
+
+ b = 34.3; mpfr_set_d (xb, b, MPFR_RNDN);
+ a = 0x1.1235P-1021; mpfr_set_d (xa, a, MPFR_RNDN);
+
+ a /= b;
+ i = mpfr_div (xa, xa, xb, MPFR_RNDN);
+ i = mpfr_subnormalize (xa, i, MPFR_RNDN); /* new ternary value */
+
+ mpfr_clear (xa); mpfr_clear (xb);
+@}
+@end example
+
+Warning: this emulates a double IEEE 754 arithmetic with correct rounding
+in the subnormal range, which may not be the case for your hardware.
+
+@deftypefun void mpfr_clear_underflow (void)
+@deftypefunx void mpfr_clear_overflow (void)
+@deftypefunx void mpfr_clear_divby0 (void)
+@deftypefunx void mpfr_clear_nanflag (void)
+@deftypefunx void mpfr_clear_inexflag (void)
+@deftypefunx void mpfr_clear_erangeflag (void)
+Clear the underflow, overflow, divide-by-zero, invalid,
+inexact and @emph{erange} flags.
+@end deftypefun
+
+@deftypefun void mpfr_set_underflow (void)
+@deftypefunx void mpfr_set_overflow (void)
+@deftypefunx void mpfr_set_divby0 (void)
+@deftypefunx void mpfr_set_nanflag (void)
+@deftypefunx void mpfr_set_inexflag (void)
+@deftypefunx void mpfr_set_erangeflag (void)
+Set the underflow, overflow, divide-by-zero, invalid,
+inexact and @emph{erange} flags.
+@end deftypefun
+
+@deftypefun void mpfr_clear_flags (void)
+Clear all global flags (underflow, overflow, divide-by-zero, invalid,
+inexact, @emph{erange}).
+@end deftypefun
+
+@deftypefun int mpfr_underflow_p (void)
+@deftypefunx int mpfr_overflow_p (void)
+@deftypefunx int mpfr_divby0_p (void)
+@deftypefunx int mpfr_nanflag_p (void)
+@deftypefunx int mpfr_inexflag_p (void)
+@deftypefunx int mpfr_erangeflag_p (void)
+Return the corresponding (underflow, overflow, divide-by-zero, invalid,
+inexact, @emph{erange}) flag, which is non-zero iff the flag is set.
+@end deftypefun
+
+@node Compatibility with MPF, Custom Interface, Exception Related Functions, MPFR Interface
+@cindex Compatibility with MPF
+@section Compatibility With MPF
+
+A header file @file{mpf2mpfr.h} is included in the distribution of MPFR for
+compatibility with the GNU MP class MPF.
+By inserting the following two lines after the @code{#include <gmp.h>} line,
+@verbatim
+#include <mpfr.h>
+#include <mpf2mpfr.h>
+@end verbatim
+@noindent
+any program written for
+MPF can be compiled directly with MPFR without any changes
+(except the @code{gmp_printf} functions will not work for arguments of type
+@code{mpfr_t}).
+All operations are then performed with the default MPFR rounding mode,
+which can be reset with @code{mpfr_set_default_rounding_mode}.
+
+Warning: the @code{mpf_init} and @code{mpf_init2} functions initialize
+to zero, whereas the corresponding MPFR functions initialize to NaN:
+this is useful to detect uninitialized values, but is slightly incompatible
+with MPF.
+
+@deftypefun void mpfr_set_prec_raw (mpfr_t @var{x}, mpfr_prec_t @var{prec})
+Reset the precision of @var{x} to be @strong{exactly} @var{prec} bits.
+The only difference with @code{mpfr_set_prec} is that @var{prec} is assumed to
+be small enough so that the significand fits into the current allocated memory
+space for @var{x}. Otherwise the behavior is undefined.
+@end deftypefun
+
+@deftypefun int mpfr_eq (mpfr_t @var{op1}, mpfr_t @var{op2}, unsigned long int @var{op3})
+Return non-zero if @var{op1} and @var{op2} are both non-zero ordinary
+numbers with the same exponent and the same first @var{op3} bits, both
+zero, or both infinities of the same sign. Return zero otherwise.
+This function is defined for compatibility with MPF, we do not recommend
+to use it otherwise.
+Do not use it either if
+you want to know whether two numbers are close to each other; for instance,
+1.011111 and 1.100000 are regarded as different for any value of
+@var{op3} larger than 1.
+@end deftypefun
+
+@deftypefun void mpfr_reldiff (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+Compute the relative difference between @var{op1} and @var{op2}
+and store the result in @var{rop}.
+This function does not guarantee the correct rounding on the relative
+difference; it just computes @math{|@var{op1}-@var{op2}|/@var{op1}}, using the
+precision of @var{rop} and the rounding mode @var{rnd} for all operations.
+@c VL: say that if op1 and op2 have the same precision and are close to
+@c each other, then one gets correct rounding?
+@end deftypefun
+
+@deftypefun int mpfr_mul_2exp (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+@deftypefunx int mpfr_div_2exp (mpfr_t @var{rop}, mpfr_t @var{op1}, unsigned long int @var{op2}, mpfr_rnd_t @var{rnd})
+These functions are identical to @code{mpfr_mul_2ui} and @code{mpfr_div_2ui}
+respectively.
+These functions are only kept for compatibility with MPF, one should
+prefer @code{mpfr_mul_2ui} and @code{mpfr_div_2ui} otherwise.
+@end deftypefun
+
+
+@node Custom Interface, Internals, Compatibility with MPF, MPFR Interface
+@cindex Custom interface
+@section Custom Interface
+
+Some applications use a stack to handle the memory and their objects.
+However, the MPFR memory design is not well suited for such a thing. So that
+such applications are able to use MPFR, an auxiliary memory interface has
+been created: the Custom Interface.
+
+The following interface allows one to use MPFR in two ways:
+@itemize
+@item Either directly store a floating-point number as a @code{mpfr_t}
+on the stack.
+@item Either store its own representation on the
+stack and construct a new temporary @code{mpfr_t} each time it is needed.
+@end itemize
+Nothing has to be done to destroy the floating-point
+numbers except garbaging the used
+memory: all the memory management (allocating, destroying, garbaging) is left
+to the application.
+
+Each function in this interface is also implemented as a macro for
+efficiency reasons: for example @code{mpfr_custom_init (s, p)}
+uses the macro, while @code{(mpfr_custom_init) (s, p)} uses the function.
+
+Note 1: MPFR functions may still initialize temporary floating-point numbers
+using @code{mpfr_init} and similar functions. See Custom Allocation (GNU MP).
+
+Note 2: MPFR functions may use the cached functions (@code{mpfr_const_pi} for
+example), even if they are not explicitly called. You have to call
+@code{mpfr_free_cache} each time you garbage the memory iff @code{mpfr_init},
+through GMP Custom Allocation, allocates its memory on the application stack.
+
+@deftypefun size_t mpfr_custom_get_size (mpfr_prec_t @var{prec})
+Return the needed size in bytes to store the significand of a floating-point
+number of precision @var{prec}.
+@end deftypefun
+
+@deftypefun void mpfr_custom_init (void *@var{significand}, mpfr_prec_t @var{prec})
+Initialize a significand of precision @var{prec}, where
+@var{significand} must be an area of @code{mpfr_custom_get_size (prec)} bytes
+at least and be suitably aligned for an array of @code{mp_limb_t} (GMP type,
+@pxref{Internals}).
+@c PZ: give an example how to align?
+@end deftypefun
+
+@deftypefun void mpfr_custom_init_set (mpfr_t @var{x}, int @var{kind}, mpfr_exp_t @var{exp}, mpfr_prec_t @var{prec}, void *@var{significand})
+Perform a dummy initialization of a @code{mpfr_t} and set it to:
+@itemize
+@item if @code{ABS(kind) == MPFR_NAN_KIND}, @var{x} is set to NaN;
+@item if @code{ABS(kind) == MPFR_INF_KIND}, @var{x} is set to the infinity
+of sign @code{sign(kind)};
+@item if @code{ABS(kind) == MPFR_ZERO_KIND}, @var{x} is set to the zero of
+sign @code{sign(kind)};
+@item if @code{ABS(kind) == MPFR_REGULAR_KIND}, @var{x} is set to a regular
+number: @code{x = sign(kind)*significand*2^exp}.
+@end itemize
+In all cases, it uses @var{significand} directly for further computing
+involving @var{x}. It will not allocate anything.
+A floating-point number initialized with this function cannot be resized using
+@code{mpfr_set_prec} or @code{mpfr_prec_round},
+or cleared using @code{mpfr_clear}!
+The @var{significand} must have been initialized with @code{mpfr_custom_init}
+using the same precision @var{prec}.
+@end deftypefun
+
+@deftypefun int mpfr_custom_get_kind (mpfr_t @var{x})
+Return the current kind of a @code{mpfr_t} as created by
+@code{mpfr_custom_init_set}.
+The behavior of this function for any @code{mpfr_t} not initialized
+with @code{mpfr_custom_init_set} is undefined.
+@end deftypefun
+
+@deftypefun {void *} mpfr_custom_get_significand (mpfr_t @var{x})
+Return a pointer to the significand used by a @code{mpfr_t} initialized with
+@code{mpfr_custom_init_set}.
+The behavior of this function for any @code{mpfr_t} not initialized
+with @code{mpfr_custom_init_set} is undefined.
+@end deftypefun
+
+@deftypefun mpfr_exp_t mpfr_custom_get_exp (mpfr_t @var{x})
+Return the exponent of @var{x}, assuming that @var{x} is a non-zero ordinary
+number. The return value for NaN, Infinity or zero is unspecified but does not
+produce any trap.
+The behavior of this function for any @code{mpfr_t} not initialized
+with @code{mpfr_custom_init_set} is undefined.
+@end deftypefun
+
+@deftypefun void mpfr_custom_move (mpfr_t @var{x}, void *@var{new_position})
+Inform MPFR that the significand of @var{x} has moved due to a garbage collect
+and update its new position to @code{new_position}.
+However the application has to move the significand and the @code{mpfr_t}
+itself.
+The behavior of this function for any @code{mpfr_t} not initialized
+with @code{mpfr_custom_init_set} is undefined.
+@end deftypefun
+
+@node Internals, , Custom Interface, MPFR Interface
+@cindex Internals
+@section Internals
+
+@cindex Limb
+@c @tindex @code{mp_limb_t}
+@noindent
+A @dfn{limb} means the part of a multi-precision number that fits in a single
+word. Usually a limb contains
+32 or 64 bits. The C data type for a limb is @code{mp_limb_t}.
+
+The @code{mpfr_t} type is internally defined as a one-element
+array of a structure, and @code{mpfr_ptr} is the C data type representing
+a pointer to this structure.
+The @code{mpfr_t} type consists of four fields:
+
+@itemize @bullet
+
+@item The @code{_mpfr_prec} field is used to store the precision of
+the variable (in bits); this is not less than @code{MPFR_PREC_MIN}.
+
+@item The @code{_mpfr_sign} field is used to store the sign of the variable.
+
+@item The @code{_mpfr_exp} field stores the exponent.
+An exponent of 0 means a radix point just above the most significant
+limb. Non-zero values @math{n} are a multiplier @math{2^n} relative to that
+point.
+A NaN, an infinity and a zero are indicated by special values of the exponent
+field.
+
+@item Finally, the @code{_mpfr_d} field is a pointer to the limbs, least
+significant limbs stored first.
+The number of limbs in use is controlled by @code{_mpfr_prec}, namely
+ceil(@code{_mpfr_prec}/@code{mp_bits_per_limb}).
+Non-singular (i.e., different from NaN, Infinity or zero)
+values always have the most significant bit of the most
+significant limb set to 1. When the precision does not correspond to a
+whole number of limbs, the excess bits at the low end of the data are zeros.
+
+@end itemize
+
+@node API Compatibility, Contributors, MPFR Interface, Top
+@chapter API Compatibility
+
+The goal of this section is to describe some API changes that occurred
+from one version of MPFR to another, and how to write code that can be compiled
+and run with older MPFR versions. The minimum MPFR version that is
+considered here is 2.2.0 (released on 20 September 2005).
+
+API changes can only occur between major or minor versions. Thus the
+patchlevel (the third number in the MPFR version) will be ignored in
+the following. If a program does not use MPFR internals, changes in
+the behavior between two versions differing only by the patchlevel
+should only result from what was regarded as a bug or unspecified behavior.
+@comment This includes undefined behavior.
+
+As a general rule, a program written for some MPFR version should work
+with later versions, possibly except at a new major version, where
+some features (described as obsolete for some time) can be removed.
+In such a case, a failure should occur during compilation or linking.
+If a result becomes incorrect because of such a change, please look
+at the various changes below (they are minimal, and most software
+should be unaffected), at the FAQ and at the MPFR web page for your
+version (a bug could have been introduced and be already fixed);
+and if the problem is not mentioned, please send us a bug report
+(@pxref{Reporting Bugs}).
+
+However, a program written for the current MPFR version (as documented
+by this manual) may not necessarily work with previous versions of
+MPFR. This section should help developers to write portable code.
+
+Note: Information given here may be incomplete. API changes are
+also described in the NEWS file (for each version, instead of being
+classified like here), together with other changes.
+
+@menu
+* Type and Macro Changes::
+* Added Functions::
+* Changed Functions::
+* Removed Functions::
+* Other Changes::
+@end menu
+
+@node Type and Macro Changes, Added Functions, API Compatibility, API Compatibility
+@section Type and Macro Changes
+
+@comment r6789
+The official type for exponent values changed from @code{mp_exp_t} to
+@code{mpfr_exp_t} in MPFR 3.0. The type @code{mp_exp_t} will remain
+available as it comes from GMP (with a different meaning). These types
+are currently the same (@code{mpfr_exp_t} is defined as @code{mp_exp_t}
+with @code{typedef}), so that programs can still use @code{mp_exp_t};
+but this may change in the future.
+Alternatively, using the following code after including @file{mpfr.h}
+will work with official MPFR versions, as @code{mpfr_exp_t} was never
+defined in MPFR 2.x:
+@example
+#if MPFR_VERSION_MAJOR < 3
+typedef mp_exp_t mpfr_exp_t;
+#endif
+@end example
+
+The official types for precision values and for rounding modes
+respectively changed from @code{mp_prec_t} and @code{mp_rnd_t}
+to @code{mpfr_prec_t} and @code{mpfr_rnd_t} in MPFR 3.0. This
+change was actually done a long time ago in MPFR, at least since
+MPFR 2.2.0, with the following code in @file{mpfr.h}:
+@example
+#ifndef mp_rnd_t
+# define mp_rnd_t mpfr_rnd_t
+#endif
+#ifndef mp_prec_t
+# define mp_prec_t mpfr_prec_t
+#endif
+@end example
+This means that it is safe to use the new official types
+@code{mpfr_prec_t} and @code{mpfr_rnd_t} in your programs.
+The types @code{mp_prec_t} and @code{mp_rnd_t} (defined
+in MPFR only) may be removed in the future, as the prefix
+@code{mp_} is reserved by GMP.
+
+@comment r6787
+The precision type @code{mpfr_prec_t} (@code{mp_prec_t}) was unsigned
+before MPFR 3.0; it is now signed. @code{MPFR_PREC_MAX} has not changed,
+though. Indeed the MPFR code requires that @code{MPFR_PREC_MAX} be
+representable in the exponent type, which may have the same size as
+@code{mpfr_prec_t} but has always been signed.
+The consequence is that valid code that does not assume anything about
+the signedness of @code{mpfr_prec_t} should work with past and new MPFR
+versions.
+This change was useful as the use of unsigned types tends to convert
+signed values to unsigned ones in expressions due to the usual arithmetic
+conversions, which can yield incorrect results if a negative value is
+converted in such a way.
+Warning! A program assuming (intentionally or not) that
+@code{mpfr_prec_t} is signed may be affected by this problem when
+it is built and run against MPFR 2.x.
+
+The rounding modes @code{GMP_RNDx} were renamed to @code{MPFR_RNDx}
+in MPFR 3.0. However the old names @code{GMP_RNDx} have been kept for
+compatibility (this might change in future versions), using:
+@example
+#define GMP_RNDN MPFR_RNDN
+#define GMP_RNDZ MPFR_RNDZ
+#define GMP_RNDU MPFR_RNDU
+#define GMP_RNDD MPFR_RNDD
+@end example
+The rounding mode ``round away from zero'' (@code{MPFR_RNDA}) was added in
+MPFR 3.0 (however no rounding mode @code{GMP_RNDA} exists).
+
+@node Added Functions, Changed Functions, Type and Macro Changes, API Compatibility
+@section Added Functions
+
+We give here in alphabetical order
+the functions that were added after MPFR 2.2, and in which
+MPFR version.
+
+@comment The functions are listed in such a way that if a developer wonders
+@comment whether some function existed in some previous version, then he can
+@comment find this very quickly.
+
+@itemize @bullet
+
+@item @code{mpfr_add_d} in MPFR 2.4.
+
+@item @code{mpfr_ai} in MPFR 3.0 (incomplete, experimental).
+
+@item @code{mpfr_asprintf} in MPFR 2.4.
+
+@item @code{mpfr_buildopt_decimal_p} and @code{mpfr_buildopt_tls_p} in MPFR 3.0.
+
+@item @code{mpfr_buildopt_gmpinternals_p} and @code{mpfr_buildopt_tune_case}
+in MPFR 3.1.
+
+@item @code{mpfr_clear_divby0} in MPFR 3.1 (new divide-by-zero exception).
+
+@item @code{mpfr_copysign} in MPFR 2.3.
+Note: MPFR 2.2 had a @code{mpfr_copysign} function that was available,
+but not documented,
+and with a slight difference in the semantics (when
+the second input operand is a NaN).
+
+@item @code{mpfr_custom_get_significand} in MPFR 3.0.
+This function was named @code{mpfr_custom_get_mantissa} in previous
+versions; @code{mpfr_custom_get_mantissa} is still available via a
+macro in @file{mpfr.h}:
+@example
+#define mpfr_custom_get_mantissa mpfr_custom_get_significand
+@end example
+Thus code that needs to work with both MPFR 2.x and MPFR 3.x should
+use @code{mpfr_custom_get_mantissa}.
+
+@item @code{mpfr_d_div} and @code{mpfr_d_sub} in MPFR 2.4.
+
+@item @code{mpfr_digamma} in MPFR 3.0.
+
+@item @code{mpfr_divby0_p} in MPFR 3.1 (new divide-by-zero exception).
+
+@item @code{mpfr_div_d} in MPFR 2.4.
+
+@item @code{mpfr_fmod} in MPFR 2.4.
+
+@item @code{mpfr_fms} in MPFR 2.3.
+
+@item @code{mpfr_fprintf} in MPFR 2.4.
+
+@item @code{mpfr_frexp} in MPFR 3.1.
+
+@item @code{mpfr_get_flt} in MPFR 3.0.
+
+@item @code{mpfr_get_patches} in MPFR 2.3.
+
+@item @code{mpfr_get_z_2exp} in MPFR 3.0.
+This function was named @code{mpfr_get_z_exp} in previous versions;
+@code{mpfr_get_z_exp} is still available via a macro in @file{mpfr.h}:
+@example
+#define mpfr_get_z_exp mpfr_get_z_2exp
+@end example
+Thus code that needs to work with both MPFR 2.x and MPFR 3.x should
+use @code{mpfr_get_z_exp}.
+
+@item @code{mpfr_grandom} in MPFR 3.1.
+
+@item @code{mpfr_j0}, @code{mpfr_j1} and @code{mpfr_jn} in MPFR 2.3.
+
+@item @code{mpfr_lgamma} in MPFR 2.3.
+
+@item @code{mpfr_li2} in MPFR 2.4.
+
+@item @code{mpfr_min_prec} in MPFR 3.0.
+
+@item @code{mpfr_modf} in MPFR 2.4.
+
+@item @code{mpfr_mul_d} in MPFR 2.4.
+
+@item @code{mpfr_printf} in MPFR 2.4.
+
+@item @code{mpfr_rec_sqrt} in MPFR 2.4.
+
+@item @code{mpfr_regular_p} in MPFR 3.0.
+
+@item @code{mpfr_remainder} and @code{mpfr_remquo} in MPFR 2.3.
+
+@item @code{mpfr_set_divby0} in MPFR 3.1 (new divide-by-zero exception).
+
+@item @code{mpfr_set_flt} in MPFR 3.0.
+
+@item @code{mpfr_set_z_2exp} in MPFR 3.0.
+
+@item @code{mpfr_set_zero} in MPFR 3.0.
+
+@item @code{mpfr_setsign} in MPFR 2.3.
+
+@item @code{mpfr_signbit} in MPFR 2.3.
+
+@item @code{mpfr_sinh_cosh} in MPFR 2.4.
+
+@item @code{mpfr_snprintf} and @code{mpfr_sprintf} in MPFR 2.4.
+
+@item @code{mpfr_sub_d} in MPFR 2.4.
+
+@item @code{mpfr_urandom} in MPFR 3.0.
+
+@item @code{mpfr_vasprintf}, @code{mpfr_vfprintf}, @code{mpfr_vprintf},
+ @code{mpfr_vsprintf} and @code{mpfr_vsnprintf} in MPFR 2.4.
+
+@item @code{mpfr_y0}, @code{mpfr_y1} and @code{mpfr_yn} in MPFR 2.3.
+
+@item @code{mpfr_z_sub} in MPFR 3.1.
+
+@end itemize
+
+@node Changed Functions, Removed Functions, Added Functions, API Compatibility
+@section Changed Functions
+
+The following functions have changed after MPFR 2.2. Changes can affect
+the behavior of code written for some MPFR version when built and run
+against another MPFR version (older or newer), as described below.
+
+@itemize @bullet
+
+@item @code{mpfr_check_range} changed in MPFR 2.3.2 and MPFR 2.4.
+If the value is an inexact infinity, the overflow flag is now set
+(in case it was lost), while it was previously left unchanged.
+This is really what is expected in practice (and what the MPFR code
+was expecting), so that the previous behavior was regarded as a bug.
+Hence the change in MPFR 2.3.2.
+
+@item @code{mpfr_get_f} changed in MPFR 3.0.
+This function was returning zero, except for NaN and Inf, which do not
+exist in MPF. The @emph{erange} flag is now set in these cases,
+and @code{mpfr_get_f} now returns the usual ternary value.
+
+@item @code{mpfr_get_si}, @code{mpfr_get_sj}, @code{mpfr_get_ui}
+and @code{mpfr_get_uj} changed in MPFR 3.0.
+In previous MPFR versions, the cases where the @emph{erange} flag
+is set were unspecified.
+
+@item @code{mpfr_get_z} changed in MPFR 3.0.
+The return type was @code{void}; it is now @code{int}, and the usual
+ternary value is returned. Thus programs that need to work with both
+MPFR 2.x and 3.x must not use the return value. Even in this case,
+C code using @code{mpfr_get_z} as the second or third term of
+a conditional operator may also be affected. For instance, the
+following is correct with MPFR 3.0, but not with MPFR 2.x:
+@example
+ bool ? mpfr_get_z(...) : mpfr_add(...);
+@end example
+On the other hand, the following is correct with MPFR 2.x, but not
+with MPFR 3.0:
+@example
+ bool ? mpfr_get_z(...) : (void) mpfr_add(...);
+@end example
+Portable code should cast @code{mpfr_get_z(...)} to @code{void} to
+use the type @code{void} for both terms of the conditional operator,
+as in:
+@example
+ bool ? (void) mpfr_get_z(...) : (void) mpfr_add(...);
+@end example
+Alternatively, @code{if ... else} can be used instead of the
+conditional operator.
+
+Moreover the cases where the @emph{erange} flag is set were unspecified
+in MPFR 2.x.
+
+@item @code{mpfr_get_z_exp} changed in MPFR 3.0.
+In previous MPFR versions, the cases where the @emph{erange} flag
+is set were unspecified.
+Note: this function has been renamed to @code{mpfr_get_z_2exp}
+in MPFR 3.0, but @code{mpfr_get_z_exp} is still available for
+compatibility reasons.
+
+@item @code{mpfr_strtofr} changed in MPFR 2.3.1 and MPFR 2.4.
+This was actually a bug fix since the code and the documentation did
+not match. But both were changed in order to have a more consistent
+and useful behavior. The main changes in the code are as follows.
+The binary exponent is now accepted even without the @code{0b} or
+@code{0x} prefix. Data corresponding to NaN can now have an optional
+sign (such data were previously invalid).
+
+@item @code{mpfr_strtofr} changed in MPFR 3.0.
+This function now accepts bases from 37 to 62 (no changes for the other
+bases). Note: if an unsupported base is provided to this function,
+the behavior is undefined; more precisely, in MPFR 2.3.1 and later,
+providing an unsupported base yields an assertion failure (this
+behavior may change in the future).
+
+@item @code{mpfr_subnormalize} changed in MPFR 3.1.
+This was actually regarded as a bug fix. The @code{mpfr_subnormalize}
+implementation up to MPFR 3.0.0 did not change the flags. In particular,
+it did not follow the generic rule concerning the inexact flag (and no
+special behavior was specified). The case of the underflow flag was more
+a lack of specification.
+
+@item @code{mpfr_urandom} and @code{mpfr_urandomb} changed in MPFR 3.1.
+Their behavior no longer depends on the platform (assuming this is also true
+for GMP's random generator, which is not the case between GMP 4.1 and 4.2 if
+@code{gmp_randinit_default} is used). As a consequence, the returned values
+can be different between MPFR 3.1 and previous MPFR versions.
+Note: as the reproducibility of these functions was not specified
+before MPFR 3.1, the MPFR 3.1 behavior is @emph{not} regarded as
+backward incompatible with previous versions.
+
+@end itemize
+
+@node Removed Functions, Other Changes, Changed Functions, API Compatibility
+@section Removed Functions
+
+Functions @code{mpfr_random} and @code{mpfr_random2} have been
+removed in MPFR 3.0 (this only affects old code built against
+MPFR 3.0 or later).
+(The function @code{mpfr_random} had been deprecated since at least MPFR 2.2.0,
+and @code{mpfr_random2} since MPFR 2.4.0.)
+
+@node Other Changes, , Removed Functions, API Compatibility
+@section Other Changes
+
+@comment r6699
+For users of a C++ compiler, the way how the availability of @code{intmax_t}
+is detected has changed in MPFR 3.0.
+In MPFR 2.x, if a macro @code{INTMAX_C} or @code{UINTMAX_C} was defined
+(e.g. when the @code{__STDC_CONSTANT_MACROS} macro had been defined
+before @code{<stdint.h>} or @code{<inttypes.h>} has been included),
+@code{intmax_t} was assumed to be defined.
+However this was not always the case (more precisely, @code{intmax_t}
+can be defined only in the namespace @code{std}, as with Boost), so
+that compilations could fail.
+Thus the check for @code{INTMAX_C} or @code{UINTMAX_C} is now disabled for
+C++ compilers, with the following consequences:
+
+@itemize
+
+@item Programs written for MPFR 2.x that need @code{intmax_t} may no longer
+be compiled against MPFR 3.0: a @code{#define MPFR_USE_INTMAX_T} may be
+necessary before @file{mpfr.h} is included.
+
+@item The compilation of programs that work with MPFR 3.0 may fail with
+MPFR 2.x due to the problem described above. Workarounds are possible,
+such as defining @code{intmax_t} and @code{uintmax_t} in the global
+namespace, though this is not clean.
+
+@end itemize
+
+The divide-by-zero exception is new in MPFR 3.1. However it should
+not introduce incompatible changes for programs that strictly follow
+the MPFR API since the exception can only be seen via new functions.
+
+As of MPFR 3.1, the @file{mpfr.h} header can be included several times,
+while still supporting optional functions (@pxref{Headers and Libraries}).
+
+@node Contributors, References, API Compatibility, Top
+@comment node-name, next, previous, up
+@unnumbered Contributors
+
+The main developers of MPFR are Guillaume Hanrot, Vincent Lef@`evre,
+Patrick P@'elissier, Philippe Th@'eveny and Paul Zimmermann.
+
+Sylvie Boldo from ENS-Lyon, France,
+contributed the functions @code{mpfr_agm} and @code{mpfr_log}.
+Sylvain Chevillard contributed the @code{mpfr_ai} function.
+David Daney contributed the hyperbolic and inverse hyperbolic functions,
+the base-2 exponential, and the factorial function.
+Alain Delplanque contributed the new version of the @code{mpfr_get_str}
+function.
+Mathieu Dutour contributed the functions @code{mpfr_acos}, @code{mpfr_asin}
+and @code{mpfr_atan}, and a previous version of @code{mpfr_gamma}.
+Laurent Fousse contributed the @code{mpfr_sum} function.
+Emmanuel Jeandel, from ENS-Lyon too,
+contributed the generic hypergeometric code,
+as well as the internal function @code{mpfr_exp3},
+a first implementation of the sine and cosine,
+and improved versions of
+@code{mpfr_const_log2} and @code{mpfr_const_pi}.
+Ludovic Meunier helped in the design of the @code{mpfr_erf} code.
+Jean-Luc R@'emy contributed the @code{mpfr_zeta} code.
+Fabrice Rouillier contributed the @code{mpfr_xxx_z} and @code{mpfr_xxx_q}
+functions, and helped to the Microsoft Windows porting.
+Damien Stehl@'e contributed the @code{mpfr_get_ld_2exp} function.
+
+We would like to thank Jean-Michel Muller and Joris van der Hoeven for very
+fruitful discussions at the beginning of that project, Torbj@"orn Granlund
+and Kevin Ryde for their help about design issues,
+and Nathalie Revol for her careful reading of a previous version of
+this documentation. In particular
+Kevin Ryde did a tremendous job for the portability of MPFR in 2002-2004.
+
+The development of the MPFR library would not have been possible without
+the continuous support of INRIA, and of the LORIA (Nancy, France) and LIP
+(Lyon, France) laboratories. In particular the main authors were or are
+members of the PolKA, Spaces, Cacao and Caramel
+project-teams at LORIA and of the
+Ar@'enaire and AriC project-teams at LIP.
+This project was started during the Fiable (reliable in French) action
+supported by INRIA, and continued during the AOC action.
+The development of MPFR was also supported by a grant
+(202F0659 00 MPN 121) from the Conseil R@'egional de Lorraine in 2002,
+from INRIA by an "associate engineer" grant (2003-2005),
+an "op@'eration de d@'eveloppement logiciel" grant (2007-2009),
+and the post-doctoral grant of Sylvain Chevillard in 2009-2010.
+The MPFR-MPC workshop in June 2012 was partly supported by the ERC
+grant ANTICS of Andreas Enge.
+
+@node References, GNU Free Documentation License, Contributors, Top
+@comment node-name, next, previous, up
+@unnumbered References
+
+@itemize @bullet
+
+@item
+Richard Brent and Paul Zimmermann,
+"Modern Computer Arithmetic",
+Cambridge University Press (to appear),
+also available from the authors' web pages.
+
+@item
+Laurent Fousse, Guillaume Hanrot, Vincent Lef@`evre,
+Patrick P@'elissier and Paul Zimmermann,
+"MPFR: A Multiple-Precision Binary Floating-Point Library With Correct Rounding",
+ACM Transactions on Mathematical Software,
+volume 33, issue 2, article 13, 15 pages, 2007,
+@url{http://doi.acm.org/10.1145/1236463.1236468}.
+
+@item
+Torbj@"orn Granlund, "GNU MP: The GNU Multiple Precision Arithmetic Library",
+ version 5.0.1, 2010, @url{http://gmplib.org}.
+
+@item
+IEEE standard for binary floating-point arithmetic, Technical Report
+ANSI-IEEE Standard 754-1985, New York, 1985.
+Approved March 21, 1985: IEEE Standards Board; approved July 26,
+ 1985: American National Standards Institute, 18 pages.
+
+@item
+IEEE Standard for Floating-Point Arithmetic,
+ANSI-IEEE Standard 754-2008, 2008.
+Revision of ANSI-IEEE Standard 754-1985,
+approved June 12, 2008: IEEE Standards Board, 70 pages.
+
+@item
+Donald E. Knuth, "The Art of Computer Programming", vol 2,
+"Seminumerical Algorithms", 2nd edition, Addison-Wesley, 1981.
+
+@item
+Jean-Michel Muller, "Elementary Functions, Algorithms and Implementation",
+Birkh@"auser, Boston, 2nd edition, 2006.
+
+@item
+Jean-Michel Muller, Nicolas Brisebarre, Florent de Dinechin,
+Claude-Pierre Jeannerod, Vincent Lef@`evre, Guillaume Melquiond,
+Nathalie Revol, Damien Stehl@'e and Serge Torr@`es,
+"Handbook of Floating-Point Arithmetic",
+Birkh@"auser, Boston, 2009.
+
+@end itemize
+
+
+@node GNU Free Documentation License, Concept Index, References, Top
+@appendix GNU Free Documentation License
+@cindex GNU Free Documentation License
+@include fdl.texi
+
+
+@node Concept Index, Function and Type Index, GNU Free Documentation License, Top
+@comment node-name, next, previous, up
+@unnumbered Concept Index
+@printindex cp
+
+@node Function and Type Index, , Concept Index, Top
+@comment node-name, next, previous, up
+@unnumbered Function and Type Index
+@printindex fn
+
+@bye
+
+@c Local variables:
+@c fill-column: 78
+@c End:
diff --git a/mpfr/doc/texinfo.tex b/mpfr/doc/texinfo.tex
new file mode 100644
index 0000000000..85b68e7950
--- /dev/null
+++ b/mpfr/doc/texinfo.tex
@@ -0,0 +1,9977 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2012-03-11.15}
+%
+% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+%
+% This texinfo.tex file is free software: you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation, either version 3 of the
+% License, or (at your option) any later version.
+%
+% This texinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction. (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+% ftp://tug.org/tex/texinfo.tex
+% (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org. Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem. Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution. For a simple
+% manual foo.texi, however, you can get away with this:
+% tex foo.texi
+% texindex foo.??
+% tex foo.texi
+% tex foo.texi
+% dvips foo.dvi -o # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent. You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexraggedright=\raggedright
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+\let\ptextop=\top
+{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Pre-3.0.
+\else
+ \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putworderror\undefined \gdef\putworderror{error}\fi
+\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\ampChar = `\&
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar = `\-
+\chardef\dotChar = `\.
+\chardef\exclamChar= `\!
+\chardef\hashChar = `\#
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar = `\;
+\chardef\slashChar = `\/
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+ ap-pen-dix bit-map bit-maps
+ data-base data-bases eshell fall-ing half-way long-est man-u-script
+ man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+ par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+ spell-ing spell-ings
+ stand-alone strong-est time-stamp time-stamps which-ever white-space
+ wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt }
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal. We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+ \tracingstats2
+ \tracingpages1
+ \tracinglostchars2 % 2 gives us more in etex
+ \tracingparagraphs1
+ \tracingoutput1
+ \tracingmacros2
+ \tracingrestores1
+ \showboxbreadth\maxdimen \showboxdepth\maxdimen
+ \ifx\eTeXversion\thisisundefined\else % etex gives us more logging
+ \tracingscantokens1
+ \tracingifs1
+ \tracinggroups1
+ \tracingnesting2
+ \tracingassigns1
+ \fi
+ \tracingcommands3 % 3 gives us more in etex
+ \errorcontextlines16
+}%
+
+% @errormsg{MSG}. Do the index-like expansions on MSG, but if things
+% aren't perfect, it's not the end of the world, being an error message,
+% after all.
+%
+\def\errormsg{\begingroup \indexnofonts \doerrormsg}
+\def\doerrormsg#1{\errmessage{#1}}
+
+% add check for \lastpenalty to plain's definitions. If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+ \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+ \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+ \removelastskip\penalty-200\bigskip\fi\fi}
+
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Output a mark which sets \thischapter, \thissection and \thiscolor.
+% We dump everything together because we only have one kind of mark.
+% This works because we only use \botmark / \topmark, not \firstmark.
+%
+% A mark contains a subexpression of the \ifcase ... \fi construct.
+% \get*marks macros below extract the needed part using \ifcase.
+%
+% Another complication is to let the user choose whether \thischapter
+% (\thissection) refers to the chapter (section) in effect at the top
+% of a page, or that at the bottom of a page. The solution is
+% described on page 260 of The TeXbook. It involves outputting two
+% marks for the sectioning macros, one before the section break, and
+% one after. I won't pretend I can describe this better than DEK...
+\def\domark{%
+ \toks0=\expandafter{\lastchapterdefs}%
+ \toks2=\expandafter{\lastsectiondefs}%
+ \toks4=\expandafter{\prevchapterdefs}%
+ \toks6=\expandafter{\prevsectiondefs}%
+ \toks8=\expandafter{\lastcolordefs}%
+ \mark{%
+ \the\toks0 \the\toks2
+ \noexpand\or \the\toks4 \the\toks6
+ \noexpand\else \the\toks8
+ }%
+}
+% \topmark doesn't work for the very first chapter (after the title
+% page or the contents), so we use \firstmark there -- this gets us
+% the mark with the chapter defs, unless the user sneaks in, e.g.,
+% @setcolor (or @url, or @link, etc.) between @contents and the very
+% first @chapter.
+\def\gettopheadingmarks{%
+ \ifcase0\topmark\fi
+ \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
+}
+\def\getbottomheadingmarks{\ifcase1\botmark\fi}
+\def\getcolormarks{\ifcase2\topmark\fi}
+
+% Avoid "undefined control sequence" errors.
+\def\lastchapterdefs{}
+\def\lastsectiondefs{}
+\def\prevchapterdefs{}
+\def\prevsectiondefs{}
+\def\lastcolordefs{}
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+ %
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
+ \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ % We don't want .vr (or whatever) entries like this:
+ % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+ % "\acronym" won't work when it's read back in;
+ % it needs to be
+ % {\code {{\tt \backslashcurfont }acronym}
+ \shipout\vbox{%
+ % Do this early so pdf references go to the beginning of the page.
+ \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+ %
+ \ifcropmarks \vbox to \outervsize\bgroup
+ \hsize = \outerhsize
+ \vskip-\topandbottommargin
+ \vtop to0pt{%
+ \line{\ewtop\hfil\ewtop}%
+ \nointerlineskip
+ \line{%
+ \vbox{\moveleft\cornerthick\nstop}%
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}%
+ }%
+ \vss}%
+ \vskip\topandbottommargin
+ \line\bgroup
+ \hfil % center the page within the outer (page) hsize.
+ \ifodd\pageno\hskip\bindingoffset\fi
+ \vbox\bgroup
+ \fi
+ %
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \ifdim\ht\footlinebox > 0pt
+ % Only leave this space if the footline is nonempty.
+ % (We lessened \vsize for it in \oddfootingyyy.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 24pt
+ \unvbox\footlinebox
+ \fi
+ %
+ \ifcropmarks
+ \egroup % end of \vbox\bgroup
+ \hfil\egroup % end of (centering) \line\bgroup
+ \vskip\topandbottommargin plus1fill minus1fill
+ \boxmaxdepth = \cornerthick
+ \vbox to0pt{\vss
+ \line{%
+ \vbox{\moveleft\cornerthick\nsbot}%
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}%
+ }%
+ \nointerlineskip
+ \line{\ewbot\hfil\ewbot}%
+ }%
+ \egroup % \vbox from first cropmarks clause
+ \fi
+ }% end of \shipout\vbox
+ }% end of group with \indexdummies
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+ \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1\relax \unvbox#1\relax
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+ \def\argtorun{#2}%
+ \begingroup
+ \obeylines
+ \spaceisspace
+ #1%
+ \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ \argremovecomment #1\comment\ArgTerm%
+ }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+% @end itemize @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+ \def\temp{#3}%
+ \ifx\temp\empty
+ % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+ \let\temp\finishparsearg
+ \else
+ \let\temp\argcheckspaces
+ \fi
+ % Put the space token in:
+ \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \argtorun.
+% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\foo{...}
+% is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick. --kasal, 16nov03
+
+\def\parseargdef#1{%
+ \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+ \def#2{\parsearg#1}%
+ \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+ \obeyspaces
+ \gdef\obeyedspace{ }
+
+ % Make each space character in the input produce a normal interword
+ % space in the output. Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ \gdef\sepspaces{\obeyspaces\let =\tie}
+
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\leavevmode \penalty \@M \ ).
+ \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex. It's used like this:
+%
+% \envdef\foo{...}
+% \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo. \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches. The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as environments; they don't open a group. (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At run-time, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+ \def\temp{#1}%
+ \ifx\thisenv\temp
+ \else
+ \badenverr
+ \fi
+}
+
+% Environment mismatch, #1 expected:
+\def\badenverr{%
+ \errhelp = \EMsimple
+ \errmessage{This command can appear only \inenvironment\temp,
+ not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+ \ifx#1\empty
+ outside of any environment%
+ \else
+ in environment \expandafter\string#1%
+ \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+ \if 1\csname iscond.#1\endcsname
+ \else
+ % The general wording of \badenverr may not be ideal.
+ \expandafter\checkenv\csname#1\endcsname
+ \csname E#1\endcsname
+ \endgroup
+ \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+ \def\temp{#1}%
+ \ifx\temp\onword \plainfrenchspacing
+ \else\ifx\temp\offword \plainnonfrenchspacing
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @frenchspacing option `\temp', must be on|off}%
+ \fi\fi
+}
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large. This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material. In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom. The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+ \ifnum\catcode`\^^M=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ \startsavinginserts
+ %
+ \setbox\groupbox = \vtop\bgroup
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it. Thus, space below is not quite equal to space
+% above. But it's pretty close.
+\def\Egroup{%
+ % To get correct interline space between the last line of the group
+ % and the first line afterwards, we have to propagate \prevdepth.
+ \endgraf % Not \par, as it may have been set to \lisppar.
+ \global\dimen1 = \prevdepth
+ \egroup % End the \vtop.
+ % \dimen0 is the vertical size of the group's box.
+ \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
+ % \dimen2 is how much space is left on the page (more or less).
+ \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
+ % if the group doesn't fit on the current page, and it's a big big
+ % group, force a page break.
+ \ifdim \dimen0 > \dimen2
+ \ifdim \pagetotal < \vfilllimit\pageheight
+ \page
+ \fi
+ \fi
+ \box\groupbox
+ \prevdepth = \dimen1
+ \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+\parseargdef\need{%
+ % Ensure vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % If the @need value is less than one line space, it's useless.
+ \dimen0 = #1\mil
+ \dimen2 = \ht\strutbox
+ \advance\dimen2 by \dp\strutbox
+ \ifdim\dimen0 > \dimen2
+ %
+ % Do a \strut just to make the height of this box be normal, so the
+ % normal leading is inserted relative to the preceding line.
+ % And a page break here is fine.
+ \vtop to #1\mil{\strut\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+ \fi
+}
+
+% @br forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph. For more general purposes, use the \margin insertion
+% class. WHICH is `l' or `r'. Not documented, written for gawk manual.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+ \nobreak
+ \kern-\strutdepth
+ \vtop to \strutdepth{%
+ \baselineskip=\strutdepth
+ \vss
+ % if you have multiple lines of stuff to put here, you'll need to
+ % make the vbox yourself of the appropriate size.
+ \ifx#1l%
+ \llap{\ignorespaces #2\hskip\inmarginspacing}%
+ \else
+ \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+ \fi
+ \null
+ }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \def\lefttext{#1}% have both texts
+ \def\righttext{#2}%
+ \else
+ \def\lefttext{#1}% have only one text
+ \def\righttext{#1}%
+ \fi
+ %
+ \ifodd\pageno
+ \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+ \else
+ \def\temp{\inleftmargin\lefttext}%
+ \fi
+ \temp
+}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change). This command
+% is not documented, not supported, and doesn't work.
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% @include FILE -- \input text of FILE.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+ \pushthisfilestack
+ \def\thisfile{#1}%
+ {%
+ \makevalueexpandable % we want to expand any @value in FILE.
+ \turnoffactive % and allow special characters in the expansion
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @include of #1^^J}%
+ \edef\temp{\noexpand\input #1 }%
+ %
+ % This trickery is to read FILE outside of a group, in case it makes
+ % definitions, etc.
+ \expandafter
+ }\temp
+ \popthisfilestack
+}
+\def\filenamecatcodes{%
+ \catcode`\\=\other
+ \catcode`~=\other
+ \catcode`^=\other
+ \catcode`_=\other
+ \catcode`|=\other
+ \catcode`<=\other
+ \catcode`>=\other
+ \catcode`+=\other
+ \catcode`-=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
+}
+
+\def\pushthisfilestack{%
+ \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+ \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+ \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+ the stack of filenames is empty.}}
+%
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+ \ifhmode
+ \let\centersub\centerH
+ \else
+ \let\centersub\centerV
+ \fi
+ \centersub{\hfil \ignorespaces#1\unskip \hfil}%
+ \let\centersub\relax % don't let the definition persist, just in case
+}
+\def\centerH#1{{%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+}}
+%
+\newcount\centerpenalty
+\def\centerV#1{%
+ % The idea here is the same as in \startdefun, \cartouche, etc.: if
+ % @center is the first thing after a section heading, we need to wipe
+ % out the negative parskip inserted by \sectionheading, but still
+ % prevent a page break here.
+ \centerpenalty = \lastpenalty
+ \ifnum\centerpenalty>10000 \vskip\parskip \fi
+ \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi
+ \line{\kern\leftskip #1\kern\rightskip}%
+}
+
+% @sp n outputs n lines of vertical space
+%
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+%
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+%
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \defaultparindent = 0pt
+ \else
+ \defaultparindent = #1em
+ \fi
+ \fi
+ \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \lispnarrowing = 0pt
+ \else
+ \lispnarrowing = #1em
+ \fi
+ \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading. If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\noneword
+ \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+ \else\ifx\temp\insertword
+ \let\suppressfirstparagraphindent = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @firstparagraphindent option `\temp'}%
+ \fi\fi
+}
+
+% Here is how we actually suppress indentation. Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+ \gdef\indent{%
+ \restorefirstparagraphindent
+ \indent
+ }%
+ \gdef\noindent{%
+ \restorefirstparagraphindent
+ \noindent
+ }%
+ \global\everypar = {%
+ \kern -\parindent
+ \restorefirstparagraphindent
+ }%
+}
+
+\gdef\restorefirstparagraphindent{%
+ \global \let \indent = \ptexindent
+ \global \let \noindent = \ptexnoindent
+ \global \everypar = {}%
+}
+
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \iflinks
+ \tryauxfile
+ % Open the new aux file. TeX will close it automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ \openin 1 texinfo.cnf
+ \ifeof 1 \else \input texinfo.cnf \fi
+ \closein 1
+ %
+ \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set). So we test for \relax and 0 as well as being undefined.
+\ifx\pdfoutput\thisisundefined
+\else
+ \ifx\pdfoutput\relax
+ \else
+ \ifcase\pdfoutput
+ \else
+ \pdftrue
+ \fi
+ \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places. Thus, we have to
+% double any backslashes. Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e. Not good.
+%
+% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
+% related messages. The final outcome is that it is up to the TeX user
+% to double the backslashes and otherwise make the string valid, so
+% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to
+% do this reliably, so we use it.
+
+% #1 is a control sequence in which to do the replacements,
+% which we \xdef.
+\def\txiescapepdf#1{%
+ \ifx\pdfescapestring\relax
+ % No primitive available; should we give a warning or log?
+ % Many times it won't matter.
+ \else
+ % The expandable \pdfescapestring primitive escapes parentheses,
+ % backslashes, and other special chars.
+ \xdef#1{\pdfescapestring{#1}}%
+ \fi
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found. (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
+\ifpdf
+ %
+ % Color manipulation macros based on pdfcolor.tex,
+ % except using rgb instead of cmyk; the latter is said to render as a
+ % very dark gray on-screen and a very dark halftone in print, instead
+ % of actual black.
+ \def\rgbDarkRed{0.50 0.09 0.12}
+ \def\rgbBlack{0 0 0}
+ %
+ % k sets the color for filling (usual text, etc.);
+ % K sets the color for stroking (thin rules, e.g., normal _'s).
+ \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}}
+ %
+ % Set color, and create a mark which defines \thiscolor accordingly,
+ % so that \makeheadline knows which color to restore.
+ \def\setcolor#1{%
+ \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
+ \domark
+ \pdfsetcolor{#1}%
+ }
+ %
+ \def\maincolor{\rgbBlack}
+ \pdfsetcolor{\maincolor}
+ \edef\thiscolor{\maincolor}
+ \def\lastcolordefs{}
+ %
+ \def\makefootline{%
+ \baselineskip24pt
+ \line{\pdfsetcolor{\maincolor}\the\footline}%
+ }
+ %
+ \def\makeheadline{%
+ \vbox to 0pt{%
+ \vskip-22.5pt
+ \line{%
+ \vbox to8.5pt{}%
+ % Extract \thiscolor definition from the marks.
+ \getcolormarks
+ % Typeset the headline with \maincolor, then restore the color.
+ \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
+ }%
+ \vss
+ }%
+ \nointerlineskip
+ }
+ %
+ %
+ \pdfcatalog{/PageMode /UseOutlines}
+ %
+ % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+ \def\dopdfimage#1#2#3{%
+ \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ %
+ % pdftex (and the PDF format) support .pdf, .png, .jpg (among
+ % others). Let's try in that order, PDF first since if
+ % someone has a scalable image, presumably better to use that than a
+ % bitmap.
+ \let\pdfimgext=\empty
+ \begingroup
+ \openin 1 #1.pdf \ifeof 1
+ \openin 1 #1.PDF \ifeof 1
+ \openin 1 #1.png \ifeof 1
+ \openin 1 #1.jpg \ifeof 1
+ \openin 1 #1.jpeg \ifeof 1
+ \openin 1 #1.JPG \ifeof 1
+ \errhelp = \nopdfimagehelp
+ \errmessage{Could not find image file #1 for pdf}%
+ \else \gdef\pdfimgext{JPG}%
+ \fi
+ \else \gdef\pdfimgext{jpeg}%
+ \fi
+ \else \gdef\pdfimgext{jpg}%
+ \fi
+ \else \gdef\pdfimgext{png}%
+ \fi
+ \else \gdef\pdfimgext{PDF}%
+ \fi
+ \else \gdef\pdfimgext{pdf}%
+ \fi
+ \closein 1
+ \endgroup
+ %
+ % without \immediate, ancient pdftex seg faults when the same image is
+ % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
+ \ifnum\pdftexversion < 14
+ \immediate\pdfimage
+ \else
+ \immediate\pdfximage
+ \fi
+ \ifdim \wd0 >0pt width \pdfimagewidth \fi
+ \ifdim \wd2 >0pt height \pdfimageheight \fi
+ \ifnum\pdftexversion<13
+ #1.\pdfimgext
+ \else
+ {#1.\pdfimgext}%
+ \fi
+ \ifnum\pdftexversion < 14 \else
+ \pdfrefximage \pdflastximage
+ \fi}
+ %
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code, and characters
+ % such as \, aren't expanded when present in a section title.
+ \indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ \def\pdfdestname{#1}%
+ \txiescapepdf\pdfdestname
+ \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+ }}
+ %
+ % used to mark target names; must be expandable.
+ \def\pdfmkpgn#1{#1}
+ %
+ % by default, use a color that is dark enough to print on paper as
+ % nearly black, but still distinguishable for online viewing.
+ \def\urlcolor{\rgbDarkRed}
+ \def\linkcolor{\rgbDarkRed}
+ \def\endlink{\setcolor{\maincolor}\pdfendlink}
+ %
+ % Adding outlines to PDF; macros for calculating structure of outlines
+ % come from Petr Olsak
+ \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi}
+ \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+ \advance\tempnum by 1
+ \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+ %
+ % #1 is the section text, which is what will be displayed in the
+ % outline by the pdf viewer. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node text,
+ % which might be empty if this toc entry had no corresponding node.
+ % #4 is the page number
+ %
+ \def\dopdfoutline#1#2#3#4{%
+ % Generate a link to the node text if that exists; else, use the
+ % page number. We could generate a destination for the section
+ % text in the case where a section has no node, but it doesn't
+ % seem worth the trouble, since most documents are normally structured.
+ \edef\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty
+ \def\pdfoutlinedest{#4}%
+ \else
+ \txiescapepdf\pdfoutlinedest
+ \fi
+ %
+ % Also escape PDF chars in the display string.
+ \edef\pdfoutlinetext{#1}%
+ \txiescapepdf\pdfoutlinetext
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \begingroup
+ % Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\partentry##1##2##3##4{}% ignore parts in the outlines
+ \def\numchapentry##1##2##3##4{%
+ \def\thischapnum{##2}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsecentry##1##2##3##4{%
+ \advancenumber{chap\thischapnum}%
+ \def\thissecnum{##2}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsubsecentry##1##2##3##4{%
+ \advancenumber{sec\thissecnum}%
+ \def\thissubsecnum{##2}%
+ }%
+ \def\numsubsubsecentry##1##2##3##4{%
+ \advancenumber{subsec\thissubsecnum}%
+ }%
+ \def\thischapnum{0}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ %
+ % use \def rather than \let here because we redefine \chapentry et
+ % al. a second time, below.
+ \def\appentry{\numchapentry}%
+ \def\appsecentry{\numsecentry}%
+ \def\appsubsecentry{\numsubsecentry}%
+ \def\appsubsubsecentry{\numsubsubsecentry}%
+ \def\unnchapentry{\numchapentry}%
+ \def\unnsecentry{\numsecentry}%
+ \def\unnsubsecentry{\numsubsecentry}%
+ \def\unnsubsubsecentry{\numsubsubsecentry}%
+ \readdatafile{toc}%
+ %
+ % Read toc second time, this time actually producing the outlines.
+ % The `-' means take the \expnumber as the absolute number of
+ % subentries, which we calculated on our first read of the .toc above.
+ %
+ % We use the node names as the destinations.
+ \def\numchapentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+ \def\numsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+ \def\numsubsubsecentry##1##2##3##4{% count is always zero
+ \dopdfoutline{##1}{}{##3}{##4}}%
+ %
+ % PDF outlines are displayed using system fonts, instead of
+ % document fonts. Therefore we cannot use special characters,
+ % since the encoding is unknown. For example, the eogonek from
+ % Latin 2 (0xea) gets translated to a | character. Info from
+ % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+ %
+ % TODO this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Too
+ % much work for too little return. Just use the ASCII equivalents
+ % we use for the index sort strings.
+ %
+ \indexnofonts
+ \setupdatafile
+ % We can have normal brace characters in the PDF outlines, unlike
+ % Texinfo index files. So set that up.
+ \def\{{\lbracecharliteral}%
+ \def\}{\rbracecharliteral}%
+ \catcode`\\=\active \otherbackslash
+ \input \tocreadfilename
+ \endgroup
+ }
+ {\catcode`[=1 \catcode`]=2
+ \catcode`{=\other \catcode`}=\other
+ \gdef\lbracecharliteral[{]%
+ \gdef\rbracecharliteral[}]%
+ ]
+ %
+ \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+ \ifx\PP\D\let\nextsp\relax
+ \else\let\nextsp\skipspaces
+ \ifx\p\space\else\addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
+ \fi
+ \fi
+ \nextsp}
+ \def\getfilename#1{%
+ \filenamelength=0
+ % If we don't expand the argument now, \skipspaces will get
+ % snagged on things like "@value{foo}".
+ \edef\temp{#1}%
+ \expandafter\skipspaces\temp|\relax
+ }
+ \ifnum\pdftexversion < 14
+ \let \startlink \pdfannotlink
+ \else
+ \let \startlink \pdfstartlink
+ \fi
+ % make a live url in pdf output.
+ \def\pdfurl#1{%
+ \begingroup
+ % it seems we really need yet another set of dummies; have not
+ % tried to figure out what each command should do in the context
+ % of @url. for now, just make @/ a no-op, that's the only one
+ % people have actually reported a problem with.
+ %
+ \normalturnoffactive
+ \def\@{@}%
+ \let\/=\empty
+ \makevalueexpandable
+ % do we want to go so far as to use \indexnofonts instead of just
+ % special-casing \var here?
+ \def\var##1{##1}%
+ %
+ \leavevmode\setcolor{\urlcolor}%
+ \startlink attr{/Border [0 0 0]}%
+ user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+ \endgroup}
+ \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+ \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+ \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+ \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+ \def\maketoks{%
+ \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+ \ifx\first0\adn0
+ \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+ \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+ \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+ \else
+ \ifnum0=\countA\else\makelink\fi
+ \ifx\first.\let\next=\done\else
+ \let\next=\maketoks
+ \addtokens{\toksB}{\the\toksD}
+ \ifx\first,\addtokens{\toksB}{\space}\fi
+ \fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next}
+ \def\makelink{\addtokens{\toksB}%
+ {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+ \def\pdflink#1{%
+ \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+ \setcolor{\linkcolor}#1\endlink}
+ \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+ % non-pdf mode
+ \let\pdfmkdest = \gobble
+ \let\pdfurl = \gobble
+ \let\endlink = \relax
+ \let\setcolor = \gobble
+ \let\pdfsetcolor = \gobble
+ \let\pdfmakeoutlines = \relax
+\fi % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+ \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+ \csname ten#1\endcsname % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Unfortunately, we have to override this for titles and the like, since
+% in those cases "rm" is bold. Sigh.
+\def\rmisbold{\rm\def\curfontstyle{bf}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% Default leading.
+\newdimen\textleading \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+% can get a sort of poor man's double spacing by redefining this.
+\def\baselinefactor{1}
+%
+\def\setleading#1{%
+ \dimen0 = #1\relax
+ \normalbaselineskip = \baselinefactor\dimen0
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+% PDF CMaps. See also LaTeX's t1.cmap.
+%
+% do nothing with this by default.
+\expandafter\let\csname cmapOT1\endcsname\gobble
+\expandafter\let\csname cmapOT1IT\endcsname\gobble
+\expandafter\let\csname cmapOT1TT\endcsname\gobble
+
+% if we are producing pdf, and we have \pdffontattr, then define cmaps.
+% (\pdffontattr was introduced many years ago, but people still run
+% older pdftex's; it's easy to conditionalize, so we do.)
+\ifpdf \ifx\pdffontattr\thisisundefined \else
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1IT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1TT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+\fi\fi
+
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
+% empty to omit).
+\def\setfont#1#2#3#4#5{%
+ \font#1=\fontprefix#2#3 scaled #4
+ \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+% emacs-page end of cmaps
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\thisisundefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx} %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Definitions for a main text size of 11pt. This is the default in
+% Texinfo.
+%
+\def\definetextfontsizexi{%
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1095}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+\def\chapecsize{1728}
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+\def\sececsize{1440}
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+\def\ssececsize{1200}
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+\def\reducedecsize{1000}
+
+\textleading = 13.2pt % line spacing for 11pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 11pt text font size definitions
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit. This is for the GNU
+% Press printing of the Emacs 22 manual. Maybe other manuals in the
+% future. Used with @smallbook, which sets the leading to 12pt.
+%
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1000}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+\def\chapecsize{1440}
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+\def\sececsize{1200}
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+\def\ssececsize{1000}
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+\def\reducedecsize{0900}
+
+\divide\parskip by 2 % reduce space between paragraphs
+\textleading = 12pt % line spacing for 10pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 10pt text font size definitions
+
+
+% We provide the user-level command
+% @fonttextsize 10
+% (or 11) to redefine the text font size. pt is assumed.
+%
+\def\xiword{11}
+\def\xword{10}
+\def\xwordpt{10pt}
+%
+\parseargdef\fonttextsize{%
+ \def\textsizearg{#1}%
+ %\wlog{doing @fonttextsize \textsizearg}%
+ %
+ % Set \globaldefs so that documents can use this inside @tex, since
+ % makeinfo 4.8 does not support it, but we need it nonetheless.
+ %
+ \begingroup \globaldefs=1
+ \ifx\textsizearg\xword \definetextfontsizex
+ \else \ifx\textsizearg\xiword \definetextfontsizexi
+ \else
+ \errhelp=\EMsimple
+ \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+ \fi\fi
+ \endgroup
+}
+
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+ \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+ \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this because \STYLE needs to also set the
+% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower). These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \let\tenttsl=\textttsl
+ \def\curfontsize{text}%
+ \def\lsize{reduced}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+ \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+ \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+ \let\tenttsl=\titlettsl
+ \def\curfontsize{title}%
+ \def\lsize{chap}\def\lllsize{subsec}%
+ \resetmathfonts \setleading{27pt}}
+\def\titlefont#1{{\titlefonts\rmisbold #1}}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \let\tenttsl=\chapttsl
+ \def\curfontsize{chap}%
+ \def\lsize{sec}\def\lllsize{text}%
+ \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \let\tenttsl=\secttsl
+ \def\curfontsize{sec}%
+ \def\lsize{subsec}\def\lllsize{reduced}%
+ \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \let\tenttsl=\ssecttsl
+ \def\curfontsize{ssec}%
+ \def\lsize{text}\def\lllsize{small}%
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+ \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+ \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+ \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+ \let\tenttsl=\reducedttsl
+ \def\curfontsize{reduced}%
+ \def\lsize{small}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+ \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+ \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+ \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+ \let\tenttsl=\smallttsl
+ \def\curfontsize{small}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+ \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+ \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+ \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+ \let\tenttsl=\smallerttsl
+ \def\curfontsize{smaller}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{9.5pt}}
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+% Define these just so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+% 8.5x11=86 smallbook=72 a4=90 a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+% 8.5x11=90+ smallbook=80 a4=90+ a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt. So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+% 8.5x11=71 smallbook=60 a4=75 a5=58
+% --karl, 24jan03.
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+
+\message{markup,}
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will
+% define and register \INITMACRO to be called on markup style changes.
+% \INITMACRO can check \currentmarkupstyle for the innermost
+% style and the set of \ifmarkupSTYLE switches for all styles
+% currently in effect.
+\newif\ifmarkupvar
+\newif\ifmarkupsamp
+\newif\ifmarkupkey
+%\newif\ifmarkupfile % @file == @samp.
+%\newif\ifmarkupoption % @option == @samp.
+\newif\ifmarkupcode
+\newif\ifmarkupkbd
+%\newif\ifmarkupenv % @env == @code.
+%\newif\ifmarkupcommand % @command == @code.
+\newif\ifmarkuptex % @tex (and part of @math, for now).
+\newif\ifmarkupexample
+\newif\ifmarkupverb
+\newif\ifmarkupverbatim
+
+\let\currentmarkupstyle\empty
+
+\def\setupmarkupstyle#1{%
+ \csname markup#1true\endcsname
+ \def\currentmarkupstyle{#1}%
+ \markupstylesetup
+}
+
+\let\markupstylesetup\empty
+
+\def\defmarkupstylesetup#1{%
+ \expandafter\def\expandafter\markupstylesetup
+ \expandafter{\markupstylesetup #1}%
+ \def#1%
+}
+
+% Markup style setup for left and right quotes.
+\defmarkupstylesetup\markupsetuplq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuplq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuplqdefault \else \temp \fi
+}
+
+\defmarkupstylesetup\markupsetuprq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuprq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuprqdefault \else \temp \fi
+}
+
+{
+\catcode`\'=\active
+\catcode`\`=\active
+
+\gdef\markupsetuplqdefault{\let`\lq}
+\gdef\markupsetuprqdefault{\let'\rq}
+
+\gdef\markupsetcodequoteleft{\let`\codequoteleft}
+\gdef\markupsetcodequoteright{\let'\codequoteright}
+
+\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft}
+}
+
+\let\markupsetuplqcode \markupsetcodequoteleft
+\let\markupsetuprqcode \markupsetcodequoteright
+%
+\let\markupsetuplqexample \markupsetcodequoteleft
+\let\markupsetuprqexample \markupsetcodequoteright
+%
+\let\markupsetuplqsamp \markupsetcodequoteleft
+\let\markupsetuprqsamp \markupsetcodequoteright
+%
+\let\markupsetuplqverb \markupsetcodequoteleft
+\let\markupsetuprqverb \markupsetcodequoteright
+%
+\let\markupsetuplqverbatim \markupsetcodequoteleft
+\let\markupsetuprqverbatim \markupsetcodequoteright
+
+\let\markupsetuplqkbd \markupsetnoligaturesquoteleft
+
+% Allow an option to not use regular directed right quote/apostrophe
+% (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
+% The undirected quote is ugly, so don't make it the default, but it
+% works for pasting with more pdf viewers (at least evince), the
+% lilypond developers report. xpdf does work with the regular 0x27.
+%
+\def\codequoteright{%
+ \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+ \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ '%
+ \else \char'15 \fi
+ \else \char'15 \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+ \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
+ \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ % [Knuth] pp. 380,381,391
+ % \relax disables Spanish ligatures ?` and !` of \tt font.
+ \relax`%
+ \else \char'22 \fi
+ \else \char'22 \fi
+}
+
+% Commands to set the quote options.
+%
+\parseargdef\codequoteundirected{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}%
+ \fi\fi
+}
+%
+\parseargdef\codequotebacktick{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}%
+ \fi\fi
+}
+
+% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font.
+\def\noligaturesquoteleft{\relax\lq}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Font commands.
+
+% #1 is the font command (\sl or \it), #2 is the text to slant.
+% If we are in a monospaced environment, however, 1) always use \ttsl,
+% and 2) do not add an italic correction.
+\def\dosmartslant#1#2{%
+ \ifusingtt
+ {{\ttsl #2}\let\next=\relax}%
+ {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}%
+ \next
+}
+\def\smartslanted{\dosmartslant\sl}
+\def\smartitalic{\dosmartslant\it}
+
+% Output an italic correction unless \next (presumed to be the following
+% character) is such as not to need one.
+\def\smartitaliccorrection{%
+ \ifx\next,%
+ \else\ifx\next-%
+ \else\ifx\next.%
+ \else\ptexslash
+ \fi\fi\fi
+ \aftersmartic
+}
+
+% like \smartslanted except unconditionally uses \ttsl, and no ic.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}}
+
+% @cite is like \smartslanted except unconditionally use \sl. We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection}
+
+\def\aftersmartic{}
+\def\var#1{%
+ \let\saveaftersmartic = \aftersmartic
+ \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}%
+ \smartslanted{#1}%
+}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @b, explicit bold. Also @strong.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+ \def\plainfrenchspacing{%
+ \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+ \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ \def\endofsentencespacefactor{1000}% for @. and friends
+ }
+ \def\plainnonfrenchspacing{%
+ \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+ \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+ \def\endofsentencespacefactor{3000}% for @. and friends
+ }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+% @t, explicit typewriter.
+\def\t#1{%
+ {\tt \rawbackslash \plainfrenchspacing #1}%
+ \null
+}
+
+% @samp.
+\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
+
+% definition of @key that produces a lozenge. Doesn't adjust to text size.
+%\setfont\keyrm\rmshape{8}{1000}{OT1}
+%\font\keysy=cmsy9
+%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+% \vbox{\hrule\kern-0.4pt
+% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+% \kern-0.4pt\hrule}%
+% \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+
+% definition of @key with no lozenge. If the current font is already
+% monospace, don't change it; that way, we respect @kbdinputstyle. But
+% if it isn't monospace, then use \tt.
+%
+\def\key#1{{\setupmarkupstyle{key}%
+ \nohyphenation
+ \ifmonospace\else\tt\fi
+ #1}\null}
+
+% ctrl is no longer a Texinfo command.
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \plainfrenchspacing
+ #1%
+ }%
+ \null % reset spacefactor to 1000
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+% -- rms.
+{
+ \catcode`\-=\active \catcode`\_=\active
+ \catcode`\'=\active \catcode`\`=\active
+ \global\let'=\rq \global\let`=\lq % default definitions
+ %
+ \global\def\code{\begingroup
+ \setupmarkupstyle{code}%
+ % The following should really be moved into \setupmarkupstyle handlers.
+ \catcode\dashChar=\active \catcode\underChar=\active
+ \ifallowcodebreaks
+ \let-\codedash
+ \let_\codeunder
+ \else
+ \let-\realdash
+ \let_\realunder
+ \fi
+ \codex
+ }
+}
+
+\def\codex #1{\tclose{#1}\endgroup}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+ % this is all so @math{@code{var_name}+1} can work. In math mode, _
+ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+ % will therefore expand the active definition of _, which is us
+ % (inside @code that is), therefore an endless loop.
+ \ifusingtt{\ifmmode
+ \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+ \else\normalunderscore \fi
+ \discretionary{}{}{}}%
+ {\_}%
+}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__. This is undesirable in
+% some manuals, especially if they don't have long identifiers in
+% general. @allowcodebreaks provides a way to control this.
+%
+\newif\ifallowcodebreaks \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\keywordtrue
+ \allowcodebreakstrue
+ \else\ifx\txiarg\keywordfalse
+ \allowcodebreaksfalse
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}%
+ \fi\fi
+}
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself. First (mandatory) arg is the url.
+% (This \urefnobreak definition isn't used now, leaving it for a while
+% for comparison.)
+\def\urefnobreak#1{\dourefnobreak #1,,,\finish}
+\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \code{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% This \urefbreak definition is the active one.
+\def\urefbreak{\begingroup \urefcatcodes \dourefbreak}
+\let\uref=\urefbreak
+\def\dourefbreak#1{\urefbreakfinish #1,,,\finish}
+\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \urefcode{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% Allow line breaks around only a few characters (only).
+\def\urefcatcodes{%
+ \catcode\ampChar=\active \catcode\dotChar=\active
+ \catcode\hashChar=\active \catcode\questChar=\active
+ \catcode\slashChar=\active
+}
+{
+ \urefcatcodes
+ %
+ \global\def\urefcode{\begingroup
+ \setupmarkupstyle{code}%
+ \urefcatcodes
+ \let&\urefcodeamp
+ \let.\urefcodedot
+ \let#\urefcodehash
+ \let?\urefcodequest
+ \let/\urefcodeslash
+ \codex
+ }
+ %
+ % By default, they are just regular characters.
+ \global\def&{\normalamp}
+ \global\def.{\normaldot}
+ \global\def#{\normalhash}
+ \global\def?{\normalquest}
+ \global\def/{\normalslash}
+}
+
+% we put a little stretch before and after the breakable chars, to help
+% line breaking of long url's. The unequal skips make look better in
+% cmtt at least, especially for dots.
+\def\urefprestretch{\urefprebreak \hskip0pt plus.13em }
+\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em }
+%
+\def\urefcodeamp{\urefprestretch \&\urefpoststretch}
+\def\urefcodedot{\urefprestretch .\urefpoststretch}
+\def\urefcodehash{\urefprestretch \#\urefpoststretch}
+\def\urefcodequest{\urefprestretch ?\urefpoststretch}
+\def\urefcodeslash{\futurelet\next\urefcodeslashfinish}
+{
+ \catcode`\/=\active
+ \global\def\urefcodeslashfinish{%
+ \urefprestretch \slashChar
+ % Allow line break only after the final / in a sequence of
+ % slashes, to avoid line break between the slashes in http://.
+ \ifx\next/\else \urefpoststretch \fi
+ }
+}
+
+% One more complication: by default we'll break after the special
+% characters, but some people like to break before the special chars, so
+% allow that. Also allow no breaking at all, for manual control.
+%
+\parseargdef\urefbreakstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\wordnone
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordbefore
+ \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordafter
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak}
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @urefbreakstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\wordafter{after}
+\def\wordbefore{before}
+\def\wordnone{none}
+
+\urefbreakstyle after
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+ \def\email#1{\doemail#1,,\finish}
+ \def\doemail#1,#2,#3\finish{\begingroup
+ \unsepspaces
+ \pdfurl{mailto:#1}%
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+ \endlink
+ \endgroup}
+\else
+ \let\email=\uref
+\fi
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}}
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct'.
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @clicksequence{File @click{} Open ...}
+\def\clicksequence#1{\begingroup #1\endgroup}
+
+% @clickstyle @arrow (by default)
+\parseargdef\clickstyle{\def\click{#1}}
+\def\click{\arrow}
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+%
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+ {\selectfonts\lsize #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+ \null % reset \spacefactor=1000
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+%
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+ {\plainfrenchspacing #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+ \null % reset \spacefactor=1000
+}
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode`\_ = \active
+ \gdef\mathunderscore{%
+ \catcode`\_=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a math (or tt) \.
+% FYI, plain.tex uses \\ as a temporary control sequence (for no
+% particular reason), but this is not advertised and we don't care.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ % make the texinfo accent commands work in math mode
+ \let\"=\ddot
+ \let\'=\acute
+ \let\==\bar
+ \let\^=\hat
+ \let\`=\grave
+ \let\u=\breve
+ \let\v=\check
+ \let\~=\tilde
+ \let\dotaccent=\dot
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \catcode`' = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ \let' = \ptexquoteright
+ }
+}
+
+% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
+% Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
+% except specified as a normal braced arg, so no newlines to worry about.
+%
+\def\outfmtnametex{tex}
+%
+\long\def\inlinefmt#1{\doinlinefmt #1,\finish}
+\long\def\doinlinefmt#1,#2,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi
+}
+% For raw, must switch into @tex before parsing the argument, to avoid
+% setting catcodes prematurely. Doing it this way means that, for
+% example, @inlineraw{html, foo{bar} gets a parse error instead of being
+% ignored. But this isn't important because if people want a literal
+% *right* brace they would have to use a command anyway, so they may as
+% well use a command to get a left brace too. We could re-use the
+% delimiter character idea from \verb, but it seems like overkill.
+%
+\long\def\inlineraw{\tex \doinlineraw}
+\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish}
+\def\doinlinerawtwo#1,#2,\finish{%
+ \def\inlinerawname{#1}%
+ \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi
+ \endgroup % close group opened by \tex.
+}
+
+
+\message{glyphs,}
+% and logos.
+
+% @@ prints an @, as does @atchar{}.
+\def\@{\char64 }
+\let\atchar=\@
+
+% @{ @} @lbracechar{} @rbracechar{} all generate brace characters.
+% Unless we're in typewriter, use \ecfont because the CM text fonts do
+% not have braces, and we don't want to switch into math.
+\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}}
+\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}}
+\let\{=\mylbrace \let\lbracechar=\{
+\let\}=\myrbrace \let\rbracechar=\}
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux/toc files.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \ptexc
+\let\dotaccent = \ptexdot
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \ptext
+\let\ubaraccent = \ptexb
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi
+ \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{%
+ \ifx\textnominalsize\xwordpt
+ % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX.
+ % Revert to plain's \scriptsize, which is 7pt.
+ \count255=\the\fam $\fam\count255 \scriptstyle A$%
+ \else
+ % For 11pt, we can use our lllsize.
+ \selectfonts\lllsize A%
+ \fi
+ }%
+ \vss
+ }}%
+ \kern-.15em
+ \TeX
+}
+
+% Some math mode symbols.
+\def\bullet{$\ptexbullet$}
+\def\geq{\ifmmode \ge\else $\ge$\fi}
+\def\leq{\ifmmode \le\else $\le$\fi}
+\def\minus{\ifmmode -\else $-$\fi}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em. So do
+% whichever is larger.
+%
+\def\dots{%
+ \leavevmode
+ \setbox0=\hbox{...}% get width of three periods
+ \ifdim\wd0 > 1.5em
+ \dimen0 = \wd0
+ \else
+ \dimen0 = 1.5em
+ \fi
+ \hbox to \dimen0{%
+ \hskip 0pt plus.25fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=\endofsentencespacefactor
+}
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, they should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}}
+\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that. The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math. Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+ % We set the font at each command, rather than predefining it in
+ % \textfonts and the other font-switching commands, so that
+ % installations which never need the symbol don't have to have the
+ % font installed.
+ %
+ % There is only one designed size (nominal 10pt), so we always scale
+ % that to the current nominal size.
+ %
+ % By the way, simply using "at 1em" works for cmr10 and the like, but
+ % does not work for cmbx10 and other extended/shrunken fonts.
+ %
+ \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+ %
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+ \else
+ % regular:
+ \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+ \fi
+ \thiseurofont
+}
+
+% Glyphs from the EC fonts. We don't use \let for the aliases, because
+% sometimes we redefine the original macro, and the alias should reflect
+% the redefinition.
+%
+% Use LaTeX names for the Icelandic letters.
+\def\DH{{\ecfont \char"D0}} % Eth
+\def\dh{{\ecfont \char"F0}} % eth
+\def\TH{{\ecfont \char"DE}} % Thorn
+\def\th{{\ecfont \char"FE}} % thorn
+%
+\def\guillemetleft{{\ecfont \char"13}}
+\def\guillemotleft{\guillemetleft}
+\def\guillemetright{{\ecfont \char"14}}
+\def\guillemotright{\guillemetright}
+\def\guilsinglleft{{\ecfont \char"0E}}
+\def\guilsinglright{{\ecfont \char"0F}}
+\def\quotedblbase{{\ecfont \char"12}}
+\def\quotesinglbase{{\ecfont \char"0D}}
+%
+% This positioning is not perfect (see the ogonek LaTeX package), but
+% we have the precomposed glyphs for the most common cases. We put the
+% tests to use those glyphs in the single \ogonek macro so we have fewer
+% dummy definitions to worry about for index entries, etc.
+%
+% ogonek is also used with other letters in Lithuanian (IOU), but using
+% the precomposed glyphs for those is not so easy since they aren't in
+% the same EC font.
+\def\ogonek#1{{%
+ \def\temp{#1}%
+ \ifx\temp\macrocharA\Aogonek
+ \else\ifx\temp\macrochara\aogonek
+ \else\ifx\temp\macrocharE\Eogonek
+ \else\ifx\temp\macrochare\eogonek
+ \else
+ \ecfont \setbox0=\hbox{#1}%
+ \ifdim\ht0=1ex\accent"0C #1%
+ \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}%
+ \fi
+ \fi\fi\fi\fi
+ }%
+}
+\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A}
+\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a}
+\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E}
+\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e}
+%
+% Use the ec* fonts (cm-super in outline format) for non-CM glyphs.
+\def\ecfont{%
+ % We can't distinguish serif/sans and italic/slanted, but this
+ % is used for crude hacks anyway (like adding French and German
+ % quotes to documents typeset with CM, where we lose kerning), so
+ % hopefully nobody will notice/care.
+ \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+ \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \else
+ % regular:
+ \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \fi
+ \thisecfont
+}
+
+% @registeredsymbol - R in a circle. The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+ \hfil\crcr\Orb}}%
+ }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% Laurent Siebenmann reports \Orb undefined with:
+% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
+% so we'll define it if necessary.
+%
+\ifx\Orb\thisisundefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+% Quotes.
+\chardef\quotedblleft="5C
+\chardef\quotedblright=`\"
+\chardef\quoteleft=`\`
+\chardef\quoteright=`\'
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{%
+ \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+ % Open one extra group, as we want to close it in the middle of \Etitlepage.
+ \begingroup
+ \parindent=0pt \textfonts
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \let\page = \oldpage
+ \page
+ \null
+ }%
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ %
+ % Need this before the \...aftertitlepage checks so that if they are
+ % in effect the toc pages will come out with page numbers.
+ \HEADINGSon
+ %
+ % If they want short, they certainly want long too.
+ \ifsetshortcontentsaftertitlepage
+ \shortcontents
+ \contents
+ \global\let\shortcontents = \relax
+ \global\let\contents = \relax
+ \fi
+ %
+ \ifsetcontentsaftertitlepage
+ \contents
+ \global\let\contents = \relax
+ \global\let\shortcontents = \relax
+ \fi
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\parseargdef\title{%
+ \checkenv\titlepage
+ \leftline{\titlefonts\rmisbold #1}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+ \checkenv\titlepage
+ {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+ \def\temp{\quotation}%
+ \ifx\thisenv\temp
+ \def\quotationauthor{#1}% printed in \Equotation.
+ \else
+ \checkenv\titlepage
+ \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+ {\secfonts\rmisbold \leftline{#1}}%
+ \fi
+}
+
+
+% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline % headline on even pages
+\newtoks\oddheadline % headline on odd pages
+\newtoks\evenfootline % footline on even pages
+\newtoks\oddfootline % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+ \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+ %
+ % Leave some space for the footline. Hopefully ok to assume
+ % @evenfooting will not be used by itself.
+ \global\advance\pageheight by -12pt
+ \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+% @evenheadingmarks top \thischapter <- chapter at the top of a page
+% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page
+%
+% The same set of arguments for:
+%
+% @oddheadingmarks
+% @evenfootingmarks
+% @oddfootingmarks
+% @everyheadingmarks
+% @everyfootingmarks
+
+\def\evenheadingmarks{\headingmarks{even}{heading}}
+\def\oddheadingmarks{\headingmarks{odd}{heading}}
+\def\evenfootingmarks{\headingmarks{even}{footing}}
+\def\oddfootingmarks{\headingmarks{odd}{footing}}
+\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
+ \headingmarks{odd}{heading}{#1} }
+\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
+ \headingmarks{odd}{footing}{#1} }
+% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
+\def\headingmarks#1#2#3 {%
+ \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
+ \global\expandafter\let\csname get#1#2marks\endcsname \temp
+}
+
+\everyheadingmarks bottom
+\everyfootingmarks bottom
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\headingsoff{% non-global headings elimination
+ \evenheadline={\hfil}\evenfootline={\hfil}%
+ \oddheadline={\hfil}\oddfootline={\hfil}%
+}
+
+\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting
+\HEADINGSoff % it's the default
+
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\thisisundefined
+\def\today{%
+ \number\day\space
+ \ifcase\month
+ \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+ \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+ \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+ \fi
+ \space\number\year}
+\fi
+
+% @settitle line... specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemindicate{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil\relax
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. However, if
+ % what follows is an environment such as @example, there will be no
+ % \parskip glue; then the negative vskip we just inserted would
+ % cause the example and the item to crash together. So we use this
+ % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+ % \parskip glue after all. Section titles are handled this way also.
+ %
+ \penalty 10001
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line.
+ \noindent
+ % Do this with kerns and \unhbox so that if there is a footnote in
+ % the item text, it can migrate to the main vertical list and
+ % eventually be printed.
+ \nobreak\kern-\tableindent
+ \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+ \unhbox0
+ \nobreak\kern\dimen0
+ \endgroup
+ \itemxneedsnegativevskiptrue
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+ \let\itemindex\gobble
+ \tablecheck{table}%
+}
+\envdef\ftable{%
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablecheck{ftable}%
+}
+\envdef\vtable{%
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+ \ifnum \the\catcode`\^^M=\active
+ \endgroup
+ \errmessage{This command won't work in this context; perhaps the problem is
+ that we are \inenvironment\thisenv}%
+ \def\next{\doignore{#1}}%
+ \else
+ \let\next\tablex
+ \fi
+ \next
+}
+\def\tablex#1{%
+ \def\itemindicate{#1}%
+ \parsearg\tabley
+}
+\def\tabley#1{%
+ {%
+ \makevalueexpandable
+ \edef\temp{\noexpand\tablez #1\space\space\space}%
+ \expandafter
+ }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+ \aboveenvbreak
+ \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+ \ifnum 0#2>0 \tableindent=#2\mil \fi
+ \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+ \itemmax=\tableindent
+ \advance \itemmax by -\itemmargin
+ \advance \leftskip by \tableindent
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi
+ \let\item = \internalBitem
+ \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+ \aboveenvbreak
+ \itemmax=\itemindent
+ \advance\itemmax by -\itemmargin
+ \advance\leftskip by \itemindent
+ \exdentamount=\itemindent
+ \parindent=0pt
+ \parskip=\smallskipamount
+ \ifdim\parskip=0pt \parskip=2pt \fi
+ %
+ % Try typesetting the item mark that if the document erroneously says
+ % something like @itemize @samp (intending @table), there's an error
+ % right away at the @itemize. It's not the best error message in the
+ % world, but it's better than leaving it to the @item. This means if
+ % the user wants an empty mark, they have to say @w{} not just @w.
+ \def\itemcontents{#1}%
+ \setbox0 = \hbox{\itemcontents}%
+ %
+ % @itemize with no arg is equivalent to @itemize @bullet.
+ \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ %
+ \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+ \advance\itemno by 1 % for enumerations
+ {\let\par=\endgraf \smallbreak}% reasonable place to break
+ {%
+ % If the document has an @itemize directly after a section title, a
+ % \nobreak will be last on the list, and \sectionheading will have
+ % done a \vskip-\parskip. In that case, we don't want to zero
+ % parskip, or the item text will crash with the heading. On the
+ % other hand, when there is normal text preceding the item (as there
+ % usually is), we do want to zero parskip, or there would be too much
+ % space. In that case, we won't have a \nobreak before. At least
+ % that's the theory.
+ \ifnum\lastpenalty<10000 \parskip=0in \fi
+ \noindent
+ \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ %
+ \vadjust{\penalty 1200}}% not good to break after first line of item.
+ \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @columnfractions .25 .3 .45
+% @item ...
+%
+% Numbers following @columnfractions are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1. We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+ \global\advance\colcount by 1
+ \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+ \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+ \def\firstarg{#1}%
+ \ifx\firstarg\xendsetuptable
+ \let\go = \relax
+ \else
+ \ifx\firstarg\xcolumnfractions
+ \global\setpercenttrue
+ \else
+ \ifsetpercent
+ \let\go\pickupwholefraction
+ \else
+ \global\advance\colcount by 1
+ \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+ % separator; typically that is always in the input, anyway.
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi
+ \fi
+ \ifx\go\pickupwholefraction
+ % Put the argument back for the \pickupwholefraction call, so
+ % we'll always have a period there to be parsed.
+ \def\go{\pickupwholefraction#1}%
+ \else
+ \let\go = \setuptable
+ \fi%
+ \fi
+ \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry. \everycr resets \everytab so we don't have to
+% undo it ourselves.
+\def\headitemfont{\b}% for people to use in the template row; not changeable
+\def\headitem{%
+ \checkenv\multitable
+ \crcr
+ \global\everytab={\bf}% can't use \headitemfont since the parsing differs
+ \the\everytab % for the first item
+}%
+%
+% A \tab used to include \hskip1sp. But then the space in a template
+% line is not enough. That is bad. So let's go back to just `&' until
+% we again encounter the problem the 1sp was intended to solve.
+% --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab % insert after every tab.
+%
+\envdef\multitable{%
+ \vskip\parskip
+ \startsavinginserts
+ %
+ % @item within a multitable starts a normal row.
+ % We use \def instead of \let so that if one of the multitable entries
+ % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+ % \endtemplate) expanding \doitemize.
+ \def\item{\crcr}%
+ %
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ %
+ \everycr = {%
+ \noalign{%
+ \global\everytab={}%
+ \global\colcount=0 % Reset the column counter.
+ % Check for saved footnotes, etc.
+ \checkinserts
+ % Keeps underfull box messages off when table breaks over pages.
+ %\filbreak
+ % Maybe so, but it also creates really weird page breaks when the
+ % table breaks over pages. Wouldn't \vfil be better? Wait until the
+ % problem manifests itself, so it can be fixed for real --karl.
+ }%
+ }%
+ %
+ \parsearg\domultitable
+}
+\def\domultitable#1{%
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+ \halign\bgroup &%
+ \global\advance\colcount by 1
+ \multistrut
+ \vtop{%
+ % Use the current \colcount to find the correct column width:
+ \hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively
+ % marking characters.
+ \noindent\ignorespaces##\unskip\multistrut
+ }\cr
+}
+\def\Emultitable{%
+ \crcr
+ \egroup % end the \halign
+ \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+ \def\multistrut{\strut}% just use the standard line spacing
+ %
+ % Compute \multitablelinespace (if not defined by user) for use in
+ % \multitableparskip calculation. We used define \multistrut based on
+ % this, but (ironically) that caused the spacing to be off.
+ % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+% Test to see if parskip is larger than space between lines of
+% table. If not, do nothing.
+% If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed. They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested. But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+ \expandafter\let\csname #1\endcsname = \relax
+ \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+ % Scan in ``verbatim'' mode:
+ \obeylines
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \spaceisspace
+ %
+ % Count number of #1's that we've seen.
+ \doignorecount = 0
+ %
+ % Swallow text until we reach the matching `@end #1'.
+ \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+ \obeylines %
+ %
+ \gdef\dodoignore#1{%
+ % #1 contains the command name as a string, e.g., `ifinfo'.
+ %
+ % Define a command to find the next `@end #1'.
+ \long\def\doignoretext##1^^M@end #1{%
+ \doignoretextyyy##1^^M@#1\_STOP_}%
+ %
+ % And this command to find another #1 command, at the beginning of a
+ % line. (Otherwise, we would consider a line `@c @ifset', for
+ % example, to count as an @ifset for nesting.)
+ \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+ %
+ % And now expand that command.
+ \doignoretext ^^M%
+ }%
+}
+
+\def\doignoreyyy#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty % Nothing found.
+ \let\next\doignoretextzzz
+ \else % Found a nested condition, ...
+ \advance\doignorecount by 1
+ \let\next\doignoretextyyy % ..., look for another.
+ % If we're here, #1 ends with ^^M\ifinfo (for example).
+ \fi
+ \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+ \ifnum\doignorecount = 0 % We have just found the outermost @end.
+ \let\next\enddoignore
+ \else % Still inside a nested condition.
+ \advance\doignorecount by -1
+ \let\next\doignoretext % Look for the next @end.
+ \fi
+ \next
+}
+
+% Finish off ignored text.
+{ \obeylines%
+ % Ignore anything after the last `@end #1'; this matters in verbatim
+ % environments, where otherwise the newline after an ignored conditional
+ % would result in a blank line in the output.
+ \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ {%
+ \makevalueexpandable
+ \def\temp{#2}%
+ \edef\next{\gdef\makecsname{SET#1}}%
+ \ifx\temp\empty
+ \next{}%
+ \else
+ \setzzz#2\endsetzzz
+ \fi
+ }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+ {%
+ \makevalueexpandable
+ \global\expandafter\let\csname SET#1\endcsname=\relax
+ }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+ \catcode`\- = \active \catcode`\_ = \active
+ %
+ \gdef\makevalueexpandable{%
+ \let\value = \expandablevalue
+ % We don't want these characters active, ...
+ \catcode`\-=\other \catcode`\_=\other
+ % ..., but we might end up with active ones in the argument if
+ % we're called from @code, as @code{@value{foo-bar_}}, though.
+ % So \let them to their normal equivalents.
+ \let-\realdash \let_\normalunderscore
+ }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file. This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {[No value for ``#1'']}%
+ \message{Variable `#1', used in @value, is not set.}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+ {%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname SET#2\endcsname\relax
+ #1% If not set, redefine \next.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{% % Define @#1index
+ \noexpand\doindex{#1}}
+}
+
+% @defindex foo == \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{%
+ \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+ % Only do \closeout if we haven't already done it, else we'll end up
+ % closing the target index.
+ \expandafter \ifx\csname donesynindex#2\endcsname \relax
+ % The \closeout helps reduce unnecessary open files; the limit on the
+ % Acorn RISC OS is a mere 16 files.
+ \expandafter\closeout\csname#2indfile\endcsname
+ \expandafter\let\csname donesynindex#2\endcsname = 1
+ \fi
+ % redefine \fooindfile:
+ \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+ \expandafter\let\csname#2indfile\endcsname=\temp
+ % redefine \fooindex:
+ \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+ \escapechar = `\\ % use backslash in output files.
+ \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+ \def\ {\realbackslash\space }%
+ %
+ % Need these unexpandable (because we define \tt as a dummy)
+ % definitions when @{ or @} appear in index entry text. Also, more
+ % complicated, when \tex is in effect and \{ is a \delimiter again.
+ % We can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters. Perhaps we
+ % should define @lbrace and @rbrace commands a la @comma.
+ \def\{{{\tt\char123}}%
+ \def\}{{\tt\char125}}%
+ %
+ % I don't entirely understand this, but when an index entry is
+ % generated from a macro call, the \endinput which \scanmacro inserts
+ % causes processing to be prematurely terminated. This is,
+ % apparently, because \indexsorttmp is fully expanded, and \endinput
+ % is an expandable command. The redefinition below makes \endinput
+ % disappear altogether for that purpose -- although logging shows that
+ % processing continues to some further point. On the other hand, it
+ % seems \endinput does not hurt in the printed index arg, since that
+ % is still getting written without apparent harm.
+ %
+ % Sample source (mac-idx3.tex, reported by Graham Percival to
+ % help-texinfo, 22may06):
+ % @macro funindex {WORD}
+ % @findex xyz
+ % @end macro
+ % ...
+ % @funindex commtest
+ %
+ % The above is not enough to reproduce the bug, but it gives the flavor.
+ %
+ % Sample whatsit resulting:
+ % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+ %
+ % So:
+ \let\endinput = \empty
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% For the aux and toc files, @ is the escape character. So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files). When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+ \def\@{@@}%
+ \def\ {@ }%
+ \let\{ = \lbraceatcmd
+ \let\} = \rbraceatcmd
+ %
+ % Do the redefinitions.
+ \commondummies
+ \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+ %
+ % \definedummyword defines \#1 as \string\#1\space, thus effectively
+ % preventing its expansion. This is used only for control words,
+ % not control letters, because the \space would be incorrect for
+ % control characters, but is needed to separate the control word
+ % from whatever follows.
+ %
+ % For control letters, we have \definedummyletter, which omits the
+ % space.
+ %
+ % These can be used both for control words that take an argument and
+ % those that do not. If it is followed by {arg} in the input, then
+ % that will dutifully get written to the index (or wherever).
+ %
+ \def\definedummyword ##1{\def##1{\string##1\space}}%
+ \def\definedummyletter##1{\def##1{\string##1}}%
+ \let\definedummyaccent\definedummyletter
+ %
+ \commondummiesnofonts
+ %
+ \definedummyletter\_%
+ \definedummyletter\-%
+ %
+ % Non-English letters.
+ \definedummyword\AA
+ \definedummyword\AE
+ \definedummyword\DH
+ \definedummyword\L
+ \definedummyword\O
+ \definedummyword\OE
+ \definedummyword\TH
+ \definedummyword\aa
+ \definedummyword\ae
+ \definedummyword\dh
+ \definedummyword\exclamdown
+ \definedummyword\l
+ \definedummyword\o
+ \definedummyword\oe
+ \definedummyword\ordf
+ \definedummyword\ordm
+ \definedummyword\questiondown
+ \definedummyword\ss
+ \definedummyword\th
+ %
+ % Although these internal commands shouldn't show up, sometimes they do.
+ \definedummyword\bf
+ \definedummyword\gtr
+ \definedummyword\hat
+ \definedummyword\less
+ \definedummyword\sf
+ \definedummyword\sl
+ \definedummyword\tclose
+ \definedummyword\tt
+ %
+ \definedummyword\LaTeX
+ \definedummyword\TeX
+ %
+ % Assorted special characters.
+ \definedummyword\arrow
+ \definedummyword\bullet
+ \definedummyword\comma
+ \definedummyword\copyright
+ \definedummyword\registeredsymbol
+ \definedummyword\dots
+ \definedummyword\enddots
+ \definedummyword\entrybreak
+ \definedummyword\equiv
+ \definedummyword\error
+ \definedummyword\euro
+ \definedummyword\expansion
+ \definedummyword\geq
+ \definedummyword\guillemetleft
+ \definedummyword\guillemetright
+ \definedummyword\guilsinglleft
+ \definedummyword\guilsinglright
+ \definedummyword\leq
+ \definedummyword\minus
+ \definedummyword\ogonek
+ \definedummyword\pounds
+ \definedummyword\point
+ \definedummyword\print
+ \definedummyword\quotedblbase
+ \definedummyword\quotedblleft
+ \definedummyword\quotedblright
+ \definedummyword\quoteleft
+ \definedummyword\quoteright
+ \definedummyword\quotesinglbase
+ \definedummyword\result
+ \definedummyword\textdegree
+ %
+ % We want to disable all macros so that they are not expanded by \write.
+ \macrolist
+ %
+ \normalturnoffactive
+ %
+ % Handle some cases of @value -- where it does not contain any
+ % (non-fully-expandable) commands.
+ \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter\!%
+ \definedummyaccent\"%
+ \definedummyaccent\'%
+ \definedummyletter\*%
+ \definedummyaccent\,%
+ \definedummyletter\.%
+ \definedummyletter\/%
+ \definedummyletter\:%
+ \definedummyaccent\=%
+ \definedummyletter\?%
+ \definedummyaccent\^%
+ \definedummyaccent\`%
+ \definedummyaccent\~%
+ \definedummyword\u
+ \definedummyword\v
+ \definedummyword\H
+ \definedummyword\dotaccent
+ \definedummyword\ogonek
+ \definedummyword\ringaccent
+ \definedummyword\tieaccent
+ \definedummyword\ubaraccent
+ \definedummyword\udotaccent
+ \definedummyword\dotless
+ %
+ % Texinfo font commands.
+ \definedummyword\b
+ \definedummyword\i
+ \definedummyword\r
+ \definedummyword\sansserif
+ \definedummyword\sc
+ \definedummyword\slanted
+ \definedummyword\t
+ %
+ % Commands that take arguments.
+ \definedummyword\acronym
+ \definedummyword\anchor
+ \definedummyword\cite
+ \definedummyword\code
+ \definedummyword\command
+ \definedummyword\dfn
+ \definedummyword\dmn
+ \definedummyword\email
+ \definedummyword\emph
+ \definedummyword\env
+ \definedummyword\file
+ \definedummyword\indicateurl
+ \definedummyword\kbd
+ \definedummyword\key
+ \definedummyword\math
+ \definedummyword\option
+ \definedummyword\pxref
+ \definedummyword\ref
+ \definedummyword\samp
+ \definedummyword\strong
+ \definedummyword\tie
+ \definedummyword\uref
+ \definedummyword\url
+ \definedummyword\var
+ \definedummyword\verb
+ \definedummyword\w
+ \definedummyword\xref
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names. It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+ % Accent commands should become @asis.
+ \def\definedummyaccent##1{\let##1\asis}%
+ % We can just ignore other control letters.
+ \def\definedummyletter##1{\let##1\empty}%
+ % All control words become @asis by default; overrides below.
+ \let\definedummyword\definedummyaccent
+ %
+ \commondummiesnofonts
+ %
+ % Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the active chars like <, >, |, etc.
+ % Likewise with the other plain tex font commands.
+ %\let\tt=\asis
+ %
+ \def\ { }%
+ \def\@{@}%
+ \def\_{\normalunderscore}%
+ \def\-{}% @- shouldn't affect sorting
+ %
+ % Unfortunately, texindex is not prepared to handle braces in the
+ % content at all. So for index sorting, we map @{ and @} to strings
+ % starting with |, since that ASCII character is between ASCII { and }.
+ \def\{{|a}%
+ \def\}{|b}%
+ %
+ % Non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\DH{DZZ}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\TH{ZZZ}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\dh{dzz}%
+ \def\exclamdown{!}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ \def\o{o}%
+ \def\questiondown{?}%
+ \def\ss{ss}%
+ \def\th{zzz}%
+ %
+ \def\LaTeX{LaTeX}%
+ \def\TeX{TeX}%
+ %
+ % Assorted special characters.
+ % (The following {} will end up in the sort string, but that's ok.)
+ \def\arrow{->}%
+ \def\bullet{bullet}%
+ \def\comma{,}%
+ \def\copyright{copyright}%
+ \def\dots{...}%
+ \def\enddots{...}%
+ \def\equiv{==}%
+ \def\error{error}%
+ \def\euro{euro}%
+ \def\expansion{==>}%
+ \def\geq{>=}%
+ \def\guillemetleft{<<}%
+ \def\guillemetright{>>}%
+ \def\guilsinglleft{<}%
+ \def\guilsinglright{>}%
+ \def\leq{<=}%
+ \def\minus{-}%
+ \def\point{.}%
+ \def\pounds{pounds}%
+ \def\print{-|}%
+ \def\quotedblbase{"}%
+ \def\quotedblleft{"}%
+ \def\quotedblright{"}%
+ \def\quoteleft{`}%
+ \def\quoteright{'}%
+ \def\quotesinglbase{,}%
+ \def\registeredsymbol{R}%
+ \def\result{=>}%
+ \def\textdegree{o}%
+ %
+ \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax
+ \else \indexlquoteignore \fi
+ %
+ % We need to get rid of all macros, leaving only the arguments (if present).
+ % Of course this is not nearly correct, but it is the best we can do for now.
+ % makeinfo does not expand macros in the argument to @deffn, which ends up
+ % writing an index entry, and texindex isn't prepared for an index sort entry
+ % that starts with \.
+ %
+ % Since macro invocations are followed by braces, we can just redefine them
+ % to take a single TeX argument. The case of a macro invocation that
+ % goes to end-of-line is not handled.
+ %
+ \macrolist
+}
+
+% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us
+% ignore left quotes in the sort term.
+{\catcode`\`=\active
+ \gdef\indexlquoteignore{\let`=\empty}}
+
+\let\indexbackslash=0 %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+ \iflinks
+ {%
+ % Store the main index entry text (including the third arg).
+ \toks0 = {#2}%
+ % If third arg is present, precede it with a space.
+ \def\thirdarg{#3}%
+ \ifx\thirdarg\empty \else
+ \toks0 = \expandafter{\the\toks0 \space #3}%
+ \fi
+ %
+ \edef\writeto{\csname#1indfile\endcsname}%
+ %
+ \safewhatsit\dosubindwrite
+ }%
+ \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+ \fi
+ %
+ % Remember, we are within a group.
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % Process the index entry with all font commands turned off, to
+ % get the string to sort by.
+ {\indexnofonts
+ \edef\temp{\the\toks0}% need full expansion
+ \xdef\indexsorttmp{\temp}%
+ }%
+ %
+ % Set up the complete index entry, with both the sort key and
+ % the original text, including any font commands. We write
+ % three arguments to \entry to the .?? file (four in the
+ % subentry case), texindex reduces to two when writing the .??s
+ % sorted result.
+ \edef\temp{%
+ \write\writeto{%
+ \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+ }%
+ \temp
+}
+
+% Take care of unwanted page breaks/skips around a whatsit:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again. Otherwise, the whatsit generated by the
+% \write or \pdfdest will make \lastskip zero. The result is that
+% sequences like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode. We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip. \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip. The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
+% ..., ready, GO:
+%
+\def\safewhatsit#1{\ifhmode
+ #1%
+ \else
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \whatsitskip = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \whatsitpenalty = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\whatsitskip glue we're inserting is preceded by a
+ % non-discardable item, therefore it is not a potential
+ % breakpoint, therefore no \nobreak needed.
+ \ifx\lastskipmacro\zeroskipmacro
+ \else
+ \vskip-\whatsitskip
+ \fi
+ %
+ #1%
+ %
+ \ifx\lastskipmacro\zeroskipmacro
+ % If \lastskip was zero, perhaps the last item was a penalty, and
+ % perhaps it was >=10000, e.g., a \nobreak. In that case, we want
+ % to re-insert the same penalty (values >10000 are used for various
+ % signals); since we just inserted a non-discardable item, any
+ % following glue (such as a \parskip) would be a breakpoint. For example:
+ % @deffn deffn-whatever
+ % @vindex index-whatever
+ % Description.
+ % would allow a break between the index-whatever whatsit
+ % and the "Description." paragraph.
+ \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
+ \else
+ % On the other hand, if we had a nonzero \lastskip,
+ % this make-up glue would be preceded by a non-discardable item
+ % (the whatsit from the \write), so we must insert a \nobreak.
+ \nobreak\vskip\whatsitskip
+ \fi
+\fi}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \smallfonts \rm
+ \tolerance = 9500
+ \plainfrenchspacing
+ \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+ %
+ % See if the index file exists and is nonempty.
+ % Change catcode of @ here so that if the index file contains
+ % \initial {@}
+ % as its first line, TeX doesn't complain about mismatched braces
+ % (because it thinks @} is a control sequence).
+ \catcode`\@ = 11
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ \putwordIndexNonexistent
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ \putwordIndexIsEmpty
+ \else
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \def\indexbackslash{\backslashcurfont}%
+ \catcode`\\ = 0
+ \escapechar = `\\
+ \begindoublecolumns
+ \input \jobname.#1s
+ \enddoublecolumns
+ \fi
+ \fi
+ \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+ % Some minor font changes for the special characters.
+ \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+ %
+ % Remove any glue we may have, we'll be inserting our own.
+ \removelastskip
+ %
+ % We like breaks before the index initials, so insert a bonus.
+ \nobreak
+ \vskip 0pt plus 3\baselineskip
+ \penalty 0
+ \vskip 0pt plus -3\baselineskip
+ %
+ % Typeset the initial. Making this add up to a whole number of
+ % baselineskips increases the chance of the dots lining up from column
+ % to column. It still won't often be perfect, because of the stretch
+ % we need before each entry, but it's better.
+ %
+ % No shrink because it confuses \balancecolumns.
+ \vskip 1.67\baselineskip plus .5\baselineskip
+ \leftline{\secbf #1}%
+ % Do our best not to break after the initial.
+ \nobreak
+ \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin. It is used for index
+% and table of contents entries. The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+% \def\entry#1#2{...
+% But this freezes the catcodes in the argument, and can cause problems to
+% @code, which sets - active. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+% The right solution is to prevent \entry from swallowing the whole text.
+% --kasal, 21nov03
+\def\entry{%
+ \begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent = 2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % A bit of stretch before each entry for the benefit of balancing
+ % columns.
+ \vskip 0pt plus1pt
+ %
+ % When reading the text of entry, convert explicit line breaks
+ % from @* into spaces. The user might give these in long section
+ % titles, for instance.
+ \def\*{\unskip\space\ignorespaces}%
+ \def\entrybreak{\hfil\break}%
+ %
+ % Swallow the left brace of the text (first parameter):
+ \afterassignment\doentry
+ \let\temp =
+}
+\def\entrybreak{\unskip\space\ignorespaces}%
+\def\doentry{%
+ \bgroup % Instead of the swallowed brace.
+ \noindent
+ \aftergroup\finishentry
+ % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+ % #1 is the page number.
+ %
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \setbox\boxA = \hbox{#1}%
+ \ifdim\wd\boxA = 0pt
+ \ %
+ \else
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ifpdf
+ \pdfgettoks#1.%
+ \ \the\toksA
+ \else
+ \ #1%
+ \fi
+ \fi
+ \par
+ \endgroup
+}
+
+% Like plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+ \parfillskip=0in
+ \parskip=0in
+ \hangindent=1in
+ \hangafter=1
+ \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+ \ifpdf
+ \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+ \else
+ #2
+ \fi
+ \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+ % Grab any single-column material above us.
+ \output = {%
+ %
+ % Here is a possibility not foreseen in manmac: if we accumulate a
+ % whole lot of material, we might end up calling this \output
+ % routine twice in a row (see the doublecol-lose test, which is
+ % essentially a couple of indexes with @setchapternewpage off). In
+ % that case we just ship out what is in \partialpage with the normal
+ % output routine. Generally, \partialpage will be empty when this
+ % runs and this will be a no-op. See the indexspread.tex test case.
+ \ifvoid\partialpage \else
+ \onepageout{\pagecontents\partialpage}%
+ \fi
+ %
+ \global\setbox\partialpage = \vbox{%
+ % Unvbox the main output page.
+ \unvbox\PAGE
+ \kern-\topskip \kern\baselineskip
+ }%
+ }%
+ \eject % run that output routine to set \partialpage
+ %
+ % Use the double-column output routine for subsequent pages.
+ \output = {\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it in one place.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +-<1pt)
+ % as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@ = \vsize
+ \divide\dimen@ by 2
+ \advance\dimen@ by -\ht\partialpage
+ %
+ % box0 will be the left-hand column, box2 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255
+ \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+ \unvbox\partialpage
+ %
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize
+ \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+ % The following penalty ensures that the page builder is exercised
+ % _before_ we change the output routine. This is necessary in the
+ % following situation:
+ %
+ % The last section of the index consists only of a single entry.
+ % Before this section, \pagetotal is less than \pagegoal, so no
+ % break occurs before the last section starts. However, the last
+ % section, consisting of \initial and the single \entry, does not
+ % fit on the page and has to be broken off. Without the following
+ % penalty the page builder will not be exercised until \eject
+ % below, and by that time we'll already have changed the output
+ % routine to the \balancecolumns version, so the next-to-last
+ % double-column page will be processed with \balancecolumns, which
+ % is wrong: The two columns will go to the main vertical list, with
+ % the broken-off section in the recent contributions. As soon as
+ % the output routine finishes, TeX starts reconsidering the page
+ % break. The two columns and the broken-off section both fit on the
+ % page, because the two columns now take up only half of the page
+ % goal. When TeX sees \eject from below which follows the final
+ % section, it invokes the new output routine that we've set after
+ % \balancecolumns below; \onepageout will try to fit the two columns
+ % and the final section into the vbox of \pageheight (see
+ % \pagebody), causing an overfull box.
+ %
+ % Note that glue won't work here, because glue does not exercise the
+ % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+ \penalty0
+ %
+ \output = {%
+ % Split the last of the double-column material. Leave it on the
+ % current page, no automatic page break.
+ \balancecolumns
+ %
+ % If we end up splitting too much material for the current page,
+ % though, there will be another page break right after this \output
+ % invocation ends. Having called \balancecolumns once, we do not
+ % want to call it again. Therefore, reset \output to its normal
+ % definition right away. (We hope \balancecolumns will never be
+ % called on to balance too much material, but if it is, this makes
+ % the output somewhat more palatable.)
+ \global\output = {\onepageout{\pagecontents\PAGE}}%
+ }%
+ \eject
+ \endgroup % started in \begindoublecolumns
+ %
+ % \pagegoal was set to the doubled \vsize above, since we restarted
+ % the current page. We're now back to normal single-column
+ % typesetting, so reset \pagegoal to the normal \vsize (after the
+ % \endgroup where \vsize got restored).
+ \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+ \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2 % target to split to
+ %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {%
+ \vbadness = 10000
+ \loop
+ \global\setbox3 = \copy0
+ \global\setbox1 = \vsplit3 to \dimen@
+ \ifdim\ht3>\dimen@
+ \global\advance\dimen@ by 1pt
+ \repeat
+ }%
+ %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ %
+ \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% Let's start with @part.
+\outer\parseargdef\part{\partzzz{#1}}
+\def\partzzz#1{%
+ \chapoddpage
+ \null
+ \vskip.3\vsize % move it down on the page a bit
+ \begingroup
+ \noindent \titlefonts\rmisbold #1\par % the text
+ \let\lastnode=\empty % no node to associate with
+ \writetocentry{part}{#1}{}% but put it in the toc
+ \headingsoff % no headline or footline on the part page
+ \chapoddpage
+ \endgroup
+}
+
+% \unnumberedno is an oxymoron. But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number". We avoid collisions with chapter
+% numbers by starting them at 10000. (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno \secno=0
+\newcount\subsecno \subsecno=0
+\newcount\subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+ \ifnum\appendixno=`A A%
+ \else\ifnum\appendixno=`B B%
+ \else\ifnum\appendixno=`C C%
+ \else\ifnum\appendixno=`D D%
+ \else\ifnum\appendixno=`E E%
+ \else\ifnum\appendixno=`F F%
+ \else\ifnum\appendixno=`G G%
+ \else\ifnum\appendixno=`H H%
+ \else\ifnum\appendixno=`I I%
+ \else\ifnum\appendixno=`J J%
+ \else\ifnum\appendixno=`K K%
+ \else\ifnum\appendixno=`L L%
+ \else\ifnum\appendixno=`M M%
+ \else\ifnum\appendixno=`N N%
+ \else\ifnum\appendixno=`O O%
+ \else\ifnum\appendixno=`P P%
+ \else\ifnum\appendixno=`Q Q%
+ \else\ifnum\appendixno=`R R%
+ \else\ifnum\appendixno=`S S%
+ \else\ifnum\appendixno=`T T%
+ \else\ifnum\appendixno=`U U%
+ \else\ifnum\appendixno=`V V%
+ \else\ifnum\appendixno=`W W%
+ \else\ifnum\appendixno=`X X%
+ \else\ifnum\appendixno=`Y Y%
+ \else\ifnum\appendixno=`Z Z%
+ % The \the is necessary, despite appearances, because \appendixletter is
+ % expanded while writing the .toc file. \char\appendixno is not
+ % expandable, thus it is written literally, thus all appendixes come out
+ % with the same letter (or @) in the toc without it.
+ \else\char\the\appendixno
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines these (using marks) as the number+name, number
+% and name of the chapter. Page headings and footings can use
+% these. @section does likewise.
+\def\thischapter{}
+\def\thischapternum{}
+\def\thischaptername{}
+\def\thissection{}
+\def\thissectionnum{}
+\def\thissectionname{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achieve this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unnlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+ % Compute the abs. sec. level:
+ \absseclevel=#2
+ \advance\absseclevel by \secbase
+ % Make sure \absseclevel doesn't fall outside the range:
+ \ifnum \absseclevel < 0
+ \absseclevel = 0
+ \else
+ \ifnum \absseclevel > 3
+ \absseclevel = 3
+ \fi
+ \fi
+ % The heading type:
+ \def\headtype{#1}%
+ \if \headtype U%
+ \ifnum \absseclevel < \unnlevel
+ \chardef\unnlevel = \absseclevel
+ \fi
+ \else
+ % Check for appendix sections:
+ \ifnum \absseclevel = 0
+ \edef\chapheadtype{\headtype}%
+ \else
+ \if \headtype A\if \chapheadtype N%
+ \errmessage{@appendix... within a non-appendix chapter}%
+ \fi\fi
+ \fi
+ % Check for numbered within unnumbered:
+ \ifnum \absseclevel > \unnlevel
+ \def\headtype{U}%
+ \else
+ \chardef\unnlevel = 3
+ \fi
+ \fi
+ % Now print the heading:
+ \if \headtype U%
+ \ifcase\absseclevel
+ \unnumberedzzz{#3}%
+ \or \unnumberedseczzz{#3}%
+ \or \unnumberedsubseczzz{#3}%
+ \or \unnumberedsubsubseczzz{#3}%
+ \fi
+ \else
+ \if \headtype A%
+ \ifcase\absseclevel
+ \appendixzzz{#3}%
+ \or \appendixsectionzzz{#3}%
+ \or \appendixsubseczzz{#3}%
+ \or \appendixsubsubseczzz{#3}%
+ \fi
+ \else
+ \ifcase\absseclevel
+ \chapterzzz{#3}%
+ \or \seczzz{#3}%
+ \or \numberedsubseczzz{#3}%
+ \or \numberedsubsubseczzz{#3}%
+ \fi
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered. Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v. By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+ % section resetting is \global in case the chapter is in a group, such
+ % as an @include file.
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\chapno by 1
+ %
+ % Used for \float.
+ \gdef\chaplevelprefix{\the\chapno.}%
+ \resetallfloatnos
+ %
+ % \putwordChapter can contain complex things in translations.
+ \toks0=\expandafter{\putwordChapter}%
+ \message{\the\toks0 \space \the\chapno}%
+ %
+ % Write the actual heading.
+ \chapmacro{#1}{Ynumbered}{\the\chapno}%
+ %
+ % So @section and the like are numbered underneath this chapter.
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz
+%
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \gdef\chaplevelprefix{\appendixletter.}%
+ \resetallfloatnos
+ %
+ % \putwordAppendix can contain complex things in translations.
+ \toks0=\expandafter{\putwordAppendix}%
+ \message{\the\toks0 \space \appendixletter}%
+ %
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ %
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+}
+
+% normally unnmhead0 calls unnumberedzzz:
+\outer\parseargdef\unnumbered{\unnmhead0{#1}}
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % Since an unnumbered has no number, no prefix for figures.
+ \global\let\chaplevelprefix = \empty
+ \resetallfloatnos
+ %
+ % This used to be simply \message{#1}, but TeX fully expands the
+ % argument to \message. Therefore, if #1 contained @-commands, TeX
+ % expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+ % expanded @cite (which turns out to cause errors because \cite is meant
+ % to be executed, not expanded).
+ %
+ % Anyway, we don't want the fully-expanded definition of @cite to appear
+ % as a result of the \message, we just want `@cite' itself. We use
+ % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+ % simply yielding the contents of <toks register>. (We also do this for
+ % the toc entries.)
+ \toks0 = {#1}%
+ \message{(\the\toks0)}%
+ %
+ \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+ %
+ \global\let\section = \unnumberedsec
+ \global\let\subsection = \unnumberedsubsec
+ \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+ % Well, we could do the following in a group, but that would break
+ % an assumption that \chapmacro is called at the outermost level.
+ % Thus we are safer this way: --kasal, 24feb04
+ \let\centerparametersmaybe = \centerparameters
+ \unnmhead0{#1}%
+ \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+%
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+% normally calls appendixsectionzzz:
+\outer\parseargdef\appendixsection{\apphead1{#1}}
+\def\appendixsectionzzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+% normally calls unnumberedseczzz:
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}}
+\def\unnumberedseczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+%
+% normally calls numberedsubseczzz:
+\outer\parseargdef\numberedsubsec{\numhead2{#1}}
+\def\numberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+% normally calls appendixsubseczzz:
+\outer\parseargdef\appendixsubsec{\apphead2{#1}}
+\def\appendixsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+% normally calls unnumberedsubseczzz:
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}}
+\def\unnumberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+%
+% normally numberedsubsubseczzz:
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}}
+\def\numberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynumbered}%
+ {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% normally appendixsubsubseczzz:
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}}
+\def\appendixsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% normally unnumberedsubsubseczzz:
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}}
+\def\unnumberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+% 1) We use \vbox rather than the earlier \line to permit
+% overlong headings to fold.
+% 2) \hyphenpenalty is set to 10000 because hyphenation in a
+% heading is obnoxious; this forbids it.
+% 3) Likewise, headings look best if no \parindent is used, and
+% if justification is not attempted. Hence \raggedright.
+
+\def\majorheading{%
+ {\advance\chapheadingskip by 10pt \chapbreak }%
+ \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+ {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\ptexraggedright
+ \rmisbold #1\hfill}}%
+ \bigskip \par\penalty 200\relax
+ \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+% Parameter controlling skip before chapter headings (if needed)
+\newskip\chapheadingskip
+
+% Define plain chapter starts, and page on/off switching for it.
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+% Because \domark is called before \chapoddpage, the filler page will
+% get the headings for the next chapter, which is wrong. But we don't
+% care -- we just disable all headings on the filler page.
+\def\chapoddpage{%
+ \chappager
+ \ifodd\pageno \else
+ \begingroup
+ \headingsoff
+ \null
+ \chappager
+ \endgroup
+ \fi
+}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+ % Insert the first mark before the heading break (see notes for \domark).
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
+ \gdef\thissection{}}%
+ %
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{\thischaptername}}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{}}%
+ \else\ifx\temptype\Yappendixkeyword
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\appendixletter}%
+ % \noexpand\putwordAppendix avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordAppendix{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \else
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\the\chapno}%
+ % \noexpand\putwordChapter avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordChapter{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \fi\fi\fi
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert the chapter heading break.
+ \pchapsepmacro
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ {%
+ \chapfonts \rmisbold
+ %
+ % Have to define \lastsection before calling \donoderef, because the
+ % xref code eventually uses it. On the other hand, it has to be called
+ % after \pchapsepmacro, or the headline will change too soon.
+ \gdef\lastsection{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \fi\fi\fi
+ %
+ % Write the toc entry for this chapter. Must come before the
+ % \donoderef, because we include the current node name in the toc
+ % entry, and \donoderef resets it to empty.
+ \writetocentry{\toctype}{#1}{#3}%
+ %
+ % For pdftex, we have to write out the node definition (aka, make
+ % the pdfdest) after any page break, but before the actual text has
+ % been typeset. If the destination for the pdf outline is after the
+ % text, then jumping from the outline may wind up with the text not
+ % being visible, for instance under high magnification.
+ \donoderef{#2}%
+ %
+ % Typeset the actual heading.
+ \nobreak % Avoid page breaks at the interline glue.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
+ \hangindent=\wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
+ }%
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff. We'll see. --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\ptexraggedright
+ \rmisbold #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt
+ \hfill {\rmisbold #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+ \global\let\chapmacro=\chfopen
+ \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles. These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\seckeyword{sec}
+%
+\def\sectionheading#1#2#3#4{%
+ {%
+ \checkenv{}% should not be in an environment.
+ %
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rmisbold
+ %
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ % Insert first mark before the heading break (see notes for \domark).
+ \let\prevsectiondefs=\lastsectiondefs
+ \ifx\temptype\Ynothingkeyword
+ \ifx\sectionlevel\seckeyword
+ \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
+ \gdef\thissection{\thissectionname}}%
+ \fi
+ \else\ifx\temptype\Yomitfromtockeyword
+ % Don't redefine \thissection.
+ \else\ifx\temptype\Yappendixkeyword
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \else
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \fi\fi\fi
+ %
+ % Go into vertical mode. Usually we'll already be there, but we
+ % don't want the following whatsit to end up in a preceding paragraph
+ % if the document didn't happen to have a blank line.
+ \par
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ % Only insert the space after the number if we have a section number.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\lastsection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \lastsection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\lastsection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\lastsection{#1}%
+ \fi\fi\fi
+ %
+ % Write the toc entry (before \donoderef). See comments in \chapmacro.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chapmacro.
+ \donoderef{#3}%
+ %
+ % Interline glue will be inserted when the vbox is completed.
+ % That glue will be a valid breakpoint for the page, since it'll be
+ % preceded by a whatsit (usually from the \donoderef, or from the
+ % \writetocentry if there was no node). We don't want to allow that
+ % break, since then the whatsits could end up on page n while the
+ % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000.
+ \nobreak
+ %
+ % Output the actual section heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
+ \hangindent=\wd0 % zero if no section number
+ \unhbox0 #1}%
+ }%
+ % Add extra space after the heading -- half of whatever came above it.
+ % Don't allow stretch, though.
+ \kern .5 \csname #2headingskip\endcsname
+ %
+ % Do not let the kern be a potential breakpoint, as it would be if it
+ % was followed by glue.
+ \nobreak
+ %
+ % We'll almost certainly start a paragraph next, so don't let that
+ % glue accumulate. (Not a breakpoint because it's preceded by a
+ % discardable item.) However, when a paragraph is not started next
+ % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out
+ % or the negative glue will cause weirdly wrong output, typically
+ % obscuring the section heading with something else.
+ \vskip-\parskip
+ %
+ % This is so the last item on the main vertical list is a known
+ % \penalty > 10000, so \startdefun, etc., can recognize the situation
+ % and do the needful.
+ \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this. The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything. This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+ \edef\writetoctype{#1}%
+ \ifx\writetoctype\omitkeyword \else
+ \iftocfileopened\else
+ \immediate\openout\tocfile = \jobname.toc
+ \global\tocfileopenedtrue
+ \fi
+ %
+ \iflinks
+ {\atdummies
+ \edef\temp{%
+ \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+ \temp
+ }%
+ \fi
+ \fi
+ %
+ % Tell \shipout to create a pdf destination on each page, if we're
+ % writing pdf. These are used in the table of contents. We can't
+ % just write one on every page because the title pages are numbered
+ % 1 and 2 (the page numbers aren't printed), and so are the first
+ % two pages of the document. Thus, we'd have two destinations named
+ % `1', and two named `2'.
+ \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care. This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+%
+\def\activecatcodes{%
+ \catcode`\"=\active
+ \catcode`\$=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
+ \catcode`\\=\active
+ \catcode`\^=\active
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+ \setupdatafile
+ \activecatcodes
+ \input \tocreadfilename
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout\tocfile
+ %
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+ %
+ % Roman numerals for page numbers.
+ \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+% redefined for the two-volume lispref. We always output on
+% \jobname.toc even if this is redefined.
+%
+\def\tocreadfilename{\jobname.toc}
+
+% Normal (long) toc.
+%
+\def\contents{%
+ \startcontents{\putwordTOC}%
+ \openin 1 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \ifeof 1 \else
+ \pdfmakeoutlines
+ \fi
+ \closein 1
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+ \startcontents{\putwordShortTOC}%
+ %
+ \let\partentry = \shortpartentry
+ \let\numchapentry = \shortchapentry
+ \let\appentry = \shortchapentry
+ \let\unnchapentry = \shortunnchapentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf
+ \let\sl=\shortcontsl \let\tt=\shortconttt
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\numsecentry##1##2##3##4{}
+ \let\appsecentry = \numsecentry
+ \let\unnsecentry = \numsecentry
+ \let\numsubsecentry = \numsecentry
+ \let\appsubsecentry = \numsecentry
+ \let\unnsubsecentry = \numsecentry
+ \let\numsubsubsecentry = \numsecentry
+ \let\appsubsubsecentry = \numsecentry
+ \let\unnsubsubsecentry = \numsecentry
+ \openin 1 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \closein 1
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+ % This space should be enough, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % But use \hss just in case.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ %
+ % We'd like to right-justify chapter numbers, but that looks strange
+ % with appendix letters. And right-justifying numbers and
+ % left-justifying letters looks strange when there is less than 10
+ % chapters. Have to read the whole toc once to know how many chapters
+ % there are before deciding ...
+ \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Parts, in the main contents. Replace the part number, which doesn't
+% exist, with an empty box. Let's hope all the numbers have the same width.
+% Also ignore the page number, which is conventionally not printed.
+\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}}
+\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}}
+%
+% Parts, in the short toc.
+\def\shortpartentry#1#2#3#4{%
+ \penalty-300
+ \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip
+ \shortchapentry{{\bf #1}}{\numeralbox}{}{}%
+}
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+ % We use M since it's probably the widest letter.
+ \setbox0 = \hbox{\putwordAppendix{} M}%
+ \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @tex ... @end tex escapes into raw TeX temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain @ character.
+
+\envdef\tex{%
+ \setupmarkupstyle{tex}%
+ \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+ \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+ \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+ \catcode `\%=14
+ \catcode `\+=\other
+ \catcode `\"=\other
+ \catcode `\|=\other
+ \catcode `\<=\other
+ \catcode `\>=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
+ \escapechar=`\\
+ %
+ % ' is active in math mode (mathcode"8000). So reset it, and all our
+ % other math active characters (just in case), to plain's definitions.
+ \mathactive
+ %
+ \let\b=\ptexb
+ \let\bullet=\ptexbullet
+ \let\c=\ptexc
+ \let\,=\ptexcomma
+ \let\.=\ptexdot
+ \let\dots=\ptexdots
+ \let\equiv=\ptexequiv
+ \let\!=\ptexexclam
+ \let\i=\ptexi
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \let\{=\ptexlbrace
+ \let\+=\tabalign
+ \let\}=\ptexrbrace
+ \let\/=\ptexslash
+ \let\*=\ptexstar
+ \let\t=\ptext
+ \expandafter \let\csname top\endcsname=\ptextop % outer
+ \let\frenchspacing=\plainfrenchspacing
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+ % =10000 instead of <10000 because of a special case in \itemzzz and
+ % \sectionheading, q.v.
+ \ifnum \lastpenalty=10000 \else
+ \advance\envskipamount by \parskip
+ \endgraf
+ \ifdim\lastskip<\envskipamount
+ \removelastskip
+ % it's not a good place to break if the last penalty was \nobreak
+ % or better ...
+ \ifnum\lastpenalty<10000 \penalty-50 \fi
+ \vskip\envskipamount
+ \fi
+ \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+ \ifhmode\par\fi % can't be in the midst of a paragraph.
+ \startsavinginserts
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt % we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ % side, and for 6pt waste from
+ % each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing = t%
+ %
+ % If this cartouche directly follows a sectioning command, we need the
+ % \parskip glue (backspaced over by default) or the cartouche can
+ % collide with the section heading.
+ \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi
+ %
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \kern3pt
+ \hsize=\cartinner
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+ \comment % For explanation, see the end of def\group.
+}
+\def\Ecartouche{%
+ \ifhmode\par\fi
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+ \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\newdimen\nonfillparindent
+\def\nonfillstart{%
+ \aboveenvbreak
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ % Turn off paragraph indentation but redefine \indent to emulate
+ % the normal \indent.
+ \nonfillparindent=\parindent
+ \parindent = 0pt
+ \let\indent\nonfillindent
+ %
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \let\exdent=\nofillexdent
+}
+
+\begingroup
+\obeyspaces
+% We want to swallow spaces (but not other tokens) after the fake
+% @indent in our nonfill-environments, where spaces are normally
+% active and set to @tie, resulting in them not being ignored after
+% @indent.
+\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}%
+\gdef\nonfillindentcheck{%
+\ifx\temp %
+\expandafter\nonfillindentgobble%
+\else%
+\leavevmode\nonfillindentbox%
+\fi%
+}%
+\endgroup
+\def\nonfillindentgobble#1{\nonfillindent}
+\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+% @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+ \ifx\SETdispenvsize\smallword
+ % end paragraph for sake of leading, in case document has no blank
+ % line. This is redundant with what happens in \aboveenvbreak, but
+ % we need to do it before changing the fonts, and it's inconvenient
+ % to change the fonts afterward.
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+\def\setsmalldispenv{%
+ \ifx\SETdispenvsize\nosmallword
+ \else
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it in one command. #1 is the env name, #2 the definition.
+\def\makedispenvdef#1#2{%
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}%
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}%
+ \expandafter\let\csname E#1\endcsname \afterenvbreak
+ \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two environment synonyms (#1 and #2) for an environment.
+\def\maketwodispenvdef#1#2#3{%
+ \makedispenvdef{#1}{#3}%
+ \makedispenvdef{#2}{#3}%
+}
+%
+% @lisp: indented, narrowed, typewriter font;
+% @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvdef{lisp}{example}{%
+ \nonfillstart
+ \tt\setupmarkupstyle{example}%
+ \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+ \gobble % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenvdef{display}{%
+ \nonfillstart
+ \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenvdef{format}{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \advance\leftskip by 0pt plus 1fill\relax
+ \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @raggedright does more-or-less normal line breaking but no right
+% justification. From plain.tex.
+\envdef\raggedright{%
+ \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax
+}
+\let\Eraggedright\par
+
+\envdef\raggedleft{%
+ \parindent=0pt \leftskip0pt plus2em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedleft\par
+
+\envdef\raggedcenter{%
+ \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedcenter\par
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins. We keep \parskip nonzero in general, since
+% we're doing normal filling. So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\makedispenvdef{quotation}{\quotationstart}
+%
+\def\quotationstart{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \advance\rightskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+ \par
+ \ifx\quotationauthor\thisisundefined\else
+ % indent a bit.
+ \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+ \fi
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallquotation{\Equotation}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty \else
+ {\bf #1: }%
+ \fi
+}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too. Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+ \do\ \do\\\do\{\do\}\do\$\do\&%
+ \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+ \do\<\do\>\do\|\do\@\do+\do\"%
+ % Don't do the quotes -- if we do, @set txicodequoteundirected and
+ % @set txicodequotebacktick will not have effect on @verb and
+ % @verbatim, and ?` and !` ligatures won't get disabled.
+ %\do\`\do\'%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+ \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+ \tt % easiest (and conventionally used) font for verbatim
+ \def\par{\leavevmode\endgraf}%
+ \setupmarkupstyle{verb}%
+ \tabeightspaces
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion.
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+% We typeset each line of the verbatim in an \hbox, so we can handle
+% tabs. The \global is in case the verbatim line starts with an accent,
+% or some other command that starts with a begin-group. Otherwise, the
+% entire \verbbox would disappear at the corresponding end-group, before
+% it is typeset. Meanwhile, we can't have nested verbatim commands
+% (can we?), so the \global won't be overwriting itself.
+\newbox\verbbox
+\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup}
+%
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabexpand{%
+ \catcode`\^^I=\active
+ \def^^I{\leavevmode\egroup
+ \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab
+ \divide\dimen\verbbox by\tabw
+ \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw
+ \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw
+ \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox
+ }%
+ }
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \tt % easiest (and conventionally used) font for verbatim
+ % The \leavevmode here is for blank lines. Otherwise, we would
+ % never \starttabox and the \egroup would end verbatim mode.
+ \def\par{\leavevmode\egroup\box\verbbox\endgraf}%
+ \tabexpand
+ \setupmarkupstyle{verbatim}%
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count.
+ % Must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+ \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters. Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+% \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+ \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+ \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+% \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+ \catcode`\ =\active
+ \obeylines %
+ % ignore everything up to the first ^^M, that's the newline at the end
+ % of the @verbatim input line itself. Otherwise we get an extra blank
+ % line in the output.
+ \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+ % We really want {...\end verbatim} in the body of the macro, but
+ % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+ \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+ {%
+ \makevalueexpandable
+ \setupverbatim
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}%
+ \input #1
+ \afterenvbreak
+ }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+ \begingroup
+ \parindent = 0pt % paragraph indentation looks wrong on title page
+ \scanexp\copyingtext
+ \endgroup
+}
+
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
+
+% Start the processing of @deffn:
+\def\startdefun{%
+ \ifnum\lastpenalty<10000
+ \medbreak
+ \defunpenalty=10003 % Will keep this @deffn together with the
+ % following @def command, see below.
+ \else
+ % If there are two @def commands in a row, we'll have a \nobreak,
+ % which is there to keep the function description together with its
+ % header. But if there's nothing but headers, we need to allow a
+ % break somewhere. Check specifically for penalty 10002, inserted
+ % by \printdefunline, instead of 10000, since the sectioning
+ % commands also insert a nobreak penalty, and we don't want to allow
+ % a break between a section heading and a defun.
+ %
+ % As a further refinement, we avoid "club" headers by signalling
+ % with penalty of 10003 after the very first @deffn in the
+ % sequence (see above), and penalty of 10002 after any following
+ % @def command.
+ \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
+ %
+ % Similarly, after a section heading, do not allow a break.
+ % But do insert the glue.
+ \medskip % preceded by discardable penalty, so not a breakpoint
+ \fi
+ %
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+ % First, check whether we are in the right environment:
+ \checkenv#1%
+ %
+ % As above, allow line break if we have multiple x headers in a row.
+ % It's not a great place, though.
+ \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
+ %
+ % And now, it's time to reuse the body of the original defun:
+ \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+ \begingroup
+ % call \deffnheader:
+ #1#2 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil\relax
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty\defunpenalty % signal to \startdefun and \dodefunx
+ % Some of the @defun-type tags do not enable magic parentheses,
+ % rendering the following check redundant. But we don't optimize.
+ \checkparencounts
+ \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remaining is to define \deffnheader.
+%
+\def\makedefun#1{%
+ \expandafter\let\csname E#1\endcsname = \Edefun
+ \edef\temp{\noexpand\domakedefun
+ \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+ \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+ \envdef#1{%
+ \startdefun
+ \doingtypefnfalse % distinguish typed functions from all else
+ \parseargusing\activeparens{\printdefunline#3}%
+ }%
+ \def#2{\dodefunx#1}%
+ \def#3%
+}
+
+\newif\ifdoingtypefn % doing typed function?
+\newif\ifrettypeownline % typeset return type on its own line?
+
+% @deftypefnnewline on|off says whether the return type of typed functions
+% are printed on their own line. This affects @deftypefn, @deftypefun,
+% @deftypeop, and @deftypemethod.
+%
+\parseargdef\deftypefnnewline{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @txideftypefnnl value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+ % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{fn}{\code{#4}}{#1}%
+ \doingtypefntrue
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{vr}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+% Types:
+
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+ \par
+ % Get the values of \leftskip and \rightskip as they were outside the @def...
+ \advance\leftskip by -\defbodyindent
+ %
+ % Determine if we are typesetting the return type of a typed function
+ % on a line by itself.
+ \rettypeownlinefalse
+ \ifdoingtypefn % doing a typed function specifically?
+ % then check user option for putting return type on its own line:
+ \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else
+ \rettypeownlinetrue
+ \fi
+ \fi
+ %
+ % How we'll format the category name. Putting it in brackets helps
+ % distinguish it from the body text that may end up on the next line
+ % just below it.
+ \def\temp{#1}%
+ \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+ %
+ % Figure out line sizes for the paragraph shape. We'll always have at
+ % least two.
+ \tempnum = 2
+ %
+ % The first line needs space for \box0; but if \rightskip is nonzero,
+ % we need only space for the part of \box0 which exceeds it:
+ \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ %
+ % If doing a return type on its own line, we'll have another line.
+ \ifrettypeownline
+ \advance\tempnum by 1
+ \def\maybeshapeline{0in \hsize}%
+ \else
+ \def\maybeshapeline{}%
+ \fi
+ %
+ % The continuations:
+ \dimen2=\hsize \advance\dimen2 by -\defargsindent
+ %
+ % The final paragraph shape:
+ \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2
+ %
+ % Put the category name at the right margin.
+ \noindent
+ \hbox to 0pt{%
+ \hfil\box0 \kern-\hsize
+ % \hsize has to be shortened this way:
+ \kern\leftskip
+ % Intentionally do not respect \rightskip, since we need the space.
+ }%
+ %
+ % Allow all lines to be underfull without complaint:
+ \tolerance=10000 \hbadness=10000
+ \exdentamount=\defbodyindent
+ {%
+ % defun fonts. We use typewriter by default (used to be bold) because:
+ % . we're printing identifiers, they should be in tt in principle.
+ % . in languages with many accents, such as Czech or French, it's
+ % common to leave accents off identifiers. The result looks ok in
+ % tt, but exceedingly strange in rm.
+ % . we don't want -- and --- to be treated as ligatures.
+ % . this still does not fix the ?` and !` ligatures, but so far no
+ % one has made identifiers using them :).
+ \df \tt
+ \def\temp{#2}% text of the return type
+ \ifx\temp\empty\else
+ \tclose{\temp}% typeset the return type
+ \ifrettypeownline
+ % put return type on its own line; prohibit line break following:
+ \hfil\vadjust{\nobreak}\break
+ \else
+ \space % type on same line, so just followed by a space
+ \fi
+ \fi % no return type
+ #3% output function name
+ }%
+ {\rm\enskip}% hskip 0.5 em of \tenrm
+ %
+ \boldbrax
+ % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name. This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable. Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+ % use sl by default (not ttsl),
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ %
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. Let's try @var for that.
+ \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
+ #1%
+ \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
+
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
+}
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
+}
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
+}
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+% these should not use \errmessage; the glibc manual, at least, actually
+% has such constructs (when documenting function pointers).
+\def\badparencount{%
+ \message{Warning: unbalanced parentheses in @def...}%
+ \global\parencount=0
+}
+\def\badbrackcount{%
+ \message{Warning: unbalanced square brackets in @def...}%
+ \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\thisisundefined
+ \newwrite\macscribble
+ \def\scantokens#1{%
+ \toks0={#1}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \input \jobname.tmp
+ }
+\fi
+
+\def\scanmacro#1{\begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ %
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ %
+ % ... and for \example:
+ \spaceisspace
+ %
+ % The \empty here causes a following catcode 5 newline to be eaten as
+ % part of reading whitespace after a control sequence. It does not
+ % eat a catcode 13 newline. There's no good way to handle the two
+ % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX
+ % would then have different behavior). See the Macro Details node in
+ % the manual for the workaround we recommend for macros and
+ % line-oriented commands.
+ %
+ \scantokens{#1\empty}%
+\endgroup}
+
+\def\scanexp#1{%
+ \edef\temp{\noexpand\scanmacro{#1}}%
+ \temp
+}
+
+\newcount\paramno % Count of parameters
+\newtoks\macname % Macro name
+\newif\ifrecursive % Is it recursive?
+
+% List of all defined macros in the form
+% \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+ \toks0 = \expandafter{\macrolist\definedummyword#1}%
+ \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+% \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+%
+\def\cslet#1#2{%
+ \expandafter\let
+ \csname#1\expandafter\endcsname
+ \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \
+% to recognize macro arguments; this is the job of \mbodybackslash.
+%
+% Non-ASCII encodings make 8-bit characters active, so un-activate
+% them to avoid their expansion. Must do this non-globally, to
+% confine the change to the current group.
+%
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+%
+\def\scanctxt{% used as subroutine
+ \catcode`\"=\other
+ \catcode`\+=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\~=\other
+ \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
+}
+
+\def\scanargctxt{% used for copying and captions, not macros.
+ \scanctxt
+ \catcode`\\=\other
+ \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{% used for @macro definitions
+ \scanctxt
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\^^M=\other
+ \usembodybackslash
+}
+
+\def\macroargctxt{% used when scanning invocations
+ \scanctxt
+ \catcode`\\=0
+}
+% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes"
+% for the single characters \ { }. Thus, we end up with the "commands"
+% that would be written @\ @{ @} in a Texinfo document.
+%
+% We already have @{ and @}. For @\, we define it here, and only for
+% this purpose, to produce a typewriter backslash (so, the @\ that we
+% define for @math can't be used with @macro calls):
+%
+\def\\{\normalbackslash}%
+%
+% We would like to do this for \, too, since that is what makeinfo does.
+% But it is not possible, because Texinfo already has a command @, for a
+% cedilla accent. Documents must use @comma{} instead.
+%
+% \anythingelse will almost certainly be an error of some kind.
+
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+%
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\margbackslash#1{\char`\#1 }
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+ \getargs{#1}% now \macname is the macname and \argl the arglist
+ \ifx\argl\empty % no arguments
+ \paramno=0\relax
+ \else
+ \expandafter\parsemargdef \argl;%
+ \if\paramno>256\relax
+ \ifx\eTeXversion\thisisundefined
+ \errhelp = \EMsimple
+ \errmessage{You need eTeX to compile a file with macros with more than 256 arguments}
+ \fi
+ \fi
+ \fi
+ \if1\csname ismacro.\the\macname\endcsname
+ \message{Warning: redefining \the\macname}%
+ \else
+ \expandafter\ifx\csname \the\macname\endcsname \relax
+ \else \errmessage{Macro name \the\macname\space already defined}\fi
+ \global\cslet{macsave.\the\macname}{\the\macname}%
+ \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+ \addtomacrolist{\the\macname}%
+ \fi
+ \begingroup \macrobodyctxt
+ \ifrecursive \expandafter\parsermacbody
+ \else \expandafter\parsemacbody
+ \fi}
+
+\parseargdef\unmacro{%
+ \if1\csname ismacro.#1\endcsname
+ \global\cslet{#1}{macsave.#1}%
+ \global\expandafter\let \csname ismacro.#1\endcsname=0%
+ % Remove the macro name from \macrolist:
+ \begingroup
+ \expandafter\let\csname#1\endcsname \relax
+ \let\definedummyword\unmacrodo
+ \xdef\macrolist{\macrolist}%
+ \endgroup
+ \else
+ \errmessage{Macro #1 not defined}%
+ \fi
+}
+
+% Called by \do from \dounmacro on each macro. The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+ \ifx #1\relax
+ % remove this
+ \else
+ \noexpand\definedummyword \noexpand#1%
+ \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname#1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% For macro processing make @ a letter so that we can make Texinfo private macro names.
+\edef\texiatcatcode{\the\catcode`\@}
+\catcode `@=11\relax
+
+% Parse the optional {params} list. Set up \paramno and \paramlist
+% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH
+% in the params list to some hook where the argument si to be expanded. If
+% there are less than 10 arguments that hook is to be replaced by ##N where N
+% is the position in that list, that is to say the macro arguments are to be
+% defined `a la TeX in the macro body.
+%
+% That gets used by \mbodybackslash (above).
+%
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX: let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+%
+% If there are 10 or more arguments, a different technique is used, where the
+% hook remains in the body, and when macro is to be expanded the body is
+% processed again to replace the arguments.
+%
+% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the
+% argument N value and then \edef the body (nothing else will expand because of
+% the catcode regime underwhich the body was input).
+%
+% If you compile with TeX (not eTeX), and you have macros with 10 or more
+% arguments, you need that no macro has more than 256 arguments, otherwise an
+% error is produced.
+\def\parsemargdef#1;{%
+ \paramno=0\def\paramlist{}%
+ \let\hash\relax
+ \let\xeatspaces\relax
+ \parsemargdefxxx#1,;,%
+ % In case that there are 10 or more arguments we parse again the arguments
+ % list to set new definitions for the \macarg.BLAH macros corresponding to
+ % each BLAH argument. It was anyhow needed to parse already once this list
+ % in order to count the arguments, and as macros with at most 9 arguments
+ % are by far more frequent than macro with 10 or more arguments, defining
+ % twice the \macarg.BLAH macros does not cost too much processing power.
+ \ifnum\paramno<10\relax\else
+ \paramno0\relax
+ \parsemmanyargdef@@#1,;,% 10 or more arguments
+ \fi
+}
+\def\parsemargdefxxx#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\parsemargdefxxx
+ \advance\paramno by 1
+ \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+ {\xeatspaces{\hash\the\paramno}}%
+ \edef\paramlist{\paramlist\hash\the\paramno,}%
+ \fi\next}
+
+\def\parsemmanyargdef@@#1,{%
+ \if#1;\let\next=\relax
+ \else
+ \let\next=\parsemmanyargdef@@
+ \edef\tempb{\eatspaces{#1}}%
+ \expandafter\def\expandafter\tempa
+ \expandafter{\csname macarg.\tempb\endcsname}%
+ % Note that we need some extra \noexpand\noexpand, this is because we
+ % don't want \the to be expanded in the \parsermacbody as it uses an
+ % \xdef .
+ \expandafter\edef\tempa
+ {\noexpand\noexpand\noexpand\the\toks\the\paramno}%
+ \advance\paramno by 1\relax
+ \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+%
+
+\catcode `\@\texiatcatcode
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\catcode `\@=11\relax
+
+\let\endargs@\relax
+\let\nil@\relax
+\def\nilm@{\nil@}%
+\long\def\nillm@{\nil@}%
+
+% This macro is expanded during the Texinfo macro expansion, not during its
+% definition. It gets all the arguments values and assigns them to macros
+% macarg.ARGNAME
+%
+% #1 is the macro name
+% #2 is the list of argument names
+% #3 is the list of argument values
+\def\getargvals@#1#2#3{%
+ \def\macargdeflist@{}%
+ \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion.
+ \def\paramlist{#2,\nil@}%
+ \def\macroname{#1}%
+ \begingroup
+ \macroargctxt
+ \def\argvaluelist{#3,\nil@}%
+ \def\@tempa{#3}%
+ \ifx\@tempa\empty
+ \setemptyargvalues@
+ \else
+ \getargvals@@
+ \fi
+}
+
+%
+\def\getargvals@@{%
+ \ifx\paramlist\nilm@
+ % Some sanity check needed here that \argvaluelist is also empty.
+ \ifx\argvaluelist\nillm@
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Too many arguments in macro `\macroname'!}%
+ \fi
+ \let\next\macargexpandinbody@
+ \else
+ \ifx\argvaluelist\nillm@
+ % No more arguments values passed to macro. Set remaining named-arg
+ % macros to empty.
+ \let\next\setemptyargvalues@
+ \else
+ % pop current arg name into \@tempb
+ \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\paramlist}%
+ % pop current argument value into \@tempc
+ \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\argvaluelist}%
+ % Here \@tempb is the current arg name and \@tempc is the current arg value.
+ % First place the new argument macro definition into \@tempd
+ \expandafter\macname\expandafter{\@tempc}%
+ \expandafter\let\csname macarg.\@tempb\endcsname\relax
+ \expandafter\def\expandafter\@tempe\expandafter{%
+ \csname macarg.\@tempb\endcsname}%
+ \edef\@tempd{\long\def\@tempe{\the\macname}}%
+ \push@\@tempd\macargdeflist@
+ \let\next\getargvals@@
+ \fi
+ \fi
+ \next
+}
+
+\def\push@#1#2{%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter#2%
+ \expandafter\expandafter\expandafter{%
+ \expandafter#1#2}%
+}
+
+% Replace arguments by their values in the macro body, and place the result
+% in macro \@tempa
+\def\macvalstoargs@{%
+ % To do this we use the property that token registers that are \the'ed
+ % within an \edef expand only once. So we are going to place all argument
+ % values into respective token registers.
+ %
+ % First we save the token context, and initialize argument numbering.
+ \begingroup
+ \paramno0\relax
+ % Then, for each argument number #N, we place the corresponding argument
+ % value into a new token list register \toks#N
+ \expandafter\putargsintokens@\saveparamlist@,;,%
+ % Then, we expand the body so that argument are replaced by their
+ % values. The trick for values not to be expanded themselves is that they
+ % are within tokens and that tokens expand only once in an \edef .
+ \edef\@tempc{\csname mac.\macroname .body\endcsname}%
+ % Now we restore the token stack pointer to free the token list registers
+ % which we have used, but we make sure that expanded body is saved after
+ % group.
+ \expandafter
+ \endgroup
+ \expandafter\def\expandafter\@tempa\expandafter{\@tempc}%
+ }
+
+\def\macargexpandinbody@{%
+ %% Define the named-macro outside of this group and then close this group.
+ \expandafter
+ \endgroup
+ \macargdeflist@
+ % First the replace in body the macro arguments by their values, the result
+ % is in \@tempa .
+ \macvalstoargs@
+ % Then we point at the \norecurse or \gobble (for recursive) macro value
+ % with \@tempb .
+ \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname
+ % Depending on whether it is recursive or not, we need some tailing
+ % \egroup .
+ \ifx\@tempb\gobble
+ \let\@tempc\relax
+ \else
+ \let\@tempc\egroup
+ \fi
+ % And now we do the real job:
+ \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}%
+ \@tempd
+}
+
+\def\putargsintokens@#1,{%
+ \if#1;\let\next\relax
+ \else
+ \let\next\putargsintokens@
+ % First we allocate the new token list register, and give it a temporary
+ % alias \@tempb .
+ \toksdef\@tempb\the\paramno
+ % Then we place the argument value into that token list register.
+ \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname
+ \expandafter\@tempb\expandafter{\@tempa}%
+ \advance\paramno by 1\relax
+ \fi
+ \next
+}
+
+% Save the token stack pointer into macro #1
+\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}}
+% Restore the token stack pointer from number in macro #1
+\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax}
+% newtoks that can be used non \outer .
+\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi}
+
+% Tailing missing arguments are set to empty
+\def\setemptyargvalues@{%
+ \ifx\paramlist\nilm@
+ \let\next\macargexpandinbody@
+ \else
+ \expandafter\setemptyargvaluesparser@\paramlist\endargs@
+ \let\next\setemptyargvalues@
+ \fi
+ \next
+}
+
+\def\setemptyargvaluesparser@#1,#2\endargs@{%
+ \expandafter\def\expandafter\@tempa\expandafter{%
+ \expandafter\def\csname macarg.#1\endcsname{}}%
+ \push@\@tempa\macargdeflist@
+ \def\paramlist{#2}%
+}
+
+% #1 is the element target macro
+% #2 is the list macro
+% #3,#4\endargs@ is the list value
+\def\pop@#1#2#3,#4\endargs@{%
+ \def#1{#3}%
+ \def#2{#4}%
+}
+\long\def\longpop@#1#2#3,#4\endargs@{%
+ \long\def#1{#3}%
+ \long\def#2{#4}%
+}
+
+% This defines a Texinfo @macro. There are eight cases: recursive and
+% nonrecursive macros of zero, one, up to nine, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+%
+\def\defmacro{%
+ \let\hash=##% convert placeholders to macro parameter chars
+ \ifrecursive
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\scanmacro{\temp}}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup\noexpand\scanmacro{\temp}}%
+ \else
+ \ifnum\paramno<10\relax % at most 9
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \else % 10 or more
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble
+ \fi
+ \fi
+ \else
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % at most 9
+ \ifnum\paramno<10\relax
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % 10 or more:
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse
+ \fi
+ \fi
+ \fi}
+
+\catcode `\@\texiatcatcode\relax
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {. If so it reads up to the closing }, if not, it reads the whole
+% line. Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg).
+%
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+ \ifx\nchar\bgroup\else
+ \expandafter\parsearg
+ \fi \macnamexxx}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign. Make them active and then expand them all to nothing.
+%
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+ {%
+ \expandafter\let\obeyedspace=\empty
+ \addtomacrolist{#1}%
+ \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+ }%
+ \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{%
+ \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references. The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross, , , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node. #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+ \ifx\lastnode\empty\else
+ \setref{\lastnode}{#1}%
+ \global\let\lastnode=\empty
+ \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \lastsection,
+% or the anchor name.
+% 2) NAME-snt - section number and type, passed as the SNT arg, or
+% empty for anchors.
+% 3) NAME-pg - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat. In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+ \pdfmkdest{#1}%
+ \iflinks
+ {%
+ \atdummies % preserve commands, but don't expand them
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\lastsection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout
+ }%
+ \fi
+}
+
+% @xrefautosectiontitle on|off says whether @section(ing) names are used
+% automatically in xrefs, if the third arg is not explicitly specified.
+% This was provided as a "secret" @set xref-automatic-section-title
+% variable, now it's official.
+%
+\parseargdef\xrefautomaticsectiontitle{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @xrefautomaticsectiontitle value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+
+% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual. All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+%
+\newbox\topbox
+\newbox\printedrefnamebox
+\newbox\printedmanualbox
+%
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \unsepspaces
+ %
+ \def\printedrefname{\ignorespaces #3}%
+ \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
+ %
+ \def\printedmanual{\ignorespaces #5}%
+ \setbox\printedmanualbox = \hbox{\printedmanual\unskip}%
+ %
+ % If the printed reference name (arg #3) was not explicitly given in
+ % the @xref, figure out what we want to use.
+ \ifdim \wd\printedrefnamebox = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax
+ % Not auto section-title: use node name inside the square brackets.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ % Auto section-title: use chapter/section title inside
+ % the square brackets if we have it.
+ \ifdim \wd\printedmanualbox > 0pt
+ % It is in another manual, so we don't have it; use node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We (should) know the real title if we have the xref values.
+ \def\printedrefname{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % Make link in pdf output.
+ \ifpdf
+ {\indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ % This expands tokens, so do it after making catcode changes, so _
+ % etc. don't get their TeX definitions.
+ \getfilename{#4}%
+ %
+ \edef\pdfxrefdest{#1}%
+ \txiescapepdf\pdfxrefdest
+ %
+ \leavevmode
+ \startlink attr{/Border [0 0 0]}%
+ \ifnum\filenamelength>0
+ goto file{\the\filename.pdf} name{\pdfxrefdest}%
+ \else
+ goto name{\pdfmkpgn{\pdfxrefdest}}%
+ \fi
+ }%
+ \setcolor{\linkcolor}%
+ \fi
+ %
+ % Float references are printed completely differently: "Figure 1.2"
+ % instead of "[somenode], p.3". We distinguish them by the
+ % LABEL-title being set to a magic string.
+ {%
+ % Have to otherify everything special to allow the \csname to
+ % include an _ in the xref name, etc.
+ \indexnofonts
+ \turnoffactive
+ \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+ \csname XR#1-title\endcsname
+ }%
+ \iffloat\Xthisreftitle
+ % If the user specified the print name (third arg) to the ref,
+ % print it instead of our usual "Figure 1.2".
+ \ifdim\wd\printedrefnamebox = 0pt
+ \refx{#1-snt}{}%
+ \else
+ \printedrefname
+ \fi
+ %
+ % if the user also gave the printed manual name (fifth arg), append
+ % "in MANUALNAME".
+ \ifdim \wd\printedmanualbox > 0pt
+ \space \putwordin{} \cite{\printedmanual}%
+ \fi
+ \else
+ % node/anchor (non-float) references.
+ %
+ % If we use \unhbox to print the node names, TeX does not insert
+ % empty discretionaries after hyphens, which means that it will not
+ % find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens,
+ % this is a loss. Therefore, we give the text of the node name
+ % again, so it is as if TeX is seeing it for the first time.
+ %
+ % Cross-manual reference. Only include the "Section ``foo'' in" if
+ % the foo is neither missing or Top. Thus, @xref{,,,foo,The Foo Manual}
+ % outputs simply "see The Foo Manual".
+ \ifdim \wd\printedmanualbox > 0pt
+ % What is the 7sp about? The idea is that we also want to omit
+ % the Section part if we would be printing "Top", since they are
+ % clearly trying to refer to the whole manual. But, this being
+ % TeX, we can't easily compare strings while ignoring the possible
+ % spaces before and after in the input. By adding the arbitrary
+ % 7sp, we make it much less likely that a real node name would
+ % happen to have the same width as "Top" (e.g., in a monospaced font).
+ % I hope it will never happen in practice.
+ %
+ % For the same basic reason, we retypeset the "Top" at every
+ % reference, since the current font is indeterminate.
+ %
+ \setbox\topbox = \hbox{Top\kern7sp}%
+ \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
+ \ifdim \wd2 > 7sp
+ \ifdim \wd2 = \wd\topbox \else
+ \putwordSection{} ``\printedrefname'' \putwordin{}\space
+ \fi
+ \fi
+ \cite{\printedmanual}%
+ \else
+ % Reference in this manual.
+ %
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive
+ % Only output a following space if the -snt ref is nonempty; for
+ % @unnumbered and @anchor, it won't be.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+ }%
+ % output the `[mynode]' via the macro below so it can be overridden.
+ \xrefprintnodename\printedrefname
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output. It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents. Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+ \ifnum\secno=0
+ \putwordChapter@tie \the\chapno
+ \else \ifnum\subsecno=0
+ \putwordSection@tie \the\chapno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+\def\Yappendix{%
+ \ifnum\secno=0
+ \putwordAppendix@tie @char\the\appendixno{}%
+ \else \ifnum\subsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie
+ @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+ {%
+ \indexnofonts
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\thisrefX
+ \csname XR#1\endcsname
+ }%
+ \ifx\thisrefX\relax
+ % If not defined, say something at least.
+ \angleleft un\-de\-fined\angleright
+ \iflinks
+ \ifhavexrefs
+ {\toks0 = {#1}% avoid expansion of possibly-complex value
+ \message{\linenumber Undefined cross reference `\the\toks0'.}}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \thisrefX
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file. Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions). But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+ {% The node name might contain 8-bit characters, which in our current
+ % implementation are changed to commands like @'e. Don't let these
+ % mess up the control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safexrefname{#1}%
+ }%
+ %
+ \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
+ %
+ % Was that xref control sequence that we just defined for a float?
+ \expandafter\iffloat\csname XR\safexrefname\endcsname
+ % it was a float, and we have the (safe) float type in \iffloattype.
+ \expandafter\let\expandafter\floatlist
+ \csname floatlist\iffloattype\endcsname
+ %
+ % Is this the first time we've seen this float type?
+ \expandafter\ifx\floatlist\relax
+ \toks0 = {\do}% yes, so just \do
+ \else
+ % had it before, so preserve previous elements in list.
+ \toks0 = \expandafter{\floatlist\do}%
+ \fi
+ %
+ % Remember this xref in the control sequence \floatlistFLOATTYPE,
+ % for later use in \listoffloats.
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+ {\safexrefname}}%
+ \fi
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+%
+\def\tryauxfile{%
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \readdatafile{aux}%
+ \global\havexrefstrue
+ \fi
+ \closein 1
+}
+
+\def\setupdatafile{%
+ \catcode`\^^@=\other
+ \catcode`\^^A=\other
+ \catcode`\^^B=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\^^K=\other
+ \catcode`\^^L=\other
+ \catcode`\^^N=\other
+ \catcode`\^^P=\other
+ \catcode`\^^Q=\other
+ \catcode`\^^R=\other
+ \catcode`\^^S=\other
+ \catcode`\^^T=\other
+ \catcode`\^^U=\other
+ \catcode`\^^V=\other
+ \catcode`\^^W=\other
+ \catcode`\^^X=\other
+ \catcode`\^^Z=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\^=\other
+ %
+ % Special characters. Should be turned off anyway, but...
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ \catcode`\%=\other
+ \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+ %
+ % This is to support \ in node names and titles, since the \
+ % characters end up in a \csname. It's easier than
+ % leaving it active and making its active definition an actual \
+ % character. What I don't understand is why it works in the *value*
+ % of the xrdef. Seems like it should be a catcode12 \, and that
+ % should not typeset properly. But it works, so I'm moving on for
+ % now. --karl, 15jan04.
+ \catcode`\\=\other
+ %
+ % Make the characters 128-255 be printing characters.
+ {%
+ \count1=128
+ \def\loop{%
+ \catcode\count1=\other
+ \advance\count1 by 1
+ \ifnum \count1<256 \loop \fi
+ }%
+ }%
+ %
+ % @ is our escape character in .aux files, and we need braces.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+ \setupdatafile
+ \input\jobname.#1
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for Info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
+%
+\gdef\dofootnote{%
+ \insert\footins\bgroup
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \hsize=\pagewidth
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ \smallfonts \rm
+ %
+ % Because we use hanging indentation in footnotes, a @noindent appears
+ % to exdent this text, so make it be a no-op. makeinfo does not use
+ % hanging indentation so @noindent can still be needed within footnote
+ % text after an @example or the like (not that this is good style).
+ \let\noindent = \relax
+ %
+ % Hang the footnote text off the number. Use \everypar in case the
+ % footnote extends for more than one paragraph.
+ \everypar = {\hang}%
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ %
+ % Invoke rest of plain TeX footnote routine.
+ \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished. Otherwise, the insertion
+% would be lost.
+% Similarly, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes. --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+ \ifx \insert\ptexinsert
+ \let\insert\saveinsert
+ \else
+ \let\checkinserts\relax
+ \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+ \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+ \afterassignment\next
+ % swallow the left brace
+ \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+ \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+ {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+ \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-)
+ \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+ \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+ \next
+}
+\def\newsaveinsX #1{%
+ \csname newbox\endcsname #1%
+ \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+ \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image. We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front. If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+ % Do not bother showing banner with epsf.tex v2.7k (available in
+ % doc/epsf.tex and on ctan).
+ \def\epsfannounce{\toks0 = }%
+ \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+ work. It is also included in the Texinfo distribution, or you can get
+ it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+ \ifx\epsfbox\thisisundefined
+ \ifwarnednoepsf \else
+ \errhelp = \noepsfhelp
+ \errmessage{epsf.tex not found, images will be ignored}%
+ \global\warnednoepsftrue
+ \fi
+ \else
+ \imagexxx #1,,,,,\finish
+ \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+ \catcode`\^^M = 5 % in case we're inside an example
+ \normalturnoffactive % allow _ et al. in names
+ % If the image is by itself, center it.
+ \ifvmode
+ \imagevmodetrue
+ \else \ifx\centersub\centerV
+ % for @center @image, we need a vbox so we can have our vertical space
+ \imagevmodetrue
+ \vbox\bgroup % vbox has better behavior than vtop herev
+ \fi\fi
+ %
+ \ifimagevmode
+ \nobreak\medskip
+ % Usually we'll have text after the image which will insert
+ % \parskip glue, so insert it here too to equalize the space
+ % above and below.
+ \nobreak\vskip\parskip
+ \nobreak
+ \fi
+ %
+ % Leave vertical mode so that indentation from an enclosing
+ % environment such as @quotation is respected.
+ % However, if we're at the top level, we don't want the
+ % normal paragraph indentation.
+ % On the other hand, if we are in the case of @center @image, we don't
+ % want to start a paragraph, which will create a hsize-width box and
+ % eradicate the centering.
+ \ifx\centersub\centerV\else \noindent \fi
+ %
+ % Output the image.
+ \ifpdf
+ \dopdfimage{#1}{#2}{#3}%
+ \else
+ % \epsfbox itself resets \epsf?size at each figure.
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+ \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+ \epsfbox{#1.eps}%
+ \fi
+ %
+ \ifimagevmode
+ \medskip % space after a standalone image
+ \fi
+ \ifx\centersub\centerV \egroup \fi
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc. We don't actually implement floating yet, we always include the
+% float "here". But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc. Can't contain commas. If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label. Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored. It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+ \let\thiscaption=\empty
+ \let\thisshortcaption=\empty
+ %
+ % don't lose footnotes inside @float.
+ %
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
+ %
+ \startsavinginserts
+ %
+ % We can't be used inside a paragraph.
+ \par
+ %
+ \vtop\bgroup
+ \def\floattype{#1}%
+ \def\floatlabel{#2}%
+ \def\floatloc{#3}% we do nothing with this yet.
+ %
+ \ifx\floattype\empty
+ \let\safefloattype=\empty
+ \else
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ \fi
+ %
+ % If label is given but no type, we handle that as the empty type.
+ \ifx\floatlabel\empty \else
+ % We want each FLOATTYPE to be numbered separately (Figure 1,
+ % Table 1, Figure 2, ...). (And if no label, no number.)
+ %
+ \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+ \global\advance\floatno by 1
+ %
+ {%
+ % This magic value for \lastsection is output by \setref as the
+ % XREFLABEL-title value. \xrefX uses it to distinguish float
+ % labels (which have a completely different output format) from
+ % node and anchor labels. And \xrdef uses it to construct the
+ % lists of floats.
+ %
+ \edef\lastsection{\floatmagic=\safefloattype}%
+ \setref{\floatlabel}{Yfloat}%
+ }%
+ \fi
+ %
+ % start with \parskip glue, I guess.
+ \vskip\parskip
+ %
+ % Don't suppress indentation if a float happens to start a section.
+ \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption: Foo 1.1
+% @float Foo & @caption{Cap}: Foo: Cap
+% @float Foo & no caption: Foo
+% @float ,lbl & Caption{Cap}: 1.1: Cap
+% @float ,lbl & no caption: 1.1
+% @float & @caption{Cap}: Cap
+% @float & no caption:
+%
+\def\Efloat{%
+ \let\floatident = \empty
+ %
+ % In all cases, if we have a float type, it comes first.
+ \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+ %
+ % If we have an xref label, the number comes next.
+ \ifx\floatlabel\empty \else
+ \ifx\floattype\empty \else % if also had float type, need tie first.
+ \appendtomacro\floatident{\tie}%
+ \fi
+ % the number.
+ \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+ \fi
+ %
+ % Start the printed caption with what we've constructed in
+ % \floatident, but keep it separate; we need \floatident again.
+ \let\captionline = \floatident
+ %
+ \ifx\thiscaption\empty \else
+ \ifx\floatident\empty \else
+ \appendtomacro\captionline{: }% had ident, so need a colon between
+ \fi
+ %
+ % caption text.
+ \appendtomacro\captionline{\scanexp\thiscaption}%
+ \fi
+ %
+ % If we have anything to print, print it, with space before.
+ % Eventually this needs to become an \insert.
+ \ifx\captionline\empty \else
+ \vskip.5\parskip
+ \captionline
+ %
+ % Space below caption.
+ \vskip\parskip
+ \fi
+ %
+ % If have an xref label, write the list of floats info. Do this
+ % after the caption, to avoid chance of it being a breakpoint.
+ \ifx\floatlabel\empty \else
+ % Write the text that goes in the lof to the aux file as
+ % \floatlabel-lof. Besides \floatident, we include the short
+ % caption if specified, else the full caption if specified, else nothing.
+ {%
+ \atdummies
+ %
+ % since we read the caption text in the macro world, where ^^M
+ % is turned into a normal character, we have to scan it back, so
+ % we don't write the literal three characters "^^M" into the aux file.
+ \scanexp{%
+ \xdef\noexpand\gtemp{%
+ \ifx\thisshortcaption\empty
+ \thiscaption
+ \else
+ \thisshortcaption
+ \fi
+ }%
+ }%
+ \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+ \ifx\gtemp\empty \else : \gtemp \fi}}%
+ }%
+ \fi
+ \egroup % end of \vtop
+ %
+ % place the captured inserts
+ %
+ % BEWARE: when the floats start floating, we have to issue warning
+ % whenever an insert appears inside a float which could possibly
+ % float. --kasal, 26may04
+ %
+ \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use. Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+ \ifx#1\relax
+ % Haven't seen this figure type before.
+ \csname newcount\endcsname #1%
+ %
+ % Remember to reset this floatno at the next chap.
+ \expandafter\gdef\expandafter\resetallfloatnos
+ \expandafter{\resetallfloatnos #1=0 }%
+ \fi
+ \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value. We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref. That is, the magic
+% \lastsection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string. If so, #2 will be the
+% (safe) float type for this float. We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+ \def\temp{#1}%
+ \def\iffloattype{#2}%
+ \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+ \def\floattype{#1}% floattype
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ %
+ % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+ \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+ \ifhavexrefs
+ % if the user said @listoffloats foo but never @float foo.
+ \message{\linenumber No `\safefloattype' floats to list.}%
+ \fi
+ \else
+ \begingroup
+ \leftskip=\tocindent % indent these entries like a toc
+ \let\do=\listoffloatsdo
+ \csname floatlist\safefloattype\endcsname
+ \endgroup
+ \fi
+}
+
+% This is called on each entry in a list of floats. We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file. We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+ % Can't fully expand XR#1-lof because it can contain anything. Just
+ % pass the control sequence. On the other hand, XR#1-pg is just the
+ % page number, and we want to fully expand that so we can get a link
+ % in pdf output.
+ \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+ %
+ % use the same \entry macro we use to generate the TOC and index.
+ \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+ \writeentry
+}}
+
+
+\message{localization,}
+
+% For single-language documents, @documentlanguage is usually given very
+% early, just after @documentencoding. Single argument is the language
+% (de) or locale (de_DE) abbreviation.
+%
+{
+ \catcode`\_ = \active
+ \globaldefs=1
+\parseargdef\documentlanguage{\begingroup
+ \let_=\normalunderscore % normal _ character for filenames
+ \tex % read txi-??.tex file in plain TeX.
+ % Read the file by the name they passed if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \documentlanguagetrywithoutunderscore{#1_\finish}%
+ \else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
+ \input txi-#1.tex
+ \fi
+ \closein 1
+ \endgroup % end raw TeX
+\endgroup}
+%
+% If they passed de_DE, and txi-de_DE.tex doesn't exist,
+% try txi-de.tex.
+%
+\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{%
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
+ \input txi-#1.tex
+ \fi
+ \closein 1
+}
+}% end of special _ catcode
+%
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty. Maybe you need to install it? Putting it in the current
+directory should work if nowhere else does.}
+
+% This macro is called from txi-??.tex files; the first argument is the
+% \language name to set (without the "\lang@" prefix), the second and
+% third args are \{left,right}hyphenmin.
+%
+% The language names to pass are determined when the format is built.
+% See the etex.log file created at that time, e.g.,
+% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log.
+%
+% With TeX Live 2008, etex now includes hyphenation patterns for all
+% available languages. This means we can support hyphenation in
+% Texinfo, at least to some extent. (This still doesn't solve the
+% accented characters problem.)
+%
+\catcode`@=11
+\def\txisetlanguage#1#2#3{%
+ % do not set the language if the name is undefined in the current TeX.
+ \expandafter\ifx\csname lang@#1\endcsname \relax
+ \message{no patterns for #1}%
+ \else
+ \global\language = \csname lang@#1\endcsname
+ \fi
+ % but there is no harm in adjusting the hyphenmin values regardless.
+ \global\lefthyphenmin = #2\relax
+ \global\righthyphenmin = #3\relax
+}
+
+% Helpers for encodings.
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \global\catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+\def\setnonasciicharscatcodenonglobal#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+ % Encoding being declared for the document.
+ \def\declaredencoding{\csname #1.enc\endcsname}%
+ %
+ % Supported encodings: names converted to tokens in order to be able
+ % to compare them with \ifx.
+ \def\ascii{\csname US-ASCII.enc\endcsname}%
+ \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+ \def\latone{\csname ISO-8859-1.enc\endcsname}%
+ \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+ \def\utfeight{\csname UTF-8.enc\endcsname}%
+ %
+ \ifx \declaredencoding \ascii
+ \asciichardefs
+ %
+ \else \ifx \declaredencoding \lattwo
+ \setnonasciicharscatcode\active
+ \lattwochardefs
+ %
+ \else \ifx \declaredencoding \latone
+ \setnonasciicharscatcode\active
+ \latonechardefs
+ %
+ \else \ifx \declaredencoding \latnine
+ \setnonasciicharscatcode\active
+ \latninechardefs
+ %
+ \else \ifx \declaredencoding \utfeight
+ \setnonasciicharscatcode\active
+ \utfeightchardefs
+ %
+ \else
+ \message{Unknown document encoding #1, ignoring.}%
+ %
+ \fi % utfeight
+ \fi % latnine
+ \fi % latone
+ \fi % lattwo
+ \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\exclamdown}
+ \gdef^^a2{\missingcharmsg{CENT SIGN}}
+ \gdef^^a3{{\pounds}}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\missingcharmsg{YEN SIGN}}
+ \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\copyright}
+ \gdef^^aa{\ordf}
+ \gdef^^ab{\guillemetleft}
+ \gdef^^ac{$\lnot$}
+ \gdef^^ad{\-}
+ \gdef^^ae{\registeredsymbol}
+ \gdef^^af{\={}}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{$\pm$}
+ \gdef^^b2{$^2$}
+ \gdef^^b3{$^3$}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{$\mu$}
+ \gdef^^b6{\P}
+ %
+ \gdef^^b7{$^.$}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{$^1$}
+ \gdef^^ba{\ordm}
+ %
+ \gdef^^bb{\guillemetright}
+ \gdef^^bc{$1\over4$}
+ \gdef^^bd{$1\over2$}
+ \gdef^^be{$3\over4$}
+ \gdef^^bf{\questiondown}
+ %
+ \gdef^^c0{\`A}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\~A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\ringaccent A}
+ \gdef^^c6{\AE}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\`E}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\^E}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\`I}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\"I}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\~N}
+ \gdef^^d2{\`O}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\~O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\O}
+ \gdef^^d9{\`U}
+ \gdef^^da{\'U}
+ \gdef^^db{\^U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\TH}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\`a}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\~a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\ringaccent a}
+ \gdef^^e6{\ae}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\`e}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\^e}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\`{\dotless i}}
+ \gdef^^ed{\'{\dotless i}}
+ \gdef^^ee{\^{\dotless i}}
+ \gdef^^ef{\"{\dotless i}}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\~n}
+ \gdef^^f2{\`o}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\~o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\o}
+ \gdef^^f9{\`u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\^u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\th}
+ \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+ % Encoding is almost identical to Latin1.
+ \latonechardefs
+ %
+ \gdef^^a4{\euro}
+ \gdef^^a6{\v S}
+ \gdef^^a8{\v s}
+ \gdef^^b4{\v Z}
+ \gdef^^b8{\v z}
+ \gdef^^bc{\OE}
+ \gdef^^bd{\oe}
+ \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\ogonek{A}}
+ \gdef^^a2{\u{}}
+ \gdef^^a3{\L}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\v L}
+ \gdef^^a6{\'S}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\v S}
+ \gdef^^aa{\cedilla S}
+ \gdef^^ab{\v T}
+ \gdef^^ac{\'Z}
+ \gdef^^ad{\-}
+ \gdef^^ae{\v Z}
+ \gdef^^af{\dotaccent Z}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{\ogonek{a}}
+ \gdef^^b2{\ogonek{ }}
+ \gdef^^b3{\l}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{\v l}
+ \gdef^^b6{\'s}
+ \gdef^^b7{\v{}}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{\v s}
+ \gdef^^ba{\cedilla s}
+ \gdef^^bb{\v t}
+ \gdef^^bc{\'z}
+ \gdef^^bd{\H{}}
+ \gdef^^be{\v z}
+ \gdef^^bf{\dotaccent z}
+ %
+ \gdef^^c0{\'R}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\u A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\'L}
+ \gdef^^c6{\'C}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\v C}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\ogonek{E}}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\v E}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\v D}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\'N}
+ \gdef^^d2{\v N}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\H O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\v R}
+ \gdef^^d9{\ringaccent U}
+ \gdef^^da{\'U}
+ \gdef^^db{\H U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\cedilla T}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\'r}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\u a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\'l}
+ \gdef^^e6{\'c}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\v c}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\ogonek{e}}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\v e}
+ \gdef^^ed{\'{\dotless{i}}}
+ \gdef^^ee{\^{\dotless{i}}}
+ \gdef^^ef{\v d}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\'n}
+ \gdef^^f2{\v n}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\H o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\v r}
+ \gdef^^f9{\ringaccent u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\H u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\cedilla t}
+ \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions. It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+ \ifx #1\relax
+ \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+ \else
+ \expandafter #1%
+ \fi
+}
+
+\begingroup
+ \catcode`\~13
+ \catcode`\"12
+
+ \def\UTFviiiLoop{%
+ \global\catcode\countUTFx\active
+ \uccode`\~\countUTFx
+ \uppercase\expandafter{\UTFviiiTmp}%
+ \advance\countUTFx by 1
+ \ifnum\countUTFx < \countUTFy
+ \expandafter\UTFviiiLoop
+ \fi}
+
+ \countUTFx = "C2
+ \countUTFy = "E0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "E0
+ \countUTFy = "F0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "F0
+ \countUTFy = "F4
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+ \UTFviiiLoop
+\endgroup
+
+\begingroup
+ \catcode`\"=12
+ \catcode`\<=12
+ \catcode`\.=12
+ \catcode`\,=12
+ \catcode`\;=12
+ \catcode`\!=12
+ \catcode`\~=13
+
+ \gdef\DeclareUnicodeCharacter#1#2{%
+ \countUTFz = "#1\relax
+ %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+ \begingroup
+ \parseXMLCharref
+ \def\UTFviiiTwoOctets##1##2{%
+ \csname u8:##1\string ##2\endcsname}%
+ \def\UTFviiiThreeOctets##1##2##3{%
+ \csname u8:##1\string ##2\string ##3\endcsname}%
+ \def\UTFviiiFourOctets##1##2##3##4{%
+ \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+ \expandafter\expandafter\expandafter\expandafter
+ \expandafter\expandafter\expandafter
+ \gdef\UTFviiiTmp{#2}%
+ \endgroup}
+
+ \gdef\parseXMLCharref{%
+ \ifnum\countUTFz < "A0\relax
+ \errhelp = \EMsimple
+ \errmessage{Cannot define Unicode char value < 00A0}%
+ \else\ifnum\countUTFz < "800\relax
+ \parseUTFviiiA,%
+ \parseUTFviiiB C\UTFviiiTwoOctets.,%
+ \else\ifnum\countUTFz < "10000\relax
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+ \else
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiA!%
+ \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+ \fi\fi\fi
+ }
+
+ \gdef\parseUTFviiiA#1{%
+ \countUTFx = \countUTFz
+ \divide\countUTFz by 64
+ \countUTFy = \countUTFz
+ \multiply\countUTFz by 64
+ \advance\countUTFx by -\countUTFz
+ \advance\countUTFx by 128
+ \uccode `#1\countUTFx
+ \countUTFz = \countUTFy}
+
+ \gdef\parseUTFviiiB#1#2#3#4{%
+ \advance\countUTFz by "#10\relax
+ \uccode `#3\countUTFz
+ \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+ \DeclareUnicodeCharacter{00A0}{\tie}
+ \DeclareUnicodeCharacter{00A1}{\exclamdown}
+ \DeclareUnicodeCharacter{00A3}{\pounds}
+ \DeclareUnicodeCharacter{00A8}{\"{ }}
+ \DeclareUnicodeCharacter{00A9}{\copyright}
+ \DeclareUnicodeCharacter{00AA}{\ordf}
+ \DeclareUnicodeCharacter{00AB}{\guillemetleft}
+ \DeclareUnicodeCharacter{00AD}{\-}
+ \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+ \DeclareUnicodeCharacter{00AF}{\={ }}
+
+ \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+ \DeclareUnicodeCharacter{00B4}{\'{ }}
+ \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+ \DeclareUnicodeCharacter{00BA}{\ordm}
+ \DeclareUnicodeCharacter{00BB}{\guillemetright}
+ \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+ \DeclareUnicodeCharacter{00C0}{\`A}
+ \DeclareUnicodeCharacter{00C1}{\'A}
+ \DeclareUnicodeCharacter{00C2}{\^A}
+ \DeclareUnicodeCharacter{00C3}{\~A}
+ \DeclareUnicodeCharacter{00C4}{\"A}
+ \DeclareUnicodeCharacter{00C5}{\AA}
+ \DeclareUnicodeCharacter{00C6}{\AE}
+ \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+ \DeclareUnicodeCharacter{00C8}{\`E}
+ \DeclareUnicodeCharacter{00C9}{\'E}
+ \DeclareUnicodeCharacter{00CA}{\^E}
+ \DeclareUnicodeCharacter{00CB}{\"E}
+ \DeclareUnicodeCharacter{00CC}{\`I}
+ \DeclareUnicodeCharacter{00CD}{\'I}
+ \DeclareUnicodeCharacter{00CE}{\^I}
+ \DeclareUnicodeCharacter{00CF}{\"I}
+
+ \DeclareUnicodeCharacter{00D0}{\DH}
+ \DeclareUnicodeCharacter{00D1}{\~N}
+ \DeclareUnicodeCharacter{00D2}{\`O}
+ \DeclareUnicodeCharacter{00D3}{\'O}
+ \DeclareUnicodeCharacter{00D4}{\^O}
+ \DeclareUnicodeCharacter{00D5}{\~O}
+ \DeclareUnicodeCharacter{00D6}{\"O}
+ \DeclareUnicodeCharacter{00D8}{\O}
+ \DeclareUnicodeCharacter{00D9}{\`U}
+ \DeclareUnicodeCharacter{00DA}{\'U}
+ \DeclareUnicodeCharacter{00DB}{\^U}
+ \DeclareUnicodeCharacter{00DC}{\"U}
+ \DeclareUnicodeCharacter{00DD}{\'Y}
+ \DeclareUnicodeCharacter{00DE}{\TH}
+ \DeclareUnicodeCharacter{00DF}{\ss}
+
+ \DeclareUnicodeCharacter{00E0}{\`a}
+ \DeclareUnicodeCharacter{00E1}{\'a}
+ \DeclareUnicodeCharacter{00E2}{\^a}
+ \DeclareUnicodeCharacter{00E3}{\~a}
+ \DeclareUnicodeCharacter{00E4}{\"a}
+ \DeclareUnicodeCharacter{00E5}{\aa}
+ \DeclareUnicodeCharacter{00E6}{\ae}
+ \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+ \DeclareUnicodeCharacter{00E8}{\`e}
+ \DeclareUnicodeCharacter{00E9}{\'e}
+ \DeclareUnicodeCharacter{00EA}{\^e}
+ \DeclareUnicodeCharacter{00EB}{\"e}
+ \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+ \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{00F0}{\dh}
+ \DeclareUnicodeCharacter{00F1}{\~n}
+ \DeclareUnicodeCharacter{00F2}{\`o}
+ \DeclareUnicodeCharacter{00F3}{\'o}
+ \DeclareUnicodeCharacter{00F4}{\^o}
+ \DeclareUnicodeCharacter{00F5}{\~o}
+ \DeclareUnicodeCharacter{00F6}{\"o}
+ \DeclareUnicodeCharacter{00F8}{\o}
+ \DeclareUnicodeCharacter{00F9}{\`u}
+ \DeclareUnicodeCharacter{00FA}{\'u}
+ \DeclareUnicodeCharacter{00FB}{\^u}
+ \DeclareUnicodeCharacter{00FC}{\"u}
+ \DeclareUnicodeCharacter{00FD}{\'y}
+ \DeclareUnicodeCharacter{00FE}{\th}
+ \DeclareUnicodeCharacter{00FF}{\"y}
+
+ \DeclareUnicodeCharacter{0100}{\=A}
+ \DeclareUnicodeCharacter{0101}{\=a}
+ \DeclareUnicodeCharacter{0102}{\u{A}}
+ \DeclareUnicodeCharacter{0103}{\u{a}}
+ \DeclareUnicodeCharacter{0104}{\ogonek{A}}
+ \DeclareUnicodeCharacter{0105}{\ogonek{a}}
+ \DeclareUnicodeCharacter{0106}{\'C}
+ \DeclareUnicodeCharacter{0107}{\'c}
+ \DeclareUnicodeCharacter{0108}{\^C}
+ \DeclareUnicodeCharacter{0109}{\^c}
+ \DeclareUnicodeCharacter{0118}{\ogonek{E}}
+ \DeclareUnicodeCharacter{0119}{\ogonek{e}}
+ \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+ \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+ \DeclareUnicodeCharacter{010C}{\v{C}}
+ \DeclareUnicodeCharacter{010D}{\v{c}}
+ \DeclareUnicodeCharacter{010E}{\v{D}}
+
+ \DeclareUnicodeCharacter{0112}{\=E}
+ \DeclareUnicodeCharacter{0113}{\=e}
+ \DeclareUnicodeCharacter{0114}{\u{E}}
+ \DeclareUnicodeCharacter{0115}{\u{e}}
+ \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+ \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+ \DeclareUnicodeCharacter{011A}{\v{E}}
+ \DeclareUnicodeCharacter{011B}{\v{e}}
+ \DeclareUnicodeCharacter{011C}{\^G}
+ \DeclareUnicodeCharacter{011D}{\^g}
+ \DeclareUnicodeCharacter{011E}{\u{G}}
+ \DeclareUnicodeCharacter{011F}{\u{g}}
+
+ \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+ \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+ \DeclareUnicodeCharacter{0124}{\^H}
+ \DeclareUnicodeCharacter{0125}{\^h}
+ \DeclareUnicodeCharacter{0128}{\~I}
+ \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+ \DeclareUnicodeCharacter{012A}{\=I}
+ \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+ \DeclareUnicodeCharacter{012C}{\u{I}}
+ \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+ \DeclareUnicodeCharacter{0131}{\dotless{i}}
+ \DeclareUnicodeCharacter{0132}{IJ}
+ \DeclareUnicodeCharacter{0133}{ij}
+ \DeclareUnicodeCharacter{0134}{\^J}
+ \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+ \DeclareUnicodeCharacter{0139}{\'L}
+ \DeclareUnicodeCharacter{013A}{\'l}
+
+ \DeclareUnicodeCharacter{0141}{\L}
+ \DeclareUnicodeCharacter{0142}{\l}
+ \DeclareUnicodeCharacter{0143}{\'N}
+ \DeclareUnicodeCharacter{0144}{\'n}
+ \DeclareUnicodeCharacter{0147}{\v{N}}
+ \DeclareUnicodeCharacter{0148}{\v{n}}
+ \DeclareUnicodeCharacter{014C}{\=O}
+ \DeclareUnicodeCharacter{014D}{\=o}
+ \DeclareUnicodeCharacter{014E}{\u{O}}
+ \DeclareUnicodeCharacter{014F}{\u{o}}
+
+ \DeclareUnicodeCharacter{0150}{\H{O}}
+ \DeclareUnicodeCharacter{0151}{\H{o}}
+ \DeclareUnicodeCharacter{0152}{\OE}
+ \DeclareUnicodeCharacter{0153}{\oe}
+ \DeclareUnicodeCharacter{0154}{\'R}
+ \DeclareUnicodeCharacter{0155}{\'r}
+ \DeclareUnicodeCharacter{0158}{\v{R}}
+ \DeclareUnicodeCharacter{0159}{\v{r}}
+ \DeclareUnicodeCharacter{015A}{\'S}
+ \DeclareUnicodeCharacter{015B}{\'s}
+ \DeclareUnicodeCharacter{015C}{\^S}
+ \DeclareUnicodeCharacter{015D}{\^s}
+ \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+ \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+ \DeclareUnicodeCharacter{0160}{\v{S}}
+ \DeclareUnicodeCharacter{0161}{\v{s}}
+ \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+ \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+ \DeclareUnicodeCharacter{0164}{\v{T}}
+
+ \DeclareUnicodeCharacter{0168}{\~U}
+ \DeclareUnicodeCharacter{0169}{\~u}
+ \DeclareUnicodeCharacter{016A}{\=U}
+ \DeclareUnicodeCharacter{016B}{\=u}
+ \DeclareUnicodeCharacter{016C}{\u{U}}
+ \DeclareUnicodeCharacter{016D}{\u{u}}
+ \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+ \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+ \DeclareUnicodeCharacter{0170}{\H{U}}
+ \DeclareUnicodeCharacter{0171}{\H{u}}
+ \DeclareUnicodeCharacter{0174}{\^W}
+ \DeclareUnicodeCharacter{0175}{\^w}
+ \DeclareUnicodeCharacter{0176}{\^Y}
+ \DeclareUnicodeCharacter{0177}{\^y}
+ \DeclareUnicodeCharacter{0178}{\"Y}
+ \DeclareUnicodeCharacter{0179}{\'Z}
+ \DeclareUnicodeCharacter{017A}{\'z}
+ \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+ \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+ \DeclareUnicodeCharacter{017D}{\v{Z}}
+ \DeclareUnicodeCharacter{017E}{\v{z}}
+
+ \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+ \DeclareUnicodeCharacter{01C5}{D\v{z}}
+ \DeclareUnicodeCharacter{01C6}{d\v{z}}
+ \DeclareUnicodeCharacter{01C7}{LJ}
+ \DeclareUnicodeCharacter{01C8}{Lj}
+ \DeclareUnicodeCharacter{01C9}{lj}
+ \DeclareUnicodeCharacter{01CA}{NJ}
+ \DeclareUnicodeCharacter{01CB}{Nj}
+ \DeclareUnicodeCharacter{01CC}{nj}
+ \DeclareUnicodeCharacter{01CD}{\v{A}}
+ \DeclareUnicodeCharacter{01CE}{\v{a}}
+ \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+ \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+ \DeclareUnicodeCharacter{01D1}{\v{O}}
+ \DeclareUnicodeCharacter{01D2}{\v{o}}
+ \DeclareUnicodeCharacter{01D3}{\v{U}}
+ \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+ \DeclareUnicodeCharacter{01E2}{\={\AE}}
+ \DeclareUnicodeCharacter{01E3}{\={\ae}}
+ \DeclareUnicodeCharacter{01E6}{\v{G}}
+ \DeclareUnicodeCharacter{01E7}{\v{g}}
+ \DeclareUnicodeCharacter{01E8}{\v{K}}
+ \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+ \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+ \DeclareUnicodeCharacter{01F1}{DZ}
+ \DeclareUnicodeCharacter{01F2}{Dz}
+ \DeclareUnicodeCharacter{01F3}{dz}
+ \DeclareUnicodeCharacter{01F4}{\'G}
+ \DeclareUnicodeCharacter{01F5}{\'g}
+ \DeclareUnicodeCharacter{01F8}{\`N}
+ \DeclareUnicodeCharacter{01F9}{\`n}
+ \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+ \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+ \DeclareUnicodeCharacter{01FE}{\'{\O}}
+ \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+ \DeclareUnicodeCharacter{021E}{\v{H}}
+ \DeclareUnicodeCharacter{021F}{\v{h}}
+
+ \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+ \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+ \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+ \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+ \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+ \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+ \DeclareUnicodeCharacter{0232}{\=Y}
+ \DeclareUnicodeCharacter{0233}{\=y}
+ \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+ \DeclareUnicodeCharacter{02DB}{\ogonek{ }}
+
+ \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+ \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+ \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+ \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+ \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+ \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+ \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+ \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+ \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+ \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+ \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+ \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+ \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+ \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+ \DeclareUnicodeCharacter{1E20}{\=G}
+ \DeclareUnicodeCharacter{1E21}{\=g}
+ \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+ \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+ \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+ \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+ \DeclareUnicodeCharacter{1E26}{\"H}
+ \DeclareUnicodeCharacter{1E27}{\"h}
+
+ \DeclareUnicodeCharacter{1E30}{\'K}
+ \DeclareUnicodeCharacter{1E31}{\'k}
+ \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+ \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+ \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+ \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+ \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+ \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+ \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+ \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+ \DeclareUnicodeCharacter{1E3E}{\'M}
+ \DeclareUnicodeCharacter{1E3F}{\'m}
+
+ \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+ \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+ \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+ \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+ \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+ \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+ \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+ \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+ \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+ \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+ \DeclareUnicodeCharacter{1E54}{\'P}
+ \DeclareUnicodeCharacter{1E55}{\'p}
+ \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+ \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+ \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+ \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+ \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+ \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+ \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+ \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+ \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+ \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+ \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+ \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+ \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+ \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+ \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+ \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+ \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+ \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+ \DeclareUnicodeCharacter{1E7C}{\~V}
+ \DeclareUnicodeCharacter{1E7D}{\~v}
+ \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+ \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+ \DeclareUnicodeCharacter{1E80}{\`W}
+ \DeclareUnicodeCharacter{1E81}{\`w}
+ \DeclareUnicodeCharacter{1E82}{\'W}
+ \DeclareUnicodeCharacter{1E83}{\'w}
+ \DeclareUnicodeCharacter{1E84}{\"W}
+ \DeclareUnicodeCharacter{1E85}{\"w}
+ \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+ \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+ \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+ \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+ \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+ \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+ \DeclareUnicodeCharacter{1E8C}{\"X}
+ \DeclareUnicodeCharacter{1E8D}{\"x}
+ \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+ \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+ \DeclareUnicodeCharacter{1E90}{\^Z}
+ \DeclareUnicodeCharacter{1E91}{\^z}
+ \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+ \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+ \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+ \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+ \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+ \DeclareUnicodeCharacter{1E97}{\"t}
+ \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+ \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+ \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+ \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+ \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+ \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+ \DeclareUnicodeCharacter{1EBC}{\~E}
+ \DeclareUnicodeCharacter{1EBD}{\~e}
+
+ \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+ \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+ \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+ \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+ \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+ \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+ \DeclareUnicodeCharacter{1EF2}{\`Y}
+ \DeclareUnicodeCharacter{1EF3}{\`y}
+ \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+ \DeclareUnicodeCharacter{1EF8}{\~Y}
+ \DeclareUnicodeCharacter{1EF9}{\~y}
+
+ \DeclareUnicodeCharacter{2013}{--}
+ \DeclareUnicodeCharacter{2014}{---}
+ \DeclareUnicodeCharacter{2018}{\quoteleft}
+ \DeclareUnicodeCharacter{2019}{\quoteright}
+ \DeclareUnicodeCharacter{201A}{\quotesinglbase}
+ \DeclareUnicodeCharacter{201C}{\quotedblleft}
+ \DeclareUnicodeCharacter{201D}{\quotedblright}
+ \DeclareUnicodeCharacter{201E}{\quotedblbase}
+ \DeclareUnicodeCharacter{2022}{\bullet}
+ \DeclareUnicodeCharacter{2026}{\dots}
+ \DeclareUnicodeCharacter{2039}{\guilsinglleft}
+ \DeclareUnicodeCharacter{203A}{\guilsinglright}
+ \DeclareUnicodeCharacter{20AC}{\euro}
+
+ \DeclareUnicodeCharacter{2192}{\expansion}
+ \DeclareUnicodeCharacter{21D2}{\result}
+
+ \DeclareUnicodeCharacter{2212}{\minus}
+ \DeclareUnicodeCharacter{2217}{\point}
+ \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+ \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be very finicky about underfull hboxes, either.
+\hbadness = 6666
+
+% Following George Bush, get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+ \ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+ \else
+ \emergencystretch = .15\hsize
+ \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading. The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+ \voffset = #3\relax
+ \topskip = #6\relax
+ \splittopskip = \topskip
+ %
+ \vsize = #1\relax
+ \advance\vsize by \topskip
+ \outervsize = \vsize
+ \advance\outervsize by 2\topandbottommargin
+ \pageheight = \vsize
+ %
+ \hsize = #2\relax
+ \outerhsize = \hsize
+ \advance\outerhsize by 0.5in
+ \pagewidth = \hsize
+ %
+ \normaloffset = #4\relax
+ \bindingoffset = #5\relax
+ %
+ \ifpdf
+ \pdfpageheight #7\relax
+ \pdfpagewidth #8\relax
+ % if we don't reset these, they will remain at "1 true in" of
+ % whatever layout pdftex was dumped with.
+ \pdfhorigin = 1 true in
+ \pdfvorigin = 1 true in
+ \fi
+ %
+ \setleading{\textleading}
+ %
+ \parindent = \defaultparindent
+ \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % If page is nothing but text, make it come out even.
+ \internalpagesizes{607.2pt}{6in}% that's 46 lines
+ {\voffset}{.25in}%
+ {\bindingoffset}{36pt}%
+ {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+ \parskip = 2pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.5in}{5in}%
+ {-.2in}{0in}%
+ {\bindingoffset}{16pt}%
+ {9.25in}{7in}%
+ %
+ \lispnarrowing = 0.3in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+ \parskip = 1.5pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.4in}{4.8in}%
+ {-.2in}{-.4in}%
+ {0pt}{14pt}%
+ {9in}{6in}%
+ %
+ \lispnarrowing = 0.25in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % Double-side printing via postscript on Laserjet 4050
+ % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+ % To change the settings for a different printer or situation, adjust
+ % \normaloffset until the front-side and back-side texts align. Then
+ % do the same for \bindingoffset. You can set these for testing in
+ % your texinfo source file like this:
+ % @tex
+ % \global\normaloffset = -6mm
+ % \global\bindingoffset = 10mm
+ % @end tex
+ \internalpagesizes{673.2pt}{160mm}% that's 51 lines
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{44pt}%
+ {297mm}{210mm}%
+ %
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+ \parskip = 2pt plus 1pt minus 0.1pt
+ \textleading = 12.5pt
+ %
+ \internalpagesizes{160mm}{120mm}%
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{8pt}%
+ {210mm}{148mm}%
+ %
+ \lispnarrowing = 0.2in
+ \tolerance = 800
+ \hfuzz = 1.2pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 2mm
+ \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{237mm}{150mm}%
+ {\voffset}{4.6mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ %
+ % Must explicitly reset to 0 because we call \afourpaper.
+ \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{241mm}{165mm}%
+ {\voffset}{-2.95mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+ \globaldefs = 1
+ %
+ \parskip = 3pt plus 2pt minus 1pt
+ \setleading{\textleading}%
+ %
+ \dimen0 = #1\relax
+ \advance\dimen0 by \voffset
+ %
+ \dimen2 = \hsize
+ \advance\dimen2 by \normaloffset
+ %
+ \internalpagesizes{#1}{\hsize}%
+ {\voffset}{\normaloffset}%
+ {\bindingoffset}{44pt}%
+ {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+\def^^L{\par} % remove \outer, so ^L can appear in an @comment
+
+% DEL is a comment character, in case @c does not suffice.
+\catcode`\^^? = 14
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other \def\normaldoublequote{"}
+\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix
+\catcode`\+=\other \def\normalplus{+}
+\catcode`\<=\other \def\normalless{<}
+\catcode`\>=\other \def\normalgreater{>}
+\catcode`\^=\other \def\normalcaret{^}
+\catcode`\_=\other \def\normalunderscore{_}
+\catcode`\|=\other \def\normalverticalbar{|}
+\catcode`\~=\other \def\normaltilde{~}
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font. Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts. But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+ \normalturnoffactive
+ \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active % @ for escape char from now on.
+
+% The story here is that in math mode, the \char of \backslashcurfont
+% ends up printing the roman \ from the math symbol font (because \char
+% in math mode uses the \mathcode, and plain.tex sets
+% \mathcode`\\="026E). It seems better for @backslashchar{} to always
+% print a typewriter backslash, hence we use an explicit \mathchar,
+% which is the decimal equivalent of "715c (class 7, e.g., use \fam;
+% ignored family value; char position "5C). We can't use " for the
+% usual hex value because it has already been made active.
+@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}}
+@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents.
+
+% On startup, @fixbackslash assigns:
+% @let \ = @normalbackslash
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other. We switch back and forth between these.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.
+%
+@def@normalturnoffactive{%
+ @let"=@normaldoublequote
+ @let$=@normaldollar %$ font-lock fix
+ @let+=@normalplus
+ @let<=@normalless
+ @let>=@normalgreater
+ @let\=@normalbackslash
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let~=@normaltilde
+ @markupsetuplqdefault
+ @markupsetuprqdefault
+ @unsepspaces
+}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\' in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+ @ifx\@eatinput @let\ = @normalbackslash @fi
+ @catcode`+=@active
+ @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These (along with & and #) are made active for url-breaking, so need
+% active definitions as the normal characters.
+@def@normaldot{.}
+@def@normalquest{?}
+@def@normalslash{/}
+
+% These look ok in all fonts, so just make them not special.
+% @hashchar{} gets its own user-level command, because of #line.
+@catcode`@& = @other @def@normalamp{&}
+@catcode`@# = @other @def@normalhash{#}
+@catcode`@% = @other @def@normalpercent{%}
+
+@let @hashchar = @normalhash
+
+@c Finally, make ` and ' active, so that txicodequoteundirected and
+@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we
+@c don't make ` and ' active, @code will not get them as active chars.
+@c Do this last of all since we use ` in the previous @catcode assignments.
+@catcode`@'=@active
+@catcode`@`=@active
+@markupsetuplqdefault
+@markupsetuprqdefault
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/mpfr/examples/ReadMe b/mpfr/examples/ReadMe
new file mode 100644
index 0000000000..2e2af32c54
--- /dev/null
+++ b/mpfr/examples/ReadMe
@@ -0,0 +1 @@
+This directory contains simple examples.
diff --git a/mpfr/examples/divworst.c b/mpfr/examples/divworst.c
new file mode 100644
index 0000000000..bb5c9fe833
--- /dev/null
+++ b/mpfr/examples/divworst.c
@@ -0,0 +1,97 @@
+/* Test of the double rounding effect.
+ *
+ * This example was presented at the CNC'2 summer school on MPFR and MPC
+ * at LORIA, Nancy, France.
+ *
+ * Arguments: max difference of exponents dmax, significand size n.
+ * Optional argument: extended precision p (with double rounding).
+ *
+ * Return all the couples of positive machine numbers (x,y) such that
+ * 1/2 <= y < 1, 0 <= Ex - Ey <= dmax, x - y is exactly representable
+ * in precision n and the results of floor(x/y) in the rounding modes
+ * toward 0 and to nearest are different.
+ */
+
+/*
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpfr.h>
+
+#define PRECN x, y, z
+#define VARS PRECN, t
+
+static unsigned long
+eval (mpfr_t x, mpfr_t y, mpfr_t z, mpfr_t t, mpfr_rnd_t rnd)
+{
+ mpfr_div (t, x, y, rnd); /* the division x/y in precision p */
+ mpfr_set (z, t, rnd); /* the rounding to the precision n */
+ mpfr_rint_floor (z, z, rnd);
+ return mpfr_get_ui (z, rnd);
+}
+
+int main (int argc, char *argv[])
+{
+ int dmax, n, p;
+ mpfr_t VARS;
+
+ if (argc != 3 && argc != 4)
+ {
+ fprintf (stderr, "Usage: divworst <dmax> <n> [ <p> ]\n");
+ exit (EXIT_FAILURE);
+ }
+
+ dmax = atoi (argv[1]);
+ n = atoi (argv[2]);
+ p = argc == 3 ? n : atoi (argv[3]);
+ if (p < n)
+ {
+ fprintf (stderr, "divworst: p must be greater or equal to n\n");
+ exit (EXIT_FAILURE);
+ }
+
+ mpfr_inits2 (n, PRECN, (mpfr_ptr) 0);
+ mpfr_init2 (t, p);
+
+ for (mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN);
+ mpfr_get_exp (x) <= dmax;
+ mpfr_nextabove (x))
+ for (mpfr_set_ui_2exp (y, 1, -1, MPFR_RNDN);
+ mpfr_get_exp (y) == 0;
+ mpfr_nextabove (y))
+ {
+ unsigned long rz, rn;
+
+ if (mpfr_sub (z, x, y, MPFR_RNDZ) != 0)
+ continue; /* x - y is not representable in precision n */
+ rz = eval (x, y, z, t, MPFR_RNDZ);
+ rn = eval (x, y, z, t, MPFR_RNDN);
+ if (rz == rn)
+ continue;
+ mpfr_printf ("x = %.*Rb ; y = %.*Rb ; Z: %lu ; N: %lu\n",
+ n - 1, x, n - 1, y, rz, rn);
+ }
+
+ mpfr_clears (VARS, (mpfr_ptr) 0);
+ return 0;
+}
diff --git a/mpfr/examples/rndo-add.c b/mpfr/examples/rndo-add.c
new file mode 100644
index 0000000000..73b8a801ef
--- /dev/null
+++ b/mpfr/examples/rndo-add.c
@@ -0,0 +1,91 @@
+/* This example was presented at the CNC'2 summer school on MPFR and MPC at
+ * LORIA, Nancy, France. It shows how one can use different rounding modes.
+ * This example implements the OddRoundedAdd algorithm, which returns the
+ * sum z = x + y rounded-to-odd:
+ * * RO(z) = z if z is exactly representable;
+ * * otherwise RO(z) is the value among RD(z) and RU(z) whose
+ * least significant bit is a one.
+ */
+
+/*
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <gmp.h>
+#include <mpfr.h>
+
+#define LIST x, y, d, u, e, z
+
+int main (int argc, char **argv)
+{
+ mpfr_t LIST;
+ mpfr_prec_t prec;
+ int pprec; /* will be prec - 1 for mpfr_printf */
+
+ if (argc != 4)
+ {
+ fprintf (stderr, "Usage: rndo-add <prec> <x> <y>\n");
+ exit (1);
+ }
+
+ prec = atoi (argv[1]);
+ if (prec < 2)
+ {
+ fprintf (stderr, "rndo-add: bad precision\n");
+ exit (1);
+ }
+ pprec = prec - 1;
+
+ mpfr_inits2 (prec, LIST, (mpfr_ptr) 0);
+
+ if (mpfr_set_str (x, argv[2], 0, MPFR_RNDN))
+ {
+ fprintf (stderr, "rndo-add: bad x value\n");
+ exit (1);
+ }
+ mpfr_printf ("x = %.*Rb\n", pprec, x);
+
+ if (mpfr_set_str (y, argv[3], 0, MPFR_RNDN))
+ {
+ fprintf (stderr, "rndo-add: bad y value\n");
+ exit (1);
+ }
+ mpfr_printf ("y = %.*Rb\n", pprec, y);
+
+ mpfr_add (d, x, y, MPFR_RNDD);
+ mpfr_printf ("d = %.*Rb\n", pprec, d);
+
+ mpfr_add (u, x, y, MPFR_RNDU);
+ mpfr_printf ("u = %.*Rb\n", pprec, u);
+
+ mpfr_add (e, d, u, MPFR_RNDN);
+ mpfr_div_2ui (e, e, 1, MPFR_RNDN);
+ mpfr_printf ("e = %.*Rb\n", pprec, e);
+
+ mpfr_sub (z, u, e, MPFR_RNDN);
+ mpfr_add (z, z, d, MPFR_RNDN);
+ mpfr_printf ("z = %.*Rb\n", pprec, z);
+
+ mpfr_clears (LIST, (mpfr_ptr) 0);
+ return 0;
+}
diff --git a/mpfr/examples/sample.c b/mpfr/examples/sample.c
new file mode 100644
index 0000000000..d6a0de39f9
--- /dev/null
+++ b/mpfr/examples/sample.c
@@ -0,0 +1,56 @@
+/* This is the example given and commented on the MPFR web site:
+ * http://www.mpfr.org/sample.html
+ */
+
+/*
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <stdio.h>
+
+#include <gmp.h>
+#include <mpfr.h>
+
+int main (void)
+{
+ unsigned int i;
+ mpfr_t s, t, u;
+
+ mpfr_init2 (t, 200);
+ mpfr_set_d (t, 1.0, MPFR_RNDD);
+ mpfr_init2 (s, 200);
+ mpfr_set_d (s, 1.0, MPFR_RNDD);
+ mpfr_init2 (u, 200);
+ for (i = 1; i <= 100; i++)
+ {
+ mpfr_mul_ui (t, t, i, MPFR_RNDU);
+ mpfr_set_d (u, 1.0, MPFR_RNDD);
+ mpfr_div (u, u, t, MPFR_RNDD);
+ mpfr_add (s, s, u, MPFR_RNDD);
+ }
+ printf ("Sum is ");
+ mpfr_out_str (stdout, 10, 0, s, MPFR_RNDD);
+ putchar ('\n');
+ mpfr_clear (s);
+ mpfr_clear (t);
+ mpfr_clear (u);
+ return 0;
+}
diff --git a/mpfr/examples/version.c b/mpfr/examples/version.c
new file mode 100644
index 0000000000..3773dcdb55
--- /dev/null
+++ b/mpfr/examples/version.c
@@ -0,0 +1,111 @@
+/*
+ * Output various information about GMP and MPFR.
+ */
+
+/*
+Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <stdio.h>
+#include <limits.h>
+#include <gmp.h>
+#include <mpfr.h>
+
+/* The following failure can occur if GMP has been rebuilt with
+ * a different ABI, e.g.
+ * 1. GMP built with ABI=mode32.
+ * 2. MPFR built against this GMP version.
+ * 3. GMP rebuilt with ABI=32.
+ */
+static void failure_test (void)
+{
+ mpfr_t x;
+
+ mpfr_init2 (x, 128);
+ mpfr_set_str (x, "17", 0, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 17) != 0)
+ printf ("\nFailure in mpfr_set_str! Probably an unmatched ABI!\n");
+ mpfr_clear (x);
+}
+
+int main (void)
+{
+ unsigned long c;
+ mp_limb_t t[4] = { -1, -1, -1, -1 };
+
+#if defined(__cplusplus)
+ printf ("A C++ compiler is used.\n");
+#endif
+
+ printf ("GMP ..... Library: %-12s Header: %d.%d.%d\n",
+ gmp_version, __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR,
+ __GNU_MP_VERSION_PATCHLEVEL);
+
+ printf ("MPFR .... Library: %-12s Header: %s (based on %d.%d.%d)\n",
+ mpfr_get_version (), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR,
+ MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL);
+
+#if MPFR_VERSION_MAJOR >= 3
+ printf ("MPFR features: TLS = %s, decimal = %s",
+ mpfr_buildopt_tls_p () ? "yes" : "no",
+ mpfr_buildopt_decimal_p () ? "yes" : "no");
+# if MPFR_VERSION_MAJOR > 3 || MPFR_VERSION_MINOR >= 1
+ printf (", GMP internals = %s\nMPFR tuning: %s",
+ mpfr_buildopt_gmpinternals_p () ? "yes" : "no",
+ mpfr_buildopt_tune_case ());
+# endif
+ printf ("\n");
+#endif
+
+ printf ("MPFR patches: %s\n\n", mpfr_get_patches ());
+
+#ifdef __GMP_CC
+ printf ("__GMP_CC = \"%s\"\n", __GMP_CC);
+#endif
+#ifdef __GMP_CFLAGS
+ printf ("__GMP_CFLAGS = \"%s\"\n", __GMP_CFLAGS);
+#endif
+ printf ("GMP_LIMB_BITS = %d\n", (int) GMP_LIMB_BITS);
+ printf ("GMP_NAIL_BITS = %d\n", (int) GMP_NAIL_BITS);
+ printf ("GMP_NUMB_BITS = %d\n", (int) GMP_NUMB_BITS);
+ printf ("mp_bits_per_limb = %d\n", (int) mp_bits_per_limb);
+ printf ("sizeof(mp_limb_t) = %d\n", (int) sizeof(mp_limb_t));
+ if (mp_bits_per_limb != GMP_LIMB_BITS)
+ printf ("Warning! mp_bits_per_limb != GMP_LIMB_BITS\n");
+ if (GMP_LIMB_BITS != sizeof(mp_limb_t) * CHAR_BIT)
+ printf ("Warning! GMP_LIMB_BITS != sizeof(mp_limb_t) * CHAR_BIT\n");
+
+ c = mpn_popcount (t, 1);
+ printf ("The GMP library expects %lu bits in a mp_limb_t.\n", c);
+ if (c != GMP_LIMB_BITS)
+ printf ("Warning! This is different from GMP_LIMB_BITS!\n"
+ "Different ABI caused by a GMP library upgrade?\n");
+
+#if MPFR_VERSION_MAJOR >= 3
+ printf ("\n");
+ printf ("sizeof(mpfr_prec_t) = %d\n", (int) sizeof(mpfr_prec_t));
+ printf ("sizeof(mpfr_exp_t) = %d\n", (int) sizeof(mpfr_exp_t));
+#endif
+
+ failure_test ();
+
+ return 0;
+}
diff --git a/mpfr/install-sh b/mpfr/install-sh
new file mode 100755
index 0000000000..a9244eb078
--- /dev/null
+++ b/mpfr/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-01-19.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for `test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mpfr/ltmain.sh b/mpfr/ltmain.sh
new file mode 100644
index 0000000000..a22775b233
--- /dev/null
+++ b/mpfr/ltmain.sh
@@ -0,0 +1,9661 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --no-quiet, --no-silent
+# print informational messages (default)
+# --no-warn don't display warning messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print more informational messages than default
+# --no-verbose don't print the extra informational messages
+# --version print version information
+# -h, --help, --help-all print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE. When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.2+local1
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.2 Debian-2.4.2-1.2+local1"
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+ s@/\./@/@g
+ t dotsl
+ s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+# value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test "$func_normal_abspath_tpath" = / ; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result" ; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+# value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=${func_dirname_result}
+ if test "x$func_relative_path_tlibdir" = x ; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test "x$func_stripname_result" != x ; then
+ func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+ fi
+
+ # Normalisation. If bindir is libdir, return empty string,
+ # else relative path ending with a slash; either way, target
+ # file name can be directly appended.
+ if test ! -z "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result/"
+ func_relative_path_result=$func_stripname_result
+ fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "$1" | $SED \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $opt_debug
+
+ $SED -n '/(C)/!b go
+ :more
+ /\./!{
+ N
+ s/\n# / /
+ b more
+ }
+ :go
+ /^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/^# *.*--help/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ echo
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ :print
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+ p
+ d
+ }
+ /^# .* home page:/b print
+ /^# General help using/b print
+ ' < "$progpath"
+ ret=$?
+ if test -z "$1"; then
+ exit $ret
+ fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $opt_debug
+
+ func_error "missing argument for $1."
+ exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+ my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+ my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+ func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+ func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+ my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+ my_sed_long_arg='1s/^--[^=]*=//'
+
+ func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+ func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+ func_quote_for_eval "${2}"
+ eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly. This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+ # this just eases exit handling
+ while test $# -gt 0; do
+ opt="$1"
+ shift
+ case $opt in
+ --debug|-x) opt_debug='set -x'
+ func_echo "enabling shell trace mode"
+ $opt_debug
+ ;;
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+ --config)
+ opt_config=:
+func_config
+ ;;
+ --dlopen|-dlopen)
+ optarg="$1"
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+ shift
+ ;;
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=:
+ ;;
+ --features)
+ opt_features=:
+func_features
+ ;;
+ --finish)
+ opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ --help)
+ opt_help=:
+ ;;
+ --help-all)
+ opt_help_all=:
+opt_help=': help-all'
+ ;;
+ --mode)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_mode="$optarg"
+case $optarg in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+esac
+ shift
+ ;;
+ --no-silent|--no-quiet)
+ opt_silent=false
+func_append preserve_args " $opt"
+ ;;
+ --no-warning|--no-warn)
+ opt_warning=false
+func_append preserve_args " $opt"
+ ;;
+ --no-verbose)
+ opt_verbose=false
+func_append preserve_args " $opt"
+ ;;
+ --silent|--quiet)
+ opt_silent=:
+func_append preserve_args " $opt"
+ opt_verbose=false
+ ;;
+ --verbose|-v)
+ opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+ ;;
+ --tag)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+ --version) func_version ;;
+
+ # Separate optargs to long options:
+ --*=*)
+ func_split_long_opt "$opt"
+ set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-n*|-v*)
+ func_split_short_opt "$opt"
+ set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+ *) set dummy "$opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # Validate options:
+
+ # save first non-option argument
+ if test "$#" -gt 0; then
+ nonopt="$opt"
+ shift
+ fi
+
+ # preserve --debug
+ test "$opt_debug" = : || func_append preserve_args " --debug"
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$opt_mode' for more information."
+ }
+
+
+ # Bail if the options were screwed
+ $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case "$lt_sysroot:$1" in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result="=$func_stripname_result"
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $opt_debug
+ func_convert_core_file_wine_to_w32_result="$1"
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $opt_debug
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=""
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $opt_debug
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $opt_debug
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $opt_debug
+ if test -z "$2" && test -n "$1" ; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " \`$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result="$1"
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $opt_debug
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " \`$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result="$3"
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $opt_debug
+ case $4 in
+ $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $opt_debug
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $opt_debug
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $opt_debug
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd="func_convert_path_${func_stripname_result}"
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $opt_debug
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_append_quoted lastarg "$arg"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test "$opt_help" = :; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | sed -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ sed '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "\`$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument \`$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test "x$prev" = x-m && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=""
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname" ; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename="$func_basename_result"
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename" ; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $opt_debug
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $opt_debug
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $opt_debug
+ if func_cygming_gnu_implib_p "$1" ; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1" ; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=""
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ if test "$lock_old_archive_extraction" = yes; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test "$lock_old_archive_extraction" = yes; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+# define _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (strcmp (argv[i], debug_opt) == 0)
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $opt_debug
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir="$arg"
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps ; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test "$prefer_static_libs" = yes ||
+ test "$prefer_static_libs,$installed" = "built,no"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$lt_sysroot$libdir"
+ absdir="$lt_sysroot$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ case "$host" in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ echo
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$opt_mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$absdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$opt_mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ func_append libobjs " $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$opt_mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test "$want_nocaseglob" = yes; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Remove ${wl} instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd1 in $cmds; do
+ IFS="$save_ifs"
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test "$try_normal_branch" = yes \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=${output_objdir}/${output_la}.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " ${wl}-bind_at_load"
+ func_append finalize_command " ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ func_append oldobjs " $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ func_resolve_sysroot "$deplib"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test "x$bindir" != x ;
+ then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=yes ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ odir="$objdir"
+ else
+ odir="$dir/$objdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$opt_mode" = uninstall && odir="$dir"
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test "$opt_mode" = clean; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case "$opt_mode" in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$opt_mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ func_append rmfiles " $odir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/mpfr/m4/libtool.m4 b/mpfr/m4/libtool.m4
new file mode 100644
index 0000000000..d288c5067a
--- /dev/null
+++ b/mpfr/m4/libtool.m4
@@ -0,0 +1,7999 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file 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.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ _LT_PROG_REPLACE_SHELLFNS
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ m4_if([$1], [CXX],
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case "$ECHO" in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[ --with-sysroot[=DIR] Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([${with_sysroot}])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd* | netbsdelf*-gnu)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ # When it learns to make shared objects, it will
+ # presumably use -fPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS="$save_LDFLAGS"])
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report which library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case ${prev}${p} in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test "$pre_test_object_deps_done" = no; then
+ case ${prev} in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+ CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+ func_split_long_opt_name=${1%%=*}
+ func_split_long_opt_arg=${1#*=}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo])
+
+ _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))])
+
+ _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+ func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+ eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/mpfr/m4/ltoptions.m4 b/mpfr/m4/ltoptions.m4
new file mode 100644
index 0000000000..5d9acd8e23
--- /dev/null
+++ b/mpfr/m4/ltoptions.m4
@@ -0,0 +1,384 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file 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.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/mpfr/m4/ltsugar.m4 b/mpfr/m4/ltsugar.m4
new file mode 100644
index 0000000000..9000a057d3
--- /dev/null
+++ b/mpfr/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file 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.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/mpfr/m4/ltversion.m4 b/mpfr/m4/ltversion.m4
new file mode 100644
index 0000000000..07a8602d48
--- /dev/null
+++ b/mpfr/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file 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.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/mpfr/m4/lt~obsolete.m4 b/mpfr/m4/lt~obsolete.m4
new file mode 100644
index 0000000000..c573da90c5
--- /dev/null
+++ b/mpfr/m4/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file 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.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/mpfr/m4/size_max.m4 b/mpfr/m4/size_max.m4
new file mode 100644
index 0000000000..e44618eec4
--- /dev/null
+++ b/mpfr/m4/size_max.m4
@@ -0,0 +1,72 @@
+# size_max.m4 serial 6
+dnl Copyright (C) 2003, 2005-2006, 2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Change by Vincent Lefevre: added <inttypes.h> for consistency with MPFR
+
+AC_DEFUN([gl_SIZE_MAX],
+[
+ AC_CHECK_HEADERS(stdint.h)
+ dnl First test whether the system already has SIZE_MAX.
+ AC_MSG_CHECKING([for SIZE_MAX])
+ AC_CACHE_VAL([gl_cv_size_max], [
+ gl_cv_size_max=
+ AC_EGREP_CPP([Found it], [
+#include <limits.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef SIZE_MAX
+Found it
+#endif
+], gl_cv_size_max=yes)
+ if test -z "$gl_cv_size_max"; then
+ dnl Define it ourselves. Here we assume that the type 'size_t' is not wider
+ dnl than the type 'unsigned long'. Try hard to find a definition that can
+ dnl be used in a preprocessor #if, i.e. doesn't contain a cast.
+ AC_COMPUTE_INT([size_t_bits_minus_1], [sizeof (size_t) * CHAR_BIT - 1],
+ [#include <stddef.h>
+#include <limits.h>], size_t_bits_minus_1=)
+ AC_COMPUTE_INT([fits_in_uint], [sizeof (size_t) <= sizeof (unsigned int)],
+ [#include <stddef.h>], fits_in_uint=)
+ if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then
+ if test $fits_in_uint = 1; then
+ dnl Even though SIZE_MAX fits in an unsigned int, it must be of type
+ dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'.
+ AC_TRY_COMPILE([#include <stddef.h>
+ extern size_t foo;
+ extern unsigned long foo;
+ ], [], fits_in_uint=0)
+ fi
+ dnl We cannot use 'expr' to simplify this expression, because 'expr'
+ dnl works only with 'long' integers in the host environment, while we
+ dnl might be cross-compiling from a 32-bit platform to a 64-bit platform.
+ if test $fits_in_uint = 1; then
+ gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)"
+ else
+ gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)"
+ fi
+ else
+ dnl Shouldn't happen, but who knows...
+ gl_cv_size_max='((size_t)~(size_t)0)'
+ fi
+ fi
+ ])
+ AC_MSG_RESULT([$gl_cv_size_max])
+ if test "$gl_cv_size_max" != yes; then
+ AC_DEFINE_UNQUOTED([SIZE_MAX], [$gl_cv_size_max],
+ [Define as the maximum value of type 'size_t', if the system doesn't define it.])
+ fi
+])
+
+dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in.
+dnl Remove this when we can assume autoconf >= 2.61.
+m4_ifdef([AC_COMPUTE_INT], [], [
+ AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])])
+])
diff --git a/mpfr/missing b/mpfr/missing
new file mode 100755
index 0000000000..86a8fc31e3
--- /dev/null
+++ b/mpfr/missing
@@ -0,0 +1,331 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2012-01-06.13; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ autom4te touch the output file, or create a stub one
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program). This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+ lex*|yacc*)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case $f in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te*)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison*|yacc*)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if test $# -ne 1; then
+ eval LASTARG=\${$#}
+ case $LASTARG in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f y.tab.h; then
+ echo >y.tab.h
+ fi
+ if test ! -f y.tab.c; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex*|flex*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if test $# -ne 1; then
+ eval LASTARG=\${$#}
+ case $LASTARG in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f lex.yy.c; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit $?
+ fi
+ ;;
+
+ makeinfo*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '
+ /^@setfilename/{
+ s/.* \([^ ]*\) *$/\1/
+ p
+ q
+ }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ # If the file does not exist, the user really needs makeinfo;
+ # let's fail without touching anything.
+ test -f $file || exit 1
+ touch $file
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mpfr/src/Makefile.am b/mpfr/src/Makefile.am
new file mode 100644
index 0000000000..7644cda720
--- /dev/null
+++ b/mpfr/src/Makefile.am
@@ -0,0 +1,93 @@
+# Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+
+
+EXTRA_DIST = round_raw_generic.c jyn_asympt.c x86/core2/mparam.h \
+ x86/mparam.h x86_64/core2/mparam.h x86_64/pentium4/mparam.h \
+ ia64/mparam.h arm/mparam.h powerpc64/mparam.h sparc64/mparam.h \
+ generic/mparam.h amd/athlon/mparam.h amd/k8/mparam.h \
+ amd/amdfam10/mparam.h powerpc32/mparam.h hppa/mparam.h
+
+include_HEADERS = mpfr.h mpf2mpfr.h
+
+BUILT_SOURCES = mparam.h
+
+
+lib_LTLIBRARIES = libmpfr.la
+
+libmpfr_la_SOURCES = mpfr.h mpf2mpfr.h mpfr-gmp.h mpfr-impl.h mpfr-intmax.h \
+mpfr-longlong.h mpfr-thread.h exceptions.c extract.c uceil_exp2.c \
+uceil_log2.c ufloor_log2.c add.c add1.c add_ui.c agm.c clear.c cmp.c \
+cmp_abs.c cmp_si.c cmp_ui.c comparisons.c div_2exp.c div_2si.c \
+div_2ui.c div.c div_ui.c dump.c eq.c exp10.c exp2.c exp3.c exp.c \
+frac.c frexp.c get_d.c get_exp.c get_str.c init.c inp_str.c isinteger.c \
+isinf.c isnan.c isnum.c const_log2.c log.c modf.c mul_2exp.c mul_2si.c \
+mul_2ui.c mul.c mul_ui.c neg.c next.c out_str.c printf.c vasprintf.c \
+const_pi.c pow.c pow_si.c pow_ui.c print_raw.c print_rnd_mode.c \
+reldiff.c round_prec.c set.c setmax.c setmin.c set_d.c set_dfl_prec.c \
+set_exp.c set_rnd.c set_f.c set_prc_raw.c set_prec.c set_q.c set_si.c \
+set_str.c set_str_raw.c set_ui.c set_z.c sqrt.c sqrt_ui.c sub.c sub1.c \
+sub_ui.c rint.c ui_div.c ui_sub.c urandom.c urandomb.c get_z_exp.c \
+swap.c factorial.c cosh.c sinh.c tanh.c sinh_cosh.c acosh.c asinh.c \
+atanh.c atan.c cmp2.c exp_2.c asin.c const_euler.c cos.c sin.c tan.c \
+fma.c fms.c hypot.c log1p.c expm1.c log2.c log10.c ui_pow.c \
+ui_pow_ui.c minmax.c dim.c signbit.c copysign.c setsign.c gmp_op.c \
+init2.c acos.c sin_cos.c set_nan.c set_inf.c set_zero.c powerof2.c \
+gamma.c set_ld.c get_ld.c cbrt.c volatile.c fits_s.h fits_sshort.c \
+fits_sint.c fits_slong.c fits_u.h fits_ushort.c fits_uint.c \
+fits_ulong.c fits_uintmax.c fits_intmax.c get_si.c get_ui.c zeta.c \
+cmp_d.c erf.c inits.c inits2.c clears.c sgn.c check.c sub1sp.c \
+version.c mpn_exp.c mpfr-gmp.c mp_clz_tab.c sum.c add1sp.c \
+free_cache.c si_op.c cmp_ld.c set_ui_2exp.c set_si_2exp.c set_uj.c \
+set_sj.c get_sj.c get_uj.c get_z.c iszero.c cache.c sqr.c \
+int_ceil_log2.c isqrt.c strtofr.c pow_z.c logging.c mulders.c get_f.c \
+round_p.c erfc.c atan2.c subnormal.c const_catalan.c root.c \
+gen_inverse.h sec.c csc.c cot.c eint.c sech.c csch.c coth.c \
+round_near_x.c constant.c abort_prec_max.c stack_interface.c lngamma.c \
+zeta_ui.c set_d64.c get_d64.c jn.c yn.c rem1.c get_patches.c add_d.c \
+sub_d.c d_sub.c mul_d.c div_d.c d_div.c li2.c rec_sqrt.c min_prec.c \
+buildopt.c digamma.c bernoulli.c isregular.c set_flt.c get_flt.c \
+scale2.c set_z_exp.c ai.c gammaonethird.c ieee_floats.h \
+grandom.c
+
+libmpfr_la_LIBADD = @LIBOBJS@
+
+# Libtool -version-info CURRENT[:REVISION[:AGE]] for libmpfr.la
+#
+# 1. No interfaces changed, only implementations (good):
+# ==> Increment REVISION.
+# 2. Interfaces added, none removed (good):
+# ==> Increment CURRENT, increment AGE, set REVISION to 0.
+# 3. Interfaces removed or changed (BAD, breaks upward compatibility):
+# ==> Increment CURRENT, set AGE and REVISION to 0.
+#
+# MPFR -version-info
+# 2.1.x -
+# 2.2.x 1:x:0
+# 2.3.x 2:x:1
+# 2.4.x 3:x:2
+# 3.0.x 4:x:0
+# 3.1.x 5:x:1
+libmpfr_la_LDFLAGS = $(MPFR_LDFLAGS) $(LIBMPFR_LDFLAGS) -version-info 5:2:1
+
+# Important note: If for some reason, srcdir is read-only at build time
+# (and you use objdir != srcdir), then you need to rebuild get_patches.c
+# (with "make get_patches.c") just after patching the MPFR source. This
+# should not be a problem in practice, in particular because "make dist"
+# automatically rebuilds get_patches.c before generating the archives.
+$(srcdir)/get_patches.c: $(top_srcdir)/PATCHES $(top_srcdir)/tools/get_patches.sh
+ (cd $(top_srcdir) && ./tools/get_patches.sh) > $@ || rm -f $@
+
+# Do not add get_patches.c to CLEANFILES so that this file doesn't
+# need to be (re)built as long as no patches are applied. Anyway the
+# update of this file should be regarded as part of the patch process,
+# and "make clean" shouldn't remove it, just like it doesn't remove
+# what has been changed by "patch".
+#CLEANFILES = get_patches.c
diff --git a/mpfr/src/Makefile.in b/mpfr/src/Makefile.in
new file mode 100644
index 0000000000..f07dd8cb4e
--- /dev/null
+++ b/mpfr/src/Makefile.in
@@ -0,0 +1,935 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+subdir = src
+DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/mparam_h.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES = mparam.h
+CONFIG_CLEAN_VPATH_FILES =
+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__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libmpfr_la_DEPENDENCIES = @LIBOBJS@
+am_libmpfr_la_OBJECTS = exceptions.lo extract.lo uceil_exp2.lo \
+ uceil_log2.lo ufloor_log2.lo add.lo add1.lo add_ui.lo agm.lo \
+ clear.lo cmp.lo cmp_abs.lo cmp_si.lo cmp_ui.lo comparisons.lo \
+ div_2exp.lo div_2si.lo div_2ui.lo div.lo div_ui.lo dump.lo \
+ eq.lo exp10.lo exp2.lo exp3.lo exp.lo frac.lo frexp.lo \
+ get_d.lo get_exp.lo get_str.lo init.lo inp_str.lo isinteger.lo \
+ isinf.lo isnan.lo isnum.lo const_log2.lo log.lo modf.lo \
+ mul_2exp.lo mul_2si.lo mul_2ui.lo mul.lo mul_ui.lo neg.lo \
+ next.lo out_str.lo printf.lo vasprintf.lo const_pi.lo pow.lo \
+ pow_si.lo pow_ui.lo print_raw.lo print_rnd_mode.lo reldiff.lo \
+ round_prec.lo set.lo setmax.lo setmin.lo set_d.lo \
+ set_dfl_prec.lo set_exp.lo set_rnd.lo set_f.lo set_prc_raw.lo \
+ set_prec.lo set_q.lo set_si.lo set_str.lo set_str_raw.lo \
+ set_ui.lo set_z.lo sqrt.lo sqrt_ui.lo sub.lo sub1.lo sub_ui.lo \
+ rint.lo ui_div.lo ui_sub.lo urandom.lo urandomb.lo \
+ get_z_exp.lo swap.lo factorial.lo cosh.lo sinh.lo tanh.lo \
+ sinh_cosh.lo acosh.lo asinh.lo atanh.lo atan.lo cmp2.lo \
+ exp_2.lo asin.lo const_euler.lo cos.lo sin.lo tan.lo fma.lo \
+ fms.lo hypot.lo log1p.lo expm1.lo log2.lo log10.lo ui_pow.lo \
+ ui_pow_ui.lo minmax.lo dim.lo signbit.lo copysign.lo \
+ setsign.lo gmp_op.lo init2.lo acos.lo sin_cos.lo set_nan.lo \
+ set_inf.lo set_zero.lo powerof2.lo gamma.lo set_ld.lo \
+ get_ld.lo cbrt.lo volatile.lo fits_sshort.lo fits_sint.lo \
+ fits_slong.lo fits_ushort.lo fits_uint.lo fits_ulong.lo \
+ fits_uintmax.lo fits_intmax.lo get_si.lo get_ui.lo zeta.lo \
+ cmp_d.lo erf.lo inits.lo inits2.lo clears.lo sgn.lo check.lo \
+ sub1sp.lo version.lo mpn_exp.lo mpfr-gmp.lo mp_clz_tab.lo \
+ sum.lo add1sp.lo free_cache.lo si_op.lo cmp_ld.lo \
+ set_ui_2exp.lo set_si_2exp.lo set_uj.lo set_sj.lo get_sj.lo \
+ get_uj.lo get_z.lo iszero.lo cache.lo sqr.lo int_ceil_log2.lo \
+ isqrt.lo strtofr.lo pow_z.lo logging.lo mulders.lo get_f.lo \
+ round_p.lo erfc.lo atan2.lo subnormal.lo const_catalan.lo \
+ root.lo sec.lo csc.lo cot.lo eint.lo sech.lo csch.lo coth.lo \
+ round_near_x.lo constant.lo abort_prec_max.lo \
+ stack_interface.lo lngamma.lo zeta_ui.lo set_d64.lo get_d64.lo \
+ jn.lo yn.lo rem1.lo get_patches.lo add_d.lo sub_d.lo d_sub.lo \
+ mul_d.lo div_d.lo d_div.lo li2.lo rec_sqrt.lo min_prec.lo \
+ buildopt.lo digamma.lo bernoulli.lo isregular.lo set_flt.lo \
+ get_flt.lo scale2.lo set_z_exp.lo ai.lo gammaonethird.lo \
+ grandom.lo
+libmpfr_la_OBJECTS = $(am_libmpfr_la_OBJECTS)
+libmpfr_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libmpfr_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libmpfr_la_SOURCES)
+DIST_SOURCES = $(libmpfr_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(include_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATAFILES = @DATAFILES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBMPFR_LDFLAGS = @LIBMPFR_LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPFR_LDFLAGS = @MPFR_LDFLAGS@
+MPFR_LIBM = @MPFR_LIBM@
+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@
+STRIP = @STRIP@
+TUNE_LIBS = @TUNE_LIBS@
+VERSION = @VERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+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@
+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@
+EXTRA_DIST = round_raw_generic.c jyn_asympt.c x86/core2/mparam.h \
+ x86/mparam.h x86_64/core2/mparam.h x86_64/pentium4/mparam.h \
+ ia64/mparam.h arm/mparam.h powerpc64/mparam.h sparc64/mparam.h \
+ generic/mparam.h amd/athlon/mparam.h amd/k8/mparam.h \
+ amd/amdfam10/mparam.h powerpc32/mparam.h hppa/mparam.h
+
+include_HEADERS = mpfr.h mpf2mpfr.h
+BUILT_SOURCES = mparam.h
+lib_LTLIBRARIES = libmpfr.la
+libmpfr_la_SOURCES = mpfr.h mpf2mpfr.h mpfr-gmp.h mpfr-impl.h mpfr-intmax.h \
+mpfr-longlong.h mpfr-thread.h exceptions.c extract.c uceil_exp2.c \
+uceil_log2.c ufloor_log2.c add.c add1.c add_ui.c agm.c clear.c cmp.c \
+cmp_abs.c cmp_si.c cmp_ui.c comparisons.c div_2exp.c div_2si.c \
+div_2ui.c div.c div_ui.c dump.c eq.c exp10.c exp2.c exp3.c exp.c \
+frac.c frexp.c get_d.c get_exp.c get_str.c init.c inp_str.c isinteger.c \
+isinf.c isnan.c isnum.c const_log2.c log.c modf.c mul_2exp.c mul_2si.c \
+mul_2ui.c mul.c mul_ui.c neg.c next.c out_str.c printf.c vasprintf.c \
+const_pi.c pow.c pow_si.c pow_ui.c print_raw.c print_rnd_mode.c \
+reldiff.c round_prec.c set.c setmax.c setmin.c set_d.c set_dfl_prec.c \
+set_exp.c set_rnd.c set_f.c set_prc_raw.c set_prec.c set_q.c set_si.c \
+set_str.c set_str_raw.c set_ui.c set_z.c sqrt.c sqrt_ui.c sub.c sub1.c \
+sub_ui.c rint.c ui_div.c ui_sub.c urandom.c urandomb.c get_z_exp.c \
+swap.c factorial.c cosh.c sinh.c tanh.c sinh_cosh.c acosh.c asinh.c \
+atanh.c atan.c cmp2.c exp_2.c asin.c const_euler.c cos.c sin.c tan.c \
+fma.c fms.c hypot.c log1p.c expm1.c log2.c log10.c ui_pow.c \
+ui_pow_ui.c minmax.c dim.c signbit.c copysign.c setsign.c gmp_op.c \
+init2.c acos.c sin_cos.c set_nan.c set_inf.c set_zero.c powerof2.c \
+gamma.c set_ld.c get_ld.c cbrt.c volatile.c fits_s.h fits_sshort.c \
+fits_sint.c fits_slong.c fits_u.h fits_ushort.c fits_uint.c \
+fits_ulong.c fits_uintmax.c fits_intmax.c get_si.c get_ui.c zeta.c \
+cmp_d.c erf.c inits.c inits2.c clears.c sgn.c check.c sub1sp.c \
+version.c mpn_exp.c mpfr-gmp.c mp_clz_tab.c sum.c add1sp.c \
+free_cache.c si_op.c cmp_ld.c set_ui_2exp.c set_si_2exp.c set_uj.c \
+set_sj.c get_sj.c get_uj.c get_z.c iszero.c cache.c sqr.c \
+int_ceil_log2.c isqrt.c strtofr.c pow_z.c logging.c mulders.c get_f.c \
+round_p.c erfc.c atan2.c subnormal.c const_catalan.c root.c \
+gen_inverse.h sec.c csc.c cot.c eint.c sech.c csch.c coth.c \
+round_near_x.c constant.c abort_prec_max.c stack_interface.c lngamma.c \
+zeta_ui.c set_d64.c get_d64.c jn.c yn.c rem1.c get_patches.c add_d.c \
+sub_d.c d_sub.c mul_d.c div_d.c d_div.c li2.c rec_sqrt.c min_prec.c \
+buildopt.c digamma.c bernoulli.c isregular.c set_flt.c get_flt.c \
+scale2.c set_z_exp.c ai.c gammaonethird.c ieee_floats.h \
+grandom.c
+
+libmpfr_la_LIBADD = @LIBOBJS@
+
+# Libtool -version-info CURRENT[:REVISION[:AGE]] for libmpfr.la
+#
+# 1. No interfaces changed, only implementations (good):
+# ==> Increment REVISION.
+# 2. Interfaces added, none removed (good):
+# ==> Increment CURRENT, increment AGE, set REVISION to 0.
+# 3. Interfaces removed or changed (BAD, breaks upward compatibility):
+# ==> Increment CURRENT, set AGE and REVISION to 0.
+#
+# MPFR -version-info
+# 2.1.x -
+# 2.2.x 1:x:0
+# 2.3.x 2:x:1
+# 2.4.x 3:x:2
+# 3.0.x 4:x:0
+# 3.1.x 5:x:1
+libmpfr_la_LDFLAGS = $(MPFR_LDFLAGS) $(LIBMPFR_LDFLAGS) -version-info 5:2:1
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: 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):
+mparam.h: $(top_builddir)/config.status $(srcdir)/mparam_h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libmpfr.la: $(libmpfr_la_OBJECTS) $(libmpfr_la_DEPENDENCIES) $(EXTRA_libmpfr_la_DEPENDENCIES)
+ $(libmpfr_la_LINK) -rpath $(libdir) $(libmpfr_la_OBJECTS) $(libmpfr_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abort_prec_max.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acos.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acosh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add1sp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add_d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ai.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asinh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atan2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atanh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bernoulli.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buildopt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cbrt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clear.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clears.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp_abs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp_d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp_ld.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp_si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comparisons.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const_catalan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const_euler.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const_log2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/const_pi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constant.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copysign.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cos.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cosh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cot.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coth.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csch.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_div.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d_sub.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digamma.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dim.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_2exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_2si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_2ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/div_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/erf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/erfc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exceptions.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp10.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp_2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expm1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/factorial.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_intmax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_sint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_slong.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_sshort.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_uint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_uintmax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_ulong.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fits_ushort.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fma.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fms.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/free_cache.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frexp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gamma.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gammaonethird.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_d64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_f.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_flt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_ld.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_patches.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_sj.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_str.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_uj.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_z.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_z_exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmp_op.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grandom.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hypot.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inits.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inits2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inp_str.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/int_ceil_log2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isinf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isinteger.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isnan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isnum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isqrt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isregular.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iszero.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jn.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/li2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lngamma.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log10.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log1p.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/min_prec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minmax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp_clz_tab.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpfr-gmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpn_exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_2exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_2si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_2ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mul_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mulders.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/neg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/next.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/out_str.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pow_z.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/powerof2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print_raw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print_rnd_mode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rec_sqrt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reldiff.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rem1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/root.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/round_near_x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/round_p.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/round_prec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scale2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sech.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_d64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_dfl_prec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_f.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_flt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_inf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_ld.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_nan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_prc_raw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_prec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_q.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_rnd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_si.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_si_2exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_sj.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_str.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_str_raw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_ui_2exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_uj.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_z.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_z_exp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_zero.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setmax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setmin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setsign.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgn.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/si_op.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signbit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sin_cos.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sinh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sinh_cosh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqrt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqrt_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack_interface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtofr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub1sp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub_d.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnormal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tanh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uceil_exp2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uceil_log2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ufloor_log2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui_div.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui_pow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui_pow_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui_sub.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/urandom.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/urandomb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vasprintf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/volatile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yn.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zeta.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zeta_ui.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) 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:
+
+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."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -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-includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+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 -rf ./$(DEPDIR)
+ -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: uninstall-includeHEADERS uninstall-libLTLIBRARIES
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags 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-includeHEADERS install-info \
+ install-info-am install-libLTLIBRARIES 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 \
+ tags uninstall uninstall-am uninstall-includeHEADERS \
+ uninstall-libLTLIBRARIES
+
+
+# Important note: If for some reason, srcdir is read-only at build time
+# (and you use objdir != srcdir), then you need to rebuild get_patches.c
+# (with "make get_patches.c") just after patching the MPFR source. This
+# should not be a problem in practice, in particular because "make dist"
+# automatically rebuilds get_patches.c before generating the archives.
+$(srcdir)/get_patches.c: $(top_srcdir)/PATCHES $(top_srcdir)/tools/get_patches.sh
+ (cd $(top_srcdir) && ./tools/get_patches.sh) > $@ || rm -f $@
+
+# Do not add get_patches.c to CLEANFILES so that this file doesn't
+# need to be (re)built as long as no patches are applied. Anyway the
+# update of this file should be regarded as part of the patch process,
+# and "make clean" shouldn't remove it, just like it doesn't remove
+# what has been changed by "patch".
+#CLEANFILES = get_patches.c
+
+# 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/mpfr/src/abort_prec_max.c b/mpfr/src/abort_prec_max.c
new file mode 100644
index 0000000000..a747e72b24
--- /dev/null
+++ b/mpfr/src/abort_prec_max.c
@@ -0,0 +1,32 @@
+/* mpfr_abort_prec_max -- Abort due to maximal precision overflow.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include "mpfr-impl.h"
+
+void mpfr_abort_prec_max (void)
+{
+ fprintf (stderr, "MPFR: Maximal precision overflow\n");
+ abort ();
+}
+
diff --git a/mpfr/src/acos.c b/mpfr/src/acos.c
new file mode 100644
index 0000000000..63eddf51cd
--- /dev/null
+++ b/mpfr/src/acos.c
@@ -0,0 +1,146 @@
+/* mpfr_acos -- arc-cosinus of a floating-point number
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_acos (mpfr_ptr acos, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xp, arcc, tmp;
+ mpfr_exp_t supplement;
+ mpfr_prec_t prec;
+ int sign, compared, inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
+ ("acos[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(acos), mpfr_log_prec, acos, inexact));
+
+ /* Singular cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x) || MPFR_IS_INF (x))
+ {
+ MPFR_SET_NAN (acos);
+ MPFR_RET_NAN;
+ }
+ else /* necessarily x=0 */
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(x));
+ /* acos(0)=Pi/2 */
+ MPFR_SAVE_EXPO_MARK (expo);
+ inexact = mpfr_const_pi (acos, rnd_mode);
+ mpfr_div_2ui (acos, acos, 1, rnd_mode); /* exact */
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (acos, inexact, rnd_mode);
+ }
+ }
+
+ /* Set x_p=|x| */
+ sign = MPFR_SIGN (x);
+ mpfr_init2 (xp, MPFR_PREC (x));
+ mpfr_abs (xp, x, MPFR_RNDN); /* Exact */
+
+ compared = mpfr_cmp_ui (xp, 1);
+
+ if (MPFR_UNLIKELY (compared >= 0))
+ {
+ mpfr_clear (xp);
+ if (compared > 0) /* acos(x) = NaN for x > 1 */
+ {
+ MPFR_SET_NAN(acos);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ if (MPFR_IS_POS_SIGN (sign)) /* acos(+1) = 0 */
+ return mpfr_set_ui (acos, 0, rnd_mode);
+ else /* acos(-1) = Pi */
+ return mpfr_const_pi (acos, rnd_mode);
+ }
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Compute the supplement */
+ mpfr_ui_sub (xp, 1, xp, MPFR_RNDD);
+ if (MPFR_IS_POS_SIGN (sign))
+ supplement = 2 - 2 * MPFR_GET_EXP (xp);
+ else
+ supplement = 2 - MPFR_GET_EXP (xp);
+ mpfr_clear (xp);
+
+ prec = MPFR_PREC (acos);
+ prec += MPFR_INT_CEIL_LOG2(prec) + 10 + supplement;
+
+ /* VL: The following change concerning prec comes from r3145
+ "Optimize mpfr_acos by choosing a better initial precision."
+ but it doesn't seem to be correct and leads to problems (assertion
+ failure or very important inefficiency) with tiny arguments.
+ Therefore, I've disabled it. */
+ /* If x ~ 2^-N, acos(x) ~ PI/2 - x - x^3/6
+ If Prec < 2*N, we can't round since x^3/6 won't be counted. */
+#if 0
+ if (MPFR_PREC (acos) >= MPFR_PREC (x) && MPFR_GET_EXP (x) < 0)
+ {
+ mpfr_uexp_t pmin = (mpfr_uexp_t) (-2 * MPFR_GET_EXP (x)) + 5;
+ MPFR_ASSERTN (pmin <= MPFR_PREC_MAX);
+ if (prec < pmin)
+ prec = pmin;
+ }
+#endif
+
+ mpfr_init2 (tmp, prec);
+ mpfr_init2 (arcc, prec);
+
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ /* acos(x) = Pi/2 - asin(x) = Pi/2 - atan(x/sqrt(1-x^2)) */
+ mpfr_sqr (tmp, x, MPFR_RNDN);
+ mpfr_ui_sub (tmp, 1, tmp, MPFR_RNDN);
+ mpfr_sqrt (tmp, tmp, MPFR_RNDN);
+ mpfr_div (tmp, x, tmp, MPFR_RNDN);
+ mpfr_atan (arcc, tmp, MPFR_RNDN);
+ mpfr_const_pi (tmp, MPFR_RNDN);
+ mpfr_div_2ui (tmp, tmp, 1, MPFR_RNDN);
+ mpfr_sub (arcc, tmp, arcc, MPFR_RNDN);
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (arcc, prec - supplement,
+ MPFR_PREC (acos), rnd_mode)))
+ break;
+ MPFR_ZIV_NEXT (loop, prec);
+ mpfr_set_prec (tmp, prec);
+ mpfr_set_prec (arcc, prec);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (acos, arcc, rnd_mode);
+ mpfr_clear (tmp);
+ mpfr_clear (arcc);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (acos, inexact, rnd_mode);
+}
diff --git a/mpfr/src/acosh.c b/mpfr/src/acosh.c
new file mode 100644
index 0000000000..75e931d189
--- /dev/null
+++ b/mpfr/src/acosh.c
@@ -0,0 +1,158 @@
+/* mpfr_acosh -- inverse hyperbolic cosine
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* The computation of acosh is done by *
+ * acosh= ln(x + sqrt(x^2-1)) */
+
+int
+mpfr_acosh (mpfr_ptr y, mpfr_srcptr x , mpfr_rnd_t rnd_mode)
+{
+ MPFR_SAVE_EXPO_DECL (expo);
+ int inexact;
+ int comp;
+
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y,
+ inexact));
+
+ /* Deal with special cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ /* Nan, or zero or -Inf */
+ if (MPFR_IS_INF (x) && MPFR_IS_POS (x))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0);
+ }
+ else /* Nan, or zero or -Inf */
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ }
+ comp = mpfr_cmp_ui (x, 1);
+ if (MPFR_UNLIKELY (comp < 0))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_UNLIKELY (comp == 0))
+ {
+ MPFR_SET_ZERO (y); /* acosh(1) = 0 */
+ MPFR_SET_POS (y);
+ MPFR_RET (0);
+ }
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* General case */
+ {
+ /* Declaration of the intermediary variables */
+ mpfr_t t;
+ /* Declaration of the size variables */
+ mpfr_prec_t Ny = MPFR_PREC(y); /* Precision of output variable */
+ mpfr_prec_t Nt; /* Precision of the intermediary variable */
+ mpfr_exp_t err, exp_te, d; /* Precision of error */
+ MPFR_ZIV_DECL (loop);
+
+ /* compute the precision of intermediary variable */
+ /* the optimal number of bits : see algorithms.tex */
+ Nt = Ny + 4 + MPFR_INT_CEIL_LOG2 (Ny);
+
+ /* initialization of intermediary variables */
+ mpfr_init2 (t, Nt);
+
+ /* First computation of acosh */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ /* compute acosh */
+ MPFR_BLOCK (flags, mpfr_mul (t, x, x, MPFR_RNDD)); /* x^2 */
+ if (MPFR_OVERFLOW (flags))
+ {
+ mpfr_t ln2;
+ mpfr_prec_t pln2;
+
+ /* As x is very large and the precision is not too large, we
+ assume that we obtain the same result by evaluating ln(2x).
+ We need to compute ln(x) + ln(2) as 2x can overflow. TODO:
+ write a proof and add an MPFR_ASSERTN. */
+ mpfr_log (t, x, MPFR_RNDN); /* err(log) < 1/2 ulp(t) */
+ pln2 = Nt - MPFR_PREC_MIN < MPFR_GET_EXP (t) ?
+ MPFR_PREC_MIN : Nt - MPFR_GET_EXP (t);
+ mpfr_init2 (ln2, pln2);
+ mpfr_const_log2 (ln2, MPFR_RNDN); /* err(ln2) < 1/2 ulp(t) */
+ mpfr_add (t, t, ln2, MPFR_RNDN); /* err <= 3/2 ulp(t) */
+ mpfr_clear (ln2);
+ err = 1;
+ }
+ else
+ {
+ exp_te = MPFR_GET_EXP (t);
+ mpfr_sub_ui (t, t, 1, MPFR_RNDD); /* x^2-1 */
+ if (MPFR_UNLIKELY (MPFR_IS_ZERO (t)))
+ {
+ /* This means that x is very close to 1: x = 1 + t with
+ t < 2^(-Nt). We have: acosh(x) = sqrt(2t) (1 - eps(t))
+ with 0 < eps(t) < t / 12. */
+ mpfr_sub_ui (t, x, 1, MPFR_RNDD); /* t = x - 1 */
+ mpfr_mul_2ui (t, t, 1, MPFR_RNDN); /* 2t */
+ mpfr_sqrt (t, t, MPFR_RNDN); /* sqrt(2t) */
+ err = 1;
+ }
+ else
+ {
+ d = exp_te - MPFR_GET_EXP (t);
+ mpfr_sqrt (t, t, MPFR_RNDN); /* sqrt(x^2-1) */
+ mpfr_add (t, t, x, MPFR_RNDN); /* sqrt(x^2-1)+x */
+ mpfr_log (t, t, MPFR_RNDN); /* ln(sqrt(x^2-1)+x) */
+
+ /* error estimate -- see algorithms.tex */
+ err = 3 + MAX (1, d) - MPFR_GET_EXP (t);
+ /* error is bounded by 1/2 + 2^err <= 2^(max(0,1+err)) */
+ err = MAX (0, 1 + err);
+ }
+ }
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - err, Ny, rnd_mode)))
+ break;
+
+ /* reactualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (y, t, rnd_mode);
+
+ mpfr_clear (t);
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/add.c b/mpfr/src/add.c
new file mode 100644
index 0000000000..4b938dc25a
--- /dev/null
+++ b/mpfr/src/add.c
@@ -0,0 +1,111 @@
+/* mpfr_add -- add two floating-point numbers
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ MPFR_LOG_FUNC
+ (("b[%Pu]=%.*Rg c[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (b), mpfr_log_prec, b,
+ mpfr_get_prec (c), mpfr_log_prec, c, rnd_mode),
+ ("a[%Pu]=%.*Rg", mpfr_get_prec (a), mpfr_log_prec, a));
+
+ if (MPFR_ARE_SINGULAR(b,c))
+ {
+ if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c))
+ {
+ MPFR_SET_NAN(a);
+ MPFR_RET_NAN;
+ }
+ /* neither b nor c is NaN here */
+ else if (MPFR_IS_INF(b))
+ {
+ if (!MPFR_IS_INF(c) || MPFR_SIGN(b) == MPFR_SIGN(c))
+ {
+ MPFR_SET_INF(a);
+ MPFR_SET_SAME_SIGN(a, b);
+ MPFR_RET(0); /* exact */
+ }
+ else
+ {
+ MPFR_SET_NAN(a);
+ MPFR_RET_NAN;
+ }
+ }
+ else if (MPFR_IS_INF(c))
+ {
+ MPFR_SET_INF(a);
+ MPFR_SET_SAME_SIGN(a, c);
+ MPFR_RET(0); /* exact */
+ }
+ /* now either b or c is zero */
+ else if (MPFR_IS_ZERO(b))
+ {
+ if (MPFR_IS_ZERO(c))
+ {
+ /* for round away, we take the same convention for 0 + 0
+ as for round to zero or to nearest: it always gives +0,
+ except (-0) + (-0) = -0. */
+ MPFR_SET_SIGN(a,
+ (rnd_mode != MPFR_RNDD ?
+ ((MPFR_IS_NEG(b) && MPFR_IS_NEG(c)) ? -1 : 1) :
+ ((MPFR_IS_POS(b) && MPFR_IS_POS(c)) ? 1 : -1)));
+ MPFR_SET_ZERO(a);
+ MPFR_RET(0); /* 0 + 0 is exact */
+ }
+ return mpfr_set (a, c, rnd_mode);
+ }
+ else
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(c));
+ return mpfr_set (a, b, rnd_mode);
+ }
+ }
+
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (b));
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (c));
+
+ if (MPFR_UNLIKELY(MPFR_SIGN(b) != MPFR_SIGN(c)))
+ { /* signs differ, it is a subtraction */
+ if (MPFR_LIKELY(MPFR_PREC(a) == MPFR_PREC(b)
+ && MPFR_PREC(b) == MPFR_PREC(c)))
+ return mpfr_sub1sp(a, b, c, rnd_mode);
+ else
+ return mpfr_sub1(a, b, c, rnd_mode);
+ }
+ else
+ { /* signs are equal, it's an addition */
+ if (MPFR_LIKELY(MPFR_PREC(a) == MPFR_PREC(b)
+ && MPFR_PREC(b) == MPFR_PREC(c)))
+ if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c))
+ return mpfr_add1sp(a, c, b, rnd_mode);
+ else
+ return mpfr_add1sp(a, b, c, rnd_mode);
+ else
+ if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c))
+ return mpfr_add1(a, c, b, rnd_mode);
+ else
+ return mpfr_add1(a, b, c, rnd_mode);
+ }
+}
diff --git a/mpfr/src/add1.c b/mpfr/src/add1.c
new file mode 100644
index 0000000000..e77f75231d
--- /dev/null
+++ b/mpfr/src/add1.c
@@ -0,0 +1,538 @@
+/* mpfr_add1 -- internal function to perform a "real" addition
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* compute sign(b) * (|b| + |c|), assuming b and c have same sign,
+ and are not NaN, Inf, nor zero. */
+int
+mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mp_limb_t *ap, *bp, *cp;
+ mpfr_prec_t aq, bq, cq, aq2;
+ mp_size_t an, bn, cn;
+ mpfr_exp_t difw, exp;
+ int sh, rb, fb, inex;
+ mpfr_uexp_t diff_exp;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_ASSERTD(MPFR_IS_PURE_FP(b));
+ MPFR_ASSERTD(MPFR_IS_PURE_FP(c));
+
+ MPFR_TMP_MARK(marker);
+
+ aq = MPFR_PREC(a);
+ bq = MPFR_PREC(b);
+ cq = MPFR_PREC(c);
+
+ an = MPFR_PREC2LIMBS (aq); /* number of limbs of a */
+ aq2 = (mpfr_prec_t) an * GMP_NUMB_BITS;
+ sh = aq2 - aq; /* non-significant bits in low limb */
+
+ bn = MPFR_PREC2LIMBS (bq); /* number of limbs of b */
+ cn = MPFR_PREC2LIMBS (cq); /* number of limbs of c */
+
+ ap = MPFR_MANT(a);
+ bp = MPFR_MANT(b);
+ cp = MPFR_MANT(c);
+
+ if (MPFR_UNLIKELY(ap == bp))
+ {
+ bp = MPFR_TMP_LIMBS_ALLOC (bn);
+ MPN_COPY (bp, ap, bn);
+ if (ap == cp)
+ { cp = bp; }
+ }
+ else if (MPFR_UNLIKELY(ap == cp))
+ {
+ cp = MPFR_TMP_LIMBS_ALLOC (cn);
+ MPN_COPY(cp, ap, cn);
+ }
+
+ exp = MPFR_GET_EXP (b);
+ MPFR_SET_SAME_SIGN(a, b);
+ MPFR_UPDATE2_RND_MODE(rnd_mode, MPFR_SIGN(b));
+ /* now rnd_mode is either MPFR_RNDN, MPFR_RNDZ or MPFR_RNDA */
+ /* Note: exponents can be negative, but the unsigned subtraction is
+ a modular subtraction, so that one gets the correct result. */
+ diff_exp = (mpfr_uexp_t) exp - MPFR_GET_EXP(c);
+
+ /*
+ * 1. Compute the significant part A', the non-significant bits of A
+ * are taken into account.
+ *
+ * 2. Perform the rounding. At each iteration, we remember:
+ * _ r = rounding bit
+ * _ f = following bits (same value)
+ * where the result has the form: [number A]rfff...fff + a remaining
+ * value in the interval [0,2) ulp. We consider the most significant
+ * bits of the remaining value to update the result; a possible carry
+ * is immediately taken into account and A is updated accordingly. As
+ * soon as the bits f don't have the same value, A can be rounded.
+ * Variables:
+ * _ rb = rounding bit (0 or 1).
+ * _ fb = following bits (0 or 1), then sticky bit.
+ * If fb == 0, the only thing that can change is the sticky bit.
+ */
+
+ rb = fb = -1; /* means: not initialized */
+
+ if (MPFR_UNLIKELY (MPFR_UEXP (aq2) <= diff_exp))
+ { /* c does not overlap with a' */
+ if (MPFR_UNLIKELY(an > bn))
+ { /* a has more limbs than b */
+ /* copy b to the most significant limbs of a */
+ MPN_COPY(ap + (an - bn), bp, bn);
+ /* zero the least significant limbs of a */
+ MPN_ZERO(ap, an - bn);
+ }
+ else /* an <= bn */
+ {
+ /* copy the most significant limbs of b to a */
+ MPN_COPY(ap, bp + (bn - an), an);
+ }
+ }
+ else /* aq2 > diff_exp */
+ { /* c overlaps with a' */
+ mp_limb_t *a2p;
+ mp_limb_t cc;
+ mpfr_prec_t dif;
+ mp_size_t difn, k;
+ int shift;
+
+ /* copy c (shifted) into a */
+
+ dif = aq2 - diff_exp;
+ /* dif is the number of bits of c which overlap with a' */
+
+ difn = MPFR_PREC2LIMBS (dif);
+ /* only the highest difn limbs from c have to be considered */
+ if (MPFR_UNLIKELY(difn > cn))
+ {
+ /* c doesn't have enough limbs; take into account the virtual
+ zero limbs now by zeroing the least significant limbs of a' */
+ MPFR_ASSERTD(difn - cn <= an);
+ MPN_ZERO(ap, difn - cn);
+ difn = cn;
+ }
+ k = diff_exp / GMP_NUMB_BITS;
+
+ /* zero the most significant k limbs of a */
+ a2p = ap + (an - k);
+ MPN_ZERO(a2p, k);
+
+ shift = diff_exp % GMP_NUMB_BITS;
+
+ if (MPFR_LIKELY(shift))
+ {
+ MPFR_ASSERTD(a2p - difn >= ap);
+ cc = mpn_rshift(a2p - difn, cp + (cn - difn), difn, shift);
+ if (MPFR_UNLIKELY(a2p - difn > ap))
+ *(a2p - difn - 1) = cc;
+ }
+ else
+ MPN_COPY(a2p - difn, cp + (cn - difn), difn);
+
+ /* add b to a */
+ cc = MPFR_UNLIKELY(an > bn)
+ ? mpn_add_n(ap + (an - bn), ap + (an - bn), bp, bn)
+ : mpn_add_n(ap, ap, bp + (bn - an), an);
+
+ if (MPFR_UNLIKELY(cc)) /* carry */
+ {
+ if (MPFR_UNLIKELY(exp == __gmpfr_emax))
+ {
+ inex = mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ goto end_of_add;
+ }
+ exp++;
+ rb = (ap[0] >> sh) & 1; /* LSB(a) --> rounding bit after the shift */
+ if (MPFR_LIKELY(sh))
+ {
+ mp_limb_t mask, bb;
+
+ mask = MPFR_LIMB_MASK (sh);
+ bb = ap[0] & mask;
+ ap[0] &= (~mask) << 1;
+ if (bb == 0)
+ fb = 0;
+ else if (bb == mask)
+ fb = 1;
+ }
+ mpn_rshift(ap, ap, an, 1);
+ ap[an-1] += MPFR_LIMB_HIGHBIT;
+ if (sh && fb < 0)
+ goto rounding;
+ } /* cc */
+ } /* aq2 > diff_exp */
+
+ /* non-significant bits of a */
+ if (MPFR_LIKELY(rb < 0 && sh))
+ {
+ mp_limb_t mask, bb;
+
+ mask = MPFR_LIMB_MASK (sh);
+ bb = ap[0] & mask;
+ ap[0] &= ~mask;
+ rb = bb >> (sh - 1);
+ if (MPFR_LIKELY(sh > 1))
+ {
+ mask >>= 1;
+ bb &= mask;
+ if (bb == 0)
+ fb = 0;
+ else if (bb == mask)
+ fb = 1;
+ else
+ goto rounding;
+ }
+ }
+
+ /* determine rounding and sticky bits (and possible carry) */
+
+ difw = (mpfr_exp_t) an - (mpfr_exp_t) (diff_exp / GMP_NUMB_BITS);
+ /* difw is the number of limbs from b (regarded as having an infinite
+ precision) that have already been combined with c; -n if the next
+ n limbs from b won't be combined with c. */
+
+ if (MPFR_UNLIKELY(bn > an))
+ { /* there are still limbs from b that haven't been taken into account */
+ mp_size_t bk;
+
+ if (fb == 0 && difw <= 0)
+ {
+ fb = 1; /* c hasn't been taken into account ==> sticky bit != 0 */
+ goto rounding;
+ }
+
+ bk = bn - an; /* index of lowest considered limb from b, > 0 */
+ while (difw < 0)
+ { /* ulp(next limb from b) > msb(c) */
+ mp_limb_t bb;
+
+ bb = bp[--bk];
+
+ MPFR_ASSERTD(fb != 0);
+ if (fb > 0)
+ {
+ if (bb != MP_LIMB_T_MAX)
+ {
+ fb = 1; /* c hasn't been taken into account
+ ==> sticky bit != 0 */
+ goto rounding;
+ }
+ }
+ else /* fb not initialized yet */
+ {
+ if (rb < 0) /* rb not initialized yet */
+ {
+ rb = bb >> (GMP_NUMB_BITS - 1);
+ bb |= MPFR_LIMB_HIGHBIT;
+ }
+ fb = 1;
+ if (bb != MP_LIMB_T_MAX)
+ goto rounding;
+ }
+
+ if (bk == 0)
+ { /* b has entirely been read */
+ fb = 1; /* c hasn't been taken into account
+ ==> sticky bit != 0 */
+ goto rounding;
+ }
+
+ difw++;
+ } /* while */
+ MPFR_ASSERTD(bk > 0 && difw >= 0);
+
+ if (difw <= cn)
+ {
+ mp_size_t ck;
+ mp_limb_t cprev;
+ int difs;
+
+ ck = cn - difw;
+ difs = diff_exp % GMP_NUMB_BITS;
+
+ if (difs == 0 && ck == 0)
+ goto c_read;
+
+ cprev = ck == cn ? 0 : cp[ck];
+
+ if (fb < 0)
+ {
+ mp_limb_t bb, cc;
+
+ if (difs)
+ {
+ cc = cprev << (GMP_NUMB_BITS - difs);
+ if (--ck >= 0)
+ {
+ cprev = cp[ck];
+ cc += cprev >> difs;
+ }
+ }
+ else
+ cc = cp[--ck];
+
+ bb = bp[--bk] + cc;
+
+ if (bb < cc /* carry */
+ && (rb < 0 || (rb ^= 1) == 0)
+ && mpn_add_1(ap, ap, an, MPFR_LIMB_ONE << sh))
+ {
+ if (exp == __gmpfr_emax)
+ {
+ inex = mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ goto end_of_add;
+ }
+ exp++;
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
+ rb = 0;
+ }
+
+ if (rb < 0) /* rb not initialized yet */
+ {
+ rb = bb >> (GMP_NUMB_BITS - 1);
+ bb <<= 1;
+ bb |= bb >> (GMP_NUMB_BITS - 1);
+ }
+
+ fb = bb != 0;
+ if (fb && bb != MP_LIMB_T_MAX)
+ goto rounding;
+ } /* fb < 0 */
+
+ while (bk > 0)
+ {
+ mp_limb_t bb, cc;
+
+ if (difs)
+ {
+ if (ck < 0)
+ goto c_read;
+ cc = cprev << (GMP_NUMB_BITS - difs);
+ if (--ck >= 0)
+ {
+ cprev = cp[ck];
+ cc += cprev >> difs;
+ }
+ }
+ else
+ {
+ if (ck == 0)
+ goto c_read;
+ cc = cp[--ck];
+ }
+
+ bb = bp[--bk] + cc;
+ if (bb < cc) /* carry */
+ {
+ fb ^= 1;
+ if (fb)
+ goto rounding;
+ rb ^= 1;
+ if (rb == 0 && mpn_add_1(ap, ap, an, MPFR_LIMB_ONE << sh))
+ {
+ if (MPFR_UNLIKELY(exp == __gmpfr_emax))
+ {
+ inex = mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ goto end_of_add;
+ }
+ exp++;
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
+ }
+ } /* bb < cc */
+
+ if (!fb && bb != 0)
+ {
+ fb = 1;
+ goto rounding;
+ }
+ if (fb && bb != MP_LIMB_T_MAX)
+ goto rounding;
+ } /* while */
+
+ /* b has entirely been read */
+
+ if (fb || ck < 0)
+ goto rounding;
+ if (difs && cprev << (GMP_NUMB_BITS - difs))
+ {
+ fb = 1;
+ goto rounding;
+ }
+ while (ck)
+ {
+ if (cp[--ck])
+ {
+ fb = 1;
+ goto rounding;
+ }
+ } /* while */
+ } /* difw <= cn */
+ else
+ { /* c has entirely been read */
+ c_read:
+ if (fb < 0) /* fb not initialized yet */
+ {
+ mp_limb_t bb;
+
+ MPFR_ASSERTD(bk > 0);
+ bb = bp[--bk];
+ if (rb < 0) /* rb not initialized yet */
+ {
+ rb = bb >> (GMP_NUMB_BITS - 1);
+ bb &= ~MPFR_LIMB_HIGHBIT;
+ }
+ fb = bb != 0;
+ } /* fb < 0 */
+ if (fb)
+ goto rounding;
+ while (bk)
+ {
+ if (bp[--bk])
+ {
+ fb = 1;
+ goto rounding;
+ }
+ } /* while */
+ } /* difw > cn */
+ } /* bn > an */
+ else if (fb != 1) /* if fb == 1, the sticky bit is 1 (no possible carry) */
+ { /* b has entirely been read */
+ if (difw > cn)
+ { /* c has entirely been read */
+ if (rb < 0)
+ rb = 0;
+ fb = 0;
+ }
+ else if (diff_exp > MPFR_UEXP (aq2))
+ { /* b is followed by at least a zero bit, then by c */
+ if (rb < 0)
+ rb = 0;
+ fb = 1;
+ }
+ else
+ {
+ mp_size_t ck;
+ int difs;
+
+ MPFR_ASSERTD(difw >= 0 && cn >= difw);
+ ck = cn - difw;
+ difs = diff_exp % GMP_NUMB_BITS;
+
+ if (difs == 0 && ck == 0)
+ { /* c has entirely been read */
+ if (rb < 0)
+ rb = 0;
+ fb = 0;
+ }
+ else
+ {
+ mp_limb_t cc;
+
+ cc = difs ? (MPFR_ASSERTD(ck < cn),
+ cp[ck] << (GMP_NUMB_BITS - difs)) : cp[--ck];
+ if (rb < 0)
+ {
+ rb = cc >> (GMP_NUMB_BITS - 1);
+ cc &= ~MPFR_LIMB_HIGHBIT;
+ }
+ while (cc == 0)
+ {
+ if (ck == 0)
+ {
+ fb = 0;
+ goto rounding;
+ }
+ cc = cp[--ck];
+ } /* while */
+ fb = 1;
+ }
+ }
+ } /* fb != 1 */
+
+ rounding:
+ /* rnd_mode should be one of MPFR_RNDN, MPFR_RNDZ or MPFR_RNDA */
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ {
+ if (fb == 0)
+ {
+ if (rb == 0)
+ {
+ inex = 0;
+ goto set_exponent;
+ }
+ /* round to even */
+ if (ap[0] & (MPFR_LIMB_ONE << sh))
+ goto rndn_away;
+ else
+ goto rndn_zero;
+ }
+ if (rb == 0)
+ {
+ rndn_zero:
+ inex = MPFR_IS_NEG(a) ? 1 : -1;
+ goto set_exponent;
+ }
+ else
+ {
+ rndn_away:
+ inex = MPFR_IS_POS(a) ? 1 : -1;
+ goto add_one_ulp;
+ }
+ }
+ else if (rnd_mode == MPFR_RNDZ)
+ {
+ inex = rb || fb ? (MPFR_IS_NEG(a) ? 1 : -1) : 0;
+ goto set_exponent;
+ }
+ else
+ {
+ MPFR_ASSERTN (rnd_mode == MPFR_RNDA);
+ inex = rb || fb ? (MPFR_IS_POS(a) ? 1 : -1) : 0;
+ if (inex)
+ goto add_one_ulp;
+ else
+ goto set_exponent;
+ }
+
+ add_one_ulp: /* add one unit in last place to a */
+ if (MPFR_UNLIKELY(mpn_add_1 (ap, ap, an, MPFR_LIMB_ONE << sh)))
+ {
+ if (MPFR_UNLIKELY(exp == __gmpfr_emax))
+ {
+ inex = mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ goto end_of_add;
+ }
+ exp++;
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
+ }
+
+ set_exponent:
+ MPFR_SET_EXP (a, exp);
+
+ end_of_add:
+ MPFR_TMP_FREE(marker);
+ MPFR_RET (inex);
+}
diff --git a/mpfr/src/add1sp.c b/mpfr/src/add1sp.c
new file mode 100644
index 0000000000..91aa303410
--- /dev/null
+++ b/mpfr/src/add1sp.c
@@ -0,0 +1,387 @@
+/* mpfr_add1sp -- internal function to perform a "real" addition
+ All the op must have the same precision
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Check if we have to check the result of mpfr_add1sp with mpfr_add1 */
+#ifdef WANT_ASSERT
+# if WANT_ASSERT >= 2
+
+int mpfr_add1sp2 (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t);
+int mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t tmpa, tmpb, tmpc;
+ int inexb, inexc, inexact, inexact2;
+
+ mpfr_init2 (tmpa, MPFR_PREC (a));
+ mpfr_init2 (tmpb, MPFR_PREC (b));
+ mpfr_init2 (tmpc, MPFR_PREC (c));
+
+ inexb = mpfr_set (tmpb, b, MPFR_RNDN);
+ MPFR_ASSERTN (inexb == 0);
+
+ inexc = mpfr_set (tmpc, c, MPFR_RNDN);
+ MPFR_ASSERTN (inexc == 0);
+
+ inexact2 = mpfr_add1 (tmpa, tmpb, tmpc, rnd_mode);
+ inexact = mpfr_add1sp2 (a, b, c, rnd_mode);
+
+ if (mpfr_cmp (tmpa, a) || inexact != inexact2)
+ {
+ fprintf (stderr, "add1 & add1sp return different values for %s\n"
+ "Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nB = ",
+ mpfr_print_rnd_mode (rnd_mode),
+ (unsigned long) MPFR_PREC (a),
+ (unsigned long) MPFR_PREC (b),
+ (unsigned long) MPFR_PREC (c));
+ mpfr_fprint_binary (stderr, tmpb);
+ fprintf (stderr, "\nC = ");
+ mpfr_fprint_binary (stderr, tmpc);
+ fprintf (stderr, "\n\nadd1 : ");
+ mpfr_fprint_binary (stderr, tmpa);
+ fprintf (stderr, "\nadd1sp: ");
+ mpfr_fprint_binary (stderr, a);
+ fprintf (stderr, "\nInexact sp = %d | Inexact = %d\n",
+ inexact, inexact2);
+ MPFR_ASSERTN (0);
+ }
+ mpfr_clears (tmpa, tmpb, tmpc, (mpfr_ptr) 0);
+ return inexact;
+}
+# define mpfr_add1sp mpfr_add1sp2
+# endif
+#endif
+
+/* Debugging support */
+#ifdef DEBUG
+# undef DEBUG
+# define DEBUG(x) (x)
+#else
+# define DEBUG(x) /**/
+#endif
+
+/* compute sign(b) * (|b| + |c|)
+ Returns 0 iff result is exact,
+ a negative value when the result is less than the exact value,
+ a positive value otherwise. */
+int
+mpfr_add1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mpfr_uexp_t d;
+ mpfr_prec_t p;
+ unsigned int sh;
+ mp_size_t n;
+ mp_limb_t *ap, *cp;
+ mpfr_exp_t bx;
+ mp_limb_t limb;
+ int inexact;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_TMP_MARK(marker);
+
+ MPFR_ASSERTD(MPFR_PREC(a) == MPFR_PREC(b) && MPFR_PREC(b) == MPFR_PREC(c));
+ MPFR_ASSERTD(MPFR_IS_PURE_FP(b));
+ MPFR_ASSERTD(MPFR_IS_PURE_FP(c));
+ MPFR_ASSERTD(MPFR_GET_EXP(b) >= MPFR_GET_EXP(c));
+
+ /* Read prec and num of limbs */
+ p = MPFR_PREC(b);
+ n = MPFR_PREC2LIMBS (p);
+ MPFR_UNSIGNED_MINUS_MODULO(sh, p);
+ bx = MPFR_GET_EXP(b);
+ d = (mpfr_uexp_t) (bx - MPFR_GET_EXP(c));
+
+ DEBUG (printf ("New add1sp with diff=%lu\n", (unsigned long) d));
+
+ if (MPFR_UNLIKELY(d == 0))
+ {
+ /* d==0 */
+ DEBUG( mpfr_print_mant_binary("C= ", MPFR_MANT(c), p) );
+ DEBUG( mpfr_print_mant_binary("B= ", MPFR_MANT(b), p) );
+ bx++; /* exp + 1 */
+ ap = MPFR_MANT(a);
+ limb = mpn_add_n(ap, MPFR_MANT(b), MPFR_MANT(c), n);
+ DEBUG( mpfr_print_mant_binary("A= ", ap, p) );
+ MPFR_ASSERTD(limb != 0); /* There must be a carry */
+ limb = ap[0]; /* Get LSB (In fact, LSW) */
+ mpn_rshift(ap, ap, n, 1); /* Shift mantissa A */
+ ap[n-1] |= MPFR_LIMB_HIGHBIT; /* Set MSB */
+ ap[0] &= ~MPFR_LIMB_MASK(sh); /* Clear LSB bit */
+ if (MPFR_LIKELY((limb&(MPFR_LIMB_ONE<<sh)) == 0)) /* Check exact case */
+ { inexact = 0; goto set_exponent; }
+ /* Zero: Truncate
+ Nearest: Even Rule => truncate or add 1
+ Away: Add 1 */
+ if (MPFR_LIKELY(rnd_mode==MPFR_RNDN))
+ {
+ if (MPFR_LIKELY((ap[0]&(MPFR_LIMB_ONE<<sh))==0))
+ { inexact = -1; goto set_exponent; }
+ else
+ goto add_one_ulp;
+ }
+ MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(b));
+ if (rnd_mode==MPFR_RNDZ)
+ { inexact = -1; goto set_exponent; }
+ else
+ goto add_one_ulp;
+ }
+ else if (MPFR_UNLIKELY (d >= p))
+ {
+ if (MPFR_LIKELY (d > p))
+ {
+ /* d > p : Copy B in A */
+ /* Away: Add 1
+ Nearest: Trunc
+ Zero: Trunc */
+ if (MPFR_LIKELY (rnd_mode==MPFR_RNDN
+ || MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG (b))))
+ {
+ copy_set_exponent:
+ ap = MPFR_MANT (a);
+ MPN_COPY (ap, MPFR_MANT(b), n);
+ inexact = -1;
+ goto set_exponent;
+ }
+ else
+ {
+ copy_add_one_ulp:
+ ap = MPFR_MANT(a);
+ MPN_COPY (ap, MPFR_MANT(b), n);
+ goto add_one_ulp;
+ }
+ }
+ else
+ {
+ /* d==p : Copy B in A */
+ /* Away: Add 1
+ Nearest: Even Rule if C is a power of 2, else Add 1
+ Zero: Trunc */
+ if (MPFR_LIKELY(rnd_mode==MPFR_RNDN))
+ {
+ /* Check if C was a power of 2 */
+ cp = MPFR_MANT(c);
+ if (MPFR_UNLIKELY(cp[n-1] == MPFR_LIMB_HIGHBIT))
+ {
+ mp_size_t k = n-1;
+ do {
+ k--;
+ } while (k>=0 && cp[k]==0);
+ if (MPFR_UNLIKELY(k<0))
+ /* Power of 2: Even rule */
+ if ((MPFR_MANT (b)[0]&(MPFR_LIMB_ONE<<sh))==0)
+ goto copy_set_exponent;
+ }
+ /* Not a Power of 2 */
+ goto copy_add_one_ulp;
+ }
+ else if (MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG (b)))
+ goto copy_set_exponent;
+ else
+ goto copy_add_one_ulp;
+ }
+ }
+ else
+ {
+ mp_limb_t mask;
+ mp_limb_t bcp, bcp1; /* Cp and C'p+1 */
+
+ /* General case: 1 <= d < p */
+ cp = MPFR_TMP_LIMBS_ALLOC (n);
+
+ /* Shift c in temporary allocated place */
+ {
+ mpfr_uexp_t dm;
+ mp_size_t m;
+
+ dm = d % GMP_NUMB_BITS;
+ m = d / GMP_NUMB_BITS;
+ if (MPFR_UNLIKELY(dm == 0))
+ {
+ /* dm = 0 and m > 0: Just copy */
+ MPFR_ASSERTD(m!=0);
+ MPN_COPY(cp, MPFR_MANT(c)+m, n-m);
+ MPN_ZERO(cp+n-m, m);
+ }
+ else if (MPFR_LIKELY(m == 0))
+ {
+ /* dm >=1 and m == 0: just shift */
+ MPFR_ASSERTD(dm >= 1);
+ mpn_rshift(cp, MPFR_MANT(c), n, dm);
+ }
+ else
+ {
+ /* dm > 0 and m > 0: shift and zero */
+ mpn_rshift(cp, MPFR_MANT(c)+m, n-m, dm);
+ MPN_ZERO(cp+n-m, m);
+ }
+ }
+
+ DEBUG( mpfr_print_mant_binary("Before", MPFR_MANT(c), p) );
+ DEBUG( mpfr_print_mant_binary("B= ", MPFR_MANT(b), p) );
+ DEBUG( mpfr_print_mant_binary("After ", cp, p) );
+
+ /* Compute bcp=Cp and bcp1=C'p+1 */
+ if (MPFR_LIKELY (sh > 0))
+ {
+ /* Try to compute them from C' rather than C */
+ bcp = (cp[0] & (MPFR_LIMB_ONE<<(sh-1))) ;
+ if (MPFR_LIKELY(cp[0]&MPFR_LIMB_MASK(sh-1)))
+ bcp1 = 1;
+ else
+ {
+ /* We can't compute C'p+1 from C'. Compute it from C */
+ /* Start from bit x=p-d+sh in mantissa C
+ (+sh since we have already looked sh bits in C'!) */
+ mpfr_prec_t x = p-d+sh-1;
+ if (MPFR_LIKELY(x>p))
+ /* We are already looked at all the bits of c, so C'p+1 = 0*/
+ bcp1 = 0;
+ else
+ {
+ mp_limb_t *tp = MPFR_MANT(c);
+ mp_size_t kx = n-1 - (x / GMP_NUMB_BITS);
+ mpfr_prec_t sx = GMP_NUMB_BITS-1-(x%GMP_NUMB_BITS);
+ DEBUG (printf ("(First) x=%lu Kx=%ld Sx=%lu\n",
+ (unsigned long) x, (long) kx,
+ (unsigned long) sx));
+ /* Looks at the last bits of limb kx (if sx=0 does nothing)*/
+ if (tp[kx] & MPFR_LIMB_MASK(sx))
+ bcp1 = 1;
+ else
+ {
+ /*kx += (sx==0);*/
+ /*If sx==0, tp[kx] hasn't been checked*/
+ do {
+ kx--;
+ } while (kx>=0 && tp[kx]==0);
+ bcp1 = (kx >= 0);
+ }
+ }
+ }
+ }
+ else /* sh == 0 */
+ {
+ /* Compute Cp and C'p+1 from C with sh=0 */
+ mp_limb_t *tp = MPFR_MANT(c);
+ /* Start from bit x=p-d in mantissa C */
+ mpfr_prec_t x = p-d;
+ mp_size_t kx = n-1 - (x / GMP_NUMB_BITS);
+ mpfr_prec_t sx = GMP_NUMB_BITS-1-(x%GMP_NUMB_BITS);
+ MPFR_ASSERTD(p >= d);
+ bcp = tp[kx] & (MPFR_LIMB_ONE<<sx);
+ /* Looks at the last bits of limb kx (If sx=0, does nothing)*/
+ if (tp[kx]&MPFR_LIMB_MASK(sx))
+ bcp1 = 1;
+ else
+ {
+ do {
+ kx--;
+ } while (kx>=0 && tp[kx]==0);
+ bcp1 = (kx>=0);
+ }
+ }
+ DEBUG (printf("sh=%u Cp=%lu C'p+1=%lu\n", sh,
+ (unsigned long) bcp, (unsigned long) bcp1));
+
+ /* Clean shifted C' */
+ mask = ~MPFR_LIMB_MASK(sh);
+ cp[0] &= mask;
+
+ /* Add the mantissa c from b in a */
+ ap = MPFR_MANT(a);
+ limb = mpn_add_n (ap, MPFR_MANT(b), cp, n);
+ DEBUG( mpfr_print_mant_binary("Add= ", ap, p) );
+
+ /* Check for overflow */
+ if (MPFR_UNLIKELY (limb))
+ {
+ limb = ap[0] & (MPFR_LIMB_ONE<<sh); /* Get LSB */
+ mpn_rshift (ap, ap, n, 1); /* Shift mantissa*/
+ bx++; /* Fix exponent */
+ ap[n-1] |= MPFR_LIMB_HIGHBIT; /* Set MSB */
+ ap[0] &= mask; /* Clear LSB bit */
+ bcp1 |= bcp; /* Recompute C'p+1 */
+ bcp = limb; /* Recompute Cp */
+ DEBUG (printf ("(Overflow) Cp=%lu C'p+1=%lu\n",
+ (unsigned long) bcp, (unsigned long) bcp1));
+ DEBUG (mpfr_print_mant_binary ("Add= ", ap, p));
+ }
+
+ /* Round:
+ Zero: Truncate but could be exact.
+ Away: Add 1 if Cp or C'p+1 !=0
+ Nearest: Truncate but could be exact if Cp==0
+ Add 1 if C'p+1 !=0,
+ Even rule else */
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ {
+ if (MPFR_LIKELY(bcp == 0))
+ { inexact = MPFR_LIKELY(bcp1) ? -1 : 0; goto set_exponent; }
+ else if (MPFR_UNLIKELY(bcp1==0) && (ap[0]&(MPFR_LIMB_ONE<<sh))==0)
+ { inexact = -1; goto set_exponent; }
+ else
+ goto add_one_ulp;
+ }
+ MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(b));
+ if (rnd_mode == MPFR_RNDZ)
+ {
+ inexact = MPFR_LIKELY(bcp || bcp1) ? -1 : 0;
+ goto set_exponent;
+ }
+ else
+ {
+ if (MPFR_UNLIKELY(bcp==0 && bcp1==0))
+ { inexact = 0; goto set_exponent; }
+ else
+ goto add_one_ulp;
+ }
+ }
+ MPFR_ASSERTN(0);
+
+ add_one_ulp:
+ /* add one unit in last place to a */
+ DEBUG( printf("AddOneUlp\n") );
+ if (MPFR_UNLIKELY( mpn_add_1(ap, ap, n, MPFR_LIMB_ONE<<sh) ))
+ {
+ /* Case 100000x0 = 0x1111x1 + 1*/
+ DEBUG( printf("Pow of 2\n") );
+ bx++;
+ ap[n-1] = MPFR_LIMB_HIGHBIT;
+ }
+ inexact = 1;
+
+ set_exponent:
+ if (MPFR_UNLIKELY(bx > __gmpfr_emax)) /* Check for overflow */
+ {
+ DEBUG( printf("Overflow\n") );
+ MPFR_TMP_FREE(marker);
+ MPFR_SET_SAME_SIGN(a,b);
+ return mpfr_overflow(a, rnd_mode, MPFR_SIGN(a));
+ }
+ MPFR_SET_EXP (a, bx);
+ MPFR_SET_SAME_SIGN(a,b);
+
+ MPFR_TMP_FREE(marker);
+ MPFR_RET (inexact * MPFR_INT_SIGN (a));
+}
diff --git a/mpfr/src/add_d.c b/mpfr/src/add_d.c
new file mode 100644
index 0000000000..888511a26f
--- /dev/null
+++ b/mpfr/src/add_d.c
@@ -0,0 +1,52 @@
+/* mpfr_add_d -- add a multiple precision floating-point number
+ to a machine double precision float
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_add_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t d;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("b[%Pu]=%.*Rg c=%.20g rnd=%d",
+ mpfr_get_prec(b), mpfr_log_prec, b, c, rnd_mode),
+ ("a[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (a), mpfr_log_prec, a, inexact));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ inexact = mpfr_set_d (d, c, rnd_mode);
+ MPFR_ASSERTN (inexact == 0);
+
+ mpfr_clear_flags ();
+ inexact = mpfr_add (a, b, d, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
+ mpfr_clear (d);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (a, inexact, rnd_mode);
+}
diff --git a/mpfr/src/add_ui.c b/mpfr/src/add_ui.c
new file mode 100644
index 0000000000..aff6c67761
--- /dev/null
+++ b/mpfr/src/add_ui.c
@@ -0,0 +1,58 @@
+/* mpfr_add_ui -- add a floating-point number with a machine integer
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_add_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode)
+{
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%d rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y));
+
+ if (MPFR_LIKELY(u != 0) ) /* if u=0, do nothing */
+ {
+ mpfr_t uu;
+ mp_limb_t up[1];
+ unsigned long cnt;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
+ MPFR_ASSERTD (u == (mp_limb_t) u);
+ count_leading_zeros(cnt, (mp_limb_t) u);
+ up[0] = (mp_limb_t) u << cnt;
+
+ /* Optimization note: Exponent save/restore operations may be
+ removed if mpfr_add works even when uu is out-of-range. */
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
+ inex = mpfr_add(y, x, uu, rnd_mode);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range(y, inex, rnd_mode);
+ }
+ else
+ /* (unsigned long) 0 is assumed to be a real 0 (unsigned) */
+ return mpfr_set (y, x, rnd_mode);
+}
diff --git a/mpfr/src/agm.c b/mpfr/src/agm.c
new file mode 100644
index 0000000000..567bc46a5e
--- /dev/null
+++ b/mpfr/src/agm.c
@@ -0,0 +1,319 @@
+/* mpfr_agm -- arithmetic-geometric mean of two floating-point numbers
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* agm(x,y) is between x and y, so we don't need to save exponent range */
+int
+mpfr_agm (mpfr_ptr r, mpfr_srcptr op2, mpfr_srcptr op1, mpfr_rnd_t rnd_mode)
+{
+ int compare, inexact;
+ mp_size_t s;
+ mpfr_prec_t p, q;
+ mp_limb_t *up, *vp, *ufp, *vfp;
+ mpfr_t u, v, uf, vf, sc1, sc2;
+ mpfr_exp_t scaleop = 0, scaleit;
+ unsigned long n; /* number of iterations */
+ MPFR_ZIV_DECL (loop);
+ MPFR_TMP_DECL(marker);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("op2[%Pu]=%.*Rg op1[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (op2), mpfr_log_prec, op2,
+ mpfr_get_prec (op1), mpfr_log_prec, op1, rnd_mode),
+ ("r[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (r), mpfr_log_prec, r, inexact));
+
+ /* Deal with special values */
+ if (MPFR_ARE_SINGULAR (op1, op2))
+ {
+ /* If a or b is NaN, the result is NaN */
+ if (MPFR_IS_NAN(op1) || MPFR_IS_NAN(op2))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ /* now one of a or b is Inf or 0 */
+ /* If a and b is +Inf, the result is +Inf.
+ Otherwise if a or b is -Inf or 0, the result is NaN */
+ else if (MPFR_IS_INF(op1) || MPFR_IS_INF(op2))
+ {
+ if (MPFR_IS_STRICTPOS(op1) && MPFR_IS_STRICTPOS(op2))
+ {
+ MPFR_SET_INF(r);
+ MPFR_SET_SAME_SIGN(r, op1);
+ MPFR_RET(0); /* exact */
+ }
+ else
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ }
+ else /* a and b are neither NaN nor Inf, and one is zero */
+ { /* If a or b is 0, the result is +0 since a sqrt is positive */
+ MPFR_ASSERTD (MPFR_IS_ZERO (op1) || MPFR_IS_ZERO (op2));
+ MPFR_SET_POS (r);
+ MPFR_SET_ZERO (r);
+ MPFR_RET (0); /* exact */
+ }
+ }
+
+ /* If a or b is negative (excluding -Infinity), the result is NaN */
+ if (MPFR_UNLIKELY(MPFR_IS_NEG(op1) || MPFR_IS_NEG(op2)))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+
+ /* Precision of the following calculus */
+ q = MPFR_PREC(r);
+ p = q + MPFR_INT_CEIL_LOG2(q) + 15;
+ MPFR_ASSERTD (p >= 7); /* see algorithms.tex */
+ s = MPFR_PREC2LIMBS (p);
+
+ /* b (op2) and a (op1) are the 2 operands but we want b >= a */
+ compare = mpfr_cmp (op1, op2);
+ if (MPFR_UNLIKELY( compare == 0 ))
+ {
+ mpfr_set (r, op1, rnd_mode);
+ MPFR_RET (0); /* exact */
+ }
+ else if (compare > 0)
+ {
+ mpfr_srcptr t = op1;
+ op1 = op2;
+ op2 = t;
+ }
+
+ /* Now b (=op2) > a (=op1) */
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ MPFR_TMP_MARK(marker);
+
+ /* Main loop */
+ MPFR_ZIV_INIT (loop, p);
+ for (;;)
+ {
+ mpfr_prec_t eq;
+ unsigned long err = 0; /* must be set to 0 at each Ziv iteration */
+ MPFR_BLOCK_DECL (flags);
+
+ /* Init temporary vars */
+ MPFR_TMP_INIT (up, u, p, s);
+ MPFR_TMP_INIT (vp, v, p, s);
+ MPFR_TMP_INIT (ufp, uf, p, s);
+ MPFR_TMP_INIT (vfp, vf, p, s);
+
+ /* Calculus of un and vn */
+ retry:
+ MPFR_BLOCK (flags,
+ mpfr_mul (u, op1, op2, MPFR_RNDN);
+ /* mpfr_mul(...): faster since PREC(op) < PREC(u) */
+ mpfr_add (v, op1, op2, MPFR_RNDN);
+ /* mpfr_add with !=prec is still good */);
+ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags) || MPFR_UNDERFLOW (flags)))
+ {
+ mpfr_exp_t e1 , e2;
+
+ MPFR_ASSERTN (scaleop == 0);
+ e1 = MPFR_GET_EXP (op1);
+ e2 = MPFR_GET_EXP (op2);
+
+ /* Let's determine scaleop to avoid an overflow/underflow. */
+ if (MPFR_OVERFLOW (flags))
+ {
+ /* Let's recall that emin <= e1 <= e2 <= emax.
+ There has been an overflow. Thus e2 >= emax/2.
+ If the mpfr_mul overflowed, then e1 + e2 > emax.
+ If the mpfr_add overflowed, then e2 = emax.
+ We want: (e1 + scale) + (e2 + scale) <= emax,
+ i.e. scale <= (emax - e1 - e2) / 2. Let's take
+ scale = min(floor((emax - e1 - e2) / 2), -1).
+ This is OK, as:
+ 1. emin <= scale <= -1.
+ 2. e1 + scale >= emin. Indeed:
+ * If e1 + e2 > emax, then
+ e1 + scale >= e1 + (emax - e1 - e2) / 2 - 1
+ >= (emax + e1 - emax) / 2 - 1
+ >= e1 / 2 - 1 >= emin.
+ * Otherwise, mpfr_mul didn't overflow, therefore
+ mpfr_add overflowed and e2 = emax, so that
+ e1 > emin (see restriction below).
+ e1 + scale > emin - 1, thus e1 + scale >= emin.
+ 3. e2 + scale <= emax, since scale < 0. */
+ if (e1 + e2 > MPFR_EXT_EMAX)
+ {
+ scaleop = - (((e1 + e2) - MPFR_EXT_EMAX + 1) / 2);
+ MPFR_ASSERTN (scaleop < 0);
+ }
+ else
+ {
+ /* The addition necessarily overflowed. */
+ MPFR_ASSERTN (e2 == MPFR_EXT_EMAX);
+ /* The case where e1 = emin and e2 = emax is not supported
+ here. This would mean that the precision of e2 would be
+ huge (and possibly not supported in practice anyway). */
+ MPFR_ASSERTN (e1 > MPFR_EXT_EMIN);
+ scaleop = -1;
+ }
+
+ }
+ else /* underflow only (in the multiplication) */
+ {
+ /* We have e1 + e2 <= emin (so, e1 <= e2 <= 0).
+ We want: (e1 + scale) + (e2 + scale) >= emin + 1,
+ i.e. scale >= (emin + 1 - e1 - e2) / 2. let's take
+ scale = ceil((emin + 1 - e1 - e2) / 2). This is OK, as:
+ 1. 1 <= scale <= emax.
+ 2. e1 + scale >= emin + 1 >= emin.
+ 3. e2 + scale <= scale <= emax. */
+ MPFR_ASSERTN (e1 <= e2 && e2 <= 0);
+ scaleop = (MPFR_EXT_EMIN + 2 - e1 - e2) / 2;
+ MPFR_ASSERTN (scaleop > 0);
+ }
+
+ MPFR_ALIAS (sc1, op1, MPFR_SIGN (op1), e1 + scaleop);
+ MPFR_ALIAS (sc2, op2, MPFR_SIGN (op2), e2 + scaleop);
+ op1 = sc1;
+ op2 = sc2;
+ MPFR_LOG_MSG (("Exception in pre-iteration, scale = %"
+ MPFR_EXP_FSPEC "d\n", scaleop));
+ goto retry;
+ }
+
+ mpfr_clear_flags ();
+ mpfr_sqrt (u, u, MPFR_RNDN);
+ mpfr_div_2ui (v, v, 1, MPFR_RNDN);
+
+ scaleit = 0;
+ n = 1;
+ while (mpfr_cmp2 (u, v, &eq) != 0 && eq <= p - 2)
+ {
+ MPFR_BLOCK_DECL (flags2);
+
+ MPFR_LOG_MSG (("Iteration n = %lu\n", n));
+
+ retry2:
+ mpfr_add (vf, u, v, MPFR_RNDN); /* No overflow? */
+ mpfr_div_2ui (vf, vf, 1, MPFR_RNDN);
+ /* See proof in algorithms.tex */
+ if (4*eq > p)
+ {
+ mpfr_t w;
+ MPFR_BLOCK_DECL (flags3);
+
+ MPFR_LOG_MSG (("4*eq > p\n", 0));
+
+ /* vf = V(k) */
+ mpfr_init2 (w, (p + 1) / 2);
+ MPFR_BLOCK
+ (flags3,
+ mpfr_sub (w, v, u, MPFR_RNDN); /* e = V(k-1)-U(k-1) */
+ mpfr_sqr (w, w, MPFR_RNDN); /* e = e^2 */
+ mpfr_div_2ui (w, w, 4, MPFR_RNDN); /* e*= (1/2)^2*1/4 */
+ mpfr_div (w, w, vf, MPFR_RNDN); /* 1/4*e^2/V(k) */
+ );
+ if (MPFR_LIKELY (! MPFR_UNDERFLOW (flags3)))
+ {
+ mpfr_sub (v, vf, w, MPFR_RNDN);
+ err = MPFR_GET_EXP (vf) - MPFR_GET_EXP (v); /* 0 or 1 */
+ mpfr_clear (w);
+ break;
+ }
+ /* There has been an underflow because of the cancellation
+ between V(k-1) and U(k-1). Let's use the conventional
+ method. */
+ MPFR_LOG_MSG (("4*eq > p -> underflow\n", 0));
+ mpfr_clear (w);
+ mpfr_clear_underflow ();
+ }
+ /* U(k) increases, so that U.V can overflow (but not underflow). */
+ MPFR_BLOCK (flags2, mpfr_mul (uf, u, v, MPFR_RNDN););
+ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags2)))
+ {
+ mpfr_exp_t scale2;
+
+ scale2 = - (((MPFR_GET_EXP (u) + MPFR_GET_EXP (v))
+ - MPFR_EXT_EMAX + 1) / 2);
+ MPFR_EXP (u) += scale2;
+ MPFR_EXP (v) += scale2;
+ scaleit += scale2;
+ MPFR_LOG_MSG (("Overflow in iteration n = %lu, scaleit = %"
+ MPFR_EXP_FSPEC "d (%" MPFR_EXP_FSPEC "d)\n",
+ n, scaleit, scale2));
+ mpfr_clear_overflow ();
+ goto retry2;
+ }
+ mpfr_sqrt (u, uf, MPFR_RNDN);
+ mpfr_swap (v, vf);
+ n ++;
+ }
+
+ MPFR_LOG_MSG (("End of iterations (n = %lu)\n", n));
+
+ /* the error on v is bounded by (18n+51) ulps, or twice if there
+ was an exponent loss in the final subtraction */
+ err += MPFR_INT_CEIL_LOG2(18 * n + 51); /* 18n+51 should not overflow
+ since n is about log(p) */
+ /* we should have n+2 <= 2^(p/4) [see algorithms.tex] */
+ if (MPFR_LIKELY (MPFR_INT_CEIL_LOG2(n + 2) <= p / 4 &&
+ MPFR_CAN_ROUND (v, p - err, q, rnd_mode)))
+ break; /* Stop the loop */
+
+ /* Next iteration */
+ MPFR_ZIV_NEXT (loop, p);
+ s = MPFR_PREC2LIMBS (p);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ if (MPFR_UNLIKELY ((__gmpfr_flags & (MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT))
+ != 0))
+ {
+ MPFR_ASSERTN (! mpfr_overflow_p ()); /* since mpfr_clear_flags */
+ MPFR_ASSERTN (! mpfr_underflow_p ()); /* since mpfr_clear_flags */
+ MPFR_ASSERTN (! mpfr_divby0_p ()); /* since mpfr_clear_flags */
+ MPFR_ASSERTN (! mpfr_nanflag_p ()); /* since mpfr_clear_flags */
+ }
+
+ /* Setting of the result */
+ inexact = mpfr_set (r, v, rnd_mode);
+ MPFR_EXP (r) -= scaleop + scaleit;
+
+ /* Let's clean */
+ MPFR_TMP_FREE(marker);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ /* From the definition of the AGM, underflow and overflow
+ are not possible. */
+ return mpfr_check_range (r, inexact, rnd_mode);
+ /* agm(u,v) can be exact for u, v rational only for u=v.
+ Proof (due to Nicolas Brisebarre): it suffices to consider
+ u=1 and v<1. Then 1/AGM(1,v) = 2F1(1/2,1/2,1;1-v^2),
+ and a theorem due to G.V. Chudnovsky states that for x a
+ non-zero algebraic number with |x|<1, then
+ 2F1(1/2,1/2,1;x) and 2F1(-1/2,1/2,1;x) are algebraically
+ independent over Q. */
+}
diff --git a/mpfr/src/ai.c b/mpfr/src/ai.c
new file mode 100644
index 0000000000..19d9eb5c11
--- /dev/null
+++ b/mpfr/src/ai.c
@@ -0,0 +1,664 @@
+/* mpfr_ai -- Airy function Ai
+
+Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Reminder and notations:
+ -----------------------
+
+ Ai is the solution of:
+ / y'' - x*y = 0
+ { Ai(0) = 1/ ( 9^(1/3)*Gamma(2/3) )
+ \ Ai'(0) = -1/ ( 3^(1/3)*Gamma(1/3) )
+
+ Series development:
+ Ai(x) = sum (a_i*x^i)
+ = sum (t_i)
+
+ Recurrences:
+ a_(i+3) = a_i / ((i+2)*(i+3))
+ t_(i+3) = t_i * x^3 / ((i+2)*(i+3))
+
+ Values:
+ a_0 = Ai(0) ~ 0.355
+ a_1 = Ai'(0) ~ -0.259
+*/
+
+
+/* Airy function Ai evaluated by the most naive algorithm */
+static int
+mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+ mpfr_prec_t wprec; /* working precision */
+ mpfr_prec_t prec; /* target precision */
+ mpfr_prec_t err; /* used to estimate the evaluation error */
+ mpfr_prec_t correct_bits; /* estimates the number of correct bits*/
+ unsigned long int k;
+ unsigned long int cond; /* condition number of the series */
+ unsigned long int assumed_exponent; /* used as a lowerbound of |EXP(Ai(x))| */
+ int r;
+ mpfr_t s; /* used to store the partial sum */
+ mpfr_t ti, tip1; /* used to store successive values of t_i */
+ mpfr_t x3; /* used to store x^3 */
+ mpfr_t tmp_sp, tmp2_sp; /* small precision variables */
+ unsigned long int x3u; /* used to store ceil(x^3) */
+ mpfr_t temp1, temp2;
+ int test1, test2;
+
+ /* Logging */
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
+ ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y) );
+
+ /* Special cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ return mpfr_set_ui (y, 0, rnd);
+ }
+
+
+ /* Save current exponents range */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ if (MPFR_UNLIKELY (MPFR_IS_ZERO (x)))
+ {
+ mpfr_t y1, y2;
+ prec = MPFR_PREC (y) + 3;
+ mpfr_init2 (y1, prec);
+ mpfr_init2 (y2, prec);
+ MPFR_ZIV_INIT (loop, prec);
+
+ /* ZIV loop */
+ for (;;)
+ {
+ mpfr_gamma_one_and_two_third (y1, y2, prec); /* y2 = Gamma(2/3)(1 + delta1), |delta1| <= 2^{1-prec}. */
+
+ r = mpfr_set_ui (y1, 9, MPFR_RNDN);
+ MPFR_ASSERTD (r == 0);
+ mpfr_cbrt (y1, y1, MPFR_RNDN); /* y1 = cbrt(9)(1 + delta2), |delta2| <= 2^{-prec}. */
+ mpfr_mul (y1, y1, y2, MPFR_RNDN);
+ mpfr_ui_div (y1, 1, y1, MPFR_RNDN);
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (y1, prec - 3, MPFR_PREC (y), rnd)))
+ break;
+ MPFR_ZIV_NEXT (loop, prec);
+ }
+ r = mpfr_set (y, y1, rnd);
+ MPFR_ZIV_FREE (loop);
+ MPFR_SAVE_EXPO_FREE (expo);
+ mpfr_clear (y1);
+ mpfr_clear (y2);
+ return mpfr_check_range (y, r, rnd);
+ }
+
+ /* FIXME: underflow for large values of |x| ? */
+
+
+ /* Set initial precision */
+ /* If we compute sum(i=0, N-1, t_i), the relative error is bounded by */
+ /* 2*(4N)*2^(1-wprec)*C(|x|)/Ai(x) */
+ /* where C(|x|) = 1 if 0<=x<=1 */
+ /* and C(|x|) = (1/2)*x^(-1/4)*exp(2/3 x^(3/2)) if x >= 1 */
+
+ /* A priori, we do not know N, so we estimate it to ~ prec */
+ /* If 0<=x<=1, we estimate Ai(x) ~ 1/8 */
+ /* if 1<=x, we estimate Ai(x) ~ (1/4)*x^(-1/4)*exp(-2/3 * x^(3/2)) */
+ /* if x<=0, ????? */
+
+ /* We begin with 11 guard bits */
+ prec = MPFR_PREC (y)+11;
+ MPFR_ZIV_INIT (loop, prec);
+
+ /* The working precision is heuristically chosen in order to obtain */
+ /* approximately prec correct bits in the sum. To sum up: the sum */
+ /* is stopped when the *exact* sum gives ~ prec correct bit. And */
+ /* when it is stopped, the accuracy of the computed sum, with respect*/
+ /* to the exact one should be ~prec bits. */
+ mpfr_init2 (tmp_sp, MPFR_SMALL_PRECISION);
+ mpfr_init2 (tmp2_sp, MPFR_SMALL_PRECISION);
+ mpfr_abs (tmp_sp, x, MPFR_RNDU);
+ mpfr_pow_ui (tmp_sp, tmp_sp, 3, MPFR_RNDU);
+ mpfr_sqrt (tmp_sp, tmp_sp, MPFR_RNDU); /* tmp_sp ~ x^3/2 */
+
+ /* 0.96179669392597567 >~ 2/3 * log2(e). See algorithms.tex */
+ mpfr_set_str (tmp2_sp, "0.96179669392597567", 10, MPFR_RNDU);
+ mpfr_mul (tmp2_sp, tmp_sp, tmp2_sp, MPFR_RNDU);
+
+ /* cond represents the number of lost bits in the evaluation of the sum */
+ if ( (MPFR_IS_ZERO (x)) || (MPFR_GET_EXP (x) <= 0) )
+ cond = 0;
+ else
+ cond = mpfr_get_ui (tmp2_sp, MPFR_RNDU) - (MPFR_GET_EXP (x)-1)/4 - 1;
+
+ /* The variable assumed_exponent is used to store the maximal assumed */
+ /* exponent of Ai(x). More precisely, we assume that |Ai(x)| will be */
+ /* greater than 2^{-assumed_exponent}. */
+ if (MPFR_IS_ZERO (x))
+ assumed_exponent = 2;
+ else
+ {
+ if (MPFR_IS_POS (x))
+ {
+ if (MPFR_GET_EXP (x) <= 0)
+ assumed_exponent = 3;
+ else
+ assumed_exponent = (2 + (MPFR_GET_EXP (x)/4 + 1)
+ + mpfr_get_ui (tmp2_sp, MPFR_RNDU));
+ }
+ /* We do not know Ai (x) yet */
+ /* We cover the case when EXP (Ai (x))>=-10 */
+ else
+ assumed_exponent = 10;
+ }
+
+ wprec = prec + MPFR_INT_CEIL_LOG2 (prec) + 5 + cond + assumed_exponent;
+
+ mpfr_init (ti);
+ mpfr_init (tip1);
+ mpfr_init (temp1);
+ mpfr_init (temp2);
+ mpfr_init (x3);
+ mpfr_init (s);
+
+ /* ZIV loop */
+ for (;;)
+ {
+ MPFR_LOG_MSG (("Working precision: %Pu\n", wprec));
+ mpfr_set_prec (ti, wprec);
+ mpfr_set_prec (tip1, wprec);
+ mpfr_set_prec (x3, wprec);
+ mpfr_set_prec (s, wprec);
+
+ mpfr_sqr (x3, x, MPFR_RNDU);
+ mpfr_mul (x3, x3, x, (MPFR_IS_POS (x)?MPFR_RNDU:MPFR_RNDD)); /* x3=x^3 */
+ if (MPFR_IS_NEG (x))
+ MPFR_CHANGE_SIGN (x3);
+ x3u = mpfr_get_ui (x3, MPFR_RNDU); /* x3u >= ceil(x^3) */
+ if (MPFR_IS_NEG (x))
+ MPFR_CHANGE_SIGN (x3);
+
+ mpfr_gamma_one_and_two_third (temp1, temp2, wprec);
+ mpfr_set_ui (ti, 9, MPFR_RNDN);
+ mpfr_cbrt (ti, ti, MPFR_RNDN);
+ mpfr_mul (ti, ti, temp2, MPFR_RNDN);
+ mpfr_ui_div (ti, 1, ti , MPFR_RNDN); /* ti = 1/( Gamma (2/3)*9^(1/3) ) */
+
+ mpfr_set_ui (tip1, 3, MPFR_RNDN);
+ mpfr_cbrt (tip1, tip1, MPFR_RNDN);
+ mpfr_mul (tip1, tip1, temp1, MPFR_RNDN);
+ mpfr_neg (tip1, tip1, MPFR_RNDN);
+ mpfr_div (tip1, x, tip1, MPFR_RNDN); /* tip1 = -x/(Gamma (1/3)*3^(1/3)) */
+
+ mpfr_add (s, ti, tip1, MPFR_RNDN);
+
+
+ /* Evaluation of the series */
+ k = 2;
+ for (;;)
+ {
+ mpfr_mul (ti, ti, x3, MPFR_RNDN);
+ mpfr_mul (tip1, tip1, x3, MPFR_RNDN);
+
+ mpfr_div_ui2 (ti, ti, k, (k+1), MPFR_RNDN);
+ mpfr_div_ui2 (tip1, tip1, (k+1), (k+2), MPFR_RNDN);
+
+ k += 3;
+ mpfr_add (s, s, ti, MPFR_RNDN);
+ mpfr_add (s, s, tip1, MPFR_RNDN);
+
+ /* FIXME: if s==0 */
+ test1 = MPFR_IS_ZERO (ti)
+ || (MPFR_GET_EXP (ti) + (mpfr_exp_t)prec + 3 <= MPFR_GET_EXP (s));
+ test2 = MPFR_IS_ZERO (tip1)
+ || (MPFR_GET_EXP (tip1) + (mpfr_exp_t)prec + 3 <= MPFR_GET_EXP (s));
+
+ if ( test1 && test2 && (x3u <= k*(k+1)/2) )
+ break; /* FIXME: if k*(k+1) overflows */
+ }
+
+ MPFR_LOG_MSG (("Truncation rank: %lu\n", k));
+
+ err = 4 + MPFR_INT_CEIL_LOG2 (k) + cond - MPFR_GET_EXP (s);
+
+ /* err is the number of bits lost due to the evaluation error */
+ /* wprec-(prec+1): number of bits lost due to the approximation error */
+ MPFR_LOG_MSG (("Roundoff error: %Pu\n", err));
+ MPFR_LOG_MSG (("Approxim error: %Pu\n", wprec-prec-1));
+
+ if (wprec < err+1)
+ correct_bits=0;
+ else
+ {
+ if (wprec < err+prec+1)
+ correct_bits = wprec - err - 1;
+ else
+ correct_bits = prec;
+ }
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, correct_bits, MPFR_PREC (y), rnd)))
+ break;
+
+ if (correct_bits == 0)
+ {
+ assumed_exponent *= 2;
+ MPFR_LOG_MSG (("Not a single bit correct (assumed_exponent=%lu)\n",
+ assumed_exponent));
+ wprec = prec + 5 + MPFR_INT_CEIL_LOG2 (k) + cond + assumed_exponent;
+ }
+ else
+ {
+ if (correct_bits < prec)
+ { /* The precision was badly chosen */
+ MPFR_LOG_MSG (("Bad assumption on the exponent of Ai(x)", 0));
+ MPFR_LOG_MSG ((" (E=%ld)\n", (long) MPFR_GET_EXP (s)));
+ wprec = prec + err + 1;
+ }
+ else
+ { /* We are really in a bad case of the TMD */
+ MPFR_ZIV_NEXT (loop, prec);
+
+ /* We update wprec */
+ /* We assume that K will not be multiplied by more than 4 */
+ wprec = prec + (MPFR_INT_CEIL_LOG2 (k)+2) + 5 + cond
+ - MPFR_GET_EXP (s);
+ }
+ }
+
+ } /* End of ZIV loop */
+
+ MPFR_ZIV_FREE (loop);
+
+ r = mpfr_set (y, s, rnd);
+
+ mpfr_clear (ti);
+ mpfr_clear (tip1);
+ mpfr_clear (temp1);
+ mpfr_clear (temp2);
+ mpfr_clear (x3);
+ mpfr_clear (s);
+ mpfr_clear (tmp_sp);
+ mpfr_clear (tmp2_sp);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, r, rnd);
+}
+
+
+/* Airy function Ai evaluated by Smith algorithm */
+static int
+mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+ mpfr_prec_t wprec; /* working precision */
+ mpfr_prec_t prec; /* target precision */
+ mpfr_prec_t err; /* used to estimate the evaluation error */
+ mpfr_prec_t correctBits; /* estimates the number of correct bits*/
+ unsigned long int i, j, L, t;
+ unsigned long int cond; /* condition number of the series */
+ unsigned long int assumed_exponent; /* used as a lowerbound of |EXP(Ai(x))| */
+ int r; /* returned ternary value */
+ mpfr_t s; /* used to store the partial sum */
+ mpfr_t u0, u1;
+ mpfr_t *z; /* used to store the (x^3j) */
+ mpfr_t result;
+ mpfr_t tmp_sp, tmp2_sp; /* small precision variables */
+ unsigned long int x3u; /* used to store ceil (x^3) */
+ mpfr_t temp1, temp2;
+ int test0, test1;
+
+ /* Logging */
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
+ ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y));
+
+ /* Special cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ return mpfr_set_ui (y, 0, rnd);
+ }
+
+ /* Save current exponents range */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* FIXME: underflow for large values of |x| */
+
+
+ /* Set initial precision */
+ /* See the analysis for the naive evaluation */
+
+ /* We begin with 11 guard bits */
+ prec = MPFR_PREC (y) + 11;
+ MPFR_ZIV_INIT (loop, prec);
+
+ mpfr_init2 (tmp_sp, MPFR_SMALL_PRECISION);
+ mpfr_init2 (tmp2_sp, MPFR_SMALL_PRECISION);
+ mpfr_abs (tmp_sp, x, MPFR_RNDU);
+ mpfr_pow_ui (tmp_sp, tmp_sp, 3, MPFR_RNDU);
+ mpfr_sqrt (tmp_sp, tmp_sp, MPFR_RNDU); /* tmp_sp ~ x^3/2 */
+
+ /* 0.96179669392597567 >~ 2/3 * log2(e). See algorithms.tex */
+ mpfr_set_str (tmp2_sp, "0.96179669392597567", 10, MPFR_RNDU);
+ mpfr_mul (tmp2_sp, tmp_sp, tmp2_sp, MPFR_RNDU);
+
+ /* cond represents the number of lost bits in the evaluation of the sum */
+ if ( (MPFR_IS_ZERO (x)) || (MPFR_GET_EXP (x) <= 0) )
+ cond = 0;
+ else
+ cond = mpfr_get_ui (tmp2_sp, MPFR_RNDU) - (MPFR_GET_EXP (x) - 1)/4 - 1;
+
+ /* This variable is used to store the maximal assumed exponent of */
+ /* Ai (x). More precisely, we assume that |Ai (x)| will be greater than */
+ /* 2^{-assumedExp}. */
+ if (MPFR_IS_ZERO (x))
+ assumed_exponent = 2;
+ else
+ {
+ if (MPFR_IS_POS (x))
+ {
+ if (MPFR_GET_EXP (x) <= 0)
+ assumed_exponent = 3;
+ else
+ assumed_exponent = (2 + (MPFR_GET_EXP (x)/4 + 1)
+ + mpfr_get_ui (tmp2_sp, MPFR_RNDU));
+ }
+ /* We do not know Ai (x) yet */
+ /* We cover the case when EXP (Ai (x))>=-10 */
+ else
+ assumed_exponent = 10;
+ }
+
+ wprec = prec + MPFR_INT_CEIL_LOG2 (prec) + 6 + cond + assumed_exponent;
+
+ /* We assume that the truncation rank will be ~ prec */
+ L = __gmpfr_isqrt (prec);
+ MPFR_LOG_MSG (("size of blocks L = %lu\n", L));
+
+ z = (mpfr_t *) (*__gmp_allocate_func) ( (L + 1) * sizeof (mpfr_t) );
+ MPFR_ASSERTN (z != NULL);
+ for (j=0; j<=L; j++)
+ mpfr_init (z[j]);
+
+ mpfr_init (s);
+ mpfr_init (u0); mpfr_init (u1);
+ mpfr_init (result);
+ mpfr_init (temp1);
+ mpfr_init (temp2);
+
+ /* ZIV loop */
+ for (;;)
+ {
+ MPFR_LOG_MSG (("working precision: %Pu\n", wprec));
+
+ for (j=0; j<=L; j++)
+ mpfr_set_prec (z[j], wprec);
+ mpfr_set_prec (s, wprec);
+ mpfr_set_prec (u0, wprec); mpfr_set_prec (u1, wprec);
+ mpfr_set_prec (result, wprec);
+
+ mpfr_set_ui (u0, 1, MPFR_RNDN);
+ mpfr_set (u1, x, MPFR_RNDN);
+
+ mpfr_set_ui (z[0], 1, MPFR_RNDU);
+ mpfr_sqr (z[1], u1, MPFR_RNDU);
+ mpfr_mul (z[1], z[1], x, (MPFR_IS_POS (x) ? MPFR_RNDU : MPFR_RNDD) );
+
+ if (MPFR_IS_NEG (x))
+ MPFR_CHANGE_SIGN (z[1]);
+ x3u = mpfr_get_ui (z[1], MPFR_RNDU); /* x3u >= ceil (x^3) */
+ if (MPFR_IS_NEG (x))
+ MPFR_CHANGE_SIGN (z[1]);
+
+ for (j=2; j<=L ;j++)
+ {
+ if (j%2 == 0)
+ mpfr_sqr (z[j], z[j/2], MPFR_RNDN);
+ else
+ mpfr_mul (z[j], z[j-1], z[1], MPFR_RNDN);
+ }
+
+ mpfr_gamma_one_and_two_third (temp1, temp2, wprec);
+ mpfr_set_ui (u0, 9, MPFR_RNDN);
+ mpfr_cbrt (u0, u0, MPFR_RNDN);
+ mpfr_mul (u0, u0, temp2, MPFR_RNDN);
+ mpfr_ui_div (u0, 1, u0 , MPFR_RNDN); /* u0 = 1/( Gamma (2/3)*9^(1/3) ) */
+
+ mpfr_set_ui (u1, 3, MPFR_RNDN);
+ mpfr_cbrt (u1, u1, MPFR_RNDN);
+ mpfr_mul (u1, u1, temp1, MPFR_RNDN);
+ mpfr_neg (u1, u1, MPFR_RNDN);
+ mpfr_div (u1, x, u1, MPFR_RNDN); /* u1 = -x/(Gamma (1/3)*3^(1/3)) */
+
+ mpfr_set_ui (result, 0, MPFR_RNDN);
+ t = 0;
+
+ /* Evaluation of the series by Smith' method */
+ for (i=0; ; i++)
+ {
+ t += 3 * L;
+
+ /* k = 0 */
+ t -= 3;
+ mpfr_set (s, z[L-1], MPFR_RNDN);
+ for (j=L-2; ; j--)
+ {
+ t -= 3;
+ mpfr_div_ui2 (s, s, (t+2), (t+3), MPFR_RNDN);
+ mpfr_add (s, s, z[j], MPFR_RNDN);
+ if (j==0)
+ break;
+ }
+ mpfr_mul (s, s, u0, MPFR_RNDN);
+ mpfr_add (result, result, s, MPFR_RNDN);
+
+ mpfr_mul (u0, u0, z[L], MPFR_RNDN);
+ for (j=0; j<=L-1; j++)
+ {
+ mpfr_div_ui2 (u0, u0, (t + 2), (t + 3), MPFR_RNDN);
+ t += 3;
+ }
+
+ t++;
+
+ /* k = 1 */
+ t -= 3;
+ mpfr_set (s, z[L-1], MPFR_RNDN);
+ for (j=L-2; ; j--)
+ {
+ t -= 3;
+ mpfr_div_ui2 (s, s, (t + 2), (t + 3), MPFR_RNDN);
+ mpfr_add (s, s, z[j], MPFR_RNDN);
+ if (j==0)
+ break;
+ }
+ mpfr_mul (s, s, u1, MPFR_RNDN);
+ mpfr_add (result, result, s, MPFR_RNDN);
+
+ mpfr_mul (u1, u1, z[L], MPFR_RNDN);
+ for (j=0; j<=L-1; j++)
+ {
+ mpfr_div_ui2 (u1, u1, (t + 2), (t + 3), MPFR_RNDN);
+ t += 3;
+ }
+
+ t++;
+
+ /* k = 2 */
+ t++;
+
+ /* End of the loop over k */
+ t -= 3;
+
+ test0 = MPFR_IS_ZERO (u0) ||
+ MPFR_GET_EXP (u0) + (mpfr_exp_t)prec + 4 <= MPFR_GET_EXP (result);
+ test1 = MPFR_IS_ZERO (u1) ||
+ MPFR_GET_EXP (u1) + (mpfr_exp_t)prec + 4 <= MPFR_GET_EXP (result);
+
+ if ( test0 && test1 && (x3u <= (t + 2) * (t + 3) / 2) )
+ break;
+ }
+
+ MPFR_LOG_MSG (("Truncation rank: %lu\n", t));
+
+ err = (5 + MPFR_INT_CEIL_LOG2 (L+1) + MPFR_INT_CEIL_LOG2 (i+1)
+ + cond - MPFR_GET_EXP (result));
+
+ /* err is the number of bits lost due to the evaluation error */
+ /* wprec-(prec+1): number of bits lost due to the approximation error */
+ MPFR_LOG_MSG (("Roundoff error: %Pu\n", err));
+ MPFR_LOG_MSG (("Approxim error: %Pu\n", wprec - prec - 1));
+
+ if (wprec < err+1)
+ correctBits = 0;
+ else
+ {
+ if (wprec < err+prec+1)
+ correctBits = wprec - err - 1;
+ else
+ correctBits = prec;
+ }
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (result, correctBits,
+ MPFR_PREC (y), rnd)))
+ break;
+
+ for (j=0; j<=L; j++)
+ mpfr_clear (z[j]);
+ (*__gmp_free_func) (z, (L + 1) * sizeof (mpfr_t));
+ L = __gmpfr_isqrt (t);
+ MPFR_LOG_MSG (("size of blocks L = %lu\n", L));
+ z = (mpfr_t *) (*__gmp_allocate_func) ( (L + 1) * sizeof (mpfr_t));
+ MPFR_ASSERTN (z != NULL);
+ for (j=0; j<=L; j++)
+ mpfr_init (z[j]);
+
+ if (correctBits == 0)
+ {
+ assumed_exponent *= 2;
+ MPFR_LOG_MSG (("Not a single bit correct (assumed_exponent=%lu)\n",
+ assumed_exponent));
+ wprec = prec + 6 + MPFR_INT_CEIL_LOG2 (t) + cond + assumed_exponent;
+ }
+ else
+ {
+ if (correctBits < prec)
+ { /* The precision was badly chosen */
+ MPFR_LOG_MSG (("Bad assumption on the exponent of Ai (x)", 0));
+ MPFR_LOG_MSG ((" (E=%ld)\n", (long) (MPFR_GET_EXP (result))));
+ wprec = prec + err + 1;
+ }
+ else
+ { /* We are really in a bad case of the TMD */
+ MPFR_ZIV_NEXT (loop, prec);
+
+ /* We update wprec */
+ /* We assume that t will not be multiplied by more than 4 */
+ wprec = (prec + (MPFR_INT_CEIL_LOG2 (t) + 2) + 6 + cond
+ - MPFR_GET_EXP (result));
+ }
+ }
+ } /* End of ZIV loop */
+
+ MPFR_ZIV_FREE (loop);
+ MPFR_SAVE_EXPO_FREE (expo);
+
+ r = mpfr_set (y, result, rnd);
+
+ mpfr_clear (tmp_sp);
+ mpfr_clear (tmp2_sp);
+ for (j=0; j<=L; j++)
+ mpfr_clear (z[j]);
+ (*__gmp_free_func) (z, (L + 1) * sizeof (mpfr_t));
+
+ mpfr_clear (s);
+ mpfr_clear (u0); mpfr_clear (u1);
+ mpfr_clear (result);
+ mpfr_clear (temp1);
+ mpfr_clear (temp2);
+
+ return r;
+}
+
+/* We consider that the boundary between the area where the naive method
+ should preferably be used and the area where Smith' method should preferably
+ be used has the following form:
+ it is a triangle defined by two lines (one for the negative values of x, and
+ one for the positive values of x) crossing at x=0.
+
+ More precisely,
+
+ * If x<0 and MPFR_AI_THRESHOLD1*x + MPFR_AI_THRESHOLD2*prec > MPFR_AI_SCALE,
+ use Smith' algorithm;
+ * If x>0 and MPFR_AI_THRESHOLD3*x + MPFR_AI_THRESHOLD2*prec > MPFR_AI_SCALE,
+ use Smith' algorithm;
+ * otherwise, use the naive method.
+*/
+
+#define MPFR_AI_SCALE 1048576
+
+int
+mpfr_ai (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ mpfr_t temp1, temp2;
+ int use_ai2;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* The exponent range must be large enough for the computation of temp1. */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (temp1, MPFR_SMALL_PRECISION);
+ mpfr_init2 (temp2, MPFR_SMALL_PRECISION);
+
+ mpfr_set (temp1, x, MPFR_RNDN);
+ mpfr_set_si (temp2, MPFR_AI_THRESHOLD2, MPFR_RNDN);
+ mpfr_mul_ui (temp2, temp2, MPFR_PREC (y) > ULONG_MAX ?
+ ULONG_MAX : (unsigned long) MPFR_PREC (y), MPFR_RNDN);
+
+ if (MPFR_IS_NEG (x))
+ mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD1, MPFR_RNDN);
+ else
+ mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD3, MPFR_RNDN);
+
+ mpfr_add (temp1, temp1, temp2, MPFR_RNDN);
+ mpfr_clear (temp2);
+
+ use_ai2 = mpfr_cmp_si (temp1, MPFR_AI_SCALE) > 0;
+ mpfr_clear (temp1);
+
+ MPFR_SAVE_EXPO_FREE (expo); /* Ignore all previous exceptions. */
+
+ return use_ai2 ? mpfr_ai2 (y, x, rnd) : mpfr_ai1 (y, x, rnd);
+}
diff --git a/mpfr/src/amd/amdfam10/mparam.h b/mpfr/src/amd/amdfam10/mparam.h
new file mode 100644
index 0000000000..b5b1d81a51
--- /dev/null
+++ b/mpfr/src/amd/amdfam10/mparam.h
@@ -0,0 +1,236 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2011-07-31, gcc 4.6.1 */
+/* contributed by Jim Cloos <cloos at jhcloos dot com> with GMP 5.0.2 on a
+ "2009 or 2010 vintage phenom-II", where __amd64, __amd64__,
+ __k8, __k8__, __x86_64 and __x86_64__ are also defined.
+*/
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,9,10,11, \
+ 12,12,12,14,14,14,16,16,18,18,19,20,18,22,20,20, \
+ 20,20,20,20,22,22,22,24,28,28,28,28,28,28,32,32, \
+ 30,32,32,32,32,32,32,38,38,38,38,40,40,40,40,40, \
+ 40,40,44,44,48,48,44,46,48,48,56,56,56,56,56,56, \
+ 56,56,56,60,64,60,64,64,64,64,64,64,64,64,64,64, \
+ 60,64,64,72,64,64,72,72,64,64,64,72,80,72,80,76, \
+ 76,80,76,80,80,80,80,76,80,79,80,80,80,80,80,80, \
+ 81,80,86,93,90,87,93,93,93,93,92,93,93,92,93,92, \
+ 93,93,93,93,102,105,105,104,105,105,105,105,105,105,111,116, \
+ 111,110,111,117,117,111,114,116,117,117,117,117,117,116,116,117, \
+ 116,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, \
+ 117,117,117,117,117,117,117,117,117,148,148,156,148,148,148,148, \
+ 148,156,156,156,155,156,156,156,156,156,156,156,156,156,155,156, \
+ 156,156,156,156,172,156,172,172,172,156,172,156,172,172,172,172, \
+ 172,172,172,172,172,172,172,180,172,180,172,172,172,188,188,172, \
+ 188,188,188,188,188,188,179,188,188,188,188,188,188,188,188,188, \
+ 188,220,220,220,220,188,220,220,220,220,220,220,220,220,220,220, \
+ 220,220,220,220,220,220,220,220,220,220,220,220,220,219,220,220, \
+ 220,220,220,220,236,220,220,220,252,252,236,252,252,252,252,236, \
+ 236,236,252,236,252,252,236,252,236,252,252,252,252,251,250,252, \
+ 252,252,252,252,252,252,252,252,252,252,252,252,251,252,252,251, \
+ 252,252,252,252,252,252,252,252,252,252,252,252,252,252,284,284, \
+ 252,284,284,284,284,284,284,284,284,284,284,284,284,284,283,284, \
+ 284,283,284,284,300,300,300,284,284,300,284,284,298,300,316,316, \
+ 300,284,300,316,300,316,300,284,316,316,316,316,300,316,300,316, \
+ 316,300,316,300,316,316,315,316,316,316,316,316,316,316,316,316, \
+ 316,316,316,316,313,316,316,316,316,316,316,316,320,316,320,368, \
+ 316,316,316,368,368,368,367,368,368,368,368,368,368,368,368,368, \
+ 367,367,368,368,368,368,368,368,368,368,368,368,368,368,368,368, \
+ 368,368,368,366,368,368,367,368,368,367,368,368,368,368,368,368, \
+ 367,366,367,368,368,367,368,368,368,368,368,368,368,368,368,368, \
+ 368,368,368,368,368,368,368,368,416,368,368,368,368,368,368,416, \
+ 368,416,415,416,416,368,416,416,416,415,415,416,416,416,416,416, \
+ 416,416,415,416,416,415,416,416,440,416,415,416,416,415,416,415, \
+ 416,416,416,474,415,416,416,415,416,416,416,416,416,416,474,474, \
+ 488,474,440,440,488,488,504,473,504,474,504,504,503,503,503,503, \
+ 503,504,501,504,504,503,474,474,503,504,504,503,504,488,488,488, \
+ 503,503,504,504,504,504,504,504,501,503,504,503,504,504,499,504, \
+ 504,503,504,504,504,504,503,504,504,504,488,504,504,504,474,504, \
+ 501,504,504,501,504,503,504,504,504,504,504,504,504,504,503,504, \
+ 504,503,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,503,568,568,568,504,504,504,504,568,504, \
+ 568,567,568,568,568,568,567,568,567,568,567,600,568,600,568,568, \
+ 568,568,568,567,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,567,568,568,568,568,568,568,568,568, \
+ 568,568,568,632,600,568,568,568,565,568,568,568,632,568,568,600, \
+ 600,631,600,632,600,632,632,600,600,632,600,600,632,600,600,600, \
+ 632,616,600,632,600,632,632,600,600,600,600,600,600,632,600,632, \
+ 632,616,632,632,632,616,632,632,632,627,631,629,632,632,631,632, \
+ 632,632,632,632,632,632,632,632,632,632,632,632,632,632,632,632, \
+ 632,632,632,632,687,629,688,632,632,632,632,632,632,632,632,632, \
+ 688,712,632,688,712,688,712,712,688,688,688,711,712,712,680,736, \
+ 712,712,712,688,688,712,712,712,712,712,712,728,712,736,736,711, \
+ 733,736,735,711,728,728,736,728,712,736,736,710,734,736,736,712, \
+ 712,736,712,712,719,728,712,712,712,734,733,726,736,736,736,735, \
+ 736,736,736,712,736,736,736,736,736,736,727,736,736,736,735,736, \
+ 731,736,736,736,736,736,736,736,733,712,736,736,736,736,736,712, \
+ 712,736,736,784,712,712,736,725,760,760,736,727,736,830,736,784, \
+ 728,736,727,783,832,736,734,830,736,736,831,736,736,830,829,832, \
+ 832,832,831,736,782,784,832,828,736,824,736,832,832,831,736,824, \
+ 824,832,832,832,832,832,832,825,832,832,832,824,832,832,832,828, \
+ 822,824,831,829,832,827,832,832,832,831,832,829,829,832,824,832, \
+ 830,832,832,832,832,832,830,832,832,832,832,828,855,832,830,830 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,-1,-1,-1,-1,-1,-1,7,8,9,8,9,9, \
+ 11,11,11,13,13,14,15,16,17,17,19,19,16,19,17,19, \
+ 19,18,19,19,21,21,21,23,23,25,25,23,25,25,25,25, \
+ 28,27,27,29,29,28,31,31,34,34,34,34,38,36,38,38, \
+ 42,42,42,42,42,42,44,46,42,46,44,50,46,50,42,50, \
+ 44,44,46,50,50,50,50,50,50,50,50,50,50,50,50,50, \
+ 52,50,54,54,54,54,56,56,56,56,58,56,56,58,58,60, \
+ 60,62,62,67,62,68,72,68,68,72,68,76,72,72,72,76, \
+ 76,76,76,76,84,72,84,76,76,76,84,76,76,84,84,84, \
+ 92,84,84,84,84,84,92,92,92,92,92,92,92,92,92,100, \
+ 92,92,100,100,92,100,100,100,100,100,100,92,100,100,92,100, \
+ 100,100,92,92,100,92,100,104,100,108,100,100,100,108,104,100, \
+ 100,104,100,108,108,108,112,108,112,112,112,123,112,123,112,135, \
+ 116,123,123,135,123,135,135,135,135,135,135,135,135,135,135,135, \
+ 135,135,147,135,135,135,135,147,147,147,147,147,147,147,147,147, \
+ 147,147,147,147,147,147,147,147,147,147,147,159,147,147,147,147, \
+ 165,147,147,159,153,147,147,147,165,159,147,147,165,153,147,159, \
+ 165,165,165,165,165,171,171,159,165,159,165,165,165,165,165,165, \
+ 171,165,171,171,165,177,171,171,189,183,171,165,165,165,183,165, \
+ 165,165,183,183,186,189,165,189,165,171,165,165,189,165,183,183, \
+ 183,189,183,201,201,189,189,183,189,183,195,189,189,189,183,213, \
+ 183,183,195,195,213,189,189,189,201,201,189,195,213,225,225,201, \
+ 201,213,213,195,213,201,225,225,225,225,225,224,225,225,213,225, \
+ 225,225,225,225,225,225,225,225,225,225,225,225,225,225,249,225, \
+ 249,249,248,225,249,249,249,249,249,249,225,249,249,248,249,249, \
+ 249,249,249,248,249,249,249,249,249,249,249,249,249,249,249,249, \
+ 249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, \
+ 273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273, \
+ 273,273,273,273,273,273,273,273,273,273,297,297,297,297,297,296, \
+ 297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, \
+ 297,297,297,297,297,297,297,297,297,273,273,273,273,273,273,296, \
+ 273,309,297,321,321,297,297,297,297,297,297,296,297,297,297,296, \
+ 297,296,297,297,297,297,297,297,297,297,297,297,297,297,309,297, \
+ 297,297,309,297,297,297,297,297,297,297,321,297,321,333,297,366, \
+ 333,333,333,366,333,296,333,333,333,297,333,333,333,297,297,321, \
+ 321,345,402,345,402,402,402,402,402,402,402,402,402,402,402,402, \
+ 401,401,402,402,402,402,402,402,402,402,402,402,401,402,402,401, \
+ 402,402,402,402,401,402,402,402,402,402,401,402,402,401,401,402, \
+ 401,401,393,402,402,438,401,402,402,401,401,402,401,402,402,402, \
+ 402,401,402,402,402,402,402,402,402,402,402,401,402,401,402,401, \
+ 402,402,400,402,402,402,402,402,402,402,438,438,438,438,438,438, \
+ 438,438,402,438,402,402,402,402,438,438,402,438,401,402,438,438, \
+ 438,438,438,438,438,438,401,437,438,402,401,402,438,401,402,402, \
+ 402,402,402,402,401,437,438,438,438,437,438,438,401,402,402,438, \
+ 438,438,402,402,402,402,401,402,402,437,438,438,438,438,438,438, \
+ 438,438,438,438,437,437,438,438,438,438,438,438,438,437,437,438, \
+ 437,438,438,438,438,402,438,402,438,438,438,438,438,438,437,438, \
+ 456,438,438,438,438,437,438,438,438,438,437,438,438,438,437,438, \
+ 438,438,438,473,437,456,438,438,438,438,438,437,438,438,438,438, \
+ 438,438,437,438,438,438,438,438,456,474,455,456,456,474,473,492, \
+ 456,474,456,474,474,474,474,474,536,512,474,512,474,536,474,474, \
+ 536,474,536,536,474,474,536,536,536,536,536,536,536,536,536,536, \
+ 536,534,536,536,536,535,536,536,536,536,535,536,536,536,536,536, \
+ 536,535,536,535,536,536,512,536,536,536,536,536,536,535,536,534, \
+ 535,584,536,536,536,534,535,536,536,536,536,536,536,536,536,534, \
+ 536,536,536,536,535,536,584,535,536,584,536,536,536,536,584,584, \
+ 584,584,536,584,584,584,584,584,584,584,583,584,582,584,584,584, \
+ 584,584,584,584,584,582,583,584,584,584,584,584,584,584,584,584, \
+ 584,583,584,584,696,584,584,583,584,584,696,726,696,584,584,584, \
+ 728,696,696,696,584,728,696,584,696,696,694,696,696,696,727,584, \
+ 695,694,584,696,696,695,728,696,696,696,696,696,694,696,727,695, \
+ 696,695,695,696,696,728,696,696,695,696,696,696,696,696,696,696, \
+ 727,696,696,696,696,695,696,728,727,696,695,727,696,726,727,726, \
+ 727,728,728,727,694,727,728,728,728,727,727,728,727,728,727,728 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,8,9,10,11,10,13,14,15, \
+ 14,15,18,19,18,14,15,18,18,18,19,17,18,19,18,19, \
+ 22,21,23,21,22,22,23,25,26,27,26,27,27,27,30,30, \
+ 30,34,30,34,32,33,34,31,30,34,37,34,38,38,38,38, \
+ 38,38,42,43,42,42,39,38,42,44,43,42,40,45,46,46, \
+ 46,45,46,43,44,50,48,48,48,46,53,51,50,50,50,50, \
+ 53,51,53,53,53,53,55,55,55,55,55,55,60,64,60,60, \
+ 62,63,64,65,60,64,68,72,64,68,68,64,64,68,72,66, \
+ 67,69,71,72,76,80,71,72,76,74,74,76,76,77,76,80, \
+ 79,84,84,84,78,84,88,88,92,84,80,92,92,80,88,84, \
+ 92,88,91,92,92,92,93,95,92,90,92,92,92,92,92,96, \
+ 96,96,92,92,92,92,96,96,102,96,95,110,96,96,100,100, \
+ 112,100,100,106,106,110,112,110,110,111,110,120,110,110,112,120, \
+ 110,120,120,120,112,120,128,128,128,128,124,128,128,120,128,128, \
+ 127,128,124,128,128,128,128,126,128,128,128,128,136,140,128,128, \
+ 128,128,136,144,128,128,144,144,128,144,144,144,144,128,152,152, \
+ 152,152,152,160,160,152,144,144,152,151,144,143,152,144,144,152, \
+ 152,144,152,152,152,152,151,152,160,158,144,160,160,160,160,160, \
+ 152,160,152,152,152,160,152,160,160,156,158,160,160,160,160,160, \
+ 160,160,160,160,168,160,160,160,160,160,159,160,160,160,176,176, \
+ 180,176,176,184,184,186,184,184,184,184,186,184,186,172,176,192, \
+ 184,184,184,184,185,176,176,185,184,185,186,183,184,184,181,191, \
+ 192,184,184,185,192,192,192,186,192,192,192,192,192,191,196,192, \
+ 192,192,192,192,196,190,192,192,200,192,198,220,222,204,200,222, \
+ 220,220,222,222,224,222,222,219,222,222,224,224,220,222,220,224, \
+ 220,221,222,220,232,222,221,232,222,220,224,232,220,232,222,232, \
+ 224,220,220,222,222,222,221,222,220,220,222,222,224,224,224,222, \
+ 220,224,224,232,224,222,222,232,224,222,223,224,224,224,231,232, \
+ 256,232,231,232,239,232,239,234,238,238,239,232,239,232,256,256, \
+ 288,288,248,256,256,256,256,256,256,239,255,256,256,256,256,256, \
+ 256,256,256,256,256,256,296,256,254,256,256,272,272,272,256,256, \
+ 288,272,256,256,280,296,288,280,288,288,296,280,288,288,288,294, \
+ 296,296,294,304,288,287,288,296,304,304,288,303,304,296,288,312, \
+ 312,312,312,288,288,312,288,288,312,320,305,288,320,320,288,312, \
+ 311,312,312,312,304,304,312,304,319,296,288,310,312,288,288,320, \
+ 304,304,304,288,300,312,309,304,304,311,288,296,296,320,312,311, \
+ 296,320,312,304,304,312,312,320,296,320,312,296,305,312,304,303, \
+ 304,312,303,312,304,311,312,312,320,312,311,320,320,320,320,320, \
+ 312,320,312,312,312,320,312,312,320,320,319,320,320,320,320,320, \
+ 320,320,320,320,320,320,320,320,320,320,320,320,320,320,352,336, \
+ 344,352,352,344,360,360,343,336,352,366,370,352,360,368,376,360, \
+ 360,360,367,368,360,352,371,360,368,368,372,352,352,352,352,352, \
+ 384,370,360,368,384,372,375,360,368,368,368,368,368,368,384,372, \
+ 352,372,352,368,366,376,352,367,384,368,360,368,360,384,371,376, \
+ 360,366,368,368,360,369,371,367,368,369,384,376,368,372,372,384, \
+ 440,368,376,384,372,376,440,440,376,440,368,369,384,370,440,440, \
+ 440,392,440,440,384,384,440,440,448,440,440,440,440,440,440,440, \
+ 440,440,384,440,439,440,384,384,440,440,440,440,440,440,439,448, \
+ 440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440, \
+ 440,440,440,440,440,440,439,440,440,440,440,440,440,440,440,440, \
+ 440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,480, \
+ 440,440,440,440,468,480,440,440,440,440,440,464,440,440,440,440, \
+ 480,440,440,440,440,448,439,440,440,440,440,440,440,448,440,448, \
+ 512,439,440,448,440,440,440,438,440,440,440,440,496,440,465,440, \
+ 440,466,440,440,440,440,512,440,440,440,440,464,440,440,448,466, \
+ 512,496,512,512,512,448,512,447,448,468,472,448,480,464,480,512, \
+ 466,466,496,468,512,468,496,480,512,512,496,467,472,512,512,512, \
+ 512,468,512,512,512,512,512,478,512,472,512,512,512,496,512,512, \
+ 512,512,512,512,496,480,496,496,512,512,512,496,480,512,544,480, \
+ 576,512,512,576,512,512,512,576,512,512,496,496,512,480,576,576, \
+ 512,510,496,568,576,576,496,560,576,511,512,576,576,512,512,576, \
+ 560,496,576,512,512,512,512,512,512,576,576,512,512,576,512,512, \
+ 512,512,576,512,512,512,508,512,576,512,576,576,512,576,592,512, \
+ 568,512,576,568,576,576,576,512,576,576,592,576,592,512,608,576 \
+
+#define MPFR_MUL_THRESHOLD 17 /* limbs */
+#define MPFR_SQR_THRESHOLD 19 /* limbs */
+#define MPFR_DIV_THRESHOLD 28 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 1031 /* bits */
+#define MPFR_EXP_THRESHOLD 10625 /* bits */
+#define MPFR_SINCOS_THRESHOLD 26682 /* bits */
+#define MPFR_AI_THRESHOLD1 -11328 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 1045
+#define MPFR_AI_THRESHOLD3 17871
+/* Tuneup completed successfully, took 562 seconds */
diff --git a/mpfr/src/amd/athlon/mparam.h b/mpfr/src/amd/athlon/mparam.h
new file mode 100644
index 0000000000..3a48522171
--- /dev/null
+++ b/mpfr/src/amd/athlon/mparam.h
@@ -0,0 +1,90 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,-1,0,-1,0,-1,-1,0,-1,-1,0,0,0,0,10, \
+ 0,12,13,14,15,16,0,0,0,0,0,19,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32, \
+ 30,32,30,34,32,32,36,34,36,36,38,38,42,38,38,42, \
+ 40,38,42,46,42,42,42,44,44,44,44,44,48,50,46,46, \
+ 60,50,50,48,50,56,56,56,56,56,56,56,60,60,64,60, \
+ 64,64,60,60,60,72,64,64,68,72,76,72,76,72,72,76, \
+ 75,76,76,72,76,72,75,72,72,72,84,76,84,75,72,76, \
+ 84,80,76,84,84,76,76,76,76,88,84,88,80,84,83,96, \
+ 84,96,92,84,88,91,92,88,92,90,96,96,92,91,92,96, \
+ 96,120,95,100,112,120,100,119,112,120,120,112,119,112,119,119, \
+ 120,118,119,119,119,118,119,120,128,127,120,128,128,120,120,127, \
+ 120,128,128,128,128,120,128,127,120,128,128,127,128,127,144,136, \
+ 128,144,152,152,152,136,144,144,144,136,151,152,144,152,128,151, \
+ 144,152,144,144,151,144,150,150,136,151,152,143,143,143,142,168, \
+ 144,144,168,151,168,144,152,151,152,152,160,152,151,152,160,151, \
+ 152,151,152,167,152,152,166,152,167,160,168,204,160,160,168,168, \
+ 204,176,202,167,168,166,167,168,204,184,202,204,204,204,204,192, \
+ 184,192,204,202,202,216,204,227,202,204,216,203,203,204,203,227, \
+ 202,204,202,202,202,203,202,215,204,202,203,202,202,215,228,214, \
+ 226,214,228,214,228,215,228,216,226,214,228,225,226,228,226,226, \
+ 226,215,216,216,226,225,226,227,216,227,240,216,252,252,226,227, \
+ 228,239,227,250,227,226,227,227,252,238,228,239,252,227,228,228, \
+ 252,226,246,228,227,227,252,247,250,263,262,250,252,250,250,252, \
+ 250,288,288,250,250,250,251,264,264,271,287,276,250,288,252,286, \
+ 251,287,288,251,276,274,288,262,263,263,282,252,288,252,276,284, \
+ 287,274,264,274,288,275,275,274,274,288,276,264,273,286,274,276, \
+ 300,287,288,286,286,276,288,285,275,300,275,273,275,299,300,299, \
+ 279,336,336,286,287,284,360,359,336,335,288,360,333,359,334,335, \
+ 335,287,359,335,336,336,359,333,334,359,360,288,360,332,335,336, \
+ 335,336,336,333,336,335,336,359,334,334,335,360,336,334,356,357, \
+ 335,336,358,359,359,336,335,336,334,355,384,356,354,384,334,357, \
+ 336,359,384,359,360,356,384,382,336,383,384,384,354,355,383,384, \
+ 382,359,384,382,382,383,383,359,381,382,383,356,384,382,381,384, \
+ 357,384,358,357,358,358,380,383,382,382,383,360,360,381,382,360, \
+ 377,360,378,360,360,381,382,383,381,380,383,383,360,382,383,380, \
+ 383,383,384,381,379,360,381,381,382,431,380,380,378,380,384,381, \
+ 382,382,384,407,384,382,379,384,430,431,383,384,408,384,456,431, \
+ 431,455,431,428,384,454,455,403,432,383,407,430,430,456,408,427, \
+ 455,455,456,455,432,431,431,429,455,432,432,424,430,427,427,429, \
+ 452,454,426,455,456,431,430,454,452,454,431,456,431,428,455,430, \
+ 454,430,432,455,454,442,443,432,443,431,451,452,456,430,451,456, \
+ 444,455,449,456,432,454,449,454,502,432,448,504,450,503,503,453, \
+ 454,502,446,452,453,454,455,499,504,453,456,504,454,453,503,455, \
+ 456,456,500,478,502,454,456,499,478,454,480,499,501,496,502,455, \
+ 499,502,503,456,478,500,501,500,479,503,504,451,452,479,454,455, \
+ 502,503,504,504,454,499,503,501,454,503,456,503,504,501,455,502, \
+ 503,503,502,504,610,503,504,574,480,551,528,504,609,576,480,503, \
+ 496,502,503,552,551,552,551,503,504,503,610,608,609,610,611,608, \
+ 608,551,648,611,612,550,576,572,608,611,610,606,608,611,610,574, \
+ 575,576,606,607,606,606,608,606,606,575,576,604,604,604,608,609, \
+ 606,606,606,608,604,604,611,604,604,576,610,606,610,606,604,610, \
+ 606,612,604,608,610,609,604,608,606,647,612,610,604,606,648,610, \
+ 610,606,646,608,604,647,606,647,606,609,610,647,648,609,641,611, \
+ 643,611,643,648,643,640,646,611,644,644,645,611,642,646,611,612, \
+ 640,647,610,611,610,611,606,647,648,647,648,644,682,642,682,683, \
+ 610,611,680,678,642,681,682,647,682,612,682,648,611,665,680,683, \
+ 609,646,666,676,680,646,679,647,646,646,648,679,684,611,612,643, \
+ 684,645,646,647,683,647,608,645,682,647,682,646,610,648,682,610, \
+ 684,612,612,683,684,647,647,646,680,646,646,745,648,646,644,647, \
+ 648,647,678,646,647,683,642,682,682,684,646,645,642,647,646,677, \
+ 646,647,683,678,680,646,646,643,681,647,683,645,666,755,756,645, \
+ 643,647,646,647,647,648,674,755,756,674,647,643,680,682,684,680, \
+ 680,682,682,675,682,677,666,683,680,682,682,684,680,681,674,674 \
+
+#define MPFR_MUL_THRESHOLD 19
+#define MPFR_EXP_2_THRESHOLD 411 /* bits */
+#define MPFR_EXP_THRESHOLD 45200 /* bits */
diff --git a/mpfr/src/amd/k8/mparam.h b/mpfr/src/amd/k8/mparam.h
new file mode 100644
index 0000000000..4f6b348868
--- /dev/null
+++ b/mpfr/src/amd/k8/mparam.h
@@ -0,0 +1,236 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2011-07-31, gcc 4.3.2 */
+/* gcc11.fsffrance.org (Dual-Core AMD Opteron(tm) Processor 2212)
+ with gmp 5.0.2.
+ Keith Briggs sent similar parameters obtained on a AMD Athlon
+ (__tune_k8__, __x86_64, __amd64, __k8) */
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,9,11,11, \
+ 12,12,11,15,14,14,15,16,18,18,19,20,18,19,19,20, \
+ 22,22,23,24,26,30,28,28,32,30,30,32,32,30,32,32, \
+ 32,30,30,32,32,38,32,32,36,40,40,40,36,38,40,38, \
+ 40,44,40,44,44,44,44,48,48,46,48,48,56,56,56,56, \
+ 56,56,56,60,64,60,60,64,64,64,64,64,64,64,64,64, \
+ 72,72,72,72,72,72,72,72,72,72,72,72,80,80,80,80, \
+ 80,80,80,80,80,80,80,80,80,80,80,80,93,80,93,93, \
+ 93,76,80,93,80,93,93,90,93,93,93,93,93,93,93,93, \
+ 93,93,111,105,93,117,105,105,117,117,111,117,117,105,117,117, \
+ 117,105,117,117,117,117,117,117,117,117,117,117,117,117,117,117, \
+ 117,117,117,117,116,117,116,117,117,117,117,117,117,117,117,117, \
+ 117,117,140,117,140,140,140,140,140,148,148,147,140,156,156,156, \
+ 148,148,156,148,156,156,156,156,156,155,156,155,156,155,156,156, \
+ 156,156,156,156,156,156,156,156,172,172,172,156,172,172,172,172, \
+ 172,172,172,172,180,180,180,180,180,180,180,188,188,188,188,188, \
+ 180,188,188,188,188,187,188,188,188,188,188,188,188,188,188,188, \
+ 188,188,188,188,188,188,188,188,188,188,188,188,188,220,220,204, \
+ 220,220,220,219,220,220,220,220,220,219,220,219,220,219,220,220, \
+ 220,236,236,220,236,219,233,236,233,252,236,252,236,252,252,236, \
+ 235,236,236,252,252,236,236,252,252,236,252,252,236,251,250,251, \
+ 252,252,251,252,252,252,252,252,252,252,252,252,252,252,252,252, \
+ 252,252,284,252,284,284,284,284,284,252,284,284,284,284,284,284, \
+ 283,284,284,284,284,284,284,284,284,284,284,283,284,284,284,284, \
+ 284,284,283,284,284,284,284,284,284,284,284,284,284,300,284,300, \
+ 300,316,300,300,300,316,300,300,316,316,316,316,316,316,316,316, \
+ 316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316, \
+ 316,315,316,316,315,316,316,316,315,316,316,316,316,316,316,316, \
+ 316,316,316,368,316,316,367,368,368,368,368,368,368,368,368,368, \
+ 368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, \
+ 368,368,368,368,368,368,367,368,368,368,368,367,368,367,367,368, \
+ 368,367,367,368,367,368,368,367,368,368,368,367,368,368,368,368, \
+ 367,368,416,415,416,416,416,416,416,416,415,416,416,416,416,416, \
+ 416,416,416,416,416,416,415,416,415,416,415,416,416,416,416,416, \
+ 416,415,416,416,415,416,416,415,416,416,440,416,416,416,440,416, \
+ 415,416,415,416,464,464,464,464,464,464,463,464,464,464,463,464, \
+ 464,464,464,464,464,463,464,464,474,474,464,464,473,474,474,504, \
+ 474,474,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,503,504,504,504,504,504,504, \
+ 503,504,504,504,504,504,503,504,504,504,504,504,503,504,504,503, \
+ 504,504,504,504,504,504,504,504,503,504,504,504,504,504,503,504, \
+ 504,504,504,504,568,568,568,504,568,568,568,568,568,568,568,568, \
+ 568,567,568,568,568,567,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,567,567,568,566,568,568,568,567, \
+ 568,568,568,568,568,568,568,568,568,568,567,568,568,567,568,568, \
+ 568,568,568,568,567,568,568,566,567,568,568,568,568,568,568,568, \
+ 568,567,568,568,567,568,567,568,567,568,567,568,567,568,632,568, \
+ 600,632,632,600,631,632,632,632,632,631,600,600,632,632,600,631, \
+ 632,632,632,632,632,632,631,632,632,632,631,632,631,632,632,632, \
+ 632,632,631,632,632,631,632,632,632,631,632,632,632,632,631,632, \
+ 632,632,632,632,630,632,632,632,632,632,631,632,631,632,631,632, \
+ 632,632,632,632,632,632,632,632,631,632,632,632,632,632,632,631, \
+ 632,632,632,631,632,632,632,736,632,631,632,736,632,632,632,632, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,734,736,736,735,736,736,735,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,735,736,736,736,736,736,736,736,735,736, \
+ 736,736,735,736,735,736,736,736,735,736,736,736,736,736,736,736, \
+ 736,736,736,735,736,736,736,735,736,736,736,736,736,735,736,736, \
+ 736,736,736,736,736,736,736,736,736,735,736,735,736,832,736,832, \
+ 832,832,832,832,831,832,832,831,832,832,832,832,832,832,831,832, \
+ 831,832,831,832,832,831,832,832,832,832,832,832,831,832,832,832, \
+ 831,832,832,832,832,832,831,832,832,832,832,832,831,832,831,832, \
+ 832,832,831,832,831,832,831,832,832,832,832,832,832,832,831,832 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,0,-1,-1,-1,-1,-1,7,7,8,9,9,11, \
+ 11,11,11,11,13,13,15,15,17,17,18,17,17,17,18,20, \
+ 20,21,23,23,20,21,23,23,24,25,23,23,24,25,26,25, \
+ 28,27,28,29,28,31,34,31,34,34,34,34,34,34,34,34, \
+ 40,34,40,36,40,42,40,42,40,40,42,42,48,48,46,46, \
+ 42,46,48,48,46,50,46,52,54,54,48,56,54,50,54,52, \
+ 50,54,54,52,54,54,58,58,62,64,58,58,58,64,62,64, \
+ 58,64,66,72,68,68,68,68,68,62,66,72,72,72,68,68, \
+ 72,72,68,72,72,72,72,72,80,84,80,80,80,84,80,80, \
+ 80,84,84,84,84,84,92,80,80,84,92,84,92,92,92,96, \
+ 100,92,100,92,96,92,92,96,100,100,96,96,96,100,100,96, \
+ 96,96,92,92,96,96,108,100,96,100,100,112,112,112,112,112, \
+ 112,112,108,112,100,104,112,116,104,116,116,108,112,112,112,116, \
+ 112,112,112,112,112,141,135,141,116,135,135,135,141,141,141,141, \
+ 141,141,141,141,141,141,135,135,141,141,147,141,141,141,140,141, \
+ 141,141,147,147,141,147,147,147,147,147,147,147,147,147,147,159, \
+ 153,147,147,159,159,159,159,159,159,159,159,159,165,171,171,171, \
+ 165,170,171,171,165,171,171,171,165,171,171,171,183,171,171,171, \
+ 183,183,171,183,171,183,183,183,183,183,183,183,189,189,183,195, \
+ 171,171,188,171,171,195,171,171,171,195,195,182,195,177,182,183, \
+ 183,181,182,183,183,189,183,194,195,195,194,195,195,195,195,195, \
+ 195,195,213,195,195,195,195,195,189,195,195,195,195,195,195,195, \
+ 212,195,213,195,195,195,213,195,195,195,195,195,195,213,213,201, \
+ 195,195,195,213,213,213,213,213,212,213,213,213,213,213,213,213, \
+ 237,212,213,213,213,213,213,225,213,213,213,249,213,249,237,237, \
+ 237,237,237,249,237,237,237,237,249,237,249,237,237,237,249,249, \
+ 249,236,237,249,249,249,249,249,249,249,249,249,249,249,249,249, \
+ 249,273,273,273,273,273,273,272,273,273,273,273,273,273,273,273, \
+ 273,273,273,273,273,273,273,285,273,284,285,285,285,285,297,284, \
+ 285,297,285,297,297,297,297,297,297,297,297,296,297,296,297,296, \
+ 297,297,297,297,297,297,297,273,297,273,309,273,273,273,273,320, \
+ 321,321,321,285,285,285,285,285,284,285,297,285,297,297,297,297, \
+ 297,297,333,297,297,297,296,297,309,297,297,297,297,285,309,348, \
+ 297,297,348,348,285,321,297,321,321,297,320,321,321,297,297,321, \
+ 297,321,333,366,333,333,309,333,333,333,332,333,297,321,321,321, \
+ 321,348,321,345,348,348,348,366,348,347,348,365,366,365,333,366, \
+ 402,366,333,366,366,366,366,402,366,365,366,366,366,366,366,366, \
+ 366,348,420,420,348,420,419,420,419,420,420,420,366,366,420,366, \
+ 366,365,366,402,366,366,366,366,402,402,402,401,402,402,402,401, \
+ 420,401,402,402,420,420,420,420,402,420,420,420,420,419,420,419, \
+ 420,419,420,420,402,401,420,402,402,420,402,420,402,401,420,420, \
+ 420,420,420,420,420,402,420,420,402,420,420,420,420,420,420,420, \
+ 420,420,420,420,420,420,420,420,420,419,420,420,438,420,420,438, \
+ 420,420,420,420,420,420,438,420,437,438,438,420,438,438,420,420, \
+ 438,420,420,438,438,420,420,420,438,420,420,420,420,419,420,420, \
+ 420,420,420,420,474,419,420,420,420,438,419,456,438,474,438,437, \
+ 438,438,438,438,438,420,438,420,438,438,438,420,420,419,420,420, \
+ 438,420,438,419,420,420,420,420,420,419,420,474,420,420,438,420, \
+ 438,473,474,474,474,473,438,474,474,438,438,437,438,438,438,438, \
+ 438,438,474,437,437,474,560,456,473,474,535,536,474,560,536,536, \
+ 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, \
+ 560,560,559,560,560,560,560,560,560,560,560,560,560,560,560,560, \
+ 559,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, \
+ 560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, \
+ 559,560,560,560,560,560,560,560,559,560,559,560,560,560,560,559, \
+ 559,560,559,560,560,560,560,560,560,559,560,560,559,560,559,560, \
+ 560,560,559,560,560,560,560,559,560,560,560,560,560,560,560,560, \
+ 560,560,560,560,560,560,560,560,560,560,559,584,560,560,560,560, \
+ 559,560,560,559,560,560,560,560,560,560,559,559,560,560,560,560, \
+ 560,560,559,560,560,560,560,560,560,583,560,560,584,560,584,584, \
+ 584,560,583,583,584,584,582,584,584,584,583,584,584,584,584,584, \
+ 727,584,728,632,728,560,727,728,728,560,584,560,560,727,728,728, \
+ 727,728,728,728,608,728,728,724,728,728,760,727,728,727,728,728, \
+ 728,759,728,696,728,728,728,728,728,727,759,760,727,760,760,727 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \
+ 14,15,18,19,18,14,22,18,18,18,18,20,18,18,20,22, \
+ 22,22,23,24,26,26,26,28,24,30,28,28,28,30,30,32, \
+ 32,34,32,34,32,34,34,31,32,37,32,37,32,33,34,35, \
+ 39,37,37,39,39,37,39,39,39,39,39,39,43,44,46,46, \
+ 47,45,46,48,52,48,50,50,48,46,50,50,52,56,54,50, \
+ 60,60,60,56,56,64,61,60,56,64,60,64,64,64,64,60, \
+ 64,64,64,63,64,64,64,64,64,64,70,64,64,68,78,66, \
+ 74,69,70,74,70,69,74,78,78,74,74,74,74,78,78,79, \
+ 78,78,78,78,78,78,78,78,78,78,88,88,88,88,88,88, \
+ 92,92,88,91,92,88,95,96,96,96,96,92,92,88,92,112, \
+ 112,112,112,108,112,112,112,112,120,112,112,112,120,112,120,112, \
+ 112,120,120,120,104,112,112,128,112,112,112,120,112,112,120,120, \
+ 128,120,120,120,112,120,128,128,128,120,128,128,128,128,128,128, \
+ 128,128,120,128,128,128,128,128,120,128,128,128,128,128,128,128, \
+ 128,128,128,128,128,128,126,128,128,128,127,128,128,128,144,148, \
+ 136,136,144,144,140,141,140,148,148,151,144,148,148,160,156,148, \
+ 160,160,160,160,156,156,156,148,148,156,148,160,160,160,148,156, \
+ 148,148,148,156,156,156,156,160,156,156,158,156,156,157,160,156, \
+ 156,160,160,158,156,156,158,158,159,160,159,160,160,160,184,183, \
+ 184,184,180,184,184,176,184,184,184,184,186,184,184,184,184,184, \
+ 184,184,186,186,192,184,184,186,184,184,186,183,184,185,186,184, \
+ 184,184,186,185,216,184,192,186,208,192,192,184,208,216,224,209, \
+ 208,216,224,222,224,216,208,224,224,224,208,224,210,224,216,234, \
+ 208,216,216,208,224,216,216,224,224,222,224,224,224,216,224,224, \
+ 224,221,224,216,232,224,224,224,224,224,224,224,208,224,222,224, \
+ 224,224,216,224,232,224,224,216,224,256,224,256,224,248,224,224, \
+ 224,224,224,224,224,222,224,232,222,224,224,224,224,224,230,232, \
+ 256,234,232,240,240,233,240,233,248,240,240,240,240,238,240,256, \
+ 248,240,248,256,256,256,256,256,256,248,256,256,256,256,256,256, \
+ 256,256,256,256,256,256,248,256,248,256,248,248,256,256,256,256, \
+ 256,256,256,256,280,296,280,280,256,288,296,280,256,280,280,296, \
+ 296,296,280,280,280,296,296,296,280,280,280,296,280,296,295,312, \
+ 312,312,312,296,312,311,312,312,312,296,296,312,296,296,312,312, \
+ 312,296,312,312,296,311,312,312,312,312,312,312,312,312,312,296, \
+ 296,312,311,296,312,312,312,312,312,312,312,312,296,312,312,312, \
+ 312,312,312,312,312,312,312,312,296,312,312,312,312,312,312,312, \
+ 312,312,312,312,311,311,312,312,312,312,312,312,312,312,312,312, \
+ 312,312,312,312,312,312,312,312,312,312,312,312,312,312,320,316, \
+ 320,319,319,320,320,320,319,320,319,320,360,320,320,320,352,360, \
+ 368,352,368,368,369,372,344,370,372,366,369,352,370,370,370,360, \
+ 360,360,360,368,360,372,372,360,370,368,372,367,368,360,370,368, \
+ 372,371,370,372,372,372,371,368,368,368,370,370,368,368,368,372, \
+ 370,372,367,368,368,370,368,368,360,368,360,368,370,368,368,367, \
+ 360,368,368,368,372,368,372,368,368,368,372,371,368,416,368,367, \
+ 372,368,372,372,372,370,440,372,368,416,368,368,368,433,448,369, \
+ 440,416,415,416,440,448,440,440,448,448,440,448,440,440,448,416, \
+ 416,416,415,440,417,416,416,418,432,418,417,448,416,432,416,432, \
+ 416,420,440,448,408,416,432,448,416,448,448,448,440,440,440,440, \
+ 448,440,440,440,440,448,416,448,440,416,448,416,448,448,440,448, \
+ 416,440,416,419,417,448,416,420,416,432,433,420,417,432,416,424, \
+ 440,440,440,440,448,437,440,440,448,440,440,448,448,448,448,432, \
+ 480,440,440,440,448,448,448,448,448,448,440,448,445,432,448,448, \
+ 448,439,448,448,468,448,448,440,440,440,448,448,468,496,480,448, \
+ 440,448,440,468,440,496,440,466,448,448,448,468,448,440,448,448, \
+ 448,496,496,496,496,448,448,496,448,468,468,448,448,468,480,467, \
+ 468,512,496,512,512,496,496,480,512,480,496,512,512,512,496,512, \
+ 512,496,496,496,512,512,512,512,512,496,512,512,496,496,496,496, \
+ 512,512,496,512,496,496,496,496,512,512,512,496,480,496,496,496, \
+ 496,496,512,512,512,512,496,496,512,496,496,496,512,480,496,544, \
+ 512,496,496,496,576,512,496,560,496,496,512,561,496,560,496,560, \
+ 560,496,512,512,512,496,512,512,512,576,512,512,512,512,512,512, \
+ 512,512,512,512,560,512,560,512,576,512,576,592,512,560,591,512, \
+ 592,512,576,512,576,592,592,624,592,576,560,512,592,576,592,592 \
+
+#define MPFR_MUL_THRESHOLD 19 /* limbs */
+#define MPFR_SQR_THRESHOLD 18 /* limbs */
+#define MPFR_DIV_THRESHOLD 34 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 1031 /* bits */
+#define MPFR_EXP_THRESHOLD 11014 /* bits */
+#define MPFR_SINCOS_THRESHOLD 26907 /* bits */
+#define MPFR_AI_THRESHOLD1 -12404 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 1024
+#define MPFR_AI_THRESHOLD3 19611
+/* Tuneup completed successfully, took 759 seconds */
diff --git a/mpfr/src/arm/mparam.h b/mpfr/src/arm/mparam.h
new file mode 100644
index 0000000000..d3037d5d00
--- /dev/null
+++ b/mpfr/src/arm/mparam.h
@@ -0,0 +1,232 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2010-10-15, gcc 4.4.4 */
+/* gcc57.fsffrance.org (Feroceon 88FR131 rev 1 (v5l)) with gmp 5.0.1 */
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 62,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, \
+ 76,76,76,84,84,84,88,88,88,92,88,92,92,92,92,92, \
+ 92,92,92,92,92,92,92,92,92,92,92,92,92,92,100,100, \
+ 104,108,104,108,108,108,108,108,108,108,108,108,108,108,108,108, \
+ 108,108,108,108,108,108,108,108,120,116,120,120,129,129,129,135, \
+ 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, \
+ 135,135,135,135,135,135,135,147,147,147,147,147,147,153,153,153, \
+ 159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, \
+ 159,159,159,159,159,159,159,159,159,171,171,171,171,177,177,177, \
+ 183,177,183,183,183,183,183,183,183,183,183,183,183,183,183,183, \
+ 183,183,183,183,183,183,183,183,204,204,204,204,204,204,212,212, \
+ 212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, \
+ 212,212,212,212,212,212,212,212,212,212,212,228,228,228,228,228, \
+ 228,228,236,236,236,236,236,244,244,244,244,244,244,244,244,244, \
+ 244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, \
+ 244,244,244,244,260,260,244,244,243,244,244,244,244,244,244,244, \
+ 244,244,244,244,244,284,284,284,284,284,284,284,284,300,300,300, \
+ 300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300, \
+ 300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300, \
+ 300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300, \
+ 300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300, \
+ 300,332,332,332,332,332,332,332,332,332,332,332,332,332,332,348, \
+ 348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348, \
+ 348,364,364,364,364,364,364,364,348,364,364,364,364,348,364,364, \
+ 364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364, \
+ 364,364,364,364,364,364,364,364,366,364,364,364,364,364,364,364, \
+ 364,364,390,364,390,390,390,390,390,390,390,390,390,390,390,426, \
+ 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, \
+ 426,426,426,426,426,426,426,450,426,450,450,450,450,450,450,450, \
+ 450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450, \
+ 450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450, \
+ 450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450, \
+ 450,450,450,450,474,450,474,498,498,498,498,498,498,498,498,498, \
+ 498,498,498,498,498,498,498,498,497,498,497,498,498,498,498,498, \
+ 498,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, \
+ 522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, \
+ 546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546, \
+ 546,546,546,546,545,546,568,568,568,546,568,568,568,568,568,568, \
+ 568,568,568,568,568,600,600,600,600,568,600,600,600,568,568,600, \
+ 600,600,600,600,600,600,600,598,600,600,600,600,600,600,600,600, \
+ 599,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600, \
+ 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600, \
+ 600,600,600,600,600,600,600,600,600,600,600,632,600,600,600,600, \
+ 632,632,600,600,632,632,600,632,664,664,664,664,664,664,664,664, \
+ 664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664, \
+ 664,664,664,664,664,664,664,664,664,664,664,664,696,696,696,696, \
+ 696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696, \
+ 696,696,696,696,696,696,696,696,695,696,728,696,728,728,727,728, \
+ 728,728,728,728,728,727,728,728,727,728,728,728,728,728,727,728, \
+ 728,727,728,727,728,728,728,728,728,728,727,728,728,727,727,728, \
+ 728,727,728,728,728,728,727,728,728,728,728,728,728,728,728,728, \
+ 728,728,728,728,728,727,728,728,727,728,728,728,728,728,728,728, \
+ 728,728,728,727,727,728,728,728,728,727,728,728,728,728,728,728, \
+ 728,728,728,727,728,728,728,728,728,728,727,728,728,728,728,792, \
+ 792,792,792,792,728,728,760,760,760,728,792,792,760,792,792,760, \
+ 760,760,824,792,824,792,824,792,824,792,824,824,824,824,824,824, \
+ 823,824,824,824,792,792,824,792,824,792,792,792,824,824,792,856 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,12,12,13,13,14,14,15,15,16,16,17,17, \
+ 18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25, \
+ 26,26,27,27,28,28,29,29,30,30,31,31,32,32,33,33, \
+ 34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41, \
+ 42,42,43,43,44,44,47,45,46,46,47,47,48,48,49,49, \
+ 50,50,51,51,52,52,53,53,54,54,55,55,56,56,57,57, \
+ 58,58,59,59,60,60,61,61,62,62,63,63,64,64,67,65, \
+ 66,66,67,67,68,68,69,69,70,70,71,71,73,72,75,73, \
+ 74,74,75,77,76,76,82,77,82,82,82,82,82,82,82,82, \
+ 82,82,86,86,90,90,90,85,90,90,90,90,90,90,90,94, \
+ 90,94,98,94,98,98,98,98,98,98,98,98,98,98,98,102, \
+ 106,106,106,102,106,106,106,106,106,106,106,110,106,114,114,110, \
+ 110,114,114,114,114,114,114,118,114,114,114,118,122,122,122,118, \
+ 122,122,122,122,122,122,122,126,130,130,126,119,130,120,130,121, \
+ 122,122,123,123,124,124,125,125,126,126,127,128,128,128,130,130, \
+ 130,132,131,132,134,132,141,136,141,138,147,144,147,144,147,144, \
+ 147,150,147,150,153,150,153,156,153,156,159,156,159,156,147,145, \
+ 147,150,147,150,148,150,153,156,153,156,159,156,159,156,159,162, \
+ 159,162,159,162,159,162,165,168,165,168,165,168,171,174,171,174, \
+ 171,174,177,174,171,180,177,174,177,180,183,180,183,180,183,186, \
+ 183,186,183,186,183,180,189,180,195,180,183,180,183,180,183,186, \
+ 183,186,183,186,189,192,195,192,189,192,195,192,195,198,195,198, \
+ 195,198,195,198,201,204,201,204,207,204,207,204,207,210,207,210, \
+ 207,210,207,210,207,220,224,220,223,228,224,224,224,228,204,228, \
+ 204,228,232,228,204,228,232,236,232,236,240,236,240,240,240,244, \
+ 240,240,243,244,240,244,228,244,228,248,228,252,228,252,228,256, \
+ 228,256,236,256,236,240,240,239,244,240,240,240,240,243,244,248, \
+ 244,243,248,248,248,248,252,248,252,256,256,256,256,256,256,256, \
+ 256,256,260,259,260,264,260,264,260,267,268,272,268,272,276,248, \
+ 252,256,256,256,260,259,256,256,256,255,260,264,260,264,260,267, \
+ 260,267,272,272,264,272,272,272,272,272,276,272,276,272,276,275, \
+ 276,280,276,280,284,280,284,288,284,280,292,288,288,291,292,287, \
+ 288,288,292,296,292,291,292,308,308,304,300,308,300,308,308,308, \
+ 308,308,304,308,316,308,316,315,324,324,324,323,324,324,324,324, \
+ 324,323,324,323,324,328,324,323,324,323,336,336,342,336,342,336, \
+ 342,336,342,348,342,348,348,348,348,323,348,353,348,360,354,360, \
+ 360,360,360,360,354,360,366,360,360,360,366,360,366,360,366,372, \
+ 366,372,366,372,378,372,372,372,378,384,378,360,378,384,390,384, \
+ 384,384,384,384,384,384,384,384,390,396,366,372,372,372,372,372, \
+ 378,396,378,384,384,384,384,384,384,384,390,384,424,384,424,423, \
+ 424,423,424,423,424,423,424,432,424,432,424,432,432,432,424,432, \
+ 432,432,432,448,432,432,440,448,440,432,440,448,424,448,448,448, \
+ 448,448,448,432,424,432,432,432,456,432,432,432,432,432,432,432, \
+ 440,432,440,448,448,448,448,448,448,448,448,448,456,448,456,448, \
+ 456,448,456,464,456,464,456,464,464,464,464,464,472,464,464,464, \
+ 464,472,480,464,472,464,480,480,472,480,480,480,480,480,480,480, \
+ 480,480,480,480,488,480,488,464,488,487,496,496,504,496,488,496, \
+ 496,472,504,496,504,512,512,512,512,512,504,512,512,512,512,512, \
+ 512,512,512,512,512,512,512,496,520,488,496,496,496,496,496,496, \
+ 503,504,536,504,496,504,511,504,512,504,512,512,512,512,512,512, \
+ 544,512,512,512,544,528,552,520,528,520,528,520,528,528,528,520, \
+ 528,528,528,536,528,528,528,544,544,536,512,544,544,528,544,544, \
+ 544,552,512,552,512,520,512,520,519,520,528,528,528,528,560,520, \
+ 528,528,528,520,528,536,528,536,528,544,528,536,544,536,544,544, \
+ 544,552,544,552,544,544,544,544,544,544,544,544,560,552,551,560, \
+ 560,552,560,552,560,560,560,560,560,568,576,568,576,568,560,568, \
+ 576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,584, \
+ 576,592,592,584,592,584,592,592,592,544,592,592,592,544,608,600, \
+ 616,600,608,608,616,600,616,552,616,616,616,616,608,616,648,616, \
+ 616,616,648,632,648,632,576,664,631,632,648,632,648,632,648,648, \
+ 647,648,647,648,647,648,647,648,648,648,648,648,647,648,648,648, \
+ 648,648,648,648,648,664,648,648,648,664,616,664,663,664,663,664, \
+ 608,664,616,664,616,664,616,664,608,632,616,616,680,632,616,632 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \
+ 16,17,18,17,18,17,13,16,16,16,19,18,19,19,20,20, \
+ 23,24,21,24,25,24,27,25,24,26,25,28,27,29,31,31, \
+ 29,31,32,32,32,33,29,34,33,33,34,37,32,36,37,37, \
+ 39,36,36,38,41,41,41,42,42,43,43,45,44,44,44,43, \
+ 45,45,48,44,47,48,47,52,47,49,51,52,49,52,53,49, \
+ 55,57,53,56,57,57,57,59,58,62,56,59,56,63,63,60, \
+ 58,65,64,66,64,60,67,67,62,68,66,66,67,69,65,71, \
+ 70,73,69,68,73,72,73,69,75,75,71,74,75,73,73,78, \
+ 76,75,77,81,80,80,77,77,81,84,85,84,84,80,81,86, \
+ 83,85,85,86,88,88,85,91,87,89,89,93,91,89,89,95, \
+ 96,95,91,91,92,92,96,93,99,99,96,96,97,96,101,100, \
+ 98,107,100,106,104,101,101,101,105,107,109,103,110,107,105,108, \
+ 106,109,111,112,114,109,116,109,116,114,113,117,116,114,115,113, \
+ 114,116,120,120,121,118,117,122,125,118,120,119,125,120,121,121, \
+ 125,125,123,124,125,125,125,125,127,126,127,128,128,131,129,129, \
+ 130,130,131,131,132,132,133,133,134,134,135,144,136,143,145,148, \
+ 143,144,152,152,152,148,149,152,152,152,151,149,160,152,152,152, \
+ 151,151,152,152,168,152,152,150,152,151,152,159,152,160,160,153, \
+ 167,176,159,160,168,160,159,168,167,167,167,168,175,160,178,166, \
+ 165,168,176,168,167,176,168,176,179,168,184,184,180,176,184,169, \
+ 175,175,182,174,175,176,183,184,184,176,192,178,184,183,182,183, \
+ 183,183,184,191,183,186,184,192,184,184,191,199,199,200,200,192, \
+ 192,192,200,208,199,197,200,202,207,208,208,198,210,208,199,209, \
+ 215,208,208,216,208,216,204,215,200,208,211,200,206,207,216,208, \
+ 202,207,208,208,216,208,208,207,214,209,216,216,212,208,218,215, \
+ 214,216,216,211,216,215,216,216,216,224,216,224,218,216,224,218, \
+ 230,224,224,238,222,232,224,226,236,222,228,232,232,238,240,240, \
+ 226,240,230,239,240,239,240,239,240,232,240,231,232,240,233,240, \
+ 240,239,238,240,240,240,246,258,240,238,239,239,240,255,241,258, \
+ 242,254,258,252,253,257,257,252,258,258,252,258,248,254,252,264, \
+ 263,257,262,266,256,266,253,258,264,258,258,270,266,262,258,257, \
+ 258,258,272,259,264,265,284,304,263,266,264,288,304,304,270,282, \
+ 300,304,288,288,288,294,288,292,302,300,286,304,302,288,300,304, \
+ 302,298,304,288,304,304,304,300,288,304,316,304,300,314,288,300, \
+ 312,302,304,304,306,302,303,300,304,304,311,304,316,300,336,318, \
+ 304,318,304,312,316,300,304,308,304,312,320,318,320,336,304,316, \
+ 299,336,318,318,318,304,340,336,320,304,304,336,324,348,305,316, \
+ 334,316,352,336,336,336,318,336,340,336,354,318,320,352,352,352, \
+ 318,336,328,318,352,336,358,330,342,360,366,366,350,334,348,336, \
+ 354,350,348,340,336,352,352,352,336,352,332,350,366,336,351,366, \
+ 352,366,352,352,352,336,336,348,353,336,351,366,366,360,366,346, \
+ 350,362,366,352,366,366,352,364,353,356,348,366,368,352,365,348, \
+ 353,366,350,366,352,352,364,372,354,352,372,352,362,352,368,365, \
+ 354,354,366,372,366,368,364,370,368,368,366,372,368,368,366,366, \
+ 368,405,374,364,366,384,372,366,366,368,367,390,368,400,372,400, \
+ 371,392,413,399,380,400,404,417,415,386,384,400,392,400,405,407, \
+ 399,421,408,400,406,408,415,421,416,400,419,415,406,416,412,408, \
+ 422,408,416,431,416,421,404,416,400,416,417,431,415,392,424,424, \
+ 415,432,421,416,432,432,408,399,415,416,400,424,422,408,420,431, \
+ 423,432,417,416,415,432,413,414,432,424,424,416,416,432,415,409, \
+ 416,424,416,430,415,431,423,432,423,424,424,420,416,431,417,436, \
+ 420,430,424,430,428,420,421,424,428,431,464,430,424,439,428,448, \
+ 432,431,432,433,436,440,464,469,468,453,431,440,448,440,449,463, \
+ 464,439,440,468,480,447,448,463,468,440,472,470,480,464,470,480, \
+ 464,471,471,464,479,460,464,461,488,478,468,480,479,464,488,463, \
+ 450,478,464,469,464,471,488,465,478,488,477,480,481,472,480,488, \
+ 496,468,480,479,488,480,488,469,463,488,480,480,464,477,480,481, \
+ 504,472,480,516,504,504,504,478,480,479,488,516,480,483,485,516, \
+ 488,488,488,516,504,488,481,484,480,516,512,528,504,480,532,503, \
+ 488,504,516,536,488,528,516,488,532,516,528,501,512,504,516,504, \
+ 528,492,520,516,516,504,525,496,516,520,516,512,520,532,528,516, \
+ 516,524,512,508,520,528,516,532,532,516,533,516,528,504,528,516, \
+ 532,576,532,515,516,600,528,517,516,600,600,532,516,600,600,524 \
+
+#define MPFR_MUL_THRESHOLD 16 /* limbs */
+#define MPFR_SQR_THRESHOLD 31 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 469 /* bits */
+#define MPFR_EXP_THRESHOLD 5484 /* bits */
+#define MPFR_SINCOS_THRESHOLD 23806 /* bits */
+#define MPFR_AI_THRESHOLD1 -24060 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 2314
+#define MPFR_AI_THRESHOLD3 40340
+/* Tuneup completed successfully, took 8148 seconds */
diff --git a/mpfr/src/asin.c b/mpfr/src/asin.c
new file mode 100644
index 0000000000..e243dcd63a
--- /dev/null
+++ b/mpfr/src/asin.c
@@ -0,0 +1,125 @@
+/* mpfr_asin -- arc-sinus of a floating-point number
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_asin (mpfr_ptr asin, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xp;
+ int compared, inexact;
+ mpfr_prec_t prec;
+ mpfr_exp_t xp_exp;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("asin[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (asin), mpfr_log_prec, asin,
+ inexact));
+
+ /* Special cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x) || MPFR_IS_INF (x))
+ {
+ MPFR_SET_NAN (asin);
+ MPFR_RET_NAN;
+ }
+ else /* x = 0 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (asin);
+ MPFR_SET_SAME_SIGN (asin, x);
+ MPFR_RET (0); /* exact result */
+ }
+ }
+
+ /* asin(x) = x + x^3/6 + ... so the error is < 2^(3*EXP(x)-2) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (asin, x, -2 * MPFR_GET_EXP (x), 2, 1,
+ rnd_mode, {});
+
+ /* Set x_p=|x| (x is a normal number) */
+ mpfr_init2 (xp, MPFR_PREC (x));
+ inexact = mpfr_abs (xp, x, MPFR_RNDN);
+ MPFR_ASSERTD (inexact == 0);
+
+ compared = mpfr_cmp_ui (xp, 1);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ if (MPFR_UNLIKELY (compared >= 0))
+ {
+ mpfr_clear (xp);
+ if (compared > 0) /* asin(x) = NaN for |x| > 1 */
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ MPFR_SET_NAN (asin);
+ MPFR_RET_NAN;
+ }
+ else /* x = 1 or x = -1 */
+ {
+ if (MPFR_IS_POS (x)) /* asin(+1) = Pi/2 */
+ inexact = mpfr_const_pi (asin, rnd_mode);
+ else /* asin(-1) = -Pi/2 */
+ {
+ inexact = -mpfr_const_pi (asin, MPFR_INVERT_RND(rnd_mode));
+ MPFR_CHANGE_SIGN (asin);
+ }
+ mpfr_div_2ui (asin, asin, 1, rnd_mode);
+ }
+ }
+ else
+ {
+ /* Compute exponent of 1 - ABS(x) */
+ mpfr_ui_sub (xp, 1, xp, MPFR_RNDD);
+ MPFR_ASSERTD (MPFR_GET_EXP (xp) <= 0);
+ MPFR_ASSERTD (MPFR_GET_EXP (x) <= 0);
+ xp_exp = 2 - MPFR_GET_EXP (xp);
+
+ /* Set up initial prec */
+ prec = MPFR_PREC (asin) + 10 + xp_exp;
+
+ /* use asin(x) = atan(x/sqrt(1-x^2)) */
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ mpfr_set_prec (xp, prec);
+ mpfr_sqr (xp, x, MPFR_RNDN);
+ mpfr_ui_sub (xp, 1, xp, MPFR_RNDN);
+ mpfr_sqrt (xp, xp, MPFR_RNDN);
+ mpfr_div (xp, x, xp, MPFR_RNDN);
+ mpfr_atan (xp, xp, MPFR_RNDN);
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (xp, prec - xp_exp,
+ MPFR_PREC (asin), rnd_mode)))
+ break;
+ MPFR_ZIV_NEXT (loop, prec);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (asin, xp, rnd_mode);
+
+ mpfr_clear (xp);
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (asin, inexact, rnd_mode);
+}
diff --git a/mpfr/src/asinh.c b/mpfr/src/asinh.c
new file mode 100644
index 0000000000..2741bf9964
--- /dev/null
+++ b/mpfr/src/asinh.c
@@ -0,0 +1,119 @@
+/* mpfr_asinh -- inverse hyperbolic sine
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* The computation of asinh is done by *
+ * asinh = ln(x + sqrt(x^2 + 1)) */
+
+int
+mpfr_asinh (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ int signx, neg;
+ mpfr_prec_t Ny, Nt;
+ mpfr_t t; /* auxiliary variables */
+ mpfr_exp_t err;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y,
+ inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ else /* x is necessarily 0 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (y); /* asinh(0) = 0 */
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ }
+
+ /* asinh(x) = x - x^3/6 + ... so the error is < 2^(3*EXP(x)-2) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * MPFR_GET_EXP (x), 2, 0,
+ rnd_mode, {});
+
+ Ny = MPFR_PREC (y); /* Precision of output variable */
+
+ signx = MPFR_SIGN (x);
+ neg = MPFR_IS_NEG (x);
+
+ /* General case */
+
+ /* compute the precision of intermediary variable */
+ /* the optimal number of bits : see algorithms.tex */
+ Nt = Ny + 4 + MPFR_INT_CEIL_LOG2 (Ny);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* initialize intermediary variables */
+ mpfr_init2 (t, Nt);
+
+ /* First computation of asinh */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ /* compute asinh */
+ mpfr_mul (t, x, x, MPFR_RNDD); /* x^2 */
+ mpfr_add_ui (t, t, 1, MPFR_RNDD); /* x^2+1 */
+ mpfr_sqrt (t, t, MPFR_RNDN); /* sqrt(x^2+1) */
+ (neg ? mpfr_sub : mpfr_add) (t, t, x, MPFR_RNDN); /* sqrt(x^2+1)+x */
+ mpfr_log (t, t, MPFR_RNDN); /* ln(sqrt(x^2+1)+x)*/
+
+ if (MPFR_LIKELY (MPFR_IS_PURE_FP (t)))
+ {
+ /* error estimate -- see algorithms.tex */
+ err = Nt - (MAX (4 - MPFR_GET_EXP (t), 0) + 1);
+ if (MPFR_LIKELY (MPFR_IS_ZERO (t)
+ || MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ break;
+ }
+
+ /* actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set4 (y, t, rnd_mode, signx);
+
+ mpfr_clear (t);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/atan.c b/mpfr/src/atan.c
new file mode 100644
index 0000000000..45e8e75f45
--- /dev/null
+++ b/mpfr/src/atan.c
@@ -0,0 +1,437 @@
+/* mpfr_atan -- arc-tangent of a floating-point number
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* If x = p/2^r, put in y an approximation of atan(x)/x using 2^m terms
+ for the series expansion, with an error of at most 1 ulp.
+ Assumes |x| < 1.
+
+ If X=x^2, we want 1 - X/3 + X^2/5 - ... + (-1)^k*X^k/(2k+1) + ...
+
+ Assume p is non-zero.
+
+ When we sum terms up to x^k/(2k+1), the denominator Q[0] is
+ 3*5*7*...*(2k+1) ~ (2k/e)^k.
+*/
+static void
+mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
+{
+ mpz_t *S, *Q, *ptoj;
+ unsigned long n, i, k, j, l;
+ mpfr_exp_t diff, expo;
+ int im, done;
+ mpfr_prec_t mult, *accu, *log2_nb_terms;
+ mpfr_prec_t precy = MPFR_PREC(y);
+
+ MPFR_ASSERTD(mpz_cmp_ui (p, 0) != 0);
+
+ accu = (mpfr_prec_t*) (*__gmp_allocate_func) ((2 * m + 2) * sizeof (mpfr_prec_t));
+ log2_nb_terms = accu + m + 1;
+
+ /* Set Tables */
+ S = tab; /* S */
+ ptoj = S + 1*(m+1); /* p^2^j Precomputed table */
+ Q = S + 2*(m+1); /* Product of Odd integer table */
+
+ /* From p to p^2, and r to 2r */
+ mpz_mul (p, p, p);
+ MPFR_ASSERTD (2 * r > r);
+ r = 2 * r;
+
+ /* Normalize p */
+ n = mpz_scan1 (p, 0);
+ mpz_tdiv_q_2exp (p, p, n); /* exact */
+ MPFR_ASSERTD (r > n);
+ r -= n;
+ /* since |p/2^r| < 1, and p is a non-zero integer, necessarily r > 0 */
+
+ MPFR_ASSERTD (mpz_sgn (p) > 0);
+ MPFR_ASSERTD (m > 0);
+
+ /* check if p=1 (special case) */
+ l = 0;
+ /*
+ We compute by binary splitting, with X = x^2 = p/2^r:
+ P(a,b) = p if a+1=b, P(a,c)*P(c,b) otherwise
+ Q(a,b) = (2a+1)*2^r if a+1=b [except Q(0,1)=1], Q(a,c)*Q(c,b) otherwise
+ S(a,b) = p*(2a+1) if a+1=b, Q(c,b)*S(a,c)+Q(a,c)*P(a,c)*S(c,b) otherwise
+ Then atan(x)/x ~ S(0,i)/Q(0,i) for i so that (p/2^r)^i/i is small enough.
+ The factor 2^(r*(b-a)) in Q(a,b) is implicit, thus we have to take it
+ into account when we compute with Q.
+ */
+ accu[0] = 0; /* accu[k] = Mult[0] + ... + Mult[k], where Mult[j] is the
+ number of bits of the corresponding term S[j]/Q[j] */
+ if (mpz_cmp_ui (p, 1) != 0)
+ {
+ /* p <> 1: precompute ptoj table */
+ mpz_set (ptoj[0], p);
+ for (im = 1 ; im <= m ; im ++)
+ mpz_mul (ptoj[im], ptoj[im - 1], ptoj[im - 1]);
+ /* main loop */
+ n = 1UL << m;
+ /* the ith term being X^i/(2i+1) with X=p/2^r, we can stop when
+ p^i/2^(r*i) < 2^(-precy), i.e. r*i > precy + log2(p^i) */
+ for (i = k = done = 0; (i < n) && (done == 0); i += 2, k ++)
+ {
+ /* initialize both S[k],Q[k] and S[k+1],Q[k+1] */
+ mpz_set_ui (Q[k+1], 2 * i + 3); /* Q(i+1,i+2) */
+ mpz_mul_ui (S[k+1], p, 2 * i + 1); /* S(i+1,i+2) */
+ mpz_mul_2exp (S[k], Q[k+1], r);
+ mpz_sub (S[k], S[k], S[k+1]); /* S(i,i+2) */
+ mpz_mul_ui (Q[k], Q[k+1], 2 * i + 1); /* Q(i,i+2) */
+ log2_nb_terms[k] = 1; /* S[k]/Q[k] corresponds to 2 terms */
+ for (j = (i + 2) >> 1, l = 1; (j & 1) == 0; l ++, j >>= 1, k --)
+ {
+ /* invariant: S[k-1]/Q[k-1] and S[k]/Q[k] correspond
+ to 2^l terms each. We combine them into S[k-1]/Q[k-1] */
+ MPFR_ASSERTD (k > 0);
+ mpz_mul (S[k], S[k], Q[k-1]);
+ mpz_mul (S[k], S[k], ptoj[l]);
+ mpz_mul (S[k-1], S[k-1], Q[k]);
+ mpz_mul_2exp (S[k-1], S[k-1], r << l);
+ mpz_add (S[k-1], S[k-1], S[k]);
+ mpz_mul (Q[k-1], Q[k-1], Q[k]);
+ log2_nb_terms[k-1] = l + 1;
+ /* now S[k-1]/Q[k-1] corresponds to 2^(l+1) terms */
+ MPFR_MPZ_SIZEINBASE2(mult, ptoj[l+1]);
+ /* FIXME: precompute bits(ptoj[l+1]) outside the loop? */
+ mult = (r << (l + 1)) - mult - 1;
+ accu[k-1] = (k == 1) ? mult : accu[k-2] + mult;
+ if (accu[k-1] > precy)
+ done = 1;
+ }
+ }
+ }
+ else /* special case p=1: the ith term being X^i/(2i+1) with X=1/2^r,
+ we can stop when r*i > precy i.e. i > precy/r */
+ {
+ n = 1UL << m;
+ for (i = k = 0; (i < n) && (i <= precy / r); i += 2, k ++)
+ {
+ mpz_set_ui (Q[k + 1], 2 * i + 3);
+ mpz_mul_2exp (S[k], Q[k+1], r);
+ mpz_sub_ui (S[k], S[k], 1 + 2 * i);
+ mpz_mul_ui (Q[k], Q[k + 1], 1 + 2 * i);
+ log2_nb_terms[k] = 1; /* S[k]/Q[k] corresponds to 2 terms */
+ for (j = (i + 2) >> 1, l = 1; (j & 1) == 0; l++, j >>= 1, k --)
+ {
+ MPFR_ASSERTD (k > 0);
+ mpz_mul (S[k], S[k], Q[k-1]);
+ mpz_mul (S[k-1], S[k-1], Q[k]);
+ mpz_mul_2exp (S[k-1], S[k-1], r << l);
+ mpz_add (S[k-1], S[k-1], S[k]);
+ mpz_mul (Q[k-1], Q[k-1], Q[k]);
+ log2_nb_terms[k-1] = l + 1;
+ }
+ }
+ }
+
+ /* we need to combine S[0]/Q[0]...S[k-1]/Q[k-1] */
+ l = 0; /* number of terms accumulated in S[k]/Q[k] */
+ while (k > 1)
+ {
+ k --;
+ /* combine S[k-1]/Q[k-1] and S[k]/Q[k] */
+ j = log2_nb_terms[k-1];
+ mpz_mul (S[k], S[k], Q[k-1]);
+ if (mpz_cmp_ui (p, 1) != 0)
+ mpz_mul (S[k], S[k], ptoj[j]);
+ mpz_mul (S[k-1], S[k-1], Q[k]);
+ l += 1 << log2_nb_terms[k];
+ mpz_mul_2exp (S[k-1], S[k-1], r * l);
+ mpz_add (S[k-1], S[k-1], S[k]);
+ mpz_mul (Q[k-1], Q[k-1], Q[k]);
+ }
+ (*__gmp_free_func) (accu, (2 * m + 2) * sizeof (mpfr_prec_t));
+
+ MPFR_MPZ_SIZEINBASE2 (diff, S[0]);
+ diff -= 2 * precy;
+ expo = diff;
+ if (diff >= 0)
+ mpz_tdiv_q_2exp (S[0], S[0], diff);
+ else
+ mpz_mul_2exp (S[0], S[0], -diff);
+
+ MPFR_MPZ_SIZEINBASE2 (diff, Q[0]);
+ diff -= precy;
+ expo -= diff;
+ if (diff >= 0)
+ mpz_tdiv_q_2exp (Q[0], Q[0], diff);
+ else
+ mpz_mul_2exp (Q[0], Q[0], -diff);
+
+ mpz_tdiv_q (S[0], S[0], Q[0]);
+ mpfr_set_z (y, S[0], MPFR_RNDD);
+ MPFR_SET_EXP (y, MPFR_EXP(y) + expo - r * (i - 1));
+}
+
+int
+mpfr_atan (mpfr_ptr atan, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xp, arctgt, sk, tmp, tmp2;
+ mpz_t ukz;
+ mpz_t *tabz;
+ mpfr_exp_t exptol;
+ mpfr_prec_t prec, realprec, est_lost, lost;
+ unsigned long twopoweri, log2p, red;
+ int comparaison, inexact;
+ int i, n0, oldn0;
+ MPFR_GROUP_DECL (group);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("atan[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (atan), mpfr_log_prec, atan, inexact));
+
+ /* Singular cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (atan);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ MPFR_SAVE_EXPO_MARK (expo);
+ if (MPFR_IS_POS (x)) /* arctan(+inf) = Pi/2 */
+ inexact = mpfr_const_pi (atan, rnd_mode);
+ else /* arctan(-inf) = -Pi/2 */
+ {
+ inexact = -mpfr_const_pi (atan,
+ MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (atan);
+ }
+ mpfr_div_2ui (atan, atan, 1, rnd_mode); /* exact (no exceptions) */
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (atan, inexact, rnd_mode);
+ }
+ else /* x is necessarily 0 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (atan);
+ MPFR_SET_SAME_SIGN (atan, x);
+ MPFR_RET (0);
+ }
+ }
+
+ /* atan(x) = x - x^3/3 + x^5/5...
+ so the error is < 2^(3*EXP(x)-1)
+ so `EXP(x)-(3*EXP(x)-1)` = -2*EXP(x)+1 */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (atan, x, -2 * MPFR_GET_EXP (x), 1, 0,
+ rnd_mode, {});
+
+ /* Set x_p=|x| */
+ MPFR_TMP_INIT_ABS (xp, x);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Other simple case arctan(-+1)=-+pi/4 */
+ comparaison = mpfr_cmp_ui (xp, 1);
+ if (MPFR_UNLIKELY (comparaison == 0))
+ {
+ int neg = MPFR_IS_NEG (x);
+ inexact = mpfr_const_pi (atan, MPFR_IS_POS (x) ? rnd_mode
+ : MPFR_INVERT_RND (rnd_mode));
+ if (neg)
+ {
+ inexact = -inexact;
+ MPFR_CHANGE_SIGN (atan);
+ }
+ mpfr_div_2ui (atan, atan, 2, rnd_mode); /* exact (no exceptions) */
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (atan, inexact, rnd_mode);
+ }
+
+ realprec = MPFR_PREC (atan) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (atan)) + 4;
+ prec = realprec + GMP_NUMB_BITS;
+
+ /* Initialisation */
+ mpz_init (ukz);
+ MPFR_GROUP_INIT_4 (group, prec, sk, tmp, tmp2, arctgt);
+ oldn0 = 0;
+ tabz = (mpz_t *) 0;
+
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ /* First, if |x| < 1, we need to have more prec to be able to round (sup)
+ n0 = ceil(log(prec_requested + 2 + 1+ln(2.4)/ln(2))/log(2)) */
+ mpfr_prec_t sup;
+ sup = MPFR_GET_EXP (xp) < 0 ? 2 - MPFR_GET_EXP (xp) : 1; /* sup >= 1 */
+
+ n0 = MPFR_INT_CEIL_LOG2 ((realprec + sup) + 3);
+ /* since realprec >= 4, n0 >= ceil(log2(8)) >= 3, thus 3*n0 > 2 */
+ prec = (realprec + sup) + 1 + MPFR_INT_CEIL_LOG2 (3*n0-2);
+
+ /* the number of lost bits due to argument reduction is
+ 9 - 2 * EXP(sk), which we estimate by 9 + 2*ceil(log2(p))
+ since we manage that sk < 1/p */
+ if (MPFR_PREC (atan) > 100)
+ {
+ log2p = MPFR_INT_CEIL_LOG2(prec) / 2 - 3;
+ est_lost = 9 + 2 * log2p;
+ prec += est_lost;
+ }
+ else
+ log2p = est_lost = 0; /* don't reduce the argument */
+
+ /* Initialisation */
+ MPFR_GROUP_REPREC_4 (group, prec, sk, tmp, tmp2, arctgt);
+ if (MPFR_LIKELY (oldn0 == 0))
+ {
+ oldn0 = 3 * (n0 + 1);
+ tabz = (mpz_t *) (*__gmp_allocate_func) (oldn0 * sizeof (mpz_t));
+ for (i = 0; i < oldn0; i++)
+ mpz_init (tabz[i]);
+ }
+ else if (MPFR_UNLIKELY (oldn0 < 3 * (n0 + 1)))
+ {
+ tabz = (mpz_t *) (*__gmp_reallocate_func)
+ (tabz, oldn0 * sizeof (mpz_t), 3 * (n0 + 1)*sizeof (mpz_t));
+ for (i = oldn0; i < 3 * (n0 + 1); i++)
+ mpz_init (tabz[i]);
+ oldn0 = 3 * (n0 + 1);
+ }
+
+ /* The mpfr_ui_div below mustn't underflow. This is guaranteed by
+ MPFR_SAVE_EXPO_MARK, but let's check that for maintainability. */
+ MPFR_ASSERTD (__gmpfr_emax <= 1 - __gmpfr_emin);
+
+ if (comparaison > 0) /* use atan(xp) = Pi/2 - atan(1/xp) */
+ mpfr_ui_div (sk, 1, xp, MPFR_RNDN);
+ else
+ mpfr_set (sk, xp, MPFR_RNDN);
+
+ /* now 0 < sk <= 1 */
+
+ /* Argument reduction: atan(x) = 2 atan((sqrt(1+x^2)-1)/x).
+ We want |sk| < k/sqrt(p) where p is the target precision. */
+ lost = 0;
+ for (red = 0; MPFR_GET_EXP(sk) > - (mpfr_exp_t) log2p; red ++)
+ {
+ lost = 9 - 2 * MPFR_EXP(sk);
+ mpfr_mul (tmp, sk, sk, MPFR_RNDN);
+ mpfr_add_ui (tmp, tmp, 1, MPFR_RNDN);
+ mpfr_sqrt (tmp, tmp, MPFR_RNDN);
+ mpfr_sub_ui (tmp, tmp, 1, MPFR_RNDN);
+ if (red == 0 && comparaison > 0)
+ /* use xp = 1/sk */
+ mpfr_mul (sk, tmp, xp, MPFR_RNDN);
+ else
+ mpfr_div (sk, tmp, sk, MPFR_RNDN);
+ }
+
+ /* we started from x0 = 1/|x| if |x| > 1, and |x| otherwise, thus
+ we had x0 = min(|x|, 1/|x|) <= 1, and applied 'red' times the
+ argument reduction x -> (sqrt(1+x^2)-1)/x, which keeps 0 < x < 1,
+ thus 0 < sk <= 1, and sk=1 can occur only if red=0 */
+
+ /* If sk=1, then if |x| < 1, we have 1 - 2^(-prec-1) <= |x| < 1,
+ or if |x| > 1, we have 1 - 2^(-prec-1) <= 1/|x| < 1, thus in all
+ cases ||x| - 1| <= 2^(-prec), from which it follows
+ |atan|x| - Pi/4| <= 2^(-prec), given the Taylor expansion
+ atan(1+x) = Pi/4 + x/2 - x^2/4 + ...
+ Since Pi/4 = 0.785..., the error is at most one ulp.
+ */
+ if (MPFR_UNLIKELY(mpfr_cmp_ui (sk, 1) == 0))
+ {
+ mpfr_const_pi (arctgt, MPFR_RNDN); /* 1/2 ulp extra error */
+ mpfr_div_2ui (arctgt, arctgt, 2, MPFR_RNDN); /* exact */
+ realprec = prec - 2;
+ goto can_round;
+ }
+
+ /* Assignation */
+ MPFR_SET_ZERO (arctgt);
+ twopoweri = 1 << 0;
+ MPFR_ASSERTD (n0 >= 4);
+ for (i = 0 ; i < n0; i++)
+ {
+ if (MPFR_UNLIKELY (MPFR_IS_ZERO (sk)))
+ break;
+ /* Calculation of trunc(tmp) --> mpz */
+ mpfr_mul_2ui (tmp, sk, twopoweri, MPFR_RNDN);
+ mpfr_trunc (tmp, tmp);
+ if (!MPFR_IS_ZERO (tmp))
+ {
+ /* tmp = ukz*2^exptol */
+ exptol = mpfr_get_z_2exp (ukz, tmp);
+ /* since the s_k are decreasing (see algorithms.tex),
+ and s_0 = min(|x|, 1/|x|) < 1, we have sk < 1,
+ thus exptol < 0 */
+ MPFR_ASSERTD (exptol < 0);
+ mpz_tdiv_q_2exp (ukz, ukz, (unsigned long int) (-exptol));
+ /* since tmp is a non-zero integer, and tmp = ukzold*2^exptol,
+ we now have ukz = tmp, thus ukz is non-zero */
+ /* Calculation of arctan(Ak) */
+ mpfr_set_z (tmp, ukz, MPFR_RNDN);
+ mpfr_div_2ui (tmp, tmp, twopoweri, MPFR_RNDN);
+ mpfr_atan_aux (tmp2, ukz, twopoweri, n0 - i, tabz);
+ mpfr_mul (tmp2, tmp2, tmp, MPFR_RNDN);
+ /* Addition */
+ mpfr_add (arctgt, arctgt, tmp2, MPFR_RNDN);
+ /* Next iteration */
+ mpfr_sub (tmp2, sk, tmp, MPFR_RNDN);
+ mpfr_mul (sk, sk, tmp, MPFR_RNDN);
+ mpfr_add_ui (sk, sk, 1, MPFR_RNDN);
+ mpfr_div (sk, tmp2, sk, MPFR_RNDN);
+ }
+ twopoweri <<= 1;
+ }
+ /* Add last step (Arctan(sk) ~= sk */
+ mpfr_add (arctgt, arctgt, sk, MPFR_RNDN);
+
+ /* argument reduction */
+ mpfr_mul_2exp (arctgt, arctgt, red, MPFR_RNDN);
+
+ if (comparaison > 0)
+ { /* atan(x) = Pi/2-atan(1/x) for x > 0 */
+ mpfr_const_pi (tmp, MPFR_RNDN);
+ mpfr_div_2ui (tmp, tmp, 1, MPFR_RNDN);
+ mpfr_sub (arctgt, tmp, arctgt, MPFR_RNDN);
+ }
+ MPFR_SET_POS (arctgt);
+
+ can_round:
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (arctgt, realprec + est_lost - lost,
+ MPFR_PREC (atan), rnd_mode)))
+ break;
+ MPFR_ZIV_NEXT (loop, realprec);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set4 (atan, arctgt, rnd_mode, MPFR_SIGN (x));
+
+ for (i = 0 ; i < oldn0 ; i++)
+ mpz_clear (tabz[i]);
+ mpz_clear (ukz);
+ (*__gmp_free_func) (tabz, oldn0 * sizeof (mpz_t));
+ MPFR_GROUP_CLEAR (group);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (atan, inexact, rnd_mode);
+}
diff --git a/mpfr/src/atan2.c b/mpfr/src/atan2.c
new file mode 100644
index 0000000000..8631beeb1c
--- /dev/null
+++ b/mpfr/src/atan2.c
@@ -0,0 +1,281 @@
+/* mpfr_atan2 -- arc-tan 2 of a floating-point number
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+static int
+pi_div_2ui (mpfr_ptr dest, int i, int neg, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ if (neg) /* -PI/2^i */
+ {
+ inexact = - mpfr_const_pi (dest, MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (dest);
+ }
+ else /* PI/2^i */
+ {
+ inexact = mpfr_const_pi (dest, rnd_mode);
+ }
+ mpfr_div_2ui (dest, dest, i, rnd_mode); /* exact */
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (dest, inexact, rnd_mode);
+}
+
+int
+mpfr_atan2 (mpfr_ptr dest, mpfr_srcptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t tmp, pi;
+ int inexact;
+ mpfr_prec_t prec;
+ mpfr_exp_t e;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC
+ (("y[%Pu]=%.*Rg x[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y,
+ mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("atan[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (dest), mpfr_log_prec, dest, inexact));
+
+ /* Special cases */
+ if (MPFR_ARE_SINGULAR (x, y))
+ {
+ /* atan2(0, 0) does not raise the "invalid" floating-point
+ exception, nor does atan2(y, 0) raise the "divide-by-zero"
+ floating-point exception.
+ -- atan2(±0, -0) returns ±pi.313)
+ -- atan2(±0, +0) returns ±0.
+ -- atan2(±0, x) returns ±pi, for x < 0.
+ -- atan2(±0, x) returns ±0, for x > 0.
+ -- atan2(y, ±0) returns -pi/2 for y < 0.
+ -- atan2(y, ±0) returns pi/2 for y > 0.
+ -- atan2(±oo, -oo) returns ±3pi/4.
+ -- atan2(±oo, +oo) returns ±pi/4.
+ -- atan2(±oo, x) returns ±pi/2, for finite x.
+ -- atan2(±y, -oo) returns ±pi, for finite y > 0.
+ -- atan2(±y, +oo) returns ±0, for finite y > 0.
+ */
+ if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y))
+ {
+ MPFR_SET_NAN (dest);
+ MPFR_RET_NAN;
+ }
+ if (MPFR_IS_ZERO (y))
+ {
+ if (MPFR_IS_NEG (x)) /* +/- PI */
+ {
+ set_pi:
+ if (MPFR_IS_NEG (y))
+ {
+ inexact = mpfr_const_pi (dest, MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (dest);
+ return -inexact;
+ }
+ else
+ return mpfr_const_pi (dest, rnd_mode);
+ }
+ else /* +/- 0 */
+ {
+ set_zero:
+ MPFR_SET_ZERO (dest);
+ MPFR_SET_SAME_SIGN (dest, y);
+ return 0;
+ }
+ }
+ if (MPFR_IS_ZERO (x))
+ {
+ return pi_div_2ui (dest, 1, MPFR_IS_NEG (y), rnd_mode);
+ }
+ if (MPFR_IS_INF (y))
+ {
+ if (!MPFR_IS_INF (x)) /* +/- PI/2 */
+ return pi_div_2ui (dest, 1, MPFR_IS_NEG (y), rnd_mode);
+ else if (MPFR_IS_POS (x)) /* +/- PI/4 */
+ return pi_div_2ui (dest, 2, MPFR_IS_NEG (y), rnd_mode);
+ else /* +/- 3*PI/4: Ugly since we have to round properly */
+ {
+ mpfr_t tmp2;
+ MPFR_ZIV_DECL (loop2);
+ mpfr_prec_t prec2 = MPFR_PREC (dest) + 10;
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (tmp2, prec2);
+ MPFR_ZIV_INIT (loop2, prec2);
+ for (;;)
+ {
+ mpfr_const_pi (tmp2, MPFR_RNDN);
+ mpfr_mul_ui (tmp2, tmp2, 3, MPFR_RNDN); /* Error <= 2 */
+ mpfr_div_2ui (tmp2, tmp2, 2, MPFR_RNDN);
+ if (mpfr_round_p (MPFR_MANT (tmp2), MPFR_LIMB_SIZE (tmp2),
+ MPFR_PREC (tmp2) - 2,
+ MPFR_PREC (dest) + (rnd_mode == MPFR_RNDN)))
+ break;
+ MPFR_ZIV_NEXT (loop2, prec2);
+ mpfr_set_prec (tmp2, prec2);
+ }
+ MPFR_ZIV_FREE (loop2);
+ if (MPFR_IS_NEG (y))
+ MPFR_CHANGE_SIGN (tmp2);
+ inexact = mpfr_set (dest, tmp2, rnd_mode);
+ mpfr_clear (tmp2);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (dest, inexact, rnd_mode);
+ }
+ }
+ MPFR_ASSERTD (MPFR_IS_INF (x));
+ if (MPFR_IS_NEG (x))
+ goto set_pi;
+ else
+ goto set_zero;
+ }
+
+ /* When x is a power of two, we call directly atan(y/x) since y/x is
+ exact. */
+ if (MPFR_UNLIKELY (MPFR_IS_POWER_OF_2 (x)))
+ {
+ int r;
+ mpfr_t yoverx;
+ unsigned int saved_flags = __gmpfr_flags;
+
+ mpfr_init2 (yoverx, MPFR_PREC (y));
+ if (MPFR_LIKELY (mpfr_div_2si (yoverx, y, MPFR_GET_EXP (x) - 1,
+ MPFR_RNDN) == 0))
+ {
+ /* Here the flags have not changed due to mpfr_div_2si. */
+ r = mpfr_atan (dest, yoverx, rnd_mode);
+ mpfr_clear (yoverx);
+ return r;
+ }
+ else
+ {
+ /* Division is inexact because of a small exponent range */
+ mpfr_clear (yoverx);
+ __gmpfr_flags = saved_flags;
+ }
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Set up initial prec */
+ prec = MPFR_PREC (dest) + 3 + MPFR_INT_CEIL_LOG2 (MPFR_PREC (dest));
+ mpfr_init2 (tmp, prec);
+
+ MPFR_ZIV_INIT (loop, prec);
+ if (MPFR_IS_POS (x))
+ /* use atan2(y,x) = atan(y/x) */
+ for (;;)
+ {
+ int div_inex;
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_BLOCK (flags, div_inex = mpfr_div (tmp, y, x, MPFR_RNDN));
+ if (div_inex == 0)
+ {
+ /* Result is exact. */
+ inexact = mpfr_atan (dest, tmp, rnd_mode);
+ goto end;
+ }
+
+ /* Error <= ulp (tmp) except in case of underflow or overflow. */
+
+ /* If the division underflowed, since |atan(z)/z| < 1, we have
+ an underflow. */
+ if (MPFR_UNDERFLOW (flags))
+ {
+ int sign;
+
+ /* In the case MPFR_RNDN with 2^(emin-2) < |y/x| < 2^(emin-1):
+ The smallest significand value S > 1 of |y/x| is:
+ * 1 / (1 - 2^(-px)) if py <= px,
+ * (1 - 2^(-px) + 2^(-py)) / (1 - 2^(-px)) if py >= px.
+ Therefore S - 1 > 2^(-pz), where pz = max(px,py). We have:
+ atan(|y/x|) > atan(z), where z = 2^(emin-2) * (1 + 2^(-pz)).
+ > z - z^3 / 3.
+ > 2^(emin-2) * (1 + 2^(-pz) - 2^(2 emin - 5))
+ Assuming pz <= -2 emin + 5, we can round away from zero
+ (this is what mpfr_underflow always does on MPFR_RNDN).
+ In the case MPFR_RNDN with |y/x| <= 2^(emin-2), we round
+ toward zero, as |atan(z)/z| < 1. */
+ MPFR_ASSERTN (MPFR_PREC_MAX <=
+ 2 * (mpfr_uexp_t) - MPFR_EMIN_MIN + 5);
+ if (rnd_mode == MPFR_RNDN && MPFR_IS_ZERO (tmp))
+ rnd_mode = MPFR_RNDZ;
+ sign = MPFR_SIGN (tmp);
+ mpfr_clear (tmp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (dest, rnd_mode, sign);
+ }
+
+ mpfr_atan (tmp, tmp, MPFR_RNDN); /* Error <= 2*ulp (tmp) since
+ abs(D(arctan)) <= 1 */
+ /* TODO: check that the error bound is correct in case of overflow. */
+ /* FIXME: Error <= ulp(tmp) ? */
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - 2, MPFR_PREC (dest),
+ rnd_mode)))
+ break;
+ MPFR_ZIV_NEXT (loop, prec);
+ mpfr_set_prec (tmp, prec);
+ }
+ else /* x < 0 */
+ /* Use sign(y)*(PI - atan (|y/x|)) */
+ {
+ mpfr_init2 (pi, prec);
+ for (;;)
+ {
+ mpfr_div (tmp, y, x, MPFR_RNDN); /* Error <= ulp (tmp) */
+ /* If tmp is 0, we have |y/x| <= 2^(-emin-2), thus
+ atan|y/x| < 2^(-emin-2). */
+ MPFR_SET_POS (tmp); /* no error */
+ mpfr_atan (tmp, tmp, MPFR_RNDN); /* Error <= 2*ulp (tmp) since
+ abs(D(arctan)) <= 1 */
+ mpfr_const_pi (pi, MPFR_RNDN); /* Error <= ulp(pi) /2 */
+ e = MPFR_NOTZERO(tmp) ? MPFR_GET_EXP (tmp) : __gmpfr_emin - 1;
+ mpfr_sub (tmp, pi, tmp, MPFR_RNDN); /* see above */
+ if (MPFR_IS_NEG (y))
+ MPFR_CHANGE_SIGN (tmp);
+ /* Error(tmp) <= (1/2+2^(EXP(pi)-EXP(tmp)-1)+2^(e-EXP(tmp)+1))*ulp
+ <= 2^(MAX (MAX (EXP(PI)-EXP(tmp)-1, e-EXP(tmp)+1),
+ -1)+2)*ulp(tmp) */
+ e = MAX (MAX (MPFR_GET_EXP (pi)-MPFR_GET_EXP (tmp) - 1,
+ e - MPFR_GET_EXP (tmp) + 1), -1) + 2;
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - e, MPFR_PREC (dest),
+ rnd_mode)))
+ break;
+ MPFR_ZIV_NEXT (loop, prec);
+ mpfr_set_prec (tmp, prec);
+ mpfr_set_prec (pi, prec);
+ }
+ mpfr_clear (pi);
+ }
+ inexact = mpfr_set (dest, tmp, rnd_mode);
+
+ end:
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (tmp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (dest, inexact, rnd_mode);
+}
diff --git a/mpfr/src/atanh.c b/mpfr/src/atanh.c
new file mode 100644
index 0000000000..078ffc6aa1
--- /dev/null
+++ b/mpfr/src/atanh.c
@@ -0,0 +1,130 @@
+/* mpfr_atanh -- Inverse Hyperbolic Tangente
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+ /* The computation of atanh is done by
+ atanh= 1/2*ln(x+1)-1/2*ln(1-x) */
+
+int
+mpfr_atanh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t x, t, te;
+ mpfr_prec_t Nx, Ny, Nt;
+ mpfr_exp_t err;
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (xt), mpfr_log_prec, xt, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ /* Special cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (xt)))
+ {
+ /* atanh(NaN) = NaN, and atanh(+/-Inf) = NaN since tanh gives a result
+ between -1 and 1 */
+ if (MPFR_IS_NAN (xt) || MPFR_IS_INF (xt))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else /* necessarily xt is 0 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (xt));
+ MPFR_SET_ZERO (y); /* atanh(0) = 0 */
+ MPFR_SET_SAME_SIGN (y,xt);
+ MPFR_RET (0);
+ }
+ }
+
+ /* atanh (x) = NaN as soon as |x| > 1, and arctanh(+/-1) = +/-Inf */
+ if (MPFR_UNLIKELY (MPFR_GET_EXP (xt) > 0))
+ {
+ if (MPFR_GET_EXP (xt) == 1 && mpfr_powerof2_raw (xt))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, xt);
+ mpfr_set_divby0 ();
+ MPFR_RET (0);
+ }
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+
+ /* atanh(x) = x + x^3/3 + ... so the error is < 2^(3*EXP(x)-1) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, xt, -2 * MPFR_GET_EXP (xt), 1, 1,
+ rnd_mode, {});
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Compute initial precision */
+ Nx = MPFR_PREC (xt);
+ MPFR_TMP_INIT_ABS (x, xt);
+ Ny = MPFR_PREC (y);
+ Nt = MAX (Nx, Ny);
+ /* the optimal number of bits : see algorithms.ps */
+ Nt = Nt + MPFR_INT_CEIL_LOG2 (Nt) + 4;
+
+ /* initialise of intermediary variable */
+ mpfr_init2 (t, Nt);
+ mpfr_init2 (te, Nt);
+
+ /* First computation of cosh */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ /* compute atanh */
+ mpfr_ui_sub (te, 1, x, MPFR_RNDU); /* (1-xt)*/
+ mpfr_add_ui (t, x, 1, MPFR_RNDD); /* (xt+1)*/
+ mpfr_div (t, t, te, MPFR_RNDN); /* (1+xt)/(1-xt)*/
+ mpfr_log (t, t, MPFR_RNDN); /* ln((1+xt)/(1-xt))*/
+ mpfr_div_2ui (t, t, 1, MPFR_RNDN); /* (1/2)*ln((1+xt)/(1-xt))*/
+
+ /* error estimate: see algorithms.tex */
+ /* FIXME: this does not correspond to the value in algorithms.tex!!! */
+ /* err=Nt-__gmpfr_ceil_log2(1+5*pow(2,1-MPFR_EXP(t)));*/
+ err = Nt - (MAX (4 - MPFR_GET_EXP (t), 0) + 1);
+
+ if (MPFR_LIKELY (MPFR_IS_ZERO (t)
+ || MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ break;
+
+ /* reactualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set4 (y, t, rnd_mode, MPFR_SIGN (xt));
+
+ mpfr_clear(t);
+ mpfr_clear(te);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
+
diff --git a/mpfr/src/bernoulli.c b/mpfr/src/bernoulli.c
new file mode 100644
index 0000000000..8538155012
--- /dev/null
+++ b/mpfr/src/bernoulli.c
@@ -0,0 +1,80 @@
+/* bernoulli -- internal function to compute Bernoulli numbers.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* assuming b[0]...b[2(n-1)] are computed, computes and stores B[2n]*(2n+1)!
+
+ t/(exp(t)-1) = sum(B[j]*t^j/j!, j=0..infinity)
+ thus t = (exp(t)-1) * sum(B[j]*t^j/j!, n=0..infinity).
+ Taking the coefficient of degree n+1 > 1, we get:
+ 0 = sum(1/(n+1-k)!*B[k]/k!, k=0..n)
+ which gives:
+ B[n] = -sum(binomial(n+1,k)*B[k], k=0..n-1)/(n+1).
+
+ Let C[n] = B[n]*(n+1)!.
+ Then C[n] = -sum(binomial(n+1,k)*C[k]*n!/(k+1)!, k=0..n-1),
+ which proves that the C[n] are integers.
+*/
+mpz_t*
+mpfr_bernoulli_internal (mpz_t *b, unsigned long n)
+{
+ if (n == 0)
+ {
+ b = (mpz_t *) (*__gmp_allocate_func) (sizeof (mpz_t));
+ mpz_init_set_ui (b[0], 1);
+ }
+ else
+ {
+ mpz_t t;
+ unsigned long k;
+
+ b = (mpz_t *) (*__gmp_reallocate_func)
+ (b, n * sizeof (mpz_t), (n + 1) * sizeof (mpz_t));
+ mpz_init (b[n]);
+ /* b[n] = -sum(binomial(2n+1,2k)*C[k]*(2n)!/(2k+1)!, k=0..n-1) */
+ mpz_init_set_ui (t, 2 * n + 1);
+ mpz_mul_ui (t, t, 2 * n - 1);
+ mpz_mul_ui (t, t, 2 * n);
+ mpz_mul_ui (t, t, n);
+ mpz_fdiv_q_ui (t, t, 3); /* exact: t=binomial(2*n+1,2*k)*(2*n)!/(2*k+1)!
+ for k=n-1 */
+ mpz_mul (b[n], t, b[n-1]);
+ for (k = n - 1; k-- > 0;)
+ {
+ mpz_mul_ui (t, t, 2 * k + 1);
+ mpz_mul_ui (t, t, 2 * k + 2);
+ mpz_mul_ui (t, t, 2 * k + 2);
+ mpz_mul_ui (t, t, 2 * k + 3);
+ mpz_fdiv_q_ui (t, t, 2 * (n - k) + 1);
+ mpz_fdiv_q_ui (t, t, 2 * (n - k));
+ mpz_addmul (b[n], t, b[k]);
+ }
+ /* take into account C[1] */
+ mpz_mul_ui (t, t, 2 * n + 1);
+ mpz_fdiv_q_2exp (t, t, 1);
+ mpz_sub (b[n], b[n], t);
+ mpz_neg (b[n], b[n]);
+ mpz_clear (t);
+ }
+ return b;
+}
diff --git a/mpfr/src/buildopt.c b/mpfr/src/buildopt.c
new file mode 100644
index 0000000000..67dd02541a
--- /dev/null
+++ b/mpfr/src/buildopt.c
@@ -0,0 +1,63 @@
+/* buildopt.c -- functions giving information about options used during the
+ mpfr library compilation
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_buildopt_tls_p (void)
+{
+#ifdef MPFR_USE_THREAD_SAFE
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+int
+mpfr_buildopt_decimal_p (void)
+{
+#ifdef MPFR_WANT_DECIMAL_FLOATS
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+int
+mpfr_buildopt_gmpinternals_p (void)
+{
+#if defined(MPFR_HAVE_GMP_IMPL) || defined(WANT_GMP_INTERNALS)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+const char *mpfr_buildopt_tune_case (void)
+{
+#ifdef MPFR_TUNE_CASE
+ return MPFR_TUNE_CASE;
+#else
+ return "Generic thresholds";
+#endif
+}
diff --git a/mpfr/src/cache.c b/mpfr/src/cache.c
new file mode 100644
index 0000000000..359ac42422
--- /dev/null
+++ b/mpfr/src/cache.c
@@ -0,0 +1,145 @@
+/* mpfr_cache -- cache interface for multiple-precision constants in MPFR.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#if 0 /* this function is not used/documented/tested so far, it could be
+ useful if some user wants to add a new constant to mpfr, and
+ implement a cache mechanism for that constant */
+void
+mpfr_init_cache (mpfr_cache_t cache, int (*func)(mpfr_ptr, mpfr_rnd_t))
+{
+ MPFR_PREC (cache->x) = 0; /* Invalid prec to detect that the cache is not
+ valid. Maybe add a flag? */
+ cache->func = func;
+}
+#endif
+
+void
+mpfr_clear_cache (mpfr_cache_t cache)
+{
+ if (MPFR_PREC (cache->x) != 0)
+ mpfr_clear (cache->x);
+ MPFR_PREC (cache->x) = 0;
+}
+
+int
+mpfr_cache (mpfr_ptr dest, mpfr_cache_t cache, mpfr_rnd_t rnd)
+{
+ mpfr_prec_t prec = MPFR_PREC (dest);
+ mpfr_prec_t pold = MPFR_PREC (cache->x);
+ int inexact, sign;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ if (MPFR_UNLIKELY (prec > pold))
+ {
+ /* No previous result in the cache or the precision of the
+ previous result is not sufficient. */
+
+ if (MPFR_UNLIKELY (pold == 0)) /* No previous result. */
+ mpfr_init2 (cache->x, prec);
+
+ /* Update the cache. */
+ pold = prec;
+ /* no need to keep the previous value */
+ mpfr_set_prec (cache->x, pold);
+ cache->inexact = (*cache->func) (cache->x, MPFR_RNDN);
+ }
+
+ /* now pold >= prec is the precision of cache->x */
+
+ /* First, check if the cache has the exact value (unlikely).
+ Else the exact value is between (assuming x=cache->x > 0):
+ x and x+ulp(x) if cache->inexact < 0,
+ x-ulp(x) and x if cache->inexact > 0,
+ and abs(x-exact) <= ulp(x)/2. */
+
+ /* we assume all cached constants are positive */
+ MPFR_ASSERTN (MPFR_IS_POS (cache->x)); /* TODO... */
+ sign = MPFR_SIGN (cache->x);
+ MPFR_SET_EXP (dest, MPFR_GET_EXP (cache->x));
+ MPFR_SET_SIGN (dest, sign);
+
+ /* round cache->x from precision pold down to precision prec */
+ MPFR_RNDRAW_GEN (inexact, dest,
+ MPFR_MANT (cache->x), pold, rnd, sign,
+ if (MPFR_UNLIKELY (cache->inexact == 0))
+ {
+ if ((_sp[0] & _ulp) == 0)
+ {
+ inexact = -sign;
+ goto trunc_doit;
+ }
+ else
+ goto addoneulp;
+ }
+ else if (cache->inexact < 0)
+ goto addoneulp;
+ else /* cache->inexact > 0 */
+ {
+ inexact = -sign;
+ goto trunc_doit;
+ },
+ if (MPFR_UNLIKELY (++MPFR_EXP (dest) > __gmpfr_emax))
+ mpfr_overflow (dest, rnd, sign);
+ );
+
+ if (MPFR_LIKELY (cache->inexact != 0))
+ {
+ switch (rnd)
+ {
+ case MPFR_RNDZ:
+ case MPFR_RNDD:
+ if (MPFR_UNLIKELY (inexact == 0))
+ {
+ inexact = cache->inexact;
+ if (inexact > 0)
+ {
+ mpfr_nextbelow (dest);
+ inexact = -inexact;
+ }
+ }
+ break;
+ case MPFR_RNDU:
+ case MPFR_RNDA:
+ if (MPFR_UNLIKELY (inexact == 0))
+ {
+ inexact = cache->inexact;
+ if (inexact < 0)
+ {
+ mpfr_nextabove (dest);
+ inexact = -inexact;
+ }
+ }
+ break;
+ default: /* MPFR_RNDN */
+ if (MPFR_UNLIKELY(inexact == 0))
+ inexact = cache->inexact;
+ break;
+ }
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (dest, inexact, rnd);
+}
diff --git a/mpfr/src/cbrt.c b/mpfr/src/cbrt.c
new file mode 100644
index 0000000000..8c7abcfb32
--- /dev/null
+++ b/mpfr/src/cbrt.c
@@ -0,0 +1,153 @@
+/* mpfr_cbrt -- cube root function.
+
+Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+ /* The computation of y = x^(1/3) is done as follows:
+
+ Let x = sign * m * 2^(3*e) where m is an integer
+
+ with 2^(3n-3) <= m < 2^(3n) where n = PREC(y)
+
+ and m = s^3 + r where 0 <= r and m < (s+1)^3
+
+ we want that s has n bits i.e. s >= 2^(n-1), or m >= 2^(3n-3)
+ i.e. m must have at least 3n-2 bits
+
+ then x^(1/3) = s * 2^e if r=0
+ x^(1/3) = (s+1) * 2^e if round up
+ x^(1/3) = (s-1) * 2^e if round down
+ x^(1/3) = s * 2^e if nearest and r < 3/2*s^2+3/4*s+1/8
+ (s+1) * 2^e otherwise
+ */
+
+int
+mpfr_cbrt (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpz_t m;
+ mpfr_exp_t e, r, sh;
+ mpfr_prec_t n, size_m, tmp;
+ int inexact, negative;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y,
+ inexact));
+
+ /* special values */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ /* case 0: cbrt(+/- 0) = +/- 0 */
+ else /* x is necessarily 0 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ }
+
+ /* General case */
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpz_init (m);
+
+ e = mpfr_get_z_2exp (m, x); /* x = m * 2^e */
+ if ((negative = MPFR_IS_NEG(x)))
+ mpz_neg (m, m);
+ r = e % 3;
+ if (r < 0)
+ r += 3;
+ /* x = (m*2^r) * 2^(e-r) = (m*2^r) * 2^(3*q) */
+
+ MPFR_MPZ_SIZEINBASE2 (size_m, m);
+ n = MPFR_PREC (y) + (rnd_mode == MPFR_RNDN);
+
+ /* we want 3*n-2 <= size_m + 3*sh + r <= 3*n
+ i.e. 3*sh + size_m + r <= 3*n */
+ sh = (3 * (mpfr_exp_t) n - (mpfr_exp_t) size_m - r) / 3;
+ sh = 3 * sh + r;
+ if (sh >= 0)
+ {
+ mpz_mul_2exp (m, m, sh);
+ e = e - sh;
+ }
+ else if (r > 0)
+ {
+ mpz_mul_2exp (m, m, r);
+ e = e - r;
+ }
+
+ /* invariant: x = m*2^e, with e divisible by 3 */
+
+ /* we reuse the variable m to store the cube root, since it is not needed
+ any more: we just need to know if the root is exact */
+ inexact = mpz_root (m, m, 3) == 0;
+
+ MPFR_MPZ_SIZEINBASE2 (tmp, m);
+ sh = tmp - n;
+ if (sh > 0) /* we have to flush to 0 the last sh bits from m */
+ {
+ inexact = inexact || ((mpfr_exp_t) mpz_scan1 (m, 0) < sh);
+ mpz_fdiv_q_2exp (m, m, sh);
+ e += 3 * sh;
+ }
+
+ if (inexact)
+ {
+ if (negative)
+ rnd_mode = MPFR_INVERT_RND (rnd_mode);
+ if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
+ || (rnd_mode == MPFR_RNDN && mpz_tstbit (m, 0)))
+ inexact = 1, mpz_add_ui (m, m, 1);
+ else
+ inexact = -1;
+ }
+
+ /* either inexact is not zero, and the conversion is exact, i.e. inexact
+ is not changed; or inexact=0, and inexact is set only when
+ rnd_mode=MPFR_RNDN and bit (n+1) from m is 1 */
+ inexact += mpfr_set_z (y, m, MPFR_RNDN);
+ MPFR_SET_EXP (y, MPFR_GET_EXP (y) + e / 3);
+
+ if (negative)
+ {
+ MPFR_CHANGE_SIGN (y);
+ inexact = -inexact;
+ }
+
+ mpz_clear (m);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/check.c b/mpfr/src/check.c
new file mode 100644
index 0000000000..97c954158b
--- /dev/null
+++ b/mpfr/src/check.c
@@ -0,0 +1,80 @@
+/* mpfr_check -- Check if a floating-point number has not been corrupted.
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/*
+ * Check if x is a valid mpfr_t initializes by mpfr_init
+ * Returns 0 if isn't valid
+ */
+int
+mpfr_check (mpfr_srcptr x)
+{
+ mp_size_t s, i;
+ mp_limb_t tmp;
+ volatile mp_limb_t *xm;
+ int rw;
+
+ /* Check Sign */
+ if (MPFR_SIGN(x) != MPFR_SIGN_POS && MPFR_SIGN(x) != MPFR_SIGN_NEG)
+ return 0;
+ /* Check Precision */
+ if ( (MPFR_PREC(x) < MPFR_PREC_MIN) || (MPFR_PREC(x) > MPFR_PREC_MAX))
+ return 0;
+ /* Check Mantissa */
+ xm = MPFR_MANT(x);
+ if (!xm)
+ return 0;
+ /* Check size of mantissa */
+ s = MPFR_GET_ALLOC_SIZE(x);
+ if (s<=0 || s > MP_SIZE_T_MAX ||
+ MPFR_PREC(x) > ((mpfr_prec_t)s*GMP_NUMB_BITS))
+ return 0;
+ /* Acces all the mp_limb of the mantissa: may do a seg fault */
+ for(i = 0 ; i < s ; i++)
+ tmp = xm[i];
+ /* Check if it isn't singular*/
+ if (! MPFR_IS_SINGULAR (x))
+ {
+ /* Check first mp_limb of mantissa (Must start with a 1 bit) */
+ if ( ((xm[MPFR_LIMB_SIZE(x)-1])>>(GMP_NUMB_BITS-1)) == 0)
+ return 0;
+ /* Check last mp_limb of mantissa */
+ rw = (MPFR_PREC(x) % GMP_NUMB_BITS);
+ if (rw != 0)
+ {
+ tmp = MPFR_LIMB_MASK (GMP_NUMB_BITS - rw);
+ if ((xm[0] & tmp) != 0)
+ return 0;
+ }
+ /* Check exponent range */
+ if ((MPFR_EXP (x) < __gmpfr_emin) || (MPFR_EXP (x) > __gmpfr_emax))
+ return 0;
+ }
+ else
+ {
+ /* Singular value is zero, inf or nan */
+ MPFR_ASSERTD(MPFR_IS_ZERO(x) || MPFR_IS_NAN(x) || MPFR_IS_INF(x));
+ }
+ return 1;
+}
+
diff --git a/mpfr/src/clear.c b/mpfr/src/clear.c
new file mode 100644
index 0000000000..0db60c133f
--- /dev/null
+++ b/mpfr/src/clear.c
@@ -0,0 +1,31 @@
+/* mpfr_clear -- free the memory space allocated for a floating-point number
+
+Copyright 1999, 2000, 2001, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_clear (mpfr_ptr m)
+{
+ (*__gmp_free_func) (MPFR_GET_REAL_PTR (m),
+ MPFR_MALLOC_SIZE (MPFR_GET_ALLOC_SIZE (m)));
+ MPFR_MANT (m) = (mp_limb_t *) 0;
+}
diff --git a/mpfr/src/clears.c b/mpfr/src/clears.c
new file mode 100644
index 0000000000..bb49e0b93e
--- /dev/null
+++ b/mpfr/src/clears.c
@@ -0,0 +1,61 @@
+/* mpfr_clears -- free the memory space allocated for several
+ floating-point numbers
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+#undef HAVE_STDARG
+#include "config.h" /* for a build within gmp */
+#endif
+
+#if HAVE_STDARG
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include "mpfr-impl.h"
+
+void
+#if HAVE_STDARG
+mpfr_clears (mpfr_ptr x, ...)
+#else
+mpfr_clears (va_alist)
+ va_dcl
+#endif
+{
+ va_list arg;
+
+#if HAVE_STDARG
+ va_start (arg, x);
+#else
+ mpfr_ptr x;
+ va_start(arg);
+ x = va_arg (arg, mpfr_ptr);
+#endif
+
+ while (x != 0)
+ {
+ mpfr_clear (x);
+ x = (mpfr_ptr) va_arg (arg, mpfr_ptr);
+ }
+ va_end (arg);
+}
diff --git a/mpfr/src/cmp.c b/mpfr/src/cmp.c
new file mode 100644
index 0000000000..d6a426827f
--- /dev/null
+++ b/mpfr/src/cmp.c
@@ -0,0 +1,104 @@
+/* mpfr_cmp -- compare two floating-point numbers
+
+Copyright 1999, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* returns 0 iff b = sign(s) * c
+ a positive value iff b > sign(s) * c
+ a negative value iff b < sign(s) * c
+ returns 0 and sets erange flag if b and/or c is NaN.
+*/
+
+int
+mpfr_cmp3 (mpfr_srcptr b, mpfr_srcptr c, int s)
+{
+ mpfr_exp_t be, ce;
+ mp_size_t bn, cn;
+ mp_limb_t *bp, *cp;
+
+ s = MPFR_MULT_SIGN( s , MPFR_SIGN(c) );
+
+ if (MPFR_ARE_SINGULAR(b, c))
+ {
+ if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
+ {
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ else if (MPFR_IS_INF(b))
+ {
+ if (MPFR_IS_INF(c) && s == MPFR_SIGN(b) )
+ return 0;
+ else
+ return MPFR_SIGN(b);
+ }
+ else if (MPFR_IS_INF(c))
+ return -s;
+ else if (MPFR_IS_ZERO(b))
+ return MPFR_IS_ZERO(c) ? 0 : -s;
+ else /* necessarily c=0 */
+ return MPFR_SIGN(b);
+ }
+ /* b and c are real numbers */
+ if (s != MPFR_SIGN(b))
+ return MPFR_SIGN(b);
+
+ /* now signs are equal */
+
+ be = MPFR_GET_EXP (b);
+ ce = MPFR_GET_EXP (c);
+ if (be > ce)
+ return s;
+ if (be < ce)
+ return -s;
+
+ /* both signs and exponents are equal */
+
+ bn = (MPFR_PREC(b)-1)/GMP_NUMB_BITS;
+ cn = (MPFR_PREC(c)-1)/GMP_NUMB_BITS;
+
+ bp = MPFR_MANT(b);
+ cp = MPFR_MANT(c);
+
+ for ( ; bn >= 0 && cn >= 0; bn--, cn--)
+ {
+ if (bp[bn] > cp[cn])
+ return s;
+ if (bp[bn] < cp[cn])
+ return -s;
+ }
+ for ( ; bn >= 0; bn--)
+ if (bp[bn])
+ return s;
+ for ( ; cn >= 0; cn--)
+ if (cp[cn])
+ return -s;
+
+ return 0;
+}
+
+#undef mpfr_cmp
+int
+mpfr_cmp (mpfr_srcptr b, mpfr_srcptr c)
+{
+ return mpfr_cmp3 (b, c, 1);
+}
diff --git a/mpfr/src/cmp2.c b/mpfr/src/cmp2.c
new file mode 100644
index 0000000000..70e40fe375
--- /dev/null
+++ b/mpfr/src/cmp2.c
@@ -0,0 +1,243 @@
+/* mpfr_cmp2 -- exponent shift when subtracting two numbers.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* If |b| != |c|, puts the number of canceled bits when one subtracts |c|
+ from |b| in *cancel. Returns the sign of the difference (-1, 0, 1).
+
+ Assumes neither of b or c is NaN, +/- infinity, or +/- 0.
+
+ In other terms, if |b| != |c|, mpfr_cmp2 (b, c) returns
+ EXP(max(|b|,|c|)) - EXP(|b| - |c|).
+*/
+
+int
+mpfr_cmp2 (mpfr_srcptr b, mpfr_srcptr c, mpfr_prec_t *cancel)
+{
+ mp_limb_t *bp, *cp, bb, cc = 0, lastc = 0, dif, high_dif = 0;
+ mp_size_t bn, cn;
+ mpfr_uexp_t diff_exp;
+ mpfr_prec_t res = 0;
+ int sign;
+
+ /* b=c should not happen, since cmp2 is called only from agm (with
+ different variables) and from sub1 (if b=c, then sub1sp would be
+ called instead). So, no need for a particular optimization here. */
+
+ /* the cases b=0 or c=0 are also treated apart in agm and sub
+ (which calls sub1) */
+ MPFR_ASSERTD (MPFR_IS_PURE_FP(b));
+ MPFR_ASSERTD (MPFR_IS_PURE_FP(c));
+
+ if (MPFR_GET_EXP (b) >= MPFR_GET_EXP (c))
+ {
+ sign = 1;
+ diff_exp = (mpfr_uexp_t) MPFR_GET_EXP (b) - MPFR_GET_EXP (c);
+
+ bp = MPFR_MANT(b);
+ cp = MPFR_MANT(c);
+
+ bn = (MPFR_PREC(b) - 1) / GMP_NUMB_BITS;
+ cn = (MPFR_PREC(c) - 1) / GMP_NUMB_BITS; /* # of limbs of c minus 1 */
+
+ if (MPFR_UNLIKELY( diff_exp == 0 ))
+ {
+ while (bn >= 0 && cn >= 0 && bp[bn] == cp[cn])
+ {
+ bn--;
+ cn--;
+ res += GMP_NUMB_BITS;
+ }
+
+ if (MPFR_UNLIKELY (bn < 0))
+ {
+ if (MPFR_LIKELY (cn < 0)) /* b = c */
+ return 0;
+
+ bp = cp;
+ bn = cn;
+ cn = -1;
+ sign = -1;
+ }
+
+ if (MPFR_UNLIKELY (cn < 0))
+ /* c discards exactly the upper part of b */
+ {
+ unsigned int z;
+
+ MPFR_ASSERTD (bn >= 0);
+
+ while (bp[bn] == 0)
+ {
+ if (--bn < 0) /* b = c */
+ return 0;
+ res += GMP_NUMB_BITS;
+ }
+
+ count_leading_zeros(z, bp[bn]); /* bp[bn] <> 0 */
+ *cancel = res + z;
+ return sign;
+ }
+
+ MPFR_ASSERTD (bn >= 0);
+ MPFR_ASSERTD (cn >= 0);
+ MPFR_ASSERTD (bp[bn] != cp[cn]);
+ if (bp[bn] < cp[cn])
+ {
+ mp_limb_t *tp;
+ mp_size_t tn;
+
+ tp = bp; bp = cp; cp = tp;
+ tn = bn; bn = cn; cn = tn;
+ sign = -1;
+ }
+ }
+ } /* MPFR_EXP(b) >= MPFR_EXP(c) */
+ else /* MPFR_EXP(b) < MPFR_EXP(c) */
+ {
+ sign = -1;
+ diff_exp = (mpfr_uexp_t) MPFR_GET_EXP (c) - MPFR_GET_EXP (b);
+
+ bp = MPFR_MANT(c);
+ cp = MPFR_MANT(b);
+
+ bn = (MPFR_PREC(c) - 1) / GMP_NUMB_BITS;
+ cn = (MPFR_PREC(b) - 1) / GMP_NUMB_BITS;
+ }
+
+ /* now we have removed the identical upper limbs of b and c
+ (can happen only when diff_exp = 0), and after the possible
+ swap, we have |b| > |c|: bp[bn] > cc, bn >= 0, cn >= 0,
+ diff_exp = EXP(b) - EXP(c).
+ */
+
+ if (MPFR_LIKELY (diff_exp < GMP_NUMB_BITS))
+ {
+ cc = cp[cn] >> diff_exp;
+ /* warning: a shift by GMP_NUMB_BITS may give wrong results */
+ if (diff_exp)
+ lastc = cp[cn] << (GMP_NUMB_BITS - diff_exp);
+ cn--;
+ }
+ else
+ diff_exp -= GMP_NUMB_BITS; /* cc = 0 */
+
+ dif = bp[bn--] - cc; /* necessarily dif >= 1 */
+ MPFR_ASSERTD(dif >= 1);
+
+ /* now high_dif = 0, dif >= 1, lastc is the neglected part of cp[cn+1] */
+
+ while (MPFR_UNLIKELY ((cn >= 0 || lastc != 0)
+ && (high_dif == 0) && (dif == 1)))
+ { /* dif=1 implies diff_exp = 0 or 1 */
+ bb = (bn >= 0) ? bp[bn] : 0;
+ cc = lastc;
+ if (cn >= 0)
+ {
+ if (diff_exp == 0)
+ {
+ cc += cp[cn];
+ }
+ else /* diff_exp = 1 */
+ {
+ cc += cp[cn] >> 1;
+ lastc = cp[cn] << (GMP_NUMB_BITS - 1);
+ }
+ }
+ else
+ lastc = 0;
+ high_dif = 1 - mpn_sub_n (&dif, &bb, &cc, 1);
+ bn--;
+ cn--;
+ res += GMP_NUMB_BITS;
+ }
+
+ /* (cn<0 and lastc=0) or (high_dif,dif)<>(0,1) */
+
+ if (MPFR_UNLIKELY (high_dif != 0)) /* high_dif == 1 */
+ {
+ res--;
+ MPFR_ASSERTD (res >= 0);
+ if (dif != 0)
+ {
+ *cancel = res;
+ return sign;
+ }
+ }
+ else /* high_dif == 0 */
+ {
+ unsigned int z;
+
+ count_leading_zeros(z, dif); /* dif > 1 here */
+ res += z;
+ if (MPFR_LIKELY(dif != (MPFR_LIMB_ONE << (GMP_NUMB_BITS - z - 1))))
+ { /* dif is not a power of two */
+ *cancel = res;
+ return sign;
+ }
+ }
+
+ /* now result is res + (low(b) < low(c)) */
+ while (MPFR_UNLIKELY (bn >= 0 && (cn >= 0 || lastc != 0)))
+ {
+ if (diff_exp >= GMP_NUMB_BITS)
+ diff_exp -= GMP_NUMB_BITS;
+ else
+ {
+ cc = lastc;
+ if (cn >= 0)
+ {
+ cc += cp[cn] >> diff_exp;
+ if (diff_exp != 0)
+ lastc = cp[cn] << (GMP_NUMB_BITS - diff_exp);
+ }
+ else
+ lastc = 0;
+ cn--;
+ }
+ if (bp[bn] != cc)
+ {
+ *cancel = res + (bp[bn] < cc);
+ return sign;
+ }
+ bn--;
+ }
+
+ if (bn < 0)
+ {
+ if (lastc != 0)
+ res++;
+ else
+ {
+ while (cn >= 0 && cp[cn] == 0)
+ cn--;
+ if (cn >= 0)
+ res++;
+ }
+ }
+
+ *cancel = res;
+ return sign;
+}
diff --git a/mpfr/src/cmp_abs.c b/mpfr/src/cmp_abs.c
new file mode 100644
index 0000000000..a6e6d9eb3e
--- /dev/null
+++ b/mpfr/src/cmp_abs.c
@@ -0,0 +1,94 @@
+/* mpfr_cmpabs -- compare the absolute values of two FP numbers
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Return a positive value if abs(b) > abs(c), 0 if abs(b) = abs(c), and
+ a negative value if abs(b) < abs(c). Neither b nor c may be NaN. */
+
+int
+mpfr_cmpabs (mpfr_srcptr b, mpfr_srcptr c)
+{
+ mpfr_exp_t be, ce;
+ mp_size_t bn, cn;
+ mp_limb_t *bp, *cp;
+
+ if (MPFR_ARE_SINGULAR (b, c))
+ {
+ if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
+ {
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ else if (MPFR_IS_INF (b))
+ return ! MPFR_IS_INF (c);
+ else if (MPFR_IS_INF (c))
+ return -1;
+ else if (MPFR_IS_ZERO (c))
+ return ! MPFR_IS_ZERO (b);
+ else /* b == 0 */
+ return -1;
+ }
+
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (b));
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (c));
+
+ /* Now that we know that b and c are pure FP numbers (i.e. they have
+ a meaningful exponent), we use MPFR_EXP instead of MPFR_GET_EXP to
+ allow exponents outside the current exponent range. For instance,
+ this is useful for mpfr_pow, which compares values to __gmpfr_one.
+ This is for internal use only! For compatibility with other MPFR
+ versions, the user must still provide values that are representable
+ in the current exponent range. */
+ be = MPFR_EXP (b);
+ ce = MPFR_EXP (c);
+ if (be > ce)
+ return 1;
+ if (be < ce)
+ return -1;
+
+ /* exponents are equal */
+
+ bn = MPFR_LIMB_SIZE(b)-1;
+ cn = MPFR_LIMB_SIZE(c)-1;
+
+ bp = MPFR_MANT(b);
+ cp = MPFR_MANT(c);
+
+ for ( ; bn >= 0 && cn >= 0; bn--, cn--)
+ {
+ if (bp[bn] > cp[cn])
+ return 1;
+ if (bp[bn] < cp[cn])
+ return -1;
+ }
+
+ for ( ; bn >= 0; bn--)
+ if (bp[bn])
+ return 1;
+
+ for ( ; cn >= 0; cn--)
+ if (cp[cn])
+ return -1;
+
+ return 0;
+}
diff --git a/mpfr/src/cmp_d.c b/mpfr/src/cmp_d.c
new file mode 100644
index 0000000000..1341a183d9
--- /dev/null
+++ b/mpfr/src/cmp_d.c
@@ -0,0 +1,38 @@
+/* mpfr_cmp_d -- compare a floating-point number with a double
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_cmp_d (mpfr_srcptr b, double d)
+{
+ mpfr_t tmp;
+ int res;
+
+ mpfr_init2 (tmp, IEEE_DBL_MANT_DIG);
+ res = mpfr_set_d (tmp, d, MPFR_RNDN);
+ MPFR_ASSERTD (res == 0);
+ res = mpfr_cmp (b, tmp);
+ mpfr_clear (tmp);
+
+ return res;
+}
diff --git a/mpfr/src/cmp_ld.c b/mpfr/src/cmp_ld.c
new file mode 100644
index 0000000000..c09bea6646
--- /dev/null
+++ b/mpfr/src/cmp_ld.c
@@ -0,0 +1,38 @@
+/* mpfr_cmp_d -- compare a floating-point number with a long double
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_cmp_ld (mpfr_srcptr b, long double d)
+{
+ mpfr_t tmp;
+ int res;
+
+ mpfr_init2 (tmp, MPFR_LDBL_MANT_DIG);
+ res = mpfr_set_ld (tmp, d, MPFR_RNDN);
+ MPFR_ASSERTD (res == 0);
+ res = mpfr_cmp (b, tmp);
+ mpfr_clear (tmp);
+
+ return res;
+}
diff --git a/mpfr/src/cmp_si.c b/mpfr/src/cmp_si.c
new file mode 100644
index 0000000000..ac104a6906
--- /dev/null
+++ b/mpfr/src/cmp_si.c
@@ -0,0 +1,101 @@
+/* mpfr_cmp_si_2exp -- compare a floating-point number with a signed
+machine integer multiplied by a power of 2
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* returns a positive value if b > i*2^f,
+ a negative value if b < i*2^f,
+ zero if b = i*2^f.
+ b must not be NaN.
+*/
+
+int
+mpfr_cmp_si_2exp (mpfr_srcptr b, long int i, mpfr_exp_t f)
+{
+ int si;
+
+ si = i < 0 ? -1 : 1; /* sign of i */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (b)))
+ {
+ if (MPFR_IS_INF(b))
+ return MPFR_INT_SIGN(b);
+ else if (MPFR_IS_ZERO(b))
+ return i != 0 ? -si : 0;
+ /* NAN */
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ else if (MPFR_SIGN(b) != si || i == 0)
+ return MPFR_INT_SIGN (b);
+ else /* b and i are of same sign si */
+ {
+ mpfr_exp_t e;
+ unsigned long ai;
+ int k;
+ mp_size_t bn;
+ mp_limb_t c, *bp;
+
+ ai = SAFE_ABS(unsigned long, i);
+
+ /* ai must be representable in a mp_limb_t */
+ MPFR_ASSERTN(ai == (mp_limb_t) ai);
+
+ e = MPFR_GET_EXP (b); /* 2^(e-1) <= b < 2^e */
+ if (e <= f)
+ return -si;
+ if (f < MPFR_EMAX_MAX - GMP_NUMB_BITS &&
+ e > f + GMP_NUMB_BITS)
+ return si;
+
+ /* now f < e <= f + GMP_NUMB_BITS */
+ c = (mp_limb_t) ai;
+ count_leading_zeros(k, c);
+ if ((int) (e - f) > GMP_NUMB_BITS - k)
+ return si;
+ if ((int) (e - f) < GMP_NUMB_BITS - k)
+ return -si;
+
+ /* now b and i*2^f have the same exponent */
+ c <<= k;
+ bn = (MPFR_PREC(b) - 1) / GMP_NUMB_BITS;
+ bp = MPFR_MANT(b);
+ if (bp[bn] > c)
+ return si;
+ if (bp[bn] < c)
+ return -si;
+
+ /* most significant limbs agree, check remaining limbs from b */
+ while (bn > 0)
+ if (bp[--bn])
+ return si;
+ return 0;
+ }
+}
+
+#undef mpfr_cmp_si
+int
+mpfr_cmp_si (mpfr_srcptr b, long int i)
+{
+ return mpfr_cmp_si_2exp (b, i, 0);
+}
diff --git a/mpfr/src/cmp_ui.c b/mpfr/src/cmp_ui.c
new file mode 100644
index 0000000000..1e094abbf6
--- /dev/null
+++ b/mpfr/src/cmp_ui.c
@@ -0,0 +1,101 @@
+/* mpfr_cmp_ui_2exp -- compare a floating-point number with an unsigned
+machine integer multiplied by a power of 2
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* returns a positive value if b > i*2^f,
+ a negative value if b < i*2^f,
+ zero if b = i*2^f.
+ b must not be NaN
+*/
+
+int
+mpfr_cmp_ui_2exp (mpfr_srcptr b, unsigned long int i, mpfr_exp_t f)
+{
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(b) ))
+ {
+ if (MPFR_IS_NAN (b))
+ {
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ else if (MPFR_IS_INF(b))
+ return MPFR_INT_SIGN (b);
+ else /* since b cannot be NaN, b=0 here */
+ return i != 0 ? -1 : 0;
+ }
+
+ if (MPFR_IS_NEG (b))
+ return -1;
+ /* now b > 0 */
+ else if (MPFR_UNLIKELY(i == 0))
+ return 1;
+ else /* b > 0, i > 0 */
+ {
+ mpfr_exp_t e;
+ int k;
+ mp_size_t bn;
+ mp_limb_t c, *bp;
+
+ /* i must be representable in a mp_limb_t */
+ MPFR_ASSERTN(i == (mp_limb_t) i);
+
+ e = MPFR_GET_EXP (b); /* 2^(e-1) <= b < 2^e */
+ if (e <= f)
+ return -1;
+ if (f < MPFR_EMAX_MAX - GMP_NUMB_BITS &&
+ e > f + GMP_NUMB_BITS)
+ return 1;
+
+ /* now f < e <= f + GMP_NUMB_BITS */
+ c = (mp_limb_t) i;
+ count_leading_zeros(k, c);
+ if ((int) (e - f) > GMP_NUMB_BITS - k)
+ return 1;
+ if ((int) (e - f) < GMP_NUMB_BITS - k)
+ return -1;
+
+ /* now b and i*2^f have the same exponent */
+ c <<= k;
+ bn = (MPFR_PREC(b) - 1) / GMP_NUMB_BITS;
+ bp = MPFR_MANT(b);
+ if (bp[bn] > c)
+ return 1;
+ if (bp[bn] < c)
+ return -1;
+
+ /* most significant limbs agree, check remaining limbs from b */
+ while (bn > 0)
+ if (bp[--bn] != 0)
+ return 1;
+ return 0;
+ }
+}
+
+#undef mpfr_cmp_ui
+int
+mpfr_cmp_ui (mpfr_srcptr b, unsigned long int i)
+{
+ return mpfr_cmp_ui_2exp (b, i, 0);
+}
diff --git a/mpfr/src/comparisons.c b/mpfr/src/comparisons.c
new file mode 100644
index 0000000000..584667e27c
--- /dev/null
+++ b/mpfr/src/comparisons.c
@@ -0,0 +1,78 @@
+/* comparison predicates
+
+Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Note: these functions currently use mpfr_cmp; they could have their
+ own code to be faster. */
+
+/* = < > unordered
+ * mpfr_greater_p 0 0 1 0
+ * mpfr_greaterequal_p 1 0 1 0
+ * mpfr_less_p 0 1 0 0
+ * mpfr_lessequal_p 1 1 0 0
+ * mpfr_lessgreater_p 0 1 1 0
+ * mpfr_equal_p 1 0 0 0
+ * mpfr_unordered_p 0 0 0 1
+ */
+
+int
+mpfr_greater_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) > 0);
+}
+
+int
+mpfr_greaterequal_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) >= 0);
+}
+
+int
+mpfr_less_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) < 0);
+}
+
+int
+mpfr_lessequal_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) <= 0);
+}
+
+int
+mpfr_lessgreater_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) != 0);
+}
+
+int
+mpfr_equal_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y) ? 0 : (mpfr_cmp (x, y) == 0);
+}
+
+int
+mpfr_unordered_p (mpfr_srcptr x, mpfr_srcptr y)
+{
+ return MPFR_IS_NAN(x) || MPFR_IS_NAN(y);
+}
diff --git a/mpfr/src/const_catalan.c b/mpfr/src/const_catalan.c
new file mode 100644
index 0000000000..c8929c15da
--- /dev/null
+++ b/mpfr/src/const_catalan.c
@@ -0,0 +1,153 @@
+/* mpfr_const_catalan -- compute Catalan's constant.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Declare the cache */
+MPFR_DECL_INIT_CACHE(__gmpfr_cache_const_catalan, mpfr_const_catalan_internal);
+
+/* Set User Interface */
+#undef mpfr_const_catalan
+int
+mpfr_const_catalan (mpfr_ptr x, mpfr_rnd_t rnd_mode) {
+ return mpfr_cache (x, __gmpfr_cache_const_catalan, rnd_mode);
+}
+
+/* return T, Q such that T/Q = sum(k!^2/(2k)!/(2k+1)^2, k=n1..n2-1) */
+static void
+S (mpz_t T, mpz_t P, mpz_t Q, unsigned long n1, unsigned long n2)
+{
+ if (n2 == n1 + 1)
+ {
+ if (n1 == 0)
+ {
+ mpz_set_ui (P, 1);
+ mpz_set_ui (Q, 1);
+ }
+ else
+ {
+ mpz_set_ui (P, 2 * n1 - 1);
+ mpz_mul_ui (P, P, n1);
+ mpz_ui_pow_ui (Q, 2 * n1 + 1, 2);
+ mpz_mul_2exp (Q, Q, 1);
+ }
+ mpz_set (T, P);
+ }
+ else
+ {
+ unsigned long m = (n1 + n2) / 2;
+ mpz_t T2, P2, Q2;
+ S (T, P, Q, n1, m);
+ mpz_init (T2);
+ mpz_init (P2);
+ mpz_init (Q2);
+ S (T2, P2, Q2, m, n2);
+ mpz_mul (T, T, Q2);
+ mpz_mul (T2, T2, P);
+ mpz_add (T, T, T2);
+ mpz_mul (P, P, P2);
+ mpz_mul (Q, Q, Q2);
+ mpz_clear (T2);
+ mpz_clear (P2);
+ mpz_clear (Q2);
+ }
+}
+
+/* Don't need to save/restore exponent range: the cache does it.
+ Catalan's constant is G = sum((-1)^k/(2*k+1)^2, k=0..infinity).
+ We compute it using formula (31) of Victor Adamchik's page
+ "33 representations for Catalan's constant"
+ http://www-2.cs.cmu.edu/~adamchik/articles/catalan/catalan.htm
+
+ G = Pi/8*log(2+sqrt(3)) + 3/8*sum(k!^2/(2k)!/(2k+1)^2,k=0..infinity)
+*/
+int
+mpfr_const_catalan_internal (mpfr_ptr g, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t x, y, z;
+ mpz_t T, P, Q;
+ mpfr_prec_t pg, p;
+ int inex;
+ MPFR_ZIV_DECL (loop);
+ MPFR_GROUP_DECL (group);
+
+ MPFR_LOG_FUNC (("rnd_mode=%d", rnd_mode),
+ ("g[%Pu]=%.*Rg inex=%d", mpfr_get_prec (g), mpfr_log_prec, g, inex));
+
+ /* Here are the WC (max prec = 100.000.000)
+ Once we have found a chain of 11, we only look for bigger chain.
+ Found 3 '1' at 0
+ Found 5 '1' at 9
+ Found 6 '0' at 34
+ Found 9 '1' at 176
+ Found 11 '1' at 705
+ Found 12 '0' at 913
+ Found 14 '1' at 12762
+ Found 15 '1' at 152561
+ Found 16 '0' at 171725
+ Found 18 '0' at 525355
+ Found 20 '0' at 529245
+ Found 21 '1' at 6390133
+ Found 22 '0' at 7806417
+ Found 25 '1' at 11936239
+ Found 27 '1' at 51752950
+ */
+ pg = MPFR_PREC (g);
+ p = pg + MPFR_INT_CEIL_LOG2 (pg) + 7;
+
+ MPFR_GROUP_INIT_3 (group, p, x, y, z);
+ mpz_init (T);
+ mpz_init (P);
+ mpz_init (Q);
+
+ MPFR_ZIV_INIT (loop, p);
+ for (;;) {
+ mpfr_sqrt_ui (x, 3, MPFR_RNDU);
+ mpfr_add_ui (x, x, 2, MPFR_RNDU);
+ mpfr_log (x, x, MPFR_RNDU);
+ mpfr_const_pi (y, MPFR_RNDU);
+ mpfr_mul (x, x, y, MPFR_RNDN);
+ S (T, P, Q, 0, (p - 1) / 2);
+ mpz_mul_ui (T, T, 3);
+ mpfr_set_z (y, T, MPFR_RNDU);
+ mpfr_set_z (z, Q, MPFR_RNDD);
+ mpfr_div (y, y, z, MPFR_RNDN);
+ mpfr_add (x, x, y, MPFR_RNDN);
+ mpfr_div_2ui (x, x, 3, MPFR_RNDN);
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (x, p - 5, pg, rnd_mode)))
+ break;
+
+ MPFR_ZIV_NEXT (loop, p);
+ MPFR_GROUP_REPREC_3 (group, p, x, y, z);
+ }
+ MPFR_ZIV_FREE (loop);
+ inex = mpfr_set (g, x, rnd_mode);
+
+ MPFR_GROUP_CLEAR (group);
+ mpz_clear (T);
+ mpz_clear (P);
+ mpz_clear (Q);
+
+ return inex;
+}
diff --git a/mpfr/src/const_euler.c b/mpfr/src/const_euler.c
new file mode 100644
index 0000000000..2257634893
--- /dev/null
+++ b/mpfr/src/const_euler.c
@@ -0,0 +1,221 @@
+/* mpfr_const_euler -- Euler's constant
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Declare the cache */
+MPFR_DECL_INIT_CACHE(__gmpfr_cache_const_euler, mpfr_const_euler_internal);
+
+/* Set User Interface */
+#undef mpfr_const_euler
+int
+mpfr_const_euler (mpfr_ptr x, mpfr_rnd_t rnd_mode) {
+ return mpfr_cache (x, __gmpfr_cache_const_euler, rnd_mode);
+}
+
+
+static void mpfr_const_euler_S2 (mpfr_ptr, unsigned long);
+static void mpfr_const_euler_R (mpfr_ptr, unsigned long);
+
+int
+mpfr_const_euler_internal (mpfr_t x, mpfr_rnd_t rnd)
+{
+ mpfr_prec_t prec = MPFR_PREC(x), m, log2m;
+ mpfr_t y, z;
+ unsigned long n;
+ int inexact;
+ MPFR_ZIV_DECL (loop);
+
+ log2m = MPFR_INT_CEIL_LOG2 (prec);
+ m = prec + 2 * log2m + 23;
+
+ mpfr_init2 (y, m);
+ mpfr_init2 (z, m);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ mpfr_exp_t exp_S, err;
+ /* since prec >= 1, we have m >= 24 here, which ensures n >= 9 below */
+ n = 1 + (unsigned long) ((double) m * LOG2 / 2.0);
+ MPFR_ASSERTD (n >= 9);
+ mpfr_const_euler_S2 (y, n); /* error <= 3 ulps */
+ exp_S = MPFR_EXP(y);
+ mpfr_set_ui (z, n, MPFR_RNDN);
+ mpfr_log (z, z, MPFR_RNDD); /* error <= 1 ulp */
+ mpfr_sub (y, y, z, MPFR_RNDN); /* S'(n) - log(n) */
+ /* the error is less than 1/2 + 3*2^(exp_S-EXP(y)) + 2^(EXP(z)-EXP(y))
+ <= 1/2 + 2^(exp_S+2-EXP(y)) + 2^(EXP(z)-EXP(y))
+ <= 1/2 + 2^(1+MAX(exp_S+2,EXP(z))-EXP(y)) */
+ err = 1 + MAX(exp_S + 2, MPFR_EXP(z)) - MPFR_EXP(y);
+ err = (err >= -1) ? err + 1 : 0; /* error <= 2^err ulp(y) */
+ exp_S = MPFR_EXP(y);
+ mpfr_const_euler_R (z, n); /* err <= ulp(1/2) = 2^(-m) */
+ mpfr_sub (y, y, z, MPFR_RNDN);
+ /* err <= 1/2 ulp(y) + 2^(-m) + 2^(err + exp_S - EXP(y)) ulp(y).
+ Since the result is between 0.5 and 1, ulp(y) = 2^(-m).
+ So we get 3/2*ulp(y) + 2^(err + exp_S - EXP(y)) ulp(y).
+ 3/2 + 2^e <= 2^(e+1) for e>=1, and <= 2^2 otherwise */
+ err = err + exp_S - MPFR_EXP(y);
+ err = (err >= 1) ? err + 1 : 2;
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (y, m - err, prec, rnd)))
+ break;
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (y, m);
+ mpfr_set_prec (z, m);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (x, y, rnd);
+
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ return inexact; /* always inexact */
+}
+
+static void
+mpfr_const_euler_S2_aux (mpz_t P, mpz_t Q, mpz_t T, unsigned long n,
+ unsigned long a, unsigned long b, int need_P)
+{
+ if (a + 1 == b)
+ {
+ mpz_set_ui (P, n);
+ if (a > 1)
+ mpz_mul_si (P, P, 1 - (long) a);
+ mpz_set (T, P);
+ mpz_set_ui (Q, a);
+ mpz_mul_ui (Q, Q, a);
+ }
+ else
+ {
+ unsigned long c = (a + b) / 2;
+ mpz_t P2, Q2, T2;
+ mpfr_const_euler_S2_aux (P, Q, T, n, a, c, 1);
+ mpz_init (P2);
+ mpz_init (Q2);
+ mpz_init (T2);
+ mpfr_const_euler_S2_aux (P2, Q2, T2, n, c, b, 1);
+ mpz_mul (T, T, Q2);
+ mpz_mul (T2, T2, P);
+ mpz_add (T, T, T2);
+ if (need_P)
+ mpz_mul (P, P, P2);
+ mpz_mul (Q, Q, Q2);
+ mpz_clear (P2);
+ mpz_clear (Q2);
+ mpz_clear (T2);
+ /* divide by 2 if possible */
+ {
+ unsigned long v2;
+ v2 = mpz_scan1 (P, 0);
+ c = mpz_scan1 (Q, 0);
+ if (c < v2)
+ v2 = c;
+ c = mpz_scan1 (T, 0);
+ if (c < v2)
+ v2 = c;
+ if (v2)
+ {
+ mpz_tdiv_q_2exp (P, P, v2);
+ mpz_tdiv_q_2exp (Q, Q, v2);
+ mpz_tdiv_q_2exp (T, T, v2);
+ }
+ }
+ }
+}
+
+/* computes S(n) = sum(n^k*(-1)^(k-1)/k!/k, k=1..ceil(4.319136566 * n))
+ using binary splitting.
+ We have S(n) = sum(f(k), k=1..N) with N=ceil(4.319136566 * n)
+ and f(k) = n^k*(-1)*(k-1)/k!/k,
+ thus f(k)/f(k-1) = -n*(k-1)/k^2
+*/
+static void
+mpfr_const_euler_S2 (mpfr_t x, unsigned long n)
+{
+ mpz_t P, Q, T;
+ unsigned long N = (unsigned long) (ALPHA * (double) n + 1.0);
+ mpz_init (P);
+ mpz_init (Q);
+ mpz_init (T);
+ mpfr_const_euler_S2_aux (P, Q, T, n, 1, N + 1, 0);
+ mpfr_set_z (x, T, MPFR_RNDN);
+ mpfr_div_z (x, x, Q, MPFR_RNDN);
+ mpz_clear (P);
+ mpz_clear (Q);
+ mpz_clear (T);
+}
+
+/* computes R(n) = exp(-n)/n * sum(k!/(-n)^k, k=0..n-2)
+ with error at most 4*ulp(x). Assumes n>=2.
+ Since x <= exp(-n)/n <= 1/8, then 4*ulp(x) <= ulp(1).
+*/
+static void
+mpfr_const_euler_R (mpfr_t x, unsigned long n)
+{
+ unsigned long k, m;
+ mpz_t a, s;
+ mpfr_t y;
+
+ MPFR_ASSERTN (n >= 2); /* ensures sum(k!/(-n)^k, k=0..n-2) >= 2/3 */
+
+ /* as we multiply the sum by exp(-n), we need only PREC(x) - n/LOG2 bits */
+ m = MPFR_PREC(x) - (unsigned long) ((double) n / LOG2);
+
+ mpz_init_set_ui (a, 1);
+ mpz_mul_2exp (a, a, m);
+ mpz_init_set (s, a);
+
+ for (k = 1; k <= n; k++)
+ {
+ mpz_mul_ui (a, a, k);
+ mpz_fdiv_q_ui (a, a, n);
+ /* the error e(k) on a is e(k) <= 1 + k/n*e(k-1) with e(0)=0,
+ i.e. e(k) <= k */
+ if (k % 2)
+ mpz_sub (s, s, a);
+ else
+ mpz_add (s, s, a);
+ }
+ /* the error on s is at most 1+2+...+n = n*(n+1)/2 */
+ mpz_fdiv_q_ui (s, s, n); /* err <= 1 + (n+1)/2 */
+ MPFR_ASSERTN (MPFR_PREC(x) >= mpz_sizeinbase(s, 2));
+ mpfr_set_z (x, s, MPFR_RNDD); /* exact */
+ mpfr_div_2ui (x, x, m, MPFR_RNDD);
+ /* now x = 1/n * sum(k!/(-n)^k, k=0..n-2) <= 1/n */
+ /* err(x) <= (n+1)/2^m <= (n+1)*exp(n)/2^PREC(x) */
+
+ mpfr_init2 (y, m);
+ mpfr_set_si (y, -(long)n, MPFR_RNDD); /* assumed exact */
+ mpfr_exp (y, y, MPFR_RNDD); /* err <= ulp(y) <= exp(-n)*2^(1-m) */
+ mpfr_mul (x, x, y, MPFR_RNDD);
+ /* err <= ulp(x) + (n + 1 + 2/n) / 2^prec(x)
+ <= ulp(x) + (n + 1 + 2/n) ulp(x)/x since x*2^(-prec(x)) < ulp(x)
+ <= ulp(x) + (n + 1 + 2/n) 3/(2n) ulp(x) since x >= 2/3*n for n >= 2
+ <= 4 * ulp(x) for n >= 2 */
+ mpfr_clear (y);
+
+ mpz_clear (a);
+ mpz_clear (s);
+}
diff --git a/mpfr/src/const_log2.c b/mpfr/src/const_log2.c
new file mode 100644
index 0000000000..7e6333fe31
--- /dev/null
+++ b/mpfr/src/const_log2.c
@@ -0,0 +1,200 @@
+/* mpfr_const_log2 -- compute natural logarithm of 2
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Declare the cache */
+#ifndef MPFR_USE_LOGGING
+MPFR_DECL_INIT_CACHE(__gmpfr_cache_const_log2, mpfr_const_log2_internal);
+#else
+MPFR_DECL_INIT_CACHE(__gmpfr_normal_log2, mpfr_const_log2_internal);
+MPFR_DECL_INIT_CACHE(__gmpfr_logging_log2, mpfr_const_log2_internal);
+mpfr_cache_ptr MPFR_THREAD_ATTR __gmpfr_cache_const_log2 = __gmpfr_normal_log2;
+#endif
+
+/* Set User interface */
+#undef mpfr_const_log2
+int
+mpfr_const_log2 (mpfr_ptr x, mpfr_rnd_t rnd_mode) {
+ return mpfr_cache (x, __gmpfr_cache_const_log2, rnd_mode);
+}
+
+/* Auxiliary function: Compute the terms from n1 to n2 (excluded)
+ 3/4*sum((-1)^n*n!^2/2^n/(2*n+1)!, n = n1..n2-1).
+ Numerator is T[0], denominator is Q[0],
+ Compute P[0] only when need_P is non-zero.
+ Need 1+ceil(log(n2-n1)/log(2)) cells in T[],P[],Q[].
+*/
+static void
+S (mpz_t *T, mpz_t *P, mpz_t *Q, unsigned long n1, unsigned long n2, int need_P)
+{
+ if (n2 == n1 + 1)
+ {
+ if (n1 == 0)
+ mpz_set_ui (P[0], 3);
+ else
+ {
+ mpz_set_ui (P[0], n1);
+ mpz_neg (P[0], P[0]);
+ }
+ if (n1 <= (ULONG_MAX / 4 - 1) / 2)
+ mpz_set_ui (Q[0], 4 * (2 * n1 + 1));
+ else /* to avoid overflow in 4 * (2 * n1 + 1) */
+ {
+ mpz_set_ui (Q[0], n1);
+ mpz_mul_2exp (Q[0], Q[0], 1);
+ mpz_add_ui (Q[0], Q[0], 1);
+ mpz_mul_2exp (Q[0], Q[0], 2);
+ }
+ mpz_set (T[0], P[0]);
+ }
+ else
+ {
+ unsigned long m = (n1 / 2) + (n2 / 2) + (n1 & 1UL & n2);
+ unsigned long v, w;
+
+ S (T, P, Q, n1, m, 1);
+ S (T + 1, P + 1, Q + 1, m, n2, need_P);
+ mpz_mul (T[0], T[0], Q[1]);
+ mpz_mul (T[1], T[1], P[0]);
+ mpz_add (T[0], T[0], T[1]);
+ if (need_P)
+ mpz_mul (P[0], P[0], P[1]);
+ mpz_mul (Q[0], Q[0], Q[1]);
+
+ /* remove common trailing zeroes if any */
+ v = mpz_scan1 (T[0], 0);
+ if (v > 0)
+ {
+ w = mpz_scan1 (Q[0], 0);
+ if (w < v)
+ v = w;
+ if (need_P)
+ {
+ w = mpz_scan1 (P[0], 0);
+ if (w < v)
+ v = w;
+ }
+ /* now v = min(val(T), val(Q), val(P)) */
+ if (v > 0)
+ {
+ mpz_fdiv_q_2exp (T[0], T[0], v);
+ mpz_fdiv_q_2exp (Q[0], Q[0], v);
+ if (need_P)
+ mpz_fdiv_q_2exp (P[0], P[0], v);
+ }
+ }
+ }
+}
+
+/* Don't need to save / restore exponent range: the cache does it */
+int
+mpfr_const_log2_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
+{
+ unsigned long n = MPFR_PREC (x);
+ mpfr_prec_t w; /* working precision */
+ unsigned long N;
+ mpz_t *T, *P, *Q;
+ mpfr_t t, q;
+ int inexact;
+ int ok = 1; /* ensures that the 1st try will give correct rounding */
+ unsigned long lgN, i;
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC (
+ ("rnd_mode=%d", rnd_mode),
+ ("x[%Pu]=%.*Rg inex=%d", mpfr_get_prec(x), mpfr_log_prec, x, inexact));
+
+ mpfr_init2 (t, MPFR_PREC_MIN);
+ mpfr_init2 (q, MPFR_PREC_MIN);
+
+ if (n < 1253)
+ w = n + 10; /* ensures correct rounding for the four rounding modes,
+ together with N = w / 3 + 1 (see below). */
+ else if (n < 2571)
+ w = n + 11; /* idem */
+ else if (n < 3983)
+ w = n + 12;
+ else if (n < 4854)
+ w = n + 13;
+ else if (n < 26248)
+ w = n + 14;
+ else
+ {
+ w = n + 15;
+ ok = 0;
+ }
+
+ MPFR_ZIV_INIT (loop, w);
+ for (;;)
+ {
+ N = w / 3 + 1; /* Warning: do not change that (even increasing N!)
+ without checking correct rounding in the above
+ ranges for n. */
+
+ /* the following are needed for error analysis (see algorithms.tex) */
+ MPFR_ASSERTD(w >= 3 && N >= 2);
+
+ lgN = MPFR_INT_CEIL_LOG2 (N) + 1;
+ T = (mpz_t *) (*__gmp_allocate_func) (3 * lgN * sizeof (mpz_t));
+ P = T + lgN;
+ Q = T + 2*lgN;
+ for (i = 0; i < lgN; i++)
+ {
+ mpz_init (T[i]);
+ mpz_init (P[i]);
+ mpz_init (Q[i]);
+ }
+
+ S (T, P, Q, 0, N, 0);
+
+ mpfr_set_prec (t, w);
+ mpfr_set_prec (q, w);
+
+ mpfr_set_z (t, T[0], MPFR_RNDN);
+ mpfr_set_z (q, Q[0], MPFR_RNDN);
+ mpfr_div (t, t, q, MPFR_RNDN);
+
+ for (i = 0; i < lgN; i++)
+ {
+ mpz_clear (T[i]);
+ mpz_clear (P[i]);
+ mpz_clear (Q[i]);
+ }
+ (*__gmp_free_func) (T, 3 * lgN * sizeof (mpz_t));
+
+ if (MPFR_LIKELY (ok != 0
+ || mpfr_can_round (t, w - 2, MPFR_RNDN, rnd_mode, n)))
+ break;
+
+ MPFR_ZIV_NEXT (loop, w);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (x, t, rnd_mode);
+
+ mpfr_clear (t);
+ mpfr_clear (q);
+
+ return inexact;
+}
diff --git a/mpfr/src/const_pi.c b/mpfr/src/const_pi.c
new file mode 100644
index 0000000000..046ccc47dd
--- /dev/null
+++ b/mpfr/src/const_pi.c
@@ -0,0 +1,128 @@
+/* mpfr_const_pi -- compute Pi
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Declare the cache */
+#ifndef MPFR_USE_LOGGING
+MPFR_DECL_INIT_CACHE(__gmpfr_cache_const_pi, mpfr_const_pi_internal);
+#else
+MPFR_DECL_INIT_CACHE(__gmpfr_normal_pi, mpfr_const_pi_internal);
+MPFR_DECL_INIT_CACHE(__gmpfr_logging_pi, mpfr_const_pi_internal);
+mpfr_cache_ptr MPFR_THREAD_ATTR __gmpfr_cache_const_pi = __gmpfr_normal_pi;
+#endif
+
+/* Set User Interface */
+#undef mpfr_const_pi
+int
+mpfr_const_pi (mpfr_ptr x, mpfr_rnd_t rnd_mode) {
+ return mpfr_cache (x, __gmpfr_cache_const_pi, rnd_mode);
+}
+
+/* Don't need to save/restore exponent range: the cache does it */
+int
+mpfr_const_pi_internal (mpfr_ptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t a, A, B, D, S;
+ mpfr_prec_t px, p, cancel, k, kmax;
+ MPFR_ZIV_DECL (loop);
+ int inex;
+
+ MPFR_LOG_FUNC
+ (("rnd_mode=%d", rnd_mode),
+ ("x[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(x), mpfr_log_prec, x, inex));
+
+ px = MPFR_PREC (x);
+
+ /* we need 9*2^kmax - 4 >= px+2*kmax+8 */
+ for (kmax = 2; ((px + 2 * kmax + 12) / 9) >> kmax; kmax ++);
+
+ p = px + 3 * kmax + 14; /* guarantees no recomputation for px <= 10000 */
+
+ mpfr_init2 (a, p);
+ mpfr_init2 (A, p);
+ mpfr_init2 (B, p);
+ mpfr_init2 (D, p);
+ mpfr_init2 (S, p);
+
+ MPFR_ZIV_INIT (loop, p);
+ for (;;) {
+ mpfr_set_ui (a, 1, MPFR_RNDN); /* a = 1 */
+ mpfr_set_ui (A, 1, MPFR_RNDN); /* A = a^2 = 1 */
+ mpfr_set_ui_2exp (B, 1, -1, MPFR_RNDN); /* B = b^2 = 1/2 */
+ mpfr_set_ui_2exp (D, 1, -2, MPFR_RNDN); /* D = 1/4 */
+
+#define b B
+#define ap a
+#define Ap A
+#define Bp B
+ for (k = 0; ; k++)
+ {
+ /* invariant: 1/2 <= B <= A <= a < 1 */
+ mpfr_add (S, A, B, MPFR_RNDN); /* 1 <= S <= 2 */
+ mpfr_div_2ui (S, S, 2, MPFR_RNDN); /* exact, 1/4 <= S <= 1/2 */
+ mpfr_sqrt (b, B, MPFR_RNDN); /* 1/2 <= b <= 1 */
+ mpfr_add (ap, a, b, MPFR_RNDN); /* 1 <= ap <= 2 */
+ mpfr_div_2ui (ap, ap, 1, MPFR_RNDN); /* exact, 1/2 <= ap <= 1 */
+ mpfr_mul (Ap, ap, ap, MPFR_RNDN); /* 1/4 <= Ap <= 1 */
+ mpfr_sub (Bp, Ap, S, MPFR_RNDN); /* -1/4 <= Bp <= 3/4 */
+ mpfr_mul_2ui (Bp, Bp, 1, MPFR_RNDN); /* -1/2 <= Bp <= 3/2 */
+ mpfr_sub (S, Ap, Bp, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (S, 1) < 0);
+ cancel = mpfr_cmp_ui (S, 0) ? (mpfr_uexp_t) -mpfr_get_exp(S) : p;
+ /* MPFR_ASSERTN (cancel >= px || cancel >= 9 * (1 << k) - 4); */
+ mpfr_mul_2ui (S, S, k, MPFR_RNDN);
+ mpfr_sub (D, D, S, MPFR_RNDN);
+ /* stop when |A_k - B_k| <= 2^(k-p) i.e. cancel >= p-k */
+ if (cancel + k >= p)
+ break;
+ }
+#undef b
+#undef ap
+#undef Ap
+#undef Bp
+
+ mpfr_div (A, B, D, MPFR_RNDN);
+
+ /* MPFR_ASSERTN(p >= 2 * k + 8); */
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (A, p - 2 * k - 8, px, rnd_mode)))
+ break;
+
+ p += kmax;
+ MPFR_ZIV_NEXT (loop, p);
+ mpfr_set_prec (a, p);
+ mpfr_set_prec (A, p);
+ mpfr_set_prec (B, p);
+ mpfr_set_prec (D, p);
+ mpfr_set_prec (S, p);
+ }
+ MPFR_ZIV_FREE (loop);
+ inex = mpfr_set (x, A, rnd_mode);
+
+ mpfr_clear (a);
+ mpfr_clear (A);
+ mpfr_clear (B);
+ mpfr_clear (D);
+ mpfr_clear (S);
+
+ return inex;
+}
diff --git a/mpfr/src/constant.c b/mpfr/src/constant.c
new file mode 100644
index 0000000000..25ea40e700
--- /dev/null
+++ b/mpfr/src/constant.c
@@ -0,0 +1,28 @@
+/* MPFR internal constant FP numbers
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+static const mp_limb_t __gmpfr_limb1[1] = {MPFR_LIMB_HIGHBIT};
+const mpfr_t __gmpfr_one = {{2, MPFR_SIGN_POS, 1, (mp_limb_t*)__gmpfr_limb1}};
+const mpfr_t __gmpfr_two = {{2, MPFR_SIGN_POS, 2, (mp_limb_t*)__gmpfr_limb1}};
+const mpfr_t __gmpfr_four ={{2, MPFR_SIGN_POS, 3, (mp_limb_t*)__gmpfr_limb1}};
diff --git a/mpfr/src/copysign.c b/mpfr/src/copysign.c
new file mode 100644
index 0000000000..e6e12811a9
--- /dev/null
+++ b/mpfr/src/copysign.c
@@ -0,0 +1,38 @@
+/* mpfr_copysign -- Produce a value with the magnitude of x and sign bit of y
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+ /*
+ The computation of z with magnitude of x and sign of y:
+ z = (-1)^signbit(y) * abs(x), i.e. with the same sign bit as y,
+ even if z is a NaN.
+ Note: This function implements copysign from the IEEE-754 standard
+ when no rounding occurs (e.g. if PREC(z) >= PREC(x)).
+ */
+
+#undef mpfr_copysign
+int
+mpfr_copysign (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_set4 (z, x, rnd_mode, MPFR_SIGN (y));
+}
diff --git a/mpfr/src/cos.c b/mpfr/src/cos.c
new file mode 100644
index 0000000000..aeb9efac6c
--- /dev/null
+++ b/mpfr/src/cos.c
@@ -0,0 +1,298 @@
+/* mpfr_cos -- cosine of a floating-point number
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+static int
+mpfr_cos_fast (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int inex;
+
+ inex = mpfr_sincos_fast (NULL, y, x, rnd_mode);
+ inex = inex >> 2; /* 0: exact, 1: rounded up, 2: rounded down */
+ return (inex == 2) ? -1 : inex;
+}
+
+/* f <- 1 - r/2! + r^2/4! + ... + (-1)^l r^l/(2l)! + ...
+ Assumes |r| < 1/2, and f, r have the same precision.
+ Returns e such that the error on f is bounded by 2^e ulps.
+*/
+static int
+mpfr_cos2_aux (mpfr_ptr f, mpfr_srcptr r)
+{
+ mpz_t x, t, s;
+ mpfr_exp_t ex, l, m;
+ mpfr_prec_t p, q;
+ unsigned long i, maxi, imax;
+
+ MPFR_ASSERTD(mpfr_get_exp (r) <= -1);
+
+ /* compute minimal i such that i*(i+1) does not fit in an unsigned long,
+ assuming that there are no padding bits. */
+ maxi = 1UL << (CHAR_BIT * sizeof(unsigned long) / 2);
+ if (maxi * (maxi / 2) == 0) /* test checked at compile time */
+ {
+ /* can occur only when there are padding bits. */
+ /* maxi * (maxi-1) is representable iff maxi * (maxi / 2) != 0 */
+ do
+ maxi /= 2;
+ while (maxi * (maxi / 2) == 0);
+ }
+
+ mpz_init (x);
+ mpz_init (s);
+ mpz_init (t);
+ ex = mpfr_get_z_2exp (x, r); /* r = x*2^ex */
+
+ /* remove trailing zeroes */
+ l = mpz_scan1 (x, 0);
+ ex += l;
+ mpz_fdiv_q_2exp (x, x, l);
+
+ /* since |r| < 1, r = x*2^ex, and x is an integer, necessarily ex < 0 */
+
+ p = mpfr_get_prec (f); /* same than r */
+ /* bound for number of iterations */
+ imax = p / (-mpfr_get_exp (r));
+ imax += (imax == 0);
+ q = 2 * MPFR_INT_CEIL_LOG2(imax) + 4; /* bound for (3l)^2 */
+
+ mpz_set_ui (s, 1); /* initialize sum with 1 */
+ mpz_mul_2exp (s, s, p + q); /* scale all values by 2^(p+q) */
+ mpz_set (t, s); /* invariant: t is previous term */
+ for (i = 1; (m = mpz_sizeinbase (t, 2)) >= q; i += 2)
+ {
+ /* adjust precision of x to that of t */
+ l = mpz_sizeinbase (x, 2);
+ if (l > m)
+ {
+ l -= m;
+ mpz_fdiv_q_2exp (x, x, l);
+ ex += l;
+ }
+ /* multiply t by r */
+ mpz_mul (t, t, x);
+ mpz_fdiv_q_2exp (t, t, -ex);
+ /* divide t by i*(i+1) */
+ if (i < maxi)
+ mpz_fdiv_q_ui (t, t, i * (i + 1));
+ else
+ {
+ mpz_fdiv_q_ui (t, t, i);
+ mpz_fdiv_q_ui (t, t, i + 1);
+ }
+ /* if m is the (current) number of bits of t, we can consider that
+ all operations on t so far had precision >= m, so we can prove
+ by induction that the relative error on t is of the form
+ (1+u)^(3l)-1, where |u| <= 2^(-m), and l=(i+1)/2 is the # of loops.
+ Since |(1+x^2)^(1/x) - 1| <= 4x/3 for |x| <= 1/2,
+ for |u| <= 1/(3l)^2, the absolute error is bounded by
+ 4/3*(3l)*2^(-m)*t <= 4*l since |t| < 2^m.
+ Therefore the error on s is bounded by 2*l*(l+1). */
+ /* add or subtract to s */
+ if (i % 4 == 1)
+ mpz_sub (s, s, t);
+ else
+ mpz_add (s, s, t);
+ }
+
+ mpfr_set_z (f, s, MPFR_RNDN);
+ mpfr_div_2ui (f, f, p + q, MPFR_RNDN);
+
+ mpz_clear (x);
+ mpz_clear (s);
+ mpz_clear (t);
+
+ l = (i - 1) / 2; /* number of iterations */
+ return 2 * MPFR_INT_CEIL_LOG2 (l + 1) + 1; /* bound is 2l(l+1) */
+}
+
+int
+mpfr_cos (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t K0, K, precy, m, k, l;
+ int inexact, reduce = 0;
+ mpfr_t r, s, xr, c;
+ mpfr_exp_t exps, cancel = 0, expx;
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_GROUP_DECL (group);
+
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%*.Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%*.Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y,
+ inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x) || MPFR_IS_INF (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ return mpfr_set_ui (y, 1, rnd_mode);
+ }
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* cos(x) = 1-x^2/2 + ..., so error < 2^(2*EXP(x)-1) */
+ expx = MPFR_GET_EXP (x);
+ MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (y, __gmpfr_one, -2 * expx,
+ 1, 0, rnd_mode, expo, {});
+
+ /* Compute initial precision */
+ precy = MPFR_PREC (y);
+
+ if (precy >= MPFR_SINCOS_THRESHOLD)
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_cos_fast (y, x, rnd_mode);
+ }
+
+ K0 = __gmpfr_isqrt (precy / 3);
+ m = precy + 2 * MPFR_INT_CEIL_LOG2 (precy) + 2 * K0;
+
+ if (expx >= 3)
+ {
+ reduce = 1;
+ /* As expx + m - 1 will silently be converted into mpfr_prec_t
+ in the mpfr_init2 call, the assert below may be useful to
+ avoid undefined behavior. */
+ MPFR_ASSERTN (expx + m - 1 <= MPFR_PREC_MAX);
+ mpfr_init2 (c, expx + m - 1);
+ mpfr_init2 (xr, m);
+ }
+
+ MPFR_GROUP_INIT_2 (group, m, r, s);
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ /* If |x| >= 4, first reduce x cmod (2*Pi) into xr, using mpfr_remainder:
+ let e = EXP(x) >= 3, and m the target precision:
+ (1) c <- 2*Pi [precision e+m-1, nearest]
+ (2) xr <- remainder (x, c) [precision m, nearest]
+ We have |c - 2*Pi| <= 1/2ulp(c) = 2^(3-e-m)
+ |xr - x - k c| <= 1/2ulp(xr) <= 2^(1-m)
+ |k| <= |x|/(2*Pi) <= 2^(e-2)
+ Thus |xr - x - 2kPi| <= |k| |c - 2Pi| + 2^(1-m) <= 2^(2-m).
+ It follows |cos(xr) - cos(x)| <= 2^(2-m). */
+ if (reduce)
+ {
+ mpfr_const_pi (c, MPFR_RNDN);
+ mpfr_mul_2ui (c, c, 1, MPFR_RNDN); /* 2Pi */
+ mpfr_remainder (xr, x, c, MPFR_RNDN);
+ if (MPFR_IS_ZERO(xr))
+ goto ziv_next;
+ /* now |xr| <= 4, thus r <= 16 below */
+ mpfr_mul (r, xr, xr, MPFR_RNDU); /* err <= 1 ulp */
+ }
+ else
+ mpfr_mul (r, x, x, MPFR_RNDU); /* err <= 1 ulp */
+
+ /* now |x| < 4 (or xr if reduce = 1), thus |r| <= 16 */
+
+ /* we need |r| < 1/2 for mpfr_cos2_aux, i.e., EXP(r) - 2K <= -1 */
+ K = K0 + 1 + MAX(0, MPFR_GET_EXP(r)) / 2;
+ /* since K0 >= 0, if EXP(r) < 0, then K >= 1, thus EXP(r) - 2K <= -3;
+ otherwise if EXP(r) >= 0, then K >= 1/2 + EXP(r)/2, thus
+ EXP(r) - 2K <= -1 */
+
+ MPFR_SET_EXP (r, MPFR_GET_EXP (r) - 2 * K); /* Can't overflow! */
+
+ /* s <- 1 - r/2! + ... + (-1)^l r^l/(2l)! */
+ l = mpfr_cos2_aux (s, r);
+ /* l is the error bound in ulps on s */
+ MPFR_SET_ONE (r);
+ for (k = 0; k < K; k++)
+ {
+ mpfr_sqr (s, s, MPFR_RNDU); /* err <= 2*olderr */
+ MPFR_SET_EXP (s, MPFR_GET_EXP (s) + 1); /* Can't overflow */
+ mpfr_sub (s, s, r, MPFR_RNDN); /* err <= 4*olderr */
+ if (MPFR_IS_ZERO(s))
+ goto ziv_next;
+ MPFR_ASSERTD (MPFR_GET_EXP (s) <= 1);
+ }
+
+ /* The absolute error on s is bounded by (2l+1/3)*2^(2K-m)
+ 2l+1/3 <= 2l+1.
+ If |x| >= 4, we need to add 2^(2-m) for the argument reduction
+ by 2Pi: if K = 0, this amounts to add 4 to 2l+1/3, i.e., to add
+ 2 to l; if K >= 1, this amounts to add 1 to 2*l+1/3. */
+ l = 2 * l + 1;
+ if (reduce)
+ l += (K == 0) ? 4 : 1;
+ k = MPFR_INT_CEIL_LOG2 (l) + 2*K;
+ /* now the error is bounded by 2^(k-m) = 2^(EXP(s)-err) */
+
+ exps = MPFR_GET_EXP (s);
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, exps + m - k, precy, rnd_mode)))
+ break;
+
+ if (MPFR_UNLIKELY (exps == 1))
+ /* s = 1 or -1, and except x=0 which was already checked above,
+ cos(x) cannot be 1 or -1, so we can round if the error is less
+ than 2^(-precy) for directed rounding, or 2^(-precy-1) for rounding
+ to nearest. */
+ {
+ if (m > k && (m - k >= precy + (rnd_mode == MPFR_RNDN)))
+ {
+ /* If round to nearest or away, result is s = 1 or -1,
+ otherwise it is round(nexttoward (s, 0)). However in order to
+ have the inexact flag correctly set below, we set |s| to
+ 1 - 2^(-m) in all cases. */
+ mpfr_nexttozero (s);
+ break;
+ }
+ }
+
+ if (exps < cancel)
+ {
+ m += cancel - exps;
+ cancel = exps;
+ }
+
+ ziv_next:
+ MPFR_ZIV_NEXT (loop, m);
+ MPFR_GROUP_REPREC_2 (group, m, r, s);
+ if (reduce)
+ {
+ mpfr_set_prec (xr, m);
+ mpfr_set_prec (c, expx + m - 1);
+ }
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (y, s, rnd_mode);
+ MPFR_GROUP_CLEAR (group);
+ if (reduce)
+ {
+ mpfr_clear (xr);
+ mpfr_clear (c);
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/cosh.c b/mpfr/src/cosh.c
new file mode 100644
index 0000000000..dbef5aa8b2
--- /dev/null
+++ b/mpfr/src/cosh.c
@@ -0,0 +1,128 @@
+/* mpfr_cosh -- hyperbolic cosine
+
+Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* The computation of cosh is done by *
+ * cosh= 1/2[e^(x)+e^(-x)] */
+
+int
+mpfr_cosh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
+{
+ mpfr_t x;
+ int inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%*.Rg rnd=%d", mpfr_get_prec (xt), mpfr_log_prec, xt, rnd_mode),
+ ("y[%Pu]=%*.Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y,
+ inexact));
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(xt)))
+ {
+ if (MPFR_IS_NAN(xt))
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF(xt))
+ {
+ MPFR_SET_INF(y);
+ MPFR_SET_POS(y);
+ MPFR_RET(0);
+ }
+ else
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(xt));
+ return mpfr_set_ui (y, 1, rnd_mode); /* cosh(0) = 1 */
+ }
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* cosh(x) = 1+x^2/2 + ... <= 1+x^2 for x <= 2.9828...,
+ thus the error < 2^(2*EXP(x)). If x >= 1, then EXP(x) >= 1,
+ thus the following will always fail. */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, __gmpfr_one, -2 * MPFR_GET_EXP (xt), 0,
+ 1, rnd_mode, inexact = _inexact; goto end);
+
+ MPFR_TMP_INIT_ABS(x, xt);
+ /* General case */
+ {
+ /* Declaration of the intermediary variable */
+ mpfr_t t, te;
+ /* Declaration of the size variable */
+ mpfr_prec_t Ny = MPFR_PREC(y); /* Precision of output variable */
+ mpfr_prec_t Nt; /* Precision of the intermediary variable */
+ long int err; /* Precision of error */
+ MPFR_ZIV_DECL (loop);
+ MPFR_GROUP_DECL (group);
+
+ /* compute the precision of intermediary variable */
+ /* The optimal number of bits : see algorithms.tex */
+ Nt = Ny + 3 + MPFR_INT_CEIL_LOG2 (Ny);
+
+ /* initialise of intermediary variables */
+ MPFR_GROUP_INIT_2 (group, Nt, t, te);
+
+ /* First computation of cosh */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ /* Compute cosh */
+ MPFR_BLOCK (flags, mpfr_exp (te, x, MPFR_RNDD)); /* exp(x) */
+ /* exp can overflow (but not underflow since x>0) */
+ if (MPFR_OVERFLOW (flags))
+ /* cosh(x) > exp(x), cosh(x) underflows too */
+ {
+ inexact = mpfr_overflow (y, rnd_mode, MPFR_SIGN_POS);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
+ break;
+ }
+ mpfr_ui_div (t, 1, te, MPFR_RNDU); /* 1/exp(x) */
+ mpfr_add (t, te, t, MPFR_RNDU); /* exp(x) + 1/exp(x)*/
+ mpfr_div_2ui (t, t, 1, MPFR_RNDN); /* 1/2(exp(x) + 1/exp(x))*/
+
+ /* Estimation of the error */
+ err = Nt - 3;
+ /* Check if we can round */
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ {
+ inexact = mpfr_set (y, t, rnd_mode);
+ break;
+ }
+
+ /* Actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ MPFR_GROUP_REPREC_2 (group, Nt, t, te);
+ }
+ MPFR_ZIV_FREE (loop);
+ MPFR_GROUP_CLEAR (group);
+ }
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/cot.c b/mpfr/src/cot.c
new file mode 100644
index 0000000000..21b786ea25
--- /dev/null
+++ b/mpfr/src/cot.c
@@ -0,0 +1,96 @@
+/* mpfr_cot - cotangent function.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* the cotangent is defined by cot(x) = 1/tan(x) = cos(x)/sin(x).
+ cot (NaN) = NaN.
+ cot (+Inf) = csc (-Inf) = NaN.
+ cot (+0) = +Inf.
+ cot (-0) = -Inf.
+*/
+
+#define FUNCTION mpfr_cot
+#define INVERSE mpfr_tan
+#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_INF(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_ZERO(y,x) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_INF(y); \
+ mpfr_set_divby0 (); MPFR_RET(0); } while (1)
+
+/* (This analysis is adapted from that for mpfr_coth.)
+ Near x=0, cot(x) = 1/x - x/3 + ..., more precisely we have
+ |cot(x) - 1/x| <= 0.36 for |x| <= 1. The error term has
+ the opposite sign as 1/x, thus |cot(x)| <= |1/x|. Then:
+ (i) either x is a power of two, then 1/x is exactly representable, and
+ as long as 1/2*ulp(1/x) > 0.36, we can conclude;
+ (ii) otherwise assume x has <= n bits, and y has <= n+1 bits, then
+ |y - 1/x| >= 2^(-2n) ufp(y), where ufp means unit in first place.
+ Since |cot(x) - 1/x| <= 0.36, if 2^(-2n) ufp(y) >= 0.72, then
+ |y - cot(x)| >= 2^(-2n-1) ufp(y), and rounding 1/x gives the correct
+ result. If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
+ A sufficient condition is thus EXP(x) + 1 <= -2 MAX(PREC(x),PREC(Y)).
+ The division can be inexact in case of underflow or overflow; but
+ an underflow is not possible as emin = - emax. The overflow is a
+ real overflow possibly except when |x| = 2^emin. */
+#define ACTION_TINY(y,x,r) \
+ if (MPFR_EXP(x) + 1 <= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(y))) \
+ { \
+ int two2emin; \
+ int signx = MPFR_SIGN(x); \
+ MPFR_ASSERTN (MPFR_EMIN_MIN + MPFR_EMAX_MAX == 0); \
+ if ((two2emin = mpfr_get_exp (x) == __gmpfr_emin + 1 && \
+ mpfr_powerof2_raw (x))) \
+ { \
+ /* Case |x| = 2^emin. 1/x is not representable; so, compute \
+ 1/(2x) instead (exact), and correct the result later. */ \
+ mpfr_set_si_2exp (y, signx, __gmpfr_emax, MPFR_RNDN); \
+ inexact = 0; \
+ } \
+ else \
+ inexact = mpfr_ui_div (y, 1, x, r); \
+ if (inexact == 0) /* x is a power of two */ \
+ { /* result always 1/x, except when rounding to zero */ \
+ if (rnd_mode == MPFR_RNDA) \
+ rnd_mode = (signx > 0) ? MPFR_RNDU : MPFR_RNDD; \
+ if (rnd_mode == MPFR_RNDU || (rnd_mode == MPFR_RNDZ && signx < 0)) \
+ { \
+ if (signx < 0) \
+ mpfr_nextabove (y); /* -2^k + epsilon */ \
+ inexact = 1; \
+ } \
+ else if (rnd_mode == MPFR_RNDD || rnd_mode == MPFR_RNDZ) \
+ { \
+ if (signx > 0) \
+ mpfr_nextbelow (y); /* 2^k - epsilon */ \
+ inexact = -1; \
+ } \
+ else /* round to nearest */ \
+ inexact = signx; \
+ if (two2emin) \
+ mpfr_mul_2ui (y, y, 1, r); /* overflow in MPFR_RNDN */ \
+ } \
+ /* Underflow is not possible with emin = - emax, but we cannot */ \
+ /* add an assert as the underflow flag could have already been */ \
+ /* set before the call to mpfr_cot. */ \
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); \
+ goto end; \
+ }
+
+#include "gen_inverse.h"
diff --git a/mpfr/src/coth.c b/mpfr/src/coth.c
new file mode 100644
index 0000000000..5cc093b639
--- /dev/null
+++ b/mpfr/src/coth.c
@@ -0,0 +1,93 @@
+/* mpfr_coth - Hyperbolic cotangent function.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* the hyperbolic cotangent is defined by coth(x) = 1/tanh(x)
+ coth (NaN) = NaN.
+ coth (+Inf) = 1
+ coth (-Inf) = -1
+ coth (+0) = +Inf.
+ coth (-0) = -Inf.
+*/
+
+#define FUNCTION mpfr_coth
+#define INVERSE mpfr_tanh
+#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_INF(y) return mpfr_set_si (y, MPFR_IS_POS(x) ? 1 : -1, rnd_mode)
+#define ACTION_ZERO(y,x) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_INF(y); \
+ mpfr_set_divby0 (); MPFR_RET(0); } while (1)
+
+/* We know |coth(x)| > 1, thus if the approximation z is such that
+ 1 <= z <= 1 + 2^(-p) where p is the target precision, then the
+ result is either 1 or nextabove(1) = 1 + 2^(1-p). */
+#define ACTION_SPECIAL \
+ if (MPFR_GET_EXP(z) == 1) /* 1 <= |z| < 2 */ \
+ { \
+ /* the following is exact by Sterbenz theorem */ \
+ mpfr_sub_si (z, z, MPFR_SIGN(z) > 0 ? 1 : -1, MPFR_RNDN); \
+ if (MPFR_IS_ZERO(z) || MPFR_GET_EXP(z) <= - (mpfr_exp_t) precy) \
+ { \
+ mpfr_add_si (z, z, MPFR_SIGN(z) > 0 ? 1 : -1, MPFR_RNDN); \
+ break; \
+ } \
+ }
+
+/* The analysis is adapted from that for mpfr_csc:
+ near x=0, coth(x) = 1/x + x/3 + ..., more precisely we have
+ |coth(x) - 1/x| <= 0.32 for |x| <= 1. Like for csc, the error term has
+ the same sign as 1/x, thus |coth(x)| >= |1/x|. Then:
+ (i) either x is a power of two, then 1/x is exactly representable, and
+ as long as 1/2*ulp(1/x) > 0.32, we can conclude;
+ (ii) otherwise assume x has <= n bits, and y has <= n+1 bits, then
+ |y - 1/x| >= 2^(-2n) ufp(y), where ufp means unit in first place.
+ Since |coth(x) - 1/x| <= 0.32, if 2^(-2n) ufp(y) >= 0.64, then
+ |y - coth(x)| >= 2^(-2n-1) ufp(y), and rounding 1/x gives the correct
+ result. If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
+ A sufficient condition is thus EXP(x) + 1 <= -2 MAX(PREC(x),PREC(Y)). */
+#define ACTION_TINY(y,x,r) \
+ if (MPFR_EXP(x) + 1 <= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(y))) \
+ { \
+ int signx = MPFR_SIGN(x); \
+ inexact = mpfr_ui_div (y, 1, x, r); \
+ if (inexact == 0) /* x is a power of two */ \
+ { /* result always 1/x, except when rounding away from zero */ \
+ if (rnd_mode == MPFR_RNDA) \
+ rnd_mode = (signx > 0) ? MPFR_RNDU : MPFR_RNDD; \
+ if (rnd_mode == MPFR_RNDU) \
+ { \
+ if (signx > 0) \
+ mpfr_nextabove (y); /* 2^k + epsilon */ \
+ inexact = 1; \
+ } \
+ else if (rnd_mode == MPFR_RNDD) \
+ { \
+ if (signx < 0) \
+ mpfr_nextbelow (y); /* -2^k - epsilon */ \
+ inexact = -1; \
+ } \
+ else /* round to zero, or nearest */ \
+ inexact = -signx; \
+ } \
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); \
+ goto end; \
+ }
+
+#include "gen_inverse.h"
diff --git a/mpfr/src/csc.c b/mpfr/src/csc.c
new file mode 100644
index 0000000000..c9cc236239
--- /dev/null
+++ b/mpfr/src/csc.c
@@ -0,0 +1,76 @@
+/* mpfr_csc - cosecant function.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* the cosecant is defined by csc(x) = 1/sin(x).
+ csc (NaN) = NaN.
+ csc (+Inf) = csc (-Inf) = NaN.
+ csc (+0) = +Inf.
+ csc (-0) = -Inf.
+*/
+
+#define FUNCTION mpfr_csc
+#define INVERSE mpfr_sin
+#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_INF(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_ZERO(y,x) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_INF(y); \
+ mpfr_set_divby0 (); MPFR_RET(0); } while (1)
+/* near x=0, we have csc(x) = 1/x + x/6 + ..., more precisely we have
+ |csc(x) - 1/x| <= 0.2 for |x| <= 1. The analysis is similar to that for
+ gamma(x) near x=0 (see gamma.c), except here the error term has the same
+ sign as 1/x, thus |csc(x)| >= |1/x|. Then:
+ (i) either x is a power of two, then 1/x is exactly representable, and
+ as long as 1/2*ulp(1/x) > 0.2, we can conclude;
+ (ii) otherwise assume x has <= n bits, and y has <= n+1 bits, then
+ |y - 1/x| >= 2^(-2n) ufp(y), where ufp means unit in first place.
+ Since |csc(x) - 1/x| <= 0.2, if 2^(-2n) ufp(y) >= 0.4, then
+ |y - csc(x)| >= 2^(-2n-1) ufp(y), and rounding 1/x gives the correct result.
+ If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
+ A sufficient condition is thus EXP(x) <= -2 MAX(PREC(x),PREC(Y)). */
+#define ACTION_TINY(y,x,r) \
+ if (MPFR_EXP(x) <= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(y))) \
+ { \
+ int signx = MPFR_SIGN(x); \
+ inexact = mpfr_ui_div (y, 1, x, r); \
+ if (inexact == 0) /* x is a power of two */ \
+ { /* result always 1/x, except when rounding away from zero */ \
+ if (rnd_mode == MPFR_RNDA) \
+ rnd_mode = (signx > 0) ? MPFR_RNDU : MPFR_RNDD; \
+ if (rnd_mode == MPFR_RNDU) \
+ { \
+ if (signx > 0) \
+ mpfr_nextabove (y); /* 2^k + epsilon */ \
+ inexact = 1; \
+ } \
+ else if (rnd_mode == MPFR_RNDD) \
+ { \
+ if (signx < 0) \
+ mpfr_nextbelow (y); /* -2^k - epsilon */ \
+ inexact = -1; \
+ } \
+ else /* round to zero, or nearest */ \
+ inexact = -signx; \
+ } \
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); \
+ goto end; \
+ }
+
+#include "gen_inverse.h"
diff --git a/mpfr/src/csch.c b/mpfr/src/csch.c
new file mode 100644
index 0000000000..2eecaf7db9
--- /dev/null
+++ b/mpfr/src/csch.c
@@ -0,0 +1,79 @@
+/* mpfr_csch - Hyperbolic cosecant function.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* the hyperbolic cosecant is defined by csch(x) = 1/sinh(x).
+ csch (NaN) = NaN.
+ csch (+Inf) = +0.
+ csch (-Inf) = -0.
+ csch (+0) = +Inf.
+ csch (-0) = -Inf.
+*/
+
+#define FUNCTION mpfr_csch
+#define INVERSE mpfr_sinh
+#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_INF(y) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_ZERO (y); \
+ MPFR_RET(0); } while (1)
+#define ACTION_ZERO(y,x) do { MPFR_SET_SAME_SIGN(y,x); MPFR_SET_INF(y); \
+ mpfr_set_divby0 (); MPFR_RET(0); } while (1)
+
+/* (This analysis is adapted from that for mpfr_csc.)
+ Near x=0, we have csch(x) = 1/x - x/6 + ..., more precisely we have
+ |csch(x) - 1/x| <= 0.2 for |x| <= 1. The error term has the opposite
+ sign as 1/x, thus |csch(x)| <= |1/x|. Then:
+ (i) either x is a power of two, then 1/x is exactly representable, and
+ as long as 1/2*ulp(1/x) > 0.2, we can conclude;
+ (ii) otherwise assume x has <= n bits, and y has <= n+1 bits, then
+ |y - 1/x| >= 2^(-2n) ufp(y), where ufp means unit in first place.
+ Since |csch(x) - 1/x| <= 0.2, if 2^(-2n) ufp(y) >= 0.4, then
+ |y - csch(x)| >= 2^(-2n-1) ufp(y), and rounding 1/x gives the correct
+ result. If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
+ A sufficient condition is thus EXP(x) <= -2 MAX(PREC(x),PREC(Y)). */
+#define ACTION_TINY(y,x,r) \
+ if (MPFR_EXP(x) <= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(y))) \
+ { \
+ int signx = MPFR_SIGN(x); \
+ inexact = mpfr_ui_div (y, 1, x, r); \
+ if (inexact == 0) /* x is a power of two */ \
+ { /* result always 1/x, except when rounding to zero */ \
+ if (rnd_mode == MPFR_RNDA) \
+ rnd_mode = (signx > 0) ? MPFR_RNDU : MPFR_RNDD; \
+ if (rnd_mode == MPFR_RNDU || (rnd_mode == MPFR_RNDZ && signx < 0)) \
+ { \
+ if (signx < 0) \
+ mpfr_nextabove (y); /* -2^k + epsilon */ \
+ inexact = 1; \
+ } \
+ else if (rnd_mode == MPFR_RNDD || rnd_mode == MPFR_RNDZ) \
+ { \
+ if (signx > 0) \
+ mpfr_nextbelow (y); /* 2^k - epsilon */ \
+ inexact = -1; \
+ } \
+ else /* round to nearest */ \
+ inexact = signx; \
+ } \
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); \
+ goto end; \
+ }
+
+#include "gen_inverse.h"
diff --git a/mpfr/src/d_div.c b/mpfr/src/d_div.c
new file mode 100644
index 0000000000..4ddac9d840
--- /dev/null
+++ b/mpfr/src/d_div.c
@@ -0,0 +1,50 @@
+/* mpfr_d_div -- divide a machine double precision float
+ by a multiple precision floating-point number
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_d_div (mpfr_ptr a, double b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t d;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC (
+ ("b=%.20g c[%Pu]=%*.Rg rnd=%d", b, mpfr_get_prec (c), mpfr_log_prec, c, rnd_mode),
+ ("a[%Pu]=%*.Rg", mpfr_get_prec (a), mpfr_log_prec, a));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ inexact = mpfr_set_d (d, b, rnd_mode);
+ MPFR_ASSERTN (inexact == 0);
+
+ mpfr_clear_flags ();
+ inexact = mpfr_div (a, d, c, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
+ mpfr_clear(d);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (a, inexact, rnd_mode);
+}
diff --git a/mpfr/src/d_sub.c b/mpfr/src/d_sub.c
new file mode 100644
index 0000000000..59d810f264
--- /dev/null
+++ b/mpfr/src/d_sub.c
@@ -0,0 +1,50 @@
+/* mpfr_d_sub -- subtract a multiple precision floating-point number
+ from a machine double precision float
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_d_sub (mpfr_ptr a, double b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t d;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC (
+ ("b=%.20g c[%Pu]=%*.Rg rnd=%d", b, mpfr_get_prec (c), mpfr_log_prec, c, rnd_mode),
+ ("a[%Pu]=%*.Rg", mpfr_get_prec (a), mpfr_log_prec, a));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ inexact = mpfr_set_d (d, b, rnd_mode);
+ MPFR_ASSERTN (inexact == 0);
+
+ mpfr_clear_flags ();
+ inexact = mpfr_sub (a, d, c, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
+ mpfr_clear(d);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (a, inexact, rnd_mode);
+}
diff --git a/mpfr/src/digamma.c b/mpfr/src/digamma.c
new file mode 100644
index 0000000000..9eb971cae7
--- /dev/null
+++ b/mpfr/src/digamma.c
@@ -0,0 +1,378 @@
+/* mpfr_digamma -- digamma function of a floating-point number
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Put in s an approximation of digamma(x).
+ Assumes x >= 2.
+ Assumes s does not overlap with x.
+ Returns an integer e such that the error is bounded by 2^e ulps
+ of the result s.
+*/
+static mpfr_exp_t
+mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
+{
+ mpfr_prec_t p = MPFR_PREC (s);
+ mpfr_t t, u, invxx;
+ mpfr_exp_t e, exps, f, expu;
+ mpz_t *INITIALIZED(B); /* variable B declared as initialized */
+ unsigned long n0, n; /* number of allocated B[] */
+
+ MPFR_ASSERTN(MPFR_IS_POS(x) && (MPFR_EXP(x) >= 2));
+
+ mpfr_init2 (t, p);
+ mpfr_init2 (u, p);
+ mpfr_init2 (invxx, p);
+
+ mpfr_log (s, x, MPFR_RNDN); /* error <= 1/2 ulp */
+ mpfr_ui_div (t, 1, x, MPFR_RNDN); /* error <= 1/2 ulp */
+ mpfr_div_2exp (t, t, 1, MPFR_RNDN); /* exact */
+ mpfr_sub (s, s, t, MPFR_RNDN);
+ /* error <= 1/2 + 1/2*2^(EXP(olds)-EXP(s)) + 1/2*2^(EXP(t)-EXP(s)).
+ For x >= 2, log(x) >= 2*(1/(2x)), thus olds >= 2t, and olds - t >= olds/2,
+ thus 0 <= EXP(olds)-EXP(s) <= 1, and EXP(t)-EXP(s) <= 0, thus
+ error <= 1/2 + 1/2*2 + 1/2 <= 2 ulps. */
+ e = 2; /* initial error */
+ mpfr_mul (invxx, x, x, MPFR_RNDZ); /* invxx = x^2 * (1 + theta)
+ for |theta| <= 2^(-p) */
+ mpfr_ui_div (invxx, 1, invxx, MPFR_RNDU); /* invxx = 1/x^2 * (1 + theta)^2 */
+
+ /* in the following we note err=xxx when the ratio between the approximation
+ and the exact result can be written (1 + theta)^xxx for |theta| <= 2^(-p),
+ following Higham's method */
+ B = mpfr_bernoulli_internal ((mpz_t *) 0, 0);
+ mpfr_set_ui (t, 1, MPFR_RNDN); /* err = 0 */
+ for (n = 1;; n++)
+ {
+ /* compute next Bernoulli number */
+ B = mpfr_bernoulli_internal (B, n);
+ /* The main term is Bernoulli[2n]/(2n)/x^(2n) = B[n]/(2n+1)!(2n)/x^(2n)
+ = B[n]*t[n]/(2n) where t[n]/t[n-1] = 1/(2n)/(2n+1)/x^2. */
+ mpfr_mul (t, t, invxx, MPFR_RNDU); /* err = err + 3 */
+ mpfr_div_ui (t, t, 2 * n, MPFR_RNDU); /* err = err + 1 */
+ mpfr_div_ui (t, t, 2 * n + 1, MPFR_RNDU); /* err = err + 1 */
+ /* we thus have err = 5n here */
+ mpfr_div_ui (u, t, 2 * n, MPFR_RNDU); /* err = 5n+1 */
+ mpfr_mul_z (u, u, B[n], MPFR_RNDU); /* err = 5n+2, and the
+ absolute error is bounded
+ by 10n+4 ulp(u) [Rule 11] */
+ /* if the terms 'u' are decreasing by a factor two at least,
+ then the error coming from those is bounded by
+ sum((10n+4)/2^n, n=1..infinity) = 24 */
+ exps = mpfr_get_exp (s);
+ expu = mpfr_get_exp (u);
+ if (expu < exps - (mpfr_exp_t) p)
+ break;
+ mpfr_sub (s, s, u, MPFR_RNDN); /* error <= 24 + n/2 */
+ if (mpfr_get_exp (s) < exps)
+ e <<= exps - mpfr_get_exp (s);
+ e ++; /* error in mpfr_sub */
+ f = 10 * n + 4;
+ while (expu < exps)
+ {
+ f = (1 + f) / 2;
+ expu ++;
+ }
+ e += f; /* total rouding error coming from 'u' term */
+ }
+
+ n0 = ++n;
+ while (n--)
+ mpz_clear (B[n]);
+ (*__gmp_free_func) (B, n0 * sizeof (mpz_t));
+
+ mpfr_clear (t);
+ mpfr_clear (u);
+ mpfr_clear (invxx);
+
+ f = 0;
+ while (e > 1)
+ {
+ f++;
+ e = (e + 1) / 2;
+ /* Invariant: 2^f * e does not decrease */
+ }
+ return f;
+}
+
+/* Use the reflection formula Digamma(1-x) = Digamma(x) + Pi * cot(Pi*x),
+ i.e., Digamma(x) = Digamma(1-x) - Pi * cot(Pi*x).
+ Assume x < 1/2. */
+static int
+mpfr_digamma_reflection (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t p = MPFR_PREC(y) + 10, q;
+ mpfr_t t, u, v;
+ mpfr_exp_t e1, expv;
+ int inex;
+ MPFR_ZIV_DECL (loop);
+
+ /* we want that 1-x is exact with precision q: if 0 < x < 1/2, then
+ q = PREC(x)-EXP(x) is ok, otherwise if -1 <= x < 0, q = PREC(x)-EXP(x)
+ is ok, otherwise for x < -1, PREC(x) is ok if EXP(x) <= PREC(x),
+ otherwise we need EXP(x) */
+ if (MPFR_EXP(x) < 0)
+ q = MPFR_PREC(x) + 1 - MPFR_EXP(x);
+ else if (MPFR_EXP(x) <= MPFR_PREC(x))
+ q = MPFR_PREC(x) + 1;
+ else
+ q = MPFR_EXP(x);
+ mpfr_init2 (u, q);
+ MPFR_ASSERTN(mpfr_ui_sub (u, 1, x, MPFR_RNDN) == 0);
+
+ /* if x is half an integer, cot(Pi*x) = 0, thus Digamma(x) = Digamma(1-x) */
+ mpfr_mul_2exp (u, u, 1, MPFR_RNDN);
+ inex = mpfr_integer_p (u);
+ mpfr_div_2exp (u, u, 1, MPFR_RNDN);
+ if (inex)
+ {
+ inex = mpfr_digamma (y, u, rnd_mode);
+ goto end;
+ }
+
+ mpfr_init2 (t, p);
+ mpfr_init2 (v, p);
+
+ MPFR_ZIV_INIT (loop, p);
+ for (;;)
+ {
+ mpfr_const_pi (v, MPFR_RNDN); /* v = Pi*(1+theta) for |theta|<=2^(-p) */
+ mpfr_mul (t, v, x, MPFR_RNDN); /* (1+theta)^2 */
+ e1 = MPFR_EXP(t) - (mpfr_exp_t) p + 1; /* bound for t: err(t) <= 2^e1 */
+ mpfr_cot (t, t, MPFR_RNDN);
+ /* cot(t * (1+h)) = cot(t) - theta * (1 + cot(t)^2) with |theta|<=t*h */
+ if (MPFR_EXP(t) > 0)
+ e1 = e1 + 2 * MPFR_EXP(t) + 1;
+ else
+ e1 = e1 + 1;
+ /* now theta * (1 + cot(t)^2) <= 2^e1 */
+ e1 += (mpfr_exp_t) p - MPFR_EXP(t); /* error is now 2^e1 ulps */
+ mpfr_mul (t, t, v, MPFR_RNDN);
+ e1 ++;
+ mpfr_digamma (v, u, MPFR_RNDN); /* error <= 1/2 ulp */
+ expv = MPFR_EXP(v);
+ mpfr_sub (v, v, t, MPFR_RNDN);
+ if (MPFR_EXP(v) < MPFR_EXP(t))
+ e1 += MPFR_EXP(t) - MPFR_EXP(v); /* scale error for t wrt new v */
+ /* now take into account the 1/2 ulp error for v */
+ if (expv - MPFR_EXP(v) - 1 > e1)
+ e1 = expv - MPFR_EXP(v) - 1;
+ else
+ e1 ++;
+ e1 ++; /* rounding error for mpfr_sub */
+ if (MPFR_CAN_ROUND (v, p - e1, MPFR_PREC(y), rnd_mode))
+ break;
+ MPFR_ZIV_NEXT (loop, p);
+ mpfr_set_prec (t, p);
+ mpfr_set_prec (v, p);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inex = mpfr_set (y, v, rnd_mode);
+
+ mpfr_clear (t);
+ mpfr_clear (v);
+ end:
+ mpfr_clear (u);
+
+ return inex;
+}
+
+/* we have x >= 1/2 here */
+static int
+mpfr_digamma_positive (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t p = MPFR_PREC(y) + 10, q;
+ mpfr_t t, u, x_plus_j;
+ int inex;
+ mpfr_exp_t errt, erru, expt;
+ unsigned long j = 0, min;
+ MPFR_ZIV_DECL (loop);
+
+ /* compute a precision q such that x+1 is exact */
+ if (MPFR_PREC(x) < MPFR_EXP(x))
+ q = MPFR_EXP(x);
+ else
+ q = MPFR_PREC(x) + 1;
+ mpfr_init2 (x_plus_j, q);
+
+ mpfr_init2 (t, p);
+ mpfr_init2 (u, p);
+ MPFR_ZIV_INIT (loop, p);
+ for(;;)
+ {
+ /* Lower bound for x+j in mpfr_digamma_approx call: since the smallest
+ term of the divergent series for Digamma(x) is about exp(-2*Pi*x), and
+ we want it to be less than 2^(-p), this gives x > p*log(2)/(2*Pi)
+ i.e., x >= 0.1103 p.
+ To be safe, we ensure x >= 0.25 * p.
+ */
+ min = (p + 3) / 4;
+ if (min < 2)
+ min = 2;
+
+ mpfr_set (x_plus_j, x, MPFR_RNDN);
+ mpfr_set_ui (u, 0, MPFR_RNDN);
+ j = 0;
+ while (mpfr_cmp_ui (x_plus_j, min) < 0)
+ {
+ j ++;
+ mpfr_ui_div (t, 1, x_plus_j, MPFR_RNDN); /* err <= 1/2 ulp */
+ mpfr_add (u, u, t, MPFR_RNDN);
+ inex = mpfr_add_ui (x_plus_j, x_plus_j, 1, MPFR_RNDZ);
+ if (inex != 0) /* we lost one bit */
+ {
+ q ++;
+ mpfr_prec_round (x_plus_j, q, MPFR_RNDZ);
+ mpfr_nextabove (x_plus_j);
+ }
+ /* since all terms are positive, the error is bounded by j ulps */
+ }
+ for (erru = 0; j > 1; erru++, j = (j + 1) / 2);
+ errt = mpfr_digamma_approx (t, x_plus_j);
+ expt = MPFR_EXP(t);
+ mpfr_sub (t, t, u, MPFR_RNDN);
+ if (MPFR_EXP(t) < expt)
+ errt += expt - MPFR_EXP(t);
+ if (MPFR_EXP(t) < MPFR_EXP(u))
+ erru += MPFR_EXP(u) - MPFR_EXP(t);
+ if (errt > erru)
+ errt = errt + 1;
+ else if (errt == erru)
+ errt = errt + 2;
+ else
+ errt = erru + 1;
+ if (MPFR_CAN_ROUND (t, p - errt, MPFR_PREC(y), rnd_mode))
+ break;
+ MPFR_ZIV_NEXT (loop, p);
+ mpfr_set_prec (t, p);
+ mpfr_set_prec (u, p);
+ }
+ MPFR_ZIV_FREE (loop);
+ inex = mpfr_set (y, t, rnd_mode);
+ mpfr_clear (t);
+ mpfr_clear (u);
+ mpfr_clear (x_plus_j);
+ return inex;
+}
+
+int
+mpfr_digamma (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y, inex));
+
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
+ {
+ if (MPFR_IS_NAN(x))
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF(x))
+ {
+ if (MPFR_IS_POS(x)) /* Digamma(+Inf) = +Inf */
+ {
+ MPFR_SET_SAME_SIGN(y, x);
+ MPFR_SET_INF(y);
+ MPFR_RET(0);
+ }
+ else /* Digamma(-Inf) = NaN */
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+ }
+ else /* Zero case */
+ {
+ /* the following works also in case of overlap */
+ MPFR_SET_INF(y);
+ MPFR_SET_OPPOSITE_SIGN(y, x);
+ mpfr_set_divby0 ();
+ MPFR_RET(0);
+ }
+ }
+
+ /* Digamma is undefined for negative integers */
+ if (MPFR_IS_NEG(x) && mpfr_integer_p (x))
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+
+ /* now x is a normal number */
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ /* for x very small, we have Digamma(x) = -1/x - gamma + O(x), more precisely
+ -1 < Digamma(x) + 1/x < 0 for -0.2 < x < 0.2, thus:
+ (i) either x is a power of two, then 1/x is exactly representable, and
+ as long as 1/2*ulp(1/x) > 1, we can conclude;
+ (ii) otherwise assume x has <= n bits, and y has <= n+1 bits, then
+ |y + 1/x| >= 2^(-2n) ufp(y), where ufp means unit in first place.
+ Since |Digamma(x) + 1/x| <= 1, if 2^(-2n) ufp(y) >= 2, then
+ |y - Digamma(x)| >= 2^(-2n-1)ufp(y), and rounding -1/x gives the correct result.
+ If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
+ A sufficient condition is thus EXP(x) <= -2 MAX(PREC(x),PREC(Y)). */
+ if (MPFR_EXP(x) < -2)
+ {
+ if (MPFR_EXP(x) <= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(y)))
+ {
+ int signx = MPFR_SIGN(x);
+ inex = mpfr_si_div (y, -1, x, rnd_mode);
+ if (inex == 0) /* x is a power of two */
+ { /* result always -1/x, except when rounding down */
+ if (rnd_mode == MPFR_RNDA)
+ rnd_mode = (signx > 0) ? MPFR_RNDD : MPFR_RNDU;
+ if (rnd_mode == MPFR_RNDZ)
+ rnd_mode = (signx > 0) ? MPFR_RNDU : MPFR_RNDD;
+ if (rnd_mode == MPFR_RNDU)
+ inex = 1;
+ else if (rnd_mode == MPFR_RNDD)
+ {
+ mpfr_nextbelow (y);
+ inex = -1;
+ }
+ else /* nearest */
+ inex = 1;
+ }
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ goto end;
+ }
+ }
+
+ if (MPFR_IS_NEG(x))
+ inex = mpfr_digamma_reflection (y, x, rnd_mode);
+ /* if x < 1/2 we use the reflection formula */
+ else if (MPFR_EXP(x) < 0)
+ inex = mpfr_digamma_reflection (y, x, rnd_mode);
+ else
+ inex = mpfr_digamma_positive (y, x, rnd_mode);
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd_mode);
+}
diff --git a/mpfr/src/dim.c b/mpfr/src/dim.c
new file mode 100644
index 0000000000..29cab12f2c
--- /dev/null
+++ b/mpfr/src/dim.c
@@ -0,0 +1,48 @@
+/* mpfr_dim -- positive difference
+
+Copyright 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* dim (x,y) is defined as:
+
+ x-y if x > y
+ +0 if x <= y
+*/
+
+int
+mpfr_dim (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y))
+ {
+ MPFR_SET_NAN(z);
+ MPFR_RET_NAN;
+ }
+
+ if (mpfr_cmp (x,y) > 0)
+ return mpfr_sub (z, x, y, rnd_mode);
+ else
+ {
+ MPFR_SET_ZERO(z);
+ MPFR_SET_POS(z);
+ MPFR_RET(0);
+ }
+}
diff --git a/mpfr/src/div.c b/mpfr/src/div.c
new file mode 100644
index 0000000000..e6834821b1
--- /dev/null
+++ b/mpfr/src/div.c
@@ -0,0 +1,790 @@
+/* mpfr_div -- divide two floating-point numbers
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* References:
+ [1] Short Division of Long Integers, David Harvey and Paul Zimmermann,
+ Proceedings of the 20th Symposium on Computer Arithmetic (ARITH-20),
+ July 25-27, 2011, pages 7-14.
+*/
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#ifdef DEBUG2
+#define mpfr_mpn_print(ap,n) mpfr_mpn_print3 (ap,n,MPFR_LIMB_ZERO)
+static void
+mpfr_mpn_print3 (mpfr_limb_ptr ap, mp_size_t n, mp_limb_t cy)
+{
+ mp_size_t i;
+ for (i = 0; i < n; i++)
+ printf ("+%lu*2^%lu", (unsigned long) ap[i], (unsigned long)
+ (GMP_NUMB_BITS * i));
+ if (cy)
+ printf ("+2^%lu", (unsigned long) (GMP_NUMB_BITS * n));
+ printf ("\n");
+}
+#endif
+
+/* check if {ap, an} is zero */
+static int
+mpfr_mpn_cmpzero (mpfr_limb_ptr ap, mp_size_t an)
+{
+ while (an > 0)
+ if (MPFR_LIKELY(ap[--an] != MPFR_LIMB_ZERO))
+ return 1;
+ return 0;
+}
+
+/* compare {ap, an} and {bp, bn} >> extra,
+ aligned by the more significant limbs.
+ Takes into account bp[0] for extra=1.
+*/
+static int
+mpfr_mpn_cmp_aux (mpfr_limb_ptr ap, mp_size_t an,
+ mpfr_limb_ptr bp, mp_size_t bn, int extra)
+{
+ int cmp = 0;
+ mp_size_t k;
+ mp_limb_t bb;
+
+ if (an >= bn)
+ {
+ k = an - bn;
+ while (cmp == 0 && bn > 0)
+ {
+ bn --;
+ bb = (extra) ? ((bp[bn+1] << (GMP_NUMB_BITS - 1)) | (bp[bn] >> 1))
+ : bp[bn];
+ cmp = (ap[k + bn] > bb) ? 1 : ((ap[k + bn] < bb) ? -1 : 0);
+ }
+ bb = (extra) ? bp[0] << (GMP_NUMB_BITS - 1) : MPFR_LIMB_ZERO;
+ while (cmp == 0 && k > 0)
+ {
+ k--;
+ cmp = (ap[k] > bb) ? 1 : ((ap[k] < bb) ? -1 : 0);
+ bb = MPFR_LIMB_ZERO; /* ensure we consider only once bp[0] & 1 */
+ }
+ if (cmp == 0 && bb != MPFR_LIMB_ZERO)
+ cmp = -1;
+ }
+ else /* an < bn */
+ {
+ k = bn - an;
+ while (cmp == 0 && an > 0)
+ {
+ an --;
+ bb = (extra) ? ((bp[k+an+1] << (GMP_NUMB_BITS - 1)) | (bp[k+an] >> 1))
+ : bp[k+an];
+ if (ap[an] > bb)
+ cmp = 1;
+ else if (ap[an] < bb)
+ cmp = -1;
+ }
+ while (cmp == 0 && k > 0)
+ {
+ k--;
+ bb = (extra) ? ((bp[k+1] << (GMP_NUMB_BITS - 1)) | (bp[k] >> 1))
+ : bp[k];
+ cmp = (bb != MPFR_LIMB_ZERO) ? -1 : 0;
+ }
+ if (cmp == 0 && extra && (bp[0] & MPFR_LIMB_ONE))
+ cmp = -1;
+ }
+ return cmp;
+}
+
+/* {ap, n} <- {ap, n} - {bp, n} >> extra - cy, with cy = 0 or 1.
+ Return borrow out.
+*/
+static mp_limb_t
+mpfr_mpn_sub_aux (mpfr_limb_ptr ap, mpfr_limb_ptr bp, mp_size_t n,
+ mp_limb_t cy, int extra)
+{
+ mp_limb_t bb, rp;
+
+ MPFR_ASSERTD (cy <= 1);
+ while (n--)
+ {
+ bb = (extra) ? ((bp[1] << (GMP_NUMB_BITS-1)) | (bp[0] >> 1)) : bp[0];
+ rp = ap[0] - bb - cy;
+ cy = (ap[0] < bb) || (cy && ~rp == MPFR_LIMB_ZERO) ?
+ MPFR_LIMB_ONE : MPFR_LIMB_ZERO;
+ ap[0] = rp;
+ ap ++;
+ bp ++;
+ }
+ MPFR_ASSERTD (cy <= 1);
+ return cy;
+}
+
+int
+mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode)
+{
+ mp_size_t q0size = MPFR_LIMB_SIZE(q); /* number of limbs of destination */
+ mp_size_t usize = MPFR_LIMB_SIZE(u);
+ mp_size_t vsize = MPFR_LIMB_SIZE(v);
+ mp_size_t qsize; /* number of limbs wanted for the computed quotient */
+ mp_size_t qqsize;
+ mp_size_t k;
+ mpfr_limb_ptr q0p = MPFR_MANT(q), qp;
+ mpfr_limb_ptr up = MPFR_MANT(u);
+ mpfr_limb_ptr vp = MPFR_MANT(v);
+ mpfr_limb_ptr ap;
+ mpfr_limb_ptr bp;
+ mp_limb_t qh;
+ mp_limb_t sticky_u = MPFR_LIMB_ZERO;
+ mp_limb_t low_u;
+ mp_limb_t sticky_v = MPFR_LIMB_ZERO;
+ mp_limb_t sticky;
+ mp_limb_t sticky3;
+ mp_limb_t round_bit = MPFR_LIMB_ZERO;
+ mpfr_exp_t qexp;
+ int sign_quotient;
+ int extra_bit;
+ int sh, sh2;
+ int inex;
+ int like_rndz;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_LOG_FUNC (
+ ("u[%Pu]=%.*Rg v[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec(u), mpfr_log_prec, u,
+ mpfr_get_prec (v),mpfr_log_prec, v, rnd_mode),
+ ("q[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(q), mpfr_log_prec, q, inex));
+
+ /**************************************************************************
+ * *
+ * This part of the code deals with special cases *
+ * *
+ **************************************************************************/
+
+ if (MPFR_UNLIKELY(MPFR_ARE_SINGULAR(u,v)))
+ {
+ if (MPFR_IS_NAN(u) || MPFR_IS_NAN(v))
+ {
+ MPFR_SET_NAN(q);
+ MPFR_RET_NAN;
+ }
+ sign_quotient = MPFR_MULT_SIGN( MPFR_SIGN(u) , MPFR_SIGN(v) );
+ MPFR_SET_SIGN(q, sign_quotient);
+ if (MPFR_IS_INF(u))
+ {
+ if (MPFR_IS_INF(v))
+ {
+ MPFR_SET_NAN(q);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ MPFR_SET_INF(q);
+ MPFR_RET(0);
+ }
+ }
+ else if (MPFR_IS_INF(v))
+ {
+ MPFR_SET_ZERO (q);
+ MPFR_RET (0);
+ }
+ else if (MPFR_IS_ZERO (v))
+ {
+ if (MPFR_IS_ZERO (u))
+ {
+ MPFR_SET_NAN(q);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ MPFR_ASSERTD (! MPFR_IS_INF (u));
+ MPFR_SET_INF(q);
+ mpfr_set_divby0 ();
+ MPFR_RET(0);
+ }
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (u));
+ MPFR_SET_ZERO (q);
+ MPFR_RET (0);
+ }
+ }
+
+ /**************************************************************************
+ * *
+ * End of the part concerning special values. *
+ * *
+ **************************************************************************/
+
+ MPFR_TMP_MARK(marker);
+
+ /* set sign */
+ sign_quotient = MPFR_MULT_SIGN( MPFR_SIGN(u) , MPFR_SIGN(v) );
+ MPFR_SET_SIGN(q, sign_quotient);
+
+ /* determine if an extra bit comes from the division, i.e. if the
+ significand of u (as a fraction in [1/2, 1[) is larger than that
+ of v */
+ if (MPFR_LIKELY(up[usize - 1] != vp[vsize - 1]))
+ extra_bit = (up[usize - 1] > vp[vsize - 1]) ? 1 : 0;
+ else /* most significant limbs are equal, must look at further limbs */
+ {
+ mp_size_t l;
+
+ k = usize - 1;
+ l = vsize - 1;
+ while (k != 0 && l != 0 && up[--k] == vp[--l]);
+ /* now k=0 or l=0 or up[k] != vp[l] */
+ if (up[k] > vp[l])
+ extra_bit = 1;
+ else if (up[k] < vp[l])
+ extra_bit = 0;
+ /* now up[k] = vp[l], thus either k=0 or l=0 */
+ else if (l == 0) /* no more divisor limb */
+ extra_bit = 1;
+ else /* k=0: no more dividend limb */
+ extra_bit = mpfr_mpn_cmpzero (vp, l) == 0;
+ }
+#ifdef DEBUG
+ printf ("extra_bit=%d\n", extra_bit);
+#endif
+
+ /* set exponent */
+ qexp = MPFR_GET_EXP (u) - MPFR_GET_EXP (v) + extra_bit;
+
+ /* sh is the number of zero bits in the low limb of the quotient */
+ MPFR_UNSIGNED_MINUS_MODULO(sh, MPFR_PREC(q));
+
+ like_rndz = rnd_mode == MPFR_RNDZ ||
+ rnd_mode == (sign_quotient < 0 ? MPFR_RNDU : MPFR_RNDD);
+
+ /**************************************************************************
+ * *
+ * We first try Mulders' short division (for large operands) *
+ * *
+ **************************************************************************/
+
+ if (MPFR_UNLIKELY(q0size >= MPFR_DIV_THRESHOLD &&
+ vsize >= MPFR_DIV_THRESHOLD))
+ {
+ mp_size_t n = q0size + 1; /* we will perform a short (2n)/n division */
+ mpfr_limb_ptr ap, bp, qp;
+ mpfr_prec_t p;
+
+ /* since Mulders' short division clobbers the dividend, we have to
+ copy it */
+ ap = MPFR_TMP_LIMBS_ALLOC (n + n);
+ if (usize >= n + n) /* truncate the dividend */
+ MPN_COPY(ap, up + usize - (n + n), n + n);
+ else /* zero-pad the dividend */
+ {
+ MPN_COPY(ap + (n + n) - usize, up, usize);
+ MPN_ZERO(ap, (n + n) - usize);
+ }
+
+ if (vsize >= n) /* truncate the divisor */
+ bp = vp + vsize - n;
+ else /* zero-pad the divisor */
+ {
+ bp = MPFR_TMP_LIMBS_ALLOC (n);
+ MPN_COPY(bp + n - vsize, vp, vsize);
+ MPN_ZERO(bp, n - vsize);
+ }
+
+ qp = MPFR_TMP_LIMBS_ALLOC (n);
+ qh = mpfr_divhigh_n (qp, ap, bp, n);
+ /* in all cases, the error is at most (2n+2) ulps on qh*B^n+{qp,n},
+ cf algorithms.tex */
+
+ p = n * GMP_NUMB_BITS - MPFR_INT_CEIL_LOG2 (2 * n + 2);
+ /* if qh is 1, then we need only PREC(q)-1 bits of {qp,n},
+ if rnd=RNDN, we need to be able to round with a directed rounding
+ and one more bit */
+ if (MPFR_LIKELY (mpfr_round_p (qp, n, p,
+ MPFR_PREC(q) + (rnd_mode == MPFR_RNDN) - qh)))
+ {
+ /* we can round correctly whatever the rounding mode */
+ if (qh == 0)
+ MPN_COPY (q0p, qp + 1, q0size);
+ else
+ {
+ mpn_rshift (q0p, qp + 1, q0size, 1);
+ q0p[q0size - 1] ^= MPFR_LIMB_HIGHBIT;
+ }
+ q0p[0] &= ~MPFR_LIMB_MASK(sh); /* put to zero low sh bits */
+
+ if (rnd_mode == MPFR_RNDN) /* round to nearest */
+ {
+ /* we know we can round, thus we are never in the even rule case:
+ if the round bit is 0, we truncate
+ if the round bit is 1, we add 1 */
+ if (qh == 0)
+ {
+ if (sh > 0)
+ round_bit = (qp[1] >> (sh - 1)) & 1;
+ else
+ round_bit = qp[0] >> (GMP_NUMB_BITS - 1);
+ }
+ else /* qh = 1 */
+ round_bit = (qp[1] >> sh) & 1;
+ if (round_bit == 0)
+ {
+ inex = -1;
+ goto truncate;
+ }
+ else /* round_bit = 1 */
+ goto add_one_ulp;
+ }
+ else if (like_rndz == 0) /* round away */
+ goto add_one_ulp;
+ /* else round to zero: nothing to do */
+ else
+ {
+ inex = -1;
+ goto truncate;
+ }
+ }
+ }
+
+ /**************************************************************************
+ * *
+ * Mulders' short division failed: we revert to integer division *
+ * *
+ **************************************************************************/
+
+ if (MPFR_UNLIKELY(rnd_mode == MPFR_RNDN && sh == 0))
+ { /* we compute the quotient with one more limb, in order to get
+ the round bit in the quotient, and the remainder only contains
+ sticky bits */
+ qsize = q0size + 1;
+ /* need to allocate memory for the quotient */
+ qp = MPFR_TMP_LIMBS_ALLOC (qsize);
+ }
+ else
+ {
+ qsize = q0size;
+ qp = q0p; /* directly put the quotient in the destination */
+ }
+ qqsize = qsize + qsize;
+
+ /* prepare the dividend */
+ ap = MPFR_TMP_LIMBS_ALLOC (qqsize);
+ if (MPFR_LIKELY(qqsize > usize)) /* use the full dividend */
+ {
+ k = qqsize - usize; /* k > 0 */
+ MPN_ZERO(ap, k);
+ if (extra_bit)
+ ap[k - 1] = mpn_rshift (ap + k, up, usize, 1);
+ else
+ MPN_COPY(ap + k, up, usize);
+ }
+ else /* truncate the dividend */
+ {
+ k = usize - qqsize;
+ if (extra_bit)
+ sticky_u = mpn_rshift (ap, up + k, qqsize, 1);
+ else
+ MPN_COPY(ap, up + k, qqsize);
+ sticky_u = sticky_u || mpfr_mpn_cmpzero (up, k);
+ }
+ low_u = sticky_u;
+
+ /* now sticky_u is non-zero iff the truncated part of u is non-zero */
+
+ /* prepare the divisor */
+ if (MPFR_LIKELY(vsize >= qsize))
+ {
+ k = vsize - qsize;
+ if (qp != vp)
+ bp = vp + k; /* avoid copying the divisor */
+ else /* need to copy, since mpn_divrem doesn't allow overlap
+ between quotient and divisor, necessarily k = 0
+ since quotient and divisor are the same mpfr variable */
+ {
+ bp = MPFR_TMP_LIMBS_ALLOC (qsize);
+ MPN_COPY(bp, vp, vsize);
+ }
+ sticky_v = sticky_v || mpfr_mpn_cmpzero (vp, k);
+ k = 0;
+ }
+ else /* vsize < qsize: small divisor case */
+ {
+ bp = vp;
+ k = qsize - vsize;
+ }
+
+ /**************************************************************************
+ * *
+ * Here we perform the real division of {ap+k,qqsize-k} by {bp,qsize-k} *
+ * *
+ **************************************************************************/
+
+ /* if Mulders' short division failed, we revert to division with remainder */
+ qh = mpn_divrem (qp, 0, ap + k, qqsize - k, bp, qsize - k);
+ /* warning: qh may be 1 if u1 == v1, but u < v */
+#ifdef DEBUG2
+ printf ("q="); mpfr_mpn_print (qp, qsize);
+ printf ("r="); mpfr_mpn_print (ap, qsize);
+#endif
+
+ k = qsize;
+ sticky_u = sticky_u || mpfr_mpn_cmpzero (ap, k);
+
+ sticky = sticky_u | sticky_v;
+
+ /* now sticky is non-zero iff one of the following holds:
+ (a) the truncated part of u is non-zero
+ (b) the truncated part of v is non-zero
+ (c) the remainder from division is non-zero */
+
+ if (MPFR_LIKELY(qsize == q0size))
+ {
+ sticky3 = qp[0] & MPFR_LIMB_MASK(sh); /* does nothing when sh=0 */
+ sh2 = sh;
+ }
+ else /* qsize = q0size + 1: only happens when rnd_mode=MPFR_RNDN and sh=0 */
+ {
+ MPN_COPY (q0p, qp + 1, q0size);
+ sticky3 = qp[0];
+ sh2 = GMP_NUMB_BITS;
+ }
+ qp[0] ^= sticky3;
+ /* sticky3 contains the truncated bits from the quotient,
+ including the round bit, and 1 <= sh2 <= GMP_NUMB_BITS
+ is the number of bits in sticky3 */
+ inex = (sticky != MPFR_LIMB_ZERO) || (sticky3 != MPFR_LIMB_ZERO);
+#ifdef DEBUG
+ printf ("sticky=%lu sticky3=%lu inex=%d\n",
+ (unsigned long) sticky, (unsigned long) sticky3, inex);
+#endif
+
+ /* to round, we distinguish two cases:
+ (a) vsize <= qsize: we used the full divisor
+ (b) vsize > qsize: the divisor was truncated
+ */
+
+#ifdef DEBUG
+ printf ("vsize=%lu qsize=%lu\n",
+ (unsigned long) vsize, (unsigned long) qsize);
+#endif
+ if (MPFR_LIKELY(vsize <= qsize)) /* use the full divisor */
+ {
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ {
+ round_bit = sticky3 & (MPFR_LIMB_ONE << (sh2 - 1));
+ sticky = (sticky3 ^ round_bit) | sticky_u;
+ }
+ else if (like_rndz || inex == 0)
+ sticky = (inex == 0) ? MPFR_LIMB_ZERO : MPFR_LIMB_ONE;
+ else /* round away from zero */
+ sticky = MPFR_LIMB_ONE;
+ goto case_1;
+ }
+ else /* vsize > qsize: need to truncate the divisor */
+ {
+ if (inex == 0)
+ goto truncate;
+ else
+ {
+ /* We know the estimated quotient is an upper bound of the exact
+ quotient (with rounding toward zero), with a difference of at
+ most 2 in qp[0].
+ Thus we can round except when sticky3 is 000...000 or 000...001
+ for directed rounding, and 100...000 or 100...001 for rounding
+ to nearest. (For rounding to nearest, we cannot determine the
+ inexact flag for 000...000 or 000...001.)
+ */
+ mp_limb_t sticky3orig = sticky3;
+ if (rnd_mode == MPFR_RNDN)
+ {
+ round_bit = sticky3 & (MPFR_LIMB_ONE << (sh2 - 1));
+ sticky3 = sticky3 ^ round_bit;
+#ifdef DEBUG
+ printf ("rb=%lu sb=%lu\n",
+ (unsigned long) round_bit, (unsigned long) sticky3);
+#endif
+ }
+ if (sticky3 != MPFR_LIMB_ZERO && sticky3 != MPFR_LIMB_ONE)
+ {
+ sticky = sticky3;
+ goto case_1;
+ }
+ else /* hard case: we have to compare q1 * v0 and r + low(u),
+ where q1 * v0 has qsize + (vsize-qsize) = vsize limbs, and
+ r + low(u) has qsize + (usize-2*qsize) = usize-qsize limbs */
+ {
+ mp_size_t l;
+ mpfr_limb_ptr sp;
+ int cmp_s_r;
+ mp_limb_t qh2;
+
+ sp = MPFR_TMP_LIMBS_ALLOC (vsize);
+ k = vsize - qsize;
+ /* sp <- {qp, qsize} * {vp, vsize-qsize} */
+ qp[0] ^= sticky3orig; /* restore original quotient */
+ if (qsize >= k)
+ mpn_mul (sp, qp, qsize, vp, k);
+ else
+ mpn_mul (sp, vp, k, qp, qsize);
+ if (qh)
+ qh2 = mpn_add_n (sp + qsize, sp + qsize, vp, k);
+ else
+ qh2 = (mp_limb_t) 0;
+ qp[0] ^= sticky3orig; /* restore truncated quotient */
+
+ /* compare qh2 + {sp, k + qsize} to {ap, qsize} + low(u) */
+ cmp_s_r = (qh2 != 0) ? 1 : mpn_cmp (sp + k, ap, qsize);
+ if (cmp_s_r == 0) /* compare {sp, k} and low(u) */
+ {
+ cmp_s_r = (usize >= qqsize) ?
+ mpfr_mpn_cmp_aux (sp, k, up, usize - qqsize, extra_bit) :
+ mpfr_mpn_cmpzero (sp, k);
+ }
+#ifdef DEBUG
+ printf ("cmp(q*v0,r+u0)=%d\n", cmp_s_r);
+#endif
+ /* now cmp_s_r > 0 if {sp, vsize} > {ap, qsize} + low(u)
+ cmp_s_r = 0 if {sp, vsize} = {ap, qsize} + low(u)
+ cmp_s_r < 0 if {sp, vsize} < {ap, qsize} + low(u) */
+ if (cmp_s_r <= 0) /* quotient is in [q1, q1+1) */
+ {
+ sticky = (cmp_s_r == 0) ? sticky3 : MPFR_LIMB_ONE;
+ goto case_1;
+ }
+ else /* cmp_s_r > 0, quotient is < q1: to determine if it is
+ in [q1-2,q1-1] or in [q1-1,q1], we need to subtract
+ the low part u0 of the dividend u0 from q*v0 */
+ {
+ mp_limb_t cy = MPFR_LIMB_ZERO;
+
+ /* subtract low(u)>>extra_bit if non-zero */
+ if (qh2 != 0) /* whatever the value of {up, m + k}, it
+ will be smaller than qh2 + {sp, k} */
+ cmp_s_r = 1;
+ else
+ {
+ if (low_u != MPFR_LIMB_ZERO)
+ {
+ mp_size_t m;
+ l = usize - qqsize; /* number of low limbs in u */
+ m = (l > k) ? l - k : 0;
+ cy = (extra_bit) ?
+ (up[m] & MPFR_LIMB_ONE) : MPFR_LIMB_ZERO;
+ if (l >= k) /* u0 has more limbs than s:
+ first look if {up, m} is not zero,
+ and compare {sp, k} and {up + m, k} */
+ {
+ cy = cy || mpfr_mpn_cmpzero (up, m);
+ low_u = cy;
+ cy = mpfr_mpn_sub_aux (sp, up + m, k,
+ cy, extra_bit);
+ }
+ else /* l < k: s has more limbs than u0 */
+ {
+ low_u = MPFR_LIMB_ZERO;
+ if (cy != MPFR_LIMB_ZERO)
+ cy = mpn_sub_1 (sp + k - l - 1, sp + k - l - 1,
+ 1, MPFR_LIMB_HIGHBIT);
+ cy = mpfr_mpn_sub_aux (sp + k - l, up, l,
+ cy, extra_bit);
+ }
+ }
+ MPFR_ASSERTD (cy <= 1);
+ cy = mpn_sub_1 (sp + k, sp + k, qsize, cy);
+ /* subtract r */
+ cy += mpn_sub_n (sp + k, sp + k, ap, qsize);
+ MPFR_ASSERTD (cy <= 1);
+ /* now compare {sp, ssize} to v */
+ cmp_s_r = mpn_cmp (sp, vp, vsize);
+ if (cmp_s_r == 0 && low_u != MPFR_LIMB_ZERO)
+ cmp_s_r = 1; /* since in fact we subtracted
+ less than 1 */
+ }
+#ifdef DEBUG
+ printf ("cmp(q*v0-(r+u0),v)=%d\n", cmp_s_r);
+#endif
+ if (cmp_s_r <= 0) /* q1-1 <= u/v < q1 */
+ {
+ if (sticky3 == MPFR_LIMB_ONE)
+ { /* q1-1 is either representable (directed rounding),
+ or the middle of two numbers (nearest) */
+ sticky = (cmp_s_r) ? MPFR_LIMB_ONE : MPFR_LIMB_ZERO;
+ goto case_1;
+ }
+ /* now necessarily sticky3=0 */
+ else if (round_bit == MPFR_LIMB_ZERO)
+ { /* round_bit=0, sticky3=0: q1-1 is exact only
+ when sh=0 */
+ inex = (cmp_s_r || sh) ? -1 : 0;
+ if (rnd_mode == MPFR_RNDN ||
+ (! like_rndz && inex != 0))
+ {
+ inex = 1;
+ goto truncate_check_qh;
+ }
+ else /* round down */
+ goto sub_one_ulp;
+ }
+ else /* sticky3=0, round_bit=1 ==> rounding to nearest */
+ {
+ inex = cmp_s_r;
+ goto truncate;
+ }
+ }
+ else /* q1-2 < u/v < q1-1 */
+ {
+ /* if rnd=MPFR_RNDN, the result is q1 when
+ q1-2 >= q1-2^(sh-1), i.e. sh >= 2,
+ otherwise (sh=1) it is q1-2 */
+ if (rnd_mode == MPFR_RNDN) /* sh > 0 */
+ {
+ /* Case sh=1: sb=0 always, and q1-rb is exactly
+ representable, like q1-rb-2.
+ rb action
+ 0 subtract two ulps, inex=-1
+ 1 truncate, inex=1
+
+ Case sh>1: one ulp is 2^(sh-1) >= 2
+ rb sb action
+ 0 0 truncate, inex=1
+ 0 1 truncate, inex=1
+ 1 x truncate, inex=-1
+ */
+ if (sh == 1)
+ {
+ if (round_bit == MPFR_LIMB_ZERO)
+ {
+ inex = -1;
+ sh = 0;
+ goto sub_two_ulp;
+ }
+ else
+ {
+ inex = 1;
+ goto truncate_check_qh;
+ }
+ }
+ else /* sh > 1 */
+ {
+ inex = (round_bit == MPFR_LIMB_ZERO) ? 1 : -1;
+ goto truncate_check_qh;
+ }
+ }
+ else if (like_rndz)
+ {
+ /* the result is down(q1-2), i.e. subtract one
+ ulp if sh > 0, and two ulps if sh=0 */
+ inex = -1;
+ if (sh > 0)
+ goto sub_one_ulp;
+ else
+ goto sub_two_ulp;
+ }
+ /* if round away from zero, the result is up(q1-1),
+ which is q1 unless sh = 0, where it is q1-1 */
+ else
+ {
+ inex = 1;
+ if (sh > 0)
+ goto truncate_check_qh;
+ else /* sh = 0 */
+ goto sub_one_ulp;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ case_1: /* quotient is in [q1, q1+1),
+ round_bit is the round_bit (0 for directed rounding),
+ sticky the sticky bit */
+ if (like_rndz || (round_bit == MPFR_LIMB_ZERO && sticky == MPFR_LIMB_ZERO))
+ {
+ inex = round_bit == MPFR_LIMB_ZERO && sticky == MPFR_LIMB_ZERO ? 0 : -1;
+ goto truncate;
+ }
+ else if (rnd_mode == MPFR_RNDN) /* sticky <> 0 or round <> 0 */
+ {
+ if (round_bit == MPFR_LIMB_ZERO) /* necessarily sticky <> 0 */
+ {
+ inex = -1;
+ goto truncate;
+ }
+ /* round_bit = 1 */
+ else if (sticky != MPFR_LIMB_ZERO)
+ goto add_one_ulp; /* inex=1 */
+ else /* round_bit=1, sticky=0 */
+ goto even_rule;
+ }
+ else /* round away from zero, sticky <> 0 */
+ goto add_one_ulp; /* with inex=1 */
+
+ sub_two_ulp:
+ /* we cannot subtract MPFR_LIMB_MPFR_LIMB_ONE << (sh+1) since this is
+ undefined for sh = GMP_NUMB_BITS */
+ qh -= mpn_sub_1 (q0p, q0p, q0size, MPFR_LIMB_ONE << sh);
+ /* go through */
+
+ sub_one_ulp:
+ qh -= mpn_sub_1 (q0p, q0p, q0size, MPFR_LIMB_ONE << sh);
+ /* go through truncate_check_qh */
+
+ truncate_check_qh:
+ if (qh)
+ {
+ qexp ++;
+ q0p[q0size - 1] = MPFR_LIMB_HIGHBIT;
+ }
+ goto truncate;
+
+ even_rule: /* has to set inex */
+ inex = (q0p[0] & (MPFR_LIMB_ONE << sh)) ? 1 : -1;
+ if (inex < 0)
+ goto truncate;
+ /* else go through add_one_ulp */
+
+ add_one_ulp:
+ inex = 1; /* always here */
+ if (mpn_add_1 (q0p, q0p, q0size, MPFR_LIMB_ONE << sh))
+ {
+ qexp ++;
+ q0p[q0size - 1] = MPFR_LIMB_HIGHBIT;
+ }
+
+ truncate: /* inex already set */
+
+ MPFR_TMP_FREE(marker);
+
+ /* check for underflow/overflow */
+ if (MPFR_UNLIKELY(qexp > __gmpfr_emax))
+ return mpfr_overflow (q, rnd_mode, sign_quotient);
+ else if (MPFR_UNLIKELY(qexp < __gmpfr_emin))
+ {
+ if (rnd_mode == MPFR_RNDN && ((qexp < __gmpfr_emin - 1) ||
+ (inex >= 0 && mpfr_powerof2_raw (q))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (q, rnd_mode, sign_quotient);
+ }
+ MPFR_SET_EXP(q, qexp);
+
+ inex *= sign_quotient;
+ MPFR_RET (inex);
+}
diff --git a/mpfr/src/div_2exp.c b/mpfr/src/div_2exp.c
new file mode 100644
index 0000000000..1dedd3b583
--- /dev/null
+++ b/mpfr/src/div_2exp.c
@@ -0,0 +1,33 @@
+/* mpfr_div_2exp -- divide a floating-point number by a power of two
+
+Copyright 1999, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Obsolete function, use mpfr_div_2ui or mpfr_div_2si instead. */
+
+#undef mpfr_div_2exp
+
+int
+mpfr_div_2exp (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_div_2ui (y, x, n, rnd_mode);
+}
diff --git a/mpfr/src/div_2si.c b/mpfr/src/div_2si.c
new file mode 100644
index 0000000000..5de15b9f63
--- /dev/null
+++ b/mpfr/src/div_2si.c
@@ -0,0 +1,60 @@
+/* mpfr_div_2si -- divide a floating-point number by a power of two
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_div_2si (mpfr_ptr y, mpfr_srcptr x, long int n, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg n=%ld rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, n, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return mpfr_set (y, x, rnd_mode);
+ else
+ {
+ mpfr_exp_t exp = MPFR_GET_EXP (x);
+ MPFR_SETRAW (inexact, y, x, exp, rnd_mode);
+ if (MPFR_UNLIKELY( n > 0 && (__gmpfr_emin > MPFR_EMAX_MAX - n ||
+ exp < __gmpfr_emin + n)) )
+ {
+ if (rnd_mode == MPFR_RNDN &&
+ (__gmpfr_emin > MPFR_EMAX_MAX - (n - 1) ||
+ exp < __gmpfr_emin + (n - 1) ||
+ (inexact >= 0 && mpfr_powerof2_raw (y))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (y, rnd_mode, MPFR_SIGN(y));
+ }
+ else if (MPFR_UNLIKELY(n < 0 && (__gmpfr_emax < MPFR_EMIN_MIN - n ||
+ exp > __gmpfr_emax + n)) )
+ return mpfr_overflow (y, rnd_mode, MPFR_SIGN(y));
+
+ MPFR_SET_EXP (y, exp - n);
+ }
+
+ MPFR_RET (inexact);
+}
diff --git a/mpfr/src/div_2ui.c b/mpfr/src/div_2ui.c
new file mode 100644
index 0000000000..89e048849e
--- /dev/null
+++ b/mpfr/src/div_2ui.c
@@ -0,0 +1,61 @@
+/* mpfr_div_2ui -- divide a floating-point number by a power of two
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_div_2ui (mpfr_ptr y, mpfr_srcptr x, unsigned long n, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%.*Rg n=%lu rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, n,
+ rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y, inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return mpfr_set (y, x, rnd_mode);
+ else
+ {
+ mpfr_exp_t exp = MPFR_GET_EXP (x);
+ mpfr_uexp_t diffexp;
+
+ MPFR_SETRAW (inexact, y, x, exp, rnd_mode);
+ diffexp = (mpfr_uexp_t) exp - (mpfr_uexp_t) (__gmpfr_emin - 1);
+ if (MPFR_UNLIKELY (n >= diffexp)) /* exp - n <= emin - 1 */
+ {
+ if (rnd_mode == MPFR_RNDN &&
+ (n > diffexp || (inexact >= 0 && mpfr_powerof2_raw (y))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (y, rnd_mode, MPFR_SIGN (y));
+ }
+ /* exp - n >= emin (no underflow, no integer overflow) */
+ while (n > LONG_MAX)
+ {
+ n -= LONG_MAX;
+ exp -= LONG_MAX; /* note: signed values */
+ }
+ MPFR_SET_EXP (y, exp - (long) n);
+ }
+
+ MPFR_RET (inexact);
+}
diff --git a/mpfr/src/div_d.c b/mpfr/src/div_d.c
new file mode 100644
index 0000000000..e2f6c9fa68
--- /dev/null
+++ b/mpfr/src/div_d.c
@@ -0,0 +1,51 @@
+/* mpfr_div_d -- divide a multiple precision floating-point number
+ by a machine double precision float
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_div_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t d;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC (
+ ("b[%Pu]=%.*Rg c%.20g rnd=%d", mpfr_get_prec (b), mpfr_log_prec, b, c,
+ rnd_mode),
+ ("a[%Pu]=%.*Rg", mpfr_get_prec (a), mpfr_log_prec, a));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ inexact = mpfr_set_d (d, c, rnd_mode);
+ MPFR_ASSERTN (inexact == 0);
+
+ mpfr_clear_flags ();
+ inexact = mpfr_div (a, b, d, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
+ mpfr_clear(d);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (a, inexact, rnd_mode);
+}
diff --git a/mpfr/src/div_ui.c b/mpfr/src/div_ui.c
new file mode 100644
index 0000000000..8688411e1f
--- /dev/null
+++ b/mpfr/src/div_ui.c
@@ -0,0 +1,281 @@
+/* mpfr_div_{ui,si} -- divide a floating-point number by a machine integer
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* returns 0 if result exact, non-zero otherwise */
+int
+mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode)
+{
+ long i;
+ int sh;
+ mp_size_t xn, yn, dif;
+ mp_limb_t *xp, *yp, *tmp, c, d;
+ mpfr_exp_t exp;
+ int inexact, middle = 1, nexttoinf;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%lu rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO(x));
+ if (u == 0) /* 0/0 is NaN */
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ MPFR_SET_ZERO(y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET(0);
+ }
+ }
+ }
+ else if (MPFR_UNLIKELY (u <= 1))
+ {
+ if (u < 1)
+ {
+ /* x/0 is Inf since x != 0*/
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ mpfr_set_divby0 ();
+ MPFR_RET (0);
+ }
+ else /* y = x/1 = x */
+ return mpfr_set (y, x, rnd_mode);
+ }
+ else if (MPFR_UNLIKELY (IS_POW2 (u)))
+ return mpfr_div_2si (y, x, MPFR_INT_CEIL_LOG2 (u), rnd_mode);
+
+ MPFR_SET_SAME_SIGN (y, x);
+
+ MPFR_TMP_MARK (marker);
+ xn = MPFR_LIMB_SIZE (x);
+ yn = MPFR_LIMB_SIZE (y);
+
+ xp = MPFR_MANT (x);
+ yp = MPFR_MANT (y);
+ exp = MPFR_GET_EXP (x);
+
+ dif = yn + 1 - xn;
+
+ /* we need to store yn+1 = xn + dif limbs of the quotient */
+ /* don't use tmp=yp since the mpn_lshift call below requires yp >= tmp+1 */
+ tmp = MPFR_TMP_LIMBS_ALLOC (yn + 1);
+
+ c = (mp_limb_t) u;
+ MPFR_ASSERTN (u == c);
+ if (dif >= 0)
+ c = mpn_divrem_1 (tmp, dif, xp, xn, c); /* used all the dividend */
+ else /* dif < 0 i.e. xn > yn, don't use the (-dif) low limbs from x */
+ c = mpn_divrem_1 (tmp, 0, xp - dif, yn + 1, c);
+
+ inexact = (c != 0);
+
+ /* First pass in estimating next bit of the quotient, in case of RNDN *
+ * In case we just have the right number of bits (postpone this ?), *
+ * we need to check whether the remainder is more or less than half *
+ * the divisor. The test must be performed with a subtraction, so as *
+ * to prevent carries. */
+
+ if (MPFR_LIKELY (rnd_mode == MPFR_RNDN))
+ {
+ if (c < (mp_limb_t) u - c) /* We have u > c */
+ middle = -1;
+ else if (c > (mp_limb_t) u - c)
+ middle = 1;
+ else
+ middle = 0; /* exactly in the middle */
+ }
+
+ /* If we believe that we are right in the middle or exact, we should check
+ that we did not neglect any word of x (division large / 1 -> small). */
+
+ for (i=0; ((inexact == 0) || (middle == 0)) && (i < -dif); i++)
+ if (xp[i])
+ inexact = middle = 1; /* larger than middle */
+
+ /*
+ If the high limb of the result is 0 (xp[xn-1] < u), remove it.
+ Otherwise, compute the left shift to be performed to normalize.
+ In the latter case, we discard some low bits computed. They
+ contain information useful for the rounding, hence the updating
+ of middle and inexact.
+ */
+
+ if (tmp[yn] == 0)
+ {
+ MPN_COPY(yp, tmp, yn);
+ exp -= GMP_NUMB_BITS;
+ }
+ else
+ {
+ int shlz;
+
+ count_leading_zeros (shlz, tmp[yn]);
+
+ /* shift left to normalize */
+ if (MPFR_LIKELY (shlz != 0))
+ {
+ mp_limb_t w = tmp[0] << shlz;
+
+ mpn_lshift (yp, tmp + 1, yn, shlz);
+ yp[0] += tmp[0] >> (GMP_NUMB_BITS - shlz);
+
+ if (w > (MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1)))
+ { middle = 1; }
+ else if (w < (MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1)))
+ { middle = -1; }
+ else
+ { middle = (c != 0); }
+
+ inexact = inexact || (w != 0);
+ exp -= shlz;
+ }
+ else
+ { /* this happens only if u == 1 and xp[xn-1] >=
+ 1<<(GMP_NUMB_BITS-1). It might be better to handle the
+ u == 1 case seperately ?
+ */
+
+ MPN_COPY (yp, tmp + 1, yn);
+ }
+ }
+
+ MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (y));
+ /* it remains sh bits in less significant limb of y */
+
+ d = *yp & MPFR_LIMB_MASK (sh);
+ *yp ^= d; /* set to zero lowest sh bits */
+
+ MPFR_TMP_FREE (marker);
+
+ if (exp < __gmpfr_emin - 1)
+ return mpfr_underflow (y, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
+ MPFR_SIGN (y));
+
+ if (MPFR_UNLIKELY (d == 0 && inexact == 0))
+ nexttoinf = 0; /* result is exact */
+ else
+ {
+ MPFR_UPDATE2_RND_MODE(rnd_mode, MPFR_SIGN (y));
+ switch (rnd_mode)
+ {
+ case MPFR_RNDZ:
+ inexact = - MPFR_INT_SIGN (y); /* result is inexact */
+ nexttoinf = 0;
+ break;
+
+ case MPFR_RNDA:
+ inexact = MPFR_INT_SIGN (y);
+ nexttoinf = 1;
+ break;
+
+ default: /* should be MPFR_RNDN */
+ MPFR_ASSERTD (rnd_mode == MPFR_RNDN);
+ /* We have one more significant bit in yn. */
+ if (sh && d < (MPFR_LIMB_ONE << (sh - 1)))
+ {
+ inexact = - MPFR_INT_SIGN (y);
+ nexttoinf = 0;
+ }
+ else if (sh && d > (MPFR_LIMB_ONE << (sh - 1)))
+ {
+ inexact = MPFR_INT_SIGN (y);
+ nexttoinf = 1;
+ }
+ else /* sh = 0 or d = 1 << (sh-1) */
+ {
+ /* The first case is "false" even rounding (significant bits
+ indicate even rounding, but the result is inexact, so up) ;
+ The second case is the case where middle should be used to
+ decide the direction of rounding (no further bit computed) ;
+ The third is the true even rounding.
+ */
+ if ((sh && inexact) || (!sh && middle > 0) ||
+ (!inexact && *yp & (MPFR_LIMB_ONE << sh)))
+ {
+ inexact = MPFR_INT_SIGN (y);
+ nexttoinf = 1;
+ }
+ else
+ {
+ inexact = - MPFR_INT_SIGN (y);
+ nexttoinf = 0;
+ }
+ }
+ }
+ }
+
+ if (nexttoinf &&
+ MPFR_UNLIKELY (mpn_add_1 (yp, yp, yn, MPFR_LIMB_ONE << sh)))
+ {
+ exp++;
+ yp[yn-1] = MPFR_LIMB_HIGHBIT;
+ }
+
+ /* Set the exponent. Warning! One may still have an underflow. */
+ MPFR_EXP (y) = exp;
+
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
+
+int
+mpfr_div_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
+{
+ int res;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%ld rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, res));
+
+ if (u >= 0)
+ res = mpfr_div_ui (y, x, u, rnd_mode);
+ else
+ {
+ res = -mpfr_div_ui (y, x, -u, MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ }
+ return res;
+}
diff --git a/mpfr/src/dump.c b/mpfr/src/dump.c
new file mode 100644
index 0000000000..9c5fda6a44
--- /dev/null
+++ b/mpfr/src/dump.c
@@ -0,0 +1,30 @@
+/* mpfr_dump -- Dump a float to stdout.
+
+Copyright 1999, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_dump (mpfr_srcptr u)
+{
+ mpfr_print_binary(u);
+ putchar('\n');
+}
diff --git a/mpfr/src/eint.c b/mpfr/src/eint.c
new file mode 100644
index 0000000000..05bf0cebb2
--- /dev/null
+++ b/mpfr/src/eint.c
@@ -0,0 +1,319 @@
+/* mpfr_eint, mpfr_eint1 -- the exponential integral
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* eint1(x) = -gamma - log(x) - sum((-1)^k*z^k/k/k!, k=1..infinity) for x > 0
+ = - eint(-x) for x < 0
+ where
+ eint (x) = gamma + log(x) + sum(z^k/k/k!, k=1..infinity) for x > 0
+ eint (x) is undefined for x < 0.
+*/
+
+/* compute in y an approximation of sum(x^k/k/k!, k=1..infinity),
+ and return e such that the absolute error is bound by 2^e ulp(y) */
+static mpfr_exp_t
+mpfr_eint_aux (mpfr_t y, mpfr_srcptr x)
+{
+ mpfr_t eps; /* dynamic (absolute) error bound on t */
+ mpfr_t erru, errs;
+ mpz_t m, s, t, u;
+ mpfr_exp_t e, sizeinbase;
+ mpfr_prec_t w = MPFR_PREC(y);
+ unsigned long k;
+ MPFR_GROUP_DECL (group);
+
+ /* for |x| <= 1, we have S := sum(x^k/k/k!, k=1..infinity) = x + R(x)
+ where |R(x)| <= (x/2)^2/(1-x/2) <= 2*(x/2)^2
+ thus |R(x)/x| <= |x|/2
+ thus if |x| <= 2^(-PREC(y)) we have |S - o(x)| <= ulp(y) */
+
+ if (MPFR_GET_EXP(x) <= - (mpfr_exp_t) w)
+ {
+ mpfr_set (y, x, MPFR_RNDN);
+ return 0;
+ }
+
+ mpz_init (s); /* initializes to 0 */
+ mpz_init (t);
+ mpz_init (u);
+ mpz_init (m);
+ MPFR_GROUP_INIT_3 (group, 31, eps, erru, errs);
+ e = mpfr_get_z_2exp (m, x); /* x = m * 2^e */
+ MPFR_ASSERTD (mpz_sizeinbase (m, 2) == MPFR_PREC (x));
+ if (MPFR_PREC (x) > w)
+ {
+ e += MPFR_PREC (x) - w;
+ mpz_tdiv_q_2exp (m, m, MPFR_PREC (x) - w);
+ }
+ /* remove trailing zeroes from m: this will speed up much cases where
+ x is a small integer divided by a power of 2 */
+ k = mpz_scan1 (m, 0);
+ mpz_tdiv_q_2exp (m, m, k);
+ e += k;
+ /* initialize t to 2^w */
+ mpz_set_ui (t, 1);
+ mpz_mul_2exp (t, t, w);
+ mpfr_set_ui (eps, 0, MPFR_RNDN); /* eps[0] = 0 */
+ mpfr_set_ui (errs, 0, MPFR_RNDN);
+ for (k = 1;; k++)
+ {
+ /* let eps[k] be the absolute error on t[k]:
+ since t[k] = trunc(t[k-1]*m*2^e/k), we have
+ eps[k+1] <= 1 + eps[k-1]*m*2^e/k + t[k-1]*m*2^(1-w)*2^e/k
+ = 1 + (eps[k-1] + t[k-1]*2^(1-w))*m*2^e/k
+ = 1 + (eps[k-1]*2^(w-1) + t[k-1])*2^(1-w)*m*2^e/k */
+ mpfr_mul_2ui (eps, eps, w - 1, MPFR_RNDU);
+ mpfr_add_z (eps, eps, t, MPFR_RNDU);
+ MPFR_MPZ_SIZEINBASE2 (sizeinbase, m);
+ mpfr_mul_2si (eps, eps, sizeinbase - (w - 1) + e, MPFR_RNDU);
+ mpfr_div_ui (eps, eps, k, MPFR_RNDU);
+ mpfr_add_ui (eps, eps, 1, MPFR_RNDU);
+ mpz_mul (t, t, m);
+ if (e < 0)
+ mpz_tdiv_q_2exp (t, t, -e);
+ else
+ mpz_mul_2exp (t, t, e);
+ mpz_tdiv_q_ui (t, t, k);
+ mpz_tdiv_q_ui (u, t, k);
+ mpz_add (s, s, u);
+ /* the absolute error on u is <= 1 + eps[k]/k */
+ mpfr_div_ui (erru, eps, k, MPFR_RNDU);
+ mpfr_add_ui (erru, erru, 1, MPFR_RNDU);
+ /* and that on s is the sum of all errors on u */
+ mpfr_add (errs, errs, erru, MPFR_RNDU);
+ /* we are done when t is smaller than errs */
+ if (mpz_sgn (t) == 0)
+ sizeinbase = 0;
+ else
+ MPFR_MPZ_SIZEINBASE2 (sizeinbase, t);
+ if (sizeinbase < MPFR_GET_EXP (errs))
+ break;
+ }
+ /* the truncation error is bounded by (|t|+eps)/k*(|x|/k + |x|^2/k^2 + ...)
+ <= (|t|+eps)/k*|x|/(k-|x|) */
+ mpz_abs (t, t);
+ mpfr_add_z (eps, eps, t, MPFR_RNDU);
+ mpfr_div_ui (eps, eps, k, MPFR_RNDU);
+ mpfr_abs (erru, x, MPFR_RNDU); /* |x| */
+ mpfr_mul (eps, eps, erru, MPFR_RNDU);
+ mpfr_ui_sub (erru, k, erru, MPFR_RNDD);
+ if (MPFR_IS_NEG (erru))
+ {
+ /* the truncated series does not converge, return fail */
+ e = w;
+ }
+ else
+ {
+ mpfr_div (eps, eps, erru, MPFR_RNDU);
+ mpfr_add (errs, errs, eps, MPFR_RNDU);
+ mpfr_set_z (y, s, MPFR_RNDN);
+ mpfr_div_2ui (y, y, w, MPFR_RNDN);
+ /* errs was an absolute error bound on s. We must convert it to an error
+ in terms of ulp(y). Since ulp(y) = 2^(EXP(y)-PREC(y)), we must
+ divide the error by 2^(EXP(y)-PREC(y)), but since we divided also
+ y by 2^w = 2^PREC(y), we must simply divide by 2^EXP(y). */
+ e = MPFR_GET_EXP (errs) - MPFR_GET_EXP (y);
+ }
+ MPFR_GROUP_CLEAR (group);
+ mpz_clear (s);
+ mpz_clear (t);
+ mpz_clear (u);
+ mpz_clear (m);
+ return e;
+}
+
+/* Return in y an approximation of Ei(x) using the asymptotic expansion:
+ Ei(x) = exp(x)/x * (1 + 1/x + 2/x^2 + ... + k!/x^k + ...)
+ Assumes x >= PREC(y) * log(2).
+ Returns the error bound in terms of ulp(y).
+*/
+static mpfr_exp_t
+mpfr_eint_asympt (mpfr_ptr y, mpfr_srcptr x)
+{
+ mpfr_prec_t p = MPFR_PREC(y);
+ mpfr_t invx, t, err;
+ unsigned long k;
+ mpfr_exp_t err_exp;
+
+ mpfr_init2 (t, p);
+ mpfr_init2 (invx, p);
+ mpfr_init2 (err, 31); /* error in ulps on y */
+ mpfr_ui_div (invx, 1, x, MPFR_RNDN); /* invx = 1/x*(1+u) with |u|<=2^(1-p) */
+ mpfr_set_ui (t, 1, MPFR_RNDN); /* exact */
+ mpfr_set (y, t, MPFR_RNDN);
+ mpfr_set_ui (err, 0, MPFR_RNDN);
+ for (k = 1; MPFR_GET_EXP(t) + (mpfr_exp_t) p > MPFR_GET_EXP(y); k++)
+ {
+ mpfr_mul (t, t, invx, MPFR_RNDN); /* 2 more roundings */
+ mpfr_mul_ui (t, t, k, MPFR_RNDN); /* 1 more rounding: t = k!/x^k*(1+u)^e
+ with u=2^{-p} and |e| <= 3*k */
+ /* we use the fact that |(1+u)^n-1| <= 2*|n*u| for |n*u| <= 1, thus
+ the error on t is less than 6*k*2^{-p}*t <= 6*k*ulp(t) */
+ /* err is in terms of ulp(y): transform it in terms of ulp(t) */
+ mpfr_mul_2si (err, err, MPFR_GET_EXP(y) - MPFR_GET_EXP(t), MPFR_RNDU);
+ mpfr_add_ui (err, err, 6 * k, MPFR_RNDU);
+ /* transform back in terms of ulp(y) */
+ mpfr_div_2si (err, err, MPFR_GET_EXP(y) - MPFR_GET_EXP(t), MPFR_RNDU);
+ mpfr_add (y, y, t, MPFR_RNDN);
+ }
+ /* add the truncation error bounded by ulp(y): 1 ulp */
+ mpfr_mul (y, y, invx, MPFR_RNDN); /* err <= 2*err + 3/2 */
+ mpfr_exp (t, x, MPFR_RNDN); /* err(t) <= 1/2*ulp(t) */
+ mpfr_mul (y, y, t, MPFR_RNDN); /* again: err <= 2*err + 3/2 */
+ mpfr_mul_2ui (err, err, 2, MPFR_RNDU);
+ mpfr_add_ui (err, err, 8, MPFR_RNDU);
+ err_exp = MPFR_GET_EXP(err);
+ mpfr_clear (t);
+ mpfr_clear (invx);
+ mpfr_clear (err);
+ return err_exp;
+}
+
+int
+mpfr_eint (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ int inex;
+ mpfr_t tmp, ump;
+ mpfr_exp_t err, te;
+ mpfr_prec_t prec;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC (
+ ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y, inex));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ /* exp(NaN) = exp(-Inf) = NaN */
+ if (MPFR_IS_NAN (x) || (MPFR_IS_INF (x) && MPFR_IS_NEG(x)))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ /* eint(+inf) = +inf */
+ else if (MPFR_IS_INF (x))
+ {
+ MPFR_SET_INF(y);
+ MPFR_SET_POS(y);
+ MPFR_RET(0);
+ }
+ else /* eint(+/-0) = -Inf */
+ {
+ MPFR_SET_INF(y);
+ MPFR_SET_NEG(y);
+ mpfr_set_divby0 ();
+ MPFR_RET(0);
+ }
+ }
+
+ /* eint(x) = NaN for x < 0 */
+ if (MPFR_IS_NEG(x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Since eint(x) >= exp(x)/x, we have log2(eint(x)) >= (x-log(x))/log(2).
+ Let's compute k <= (x-log(x))/log(2) in a low precision. If k >= emax,
+ then log2(eint(x)) >= emax, and eint(x) >= 2^emax, i.e. it overflows. */
+ mpfr_init2 (tmp, 64);
+ mpfr_init2 (ump, 64);
+ mpfr_log (tmp, x, MPFR_RNDU);
+ mpfr_sub (ump, x, tmp, MPFR_RNDD);
+ mpfr_const_log2 (tmp, MPFR_RNDU);
+ mpfr_div (ump, ump, tmp, MPFR_RNDD);
+ /* FIXME: We really need mpfr_set_exp_t and mpfr_cmpfr_exp_t functions. */
+ MPFR_ASSERTN (MPFR_EMAX_MAX <= LONG_MAX);
+ if (mpfr_cmp_ui (ump, __gmpfr_emax) >= 0)
+ {
+ mpfr_clear (tmp);
+ mpfr_clear (ump);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_overflow (y, rnd, 1);
+ }
+
+ /* Init stuff */
+ prec = MPFR_PREC (y) + 2 * MPFR_INT_CEIL_LOG2 (MPFR_PREC (y)) + 6;
+
+ /* eint() has a root 0.37250741078136663446..., so if x is near,
+ already take more bits */
+ /* FIXME: do not use native floating-point here. */
+ if (MPFR_GET_EXP(x) == -1) /* 1/4 <= x < 1/2 */
+ {
+ double d;
+ d = mpfr_get_d (x, MPFR_RNDN) - 0.37250741078136663;
+ d = (d == 0.0) ? -53 : __gmpfr_ceil_log2 (d);
+ prec += -d;
+ }
+
+ mpfr_set_prec (tmp, prec);
+ mpfr_set_prec (ump, prec);
+
+ MPFR_ZIV_INIT (loop, prec); /* Initialize the ZivLoop controler */
+ for (;;) /* Infinite loop */
+ {
+ /* We need that the smallest value of k!/x^k is smaller than 2^(-p).
+ The minimum is obtained for x=k, and it is smaller than e*sqrt(x)/e^x
+ for x>=1. */
+ if (MPFR_GET_EXP (x) > 0 && mpfr_cmp_d (x, ((double) prec +
+ 0.5 * (double) MPFR_GET_EXP (x)) * LOG2 + 1.0) > 0)
+ err = mpfr_eint_asympt (tmp, x);
+ else
+ {
+ err = mpfr_eint_aux (tmp, x); /* error <= 2^err ulp(tmp) */
+ te = MPFR_GET_EXP(tmp);
+ mpfr_const_euler (ump, MPFR_RNDN); /* 0.577 -> EXP(ump)=0 */
+ mpfr_add (tmp, tmp, ump, MPFR_RNDN);
+ /* error <= 1/2 + 1/2*2^(EXP(ump)-EXP(tmp)) + 2^(te-EXP(tmp)+err)
+ <= 1/2 + 2^(MAX(EXP(ump), te+err+1) - EXP(tmp))
+ <= 2^(MAX(0, 1 + MAX(EXP(ump), te+err+1) - EXP(tmp))) */
+ err = MAX(1, te + err + 2) - MPFR_GET_EXP(tmp);
+ err = MAX(0, err);
+ te = MPFR_GET_EXP(tmp);
+ mpfr_log (ump, x, MPFR_RNDN);
+ mpfr_add (tmp, tmp, ump, MPFR_RNDN);
+ /* same formula as above, except now EXP(ump) is not 0 */
+ err += te + 1;
+ if (MPFR_LIKELY (!MPFR_IS_ZERO (ump)))
+ err = MAX (MPFR_GET_EXP (ump), err);
+ err = MAX(0, err - MPFR_GET_EXP (tmp));
+ }
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - err, MPFR_PREC (y), rnd)))
+ break;
+ MPFR_ZIV_NEXT (loop, prec); /* Increase used precision */
+ mpfr_set_prec (tmp, prec);
+ mpfr_set_prec (ump, prec);
+ }
+ MPFR_ZIV_FREE (loop); /* Free the ZivLoop Controler */
+
+ inex = mpfr_set (y, tmp, rnd); /* Set y to the computed value */
+ mpfr_clear (tmp);
+ mpfr_clear (ump);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd);
+}
diff --git a/mpfr/src/eq.c b/mpfr/src/eq.c
new file mode 100644
index 0000000000..7589070257
--- /dev/null
+++ b/mpfr/src/eq.c
@@ -0,0 +1,141 @@
+/* mpfr_eq -- Compare two floats up to a specified bit #.
+
+Copyright 1999, 2001, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#include "mpfr-impl.h"
+
+/* return non-zero if the first n_bits bits of u, v are equal,
+ 0 otherwise */
+int
+mpfr_eq (mpfr_srcptr u, mpfr_srcptr v, unsigned long int n_bits)
+{
+ mpfr_limb_srcptr up, vp;
+ mp_size_t usize, vsize, size, i;
+ mpfr_exp_t uexp, vexp;
+ int k;
+
+ if (MPFR_ARE_SINGULAR(u, v))
+ {
+ if (MPFR_IS_NAN(u) || MPFR_IS_NAN(v))
+ return 0; /* non equal */
+ else if (MPFR_IS_INF(u) && MPFR_IS_INF(v))
+ return (MPFR_SIGN(u) == MPFR_SIGN(v));
+ else if (MPFR_IS_ZERO(u) && MPFR_IS_ZERO(v))
+ return 1;
+ else
+ return 0;
+ }
+
+ /* 1. Are the signs different? */
+ if (MPFR_SIGN(u) != MPFR_SIGN(v))
+ return 0;
+
+ uexp = MPFR_GET_EXP (u);
+ vexp = MPFR_GET_EXP (v);
+
+ /* 2. Are the exponents different? */
+ if (uexp != vexp)
+ return 0; /* no bit agree */
+
+ usize = MPFR_LIMB_SIZE (u);
+ vsize = MPFR_LIMB_SIZE (v);
+
+ if (vsize > usize) /* exchange u and v */
+ {
+ up = MPFR_MANT(v);
+ vp = MPFR_MANT(u);
+ size = vsize;
+ vsize = usize;
+ usize = size;
+ }
+ else
+ {
+ up = MPFR_MANT(u);
+ vp = MPFR_MANT(v);
+ }
+
+ /* now usize >= vsize */
+ MPFR_ASSERTD(usize >= vsize);
+
+ if (usize > vsize)
+ {
+ if ((unsigned long) vsize * GMP_NUMB_BITS < n_bits)
+ {
+ /* check if low min(PREC(u), n_bits) - (vsize * GMP_NUMB_BITS)
+ bits from u are non-zero */
+ unsigned long remains = n_bits - (vsize * GMP_NUMB_BITS);
+ k = usize - vsize - 1;
+ while (k >= 0 && remains >= GMP_NUMB_BITS && !up[k])
+ {
+ k--;
+ remains -= GMP_NUMB_BITS;
+ }
+ /* now either k < 0: all low bits from u are zero
+ or remains < GMP_NUMB_BITS: check high bits from up[k]
+ or up[k] <> 0: different */
+ if (k >= 0 && (((remains < GMP_NUMB_BITS) &&
+ (up[k] >> (GMP_NUMB_BITS - remains))) ||
+ (remains >= GMP_NUMB_BITS && up[k])))
+ return 0; /* surely too different */
+ }
+ size = vsize;
+ }
+ else
+ {
+ size = usize;
+ }
+
+ /* now size = min (usize, vsize) */
+
+ /* If size is too large wrt n_bits, reduce it to look only at the
+ high n_bits bits.
+ Otherwise, if n_bits > size * GMP_NUMB_BITS, reduce n_bits to
+ size * GMP_NUMB_BITS, since the extra low bits of one of the
+ operands have already been check above. */
+ if ((unsigned long) size > 1 + (n_bits - 1) / GMP_NUMB_BITS)
+ size = 1 + (n_bits - 1) / GMP_NUMB_BITS;
+ else if (n_bits > (unsigned long) size * GMP_NUMB_BITS)
+ n_bits = size * GMP_NUMB_BITS;
+
+ up += usize - size;
+ vp += vsize - size;
+
+ for (i = size - 1; i > 0 && n_bits >= GMP_NUMB_BITS; i--)
+ {
+ if (up[i] != vp[i])
+ return 0;
+ n_bits -= GMP_NUMB_BITS;
+ }
+
+ /* now either i=0 or n_bits<GMP_NUMB_BITS */
+
+ /* since n_bits <= size * GMP_NUMB_BITS before the above for-loop,
+ we have the invariant n_bits <= (i+1) * GMP_NUMB_BITS, thus
+ we always have n_bits <= GMP_NUMB_BITS here */
+ MPFR_ASSERTD(n_bits <= GMP_NUMB_BITS);
+
+ if (n_bits & (GMP_NUMB_BITS - 1))
+ return (up[i] >> (GMP_NUMB_BITS - (n_bits & (GMP_NUMB_BITS - 1))) ==
+ vp[i] >> (GMP_NUMB_BITS - (n_bits & (GMP_NUMB_BITS - 1))));
+ else
+ return (up[i] == vp[i]);
+}
diff --git a/mpfr/src/erf.c b/mpfr/src/erf.c
new file mode 100644
index 0000000000..0b5a221ee8
--- /dev/null
+++ b/mpfr/src/erf.c
@@ -0,0 +1,262 @@
+/* mpfr_erf -- error function of a floating-point number
+
+Copyright 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#define EXP1 2.71828182845904523536 /* exp(1) */
+
+static int mpfr_erf_0 (mpfr_ptr, mpfr_srcptr, double, mpfr_rnd_t);
+
+int
+mpfr_erf (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xf;
+ int inex, large;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y, inex));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x)) /* erf(+inf) = +1, erf(-inf) = -1 */
+ return mpfr_set_si (y, MPFR_INT_SIGN (x), MPFR_RNDN);
+ else /* erf(+0) = +0, erf(-0) = -0 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ return mpfr_set (y, x, MPFR_RNDN); /* should keep the sign of x */
+ }
+ }
+
+ /* now x is neither NaN, Inf nor 0 */
+
+ /* first try expansion at x=0 when x is small, or asymptotic expansion
+ where x is large */
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* around x=0, we have erf(x) = 2x/sqrt(Pi) (1 - x^2/3 + ...),
+ with 1 - x^2/3 <= sqrt(Pi)*erf(x)/2/x <= 1 for x >= 0. This means that
+ if x^2/3 < 2^(-PREC(y)-1) we can decide of the correct rounding,
+ unless we have a worst-case for 2x/sqrt(Pi). */
+ if (MPFR_EXP(x) < - (mpfr_exp_t) (MPFR_PREC(y) / 2))
+ {
+ /* we use 2x/sqrt(Pi) (1 - x^2/3) <= erf(x) <= 2x/sqrt(Pi) for x > 0
+ and 2x/sqrt(Pi) <= erf(x) <= 2x/sqrt(Pi) (1 - x^2/3) for x < 0.
+ In both cases |2x/sqrt(Pi) (1 - x^2/3)| <= |erf(x)| <= |2x/sqrt(Pi)|.
+ We will compute l and h such that l <= |2x/sqrt(Pi) (1 - x^2/3)|
+ and |2x/sqrt(Pi)| <= h. If l and h round to the same value to
+ precision PREC(y) and rounding rnd_mode, then we are done. */
+ mpfr_t l, h; /* lower and upper bounds for erf(x) */
+ int ok, inex2;
+
+ mpfr_init2 (l, MPFR_PREC(y) + 17);
+ mpfr_init2 (h, MPFR_PREC(y) + 17);
+ /* first compute l */
+ mpfr_mul (l, x, x, MPFR_RNDU);
+ mpfr_div_ui (l, l, 3, MPFR_RNDU); /* upper bound on x^2/3 */
+ mpfr_ui_sub (l, 1, l, MPFR_RNDZ); /* lower bound on 1 - x^2/3 */
+ mpfr_const_pi (h, MPFR_RNDU); /* upper bound of Pi */
+ mpfr_sqrt (h, h, MPFR_RNDU); /* upper bound on sqrt(Pi) */
+ mpfr_div (l, l, h, MPFR_RNDZ); /* lower bound on 1/sqrt(Pi) (1 - x^2/3) */
+ mpfr_mul_2ui (l, l, 1, MPFR_RNDZ); /* 2/sqrt(Pi) (1 - x^2/3) */
+ mpfr_mul (l, l, x, MPFR_RNDZ); /* |l| is a lower bound on
+ |2x/sqrt(Pi) (1 - x^2/3)| */
+ /* now compute h */
+ mpfr_const_pi (h, MPFR_RNDD); /* lower bound on Pi */
+ mpfr_sqrt (h, h, MPFR_RNDD); /* lower bound on sqrt(Pi) */
+ mpfr_div_2ui (h, h, 1, MPFR_RNDD); /* lower bound on sqrt(Pi)/2 */
+ /* since sqrt(Pi)/2 < 1, the following should not underflow */
+ mpfr_div (h, x, h, MPFR_IS_POS(x) ? MPFR_RNDU : MPFR_RNDD);
+ /* round l and h to precision PREC(y) */
+ inex = mpfr_prec_round (l, MPFR_PREC(y), rnd_mode);
+ inex2 = mpfr_prec_round (h, MPFR_PREC(y), rnd_mode);
+ /* Caution: we also need inex=inex2 (inex might be 0). */
+ ok = SAME_SIGN (inex, inex2) && mpfr_cmp (l, h) == 0;
+ if (ok)
+ mpfr_set (y, h, rnd_mode);
+ mpfr_clear (l);
+ mpfr_clear (h);
+ if (ok)
+ goto end;
+ /* this test can still fail for small precision, for example
+ for x=-0.100E-2 with a target precision of 3 bits, since
+ the error term x^2/3 is not that small. */
+ }
+
+ mpfr_init2 (xf, 53);
+ mpfr_const_log2 (xf, MPFR_RNDU);
+ mpfr_div (xf, x, xf, MPFR_RNDZ); /* round to zero ensures we get a lower
+ bound of |x/log(2)| */
+ mpfr_mul (xf, xf, x, MPFR_RNDZ);
+ large = mpfr_cmp_ui (xf, MPFR_PREC (y) + 1) > 0;
+ mpfr_clear (xf);
+
+ /* when x goes to infinity, we have erf(x) = 1 - 1/sqrt(Pi)/exp(x^2)/x + ...
+ and |erf(x) - 1| <= exp(-x^2) is true for any x >= 0, thus if
+ exp(-x^2) < 2^(-PREC(y)-1) the result is 1 or 1-epsilon.
+ This rewrites as x^2/log(2) > p+1. */
+ if (MPFR_UNLIKELY (large))
+ /* |erf x| = 1 or 1- */
+ {
+ mpfr_rnd_t rnd2 = MPFR_IS_POS (x) ? rnd_mode : MPFR_INVERT_RND(rnd_mode);
+ if (rnd2 == MPFR_RNDN || rnd2 == MPFR_RNDU || rnd2 == MPFR_RNDA)
+ {
+ inex = MPFR_INT_SIGN (x);
+ mpfr_set_si (y, inex, rnd2);
+ }
+ else /* round to zero */
+ {
+ inex = -MPFR_INT_SIGN (x);
+ mpfr_setmax (y, 0); /* warning: setmax keeps the old sign of y */
+ MPFR_SET_SAME_SIGN (y, x);
+ }
+ }
+ else /* use Taylor */
+ {
+ double xf2;
+
+ /* FIXME: get rid of doubles/mpfr_get_d here */
+ xf2 = mpfr_get_d (x, MPFR_RNDN);
+ xf2 = xf2 * xf2; /* xf2 ~ x^2 */
+ inex = mpfr_erf_0 (y, x, xf2, rnd_mode);
+ }
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd_mode);
+}
+
+/* return x*2^e */
+static double
+mul_2exp (double x, mpfr_exp_t e)
+{
+ if (e > 0)
+ {
+ while (e--)
+ x *= 2.0;
+ }
+ else
+ {
+ while (e++)
+ x /= 2.0;
+ }
+
+ return x;
+}
+
+/* evaluates erf(x) using the expansion at x=0:
+
+ erf(x) = 2/sqrt(Pi) * sum((-1)^k*x^(2k+1)/k!/(2k+1), k=0..infinity)
+
+ Assumes x is neither NaN nor infinite nor zero.
+ Assumes also that e*x^2 <= n (target precision).
+ */
+static int
+mpfr_erf_0 (mpfr_ptr res, mpfr_srcptr x, double xf2, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t n, m;
+ mpfr_exp_t nuk, sigmak;
+ double tauk;
+ mpfr_t y, s, t, u;
+ unsigned int k;
+ int log2tauk;
+ int inex;
+ MPFR_ZIV_DECL (loop);
+
+ n = MPFR_PREC (res); /* target precision */
+
+ /* initial working precision */
+ m = n + (mpfr_prec_t) (xf2 / LOG2) + 8 + MPFR_INT_CEIL_LOG2 (n);
+
+ mpfr_init2 (y, m);
+ mpfr_init2 (s, m);
+ mpfr_init2 (t, m);
+ mpfr_init2 (u, m);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ mpfr_mul (y, x, x, MPFR_RNDU); /* err <= 1 ulp */
+ mpfr_set_ui (s, 1, MPFR_RNDN);
+ mpfr_set_ui (t, 1, MPFR_RNDN);
+ tauk = 0.0;
+
+ for (k = 1; ; k++)
+ {
+ mpfr_mul (t, y, t, MPFR_RNDU);
+ mpfr_div_ui (t, t, k, MPFR_RNDU);
+ mpfr_div_ui (u, t, 2 * k + 1, MPFR_RNDU);
+ sigmak = MPFR_GET_EXP (s);
+ if (k % 2)
+ mpfr_sub (s, s, u, MPFR_RNDN);
+ else
+ mpfr_add (s, s, u, MPFR_RNDN);
+ sigmak -= MPFR_GET_EXP(s);
+ nuk = MPFR_GET_EXP(u) - MPFR_GET_EXP(s);
+
+ if ((nuk < - (mpfr_exp_t) m) && ((double) k >= xf2))
+ break;
+
+ /* tauk <- 1/2 + tauk * 2^sigmak + (1+8k)*2^nuk */
+ tauk = 0.5 + mul_2exp (tauk, sigmak)
+ + mul_2exp (1.0 + 8.0 * (double) k, nuk);
+ }
+
+ mpfr_mul (s, x, s, MPFR_RNDU);
+ MPFR_SET_EXP (s, MPFR_GET_EXP (s) + 1);
+
+ mpfr_const_pi (t, MPFR_RNDZ);
+ mpfr_sqrt (t, t, MPFR_RNDZ);
+ mpfr_div (s, s, t, MPFR_RNDN);
+ tauk = 4.0 * tauk + 11.0; /* final ulp-error on s */
+ log2tauk = __gmpfr_ceil_log2 (tauk);
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, m - log2tauk, n, rnd_mode)))
+ break;
+
+ /* Actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (y, m);
+ mpfr_set_prec (s, m);
+ mpfr_set_prec (t, m);
+ mpfr_set_prec (u, m);
+
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inex = mpfr_set (res, s, rnd_mode);
+
+ mpfr_clear (y);
+ mpfr_clear (t);
+ mpfr_clear (u);
+ mpfr_clear (s);
+
+ return inex;
+}
diff --git a/mpfr/src/erfc.c b/mpfr/src/erfc.c
new file mode 100644
index 0000000000..653bf2f682
--- /dev/null
+++ b/mpfr/src/erfc.c
@@ -0,0 +1,277 @@
+/* mpfr_erfc -- The Complementary Error Function of a floating-point number
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* erfc(x) = 1 - erf(x) */
+
+/* Put in y an approximation of erfc(x) for large x, using formulae 7.1.23 and
+ 7.1.24 from Abramowitz and Stegun.
+ Returns e such that the error is bounded by 2^e ulp(y),
+ or returns 0 in case of underflow.
+*/
+static mpfr_exp_t
+mpfr_erfc_asympt (mpfr_ptr y, mpfr_srcptr x)
+{
+ mpfr_t t, xx, err;
+ unsigned long k;
+ mpfr_prec_t prec = MPFR_PREC(y);
+ mpfr_exp_t exp_err;
+
+ mpfr_init2 (t, prec);
+ mpfr_init2 (xx, prec);
+ mpfr_init2 (err, 31);
+ /* let u = 2^(1-p), and let us represent the error as (1+u)^err
+ with a bound for err */
+ mpfr_mul (xx, x, x, MPFR_RNDD); /* err <= 1 */
+ mpfr_ui_div (xx, 1, xx, MPFR_RNDU); /* upper bound for 1/(2x^2), err <= 2 */
+ mpfr_div_2ui (xx, xx, 1, MPFR_RNDU); /* exact */
+ mpfr_set_ui (t, 1, MPFR_RNDN); /* current term, exact */
+ mpfr_set (y, t, MPFR_RNDN); /* current sum */
+ mpfr_set_ui (err, 0, MPFR_RNDN);
+ for (k = 1; ; k++)
+ {
+ mpfr_mul_ui (t, t, 2 * k - 1, MPFR_RNDU); /* err <= 4k-3 */
+ mpfr_mul (t, t, xx, MPFR_RNDU); /* err <= 4k */
+ /* for -1 < x < 1, and |nx| < 1, we have |(1+x)^n| <= 1+7/4|nx|.
+ Indeed, for x>=0: log((1+x)^n) = n*log(1+x) <= n*x. Let y=n*x < 1,
+ then exp(y) <= 1+7/4*y.
+ For x<=0, let x=-x, we can prove by induction that (1-x)^n >= 1-n*x.*/
+ mpfr_mul_2si (err, err, MPFR_GET_EXP (y) - MPFR_GET_EXP (t), MPFR_RNDU);
+ mpfr_add_ui (err, err, 14 * k, MPFR_RNDU); /* 2^(1-p) * t <= 2 ulp(t) */
+ mpfr_div_2si (err, err, MPFR_GET_EXP (y) - MPFR_GET_EXP (t), MPFR_RNDU);
+ if (MPFR_GET_EXP (t) + (mpfr_exp_t) prec <= MPFR_GET_EXP (y))
+ {
+ /* the truncation error is bounded by |t| < ulp(y) */
+ mpfr_add_ui (err, err, 1, MPFR_RNDU);
+ break;
+ }
+ if (k & 1)
+ mpfr_sub (y, y, t, MPFR_RNDN);
+ else
+ mpfr_add (y, y, t, MPFR_RNDN);
+ }
+ /* the error on y is bounded by err*ulp(y) */
+ mpfr_mul (t, x, x, MPFR_RNDU); /* rel. err <= 2^(1-p) */
+ mpfr_div_2ui (err, err, 3, MPFR_RNDU); /* err/8 */
+ mpfr_add (err, err, t, MPFR_RNDU); /* err/8 + xx */
+ mpfr_mul_2ui (err, err, 3, MPFR_RNDU); /* err + 8*xx */
+ mpfr_exp (t, t, MPFR_RNDU); /* err <= 1/2*ulp(t) + err(x*x)*t
+ <= 1/2*ulp(t)+2*|x*x|*ulp(t)
+ <= (2*|x*x|+1/2)*ulp(t) */
+ mpfr_mul (t, t, x, MPFR_RNDN); /* err <= 1/2*ulp(t) + (4*|x*x|+1)*ulp(t)
+ <= (4*|x*x|+3/2)*ulp(t) */
+ mpfr_const_pi (xx, MPFR_RNDZ); /* err <= ulp(Pi) */
+ mpfr_sqrt (xx, xx, MPFR_RNDN); /* err <= 1/2*ulp(xx) + ulp(Pi)/2/sqrt(Pi)
+ <= 3/2*ulp(xx) */
+ mpfr_mul (t, t, xx, MPFR_RNDN); /* err <= (8 |xx| + 13/2) * ulp(t) */
+ mpfr_div (y, y, t, MPFR_RNDN); /* the relative error on input y is bounded
+ by (1+u)^err with u = 2^(1-p), that on
+ t is bounded by (1+u)^(8 |xx| + 13/2),
+ thus that on output y is bounded by
+ 8 |xx| + 7 + err. */
+
+ if (MPFR_IS_ZERO(y))
+ {
+ /* If y is zero, most probably we have underflow. We check it directly
+ using the fact that erfc(x) <= exp(-x^2)/sqrt(Pi)/x for x >= 0.
+ We compute an upper approximation of exp(-x^2)/sqrt(Pi)/x.
+ */
+ mpfr_mul (t, x, x, MPFR_RNDD); /* t <= x^2 */
+ mpfr_neg (t, t, MPFR_RNDU); /* -x^2 <= t */
+ mpfr_exp (t, t, MPFR_RNDU); /* exp(-x^2) <= t */
+ mpfr_const_pi (xx, MPFR_RNDD); /* xx <= sqrt(Pi), cached */
+ mpfr_mul (xx, xx, x, MPFR_RNDD); /* xx <= sqrt(Pi)*x */
+ mpfr_div (y, t, xx, MPFR_RNDN); /* if y is zero, this means that the upper
+ approximation of exp(-x^2)/sqrt(Pi)/x
+ is nearer from 0 than from 2^(-emin-1),
+ thus we have underflow. */
+ exp_err = 0;
+ }
+ else
+ {
+ mpfr_add_ui (err, err, 7, MPFR_RNDU);
+ exp_err = MPFR_GET_EXP (err);
+ }
+
+ mpfr_clear (t);
+ mpfr_clear (xx);
+ mpfr_clear (err);
+ return exp_err;
+}
+
+int
+mpfr_erfc (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ int inex;
+ mpfr_t tmp;
+ mpfr_exp_t te, err;
+ mpfr_prec_t prec;
+ mpfr_exp_t emin = mpfr_get_emin ();
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y, inex));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ /* erfc(+inf) = 0+, erfc(-inf) = 2 erfc (0) = 1 */
+ else if (MPFR_IS_INF (x))
+ return mpfr_set_ui (y, MPFR_IS_POS (x) ? 0 : 2, rnd);
+ else
+ return mpfr_set_ui (y, 1, rnd);
+ }
+
+ if (MPFR_SIGN (x) > 0)
+ {
+ /* by default, emin = 1-2^30, thus the smallest representable
+ number is 1/2*2^emin = 2^(-2^30):
+ for x >= 27282, erfc(x) < 2^(-2^30-1), and
+ for x >= 1787897414, erfc(x) < 2^(-2^62-1).
+ */
+ if ((emin >= -1073741823 && mpfr_cmp_ui (x, 27282) >= 0) ||
+ mpfr_cmp_ui (x, 1787897414) >= 0)
+ {
+ /* May be incorrect if MPFR_EMAX_MAX >= 2^62. */
+ MPFR_ASSERTN ((MPFR_EMAX_MAX >> 31) >> 31 == 0);
+ return mpfr_underflow (y, (rnd == MPFR_RNDN) ? MPFR_RNDZ : rnd, 1);
+ }
+ }
+
+ /* Init stuff */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ if (MPFR_SIGN (x) < 0)
+ {
+ mpfr_exp_t e = MPFR_EXP(x);
+ /* For x < 0 going to -infinity, erfc(x) tends to 2 by below.
+ More precisely, we have 2 + 1/sqrt(Pi)/x/exp(x^2) < erfc(x) < 2.
+ Thus log2 |2 - erfc(x)| <= -log2|x| - x^2 / log(2).
+ If |2 - erfc(x)| < 2^(-PREC(y)) then the result is either 2 or
+ nextbelow(2).
+ For x <= -27282, -log2|x| - x^2 / log(2) <= -2^30.
+ */
+ if ((MPFR_PREC(y) <= 7 && e >= 2) || /* x <= -2 */
+ (MPFR_PREC(y) <= 25 && e >= 3) || /* x <= -4 */
+ (MPFR_PREC(y) <= 120 && mpfr_cmp_si (x, -9) <= 0) ||
+ mpfr_cmp_si (x, -27282) <= 0)
+ {
+ near_two:
+ mpfr_set_ui (y, 2, MPFR_RNDN);
+ mpfr_set_inexflag ();
+ if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ {
+ mpfr_nextbelow (y);
+ inex = -1;
+ }
+ else
+ inex = 1;
+ goto end;
+ }
+ else if (e >= 3) /* more accurate test */
+ {
+ mpfr_t t, u;
+ int near_2;
+ mpfr_init2 (t, 32);
+ mpfr_init2 (u, 32);
+ /* the following is 1/log(2) rounded to zero on 32 bits */
+ mpfr_set_str_binary (t, "1.0111000101010100011101100101001");
+ mpfr_sqr (u, x, MPFR_RNDZ);
+ mpfr_mul (t, t, u, MPFR_RNDZ); /* t <= x^2/log(2) */
+ mpfr_neg (u, x, MPFR_RNDZ); /* 0 <= u <= |x| */
+ mpfr_log2 (u, u, MPFR_RNDZ); /* u <= log2(|x|) */
+ mpfr_add (t, t, u, MPFR_RNDZ); /* t <= log2|x| + x^2 / log(2) */
+ /* Taking into account that mpfr_exp_t >= mpfr_prec_t */
+ mpfr_set_exp_t (u, MPFR_PREC (y), MPFR_RNDU);
+ near_2 = mpfr_cmp (t, u) >= 0; /* 1 if PREC(y) <= u <= t <= ... */
+ mpfr_clear (t);
+ mpfr_clear (u);
+ if (near_2)
+ goto near_two;
+ }
+ }
+
+ /* erfc(x) ~ 1, with error < 2^(EXP(x)+1) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, __gmpfr_one, - MPFR_GET_EXP (x) - 1,
+ 0, MPFR_SIGN(x) < 0,
+ rnd, inex = _inexact; goto end);
+
+ prec = MPFR_PREC (y) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (y)) + 3;
+ if (MPFR_GET_EXP (x) > 0)
+ prec += 2 * MPFR_GET_EXP(x);
+
+ mpfr_init2 (tmp, prec);
+
+ MPFR_ZIV_INIT (loop, prec); /* Initialize the ZivLoop controler */
+ for (;;) /* Infinite loop */
+ {
+ /* use asymptotic formula only whenever x^2 >= p*log(2),
+ otherwise it will not converge */
+ if (MPFR_SIGN (x) > 0 &&
+ 2 * MPFR_GET_EXP (x) - 2 >= MPFR_INT_CEIL_LOG2 (prec))
+ /* we have x^2 >= p in that case */
+ {
+ err = mpfr_erfc_asympt (tmp, x);
+ if (err == 0) /* underflow case */
+ {
+ mpfr_clear (tmp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (y, (rnd == MPFR_RNDN) ? MPFR_RNDZ : rnd, 1);
+ }
+ }
+ else
+ {
+ mpfr_erf (tmp, x, MPFR_RNDN);
+ MPFR_ASSERTD (!MPFR_IS_SINGULAR (tmp)); /* FIXME: 0 only for x=0 ? */
+ te = MPFR_GET_EXP (tmp);
+ mpfr_ui_sub (tmp, 1, tmp, MPFR_RNDN);
+ /* See error analysis in algorithms.tex for details */
+ if (MPFR_IS_ZERO (tmp))
+ {
+ prec *= 2;
+ err = prec; /* ensures MPFR_CAN_ROUND fails */
+ }
+ else
+ err = MAX (te - MPFR_GET_EXP (tmp), 0) + 1;
+ }
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp, prec - err, MPFR_PREC (y), rnd)))
+ break;
+ MPFR_ZIV_NEXT (loop, prec); /* Increase used precision */
+ mpfr_set_prec (tmp, prec);
+ }
+ MPFR_ZIV_FREE (loop); /* Free the ZivLoop Controler */
+
+ inex = mpfr_set (y, tmp, rnd); /* Set y to the computed value */
+ mpfr_clear (tmp);
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd);
+}
diff --git a/mpfr/src/exceptions.c b/mpfr/src/exceptions.c
new file mode 100644
index 0000000000..2bd89dc3cb
--- /dev/null
+++ b/mpfr/src/exceptions.c
@@ -0,0 +1,360 @@
+/* Exception flags and utilities.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+unsigned int MPFR_THREAD_ATTR __gmpfr_flags = 0;
+
+mpfr_exp_t MPFR_THREAD_ATTR __gmpfr_emin = MPFR_EMIN_DEFAULT;
+mpfr_exp_t MPFR_THREAD_ATTR __gmpfr_emax = MPFR_EMAX_DEFAULT;
+
+#undef mpfr_get_emin
+
+mpfr_exp_t
+mpfr_get_emin (void)
+{
+ return __gmpfr_emin;
+}
+
+#undef mpfr_set_emin
+
+int
+mpfr_set_emin (mpfr_exp_t exponent)
+{
+ if (exponent >= MPFR_EMIN_MIN && exponent <= MPFR_EMIN_MAX)
+ {
+ __gmpfr_emin = exponent;
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+mpfr_exp_t
+mpfr_get_emin_min (void)
+{
+ return MPFR_EMIN_MIN;
+}
+
+mpfr_exp_t
+mpfr_get_emin_max (void)
+{
+ return MPFR_EMIN_MAX;
+}
+
+#undef mpfr_get_emax
+
+mpfr_exp_t
+mpfr_get_emax (void)
+{
+ return __gmpfr_emax;
+}
+
+#undef mpfr_set_emax
+
+int
+mpfr_set_emax (mpfr_exp_t exponent)
+{
+ if (exponent >= MPFR_EMAX_MIN && exponent <= MPFR_EMAX_MAX)
+ {
+ __gmpfr_emax = exponent;
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+mpfr_exp_t
+mpfr_get_emax_min (void)
+{
+ return MPFR_EMAX_MIN;
+}
+mpfr_exp_t
+mpfr_get_emax_max (void)
+{
+ return MPFR_EMAX_MAX;
+}
+
+
+#undef mpfr_clear_flags
+
+void
+mpfr_clear_flags (void)
+{
+ __gmpfr_flags = 0;
+}
+
+#undef mpfr_clear_underflow
+
+void
+mpfr_clear_underflow (void)
+{
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW;
+}
+
+#undef mpfr_clear_overflow
+
+void
+mpfr_clear_overflow (void)
+{
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW;
+}
+
+#undef mpfr_clear_divby0
+
+void
+mpfr_clear_divby0 (void)
+{
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_DIVBY0;
+}
+
+#undef mpfr_clear_nanflag
+
+void
+mpfr_clear_nanflag (void)
+{
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN;
+}
+
+#undef mpfr_clear_inexflag
+
+void
+mpfr_clear_inexflag (void)
+{
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT;
+}
+
+#undef mpfr_clear_erangeflag
+
+void
+mpfr_clear_erangeflag (void)
+{
+ __gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
+}
+
+#undef mpfr_set_underflow
+
+void
+mpfr_set_underflow (void)
+{
+ __gmpfr_flags |= MPFR_FLAGS_UNDERFLOW;
+}
+
+#undef mpfr_set_overflow
+
+void
+mpfr_set_overflow (void)
+{
+ __gmpfr_flags |= MPFR_FLAGS_OVERFLOW;
+}
+
+#undef mpfr_set_divby0
+
+void
+mpfr_set_divby0 (void)
+{
+ __gmpfr_flags |= MPFR_FLAGS_DIVBY0;
+}
+
+#undef mpfr_set_nanflag
+
+void
+mpfr_set_nanflag (void)
+{
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+}
+
+#undef mpfr_set_inexflag
+
+void
+mpfr_set_inexflag (void)
+{
+ __gmpfr_flags |= MPFR_FLAGS_INEXACT;
+}
+
+#undef mpfr_set_erangeflag
+
+void
+mpfr_set_erangeflag (void)
+{
+ __gmpfr_flags |= MPFR_FLAGS_ERANGE;
+}
+
+
+#undef mpfr_check_range
+
+int
+mpfr_check_range (mpfr_ptr x, int t, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_LIKELY( MPFR_IS_PURE_FP(x)) )
+ { /* x is a non-zero FP */
+ mpfr_exp_t exp = MPFR_EXP (x); /* Do not use MPFR_GET_EXP */
+ if (MPFR_UNLIKELY( exp < __gmpfr_emin) )
+ {
+ /* The following test is necessary because in the rounding to the
+ * nearest mode, mpfr_underflow always rounds away from 0. In
+ * this rounding mode, we need to round to 0 if:
+ * _ |x| < 2^(emin-2), or
+ * _ |x| = 2^(emin-2) and the absolute value of the exact
+ * result is <= 2^(emin-2).
+ */
+ if (rnd_mode == MPFR_RNDN &&
+ (exp + 1 < __gmpfr_emin ||
+ (mpfr_powerof2_raw(x) &&
+ (MPFR_IS_NEG(x) ? t <= 0 : t >= 0))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow(x, rnd_mode, MPFR_SIGN(x));
+ }
+ if (MPFR_UNLIKELY( exp > __gmpfr_emax) )
+ return mpfr_overflow (x, rnd_mode, MPFR_SIGN(x));
+ }
+ else if (MPFR_UNLIKELY (t != 0 && MPFR_IS_INF (x)))
+ {
+ /* We need to do the following because most MPFR functions are
+ * implemented in the following way:
+ * Ziv's loop:
+ * | Compute an approximation to the result and an error bound.
+ * | Possible underflow/overflow detection -> return.
+ * | If can_round, break (exit the loop).
+ * | Otherwise, increase the working precision and loop.
+ * Round the approximation in the target precision. <== See below
+ * Restore the flags (that could have been set due to underflows
+ * or overflows during the internal computations).
+ * Execute: return mpfr_check_range (...).
+ * The problem is that an overflow could be generated when rounding the
+ * approximation (in general, such an overflow could not be detected
+ * earlier), and the overflow flag is lost when the flags are restored.
+ * This can occur only when the rounding yields an exponent change
+ * and the new exponent is larger than the maximum exponent, so that
+ * an infinity is necessarily obtained.
+ * So, the simplest solution is to detect this overflow case here in
+ * mpfr_check_range, which is easy to do since the rounded result is
+ * necessarily an inexact infinity.
+ */
+ __gmpfr_flags |= MPFR_FLAGS_OVERFLOW;
+ }
+ MPFR_RET (t); /* propagate inexact ternary value, unlike most functions */
+}
+
+#undef mpfr_underflow_p
+
+int
+mpfr_underflow_p (void)
+{
+ return __gmpfr_flags & MPFR_FLAGS_UNDERFLOW;
+}
+
+#undef mpfr_overflow_p
+
+int
+mpfr_overflow_p (void)
+{
+ return __gmpfr_flags & MPFR_FLAGS_OVERFLOW;
+}
+
+#undef mpfr_divby0_p
+
+int
+mpfr_divby0_p (void)
+{
+ return __gmpfr_flags & MPFR_FLAGS_DIVBY0;
+}
+
+#undef mpfr_nanflag_p
+
+int
+mpfr_nanflag_p (void)
+{
+ return __gmpfr_flags & MPFR_FLAGS_NAN;
+}
+
+#undef mpfr_inexflag_p
+
+int
+mpfr_inexflag_p (void)
+{
+ return __gmpfr_flags & MPFR_FLAGS_INEXACT;
+}
+
+#undef mpfr_erangeflag_p
+
+int
+mpfr_erangeflag_p (void)
+{
+ return __gmpfr_flags & MPFR_FLAGS_ERANGE;
+}
+
+/* #undef mpfr_underflow */
+
+/* Note: In the rounding to the nearest mode, mpfr_underflow
+ always rounds away from 0. In this rounding mode, you must call
+ mpfr_underflow with rnd_mode = MPFR_RNDZ if the exact result
+ is <= 2^(emin-2) in absolute value. */
+
+int
+mpfr_underflow (mpfr_ptr x, mpfr_rnd_t rnd_mode, int sign)
+{
+ int inex;
+
+ MPFR_ASSERT_SIGN (sign);
+
+ if (MPFR_IS_LIKE_RNDZ(rnd_mode, sign < 0))
+ {
+ MPFR_SET_ZERO(x);
+ inex = -1;
+ }
+ else
+ {
+ mpfr_setmin (x, __gmpfr_emin);
+ inex = 1;
+ }
+ MPFR_SET_SIGN(x, sign);
+ __gmpfr_flags |= MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW;
+ return sign > 0 ? inex : -inex;
+}
+
+/* #undef mpfr_overflow */
+
+int
+mpfr_overflow (mpfr_ptr x, mpfr_rnd_t rnd_mode, int sign)
+{
+ int inex;
+
+ MPFR_ASSERT_SIGN(sign);
+ if (MPFR_IS_LIKE_RNDZ(rnd_mode, sign < 0))
+ {
+ mpfr_setmax (x, __gmpfr_emax);
+ inex = -1;
+ }
+ else
+ {
+ MPFR_SET_INF(x);
+ inex = 1;
+ }
+ MPFR_SET_SIGN(x,sign);
+ __gmpfr_flags |= MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
+ return sign > 0 ? inex : -inex;
+}
diff --git a/mpfr/src/exp.c b/mpfr/src/exp.c
new file mode 100644
index 0000000000..82e6d4b4ad
--- /dev/null
+++ b/mpfr/src/exp.c
@@ -0,0 +1,164 @@
+/* mpfr_exp -- exponential of a floating-point number
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* #define DEBUG */
+
+int
+mpfr_exp (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_exp_t expx;
+ mpfr_prec_t precy;
+ int inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(x) ))
+ {
+ if (MPFR_IS_NAN(x))
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF(x))
+ {
+ if (MPFR_IS_POS(x))
+ MPFR_SET_INF(y);
+ else
+ MPFR_SET_ZERO(y);
+ MPFR_SET_POS(y);
+ MPFR_RET(0);
+ }
+ else
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(x));
+ return mpfr_set_ui (y, 1, rnd_mode);
+ }
+ }
+
+ /* First, let's detect most overflow and underflow cases. */
+ {
+ mpfr_t e, bound;
+
+ /* We must extended the exponent range and save the flags now. */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (e, sizeof (mpfr_exp_t) * CHAR_BIT);
+ mpfr_init2 (bound, 32);
+
+ inexact = mpfr_set_exp_t (e, expo.saved_emax, MPFR_RNDN);
+ MPFR_ASSERTD (inexact == 0);
+ mpfr_const_log2 (bound, expo.saved_emax < 0 ? MPFR_RNDD : MPFR_RNDU);
+ mpfr_mul (bound, bound, e, MPFR_RNDU);
+ if (MPFR_UNLIKELY (mpfr_cmp (x, bound) >= 0))
+ {
+ /* x > log(2^emax), thus exp(x) > 2^emax */
+ mpfr_clears (e, bound, (mpfr_ptr) 0);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_overflow (y, rnd_mode, 1);
+ }
+
+ inexact = mpfr_set_exp_t (e, expo.saved_emin, MPFR_RNDN);
+ MPFR_ASSERTD (inexact == 0);
+ inexact = mpfr_sub_ui (e, e, 2, MPFR_RNDN);
+ MPFR_ASSERTD (inexact == 0);
+ mpfr_const_log2 (bound, expo.saved_emin < 0 ? MPFR_RNDU : MPFR_RNDD);
+ mpfr_mul (bound, bound, e, MPFR_RNDD);
+ if (MPFR_UNLIKELY (mpfr_cmp (x, bound) <= 0))
+ {
+ /* x < log(2^(emin - 2)), thus exp(x) < 2^(emin - 2) */
+ mpfr_clears (e, bound, (mpfr_ptr) 0);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (y, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
+ 1);
+ }
+
+ /* Other overflow/underflow cases must be detected
+ by the generic routines. */
+ mpfr_clears (e, bound, (mpfr_ptr) 0);
+ MPFR_SAVE_EXPO_FREE (expo);
+ }
+
+ expx = MPFR_GET_EXP (x);
+ precy = MPFR_PREC (y);
+
+ /* if x < 2^(-precy), then exp(x) i.e. gives 1 +/- 1 ulp(1) */
+ if (MPFR_UNLIKELY (expx < 0 && (mpfr_uexp_t) (-expx) > precy))
+ {
+ mpfr_exp_t emin = __gmpfr_emin;
+ mpfr_exp_t emax = __gmpfr_emax;
+ int signx = MPFR_SIGN (x);
+
+ MPFR_SET_POS (y);
+ if (MPFR_IS_NEG_SIGN (signx) && (rnd_mode == MPFR_RNDD ||
+ rnd_mode == MPFR_RNDZ))
+ {
+ __gmpfr_emin = 0;
+ __gmpfr_emax = 0;
+ mpfr_setmax (y, 0); /* y = 1 - epsilon */
+ inexact = -1;
+ }
+ else
+ {
+ __gmpfr_emin = 1;
+ __gmpfr_emax = 1;
+ mpfr_setmin (y, 1); /* y = 1 */
+ if (MPFR_IS_POS_SIGN (signx) && (rnd_mode == MPFR_RNDU ||
+ rnd_mode == MPFR_RNDA))
+ {
+ mp_size_t yn;
+ int sh;
+
+ yn = MPFR_LIMB_SIZE (y);
+ sh = (mpfr_prec_t) yn * GMP_NUMB_BITS - MPFR_PREC(y);
+ MPFR_MANT(y)[0] += MPFR_LIMB_ONE << sh;
+ inexact = 1;
+ }
+ else
+ inexact = -MPFR_FROM_SIGN_TO_INT(signx);
+ }
+
+ __gmpfr_emin = emin;
+ __gmpfr_emax = emax;
+ }
+ else /* General case */
+ {
+ if (MPFR_UNLIKELY (precy >= MPFR_EXP_THRESHOLD))
+ /* mpfr_exp_3 saves the exponent range and flags itself, otherwise
+ the flag changes in mpfr_exp_3 are lost */
+ inexact = mpfr_exp_3 (y, x, rnd_mode); /* O(M(n) log(n)^2) */
+ else
+ {
+ MPFR_SAVE_EXPO_MARK (expo);
+ inexact = mpfr_exp_2 (y, x, rnd_mode); /* O(n^(1/3) M(n)) */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ MPFR_SAVE_EXPO_FREE (expo);
+ }
+ }
+
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/exp10.c b/mpfr/src/exp10.c
new file mode 100644
index 0000000000..3540cb97af
--- /dev/null
+++ b/mpfr/src/exp10.c
@@ -0,0 +1,29 @@
+/* mpfr_exp10 -- power of 10 function 10^y
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_exp10 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_ui_pow (y, 10, x, rnd_mode);
+}
diff --git a/mpfr/src/exp2.c b/mpfr/src/exp2.c
new file mode 100644
index 0000000000..a107d8ade7
--- /dev/null
+++ b/mpfr/src/exp2.c
@@ -0,0 +1,151 @@
+/* mpfr_exp2 -- power of 2 function 2^y
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* The computation of y = 2^z is done by *
+ * y = exp(z*log(2)). The result is exact iff z is an integer. */
+
+int
+mpfr_exp2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ long xint;
+ mpfr_t xfrac;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y,
+ inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ if (MPFR_IS_POS (x))
+ MPFR_SET_INF (y);
+ else
+ MPFR_SET_ZERO (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0);
+ }
+ else /* 2^0 = 1 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO(x));
+ return mpfr_set_ui (y, 1, rnd_mode);
+ }
+ }
+
+ /* since the smallest representable non-zero float is 1/2*2^__gmpfr_emin,
+ if x < __gmpfr_emin - 1, the result is either 1/2*2^__gmpfr_emin or 0 */
+ MPFR_ASSERTN (MPFR_EMIN_MIN >= LONG_MIN + 2);
+ if (MPFR_UNLIKELY (mpfr_cmp_si (x, __gmpfr_emin - 1) < 0))
+ {
+ mpfr_rnd_t rnd2 = rnd_mode;
+ /* in round to nearest mode, round to zero when x <= __gmpfr_emin-2 */
+ if (rnd_mode == MPFR_RNDN &&
+ mpfr_cmp_si_2exp (x, __gmpfr_emin - 2, 0) <= 0)
+ rnd2 = MPFR_RNDZ;
+ return mpfr_underflow (y, rnd2, 1);
+ }
+
+ MPFR_ASSERTN (MPFR_EMAX_MAX <= LONG_MAX);
+ if (MPFR_UNLIKELY (mpfr_cmp_si (x, __gmpfr_emax) >= 0))
+ return mpfr_overflow (y, rnd_mode, 1);
+
+ /* We now know that emin - 1 <= x < emax. */
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* 2^x = 1 + x*log(2) + O(x^2) for x near zero, and for |x| <= 1 we have
+ |2^x - 1| <= x < 2^EXP(x). If x > 0 we must round away from 0 (dir=1);
+ if x < 0 we must round toward 0 (dir=0). */
+ MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (y, __gmpfr_one, - MPFR_GET_EXP (x), 0,
+ MPFR_SIGN(x) > 0, rnd_mode, expo, {});
+
+ xint = mpfr_get_si (x, MPFR_RNDZ);
+ mpfr_init2 (xfrac, MPFR_PREC (x));
+ mpfr_sub_si (xfrac, x, xint, MPFR_RNDN); /* exact */
+
+ if (MPFR_IS_ZERO (xfrac))
+ {
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ inexact = 0;
+ }
+ else
+ {
+ /* Declaration of the intermediary variable */
+ mpfr_t t;
+
+ /* Declaration of the size variable */
+ mpfr_prec_t Ny = MPFR_PREC(y); /* target precision */
+ mpfr_prec_t Nt; /* working precision */
+ mpfr_exp_t err; /* error */
+ MPFR_ZIV_DECL (loop);
+
+ /* compute the precision of intermediary variable */
+ /* the optimal number of bits : see algorithms.tex */
+ Nt = Ny + 5 + MPFR_INT_CEIL_LOG2 (Ny);
+
+ /* initialise of intermediary variable */
+ mpfr_init2 (t, Nt);
+
+ /* First computation */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ /* compute exp(x*ln(2))*/
+ mpfr_const_log2 (t, MPFR_RNDU); /* ln(2) */
+ mpfr_mul (t, xfrac, t, MPFR_RNDU); /* xfrac * ln(2) */
+ err = Nt - (MPFR_GET_EXP (t) + 2); /* Estimate of the error */
+ mpfr_exp (t, t, MPFR_RNDN); /* exp(xfrac * ln(2)) */
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ break;
+
+ /* Actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (y, t, rnd_mode);
+
+ mpfr_clear (t);
+ }
+
+ mpfr_clear (xfrac);
+ mpfr_clear_flags ();
+ mpfr_mul_2si (y, y, xint, MPFR_RNDN); /* exact or overflow */
+ /* Note: We can have an overflow only when t was rounded up to 2. */
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (y) || inexact > 0);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/exp3.c b/mpfr/src/exp3.c
new file mode 100644
index 0000000000..57fd0a4bb2
--- /dev/null
+++ b/mpfr/src/exp3.c
@@ -0,0 +1,335 @@
+/* mpfr_exp -- exponential of a floating-point number
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H /* for MPFR_MPZ_SIZEINBASE2 */
+#include "mpfr-impl.h"
+
+/* y <- exp(p/2^r) within 1 ulp, using 2^m terms from the series
+ Assume |p/2^r| < 1.
+ We use the following binary splitting formula:
+ P(a,b) = p if a+1=b, P(a,c)*P(c,b) otherwise
+ Q(a,b) = a*2^r if a+1=b [except Q(0,1)=1], Q(a,c)*Q(c,b) otherwise
+ T(a,b) = P(a,b) if a+1=b, Q(c,b)*T(a,c)+P(a,c)*T(c,b) otherwise
+ Then exp(p/2^r) ~ T(0,i)/Q(0,i) for i so that (p/2^r)^i/i! is small enough.
+
+ Since P(a,b) = p^(b-a), and we consider only values of b-a of the form 2^j,
+ we don't need to compute P(), we only precompute p^(2^j) in the ptoj[] array
+ below.
+
+ Since Q(a,b) is divisible by 2^(r*(b-a-1)), we don't compute the power of
+ two part.
+*/
+static void
+mpfr_exp_rational (mpfr_ptr y, mpz_ptr p, long r, int m,
+ mpz_t *Q, mpfr_prec_t *mult)
+{
+ unsigned long n, i, j;
+ mpz_t *S, *ptoj;
+ mpfr_prec_t *log2_nb_terms;
+ mpfr_exp_t diff, expo;
+ mpfr_prec_t precy = MPFR_PREC(y), prec_i_have, prec_ptoj;
+ int k, l;
+
+ MPFR_ASSERTN ((size_t) m < sizeof (long) * CHAR_BIT - 1);
+
+ S = Q + (m+1);
+ ptoj = Q + 2*(m+1); /* ptoj[i] = mantissa^(2^i) */
+ log2_nb_terms = mult + (m+1);
+
+ /* Normalize p */
+ MPFR_ASSERTD (mpz_cmp_ui (p, 0) != 0);
+ n = mpz_scan1 (p, 0); /* number of trailing zeros in p */
+ mpz_tdiv_q_2exp (p, p, n);
+ r -= n; /* since |p/2^r| < 1 and p >= 1, r >= 1 */
+
+ /* Set initial var */
+ mpz_set (ptoj[0], p);
+ for (k = 1; k < m; k++)
+ mpz_mul (ptoj[k], ptoj[k-1], ptoj[k-1]); /* ptoj[k] = p^(2^k) */
+ mpz_set_ui (Q[0], 1);
+ mpz_set_ui (S[0], 1);
+ k = 0;
+ mult[0] = 0; /* the multiplier P[k]/Q[k] for the remaining terms
+ satisfies P[k]/Q[k] <= 2^(-mult[k]) */
+ log2_nb_terms[0] = 0; /* log2(#terms) [exact in 1st loop where 2^k] */
+ prec_i_have = 0;
+
+ /* Main Loop */
+ n = 1UL << m;
+ for (i = 1; (prec_i_have < precy) && (i < n); i++)
+ {
+ /* invariant: Q[0]*Q[1]*...*Q[k] equals i! */
+ k++;
+ log2_nb_terms[k] = 0; /* 1 term */
+ mpz_set_ui (Q[k], i + 1);
+ mpz_set_ui (S[k], i + 1);
+ j = i + 1; /* we have computed j = i+1 terms so far */
+ l = 0;
+ while ((j & 1) == 0) /* combine and reduce */
+ {
+ /* invariant: S[k] corresponds to 2^l consecutive terms */
+ mpz_mul (S[k], S[k], ptoj[l]);
+ mpz_mul (S[k-1], S[k-1], Q[k]);
+ /* Q[k] corresponds to 2^l consecutive terms too.
+ Since it does not contains the factor 2^(r*2^l),
+ when going from l to l+1 we need to multiply
+ by 2^(r*2^(l+1))/2^(r*2^l) = 2^(r*2^l) */
+ mpz_mul_2exp (S[k-1], S[k-1], r << l);
+ mpz_add (S[k-1], S[k-1], S[k]);
+ mpz_mul (Q[k-1], Q[k-1], Q[k]);
+ log2_nb_terms[k-1] ++; /* number of terms in S[k-1]
+ is a power of 2 by construction */
+ MPFR_MPZ_SIZEINBASE2 (prec_i_have, Q[k]);
+ MPFR_MPZ_SIZEINBASE2 (prec_ptoj, ptoj[l]);
+ mult[k-1] += prec_i_have + (r << l) - prec_ptoj - 1;
+ prec_i_have = mult[k] = mult[k-1];
+ /* since mult[k] >= mult[k-1] + nbits(Q[k]),
+ we have Q[0]*...*Q[k] <= 2^mult[k] = 2^prec_i_have */
+ l ++;
+ j >>= 1;
+ k --;
+ }
+ }
+
+ /* accumulate all products in S[0] and Q[0]. Warning: contrary to above,
+ here we do not have log2_nb_terms[k-1] = log2_nb_terms[k]+1. */
+ l = 0; /* number of accumulated terms in the right part S[k]/Q[k] */
+ while (k > 0)
+ {
+ j = log2_nb_terms[k-1];
+ mpz_mul (S[k], S[k], ptoj[j]);
+ mpz_mul (S[k-1], S[k-1], Q[k]);
+ l += 1 << log2_nb_terms[k];
+ mpz_mul_2exp (S[k-1], S[k-1], r * l);
+ mpz_add (S[k-1], S[k-1], S[k]);
+ mpz_mul (Q[k-1], Q[k-1], Q[k]);
+ k--;
+ }
+
+ /* Q[0] now equals i! */
+ MPFR_MPZ_SIZEINBASE2 (prec_i_have, S[0]);
+ diff = (mpfr_exp_t) prec_i_have - 2 * (mpfr_exp_t) precy;
+ expo = diff;
+ if (diff >= 0)
+ mpz_fdiv_q_2exp (S[0], S[0], diff);
+ else
+ mpz_mul_2exp (S[0], S[0], -diff);
+
+ MPFR_MPZ_SIZEINBASE2 (prec_i_have, Q[0]);
+ diff = (mpfr_exp_t) prec_i_have - (mpfr_prec_t) precy;
+ expo -= diff;
+ if (diff > 0)
+ mpz_fdiv_q_2exp (Q[0], Q[0], diff);
+ else
+ mpz_mul_2exp (Q[0], Q[0], -diff);
+
+ mpz_tdiv_q (S[0], S[0], Q[0]);
+ mpfr_set_z (y, S[0], MPFR_RNDD);
+ MPFR_SET_EXP (y, MPFR_GET_EXP (y) + expo - r * (i - 1) );
+}
+
+#define shift (GMP_NUMB_BITS/2)
+
+int
+mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t t, x_copy, tmp;
+ mpz_t uk;
+ mpfr_exp_t ttt, shift_x;
+ unsigned long twopoweri;
+ mpz_t *P;
+ mpfr_prec_t *mult;
+ int i, k, loop;
+ int prec_x;
+ mpfr_prec_t realprec, Prec;
+ int iter;
+ int inexact = 0;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (ziv_loop);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y,
+ inexact));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* decompose x */
+ /* we first write x = 1.xxxxxxxxxxxxx
+ ----- k bits -- */
+ prec_x = MPFR_INT_CEIL_LOG2 (MPFR_PREC (x)) - MPFR_LOG2_GMP_NUMB_BITS;
+ if (prec_x < 0)
+ prec_x = 0;
+
+ ttt = MPFR_GET_EXP (x);
+ mpfr_init2 (x_copy, MPFR_PREC(x));
+ mpfr_set (x_copy, x, MPFR_RNDD);
+
+ /* we shift to get a number less than 1 */
+ if (ttt > 0)
+ {
+ shift_x = ttt;
+ mpfr_div_2ui (x_copy, x, ttt, MPFR_RNDN);
+ ttt = MPFR_GET_EXP (x_copy);
+ }
+ else
+ shift_x = 0;
+ MPFR_ASSERTD (ttt <= 0);
+
+ /* Init prec and vars */
+ realprec = MPFR_PREC (y) + MPFR_INT_CEIL_LOG2 (prec_x + MPFR_PREC (y));
+ Prec = realprec + shift + 2 + shift_x;
+ mpfr_init2 (t, Prec);
+ mpfr_init2 (tmp, Prec);
+ mpz_init (uk);
+
+ /* Main loop */
+ MPFR_ZIV_INIT (ziv_loop, realprec);
+ for (;;)
+ {
+ int scaled = 0;
+ MPFR_BLOCK_DECL (flags);
+
+ k = MPFR_INT_CEIL_LOG2 (Prec) - MPFR_LOG2_GMP_NUMB_BITS;
+
+ /* now we have to extract */
+ twopoweri = GMP_NUMB_BITS;
+
+ /* Allocate tables */
+ P = (mpz_t*) (*__gmp_allocate_func) (3*(k+2)*sizeof(mpz_t));
+ for (i = 0; i < 3*(k+2); i++)
+ mpz_init (P[i]);
+ mult = (mpfr_prec_t*) (*__gmp_allocate_func) (2*(k+2)*sizeof(mpfr_prec_t));
+
+ /* Particular case for i==0 */
+ mpfr_extract (uk, x_copy, 0);
+ MPFR_ASSERTD (mpz_cmp_ui (uk, 0) != 0);
+ mpfr_exp_rational (tmp, uk, shift + twopoweri - ttt, k + 1, P, mult);
+ for (loop = 0; loop < shift; loop++)
+ mpfr_sqr (tmp, tmp, MPFR_RNDD);
+ twopoweri *= 2;
+
+ /* General case */
+ iter = (k <= prec_x) ? k : prec_x;
+ for (i = 1; i <= iter; i++)
+ {
+ mpfr_extract (uk, x_copy, i);
+ if (MPFR_LIKELY (mpz_cmp_ui (uk, 0) != 0))
+ {
+ mpfr_exp_rational (t, uk, twopoweri - ttt, k - i + 1, P, mult);
+ mpfr_mul (tmp, tmp, t, MPFR_RNDD);
+ }
+ MPFR_ASSERTN (twopoweri <= LONG_MAX/2);
+ twopoweri *=2;
+ }
+
+ /* Clear tables */
+ for (i = 0; i < 3*(k+2); i++)
+ mpz_clear (P[i]);
+ (*__gmp_free_func) (P, 3*(k+2)*sizeof(mpz_t));
+ (*__gmp_free_func) (mult, 2*(k+2)*sizeof(mpfr_prec_t));
+
+ if (shift_x > 0)
+ {
+ MPFR_BLOCK (flags, {
+ for (loop = 0; loop < shift_x - 1; loop++)
+ mpfr_sqr (tmp, tmp, MPFR_RNDD);
+ mpfr_sqr (t, tmp, MPFR_RNDD);
+ } );
+
+ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags)))
+ {
+ /* tmp <= exact result, so that it is a real overflow. */
+ inexact = mpfr_overflow (y, rnd_mode, 1);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
+ break;
+ }
+
+ if (MPFR_UNLIKELY (MPFR_UNDERFLOW (flags)))
+ {
+ /* This may be a spurious underflow. So, let's scale
+ the result. */
+ mpfr_mul_2ui (tmp, tmp, 1, MPFR_RNDD); /* no overflow, exact */
+ mpfr_sqr (t, tmp, MPFR_RNDD);
+ if (MPFR_IS_ZERO (t))
+ {
+ /* approximate result < 2^(emin - 3), thus
+ exact result < 2^(emin - 2). */
+ inexact = mpfr_underflow (y, (rnd_mode == MPFR_RNDN) ?
+ MPFR_RNDZ : rnd_mode, 1);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_UNDERFLOW);
+ break;
+ }
+ scaled = 1;
+ }
+ }
+
+ if (mpfr_can_round (shift_x > 0 ? t : tmp, realprec, MPFR_RNDD, MPFR_RNDZ,
+ MPFR_PREC(y) + (rnd_mode == MPFR_RNDN)))
+ {
+ inexact = mpfr_set (y, shift_x > 0 ? t : tmp, rnd_mode);
+ if (MPFR_UNLIKELY (scaled && MPFR_IS_PURE_FP (y)))
+ {
+ int inex2;
+ mpfr_exp_t ey;
+
+ /* The result has been scaled and needs to be corrected. */
+ ey = MPFR_GET_EXP (y);
+ inex2 = mpfr_mul_2si (y, y, -2, rnd_mode);
+ if (inex2) /* underflow */
+ {
+ if (rnd_mode == MPFR_RNDN && inexact < 0 &&
+ MPFR_IS_ZERO (y) && ey == __gmpfr_emin + 1)
+ {
+ /* Double rounding case: in MPFR_RNDN, the scaled
+ result has been rounded downward to 2^emin.
+ As the exact result is > 2^(emin - 2), correct
+ rounding must be done upward. */
+ /* TODO: make sure in coverage tests that this line
+ is reached. */
+ inexact = mpfr_underflow (y, MPFR_RNDU, 1);
+ }
+ else
+ {
+ /* No double rounding. */
+ inexact = inex2;
+ }
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_UNDERFLOW);
+ }
+ }
+ break;
+ }
+
+ MPFR_ZIV_NEXT (ziv_loop, realprec);
+ Prec = realprec + shift + 2 + shift_x;
+ mpfr_set_prec (t, Prec);
+ mpfr_set_prec (tmp, Prec);
+ }
+ MPFR_ZIV_FREE (ziv_loop);
+
+ mpz_clear (uk);
+ mpfr_clear (tmp);
+ mpfr_clear (t);
+ mpfr_clear (x_copy);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return inexact;
+}
diff --git a/mpfr/src/exp_2.c b/mpfr/src/exp_2.c
new file mode 100644
index 0000000000..7f9ef6f489
--- /dev/null
+++ b/mpfr/src/exp_2.c
@@ -0,0 +1,421 @@
+/* mpfr_exp_2 -- exponential of a floating-point number
+ using algorithms in O(n^(1/2)*M(n)) and O(n^(1/3)*M(n))
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* #define DEBUG */
+#define MPFR_NEED_LONGLONG_H /* for count_leading_zeros */
+#include "mpfr-impl.h"
+
+static unsigned long
+mpfr_exp2_aux (mpz_t, mpfr_srcptr, mpfr_prec_t, mpfr_exp_t *);
+static unsigned long
+mpfr_exp2_aux2 (mpz_t, mpfr_srcptr, mpfr_prec_t, mpfr_exp_t *);
+static mpfr_exp_t
+mpz_normalize (mpz_t, mpz_t, mpfr_exp_t);
+static mpfr_exp_t
+mpz_normalize2 (mpz_t, mpz_t, mpfr_exp_t, mpfr_exp_t);
+
+/* if k = the number of bits of z > q, divides z by 2^(k-q) and returns k-q.
+ Otherwise do nothing and return 0.
+ */
+static mpfr_exp_t
+mpz_normalize (mpz_t rop, mpz_t z, mpfr_exp_t q)
+{
+ size_t k;
+
+ MPFR_MPZ_SIZEINBASE2 (k, z);
+ MPFR_ASSERTD (k == (mpfr_uexp_t) k);
+ if (q < 0 || (mpfr_uexp_t) k > (mpfr_uexp_t) q)
+ {
+ mpz_fdiv_q_2exp (rop, z, (unsigned long) ((mpfr_uexp_t) k - q));
+ return (mpfr_exp_t) k - q;
+ }
+ if (MPFR_UNLIKELY(rop != z))
+ mpz_set (rop, z);
+ return 0;
+}
+
+/* if expz > target, shift z by (expz-target) bits to the left.
+ if expz < target, shift z by (target-expz) bits to the right.
+ Returns target.
+*/
+static mpfr_exp_t
+mpz_normalize2 (mpz_t rop, mpz_t z, mpfr_exp_t expz, mpfr_exp_t target)
+{
+ if (target > expz)
+ mpz_fdiv_q_2exp (rop, z, target - expz);
+ else
+ mpz_mul_2exp (rop, z, expz - target);
+ return target;
+}
+
+/* use Brent's formula exp(x) = (1+r+r^2/2!+r^3/3!+...)^(2^K)*2^n
+ where x = n*log(2)+(2^K)*r
+ together with the Paterson-Stockmeyer O(t^(1/2)) algorithm for the
+ evaluation of power series. The resulting complexity is O(n^(1/3)*M(n)).
+ This function returns with the exact flags due to exp.
+*/
+int
+mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ long n;
+ unsigned long K, k, l, err; /* FIXME: Which type ? */
+ int error_r;
+ mpfr_exp_t exps, expx;
+ mpfr_prec_t q, precy;
+ int inexact;
+ mpfr_t r, s;
+ mpz_t ss;
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y,
+ inexact));
+
+ expx = MPFR_GET_EXP (x);
+ precy = MPFR_PREC(y);
+
+ /* Warning: we cannot use the 'double' type here, since on 64-bit machines
+ x may be as large as 2^62*log(2) without overflow, and then x/log(2)
+ is about 2^62: not every integer of that size can be represented as a
+ 'double', thus the argument reduction would fail. */
+ if (expx <= -2)
+ /* |x| <= 0.25, thus n = round(x/log(2)) = 0 */
+ n = 0;
+ else
+ {
+ mpfr_init2 (r, sizeof (long) * CHAR_BIT);
+ mpfr_const_log2 (r, MPFR_RNDZ);
+ mpfr_div (r, x, r, MPFR_RNDN);
+ n = mpfr_get_si (r, MPFR_RNDN);
+ mpfr_clear (r);
+ }
+ /* we have |x| <= (|n|+1)*log(2) */
+ MPFR_LOG_MSG (("d(x)=%1.30e n=%ld\n", mpfr_get_d1(x), n));
+
+ /* error_r bounds the cancelled bits in x - n*log(2) */
+ if (MPFR_UNLIKELY (n == 0))
+ error_r = 0;
+ else
+ {
+ count_leading_zeros (error_r, (mp_limb_t) SAFE_ABS (unsigned long, n) + 1);
+ error_r = GMP_NUMB_BITS - error_r;
+ /* we have |x| <= 2^error_r * log(2) */
+ }
+
+ /* for the O(n^(1/2)*M(n)) method, the Taylor series computation of
+ n/K terms costs about n/(2K) multiplications when computed in fixed
+ point */
+ K = (precy < MPFR_EXP_2_THRESHOLD) ? __gmpfr_isqrt ((precy + 1) / 2)
+ : __gmpfr_cuberoot (4*precy);
+ l = (precy - 1) / K + 1;
+ err = K + MPFR_INT_CEIL_LOG2 (2 * l + 18);
+ /* add K extra bits, i.e. failure probability <= 1/2^K = O(1/precy) */
+ q = precy + err + K + 8;
+ /* if |x| >> 1, take into account the cancelled bits */
+ if (expx > 0)
+ q += expx;
+
+ /* Note: due to the mpfr_prec_round below, it is not possible to use
+ the MPFR_GROUP_* macros here. */
+
+ mpfr_init2 (r, q + error_r);
+ mpfr_init2 (s, q + error_r);
+
+ /* the algorithm consists in computing an upper bound of exp(x) using
+ a precision of q bits, and see if we can round to MPFR_PREC(y) taking
+ into account the maximal error. Otherwise we increase q. */
+ MPFR_ZIV_INIT (loop, q);
+ for (;;)
+ {
+ MPFR_LOG_MSG (("n=%ld K=%lu l=%lu q=%lu error_r=%d\n",
+ n, K, l, (unsigned long) q, error_r));
+
+ /* First reduce the argument to r = x - n * log(2),
+ so that r is small in absolute value. We want an upper
+ bound on r to get an upper bound on exp(x). */
+
+ /* if n<0, we have to get an upper bound of log(2)
+ in order to get an upper bound of r = x-n*log(2) */
+ mpfr_const_log2 (s, (n >= 0) ? MPFR_RNDZ : MPFR_RNDU);
+ /* s is within 1 ulp(s) of log(2) */
+
+ mpfr_mul_ui (r, s, (n < 0) ? -n : n, (n >= 0) ? MPFR_RNDZ : MPFR_RNDU);
+ /* r is within 3 ulps of |n|*log(2) */
+ if (n < 0)
+ MPFR_CHANGE_SIGN (r);
+ /* r <= n*log(2), within 3 ulps */
+
+ MPFR_LOG_VAR (x);
+ MPFR_LOG_VAR (r);
+
+ mpfr_sub (r, x, r, MPFR_RNDU);
+
+ if (MPFR_IS_PURE_FP (r))
+ {
+ while (MPFR_IS_NEG (r))
+ { /* initial approximation n was too large */
+ n--;
+ mpfr_add (r, r, s, MPFR_RNDU);
+ }
+
+ /* since there was a cancellation in x - n*log(2), the low error_r
+ bits from r are zero and thus non significant, thus we can reduce
+ the working precision */
+ if (error_r > 0)
+ mpfr_prec_round (r, q, MPFR_RNDU);
+ /* the error on r is at most 3 ulps (3 ulps if error_r = 0,
+ and 1 + 3/2 if error_r > 0) */
+ MPFR_LOG_VAR (r);
+ MPFR_ASSERTD (MPFR_IS_POS (r));
+ mpfr_div_2ui (r, r, K, MPFR_RNDU); /* r = (x-n*log(2))/2^K, exact */
+
+ mpz_init (ss);
+ exps = mpfr_get_z_2exp (ss, s);
+ /* s <- 1 + r/1! + r^2/2! + ... + r^l/l! */
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (r) && MPFR_EXP (r) < 0);
+ l = (precy < MPFR_EXP_2_THRESHOLD)
+ ? mpfr_exp2_aux (ss, r, q, &exps) /* naive method */
+ : mpfr_exp2_aux2 (ss, r, q, &exps); /* Paterson/Stockmeyer meth */
+
+ MPFR_LOG_MSG (("l=%lu q=%lu (K+l)*q^2=%1.3e\n",
+ l, (unsigned long) q, (K + l) * (double) q * q));
+
+ for (k = 0; k < K; k++)
+ {
+ mpz_mul (ss, ss, ss);
+ exps <<= 1;
+ exps += mpz_normalize (ss, ss, q);
+ }
+ mpfr_set_z (s, ss, MPFR_RNDN);
+
+ MPFR_SET_EXP(s, MPFR_GET_EXP (s) + exps);
+ mpz_clear (ss);
+
+ /* error is at most 2^K*l, plus 2 to take into account of
+ the error of 3 ulps on r */
+ err = K + MPFR_INT_CEIL_LOG2 (l) + 2;
+
+ MPFR_LOG_MSG (("before mult. by 2^n:\n", 0));
+ MPFR_LOG_VAR (s);
+ MPFR_LOG_MSG (("err=%lu bits\n", K));
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, q - err, precy, rnd_mode)))
+ {
+ mpfr_clear_flags ();
+ inexact = mpfr_mul_2si (y, s, n, rnd_mode);
+ break;
+ }
+ }
+
+ MPFR_ZIV_NEXT (loop, q);
+ mpfr_set_prec (r, q + error_r);
+ mpfr_set_prec (s, q + error_r);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ mpfr_clear (r);
+ mpfr_clear (s);
+
+ return inexact;
+}
+
+/* s <- 1 + r/1! + r^2/2! + ... + r^l/l! while MPFR_EXP(r^l/l!)+MPFR_EXPR(r)>-q
+ using naive method with O(l) multiplications.
+ Return the number of iterations l.
+ The absolute error on s is less than 3*l*(l+1)*2^(-q).
+ Version using fixed-point arithmetic with mpz instead
+ of mpfr for internal computations.
+ NOTE[VL]: the following sentence seems to be obsolete since MY_INIT_MPZ
+ is no longer used (r6919); qn was the number of limbs of q.
+ s must have at least qn+1 limbs (qn should be enough, but currently fails
+ since mpz_mul_2exp(s, s, q-1) reallocates qn+1 limbs)
+*/
+static unsigned long
+mpfr_exp2_aux (mpz_t s, mpfr_srcptr r, mpfr_prec_t q, mpfr_exp_t *exps)
+{
+ unsigned long l;
+ mpfr_exp_t dif, expt, expr;
+ mpz_t t, rr;
+ mp_size_t sbit, tbit;
+
+ MPFR_ASSERTN (MPFR_IS_PURE_FP (r));
+
+ expt = 0;
+ *exps = 1 - (mpfr_exp_t) q; /* s = 2^(q-1) */
+ mpz_init (t);
+ mpz_init (rr);
+ mpz_set_ui(t, 1);
+ mpz_set_ui(s, 1);
+ mpz_mul_2exp(s, s, q-1);
+ expr = mpfr_get_z_2exp(rr, r); /* no error here */
+
+ l = 0;
+ for (;;) {
+ l++;
+ mpz_mul(t, t, rr);
+ expt += expr;
+ MPFR_MPZ_SIZEINBASE2 (sbit, s);
+ MPFR_MPZ_SIZEINBASE2 (tbit, t);
+ dif = *exps + sbit - expt - tbit;
+ /* truncates the bits of t which are < ulp(s) = 2^(1-q) */
+ expt += mpz_normalize(t, t, (mpfr_exp_t) q-dif); /* error at most 2^(1-q) */
+ mpz_fdiv_q_ui (t, t, l); /* error at most 2^(1-q) */
+ /* the error wrt t^l/l! is here at most 3*l*ulp(s) */
+ MPFR_ASSERTD (expt == *exps);
+ if (mpz_sgn (t) == 0)
+ break;
+ mpz_add(s, s, t); /* no error here: exact */
+ /* ensures rr has the same size as t: after several shifts, the error
+ on rr is still at most ulp(t)=ulp(s) */
+ MPFR_MPZ_SIZEINBASE2 (tbit, t);
+ expr += mpz_normalize(rr, rr, tbit);
+ }
+
+ mpz_clear (t);
+ mpz_clear (rr);
+
+ return 3 * l * (l + 1);
+}
+
+/* s <- 1 + r/1! + r^2/2! + ... + r^l/l! while MPFR_EXP(r^l/l!)+MPFR_EXPR(r)>-q
+ using Paterson-Stockmeyer algorithm with O(sqrt(l)) multiplications.
+ Return l.
+ Uses m multiplications of full size and 2l/m of decreasing size,
+ i.e. a total equivalent to about m+l/m full multiplications,
+ i.e. 2*sqrt(l) for m=sqrt(l).
+ NOTE[VL]: The following sentence seems to be obsolete since MY_INIT_MPZ
+ is no longer used (r6919); sizer was the number of limbs of r.
+ Version using mpz. ss must have at least (sizer+1) limbs.
+ The error is bounded by (l^2+4*l) ulps where l is the return value.
+*/
+static unsigned long
+mpfr_exp2_aux2 (mpz_t s, mpfr_srcptr r, mpfr_prec_t q, mpfr_exp_t *exps)
+{
+ mpfr_exp_t expr, *expR, expt;
+ mpfr_prec_t ql;
+ unsigned long l, m, i;
+ mpz_t t, *R, rr, tmp;
+ mp_size_t sbit, rrbit;
+ MPFR_TMP_DECL(marker);
+
+ /* estimate value of l */
+ MPFR_ASSERTD (MPFR_GET_EXP (r) < 0);
+ l = q / (- MPFR_GET_EXP (r));
+ m = __gmpfr_isqrt (l);
+ /* we access R[2], thus we need m >= 2 */
+ if (m < 2)
+ m = 2;
+
+ MPFR_TMP_MARK(marker);
+ R = (mpz_t*) MPFR_TMP_ALLOC ((m + 1) * sizeof (mpz_t)); /* R[i] is r^i */
+ expR = (mpfr_exp_t*) MPFR_TMP_ALLOC((m + 1) * sizeof (mpfr_exp_t));
+ /* expR[i] is the exponent for R[i] */
+ mpz_init (tmp);
+ mpz_init (rr);
+ mpz_init (t);
+ mpz_set_ui (s, 0);
+ *exps = 1 - q; /* 1 ulp = 2^(1-q) */
+ for (i = 0 ; i <= m ; i++)
+ mpz_init (R[i]);
+ expR[1] = mpfr_get_z_2exp (R[1], r); /* exact operation: no error */
+ expR[1] = mpz_normalize2 (R[1], R[1], expR[1], 1 - q); /* error <= 1 ulp */
+ mpz_mul (t, R[1], R[1]); /* err(t) <= 2 ulps */
+ mpz_fdiv_q_2exp (R[2], t, q - 1); /* err(R[2]) <= 3 ulps */
+ expR[2] = 1 - q;
+ for (i = 3 ; i <= m ; i++)
+ {
+ if ((i & 1) == 1)
+ mpz_mul (t, R[i-1], R[1]); /* err(t) <= 2*i-2 */
+ else
+ mpz_mul (t, R[i/2], R[i/2]);
+ mpz_fdiv_q_2exp (R[i], t, q - 1); /* err(R[i]) <= 2*i-1 ulps */
+ expR[i] = 1 - q;
+ }
+ mpz_set_ui (R[0], 1);
+ mpz_mul_2exp (R[0], R[0], q-1);
+ expR[0] = 1-q; /* R[0]=1 */
+ mpz_set_ui (rr, 1);
+ expr = 0; /* rr contains r^l/l! */
+ /* by induction: err(rr) <= 2*l ulps */
+
+ l = 0;
+ ql = q; /* precision used for current giant step */
+ do
+ {
+ /* all R[i] must have exponent 1-ql */
+ if (l != 0)
+ for (i = 0 ; i < m ; i++)
+ expR[i] = mpz_normalize2 (R[i], R[i], expR[i], 1 - ql);
+ /* the absolute error on R[i]*rr is still 2*i-1 ulps */
+ expt = mpz_normalize2 (t, R[m-1], expR[m-1], 1 - ql);
+ /* err(t) <= 2*m-1 ulps */
+ /* computes t = 1 + r/(l+1) + ... + r^(m-1)*l!/(l+m-1)!
+ using Horner's scheme */
+ for (i = m-1 ; i-- != 0 ; )
+ {
+ mpz_fdiv_q_ui (t, t, l+i+1); /* err(t) += 1 ulp */
+ mpz_add (t, t, R[i]);
+ }
+ /* now err(t) <= (3m-2) ulps */
+
+ /* now multiplies t by r^l/l! and adds to s */
+ mpz_mul (t, t, rr);
+ expt += expr;
+ expt = mpz_normalize2 (t, t, expt, *exps);
+ /* err(t) <= (3m-1) + err_rr(l) <= (3m-2) + 2*l */
+ MPFR_ASSERTD (expt == *exps);
+ mpz_add (s, s, t); /* no error here */
+
+ /* updates rr, the multiplication of the factors l+i could be done
+ using binary splitting too, but it is not sure it would save much */
+ mpz_mul (t, rr, R[m]); /* err(t) <= err(rr) + 2m-1 */
+ expr += expR[m];
+ mpz_set_ui (tmp, 1);
+ for (i = 1 ; i <= m ; i++)
+ mpz_mul_ui (tmp, tmp, l + i);
+ mpz_fdiv_q (t, t, tmp); /* err(t) <= err(rr) + 2m */
+ l += m;
+ if (MPFR_UNLIKELY (mpz_sgn (t) == 0))
+ break;
+ expr += mpz_normalize (rr, t, ql); /* err_rr(l+1) <= err_rr(l) + 2m+1 */
+ if (MPFR_UNLIKELY (mpz_sgn (rr) == 0))
+ rrbit = 1;
+ else
+ MPFR_MPZ_SIZEINBASE2 (rrbit, rr);
+ MPFR_MPZ_SIZEINBASE2 (sbit, s);
+ ql = q - *exps - sbit + expr + rrbit;
+ /* TODO: Wrong cast. I don't want what is right, but this is
+ certainly wrong */
+ }
+ while ((size_t) expr + rrbit > (size_t) -q);
+
+ for (i = 0 ; i <= m ; i++)
+ mpz_clear (R[i]);
+ MPFR_TMP_FREE(marker);
+ mpz_clear (rr);
+ mpz_clear (t);
+ mpz_clear (tmp);
+
+ return l * (l + 4);
+}
diff --git a/mpfr/src/expm1.c b/mpfr/src/expm1.c
new file mode 100644
index 0000000000..1961dd4b8c
--- /dev/null
+++ b/mpfr/src/expm1.c
@@ -0,0 +1,179 @@
+/* mpfr_expm1 -- Compute exp(x)-1
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+ /* The computation of expm1 is done by
+ expm1(x)=exp(x)-1
+ */
+
+int
+mpfr_expm1 (mpfr_ptr y, mpfr_srcptr x , mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_exp_t ex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y,
+ inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ /* check for inf or -inf (expm1(-inf)=-1) */
+ else if (MPFR_IS_INF (x))
+ {
+ if (MPFR_IS_POS (x))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0);
+ }
+ else
+ return mpfr_set_si (y, -1, rnd_mode);
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (y); /* expm1(+/- 0) = +/- 0 */
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ }
+
+ ex = MPFR_GET_EXP (x);
+ if (ex < 0)
+ {
+ /* For -1 < x < 0, abs(expm1(x)-x) < x^2/2.
+ For 0 < x < 1, abs(expm1(x)-x) < x^2. */
+ if (MPFR_IS_POS (x))
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, - ex, 0, 1, rnd_mode, {});
+ else
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, - ex, 1, 0, rnd_mode, {});
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ if (MPFR_IS_NEG (x) && ex > 5) /* x <= -32 */
+ {
+ mpfr_t minus_one, t;
+ mpfr_exp_t err;
+
+ mpfr_init2 (minus_one, 2);
+ mpfr_init2 (t, 64);
+ mpfr_set_si (minus_one, -1, MPFR_RNDN);
+ mpfr_const_log2 (t, MPFR_RNDU); /* round upward since x is negative */
+ mpfr_div (t, x, t, MPFR_RNDU); /* > x / ln(2) */
+ err = mpfr_cmp_si (t, MPFR_EMIN_MIN >= -LONG_MAX ?
+ MPFR_EMIN_MIN : -LONG_MAX) <= 0 ?
+ - (MPFR_EMIN_MIN >= -LONG_MAX ? MPFR_EMIN_MIN : -LONG_MAX) :
+ - mpfr_get_si (t, MPFR_RNDU);
+ /* exp(x) = 2^(x/ln(2))
+ <= 2^max(MPFR_EMIN_MIN,-LONG_MAX,ceil(x/ln(2)+epsilon))
+ with epsilon > 0 */
+ mpfr_clear (t);
+ MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (y, minus_one, err, 0, 0, rnd_mode,
+ expo, { mpfr_clear (minus_one); });
+ mpfr_clear (minus_one);
+ }
+
+ /* General case */
+ {
+ /* Declaration of the intermediary variable */
+ mpfr_t t;
+ /* Declaration of the size variable */
+ mpfr_prec_t Ny = MPFR_PREC(y); /* target precision */
+ mpfr_prec_t Nt; /* working precision */
+ mpfr_exp_t err, exp_te; /* error */
+ MPFR_ZIV_DECL (loop);
+
+ /* compute the precision of intermediary variable */
+ /* the optimal number of bits : see algorithms.tex */
+ Nt = Ny + MPFR_INT_CEIL_LOG2 (Ny) + 6;
+
+ /* if |x| is smaller than 2^(-e), we will loose about e bits in the
+ subtraction exp(x) - 1 */
+ if (ex < 0)
+ Nt += - ex;
+
+ /* initialize auxiliary variable */
+ mpfr_init2 (t, Nt);
+
+ /* First computation of expm1 */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ /* exp(x) may overflow and underflow */
+ MPFR_BLOCK (flags, mpfr_exp (t, x, MPFR_RNDN));
+ if (MPFR_OVERFLOW (flags))
+ {
+ inexact = mpfr_overflow (y, rnd_mode, MPFR_SIGN_POS);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
+ break;
+ }
+ else if (MPFR_UNDERFLOW (flags))
+ {
+ inexact = mpfr_set_si (y, -1, rnd_mode);
+ MPFR_ASSERTD (inexact == 0);
+ inexact = -1;
+ if (MPFR_IS_LIKE_RNDZ (rnd_mode, 1))
+ {
+ inexact = 1;
+ mpfr_nexttozero (y);
+ }
+ break;
+ }
+
+ exp_te = MPFR_GET_EXP (t); /* FIXME: exp(x) may overflow! */
+ mpfr_sub_ui (t, t, 1, MPFR_RNDN); /* exp(x)-1 */
+
+ /* error estimate */
+ /*err=Nt-(__gmpfr_ceil_log2(1+pow(2,MPFR_EXP(te)-MPFR_EXP(t))));*/
+ err = Nt - (MAX (exp_te - MPFR_GET_EXP (t), 0) + 1);
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ {
+ inexact = mpfr_set (y, t, rnd_mode);
+ break;
+ }
+
+ /* increase the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ mpfr_clear (t);
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/extract.c b/mpfr/src/extract.c
new file mode 100644
index 0000000000..0338932053
--- /dev/null
+++ b/mpfr/src/extract.c
@@ -0,0 +1,55 @@
+/* mpfr_extract -- bit-extraction function for the binary splitting algorithm
+
+Copyright 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* given 0 <= |p| < 1, this function extracts limbs of p and puts them in y.
+ It is mainly designed for the "binary splitting" algorithm.
+
+ More precisely, if B = 2^GMP_NUMB_BITS:
+ - for i=0, y = floor(p * B)
+ - for i>0, y = (p * B^(2^i)) mod B^(2^(i-1))
+ */
+
+void
+mpfr_extract (mpz_ptr y, mpfr_srcptr p, unsigned int i)
+{
+ unsigned long two_i = 1UL << i;
+ unsigned long two_i_2 = i ? two_i / 2 : 1;
+ mp_size_t size_p = MPFR_LIMB_SIZE (p);
+
+ /* as 0 <= |p| < 1, we don't have to care with infinities, NaN, ... */
+ MPFR_ASSERTD (!MPFR_IS_SINGULAR (p));
+
+ _mpz_realloc (y, two_i_2);
+ if ((mpfr_uexp_t) size_p < two_i)
+ {
+ MPN_ZERO (PTR(y), two_i_2);
+ if ((mpfr_uexp_t) size_p >= two_i_2)
+ MPN_COPY (PTR(y) + two_i - size_p, MPFR_MANT(p), size_p - two_i_2);
+ }
+ else
+ MPN_COPY (PTR(y), MPFR_MANT(p) + size_p - two_i, two_i_2);
+
+ MPN_NORMALIZE (PTR(y), two_i_2);
+ SIZ(y) = (MPFR_IS_NEG (p)) ? -two_i_2 : two_i_2;
+}
diff --git a/mpfr/src/factorial.c b/mpfr/src/factorial.c
new file mode 100644
index 0000000000..a4fee01418
--- /dev/null
+++ b/mpfr/src/factorial.c
@@ -0,0 +1,113 @@
+/* mpfr_fac_ui -- factorial of a non-negative integer
+
+Copyright 2001, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+ /* The computation of n! is done by
+
+ n!=prod^{n}_{i=1}i
+ */
+
+/* FIXME: efficient problems with large arguments; see comments in gamma.c. */
+
+int
+mpfr_fac_ui (mpfr_ptr y, unsigned long int x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t t; /* Variable of Intermediary Calculation*/
+ unsigned long i;
+ int round, inexact;
+
+ mpfr_prec_t Ny; /* Precision of output variable */
+ mpfr_prec_t Nt; /* Precision of Intermediary Calculation variable */
+ mpfr_prec_t err; /* Precision of error */
+
+ mpfr_rnd_t rnd;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ /***** test x = 0 and x == 1******/
+ if (MPFR_UNLIKELY (x <= 1))
+ return mpfr_set_ui (y, 1, rnd_mode); /* 0! = 1 and 1! = 1 */
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Initialisation of the Precision */
+ Ny = MPFR_PREC (y);
+
+ /* compute the size of intermediary variable */
+ Nt = Ny + 2 * MPFR_INT_CEIL_LOG2 (x) + 7;
+
+ mpfr_init2 (t, Nt); /* initialise of intermediary variable */
+
+ rnd = MPFR_RNDZ;
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ /* compute factorial */
+ inexact = mpfr_set_ui (t, 1, rnd);
+ for (i = 2 ; i <= x ; i++)
+ {
+ round = mpfr_mul_ui (t, t, i, rnd);
+ /* assume the first inexact product gives the sign
+ of difference: is that always correct? */
+ if (inexact == 0)
+ inexact = round;
+ }
+
+ err = Nt - 1 - MPFR_INT_CEIL_LOG2 (Nt);
+
+ round = !inexact || mpfr_can_round (t, err, rnd, MPFR_RNDZ,
+ Ny + (rnd_mode == MPFR_RNDN));
+
+ if (MPFR_LIKELY (round))
+ {
+ /* If inexact = 0, then t is exactly x!, so round is the
+ correct inexact flag.
+ Otherwise, t != x! since we rounded to zero or away. */
+ round = mpfr_set (y, t, rnd_mode);
+ if (inexact == 0)
+ {
+ inexact = round;
+ break;
+ }
+ else if ((inexact < 0 && round <= 0)
+ || (inexact > 0 && round >= 0))
+ break;
+ else /* inexact and round have opposite signs: we cannot
+ compute the inexact flag. Restart using the
+ symmetric rounding. */
+ rnd = (rnd == MPFR_RNDZ) ? MPFR_RNDU : MPFR_RNDZ;
+ }
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
+
+
+
+
diff --git a/mpfr/src/fits_intmax.c b/mpfr/src/fits_intmax.c
new file mode 100644
index 0000000000..260338eb63
--- /dev/null
+++ b/mpfr/src/fits_intmax.c
@@ -0,0 +1,107 @@
+/* mpfr_fits_intmax_p -- test whether an mpfr fits an intmax_t.
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+#endif
+
+#include "mpfr-intmax.h"
+#include "mpfr-impl.h"
+
+#ifdef _MPFR_H_HAVE_INTMAX_T
+
+/* We can't use fits_s.h <= mpfr_cmp_ui */
+int
+mpfr_fits_intmax_p (mpfr_srcptr f, mpfr_rnd_t rnd)
+{
+ mpfr_exp_t e;
+ int prec;
+ mpfr_t x, y;
+ int neg;
+ int res;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
+ /* Zero always fit */
+ return MPFR_IS_ZERO (f) ? 1 : 0;
+
+ /* now it fits if either
+ (a) MINIMUM <= f <= MAXIMUM
+ (b) or MINIMUM <= round(f, prec(slong), rnd) <= MAXIMUM */
+
+ e = MPFR_EXP (f);
+ if (e < 1)
+ return 1; /* |f| < 1: always fits */
+
+ neg = MPFR_IS_NEG (f);
+
+ /* let EXTREMUM be MAXIMUM if f > 0, and MINIMUM if f < 0 */
+
+ /* first compute prec(EXTREMUM), this could be done at configure time,
+ but the result can depend on neg (the loop is moved inside the "if"
+ to give the compiler a better chance to compute prec statically) */
+ if (neg)
+ {
+ uintmax_t s;
+ /* In C89, the division on negative integers isn't well-defined. */
+ s = SAFE_ABS (uintmax_t, MPFR_INTMAX_MIN);
+ for (prec = 0; s != 0; s /= 2, prec ++);
+ }
+ else
+ {
+ intmax_t s;
+ s = MPFR_INTMAX_MAX;
+ for (prec = 0; s != 0; s /= 2, prec ++);
+ }
+
+ /* EXTREMUM needs prec bits, i.e. 2^(prec-1) <= |EXTREMUM| < 2^prec */
+
+ /* if e <= prec - 1, then f < 2^(prec-1) <= |EXTREMUM| */
+ if (e <= prec - 1)
+ return 1;
+
+ /* if e >= prec + 1, then f >= 2^prec > |EXTREMUM| */
+ if (e >= prec + 1)
+ return 0;
+
+ MPFR_ASSERTD (e == prec);
+
+ /* hard case: first round to prec bits, then check */
+ mpfr_init2 (x, prec);
+ mpfr_set (x, f, rnd);
+
+ if (neg)
+ {
+ mpfr_init2 (y, prec);
+ mpfr_set_sj (y, MPFR_INTMAX_MIN, MPFR_RNDN);
+ res = mpfr_cmp (x, y) >= 0;
+ mpfr_clear (y);
+ }
+ else
+ {
+ res = MPFR_GET_EXP (x) == e;
+ }
+
+ mpfr_clear (x);
+ return res;
+}
+
+#endif
diff --git a/mpfr/src/fits_s.h b/mpfr/src/fits_s.h
new file mode 100644
index 0000000000..83ebc2c283
--- /dev/null
+++ b/mpfr/src/fits_s.h
@@ -0,0 +1,89 @@
+/* mpfr_fits_*_p -- test whether an mpfr fits a C signed type.
+
+Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* The original version of this file came from GMP's mpf/fits_s.h;
+ it has been adapted for MPFR. In particular, the result can be
+ rounded away from zero. */
+
+int
+FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd)
+{
+ mpfr_exp_t e;
+ int prec;
+ mpfr_t x;
+ int neg;
+ int res;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
+ /* Zero always fit */
+ return MPFR_IS_ZERO (f) ? 1 : 0;
+
+ /* now it fits if either
+ (a) MINIMUM <= f <= MAXIMUM
+ (b) or MINIMUM <= round(f, prec(slong), rnd) <= MAXIMUM */
+
+ e = MPFR_GET_EXP (f);
+ if (e < 1)
+ return 1; /* |f| < 1: always fits */
+
+ neg = MPFR_IS_NEG (f);
+
+ /* let EXTREMUM be MAXIMUM if f > 0, and MINIMUM if f < 0 */
+
+ /* first compute prec(EXTREMUM), this could be done at configure time,
+ but the result can depend on neg (the loop is moved inside the "if"
+ to give the compiler a better chance to compute prec statically) */
+ if (neg)
+ {
+ unsigned TYPE s;
+ /* In C89, the division on negative integers isn't well-defined. */
+ s = SAFE_ABS (unsigned TYPE, MINIMUM);
+ for (prec = 0; s != 0; s /= 2, prec ++);
+ }
+ else
+ {
+ TYPE s;
+ s = MAXIMUM;
+ for (prec = 0; s != 0; s /= 2, prec ++);
+ }
+
+ /* EXTREMUM needs prec bits, i.e. 2^(prec-1) <= |EXTREMUM| < 2^prec */
+
+ /* if e <= prec - 1, then f < 2^(prec-1) <= |EXTREMUM| */
+ if (e <= prec - 1)
+ return 1;
+
+ /* if e >= prec + 1, then f >= 2^prec > |EXTREMUM| */
+ if (e >= prec + 1)
+ return 0;
+
+ MPFR_ASSERTD (e == prec);
+
+ /* hard case: first round to prec bits, then check */
+ mpfr_init2 (x, prec);
+ mpfr_set (x, f, rnd);
+ res = neg ? (mpfr_cmp_si (x, MINIMUM) >= 0) : (MPFR_GET_EXP (x) == e);
+ mpfr_clear (x);
+ return res;
+}
diff --git a/mpfr/src/fits_sint.c b/mpfr/src/fits_sint.c
new file mode 100644
index 0000000000..111b05c5a6
--- /dev/null
+++ b/mpfr/src/fits_sint.c
@@ -0,0 +1,28 @@
+/* mpfr_fits_sint_p -- test whether an mpfr fits an int.
+
+Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define FUNCTION mpfr_fits_sint_p
+#define MAXIMUM INT_MAX
+#define MINIMUM INT_MIN
+#define TYPE int
+
+#include "fits_s.h"
diff --git a/mpfr/src/fits_slong.c b/mpfr/src/fits_slong.c
new file mode 100644
index 0000000000..2e37f0de0f
--- /dev/null
+++ b/mpfr/src/fits_slong.c
@@ -0,0 +1,28 @@
+/* mpfr_fits_slong_p -- test whether an mpfr fits a long.
+
+Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define FUNCTION mpfr_fits_slong_p
+#define MAXIMUM LONG_MAX
+#define MINIMUM LONG_MIN
+#define TYPE long
+
+#include "fits_s.h"
diff --git a/mpfr/src/fits_sshort.c b/mpfr/src/fits_sshort.c
new file mode 100644
index 0000000000..85e31fbe73
--- /dev/null
+++ b/mpfr/src/fits_sshort.c
@@ -0,0 +1,28 @@
+/* mpfr_fits_sshort_p -- test whether an mpfr fits a short.
+
+Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define FUNCTION mpfr_fits_sshort_p
+#define MAXIMUM SHRT_MAX
+#define MINIMUM SHRT_MIN
+#define TYPE short
+
+#include "fits_s.h"
diff --git a/mpfr/src/fits_u.h b/mpfr/src/fits_u.h
new file mode 100644
index 0000000000..ab4715f154
--- /dev/null
+++ b/mpfr/src/fits_u.h
@@ -0,0 +1,67 @@
+/* mpfr_fits_*_p -- test whether an mpfr fits a C unsigned type.
+
+Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd)
+{
+ mpfr_exp_t e;
+ int prec;
+ TYPE s;
+ mpfr_t x;
+ int res;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
+ /* Zero always fit */
+ return MPFR_IS_ZERO (f) ? 1 : 0;
+ else if (MPFR_IS_NEG (f))
+ /* Negative numbers don't fit */
+ return 0;
+ /* now it fits if
+ (a) f <= MAXIMUM
+ (b) round(f, prec(slong), rnd) <= MAXIMUM */
+
+ e = MPFR_GET_EXP (f);
+
+ /* first compute prec(MAXIMUM); fits in an int */
+ for (s = MAXIMUM, prec = 0; s != 0; s /= 2, prec ++);
+
+ /* MAXIMUM needs prec bits, i.e. MAXIMUM = 2^prec - 1 */
+
+ /* if e <= prec - 1, then f < 2^(prec-1) < MAXIMUM */
+ if (e <= prec - 1)
+ return 1;
+
+ /* if e >= prec + 1, then f >= 2^prec > MAXIMUM */
+ if (e >= prec + 1)
+ return 0;
+
+ MPFR_ASSERTD (e == prec);
+
+ /* hard case: first round to prec bits, then check */
+ mpfr_init2 (x, prec);
+ mpfr_set (x, f, rnd);
+ res = MPFR_GET_EXP (x) == e;
+ mpfr_clear (x);
+ return res;
+}
diff --git a/mpfr/src/fits_uint.c b/mpfr/src/fits_uint.c
new file mode 100644
index 0000000000..6c6d3bb9b9
--- /dev/null
+++ b/mpfr/src/fits_uint.c
@@ -0,0 +1,27 @@
+/* mpfr_fits_uint_p -- test whether an mpfr fits an unsigned int.
+
+Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define FUNCTION mpfr_fits_uint_p
+#define MAXIMUM UINT_MAX
+#define TYPE unsigned int
+
+#include "fits_u.h"
diff --git a/mpfr/src/fits_uintmax.c b/mpfr/src/fits_uintmax.c
new file mode 100644
index 0000000000..43a9ca98cc
--- /dev/null
+++ b/mpfr/src/fits_uintmax.c
@@ -0,0 +1,77 @@
+/* mpfr_fits_uintmax_p -- test whether an mpfr fits an uintmax_t.
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+#endif
+
+#include "mpfr-intmax.h"
+#include "mpfr-impl.h"
+
+#ifdef _MPFR_H_HAVE_INTMAX_T
+
+/* We can't use fits_u.h <= mpfr_cmp_ui */
+int
+mpfr_fits_uintmax_p (mpfr_srcptr f, mpfr_rnd_t rnd)
+{
+ mpfr_exp_t e;
+ int prec;
+ uintmax_t s;
+ mpfr_t x;
+ int res;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
+ /* Zero always fit */
+ return MPFR_IS_ZERO (f) ? 1 : 0;
+ else if (MPFR_IS_NEG (f))
+ /* Negative numbers don't fit */
+ return 0;
+ /* now it fits if
+ (a) f <= MAXIMUM
+ (b) round(f, prec(slong), rnd) <= MAXIMUM */
+
+ e = MPFR_GET_EXP (f);
+
+ /* first compute prec(MAXIMUM); fits in an int */
+ for (s = MPFR_UINTMAX_MAX, prec = 0; s != 0; s /= 2, prec ++);
+
+ /* MAXIMUM needs prec bits, i.e. MAXIMUM = 2^prec - 1 */
+
+ /* if e <= prec - 1, then f < 2^(prec-1) < MAXIMUM */
+ if (e <= prec - 1)
+ return 1;
+
+ /* if e >= prec + 1, then f >= 2^prec > MAXIMUM */
+ if (e >= prec + 1)
+ return 0;
+
+ MPFR_ASSERTD (e == prec);
+
+ /* hard case: first round to prec bits, then check */
+ mpfr_init2 (x, prec);
+ mpfr_set (x, f, rnd);
+ res = MPFR_GET_EXP (x) == e;
+ mpfr_clear (x);
+ return res;
+}
+
+#endif
diff --git a/mpfr/src/fits_ulong.c b/mpfr/src/fits_ulong.c
new file mode 100644
index 0000000000..d311e7e47b
--- /dev/null
+++ b/mpfr/src/fits_ulong.c
@@ -0,0 +1,27 @@
+/* mpfr_fits_ulong_p -- test whether an mpfr fits an unsigned long.
+
+Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define FUNCTION mpfr_fits_ulong_p
+#define MAXIMUM ULONG_MAX
+#define TYPE unsigned long
+
+#include "fits_u.h"
diff --git a/mpfr/src/fits_ushort.c b/mpfr/src/fits_ushort.c
new file mode 100644
index 0000000000..25c74b12ab
--- /dev/null
+++ b/mpfr/src/fits_ushort.c
@@ -0,0 +1,27 @@
+/* mpfr_fits_ushort_p -- test whether an mpfr fits an unsigned short.
+
+Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define FUNCTION mpfr_fits_ushort_p
+#define MAXIMUM USHRT_MAX
+#define TYPE unsigned short
+
+#include "fits_u.h"
diff --git a/mpfr/src/fma.c b/mpfr/src/fma.c
new file mode 100644
index 0000000000..8454e8d218
--- /dev/null
+++ b/mpfr/src/fma.c
@@ -0,0 +1,302 @@
+/* mpfr_fma -- Floating multiply-add
+
+Copyright 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* The fused-multiply-add (fma) of x, y and z is defined by:
+ fma(x,y,z)= x*y + z
+*/
+
+int
+mpfr_fma (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
+ mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t u;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_GROUP_DECL(group);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg z[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x,
+ mpfr_get_prec (y), mpfr_log_prec, y,
+ mpfr_get_prec (z), mpfr_log_prec, z, rnd_mode),
+ ("s[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (s), mpfr_log_prec, s, inexact));
+
+ /* particular cases */
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(x) ||
+ MPFR_IS_SINGULAR(y) ||
+ MPFR_IS_SINGULAR(z) ))
+ {
+ if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) || MPFR_IS_NAN(z))
+ {
+ MPFR_SET_NAN(s);
+ MPFR_RET_NAN;
+ }
+ /* now neither x, y or z is NaN */
+ else if (MPFR_IS_INF(x) || MPFR_IS_INF(y))
+ {
+ /* cases Inf*0+z, 0*Inf+z, Inf-Inf */
+ if ((MPFR_IS_ZERO(y)) ||
+ (MPFR_IS_ZERO(x)) ||
+ (MPFR_IS_INF(z) &&
+ ((MPFR_MULT_SIGN(MPFR_SIGN(x), MPFR_SIGN(y))) != MPFR_SIGN(z))))
+ {
+ MPFR_SET_NAN(s);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF(z)) /* case Inf-Inf already checked above */
+ {
+ MPFR_SET_INF(s);
+ MPFR_SET_SAME_SIGN(s, z);
+ MPFR_RET(0);
+ }
+ else /* z is finite */
+ {
+ MPFR_SET_INF(s);
+ MPFR_SET_SIGN(s, MPFR_MULT_SIGN(MPFR_SIGN(x) , MPFR_SIGN(y)));
+ MPFR_RET(0);
+ }
+ }
+ /* now x and y are finite */
+ else if (MPFR_IS_INF(z))
+ {
+ MPFR_SET_INF(s);
+ MPFR_SET_SAME_SIGN(s, z);
+ MPFR_RET(0);
+ }
+ else if (MPFR_IS_ZERO(x) || MPFR_IS_ZERO(y))
+ {
+ if (MPFR_IS_ZERO(z))
+ {
+ int sign_p;
+ sign_p = MPFR_MULT_SIGN( MPFR_SIGN(x) , MPFR_SIGN(y) );
+ MPFR_SET_SIGN(s,(rnd_mode != MPFR_RNDD ?
+ ((MPFR_IS_NEG_SIGN(sign_p) && MPFR_IS_NEG(z))
+ ? -1 : 1) :
+ ((MPFR_IS_POS_SIGN(sign_p) && MPFR_IS_POS(z))
+ ? 1 : -1)));
+ MPFR_SET_ZERO(s);
+ MPFR_RET(0);
+ }
+ else
+ return mpfr_set (s, z, rnd_mode);
+ }
+ else /* necessarily z is zero here */
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(z));
+ return mpfr_mul (s, x, y, rnd_mode);
+ }
+ }
+
+ /* If we take prec(u) >= prec(x) + prec(y), the product u <- x*y
+ is exact, except in case of overflow or underflow. */
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_GROUP_INIT_1 (group, MPFR_PREC(x) + MPFR_PREC(y), u);
+
+ if (MPFR_UNLIKELY (mpfr_mul (u, x, y, MPFR_RNDN)))
+ {
+ /* overflow or underflow - this case is regarded as rare, thus
+ does not need to be very efficient (even if some tests below
+ could have been done earlier).
+ It is an overflow iff u is an infinity (since MPFR_RNDN was used).
+ Alternatively, we could test the overflow flag, but in this case,
+ mpfr_clear_flags would have been necessary. */
+ if (MPFR_IS_INF (u)) /* overflow */
+ {
+ /* Let's eliminate the obvious case where x*y and z have the
+ same sign. No possible cancellation -> real overflow.
+ Also, we know that |z| < 2^emax. If E(x) + E(y) >= emax+3,
+ then |x*y| >= 2^(emax+1), and |x*y + z| >= 2^emax. This case
+ is also an overflow. */
+ if (MPFR_SIGN (u) == MPFR_SIGN (z) ||
+ MPFR_GET_EXP (x) + MPFR_GET_EXP (y) >= __gmpfr_emax + 3)
+ {
+ MPFR_GROUP_CLEAR (group);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_overflow (s, rnd_mode, MPFR_SIGN (z));
+ }
+
+ /* E(x) + E(y) <= emax+2, therefore |x*y| < 2^(emax+2), and
+ (x/4)*y does not overflow (let's recall that the result
+ is exact with an unbounded exponent range). It does not
+ underflow either, because x*y overflows and the exponent
+ range is large enough. */
+ inexact = mpfr_div_2ui (u, x, 2, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ inexact = mpfr_mul (u, u, y, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+
+ /* Now, we need to add z/4... But it may underflow! */
+ {
+ mpfr_t zo4;
+ mpfr_srcptr zz;
+ MPFR_BLOCK_DECL (flags);
+
+ if (MPFR_GET_EXP (u) > MPFR_GET_EXP (z) &&
+ MPFR_GET_EXP (u) - MPFR_GET_EXP (z) > MPFR_PREC (u))
+ {
+ /* |z| < ulp(u)/2, therefore one can use z instead of z/4. */
+ zz = z;
+ }
+ else
+ {
+ mpfr_init2 (zo4, MPFR_PREC (z));
+ if (mpfr_div_2ui (zo4, z, 2, MPFR_RNDZ))
+ {
+ /* The division by 4 underflowed! */
+ MPFR_ASSERTN (0); /* TODO... */
+ }
+ zz = zo4;
+ }
+
+ /* Let's recall that u = x*y/4 and zz = z/4 (or z if the
+ following addition would give the same result). */
+ MPFR_BLOCK (flags, inexact = mpfr_add (s, u, zz, rnd_mode));
+ /* u and zz have different signs, so that an overflow
+ is not possible. But an underflow is theoretically
+ possible! */
+ if (MPFR_UNDERFLOW (flags))
+ {
+ MPFR_ASSERTN (zz != z);
+ MPFR_ASSERTN (0); /* TODO... */
+ mpfr_clears (zo4, u, (mpfr_ptr) 0);
+ }
+ else
+ {
+ int inex2;
+
+ if (zz != z)
+ mpfr_clear (zo4);
+ MPFR_GROUP_CLEAR (group);
+ MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
+ inex2 = mpfr_mul_2ui (s, s, 2, rnd_mode);
+ if (inex2) /* overflow */
+ {
+ inexact = inex2;
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ }
+ goto end;
+ }
+ }
+ }
+ else /* underflow: one has |xy| < 2^(emin-1). */
+ {
+ unsigned long scale = 0;
+ mpfr_t scaled_z;
+ mpfr_srcptr new_z;
+ mpfr_exp_t diffexp;
+ mpfr_prec_t pzs;
+ int xy_underflows;
+
+ /* Let's scale z so that ulp(z) > 2^emin and ulp(s) > 2^emin
+ (the + 1 on MPFR_PREC (s) is necessary because the exponent
+ of the result can be EXP(z) - 1). */
+ diffexp = MPFR_GET_EXP (z) - __gmpfr_emin;
+ pzs = MAX (MPFR_PREC (z), MPFR_PREC (s) + 1);
+ if (diffexp <= pzs)
+ {
+ mpfr_uexp_t uscale;
+ mpfr_t scaled_v;
+ MPFR_BLOCK_DECL (flags);
+
+ uscale = (mpfr_uexp_t) pzs - diffexp + 1;
+ MPFR_ASSERTN (uscale > 0);
+ MPFR_ASSERTN (uscale <= ULONG_MAX);
+ scale = uscale;
+ mpfr_init2 (scaled_z, MPFR_PREC (z));
+ inexact = mpfr_mul_2ui (scaled_z, z, scale, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0); /* TODO: overflow case */
+ new_z = scaled_z;
+ /* Now we need to recompute u = xy * 2^scale. */
+ MPFR_BLOCK (flags,
+ if (MPFR_GET_EXP (x) < MPFR_GET_EXP (y))
+ {
+ mpfr_init2 (scaled_v, MPFR_PREC (x));
+ mpfr_mul_2ui (scaled_v, x, scale, MPFR_RNDN);
+ mpfr_mul (u, scaled_v, y, MPFR_RNDN);
+ }
+ else
+ {
+ mpfr_init2 (scaled_v, MPFR_PREC (y));
+ mpfr_mul_2ui (scaled_v, y, scale, MPFR_RNDN);
+ mpfr_mul (u, x, scaled_v, MPFR_RNDN);
+ });
+ mpfr_clear (scaled_v);
+ MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
+ xy_underflows = MPFR_UNDERFLOW (flags);
+ }
+ else
+ {
+ new_z = z;
+ xy_underflows = 1;
+ }
+
+ if (xy_underflows)
+ {
+ /* Let's replace xy by sign(xy) * 2^(emin-1). */
+ MPFR_PREC (u) = MPFR_PREC_MIN;
+ mpfr_setmin (u, __gmpfr_emin);
+ MPFR_SET_SIGN (u, MPFR_MULT_SIGN (MPFR_SIGN (x),
+ MPFR_SIGN (y)));
+ }
+
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_BLOCK (flags, inexact = mpfr_add (s, u, new_z, rnd_mode));
+ MPFR_GROUP_CLEAR (group);
+ if (scale != 0)
+ {
+ int inex2;
+
+ mpfr_clear (scaled_z);
+ /* Here an overflow is theoretically possible, in which case
+ the result may be wrong, hence the assert. An underflow
+ is not possible, but let's check that anyway. */
+ MPFR_ASSERTN (! MPFR_OVERFLOW (flags)); /* TODO... */
+ MPFR_ASSERTN (! MPFR_UNDERFLOW (flags)); /* not possible */
+ inex2 = mpfr_div_2ui (s, s, scale, MPFR_RNDN);
+ /* FIXME: this seems incorrect. MPFR_RNDN -> rnd_mode?
+ Also, handle the double rounding case:
+ s / 2^scale = 2^(emin - 2) in MPFR_RNDN. */
+ if (inex2) /* underflow */
+ inexact = inex2;
+ }
+ }
+
+ /* FIXME/TODO: I'm not sure that the following is correct.
+ Check for possible spurious exceptions due to intermediate
+ computations. */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ goto end;
+ }
+ }
+
+ inexact = mpfr_add (s, u, z, rnd_mode);
+ MPFR_GROUP_CLEAR (group);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (s, inexact, rnd_mode);
+}
diff --git a/mpfr/src/fms.c b/mpfr/src/fms.c
new file mode 100644
index 0000000000..2c0fd53f43
--- /dev/null
+++ b/mpfr/src/fms.c
@@ -0,0 +1,304 @@
+/* mpfr_fms -- Floating multiply-subtract
+
+Copyright 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* The fused-multiply-subtract (fms) of x, y and z is defined by:
+ fms(x,y,z)= x*y - z
+ Note: this is neither in IEEE754R, nor in LIA-2, but both the
+ PowerPC and the Itanium define fms as x*y - z.
+*/
+
+int
+mpfr_fms (mpfr_ptr s, mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z,
+ mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t u;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_GROUP_DECL(group);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg z[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x,
+ mpfr_get_prec (y), mpfr_log_prec, y,
+ mpfr_get_prec (z), mpfr_log_prec, z, rnd_mode),
+ ("s[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (s), mpfr_log_prec, s, inexact));
+
+ /* particular cases */
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(x) ||
+ MPFR_IS_SINGULAR(y) ||
+ MPFR_IS_SINGULAR(z) ))
+ {
+ if (MPFR_IS_NAN(x) || MPFR_IS_NAN(y) || MPFR_IS_NAN(z))
+ {
+ MPFR_SET_NAN(s);
+ MPFR_RET_NAN;
+ }
+ /* now neither x, y or z is NaN */
+ else if (MPFR_IS_INF(x) || MPFR_IS_INF(y))
+ {
+ /* cases Inf*0-z, 0*Inf-z, Inf-Inf */
+ if ((MPFR_IS_ZERO(y)) ||
+ (MPFR_IS_ZERO(x)) ||
+ (MPFR_IS_INF(z) &&
+ ((MPFR_MULT_SIGN(MPFR_SIGN(x), MPFR_SIGN(y))) == MPFR_SIGN(z))))
+ {
+ MPFR_SET_NAN(s);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF(z)) /* case Inf-Inf already checked above */
+ {
+ MPFR_SET_INF(s);
+ MPFR_SET_OPPOSITE_SIGN(s, z);
+ MPFR_RET(0);
+ }
+ else /* z is finite */
+ {
+ MPFR_SET_INF(s);
+ MPFR_SET_SIGN(s, MPFR_MULT_SIGN(MPFR_SIGN(x) , MPFR_SIGN(y)));
+ MPFR_RET(0);
+ }
+ }
+ /* now x and y are finite */
+ else if (MPFR_IS_INF(z))
+ {
+ MPFR_SET_INF(s);
+ MPFR_SET_OPPOSITE_SIGN(s, z);
+ MPFR_RET(0);
+ }
+ else if (MPFR_IS_ZERO(x) || MPFR_IS_ZERO(y))
+ {
+ if (MPFR_IS_ZERO(z))
+ {
+ int sign_p;
+ sign_p = MPFR_MULT_SIGN( MPFR_SIGN(x) , MPFR_SIGN(y) );
+ MPFR_SET_SIGN(s,(rnd_mode != MPFR_RNDD ?
+ ((MPFR_IS_NEG_SIGN(sign_p) && MPFR_IS_POS(z))
+ ? -1 : 1) :
+ ((MPFR_IS_POS_SIGN(sign_p) && MPFR_IS_NEG(z))
+ ? 1 : -1)));
+ MPFR_SET_ZERO(s);
+ MPFR_RET(0);
+ }
+ else
+ return mpfr_neg (s, z, rnd_mode);
+ }
+ else /* necessarily z is zero here */
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(z));
+ return mpfr_mul (s, x, y, rnd_mode);
+ }
+ }
+
+ /* If we take prec(u) >= prec(x) + prec(y), the product u <- x*y
+ is exact, except in case of overflow or underflow. */
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_GROUP_INIT_1 (group, MPFR_PREC(x) + MPFR_PREC(y), u);
+
+ if (MPFR_UNLIKELY (mpfr_mul (u, x, y, MPFR_RNDN)))
+ {
+ /* overflow or underflow - this case is regarded as rare, thus
+ does not need to be very efficient (even if some tests below
+ could have been done earlier).
+ It is an overflow iff u is an infinity (since MPFR_RNDN was used).
+ Alternatively, we could test the overflow flag, but in this case,
+ mpfr_clear_flags would have been necessary. */
+ if (MPFR_IS_INF (u)) /* overflow */
+ {
+ /* Let's eliminate the obvious case where x*y and z have the
+ same sign. No possible cancellation -> real overflow.
+ Also, we know that |z| < 2^emax. If E(x) + E(y) >= emax+3,
+ then |x*y| >= 2^(emax+1), and |x*y - z| >= 2^emax. This case
+ is also an overflow. */
+ if (MPFR_SIGN (u) != MPFR_SIGN (z) ||
+ MPFR_GET_EXP (x) + MPFR_GET_EXP (y) >= __gmpfr_emax + 3)
+ {
+ MPFR_GROUP_CLEAR (group);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_overflow (s, rnd_mode, - MPFR_SIGN (z));
+ }
+
+ /* E(x) + E(y) <= emax+2, therefore |x*y| < 2^(emax+2), and
+ (x/4)*y does not overflow (let's recall that the result
+ is exact with an unbounded exponent range). It does not
+ underflow either, because x*y overflows and the exponent
+ range is large enough. */
+ inexact = mpfr_div_2ui (u, x, 2, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ inexact = mpfr_mul (u, u, y, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+
+ /* Now, we need to subtract z/4... But it may underflow! */
+ {
+ mpfr_t zo4;
+ mpfr_srcptr zz;
+ MPFR_BLOCK_DECL (flags);
+
+ if (MPFR_GET_EXP (u) > MPFR_GET_EXP (z) &&
+ MPFR_GET_EXP (u) - MPFR_GET_EXP (z) > MPFR_PREC (u))
+ {
+ /* |z| < ulp(u)/2, therefore one can use z instead of z/4. */
+ zz = z;
+ }
+ else
+ {
+ mpfr_init2 (zo4, MPFR_PREC (z));
+ if (mpfr_div_2ui (zo4, z, 2, MPFR_RNDZ))
+ {
+ /* The division by 4 underflowed! */
+ MPFR_ASSERTN (0); /* TODO... */
+ }
+ zz = zo4;
+ }
+
+ /* Let's recall that u = x*y/4 and zz = z/4 (or z if the
+ following subtraction would give the same result). */
+ MPFR_BLOCK (flags, inexact = mpfr_sub (s, u, zz, rnd_mode));
+ /* u and zz have the same sign, so that an overflow
+ is not possible. But an underflow is theoretically
+ possible! */
+ if (MPFR_UNDERFLOW (flags))
+ {
+ MPFR_ASSERTN (zz != z);
+ MPFR_ASSERTN (0); /* TODO... */
+ mpfr_clears (zo4, u, (mpfr_ptr) 0);
+ }
+ else
+ {
+ int inex2;
+
+ if (zz != z)
+ mpfr_clear (zo4);
+ MPFR_GROUP_CLEAR (group);
+ MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
+ inex2 = mpfr_mul_2ui (s, s, 2, rnd_mode);
+ if (inex2) /* overflow */
+ {
+ inexact = inex2;
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ }
+ goto end;
+ }
+ }
+ }
+ else /* underflow: one has |xy| < 2^(emin-1). */
+ {
+ unsigned long scale = 0;
+ mpfr_t scaled_z;
+ mpfr_srcptr new_z;
+ mpfr_exp_t diffexp;
+ mpfr_prec_t pzs;
+ int xy_underflows;
+
+ /* Let's scale z so that ulp(z) > 2^emin and ulp(s) > 2^emin
+ (the + 1 on MPFR_PREC (s) is necessary because the exponent
+ of the result can be EXP(z) - 1). */
+ diffexp = MPFR_GET_EXP (z) - __gmpfr_emin;
+ pzs = MAX (MPFR_PREC (z), MPFR_PREC (s) + 1);
+ if (diffexp <= pzs)
+ {
+ mpfr_uexp_t uscale;
+ mpfr_t scaled_v;
+ MPFR_BLOCK_DECL (flags);
+
+ uscale = (mpfr_uexp_t) pzs - diffexp + 1;
+ MPFR_ASSERTN (uscale > 0);
+ MPFR_ASSERTN (uscale <= ULONG_MAX);
+ scale = uscale;
+ mpfr_init2 (scaled_z, MPFR_PREC (z));
+ inexact = mpfr_mul_2ui (scaled_z, z, scale, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0); /* TODO: overflow case */
+ new_z = scaled_z;
+ /* Now we need to recompute u = xy * 2^scale. */
+ MPFR_BLOCK (flags,
+ if (MPFR_GET_EXP (x) < MPFR_GET_EXP (y))
+ {
+ mpfr_init2 (scaled_v, MPFR_PREC (x));
+ mpfr_mul_2ui (scaled_v, x, scale, MPFR_RNDN);
+ mpfr_mul (u, scaled_v, y, MPFR_RNDN);
+ }
+ else
+ {
+ mpfr_init2 (scaled_v, MPFR_PREC (y));
+ mpfr_mul_2ui (scaled_v, y, scale, MPFR_RNDN);
+ mpfr_mul (u, x, scaled_v, MPFR_RNDN);
+ });
+ mpfr_clear (scaled_v);
+ MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
+ xy_underflows = MPFR_UNDERFLOW (flags);
+ }
+ else
+ {
+ new_z = z;
+ xy_underflows = 1;
+ }
+
+ if (xy_underflows)
+ {
+ /* Let's replace xy by sign(xy) * 2^(emin-1). */
+ MPFR_PREC (u) = MPFR_PREC_MIN;
+ mpfr_setmin (u, __gmpfr_emin);
+ MPFR_SET_SIGN (u, MPFR_MULT_SIGN (MPFR_SIGN (x),
+ MPFR_SIGN (y)));
+ }
+
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_BLOCK (flags, inexact = mpfr_sub (s, u, new_z, rnd_mode));
+ MPFR_GROUP_CLEAR (group);
+ if (scale != 0)
+ {
+ int inex2;
+
+ mpfr_clear (scaled_z);
+ /* Here an overflow is theoretically possible, in which case
+ the result may be wrong, hence the assert. An underflow
+ is not possible, but let's check that anyway. */
+ MPFR_ASSERTN (! MPFR_OVERFLOW (flags)); /* TODO... */
+ MPFR_ASSERTN (! MPFR_UNDERFLOW (flags)); /* not possible */
+ inex2 = mpfr_div_2ui (s, s, scale, MPFR_RNDN);
+ /* FIXME: this seems incorrect. MPFR_RNDN -> rnd_mode?
+ Also, handle the double rounding case:
+ s / 2^scale = 2^(emin - 2) in MPFR_RNDN. */
+ if (inex2) /* underflow */
+ inexact = inex2;
+ }
+ }
+
+ /* FIXME/TODO: I'm not sure that the following is correct.
+ Check for possible spurious exceptions due to intermediate
+ computations. */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ goto end;
+ }
+ }
+
+ inexact = mpfr_sub (s, u, z, rnd_mode);
+ MPFR_GROUP_CLEAR (group);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (s, inexact, rnd_mode);
+}
diff --git a/mpfr/src/frac.c b/mpfr/src/frac.c
new file mode 100644
index 0000000000..b857e3a883
--- /dev/null
+++ b/mpfr/src/frac.c
@@ -0,0 +1,144 @@
+/* mpfr_frac -- Fractional part of a floating-point number.
+
+Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Optimization note: it is not a good idea to call mpfr_integer_p,
+ as some cases will take longer (the number may be parsed twice). */
+
+int
+mpfr_frac (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ mpfr_exp_t re, ue;
+ mpfr_prec_t uq;
+ mp_size_t un, tn, t0;
+ mp_limb_t *up, *tp, k;
+ int sh;
+ mpfr_t tmp;
+ mpfr_ptr t;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* Special cases */
+ if (MPFR_UNLIKELY(MPFR_IS_NAN(u)))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_UNLIKELY(MPFR_IS_INF(u) || mpfr_integer_p (u)))
+ {
+ MPFR_SET_SAME_SIGN(r, u);
+ MPFR_SET_ZERO(r);
+ MPFR_RET(0); /* zero is exact */
+ }
+
+ ue = MPFR_GET_EXP (u);
+ if (ue <= 0) /* |u| < 1 */
+ return mpfr_set (r, u, rnd_mode);
+
+ /* Now |u| >= 1, meaning that an overflow is not possible. */
+
+ uq = MPFR_PREC(u);
+ un = (uq - 1) / GMP_NUMB_BITS; /* index of most significant limb */
+ un -= (mp_size_t) (ue / GMP_NUMB_BITS);
+ /* now the index of the MSL containing bits of the fractional part */
+
+ up = MPFR_MANT(u);
+ sh = ue % GMP_NUMB_BITS;
+ k = up[un] << sh;
+ /* the first bit of the fractional part is the MSB of k */
+
+ if (k != 0)
+ {
+ int cnt;
+
+ count_leading_zeros(cnt, k);
+ /* first bit 1 of the fractional part -> MSB of the number */
+ re = -cnt;
+ sh += cnt;
+ MPFR_ASSERTN (sh < GMP_NUMB_BITS);
+ k <<= cnt;
+ }
+ else
+ {
+ re = sh - GMP_NUMB_BITS;
+ /* searching for the first bit 1 (exists since u isn't an integer) */
+ while (up[--un] == 0)
+ re -= GMP_NUMB_BITS;
+ MPFR_ASSERTN(un >= 0);
+ k = up[un];
+ count_leading_zeros(sh, k);
+ re -= sh;
+ k <<= sh;
+ }
+ /* The exponent of r will be re */
+ /* un: index of the limb of u that contains the first bit 1 of the FP */
+
+ t = (mp_size_t) (MPFR_PREC(r) - 1) / GMP_NUMB_BITS < un ?
+ (mpfr_init2 (tmp, (un + 1) * GMP_NUMB_BITS), tmp) : r;
+ /* t has enough precision to contain the fractional part of u */
+ /* If we use a temporary variable, we take the non-significant bits
+ of u into account, because of the mpn_lshift below. */
+ MPFR_SET_SAME_SIGN(t, u);
+
+ /* Put the fractional part of u into t */
+ tn = (MPFR_PREC(t) - 1) / GMP_NUMB_BITS;
+ MPFR_ASSERTN(tn >= un);
+ t0 = tn - un;
+ tp = MPFR_MANT(t);
+ if (sh == 0)
+ MPN_COPY_DECR(tp + t0, up, un + 1);
+ else /* warning: un may be 0 here */
+ tp[tn] = k | ((un) ? mpn_lshift (tp + t0, up, un, sh) : (mp_limb_t) 0);
+ if (t0 > 0)
+ MPN_ZERO(tp, t0);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ if (t != r)
+ { /* t is tmp */
+ MPFR_EXP (t) = 0; /* should be re, but not necessarily in the range */
+ inex = mpfr_set (r, t, rnd_mode); /* no underflow */
+ mpfr_clear (t);
+ MPFR_EXP (r) += re;
+ }
+ else
+ { /* There may be remaining non-significant bits in t (= r). */
+ int carry;
+
+ MPFR_EXP (r) = re;
+ carry = mpfr_round_raw (tp, tp,
+ (mpfr_prec_t) (tn + 1) * GMP_NUMB_BITS,
+ MPFR_IS_NEG (r), MPFR_PREC (r), rnd_mode,
+ &inex);
+ if (carry)
+ {
+ tp[tn] = MPFR_LIMB_HIGHBIT;
+ MPFR_EXP (r) ++;
+ }
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inex, rnd_mode);
+}
diff --git a/mpfr/src/free_cache.c b/mpfr/src/free_cache.c
new file mode 100644
index 0000000000..990f9999b1
--- /dev/null
+++ b/mpfr/src/free_cache.c
@@ -0,0 +1,59 @@
+/* mpfr_free_cache - Free the cache used by MPFR for internal consts.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#if 0
+static void
+free_l2b (void)
+{
+ int i, b;
+
+ for (b = 2; b <= BASE_MAX; b++)
+ for (i = 0; i < 2; i++)
+ {
+ mpfr_ptr p = __gmpfr_l2b[b-2][i];
+ if (p != NULL)
+ {
+ mpfr_clear (p);
+ (*__gmp_free_func) (p, sizeof (mpfr_t));
+ }
+ }
+}
+#endif
+
+void
+mpfr_free_cache (void)
+{
+#ifndef MPFR_USE_LOGGING
+ mpfr_clear_cache (__gmpfr_cache_const_pi);
+ mpfr_clear_cache (__gmpfr_cache_const_log2);
+#else
+ mpfr_clear_cache (__gmpfr_normal_pi);
+ mpfr_clear_cache (__gmpfr_normal_log2);
+ mpfr_clear_cache (__gmpfr_logging_pi);
+ mpfr_clear_cache (__gmpfr_logging_log2);
+#endif
+ mpfr_clear_cache (__gmpfr_cache_const_euler);
+ mpfr_clear_cache (__gmpfr_cache_const_catalan);
+ /* free_l2b (); */
+}
diff --git a/mpfr/src/frexp.c b/mpfr/src/frexp.c
new file mode 100644
index 0000000000..0aea130df6
--- /dev/null
+++ b/mpfr/src/frexp.c
@@ -0,0 +1,56 @@
+/* mpfr_frexp -- convert to integral and fractional parts
+
+Copyright 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_frexp (mpfr_exp_t *exp, mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ int inex;
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
+ {
+ if (MPFR_IS_NAN(x))
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN; /* exp is unspecified */
+ }
+ else if (MPFR_IS_INF(x))
+ {
+ MPFR_SET_INF(y);
+ MPFR_SET_SAME_SIGN(y,x);
+ MPFR_RET(0); /* exp is unspecified */
+ }
+ else
+ {
+ MPFR_SET_ZERO(y);
+ MPFR_SET_SAME_SIGN(y,x);
+ *exp = 0;
+ MPFR_RET(0);
+ }
+ }
+
+ inex = mpfr_set (y, x, rnd);
+ *exp = MPFR_GET_EXP (y);
+ MPFR_SET_EXP (y, 0);
+ return mpfr_check_range (y, inex, rnd);
+}
diff --git a/mpfr/src/gamma.c b/mpfr/src/gamma.c
new file mode 100644
index 0000000000..dbfacec103
--- /dev/null
+++ b/mpfr/src/gamma.c
@@ -0,0 +1,439 @@
+/* mpfr_gamma -- gamma function
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#define IS_GAMMA
+#include "lngamma.c"
+#undef IS_GAMMA
+
+/* return a sufficient precision such that 2-x is exact, assuming x < 0 */
+static mpfr_prec_t
+mpfr_gamma_2_minus_x_exact (mpfr_srcptr x)
+{
+ /* Since x < 0, 2-x = 2+y with y := -x.
+ If y < 2, a precision w >= PREC(y) + EXP(2)-EXP(y) = PREC(y) + 2 - EXP(y)
+ is enough, since no overlap occurs in 2+y, so no carry happens.
+ If y >= 2, either ULP(y) <= 2, and we need w >= PREC(y)+1 since a
+ carry can occur, or ULP(y) > 2, and we need w >= EXP(y)-1:
+ (a) if EXP(y) <= 1, w = PREC(y) + 2 - EXP(y)
+ (b) if EXP(y) > 1 and EXP(y)-PREC(y) <= 1, w = PREC(y) + 1
+ (c) if EXP(y) > 1 and EXP(y)-PREC(y) > 1, w = EXP(y) - 1 */
+ return (MPFR_GET_EXP(x) <= 1) ? MPFR_PREC(x) + 2 - MPFR_GET_EXP(x)
+ : ((MPFR_GET_EXP(x) <= MPFR_PREC(x) + 1) ? MPFR_PREC(x) + 1
+ : MPFR_GET_EXP(x) - 1);
+}
+
+/* return a sufficient precision such that 1-x is exact, assuming x < 1 */
+static mpfr_prec_t
+mpfr_gamma_1_minus_x_exact (mpfr_srcptr x)
+{
+ if (MPFR_IS_POS(x))
+ return MPFR_PREC(x) - MPFR_GET_EXP(x);
+ else if (MPFR_GET_EXP(x) <= 0)
+ return MPFR_PREC(x) + 1 - MPFR_GET_EXP(x);
+ else if (MPFR_PREC(x) >= MPFR_GET_EXP(x))
+ return MPFR_PREC(x) + 1;
+ else
+ return MPFR_GET_EXP(x);
+}
+
+/* returns a lower bound of the number of significant bits of n!
+ (not counting the low zero bits).
+ We know n! >= (n/e)^n*sqrt(2*Pi*n) for n >= 1, and the number of zero bits
+ is floor(n/2) + floor(n/4) + floor(n/8) + ...
+ This approximation is exact for n <= 500000, except for n = 219536, 235928,
+ 298981, 355854, 464848, 493725, 498992 where it returns a value 1 too small.
+*/
+static unsigned long
+bits_fac (unsigned long n)
+{
+ mpfr_t x, y;
+ unsigned long r, k;
+ mpfr_init2 (x, 38);
+ mpfr_init2 (y, 38);
+ mpfr_set_ui (x, n, MPFR_RNDZ);
+ mpfr_set_str_binary (y, "10.101101111110000101010001011000101001"); /* upper bound of e */
+ mpfr_div (x, x, y, MPFR_RNDZ);
+ mpfr_pow_ui (x, x, n, MPFR_RNDZ);
+ mpfr_const_pi (y, MPFR_RNDZ);
+ mpfr_mul_ui (y, y, 2 * n, MPFR_RNDZ);
+ mpfr_sqrt (y, y, MPFR_RNDZ);
+ mpfr_mul (x, x, y, MPFR_RNDZ);
+ mpfr_log2 (x, x, MPFR_RNDZ);
+ r = mpfr_get_ui (x, MPFR_RNDU);
+ for (k = 2; k <= n; k *= 2)
+ r -= n / k;
+ mpfr_clear (x);
+ mpfr_clear (y);
+ return r;
+}
+
+/* We use the reflection formula
+ Gamma(1+t) Gamma(1-t) = - Pi t / sin(Pi (1 + t))
+ in order to treat the case x <= 1,
+ i.e. with x = 1-t, then Gamma(x) = -Pi*(1-x)/sin(Pi*(2-x))/GAMMA(2-x)
+*/
+int
+mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xp, GammaTrial, tmp, tmp2;
+ mpz_t fact;
+ mpfr_prec_t realprec;
+ int compared, is_integer;
+ int inex = 0; /* 0 means: result gamma not set yet */
+ MPFR_GROUP_DECL (group);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("gamma[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (gamma), mpfr_log_prec, gamma, inex));
+
+ /* Trivial cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (gamma);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ if (MPFR_IS_NEG (x))
+ {
+ MPFR_SET_NAN (gamma);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ MPFR_SET_INF (gamma);
+ MPFR_SET_POS (gamma);
+ MPFR_RET (0); /* exact */
+ }
+ }
+ else /* x is zero */
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(x));
+ MPFR_SET_INF(gamma);
+ MPFR_SET_SAME_SIGN(gamma, x);
+ mpfr_set_divby0 ();
+ MPFR_RET (0); /* exact */
+ }
+ }
+
+ /* Check for tiny arguments, where gamma(x) ~ 1/x - euler + ....
+ We know from "Bound on Runs of Zeros and Ones for Algebraic Functions",
+ Proceedings of Arith15, T. Lang and J.-M. Muller, 2001, that the maximal
+ number of consecutive zeroes or ones after the round bit is n-1 for an
+ input of n bits. But we need a more precise lower bound. Assume x has
+ n bits, and 1/x is near a floating-point number y of n+1 bits. We can
+ write x = X*2^e, y = Y/2^f with X, Y integers of n and n+1 bits.
+ Thus X*Y^2^(e-f) is near from 1, i.e., X*Y is near from 2^(f-e).
+ Two cases can happen:
+ (i) either X*Y is exactly 2^(f-e), but this can happen only if X and Y
+ are themselves powers of two, i.e., x is a power of two;
+ (ii) or X*Y is at distance at least one from 2^(f-e), thus
+ |xy-1| >= 2^(e-f), or |y-1/x| >= 2^(e-f)/x = 2^(-f)/X >= 2^(-f-n).
+ Since ufp(y) = 2^(n-f) [ufp = unit in first place], this means
+ that the distance |y-1/x| >= 2^(-2n) ufp(y).
+ Now assuming |gamma(x)-1/x| <= 1, which is true for x <= 1,
+ if 2^(-2n) ufp(y) >= 2, the error is at most 2^(-2n-1) ufp(y),
+ and round(1/x) with precision >= 2n+2 gives the correct result.
+ If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
+ A sufficient condition is thus EXP(x) + 2 <= -2 MAX(PREC(x),PREC(Y)).
+ */
+ if (MPFR_GET_EXP (x) + 2
+ <= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(gamma)))
+ {
+ int sign = MPFR_SIGN (x); /* retrieve sign before possible override */
+ int special;
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* for overflow cases, see below; this needs to be done
+ before x possibly gets overridden. */
+ special =
+ MPFR_GET_EXP (x) == 1 - MPFR_EMAX_MAX &&
+ MPFR_IS_POS_SIGN (sign) &&
+ MPFR_IS_LIKE_RNDD (rnd_mode, sign) &&
+ mpfr_powerof2_raw (x);
+
+ MPFR_BLOCK (flags, inex = mpfr_ui_div (gamma, 1, x, rnd_mode));
+ if (inex == 0) /* x is a power of two */
+ {
+ /* return RND(1/x - euler) = RND(+/- 2^k - eps) with eps > 0 */
+ if (rnd_mode == MPFR_RNDN || MPFR_IS_LIKE_RNDU (rnd_mode, sign))
+ inex = 1;
+ else
+ {
+ mpfr_nextbelow (gamma);
+ inex = -1;
+ }
+ }
+ else if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags)))
+ {
+ /* Overflow in the division 1/x. This is a real overflow, except
+ in RNDZ or RNDD when 1/x = 2^emax, i.e. x = 2^(-emax): due to
+ the "- euler", the rounded value in unbounded exponent range
+ is 0.111...11 * 2^emax (not an overflow). */
+ if (!special)
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, flags);
+ }
+ MPFR_SAVE_EXPO_FREE (expo);
+ /* Note: an overflow is possible with an infinite result;
+ in this case, the overflow flag will automatically be
+ restored by mpfr_check_range. */
+ return mpfr_check_range (gamma, inex, rnd_mode);
+ }
+
+ is_integer = mpfr_integer_p (x);
+ /* gamma(x) for x a negative integer gives NaN */
+ if (is_integer && MPFR_IS_NEG(x))
+ {
+ MPFR_SET_NAN (gamma);
+ MPFR_RET_NAN;
+ }
+
+ compared = mpfr_cmp_ui (x, 1);
+ if (compared == 0)
+ return mpfr_set_ui (gamma, 1, rnd_mode);
+
+ /* if x is an integer that fits into an unsigned long, use mpfr_fac_ui
+ if argument is not too large.
+ If precision is p, fac_ui costs O(u*p), whereas gamma costs O(p*M(p)),
+ so for u <= M(p), fac_ui should be faster.
+ We approximate here M(p) by p*log(p)^2, which is not a bad guess.
+ Warning: since the generic code does not handle exact cases,
+ we want all cases where gamma(x) is exact to be treated here.
+ */
+ if (is_integer && mpfr_fits_ulong_p (x, MPFR_RNDN))
+ {
+ unsigned long int u;
+ mpfr_prec_t p = MPFR_PREC(gamma);
+ u = mpfr_get_ui (x, MPFR_RNDN);
+ if (u < 44787929UL && bits_fac (u - 1) <= p + (rnd_mode == MPFR_RNDN))
+ /* bits_fac: lower bound on the number of bits of m,
+ where gamma(x) = (u-1)! = m*2^e with m odd. */
+ return mpfr_fac_ui (gamma, u - 1, rnd_mode);
+ /* if bits_fac(...) > p (resp. p+1 for rounding to nearest),
+ then gamma(x) cannot be exact in precision p (resp. p+1).
+ FIXME: remove the test u < 44787929UL after changing bits_fac
+ to return a mpz_t or mpfr_t. */
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* check for overflow: according to (6.1.37) in Abramowitz & Stegun,
+ gamma(x) >= exp(-x) * x^(x-1/2) * sqrt(2*Pi)
+ >= 2 * (x/e)^x / x for x >= 1 */
+ if (compared > 0)
+ {
+ mpfr_t yp;
+ mpfr_exp_t expxp;
+ MPFR_BLOCK_DECL (flags);
+
+ /* 1/e rounded down to 53 bits */
+#define EXPM1_STR "0.010111100010110101011000110110001011001110111100111"
+ mpfr_init2 (xp, 53);
+ mpfr_init2 (yp, 53);
+ mpfr_set_str_binary (xp, EXPM1_STR);
+ mpfr_mul (xp, x, xp, MPFR_RNDZ);
+ mpfr_sub_ui (yp, x, 2, MPFR_RNDZ);
+ mpfr_pow (xp, xp, yp, MPFR_RNDZ); /* (x/e)^(x-2) */
+ mpfr_set_str_binary (yp, EXPM1_STR);
+ mpfr_mul (xp, xp, yp, MPFR_RNDZ); /* x^(x-2) / e^(x-1) */
+ mpfr_mul (xp, xp, yp, MPFR_RNDZ); /* x^(x-2) / e^x */
+ mpfr_mul (xp, xp, x, MPFR_RNDZ); /* lower bound on x^(x-1) / e^x */
+ MPFR_BLOCK (flags, mpfr_mul_2ui (xp, xp, 1, MPFR_RNDZ));
+ expxp = MPFR_GET_EXP (xp);
+ mpfr_clear (xp);
+ mpfr_clear (yp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return MPFR_OVERFLOW (flags) || expxp > __gmpfr_emax ?
+ mpfr_overflow (gamma, rnd_mode, 1) :
+ mpfr_gamma_aux (gamma, x, rnd_mode);
+ }
+
+ /* now compared < 0 */
+
+ /* check for underflow: for x < 1,
+ gamma(x) = Pi*(x-1)/sin(Pi*(2-x))/gamma(2-x).
+ Since gamma(2-x) >= 2 * ((2-x)/e)^(2-x) / (2-x), we have
+ |gamma(x)| <= Pi*(1-x)*(2-x)/2/((2-x)/e)^(2-x) / |sin(Pi*(2-x))|
+ <= 12 * ((2-x)/e)^x / |sin(Pi*(2-x))|.
+ To avoid an underflow in ((2-x)/e)^x, we compute the logarithm.
+ */
+ if (MPFR_IS_NEG(x))
+ {
+ int underflow = 0, sgn, ck;
+ mpfr_prec_t w;
+
+ mpfr_init2 (xp, 53);
+ mpfr_init2 (tmp, 53);
+ mpfr_init2 (tmp2, 53);
+ /* we want an upper bound for x * [log(2-x)-1].
+ since x < 0, we need a lower bound on log(2-x) */
+ mpfr_ui_sub (xp, 2, x, MPFR_RNDD);
+ mpfr_log (xp, xp, MPFR_RNDD);
+ mpfr_sub_ui (xp, xp, 1, MPFR_RNDD);
+ mpfr_mul (xp, xp, x, MPFR_RNDU);
+
+ /* we need an upper bound on 1/|sin(Pi*(2-x))|,
+ thus a lower bound on |sin(Pi*(2-x))|.
+ If 2-x is exact, then the error of Pi*(2-x) is (1+u)^2 with u = 2^(-p)
+ thus the error on sin(Pi*(2-x)) is less than 1/2ulp + 3Pi(2-x)u,
+ assuming u <= 1, thus <= u + 3Pi(2-x)u */
+
+ w = mpfr_gamma_2_minus_x_exact (x); /* 2-x is exact for prec >= w */
+ w += 17; /* to get tmp2 small enough */
+ mpfr_set_prec (tmp, w);
+ mpfr_set_prec (tmp2, w);
+ ck = mpfr_ui_sub (tmp, 2, x, MPFR_RNDN);
+ MPFR_ASSERTD (ck == 0); (void) ck; /* use ck to avoid a warning */
+ mpfr_const_pi (tmp2, MPFR_RNDN);
+ mpfr_mul (tmp2, tmp2, tmp, MPFR_RNDN); /* Pi*(2-x) */
+ mpfr_sin (tmp, tmp2, MPFR_RNDN); /* sin(Pi*(2-x)) */
+ sgn = mpfr_sgn (tmp);
+ mpfr_abs (tmp, tmp, MPFR_RNDN);
+ mpfr_mul_ui (tmp2, tmp2, 3, MPFR_RNDU); /* 3Pi(2-x) */
+ mpfr_add_ui (tmp2, tmp2, 1, MPFR_RNDU); /* 3Pi(2-x)+1 */
+ mpfr_div_2ui (tmp2, tmp2, mpfr_get_prec (tmp), MPFR_RNDU);
+ /* if tmp2<|tmp|, we get a lower bound */
+ if (mpfr_cmp (tmp2, tmp) < 0)
+ {
+ mpfr_sub (tmp, tmp, tmp2, MPFR_RNDZ); /* low bnd on |sin(Pi*(2-x))| */
+ mpfr_ui_div (tmp, 12, tmp, MPFR_RNDU); /* upper bound */
+ mpfr_log2 (tmp, tmp, MPFR_RNDU);
+ mpfr_add (xp, tmp, xp, MPFR_RNDU);
+ /* The assert below checks that expo.saved_emin - 2 always
+ fits in a long. FIXME if we want to allow mpfr_exp_t to
+ be a long long, for instance. */
+ MPFR_ASSERTN (MPFR_EMIN_MIN - 2 >= LONG_MIN);
+ underflow = mpfr_cmp_si (xp, expo.saved_emin - 2) <= 0;
+ }
+
+ mpfr_clear (xp);
+ mpfr_clear (tmp);
+ mpfr_clear (tmp2);
+ if (underflow) /* the sign is the opposite of that of sin(Pi*(2-x)) */
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (gamma, (rnd_mode == MPFR_RNDN) ? MPFR_RNDZ : rnd_mode, -sgn);
+ }
+ }
+
+ realprec = MPFR_PREC (gamma);
+ /* we want both 1-x and 2-x to be exact */
+ {
+ mpfr_prec_t w;
+ w = mpfr_gamma_1_minus_x_exact (x);
+ if (realprec < w)
+ realprec = w;
+ w = mpfr_gamma_2_minus_x_exact (x);
+ if (realprec < w)
+ realprec = w;
+ }
+ realprec = realprec + MPFR_INT_CEIL_LOG2 (realprec) + 20;
+ MPFR_ASSERTD(realprec >= 5);
+
+ MPFR_GROUP_INIT_4 (group, realprec + MPFR_INT_CEIL_LOG2 (realprec) + 20,
+ xp, tmp, tmp2, GammaTrial);
+ mpz_init (fact);
+ MPFR_ZIV_INIT (loop, realprec);
+ for (;;)
+ {
+ mpfr_exp_t err_g;
+ int ck;
+ MPFR_GROUP_REPREC_4 (group, realprec, xp, tmp, tmp2, GammaTrial);
+
+ /* reflection formula: gamma(x) = Pi*(x-1)/sin(Pi*(2-x))/gamma(2-x) */
+
+ ck = mpfr_ui_sub (xp, 2, x, MPFR_RNDN); /* 2-x, exact */
+ MPFR_ASSERTD(ck == 0); (void) ck; /* use ck to avoid a warning */
+ mpfr_gamma (tmp, xp, MPFR_RNDN); /* gamma(2-x), error (1+u) */
+ mpfr_const_pi (tmp2, MPFR_RNDN); /* Pi, error (1+u) */
+ mpfr_mul (GammaTrial, tmp2, xp, MPFR_RNDN); /* Pi*(2-x), error (1+u)^2 */
+ err_g = MPFR_GET_EXP(GammaTrial);
+ mpfr_sin (GammaTrial, GammaTrial, MPFR_RNDN); /* sin(Pi*(2-x)) */
+ /* If tmp is +Inf, we compute exp(lngamma(x)). */
+ if (mpfr_inf_p (tmp))
+ {
+ inex = mpfr_explgamma (gamma, x, &expo, tmp, tmp2, rnd_mode);
+ if (inex)
+ goto end;
+ else
+ goto ziv_next;
+ }
+ err_g = err_g + 1 - MPFR_GET_EXP(GammaTrial);
+ /* let g0 the true value of Pi*(2-x), g the computed value.
+ We have g = g0 + h with |h| <= |(1+u^2)-1|*g.
+ Thus sin(g) = sin(g0) + h' with |h'| <= |(1+u^2)-1|*g.
+ The relative error is thus bounded by |(1+u^2)-1|*g/sin(g)
+ <= |(1+u^2)-1|*2^err_g. <= 2.25*u*2^err_g for |u|<=1/4.
+ With the rounding error, this gives (0.5 + 2.25*2^err_g)*u. */
+ ck = mpfr_sub_ui (xp, x, 1, MPFR_RNDN); /* x-1, exact */
+ MPFR_ASSERTD(ck == 0); (void) ck; /* use ck to avoid a warning */
+ mpfr_mul (xp, tmp2, xp, MPFR_RNDN); /* Pi*(x-1), error (1+u)^2 */
+ mpfr_mul (GammaTrial, GammaTrial, tmp, MPFR_RNDN);
+ /* [1 + (0.5 + 2.25*2^err_g)*u]*(1+u)^2 = 1 + (2.5 + 2.25*2^err_g)*u
+ + (0.5 + 2.25*2^err_g)*u*(2u+u^2) + u^2.
+ For err_g <= realprec-2, we have (0.5 + 2.25*2^err_g)*u <=
+ 0.5*u + 2.25/4 <= 0.6875 and u^2 <= u/4, thus
+ (0.5 + 2.25*2^err_g)*u*(2u+u^2) + u^2 <= 0.6875*(2u+u/4) + u/4
+ <= 1.8*u, thus the rel. error is bounded by (4.5 + 2.25*2^err_g)*u. */
+ mpfr_div (GammaTrial, xp, GammaTrial, MPFR_RNDN);
+ /* the error is of the form (1+u)^3/[1 + (4.5 + 2.25*2^err_g)*u].
+ For realprec >= 5 and err_g <= realprec-2, [(4.5 + 2.25*2^err_g)*u]^2
+ <= 0.71, and for |y|<=0.71, 1/(1-y) can be written 1+a*y with a<=4.
+ (1+u)^3 * (1+4*(4.5 + 2.25*2^err_g)*u)
+ = 1 + (21 + 9*2^err_g)*u + (57+27*2^err_g)*u^2 + (55+27*2^err_g)*u^3
+ + (18+9*2^err_g)*u^4
+ <= 1 + (21 + 9*2^err_g)*u + (57+27*2^err_g)*u^2 + (56+28*2^err_g)*u^3
+ <= 1 + (21 + 9*2^err_g)*u + (59+28*2^err_g)*u^2
+ <= 1 + (23 + 10*2^err_g)*u.
+ The final error is thus bounded by (23 + 10*2^err_g) ulps,
+ which is <= 2^6 for err_g<=2, and <= 2^(err_g+4) for err_g >= 2. */
+ err_g = (err_g <= 2) ? 6 : err_g + 4;
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (GammaTrial, realprec - err_g,
+ MPFR_PREC(gamma), rnd_mode)))
+ break;
+
+ ziv_next:
+ MPFR_ZIV_NEXT (loop, realprec);
+ }
+
+ end:
+ MPFR_ZIV_FREE (loop);
+
+ if (inex == 0)
+ inex = mpfr_set (gamma, GammaTrial, rnd_mode);
+ MPFR_GROUP_CLEAR (group);
+ mpz_clear (fact);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (gamma, inex, rnd_mode);
+}
diff --git a/mpfr/src/gammaonethird.c b/mpfr/src/gammaonethird.c
new file mode 100644
index 0000000000..93fda9c128
--- /dev/null
+++ b/mpfr/src/gammaonethird.c
@@ -0,0 +1,191 @@
+/* Functions for evaluating Gamma(1/3) and Gamma(2/3). Used by mpfr_ai.
+
+Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#define MPFR_ACC_OR_MUL(v) \
+ do \
+ { \
+ if (v <= ULONG_MAX / acc) \
+ acc *= v; \
+ else \
+ { \
+ mpfr_mul_ui (y, y, acc, mode); acc = v; \
+ } \
+ } \
+ while (0)
+
+#define MPFR_ACC_OR_DIV(v) \
+ do \
+ { \
+ if (v <= ULONG_MAX / acc) \
+ acc *= v; \
+ else \
+ { \
+ mpfr_div_ui (y, y, acc, mode); acc = v; \
+ } \
+ } \
+ while (0)
+
+static void
+mpfr_mul_ui5 (mpfr_ptr y, mpfr_srcptr x,
+ unsigned long int v1, unsigned long int v2,
+ unsigned long int v3, unsigned long int v4,
+ unsigned long int v5, mpfr_rnd_t mode)
+{
+ unsigned long int acc = v1;
+ mpfr_set (y, x, mode);
+ MPFR_ACC_OR_MUL (v2);
+ MPFR_ACC_OR_MUL (v3);
+ MPFR_ACC_OR_MUL (v4);
+ MPFR_ACC_OR_MUL (v5);
+ mpfr_mul_ui (y, y, acc, mode);
+}
+
+void
+mpfr_div_ui2 (mpfr_ptr y, mpfr_srcptr x,
+ unsigned long int v1, unsigned long int v2, mpfr_rnd_t mode)
+{
+ unsigned long int acc = v1;
+ mpfr_set (y, x, mode);
+ MPFR_ACC_OR_DIV (v2);
+ mpfr_div_ui (y, y, acc, mode);
+}
+
+static void
+mpfr_div_ui8 (mpfr_ptr y, mpfr_srcptr x,
+ unsigned long int v1, unsigned long int v2,
+ unsigned long int v3, unsigned long int v4,
+ unsigned long int v5, unsigned long int v6,
+ unsigned long int v7, unsigned long int v8, mpfr_rnd_t mode)
+{
+ unsigned long int acc = v1;
+ mpfr_set (y, x, mode);
+ MPFR_ACC_OR_DIV (v2);
+ MPFR_ACC_OR_DIV (v3);
+ MPFR_ACC_OR_DIV (v4);
+ MPFR_ACC_OR_DIV (v5);
+ MPFR_ACC_OR_DIV (v6);
+ MPFR_ACC_OR_DIV (v7);
+ MPFR_ACC_OR_DIV (v8);
+ mpfr_div_ui (y, y, acc, mode);
+}
+
+
+/* Gives an approximation of omega = Gamma(1/3)^6 * sqrt(10) / (12pi^4) */
+/* using C. H. Brown's formula. */
+/* The computed value s satisfies |s-omega| <= 2^{1-prec}*omega */
+/* As usual, the variable s is supposed to be initialized. */
+static void
+mpfr_Browns_const (mpfr_ptr s, mpfr_prec_t prec)
+{
+ mpfr_t uk;
+ unsigned long int k;
+
+ mpfr_prec_t working_prec = prec + 10 + MPFR_INT_CEIL_LOG2 (2 + prec / 10);
+
+ mpfr_init2 (uk, working_prec);
+ mpfr_set_prec (s, working_prec);
+
+ mpfr_set_ui (uk, 1, MPFR_RNDN);
+ mpfr_set (s, uk, MPFR_RNDN);
+ k = 1;
+
+ /* Invariants: uk ~ u(k-1) and s ~ sum(i=0..k-1, u(i)) */
+ for (;;)
+ {
+ mpfr_mul_ui5 (uk, uk, 6 * k - 5, 6 * k - 4, 6 * k - 3, 6 * k - 2,
+ 6 * k - 1, MPFR_RNDN);
+ mpfr_div_ui8 (uk, uk, k, k, 3 * k - 2, 3 * k - 1, 3 * k, 80, 160, 160,
+ MPFR_RNDN);
+ MPFR_CHANGE_SIGN (uk);
+
+ mpfr_add (s, s, uk, MPFR_RNDN);
+ k++;
+ if (MPFR_GET_EXP (uk) + prec <= MPFR_GET_EXP (s) + 7)
+ break;
+ }
+
+ mpfr_clear (uk);
+ return;
+}
+
+/* Returns y such that |Gamma(1/3)-y| <= 2^{1-prec}*Gamma(1/3) */
+static void
+mpfr_gamma_one_third (mpfr_ptr y, mpfr_prec_t prec)
+{
+ mpfr_t tmp, tmp2, tmp3;
+
+ mpfr_init2 (tmp, prec + 9);
+ mpfr_init2 (tmp2, prec + 9);
+ mpfr_init2 (tmp3, prec + 4);
+ mpfr_set_prec (y, prec + 2);
+
+ mpfr_const_pi (tmp, MPFR_RNDN);
+ mpfr_sqr (tmp, tmp, MPFR_RNDN);
+ mpfr_sqr (tmp, tmp, MPFR_RNDN);
+ mpfr_mul_ui (tmp, tmp, 12, MPFR_RNDN);
+
+ mpfr_Browns_const (tmp2, prec + 9);
+ mpfr_mul (tmp, tmp, tmp2, MPFR_RNDN);
+
+ mpfr_set_ui (tmp2, 10, MPFR_RNDN);
+ mpfr_sqrt (tmp2, tmp2, MPFR_RNDN);
+ mpfr_div (tmp, tmp, tmp2, MPFR_RNDN);
+
+ mpfr_sqrt (tmp3, tmp, MPFR_RNDN);
+ mpfr_cbrt (y, tmp3, MPFR_RNDN);
+
+ mpfr_clear (tmp);
+ mpfr_clear (tmp2);
+ mpfr_clear (tmp3);
+ return;
+}
+
+/* Computes y1 and y2 such that: */
+/* |y1-Gamma(1/3)| <= 2^{1-prec}Gamma(1/3) */
+/* and |y2-Gamma(2/3)| <= 2^{1-prec}Gamma(2/3) */
+/* */
+/* Uses the formula Gamma(z)Gamma(1-z) = pi / sin(pi*z) */
+/* to compute Gamma(2/3) from Gamma(1/3). */
+void
+mpfr_gamma_one_and_two_third (mpfr_ptr y1, mpfr_ptr y2, mpfr_prec_t prec)
+{
+ mpfr_t temp;
+
+ mpfr_init2 (temp, prec + 4);
+ mpfr_set_prec (y2, prec + 4);
+
+ mpfr_gamma_one_third (y1, prec + 4);
+
+ mpfr_set_ui (temp, 3, MPFR_RNDN);
+ mpfr_sqrt (temp, temp, MPFR_RNDN);
+ mpfr_mul (temp, y1, temp, MPFR_RNDN);
+
+ mpfr_const_pi (y2, MPFR_RNDN);
+ mpfr_mul_2ui (y2, y2, 1, MPFR_RNDN);
+
+ mpfr_div (y2, y2, temp, MPFR_RNDN);
+
+ mpfr_clear (temp);
+}
diff --git a/mpfr/src/gen_inverse.h b/mpfr/src/gen_inverse.h
new file mode 100644
index 0000000000..49f8ed0d75
--- /dev/null
+++ b/mpfr/src/gen_inverse.h
@@ -0,0 +1,106 @@
+/* generic inverse of a function.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#ifndef ACTION_SPECIAL
+#define ACTION_SPECIAL
+#endif
+
+#ifndef ACTION_TINY
+#define ACTION_TINY
+#endif
+
+/* example of use:
+#define FUNCTION mpfr_sec
+#define INVERSE mpfr_cos
+#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_INF(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_ZERO(y) return mpfr_set_ui (y, 1, MPFR_RNDN)
+#include "gen_inverse.h"
+*/
+
+int
+FUNCTION (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t precy; /* target precision */
+ mpfr_prec_t m; /* working precision */
+ mpfr_t z; /* temporary variable to store INVERSE(x) */
+ int inexact; /* inexact flag */
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
+ {
+ if (MPFR_IS_NAN(x))
+ ACTION_NAN(y);
+ else if (MPFR_IS_INF(x))
+ ACTION_INF(y);
+ else /* x = 0 */
+ ACTION_ZERO(y,x);
+ }
+
+ /* x is neither NaN, Inf nor zero */
+ MPFR_SAVE_EXPO_MARK (expo);
+ ACTION_TINY (y, x, rnd_mode); /* special case for very small input x */
+ precy = MPFR_PREC(y);
+ m = precy + MPFR_INT_CEIL_LOG2 (precy) + 3;
+ mpfr_init2 (z, m);
+
+ MPFR_ZIV_INIT (loop, m);
+ for(;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_BLOCK (flags, INVERSE (z, x, MPFR_RNDZ)); /* error k_u < 1 ulp */
+ /* FIXME: the following assumes that if an overflow happens with
+ MPFR_EMAX_MAX, then necessarily an underflow happens with
+ __gmpfr_emin */
+ if (MPFR_OVERFLOW (flags))
+ {
+ int s = MPFR_SIGN(z);
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (z);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (y, (rnd_mode == MPFR_RNDN) ?
+ MPFR_RNDZ : rnd_mode, s);
+ }
+ mpfr_ui_div (z, 1, z, MPFR_RNDN);
+ /* the error is less than c_w + 2*c_u*k_u (see algorithms.tex),
+ where c_w = 1/2, c_u = 1 since z was rounded toward zero,
+ thus 1/2 + 2 < 4 */
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (z, m - 2, precy, rnd_mode)))
+ break;
+ ACTION_SPECIAL;
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (z, m);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (y, z, rnd_mode);
+ mpfr_clear (z);
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/generic/mparam.h b/mpfr/src/generic/mparam.h
new file mode 100644
index 0000000000..c0ff603811
--- /dev/null
+++ b/mpfr/src/generic/mparam.h
@@ -0,0 +1,69 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef MPFR_MULHIGH_TAB
+# define MPFR_MULHIGH_TAB -1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0
+#endif
+
+#ifndef MPFR_SQRHIGH_TAB
+# define MPFR_SQRHIGH_TAB -1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0
+#endif
+
+#ifndef MPFR_DIVHIGH_TAB
+# define MPFR_DIVHIGH_TAB 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
+#endif
+
+#ifndef MPFR_MUL_THRESHOLD
+# define MPFR_MUL_THRESHOLD 20 /* limbs */
+#endif
+
+#ifndef MPFR_SQR_THRESHOLD
+# define MPFR_SQR_THRESHOLD 20 /* limbs */
+#endif
+
+#ifndef MPFR_DIV_THRESHOLD
+# define MPFR_DIV_THRESHOLD 25 /* limbs */
+#endif
+
+#ifndef MPFR_EXP_2_THRESHOLD
+# define MPFR_EXP_2_THRESHOLD 100 /* bits */
+#endif
+
+#ifndef MPFR_EXP_THRESHOLD
+# define MPFR_EXP_THRESHOLD 25000 /* bits */
+#endif
+
+#ifndef MPFR_SINCOS_THRESHOLD
+# define MPFR_SINCOS_THRESHOLD 30000 /* bits */
+#endif
+
+#ifndef MPFR_AI_THRESHOLD1
+# define MPFR_AI_THRESHOLD1 -13107 /* threshold for negative input of mpfr_ai */
+#endif
+
+#ifndef MPFR_AI_THRESHOLD2
+# define MPFR_AI_THRESHOLD2 1311
+#endif
+
+#ifndef MPFR_AI_THRESHOLD3
+# define MPFR_AI_THRESHOLD3 19661
+#endif
+
diff --git a/mpfr/src/get_d.c b/mpfr/src/get_d.c
new file mode 100644
index 0000000000..307148a9f9
--- /dev/null
+++ b/mpfr/src/get_d.c
@@ -0,0 +1,183 @@
+/* mpfr_get_d, mpfr_get_d_2exp -- convert a multiple precision floating-point
+ number to a machine double precision float
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <float.h>
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#include "ieee_floats.h"
+
+/* Assumes IEEE-754 double precision; otherwise, only an approximated
+ result will be returned, without any guaranty (and special cases
+ such as NaN must be avoided if not supported). */
+
+double
+mpfr_get_d (mpfr_srcptr src, mpfr_rnd_t rnd_mode)
+{
+ double d;
+ int negative;
+ mpfr_exp_t e;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (src)))
+ {
+ if (MPFR_IS_NAN (src))
+ return MPFR_DBL_NAN;
+
+ negative = MPFR_IS_NEG (src);
+
+ if (MPFR_IS_INF (src))
+ return negative ? MPFR_DBL_INFM : MPFR_DBL_INFP;
+
+ MPFR_ASSERTD (MPFR_IS_ZERO(src));
+ return negative ? DBL_NEG_ZERO : 0.0;
+ }
+
+ e = MPFR_GET_EXP (src);
+ negative = MPFR_IS_NEG (src);
+
+ if (MPFR_UNLIKELY(rnd_mode == MPFR_RNDA))
+ rnd_mode = negative ? MPFR_RNDD : MPFR_RNDU;
+
+ /* the smallest normalized number is 2^(-1022)=0.1e-1021, and the smallest
+ subnormal is 2^(-1074)=0.1e-1073 */
+ if (MPFR_UNLIKELY (e < -1073))
+ {
+ /* Note: Avoid using a constant expression DBL_MIN * DBL_EPSILON
+ as this gives 0 instead of the correct result with gcc on some
+ Alpha machines. */
+ d = negative ?
+ (rnd_mode == MPFR_RNDD ||
+ (rnd_mode == MPFR_RNDN && mpfr_cmp_si_2exp(src, -1, -1075) < 0)
+ ? -DBL_MIN : DBL_NEG_ZERO) :
+ (rnd_mode == MPFR_RNDU ||
+ (rnd_mode == MPFR_RNDN && mpfr_cmp_si_2exp(src, 1, -1075) > 0)
+ ? DBL_MIN : 0.0);
+ if (d != 0.0) /* we multiply DBL_MIN = 2^(-1022) by DBL_EPSILON = 2^(-52)
+ to get +-2^(-1074) */
+ d *= DBL_EPSILON;
+ }
+ /* the largest normalized number is 2^1024*(1-2^(-53))=0.111...111e1024 */
+ else if (MPFR_UNLIKELY (e > 1024))
+ {
+ d = negative ?
+ (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDU ?
+ -DBL_MAX : MPFR_DBL_INFM) :
+ (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDD ?
+ DBL_MAX : MPFR_DBL_INFP);
+ }
+ else
+ {
+ int nbits;
+ mp_size_t np, i;
+ mp_limb_t tp[ MPFR_LIMBS_PER_DOUBLE ];
+ int carry;
+
+ nbits = IEEE_DBL_MANT_DIG; /* 53 */
+ if (MPFR_UNLIKELY (e < -1021))
+ /*In the subnormal case, compute the exact number of significant bits*/
+ {
+ nbits += (1021 + e);
+ MPFR_ASSERTD (nbits >= 1);
+ }
+ np = MPFR_PREC2LIMBS (nbits);
+ MPFR_ASSERTD ( np <= MPFR_LIMBS_PER_DOUBLE );
+ carry = mpfr_round_raw_4 (tp, MPFR_MANT(src), MPFR_PREC(src), negative,
+ nbits, rnd_mode);
+ if (MPFR_UNLIKELY(carry))
+ d = 1.0;
+ else
+ {
+ /* The following computations are exact thanks to the previous
+ mpfr_round_raw. */
+ d = (double) tp[0] / MP_BASE_AS_DOUBLE;
+ for (i = 1 ; i < np ; i++)
+ d = (d + tp[i]) / MP_BASE_AS_DOUBLE;
+ /* d is the mantissa (between 1/2 and 1) of the argument rounded
+ to 53 bits */
+ }
+ d = mpfr_scale2 (d, e);
+ if (negative)
+ d = -d;
+ }
+
+ return d;
+}
+
+#undef mpfr_get_d1
+double
+mpfr_get_d1 (mpfr_srcptr src)
+{
+ return mpfr_get_d (src, __gmpfr_default_rounding_mode);
+}
+
+double
+mpfr_get_d_2exp (long *expptr, mpfr_srcptr src, mpfr_rnd_t rnd_mode)
+{
+ double ret;
+ mpfr_exp_t exp;
+ mpfr_t tmp;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (src)))
+ {
+ int negative;
+ *expptr = 0;
+ if (MPFR_IS_NAN (src))
+ return MPFR_DBL_NAN;
+ negative = MPFR_IS_NEG (src);
+ if (MPFR_IS_INF (src))
+ return negative ? MPFR_DBL_INFM : MPFR_DBL_INFP;
+ MPFR_ASSERTD (MPFR_IS_ZERO(src));
+ return negative ? DBL_NEG_ZERO : 0.0;
+ }
+
+ tmp[0] = *src; /* Hack copy mpfr_t */
+ MPFR_SET_EXP (tmp, 0);
+ ret = mpfr_get_d (tmp, rnd_mode);
+
+ if (MPFR_IS_PURE_FP(src))
+ {
+ exp = MPFR_GET_EXP (src);
+
+ /* rounding can give 1.0, adjust back to 0.5 <= abs(ret) < 1.0 */
+ if (ret == 1.0)
+ {
+ ret = 0.5;
+ exp++;
+ }
+ else if (ret == -1.0)
+ {
+ ret = -0.5;
+ exp++;
+ }
+
+ MPFR_ASSERTN ((ret >= 0.5 && ret < 1.0)
+ || (ret <= -0.5 && ret > -1.0));
+ MPFR_ASSERTN (exp >= LONG_MIN && exp <= LONG_MAX);
+ }
+ else
+ exp = 0;
+
+ *expptr = exp;
+ return ret;
+}
diff --git a/mpfr/src/get_d64.c b/mpfr/src/get_d64.c
new file mode 100644
index 0000000000..ec4d8e8f33
--- /dev/null
+++ b/mpfr/src/get_d64.c
@@ -0,0 +1,400 @@
+/* mpfr_get_decimal64 -- convert a multiple precision floating-point number
+ to a IEEE 754r decimal64 float
+
+See http://gcc.gnu.org/ml/gcc/2006-06/msg00691.html,
+http://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html,
+and TR 24732 <http://www.open-std.org/jtc1/sc22/wg14/www/projects#24732>.
+
+Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h> /* for strtol */
+#include "mpfr-impl.h"
+
+#define ISDIGIT(c) ('0' <= c && c <= '9')
+
+#ifdef MPFR_WANT_DECIMAL_FLOATS
+
+#ifndef DEC64_MAX
+# define DEC64_MAX 9.999999999999999E384dd
+#endif
+
+#ifdef DPD_FORMAT
+static int T[1000] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 10, 11, 42, 43, 74, 75, 106, 107, 78, 79, 26, 27,
+ 58, 59, 90, 91, 122, 123, 94, 95, 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 160, 161, 162,
+ 163, 164, 165, 166, 167, 168, 169, 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 208, 209, 210,
+ 211, 212, 213, 214, 215, 216, 217, 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 138, 139, 170,
+ 171, 202, 203, 234, 235, 206, 207, 154, 155, 186, 187, 218, 219, 250, 251,
+ 222, 223, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 288, 289, 290, 291, 292, 293, 294, 295,
+ 296, 297, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 320, 321, 322,
+ 323, 324, 325, 326, 327, 328, 329, 336, 337, 338, 339, 340, 341, 342, 343,
+ 344, 345, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 368, 369, 370,
+ 371, 372, 373, 374, 375, 376, 377, 266, 267, 298, 299, 330, 331, 362, 363,
+ 334, 335, 282, 283, 314, 315, 346, 347, 378, 379, 350, 351, 384, 385, 386,
+ 387, 388, 389, 390, 391, 392, 393, 400, 401, 402, 403, 404, 405, 406, 407,
+ 408, 409, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 432, 433, 434,
+ 435, 436, 437, 438, 439, 440, 441, 448, 449, 450, 451, 452, 453, 454, 455,
+ 456, 457, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 480, 481, 482,
+ 483, 484, 485, 486, 487, 488, 489, 496, 497, 498, 499, 500, 501, 502, 503,
+ 504, 505, 394, 395, 426, 427, 458, 459, 490, 491, 462, 463, 410, 411, 442,
+ 443, 474, 475, 506, 507, 478, 479, 512, 513, 514, 515, 516, 517, 518, 519,
+ 520, 521, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 544, 545, 546,
+ 547, 548, 549, 550, 551, 552, 553, 560, 561, 562, 563, 564, 565, 566, 567,
+ 568, 569, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 592, 593, 594,
+ 595, 596, 597, 598, 599, 600, 601, 608, 609, 610, 611, 612, 613, 614, 615,
+ 616, 617, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 522, 523, 554,
+ 555, 586, 587, 618, 619, 590, 591, 538, 539, 570, 571, 602, 603, 634, 635,
+ 606, 607, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 656, 657, 658,
+ 659, 660, 661, 662, 663, 664, 665, 672, 673, 674, 675, 676, 677, 678, 679,
+ 680, 681, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 704, 705, 706,
+ 707, 708, 709, 710, 711, 712, 713, 720, 721, 722, 723, 724, 725, 726, 727,
+ 728, 729, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 752, 753, 754,
+ 755, 756, 757, 758, 759, 760, 761, 650, 651, 682, 683, 714, 715, 746, 747,
+ 718, 719, 666, 667, 698, 699, 730, 731, 762, 763, 734, 735, 768, 769, 770,
+ 771, 772, 773, 774, 775, 776, 777, 784, 785, 786, 787, 788, 789, 790, 791,
+ 792, 793, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 816, 817, 818,
+ 819, 820, 821, 822, 823, 824, 825, 832, 833, 834, 835, 836, 837, 838, 839,
+ 840, 841, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 864, 865, 866,
+ 867, 868, 869, 870, 871, 872, 873, 880, 881, 882, 883, 884, 885, 886, 887,
+ 888, 889, 778, 779, 810, 811, 842, 843, 874, 875, 846, 847, 794, 795, 826,
+ 827, 858, 859, 890, 891, 862, 863, 896, 897, 898, 899, 900, 901, 902, 903,
+ 904, 905, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 928, 929, 930,
+ 931, 932, 933, 934, 935, 936, 937, 944, 945, 946, 947, 948, 949, 950, 951,
+ 952, 953, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 976, 977, 978,
+ 979, 980, 981, 982, 983, 984, 985, 992, 993, 994, 995, 996, 997, 998, 999,
+ 1000, 1001, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 906,
+ 907, 938, 939, 970, 971, 1002, 1003, 974, 975, 922, 923, 954, 955, 986,
+ 987, 1018, 1019, 990, 991, 12, 13, 268, 269, 524, 525, 780, 781, 46, 47, 28,
+ 29, 284, 285, 540, 541, 796, 797, 62, 63, 44, 45, 300, 301, 556, 557, 812,
+ 813, 302, 303, 60, 61, 316, 317, 572, 573, 828, 829, 318, 319, 76, 77,
+ 332, 333, 588, 589, 844, 845, 558, 559, 92, 93, 348, 349, 604, 605, 860,
+ 861, 574, 575, 108, 109, 364, 365, 620, 621, 876, 877, 814, 815, 124, 125,
+ 380, 381, 636, 637, 892, 893, 830, 831, 14, 15, 270, 271, 526, 527, 782,
+ 783, 110, 111, 30, 31, 286, 287, 542, 543, 798, 799, 126, 127, 140, 141,
+ 396, 397, 652, 653, 908, 909, 174, 175, 156, 157, 412, 413, 668, 669, 924,
+ 925, 190, 191, 172, 173, 428, 429, 684, 685, 940, 941, 430, 431, 188, 189,
+ 444, 445, 700, 701, 956, 957, 446, 447, 204, 205, 460, 461, 716, 717, 972,
+ 973, 686, 687, 220, 221, 476, 477, 732, 733, 988, 989, 702, 703, 236, 237,
+ 492, 493, 748, 749, 1004, 1005, 942, 943, 252, 253, 508, 509, 764, 765,
+ 1020, 1021, 958, 959, 142, 143, 398, 399, 654, 655, 910, 911, 238, 239, 158,
+ 159, 414, 415, 670, 671, 926, 927, 254, 255};
+#endif
+
+/* construct a decimal64 NaN */
+static _Decimal64
+get_decimal64_nan (void)
+{
+ union ieee_double_extract x;
+ union ieee_double_decimal64 y;
+
+ x.s.exp = 1984; /* G[0]..G[4] = 11111: quiet NaN */
+ y.d = x.d;
+ return y.d64;
+}
+
+/* construct the decimal64 Inf with given sign */
+static _Decimal64
+get_decimal64_inf (int negative)
+{
+ union ieee_double_extract x;
+ union ieee_double_decimal64 y;
+
+ x.s.sig = (negative) ? 1 : 0;
+ x.s.exp = 1920; /* G[0]..G[4] = 11110: Inf */
+ y.d = x.d;
+ return y.d64;
+}
+
+/* construct the decimal64 zero with given sign */
+static _Decimal64
+get_decimal64_zero (int negative)
+{
+ union ieee_double_decimal64 y;
+
+ /* zero has the same representation in binary64 and decimal64 */
+ y.d = negative ? DBL_NEG_ZERO : 0.0;
+ return y.d64;
+}
+
+/* construct the decimal64 smallest non-zero with given sign */
+static _Decimal64
+get_decimal64_min (int negative)
+{
+ return negative ? - 1E-398dd : 1E-398dd;
+}
+
+/* construct the decimal64 largest finite number with given sign */
+static _Decimal64
+get_decimal64_max (int negative)
+{
+ return negative ? - DEC64_MAX : DEC64_MAX;
+}
+
+/* one-to-one conversion:
+ s is a decimal string representing a number x = m * 10^e which must be
+ exactly representable in the decimal64 format, i.e.
+ (a) the mantissa m has at most 16 decimal digits
+ (b1) -383 <= e <= 384 with m integer multiple of 10^(-15), |m| < 10
+ (b2) or -398 <= e <= 369 with m integer, |m| < 10^16.
+ Assumes s is neither NaN nor +Inf nor -Inf.
+*/
+static _Decimal64
+string_to_Decimal64 (char *s)
+{
+ long int exp = 0;
+ char m[17];
+ long n = 0; /* mantissa length */
+ char *endptr[1];
+ union ieee_double_extract x;
+ union ieee_double_decimal64 y;
+#ifdef DPD_FORMAT
+ unsigned int G, d1, d2, d3, d4, d5;
+#endif
+
+ /* read sign */
+ if (*s == '-')
+ {
+ x.s.sig = 1;
+ s ++;
+ }
+ else
+ x.s.sig = 0;
+ /* read mantissa */
+ while (ISDIGIT (*s))
+ m[n++] = *s++;
+ exp = n;
+ if (*s == '.')
+ {
+ s ++;
+ while (ISDIGIT (*s))
+ m[n++] = *s++;
+ }
+ /* we have exp digits before decimal point, and a total of n digits */
+ exp -= n; /* we will consider an integer mantissa */
+ MPFR_ASSERTN(n <= 16);
+ if (*s == 'E' || *s == 'e')
+ exp += strtol (s + 1, endptr, 10);
+ else
+ *endptr = s;
+ MPFR_ASSERTN(**endptr == '\0');
+ MPFR_ASSERTN(-398 <= exp && exp <= (long) (385 - n));
+ while (n < 16)
+ {
+ m[n++] = '0';
+ exp --;
+ }
+ /* now n=16 and -398 <= exp <= 369 */
+ m[n] = '\0';
+
+ /* compute biased exponent */
+ exp += 398;
+
+ MPFR_ASSERTN(exp >= -15);
+ if (exp < 0)
+ {
+ int i;
+ n = -exp;
+ /* check the last n digits of the mantissa are zero */
+ for (i = 1; i <= n; i++)
+ MPFR_ASSERTN(m[16 - n] == '0');
+ /* shift the first (16-n) digits to the right */
+ for (i = 16 - n - 1; i >= 0; i--)
+ m[i + n] = m[i];
+ /* zero the first n digits */
+ for (i = 0; i < n; i ++)
+ m[i] = '0';
+ exp = 0;
+ }
+
+ /* now convert to DPD or BID */
+#ifdef DPD_FORMAT
+#define CH(d) (d - '0')
+ if (m[0] >= '8')
+ G = (3 << 11) | ((exp & 768) << 1) | ((CH(m[0]) & 1) << 8);
+ else
+ G = ((exp & 768) << 3) | (CH(m[0]) << 8);
+ /* now the most 5 significant bits of G are filled */
+ G |= exp & 255;
+ d1 = T[100 * CH(m[1]) + 10 * CH(m[2]) + CH(m[3])]; /* 10-bit encoding */
+ d2 = T[100 * CH(m[4]) + 10 * CH(m[5]) + CH(m[6])]; /* 10-bit encoding */
+ d3 = T[100 * CH(m[7]) + 10 * CH(m[8]) + CH(m[9])]; /* 10-bit encoding */
+ d4 = T[100 * CH(m[10]) + 10 * CH(m[11]) + CH(m[12])]; /* 10-bit encoding */
+ d5 = T[100 * CH(m[13]) + 10 * CH(m[14]) + CH(m[15])]; /* 10-bit encoding */
+ x.s.exp = G >> 2;
+ x.s.manh = ((G & 3) << 18) | (d1 << 8) | (d2 >> 2);
+ x.s.manl = (d2 & 3) << 30;
+ x.s.manl |= (d3 << 20) | (d4 << 10) | d5;
+#else /* BID format */
+ {
+ mp_size_t rn;
+ mp_limb_t rp[2];
+ int case_i = strcmp (m, "9007199254740992") < 0;
+
+ for (n = 0; n < 16; n++)
+ m[n] -= '0';
+ rn = mpn_set_str (rp, (unsigned char *) m, 16, 10);
+ if (rn == 1)
+ rp[1] = 0;
+#if GMP_NUMB_BITS > 32
+ rp[1] = rp[1] << (GMP_NUMB_BITS - 32);
+ rp[1] |= rp[0] >> 32;
+ rp[0] &= 4294967295UL;
+#endif
+ if (case_i)
+ { /* s < 2^53: case i) */
+ x.s.exp = exp << 1;
+ x.s.manl = rp[0]; /* 32 bits */
+ x.s.manh = rp[1] & 1048575; /* 20 low bits */
+ x.s.exp |= rp[1] >> 20; /* 1 bit */
+ }
+ else /* s >= 2^53: case ii) */
+ {
+ x.s.exp = 1536 | (exp >> 1);
+ x.s.manl = rp[0];
+ x.s.manh = (rp[1] ^ 2097152) | ((exp & 1) << 19);
+ }
+ }
+#endif /* DPD_FORMAT */
+ y.d = x.d;
+ return y.d64;
+}
+
+_Decimal64
+mpfr_get_decimal64 (mpfr_srcptr src, mpfr_rnd_t rnd_mode)
+{
+ int negative;
+ mpfr_exp_t e;
+
+ /* the encoding of NaN, Inf, zero is the same under DPD or BID */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (src)))
+ {
+ if (MPFR_IS_NAN (src))
+ return get_decimal64_nan ();
+
+ negative = MPFR_IS_NEG (src);
+
+ if (MPFR_IS_INF (src))
+ return get_decimal64_inf (negative);
+
+ MPFR_ASSERTD (MPFR_IS_ZERO(src));
+ return get_decimal64_zero (negative);
+ }
+
+ e = MPFR_GET_EXP (src);
+ negative = MPFR_IS_NEG (src);
+
+ if (MPFR_UNLIKELY(rnd_mode == MPFR_RNDA))
+ rnd_mode = negative ? MPFR_RNDD : MPFR_RNDU;
+
+ /* the smallest decimal64 number is 10^(-398),
+ with 2^(-1323) < 10^(-398) < 2^(-1322) */
+ if (MPFR_UNLIKELY (e < -1323)) /* src <= 2^(-1324) < 1/2*10^(-398) */
+ {
+ if (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDN
+ || (rnd_mode == MPFR_RNDD && negative == 0)
+ || (rnd_mode == MPFR_RNDU && negative != 0))
+ return get_decimal64_zero (negative);
+ else /* return the smallest non-zero number */
+ return get_decimal64_min (negative);
+ }
+ /* the largest decimal64 number is just below 10^(385) < 2^1279 */
+ else if (MPFR_UNLIKELY (e > 1279)) /* then src >= 2^1279 */
+ {
+ if (rnd_mode == MPFR_RNDZ
+ || (rnd_mode == MPFR_RNDU && negative != 0)
+ || (rnd_mode == MPFR_RNDD && negative == 0))
+ return get_decimal64_max (negative);
+ else
+ return get_decimal64_inf (negative);
+ }
+ else
+ {
+ /* we need to store the sign (1), the mantissa (16), and the terminating
+ character, thus we need at least 18 characters in s */
+ char s[23];
+ mpfr_get_str (s, &e, 10, 16, src, rnd_mode);
+ /* the smallest normal number is 1.000...000E-383,
+ which corresponds to s=[0.]1000...000 and e=-382 */
+ if (e < -382)
+ {
+ /* the smallest subnormal number is 0.000...001E-383 = 1E-398,
+ which corresponds to s=[0.]1000...000 and e=-397 */
+ if (e < -397)
+ {
+ if (rnd_mode == MPFR_RNDN && e == -398)
+ {
+ /* If 0.5E-398 < |src| < 1E-398 (smallest subnormal),
+ src should round to +/- 1E-398 in MPFR_RNDN. */
+ mpfr_get_str (s, &e, 10, 1, src, MPFR_RNDA);
+ return e == -398 && s[negative] <= '5' ?
+ get_decimal64_zero (negative) :
+ get_decimal64_min (negative);
+ }
+ if (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDN
+ || (rnd_mode == MPFR_RNDD && negative == 0)
+ || (rnd_mode == MPFR_RNDU && negative != 0))
+ return get_decimal64_zero (negative);
+ else /* return the smallest non-zero number */
+ return get_decimal64_min (negative);
+ }
+ else
+ {
+ mpfr_exp_t e2;
+ long digits = 16 - (-382 - e);
+ /* if e = -397 then 16 - (-382 - e) = 1 */
+ mpfr_get_str (s, &e2, 10, digits, src, rnd_mode);
+ /* Warning: we can have e2 = e + 1 here, when rounding to
+ nearest or away from zero. */
+ s[negative + digits] = 'E';
+ sprintf (s + negative + digits + 1, "%ld",
+ (long int)e2 - digits);
+ return string_to_Decimal64 (s);
+ }
+ }
+ /* the largest number is 9.999...999E+384,
+ which corresponds to s=[0.]9999...999 and e=385 */
+ else if (e > 385)
+ {
+ if (rnd_mode == MPFR_RNDZ
+ || (rnd_mode == MPFR_RNDU && negative != 0)
+ || (rnd_mode == MPFR_RNDD && negative == 0))
+ return get_decimal64_max (negative);
+ else
+ return get_decimal64_inf (negative);
+ }
+ else /* -382 <= e <= 385 */
+ {
+ s[16 + negative] = 'E';
+ sprintf (s + 17 + negative, "%ld", (long int)e - 16);
+ return string_to_Decimal64 (s);
+ }
+ }
+}
+
+#endif /* MPFR_WANT_DECIMAL_FLOATS */
diff --git a/mpfr/src/get_exp.c b/mpfr/src/get_exp.c
new file mode 100644
index 0000000000..5be268f53e
--- /dev/null
+++ b/mpfr/src/get_exp.c
@@ -0,0 +1,31 @@
+/* mpfr_get_exp - get the exponent of a floating-point number
+
+Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#undef mpfr_get_exp
+mpfr_exp_t
+mpfr_get_exp (mpfr_srcptr x)
+{
+ MPFR_ASSERTN(MPFR_IS_PURE_FP(x));
+ return MPFR_EXP(x); /* do not use MPFR_GET_EXP of course... */
+}
diff --git a/mpfr/src/get_f.c b/mpfr/src/get_f.c
new file mode 100644
index 0000000000..67b2962d79
--- /dev/null
+++ b/mpfr/src/get_f.c
@@ -0,0 +1,148 @@
+/* mpfr_get_f -- convert a MPFR number to a GNU MPF number
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Since MPFR-3.0, return the usual inexact value.
+ The erange flag is set if an error occurred in the conversion
+ (y is NaN, +Inf, or -Inf that have no equivalent in mpf)
+*/
+int
+mpfr_get_f (mpf_ptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
+{
+ int inex;
+ mp_size_t sx, sy;
+ mpfr_prec_t precx, precy;
+ mp_limb_t *xp;
+ int sh;
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(y)))
+ {
+ if (MPFR_IS_ZERO(y))
+ {
+ mpf_set_ui (x, 0);
+ return 0;
+ }
+ else if (MPFR_IS_NAN (y))
+ {
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ else /* y is plus infinity (resp. minus infinity), set x to the maximum
+ value (resp. the minimum value) in precision PREC(x) */
+ {
+ int i;
+ mp_limb_t *xp;
+
+ MPFR_SET_ERANGE ();
+
+ /* To this day, [mp_exp_t] and mp_size_t are #defined as the same
+ type */
+ EXP (x) = MP_SIZE_T_MAX;
+
+ sx = PREC (x);
+ SIZ (x) = sx;
+ xp = PTR (x);
+ for (i = 0; i < sx; i++)
+ xp[i] = MP_LIMB_T_MAX;
+
+ if (MPFR_IS_POS (y))
+ return -1;
+ else
+ {
+ mpf_neg (x, x);
+ return +1;
+ }
+ }
+ }
+
+ sx = PREC(x); /* number of limbs of the mantissa of x */
+
+ precy = MPFR_PREC(y);
+ precx = (mpfr_prec_t) sx * GMP_NUMB_BITS;
+ sy = MPFR_LIMB_SIZE (y);
+
+ xp = PTR (x);
+
+ /* since mpf numbers are represented in base 2^GMP_NUMB_BITS,
+ we loose -EXP(y) % GMP_NUMB_BITS bits in the most significant limb */
+ sh = MPFR_GET_EXP(y) % GMP_NUMB_BITS;
+ sh = sh <= 0 ? - sh : GMP_NUMB_BITS - sh;
+ MPFR_ASSERTD (sh >= 0);
+ if (precy + sh <= precx) /* we can copy directly */
+ {
+ mp_size_t ds;
+
+ MPFR_ASSERTN (sx >= sy);
+ ds = sx - sy;
+
+ if (sh != 0)
+ {
+ mp_limb_t out;
+ out = mpn_rshift (xp + ds, MPFR_MANT(y), sy, sh);
+ MPFR_ASSERTN (ds > 0 || out == 0);
+ if (ds > 0)
+ xp[--ds] = out;
+ }
+ else
+ MPN_COPY (xp + ds, MPFR_MANT (y), sy);
+ if (ds > 0)
+ MPN_ZERO (xp, ds);
+ EXP(x) = (MPFR_GET_EXP(y) + sh) / GMP_NUMB_BITS;
+ inex = 0;
+ }
+ else /* we have to round to precx - sh bits */
+ {
+ mpfr_t z;
+ mp_size_t sz;
+
+ /* Recall that precx = (mpfr_prec_t) sx * GMP_NUMB_BITS, thus removing
+ sh bits (sh < GMP_NUMB_BITSS) won't reduce the number of limbs. */
+ mpfr_init2 (z, precx - sh);
+ sz = MPFR_LIMB_SIZE (z);
+ MPFR_ASSERTN (sx == sz);
+
+ inex = mpfr_set (z, y, rnd_mode);
+ /* warning, sh may change due to rounding, but then z is a power of two,
+ thus we can safely ignore its last bit which is 0 */
+ sh = MPFR_GET_EXP(z) % GMP_NUMB_BITS;
+ sh = sh <= 0 ? - sh : GMP_NUMB_BITS - sh;
+ MPFR_ASSERTD (sh >= 0);
+ if (sh != 0)
+ {
+ mp_limb_t out;
+ out = mpn_rshift (xp, MPFR_MANT(z), sz, sh);
+ /* If sh hasn't changed, it is the number of the non-significant
+ bits in the lowest limb of z. Therefore out == 0. */
+ MPFR_ASSERTD (out == 0); (void) out; /* avoid a warning */
+ }
+ else
+ MPN_COPY (xp, MPFR_MANT(z), sz);
+ EXP(x) = (MPFR_GET_EXP(z) + sh) / GMP_NUMB_BITS;
+ mpfr_clear (z);
+ }
+
+ /* set size and sign */
+ SIZ(x) = (MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(y)) < 0) ? -sx : sx;
+
+ return inex;
+}
diff --git a/mpfr/src/get_flt.c b/mpfr/src/get_flt.c
new file mode 100644
index 0000000000..411e3c7594
--- /dev/null
+++ b/mpfr/src/get_flt.c
@@ -0,0 +1,123 @@
+/* mpfr_get_flt -- convert a mpfr_t to a machine single precision float
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <float.h> /* for FLT_MIN */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#include "ieee_floats.h"
+
+#define FLT_NEG_ZERO ((float) DBL_NEG_ZERO)
+#define MPFR_FLT_INFM ((float) MPFR_DBL_INFM)
+#define MPFR_FLT_INFP ((float) MPFR_DBL_INFP)
+
+float
+mpfr_get_flt (mpfr_srcptr src, mpfr_rnd_t rnd_mode)
+{
+ int negative;
+ mpfr_exp_t e;
+ float d;
+
+ /* in case of NaN, +Inf, -Inf, +0, -0, the conversion from double to float
+ is exact */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (src)))
+ return (float) mpfr_get_d (src, rnd_mode);
+
+ e = MPFR_GET_EXP (src);
+ negative = MPFR_IS_NEG (src);
+
+ if (MPFR_UNLIKELY(rnd_mode == MPFR_RNDA))
+ rnd_mode = negative ? MPFR_RNDD : MPFR_RNDU;
+
+ /* the smallest positive normal float number is 2^(-126) = 0.5*2^(-125),
+ and the smallest positive subnormal number is 2^(-149) = 0.5*2^(-148) */
+ if (MPFR_UNLIKELY (e < -148))
+ {
+ /* |src| < 2^(-149), i.e., |src| is smaller than the smallest positive
+ subnormal number.
+ In round-to-nearest mode, 2^(-150) is rounded to zero.
+ */
+ d = negative ?
+ (rnd_mode == MPFR_RNDD ||
+ (rnd_mode == MPFR_RNDN && mpfr_cmp_si_2exp (src, -1, -150) < 0)
+ ? -FLT_MIN : FLT_NEG_ZERO) :
+ (rnd_mode == MPFR_RNDU ||
+ (rnd_mode == MPFR_RNDN && mpfr_cmp_si_2exp (src, 1, -150) > 0)
+ ? FLT_MIN : 0.0);
+ if (d != 0.0) /* we multiply FLT_MIN = 2^(-126) by FLT_EPSILON = 2^(-23)
+ to get +-2^(-149) */
+ d *= FLT_EPSILON;
+ }
+ /* the largest normal number is 2^128*(1-2^(-24)) = 0.111...111e128 */
+ else if (MPFR_UNLIKELY (e > 128))
+ {
+ d = negative ?
+ (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDU ?
+ -FLT_MAX : MPFR_FLT_INFM) :
+ (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDD ?
+ FLT_MAX : MPFR_FLT_INFP);
+ }
+ else /* -148 <= e <= 127 */
+ {
+ int nbits;
+ mp_size_t np, i;
+ mp_limb_t tp[MPFR_LIMBS_PER_FLT];
+ int carry;
+ double dd;
+
+ nbits = IEEE_FLT_MANT_DIG; /* 24 */
+ if (MPFR_UNLIKELY (e < -125))
+ /*In the subnormal case, compute the exact number of significant bits*/
+ {
+ nbits += (125 + e);
+ MPFR_ASSERTD (nbits >= 1);
+ }
+ np = MPFR_PREC2LIMBS (nbits);
+ MPFR_ASSERTD(np <= MPFR_LIMBS_PER_FLT);
+ carry = mpfr_round_raw_4 (tp, MPFR_MANT(src), MPFR_PREC(src), negative,
+ nbits, rnd_mode);
+ /* we perform the reconstruction using the 'double' type here,
+ knowing the result is exactly representable as 'float' */
+ if (MPFR_UNLIKELY(carry))
+ dd = 1.0;
+ else
+ {
+ /* The following computations are exact thanks to the previous
+ mpfr_round_raw. */
+ dd = (double) tp[0] / MP_BASE_AS_DOUBLE;
+ for (i = 1 ; i < np ; i++)
+ dd = (dd + tp[i]) / MP_BASE_AS_DOUBLE;
+ /* dd is the mantissa (between 1/2 and 1) of the argument rounded
+ to 24 bits */
+ }
+ dd = mpfr_scale2 (dd, e);
+ if (negative)
+ dd = -dd;
+
+ /* convert (exacly) to float */
+ d = (float) dd;
+ }
+
+ return d;
+}
+
diff --git a/mpfr/src/get_ld.c b/mpfr/src/get_ld.c
new file mode 100644
index 0000000000..146c516613
--- /dev/null
+++ b/mpfr/src/get_ld.c
@@ -0,0 +1,222 @@
+/* mpfr_get_ld, mpfr_get_ld_2exp -- convert a multiple precision floating-point
+ number to a machine long double
+
+Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <float.h>
+
+#include "mpfr-impl.h"
+
+#ifndef HAVE_LDOUBLE_IEEE_EXT_LITTLE
+
+long double
+mpfr_get_ld (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return (long double) mpfr_get_d (x, rnd_mode);
+ else /* now x is a normal non-zero number */
+ {
+ long double r; /* result */
+ long double m;
+ double s; /* part of result */
+ mpfr_exp_t sh; /* exponent shift, so that x/2^sh is in the double range */
+ mpfr_t y, z;
+ int sign;
+
+ /* first round x to the target long double precision, so that
+ all subsequent operations are exact (this avoids double rounding
+ problems) */
+ mpfr_init2 (y, MPFR_LDBL_MANT_DIG);
+ mpfr_init2 (z, MPFR_LDBL_MANT_DIG);
+ /* Note about the precision of z: even though IEEE_DBL_MANT_DIG is
+ sufficient, z has been set to the same precision as y so that
+ the mpfr_sub below calls mpfr_sub1sp, which is faster than the
+ generic subtraction, even in this particular case (from tests
+ done by Patrick Pelissier on a 64-bit Core2 Duo against r7285).
+ But here there is an important cancellation in the subtraction.
+ TODO: get more information about what has been tested. */
+
+ mpfr_set (y, x, rnd_mode);
+ sh = MPFR_GET_EXP (y);
+ sign = MPFR_SIGN (y);
+ MPFR_SET_EXP (y, 0);
+ MPFR_SET_POS (y);
+
+ r = 0.0;
+ do {
+ s = mpfr_get_d (y, MPFR_RNDN); /* high part of y */
+ r += (long double) s;
+ mpfr_set_d (z, s, MPFR_RNDN); /* exact */
+ mpfr_sub (y, y, z, MPFR_RNDN); /* exact */
+ } while (!MPFR_IS_ZERO (y));
+
+ mpfr_clear (z);
+ mpfr_clear (y);
+
+ /* we now have to multiply back by 2^sh */
+ MPFR_ASSERTD (r > 0);
+ if (sh != 0)
+ {
+ /* An overflow may occurs (example: 0.5*2^1024) */
+ while (r < 1.0)
+ {
+ r += r;
+ sh--;
+ }
+
+ if (sh > 0)
+ m = 2.0;
+ else
+ {
+ m = 0.5;
+ sh = -sh;
+ }
+
+ for (;;)
+ {
+ if (sh % 2)
+ r = r * m;
+ sh >>= 1;
+ if (sh == 0)
+ break;
+ m = m * m;
+ }
+ }
+ if (sign < 0)
+ r = -r;
+ return r;
+ }
+}
+
+#else
+
+long double
+mpfr_get_ld (mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_long_double_t ld;
+ mpfr_t tmp;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (tmp, MPFR_LDBL_MANT_DIG);
+ inex = mpfr_set (tmp, x, rnd_mode);
+
+ mpfr_set_emin (-16382-63);
+ mpfr_set_emax (16384);
+ mpfr_subnormalize (tmp, mpfr_check_range (tmp, inex, rnd_mode), rnd_mode);
+ mpfr_prec_round (tmp, 64, MPFR_RNDZ); /* exact */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (tmp)))
+ ld.ld = (long double) mpfr_get_d (tmp, rnd_mode);
+ else
+ {
+ mp_limb_t *tmpmant;
+ mpfr_exp_t e, denorm;
+
+ tmpmant = MPFR_MANT (tmp);
+ e = MPFR_GET_EXP (tmp);
+ /* the smallest normal number is 2^(-16382), which is 0.5*2^(-16381)
+ in MPFR, thus any exponent <= -16382 corresponds to a subnormal
+ number */
+ denorm = MPFR_UNLIKELY (e <= -16382) ? - e - 16382 + 1 : 0;
+#if GMP_NUMB_BITS >= 64
+ ld.s.manl = (tmpmant[0] >> denorm);
+ ld.s.manh = (tmpmant[0] >> denorm) >> 32;
+#elif GMP_NUMB_BITS == 32
+ if (MPFR_LIKELY (denorm == 0))
+ {
+ ld.s.manl = tmpmant[0];
+ ld.s.manh = tmpmant[1];
+ }
+ else if (denorm < 32)
+ {
+ ld.s.manl = (tmpmant[0] >> denorm) | (tmpmant[1] << (32 - denorm));
+ ld.s.manh = tmpmant[1] >> denorm;
+ }
+ else /* 32 <= denorm <= 64 */
+ {
+ ld.s.manl = tmpmant[1] >> (denorm - 32);
+ ld.s.manh = 0;
+ }
+#else
+# error "GMP_NUMB_BITS must be 32 or >= 64"
+ /* Other values have never been supported anyway. */
+#endif
+ if (MPFR_LIKELY (denorm == 0))
+ {
+ ld.s.exph = (e + 0x3FFE) >> 8;
+ ld.s.expl = (e + 0x3FFE);
+ }
+ else
+ ld.s.exph = ld.s.expl = 0;
+ ld.s.sign = MPFR_IS_NEG (x);
+ }
+
+ mpfr_clear (tmp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return ld.ld;
+}
+
+#endif
+
+/* contributed by Damien Stehle */
+long double
+mpfr_get_ld_2exp (long *expptr, mpfr_srcptr src, mpfr_rnd_t rnd_mode)
+{
+ long double ret;
+ mpfr_exp_t exp;
+ mpfr_t tmp;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (src)))
+ return (long double) mpfr_get_d_2exp (expptr, src, rnd_mode);
+
+ tmp[0] = *src; /* Hack copy mpfr_t */
+ MPFR_SET_EXP (tmp, 0);
+ ret = mpfr_get_ld (tmp, rnd_mode);
+
+ if (MPFR_IS_PURE_FP(src))
+ {
+ exp = MPFR_GET_EXP (src);
+
+ /* rounding can give 1.0, adjust back to 0.5 <= abs(ret) < 1.0 */
+ if (ret == 1.0)
+ {
+ ret = 0.5;
+ exp ++;
+ }
+ else if (ret == -1.0)
+ {
+ ret = -0.5;
+ exp ++;
+ }
+
+ MPFR_ASSERTN ((ret >= 0.5 && ret < 1.0)
+ || (ret <= -0.5 && ret > -1.0));
+ MPFR_ASSERTN (exp >= LONG_MIN && exp <= LONG_MAX);
+ }
+ else
+ exp = 0;
+
+ *expptr = exp;
+ return ret;
+}
diff --git a/mpfr/src/get_patches.c b/mpfr/src/get_patches.c
new file mode 100644
index 0000000000..ac9f6ae753
--- /dev/null
+++ b/mpfr/src/get_patches.c
@@ -0,0 +1,29 @@
+/* mpfr_get_patches -- Patches that have been applied
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+const char *
+mpfr_get_patches (void)
+{
+ return "";
+}
diff --git a/mpfr/src/get_si.c b/mpfr/src/get_si.c
new file mode 100644
index 0000000000..f2b2762ebd
--- /dev/null
+++ b/mpfr/src/get_si.c
@@ -0,0 +1,69 @@
+/* mpfr_get_si -- convert a floating-point number to a signed long.
+
+Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+long
+mpfr_get_si (mpfr_srcptr f, mpfr_rnd_t rnd)
+{
+ mpfr_prec_t prec;
+ long s;
+ mpfr_t x;
+
+ if (MPFR_UNLIKELY (!mpfr_fits_slong_p (f, rnd)))
+ {
+ MPFR_SET_ERANGE ();
+ return MPFR_IS_NAN (f) ? 0 :
+ MPFR_IS_NEG (f) ? LONG_MIN : LONG_MAX;
+ }
+
+ if (MPFR_IS_ZERO (f))
+ return (long) 0;
+
+ /* determine prec of long */
+ for (s = LONG_MIN, prec = 0; s != 0; s /= 2, prec++)
+ { }
+
+ /* first round to prec bits */
+ mpfr_init2 (x, prec);
+ mpfr_rint (x, f, rnd);
+
+ /* warning: if x=0, taking its exponent is illegal */
+ if (MPFR_UNLIKELY (MPFR_IS_ZERO(x)))
+ s = 0;
+ else
+ {
+ mp_limb_t a;
+ mp_size_t n;
+ mpfr_exp_t exp;
+
+ /* now the result is in the most significant limb of x */
+ exp = MPFR_GET_EXP (x); /* since |x| >= 1, exp >= 1 */
+ n = MPFR_LIMB_SIZE(x);
+ a = MPFR_MANT(x)[n - 1] >> (GMP_NUMB_BITS - exp);
+ s = MPFR_SIGN(f) > 0 ? a : a <= LONG_MAX ? - (long) a : LONG_MIN;
+ }
+
+ mpfr_clear (x);
+
+ return s;
+}
diff --git a/mpfr/src/get_sj.c b/mpfr/src/get_sj.c
new file mode 100644
index 0000000000..528f42158f
--- /dev/null
+++ b/mpfr/src/get_sj.c
@@ -0,0 +1,123 @@
+/* mpfr_get_sj -- convert a MPFR number to a huge machine signed integer
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+#endif
+
+#include "mpfr-intmax.h"
+#include "mpfr-impl.h"
+
+#ifdef _MPFR_H_HAVE_INTMAX_T
+
+intmax_t
+mpfr_get_sj (mpfr_srcptr f, mpfr_rnd_t rnd)
+{
+ intmax_t r;
+ mpfr_prec_t prec;
+ mpfr_t x;
+
+ if (MPFR_UNLIKELY (!mpfr_fits_intmax_p (f, rnd)))
+ {
+ MPFR_SET_ERANGE ();
+ return MPFR_IS_NAN (f) ? 0 :
+ MPFR_IS_NEG (f) ? MPFR_INTMAX_MIN : MPFR_INTMAX_MAX;
+ }
+
+ if (MPFR_IS_ZERO (f))
+ return (intmax_t) 0;
+
+ /* determine the precision of intmax_t */
+ for (r = MPFR_INTMAX_MIN, prec = 0; r != 0; r /= 2, prec++)
+ { }
+ /* Note: though INTMAX_MAX would have been sufficient for the conversion,
+ we chose INTMAX_MIN so that INTMAX_MIN - 1 is always representable in
+ precision prec; this is useful to detect overflows in MPFR_RNDZ (will
+ be needed later). */
+
+ /* Now, r = 0. */
+
+ mpfr_init2 (x, prec);
+ mpfr_rint (x, f, rnd);
+ MPFR_ASSERTN (MPFR_IS_FP (x));
+
+ if (MPFR_NOTZERO (x))
+ {
+ mp_limb_t *xp;
+ int sh, n; /* An int should be sufficient in this context. */
+
+ xp = MPFR_MANT (x);
+ sh = MPFR_GET_EXP (x);
+ MPFR_ASSERTN ((mpfr_prec_t) sh <= prec);
+ if (MPFR_INTMAX_MIN + MPFR_INTMAX_MAX != 0
+ && MPFR_UNLIKELY ((mpfr_prec_t) sh == prec))
+ {
+ /* 2's complement and x <= INTMAX_MIN: in the case mp_limb_t
+ has the same size as intmax_t, we cannot use the code in
+ the for loop since the operations would be performed in
+ unsigned arithmetic. */
+ MPFR_ASSERTN (MPFR_IS_NEG (x) && (mpfr_powerof2_raw (x)));
+ r = MPFR_INTMAX_MIN;
+ }
+ else if (MPFR_IS_POS (x))
+ {
+ /* Note: testing the condition sh >= 0 is necessary to avoid
+ an undefined behavior on xp[n] >> S when S >= GMP_NUMB_BITS
+ (even though xp[n] == 0 in such a case). This can happen if
+ sizeof(mp_limb_t) < sizeof(intmax_t) and |x| is small enough
+ because of the trailing bits due to its normalization. */
+ for (n = MPFR_LIMB_SIZE (x) - 1; n >= 0 && sh >= 0; n--)
+ {
+ sh -= GMP_NUMB_BITS;
+ /* Note the concerning the casts below:
+ When sh >= 0, the cast must be performed before the shift
+ for the case sizeof(intmax_t) > sizeof(mp_limb_t).
+ When sh < 0, the cast must be performed after the shift
+ for the case sizeof(intmax_t) == sizeof(mp_limb_t), as
+ mp_limb_t is unsigned, therefore not representable as an
+ intmax_t when the MSB is 1 (this is the case here). */
+ MPFR_ASSERTD (sh < GMP_NUMB_BITS && -sh < GMP_NUMB_BITS);
+ r += (sh >= 0
+ ? (intmax_t) xp[n] << sh
+ : (intmax_t) (xp[n] >> (-sh)));
+ }
+ }
+ else
+ {
+ /* See the comments for the case x positive. */
+ for (n = MPFR_LIMB_SIZE (x) - 1; n >= 0 && sh >= 0; n--)
+ {
+ sh -= GMP_NUMB_BITS;
+ MPFR_ASSERTD (sh < GMP_NUMB_BITS && -sh < GMP_NUMB_BITS);
+ r -= (sh >= 0
+ ? (intmax_t) xp[n] << sh
+ : (intmax_t) (xp[n] >> (-sh)));
+ }
+ }
+ }
+
+ mpfr_clear (x);
+
+ return r;
+}
+
+#endif
diff --git a/mpfr/src/get_str.c b/mpfr/src/get_str.c
new file mode 100644
index 0000000000..b907aa6644
--- /dev/null
+++ b/mpfr/src/get_str.c
@@ -0,0 +1,2555 @@
+/* mpfr_get_str -- output a floating-point number to a string
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+static int mpfr_get_str_aux (char *const, mpfr_exp_t *const, mp_limb_t *const,
+ mp_size_t, mpfr_exp_t, long, int, size_t, mpfr_rnd_t);
+
+/* The implicit \0 is useless, but we do not write num_to_text[62] otherwise
+ g++ complains. */
+static const char num_to_text36[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+static const char num_to_text62[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+
+/* copy most important limbs of {op, n2} in {rp, n1} */
+/* if n1 > n2 put 0 in low limbs of {rp, n1} */
+#define MPN_COPY2(rp, n1, op, n2) \
+ if ((n1) <= (n2)) \
+ { \
+ MPN_COPY ((rp), (op) + (n2) - (n1), (n1)); \
+ } \
+ else \
+ { \
+ MPN_COPY ((rp) + (n1) - (n2), (op), (n2)); \
+ MPN_ZERO ((rp), (n1) - (n2)); \
+ }
+
+#define MPFR_ROUND_FAILED 3
+
+/* Input: an approximation r*2^f of a real Y, with |r*2^f-Y| <= 2^(e+f).
+ Returns if possible in the string s the mantissa corresponding to
+ the integer nearest to Y, within the direction rnd, and returns the
+ exponent in exp.
+ n is the number of limbs of r.
+ e represents the maximal error in the approximation of Y
+ (e < 0 iff the approximation is exact, i.e., r*2^f = Y).
+ b is the wanted base (2 <= b <= 62).
+ m is the number of wanted digits in the mantissa.
+ rnd is the rounding mode.
+ It is assumed that b^(m-1) <= Y < b^(m+1), thus the returned value
+ satisfies b^(m-1) <= rnd(Y) < b^(m+1).
+
+ Rounding may fail for two reasons:
+ - the error is too large to determine the integer N nearest to Y
+ - either the number of digits of N in base b is too large (m+1),
+ N=2*N1+(b/2) and the rounding mode is to nearest. This can
+ only happen when b is even.
+
+ Return value:
+ - the direction of rounding (-1, 0, 1) if rounding is possible
+ - -MPFR_ROUND_FAILED if rounding not possible because m+1 digits
+ - MPFR_ROUND_FAILED otherwise (too large error)
+*/
+static int
+mpfr_get_str_aux (char *const str, mpfr_exp_t *const exp, mp_limb_t *const r,
+ mp_size_t n, mpfr_exp_t f, long e, int b, size_t m,
+ mpfr_rnd_t rnd)
+{
+ const char *num_to_text;
+ int dir; /* direction of the rounded result */
+ mp_limb_t ret = 0; /* possible carry in addition */
+ mp_size_t i0, j0; /* number of limbs and bits of Y */
+ unsigned char *str1; /* string of m+2 characters */
+ size_t size_s1; /* length of str1 */
+ mpfr_rnd_t rnd1;
+ size_t i;
+ int exact = (e < 0);
+ MPFR_TMP_DECL(marker);
+
+ /* if f > 0, then the maximal error 2^(e+f) is larger than 2 so we can't
+ determine the integer Y */
+ MPFR_ASSERTN(f <= 0);
+ /* if f is too small, then r*2^f is smaller than 1 */
+ MPFR_ASSERTN(f > (-n * GMP_NUMB_BITS));
+
+ MPFR_TMP_MARK(marker);
+
+ num_to_text = b < 37 ? num_to_text36 : num_to_text62;
+
+ /* R = 2^f sum r[i]K^(i)
+ r[i] = (r_(i,k-1)...r_(i,0))_2
+ R = sum r(i,j)2^(j+ki+f)
+ the bits from R are referenced by pairs (i,j) */
+
+ /* check if is possible to round r with rnd mode
+ where |r*2^f-Y| <= 2^(e+f)
+ the exponent of R is: f + n*GMP_NUMB_BITS
+ we must have e + f == f + n*GMP_NUMB_BITS - err
+ err = n*GMP_NUMB_BITS - e
+ R contains exactly -f bits after the integer point:
+ to determine the nearest integer, we thus need a precision of
+ n * GMP_NUMB_BITS + f */
+
+ if (exact || mpfr_can_round_raw (r, n, (mp_size_t) 1,
+ n * GMP_NUMB_BITS - e, MPFR_RNDN, rnd, n * GMP_NUMB_BITS + f))
+ {
+ /* compute the nearest integer to R */
+
+ /* bit of weight 0 in R has position j0 in limb r[i0] */
+ i0 = (-f) / GMP_NUMB_BITS;
+ j0 = (-f) % GMP_NUMB_BITS;
+
+ ret = mpfr_round_raw (r + i0, r, n * GMP_NUMB_BITS, 0,
+ n * GMP_NUMB_BITS + f, rnd, &dir);
+ MPFR_ASSERTD(dir != MPFR_ROUND_FAILED);
+
+ /* warning: mpfr_round_raw_generic returns MPFR_EVEN_INEX (2) or
+ -MPFR_EVEN_INEX (-2) in case of even rounding */
+
+ if (ret) /* Y is a power of 2 */
+ {
+ if (j0)
+ r[n - 1] = MPFR_LIMB_HIGHBIT >> (j0 - 1);
+ else /* j0=0, necessarily i0 >= 1 otherwise f=0 and r is exact */
+ {
+ r[n - 1] = ret;
+ r[--i0] = 0; /* set to zero the new low limb */
+ }
+ }
+ else /* shift r to the right by (-f) bits (i0 already done) */
+ {
+ if (j0)
+ mpn_rshift (r + i0, r + i0, n - i0, j0);
+ }
+
+ /* now the rounded value Y is in {r+i0, n-i0} */
+
+ /* convert r+i0 into base b */
+ str1 = (unsigned char*) MPFR_TMP_ALLOC (m + 3); /* need one extra character for mpn_get_str */
+ size_s1 = mpn_get_str (str1, b, r + i0, n - i0);
+
+ /* round str1 */
+ MPFR_ASSERTN(size_s1 >= m);
+ *exp = size_s1 - m; /* number of superfluous characters */
+
+ /* if size_s1 = m + 2, necessarily we have b^(m+1) as result,
+ and the result will not change */
+
+ /* so we have to double-round only when size_s1 = m + 1 and
+ (i) the result is inexact
+ (ii) or the last digit is non-zero */
+ if ((size_s1 == m + 1) && ((dir != 0) || (str1[size_s1 - 1] != 0)))
+ {
+ /* rounding mode */
+ rnd1 = rnd;
+
+ /* round to nearest case */
+ if (rnd == MPFR_RNDN)
+ {
+ if (2 * str1[size_s1 - 1] == b)
+ {
+ if (dir == 0 && exact) /* exact: even rounding */
+ {
+ rnd1 = ((str1[size_s1 - 2] & 1) == 0)
+ ? MPFR_RNDD : MPFR_RNDU;
+ }
+ else
+ {
+ /* otherwise we cannot round correctly: for example
+ if b=10, we might have a mantissa of
+ xxxxxxx5.00000000 which can be rounded to nearest
+ to 8 digits but not to 7 */
+ dir = -MPFR_ROUND_FAILED;
+ MPFR_ASSERTD(dir != MPFR_EVEN_INEX);
+ goto free_and_return;
+ }
+ }
+ else if (2 * str1[size_s1 - 1] < b)
+ rnd1 = MPFR_RNDD;
+ else
+ rnd1 = MPFR_RNDU;
+ }
+
+ /* now rnd1 is either
+ MPFR_RNDD or MPFR_RNDZ -> truncate, or
+ MPFR_RNDU or MPFR_RNDA -> round toward infinity */
+
+ /* round away from zero */
+ if (rnd1 == MPFR_RNDU || rnd1 == MPFR_RNDA)
+ {
+ if (str1[size_s1 - 1] != 0)
+ {
+ /* the carry cannot propagate to the whole string, since
+ Y = x*b^(m-g) < 2*b^m <= b^(m+1)-b
+ where x is the input float */
+ MPFR_ASSERTN(size_s1 >= 2);
+ i = size_s1 - 2;
+ while (str1[i] == b - 1)
+ {
+ MPFR_ASSERTD(i > 0);
+ str1[i--] = 0;
+ }
+ str1[i]++;
+ }
+ dir = 1;
+ }
+ /* round toward zero (truncate) */
+ else
+ dir = -1;
+ }
+
+ /* copy str1 into str and convert to characters (digits and
+ lowercase letters from the source character set) */
+ for (i = 0; i < m; i++)
+ str[i] = num_to_text[(int) str1[i]]; /* str1[i] is an unsigned char */
+ str[m] = 0;
+ }
+ /* mpfr_can_round_raw failed: rounding is not possible */
+ else
+ {
+ dir = MPFR_ROUND_FAILED; /* should be different from MPFR_EVEN_INEX */
+ MPFR_ASSERTD(dir != MPFR_EVEN_INEX);
+ }
+
+ free_and_return:
+ MPFR_TMP_FREE(marker);
+
+ return dir;
+}
+
+/***************************************************************************
+ * __gmpfr_l2b[b-2][0] is a 23-bit upper approximation to log(b)/log(2), *
+ * __gmpfr_l2b[b-2][1] is a 76-bit upper approximation to log(2)/log(b). *
+ * The following code is generated by tests/tl2b (with an argument). *
+ ***************************************************************************/
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x0000, 0x8000 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x80000000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x8000000000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x800000000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x80000000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_2_0__tab[] = { 0x8000000000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x8000 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x00000000, 0x00000000, 0x80000000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x0000000000000000, 0x8000000000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x800000000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x80000000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_2_1__tab[] = { 0x8000000000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_3_0__tab[] = { 0x0e00, 0xcae0 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_3_0__tab[] = { 0xcae00e00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_3_0__tab[] = { 0xcae00e0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_3_0__tab[] = { 0xcae00e000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_3_0__tab[] = { 0xcae00e00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_3_0__tab[] = { 0xcae00e0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_3_1__tab[] = { 0x0448, 0xe94e, 0xa9a9, 0x9cc1, 0xa184 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_3_1__tab[] = { 0x04480000, 0xa9a9e94e, 0xa1849cc1 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_3_1__tab[] = { 0x0448000000000000, 0xa1849cc1a9a9e94e };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_3_1__tab[] = { 0xa1849cc1a9a9e94e04480000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_3_1__tab[] = { 0xa1849cc1a9a9e94e0448000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_3_1__tab[] = { 0xa1849cc1a9a9e94e044800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x0000, 0x8000 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x80000000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x8000000000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x800000000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x80000000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_4_0__tab[] = { 0x8000000000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x8000 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x00000000, 0x00000000, 0x80000000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x0000000000000000, 0x8000000000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x800000000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x80000000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_4_1__tab[] = { 0x8000000000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x7a00, 0x949a };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x949a7a00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x949a7a0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x949a7a000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x949a7a00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_5_0__tab[] = { 0x949a7a0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_5_1__tab[] = { 0x67b8, 0x9728, 0x287b, 0xa348, 0xdc81 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_5_1__tab[] = { 0x67b80000, 0x287b9728, 0xdc81a348 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_5_1__tab[] = { 0x67b8000000000000, 0xdc81a348287b9728 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_5_1__tab[] = { 0xdc81a348287b972867b80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_5_1__tab[] = { 0xdc81a348287b972867b8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_5_1__tab[] = { 0xdc81a348287b972867b800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_6_0__tab[] = { 0x0800, 0xa570 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_6_0__tab[] = { 0xa5700800 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_6_0__tab[] = { 0xa570080000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_6_0__tab[] = { 0xa57008000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_6_0__tab[] = { 0xa5700800000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_6_0__tab[] = { 0xa570080000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xff10, 0xf9e9, 0xe054, 0x9236, 0xc611 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xff100000, 0xe054f9e9, 0xc6119236 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xff10000000000000, 0xc6119236e054f9e9 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xc6119236e054f9e9ff100000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xc6119236e054f9e9ff10000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_6_1__tab[] = { 0xc6119236e054f9e9ff1000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb400, 0xb3ab };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb3abb400 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb3abb40000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb3abb4000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb3abb400000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_7_0__tab[] = { 0xb3abb40000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_7_1__tab[] = { 0x37b8, 0xa711, 0x754d, 0xc9d6, 0xb660 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_7_1__tab[] = { 0x37b80000, 0x754da711, 0xb660c9d6 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_7_1__tab[] = { 0x37b8000000000000, 0xb660c9d6754da711 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_7_1__tab[] = { 0xb660c9d6754da71137b80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_7_1__tab[] = { 0xb660c9d6754da71137b8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_7_1__tab[] = { 0xb660c9d6754da71137b800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_8_0__tab[] = { 0x0000, 0xc000 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_8_0__tab[] = { 0xc0000000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_8_0__tab[] = { 0xc000000000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_8_0__tab[] = { 0xc00000000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_8_0__tab[] = { 0xc0000000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_8_0__tab[] = { 0xc000000000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaab0, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaab00000, 0xaaaaaaaa, 0xaaaaaaaa };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaab0000000000000, 0xaaaaaaaaaaaaaaaa };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaaaaaaaaaaaaaaaaaab00000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaaaaaaaaaaaaaaaaaab0000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_8_1__tab[] = { 0xaaaaaaaaaaaaaaaaaab000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_9_0__tab[] = { 0x0e00, 0xcae0 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_9_0__tab[] = { 0xcae00e00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_9_0__tab[] = { 0xcae00e0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_9_0__tab[] = { 0xcae00e000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_9_0__tab[] = { 0xcae00e00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_9_0__tab[] = { 0xcae00e0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_9_1__tab[] = { 0x0448, 0xe94e, 0xa9a9, 0x9cc1, 0xa184 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_9_1__tab[] = { 0x04480000, 0xa9a9e94e, 0xa1849cc1 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_9_1__tab[] = { 0x0448000000000000, 0xa1849cc1a9a9e94e };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_9_1__tab[] = { 0xa1849cc1a9a9e94e04480000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_9_1__tab[] = { 0xa1849cc1a9a9e94e0448000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_9_1__tab[] = { 0xa1849cc1a9a9e94e044800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_10_0__tab[] = { 0x7a00, 0xd49a };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_10_0__tab[] = { 0xd49a7a00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_10_0__tab[] = { 0xd49a7a0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_10_0__tab[] = { 0xd49a7a000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_10_0__tab[] = { 0xd49a7a00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_10_0__tab[] = { 0xd49a7a0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x8f90, 0xf798, 0xfbcf, 0x9a84, 0x9a20 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x8f900000, 0xfbcff798, 0x9a209a84 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x8f90000000000000, 0x9a209a84fbcff798 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x9a209a84fbcff7988f900000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x9a209a84fbcff7988f90000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_10_1__tab[] = { 0x9a209a84fbcff7988f9000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_11_0__tab[] = { 0x5400, 0xdd67 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_11_0__tab[] = { 0xdd675400 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_11_0__tab[] = { 0xdd67540000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_11_0__tab[] = { 0xdd6754000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_11_0__tab[] = { 0xdd675400000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_11_0__tab[] = { 0xdd67540000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_11_1__tab[] = { 0xe170, 0x9d10, 0xeb22, 0x4e0e, 0x9400 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_11_1__tab[] = { 0xe1700000, 0xeb229d10, 0x94004e0e };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_11_1__tab[] = { 0xe170000000000000, 0x94004e0eeb229d10 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_11_1__tab[] = { 0x94004e0eeb229d10e1700000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_11_1__tab[] = { 0x94004e0eeb229d10e170000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_11_1__tab[] = { 0x94004e0eeb229d10e17000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_12_0__tab[] = { 0x0800, 0xe570 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_12_0__tab[] = { 0xe5700800 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_12_0__tab[] = { 0xe570080000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_12_0__tab[] = { 0xe57008000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_12_0__tab[] = { 0xe5700800000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_12_0__tab[] = { 0xe570080000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_12_1__tab[] = { 0xfe28, 0x1c24, 0x0b03, 0x9c1a, 0x8ed1 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_12_1__tab[] = { 0xfe280000, 0x0b031c24, 0x8ed19c1a };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_12_1__tab[] = { 0xfe28000000000000, 0x8ed19c1a0b031c24 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_12_1__tab[] = { 0x8ed19c1a0b031c24fe280000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_12_1__tab[] = { 0x8ed19c1a0b031c24fe28000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_12_1__tab[] = { 0x8ed19c1a0b031c24fe2800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_13_0__tab[] = { 0x0200, 0xecd4 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_13_0__tab[] = { 0xecd40200 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_13_0__tab[] = { 0xecd4020000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_13_0__tab[] = { 0xecd402000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_13_0__tab[] = { 0xecd40200000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_13_0__tab[] = { 0xecd4020000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x57f8, 0xf7b4, 0xcb20, 0xa7c6, 0x8a5c };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x57f80000, 0xcb20f7b4, 0x8a5ca7c6 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x57f8000000000000, 0x8a5ca7c6cb20f7b4 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x8a5ca7c6cb20f7b457f80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x8a5ca7c6cb20f7b457f8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_13_1__tab[] = { 0x8a5ca7c6cb20f7b457f800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xb400, 0xf3ab };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xf3abb400 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xf3abb40000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xf3abb4000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xf3abb400000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_14_0__tab[] = { 0xf3abb40000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x85a8, 0x5cab, 0x96b5, 0xfff6, 0x8679 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x85a80000, 0x96b55cab, 0x8679fff6 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x85a8000000000000, 0x8679fff696b55cab };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x8679fff696b55cab85a80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x8679fff696b55cab85a8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_14_1__tab[] = { 0x8679fff696b55cab85a800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_15_0__tab[] = { 0x8000, 0xfa0a };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_15_0__tab[] = { 0xfa0a8000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_15_0__tab[] = { 0xfa0a800000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_15_0__tab[] = { 0xfa0a80000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_15_0__tab[] = { 0xfa0a8000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_15_0__tab[] = { 0xfa0a800000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x6f80, 0xa6aa, 0x69f0, 0xee23, 0x830c };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x6f800000, 0x69f0a6aa, 0x830cee23 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x6f80000000000000, 0x830cee2369f0a6aa };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x830cee2369f0a6aa6f800000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x830cee2369f0a6aa6f80000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_15_1__tab[] = { 0x830cee2369f0a6aa6f8000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x0000, 0x8000 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x80000000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x8000000000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x800000000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x80000000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_16_0__tab[] = { 0x8000000000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x8000 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x00000000, 0x00000000, 0x80000000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x0000000000000000, 0x8000000000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x800000000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x80000000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_16_1__tab[] = { 0x8000000000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x8000, 0x82cc };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x82cc8000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x82cc800000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x82cc80000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x82cc8000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_17_0__tab[] = { 0x82cc800000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_17_1__tab[] = { 0x8720, 0x259b, 0x62c4, 0xabf5, 0xfa85 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_17_1__tab[] = { 0x87200000, 0x62c4259b, 0xfa85abf5 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_17_1__tab[] = { 0x8720000000000000, 0xfa85abf562c4259b };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_17_1__tab[] = { 0xfa85abf562c4259b87200000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_17_1__tab[] = { 0xfa85abf562c4259b8720000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_17_1__tab[] = { 0xfa85abf562c4259b872000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x0800, 0x8570 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x85700800 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x8570080000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x857008000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x85700800000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_18_0__tab[] = { 0x8570080000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_18_1__tab[] = { 0x3698, 0x1378, 0x5537, 0x6634, 0xf591 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_18_1__tab[] = { 0x36980000, 0x55371378, 0xf5916634 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_18_1__tab[] = { 0x3698000000000000, 0xf591663455371378 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_18_1__tab[] = { 0xf59166345537137836980000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_18_1__tab[] = { 0xf5916634553713783698000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_18_1__tab[] = { 0xf591663455371378369800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x0600, 0x87ef };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x87ef0600 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x87ef060000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x87ef06000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x87ef0600000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_19_0__tab[] = { 0x87ef060000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_19_1__tab[] = { 0x0db8, 0x558c, 0x62ed, 0x08c0, 0xf10f };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_19_1__tab[] = { 0x0db80000, 0x62ed558c, 0xf10f08c0 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_19_1__tab[] = { 0x0db8000000000000, 0xf10f08c062ed558c };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_19_1__tab[] = { 0xf10f08c062ed558c0db80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_19_1__tab[] = { 0xf10f08c062ed558c0db8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_19_1__tab[] = { 0xf10f08c062ed558c0db800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x3e00, 0x8a4d };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x8a4d3e00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x8a4d3e0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x8a4d3e000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x8a4d3e00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_20_0__tab[] = { 0x8a4d3e0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_20_1__tab[] = { 0x0b40, 0xa71c, 0x1cc1, 0x690a, 0xecee };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_20_1__tab[] = { 0x0b400000, 0x1cc1a71c, 0xecee690a };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_20_1__tab[] = { 0x0b40000000000000, 0xecee690a1cc1a71c };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_20_1__tab[] = { 0xecee690a1cc1a71c0b400000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_20_1__tab[] = { 0xecee690a1cc1a71c0b40000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_20_1__tab[] = { 0xecee690a1cc1a71c0b4000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_21_0__tab[] = { 0xde00, 0x8c8d };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_21_0__tab[] = { 0x8c8dde00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_21_0__tab[] = { 0x8c8dde0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_21_0__tab[] = { 0x8c8dde000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_21_0__tab[] = { 0x8c8dde00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_21_0__tab[] = { 0x8c8dde0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_21_1__tab[] = { 0x4108, 0x6b26, 0xb3d0, 0x63c1, 0xe922 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_21_1__tab[] = { 0x41080000, 0xb3d06b26, 0xe92263c1 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_21_1__tab[] = { 0x4108000000000000, 0xe92263c1b3d06b26 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_21_1__tab[] = { 0xe92263c1b3d06b2641080000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_21_1__tab[] = { 0xe92263c1b3d06b264108000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_21_1__tab[] = { 0xe92263c1b3d06b26410800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_22_0__tab[] = { 0xaa00, 0x8eb3 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_22_0__tab[] = { 0x8eb3aa00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_22_0__tab[] = { 0x8eb3aa0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_22_0__tab[] = { 0x8eb3aa000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_22_0__tab[] = { 0x8eb3aa00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_22_0__tab[] = { 0x8eb3aa0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xdbe8, 0xf061, 0x60b9, 0x2c4d, 0xe5a0 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xdbe80000, 0x60b9f061, 0xe5a02c4d };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xdbe8000000000000, 0xe5a02c4d60b9f061 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xe5a02c4d60b9f061dbe80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xe5a02c4d60b9f061dbe8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_22_1__tab[] = { 0xe5a02c4d60b9f061dbe800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x0600, 0x90c1 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x90c10600 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x90c1060000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x90c106000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x90c10600000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_23_0__tab[] = { 0x90c1060000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xc3e0, 0x586a, 0x46b9, 0xcadd, 0xe25e };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xc3e00000, 0x46b9586a, 0xe25ecadd };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xc3e0000000000000, 0xe25ecadd46b9586a };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xe25ecadd46b9586ac3e00000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xe25ecadd46b9586ac3e0000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_23_1__tab[] = { 0xe25ecadd46b9586ac3e000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x0400, 0x92b8 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x92b80400 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x92b8040000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x92b804000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x92b80400000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_24_0__tab[] = { 0x92b8040000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_24_1__tab[] = { 0x3668, 0x7263, 0xc7c6, 0xbb44, 0xdf56 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_24_1__tab[] = { 0x36680000, 0xc7c67263, 0xdf56bb44 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_24_1__tab[] = { 0x3668000000000000, 0xdf56bb44c7c67263 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_24_1__tab[] = { 0xdf56bb44c7c6726336680000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_24_1__tab[] = { 0xdf56bb44c7c672633668000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_24_1__tab[] = { 0xdf56bb44c7c67263366800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x7a00, 0x949a };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x949a7a00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x949a7a0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x949a7a000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x949a7a00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_25_0__tab[] = { 0x949a7a0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_25_1__tab[] = { 0x67b8, 0x9728, 0x287b, 0xa348, 0xdc81 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_25_1__tab[] = { 0x67b80000, 0x287b9728, 0xdc81a348 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_25_1__tab[] = { 0x67b8000000000000, 0xdc81a348287b9728 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_25_1__tab[] = { 0xdc81a348287b972867b80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_25_1__tab[] = { 0xdc81a348287b972867b8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_25_1__tab[] = { 0xdc81a348287b972867b800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x0200, 0x966a };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x966a0200 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x966a020000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x966a02000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x966a0200000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_26_0__tab[] = { 0x966a020000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_26_1__tab[] = { 0x6458, 0x78a4, 0x7583, 0x19f9, 0xd9da };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_26_1__tab[] = { 0x64580000, 0x758378a4, 0xd9da19f9 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_26_1__tab[] = { 0x6458000000000000, 0xd9da19f9758378a4 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_26_1__tab[] = { 0xd9da19f9758378a464580000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_26_1__tab[] = { 0xd9da19f9758378a46458000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_26_1__tab[] = { 0xd9da19f9758378a4645800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x0a00, 0x9828 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x98280a00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x98280a0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x98280a000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x98280a00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_27_0__tab[] = { 0x98280a0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_27_1__tab[] = { 0x5b08, 0xe1bd, 0xe237, 0x7bac, 0xd75b };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_27_1__tab[] = { 0x5b080000, 0xe237e1bd, 0xd75b7bac };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_27_1__tab[] = { 0x5b08000000000000, 0xd75b7bace237e1bd };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_27_1__tab[] = { 0xd75b7bace237e1bd5b080000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_27_1__tab[] = { 0xd75b7bace237e1bd5b08000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_27_1__tab[] = { 0xd75b7bace237e1bd5b0800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_28_0__tab[] = { 0xda00, 0x99d5 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_28_0__tab[] = { 0x99d5da00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_28_0__tab[] = { 0x99d5da0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_28_0__tab[] = { 0x99d5da000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_28_0__tab[] = { 0x99d5da00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_28_0__tab[] = { 0x99d5da0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xdeb8, 0xe8b8, 0x71df, 0xc758, 0xd501 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xdeb80000, 0x71dfe8b8, 0xd501c758 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xdeb8000000000000, 0xd501c75871dfe8b8 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xd501c75871dfe8b8deb80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xd501c75871dfe8b8deb8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_28_1__tab[] = { 0xd501c75871dfe8b8deb800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9600, 0x9b74 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9b749600 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9b74960000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9b7496000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9b749600000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_29_0__tab[] = { 0x9b74960000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xccc8, 0x62b3, 0x9c6c, 0x8315, 0xd2c9 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xccc80000, 0x9c6c62b3, 0xd2c98315 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xccc8000000000000, 0xd2c983159c6c62b3 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xd2c983159c6c62b3ccc80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xd2c983159c6c62b3ccc8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_29_1__tab[] = { 0xd2c983159c6c62b3ccc800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x4000, 0x9d05 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x9d054000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x9d05400000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x9d0540000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x9d054000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_30_0__tab[] = { 0x9d05400000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_30_1__tab[] = { 0x3588, 0x1732, 0x5cad, 0xa619, 0xd0af };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_30_1__tab[] = { 0x35880000, 0x5cad1732, 0xd0afa619 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_30_1__tab[] = { 0x3588000000000000, 0xd0afa6195cad1732 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_30_1__tab[] = { 0xd0afa6195cad173235880000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_30_1__tab[] = { 0xd0afa6195cad17323588000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_30_1__tab[] = { 0xd0afa6195cad1732358800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_31_0__tab[] = { 0xc800, 0x9e88 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_31_0__tab[] = { 0x9e88c800 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_31_0__tab[] = { 0x9e88c80000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_31_0__tab[] = { 0x9e88c8000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_31_0__tab[] = { 0x9e88c800000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_31_0__tab[] = { 0x9e88c80000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xd578, 0xf7ca, 0x63ee, 0x86e6, 0xceb1 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xd5780000, 0x63eef7ca, 0xceb186e6 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xd578000000000000, 0xceb186e663eef7ca };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xceb186e663eef7cad5780000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xceb186e663eef7cad578000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_31_1__tab[] = { 0xceb186e663eef7cad57800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_32_0__tab[] = { 0x0000, 0xa000 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_32_0__tab[] = { 0xa0000000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_32_0__tab[] = { 0xa000000000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_32_0__tab[] = { 0xa00000000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_32_0__tab[] = { 0xa0000000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_32_0__tab[] = { 0xa000000000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccd0, 0xcccc, 0xcccc, 0xcccc, 0xcccc };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccd00000, 0xcccccccc, 0xcccccccc };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccd0000000000000, 0xcccccccccccccccc };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccccccccccccccccccd00000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccccccccccccccccccd0000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_32_1__tab[] = { 0xccccccccccccccccccd000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xae00, 0xa16b };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xa16bae00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xa16bae0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xa16bae000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xa16bae00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_33_0__tab[] = { 0xa16bae0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_33_1__tab[] = { 0x0888, 0xa187, 0x5304, 0x6404, 0xcaff };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_33_1__tab[] = { 0x08880000, 0x5304a187, 0xcaff6404 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_33_1__tab[] = { 0x0888000000000000, 0xcaff64045304a187 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_33_1__tab[] = { 0xcaff64045304a18708880000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_33_1__tab[] = { 0xcaff64045304a1870888000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_33_1__tab[] = { 0xcaff64045304a187088800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_34_0__tab[] = { 0x8000, 0xa2cc };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_34_0__tab[] = { 0xa2cc8000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_34_0__tab[] = { 0xa2cc800000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_34_0__tab[] = { 0xa2cc80000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_34_0__tab[] = { 0xa2cc8000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_34_0__tab[] = { 0xa2cc800000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xfb50, 0x17ca, 0x5a79, 0x73d8, 0xc947 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xfb500000, 0x5a7917ca, 0xc94773d8 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xfb50000000000000, 0xc94773d85a7917ca };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xc94773d85a7917cafb500000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xc94773d85a7917cafb50000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_34_1__tab[] = { 0xc94773d85a7917cafb5000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_35_0__tab[] = { 0x1800, 0xa423 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_35_0__tab[] = { 0xa4231800 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_35_0__tab[] = { 0xa423180000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_35_0__tab[] = { 0xa42318000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_35_0__tab[] = { 0xa4231800000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_35_0__tab[] = { 0xa423180000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_35_1__tab[] = { 0x6960, 0x18c2, 0x6037, 0x567c, 0xc7a3 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_35_1__tab[] = { 0x69600000, 0x603718c2, 0xc7a3567c };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_35_1__tab[] = { 0x6960000000000000, 0xc7a3567c603718c2 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_35_1__tab[] = { 0xc7a3567c603718c269600000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_35_1__tab[] = { 0xc7a3567c603718c26960000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_35_1__tab[] = { 0xc7a3567c603718c2696000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_36_0__tab[] = { 0x0800, 0xa570 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_36_0__tab[] = { 0xa5700800 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_36_0__tab[] = { 0xa570080000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_36_0__tab[] = { 0xa57008000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_36_0__tab[] = { 0xa5700800000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_36_0__tab[] = { 0xa570080000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xff10, 0xf9e9, 0xe054, 0x9236, 0xc611 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xff100000, 0xe054f9e9, 0xc6119236 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xff10000000000000, 0xc6119236e054f9e9 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xc6119236e054f9e9ff100000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xc6119236e054f9e9ff10000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_36_1__tab[] = { 0xc6119236e054f9e9ff1000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xd800, 0xa6b3 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xa6b3d800 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xa6b3d80000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xa6b3d8000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xa6b3d800000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_37_0__tab[] = { 0xa6b3d80000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_37_1__tab[] = { 0x1618, 0x6b36, 0x70d7, 0xd3a2, 0xc490 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_37_1__tab[] = { 0x16180000, 0x70d76b36, 0xc490d3a2 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_37_1__tab[] = { 0x1618000000000000, 0xc490d3a270d76b36 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_37_1__tab[] = { 0xc490d3a270d76b3616180000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_37_1__tab[] = { 0xc490d3a270d76b361618000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_37_1__tab[] = { 0xc490d3a270d76b36161800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_38_0__tab[] = { 0x0600, 0xa7ef };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_38_0__tab[] = { 0xa7ef0600 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_38_0__tab[] = { 0xa7ef060000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_38_0__tab[] = { 0xa7ef06000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_38_0__tab[] = { 0xa7ef0600000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_38_0__tab[] = { 0xa7ef060000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xa3e0, 0x9505, 0x5182, 0xe8d2, 0xc31f };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xa3e00000, 0x51829505, 0xc31fe8d2 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xa3e0000000000000, 0xc31fe8d251829505 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xc31fe8d251829505a3e00000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xc31fe8d251829505a3e0000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_38_1__tab[] = { 0xc31fe8d251829505a3e000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_39_0__tab[] = { 0x0400, 0xa922 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_39_0__tab[] = { 0xa9220400 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_39_0__tab[] = { 0xa922040000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_39_0__tab[] = { 0xa92204000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_39_0__tab[] = { 0xa9220400000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_39_0__tab[] = { 0xa922040000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xfcf8, 0xf1b5, 0x10ca, 0xbd32, 0xc1bd };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xfcf80000, 0x10caf1b5, 0xc1bdbd32 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xfcf8000000000000, 0xc1bdbd3210caf1b5 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xc1bdbd3210caf1b5fcf80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xc1bdbd3210caf1b5fcf8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_39_1__tab[] = { 0xc1bdbd3210caf1b5fcf800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_40_0__tab[] = { 0x3e00, 0xaa4d };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_40_0__tab[] = { 0xaa4d3e00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_40_0__tab[] = { 0xaa4d3e0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_40_0__tab[] = { 0xaa4d3e000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_40_0__tab[] = { 0xaa4d3e00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_40_0__tab[] = { 0xaa4d3e0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xdce8, 0x4948, 0xeff7, 0x55ff, 0xc069 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xdce80000, 0xeff74948, 0xc06955ff };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xdce8000000000000, 0xc06955ffeff74948 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xc06955ffeff74948dce80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xc06955ffeff74948dce8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_40_1__tab[] = { 0xc06955ffeff74948dce800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_41_0__tab[] = { 0x1200, 0xab71 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_41_0__tab[] = { 0xab711200 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_41_0__tab[] = { 0xab71120000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_41_0__tab[] = { 0xab7112000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_41_0__tab[] = { 0xab711200000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_41_0__tab[] = { 0xab71120000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xdc28, 0x7cef, 0xf695, 0xcf47, 0xbf21 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xdc280000, 0xf6957cef, 0xbf21cf47 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xdc28000000000000, 0xbf21cf47f6957cef };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xbf21cf47f6957cefdc280000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xbf21cf47f6957cefdc28000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_41_1__tab[] = { 0xbf21cf47f6957cefdc2800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xde00, 0xac8d };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xac8dde00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xac8dde0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xac8dde000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xac8dde00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_42_0__tab[] = { 0xac8dde0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xba10, 0x7125, 0x939b, 0x594a, 0xbde6 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xba100000, 0x939b7125, 0xbde6594a };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xba10000000000000, 0xbde6594a939b7125 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xbde6594a939b7125ba100000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xbde6594a939b7125ba10000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_42_1__tab[] = { 0xbde6594a939b7125ba1000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xf600, 0xada3 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xada3f600 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xada3f60000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xada3f6000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xada3f600000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_43_0__tab[] = { 0xada3f60000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_43_1__tab[] = { 0x9560, 0x2ab5, 0x9118, 0x363d, 0xbcb6 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_43_1__tab[] = { 0x95600000, 0x91182ab5, 0xbcb6363d };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_43_1__tab[] = { 0x9560000000000000, 0xbcb6363d91182ab5 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_43_1__tab[] = { 0xbcb6363d91182ab595600000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_43_1__tab[] = { 0xbcb6363d91182ab59560000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_43_1__tab[] = { 0xbcb6363d91182ab5956000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaa00, 0xaeb3 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaeb3aa00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaeb3aa0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaeb3aa000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaeb3aa00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_44_0__tab[] = { 0xaeb3aa0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_44_1__tab[] = { 0x1590, 0x4e90, 0x3a3d, 0xb859, 0xbb90 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_44_1__tab[] = { 0x15900000, 0x3a3d4e90, 0xbb90b859 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_44_1__tab[] = { 0x1590000000000000, 0xbb90b8593a3d4e90 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_44_1__tab[] = { 0xbb90b8593a3d4e9015900000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_44_1__tab[] = { 0xbb90b8593a3d4e901590000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_44_1__tab[] = { 0xbb90b8593a3d4e90159000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_45_0__tab[] = { 0x4400, 0xafbd };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_45_0__tab[] = { 0xafbd4400 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_45_0__tab[] = { 0xafbd440000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_45_0__tab[] = { 0xafbd44000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_45_0__tab[] = { 0xafbd4400000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_45_0__tab[] = { 0xafbd440000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_45_1__tab[] = { 0x1e78, 0x76f5, 0x1010, 0x4026, 0xba75 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_45_1__tab[] = { 0x1e780000, 0x101076f5, 0xba754026 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_45_1__tab[] = { 0x1e78000000000000, 0xba754026101076f5 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_45_1__tab[] = { 0xba754026101076f51e780000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_45_1__tab[] = { 0xba754026101076f51e78000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_45_1__tab[] = { 0xba754026101076f51e7800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_46_0__tab[] = { 0x0600, 0xb0c1 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_46_0__tab[] = { 0xb0c10600 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_46_0__tab[] = { 0xb0c1060000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_46_0__tab[] = { 0xb0c106000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_46_0__tab[] = { 0xb0c10600000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_46_0__tab[] = { 0xb0c1060000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb670, 0x0512, 0x69aa, 0x3b01, 0xb963 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb6700000, 0x69aa0512, 0xb9633b01 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb670000000000000, 0xb9633b0169aa0512 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb9633b0169aa0512b6700000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb9633b0169aa0512b670000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_46_1__tab[] = { 0xb9633b0169aa0512b67000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_47_0__tab[] = { 0x3200, 0xb1bf };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_47_0__tab[] = { 0xb1bf3200 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_47_0__tab[] = { 0xb1bf320000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_47_0__tab[] = { 0xb1bf32000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_47_0__tab[] = { 0xb1bf3200000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_47_0__tab[] = { 0xb1bf320000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_47_1__tab[] = { 0x5118, 0x4133, 0xfbe4, 0x21d0, 0xb85a };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_47_1__tab[] = { 0x51180000, 0xfbe44133, 0xb85a21d0 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_47_1__tab[] = { 0x5118000000000000, 0xb85a21d0fbe44133 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_47_1__tab[] = { 0xb85a21d0fbe4413351180000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_47_1__tab[] = { 0xb85a21d0fbe441335118000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_47_1__tab[] = { 0xb85a21d0fbe44133511800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_48_0__tab[] = { 0x0400, 0xb2b8 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_48_0__tab[] = { 0xb2b80400 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_48_0__tab[] = { 0xb2b8040000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_48_0__tab[] = { 0xb2b804000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_48_0__tab[] = { 0xb2b80400000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_48_0__tab[] = { 0xb2b8040000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_48_1__tab[] = { 0x0490, 0x663d, 0x960d, 0x77de, 0xb759 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_48_1__tab[] = { 0x04900000, 0x960d663d, 0xb75977de };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_48_1__tab[] = { 0x0490000000000000, 0xb75977de960d663d };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_48_1__tab[] = { 0xb75977de960d663d04900000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_48_1__tab[] = { 0xb75977de960d663d0490000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_48_1__tab[] = { 0xb75977de960d663d049000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb400, 0xb3ab };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb3abb400 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb3abb40000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb3abb4000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb3abb400000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_49_0__tab[] = { 0xb3abb40000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_49_1__tab[] = { 0x37b8, 0xa711, 0x754d, 0xc9d6, 0xb660 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_49_1__tab[] = { 0x37b80000, 0x754da711, 0xb660c9d6 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_49_1__tab[] = { 0x37b8000000000000, 0xb660c9d6754da711 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_49_1__tab[] = { 0xb660c9d6754da71137b80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_49_1__tab[] = { 0xb660c9d6754da71137b8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_49_1__tab[] = { 0xb660c9d6754da71137b800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_50_0__tab[] = { 0x7a00, 0xb49a };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_50_0__tab[] = { 0xb49a7a00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_50_0__tab[] = { 0xb49a7a0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_50_0__tab[] = { 0xb49a7a000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_50_0__tab[] = { 0xb49a7a00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_50_0__tab[] = { 0xb49a7a0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_50_1__tab[] = { 0x27f0, 0xe532, 0x7344, 0xace3, 0xb56f };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_50_1__tab[] = { 0x27f00000, 0x7344e532, 0xb56face3 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_50_1__tab[] = { 0x27f0000000000000, 0xb56face37344e532 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_50_1__tab[] = { 0xb56face37344e53227f00000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_50_1__tab[] = { 0xb56face37344e53227f0000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_50_1__tab[] = { 0xb56face37344e53227f000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_51_0__tab[] = { 0x8400, 0xb584 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_51_0__tab[] = { 0xb5848400 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_51_0__tab[] = { 0xb584840000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_51_0__tab[] = { 0xb58484000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_51_0__tab[] = { 0xb5848400000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_51_0__tab[] = { 0xb584840000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_51_1__tab[] = { 0x4000, 0xe9a9, 0x0f8a, 0xbde5, 0xb485 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_51_1__tab[] = { 0x40000000, 0x0f8ae9a9, 0xb485bde5 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_51_1__tab[] = { 0x4000000000000000, 0xb485bde50f8ae9a9 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_51_1__tab[] = { 0xb485bde50f8ae9a940000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_51_1__tab[] = { 0xb485bde50f8ae9a94000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_51_1__tab[] = { 0xb485bde50f8ae9a9400000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_52_0__tab[] = { 0x0200, 0xb66a };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_52_0__tab[] = { 0xb66a0200 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_52_0__tab[] = { 0xb66a020000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_52_0__tab[] = { 0xb66a02000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_52_0__tab[] = { 0xb66a0200000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_52_0__tab[] = { 0xb66a020000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_52_1__tab[] = { 0x4608, 0xfcb3, 0xeecf, 0xa0bb, 0xb3a2 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_52_1__tab[] = { 0x46080000, 0xeecffcb3, 0xb3a2a0bb };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_52_1__tab[] = { 0x4608000000000000, 0xb3a2a0bbeecffcb3 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_52_1__tab[] = { 0xb3a2a0bbeecffcb346080000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_52_1__tab[] = { 0xb3a2a0bbeecffcb34608000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_52_1__tab[] = { 0xb3a2a0bbeecffcb3460800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_53_0__tab[] = { 0x2000, 0xb74b };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_53_0__tab[] = { 0xb74b2000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_53_0__tab[] = { 0xb74b200000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_53_0__tab[] = { 0xb74b20000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_53_0__tab[] = { 0xb74b2000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_53_0__tab[] = { 0xb74b200000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xa360, 0x8ccb, 0xeb5f, 0xffa9, 0xb2c5 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xa3600000, 0xeb5f8ccb, 0xb2c5ffa9 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xa360000000000000, 0xb2c5ffa9eb5f8ccb };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xb2c5ffa9eb5f8ccba3600000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xb2c5ffa9eb5f8ccba360000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_53_1__tab[] = { 0xb2c5ffa9eb5f8ccba36000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_54_0__tab[] = { 0x0a00, 0xb828 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_54_0__tab[] = { 0xb8280a00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_54_0__tab[] = { 0xb8280a0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_54_0__tab[] = { 0xb8280a000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_54_0__tab[] = { 0xb8280a00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_54_0__tab[] = { 0xb8280a0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xf368, 0xe940, 0x3e86, 0x8ac3, 0xb1ef };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xf3680000, 0x3e86e940, 0xb1ef8ac3 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xf368000000000000, 0xb1ef8ac33e86e940 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xb1ef8ac33e86e940f3680000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xb1ef8ac33e86e940f368000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_54_1__tab[] = { 0xb1ef8ac33e86e940f36800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xe800, 0xb900 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xb900e800 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xb900e80000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xb900e8000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xb900e800000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_55_0__tab[] = { 0xb900e80000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_55_1__tab[] = { 0x7a40, 0xd18e, 0xa4b5, 0xf76e, 0xb11e };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_55_1__tab[] = { 0x7a400000, 0xa4b5d18e, 0xb11ef76e };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_55_1__tab[] = { 0x7a40000000000000, 0xb11ef76ea4b5d18e };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_55_1__tab[] = { 0xb11ef76ea4b5d18e7a400000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_55_1__tab[] = { 0xb11ef76ea4b5d18e7a40000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_55_1__tab[] = { 0xb11ef76ea4b5d18e7a4000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xda00, 0xb9d5 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xb9d5da00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xb9d5da0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xb9d5da000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xb9d5da00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_56_0__tab[] = { 0xb9d5da0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xe818, 0x4c7b, 0xaa2c, 0xfff2, 0xb053 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xe8180000, 0xaa2c4c7b, 0xb053fff2 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xe818000000000000, 0xb053fff2aa2c4c7b };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xb053fff2aa2c4c7be8180000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xb053fff2aa2c4c7be818000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_56_1__tab[] = { 0xb053fff2aa2c4c7be81800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_57_0__tab[] = { 0x0a00, 0xbaa7 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_57_0__tab[] = { 0xbaa70a00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_57_0__tab[] = { 0xbaa70a0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_57_0__tab[] = { 0xbaa70a000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_57_0__tab[] = { 0xbaa70a00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_57_0__tab[] = { 0xbaa70a0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xefb0, 0x814f, 0x8e2f, 0x630e, 0xaf8e };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xefb00000, 0x8e2f814f, 0xaf8e630e };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xefb0000000000000, 0xaf8e630e8e2f814f };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xaf8e630e8e2f814fefb00000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xaf8e630e8e2f814fefb0000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_57_1__tab[] = { 0xaf8e630e8e2f814fefb000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_58_0__tab[] = { 0x9600, 0xbb74 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_58_0__tab[] = { 0xbb749600 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_58_0__tab[] = { 0xbb74960000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_58_0__tab[] = { 0xbb7496000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_58_0__tab[] = { 0xbb749600000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_58_0__tab[] = { 0xbb74960000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_58_1__tab[] = { 0x5d18, 0x41a1, 0x6114, 0xe39d, 0xaecd };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_58_1__tab[] = { 0x5d180000, 0x611441a1, 0xaecde39d };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_58_1__tab[] = { 0x5d18000000000000, 0xaecde39d611441a1 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_58_1__tab[] = { 0xaecde39d611441a15d180000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_58_1__tab[] = { 0xaecde39d611441a15d18000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_58_1__tab[] = { 0xaecde39d611441a15d1800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_59_0__tab[] = { 0x9e00, 0xbc3e };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_59_0__tab[] = { 0xbc3e9e00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_59_0__tab[] = { 0xbc3e9e0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_59_0__tab[] = { 0xbc3e9e000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_59_0__tab[] = { 0xbc3e9e00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_59_0__tab[] = { 0xbc3e9e0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xd000, 0x97df, 0x2f97, 0x4842, 0xae12 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xd0000000, 0x2f9797df, 0xae124842 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xd000000000000000, 0xae1248422f9797df };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xae1248422f9797dfd0000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xae1248422f9797dfd000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_59_1__tab[] = { 0xae1248422f9797dfd00000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_60_0__tab[] = { 0x4000, 0xbd05 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_60_0__tab[] = { 0xbd054000 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_60_0__tab[] = { 0xbd05400000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_60_0__tab[] = { 0xbd0540000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_60_0__tab[] = { 0xbd054000000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_60_0__tab[] = { 0xbd05400000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xfe58, 0x206d, 0x3555, 0x5b1c, 0xad5b };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xfe580000, 0x3555206d, 0xad5b5b1c };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xfe58000000000000, 0xad5b5b1c3555206d };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xad5b5b1c3555206dfe580000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xad5b5b1c3555206dfe58000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_60_1__tab[] = { 0xad5b5b1c3555206dfe5800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_61_0__tab[] = { 0x9a00, 0xbdc8 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_61_0__tab[] = { 0xbdc89a00 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_61_0__tab[] = { 0xbdc89a0000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_61_0__tab[] = { 0xbdc89a000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_61_0__tab[] = { 0xbdc89a00000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_61_0__tab[] = { 0xbdc89a0000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_61_1__tab[] = { 0x4df8, 0x7757, 0x31cb, 0xe982, 0xaca8 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_61_1__tab[] = { 0x4df80000, 0x31cb7757, 0xaca8e982 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_61_1__tab[] = { 0x4df8000000000000, 0xaca8e98231cb7757 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_61_1__tab[] = { 0xaca8e98231cb77574df80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_61_1__tab[] = { 0xaca8e98231cb77574df8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_61_1__tab[] = { 0xaca8e98231cb77574df800000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xc800, 0xbe88 };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xbe88c800 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xbe88c80000000000 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xbe88c8000000000000000000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xbe88c800000000000000000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_62_0__tab[] = { 0xbe88c80000000000000000000000000000000000000000000000000000000000 };
+#endif
+
+#if 0
+#elif GMP_NUMB_BITS == 16
+const mp_limb_t mpfr_l2b_62_1__tab[] = { 0x74f8, 0xf905, 0x1831, 0xc3c4, 0xabfa };
+#elif GMP_NUMB_BITS == 32
+const mp_limb_t mpfr_l2b_62_1__tab[] = { 0x74f80000, 0x1831f905, 0xabfac3c4 };
+#elif GMP_NUMB_BITS == 64
+const mp_limb_t mpfr_l2b_62_1__tab[] = { 0x74f8000000000000, 0xabfac3c41831f905 };
+#elif GMP_NUMB_BITS == 96
+const mp_limb_t mpfr_l2b_62_1__tab[] = { 0xabfac3c41831f90574f80000 };
+#elif GMP_NUMB_BITS == 128
+const mp_limb_t mpfr_l2b_62_1__tab[] = { 0xabfac3c41831f90574f8000000000000 };
+#elif GMP_NUMB_BITS == 256
+const mp_limb_t mpfr_l2b_62_1__tab[] = { 0xabfac3c41831f90574f800000000000000000000000000000000000000000000 };
+#endif
+
+const __mpfr_struct __gmpfr_l2b[BASE_MAX-1][2] = {
+ { { 23, 1, 1, (mp_limb_t *) mpfr_l2b_2_0__tab },
+ { 77, 1, 1, (mp_limb_t *) mpfr_l2b_2_1__tab } },
+ { { 23, 1, 1, (mp_limb_t *) mpfr_l2b_3_0__tab },
+ { 77, 1, 0, (mp_limb_t *) mpfr_l2b_3_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_4_0__tab },
+ { 77, 1, 0, (mp_limb_t *) mpfr_l2b_4_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_5_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_5_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_6_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_6_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_7_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_7_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_8_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_8_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_9_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_9_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_10_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_10_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_11_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_11_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_12_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_12_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_13_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_13_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_14_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_14_1__tab } },
+ { { 23, 1, 2, (mp_limb_t *) mpfr_l2b_15_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_15_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_16_0__tab },
+ { 77, 1, -1, (mp_limb_t *) mpfr_l2b_16_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_17_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_17_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_18_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_18_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_19_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_19_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_20_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_20_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_21_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_21_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_22_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_22_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_23_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_23_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_24_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_24_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_25_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_25_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_26_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_26_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_27_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_27_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_28_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_28_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_29_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_29_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_30_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_30_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_31_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_31_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_32_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_32_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_33_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_33_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_34_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_34_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_35_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_35_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_36_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_36_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_37_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_37_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_38_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_38_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_39_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_39_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_40_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_40_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_41_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_41_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_42_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_42_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_43_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_43_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_44_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_44_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_45_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_45_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_46_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_46_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_47_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_47_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_48_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_48_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_49_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_49_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_50_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_50_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_51_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_51_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_52_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_52_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_53_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_53_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_54_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_54_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_55_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_55_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_56_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_56_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_57_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_57_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_58_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_58_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_59_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_59_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_60_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_60_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_61_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_61_1__tab } },
+ { { 23, 1, 3, (mp_limb_t *) mpfr_l2b_62_0__tab },
+ { 77, 1, -2, (mp_limb_t *) mpfr_l2b_62_1__tab } } };
+
+/***************************************************************************/
+
+/* returns ceil(e * log2(b)^((-1)^i)), or ... + 1.
+ For i=0, uses a 23-bit upper approximation to log(beta)/log(2).
+ For i=1, uses a 76-bit upper approximation to log(2)/log(beta).
+ Note: this function should be called only in the extended exponent range.
+*/
+mpfr_exp_t
+mpfr_ceil_mul (mpfr_exp_t e, int beta, int i)
+{
+ mpfr_srcptr p;
+ mpfr_t t;
+ mpfr_exp_t r;
+
+ p = &__gmpfr_l2b[beta-2][i];
+ mpfr_init2 (t, sizeof (mpfr_exp_t) * CHAR_BIT);
+ mpfr_set_exp_t (t, e, MPFR_RNDU);
+ mpfr_mul (t, t, p, MPFR_RNDU);
+ r = mpfr_get_exp_t (t, MPFR_RNDU);
+ mpfr_clear (t);
+ return r;
+}
+
+/* prints the mantissa of x in the string s, and writes the corresponding
+ exponent in e.
+ x is rounded with direction rnd, m is the number of digits of the mantissa,
+ b is the given base (2 <= b <= 62).
+
+ Return value:
+ if s=NULL, allocates a string to store the mantissa, with
+ m characters, plus a final '\0', plus a possible minus sign
+ (thus m+1 or m+2 characters).
+
+ Important: when you call this function with s=NULL, don't forget to free
+ the memory space allocated, with free(s, strlen(s)).
+*/
+char*
+mpfr_get_str (char *s, mpfr_exp_t *e, int b, size_t m, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ const char *num_to_text;
+ int exact; /* exact result */
+ mpfr_exp_t exp, g;
+ mpfr_exp_t prec; /* precision of the computation */
+ long err;
+ mp_limb_t *a;
+ mpfr_exp_t exp_a;
+ mp_limb_t *result;
+ mp_limb_t *xp;
+ mp_limb_t *reste;
+ size_t nx, nx1;
+ size_t n, i;
+ char *s0;
+ int neg;
+ int ret; /* return value of mpfr_get_str_aux */
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_TMP_DECL(marker);
+
+ /* if exact = 1 then err is undefined */
+ /* otherwise err is such that |x*b^(m-g)-a*2^exp_a| < 2^(err+exp_a) */
+
+ /* is the base valid? */
+ if (b < 2 || b > 62)
+ return NULL;
+
+ num_to_text = b < 37 ? num_to_text36 : num_to_text62;
+
+ if (MPFR_UNLIKELY (MPFR_IS_NAN (x)))
+ {
+ if (s == NULL)
+ s = (char *) (*__gmp_allocate_func) (6);
+ strcpy (s, "@NaN@");
+ return s;
+ }
+
+ neg = MPFR_SIGN(x) < 0; /* 0 if positive, 1 if negative */
+
+ if (MPFR_UNLIKELY (MPFR_IS_INF (x)))
+ {
+ if (s == NULL)
+ s = (char *) (*__gmp_allocate_func) (neg + 6);
+ strcpy (s, (neg) ? "-@Inf@" : "@Inf@");
+ return s;
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo); /* needed for mpfr_ceil_mul (at least) */
+
+ if (m == 0)
+ {
+
+ /* take at least 1 + ceil(n*log(2)/log(b)) digits, where n is the
+ number of bits of the mantissa, to ensure back conversion from
+ the output gives the same floating-point.
+
+ Warning: if b = 2^k, this may be too large. The worst case is when
+ the first base-b digit contains only one bit, so we get
+ 1 + ceil((n-1)/k) = 2 + floor((n-2)/k) instead.
+ */
+ m = 1 +
+ mpfr_ceil_mul (IS_POW2(b) ? MPFR_PREC(x) - 1 : MPFR_PREC(x), b, 1);
+ if (m < 2)
+ m = 2;
+ }
+
+ /* the code below for non-power-of-two bases works for m=1 */
+ MPFR_ASSERTN (m >= 2 || (IS_POW2(b) == 0 && m >= 1));
+
+ /* x is a floating-point number */
+
+ if (MPFR_IS_ZERO(x))
+ {
+ if (s == NULL)
+ s = (char*) (*__gmp_allocate_func) (neg + m + 1);
+ s0 = s;
+ if (neg)
+ *s++ = '-';
+ memset (s, '0', m);
+ s[m] = '\0';
+ *e = 0; /* a bit like frexp() in ISO C99 */
+ MPFR_SAVE_EXPO_FREE (expo);
+ return s0; /* strlen(s0) = neg + m */
+ }
+
+ if (s == NULL)
+ s = (char*) (*__gmp_allocate_func) (neg + m + 1);
+ s0 = s;
+ if (neg)
+ *s++ = '-';
+
+ xp = MPFR_MANT(x);
+
+ if (IS_POW2(b))
+ {
+ int pow2;
+ mpfr_exp_t f, r;
+ mp_limb_t *x1;
+ mp_size_t nb;
+ int inexp;
+
+ count_leading_zeros (pow2, (mp_limb_t) b);
+ pow2 = GMP_NUMB_BITS - pow2 - 1; /* base = 2^pow2 */
+
+ /* set MPFR_EXP(x) = f*pow2 + r, 1 <= r <= pow2 */
+ f = (MPFR_GET_EXP (x) - 1) / pow2;
+ r = MPFR_GET_EXP (x) - f * pow2;
+ if (r <= 0)
+ {
+ f --;
+ r += pow2;
+ }
+
+ /* the first digit will contain only r bits */
+ prec = (m - 1) * pow2 + r; /* total number of bits */
+ n = MPFR_PREC2LIMBS (prec);
+
+ MPFR_TMP_MARK (marker);
+ x1 = MPFR_TMP_LIMBS_ALLOC (n + 1);
+ nb = n * GMP_NUMB_BITS - prec;
+ /* round xp to the precision prec, and put it into x1
+ put the carry into x1[n] */
+ if ((x1[n] = mpfr_round_raw (x1, xp, MPFR_PREC(x),
+ MPFR_IS_STRICTNEG(x),
+ prec, rnd, &inexp)))
+ {
+ /* overflow when rounding x: x1 = 2^prec */
+ if (r == pow2) /* prec = m * pow2,
+ 2^prec will need (m+1) digits in base 2^pow2 */
+ {
+ /* divide x1 by 2^pow2, and increase the exponent */
+ mpn_rshift (x1, x1, n + 1, pow2);
+ f ++;
+ }
+ else /* 2^prec needs still m digits, but x1 may need n+1 limbs */
+ n ++;
+ }
+
+ /* it remains to shift x1 by nb limbs to the right, since mpn_get_str
+ expects a right-normalized number */
+ if (nb != 0)
+ {
+ mpn_rshift (x1, x1, n, nb);
+ /* the most significant word may be zero */
+ if (x1[n - 1] == 0)
+ n --;
+ }
+
+ mpn_get_str ((unsigned char*) s, b, x1, n);
+ for (i=0; i<m; i++)
+ s[i] = num_to_text[(int) s[i]];
+ s[m] = 0;
+
+ /* the exponent of s is f + 1 */
+ *e = f + 1;
+
+ MPFR_TMP_FREE(marker);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return (s0);
+ }
+
+ /* if x < 0, reduce to x > 0 */
+ if (neg)
+ rnd = MPFR_INVERT_RND(rnd);
+
+ g = mpfr_ceil_mul (MPFR_GET_EXP (x) - 1, b, 1);
+ exact = 1;
+ prec = mpfr_ceil_mul (m, b, 0) + 1;
+ exp = ((mpfr_exp_t) m < g) ? g - (mpfr_exp_t) m : (mpfr_exp_t) m - g;
+ prec += MPFR_INT_CEIL_LOG2 (prec); /* number of guard bits */
+ if (exp != 0) /* add maximal exponentiation error */
+ prec += 3 * (mpfr_exp_t) MPFR_INT_CEIL_LOG2 (exp);
+
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ MPFR_TMP_MARK(marker);
+
+ exact = 1;
+
+ /* number of limbs */
+ n = MPFR_PREC2LIMBS (prec);
+
+ /* a will contain the approximation of the mantissa */
+ a = MPFR_TMP_LIMBS_ALLOC (n);
+
+ nx = MPFR_LIMB_SIZE (x);
+
+ if ((mpfr_exp_t) m == g) /* final exponent is 0, no multiplication or
+ division to perform */
+ {
+ if (nx > n)
+ exact = mpn_scan1 (xp, 0) >= (nx - n) * GMP_NUMB_BITS;
+ err = !exact;
+ MPN_COPY2 (a, n, xp, nx);
+ exp_a = MPFR_GET_EXP (x) - n * GMP_NUMB_BITS;
+ }
+ else if ((mpfr_exp_t) m > g) /* we have to multiply x by b^exp */
+ {
+ mp_limb_t *x1;
+
+ /* a2*2^exp_a = b^e */
+ err = mpfr_mpn_exp (a, &exp_a, b, exp, n);
+ /* here, the error on a is at most 2^err ulps */
+ exact = (err == -1);
+
+ /* x = x1*2^(n*GMP_NUMB_BITS) */
+ x1 = (nx >= n) ? xp + nx - n : xp;
+ nx1 = (nx >= n) ? n : nx; /* nx1 = min(n, nx) */
+
+ /* test si exact */
+ if (nx > n)
+ exact = (exact &&
+ ((mpn_scan1 (xp, 0) >= (nx - n) * GMP_NUMB_BITS)));
+
+ /* we loose one more bit in the multiplication,
+ except when err=0 where we loose two bits */
+ err = (err <= 0) ? 2 : err + 1;
+
+ /* result = a * x */
+ result = MPFR_TMP_LIMBS_ALLOC (n + nx1);
+ mpn_mul (result, a, n, x1, nx1);
+ exp_a += MPFR_GET_EXP (x);
+ if (mpn_scan1 (result, 0) < (nx1 * GMP_NUMB_BITS))
+ exact = 0;
+
+ /* normalize a and truncate */
+ if ((result[n + nx1 - 1] & MPFR_LIMB_HIGHBIT) == 0)
+ {
+ mpn_lshift (a, result + nx1, n , 1);
+ a[0] |= result[nx1 - 1] >> (GMP_NUMB_BITS - 1);
+ exp_a --;
+ }
+ else
+ MPN_COPY (a, result + nx1, n);
+ }
+ else
+ {
+ mp_limb_t *x1;
+
+ /* a2*2^exp_a = b^e */
+ err = mpfr_mpn_exp (a, &exp_a, b, exp, n);
+ exact = (err == -1);
+
+ /* allocate memory for x1, result and reste */
+ x1 = MPFR_TMP_LIMBS_ALLOC (2 * n);
+ result = MPFR_TMP_LIMBS_ALLOC (n + 1);
+ reste = MPFR_TMP_LIMBS_ALLOC (n);
+
+ /* initialize x1 = x */
+ MPN_COPY2 (x1, 2 * n, xp, nx);
+ if ((exact) && (nx > 2 * n) &&
+ (mpn_scan1 (xp, 0) < (nx - 2 * n) * GMP_NUMB_BITS))
+ exact = 0;
+
+ /* result = x / a */
+ mpn_tdiv_qr (result, reste, 0, x1, 2 * n, a, n);
+ exp_a = MPFR_GET_EXP (x) - exp_a - 2 * n * GMP_NUMB_BITS;
+
+ /* test if division was exact */
+ if (exact)
+ exact = mpn_popcount (reste, n) == 0;
+
+ /* normalize the result and copy into a */
+ if (result[n] == 1)
+ {
+ mpn_rshift (a, result, n, 1);
+ a[n - 1] |= MPFR_LIMB_HIGHBIT;;
+ exp_a ++;
+ }
+ else
+ MPN_COPY (a, result, n);
+
+ err = (err == -1) ? 2 : err + 2;
+ }
+
+ /* check if rounding is possible */
+ if (exact)
+ err = -1;
+ ret = mpfr_get_str_aux (s, e, a, n, exp_a, err, b, m, rnd);
+ if (ret == MPFR_ROUND_FAILED)
+ {
+ /* too large error: increment the working precision */
+ MPFR_ZIV_NEXT (loop, prec);
+ }
+ else if (ret == -MPFR_ROUND_FAILED)
+ {
+ /* too many digits in mantissa: exp = |m-g| */
+ if ((mpfr_exp_t) m > g) /* exp = m - g, multiply by b^exp */
+ {
+ g++;
+ exp --;
+ }
+ else /* exp = g - m, divide by b^exp */
+ {
+ g++;
+ exp ++;
+ }
+ }
+ else
+ break;
+
+ MPFR_TMP_FREE(marker);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ *e += g;
+
+ MPFR_TMP_FREE(marker);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return s0;
+}
+
+void mpfr_free_str (char *str)
+{
+ (*__gmp_free_func) (str, strlen (str) + 1);
+}
diff --git a/mpfr/src/get_ui.c b/mpfr/src/get_ui.c
new file mode 100644
index 0000000000..d7b11fe883
--- /dev/null
+++ b/mpfr/src/get_ui.c
@@ -0,0 +1,65 @@
+/* mpfr_get_ui -- convert a floating-point number to an unsigned long.
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+unsigned long
+mpfr_get_ui (mpfr_srcptr f, mpfr_rnd_t rnd)
+{
+ mpfr_prec_t prec;
+ unsigned long s;
+ mpfr_t x;
+ mp_size_t n;
+ mpfr_exp_t exp;
+
+ if (MPFR_UNLIKELY (!mpfr_fits_ulong_p (f, rnd)))
+ {
+ MPFR_SET_ERANGE ();
+ return MPFR_IS_NAN (f) || MPFR_IS_NEG (f) ?
+ (unsigned long) 0 : ULONG_MAX;
+ }
+
+ if (MPFR_IS_ZERO (f))
+ return (unsigned long) 0;
+
+ for (s = ULONG_MAX, prec = 0; s != 0; s /= 2, prec ++)
+ { }
+
+ /* first round to prec bits */
+ mpfr_init2 (x, prec);
+ mpfr_rint (x, f, rnd);
+
+ /* warning: if x=0, taking its exponent is illegal */
+ if (MPFR_IS_ZERO(x))
+ s = 0;
+ else
+ {
+ /* now the result is in the most significant limb of x */
+ exp = MPFR_GET_EXP (x); /* since |x| >= 1, exp >= 1 */
+ n = MPFR_LIMB_SIZE(x);
+ s = MPFR_MANT(x)[n - 1] >> (GMP_NUMB_BITS - exp);
+ }
+
+ mpfr_clear (x);
+
+ return s;
+}
diff --git a/mpfr/src/get_uj.c b/mpfr/src/get_uj.c
new file mode 100644
index 0000000000..4f085b4142
--- /dev/null
+++ b/mpfr/src/get_uj.c
@@ -0,0 +1,82 @@
+/* mpfr_get_uj -- convert a MPFR number to a huge machine unsigned integer
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+#endif
+
+#include "mpfr-intmax.h"
+#include "mpfr-impl.h"
+
+#ifdef _MPFR_H_HAVE_INTMAX_T
+
+uintmax_t
+mpfr_get_uj (mpfr_srcptr f, mpfr_rnd_t rnd)
+{
+ uintmax_t r;
+ mpfr_prec_t prec;
+ mpfr_t x;
+
+ if (MPFR_UNLIKELY (!mpfr_fits_uintmax_p (f, rnd)))
+ {
+ MPFR_SET_ERANGE ();
+ return MPFR_IS_NAN (f) || MPFR_IS_NEG (f) ?
+ (uintmax_t) 0 : MPFR_UINTMAX_MAX;
+ }
+
+ if (MPFR_IS_ZERO (f))
+ return (uintmax_t) 0;
+
+ /* determine the precision of uintmax_t */
+ for (r = MPFR_UINTMAX_MAX, prec = 0; r != 0; r /= 2, prec++)
+ { }
+
+ /* Now, r = 0. */
+
+ mpfr_init2 (x, prec);
+ mpfr_rint (x, f, rnd);
+ MPFR_ASSERTN (MPFR_IS_FP (x));
+
+ if (MPFR_NOTZERO (x))
+ {
+ mp_limb_t *xp;
+ int sh, n; /* An int should be sufficient in this context. */
+
+ MPFR_ASSERTN (MPFR_IS_POS (x));
+ xp = MPFR_MANT (x);
+ sh = MPFR_GET_EXP (x);
+ MPFR_ASSERTN ((mpfr_prec_t) sh <= prec);
+ for (n = MPFR_LIMB_SIZE(x) - 1; n >= 0; n--)
+ {
+ sh -= GMP_NUMB_BITS;
+ r += (sh >= 0
+ ? (uintmax_t) xp[n] << sh
+ : (uintmax_t) xp[n] >> (- sh));
+ }
+ }
+
+ mpfr_clear (x);
+
+ return r;
+}
+
+#endif
diff --git a/mpfr/src/get_z.c b/mpfr/src/get_z.c
new file mode 100644
index 0000000000..13a2e9960d
--- /dev/null
+++ b/mpfr/src/get_z.c
@@ -0,0 +1,61 @@
+/* mpfr_get_z -- get a multiple-precision integer from
+ a floating-point number
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_get_z (mpz_ptr z, mpfr_srcptr f, mpfr_rnd_t rnd)
+{
+ int inex;
+ mpfr_t r;
+ mpfr_exp_t exp;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
+ {
+ if (MPFR_UNLIKELY (MPFR_NOTZERO (f)))
+ MPFR_SET_ERANGE ();
+ mpz_set_ui (z, 0);
+ /* The ternary value is 0 even for infinity. Giving the rounding
+ direction in this case would not make much sense anyway, and
+ the direction would not necessarily match rnd. */
+ return 0;
+ }
+
+ exp = MPFR_GET_EXP (f);
+ /* if exp <= 0, then |f|<1, thus |o(f)|<=1 */
+ MPFR_ASSERTN (exp < 0 || exp <= MPFR_PREC_MAX);
+ mpfr_init2 (r, (exp < (mpfr_exp_t) MPFR_PREC_MIN ?
+ MPFR_PREC_MIN : (mpfr_prec_t) exp));
+ inex = mpfr_rint (r, f, rnd);
+ MPFR_ASSERTN (inex != 1 && inex != -1); /* integral part of f is
+ representable in r */
+ MPFR_ASSERTN (MPFR_IS_FP (r));
+ exp = mpfr_get_z_2exp (z, r);
+ if (exp >= 0)
+ mpz_mul_2exp (z, z, exp);
+ else
+ mpz_fdiv_q_2exp (z, z, -exp);
+ mpfr_clear (r);
+
+ return inex;
+}
diff --git a/mpfr/src/get_z_exp.c b/mpfr/src/get_z_exp.c
new file mode 100644
index 0000000000..30a5f182fc
--- /dev/null
+++ b/mpfr/src/get_z_exp.c
@@ -0,0 +1,79 @@
+/* mpfr_get_z_2exp -- get a multiple-precision integer and an exponent
+ from a floating-point number
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* puts the significand of f into z, and returns 'exp' such that f = z * 2^exp
+ *
+ * 0 doesn't have an exponent, therefore the returned exponent in this case
+ * isn't really important. We choose to return __gmpfr_emin because
+ * 1) it is in the exponent range [__gmpfr_emin,__gmpfr_emax],
+ * 2) the smaller a number is (in absolute value), the smaller its
+ * exponent is. In other words, the f -> exp function is monotonous
+ * on nonnegative numbers. --> This is WRONG since the returned
+ * exponent is not necessarily in the exponent range!
+ * Note that this is different from the C function frexp().
+ *
+ * For NaN and infinities, we choose to set z = 0 (neutral value).
+ * The exponent doesn't really matter, so let's keep __gmpfr_emin
+ * for consistency. The erange flag is set.
+ */
+
+mpfr_exp_t
+mpfr_get_z_2exp (mpz_ptr z, mpfr_srcptr f)
+{
+ mp_size_t fn;
+ int sh;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
+ {
+ if (MPFR_UNLIKELY (MPFR_NOTZERO (f)))
+ MPFR_SET_ERANGE ();
+ mpz_set_ui (z, 0);
+ return __gmpfr_emin;
+ }
+
+ fn = MPFR_LIMB_SIZE(f);
+
+ /* check whether allocated space for z is enough */
+ if (MPFR_UNLIKELY (ALLOC (z) < fn))
+ MPZ_REALLOC (z, fn);
+
+ MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (f));
+ if (MPFR_LIKELY (sh))
+ mpn_rshift (PTR (z), MPFR_MANT (f), fn, sh);
+ else
+ MPN_COPY (PTR (z), MPFR_MANT (f), fn);
+
+ SIZ(z) = MPFR_IS_NEG (f) ? -fn : fn;
+
+ if (MPFR_UNLIKELY ((mpfr_uexp_t) MPFR_GET_EXP (f) - MPFR_EXP_MIN
+ < (mpfr_uexp_t) MPFR_PREC (f)))
+ {
+ /* The exponent isn't representable in an mpfr_exp_t. */
+ MPFR_SET_ERANGE ();
+ return MPFR_EXP_MIN;
+ }
+
+ return MPFR_GET_EXP (f) - MPFR_PREC (f);
+}
diff --git a/mpfr/src/gmp_op.c b/mpfr/src/gmp_op.c
new file mode 100644
index 0000000000..769cd03165
--- /dev/null
+++ b/mpfr/src/gmp_op.c
@@ -0,0 +1,489 @@
+/* Implementations of operations between mpfr and mpz/mpq data
+
+Copyright 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Init and set a mpfr_t with enough precision to store a mpz.
+ This function should be called in the extended exponent range. */
+static void
+init_set_z (mpfr_ptr t, mpz_srcptr z)
+{
+ mpfr_prec_t p;
+ int i;
+
+ if (mpz_size (z) <= 1)
+ p = GMP_NUMB_BITS;
+ else
+ MPFR_MPZ_SIZEINBASE2 (p, z);
+ mpfr_init2 (t, p);
+ i = mpfr_set_z (t, z, MPFR_RNDN);
+ /* Possible assertion failure in case of overflow. Such cases,
+ which imply that z is huge (if the function is called in
+ the extended exponent range), are currently not supported,
+ just like precisions around MPFR_PREC_MAX. */
+ MPFR_ASSERTN (i == 0); (void) i; /* use i to avoid a warning */
+}
+
+/* Init, set a mpfr_t with enough precision to store a mpz_t without round,
+ call the function, and clear the allocated mpfr_t */
+static int
+foo (mpfr_ptr x, mpfr_srcptr y, mpz_srcptr z, mpfr_rnd_t r,
+ int (*f)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t))
+{
+ mpfr_t t;
+ int i;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ init_set_z (t, z); /* There should be no exceptions. */
+ i = (*f) (x, y, t, r);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (x, i, r);
+}
+
+static int
+foo2 (mpfr_ptr x, mpz_srcptr y, mpfr_srcptr z, mpfr_rnd_t r,
+ int (*f)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t))
+{
+ mpfr_t t;
+ int i;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ init_set_z (t, y); /* There should be no exceptions. */
+ i = (*f) (x, t, z, r);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (x, i, r);
+}
+
+int
+mpfr_mul_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
+{
+ return foo (y, x, z, r, mpfr_mul);
+}
+
+int
+mpfr_div_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
+{
+ return foo (y, x, z, r, mpfr_div);
+}
+
+int
+mpfr_add_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
+{
+ /* Mpz 0 is unsigned */
+ if (MPFR_UNLIKELY (mpz_sgn (z) == 0))
+ return mpfr_set (y, x, r);
+ else
+ return foo (y, x, z, r, mpfr_add);
+}
+
+int
+mpfr_sub_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t r)
+{
+ /* Mpz 0 is unsigned */
+ if (MPFR_UNLIKELY (mpz_sgn (z) == 0))
+ return mpfr_set (y, x, r);
+ else
+ return foo (y, x, z, r, mpfr_sub);
+}
+
+int
+mpfr_z_sub (mpfr_ptr y, mpz_srcptr x, mpfr_srcptr z, mpfr_rnd_t r)
+{
+ /* Mpz 0 is unsigned */
+ if (MPFR_UNLIKELY (mpz_sgn (x) == 0))
+ return mpfr_neg (y, z, r);
+ else
+ return foo2 (y, x, z, r, mpfr_sub);
+}
+
+int
+mpfr_cmp_z (mpfr_srcptr x, mpz_srcptr z)
+{
+ mpfr_t t;
+ int res;
+ mpfr_prec_t p;
+ unsigned int flags;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return mpfr_cmp_si (x, mpz_sgn (z));
+
+ if (mpz_size (z) <= 1)
+ p = GMP_NUMB_BITS;
+ else
+ MPFR_MPZ_SIZEINBASE2 (p, z);
+ mpfr_init2 (t, p);
+ flags = __gmpfr_flags;
+ if (mpfr_set_z (t, z, MPFR_RNDN))
+ {
+ /* overflow (t is an infinity) or underflow */
+ mpfr_div_2ui (t, t, 2, MPFR_RNDZ); /* if underflow, set t to zero */
+ __gmpfr_flags = flags; /* restore the flags */
+ /* The real value of t (= z), which falls outside the exponent range,
+ has been replaced by an equivalent value for the comparison: zero
+ or an infinity. */
+ }
+ res = mpfr_cmp (x, t);
+ mpfr_clear (t);
+ return res;
+}
+
+/* Compute y = RND(x*n/d), where n and d are mpz integers.
+ An integer 0 is assumed to have a positive sign.
+ This function is used by mpfr_mul_q and mpfr_div_q.
+ Note: the status of the rational 0/(-1) is not clear (if there is
+ a signed infinity, there should be a signed zero). But infinities
+ are not currently supported/documented in GMP, and if the rational
+ is canonicalized as it should be, the case 0/(-1) cannot occur. */
+static int
+mpfr_muldiv_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr n, mpz_srcptr d,
+ mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_UNLIKELY (mpz_sgn (n) == 0))
+ {
+ if (MPFR_UNLIKELY (mpz_sgn (d) == 0))
+ MPFR_SET_NAN (y);
+ else
+ {
+ mpfr_mul_ui (y, x, 0, MPFR_RNDN); /* exact: +0, -0 or NaN */
+ if (MPFR_UNLIKELY (mpz_sgn (d) < 0))
+ MPFR_CHANGE_SIGN (y);
+ }
+ return 0;
+ }
+ else if (MPFR_UNLIKELY (mpz_sgn (d) == 0))
+ {
+ mpfr_div_ui (y, x, 0, MPFR_RNDN); /* exact: +Inf, -Inf or NaN */
+ if (MPFR_UNLIKELY (mpz_sgn (n) < 0))
+ MPFR_CHANGE_SIGN (y);
+ return 0;
+ }
+ else
+ {
+ mpfr_prec_t p;
+ mpfr_t tmp;
+ int inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* With the current MPFR code, using mpfr_mul_z and mpfr_div_z
+ for the general case should be faster than doing everything
+ in mpn, mpz and/or mpq. MPFR_SAVE_EXPO_MARK could be avoided
+ here, but it would be more difficult to handle corner cases. */
+ MPFR_MPZ_SIZEINBASE2 (p, n);
+ mpfr_init2 (tmp, MPFR_PREC (x) + p);
+ inexact = mpfr_mul_z (tmp, x, n, MPFR_RNDN);
+ /* Since |n| >= 1, an underflow is not possible. And the precision of
+ tmp has been chosen so that inexact != 0 iff there's an overflow. */
+ if (MPFR_UNLIKELY (inexact != 0))
+ {
+ mpfr_t x0;
+ mpfr_exp_t ex;
+ MPFR_BLOCK_DECL (flags);
+
+ /* intermediate overflow case */
+ MPFR_ASSERTD (mpfr_inf_p (tmp));
+ ex = MPFR_GET_EXP (x); /* x is a pure FP number */
+ MPFR_ALIAS (x0, x, MPFR_SIGN(x), 0); /* x0 = x / 2^ex */
+ MPFR_BLOCK (flags,
+ inexact = mpfr_mul_z (tmp, x0, n, MPFR_RNDN);
+ MPFR_ASSERTD (inexact == 0);
+ inexact = mpfr_div_z (y, tmp, d, rnd_mode);
+ /* Just in case the division underflows
+ (highly unlikely, not supported)... */
+ MPFR_ASSERTN (!MPFR_BLOCK_EXCEP));
+ MPFR_EXP (y) += ex;
+ /* Detect highly unlikely, not supported corner cases... */
+ MPFR_ASSERTN (MPFR_EXP (y) >= __gmpfr_emin && MPFR_IS_PURE_FP (y));
+ /* The potential overflow will be detected by mpfr_check_range. */
+ }
+ else
+ inexact = mpfr_div_z (y, tmp, d, rnd_mode);
+
+ mpfr_clear (tmp);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
+}
+
+int
+mpfr_mul_q (mpfr_ptr y, mpfr_srcptr x, mpq_srcptr z, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_muldiv_z (y, x, mpq_numref (z), mpq_denref (z), rnd_mode);
+}
+
+int
+mpfr_div_q (mpfr_ptr y, mpfr_srcptr x, mpq_srcptr z, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_muldiv_z (y, x, mpq_denref (z), mpq_numref (z), rnd_mode);
+}
+
+int
+mpfr_add_q (mpfr_ptr y, mpfr_srcptr x, mpq_srcptr z, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t t,q;
+ mpfr_prec_t p;
+ mpfr_exp_t err;
+ int res;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ if (MPFR_UNLIKELY (mpz_sgn (mpq_denref (z)) == 0 &&
+ MPFR_MULT_SIGN (mpz_sgn (mpq_numref (z)),
+ MPFR_SIGN (x)) <= 0))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ if (MPFR_UNLIKELY (mpq_sgn (z) == 0))
+ return mpfr_set (y, x, rnd_mode); /* signed 0 - Unsigned 0 */
+ else
+ return mpfr_set_q (y, z, rnd_mode);
+ }
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ p = MPFR_PREC (y) + 10;
+ mpfr_init2 (t, p);
+ mpfr_init2 (q, p);
+
+ MPFR_ZIV_INIT (loop, p);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ res = mpfr_set_q (q, z, MPFR_RNDN); /* Error <= 1/2 ulp(q) */
+ /* If z if @INF@ (1/0), res = 0, so it quits immediately */
+ if (MPFR_UNLIKELY (res == 0))
+ /* Result is exact so we can add it directly! */
+ {
+ res = mpfr_add (y, x, q, rnd_mode);
+ break;
+ }
+ MPFR_BLOCK (flags, mpfr_add (t, x, q, MPFR_RNDN));
+ /* Error on t is <= 1/2 ulp(t), except in case of overflow/underflow,
+ but such an exception is very unlikely as it would be possible
+ only if q has a huge numerator or denominator. Not supported! */
+ MPFR_ASSERTN (! (MPFR_OVERFLOW (flags) || MPFR_UNDERFLOW (flags)));
+ /* Error / ulp(t) <= 1/2 + 1/2 * 2^(EXP(q)-EXP(t))
+ If EXP(q)-EXP(t)>0, <= 2^(EXP(q)-EXP(t)-1)*(1+2^-(EXP(q)-EXP(t)))
+ <= 2^(EXP(q)-EXP(t))
+ If EXP(q)-EXP(t)<0, <= 2^0 */
+ /* We can get 0, but we can't round since q is inexact */
+ if (MPFR_LIKELY (!MPFR_IS_ZERO (t)))
+ {
+ err = (mpfr_exp_t) p - 1 - MAX (MPFR_GET_EXP(q)-MPFR_GET_EXP(t), 0);
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, MPFR_PREC (y), rnd_mode)))
+ {
+ res = mpfr_set (y, t, rnd_mode);
+ break;
+ }
+ }
+ MPFR_ZIV_NEXT (loop, p);
+ mpfr_set_prec (t, p);
+ mpfr_set_prec (q, p);
+ }
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (t);
+ mpfr_clear (q);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, res, rnd_mode);
+}
+
+int
+mpfr_sub_q (mpfr_ptr y, mpfr_srcptr x, mpq_srcptr z,mpfr_rnd_t rnd_mode)
+{
+ mpfr_t t,q;
+ mpfr_prec_t p;
+ int res;
+ mpfr_exp_t err;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ if (MPFR_UNLIKELY (mpz_sgn (mpq_denref (z)) == 0 &&
+ MPFR_MULT_SIGN (mpz_sgn (mpq_numref (z)),
+ MPFR_SIGN (x)) >= 0))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+
+ if (MPFR_UNLIKELY (mpq_sgn (z) == 0))
+ return mpfr_set (y, x, rnd_mode); /* signed 0 - Unsigned 0 */
+ else
+ {
+ res = mpfr_set_q (y, z, MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ return -res;
+ }
+ }
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ p = MPFR_PREC (y) + 10;
+ mpfr_init2 (t, p);
+ mpfr_init2 (q, p);
+
+ MPFR_ZIV_INIT (loop, p);
+ for(;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ res = mpfr_set_q(q, z, MPFR_RNDN); /* Error <= 1/2 ulp(q) */
+ /* If z if @INF@ (1/0), res = 0, so it quits immediately */
+ if (MPFR_UNLIKELY (res == 0))
+ /* Result is exact so we can add it directly!*/
+ {
+ res = mpfr_sub (y, x, q, rnd_mode);
+ break;
+ }
+ MPFR_BLOCK (flags, mpfr_sub (t, x, q, MPFR_RNDN));
+ /* Error on t is <= 1/2 ulp(t), except in case of overflow/underflow,
+ but such an exception is very unlikely as it would be possible
+ only if q has a huge numerator or denominator. Not supported! */
+ MPFR_ASSERTN (! (MPFR_OVERFLOW (flags) || MPFR_UNDERFLOW (flags)));
+ /* Error / ulp(t) <= 1/2 + 1/2 * 2^(EXP(q)-EXP(t))
+ If EXP(q)-EXP(t)>0, <= 2^(EXP(q)-EXP(t)-1)*(1+2^-(EXP(q)-EXP(t)))
+ <= 2^(EXP(q)-EXP(t))
+ If EXP(q)-EXP(t)<0, <= 2^0 */
+ /* We can get 0, but we can't round since q is inexact */
+ if (MPFR_LIKELY (!MPFR_IS_ZERO (t)))
+ {
+ err = (mpfr_exp_t) p - 1 - MAX (MPFR_GET_EXP(q)-MPFR_GET_EXP(t), 0);
+ res = MPFR_CAN_ROUND (t, err, MPFR_PREC (y), rnd_mode);
+ if (MPFR_LIKELY (res != 0)) /* We can round! */
+ {
+ res = mpfr_set (y, t, rnd_mode);
+ break;
+ }
+ }
+ MPFR_ZIV_NEXT (loop, p);
+ mpfr_set_prec (t, p);
+ mpfr_set_prec (q, p);
+ }
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (t);
+ mpfr_clear (q);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, res, rnd_mode);
+}
+
+int
+mpfr_cmp_q (mpfr_srcptr x, mpq_srcptr q)
+{
+ mpfr_t t;
+ int res;
+ mpfr_prec_t p;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ if (MPFR_UNLIKELY (mpq_denref (q) == 0))
+ {
+ /* q is an infinity or NaN */
+ mpfr_init2 (t, 2);
+ mpfr_set_q (t, q, MPFR_RNDN);
+ res = mpfr_cmp (x, t);
+ mpfr_clear (t);
+ return res;
+ }
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return mpfr_cmp_si (x, mpq_sgn (q));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* x < a/b ? <=> x*b < a */
+ MPFR_MPZ_SIZEINBASE2 (p, mpq_denref (q));
+ mpfr_init2 (t, MPFR_PREC(x) + p);
+ res = mpfr_mul_z (t, x, mpq_denref (q), MPFR_RNDN);
+ MPFR_ASSERTD (res == 0);
+ res = mpfr_cmp_z (t, mpq_numref (q));
+ mpfr_clear (t);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return res;
+}
+
+int
+mpfr_cmp_f (mpfr_srcptr x, mpf_srcptr z)
+{
+ mpfr_t t;
+ int res;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return mpfr_cmp_si (x, mpf_sgn (z));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (t, MPFR_PREC_MIN + ABS(SIZ(z)) * GMP_NUMB_BITS );
+ res = mpfr_set_f (t, z, MPFR_RNDN);
+ MPFR_ASSERTD (res == 0);
+ res = mpfr_cmp (x, t);
+ mpfr_clear (t);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return res;
+}
diff --git a/mpfr/src/grandom.c b/mpfr/src/grandom.c
new file mode 100644
index 0000000000..f3aead3c07
--- /dev/null
+++ b/mpfr/src/grandom.c
@@ -0,0 +1,198 @@
+/* mpfr_grandom (rop1, rop2, state, rnd_mode) -- Generate up to two
+ pseudorandom real numbers according to a standard normal gaussian
+ distribution and round it to the precision of rop1, rop2 according
+ to the given rounding mode.
+
+Copyright 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+/* #define MPFR_NEED_LONGLONG_H */
+#include "mpfr-impl.h"
+
+
+int
+mpfr_grandom (mpfr_ptr rop1, mpfr_ptr rop2, gmp_randstate_t rstate,
+ mpfr_rnd_t rnd)
+{
+ int inex1, inex2, s1, s2;
+ mpz_t x, y, xp, yp, t, a, b, s;
+ mpfr_t sfr, l, r1, r2;
+ mpfr_prec_t tprec, tprec0;
+
+ inex2 = inex1 = 0;
+
+ if (rop2 == NULL) /* only one output requested. */
+ {
+ tprec0 = MPFR_PREC (rop1);
+ }
+ else
+ {
+ tprec0 = MAX (MPFR_PREC (rop1), MPFR_PREC (rop2));
+ }
+
+ tprec0 += 11;
+
+ /* We use "Marsaglia polar method" here (cf.
+ George Marsaglia, Normal (Gaussian) random variables for supercomputers
+ The Journal of Supercomputing, Volume 5, Number 1, 49–55
+ DOI: 10.1007/BF00155857).
+
+ First we draw uniform x and y in [0,1] using mpz_urandomb (in
+ fixed precision), and scale them to [-1, 1].
+ */
+
+ mpz_init (xp);
+ mpz_init (yp);
+ mpz_init (x);
+ mpz_init (y);
+ mpz_init (t);
+ mpz_init (s);
+ mpz_init (a);
+ mpz_init (b);
+ mpfr_init2 (sfr, MPFR_PREC_MIN);
+ mpfr_init2 (l, MPFR_PREC_MIN);
+ mpfr_init2 (r1, MPFR_PREC_MIN);
+ if (rop2 != NULL)
+ mpfr_init2 (r2, MPFR_PREC_MIN);
+
+ mpz_set_ui (xp, 0);
+ mpz_set_ui (yp, 0);
+
+ for (;;)
+ {
+ tprec = tprec0;
+ do
+ {
+ mpz_urandomb (xp, rstate, tprec);
+ mpz_urandomb (yp, rstate, tprec);
+ mpz_mul (a, xp, xp);
+ mpz_mul (b, yp, yp);
+ mpz_add (s, a, b);
+ }
+ while (mpz_sizeinbase (s, 2) > tprec * 2); /* x^2 + y^2 <= 2^{2tprec} */
+
+ for (;;)
+ {
+ /* FIXME: compute s as s += 2x + 2y + 2 */
+ mpz_add_ui (a, xp, 1);
+ mpz_add_ui (b, yp, 1);
+ mpz_mul (a, a, a);
+ mpz_mul (b, b, b);
+ mpz_add (s, a, b);
+ if ((mpz_sizeinbase (s, 2) <= 2 * tprec) ||
+ ((mpz_sizeinbase (s, 2) == 2 * tprec + 1) &&
+ (mpz_scan1 (s, 0) == 2 * tprec)))
+ goto yeepee;
+ /* Extend by 32 bits */
+ mpz_mul_2exp (xp, xp, 32);
+ mpz_mul_2exp (yp, yp, 32);
+ mpz_urandomb (x, rstate, 32);
+ mpz_urandomb (y, rstate, 32);
+ mpz_add (xp, xp, x);
+ mpz_add (yp, yp, y);
+ tprec += 32;
+
+ mpz_mul (a, xp, xp);
+ mpz_mul (b, yp, yp);
+ mpz_add (s, a, b);
+ if (mpz_sizeinbase (s, 2) > tprec * 2)
+ break;
+ }
+ }
+ yeepee:
+
+ /* FIXME: compute s with s -= 2x + 2y + 2 */
+ mpz_mul (a, xp, xp);
+ mpz_mul (b, yp, yp);
+ mpz_add (s, a, b);
+ /* Compute the signs of the output */
+ mpz_urandomb (x, rstate, 2);
+ s1 = mpz_tstbit (x, 0);
+ s2 = mpz_tstbit (x, 1);
+ for (;;)
+ {
+ /* s = xp^2 + yp^2 (loop invariant) */
+ mpfr_set_prec (sfr, 2 * tprec);
+ mpfr_set_prec (l, tprec);
+ mpfr_set_z (sfr, s, MPFR_RNDN); /* exact */
+ mpfr_mul_2si (sfr, sfr, -2 * tprec, MPFR_RNDN); /* exact */
+ mpfr_log (l, sfr, MPFR_RNDN);
+ mpfr_neg (l, l, MPFR_RNDN);
+ mpfr_mul_2si (l, l, 1, MPFR_RNDN);
+ mpfr_div (l, l, sfr, MPFR_RNDN);
+ mpfr_sqrt (l, l, MPFR_RNDN);
+
+ mpfr_set_prec (r1, tprec);
+ mpfr_mul_z (r1, l, xp, MPFR_RNDN);
+ mpfr_div_2ui (r1, r1, tprec, MPFR_RNDN); /* exact */
+ if (s1)
+ mpfr_neg (r1, r1, MPFR_RNDN);
+ if (MPFR_CAN_ROUND (r1, tprec - 2, MPFR_PREC (rop1), rnd))
+ {
+ if (rop2 != NULL)
+ {
+ mpfr_set_prec (r2, tprec);
+ mpfr_mul_z (r2, l, yp, MPFR_RNDN);
+ mpfr_div_2ui (r2, r2, tprec, MPFR_RNDN); /* exact */
+ if (s2)
+ mpfr_neg (r2, r2, MPFR_RNDN);
+ if (MPFR_CAN_ROUND (r2, tprec - 2, MPFR_PREC (rop2), rnd))
+ break;
+ }
+ else
+ break;
+ }
+ /* Extend by 32 bits */
+ mpz_mul_2exp (xp, xp, 32);
+ mpz_mul_2exp (yp, yp, 32);
+ mpz_urandomb (x, rstate, 32);
+ mpz_urandomb (y, rstate, 32);
+ mpz_add (xp, xp, x);
+ mpz_add (yp, yp, y);
+ tprec += 32;
+ mpz_mul (a, xp, xp);
+ mpz_mul (b, yp, yp);
+ mpz_add (s, a, b);
+ }
+ inex1 = mpfr_set (rop1, r1, rnd);
+ if (rop2 != NULL)
+ {
+ inex2 = mpfr_set (rop2, r2, rnd);
+ inex2 = mpfr_check_range (rop2, inex2, rnd);
+ }
+ inex1 = mpfr_check_range (rop1, inex1, rnd);
+
+ if (rop2 != NULL)
+ mpfr_clear (r2);
+ mpfr_clear (r1);
+ mpfr_clear (l);
+ mpfr_clear (sfr);
+ mpz_clear (b);
+ mpz_clear (a);
+ mpz_clear (s);
+ mpz_clear (t);
+ mpz_clear (y);
+ mpz_clear (x);
+ mpz_clear (yp);
+ mpz_clear (xp);
+
+ return INEX (inex1, inex2);
+}
diff --git a/mpfr/src/hppa/mparam.h b/mpfr/src/hppa/mparam.h
new file mode 100644
index 0000000000..febdca5a40
--- /dev/null
+++ b/mpfr/src/hppa/mparam.h
@@ -0,0 +1,233 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2011-07-31, gcc 4.3.2 */
+/* generated on gcc61.fsffrance.org (HP PA-8600) with GMP 5.0.2 */
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,48,47,48,47,48,47,48,47, \
+ 48,47,64,63,64,63,64,63,64,63,64,63,64,63,64,63, \
+ 64,63,64,63,64,63,64,63,64,63,64,63,64,63,64,63, \
+ 64,63,64,72,64,72,64,93,64,93,64,93,92,93,92,93, \
+ 92,93,92,93,92,93,92,93,92,93,92,93,92,93,92,93, \
+ 92,93,92,93,105,93,105,93,105,93,105,93,105,105,105,108, \
+ 105,105,105,105,108,105,105,105,108,108,108,117,108,117,108,141, \
+ 140,141,140,141,140,141,140,141,140,141,140,141,140,141,140,141, \
+ 140,141,140,141,140,141,140,141,140,141,140,141,140,141,140,141, \
+ 140,141,140,141,140,141,140,141,141,153,140,141,140,141,140,140, \
+ 144,140,140,141,140,139,140,141,140,141,140,141,188,188,188,187, \
+ 188,187,188,188,188,188,188,188,188,188,188,188,188,188,188,187, \
+ 187,187,188,188,188,188,188,188,210,188,210,188,188,210,188,188, \
+ 188,188,188,188,188,188,188,188,188,188,186,188,210,188,188,187, \
+ 188,188,210,210,210,210,210,210,210,210,210,210,210,210,210,210, \
+ 210,210,210,210,210,210,210,208,210,209,210,210,210,210,210,233, \
+ 234,234,234,233,232,234,234,234,234,234,234,234,234,234,234,276, \
+ 234,276,234,276,234,276,276,276,276,276,276,276,282,276,282,276, \
+ 282,276,276,276,276,276,282,281,276,276,276,276,276,276,276,276, \
+ 276,276,276,276,276,276,282,276,282,276,282,276,282,281,282,281, \
+ 282,281,282,281,282,281,282,281,282,281,282,306,282,306,282,306, \
+ 306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306, \
+ 306,372,306,371,306,372,372,372,372,372,372,371,372,372,372,372, \
+ 372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, \
+ 372,371,372,372,372,372,372,372,372,372,372,372,372,372,372,372, \
+ 372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, \
+ 372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, \
+ 372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, \
+ 372,372,372,372,372,372,372,372,426,372,426,426,426,426,426,426, \
+ 426,426,426,426,426,425,426,425,426,426,426,426,426,426,426,426, \
+ 426,426,426,426,426,424,426,426,426,426,426,426,426,426,426,426, \
+ 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, \
+ 426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,503, \
+ 504,503,504,503,504,503,504,503,504,503,504,503,504,503,504,503, \
+ 504,503,504,503,504,503,504,503,502,503,504,503,504,503,504,503, \
+ 504,496,504,503,504,503,504,503,504,503,504,503,504,503,504,503, \
+ 504,503,504,503,504,503,504,503,504,503,568,568,568,568,568,568, \
+ 568,567,568,568,568,567,568,567,568,567,568,568,568,567,568,568, \
+ 568,568,568,568,568,567,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,567,568,568,568,568,568,567,568,567,568,568,568,567, \
+ 568,567,568,567,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,567,568,568,568,568,568,568,632,568,568,568,568,631,568,568, \
+ 568,568,568,568,568,567,568,567,568,568,568,568,632,632,632,631, \
+ 632,631,632,631,632,632,632,631,632,632,632,631,632,632,632,728, \
+ 728,727,728,727,728,728,728,727,728,727,728,727,728,727,728,728, \
+ 728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728, \
+ 728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728, \
+ 728,752,728,752,728,752,728,752,752,752,728,752,752,752,752,752, \
+ 752,752,752,752,752,752,752,752,752,752,752,752,752,751,752,751, \
+ 752,751,752,751,728,728,728,728,752,728,728,728,728,728,728,728, \
+ 728,752,832,751,832,752,832,752,832,752,832,752,832,752,832,751, \
+ 832,831,832,752,832,831,832,832,832,832,832,832,832,824,832,832, \
+ 832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, \
+ 832,832,832,832,832,832,832,831,832,831,832,831,832,831,832,831, \
+ 832,831,832,832,832,831,832,831,832,831,832,831,832,831,832,831, \
+ 832,832,832,831,832,832,832,832,832,831,832,832,832,832,832,832 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,0,0,0,0,0,0,0,7,0,8,9,9, \
+ 10,10,11,11,12,13,14,13,14,15,16,15,16,17,18,17, \
+ 18,19,20,19,20,21,22,21,22,23,24,23,24,25,26,25, \
+ 26,27,28,27,28,29,30,29,30,31,32,31,32,33,34,33, \
+ 34,35,36,35,36,37,38,37,38,39,40,39,40,41,42,41, \
+ 42,43,44,43,44,47,48,47,48,47,48,47,48,51,52,51, \
+ 52,51,52,51,56,55,56,55,56,55,56,59,60,59,60,59, \
+ 60,63,60,63,64,63,64,63,68,63,68,67,68,67,68,71, \
+ 68,71,72,71,72,71,72,75,76,75,76,75,76,79,80,79, \
+ 80,79,80,75,76,83,84,79,80,79,80,79,80,83,84,83, \
+ 84,83,84,83,88,93,88,93,88,93,96,93,88,93,96,99, \
+ 96,93,92,93,92,93,96,93,96,99,96,99,96,99,98,99, \
+ 102,99,102,99,102,105,102,105,102,105,104,105,108,111,108,111, \
+ 108,117,114,117,116,117,116,117,116,117,120,117,120,123,120,123, \
+ 120,123,128,129,126,129,128,129,132,129,132,141,138,141,140,141, \
+ 140,141,140,141,140,141,140,141,140,153,152,153,152,153,152,153, \
+ 152,153,152,153,152,153,152,153,164,165,164,165,164,165,164,165, \
+ 164,165,164,165,164,177,176,177,176,177,176,177,176,177,176,177, \
+ 176,177,180,177,165,189,165,189,165,189,165,164,165,164,165,164, \
+ 165,164,177,176,177,176,177,176,177,176,177,176,177,176,177,188, \
+ 189,188,189,188,189,188,189,188,189,188,189,188,189,188,189,200, \
+ 189,200,201,200,201,200,201,200,201,200,201,212,213,212,213,212, \
+ 213,212,213,212,213,212,213,212,213,212,213,212,213,224,225,213, \
+ 225,213,225,213,225,213,225,213,225,213,237,225,237,225,237,225, \
+ 201,225,201,200,201,201,201,252,201,201,201,201,201,212,213,213, \
+ 213,213,213,212,213,213,213,212,213,213,213,213,213,213,225,225, \
+ 225,225,225,225,225,225,225,225,225,225,225,237,237,237,237,237, \
+ 237,236,237,237,237,252,252,252,252,252,252,252,252,252,252,252, \
+ 252,252,252,252,252,252,252,252,268,268,268,268,268,268,268,268, \
+ 268,266,268,268,268,268,268,268,268,268,275,268,275,268,275,268, \
+ 275,294,294,294,294,294,294,294,300,294,300,294,300,300,300,300, \
+ 300,300,300,300,300,300,318,318,318,318,318,318,318,318,318,318, \
+ 318,318,318,318,324,318,318,318,318,324,324,318,324,324,330,330, \
+ 330,330,342,342,342,342,342,342,342,342,342,342,342,342,342,342, \
+ 342,348,348,348,348,348,348,348,348,348,348,366,366,366,366,366, \
+ 366,366,366,366,372,366,372,366,372,372,366,372,372,372,372,372, \
+ 372,372,372,372,372,372,378,390,378,390,390,390,390,390,390,390, \
+ 390,390,396,390,396,390,366,390,396,396,372,396,372,396,372,396, \
+ 378,414,366,414,366,414,366,414,366,414,372,414,372,414,372,414, \
+ 372,372,372,395,396,395,396,390,390,390,390,390,390,390,390,390, \
+ 390,390,366,390,396,365,366,371,396,396,372,371,372,390,378,414, \
+ 378,414,378,414,414,414,414,414,390,414,390,389,390,389,390,395, \
+ 396,395,396,395,396,396,402,414,402,395,396,395,396,389,414,413, \
+ 414,413,414,413,414,413,414,414,420,395,420,419,420,395,396,401, \
+ 396,419,420,419,414,413,414,413,414,413,414,413,414,413,414,413, \
+ 414,413,420,419,420,419,420,419,420,419,426,425,426,437,438,437, \
+ 438,437,438,437,438,437,444,437,444,443,438,443,444,443,444,443, \
+ 444,443,444,443,444,461,462,461,462,461,462,461,462,461,462,461, \
+ 462,461,462,467,468,467,468,467,468,467,468,467,468,467,474,473, \
+ 486,485,486,485,486,485,414,485,486,485,486,491,492,491,492,519, \
+ 520,491,504,503,420,503,504,437,504,503,504,437,504,437,438,437, \
+ 520,443,444,519,520,519,520,519,520,519,520,519,520,527,520,527, \
+ 528,527,528,461,528,461,528,461,462,461,462,467,468,467,468,467, \
+ 468,551,552,551,552,551,552,551,552,551,560,551,552,551,552,551, \
+ 552,551,552,559,560,559,560,559,560,503,568,567,504,503,504,503, \
+ 504,503,504,519,520,519,520,519,520,519,520,520,520,519,520,519, \
+ 520,519,520,519,520,527,528,527,528,527,528,527,528,527,528,527, \
+ 528,535,552,551,552,551,552,551,552,552,552,551,552,551,552,551, \
+ 552,551,552,551,552,551,552,551,552,559,560,551,560,559,560,559, \
+ 560,567,568,567,568,583,568,567,584,583,584,583,584,583,584,583, \
+ 584,583,584,583,584,583,584,583,584,583,592,591,592,591,592,591, \
+ 592,591,592,591,592,615,616,519,520,615,520,519,520,615,616,615, \
+ 616,615,528,615,616,615,528,527,528,615,528,623,624,623,536,552, \
+ 552,551,552,551,552,551,552,551,552,551,552,551,552,551,552,551 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,6,7,10,11,10,11,12,13, \
+ 10,11,11,11,12,12,14,15,14,14,16,16,16,16,18,17, \
+ 22,19,22,23,22,23,26,27,26,23,30,29,26,27,26,27, \
+ 30,31,30,31,30,35,30,35,30,35,34,31,34,35,38,35, \
+ 34,36,38,39,38,39,38,43,38,40,42,43,42,44,42,43, \
+ 42,44,46,47,46,44,46,51,50,48,50,51,54,52,54,52, \
+ 50,51,54,55,58,55,54,56,58,56,62,60,58,63,58,63, \
+ 62,64,62,64,62,64,62,64,62,67,66,71,66,67,74,71, \
+ 70,67,70,71,74,72,74,75,70,76,74,79,74,75,74,79, \
+ 74,79,78,80,78,76,78,80,78,79,82,84,82,80,82,87, \
+ 86,84,86,84,86,84,86,88,90,88,90,92,90,88,94,96, \
+ 90,92,94,92,94,92,94,96,94,102,98,96,100,102,98,102, \
+ 98,104,100,102,102,104,104,102,102,102,104,104,104,104,108,112, \
+ 128,110,128,110,128,128,128,128,128,128,128,128,128,128,128,128, \
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, \
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,142,142, \
+ 142,142,140,142,144,144,144,142,144,142,140,142,140,142,142,144, \
+ 140,142,140,142,140,144,144,144,144,144,144,144,144,144,148,146, \
+ 148,160,148,150,148,158,156,158,156,160,156,158,160,160,156,160, \
+ 164,158,156,160,164,160,164,182,180,182,164,184,182,184,182,182, \
+ 180,182,182,182,182,186,184,182,180,182,184,184,184,185,182,184, \
+ 182,185,182,185,182,185,184,185,184,185,182,185,184,184,184,182, \
+ 184,185,184,186,184,185,182,182,184,184,184,184,184,184,186,185, \
+ 186,206,200,206,188,206,196,198,196,208,196,198,196,198,196,206, \
+ 200,206,208,206,196,198,200,208,200,206,200,206,200,208,216,208, \
+ 208,206,208,206,216,208,216,208,216,208,216,208,216,208,216,220, \
+ 216,210,216,220,256,220,216,220,216,224,216,222,256,250,248,254, \
+ 256,256,256,254,256,254,256,254,256,254,256,254,256,256,256,256, \
+ 256,254,256,254,256,256,256,254,256,254,256,254,256,256,256,254, \
+ 256,254,256,254,256,254,256,256,256,254,256,254,256,256,256,254, \
+ 256,254,256,256,256,254,256,254,256,254,256,256,256,254,256,254, \
+ 256,254,256,254,256,254,256,254,256,282,280,256,256,256,282,284, \
+ 282,284,282,288,280,281,282,288,282,288,282,282,280,281,280,282, \
+ 282,287,288,288,280,282,282,288,282,288,282,288,282,288,282,288, \
+ 282,284,282,288,280,288,282,288,282,284,282,288,282,288,282,288, \
+ 282,288,288,288,288,288,288,288,288,288,288,288,288,288,296,300, \
+ 296,304,296,304,298,300,296,300,296,300,312,302,296,306,312,300, \
+ 312,320,312,300,312,370,312,320,312,302,312,320,312,370,312,371, \
+ 312,371,312,369,372,371,372,371,368,370,372,370,372,370,372,370, \
+ 371,369,372,370,368,370,372,370,372,370,372,370,370,370,364,370, \
+ 371,370,372,370,370,370,372,370,372,370,372,370,370,370,372,370, \
+ 370,372,370,370,372,370,372,370,372,370,368,370,370,372,372,370, \
+ 370,370,372,370,372,372,372,370,372,370,370,366,372,370,370,370, \
+ 372,368,368,370,370,370,372,370,370,370,372,370,372,370,368,370, \
+ 372,370,372,370,369,370,372,370,372,369,372,370,372,371,372,370, \
+ 372,370,368,372,372,371,372,369,372,371,370,371,372,370,372,372, \
+ 372,370,372,372,372,372,376,416,376,416,376,416,414,416,416,420, \
+ 384,416,415,416,414,416,415,416,392,420,400,416,420,420,392,420, \
+ 400,416,416,416,416,420,416,412,416,416,416,416,418,416,414,416, \
+ 418,420,418,420,418,416,416,416,418,420,414,420,418,420,420,420, \
+ 416,416,418,420,418,418,416,416,420,416,418,416,432,420,432,420, \
+ 416,416,416,420,416,420,432,420,418,420,432,420,418,416,418,420, \
+ 420,420,432,420,420,420,432,468,464,512,432,468,432,444,432,444, \
+ 512,508,432,468,512,512,464,510,432,510,512,512,512,512,512,512, \
+ 512,512,512,512,512,508,512,508,512,512,512,508,512,510,512,512, \
+ 512,512,512,512,512,512,512,508,512,512,512,508,512,512,512,512, \
+ 512,512,512,512,512,512,512,512,512,512,512,508,512,512,512,512, \
+ 512,512,512,512,512,508,512,512,512,512,512,468,464,512,564,468, \
+ 512,564,512,512,564,512,512,512,564,508,564,508,564,503,564,508, \
+ 512,508,512,512,564,508,512,508,564,512,512,512,512,512,512,508, \
+ 512,510,512,512,512,512,512,512,512,512,512,512,512,512,512,512, \
+ 512,508,512,508,512,512,512,512,512,512,512,512,512,512,512,512, \
+ 512,512,512,512,512,512,512,512,512,564,562,564,560,512,564,564, \
+ 562,564,560,564,564,564,560,564,564,564,564,564,564,564,564,562 \
+
+#define MPFR_MUL_THRESHOLD 6 /* limbs */
+#define MPFR_SQR_THRESHOLD 8 /* limbs */
+#define MPFR_DIV_THRESHOLD 23 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 530 /* bits */
+#define MPFR_EXP_THRESHOLD 2918 /* bits */
+#define MPFR_SINCOS_THRESHOLD 28251 /* bits */
+#define MPFR_AI_THRESHOLD1 -21852 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 2256
+#define MPFR_AI_THRESHOLD3 34310
+/* Tuneup completed successfully, took 8236 seconds */
diff --git a/mpfr/src/hypot.c b/mpfr/src/hypot.c
new file mode 100644
index 0000000000..79e25ab8e8
--- /dev/null
+++ b/mpfr/src/hypot.c
@@ -0,0 +1,194 @@
+/* mpfr_hypot -- Euclidean distance
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* The computation of hypot of x and y is done by *
+ * hypot(x,y)= sqrt(x^2+y^2) = z */
+
+int
+mpfr_hypot (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
+{
+ int inexact, exact;
+ mpfr_t t, te, ti; /* auxiliary variables */
+ mpfr_prec_t N, Nz; /* size variables */
+ mpfr_prec_t Nt; /* precision of the intermediary variable */
+ mpfr_prec_t threshold;
+ mpfr_exp_t Ex, sh;
+ mpfr_uexp_t diff_exp;
+
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x,
+ mpfr_get_prec (y), mpfr_log_prec, y, rnd_mode),
+ ("z[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (z), mpfr_log_prec, z, inexact));
+
+ /* particular cases */
+ if (MPFR_ARE_SINGULAR (x, y))
+ {
+ if (MPFR_IS_INF (x) || MPFR_IS_INF (y))
+ {
+ /* Return +inf, even when the other number is NaN. */
+ MPFR_SET_INF (z);
+ MPFR_SET_POS (z);
+ MPFR_RET (0);
+ }
+ else if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y))
+ {
+ MPFR_SET_NAN (z);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_ZERO (x))
+ return mpfr_abs (z, y, rnd_mode);
+ else /* y is necessarily 0 */
+ return mpfr_abs (z, x, rnd_mode);
+ }
+
+ if (mpfr_cmpabs (x, y) < 0)
+ {
+ mpfr_srcptr u;
+ u = x;
+ x = y;
+ y = u;
+ }
+
+ /* now |x| >= |y| */
+
+ Ex = MPFR_GET_EXP (x);
+ diff_exp = (mpfr_uexp_t) Ex - MPFR_GET_EXP (y);
+
+ N = MPFR_PREC (x); /* Precision of input variable */
+ Nz = MPFR_PREC (z); /* Precision of output variable */
+ threshold = (MAX (N, Nz) + (rnd_mode == MPFR_RNDN ? 1 : 0)) << 1;
+ if (rnd_mode == MPFR_RNDA)
+ rnd_mode = MPFR_RNDU; /* since the result is positive, RNDA = RNDU */
+
+ /* Is |x| a suitable approximation to the precision Nz ?
+ (see algorithms.tex for explanations) */
+ if (diff_exp > threshold)
+ /* result is |x| or |x|+ulp(|x|,Nz) */
+ {
+ if (MPFR_UNLIKELY (rnd_mode == MPFR_RNDU))
+ {
+ /* If z > abs(x), then it was already rounded up; otherwise
+ z = abs(x), and we need to add one ulp due to y. */
+ if (mpfr_abs (z, x, rnd_mode) == 0)
+ mpfr_nexttoinf (z);
+ MPFR_RET (1);
+ }
+ else /* MPFR_RNDZ, MPFR_RNDD, MPFR_RNDN */
+ {
+ if (MPFR_LIKELY (Nz >= N))
+ {
+ mpfr_abs (z, x, rnd_mode); /* exact */
+ MPFR_RET (-1);
+ }
+ else
+ {
+ MPFR_SET_EXP (z, Ex);
+ MPFR_SET_SIGN (z, 1);
+ MPFR_RNDRAW_GEN (inexact, z, MPFR_MANT (x), N, rnd_mode, 1,
+ goto addoneulp,
+ if (MPFR_UNLIKELY (++ MPFR_EXP (z) >
+ __gmpfr_emax))
+ return mpfr_overflow (z, rnd_mode, 1);
+ );
+
+ if (MPFR_UNLIKELY (inexact == 0))
+ inexact = -1;
+ MPFR_RET (inexact);
+ }
+ }
+ }
+
+ /* General case */
+
+ N = MAX (MPFR_PREC (x), MPFR_PREC (y));
+
+ /* working precision */
+ Nt = Nz + MPFR_INT_CEIL_LOG2 (Nz) + 4;
+
+ mpfr_init2 (t, Nt);
+ mpfr_init2 (te, Nt);
+ mpfr_init2 (ti, Nt);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Scale x and y to avoid overflow/underflow in x^2 and overflow in y^2
+ (as |x| >= |y|). The scaling of y can underflow only when the target
+ precision is huge, otherwise the case would already have been handled
+ by the diff_exp > threshold code. */
+ sh = mpfr_get_emax () / 2 - Ex - 1;
+
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ mpfr_prec_t err;
+
+ exact = mpfr_mul_2si (te, x, sh, MPFR_RNDZ);
+ exact |= mpfr_mul_2si (ti, y, sh, MPFR_RNDZ);
+ exact |= mpfr_sqr (te, te, MPFR_RNDZ);
+ /* Use fma in order to avoid underflow when diff_exp<=MPFR_EMAX_MAX-2 */
+ exact |= mpfr_fma (t, ti, ti, te, MPFR_RNDZ);
+ exact |= mpfr_sqrt (t, t, MPFR_RNDZ);
+
+ err = Nt < N ? 4 : 2;
+ if (MPFR_LIKELY (exact == 0
+ || MPFR_CAN_ROUND (t, Nt-err, Nz, rnd_mode)))
+ break;
+
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (te, Nt);
+ mpfr_set_prec (ti, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ MPFR_BLOCK (flags, inexact = mpfr_div_2si (z, t, sh, rnd_mode));
+ MPFR_ASSERTD (exact == 0 || inexact != 0);
+
+ mpfr_clear (t);
+ mpfr_clear (ti);
+ mpfr_clear (te);
+
+ /*
+ exact inexact
+ 0 0 result is exact, ternary flag is 0
+ 0 non zero t is exact, ternary flag given by inexact
+ 1 0 impossible (see above)
+ 1 non zero ternary flag given by inexact
+ */
+
+ MPFR_SAVE_EXPO_FREE (expo);
+
+ if (MPFR_OVERFLOW (flags))
+ mpfr_set_overflow ();
+ /* hypot(x,y) >= |x|, thus underflow is not possible. */
+
+ return mpfr_check_range (z, inexact, rnd_mode);
+}
diff --git a/mpfr/src/ia64/mparam.h b/mpfr/src/ia64/mparam.h
new file mode 100644
index 0000000000..4292ca221e
--- /dev/null
+++ b/mpfr/src/ia64/mparam.h
@@ -0,0 +1,233 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2011-07-31, gcc 4.4.5 */
+/* gcc60.fsffrance.org (Madison) with gmp 5.0.2 */
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, \
+ -1,-1,14,16,16,17,18,19,20,20,22,22,20,21,22,23, \
+ 24,23,24,25,24,25,30,30,30,31,32,32,32,33,32,33, \
+ 32,33,34,37,36,37,38,35,36,40,36,39,40,41,40,43, \
+ 48,48,42,43,48,41,48,50,48,48,48,50,48,60,48,50, \
+ 60,64,60,60,60,60,60,66,64,64,64,63,64,65,68,64, \
+ 64,64,64,63,64,64,68,68,64,68,64,64,64,64,76,76, \
+ 80,76,76,72,72,80,76,76,76,82,80,80,80,80,80,80, \
+ 84,93,88,96,96,96,90,99,96,93,96,99,96,93,96,99, \
+ 96,96,102,105,108,99,108,105,108,105,108,111,108,111,108,111, \
+ 108,117,120,117,120,117,117,117,120,120,120,117,120,120,120,123, \
+ 120,117,120,123,120,120,126,141,120,141,141,141,140,141,144,141, \
+ 140,141,141,141,144,141,144,147,144,141,156,141,140,141,156,165, \
+ 164,165,156,165,164,165,165,165,164,165,164,165,164,165,165,165, \
+ 164,165,164,165,168,177,180,177,165,177,177,177,176,177,180,177, \
+ 180,177,180,177,176,177,180,165,168,189,180,189,192,189,186,189, \
+ 188,189,176,177,192,189,180,177,192,189,180,201,192,177,192,189, \
+ 192,189,189,189,188,213,212,213,192,213,200,201,192,213,200,201, \
+ 212,213,192,201,200,213,212,213,212,213,200,213,212,213,210,201, \
+ 212,213,236,212,212,213,212,213,216,213,236,213,236,235,236,252, \
+ 236,225,236,251,236,233,236,235,236,240,252,252,236,235,252,252, \
+ 236,249,252,251,252,252,252,251,256,256,256,251,252,251,252,251, \
+ 252,252,252,267,268,265,268,267,268,265,268,267,268,265,268,267, \
+ 268,267,268,283,268,281,284,283,284,281,268,283,284,281,284,283, \
+ 284,284,284,283,284,283,284,283,284,283,284,283,284,281,300,284, \
+ 284,284,300,300,300,316,284,315,284,313,300,315,316,284,316,315, \
+ 316,299,300,284,316,284,316,315,300,315,316,315,316,300,316,316, \
+ 316,313,316,315,316,313,316,315,316,316,316,315,320,316,316,315, \
+ 354,354,354,315,354,354,354,354,354,354,354,354,354,353,378,378, \
+ 354,354,354,378,354,354,354,354,354,377,378,354,354,377,378,378, \
+ 378,378,378,378,378,377,378,378,378,378,378,378,378,377,378,378, \
+ 378,378,378,378,378,377,378,378,378,378,378,378,378,378,378,378, \
+ 378,377,378,378,378,378,378,402,378,378,378,378,402,378,378,378, \
+ 402,426,426,426,426,402,426,426,402,402,426,426,402,402,426,426, \
+ 426,426,426,426,426,425,426,426,426,402,426,426,426,426,426,426, \
+ 426,426,426,426,426,426,426,426,472,472,426,426,472,426,472,472, \
+ 472,426,426,426,472,471,472,472,472,472,472,472,472,472,472,472, \
+ 472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, \
+ 472,472,472,472,472,472,472,472,472,472,472,472,504,504,472,472, \
+ 504,504,504,472,472,472,472,504,472,472,472,472,504,472,504,504, \
+ 504,504,504,504,504,504,536,504,504,504,504,504,504,504,504,504, \
+ 504,504,536,535,536,504,536,536,536,504,536,536,504,504,504,504, \
+ 504,504,536,536,536,536,536,536,536,536,536,536,536,536,536,536, \
+ 536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, \
+ 536,536,536,536,536,536,536,536,536,536,536,568,536,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,600,600,568,600,600,600,600,568,600,600, \
+ 600,600,600,600,600,600,600,600,600,600,599,600,600,600,600,600, \
+ 600,600,600,600,600,600,600,599,600,600,600,600,600,600,632,600, \
+ 600,600,600,600,632,600,600,600,632,600,632,632,632,632,632,632, \
+ 632,632,632,632,632,632,632,632,632,600,632,600,632,632,632,600, \
+ 664,632,664,664,632,632,664,664,664,664,632,664,664,632,664,664, \
+ 664,632,664,664,664,664,664,664,664,664,664,664,631,632,632,632, \
+ 664,632,664,664,664,664,663,664,664,664,736,664,736,664,664,664, \
+ 736,736,736,664,736,735,736,735,736,736,736,735,736,735,736,735, \
+ 736,736,664,735,736,736,736,736,736,735,736,735,736,735,736,736, \
+ 736,736,736,735,736,736,736,735,736,736,736,735,736,735,736,736, \
+ 736,736,760,760,736,760,760,760,760,760,784,760,760,783,784,760, \
+ 760,760,760,760,784,760,760,760,760,784,784,784,784,784,784,784, \
+ 736,760,784,784,784,784,784,783,784,783,784,783,784,783,784,784, \
+ 784,760,784,784,784,784,784,784,784,784,784,784,784,784,784,760, \
+ 784,784,784,784,784,783,784,831,784,784,784,784,784,784,784,831, \
+ 832,784,832,831,784,831,832,831,832,784,784,831,832,783,784,831, \
+ 832,784,832,831,832,784,856,856,856,856,856,856,856,856,856,856 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,0,0,-1,-1,-1,6,-1,8,8,8,10,10, \
+ 10,12,11,11,12,12,14,14,14,14,16,15,16,16,18,19, \
+ 18,18,19,20,20,20,22,22,22,22,24,24,24,28,26,30, \
+ 28,32,30,28,28,28,30,30,30,30,32,34,34,34,36,36, \
+ 36,38,38,40,36,38,38,40,38,42,42,44,44,44,42,44, \
+ 44,46,46,48,44,50,46,52,48,54,50,52,48,54,50,52, \
+ 54,50,56,52,56,52,58,56,56,56,58,58,60,60,62,62, \
+ 60,64,62,62,68,68,66,66,64,68,66,70,72,72,66,68, \
+ 68,70,70,70,72,74,74,74,80,78,78,76,80,80,82,84, \
+ 84,82,86,80,82,82,84,84,86,86,88,92,88,90,86,92, \
+ 84,94,86,90,88,92,90,94,86,86,88,98,92,88,90,90, \
+ 94,92,92,94,96,92,94,94,96,100,98,98,96,100,102,102, \
+ 100,98,102,100,100,102,102,102,104,106,106,108,108,104,106,110, \
+ 108,106,114,108,108,124,110,110,116,110,114,116,112,114,114,128, \
+ 128,114,118,120,128,128,118,120,132,132,132,120,120,128,124,124, \
+ 128,144,124,128,128,128,140,136,132,132,128,136,136,128,136,140, \
+ 132,140,166,136,160,161,140,140,136,140,166,154,144,168,166,154, \
+ 154,155,142,142,160,167,166,166,148,166,178,167,160,154,154,179, \
+ 172,167,167,154,156,148,156,160,172,172,166,166,167,166,154,155, \
+ 168,167,166,162,172,168,167,178,166,178,167,178,180,174,173,184, \
+ 180,190,178,172,178,178,190,178,178,190,191,184,178,190,190,172, \
+ 191,184,178,192,180,180,191,184,192,190,190,190,184,190,190,190, \
+ 192,190,214,203,204,202,190,214,202,190,190,190,204,191,190,208, \
+ 204,216,196,203,216,208,215,212,209,214,214,216,215,220,215,216, \
+ 214,216,216,214,220,216,214,216,220,214,214,240,228,226,226,232, \
+ 226,234,228,238,233,238,226,226,232,220,238,240,244,239,239,214, \
+ 240,232,238,250,227,232,250,250,233,238,240,226,232,234,238,226, \
+ 252,232,238,244,239,240,238,238,239,240,238,262,246,256,250,246, \
+ 252,244,262,252,252,262,251,262,262,264,275,262,264,258,233,262, \
+ 268,234,263,236,263,240,239,270,238,244,239,244,240,240,249,244, \
+ 243,244,245,252,249,244,251,250,257,258,255,250,262,264,257,258, \
+ 250,262,262,258,257,262,262,274,274,262,273,262,263,274,275,274, \
+ 275,264,263,276,274,268,275,288,281,286,288,288,264,274,281,274, \
+ 295,274,296,300,293,274,275,296,295,288,292,280,311,312,300,304, \
+ 307,302,300,308,312,304,315,314,299,316,320,316,303,320,318,320, \
+ 315,312,320,320,318,320,307,336,316,334,313,332,327,336,312,334, \
+ 316,320,313,340,316,320,315,344,332,315,332,315,316,328,335,318, \
+ 332,320,331,308,332,331,326,315,316,331,345,332,347,344,347,347, \
+ 315,329,335,331,348,345,327,320,331,334,348,352,378,378,334,378, \
+ 351,390,332,378,348,390,390,378,377,390,377,378,390,377,329,402, \
+ 356,390,402,378,378,390,378,390,378,390,401,378,378,390,390,414, \
+ 388,426,401,426,378,401,378,426,389,390,402,426,402,402,426,414, \
+ 402,414,402,426,425,426,437,414,402,438,402,426,426,401,426,426, \
+ 426,390,426,390,426,425,426,414,426,426,402,426,426,426,426,426, \
+ 426,438,426,426,426,426,438,414,402,438,450,426,426,402,426,438, \
+ 426,426,426,426,437,438,426,426,438,438,450,426,426,438,426,426, \
+ 437,438,426,426,425,426,438,460,474,438,449,438,426,474,426,474, \
+ 425,438,426,425,486,462,438,474,438,462,450,474,426,426,426,474, \
+ 438,474,462,474,450,474,438,474,473,438,474,474,474,536,426,474, \
+ 486,486,474,486,474,474,536,474,474,536,474,474,474,536,462,536, \
+ 486,536,474,536,536,536,536,536,536,536,536,536,474,536,536,536, \
+ 535,536,535,536,536,536,536,536,536,536,536,536,536,536,536,536, \
+ 536,536,535,535,536,536,536,535,536,536,535,535,536,536,536,536, \
+ 536,536,536,536,536,552,536,535,536,535,536,535,536,536,536,535, \
+ 536,536,536,536,536,584,536,536,536,535,536,535,536,536,568,535, \
+ 552,536,568,536,536,584,536,535,536,536,536,536,536,536,600,535, \
+ 536,536,536,584,536,584,536,535,536,536,536,535,536,600,600,535, \
+ 536,600,568,536,568,568,536,584,536,536,536,536,600,584,567,584, \
+ 600,584,583,599,584,584,600,584,600,568,600,599,600,600,600,584, \
+ 616,600,600,600,600,600,600,599,600,600,600,600,600,600,600,599, \
+ 600,600,615,599,616,616,584,599,600,616,600,600,600,600,600,599, \
+ 616,616,600,600,616,616,600,600,600,616,600,599,600,600,600,599, \
+ 600,616,616,599,616,616,616,599,616,616,616,599,616,616,600,599, \
+ 616,616,600,616,616,616,632,648,664,648,616,648,600,600,632,664 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,13, \
+ 16,17,18,19,18,21,22,23,22,25,17,17,20,23,25,22, \
+ 24,25,21,21,24,29,29,31,28,28,26,31,30,28,29,30, \
+ 31,37,38,37,36,40,37,37,40,37,41,37,36,39,38,46, \
+ 42,43,42,43,40,37,42,43,44,49,42,43,40,45,46,47, \
+ 49,49,50,43,44,45,50,46,54,53,53,55,50,51,50,50, \
+ 54,56,54,52,55,53,57,55,56,57,58,58,56,62,66,59, \
+ 62,65,64,59,60,65,66,77,76,73,70,73,68,65,72,73, \
+ 76,69,72,71,70,81,72,85,76,77,74,77,80,81,76,77, \
+ 84,85,84,79,82,81,84,77,84,83,80,85,82,81,96,83, \
+ 96,85,85,91,96,84,92,95,92,100,92,96,88,98,96,99, \
+ 96,96,100,100,96,95,100,100,102,96,100,95,96,98,100,99, \
+ 109,100,100,100,104,112,104,117,104,109,120,117,108,110,124,109, \
+ 112,114,112,115,120,120,112,117,118,116,116,115,112,120,124,127, \
+ 128,127,120,116,120,127,125,129,120,123,120,131,131,129,132,136, \
+ 132,125,136,131,136,125,144,144,136,144,144,147,144,128,152,144, \
+ 148,149,132,144,150,145,147,145,152,151,144,143,152,164,152,152, \
+ 152,152,152,149,152,159,152,152,152,159,144,155,160,144,164,160, \
+ 152,152,168,163,148,160,168,160,155,164,170,152,152,160,160,164, \
+ 168,160,166,168,168,170,168,162,164,168,164,168,168,160,163,176, \
+ 168,166,176,167,168,168,169,176,168,190,186,176,192,171,184,192, \
+ 192,190,192,186,176,172,176,176,176,192,192,186,192,192,198,191, \
+ 192,198,192,198,192,192,192,216,192,192,192,191,192,191,216,198, \
+ 198,198,192,192,192,198,197,192,192,192,198,198,208,224,208,198, \
+ 198,216,198,198,216,208,216,208,216,222,216,215,208,209,234,224, \
+ 240,221,234,216,216,240,232,233,216,222,233,232,216,239,240,218, \
+ 224,234,240,240,240,240,224,232,240,240,216,240,224,233,230,240, \
+ 224,233,240,234,240,234,224,232,240,233,233,240,230,230,234,240, \
+ 240,232,240,240,240,228,240,240,235,240,240,232,240,238,240,240, \
+ 240,240,240,240,240,244,246,240,256,240,240,240,244,288,250,250, \
+ 256,288,288,256,246,282,288,288,256,288,256,288,248,293,254,288, \
+ 288,256,264,256,257,265,288,257,255,288,288,288,256,288,288,281, \
+ 292,280,288,292,288,287,280,288,287,280,288,282,288,294,288,288, \
+ 288,288,288,288,288,288,288,288,294,304,288,304,288,288,288,292, \
+ 294,288,288,288,280,294,292,294,292,328,288,282,328,288,288,291, \
+ 288,288,288,288,300,288,317,304,288,329,304,292,304,320,304,318, \
+ 327,325,324,326,304,312,336,304,329,320,328,330,328,330,336,320, \
+ 328,327,330,318,316,319,330,336,328,336,352,336,320,326,352,320, \
+ 336,325,326,324,342,329,327,328,336,336,336,336,336,328,352,330, \
+ 320,328,336,326,320,335,335,326,352,352,342,336,352,326,336,336, \
+ 336,352,329,328,342,328,342,336,326,336,384,352,384,329,352,336, \
+ 384,352,384,352,336,336,334,384,384,384,384,384,384,352,351,384, \
+ 384,384,383,372,384,372,384,384,352,368,384,384,382,396,384,372, \
+ 384,384,352,384,384,383,384,384,384,384,384,384,384,384,384,384, \
+ 372,384,384,396,384,384,384,384,384,384,384,384,384,384,384,384, \
+ 384,396,384,384,384,384,384,372,384,384,384,396,384,384,384,432, \
+ 384,383,384,384,384,396,384,384,384,396,382,384,384,396,394,384, \
+ 384,384,384,383,392,396,400,384,384,401,384,384,396,432,396,432, \
+ 392,408,432,396,396,396,416,396,416,432,448,428,424,420,394,395, \
+ 432,432,432,396,432,432,432,432,432,426,432,432,448,448,444,464, \
+ 416,440,432,425,432,430,448,432,432,432,432,432,432,432,442,432, \
+ 432,432,432,447,472,432,432,480,432,468,480,480,448,465,450,432, \
+ 480,465,448,464,480,448,472,467,468,480,438,479,464,465,468,472, \
+ 468,469,480,448,480,480,464,480,468,469,464,467,468,432,472,480, \
+ 464,480,472,468,480,468,472,472,468,477,480,471,472,467,448,480, \
+ 448,496,488,464,470,480,480,480,480,469,472,448,480,479,480,512, \
+ 492,477,480,469,480,464,480,480,464,480,500,480,472,480,472,479, \
+ 488,468,500,480,512,472,504,467,480,472,480,480,464,469,480,480, \
+ 480,472,496,500,480,480,480,480,472,480,480,496,480,576,480,480, \
+ 480,497,576,500,480,516,504,504,498,480,504,480,504,480,504,576, \
+ 512,496,512,508,576,529,512,500,576,534,534,504,512,515,528,576, \
+ 560,528,576,512,528,513,512,528,528,576,576,496,528,576,576,511, \
+ 512,504,576,576,560,512,576,504,576,576,576,576,564,576,564,576, \
+ 576,562,576,576,576,576,576,560,576,576,564,528,532,576,576,576 \
+
+#define MPFR_MUL_THRESHOLD 26 /* limbs */
+#define MPFR_SQR_THRESHOLD 19 /* limbs */
+#define MPFR_DIV_THRESHOLD 44 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 1092 /* bits */
+#define MPFR_EXP_THRESHOLD 5435 /* bits */
+#define MPFR_SINCOS_THRESHOLD 24855 /* bits */
+#define MPFR_AI_THRESHOLD1 -9637 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 922
+#define MPFR_AI_THRESHOLD3 16031
+/* Tuneup completed successfully, took 1058 seconds */
diff --git a/mpfr/src/ieee_floats.h b/mpfr/src/ieee_floats.h
new file mode 100644
index 0000000000..fe524681c9
--- /dev/null
+++ b/mpfr/src/ieee_floats.h
@@ -0,0 +1,80 @@
+/* auxiliary data to generate special IEEE floats (NaN, +Inf, -Inf)
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* "double" NaN and infinities are written as explicit bytes to be sure of
+ getting what we want, and to be sure of not depending on libm.
+
+ Could use 4-byte "float" values and let the code convert them, but it
+ seems more direct to give exactly what we want. Certainly for gcc 3.0.2
+ on alphaev56-unknown-freebsd4.3 the NaN must be 8-bytes, since that
+ compiler+system was seen incorrectly converting from a "float" NaN. */
+
+#if _GMP_IEEE_FLOATS
+
+/* The "d" field guarantees alignment to a suitable boundary for a double.
+ Could use a union instead, if we checked the compiler supports union
+ initializers. */
+union dbl_bytes {
+ unsigned char b[8];
+ double d;
+};
+
+#define MPFR_DBL_INFP (dbl_infp.d)
+#define MPFR_DBL_INFM (dbl_infm.d)
+#define MPFR_DBL_NAN (dbl_nan.d)
+
+/* Warning! dbl_nan.d is not consistently the same NaN on all the
+ processors: it can be either a qNaN (quiet) or sNaN (signaling).
+ Processors are known to differ... */
+
+#if HAVE_DOUBLE_IEEE_LITTLE_ENDIAN
+static const union dbl_bytes dbl_infp =
+ { { 0, 0, 0, 0, 0, 0, 0xF0, 0x7F } };
+static const union dbl_bytes dbl_infm =
+ { { 0, 0, 0, 0, 0, 0, 0xF0, 0xFF } };
+static const union dbl_bytes dbl_nan =
+ { { 0, 0, 0, 0, 0, 0, 0xF8, 0x7F } };
+#endif
+#if HAVE_DOUBLE_IEEE_LITTLE_SWAPPED
+static const union dbl_bytes dbl_infp =
+ { { 0, 0, 0xF0, 0x7F, 0, 0, 0, 0 } };
+static const union dbl_bytes dbl_infm =
+ { { 0, 0, 0xF0, 0xFF, 0, 0, 0, 0 } };
+static const union dbl_bytes dbl_nan =
+ { { 0, 0, 0xF8, 0x7F, 0, 0, 0, 0 } };
+#endif
+#if HAVE_DOUBLE_IEEE_BIG_ENDIAN
+static const union dbl_bytes dbl_infp =
+ { { 0x7F, 0xF0, 0, 0, 0, 0, 0, 0 } };
+static const union dbl_bytes dbl_infm =
+ { { 0xFF, 0xF0, 0, 0, 0, 0, 0, 0 } };
+static const union dbl_bytes dbl_nan =
+ { { 0x7F, 0xF8, 0, 0, 0, 0, 0, 0 } };
+#endif
+
+#else /* _GMP_IEEE_FLOATS */
+
+#define MPFR_DBL_INFP DBL_POS_INF
+#define MPFR_DBL_INFM DBL_NEG_INF
+#define MPFR_DBL_NAN DBL_NAN
+
+#endif /* _GMP_IEEE_FLOATS */
diff --git a/mpfr/src/init.c b/mpfr/src/init.c
new file mode 100644
index 0000000000..a36de47b5b
--- /dev/null
+++ b/mpfr/src/init.c
@@ -0,0 +1,29 @@
+/* mpfr_init -- initialize a floating-point number
+
+Copyright 1999, 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_init (mpfr_ptr x)
+{
+ mpfr_init2 (x, __gmpfr_default_fp_bit_precision);
+}
diff --git a/mpfr/src/init2.c b/mpfr/src/init2.c
new file mode 100644
index 0000000000..25f53af8c0
--- /dev/null
+++ b/mpfr/src/init2.c
@@ -0,0 +1,69 @@
+/* mpfr_init2 -- initialize a floating-point number with given precision
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_init2 (mpfr_ptr x, mpfr_prec_t p)
+{
+ mp_size_t xsize;
+ mpfr_limb_ptr tmp;
+
+ /* Check if we can represent the number of limbs
+ * associated to the maximum of mpfr_prec_t*/
+ MPFR_ASSERTN( MP_SIZE_T_MAX >= (MPFR_PREC_MAX/BYTES_PER_MP_LIMB) );
+
+ /* Check for correct GMP_NUMB_BITS and BYTES_PER_MP_LIMB */
+ MPFR_ASSERTN( GMP_NUMB_BITS == BYTES_PER_MP_LIMB * CHAR_BIT
+ && sizeof(mp_limb_t) == BYTES_PER_MP_LIMB );
+
+ MPFR_ASSERTN (mp_bits_per_limb == GMP_NUMB_BITS);
+
+ /* Check for correct EXP NAN, ZERO & INF in both mpfr.h and mpfr-impl.h */
+ MPFR_ASSERTN( __MPFR_EXP_NAN == MPFR_EXP_NAN );
+ MPFR_ASSERTN( __MPFR_EXP_ZERO == MPFR_EXP_ZERO );
+ MPFR_ASSERTN( __MPFR_EXP_INF == MPFR_EXP_INF );
+
+ MPFR_ASSERTN( MPFR_EMAX_MAX <= (MPFR_EXP_MAX >> 1) );
+ MPFR_ASSERTN( MPFR_EMIN_MIN >= -(MPFR_EXP_MAX >> 1) );
+
+ /* p=1 is not allowed since the rounding to nearest even rule requires at
+ least two bits of mantissa: the neighbours of 3/2 are 1*2^0 and 1*2^1,
+ which both have an odd mantissa */
+ MPFR_ASSERTN(p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX);
+
+ xsize = MPFR_PREC2LIMBS (p);
+ tmp = (mpfr_limb_ptr) (*__gmp_allocate_func)(MPFR_MALLOC_SIZE(xsize));
+
+ MPFR_PREC(x) = p; /* Set prec */
+ MPFR_EXP (x) = MPFR_EXP_INVALID; /* make sure that the exp field has a
+ valid value in the C point of view */
+ MPFR_SET_POS(x); /* Set a sign */
+ MPFR_SET_MANT_PTR(x, tmp); /* Set Mantissa ptr */
+ MPFR_SET_ALLOC_SIZE(x, xsize); /* Fix alloc size of Mantissa */
+ MPFR_SET_NAN(x); /* initializes to NaN */
+}
+
+#ifdef MPFR_USE_OWN_MPFR_TMP_ALLOC
+static unsigned char mpfr_stack_tab[8000000];
+unsigned char *mpfr_stack = mpfr_stack_tab;
+#endif
diff --git a/mpfr/src/inits.c b/mpfr/src/inits.c
new file mode 100644
index 0000000000..b27599dd45
--- /dev/null
+++ b/mpfr/src/inits.c
@@ -0,0 +1,62 @@
+/* mpfr_inits -- initialize several floating-point numbers
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+#undef HAVE_STDARG
+#include "config.h" /* for a build within gmp */
+#endif
+
+#if HAVE_STDARG
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include "mpfr-impl.h"
+
+/* Since it uses "...", we need an explicit support for K&R */
+
+void
+#if HAVE_STDARG
+mpfr_inits (mpfr_ptr x, ...)
+#else
+mpfr_inits (va_alist)
+ va_dcl
+#endif
+{
+ va_list arg;
+
+#if HAVE_STDARG
+ va_start (arg, x);
+#else
+ mpfr_ptr x;
+ va_start(arg);
+ x = va_arg (arg, mpfr_ptr);
+#endif
+
+ while (x != 0)
+ {
+ mpfr_init (x);
+ x = (mpfr_ptr) va_arg (arg, mpfr_ptr);
+ }
+ va_end (arg);
+}
diff --git a/mpfr/src/inits2.c b/mpfr/src/inits2.c
new file mode 100644
index 0000000000..dd3d32ddc0
--- /dev/null
+++ b/mpfr/src/inits2.c
@@ -0,0 +1,66 @@
+/* mpfr_inits2 -- initialize several floating-point numbers with given
+ precision
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+#undef HAVE_STDARG
+#include "config.h" /* for a build within gmp */
+#endif
+
+#if HAVE_STDARG
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#include "mpfr-impl.h"
+
+/*
+ * Contrary to mpfr_init2, mpfr_prec_t p is the first argument
+ */
+
+/* Explicit support for K&R compiler */
+void
+#if HAVE_STDARG
+mpfr_inits2 (mpfr_prec_t p, mpfr_ptr x, ...)
+#else
+mpfr_inits2 (va_alist)
+ va_dcl
+#endif
+{
+ va_list arg;
+#if HAVE_STDARG
+ va_start (arg, x);
+#else
+ mpfr_prec_t p;
+ mpfr_ptr x;
+ va_start(arg);
+ p = va_arg (arg, mpfr_prec_t);
+ x = va_arg (arg, mpfr_ptr);
+#endif
+ while (x != 0)
+ {
+ mpfr_init2 (x, p);
+ x = (mpfr_ptr) va_arg (arg, mpfr_ptr);
+ }
+ va_end (arg);
+}
diff --git a/mpfr/src/inp_str.c b/mpfr/src/inp_str.c
new file mode 100644
index 0000000000..5679844b8d
--- /dev/null
+++ b/mpfr/src/inp_str.c
@@ -0,0 +1,89 @@
+/* mpfr_inp_str -- input a number in base BASE from stdio stream STREAM
+ and store the result in ROP
+
+Copyright 1999, 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <ctype.h>
+
+#include "mpfr-impl.h"
+
+/* The original version of this function came from GMP's mpf/inp_str.c;
+ it has been adapted for MPFR. */
+
+size_t
+mpfr_inp_str (mpfr_ptr rop, FILE *stream, int base, mpfr_rnd_t rnd_mode)
+{
+ unsigned char *str;
+ size_t alloc_size, str_size;
+ int c;
+ int retval;
+ size_t nread;
+
+ if (stream == NULL)
+ stream = stdin;
+
+ alloc_size = 100;
+ str = (unsigned char *) (*__gmp_allocate_func) (alloc_size);
+ str_size = 0;
+ nread = 0;
+
+ /* Skip whitespace. */
+ do
+ {
+ c = getc (stream);
+ nread++;
+ }
+ while (isspace (c));
+
+ /* number of characters read is nread */
+
+ for (;;)
+ {
+ if (str_size >= alloc_size)
+ {
+ size_t old_alloc_size = alloc_size;
+ alloc_size = alloc_size * 3 / 2;
+ str = (unsigned char *)
+ (*__gmp_reallocate_func) (str, old_alloc_size, alloc_size);
+ }
+ if (c == EOF || isspace (c))
+ break;
+ str[str_size++] = (unsigned char) c;
+ c = getc (stream);
+ }
+ ungetc (c, stream);
+
+ /* number of characters read is nread + str_size - 1 */
+
+ /* we can exit the for loop only by the break instruction,
+ then necessarily str_size >= alloc_size was checked, so
+ now str_size < alloc_size */
+
+ str[str_size] = '\0';
+
+ retval = mpfr_set_str (rop, (char *) str, base, rnd_mode);
+ (*__gmp_free_func) (str, alloc_size);
+
+ if (retval == -1)
+ return 0; /* error */
+
+ return str_size + nread - 1;
+}
diff --git a/mpfr/src/int_ceil_log2.c b/mpfr/src/int_ceil_log2.c
new file mode 100644
index 0000000000..5763830954
--- /dev/null
+++ b/mpfr/src/int_ceil_log2.c
@@ -0,0 +1,42 @@
+/* __gmpfr_int_ceil_log2 -- Integer ceil of log2(x)
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H /* for count_leading_zeros */
+#include "mpfr-impl.h"
+
+int
+__gmpfr_int_ceil_log2 (unsigned long n)
+{
+ if (MPFR_UNLIKELY (n == 1))
+ return 0;
+ else
+ {
+ int b;
+ mp_limb_t limb;
+
+ MPFR_ASSERTN (n > 1);
+ limb = n - 1;
+ MPFR_ASSERTN (limb == n - 1);
+ count_leading_zeros (b, limb);
+ return GMP_NUMB_BITS - b;
+ }
+}
diff --git a/mpfr/src/isinf.c b/mpfr/src/isinf.c
new file mode 100644
index 0000000000..85cb6fdf3e
--- /dev/null
+++ b/mpfr/src/isinf.c
@@ -0,0 +1,29 @@
+/* mpfr_inf_p -- check for infinities
+
+Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+(mpfr_inf_p) (mpfr_srcptr x)
+{
+ return MPFR_IS_INF(x);
+}
diff --git a/mpfr/src/isinteger.c b/mpfr/src/isinteger.c
new file mode 100644
index 0000000000..b82a95d3ae
--- /dev/null
+++ b/mpfr/src/isinteger.c
@@ -0,0 +1,59 @@
+/* mpfr_integer_p -- test if a mpfr variable is integer.
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#include "mpfr-impl.h"
+
+int
+mpfr_integer_p (mpfr_srcptr x)
+{
+ mpfr_exp_t expo;
+ mpfr_prec_t prec;
+ mp_size_t xn;
+ mp_limb_t *xp;
+
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(x)))
+ return (MPFR_IS_ZERO(x));
+
+ expo = MPFR_GET_EXP (x);
+ if (expo <= 0)
+ return 0;
+
+ prec = MPFR_PREC(x);
+ if ((mpfr_uexp_t) expo >= (mpfr_uexp_t) prec)
+ return 1;
+
+ /* 0 < expo < prec */
+
+ xn = (mp_size_t) ((prec - 1) / GMP_NUMB_BITS); /* index of last limb */
+ xn -= (mp_size_t) (expo / GMP_NUMB_BITS);
+ /* now the index of the last limb containing bits of the fractional part */
+
+ xp = MPFR_MANT(x);
+ MPFR_ASSERTN(xn >= 0);
+ if (xp[xn] << (expo % GMP_NUMB_BITS) != 0)
+ return 0;
+ while (--xn >= 0)
+ if (xp[xn] != 0)
+ return 0;
+ return 1;
+}
diff --git a/mpfr/src/isnan.c b/mpfr/src/isnan.c
new file mode 100644
index 0000000000..4049701d8a
--- /dev/null
+++ b/mpfr/src/isnan.c
@@ -0,0 +1,29 @@
+/* mpfr_nan_p -- check for NaN
+
+Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+(mpfr_nan_p) (mpfr_srcptr x)
+{
+ return MPFR_IS_NAN (x);
+}
diff --git a/mpfr/src/isnum.c b/mpfr/src/isnum.c
new file mode 100644
index 0000000000..9f25138be7
--- /dev/null
+++ b/mpfr/src/isnum.c
@@ -0,0 +1,29 @@
+/* mpfr_number_p -- check for ordinary numbers
+
+Copyright 2000, 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_number_p (mpfr_srcptr x)
+{
+ return MPFR_IS_FP(x);
+}
diff --git a/mpfr/src/isqrt.c b/mpfr/src/isqrt.c
new file mode 100644
index 0000000000..34d02ff46f
--- /dev/null
+++ b/mpfr/src/isqrt.c
@@ -0,0 +1,84 @@
+/* __gmpfr_isqrt && __gmpfr_cuberoot -- Integer square root and cube root
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* returns floor(sqrt(n)) */
+unsigned long
+__gmpfr_isqrt (unsigned long n)
+{
+ unsigned long i, s;
+
+ /* First find an approximation to floor(sqrt(n)) of the form 2^k. */
+ i = n;
+ s = 1;
+ while (i >= 2)
+ {
+ i >>= 2;
+ s <<= 1;
+ }
+
+ do
+ {
+ s = (s + n / s) / 2;
+ }
+ while (!(s*s <= n && (s*s > s*(s+2) || n <= s*(s+2))));
+ /* Short explanation: As mathematically s*(s+2) < 2*ULONG_MAX,
+ the condition s*s > s*(s+2) is evaluated as true when s*(s+2)
+ "overflows" but not s*s. This implies that mathematically, one
+ has s*s <= n <= s*(s+2). If s*s "overflows", this means that n
+ is "large" and the inequality n <= s*(s+2) cannot be satisfied. */
+ return s;
+}
+
+/* returns floor(n^(1/3)) */
+unsigned long
+__gmpfr_cuberoot (unsigned long n)
+{
+ unsigned long i, s;
+
+ /* First find an approximation to floor(cbrt(n)) of the form 2^k. */
+ i = n;
+ s = 1;
+ while (i >= 4)
+ {
+ i >>= 3;
+ s <<= 1;
+ }
+
+ /* Improve the approximation (this is necessary if n is large, so that
+ mathematically (s+1)*(s+1)*(s+1) isn't much larger than ULONG_MAX). */
+ if (n >= 256)
+ {
+ s = (2 * s + n / (s * s)) / 3;
+ s = (2 * s + n / (s * s)) / 3;
+ s = (2 * s + n / (s * s)) / 3;
+ }
+
+ do
+ {
+ s = (2 * s + n / (s * s)) / 3;
+ }
+ while (!(s*s*s <= n && (s*s*s > (s+1)*(s+1)*(s+1) ||
+ n < (s+1)*(s+1)*(s+1))));
+ return s;
+}
diff --git a/mpfr/src/isregular.c b/mpfr/src/isregular.c
new file mode 100644
index 0000000000..51f47ab896
--- /dev/null
+++ b/mpfr/src/isregular.c
@@ -0,0 +1,29 @@
+/* mpfr_regular_p -- check for regular number (neither NaN, Inf or zero)
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+(mpfr_regular_p) (mpfr_srcptr x)
+{
+ return MPFR_IS_SINGULAR(x) == 0;
+}
diff --git a/mpfr/src/iszero.c b/mpfr/src/iszero.c
new file mode 100644
index 0000000000..ed9e9f78d1
--- /dev/null
+++ b/mpfr/src/iszero.c
@@ -0,0 +1,29 @@
+/* mpfr_zero_p -- check for zero
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+(mpfr_zero_p) (mpfr_srcptr x)
+{
+ return MPFR_IS_ZERO(x);
+}
diff --git a/mpfr/src/jn.c b/mpfr/src/jn.c
new file mode 100644
index 0000000000..f85720784c
--- /dev/null
+++ b/mpfr/src/jn.c
@@ -0,0 +1,329 @@
+/* mpfr_j0, mpfr_j1, mpfr_jn -- Bessel functions of 1st kind, integer order.
+ http://www.opengroup.org/onlinepubs/009695399/functions/j0.html
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Relations: j(-n,z) = (-1)^n j(n,z)
+ j(n,-z) = (-1)^n j(n,z)
+*/
+
+static int mpfr_jn_asympt (mpfr_ptr, long, mpfr_srcptr, mpfr_rnd_t);
+
+int
+mpfr_j0 (mpfr_ptr res, mpfr_srcptr z, mpfr_rnd_t r)
+{
+ return mpfr_jn (res, 0, z, r);
+}
+
+int
+mpfr_j1 (mpfr_ptr res, mpfr_srcptr z, mpfr_rnd_t r)
+{
+ return mpfr_jn (res, 1, z, r);
+}
+
+/* Estimate k1 such that z^2/4 = k1 * (k1 + n)
+ i.e., k1 = (sqrt(n^2+z^2)-n)/2 = n/2 * (sqrt(1+(z/n)^2) - 1) if n != 0.
+ Return k0 = min(2*k1/log(2), ULONG_MAX).
+*/
+static unsigned long
+mpfr_jn_k0 (unsigned long n, mpfr_srcptr z)
+{
+ mpfr_t t, u;
+ unsigned long k0;
+
+ mpfr_init2 (t, 32);
+ mpfr_init2 (u, 32);
+ if (n == 0)
+ {
+ mpfr_abs (t, z, MPFR_RNDN); /* t = 2*k1 */
+ }
+ else
+ {
+ mpfr_div_ui (t, z, n, MPFR_RNDN);
+ mpfr_sqr (t, t, MPFR_RNDN);
+ mpfr_add_ui (t, t, 1, MPFR_RNDN);
+ mpfr_sqrt (t, t, MPFR_RNDN);
+ mpfr_sub_ui (t, t, 1, MPFR_RNDN);
+ mpfr_mul_ui (t, t, n, MPFR_RNDN); /* t = 2*k1 */
+ }
+ /* the following is a 32-bit approximation to nearest to 1/log(2) */
+ mpfr_set_str_binary (u, "1.0111000101010100011101100101001");
+ mpfr_mul (t, t, u, MPFR_RNDN);
+ if (mpfr_fits_ulong_p (t, MPFR_RNDN))
+ k0 = mpfr_get_ui (t, MPFR_RNDN);
+ else
+ k0 = ULONG_MAX;
+ mpfr_clear (t);
+ mpfr_clear (u);
+ return k0;
+}
+
+int
+mpfr_jn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
+{
+ int inex;
+ int exception = 0;
+ unsigned long absn;
+ mpfr_prec_t prec, pbound, err;
+ mpfr_uprec_t uprec;
+ mpfr_exp_t exps, expT, diffexp;
+ mpfr_t y, s, t, absz;
+ unsigned long k, zz, k0;
+ MPFR_GROUP_DECL(g);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_LOG_FUNC
+ (("n=%d x[%Pu]=%.*Rg rnd=%d", n, mpfr_get_prec (z), mpfr_log_prec, z, r),
+ ("res[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (res), mpfr_log_prec, res, inex));
+
+ absn = SAFE_ABS (unsigned long, n);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (z)))
+ {
+ if (MPFR_IS_NAN (z))
+ {
+ MPFR_SET_NAN (res);
+ MPFR_RET_NAN;
+ }
+ /* j(n,z) tends to zero when z goes to +Inf or -Inf, oscillating around
+ 0. We choose to return +0 in that case. */
+ else if (MPFR_IS_INF (z)) /* FIXME: according to j(-n,z) = (-1)^n j(n,z)
+ we might want to give a sign depending on
+ z and n */
+ return mpfr_set_ui (res, 0, r);
+ else /* z=0: j(0,0)=1, j(n odd,+/-0) = +/-0 if n > 0, -/+0 if n < 0,
+ j(n even,+/-0) = +0 */
+ {
+ if (n == 0)
+ return mpfr_set_ui (res, 1, r);
+ else if (absn & 1) /* n odd */
+ return (n > 0) ? mpfr_set (res, z, r) : mpfr_neg (res, z, r);
+ else /* n even */
+ return mpfr_set_ui (res, 0, r);
+ }
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* check for tiny input for j0: j0(z) = 1 - z^2/4 + ..., more precisely
+ |j0(z) - 1| <= z^2/4 for -1 <= z <= 1. */
+ if (n == 0)
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (res, __gmpfr_one, -2 * MPFR_GET_EXP (z),
+ 2, 0, r, inex = _inexact; goto end);
+
+ /* idem for j1: j1(z) = z/2 - z^3/16 + ..., more precisely
+ |j1(z) - z/2| <= |z^3|/16 for -1 <= z <= 1, with the sign of j1(z) - z/2
+ being the opposite of that of z. */
+ /* TODO: add a test to trigger an error when
+ inex = _inexact; goto end
+ is forgotten in MPFR_FAST_COMPUTE_IF_SMALL_INPUT below. */
+ if (n == 1)
+ {
+ /* We first compute 2j1(z) = z - z^3/8 + ..., then divide by 2 using
+ the "extra" argument of MPFR_FAST_COMPUTE_IF_SMALL_INPUT. But we
+ must also handle the underflow case (an overflow is not possible
+ for small inputs). If an underflow occurred in mpfr_round_near_x,
+ the rounding was to zero or equivalent, and the result is 0, so
+ that the division by 2 will give the wanted result. Otherwise...
+ The rounded result in unbounded exponent range is res/2. If the
+ division by 2 doesn't underflow, it is exact, and we can return
+ this result. And an underflow in the division is a real underflow.
+ In case of directed rounding mode, the result is correct. But in
+ case of rounding to nearest, there is a double rounding problem,
+ and the result is 0 iff the result before the division is the
+ minimum positive number and _inexact has the same sign as z;
+ but in rounding to nearest, res/2 will yield 0 iff |res| is the
+ minimum positive number, so that we just need to test the result
+ of the division and the sign of _inexact. */
+ mpfr_clear_flags ();
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT
+ (res, z, -2 * MPFR_GET_EXP (z), 3, 0, r, {
+ int inex2 = mpfr_div_2ui (res, res, 1, r);
+ if (MPFR_UNLIKELY (r == MPFR_RNDN && MPFR_IS_ZERO (res)) &&
+ (MPFR_ASSERTN (inex2 != 0), SIGN (_inexact) != MPFR_SIGN (z)))
+ {
+ mpfr_nexttoinf (res);
+ inex = - inex2;
+ }
+ else
+ inex = inex2 != 0 ? inex2 : _inexact;
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ goto end;
+ });
+ }
+
+ /* we can use the asymptotic expansion as soon as |z| > p log(2)/2,
+ but to get some margin we use it for |z| > p/2 */
+ pbound = MPFR_PREC (res) / 2 + 3;
+ MPFR_ASSERTN (pbound <= ULONG_MAX);
+ MPFR_ALIAS (absz, z, 1, MPFR_EXP (z));
+ if (mpfr_cmp_ui (absz, pbound) > 0)
+ {
+ inex = mpfr_jn_asympt (res, n, z, r);
+ if (inex != 0)
+ goto end;
+ }
+
+ MPFR_GROUP_INIT_3 (g, 32, y, s, t);
+
+ /* check underflow case: |j(n,z)| <= 1/sqrt(2 Pi n) (ze/2n)^n
+ (see algorithms.tex) */
+ /* FIXME: the code below doesn't detect all the underflow cases. Either
+ this should be done, or the generic code should detect underflows. */
+ if (absn > 0)
+ {
+ /* the following is an upper 32-bit approximation to exp(1)/2 */
+ mpfr_set_str_binary (y, "1.0101101111110000101010001011001");
+ if (MPFR_SIGN(z) > 0)
+ mpfr_mul (y, y, z, MPFR_RNDU);
+ else
+ {
+ mpfr_mul (y, y, z, MPFR_RNDD);
+ mpfr_neg (y, y, MPFR_RNDU);
+ }
+ mpfr_div_ui (y, y, absn, MPFR_RNDU);
+ /* now y is an upper approximation to |ze/2n|: y < 2^EXP(y),
+ thus |j(n,z)| < 1/2*y^n < 2^(n*EXP(y)-1).
+ If n*EXP(y) < emin then we have an underflow.
+ Note that if emin = MPFR_EMIN_MIN and j = 1, this inequality
+ will never be satisfied.
+ Warning: absn is an unsigned long. */
+ if ((MPFR_GET_EXP (y) < 0 && absn > - expo.saved_emin)
+ || (absn <= - MPFR_EMIN_MIN &&
+ MPFR_GET_EXP (y) < expo.saved_emin / (mpfr_exp_t) absn))
+ {
+ MPFR_GROUP_CLEAR (g);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (res, (r == MPFR_RNDN) ? MPFR_RNDZ : r,
+ (n % 2) ? ((n > 0) ? MPFR_SIGN(z) : -MPFR_SIGN(z))
+ : MPFR_SIGN_POS);
+ }
+ }
+
+ /* the logarithm of the ratio between the largest term in the series
+ and the first one is roughly bounded by k0, which we add to the
+ working precision to take into account this cancellation */
+ /* The following operations avoid integer overflow and ensure that
+ prec <= MPFR_PREC_MAX (prec = MPFR_PREC_MAX won't prevent an abort,
+ but the failure should be handled cleanly). */
+ k0 = mpfr_jn_k0 (absn, z);
+ MPFR_LOG_MSG (("k0 = %lu\n", k0));
+ uprec = MPFR_PREC_MAX - 2 * MPFR_INT_CEIL_LOG2 (MPFR_PREC_MAX) - 3;
+ if (k0 < uprec)
+ uprec = k0;
+ uprec += MPFR_PREC (res) + 2 * MPFR_INT_CEIL_LOG2 (MPFR_PREC (res)) + 3;
+ prec = uprec < MPFR_PREC_MAX ? (mpfr_prec_t) uprec : MPFR_PREC_MAX;
+
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_GROUP_REPREC_3 (g, prec, y, s, t);
+ MPFR_BLOCK (flags, {
+ mpfr_pow_ui (t, z, absn, MPFR_RNDN); /* z^|n| */
+ mpfr_mul (y, z, z, MPFR_RNDN); /* z^2 */
+ mpfr_clear_erangeflag ();
+ zz = mpfr_get_ui (y, MPFR_RNDU);
+ /* FIXME: The error analysis is incorrect in case of range error. */
+ MPFR_ASSERTN (! mpfr_erangeflag_p ()); /* since mpfr_clear_erangeflag */
+ mpfr_div_2ui (y, y, 2, MPFR_RNDN); /* z^2/4 */
+ mpfr_fac_ui (s, absn, MPFR_RNDN); /* |n|! */
+ mpfr_div (t, t, s, MPFR_RNDN);
+ if (absn > 0)
+ mpfr_div_2ui (t, t, absn, MPFR_RNDN);
+ mpfr_set (s, t, MPFR_RNDN);
+ /* note: we assume here that the maximal error bound is proportional to
+ 2^exps, which is true also in the case where s=0 */
+ exps = MPFR_IS_ZERO (s) ? MPFR_EMIN_MIN : MPFR_GET_EXP (s);
+ expT = exps;
+ for (k = 1; ; k++)
+ {
+ MPFR_LOG_MSG (("loop on k, k = %lu\n", k));
+ mpfr_mul (t, t, y, MPFR_RNDN);
+ mpfr_neg (t, t, MPFR_RNDN);
+ /* Mathematically: absn <= LONG_MAX + 1 <= (ULONG_MAX + 1) / 2,
+ and in practice, k is not very large, so that one should have
+ k + absn <= ULONG_MAX. */
+ MPFR_ASSERTN (absn <= ULONG_MAX - k);
+ if (k + absn <= ULONG_MAX / k)
+ mpfr_div_ui (t, t, k * (k + absn), MPFR_RNDN);
+ else
+ {
+ mpfr_div_ui (t, t, k, MPFR_RNDN);
+ mpfr_div_ui (t, t, k + absn, MPFR_RNDN);
+ }
+ /* see above note */
+ exps = MPFR_IS_ZERO (s) ? MPFR_EMIN_MIN : MPFR_GET_EXP (t);
+ if (exps > expT)
+ expT = exps;
+ mpfr_add (s, s, t, MPFR_RNDN);
+ exps = MPFR_IS_ZERO (s) ? MPFR_EMIN_MIN : MPFR_GET_EXP (s);
+ if (exps > expT)
+ expT = exps;
+ /* Above it has been checked that k + absn <= ULONG_MAX. */
+ if (MPFR_GET_EXP (t) + (mpfr_exp_t) prec <= exps &&
+ zz / (2 * k) < k + absn)
+ break;
+ }
+ });
+ /* the error is bounded by (4k^2+21/2k+7) ulp(s)*2^(expT-exps)
+ <= (k+2)^2 ulp(s)*2^(2+expT-exps) */
+ diffexp = expT - exps;
+ err = 2 * MPFR_INT_CEIL_LOG2(k + 2) + 2;
+ /* FIXME: Can an overflow occur in the following sum? */
+ MPFR_ASSERTN (diffexp >= 0 && err >= 0 &&
+ diffexp <= MPFR_PREC_MAX - err);
+ err += diffexp;
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, prec - err, MPFR_PREC(res), r)))
+ {
+ if (MPFR_LIKELY (! (MPFR_UNDERFLOW (flags) ||
+ MPFR_OVERFLOW (flags))))
+ break;
+ /* The error analysis is incorrect in case of exception.
+ If an underflow or overflow occurred, try once more in
+ a larger precision, and if this happens a second time,
+ then abort to avoid a probable infinite loop. This is
+ a problem that must be fixed! */
+ MPFR_ASSERTN (! exception);
+ exception = 1;
+ }
+ MPFR_ZIV_NEXT (loop, prec);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inex = ((n >= 0) || ((n & 1) == 0)) ? mpfr_set (res, s, r)
+ : mpfr_neg (res, s, r);
+
+ MPFR_GROUP_CLEAR (g);
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (res, inex, r);
+}
+
+#define MPFR_JN
+#include "jyn_asympt.c"
diff --git a/mpfr/src/jyn_asympt.c b/mpfr/src/jyn_asympt.c
new file mode 100644
index 0000000000..2f0e2fda54
--- /dev/null
+++ b/mpfr/src/jyn_asympt.c
@@ -0,0 +1,269 @@
+/* mpfr_jn_asympt, mpfr_yn_asympt -- shared code for mpfr_jn and mpfr_yn
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef MPFR_JN
+# define FUNCTION mpfr_jn_asympt
+#else
+# ifdef MPFR_YN
+# define FUNCTION mpfr_yn_asympt
+# else
+# error "neither MPFR_JN nor MPFR_YN is defined"
+# endif
+#endif
+
+/* Implements asymptotic expansion for jn or yn (formulae 9.2.5 and 9.2.6
+ from Abramowitz & Stegun).
+ Assumes |z| > p log(2)/2, where p is the target precision
+ (z can be negative only for jn).
+ Return 0 if the expansion does not converge enough (the value 0 as inexact
+ flag should not happen for normal input).
+*/
+static int
+FUNCTION (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
+{
+ mpfr_t s, c, P, Q, t, iz, err_t, err_s, err_u;
+ mpfr_prec_t w;
+ long k;
+ int inex, stop, diverge = 0;
+ mpfr_exp_t err2, err;
+ MPFR_ZIV_DECL (loop);
+
+ mpfr_init (c);
+
+ w = MPFR_PREC(res) + MPFR_INT_CEIL_LOG2(MPFR_PREC(res)) + 4;
+
+ MPFR_ZIV_INIT (loop, w);
+ for (;;)
+ {
+ mpfr_set_prec (c, w);
+ mpfr_init2 (s, w);
+ mpfr_init2 (P, w);
+ mpfr_init2 (Q, w);
+ mpfr_init2 (t, w);
+ mpfr_init2 (iz, w);
+ mpfr_init2 (err_t, 31);
+ mpfr_init2 (err_s, 31);
+ mpfr_init2 (err_u, 31);
+
+ /* Approximate sin(z) and cos(z). In the following, err <= k means that
+ the approximate value y and the true value x are related by
+ y = x * (1 + u)^k with |u| <= 2^(-w), following Higham's method. */
+ mpfr_sin_cos (s, c, z, MPFR_RNDN);
+ if (MPFR_IS_NEG(z))
+ mpfr_neg (s, s, MPFR_RNDN); /* compute jn/yn(|z|), fix sign later */
+ /* The absolute error on s/c is bounded by 1/2 ulp(1/2) <= 2^(-w-1). */
+ mpfr_add (t, s, c, MPFR_RNDN);
+ mpfr_sub (c, s, c, MPFR_RNDN);
+ mpfr_swap (s, t);
+ /* now s approximates sin(z)+cos(z), and c approximates sin(z)-cos(z),
+ with total absolute error bounded by 2^(1-w). */
+
+ /* precompute 1/(8|z|) */
+ mpfr_si_div (iz, MPFR_IS_POS(z) ? 1 : -1, z, MPFR_RNDN); /* err <= 1 */
+ mpfr_div_2ui (iz, iz, 3, MPFR_RNDN);
+
+ /* compute P and Q */
+ mpfr_set_ui (P, 1, MPFR_RNDN);
+ mpfr_set_ui (Q, 0, MPFR_RNDN);
+ mpfr_set_ui (t, 1, MPFR_RNDN); /* current term */
+ mpfr_set_ui (err_t, 0, MPFR_RNDN); /* error on t */
+ mpfr_set_ui (err_s, 0, MPFR_RNDN); /* error on P and Q (sum of errors) */
+ for (k = 1, stop = 0; stop < 4; k++)
+ {
+ /* compute next term: t(k)/t(k-1) = (2n+2k-1)(2n-2k+1)/(8kz) */
+ mpfr_mul_si (t, t, 2 * (n + k) - 1, MPFR_RNDN); /* err <= err_k + 1 */
+ mpfr_mul_si (t, t, 2 * (n - k) + 1, MPFR_RNDN); /* err <= err_k + 2 */
+ mpfr_div_ui (t, t, k, MPFR_RNDN); /* err <= err_k + 3 */
+ mpfr_mul (t, t, iz, MPFR_RNDN); /* err <= err_k + 5 */
+ /* the relative error on t is bounded by (1+u)^(5k)-1, which is
+ bounded by 6ku for 6ku <= 0.02: first |5 log(1+u)| <= |5.5u|
+ for |u| <= 0.15, then |exp(5.5u)-1| <= 6u for |u| <= 0.02. */
+ mpfr_mul_ui (err_t, t, 6 * k, MPFR_IS_POS(t) ? MPFR_RNDU : MPFR_RNDD);
+ mpfr_abs (err_t, err_t, MPFR_RNDN); /* exact */
+ /* the absolute error on t is bounded by err_t * 2^(-w) */
+ mpfr_abs (err_u, t, MPFR_RNDU);
+ mpfr_mul_2ui (err_u, err_u, w, MPFR_RNDU); /* t * 2^w */
+ mpfr_add (err_u, err_u, err_t, MPFR_RNDU); /* max|t| * 2^w */
+ if (stop >= 2)
+ {
+ /* take into account the neglected terms: t * 2^w */
+ mpfr_div_2ui (err_s, err_s, w, MPFR_RNDU);
+ if (MPFR_IS_POS(t))
+ mpfr_add (err_s, err_s, t, MPFR_RNDU);
+ else
+ mpfr_sub (err_s, err_s, t, MPFR_RNDU);
+ mpfr_mul_2ui (err_s, err_s, w, MPFR_RNDU);
+ stop ++;
+ }
+ /* if k is odd, add to Q, otherwise to P */
+ else if (k & 1)
+ {
+ /* if k = 1 mod 4, add, otherwise subtract */
+ if ((k & 2) == 0)
+ mpfr_add (Q, Q, t, MPFR_RNDN);
+ else
+ mpfr_sub (Q, Q, t, MPFR_RNDN);
+ /* check if the next term is smaller than ulp(Q): if EXP(err_u)
+ <= EXP(Q), since the current term is bounded by
+ err_u * 2^(-w), it is bounded by ulp(Q) */
+ if (MPFR_EXP(err_u) <= MPFR_EXP(Q))
+ stop ++;
+ else
+ stop = 0;
+ }
+ else
+ {
+ /* if k = 0 mod 4, add, otherwise subtract */
+ if ((k & 2) == 0)
+ mpfr_add (P, P, t, MPFR_RNDN);
+ else
+ mpfr_sub (P, P, t, MPFR_RNDN);
+ /* check if the next term is smaller than ulp(P) */
+ if (MPFR_EXP(err_u) <= MPFR_EXP(P))
+ stop ++;
+ else
+ stop = 0;
+ }
+ mpfr_add (err_s, err_s, err_t, MPFR_RNDU);
+ /* the sum of the rounding errors on P and Q is bounded by
+ err_s * 2^(-w) */
+
+ /* stop when start to diverge */
+ if (stop < 2 &&
+ ((MPFR_IS_POS(z) && mpfr_cmp_ui (z, (k + 1) / 2) < 0) ||
+ (MPFR_IS_NEG(z) && mpfr_cmp_si (z, - ((k + 1) / 2)) > 0)))
+ {
+ /* if we have to stop the series because it diverges, then
+ increasing the precision will most probably fail, since
+ we will stop to the same point, and thus compute a very
+ similar approximation */
+ diverge = 1;
+ stop = 2; /* force stop */
+ }
+ }
+ /* the sum of the total errors on P and Q is bounded by err_s * 2^(-w) */
+
+ /* Now combine: the sum of the rounding errors on P and Q is bounded by
+ err_s * 2^(-w), and the absolute error on s/c is bounded by 2^(1-w) */
+ if ((n & 1) == 0) /* n even: P * (sin + cos) + Q (cos - sin) for jn
+ Q * (sin + cos) + P (sin - cos) for yn */
+ {
+#ifdef MPFR_JN
+ mpfr_mul (c, c, Q, MPFR_RNDN); /* Q * (sin - cos) */
+ mpfr_mul (s, s, P, MPFR_RNDN); /* P * (sin + cos) */
+#else
+ mpfr_mul (c, c, P, MPFR_RNDN); /* P * (sin - cos) */
+ mpfr_mul (s, s, Q, MPFR_RNDN); /* Q * (sin + cos) */
+#endif
+ err = MPFR_EXP(c);
+ if (MPFR_EXP(s) > err)
+ err = MPFR_EXP(s);
+#ifdef MPFR_JN
+ mpfr_sub (s, s, c, MPFR_RNDN);
+#else
+ mpfr_add (s, s, c, MPFR_RNDN);
+#endif
+ }
+ else /* n odd: P * (sin - cos) + Q (cos + sin) for jn,
+ Q * (sin - cos) - P (cos + sin) for yn */
+ {
+#ifdef MPFR_JN
+ mpfr_mul (c, c, P, MPFR_RNDN); /* P * (sin - cos) */
+ mpfr_mul (s, s, Q, MPFR_RNDN); /* Q * (sin + cos) */
+#else
+ mpfr_mul (c, c, Q, MPFR_RNDN); /* Q * (sin - cos) */
+ mpfr_mul (s, s, P, MPFR_RNDN); /* P * (sin + cos) */
+#endif
+ err = MPFR_EXP(c);
+ if (MPFR_EXP(s) > err)
+ err = MPFR_EXP(s);
+#ifdef MPFR_JN
+ mpfr_add (s, s, c, MPFR_RNDN);
+#else
+ mpfr_sub (s, c, s, MPFR_RNDN);
+#endif
+ }
+ if ((n & 2) != 0)
+ mpfr_neg (s, s, MPFR_RNDN);
+ if (MPFR_EXP(s) > err)
+ err = MPFR_EXP(s);
+ /* the absolute error on s is bounded by P*err(s/c) + Q*err(s/c)
+ + err(P)*(s/c) + err(Q)*(s/c) + 3 * 2^(err - w - 1)
+ <= (|P|+|Q|) * 2^(1-w) + err_s * 2^(1-w) + 2^err * 2^(1-w),
+ since |c|, |old_s| <= 2. */
+ err2 = (MPFR_EXP(P) >= MPFR_EXP(Q)) ? MPFR_EXP(P) + 2 : MPFR_EXP(Q) + 2;
+ /* (|P| + |Q|) * 2^(1 - w) <= 2^(err2 - w) */
+ err = MPFR_EXP(err_s) >= err ? MPFR_EXP(err_s) + 2 : err + 2;
+ /* err_s * 2^(1-w) + 2^old_err * 2^(1-w) <= 2^err * 2^(-w) */
+ err2 = (err >= err2) ? err + 1 : err2 + 1;
+ /* now the absolute error on s is bounded by 2^(err2 - w) */
+
+ /* multiply by sqrt(1/(Pi*z)) */
+ mpfr_const_pi (c, MPFR_RNDN); /* Pi, err <= 1 */
+ mpfr_mul (c, c, z, MPFR_RNDN); /* err <= 2 */
+ mpfr_si_div (c, MPFR_IS_POS(z) ? 1 : -1, c, MPFR_RNDN); /* err <= 3 */
+ mpfr_sqrt (c, c, MPFR_RNDN); /* err<=5/2, thus the absolute error is
+ bounded by 3*u*|c| for |u| <= 0.25 */
+ mpfr_mul (err_t, c, s, MPFR_SIGN(c)==MPFR_SIGN(s) ? MPFR_RNDU : MPFR_RNDD);
+ mpfr_abs (err_t, err_t, MPFR_RNDU);
+ mpfr_mul_ui (err_t, err_t, 3, MPFR_RNDU);
+ /* 3*2^(-w)*|old_c|*|s| [see below] is bounded by err_t * 2^(-w) */
+ err2 += MPFR_EXP(c);
+ /* |old_c| * 2^(err2 - w) [see below] is bounded by 2^(err2-w) */
+ mpfr_mul (c, c, s, MPFR_RNDN); /* the absolute error on c is bounded by
+ 1/2 ulp(c) + 3*2^(-w)*|old_c|*|s|
+ + |old_c| * 2^(err2 - w) */
+ /* compute err_t * 2^(-w) + 1/2 ulp(c) = (err_t + 2^EXP(c)) * 2^(-w) */
+ err = (MPFR_EXP(err_t) > MPFR_EXP(c)) ? MPFR_EXP(err_t) + 1 : MPFR_EXP(c) + 1;
+ /* err_t * 2^(-w) + 1/2 ulp(c) <= 2^(err - w) */
+ /* now err_t * 2^(-w) bounds 1/2 ulp(c) + 3*2^(-w)*|old_c|*|s| */
+ err = (err >= err2) ? err + 1 : err2 + 1;
+ /* the absolute error on c is bounded by 2^(err - w) */
+
+ mpfr_clear (s);
+ mpfr_clear (P);
+ mpfr_clear (Q);
+ mpfr_clear (t);
+ mpfr_clear (iz);
+ mpfr_clear (err_t);
+ mpfr_clear (err_s);
+ mpfr_clear (err_u);
+
+ err -= MPFR_EXP(c);
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (c, w - err, MPFR_PREC(res), r)))
+ break;
+ if (diverge != 0)
+ {
+ mpfr_set (c, z, r); /* will force inex=0 below, which means the
+ asymptotic expansion failed */
+ break;
+ }
+ MPFR_ZIV_NEXT (loop, w);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inex = (MPFR_IS_POS(z) || ((n & 1) == 0)) ? mpfr_set (res, c, r)
+ : mpfr_neg (res, c, r);
+ mpfr_clear (c);
+
+ return inex;
+}
diff --git a/mpfr/src/li2.c b/mpfr/src/li2.c
new file mode 100644
index 0000000000..c118c0fa2b
--- /dev/null
+++ b/mpfr/src/li2.c
@@ -0,0 +1,634 @@
+/* mpfr_li2 -- Dilogarithm.
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Compute the alternating series
+ s = S(z) = \sum_{k=0}^infty B_{2k} (z))^{2k+1} / (2k+1)!
+ with 0 < z <= log(2) to the precision of s rounded in the direction
+ rnd_mode.
+ Return the maximum index of the truncature which is useful
+ for determinating the relative error.
+*/
+static int
+li2_series (mpfr_t sum, mpfr_srcptr z, mpfr_rnd_t rnd_mode)
+{
+ int i, Bm, Bmax;
+ mpfr_t s, u, v, w;
+ mpfr_prec_t sump, p;
+ mpfr_exp_t se, err;
+ mpz_t *B;
+ MPFR_ZIV_DECL (loop);
+
+ /* The series converges for |z| < 2 pi, but in mpfr_li2 the argument is
+ reduced so that 0 < z <= log(2). Here is additionnal check that z is
+ (nearly) correct */
+ MPFR_ASSERTD (MPFR_IS_STRICTPOS (z));
+ MPFR_ASSERTD (mpfr_cmp_d (z, 0.6953125) <= 0);
+
+ sump = MPFR_PREC (sum); /* target precision */
+ p = sump + MPFR_INT_CEIL_LOG2 (sump) + 4; /* the working precision */
+ mpfr_init2 (s, p);
+ mpfr_init2 (u, p);
+ mpfr_init2 (v, p);
+ mpfr_init2 (w, p);
+
+ B = mpfr_bernoulli_internal ((mpz_t *) 0, 0);
+ Bm = Bmax = 1;
+
+ MPFR_ZIV_INIT (loop, p);
+ for (;;)
+ {
+ mpfr_sqr (u, z, MPFR_RNDU);
+ mpfr_set (v, z, MPFR_RNDU);
+ mpfr_set (s, z, MPFR_RNDU);
+ se = MPFR_GET_EXP (s);
+ err = 0;
+
+ for (i = 1;; i++)
+ {
+ if (i >= Bmax)
+ B = mpfr_bernoulli_internal (B, Bmax++); /* B_2i*(2i+1)!, exact */
+
+ mpfr_mul (v, u, v, MPFR_RNDU);
+ mpfr_div_ui (v, v, 2 * i, MPFR_RNDU);
+ mpfr_div_ui (v, v, 2 * i, MPFR_RNDU);
+ mpfr_div_ui (v, v, 2 * i + 1, MPFR_RNDU);
+ mpfr_div_ui (v, v, 2 * i + 1, MPFR_RNDU);
+ /* here, v_2i = v_{2i-2} / (2i * (2i+1))^2 */
+
+ mpfr_mul_z (w, v, B[i], MPFR_RNDN);
+ /* here, w_2i = v_2i * B_2i * (2i+1)! with
+ error(w_2i) < 2^(5 * i + 8) ulp(w_2i) (see algorithms.tex) */
+
+ mpfr_add (s, s, w, MPFR_RNDN);
+
+ err = MAX (err + se, 5 * i + 8 + MPFR_GET_EXP (w))
+ - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err);
+ se = MPFR_GET_EXP (s);
+ if (MPFR_GET_EXP (w) <= se - (mpfr_exp_t) p)
+ break;
+ }
+
+ /* the previous value of err is the rounding error,
+ the truncation error is less than EXP(z) - 6 * i - 5
+ (see algorithms.tex) */
+ err = MAX (err, MPFR_GET_EXP (z) - 6 * i - 5) + 1;
+ if (MPFR_CAN_ROUND (s, (mpfr_exp_t) p - err, sump, rnd_mode))
+ break;
+
+ MPFR_ZIV_NEXT (loop, p);
+ mpfr_set_prec (s, p);
+ mpfr_set_prec (u, p);
+ mpfr_set_prec (v, p);
+ mpfr_set_prec (w, p);
+ }
+ MPFR_ZIV_FREE (loop);
+ mpfr_set (sum, s, rnd_mode);
+
+ Bm = Bmax;
+ while (Bm--)
+ mpz_clear (B[Bm]);
+ (*__gmp_free_func) (B, Bmax * sizeof (mpz_t));
+ mpfr_clears (s, u, v, w, (mpfr_ptr) 0);
+
+ /* Let K be the returned value.
+ 1. As we compute an alternating series, the truncation error has the same
+ sign as the next term w_{K+2} which is positive iff K%4 == 0.
+ 2. Assume that error(z) <= (1+t) z', where z' is the actual value, then
+ error(s) <= 2 * (K+1) * t (see algorithms.tex).
+ */
+ return 2 * i;
+}
+
+/* try asymptotic expansion when x is large and positive:
+ Li2(x) = -log(x)^2/2 + Pi^2/3 - 1/x + O(1/x^2).
+ More precisely for x >= 2 we have for g(x) = -log(x)^2/2 + Pi^2/3:
+ -2 <= x * (Li2(x) - g(x)) <= -1
+ thus |Li2(x) - g(x)| <= 2/x.
+ Assumes x >= 38, which ensures log(x)^2/2 >= 2*Pi^2/3, and g(x) <= -3.3.
+ Return 0 if asymptotic expansion failed (unable to round), otherwise
+ returns correct ternary value.
+*/
+static int
+mpfr_li2_asympt_pos (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t g, h;
+ mpfr_prec_t w = MPFR_PREC (y) + 20;
+ int inex = 0;
+
+ MPFR_ASSERTN (mpfr_cmp_ui (x, 38) >= 0);
+
+ mpfr_init2 (g, w);
+ mpfr_init2 (h, w);
+ mpfr_log (g, x, MPFR_RNDN); /* rel. error <= |(1 + theta) - 1| */
+ mpfr_sqr (g, g, MPFR_RNDN); /* rel. error <= |(1 + theta)^3 - 1| <= 2^(2-w) */
+ mpfr_div_2ui (g, g, 1, MPFR_RNDN); /* rel. error <= 2^(2-w) */
+ mpfr_const_pi (h, MPFR_RNDN); /* error <= 2^(1-w) */
+ mpfr_sqr (h, h, MPFR_RNDN); /* rel. error <= 2^(2-w) */
+ mpfr_div_ui (h, h, 3, MPFR_RNDN); /* rel. error <= |(1 + theta)^4 - 1|
+ <= 5 * 2^(-w) */
+ /* since x is chosen such that log(x)^2/2 >= 2 * (Pi^2/3), we should have
+ g >= 2*h, thus |g-h| >= |h|, and the relative error on g is at most
+ multiplied by 2 in the difference, and that by h is unchanged. */
+ MPFR_ASSERTN (MPFR_EXP (g) > MPFR_EXP (h));
+ mpfr_sub (g, h, g, MPFR_RNDN); /* err <= ulp(g)/2 + g*2^(3-w) + g*5*2^(-w)
+ <= ulp(g) * (1/2 + 8 + 5) < 14 ulp(g).
+
+ If in addition 2/x <= 2 ulp(g), i.e.,
+ 1/x <= ulp(g), then the total error is
+ bounded by 16 ulp(g). */
+ if ((MPFR_EXP (x) >= (mpfr_exp_t) w - MPFR_EXP (g)) &&
+ MPFR_CAN_ROUND (g, w - 4, MPFR_PREC (y), rnd_mode))
+ inex = mpfr_set (y, g, rnd_mode);
+
+ mpfr_clear (g);
+ mpfr_clear (h);
+
+ return inex;
+}
+
+/* try asymptotic expansion when x is large and negative:
+ Li2(x) = -log(-x)^2/2 - Pi^2/6 - 1/x + O(1/x^2).
+ More precisely for x <= -2 we have for g(x) = -log(-x)^2/2 - Pi^2/6:
+ |Li2(x) - g(x)| <= 1/|x|.
+ Assumes x <= -7, which ensures |log(-x)^2/2| >= Pi^2/6, and g(x) <= -3.5.
+ Return 0 if asymptotic expansion failed (unable to round), otherwise
+ returns correct ternary value.
+*/
+static int
+mpfr_li2_asympt_neg (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t g, h;
+ mpfr_prec_t w = MPFR_PREC (y) + 20;
+ int inex = 0;
+
+ MPFR_ASSERTN (mpfr_cmp_si (x, -7) <= 0);
+
+ mpfr_init2 (g, w);
+ mpfr_init2 (h, w);
+ mpfr_neg (g, x, MPFR_RNDN);
+ mpfr_log (g, g, MPFR_RNDN); /* rel. error <= |(1 + theta) - 1| */
+ mpfr_sqr (g, g, MPFR_RNDN); /* rel. error <= |(1 + theta)^3 - 1| <= 2^(2-w) */
+ mpfr_div_2ui (g, g, 1, MPFR_RNDN); /* rel. error <= 2^(2-w) */
+ mpfr_const_pi (h, MPFR_RNDN); /* error <= 2^(1-w) */
+ mpfr_sqr (h, h, MPFR_RNDN); /* rel. error <= 2^(2-w) */
+ mpfr_div_ui (h, h, 6, MPFR_RNDN); /* rel. error <= |(1 + theta)^4 - 1|
+ <= 5 * 2^(-w) */
+ MPFR_ASSERTN (MPFR_EXP (g) >= MPFR_EXP (h));
+ mpfr_add (g, g, h, MPFR_RNDN); /* err <= ulp(g)/2 + g*2^(2-w) + g*5*2^(-w)
+ <= ulp(g) * (1/2 + 4 + 5) < 10 ulp(g).
+
+ If in addition |1/x| <= 4 ulp(g), then the
+ total error is bounded by 16 ulp(g). */
+ if ((MPFR_EXP (x) >= (mpfr_exp_t) (w - 2) - MPFR_EXP (g)) &&
+ MPFR_CAN_ROUND (g, w - 4, MPFR_PREC (y), rnd_mode))
+ inex = mpfr_neg (y, g, rnd_mode);
+
+ mpfr_clear (g);
+ mpfr_clear (h);
+
+ return inex;
+}
+
+/* Compute the real part of the dilogarithm defined by
+ Li2(x) = -\Int_{t=0}^x log(1-t)/t dt */
+int
+mpfr_li2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_exp_t err;
+ mpfr_prec_t yp, m;
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ MPFR_SET_NEG (y);
+ MPFR_SET_INF (y);
+ MPFR_RET (0);
+ }
+ else /* x is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_SET_ZERO (y);
+ MPFR_RET (0);
+ }
+ }
+
+ /* Li2(x) = x + x^2/4 + x^3/9 + ..., more precisely for 0 < x <= 1/2
+ we have |Li2(x) - x| < x^2/2 <= 2^(2EXP(x)-1) and for -1/2 <= x < 0
+ we have |Li2(x) - x| < x^2/4 <= 2^(2EXP(x)-2) */
+ if (MPFR_IS_POS (x))
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -MPFR_GET_EXP (x), 1, 1, rnd_mode,
+ {});
+ else
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -MPFR_GET_EXP (x), 2, 0, rnd_mode,
+ {});
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ yp = MPFR_PREC (y);
+ m = yp + MPFR_INT_CEIL_LOG2 (yp) + 13;
+
+ if (MPFR_LIKELY ((mpfr_cmp_ui (x, 0) > 0) && (mpfr_cmp_d (x, 0.5) <= 0)))
+ /* 0 < x <= 1/2: Li2(x) = S(-log(1-x))-log^2(1-x)/4 */
+ {
+ mpfr_t s, u;
+ mpfr_exp_t expo_l;
+ int k;
+
+ mpfr_init2 (u, m);
+ mpfr_init2 (s, m);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ mpfr_ui_sub (u, 1, x, MPFR_RNDN);
+ mpfr_log (u, u, MPFR_RNDU);
+ if (MPFR_IS_ZERO(u))
+ goto next_m;
+ mpfr_neg (u, u, MPFR_RNDN); /* u = -log(1-x) */
+ expo_l = MPFR_GET_EXP (u);
+ k = li2_series (s, u, MPFR_RNDU);
+ err = 1 + MPFR_INT_CEIL_LOG2 (k + 1);
+
+ mpfr_sqr (u, u, MPFR_RNDU);
+ mpfr_div_2ui (u, u, 2, MPFR_RNDU); /* u = log^2(1-x) / 4 */
+ mpfr_sub (s, s, u, MPFR_RNDN);
+
+ /* error(s) <= (0.5 + 2^(d-EXP(s))
+ + 2^(3 + MAX(1, - expo_l) - EXP(s))) ulp(s) */
+ err = MAX (err, MAX (1, - expo_l) - 1) - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err);
+ if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
+ break;
+
+ next_m:
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (u, m);
+ mpfr_set_prec (s, m);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (y, s, rnd_mode);
+
+ mpfr_clear (u);
+ mpfr_clear (s);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
+ else if (!mpfr_cmp_ui (x, 1))
+ /* Li2(1)= pi^2 / 6 */
+ {
+ mpfr_t u;
+ mpfr_init2 (u, m);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ mpfr_const_pi (u, MPFR_RNDU);
+ mpfr_sqr (u, u, MPFR_RNDN);
+ mpfr_div_ui (u, u, 6, MPFR_RNDN);
+
+ err = m - 4; /* error(u) <= 19/2 ulp(u) */
+ if (MPFR_CAN_ROUND (u, err, yp, rnd_mode))
+ break;
+
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (u, m);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (y, u, rnd_mode);
+
+ mpfr_clear (u);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
+ else if (mpfr_cmp_ui (x, 2) >= 0)
+ /* x >= 2: Li2(x) = -S(-log(1-1/x))-log^2(x)/2+log^2(1-1/x)/4+pi^2/3 */
+ {
+ int k;
+ mpfr_exp_t expo_l;
+ mpfr_t s, u, xx;
+
+ if (mpfr_cmp_ui (x, 38) >= 0)
+ {
+ inexact = mpfr_li2_asympt_pos (y, x, rnd_mode);
+ if (inexact != 0)
+ goto end_of_case_gt2;
+ }
+
+ mpfr_init2 (u, m);
+ mpfr_init2 (s, m);
+ mpfr_init2 (xx, m);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ mpfr_ui_div (xx, 1, x, MPFR_RNDN);
+ mpfr_neg (xx, xx, MPFR_RNDN);
+ mpfr_log1p (u, xx, MPFR_RNDD);
+ mpfr_neg (u, u, MPFR_RNDU); /* u = -log(1-1/x) */
+ expo_l = MPFR_GET_EXP (u);
+ k = li2_series (s, u, MPFR_RNDN);
+ mpfr_neg (s, s, MPFR_RNDN);
+ err = MPFR_INT_CEIL_LOG2 (k + 1) + 1; /* error(s) <= 2^err ulp(s) */
+
+ mpfr_sqr (u, u, MPFR_RNDN);
+ mpfr_div_2ui (u, u, 2, MPFR_RNDN); /* u= log^2(1-1/x)/4 */
+ mpfr_add (s, s, u, MPFR_RNDN);
+ err =
+ MAX (err,
+ 3 + MAX (1, -expo_l) + MPFR_GET_EXP (u)) - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err); /* error(s) <= 2^err ulp(s) */
+ err += MPFR_GET_EXP (s);
+
+ mpfr_log (u, x, MPFR_RNDU);
+ mpfr_sqr (u, u, MPFR_RNDN);
+ mpfr_div_2ui (u, u, 1, MPFR_RNDN); /* u = log^2(x)/2 */
+ mpfr_sub (s, s, u, MPFR_RNDN);
+ err = MAX (err, 3 + MPFR_GET_EXP (u)) - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err); /* error(s) <= 2^err ulp(s) */
+ err += MPFR_GET_EXP (s);
+
+ mpfr_const_pi (u, MPFR_RNDU);
+ mpfr_sqr (u, u, MPFR_RNDN);
+ mpfr_div_ui (u, u, 3, MPFR_RNDN); /* u = pi^2/3 */
+ mpfr_add (s, s, u, MPFR_RNDN);
+ err = MAX (err, 2) - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err); /* error(s) <= 2^err ulp(s) */
+ if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
+ break;
+
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (u, m);
+ mpfr_set_prec (s, m);
+ mpfr_set_prec (xx, m);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (y, s, rnd_mode);
+ mpfr_clears (s, u, xx, (mpfr_ptr) 0);
+
+ end_of_case_gt2:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
+ else if (mpfr_cmp_ui (x, 1) > 0)
+ /* 2 > x > 1: Li2(x) = S(log(x))+log^2(x)/4-log(x)log(x-1)+pi^2/6 */
+ {
+ int k;
+ mpfr_exp_t e1, e2;
+ mpfr_t s, u, v, xx;
+ mpfr_init2 (s, m);
+ mpfr_init2 (u, m);
+ mpfr_init2 (v, m);
+ mpfr_init2 (xx, m);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ mpfr_log (v, x, MPFR_RNDU);
+ k = li2_series (s, v, MPFR_RNDN);
+ e1 = MPFR_GET_EXP (s);
+
+ mpfr_sqr (u, v, MPFR_RNDN);
+ mpfr_div_2ui (u, u, 2, MPFR_RNDN); /* u = log^2(x)/4 */
+ mpfr_add (s, s, u, MPFR_RNDN);
+
+ mpfr_sub_ui (xx, x, 1, MPFR_RNDN);
+ mpfr_log (u, xx, MPFR_RNDU);
+ e2 = MPFR_GET_EXP (u);
+ mpfr_mul (u, v, u, MPFR_RNDN); /* u = log(x) * log(x-1) */
+ mpfr_sub (s, s, u, MPFR_RNDN);
+
+ mpfr_const_pi (u, MPFR_RNDU);
+ mpfr_sqr (u, u, MPFR_RNDN);
+ mpfr_div_ui (u, u, 6, MPFR_RNDN); /* u = pi^2/6 */
+ mpfr_add (s, s, u, MPFR_RNDN);
+ /* error(s) <= (31 + (k+1) * 2^(1-e1) + 2^(1-e2)) ulp(s)
+ see algorithms.tex */
+ err = MAX (MPFR_INT_CEIL_LOG2 (k + 1) + 1 - e1, 1 - e2);
+ err = 2 + MAX (5, err);
+ if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
+ break;
+
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (s, m);
+ mpfr_set_prec (u, m);
+ mpfr_set_prec (v, m);
+ mpfr_set_prec (xx, m);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (y, s, rnd_mode);
+
+ mpfr_clears (s, u, v, xx, (mpfr_ptr) 0);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
+ else if (mpfr_cmp_ui_2exp (x, 1, -1) > 0) /* 1/2 < x < 1 */
+ /* 1 > x > 1/2: Li2(x) = -S(-log(x))+log^2(x)/4-log(x)log(1-x)+pi^2/6 */
+ {
+ int k;
+ mpfr_t s, u, v, xx;
+ mpfr_init2 (s, m);
+ mpfr_init2 (u, m);
+ mpfr_init2 (v, m);
+ mpfr_init2 (xx, m);
+
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ mpfr_log (u, x, MPFR_RNDD);
+ mpfr_neg (u, u, MPFR_RNDN);
+ k = li2_series (s, u, MPFR_RNDN);
+ mpfr_neg (s, s, MPFR_RNDN);
+ err = 1 + MPFR_INT_CEIL_LOG2 (k + 1) - MPFR_GET_EXP (s);
+
+ mpfr_ui_sub (xx, 1, x, MPFR_RNDN);
+ mpfr_log (v, xx, MPFR_RNDU);
+ mpfr_mul (v, v, u, MPFR_RNDN); /* v = - log(x) * log(1-x) */
+ mpfr_add (s, s, v, MPFR_RNDN);
+ err = MAX (err, 1 - MPFR_GET_EXP (v));
+ err = 2 + MAX (3, err) - MPFR_GET_EXP (s);
+
+ mpfr_sqr (u, u, MPFR_RNDN);
+ mpfr_div_2ui (u, u, 2, MPFR_RNDN); /* u = log^2(x)/4 */
+ mpfr_add (s, s, u, MPFR_RNDN);
+ err = MAX (err, 2 + MPFR_GET_EXP (u)) - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
+
+ mpfr_const_pi (u, MPFR_RNDU);
+ mpfr_sqr (u, u, MPFR_RNDN);
+ mpfr_div_ui (u, u, 6, MPFR_RNDN); /* u = pi^2/6 */
+ mpfr_add (s, s, u, MPFR_RNDN);
+ err = MAX (err, 3) - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err);
+
+ if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
+ break;
+
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (s, m);
+ mpfr_set_prec (u, m);
+ mpfr_set_prec (v, m);
+ mpfr_set_prec (xx, m);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (y, s, rnd_mode);
+
+ mpfr_clears (s, u, v, xx, (mpfr_ptr) 0);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
+ else if (mpfr_cmp_si (x, -1) >= 0)
+ /* 0 > x >= -1: Li2(x) = -S(log(1-x))-log^2(1-x)/4 */
+ {
+ int k;
+ mpfr_exp_t expo_l;
+ mpfr_t s, u, xx;
+ mpfr_init2 (s, m);
+ mpfr_init2 (u, m);
+ mpfr_init2 (xx, m);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ mpfr_neg (xx, x, MPFR_RNDN);
+ mpfr_log1p (u, xx, MPFR_RNDN);
+ k = li2_series (s, u, MPFR_RNDN);
+ mpfr_neg (s, s, MPFR_RNDN);
+ expo_l = MPFR_GET_EXP (u);
+ err = 1 + MPFR_INT_CEIL_LOG2 (k + 1) - MPFR_GET_EXP (s);
+
+ mpfr_sqr (u, u, MPFR_RNDN);
+ mpfr_div_2ui (u, u, 2, MPFR_RNDN); /* u = log^2(1-x)/4 */
+ mpfr_sub (s, s, u, MPFR_RNDN);
+ err = MAX (err, - expo_l);
+ err = 2 + MAX (err, 3);
+ if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
+ break;
+
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (s, m);
+ mpfr_set_prec (u, m);
+ mpfr_set_prec (xx, m);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (y, s, rnd_mode);
+
+ mpfr_clears (s, u, xx, (mpfr_ptr) 0);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
+ else
+ /* x < -1: Li2(x)
+ = S(log(1-1/x))-log^2(-x)/4-log(1-x)log(-x)/2+log^2(1-x)/4-pi^2/6 */
+ {
+ int k;
+ mpfr_t s, u, v, w, xx;
+
+ if (mpfr_cmp_si (x, -7) <= 0)
+ {
+ inexact = mpfr_li2_asympt_neg (y, x, rnd_mode);
+ if (inexact != 0)
+ goto end_of_case_ltm1;
+ }
+
+ mpfr_init2 (s, m);
+ mpfr_init2 (u, m);
+ mpfr_init2 (v, m);
+ mpfr_init2 (w, m);
+ mpfr_init2 (xx, m);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ mpfr_ui_div (xx, 1, x, MPFR_RNDN);
+ mpfr_neg (xx, xx, MPFR_RNDN);
+ mpfr_log1p (u, xx, MPFR_RNDN);
+ k = li2_series (s, u, MPFR_RNDN);
+
+ mpfr_ui_sub (xx, 1, x, MPFR_RNDN);
+ mpfr_log (u, xx, MPFR_RNDU);
+ mpfr_neg (xx, x, MPFR_RNDN);
+ mpfr_log (v, xx, MPFR_RNDU);
+ mpfr_mul (w, v, u, MPFR_RNDN);
+ mpfr_div_2ui (w, w, 1, MPFR_RNDN); /* w = log(-x) * log(1-x) / 2 */
+ mpfr_sub (s, s, w, MPFR_RNDN);
+ err = 1 + MAX (3, MPFR_INT_CEIL_LOG2 (k+1) + 1 - MPFR_GET_EXP (s))
+ + MPFR_GET_EXP (s);
+
+ mpfr_sqr (w, v, MPFR_RNDN);
+ mpfr_div_2ui (w, w, 2, MPFR_RNDN); /* w = log^2(-x) / 4 */
+ mpfr_sub (s, s, w, MPFR_RNDN);
+ err = MAX (err, 3 + MPFR_GET_EXP(w)) - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
+
+ mpfr_sqr (w, u, MPFR_RNDN);
+ mpfr_div_2ui (w, w, 2, MPFR_RNDN); /* w = log^2(1-x) / 4 */
+ mpfr_add (s, s, w, MPFR_RNDN);
+ err = MAX (err, 3 + MPFR_GET_EXP (w)) - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
+
+ mpfr_const_pi (w, MPFR_RNDU);
+ mpfr_sqr (w, w, MPFR_RNDN);
+ mpfr_div_ui (w, w, 6, MPFR_RNDN); /* w = pi^2 / 6 */
+ mpfr_sub (s, s, w, MPFR_RNDN);
+ err = MAX (err, 3) - MPFR_GET_EXP (s);
+ err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
+
+ if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
+ break;
+
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (s, m);
+ mpfr_set_prec (u, m);
+ mpfr_set_prec (v, m);
+ mpfr_set_prec (w, m);
+ mpfr_set_prec (xx, m);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (y, s, rnd_mode);
+ mpfr_clears (s, u, v, w, xx, (mpfr_ptr) 0);
+
+ end_of_case_ltm1:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
+
+ MPFR_ASSERTN (0); /* should never reach this point */
+}
diff --git a/mpfr/src/lngamma.c b/mpfr/src/lngamma.c
new file mode 100644
index 0000000000..c400bd8d3a
--- /dev/null
+++ b/mpfr/src/lngamma.c
@@ -0,0 +1,738 @@
+/* mpfr_lngamma -- lngamma function
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* given a precision p, return alpha, such that the argument reduction
+ will use k = alpha*p*log(2).
+
+ Warning: we should always have alpha >= log(2)/(2Pi) ~ 0.11,
+ and the smallest value of alpha multiplied by the smallest working
+ precision should be >= 4.
+*/
+static void
+mpfr_gamma_alpha (mpfr_t s, mpfr_prec_t p)
+{
+ if (p <= 100)
+ mpfr_set_ui_2exp (s, 614, -10, MPFR_RNDN); /* about 0.6 */
+ else if (p <= 500)
+ mpfr_set_ui_2exp (s, 819, -10, MPFR_RNDN); /* about 0.8 */
+ else if (p <= 1000)
+ mpfr_set_ui_2exp (s, 1331, -10, MPFR_RNDN); /* about 1.3 */
+ else if (p <= 2000)
+ mpfr_set_ui_2exp (s, 1741, -10, MPFR_RNDN); /* about 1.7 */
+ else if (p <= 5000)
+ mpfr_set_ui_2exp (s, 2253, -10, MPFR_RNDN); /* about 2.2 */
+ else if (p <= 10000)
+ mpfr_set_ui_2exp (s, 3482, -10, MPFR_RNDN); /* about 3.4 */
+ else
+ mpfr_set_ui_2exp (s, 9, -1, MPFR_RNDN); /* 4.5 */
+}
+
+#ifdef IS_GAMMA
+
+/* This function is called in case of intermediate overflow/underflow.
+ The s1 and s2 arguments are temporary MPFR numbers, having the
+ working precision. If the result could be determined, then the
+ flags are updated via pexpo, y is set to the result, and the
+ (non-zero) ternary value is returned. Otherwise 0 is returned
+ in order to perform the next Ziv iteration. */
+static int
+mpfr_explgamma (mpfr_ptr y, mpfr_srcptr x, mpfr_save_expo_t *pexpo,
+ mpfr_ptr s1, mpfr_ptr s2, mpfr_rnd_t rnd)
+{
+ mpfr_t t1, t2;
+ int inex1, inex2, sign;
+ MPFR_BLOCK_DECL (flags1);
+ MPFR_BLOCK_DECL (flags2);
+ MPFR_GROUP_DECL (group);
+
+ MPFR_BLOCK (flags1, inex1 = mpfr_lgamma (s1, &sign, x, MPFR_RNDD));
+ MPFR_ASSERTN (inex1 != 0);
+ /* s1 = RNDD(lngamma(x)), inexact */
+ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags1)))
+ {
+ if (MPFR_SIGN (s1) > 0)
+ {
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (*pexpo, MPFR_FLAGS_OVERFLOW);
+ return mpfr_overflow (y, rnd, sign);
+ }
+ else
+ {
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (*pexpo, MPFR_FLAGS_UNDERFLOW);
+ return mpfr_underflow (y, rnd == MPFR_RNDN ? MPFR_RNDZ : rnd, sign);
+ }
+ }
+
+ mpfr_set (s2, s1, MPFR_RNDN); /* exact */
+ mpfr_nextabove (s2); /* v = RNDU(lngamma(z0)) */
+
+ if (sign < 0)
+ rnd = MPFR_INVERT_RND (rnd); /* since the result with be negated */
+ MPFR_GROUP_INIT_2 (group, MPFR_PREC (y), t1, t2);
+ MPFR_BLOCK (flags1, inex1 = mpfr_exp (t1, s1, rnd));
+ MPFR_BLOCK (flags2, inex2 = mpfr_exp (t2, s2, rnd));
+ /* t1 is the rounding with mode 'rnd' of a lower bound on |Gamma(x)|,
+ t2 is the rounding with mode 'rnd' of an upper bound, thus if both
+ are equal, so is the wanted result. If t1 and t2 differ or the flags
+ differ, at some point of Ziv's loop they should agree. */
+ if (mpfr_equal_p (t1, t2) && flags1 == flags2)
+ {
+ MPFR_ASSERTN ((inex1 > 0 && inex2 > 0) || (inex1 < 0 && inex2 < 0));
+ mpfr_set4 (y, t1, MPFR_RNDN, sign); /* exact */
+ if (sign < 0)
+ inex1 = - inex1;
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (*pexpo, flags1);
+ }
+ else
+ inex1 = 0; /* couldn't determine the result */
+ MPFR_GROUP_CLEAR (group);
+
+ return inex1;
+}
+
+#else
+
+static int
+unit_bit (mpfr_srcptr x)
+{
+ mpfr_exp_t expo;
+ mpfr_prec_t prec;
+ mp_limb_t x0;
+
+ expo = MPFR_GET_EXP (x);
+ if (expo <= 0)
+ return 0; /* |x| < 1 */
+
+ prec = MPFR_PREC (x);
+ if (expo > prec)
+ return 0; /* y is a multiple of 2^(expo-prec), thus an even integer */
+
+ /* Now, the unit bit is represented. */
+
+ prec = MPFR_PREC2LIMBS (prec) * GMP_NUMB_BITS - expo;
+ /* number of represented fractional bits (including the trailing 0's) */
+
+ x0 = *(MPFR_MANT (x) + prec / GMP_NUMB_BITS);
+ /* limb containing the unit bit */
+
+ return (x0 >> (prec % GMP_NUMB_BITS)) & 1;
+}
+
+#endif
+
+/* lngamma(x) = log(gamma(x)).
+ We use formula [6.1.40] from Abramowitz&Stegun:
+ lngamma(z) = (z-1/2)*log(z) - z + 1/2*log(2*Pi)
+ + sum (Bernoulli[2m]/(2m)/(2m-1)/z^(2m-1),m=1..infinity)
+ According to [6.1.42], if the sum is truncated after m=n, the error
+ R_n(z) is bounded by |B[2n+2]|*K(z)/(2n+1)/(2n+2)/|z|^(2n+1)
+ where K(z) = max (z^2/(u^2+z^2)) for u >= 0.
+ For z real, |K(z)| <= 1 thus R_n(z) is bounded by the first neglected term.
+ */
+#ifdef IS_GAMMA
+#define GAMMA_FUNC mpfr_gamma_aux
+#else
+#define GAMMA_FUNC mpfr_lngamma_aux
+#endif
+
+static int
+GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mpfr_rnd_t rnd)
+{
+ mpfr_prec_t precy, w; /* working precision */
+ mpfr_t s, t, u, v, z;
+ unsigned long m, k, maxm;
+ mpz_t *INITIALIZED(B); /* variable B declared as initialized */
+ int compared;
+ int inexact = 0; /* 0 means: result y not set yet */
+ mpfr_exp_t err_s, err_t;
+ unsigned long Bm = 0; /* number of allocated B[] */
+ unsigned long oldBm;
+ double d;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ compared = mpfr_cmp_ui (z0, 1);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+#ifndef IS_GAMMA /* lngamma or lgamma */
+ if (compared == 0 || (compared > 0 && mpfr_cmp_ui (z0, 2) == 0))
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_set_ui (y, 0, MPFR_RNDN); /* lngamma(1 or 2) = +0 */
+ }
+
+ /* Deal here with tiny inputs. We have for -0.3 <= x <= 0.3:
+ - log|x| - gamma*x <= log|gamma(x)| <= - log|x| - gamma*x + x^2 */
+ if (MPFR_EXP(z0) <= - (mpfr_exp_t) MPFR_PREC(y))
+ {
+ mpfr_t l, h, g;
+ int ok, inex1, inex2;
+ mpfr_prec_t prec = MPFR_PREC(y) + 14;
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_ZIV_INIT (loop, prec);
+ do
+ {
+ mpfr_init2 (l, prec);
+ if (MPFR_IS_POS(z0))
+ {
+ mpfr_log (l, z0, MPFR_RNDU); /* upper bound for log(z0) */
+ mpfr_init2 (h, MPFR_PREC(l));
+ }
+ else
+ {
+ mpfr_init2 (h, MPFR_PREC(z0));
+ mpfr_neg (h, z0, MPFR_RNDN); /* exact */
+ mpfr_log (l, h, MPFR_RNDU); /* upper bound for log(-z0) */
+ mpfr_set_prec (h, MPFR_PREC(l));
+ }
+ mpfr_neg (l, l, MPFR_RNDD); /* lower bound for -log(|z0|) */
+ mpfr_set (h, l, MPFR_RNDD); /* exact */
+ mpfr_nextabove (h); /* upper bound for -log(|z0|), avoids two calls
+ to mpfr_log */
+ mpfr_init2 (g, MPFR_PREC(l));
+ /* if z0>0, we need an upper approximation of Euler's constant
+ for the left bound */
+ mpfr_const_euler (g, MPFR_IS_POS(z0) ? MPFR_RNDU : MPFR_RNDD);
+ mpfr_mul (g, g, z0, MPFR_RNDD);
+ mpfr_sub (l, l, g, MPFR_RNDD);
+ mpfr_const_euler (g, MPFR_IS_POS(z0) ? MPFR_RNDD : MPFR_RNDU); /* cached */
+ mpfr_mul (g, g, z0, MPFR_RNDU);
+ mpfr_sub (h, h, g, MPFR_RNDD);
+ mpfr_mul (g, z0, z0, MPFR_RNDU);
+ mpfr_add (h, h, g, MPFR_RNDU);
+ inex1 = mpfr_prec_round (l, MPFR_PREC(y), rnd);
+ inex2 = mpfr_prec_round (h, MPFR_PREC(y), rnd);
+ /* Caution: we not only need l = h, but both inexact flags should
+ agree. Indeed, one of the inexact flags might be zero. In that
+ case if we assume lngamma(z0) cannot be exact, the other flag
+ should be correct. We are conservative here and request that both
+ inexact flags agree. */
+ ok = SAME_SIGN (inex1, inex2) && mpfr_cmp (l, h) == 0;
+ if (ok)
+ mpfr_set (y, h, rnd); /* exact */
+ mpfr_clear (l);
+ mpfr_clear (h);
+ mpfr_clear (g);
+ if (ok)
+ {
+ MPFR_ZIV_FREE (loop);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex1, rnd);
+ }
+ /* since we have log|gamma(x)| = - log|x| - gamma*x + O(x^2),
+ if x ~ 2^(-n), then we have a n-bit approximation, thus
+ we can try again with a working precision of n bits,
+ especially when n >> PREC(y).
+ Otherwise we would use the reflection formula evaluating x-1,
+ which would need precision n. */
+ MPFR_ZIV_NEXT (loop, prec);
+ }
+ while (prec <= -MPFR_EXP(z0));
+ MPFR_ZIV_FREE (loop);
+ }
+#endif
+
+ precy = MPFR_PREC(y);
+
+ mpfr_init2 (s, MPFR_PREC_MIN);
+ mpfr_init2 (t, MPFR_PREC_MIN);
+ mpfr_init2 (u, MPFR_PREC_MIN);
+ mpfr_init2 (v, MPFR_PREC_MIN);
+ mpfr_init2 (z, MPFR_PREC_MIN);
+
+ if (compared < 0)
+ {
+ mpfr_exp_t err_u;
+
+ /* use reflection formula:
+ gamma(x) = Pi*(x-1)/sin(Pi*(2-x))/gamma(2-x)
+ thus lngamma(x) = log(Pi*(x-1)/sin(Pi*(2-x))) - lngamma(2-x) */
+
+ w = precy + MPFR_INT_CEIL_LOG2 (precy);
+ w += MPFR_INT_CEIL_LOG2 (w) + 14;
+ MPFR_ZIV_INIT (loop, w);
+ while (1)
+ {
+ MPFR_ASSERTD(w >= 3);
+ mpfr_set_prec (s, w);
+ mpfr_set_prec (t, w);
+ mpfr_set_prec (u, w);
+ mpfr_set_prec (v, w);
+ /* In the following, we write r for a real of absolute value
+ at most 2^(-w). Different instances of r may represent different
+ values. */
+ mpfr_ui_sub (s, 2, z0, MPFR_RNDD); /* s = (2-z0) * (1+2r) >= 1 */
+ mpfr_const_pi (t, MPFR_RNDN); /* t = Pi * (1+r) */
+ mpfr_lngamma (u, s, MPFR_RNDN); /* lngamma(2-x) */
+ /* Let s = (2-z0) + h. By construction, -(2-z0)*2^(1-w) <= h <= 0.
+ We have lngamma(s) = lngamma(2-z0) + h*Psi(z), z in [2-z0+h,2-z0].
+ Since 2-z0+h = s >= 1 and |Psi(x)| <= max(1,log(x)) for x >= 1,
+ the error on u is bounded by
+ ulp(u)/2 + (2-z0)*max(1,log(2-z0))*2^(1-w)
+ = (1/2 + (2-z0)*max(1,log(2-z0))*2^(1-E(u))) ulp(u) */
+ d = (double) MPFR_GET_EXP(s) * 0.694; /* upper bound for log(2-z0) */
+ err_u = MPFR_GET_EXP(s) + __gmpfr_ceil_log2 (d) + 1 - MPFR_GET_EXP(u);
+ err_u = (err_u >= 0) ? err_u + 1 : 0;
+ /* now the error on u is bounded by 2^err_u ulps */
+
+ mpfr_mul (s, s, t, MPFR_RNDN); /* Pi*(2-x) * (1+r)^4 */
+ err_s = MPFR_GET_EXP(s); /* 2-x <= 2^err_s */
+ mpfr_sin (s, s, MPFR_RNDN); /* sin(Pi*(2-x)) */
+ /* the error on s is bounded by 1/2*ulp(s) + [(1+2^(-w))^4-1]*(2-x)
+ <= 1/2*ulp(s) + 5*2^(-w)*(2-x) for w >= 3
+ <= (1/2 + 5 * 2^(-E(s)) * (2-x)) ulp(s) */
+ err_s += 3 - MPFR_GET_EXP(s);
+ err_s = (err_s >= 0) ? err_s + 1 : 0;
+ /* the error on s is bounded by 2^err_s ulp(s), thus by
+ 2^(err_s+1)*2^(-w)*|s| since ulp(s) <= 2^(1-w)*|s|.
+ Now n*2^(-w) can always be written |(1+r)^n-1| for some
+ |r|<=2^(-w), thus taking n=2^(err_s+1) we see that
+ |S - s| <= |(1+r)^(2^(err_s+1))-1| * |s|, where S is the
+ true value.
+ In fact if ulp(s) <= ulp(S) the same inequality holds for
+ |S| instead of |s| in the right hand side, i.e., we can
+ write s = (1+r)^(2^(err_s+1)) * S.
+ But if ulp(S) < ulp(s), we need to add one ``bit'' to the error,
+ to get s = (1+r)^(2^(err_s+2)) * S. This is true since with
+ E = n*2^(-w) we have |s - S| <= E * |s|, thus
+ |s - S| <= E/(1-E) * |S|.
+ Now E/(1-E) is bounded by 2E as long as E<=1/2,
+ and 2E can be written (1+r)^(2n)-1 as above.
+ */
+ err_s += 2; /* exponent of relative error */
+
+ mpfr_sub_ui (v, z0, 1, MPFR_RNDN); /* v = (x-1) * (1+r) */
+ mpfr_mul (v, v, t, MPFR_RNDN); /* v = Pi*(x-1) * (1+r)^3 */
+ mpfr_div (v, v, s, MPFR_RNDN); /* Pi*(x-1)/sin(Pi*(2-x)) */
+ mpfr_abs (v, v, MPFR_RNDN);
+ /* (1+r)^(3+2^err_s+1) */
+ err_s = (err_s <= 1) ? 3 : err_s + 1;
+ /* now (1+r)^M with M <= 2^err_s */
+ mpfr_log (v, v, MPFR_RNDN);
+ /* log(v*(1+e)) = log(v)+log(1+e) where |e| <= 2^(err_s-w).
+ Since |log(1+e)| <= 2*e for |e| <= 1/4, the error on v is
+ bounded by ulp(v)/2 + 2^(err_s+1-w). */
+ if (err_s + 2 > w)
+ {
+ w += err_s + 2;
+ }
+ else
+ {
+ err_s += 1 - MPFR_GET_EXP(v);
+ err_s = (err_s >= 0) ? err_s + 1 : 0;
+ /* the error on v is bounded by 2^err_s ulps */
+ err_u += MPFR_GET_EXP(u); /* absolute error on u */
+ err_s += MPFR_GET_EXP(v); /* absolute error on v */
+ mpfr_sub (s, v, u, MPFR_RNDN);
+ /* the total error on s is bounded by ulp(s)/2 + 2^(err_u-w)
+ + 2^(err_s-w) <= ulp(s)/2 + 2^(max(err_u,err_s)+1-w) */
+ err_s = (err_s >= err_u) ? err_s : err_u;
+ err_s += 1 - MPFR_GET_EXP(s); /* error is 2^err_s ulp(s) */
+ err_s = (err_s >= 0) ? err_s + 1 : 0;
+ if (mpfr_can_round (s, w - err_s, MPFR_RNDN, MPFR_RNDZ, precy
+ + (rnd == MPFR_RNDN)))
+ goto end;
+ }
+ MPFR_ZIV_NEXT (loop, w);
+ }
+ MPFR_ZIV_FREE (loop);
+ }
+
+ /* now z0 > 1 */
+
+ MPFR_ASSERTD (compared > 0);
+
+ /* since k is O(w), the value of log(z0*...*(z0+k-1)) is about w*log(w),
+ so there is a cancellation of ~log(w) in the argument reconstruction */
+ w = precy + MPFR_INT_CEIL_LOG2 (precy);
+ w += MPFR_INT_CEIL_LOG2 (w) + 13;
+ MPFR_ZIV_INIT (loop, w);
+ while (1)
+ {
+ MPFR_ASSERTD (w >= 3);
+
+ /* argument reduction: we compute gamma(z0 + k), where the series
+ has error term B_{2n}/(z0+k)^(2n) ~ (n/(Pi*e*(z0+k)))^(2n)
+ and we need k steps of argument reconstruction. Assuming k is large
+ with respect to z0, and k = n, we get 1/(Pi*e)^(2n) ~ 2^(-w), i.e.,
+ k ~ w*log(2)/2/log(Pi*e) ~ 0.1616 * w.
+ However, since the series is more expensive to compute, the optimal
+ value seems to be k ~ 4.5 * w experimentally. */
+ mpfr_set_prec (s, 53);
+ mpfr_gamma_alpha (s, w);
+ mpfr_set_ui_2exp (s, 9, -1, MPFR_RNDU);
+ mpfr_mul_ui (s, s, w, MPFR_RNDU);
+ if (mpfr_cmp (z0, s) < 0)
+ {
+ mpfr_sub (s, s, z0, MPFR_RNDU);
+ k = mpfr_get_ui (s, MPFR_RNDU);
+ if (k < 3)
+ k = 3;
+ }
+ else
+ k = 3;
+
+ mpfr_set_prec (s, w);
+ mpfr_set_prec (t, w);
+ mpfr_set_prec (u, w);
+ mpfr_set_prec (v, w);
+ mpfr_set_prec (z, w);
+
+ mpfr_add_ui (z, z0, k, MPFR_RNDN);
+ /* z = (z0+k)*(1+t1) with |t1| <= 2^(-w) */
+
+ /* z >= 4 ensures the relative error on log(z) is small,
+ and also (z-1/2)*log(z)-z >= 0 */
+ MPFR_ASSERTD (mpfr_cmp_ui (z, 4) >= 0);
+
+ mpfr_log (s, z, MPFR_RNDN); /* log(z) */
+ /* we have s = log((z0+k)*(1+t1))*(1+t2) with |t1|, |t2| <= 2^(-w).
+ Since w >= 2 and z0+k >= 4, we can write log((z0+k)*(1+t1))
+ = log(z0+k) * (1+t3) with |t3| <= 2^(-w), thus we have
+ s = log(z0+k) * (1+t4)^2 with |t4| <= 2^(-w) */
+ mpfr_mul_2ui (t, z, 1, MPFR_RNDN); /* t = 2z * (1+t5) */
+ mpfr_sub_ui (t, t, 1, MPFR_RNDN); /* t = 2z-1 * (1+t6)^3 */
+ /* since we can write 2z*(1+t5) = (2z-1)*(1+t5') with
+ t5' = 2z/(2z-1) * t5, thus |t5'| <= 8/7 * t5 */
+ mpfr_mul (s, s, t, MPFR_RNDN); /* (2z-1)*log(z) * (1+t7)^6 */
+ mpfr_div_2ui (s, s, 1, MPFR_RNDN); /* (z-1/2)*log(z) * (1+t7)^6 */
+ mpfr_sub (s, s, z, MPFR_RNDN); /* (z-1/2)*log(z)-z */
+ /* s = [(z-1/2)*log(z)-z]*(1+u)^14, s >= 1/2 */
+
+ mpfr_ui_div (u, 1, z, MPFR_RNDN); /* 1/z * (1+u), u <= 1/4 since z >= 4 */
+
+ /* the first term is B[2]/2/z = 1/12/z: t=1/12/z, C[2]=1 */
+ mpfr_div_ui (t, u, 12, MPFR_RNDN); /* 1/(12z) * (1+u)^2, t <= 3/128 */
+ mpfr_set (v, t, MPFR_RNDN); /* (1+u)^2, v < 2^(-5) */
+ mpfr_add (s, s, v, MPFR_RNDN); /* (1+u)^15 */
+
+ mpfr_mul (u, u, u, MPFR_RNDN); /* 1/z^2 * (1+u)^3 */
+
+ if (Bm == 0)
+ {
+ B = mpfr_bernoulli_internal ((mpz_t *) 0, 0);
+ B = mpfr_bernoulli_internal (B, 1);
+ Bm = 2;
+ }
+
+ /* m <= maxm ensures that 2*m*(2*m+1) <= ULONG_MAX */
+ maxm = 1UL << (GMP_NUMB_BITS / 2 - 1);
+
+ /* s:(1+u)^15, t:(1+u)^2, t <= 3/128 */
+
+ for (m = 2; MPFR_GET_EXP(v) + (mpfr_exp_t) w >= MPFR_GET_EXP(s); m++)
+ {
+ mpfr_mul (t, t, u, MPFR_RNDN); /* (1+u)^(10m-14) */
+ if (m <= maxm)
+ {
+ mpfr_mul_ui (t, t, 2*(m-1)*(2*m-3), MPFR_RNDN);
+ mpfr_div_ui (t, t, 2*m*(2*m-1), MPFR_RNDN);
+ mpfr_div_ui (t, t, 2*m*(2*m+1), MPFR_RNDN);
+ }
+ else
+ {
+ mpfr_mul_ui (t, t, 2*(m-1), MPFR_RNDN);
+ mpfr_mul_ui (t, t, 2*m-3, MPFR_RNDN);
+ mpfr_div_ui (t, t, 2*m, MPFR_RNDN);
+ mpfr_div_ui (t, t, 2*m-1, MPFR_RNDN);
+ mpfr_div_ui (t, t, 2*m, MPFR_RNDN);
+ mpfr_div_ui (t, t, 2*m+1, MPFR_RNDN);
+ }
+ /* (1+u)^(10m-8) */
+ /* invariant: t=1/(2m)/(2m-1)/z^(2m-1)/(2m+1)! */
+ if (Bm <= m)
+ {
+ B = mpfr_bernoulli_internal (B, m); /* B[2m]*(2m+1)!, exact */
+ Bm ++;
+ }
+ mpfr_mul_z (v, t, B[m], MPFR_RNDN); /* (1+u)^(10m-7) */
+ MPFR_ASSERTD(MPFR_GET_EXP(v) <= - (2 * m + 3));
+ mpfr_add (s, s, v, MPFR_RNDN);
+ }
+ /* m <= 1/2*Pi*e*z ensures that |v[m]| < 1/2^(2m+3) */
+ MPFR_ASSERTD ((double) m <= 4.26 * mpfr_get_d (z, MPFR_RNDZ));
+
+ /* We have sum([(1+u)^(10m-7)-1]*1/2^(2m+3), m=2..infinity)
+ <= 1.46*u for u <= 2^(-3).
+ We have 0 < lngamma(z) - [(z - 1/2) ln(z) - z + 1/2 ln(2 Pi)] < 0.021
+ for z >= 4, thus since the initial s >= 0.85, the different values of
+ s differ by at most one binade, and the total rounding error on s
+ in the for-loop is bounded by 2*(m-1)*ulp(final_s).
+ The error coming from the v's is bounded by
+ 1.46*2^(-w) <= 2*ulp(final_s).
+ Thus the total error so far is bounded by [(1+u)^15-1]*s+2m*ulp(s)
+ <= (2m+47)*ulp(s).
+ Taking into account the truncation error (which is bounded by the last
+ term v[] according to 6.1.42 in A&S), the bound is (2m+48)*ulp(s).
+ */
+
+ /* add 1/2*log(2*Pi) and subtract log(z0*(z0+1)*...*(z0+k-1)) */
+ mpfr_const_pi (v, MPFR_RNDN); /* v = Pi*(1+u) */
+ mpfr_mul_2ui (v, v, 1, MPFR_RNDN); /* v = 2*Pi * (1+u) */
+ if (k)
+ {
+ unsigned long l;
+ mpfr_set (t, z0, MPFR_RNDN); /* t = z0*(1+u) */
+ for (l = 1; l < k; l++)
+ {
+ mpfr_add_ui (u, z0, l, MPFR_RNDN); /* u = (z0+l)*(1+u) */
+ mpfr_mul (t, t, u, MPFR_RNDN); /* (1+u)^(2l+1) */
+ }
+ /* now t: (1+u)^(2k-1) */
+ /* instead of computing log(sqrt(2*Pi)/t), we compute
+ 1/2*log(2*Pi/t^2), which trades a square root for a square */
+ mpfr_mul (t, t, t, MPFR_RNDN); /* (z0*...*(z0+k-1))^2, (1+u)^(4k-1) */
+ mpfr_div (v, v, t, MPFR_RNDN);
+ /* 2*Pi/(z0*...*(z0+k-1))^2 (1+u)^(4k+1) */
+ }
+#ifdef IS_GAMMA
+ err_s = MPFR_GET_EXP(s);
+ mpfr_exp (s, s, MPFR_RNDN);
+ /* If s is +Inf, we compute exp(lngamma(z0)). */
+ if (mpfr_inf_p (s))
+ {
+ inexact = mpfr_explgamma (y, z0, &expo, s, t, rnd);
+ if (inexact)
+ goto end0;
+ else
+ goto ziv_next;
+ }
+ /* before the exponential, we have s = s0 + h where
+ |h| <= (2m+48)*ulp(s), thus exp(s0) = exp(s) * exp(-h).
+ For |h| <= 1/4, we have |exp(h)-1| <= 1.2*|h| thus
+ |exp(s) - exp(s0)| <= 1.2 * exp(s) * (2m+48)* 2^(EXP(s)-w). */
+ d = 1.2 * (2.0 * (double) m + 48.0);
+ /* the error on s is bounded by d*2^err_s * 2^(-w) */
+ mpfr_sqrt (t, v, MPFR_RNDN);
+ /* let v0 be the exact value of v. We have v = v0*(1+u)^(4k+1),
+ thus t = sqrt(v0)*(1+u)^(2k+3/2). */
+ mpfr_mul (s, s, t, MPFR_RNDN);
+ /* the error on input s is bounded by (1+u)^(d*2^err_s),
+ and that on t is (1+u)^(2k+3/2), thus the
+ total error is (1+u)^(d*2^err_s+2k+5/2) */
+ err_s += __gmpfr_ceil_log2 (d);
+ err_t = __gmpfr_ceil_log2 (2.0 * (double) k + 2.5);
+ err_s = (err_s >= err_t) ? err_s + 1 : err_t + 1;
+#else
+ mpfr_log (t, v, MPFR_RNDN);
+ /* let v0 be the exact value of v. We have v = v0*(1+u)^(4k+1),
+ thus log(v) = log(v0) + (4k+1)*log(1+u). Since |log(1+u)/u| <= 1.07
+ for |u| <= 2^(-3), the absolute error on log(v) is bounded by
+ 1.07*(4k+1)*u, and the rounding error by ulp(t). */
+ mpfr_div_2ui (t, t, 1, MPFR_RNDN);
+ /* the error on t is now bounded by ulp(t) + 0.54*(4k+1)*2^(-w).
+ We have sqrt(2*Pi)/(z0*(z0+1)*...*(z0+k-1)) <= sqrt(2*Pi)/k! <= 0.5
+ since k>=3, thus t <= -0.5 and ulp(t) >= 2^(-w).
+ Thus the error on t is bounded by (2.16*k+1.54)*ulp(t). */
+ err_t = MPFR_GET_EXP(t) + (mpfr_exp_t)
+ __gmpfr_ceil_log2 (2.2 * (double) k + 1.6);
+ err_s = MPFR_GET_EXP(s) + (mpfr_exp_t)
+ __gmpfr_ceil_log2 (2.0 * (double) m + 48.0);
+ mpfr_add (s, s, t, MPFR_RNDN); /* this is a subtraction in fact */
+ /* the final error in ulp(s) is
+ <= 1 + 2^(err_t-EXP(s)) + 2^(err_s-EXP(s))
+ <= 2^(1+max(err_t,err_s)-EXP(s)) if err_t <> err_s
+ <= 2^(2+max(err_t,err_s)-EXP(s)) if err_t = err_s */
+ err_s = (err_t == err_s) ? 1 + err_s : ((err_t > err_s) ? err_t : err_s);
+ err_s += 1 - MPFR_GET_EXP(s);
+#endif
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, w - err_s, precy, rnd)))
+ break;
+#ifdef IS_GAMMA
+ ziv_next:
+#endif
+ MPFR_ZIV_NEXT (loop, w);
+ }
+
+#ifdef IS_GAMMA
+ end0:
+#endif
+ oldBm = Bm;
+ while (Bm--)
+ mpz_clear (B[Bm]);
+ (*__gmp_free_func) (B, oldBm * sizeof (mpz_t));
+
+ end:
+ if (inexact == 0)
+ inexact = mpfr_set (y, s, rnd);
+ MPFR_ZIV_FREE (loop);
+
+ mpfr_clear (s);
+ mpfr_clear (t);
+ mpfr_clear (u);
+ mpfr_clear (v);
+ mpfr_clear (z);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd);
+}
+
+#ifndef IS_GAMMA
+
+int
+mpfr_lngamma (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ int inex;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inex));
+
+ /* special cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x) || MPFR_IS_NEG (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else /* lngamma(+Inf) = lngamma(+0) = +Inf */
+ {
+ if (MPFR_IS_ZERO (x))
+ mpfr_set_divby0 ();
+ MPFR_SET_INF (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0); /* exact */
+ }
+ }
+
+ /* if x < 0 and -2k-1 <= x <= -2k, then lngamma(x) = NaN */
+ if (MPFR_IS_NEG (x) && (unit_bit (x) == 0 || mpfr_integer_p (x)))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+
+ inex = mpfr_lngamma_aux (y, x, rnd);
+ return inex;
+}
+
+int
+mpfr_lgamma (mpfr_ptr y, int *signp, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ int inex;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
+ ("y[%Pu]=%.*Rg signp=%d inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, *signp, inex));
+
+ *signp = 1; /* most common case */
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ if (MPFR_IS_ZERO (x))
+ mpfr_set_divby0 ();
+ *signp = MPFR_INT_SIGN (x);
+ MPFR_SET_INF (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0);
+ }
+ }
+
+ if (MPFR_IS_NEG (x))
+ {
+ if (mpfr_integer_p (x))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_POS (y);
+ mpfr_set_divby0 ();
+ MPFR_RET (0);
+ }
+
+ if (unit_bit (x) == 0)
+ *signp = -1;
+
+ /* For tiny negative x, we have gamma(x) = 1/x - euler + O(x),
+ thus |gamma(x)| = -1/x + euler + O(x), and
+ log |gamma(x)| = -log(-x) - euler*x + O(x^2).
+ More precisely we have for -0.4 <= x < 0:
+ -log(-x) <= log |gamma(x)| <= -log(-x) - x.
+ Since log(x) is not representable, we may have an instance of the
+ Table Maker Dilemma. The only way to ensure correct rounding is to
+ compute an interval [l,h] such that l <= -log(-x) and
+ -log(-x) - x <= h, and check whether l and h round to the same number
+ for the target precision and rounding modes. */
+ if (MPFR_EXP(x) + 1 <= - (mpfr_exp_t) MPFR_PREC(y))
+ /* since PREC(y) >= 1, this ensures EXP(x) <= -2,
+ thus |x| <= 0.25 < 0.4 */
+ {
+ mpfr_t l, h;
+ int ok, inex2;
+ mpfr_prec_t w = MPFR_PREC (y) + 14;
+ mpfr_exp_t expl;
+
+ while (1)
+ {
+ mpfr_init2 (l, w);
+ mpfr_init2 (h, w);
+ /* we want a lower bound on -log(-x), thus an upper bound
+ on log(-x), thus an upper bound on -x. */
+ mpfr_neg (l, x, MPFR_RNDU); /* upper bound on -x */
+ mpfr_log (l, l, MPFR_RNDU); /* upper bound for log(-x) */
+ mpfr_neg (l, l, MPFR_RNDD); /* lower bound for -log(-x) */
+ mpfr_neg (h, x, MPFR_RNDD); /* lower bound on -x */
+ mpfr_log (h, h, MPFR_RNDD); /* lower bound on log(-x) */
+ mpfr_neg (h, h, MPFR_RNDU); /* upper bound for -log(-x) */
+ mpfr_sub (h, h, x, MPFR_RNDU); /* upper bound for -log(-x) - x */
+ inex = mpfr_prec_round (l, MPFR_PREC (y), rnd);
+ inex2 = mpfr_prec_round (h, MPFR_PREC (y), rnd);
+ /* Caution: we not only need l = h, but both inexact flags
+ should agree. Indeed, one of the inexact flags might be
+ zero. In that case if we assume ln|gamma(x)| cannot be
+ exact, the other flag should be correct. We are conservative
+ here and request that both inexact flags agree. */
+ ok = SAME_SIGN (inex, inex2) && mpfr_equal_p (l, h);
+ if (ok)
+ mpfr_set (y, h, rnd); /* exact */
+ else
+ expl = MPFR_EXP (l);
+ mpfr_clear (l);
+ mpfr_clear (h);
+ if (ok)
+ return inex;
+ /* if ulp(log(-x)) <= |x| there is no reason to loop,
+ since the width of [l, h] will be at least |x| */
+ if (expl < MPFR_EXP(x) + (mpfr_exp_t) w)
+ break;
+ w += MPFR_INT_CEIL_LOG2(w) + 3;
+ }
+ }
+ }
+
+ inex = mpfr_lngamma_aux (y, x, rnd);
+ return inex;
+}
+
+#endif
diff --git a/mpfr/src/log.c b/mpfr/src/log.c
new file mode 100644
index 0000000000..0244ab569f
--- /dev/null
+++ b/mpfr/src/log.c
@@ -0,0 +1,171 @@
+/* mpfr_log -- natural logarithm of a floating-point number
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* The computation of log(x) is done using the formula :
+ if we want p bits of the result,
+
+ pi
+ log(x) ~ ------------ - m log 2
+ 2 AG(1,4/s)
+
+ where s = x 2^m > 2^(p/2)
+
+ More precisely, if F(x) = int(1/sqrt(1-(1-x^2)*sin(t)^2), t=0..PI/2),
+ then for s>=1.26 we have log(s) < F(4/s) < log(s)*(1+4/s^2)
+ from which we deduce pi/2/AG(1,4/s)*(1-4/s^2) < log(s) < pi/2/AG(1,4/s)
+ so the relative error 4/s^2 is < 4/2^p i.e. 4 ulps.
+*/
+
+int
+mpfr_log (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_prec_t p, q;
+ mpfr_t tmp1, tmp2;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+ MPFR_GROUP_DECL(group);
+
+ MPFR_LOG_FUNC
+ (("a[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (a), mpfr_log_prec, a, rnd_mode),
+ ("r[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (r), mpfr_log_prec, r,
+ inexact));
+
+ /* Special cases */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)))
+ {
+ /* If a is NaN, the result is NaN */
+ if (MPFR_IS_NAN (a))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ /* check for infinity before zero */
+ else if (MPFR_IS_INF (a))
+ {
+ if (MPFR_IS_NEG (a))
+ /* log(-Inf) = NaN */
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ else /* log(+Inf) = +Inf */
+ {
+ MPFR_SET_INF (r);
+ MPFR_SET_POS (r);
+ MPFR_RET (0);
+ }
+ }
+ else /* a is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (a));
+ MPFR_SET_INF (r);
+ MPFR_SET_NEG (r);
+ mpfr_set_divby0 ();
+ MPFR_RET (0); /* log(0) is an exact -infinity */
+ }
+ }
+ /* If a is negative, the result is NaN */
+ else if (MPFR_UNLIKELY (MPFR_IS_NEG (a)))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ /* If a is 1, the result is 0 */
+ else if (MPFR_UNLIKELY (MPFR_GET_EXP (a) == 1 && mpfr_cmp_ui (a, 1) == 0))
+ {
+ MPFR_SET_ZERO (r);
+ MPFR_SET_POS (r);
+ MPFR_RET (0); /* only "normal" case where the result is exact */
+ }
+
+ q = MPFR_PREC (r);
+
+ /* use initial precision about q+lg(q)+5 */
+ p = q + 5 + 2 * MPFR_INT_CEIL_LOG2 (q);
+ /* % ~(mpfr_prec_t)GMP_NUMB_BITS ;
+ m=q; while (m) { p++; m >>= 1; } */
+ /* if (MPFR_LIKELY(p % GMP_NUMB_BITS != 0))
+ p += GMP_NUMB_BITS - (p%GMP_NUMB_BITS); */
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_GROUP_INIT_2 (group, p, tmp1, tmp2);
+
+ MPFR_ZIV_INIT (loop, p);
+ for (;;)
+ {
+ long m;
+ mpfr_exp_t cancel;
+
+ /* Calculus of m (depends on p) */
+ m = (p + 1) / 2 - MPFR_GET_EXP (a) + 1;
+
+ mpfr_mul_2si (tmp2, a, m, MPFR_RNDN); /* s=a*2^m, err<=1 ulp */
+ mpfr_div (tmp1, __gmpfr_four, tmp2, MPFR_RNDN);/* 4/s, err<=2 ulps */
+ mpfr_agm (tmp2, __gmpfr_one, tmp1, MPFR_RNDN); /* AG(1,4/s),err<=3 ulps */
+ mpfr_mul_2ui (tmp2, tmp2, 1, MPFR_RNDN); /* 2*AG(1,4/s), err<=3 ulps */
+ mpfr_const_pi (tmp1, MPFR_RNDN); /* compute pi, err<=1ulp */
+ mpfr_div (tmp2, tmp1, tmp2, MPFR_RNDN); /* pi/2*AG(1,4/s), err<=5ulps */
+ mpfr_const_log2 (tmp1, MPFR_RNDN); /* compute log(2), err<=1ulp */
+ mpfr_mul_si (tmp1, tmp1, m, MPFR_RNDN); /* compute m*log(2),err<=2ulps */
+ mpfr_sub (tmp1, tmp2, tmp1, MPFR_RNDN); /* log(a), err<=7ulps+cancel */
+
+ if (MPFR_LIKELY (MPFR_IS_PURE_FP (tmp1) && MPFR_IS_PURE_FP (tmp2)))
+ {
+ cancel = MPFR_GET_EXP (tmp2) - MPFR_GET_EXP (tmp1);
+ MPFR_LOG_MSG (("canceled bits=%ld\n", (long) cancel));
+ MPFR_LOG_VAR (tmp1);
+ if (MPFR_UNLIKELY (cancel < 0))
+ cancel = 0;
+
+ /* we have 7 ulps of error from the above roundings,
+ 4 ulps from the 4/s^2 second order term,
+ plus the canceled bits */
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (tmp1, p-cancel-4, q, rnd_mode)))
+ break;
+
+ /* VL: I think it is better to have an increment that it isn't
+ too low; in particular, the increment must be positive even
+ if cancel = 0 (can this occur?). */
+ p += cancel >= 8 ? cancel : 8;
+ }
+ else
+ {
+ /* TODO: find why this case can occur and what is best to do
+ with it. */
+ p += 32;
+ }
+
+ MPFR_ZIV_NEXT (loop, p);
+ MPFR_GROUP_REPREC_2 (group, p, tmp1, tmp2);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (r, tmp1, rnd_mode);
+ /* We clean */
+ MPFR_GROUP_CLEAR (group);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inexact, rnd_mode);
+}
diff --git a/mpfr/src/log10.c b/mpfr/src/log10.c
new file mode 100644
index 0000000000..31b6ce9f6e
--- /dev/null
+++ b/mpfr/src/log10.c
@@ -0,0 +1,150 @@
+/* mpfr_log10 -- logarithm in base 10.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+ /* The computation of r=log10(a)
+
+ r=log10(a)=log(a)/log(10)
+ */
+
+int
+mpfr_log10 (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("a[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (a), mpfr_log_prec, a, rnd_mode),
+ ("r[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (r), mpfr_log_prec, r, inexact));
+
+ /* If a is NaN, the result is NaN */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)))
+ {
+ if (MPFR_IS_NAN (a))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ /* check for infinity before zero */
+ else if (MPFR_IS_INF (a))
+ {
+ if (MPFR_IS_NEG (a))
+ /* log10(-Inf) = NaN */
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ else /* log10(+Inf) = +Inf */
+ {
+ MPFR_SET_INF (r);
+ MPFR_SET_POS (r);
+ MPFR_RET (0); /* exact */
+ }
+ }
+ else /* a = 0 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (a));
+ MPFR_SET_INF (r);
+ MPFR_SET_NEG (r);
+ mpfr_set_divby0 ();
+ MPFR_RET (0); /* log10(0) is an exact -infinity */
+ }
+ }
+
+ /* If a is negative, the result is NaN */
+ if (MPFR_UNLIKELY (MPFR_IS_NEG (a)))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+
+ /* If a is 1, the result is 0 */
+ if (mpfr_cmp_ui (a, 1) == 0)
+ {
+ MPFR_SET_ZERO (r);
+ MPFR_SET_POS (r);
+ MPFR_RET (0); /* result is exact */
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* General case */
+ {
+ /* Declaration of the intermediary variable */
+ mpfr_t t, tt;
+ MPFR_ZIV_DECL (loop);
+ /* Declaration of the size variable */
+ mpfr_prec_t Ny = MPFR_PREC(r); /* Precision of output variable */
+ mpfr_prec_t Nt; /* Precision of the intermediary variable */
+ mpfr_exp_t err; /* Precision of error */
+
+ /* compute the precision of intermediary variable */
+ /* the optimal number of bits : see algorithms.tex */
+ Nt = Ny + 4 + MPFR_INT_CEIL_LOG2 (Ny);
+
+ /* initialise of intermediary variables */
+ mpfr_init2 (t, Nt);
+ mpfr_init2 (tt, Nt);
+
+ /* First computation of log10 */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ /* compute log10 */
+ mpfr_set_ui (t, 10, MPFR_RNDN); /* 10 */
+ mpfr_log (t, t, MPFR_RNDD); /* log(10) */
+ mpfr_log (tt, a, MPFR_RNDN); /* log(a) */
+ mpfr_div (t, tt, t, MPFR_RNDN); /* log(a)/log(10) */
+
+ /* estimation of the error */
+ err = Nt - 4;
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ break;
+
+ /* log10(10^n) is exact:
+ FIXME: Can we have 10^n exactly representable as a mpfr_t
+ but n can't fit an unsigned long? */
+ if (MPFR_IS_POS (t)
+ && mpfr_integer_p (t) && mpfr_fits_ulong_p (t, MPFR_RNDN)
+ && !mpfr_ui_pow_ui (tt, 10, mpfr_get_ui (t, MPFR_RNDN), MPFR_RNDN)
+ && mpfr_cmp (a, tt) == 0)
+ break;
+
+ /* actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (tt, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (r, t, rnd_mode);
+
+ mpfr_clear (t);
+ mpfr_clear (tt);
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inexact, rnd_mode);
+}
diff --git a/mpfr/src/log1p.c b/mpfr/src/log1p.c
new file mode 100644
index 0000000000..a4c9b2593f
--- /dev/null
+++ b/mpfr/src/log1p.c
@@ -0,0 +1,158 @@
+/* mpfr_log1p -- Compute log(1+x)
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+ /* The computation of log1p is done by
+ log1p(x)=log(1+x) */
+
+int
+mpfr_log1p (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int comp, inexact;
+ mpfr_exp_t ex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y,
+ inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ /* check for inf or -inf (result is not defined) */
+ else if (MPFR_IS_INF (x))
+ {
+ if (MPFR_IS_POS (x))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_POS (y);
+ MPFR_RET (0);
+ }
+ else
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ }
+ else /* x is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (y); /* log1p(+/- 0) = +/- 0 */
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ }
+
+ ex = MPFR_GET_EXP (x);
+ if (ex < 0) /* -0.5 < x < 0.5 */
+ {
+ /* For x > 0, abs(log(1+x)-x) < x^2/2.
+ For x > -0.5, abs(log(1+x)-x) < x^2. */
+ if (MPFR_IS_POS (x))
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, - ex - 1, 0, 0, rnd_mode, {});
+ else
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, - ex, 0, 1, rnd_mode, {});
+ }
+
+ comp = mpfr_cmp_si (x, -1);
+ /* log1p(x) is undefined for x < -1 */
+ if (MPFR_UNLIKELY(comp <= 0))
+ {
+ if (comp == 0)
+ /* x=0: log1p(-1)=-inf (divide-by-zero exception) */
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_NEG (y);
+ mpfr_set_divby0 ();
+ MPFR_RET (0);
+ }
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* General case */
+ {
+ /* Declaration of the intermediary variable */
+ mpfr_t t;
+ /* Declaration of the size variable */
+ mpfr_prec_t Ny = MPFR_PREC(y); /* target precision */
+ mpfr_prec_t Nt; /* working precision */
+ mpfr_exp_t err; /* error */
+ MPFR_ZIV_DECL (loop);
+
+ /* compute the precision of intermediary variable */
+ /* the optimal number of bits : see algorithms.tex */
+ Nt = Ny + MPFR_INT_CEIL_LOG2 (Ny) + 6;
+
+ /* if |x| is smaller than 2^(-e), we will loose about e bits
+ in log(1+x) */
+ if (MPFR_EXP(x) < 0)
+ Nt += -MPFR_EXP(x);
+
+ /* initialise of intermediary variable */
+ mpfr_init2 (t, Nt);
+
+ /* First computation of log1p */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ /* compute log1p */
+ inexact = mpfr_add_ui (t, x, 1, MPFR_RNDN); /* 1+x */
+ /* if inexact = 0, then t = x+1, and the result is simply log(t) */
+ if (inexact == 0)
+ {
+ inexact = mpfr_log (y, t, rnd_mode);
+ goto end;
+ }
+ mpfr_log (t, t, MPFR_RNDN); /* log(1+x) */
+
+ /* the error is bounded by (1/2+2^(1-EXP(t))*ulp(t) (cf algorithms.tex)
+ if EXP(t)>=2, then error <= ulp(t)
+ if EXP(t)<=1, then error <= 2^(2-EXP(t))*ulp(t) */
+ err = Nt - MAX (0, 2 - MPFR_GET_EXP (t));
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ break;
+
+ /* increase the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ }
+ inexact = mpfr_set (y, t, rnd_mode);
+
+ end:
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (t);
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/log2.c b/mpfr/src/log2.c
new file mode 100644
index 0000000000..d95497bfea
--- /dev/null
+++ b/mpfr/src/log2.c
@@ -0,0 +1,142 @@
+/* mpfr_log2 -- log base 2
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+ /* The computation of r=log2(a)
+ r=log2(a)=log(a)/log(2) */
+
+int
+mpfr_log2 (mpfr_ptr r, mpfr_srcptr a, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("a[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (a), mpfr_log_prec, a, rnd_mode),
+ ("r[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (r), mpfr_log_prec, r,
+ inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)))
+ {
+ /* If a is NaN, the result is NaN */
+ if (MPFR_IS_NAN (a))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ /* check for infinity before zero */
+ else if (MPFR_IS_INF (a))
+ {
+ if (MPFR_IS_NEG (a))
+ /* log(-Inf) = NaN */
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ else /* log(+Inf) = +Inf */
+ {
+ MPFR_SET_INF (r);
+ MPFR_SET_POS (r);
+ MPFR_RET (0);
+ }
+ }
+ else /* a is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (a));
+ MPFR_SET_INF (r);
+ MPFR_SET_NEG (r);
+ mpfr_set_divby0 ();
+ MPFR_RET (0); /* log2(0) is an exact -infinity */
+ }
+ }
+
+ /* If a is negative, the result is NaN */
+ if (MPFR_UNLIKELY (MPFR_IS_NEG (a)))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+
+ /* If a is 1, the result is 0 */
+ if (MPFR_UNLIKELY (mpfr_cmp_ui (a, 1) == 0))
+ {
+ MPFR_SET_ZERO (r);
+ MPFR_SET_POS (r);
+ MPFR_RET (0); /* only "normal" case where the result is exact */
+ }
+
+ /* If a is 2^N, log2(a) is exact*/
+ if (MPFR_UNLIKELY (mpfr_cmp_ui_2exp (a, 1, MPFR_GET_EXP (a) - 1) == 0))
+ return mpfr_set_si(r, MPFR_GET_EXP (a) - 1, rnd_mode);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* General case */
+ {
+ /* Declaration of the intermediary variable */
+ mpfr_t t, tt;
+ /* Declaration of the size variable */
+ mpfr_prec_t Ny = MPFR_PREC(r); /* target precision */
+ mpfr_prec_t Nt; /* working precision */
+ mpfr_exp_t err; /* error */
+ MPFR_ZIV_DECL (loop);
+
+ /* compute the precision of intermediary variable */
+ /* the optimal number of bits : see algorithms.tex */
+ Nt = Ny + 3 + MPFR_INT_CEIL_LOG2 (Ny);
+
+ /* initialise of intermediary variable */
+ mpfr_init2 (t, Nt);
+ mpfr_init2 (tt, Nt);
+
+ /* First computation of log2 */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ /* compute log2 */
+ mpfr_const_log2(t,MPFR_RNDD); /* log(2) */
+ mpfr_log(tt,a,MPFR_RNDN); /* log(a) */
+ mpfr_div(t,tt,t,MPFR_RNDN); /* log(a)/log(2) */
+
+ /* estimation of the error */
+ err = Nt-3;
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ break;
+
+ /* actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ mpfr_set_prec (tt, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (r, t, rnd_mode);
+
+ mpfr_clear (t);
+ mpfr_clear (tt);
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inexact, rnd_mode);
+}
diff --git a/mpfr/src/logging.c b/mpfr/src/logging.c
new file mode 100644
index 0000000000..7b3f8c5d73
--- /dev/null
+++ b/mpfr/src/logging.c
@@ -0,0 +1,124 @@
+/* MPFR Logging functions.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Logging MPFR needs GCC >= 3.0 and GLIBC >= 2.0. */
+
+#ifdef MPFR_USE_LOGGING
+
+/* Can't include them before (in particular, printf.h) */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <time.h>
+
+/* Define LOGGING variables */
+
+FILE *mpfr_log_file;
+int mpfr_log_type;
+int mpfr_log_level;
+int mpfr_log_current;
+int mpfr_log_worstcase_limit;
+mpfr_prec_t mpfr_log_prec;
+
+static void mpfr_log_begin (void) __attribute__((constructor));
+
+/* We let the system close the LOG itself
+ (Otherwise functions called by destructor can't use LOG File */
+static void
+mpfr_log_begin (void)
+{
+ const char *var;
+ time_t tt;
+
+ /* Grab some information */
+ var = getenv ("MPFR_LOG_LEVEL");
+ mpfr_log_level = var == NULL || *var == 0 ? 7 : atoi (var);
+ mpfr_log_current = 0;
+
+ var = getenv ("MPFR_LOG_PREC");
+ mpfr_log_prec = var == NULL ? 6 : atol (var);
+
+ /* Get what we need to log */
+ mpfr_log_type = 0;
+ if (getenv ("MPFR_LOG_INPUT") != NULL)
+ mpfr_log_type |= MPFR_LOG_INPUT_F;
+ if (getenv ("MPFR_LOG_OUTPUT") != NULL)
+ mpfr_log_type |= MPFR_LOG_OUTPUT_F;
+ if (getenv ("MPFR_LOG_TIME") != NULL)
+ mpfr_log_type |= MPFR_LOG_TIME_F;
+ if (getenv ("MPFR_LOG_INTERNAL") != NULL)
+ mpfr_log_type |= MPFR_LOG_INTERNAL_F;
+ if (getenv ("MPFR_LOG_MSG") != NULL)
+ mpfr_log_type |= MPFR_LOG_MSG_F;
+ if (getenv ("MPFR_LOG_ZIV") != NULL)
+ mpfr_log_type |= MPFR_LOG_BADCASE_F;
+ if (getenv ("MPFR_LOG_STAT") != NULL)
+ mpfr_log_type |= MPFR_LOG_STAT_F;
+ if (getenv ("MPFR_LOG_ALL") != NULL)
+ mpfr_log_type = MPFR_LOG_INPUT_F|MPFR_LOG_OUTPUT_F|MPFR_LOG_TIME_F
+ |MPFR_LOG_INTERNAL_F|MPFR_LOG_MSG_F|MPFR_LOG_BADCASE_F|MPFR_LOG_STAT_F;
+
+ /* Open filename if needed */
+ var = getenv ("MPFR_LOG_FILE");
+ if (var == NULL || *var == 0)
+ var = "mpfr.log";
+ if (mpfr_log_type != 0)
+ {
+ mpfr_log_file = fopen (var, "w");
+ if (mpfr_log_file == NULL)
+ {
+ fprintf (stderr, "MPFR LOG: Can't open '%s' with w.\n", var);
+ abort ();
+ }
+ time (&tt);
+ fprintf (mpfr_log_file, "MPFR LOG FILE %s\n", ctime (&tt));
+ }
+}
+
+/* Return user CPU time measured in milliseconds. Thanks to Torbjorn. */
+
+#if defined (ANSIONLY) || defined (USG) || defined (__SVR4) \
+ || defined (_UNICOS) || defined(__hpux)
+
+int
+mpfr_get_cputime (void)
+{
+ return (int) ((unsigned long long) clock () * 1000 / CLOCKS_PER_SEC);
+}
+
+#else /* Use getrusage for cputime */
+
+#include <sys/types.h>
+#include <sys/resource.h>
+
+int
+mpfr_get_cputime (void)
+{
+ struct rusage rus;
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+
+#endif /* cputime */
+
+#endif /* MPFR_USE_LOGGING */
diff --git a/mpfr/src/min_prec.c b/mpfr/src/min_prec.c
new file mode 100644
index 0000000000..7df9e77521
--- /dev/null
+++ b/mpfr/src/min_prec.c
@@ -0,0 +1,33 @@
+/* mpfr_min_prec -- minimal size in bits to hold the mantissa
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+mpfr_prec_t
+mpfr_min_prec (mpfr_srcptr x)
+{
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return 0;
+
+ /* from a suggestion by Andreas Enge (2010-11-18) */
+ return MPFR_LIMB_SIZE (x) * GMP_NUMB_BITS - mpn_scan1 (MPFR_MANT (x), 0);
+}
diff --git a/mpfr/src/minmax.c b/mpfr/src/minmax.c
new file mode 100644
index 0000000000..288027b73b
--- /dev/null
+++ b/mpfr/src/minmax.c
@@ -0,0 +1,92 @@
+/* mpfr_min -- min and max of x, y
+
+Copyright 2001, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#include "mpfr-impl.h"
+
+ /* The computation of z=min(x,y)
+
+ z=x if x <= y
+ z=y if x > y
+ */
+
+int
+mpfr_min (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_ARE_SINGULAR(x,y))
+ {
+ if (MPFR_IS_NAN(x) && MPFR_IS_NAN(y) )
+ {
+ MPFR_SET_NAN(z);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_NAN(x))
+ return mpfr_set(z, y, rnd_mode);
+ else if (MPFR_IS_NAN(y))
+ return mpfr_set(z, x, rnd_mode);
+ else if (MPFR_IS_ZERO(x) && MPFR_IS_ZERO(y))
+ {
+ if (MPFR_IS_NEG(x))
+ return mpfr_set(z, x, rnd_mode);
+ else
+ return mpfr_set(z, y, rnd_mode);
+ }
+ }
+ if (mpfr_cmp(x,y) <= 0)
+ return mpfr_set(z, x, rnd_mode);
+ else
+ return mpfr_set(z, y, rnd_mode);
+}
+
+ /* The computation of z=max(x,y)
+
+ z=x if x >= y
+ z=y if x < y
+ */
+
+int
+mpfr_max (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_ARE_SINGULAR(x,y))
+ {
+ if (MPFR_IS_NAN(x) && MPFR_IS_NAN(y) )
+ {
+ MPFR_SET_NAN(z);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_NAN(x))
+ return mpfr_set(z, y, rnd_mode);
+ else if (MPFR_IS_NAN(y))
+ return mpfr_set(z, x, rnd_mode);
+ else if (MPFR_IS_ZERO(x) && MPFR_IS_ZERO(y))
+ {
+ if (MPFR_IS_NEG(x))
+ return mpfr_set(z, y, rnd_mode);
+ else
+ return mpfr_set(z, x, rnd_mode);
+ }
+ }
+ if (mpfr_cmp(x,y) <= 0)
+ return mpfr_set(z, y, rnd_mode);
+ else
+ return mpfr_set(z, x, rnd_mode);
+}
diff --git a/mpfr/src/modf.c b/mpfr/src/modf.c
new file mode 100644
index 0000000000..a16020b153
--- /dev/null
+++ b/mpfr/src/modf.c
@@ -0,0 +1,102 @@
+/* mpfr_modf -- Integral and fractional part.
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#define INEXPOS(y) ((y) == 0 ? 0 : (((y) > 0) ? 1 : 2))
+#define INEX(y,z) (INEXPOS(y) | (INEXPOS(z) << 2))
+
+/* Set iop to the integral part of op and fop to its fractional part */
+int
+mpfr_modf (mpfr_ptr iop, mpfr_ptr fop, mpfr_srcptr op, mpfr_rnd_t rnd_mode)
+{
+ mpfr_exp_t ope;
+ mpfr_prec_t opq;
+ int inexi, inexf;
+
+ MPFR_LOG_FUNC
+ (("op[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (op), mpfr_log_prec, op, rnd_mode),
+ ("iop[%Pu]=%.*Rg fop[%Pu]=%.*Rg",
+ mpfr_get_prec (iop), mpfr_log_prec, iop,
+ mpfr_get_prec (fop), mpfr_log_prec, fop));
+
+ MPFR_ASSERTN (iop != fop);
+
+ if ( MPFR_UNLIKELY (MPFR_IS_SINGULAR (op)) )
+ {
+ if (MPFR_IS_NAN (op))
+ {
+ MPFR_SET_NAN (iop);
+ MPFR_SET_NAN (fop);
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_SAME_SIGN (iop, op);
+ MPFR_SET_SAME_SIGN (fop, op);
+ if (MPFR_IS_INF (op))
+ {
+ MPFR_SET_INF (iop);
+ MPFR_SET_ZERO (fop);
+ MPFR_RET (0);
+ }
+ else /* op is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (op));
+ MPFR_SET_ZERO (iop);
+ MPFR_SET_ZERO (fop);
+ MPFR_RET (0);
+ }
+ }
+
+ ope = MPFR_GET_EXP (op);
+ opq = MPFR_PREC (op);
+
+ if (ope <= 0) /* 0 < |op| < 1 */
+ {
+ inexf = (fop != op) ? mpfr_set (fop, op, rnd_mode) : 0;
+ MPFR_SET_SAME_SIGN (iop, op);
+ MPFR_SET_ZERO (iop);
+ MPFR_RET (INEX(0, inexf));
+ }
+ else if (ope >= opq) /* op has no fractional part */
+ {
+ inexi = (iop != op) ? mpfr_set (iop, op, rnd_mode) : 0;
+ MPFR_SET_SAME_SIGN (fop, op);
+ MPFR_SET_ZERO (fop);
+ MPFR_RET (INEX(inexi, 0));
+ }
+ else /* op has both integral and fractional parts */
+ {
+ if (iop != op)
+ {
+ inexi = mpfr_rint_trunc (iop, op, rnd_mode);
+ inexf = mpfr_frac (fop, op, rnd_mode);
+ }
+ else
+ {
+ MPFR_ASSERTN (fop != op);
+ inexf = mpfr_frac (fop, op, rnd_mode);
+ inexi = mpfr_rint_trunc (iop, op, rnd_mode);
+ }
+ MPFR_RET (INEX(inexi, inexf));
+ }
+}
diff --git a/mpfr/src/mp_clz_tab.c b/mpfr/src/mp_clz_tab.c
new file mode 100644
index 0000000000..3f455e4761
--- /dev/null
+++ b/mpfr/src/mp_clz_tab.c
@@ -0,0 +1,38 @@
+/* __clz_tab -- support for longlong.h
+
+ THE CONTENTS OF THIS FILE ARE FOR INTERNAL USE AND MAY CHANGE
+ INCOMPATIBLY OR DISAPPEAR IN A FUTURE GNU MPFR RELEASE.
+
+Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+It has been copied and adapted from the GNU MP Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#if defined(COUNT_LEADING_ZEROS_NEED_CLZ_TAB) && defined(__GMPFR_GMP_H__)
+const
+unsigned char __clz_tab[128] =
+{
+ 1,2,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+};
+#endif
diff --git a/mpfr/src/mparam_h.in b/mpfr/src/mparam_h.in
new file mode 100644
index 0000000000..732f0734b4
--- /dev/null
+++ b/mpfr/src/mparam_h.in
@@ -0,0 +1,92 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __MPFR_IMPL_H__
+# error "MPFR Internal not included"
+#endif
+
+/* Note: the different macros used here are those defined by gcc,
+ for example with gcc -dM -E -xc /dev/null
+ As of gcc 4.2, you can also use: -march=native or -mtune=native */
+
+#if defined (__tune_pentium4__) /* Threshold for Pentium 4 */
+#define MPFR_TUNE_CASE "src/x86_64/pentium4/mparam.h"
+#include "x86_64/pentium4/mparam.h"
+
+#elif (defined (__tune_core2__) || defined (__tune_nocona__)) && defined (__x86_64) /* 64-bit Core 2 or Xeon */
+#define MPFR_TUNE_CASE "src/x86_64/core2/mparam.h"
+#include "x86_64/core2/mparam.h"
+
+#elif defined (__tune_core2__) && defined (__i386) /* 32-bit Core 2,
+ for example a 64-bit machine with gmp/mpfr compiled with ABI=32 */
+#define MPFR_TUNE_CASE "src/x86/core2/mparam.h"
+#include "x86/core2/mparam.h"
+
+#elif defined (__tune_k8__) /* Threshold for AMD 64 */
+#define MPFR_TUNE_CASE "src/amd/k8/mparam.h"
+#include "amd/k8/mparam.h"
+
+#elif defined (__tune_athlon__) /* Threshold for Athlon */
+#define MPFR_TUNE_CASE "src/amd/athlon/mparam.h"
+#include "amd/athlon/mparam.h"
+
+#elif defined (__tune_pentiumpro__) || defined (__tune_i686__) || defined (__i386) /* we consider all other 386's here */
+#define MPFR_TUNE_CASE "src/x86/mparam.h"
+#include "x86/mparam.h"
+
+#elif defined (__ia64) || defined (__itanium__) || defined (__tune_ia64__)
+/* Threshold for IA64 */
+#define MPFR_TUNE_CASE "src/ia64/mparam.h"
+#include "ia64/mparam.h"
+
+#elif defined (__arm__) /* Threshold for ARM */
+#define MPFR_TUNE_CASE "src/arm/mparam.h"
+#include "arm/mparam.h"
+
+#elif defined (__PPC64__) /* Threshold for 64-bit PowerPC, test it before
+ 32-bit PowerPC since _ARCH_PPC is also defined
+ on 64-bit PowerPC */
+#define MPFR_TUNE_CASE "src/powerpc64/mparam.h"
+#include "powerpc64/mparam.h"
+
+#elif defined (_ARCH_PPC) /* Threshold for 32-bit PowerPC */
+#define MPFR_TUNE_CASE "src/powerpc32/mparam.h"
+#include "powerpc32/mparam.h"
+
+#elif defined (__sparc_v9__) /* Threshold for 64-bits Sparc */
+#define MPFR_TUNE_CASE "src/sparc64/mparam.h"
+#include "sparc64/mparam.h"
+
+#elif defined (__hppa__) /* Threshold for HPPA */
+#define MPFR_TUNE_CASE "src/hppa/mparam.h"
+#include "hppa/mparam.h"
+
+#else
+#define MPFR_TUNE_CASE "default"
+#endif
+
+/****************************************************************
+ * Default values of Threshold. *
+ * Must be included in any case: it checks, for every constant, *
+ * if it has been defined, and it sets it to a default value if *
+ * it was not previously defined. *
+ ****************************************************************/
+#include "generic/mparam.h"
diff --git a/mpfr/src/mpf2mpfr.h b/mpfr/src/mpf2mpfr.h
new file mode 100644
index 0000000000..ef6ab82e43
--- /dev/null
+++ b/mpfr/src/mpf2mpfr.h
@@ -0,0 +1,175 @@
+/* mpf2mpfr.h -- Compatibility include file with mpf.
+
+Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __MPFR_FROM_MPF__
+#define __MPFR_FROM_MPF__
+
+/* types */
+#define mpf_t mpfr_t
+#define mpf_srcptr mpfr_srcptr
+#define mpf_ptr mpfr_ptr
+
+/* Get current Rounding Mode */
+#ifndef MPFR_DEFAULT_RND
+# define MPFR_DEFAULT_RND mpfr_get_default_rounding_mode ()
+#endif
+
+/* mpf_init initalizes at 0 */
+#undef mpf_init
+#define mpf_init(x) mpfr_init_set_ui ((x), 0, MPFR_DEFAULT_RND)
+#undef mpf_init2
+#define mpf_init2(x,p) (mpfr_init2((x),(p)), mpfr_set_ui ((x), 0, MPFR_DEFAULT_RND))
+
+/* functions which don't take as argument the rounding mode */
+#undef mpf_ceil
+#define mpf_ceil mpfr_ceil
+#undef mpf_clear
+#define mpf_clear mpfr_clear
+#undef mpf_cmp
+#define mpf_cmp mpfr_cmp
+#undef mpf_cmp_si
+#define mpf_cmp_si mpfr_cmp_si
+#undef mpf_cmp_ui
+#define mpf_cmp_ui mpfr_cmp_ui
+#undef mpf_cmp_d
+#define mpf_cmp_d mpfr_cmp_d
+#undef mpf_eq
+#define mpf_eq mpfr_eq
+#undef mpf_floor
+#define mpf_floor mpfr_floor
+#undef mpf_get_prec
+#define mpf_get_prec mpfr_get_prec
+#undef mpf_integer_p
+#define mpf_integer_p mpfr_integer_p
+#undef mpf_random2
+#define mpf_random2 mpfr_random2
+#undef mpf_set_default_prec
+#define mpf_set_default_prec mpfr_set_default_prec
+#undef mpf_get_default_prec
+#define mpf_get_default_prec mpfr_get_default_prec
+#undef mpf_set_prec
+#define mpf_set_prec mpfr_set_prec
+#undef mpf_set_prec_raw
+#define mpf_set_prec_raw(x,p) mpfr_prec_round(x,p,MPFR_DEFAULT_RND)
+#undef mpf_trunc
+#define mpf_trunc mpfr_trunc
+#undef mpf_sgn
+#define mpf_sgn mpfr_sgn
+#undef mpf_swap
+#define mpf_swap mpfr_swap
+#undef mpf_dump
+#define mpf_dump mpfr_dump
+
+/* functions which take as argument the rounding mode */
+#undef mpf_abs
+#define mpf_abs(x,y) mpfr_abs(x,y,MPFR_DEFAULT_RND)
+#undef mpf_add
+#define mpf_add(x,y,z) mpfr_add(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_add_ui
+#define mpf_add_ui(x,y,z) mpfr_add_ui(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_div
+#define mpf_div(x,y,z) mpfr_div(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_div_ui
+#define mpf_div_ui(x,y,z) mpfr_div_ui(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_div_2exp
+#define mpf_div_2exp(x,y,z) mpfr_div_2exp(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_fits_slong_p
+#define mpf_fits_slong_p(x) mpfr_fits_ulong_p(x,MPFR_DEFAULT_RND)
+#undef mpf_fits_ulong_p
+#define mpf_fits_ulong_p(x) mpfr_fits_ulong_p(x,MPFR_DEFAULT_RND)
+#undef mpf_fits_sint_p
+#define mpf_fits_sint_p(x) mpfr_fits_uint_p(x,MPFR_DEFAULT_RND)
+#undef mpf_fits_uint_p
+#define mpf_fits_uint_p(x) mpfr_fits_uint_p(x,MPFR_DEFAULT_RND)
+#undef mpf_fits_sshort_p
+#define mpf_fits_sshort_p(x) mpfr_fits_ushort_p(x,MPFR_DEFAULT_RND)
+#undef mpf_fits_ushort_p
+#define mpf_fits_ushort_p(x) mpfr_fits_ushort_p(x,MPFR_DEFAULT_RND)
+#undef mpf_get_str
+#define mpf_get_str(x,y,z,t,u) mpfr_get_str(x,y,z,t,u,MPFR_DEFAULT_RND)
+#undef mpf_get_d
+#define mpf_get_d(x) mpfr_get_d(x,MPFR_DEFAULT_RND)
+#undef mpf_get_d_2exp
+#define mpf_get_d_2exp(e,x) mpfr_get_d_2exp(e,x,MPFR_DEFAULT_RND)
+#undef mpf_get_ui
+#define mpf_get_ui(x) mpfr_get_ui(x,MPFR_DEFAULT_RND)
+#undef mpf_get_si
+#define mpf_get_si(x) mpfr_get_ui(x,MPFR_DEFAULT_RND)
+#undef mpf_inp_str
+#define mpf_inp_str(x,y,z) mpfr_inp_str(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_set_str
+#define mpf_set_str(x,y,z) mpfr_set_str(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_init_set
+#define mpf_init_set(x,y) mpfr_init_set(x,y,MPFR_DEFAULT_RND)
+#undef mpf_init_set_d
+#define mpf_init_set_d(x,y) mpfr_init_set_d(x,y,MPFR_DEFAULT_RND)
+#undef mpf_init_set_si
+#define mpf_init_set_si(x,y) mpfr_init_set_si(x,y,MPFR_DEFAULT_RND)
+#undef mpf_init_set_str
+#define mpf_init_set_str(x,y,z) mpfr_init_set_str(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_init_set_ui
+#define mpf_init_set_ui(x,y) mpfr_init_set_ui(x,y,MPFR_DEFAULT_RND)
+#undef mpf_mul
+#define mpf_mul(x,y,z) mpfr_mul(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_mul_2exp
+#define mpf_mul_2exp(x,y,z) mpfr_mul_2exp(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_mul_ui
+#define mpf_mul_ui(x,y,z) mpfr_mul_ui(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_neg
+#define mpf_neg(x,y) mpfr_neg(x,y,MPFR_DEFAULT_RND)
+#undef mpf_out_str
+#define mpf_out_str(x,y,z,t) mpfr_out_str(x,y,z,t,MPFR_DEFAULT_RND)
+#undef mpf_pow_ui
+#define mpf_pow_ui(x,y,z) mpfr_pow_ui(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_reldiff
+#define mpf_reldiff(x,y,z) mpfr_reldiff(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_set
+#define mpf_set(x,y) mpfr_set(x,y,MPFR_DEFAULT_RND)
+#undef mpf_set_d
+#define mpf_set_d(x,y) mpfr_set_d(x,y,MPFR_DEFAULT_RND)
+#undef mpf_set_q
+#define mpf_set_q(x,y) mpfr_set_q(x,y,MPFR_DEFAULT_RND)
+#undef mpf_set_si
+#define mpf_set_si(x,y) mpfr_set_si(x,y,MPFR_DEFAULT_RND)
+#undef mpf_set_ui
+#define mpf_set_ui(x,y) mpfr_set_ui(x,y,MPFR_DEFAULT_RND)
+#undef mpf_set_z
+#define mpf_set_z(x,y) mpfr_set_z(x,y,MPFR_DEFAULT_RND)
+#undef mpf_sqrt
+#define mpf_sqrt(x,y) mpfr_sqrt(x,y,MPFR_DEFAULT_RND)
+#undef mpf_sqrt_ui
+#define mpf_sqrt_ui(x,y) mpfr_sqrt_ui(x,y,MPFR_DEFAULT_RND)
+#undef mpf_sub
+#define mpf_sub(x,y,z) mpfr_sub(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_sub_ui
+#define mpf_sub_ui(x,y,z) mpfr_sub_ui(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_ui_div
+#define mpf_ui_div(x,y,z) mpfr_ui_div(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_ui_sub
+#define mpf_ui_sub(x,y,z) mpfr_ui_sub(x,y,z,MPFR_DEFAULT_RND)
+#undef mpf_urandomb
+#define mpf_urandomb(x,y,n) mpfr_urandomb(x,y)
+
+#undef mpz_set_f
+#define mpz_set_f(z,f) mpfr_get_z(z,f,MPFR_DEFAULT_RND)
+
+#endif /* __MPFR_FROM_MPF__ */
diff --git a/mpfr/src/mpfr-gmp.c b/mpfr/src/mpfr-gmp.c
new file mode 100644
index 0000000000..0d60c88c60
--- /dev/null
+++ b/mpfr/src/mpfr-gmp.c
@@ -0,0 +1,386 @@
+/* mpfr_gmp -- Limited gmp-impl emulator
+ Modified version of the GMP files.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h> /* For malloc, free, realloc and abort */
+
+#include "mpfr-impl.h"
+
+#ifndef MPFR_HAVE_GMP_IMPL
+
+char mpfr_rands_initialized = 0;
+gmp_randstate_t mpfr_rands;
+
+const struct bases mpfr_bases[257] =
+{
+ /* 0 */ {0.0},
+ /* 1 */ {1e37},
+ /* 2 */ {1.0000000000000000},
+ /* 3 */ {0.6309297535714574},
+ /* 4 */ {0.5000000000000000},
+ /* 5 */ {0.4306765580733931},
+ /* 6 */ {0.3868528072345416},
+ /* 7 */ {0.3562071871080222},
+ /* 8 */ {0.3333333333333333},
+ /* 9 */ {0.3154648767857287},
+ /* 10 */ {0.3010299956639812},
+ /* 11 */ {0.2890648263178878},
+ /* 12 */ {0.2789429456511298},
+ /* 13 */ {0.2702381544273197},
+ /* 14 */ {0.2626495350371935},
+ /* 15 */ {0.2559580248098155},
+ /* 16 */ {0.2500000000000000},
+ /* 17 */ {0.2446505421182260},
+ /* 18 */ {0.2398124665681314},
+ /* 19 */ {0.2354089133666382},
+ /* 20 */ {0.2313782131597592},
+ /* 21 */ {0.2276702486969530},
+ /* 22 */ {0.2242438242175754},
+ /* 23 */ {0.2210647294575037},
+ /* 24 */ {0.2181042919855316},
+ /* 25 */ {0.2153382790366965},
+ /* 26 */ {0.2127460535533632},
+ /* 27 */ {0.2103099178571525},
+ /* 28 */ {0.2080145976765095},
+ /* 29 */ {0.2058468324604344},
+ /* 30 */ {0.2037950470905062},
+ /* 31 */ {0.2018490865820999},
+ /* 32 */ {0.2000000000000000},
+ /* 33 */ {0.1982398631705605},
+ /* 34 */ {0.1965616322328226},
+ /* 35 */ {0.1949590218937863},
+ /* 36 */ {0.1934264036172708},
+ /* 37 */ {0.1919587200065601},
+ /* 38 */ {0.1905514124267734},
+ /* 39 */ {0.1892003595168700},
+ /* 40 */ {0.1879018247091076},
+ /* 41 */ {0.1866524112389434},
+ /* 42 */ {0.1854490234153689},
+ /* 43 */ {0.1842888331487062},
+ /* 44 */ {0.1831692509136336},
+ /* 45 */ {0.1820879004699383},
+ /* 46 */ {0.1810425967800402},
+ /* 47 */ {0.1800313266566926},
+ /* 48 */ {0.1790522317510414},
+ /* 49 */ {0.1781035935540111},
+ /* 50 */ {0.1771838201355579},
+ /* 51 */ {0.1762914343888821},
+ /* 52 */ {0.1754250635819545},
+ /* 53 */ {0.1745834300480449},
+ /* 54 */ {0.1737653428714400},
+ /* 55 */ {0.1729696904450771},
+ /* 56 */ {0.1721954337940981},
+ /* 57 */ {0.1714416005739134},
+ /* 58 */ {0.1707072796637201},
+ /* 59 */ {0.1699916162869140},
+ /* 60 */ {0.1692938075987814},
+ /* 61 */ {0.1686130986895011},
+ /* 62 */ {0.1679487789570419},
+ /* 63 */ {0.1673001788101741},
+ /* 64 */ {0.1666666666666667},
+ /* 65 */ {0.1660476462159378},
+ /* 66 */ {0.1654425539190583},
+ /* 67 */ {0.1648508567221603},
+ /* 68 */ {0.1642720499620502},
+ /* 69 */ {0.1637056554452156},
+ /* 70 */ {0.1631512196835108},
+ /* 71 */ {0.1626083122716342},
+ /* 72 */ {0.1620765243931223},
+ /* 73 */ {0.1615554674429964},
+ /* 74 */ {0.1610447717564444},
+ /* 75 */ {0.1605440854340214},
+ /* 76 */ {0.1600530732548213},
+ /* 77 */ {0.1595714156699382},
+ /* 78 */ {0.1590988078692941},
+ /* 79 */ {0.1586349589155960},
+ /* 80 */ {0.1581795909397823},
+ /* 81 */ {0.1577324383928644},
+ /* 82 */ {0.1572932473495469},
+ /* 83 */ {0.1568617748594410},
+ /* 84 */ {0.1564377883420715},
+ /* 85 */ {0.1560210650222250},
+ /* 86 */ {0.1556113914024939},
+ /* 87 */ {0.1552085627701551},
+ /* 88 */ {0.1548123827357682},
+ /* 89 */ {0.1544226628011101},
+ /* 90 */ {0.1540392219542636},
+ /* 91 */ {0.1536618862898642},
+ /* 92 */ {0.1532904886526781},
+ /* 93 */ {0.1529248683028321},
+ /* 94 */ {0.1525648706011593},
+ /* 95 */ {0.1522103467132434},
+ /* 96 */ {0.1518611533308632},
+ /* 97 */ {0.1515171524096389},
+ /* 98 */ {0.1511782109217764},
+ /* 99 */ {0.1508442006228941},
+ /* 100 */ {0.1505149978319906},
+ /* 101 */ {0.1501904832236880},
+ /* 102 */ {0.1498705416319474},
+ /* 103 */ {0.1495550618645152},
+ /* 104 */ {0.1492439365274121},
+ /* 105 */ {0.1489370618588283},
+ /* 106 */ {0.1486343375718350},
+ /* 107 */ {0.1483356667053617},
+ /* 108 */ {0.1480409554829326},
+ /* 109 */ {0.1477501131786861},
+ /* 110 */ {0.1474630519902391},
+ /* 111 */ {0.1471796869179852},
+ /* 112 */ {0.1468999356504447},
+ /* 113 */ {0.1466237184553111},
+ /* 114 */ {0.1463509580758620},
+ /* 115 */ {0.1460815796324244},
+ /* 116 */ {0.1458155105286054},
+ /* 117 */ {0.1455526803620167},
+ /* 118 */ {0.1452930208392429},
+ /* 119 */ {0.1450364656948130},
+ /* 120 */ {0.1447829506139581},
+ /* 121 */ {0.1445324131589439},
+ /* 122 */ {0.1442847926987864},
+ /* 123 */ {0.1440400303421672},
+ /* 124 */ {0.1437980688733776},
+ /* 125 */ {0.1435588526911310},
+ /* 126 */ {0.1433223277500932},
+ /* 127 */ {0.1430884415049874},
+ /* 128 */ {0.1428571428571428},
+ /* 129 */ {0.1426283821033600},
+ /* 130 */ {0.1424021108869747},
+ /* 131 */ {0.1421782821510107},
+ /* 132 */ {0.1419568500933153},
+ /* 133 */ {0.1417377701235801},
+ /* 134 */ {0.1415209988221527},
+ /* 135 */ {0.1413064939005528},
+ /* 136 */ {0.1410942141636095},
+ /* 137 */ {0.1408841194731412},
+ /* 138 */ {0.1406761707131039},
+ /* 139 */ {0.1404703297561400},
+ /* 140 */ {0.1402665594314587},
+ /* 141 */ {0.1400648234939879},
+ /* 142 */ {0.1398650865947379},
+ /* 143 */ {0.1396673142523192},
+ /* 144 */ {0.1394714728255649},
+ /* 145 */ {0.1392775294872041},
+ /* 146 */ {0.1390854521985406},
+ /* 147 */ {0.1388952096850913},
+ /* 148 */ {0.1387067714131417},
+ /* 149 */ {0.1385201075671774},
+ /* 150 */ {0.1383351890281539},
+ /* 151 */ {0.1381519873525671},
+ /* 152 */ {0.1379704747522905},
+ /* 153 */ {0.1377906240751463},
+ /* 154 */ {0.1376124087861776},
+ /* 155 */ {0.1374358029495937},
+ /* 156 */ {0.1372607812113589},
+ /* 157 */ {0.1370873187823978},
+ /* 158 */ {0.1369153914223921},
+ /* 159 */ {0.1367449754241439},
+ /* 160 */ {0.1365760475984821},
+ /* 161 */ {0.1364085852596902},
+ /* 162 */ {0.1362425662114337},
+ /* 163 */ {0.1360779687331669},
+ /* 164 */ {0.1359147715670014},
+ /* 165 */ {0.1357529539050150},
+ /* 166 */ {0.1355924953769864},
+ /* 167 */ {0.1354333760385373},
+ /* 168 */ {0.1352755763596663},
+ /* 169 */ {0.1351190772136599},
+ /* 170 */ {0.1349638598663645},
+ /* 171 */ {0.1348099059658080},
+ /* 172 */ {0.1346571975321549},
+ /* 173 */ {0.1345057169479844},
+ /* 174 */ {0.1343554469488779},
+ /* 175 */ {0.1342063706143054},
+ /* 176 */ {0.1340584713587979},
+ /* 177 */ {0.1339117329233981},
+ /* 178 */ {0.1337661393673756},
+ /* 179 */ {0.1336216750601996},
+ /* 180 */ {0.1334783246737591},
+ /* 181 */ {0.1333360731748201},
+ /* 182 */ {0.1331949058177136},
+ /* 183 */ {0.1330548081372441},
+ /* 184 */ {0.1329157659418126},
+ /* 185 */ {0.1327777653067443},
+ /* 186 */ {0.1326407925678156},
+ /* 187 */ {0.1325048343149731},
+ /* 188 */ {0.1323698773862368},
+ /* 189 */ {0.1322359088617821},
+ /* 190 */ {0.1321029160581950},
+ /* 191 */ {0.1319708865228925},
+ /* 192 */ {0.1318398080287045},
+ /* 193 */ {0.1317096685686114},
+ /* 194 */ {0.1315804563506306},
+ /* 195 */ {0.1314521597928493},
+ /* 196 */ {0.1313247675185968},
+ /* 197 */ {0.1311982683517524},
+ /* 198 */ {0.1310726513121843},
+ /* 199 */ {0.1309479056113158},
+ /* 200 */ {0.1308240206478128},
+ /* 201 */ {0.1307009860033912},
+ /* 202 */ {0.1305787914387386},
+ /* 203 */ {0.1304574268895465},
+ /* 204 */ {0.1303368824626505},
+ /* 205 */ {0.1302171484322746},
+ /* 206 */ {0.1300982152363760},
+ /* 207 */ {0.1299800734730872},
+ /* 208 */ {0.1298627138972530},
+ /* 209 */ {0.1297461274170591},
+ /* 210 */ {0.1296303050907487},
+ /* 211 */ {0.1295152381234257},
+ /* 212 */ {0.1294009178639407},
+ /* 213 */ {0.1292873358018581},
+ /* 214 */ {0.1291744835645007},
+ /* 215 */ {0.1290623529140715},
+ /* 216 */ {0.1289509357448472},
+ /* 217 */ {0.1288402240804449},
+ /* 218 */ {0.1287302100711566},
+ /* 219 */ {0.1286208859913518},
+ /* 220 */ {0.1285122442369443},
+ /* 221 */ {0.1284042773229231},
+ /* 222 */ {0.1282969778809442},
+ /* 223 */ {0.1281903386569819},
+ /* 224 */ {0.1280843525090381},
+ /* 225 */ {0.1279790124049077},
+ /* 226 */ {0.1278743114199984},
+ /* 227 */ {0.1277702427352035},
+ /* 228 */ {0.1276667996348261},
+ /* 229 */ {0.1275639755045533},
+ /* 230 */ {0.1274617638294791},
+ /* 231 */ {0.1273601581921740},
+ /* 232 */ {0.1272591522708010},
+ /* 233 */ {0.1271587398372755},
+ /* 234 */ {0.1270589147554692},
+ /* 235 */ {0.1269596709794558},
+ /* 236 */ {0.1268610025517973},
+ /* 237 */ {0.1267629036018709},
+ /* 238 */ {0.1266653683442337},
+ /* 239 */ {0.1265683910770258},
+ /* 240 */ {0.1264719661804097},
+ /* 241 */ {0.1263760881150453},
+ /* 242 */ {0.1262807514205999},
+ /* 243 */ {0.1261859507142915},
+ /* 244 */ {0.1260916806894653},
+ /* 245 */ {0.1259979361142023},
+ /* 246 */ {0.1259047118299582},
+ /* 247 */ {0.1258120027502338},
+ /* 248 */ {0.1257198038592741},
+ /* 249 */ {0.1256281102107963},
+ /* 250 */ {0.1255369169267456},
+ /* 251 */ {0.1254462191960791},
+ /* 252 */ {0.1253560122735751},
+ /* 253 */ {0.1252662914786691},
+ /* 254 */ {0.1251770521943144},
+ /* 255 */ {0.1250882898658681},
+ /* 256 */ {0.1250000000000000},
+};
+
+void
+mpfr_assert_fail (const char *filename, int linenum,
+ const char *expr)
+{
+ if (filename != NULL && filename[0] != '\0')
+ {
+ fprintf (stderr, "%s:", filename);
+ if (linenum != -1)
+ fprintf (stderr, "%d: ", linenum);
+ }
+ fprintf (stderr, "MPFR assertion failed: %s\n", expr);
+ abort();
+}
+
+#ifdef mp_get_memory_functions
+
+/* putting 0 as initial values forces those symbols to be fully defined,
+ and always resolved, otherwise they are only tentatively defined, which
+ leads to problems on e.g. MacOS, cf
+ http://lists.gforge.inria.fr/pipermail/mpc-discuss/2008-November/000048.html
+ and http://software.intel.com/en-us/articles/intelr-fortran-compiler-for-mac-os-non_lazy_ptr-unresolved-references-from-linking
+ Note that using ranlib -c or libtool -c is another fix.
+*/
+void * (*mpfr_allocate_func) (size_t) = 0;
+void * (*mpfr_reallocate_func) (void *,size_t, size_t) = 0;
+void (*mpfr_free_func) (void *, size_t) = 0;
+
+#endif
+
+void *
+mpfr_default_allocate (size_t size)
+{
+ void *ret;
+ ret = malloc (size);
+ if (ret == NULL)
+ {
+ fprintf (stderr, "MPFR: Can't allocate memory (size=%lu)\n",
+ (unsigned long) size);
+ abort ();
+ }
+ return ret;
+}
+
+void *
+mpfr_default_reallocate (void *oldptr, size_t old_size, size_t new_size)
+{
+ void *ret;
+ ret = realloc (oldptr, new_size);
+ if (ret == NULL)
+ {
+ fprintf (stderr,
+ "MPFR: Can't reallocate memory (old_size=%lu new_size=%lu)\n",
+ (unsigned long) old_size, (unsigned long) new_size);
+ abort ();
+ }
+ return ret;
+}
+
+void
+mpfr_default_free (void *blk_ptr, size_t blk_size)
+{
+ free (blk_ptr);
+}
+
+void *
+mpfr_tmp_allocate (struct tmp_marker **tmp_marker, size_t size)
+{
+ struct tmp_marker *head;
+
+ head = (struct tmp_marker *)
+ mpfr_default_allocate (sizeof (struct tmp_marker));
+ head->ptr = mpfr_default_allocate (size);
+ head->size = size;
+ head->next = *tmp_marker;
+ *tmp_marker = head;
+ return head->ptr;
+}
+
+void
+mpfr_tmp_free (struct tmp_marker *tmp_marker)
+{
+ struct tmp_marker *t;
+
+ while (tmp_marker != NULL)
+ {
+ t = tmp_marker;
+ mpfr_default_free (t->ptr, t->size);
+ tmp_marker = t->next;
+ mpfr_default_free (t, sizeof (struct tmp_marker));
+ }
+}
+
+#endif /* Have gmp-impl.h */
diff --git a/mpfr/src/mpfr-gmp.h b/mpfr/src/mpfr-gmp.h
new file mode 100644
index 0000000000..c004fe5bb8
--- /dev/null
+++ b/mpfr/src/mpfr-gmp.h
@@ -0,0 +1,411 @@
+/* Interface to replace gmp-impl.h
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __GMPFR_GMP_H__
+#define __GMPFR_GMP_H__
+
+#ifndef __MPFR_IMPL_H__
+# error "mpfr-impl.h not included"
+#endif
+
+#include <limits.h> /* For INT_MAX, ... */
+#include <string.h> /* For memcpy, memset and memmove */
+
+/* The following tries to get a good version of alloca.
+ See gmp-impl.h for implementation details and original version */
+/* FIXME: the autoconf manual gives a different piece of code under the
+ documentation of the AC_FUNC_ALLOCA macro. Should we switch to it? */
+#ifndef alloca
+# if defined ( __GNUC__ )
+# define alloca __builtin_alloca
+# elif defined (__DECC)
+# define alloca(x) __ALLOCA(x)
+# elif defined (_MSC_VER)
+# include <malloc.h>
+# define alloca _alloca
+# elif defined (HAVE_ALLOCA_H)
+# include <alloca.h>
+# elif defined (_AIX) || defined (_IBMR2)
+# pragma alloca
+# else
+void *alloca (size_t);
+# endif
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* Define GMP_NUMB_BITS
+ Can't use sizeof(mp_limb_t) since it should be a preprocessor constant */
+#if defined(GMP_NUMB_BITS) /* GMP 4.1.2 or above */
+#ifndef GMP_NUMB_BITS
+# define GMP_NUMB_BITS (GMP_NUMB_BITS+GMP_NAIL_BITS)
+#endif
+#elif defined (__GMP_GMP_NUMB_BITS) /* Older versions 4.x.x */
+# define GMP_NUMB_BITS __GMP_GMP_NUMB_BITS
+# define GMP_NUMB_BITS GMP_NUMB_BITS
+# ifndef GMP_NAIL_BITS
+# define GMP_NAIL_BITS 0
+# endif
+#else
+# error "Could not detect GMP_NUMB_BITS. Try with gmp internal files."
+#endif
+
+/* Define some macros */
+#define BYTES_PER_MP_LIMB (GMP_NUMB_BITS/CHAR_BIT)
+
+#define MP_LIMB_T_MAX (~(mp_limb_t)0)
+
+#define ULONG_HIGHBIT (ULONG_MAX ^ ((unsigned long) ULONG_MAX >> 1))
+#define UINT_HIGHBIT (UINT_MAX ^ ((unsigned) UINT_MAX >> 1))
+#define USHRT_HIGHBIT ((unsigned short) (USHRT_MAX ^ ((unsigned short) USHRT_MAX >> 1)))
+
+#define GMP_LIMB_HIGHBIT (MP_LIMB_T_MAX ^ (MP_LIMB_T_MAX >> 1))
+
+
+#if __GMP_MP_SIZE_T_INT
+#define MP_SIZE_T_MAX INT_MAX
+#define MP_SIZE_T_MIN INT_MIN
+#else
+#define MP_SIZE_T_MAX LONG_MAX
+#define MP_SIZE_T_MIN LONG_MIN
+#endif
+
+#define LONG_HIGHBIT LONG_MIN
+#define INT_HIGHBIT INT_MIN
+#define SHRT_HIGHBIT SHRT_MIN
+
+/* MP_LIMB macros */
+#define MPN_ZERO(dst, n) memset((dst), 0, (n)*BYTES_PER_MP_LIMB)
+#define MPN_COPY_DECR(dst,src,n) memmove((dst),(src),(n)*BYTES_PER_MP_LIMB)
+#define MPN_COPY_INCR(dst,src,n) memmove((dst),(src),(n)*BYTES_PER_MP_LIMB)
+#define MPN_COPY(dst,src,n) \
+ do \
+ { \
+ if ((dst) != (src)) \
+ { \
+ MPFR_ASSERTD ((char *) (dst) >= (char *) (src) + \
+ (n) * BYTES_PER_MP_LIMB || \
+ (char *) (src) >= (char *) (dst) + \
+ (n) * BYTES_PER_MP_LIMB); \
+ memcpy ((dst), (src), (n) * BYTES_PER_MP_LIMB); \
+ } \
+ } \
+ while (0)
+
+/* MPN macros taken from gmp-impl.h */
+#define MPN_NORMALIZE(DST, NLIMBS) \
+ do { \
+ while (NLIMBS > 0) \
+ { \
+ if ((DST)[(NLIMBS) - 1] != 0) \
+ break; \
+ NLIMBS--; \
+ } \
+ } while (0)
+#define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS) \
+ do { \
+ MPFR_ASSERTD ((NLIMBS) >= 1); \
+ while (1) \
+ { \
+ if ((DST)[(NLIMBS) - 1] != 0) \
+ break; \
+ NLIMBS--; \
+ } \
+ } while (0)
+#define MPN_OVERLAP_P(xp, xsize, yp, ysize) \
+ ((xp) + (xsize) > (yp) && (yp) + (ysize) > (xp))
+#define MPN_SAME_OR_INCR2_P(dst, dsize, src, ssize) \
+ ((dst) <= (src) || ! MPN_OVERLAP_P (dst, dsize, src, ssize))
+#define MPN_SAME_OR_INCR_P(dst, src, size) \
+ MPN_SAME_OR_INCR2_P(dst, size, src, size)
+#define MPN_SAME_OR_DECR2_P(dst, dsize, src, ssize) \
+ ((dst) >= (src) || ! MPN_OVERLAP_P (dst, dsize, src, ssize))
+#define MPN_SAME_OR_DECR_P(dst, src, size) \
+ MPN_SAME_OR_DECR2_P(dst, size, src, size)
+
+/* If mul_basecase or mpn_sqr_basecase are not exported, used mpn_mul instead */
+#ifndef mpn_mul_basecase
+# define mpn_mul_basecase(dst,s1,n1,s2,n2) mpn_mul((dst),(s1),(n1),(s2),(n2))
+#endif
+#ifndef mpn_sqr_basecase
+# define mpn_sqr_basecase(dst,src,n) mpn_mul((dst),(src),(n),(src),(n))
+#endif
+
+/* ASSERT */
+__MPFR_DECLSPEC void mpfr_assert_fail _MPFR_PROTO((const char *, int,
+ const char *));
+
+#define ASSERT_FAIL(expr) mpfr_assert_fail (__FILE__, __LINE__, #expr)
+#define ASSERT(expr) MPFR_ASSERTD(expr)
+
+/* Access fileds of GMP struct */
+#define SIZ(x) ((x)->_mp_size)
+#define ABSIZ(x) ABS (SIZ (x))
+#define PTR(x) ((x)->_mp_d)
+#define EXP(x) ((x)->_mp_exp)
+#define PREC(x) ((x)->_mp_prec)
+#define ALLOC(x) ((x)->_mp_alloc)
+#define MPZ_REALLOC(z,n) ((n) > ALLOC(z) ? _mpz_realloc(z,n) : PTR(z))
+
+/* Non IEEE float supports -- needs to detect them with proper configure */
+#undef XDEBUG
+#define XDEBUG
+
+/* For longlong.h */
+#ifdef HAVE_ATTRIBUTE_MODE
+typedef unsigned int UQItype __attribute__ ((mode (QI)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+#else
+typedef unsigned char UQItype;
+typedef long SItype;
+typedef unsigned long USItype;
+#ifdef HAVE_LONG_LONG
+typedef long long int DItype;
+typedef unsigned long long int UDItype;
+#else /* Assume `long' gives us a wide enough type. Needed for hppa2.0w. */
+typedef long int DItype;
+typedef unsigned long int UDItype;
+#endif
+#endif
+typedef mp_limb_t UWtype;
+typedef unsigned int UHWtype;
+#define W_TYPE_SIZE GMP_NUMB_BITS
+
+/* Remap names of internal mpn functions (for longlong.h). */
+#undef __clz_tab
+#define __clz_tab mpfr_clz_tab
+
+/* Use (4.0 * ...) instead of (2.0 * ...) to work around buggy compilers
+ that don't convert ulong->double correctly (eg. SunOS 4 native cc). */
+#undef MP_BASE_AS_DOUBLE
+#define MP_BASE_AS_DOUBLE (4.0 * ((mp_limb_t) 1 << (GMP_NUMB_BITS - 2)))
+
+/* Structure for conversion between internal binary format and
+ strings in base 2..36. */
+struct bases
+{
+ /* log(2)/log(conversion_base) */
+ double chars_per_bit_exactly;
+};
+#undef __mp_bases
+#define __mp_bases mpfr_bases
+__MPFR_DECLSPEC extern const struct bases mpfr_bases[257];
+
+/* Standard macros */
+#undef ABS
+#undef MIN
+#undef MAX
+#undef numberof
+#define ABS(x) ((x) >= 0 ? (x) : -(x))
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#define MAX(h,i) ((h) > (i) ? (h) : (i))
+#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
+
+/* Random */
+#undef __gmp_rands_initialized
+#undef __gmp_rands
+#define __gmp_rands_initialized mpfr_rands_initialized
+#define __gmp_rands mpfr_rands
+
+__MPFR_DECLSPEC extern char mpfr_rands_initialized;
+__MPFR_DECLSPEC extern gmp_randstate_t mpfr_rands;
+
+#undef RANDS
+#define RANDS \
+ ((__gmp_rands_initialized ? 0 \
+ : (__gmp_rands_initialized = 1, \
+ gmp_randinit_default (__gmp_rands), 0)), \
+ __gmp_rands)
+
+#undef RANDS_CLEAR
+#define RANDS_CLEAR() \
+ do { \
+ if (__gmp_rands_initialized) \
+ { \
+ __gmp_rands_initialized = 0; \
+ gmp_randclear (__gmp_rands); \
+ } \
+ } while (0)
+
+typedef __gmp_randstate_struct *gmp_randstate_ptr;
+
+/* Allocate func are defined in gmp-impl.h */
+
+/* In newer GMP, there aren't anymore __gmp_allocate_func,
+ __gmp_reallocate_func & __gmp_free_func in gmp.h
+ Just getting the correct value by calling mp_get_memory_functions */
+#ifdef mp_get_memory_functions
+
+#undef __gmp_allocate_func
+#undef __gmp_reallocate_func
+#undef __gmp_free_func
+#define MPFR_GET_MEMFUNC mp_get_memory_functions(&mpfr_allocate_func, &mpfr_reallocate_func, &mpfr_free_func)
+#define __gmp_allocate_func (MPFR_GET_MEMFUNC, mpfr_allocate_func)
+#define __gmp_reallocate_func (MPFR_GET_MEMFUNC, mpfr_reallocate_func)
+#define __gmp_free_func (MPFR_GET_MEMFUNC, mpfr_free_func)
+__MPFR_DECLSPEC extern void * (*mpfr_allocate_func) _MPFR_PROTO ((size_t));
+__MPFR_DECLSPEC extern void * (*mpfr_reallocate_func) _MPFR_PROTO ((void *,
+ size_t, size_t));
+__MPFR_DECLSPEC extern void (*mpfr_free_func) _MPFR_PROTO ((void *,
+ size_t));
+
+#endif
+
+#undef __gmp_default_allocate
+#undef __gmp_default_reallocate
+#undef __gmp_default_free
+#define __gmp_default_allocate mpfr_default_allocate
+#define __gmp_default_reallocate mpfr_default_reallocate
+#define __gmp_default_free mpfr_default_free
+__MPFR_DECLSPEC void *__gmp_default_allocate _MPFR_PROTO ((size_t));
+__MPFR_DECLSPEC void *__gmp_default_reallocate _MPFR_PROTO ((void *, size_t,
+ size_t));
+__MPFR_DECLSPEC void __gmp_default_free _MPFR_PROTO ((void *, size_t));
+
+#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_ROOTREM)
+#ifndef __gmpn_rootrem
+ __MPFR_DECLSPEC mp_size_t __gmpn_rootrem _MPFR_PROTO ((mp_limb_t*,
+ mp_limb_t*, mp_limb_t*, mp_size_t, mp_limb_t));
+#endif
+#endif
+
+#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_SBPI1_DIVAPPR_Q)
+#ifndef __gmpn_sbpi1_divappr_q
+ __MPFR_DECLSPEC mp_limb_t __gmpn_sbpi1_divappr_q _MPFR_PROTO ((mp_limb_t*,
+ mp_limb_t*, mp_size_t, mp_limb_t*, mp_size_t, mp_limb_t));
+#endif
+#endif
+
+/* Temp memory allocate */
+
+struct tmp_marker
+{
+ void *ptr;
+ size_t size;
+ struct tmp_marker *next;
+};
+
+__MPFR_DECLSPEC void *mpfr_tmp_allocate _MPFR_PROTO ((struct tmp_marker **,
+ size_t));
+__MPFR_DECLSPEC void mpfr_tmp_free _MPFR_PROTO ((struct tmp_marker *));
+
+/* Do not define TMP_SALLOC (see the test in mpfr-impl.h)! */
+#define TMP_ALLOC(n) (MPFR_LIKELY ((n) < 16384) ? \
+ alloca (n) : mpfr_tmp_allocate (&tmp_marker, (n)))
+#define TMP_DECL(m) struct tmp_marker *tmp_marker
+#define TMP_MARK(m) (tmp_marker = 0)
+#define TMP_FREE(m) mpfr_tmp_free (tmp_marker)
+
+/* invert_limb macro, copied from GMP 5.0.2, file gmp-impl.h.
+ It returns invxl = floor((B^2-1)/xl)-B, where B=2^BITS_PER_LIMB,
+ assuming the most significant bit of xl is set. */
+#undef invert_limb
+#define invert_limb(invxl,xl) \
+ do { \
+ mp_limb_t dummy; \
+ MPFR_ASSERTD ((xl) != 0); \
+ udiv_qrnnd (invxl, dummy, ~(xl), ~(mp_limb_t)0, xl); \
+ } while (0)
+
+typedef struct {mp_limb_t inv32;} mpfr_pi1_t; /* We changed gmp_pi1_t into
+ mpfr_pi1_t to avoid using
+ GMP's namespace. */
+/* invert_pi1 macro, adapted from GMP 5.0.2, file gmp-impl.h.
+ It returns dinv = floor((B^3-1)/(d1*B+d0))-B, where B=2^BITS_PER_LIMB,
+ assuming the most significant bit of d1 is set. */
+#undef invert_pi1
+#define invert_pi1(dinv, d1, d0) \
+ do { \
+ mp_limb_t _v, _p, _t1, _t0, _mask; \
+ invert_limb (_v, d1); \
+ _p = d1 * _v; \
+ _p += d0; \
+ if (_p < d0) \
+ { \
+ _v--; \
+ _mask = -(_p >= d1); \
+ _p -= d1; \
+ _v += _mask; \
+ _p -= _mask & d1; \
+ } \
+ umul_ppmm (_t1, _t0, d0, _v); \
+ _p += _t1; \
+ if (_p < _t1) \
+ { \
+ _v--; \
+ if (MPFR_UNLIKELY (_p >= d1)) \
+ { \
+ if (_p > d1 || _t0 >= d0) \
+ _v--; \
+ } \
+ } \
+ (dinv).inv32 = _v; \
+ } while (0)
+
+/* udiv_qr_3by2 macro, adapted from GMP 5.0.2, file gmp-impl.h.
+ Compute quotient the quotient and remainder for n / d. Requires d
+ >= B^2 / 2 and n < d B. dinv is the inverse
+
+ floor ((B^3 - 1) / (d0 + d1 B)) - B.
+
+ NOTE: Output variables are updated multiple times. Only some inputs
+ and outputs may overlap.
+*/
+#undef udiv_qr_3by2
+#define udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \
+ do { \
+ mp_limb_t _q0, _t1, _t0, _mask; \
+ umul_ppmm ((q), _q0, (n2), (dinv)); \
+ add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \
+ \
+ /* Compute the two most significant limbs of n - q'd */ \
+ (r1) = (n1) - (d1) * (q); \
+ (r0) = (n0); \
+ sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \
+ umul_ppmm (_t1, _t0, (d0), (q)); \
+ sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \
+ (q)++; \
+ \
+ /* Conditionally adjust q and the remainders */ \
+ _mask = - (mp_limb_t) ((r1) >= _q0); \
+ (q) += _mask; \
+ add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \
+ if (MPFR_UNLIKELY ((r1) >= (d1))) \
+ { \
+ if ((r1) > (d1) || (r0) >= (d0)) \
+ { \
+ (q)++; \
+ sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \
+ } \
+ } \
+ } while (0)
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* Gmp internal emulator */
diff --git a/mpfr/src/mpfr-impl.h b/mpfr/src/mpfr-impl.h
new file mode 100644
index 0000000000..fa693d3ff5
--- /dev/null
+++ b/mpfr/src/mpfr-impl.h
@@ -0,0 +1,1924 @@
+/* Utilities for MPFR developers, not exported.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __MPFR_IMPL_H__
+#define __MPFR_IMPL_H__
+
+/* Let's include some standard headers unconditionally as they are
+ already needed by several source files or when some options are
+ enabled/disabled, and it is easy to forget them (some configure
+ options may hide the error).
+ Note: If some source file must not have such a header included
+ (which is very unlikely and probably means something broken in
+ this source file), we should do that with some macro (that would
+ also force to disable incompatible features). */
+#if defined (__cplusplus)
+#include <cstdio>
+#include <cstring>
+#else
+#include <stdio.h>
+#include <string.h>
+#endif
+#include <limits.h>
+
+#if _MPFR_EXP_FORMAT == 4
+/* mpfr_exp_t will be defined as intmax_t */
+# include "mpfr-intmax.h"
+#endif
+
+/* Check if we are inside a build of MPFR or inside the test suite.
+ This is needed in mpfr.h to export or import the functions.
+ It matters only for Windows DLL */
+#ifndef __MPFR_TEST_H__
+# define __MPFR_WITHIN_MPFR 1
+#endif
+
+/******************************************************
+ ****************** Include files *********************
+ ******************************************************/
+
+/* Include 'config.h' before using ANY configure macros if needed
+ NOTE: It isn't MPFR 'config.h', but GMP's one! */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef MPFR_HAVE_GMP_IMPL /* Build with gmp internals*/
+
+# ifndef __GMP_H__
+# include "gmp.h"
+# endif
+# ifndef __GMP_IMPL_H__
+# include "gmp-impl.h"
+# endif
+# ifdef MPFR_NEED_LONGLONG_H
+# include "longlong.h"
+# endif
+# ifndef __MPFR_H
+# include "mpfr.h"
+# endif
+
+#else /* Build without gmp internals */
+
+# ifndef __GMP_H__
+# include "gmp.h"
+# endif
+# ifndef __MPFR_H
+# include "mpfr.h"
+# endif
+# ifndef __GMPFR_GMP_H__
+# include "mpfr-gmp.h"
+# endif
+# ifdef MPFR_NEED_LONGLONG_H
+# define LONGLONG_STANDALONE
+# include "mpfr-longlong.h"
+# endif
+
+#endif
+#undef MPFR_NEED_LONGLONG_H
+
+/* If a mpn_sqr_n macro is not defined, use mpn_mul. GMP 4.x defines a
+ mpn_sqr_n macro in gmp-impl.h (and this macro disappeared in GMP 5),
+ so that GMP's macro can only be used when MPFR has been configured
+ with --with-gmp-build (and only with GMP 4.x). */
+#ifndef mpn_sqr_n
+# define mpn_sqr_n(dst,src,n) mpn_mul((dst),(src),(n),(src),(n))
+#endif
+
+/* For the definition of MPFR_THREAD_ATTR. GCC/ICC detection macros are
+ no longer used, as they sometimes gave incorrect information about
+ the support of thread-local variables. A configure check is now done.
+ If the use of detection macros is needed in the future, this could be
+ moved below (after the detection macros are defined). */
+#include "mpfr-thread.h"
+
+
+/******************************************************
+ ***************** Detection macros *******************
+ ******************************************************/
+
+/* Macros to detect STDC, GCC, GLIBC, GMP and ICC version */
+#if defined(__STDC_VERSION__)
+# define __MPFR_STDC(version) (__STDC_VERSION__>=(version))
+#elif defined(__STDC__)
+# define __MPFR_STDC(version) (0 == (version))
+#else
+# define __MPFR_STDC(version) 0
+#endif
+
+#if defined(_WIN32)
+/* Under MS Windows (e.g. with VS2008 or VS2010), Intel's compiler doesn't
+ support/enable extensions like the ones seen under GNU/Linux.
+ https://sympa.inria.fr/sympa/arc/mpfr/2011-02/msg00032.html */
+# define __MPFR_ICC(a,b,c) 0
+#elif defined(__ICC)
+# define __MPFR_ICC(a,b,c) (__ICC >= (a)*100+(b)*10+(c))
+#elif defined(__INTEL_COMPILER)
+# define __MPFR_ICC(a,b,c) (__INTEL_COMPILER >= (a)*100+(b)*10+(c))
+#else
+# define __MPFR_ICC(a,b,c) 0
+#endif
+
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && ! __MPFR_ICC(0,0,0)
+# define __MPFR_GNUC(a,i) \
+ (MPFR_VERSION_NUM(__GNUC__,__GNUC_MINOR__,0) >= MPFR_VERSION_NUM(a,i,0))
+#else
+# define __MPFR_GNUC(a,i) 0
+#endif
+
+#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+# define __MPFR_GLIBC(a,i) \
+ (MPFR_VERSION_NUM(__GLIBC__,__GLIBC_MINOR__,0) >= MPFR_VERSION_NUM(a,i,0))
+#else
+# define __MPFR_GLIBC(a,i) 0
+#endif
+
+#if defined(__GNU_MP_VERSION) && \
+ defined(__GNU_MP_VERSION_MINOR) && \
+ defined(__GNU_MP_VERSION_PATCHLEVEL)
+# define __MPFR_GMP(a,b,c) \
+ (MPFR_VERSION_NUM(__GNU_MP_VERSION,__GNU_MP_VERSION_MINOR,__GNU_MP_VERSION_PATCHLEVEL) >= MPFR_VERSION_NUM(a,b,c))
+#else
+# define __MPFR_GMP(a,b,c) 0
+#endif
+
+
+
+/******************************************************
+ ************* GMP Basic Pointer Types ****************
+ ******************************************************/
+
+typedef mp_limb_t *mpfr_limb_ptr;
+typedef __gmp_const mp_limb_t *mpfr_limb_srcptr;
+
+
+
+/******************************************************
+ ****************** (U)INTMAX_MAX *********************
+ ******************************************************/
+
+/* Let's try to fix UINTMAX_MAX and INTMAX_MAX if these macros don't work
+ (e.g. with gcc -ansi -pedantic-errors in 32-bit mode under GNU/Linux),
+ see <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582698>. */
+#ifdef _MPFR_H_HAVE_INTMAX_T
+# ifdef MPFR_HAVE_INTMAX_MAX
+# define MPFR_UINTMAX_MAX UINTMAX_MAX
+# define MPFR_INTMAX_MAX INTMAX_MAX
+# define MPFR_INTMAX_MIN INTMAX_MIN
+# else
+# define MPFR_UINTMAX_MAX ((uintmax_t) -1)
+# define MPFR_INTMAX_MAX ((intmax_t) (MPFR_UINTMAX_MAX >> 1))
+# define MPFR_INTMAX_MIN (INT_MIN + INT_MAX - MPFR_INTMAX_MAX)
+# endif
+#endif
+
+
+
+/******************************************************
+ ******************** Check GMP ***********************
+ ******************************************************/
+
+#if !__MPFR_GMP(4,1,0)
+# error "GMP 4.1.0 or newer needed"
+#endif
+
+#if GMP_NAIL_BITS != 0
+# error "MPFR doesn't support nonzero values of GMP_NAIL_BITS"
+#endif
+
+#if (GMP_NUMB_BITS<32) || (GMP_NUMB_BITS & (GMP_NUMB_BITS - 1))
+# error "GMP_NUMB_BITS must be a power of 2, and >= 32"
+#endif
+
+#if GMP_NUMB_BITS == 16
+# define MPFR_LOG2_GMP_NUMB_BITS 4
+#elif GMP_NUMB_BITS == 32
+# define MPFR_LOG2_GMP_NUMB_BITS 5
+#elif GMP_NUMB_BITS == 64
+# define MPFR_LOG2_GMP_NUMB_BITS 6
+#elif GMP_NUMB_BITS == 128
+# define MPFR_LOG2_GMP_NUMB_BITS 7
+#elif GMP_NUMB_BITS == 256
+# define MPFR_LOG2_GMP_NUMB_BITS 8
+#else
+# error "Can't compute log2(GMP_NUMB_BITS)"
+#endif
+
+#if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
+/* For the future: N1478: Supporting the 'noreturn' property in C1x
+ http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1478.htm */
+# define MPFR_NORETURN_ATTR __attribute__ ((noreturn))
+# define MPFR_CONST_ATTR __attribute__ ((const))
+#else
+# define MPFR_NORETURN_ATTR
+# define MPFR_CONST_ATTR
+#endif
+
+/******************************************************
+ ************* Global Internal Variables **************
+ ******************************************************/
+
+/* Cache struct */
+struct __gmpfr_cache_s {
+ mpfr_t x;
+ int inexact;
+ int (*func)(mpfr_ptr, mpfr_rnd_t);
+};
+typedef struct __gmpfr_cache_s mpfr_cache_t[1];
+typedef struct __gmpfr_cache_s *mpfr_cache_ptr;
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR unsigned int __gmpfr_flags;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emin;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emax;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_prec_t __gmpfr_default_fp_bit_precision;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_rnd_t __gmpfr_default_rounding_mode;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_euler;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_catalan;
+
+#ifndef MPFR_USE_LOGGING
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_pi;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_cache_const_log2;
+#else
+/* Two constants are used by the logging functions (via mpfr_fprintf,
+ then mpfr_log, for the base conversion): pi and log(2). Since the
+ mpfr_cache function isn't re-entrant when working on the same cache,
+ we need to define two caches for each constant. */
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_normal_pi;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_normal_log2;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_logging_pi;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_t __gmpfr_logging_log2;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_ptr __gmpfr_cache_const_pi;
+__MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_cache_ptr __gmpfr_cache_const_log2;
+#endif
+
+#define BASE_MAX 62
+__MPFR_DECLSPEC extern const __mpfr_struct __gmpfr_l2b[BASE_MAX-1][2];
+
+/* Note: do not use the following values when they can be outside the
+ current exponent range, e.g. when the exponent range has not been
+ extended yet; under such a condition, they can be used only in
+ mpfr_cmpabs. */
+__MPFR_DECLSPEC extern const mpfr_t __gmpfr_one;
+__MPFR_DECLSPEC extern const mpfr_t __gmpfr_two;
+__MPFR_DECLSPEC extern const mpfr_t __gmpfr_four;
+
+
+#if defined (__cplusplus)
+ }
+#endif
+
+/* Flags of __gmpfr_flags */
+#define MPFR_FLAGS_UNDERFLOW 1
+#define MPFR_FLAGS_OVERFLOW 2
+#define MPFR_FLAGS_NAN 4
+#define MPFR_FLAGS_INEXACT 8
+#define MPFR_FLAGS_ERANGE 16
+#define MPFR_FLAGS_DIVBY0 32
+#define MPFR_FLAGS_ALL 63
+
+/* Replace some common functions for direct access to the global vars */
+#define mpfr_get_emin() (__gmpfr_emin + 0)
+#define mpfr_get_emax() (__gmpfr_emax + 0)
+#define mpfr_get_default_rounding_mode() (__gmpfr_default_rounding_mode + 0)
+#define mpfr_get_default_prec() (__gmpfr_default_fp_bit_precision + 0)
+
+#define mpfr_clear_flags() \
+ ((void) (__gmpfr_flags = 0))
+#define mpfr_clear_underflow() \
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW))
+#define mpfr_clear_overflow() \
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW))
+#define mpfr_clear_nanflag() \
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN))
+#define mpfr_clear_inexflag() \
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT))
+#define mpfr_clear_erangeflag() \
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE))
+#define mpfr_clear_divby0() \
+ ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_DIVBY0))
+#define mpfr_underflow_p() \
+ ((int) (__gmpfr_flags & MPFR_FLAGS_UNDERFLOW))
+#define mpfr_overflow_p() \
+ ((int) (__gmpfr_flags & MPFR_FLAGS_OVERFLOW))
+#define mpfr_nanflag_p() \
+ ((int) (__gmpfr_flags & MPFR_FLAGS_NAN))
+#define mpfr_inexflag_p() \
+ ((int) (__gmpfr_flags & MPFR_FLAGS_INEXACT))
+#define mpfr_erangeflag_p() \
+ ((int) (__gmpfr_flags & MPFR_FLAGS_ERANGE))
+#define mpfr_divby0_p() \
+ ((int) (__gmpfr_flags & MPFR_FLAGS_DIVBY0))
+
+/* Testing an exception flag correctly is tricky. There are mainly two
+ pitfalls: First, one needs to remember to clear the corresponding
+ flag, in case it was set before the function call or during some
+ intermediate computations (in practice, one can clear all the flags).
+ Secondly, one needs to test the flag early enough, i.e. before it
+ can be modified by another function. Moreover, it is quite difficult
+ (if not impossible) to reliably check problems with "make check". To
+ avoid these pitfalls, it is recommended to use the following macros.
+ Other use of the exception-flag predicate functions/macros will be
+ detected by mpfrlint.
+ Note: _op can be either a statement or an expression.
+ MPFR_BLOCK_EXCEP should be used only inside a block; it is useful to
+ detect some exception in order to exit the block as soon as possible. */
+#define MPFR_BLOCK_DECL(_flags) unsigned int _flags
+/* The (void) (_flags) makes sure that _flags is read at least once (it
+ makes sense to use MPFR_BLOCK while _flags will never be read in the
+ source, so that we wish to avoid the corresponding warning). */
+#define MPFR_BLOCK(_flags,_op) \
+ do \
+ { \
+ mpfr_clear_flags (); \
+ _op; \
+ (_flags) = __gmpfr_flags; \
+ (void) (_flags); \
+ } \
+ while (0)
+#define MPFR_BLOCK_TEST(_flags,_f) MPFR_UNLIKELY ((_flags) & (_f))
+#define MPFR_BLOCK_EXCEP (__gmpfr_flags & (MPFR_FLAGS_UNDERFLOW | \
+ MPFR_FLAGS_OVERFLOW | \
+ MPFR_FLAGS_DIVBY0 | \
+ MPFR_FLAGS_NAN))
+/* Let's use a MPFR_ prefix, because e.g. OVERFLOW is defined by glibc's
+ math.h, though this is not a reserved identifier! */
+#define MPFR_UNDERFLOW(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_UNDERFLOW)
+#define MPFR_OVERFLOW(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_OVERFLOW)
+#define MPFR_NANFLAG(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_NAN)
+#define MPFR_INEXFLAG(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_INEXACT)
+#define MPFR_ERANGEFLAG(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_ERANGE)
+#define MPFR_DIVBY0(_flags) MPFR_BLOCK_TEST (_flags, MPFR_FLAGS_DIVBY0)
+
+
+/******************************************************
+ ******************** Assertions **********************
+ ******************************************************/
+
+/* Compile with -DWANT_ASSERT to check all assert statements */
+
+/* Note: do not use GMP macros ASSERT_ALWAYS and ASSERT as they are not
+ expressions, and as a consequence, they cannot be used in a for(),
+ with a comma operator and so on. */
+
+/* MPFR_ASSERTN(expr): assertions that should always be checked */
+#define MPFR_ASSERTN(expr) \
+ ((void) ((MPFR_UNLIKELY(expr)) || MPFR_UNLIKELY( (ASSERT_FAIL(expr),0) )))
+
+/* MPFR_ASSERTD(expr): assertions that should be checked when testing */
+#ifdef WANT_ASSERT
+# define MPFR_EXP_CHECK 1
+# define MPFR_ASSERTD(expr) MPFR_ASSERTN (expr)
+#else
+# define MPFR_ASSERTD(expr) ((void) 0)
+#endif
+
+/* Code to deal with impossible
+ WARNING: It doesn't use do { } while (0) for Insure++*/
+#define MPFR_RET_NEVER_GO_HERE() {MPFR_ASSERTN(0); return 0;}
+
+
+/******************************************************
+ ******************** Warnings ************************
+ ******************************************************/
+
+/* MPFR_WARNING is no longer useful, but let's keep the macro in case
+ it needs to be used again in the future. */
+
+#ifdef MPFR_USE_WARNINGS
+# include <stdlib.h>
+# define MPFR_WARNING(W) \
+ do \
+ { \
+ char *q = getenv ("MPFR_QUIET"); \
+ if (q == NULL || *q == 0) \
+ fprintf (stderr, "MPFR: %s\n", W); \
+ } \
+ while (0)
+#else
+# define MPFR_WARNING(W) ((void) 0)
+#endif
+
+
+/******************************************************
+ ****************** double macros *********************
+ ******************************************************/
+
+/* Precision used for lower precision computations */
+#define MPFR_SMALL_PRECISION 32
+
+/* Definition of constants */
+#define LOG2 0.69314718055994528622 /* log(2) rounded to zero on 53 bits */
+#define ALPHA 4.3191365662914471407 /* a+2 = a*log(a), rounded to +infinity */
+#define EXPM1 0.36787944117144227851 /* exp(-1), rounded to zero */
+
+/* MPFR_DOUBLE_SPEC = 1 if the C type 'double' corresponds to IEEE-754
+ double precision, 0 if it doesn't, and undefined if one doesn't know.
+ On all the tested machines, MPFR_DOUBLE_SPEC = 1. To have this macro
+ defined here, #include <float.h> is needed. If need be, other values
+ could be defined for other specs (once they are known). */
+#if !defined(MPFR_DOUBLE_SPEC) && defined(FLT_RADIX) && \
+ defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP) && defined(DBL_MAX_EXP)
+# if FLT_RADIX == 2 && DBL_MANT_DIG == 53 && \
+ DBL_MIN_EXP == -1021 && DBL_MAX_EXP == 1024
+# define MPFR_DOUBLE_SPEC 1
+# else
+# define MPFR_DOUBLE_SPEC 0
+# endif
+#endif
+
+/* Debug non IEEE floats */
+#ifdef XDEBUG
+# undef _GMP_IEEE_FLOATS
+#endif
+#ifndef _GMP_IEEE_FLOATS
+# define _GMP_IEEE_FLOATS 0
+#endif
+
+#ifndef IEEE_DBL_MANT_DIG
+#define IEEE_DBL_MANT_DIG 53
+#endif
+#define MPFR_LIMBS_PER_DOUBLE ((IEEE_DBL_MANT_DIG-1)/GMP_NUMB_BITS+1)
+
+#ifndef IEEE_FLT_MANT_DIG
+#define IEEE_FLT_MANT_DIG 24
+#endif
+#define MPFR_LIMBS_PER_FLT ((IEEE_FLT_MANT_DIG-1)/GMP_NUMB_BITS+1)
+
+/* Visual C++ doesn't support +1.0/0.0, -1.0/0.0 and 0.0/0.0
+ at compile time. */
+#if defined(_MSC_VER) && defined(_WIN32) && (_MSC_VER >= 1200)
+static double double_zero = 0.0;
+# define DBL_NAN (double_zero/double_zero)
+# define DBL_POS_INF ((double) 1.0/double_zero)
+# define DBL_NEG_INF ((double)-1.0/double_zero)
+# define DBL_NEG_ZERO (-double_zero)
+#else
+# define DBL_POS_INF ((double) 1.0/0.0)
+# define DBL_NEG_INF ((double)-1.0/0.0)
+# define DBL_NAN ((double) 0.0/0.0)
+# define DBL_NEG_ZERO (-0.0)
+#endif
+
+/* Note: In the past, there was specific code for _GMP_IEEE_FLOATS, which
+ was based on NaN and Inf memory representations. This code was breaking
+ the aliasing rules (see ISO C99, 6.5#6 and 6.5#7 on the effective type)
+ and for this reason it did not behave correctly with GCC 4.5.0 20091119.
+ The code needed a memory transfer and was probably not better than the
+ macros below with a good compiler (a fix based on the NaN / Inf memory
+ representation would be even worse due to C limitations), and this code
+ could be selected only when MPFR was built with --with-gmp-build, thus
+ introducing a difference (bad for maintaining/testing MPFR); therefore
+ it has been removed. The old code required that the argument x be an
+ lvalue of type double. We still require that, in case one would need
+ to change the macros below, e.g. for some broken compiler. But the
+ LVALUE(x) condition could be removed if really necessary. */
+/* Below, the &(x) == &(x) || &(x) != &(x) allows to make sure that x
+ is a lvalue without (probably) any warning from the compiler. The
+ &(x) != &(x) is needed to avoid a failure under Mac OS X 10.4.11
+ (with Xcode 2.4.1, i.e. the latest one). */
+#define LVALUE(x) (&(x) == &(x) || &(x) != &(x))
+#define DOUBLE_ISINF(x) (LVALUE(x) && ((x) > DBL_MAX || (x) < -DBL_MAX))
+#ifdef MPFR_NANISNAN
+/* Avoid MIPSpro / IRIX64 / gcc -ffast-math (incorrect) optimizations.
+ The + must not be replaced by a ||. With gcc -ffast-math, NaN is
+ regarded as a positive number or something like that; the second
+ test catches this case. */
+# define DOUBLE_ISNAN(x) \
+ (LVALUE(x) && !((((x) >= 0.0) + ((x) <= 0.0)) && -(x)*(x) <= 0.0))
+#else
+# define DOUBLE_ISNAN(x) (LVALUE(x) && (x) != (x))
+#endif
+
+/******************************************************
+ *************** Long double macros *******************
+ ******************************************************/
+
+/* We try to get the exact value of the precision of long double
+ (provided by the implementation) in order to provide correct
+ rounding in this case (not guaranteed if the C implementation
+ does not have an adequate long double arithmetic). Note that
+ it may be lower than the precision of some numbers that can
+ be represented in a long double; e.g. on FreeBSD/x86, it is
+ 53 because the processor is configured to round in double
+ precision (even when using the long double type -- this is a
+ limitation of the x87 arithmetic), and on Mac OS X, it is 106
+ because the implementation is a double-double arithmetic.
+ Otherwise (e.g. in base 10), we get an upper bound of the
+ precision, and correct rounding isn't currently provided.
+*/
+#if defined(LDBL_MANT_DIG) && FLT_RADIX == 2
+# define MPFR_LDBL_MANT_DIG LDBL_MANT_DIG
+#else
+# define MPFR_LDBL_MANT_DIG \
+ (sizeof(long double)*GMP_NUMB_BITS/sizeof(mp_limb_t))
+#endif
+#define MPFR_LIMBS_PER_LONG_DOUBLE \
+ ((sizeof(long double)-1)/sizeof(mp_limb_t)+1)
+
+/* LONGDOUBLE_NAN_ACTION executes the code "action" if x is a NaN. */
+
+/* On hppa2.0n-hp-hpux10 with the unbundled HP cc, the test x!=x on a NaN
+ has been seen false, meaning NaNs are not detected. This seemed to
+ happen only after other comparisons, not sure what's really going on. In
+ any case we can pick apart the bytes to identify a NaN. */
+#ifdef HAVE_LDOUBLE_IEEE_QUAD_BIG
+# define LONGDOUBLE_NAN_ACTION(x, action) \
+ do { \
+ union { \
+ long double ld; \
+ struct { \
+ unsigned int sign : 1; \
+ unsigned int exp : 15; \
+ unsigned int man3 : 16; \
+ unsigned int man2 : 32; \
+ unsigned int man1 : 32; \
+ unsigned int man0 : 32; \
+ } s; \
+ } u; \
+ u.ld = (x); \
+ if (u.s.exp == 0x7FFFL \
+ && (u.s.man0 | u.s.man1 | u.s.man2 | u.s.man3) != 0) \
+ { action; } \
+ } while (0)
+#endif
+
+#ifdef HAVE_LDOUBLE_IEEE_QUAD_LITTLE
+# define LONGDOUBLE_NAN_ACTION(x, action) \
+ do { \
+ union { \
+ long double ld; \
+ struct { \
+ unsigned int man0 : 32; \
+ unsigned int man1 : 32; \
+ unsigned int man2 : 32; \
+ unsigned int man3 : 16; \
+ unsigned int exp : 15; \
+ unsigned int sign : 1; \
+ } s; \
+ } u; \
+ u.ld = (x); \
+ if (u.s.exp == 0x7FFFL \
+ && (u.s.man0 | u.s.man1 | u.s.man2 | u.s.man3) != 0) \
+ { action; } \
+ } while (0)
+#endif
+
+/* Under IEEE rules, NaN is not equal to anything, including itself.
+ "volatile" here stops "cc" on mips64-sgi-irix6.5 from optimizing away
+ x!=x. */
+#ifndef LONGDOUBLE_NAN_ACTION
+# define LONGDOUBLE_NAN_ACTION(x, action) \
+ do { \
+ volatile long double __x = LONGDOUBLE_VOLATILE (x); \
+ if ((x) != __x) \
+ { action; } \
+ } while (0)
+# define WANT_LONGDOUBLE_VOLATILE 1
+#endif
+
+/* If we don't have a proper "volatile" then volatile is #defined to empty,
+ in this case call through an external function to stop the compiler
+ optimizing anything. */
+#ifdef WANT_LONGDOUBLE_VOLATILE
+# ifdef volatile
+__MPFR_DECLSPEC long double __gmpfr_longdouble_volatile _MPFR_PROTO ((long double)) MPFR_CONST_ATTR;
+# define LONGDOUBLE_VOLATILE(x) (__gmpfr_longdouble_volatile (x))
+# define WANT_GMPFR_LONGDOUBLE_VOLATILE 1
+# else
+# define LONGDOUBLE_VOLATILE(x) (x)
+# endif
+#endif
+
+/* Some special case for IEEE_EXT Litle Endian */
+#if HAVE_LDOUBLE_IEEE_EXT_LITTLE
+
+typedef union {
+ long double ld;
+ struct {
+ unsigned int manl : 32;
+ unsigned int manh : 32;
+ unsigned int expl : 8 ;
+ unsigned int exph : 7;
+ unsigned int sign : 1;
+ } s;
+} mpfr_long_double_t;
+
+/* #undef MPFR_LDBL_MANT_DIG */
+#undef MPFR_LIMBS_PER_LONG_DOUBLE
+/* #define MPFR_LDBL_MANT_DIG 64 */
+#define MPFR_LIMBS_PER_LONG_DOUBLE ((64-1)/GMP_NUMB_BITS+1)
+
+#endif
+
+/******************************************************
+ *************** _Decimal64 support *******************
+ ******************************************************/
+
+#ifdef MPFR_WANT_DECIMAL_FLOATS
+/* to cast between binary64 and decimal64 */
+union ieee_double_decimal64 { double d; _Decimal64 d64; };
+#endif
+
+/******************************************************
+ **************** mpfr_t properties *******************
+ ******************************************************/
+
+/* In the following macro, p is usually a mpfr_prec_t, but this macro
+ works with other integer types (without integer overflow). Checking
+ that p >= 1 in debug mode is useful here because this macro can be
+ used on a computed precision (in particular, this formula does not
+ work for a degenerate case p = 0, and could give different results
+ on different platforms). But let us not use an assertion checking
+ in the MPFR_LAST_LIMB() and MPFR_LIMB_SIZE() macros below to avoid
+ too much expansion for assertions (in practice, this should be a
+ problem just when testing MPFR with the --enable-assert configure
+ option and the -ansi -pedantic-errors gcc compiler flags). */
+#define MPFR_PREC2LIMBS(p) \
+ (MPFR_ASSERTD ((p) >= 1), ((p) - 1) / GMP_NUMB_BITS + 1)
+
+#define MPFR_PREC(x) ((x)->_mpfr_prec)
+#define MPFR_EXP(x) ((x)->_mpfr_exp)
+#define MPFR_MANT(x) ((x)->_mpfr_d)
+#define MPFR_LAST_LIMB(x) ((MPFR_PREC (x) - 1) / GMP_NUMB_BITS)
+#define MPFR_LIMB_SIZE(x) (MPFR_LAST_LIMB (x) + 1)
+
+
+/******************************************************
+ **************** exponent properties *****************
+ ******************************************************/
+
+/* Limits of the mpfr_exp_t type (NOT those of valid exponent values).
+ These macros can be used in preprocessor directives. */
+#if _MPFR_EXP_FORMAT == 1
+# define MPFR_EXP_MAX (SHRT_MAX)
+# define MPFR_EXP_MIN (SHRT_MIN)
+#elif _MPFR_EXP_FORMAT == 2
+# define MPFR_EXP_MAX (INT_MAX)
+# define MPFR_EXP_MIN (INT_MIN)
+#elif _MPFR_EXP_FORMAT == 3
+# define MPFR_EXP_MAX (LONG_MAX)
+# define MPFR_EXP_MIN (LONG_MIN)
+#elif _MPFR_EXP_FORMAT == 4
+# define MPFR_EXP_MAX (MPFR_INTMAX_MAX)
+# define MPFR_EXP_MIN (MPFR_INTMAX_MIN)
+#else
+# error "Invalid MPFR Exp format"
+#endif
+
+/* Before doing a cast to mpfr_uexp_t, make sure that the value is
+ nonnegative. */
+#define MPFR_UEXP(X) (MPFR_ASSERTD ((X) >= 0), (mpfr_uexp_t) (X))
+
+#if MPFR_EXP_MIN >= LONG_MIN && MPFR_EXP_MAX <= LONG_MAX
+typedef long int mpfr_eexp_t;
+# define mpfr_get_exp_t(x,r) mpfr_get_si((x),(r))
+# define mpfr_set_exp_t(x,e,r) mpfr_set_si((x),(e),(r))
+# define MPFR_EXP_FSPEC "l"
+#elif defined (_MPFR_H_HAVE_INTMAX_T)
+typedef intmax_t mpfr_eexp_t;
+# define mpfr_get_exp_t(x,r) mpfr_get_sj((x),(r))
+# define mpfr_set_exp_t(x,e,r) mpfr_set_sj((x),(e),(r))
+# define MPFR_EXP_FSPEC "j"
+#else
+# error "Cannot define mpfr_get_exp_t and mpfr_set_exp_t"
+#endif
+
+/* Invalid exponent value (to track bugs...) */
+#define MPFR_EXP_INVALID \
+ ((mpfr_exp_t) 1 << (GMP_NUMB_BITS*sizeof(mpfr_exp_t)/sizeof(mp_limb_t)-2))
+
+/* Definition of the exponent limits for MPFR numbers.
+ * These limits are chosen so that if e is such an exponent, then 2e-1 and
+ * 2e+1 are representable. This is useful for intermediate computations,
+ * in particular the multiplication.
+ */
+#undef MPFR_EMIN_MIN
+#undef MPFR_EMIN_MAX
+#undef MPFR_EMAX_MIN
+#undef MPFR_EMAX_MAX
+#define MPFR_EMIN_MIN (1-MPFR_EXP_INVALID)
+#define MPFR_EMIN_MAX (MPFR_EXP_INVALID-1)
+#define MPFR_EMAX_MIN (1-MPFR_EXP_INVALID)
+#define MPFR_EMAX_MAX (MPFR_EXP_INVALID-1)
+
+/* Use MPFR_GET_EXP and MPFR_SET_EXP instead of MPFR_EXP directly,
+ unless when the exponent may be out-of-range, for instance when
+ setting the exponent before calling mpfr_check_range.
+ MPFR_EXP_CHECK is defined when WANT_ASSERT is defined, but if you
+ don't use WANT_ASSERT (for speed reasons), you can still define
+ MPFR_EXP_CHECK by setting -DMPFR_EXP_CHECK in $CFLAGS. */
+
+#ifdef MPFR_EXP_CHECK
+# define MPFR_GET_EXP(x) (mpfr_get_exp) (x)
+# define MPFR_SET_EXP(x, exp) MPFR_ASSERTN (!mpfr_set_exp ((x), (exp)))
+# define MPFR_SET_INVALID_EXP(x) ((void) (MPFR_EXP (x) = MPFR_EXP_INVALID))
+#else
+# define MPFR_GET_EXP(x) MPFR_EXP (x)
+# define MPFR_SET_EXP(x, exp) ((void) (MPFR_EXP (x) = (exp)))
+# define MPFR_SET_INVALID_EXP(x) ((void) 0)
+#endif
+
+
+
+/******************************************************
+ ********** Singular Values (NAN, INF, ZERO) **********
+ ******************************************************/
+
+/* Enum special value of exponent. */
+# define MPFR_EXP_ZERO (MPFR_EXP_MIN+1)
+# define MPFR_EXP_NAN (MPFR_EXP_MIN+2)
+# define MPFR_EXP_INF (MPFR_EXP_MIN+3)
+
+#define MPFR_IS_NAN(x) (MPFR_EXP(x) == MPFR_EXP_NAN)
+#define MPFR_SET_NAN(x) (MPFR_EXP(x) = MPFR_EXP_NAN)
+#define MPFR_IS_INF(x) (MPFR_EXP(x) == MPFR_EXP_INF)
+#define MPFR_SET_INF(x) (MPFR_EXP(x) = MPFR_EXP_INF)
+#define MPFR_IS_ZERO(x) (MPFR_EXP(x) == MPFR_EXP_ZERO)
+#define MPFR_SET_ZERO(x) (MPFR_EXP(x) = MPFR_EXP_ZERO)
+#define MPFR_NOTZERO(x) (MPFR_EXP(x) != MPFR_EXP_ZERO)
+
+#define MPFR_IS_FP(x) (!MPFR_IS_NAN(x) && !MPFR_IS_INF(x))
+#define MPFR_IS_SINGULAR(x) (MPFR_EXP(x) <= MPFR_EXP_INF)
+#define MPFR_IS_PURE_FP(x) (!MPFR_IS_SINGULAR(x) && \
+ (MPFR_ASSERTD ((MPFR_MANT(x)[MPFR_LAST_LIMB(x)] \
+ & MPFR_LIMB_HIGHBIT) != 0), 1))
+
+#define MPFR_ARE_SINGULAR(x,y) \
+ (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)) || MPFR_UNLIKELY(MPFR_IS_SINGULAR(y)))
+
+#define MPFR_IS_POWER_OF_2(x) \
+ (mpfr_cmp_ui_2exp ((x), 1, MPFR_GET_EXP (x) - 1) == 0)
+
+
+/******************************************************
+ ********************* Sign Macros ********************
+ ******************************************************/
+
+#define MPFR_SIGN_POS (1)
+#define MPFR_SIGN_NEG (-1)
+
+#define MPFR_IS_STRICTPOS(x) (MPFR_NOTZERO((x)) && MPFR_SIGN(x) > 0)
+#define MPFR_IS_STRICTNEG(x) (MPFR_NOTZERO((x)) && MPFR_SIGN(x) < 0)
+
+#define MPFR_IS_NEG(x) (MPFR_SIGN(x) < 0)
+#define MPFR_IS_POS(x) (MPFR_SIGN(x) > 0)
+
+#define MPFR_SET_POS(x) (MPFR_SIGN(x) = MPFR_SIGN_POS)
+#define MPFR_SET_NEG(x) (MPFR_SIGN(x) = MPFR_SIGN_NEG)
+
+#define MPFR_CHANGE_SIGN(x) (MPFR_SIGN(x) = -MPFR_SIGN(x))
+#define MPFR_SET_SAME_SIGN(x, y) (MPFR_SIGN(x) = MPFR_SIGN(y))
+#define MPFR_SET_OPPOSITE_SIGN(x, y) (MPFR_SIGN(x) = -MPFR_SIGN(y))
+#define MPFR_ASSERT_SIGN(s) \
+ (MPFR_ASSERTD((s) == MPFR_SIGN_POS || (s) == MPFR_SIGN_NEG))
+#define MPFR_SET_SIGN(x, s) \
+ (MPFR_ASSERT_SIGN(s), MPFR_SIGN(x) = s)
+#define MPFR_IS_POS_SIGN(s1) (s1 > 0)
+#define MPFR_IS_NEG_SIGN(s1) (s1 < 0)
+#define MPFR_MULT_SIGN(s1, s2) ((s1) * (s2))
+/* Transform a sign to 1 or -1 */
+#define MPFR_FROM_SIGN_TO_INT(s) (s)
+#define MPFR_INT_SIGN(x) MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(x))
+
+
+
+/******************************************************
+ ***************** Ternary Value Macros ***************
+ ******************************************************/
+
+/* Special inexact value */
+#define MPFR_EVEN_INEX 2
+
+/* Macros for functions returning two inexact values in an 'int' */
+#define INEXPOS(y) ((y) == 0 ? 0 : (((y) > 0) ? 1 : 2))
+#define INEX(y,z) (INEXPOS(y) | (INEXPOS(z) << 2))
+
+/* When returning the ternary inexact value, ALWAYS use one of the
+ following two macros, unless the flag comes from another function
+ returning the ternary inexact value */
+#define MPFR_RET(I) return \
+ (I) ? ((__gmpfr_flags |= MPFR_FLAGS_INEXACT), (I)) : 0
+#define MPFR_RET_NAN return (__gmpfr_flags |= MPFR_FLAGS_NAN), 0
+
+#define MPFR_SET_ERANGE() (__gmpfr_flags |= MPFR_FLAGS_ERANGE)
+
+#define SIGN(I) ((I) < 0 ? -1 : (I) > 0)
+#define SAME_SIGN(I1,I2) (SIGN (I1) == SIGN (I2))
+
+
+
+/******************************************************
+ ************** Rounding mode macros *****************
+ ******************************************************/
+
+/* MPFR_RND_MAX gives the number of supported rounding modes by all functions.
+ * Once faithful rounding is implemented, MPFR_RNDA should be changed
+ * to MPFR_RNDF. But this will also require more changes in the tests.
+ */
+#define MPFR_RND_MAX ((mpfr_rnd_t)((MPFR_RNDA)+1))
+
+/* We want to test this :
+ * (rnd == MPFR_RNDU && test) || (rnd == RNDD && !test)
+ * ie it transforms RNDU or RNDD to Away or Zero according to the sign */
+#define MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd, test) \
+ (((rnd) + (test)) == MPFR_RNDD)
+
+/* We want to test if rnd = Zero, or Away.
+ 'test' is 1 if negative, and 0 if positive. */
+#define MPFR_IS_LIKE_RNDZ(rnd, test) \
+ ((rnd==MPFR_RNDZ) || MPFR_IS_RNDUTEST_OR_RNDDNOTTEST (rnd, test))
+
+#define MPFR_IS_LIKE_RNDU(rnd, sign) \
+ ((rnd==MPFR_RNDU) || (rnd==MPFR_RNDZ && sign<0) || (rnd==MPFR_RNDA && sign>0))
+
+#define MPFR_IS_LIKE_RNDD(rnd, sign) \
+ ((rnd==MPFR_RNDD) || (rnd==MPFR_RNDZ && sign>0) || (rnd==MPFR_RNDA && sign<0))
+
+/* Invert a rounding mode, RNDZ and RNDA are unchanged */
+#define MPFR_INVERT_RND(rnd) ((rnd == MPFR_RNDU) ? MPFR_RNDD : \
+ ((rnd == MPFR_RNDD) ? MPFR_RNDU : rnd))
+
+/* Transform RNDU and RNDD to RNDZ according to test */
+#define MPFR_UPDATE_RND_MODE(rnd, test) \
+ do { \
+ if (MPFR_UNLIKELY(MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd, test))) \
+ rnd = MPFR_RNDZ; \
+ } while (0)
+
+/* Transform RNDU and RNDD to RNDZ or RNDA according to sign,
+ leave the other modes unchanged */
+#define MPFR_UPDATE2_RND_MODE(rnd, sign) \
+ do { \
+ if (rnd == MPFR_RNDU) \
+ rnd = (sign > 0) ? MPFR_RNDA : MPFR_RNDZ; \
+ else if (rnd == MPFR_RNDD) \
+ rnd = (sign < 0) ? MPFR_RNDA : MPFR_RNDZ; \
+ } while (0)
+
+
+/******************************************************
+ ******************* Limb Macros **********************
+ ******************************************************/
+
+ /* Definition of MPFR_LIMB_HIGHBIT */
+#if defined(GMP_LIMB_HIGHBIT)
+# define MPFR_LIMB_HIGHBIT GMP_LIMB_HIGHBIT
+#elif defined(MP_LIMB_T_HIGHBIT)
+# define MPFR_LIMB_HIGHBIT MP_LIMB_T_HIGHBIT
+#else
+# error "Neither GMP_LIMB_HIGHBIT nor MP_LIMB_T_HIGHBIT defined in GMP"
+#endif
+
+/* Mask to get the Most Significant Bit of a limb */
+#define MPFR_LIMB_MSB(l) ((l)&MPFR_LIMB_HIGHBIT)
+
+/* Definition of MPFR_LIMB_ONE & MPFR_LIMB_ZERO */
+#ifdef CNST_LIMB
+# define MPFR_LIMB_ONE CNST_LIMB(1)
+# define MPFR_LIMB_ZERO CNST_LIMB(0)
+#else
+# define MPFR_LIMB_ONE ((mp_limb_t) 1L)
+# define MPFR_LIMB_ZERO ((mp_limb_t) 0L)
+#endif
+
+/* Mask for the low 's' bits of a limb */
+#define MPFR_LIMB_MASK(s) ((MPFR_LIMB_ONE<<(s))-MPFR_LIMB_ONE)
+
+
+
+/******************************************************
+ ********************** Memory ************************
+ ******************************************************/
+
+/* Heap Memory gestion */
+typedef union { mp_size_t s; mp_limb_t l; } mpfr_size_limb_t;
+#define MPFR_GET_ALLOC_SIZE(x) \
+ ( ((mp_size_t*) MPFR_MANT(x))[-1] + 0)
+#define MPFR_SET_ALLOC_SIZE(x, n) \
+ ( ((mp_size_t*) MPFR_MANT(x))[-1] = n)
+#define MPFR_MALLOC_SIZE(s) \
+ ( sizeof(mpfr_size_limb_t) + BYTES_PER_MP_LIMB * ((size_t) s) )
+#define MPFR_SET_MANT_PTR(x,p) \
+ (MPFR_MANT(x) = (mp_limb_t*) ((mpfr_size_limb_t*) p + 1))
+#define MPFR_GET_REAL_PTR(x) \
+ ((mp_limb_t*) ((mpfr_size_limb_t*) MPFR_MANT(x) - 1))
+
+/* Temporary memory gestion */
+#ifndef TMP_SALLOC
+/* GMP 4.1.x or below or internals */
+#define MPFR_TMP_DECL TMP_DECL
+#define MPFR_TMP_MARK TMP_MARK
+#define MPFR_TMP_ALLOC TMP_ALLOC
+#define MPFR_TMP_FREE TMP_FREE
+#else
+#define MPFR_TMP_DECL(x) TMP_DECL
+#define MPFR_TMP_MARK(x) TMP_MARK
+#define MPFR_TMP_ALLOC(s) TMP_ALLOC(s)
+#define MPFR_TMP_FREE(x) TMP_FREE
+#endif
+
+/* This code is experimental: don't use it */
+#ifdef MPFR_USE_OWN_MPFR_TMP_ALLOC
+extern unsigned char *mpfr_stack;
+#undef MPFR_TMP_DECL
+#undef MPFR_TMP_MARK
+#undef MPFR_TMP_ALLOC
+#undef MPFR_TMP_FREE
+#define MPFR_TMP_DECL(_x) unsigned char *(_x)
+#define MPFR_TMP_MARK(_x) ((_x) = mpfr_stack)
+#define MPFR_TMP_ALLOC(_s) (mpfr_stack += (_s), mpfr_stack - (_s))
+#define MPFR_TMP_FREE(_x) (mpfr_stack = (_x))
+#endif
+
+#define MPFR_TMP_LIMBS_ALLOC(N) \
+ ((mp_limb_t *) MPFR_TMP_ALLOC ((size_t) (N) * BYTES_PER_MP_LIMB))
+
+/* temporary allocate 1 limb at xp, and initialize mpfr variable x */
+/* The temporary var doesn't have any size field, but it doesn't matter
+ * since only functions dealing with the Heap care about it */
+#define MPFR_TMP_INIT1(xp, x, p) \
+ ( MPFR_PREC(x) = (p), \
+ MPFR_MANT(x) = (xp), \
+ MPFR_SET_POS(x), \
+ MPFR_SET_INVALID_EXP(x))
+
+#define MPFR_TMP_INIT(xp, x, p, s) \
+ (xp = MPFR_TMP_LIMBS_ALLOC(s), \
+ MPFR_TMP_INIT1(xp, x, p))
+
+#define MPFR_TMP_INIT_ABS(d, s) \
+ ( MPFR_PREC(d) = MPFR_PREC(s), \
+ MPFR_MANT(d) = MPFR_MANT(s), \
+ MPFR_SET_POS(d), \
+ MPFR_EXP(d) = MPFR_EXP(s))
+
+
+
+/******************************************************
+ ***************** Cache macros **********************
+ ******************************************************/
+
+#define mpfr_const_pi(_d,_r) mpfr_cache(_d, __gmpfr_cache_const_pi,_r)
+#define mpfr_const_log2(_d,_r) mpfr_cache(_d, __gmpfr_cache_const_log2, _r)
+#define mpfr_const_euler(_d,_r) mpfr_cache(_d, __gmpfr_cache_const_euler, _r)
+#define mpfr_const_catalan(_d,_r) mpfr_cache(_d,__gmpfr_cache_const_catalan,_r)
+
+#define MPFR_DECL_INIT_CACHE(_cache,_func) \
+ mpfr_cache_t MPFR_THREAD_ATTR _cache = \
+ {{{{0,MPFR_SIGN_POS,0,(mp_limb_t*)0}},0,_func}}
+
+
+
+/******************************************************
+ ******************* Threshold ***********************
+ ******************************************************/
+
+#include "mparam.h"
+
+/******************************************************
+ ***************** Useful macros *********************
+ ******************************************************/
+
+/* Theses macros help the compiler to determine if a test is
+ likely or unlikely. The !! is necessary in case x is larger
+ than a long. */
+#if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
+# define MPFR_LIKELY(x) (__builtin_expect(!!(x),1))
+# define MPFR_UNLIKELY(x) (__builtin_expect(!!(x),0))
+#else
+# define MPFR_LIKELY(x) (x)
+# define MPFR_UNLIKELY(x) (x)
+#endif
+
+/* Declare that some variable is initialized before being used (without a
+ dummy initialization) in order to avoid some compiler warnings. Use the
+ VAR = VAR trick (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36296)
+ only with gcc as this is undefined behavior, and we don't know what
+ other compilers do (they may also be smarter). This trick could be
+ disabled with future gcc versions. */
+#if defined(__GNUC__)
+# define INITIALIZED(VAR) VAR = VAR
+#else
+# define INITIALIZED(VAR) VAR
+#endif
+
+/* Ceil log 2: If GCC, uses a GCC extension, otherwise calls a function */
+/* Warning:
+ * Needs to define MPFR_NEED_LONGLONG.
+ * Computes ceil(log2(x)) only for x integer (unsigned long)
+ * Undefined if x is 0 */
+#if __MPFR_GNUC(2,95) || __MPFR_ICC(8,1,0)
+# define MPFR_INT_CEIL_LOG2(x) \
+ (MPFR_UNLIKELY ((x) == 1) ? 0 : \
+ __extension__ ({ int _b; mp_limb_t _limb; \
+ MPFR_ASSERTN ((x) > 1); \
+ _limb = (x) - 1; \
+ MPFR_ASSERTN (_limb == (x) - 1); \
+ count_leading_zeros (_b, _limb); \
+ (GMP_NUMB_BITS - _b); }))
+#else
+# define MPFR_INT_CEIL_LOG2(x) (__gmpfr_int_ceil_log2(x))
+#endif
+
+/* Add two integers with overflow handling */
+/* Example: MPFR_SADD_OVERFLOW (c, a, b, long, unsigned long,
+ * LONG_MIN, LONG_MAX,
+ * goto overflow, goto underflow); */
+#define MPFR_UADD_OVERFLOW(c,a,b,ACTION_IF_OVERFLOW) \
+ do { \
+ (c) = (a) + (b); \
+ if ((c) < (a)) ACTION_IF_OVERFLOW; \
+ } while (0)
+
+#define MPFR_SADD_OVERFLOW(c,a,b,STYPE,UTYPE,MIN,MAX,ACTION_IF_POS_OVERFLOW,ACTION_IF_NEG_OVERFLOW) \
+ do { \
+ if ((a) >= 0 && (b) >= 0) { \
+ UTYPE uc,ua,ub; \
+ ua = (UTYPE) (a); ub = (UTYPE) (b); \
+ MPFR_UADD_OVERFLOW (uc, ua, ub, ACTION_IF_POS_OVERFLOW); \
+ if (uc > (UTYPE)(MAX)) ACTION_IF_POS_OVERFLOW; \
+ else (c) = (STYPE) uc; \
+ } else if ((a) < 0 && (b) < 0) { \
+ UTYPE uc,ua,ub; \
+ ua = -(UTYPE) (a); ub = -(UTYPE) (b); \
+ MPFR_UADD_OVERFLOW (uc, ua, ub, ACTION_IF_NEG_OVERFLOW); \
+ if (uc >= -(UTYPE)(MIN) || uc > (UTYPE)(MAX)) { \
+ if (uc == -(UTYPE)(MIN)) (c) = (MIN); \
+ else ACTION_IF_NEG_OVERFLOW; } \
+ else (c) = -(STYPE) uc; \
+ } else (c) = (a) + (b); \
+ } while (0)
+
+
+/* Set a number to 1 (Fast) - It doesn't check if 1 is in the exponent range */
+#define MPFR_SET_ONE(x) \
+do { \
+ mp_size_t _size = MPFR_LAST_LIMB(x); \
+ MPFR_SET_POS(x); \
+ MPFR_EXP(x) = 1; \
+ MPN_ZERO ( MPFR_MANT(x), _size); \
+ MPFR_MANT(x)[_size] = MPFR_LIMB_HIGHBIT; \
+} while (0)
+
+/* Compute s = (-a) % GMP_NUMB_BITS as unsigned */
+#define MPFR_UNSIGNED_MINUS_MODULO(s, a) \
+ do \
+ { \
+ if (IS_POW2 (GMP_NUMB_BITS)) \
+ (s) = (- (unsigned int) (a)) % GMP_NUMB_BITS; \
+ else \
+ { \
+ (s) = (a) % GMP_NUMB_BITS; \
+ if ((s) != 0) \
+ (s) = GMP_NUMB_BITS - (s); \
+ } \
+ MPFR_ASSERTD ((s) >= 0 && (s) < GMP_NUMB_BITS); \
+ } \
+ while (0)
+
+/* Use it only for debug reasons */
+/* MPFR_TRACE (operation) : execute operation iff DEBUG flag is set */
+/* MPFR_DUMP (x) : print x (a mpfr_t) on stdout */
+#ifdef DEBUG
+# define MPFR_TRACE(x) x
+#else
+# define MPFR_TRACE(x) (void) 0
+#endif
+#define MPFR_DUMP(x) ( printf(#x"="), mpfr_dump(x) )
+
+/* Test if X (positive) is a power of 2 */
+#define IS_POW2(X) (((X) & ((X) - 1)) == 0)
+#define NOT_POW2(X) (((X) & ((X) - 1)) != 0)
+
+/* Safe absolute value (to avoid possible integer overflow) */
+/* type is the target (unsigned) type */
+#define SAFE_ABS(type,x) ((x) >= 0 ? (type)(x) : -(type)(x))
+
+#define mpfr_get_d1(x) mpfr_get_d(x,__gmpfr_default_rounding_mode)
+
+/* Store in r the size in bits of the mpz_t z */
+#define MPFR_MPZ_SIZEINBASE2(r, z) \
+ do { \
+ int _cnt; \
+ mp_size_t _size; \
+ MPFR_ASSERTD (mpz_sgn (z) != 0); \
+ _size = ABSIZ(z); \
+ count_leading_zeros (_cnt, PTR(z)[_size-1]); \
+ (r) = _size * GMP_NUMB_BITS - _cnt; \
+ } while (0)
+
+/* Needs <locale.h> */
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+/* Warning! In case of signed char, the value of MPFR_DECIMAL_POINT may
+ be negative (the ISO C99 does not seem to forbid negative values). */
+#define MPFR_DECIMAL_POINT (localeconv()->decimal_point[0])
+#define MPFR_THOUSANDS_SEPARATOR (localeconv()->thousands_sep[0])
+#else
+#define MPFR_DECIMAL_POINT ((char) '.')
+#define MPFR_THOUSANDS_SEPARATOR ('\0')
+#endif
+
+
+/* Set y to s*significand(x)*2^e, for example MPFR_ALIAS(y,x,1,MPFR_EXP(x))
+ sets y to |x|, and MPFR_ALIAS(y,x,MPFR_SIGN(x),0) sets y to x*2^f such
+ that 1/2 <= |y| < 1. Does not check y is in the valid exponent range.
+ WARNING! x and y share the same mantissa. So, some operations are
+ not valid if x has been provided via an argument, e.g., trying to
+ modify the mantissa of y, even temporarily, or calling mpfr_clear on y.
+*/
+#define MPFR_ALIAS(y,x,s,e) \
+ do \
+ { \
+ MPFR_PREC(y) = MPFR_PREC(x); \
+ MPFR_SIGN(y) = (s); \
+ MPFR_EXP(y) = (e); \
+ MPFR_MANT(y) = MPFR_MANT(x); \
+ } while (0)
+
+
+/******************************************************
+ ************** Save exponent macros ****************
+ ******************************************************/
+
+/* See README.dev for details on how to use the macros.
+ They are used to set the exponent range to the maximum
+ temporarily */
+
+typedef struct {
+ unsigned int saved_flags;
+ mpfr_exp_t saved_emin;
+ mpfr_exp_t saved_emax;
+} mpfr_save_expo_t;
+
+/* Minimum and maximum exponents of the extended exponent range. */
+#define MPFR_EXT_EMIN MPFR_EMIN_MIN
+#define MPFR_EXT_EMAX MPFR_EMAX_MAX
+
+#define MPFR_SAVE_EXPO_DECL(x) mpfr_save_expo_t x
+#define MPFR_SAVE_EXPO_MARK(x) \
+ ((x).saved_flags = __gmpfr_flags, \
+ (x).saved_emin = __gmpfr_emin, \
+ (x).saved_emax = __gmpfr_emax, \
+ __gmpfr_emin = MPFR_EXT_EMIN, \
+ __gmpfr_emax = MPFR_EXT_EMAX)
+#define MPFR_SAVE_EXPO_FREE(x) \
+ (__gmpfr_flags = (x).saved_flags, \
+ __gmpfr_emin = (x).saved_emin, \
+ __gmpfr_emax = (x).saved_emax)
+#define MPFR_SAVE_EXPO_UPDATE_FLAGS(x, flags) \
+ (x).saved_flags |= (flags)
+
+/* Speed up final checking */
+#define mpfr_check_range(x,t,r) \
+ (MPFR_LIKELY (MPFR_EXP (x) >= __gmpfr_emin && MPFR_EXP (x) <= __gmpfr_emax) \
+ ? ((t) ? (__gmpfr_flags |= MPFR_FLAGS_INEXACT, (t)) : 0) \
+ : mpfr_check_range(x,t,r))
+
+
+/******************************************************
+ ***************** Inline Rounding *******************
+ ******************************************************/
+
+/*
+ * Note: due to the labels, one cannot use a macro MPFR_RNDRAW* more than
+ * once in a function (otherwise these labels would not be unique).
+ */
+
+/*
+ * Round mantissa (srcp, sprec) to mpfr_t dest using rounding mode rnd
+ * assuming dest's sign is sign.
+ * In rounding to nearest mode, execute MIDDLE_HANDLER when the value
+ * is the middle of two consecutive numbers in dest precision.
+ * Execute OVERFLOW_HANDLER in case of overflow when rounding.
+ */
+#define MPFR_RNDRAW_GEN(inexact, dest, srcp, sprec, rnd, sign, \
+ MIDDLE_HANDLER, OVERFLOW_HANDLER) \
+ do { \
+ mp_size_t _dests, _srcs; \
+ mp_limb_t *_destp; \
+ mpfr_prec_t _destprec, _srcprec; \
+ \
+ /* Check Trivial Case when Dest Mantissa has more bits than source */ \
+ _srcprec = (sprec); \
+ _destprec = MPFR_PREC (dest); \
+ _destp = MPFR_MANT (dest); \
+ if (MPFR_UNLIKELY (_destprec >= _srcprec)) \
+ { \
+ _srcs = MPFR_PREC2LIMBS (_srcprec); \
+ _dests = MPFR_PREC2LIMBS (_destprec) - _srcs; \
+ MPN_COPY (_destp + _dests, srcp, _srcs); \
+ MPN_ZERO (_destp, _dests); \
+ inexact = 0; \
+ } \
+ else \
+ { \
+ /* Non trivial case: rounding needed */ \
+ mpfr_prec_t _sh; \
+ mp_limb_t *_sp; \
+ mp_limb_t _rb, _sb, _ulp; \
+ \
+ /* Compute Position and shift */ \
+ _srcs = MPFR_PREC2LIMBS (_srcprec); \
+ _dests = MPFR_PREC2LIMBS (_destprec); \
+ MPFR_UNSIGNED_MINUS_MODULO (_sh, _destprec); \
+ _sp = (srcp) + _srcs - _dests; \
+ \
+ /* General case when prec % GMP_NUMB_BITS != 0 */ \
+ if (MPFR_LIKELY (_sh != 0)) \
+ { \
+ mp_limb_t _mask; \
+ /* Compute Rounding Bit and Sticky Bit */ \
+ /* Note: in directed rounding modes, if the rounding bit */ \
+ /* is 1, the behavior does not depend on the sticky bit; */ \
+ /* thus we will not try to compute it in this case (this */ \
+ /* can be much faster and avoids to read uninitialized */ \
+ /* data in the current mpfr_mul implementation). We just */ \
+ /* make sure that _sb is initialized. */ \
+ _mask = MPFR_LIMB_ONE << (_sh - 1); \
+ _rb = _sp[0] & _mask; \
+ _sb = _sp[0] & (_mask - 1); \
+ if (MPFR_UNLIKELY (_sb == 0) && \
+ ((rnd) == MPFR_RNDN || _rb == 0)) \
+ { /* TODO: Improve it */ \
+ mp_limb_t *_tmp; \
+ mp_size_t _n; \
+ for (_tmp = _sp, _n = _srcs - _dests ; \
+ _n != 0 && _sb == 0 ; _n--) \
+ _sb = *--_tmp; \
+ } \
+ _ulp = 2 * _mask; \
+ } \
+ else /* _sh == 0 */ \
+ { \
+ MPFR_ASSERTD (_dests < _srcs); \
+ /* Compute Rounding Bit and Sticky Bit - see note above */ \
+ _rb = _sp[-1] & MPFR_LIMB_HIGHBIT; \
+ _sb = _sp[-1] & (MPFR_LIMB_HIGHBIT-1); \
+ if (MPFR_UNLIKELY (_sb == 0) && \
+ ((rnd) == MPFR_RNDN || _rb == 0)) \
+ { \
+ mp_limb_t *_tmp; \
+ mp_size_t _n; \
+ for (_tmp = _sp - 1, _n = _srcs - _dests - 1 ; \
+ _n != 0 && _sb == 0 ; _n--) \
+ _sb = *--_tmp; \
+ } \
+ _ulp = MPFR_LIMB_ONE; \
+ } \
+ /* Rounding */ \
+ if (MPFR_LIKELY (rnd == MPFR_RNDN)) \
+ { \
+ if (_rb == 0) \
+ { \
+ trunc: \
+ inexact = MPFR_LIKELY ((_sb | _rb) != 0) ? -sign : 0; \
+ trunc_doit: \
+ MPN_COPY (_destp, _sp, _dests); \
+ _destp[0] &= ~(_ulp - 1); \
+ } \
+ else if (MPFR_UNLIKELY (_sb == 0)) \
+ { /* Middle of two consecutive representable numbers */ \
+ MIDDLE_HANDLER; \
+ } \
+ else \
+ { \
+ if (0) \
+ goto addoneulp_doit; /* dummy code to avoid warning */ \
+ addoneulp: \
+ inexact = sign; \
+ addoneulp_doit: \
+ if (MPFR_UNLIKELY (mpn_add_1 (_destp, _sp, _dests, _ulp))) \
+ { \
+ _destp[_dests - 1] = MPFR_LIMB_HIGHBIT; \
+ OVERFLOW_HANDLER; \
+ } \
+ _destp[0] &= ~(_ulp - 1); \
+ } \
+ } \
+ else \
+ { /* Directed rounding mode */ \
+ if (MPFR_LIKELY (MPFR_IS_LIKE_RNDZ (rnd, \
+ MPFR_IS_NEG_SIGN (sign)))) \
+ goto trunc; \
+ else if (MPFR_UNLIKELY ((_sb | _rb) == 0)) \
+ { \
+ inexact = 0; \
+ goto trunc_doit; \
+ } \
+ else \
+ goto addoneulp; \
+ } \
+ } \
+ } while (0)
+
+/*
+ * Round mantissa (srcp, sprec) to mpfr_t dest using rounding mode rnd
+ * assuming dest's sign is sign.
+ * Execute OVERFLOW_HANDLER in case of overflow when rounding.
+ */
+#define MPFR_RNDRAW(inexact, dest, srcp, sprec, rnd, sign, OVERFLOW_HANDLER) \
+ MPFR_RNDRAW_GEN (inexact, dest, srcp, sprec, rnd, sign, \
+ if ((_sp[0] & _ulp) == 0) \
+ { \
+ inexact = -sign; \
+ goto trunc_doit; \
+ } \
+ else \
+ goto addoneulp; \
+ , OVERFLOW_HANDLER)
+
+/*
+ * Round mantissa (srcp, sprec) to mpfr_t dest using rounding mode rnd
+ * assuming dest's sign is sign.
+ * Execute OVERFLOW_HANDLER in case of overflow when rounding.
+ * Set inexact to +/- MPFR_EVEN_INEX in case of even rounding.
+ */
+#define MPFR_RNDRAW_EVEN(inexact, dest, srcp, sprec, rnd, sign, \
+ OVERFLOW_HANDLER) \
+ MPFR_RNDRAW_GEN (inexact, dest, srcp, sprec, rnd, sign, \
+ if ((_sp[0] & _ulp) == 0) \
+ { \
+ inexact = -MPFR_EVEN_INEX * sign; \
+ goto trunc_doit; \
+ } \
+ else \
+ { \
+ inexact = MPFR_EVEN_INEX * sign; \
+ goto addoneulp_doit; \
+ } \
+ , OVERFLOW_HANDLER)
+
+/* Return TRUE if b is non singular and we can round it to precision 'prec'
+ and determine the ternary value, with rounding mode 'rnd', and with
+ error at most 'error' */
+#define MPFR_CAN_ROUND(b,err,prec,rnd) \
+ (!MPFR_IS_SINGULAR (b) && mpfr_round_p (MPFR_MANT (b), MPFR_LIMB_SIZE (b), \
+ (err), (prec) + ((rnd)==MPFR_RNDN)))
+
+/* Copy the sign and the significand, and handle the exponent in exp. */
+#define MPFR_SETRAW(inexact,dest,src,exp,rnd) \
+ if (MPFR_UNLIKELY (dest != src)) \
+ { \
+ MPFR_SET_SIGN (dest, MPFR_SIGN (src)); \
+ if (MPFR_LIKELY (MPFR_PREC (dest) == MPFR_PREC (src))) \
+ { \
+ MPN_COPY (MPFR_MANT (dest), MPFR_MANT (src), \
+ MPFR_LIMB_SIZE (src)); \
+ inexact = 0; \
+ } \
+ else \
+ { \
+ MPFR_RNDRAW (inexact, dest, MPFR_MANT (src), MPFR_PREC (src), \
+ rnd, MPFR_SIGN (src), exp++); \
+ } \
+ } \
+ else \
+ inexact = 0;
+
+/* TODO: fix this description (see round_near_x.c). */
+/* Assuming that the function has a Taylor expansion which looks like:
+ y=o(f(x)) = o(v + g(x)) with |g(x)| <= 2^(EXP(v)-err)
+ we can quickly set y to v if x is small (ie err > prec(y)+1) in most
+ cases. It assumes that f(x) is not representable exactly as a FP number.
+ v must not be a singular value (NAN, INF or ZERO); usual values are
+ v=1 or v=x.
+
+ y is the destination (a mpfr_t), v the value to set (a mpfr_t),
+ err1+err2 with err2 <= 3 the error term (mpfr_exp_t's), dir (an int) is
+ the direction of the committed error (if dir = 0, it rounds toward 0,
+ if dir=1, it rounds away from 0), rnd the rounding mode.
+
+ It returns from the function a ternary value in case of success.
+ If you want to free something, you must fill the "extra" field
+ in consequences, otherwise put nothing in it.
+
+ The test is less restrictive than necessary, but the function
+ will finish the check itself.
+
+ Note: err1 + err2 is allowed to overflow as mpfr_exp_t, but it must give
+ its real value as mpfr_uexp_t.
+*/
+#define MPFR_FAST_COMPUTE_IF_SMALL_INPUT(y,v,err1,err2,dir,rnd,extra) \
+ do { \
+ mpfr_ptr _y = (y); \
+ mpfr_exp_t _err1 = (err1); \
+ mpfr_exp_t _err2 = (err2); \
+ if (_err1 > 0) \
+ { \
+ mpfr_uexp_t _err = (mpfr_uexp_t) _err1 + _err2; \
+ if (MPFR_UNLIKELY (_err > MPFR_PREC (_y) + 1)) \
+ { \
+ int _inexact = mpfr_round_near_x (_y,(v),_err,(dir),(rnd)); \
+ if (_inexact != 0) \
+ { \
+ extra; \
+ return _inexact; \
+ } \
+ } \
+ } \
+ } while (0)
+
+/* Variant, to be called somewhere after MPFR_SAVE_EXPO_MARK. This variant
+ is needed when there are some computations before or when some non-zero
+ real constant is used, such as __gmpfr_one for mpfr_cos. */
+#define MPFR_SMALL_INPUT_AFTER_SAVE_EXPO(y,v,err1,err2,dir,rnd,expo,extra) \
+ do { \
+ mpfr_ptr _y = (y); \
+ mpfr_exp_t _err1 = (err1); \
+ mpfr_exp_t _err2 = (err2); \
+ if (_err1 > 0) \
+ { \
+ mpfr_uexp_t _err = (mpfr_uexp_t) _err1 + _err2; \
+ if (MPFR_UNLIKELY (_err > MPFR_PREC (_y) + 1)) \
+ { \
+ int _inexact; \
+ mpfr_clear_flags (); \
+ _inexact = mpfr_round_near_x (_y,(v),_err,(dir),(rnd)); \
+ if (_inexact != 0) \
+ { \
+ extra; \
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); \
+ MPFR_SAVE_EXPO_FREE (expo); \
+ return mpfr_check_range (_y, _inexact, (rnd)); \
+ } \
+ } \
+ } \
+ } while (0)
+
+/******************************************************
+ *************** Ziv Loop Macro *********************
+ ******************************************************/
+
+#ifndef MPFR_USE_LOGGING
+
+#define MPFR_ZIV_DECL(_x) mpfr_prec_t _x
+#define MPFR_ZIV_INIT(_x, _p) (_x) = GMP_NUMB_BITS
+#define MPFR_ZIV_NEXT(_x, _p) ((_p) += (_x), (_x) = (_p)/2)
+#define MPFR_ZIV_FREE(x)
+
+#else
+
+/* The following test on glibc is there mainly for Darwin (Mac OS X), to
+ obtain a better error message. The real test should have been a test
+ concerning nested functions in gcc, which are disabled by default on
+ Darwin; but it is not possible to do that without a configure test. */
+# if defined (__cplusplus) || !(__MPFR_GNUC(3,0) && __MPFR_GLIBC(2,0))
+# error "Logging not supported (needs gcc >= 3.0 and GNU C Library >= 2.0)."
+# endif
+
+/* Use LOGGING */
+
+/* Note: the mpfr_log_level >= 0 below avoids to take into account
+ Ziv loops used by the MPFR functions called by the mpfr_fprintf
+ in LOG_PRINT. */
+
+#define MPFR_ZIV_DECL(_x) \
+ mpfr_prec_t _x; \
+ int _x ## _cpt = 1; \
+ static unsigned long _x ## _loop = 0, _x ## _bad = 0; \
+ static const char *_x ## _fname = __func__; \
+ auto void __attribute__ ((destructor)) x ## _f (void); \
+ void __attribute__ ((destructor)) x ## _f (void) { \
+ if (_x ## _loop != 0 && (MPFR_LOG_STAT_F & mpfr_log_type)) \
+ fprintf (mpfr_log_file, \
+ "%s: Ziv failed %2.2f%% (%lu bad cases / %lu calls)\n", \
+ _x ## _fname, (double) 100.0 * _x ## _bad / _x ## _loop, \
+ _x ## _bad, _x ## _loop ); }
+
+#define MPFR_ZIV_INIT(_x, _p) \
+ do \
+ { \
+ (_x) = GMP_NUMB_BITS; \
+ if (mpfr_log_level >= 0) \
+ _x ## _loop ++; \
+ if ((MPFR_LOG_BADCASE_F & mpfr_log_type) && \
+ (mpfr_log_current <= mpfr_log_level)) \
+ LOG_PRINT ("%s:ZIV 1st prec=%Pd\n", \
+ __func__, (mpfr_prec_t) (_p)); \
+ } \
+ while (0)
+
+#define MPFR_ZIV_NEXT(_x, _p) \
+ do \
+ { \
+ (_p) += (_x); \
+ (_x) = (_p) / 2; \
+ if (mpfr_log_level >= 0) \
+ _x ## _bad += (_x ## _cpt == 1); \
+ _x ## _cpt ++; \
+ if ((MPFR_LOG_BADCASE_F & mpfr_log_type) && \
+ (mpfr_log_current <= mpfr_log_level)) \
+ LOG_PRINT ("%s:ZIV new prec=%Pd\n", \
+ __func__, (mpfr_prec_t) (_p)); \
+ } \
+ while (0)
+
+#define MPFR_ZIV_FREE(_x) \
+ do \
+ { \
+ if ((MPFR_LOG_BADCASE_F & mpfr_log_type) && _x ## _cpt > 1 && \
+ (mpfr_log_current <= mpfr_log_level)) \
+ fprintf (mpfr_log_file, "%s:ZIV %d loops\n", \
+ __func__, _x ## _cpt); \
+ } \
+ while (0)
+
+#endif
+
+
+/******************************************************
+ *************** Logging Macros *********************
+ ******************************************************/
+
+/* The different kind of LOG */
+#define MPFR_LOG_INPUT_F 1
+#define MPFR_LOG_OUTPUT_F 2
+#define MPFR_LOG_INTERNAL_F 4
+#define MPFR_LOG_TIME_F 8
+#define MPFR_LOG_BADCASE_F 16
+#define MPFR_LOG_MSG_F 32
+#define MPFR_LOG_STAT_F 64
+
+#ifdef MPFR_USE_LOGGING
+
+/* Check if we can support this feature */
+# ifdef MPFR_USE_THREAD_SAFE
+# error "Enable either `Logging' or `thread-safe', not both"
+# endif
+# if !__MPFR_GNUC(3,0)
+# error "Logging not supported (GCC >= 3.0)"
+# endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+__MPFR_DECLSPEC extern FILE *mpfr_log_file;
+__MPFR_DECLSPEC extern int mpfr_log_type;
+__MPFR_DECLSPEC extern int mpfr_log_level;
+__MPFR_DECLSPEC extern int mpfr_log_current;
+__MPFR_DECLSPEC extern mpfr_prec_t mpfr_log_prec;
+
+#if defined (__cplusplus)
+ }
+#endif
+
+/* LOG_PRINT calls mpfr_fprintf on mpfr_log_file with logging disabled
+ (recursive logging is not wanted and freezes MPFR). */
+#define LOG_PRINT(format, ...) \
+ do \
+ { \
+ int old_level = mpfr_log_level; \
+ mpfr_log_level = -1; /* disable logging in mpfr_fprintf */ \
+ __gmpfr_cache_const_pi = __gmpfr_logging_pi; \
+ __gmpfr_cache_const_log2 = __gmpfr_logging_log2; \
+ mpfr_fprintf (mpfr_log_file, format, __VA_ARGS__); \
+ mpfr_log_level = old_level; \
+ __gmpfr_cache_const_pi = __gmpfr_normal_pi; \
+ __gmpfr_cache_const_log2 = __gmpfr_normal_log2; \
+ } \
+ while (0)
+
+#define MPFR_LOG_VAR(x) \
+ do \
+ if ((MPFR_LOG_INTERNAL_F & mpfr_log_type) && \
+ (mpfr_log_current <= mpfr_log_level)) \
+ LOG_PRINT ("%s.%d:%s[%#Pu]=%.*Rg\n", __func__, __LINE__, \
+ #x, mpfr_get_prec (x), mpfr_log_prec, x); \
+ while (0)
+
+#define MPFR_LOG_MSG2(format, ...) \
+ do \
+ if ((MPFR_LOG_MSG_F & mpfr_log_type) && \
+ (mpfr_log_current <= mpfr_log_level)) \
+ LOG_PRINT ("%s.%d: "format, __func__, __LINE__, __VA_ARGS__); \
+ while (0)
+#define MPFR_LOG_MSG(x) MPFR_LOG_MSG2 x
+
+#define MPFR_LOG_BEGIN2(format, ...) \
+ mpfr_log_current ++; \
+ if ((MPFR_LOG_INPUT_F & mpfr_log_type) && \
+ (mpfr_log_current <= mpfr_log_level)) \
+ LOG_PRINT ("%s:IN "format"\n", __func__, __VA_ARGS__); \
+ if ((MPFR_LOG_TIME_F & mpfr_log_type) && \
+ (mpfr_log_current <= mpfr_log_level)) \
+ __gmpfr_log_time = mpfr_get_cputime ();
+#define MPFR_LOG_BEGIN(x) \
+ int __gmpfr_log_time = 0; \
+ MPFR_LOG_BEGIN2 x
+
+#define MPFR_LOG_END2(format, ...) \
+ if ((MPFR_LOG_TIME_F & mpfr_log_type) && \
+ (mpfr_log_current <= mpfr_log_level)) \
+ fprintf (mpfr_log_file, "%s:TIM %dms\n", __mpfr_log_fname, \
+ mpfr_get_cputime () - __gmpfr_log_time); \
+ if ((MPFR_LOG_OUTPUT_F & mpfr_log_type) && \
+ (mpfr_log_current <= mpfr_log_level)) \
+ LOG_PRINT ("%s:OUT "format"\n", __mpfr_log_fname, __VA_ARGS__); \
+ mpfr_log_current --;
+#define MPFR_LOG_END(x) \
+ static const char *__mpfr_log_fname = __func__; \
+ MPFR_LOG_END2 x
+
+#define MPFR_LOG_FUNC(begin,end) \
+ static const char *__mpfr_log_fname = __func__; \
+ auto void __mpfr_log_cleanup (int *time); \
+ void __mpfr_log_cleanup (int *time) { \
+ int __gmpfr_log_time = *time; \
+ MPFR_LOG_END2 end; } \
+ int __gmpfr_log_time __attribute__ ((cleanup (__mpfr_log_cleanup))); \
+ __gmpfr_log_time = 0; \
+ MPFR_LOG_BEGIN2 begin
+
+#else /* MPFR_USE_LOGGING */
+
+/* Define void macro for logging */
+
+#define MPFR_LOG_VAR(x)
+#define MPFR_LOG_BEGIN(x)
+#define MPFR_LOG_END(x)
+#define MPFR_LOG_MSG(x)
+#define MPFR_LOG_FUNC(x,y)
+
+#endif /* MPFR_USE_LOGGING */
+
+
+/**************************************************************
+ ************ Group Initialize Functions Macros *************
+ **************************************************************/
+
+#ifndef MPFR_GROUP_STATIC_SIZE
+# define MPFR_GROUP_STATIC_SIZE 16
+#endif
+
+struct mpfr_group_t {
+ size_t alloc;
+ mp_limb_t *mant;
+ mp_limb_t tab[MPFR_GROUP_STATIC_SIZE];
+};
+
+#define MPFR_GROUP_DECL(g) struct mpfr_group_t g
+#define MPFR_GROUP_CLEAR(g) do { \
+ MPFR_LOG_MSG (("GROUP_CLEAR: ptr = 0x%lX, size = %lu\n", \
+ (unsigned long) (g).mant, \
+ (unsigned long) (g).alloc)); \
+ if (MPFR_UNLIKELY ((g).alloc != 0)) { \
+ MPFR_ASSERTD ((g).mant != (g).tab); \
+ (*__gmp_free_func) ((g).mant, (g).alloc); \
+ }} while (0)
+
+#define MPFR_GROUP_INIT_TEMPLATE(g, prec, num, handler) do { \
+ mpfr_prec_t _prec = (prec); \
+ mp_size_t _size; \
+ MPFR_ASSERTD (_prec >= MPFR_PREC_MIN); \
+ if (MPFR_UNLIKELY (_prec > MPFR_PREC_MAX)) \
+ mpfr_abort_prec_max (); \
+ _size = MPFR_PREC2LIMBS (_prec); \
+ if (MPFR_UNLIKELY (_size * (num) > MPFR_GROUP_STATIC_SIZE)) \
+ { \
+ (g).alloc = (num) * _size * sizeof (mp_limb_t); \
+ (g).mant = (mp_limb_t *) (*__gmp_allocate_func) ((g).alloc); \
+ } \
+ else \
+ { \
+ (g).alloc = 0; \
+ (g).mant = (g).tab; \
+ } \
+ MPFR_LOG_MSG (("GROUP_INIT: ptr = 0x%lX, size = %lu\n", \
+ (unsigned long) (g).mant, (unsigned long) (g).alloc)); \
+ handler; \
+ } while (0)
+#define MPFR_GROUP_TINIT(g, n, x) \
+ MPFR_TMP_INIT1 ((g).mant + _size * (n), x, _prec)
+
+#define MPFR_GROUP_INIT_1(g, prec, x) \
+ MPFR_GROUP_INIT_TEMPLATE(g, prec, 1, MPFR_GROUP_TINIT(g, 0, x))
+#define MPFR_GROUP_INIT_2(g, prec, x, y) \
+ MPFR_GROUP_INIT_TEMPLATE(g, prec, 2, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y))
+#define MPFR_GROUP_INIT_3(g, prec, x, y, z) \
+ MPFR_GROUP_INIT_TEMPLATE(g, prec, 3, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
+ MPFR_GROUP_TINIT(g, 2, z))
+#define MPFR_GROUP_INIT_4(g, prec, x, y, z, t) \
+ MPFR_GROUP_INIT_TEMPLATE(g, prec, 4, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
+ MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t))
+#define MPFR_GROUP_INIT_5(g, prec, x, y, z, t, a) \
+ MPFR_GROUP_INIT_TEMPLATE(g, prec, 5, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
+ MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t); \
+ MPFR_GROUP_TINIT(g, 4, a))
+#define MPFR_GROUP_INIT_6(g, prec, x, y, z, t, a, b) \
+ MPFR_GROUP_INIT_TEMPLATE(g, prec, 6, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
+ MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t); \
+ MPFR_GROUP_TINIT(g, 4, a);MPFR_GROUP_TINIT(g, 5, b))
+
+#define MPFR_GROUP_REPREC_TEMPLATE(g, prec, num, handler) do { \
+ mpfr_prec_t _prec = (prec); \
+ size_t _oalloc = (g).alloc; \
+ mp_size_t _size; \
+ MPFR_LOG_MSG (("GROUP_REPREC: oldptr = 0x%lX, oldsize = %lu\n", \
+ (unsigned long) (g).mant, (unsigned long) _oalloc)); \
+ MPFR_ASSERTD (_prec >= MPFR_PREC_MIN); \
+ if (MPFR_UNLIKELY (_prec > MPFR_PREC_MAX)) \
+ mpfr_abort_prec_max (); \
+ _size = MPFR_PREC2LIMBS (_prec); \
+ (g).alloc = (num) * _size * sizeof (mp_limb_t); \
+ if (MPFR_LIKELY (_oalloc == 0)) \
+ (g).mant = (mp_limb_t *) (*__gmp_allocate_func) ((g).alloc); \
+ else \
+ (g).mant = (mp_limb_t *) \
+ (*__gmp_reallocate_func) ((g).mant, _oalloc, (g).alloc); \
+ MPFR_LOG_MSG (("GROUP_REPREC: newptr = 0x%lX, newsize = %lu\n", \
+ (unsigned long) (g).mant, (unsigned long) (g).alloc)); \
+ handler; \
+ } while (0)
+
+#define MPFR_GROUP_REPREC_1(g, prec, x) \
+ MPFR_GROUP_REPREC_TEMPLATE(g, prec, 1, MPFR_GROUP_TINIT(g, 0, x))
+#define MPFR_GROUP_REPREC_2(g, prec, x, y) \
+ MPFR_GROUP_REPREC_TEMPLATE(g, prec, 2, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y))
+#define MPFR_GROUP_REPREC_3(g, prec, x, y, z) \
+ MPFR_GROUP_REPREC_TEMPLATE(g, prec, 3, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
+ MPFR_GROUP_TINIT(g, 2, z))
+#define MPFR_GROUP_REPREC_4(g, prec, x, y, z, t) \
+ MPFR_GROUP_REPREC_TEMPLATE(g, prec, 4, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
+ MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t))
+#define MPFR_GROUP_REPREC_5(g, prec, x, y, z, t, a) \
+ MPFR_GROUP_REPREC_TEMPLATE(g, prec, 5, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
+ MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t); \
+ MPFR_GROUP_TINIT(g, 4, a))
+#define MPFR_GROUP_REPREC_6(g, prec, x, y, z, t, a, b) \
+ MPFR_GROUP_REPREC_TEMPLATE(g, prec, 6, \
+ MPFR_GROUP_TINIT(g, 0, x);MPFR_GROUP_TINIT(g, 1, y); \
+ MPFR_GROUP_TINIT(g, 2, z);MPFR_GROUP_TINIT(g, 3, t); \
+ MPFR_GROUP_TINIT(g, 4, a);MPFR_GROUP_TINIT(g, 5, b))
+
+
+/******************************************************
+ *************** Internal Functions *****************
+ ******************************************************/
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+__MPFR_DECLSPEC int mpfr_underflow _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t, int));
+__MPFR_DECLSPEC int mpfr_overflow _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t, int));
+
+__MPFR_DECLSPEC int mpfr_add1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sub1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_add1sp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sub1sp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_can_round_raw _MPFR_PROTO ((const mp_limb_t *,
+ mp_size_t, int, mpfr_exp_t, mpfr_rnd_t, mpfr_rnd_t, mpfr_prec_t));
+
+__MPFR_DECLSPEC int mpfr_cmp2 _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr,
+ mpfr_prec_t *));
+
+__MPFR_DECLSPEC long __gmpfr_ceil_log2 _MPFR_PROTO ((double));
+__MPFR_DECLSPEC long __gmpfr_floor_log2 _MPFR_PROTO ((double));
+__MPFR_DECLSPEC double __gmpfr_ceil_exp2 _MPFR_PROTO ((double));
+__MPFR_DECLSPEC unsigned long __gmpfr_isqrt _MPFR_PROTO ((unsigned long));
+__MPFR_DECLSPEC unsigned long __gmpfr_cuberoot _MPFR_PROTO ((unsigned long));
+__MPFR_DECLSPEC int __gmpfr_int_ceil_log2 _MPFR_PROTO ((unsigned long));
+
+__MPFR_DECLSPEC mpfr_exp_t mpfr_ceil_mul _MPFR_PROTO ((mpfr_exp_t, int, int));
+
+__MPFR_DECLSPEC int mpfr_exp_2 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_exp_3 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_powerof2_raw _MPFR_PROTO ((mpfr_srcptr));
+
+__MPFR_DECLSPEC int mpfr_pow_general _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t, int, mpfr_save_expo_t *));
+
+__MPFR_DECLSPEC void mpfr_setmax _MPFR_PROTO ((mpfr_ptr, mpfr_exp_t));
+__MPFR_DECLSPEC void mpfr_setmin _MPFR_PROTO ((mpfr_ptr, mpfr_exp_t));
+
+__MPFR_DECLSPEC long mpfr_mpn_exp _MPFR_PROTO ((mp_limb_t *, mpfr_exp_t *, int,
+ mpfr_exp_t, size_t));
+
+#ifdef _MPFR_H_HAVE_FILE
+__MPFR_DECLSPEC void mpfr_fprint_binary _MPFR_PROTO ((FILE *, mpfr_srcptr));
+#endif
+__MPFR_DECLSPEC void mpfr_print_binary _MPFR_PROTO ((mpfr_srcptr));
+__MPFR_DECLSPEC void mpfr_print_mant_binary _MPFR_PROTO ((const char*,
+ const mp_limb_t*, mpfr_prec_t));
+__MPFR_DECLSPEC void mpfr_set_str_binary _MPFR_PROTO((mpfr_ptr, const char*));
+
+__MPFR_DECLSPEC int mpfr_round_raw _MPFR_PROTO ((mp_limb_t *,
+ const mp_limb_t *, mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t, int *));
+__MPFR_DECLSPEC int mpfr_round_raw_2 _MPFR_PROTO ((const mp_limb_t *,
+ mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t));
+/* No longer defined (see round_prec.c).
+ Uncomment if it needs to be defined again.
+__MPFR_DECLSPEC int mpfr_round_raw_3 _MPFR_PROTO ((const mp_limb_t *,
+ mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t, int *));
+*/
+__MPFR_DECLSPEC int mpfr_round_raw_4 _MPFR_PROTO ((mp_limb_t *,
+ const mp_limb_t *, mpfr_prec_t, int, mpfr_prec_t, mpfr_rnd_t));
+
+#define mpfr_round_raw2(xp, xn, neg, r, prec) \
+ mpfr_round_raw_2((xp),(xn)*GMP_NUMB_BITS,(neg),(prec),(r))
+
+__MPFR_DECLSPEC int mpfr_check _MPFR_PROTO ((mpfr_srcptr));
+
+__MPFR_DECLSPEC int mpfr_sum_sort _MPFR_PROTO ((mpfr_srcptr *const,
+ unsigned long, mpfr_srcptr *));
+
+__MPFR_DECLSPEC int mpfr_get_cputime _MPFR_PROTO ((void));
+
+__MPFR_DECLSPEC void mpfr_nexttozero _MPFR_PROTO ((mpfr_ptr));
+__MPFR_DECLSPEC void mpfr_nexttoinf _MPFR_PROTO ((mpfr_ptr));
+
+__MPFR_DECLSPEC int mpfr_const_pi_internal _MPFR_PROTO ((mpfr_ptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_const_log2_internal _MPFR_PROTO((mpfr_ptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_const_euler_internal _MPFR_PROTO((mpfr_ptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_const_catalan_internal _MPFR_PROTO((mpfr_ptr, mpfr_rnd_t));
+
+#if 0
+__MPFR_DECLSPEC void mpfr_init_cache _MPFR_PROTO ((mpfr_cache_t,
+ int(*)(mpfr_ptr,mpfr_rnd_t)));
+#endif
+__MPFR_DECLSPEC void mpfr_clear_cache _MPFR_PROTO ((mpfr_cache_t));
+__MPFR_DECLSPEC int mpfr_cache _MPFR_PROTO ((mpfr_ptr, mpfr_cache_t,
+ mpfr_rnd_t));
+
+__MPFR_DECLSPEC void mpfr_mulhigh_n _MPFR_PROTO ((mpfr_limb_ptr,
+ mpfr_limb_srcptr, mpfr_limb_srcptr, mp_size_t));
+__MPFR_DECLSPEC void mpfr_mullow_n _MPFR_PROTO ((mpfr_limb_ptr,
+ mpfr_limb_srcptr, mpfr_limb_srcptr, mp_size_t));
+__MPFR_DECLSPEC void mpfr_sqrhigh_n _MPFR_PROTO ((mpfr_limb_ptr,
+ mpfr_limb_srcptr, mp_size_t));
+__MPFR_DECLSPEC mp_limb_t mpfr_divhigh_n _MPFR_PROTO ((mpfr_limb_ptr,
+ mpfr_limb_ptr, mpfr_limb_ptr, mp_size_t));
+
+__MPFR_DECLSPEC int mpfr_round_p _MPFR_PROTO ((mp_limb_t *, mp_size_t,
+ mpfr_exp_t, mpfr_prec_t));
+
+__MPFR_DECLSPEC void mpfr_dump_mant _MPFR_PROTO ((const mp_limb_t *,
+ mpfr_prec_t, mpfr_prec_t,
+ mpfr_prec_t));
+
+__MPFR_DECLSPEC int mpfr_round_near_x _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_uexp_t, int,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC void mpfr_abort_prec_max _MPFR_PROTO ((void))
+ MPFR_NORETURN_ATTR;
+
+__MPFR_DECLSPEC void mpfr_rand_raw _MPFR_PROTO((mpfr_limb_ptr, gmp_randstate_t,
+ mpfr_prec_t));
+
+__MPFR_DECLSPEC mpz_t* mpfr_bernoulli_internal _MPFR_PROTO((mpz_t*,
+ unsigned long));
+
+__MPFR_DECLSPEC int mpfr_sincos_fast _MPFR_PROTO((mpfr_t, mpfr_t,
+ mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC double mpfr_scale2 _MPFR_PROTO((double, int));
+
+__MPFR_DECLSPEC void mpfr_div_ui2 _MPFR_PROTO((mpfr_ptr, mpfr_srcptr,
+ unsigned long int, unsigned long int,
+ mpfr_rnd_t));
+
+__MPFR_DECLSPEC void mpfr_gamma_one_and_two_third _MPFR_PROTO((mpfr_ptr, mpfr_ptr, mpfr_prec_t));
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
diff --git a/mpfr/src/mpfr-intmax.h b/mpfr/src/mpfr-intmax.h
new file mode 100644
index 0000000000..f00c672337
--- /dev/null
+++ b/mpfr/src/mpfr-intmax.h
@@ -0,0 +1,40 @@
+/* MPFR internal header related to intmax_t.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __MPFR_INTMAX_H__
+#define __MPFR_INTMAX_H__
+
+/* The ISO C99 standard specifies that in C++ implementations the
+ INTMAX_MAX, ... macros should only be defined if explicitly requested. */
+#if defined __cplusplus
+# define __STDC_LIMIT_MACROS
+# define __STDC_CONSTANT_MACROS
+#endif
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#endif
diff --git a/mpfr/src/mpfr-longlong.h b/mpfr/src/mpfr-longlong.h
new file mode 100644
index 0000000000..32d0873802
--- /dev/null
+++ b/mpfr/src/mpfr-longlong.h
@@ -0,0 +1,1943 @@
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
+
+Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
+2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it under the
+terms of the GNU Lesser General Public License as published by the Free
+Software Foundation; either version 3 of the License, or (at your option) any
+later version.
+
+This file is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this file. If not, see http://www.gnu.org/licenses/. */
+
+/* You have to define the following before including this file:
+
+ UWtype -- An unsigned type, default type for operations (typically a "word")
+ UHWtype -- An unsigned type, at least half the size of UWtype.
+ UDWtype -- An unsigned type, at least twice as large a UWtype
+ W_TYPE_SIZE -- size in bits of UWtype
+
+ SItype, USItype -- Signed and unsigned 32 bit types.
+ DItype, UDItype -- Signed and unsigned 64 bit types.
+
+ On a 32 bit machine UWtype should typically be USItype;
+ on a 64 bit machine, UWtype should typically be UDItype.
+
+ CAUTION! Using this file outside of GMP is not safe. You need to include
+ gmp.h and gmp-impl.h, or certain things might not work as expected.
+*/
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+/* This is used to make sure no undesirable sharing between different libraries
+ that use this file takes place. */
+#ifndef __MPN
+#define __MPN(x) __##x
+#endif
+
+#ifndef _PROTO
+#if (__STDC__-0) || defined (__cplusplus)
+#define _PROTO(x) x
+#else
+#define _PROTO(x) ()
+#endif
+#endif
+
+/* Define auxiliary asm macros.
+
+ 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
+ UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype
+ word product in HIGH_PROD and LOW_PROD.
+
+ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
+ UDWtype product. This is just a variant of umul_ppmm.
+
+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator) divides a UDWtype, composed by the UWtype integers
+ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
+ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
+ than DENOMINATOR for correct operation. If, in addition, the most
+ significant bit of DENOMINATOR must be 1, then the pre-processor symbol
+ UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator). Like udiv_qrnnd but the numbers are signed. The quotient
+ is rounded toward 0.
+
+ 5) count_leading_zeros(count, x) counts the number of zero-bits from the
+ msb to the first non-zero bit in the UWtype X. This is the number of
+ steps X needs to be shifted left to set the msb. Undefined for X == 0,
+ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
+
+ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
+ from the least significant end.
+
+ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+ high_addend_2, low_addend_2) adds two UWtype integers, composed by
+ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
+ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
+ (i.e. carry out) is not stored anywhere, and is lost.
+
+ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
+ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
+ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
+ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
+ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ and is lost.
+
+ If any of these macros are left undefined for a particular CPU,
+ C macros are used.
+
+
+ Notes:
+
+ For add_ssaaaa the two high and two low addends can both commute, but
+ unfortunately gcc only supports one "%" commutative in each asm block.
+ This has always been so but is only documented in recent versions
+ (eg. pre-release 3.3). Having two or more "%"s can cause an internal
+ compiler error in certain rare circumstances.
+
+ Apparently it was only the last "%" that was ever actually respected, so
+ the code has been updated to leave just that. Clearly there's a free
+ choice whether high or low should get it, if there's a reason to favour
+ one over the other. Also obviously when the constraints on the two
+ operands are identical there's no benefit to the reloader in any "%" at
+ all.
+
+ */
+
+/* The CPUs come in alphabetical order below.
+
+ Please add support for more CPUs here, or improve the current support
+ for the CPUs below! */
+
+
+/* count_leading_zeros_gcc_clz is count_leading_zeros implemented with gcc
+ 3.4 __builtin_clzl or __builtin_clzll, according to our limb size.
+ Similarly count_trailing_zeros_gcc_ctz using __builtin_ctzl or
+ __builtin_ctzll.
+
+ These builtins are only used when we check what code comes out, on some
+ chips they're merely libgcc calls, where we will instead want an inline
+ in that case (either asm or generic C).
+
+ These builtins are better than an asm block of the same insn, since an
+ asm block doesn't give gcc any information about scheduling or resource
+ usage. We keep an asm block for use on prior versions of gcc though.
+
+ For reference, __builtin_ffs existed in gcc prior to __builtin_clz, but
+ it's not used (for count_leading_zeros) because it generally gives extra
+ code to ensure the result is 0 when the input is 0, which we don't need
+ or want. */
+
+#ifdef _LONG_LONG_LIMB
+#define count_leading_zeros_gcc_clz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_clzll (x); \
+ } while (0)
+#else
+#define count_leading_zeros_gcc_clz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_clzl (x); \
+ } while (0)
+#endif
+
+#ifdef _LONG_LONG_LIMB
+#define count_trailing_zeros_gcc_ctz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_ctzll (x); \
+ } while (0)
+#else
+#define count_trailing_zeros_gcc_ctz(count,x) \
+ do { \
+ ASSERT ((x) != 0); \
+ (count) = __builtin_ctzl (x); \
+ } while (0)
+#endif
+
+/* Note: the following FIXME comes from GMP, thus it does make sense to try
+ to resolve it in MPFR. */
+/* FIXME: The macros using external routines like __MPN(count_leading_zeros)
+ don't need to be under !NO_ASM */
+#if ! defined (NO_ASM)
+
+#if defined (__alpha) && W_TYPE_SIZE == 64
+/* Most alpha-based machines, except Cray systems. */
+#if defined (__GNUC__)
+#if __GMP_GNUC_PREREQ (3,3)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ (ph) = __builtin_alpha_umulh (__m0, __m1); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#else
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("umulh %r1,%2,%0" \
+ : "=r" (ph) \
+ : "%rJ" (m0), "rI" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#endif
+#define UMUL_TIME 18
+#else /* ! __GNUC__ */
+#include <machine/builtins.h>
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ (ph) = __UMULH (m0, m1); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#endif
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __di; \
+ __di = __MPN(invert_limb) (d); \
+ udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \
+ } while (0)
+#define UDIV_PREINV_ALWAYS 1
+#define UDIV_NEEDS_NORMALIZATION 1
+#define UDIV_TIME 220
+#endif /* LONGLONG_STANDALONE */
+
+/* clz_tab is required in all configurations, since mpn/alpha/cntlz.asm
+ always goes into libgmp.so, even when not actually used. */
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+
+#if defined (__GNUC__) && HAVE_HOST_CPU_alpha_CIX
+#define count_leading_zeros(COUNT,X) \
+ __asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X))
+#define count_trailing_zeros(COUNT,X) \
+ __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X))
+#endif /* clz/ctz using cix */
+
+#if ! defined (count_leading_zeros) \
+ && defined (__GNUC__) && ! defined (LONGLONG_STANDALONE)
+/* ALPHA_CMPBGE_0 gives "cmpbge $31,src,dst", ie. test src bytes == 0.
+ "$31" is written explicitly in the asm, since an "r" constraint won't
+ select reg 31. There seems no need to worry about "r31" syntax for cray,
+ since gcc itself (pre-release 3.4) emits just $31 in various places. */
+#define ALPHA_CMPBGE_0(dst, src) \
+ do { asm ("cmpbge $31, %1, %0" : "=r" (dst) : "r" (src)); } while (0)
+/* Zero bytes are turned into bits with cmpbge, a __clz_tab lookup counts
+ them, locating the highest non-zero byte. A second __clz_tab lookup
+ counts the leading zero bits in that byte, giving the result. */
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype __clz__b, __clz__c, __clz__x = (x); \
+ ALPHA_CMPBGE_0 (__clz__b, __clz__x); /* zero bytes */ \
+ __clz__b = __clz_tab [(__clz__b >> 1) ^ 0x7F]; /* 8 to 1 byte */ \
+ __clz__b = __clz__b * 8 - 7; /* 57 to 1 shift */ \
+ __clz__x >>= __clz__b; \
+ __clz__c = __clz_tab [__clz__x]; /* 8 to 1 bit */ \
+ __clz__b = 65 - __clz__b; \
+ (count) = __clz__b - __clz__c; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#endif /* clz using cmpbge */
+
+#if ! defined (count_leading_zeros) && ! defined (LONGLONG_STANDALONE)
+#if HAVE_ATTRIBUTE_CONST
+long __MPN(count_leading_zeros) _PROTO ((UDItype)) __attribute__ ((const));
+#else
+long __MPN(count_leading_zeros) _PROTO ((UDItype));
+#endif
+#define count_leading_zeros(count, x) \
+ ((count) = __MPN(count_leading_zeros) (x))
+#endif /* clz using mpn */
+#endif /* __alpha */
+
+#if defined (_CRAY) && W_TYPE_SIZE == 64
+#include <intrinsics.h>
+#define UDIV_PREINV_ALWAYS 1
+#define UDIV_NEEDS_NORMALIZATION 1
+#define UDIV_TIME 220
+long __MPN(count_leading_zeros) _PROTO ((UDItype));
+#define count_leading_zeros(count, x) \
+ ((count) = _leadz ((UWtype) (x)))
+#if defined (_CRAYIEEE) /* I.e., Cray T90/ieee, T3D, and T3E */
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ (ph) = _int_mult_upper (m0, m1); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __di; \
+ __di = __MPN(invert_limb) (d); \
+ udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \
+ } while (0)
+#endif /* LONGLONG_STANDALONE */
+#endif /* _CRAYIEEE */
+#endif /* _CRAY */
+
+#if defined (__ia64) && W_TYPE_SIZE == 64
+/* This form encourages gcc (pre-release 3.4 at least) to emit predicated
+ "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency. The generic
+ code using "al<bl" arithmetically comes out making an actual 0 or 1 in a
+ register, which takes an extra cycle. */
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ if ((al) < (bl)) \
+ (sh) = (ah) - (bh) - 1; \
+ else \
+ (sh) = (ah) - (bh); \
+ (sl) = __x; \
+ } while (0)
+#if defined (__GNUC__) && ! defined (__INTEL_COMPILER)
+/* Do both product parts in assembly, since that gives better code with
+ all gcc versions. Some callers will just use the upper part, and in
+ that situation we waste an instruction, but not any cycles. */
+#define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0" \
+ : "=&f" (ph), "=f" (pl) \
+ : "f" (m0), "f" (m1))
+#define UMUL_TIME 14
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype _x = (x), _y, _a, _c; \
+ __asm__ ("mux1 %0 = %1, @rev" : "=r" (_y) : "r" (_x)); \
+ __asm__ ("czx1.l %0 = %1" : "=r" (_a) : "r" (-_y | _y)); \
+ _c = (_a - 1) << 3; \
+ _x >>= _c; \
+ if (_x >= 1 << 4) \
+ _x >>= 4, _c += 4; \
+ if (_x >= 1 << 2) \
+ _x >>= 2, _c += 2; \
+ _c += _x >> 1; \
+ (count) = W_TYPE_SIZE - 1 - _c; \
+ } while (0)
+/* similar to what gcc does for __builtin_ffs, but 0 based rather than 1
+ based, and we don't need a special case for x==0 here */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ __asm__ ("popcnt %0 = %1" \
+ : "=r" (count) \
+ : "r" ((__ctz_x-1) & ~__ctz_x)); \
+ } while (0)
+#endif
+#if defined (__INTEL_COMPILER)
+#include <ia64intrin.h>
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UWtype _m0 = (m0), _m1 = (m1); \
+ ph = _m64_xmahu (_m0, _m1, 0); \
+ pl = _m0 * _m1; \
+ } while (0)
+#endif
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __di; \
+ __di = __MPN(invert_limb) (d); \
+ udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \
+ } while (0)
+#define UDIV_PREINV_ALWAYS 1
+#define UDIV_NEEDS_NORMALIZATION 1
+#endif
+#define UDIV_TIME 220
+#endif
+
+
+#if defined (__GNUC__)
+
+/* We sometimes need to clobber "cc" with gcc2, but that would not be
+ understood by gcc1. Use cpp to avoid major code duplication. */
+#if __GNUC__ < 2
+#define __CLOBBER_CC
+#define __AND_CLOBBER_CC
+#else /* __GNUC__ >= 2 */
+#define __CLOBBER_CC : "cc"
+#define __AND_CLOBBER_CC , "cc"
+#endif /* __GNUC__ < 2 */
+
+#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %1,%4,%5\n\taddc %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %1,%4,%5\n\tsubc %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "r" (al), "rI" (bl))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("multiplu %0,%1,%2" \
+ : "=r" (xl) \
+ : "r" (__m0), "r" (__m1)); \
+ __asm__ ("multmu %0,%1,%2" \
+ : "=r" (xh) \
+ : "r" (__m0), "r" (__m1)); \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("dividu %0,%3,%4" \
+ : "=r" (q), "=q" (r) \
+ : "1" (n1), "r" (n0), "r" (d))
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz %0,%1" \
+ : "=r" (count) \
+ : "r" (x))
+#define COUNT_LEADING_ZEROS_0 32
+#endif /* __a29k__ */
+
+#if defined (__arc__)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add.f\t%1, %4, %5\n\tadc\t%0, %2, %3" \
+ : "=r" (sh), \
+ "=&r" (sl) \
+ : "r" ((USItype) (ah)), \
+ "rIJ" ((USItype) (bh)), \
+ "%r" ((USItype) (al)), \
+ "rIJ" ((USItype) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub.f\t%1, %4, %5\n\tsbc\t%0, %2, %3" \
+ : "=r" (sh), \
+ "=&r" (sl) \
+ : "r" ((USItype) (ah)), \
+ "rIJ" ((USItype) (bh)), \
+ "r" ((USItype) (al)), \
+ "rIJ" ((USItype) (bl)))
+#endif
+
+#if defined (__arm__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (al)) \
+ { \
+ if (__builtin_constant_p (ah)) \
+ __asm__ ("rsbs\t%1, %5, %4\n\trsc\t%0, %3, %2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rI" (ah), "r" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \
+ else \
+ __asm__ ("rsbs\t%1, %5, %4\n\tsbc\t%0, %2, %3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \
+ } \
+ else if (__builtin_constant_p (ah)) \
+ { \
+ if (__builtin_constant_p (bl)) \
+ __asm__ ("subs\t%1, %4, %5\n\trsc\t%0, %3, %2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rI" (ah), "r" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \
+ else \
+ __asm__ ("rsbs\t%1, %5, %4\n\trsc\t%0, %3, %2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rI" (ah), "r" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \
+ } \
+ else if (__builtin_constant_p (bl)) \
+ { \
+ if (__builtin_constant_p (bh)) \
+ __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \
+ else \
+ __asm__ ("subs\t%1, %4, %5\n\trsc\t%0, %3, %2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rI" (ah), "r" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \
+ } \
+ else /* only bh might be a constant */ \
+ __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC);\
+ } while (0)
+#if 1 || defined (__arm_m__) /* `M' series has widening multiply support */
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("umull %0,%1,%2,%3" : "=&r" (xl), "=&r" (xh) : "r" (a), "r" (b))
+#define UMUL_TIME 5
+#define smul_ppmm(xh, xl, a, b) \
+ __asm__ ("smull %0,%1,%2,%3" : "=&r" (xl), "=&r" (xh) : "r" (a), "r" (b))
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __di; \
+ __di = __MPN(invert_limb) (d); \
+ udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \
+ } while (0)
+#define UDIV_PREINV_ALWAYS 1
+#define UDIV_NEEDS_NORMALIZATION 1
+#define UDIV_TIME 70
+#endif /* LONGLONG_STANDALONE */
+#else
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+" mov %|r0, %2, lsr #16\n" \
+" mov %|r2, %3, lsr #16\n" \
+" bic %|r1, %2, %|r0, lsl #16\n" \
+" bic %|r2, %3, %|r2, lsl #16\n" \
+" mul %1, %|r1, %|r2\n" \
+" mul %|r2, %|r0, %|r2\n" \
+" mul %|r1, %0, %|r1\n" \
+" mul %0, %|r0, %0\n" \
+" adds %|r1, %|r2, %|r1\n" \
+" addcs %0, %0, #65536\n" \
+" adds %1, %1, %|r1, lsl #16\n" \
+" adc %0, %0, %|r1, lsr #16" \
+ : "=&r" (xh), "=r" (xl) \
+ : "r" (a), "r" (b) \
+ : "r0", "r1", "r2")
+#define UMUL_TIME 20
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __r; \
+ (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
+#define UDIV_TIME 200
+#endif /* LONGLONG_STANDALONE */
+#endif
+#endif /* __arm__ */
+
+#if defined (__clipper__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__x.__ll) \
+ : "%0" ((USItype)(u)), "r" ((USItype)(v))); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#define smul_ppmm(w1, w0, u, v) \
+ ({union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __x; \
+ __asm__ ("mulwx %2,%0" \
+ : "=r" (__x.__ll) \
+ : "%0" ((SItype)(u)), "r" ((SItype)(v))); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__w) : "%0" ((USItype)(u)), "r" ((USItype)(v))); \
+ __w; })
+#endif /* __clipper__ */
+
+/* Fujitsu vector computers. */
+#if defined (__uxp__) && W_TYPE_SIZE == 32
+#define umul_ppmm(ph, pl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mult.lu %1,%2,%0" : "=r" (__x.__ll) : "%r" (u), "rK" (v));\
+ (ph) = __x.__i.__h; \
+ (pl) = __x.__i.__l; \
+ } while (0)
+#define smul_ppmm(ph, pl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mult.l %1,%2,%0" : "=r" (__x.__ll) : "%r" (u), "rK" (v)); \
+ (ph) = __x.__i.__h; \
+ (pl) = __x.__i.__l; \
+ } while (0)
+#endif
+
+#if defined (__gmicro__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add.w %5,%1\n\taddx %3,%0" \
+ : "=g" (sh), "=&g" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub.w %5,%1\n\tsubx %3,%0" \
+ : "=g" (sh), "=&g" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("mulx %3,%0,%1" \
+ : "=g" (ph), "=r" (pl) \
+ : "%0" ((USItype)(m0)), "g" ((USItype)(m1)))
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("divx %4,%0,%1" \
+ : "=g" (q), "=r" (r) \
+ : "1" ((USItype)(nh)), "0" ((USItype)(nl)), "g" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bsch/1 %1,%0" \
+ : "=g" (count) : "g" ((USItype)(x)), "0" ((USItype)0))
+#endif
+
+#if defined (__hppa) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%I5 %5,%r4,%1\n\taddc %r2,%r3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rM" (ah), "rM" (bh), "%rM" (al), "rI" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%I4 %4,%r5,%1\n\tsubb %r2,%r3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rM" (ah), "rM" (bh), "rI" (al), "rM" (bl))
+#if defined (_PA_RISC1_1)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("xmpyu %1,%2,%0" : "=*f" (__x.__ll) : "*f" (u), "*f" (v)); \
+ (wh) = __x.__i.__h; \
+ (wl) = __x.__i.__l; \
+ } while (0)
+#define UMUL_TIME 8
+#define UDIV_TIME 60
+#else
+#define UMUL_TIME 40
+#define UDIV_TIME 80
+#endif
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __tmp; \
+ __asm__ ( \
+ "ldi 1,%0\n" \
+" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \
+" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \
+" ldo 16(%0),%0 ; Yes. Perform add.\n" \
+" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \
+" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \
+" ldo 8(%0),%0 ; Yes. Perform add.\n" \
+" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \
+" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \
+" ldo 4(%0),%0 ; Yes. Perform add.\n" \
+" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \
+" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \
+" ldo 2(%0),%0 ; Yes. Perform add.\n" \
+" extru %1,30,1,%1 ; Extract bit 1.\n" \
+" sub %0,%1,%0 ; Subtract it.\n" \
+ : "=r" (count), "=r" (__tmp) : "1" (x)); \
+ } while (0)
+#endif /* hppa */
+
+/* These macros are for ABI=2.0w. In ABI=2.0n they can't be used, since GCC
+ (3.2) puts longlong into two adjacent 32-bit registers. Presumably this
+ is just a case of no direct support for 2.0n but treating it like 1.0. */
+#if defined (__hppa) && W_TYPE_SIZE == 64 && ! defined (_LONG_LONG_LIMB)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%I5 %5,%r4,%1\n\tadd,dc %r2,%r3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rM" (ah), "rM" (bh), "%rM" (al), "rI" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%I4 %4,%r5,%1\n\tsub,db %r2,%r3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rM" (ah), "rM" (bh), "rI" (al), "rM" (bl))
+#endif /* hppa */
+
+#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32
+#define smul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("lr %N0,%1\n\tmr %0,%2" \
+ : "=&r" (__x.__ll) \
+ : "r" (m0), "r" (m1)); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __x.__i.__h = n1; __x.__i.__l = n0; \
+ __asm__ ("dr %0,%2" \
+ : "=r" (__x.__ll) \
+ : "0" (__x.__ll), "r" (d)); \
+ (q) = __x.__i.__l; (r) = __x.__i.__h; \
+ } while (0)
+#endif
+
+#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl %5,%k1\n\tadcl %3,%k0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl %5,%k1\n\tsbbl %3,%k0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mull %3" \
+ : "=a" (w0), "=d" (w1) \
+ : "%0" ((USItype)(u)), "rm" ((USItype)(v)))
+#define udiv_qrnnd(q, r, n1, n0, dx) /* d renamed to dx avoiding "=d" */\
+ __asm__ ("divl %4" /* stringification in K&R C */ \
+ : "=a" (q), "=d" (r) \
+ : "0" ((USItype)(n0)), "1" ((USItype)(n1)), "rm" ((USItype)(dx)))
+
+#if HAVE_HOST_CPU_i586 || HAVE_HOST_CPU_pentium || HAVE_HOST_CPU_pentiummmx
+/* Pentium bsrl takes between 10 and 72 cycles depending where the most
+ significant 1 bit is, hence the use of the following alternatives. bsfl
+ is slow too, between 18 and 42 depending where the least significant 1
+ bit is, so let the generic count_trailing_zeros below make use of the
+ count_leading_zeros here too. */
+
+#if HAVE_HOST_CPU_pentiummmx && ! defined (LONGLONG_STANDALONE)
+/* The following should be a fixed 14 or 15 cycles, but possibly plus an L1
+ cache miss reading from __clz_tab. For P55 it's favoured over the float
+ below so as to avoid mixing MMX and x87, since the penalty for switching
+ between the two is about 100 cycles.
+
+ The asm block sets __shift to -3 if the high 24 bits are clear, -2 for
+ 16, -1 for 8, or 0 otherwise. This could be written equivalently as
+ follows, but as of gcc 2.95.2 it results in conditional jumps.
+
+ __shift = -(__n < 0x1000000);
+ __shift -= (__n < 0x10000);
+ __shift -= (__n < 0x100);
+
+ The middle two sbbl and cmpl's pair, and with luck something gcc
+ generates might pair with the first cmpl and the last sbbl. The "32+1"
+ constant could be folded into __clz_tab[], but it doesn't seem worth
+ making a different table just for that. */
+
+#define count_leading_zeros(c,n) \
+ do { \
+ USItype __n = (n); \
+ USItype __shift; \
+ __asm__ ("cmpl $0x1000000, %1\n" \
+ "sbbl %0, %0\n" \
+ "cmpl $0x10000, %1\n" \
+ "sbbl $0, %0\n" \
+ "cmpl $0x100, %1\n" \
+ "sbbl $0, %0\n" \
+ : "=&r" (__shift) : "r" (__n)); \
+ __shift = __shift*8 + 24 + 1; \
+ (c) = 32 + 1 - __shift - __clz_tab[__n >> __shift]; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#define COUNT_LEADING_ZEROS_0 31 /* n==0 indistinguishable from n==1 */
+
+#else /* ! pentiummmx || LONGLONG_STANDALONE */
+/* The following should be a fixed 14 cycles or so. Some scheduling
+ opportunities should be available between the float load/store too. This
+ sort of code is used in gcc 3 for __builtin_ffs (with "n&-n") and is
+ apparently suggested by the Intel optimizing manual (don't know exactly
+ where). gcc 2.95 or up will be best for this, so the "double" is
+ correctly aligned on the stack. */
+#define count_leading_zeros(c,n) \
+ do { \
+ union { \
+ double d; \
+ unsigned a[2]; \
+ } __u; \
+ ASSERT ((n) != 0); \
+ __u.d = (UWtype) (n); \
+ (c) = 0x3FF + 31 - (__u.a[1] >> 20); \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 (0x3FF + 31)
+#endif /* pentiummx */
+
+#else /* ! pentium */
+
+#if __GMP_GNUC_PREREQ (3,4) /* using bsrl */
+#define count_leading_zeros(count,x) count_leading_zeros_gcc_clz(count,x)
+#endif /* gcc clz */
+
+/* On P6, gcc prior to 3.0 generates a partial register stall for
+ __cbtmp^31, due to using "xorb $31" instead of "xorl $31", the former
+ being 1 code byte smaller. "31-__cbtmp" is a workaround, probably at the
+ cost of one extra instruction. Do this for "i386" too, since that means
+ generic x86. */
+#if ! defined (count_leading_zeros) && __GNUC__ < 3 \
+ && (HAVE_HOST_CPU_i386 \
+ || HAVE_HOST_CPU_i686 \
+ || HAVE_HOST_CPU_pentiumpro \
+ || HAVE_HOST_CPU_pentium2 \
+ || HAVE_HOST_CPU_pentium3)
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsrl %1,%0" : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ (count) = 31 - __cbtmp; \
+ } while (0)
+#endif /* gcc<3 asm bsrl */
+
+#ifndef count_leading_zeros
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsrl %1,%0" : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#endif /* asm bsrl */
+
+#if __GMP_GNUC_PREREQ (3,4) /* using bsfl */
+#define count_trailing_zeros(count,x) count_trailing_zeros_gcc_ctz(count,x)
+#endif /* gcc ctz */
+
+#ifndef count_trailing_zeros
+#define count_trailing_zeros(count, x) \
+ do { \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsfl %1,%k0" : "=r" (count) : "rm" ((USItype)(x))); \
+ } while (0)
+#endif /* asm bsfl */
+
+#endif /* ! pentium */
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 10
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME 40
+#endif
+#endif /* 80x86 */
+
+#if defined (__amd64__) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addq %5,%q1\n\tadcq %3,%q0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((UDItype)(ah)), "rme" ((UDItype)(bh)), \
+ "%1" ((UDItype)(al)), "rme" ((UDItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subq %5,%q1\n\tsbbq %3,%q0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((UDItype)(ah)), "rme" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), "rme" ((UDItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulq %3" \
+ : "=a" (w0), "=d" (w1) \
+ : "%0" ((UDItype)(u)), "rm" ((UDItype)(v)))
+#define udiv_qrnnd(q, r, n1, n0, dx) /* d renamed to dx avoiding "=d" */\
+ __asm__ ("divq %4" /* stringification in K&R C */ \
+ : "=a" (q), "=d" (r) \
+ : "0" ((UDItype)(n0)), "1" ((UDItype)(n1)), "rm" ((UDItype)(dx)))
+/* bsrq destination must be a 64-bit register, hence UDItype for __cbtmp. */
+#define count_leading_zeros(count, x) \
+ do { \
+ UDItype __cbtmp; \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsrq %1,%0" : "=r" (__cbtmp) : "rm" ((UDItype)(x))); \
+ (count) = __cbtmp ^ 63; \
+ } while (0)
+/* bsfq destination must be a 64-bit register, "%q0" forces this in case
+ count is only an int. */
+#define count_trailing_zeros(count, x) \
+ do { \
+ ASSERT ((x) != 0); \
+ __asm__ ("bsfq %1,%q0" : "=r" (count) : "rm" ((UDItype)(x))); \
+ } while (0)
+#endif /* x86_64 */
+
+#if defined (__i860__) && W_TYPE_SIZE == 32
+#define rshift_rhlc(r,h,l,c) \
+ __asm__ ("shr %3,r0,r0\;shrd %1,%2,%0" \
+ "=r" (r) : "r" (h), "r" (l), "rn" (c))
+#endif /* i860 */
+
+#if defined (__i960__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 1,0\;addc %5,%4,%1\;addc %3,%2,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "dI" (ah), "dI" (bh), "%dI" (al), "dI" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 0,0\;subc %5,%4,%1\;subc %3,%2,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "dI" (ah), "dI" (bh), "dI" (al), "dI" (bl))
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__x.__ll) : "%dI" (u), "dI" (v)); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("emul %2,%1,%0" : "=d" (__w) : "%dI" (u), "dI" (v)); \
+ __w; })
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (nh); __nn.__i.__l = (nl); \
+ __asm__ ("ediv %d,%n,%0" \
+ : "=d" (__rq.__ll) : "dI" (__nn.__ll), "dI" (d)); \
+ (r) = __rq.__i.__l; (q) = __rq.__i.__h; \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("scanbit %1,%0" : "=r" (__cbtmp) : "r" (x)); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
+#if defined (__i960mx) /* what is the proper symbol to test??? */
+#define rshift_rhlc(r,h,l,c) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (h); __nn.__i.__l = (l); \
+ __asm__ ("shre %2,%1,%0" : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
+ }
+#endif /* i960mx */
+#endif /* i960 */
+
+#if (defined (__mc68000__) || defined (__mc68020__) || defined(mc68020) \
+ || defined (__m68k__) || defined (__mc5200__) || defined (__mc5206e__) \
+ || defined (__mc5307__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \
+ : "=d" (sh), "=&d" (sl) \
+ : "0" ((USItype)(ah)), "d" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \
+ : "=d" (sh), "=&d" (sl) \
+ : "0" ((USItype)(ah)), "d" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */
+#if defined (__mc68020__) || defined(mc68020) \
+ || defined (__mc68030__) || defined (mc68030) \
+ || defined (__mc68040__) || defined (mc68040) \
+ || defined (__mcpu32__) || defined (mcpu32) \
+ || defined (__NeXT__)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulu%.l %3,%1:%0" \
+ : "=d" (w0), "=d" (w1) \
+ : "%0" ((USItype)(u)), "dmi" ((USItype)(v)))
+#define UMUL_TIME 45
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divu%.l %4,%1:%0" \
+ : "=d" (q), "=d" (r) \
+ : "0" ((USItype)(n0)), "1" ((USItype)(n1)), "dmi" ((USItype)(d)))
+#define UDIV_TIME 90
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divs%.l %4,%1:%0" \
+ : "=d" (q), "=d" (r) \
+ : "0" ((USItype)(n0)), "1" ((USItype)(n1)), "dmi" ((USItype)(d)))
+#else /* for other 68k family members use 16x16->32 multiplication */
+#define umul_ppmm(xh, xl, a, b) \
+ do { USItype __umul_tmp1, __umul_tmp2; \
+ __asm__ ("| Inlined umul_ppmm\n" \
+" move%.l %5,%3\n" \
+" move%.l %2,%0\n" \
+" move%.w %3,%1\n" \
+" swap %3\n" \
+" swap %0\n" \
+" mulu%.w %2,%1\n" \
+" mulu%.w %3,%0\n" \
+" mulu%.w %2,%3\n" \
+" swap %2\n" \
+" mulu%.w %5,%2\n" \
+" add%.l %3,%2\n" \
+" jcc 1f\n" \
+" add%.l %#0x10000,%0\n" \
+"1: move%.l %2,%3\n" \
+" clr%.w %2\n" \
+" swap %2\n" \
+" swap %3\n" \
+" clr%.w %3\n" \
+" add%.l %3,%1\n" \
+" addx%.l %2,%0\n" \
+" | End inlined umul_ppmm" \
+ : "=&d" (xh), "=&d" (xl), \
+ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
+ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
+ } while (0)
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+#endif /* not mc68020 */
+/* The '020, '030, '040 and '060 have bitfield insns.
+ GCC 3.4 defines __mc68020__ when in CPU32 mode, check for __mcpu32__ to
+ exclude bfffo on that chip (bitfield insns not available). */
+#if (defined (__mc68020__) || defined (mc68020) \
+ || defined (__mc68030__) || defined (mc68030) \
+ || defined (__mc68040__) || defined (mc68040) \
+ || defined (__mc68060__) || defined (mc68060) \
+ || defined (__NeXT__)) \
+ && ! defined (__mcpu32__)
+#define count_leading_zeros(count, x) \
+ __asm__ ("bfffo %1{%b2:%b2},%0" \
+ : "=d" (count) \
+ : "od" ((USItype) (x)), "n" (0))
+#define COUNT_LEADING_ZEROS_0 32
+#endif
+#endif /* mc68000 */
+
+#if defined (__m88000__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rJ" (bh), "%rJ" (al), "rJ" (bl))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rJ" (bh), "rJ" (al), "rJ" (bl))
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("ff1 %0,%1" : "=r" (__cbtmp) : "r" (x)); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 63 /* sic */
+#if defined (__m88110__)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \
+ (wh) = __x.__i.__h; \
+ (wl) = __x.__i.__l; \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x, __q; \
+ __x.__i.__h = (n1); __x.__i.__l = (n0); \
+ __asm__ ("divu.d %0,%1,%2" \
+ : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \
+ (r) = (n0) - __q.__l * (d); (q) = __q.__l; })
+#define UMUL_TIME 5
+#define UDIV_TIME 25
+#else
+#define UMUL_TIME 17
+#define UDIV_TIME 150
+#endif /* __m88110__ */
+#endif /* __m88000__ */
+
+#if defined (__mips) && W_TYPE_SIZE == 32
+#if __GMP_GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UDItype __ll = (UDItype)(u) * (v); \
+ w1 = __ll >> 32; \
+ w0 = __ll; \
+ } while (0)
+#endif
+#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v))
+#endif
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3\n\tmflo %0\n\tmfhi %1" \
+ : "=d" (w0), "=d" (w1) : "d" (u), "d" (v))
+#endif
+#define UMUL_TIME 10
+#define UDIV_TIME 100
+#endif /* __mips */
+
+#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
+#if __GMP_GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
+ __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \
+ w1 = __ll >> 64; \
+ w0 = __ll; \
+ } while (0)
+#endif
+#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v))
+#endif
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3\n\tmflo %0\n\tmfhi %1" \
+ : "=d" (w0), "=d" (w1) : "d" (u), "d" (v))
+#endif
+#define UMUL_TIME 20
+#define UDIV_TIME 140
+#endif /* __mips */
+
+#if defined (__mmix__) && W_TYPE_SIZE == 64
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("MULU %0,%2,%3" : "=r" (w0), "=z" (w1) : "r" (u), "r" (v))
+#endif
+
+#if defined (__ns32000__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__x.__ll) \
+ : "%0" ((USItype)(u)), "g" ((USItype)(v))); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__w) \
+ : "%0" ((USItype)(u)), "g" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ __x.__i.__h = (n1); __x.__i.__l = (n0); \
+ __asm__ ("deid %2,%0" \
+ : "=g" (__x.__ll) \
+ : "0" (__x.__ll), "g" ((USItype)(d))); \
+ (r) = __x.__i.__l; (q) = __x.__i.__h; })
+#define count_trailing_zeros(count,x) \
+ do { \
+ __asm__ ("ffsd %2,%0" \
+ : "=r" (count) \
+ : "0" ((USItype) 0), "r" ((USItype) (x))); \
+ } while (0)
+#endif /* __ns32000__ */
+
+/* In the past we had a block of various #defines tested
+ _ARCH_PPC - AIX
+ _ARCH_PWR - AIX
+ __powerpc__ - gcc
+ __POWERPC__ - BEOS
+ __ppc__ - Darwin
+ PPC - old gcc, GNU/Linux, SysV
+ The plain PPC test was not good for vxWorks, since PPC is defined on all
+ CPUs there (eg. m68k too), as a constant one is expected to compare
+ CPU_FAMILY against.
+
+ At any rate, this was pretty unattractive and a bit fragile. The use of
+ HAVE_HOST_CPU_FAMILY is designed to cut through it all and be sure of
+ getting the desired effect.
+
+ ENHANCE-ME: We should test _IBMR2 here when we add assembly support for
+ the system vendor compilers. (Is that vendor compilers with inline asm,
+ or what?) */
+
+#if (HAVE_HOST_CPU_FAMILY_power || HAVE_HOST_CPU_FAMILY_powerpc) \
+ && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 32
+#if HAVE_HOST_CPU_FAMILY_powerpc
+#if __GMP_GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UDItype __ll = (UDItype)(u) * (v); \
+ w1 = __ll >> 32; \
+ w0 = __ll; \
+ } while (0)
+#endif
+#if !defined (umul_ppmm)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#endif
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ SItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14
+#define UDIV_TIME 120
+#else
+#define UMUL_TIME 8
+#define smul_ppmm(xh, xl, m0, m1) \
+ __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1))
+#define SMUL_TIME 4
+#define sdiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d))
+#define UDIV_TIME 100
+#endif
+#endif /* 32-bit POWER architecture variants. */
+
+/* We should test _IBMR2 here when we add assembly support for the system
+ vendor compilers. */
+#if HAVE_HOST_CPU_FAMILY_powerpc && W_TYPE_SIZE == 64
+#if !defined (_LONG_LONG_LIMB)
+/* _LONG_LONG_LIMB is ABI=mode32 where adde operates on 32-bit values. So
+ use adde etc only when not _LONG_LONG_LIMB. */
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
+ } while (0)
+/* We use "*rI" for the constant operand here, since with just "I", gcc barfs.
+ This might seem strange, but gcc folds away the dead code late. */
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bl) && bl > -0x8000 && bl <= 0x8000) { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{ai|addic} %1,%3,%4\n\t{sfze|subfze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "*rI" (-bl)); \
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("{ai|addic} %1,%3,%4\n\t{sfme|subfme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "*rI" (-bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{ai|addic} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "*rI" (-bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("{ai|addic} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "*rI" (-bl)); \
+ else \
+ __asm__ ("{ai|addic} %1,%4,%5\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "rI" (al), "*rI" (-bl)); \
+ } else { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl)); \
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl)); \
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl)); \
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
+ } \
+ } while (0)
+#endif /* ! _LONG_LONG_LIMB */
+#define count_leading_zeros(count, x) \
+ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 64
+#if __GMP_GNUC_PREREQ (4,4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
+ __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \
+ w1 = __ll >> 64; \
+ w0 = __ll; \
+ } while (0)
+#endif
+#if !defined (umul_ppmm)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#endif
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ DItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14 /* ??? */
+#define UDIV_TIME 120 /* ??? */
+#endif /* 64-bit PowerPC. */
+
+#if defined (__pyr__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addw %5,%1\n\taddwc %3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subw %5,%1\n\tsubwb %3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("movw %1,%R0\n\tuemul %2,%0" \
+ : "=&r" (__x.__ll) \
+ : "g" ((USItype) (u)), "g" ((USItype)(v))); \
+ (w1) = __x.__i.__h; (w0) = __x.__i.__l;})
+#endif /* __pyr__ */
+
+#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("a %1,%5\n\tae %0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "r" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "r" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("s %1,%5\n\tse %0,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((USItype)(ah)), "r" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "r" ((USItype)(bl)))
+#define smul_ppmm(ph, pl, m0, m1) \
+ __asm__ ( \
+ "s r2,r2\n" \
+" mts r10,%2\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" m r2,%3\n" \
+" cas %0,r2,r0\n" \
+" mfs r10,%1" \
+ : "=r" (ph), "=r" (pl) \
+ : "%r" ((USItype)(m0)), "r" ((USItype)(m1)) \
+ : "r2")
+#define UMUL_TIME 20
+#define UDIV_TIME 200
+#define count_leading_zeros(count, x) \
+ do { \
+ if ((x) >= 0x10000) \
+ __asm__ ("clz %0,%1" \
+ : "=r" (count) : "r" ((USItype)(x) >> 16)); \
+ else \
+ { \
+ __asm__ ("clz %0,%1" \
+ : "=r" (count) : "r" ((USItype)(x))); \
+ (count) += 16; \
+ } \
+ } while (0)
+#endif /* RT/ROMP */
+
+#if defined (__sh2__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \
+ : "=r" (w1), "=r" (w0) : "r" (u), "r" (v) : "macl", "mach")
+#define UMUL_TIME 5
+#endif
+
+#if defined (__sparc__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh),"%rJ" (al), "rI" (bl) \
+ __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "rJ" (al), "rI" (bl) \
+ __CLOBBER_CC)
+/* Note: the following FIXME comes from GMP, thus it does make sense to try
+ to resolve it in MPFR. */
+/* FIXME: When gcc -mcpu=v9 is used on solaris, gcc/config/sol2-sld-64.h
+ doesn't define anything to indicate that to us, it only sets __sparcv8. */
+#if defined (__sparc_v9__) || defined (__sparcv9)
+/* Perhaps we should use floating-point operations here? */
+#if 0
+/* Triggers a bug making mpz/tests/t-gcd.c fail.
+ Perhaps we simply need explicitly zero-extend the inputs? */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulx %2,%3,%%g1; srl %%g1,0,%1; srlx %%g1,32,%0" : \
+ "=r" (w1), "=r" (w0) : "r" (u), "r" (v) : "g1")
+#else
+/* Use v8 umul until above bug is fixed. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" : "=r" (w1), "=r" (w0) : "r" (u), "r" (v))
+#endif
+/* Use a plain v8 divide for v9. */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ USItype __q; \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" (__q) : "r" (n1), "r" (n0), "r" (d)); \
+ (r) = (n0) - __q * (d); \
+ (q) = __q; \
+ } while (0)
+#else
+#if defined (__sparc_v8__) /* gcc normal */ \
+ || defined (__sparcv8) /* gcc solaris */ \
+ || HAVE_HOST_CPU_supersparc
+/* Don't match immediate range because, 1) it is not often useful,
+ 2) the 'I' flag thinks of the range as a 13 bit signed interval,
+ while we want to match a 13 bit interval, sign extended to 32 bits,
+ but INTERPRETED AS UNSIGNED. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" : "=r" (w1), "=r" (w0) : "r" (u), "r" (v))
+#define UMUL_TIME 5
+
+#if HAVE_HOST_CPU_supersparc
+#define UDIV_TIME 60 /* SuperSPARC timing */
+#else
+/* Don't use this on SuperSPARC because its udiv only handles 53 bit
+ dividends and will trap to the kernel for the rest. */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ USItype __q; \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" (__q) : "r" (n1), "r" (n0), "r" (d)); \
+ (r) = (n0) - __q * (d); \
+ (q) = __q; \
+ } while (0)
+#define UDIV_TIME 25
+#endif /* HAVE_HOST_CPU_supersparc */
+
+#else /* ! __sparc_v8__ */
+#if defined (__sparclite__)
+/* This has hardware multiply but not divide. It also has two additional
+ instructions scan (ffs from high bit) and divscc. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" : "=r" (w1), "=r" (w0) : "r" (u), "r" (v))
+#define UMUL_TIME 5
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("! Inlined udiv_qrnnd\n" \
+" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \
+" tst %%g0\n" \
+" divscc %3,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%%g1\n" \
+" divscc %%g1,%4,%0\n" \
+" rd %%y,%1\n" \
+" bl,a 1f\n" \
+" add %1,%4,%1\n" \
+"1: ! End of inline udiv_qrnnd" \
+ : "=r" (q), "=r" (r) : "r" (n1), "r" (n0), "rI" (d) \
+ : "%g1" __AND_CLOBBER_CC)
+#define UDIV_TIME 37
+#define count_leading_zeros(count, x) \
+ __asm__ ("scan %1,1,%0" : "=r" (count) : "r" (x))
+/* Early sparclites return 63 for an argument of 0, but they warn that future
+ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
+ undefined. */
+#endif /* __sparclite__ */
+#endif /* __sparc_v8__ */
+#endif /* __sparc_v9__ */
+/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
+#ifndef umul_ppmm
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("! Inlined umul_ppmm\n" \
+" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n" \
+" sra %3,31,%%g2 ! Don't move this insn\n" \
+" and %2,%%g2,%%g2 ! Don't move this insn\n" \
+" andcc %%g0,0,%%g1 ! Don't move this insn\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,%3,%%g1\n" \
+" mulscc %%g1,0,%%g1\n" \
+" add %%g1,%%g2,%0\n" \
+" rd %%y,%1" \
+ : "=r" (w1), "=r" (w0) : "%rI" (u), "r" (v) \
+ : "%g1", "%g2" __AND_CLOBBER_CC)
+#define UMUL_TIME 39 /* 39 instructions */
+#endif
+#ifndef udiv_qrnnd
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UWtype __r; \
+ (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UWtype __MPN(udiv_qrnnd) _PROTO ((UWtype *, UWtype, UWtype, UWtype));
+#ifndef UDIV_TIME
+#define UDIV_TIME 140
+#endif
+#endif /* LONGLONG_STANDALONE */
+#endif /* udiv_qrnnd */
+#endif /* __sparc__ */
+
+#if defined (__sparc__) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ( \
+ "addcc %r4,%5,%1\n" \
+ " addccc %r6,%7,%%g0\n" \
+ " addc %r2,%3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "%rJ" (al), "rI" (bl), \
+ "%rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ( \
+ "subcc %r4,%5,%1\n" \
+ " subccc %r6,%7,%%g0\n" \
+ " subc %r2,%3,%0" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rJ" (ah), "rI" (bh), "rJ" (al), "rI" (bl), \
+ "rJ" ((al) >> 32), "rI" ((bl) >> 32) \
+ __CLOBBER_CC)
+#endif
+
+#if defined (__vax__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \
+ : "=g" (sh), "=&g" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \
+ : "=g" (sh), "=&g" (sl) \
+ : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), "g" ((USItype)(bl)))
+#define smul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __x; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("emul %1,%2,$0,%0" \
+ : "=g" (__x.__ll) : "g" (__m0), "g" (__m1)); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __x; \
+ __x.__i.__h = n1; __x.__i.__l = n0; \
+ __asm__ ("ediv %3,%2,%0,%1" \
+ : "=g" (q), "=g" (r) : "g" (__x.__ll), "g" (d)); \
+ } while (0)
+#if 0
+/* Note: the following FIXME comes from GMP, thus it does make sense to try
+ to resolve it in MPFR. */
+/* FIXME: This instruction appears to be unimplemented on some systems (vax
+ 8800 maybe). */
+#define count_trailing_zeros(count,x) \
+ do { \
+ __asm__ ("ffs 0, 31, %1, %0" \
+ : "=g" (count) \
+ : "g" ((USItype) (x))); \
+ } while (0)
+#endif
+#endif /* __vax__ */
+
+#if defined (__z8000__) && W_TYPE_SIZE == 16
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((unsigned int)(ah)), "r" ((unsigned int)(bh)), \
+ "%1" ((unsigned int)(al)), "rQR" ((unsigned int)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "0" ((unsigned int)(ah)), "r" ((unsigned int)(bh)), \
+ "1" ((unsigned int)(al)), "rQR" ((unsigned int)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {long int __ll; \
+ struct {unsigned int __h, __l;} __i; \
+ } __x; \
+ unsigned int __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mult %S0,%H3" \
+ : "=r" (__x.__i.__h), "=r" (__x.__i.__l) \
+ : "%1" (m0), "rQR" (m1)); \
+ (xh) = __x.__i.__h; (xl) = __x.__i.__l; \
+ (xh) += ((((signed int) __m0 >> 15) & __m1) \
+ + (((signed int) __m1 >> 15) & __m0)); \
+ } while (0)
+#endif /* __z8000__ */
+
+#endif /* __GNUC__ */
+
+#endif /* NO_ASM */
+
+
+#if !defined (umul_ppmm) && defined (__umulsidi3)
+#define umul_ppmm(ph, pl, m0, m1) \
+ { \
+ UDWtype __ll = __umulsidi3 (m0, m1); \
+ ph = (UWtype) (__ll >> W_TYPE_SIZE); \
+ pl = (UWtype) __ll; \
+ }
+#endif
+
+#if !defined (__umulsidi3)
+#define __umulsidi3(u, v) \
+ ({UWtype __hi, __lo; \
+ umul_ppmm (__hi, __lo, u, v); \
+ ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
+#endif
+
+
+/* Use mpn_umul_ppmm or mpn_udiv_qrnnd functions, if they exist. The "_r"
+ forms have "reversed" arguments, meaning the pointer is last, which
+ sometimes allows better parameter passing, in particular on 64-bit
+ hppa. */
+
+#define mpn_umul_ppmm __MPN(umul_ppmm)
+extern UWtype mpn_umul_ppmm _PROTO ((UWtype *, UWtype, UWtype));
+
+#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm \
+ && ! defined (LONGLONG_STANDALONE)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ UWtype __umul_ppmm__p0; \
+ (wh) = mpn_umul_ppmm (&__umul_ppmm__p0, (UWtype) (u), (UWtype) (v)); \
+ (wl) = __umul_ppmm__p0; \
+ } while (0)
+#endif
+
+#define mpn_umul_ppmm_r __MPN(umul_ppmm_r)
+extern UWtype mpn_umul_ppmm_r _PROTO ((UWtype, UWtype, UWtype *));
+
+#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm_r \
+ && ! defined (LONGLONG_STANDALONE)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ UWtype __umul_ppmm__p0; \
+ (wh) = mpn_umul_ppmm_r ((UWtype) (u), (UWtype) (v), &__umul_ppmm__p0); \
+ (wl) = __umul_ppmm__p0; \
+ } while (0)
+#endif
+
+#define mpn_udiv_qrnnd __MPN(udiv_qrnnd)
+extern UWtype mpn_udiv_qrnnd _PROTO ((UWtype *, UWtype, UWtype, UWtype));
+
+#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd \
+ && ! defined (LONGLONG_STANDALONE)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ UWtype __udiv_qrnnd__r; \
+ (q) = mpn_udiv_qrnnd (&__udiv_qrnnd__r, \
+ (UWtype) (n1), (UWtype) (n0), (UWtype) d); \
+ (r) = __udiv_qrnnd__r; \
+ } while (0)
+#endif
+
+#define mpn_udiv_qrnnd_r __MPN(udiv_qrnnd_r)
+extern UWtype mpn_udiv_qrnnd_r _PROTO ((UWtype, UWtype, UWtype, UWtype *));
+
+#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd_r \
+ && ! defined (LONGLONG_STANDALONE)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ UWtype __udiv_qrnnd__r; \
+ (q) = mpn_udiv_qrnnd_r ((UWtype) (n1), (UWtype) (n0), (UWtype) d, \
+ &__udiv_qrnnd__r); \
+ (r) = __udiv_qrnnd__r; \
+ } while (0)
+#endif
+
+
+/* If this machine has no inline assembler, use C macros. */
+
+#if !defined (add_ssaaaa)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) + (bl); \
+ (sh) = (ah) + (bh) + (__x < (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (sub_ddmmss)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - ((al) < (bl)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of
+ smul_ppmm. */
+#if !defined (umul_ppmm) && defined (smul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __w1; \
+ UWtype __xm0 = (u), __xm1 = (v); \
+ smul_ppmm (__w1, w0, __xm0, __xm1); \
+ (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \
+ + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \
+ } while (0)
+#endif
+
+/* If we still don't have umul_ppmm, define it using plain C.
+
+ For reference, when this code is used for squaring (ie. u and v identical
+ expressions), gcc recognises __x1 and __x2 are the same and generates 3
+ multiplies, not 4. The subsequent additions could be optimized a bit,
+ but the only place GMP currently uses such a square is mpn_sqr_basecase,
+ and chips obliged to use this generic C umul will have plenty of worse
+ performance problems than a couple of extra instructions on the diagonal
+ of sqr_basecase. */
+
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __x0, __x1, __x2, __x3; \
+ UHWtype __ul, __vl, __uh, __vh; \
+ UWtype __u = (u), __v = (v); \
+ \
+ __ul = __ll_lowpart (__u); \
+ __uh = __ll_highpart (__u); \
+ __vl = __ll_lowpart (__v); \
+ __vh = __ll_highpart (__v); \
+ \
+ __x0 = (UWtype) __ul * __vl; \
+ __x1 = (UWtype) __ul * __vh; \
+ __x2 = (UWtype) __uh * __vl; \
+ __x3 = (UWtype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = (__x1 << W_TYPE_SIZE/2) + __ll_lowpart (__x0); \
+ } while (0)
+#endif
+
+/* If we don't have smul_ppmm, define it using umul_ppmm (which surely will
+ exist in one form or another. */
+#if !defined (smul_ppmm)
+#define smul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __w1; \
+ UWtype __xm0 = (u), __xm1 = (v); \
+ umul_ppmm (__w1, w0, __xm0, __xm1); \
+ (w1) = __w1 - (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \
+ - (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \
+ } while (0)
+#endif
+
+/* Define this unconditionally, so it can be used for debugging. */
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
+ \
+ ASSERT ((d) != 0); \
+ ASSERT ((n1) < (d)); \
+ \
+ __d1 = __ll_highpart (d); \
+ __d0 = __ll_lowpart (d); \
+ \
+ __q1 = (n1) / __d1; \
+ __r1 = (n1) - __q1 * __d1; \
+ __m = __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
+ if (__r1 < __m) \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __q0 = __r1 / __d1; \
+ __r0 = __r1 - __q0 * __d1; \
+ __m = __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
+ if (__r0 < __m) \
+ { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
+ __udiv_w_sdiv (defined in libgcc or elsewhere). */
+#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ UWtype __r; \
+ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
+ (r) = __r; \
+ } while (0)
+#endif
+
+/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
+#if !defined (udiv_qrnnd)
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+#endif
+
+#if !defined (count_leading_zeros)
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype __xr = (x); \
+ UWtype __a; \
+ \
+ if (W_TYPE_SIZE == 32) \
+ { \
+ __a = __xr < ((UWtype) 1 << 2*__BITS4) \
+ ? (__xr < ((UWtype) 1 << __BITS4) ? 1 : __BITS4 + 1) \
+ : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 + 1 \
+ : 3*__BITS4 + 1); \
+ } \
+ else \
+ { \
+ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
+ if (((__xr >> __a) & 0xff) != 0) \
+ break; \
+ ++__a; \
+ } \
+ \
+ (count) = W_TYPE_SIZE + 1 - __a - __clz_tab[__xr >> __a]; \
+ } while (0)
+/* This version gives a well-defined value for zero. */
+#define COUNT_LEADING_ZEROS_0 (W_TYPE_SIZE - 1)
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#endif
+
+/* clz_tab needed by mpn/x86/pentium/mod_1.asm in a fat binary */
+#if HAVE_HOST_CPU_FAMILY_x86 && WANT_FAT_BINARY
+#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+#endif
+
+#ifdef COUNT_LEADING_ZEROS_NEED_CLZ_TAB
+# ifdef MPFR_HAVE_GMP_IMPL
+ extern const unsigned char __GMP_DECLSPEC __clz_tab[128];
+# else
+ extern const unsigned char __clz_tab[128];
+# endif
+#endif
+
+#if !defined (count_trailing_zeros)
+/* Define count_trailing_zeros using count_leading_zeros. The latter might be
+ defined in asm, but if it is not, the C version above is good enough. */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ UWtype __ctz_c; \
+ ASSERT (__ctz_x != 0); \
+ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
+ (count) = W_TYPE_SIZE - 1 - __ctz_c; \
+ } while (0)
+#endif
+
+#ifndef UDIV_NEEDS_NORMALIZATION
+#define UDIV_NEEDS_NORMALIZATION 0
+#endif
+
+/* Whether udiv_qrnnd is actually implemented with udiv_qrnnd_preinv, and
+ that hence the latter should always be used. */
+#ifndef UDIV_PREINV_ALWAYS
+#define UDIV_PREINV_ALWAYS 0
+#endif
+
+/* Give defaults for UMUL_TIME and UDIV_TIME. */
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
diff --git a/mpfr/src/mpfr-thread.h b/mpfr/src/mpfr-thread.h
new file mode 100644
index 0000000000..5dd137bd62
--- /dev/null
+++ b/mpfr/src/mpfr-thread.h
@@ -0,0 +1,48 @@
+/* MPFR internal header related to thread-local variables.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __MPFR_THREAD_H__
+#define __MPFR_THREAD_H__
+
+/* Note: Let's define MPFR_THREAD_ATTR even after a #error to make the
+ error message more visible (e.g. gcc doesn't immediately stop after
+ the #error line and outputs many error messages if MPFR_THREAD_ATTR
+ is not defined). But some compilers will just output a message and
+ may build MPFR "successfully" (without thread support). */
+#ifndef MPFR_THREAD_ATTR
+# ifdef MPFR_USE_THREAD_SAFE
+# if defined(_MSC_VER)
+# if defined(_WINDLL)
+# error "Can't build MPFR DLL as thread safe."
+# define MPFR_THREAD_ATTR
+# else
+# define MPFR_THREAD_ATTR __declspec( thread )
+# endif
+# else
+# define MPFR_THREAD_ATTR __thread
+# endif
+# else
+# define MPFR_THREAD_ATTR
+# endif
+#endif
+
+#endif
diff --git a/mpfr/src/mpfr.h b/mpfr/src/mpfr.h
new file mode 100644
index 0000000000..a3241dcb1c
--- /dev/null
+++ b/mpfr/src/mpfr.h
@@ -0,0 +1,1059 @@
+/* mpfr.h -- Include file for mpfr.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __MPFR_H
+#define __MPFR_H
+
+/* Define MPFR version number */
+#define MPFR_VERSION_MAJOR 3
+#define MPFR_VERSION_MINOR 1
+#define MPFR_VERSION_PATCHLEVEL 2
+#define MPFR_VERSION_STRING "3.1.2"
+
+/* Macros dealing with MPFR VERSION */
+#define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+#define MPFR_VERSION \
+MPFR_VERSION_NUM(MPFR_VERSION_MAJOR,MPFR_VERSION_MINOR,MPFR_VERSION_PATCHLEVEL)
+
+/* Check if GMP is included, and try to include it (Works with local GMP) */
+#ifndef __GMP_H__
+# include <gmp.h>
+#endif
+
+/* GMP's internal __gmp_const macro has been removed on 2012-03-04:
+ http://gmplib.org:8000/gmp/rev/d287cfaf6732
+ const is standard and now assumed to be available. If the __gmp_const
+ definition is no longer present in GMP, this probably means that GMP
+ assumes that const is available; thus let's define it to const.
+ Note: this is a temporary fix that can be backported to previous MPFR
+ versions. In the future, __gmp_const should be replaced by const like
+ in GMP. */
+#ifndef __gmp_const
+# define __gmp_const const
+#endif
+
+/* Avoid some problems with macro expansion if the user defines macros
+ with the same name as keywords. By convention, identifiers and macro
+ names starting with mpfr_ are reserved by MPFR. */
+typedef void mpfr_void;
+typedef int mpfr_int;
+typedef unsigned int mpfr_uint;
+typedef long mpfr_long;
+typedef unsigned long mpfr_ulong;
+typedef size_t mpfr_size_t;
+
+/* Definition of rounding modes (DON'T USE MPFR_RNDNA!).
+ Warning! Changing the contents of this enum should be seen as an
+ interface change since the old and the new types are not compatible
+ (the integer type compatible with the enumerated type can even change,
+ see ISO C99, 6.7.2.2#4), and in Makefile.am, AGE should be set to 0.
+
+ MPFR_RNDU must appear just before MPFR_RNDD (see
+ MPFR_IS_RNDUTEST_OR_RNDDNOTTEST in mpfr-impl.h).
+
+ MPFR_RNDF has been added, though not implemented yet, in order to avoid
+ to break the ABI once faithful rounding gets implemented.
+
+ If you change the order of the rounding modes, please update the routines
+ in texceptions.c which assume 0=RNDN, 1=RNDZ, 2=RNDU, 3=RNDD, 4=RNDA.
+*/
+typedef enum {
+ MPFR_RNDN=0, /* round to nearest, with ties to even */
+ MPFR_RNDZ, /* round toward zero */
+ MPFR_RNDU, /* round toward +Inf */
+ MPFR_RNDD, /* round toward -Inf */
+ MPFR_RNDA, /* round away from zero */
+ MPFR_RNDF, /* faithful rounding (not implemented yet) */
+ MPFR_RNDNA=-1 /* round to nearest, with ties away from zero (mpfr_round) */
+} mpfr_rnd_t;
+
+/* kept for compatibility with MPFR 2.4.x and before */
+#define GMP_RNDN MPFR_RNDN
+#define GMP_RNDZ MPFR_RNDZ
+#define GMP_RNDU MPFR_RNDU
+#define GMP_RNDD MPFR_RNDD
+
+/* Note: With the following default choices for _MPFR_PREC_FORMAT and
+ _MPFR_EXP_FORMAT, mpfr_exp_t will be the same as [mp_exp_t] (at least
+ up to GMP 5). */
+
+/* Define precision: 1 (short), 2 (int) or 3 (long) (DON'T USE IT!) */
+#ifndef _MPFR_PREC_FORMAT
+# if __GMP_MP_SIZE_T_INT == 1
+# define _MPFR_PREC_FORMAT 2
+# else
+# define _MPFR_PREC_FORMAT 3
+# endif
+#endif
+
+/* Define exponent: 1 (short), 2 (int), 3 (long) or 4 (intmax_t)
+ (DON'T USE IT!) */
+#ifndef _MPFR_EXP_FORMAT
+# define _MPFR_EXP_FORMAT _MPFR_PREC_FORMAT
+#endif
+
+#if _MPFR_PREC_FORMAT > _MPFR_EXP_FORMAT
+# error "mpfr_prec_t must not be larger than mpfr_exp_t"
+#endif
+
+/* Let's make mpfr_prec_t signed in order to avoid problems due to the
+ usual arithmetic conversions when mixing mpfr_prec_t and mpfr_exp_t
+ in an expression (for error analysis) if casts are forgotten. */
+#if _MPFR_PREC_FORMAT == 1
+typedef short mpfr_prec_t;
+typedef unsigned short mpfr_uprec_t;
+#elif _MPFR_PREC_FORMAT == 2
+typedef int mpfr_prec_t;
+typedef unsigned int mpfr_uprec_t;
+#elif _MPFR_PREC_FORMAT == 3
+typedef long mpfr_prec_t;
+typedef unsigned long mpfr_uprec_t;
+#else
+# error "Invalid MPFR Prec format"
+#endif
+
+/* Definition of precision limits without needing <limits.h> */
+/* Note: the casts allows the expression to yield the wanted behavior
+ for _MPFR_PREC_FORMAT == 1 (due to integer promotion rules). */
+#define MPFR_PREC_MIN 2
+#define MPFR_PREC_MAX ((mpfr_prec_t)((mpfr_uprec_t)(~(mpfr_uprec_t)0)>>1))
+
+/* Definition of sign */
+typedef int mpfr_sign_t;
+
+/* Definition of the exponent. _MPFR_EXP_FORMAT must be large enough
+ so that mpfr_exp_t has at least 32 bits. */
+#if _MPFR_EXP_FORMAT == 1
+typedef short mpfr_exp_t;
+typedef unsigned short mpfr_uexp_t;
+#elif _MPFR_EXP_FORMAT == 2
+typedef int mpfr_exp_t;
+typedef unsigned int mpfr_uexp_t;
+#elif _MPFR_EXP_FORMAT == 3
+typedef long mpfr_exp_t;
+typedef unsigned long mpfr_uexp_t;
+#elif _MPFR_EXP_FORMAT == 4
+/* Note: in this case, intmax_t and uintmax_t must be defined before
+ the inclusion of mpfr.h (we do not include <stdint.h> here because
+ of some non-ISO C99 implementations that support these types). */
+typedef intmax_t mpfr_exp_t;
+typedef uintmax_t mpfr_uexp_t;
+#else
+# error "Invalid MPFR Exp format"
+#endif
+
+/* Definition of the standard exponent limits */
+#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((mpfr_ulong) 1 << 30) - 1))
+#define MPFR_EMIN_DEFAULT (-(MPFR_EMAX_DEFAULT))
+
+/* DON'T USE THIS! (For MPFR-public macros only, see below.)
+ The mpfr_sgn macro uses the fact that __MPFR_EXP_NAN and __MPFR_EXP_ZERO
+ are the smallest values. */
+#define __MPFR_EXP_MAX ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1))
+#define __MPFR_EXP_NAN (1 - __MPFR_EXP_MAX)
+#define __MPFR_EXP_ZERO (0 - __MPFR_EXP_MAX)
+#define __MPFR_EXP_INF (2 - __MPFR_EXP_MAX)
+
+/* Definition of the main structure */
+typedef struct {
+ mpfr_prec_t _mpfr_prec;
+ mpfr_sign_t _mpfr_sign;
+ mpfr_exp_t _mpfr_exp;
+ mp_limb_t *_mpfr_d;
+} __mpfr_struct;
+
+/* Compatibility with previous types of MPFR */
+#ifndef mp_rnd_t
+# define mp_rnd_t mpfr_rnd_t
+#endif
+#ifndef mp_prec_t
+# define mp_prec_t mpfr_prec_t
+#endif
+
+/*
+ The represented number is
+ _sign*(_d[k-1]/B+_d[k-2]/B^2+...+_d[0]/B^k)*2^_exp
+ where k=ceil(_mp_prec/GMP_NUMB_BITS) and B=2^GMP_NUMB_BITS.
+
+ For the msb (most significant bit) normalized representation, we must have
+ _d[k-1]>=B/2, unless the number is singular.
+
+ We must also have the last k*GMP_NUMB_BITS-_prec bits set to zero.
+*/
+
+typedef __mpfr_struct mpfr_t[1];
+typedef __mpfr_struct *mpfr_ptr;
+typedef __gmp_const __mpfr_struct *mpfr_srcptr;
+
+/* For those who need a direct and fast access to the sign field.
+ However it is not in the API, thus use it at your own risk: it might
+ not be supported, or change name, in further versions!
+ Unfortunately, it must be defined here (instead of MPFR's internal
+ header file mpfr-impl.h) because it is used by some macros below.
+*/
+#define MPFR_SIGN(x) ((x)->_mpfr_sign)
+
+/* Stack interface */
+typedef enum {
+ MPFR_NAN_KIND = 0,
+ MPFR_INF_KIND = 1, MPFR_ZERO_KIND = 2, MPFR_REGULAR_KIND = 3
+} mpfr_kind_t;
+
+/* GMP defines:
+ + size_t: Standard size_t
+ + __GMP_ATTRIBUTE_PURE Attribute for math functions.
+ + __GMP_NOTHROW For C++: can't throw .
+ + __GMP_EXTERN_INLINE Attribute for inline function.
+ * __gmp_const const (Supports for K&R compiler only for mpfr.h).
+ + __GMP_DECLSPEC_EXPORT compiling to go into a DLL
+ + __GMP_DECLSPEC_IMPORT compiling to go into a application
+*/
+/* Extra MPFR defines */
+#define __MPFR_SENTINEL_ATTR
+#if defined (__GNUC__)
+# if __GNUC__ >= 4
+# undef __MPFR_SENTINEL_ATTR
+# define __MPFR_SENTINEL_ATTR __attribute__ ((sentinel))
+# endif
+#endif
+
+/* Prototypes: Support of K&R compiler */
+#if defined (__GMP_PROTO)
+# define _MPFR_PROTO __GMP_PROTO
+#elif defined (__STDC__) || defined (__cplusplus)
+# define _MPFR_PROTO(x) x
+#else
+# define _MPFR_PROTO(x) ()
+#endif
+/* Support for WINDOWS Dll:
+ Check if we are inside a MPFR build, and if so export the functions.
+ Otherwise does the same thing as GMP */
+#if defined(__MPFR_WITHIN_MPFR) && __GMP_LIBGMP_DLL
+# define __MPFR_DECLSPEC __GMP_DECLSPEC_EXPORT
+#else
+# define __MPFR_DECLSPEC __GMP_DECLSPEC
+#endif
+
+/* Use MPFR_DEPRECATED to mark MPFR functions, types or variables as
+ deprecated. Code inspired by Apache Subversion's svn_types.h file. */
+#if defined(__GNUC__) && \
+ (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+# define MPFR_DEPRECATED __attribute__ ((deprecated))
+#elif defined(_MSC_VER) && _MSC_VER >= 1300
+# define MPFR_DEPRECATED __declspec(deprecated)
+#else
+# define MPFR_DEPRECATED
+#endif
+
+/* Note: In order to be declared, some functions need a specific
+ system header to be included *before* "mpfr.h". If the user
+ forgets to include the header, the MPFR function prototype in
+ the user object file is not correct. To avoid wrong results,
+ we raise a linker error in that case by changing their internal
+ name in the library (prefixed by __gmpfr instead of mpfr). See
+ the lines of the form "#define mpfr_xxx __gmpfr_xxx" below. */
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+__MPFR_DECLSPEC __gmp_const char * mpfr_get_version _MPFR_PROTO ((void));
+__MPFR_DECLSPEC __gmp_const char * mpfr_get_patches _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_buildopt_tls_p _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_buildopt_decimal_p _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_buildopt_gmpinternals_p _MPFR_PROTO ((void));
+__MPFR_DECLSPEC __gmp_const char * mpfr_buildopt_tune_case _MPFR_PROTO ((void));
+
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emin _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_set_emin _MPFR_PROTO ((mpfr_exp_t));
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emin_min _MPFR_PROTO ((void));
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emin_max _MPFR_PROTO ((void));
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emax _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_set_emax _MPFR_PROTO ((mpfr_exp_t));
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emax_min _MPFR_PROTO ((void));
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_emax_max _MPFR_PROTO ((void));
+
+__MPFR_DECLSPEC void mpfr_set_default_rounding_mode _MPFR_PROTO((mpfr_rnd_t));
+__MPFR_DECLSPEC mpfr_rnd_t mpfr_get_default_rounding_mode _MPFR_PROTO((void));
+__MPFR_DECLSPEC __gmp_const char *
+ mpfr_print_rnd_mode _MPFR_PROTO((mpfr_rnd_t));
+
+__MPFR_DECLSPEC void mpfr_clear_flags _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_clear_underflow _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_clear_overflow _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_clear_divby0 _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_clear_nanflag _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_clear_inexflag _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_clear_erangeflag _MPFR_PROTO ((void));
+
+__MPFR_DECLSPEC void mpfr_set_underflow _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_set_overflow _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_set_divby0 _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_set_nanflag _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_set_inexflag _MPFR_PROTO ((void));
+__MPFR_DECLSPEC void mpfr_set_erangeflag _MPFR_PROTO ((void));
+
+__MPFR_DECLSPEC int mpfr_underflow_p _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_overflow_p _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_divby0_p _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_nanflag_p _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_inexflag_p _MPFR_PROTO ((void));
+__MPFR_DECLSPEC int mpfr_erangeflag_p _MPFR_PROTO ((void));
+
+__MPFR_DECLSPEC int
+ mpfr_check_range _MPFR_PROTO ((mpfr_ptr, int, mpfr_rnd_t));
+
+__MPFR_DECLSPEC void mpfr_init2 _MPFR_PROTO ((mpfr_ptr, mpfr_prec_t));
+__MPFR_DECLSPEC void mpfr_init _MPFR_PROTO ((mpfr_ptr));
+__MPFR_DECLSPEC void mpfr_clear _MPFR_PROTO ((mpfr_ptr));
+
+__MPFR_DECLSPEC void
+ mpfr_inits2 _MPFR_PROTO ((mpfr_prec_t, mpfr_ptr, ...)) __MPFR_SENTINEL_ATTR;
+__MPFR_DECLSPEC void
+ mpfr_inits _MPFR_PROTO ((mpfr_ptr, ...)) __MPFR_SENTINEL_ATTR;
+__MPFR_DECLSPEC void
+ mpfr_clears _MPFR_PROTO ((mpfr_ptr, ...)) __MPFR_SENTINEL_ATTR;
+
+__MPFR_DECLSPEC int
+ mpfr_prec_round _MPFR_PROTO ((mpfr_ptr, mpfr_prec_t, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_can_round _MPFR_PROTO ((mpfr_srcptr, mpfr_exp_t, mpfr_rnd_t, mpfr_rnd_t,
+ mpfr_prec_t));
+__MPFR_DECLSPEC mpfr_prec_t mpfr_min_prec _MPFR_PROTO ((mpfr_srcptr));
+
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_exp _MPFR_PROTO ((mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_set_exp _MPFR_PROTO ((mpfr_ptr, mpfr_exp_t));
+__MPFR_DECLSPEC mpfr_prec_t mpfr_get_prec _MPFR_PROTO((mpfr_srcptr));
+__MPFR_DECLSPEC void mpfr_set_prec _MPFR_PROTO((mpfr_ptr, mpfr_prec_t));
+__MPFR_DECLSPEC void mpfr_set_prec_raw _MPFR_PROTO((mpfr_ptr, mpfr_prec_t));
+__MPFR_DECLSPEC void mpfr_set_default_prec _MPFR_PROTO((mpfr_prec_t));
+__MPFR_DECLSPEC mpfr_prec_t mpfr_get_default_prec _MPFR_PROTO((void));
+
+__MPFR_DECLSPEC int mpfr_set_d _MPFR_PROTO ((mpfr_ptr, double, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_set_flt _MPFR_PROTO ((mpfr_ptr, float, mpfr_rnd_t));
+#ifdef MPFR_WANT_DECIMAL_FLOATS
+__MPFR_DECLSPEC int mpfr_set_decimal64 _MPFR_PROTO ((mpfr_ptr, _Decimal64,
+ mpfr_rnd_t));
+#endif
+__MPFR_DECLSPEC int
+ mpfr_set_ld _MPFR_PROTO ((mpfr_ptr, long double, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set_z _MPFR_PROTO ((mpfr_ptr, mpz_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set_z_2exp _MPFR_PROTO ((mpfr_ptr, mpz_srcptr, mpfr_exp_t, mpfr_rnd_t));
+__MPFR_DECLSPEC void mpfr_set_nan _MPFR_PROTO ((mpfr_ptr));
+__MPFR_DECLSPEC void mpfr_set_inf _MPFR_PROTO ((mpfr_ptr, int));
+__MPFR_DECLSPEC void mpfr_set_zero _MPFR_PROTO ((mpfr_ptr, int));
+__MPFR_DECLSPEC int
+ mpfr_set_f _MPFR_PROTO ((mpfr_ptr, mpf_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_get_f _MPFR_PROTO ((mpf_ptr, mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_set_si _MPFR_PROTO ((mpfr_ptr, long, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set_ui _MPFR_PROTO ((mpfr_ptr, unsigned long, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set_si_2exp _MPFR_PROTO ((mpfr_ptr, long, mpfr_exp_t, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set_ui_2exp _MPFR_PROTO ((mpfr_ptr,unsigned long,mpfr_exp_t,mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set_q _MPFR_PROTO ((mpfr_ptr, mpq_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set_str _MPFR_PROTO ((mpfr_ptr, __gmp_const char *, int, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_init_set_str _MPFR_PROTO ((mpfr_ptr, __gmp_const char *, int,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set4 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t, int));
+__MPFR_DECLSPEC int
+ mpfr_abs _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_neg _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_signbit _MPFR_PROTO ((mpfr_srcptr));
+__MPFR_DECLSPEC int
+ mpfr_setsign _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, int, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_copysign _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC mpfr_exp_t mpfr_get_z_2exp _MPFR_PROTO ((mpz_ptr, mpfr_srcptr));
+__MPFR_DECLSPEC float mpfr_get_flt _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC double mpfr_get_d _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
+#ifdef MPFR_WANT_DECIMAL_FLOATS
+__MPFR_DECLSPEC _Decimal64 mpfr_get_decimal64 _MPFR_PROTO ((mpfr_srcptr,
+ mpfr_rnd_t));
+#endif
+__MPFR_DECLSPEC long double mpfr_get_ld _MPFR_PROTO ((mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC double mpfr_get_d1 _MPFR_PROTO ((mpfr_srcptr));
+__MPFR_DECLSPEC double mpfr_get_d_2exp _MPFR_PROTO ((long*, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC long double mpfr_get_ld_2exp _MPFR_PROTO ((long*, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_frexp _MPFR_PROTO ((mpfr_exp_t*, mpfr_ptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC long mpfr_get_si _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC unsigned long mpfr_get_ui _MPFR_PROTO ((mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC char*mpfr_get_str _MPFR_PROTO ((char*, mpfr_exp_t*, int, size_t,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_get_z _MPFR_PROTO ((mpz_ptr z, mpfr_srcptr f,
+ mpfr_rnd_t));
+
+__MPFR_DECLSPEC void mpfr_free_str _MPFR_PROTO ((char *));
+
+__MPFR_DECLSPEC int mpfr_urandom _MPFR_PROTO ((mpfr_ptr, gmp_randstate_t,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_grandom _MPFR_PROTO ((mpfr_ptr, mpfr_ptr, gmp_randstate_t,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_urandomb _MPFR_PROTO ((mpfr_ptr, gmp_randstate_t));
+
+__MPFR_DECLSPEC void mpfr_nextabove _MPFR_PROTO ((mpfr_ptr));
+__MPFR_DECLSPEC void mpfr_nextbelow _MPFR_PROTO ((mpfr_ptr));
+__MPFR_DECLSPEC void mpfr_nexttoward _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr));
+
+__MPFR_DECLSPEC int mpfr_printf _MPFR_PROTO ((__gmp_const char*, ...));
+__MPFR_DECLSPEC int mpfr_asprintf _MPFR_PROTO ((char**, __gmp_const char*,
+ ...));
+__MPFR_DECLSPEC int mpfr_sprintf _MPFR_PROTO ((char*, __gmp_const char*,
+ ...));
+__MPFR_DECLSPEC int mpfr_snprintf _MPFR_PROTO ((char*, size_t,
+ __gmp_const char*, ...));
+
+__MPFR_DECLSPEC int mpfr_pow _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_pow_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ long int, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_pow_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ unsigned long int, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_ui_pow_ui _MPFR_PROTO ((mpfr_ptr, unsigned long int,
+ unsigned long int, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_ui_pow _MPFR_PROTO ((mpfr_ptr, unsigned long int,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_pow_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpz_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_sqrt _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sqrt_ui _MPFR_PROTO ((mpfr_ptr, unsigned long,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_rec_sqrt _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_add _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sub _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_mul _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_div _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_add_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ unsigned long, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sub_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ unsigned long, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_ui_sub _MPFR_PROTO ((mpfr_ptr, unsigned long,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_mul_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ unsigned long, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_div_ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ unsigned long, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_ui_div _MPFR_PROTO ((mpfr_ptr, unsigned long,
+ mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_add_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ long int, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sub_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ long int, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_si_sub _MPFR_PROTO ((mpfr_ptr, long int,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_mul_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ long int, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_div_si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ long int, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_si_div _MPFR_PROTO ((mpfr_ptr, long int,
+ mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_add_d _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ double, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sub_d _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ double, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_d_sub _MPFR_PROTO ((mpfr_ptr, double,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_mul_d _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ double, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_div_d _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ double, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_d_div _MPFR_PROTO ((mpfr_ptr, double,
+ mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_sqr _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_const_pi _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_const_log2 _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_const_euler _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_const_catalan _MPFR_PROTO ((mpfr_ptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_agm _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_log _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_log2 _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_log10 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_log1p _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_exp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_exp2 _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_exp10 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_expm1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_eint _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_li2 _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_cmp _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_cmp3 _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr, int));
+__MPFR_DECLSPEC int mpfr_cmp_d _MPFR_PROTO ((mpfr_srcptr, double));
+__MPFR_DECLSPEC int mpfr_cmp_ld _MPFR_PROTO ((mpfr_srcptr, long double));
+__MPFR_DECLSPEC int mpfr_cmpabs _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_cmp_ui _MPFR_PROTO ((mpfr_srcptr, unsigned long));
+__MPFR_DECLSPEC int mpfr_cmp_si _MPFR_PROTO ((mpfr_srcptr, long));
+__MPFR_DECLSPEC int mpfr_cmp_ui_2exp _MPFR_PROTO ((mpfr_srcptr, unsigned long,
+ mpfr_exp_t));
+__MPFR_DECLSPEC int mpfr_cmp_si_2exp _MPFR_PROTO ((mpfr_srcptr, long,
+ mpfr_exp_t));
+__MPFR_DECLSPEC void mpfr_reldiff _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_eq _MPFR_PROTO((mpfr_srcptr, mpfr_srcptr,
+ unsigned long));
+__MPFR_DECLSPEC int mpfr_sgn _MPFR_PROTO ((mpfr_srcptr));
+
+__MPFR_DECLSPEC int mpfr_mul_2exp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ unsigned long, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_div_2exp _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ unsigned long, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_mul_2ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ unsigned long, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_div_2ui _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ unsigned long, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_mul_2si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ long, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_div_2si _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ long, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_rint _MPFR_PROTO((mpfr_ptr,mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_round _MPFR_PROTO((mpfr_ptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_trunc _MPFR_PROTO((mpfr_ptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_ceil _MPFR_PROTO((mpfr_ptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_floor _MPFR_PROTO((mpfr_ptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_rint_round _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_rint_trunc _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_rint_ceil _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_rint_floor _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_frac _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_modf _MPFR_PROTO ((mpfr_ptr, mpfr_ptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_remquo _MPFR_PROTO ((mpfr_ptr, long*, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_remainder _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fmod _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_fits_ulong_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fits_slong_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fits_uint_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fits_sint_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fits_ushort_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fits_sshort_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fits_uintmax_p _MPFR_PROTO((mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fits_intmax_p _MPFR_PROTO((mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC void mpfr_extract _MPFR_PROTO ((mpz_ptr, mpfr_srcptr,
+ unsigned int));
+__MPFR_DECLSPEC void mpfr_swap _MPFR_PROTO ((mpfr_ptr, mpfr_ptr));
+__MPFR_DECLSPEC void mpfr_dump _MPFR_PROTO ((mpfr_srcptr));
+
+__MPFR_DECLSPEC int mpfr_nan_p _MPFR_PROTO((mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_inf_p _MPFR_PROTO((mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_number_p _MPFR_PROTO((mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_integer_p _MPFR_PROTO ((mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_zero_p _MPFR_PROTO ((mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_regular_p _MPFR_PROTO ((mpfr_srcptr));
+
+__MPFR_DECLSPEC int mpfr_greater_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_greaterequal_p _MPFR_PROTO ((mpfr_srcptr,
+ mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_less_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_lessequal_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_lessgreater_p _MPFR_PROTO((mpfr_srcptr,mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_equal_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
+__MPFR_DECLSPEC int mpfr_unordered_p _MPFR_PROTO ((mpfr_srcptr, mpfr_srcptr));
+
+__MPFR_DECLSPEC int mpfr_atanh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_acosh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_asinh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_cosh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sinh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_tanh _MPFR_PROTO((mpfr_ptr,mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sinh_cosh _MPFR_PROTO ((mpfr_ptr, mpfr_ptr,
+ mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_sech _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_csch _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_coth _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_acos _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_asin _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_atan _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sin _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sin_cos _MPFR_PROTO ((mpfr_ptr, mpfr_ptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_cos _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_tan _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_atan2 _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sec _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_csc _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_cot _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_hypot _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_erf _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_erfc _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_cbrt _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_root _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,unsigned long,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_gamma _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_lngamma _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_lgamma _MPFR_PROTO((mpfr_ptr,int*,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_digamma _MPFR_PROTO((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_zeta _MPFR_PROTO ((mpfr_ptr,mpfr_srcptr,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_zeta_ui _MPFR_PROTO ((mpfr_ptr,unsigned long,mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fac_ui _MPFR_PROTO ((mpfr_ptr, unsigned long int,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_j0 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_j1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_jn _MPFR_PROTO ((mpfr_ptr, long, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_y0 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_y1 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_yn _MPFR_PROTO ((mpfr_ptr, long, mpfr_srcptr,
+ mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_ai _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_min _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_max _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_dim _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_mul_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpz_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_div_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpz_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_add_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpz_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sub_z _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpz_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_z_sub _MPFR_PROTO ((mpfr_ptr, mpz_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_cmp_z _MPFR_PROTO ((mpfr_srcptr, mpz_srcptr));
+
+__MPFR_DECLSPEC int mpfr_mul_q _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpq_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_div_q _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpq_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_add_q _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpq_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sub_q _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,
+ mpq_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_cmp_q _MPFR_PROTO ((mpfr_srcptr, mpq_srcptr));
+
+__MPFR_DECLSPEC int mpfr_cmp_f _MPFR_PROTO ((mpfr_srcptr, mpf_srcptr));
+
+__MPFR_DECLSPEC int mpfr_fma _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_fms _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_sum _MPFR_PROTO ((mpfr_ptr, mpfr_ptr *__gmp_const,
+ unsigned long, mpfr_rnd_t));
+
+__MPFR_DECLSPEC void mpfr_free_cache _MPFR_PROTO ((void));
+
+__MPFR_DECLSPEC int mpfr_subnormalize _MPFR_PROTO ((mpfr_ptr, int,
+ mpfr_rnd_t));
+
+__MPFR_DECLSPEC int mpfr_strtofr _MPFR_PROTO ((mpfr_ptr, __gmp_const char *,
+ char **, int, mpfr_rnd_t));
+
+__MPFR_DECLSPEC size_t mpfr_custom_get_size _MPFR_PROTO ((mpfr_prec_t));
+__MPFR_DECLSPEC void mpfr_custom_init _MPFR_PROTO ((void *, mpfr_prec_t));
+__MPFR_DECLSPEC void * mpfr_custom_get_significand _MPFR_PROTO ((mpfr_srcptr));
+__MPFR_DECLSPEC mpfr_exp_t mpfr_custom_get_exp _MPFR_PROTO ((mpfr_srcptr));
+__MPFR_DECLSPEC void mpfr_custom_move _MPFR_PROTO ((mpfr_ptr, void *));
+__MPFR_DECLSPEC void mpfr_custom_init_set _MPFR_PROTO ((mpfr_ptr, int,
+ mpfr_exp_t, mpfr_prec_t, void *));
+__MPFR_DECLSPEC int mpfr_custom_get_kind _MPFR_PROTO ((mpfr_srcptr));
+
+#if defined (__cplusplus)
+}
+#endif
+
+/* Define MPFR_USE_EXTENSION to avoid "gcc -pedantic" warnings. */
+#ifndef MPFR_EXTENSION
+# if defined(MPFR_USE_EXTENSION)
+# define MPFR_EXTENSION __extension__
+# else
+# define MPFR_EXTENSION
+# endif
+#endif
+
+/* Warning! This macro doesn't work with K&R C (e.g., compare the "gcc -E"
+ output with and without -traditional) and shouldn't be used internally.
+ For public use only, but see the MPFR manual. */
+#define MPFR_DECL_INIT(_x, _p) \
+ MPFR_EXTENSION mp_limb_t __gmpfr_local_tab_##_x[((_p)-1)/GMP_NUMB_BITS+1]; \
+ MPFR_EXTENSION mpfr_t _x = {{(_p),1,__MPFR_EXP_NAN,__gmpfr_local_tab_##_x}}
+
+/* Fast access macros to replace function interface.
+ If the USER don't want to use the macro interface, let him make happy
+ even if it produces faster and smaller code. */
+#ifndef MPFR_USE_NO_MACRO
+
+/* Inlining theses functions is both faster and smaller */
+#define mpfr_nan_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_NAN)
+#define mpfr_inf_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_INF)
+#define mpfr_zero_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_ZERO)
+#define mpfr_regular_p(_x) ((_x)->_mpfr_exp > __MPFR_EXP_INF)
+#define mpfr_sgn(_x) \
+ ((_x)->_mpfr_exp < __MPFR_EXP_INF ? \
+ (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : \
+ MPFR_SIGN (_x))
+
+/* Prevent them from using as lvalues */
+#define MPFR_VALUE_OF(x) (0 ? (x) : (x))
+#define mpfr_get_prec(_x) MPFR_VALUE_OF((_x)->_mpfr_prec)
+#define mpfr_get_exp(_x) MPFR_VALUE_OF((_x)->_mpfr_exp)
+/* Note: if need be, the MPFR_VALUE_OF can be used for other expressions
+ (of any type). Thanks to Wojtek Lerch and Tim Rentsch for the idea. */
+
+#define mpfr_round(a,b) mpfr_rint((a), (b), MPFR_RNDNA)
+#define mpfr_trunc(a,b) mpfr_rint((a), (b), MPFR_RNDZ)
+#define mpfr_ceil(a,b) mpfr_rint((a), (b), MPFR_RNDU)
+#define mpfr_floor(a,b) mpfr_rint((a), (b), MPFR_RNDD)
+
+#define mpfr_cmp_ui(b,i) mpfr_cmp_ui_2exp((b),(i),0)
+#define mpfr_cmp_si(b,i) mpfr_cmp_si_2exp((b),(i),0)
+#define mpfr_set(a,b,r) mpfr_set4(a,b,r,MPFR_SIGN(b))
+#define mpfr_abs(a,b,r) mpfr_set4(a,b,r,1)
+#define mpfr_copysign(a,b,c,r) mpfr_set4(a,b,r,MPFR_SIGN(c))
+#define mpfr_setsign(a,b,s,r) mpfr_set4(a,b,r,(s) ? -1 : 1)
+#define mpfr_signbit(x) (MPFR_SIGN(x) < 0)
+#define mpfr_cmp(b, c) mpfr_cmp3(b, c, 1)
+#define mpfr_mul_2exp(y,x,n,r) mpfr_mul_2ui((y),(x),(n),(r))
+#define mpfr_div_2exp(y,x,n,r) mpfr_div_2ui((y),(x),(n),(r))
+
+
+/* When using GCC, optimize certain common comparisons and affectations.
+ + Remove ICC since it defines __GNUC__ but produces a
+ huge number of warnings if you use this code.
+ VL: I couldn't reproduce a single warning when enabling these macros
+ with icc 10.1 20080212 on Itanium. But with this version, __ICC isn't
+ defined (__INTEL_COMPILER is, though), so that these macros are enabled
+ anyway. Checking with other ICC versions is needed. Possibly detect
+ whether warnings are produced or not with a configure test.
+ + Remove C++ too, since it complains too much. */
+/* Added casts to improve robustness in case of undefined behavior and
+ compiler extensions based on UB (in particular -fwrapv). MPFR doesn't
+ use such extensions, but these macros will be used by 3rd-party code,
+ where such extensions may be required.
+ Moreover casts to unsigned long have been added to avoid warnings in
+ programs that use MPFR and are compiled with -Wconversion; such casts
+ are OK since if X is a constant expression, then (unsigned long) X is
+ also a constant expression, so that the optimizations still work. The
+ warnings are probably related to the following two bugs:
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38470 (possibly a variant)
+ and the casts could be removed once these bugs are fixed.
+ Casts shouldn't be used on the generic calls (to the ..._2exp functions),
+ where implicit conversions are performed. Indeed, having at least one
+ implicit conversion in the macro allows the compiler to emit diagnostics
+ when normally expected, for instance in the following call:
+ mpfr_set_ui (x, "foo", MPFR_RNDN);
+ If this is not possible (for future macros), one of the tricks described
+ on http://groups.google.com/group/comp.std.c/msg/e92abd24bf9eaf7b could
+ be used. */
+#if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus)
+#if (__GNUC__ >= 2)
+#undef mpfr_cmp_ui
+/* We use the fact that mpfr_sgn on NaN sets the erange flag and returns 0.
+ But warning! mpfr_sgn is specified as a macro in the API, thus the macro
+ mustn't be used if side effects are possible, like here. */
+#define mpfr_cmp_ui(_f,_u) \
+ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \
+ (mpfr_sgn) (_f) : \
+ mpfr_cmp_ui_2exp ((_f), (_u), 0))
+#undef mpfr_cmp_si
+#define mpfr_cmp_si(_f,_s) \
+ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
+ mpfr_cmp_ui ((_f), (mpfr_ulong) (mpfr_long) (_s)) : \
+ mpfr_cmp_si_2exp ((_f), (_s), 0))
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
+#undef mpfr_set_ui
+#define mpfr_set_ui(_f,_u,_r) \
+ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \
+ __extension__ ({ \
+ mpfr_ptr _p = (_f); \
+ _p->_mpfr_sign = 1; \
+ _p->_mpfr_exp = __MPFR_EXP_ZERO; \
+ (mpfr_void) (_r); 0; }) : \
+ mpfr_set_ui_2exp ((_f), (_u), 0, (_r)))
+#endif
+#undef mpfr_set_si
+#define mpfr_set_si(_f,_s,_r) \
+ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
+ mpfr_set_ui ((_f), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \
+ mpfr_set_si_2exp ((_f), (_s), 0, (_r)))
+#endif
+#endif
+
+/* Macro version of mpfr_stack interface for fast access */
+#define mpfr_custom_get_size(p) ((mpfr_size_t) \
+ (((p)+GMP_NUMB_BITS-1)/GMP_NUMB_BITS*sizeof (mp_limb_t)))
+#define mpfr_custom_init(m,p) do {} while (0)
+#define mpfr_custom_get_significand(x) ((mpfr_void*)((x)->_mpfr_d))
+#define mpfr_custom_get_exp(x) ((x)->_mpfr_exp)
+#define mpfr_custom_move(x,m) do { ((x)->_mpfr_d = (mp_limb_t*)(m)); } while (0)
+#define mpfr_custom_init_set(x,k,e,p,m) do { \
+ mpfr_ptr _x = (x); \
+ mpfr_exp_t _e; \
+ mpfr_kind_t _t; \
+ mpfr_int _s, _k; \
+ _k = (k); \
+ if (_k >= 0) { \
+ _t = (mpfr_kind_t) _k; \
+ _s = 1; \
+ } else { \
+ _t = (mpfr_kind_t) -k; \
+ _s = -1; \
+ } \
+ _e = _t == MPFR_REGULAR_KIND ? (e) : \
+ _t == MPFR_NAN_KIND ? __MPFR_EXP_NAN : \
+ _t == MPFR_INF_KIND ? __MPFR_EXP_INF : __MPFR_EXP_ZERO; \
+ _x->_mpfr_prec = (p); \
+ _x->_mpfr_sign = _s; \
+ _x->_mpfr_exp = _e; \
+ _x->_mpfr_d = (mp_limb_t*) (m); \
+ } while (0)
+#define mpfr_custom_get_kind(x) \
+ ( (x)->_mpfr_exp > __MPFR_EXP_INF ? \
+ (mpfr_int) MPFR_REGULAR_KIND * MPFR_SIGN (x) \
+ : (x)->_mpfr_exp == __MPFR_EXP_INF ? \
+ (mpfr_int) MPFR_INF_KIND * MPFR_SIGN (x) \
+ : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (mpfr_int) MPFR_NAN_KIND \
+ : (mpfr_int) MPFR_ZERO_KIND * MPFR_SIGN (x) )
+
+
+#endif /* MPFR_USE_NO_MACRO */
+
+/* Theses are defined to be macros */
+#define mpfr_init_set_si(x, i, rnd) \
+ ( mpfr_init(x), mpfr_set_si((x), (i), (rnd)) )
+#define mpfr_init_set_ui(x, i, rnd) \
+ ( mpfr_init(x), mpfr_set_ui((x), (i), (rnd)) )
+#define mpfr_init_set_d(x, d, rnd) \
+ ( mpfr_init(x), mpfr_set_d((x), (d), (rnd)) )
+#define mpfr_init_set_ld(x, d, rnd) \
+ ( mpfr_init(x), mpfr_set_ld((x), (d), (rnd)) )
+#define mpfr_init_set_z(x, i, rnd) \
+ ( mpfr_init(x), mpfr_set_z((x), (i), (rnd)) )
+#define mpfr_init_set_q(x, i, rnd) \
+ ( mpfr_init(x), mpfr_set_q((x), (i), (rnd)) )
+#define mpfr_init_set(x, y, rnd) \
+ ( mpfr_init(x), mpfr_set((x), (y), (rnd)) )
+#define mpfr_init_set_f(x, y, rnd) \
+ ( mpfr_init(x), mpfr_set_f((x), (y), (rnd)) )
+
+/* Compatibility layer -- obsolete functions and macros */
+/* Note: it is not possible to output warnings, unless one defines
+ * a deprecated variable and uses it, e.g.
+ * MPFR_DEPRECATED extern int mpfr_deprecated_feature;
+ * #define MPFR_EMIN_MIN ((void)mpfr_deprecated_feature,mpfr_get_emin_min())
+ * (the cast to void avoids a warning because the left-hand operand
+ * has no effect).
+ */
+#define mpfr_cmp_abs mpfr_cmpabs
+#define mpfr_round_prec(x,r,p) mpfr_prec_round(x,p,r)
+#define __gmp_default_rounding_mode (mpfr_get_default_rounding_mode())
+#define __mpfr_emin (mpfr_get_emin())
+#define __mpfr_emax (mpfr_get_emax())
+#define __mpfr_default_fp_bit_precision (mpfr_get_default_fp_bit_precision())
+#define MPFR_EMIN_MIN mpfr_get_emin_min()
+#define MPFR_EMIN_MAX mpfr_get_emin_max()
+#define MPFR_EMAX_MIN mpfr_get_emax_min()
+#define MPFR_EMAX_MAX mpfr_get_emax_max()
+#define mpfr_version (mpfr_get_version())
+#ifndef mpz_set_fr
+# define mpz_set_fr mpfr_get_z
+#endif
+#define mpfr_add_one_ulp(x,r) \
+ (mpfr_sgn (x) > 0 ? mpfr_nextabove (x) : mpfr_nextbelow (x))
+#define mpfr_sub_one_ulp(x,r) \
+ (mpfr_sgn (x) > 0 ? mpfr_nextbelow (x) : mpfr_nextabove (x))
+#define mpfr_get_z_exp mpfr_get_z_2exp
+#define mpfr_custom_get_mantissa mpfr_custom_get_significand
+
+#endif /* __MPFR_H */
+
+
+/* Check if <stdint.h> / <inttypes.h> is included or if the user
+ explicitly wants intmax_t. Automatical detection is done by
+ checking:
+ - INTMAX_C and UINTMAX_C, but not if the compiler is a C++ one
+ (as suggested by Patrick Pelissier) because the test does not
+ work well in this case. See:
+ https://sympa.inria.fr/sympa/arc/mpfr/2010-02/msg00025.html
+ We do not check INTMAX_MAX and UINTMAX_MAX because under Solaris,
+ these macros are always defined by <limits.h> (i.e. even when
+ <stdint.h> and <inttypes.h> are not included).
+ - _STDINT_H (defined by the glibc), _STDINT_H_ (defined under
+ Mac OS X) and _STDINT (defined under MS Visual Studio), but
+ this test may not work with all implementations.
+ Portable software should not rely on these tests.
+*/
+#if (defined (INTMAX_C) && defined (UINTMAX_C) && !defined(__cplusplus)) || \
+ defined (MPFR_USE_INTMAX_T) || \
+ defined (_STDINT_H) || defined (_STDINT_H_) || defined (_STDINT)
+# ifndef _MPFR_H_HAVE_INTMAX_T
+# define _MPFR_H_HAVE_INTMAX_T 1
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define mpfr_set_sj __gmpfr_set_sj
+#define mpfr_set_sj_2exp __gmpfr_set_sj_2exp
+#define mpfr_set_uj __gmpfr_set_uj
+#define mpfr_set_uj_2exp __gmpfr_set_uj_2exp
+#define mpfr_get_sj __gmpfr_mpfr_get_sj
+#define mpfr_get_uj __gmpfr_mpfr_get_uj
+__MPFR_DECLSPEC int mpfr_set_sj _MPFR_PROTO ((mpfr_t, intmax_t, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set_sj_2exp _MPFR_PROTO ((mpfr_t, intmax_t, intmax_t, mpfr_rnd_t));
+__MPFR_DECLSPEC int mpfr_set_uj _MPFR_PROTO ((mpfr_t, uintmax_t, mpfr_rnd_t));
+__MPFR_DECLSPEC int
+ mpfr_set_uj_2exp _MPFR_PROTO ((mpfr_t, uintmax_t, intmax_t, mpfr_rnd_t));
+__MPFR_DECLSPEC intmax_t mpfr_get_sj _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
+__MPFR_DECLSPEC uintmax_t mpfr_get_uj _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
+
+#if defined (__cplusplus)
+}
+#endif
+
+# endif /* _MPFR_H_HAVE_INTMAX_T */
+#endif
+
+
+/* Check if <stdio.h> has been included or if the user wants FILE */
+#if defined (_GMP_H_HAVE_FILE) || defined (MPFR_USE_FILE)
+# ifndef _MPFR_H_HAVE_FILE
+# define _MPFR_H_HAVE_FILE 1
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define mpfr_inp_str __gmpfr_inp_str
+#define mpfr_out_str __gmpfr_out_str
+__MPFR_DECLSPEC size_t mpfr_inp_str _MPFR_PROTO ((mpfr_ptr, FILE*, int,
+ mpfr_rnd_t));
+__MPFR_DECLSPEC size_t mpfr_out_str _MPFR_PROTO ((FILE*, int, size_t,
+ mpfr_srcptr, mpfr_rnd_t));
+#define mpfr_fprintf __gmpfr_fprintf
+__MPFR_DECLSPEC int mpfr_fprintf _MPFR_PROTO ((FILE*, __gmp_const char*,
+ ...));
+
+#if defined (__cplusplus)
+}
+#endif
+
+# endif /* _MPFR_H_HAVE_FILE */
+#endif
+
+
+/* check if <stdarg.h> has been included or if the user wants va_list */
+#if defined (_GMP_H_HAVE_VA_LIST) || defined (MPFR_USE_VA_LIST)
+# ifndef _MPFR_H_HAVE_VA_LIST
+# define _MPFR_H_HAVE_VA_LIST 1
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define mpfr_vprintf __gmpfr_vprintf
+#define mpfr_vasprintf __gmpfr_vasprintf
+#define mpfr_vsprintf __gmpfr_vsprintf
+#define mpfr_vsnprintf __gmpfr_vsnprintf
+__MPFR_DECLSPEC int mpfr_vprintf _MPFR_PROTO ((__gmp_const char*, va_list));
+__MPFR_DECLSPEC int mpfr_vasprintf _MPFR_PROTO ((char**, __gmp_const char*,
+ va_list));
+__MPFR_DECLSPEC int mpfr_vsprintf _MPFR_PROTO ((char*, __gmp_const char*,
+ va_list));
+__MPFR_DECLSPEC int mpfr_vsnprintf _MPFR_PROTO ((char*, size_t,
+ __gmp_const char*, va_list));
+
+#if defined (__cplusplus)
+}
+#endif
+
+# endif /* _MPFR_H_HAVE_VA_LIST */
+#endif
+
+
+/* check if <stdarg.h> has been included and if FILE is available
+ (see above) */
+#if defined (_MPFR_H_HAVE_VA_LIST) && defined (_MPFR_H_HAVE_FILE)
+# ifndef _MPFR_H_HAVE_VA_LIST_FILE
+# define _MPFR_H_HAVE_VA_LIST_FILE 1
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define mpfr_vfprintf __gmpfr_vfprintf
+__MPFR_DECLSPEC int mpfr_vfprintf _MPFR_PROTO ((FILE*, __gmp_const char*,
+ va_list));
+
+#if defined (__cplusplus)
+}
+#endif
+
+# endif /* _MPFR_H_HAVE_VA_LIST_FILE */
+#endif
diff --git a/mpfr/src/mpn_exp.c b/mpfr/src/mpn_exp.c
new file mode 100644
index 0000000000..63dcde9f64
--- /dev/null
+++ b/mpfr/src/mpn_exp.c
@@ -0,0 +1,174 @@
+/* mpfr_mpn_exp -- auxiliary function for mpfr_get_str and mpfr_set_str
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* this function computes an approximation of b^e in {a, n}, with exponent
+ stored in exp_r. The computed value is rounded toward zero (truncated).
+ It returns an integer f such that the final error is bounded by 2^f ulps,
+ that is:
+ a*2^exp_r <= b^e <= 2^exp_r (a + 2^f),
+ where a represents {a, n}, i.e. the integer
+ a[0] + a[1]*B + ... + a[n-1]*B^(n-1) where B=2^GMP_NUMB_BITS
+
+ Return -1 is the result is exact.
+ Return -2 if an overflow occurred in the computation of exp_r.
+*/
+
+long
+mpfr_mpn_exp (mp_limb_t *a, mpfr_exp_t *exp_r, int b, mpfr_exp_t e, size_t n)
+{
+ mp_limb_t *c, B;
+ mpfr_exp_t f, h;
+ int i;
+ unsigned long t; /* number of bits in e */
+ unsigned long bits;
+ size_t n1;
+ unsigned int error; /* (number - 1) of loop a^2b inexact */
+ /* error == t means no error */
+ int err_s_a2 = 0;
+ int err_s_ab = 0; /* number of error when shift A^2, AB */
+ MPFR_TMP_DECL(marker);
+
+ MPFR_ASSERTN(e > 0);
+ MPFR_ASSERTN((2 <= b) && (b <= 62));
+
+ MPFR_TMP_MARK(marker);
+
+ /* initialization of a, b, f, h */
+
+ /* normalize the base */
+ B = (mp_limb_t) b;
+ count_leading_zeros (h, B);
+
+ bits = GMP_NUMB_BITS - h;
+
+ B = B << h;
+ h = - h;
+
+ /* allocate space for A and set it to B */
+ c = MPFR_TMP_LIMBS_ALLOC (2 * n);
+ a [n - 1] = B;
+ MPN_ZERO (a, n - 1);
+ /* initial exponent for A: invariant is A = {a, n} * 2^f */
+ f = h - (n - 1) * GMP_NUMB_BITS;
+
+ /* determine number of bits in e */
+ count_leading_zeros (t, (mp_limb_t) e);
+
+ t = GMP_NUMB_BITS - t; /* number of bits of exponent e */
+
+ error = t; /* error <= GMP_NUMB_BITS */
+
+ MPN_ZERO (c, 2 * n);
+
+ for (i = t - 2; i >= 0; i--)
+ {
+
+ /* determine precision needed */
+ bits = n * GMP_NUMB_BITS - mpn_scan1 (a, 0);
+ n1 = (n * GMP_NUMB_BITS - bits) / GMP_NUMB_BITS;
+
+ /* square of A : {c+2n1, 2(n-n1)} = {a+n1, n-n1}^2 */
+ mpn_sqr_n (c + 2 * n1, a + n1, n - n1);
+
+ /* set {c+n, 2n1-n} to 0 : {c, n} = {a, n}^2*K^n */
+
+ /* check overflow on f */
+ if (MPFR_UNLIKELY(f < MPFR_EXP_MIN/2 || f > MPFR_EXP_MAX/2))
+ {
+ overflow:
+ MPFR_TMP_FREE(marker);
+ return -2;
+ }
+ /* FIXME: Could f = 2*f + n * GMP_NUMB_BITS be used? */
+ f = 2*f;
+ MPFR_SADD_OVERFLOW (f, f, n * GMP_NUMB_BITS,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN, MPFR_EXP_MAX,
+ goto overflow, goto overflow);
+ if ((c[2*n - 1] & MPFR_LIMB_HIGHBIT) == 0)
+ {
+ /* shift A by one bit to the left */
+ mpn_lshift (a, c + n, n, 1);
+ a[0] |= mpn_lshift (c + n - 1, c + n - 1, 1, 1);
+ f --;
+ if (error != t)
+ err_s_a2 ++;
+ }
+ else
+ MPN_COPY (a, c + n, n);
+
+ if ((error == t) && (2 * n1 <= n) &&
+ (mpn_scan1 (c + 2 * n1, 0) < (n - 2 * n1) * GMP_NUMB_BITS))
+ error = i;
+
+ if (e & ((mpfr_exp_t) 1 << i))
+ {
+ /* multiply A by B */
+ c[2 * n - 1] = mpn_mul_1 (c + n - 1, a, n, B);
+ f += h + GMP_NUMB_BITS;
+ if ((c[2 * n - 1] & MPFR_LIMB_HIGHBIT) == 0)
+ { /* shift A by one bit to the left */
+ mpn_lshift (a, c + n, n, 1);
+ a[0] |= mpn_lshift (c + n - 1, c + n - 1, 1, 1);
+ f --;
+ }
+ else
+ {
+ MPN_COPY (a, c + n, n);
+ if (error != t)
+ err_s_ab ++;
+ }
+ if ((error == t) && (c[n - 1] != 0))
+ error = i;
+ }
+ }
+
+ MPFR_TMP_FREE(marker);
+
+ *exp_r = f;
+
+ if (error == t)
+ return -1; /* result is exact */
+ else /* error <= t-2 <= GMP_NUMB_BITS-2
+ err_s_ab, err_s_a2 <= t-1 */
+ {
+ /* if there are p loops after the first inexact result, with
+ j shifts in a^2 and l shifts in a*b, then the final error is
+ at most 2^(p+ceil((j+1)/2)+l+1)*ulp(res).
+ This is bounded by 2^(5/2*t-1/2) where t is the number of bits of e.
+ */
+ error = error + err_s_ab + err_s_a2 / 2 + 3; /* <= 5t/2-1/2 */
+#if 0
+ if ((error - 1) >= ((n * GMP_NUMB_BITS - 1) / 2))
+ error = n * GMP_NUMB_BITS; /* result is completely wrong:
+ this is very unlikely since error is
+ at most 5/2*log_2(e), and
+ n * GMP_NUMB_BITS is at least
+ 3*log_2(e) */
+#endif
+ return error;
+ }
+}
diff --git a/mpfr/src/mul.c b/mpfr/src/mul.c
new file mode 100644
index 0000000000..efbfdb1b08
--- /dev/null
+++ b/mpfr/src/mul.c
@@ -0,0 +1,547 @@
+/* mpfr_mul -- multiply two floating-point numbers
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+
+/********* BEGINNING CHECK *************/
+
+/* Check if we have to check the result of mpfr_mul.
+ TODO: Find a better (and faster?) check than using old implementation */
+#ifdef WANT_ASSERT
+# if WANT_ASSERT >= 3
+
+int mpfr_mul2 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode);
+static int
+mpfr_mul3 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ /* Old implementation */
+ int sign_product, cc, inexact;
+ mpfr_exp_t ax;
+ mp_limb_t *tmp;
+ mp_limb_t b1;
+ mpfr_prec_t bq, cq;
+ mp_size_t bn, cn, tn, k;
+ MPFR_TMP_DECL(marker);
+
+ /* deal with special cases */
+ if (MPFR_ARE_SINGULAR(b,c))
+ {
+ if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c))
+ {
+ MPFR_SET_NAN(a);
+ MPFR_RET_NAN;
+ }
+ sign_product = MPFR_MULT_SIGN( MPFR_SIGN(b) , MPFR_SIGN(c) );
+ if (MPFR_IS_INF(b))
+ {
+ if (MPFR_IS_INF(c) || MPFR_NOTZERO(c))
+ {
+ MPFR_SET_SIGN(a,sign_product);
+ MPFR_SET_INF(a);
+ MPFR_RET(0); /* exact */
+ }
+ else
+ {
+ MPFR_SET_NAN(a);
+ MPFR_RET_NAN;
+ }
+ }
+ else if (MPFR_IS_INF(c))
+ {
+ if (MPFR_NOTZERO(b))
+ {
+ MPFR_SET_SIGN(a, sign_product);
+ MPFR_SET_INF(a);
+ MPFR_RET(0); /* exact */
+ }
+ else
+ {
+ MPFR_SET_NAN(a);
+ MPFR_RET_NAN;
+ }
+ }
+ else
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(b) || MPFR_IS_ZERO(c));
+ MPFR_SET_SIGN(a, sign_product);
+ MPFR_SET_ZERO(a);
+ MPFR_RET(0); /* 0 * 0 is exact */
+ }
+ }
+ sign_product = MPFR_MULT_SIGN( MPFR_SIGN(b) , MPFR_SIGN(c) );
+
+ ax = MPFR_GET_EXP (b) + MPFR_GET_EXP (c);
+
+ bq = MPFR_PREC (b);
+ cq = MPFR_PREC (c);
+
+ MPFR_ASSERTN ((mpfr_uprec_t) bq + cq <= MPFR_PREC_MAX);
+
+ bn = MPFR_PREC2LIMBS (bq); /* number of limbs of b */
+ cn = MPFR_PREC2LIMBS (cq); /* number of limbs of c */
+ k = bn + cn; /* effective nb of limbs used by b*c (= tn or tn+1) below */
+ tn = MPFR_PREC2LIMBS (bq + cq);
+ /* <= k, thus no int overflow */
+ MPFR_ASSERTD(tn <= k);
+
+ /* Check for no size_t overflow*/
+ MPFR_ASSERTD((size_t) k <= ((size_t) -1) / BYTES_PER_MP_LIMB);
+ MPFR_TMP_MARK(marker);
+ tmp = MPFR_TMP_LIMBS_ALLOC (k);
+
+ /* multiplies two mantissa in temporary allocated space */
+ b1 = (MPFR_LIKELY(bn >= cn)) ?
+ mpn_mul (tmp, MPFR_MANT(b), bn, MPFR_MANT(c), cn)
+ : mpn_mul (tmp, MPFR_MANT(c), cn, MPFR_MANT(b), bn);
+
+ /* now tmp[0]..tmp[k-1] contains the product of both mantissa,
+ with tmp[k-1]>=2^(GMP_NUMB_BITS-2) */
+ b1 >>= GMP_NUMB_BITS - 1; /* msb from the product */
+
+ /* if the mantissas of b and c are uniformly distributed in ]1/2, 1],
+ then their product is in ]1/4, 1/2] with probability 2*ln(2)-1 ~ 0.386
+ and in [1/2, 1] with probability 2-2*ln(2) ~ 0.614 */
+ tmp += k - tn;
+ if (MPFR_UNLIKELY(b1 == 0))
+ mpn_lshift (tmp, tmp, tn, 1); /* tn <= k, so no stack corruption */
+ cc = mpfr_round_raw (MPFR_MANT (a), tmp, bq + cq,
+ MPFR_IS_NEG_SIGN(sign_product),
+ MPFR_PREC (a), rnd_mode, &inexact);
+
+ /* cc = 1 ==> result is a power of two */
+ if (MPFR_UNLIKELY(cc))
+ MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] = MPFR_LIMB_HIGHBIT;
+
+ MPFR_TMP_FREE(marker);
+
+ {
+ mpfr_exp_t ax2 = ax + (mpfr_exp_t) (b1 - 1 + cc);
+ if (MPFR_UNLIKELY( ax2 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, sign_product);
+ if (MPFR_UNLIKELY( ax2 < __gmpfr_emin))
+ {
+ /* In the rounding to the nearest mode, if the exponent of the exact
+ result (i.e. before rounding, i.e. without taking cc into account)
+ is < __gmpfr_emin - 1 or the exact result is a power of 2 (i.e. if
+ both arguments are powers of 2) in absolute value, then round to
+ zero. */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax + (mpfr_exp_t) b1 < __gmpfr_emin ||
+ (mpfr_powerof2_raw (b) && mpfr_powerof2_raw (c))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, sign_product);
+ }
+ MPFR_SET_EXP (a, ax2);
+ MPFR_SET_SIGN(a, sign_product);
+ }
+ MPFR_RET (inexact);
+}
+
+int
+mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t ta, tb, tc;
+ int inexact1, inexact2;
+
+ mpfr_init2 (ta, MPFR_PREC (a));
+ mpfr_init2 (tb, MPFR_PREC (b));
+ mpfr_init2 (tc, MPFR_PREC (c));
+ MPFR_ASSERTN (mpfr_set (tb, b, MPFR_RNDN) == 0);
+ MPFR_ASSERTN (mpfr_set (tc, c, MPFR_RNDN) == 0);
+
+ inexact2 = mpfr_mul3 (ta, tb, tc, rnd_mode);
+ inexact1 = mpfr_mul2 (a, b, c, rnd_mode);
+ if (mpfr_cmp (ta, a) || inexact1*inexact2 < 0
+ || (inexact1*inexact2 == 0 && (inexact1|inexact2) != 0))
+ {
+ fprintf (stderr, "mpfr_mul return different values for %s\n"
+ "Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nB = ",
+ mpfr_print_rnd_mode (rnd_mode),
+ MPFR_PREC (a), MPFR_PREC (b), MPFR_PREC (c));
+ mpfr_out_str (stderr, 16, 0, tb, MPFR_RNDN);
+ fprintf (stderr, "\nC = ");
+ mpfr_out_str (stderr, 16, 0, tc, MPFR_RNDN);
+ fprintf (stderr, "\nOldMul: ");
+ mpfr_out_str (stderr, 16, 0, ta, MPFR_RNDN);
+ fprintf (stderr, "\nNewMul: ");
+ mpfr_out_str (stderr, 16, 0, a, MPFR_RNDN);
+ fprintf (stderr, "\nNewInexact = %d | OldInexact = %d\n",
+ inexact1, inexact2);
+ MPFR_ASSERTN(0);
+ }
+
+ mpfr_clears (ta, tb, tc, (mpfr_ptr) 0);
+ return inexact1;
+}
+
+# define mpfr_mul mpfr_mul2
+# endif
+#endif
+
+/****** END OF CHECK *******/
+
+/* Multiply 2 mpfr_t */
+
+/* Note: mpfr_sqr will call mpfr_mul if bn > MPFR_SQR_THRESHOLD,
+ in order to use Mulders' mulhigh, which is handled only here
+ to avoid partial code duplication. There is some overhead due
+ to the additional tests, but slowdown should not be noticeable
+ as this code is not executed in very small precisions. */
+
+int
+mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ int sign, inexact;
+ mpfr_exp_t ax, ax2;
+ mp_limb_t *tmp;
+ mp_limb_t b1;
+ mpfr_prec_t bq, cq;
+ mp_size_t bn, cn, tn, k, threshold;
+ MPFR_TMP_DECL (marker);
+
+ MPFR_LOG_FUNC
+ (("b[%Pu]=%.*Rg c[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (b), mpfr_log_prec, b,
+ mpfr_get_prec (c), mpfr_log_prec, c, rnd_mode),
+ ("a[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (a), mpfr_log_prec, a, inexact));
+
+ /* deal with special cases */
+ if (MPFR_ARE_SINGULAR (b, c))
+ {
+ if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
+ {
+ MPFR_SET_NAN (a);
+ MPFR_RET_NAN;
+ }
+ sign = MPFR_MULT_SIGN (MPFR_SIGN (b), MPFR_SIGN (c));
+ if (MPFR_IS_INF (b))
+ {
+ if (!MPFR_IS_ZERO (c))
+ {
+ MPFR_SET_SIGN (a, sign);
+ MPFR_SET_INF (a);
+ MPFR_RET (0);
+ }
+ else
+ {
+ MPFR_SET_NAN (a);
+ MPFR_RET_NAN;
+ }
+ }
+ else if (MPFR_IS_INF (c))
+ {
+ if (!MPFR_IS_ZERO (b))
+ {
+ MPFR_SET_SIGN (a, sign);
+ MPFR_SET_INF (a);
+ MPFR_RET(0);
+ }
+ else
+ {
+ MPFR_SET_NAN (a);
+ MPFR_RET_NAN;
+ }
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO(b) || MPFR_IS_ZERO(c));
+ MPFR_SET_SIGN (a, sign);
+ MPFR_SET_ZERO (a);
+ MPFR_RET (0);
+ }
+ }
+ sign = MPFR_MULT_SIGN (MPFR_SIGN (b), MPFR_SIGN (c));
+
+ ax = MPFR_GET_EXP (b) + MPFR_GET_EXP (c);
+ /* Note: the exponent of the exact result will be e = bx + cx + ec with
+ ec in {-1,0,1} and the following assumes that e is representable. */
+
+ /* FIXME: Useful since we do an exponent check after ?
+ * It is useful iff the precision is big, there is an overflow
+ * and we are doing further mults...*/
+#ifdef HUGE
+ if (MPFR_UNLIKELY (ax > __gmpfr_emax + 1))
+ return mpfr_overflow (a, rnd_mode, sign);
+ if (MPFR_UNLIKELY (ax < __gmpfr_emin - 2))
+ return mpfr_underflow (a, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
+ sign);
+#endif
+
+ bq = MPFR_PREC (b);
+ cq = MPFR_PREC (c);
+
+ MPFR_ASSERTN ((mpfr_uprec_t) bq + cq <= MPFR_PREC_MAX);
+
+ bn = MPFR_PREC2LIMBS (bq); /* number of limbs of b */
+ cn = MPFR_PREC2LIMBS (cq); /* number of limbs of c */
+ k = bn + cn; /* effective nb of limbs used by b*c (= tn or tn+1) below */
+ tn = MPFR_PREC2LIMBS (bq + cq);
+ MPFR_ASSERTD (tn <= k); /* tn <= k, thus no int overflow */
+
+ /* Check for no size_t overflow*/
+ MPFR_ASSERTD ((size_t) k <= ((size_t) -1) / BYTES_PER_MP_LIMB);
+ MPFR_TMP_MARK (marker);
+ tmp = MPFR_TMP_LIMBS_ALLOC (k);
+
+ /* multiplies two mantissa in temporary allocated space */
+ if (MPFR_UNLIKELY (bn < cn))
+ {
+ mpfr_srcptr z = b;
+ mp_size_t zn = bn;
+ b = c;
+ bn = cn;
+ c = z;
+ cn = zn;
+ }
+ MPFR_ASSERTD (bn >= cn);
+ if (MPFR_LIKELY (bn <= 2))
+ {
+ if (bn == 1)
+ {
+ /* 1 limb * 1 limb */
+ umul_ppmm (tmp[1], tmp[0], MPFR_MANT (b)[0], MPFR_MANT (c)[0]);
+ b1 = tmp[1];
+ }
+ else if (MPFR_UNLIKELY (cn == 1))
+ {
+ /* 2 limbs * 1 limb */
+ mp_limb_t t;
+ umul_ppmm (tmp[1], tmp[0], MPFR_MANT (b)[0], MPFR_MANT (c)[0]);
+ umul_ppmm (tmp[2], t, MPFR_MANT (b)[1], MPFR_MANT (c)[0]);
+ add_ssaaaa (tmp[2], tmp[1], tmp[2], tmp[1], 0, t);
+ b1 = tmp[2];
+ }
+ else
+ {
+ /* 2 limbs * 2 limbs */
+ mp_limb_t t1, t2, t3;
+ /* First 2 limbs * 1 limb */
+ umul_ppmm (tmp[1], tmp[0], MPFR_MANT (b)[0], MPFR_MANT (c)[0]);
+ umul_ppmm (tmp[2], t1, MPFR_MANT (b)[1], MPFR_MANT (c)[0]);
+ add_ssaaaa (tmp[2], tmp[1], tmp[2], tmp[1], 0, t1);
+ /* Second, the other 2 limbs * 1 limb product */
+ umul_ppmm (t1, t2, MPFR_MANT (b)[0], MPFR_MANT (c)[1]);
+ umul_ppmm (tmp[3], t3, MPFR_MANT (b)[1], MPFR_MANT (c)[1]);
+ add_ssaaaa (tmp[3], t1, tmp[3], t1, 0, t3);
+ /* Sum those two partial products */
+ add_ssaaaa (tmp[2], tmp[1], tmp[2], tmp[1], t1, t2);
+ tmp[3] += (tmp[2] < t1);
+ b1 = tmp[3];
+ }
+ b1 >>= (GMP_NUMB_BITS - 1);
+ tmp += k - tn;
+ if (MPFR_UNLIKELY (b1 == 0))
+ mpn_lshift (tmp, tmp, tn, 1); /* tn <= k, so no stack corruption */
+ }
+ else
+ /* Mulders' mulhigh. This code can also be used via mpfr_sqr,
+ hence the tests b != c. */
+ if (MPFR_UNLIKELY (bn > (threshold = b != c ?
+ MPFR_MUL_THRESHOLD : MPFR_SQR_THRESHOLD)))
+ {
+ mp_limb_t *bp, *cp;
+ mp_size_t n;
+ mpfr_prec_t p;
+
+ /* First check if we can reduce the precision of b or c:
+ exact values are a nightmare for the short product trick */
+ bp = MPFR_MANT (b);
+ cp = MPFR_MANT (c);
+ MPFR_ASSERTN (threshold >= 1);
+ if (MPFR_UNLIKELY ((bp[0] == 0 && bp[1] == 0) ||
+ (cp[0] == 0 && cp[1] == 0)))
+ {
+ mpfr_t b_tmp, c_tmp;
+
+ MPFR_TMP_FREE (marker);
+ /* Check for b */
+ while (*bp == 0)
+ {
+ bp++;
+ bn--;
+ MPFR_ASSERTD (bn > 0);
+ } /* This must end since the most significant limb is != 0 */
+
+ /* Check for c too: if b ==c, will do nothing */
+ while (*cp == 0)
+ {
+ cp++;
+ cn--;
+ MPFR_ASSERTD (cn > 0);
+ } /* This must end since the most significant limb is != 0 */
+
+ /* It is not the faster way, but it is safer */
+ MPFR_SET_SAME_SIGN (b_tmp, b);
+ MPFR_SET_EXP (b_tmp, MPFR_GET_EXP (b));
+ MPFR_PREC (b_tmp) = bn * GMP_NUMB_BITS;
+ MPFR_MANT (b_tmp) = bp;
+
+ if (b != c)
+ {
+ MPFR_SET_SAME_SIGN (c_tmp, c);
+ MPFR_SET_EXP (c_tmp, MPFR_GET_EXP (c));
+ MPFR_PREC (c_tmp) = cn * GMP_NUMB_BITS;
+ MPFR_MANT (c_tmp) = cp;
+
+ /* Call again mpfr_mul with the fixed arguments */
+ return mpfr_mul (a, b_tmp, c_tmp, rnd_mode);
+ }
+ else
+ /* Call mpfr_mul instead of mpfr_sqr as the precision
+ is probably still high enough. */
+ return mpfr_mul (a, b_tmp, b_tmp, rnd_mode);
+ }
+
+ /* Compute estimated precision of mulhigh.
+ We could use `+ (n < cn) + (n < bn)' instead of `+ 2',
+ but does it worth it? */
+ n = MPFR_LIMB_SIZE (a) + 1;
+ n = MIN (n, cn);
+ MPFR_ASSERTD (n >= 1 && 2*n <= k && n <= cn && n <= bn);
+ p = n * GMP_NUMB_BITS - MPFR_INT_CEIL_LOG2 (n + 2);
+ bp += bn - n;
+ cp += cn - n;
+
+ /* Check if MulHigh can produce a roundable result.
+ We may lose 1 bit due to RNDN, 1 due to final shift. */
+ if (MPFR_UNLIKELY (MPFR_PREC (a) > p - 5))
+ {
+ if (MPFR_UNLIKELY (MPFR_PREC (a) > p - 5 + GMP_NUMB_BITS
+ || bn <= threshold + 1))
+ {
+ /* MulHigh can't produce a roundable result. */
+ MPFR_LOG_MSG (("mpfr_mulhigh can't be used (%lu VS %lu)\n",
+ MPFR_PREC (a), p));
+ goto full_multiply;
+ }
+ /* Add one extra limb to mantissa of b and c. */
+ if (bn > n)
+ bp --;
+ else
+ {
+ bp = MPFR_TMP_LIMBS_ALLOC (n + 1);
+ bp[0] = 0;
+ MPN_COPY (bp + 1, MPFR_MANT (b) + bn - n, n);
+ }
+ if (b != c)
+ {
+ if (cn > n)
+ cp --; /* FIXME: Could this happen? */
+ else
+ {
+ cp = MPFR_TMP_LIMBS_ALLOC (n + 1);
+ cp[0] = 0;
+ MPN_COPY (cp + 1, MPFR_MANT (c) + cn - n, n);
+ }
+ }
+ /* We will compute with one extra limb */
+ n++;
+ /* ceil(log2(n+2)) takes into account the lost bits due to
+ Mulders' short product */
+ p = n * GMP_NUMB_BITS - MPFR_INT_CEIL_LOG2 (n + 2);
+ /* Due to some nasty reasons we can have only 4 bits */
+ MPFR_ASSERTD (MPFR_PREC (a) <= p - 4);
+
+ if (MPFR_LIKELY (k < 2*n))
+ {
+ tmp = MPFR_TMP_LIMBS_ALLOC (2 * n);
+ tmp += 2*n-k; /* `tmp' still points to an area of `k' limbs */
+ }
+ }
+ MPFR_LOG_MSG (("Use mpfr_mulhigh (%lu VS %lu)\n", MPFR_PREC (a), p));
+ /* Compute an approximation of the product of b and c */
+ if (b != c)
+ mpfr_mulhigh_n (tmp + k - 2 * n, bp, cp, n);
+ else
+ mpfr_sqrhigh_n (tmp + k - 2 * n, bp, n);
+ /* now tmp[0]..tmp[k-1] contains the product of both mantissa,
+ with tmp[k-1]>=2^(GMP_NUMB_BITS-2) */
+ /* [VL] FIXME: This cannot be true: mpfr_mulhigh_n only
+ depends on pointers and n. As k can be arbitrarily larger,
+ the result cannot depend on k. And indeed, with GMP compiled
+ with --enable-alloca=debug, valgrind was complaining, at
+ least because MPFR_RNDRAW at the end tried to compute the
+ sticky bit even when not necessary; this problem is fixed,
+ but there's at least something wrong with the comment above. */
+ b1 = tmp[k-1] >> (GMP_NUMB_BITS - 1); /* msb from the product */
+
+ /* If the mantissas of b and c are uniformly distributed in (1/2, 1],
+ then their product is in (1/4, 1/2] with probability 2*ln(2)-1
+ ~ 0.386 and in [1/2, 1] with probability 2-2*ln(2) ~ 0.614 */
+ if (MPFR_UNLIKELY (b1 == 0))
+ /* Warning: the mpfr_mulhigh_n call above only surely affects
+ tmp[k-n-1..k-1], thus we shift only those limbs */
+ mpn_lshift (tmp + k - n - 1, tmp + k - n - 1, n + 1, 1);
+ tmp += k - tn;
+ MPFR_ASSERTD (MPFR_LIMB_MSB (tmp[tn-1]) != 0);
+
+ /* if the most significant bit b1 is zero, we have only p-1 correct
+ bits */
+ if (MPFR_UNLIKELY (!mpfr_round_p (tmp, tn, p + b1 - 1, MPFR_PREC(a)
+ + (rnd_mode == MPFR_RNDN))))
+ {
+ tmp -= k - tn; /* tmp may have changed, FIX IT!!!!! */
+ goto full_multiply;
+ }
+ }
+ else
+ {
+ full_multiply:
+ MPFR_LOG_MSG (("Use mpn_mul\n", 0));
+ b1 = mpn_mul (tmp, MPFR_MANT (b), bn, MPFR_MANT (c), cn);
+
+ /* now tmp[0]..tmp[k-1] contains the product of both mantissa,
+ with tmp[k-1]>=2^(GMP_NUMB_BITS-2) */
+ b1 >>= GMP_NUMB_BITS - 1; /* msb from the product */
+
+ /* if the mantissas of b and c are uniformly distributed in (1/2, 1],
+ then their product is in (1/4, 1/2] with probability 2*ln(2)-1
+ ~ 0.386 and in [1/2, 1] with probability 2-2*ln(2) ~ 0.614 */
+ tmp += k - tn;
+ if (MPFR_UNLIKELY (b1 == 0))
+ mpn_lshift (tmp, tmp, tn, 1); /* tn <= k, so no stack corruption */
+ }
+
+ ax2 = ax + (mpfr_exp_t) (b1 - 1);
+ MPFR_RNDRAW (inexact, a, tmp, bq+cq, rnd_mode, sign, ax2++);
+ MPFR_TMP_FREE (marker);
+ MPFR_EXP (a) = ax2; /* Can't use MPFR_SET_EXP: Expo may be out of range */
+ MPFR_SET_SIGN (a, sign);
+ if (MPFR_UNLIKELY (ax2 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, sign);
+ if (MPFR_UNLIKELY (ax2 < __gmpfr_emin))
+ {
+ /* In the rounding to the nearest mode, if the exponent of the exact
+ result (i.e. before rounding, i.e. without taking cc into account)
+ is < __gmpfr_emin - 1 or the exact result is a power of 2 (i.e. if
+ both arguments are powers of 2), then round to zero. */
+ if (rnd_mode == MPFR_RNDN
+ && (ax + (mpfr_exp_t) b1 < __gmpfr_emin
+ || (mpfr_powerof2_raw (b) && mpfr_powerof2_raw (c))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, sign);
+ }
+ MPFR_RET (inexact);
+}
diff --git a/mpfr/src/mul_2exp.c b/mpfr/src/mul_2exp.c
new file mode 100644
index 0000000000..a3e245061f
--- /dev/null
+++ b/mpfr/src/mul_2exp.c
@@ -0,0 +1,33 @@
+/* mpfr_mul_2exp -- multiply a floating-point number by a power of two
+
+Copyright 1999, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Obsolete function, use mpfr_mul_2ui or mpfr_mul_2si instead. */
+
+#undef mpfr_mul_2exp
+
+int
+mpfr_mul_2exp (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_mul_2ui (y, x, n, rnd_mode);
+}
diff --git a/mpfr/src/mul_2si.c b/mpfr/src/mul_2si.c
new file mode 100644
index 0000000000..814a30de22
--- /dev/null
+++ b/mpfr/src/mul_2si.c
@@ -0,0 +1,59 @@
+/* mpfr_mul_2si -- multiply a floating-point number by a power of two
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_mul_2si (mpfr_ptr y, mpfr_srcptr x, long int n, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg n=%ld rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x, n, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ return mpfr_set (y, x, rnd_mode);
+ else
+ {
+ mpfr_exp_t exp = MPFR_GET_EXP (x);
+ MPFR_SETRAW (inexact, y, x, exp, rnd_mode);
+ if (MPFR_UNLIKELY( n > 0 && (__gmpfr_emax < MPFR_EMIN_MIN + n ||
+ exp > __gmpfr_emax - n)))
+ return mpfr_overflow (y, rnd_mode, MPFR_SIGN(y));
+ else if (MPFR_UNLIKELY(n < 0 && (__gmpfr_emin > MPFR_EMAX_MAX + n ||
+ exp < __gmpfr_emin - n)))
+ {
+ if (rnd_mode == MPFR_RNDN &&
+ (__gmpfr_emin > MPFR_EMAX_MAX + (n + 1) ||
+ exp < __gmpfr_emin - (n + 1) ||
+ (inexact >= 0 && mpfr_powerof2_raw (y))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (y, rnd_mode, MPFR_SIGN(y));
+ }
+ MPFR_SET_EXP (y, exp + n);
+ }
+
+ MPFR_RET (inexact);
+}
diff --git a/mpfr/src/mul_2ui.c b/mpfr/src/mul_2ui.c
new file mode 100644
index 0000000000..a4bafe9a23
--- /dev/null
+++ b/mpfr/src/mul_2ui.c
@@ -0,0 +1,66 @@
+/* mpfr_mul_2ui -- multiply a floating-point number by a power of two
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_mul_2ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg n=%lu rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x, n, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ inexact = MPFR_UNLIKELY(y != x) ? mpfr_set (y, x, rnd_mode) : 0;
+
+ if (MPFR_LIKELY( MPFR_IS_PURE_FP(y)) )
+ {
+ /* n will have to be casted to long to make sure that the addition
+ and subtraction below (for overflow detection) are signed */
+ while (MPFR_UNLIKELY(n > LONG_MAX))
+ {
+ int inex2;
+
+ n -= LONG_MAX;
+ inex2 = mpfr_mul_2ui(y, y, LONG_MAX, rnd_mode);
+ if (inex2)
+ return inex2; /* overflow */
+ }
+
+ /* MPFR_EMIN_MIN + (long) n is signed and doesn't lead to an overflow;
+ the first test useful so that the real test can't lead to an
+ overflow. */
+ {
+ mpfr_exp_t exp = MPFR_GET_EXP (y);
+ if (MPFR_UNLIKELY( __gmpfr_emax < MPFR_EMIN_MIN + (long) n ||
+ exp > __gmpfr_emax - (long) n))
+ return mpfr_overflow (y, rnd_mode, MPFR_SIGN(y));
+
+ MPFR_SET_EXP (y, exp + (long) n);
+ }
+ }
+
+ return inexact;
+}
diff --git a/mpfr/src/mul_d.c b/mpfr/src/mul_d.c
new file mode 100644
index 0000000000..d1296da9c6
--- /dev/null
+++ b/mpfr/src/mul_d.c
@@ -0,0 +1,52 @@
+/* mpfr_mul_d -- multiply a multiple precision floating-point number
+ by a machine double precision float
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_mul_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t d;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("b[%Pu]=%.*Rg c=%.20g rnd=%d",
+ mpfr_get_prec(b), mpfr_log_prec, b, c, rnd_mode),
+ ("a[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (a), mpfr_log_prec, a, inexact));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ inexact = mpfr_set_d (d, c, rnd_mode);
+ MPFR_ASSERTN (inexact == 0);
+
+ mpfr_clear_flags ();
+ inexact = mpfr_mul (a, b, d, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
+ mpfr_clear(d);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (a, inexact, rnd_mode);
+}
diff --git a/mpfr/src/mul_ui.c b/mpfr/src/mul_ui.c
new file mode 100644
index 0000000000..8c9258a21d
--- /dev/null
+++ b/mpfr/src/mul_ui.c
@@ -0,0 +1,133 @@
+/* mpfr_mul_ui -- multiply a floating-point number by a machine integer
+ mpfr_mul_si -- multiply a floating-point number by a machine integer
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode)
+{
+ mp_limb_t *yp;
+ mp_size_t xn;
+ int cnt, inexact;
+ MPFR_TMP_DECL (marker);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ if (u != 0)
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0); /* infinity is exact */
+ }
+ else /* 0 * infinity */
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ }
+ else /* x is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0); /* zero is exact */
+ }
+ }
+ else if (MPFR_UNLIKELY (u <= 1))
+ {
+ if (u < 1)
+ {
+ MPFR_SET_ZERO (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0); /* zero is exact */
+ }
+ else
+ return mpfr_set (y, x, rnd_mode);
+ }
+ else if (MPFR_UNLIKELY (IS_POW2 (u)))
+ return mpfr_mul_2si (y, x, MPFR_INT_CEIL_LOG2 (u), rnd_mode);
+
+ yp = MPFR_MANT (y);
+ xn = MPFR_LIMB_SIZE (x);
+
+ MPFR_ASSERTD (xn < MP_SIZE_T_MAX);
+ MPFR_TMP_MARK(marker);
+ yp = MPFR_TMP_LIMBS_ALLOC (xn + 1);
+
+ MPFR_ASSERTN (u == (mp_limb_t) u);
+ yp[xn] = mpn_mul_1 (yp, MPFR_MANT (x), xn, u);
+
+ /* x * u is stored in yp[xn], ..., yp[0] */
+
+ /* since the case u=1 was treated above, we have u >= 2, thus
+ yp[xn] >= 1 since x was msb-normalized */
+ MPFR_ASSERTD (yp[xn] != 0);
+ if (MPFR_LIKELY (MPFR_LIMB_MSB (yp[xn]) == 0))
+ {
+ count_leading_zeros (cnt, yp[xn]);
+ mpn_lshift (yp, yp, xn + 1, cnt);
+ }
+ else
+ {
+ cnt = 0;
+ }
+
+ /* now yp[xn], ..., yp[0] is msb-normalized too, and has at most
+ PREC(x) + (GMP_NUMB_BITS - cnt) non-zero bits */
+ MPFR_RNDRAW (inexact, y, yp, (mpfr_prec_t) (xn + 1) * GMP_NUMB_BITS,
+ rnd_mode, MPFR_SIGN (x), cnt -- );
+
+ MPFR_TMP_FREE (marker);
+
+ cnt = GMP_NUMB_BITS - cnt;
+ if (MPFR_UNLIKELY (__gmpfr_emax < MPFR_EMAX_MIN + cnt
+ || MPFR_GET_EXP (x) > __gmpfr_emax - cnt))
+ return mpfr_overflow (y, rnd_mode, MPFR_SIGN(x));
+
+ MPFR_SET_EXP (y, MPFR_GET_EXP (x) + cnt);
+ MPFR_SET_SAME_SIGN (y, x);
+
+ return inexact;
+}
+
+int mpfr_mul_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
+{
+ int res;
+
+ if (u >= 0)
+ res = mpfr_mul_ui (y, x, u, rnd_mode);
+ else
+ {
+ res = -mpfr_mul_ui (y, x, -u, MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ }
+ return res;
+}
diff --git a/mpfr/src/mulders.c b/mpfr/src/mulders.c
new file mode 100644
index 0000000000..273c75a594
--- /dev/null
+++ b/mpfr/src/mulders.c
@@ -0,0 +1,495 @@
+/* Mulders' MulHigh function (short product)
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* References:
+ [1] Short Division of Long Integers, David Harvey and Paul Zimmermann,
+ Proceedings of the 20th Symposium on Computer Arithmetic (ARITH-20),
+ July 25-27, 2011, pages 7-14.
+*/
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#ifndef MUL_FFT_THRESHOLD
+#define MUL_FFT_THRESHOLD 8448
+#endif
+
+/* Don't use MPFR_MULHIGH_SIZE since it is handled by tuneup */
+#ifdef MPFR_MULHIGH_TAB_SIZE
+static short mulhigh_ktab[MPFR_MULHIGH_TAB_SIZE];
+#else
+static short mulhigh_ktab[] = {MPFR_MULHIGH_TAB};
+#define MPFR_MULHIGH_TAB_SIZE \
+ ((mp_size_t) (sizeof(mulhigh_ktab) / sizeof(mulhigh_ktab[0])))
+#endif
+
+/* Put in rp[n..2n-1] an approximation of the n high limbs
+ of {up, n} * {vp, n}. The error is less than n ulps of rp[n] (and the
+ approximation is always less or equal to the truncated full product).
+ Assume 2n limbs are allocated at rp.
+
+ Implements Algorithm ShortMulNaive from [1].
+*/
+static void
+mpfr_mulhigh_n_basecase (mpfr_limb_ptr rp, mpfr_limb_srcptr up,
+ mpfr_limb_srcptr vp, mp_size_t n)
+{
+ mp_size_t i;
+
+ rp += n - 1;
+ umul_ppmm (rp[1], rp[0], up[n-1], vp[0]); /* we neglect up[0..n-2]*vp[0],
+ which is less than B^n */
+ for (i = 1 ; i < n ; i++)
+ /* here, we neglect up[0..n-i-2] * vp[i], which is less than B^n too */
+ rp[i + 1] = mpn_addmul_1 (rp, up + (n - i - 1), i + 1, vp[i]);
+ /* in total, we neglect less than n*B^n, i.e., n ulps of rp[n]. */
+}
+
+/* Put in rp[0..n] the n+1 low limbs of {up, n} * {vp, n}.
+ Assume 2n limbs are allocated at rp. */
+static void
+mpfr_mullow_n_basecase (mpfr_limb_ptr rp, mpfr_limb_srcptr up,
+ mpfr_limb_srcptr vp, mp_size_t n)
+{
+ mp_size_t i;
+
+ rp[n] = mpn_mul_1 (rp, up, n, vp[0]);
+ for (i = 1 ; i < n ; i++)
+ mpn_addmul_1 (rp + i, up, n - i + 1, vp[i]);
+}
+
+/* Put in rp[n..2n-1] an approximation of the n high limbs
+ of {np, n} * {mp, n}. The error is less than n ulps of rp[n] (and the
+ approximation is always less or equal to the truncated full product).
+
+ Implements Algorithm ShortMul from [1].
+*/
+void
+mpfr_mulhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mpfr_limb_srcptr mp,
+ mp_size_t n)
+{
+ mp_size_t k;
+
+ MPFR_ASSERTN (MPFR_MULHIGH_TAB_SIZE >= 8); /* so that 3*(n/4) > n/2 */
+ k = MPFR_LIKELY (n < MPFR_MULHIGH_TAB_SIZE) ? mulhigh_ktab[n] : 3*(n/4);
+ /* Algorithm ShortMul from [1] requires k >= (n+3)/2, which translates
+ into k >= (n+4)/2 in the C language. */
+ MPFR_ASSERTD (k == -1 || k == 0 || (k >= (n+4)/2 && k < n));
+ if (k < 0)
+ mpn_mul_basecase (rp, np, n, mp, n); /* result is exact, no error */
+ else if (k == 0)
+ mpfr_mulhigh_n_basecase (rp, np, mp, n); /* basecase error < n ulps */
+ else if (n > MUL_FFT_THRESHOLD)
+ mpn_mul_n (rp, np, mp, n); /* result is exact, no error */
+ else
+ {
+ mp_size_t l = n - k;
+ mp_limb_t cy;
+
+ mpn_mul_n (rp + 2 * l, np + l, mp + l, k); /* fills rp[2l..2n-1] */
+ mpfr_mulhigh_n (rp, np + k, mp, l); /* fills rp[l-1..2l-1] */
+ cy = mpn_add_n (rp + n - 1, rp + n - 1, rp + l - 1, l + 1);
+ mpfr_mulhigh_n (rp, np, mp + k, l); /* fills rp[l-1..2l-1] */
+ cy += mpn_add_n (rp + n - 1, rp + n - 1, rp + l - 1, l + 1);
+ mpn_add_1 (rp + n + l, rp + n + l, k, cy); /* propagate carry */
+ }
+}
+
+/* Put in rp[0..n] the n+1 low limbs of {np, n} * {mp, n}.
+ Assume 2n limbs are allocated at rp. */
+void
+mpfr_mullow_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mpfr_limb_srcptr mp,
+ mp_size_t n)
+{
+ mp_size_t k;
+
+ MPFR_ASSERTN (MPFR_MULHIGH_TAB_SIZE >= 8); /* so that 3*(n/4) > n/2 */
+ k = MPFR_LIKELY (n < MPFR_MULHIGH_TAB_SIZE) ? mulhigh_ktab[n] : 3*(n/4);
+ MPFR_ASSERTD (k == -1 || k == 0 || (2 * k >= n && k < n));
+ if (k < 0)
+ mpn_mul_basecase (rp, np, n, mp, n);
+ else if (k == 0)
+ mpfr_mullow_n_basecase (rp, np, mp, n);
+ else if (n > MUL_FFT_THRESHOLD)
+ mpn_mul_n (rp, np, mp, n);
+ else
+ {
+ mp_size_t l = n - k;
+
+ mpn_mul_n (rp, np, mp, k); /* fills rp[0..2k] */
+ mpfr_mullow_n (rp + n, np + k, mp, l); /* fills rp[n..n+2l] */
+ mpn_add_n (rp + k, rp + k, rp + n, l + 1);
+ mpfr_mullow_n (rp + n, np, mp + k, l); /* fills rp[n..n+2l] */
+ mpn_add_n (rp + k, rp + k, rp + n, l + 1);
+ }
+}
+
+#ifdef MPFR_SQRHIGH_TAB_SIZE
+static short sqrhigh_ktab[MPFR_SQRHIGH_TAB_SIZE];
+#else
+static short sqrhigh_ktab[] = {MPFR_SQRHIGH_TAB};
+#define MPFR_SQRHIGH_TAB_SIZE (sizeof(sqrhigh_ktab) / sizeof(sqrhigh_ktab[0]))
+#endif
+
+/* Put in rp[n..2n-1] an approximation of the n high limbs
+ of {np, n}^2. The error is less than n ulps of rp[n]. */
+void
+mpfr_sqrhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mp_size_t n)
+{
+ mp_size_t k;
+
+ MPFR_ASSERTN (MPFR_SQRHIGH_TAB_SIZE > 2); /* ensures k < n */
+ k = MPFR_LIKELY (n < MPFR_SQRHIGH_TAB_SIZE) ? sqrhigh_ktab[n]
+ : (n+4)/2; /* ensures that k >= (n+3)/2 */
+ MPFR_ASSERTD (k == -1 || k == 0 || (k >= (n+4)/2 && k < n));
+ if (k < 0)
+ /* we can't use mpn_sqr_basecase here, since it requires
+ n <= SQR_KARATSUBA_THRESHOLD, where SQR_KARATSUBA_THRESHOLD
+ is not exported by GMP */
+ mpn_sqr_n (rp, np, n);
+ else if (k == 0)
+ mpfr_mulhigh_n_basecase (rp, np, np, n);
+ else
+ {
+ mp_size_t l = n - k;
+ mp_limb_t cy;
+
+ mpn_sqr_n (rp + 2 * l, np + l, k); /* fills rp[2l..2n-1] */
+ mpfr_mulhigh_n (rp, np, np + k, l); /* fills rp[l-1..2l-1] */
+ /* {rp+n-1,l+1} += 2 * {rp+l-1,l+1} */
+ cy = mpn_lshift (rp + l - 1, rp + l - 1, l + 1, 1);
+ cy += mpn_add_n (rp + n - 1, rp + n - 1, rp + l - 1, l + 1);
+ mpn_add_1 (rp + n + l, rp + n + l, k, cy); /* propagate carry */
+ }
+}
+
+#ifdef MPFR_DIVHIGH_TAB_SIZE
+static short divhigh_ktab[MPFR_DIVHIGH_TAB_SIZE];
+#else
+static short divhigh_ktab[] = {MPFR_DIVHIGH_TAB};
+#define MPFR_DIVHIGH_TAB_SIZE (sizeof(divhigh_ktab) / sizeof(divhigh_ktab[0]))
+#endif
+
+#ifndef __GMPFR_GMP_H__
+#define mpfr_pi1_t gmp_pi1_t /* with a GMP build */
+#endif
+
+#if !(defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_SBPI1_DIVAPPR_Q))
+/* Put in Q={qp, n} an approximation of N={np, 2*n} divided by D={dp, n},
+ with the most significant limb of the quotient as return value (0 or 1).
+ Assumes the most significant bit of D is set. Clobbers N.
+
+ The approximate quotient Q satisfies - 2(n-1) < N/D - Q <= 4.
+*/
+static mp_limb_t
+mpfr_divhigh_n_basecase (mpfr_limb_ptr qp, mpfr_limb_ptr np,
+ mpfr_limb_srcptr dp, mp_size_t n)
+{
+ mp_limb_t qh, d1, d0, dinv, q2, q1, q0;
+ mpfr_pi1_t dinv2;
+
+ np += n;
+
+ if ((qh = (mpn_cmp (np, dp, n) >= 0)))
+ mpn_sub_n (np, np, dp, n);
+
+ /* now {np, n} is less than D={dp, n}, which implies np[n-1] <= dp[n-1] */
+
+ d1 = dp[n - 1];
+
+ if (n == 1)
+ {
+ invert_limb (dinv, d1);
+ umul_ppmm (q1, q0, np[0], dinv);
+ qp[0] = np[0] + q1;
+ return qh;
+ }
+
+ /* now n >= 2 */
+ d0 = dp[n - 2];
+ invert_pi1 (dinv2, d1, d0);
+ /* dinv2.inv32 = floor ((B^3 - 1) / (d0 + d1 B)) - B */
+ while (n > 1)
+ {
+ /* Invariant: it remains to reduce n limbs from N (in addition to the
+ initial low n limbs).
+ Since n >= 2 here, necessarily we had n >= 2 initially, which means
+ that in addition to the limb np[n-1] to reduce, we have at least 2
+ extra limbs, thus accessing np[n-3] is valid. */
+
+ /* warning: we can have np[n-1]=d1 and np[n-2]=d0, but since {np,n} < D,
+ the largest possible partial quotient is B-1 */
+ if (MPFR_UNLIKELY(np[n - 1] == d1 && np[n - 2] == d0))
+ q2 = ~ (mp_limb_t) 0;
+ else
+ udiv_qr_3by2 (q2, q1, q0, np[n - 1], np[n - 2], np[n - 3],
+ d1, d0, dinv2.inv32);
+ /* since q2 = floor((np[n-1]*B^2+np[n-2]*B+np[n-3])/(d1*B+d0)),
+ we have q2 <= (np[n-1]*B^2+np[n-2]*B+np[n-3])/(d1*B+d0),
+ thus np[n-1]*B^2+np[n-2]*B+np[n-3] >= q2*(d1*B+d0)
+ and {np-1, n} >= q2*D - q2*B^(n-2) >= q2*D - B^(n-1)
+ thus {np-1, n} - (q2-1)*D >= D - B^(n-1) >= 0
+ which proves that at most one correction is needed */
+ q0 = mpn_submul_1 (np - 1, dp, n, q2);
+ if (MPFR_UNLIKELY(q0 > np[n - 1]))
+ {
+ mpn_add_n (np - 1, np - 1, dp, n);
+ q2 --;
+ }
+ qp[--n] = q2;
+ dp ++;
+ }
+
+ /* we have B+dinv2 = floor((B^3-1)/(d1*B+d0)) < B^2/d1
+ q1 = floor(np[0]*(B+dinv2)/B) <= floor(np[0]*B/d1)
+ <= floor((np[0]*B+np[1])/d1)
+ thus q1 is not larger than the true quotient.
+ q1 > np[0]*(B+dinv2)/B - 1 > np[0]*(B^3-1)/(d1*B+d0)/B - 2
+ For d1*B+d0 <> B^2/2, we have B+dinv2 = floor(B^3/(d1*B+d0))
+ thus q1 > np[0]*B^2/(d1*B+d0) - 2, i.e.,
+ (d1*B+d0)*q1 > np[0]*B^2 - 2*(d1*B+d0)
+ d1*B*q1 > np[0]*B^2 - 2*d1*B - 2*d0 - d0*q1 >= np[0]*B^2 - 2*d1*B - B^2
+ thus q1 > np[0]*B/d1 - 2 - B/d1 > np[0]*B/d1 - 4.
+
+ For d1*B+d0 = B^2/2, dinv2 = B-1 thus q1 > np[0]*(2B-1)/B - 1 >
+ np[0]*B/d1 - 2.
+
+ In all cases, if q = floor((np[0]*B+np[1])/d1), we have:
+ q - 4 <= q1 <= q
+ */
+ umul_ppmm (q1, q0, np[0], dinv2.inv32);
+ qp[0] = np[0] + q1;
+
+ return qh;
+}
+#endif
+
+/* Put in {qp, n} an approximation of N={np, 2*n} divided by D={dp, n},
+ with the most significant limb of the quotient as return value (0 or 1).
+ Assumes the most significant bit of D is set. Clobbers N.
+
+ This implements the ShortDiv algorithm from reference [1].
+*/
+#if 1
+mp_limb_t
+mpfr_divhigh_n (mpfr_limb_ptr qp, mpfr_limb_ptr np, mpfr_limb_ptr dp,
+ mp_size_t n)
+{
+ mp_size_t k, l;
+ mp_limb_t qh, cy;
+ mpfr_limb_ptr tp;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_ASSERTN (MPFR_MULHIGH_TAB_SIZE >= 15); /* so that 2*(n/3) >= (n+4)/2 */
+ k = MPFR_LIKELY (n < MPFR_DIVHIGH_TAB_SIZE) ? divhigh_ktab[n] : 2*(n/3);
+
+ if (k == 0)
+#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_SBPI1_DIVAPPR_Q)
+ {
+ mpfr_pi1_t dinv2;
+ invert_pi1 (dinv2, dp[n - 1], dp[n - 2]);
+ return __gmpn_sbpi1_divappr_q (qp, np, n + n, dp, n, dinv2.inv32);
+ }
+#else /* use our own code for base-case short division */
+ return mpfr_divhigh_n_basecase (qp, np, dp, n);
+#endif
+ else if (k == n)
+ /* for k=n, we use a division with remainder (mpn_divrem),
+ which computes the exact quotient */
+ return mpn_divrem (qp, 0, np, 2 * n, dp, n);
+
+ MPFR_ASSERTD ((n+4)/2 <= k && k < n); /* bounds from [1] */
+ MPFR_TMP_MARK (marker);
+ l = n - k;
+ /* first divide the most significant 2k limbs from N by the most significant
+ k limbs of D */
+ qh = mpn_divrem (qp + l, 0, np + 2 * l, 2 * k, dp + l, k); /* exact */
+
+ /* it remains {np,2l+k} = {np,n+l} as remainder */
+
+ /* now we have to subtract high(Q1)*D0 where Q1=qh*B^k+{qp+l,k} and
+ D0={dp,l} */
+ tp = MPFR_TMP_LIMBS_ALLOC (2 * l);
+ mpfr_mulhigh_n (tp, qp + k, dp, l);
+ /* we are only interested in the upper l limbs from {tp,2l} */
+ cy = mpn_sub_n (np + n, np + n, tp + l, l);
+ if (qh)
+ cy += mpn_sub_n (np + n, np + n, dp, l);
+ while (cy > 0) /* Q1 was too large: subtract 1 to Q1 and add D to np+l */
+ {
+ qh -= mpn_sub_1 (qp + l, qp + l, k, MPFR_LIMB_ONE);
+ cy -= mpn_add_n (np + l, np + l, dp, n);
+ }
+
+ /* now it remains {np,n+l} to divide by D */
+ cy = mpfr_divhigh_n (qp, np + k, dp + k, l);
+ qh += mpn_add_1 (qp + l, qp + l, k, cy);
+ MPFR_TMP_FREE(marker);
+
+ return qh;
+}
+#else /* below is the FoldDiv(K) algorithm from [1] */
+mp_limb_t
+mpfr_divhigh_n (mpfr_limb_ptr qp, mpfr_limb_ptr np, mpfr_limb_ptr dp,
+ mp_size_t n)
+{
+ mp_size_t k, r;
+ mpfr_limb_ptr ip, tp, up;
+ mp_limb_t qh = 0, cy, cc;
+ int count;
+ MPFR_TMP_DECL(marker);
+
+#define K 3
+ if (n < K)
+ return mpn_divrem (qp, 0, np, 2 * n, dp, n);
+
+ k = (n - 1) / K + 1; /* ceil(n/K) */
+
+ MPFR_TMP_MARK (marker);
+ ip = MPFR_TMP_LIMBS_ALLOC (k + 1);
+ tp = MPFR_TMP_LIMBS_ALLOC (n + k);
+ up = MPFR_TMP_LIMBS_ALLOC (2 * (k + 1));
+ mpn_invert (ip, dp + n - (k + 1), k + 1, NULL); /* takes about 13% for n=1000 */
+ /* {ip, k+1} = floor((B^(2k+2)-1)/D - B^(k+1) where D = {dp+n-(k+1),k+1} */
+ for (r = n, cc = 0UL; r > 0;)
+ {
+ /* cc is the carry at np[n+r] */
+ MPFR_ASSERTD(cc <= 1);
+ /* FIXME: why can we have cc as large as say 8? */
+ count = 0;
+ while (cc > 0)
+ {
+ count ++;
+ MPFR_ASSERTD(count <= 1);
+ /* subtract {dp+n-r,r} from {np+n,r} */
+ cc -= mpn_sub_n (np + n, np + n, dp + n - r, r);
+ /* add 1 at qp[r] */
+ qh += mpn_add_1 (qp + r, qp + r, n - r, 1UL);
+ }
+ /* it remains r limbs to reduce, i.e., the remainder is {np, n+r} */
+ if (r < k)
+ {
+ ip += k - r;
+ k = r;
+ }
+ /* now r >= k */
+ /* qp + r - 2 * k -> up */
+ mpfr_mulhigh_n (up, np + n + r - (k + 1), ip, k + 1);
+ /* take into account the term B^k in the inverse: B^k * {np+n+r-k, k} */
+ cy = mpn_add_n (qp + r - k, up + k + 2, np + n + r - k, k);
+ /* since we need only r limbs of tp (below), it suffices to consider
+ r high limbs of dp */
+ if (r > k)
+ {
+#if 0
+ mpn_mul (tp, dp + n - r, r, qp + r - k, k);
+#else /* use a short product for the low k x k limbs */
+ /* we know the upper k limbs of the r-limb product cancel with the
+ remainder, thus we only need to compute the low r-k limbs */
+ if (r - k >= k)
+ mpn_mul (tp + k, dp + n - r + k, r - k, qp + r - k, k);
+ else /* r-k < k */
+ {
+/* #define LOW */
+#ifndef LOW
+ mpn_mul (tp + k, qp + r - k, k, dp + n - r + k, r - k);
+#else
+ mpfr_mullow_n_basecase (tp + k, qp + r - k, dp + n - r + k, r - k);
+ /* take into account qp[2r-2k] * dp[n - r + k] */
+ tp[r] += qp[2*r-2*k] * dp[n - r + k];
+#endif
+ /* tp[k..r] is filled */
+ }
+#if 0
+ mpfr_mulhigh_n (up, dp + n - r, qp + r - k, k);
+#else /* compute one more limb. FIXME: we could add one limb of dp in the
+ above, to save one mpn_addmul_1 call */
+ mpfr_mulhigh_n (up, dp + n - r, qp + r - k, k - 1); /* {up,2k-2} */
+ /* add {qp + r - k, k - 1} * dp[n-r+k-1] */
+ up[2*k-2] = mpn_addmul_1 (up + k - 1, qp + r - k, k-1, dp[n-r+k-1]);
+ /* add {dp+n-r, k} * qp[r-1] */
+ up[2*k-1] = mpn_addmul_1 (up + k - 1, dp + n - r, k, qp[r-1]);
+#endif
+#ifndef LOW
+ cc = mpn_add_n (tp + k, tp + k, up + k, k);
+ mpn_add_1 (tp + 2 * k, tp + 2 * k, r - k, cc);
+#else
+ /* update tp[k..r] */
+ if (r - k + 1 <= k)
+ mpn_add_n (tp + k, tp + k, up + k, r - k + 1);
+ else /* r - k >= k */
+ {
+ cc = mpn_add_n (tp + k, tp + k, up + k, k);
+ mpn_add_1 (tp + 2 * k, tp + 2 * k, r - 2 * k + 1, cc);
+ }
+#endif
+#endif
+ }
+ else /* last step: since we only want the quotient, no need to update,
+ just propagate the carry cy */
+ {
+ MPFR_ASSERTD(r < n);
+ if (cy > 0)
+ qh += mpn_add_1 (qp + r, qp + r, n - r, cy);
+ break;
+ }
+ /* subtract {tp, n+k} from {np+r-k, n+k}; however we only want to
+ update {np+n, n} */
+ /* we should have tp[r] = np[n+r-k] up to 1 */
+ MPFR_ASSERTD(tp[r] == np[n + r - k] || tp[r] + 1 == np[n + r - k]);
+#ifndef LOW
+ cc = mpn_sub_n (np + n - 1, np + n - 1, tp + k - 1, r + 1); /* borrow at np[n+r] */
+#else
+ cc = mpn_sub_n (np + n - 1, np + n - 1, tp + k - 1, r - k + 2);
+#endif
+ /* if cy = 1, subtract {dp, n} from {np+r, n}, thus
+ {dp+n-r,r} from {np+n,r} */
+ if (cy)
+ {
+ if (r < n)
+ cc += mpn_sub_n (np + n - 1, np + n - 1, dp + n - r - 1, r + 1);
+ else
+ cc += mpn_sub_n (np + n, np + n, dp + n - r, r);
+ /* propagate cy */
+ if (r == n)
+ qh = cy;
+ else
+ qh += mpn_add_1 (qp + r, qp + r, n - r, cy);
+ }
+ /* cc is the borrow at np[n+r] */
+ count = 0;
+ while (cc > 0) /* quotient was too large */
+ {
+ count++;
+ MPFR_ASSERTD (count <= 1);
+ cy = mpn_add_n (np + n, np + n, dp + n - (r - k), r - k);
+ cc -= mpn_add_1 (np + n + r - k, np + n + r - k, k, cy);
+ qh -= mpn_sub_1 (qp + r - k, qp + r - k, n - (r - k), 1UL);
+ }
+ r -= k;
+ cc = np[n + r];
+ }
+ MPFR_TMP_FREE(marker);
+
+ return qh;
+}
+#endif
diff --git a/mpfr/src/neg.c b/mpfr/src/neg.c
new file mode 100644
index 0000000000..400b78b8a5
--- /dev/null
+++ b/mpfr/src/neg.c
@@ -0,0 +1,39 @@
+/* mpfr_neg -- change the sign of a floating-point number
+
+Copyright 1999, 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_neg (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_UNLIKELY(a != b))
+ return mpfr_set4 (a, b, rnd_mode, -MPFR_SIGN(b));
+ else if (MPFR_UNLIKELY(MPFR_IS_NAN (b)))
+ {
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ MPFR_CHANGE_SIGN(a);
+ MPFR_RET(0);
+ }
+}
diff --git a/mpfr/src/next.c b/mpfr/src/next.c
new file mode 100644
index 0000000000..849d206635
--- /dev/null
+++ b/mpfr/src/next.c
@@ -0,0 +1,150 @@
+/* mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward -- next representable
+floating-point number
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_nexttozero (mpfr_ptr x)
+{
+ if (MPFR_UNLIKELY(MPFR_IS_INF(x)))
+ {
+ mpfr_setmax (x, __gmpfr_emax);
+ return;
+ }
+ else if (MPFR_UNLIKELY( MPFR_IS_ZERO(x) ))
+ {
+ MPFR_CHANGE_SIGN(x);
+ mpfr_setmin (x, __gmpfr_emin);
+ }
+ else
+ {
+ mp_size_t xn;
+ int sh;
+ mp_limb_t *xp;
+
+ xn = MPFR_LIMB_SIZE (x);
+ MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC(x));
+ xp = MPFR_MANT(x);
+ mpn_sub_1 (xp, xp, xn, MPFR_LIMB_ONE << sh);
+ if (MPFR_UNLIKELY( MPFR_LIMB_MSB(xp[xn-1]) == 0) )
+ { /* was an exact power of two: not normalized any more */
+ mpfr_exp_t exp = MPFR_EXP (x);
+ if (MPFR_UNLIKELY(exp == __gmpfr_emin))
+ MPFR_SET_ZERO(x);
+ else
+ {
+ mp_size_t i;
+ MPFR_SET_EXP (x, exp - 1);
+ xp[0] = MP_LIMB_T_MAX << sh;
+ for (i = 1; i < xn; i++)
+ xp[i] = MP_LIMB_T_MAX;
+ }
+ }
+ }
+}
+
+void
+mpfr_nexttoinf (mpfr_ptr x)
+{
+ if (MPFR_UNLIKELY(MPFR_IS_INF(x)))
+ return;
+ else if (MPFR_UNLIKELY(MPFR_IS_ZERO(x)))
+ mpfr_setmin (x, __gmpfr_emin);
+ else
+ {
+ mp_size_t xn;
+ int sh;
+ mp_limb_t *xp;
+
+ xn = MPFR_LIMB_SIZE (x);
+ MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC(x));
+ xp = MPFR_MANT(x);
+ if (MPFR_UNLIKELY( mpn_add_1 (xp, xp, xn, MPFR_LIMB_ONE << sh)) )
+ /* got 1.0000... */
+ {
+ mpfr_exp_t exp = MPFR_EXP (x);
+ if (MPFR_UNLIKELY(exp == __gmpfr_emax))
+ MPFR_SET_INF(x);
+ else
+ {
+ MPFR_SET_EXP (x, exp + 1);
+ xp[xn-1] = MPFR_LIMB_HIGHBIT;
+ }
+ }
+ }
+}
+
+void
+mpfr_nextabove (mpfr_ptr x)
+{
+ if (MPFR_UNLIKELY(MPFR_IS_NAN(x)))
+ {
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return;
+ }
+ if (MPFR_IS_NEG(x))
+ mpfr_nexttozero (x);
+ else
+ mpfr_nexttoinf (x);
+}
+
+void
+mpfr_nextbelow (mpfr_ptr x)
+{
+ if (MPFR_UNLIKELY(MPFR_IS_NAN(x)))
+ {
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return;
+ }
+
+ if (MPFR_IS_NEG(x))
+ mpfr_nexttoinf (x);
+ else
+ mpfr_nexttozero (x);
+}
+
+void
+mpfr_nexttoward (mpfr_ptr x, mpfr_srcptr y)
+{
+ int s;
+
+ if (MPFR_UNLIKELY(MPFR_IS_NAN(x)))
+ {
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return;
+ }
+ else if (MPFR_UNLIKELY(MPFR_IS_NAN(x) || MPFR_IS_NAN(y)))
+ {
+ MPFR_SET_NAN(x);
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return;
+ }
+
+ s = mpfr_cmp (x, y);
+ if (s == 0)
+ return;
+ else if (s < 0)
+ mpfr_nextabove (x);
+ else
+ mpfr_nextbelow (x);
+}
diff --git a/mpfr/src/out_str.c b/mpfr/src/out_str.c
new file mode 100644
index 0000000000..c32dbe2b88
--- /dev/null
+++ b/mpfr/src/out_str.c
@@ -0,0 +1,98 @@
+/* mpfr_out_str -- output a floating-point number to a stream
+
+Copyright 1999, 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Warning! S should not contain "%". */
+#define OUT_STR_RET(S) \
+ do \
+ { \
+ int r; \
+ r = fprintf (stream, (S)); \
+ return r < 0 ? 0 : r; \
+ } \
+ while (0)
+
+size_t
+mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op,
+ mpfr_rnd_t rnd_mode)
+{
+ char *s, *s0;
+ size_t l;
+ mpfr_exp_t e;
+ int err;
+
+ MPFR_ASSERTN (base >= 2 && base <= 62);
+
+ /* when stream=NULL, output to stdout */
+ if (stream == NULL)
+ stream = stdout;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (op)))
+ {
+ if (MPFR_IS_NAN (op))
+ OUT_STR_RET ("@NaN@");
+ else if (MPFR_IS_INF (op))
+ OUT_STR_RET (MPFR_IS_POS (op) ? "@Inf@" : "-@Inf@");
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (op));
+ OUT_STR_RET (MPFR_IS_POS (op) ? "0" : "-0");
+ }
+ }
+
+ s = mpfr_get_str (NULL, &e, base, n_digits, op, rnd_mode);
+
+ s0 = s;
+ /* for op=3.1416 we have s = "31416" and e = 1 */
+
+ l = strlen (s) + 1; /* size of allocated block returned by mpfr_get_str
+ - may be incorrect, as only an upper bound? */
+
+ /* outputs possible sign and significand */
+ err = (*s == '-' && fputc (*s++, stream) == EOF)
+ || fputc (*s++, stream) == EOF /* leading digit */
+ || fputc ((unsigned char) MPFR_DECIMAL_POINT, stream) == EOF
+ || fputs (s, stream) == EOF; /* trailing significand */
+ (*__gmp_free_func) (s0, l);
+ if (MPFR_UNLIKELY (err))
+ return 0;
+
+ e--; /* due to the leading digit */
+
+ /* outputs exponent */
+ if (e)
+ {
+ int r;
+
+ MPFR_ASSERTN(e >= LONG_MIN);
+ MPFR_ASSERTN(e <= LONG_MAX);
+
+ r = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e);
+ if (MPFR_UNLIKELY (r < 0))
+ return 0;
+
+ l += r;
+ }
+
+ return l;
+}
diff --git a/mpfr/src/pow.c b/mpfr/src/pow.c
new file mode 100644
index 0000000000..b0add7e682
--- /dev/null
+++ b/mpfr/src/pow.c
@@ -0,0 +1,715 @@
+/* mpfr_pow -- power function x^y
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* return non zero iff x^y is exact.
+ Assumes x and y are ordinary numbers,
+ y is not an integer, x is not a power of 2 and x is positive
+
+ If x^y is exact, it computes it and sets *inexact.
+*/
+static int
+mpfr_pow_is_exact (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y,
+ mpfr_rnd_t rnd_mode, int *inexact)
+{
+ mpz_t a, c;
+ mpfr_exp_t d, b;
+ unsigned long i;
+ int res;
+
+ MPFR_ASSERTD (!MPFR_IS_SINGULAR (y));
+ MPFR_ASSERTD (!MPFR_IS_SINGULAR (x));
+ MPFR_ASSERTD (!mpfr_integer_p (y));
+ MPFR_ASSERTD (mpfr_cmp_si_2exp (x, MPFR_INT_SIGN (x),
+ MPFR_GET_EXP (x) - 1) != 0);
+ MPFR_ASSERTD (MPFR_IS_POS (x));
+
+ if (MPFR_IS_NEG (y))
+ return 0; /* x is not a power of two => x^-y is not exact */
+
+ /* compute d such that y = c*2^d with c odd integer */
+ mpz_init (c);
+ d = mpfr_get_z_2exp (c, y);
+ i = mpz_scan1 (c, 0);
+ mpz_fdiv_q_2exp (c, c, i);
+ d += i;
+ /* now y=c*2^d with c odd */
+ /* Since y is not an integer, d is necessarily < 0 */
+ MPFR_ASSERTD (d < 0);
+
+ /* Compute a,b such that x=a*2^b */
+ mpz_init (a);
+ b = mpfr_get_z_2exp (a, x);
+ i = mpz_scan1 (a, 0);
+ mpz_fdiv_q_2exp (a, a, i);
+ b += i;
+ /* now x=a*2^b with a is odd */
+
+ for (res = 1 ; d != 0 ; d++)
+ {
+ /* a*2^b is a square iff
+ (i) a is a square when b is even
+ (ii) 2*a is a square when b is odd */
+ if (b % 2 != 0)
+ {
+ mpz_mul_2exp (a, a, 1); /* 2*a */
+ b --;
+ }
+ MPFR_ASSERTD ((b % 2) == 0);
+ if (!mpz_perfect_square_p (a))
+ {
+ res = 0;
+ goto end;
+ }
+ mpz_sqrt (a, a);
+ b = b / 2;
+ }
+ /* Now x = (a'*2^b')^(2^-d) with d < 0
+ so x^y = ((a'*2^b')^(2^-d))^(c*2^d)
+ = ((a'*2^b')^c with c odd integer */
+ {
+ mpfr_t tmp;
+ mpfr_prec_t p;
+ MPFR_MPZ_SIZEINBASE2 (p, a);
+ mpfr_init2 (tmp, p); /* prec = 1 should not be possible */
+ res = mpfr_set_z (tmp, a, MPFR_RNDN);
+ MPFR_ASSERTD (res == 0);
+ res = mpfr_mul_2si (tmp, tmp, b, MPFR_RNDN);
+ MPFR_ASSERTD (res == 0);
+ *inexact = mpfr_pow_z (z, tmp, c, rnd_mode);
+ mpfr_clear (tmp);
+ res = 1;
+ }
+ end:
+ mpz_clear (a);
+ mpz_clear (c);
+ return res;
+}
+
+/* Return 1 if y is an odd integer, 0 otherwise. */
+static int
+is_odd (mpfr_srcptr y)
+{
+ mpfr_exp_t expo;
+ mpfr_prec_t prec;
+ mp_size_t yn;
+ mp_limb_t *yp;
+
+ /* NAN, INF or ZERO are not allowed */
+ MPFR_ASSERTD (!MPFR_IS_SINGULAR (y));
+
+ expo = MPFR_GET_EXP (y);
+ if (expo <= 0)
+ return 0; /* |y| < 1 and not 0 */
+
+ prec = MPFR_PREC(y);
+ if ((mpfr_prec_t) expo > prec)
+ return 0; /* y is a multiple of 2^(expo-prec), thus not odd */
+
+ /* 0 < expo <= prec:
+ y = 1xxxxxxxxxt.zzzzzzzzzzzzzzzzzz[000]
+ expo bits (prec-expo) bits
+
+ We have to check that:
+ (a) the bit 't' is set
+ (b) all the 'z' bits are zero
+ */
+
+ prec = MPFR_PREC2LIMBS (prec) * GMP_NUMB_BITS - expo;
+ /* number of z+0 bits */
+
+ yn = prec / GMP_NUMB_BITS;
+ MPFR_ASSERTN(yn >= 0);
+ /* yn is the index of limb containing the 't' bit */
+
+ yp = MPFR_MANT(y);
+ /* if expo is a multiple of GMP_NUMB_BITS, t is bit 0 */
+ if (expo % GMP_NUMB_BITS == 0 ? (yp[yn] & 1) == 0
+ : yp[yn] << ((expo % GMP_NUMB_BITS) - 1) != MPFR_LIMB_HIGHBIT)
+ return 0;
+ while (--yn >= 0)
+ if (yp[yn] != 0)
+ return 0;
+ return 1;
+}
+
+/* Assumes that the exponent range has already been extended and if y is
+ an integer, then the result is not exact in unbounded exponent range. */
+int
+mpfr_pow_general (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y,
+ mpfr_rnd_t rnd_mode, int y_is_integer, mpfr_save_expo_t *expo)
+{
+ mpfr_t t, u, k, absx;
+ int neg_result = 0;
+ int k_non_zero = 0;
+ int check_exact_case = 0;
+ int inexact;
+ /* Declaration of the size variable */
+ mpfr_prec_t Nz = MPFR_PREC(z); /* target precision */
+ mpfr_prec_t Nt; /* working precision */
+ mpfr_exp_t err; /* error */
+ MPFR_ZIV_DECL (ziv_loop);
+
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x,
+ mpfr_get_prec (y), mpfr_log_prec, y, rnd_mode),
+ ("z[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (z), mpfr_log_prec, z, inexact));
+
+ /* We put the absolute value of x in absx, pointing to the significand
+ of x to avoid allocating memory for the significand of absx. */
+ MPFR_ALIAS(absx, x, /*sign=*/ 1, /*EXP=*/ MPFR_EXP(x));
+
+ /* We will compute the absolute value of the result. So, let's
+ invert the rounding mode if the result is negative. */
+ if (MPFR_IS_NEG (x) && is_odd (y))
+ {
+ neg_result = 1;
+ rnd_mode = MPFR_INVERT_RND (rnd_mode);
+ }
+
+ /* compute the precision of intermediary variable */
+ /* the optimal number of bits : see algorithms.tex */
+ Nt = Nz + 5 + MPFR_INT_CEIL_LOG2 (Nz);
+
+ /* initialise of intermediary variable */
+ mpfr_init2 (t, Nt);
+
+ MPFR_ZIV_INIT (ziv_loop, Nt);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags1);
+
+ /* compute exp(y*ln|x|), using MPFR_RNDU to get an upper bound, so
+ that we can detect underflows. */
+ mpfr_log (t, absx, MPFR_IS_NEG (y) ? MPFR_RNDD : MPFR_RNDU); /* ln|x| */
+ mpfr_mul (t, y, t, MPFR_RNDU); /* y*ln|x| */
+ if (k_non_zero)
+ {
+ MPFR_LOG_MSG (("subtract k * ln(2)\n", 0));
+ mpfr_const_log2 (u, MPFR_RNDD);
+ mpfr_mul (u, u, k, MPFR_RNDD);
+ /* Error on u = k * log(2): < k * 2^(-Nt) < 1. */
+ mpfr_sub (t, t, u, MPFR_RNDU);
+ MPFR_LOG_MSG (("t = y * ln|x| - k * ln(2)\n", 0));
+ MPFR_LOG_VAR (t);
+ }
+ /* estimate of the error -- see pow function in algorithms.tex.
+ The error on t is at most 1/2 + 3*2^(EXP(t)+1) ulps, which is
+ <= 2^(EXP(t)+3) for EXP(t) >= -1, and <= 2 ulps for EXP(t) <= -2.
+ Additional error if k_no_zero: treal = t * errk, with
+ 1 - |k| * 2^(-Nt) <= exp(-|k| * 2^(-Nt)) <= errk <= 1,
+ i.e., additional absolute error <= 2^(EXP(k)+EXP(t)-Nt).
+ Total error <= 2^err1 + 2^err2 <= 2^(max(err1,err2)+1). */
+ err = MPFR_NOTZERO (t) && MPFR_GET_EXP (t) >= -1 ?
+ MPFR_GET_EXP (t) + 3 : 1;
+ if (k_non_zero)
+ {
+ if (MPFR_GET_EXP (k) > err)
+ err = MPFR_GET_EXP (k);
+ err++;
+ }
+ MPFR_BLOCK (flags1, mpfr_exp (t, t, MPFR_RNDN)); /* exp(y*ln|x|)*/
+ /* We need to test */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (t) || MPFR_UNDERFLOW (flags1)))
+ {
+ mpfr_prec_t Ntmin;
+ MPFR_BLOCK_DECL (flags2);
+
+ MPFR_ASSERTN (!k_non_zero);
+ MPFR_ASSERTN (!MPFR_IS_NAN (t));
+
+ /* Real underflow? */
+ if (MPFR_IS_ZERO (t))
+ {
+ /* Underflow. We computed rndn(exp(t)), where t >= y*ln|x|.
+ Therefore rndn(|x|^y) = 0, and we have a real underflow on
+ |x|^y. */
+ inexact = mpfr_underflow (z, rnd_mode == MPFR_RNDN ? MPFR_RNDZ
+ : rnd_mode, MPFR_SIGN_POS);
+ if (expo != NULL)
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (*expo, MPFR_FLAGS_INEXACT
+ | MPFR_FLAGS_UNDERFLOW);
+ break;
+ }
+
+ /* Real overflow? */
+ if (MPFR_IS_INF (t))
+ {
+ /* Note: we can probably use a low precision for this test. */
+ mpfr_log (t, absx, MPFR_IS_NEG (y) ? MPFR_RNDU : MPFR_RNDD);
+ mpfr_mul (t, y, t, MPFR_RNDD); /* y * ln|x| */
+ MPFR_BLOCK (flags2, mpfr_exp (t, t, MPFR_RNDD));
+ /* t = lower bound on exp(y * ln|x|) */
+ if (MPFR_OVERFLOW (flags2))
+ {
+ /* We have computed a lower bound on |x|^y, and it
+ overflowed. Therefore we have a real overflow
+ on |x|^y. */
+ inexact = mpfr_overflow (z, rnd_mode, MPFR_SIGN_POS);
+ if (expo != NULL)
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (*expo, MPFR_FLAGS_INEXACT
+ | MPFR_FLAGS_OVERFLOW);
+ break;
+ }
+ }
+
+ k_non_zero = 1;
+ Ntmin = sizeof(mpfr_exp_t) * CHAR_BIT;
+ if (Ntmin > Nt)
+ {
+ Nt = Ntmin;
+ mpfr_set_prec (t, Nt);
+ }
+ mpfr_init2 (u, Nt);
+ mpfr_init2 (k, Ntmin);
+ mpfr_log2 (k, absx, MPFR_RNDN);
+ mpfr_mul (k, y, k, MPFR_RNDN);
+ mpfr_round (k, k);
+ MPFR_LOG_VAR (k);
+ /* |y| < 2^Ntmin, therefore |k| < 2^Nt. */
+ continue;
+ }
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - err, Nz, rnd_mode)))
+ {
+ inexact = mpfr_set (z, t, rnd_mode);
+ break;
+ }
+
+ /* check exact power, except when y is an integer (since the
+ exact cases for y integer have already been filtered out) */
+ if (check_exact_case == 0 && ! y_is_integer)
+ {
+ if (mpfr_pow_is_exact (z, absx, y, rnd_mode, &inexact))
+ break;
+ check_exact_case = 1;
+ }
+
+ /* reactualisation of the precision */
+ MPFR_ZIV_NEXT (ziv_loop, Nt);
+ mpfr_set_prec (t, Nt);
+ if (k_non_zero)
+ mpfr_set_prec (u, Nt);
+ }
+ MPFR_ZIV_FREE (ziv_loop);
+
+ if (k_non_zero)
+ {
+ int inex2;
+ long lk;
+
+ /* The rounded result in an unbounded exponent range is z * 2^k. As
+ * MPFR chooses underflow after rounding, the mpfr_mul_2si below will
+ * correctly detect underflows and overflows. However, in rounding to
+ * nearest, if z * 2^k = 2^(emin - 2), then the double rounding may
+ * affect the result. We need to cope with that before overwriting z.
+ * This can occur only if k < 0 (this test is necessary to avoid a
+ * potential integer overflow).
+ * If inexact >= 0, then the real result is <= 2^(emin - 2), so that
+ * o(2^(emin - 2)) = +0 is correct. If inexact < 0, then the real
+ * result is > 2^(emin - 2) and we need to round to 2^(emin - 1).
+ */
+ MPFR_ASSERTN (MPFR_EXP_MAX <= LONG_MAX);
+ lk = mpfr_get_si (k, MPFR_RNDN);
+ /* Due to early overflow detection, |k| should not be much larger than
+ * MPFR_EMAX_MAX, and as MPFR_EMAX_MAX <= MPFR_EXP_MAX/2 <= LONG_MAX/2,
+ * an overflow should not be possible in mpfr_get_si (and lk is exact).
+ * And one even has the following assertion. TODO: complete proof.
+ */
+ MPFR_ASSERTD (lk > LONG_MIN && lk < LONG_MAX);
+ /* Note: even in case of overflow (lk inexact), the code is correct.
+ * Indeed, for the 3 occurrences of lk:
+ * - The test lk < 0 is correct as sign(lk) = sign(k).
+ * - In the test MPFR_GET_EXP (z) == __gmpfr_emin - 1 - lk,
+ * if lk is inexact, then lk = LONG_MIN <= MPFR_EXP_MIN
+ * (the minimum value of the mpfr_exp_t type), and
+ * __gmpfr_emin - 1 - lk >= MPFR_EMIN_MIN - 1 - 2 * MPFR_EMIN_MIN
+ * >= - MPFR_EMIN_MIN - 1 = MPFR_EMAX_MAX - 1. However, from the
+ * choice of k, z has been chosen to be around 1, so that the
+ * result of the test is false, as if lk were exact.
+ * - In the mpfr_mul_2si (z, z, lk, rnd_mode), if lk is inexact,
+ * then |lk| >= LONG_MAX >= MPFR_EXP_MAX, and as z is around 1,
+ * mpfr_mul_2si underflows or overflows in the same way as if
+ * lk were exact.
+ * TODO: give a bound on |t|, then on |EXP(z)|.
+ */
+ if (rnd_mode == MPFR_RNDN && inexact < 0 && lk < 0 &&
+ MPFR_GET_EXP (z) == __gmpfr_emin - 1 - lk && mpfr_powerof2_raw (z))
+ {
+ /* Rounding to nearest, real result > z * 2^k = 2^(emin - 2),
+ * underflow case: as the minimum precision is > 1, we will
+ * obtain the correct result and exceptions by replacing z by
+ * nextabove(z).
+ */
+ MPFR_ASSERTN (MPFR_PREC_MIN > 1);
+ mpfr_nextabove (z);
+ }
+ mpfr_clear_flags ();
+ inex2 = mpfr_mul_2si (z, z, lk, rnd_mode);
+ if (inex2) /* underflow or overflow */
+ {
+ inexact = inex2;
+ if (expo != NULL)
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (*expo, __gmpfr_flags);
+ }
+ mpfr_clears (u, k, (mpfr_ptr) 0);
+ }
+ mpfr_clear (t);
+
+ /* update the sign of the result if x was negative */
+ if (neg_result)
+ {
+ MPFR_SET_NEG(z);
+ inexact = -inexact;
+ }
+
+ return inexact;
+}
+
+/* The computation of z = pow(x,y) is done by
+ z = exp(y * log(x)) = x^y
+ For the special cases, see Section F.9.4.4 of the C standard:
+ _ pow(±0, y) = ±inf for y an odd integer < 0.
+ _ pow(±0, y) = +inf for y < 0 and not an odd integer.
+ _ pow(±0, y) = ±0 for y an odd integer > 0.
+ _ pow(±0, y) = +0 for y > 0 and not an odd integer.
+ _ pow(-1, ±inf) = 1.
+ _ pow(+1, y) = 1 for any y, even a NaN.
+ _ pow(x, ±0) = 1 for any x, even a NaN.
+ _ pow(x, y) = NaN for finite x < 0 and finite non-integer y.
+ _ pow(x, -inf) = +inf for |x| < 1.
+ _ pow(x, -inf) = +0 for |x| > 1.
+ _ pow(x, +inf) = +0 for |x| < 1.
+ _ pow(x, +inf) = +inf for |x| > 1.
+ _ pow(-inf, y) = -0 for y an odd integer < 0.
+ _ pow(-inf, y) = +0 for y < 0 and not an odd integer.
+ _ pow(-inf, y) = -inf for y an odd integer > 0.
+ _ pow(-inf, y) = +inf for y > 0 and not an odd integer.
+ _ pow(+inf, y) = +0 for y < 0.
+ _ pow(+inf, y) = +inf for y > 0. */
+int
+mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ int cmp_x_1;
+ int y_is_integer;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x,
+ mpfr_get_prec (y), mpfr_log_prec, y, rnd_mode),
+ ("z[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (z), mpfr_log_prec, z, inexact));
+
+ if (MPFR_ARE_SINGULAR (x, y))
+ {
+ /* pow(x, 0) returns 1 for any x, even a NaN. */
+ if (MPFR_UNLIKELY (MPFR_IS_ZERO (y)))
+ return mpfr_set_ui (z, 1, rnd_mode);
+ else if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (z);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_NAN (y))
+ {
+ /* pow(+1, NaN) returns 1. */
+ if (mpfr_cmp_ui (x, 1) == 0)
+ return mpfr_set_ui (z, 1, rnd_mode);
+ MPFR_SET_NAN (z);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (y))
+ {
+ if (MPFR_IS_INF (x))
+ {
+ if (MPFR_IS_POS (y))
+ MPFR_SET_INF (z);
+ else
+ MPFR_SET_ZERO (z);
+ MPFR_SET_POS (z);
+ MPFR_RET (0);
+ }
+ else
+ {
+ int cmp;
+ cmp = mpfr_cmpabs (x, __gmpfr_one) * MPFR_INT_SIGN (y);
+ MPFR_SET_POS (z);
+ if (cmp > 0)
+ {
+ /* Return +inf. */
+ MPFR_SET_INF (z);
+ MPFR_RET (0);
+ }
+ else if (cmp < 0)
+ {
+ /* Return +0. */
+ MPFR_SET_ZERO (z);
+ MPFR_RET (0);
+ }
+ else
+ {
+ /* Return 1. */
+ return mpfr_set_ui (z, 1, rnd_mode);
+ }
+ }
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ int negative;
+ /* Determine the sign now, in case y and z are the same object */
+ negative = MPFR_IS_NEG (x) && is_odd (y);
+ if (MPFR_IS_POS (y))
+ MPFR_SET_INF (z);
+ else
+ MPFR_SET_ZERO (z);
+ if (negative)
+ MPFR_SET_NEG (z);
+ else
+ MPFR_SET_POS (z);
+ MPFR_RET (0);
+ }
+ else
+ {
+ int negative;
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ /* Determine the sign now, in case y and z are the same object */
+ negative = MPFR_IS_NEG(x) && is_odd (y);
+ if (MPFR_IS_NEG (y))
+ {
+ MPFR_ASSERTD (! MPFR_IS_INF (y));
+ MPFR_SET_INF (z);
+ mpfr_set_divby0 ();
+ }
+ else
+ MPFR_SET_ZERO (z);
+ if (negative)
+ MPFR_SET_NEG (z);
+ else
+ MPFR_SET_POS (z);
+ MPFR_RET (0);
+ }
+ }
+
+ /* x^y for x < 0 and y not an integer is not defined */
+ y_is_integer = mpfr_integer_p (y);
+ if (MPFR_IS_NEG (x) && ! y_is_integer)
+ {
+ MPFR_SET_NAN (z);
+ MPFR_RET_NAN;
+ }
+
+ /* now the result cannot be NaN:
+ (1) either x > 0
+ (2) or x < 0 and y is an integer */
+
+ cmp_x_1 = mpfr_cmpabs (x, __gmpfr_one);
+ if (cmp_x_1 == 0)
+ return mpfr_set_si (z, MPFR_IS_NEG (x) && is_odd (y) ? -1 : 1, rnd_mode);
+
+ /* now we have:
+ (1) either x > 0
+ (2) or x < 0 and y is an integer
+ and in addition |x| <> 1.
+ */
+
+ /* detect overflow: an overflow is possible if
+ (a) |x| > 1 and y > 0
+ (b) |x| < 1 and y < 0.
+ FIXME: this assumes 1 is always representable.
+
+ FIXME2: maybe we can test overflow and underflow simultaneously.
+ The idea is the following: first compute an approximation to
+ y * log2|x|, using rounding to nearest. If |x| is not too near from 1,
+ this approximation should be accurate enough, and in most cases enable
+ one to prove that there is no underflow nor overflow.
+ Otherwise, it should enable one to check only underflow or overflow,
+ instead of both cases as in the present case.
+ */
+ if (cmp_x_1 * MPFR_SIGN (y) > 0)
+ {
+ mpfr_t t;
+ int negative, overflow;
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (t, 53);
+ /* we want a lower bound on y*log2|x|:
+ (i) if x > 0, it suffices to round log2(x) toward zero, and
+ to round y*o(log2(x)) toward zero too;
+ (ii) if x < 0, we first compute t = o(-x), with rounding toward 1,
+ and then follow as in case (1). */
+ if (MPFR_SIGN (x) > 0)
+ mpfr_log2 (t, x, MPFR_RNDZ);
+ else
+ {
+ mpfr_neg (t, x, (cmp_x_1 > 0) ? MPFR_RNDZ : MPFR_RNDU);
+ mpfr_log2 (t, t, MPFR_RNDZ);
+ }
+ mpfr_mul (t, t, y, MPFR_RNDZ);
+ overflow = mpfr_cmp_si (t, __gmpfr_emax) > 0;
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_FREE (expo);
+ if (overflow)
+ {
+ MPFR_LOG_MSG (("early overflow detection\n", 0));
+ negative = MPFR_SIGN(x) < 0 && is_odd (y);
+ return mpfr_overflow (z, rnd_mode, negative ? -1 : 1);
+ }
+ }
+
+ /* Basic underflow checking. One has:
+ * - if y > 0, |x^y| < 2^(EXP(x) * y);
+ * - if y < 0, |x^y| <= 2^((EXP(x) - 1) * y);
+ * so that one can compute a value ebound such that |x^y| < 2^ebound.
+ * If we have ebound <= emin - 2 (emin - 1 in directed rounding modes),
+ * then there is an underflow and we can decide the return value.
+ */
+ if (MPFR_IS_NEG (y) ? (MPFR_GET_EXP (x) > 1) : (MPFR_GET_EXP (x) < 0))
+ {
+ mpfr_t tmp;
+ mpfr_eexp_t ebound;
+ int inex2;
+
+ /* We must restore the flags. */
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (tmp, sizeof (mpfr_exp_t) * CHAR_BIT);
+ inex2 = mpfr_set_exp_t (tmp, MPFR_GET_EXP (x), MPFR_RNDN);
+ MPFR_ASSERTN (inex2 == 0);
+ if (MPFR_IS_NEG (y))
+ {
+ inex2 = mpfr_sub_ui (tmp, tmp, 1, MPFR_RNDN);
+ MPFR_ASSERTN (inex2 == 0);
+ }
+ mpfr_mul (tmp, tmp, y, MPFR_RNDU);
+ if (MPFR_IS_NEG (y))
+ mpfr_nextabove (tmp);
+ /* tmp doesn't necessarily fit in ebound, but that doesn't matter
+ since we get the minimum value in such a case. */
+ ebound = mpfr_get_exp_t (tmp, MPFR_RNDU);
+ mpfr_clear (tmp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ if (MPFR_UNLIKELY (ebound <=
+ __gmpfr_emin - (rnd_mode == MPFR_RNDN ? 2 : 1)))
+ {
+ /* warning: mpfr_underflow rounds away from 0 for MPFR_RNDN */
+ MPFR_LOG_MSG (("early underflow detection\n", 0));
+ return mpfr_underflow (z,
+ rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
+ MPFR_SIGN (x) < 0 && is_odd (y) ? -1 : 1);
+ }
+ }
+
+ /* If y is an integer, we can use mpfr_pow_z (based on multiplications),
+ but if y is very large (I'm not sure about the best threshold -- VL),
+ we shouldn't use it, as it can be very slow and take a lot of memory
+ (and even crash or make other programs crash, as several hundred of
+ MBs may be necessary). Note that in such a case, either x = +/-2^b
+ (this case is handled below) or x^y cannot be represented exactly in
+ any precision supported by MPFR (the general case uses this property).
+ */
+ if (y_is_integer && (MPFR_GET_EXP (y) <= 256))
+ {
+ mpz_t zi;
+
+ MPFR_LOG_MSG (("special code for y not too large integer\n", 0));
+ mpz_init (zi);
+ mpfr_get_z (zi, y, MPFR_RNDN);
+ inexact = mpfr_pow_z (z, x, zi, rnd_mode);
+ mpz_clear (zi);
+ return inexact;
+ }
+
+ /* Special case (+/-2^b)^Y which could be exact. If x is negative, then
+ necessarily y is a large integer. */
+ {
+ mpfr_exp_t b = MPFR_GET_EXP (x) - 1;
+
+ MPFR_ASSERTN (b >= LONG_MIN && b <= LONG_MAX); /* FIXME... */
+ if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), b) == 0)
+ {
+ mpfr_t tmp;
+ int sgnx = MPFR_SIGN (x);
+
+ MPFR_LOG_MSG (("special case (+/-2^b)^Y\n", 0));
+ /* now x = +/-2^b, so x^y = (+/-1)^y*2^(b*y) is exact whenever b*y is
+ an integer */
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (tmp, MPFR_PREC (y) + sizeof (long) * CHAR_BIT);
+ inexact = mpfr_mul_si (tmp, y, b, MPFR_RNDN); /* exact */
+ MPFR_ASSERTN (inexact == 0);
+ /* Note: as the exponent range has been extended, an overflow is not
+ possible (due to basic overflow and underflow checking above, as
+ the result is ~ 2^tmp), and an underflow is not possible either
+ because b is an integer (thus either 0 or >= 1). */
+ mpfr_clear_flags ();
+ inexact = mpfr_exp2 (z, tmp, rnd_mode);
+ mpfr_clear (tmp);
+ if (sgnx < 0 && is_odd (y))
+ {
+ mpfr_neg (z, z, rnd_mode);
+ inexact = -inexact;
+ }
+ /* Without the following, the overflows3 test in tpow.c fails. */
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (z, inexact, rnd_mode);
+ }
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Case where |y * log(x)| is very small. Warning: x can be negative, in
+ that case y is a large integer. */
+ {
+ mpfr_t t;
+ mpfr_exp_t err;
+
+ /* We need an upper bound on the exponent of y * log(x). */
+ mpfr_init2 (t, 16);
+ if (MPFR_IS_POS(x))
+ mpfr_log (t, x, cmp_x_1 < 0 ? MPFR_RNDD : MPFR_RNDU); /* away from 0 */
+ else
+ {
+ /* if x < -1, round to +Inf, else round to zero */
+ mpfr_neg (t, x, (mpfr_cmp_si (x, -1) < 0) ? MPFR_RNDU : MPFR_RNDD);
+ mpfr_log (t, t, (mpfr_cmp_ui (t, 1) < 0) ? MPFR_RNDD : MPFR_RNDU);
+ }
+ MPFR_ASSERTN (MPFR_IS_PURE_FP (t));
+ err = MPFR_GET_EXP (y) + MPFR_GET_EXP (t);
+ mpfr_clear (t);
+ mpfr_clear_flags ();
+ MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (z, __gmpfr_one, - err, 0,
+ (MPFR_SIGN (y) > 0) ^ (cmp_x_1 < 0),
+ rnd_mode, expo, {});
+ }
+
+ /* General case */
+ inexact = mpfr_pow_general (z, x, y, rnd_mode, y_is_integer, &expo);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (z, inexact, rnd_mode);
+}
diff --git a/mpfr/src/pow_si.c b/mpfr/src/pow_si.c
new file mode 100644
index 0000000000..645035e206
--- /dev/null
+++ b/mpfr/src/pow_si.c
@@ -0,0 +1,250 @@
+/* mpfr_pow_si -- power function x^y with y a signed int
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* The computation of y = pow_si(x,n) is done by
+ * y = pow_ui(x,n) if n >= 0
+ * y = 1 / pow_ui(x,-n) if n < 0
+ */
+
+int
+mpfr_pow_si (mpfr_ptr y, mpfr_srcptr x, long int n, mpfr_rnd_t rnd)
+{
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg n=%ld rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x, n, rnd),
+ ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y));
+
+ if (n >= 0)
+ return mpfr_pow_ui (y, x, n, rnd);
+ else
+ {
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ int positive = MPFR_IS_POS (x) || ((unsigned long) n & 1) == 0;
+ if (MPFR_IS_INF (x))
+ MPFR_SET_ZERO (y);
+ else /* x is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_INF (y);
+ mpfr_set_divby0 ();
+ }
+ if (positive)
+ MPFR_SET_POS (y);
+ else
+ MPFR_SET_NEG (y);
+ MPFR_RET (0);
+ }
+ }
+
+ /* detect exact powers: x^(-n) is exact iff x is a power of 2 */
+ if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), MPFR_EXP(x) - 1) == 0)
+ {
+ mpfr_exp_t expx = MPFR_EXP (x) - 1, expy;
+ MPFR_ASSERTD (n < 0);
+ /* Warning: n * expx may overflow!
+ *
+ * Some systems (apparently alpha-freebsd) abort with
+ * LONG_MIN / 1, and LONG_MIN / -1 is undefined.
+ * http://www.freebsd.org/cgi/query-pr.cgi?pr=72024
+ *
+ * Proof of the overflow checking. The expressions below are
+ * assumed to be on the rational numbers, but the word "overflow"
+ * still has its own meaning in the C context. / still denotes
+ * the integer (truncated) division, and // denotes the exact
+ * division.
+ * - First, (__gmpfr_emin - 1) / n and (__gmpfr_emax - 1) / n
+ * cannot overflow due to the constraints on the exponents of
+ * MPFR numbers.
+ * - If n = -1, then n * expx = - expx, which is representable
+ * because of the constraints on the exponents of MPFR numbers.
+ * - If expx = 0, then n * expx = 0, which is representable.
+ * - If n < -1 and expx > 0:
+ * + If expx > (__gmpfr_emin - 1) / n, then
+ * expx >= (__gmpfr_emin - 1) / n + 1
+ * > (__gmpfr_emin - 1) // n,
+ * and
+ * n * expx < __gmpfr_emin - 1,
+ * i.e.
+ * n * expx <= __gmpfr_emin - 2.
+ * This corresponds to an underflow, with a null result in
+ * the rounding-to-nearest mode.
+ * + If expx <= (__gmpfr_emin - 1) / n, then n * expx cannot
+ * overflow since 0 < expx <= (__gmpfr_emin - 1) / n and
+ * 0 > n * expx >= n * ((__gmpfr_emin - 1) / n)
+ * >= __gmpfr_emin - 1.
+ * - If n < -1 and expx < 0:
+ * + If expx < (__gmpfr_emax - 1) / n, then
+ * expx <= (__gmpfr_emax - 1) / n - 1
+ * < (__gmpfr_emax - 1) // n,
+ * and
+ * n * expx > __gmpfr_emax - 1,
+ * i.e.
+ * n * expx >= __gmpfr_emax.
+ * This corresponds to an overflow (2^(n * expx) has an
+ * exponent > __gmpfr_emax).
+ * + If expx >= (__gmpfr_emax - 1) / n, then n * expx cannot
+ * overflow since 0 > expx >= (__gmpfr_emax - 1) / n and
+ * 0 < n * expx <= n * ((__gmpfr_emax - 1) / n)
+ * <= __gmpfr_emax - 1.
+ * Note: one could use expx bounds based on MPFR_EXP_MIN and
+ * MPFR_EXP_MAX instead of __gmpfr_emin and __gmpfr_emax. The
+ * current bounds do not lead to noticeably slower code and
+ * allow us to avoid a bug in Sun's compiler for Solaris/x86
+ * (when optimizations are enabled); known affected versions:
+ * cc: Sun C 5.8 2005/10/13
+ * cc: Sun C 5.8 Patch 121016-02 2006/03/31
+ * cc: Sun C 5.8 Patch 121016-04 2006/10/18
+ */
+ expy =
+ n != -1 && expx > 0 && expx > (__gmpfr_emin - 1) / n ?
+ MPFR_EMIN_MIN - 2 /* Underflow */ :
+ n != -1 && expx < 0 && expx < (__gmpfr_emax - 1) / n ?
+ MPFR_EMAX_MAX /* Overflow */ : n * expx;
+ return mpfr_set_si_2exp (y, n % 2 ? MPFR_INT_SIGN (x) : 1,
+ expy, rnd);
+ }
+
+ /* General case */
+ {
+ /* Declaration of the intermediary variable */
+ mpfr_t t;
+ /* Declaration of the size variable */
+ mpfr_prec_t Ny; /* target precision */
+ mpfr_prec_t Nt; /* working precision */
+ mpfr_rnd_t rnd1;
+ int size_n;
+ int inexact;
+ unsigned long abs_n;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+
+ abs_n = - (unsigned long) n;
+ count_leading_zeros (size_n, (mp_limb_t) abs_n);
+ size_n = GMP_NUMB_BITS - size_n;
+
+ /* initial working precision */
+ Ny = MPFR_PREC (y);
+ Nt = Ny + size_n + 3 + MPFR_INT_CEIL_LOG2 (Ny);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* initialise of intermediary variable */
+ mpfr_init2 (t, Nt);
+
+ /* We will compute rnd(rnd1(1/x) ^ |n|), where rnd1 is the rounding
+ toward sign(x), to avoid spurious overflow or underflow, as in
+ mpfr_pow_z. */
+ rnd1 = MPFR_EXP (x) < 1 ? MPFR_RNDZ :
+ (MPFR_SIGN (x) > 0 ? MPFR_RNDU : MPFR_RNDD);
+
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ /* compute (1/x)^|n| */
+ MPFR_BLOCK (flags, mpfr_ui_div (t, 1, x, rnd1));
+ MPFR_ASSERTD (! MPFR_UNDERFLOW (flags));
+ /* t = (1/x)*(1+theta) where |theta| <= 2^(-Nt) */
+ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags)))
+ goto overflow;
+ MPFR_BLOCK (flags, mpfr_pow_ui (t, t, abs_n, rnd));
+ /* t = (1/x)^|n|*(1+theta')^(|n|+1) where |theta'| <= 2^(-Nt).
+ If (|n|+1)*2^(-Nt) <= 1/2, which is satisfied as soon as
+ Nt >= bits(n)+2, then we can use Lemma \ref{lemma_graillat}
+ from algorithms.tex, which yields x^n*(1+theta) with
+ |theta| <= 2(|n|+1)*2^(-Nt), thus the error is bounded by
+ 2(|n|+1) ulps <= 2^(bits(n)+2) ulps. */
+ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags)))
+ {
+ overflow:
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_FREE (expo);
+ MPFR_LOG_MSG (("overflow\n", 0));
+ return mpfr_overflow (y, rnd, abs_n & 1 ?
+ MPFR_SIGN (x) : MPFR_SIGN_POS);
+ }
+ if (MPFR_UNLIKELY (MPFR_UNDERFLOW (flags)))
+ {
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (t);
+ MPFR_LOG_MSG (("underflow\n", 0));
+ if (rnd == MPFR_RNDN)
+ {
+ mpfr_t y2, nn;
+
+ /* We cannot decide now whether the result should be
+ rounded toward zero or away from zero. So, like
+ in mpfr_pow_pos_z, let's use the general case of
+ mpfr_pow in precision 2. */
+ MPFR_ASSERTD (mpfr_cmp_si_2exp (x, MPFR_SIGN (x),
+ MPFR_EXP (x) - 1) != 0);
+ mpfr_init2 (y2, 2);
+ mpfr_init2 (nn, sizeof (long) * CHAR_BIT);
+ inexact = mpfr_set_si (nn, n, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ inexact = mpfr_pow_general (y2, x, nn, rnd, 1,
+ (mpfr_save_expo_t *) NULL);
+ mpfr_clear (nn);
+ mpfr_set (y, y2, MPFR_RNDN);
+ mpfr_clear (y2);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_UNDERFLOW);
+ goto end;
+ }
+ else
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (y, rnd, abs_n & 1 ?
+ MPFR_SIGN (x) : MPFR_SIGN_POS);
+ }
+ }
+ /* error estimate -- see pow function in algorithms.ps */
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - size_n - 2, Ny, rnd)))
+ break;
+
+ /* actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (y, t, rnd);
+ mpfr_clear (t);
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd);
+ }
+ }
+}
diff --git a/mpfr/src/pow_ui.c b/mpfr/src/pow_ui.c
new file mode 100644
index 0000000000..377aee1cec
--- /dev/null
+++ b/mpfr/src/pow_ui.c
@@ -0,0 +1,164 @@
+/* mpfr_pow_ui-- compute the power of a floating-point
+ by a machine integer
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* sets y to x^n, and return 0 if exact, non-zero otherwise */
+int
+mpfr_pow_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int n, mpfr_rnd_t rnd)
+{
+ unsigned long m;
+ mpfr_t res;
+ mpfr_prec_t prec, err;
+ int inexact;
+ mpfr_rnd_t rnd1;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg n=%lu rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x, n, rnd),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ /* x^0 = 1 for any x, even a NaN */
+ if (MPFR_UNLIKELY (n == 0))
+ return mpfr_set_ui (y, 1, rnd);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ /* Inf^n = Inf, (-Inf)^n = Inf for n even, -Inf for n odd */
+ if (MPFR_IS_NEG (x) && (n & 1) == 1)
+ MPFR_SET_NEG (y);
+ else
+ MPFR_SET_POS (y);
+ MPFR_SET_INF (y);
+ MPFR_RET (0);
+ }
+ else /* x is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ /* 0^n = 0 for any n */
+ MPFR_SET_ZERO (y);
+ if (MPFR_IS_POS (x) || (n & 1) == 0)
+ MPFR_SET_POS (y);
+ else
+ MPFR_SET_NEG (y);
+ MPFR_RET (0);
+ }
+ }
+ else if (MPFR_UNLIKELY (n <= 2))
+ {
+ if (n < 2)
+ /* x^1 = x */
+ return mpfr_set (y, x, rnd);
+ else
+ /* x^2 = sqr(x) */
+ return mpfr_sqr (y, x, rnd);
+ }
+
+ /* Augment exponent range */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* setup initial precision */
+ prec = MPFR_PREC (y) + 3 + GMP_NUMB_BITS
+ + MPFR_INT_CEIL_LOG2 (MPFR_PREC (y));
+ mpfr_init2 (res, prec);
+
+ rnd1 = MPFR_IS_POS (x) ? MPFR_RNDU : MPFR_RNDD; /* away */
+
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ int i;
+
+ for (m = n, i = 0; m; i++, m >>= 1)
+ ;
+ /* now 2^(i-1) <= n < 2^i */
+ MPFR_ASSERTD (prec > (mpfr_prec_t) i);
+ err = prec - 1 - (mpfr_prec_t) i;
+ /* First step: compute square from x */
+ MPFR_BLOCK (flags,
+ inexact = mpfr_mul (res, x, x, MPFR_RNDU);
+ MPFR_ASSERTD (i >= 2);
+ if (n & (1UL << (i-2)))
+ inexact |= mpfr_mul (res, res, x, rnd1);
+ for (i -= 3; i >= 0 && !MPFR_BLOCK_EXCEP; i--)
+ {
+ inexact |= mpfr_mul (res, res, res, MPFR_RNDU);
+ if (n & (1UL << i))
+ inexact |= mpfr_mul (res, res, x, rnd1);
+ });
+ /* let r(n) be the number of roundings: we have r(2)=1, r(3)=2,
+ and r(2n)=2r(n)+1, r(2n+1)=2r(n)+2, thus r(n)=n-1.
+ Using Higham's method, to each rounding corresponds a factor
+ (1-theta) with 0 <= theta <= 2^(1-p), thus at the end the
+ absolute error is bounded by (n-1)*2^(1-p)*res <= 2*(n-1)*ulp(res)
+ since 2^(-p)*x <= ulp(x). Since n < 2^i, this gives a maximal
+ error of 2^(1+i)*ulp(res).
+ */
+ if (MPFR_LIKELY (inexact == 0
+ || MPFR_OVERFLOW (flags) || MPFR_UNDERFLOW (flags)
+ || MPFR_CAN_ROUND (res, err, MPFR_PREC (y), rnd)))
+ break;
+ /* Actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, prec);
+ mpfr_set_prec (res, prec);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags) || MPFR_UNDERFLOW (flags)))
+ {
+ mpz_t z;
+
+ /* Internal overflow or underflow. However the approximation error has
+ * not been taken into account. So, let's solve this problem by using
+ * mpfr_pow_z, which can handle it. This case could be improved in the
+ * future, without having to use mpfr_pow_z.
+ */
+ MPFR_LOG_MSG (("Internal overflow or underflow,"
+ " let's use mpfr_pow_z.\n", 0));
+ mpfr_clear (res);
+ MPFR_SAVE_EXPO_FREE (expo);
+ mpz_init (z);
+ mpz_set_ui (z, n);
+ inexact = mpfr_pow_z (y, x, z, rnd);
+ mpz_clear (z);
+ return inexact;
+ }
+
+ inexact = mpfr_set (y, res, rnd);
+ mpfr_clear (res);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd);
+}
diff --git a/mpfr/src/pow_z.c b/mpfr/src/pow_z.c
new file mode 100644
index 0000000000..df356ee0aa
--- /dev/null
+++ b/mpfr/src/pow_z.c
@@ -0,0 +1,373 @@
+/* mpfr_pow_z -- power function x^z with z a MPZ
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* y <- x^|z| with z != 0
+ if cr=1: ensures correct rounding of y
+ if cr=0: does not ensure correct rounding, but avoid spurious overflow
+ or underflow, and uses the precision of y as working precision (warning,
+ y and x might be the same variable). */
+static int
+mpfr_pow_pos_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t rnd, int cr)
+{
+ mpfr_t res;
+ mpfr_prec_t prec, err;
+ int inexact;
+ mpfr_rnd_t rnd1, rnd2;
+ mpz_t absz;
+ mp_size_t size_z;
+ MPFR_ZIV_DECL (loop);
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg z=%Zd rnd=%d cr=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x, z, rnd, cr),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ MPFR_ASSERTD (mpz_sgn (z) != 0);
+
+ if (MPFR_UNLIKELY (mpz_cmpabs_ui (z, 1) == 0))
+ return mpfr_set (y, x, rnd);
+
+ absz[0] = z[0];
+ SIZ (absz) = ABS(SIZ(absz)); /* Hack to get abs(z) */
+ MPFR_MPZ_SIZEINBASE2 (size_z, z);
+
+ /* round toward 1 (or -1) to avoid spurious overflow or underflow,
+ i.e. if an overflow or underflow occurs, it is a real exception
+ and is not just due to the rounding error. */
+ rnd1 = (MPFR_EXP(x) >= 1) ? MPFR_RNDZ
+ : (MPFR_IS_POS(x) ? MPFR_RNDU : MPFR_RNDD);
+ rnd2 = (MPFR_EXP(x) >= 1) ? MPFR_RNDD : MPFR_RNDU;
+
+ if (cr != 0)
+ prec = MPFR_PREC (y) + 3 + size_z + MPFR_INT_CEIL_LOG2 (MPFR_PREC (y));
+ else
+ prec = MPFR_PREC (y);
+ mpfr_init2 (res, prec);
+
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ unsigned int inexmul; /* will be non-zero if res may be inexact */
+ mp_size_t i = size_z;
+
+ /* now 2^(i-1) <= z < 2^i */
+ /* see below (case z < 0) for the error analysis, which is identical,
+ except if z=n, the maximal relative error is here 2(n-1)2^(-prec)
+ instead of 2(2n-1)2^(-prec) for z<0. */
+ MPFR_ASSERTD (prec > (mpfr_prec_t) i);
+ err = prec - 1 - (mpfr_prec_t) i;
+
+ MPFR_BLOCK (flags,
+ inexmul = mpfr_mul (res, x, x, rnd2);
+ MPFR_ASSERTD (i >= 2);
+ if (mpz_tstbit (absz, i - 2))
+ inexmul |= mpfr_mul (res, res, x, rnd1);
+ for (i -= 3; i >= 0 && !MPFR_BLOCK_EXCEP; i--)
+ {
+ inexmul |= mpfr_mul (res, res, res, rnd2);
+ if (mpz_tstbit (absz, i))
+ inexmul |= mpfr_mul (res, res, x, rnd1);
+ });
+ if (MPFR_LIKELY (inexmul == 0 || cr == 0
+ || MPFR_OVERFLOW (flags) || MPFR_UNDERFLOW (flags)
+ || MPFR_CAN_ROUND (res, err, MPFR_PREC (y), rnd)))
+ break;
+ /* Can't decide correct rounding, increase the precision */
+ MPFR_ZIV_NEXT (loop, prec);
+ mpfr_set_prec (res, prec);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ /* Check Overflow */
+ if (MPFR_OVERFLOW (flags))
+ {
+ MPFR_LOG_MSG (("overflow\n", 0));
+ inexact = mpfr_overflow (y, rnd, mpz_odd_p (absz) ?
+ MPFR_SIGN (x) : MPFR_SIGN_POS);
+ }
+ /* Check Underflow */
+ else if (MPFR_UNDERFLOW (flags))
+ {
+ MPFR_LOG_MSG (("underflow\n", 0));
+ if (rnd == MPFR_RNDN)
+ {
+ mpfr_t y2, zz;
+
+ /* We cannot decide now whether the result should be rounded
+ toward zero or +Inf. So, let's use the general case of
+ mpfr_pow, which can do that. But the problem is that the
+ result can be exact! However, it is sufficient to try to
+ round on 2 bits (the precision does not matter in case of
+ underflow, since MPFR does not have subnormals), in which
+ case, the result cannot be exact due to previous filtering
+ of trivial cases. */
+ MPFR_ASSERTD (mpfr_cmp_si_2exp (x, MPFR_SIGN (x),
+ MPFR_EXP (x) - 1) != 0);
+ mpfr_init2 (y2, 2);
+ mpfr_init2 (zz, ABS (SIZ (z)) * GMP_NUMB_BITS);
+ inexact = mpfr_set_z (zz, z, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ inexact = mpfr_pow_general (y2, x, zz, rnd, 1,
+ (mpfr_save_expo_t *) NULL);
+ mpfr_clear (zz);
+ mpfr_set (y, y2, MPFR_RNDN);
+ mpfr_clear (y2);
+ __gmpfr_flags = MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW;
+ }
+ else
+ {
+ inexact = mpfr_underflow (y, rnd, mpz_odd_p (absz) ?
+ MPFR_SIGN (x) : MPFR_SIGN_POS);
+ }
+ }
+ else
+ inexact = mpfr_set (y, res, rnd);
+
+ mpfr_clear (res);
+ return inexact;
+}
+
+/* The computation of y = pow(x,z) is done by
+ * y = set_ui(1) if z = 0
+ * y = pow_ui(x,z) if z > 0
+ * y = pow_ui(1/x,-z) if z < 0
+ *
+ * Note: in case z < 0, we could also compute 1/pow_ui(x,-z). However, in
+ * case MAX < 1/MIN, where MAX is the largest positive value, i.e.,
+ * MAX = nextbelow(+Inf), and MIN is the smallest positive value, i.e.,
+ * MIN = nextabove(+0), then x^(-z) might produce an overflow, whereas
+ * x^z is representable.
+ */
+
+int
+mpfr_pow_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mpfr_rnd_t rnd)
+{
+ int inexact;
+ mpz_t tmp;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg z=%Zd rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x, z, rnd),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ /* x^0 = 1 for any x, even a NaN */
+ if (MPFR_UNLIKELY (mpz_sgn (z) == 0))
+ return mpfr_set_ui (y, 1, rnd);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x))
+ {
+ /* Inf^n = Inf, (-Inf)^n = Inf for n even, -Inf for n odd */
+ /* Inf ^(-n) = 0, sign = + if x>0 or z even */
+ if (mpz_sgn (z) > 0)
+ MPFR_SET_INF (y);
+ else
+ MPFR_SET_ZERO (y);
+ if (MPFR_UNLIKELY (MPFR_IS_NEG (x) && mpz_odd_p (z)))
+ MPFR_SET_NEG (y);
+ else
+ MPFR_SET_POS (y);
+ MPFR_RET (0);
+ }
+ else /* x is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO(x));
+ if (mpz_sgn (z) > 0)
+ /* 0^n = +/-0 for any n */
+ MPFR_SET_ZERO (y);
+ else
+ {
+ /* 0^(-n) if +/- INF */
+ MPFR_SET_INF (y);
+ mpfr_set_divby0 ();
+ }
+ if (MPFR_LIKELY (MPFR_IS_POS (x) || mpz_even_p (z)))
+ MPFR_SET_POS (y);
+ else
+ MPFR_SET_NEG (y);
+ MPFR_RET(0);
+ }
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* detect exact powers: x^-n is exact iff x is a power of 2
+ Do it if n > 0 too as this is faster and this filtering is
+ needed in case of underflow. */
+ if (MPFR_UNLIKELY (mpfr_cmp_si_2exp (x, MPFR_SIGN (x),
+ MPFR_EXP (x) - 1) == 0))
+ {
+ mpfr_exp_t expx = MPFR_EXP (x); /* warning: x and y may be the same
+ variable */
+
+ MPFR_LOG_MSG (("x^n with x power of two\n", 0));
+ mpfr_set_si (y, mpz_odd_p (z) ? MPFR_INT_SIGN(x) : 1, rnd);
+ MPFR_ASSERTD (MPFR_IS_FP (y));
+ mpz_init (tmp);
+ mpz_mul_si (tmp, z, expx - 1);
+ MPFR_ASSERTD (MPFR_GET_EXP (y) == 1);
+ mpz_add_ui (tmp, tmp, 1);
+ inexact = 0;
+ if (MPFR_UNLIKELY (mpz_cmp_si (tmp, __gmpfr_emin) < 0))
+ {
+ MPFR_LOG_MSG (("underflow\n", 0));
+ /* |y| is a power of two, thus |y| <= 2^(emin-2), and in
+ rounding to nearest, the value must be rounded to 0. */
+ if (rnd == MPFR_RNDN)
+ rnd = MPFR_RNDZ;
+ inexact = mpfr_underflow (y, rnd, MPFR_SIGN (y));
+ }
+ else if (MPFR_UNLIKELY (mpz_cmp_si (tmp, __gmpfr_emax) > 0))
+ {
+ MPFR_LOG_MSG (("overflow\n", 0));
+ inexact = mpfr_overflow (y, rnd, MPFR_SIGN (y));
+ }
+ else
+ MPFR_SET_EXP (y, mpz_get_si (tmp));
+ mpz_clear (tmp);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ }
+ else if (mpz_sgn (z) > 0)
+ {
+ inexact = mpfr_pow_pos_z (y, x, z, rnd, 1);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ }
+ else
+ {
+ /* Declaration of the intermediary variable */
+ mpfr_t t;
+ mpfr_prec_t Nt; /* Precision of the intermediary variable */
+ mpfr_rnd_t rnd1;
+ mp_size_t size_z;
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_MPZ_SIZEINBASE2 (size_z, z);
+
+ /* initial working precision */
+ Nt = MPFR_PREC (y);
+ Nt = Nt + size_z + 3 + MPFR_INT_CEIL_LOG2 (Nt);
+ /* ensures Nt >= bits(z)+2 */
+
+ /* initialise of intermediary variable */
+ mpfr_init2 (t, Nt);
+
+ /* We will compute rnd(rnd1(1/x) ^ (-z)), where rnd1 is the rounding
+ toward sign(x), to avoid spurious overflow or underflow. */
+ rnd1 = MPFR_EXP (x) < 1 ? MPFR_RNDZ :
+ (MPFR_SIGN (x) > 0 ? MPFR_RNDU : MPFR_RNDD);
+
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ /* compute (1/x)^(-z), -z>0 */
+ /* As emin = -emax, an underflow cannot occur in the division.
+ And if an overflow occurs, then this means that x^z overflows
+ too (since we have rounded toward 1 or -1). */
+ MPFR_BLOCK (flags, mpfr_ui_div (t, 1, x, rnd1));
+ MPFR_ASSERTD (! MPFR_UNDERFLOW (flags));
+ /* t = (1/x)*(1+theta) where |theta| <= 2^(-Nt) */
+ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags)))
+ goto overflow;
+ MPFR_BLOCK (flags, mpfr_pow_pos_z (t, t, z, rnd, 0));
+ /* Now if z=-n, t = x^z*(1+theta)^(2n-1) where |theta| <= 2^(-Nt),
+ with theta maybe different from above. If (2n-1)*2^(-Nt) <= 1/2,
+ which is satisfied as soon as Nt >= bits(z)+2, then we can use
+ Lemma \ref{lemma_graillat} from algorithms.tex, which yields
+ t = x^z*(1+theta) with |theta| <= 2(2n-1)*2^(-Nt), thus the
+ error is bounded by 2(2n-1) ulps <= 2^(bits(z)+2) ulps. */
+ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags)))
+ {
+ overflow:
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_FREE (expo);
+ MPFR_LOG_MSG (("overflow\n", 0));
+ return mpfr_overflow (y, rnd,
+ mpz_odd_p (z) ? MPFR_SIGN (x) :
+ MPFR_SIGN_POS);
+ }
+ if (MPFR_UNLIKELY (MPFR_UNDERFLOW (flags)))
+ {
+ MPFR_ZIV_FREE (loop);
+ mpfr_clear (t);
+ MPFR_LOG_MSG (("underflow\n", 0));
+ if (rnd == MPFR_RNDN)
+ {
+ mpfr_t y2, zz;
+
+ /* We cannot decide now whether the result should be
+ rounded toward zero or away from zero. So, like
+ in mpfr_pow_pos_z, let's use the general case of
+ mpfr_pow in precision 2. */
+ MPFR_ASSERTD (mpfr_cmp_si_2exp (x, MPFR_SIGN (x),
+ MPFR_EXP (x) - 1) != 0);
+ mpfr_init2 (y2, 2);
+ mpfr_init2 (zz, ABS (SIZ (z)) * GMP_NUMB_BITS);
+ inexact = mpfr_set_z (zz, z, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ inexact = mpfr_pow_general (y2, x, zz, rnd, 1,
+ (mpfr_save_expo_t *) NULL);
+ mpfr_clear (zz);
+ mpfr_set (y, y2, MPFR_RNDN);
+ mpfr_clear (y2);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_UNDERFLOW);
+ goto end;
+ }
+ else
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_underflow (y, rnd, mpz_odd_p (z) ?
+ MPFR_SIGN (x) : MPFR_SIGN_POS);
+ }
+ }
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - size_z - 2, MPFR_PREC (y),
+ rnd)))
+ break;
+ /* actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ mpfr_set_prec (t, Nt);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (y, t, rnd);
+ mpfr_clear (t);
+ }
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd);
+}
diff --git a/mpfr/src/powerof2.c b/mpfr/src/powerof2.c
new file mode 100644
index 0000000000..76ce6b934a
--- /dev/null
+++ b/mpfr/src/powerof2.c
@@ -0,0 +1,49 @@
+/* mpfr_powerof2_raw -- test whether a floating-point number is a power of 2
+
+Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* This is an internal function and one assumes that x is a non-special
+ * number (more precisely, only its significand is considered and this
+ * function can be used even if the exponent field of x has not been
+ * initialized). It returns 1 (true) if |x| is a power of 2, else 0.
+ */
+
+int
+mpfr_powerof2_raw (mpfr_srcptr x)
+{
+ mp_limb_t *xp;
+ mp_size_t xn;
+
+ /* This is an internal function, and we may call it with some
+ wrong numbers (ie good mantissa but wrong flags or exp)
+ So we don't want to test if it is a pure FP.
+ MPFR_ASSERTN(MPFR_IS_PURE_FP(x)); */
+ xp = MPFR_MANT(x);
+ xn = (MPFR_PREC(x) - 1) / GMP_NUMB_BITS;
+ if (xp[xn] != MPFR_LIMB_HIGHBIT)
+ return 0;
+ while (xn > 0)
+ if (xp[--xn] != 0)
+ return 0;
+ return 1;
+}
diff --git a/mpfr/src/powerpc32/mparam.h b/mpfr/src/powerpc32/mparam.h
new file mode 100644
index 0000000000..44e966734f
--- /dev/null
+++ b/mpfr/src/powerpc32/mparam.h
@@ -0,0 +1,232 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2010-10-22, gcc 4.2.4, gmp 5.0.1 */
+/* RS/6000 7025 F50 kindly provided by David Kirkby, under AIX 5.3 */
+/* used MPFR svn revision 7238 */
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,40,40,40,40,40,40, \
+ 40,40,40,40,40,44,48,48,48,48,48,48,48,48,48,48, \
+ 48,48,48,48,52,52,52,52,52,52,52,52,52,52,52,64, \
+ 64,64,64,64,74,74,74,75,74,75,75,75,75,75,75,75, \
+ 75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, \
+ 75,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, \
+ 105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, \
+ 105,105,124,124,124,124,124,124,124,124,124,124,124,124,124,124, \
+ 124,124,124,124,124,124,140,140,140,140,140,140,140,140,156,156, \
+ 156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, \
+ 156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, \
+ 156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, \
+ 156,156,156,156,156,156,156,156,186,186,186,186,186,186,186,186, \
+ 186,186,186,186,186,186,186,186,186,186,186,186,186,186,210,210, \
+ 210,210,234,234,234,234,234,234,234,234,234,234,234,234,234,234, \
+ 234,234,234,234,234,234,234,233,234,234,234,234,234,234,234,234, \
+ 234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, \
+ 234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, \
+ 234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, \
+ 234,280,280,280,280,280,280,280,312,312,312,312,312,312,312,312, \
+ 312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312, \
+ 312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312, \
+ 312,312,312,312,312,312,312,312,312,344,344,344,344,344,344,312, \
+ 344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344, \
+ 344,344,344,344,344,344,376,376,376,376,376,376,376,376,376,376, \
+ 376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, \
+ 376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, \
+ 376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, \
+ 376,376,376,376,376,376,376,376,408,408,408,408,408,408,408,408, \
+ 408,408,408,408,408,408,408,408,408,407,408,408,408,408,408,408, \
+ 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, \
+ 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, \
+ 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, \
+ 408,408,408,408,408,408,408,408,408,408,408,408,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,584,584,584,584,584,584,584,584,584,584,584, \
+ 584,584,584,584,584,584,584,584,583,584,583,584,584,584,584,584, \
+ 592,584,592,584,592,592,592,592,592,584,592,592,592,584,584,584, \
+ 584,584,584,584,584,584,584,584,584,584,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,591,592,591,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,592,591,592,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,592,592,592,592,592,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,735,736,735,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,832,832,736, \
+ 832,831,832,832,832,832,832,832,832,832,832,832,832,832,832,832, \
+ 832,832,831,832,832,832,832,832,832,832,832,832,832,832,832,832, \
+ 832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,0,0,0,0,0,0,0,7,8,8,9,9, \
+ 10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17, \
+ 18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25, \
+ 26,26,27,28,28,28,30,32,32,32,32,32,32,32,34,34, \
+ 36,36,36,36,36,40,40,40,40,40,40,40,42,42,42,44, \
+ 44,44,46,46,46,46,46,46,46,46,47,47,56,56,56,56, \
+ 56,56,56,56,60,64,64,64,64,64,64,64,64,64,64,64, \
+ 64,64,64,68,68,72,72,72,72,72,72,72,72,76,76,76, \
+ 76,76,76,76,68,72,72,72,72,72,76,76,76,76,76,76, \
+ 76,76,76,76,76,76,77,77,87,90,93,93,93,93,93,93, \
+ 93,96,99,99,99,99,93,96,93,93,96,99,99,102,99,99, \
+ 105,102,105,105,105,105,108,108,108,111,111,111,111,111,117,117, \
+ 117,117,117,117,117,117,123,123,123,123,123,123,123,126,126,129, \
+ 129,123,129,129,129,129,129,129,129,129,129,129,129,129,129,129, \
+ 129,123,123,123,123,123,123,123,126,129,129,129,129,129,129,129, \
+ 129,129,129,129,129,129,164,164,164,164,164,164,164,164,164,164, \
+ 172,172,172,172,172,172,156,156,156,156,156,156,156,156,156,163, \
+ 164,164,164,164,164,171,171,171,172,172,172,172,172,172,172,180, \
+ 180,179,180,180,180,180,180,180,180,180,180,180,180,180,180,180, \
+ 180,180,180,180,198,198,198,198,180,198,198,198,210,210,210,210, \
+ 210,210,210,210,210,210,210,222,222,222,222,222,222,222,222,222, \
+ 222,222,222,222,234,234,234,234,234,234,234,234,234,234,234,234, \
+ 234,234,246,246,246,246,246,246,246,246,246,246,246,246,246,246, \
+ 258,246,246,258,258,258,258,258,258,258,258,258,258,270,270,270, \
+ 270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270, \
+ 270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270, \
+ 270,270,270,270,270,270,270,270,270,270,270,270,270,270,312,270, \
+ 312,312,312,270,270,270,270,270,270,270,270,328,328,312,328,328, \
+ 328,328,328,328,328,328,328,344,344,312,328,344,328,328,328,328, \
+ 328,328,328,328,328,328,328,328,328,328,328,327,328,328,328,328, \
+ 328,344,328,328,328,328,328,328,344,344,344,344,344,344,344,344, \
+ 344,344,344,360,360,360,360,360,360,360,360,360,360,360,360,360, \
+ 360,360,360,360,360,360,360,360,360,360,328,328,360,328,328,328, \
+ 328,328,360,328,328,328,328,328,328,328,328,344,344,344,344,344, \
+ 344,344,344,344,344,344,344,344,344,360,360,360,360,360,360,360, \
+ 360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, \
+ 360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, \
+ 360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, \
+ 360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, \
+ 408,408,408,408,408,408,408,408,408,408,440,440,440,440,440,439, \
+ 440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440, \
+ 440,440,440,440,440,440,440,440,440,440,440,440,440,472,472,440, \
+ 440,471,504,472,472,472,472,472,472,472,472,472,472,472,472,472, \
+ 472,472,472,472,472,472,472,472,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,504,504,504,504,536,536,536,536,536,536,536, \
+ 536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, \
+ 536,536,536,536,536,536,536,536,536,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 504,504,504,504,568,568,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,504,600,600,600,600,600,600,600,536,536,536,535, \
+ 535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536, \
+ 536,536,536,536,536,536,536,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,567,568,568,568,568,568,568, \
+ 568,568,568,568,568,567,568,568,568,568,568,568,600,600,600,599, \
+ 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600, \
+ 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600, \
+ 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600, \
+ 600,600,568,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,600,600,600,600,600, \
+ 600,600,600,600,600,600,600,600,599,600,600,600,600,600,600,600, \
+ 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600, \
+ 600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,8,7,10,9,12,13,12,9, \
+ 12,12,12,12,12,12,15,15,16,15,16,16,16,19,20,20, \
+ 20,19,19,19,20,20,21,21,22,23,23,24,25,25,25,25, \
+ 26,26,27,27,28,28,29,29,31,31,31,31,32,35,33,33, \
+ 34,36,35,35,36,36,37,37,38,38,40,39,40,40,41,41, \
+ 42,42,43,48,44,48,47,45,47,47,47,48,48,48,49,49, \
+ 50,51,51,51,52,52,53,53,54,55,56,55,56,63,57,64, \
+ 63,64,64,64,64,64,62,64,64,63,64,64,72,64,72,65, \
+ 66,72,72,71,72,71,71,70,80,71,71,71,80,72,73,80, \
+ 74,79,80,80,80,80,80,80,80,79,80,80,80,80,81,81, \
+ 82,88,85,95,84,96,96,88,96,96,95,95,96,96,96,96, \
+ 96,95,96,104,96,96,96,94,96,95,104,96,96,96,104,104, \
+ 98,104,100,104,104,104,104,104,103,104,104,103,104,104,105,105, \
+ 106,106,128,110,108,128,128,128,128,128,128,128,128,128,128,128, \
+ 128,128,128,128,127,128,128,128,127,124,128,128,126,126,128,125, \
+ 128,128,127,128,128,128,128,128,128,127,128,128,148,128,146,129, \
+ 130,148,144,147,150,148,150,148,148,150,147,150,144,148,150,148, \
+ 150,150,160,148,160,148,148,150,148,149,150,150,160,148,150,148, \
+ 148,150,147,150,150,150,149,149,160,150,151,151,152,156,156,156, \
+ 154,156,160,160,160,156,159,157,158,160,160,160,160,160,161,161, \
+ 162,168,176,192,186,192,186,186,186,192,192,184,192,186,184,192, \
+ 185,186,191,192,192,191,186,192,192,192,192,192,192,192,192,192, \
+ 192,190,192,192,190,192,192,192,186,192,192,192,192,192,192,192, \
+ 192,192,192,192,192,192,192,191,192,192,191,192,192,208,208,208, \
+ 194,208,208,208,208,207,208,208,208,208,207,208,206,208,201,208, \
+ 208,208,204,208,208,208,208,208,208,208,208,208,208,208,209,209, \
+ 210,210,211,211,212,248,256,216,216,248,254,256,256,248,255,256, \
+ 256,256,256,255,256,256,256,255,256,256,256,248,256,256,248,256, \
+ 256,255,256,256,254,256,256,256,248,255,256,256,256,256,254,256, \
+ 256,248,256,247,256,256,256,256,256,256,256,255,255,255,256,256, \
+ 256,254,256,256,253,255,256,256,256,255,256,256,256,253,256,288, \
+ 256,256,296,256,256,296,300,296,296,288,300,299,312,312,312,312, \
+ 288,312,294,311,312,312,299,300,312,296,312,300,300,296,295,299, \
+ 312,300,310,312,296,312,310,312,312,311,312,312,311,312,312,312, \
+ 312,312,311,312,312,312,310,311,312,310,312,312,310,311,311,312, \
+ 312,312,312,312,299,300,300,312,312,312,311,312,312,312,312,312, \
+ 312,312,312,312,310,300,311,310,312,312,312,312,308,300,312,312, \
+ 312,310,311,310,311,311,312,301,312,312,312,311,312,312,312,312, \
+ 311,312,312,312,312,312,312,312,312,312,311,312,312,312,313,313, \
+ 314,314,315,320,320,372,320,320,320,372,372,371,371,372,324,372, \
+ 371,371,372,370,369,371,371,372,372,372,372,372,370,370,372,370, \
+ 371,372,370,372,372,372,372,372,371,371,372,372,370,372,372,372, \
+ 370,372,372,372,370,372,372,370,372,370,370,371,372,371,384,372, \
+ 371,384,368,372,384,370,383,372,384,383,384,384,384,384,384,372, \
+ 372,384,372,372,369,370,372,370,372,368,372,372,372,372,371,370, \
+ 372,372,371,416,384,384,384,416,415,383,383,416,384,384,372,372, \
+ 416,370,371,372,372,415,373,417,415,416,384,384,384,416,416,417, \
+ 417,416,384,416,416,384,415,415,416,384,414,416,414,416,416,417, \
+ 386,408,416,416,416,408,416,416,414,416,417,417,417,416,414,416, \
+ 415,416,416,416,414,416,408,415,415,417,414,407,415,416,416,415, \
+ 416,416,417,416,416,415,416,416,416,416,415,416,416,416,419,415, \
+ 416,416,415,414,415,416,417,413,416,417,416,416,416,416,417,417, \
+ 418,418,419,419,420,420,421,421,422,444,432,430,496,443,496,496, \
+ 432,432,432,468,468,468,468,444,495,466,496,496,496,494,496,496, \
+ 496,468,512,494,496,496,496,496,468,496,493,496,492,496,496,512, \
+ 496,496,496,495,495,495,496,496,496,496,496,512,496,496,512,496, \
+ 496,493,496,496,496,509,496,512,512,496,512,496,512,512,496,495, \
+ 496,512,511,511,512,512,512,511,512,511,495,496,511,511,512,511, \
+ 512,512,493,495,495,495,512,493,495,560,496,496,496,496,496,560, \
+ 496,560,492,496,560,495,494,496,496,495,496,495,496,560,511,496, \
+ 512,509,512,495,494,496,511,496,560,496,512,512,511,496,575,512, \
+ 560,496,496,495,585,511,621,495,621,511,622,624,623,511,624,620, \
+ 624,623,511,620,620,624,591,623,624,622,623,620,624,613,624,624, \
+ 560,623,624,624,624,621,622,623,624,623,576,624,624,624,624,620 \
+
+#define MPFR_MUL_THRESHOLD 8 /* limbs */
+#define MPFR_SQR_THRESHOLD 1 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 530 /* bits */
+#define MPFR_EXP_THRESHOLD 7030 /* bits */
+#define MPFR_SINCOS_THRESHOLD 10754 /* bits */
+#define MPFR_AI_THRESHOLD1 -30447 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 3973
+#define MPFR_AI_THRESHOLD3 46501
+/* Tuneup completed successfully, took 12578 seconds */
diff --git a/mpfr/src/powerpc64/mparam.h b/mpfr/src/powerpc64/mparam.h
new file mode 100644
index 0000000000..b220950cde
--- /dev/null
+++ b/mpfr/src/powerpc64/mparam.h
@@ -0,0 +1,233 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2011-07-31, gcc 4.3.2 */
+/* generated on gcc40.fsffrance.org (IBM PowerPC 970 G5) with GMP 5.0.2 */
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,10,11,12,13,12,13,16,14,18,18,18,18,18,20,20, \
+ 22,22,23,24,24,26,24,24,26,26,26,28,26,32,36,36, \
+ 32,36,36,36,36,36,36,36,36,36,36,40,40,36,44,44, \
+ 44,44,44,44,48,48,48,44,44,44,48,48,48,48,48,48, \
+ 52,52,52,52,52,52,63,57,57,63,63,63,63,63,63,63, \
+ 63,69,69,69,69,69,69,75,75,69,75,72,75,74,75,75, \
+ 75,75,75,75,75,75,81,81,81,81,81,93,93,93,93,93, \
+ 93,93,105,104,105,105,105,105,105,105,105,104,105,105,105,105, \
+ 105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, \
+ 105,105,105,105,117,117,105,117,117,117,117,129,117,129,117,129, \
+ 129,129,129,129,129,129,129,129,129,129,129,129,129,129,141,129, \
+ 141,141,141,141,141,141,141,141,141,141,156,156,156,156,156,156, \
+ 156,156,156,156,156,156,156,156,156,156,156,156,156,172,172,172, \
+ 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, \
+ 188,172,172,188,172,188,188,188,188,188,188,188,188,188,188,187, \
+ 188,188,188,210,210,210,210,210,210,210,210,210,210,210,210,210, \
+ 210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, \
+ 210,234,210,210,234,234,234,210,234,234,234,234,234,234,234,234, \
+ 234,234,234,234,234,258,234,234,258,234,258,258,258,258,258,258, \
+ 258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, \
+ 258,258,258,258,258,257,258,258,282,282,282,282,282,281,282,282, \
+ 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282, \
+ 312,282,282,312,282,282,282,312,312,312,312,282,312,312,312,312, \
+ 312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312, \
+ 312,312,312,312,344,344,344,344,344,344,344,344,344,344,344,344, \
+ 344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,343, \
+ 344,343,344,344,344,344,344,344,344,344,344,344,376,376,376,376, \
+ 344,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, \
+ 376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, \
+ 376,376,376,376,376,376,376,376,376,376,376,376,376,376,408,376, \
+ 408,408,408,408,376,376,408,408,376,408,408,408,408,376,408,408, \
+ 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, \
+ 408,408,408,408,408,408,408,408,408,408,408,448,448,408,408,407, \
+ 408,408,408,448,408,448,448,448,448,408,448,448,448,448,448,448, \
+ 448,448,448,448,448,448,448,496,496,496,496,496,496,496,448,496, \
+ 496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, \
+ 496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, \
+ 496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, \
+ 496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, \
+ 496,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, \
+ 544,544,544,544,544,544,544,544,544,544,543,544,544,544,544,544, \
+ 544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, \
+ 544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, \
+ 544,544,592,592,592,592,567,544,568,568,568,592,592,592,592,592, \
+ 592,592,568,592,592,592,592,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,591,592,592,592,592,592,592, \
+ 592,592,592,592,592,592,592,592,592,592,640,592,640,592,640,640, \
+ 640,640,639,640,640,640,640,639,640,639,640,640,639,640,640,639, \
+ 640,639,640,640,640,640,640,640,640,640,640,640,640,640,640,639, \
+ 640,639,640,639,639,640,640,639,639,640,640,640,736,736,736,736, \
+ 735,736,736,736,736,735,736,736,736,735,736,736,736,735,734,735, \
+ 736,735,736,736,736,736,736,736,736,736,736,736,736,736,736,735, \
+ 736,736,736,735,736,736,736,736,736,736,736,735,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,735,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,735,736,736,736,735,736,832,832,831,831,832,832,832,831, \
+ 832,832,832,832,832,831,832,831,832,832,831,832,832,832,832,832, \
+ 832,832,832,831,832,832,832,832,832,832,832,832,832,831,832,832, \
+ 832,832,832,832,832,832,832,831,832,832,832,832,832,832,832,832, \
+ 832,832,831,832,832,832,832,831,832,830,832,832,832,832,832,832, \
+ 832,832,832,832,832,832,832,831,832,832,832,832,832,832,832,832, \
+ 832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,0,0,0,0,0,0,0,0,0,0,10,9, \
+ 10,10,12,12,12,12,14,13,14,14,15,15,16,16,17,17, \
+ 18,18,19,20,20,20,22,22,22,22,23,23,25,25,26,25, \
+ 26,26,27,27,28,28,29,29,30,30,31,31,32,32,33,34, \
+ 34,34,35,35,36,36,38,38,40,38,42,40,40,42,42,44, \
+ 42,42,44,44,44,44,46,46,46,46,50,48,52,48,50,52, \
+ 50,50,52,52,52,52,53,53,54,54,56,56,56,56,58,60, \
+ 58,58,60,60,60,60,63,63,63,63,63,63,66,66,66,72, \
+ 66,66,75,75,75,75,69,69,72,72,75,75,75,75,78,75, \
+ 75,75,75,75,78,78,78,81,78,81,81,81,81,81,81,87, \
+ 84,84,87,87,87,90,90,87,87,90,93,87,96,93,90,90, \
+ 99,96,102,99,96,93,99,93,99,96,96,96,96,99,99,99, \
+ 99,99,99,99,105,102,102,102,102,102,105,105,105,105,105,105, \
+ 111,111,111,111,111,111,117,111,111,111,111,111,123,117,117,123, \
+ 129,129,129,129,123,129,129,123,129,129,129,123,129,129,135,129, \
+ 129,129,135,135,129,135,134,135,135,135,135,135,135,141,135,129, \
+ 135,141,135,135,135,135,135,135,135,135,135,135,141,141,141,138, \
+ 138,141,141,141,141,141,141,141,147,144,147,146,147,147,146,147, \
+ 153,146,153,147,152,153,153,153,153,153,153,153,153,153,153,153, \
+ 164,164,164,164,164,172,164,171,172,172,172,172,172,172,172,164, \
+ 164,164,172,180,172,180,180,172,172,180,172,171,172,172,172,180, \
+ 180,180,180,180,180,180,180,188,188,187,187,188,188,188,180,196, \
+ 196,196,180,180,196,196,203,204,204,204,204,204,204,204,210,210, \
+ 188,188,188,210,188,188,222,222,204,196,222,222,222,222,204,222, \
+ 204,204,204,204,204,234,234,222,234,234,234,234,210,222,222,234, \
+ 246,246,222,222,222,222,246,222,222,234,258,258,258,258,234,258, \
+ 258,258,258,258,234,234,234,258,246,246,270,246,258,246,246,246, \
+ 246,246,258,258,258,258,258,258,258,258,258,258,258,258,258,258, \
+ 270,270,258,270,270,258,270,270,270,270,258,258,270,270,258,270, \
+ 258,258,258,258,258,258,258,270,257,258,258,270,258,270,258,270, \
+ 270,270,270,270,258,270,270,258,270,270,270,270,258,270,282,270, \
+ 270,270,270,270,270,270,270,270,270,270,270,282,270,282,282,282, \
+ 282,270,282,282,282,282,282,306,282,306,306,294,282,306,306,306, \
+ 312,306,294,306,306,306,306,306,270,306,306,306,306,306,306,282, \
+ 306,282,282,282,282,282,282,328,282,282,344,344,328,344,282,344, \
+ 344,282,328,344,344,344,344,306,306,306,344,306,306,306,344,344, \
+ 360,344,344,344,344,344,344,344,306,360,344,360,360,360,360,360, \
+ 360,360,360,360,360,360,360,360,328,344,344,344,344,344,344,344, \
+ 344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344, \
+ 344,344,344,344,360,344,344,360,360,360,360,360,360,360,360,360, \
+ 360,360,360,376,376,360,360,360,376,376,360,376,376,376,376,376, \
+ 376,376,376,376,376,376,376,376,392,392,392,408,408,376,408,408, \
+ 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, \
+ 408,408,408,408,408,408,408,408,408,424,408,408,424,408,408,424, \
+ 408,408,408,408,408,408,408,408,408,408,408,408,408,407,408,408, \
+ 408,407,407,408,408,408,424,408,408,408,408,408,408,408,408,408, \
+ 408,408,408,408,408,408,408,408,424,408,424,424,424,424,424,424, \
+ 424,424,424,424,424,424,408,408,408,408,408,407,440,440,408,408, \
+ 408,440,440,424,424,440,424,424,424,424,424,424,424,424,424,424, \
+ 424,424,424,440,440,408,440,440,440,472,440,440,472,440,440,440, \
+ 440,472,440,440,440,424,472,440,472,440,472,424,424,440,424,424, \
+ 424,440,440,424,440,440,440,472,472,440,440,472,440,472,472,472, \
+ 472,472,472,424,440,424,424,423,424,424,472,440,424,424,472,440, \
+ 440,440,440,440,440,472,440,472,440,440,472,440,440,440,472,440, \
+ 440,440,440,440,440,440,440,456,440,472,439,440,440,456,456,472, \
+ 472,472,472,471,471,472,472,472,472,472,472,472,471,472,472,472, \
+ 472,472,471,471,472,472,472,471,472,472,472,472,472,472,472,472, \
+ 472,472,472,471,472,472,472,472,472,471,472,472,472,472,472,472, \
+ 472,472,472,472,471,472,472,519,520,472,520,472,472,472,591,592, \
+ 520,520,520,520,520,592,592,592,592,568,592,592,520,520,520,592, \
+ 520,544,520,544,592,544,520,543,544,544,544,520,520,520,592,519, \
+ 568,568,592,592,592,592,568,592,568,568,592,568,568,592,568,592, \
+ 568,568,592,592,544,568,592,592,592,592,592,568,592,592,592,592, \
+ 592,592,591,592,592,592,592,592,592,592,592,568,592,592,592,568 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,6,9,8,9,10,8,12,13, \
+ 10,10,11,12,13,14,14,13,15,14,15,17,17,18,19,20, \
+ 21,21,19,21,20,20,23,21,22,22,23,24,25,24,26,28, \
+ 27,27,27,27,29,28,29,35,32,32,32,32,32,36,35,36, \
+ 36,36,36,36,36,36,39,40,40,40,43,40,47,40,43,42, \
+ 44,47,43,43,44,44,47,48,48,48,48,48,48,48,52,50, \
+ 52,52,52,52,52,52,56,55,64,64,55,64,64,64,64,64, \
+ 64,72,64,72,72,64,64,72,64,72,72,72,72,70,72,72, \
+ 72,72,72,72,72,72,72,72,72,72,72,72,80,72,80,80, \
+ 80,80,80,80,80,80,80,88,80,88,88,80,87,80,88,88, \
+ 88,88,88,96,88,88,88,96,88,96,96,96,88,96,96,96, \
+ 96,96,96,96,96,96,96,96,96,96,96,96,96,104,104,104, \
+ 104,104,100,104,104,104,104,103,104,102,104,104,104,104,112,120, \
+ 112,112,126,126,126,126,126,126,126,126,126,126,126,126,126,126, \
+ 144,126,126,128,144,144,128,126,144,144,144,144,144,144,144,128, \
+ 144,144,144,144,144,128,144,144,144,144,144,144,144,144,144,144, \
+ 144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, \
+ 144,144,144,144,144,144,144,144,144,144,144,144,144,144,150,160, \
+ 160,156,150,156,160,160,160,160,160,156,160,160,160,160,160,160, \
+ 160,160,160,160,160,160,160,160,160,160,160,160,160,160,174,176, \
+ 176,176,176,192,186,192,174,176,192,192,192,192,192,174,192,192, \
+ 192,192,192,192,192,192,208,186,192,192,186,192,192,192,192,192, \
+ 192,192,192,192,192,192,192,208,192,208,192,192,208,192,208,208, \
+ 208,208,208,208,192,208,208,207,208,192,204,208,208,208,208,208, \
+ 208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, \
+ 208,208,208,208,208,208,208,208,208,208,208,208,208,208,209,209, \
+ 256,220,216,216,256,252,256,240,240,252,252,256,224,252,256,256, \
+ 252,256,256,240,252,256,256,256,256,256,256,256,256,252,252,256, \
+ 256,256,252,256,252,256,256,256,288,288,254,256,256,288,288,288, \
+ 288,252,252,288,288,288,288,288,288,288,288,288,288,288,288,252, \
+ 288,288,288,288,288,288,288,288,288,288,256,288,288,288,252,257, \
+ 288,256,256,256,288,288,288,288,288,288,288,288,288,288,288,288, \
+ 288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288, \
+ 288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288, \
+ 288,288,288,288,288,288,288,288,288,288,288,288,288,288,288,288, \
+ 288,288,288,288,288,288,288,288,288,288,288,288,288,288,312,312, \
+ 312,300,312,312,312,312,312,312,312,320,312,312,312,312,312,312, \
+ 312,312,312,312,320,312,320,320,320,320,320,320,320,320,320,320, \
+ 312,344,320,312,344,320,312,312,320,344,320,336,342,344,344,344, \
+ 320,344,344,320,344,320,320,320,352,352,352,352,352,352,352,372, \
+ 372,368,368,384,344,372,368,384,369,368,384,372,370,368,376,370, \
+ 372,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, \
+ 384,384,372,372,384,372,384,344,368,368,384,384,384,408,384,372, \
+ 384,384,384,416,416,416,384,416,384,416,416,416,416,416,384,384, \
+ 384,384,384,415,384,384,416,416,416,384,384,384,384,416,384,384, \
+ 384,416,384,384,372,384,417,416,384,416,416,416,384,416,416,416, \
+ 416,416,416,384,384,416,416,384,384,384,416,416,417,416,416,416, \
+ 416,416,416,417,417,417,416,418,416,415,416,416,416,416,416,415, \
+ 416,417,417,416,417,416,415,416,416,416,416,417,416,413,416,416, \
+ 416,416,416,416,416,416,416,417,416,416,418,416,415,416,416,417, \
+ 416,416,416,416,416,416,416,416,416,416,417,416,416,416,416,415, \
+ 416,416,417,416,416,417,416,416,416,416,416,416,416,416,417,419, \
+ 419,420,420,444,420,420,432,512,468,504,456,456,456,456,514,512, \
+ 512,512,456,504,456,444,512,512,504,512,513,512,512,504,512,512, \
+ 512,512,513,513,512,512,513,504,512,512,513,512,512,504,512,512, \
+ 513,514,513,512,512,513,513,504,512,504,512,512,512,513,512,512, \
+ 510,512,512,512,512,512,512,512,513,512,515,512,513,512,504,512, \
+ 512,514,516,512,512,512,512,512,512,513,512,512,513,513,513,514, \
+ 515,512,512,504,564,512,512,512,512,512,512,576,561,512,576,564, \
+ 576,512,512,576,512,512,512,515,564,512,513,576,564,564,576,512, \
+ 512,510,512,564,576,576,512,576,576,514,576,576,512,564,576,576, \
+ 512,513,576,512,512,513,514,512,512,576,576,512,513,576,513,515, \
+ 552,552,576,512,512,512,564,513,564,576,576,576,564,576,564,576, \
+ 564,512,576,564,564,576,576,564,564,576,564,576,564,576,551,576 \
+
+#define MPFR_MUL_THRESHOLD 1 /* limbs */
+#define MPFR_SQR_THRESHOLD 5 /* limbs */
+#define MPFR_DIV_THRESHOLD 17 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 966 /* bits */
+#define MPFR_EXP_THRESHOLD 10924 /* bits */
+#define MPFR_SINCOS_THRESHOLD 36978 /* bits */
+#define MPFR_AI_THRESHOLD1 -12626 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 1377
+#define MPFR_AI_THRESHOLD3 24323
+/* Tuneup completed successfully, took 2598 seconds */
diff --git a/mpfr/src/print_raw.c b/mpfr/src/print_raw.c
new file mode 100644
index 0000000000..08b7baf5d7
--- /dev/null
+++ b/mpfr/src/print_raw.c
@@ -0,0 +1,129 @@
+/* mpfr_print_binary -- print the internal binary representation of a
+ floating-point number
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_fprint_binary (FILE *stream, mpfr_srcptr x)
+{
+ if (MPFR_IS_NAN (x))
+ {
+ fprintf (stream, "@NaN@");
+ return;
+ }
+
+ if (MPFR_SIGN (x) < 0)
+ fprintf (stream, "-");
+
+ if (MPFR_IS_INF (x))
+ fprintf (stream, "@Inf@");
+ else if (MPFR_IS_ZERO (x))
+ fprintf (stream, "0");
+ else
+ {
+ mp_limb_t *mx;
+ mpfr_prec_t px;
+ mp_size_t n;
+
+ mx = MPFR_MANT (x);
+ px = MPFR_PREC (x);
+
+ fprintf (stream, "0.");
+ for (n = (px - 1) / GMP_NUMB_BITS; ; n--)
+ {
+ mp_limb_t wd, t;
+
+ MPFR_ASSERTN (n >= 0);
+ wd = mx[n];
+ for (t = MPFR_LIMB_HIGHBIT; t != 0; t >>= 1)
+ {
+ putc ((wd & t) == 0 ? '0' : '1', stream);
+ if (--px == 0)
+ {
+ mpfr_exp_t ex;
+
+ ex = MPFR_GET_EXP (x);
+ MPFR_ASSERTN (ex >= LONG_MIN && ex <= LONG_MAX);
+ fprintf (stream, "E%ld", (long) ex);
+ return;
+ }
+ }
+ }
+ }
+}
+
+void
+mpfr_print_binary (mpfr_srcptr x)
+{
+ mpfr_fprint_binary (stdout, x);
+}
+
+void
+mpfr_print_mant_binary(const char *str, const mp_limb_t *p, mpfr_prec_t r)
+{
+ int i;
+ mpfr_prec_t count = 0;
+ char c;
+ mp_size_t n = MPFR_PREC2LIMBS (r);
+
+ printf("%s ", str);
+ for(n-- ; n>=0 ; n--)
+ {
+ for(i = GMP_NUMB_BITS-1 ; i >=0 ; i--)
+ {
+ c = (p[n] & (((mp_limb_t)1L)<<i)) ? '1' : '0';
+ putchar(c);
+ count++;
+ if (count == r)
+ putchar('[');
+ }
+ putchar('.');
+ }
+ putchar('\n');
+}
+
+void
+mpfr_dump_mant (const mp_limb_t *p, mpfr_prec_t r, mpfr_prec_t precx,
+ mpfr_prec_t error)
+{
+ int i;
+ mpfr_prec_t count = 0;
+ char c;
+ mp_size_t n = MPFR_PREC2LIMBS (r);
+
+ for(n-- ; n>=0 ; n--)
+ {
+ for(i = GMP_NUMB_BITS-1 ; i >=0 ; i--)
+ {
+ c = (p[n] & (((mp_limb_t)1L)<<i)) ? '1' : '0';
+ putchar(c);
+ count++;
+ if (count == precx)
+ putchar (',');
+ if (count == error)
+ putchar('[');
+ }
+ putchar('.');
+ }
+ putchar('\n');
+}
diff --git a/mpfr/src/print_rnd_mode.c b/mpfr/src/print_rnd_mode.c
new file mode 100644
index 0000000000..65269c7663
--- /dev/null
+++ b/mpfr/src/print_rnd_mode.c
@@ -0,0 +1,46 @@
+/* mpfr_print_rnd_mode -- convert a given rounding mode to a string
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+const char *
+mpfr_print_rnd_mode (mpfr_rnd_t rnd_mode)
+{
+ /* If we forget to update this function after a new rounding mode
+ is added, this will be detected by the following assertion. */
+ MPFR_ASSERTN (MPFR_RND_MAX == MPFR_RNDA + 1);
+ switch (rnd_mode)
+ {
+ case MPFR_RNDD:
+ return "MPFR_RNDD";
+ case MPFR_RNDU:
+ return "MPFR_RNDU";
+ case MPFR_RNDN:
+ return "MPFR_RNDN";
+ case MPFR_RNDZ:
+ return "MPFR_RNDZ";
+ case MPFR_RNDA:
+ return "MPFR_RNDA";
+ default:
+ return (const char*) 0;
+ }
+}
diff --git a/mpfr/src/printf.c b/mpfr/src/printf.c
new file mode 100644
index 0000000000..10a67c4d97
--- /dev/null
+++ b/mpfr/src/printf.c
@@ -0,0 +1,215 @@
+/* mpfr_printf -- printf function and friends.
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* The mpfr_printf-like functions are defined only if <stdarg.h> exists */
+#ifdef HAVE_STDARG
+
+#include <stdarg.h>
+
+#ifndef HAVE_VA_COPY
+# ifdef HAVE___VA_COPY
+# define va_copy(dst,src) __va_copy(dst, src)
+# else
+/* autoconf manual advocates this fallback.
+ This is also the solution chosen by gmp */
+# define va_copy(dst,src) \
+ do { memcpy(&(dst), &(src), sizeof(va_list)); } while (0)
+# endif /* HAVE___VA_COPY */
+#endif /* HAVE_VA_COPY */
+
+#include <errno.h>
+#include "mpfr-impl.h"
+
+#ifdef _MPFR_H_HAVE_FILE
+
+/* Each printf-like function calls mpfr_vasprintf which
+ - returns the number of characters in the returned string excluding the
+ terminating null
+ - returns -1 and sets the erange flag if the number of produced characters
+ exceeds INT_MAX (in that case, also sets errno to EOVERFLOW in POSIX
+ systems) */
+
+#define GET_STR_VA(sz, str, fmt, ap) \
+ do \
+ { \
+ sz = mpfr_vasprintf (&(str), fmt, ap); \
+ if (sz < 0) \
+ { \
+ if (str) \
+ mpfr_free_str (str); \
+ return -1; \
+ } \
+ } while (0)
+
+#define GET_STR(sz, str, fmt) \
+ do \
+ { \
+ va_list ap; \
+ va_start(ap, fmt); \
+ sz = mpfr_vasprintf (&(str), fmt, ap); \
+ va_end (ap); \
+ if (sz < 0) \
+ { \
+ if (str) \
+ mpfr_free_str (str); \
+ return -1; \
+ } \
+ } while (0)
+
+int
+mpfr_printf (const char *fmt, ...)
+{
+ char *str;
+ int ret;
+
+ GET_STR (ret, str, fmt);
+ ret = printf ("%s", str);
+
+ mpfr_free_str (str);
+ return ret;
+}
+
+int
+mpfr_vprintf (const char *fmt, va_list ap)
+{
+ char *str;
+ int ret;
+
+ GET_STR_VA (ret, str, fmt, ap);
+ ret = printf ("%s", str);
+
+ mpfr_free_str (str);
+ return ret;
+}
+
+
+int
+mpfr_fprintf (FILE *fp, const char *fmt, ...)
+{
+ char *str;
+ int ret;
+
+ GET_STR (ret, str, fmt);
+ ret = fprintf (fp, "%s", str);
+
+ mpfr_free_str (str);
+ return ret;
+}
+
+int
+mpfr_vfprintf (FILE *fp, const char *fmt, va_list ap)
+{
+ char *str;
+ int ret;
+
+ GET_STR_VA (ret, str, fmt, ap);
+ ret = fprintf (fp, "%s", str);
+
+ mpfr_free_str (str);
+ return ret;
+}
+#endif /* _MPFR_H_HAVE_FILE */
+
+int
+mpfr_sprintf (char *buf, const char *fmt, ...)
+{
+ char *str;
+ int ret;
+
+ GET_STR (ret, str, fmt);
+ ret = sprintf (buf, "%s", str);
+
+ mpfr_free_str (str);
+ return ret;
+}
+
+int
+mpfr_vsprintf (char *buf, const char *fmt, va_list ap)
+{
+ char *str;
+ int ret;
+
+ GET_STR_VA (ret, str, fmt, ap);
+ ret = sprintf (buf, "%s", str);
+
+ mpfr_free_str (str);
+ return ret;
+}
+
+int
+mpfr_snprintf (char *buf, size_t size, const char *fmt, ...)
+{
+ char *str;
+ int ret;
+ size_t min_size;
+
+ GET_STR (ret, str, fmt);
+
+ /* C99 allows SIZE to be zero */
+ if (size != 0)
+ {
+ MPFR_ASSERTN (buf != NULL);
+ min_size = (size_t)ret < size ? (size_t)ret : size - 1;
+ strncpy (buf, str, min_size);
+ buf[min_size] = '\0';
+ }
+
+ mpfr_free_str (str);
+ return ret;
+}
+
+int
+mpfr_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
+{
+ char *str;
+ int ret;
+ int min_size;
+
+ GET_STR_VA (ret, str, fmt, ap);
+
+ /* C99 allows SIZE to be zero */
+ if (size != 0)
+ {
+ MPFR_ASSERTN (buf != NULL);
+ min_size = (size_t)ret < size ? (size_t)ret : size - 1;
+ strncpy (buf, str, min_size);
+ buf[min_size] = '\0';
+ }
+
+ mpfr_free_str (str);
+ return ret;
+}
+
+int
+mpfr_asprintf (char **pp, const char *fmt, ...)
+{
+ int ret;
+
+ GET_STR (ret, *pp, fmt);
+
+ return ret;
+}
+#endif /* HAVE_STDARG */
diff --git a/mpfr/src/rec_sqrt.c b/mpfr/src/rec_sqrt.c
new file mode 100644
index 0000000000..f3ccf724d6
--- /dev/null
+++ b/mpfr/src/rec_sqrt.c
@@ -0,0 +1,556 @@
+/* mpfr_rec_sqrt -- inverse square root
+
+Copyright 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MPFR_NEED_LONGLONG_H /* for umul_ppmm */
+#include "mpfr-impl.h"
+
+#define LIMB_SIZE(x) ((((x)-1)>>MPFR_LOG2_GMP_NUMB_BITS) + 1)
+
+#define MPFR_COM_N(x,y,n) \
+ { \
+ mp_size_t i; \
+ for (i = 0; i < n; i++) \
+ *((x)+i) = ~*((y)+i); \
+ }
+
+/* Put in X a p-bit approximation of 1/sqrt(A),
+ where X = {x, n}/B^n, n = ceil(p/GMP_NUMB_BITS),
+ A = 2^(1+as)*{a, an}/B^an, as is 0 or 1, an = ceil(ap/GMP_NUMB_BITS),
+ where B = 2^GMP_NUMB_BITS.
+
+ We have 1 <= A < 4 and 1/2 <= X < 1.
+
+ The error in the approximate result with respect to the true
+ value 1/sqrt(A) is bounded by 1 ulp(X), i.e., 2^{-p} since 1/2 <= X < 1.
+
+ Note: x and a are left-aligned, i.e., the most significant bit of
+ a[an-1] is set, and so is the most significant bit of the output x[n-1].
+
+ If p is not a multiple of GMP_NUMB_BITS, the extra low bits of the input
+ A are taken into account to compute the approximation of 1/sqrt(A), but
+ whether or not they are zero, the error between X and 1/sqrt(A) is bounded
+ by 1 ulp(X) [in precision p].
+ The extra low bits of the output X (if p is not a multiple of GMP_NUMB_BITS)
+ are set to 0.
+
+ Assumptions:
+ (1) A should be normalized, i.e., the most significant bit of a[an-1]
+ should be 1. If as=0, we have 1 <= A < 2; if as=1, we have 2 <= A < 4.
+ (2) p >= 12
+ (3) {a, an} and {x, n} should not overlap
+ (4) GMP_NUMB_BITS >= 12 and is even
+
+ Note: this routine is much more efficient when ap is small compared to p,
+ including the case where ap <= GMP_NUMB_BITS, thus it can be used to
+ implement an efficient mpfr_rec_sqrt_ui function.
+
+ References:
+ [1] Modern Computer Algebra, Richard Brent and Paul Zimmermann,
+ http://www.loria.fr/~zimmerma/mca/pub226.html
+*/
+static void
+mpfr_mpn_rec_sqrt (mpfr_limb_ptr x, mpfr_prec_t p,
+ mpfr_limb_srcptr a, mpfr_prec_t ap, int as)
+
+{
+ /* the following T1 and T2 are bipartite tables giving initial
+ approximation for the inverse square root, with 13-bit input split in
+ 5+4+4, and 11-bit output. More precisely, if 2048 <= i < 8192,
+ with i = a*2^8 + b*2^4 + c, we use for approximation of
+ 2048/sqrt(i/2048) the value x = T1[16*(a-8)+b] + T2[16*(a-8)+c].
+ The largest error is obtained for i = 2054, where x = 2044,
+ and 2048/sqrt(i/2048) = 2045.006576...
+ */
+ static short int T1[384] = {
+2040, 2033, 2025, 2017, 2009, 2002, 1994, 1987, 1980, 1972, 1965, 1958, 1951,
+1944, 1938, 1931, /* a=8 */
+1925, 1918, 1912, 1905, 1899, 1892, 1886, 1880, 1874, 1867, 1861, 1855, 1849,
+1844, 1838, 1832, /* a=9 */
+1827, 1821, 1815, 1810, 1804, 1799, 1793, 1788, 1783, 1777, 1772, 1767, 1762,
+1757, 1752, 1747, /* a=10 */
+1742, 1737, 1733, 1728, 1723, 1718, 1713, 1709, 1704, 1699, 1695, 1690, 1686,
+1681, 1677, 1673, /* a=11 */
+1669, 1664, 1660, 1656, 1652, 1647, 1643, 1639, 1635, 1631, 1627, 1623, 1619,
+1615, 1611, 1607, /* a=12 */
+1603, 1600, 1596, 1592, 1588, 1585, 1581, 1577, 1574, 1570, 1566, 1563, 1559,
+1556, 1552, 1549, /* a=13 */
+1545, 1542, 1538, 1535, 1532, 1528, 1525, 1522, 1518, 1515, 1512, 1509, 1505,
+1502, 1499, 1496, /* a=14 */
+1493, 1490, 1487, 1484, 1481, 1478, 1475, 1472, 1469, 1466, 1463, 1460, 1457,
+1454, 1451, 1449, /* a=15 */
+1446, 1443, 1440, 1438, 1435, 1432, 1429, 1427, 1424, 1421, 1419, 1416, 1413,
+1411, 1408, 1405, /* a=16 */
+1403, 1400, 1398, 1395, 1393, 1390, 1388, 1385, 1383, 1380, 1378, 1375, 1373,
+1371, 1368, 1366, /* a=17 */
+1363, 1360, 1358, 1356, 1353, 1351, 1349, 1346, 1344, 1342, 1340, 1337, 1335,
+1333, 1331, 1329, /* a=18 */
+1327, 1325, 1323, 1321, 1319, 1316, 1314, 1312, 1310, 1308, 1306, 1304, 1302,
+1300, 1298, 1296, /* a=19 */
+1294, 1292, 1290, 1288, 1286, 1284, 1282, 1280, 1278, 1276, 1274, 1272, 1270,
+1268, 1266, 1265, /* a=20 */
+1263, 1261, 1259, 1257, 1255, 1253, 1251, 1250, 1248, 1246, 1244, 1242, 1241,
+1239, 1237, 1235, /* a=21 */
+1234, 1232, 1230, 1229, 1227, 1225, 1223, 1222, 1220, 1218, 1217, 1215, 1213,
+1212, 1210, 1208, /* a=22 */
+1206, 1204, 1203, 1201, 1199, 1198, 1196, 1195, 1193, 1191, 1190, 1188, 1187,
+1185, 1184, 1182, /* a=23 */
+1181, 1180, 1178, 1177, 1175, 1174, 1172, 1171, 1169, 1168, 1166, 1165, 1163,
+1162, 1160, 1159, /* a=24 */
+1157, 1156, 1154, 1153, 1151, 1150, 1149, 1147, 1146, 1144, 1143, 1142, 1140,
+1139, 1137, 1136, /* a=25 */
+1135, 1133, 1132, 1131, 1129, 1128, 1127, 1125, 1124, 1123, 1121, 1120, 1119,
+1117, 1116, 1115, /* a=26 */
+1114, 1113, 1111, 1110, 1109, 1108, 1106, 1105, 1104, 1103, 1101, 1100, 1099,
+1098, 1096, 1095, /* a=27 */
+1093, 1092, 1091, 1090, 1089, 1087, 1086, 1085, 1084, 1083, 1081, 1080, 1079,
+1078, 1077, 1076, /* a=28 */
+1075, 1073, 1072, 1071, 1070, 1069, 1068, 1067, 1065, 1064, 1063, 1062, 1061,
+1060, 1059, 1058, /* a=29 */
+1057, 1056, 1055, 1054, 1052, 1051, 1050, 1049, 1048, 1047, 1046, 1045, 1044,
+1043, 1042, 1041, /* a=30 */
+1040, 1039, 1038, 1037, 1036, 1035, 1034, 1033, 1032, 1031, 1030, 1029, 1028,
+1027, 1026, 1025 /* a=31 */
+};
+ static unsigned char T2[384] = {
+ 7, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 2, 2, 1, 1, 0, /* a=8 */
+ 6, 5, 5, 5, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 0, 0, /* a=9 */
+ 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, /* a=10 */
+ 4, 4, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, /* a=11 */
+ 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, /* a=12 */
+ 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* a=13 */
+ 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* a=14 */
+ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* a=15 */
+ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* a=16 */
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* a=17 */
+ 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, /* a=18 */
+ 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* a=19 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* a=20 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* a=21 */
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a=22 */
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* a=23 */
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a=24 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* a=25 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* a=26 */
+ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a=27 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* a=28 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* a=29 */
+ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a=30 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* a=31 */
+};
+ mp_size_t n = LIMB_SIZE(p); /* number of limbs of X */
+ mp_size_t an = LIMB_SIZE(ap); /* number of limbs of A */
+
+ /* A should be normalized */
+ MPFR_ASSERTD((a[an - 1] & MPFR_LIMB_HIGHBIT) != 0);
+ /* We should have enough bits in one limb and GMP_NUMB_BITS should be even.
+ Since that does not depend on MPFR, we always check this. */
+ MPFR_ASSERTN((GMP_NUMB_BITS >= 12) && ((GMP_NUMB_BITS & 1) == 0));
+ /* {a, an} and {x, n} should not overlap */
+ MPFR_ASSERTD((a + an <= x) || (x + n <= a));
+ MPFR_ASSERTD(p >= 11);
+
+ if (MPFR_UNLIKELY(an > n)) /* we can cut the input to n limbs */
+ {
+ a += an - n;
+ an = n;
+ }
+
+ if (p == 11) /* should happen only from recursive calls */
+ {
+ unsigned long i, ab, ac;
+ mp_limb_t t;
+
+ /* take the 12+as most significant bits of A */
+ i = a[an - 1] >> (GMP_NUMB_BITS - (12 + as));
+ /* if one wants faithful rounding for p=11, replace #if 0 by #if 1 */
+ ab = i >> 4;
+ ac = (ab & 0x3F0) | (i & 0x0F);
+ t = (mp_limb_t) T1[ab - 0x80] + (mp_limb_t) T2[ac - 0x80];
+ x[0] = t << (GMP_NUMB_BITS - p);
+ }
+ else /* p >= 12 */
+ {
+ mpfr_prec_t h, pl;
+ mpfr_limb_ptr r, s, t, u;
+ mp_size_t xn, rn, th, ln, tn, sn, ahn, un;
+ mp_limb_t neg, cy, cu;
+ MPFR_TMP_DECL(marker);
+
+ /* compared to Algorithm 3.9 of [1], we have {a, an} = A/2 if as=0,
+ and A/4 if as=1. */
+
+ /* h = max(11, ceil((p+3)/2)) is the bitsize of the recursive call */
+ h = (p < 18) ? 11 : (p >> 1) + 2;
+
+ xn = LIMB_SIZE(h); /* limb size of the recursive Xh */
+ rn = LIMB_SIZE(2 * h); /* a priori limb size of Xh^2 */
+ ln = n - xn; /* remaining limbs to be computed */
+
+ /* Since |Xh - A^{-1/2}| <= 2^{-h}, then by multiplying by Xh + A^{-1/2}
+ we get |Xh^2 - 1/A| <= 2^{-h+1}, thus |A*Xh^2 - 1| <= 2^{-h+3},
+ thus the h-3 most significant bits of t should be zero,
+ which is in fact h+1+as-3 because of the normalization of A.
+ This corresponds to th=floor((h+1+as-3)/GMP_NUMB_BITS) limbs.
+
+ More precisely we have |Xh^2 - 1/A| <= 2^{-h} * (Xh + A^{-1/2})
+ <= 2^{-h} * (2 A^{-1/2} + 2^{-h}) <= 2.001 * 2^{-h} * A^{-1/2}
+ since A < 4 and h >= 11, thus
+ |A*Xh^2 - 1| <= 2.001 * 2^{-h} * A^{1/2} <= 1.001 * 2^{2-h}.
+ This is sufficient to prove that the upper limb of {t,tn} below is
+ less that 0.501 * 2^GMP_NUMB_BITS, thus cu = 0 below.
+ */
+ th = (h + 1 + as - 3) >> MPFR_LOG2_GMP_NUMB_BITS;
+ tn = LIMB_SIZE(2 * h + 1 + as);
+
+ /* we need h+1+as bits of a */
+ ahn = LIMB_SIZE(h + 1 + as); /* number of high limbs of A
+ needed for the recursive call*/
+ if (MPFR_UNLIKELY(ahn > an))
+ ahn = an;
+ mpfr_mpn_rec_sqrt (x + ln, h, a + an - ahn, ahn * GMP_NUMB_BITS, as);
+ /* the most h significant bits of X are set, X has ceil(h/GMP_NUMB_BITS)
+ limbs, the low (-h) % GMP_NUMB_BITS bits are zero */
+
+ /* compared to Algorithm 3.9 of [1], we have {x+ln,xn} = X_h */
+
+ MPFR_TMP_MARK (marker);
+ /* first step: square X in r, result is exact */
+ un = xn + (tn - th);
+ /* We use the same temporary buffer to store r and u: r needs 2*xn
+ limbs where u needs xn+(tn-th) limbs. Since tn can store at least
+ 2h bits, and th at most h bits, then tn-th can store at least h bits,
+ thus tn - th >= xn, and reserving the space for u is enough. */
+ MPFR_ASSERTD(2 * xn <= un);
+ u = r = MPFR_TMP_LIMBS_ALLOC (un);
+ if (2 * h <= GMP_NUMB_BITS) /* xn=rn=1, and since p <= 2h-3, n=1,
+ thus ln = 0 */
+ {
+ MPFR_ASSERTD(ln == 0);
+ cy = x[0] >> (GMP_NUMB_BITS >> 1);
+ r ++;
+ r[0] = cy * cy;
+ }
+ else if (xn == 1) /* xn=1, rn=2 */
+ umul_ppmm(r[1], r[0], x[ln], x[ln]);
+ else
+ {
+ mpn_mul_n (r, x + ln, x + ln, xn);
+ /* we have {r, 2*xn} = X_h^2 */
+ if (rn < 2 * xn)
+ r ++;
+ }
+ /* now the 2h most significant bits of {r, rn} contains X^2, r has rn
+ limbs, and the low (-2h) % GMP_NUMB_BITS bits are zero */
+
+ /* Second step: s <- A * (r^2), and truncate the low ap bits,
+ i.e., at weight 2^{-2h} (s is aligned to the low significant bits)
+ */
+ sn = an + rn;
+ s = MPFR_TMP_LIMBS_ALLOC (sn);
+ if (rn == 1) /* rn=1 implies n=1, since rn*GMP_NUMB_BITS >= 2h,
+ and 2h >= p+3 */
+ {
+ /* necessarily p <= GMP_NUMB_BITS-3: we can ignore the two low
+ bits from A */
+ /* since n=1, and we ensured an <= n, we also have an=1 */
+ MPFR_ASSERTD(an == 1);
+ umul_ppmm (s[1], s[0], r[0], a[0]);
+ }
+ else
+ {
+ /* we have p <= n * GMP_NUMB_BITS
+ 2h <= rn * GMP_NUMB_BITS with p+3 <= 2h <= p+4
+ thus n <= rn <= n + 1 */
+ MPFR_ASSERTD(rn <= n + 1);
+ /* since we ensured an <= n, we have an <= rn */
+ MPFR_ASSERTD(an <= rn);
+ mpn_mul (s, r, rn, a, an);
+ /* s should be near B^sn/2^(1+as), thus s[sn-1] is either
+ 100000... or 011111... if as=0, or
+ 010000... or 001111... if as=1.
+ We ignore the bits of s after the first 2h+1+as ones.
+ We have {s, rn+an} = A*X_h^2/2 if as=0, A*X_h^2/4 if as=1. */
+ }
+
+ /* We ignore the bits of s after the first 2h+1+as ones: s has rn + an
+ limbs, where rn = LIMBS(2h), an=LIMBS(a), and tn = LIMBS(2h+1+as). */
+ t = s + sn - tn; /* pointer to low limb of the high part of t */
+ /* the upper h-3 bits of 1-t should be zero,
+ where 1 corresponds to the most significant bit of t[tn-1] if as=0,
+ and to the 2nd most significant bit of t[tn-1] if as=1 */
+
+ /* compute t <- 1 - t, which is B^tn - {t, tn+1},
+ with rounding toward -Inf, i.e., rounding the input t toward +Inf.
+ We could only modify the low tn - th limbs from t, but it gives only
+ a small speedup, and would make the code more complex.
+ */
+ neg = t[tn - 1] & (MPFR_LIMB_HIGHBIT >> as);
+ if (neg == 0) /* Ax^2 < 1: we have t = th + eps, where 0 <= eps < ulp(th)
+ is the part truncated above, thus 1 - t rounded to -Inf
+ is 1 - th - ulp(th) */
+ {
+ /* since the 1+as most significant bits of t are zero, set them
+ to 1 before the one-complement */
+ t[tn - 1] |= MPFR_LIMB_HIGHBIT | (MPFR_LIMB_HIGHBIT >> as);
+ MPFR_COM_N (t, t, tn);
+ /* we should add 1 here to get 1-th complement, and subtract 1 for
+ -ulp(th), thus we do nothing */
+ }
+ else /* negative case: we want 1 - t rounded toward -Inf, i.e.,
+ th + eps rounded toward +Inf, which is th + ulp(th):
+ we discard the bit corresponding to 1,
+ and we add 1 to the least significant bit of t */
+ {
+ t[tn - 1] ^= neg;
+ mpn_add_1 (t, t, tn, 1);
+ }
+ tn -= th; /* we know at least th = floor((h+1+as-3)/GMP_NUMB_LIMBS) of
+ the high limbs of {t, tn} are zero */
+
+ /* tn = rn - th, where rn * GMP_NUMB_BITS >= 2*h and
+ th * GMP_NUMB_BITS <= h+1+as-3, thus tn > 0 */
+ MPFR_ASSERTD(tn > 0);
+
+ /* u <- x * t, where {t, tn} contains at least h+3 bits,
+ and {x, xn} contains h bits, thus tn >= xn */
+ MPFR_ASSERTD(tn >= xn);
+ if (tn == 1) /* necessarily xn=1 */
+ umul_ppmm (u[1], u[0], t[0], x[ln]);
+ else
+ mpn_mul (u, t, tn, x + ln, xn);
+
+ /* we have {u, tn+xn} = T_l X_h/2 if as=0, T_l X_h/4 if as=1 */
+
+ /* we have already discarded the upper th high limbs of t, thus we only
+ have to consider the upper n - th limbs of u */
+ un = n - th; /* un cannot be zero, since p <= n*GMP_NUMB_BITS,
+ h = ceil((p+3)/2) <= (p+4)/2,
+ th*GMP_NUMB_BITS <= h-1 <= p/2+1,
+ thus (n-th)*GMP_NUMB_BITS >= p/2-1.
+ */
+ MPFR_ASSERTD(un > 0);
+ u += (tn + xn) - un; /* xn + tn - un = xn + (original_tn - th) - (n - th)
+ = xn + original_tn - n
+ = LIMBS(h) + LIMBS(2h+1+as) - LIMBS(p) > 0
+ since 2h >= p+3 */
+ MPFR_ASSERTD(tn + xn > un); /* will allow to access u[-1] below */
+
+ /* In case as=0, u contains |x*(1-Ax^2)/2|, which is exactly what we
+ need to add or subtract.
+ In case as=1, u contains |x*(1-Ax^2)/4|, thus we need to multiply
+ u by 2. */
+
+ if (as == 1)
+ /* shift on un+1 limbs to get most significant bit of u[-1] into
+ least significant bit of u[0] */
+ mpn_lshift (u - 1, u - 1, un + 1, 1);
+
+ /* now {u,un} represents U / 2 from Algorithm 3.9 */
+
+ pl = n * GMP_NUMB_BITS - p; /* low bits from x */
+ /* We want that the low pl bits are zero after rounding to nearest,
+ thus we round u to nearest at bit pl-1 of u[0] */
+ if (pl > 0)
+ {
+ cu = mpn_add_1 (u, u, un, u[0] & (MPFR_LIMB_ONE << (pl - 1)));
+ /* mask bits 0..pl-1 of u[0] */
+ u[0] &= ~MPFR_LIMB_MASK(pl);
+ }
+ else /* round bit is in u[-1] */
+ cu = mpn_add_1 (u, u, un, u[-1] >> (GMP_NUMB_BITS - 1));
+ MPFR_ASSERTN(cu == 0);
+
+ /* We already have filled {x + ln, xn = n - ln}, and we want to add or
+ subtract {u, un} at position x.
+ un = n - th, where th contains <= h+1+as-3<=h-1 bits
+ ln = n - xn, where xn contains >= h bits
+ thus un > ln.
+ Warning: ln might be zero.
+ */
+ MPFR_ASSERTD(un > ln);
+ /* we can have un = ln + 2, for example with GMP_NUMB_BITS=32 and
+ p=62, as=0, then h=33, n=2, th=0, xn=2, thus un=2 and ln=0. */
+ MPFR_ASSERTD(un == ln + 1 || un == ln + 2);
+ /* the high un-ln limbs of u will overlap the low part of {x+ln,xn},
+ we need to add or subtract the overlapping part {u + ln, un - ln} */
+ /* Warning! th may be 0, in which case the mpn_add_1 and mpn_sub_1
+ below (with size = th) mustn't be used. */
+ if (neg == 0)
+ {
+ if (ln > 0)
+ MPN_COPY (x, u, ln);
+ cy = mpn_add (x + ln, x + ln, xn, u + ln, un - ln);
+ /* cy is the carry at x + (ln + xn) = x + n */
+ }
+ else /* negative case */
+ {
+ /* subtract {u+ln, un-ln} from {x+ln,un} */
+ cy = mpn_sub (x + ln, x + ln, xn, u + ln, un - ln);
+ /* cy is the borrow at x + (ln + xn) = x + n */
+
+ /* cy cannot be non-zero, since the most significant bit of Xh is 1,
+ and the correction is bounded by 2^{-h+3} */
+ MPFR_ASSERTD(cy == 0);
+ if (ln > 0)
+ {
+ MPFR_COM_N (x, u, ln);
+ /* we must add one for the 2-complement ... */
+ cy = mpn_add_1 (x, x, n, MPFR_LIMB_ONE);
+ /* ... and subtract 1 at x[ln], where n = ln + xn */
+ cy -= mpn_sub_1 (x + ln, x + ln, xn, MPFR_LIMB_ONE);
+ }
+ }
+
+ /* cy can be 1 when A=1, i.e., {a, n} = B^n. In that case we should
+ have X = B^n, and setting X to 1-2^{-p} satisties the error bound
+ of 1 ulp. */
+ if (MPFR_UNLIKELY(cy != 0))
+ {
+ cy -= mpn_sub_1 (x, x, n, MPFR_LIMB_ONE << pl);
+ MPFR_ASSERTD(cy == 0);
+ }
+
+ MPFR_TMP_FREE (marker);
+ }
+}
+
+int
+mpfr_rec_sqrt (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t rp, up, wp;
+ mp_size_t rn, wn;
+ int s, cy, inex;
+ mpfr_limb_ptr x;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (u), mpfr_log_prec, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (r), mpfr_log_prec, r, inex));
+
+ /* special values */
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(u)))
+ {
+ if (MPFR_IS_NAN(u))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_ZERO(u)) /* 1/sqrt(+0) = 1/sqrt(-0) = +Inf */
+ {
+ /* 0+ or 0- */
+ MPFR_SET_INF(r);
+ MPFR_SET_POS(r);
+ mpfr_set_divby0 ();
+ MPFR_RET(0); /* Inf is exact */
+ }
+ else
+ {
+ MPFR_ASSERTD(MPFR_IS_INF(u));
+ /* 1/sqrt(-Inf) = NAN */
+ if (MPFR_IS_NEG(u))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ /* 1/sqrt(+Inf) = +0 */
+ MPFR_SET_POS(r);
+ MPFR_SET_ZERO(r);
+ MPFR_RET(0);
+ }
+ }
+
+ /* if u < 0, 1/sqrt(u) is NaN */
+ if (MPFR_UNLIKELY(MPFR_IS_NEG(u)))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+
+ MPFR_SET_POS(r);
+
+ rp = MPFR_PREC(r); /* output precision */
+ up = MPFR_PREC(u); /* input precision */
+ wp = rp + 11; /* initial working precision */
+
+ /* Let u = U*2^e, where e = EXP(u), and 1/2 <= U < 1.
+ If e is even, we compute an approximation of X of (4U)^{-1/2},
+ and the result is X*2^(-(e-2)/2) [case s=1].
+ If e is odd, we compute an approximation of X of (2U)^{-1/2},
+ and the result is X*2^(-(e-1)/2) [case s=0]. */
+
+ /* parity of the exponent of u */
+ s = 1 - ((mpfr_uexp_t) MPFR_GET_EXP (u) & 1);
+
+ rn = LIMB_SIZE(rp);
+
+ /* for the first iteration, if rp + 11 fits into rn limbs, we round up
+ up to a full limb to maximize the chance of rounding, while avoiding
+ to allocate extra space */
+ wp = rp + 11;
+ if (wp < rn * GMP_NUMB_BITS)
+ wp = rn * GMP_NUMB_BITS;
+ for (;;)
+ {
+ MPFR_TMP_MARK (marker);
+ wn = LIMB_SIZE(wp);
+ if (r == u || wn > rn) /* out of place, i.e., we cannot write to r */
+ x = MPFR_TMP_LIMBS_ALLOC (wn);
+ else
+ x = MPFR_MANT(r);
+ mpfr_mpn_rec_sqrt (x, wp, MPFR_MANT(u), up, s);
+ /* If the input was not truncated, the error is at most one ulp;
+ if the input was truncated, the error is at most two ulps
+ (see algorithms.tex). */
+ if (MPFR_LIKELY (mpfr_round_p (x, wn, wp - (wp < up),
+ rp + (rnd_mode == MPFR_RNDN))))
+ break;
+
+ /* We detect only now the exact case where u=2^(2e), to avoid
+ slowing down the average case. This can happen only when the
+ mantissa is exactly 1/2 and the exponent is odd. */
+ if (s == 0 && mpfr_cmp_ui_2exp (u, 1, MPFR_EXP(u) - 1) == 0)
+ {
+ mpfr_prec_t pl = wn * GMP_NUMB_BITS - wp;
+
+ /* we should have x=111...111 */
+ mpn_add_1 (x, x, wn, MPFR_LIMB_ONE << pl);
+ x[wn - 1] = MPFR_LIMB_HIGHBIT;
+ s += 2;
+ break; /* go through */
+ }
+ MPFR_TMP_FREE(marker);
+
+ wp += GMP_NUMB_BITS;
+ }
+ cy = mpfr_round_raw (MPFR_MANT(r), x, wp, 0, rp, rnd_mode, &inex);
+ MPFR_EXP(r) = - (MPFR_EXP(u) - 1 - s) / 2;
+ if (MPFR_UNLIKELY(cy != 0))
+ {
+ MPFR_EXP(r) ++;
+ MPFR_MANT(r)[rn - 1] = MPFR_LIMB_HIGHBIT;
+ }
+ MPFR_TMP_FREE(marker);
+ return mpfr_check_range (r, inex, rnd_mode);
+}
diff --git a/mpfr/src/reldiff.c b/mpfr/src/reldiff.c
new file mode 100644
index 0000000000..a82400ef33
--- /dev/null
+++ b/mpfr/src/reldiff.c
@@ -0,0 +1,73 @@
+/* mpfr_reldiff -- compute relative difference of two floating-point numbers.
+
+Copyright 2000, 2001, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* reldiff(b, c) = abs(b-c)/b */
+void
+mpfr_reldiff (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t b_copy;
+
+ if (MPFR_ARE_SINGULAR (b, c))
+ {
+ if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c))
+ {
+ MPFR_SET_NAN(a);
+ return;
+ }
+ else if (MPFR_IS_INF(b))
+ {
+ if (MPFR_IS_INF (c) && (MPFR_SIGN (c) == MPFR_SIGN (b)))
+ MPFR_SET_ZERO(a);
+ else
+ MPFR_SET_NAN(a);
+ return;
+ }
+ else if (MPFR_IS_INF(c))
+ {
+ MPFR_SET_SAME_SIGN (a, b);
+ MPFR_SET_INF (a);
+ return;
+ }
+ else if (MPFR_IS_ZERO(b)) /* reldiff = abs(c)/c = sign(c) */
+ {
+ mpfr_set_si (a, MPFR_INT_SIGN (c), rnd_mode);
+ return;
+ }
+ /* Fall through */
+ }
+
+ if (a == b)
+ {
+ mpfr_init2 (b_copy, MPFR_PREC(b));
+ mpfr_set (b_copy, b, MPFR_RNDN);
+ }
+
+ mpfr_sub (a, b, c, rnd_mode);
+ mpfr_abs (a, a, rnd_mode); /* for compatibility with MPF */
+ mpfr_div (a, a, (a == b) ? b_copy : b, rnd_mode);
+
+ if (a == b)
+ mpfr_clear (b_copy);
+
+}
diff --git a/mpfr/src/rem1.c b/mpfr/src/rem1.c
new file mode 100644
index 0000000000..24d544154f
--- /dev/null
+++ b/mpfr/src/rem1.c
@@ -0,0 +1,229 @@
+/* mpfr_rem1 -- internal function
+ mpfr_fmod -- compute the floating-point remainder of x/y
+ mpfr_remquo and mpfr_remainder -- argument reduction functions
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+# include "mpfr-impl.h"
+
+/* we return as many bits as we can, keeping just one bit for the sign */
+# define WANTED_BITS (sizeof(long) * CHAR_BIT - 1)
+
+/*
+ rem1 works as follows:
+ The first rounding mode rnd_q indicate if we are actually computing
+ a fmod (MPFR_RNDZ) or a remainder/remquo (MPFR_RNDN).
+
+ Let q = x/y rounded to an integer in the direction rnd_q.
+ Put x - q*y in rem, rounded according to rnd.
+ If quo is not null, the value stored in *quo has the sign of q,
+ and agrees with q with the 2^n low order bits.
+ In other words, *quo = q (mod 2^n) and *quo q >= 0.
+ If rem is zero, then it has the sign of x.
+ The returned 'int' is the inexact flag giving the place of rem wrt x - q*y.
+
+ If x or y is NaN: *quo is undefined, rem is NaN.
+ If x is Inf, whatever y: *quo is undefined, rem is NaN.
+ If y is Inf, x not NaN nor Inf: *quo is 0, rem is x.
+ If y is 0, whatever x: *quo is undefined, rem is NaN.
+ If x is 0, whatever y (not NaN nor 0): *quo is 0, rem is x.
+
+ Otherwise if x and y are neither NaN, Inf nor 0, q is always defined,
+ thus *quo is.
+ Since |x - q*y| <= y/2, no overflow is possible.
+ Only an underflow is possible when y is very small.
+ */
+
+static int
+mpfr_rem1 (mpfr_ptr rem, long *quo, mpfr_rnd_t rnd_q,
+ mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
+{
+ mpfr_exp_t ex, ey;
+ int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x);
+ mpz_t mx, my, r;
+
+ MPFR_ASSERTD (rnd_q == MPFR_RNDN || rnd_q == MPFR_RNDZ);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y)))
+ {
+ if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x)
+ || MPFR_IS_ZERO (y))
+ {
+ /* for remquo, quo is undefined */
+ MPFR_SET_NAN (rem);
+ MPFR_RET_NAN;
+ }
+ else /* either y is Inf and x is 0 or non-special,
+ or x is 0 and y is non-special,
+ in both cases the quotient is zero. */
+ {
+ if (quo)
+ *quo = 0;
+ return mpfr_set (rem, x, rnd);
+ }
+ }
+
+ /* now neither x nor y is NaN, Inf or zero */
+
+ mpz_init (mx);
+ mpz_init (my);
+ mpz_init (r);
+
+ ex = mpfr_get_z_2exp (mx, x); /* x = mx*2^ex */
+ ey = mpfr_get_z_2exp (my, y); /* y = my*2^ey */
+
+ /* to get rid of sign problems, we compute it separately:
+ quo(-x,-y) = quo(x,y), rem(-x,-y) = -rem(x,y)
+ quo(-x,y) = -quo(x,y), rem(-x,y) = -rem(x,y)
+ thus quo = sign(x/y)*quo(|x|,|y|), rem = sign(x)*rem(|x|,|y|) */
+ sign = (signx == MPFR_SIGN (y)) ? 1 : -1;
+ mpz_abs (mx, mx);
+ mpz_abs (my, my);
+ q_is_odd = 0;
+
+ /* divide my by 2^k if possible to make operations mod my easier */
+ {
+ unsigned long k = mpz_scan1 (my, 0);
+ ey += k;
+ mpz_fdiv_q_2exp (my, my, k);
+ }
+
+ if (ex <= ey)
+ {
+ /* q = x/y = mx/(my*2^(ey-ex)) */
+ mpz_mul_2exp (my, my, ey - ex); /* divide mx by my*2^(ey-ex) */
+ if (rnd_q == MPFR_RNDZ)
+ /* 0 <= |r| <= |my|, r has the same sign as mx */
+ mpz_tdiv_qr (mx, r, mx, my);
+ else
+ /* 0 <= |r| <= |my|, r has the same sign as my */
+ mpz_fdiv_qr (mx, r, mx, my);
+
+ if (rnd_q == MPFR_RNDN)
+ q_is_odd = mpz_tstbit (mx, 0);
+ if (quo) /* mx is the quotient */
+ {
+ mpz_tdiv_r_2exp (mx, mx, WANTED_BITS);
+ *quo = mpz_get_si (mx);
+ }
+ }
+ else /* ex > ey */
+ {
+ if (quo) /* remquo case */
+ /* for remquo, to get the low WANTED_BITS more bits of the quotient,
+ we first compute R = X mod Y*2^WANTED_BITS, where X and Y are
+ defined below. Then the low WANTED_BITS of the quotient are
+ floor(R/Y). */
+ mpz_mul_2exp (my, my, WANTED_BITS); /* 2^WANTED_BITS*Y */
+
+ else if (rnd_q == MPFR_RNDN) /* remainder case */
+ /* Let X = mx*2^(ex-ey) and Y = my. Then both X and Y are integers.
+ Assume X = R mod Y, then x = X*2^ey = R*2^ey mod (Y*2^ey=y).
+ To be able to perform the rounding, we need the least significant
+ bit of the quotient, i.e., one more bit in the remainder,
+ which is obtained by dividing by 2Y. */
+ mpz_mul_2exp (my, my, 1); /* 2Y */
+
+ mpz_set_ui (r, 2);
+ mpz_powm_ui (r, r, ex - ey, my); /* 2^(ex-ey) mod my */
+ mpz_mul (r, r, mx);
+ mpz_mod (r, r, my);
+
+ if (quo) /* now 0 <= r < 2^WANTED_BITS*Y */
+ {
+ mpz_fdiv_q_2exp (my, my, WANTED_BITS); /* back to Y */
+ mpz_tdiv_qr (mx, r, r, my);
+ /* oldr = mx*my + newr */
+ *quo = mpz_get_si (mx);
+ q_is_odd = *quo & 1;
+ }
+ else if (rnd_q == MPFR_RNDN) /* now 0 <= r < 2Y in the remainder case */
+ {
+ mpz_fdiv_q_2exp (my, my, 1); /* back to Y */
+ /* least significant bit of q */
+ q_is_odd = mpz_cmpabs (r, my) >= 0;
+ if (q_is_odd)
+ mpz_sub (r, r, my);
+ }
+ /* now 0 <= |r| < |my|, and if needed,
+ q_is_odd is the least significant bit of q */
+ }
+
+ if (mpz_cmp_ui (r, 0) == 0)
+ {
+ inex = mpfr_set_ui (rem, 0, MPFR_RNDN);
+ /* take into account sign of x */
+ if (signx < 0)
+ mpfr_neg (rem, rem, MPFR_RNDN);
+ }
+ else
+ {
+ if (rnd_q == MPFR_RNDN)
+ {
+ /* FIXME: the comparison 2*r < my could be done more efficiently
+ at the mpn level */
+ mpz_mul_2exp (r, r, 1);
+ compare = mpz_cmpabs (r, my);
+ mpz_fdiv_q_2exp (r, r, 1);
+ compare = ((compare > 0) ||
+ ((rnd_q == MPFR_RNDN) && (compare == 0) && q_is_odd));
+ /* if compare != 0, we need to subtract my to r, and add 1 to quo */
+ if (compare)
+ {
+ mpz_sub (r, r, my);
+ if (quo && (rnd_q == MPFR_RNDN))
+ *quo += 1;
+ }
+ }
+ /* take into account sign of x */
+ if (signx < 0)
+ mpz_neg (r, r);
+ inex = mpfr_set_z_2exp (rem, r, ex > ey ? ey : ex, rnd);
+ }
+
+ if (quo)
+ *quo *= sign;
+
+ mpz_clear (mx);
+ mpz_clear (my);
+ mpz_clear (r);
+
+ return inex;
+}
+
+int
+mpfr_remainder (mpfr_ptr rem, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
+{
+ return mpfr_rem1 (rem, (long *) 0, MPFR_RNDN, x, y, rnd);
+}
+
+int
+mpfr_remquo (mpfr_ptr rem, long *quo,
+ mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
+{
+ return mpfr_rem1 (rem, quo, MPFR_RNDN, x, y, rnd);
+}
+
+int
+mpfr_fmod (mpfr_ptr rem, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
+{
+ return mpfr_rem1 (rem, (long *) 0, MPFR_RNDZ, x, y, rnd);
+}
diff --git a/mpfr/src/rint.c b/mpfr/src/rint.c
new file mode 100644
index 0000000000..809f366950
--- /dev/null
+++ b/mpfr/src/rint.c
@@ -0,0 +1,437 @@
+/* mpfr_rint -- Round to an integer.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Merge the following mpfr_rint code with mpfr_round_raw_generic? */
+
+int
+mpfr_rint (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ int sign;
+ int rnd_away;
+ mpfr_exp_t exp;
+
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(u) ))
+ {
+ if (MPFR_IS_NAN(u))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_SAME_SIGN(r, u);
+ if (MPFR_IS_INF(u))
+ {
+ MPFR_SET_INF(r);
+ MPFR_RET(0); /* infinity is exact */
+ }
+ else /* now u is zero */
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(u));
+ MPFR_SET_ZERO(r);
+ MPFR_RET(0); /* zero is exact */
+ }
+ }
+ MPFR_SET_SAME_SIGN (r, u); /* Does nothing if r==u */
+
+ sign = MPFR_INT_SIGN (u);
+ exp = MPFR_GET_EXP (u);
+
+ rnd_away =
+ rnd_mode == MPFR_RNDD ? sign < 0 :
+ rnd_mode == MPFR_RNDU ? sign > 0 :
+ rnd_mode == MPFR_RNDZ ? 0 :
+ rnd_mode == MPFR_RNDA ? 1 :
+ -1; /* round to nearest-even (RNDN) or nearest-away (RNDNA) */
+
+ /* rnd_away:
+ 1 if round away from zero,
+ 0 if round to zero,
+ -1 if not decided yet.
+ */
+
+ if (MPFR_UNLIKELY (exp <= 0)) /* 0 < |u| < 1 ==> round |u| to 0 or 1 */
+ {
+ /* Note: in the MPFR_RNDN mode, 0.5 must be rounded to 0. */
+ if (rnd_away != 0 &&
+ (rnd_away > 0 ||
+ (exp == 0 && (rnd_mode == MPFR_RNDNA ||
+ !mpfr_powerof2_raw (u)))))
+ {
+ mp_limb_t *rp;
+ mp_size_t rm;
+
+ rp = MPFR_MANT(r);
+ rm = (MPFR_PREC(r) - 1) / GMP_NUMB_BITS;
+ rp[rm] = MPFR_LIMB_HIGHBIT;
+ MPN_ZERO(rp, rm);
+ MPFR_SET_EXP (r, 1); /* |r| = 1 */
+ MPFR_RET(sign > 0 ? 2 : -2);
+ }
+ else
+ {
+ MPFR_SET_ZERO(r); /* r = 0 */
+ MPFR_RET(sign > 0 ? -2 : 2);
+ }
+ }
+ else /* exp > 0, |u| >= 1 */
+ {
+ mp_limb_t *up, *rp;
+ mp_size_t un, rn, ui;
+ int sh, idiff;
+ int uflags;
+
+ /*
+ * uflags will contain:
+ * _ 0 if u is an integer representable in r,
+ * _ 1 if u is an integer not representable in r,
+ * _ 2 if u is not an integer.
+ */
+
+ up = MPFR_MANT(u);
+ rp = MPFR_MANT(r);
+
+ un = MPFR_LIMB_SIZE(u);
+ rn = MPFR_LIMB_SIZE(r);
+ MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (r));
+
+ MPFR_SET_EXP (r, exp); /* Does nothing if r==u */
+
+ if ((exp - 1) / GMP_NUMB_BITS >= un)
+ {
+ ui = un;
+ idiff = 0;
+ uflags = 0; /* u is an integer, representable or not in r */
+ }
+ else
+ {
+ mp_size_t uj;
+
+ ui = (exp - 1) / GMP_NUMB_BITS + 1; /* #limbs of the int part */
+ MPFR_ASSERTD (un >= ui);
+ uj = un - ui; /* lowest limb of the integer part */
+ idiff = exp % GMP_NUMB_BITS; /* #int-part bits in up[uj] or 0 */
+
+ uflags = idiff == 0 || (up[uj] << idiff) == 0 ? 0 : 2;
+ if (uflags == 0)
+ while (uj > 0)
+ if (up[--uj] != 0)
+ {
+ uflags = 2;
+ break;
+ }
+ }
+
+ if (ui > rn)
+ {
+ /* More limbs in the integer part of u than in r.
+ Just round u with the precision of r. */
+ MPFR_ASSERTD (rp != up && un > rn);
+ MPN_COPY (rp, up + (un - rn), rn); /* r != u */
+ if (rnd_away < 0)
+ {
+ /* This is a rounding to nearest mode (MPFR_RNDN or MPFR_RNDNA).
+ Decide the rounding direction here. */
+ if (rnd_mode == MPFR_RNDN &&
+ (rp[0] & (MPFR_LIMB_ONE << sh)) == 0)
+ { /* halfway cases rounded toward zero */
+ mp_limb_t a, b;
+ /* a: rounding bit and some of the following bits */
+ /* b: boundary for a (weight of the rounding bit in a) */
+ if (sh != 0)
+ {
+ a = rp[0] & ((MPFR_LIMB_ONE << sh) - 1);
+ b = MPFR_LIMB_ONE << (sh - 1);
+ }
+ else
+ {
+ a = up[un - rn - 1];
+ b = MPFR_LIMB_HIGHBIT;
+ }
+ rnd_away = a > b;
+ if (a == b)
+ {
+ mp_size_t i;
+ for (i = un - rn - 1 - (sh == 0); i >= 0; i--)
+ if (up[i] != 0)
+ {
+ rnd_away = 1;
+ break;
+ }
+ }
+ }
+ else /* halfway cases rounded away from zero */
+ rnd_away = /* rounding bit */
+ ((sh != 0 && (rp[0] & (MPFR_LIMB_ONE << (sh - 1))) != 0) ||
+ (sh == 0 && (up[un - rn - 1] & MPFR_LIMB_HIGHBIT) != 0));
+ }
+ if (uflags == 0)
+ { /* u is an integer; determine if it is representable in r */
+ if (sh != 0 && rp[0] << (GMP_NUMB_BITS - sh) != 0)
+ uflags = 1; /* u is not representable in r */
+ else
+ {
+ mp_size_t i;
+ for (i = un - rn - 1; i >= 0; i--)
+ if (up[i] != 0)
+ {
+ uflags = 1; /* u is not representable in r */
+ break;
+ }
+ }
+ }
+ }
+ else /* ui <= rn */
+ {
+ mp_size_t uj, rj;
+ int ush;
+
+ uj = un - ui; /* lowest limb of the integer part in u */
+ rj = rn - ui; /* lowest limb of the integer part in r */
+
+ if (MPFR_LIKELY (rp != up))
+ MPN_COPY(rp + rj, up + uj, ui);
+
+ /* Ignore the lowest rj limbs, all equal to zero. */
+ rp += rj;
+ rn = ui;
+
+ /* number of fractional bits in whole rp[0] */
+ ush = idiff == 0 ? 0 : GMP_NUMB_BITS - idiff;
+
+ if (rj == 0 && ush < sh)
+ {
+ /* If u is an integer (uflags == 0), we need to determine
+ if it is representable in r, i.e. if its sh - ush bits
+ in the non-significant part of r are all 0. */
+ if (uflags == 0 && (rp[0] & ((MPFR_LIMB_ONE << sh) -
+ (MPFR_LIMB_ONE << ush))) != 0)
+ uflags = 1; /* u is an integer not representable in r */
+ }
+ else /* The integer part of u fits in r, we'll round to it. */
+ sh = ush;
+
+ if (rnd_away < 0)
+ {
+ /* This is a rounding to nearest mode.
+ Decide the rounding direction here. */
+ if (uj == 0 && sh == 0)
+ rnd_away = 0; /* rounding bit = 0 (not represented in u) */
+ else if (rnd_mode == MPFR_RNDN &&
+ (rp[0] & (MPFR_LIMB_ONE << sh)) == 0)
+ { /* halfway cases rounded toward zero */
+ mp_limb_t a, b;
+ /* a: rounding bit and some of the following bits */
+ /* b: boundary for a (weight of the rounding bit in a) */
+ if (sh != 0)
+ {
+ a = rp[0] & ((MPFR_LIMB_ONE << sh) - 1);
+ b = MPFR_LIMB_ONE << (sh - 1);
+ }
+ else
+ {
+ MPFR_ASSERTD (uj >= 1); /* see above */
+ a = up[uj - 1];
+ b = MPFR_LIMB_HIGHBIT;
+ }
+ rnd_away = a > b;
+ if (a == b)
+ {
+ mp_size_t i;
+ for (i = uj - 1 - (sh == 0); i >= 0; i--)
+ if (up[i] != 0)
+ {
+ rnd_away = 1;
+ break;
+ }
+ }
+ }
+ else /* halfway cases rounded away from zero */
+ rnd_away = /* rounding bit */
+ ((sh != 0 && (rp[0] & (MPFR_LIMB_ONE << (sh - 1))) != 0) ||
+ (sh == 0 && (MPFR_ASSERTD (uj >= 1),
+ up[uj - 1] & MPFR_LIMB_HIGHBIT) != 0));
+ }
+ /* Now we can make the low rj limbs to 0 */
+ MPN_ZERO (rp-rj, rj);
+ }
+
+ if (sh != 0)
+ rp[0] &= MP_LIMB_T_MAX << sh;
+
+ /* If u is a representable integer, there is no rounding. */
+ if (uflags == 0)
+ MPFR_RET(0);
+
+ MPFR_ASSERTD (rnd_away >= 0); /* rounding direction is defined */
+ if (rnd_away && mpn_add_1(rp, rp, rn, MPFR_LIMB_ONE << sh))
+ {
+ if (exp == __gmpfr_emax)
+ return mpfr_overflow(r, rnd_mode, MPFR_SIGN(r)) >= 0 ?
+ uflags : -uflags;
+ else
+ {
+ MPFR_SET_EXP(r, exp + 1);
+ rp[rn-1] = MPFR_LIMB_HIGHBIT;
+ }
+ }
+
+ MPFR_RET (rnd_away ^ (sign < 0) ? uflags : -uflags);
+ } /* exp > 0, |u| >= 1 */
+}
+
+#undef mpfr_round
+
+int
+mpfr_round (mpfr_ptr r, mpfr_srcptr u)
+{
+ return mpfr_rint (r, u, MPFR_RNDNA);
+}
+
+#undef mpfr_trunc
+
+int
+mpfr_trunc (mpfr_ptr r, mpfr_srcptr u)
+{
+ return mpfr_rint (r, u, MPFR_RNDZ);
+}
+
+#undef mpfr_ceil
+
+int
+mpfr_ceil (mpfr_ptr r, mpfr_srcptr u)
+{
+ return mpfr_rint (r, u, MPFR_RNDU);
+}
+
+#undef mpfr_floor
+
+int
+mpfr_floor (mpfr_ptr r, mpfr_srcptr u)
+{
+ return mpfr_rint (r, u, MPFR_RNDD);
+}
+
+#undef mpfr_rint_round
+
+int
+mpfr_rint_round (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(u) ) || mpfr_integer_p (u))
+ return mpfr_set (r, u, rnd_mode);
+ else
+ {
+ mpfr_t tmp;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (tmp, MPFR_PREC (u));
+ /* round(u) is representable in tmp unless an overflow occurs */
+ MPFR_BLOCK (flags, mpfr_round (tmp, u));
+ inex = (MPFR_OVERFLOW (flags)
+ ? mpfr_overflow (r, rnd_mode, MPFR_SIGN (u))
+ : mpfr_set (r, tmp, rnd_mode));
+ mpfr_clear (tmp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inex, rnd_mode);
+ }
+}
+
+#undef mpfr_rint_trunc
+
+int
+mpfr_rint_trunc (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(u) ) || mpfr_integer_p (u))
+ return mpfr_set (r, u, rnd_mode);
+ else
+ {
+ mpfr_t tmp;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (tmp, MPFR_PREC (u));
+ /* trunc(u) is always representable in tmp */
+ mpfr_trunc (tmp, u);
+ inex = mpfr_set (r, tmp, rnd_mode);
+ mpfr_clear (tmp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inex, rnd_mode);
+ }
+}
+
+#undef mpfr_rint_ceil
+
+int
+mpfr_rint_ceil (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(u) ) || mpfr_integer_p (u))
+ return mpfr_set (r, u, rnd_mode);
+ else
+ {
+ mpfr_t tmp;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (tmp, MPFR_PREC (u));
+ /* ceil(u) is representable in tmp unless an overflow occurs */
+ MPFR_BLOCK (flags, mpfr_ceil (tmp, u));
+ inex = (MPFR_OVERFLOW (flags)
+ ? mpfr_overflow (r, rnd_mode, MPFR_SIGN_POS)
+ : mpfr_set (r, tmp, rnd_mode));
+ mpfr_clear (tmp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inex, rnd_mode);
+ }
+}
+
+#undef mpfr_rint_floor
+
+int
+mpfr_rint_floor (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(u) ) || mpfr_integer_p (u))
+ return mpfr_set (r, u, rnd_mode);
+ else
+ {
+ mpfr_t tmp;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_BLOCK_DECL (flags);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (tmp, MPFR_PREC (u));
+ /* floor(u) is representable in tmp unless an overflow occurs */
+ MPFR_BLOCK (flags, mpfr_floor (tmp, u));
+ inex = (MPFR_OVERFLOW (flags)
+ ? mpfr_overflow (r, rnd_mode, MPFR_SIGN_NEG)
+ : mpfr_set (r, tmp, rnd_mode));
+ mpfr_clear (tmp);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inex, rnd_mode);
+ }
+}
diff --git a/mpfr/src/root.c b/mpfr/src/root.c
new file mode 100644
index 0000000000..619c9dd0f9
--- /dev/null
+++ b/mpfr/src/root.c
@@ -0,0 +1,205 @@
+/* mpfr_root -- kth root.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+ /* The computation of y = x^(1/k) is done as follows:
+
+ Let x = sign * m * 2^(k*e) where m is an integer
+
+ with 2^(k*(n-1)) <= m < 2^(k*n) where n = PREC(y)
+
+ and m = s^k + r where 0 <= r and m < (s+1)^k
+
+ we want that s has n bits i.e. s >= 2^(n-1), or m >= 2^(k*(n-1))
+ i.e. m must have at least k*(n-1)+1 bits
+
+ then, not taking into account the sign, the result will be
+ x^(1/k) = s * 2^e or (s+1) * 2^e according to the rounding mode.
+ */
+
+int
+mpfr_root (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
+{
+ mpz_t m;
+ mpfr_exp_t e, r, sh;
+ mpfr_prec_t n, size_m, tmp;
+ int inexact, negative;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg k=%lu rnd=%d",
+ mpfr_get_prec (x), mpfr_log_prec, x, k, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ if (MPFR_UNLIKELY (k <= 1))
+ {
+ if (k < 1) /* k==0 => y=x^(1/0)=x^(+Inf) */
+#if 0
+ /* For 0 <= x < 1 => +0.
+ For x = 1 => 1.
+ For x > 1, => +Inf.
+ For x < 0 => NaN.
+ */
+ {
+ if (MPFR_IS_NEG (x) && !MPFR_IS_ZERO (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ inexact = mpfr_cmp (x, __gmpfr_one);
+ if (inexact == 0)
+ return mpfr_set_ui (y, 1, rnd_mode); /* 1 may be Out of Range */
+ else if (inexact < 0)
+ return mpfr_set_ui (y, 0, rnd_mode); /* 0+ */
+ else
+ {
+ mpfr_set_inf (y, 1);
+ return 0;
+ }
+ }
+#endif
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else /* y =x^(1/1)=x */
+ return mpfr_set (y, x, rnd_mode);
+ }
+
+ /* Singular values */
+ else if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y); /* NaN^(1/k) = NaN */
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (x)) /* +Inf^(1/k) = +Inf
+ -Inf^(1/k) = -Inf if k odd
+ -Inf^(1/k) = NaN if k even */
+ {
+ if (MPFR_IS_NEG(x) && (k % 2 == 0))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ else /* x is necessarily 0: (+0)^(1/k) = +0
+ (-0)^(1/k) = -0 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ }
+
+ /* Returns NAN for x < 0 and k even */
+ else if (MPFR_IS_NEG (x) && (k % 2 == 0))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+
+ /* General case */
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpz_init (m);
+
+ e = mpfr_get_z_2exp (m, x); /* x = m * 2^e */
+ if ((negative = MPFR_IS_NEG(x)))
+ mpz_neg (m, m);
+ r = e % (mpfr_exp_t) k;
+ if (r < 0)
+ r += k; /* now r = e (mod k) with 0 <= e < r */
+ /* x = (m*2^r) * 2^(e-r) where e-r is a multiple of k */
+
+ MPFR_MPZ_SIZEINBASE2 (size_m, m);
+ /* for rounding to nearest, we want the round bit to be in the root */
+ n = MPFR_PREC (y) + (rnd_mode == MPFR_RNDN);
+
+ /* we now multiply m by 2^(r+k*sh) so that root(m,k) will give
+ exactly n bits: we want k*(n-1)+1 <= size_m + k*sh + r <= k*n
+ i.e. sh = floor ((kn-size_m-r)/k) */
+ if ((mpfr_exp_t) size_m + r > k * (mpfr_exp_t) n)
+ sh = 0; /* we already have too many bits */
+ else
+ sh = (k * (mpfr_exp_t) n - (mpfr_exp_t) size_m - r) / k;
+ sh = k * sh + r;
+ if (sh >= 0)
+ {
+ mpz_mul_2exp (m, m, sh);
+ e = e - sh;
+ }
+ else if (r > 0)
+ {
+ mpz_mul_2exp (m, m, r);
+ e = e - r;
+ }
+
+ /* invariant: x = m*2^e, with e divisible by k */
+
+ /* we reuse the variable m to store the kth root, since it is not needed
+ any more: we just need to know if the root is exact */
+ inexact = mpz_root (m, m, k) == 0;
+
+ MPFR_MPZ_SIZEINBASE2 (tmp, m);
+ sh = tmp - n;
+ if (sh > 0) /* we have to flush to 0 the last sh bits from m */
+ {
+ inexact = inexact || ((mpfr_exp_t) mpz_scan1 (m, 0) < sh);
+ mpz_fdiv_q_2exp (m, m, sh);
+ e += k * sh;
+ }
+
+ if (inexact)
+ {
+ if (negative)
+ rnd_mode = MPFR_INVERT_RND (rnd_mode);
+ if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
+ || (rnd_mode == MPFR_RNDN && mpz_tstbit (m, 0)))
+ inexact = 1, mpz_add_ui (m, m, 1);
+ else
+ inexact = -1;
+ }
+
+ /* either inexact is not zero, and the conversion is exact, i.e. inexact
+ is not changed; or inexact=0, and inexact is set only when
+ rnd_mode=MPFR_RNDN and bit (n+1) from m is 1 */
+ inexact += mpfr_set_z (y, m, MPFR_RNDN);
+ MPFR_SET_EXP (y, MPFR_GET_EXP (y) + e / (mpfr_exp_t) k);
+
+ if (negative)
+ {
+ MPFR_CHANGE_SIGN (y);
+ inexact = -inexact;
+ }
+
+ mpz_clear (m);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/round_near_x.c b/mpfr/src/round_near_x.c
new file mode 100644
index 0000000000..9789c9b542
--- /dev/null
+++ b/mpfr/src/round_near_x.c
@@ -0,0 +1,233 @@
+/* mpfr_round_near_x -- Round a floating point number nears another one.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Use MPFR_FAST_COMPUTE_IF_SMALL_INPUT instead (a simple wrapper) */
+
+/* int mpfr_round_near_x (mpfr_ptr y, mpfr_srcptr v, mpfr_uexp_t err, int dir,
+ mpfr_rnd_t rnd)
+
+ TODO: fix this description.
+ Assuming y = o(f(x)) = o(x + g(x)) with |g(x)| < 2^(EXP(v)-error)
+ If x is small enough, y ~= v. This function checks and does this.
+
+ It assumes that f(x) is not representable exactly as a FP number.
+ v must not be a singular value (NAN, INF or ZERO), usual values are
+ v=1 or v=x.
+
+ y is the destination (a mpfr_t), v the value to set (a mpfr_t),
+ err the error term (a mpfr_uexp_t) such that |g(x)| < 2^(EXP(x)-err),
+ dir (an int) is the direction of the error (if dir = 0,
+ it rounds toward 0, if dir=1, it rounds away from 0),
+ rnd the rounding mode.
+
+ It returns 0 if it can't round.
+ Otherwise it returns the ternary flag (It can't return an exact value).
+*/
+
+/* What "small enough" means?
+
+ We work with the positive values.
+ Assuming err > Prec (y)+1
+
+ i = [ y = o(x)] // i = inexact flag
+ If i == 0
+ Setting x in y is exact. We have:
+ y = [XXXXXXXXX[...]]0[...] + error where [..] are optional zeros
+ if dirError = ToInf,
+ x < f(x) < x + 2^(EXP(x)-err)
+ since x=y, and ulp (y)/2 > 2^(EXP(x)-err), we have:
+ y < f(x) < y+ulp(y) and |y-f(x)| < ulp(y)/2
+ if rnd = RNDN, nothing
+ if rnd = RNDZ, nothing
+ if rnd = RNDA, addoneulp
+ elif dirError = ToZero
+ x -2^(EXP(x)-err) < f(x) < x
+ since x=y, and ulp (y)/2 > 2^(EXP(x)-err), we have:
+ y-ulp(y) < f(x) < y and |y-f(x)| < ulp(y)/2
+ if rnd = RNDN, nothing
+ if rnd = RNDZ, nexttozero
+ if rnd = RNDA, nothing
+ NOTE: err > prec (y)+1 is needed only for RNDN.
+ elif i > 0 and i = EVEN_ROUNDING
+ So rnd = RNDN and we have y = x + ulp(y)/2
+ if dirError = ToZero,
+ we have x -2^(EXP(x)-err) < f(x) < x
+ so y - ulp(y)/2 - 2^(EXP(x)-err) < f(x) < y-ulp(y)/2
+ so y -ulp(y) < f(x) < y-ulp(y)/2
+ => nexttozero(y)
+ elif dirError = ToInf
+ we have x < f(x) < x + 2^(EXP(x)-err)
+ so y - ulp(y)/2 < f(x) < y+ulp(y)/2-ulp(y)/2
+ so y - ulp(y)/2 < f(x) < y
+ => do nothing
+ elif i < 0 and i = -EVEN_ROUNDING
+ So rnd = RNDN and we have y = x - ulp(y)/2
+ if dirError = ToZero,
+ y < f(x) < y + ulp(y)/2 => do nothing
+ if dirError = ToInf
+ y + ulp(y)/2 < f(x) < y + ulp(y) => AddOneUlp
+ elif i > 0
+ we can't have rnd = RNDZ, and prec(x) > prec(y), so ulp(x) < ulp(y)
+ we have y - ulp (y) < x < y
+ or more exactly y - ulp(y) + ulp(x)/2 <= x <= y - ulp(x)/2
+ if rnd = RNDA,
+ if dirError = ToInf,
+ we have x < f(x) < x + 2^(EXP(x)-err)
+ if err > prec (x),
+ we have 2^(EXP(x)-err) < ulp(x), so 2^(EXP(x)-err) <= ulp(x)/2
+ so f(x) <= y - ulp(x)/2+ulp(x)/2 <= y
+ and y - ulp(y) < x < f(x)
+ so we have y - ulp(y) < f(x) < y
+ so do nothing.
+ elif we can round, ie y - ulp(y) < x + 2^(EXP(x)-err) < y
+ we have y - ulp(y) < x < f(x) < x + 2^(EXP(x)-err) < y
+ so do nothing
+ otherwise
+ Wrong. Example X=[0.11101]111111110000
+ + 1111111111111111111....
+ elif dirError = ToZero
+ we have x - 2^(EXP(x)-err) < f(x) < x
+ so f(x) < x < y
+ if err > prec (x)
+ x-2^(EXP(x)-err) >= x-ulp(x)/2 >= y - ulp(y) + ulp(x)/2-ulp(x)/2
+ so y - ulp(y) < f(x) < y
+ so do nothing
+ elif we can round, ie y - ulp(y) < x - 2^(EXP(x)-err) < y
+ y - ulp(y) < x - 2^(EXP(x)-err) < f(x) < y
+ so do nothing
+ otherwise
+ Wrong. Example: X=[1.111010]00000010
+ - 10000001000000000000100....
+ elif rnd = RNDN,
+ y - ulp(y)/2 < x < y and we can't have x = y-ulp(y)/2:
+ so we have:
+ y - ulp(y)/2 + ulp(x)/2 <= x <= y - ulp(x)/2
+ if dirError = ToInf
+ we have x < f(x) < x+2^(EXP(x)-err) and ulp(y) > 2^(EXP(x)-err)
+ so y - ulp(y)/2 + ulp (x)/2 < f(x) < y + ulp (y)/2 - ulp (x)/2
+ we can round but we can't compute inexact flag.
+ if err > prec (x)
+ y - ulp(y)/2 + ulp (x)/2 < f(x) < y + ulp(x)/2 - ulp(x)/2
+ so y - ulp(y)/2 + ulp (x)/2 < f(x) < y
+ we can round and compute inexact flag. do nothing
+ elif we can round, ie y - ulp(y)/2 < x + 2^(EXP(x)-err) < y
+ we have y - ulp(y)/2 + ulp (x)/2 < f(x) < y
+ so do nothing
+ otherwise
+ Wrong
+ elif dirError = ToZero
+ we have x -2^(EXP(x)-err) < f(x) < x and ulp(y)/2 > 2^(EXP(x)-err)
+ so y-ulp(y)+ulp(x)/2 < f(x) < y - ulp(x)/2
+ if err > prec (x)
+ x- ulp(x)/2 < f(x) < x
+ so y - ulp(y)/2+ulp(x)/2 - ulp(x)/2 < f(x) < x <= y - ulp(x)/2 < y
+ do nothing
+ elif we can round, ie y-ulp(y)/2 < x-2^(EXP(x)-err) < y
+ we have y-ulp(y)/2 < x-2^(EXP(x)-err) < f(x) < x < y
+ do nothing
+ otherwise
+ Wrong
+ elif i < 0
+ same thing?
+ */
+
+int
+mpfr_round_near_x (mpfr_ptr y, mpfr_srcptr v, mpfr_uexp_t err, int dir,
+ mpfr_rnd_t rnd)
+{
+ int inexact, sign;
+ unsigned int old_flags = __gmpfr_flags;
+
+ MPFR_ASSERTD (!MPFR_IS_SINGULAR (v));
+ MPFR_ASSERTD (dir == 0 || dir == 1);
+
+ /* First check if we can round. The test is more restrictive than
+ necessary. Note that if err is not representable in an mpfr_exp_t,
+ then err > MPFR_PREC (v) and the conversion to mpfr_exp_t will not
+ occur. */
+ if (!(err > MPFR_PREC (y) + 1
+ && (err > MPFR_PREC (v)
+ || mpfr_round_p (MPFR_MANT (v), MPFR_LIMB_SIZE (v),
+ (mpfr_exp_t) err,
+ MPFR_PREC (y) + (rnd == MPFR_RNDN)))))
+ /* If we assume we can not round, return 0, and y is not modified */
+ return 0;
+
+ /* First round v in y */
+ sign = MPFR_SIGN (v);
+ MPFR_SET_EXP (y, MPFR_GET_EXP (v));
+ MPFR_SET_SIGN (y, sign);
+ MPFR_RNDRAW_GEN (inexact, y, MPFR_MANT (v), MPFR_PREC (v), rnd, sign,
+ if (dir == 0)
+ {
+ inexact = -sign;
+ goto trunc_doit;
+ }
+ else
+ goto addoneulp;
+ , if (MPFR_UNLIKELY (++MPFR_EXP (y) > __gmpfr_emax))
+ mpfr_overflow (y, rnd, sign)
+ );
+
+ /* Fix it in some cases */
+ MPFR_ASSERTD (!MPFR_IS_NAN (y) && !MPFR_IS_ZERO (y));
+ /* If inexact == 0, setting y from v is exact but we haven't
+ take into account yet the error term */
+ if (inexact == 0)
+ {
+ if (dir == 0) /* The error term is negative for v positive */
+ {
+ inexact = sign;
+ if (MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG_SIGN (sign)))
+ {
+ /* case nexttozero */
+ /* The underflow flag should be set if the result is zero */
+ __gmpfr_flags = old_flags;
+ inexact = -sign;
+ mpfr_nexttozero (y);
+ if (MPFR_UNLIKELY (MPFR_IS_ZERO (y)))
+ mpfr_set_underflow ();
+ }
+ }
+ else /* The error term is positive for v positive */
+ {
+ inexact = -sign;
+ /* Round Away */
+ if (rnd != MPFR_RNDN && !MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG_SIGN(sign)))
+ {
+ /* case nexttoinf */
+ /* The overflow flag should be set if the result is infinity */
+ inexact = sign;
+ mpfr_nexttoinf (y);
+ if (MPFR_UNLIKELY (MPFR_IS_INF (y)))
+ mpfr_set_overflow ();
+ }
+ }
+ }
+
+ /* the inexact flag cannot be 0, since this would mean an exact value,
+ and in this case we cannot round correctly */
+ MPFR_ASSERTD(inexact != 0);
+ MPFR_RET (inexact);
+}
diff --git a/mpfr/src/round_p.c b/mpfr/src/round_p.c
new file mode 100644
index 0000000000..4a35831014
--- /dev/null
+++ b/mpfr/src/round_p.c
@@ -0,0 +1,123 @@
+/* mpfr_round_p -- check if an approximation is roundable.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Check against mpfr_can_round? */
+#ifdef WANT_ASSERT
+# if WANT_ASSERT >= 2
+int mpfr_round_p_2 (mp_limb_t *, mp_size_t, mpfr_exp_t, mpfr_prec_t);
+int
+mpfr_round_p (mp_limb_t *bp, mp_size_t bn, mpfr_exp_t err0, mpfr_prec_t prec)
+{
+ int i1, i2;
+
+ i1 = mpfr_round_p_2 (bp, bn, err0, prec);
+ i2 = mpfr_can_round_raw (bp, bn, MPFR_SIGN_POS, err0,
+ MPFR_RNDN, MPFR_RNDZ, prec);
+ if (i1 != i2)
+ {
+ fprintf (stderr, "mpfr_round_p(%d) != mpfr_can_round(%d)!\n"
+ "bn = %lu, err0 = %ld, prec = %lu\nbp = ", i1, i2,
+ (unsigned long) bn, (long) err0, (unsigned long) prec);
+ gmp_fprintf (stderr, "%NX\n", bp, bn);
+ MPFR_ASSERTN (0);
+ }
+ return i1;
+}
+# define mpfr_round_p mpfr_round_p_2
+# endif
+#endif
+
+/*
+ * Assuming {bp, bn} is an approximation of a non-singular number
+ * with error at most equal to 2^(EXP(b)-err0) (`err0' bits of b are known)
+ * of direction unknown, check if we can round b toward zero with
+ * precision prec.
+ */
+int
+mpfr_round_p (mp_limb_t *bp, mp_size_t bn, mpfr_exp_t err0, mpfr_prec_t prec)
+{
+ mpfr_prec_t err;
+ mp_size_t k, n;
+ mp_limb_t tmp, mask;
+ int s;
+
+ err = (mpfr_prec_t) bn * GMP_NUMB_BITS;
+ if (MPFR_UNLIKELY (err0 <= 0 || (mpfr_uexp_t) err0 <= prec || prec >= err))
+ return 0; /* can't round */
+ err = MIN (err, (mpfr_uexp_t) err0);
+
+ k = prec / GMP_NUMB_BITS;
+ s = GMP_NUMB_BITS - prec%GMP_NUMB_BITS;
+ n = err / GMP_NUMB_BITS - k;
+
+ MPFR_ASSERTD (n >= 0);
+ MPFR_ASSERTD (bn > k);
+
+ /* Check first limb */
+ bp += bn-1-k;
+ tmp = *bp--;
+ mask = s == GMP_NUMB_BITS ? MP_LIMB_T_MAX : MPFR_LIMB_MASK (s);
+ tmp &= mask;
+
+ if (MPFR_LIKELY (n == 0))
+ {
+ /* prec and error are in the same limb */
+ s = GMP_NUMB_BITS - err % GMP_NUMB_BITS;
+ MPFR_ASSERTD (s < GMP_NUMB_BITS);
+ tmp >>= s;
+ mask >>= s;
+ return tmp != 0 && tmp != mask;
+ }
+ else if (MPFR_UNLIKELY (tmp == 0))
+ {
+ /* Check if all (n-1) limbs are 0 */
+ while (--n)
+ if (*bp-- != 0)
+ return 1;
+ /* Check if final error limb is 0 */
+ s = GMP_NUMB_BITS - err % GMP_NUMB_BITS;
+ if (s == GMP_NUMB_BITS)
+ return 0;
+ tmp = *bp >> s;
+ return tmp != 0;
+ }
+ else if (MPFR_UNLIKELY (tmp == mask))
+ {
+ /* Check if all (n-1) limbs are 11111111111111111 */
+ while (--n)
+ if (*bp-- != MP_LIMB_T_MAX)
+ return 1;
+ /* Check if final error limb is 0 */
+ s = GMP_NUMB_BITS - err % GMP_NUMB_BITS;
+ if (s == GMP_NUMB_BITS)
+ return 0;
+ tmp = *bp >> s;
+ return tmp != (MP_LIMB_T_MAX >> s);
+ }
+ else
+ {
+ /* First limb is different from 000000 or 1111111 */
+ return 1;
+ }
+}
diff --git a/mpfr/src/round_prec.c b/mpfr/src/round_prec.c
new file mode 100644
index 0000000000..600ac8d6f2
--- /dev/null
+++ b/mpfr/src/round_prec.c
@@ -0,0 +1,240 @@
+/* mpfr_round_raw_generic, mpfr_round_raw2, mpfr_round_raw, mpfr_prec_round,
+ mpfr_can_round, mpfr_can_round_raw -- various rounding functions
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#define mpfr_round_raw_generic mpfr_round_raw
+#define flag 0
+#define use_inexp 1
+#include "round_raw_generic.c"
+
+#define mpfr_round_raw_generic mpfr_round_raw_2
+#define flag 1
+#define use_inexp 0
+#include "round_raw_generic.c"
+
+/* Seems to be unused. Remove comment to implement it.
+#define mpfr_round_raw_generic mpfr_round_raw_3
+#define flag 1
+#define use_inexp 1
+#include "round_raw_generic.c"
+*/
+
+#define mpfr_round_raw_generic mpfr_round_raw_4
+#define flag 0
+#define use_inexp 0
+#include "round_raw_generic.c"
+
+int
+mpfr_prec_round (mpfr_ptr x, mpfr_prec_t prec, mpfr_rnd_t rnd_mode)
+{
+ mp_limb_t *tmp, *xp;
+ int carry, inexact;
+ mpfr_prec_t nw, ow;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_ASSERTN(prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX);
+
+ nw = MPFR_PREC2LIMBS (prec); /* needed allocated limbs */
+
+ /* check if x has enough allocated space for the significand */
+ /* Get the number of limbs from the precision.
+ (Compatible with all allocation methods) */
+ ow = MPFR_LIMB_SIZE (x);
+ if (nw > ow)
+ {
+ /* FIXME: Variable can't be created using custom allocation,
+ MPFR_DECL_INIT or GROUP_ALLOC: How to detect? */
+ ow = MPFR_GET_ALLOC_SIZE(x);
+ if (nw > ow)
+ {
+ /* Realloc significand */
+ mpfr_limb_ptr tmpx = (mpfr_limb_ptr) (*__gmp_reallocate_func)
+ (MPFR_GET_REAL_PTR(x), MPFR_MALLOC_SIZE(ow), MPFR_MALLOC_SIZE(nw));
+ MPFR_SET_MANT_PTR(x, tmpx); /* mant ptr must be set
+ before alloc size */
+ MPFR_SET_ALLOC_SIZE(x, nw); /* new number of allocated limbs */
+ }
+ }
+
+ if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(x) ))
+ {
+ MPFR_PREC(x) = prec; /* Special value: need to set prec */
+ if (MPFR_IS_NAN(x))
+ MPFR_RET_NAN;
+ MPFR_ASSERTD(MPFR_IS_INF(x) || MPFR_IS_ZERO(x));
+ return 0; /* infinity and zero are exact */
+ }
+
+ /* x is a non-zero real number */
+
+ MPFR_TMP_MARK(marker);
+ tmp = MPFR_TMP_LIMBS_ALLOC (nw);
+ xp = MPFR_MANT(x);
+ carry = mpfr_round_raw (tmp, xp, MPFR_PREC(x), MPFR_IS_NEG(x),
+ prec, rnd_mode, &inexact);
+ MPFR_PREC(x) = prec;
+
+ if (MPFR_UNLIKELY(carry))
+ {
+ mpfr_exp_t exp = MPFR_EXP (x);
+
+ if (MPFR_UNLIKELY(exp == __gmpfr_emax))
+ (void) mpfr_overflow(x, rnd_mode, MPFR_SIGN(x));
+ else
+ {
+ MPFR_ASSERTD (exp < __gmpfr_emax);
+ MPFR_SET_EXP (x, exp + 1);
+ xp[nw - 1] = MPFR_LIMB_HIGHBIT;
+ if (nw - 1 > 0)
+ MPN_ZERO(xp, nw - 1);
+ }
+ }
+ else
+ MPN_COPY(xp, tmp, nw);
+
+ MPFR_TMP_FREE(marker);
+ return inexact;
+}
+
+/* assumption: GMP_NUMB_BITS is a power of 2 */
+
+/* assuming b is an approximation to x in direction rnd1 with error at
+ most 2^(MPFR_EXP(b)-err), returns 1 if one is able to round exactly
+ x to precision prec with direction rnd2, and 0 otherwise.
+
+ Side effects: none.
+*/
+
+int
+mpfr_can_round (mpfr_srcptr b, mpfr_exp_t err, mpfr_rnd_t rnd1,
+ mpfr_rnd_t rnd2, mpfr_prec_t prec)
+{
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(b)))
+ return 0; /* We cannot round if Zero, Nan or Inf */
+ else
+ return mpfr_can_round_raw (MPFR_MANT(b), MPFR_LIMB_SIZE(b),
+ MPFR_SIGN(b), err, rnd1, rnd2, prec);
+}
+
+int
+mpfr_can_round_raw (const mp_limb_t *bp, mp_size_t bn, int neg, mpfr_exp_t err0,
+ mpfr_rnd_t rnd1, mpfr_rnd_t rnd2, mpfr_prec_t prec)
+{
+ mpfr_prec_t err;
+ mp_size_t k, k1, tn;
+ int s, s1;
+ mp_limb_t cc, cc2;
+ mp_limb_t *tmp;
+ MPFR_TMP_DECL(marker);
+
+ if (MPFR_UNLIKELY(err0 < 0 || (mpfr_uexp_t) err0 <= prec))
+ return 0; /* can't round */
+ else if (MPFR_UNLIKELY (prec > (mpfr_prec_t) bn * GMP_NUMB_BITS))
+ { /* then ulp(b) < precision < error */
+ return rnd2 == MPFR_RNDN && (mpfr_uexp_t) err0 - 2 >= prec;
+ /* can round only in rounding to the nearest and err0 >= prec + 2 */
+ }
+
+ MPFR_ASSERT_SIGN(neg);
+ neg = MPFR_IS_NEG_SIGN(neg);
+
+ /* if the error is smaller than ulp(b), then anyway it will propagate
+ up to ulp(b) */
+ err = ((mpfr_uexp_t) err0 > (mpfr_prec_t) bn * GMP_NUMB_BITS) ?
+ (mpfr_prec_t) bn * GMP_NUMB_BITS : (mpfr_prec_t) err0;
+
+ /* warning: if k = m*GMP_NUMB_BITS, consider limb m-1 and not m */
+ k = (err - 1) / GMP_NUMB_BITS;
+ MPFR_UNSIGNED_MINUS_MODULO(s, err);
+ /* the error corresponds to bit s in limb k, the most significant limb
+ being limb 0 */
+
+ k1 = (prec - 1) / GMP_NUMB_BITS;
+ MPFR_UNSIGNED_MINUS_MODULO(s1, prec);
+ /* the last significant bit is bit s1 in limb k1 */
+
+ /* don't need to consider the k1 most significant limbs */
+ k -= k1;
+ bn -= k1;
+ prec -= (mpfr_prec_t) k1 * GMP_NUMB_BITS;
+
+ /* if when adding or subtracting (1 << s) in bp[bn-1-k], it does not
+ change bp[bn-1] >> s1, then we can round */
+ MPFR_TMP_MARK(marker);
+ tn = bn;
+ k++; /* since we work with k+1 everywhere */
+ tmp = MPFR_TMP_LIMBS_ALLOC (tn);
+ if (bn > k)
+ MPN_COPY (tmp, bp, bn - k);
+
+ MPFR_ASSERTD (k > 0);
+
+ /* Transform RNDD and RNDU to Zero / Away */
+ MPFR_ASSERTD((neg == 0) || (neg ==1));
+ if (MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd1, neg))
+ rnd1 = MPFR_RNDZ;
+
+ switch (rnd1)
+ {
+ case MPFR_RNDZ:
+ /* Round to Zero */
+ cc = (bp[bn - 1] >> s1) & 1;
+ /* mpfr_round_raw2 returns 1 if one should add 1 at ulp(b,prec),
+ and 0 otherwise */
+ cc ^= mpfr_round_raw2 (bp, bn, neg, rnd2, prec);
+ /* cc is the new value of bit s1 in bp[bn-1] */
+ /* now round b + 2^(MPFR_EXP(b)-err) */
+ cc2 = mpn_add_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s);
+ break;
+ case MPFR_RNDN:
+ /* Round to nearest */
+ /* first round b+2^(MPFR_EXP(b)-err) */
+ cc = mpn_add_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s);
+ cc = (tmp[bn - 1] >> s1) & 1; /* gives 0 when cc=1 */
+ cc ^= mpfr_round_raw2 (tmp, bn, neg, rnd2, prec);
+ /* now round b-2^(MPFR_EXP(b)-err) */
+ cc2 = mpn_sub_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s);
+ break;
+ default:
+ /* Round away */
+ cc = (bp[bn - 1] >> s1) & 1;
+ cc ^= mpfr_round_raw2 (bp, bn, neg, rnd2, prec);
+ /* now round b +/- 2^(MPFR_EXP(b)-err) */
+ cc2 = mpn_sub_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s);
+ break;
+ }
+
+ /* if cc2 is 1, then a carry or borrow propagates to the next limb */
+ if (cc2 && cc)
+ {
+ MPFR_TMP_FREE(marker);
+ return 0;
+ }
+
+ cc2 = (tmp[bn - 1] >> s1) & 1;
+ cc2 ^= mpfr_round_raw2 (tmp, bn, neg, rnd2, prec);
+
+ MPFR_TMP_FREE(marker);
+ return cc == cc2;
+}
diff --git a/mpfr/src/round_raw_generic.c b/mpfr/src/round_raw_generic.c
new file mode 100644
index 0000000000..79ba90db8c
--- /dev/null
+++ b/mpfr/src/round_raw_generic.c
@@ -0,0 +1,259 @@
+/* mpfr_round_raw_generic -- Generic rounding function
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef flag
+# error "ERROR: flag must be defined (0 / 1)"
+#endif
+#ifndef use_inexp
+# error "ERROR: use_enexp must be defined (0 / 1)"
+#endif
+#ifndef mpfr_round_raw_generic
+# error "ERROR: mpfr_round_raw_generic must be defined"
+#endif
+
+/*
+ * If flag = 0, puts in y the value of xp (with precision xprec and
+ * sign 1 if negative=0, -1 otherwise) rounded to precision yprec and
+ * direction rnd_mode. Supposes x is not zero nor NaN nor +/- Infinity
+ * (i.e. *xp != 0). In that case, the return value is a possible carry
+ * (0 or 1) that may happen during the rounding, in which case the result
+ * is a power of two.
+ *
+ * If inexp != NULL, put in *inexp the inexact flag of the rounding (0, 1, -1).
+ * In case of even rounding when rnd = MPFR_RNDN, put MPFR_EVEN_INEX (2) or
+ * -MPFR_EVEN_INEX (-2) in *inexp.
+ *
+ * If flag = 1, just returns whether one should add 1 or not for rounding.
+ *
+ * Note: yprec may be < MPFR_PREC_MIN; in particular, it may be equal
+ * to 1. In this case, the even rounding is done away from 0, which is
+ * a natural generalization. Indeed, a number with 1-bit precision can
+ * be seen as a denormalized number with more precision.
+ */
+
+int
+mpfr_round_raw_generic(
+#if flag == 0
+ mp_limb_t *yp,
+#endif
+ const mp_limb_t *xp, mpfr_prec_t xprec,
+ int neg, mpfr_prec_t yprec, mpfr_rnd_t rnd_mode
+#if use_inexp != 0
+ , int *inexp
+#endif
+ )
+{
+ mp_size_t xsize, nw;
+ mp_limb_t himask, lomask, sb;
+ int rw;
+#if flag == 0
+ int carry;
+#endif
+#if use_inexp == 0
+ int *inexp;
+#endif
+
+ if (use_inexp)
+ MPFR_ASSERTD(inexp != ((int*) 0));
+ MPFR_ASSERTD(neg == 0 || neg == 1);
+
+ if (flag && !use_inexp &&
+ (xprec <= yprec || MPFR_IS_LIKE_RNDZ (rnd_mode, neg)))
+ return 0;
+
+ xsize = MPFR_PREC2LIMBS (xprec);
+ nw = yprec / GMP_NUMB_BITS;
+ rw = yprec & (GMP_NUMB_BITS - 1);
+
+ if (MPFR_UNLIKELY(xprec <= yprec))
+ { /* No rounding is necessary. */
+ /* if yp=xp, maybe an overlap: MPN_COPY_DECR is ok when src <= dst */
+ if (MPFR_LIKELY(rw))
+ nw++;
+ MPFR_ASSERTD(nw >= 1);
+ MPFR_ASSERTD(nw >= xsize);
+ if (use_inexp)
+ *inexp = 0;
+#if flag == 0
+ MPN_COPY_DECR(yp + (nw - xsize), xp, xsize);
+ MPN_ZERO(yp, nw - xsize);
+#endif
+ return 0;
+ }
+
+ if (use_inexp || !MPFR_IS_LIKE_RNDZ(rnd_mode, neg))
+ {
+ mp_size_t k = xsize - nw - 1;
+
+ if (MPFR_LIKELY(rw))
+ {
+ nw++;
+ lomask = MPFR_LIMB_MASK (GMP_NUMB_BITS - rw);
+ himask = ~lomask;
+ }
+ else
+ {
+ lomask = ~(mp_limb_t) 0;
+ himask = ~(mp_limb_t) 0;
+ }
+ MPFR_ASSERTD(k >= 0);
+ sb = xp[k] & lomask; /* First non-significant bits */
+ /* Rounding to nearest ? */
+ if (MPFR_LIKELY( rnd_mode == MPFR_RNDN) )
+ {
+ /* Rounding to nearest */
+ mp_limb_t rbmask = MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1 - rw);
+ if (sb & rbmask) /* rounding bit */
+ sb &= ~rbmask; /* it is 1, clear it */
+ else
+ {
+ /* Rounding bit is 0, behave like rounding to 0 */
+ goto rnd_RNDZ;
+ }
+ while (MPFR_UNLIKELY(sb == 0) && k > 0)
+ sb = xp[--k];
+ /* rounding to nearest, with rounding bit = 1 */
+ if (MPFR_UNLIKELY(sb == 0)) /* Even rounding. */
+ {
+ /* sb == 0 && rnd_mode == MPFR_RNDN */
+ sb = xp[xsize - nw] & (himask ^ (himask << 1));
+ if (sb == 0)
+ {
+ if (use_inexp)
+ *inexp = 2*MPFR_EVEN_INEX*neg-MPFR_EVEN_INEX;
+ /* ((neg!=0)^(sb!=0)) ? MPFR_EVEN_INEX : -MPFR_EVEN_INEX;*/
+ /* Since neg = 0 or 1 and sb=0*/
+#if flag == 1
+ return 0 /*sb != 0 && rnd_mode != MPFR_RNDZ */;
+#else
+ MPN_COPY_INCR(yp, xp + xsize - nw, nw);
+ yp[0] &= himask;
+ return 0;
+#endif
+ }
+ else
+ {
+ /* sb != 0 && rnd_mode == MPFR_RNDN */
+ if (use_inexp)
+ *inexp = MPFR_EVEN_INEX-2*MPFR_EVEN_INEX*neg;
+ /*((neg!=0)^(sb!=0))? MPFR_EVEN_INEX : -MPFR_EVEN_INEX; */
+ /*Since neg= 0 or 1 and sb != 0 */
+ goto rnd_RNDN_add_one_ulp;
+ }
+ }
+ else /* sb != 0 && rnd_mode == MPFR_RNDN*/
+ {
+ if (use_inexp)
+ /* *inexp = (neg == 0) ? 1 : -1; but since neg = 0 or 1 */
+ *inexp = 1-2*neg;
+ rnd_RNDN_add_one_ulp:
+#if flag == 1
+ return 1; /*sb != 0 && rnd_mode != MPFR_RNDZ;*/
+#else
+ carry = mpn_add_1 (yp, xp + xsize - nw, nw,
+ rw ?
+ MPFR_LIMB_ONE << (GMP_NUMB_BITS - rw)
+ : MPFR_LIMB_ONE);
+ yp[0] &= himask;
+ return carry;
+#endif
+ }
+ }
+ /* Rounding to Zero ? */
+ else if (MPFR_IS_LIKE_RNDZ(rnd_mode, neg))
+ {
+ /* rnd_mode == MPFR_RNDZ */
+ rnd_RNDZ:
+ while (MPFR_UNLIKELY(sb == 0) && k > 0)
+ sb = xp[--k];
+ if (use_inexp)
+ /* rnd_mode == MPFR_RNDZ and neg = 0 or 1 */
+ /* (neg != 0) ^ (rnd_mode != MPFR_RNDZ)) ? 1 : -1);*/
+ *inexp = MPFR_UNLIKELY(sb == 0) ? 0 : (2*neg-1);
+#if flag == 1
+ return 0; /*sb != 0 && rnd_mode != MPFR_RNDZ;*/
+#else
+ MPN_COPY_INCR(yp, xp + xsize - nw, nw);
+ yp[0] &= himask;
+ return 0;
+#endif
+ }
+ else
+ {
+ /* rnd_mode = Away */
+ while (MPFR_UNLIKELY(sb == 0) && k > 0)
+ sb = xp[--k];
+ if (MPFR_UNLIKELY(sb == 0))
+ {
+ /* sb = 0 && rnd_mode != MPFR_RNDZ */
+ if (use_inexp)
+ /* (neg != 0) ^ (rnd_mode != MPFR_RNDZ)) ? 1 : -1);*/
+ *inexp = 0;
+#if flag == 1
+ return 0;
+#else
+ MPN_COPY_INCR(yp, xp + xsize - nw, nw);
+ yp[0] &= himask;
+ return 0;
+#endif
+ }
+ else
+ {
+ /* sb != 0 && rnd_mode != MPFR_RNDZ */
+ if (use_inexp)
+ /* (neg != 0) ^ (rnd_mode != MPFR_RNDZ)) ? 1 : -1);*/
+ *inexp = 1-2*neg;
+#if flag == 1
+ return 1;
+#else
+ carry = mpn_add_1(yp, xp + xsize - nw, nw,
+ rw ? MPFR_LIMB_ONE << (GMP_NUMB_BITS - rw)
+ : 1);
+ yp[0] &= himask;
+ return carry;
+#endif
+ }
+ }
+ }
+ else
+ {
+ /* Roundind mode = Zero / No inexact flag */
+#if flag == 1
+ return 0 /*sb != 0 && rnd_mode != MPFR_RNDZ*/;
+#else
+ if (MPFR_LIKELY(rw))
+ {
+ nw++;
+ himask = ~MPFR_LIMB_MASK (GMP_NUMB_BITS - rw);
+ }
+ else
+ himask = ~(mp_limb_t) 0;
+ MPN_COPY_INCR(yp, xp + xsize - nw, nw);
+ yp[0] &= himask;
+ return 0;
+#endif
+ }
+}
+
+#undef flag
+#undef use_inexp
+#undef mpfr_round_raw_generic
diff --git a/mpfr/src/scale2.c b/mpfr/src/scale2.c
new file mode 100644
index 0000000000..5de38c32cc
--- /dev/null
+++ b/mpfr/src/scale2.c
@@ -0,0 +1,91 @@
+/* mpfr_scale2 -- multiply a double float by 2^exp
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <float.h> /* for DBL_EPSILON */
+#include "mpfr-impl.h"
+
+/* Note: we could use the ldexp function, but since we want not to depend on
+ math.h, we write our own implementation. */
+
+/* multiplies 1/2 <= d <= 1 by 2^exp */
+double
+mpfr_scale2 (double d, int exp)
+{
+#if _GMP_IEEE_FLOATS
+ {
+ union ieee_double_extract x;
+
+ if (MPFR_UNLIKELY (d == 1.0))
+ {
+ d = 0.5;
+ exp ++;
+ }
+
+ /* now 1/2 <= d < 1 */
+
+ /* infinities and zeroes have already been checked */
+ MPFR_ASSERTD (-1073 <= exp && exp <= 1025);
+
+ x.d = d;
+ if (MPFR_UNLIKELY (exp < -1021)) /* subnormal case */
+ {
+ x.s.exp += exp + 52;
+ x.d *= DBL_EPSILON;
+ }
+ else /* normalized case */
+ {
+ x.s.exp += exp;
+ }
+ return x.d;
+ }
+#else /* _GMP_IEEE_FLOATS */
+ {
+ double factor;
+
+ /* An overflow may occurs (example: 0.5*2^1024) */
+ if (d < 1.0)
+ {
+ d += d;
+ exp--;
+ }
+ /* Now 1.0 <= d < 2.0 */
+
+ if (exp < 0)
+ {
+ factor = 0.5;
+ exp = -exp;
+ }
+ else
+ {
+ factor = 2.0;
+ }
+ while (exp != 0)
+ {
+ if ((exp & 1) != 0)
+ d *= factor;
+ exp >>= 1;
+ factor *= factor;
+ }
+ return d;
+ }
+#endif
+}
diff --git a/mpfr/src/sec.c b/mpfr/src/sec.c
new file mode 100644
index 0000000000..c5ced391da
--- /dev/null
+++ b/mpfr/src/sec.c
@@ -0,0 +1,34 @@
+/* mpfr_sec - secant function = 1/cos.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define FUNCTION mpfr_sec
+#define INVERSE mpfr_cos
+#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_INF(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_ZERO(y,x) return mpfr_set_ui (y, 1, rnd_mode)
+/* for x near 0, sec(x) = 1 + x^2/2 + ..., more precisely |sec(x)-1| < x^2
+ for |x| <= 1. */
+#define ACTION_TINY(y,x,r) \
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT(y, __gmpfr_one, -2 * MPFR_GET_EXP (x), 0, \
+ 1, r, inexact = _inexact; goto end)
+
+#include "gen_inverse.h"
diff --git a/mpfr/src/sech.c b/mpfr/src/sech.c
new file mode 100644
index 0000000000..6e37a9a280
--- /dev/null
+++ b/mpfr/src/sech.c
@@ -0,0 +1,40 @@
+/* mpfr_sech - Hyperbolic secant function = 1/cosh.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* The hyperbolic secant function is defined by sech(x)=1/cosh(x):
+ csc (NaN) = NaN.
+ csc (+Inf) = csc (-Inf) = 0+.
+ csc (+0) = csc (-0) = 1.
+ */
+
+#define FUNCTION mpfr_sech
+#define INVERSE mpfr_cosh
+#define ACTION_NAN(y) do { MPFR_SET_NAN(y); MPFR_RET_NAN; } while (1)
+#define ACTION_INF(y) return mpfr_set_ui (y, 0, MPFR_RNDN)
+#define ACTION_ZERO(y,x) return mpfr_set_ui (y, 1, rnd_mode)
+/* for x near 0, sech(x) = 1 - x^2/2 + ..., more precisely |sech(x)-1| <= x^2/2
+ for |x| <= 1. The tiny action is the same as for cos(x). */
+#define ACTION_TINY(y,x,r) \
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT(y, __gmpfr_one, -2 * MPFR_GET_EXP (x), 1, \
+ 0, r, inexact = _inexact; goto end)
+
+#include "gen_inverse.h"
diff --git a/mpfr/src/set.c b/mpfr/src/set.c
new file mode 100644
index 0000000000..1561aa27a2
--- /dev/null
+++ b/mpfr/src/set.c
@@ -0,0 +1,80 @@
+/* mpfr_set -- copy of a floating-point number
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* set a to abs(b) * signb: a=b when signb = SIGN(b), a=abs(b) when signb=1 */
+int
+mpfr_set4 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode, int signb)
+{
+ /* Sign is ALWAYS copied */
+ MPFR_SET_SIGN (a, signb);
+
+ /* Exponent is also always copied since if the number is singular,
+ the exponent field determined the number.
+ Can't use MPFR_SET_EXP since the exponent may be singular */
+ MPFR_EXP (a) = MPFR_EXP (b);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (b)))
+ {
+ /* MPFR_SET_NAN, MPFR_SET_ZERO and MPFR_SET_INF are useless
+ since MPFR_EXP (a) = MPFR_EXP (b) does the job */
+ if (MPFR_IS_NAN (b))
+ MPFR_RET_NAN;
+ else
+ MPFR_RET (0);
+ }
+ else if (MPFR_LIKELY (MPFR_PREC (b) == MPFR_PREC (a)))
+ {
+ /* Same precision and b is not singular:
+ * just copy the mantissa, and set the exponent and the sign
+ * The result is exact. */
+ MPN_COPY (MPFR_MANT (a), MPFR_MANT (b), MPFR_LIMB_SIZE (b));
+ MPFR_RET (0);
+ }
+ else
+ {
+ int inex;
+
+ /* Else Round B inside a */
+ MPFR_RNDRAW (inex, a, MPFR_MANT (b), MPFR_PREC (b), rnd_mode, signb,
+ if (MPFR_UNLIKELY ( ++MPFR_EXP (a) > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, signb) );
+ MPFR_RET (inex);
+ }
+}
+
+/* Set a to b */
+#undef mpfr_set
+int
+mpfr_set (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_set4 (a, b, rnd_mode, MPFR_SIGN (b));
+}
+
+/* Set a to |b| */
+#undef mpfr_abs
+int
+mpfr_abs (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_set4 (a, b, rnd_mode, MPFR_SIGN_POS);
+}
diff --git a/mpfr/src/set_d.c b/mpfr/src/set_d.c
new file mode 100644
index 0000000000..479167b0e1
--- /dev/null
+++ b/mpfr/src/set_d.c
@@ -0,0 +1,255 @@
+/* mpfr_set_d -- convert a machine double precision float to
+ a multiple precision floating-point number
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <float.h> /* For DOUBLE_ISINF and DOUBLE_ISNAN */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* extracts the bits of d in rp[0..n-1] where n=ceil(53/GMP_NUMB_BITS).
+ Assumes d is neither 0 nor NaN nor Inf. */
+static long
+__gmpfr_extract_double (mpfr_limb_ptr rp, double d)
+ /* e=0 iff GMP_NUMB_BITS=32 and rp has only one limb */
+{
+ long exp;
+ mp_limb_t manl;
+#if GMP_NUMB_BITS == 32
+ mp_limb_t manh;
+#endif
+
+ /* BUGS
+ 1. Should handle Inf and NaN in IEEE specific code.
+ 2. Handle Inf and NaN also in default code, to avoid hangs.
+ 3. Generalize to handle all GMP_NUMB_BITS.
+ 4. This lits is incomplete and misspelled.
+ */
+
+ MPFR_ASSERTD(!DOUBLE_ISNAN(d));
+ MPFR_ASSERTD(!DOUBLE_ISINF(d));
+ MPFR_ASSERTD(d != 0.0);
+
+#if _GMP_IEEE_FLOATS
+
+ {
+ union ieee_double_extract x;
+ x.d = d;
+
+ exp = x.s.exp;
+ if (exp)
+ {
+#if GMP_NUMB_BITS >= 64
+ manl = ((MPFR_LIMB_ONE << 63)
+ | ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11));
+#else
+ manh = (MPFR_LIMB_ONE << 31) | (x.s.manh << 11) | (x.s.manl >> 21);
+ manl = x.s.manl << 11;
+#endif
+ }
+ else /* denormalized number */
+ {
+#if GMP_NUMB_BITS >= 64
+ manl = ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11);
+#else
+ manh = (x.s.manh << 11) /* high 21 bits */
+ | (x.s.manl >> 21); /* middle 11 bits */
+ manl = x.s.manl << 11; /* low 21 bits */
+#endif
+ }
+
+ if (exp)
+ exp -= 1022;
+ else
+ exp = -1021;
+ }
+
+#else /* _GMP_IEEE_FLOATS */
+
+ {
+ /* Unknown (or known to be non-IEEE) double format. */
+ exp = 0;
+ if (d >= 1.0)
+ {
+ MPFR_ASSERTN (d * 0.5 != d);
+ while (d >= 32768.0)
+ {
+ d *= (1.0 / 65536.0);
+ exp += 16;
+ }
+ while (d >= 1.0)
+ {
+ d *= 0.5;
+ exp += 1;
+ }
+ }
+ else if (d < 0.5)
+ {
+ while (d < (1.0 / 65536.0))
+ {
+ d *= 65536.0;
+ exp -= 16;
+ }
+ while (d < 0.5)
+ {
+ d *= 2.0;
+ exp -= 1;
+ }
+ }
+
+ d *= MP_BASE_AS_DOUBLE;
+#if GMP_NUMB_BITS >= 64
+ manl = d;
+#else
+ manh = (mp_limb_t) d;
+ manl = (mp_limb_t) ((d - manh) * MP_BASE_AS_DOUBLE);
+#endif
+ }
+
+#endif /* _GMP_IEEE_FLOATS */
+
+#if GMP_NUMB_BITS >= 64
+ rp[0] = manl;
+#else
+ rp[1] = manh;
+ rp[0] = manl;
+#endif
+
+ return exp;
+}
+
+/* End of part included from gmp-2.0.2 */
+
+int
+mpfr_set_d (mpfr_ptr r, double d, mpfr_rnd_t rnd_mode)
+{
+ int signd, inexact;
+ unsigned int cnt;
+ mp_size_t i, k;
+ mpfr_t tmp;
+ mp_limb_t tmpmant[MPFR_LIMBS_PER_DOUBLE];
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ if (MPFR_UNLIKELY(DOUBLE_ISNAN(d)))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_UNLIKELY(d == 0))
+ {
+#if _GMP_IEEE_FLOATS
+ union ieee_double_extract x;
+
+ MPFR_SET_ZERO(r);
+ /* set correct sign */
+ x.d = d;
+ if (x.s.sig == 1)
+ MPFR_SET_NEG(r);
+ else
+ MPFR_SET_POS(r);
+#else /* _GMP_IEEE_FLOATS */
+ MPFR_SET_ZERO(r);
+ {
+ /* This is to get the sign of zero on non-IEEE hardware
+ Some systems support +0.0, -0.0 and unsigned zero.
+ We can't use d==+0.0 since it should be always true,
+ so we check that the memory representation of d is the
+ same than +0.0. etc */
+ /* FIXME: consider the case where +0.0 or -0.0 may have several
+ representations. */
+ double poszero = +0.0, negzero = DBL_NEG_ZERO;
+ if (memcmp(&d, &poszero, sizeof(double)) == 0)
+ MPFR_SET_POS(r);
+ else if (memcmp(&d, &negzero, sizeof(double)) == 0)
+ MPFR_SET_NEG(r);
+ else
+ MPFR_SET_POS(r);
+ }
+#endif
+ return 0; /* 0 is exact */
+ }
+ else if (MPFR_UNLIKELY(DOUBLE_ISINF(d)))
+ {
+ MPFR_SET_INF(r);
+ if (d > 0)
+ MPFR_SET_POS(r);
+ else
+ MPFR_SET_NEG(r);
+ return 0; /* infinity is exact */
+ }
+
+ /* now d is neither 0, nor NaN nor Inf */
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* warning: don't use tmp=r here, even if SIZE(r) >= MPFR_LIMBS_PER_DOUBLE,
+ since PREC(r) may be different from PREC(tmp), and then both variables
+ would have same precision in the mpfr_set4 call below. */
+ MPFR_MANT(tmp) = tmpmant;
+ MPFR_PREC(tmp) = IEEE_DBL_MANT_DIG;
+
+ signd = (d < 0) ? MPFR_SIGN_NEG : MPFR_SIGN_POS;
+ d = ABS (d);
+
+ /* don't use MPFR_SET_EXP here since the exponent may be out of range */
+ MPFR_EXP(tmp) = __gmpfr_extract_double (tmpmant, d);
+
+#ifdef WANT_ASSERT
+ /* Failed assertion if the stored value is 0 (e.g., if the exponent range
+ has been reduced at the wrong moment and an underflow to 0 occurred).
+ Probably a bug in the C implementation if this happens. */
+ i = 0;
+ while (tmpmant[i] == 0)
+ {
+ i++;
+ MPFR_ASSERTN(i < MPFR_LIMBS_PER_DOUBLE);
+ }
+#endif
+
+ /* determine the index i-1 of the most significant non-zero limb
+ and the number k of zero high limbs */
+ i = MPFR_LIMBS_PER_DOUBLE;
+ MPN_NORMALIZE_NOT_ZERO(tmpmant, i);
+ k = MPFR_LIMBS_PER_DOUBLE - i;
+
+ count_leading_zeros (cnt, tmpmant[i - 1]);
+
+ if (MPFR_LIKELY(cnt != 0))
+ mpn_lshift (tmpmant + k, tmpmant, i, cnt);
+ else if (k != 0)
+ MPN_COPY (tmpmant + k, tmpmant, i);
+
+ if (MPFR_UNLIKELY(k != 0))
+ MPN_ZERO (tmpmant, k);
+
+ /* don't use MPFR_SET_EXP here since the exponent may be out of range */
+ MPFR_EXP(tmp) -= (mpfr_exp_t) (cnt + k * GMP_NUMB_BITS);
+
+ /* tmp is exact since PREC(tmp)=53 */
+ inexact = mpfr_set4 (r, tmp, rnd_mode, signd);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inexact, rnd_mode);
+}
+
+
+
diff --git a/mpfr/src/set_d64.c b/mpfr/src/set_d64.c
new file mode 100644
index 0000000000..d950acfa79
--- /dev/null
+++ b/mpfr/src/set_d64.c
@@ -0,0 +1,224 @@
+/* mpfr_set_decimal64 -- convert a IEEE 754r decimal64 float to
+ a multiple precision floating-point number
+
+See http://gcc.gnu.org/ml/gcc/2006-06/msg00691.html,
+http://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html,
+and TR 24732 <http://www.open-std.org/jtc1/sc22/wg14/www/projects#24732>.
+
+Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#ifdef MPFR_WANT_DECIMAL_FLOATS
+
+#ifdef DPD_FORMAT
+ /* conversion 10-bits to 3 digits */
+static unsigned int T[1024] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 80, 81, 800, 801, 880, 881, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 90, 91, 810, 811, 890, 891, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 82, 83, 820, 821, 808, 809, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 92, 93, 830, 831, 818, 819, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 84, 85, 840, 841, 88, 89, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 94, 95,
+ 850, 851, 98, 99, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 86, 87, 860, 861,
+ 888, 889, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 96, 97, 870, 871, 898,
+ 899, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 180, 181, 900, 901,
+ 980, 981, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 190, 191, 910,
+ 911, 990, 991, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 182, 183,
+ 920, 921, 908, 909, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 192,
+ 193, 930, 931, 918, 919, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 184, 185, 940, 941, 188, 189, 150, 151, 152, 153, 154, 155, 156, 157, 158,
+ 159, 194, 195, 950, 951, 198, 199, 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 186, 187, 960, 961, 988, 989, 170, 171, 172, 173, 174, 175, 176,
+ 177, 178, 179, 196, 197, 970, 971, 998, 999, 200, 201, 202, 203, 204, 205,
+ 206, 207, 208, 209, 280, 281, 802, 803, 882, 883, 210, 211, 212, 213, 214,
+ 215, 216, 217, 218, 219, 290, 291, 812, 813, 892, 893, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 282, 283, 822, 823, 828, 829, 230, 231, 232,
+ 233, 234, 235, 236, 237, 238, 239, 292, 293, 832, 833, 838, 839, 240, 241,
+ 242, 243, 244, 245, 246, 247, 248, 249, 284, 285, 842, 843, 288, 289, 250,
+ 251, 252, 253, 254, 255, 256, 257, 258, 259, 294, 295, 852, 853, 298, 299,
+ 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 286, 287, 862, 863, 888,
+ 889, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 296, 297, 872, 873,
+ 898, 899, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 380, 381, 902,
+ 903, 982, 983, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 390, 391,
+ 912, 913, 992, 993, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 382,
+ 383, 922, 923, 928, 929, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339,
+ 392, 393, 932, 933, 938, 939, 340, 341, 342, 343, 344, 345, 346, 347, 348,
+ 349, 384, 385, 942, 943, 388, 389, 350, 351, 352, 353, 354, 355, 356, 357,
+ 358, 359, 394, 395, 952, 953, 398, 399, 360, 361, 362, 363, 364, 365, 366,
+ 367, 368, 369, 386, 387, 962, 963, 988, 989, 370, 371, 372, 373, 374, 375,
+ 376, 377, 378, 379, 396, 397, 972, 973, 998, 999, 400, 401, 402, 403, 404,
+ 405, 406, 407, 408, 409, 480, 481, 804, 805, 884, 885, 410, 411, 412, 413,
+ 414, 415, 416, 417, 418, 419, 490, 491, 814, 815, 894, 895, 420, 421, 422,
+ 423, 424, 425, 426, 427, 428, 429, 482, 483, 824, 825, 848, 849, 430, 431,
+ 432, 433, 434, 435, 436, 437, 438, 439, 492, 493, 834, 835, 858, 859, 440,
+ 441, 442, 443, 444, 445, 446, 447, 448, 449, 484, 485, 844, 845, 488, 489,
+ 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 494, 495, 854, 855, 498,
+ 499, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 486, 487, 864, 865,
+ 888, 889, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 496, 497, 874,
+ 875, 898, 899, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 580, 581,
+ 904, 905, 984, 985, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 590,
+ 591, 914, 915, 994, 995, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529,
+ 582, 583, 924, 925, 948, 949, 530, 531, 532, 533, 534, 535, 536, 537, 538,
+ 539, 592, 593, 934, 935, 958, 959, 540, 541, 542, 543, 544, 545, 546, 547,
+ 548, 549, 584, 585, 944, 945, 588, 589, 550, 551, 552, 553, 554, 555, 556,
+ 557, 558, 559, 594, 595, 954, 955, 598, 599, 560, 561, 562, 563, 564, 565,
+ 566, 567, 568, 569, 586, 587, 964, 965, 988, 989, 570, 571, 572, 573, 574,
+ 575, 576, 577, 578, 579, 596, 597, 974, 975, 998, 999, 600, 601, 602, 603,
+ 604, 605, 606, 607, 608, 609, 680, 681, 806, 807, 886, 887, 610, 611, 612,
+ 613, 614, 615, 616, 617, 618, 619, 690, 691, 816, 817, 896, 897, 620, 621,
+ 622, 623, 624, 625, 626, 627, 628, 629, 682, 683, 826, 827, 868, 869, 630,
+ 631, 632, 633, 634, 635, 636, 637, 638, 639, 692, 693, 836, 837, 878, 879,
+ 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 684, 685, 846, 847, 688,
+ 689, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 694, 695, 856, 857,
+ 698, 699, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 686, 687, 866,
+ 867, 888, 889, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 696, 697,
+ 876, 877, 898, 899, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 780,
+ 781, 906, 907, 986, 987, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719,
+ 790, 791, 916, 917, 996, 997, 720, 721, 722, 723, 724, 725, 726, 727, 728,
+ 729, 782, 783, 926, 927, 968, 969, 730, 731, 732, 733, 734, 735, 736, 737,
+ 738, 739, 792, 793, 936, 937, 978, 979, 740, 741, 742, 743, 744, 745, 746,
+ 747, 748, 749, 784, 785, 946, 947, 788, 789, 750, 751, 752, 753, 754, 755,
+ 756, 757, 758, 759, 794, 795, 956, 957, 798, 799, 760, 761, 762, 763, 764,
+ 765, 766, 767, 768, 769, 786, 787, 966, 967, 988, 989, 770, 771, 772, 773,
+ 774, 775, 776, 777, 778, 779, 796, 797, 976, 977, 998, 999 };
+#endif
+
+/* Convert d to a decimal string (one-to-one correspondence, no rounding).
+ The string s needs to have at least 23 characters.
+ */
+static void
+decimal64_to_string (char *s, _Decimal64 d)
+{
+ union ieee_double_extract x;
+ union ieee_double_decimal64 y;
+ char *t;
+ unsigned int Gh; /* most 5 significant bits from combination field */
+ int exp; /* exponent */
+ mp_limb_t rp[2];
+ mp_size_t rn = 2;
+ unsigned int i;
+#ifdef DPD_FORMAT
+ unsigned int d0, d1, d2, d3, d4, d5;
+#endif
+
+ /* now convert BID or DPD to string */
+ y.d64 = d;
+ x.d = y.d;
+ Gh = x.s.exp >> 6;
+ if (Gh == 31)
+ {
+ sprintf (s, "NaN");
+ return;
+ }
+ else if (Gh == 30)
+ {
+ if (x.s.sig == 0)
+ sprintf (s, "Inf");
+ else
+ sprintf (s, "-Inf");
+ return;
+ }
+ t = s;
+ if (x.s.sig)
+ *t++ = '-';
+
+#ifdef DPD_FORMAT
+ if (Gh < 24)
+ {
+ exp = (x.s.exp >> 1) & 768;
+ d0 = Gh & 7;
+ }
+ else
+ {
+ exp = (x.s.exp & 384) << 1;
+ d0 = 8 | (Gh & 1);
+ }
+ exp |= (x.s.exp & 63) << 2;
+ exp |= x.s.manh >> 18;
+ d1 = (x.s.manh >> 8) & 1023;
+ d2 = ((x.s.manh << 2) | (x.s.manl >> 30)) & 1023;
+ d3 = (x.s.manl >> 20) & 1023;
+ d4 = (x.s.manl >> 10) & 1023;
+ d5 = x.s.manl & 1023;
+ sprintf (t, "%1u%3u%3u%3u%3u%3u", d0, T[d1], T[d2], T[d3], T[d4], T[d5]);
+ /* Warning: some characters may be blank */
+ for (i = 0; i < 16; i++)
+ if (t[i] == ' ')
+ t[i] = '0';
+ t += 16;
+#else /* BID */
+ if (Gh < 24)
+ {
+ /* the biased exponent E is formed from G[0] to G[9] and the
+ significand from bits G[10] through the end of the decoding */
+ exp = x.s.exp >> 1;
+ /* manh has 20 bits, manl has 32 bits */
+ rp[1] = ((x.s.exp & 1) << 20) | x.s.manh;
+ rp[0] = x.s.manl;
+ }
+ else
+ {
+ /* the biased exponent is formed from G[2] to G[11] */
+ exp = (x.s.exp & 511) << 1;
+ rp[1] = x.s.manh;
+ rp[0] = x.s.manl;
+ exp |= rp[1] >> 19;
+ rp[1] &= 524287; /* 2^19-1: cancel G[11] */
+ rp[1] |= 2097152; /* add 2^21 */
+ }
+#if GMP_NUMB_BITS >= 54
+ rp[0] |= rp[1] << 32;
+ rn = 1;
+#endif
+ while (rn > 0 && rp[rn - 1] == 0)
+ rn --;
+ if (rn == 0)
+ {
+ *t = 0;
+ i = 1;
+ }
+ else
+ {
+ i = mpn_get_str ((unsigned char*)t, 10, rp, rn);
+ }
+ while (i-- > 0)
+ *t++ += '0';
+#endif /* DPD or BID */
+
+ exp -= 398; /* unbiased exponent */
+ t += sprintf (t, "E%d", exp);
+}
+
+int
+mpfr_set_decimal64 (mpfr_ptr r, _Decimal64 d, mpfr_rnd_t rnd_mode)
+{
+ char s[23]; /* need 1 character for sign,
+ 16 characters for mantissa,
+ 1 character for exponent,
+ 4 characters for exponent (including sign),
+ 1 character for terminating \0. */
+
+ decimal64_to_string (s, d);
+ return mpfr_set_str (r, s, 10, rnd_mode);
+}
+
+#endif /* MPFR_WANT_DECIMAL_FLOATS */
diff --git a/mpfr/src/set_dfl_prec.c b/mpfr/src/set_dfl_prec.c
new file mode 100644
index 0000000000..f2bbf321a6
--- /dev/null
+++ b/mpfr/src/set_dfl_prec.c
@@ -0,0 +1,41 @@
+/* mpfr_set_default_prec, mpfr_get_default_prec -- set/get default precision
+
+Copyright 1999, 2000, 2001, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* default is IEEE double precision, i.e. 53 bits */
+mpfr_prec_t MPFR_THREAD_ATTR __gmpfr_default_fp_bit_precision \
+ = IEEE_DBL_MANT_DIG;
+
+void
+mpfr_set_default_prec (mpfr_prec_t prec)
+{
+ MPFR_ASSERTN (prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX);
+ __gmpfr_default_fp_bit_precision = prec;
+}
+
+#undef mpfr_get_default_prec
+mpfr_prec_t
+mpfr_get_default_prec (void)
+{
+ return __gmpfr_default_fp_bit_precision;
+}
diff --git a/mpfr/src/set_exp.c b/mpfr/src/set_exp.c
new file mode 100644
index 0000000000..e2d01da1cc
--- /dev/null
+++ b/mpfr/src/set_exp.c
@@ -0,0 +1,37 @@
+/* mpfr_set_exp - set the exponent of a floating-point number
+
+Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_set_exp (mpfr_ptr x, mpfr_exp_t exponent)
+{
+ if (exponent >= __gmpfr_emin && exponent <= __gmpfr_emax)
+ {
+ MPFR_EXP(x) = exponent; /* do not use MPFR_SET_EXP of course... */
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
diff --git a/mpfr/src/set_f.c b/mpfr/src/set_f.c
new file mode 100644
index 0000000000..80f776b8cd
--- /dev/null
+++ b/mpfr/src/set_f.c
@@ -0,0 +1,99 @@
+/* mpfr_set_f -- set a MPFR number from a GNU MPF number
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mp_limb_t *my, *mx, *tmp;
+ unsigned long cnt, sx, sy;
+ int inexact, carry = 0;
+ MPFR_TMP_DECL(marker);
+
+ sx = ABS(SIZ(x)); /* number of limbs of the mantissa of x */
+
+ if (sx == 0) /* x is zero */
+ {
+ MPFR_SET_ZERO(y);
+ MPFR_SET_POS(y);
+ return 0; /* 0 is exact */
+ }
+
+ if (SIZ(x) * MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(y)) < 0)
+ MPFR_CHANGE_SIGN (y);
+
+ sy = MPFR_LIMB_SIZE (y);
+ my = MPFR_MANT(y);
+ mx = PTR(x);
+
+ count_leading_zeros(cnt, mx[sx - 1]);
+
+ if (sy <= sx) /* we may have to round even when sy = sx */
+ {
+ unsigned long xprec = sx * GMP_NUMB_BITS;
+
+ MPFR_TMP_MARK(marker);
+ tmp = MPFR_TMP_LIMBS_ALLOC (sx);
+ if (cnt)
+ mpn_lshift (tmp, mx, sx, cnt);
+ else
+ /* FIXME: we may avoid the copy here, and directly call mpfr_round_raw
+ on mx instead of tmp */
+ MPN_COPY (tmp, mx, sx);
+ carry = mpfr_round_raw (my, tmp, xprec, (SIZ(x) < 0), MPFR_PREC(y),
+ rnd_mode, &inexact);
+ if (MPFR_UNLIKELY(carry)) /* result is a power of two */
+ my[sy - 1] = MPFR_LIMB_HIGHBIT;
+ MPFR_TMP_FREE(marker);
+ }
+ else
+ {
+ if (cnt)
+ mpn_lshift (my + sy - sx, mx, sx, cnt);
+ else
+ MPN_COPY (my + sy - sx, mx, sx);
+ MPN_ZERO(my, sy - sx);
+ /* no rounding necessary, since y has a larger mantissa */
+ inexact = 0;
+ }
+
+ /* warning: EXP(x) * GMP_NUMB_BITS may exceed the maximal exponent */
+ if (EXP(x) > 1 + (__gmpfr_emax - 1) / GMP_NUMB_BITS)
+ {
+ /* EXP(x) >= 2 + floor((__gmpfr_emax-1)/GMP_NUMB_BITS)
+ EXP(x) >= 2 + (__gmpfr_emax - GMP_NUMB_BITS) / GMP_NUMB_BITS
+ >= 1 + __gmpfr_emax / GMP_NUMB_BITS
+ EXP(x) * GMP_NUMB_BITS >= __gmpfr_emax + GMP_NUMB_BITS
+ Since 0 <= cnt <= GMP_NUMB_BITS-1, and 0 <= carry <= 1,
+ we have then EXP(x) * GMP_NUMB_BITS - cnt + carry > __gmpfr_emax */
+ return mpfr_overflow (y, rnd_mode, MPFR_SIGN (y));
+ }
+ else
+ {
+ /* Do not use MPFR_SET_EXP as the exponent may be out of range. */
+ MPFR_EXP (y) = EXP (x) * GMP_NUMB_BITS - (mpfr_exp_t) cnt + carry;
+ }
+
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/set_flt.c b/mpfr/src/set_flt.c
new file mode 100644
index 0000000000..46677b3835
--- /dev/null
+++ b/mpfr/src/set_flt.c
@@ -0,0 +1,34 @@
+/* mpfr_set_flt -- convert a machine single precision float to mpfr_t
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_set_flt (mpfr_ptr r, float f, mpfr_rnd_t rnd_mode)
+{
+ /* we convert f to double precision and use mpfr_set_d;
+ NaN and infinities should be preserved, and all single precision
+ numbers are exactly representable in the double format, thus the
+ conversion is always exact */
+ return mpfr_set_d (r, (double) f, rnd_mode);
+}
+
diff --git a/mpfr/src/set_inf.c b/mpfr/src/set_inf.c
new file mode 100644
index 0000000000..c7daefb1e4
--- /dev/null
+++ b/mpfr/src/set_inf.c
@@ -0,0 +1,33 @@
+/* mpfr_set_inf -- set a number to plus or minus infinity.
+
+Copyright 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_set_inf (mpfr_ptr x, int sign)
+{
+ MPFR_SET_INF(x);
+ if (sign >= 0)
+ MPFR_SET_POS(x);
+ else
+ MPFR_SET_NEG(x);
+}
diff --git a/mpfr/src/set_ld.c b/mpfr/src/set_ld.c
new file mode 100644
index 0000000000..6a3bd04140
--- /dev/null
+++ b/mpfr/src/set_ld.c
@@ -0,0 +1,331 @@
+/* mpfr_set_ld -- convert a machine long double to
+ a multiple precision floating-point number
+
+Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <float.h>
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Various i386 systems have been seen with <float.h> LDBL constants equal
+ to the DBL ones, whereas they ought to be bigger, reflecting the 10-byte
+ IEEE extended format on that processor. gcc 3.2.1 on FreeBSD and Solaris
+ has been seen with the problem, and gcc 2.95.4 on FreeBSD 4.7. */
+
+#if HAVE_LDOUBLE_IEEE_EXT_LITTLE
+static const union {
+ char bytes[10];
+ long double d;
+} ldbl_max_struct = {
+ { '\377','\377','\377','\377',
+ '\377','\377','\377','\377',
+ '\376','\177' }
+};
+#define MPFR_LDBL_MAX (ldbl_max_struct.d)
+#else
+#define MPFR_LDBL_MAX LDBL_MAX
+#endif
+
+#ifndef HAVE_LDOUBLE_IEEE_EXT_LITTLE
+
+/* Generic code */
+int
+mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t t, u;
+ int inexact, shift_exp;
+ long double x;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* Check for NAN */
+ LONGDOUBLE_NAN_ACTION (d, goto nan);
+
+ /* Check for INF */
+ if (d > MPFR_LDBL_MAX)
+ {
+ mpfr_set_inf (r, 1);
+ return 0;
+ }
+ else if (d < -MPFR_LDBL_MAX)
+ {
+ mpfr_set_inf (r, -1);
+ return 0;
+ }
+ /* Check for ZERO */
+ else if (d == 0.0)
+ return mpfr_set_d (r, (double) d, rnd_mode);
+
+ mpfr_init2 (t, MPFR_LDBL_MANT_DIG);
+ mpfr_init2 (u, IEEE_DBL_MANT_DIG);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ convert:
+ x = d;
+ MPFR_SET_ZERO (t); /* The sign doesn't matter. */
+ shift_exp = 0; /* invariant: remainder to deal with is d*2^shift_exp */
+ while (x != (long double) 0.0)
+ {
+ /* Check overflow of double */
+ if (x > (long double) DBL_MAX || (-x) > (long double) DBL_MAX)
+ {
+ long double div9, div10, div11, div12, div13;
+
+#define TWO_64 18446744073709551616.0 /* 2^64 */
+#define TWO_128 (TWO_64 * TWO_64)
+#define TWO_256 (TWO_128 * TWO_128)
+ div9 = (long double) (double) (TWO_256 * TWO_256); /* 2^(2^9) */
+ div10 = div9 * div9;
+ div11 = div10 * div10; /* 2^(2^11) */
+ div12 = div11 * div11; /* 2^(2^12) */
+ div13 = div12 * div12; /* 2^(2^13) */
+ if (ABS (x) >= div13)
+ {
+ x /= div13; /* exact */
+ shift_exp += 8192;
+ mpfr_div_2si (t, t, 8192, MPFR_RNDZ);
+ }
+ if (ABS (x) >= div12)
+ {
+ x /= div12; /* exact */
+ shift_exp += 4096;
+ mpfr_div_2si (t, t, 4096, MPFR_RNDZ);
+ }
+ if (ABS (x) >= div11)
+ {
+ x /= div11; /* exact */
+ shift_exp += 2048;
+ mpfr_div_2si (t, t, 2048, MPFR_RNDZ);
+ }
+ if (ABS (x) >= div10)
+ {
+ x /= div10; /* exact */
+ shift_exp += 1024;
+ mpfr_div_2si (t, t, 1024, MPFR_RNDZ);
+ }
+ /* warning: we may have DBL_MAX=2^1024*(1-2^(-53)) < x < 2^1024,
+ therefore we have one extra exponent reduction step */
+ if (ABS (x) >= div9)
+ {
+ x /= div9; /* exact */
+ shift_exp += 512;
+ mpfr_div_2si (t, t, 512, MPFR_RNDZ);
+ }
+ } /* Check overflow of double */
+ else /* no overflow on double */
+ {
+ long double div9, div10, div11;
+
+ div9 = (long double) (double) 7.4583407312002067432909653e-155;
+ /* div9 = 2^(-2^9) */
+ div10 = div9 * div9; /* 2^(-2^10) */
+ div11 = div10 * div10; /* 2^(-2^11) if extended precision */
+ /* since -DBL_MAX <= x <= DBL_MAX, the cast to double should not
+ overflow here */
+ if (ABS(x) < div10 &&
+ div11 != (long double) 0.0 &&
+ div11 / div10 == div10) /* possible underflow */
+ {
+ long double div12, div13;
+ /* After the divisions, any bit of x must be >= div10,
+ hence the possible division by div9. */
+ div12 = div11 * div11; /* 2^(-2^12) */
+ div13 = div12 * div12; /* 2^(-2^13) */
+ if (ABS (x) <= div13)
+ {
+ x /= div13; /* exact */
+ shift_exp -= 8192;
+ mpfr_mul_2si (t, t, 8192, MPFR_RNDZ);
+ }
+ if (ABS (x) <= div12)
+ {
+ x /= div12; /* exact */
+ shift_exp -= 4096;
+ mpfr_mul_2si (t, t, 4096, MPFR_RNDZ);
+ }
+ if (ABS (x) <= div11)
+ {
+ x /= div11; /* exact */
+ shift_exp -= 2048;
+ mpfr_mul_2si (t, t, 2048, MPFR_RNDZ);
+ }
+ if (ABS (x) <= div10)
+ {
+ x /= div10; /* exact */
+ shift_exp -= 1024;
+ mpfr_mul_2si (t, t, 1024, MPFR_RNDZ);
+ }
+ if (ABS(x) <= div9)
+ {
+ x /= div9; /* exact */
+ shift_exp -= 512;
+ mpfr_mul_2si (t, t, 512, MPFR_RNDZ);
+ }
+ }
+ else /* no underflow */
+ {
+ inexact = mpfr_set_d (u, (double) x, MPFR_RNDZ);
+ MPFR_ASSERTD (inexact == 0);
+ if (mpfr_add (t, t, u, MPFR_RNDZ) != 0)
+ {
+ if (!mpfr_number_p (t))
+ break;
+ /* Inexact. This cannot happen unless the C implementation
+ "lies" on the precision or when long doubles are
+ implemented with FP expansions like under Mac OS X. */
+ if (MPFR_PREC (t) != MPFR_PREC (r) + 1)
+ {
+ /* We assume that MPFR_PREC (r) < MPFR_PREC_MAX.
+ The precision MPFR_PREC (r) + 1 allows us to
+ deduce the rounding bit and the sticky bit. */
+ mpfr_set_prec (t, MPFR_PREC (r) + 1);
+ goto convert;
+ }
+ else
+ {
+ mp_limb_t *tp;
+ int rb_mask;
+
+ /* Since mpfr_add was inexact, the sticky bit is 1. */
+ tp = MPFR_MANT (t);
+ rb_mask = MPFR_LIMB_ONE <<
+ (GMP_NUMB_BITS - 1 -
+ (MPFR_PREC (r) & (GMP_NUMB_BITS - 1)));
+ if (rnd_mode == MPFR_RNDN)
+ rnd_mode = (*tp & rb_mask) ^ MPFR_IS_NEG (t) ?
+ MPFR_RNDU : MPFR_RNDD;
+ *tp |= rb_mask;
+ break;
+ }
+ }
+ x -= (long double) mpfr_get_d1 (u); /* exact */
+ }
+ }
+ }
+ inexact = mpfr_mul_2si (r, t, shift_exp, rnd_mode);
+ mpfr_clear (t);
+ mpfr_clear (u);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inexact, rnd_mode);
+
+ nan:
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+}
+
+#else /* IEEE Extended Little Endian Code */
+
+int
+mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
+{
+ int inexact, i, k, cnt;
+ mpfr_t tmp;
+ mp_limb_t tmpmant[MPFR_LIMBS_PER_LONG_DOUBLE];
+ mpfr_long_double_t x;
+ mpfr_exp_t exp;
+ int signd;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ /* Check for NAN */
+ if (MPFR_UNLIKELY (d != d))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ /* Check for INF */
+ else if (MPFR_UNLIKELY (d > MPFR_LDBL_MAX))
+ {
+ MPFR_SET_INF (r);
+ MPFR_SET_POS (r);
+ return 0;
+ }
+ else if (MPFR_UNLIKELY (d < -MPFR_LDBL_MAX))
+ {
+ MPFR_SET_INF (r);
+ MPFR_SET_NEG (r);
+ return 0;
+ }
+ /* Check for ZERO */
+ else if (MPFR_UNLIKELY (d == 0.0))
+ {
+ x.ld = d;
+ MPFR_SET_ZERO (r);
+ if (x.s.sign == 1)
+ MPFR_SET_NEG(r);
+ else
+ MPFR_SET_POS(r);
+ return 0;
+ }
+
+ /* now d is neither 0, nor NaN nor Inf */
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ MPFR_MANT (tmp) = tmpmant;
+ MPFR_PREC (tmp) = 64;
+
+ /* Extract sign */
+ x.ld = d;
+ signd = MPFR_SIGN_POS;
+ if (x.ld < 0.0)
+ {
+ signd = MPFR_SIGN_NEG;
+ x.ld = -x.ld;
+ }
+
+ /* Extract mantissa */
+#if GMP_NUMB_BITS >= 64
+ tmpmant[0] = ((mp_limb_t) x.s.manh << 32) | ((mp_limb_t) x.s.manl);
+#else
+ tmpmant[0] = (mp_limb_t) x.s.manl;
+ tmpmant[1] = (mp_limb_t) x.s.manh;
+#endif
+
+ /* Normalize mantissa */
+ i = MPFR_LIMBS_PER_LONG_DOUBLE;
+ MPN_NORMALIZE_NOT_ZERO (tmpmant, i);
+ k = MPFR_LIMBS_PER_LONG_DOUBLE - i;
+ count_leading_zeros (cnt, tmpmant[i - 1]);
+ if (MPFR_LIKELY (cnt != 0))
+ mpn_lshift (tmpmant + k, tmpmant, i, cnt);
+ else if (k != 0)
+ MPN_COPY (tmpmant + k, tmpmant, i);
+ if (MPFR_UNLIKELY (k != 0))
+ MPN_ZERO (tmpmant, k);
+
+ /* Set exponent */
+ exp = (mpfr_exp_t) ((x.s.exph << 8) + x.s.expl); /* 15-bit unsigned int */
+ if (MPFR_UNLIKELY (exp == 0))
+ exp -= 0x3FFD;
+ else
+ exp -= 0x3FFE;
+
+ MPFR_SET_EXP (tmp, exp - cnt - k * GMP_NUMB_BITS);
+
+ /* tmp is exact */
+ inexact = mpfr_set4 (r, tmp, rnd_mode, signd);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (r, inexact, rnd_mode);
+}
+
+#endif
diff --git a/mpfr/src/set_nan.c b/mpfr/src/set_nan.c
new file mode 100644
index 0000000000..db890414e7
--- /dev/null
+++ b/mpfr/src/set_nan.c
@@ -0,0 +1,31 @@
+/* mpfr_set_nan -- set a number to NaN.
+
+Copyright 2002, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#include "mpfr-impl.h"
+
+void
+mpfr_set_nan (mpfr_ptr x)
+{
+ MPFR_SET_NAN (x);
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+}
diff --git a/mpfr/src/set_prc_raw.c b/mpfr/src/set_prc_raw.c
new file mode 100644
index 0000000000..7b66e54e6f
--- /dev/null
+++ b/mpfr/src/set_prc_raw.c
@@ -0,0 +1,31 @@
+/* mpfr_set_prec_raw -- reset the precision of a floating-point number
+
+Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_set_prec_raw (mpfr_ptr x, mpfr_prec_t p)
+{
+ MPFR_ASSERTN (p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX);
+ MPFR_ASSERTN (p <= (mpfr_prec_t) MPFR_GET_ALLOC_SIZE(x) * GMP_NUMB_BITS);
+ MPFR_PREC(x) = p;
+}
diff --git a/mpfr/src/set_prec.c b/mpfr/src/set_prec.c
new file mode 100644
index 0000000000..3ecdc056fd
--- /dev/null
+++ b/mpfr/src/set_prec.c
@@ -0,0 +1,55 @@
+/* mpfr_set_prec -- reset the precision of a floating-point number
+
+Copyright 1999, 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_set_prec (mpfr_ptr x, mpfr_prec_t p)
+{
+ mp_size_t xsize, xoldsize;
+ mpfr_limb_ptr tmp;
+
+ /* first, check if p is correct */
+ MPFR_ASSERTN (p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX);
+
+ /* Calculate the new number of limbs */
+ xsize = MPFR_PREC2LIMBS (p);
+
+ /* Realloc only if the new size is greater than the old */
+ xoldsize = MPFR_GET_ALLOC_SIZE (x);
+ if (xsize > xoldsize)
+ {
+ tmp = (mpfr_limb_ptr) (*__gmp_reallocate_func)
+ (MPFR_GET_REAL_PTR(x), MPFR_MALLOC_SIZE(xoldsize), MPFR_MALLOC_SIZE(xsize));
+ MPFR_SET_MANT_PTR(x, tmp);
+ MPFR_SET_ALLOC_SIZE(x, xsize);
+ }
+ MPFR_PREC (x) = p;
+ MPFR_SET_NAN (x); /* initializes to NaN */
+}
+
+#undef mpfr_get_prec
+mpfr_prec_t
+mpfr_get_prec (mpfr_srcptr x)
+{
+ return MPFR_PREC(x);
+}
diff --git a/mpfr/src/set_q.c b/mpfr/src/set_q.c
new file mode 100644
index 0000000000..1a4e5117fb
--- /dev/null
+++ b/mpfr/src/set_q.c
@@ -0,0 +1,133 @@
+/* mpfr_set_q -- set a floating-point number from a multiple-precision rational
+
+Copyright 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/*
+ * Set f to z, choosing the smallest precision for f
+ * so that z = f*(2^BPML)*zs*2^(RetVal)
+ */
+static int
+set_z (mpfr_ptr f, mpz_srcptr z, mp_size_t *zs)
+{
+ mp_limb_t *p;
+ mp_size_t s;
+ int c;
+ mpfr_prec_t pf;
+
+ MPFR_ASSERTD (mpz_sgn (z) != 0);
+
+ /* Remove useless ending 0 */
+ for (p = PTR (z), s = *zs = ABS (SIZ (z)) ; *p == 0; p++, s--)
+ MPFR_ASSERTD (s >= 0);
+
+ /* Get working precision */
+ count_leading_zeros (c, p[s-1]);
+ pf = s * GMP_NUMB_BITS - c;
+ if (pf < MPFR_PREC_MIN)
+ pf = MPFR_PREC_MIN;
+ mpfr_init2 (f, pf);
+
+ /* Copy Mantissa */
+ if (MPFR_LIKELY (c))
+ mpn_lshift (MPFR_MANT (f), p, s, c);
+ else
+ MPN_COPY (MPFR_MANT (f), p, s);
+
+ MPFR_SET_SIGN (f, mpz_sgn (z));
+ MPFR_SET_EXP (f, 0);
+
+ return -c;
+}
+
+/* set f to the rational q */
+int
+mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mpfr_rnd_t rnd)
+{
+ mpz_srcptr num, den;
+ mpfr_t n, d;
+ int inexact;
+ int cn, cd;
+ long shift;
+ mp_size_t sn, sd;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ num = mpq_numref (q);
+ den = mpq_denref (q);
+ /* NAN and INF for mpq are not really documented, but could be found */
+ if (MPFR_UNLIKELY (mpz_sgn (num) == 0))
+ {
+ if (MPFR_UNLIKELY (mpz_sgn (den) == 0))
+ {
+ MPFR_SET_NAN (f);
+ MPFR_RET_NAN;
+ }
+ else
+ {
+ MPFR_SET_ZERO (f);
+ MPFR_SET_POS (f);
+ MPFR_RET (0);
+ }
+ }
+ if (MPFR_UNLIKELY (mpz_sgn (den) == 0))
+ {
+ MPFR_SET_INF (f);
+ MPFR_SET_SIGN (f, mpz_sgn (num));
+ MPFR_RET (0);
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ cn = set_z (n, num, &sn);
+ cd = set_z (d, den, &sd);
+
+ sn -= sd;
+ if (MPFR_UNLIKELY (sn > MPFR_EMAX_MAX / GMP_NUMB_BITS))
+ {
+ inexact = mpfr_overflow (f, rnd, MPFR_SIGN (f));
+ goto end;
+ }
+ if (MPFR_UNLIKELY (sn < MPFR_EMIN_MIN / GMP_NUMB_BITS -1))
+ {
+ if (rnd == MPFR_RNDN)
+ rnd = MPFR_RNDZ;
+ inexact = mpfr_underflow (f, rnd, MPFR_SIGN (f));
+ goto end;
+ }
+
+ inexact = mpfr_div (f, n, d, rnd);
+ shift = GMP_NUMB_BITS*sn+cn-cd;
+ MPFR_ASSERTD (shift == GMP_NUMB_BITS*sn+cn-cd);
+ cd = mpfr_mul_2si (f, f, shift, rnd);
+ MPFR_SAVE_EXPO_FREE (expo);
+ if (MPFR_UNLIKELY (cd != 0))
+ inexact = cd;
+ else
+ inexact = mpfr_check_range (f, inexact, rnd);
+ end:
+ mpfr_clear (d);
+ mpfr_clear (n);
+ return inexact;
+}
+
+
diff --git a/mpfr/src/set_rnd.c b/mpfr/src/set_rnd.c
new file mode 100644
index 0000000000..7b014dd64d
--- /dev/null
+++ b/mpfr/src/set_rnd.c
@@ -0,0 +1,40 @@
+/* mpfr_set_default_rounding_mode -- set the default rounding mode
+ mpfr_get_default_rounding_mode -- get the default rounding mode
+
+Copyright 1999, 2001, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+mpfr_rnd_t MPFR_THREAD_ATTR __gmpfr_default_rounding_mode = MPFR_RNDN;
+
+void
+mpfr_set_default_rounding_mode (mpfr_rnd_t rnd_mode)
+{
+ if (rnd_mode >= MPFR_RNDN && rnd_mode < MPFR_RND_MAX)
+ __gmpfr_default_rounding_mode = rnd_mode;
+}
+
+#undef mpfr_get_default_rounding_mode
+mpfr_rnd_t
+mpfr_get_default_rounding_mode (void)
+{
+ return __gmpfr_default_rounding_mode;
+}
diff --git a/mpfr/src/set_si.c b/mpfr/src/set_si.c
new file mode 100644
index 0000000000..30cb66d400
--- /dev/null
+++ b/mpfr/src/set_si.c
@@ -0,0 +1,30 @@
+/* mpfr_set_si -- set a MPFR number from a machine signed integer
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#undef mpfr_set_si
+int
+mpfr_set_si (mpfr_ptr x, long i, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_set_si_2exp (x, i, 0, rnd_mode);
+}
diff --git a/mpfr/src/set_si_2exp.c b/mpfr/src/set_si_2exp.c
new file mode 100644
index 0000000000..2064a70db5
--- /dev/null
+++ b/mpfr/src/set_si_2exp.c
@@ -0,0 +1,73 @@
+/* mpfr_set_si_2exp -- set a MPFR number from a machine signed integer with
+ a shift
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_set_si_2exp (mpfr_ptr x, long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
+{
+ if (i == 0)
+ {
+ MPFR_SET_ZERO (x);
+ MPFR_SET_POS (x);
+ MPFR_RET (0);
+ }
+ else
+ {
+ mp_size_t xn;
+ unsigned int cnt, nbits;
+ mp_limb_t ai, *xp;
+ int inex = 0;
+
+ /* FIXME: support int limbs (e.g. 16-bit limbs on 16-bit proc) */
+ ai = SAFE_ABS (unsigned long, i);
+ MPFR_ASSERTN (SAFE_ABS (unsigned long, i) == ai);
+
+ /* Position of the highest limb */
+ xn = (MPFR_PREC (x) - 1) / GMP_NUMB_BITS;
+ count_leading_zeros (cnt, ai);
+ MPFR_ASSERTD (cnt < GMP_NUMB_BITS); /* OK since i != 0 */
+
+ xp = MPFR_MANT(x);
+ xp[xn] = ai << cnt;
+ /* Zero the xn lower limbs. */
+ MPN_ZERO(xp, xn);
+ MPFR_SET_SIGN (x, i < 0 ? MPFR_SIGN_NEG : MPFR_SIGN_POS);
+
+ nbits = GMP_NUMB_BITS - cnt;
+ e += nbits; /* exponent _before_ the rounding */
+
+ /* round if MPFR_PREC(x) smaller than length of i */
+ if (MPFR_UNLIKELY (MPFR_PREC (x) < nbits) &&
+ MPFR_UNLIKELY (mpfr_round_raw (xp + xn, xp + xn, nbits, i < 0,
+ MPFR_PREC (x), rnd_mode, &inex)))
+ {
+ e++;
+ xp[xn] = MPFR_LIMB_HIGHBIT;
+ }
+
+ MPFR_EXP (x) = e;
+ return mpfr_check_range (x, inex, rnd_mode);
+ }
+}
diff --git a/mpfr/src/set_sj.c b/mpfr/src/set_sj.c
new file mode 100644
index 0000000000..1d8c522503
--- /dev/null
+++ b/mpfr/src/set_sj.c
@@ -0,0 +1,52 @@
+/* mpfr_set_sj -- set a MPFR number from a huge machine signed integer
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+#endif
+
+#include "mpfr-intmax.h"
+#include "mpfr-impl.h"
+
+#ifdef _MPFR_H_HAVE_INTMAX_T
+
+int
+mpfr_set_sj (mpfr_t x, intmax_t j, mpfr_rnd_t rnd)
+{
+ return mpfr_set_sj_2exp (x, j, 0, rnd);
+}
+
+int
+mpfr_set_sj_2exp (mpfr_t x, intmax_t j, intmax_t e, mpfr_rnd_t rnd)
+{
+ if (j>=0)
+ return mpfr_set_uj_2exp (x, j, e, rnd);
+ else
+ {
+ int inex;
+ inex = mpfr_set_uj_2exp (x, - (uintmax_t) j, e, MPFR_INVERT_RND (rnd));
+ MPFR_CHANGE_SIGN (x);
+ return -inex;
+ }
+}
+
+#endif
diff --git a/mpfr/src/set_str.c b/mpfr/src/set_str.c
new file mode 100644
index 0000000000..d2c40fc740
--- /dev/null
+++ b/mpfr/src/set_str.c
@@ -0,0 +1,42 @@
+/* mpfr_set_str -- set a floating-point number from a string
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_set_str (mpfr_t x, const char *str, int base, mpfr_rnd_t rnd)
+{
+ char *p;
+
+ if (MPFR_UNLIKELY (*str == 0))
+ return -1;
+ mpfr_strtofr (x, str, &p, base, rnd);
+ return (*p == 0) ? 0 : -1;
+}
+
+
+int
+mpfr_init_set_str (mpfr_ptr x, const char *str, int base, mpfr_rnd_t rnd)
+{
+ mpfr_init (x);
+ return mpfr_set_str (x, str, base, rnd);
+}
diff --git a/mpfr/src/set_str_raw.c b/mpfr/src/set_str_raw.c
new file mode 100644
index 0000000000..e7debb4b3a
--- /dev/null
+++ b/mpfr/src/set_str_raw.c
@@ -0,0 +1,55 @@
+/* mpfr_set_str_binary -- set a floating-point number from a binary string
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Currently the number should be of the form +/- xxxx.xxxxxxEyy, with
+ decimal exponent. The mantissa of x is supposed to be large enough
+ to hold all the bits of str. */
+
+void
+mpfr_set_str_binary (mpfr_ptr x, const char *str)
+{
+ int has_sign;
+ int res;
+
+ if (*str == 'N')
+ {
+ MPFR_SET_NAN(x);
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return;
+ }
+
+ has_sign = *str == '-' || *str == '+';
+ if (str[has_sign] == 'I')
+ {
+ MPFR_SET_INF(x);
+ if (*str == '-')
+ MPFR_SET_NEG(x);
+ else
+ MPFR_SET_POS(x);
+ return;
+ }
+
+ res = mpfr_strtofr (x, str, 0, 2, MPFR_RNDZ);
+ MPFR_ASSERTN (res == 0);
+}
diff --git a/mpfr/src/set_ui.c b/mpfr/src/set_ui.c
new file mode 100644
index 0000000000..caafaacf46
--- /dev/null
+++ b/mpfr/src/set_ui.c
@@ -0,0 +1,30 @@
+/* mpfr_set_ui -- set a MPFR number from a machine unsigned integer
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#undef mpfr_set_ui
+int
+mpfr_set_ui (mpfr_ptr x, unsigned long i, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_set_ui_2exp (x, i, 0, rnd_mode);
+}
diff --git a/mpfr/src/set_ui_2exp.c b/mpfr/src/set_ui_2exp.c
new file mode 100644
index 0000000000..6c77ba26c9
--- /dev/null
+++ b/mpfr/src/set_ui_2exp.c
@@ -0,0 +1,72 @@
+/* mpfr_set_ui_2exp -- set a MPFR number from a machine unsigned integer with
+ a shift
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_set_ui_2exp (mpfr_ptr x, unsigned long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
+{
+ MPFR_SET_POS (x);
+
+ if (i == 0)
+ {
+ MPFR_SET_ZERO (x);
+ MPFR_RET (0);
+ }
+ else
+ {
+ mp_size_t xn;
+ unsigned int cnt, nbits;
+ mp_limb_t *xp;
+ int inex = 0;
+
+ /* FIXME: support int limbs (e.g. 16-bit limbs on 16-bit proc) */
+ MPFR_ASSERTD (i == (mp_limb_t) i);
+
+ /* Position of the highest limb */
+ xn = (MPFR_PREC (x) - 1) / GMP_NUMB_BITS;
+ count_leading_zeros (cnt, (mp_limb_t) i);
+ MPFR_ASSERTD (cnt < GMP_NUMB_BITS); /* OK since i != 0 */
+
+ xp = MPFR_MANT(x);
+ xp[xn] = ((mp_limb_t) i) << cnt;
+ /* Zero the xn lower limbs. */
+ MPN_ZERO(xp, xn);
+
+ nbits = GMP_NUMB_BITS - cnt;
+ e += nbits; /* exponent _before_ the rounding */
+
+ /* round if MPFR_PREC(x) smaller than length of i */
+ if (MPFR_UNLIKELY (MPFR_PREC (x) < nbits) &&
+ MPFR_UNLIKELY (mpfr_round_raw (xp + xn, xp + xn, nbits, 0,
+ MPFR_PREC (x), rnd_mode, &inex)))
+ {
+ e++;
+ xp[xn] = MPFR_LIMB_HIGHBIT;
+ }
+
+ MPFR_EXP (x) = e;
+ return mpfr_check_range (x, inex, rnd_mode);
+ }
+}
diff --git a/mpfr/src/set_uj.c b/mpfr/src/set_uj.c
new file mode 100644
index 0000000000..768d3fe5f9
--- /dev/null
+++ b/mpfr/src/set_uj.c
@@ -0,0 +1,123 @@
+/* mpfr_set_uj -- set a MPFR number from a huge machine unsigned integer
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+#endif
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-intmax.h"
+#include "mpfr-impl.h"
+
+#ifdef _MPFR_H_HAVE_INTMAX_T
+
+int
+mpfr_set_uj (mpfr_t x, uintmax_t j, mpfr_rnd_t rnd)
+{
+ return mpfr_set_uj_2exp (x, j, 0, rnd);
+}
+
+int
+mpfr_set_uj_2exp (mpfr_t x, uintmax_t j, intmax_t e, mpfr_rnd_t rnd)
+{
+ unsigned int cnt, i;
+ mp_size_t k, len;
+ mp_limb_t limb;
+ mp_limb_t yp[sizeof(uintmax_t) / sizeof(mp_limb_t)];
+ mpfr_t y;
+ unsigned long uintmax_bit_size = sizeof(uintmax_t) * CHAR_BIT;
+ unsigned long bpml = GMP_NUMB_BITS % uintmax_bit_size;
+
+ /* Special case */
+ if (j == 0)
+ {
+ MPFR_SET_POS(x);
+ MPFR_SET_ZERO(x);
+ MPFR_RET(0);
+ }
+
+ MPFR_ASSERTN (sizeof(uintmax_t) % sizeof(mp_limb_t) == 0);
+
+ /* Create an auxillary var */
+ MPFR_TMP_INIT1 (yp, y, uintmax_bit_size);
+ k = numberof (yp);
+ if (k == 1)
+ limb = yp[0] = j;
+ else
+ {
+ /* Note: either GMP_NUMB_BITS = uintmax_bit_size, then k = 1 the
+ shift j >>= bpml is never done, or GMP_NUMB_BITS < uintmax_bit_size
+ and bpml = GMP_NUMB_BITS. */
+ for (i = 0; i < k; i++, j >>= bpml)
+ yp[i] = j; /* Only the low bits are copied */
+
+ /* Find the first limb not equal to zero. */
+ do
+ {
+ MPFR_ASSERTD (k > 0);
+ limb = yp[--k];
+ }
+ while (limb == 0);
+ k++;
+ }
+ count_leading_zeros(cnt, limb);
+ len = numberof (yp) - k;
+
+ /* Normalize it: len = number of last 0 limb, k number of non-zero limbs */
+ if (MPFR_LIKELY(cnt))
+ mpn_lshift (yp+len, yp, k, cnt); /* Normalize the High Limb*/
+ else if (len != 0)
+ MPN_COPY_DECR (yp+len, yp, k); /* Must use DECR */
+ if (len != 0)
+ /* Note: when numberof(yp)==1, len is constant and null, so the compiler
+ can optimize out this code. */
+ {
+ if (len == 1)
+ yp[0] = (mp_limb_t) 0;
+ else
+ MPN_ZERO (yp, len); /* Zeroing the last limbs */
+ }
+ e += k * GMP_NUMB_BITS - cnt; /* Update Expo */
+ MPFR_ASSERTD (MPFR_LIMB_MSB(yp[numberof (yp) - 1]) != 0);
+
+ /* Check expo underflow / overflow (can't use mpfr_check_range) */
+ if (MPFR_UNLIKELY(e < __gmpfr_emin))
+ {
+ /* The following test is necessary because in the rounding to the
+ * nearest mode, mpfr_underflow always rounds away from 0. In
+ * this rounding mode, we need to round to 0 if:
+ * _ |x| < 2^(emin-2), or
+ * _ |x| = 2^(emin-2) and the absolute value of the exact
+ * result is <= 2^(emin-2). */
+ if (rnd == MPFR_RNDN && (e+1 < __gmpfr_emin || mpfr_powerof2_raw(y)))
+ rnd = MPFR_RNDZ;
+ return mpfr_underflow (x, rnd, MPFR_SIGN_POS);
+ }
+ if (MPFR_UNLIKELY(e > __gmpfr_emax))
+ return mpfr_overflow (x, rnd, MPFR_SIGN_POS);
+ MPFR_SET_EXP (y, e);
+
+ /* Final: set x to y (rounding if necessary) */
+ return mpfr_set (x, y, rnd);
+}
+
+#endif
diff --git a/mpfr/src/set_z.c b/mpfr/src/set_z.c
new file mode 100644
index 0000000000..8a14d94886
--- /dev/null
+++ b/mpfr/src/set_z.c
@@ -0,0 +1,30 @@
+/* mpfr_set_z -- set a floating-point number from a multiple-precision integer
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* set f to the integer z */
+int
+mpfr_set_z (mpfr_ptr f, mpz_srcptr z, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_set_z_2exp (f, z, 0, rnd_mode);
+}
diff --git a/mpfr/src/set_z_exp.c b/mpfr/src/set_z_exp.c
new file mode 100644
index 0000000000..e5fe9610d6
--- /dev/null
+++ b/mpfr/src/set_z_exp.c
@@ -0,0 +1,180 @@
+/* mpfr_set_z_2exp -- set a floating-point number from a multiple-precision
+ integer and an exponent
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* set f to the integer z multiplied by 2^e */
+int
+mpfr_set_z_2exp (mpfr_ptr f, mpz_srcptr z, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
+{
+ mp_size_t fn, zn, dif, en;
+ int k, sign_z, inex;
+ mp_limb_t *fp, *zp;
+ mpfr_exp_t exp;
+
+ sign_z = mpz_sgn (z);
+ if (MPFR_UNLIKELY (sign_z == 0)) /* ignore the exponent for 0 */
+ {
+ MPFR_SET_ZERO(f);
+ MPFR_SET_POS(f);
+ MPFR_RET(0);
+ }
+ MPFR_ASSERTD (sign_z == MPFR_SIGN_POS || sign_z == MPFR_SIGN_NEG);
+
+ zn = ABS(SIZ(z)); /* limb size of z */
+ /* compute en = floor(e/GMP_NUMB_BITS) */
+ en = (e >= 0) ? e / GMP_NUMB_BITS : (e + 1) / GMP_NUMB_BITS - 1;
+ MPFR_ASSERTD (zn >= 1);
+ if (MPFR_UNLIKELY (zn + en > MPFR_EMAX_MAX / GMP_NUMB_BITS + 1))
+ return mpfr_overflow (f, rnd_mode, sign_z);
+ /* because zn + en >= MPFR_EMAX_MAX / GMP_NUMB_BITS + 2
+ implies (zn + en) * GMP_NUMB_BITS >= MPFR_EMAX_MAX + GMP_NUMB_BITS + 1
+ and exp = zn * GMP_NUMB_BITS + e - k
+ >= (zn + en) * GMP_NUMB_BITS - k > MPFR_EMAX_MAX */
+
+ fp = MPFR_MANT (f);
+ fn = MPFR_LIMB_SIZE (f);
+ dif = zn - fn;
+ zp = PTR(z);
+ count_leading_zeros (k, zp[zn-1]);
+
+ /* now zn + en <= MPFR_EMAX_MAX / GMP_NUMB_BITS + 1
+ thus (zn + en) * GMP_NUMB_BITS <= MPFR_EMAX_MAX + GMP_NUMB_BITS
+ and exp = zn * GMP_NUMB_BITS + e - k
+ <= (zn + en) * GMP_NUMB_BITS - k + GMP_NUMB_BITS - 1
+ <= MPFR_EMAX_MAX + 2 * GMP_NUMB_BITS - 1 */
+ exp = (mpfr_prec_t) zn * GMP_NUMB_BITS + e - k;
+ /* The exponent will be exp or exp + 1 (due to rounding) */
+ if (MPFR_UNLIKELY (exp > __gmpfr_emax))
+ return mpfr_overflow (f, rnd_mode, sign_z);
+ if (MPFR_UNLIKELY (exp + 1 < __gmpfr_emin))
+ return mpfr_underflow (f, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode,
+ sign_z);
+
+ if (MPFR_LIKELY (dif >= 0))
+ {
+ mp_limb_t rb, sb, ulp;
+ int sh;
+
+ /* number has to be truncated */
+ if (MPFR_LIKELY (k != 0))
+ {
+ mpn_lshift (fp, &zp[dif], fn, k);
+ if (MPFR_LIKELY (dif > 0))
+ fp[0] |= zp[dif - 1] >> (GMP_NUMB_BITS - k);
+ }
+ else
+ MPN_COPY (fp, zp + dif, fn);
+
+ /* Compute Rounding Bit and Sticky Bit */
+ MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (f) );
+ if (MPFR_LIKELY (sh != 0))
+ {
+ mp_limb_t mask = MPFR_LIMB_ONE << (sh-1);
+ mp_limb_t limb = fp[0];
+ rb = limb & mask;
+ sb = limb & (mask-1);
+ ulp = 2*mask;
+ fp[0] = limb & ~(ulp-1);
+ }
+ else /* sh == 0 */
+ {
+ mp_limb_t mask = MPFR_LIMB_ONE << (GMP_NUMB_BITS - 1 - k);
+ if (MPFR_LIKELY (dif > 0))
+ {
+ rb = zp[--dif] & mask;
+ sb = zp[dif] & (mask-1);
+ }
+ else
+ rb = sb = 0;
+ k = 0;
+ ulp = MPFR_LIMB_ONE;
+ }
+ if (MPFR_UNLIKELY (sb == 0) && MPFR_LIKELY (dif > 0))
+ {
+ sb = zp[--dif];
+ if (MPFR_LIKELY (k != 0))
+ sb &= MPFR_LIMB_MASK (GMP_NUMB_BITS - k);
+ if (MPFR_UNLIKELY (sb == 0) && MPFR_LIKELY (dif > 0))
+ do {
+ sb = zp[--dif];
+ } while (dif > 0 && sb == 0);
+ }
+
+ /* Rounding */
+ if (MPFR_LIKELY (rnd_mode == MPFR_RNDN))
+ {
+ if (rb == 0 || MPFR_UNLIKELY (sb == 0 && (fp[0] & ulp) == 0))
+ goto trunc;
+ else
+ goto addoneulp;
+ }
+ else /* Not Nearest */
+ {
+ if (MPFR_LIKELY (MPFR_IS_LIKE_RNDZ (rnd_mode, sign_z < 0))
+ || MPFR_UNLIKELY ( (sb | rb) == 0 ))
+ goto trunc;
+ else
+ goto addoneulp;
+ }
+
+ trunc:
+ inex = MPFR_LIKELY ((sb | rb) != 0) ? -1 : 0;
+ goto end;
+
+ addoneulp:
+ inex = 1;
+ if (MPFR_UNLIKELY (mpn_add_1 (fp, fp, fn, ulp)))
+ {
+ /* Pow 2 case */
+ if (MPFR_UNLIKELY (exp == __gmpfr_emax))
+ return mpfr_overflow (f, rnd_mode, sign_z);
+ exp ++;
+ fp[fn-1] = MPFR_LIMB_HIGHBIT;
+ }
+ end:
+ (void) 0;
+ }
+ else /* dif < 0: Mantissa F is strictly bigger than z's one */
+ {
+ if (MPFR_LIKELY (k != 0))
+ mpn_lshift (fp - dif, zp, zn, k);
+ else
+ MPN_COPY (fp - dif, zp, zn);
+ /* fill with zeroes */
+ MPN_ZERO (fp, -dif);
+ inex = 0; /* result is exact */
+ }
+
+ if (MPFR_UNLIKELY (exp < __gmpfr_emin))
+ {
+ if (rnd_mode == MPFR_RNDN && inex == 0 && mpfr_powerof2_raw (f))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (f, rnd_mode, sign_z);
+ }
+
+ MPFR_SET_EXP (f, exp);
+ MPFR_SET_SIGN (f, sign_z);
+ MPFR_RET (inex*sign_z);
+}
diff --git a/mpfr/src/set_zero.c b/mpfr/src/set_zero.c
new file mode 100644
index 0000000000..ea13b034c0
--- /dev/null
+++ b/mpfr/src/set_zero.c
@@ -0,0 +1,31 @@
+/* mpfr_set_zero -- set a number to plus or minus zero.
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+void
+mpfr_set_zero (mpfr_ptr x, int sign)
+{
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ if (sign < 0)
+ MPFR_SET_NEG(x);
+}
diff --git a/mpfr/src/setmax.c b/mpfr/src/setmax.c
new file mode 100644
index 0000000000..e88a70947c
--- /dev/null
+++ b/mpfr/src/setmax.c
@@ -0,0 +1,41 @@
+/* mpfr_setmax -- maximum representable floating-point number (raw version)
+
+Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Note: the flags are not cleared and the current sign is kept. */
+
+void
+mpfr_setmax (mpfr_ptr x, mpfr_exp_t e)
+{
+ mp_size_t xn, i;
+ int sh;
+ mp_limb_t *xp;
+
+ MPFR_SET_EXP (x, e);
+ xn = MPFR_LIMB_SIZE (x);
+ sh = (mpfr_prec_t) xn * GMP_NUMB_BITS - MPFR_PREC(x);
+ xp = MPFR_MANT(x);
+ xp[0] = MP_LIMB_T_MAX << sh;
+ for (i = 1; i < xn; i++)
+ xp[i] = MP_LIMB_T_MAX;
+}
diff --git a/mpfr/src/setmin.c b/mpfr/src/setmin.c
new file mode 100644
index 0000000000..62c003a66e
--- /dev/null
+++ b/mpfr/src/setmin.c
@@ -0,0 +1,38 @@
+/* mpfr_setmin -- minimum representable floating-point number (raw version)
+
+Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Note: the flags are not cleared and the current sign is kept. */
+
+void
+mpfr_setmin (mpfr_ptr x, mpfr_exp_t e)
+{
+ mp_size_t xn;
+ mp_limb_t *xp;
+
+ MPFR_SET_EXP (x, e);
+ xn = (MPFR_PREC(x) - 1) / GMP_NUMB_BITS;
+ xp = MPFR_MANT(x);
+ xp[xn] = MPFR_LIMB_HIGHBIT;
+ MPN_ZERO(xp, xn);
+}
diff --git a/mpfr/src/setsign.c b/mpfr/src/setsign.c
new file mode 100644
index 0000000000..eb9e481688
--- /dev/null
+++ b/mpfr/src/setsign.c
@@ -0,0 +1,30 @@
+/* mpfr_setsign -- Produce a value with the magnitude of x and sign bit s
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#undef mpfr_setsign
+int
+mpfr_setsign (mpfr_ptr z, mpfr_srcptr x, int s, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_set4 (z, x, rnd_mode, s ? -1 : 1);
+}
diff --git a/mpfr/src/sgn.c b/mpfr/src/sgn.c
new file mode 100644
index 0000000000..ec59929786
--- /dev/null
+++ b/mpfr/src/sgn.c
@@ -0,0 +1,40 @@
+/* mpfr_sgn -- Sign of a floating point number.
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+(mpfr_sgn) (mpfr_srcptr a)
+{
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)))
+ {
+ if (MPFR_LIKELY (MPFR_IS_ZERO (a)))
+ return 0;
+ if (MPFR_UNLIKELY (MPFR_IS_NAN (a)))
+ {
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ /* Remains infinity, handled by the return below. */
+ }
+ return MPFR_INT_SIGN (a);
+}
diff --git a/mpfr/src/si_op.c b/mpfr/src/si_op.c
new file mode 100644
index 0000000000..bad4b856b7
--- /dev/null
+++ b/mpfr/src/si_op.c
@@ -0,0 +1,57 @@
+/* mpfr_add_si -- add a floating-point number with a machine integer
+ mpfr_sub_si -- sub a floating-point number with a machine integer
+ mpfr_si_sub -- sub a machine number with a floating-point number
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_add_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
+{
+ if (u >= 0)
+ return mpfr_add_ui (y, x, u, rnd_mode);
+ else
+ return mpfr_sub_ui (y, x, -u, rnd_mode);
+}
+
+int
+mpfr_sub_si (mpfr_ptr y, mpfr_srcptr x, long int u, mpfr_rnd_t rnd_mode)
+{
+ if (u >= 0)
+ return mpfr_sub_ui (y, x, u, rnd_mode);
+ else
+ return mpfr_add_ui (y, x, -u, rnd_mode);
+}
+
+int
+mpfr_si_sub (mpfr_ptr y, long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ if (u >= 0)
+ return mpfr_ui_sub (y, u, x, rnd_mode);
+ else
+ {
+ int res = -mpfr_add_ui (y, x, -u, MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ return res;
+ }
+}
+
diff --git a/mpfr/src/signbit.c b/mpfr/src/signbit.c
new file mode 100644
index 0000000000..8a2bc7f141
--- /dev/null
+++ b/mpfr/src/signbit.c
@@ -0,0 +1,30 @@
+/* mpfr_signbit -- Signbit of a MPFR number
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#undef mpfr_signbit
+int
+mpfr_signbit (mpfr_srcptr x)
+{
+ return MPFR_SIGN (x) < 0;
+}
diff --git a/mpfr/src/sin.c b/mpfr/src/sin.c
new file mode 100644
index 0000000000..88e73f34c0
--- /dev/null
+++ b/mpfr/src/sin.c
@@ -0,0 +1,183 @@
+/* mpfr_sin -- sine of a floating-point number
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+static int
+mpfr_sin_fast (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int inex;
+
+ inex = mpfr_sincos_fast (y, NULL, x, rnd_mode);
+ inex = inex & 3; /* 0: exact, 1: rounded up, 2: rounded down */
+ return (inex == 2) ? -1 : inex;
+}
+
+int
+mpfr_sin (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t c, xr;
+ mpfr_srcptr xx;
+ mpfr_exp_t expx, err;
+ mpfr_prec_t precy, m;
+ int inexact, sign, reduce;
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y,
+ inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x) || MPFR_IS_INF (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+
+ }
+ else /* x is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ MPFR_RET (0);
+ }
+ }
+
+ /* sin(x) = x - x^3/6 + ... so the error is < 2^(3*EXP(x)-2) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * MPFR_GET_EXP (x), 2, 0,
+ rnd_mode, {});
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Compute initial precision */
+ precy = MPFR_PREC (y);
+
+ if (precy >= MPFR_SINCOS_THRESHOLD)
+ return mpfr_sin_fast (y, x, rnd_mode);
+
+ m = precy + MPFR_INT_CEIL_LOG2 (precy) + 13;
+ expx = MPFR_GET_EXP (x);
+
+ mpfr_init (c);
+ mpfr_init (xr);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ /* first perform argument reduction modulo 2*Pi (if needed),
+ also helps to determine the sign of sin(x) */
+ if (expx >= 2) /* If Pi < x < 4, we need to reduce too, to determine
+ the sign of sin(x). For 2 <= |x| < Pi, we could avoid
+ the reduction. */
+ {
+ reduce = 1;
+ /* As expx + m - 1 will silently be converted into mpfr_prec_t
+ in the mpfr_set_prec call, the assert below may be useful to
+ avoid undefined behavior. */
+ MPFR_ASSERTN (expx + m - 1 <= MPFR_PREC_MAX);
+ mpfr_set_prec (c, expx + m - 1);
+ mpfr_set_prec (xr, m);
+ mpfr_const_pi (c, MPFR_RNDN);
+ mpfr_mul_2ui (c, c, 1, MPFR_RNDN);
+ mpfr_remainder (xr, x, c, MPFR_RNDN);
+ /* The analysis is similar to that of cos.c:
+ |xr - x - 2kPi| <= 2^(2-m). Thus we can decide the sign
+ of sin(x) if xr is at distance at least 2^(2-m) of both
+ 0 and +/-Pi. */
+ mpfr_div_2ui (c, c, 1, MPFR_RNDN);
+ /* Since c approximates Pi with an error <= 2^(2-expx-m) <= 2^(-m),
+ it suffices to check that c - |xr| >= 2^(2-m). */
+ if (MPFR_SIGN (xr) > 0)
+ mpfr_sub (c, c, xr, MPFR_RNDZ);
+ else
+ mpfr_add (c, c, xr, MPFR_RNDZ);
+ if (MPFR_IS_ZERO(xr)
+ || MPFR_GET_EXP(xr) < (mpfr_exp_t) 3 - (mpfr_exp_t) m
+ || MPFR_IS_ZERO(c)
+ || MPFR_GET_EXP(c) < (mpfr_exp_t) 3 - (mpfr_exp_t) m)
+ goto ziv_next;
+
+ /* |xr - x - 2kPi| <= 2^(2-m), thus |sin(xr) - sin(x)| <= 2^(2-m) */
+ xx = xr;
+ }
+ else /* the input argument is already reduced */
+ {
+ reduce = 0;
+ xx = x;
+ }
+
+ sign = MPFR_SIGN(xx);
+ /* now that the argument is reduced, precision m is enough */
+ mpfr_set_prec (c, m);
+ mpfr_cos (c, xx, MPFR_RNDZ); /* can't be exact */
+ mpfr_nexttoinf (c); /* now c = cos(x) rounded away */
+ mpfr_mul (c, c, c, MPFR_RNDU); /* away */
+ mpfr_ui_sub (c, 1, c, MPFR_RNDZ);
+ mpfr_sqrt (c, c, MPFR_RNDZ);
+ if (MPFR_IS_NEG_SIGN(sign))
+ MPFR_CHANGE_SIGN(c);
+
+ /* Warning: c may be 0! */
+ if (MPFR_UNLIKELY (MPFR_IS_ZERO (c)))
+ {
+ /* Huge cancellation: increase prec a lot! */
+ m = MAX (m, MPFR_PREC (x));
+ m = 2 * m;
+ }
+ else
+ {
+ /* the absolute error on c is at most 2^(3-m-EXP(c)),
+ plus 2^(2-m) if there was an argument reduction.
+ Since EXP(c) <= 1, 3-m-EXP(c) >= 2-m, thus the error
+ is at most 2^(3-m-EXP(c)) in case of argument reduction. */
+ err = 2 * MPFR_GET_EXP (c) + (mpfr_exp_t) m - 3 - (reduce != 0);
+ if (MPFR_CAN_ROUND (c, err, precy, rnd_mode))
+ break;
+
+ /* check for huge cancellation (Near 0) */
+ if (err < (mpfr_exp_t) MPFR_PREC (y))
+ m += MPFR_PREC (y) - err;
+ /* Check if near 1 */
+ if (MPFR_GET_EXP (c) == 1)
+ m += m;
+ }
+
+ ziv_next:
+ /* Else generic increase */
+ MPFR_ZIV_NEXT (loop, m);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (y, c, rnd_mode);
+ /* inexact cannot be 0, since this would mean that c was representable
+ within the target precision, but in that case mpfr_can_round will fail */
+
+ mpfr_clear (c);
+ mpfr_clear (xr);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/sin_cos.c b/mpfr/src/sin_cos.c
new file mode 100644
index 0000000000..8ee95e934d
--- /dev/null
+++ b/mpfr/src/sin_cos.c
@@ -0,0 +1,662 @@
+/* mpfr_sin_cos -- sine and cosine of a floating-point number
+
+Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* (y, z) <- (sin(x), cos(x)), return value is 0 iff both results are exact
+ ie, iff x = 0 */
+int
+mpfr_sin_cos (mpfr_ptr y, mpfr_ptr z, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t prec, m;
+ int neg, reduce;
+ mpfr_t c, xr;
+ mpfr_srcptr xx;
+ mpfr_exp_t err, expx;
+ int inexy, inexz;
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_ASSERTN (y != z);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN(x) || MPFR_IS_INF(x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_SET_NAN (z);
+ MPFR_RET_NAN;
+ }
+ else /* x is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (y);
+ MPFR_SET_SAME_SIGN (y, x);
+ /* y = 0, thus exact, but z is inexact in case of underflow
+ or overflow */
+ inexy = 0; /* y is exact */
+ inexz = mpfr_set_ui (z, 1, rnd_mode);
+ return INEX(inexy,inexz);
+ }
+ }
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("sin[%Pu]=%.*Rg cos[%Pu]=%.*Rg", mpfr_get_prec(y), mpfr_log_prec, y,
+ mpfr_get_prec (z), mpfr_log_prec, z));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ prec = MAX (MPFR_PREC (y), MPFR_PREC (z));
+ m = prec + MPFR_INT_CEIL_LOG2 (prec) + 13;
+ expx = MPFR_GET_EXP (x);
+
+ /* When x is close to 0, say 2^(-k), then there is a cancellation of about
+ 2k bits in 1-cos(x)^2. FIXME: in that case, it would be more efficient
+ to compute sin(x) directly. VL: This is partly done by using
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT from the mpfr_sin and mpfr_cos
+ functions. Moreover, any overflow on m is avoided. */
+ if (expx < 0)
+ {
+ /* Warning: in case y = x, and the first call to
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT succeeds but the second fails,
+ we will have clobbered the original value of x.
+ The workaround is to first compute z = cos(x) in that case, since
+ y and z are different. */
+ if (y != x)
+ /* y and x differ, thus we can safely try to compute y first */
+ {
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
+ y, x, -2 * expx, 2, 0, rnd_mode,
+ { inexy = _inexact;
+ goto small_input; });
+ if (0)
+ {
+ small_input:
+ /* we can go here only if we can round sin(x) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
+ z, __gmpfr_one, -2 * expx, 1, 0, rnd_mode,
+ { inexz = _inexact;
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ goto end; });
+ }
+
+ /* if we go here, one of the two MPFR_FAST_COMPUTE_IF_SMALL_INPUT
+ calls failed */
+ }
+ else /* y and x are the same variable: try to compute z first, which
+ necessarily differs */
+ {
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
+ z, __gmpfr_one, -2 * expx, 1, 0, rnd_mode,
+ { inexz = _inexact;
+ goto small_input2; });
+ if (0)
+ {
+ small_input2:
+ /* we can go here only if we can round cos(x) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (
+ y, x, -2 * expx, 2, 0, rnd_mode,
+ { inexy = _inexact;
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ goto end; });
+ }
+ }
+ m += 2 * (-expx);
+ }
+
+ if (prec >= MPFR_SINCOS_THRESHOLD)
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_sincos_fast (y, z, x, rnd_mode);
+ }
+
+ mpfr_init (c);
+ mpfr_init (xr);
+
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ /* the following is copied from sin.c */
+ if (expx >= 2) /* reduce the argument */
+ {
+ reduce = 1;
+ mpfr_set_prec (c, expx + m - 1);
+ mpfr_set_prec (xr, m);
+ mpfr_const_pi (c, MPFR_RNDN);
+ mpfr_mul_2ui (c, c, 1, MPFR_RNDN);
+ mpfr_remainder (xr, x, c, MPFR_RNDN);
+ mpfr_div_2ui (c, c, 1, MPFR_RNDN);
+ if (MPFR_SIGN (xr) > 0)
+ mpfr_sub (c, c, xr, MPFR_RNDZ);
+ else
+ mpfr_add (c, c, xr, MPFR_RNDZ);
+ if (MPFR_IS_ZERO(xr)
+ || MPFR_EXP(xr) < (mpfr_exp_t) 3 - (mpfr_exp_t) m
+ || MPFR_EXP(c) < (mpfr_exp_t) 3 - (mpfr_exp_t) m)
+ goto next_step;
+ xx = xr;
+ }
+ else /* the input argument is already reduced */
+ {
+ reduce = 0;
+ xx = x;
+ }
+
+ neg = MPFR_IS_NEG (xx); /* gives sign of sin(x) */
+ mpfr_set_prec (c, m);
+ mpfr_cos (c, xx, MPFR_RNDZ);
+ /* If no argument reduction was performed, the error is at most ulp(c),
+ otherwise it is at most ulp(c) + 2^(2-m). Since |c| < 1, we have
+ ulp(c) <= 2^(-m), thus the error is bounded by 2^(3-m) in that later
+ case. */
+ if (reduce == 0)
+ err = m;
+ else
+ err = MPFR_GET_EXP (c) + (mpfr_exp_t) (m - 3);
+ if (!mpfr_can_round (c, err, MPFR_RNDN, MPFR_RNDZ,
+ MPFR_PREC (z) + (rnd_mode == MPFR_RNDN)))
+ goto next_step;
+
+ /* we can't set z now, because in case z = x, and the mpfr_can_round()
+ call below fails, we will have clobbered the input */
+ mpfr_set_prec (xr, MPFR_PREC(c));
+ mpfr_swap (xr, c); /* save the approximation of the cosine in xr */
+ mpfr_sqr (c, xr, MPFR_RNDU); /* the absolute error is bounded by
+ 2^(5-m) if reduce=1, and by 2^(2-m)
+ otherwise */
+ mpfr_ui_sub (c, 1, c, MPFR_RNDN); /* error bounded by 2^(6-m) if reduce
+ is 1, and 2^(3-m) otherwise */
+ mpfr_sqrt (c, c, MPFR_RNDN); /* the absolute error is bounded by
+ 2^(6-m-Exp(c)) if reduce=1, and
+ 2^(3-m-Exp(c)) otherwise */
+ err = 3 + 3 * reduce - MPFR_GET_EXP (c);
+ if (neg)
+ MPFR_CHANGE_SIGN (c);
+
+ /* the absolute error on c is at most 2^(err-m), which we must put
+ in the form 2^(EXP(c)-err). */
+ err = MPFR_GET_EXP (c) + (mpfr_exp_t) m - err;
+ if (mpfr_can_round (c, err, MPFR_RNDN, MPFR_RNDZ,
+ MPFR_PREC (y) + (rnd_mode == MPFR_RNDN)))
+ break;
+ /* check for huge cancellation */
+ if (err < (mpfr_exp_t) MPFR_PREC (y))
+ m += MPFR_PREC (y) - err;
+ /* Check if near 1 */
+ if (MPFR_GET_EXP (c) == 1
+ && MPFR_MANT (c)[MPFR_LIMB_SIZE (c)-1] == MPFR_LIMB_HIGHBIT)
+ m += m;
+
+ next_step:
+ MPFR_ZIV_NEXT (loop, m);
+ mpfr_set_prec (c, m);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexy = mpfr_set (y, c, rnd_mode);
+ inexz = mpfr_set (z, xr, rnd_mode);
+
+ mpfr_clear (c);
+ mpfr_clear (xr);
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ /* FIXME: add a test for bug before revision 7355 */
+ inexy = mpfr_check_range (y, inexy, rnd_mode);
+ inexz = mpfr_check_range (z, inexz, rnd_mode);
+ MPFR_RET (INEX(inexy,inexz));
+}
+
+/*************** asymptotically fast implementation below ********************/
+
+/* truncate Q from R to at most prec bits.
+ Return the number of truncated bits.
+ */
+static mpfr_prec_t
+reduce (mpz_t Q, mpz_srcptr R, mpfr_prec_t prec)
+{
+ mpfr_prec_t l = mpz_sizeinbase (R, 2);
+
+ l = (l > prec) ? l - prec : 0;
+ mpz_fdiv_q_2exp (Q, R, l);
+ return l;
+}
+
+/* truncate S and C so that the smaller has prec bits.
+ Return the number of truncated bits.
+ */
+static unsigned long
+reduce2 (mpz_t S, mpz_t C, mpfr_prec_t prec)
+{
+ unsigned long ls = mpz_sizeinbase (S, 2);
+ unsigned long lc = mpz_sizeinbase (C, 2);
+ unsigned long l;
+
+ l = (ls < lc) ? ls : lc; /* smaller length */
+ l = (l > prec) ? l - prec : 0;
+ mpz_fdiv_q_2exp (S, S, l);
+ mpz_fdiv_q_2exp (C, C, l);
+ return l;
+}
+
+/* return in S0/Q0 a rational approximation of sin(X) with absolute error
+ bounded by 9*2^(-prec), where 0 <= X=p/2^r <= 1/2,
+ and in C0/Q0 a rational approximation of cos(X), with relative error
+ bounded by 9*2^(-prec) (and also absolute error, since
+ |cos(X)| <= 1).
+ We have sin(X)/X = sum((-1)^i*(p/2^r)^i/(2i+1)!, i=0..infinity).
+ We use the following binary splitting formula:
+ P(a,b) = (-p)^(b-a)
+ Q(a,b) = (2a)*(2a+1)*2^r if a+1=b [except Q(0,1)=1], Q(a,c)*Q(c,b) otherwise
+ T(a,b) = 1 if a+1=b, Q(c,b)*T(a,c)+P(a,c)*T(c,b) otherwise.
+
+ Since we use P(a,b) for b-a=2^k only, we compute only p^(2^k).
+ We do not store the factor 2^r in Q().
+
+ Then sin(X)/X ~ T(0,i)/Q(0,i) for i so that (p/2^r)^i/i! is small enough.
+
+ Return l such that Q0 has to be multiplied by 2^l.
+
+ Assumes prec >= 10.
+*/
+static unsigned long
+sin_bs_aux (mpz_t Q0, mpz_t S0, mpz_t C0, mpz_srcptr p, mpfr_prec_t r,
+ mpfr_prec_t prec)
+{
+ mpz_t T[GMP_NUMB_BITS], Q[GMP_NUMB_BITS], ptoj[GMP_NUMB_BITS], pp;
+ mpfr_prec_t log2_nb_terms[GMP_NUMB_BITS], mult[GMP_NUMB_BITS];
+ mpfr_prec_t accu[GMP_NUMB_BITS], size_ptoj[GMP_NUMB_BITS];
+ mpfr_prec_t prec_i_have, r0 = r;
+ unsigned long alloc, i, j, k;
+ mpfr_prec_t l;
+
+ if (MPFR_UNLIKELY(mpz_cmp_ui (p, 0) == 0)) /* sin(x)/x -> 1 */
+ {
+ mpz_set_ui (Q0, 1);
+ mpz_set_ui (S0, 1);
+ mpz_set_ui (C0, 1);
+ return 0;
+ }
+
+ /* check that X=p/2^r <= 1/2 */
+ MPFR_ASSERTN(mpz_sizeinbase (p, 2) - (mpfr_exp_t) r <= -1);
+
+ mpz_init (pp);
+
+ /* normalize p (non-zero here) */
+ l = mpz_scan1 (p, 0);
+ mpz_fdiv_q_2exp (pp, p, l); /* p = pp * 2^l */
+ mpz_mul (pp, pp, pp);
+ r = 2 * (r - l); /* x^2 = (p/2^r0)^2 = pp / 2^r */
+
+ /* now p is odd */
+ alloc = 2;
+ mpz_init_set_ui (T[0], 6);
+ mpz_init_set_ui (Q[0], 6);
+ mpz_init_set (ptoj[0], pp); /* ptoj[i] = pp^(2^i) */
+ mpz_init (T[1]);
+ mpz_init (Q[1]);
+ mpz_init (ptoj[1]);
+ mpz_mul (ptoj[1], pp, pp); /* ptoj[1] = pp^2 */
+ size_ptoj[1] = mpz_sizeinbase (ptoj[1], 2);
+
+ mpz_mul_2exp (T[0], T[0], r);
+ mpz_sub (T[0], T[0], pp); /* 6*2^r - pp = 6*2^r*(1 - x^2/6) */
+ log2_nb_terms[0] = 1;
+
+ /* already take into account the factor x=p/2^r in sin(x) = x * (...) */
+ mult[0] = r - mpz_sizeinbase (pp, 2) + r0 - mpz_sizeinbase (p, 2);
+ /* we have x^3 < 1/2^mult[0] */
+
+ for (i = 2, k = 0, prec_i_have = mult[0]; prec_i_have < prec; i += 2)
+ {
+ /* i is even here */
+ /* invariant: Q[0]*Q[1]*...*Q[k] equals (2i-1)!,
+ we have already summed terms of index < i
+ in S[0]/Q[0], ..., S[k]/Q[k] */
+ k ++;
+ if (k + 1 >= alloc) /* necessarily k + 1 = alloc */
+ {
+ alloc ++;
+ mpz_init (T[k+1]);
+ mpz_init (Q[k+1]);
+ mpz_init (ptoj[k+1]);
+ mpz_mul (ptoj[k+1], ptoj[k], ptoj[k]); /* pp^(2^(k+1)) */
+ size_ptoj[k+1] = mpz_sizeinbase (ptoj[k+1], 2);
+ }
+ /* for i even, we have Q[k] = (2*i)*(2*i+1), T[k] = 1,
+ then Q[k+1] = (2*i+2)*(2*i+3), T[k+1] = 1,
+ which reduces to T[k] = (2*i+2)*(2*i+3)*2^r-pp,
+ Q[k] = (2*i)*(2*i+1)*(2*i+2)*(2*i+3). */
+ log2_nb_terms[k] = 1;
+ mpz_set_ui (Q[k], (2 * i + 2) * (2 * i + 3));
+ mpz_mul_2exp (T[k], Q[k], r);
+ mpz_sub (T[k], T[k], pp);
+ mpz_mul_ui (Q[k], Q[k], (2 * i) * (2 * i + 1));
+ /* the next term of the series is divided by Q[k] and multiplied
+ by pp^2/2^(2r), thus the mult. factor < 1/2^mult[k] */
+ mult[k] = mpz_sizeinbase (Q[k], 2) + 2 * r - size_ptoj[1] - 1;
+ /* the absolute contribution of the next term is 1/2^accu[k] */
+ accu[k] = (k == 0) ? mult[k] : mult[k] + accu[k-1];
+ prec_i_have = accu[k]; /* the current term is < 1/2^accu[k] */
+ j = (i + 2) / 2;
+ l = 1;
+ while ((j & 1) == 0) /* combine and reduce */
+ {
+ mpz_mul (T[k], T[k], ptoj[l]);
+ mpz_mul (T[k-1], T[k-1], Q[k]);
+ mpz_mul_2exp (T[k-1], T[k-1], r << l);
+ mpz_add (T[k-1], T[k-1], T[k]);
+ mpz_mul (Q[k-1], Q[k-1], Q[k]);
+ log2_nb_terms[k-1] ++; /* number of terms in S[k-1]
+ is a power of 2 by construction */
+ prec_i_have = mpz_sizeinbase (Q[k], 2);
+ mult[k-1] += prec_i_have + (r << l) - size_ptoj[l] - 1;
+ accu[k-1] = (k == 1) ? mult[k-1] : mult[k-1] + accu[k-2];
+ prec_i_have = accu[k-1];
+ l ++;
+ j >>= 1;
+ k --;
+ }
+ }
+
+ /* accumulate all products in T[0] and Q[0]. Warning: contrary to above,
+ here we do not have log2_nb_terms[k-1] = log2_nb_terms[k]+1. */
+ l = 0; /* number of accumulated terms in the right part T[k]/Q[k] */
+ while (k > 0)
+ {
+ j = log2_nb_terms[k-1];
+ mpz_mul (T[k], T[k], ptoj[j]);
+ mpz_mul (T[k-1], T[k-1], Q[k]);
+ l += 1 << log2_nb_terms[k];
+ mpz_mul_2exp (T[k-1], T[k-1], r * l);
+ mpz_add (T[k-1], T[k-1], T[k]);
+ mpz_mul (Q[k-1], Q[k-1], Q[k]);
+ k--;
+ }
+
+ l = r0 + r * (i - 1); /* implicit multiplier 2^r for Q0 */
+ /* at this point T[0]/(2^l*Q[0]) is an approximation of sin(x) where the 1st
+ neglected term has contribution < 1/2^prec, thus since the series has
+ alternate signs, the error is < 1/2^prec */
+
+ /* we truncate Q0 to prec bits: the relative error is at most 2^(1-prec),
+ which means that Q0 = Q[0] * (1+theta) with |theta| <= 2^(1-prec)
+ [up to a power of two] */
+ l += reduce (Q0, Q[0], prec);
+ l -= reduce (T[0], T[0], prec);
+ /* multiply by x = p/2^l */
+ mpz_mul (S0, T[0], p);
+ l -= reduce (S0, S0, prec); /* S0 = T[0] * (1 + theta)^2 up to power of 2 */
+ /* sin(X) ~ S0/Q0*(1 + theta)^3 + err with |theta| <= 2^(1-prec) and
+ |err| <= 2^(-prec), thus since |S0/Q0| <= 1:
+ |sin(X) - S0/Q0| <= 4*|theta*S0/Q0| + |err| <= 9*2^(-prec) */
+
+ mpz_clear (pp);
+ for (j = 0; j < alloc; j ++)
+ {
+ mpz_clear (T[j]);
+ mpz_clear (Q[j]);
+ mpz_clear (ptoj[j]);
+ }
+
+ /* compute cos(X) from sin(X): sqrt(1-(S/Q)^2) = sqrt(Q^2-S^2)/Q
+ = sqrt(Q0^2*2^(2l)-S0^2)/Q0.
+ Write S/Q = sin(X) + eps with |eps| <= 9*2^(-prec),
+ then sqrt(Q^2-S^2) = sqrt(Q^2-Q^2*(sin(X)+eps)^2)
+ = sqrt(Q^2*cos(X)^2-Q^2*(2*sin(X)*eps+eps^2))
+ = sqrt(Q^2*cos(X)^2-Q^2*eps1) with |eps1|<=9*2^(-prec)
+ [using X<=1/2 and eps<=9*2^(-prec) and prec>=10]
+
+ Since we truncate the square root, we get:
+ sqrt(Q^2*cos(X)^2-Q^2*eps1)+eps2 with |eps2|<1
+ = Q*sqrt(cos(X)^2-eps1)+eps2
+ = Q*cos(X)*(1+eps3)+eps2 with |eps3| <= 6*2^(-prec)
+ = Q*cos(X)*(1+eps3+eps2/(Q*cos(X)))
+ = Q*cos(X)*(1+eps4) with |eps4| <= 9*2^(-prec)
+ since |Q| >= 2^(prec-1) */
+ /* we assume that Q0*2^l >= 2^(prec-1) */
+ MPFR_ASSERTN(l + mpz_sizeinbase (Q0, 2) >= prec);
+ mpz_mul (C0, Q0, Q0);
+ mpz_mul_2exp (C0, C0, 2 * l);
+ mpz_submul (C0, S0, S0);
+ mpz_sqrt (C0, C0);
+
+ return l;
+}
+
+/* Put in s and c approximations of sin(x) and cos(x) respectively.
+ Assumes 0 < x < Pi/4 and PREC(s) = PREC(c) >= 10.
+ Return err such that the relative error is bounded by 2^err ulps.
+*/
+static int
+sincos_aux (mpfr_t s, mpfr_t c, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t prec_s, sh;
+ mpz_t Q, S, C, Q2, S2, C2, y;
+ mpfr_t x2;
+ unsigned long l, l2, j, err;
+
+ MPFR_ASSERTD(MPFR_PREC(s) == MPFR_PREC(c));
+
+ prec_s = MPFR_PREC(s);
+
+ mpfr_init2 (x2, MPFR_PREC(x));
+ mpz_init (Q);
+ mpz_init (S);
+ mpz_init (C);
+ mpz_init (Q2);
+ mpz_init (S2);
+ mpz_init (C2);
+ mpz_init (y);
+
+ mpfr_set (x2, x, MPFR_RNDN); /* exact */
+ mpz_set_ui (Q, 1);
+ l = 0;
+ mpz_set_ui (S, 0); /* sin(0) = S/(2^l*Q), exact */
+ mpz_set_ui (C, 1); /* cos(0) = C/(2^l*Q), exact */
+
+ /* Invariant: x = X + x2/2^(sh-1), where the part X was already treated,
+ S/(2^l*Q) ~ sin(X), C/(2^l*Q) ~ cos(X), and x2/2^(sh-1) < Pi/4.
+ 'sh-1' is the number of already shifted bits in x2.
+ */
+
+ for (sh = 1, j = 0; mpfr_cmp_ui (x2, 0) != 0 && sh <= prec_s; sh <<= 1, j++)
+ {
+ if (sh > prec_s / 2) /* sin(x) = x + O(x^3), cos(x) = 1 + O(x^2) */
+ {
+ l2 = -mpfr_get_z_2exp (S2, x2); /* S2/2^l2 = x2 */
+ l2 += sh - 1;
+ mpz_set_ui (Q2, 1);
+ mpz_set_ui (C2, 1);
+ mpz_mul_2exp (C2, C2, l2);
+ mpfr_set_ui (x2, 0, MPFR_RNDN);
+ }
+ else
+ {
+ /* y <- trunc(x2 * 2^sh) = trunc(x * 2^(2*sh-1)) */
+ mpfr_mul_2exp (x2, x2, sh, MPFR_RNDN); /* exact */
+ mpfr_get_z (y, x2, MPFR_RNDZ); /* round towards zero: now
+ 0 <= x2 < 2^sh, thus
+ 0 <= x2/2^(sh-1) < 2^(1-sh) */
+ if (mpz_cmp_ui (y, 0) == 0)
+ continue;
+ mpfr_sub_z (x2, x2, y, MPFR_RNDN); /* should be exact */
+ l2 = sin_bs_aux (Q2, S2, C2, y, 2 * sh - 1, prec_s);
+ /* we now have |S2/Q2/2^l2 - sin(X)| <= 9*2^(prec_s)
+ and |C2/Q2/2^l2 - cos(X)| <= 6*2^(prec_s), with X=y/2^(2sh-1) */
+ }
+ if (sh == 1) /* S=0, C=1 */
+ {
+ l = l2;
+ mpz_swap (Q, Q2);
+ mpz_swap (S, S2);
+ mpz_swap (C, C2);
+ }
+ else
+ {
+ /* s <- s*c2+c*s2, c <- c*c2-s*s2, using Karatsuba:
+ a = s+c, b = s2+c2, t = a*b, d = s*s2, e = c*c2,
+ s <- t - d - e, c <- e - d */
+ mpz_add (y, S, C); /* a */
+ mpz_mul (C, C, C2); /* e */
+ mpz_add (C2, C2, S2); /* b */
+ mpz_mul (S2, S, S2); /* d */
+ mpz_mul (y, y, C2); /* a*b */
+ mpz_sub (S, y, S2); /* t - d */
+ mpz_sub (S, S, C); /* t - d - e */
+ mpz_sub (C, C, S2); /* e - d */
+ mpz_mul (Q, Q, Q2);
+ /* after j loops, the error is <= (11j-2)*2^(prec_s) */
+ l += l2;
+ /* reduce Q to prec_s bits */
+ l += reduce (Q, Q, prec_s);
+ /* reduce S,C to prec_s bits, error <= 11*j*2^(prec_s) */
+ l -= reduce2 (S, C, prec_s);
+ }
+ }
+
+ j = 11 * j;
+ for (err = 0; j > 1; j = (j + 1) / 2, err ++);
+
+ mpfr_set_z (s, S, MPFR_RNDN);
+ mpfr_div_z (s, s, Q, MPFR_RNDN);
+ mpfr_div_2exp (s, s, l, MPFR_RNDN);
+
+ mpfr_set_z (c, C, MPFR_RNDN);
+ mpfr_div_z (c, c, Q, MPFR_RNDN);
+ mpfr_div_2exp (c, c, l, MPFR_RNDN);
+
+ mpz_clear (Q);
+ mpz_clear (S);
+ mpz_clear (C);
+ mpz_clear (Q2);
+ mpz_clear (S2);
+ mpz_clear (C2);
+ mpz_clear (y);
+ mpfr_clear (x2);
+ return err;
+}
+
+/* Assumes x is neither NaN, +/-Inf, nor +/- 0.
+ One of s and c might be NULL, in which case the corresponding value is
+ not computed.
+ Assumes s differs from c.
+ */
+int
+mpfr_sincos_fast (mpfr_t s, mpfr_t c, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ int inexs, inexc;
+ mpfr_t x_red, ts, tc;
+ mpfr_prec_t w;
+ mpfr_exp_t err, errs, errc;
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_ASSERTN(s != c);
+ if (s == NULL)
+ w = MPFR_PREC(c);
+ else if (c == NULL)
+ w = MPFR_PREC(s);
+ else
+ w = MPFR_PREC(s) >= MPFR_PREC(c) ? MPFR_PREC(s) : MPFR_PREC(c);
+ w += MPFR_INT_CEIL_LOG2(w) + 9; /* ensures w >= 10 (needed by sincos_aux) */
+ mpfr_init2 (ts, w);
+ mpfr_init2 (tc, w);
+
+ MPFR_ZIV_INIT (loop, w);
+ for (;;)
+ {
+ /* if 0 < x <= Pi/4, we can call sincos_aux directly */
+ if (MPFR_IS_POS(x) && mpfr_cmp_ui_2exp (x, 1686629713, -31) <= 0)
+ {
+ err = sincos_aux (ts, tc, x, MPFR_RNDN);
+ }
+ /* if -Pi/4 <= x < 0, use sin(-x)=-sin(x) */
+ else if (MPFR_IS_NEG(x) && mpfr_cmp_si_2exp (x, -1686629713, -31) >= 0)
+ {
+ mpfr_init2 (x_red, MPFR_PREC(x));
+ mpfr_neg (x_red, x, rnd); /* exact */
+ err = sincos_aux (ts, tc, x_red, MPFR_RNDN);
+ mpfr_neg (ts, ts, MPFR_RNDN);
+ mpfr_clear (x_red);
+ }
+ else /* argument reduction is needed */
+ {
+ long q;
+ mpfr_t pi;
+ int neg = 0;
+
+ mpfr_init2 (x_red, w);
+ mpfr_init2 (pi, (MPFR_EXP(x) > 0) ? w + MPFR_EXP(x) : w);
+ mpfr_const_pi (pi, MPFR_RNDN);
+ mpfr_div_2exp (pi, pi, 1, MPFR_RNDN); /* Pi/2 */
+ mpfr_remquo (x_red, &q, x, pi, MPFR_RNDN);
+ /* x = q * (Pi/2 + eps1) + x_red + eps2,
+ where |eps1| <= 1/2*ulp(Pi/2) = 2^(-w-MAX(0,EXP(x))),
+ and eps2 <= 1/2*ulp(x_red) <= 1/2*ulp(Pi/2) = 2^(-w)
+ Since |q| <= x/(Pi/2) <= |x|, we have
+ q*|eps1| <= 2^(-w), thus
+ |x - q * Pi/2 - x_red| <= 2^(1-w) */
+ /* now -Pi/4 <= x_red <= Pi/4: if x_red < 0, consider -x_red */
+ if (MPFR_IS_NEG(x_red))
+ {
+ mpfr_neg (x_red, x_red, MPFR_RNDN);
+ neg = 1;
+ }
+ err = sincos_aux (ts, tc, x_red, MPFR_RNDN);
+ err ++; /* to take into account the argument reduction */
+ if (neg) /* sin(-x) = -sin(x), cos(-x) = cos(x) */
+ mpfr_neg (ts, ts, MPFR_RNDN);
+ if (q & 2) /* sin(x+Pi) = -sin(x), cos(x+Pi) = -cos(x) */
+ {
+ mpfr_neg (ts, ts, MPFR_RNDN);
+ mpfr_neg (tc, tc, MPFR_RNDN);
+ }
+ if (q & 1) /* sin(x+Pi/2) = cos(x), cos(x+Pi/2) = -sin(x) */
+ {
+ mpfr_neg (ts, ts, MPFR_RNDN);
+ mpfr_swap (ts, tc);
+ }
+ mpfr_clear (x_red);
+ mpfr_clear (pi);
+ }
+ /* adjust errors with respect to absolute values */
+ errs = err - MPFR_EXP(ts);
+ errc = err - MPFR_EXP(tc);
+ if ((s == NULL || MPFR_CAN_ROUND (ts, w - errs, MPFR_PREC(s), rnd)) &&
+ (c == NULL || MPFR_CAN_ROUND (tc, w - errc, MPFR_PREC(c), rnd)))
+ break;
+ MPFR_ZIV_NEXT (loop, w);
+ mpfr_set_prec (ts, w);
+ mpfr_set_prec (tc, w);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexs = (s == NULL) ? 0 : mpfr_set (s, ts, rnd);
+ inexc = (c == NULL) ? 0 : mpfr_set (c, tc, rnd);
+
+ mpfr_clear (ts);
+ mpfr_clear (tc);
+ return INEX(inexs,inexc);
+}
diff --git a/mpfr/src/sinh.c b/mpfr/src/sinh.c
new file mode 100644
index 0000000000..0349036afd
--- /dev/null
+++ b/mpfr/src/sinh.c
@@ -0,0 +1,184 @@
+/* mpfr_sinh -- hyperbolic sine
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+ /* The computation of sinh is done by
+ sinh(x) = 1/2 [e^(x)-e^(-x)] */
+
+int
+mpfr_sinh (mpfr_ptr y, mpfr_srcptr xt, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t x;
+ int inexact;
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (xt), mpfr_log_prec, xt, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (xt)))
+ {
+ if (MPFR_IS_NAN (xt))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (xt))
+ {
+ MPFR_SET_INF (y);
+ MPFR_SET_SAME_SIGN (y, xt);
+ MPFR_RET (0);
+ }
+ else /* xt is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (xt));
+ MPFR_SET_ZERO (y); /* sinh(0) = 0 */
+ MPFR_SET_SAME_SIGN (y, xt);
+ MPFR_RET (0);
+ }
+ }
+
+ /* sinh(x) = x + x^3/6 + ... so the error is < 2^(3*EXP(x)-2) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, xt, -2 * MPFR_GET_EXP(xt), 2, 1,
+ rnd_mode, {});
+
+ MPFR_TMP_INIT_ABS (x, xt);
+
+ {
+ mpfr_t t, ti;
+ mpfr_exp_t d;
+ mpfr_prec_t Nt; /* Precision of the intermediary variable */
+ long int err; /* Precision of error */
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_GROUP_DECL (group);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* compute the precision of intermediary variable */
+ Nt = MAX (MPFR_PREC (x), MPFR_PREC (y));
+ /* the optimal number of bits : see algorithms.ps */
+ Nt = Nt + MPFR_INT_CEIL_LOG2 (Nt) + 4;
+ /* If x is near 0, exp(x) - 1/exp(x) = 2*x+x^3/3+O(x^5) */
+ if (MPFR_GET_EXP (x) < 0)
+ Nt -= 2*MPFR_GET_EXP (x);
+
+ /* initialise of intermediary variables */
+ MPFR_GROUP_INIT_2 (group, Nt, t, ti);
+
+ /* First computation of sinh */
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ /* compute sinh */
+ MPFR_BLOCK (flags, mpfr_exp (t, x, MPFR_RNDD));
+ if (MPFR_OVERFLOW (flags))
+ /* exp(x) does overflow */
+ {
+ /* sinh(x) = 2 * sinh(x/2) * cosh(x/2) */
+ mpfr_div_2ui (ti, x, 1, MPFR_RNDD); /* exact */
+
+ /* t <- cosh(x/2): error(t) <= 1 ulp(t) */
+ MPFR_BLOCK (flags, mpfr_cosh (t, ti, MPFR_RNDD));
+ if (MPFR_OVERFLOW (flags))
+ /* when x>1 we have |sinh(x)| >= cosh(x/2), so sinh(x)
+ overflows too */
+ {
+ inexact = mpfr_overflow (y, rnd_mode, MPFR_SIGN (xt));
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
+ break;
+ }
+
+ /* ti <- sinh(x/2): , error(ti) <= 1 ulp(ti)
+ cannot overflow because 0 < sinh(x) < cosh(x) when x > 0 */
+ mpfr_sinh (ti, ti, MPFR_RNDD);
+
+ /* multiplication below, error(t) <= 5 ulp(t) */
+ MPFR_BLOCK (flags, mpfr_mul (t, t, ti, MPFR_RNDD));
+ if (MPFR_OVERFLOW (flags))
+ {
+ inexact = mpfr_overflow (y, rnd_mode, MPFR_SIGN (xt));
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
+ break;
+ }
+
+ /* doubling below, exact */
+ MPFR_BLOCK (flags, mpfr_mul_2ui (t, t, 1, MPFR_RNDN));
+ if (MPFR_OVERFLOW (flags))
+ {
+ inexact = mpfr_overflow (y, rnd_mode, MPFR_SIGN (xt));
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
+ break;
+ }
+
+ /* we have lost at most 3 bits of precision */
+ err = Nt - 3;
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, MPFR_PREC (y),
+ rnd_mode)))
+ {
+ inexact = mpfr_set4 (y, t, rnd_mode, MPFR_SIGN (xt));
+ break;
+ }
+ err = Nt; /* double the precision */
+ }
+ else
+ {
+ d = MPFR_GET_EXP (t);
+ mpfr_ui_div (ti, 1, t, MPFR_RNDU); /* 1/exp(x) */
+ mpfr_sub (t, t, ti, MPFR_RNDN); /* exp(x) - 1/exp(x) */
+ mpfr_div_2ui (t, t, 1, MPFR_RNDN); /* 1/2(exp(x) - 1/exp(x)) */
+
+ /* it may be that t is zero (in fact, it can only occur when te=1,
+ and thus ti=1 too) */
+ if (MPFR_IS_ZERO (t))
+ err = Nt; /* double the precision */
+ else
+ {
+ /* calculation of the error */
+ d = d - MPFR_GET_EXP (t) + 2;
+ /* error estimate: err = Nt-(__gmpfr_ceil_log2(1+pow(2,d)));*/
+ err = Nt - (MAX (d, 0) + 1);
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (t, err, MPFR_PREC (y),
+ rnd_mode)))
+ {
+ inexact = mpfr_set4 (y, t, rnd_mode, MPFR_SIGN (xt));
+ break;
+ }
+ }
+ }
+
+ /* actualisation of the precision */
+ Nt += err;
+ MPFR_ZIV_NEXT (loop, Nt);
+ MPFR_GROUP_REPREC_2 (group, Nt, t, ti);
+ }
+ MPFR_ZIV_FREE (loop);
+ MPFR_GROUP_CLEAR (group);
+ MPFR_SAVE_EXPO_FREE (expo);
+ }
+
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/sinh_cosh.c b/mpfr/src/sinh_cosh.c
new file mode 100644
index 0000000000..af4fede25f
--- /dev/null
+++ b/mpfr/src/sinh_cosh.c
@@ -0,0 +1,161 @@
+/* mpfr_sinh_cosh -- hyperbolic sine and cosine
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#define INEXPOS(y) ((y) == 0 ? 0 : (((y) > 0) ? 1 : 2))
+#define INEX(y,z) (INEXPOS(y) | (INEXPOS(z) << 2))
+
+ /* The computations are done by
+ cosh(x) = 1/2 [e^(x)+e^(-x)]
+ sinh(x) = 1/2 [e^(x)-e^(-x)]
+ Adapted from mpfr_sinh.c */
+
+int
+mpfr_sinh_cosh (mpfr_ptr sh, mpfr_ptr ch, mpfr_srcptr xt, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t x;
+ int inexact_sh, inexact_ch;
+
+ MPFR_ASSERTN (sh != ch);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (xt), mpfr_log_prec, xt, rnd_mode),
+ ("sh[%Pu]=%.*Rg ch[%Pu]=%.*Rg",
+ mpfr_get_prec (sh), mpfr_log_prec, sh,
+ mpfr_get_prec (ch), mpfr_log_prec, ch));
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (xt)))
+ {
+ if (MPFR_IS_NAN (xt))
+ {
+ MPFR_SET_NAN (ch);
+ MPFR_SET_NAN (sh);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (xt))
+ {
+ MPFR_SET_INF (sh);
+ MPFR_SET_SAME_SIGN (sh, xt);
+ MPFR_SET_INF (ch);
+ MPFR_SET_POS (ch);
+ MPFR_RET (0);
+ }
+ else /* xt is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (xt));
+ MPFR_SET_ZERO (sh); /* sinh(0) = 0 */
+ MPFR_SET_SAME_SIGN (sh, xt);
+ inexact_sh = 0;
+ inexact_ch = mpfr_set_ui (ch, 1, rnd_mode); /* cosh(0) = 1 */
+ return INEX(inexact_sh,inexact_ch);
+ }
+ }
+
+ /* Warning: if we use MPFR_FAST_COMPUTE_IF_SMALL_INPUT here, make sure
+ that the code also works in case of overlap (see sin_cos.c) */
+
+ MPFR_TMP_INIT_ABS (x, xt);
+
+ {
+ mpfr_t s, c, ti;
+ mpfr_exp_t d;
+ mpfr_prec_t N; /* Precision of the intermediary variables */
+ long int err; /* Precision of error */
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_GROUP_DECL (group);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* compute the precision of intermediary variable */
+ N = MPFR_PREC (ch);
+ N = MAX (N, MPFR_PREC (sh));
+ /* the optimal number of bits : see algorithms.ps */
+ N = N + MPFR_INT_CEIL_LOG2 (N) + 4;
+
+ /* initialise of intermediary variables */
+ MPFR_GROUP_INIT_3 (group, N, s, c, ti);
+
+ /* First computation of sinh_cosh */
+ MPFR_ZIV_INIT (loop, N);
+ for (;;)
+ {
+ MPFR_BLOCK_DECL (flags);
+
+ /* compute sinh_cosh */
+ MPFR_BLOCK (flags, mpfr_exp (s, x, MPFR_RNDD));
+ if (MPFR_OVERFLOW (flags))
+ /* exp(x) does overflow */
+ {
+ /* since cosh(x) >= exp(x), cosh(x) overflows too */
+ inexact_ch = mpfr_overflow (ch, rnd_mode, MPFR_SIGN_POS);
+ /* sinh(x) may be representable */
+ inexact_sh = mpfr_sinh (sh, xt, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
+ break;
+ }
+ d = MPFR_GET_EXP (s);
+ mpfr_ui_div (ti, 1, s, MPFR_RNDU); /* 1/exp(x) */
+ mpfr_add (c, s, ti, MPFR_RNDU); /* exp(x) + 1/exp(x) */
+ mpfr_sub (s, s, ti, MPFR_RNDN); /* exp(x) - 1/exp(x) */
+ mpfr_div_2ui (c, c, 1, MPFR_RNDN); /* 1/2(exp(x) + 1/exp(x)) */
+ mpfr_div_2ui (s, s, 1, MPFR_RNDN); /* 1/2(exp(x) - 1/exp(x)) */
+
+ /* it may be that s is zero (in fact, it can only occur when exp(x)=1,
+ and thus ti=1 too) */
+ if (MPFR_IS_ZERO (s))
+ err = N; /* double the precision */
+ else
+ {
+ /* calculation of the error */
+ d = d - MPFR_GET_EXP (s) + 2;
+ /* error estimate: err = N-(__gmpfr_ceil_log2(1+pow(2,d)));*/
+ err = N - (MAX (d, 0) + 1);
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, err, MPFR_PREC (sh),
+ rnd_mode) && \
+ MPFR_CAN_ROUND (c, err, MPFR_PREC (ch),
+ rnd_mode)))
+ {
+ inexact_sh = mpfr_set4 (sh, s, rnd_mode, MPFR_SIGN (xt));
+ inexact_ch = mpfr_set (ch, c, rnd_mode);
+ break;
+ }
+ }
+ /* actualisation of the precision */
+ N += err;
+ MPFR_ZIV_NEXT (loop, N);
+ MPFR_GROUP_REPREC_3 (group, N, s, c, ti);
+ }
+ MPFR_ZIV_FREE (loop);
+ MPFR_GROUP_CLEAR (group);
+ MPFR_SAVE_EXPO_FREE (expo);
+ }
+
+ /* now, let's raise the flags if needed */
+ inexact_sh = mpfr_check_range (sh, inexact_sh, rnd_mode);
+ inexact_ch = mpfr_check_range (ch, inexact_ch, rnd_mode);
+
+ return INEX(inexact_sh,inexact_ch);
+}
diff --git a/mpfr/src/sparc64/mparam.h b/mpfr/src/sparc64/mparam.h
new file mode 100644
index 0000000000..4de32afa1c
--- /dev/null
+++ b/mpfr/src/sparc64/mparam.h
@@ -0,0 +1,233 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2011-07-31, gcc 3.3.5 */
+/* gcc64.fsffrance.org (sparc64) with gmp 5.0.2 */
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,0,-1,0,-1,-1,-1,7,-1,9,9,11,11,11,13, \
+ 11,13,13,15,15,17,15,19,17,17,19,19,19,19,21,21, \
+ 23,23,23,23,25,27,23,30,30,30,30,30,30,30,34,34, \
+ 34,34,34,34,38,38,38,38,38,38,42,42,41,42,42,42, \
+ 42,42,42,46,46,46,46,46,46,50,50,50,50,50,50,60, \
+ 60,60,60,60,60,60,60,60,60,68,60,68,68,60,68,68, \
+ 68,68,68,68,68,68,68,68,76,76,76,76,76,76,76,76, \
+ 76,76,76,76,84,76,84,84,84,76,84,84,84,84,84,84, \
+ 84,84,84,84,84,84,92,92,92,92,92,92,92,84,92,92, \
+ 92,92,100,100,100,100,100,100,100,100,100,100,120,100,120,120, \
+ 120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, \
+ 120,120,119,120,119,120,120,136,136,136,136,136,136,136,136,136, \
+ 136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,152, \
+ 152,152,152,136,152,152,152,136,152,136,152,152,136,152,152,152, \
+ 152,152,152,136,152,152,168,168,168,201,168,168,201,201,201,201, \
+ 201,201,201,201,201,200,201,200,201,200,201,201,201,201,201,201, \
+ 201,201,201,201,201,200,201,201,201,201,201,201,201,201,201,201, \
+ 201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, \
+ 201,201,201,201,200,201,200,201,201,201,201,201,201,201,201,201, \
+ 225,224,225,225,225,225,225,224,225,224,225,224,225,225,225,282, \
+ 225,282,282,282,282,282,282,294,294,294,294,294,294,294,294,294, \
+ 282,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, \
+ 294,294,293,294,294,294,294,294,294,294,294,294,294,294,294,294, \
+ 294,294,294,294,293,294,294,294,294,294,294,294,294,294,293,294, \
+ 294,294,294,294,294,294,294,294,294,294,294,294,294,318,294,318, \
+ 294,294,294,360,359,360,360,358,360,360,360,360,359,360,360,360, \
+ 360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, \
+ 360,360,360,360,360,360,359,360,360,360,360,360,360,360,360,360, \
+ 360,360,360,360,360,360,360,358,360,360,360,360,360,360,354,360, \
+ 360,360,360,360,360,360,360,392,360,360,392,392,360,392,391,392, \
+ 391,392,392,392,391,392,391,392,354,392,391,392,391,392,391,392, \
+ 391,392,391,392,391,392,391,392,392,392,391,392,392,392,392,392, \
+ 424,392,391,392,424,392,424,424,424,392,424,424,424,424,424,472, \
+ 424,424,424,472,424,472,472,472,472,472,472,472,472,472,472,471, \
+ 472,472,472,472,472,472,472,472,472,472,472,471,472,472,472,471, \
+ 472,472,472,472,472,472,472,472,472,472,472,472,472,472,471,472, \
+ 472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, \
+ 472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, \
+ 472,472,472,472,472,471,472,472,472,472,472,472,472,472,472,472, \
+ 472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, \
+ 472,472,472,536,536,536,536,536,536,528,536,536,536,536,536,536, \
+ 536,536,536,536,536,536,544,536,536,536,536,600,536,599,600,600, \
+ 599,599,600,600,600,600,600,600,599,600,600,600,600,599,600,600, \
+ 600,600,600,600,600,599,600,599,600,600,600,599,600,600,600,600, \
+ 600,599,600,599,600,600,600,599,600,600,600,600,600,600,600,600, \
+ 600,600,600,599,599,600,600,600,600,600,600,600,600,600,600,600, \
+ 600,600,600,600,600,599,600,600,599,600,599,600,599,600,600,600, \
+ 599,600,600,600,599,600,600,664,600,664,600,600,600,600,600,663, \
+ 599,664,600,664,600,664,664,664,664,664,664,664,663,664,664,664, \
+ 663,664,664,664,663,664,663,664,664,664,663,664,663,664,664,664, \
+ 664,664,664,664,664,664,663,664,664,663,664,664,664,664,664,664, \
+ 663,663,664,664,664,664,663,664,663,664,663,664,663,664,663,664, \
+ 663,664,663,664,664,664,664,664,664,664,663,664,663,664,664,664, \
+ 664,664,664,664,664,664,664,664,663,728,663,728,728,727,728,728, \
+ 728,728,728,728,728,728,728,728,727,728,728,728,727,728,728,728, \
+ 728,728,728,728,727,728,727,728,728,728,727,728,727,728,728,728, \
+ 727,728,728,728,727,728,728,728,728,728,727,728,728,728,728,728, \
+ 727,728,728,728,727,728,792,792,727,728,727,728,791,792,728,728, \
+ 728,728,728,728,728,728,792,792,727,792,792,792,792,792,791,792, \
+ 792,792,792,792,792,792,792,792,792,792,792,792,792,792,791,790, \
+ 791,792,791,792,792,792,791,792,791,792,791,792,791,792,791,792, \
+ 791,792,792,792,791,792,792,792,791,792,792,792,791,792,791,791, \
+ 791,791,791,792,792,791,792,792,791,792,792,792,791,792,792,792, \
+ 792,791,792,792,791,792,792,856,792,792,792,856,792,791,792,856 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,0,-1,5,5,7,7,9,7,9,8,9,10, \
+ 11,10,11,11,13,12,13,13,17,14,16,16,16,16,17,18, \
+ 18,18,19,20,20,22,21,24,22,24,23,24,24,26,26,26, \
+ 28,28,28,30,28,29,30,31,30,31,32,33,32,33,34,35, \
+ 34,35,36,36,36,37,38,40,40,40,40,40,42,43,42,44, \
+ 45,47,50,44,44,44,50,48,50,51,47,48,49,48,49,50, \
+ 51,52,53,52,53,52,53,54,55,56,57,58,59,56,57,58, \
+ 59,58,59,62,61,60,61,62,63,62,63,64,65,64,65,70, \
+ 67,72,72,72,76,74,72,72,74,76,76,76,76,74,80,80, \
+ 74,76,84,80,80,82,80,84,82,84,84,88,84,90,88,82, \
+ 86,88,88,84,84,86,88,88,88,88,88,88,88,88,90,92, \
+ 90,92,92,92,96,94,96,96,96,96,100,96,96,116,98,100, \
+ 98,98,100,100,117,117,118,119,119,120,116,119,120,119,118,119, \
+ 119,119,122,128,120,119,120,119,116,121,120,118,120,125,125,119, \
+ 125,124,131,131,130,131,134,131,132,134,124,125,133,143,137,138, \
+ 131,144,138,137,135,138,130,135,137,143,143,137,137,143,130,138, \
+ 131,140,138,137,136,149,149,142,143,156,149,149,144,154,149,147, \
+ 149,156,149,152,147,147,155,156,149,150,149,146,160,160,163,168, \
+ 167,167,156,166,156,164,156,158,161,172,161,166,167,161,173,164, \
+ 167,174,173,162,171,172,173,176,173,171,165,182,174,174,173,184, \
+ 171,170,174,173,178,176,176,168,179,176,177,182,178,180,191,174, \
+ 186,184,176,192,180,180,173,174,179,185,175,182,184,180,179,178, \
+ 179,180,179,186,185,185,188,184,186,188,186,190,191,191,195,192, \
+ 198,192,194,200,213,197,225,198,201,200,191,210,195,212,224,212, \
+ 213,213,212,212,213,213,221,218,218,224,199,224,219,224,225,225, \
+ 225,222,225,228,229,213,237,228,218,224,234,240,237,240,242,242, \
+ 243,240,242,242,235,228,231,228,237,230,231,236,236,237,336,336, \
+ 336,336,336,336,336,336,336,336,336,336,341,336,336,336,336,336, \
+ 336,336,341,336,336,336,336,342,336,336,342,336,336,336,336,342, \
+ 336,336,336,336,336,336,336,342,336,336,336,336,342,336,336,336, \
+ 336,336,336,336,336,336,336,342,336,336,336,336,342,336,336,342, \
+ 336,336,342,336,336,336,336,336,336,336,342,336,336,336,336,342, \
+ 336,342,342,336,342,342,336,342,336,342,336,336,342,336,336,342, \
+ 336,336,342,336,336,342,336,342,342,342,341,348,342,348,348,348, \
+ 342,342,354,348,354,354,348,336,354,354,354,336,342,360,360,354, \
+ 354,342,360,360,366,366,360,372,354,360,354,360,354,360,360,353, \
+ 336,336,342,360,366,342,360,336,336,342,342,336,336,336,341,341, \
+ 336,336,336,336,342,342,336,342,342,342,342,336,342,342,341,342, \
+ 348,342,342,360,354,348,348,342,354,348,360,348,354,354,353,354, \
+ 354,354,354,456,360,360,456,366,372,366,366,456,354,366,456,456, \
+ 456,378,456,456,455,456,456,456,378,366,390,384,378,378,360,378, \
+ 372,366,378,456,378,464,472,378,472,472,336,456,472,456,456,456, \
+ 472,472,456,456,472,464,456,456,456,342,426,456,426,455,472,456, \
+ 472,472,426,472,348,456,472,456,456,455,456,480,455,456,455,456, \
+ 456,455,456,456,454,456,456,456,456,455,456,456,454,455,456,456, \
+ 456,464,456,456,455,456,455,456,456,464,456,456,472,456,456,464, \
+ 472,472,456,456,455,456,456,456,455,472,479,456,472,472,488,464, \
+ 472,472,471,488,472,472,488,488,472,472,488,456,480,472,456,488, \
+ 472,472,479,463,488,426,456,426,426,426,426,425,455,455,425,456, \
+ 455,455,456,480,455,456,456,456,456,455,456,456,454,456,455,456, \
+ 456,455,456,456,455,455,455,456,456,454,456,456,455,456,456,456, \
+ 456,455,456,456,472,456,456,456,456,455,464,464,472,472,472,464, \
+ 472,472,456,455,472,472,471,456,472,480,456,480,480,480,456,488, \
+ 480,488,488,488,472,472,488,488,472,472,488,480,496,472,456,480, \
+ 496,472,488,456,480,456,456,456,456,488,456,456,488,456,456,456, \
+ 456,455,456,456,455,455,456,464,456,512,456,456,512,472,464,456, \
+ 472,512,456,480,464,480,472,471,472,472,471,479,470,480,471,471, \
+ 472,472,480,488,478,480,488,487,480,480,488,488,568,485,488,488, \
+ 512,488,488,471,568,512,512,512,512,496,511,511,512,512,520,511, \
+ 512,512,520,520,568,512,520,520,512,512,520,520,519,520,519,519, \
+ 520,568,520,536,536,536,536,528,536,528,535,535,534,512,535,512, \
+ 536,536,552,552,536,552,552,520,567,544,552,552,552,568,567,567, \
+ 568,568,567,567,568,568,535,584,568,512,568,567,512,568,567,568, \
+ 576,568,567,584,568,600,584,584,600,568,597,592,591,600,599,599 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,6,7,8,9,10,11,12,13, \
+ 10,10,11,11,13,12,13,13,14,14,15,15,18,17,19,19, \
+ 18,21,19,20,22,21,27,27,22,22,27,28,27,27,27,30, \
+ 27,27,27,27,31,31,30,30,31,31,31,35,34,33,35,35, \
+ 38,37,36,38,39,39,39,37,39,39,43,43,47,42,43,43, \
+ 45,47,54,43,54,54,45,54,54,54,54,55,54,54,55,54, \
+ 54,54,54,54,54,54,54,54,54,54,58,58,60,60,60,60, \
+ 60,60,68,62,60,60,65,68,68,68,68,68,67,68,76,68, \
+ 67,68,67,68,76,76,71,73,76,76,77,76,79,73,79,84, \
+ 76,76,78,76,76,84,84,84,84,83,84,84,92,92,83,84, \
+ 92,92,84,84,92,84,88,108,86,108,108,108,108,108,108,108, \
+ 108,92,108,108,92,108,108,108,120,120,108,108,120,120,120,120, \
+ 120,120,108,108,108,120,108,108,120,108,118,108,108,108,108,120, \
+ 120,120,108,108,120,120,118,120,120,120,120,120,120,120,120,120, \
+ 120,120,120,120,120,120,136,120,120,120,125,136,136,120,136,136, \
+ 136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, \
+ 136,136,136,136,152,136,135,136,152,152,136,136,152,152,152,152, \
+ 152,152,152,152,151,152,152,152,152,152,149,150,152,152,152,152, \
+ 152,152,151,152,152,168,167,168,152,152,167,152,152,152,165,157, \
+ 168,168,167,168,168,184,168,168,168,168,168,168,168,168,168,168, \
+ 168,167,168,168,184,168,168,168,184,184,184,184,184,184,184,184, \
+ 172,184,179,180,184,184,184,184,184,184,176,180,184,184,216,216, \
+ 184,184,184,216,184,184,216,184,184,216,184,216,216,184,216,216, \
+ 240,240,216,216,240,240,216,216,240,240,239,214,240,240,216,240, \
+ 240,240,238,240,240,240,216,240,240,239,240,216,240,240,216,238, \
+ 240,240,240,216,240,240,240,238,240,240,239,240,240,240,240,240, \
+ 240,239,240,240,240,240,240,240,240,240,239,238,240,240,240,240, \
+ 240,240,240,238,240,240,240,240,240,240,239,238,240,240,240,240, \
+ 240,240,238,238,240,240,240,240,240,239,239,240,240,240,240,240, \
+ 240,240,240,240,240,240,271,240,240,240,240,271,240,240,272,272, \
+ 272,272,272,272,272,272,272,272,270,271,272,272,272,272,272,272, \
+ 272,271,272,272,272,269,272,272,272,270,269,272,272,272,272,272, \
+ 272,272,272,269,272,272,272,272,304,267,271,272,272,272,272,272, \
+ 271,272,272,272,272,272,271,272,272,270,272,272,272,272,273,301, \
+ 304,304,300,301,304,303,304,304,304,303,303,304,304,304,303,301, \
+ 304,304,303,298,304,304,303,304,304,303,301,304,304,303,301,302, \
+ 304,303,304,304,304,304,301,304,304,304,301,302,304,304,301,304, \
+ 304,303,303,304,304,304,304,304,304,304,303,304,304,304,336,336, \
+ 336,335,336,334,336,336,336,336,336,336,336,336,336,336,336,336, \
+ 336,336,334,336,336,336,336,336,336,336,335,336,336,336,336,336, \
+ 336,336,336,336,336,328,336,336,336,336,335,336,336,336,336,336, \
+ 336,368,336,334,336,336,336,336,336,336,336,336,336,336,396,400, \
+ 398,384,368,400,384,399,399,400,368,368,368,400,368,368,368,400, \
+ 400,400,399,400,400,376,400,400,400,367,399,400,368,367,400,366, \
+ 367,368,400,366,368,368,365,368,368,368,400,399,400,400,368,399, \
+ 368,368,366,368,368,368,400,368,368,368,368,368,368,368,400,400, \
+ 396,400,397,374,400,399,400,400,400,400,397,398,400,401,400,400, \
+ 400,400,400,396,399,397,400,400,400,400,400,396,400,401,400,432, \
+ 400,398,399,400,396,396,432,432,400,432,400,396,400,397,399,400, \
+ 400,400,400,396,400,401,432,432,432,399,432,400,400,432,432,432, \
+ 432,432,432,432,432,433,432,432,432,432,432,480,480,432,432,432, \
+ 432,432,432,432,432,432,432,432,432,431,431,432,432,480,432,432, \
+ 480,480,432,478,480,432,432,480,432,432,432,432,480,432,432,432, \
+ 432,432,432,432,480,480,432,432,480,432,432,432,432,432,480,478, \
+ 480,447,477,480,480,480,480,480,480,479,440,444,480,445,448,480, \
+ 480,479,464,464,480,480,480,478,480,480,478,480,480,480,480,480, \
+ 480,479,480,479,480,480,478,480,480,480,478,478,480,480,480,480, \
+ 480,480,480,478,480,480,480,478,480,479,478,480,480,476,480,478, \
+ 480,480,478,478,480,480,480,480,480,479,479,478,480,480,480,480, \
+ 480,479,480,478,480,480,480,480,480,479,543,544,544,480,544,544, \
+ 542,543,544,544,544,540,544,544,544,544,544,542,544,544,544,544, \
+ 542,542,542,542,544,544,544,560,542,542,575,543,544,544,544,542, \
+ 544,575,575,544,544,544,544,544,561,561,543,559,544,560,560,560, \
+ 608,587,573,575,575,608,583,585,560,575,585,575,588,573,608,577 \
+
+#define MPFR_MUL_THRESHOLD 13 /* limbs */
+#define MPFR_SQR_THRESHOLD 11 /* limbs */
+#define MPFR_DIV_THRESHOLD 19 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 1092 /* bits */
+#define MPFR_EXP_THRESHOLD 11053 /* bits */
+#define MPFR_SINCOS_THRESHOLD 25857 /* bits */
+#define MPFR_AI_THRESHOLD1 -19352 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 1476
+#define MPFR_AI_THRESHOLD3 30069
+/* Tuneup completed successfully, took 8167 seconds */
diff --git a/mpfr/src/sqr.c b/mpfr/src/sqr.c
new file mode 100644
index 0000000000..a3748b5612
--- /dev/null
+++ b/mpfr/src/sqr.c
@@ -0,0 +1,112 @@
+/* mpfr_sqr -- Floating square
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_sqr (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ int cc, inexact;
+ mpfr_exp_t ax;
+ mp_limb_t *tmp;
+ mp_limb_t b1;
+ mpfr_prec_t bq;
+ mp_size_t bn, tn;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (b), mpfr_log_prec, b, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (a), mpfr_log_prec, a, inexact));
+
+ /* deal with special cases */
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(b)))
+ {
+ if (MPFR_IS_NAN(b))
+ {
+ MPFR_SET_NAN(a);
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_POS (a);
+ if (MPFR_IS_INF(b))
+ MPFR_SET_INF(a);
+ else
+ ( MPFR_ASSERTD(MPFR_IS_ZERO(b)), MPFR_SET_ZERO(a) );
+ MPFR_RET(0);
+ }
+ ax = 2 * MPFR_GET_EXP (b);
+ bq = MPFR_PREC(b);
+
+ MPFR_ASSERTN (2 * (mpfr_uprec_t) bq <= MPFR_PREC_MAX);
+
+ bn = MPFR_LIMB_SIZE (b); /* number of limbs of b */
+ tn = MPFR_PREC2LIMBS (2 * bq); /* number of limbs of square,
+ 2*bn or 2*bn-1 */
+
+ if (MPFR_UNLIKELY(bn > MPFR_SQR_THRESHOLD))
+ return mpfr_mul (a, b, b, rnd_mode);
+
+ MPFR_TMP_MARK(marker);
+ tmp = MPFR_TMP_LIMBS_ALLOC (2 * bn);
+
+ /* Multiplies the mantissa in temporary allocated space */
+ mpn_sqr_n (tmp, MPFR_MANT(b), bn);
+ b1 = tmp[2 * bn - 1];
+
+ /* now tmp[0]..tmp[2*bn-1] contains the product of both mantissa,
+ with tmp[2*bn-1]>=2^(GMP_NUMB_BITS-2) */
+ b1 >>= GMP_NUMB_BITS - 1; /* msb from the product */
+
+ /* if the mantissas of b and c are uniformly distributed in ]1/2, 1],
+ then their product is in ]1/4, 1/2] with probability 2*ln(2)-1 ~ 0.386
+ and in [1/2, 1] with probability 2-2*ln(2) ~ 0.614 */
+ tmp += 2 * bn - tn; /* +0 or +1 */
+ if (MPFR_UNLIKELY(b1 == 0))
+ mpn_lshift (tmp, tmp, tn, 1); /* tn <= k, so no stack corruption */
+
+ cc = mpfr_round_raw (MPFR_MANT (a), tmp, 2 * bq, 0,
+ MPFR_PREC (a), rnd_mode, &inexact);
+ /* cc = 1 ==> result is a power of two */
+ if (MPFR_UNLIKELY(cc))
+ MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] = MPFR_LIMB_HIGHBIT;
+
+ MPFR_TMP_FREE(marker);
+ {
+ mpfr_exp_t ax2 = ax + (mpfr_exp_t) (b1 - 1 + cc);
+ if (MPFR_UNLIKELY( ax2 > __gmpfr_emax))
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS);
+ if (MPFR_UNLIKELY( ax2 < __gmpfr_emin))
+ {
+ /* In the rounding to the nearest mode, if the exponent of the exact
+ result (i.e. before rounding, i.e. without taking cc into account)
+ is < __gmpfr_emin - 1 or the exact result is a power of 2 (i.e. if
+ both arguments are powers of 2), then round to zero. */
+ if (rnd_mode == MPFR_RNDN &&
+ (ax + (mpfr_exp_t) b1 < __gmpfr_emin || mpfr_powerof2_raw (b)))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN_POS);
+ }
+ MPFR_SET_EXP (a, ax2);
+ MPFR_SET_POS (a);
+ }
+ MPFR_RET (inexact);
+}
diff --git a/mpfr/src/sqrt.c b/mpfr/src/sqrt.c
new file mode 100644
index 0000000000..64a9e025c7
--- /dev/null
+++ b/mpfr/src/sqrt.c
@@ -0,0 +1,231 @@
+/* mpfr_sqrt -- square root of a floating-point number
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode)
+{
+ mp_size_t rsize; /* number of limbs of r (plus 1 if exact limb multiple) */
+ mp_size_t rrsize;
+ mp_size_t usize; /* number of limbs of u */
+ mp_size_t tsize; /* number of limbs of the sqrtrem remainder */
+ mp_size_t k;
+ mp_size_t l;
+ mpfr_limb_ptr rp, rp0;
+ mpfr_limb_ptr up;
+ mpfr_limb_ptr sp;
+ mp_limb_t sticky0; /* truncated part of input */
+ mp_limb_t sticky1; /* truncated part of rp[0] */
+ mp_limb_t sticky;
+ int odd_exp;
+ int sh; /* number of extra bits in rp[0] */
+ int inexact; /* return ternary flag */
+ mpfr_exp_t expr;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (u), mpfr_log_prec, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (r), mpfr_log_prec, r, inexact));
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(u)))
+ {
+ if (MPFR_IS_NAN(u))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_ZERO(u))
+ {
+ /* 0+ or 0- */
+ MPFR_SET_SAME_SIGN(r, u);
+ MPFR_SET_ZERO(r);
+ MPFR_RET(0); /* zero is exact */
+ }
+ else
+ {
+ MPFR_ASSERTD(MPFR_IS_INF(u));
+ /* sqrt(-Inf) = NAN */
+ if (MPFR_IS_NEG(u))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_POS(r);
+ MPFR_SET_INF(r);
+ MPFR_RET(0);
+ }
+ }
+ if (MPFR_UNLIKELY(MPFR_IS_NEG(u)))
+ {
+ MPFR_SET_NAN(r);
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_POS(r);
+
+ MPFR_TMP_MARK (marker);
+ MPFR_UNSIGNED_MINUS_MODULO(sh,MPFR_PREC(r));
+ if (sh == 0 && rnd_mode == MPFR_RNDN)
+ sh = GMP_NUMB_BITS; /* ugly case */
+ rsize = MPFR_LIMB_SIZE(r) + (sh == GMP_NUMB_BITS);
+ /* rsize is the number of limbs of r + 1 if exact limb multiple and rounding
+ to nearest, this is the number of wanted limbs for the square root */
+ rrsize = rsize + rsize;
+ usize = MPFR_LIMB_SIZE(u); /* number of limbs of u */
+ rp0 = MPFR_MANT(r);
+ rp = (sh < GMP_NUMB_BITS) ? rp0 : MPFR_TMP_LIMBS_ALLOC (rsize);
+ up = MPFR_MANT(u);
+ sticky0 = MPFR_LIMB_ZERO; /* truncated part of input */
+ sticky1 = MPFR_LIMB_ZERO; /* truncated part of rp[0] */
+ odd_exp = (unsigned int) MPFR_GET_EXP (u) & 1;
+ inexact = -1; /* return ternary flag */
+
+ sp = MPFR_TMP_LIMBS_ALLOC (rrsize);
+
+ /* copy the most significant limbs of u to {sp, rrsize} */
+ if (MPFR_LIKELY(usize <= rrsize)) /* in case r and u have the same precision,
+ we have indeed rrsize = 2 * usize */
+ {
+ k = rrsize - usize;
+ if (MPFR_LIKELY(k))
+ MPN_ZERO (sp, k);
+ if (odd_exp)
+ {
+ if (MPFR_LIKELY(k))
+ sp[k - 1] = mpn_rshift (sp + k, up, usize, 1);
+ else
+ sticky0 = mpn_rshift (sp, up, usize, 1);
+ }
+ else
+ MPN_COPY (sp + rrsize - usize, up, usize);
+ }
+ else /* usize > rrsize: truncate the input */
+ {
+ k = usize - rrsize;
+ if (odd_exp)
+ sticky0 = mpn_rshift (sp, up + k, rrsize, 1);
+ else
+ MPN_COPY (sp, up + k, rrsize);
+ l = k;
+ while (sticky0 == MPFR_LIMB_ZERO && l != 0)
+ sticky0 = up[--l];
+ }
+
+ /* sticky0 is non-zero iff the truncated part of the input is non-zero */
+
+ /* mpn_rootrem with NULL 2nd argument is faster than mpn_sqrtrem, thus use
+ it if available and if the user asked to use GMP internal functions */
+#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_ROOTREM)
+ tsize = __gmpn_rootrem (rp, NULL, sp, rrsize, 2);
+#else
+ tsize = mpn_sqrtrem (rp, NULL, sp, rrsize);
+#endif
+
+ /* a return value of zero in mpn_sqrtrem indicates a perfect square */
+ sticky = sticky0 || tsize != 0;
+
+ /* truncate low bits of rp[0] */
+ sticky1 = rp[0] & ((sh < GMP_NUMB_BITS) ? MPFR_LIMB_MASK(sh)
+ : ~MPFR_LIMB_ZERO);
+ rp[0] -= sticky1;
+
+ sticky = sticky || sticky1;
+
+ expr = (MPFR_GET_EXP(u) + odd_exp) / 2; /* exact */
+
+ if (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDD || sticky == MPFR_LIMB_ZERO)
+ {
+ inexact = (sticky == MPFR_LIMB_ZERO) ? 0 : -1;
+ goto truncate;
+ }
+ else if (rnd_mode == MPFR_RNDN)
+ {
+ /* if sh < GMP_NUMB_BITS, the round bit is bit (sh-1) of sticky1
+ and the sticky bit is formed by the low sh-1 bits from
+ sticky1, together with the sqrtrem remainder and sticky0. */
+ if (sh < GMP_NUMB_BITS)
+ {
+ if (sticky1 & (MPFR_LIMB_ONE << (sh - 1)))
+ { /* round bit is set */
+ if (sticky1 == (MPFR_LIMB_ONE << (sh - 1)) && tsize == 0
+ && sticky0 == 0)
+ goto even_rule;
+ else
+ goto add_one_ulp;
+ }
+ else /* round bit is zero */
+ goto truncate; /* with the default inexact=-1 */
+ }
+ else /* sh = GMP_NUMB_BITS: the round bit is the most significant bit
+ of rp[0], and the remaining GMP_NUMB_BITS-1 bits contribute to
+ the sticky bit */
+ {
+ if (sticky1 & MPFR_LIMB_HIGHBIT)
+ { /* round bit is set */
+ if (sticky1 == MPFR_LIMB_HIGHBIT && tsize == 0 && sticky0 == 0)
+ goto even_rule;
+ else
+ goto add_one_ulp;
+ }
+ else /* round bit is zero */
+ goto truncate; /* with the default inexact=-1 */
+ }
+ }
+ else /* rnd_mode=GMP_RDNU, necessarily sticky <> 0, thus add 1 ulp */
+ goto add_one_ulp;
+
+ even_rule: /* has to set inexact */
+ if (sh < GMP_NUMB_BITS)
+ inexact = (rp[0] & (MPFR_LIMB_ONE << sh)) ? 1 : -1;
+ else
+ inexact = (rp[1] & MPFR_LIMB_ONE) ? 1 : -1;
+ if (inexact == -1)
+ goto truncate;
+ /* else go through add_one_ulp */
+
+ add_one_ulp:
+ inexact = 1; /* always here */
+ if (sh == GMP_NUMB_BITS)
+ {
+ rp ++;
+ rsize --;
+ sh = 0;
+ }
+ if (mpn_add_1 (rp0, rp, rsize, MPFR_LIMB_ONE << sh))
+ {
+ expr ++;
+ rp[rsize - 1] = MPFR_LIMB_HIGHBIT;
+ }
+ goto end;
+
+ truncate: /* inexact = 0 or -1 */
+ if (sh == GMP_NUMB_BITS)
+ MPN_COPY (rp0, rp + 1, rsize - 1);
+
+ end:
+ MPFR_ASSERTN (expr >= MPFR_EMIN_MIN && expr <= MPFR_EMAX_MAX);
+ MPFR_EXP (r) = expr;
+ MPFR_TMP_FREE(marker);
+
+ return mpfr_check_range (r, inexact, rnd_mode);
+}
diff --git a/mpfr/src/sqrt_ui.c b/mpfr/src/sqrt_ui.c
new file mode 100644
index 0000000000..92d60de500
--- /dev/null
+++ b/mpfr/src/sqrt_ui.c
@@ -0,0 +1,54 @@
+/* mpfr_sqrt_ui -- square root of a machine integer
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_sqrt_ui (mpfr_ptr r, unsigned long u, mpfr_rnd_t rnd_mode)
+{
+ if (u)
+ {
+ mpfr_t uu;
+ mp_limb_t up[1];
+ unsigned long cnt;
+ int inex;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
+ MPFR_ASSERTN (u == (mp_limb_t) u);
+ count_leading_zeros (cnt, (mp_limb_t) u);
+ *up = (mp_limb_t) u << cnt;
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
+ inex = mpfr_sqrt(r, uu, rnd_mode);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range(r, inex, rnd_mode);
+ }
+ else /* sqrt(0) = 0 */
+ {
+ MPFR_SET_ZERO(r);
+ MPFR_SET_POS(r);
+ MPFR_RET(0);
+ }
+}
diff --git a/mpfr/src/stack_interface.c b/mpfr/src/stack_interface.c
new file mode 100644
index 0000000000..25c44da77f
--- /dev/null
+++ b/mpfr/src/stack_interface.c
@@ -0,0 +1,104 @@
+/* mpfr_stack -- initialize a floating-point number with given allocation area
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+#undef mpfr_custom_get_size
+size_t
+mpfr_custom_get_size (mpfr_prec_t prec)
+{
+ return MPFR_PREC2LIMBS (prec) * BYTES_PER_MP_LIMB;
+}
+
+#undef mpfr_custom_init
+void
+mpfr_custom_init (void *mantissa, mpfr_prec_t prec)
+{
+ return ;
+}
+
+#undef mpfr_custom_get_significand
+void *
+mpfr_custom_get_significand (mpfr_srcptr x)
+{
+ return (void*) MPFR_MANT (x);
+}
+
+#undef mpfr_custom_get_exp
+mpfr_exp_t
+mpfr_custom_get_exp (mpfr_srcptr x)
+{
+ return MPFR_EXP (x);
+}
+
+#undef mpfr_custom_move
+void
+mpfr_custom_move (mpfr_ptr x, void *new_position)
+{
+ MPFR_MANT (x) = (mp_limb_t *) new_position;
+}
+
+#undef mpfr_custom_init_set
+void
+mpfr_custom_init_set (mpfr_ptr x, int kind, mpfr_exp_t exp,
+ mpfr_prec_t prec, void *mantissa)
+{
+ mpfr_kind_t t;
+ int s;
+ mpfr_exp_t e;
+
+ if (kind >= 0)
+ {
+ t = (mpfr_kind_t) kind;
+ s = MPFR_SIGN_POS;
+ }
+ else
+ {
+ t = (mpfr_kind_t) -kind;
+ s = MPFR_SIGN_NEG;
+ }
+ MPFR_ASSERTD (t <= MPFR_REGULAR_KIND);
+ e = MPFR_LIKELY (t == MPFR_REGULAR_KIND) ? exp :
+ MPFR_UNLIKELY (t == MPFR_NAN_KIND) ? MPFR_EXP_NAN :
+ MPFR_UNLIKELY (t == MPFR_INF_KIND) ? MPFR_EXP_INF : MPFR_EXP_ZERO;
+
+ MPFR_PREC (x) = prec;
+ MPFR_SET_SIGN (x, s);
+ MPFR_EXP (x) = e;
+ MPFR_MANT (x) = (mp_limb_t*) mantissa;
+ return;
+}
+
+#undef mpfr_custom_get_kind
+int
+mpfr_custom_get_kind (mpfr_srcptr x)
+{
+ if (MPFR_LIKELY (!MPFR_IS_SINGULAR (x)))
+ return (int) MPFR_REGULAR_KIND * MPFR_INT_SIGN (x);
+ if (MPFR_IS_INF (x))
+ return (int) MPFR_INF_KIND * MPFR_INT_SIGN (x);
+ if (MPFR_IS_NAN (x))
+ return (int) MPFR_NAN_KIND;
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ return (int) MPFR_ZERO_KIND * MPFR_INT_SIGN (x);
+}
+
diff --git a/mpfr/src/strtofr.c b/mpfr/src/strtofr.c
new file mode 100644
index 0000000000..5248c10ca0
--- /dev/null
+++ b/mpfr/src/strtofr.c
@@ -0,0 +1,851 @@
+/* mpfr_strtofr -- set a floating-point number from a string
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h> /* For strtol */
+#include <ctype.h> /* For isspace */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#define MPFR_MAX_BASE 62
+
+struct parsed_string {
+ int negative; /* non-zero iff the number is negative */
+ int base; /* base of the string */
+ unsigned char *mantissa; /* raw significand (without any point) */
+ unsigned char *mant; /* stripped significand (without starting and
+ ending zeroes). This points inside the area
+ allocated for the mantissa field. */
+ size_t prec; /* length of mant (zero for +/-0) */
+ size_t alloc; /* allocation size of mantissa */
+ mpfr_exp_t exp_base; /* number of digits before the point */
+ mpfr_exp_t exp_bin; /* exponent in case base=2 or 16, and the pxxx
+ format is used (i.e., exponent is given in
+ base 10) */
+};
+
+/* This table has been generated by the following program.
+ For 2 <= b <= MPFR_MAX_BASE,
+ RedInvLog2Table[b-2][0] / RedInvLog2Table[b-2][1]
+ is an upper approximation of log(2)/log(b).
+*/
+static const unsigned long RedInvLog2Table[MPFR_MAX_BASE-1][2] = {
+ {1UL, 1UL},
+ {53UL, 84UL},
+ {1UL, 2UL},
+ {4004UL, 9297UL},
+ {53UL, 137UL},
+ {2393UL, 6718UL},
+ {1UL, 3UL},
+ {665UL, 2108UL},
+ {4004UL, 13301UL},
+ {949UL, 3283UL},
+ {53UL, 190UL},
+ {5231UL, 19357UL},
+ {2393UL, 9111UL},
+ {247UL, 965UL},
+ {1UL, 4UL},
+ {4036UL, 16497UL},
+ {665UL, 2773UL},
+ {5187UL, 22034UL},
+ {4004UL, 17305UL},
+ {51UL, 224UL},
+ {949UL, 4232UL},
+ {3077UL, 13919UL},
+ {53UL, 243UL},
+ {73UL, 339UL},
+ {5231UL, 24588UL},
+ {665UL, 3162UL},
+ {2393UL, 11504UL},
+ {4943UL, 24013UL},
+ {247UL, 1212UL},
+ {3515UL, 17414UL},
+ {1UL, 5UL},
+ {4415UL, 22271UL},
+ {4036UL, 20533UL},
+ {263UL, 1349UL},
+ {665UL, 3438UL},
+ {1079UL, 5621UL},
+ {5187UL, 27221UL},
+ {2288UL, 12093UL},
+ {4004UL, 21309UL},
+ {179UL, 959UL},
+ {51UL, 275UL},
+ {495UL, 2686UL},
+ {949UL, 5181UL},
+ {3621UL, 19886UL},
+ {3077UL, 16996UL},
+ {229UL, 1272UL},
+ {53UL, 296UL},
+ {109UL, 612UL},
+ {73UL, 412UL},
+ {1505UL, 8537UL},
+ {5231UL, 29819UL},
+ {283UL, 1621UL},
+ {665UL, 3827UL},
+ {32UL, 185UL},
+ {2393UL, 13897UL},
+ {1879UL, 10960UL},
+ {4943UL, 28956UL},
+ {409UL, 2406UL},
+ {247UL, 1459UL},
+ {231UL, 1370UL},
+ {3515UL, 20929UL} };
+#if 0
+#define N 8
+int main ()
+{
+ unsigned long tab[N];
+ int i, n, base;
+ mpfr_t x, y;
+ mpq_t q1, q2;
+ int overflow = 0, base_overflow;
+
+ mpfr_init2 (x, 200);
+ mpfr_init2 (y, 200);
+ mpq_init (q1);
+ mpq_init (q2);
+
+ for (base = 2 ; base < 63 ; base ++)
+ {
+ mpfr_set_ui (x, base, MPFR_RNDN);
+ mpfr_log2 (x, x, MPFR_RNDN);
+ mpfr_ui_div (x, 1, x, MPFR_RNDN);
+ printf ("Base: %d x=%e ", base, mpfr_get_d1 (x));
+ for (i = 0 ; i < N ; i++)
+ {
+ mpfr_floor (y, x);
+ tab[i] = mpfr_get_ui (y, MPFR_RNDN);
+ mpfr_sub (x, x, y, MPFR_RNDN);
+ mpfr_ui_div (x, 1, x, MPFR_RNDN);
+ }
+ for (i = N-1 ; i >= 0 ; i--)
+ if (tab[i] != 0)
+ break;
+ mpq_set_ui (q1, tab[i], 1);
+ for (i = i-1 ; i >= 0 ; i--)
+ {
+ mpq_inv (q1, q1);
+ mpq_set_ui (q2, tab[i], 1);
+ mpq_add (q1, q1, q2);
+ }
+ printf("Approx: ", base);
+ mpq_out_str (stdout, 10, q1);
+ printf (" = %e\n", mpq_get_d (q1) );
+ fprintf (stderr, "{");
+ mpz_out_str (stderr, 10, mpq_numref (q1));
+ fprintf (stderr, "UL, ");
+ mpz_out_str (stderr, 10, mpq_denref (q1));
+ fprintf (stderr, "UL},\n");
+ if (mpz_cmp_ui (mpq_numref (q1), 1<<16-1) >= 0
+ || mpz_cmp_ui (mpq_denref (q1), 1<<16-1) >= 0)
+ overflow = 1, base_overflow = base;
+ }
+
+ mpq_clear (q2);
+ mpq_clear (q1);
+ mpfr_clear (y);
+ mpfr_clear (x);
+ if (overflow )
+ printf ("OVERFLOW for base =%d!\n", base_overflow);
+}
+#endif
+
+
+/* Compatible with any locale, but one still assumes that 'a', 'b', 'c',
+ ..., 'z', and 'A', 'B', 'C', ..., 'Z' are consecutive values (like
+ in any ASCII-based character set). */
+static int
+digit_value_in_base (int c, int base)
+{
+ int digit;
+
+ MPFR_ASSERTD (base > 0 && base <= MPFR_MAX_BASE);
+
+ if (c >= '0' && c <= '9')
+ digit = c - '0';
+ else if (c >= 'a' && c <= 'z')
+ digit = (base >= 37) ? c - 'a' + 36 : c - 'a' + 10;
+ else if (c >= 'A' && c <= 'Z')
+ digit = c - 'A' + 10;
+ else
+ return -1;
+
+ return MPFR_LIKELY (digit < base) ? digit : -1;
+}
+
+/* Compatible with any locale, but one still assumes that 'a', 'b', 'c',
+ ..., 'z', and 'A', 'B', 'C', ..., 'Z' are consecutive values (like
+ in any ASCII-based character set). */
+/* TODO: support EBCDIC. */
+static int
+fast_casecmp (const char *s1, const char *s2)
+{
+ unsigned char c1, c2;
+
+ do
+ {
+ c2 = *(const unsigned char *) s2++;
+ if (c2 == '\0')
+ return 0;
+ c1 = *(const unsigned char *) s1++;
+ if (c1 >= 'A' && c1 <= 'Z')
+ c1 = c1 - 'A' + 'a';
+ }
+ while (c1 == c2);
+ return 1;
+}
+
+/* Parse a string and fill pstr.
+ Return the advanced ptr too.
+ It returns:
+ -1 if invalid string,
+ 0 if special string (like nan),
+ 1 if the string is ok.
+ 2 if overflows
+ So it doesn't return the ternary value
+ BUT if it returns 0 (NAN or INF), the ternary value is also '0'
+ (ie NAN and INF are exact) */
+static int
+parse_string (mpfr_t x, struct parsed_string *pstr,
+ const char **string, int base)
+{
+ const char *str = *string;
+ unsigned char *mant;
+ int point;
+ int res = -1; /* Invalid input return value */
+ const char *prefix_str;
+ int decimal_point;
+
+ decimal_point = (unsigned char) MPFR_DECIMAL_POINT;
+
+ /* Init variable */
+ pstr->mantissa = NULL;
+
+ /* Optional leading whitespace */
+ while (isspace((unsigned char) *str)) str++;
+
+ /* An optional sign `+' or `-' */
+ pstr->negative = (*str == '-');
+ if (*str == '-' || *str == '+')
+ str++;
+
+ /* Can be case-insensitive NAN */
+ if (fast_casecmp (str, "@nan@") == 0)
+ {
+ str += 5;
+ goto set_nan;
+ }
+ if (base <= 16 && fast_casecmp (str, "nan") == 0)
+ {
+ str += 3;
+ set_nan:
+ /* Check for "(dummychars)" */
+ if (*str == '(')
+ {
+ const char *s;
+ for (s = str+1 ; *s != ')' ; s++)
+ if (!(*s >= 'A' && *s <= 'Z')
+ && !(*s >= 'a' && *s <= 'z')
+ && !(*s >= '0' && *s <= '9')
+ && *s != '_')
+ break;
+ if (*s == ')')
+ str = s+1;
+ }
+ *string = str;
+ MPFR_SET_NAN(x);
+ /* MPFR_RET_NAN not used as the return value isn't a ternary value */
+ __gmpfr_flags |= MPFR_FLAGS_NAN;
+ return 0;
+ }
+
+ /* Can be case-insensitive INF */
+ if (fast_casecmp (str, "@inf@") == 0)
+ {
+ str += 5;
+ goto set_inf;
+ }
+ if (base <= 16 && fast_casecmp (str, "infinity") == 0)
+ {
+ str += 8;
+ goto set_inf;
+ }
+ if (base <= 16 && fast_casecmp (str, "inf") == 0)
+ {
+ str += 3;
+ set_inf:
+ *string = str;
+ MPFR_SET_INF (x);
+ (pstr->negative) ? MPFR_SET_NEG (x) : MPFR_SET_POS (x);
+ return 0;
+ }
+
+ /* If base=0 or 16, it may include '0x' prefix */
+ prefix_str = NULL;
+ if ((base == 0 || base == 16) && str[0]=='0'
+ && (str[1]=='x' || str[1] == 'X'))
+ {
+ prefix_str = str;
+ base = 16;
+ str += 2;
+ }
+ /* If base=0 or 2, it may include '0b' prefix */
+ if ((base == 0 || base == 2) && str[0]=='0'
+ && (str[1]=='b' || str[1] == 'B'))
+ {
+ prefix_str = str;
+ base = 2;
+ str += 2;
+ }
+ /* Else if base=0, we assume decimal base */
+ if (base == 0)
+ base = 10;
+ pstr->base = base;
+
+ /* Alloc mantissa */
+ pstr->alloc = (size_t) strlen (str) + 1;
+ pstr->mantissa = (unsigned char*) (*__gmp_allocate_func) (pstr->alloc);
+
+ /* Read mantissa digits */
+ parse_begin:
+ mant = pstr->mantissa;
+ point = 0;
+ pstr->exp_base = 0;
+ pstr->exp_bin = 0;
+
+ for (;;) /* Loop until an invalid character is read */
+ {
+ int c = (unsigned char) *str++;
+ /* The cast to unsigned char is needed because of digit_value_in_base;
+ decimal_point uses this convention too. */
+ if (c == '.' || c == decimal_point)
+ {
+ if (MPFR_UNLIKELY(point)) /* Second '.': stop parsing */
+ break;
+ point = 1;
+ continue;
+ }
+ c = digit_value_in_base (c, base);
+ if (c == -1)
+ break;
+ MPFR_ASSERTN (c >= 0); /* c is representable in an unsigned char */
+ *mant++ = (unsigned char) c;
+ if (!point)
+ pstr->exp_base ++;
+ }
+ str--; /* The last read character was invalid */
+
+ /* Update the # of char in the mantissa */
+ pstr->prec = mant - pstr->mantissa;
+ /* Check if there are no characters in the mantissa (Invalid argument) */
+ if (pstr->prec == 0)
+ {
+ /* Check if there was a prefix (in such a case, we have to read
+ again the mantissa without skipping the prefix)
+ The allocated mantissa is still big enough since we will
+ read only 0, and we alloc one more char than needed.
+ FIXME: Not really friendly. Maybe cleaner code? */
+ if (prefix_str != NULL)
+ {
+ str = prefix_str;
+ prefix_str = NULL;
+ goto parse_begin;
+ }
+ goto end;
+ }
+
+ /* Valid entry */
+ res = 1;
+ MPFR_ASSERTD (pstr->exp_base >= 0);
+
+ /* an optional exponent (e or E, p or P, @) */
+ if ( (*str == '@' || (base <= 10 && (*str == 'e' || *str == 'E')))
+ && (!isspace((unsigned char) str[1])) )
+ {
+ char *endptr;
+ /* the exponent digits are kept in ASCII */
+ mpfr_exp_t sum;
+ long read_exp = strtol (str + 1, &endptr, 10);
+ if (endptr != str+1)
+ str = endptr;
+ sum =
+ read_exp < MPFR_EXP_MIN ? (str = endptr, MPFR_EXP_MIN) :
+ read_exp > MPFR_EXP_MAX ? (str = endptr, MPFR_EXP_MAX) :
+ (mpfr_exp_t) read_exp;
+ MPFR_SADD_OVERFLOW (sum, sum, pstr->exp_base,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN, MPFR_EXP_MAX,
+ res = 2, res = 3);
+ /* Since exp_base was positive, read_exp + exp_base can't
+ do a negative overflow. */
+ MPFR_ASSERTD (res != 3);
+ pstr->exp_base = sum;
+ }
+ else if ((base == 2 || base == 16)
+ && (*str == 'p' || *str == 'P')
+ && (!isspace((unsigned char) str[1])))
+ {
+ char *endptr;
+ long read_exp = strtol (str + 1, &endptr, 10);
+ if (endptr != str+1)
+ str = endptr;
+ pstr->exp_bin =
+ read_exp < MPFR_EXP_MIN ? (str = endptr, MPFR_EXP_MIN) :
+ read_exp > MPFR_EXP_MAX ? (str = endptr, MPFR_EXP_MAX) :
+ (mpfr_exp_t) read_exp;
+ }
+
+ /* Remove 0's at the beginning and end of mantissa[0..prec-1] */
+ mant = pstr->mantissa;
+ for ( ; (pstr->prec > 0) && (*mant == 0) ; mant++, pstr->prec--)
+ pstr->exp_base--;
+ for ( ; (pstr->prec > 0) && (mant[pstr->prec - 1] == 0); pstr->prec--);
+ pstr->mant = mant;
+
+ /* Check if x = 0 */
+ if (pstr->prec == 0)
+ {
+ MPFR_SET_ZERO (x);
+ if (pstr->negative)
+ MPFR_SET_NEG(x);
+ else
+ MPFR_SET_POS(x);
+ res = 0;
+ }
+
+ *string = str;
+ end:
+ if (pstr->mantissa != NULL && res != 1)
+ (*__gmp_free_func) (pstr->mantissa, pstr->alloc);
+ return res;
+}
+
+/* Transform a parsed string to a mpfr_t according to the rounding mode
+ and the precision of x.
+ Returns the ternary value. */
+static int
+parsed_string_to_mpfr (mpfr_t x, struct parsed_string *pstr, mpfr_rnd_t rnd)
+{
+ mpfr_prec_t prec;
+ mpfr_exp_t exp;
+ mpfr_exp_t ysize_bits;
+ mp_limb_t *y, *result;
+ int count, exact;
+ size_t pstr_size;
+ mp_size_t ysize, real_ysize;
+ int res, err;
+ MPFR_ZIV_DECL (loop);
+ MPFR_TMP_DECL (marker);
+
+ /* initialize the working precision */
+ prec = MPFR_PREC (x) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (x));
+
+ /* compute the value y of the leading characters as long as rounding is not
+ possible */
+ MPFR_TMP_MARK(marker);
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ /* Set y to the value of the ~prec most significant bits of pstr->mant
+ (as long as we guarantee correct rounding, we don't need to get
+ exactly prec bits). */
+ ysize = MPFR_PREC2LIMBS (prec);
+ /* prec bits corresponds to ysize limbs */
+ ysize_bits = ysize * GMP_NUMB_BITS;
+ /* and to ysize_bits >= prec > MPFR_PREC (x) bits */
+ y = MPFR_TMP_LIMBS_ALLOC (2 * ysize + 1);
+ y += ysize; /* y has (ysize+1) allocated limbs */
+
+ /* pstr_size is the number of characters we read in pstr->mant
+ to have at least ysize full limbs.
+ We must have base^(pstr_size-1) >= (2^(GMP_NUMB_BITS))^ysize
+ (in the worst case, the first digit is one and all others are zero).
+ i.e., pstr_size >= 1 + ysize*GMP_NUMB_BITS/log2(base)
+ Since ysize ~ prec/GMP_NUMB_BITS and prec < Umax/2 =>
+ ysize*GMP_NUMB_BITS can not overflow.
+ We compute pstr_size = 1 + ceil(ysize_bits * Num / Den)
+ where Num/Den >= 1/log2(base)
+ It is not exactly ceil(1/log2(base)) but could be one more (base 2)
+ Quite ugly since it tries to avoid overflow:
+ let Num = RedInvLog2Table[pstr->base-2][0]
+ and Den = RedInvLog2Table[pstr->base-2][1],
+ and ysize_bits = a*Den+b,
+ then ysize_bits * Num/Den = a*Num + (b * Num)/Den,
+ thus ceil(ysize_bits * Num/Den) = a*Num + floor(b * Num + Den - 1)/Den
+ */
+ {
+ unsigned long Num = RedInvLog2Table[pstr->base-2][0];
+ unsigned long Den = RedInvLog2Table[pstr->base-2][1];
+ pstr_size = ((ysize_bits / Den) * Num)
+ + (((ysize_bits % Den) * Num + Den - 1) / Den)
+ + 1;
+ }
+
+ /* since pstr_size corresponds to at least ysize_bits full bits,
+ and ysize_bits > prec, the weight of the neglected part of
+ pstr->mant (if any) is < ulp(y) < ulp(x) */
+
+ /* if the number of wanted characters is more than what we have in
+ pstr->mant, round it down */
+ if (pstr_size >= pstr->prec)
+ pstr_size = pstr->prec;
+ MPFR_ASSERTD (pstr_size == (mpfr_exp_t) pstr_size);
+
+ /* convert str into binary: note that pstr->mant is big endian,
+ thus no offset is needed */
+ real_ysize = mpn_set_str (y, pstr->mant, pstr_size, pstr->base);
+ MPFR_ASSERTD (real_ysize <= ysize+1);
+
+ /* normalize y: warning we can even get ysize+1 limbs! */
+ MPFR_ASSERTD (y[real_ysize - 1] != 0); /* mpn_set_str guarantees this */
+ count_leading_zeros (count, y[real_ysize - 1]);
+ /* exact means that the number of limbs of the output of mpn_set_str
+ is less or equal to ysize */
+ exact = real_ysize <= ysize;
+ if (exact) /* shift y to the left in that case y should be exact */
+ {
+ /* we have enough limbs to store {y, real_ysize} */
+ /* shift {y, num_limb} for count bits to the left */
+ if (count != 0)
+ mpn_lshift (y + ysize - real_ysize, y, real_ysize, count);
+ if (real_ysize != ysize)
+ {
+ if (count == 0)
+ MPN_COPY_DECR (y + ysize - real_ysize, y, real_ysize);
+ MPN_ZERO (y, ysize - real_ysize);
+ }
+ /* for each bit shift decrease exponent of y */
+ /* (This should not overflow) */
+ exp = - ((ysize - real_ysize) * GMP_NUMB_BITS + count);
+ }
+ else /* shift y to the right, by doing this we might lose some
+ bits from the result of mpn_set_str (in addition to the
+ characters neglected from pstr->mant) */
+ {
+ /* shift {y, num_limb} for (GMP_NUMB_BITS - count) bits
+ to the right. FIXME: can we prove that count cannot be zero here,
+ since mpn_rshift does not accept a shift of GMP_NUMB_BITS? */
+ MPFR_ASSERTD (count != 0);
+ exact = mpn_rshift (y, y, real_ysize, GMP_NUMB_BITS - count) ==
+ MPFR_LIMB_ZERO;
+ /* for each bit shift increase exponent of y */
+ exp = GMP_NUMB_BITS - count;
+ }
+
+ /* compute base^(exp_base - pstr_size) on n limbs */
+ if (IS_POW2 (pstr->base))
+ {
+ /* Base: 2, 4, 8, 16, 32 */
+ int pow2;
+ mpfr_exp_t tmp;
+
+ count_leading_zeros (pow2, (mp_limb_t) pstr->base);
+ pow2 = GMP_NUMB_BITS - pow2 - 1; /* base = 2^pow2 */
+ MPFR_ASSERTD (0 < pow2 && pow2 <= 5);
+ /* exp += pow2 * (pstr->exp_base - pstr_size) + pstr->exp_bin
+ with overflow checking
+ and check that we can add/substract 2 to exp without overflow */
+ MPFR_SADD_OVERFLOW (tmp, pstr->exp_base, -(mpfr_exp_t) pstr_size,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN, MPFR_EXP_MAX,
+ goto overflow, goto underflow);
+ /* On some FreeBsd/Alpha, LONG_MIN/1 produced an exception
+ so we used to check for this before doing the division.
+ Since this bug is closed now (Nov 26, 2009), we remove
+ that check (http://www.freebsd.org/cgi/query-pr.cgi?pr=72024) */
+ if (tmp > 0 && MPFR_EXP_MAX / pow2 <= tmp)
+ goto overflow;
+ else if (tmp < 0 && MPFR_EXP_MIN / pow2 >= tmp)
+ goto underflow;
+ tmp *= pow2;
+ MPFR_SADD_OVERFLOW (tmp, tmp, pstr->exp_bin,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN, MPFR_EXP_MAX,
+ goto overflow, goto underflow);
+ MPFR_SADD_OVERFLOW (exp, exp, tmp,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN+2, MPFR_EXP_MAX-2,
+ goto overflow, goto underflow);
+ result = y;
+ err = 0;
+ }
+ /* case non-power-of-two-base, and pstr->exp_base > pstr_size */
+ else if (pstr->exp_base > (mpfr_exp_t) pstr_size)
+ {
+ mp_limb_t *z;
+ mpfr_exp_t exp_z;
+
+ result = MPFR_TMP_LIMBS_ALLOC (2 * ysize + 1);
+
+ /* z = base^(exp_base-sptr_size) using space allocated at y-ysize */
+ z = y - ysize;
+ /* NOTE: exp_base-pstr_size can't overflow since pstr_size > 0 */
+ err = mpfr_mpn_exp (z, &exp_z, pstr->base,
+ pstr->exp_base - pstr_size, ysize);
+ if (err == -2)
+ goto overflow;
+ exact = exact && (err == -1);
+
+ /* If exact is non zero, then z equals exactly the value of the
+ pstr_size most significant digits from pstr->mant, i.e., the
+ only difference can come from the neglected pstr->prec-pstr_size
+ least significant digits of pstr->mant.
+ If exact is zero, then z is rounded toward zero with respect
+ to that value. */
+
+ /* multiply(y = 0.mant[0]...mant[pr-1])_base by base^(exp-g):
+ since both y and z are rounded toward zero, so is "result" */
+ mpn_mul_n (result, y, z, ysize);
+
+ /* compute the error on the product */
+ if (err == -1)
+ err = 0;
+ err ++;
+
+ /* compute the exponent of y */
+ /* exp += exp_z + ysize_bits with overflow checking
+ and check that we can add/substract 2 to exp without overflow */
+ MPFR_SADD_OVERFLOW (exp_z, exp_z, ysize_bits,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN, MPFR_EXP_MAX,
+ goto overflow, goto underflow);
+ MPFR_SADD_OVERFLOW (exp, exp, exp_z,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN+2, MPFR_EXP_MAX-2,
+ goto overflow, goto underflow);
+
+ /* normalize result */
+ if (MPFR_LIMB_MSB (result[2 * ysize - 1]) == 0)
+ {
+ mp_limb_t *r = result + ysize - 1;
+ mpn_lshift (r, r, ysize + 1, 1);
+ /* Overflow checking not needed */
+ exp --;
+ }
+
+ /* if the low ysize limbs of {result, 2*ysize} are all zero,
+ then the result is still "exact" (if it was before) */
+ exact = exact && (mpn_scan1 (result, 0)
+ >= (unsigned long) ysize_bits);
+ result += ysize;
+ }
+ /* case exp_base < pstr_size */
+ else if (pstr->exp_base < (mpfr_exp_t) pstr_size)
+ {
+ mp_limb_t *z;
+ mpfr_exp_t exp_z;
+
+ result = MPFR_TMP_LIMBS_ALLOC (3 * ysize + 1);
+
+ /* set y to y * K^ysize */
+ y = y - ysize; /* we have allocated ysize limbs at y - ysize */
+ MPN_ZERO (y, ysize);
+
+ /* pstr_size - pstr->exp_base can overflow */
+ MPFR_SADD_OVERFLOW (exp_z, (mpfr_exp_t) pstr_size, -pstr->exp_base,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN, MPFR_EXP_MAX,
+ goto underflow, goto overflow);
+
+ /* (z, exp_z) = base^(exp_base-pstr_size) */
+ z = result + 2*ysize + 1;
+ err = mpfr_mpn_exp (z, &exp_z, pstr->base, exp_z, ysize);
+ /* Since we want y/z rounded toward zero, we must get an upper
+ bound of z. If err >= 0, the error on z is bounded by 2^err. */
+ if (err >= 0)
+ {
+ mp_limb_t cy;
+ unsigned long h = err / GMP_NUMB_BITS;
+ unsigned long l = err - h * GMP_NUMB_BITS;
+
+ if (h >= ysize) /* not enough precision in z */
+ goto next_loop;
+ cy = mpn_add_1 (z, z, ysize - h, MPFR_LIMB_ONE << l);
+ if (cy != 0) /* the code below requires z on ysize limbs */
+ goto next_loop;
+ }
+ exact = exact && (err == -1);
+ if (err == -2)
+ goto underflow; /* FIXME: Sure? */
+ if (err == -1)
+ err = 0;
+
+ /* compute y / z */
+ /* result will be put into result + n, and remainder into result */
+ mpn_tdiv_qr (result + ysize, result, (mp_size_t) 0, y,
+ 2 * ysize, z, ysize);
+
+ /* exp -= exp_z + ysize_bits with overflow checking
+ and check that we can add/substract 2 to exp without overflow */
+ MPFR_SADD_OVERFLOW (exp_z, exp_z, ysize_bits,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN, MPFR_EXP_MAX,
+ goto underflow, goto overflow);
+ MPFR_SADD_OVERFLOW (exp, exp, -exp_z,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN+2, MPFR_EXP_MAX-2,
+ goto overflow, goto underflow);
+ err += 2;
+ /* if the remainder of the division is zero, then the result is
+ still "exact" if it was before */
+ exact = exact && (mpn_popcount (result, ysize) == 0);
+
+ /* normalize result */
+ if (result[2 * ysize] == MPFR_LIMB_ONE)
+ {
+ mp_limb_t *r = result + ysize;
+
+ exact = exact && ((*r & MPFR_LIMB_ONE) == 0);
+ mpn_rshift (r, r, ysize + 1, 1);
+ /* Overflow Checking not needed */
+ exp ++;
+ }
+ result += ysize;
+ }
+ /* case exp_base = pstr_size: no multiplication or division needed */
+ else
+ {
+ /* base^(exp-pr) = 1 nothing to compute */
+ result = y;
+ err = 0;
+ }
+
+ /* If result is exact, we still have to consider the neglected part
+ of the input string. For a directed rounding, in that case we could
+ still correctly round, since the neglected part is less than
+ one ulp, but that would make the code more complex, and give a
+ speedup for rare cases only. */
+ exact = exact && (pstr_size == pstr->prec);
+
+ /* at this point, result is an approximation rounded toward zero
+ of the pstr_size most significant digits of pstr->mant, with
+ equality in case exact is non-zero. */
+
+ /* test if rounding is possible, and if so exit the loop */
+ if (exact || mpfr_can_round_raw (result, ysize,
+ (pstr->negative) ? -1 : 1,
+ ysize_bits - err - 1,
+ MPFR_RNDN, rnd, MPFR_PREC(x)))
+ break;
+
+ next_loop:
+ /* update the prec for next loop */
+ MPFR_ZIV_NEXT (loop, prec);
+ } /* loop */
+ MPFR_ZIV_FREE (loop);
+
+ /* round y */
+ if (mpfr_round_raw (MPFR_MANT (x), result,
+ ysize_bits,
+ pstr->negative, MPFR_PREC(x), rnd, &res ))
+ {
+ /* overflow when rounding y */
+ MPFR_MANT (x)[MPFR_LIMB_SIZE (x) - 1] = MPFR_LIMB_HIGHBIT;
+ /* Overflow Checking not needed */
+ exp ++;
+ }
+
+ if (res == 0) /* fix ternary value */
+ {
+ exact = exact && (pstr_size == pstr->prec);
+ if (!exact)
+ res = (pstr->negative) ? 1 : -1;
+ }
+
+ /* Set sign of x before exp since check_range needs a valid sign */
+ (pstr->negative) ? MPFR_SET_NEG (x) : MPFR_SET_POS (x);
+
+ /* DO NOT USE MPFR_SET_EXP. The exp may be out of range! */
+ MPFR_SADD_OVERFLOW (exp, exp, ysize_bits,
+ mpfr_exp_t, mpfr_uexp_t,
+ MPFR_EXP_MIN, MPFR_EXP_MAX,
+ goto overflow, goto underflow);
+ MPFR_EXP (x) = exp;
+ res = mpfr_check_range (x, res, rnd);
+ goto end;
+
+ underflow:
+ /* This is called when there is a huge overflow
+ (Real expo < MPFR_EXP_MIN << __gmpfr_emin */
+ if (rnd == MPFR_RNDN)
+ rnd = MPFR_RNDZ;
+ res = mpfr_underflow (x, rnd, (pstr->negative) ? -1 : 1);
+ goto end;
+
+ overflow:
+ res = mpfr_overflow (x, rnd, (pstr->negative) ? -1 : 1);
+
+ end:
+ MPFR_TMP_FREE (marker);
+ return res;
+}
+
+static void
+free_parsed_string (struct parsed_string *pstr)
+{
+ (*__gmp_free_func) (pstr->mantissa, pstr->alloc);
+}
+
+int
+mpfr_strtofr (mpfr_t x, const char *string, char **end, int base,
+ mpfr_rnd_t rnd)
+{
+ int res;
+ struct parsed_string pstr;
+
+ /* For base <= 36, parsing is case-insensitive. */
+ MPFR_ASSERTN (base == 0 || (base >= 2 && base <= 62));
+
+ /* If an error occured, it must return 0 */
+ MPFR_SET_ZERO (x);
+ MPFR_SET_POS (x);
+
+ MPFR_ASSERTN (MPFR_MAX_BASE >= 62);
+ res = parse_string (x, &pstr, &string, base);
+ /* If res == 0, then it was exact (NAN or INF),
+ so it is also the ternary value */
+ if (MPFR_UNLIKELY (res == -1)) /* invalid data */
+ res = 0; /* x is set to 0, which is exact, thus ternary value is 0 */
+ else if (res == 1)
+ {
+ res = parsed_string_to_mpfr (x, &pstr, rnd);
+ free_parsed_string (&pstr);
+ }
+ else if (res == 2)
+ res = mpfr_overflow (x, rnd, (pstr.negative) ? -1 : 1);
+ MPFR_ASSERTD (res != 3);
+#if 0
+ else if (res == 3)
+ {
+ /* This is called when there is a huge overflow
+ (Real expo < MPFR_EXP_MIN << __gmpfr_emin */
+ if (rnd == MPFR_RNDN)
+ rnd = MPFR_RNDZ;
+ res = mpfr_underflow (x, rnd, (pstr.negative) ? -1 : 1);
+ }
+#endif
+
+ if (end != NULL)
+ *end = (char *) string;
+ return res;
+}
diff --git a/mpfr/src/sub.c b/mpfr/src/sub.c
new file mode 100644
index 0000000000..d1af16f719
--- /dev/null
+++ b/mpfr/src/sub.c
@@ -0,0 +1,116 @@
+/* mpfr_sub -- subtract two floating-point numbers
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ MPFR_LOG_FUNC
+ (("b[%Pu]=%.*Rg c[%Pu]=%.*Rg rnd=%d",
+ mpfr_get_prec (b), mpfr_log_prec, b,
+ mpfr_get_prec (c), mpfr_log_prec, c, rnd_mode),
+ ("a[%Pu]=%.*Rg", mpfr_get_prec (a), mpfr_log_prec, a));
+
+ if (MPFR_ARE_SINGULAR (b,c))
+ {
+ if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
+ {
+ MPFR_SET_NAN (a);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (b))
+ {
+ if (!MPFR_IS_INF (c) || MPFR_SIGN (b) != MPFR_SIGN(c))
+ {
+ MPFR_SET_INF (a);
+ MPFR_SET_SAME_SIGN (a, b);
+ MPFR_RET (0); /* exact */
+ }
+ else
+ {
+ MPFR_SET_NAN (a); /* Inf - Inf */
+ MPFR_RET_NAN;
+ }
+ }
+ else if (MPFR_IS_INF (c))
+ {
+ MPFR_SET_INF (a);
+ MPFR_SET_OPPOSITE_SIGN (a, c);
+ MPFR_RET (0); /* exact */
+ }
+ else if (MPFR_IS_ZERO (b))
+ {
+ if (MPFR_IS_ZERO (c))
+ {
+ int sign = rnd_mode != MPFR_RNDD
+ ? ((MPFR_IS_NEG(b) && MPFR_IS_POS(c)) ? -1 : 1)
+ : ((MPFR_IS_POS(b) && MPFR_IS_NEG(c)) ? 1 : -1);
+ MPFR_SET_SIGN (a, sign);
+ MPFR_SET_ZERO (a);
+ MPFR_RET(0); /* 0 - 0 is exact */
+ }
+ else
+ return mpfr_neg (a, c, rnd_mode);
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (c));
+ return mpfr_set (a, b, rnd_mode);
+ }
+ }
+
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (b));
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (c));
+
+ if (MPFR_LIKELY (MPFR_SIGN (b) == MPFR_SIGN (c)))
+ { /* signs are equal, it's a real subtraction */
+ if (MPFR_LIKELY (MPFR_PREC (a) == MPFR_PREC (b)
+ && MPFR_PREC (b) == MPFR_PREC (c)))
+ return mpfr_sub1sp (a, b, c, rnd_mode);
+ else
+ return mpfr_sub1 (a, b, c, rnd_mode);
+ }
+ else
+ { /* signs differ, it's an addition */
+ if (MPFR_GET_EXP (b) < MPFR_GET_EXP (c))
+ { /* exchange rounding modes toward +/- infinity */
+ int inexact;
+ rnd_mode = MPFR_INVERT_RND (rnd_mode);
+ if (MPFR_LIKELY (MPFR_PREC (a) == MPFR_PREC (b)
+ && MPFR_PREC (b) == MPFR_PREC (c)))
+ inexact = mpfr_add1sp (a, c, b, rnd_mode);
+ else
+ inexact = mpfr_add1 (a, c, b, rnd_mode);
+ MPFR_CHANGE_SIGN (a);
+ return -inexact;
+ }
+ else
+ {
+ if (MPFR_LIKELY (MPFR_PREC (a) == MPFR_PREC (b)
+ && MPFR_PREC (b) == MPFR_PREC (c)))
+ return mpfr_add1sp (a, b, c, rnd_mode);
+ else
+ return mpfr_add1 (a, b, c, rnd_mode);
+ }
+ }
+}
diff --git a/mpfr/src/sub1.c b/mpfr/src/sub1.c
new file mode 100644
index 0000000000..b266412faa
--- /dev/null
+++ b/mpfr/src/sub1.c
@@ -0,0 +1,657 @@
+/* mpfr_sub1 -- internal function to perform a "real" subtraction
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* compute sign(b) * (|b| - |c|), with |b| > |c|, diff_exp = EXP(b) - EXP(c)
+ Returns 0 iff result is exact,
+ a negative value when the result is less than the exact value,
+ a positive value otherwise.
+*/
+
+int
+mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ int sign;
+ mpfr_uexp_t diff_exp;
+ mpfr_prec_t cancel, cancel1;
+ mp_size_t cancel2, an, bn, cn, cn0;
+ mp_limb_t *ap, *bp, *cp;
+ mp_limb_t carry, bb, cc;
+ int inexact, shift_b, shift_c, add_exp = 0;
+ int cmp_low = 0; /* used for rounding to nearest: 0 if low(b) = low(c),
+ negative if low(b) < low(c), positive if low(b)>low(c) */
+ int sh, k;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_TMP_MARK(marker);
+ ap = MPFR_MANT(a);
+ an = MPFR_LIMB_SIZE(a);
+
+ sign = mpfr_cmp2 (b, c, &cancel);
+ if (MPFR_UNLIKELY(sign == 0))
+ {
+ if (rnd_mode == MPFR_RNDD)
+ MPFR_SET_NEG (a);
+ else
+ MPFR_SET_POS (a);
+ MPFR_SET_ZERO (a);
+ MPFR_RET (0);
+ }
+
+ /*
+ * If subtraction: sign(a) = sign * sign(b)
+ * If addition: sign(a) = sign of the larger argument in absolute value.
+ *
+ * Both cases can be simplidied in:
+ * if (sign>0)
+ * if addition: sign(a) = sign * sign(b) = sign(b)
+ * if subtraction, b is greater, so sign(a) = sign(b)
+ * else
+ * if subtraction, sign(a) = - sign(b)
+ * if addition, sign(a) = sign(c) (since c is greater)
+ * But if it is an addition, sign(b) and sign(c) are opposed!
+ * So sign(a) = - sign(b)
+ */
+
+ if (sign < 0) /* swap b and c so that |b| > |c| */
+ {
+ mpfr_srcptr t;
+ MPFR_SET_OPPOSITE_SIGN (a,b);
+ t = b; b = c; c = t;
+ }
+ else
+ MPFR_SET_SAME_SIGN (a,b);
+
+ /* Check if c is too small.
+ A more precise test is to replace 2 by
+ (rnd == MPFR_RNDN) + mpfr_power2_raw (b)
+ but it is more expensive and not very useful */
+ if (MPFR_UNLIKELY (MPFR_GET_EXP (c) <= MPFR_GET_EXP (b)
+ - (mpfr_exp_t) MAX (MPFR_PREC (a), MPFR_PREC (b)) - 2))
+ {
+ /* Remember, we can't have an exact result! */
+ /* A.AAAAAAAAAAAAAAAAA
+ = B.BBBBBBBBBBBBBBB
+ - C.CCCCCCCCCCCCC */
+ /* A = S*ABS(B) +/- ulp(a) */
+ MPFR_SET_EXP (a, MPFR_GET_EXP (b));
+ MPFR_RNDRAW_EVEN (inexact, a, MPFR_MANT (b), MPFR_PREC (b),
+ rnd_mode, MPFR_SIGN (a),
+ if (MPFR_UNLIKELY ( ++MPFR_EXP (a) > __gmpfr_emax))
+ inexact = mpfr_overflow (a, rnd_mode, MPFR_SIGN (a)));
+ /* inexact = mpfr_set4 (a, b, rnd_mode, MPFR_SIGN (a)); */
+ if (inexact == 0)
+ {
+ /* a = b (Exact)
+ But we know it isn't (Since we have to remove `c')
+ So if we round to Zero, we have to remove one ulp.
+ Otherwise the result is correctly rounded. */
+ if (MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG (a)))
+ {
+ mpfr_nexttozero (a);
+ MPFR_RET (- MPFR_INT_SIGN (a));
+ }
+ MPFR_RET (MPFR_INT_SIGN (a));
+ }
+ else
+ {
+ /* A.AAAAAAAAAAAAAA
+ = B.BBBBBBBBBBBBBBB
+ - C.CCCCCCCCCCCCC */
+ /* It isn't exact so Prec(b) > Prec(a) and the last
+ Prec(b)-Prec(a) bits of `b' are not zeros.
+ Which means that removing c from b can't generate a carry
+ execpt in case of even rounding.
+ In all other case the result and the inexact flag should be
+ correct (We can't have an exact result).
+ In case of EVEN rounding:
+ 1.BBBBBBBBBBBBBx10
+ - 1.CCCCCCCCCCCC
+ = 1.BBBBBBBBBBBBBx01 Rounded to Prec(b)
+ = 1.BBBBBBBBBBBBBx Nearest / Rounded to Prec(a)
+ Set gives:
+ 1.BBBBBBBBBBBBB0 if inexact == EVEN_INEX (x == 0)
+ 1.BBBBBBBBBBBBB1+1 if inexact == -EVEN_INEX (x == 1)
+ which means we get a wrong rounded result if x==1,
+ i.e. inexact= MPFR_EVEN_INEX */
+ if (MPFR_UNLIKELY (inexact == MPFR_EVEN_INEX*MPFR_INT_SIGN (a)))
+ {
+ mpfr_nexttozero (a);
+ inexact = -MPFR_INT_SIGN (a);
+ }
+ MPFR_RET (inexact);
+ }
+ }
+
+ diff_exp = (mpfr_uexp_t) MPFR_GET_EXP (b) - MPFR_GET_EXP (c);
+
+ /* reserve a space to store b aligned with the result, i.e. shifted by
+ (-cancel) % GMP_NUMB_BITS to the right */
+ bn = MPFR_LIMB_SIZE (b);
+ MPFR_UNSIGNED_MINUS_MODULO (shift_b, cancel);
+ cancel1 = (cancel + shift_b) / GMP_NUMB_BITS;
+
+ /* the high cancel1 limbs from b should not be taken into account */
+ if (MPFR_UNLIKELY (shift_b == 0))
+ {
+ bp = MPFR_MANT(b); /* no need of an extra space */
+ /* Ensure ap != bp */
+ if (MPFR_UNLIKELY (ap == bp))
+ {
+ bp = MPFR_TMP_LIMBS_ALLOC (bn);
+ MPN_COPY (bp, ap, bn);
+ }
+ }
+ else
+ {
+ bp = MPFR_TMP_LIMBS_ALLOC (bn + 1);
+ bp[0] = mpn_rshift (bp + 1, MPFR_MANT(b), bn++, shift_b);
+ }
+
+ /* reserve a space to store c aligned with the result, i.e. shifted by
+ (diff_exp-cancel) % GMP_NUMB_BITS to the right */
+ cn = MPFR_LIMB_SIZE(c);
+ if ((UINT_MAX % GMP_NUMB_BITS) == (GMP_NUMB_BITS-1)
+ && ((-(unsigned) 1)%GMP_NUMB_BITS > 0))
+ shift_c = ((mpfr_uexp_t) diff_exp - cancel) % GMP_NUMB_BITS;
+ else
+ {
+ shift_c = diff_exp - (cancel % GMP_NUMB_BITS);
+ shift_c = (shift_c + GMP_NUMB_BITS) % GMP_NUMB_BITS;
+ }
+ MPFR_ASSERTD( shift_c >= 0 && shift_c < GMP_NUMB_BITS);
+
+ if (MPFR_UNLIKELY(shift_c == 0))
+ {
+ cp = MPFR_MANT(c);
+ /* Ensure ap != cp */
+ if (ap == cp)
+ {
+ cp = MPFR_TMP_LIMBS_ALLOC (cn);
+ MPN_COPY(cp, ap, cn);
+ }
+ }
+ else
+ {
+ cp = MPFR_TMP_LIMBS_ALLOC (cn + 1);
+ cp[0] = mpn_rshift (cp + 1, MPFR_MANT(c), cn++, shift_c);
+ }
+
+#ifdef DEBUG
+ printf ("rnd=%s shift_b=%d shift_c=%d diffexp=%lu\n",
+ mpfr_print_rnd_mode (rnd_mode), shift_b, shift_c,
+ (unsigned long) diff_exp);
+#endif
+
+ MPFR_ASSERTD (ap != cp);
+ MPFR_ASSERTD (bp != cp);
+
+ /* here we have shift_c = (diff_exp - cancel) % GMP_NUMB_BITS,
+ 0 <= shift_c < GMP_NUMB_BITS
+ thus we want cancel2 = ceil((cancel - diff_exp) / GMP_NUMB_BITS) */
+
+ /* Possible optimization with a C99 compiler (i.e. well-defined
+ integer division): if MPFR_PREC_MAX is reduced to
+ ((mpfr_prec_t)((mpfr_uprec_t)(~(mpfr_uprec_t)0)>>1) - GMP_NUMB_BITS + 1)
+ and diff_exp is of type mpfr_exp_t (no need for mpfr_uexp_t, since
+ the sum or difference of 2 exponents must be representable, as used
+ by the multiplication code), then the computation of cancel2 could
+ be simplified to
+ cancel2 = (cancel - (diff_exp - shift_c)) / GMP_NUMB_BITS;
+ because cancel, diff_exp and shift_c are all non-negative and
+ these variables are signed. */
+
+ MPFR_ASSERTD (cancel >= 0);
+ if (cancel >= diff_exp)
+ /* Note that cancel is signed and will be converted to mpfr_uexp_t
+ (type of diff_exp) in the expression below, so that this will
+ work even if cancel is very large and diff_exp = 0. */
+ cancel2 = (cancel - diff_exp + (GMP_NUMB_BITS - 1)) / GMP_NUMB_BITS;
+ else
+ cancel2 = - (mp_size_t) ((diff_exp - cancel) / GMP_NUMB_BITS);
+ /* the high cancel2 limbs from b should not be taken into account */
+#ifdef DEBUG
+ printf ("cancel=%lu cancel1=%lu cancel2=%ld\n",
+ (unsigned long) cancel, (unsigned long) cancel1, (long) cancel2);
+#endif
+
+ /* ap[an-1] ap[0]
+ <----------------+-----------|---->
+ <----------PREC(a)----------><-sh->
+ cancel1
+ limbs bp[bn-cancel1-1]
+ <--...-----><----------------+-----------+----------->
+ cancel2
+ limbs cp[cn-cancel2-1] cancel2 >= 0
+ <--...--><----------------+----------------+---------------->
+ (-cancel2) cancel2 < 0
+ limbs <----------------+---------------->
+ */
+
+ /* first part: put in ap[0..an-1] the value of high(b) - high(c),
+ where high(b) consists of the high an+cancel1 limbs of b,
+ and high(c) consists of the high an+cancel2 limbs of c.
+ */
+
+ /* copy high(b) into a */
+ if (MPFR_LIKELY(an + (mp_size_t) cancel1 <= bn))
+ /* a: <----------------+-----------|---->
+ b: <-----------------------------------------> */
+ MPN_COPY (ap, bp + bn - (an + cancel1), an);
+ else
+ /* a: <----------------+-----------|---->
+ b: <-------------------------> */
+ if ((mp_size_t) cancel1 < bn) /* otherwise b does not overlap with a */
+ {
+ MPN_ZERO (ap, an + cancel1 - bn);
+ MPN_COPY (ap + (an + cancel1 - bn), bp, bn - cancel1);
+ }
+ else
+ MPN_ZERO (ap, an);
+
+#ifdef DEBUG
+ printf("after copying high(b), a="); mpfr_print_binary(a); putchar('\n');
+#endif
+
+ /* subtract high(c) */
+ if (MPFR_LIKELY(an + cancel2 > 0)) /* otherwise c does not overlap with a */
+ {
+ mp_limb_t *ap2;
+
+ if (cancel2 >= 0)
+ {
+ if (an + cancel2 <= cn)
+ /* a: <----------------------------->
+ c: <-----------------------------------------> */
+ mpn_sub_n (ap, ap, cp + cn - (an + cancel2), an);
+ else
+ /* a: <---------------------------->
+ c: <-------------------------> */
+ {
+ ap2 = ap + an + (cancel2 - cn);
+ if (cn > cancel2)
+ mpn_sub_n (ap2, ap2, cp, cn - cancel2);
+ }
+ }
+ else /* cancel2 < 0 */
+ {
+ mp_limb_t borrow;
+
+ if (an + cancel2 <= cn)
+ /* a: <----------------------------->
+ c: <-----------------------------> */
+ borrow = mpn_sub_n (ap, ap, cp + cn - (an + cancel2),
+ an + cancel2);
+ else
+ /* a: <---------------------------->
+ c: <----------------> */
+ {
+ ap2 = ap + an + cancel2 - cn;
+ borrow = mpn_sub_n (ap2, ap2, cp, cn);
+ }
+ ap2 = ap + an + cancel2;
+ mpn_sub_1 (ap2, ap2, -cancel2, borrow);
+ }
+ }
+
+#ifdef DEBUG
+ printf("after subtracting high(c), a=");
+ mpfr_print_binary(a);
+ putchar('\n');
+#endif
+
+ /* now perform rounding */
+ sh = (mpfr_prec_t) an * GMP_NUMB_BITS - MPFR_PREC(a);
+ /* last unused bits from a */
+ carry = ap[0] & MPFR_LIMB_MASK (sh);
+ ap[0] -= carry;
+
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ {
+ if (MPFR_LIKELY(sh))
+ {
+ /* can decide except when carry = 2^(sh-1) [middle]
+ or carry = 0 [truncate, but cannot decide inexact flag] */
+ if (carry > (MPFR_LIMB_ONE << (sh - 1)))
+ goto add_one_ulp;
+ else if ((0 < carry) && (carry < (MPFR_LIMB_ONE << (sh - 1))))
+ {
+ inexact = -1; /* result if smaller than exact value */
+ goto truncate;
+ }
+ /* now carry = 2^(sh-1), in which case cmp_low=2,
+ or carry = 0, in which case cmp_low=0 */
+ cmp_low = (carry == 0) ? 0 : 2;
+ }
+ }
+ else /* directed rounding: set rnd_mode to RNDZ iff toward zero */
+ {
+ if (MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd_mode, MPFR_IS_NEG(a)))
+ rnd_mode = MPFR_RNDZ;
+
+ if (carry)
+ {
+ if (rnd_mode == MPFR_RNDZ)
+ {
+ inexact = -1;
+ goto truncate;
+ }
+ else /* round away */
+ goto add_one_ulp;
+ }
+ }
+
+ /* we have to consider the low (bn - (an+cancel1)) limbs from b,
+ and the (cn - (an+cancel2)) limbs from c. */
+ bn -= an + cancel1;
+ cn0 = cn;
+ cn -= an + cancel2;
+
+#ifdef DEBUG
+ printf ("last sh=%d bits from a are %lu, bn=%ld, cn=%ld\n",
+ sh, (unsigned long) carry, (long) bn, (long) cn);
+#endif
+
+ /* for rounding to nearest, we couldn't conclude up to here in the following
+ cases:
+ 1. sh = 0, then cmp_low=0: we can either truncate, subtract one ulp
+ or add one ulp: -1 ulp < low(b)-low(c) < 1 ulp
+ 2. sh > 0 but the low sh bits from high(b)-high(c) equal 2^(sh-1):
+ -0.5 ulp <= -1/2^sh < low(b)-low(c)-0.5 < 1/2^sh <= 0.5 ulp
+ we can't decide the rounding, in that case cmp_low=2:
+ either we truncate and flag=-1, or we add one ulp and flag=1
+ 3. the low sh>0 bits from high(b)-high(c) equal 0: we know we have to
+ truncate but we can't decide the ternary value, here cmp_low=0:
+ -0.5 ulp <= -1/2^sh < low(b)-low(c) < 1/2^sh <= 0.5 ulp
+ we always truncate and inexact can be any of -1,0,1
+ */
+
+ /* note: here cn might exceed cn0, in which case we consider a zero limb */
+ for (k = 0; (bn > 0) || (cn > 0); k = 1)
+ {
+ /* if cmp_low < 0, we know low(b) - low(c) < 0
+ if cmp_low > 0, we know low(b) - low(c) > 0
+ (more precisely if cmp_low = 2, low(b) - low(c) = 0.5 ulp so far)
+ if cmp_low = 0, so far low(b) - low(c) = 0 */
+
+ /* get next limbs */
+ bb = (bn > 0) ? bp[--bn] : 0;
+ if ((cn > 0) && (cn-- <= cn0))
+ cc = cp[cn];
+ else
+ cc = 0;
+
+ /* cmp_low compares low(b) and low(c) */
+ if (cmp_low == 0) /* case 1 or 3 */
+ cmp_low = (bb < cc) ? -2+k : (bb > cc) ? 1 : 0;
+
+ /* Case 1 for k=0 splits into 7 subcases:
+ 1a: bb > cc + half
+ 1b: bb = cc + half
+ 1c: 0 < bb - cc < half
+ 1d: bb = cc
+ 1e: -half < bb - cc < 0
+ 1f: bb - cc = -half
+ 1g: bb - cc < -half
+
+ Case 2 splits into 3 subcases:
+ 2a: bb > cc
+ 2b: bb = cc
+ 2c: bb < cc
+
+ Case 3 splits into 3 subcases:
+ 3a: bb > cc
+ 3b: bb = cc
+ 3c: bb < cc
+ */
+
+ /* the case rounding to nearest with sh=0 is special since one couldn't
+ subtract above 1/2 ulp in the trailing limb of the result */
+ if (rnd_mode == MPFR_RNDN && sh == 0 && k == 0) /* case 1 for k=0 */
+ {
+ mp_limb_t half = MPFR_LIMB_HIGHBIT;
+
+ /* add one ulp if bb > cc + half
+ truncate if cc - half < bb < cc + half
+ sub one ulp if bb < cc - half
+ */
+
+ if (cmp_low < 0) /* bb < cc: -1 ulp < low(b) - low(c) < 0,
+ cases 1e, 1f and 1g */
+ {
+ if (cc >= half)
+ cc -= half;
+ else /* since bb < cc < half, bb+half < 2*half */
+ bb += half;
+ /* now we have bb < cc + half:
+ we have to subtract one ulp if bb < cc,
+ and truncate if bb > cc */
+ }
+ else if (cmp_low >= 0) /* bb >= cc, cases 1a to 1d */
+ {
+ if (cc < half)
+ cc += half;
+ else /* since bb >= cc >= half, bb - half >= 0 */
+ bb -= half;
+ /* now we have bb > cc - half: we have to add one ulp if bb > cc,
+ and truncate if bb < cc */
+ if (cmp_low > 0)
+ cmp_low = 2;
+ }
+ }
+
+#ifdef DEBUG
+ printf ("k=%u bb=%lu cc=%lu cmp_low=%d\n", k,
+ (unsigned long) bb, (unsigned long) cc, cmp_low);
+#endif
+ if (cmp_low < 0) /* low(b) - low(c) < 0: either truncate or subtract
+ one ulp */
+ {
+ if (rnd_mode == MPFR_RNDZ)
+ goto sub_one_ulp; /* set inexact=-1 */
+ else if (rnd_mode != MPFR_RNDN) /* round away */
+ {
+ inexact = 1;
+ goto truncate;
+ }
+ else /* round to nearest */
+ {
+ /* If cmp_low < 0 and bb > cc, then -0.5 ulp < low(b)-low(c) < 0,
+ whatever the value of sh.
+ If sh>0, then cmp_low < 0 implies that the initial neglected
+ sh bits were 0 (otherwise cmp_low=2 initially), thus the
+ weight of the new bits is less than 0.5 ulp too.
+ If k > 0 (and sh=0) this means that either the first neglected
+ limbs bb and cc were equal (thus cmp_low was 0 for k=0),
+ or we had bb - cc = -0.5 ulp or 0.5 ulp.
+ The last case is not possible here since we would have
+ cmp_low > 0 which is sticky.
+ In the first case (where we have cmp_low = -1), we truncate,
+ whereas in the 2nd case we have cmp_low = -2 and we subtract
+ one ulp.
+ */
+ if (bb > cc || sh > 0 || cmp_low == -1)
+ { /* -0.5 ulp < low(b)-low(c) < 0,
+ bb > cc corresponds to cases 1e and 1f1
+ sh > 0 corresponds to cases 3c and 3b3
+ cmp_low = -1 corresponds to case 1d3 (also 3b3) */
+ inexact = 1;
+ goto truncate;
+ }
+ else if (bb < cc) /* here sh = 0 and low(b)-low(c) < -0.5 ulp,
+ this corresponds to cases 1g and 1f3 */
+ goto sub_one_ulp;
+ /* the only case where we can't conclude is sh=0 and bb=cc,
+ i.e., we have low(b) - low(c) = -0.5 ulp (up to now), thus
+ we don't know if we must truncate or subtract one ulp.
+ Note: for sh=0 we can't have low(b) - low(c) = -0.5 ulp up to
+ now, since low(b) - low(c) > 1/2^sh */
+ }
+ }
+ else if (cmp_low > 0) /* 0 < low(b) - low(c): either truncate or
+ add one ulp */
+ {
+ if (rnd_mode == MPFR_RNDZ)
+ {
+ inexact = -1;
+ goto truncate;
+ }
+ else if (rnd_mode != MPFR_RNDN) /* round away */
+ goto add_one_ulp;
+ else /* round to nearest */
+ {
+ if (bb > cc)
+ {
+ /* if sh=0, then bb>cc means that low(b)-low(c) > 0.5 ulp,
+ and similarly when cmp_low=2 */
+ if (cmp_low == 2) /* cases 1a, 1b1, 2a and 2b1 */
+ goto add_one_ulp;
+ /* sh > 0 and cmp_low > 0: this implies that the sh initial
+ neglected bits were 0, and the remaining low(b)-low(c)>0,
+ but its weight is less than 0.5 ulp */
+ else /* 0 < low(b) - low(c) < 0.5 ulp, this corresponds to
+ cases 3a, 1d1 and 3b1 */
+ {
+ inexact = -1;
+ goto truncate;
+ }
+ }
+ else if (bb < cc) /* 0 < low(b) - low(c) < 0.5 ulp, cases 1c,
+ 1b3, 2b3 and 2c */
+ {
+ inexact = -1;
+ goto truncate;
+ }
+ /* the only case where we can't conclude is bb=cc, i.e.,
+ low(b) - low(c) = 0.5 ulp (up to now), thus we don't know
+ if we must truncate or add one ulp. */
+ }
+ }
+ /* after k=0, we cannot conclude in the following cases, we split them
+ according to the values of bb and cc for k=1:
+ 1b. sh=0 and cmp_low = 1 and bb-cc = half [around 0.5 ulp]
+ 1b1. bb > cc: add one ulp, inex = 1
+ 1b2: bb = cc: cannot conclude
+ 1b3: bb < cc: truncate, inex = -1
+ 1d. sh=0 and cmp_low = 0 and bb-cc = 0 [around 0]
+ 1d1: bb > cc: truncate, inex = -1
+ 1d2: bb = cc: cannot conclude
+ 1d3: bb < cc: truncate, inex = +1
+ 1f. sh=0 and cmp_low = -1 and bb-cc = -half [around -0.5 ulp]
+ 1f1: bb > cc: truncate, inex = +1
+ 1f2: bb = cc: cannot conclude
+ 1f3: bb < cc: sub one ulp, inex = -1
+ 2b. sh > 0 and cmp_low = 2 and bb=cc [around 0.5 ulp]
+ 2b1. bb > cc: add one ulp, inex = 1
+ 2b2: bb = cc: cannot conclude
+ 2b3: bb < cc: truncate, inex = -1
+ 3b. sh > 0 and cmp_low = 0 [around 0]
+ 3b1. bb > cc: truncate, inex = -1
+ 3b2: bb = cc: cannot conclude
+ 3b3: bb < cc: truncate, inex = +1
+ */
+ }
+
+ if ((rnd_mode == MPFR_RNDN) && cmp_low != 0)
+ {
+ /* even rounding rule */
+ if ((ap[0] >> sh) & 1)
+ {
+ if (cmp_low < 0)
+ goto sub_one_ulp;
+ else
+ goto add_one_ulp;
+ }
+ else
+ inexact = (cmp_low > 0) ? -1 : 1;
+ }
+ else
+ inexact = 0;
+ goto truncate;
+
+ sub_one_ulp: /* sub one unit in last place to a */
+ mpn_sub_1 (ap, ap, an, MPFR_LIMB_ONE << sh);
+ inexact = -1;
+ goto end_of_sub;
+
+ add_one_ulp: /* add one unit in last place to a */
+ if (MPFR_UNLIKELY(mpn_add_1 (ap, ap, an, MPFR_LIMB_ONE << sh)))
+ /* result is a power of 2: 11111111111111 + 1 = 1000000000000000 */
+ {
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
+ add_exp = 1;
+ }
+ inexact = 1; /* result larger than exact value */
+
+ truncate:
+ if (MPFR_UNLIKELY((ap[an-1] >> (GMP_NUMB_BITS - 1)) == 0))
+ /* case 1 - epsilon */
+ {
+ ap[an-1] = MPFR_LIMB_HIGHBIT;
+ add_exp = 1;
+ }
+
+ end_of_sub:
+ /* we have to set MPFR_EXP(a) to MPFR_EXP(b) - cancel + add_exp, taking
+ care of underflows/overflows in that computation, and of the allowed
+ exponent range */
+ if (MPFR_LIKELY(cancel))
+ {
+ mpfr_exp_t exp_a;
+
+ cancel -= add_exp; /* OK: add_exp is an int equal to 0 or 1 */
+ exp_a = MPFR_GET_EXP (b) - cancel;
+ if (MPFR_UNLIKELY(exp_a < __gmpfr_emin))
+ {
+ MPFR_TMP_FREE(marker);
+ if (rnd_mode == MPFR_RNDN &&
+ (exp_a < __gmpfr_emin - 1 ||
+ (inexact >= 0 && mpfr_powerof2_raw (a))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+ MPFR_SET_EXP (a, exp_a);
+ }
+ else /* cancel = 0: MPFR_EXP(a) <- MPFR_EXP(b) + add_exp */
+ {
+ /* in case cancel = 0, add_exp can still be 1, in case b is just
+ below a power of two, c is very small, prec(a) < prec(b),
+ and rnd=away or nearest */
+ mpfr_exp_t exp_b;
+
+ exp_b = MPFR_GET_EXP (b);
+ if (MPFR_UNLIKELY(add_exp && exp_b == __gmpfr_emax))
+ {
+ MPFR_TMP_FREE(marker);
+ return mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+ MPFR_SET_EXP (a, exp_b + add_exp);
+ }
+ MPFR_TMP_FREE(marker);
+#ifdef DEBUG
+ printf ("result is a="); mpfr_print_binary(a); putchar('\n');
+#endif
+ /* check that result is msb-normalized */
+ MPFR_ASSERTD(ap[an-1] > ~ap[an-1]);
+ MPFR_RET (inexact * MPFR_INT_SIGN (a));
+}
diff --git a/mpfr/src/sub1sp.c b/mpfr/src/sub1sp.c
new file mode 100644
index 0000000000..07417343ba
--- /dev/null
+++ b/mpfr/src/sub1sp.c
@@ -0,0 +1,810 @@
+/* mpfr_sub1sp -- internal function to perform a "real" substraction
+ All the op must have the same precision
+
+Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* Check if we have to check the result of mpfr_sub1sp with mpfr_sub1 */
+#ifdef WANT_ASSERT
+# if WANT_ASSERT >= 2
+
+int mpfr_sub1sp2 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode);
+int mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t tmpa, tmpb, tmpc;
+ int inexb, inexc, inexact, inexact2;
+
+ mpfr_init2 (tmpa, MPFR_PREC (a));
+ mpfr_init2 (tmpb, MPFR_PREC (b));
+ mpfr_init2 (tmpc, MPFR_PREC (c));
+
+ inexb = mpfr_set (tmpb, b, MPFR_RNDN);
+ MPFR_ASSERTN (inexb == 0);
+
+ inexc = mpfr_set (tmpc, c, MPFR_RNDN);
+ MPFR_ASSERTN (inexc == 0);
+
+ inexact2 = mpfr_sub1 (tmpa, tmpb, tmpc, rnd_mode);
+ inexact = mpfr_sub1sp2(a, b, c, rnd_mode);
+
+ if (mpfr_cmp (tmpa, a) || inexact != inexact2)
+ {
+ fprintf (stderr, "sub1 & sub1sp return different values for %s\n"
+ "Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nB = ",
+ mpfr_print_rnd_mode (rnd_mode), (unsigned long) MPFR_PREC (a),
+ (unsigned long) MPFR_PREC (b), (unsigned long) MPFR_PREC (c));
+ mpfr_fprint_binary (stderr, tmpb);
+ fprintf (stderr, "\nC = ");
+ mpfr_fprint_binary (stderr, tmpc);
+ fprintf (stderr, "\nSub1 : ");
+ mpfr_fprint_binary (stderr, tmpa);
+ fprintf (stderr, "\nSub1sp: ");
+ mpfr_fprint_binary (stderr, a);
+ fprintf (stderr, "\nInexact sp = %d | Inexact = %d\n",
+ inexact, inexact2);
+ MPFR_ASSERTN (0);
+ }
+ mpfr_clears (tmpa, tmpb, tmpc, (mpfr_ptr) 0);
+ return inexact;
+}
+# define mpfr_sub1sp mpfr_sub1sp2
+# endif
+#endif
+
+/* Debugging support */
+#ifdef DEBUG
+# undef DEBUG
+# define DEBUG(x) (x)
+#else
+# define DEBUG(x) /**/
+#endif
+
+/* Rounding Sub */
+
+/*
+ compute sgn(b)*(|b| - |c|) if |b|>|c| else -sgn(b)*(|c| -|b|)
+ Returns 0 iff result is exact,
+ a negative value when the result is less than the exact value,
+ a positive value otherwise.
+*/
+
+/* A0...Ap-1
+ * Cp Cp+1 ....
+ * <- C'p+1 ->
+ * Cp = -1 if calculated from c mantissa
+ * Cp = 0 if 0 from a or c
+ * Cp = 1 if calculated from a.
+ * C'p+1 = First bit not null or 0 if there isn't one
+ *
+ * Can't have Cp=-1 and C'p+1=1*/
+
+/* RND = MPFR_RNDZ:
+ * + if Cp=0 and C'p+1=0,1, Truncate.
+ * + if Cp=0 and C'p+1=-1, SubOneUlp
+ * + if Cp=-1, SubOneUlp
+ * + if Cp=1, AddOneUlp
+ * RND = MPFR_RNDA (Away)
+ * + if Cp=0 and C'p+1=0,-1, Truncate
+ * + if Cp=0 and C'p+1=1, AddOneUlp
+ * + if Cp=1, AddOneUlp
+ * + if Cp=-1, Truncate
+ * RND = MPFR_RNDN
+ * + if Cp=0, Truncate
+ * + if Cp=1 and C'p+1=1, AddOneUlp
+ * + if Cp=1 and C'p+1=-1, Truncate
+ * + if Cp=1 and C'p+1=0, Truncate if Ap-1=0, AddOneUlp else
+ * + if Cp=-1 and C'p+1=-1, SubOneUlp
+ * + if Cp=-1 and C'p+1=0, Truncate if Ap-1=0, SubOneUlp else
+ *
+ * If AddOneUlp:
+ * If carry, then it is 11111111111 + 1 = 10000000000000
+ * ap[n-1]=MPFR_HIGHT_BIT
+ * If SubOneUlp:
+ * If we lose one bit, it is 1000000000 - 1 = 0111111111111
+ * Then shift, and put as last bit x which is calculated
+ * according Cp, Cp-1 and rnd_mode.
+ * If Truncate,
+ * If it is a power of 2,
+ * we may have to suboneulp in some special cases.
+ *
+ * To simplify, we don't use Cp = 1.
+ *
+ */
+
+int
+mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mpfr_exp_t bx,cx;
+ mpfr_uexp_t d;
+ mpfr_prec_t p, sh, cnt;
+ mp_size_t n;
+ mp_limb_t *ap, *bp, *cp;
+ mp_limb_t limb;
+ int inexact;
+ mp_limb_t bcp,bcp1; /* Cp and C'p+1 */
+ mp_limb_t bbcp = (mp_limb_t) -1, bbcp1 = (mp_limb_t) -1; /* Cp+1 and C'p+2,
+ gcc claims that they might be used uninitialized. We fill them with invalid
+ values, which should produce a failure if so. See README.dev file. */
+
+ MPFR_TMP_DECL(marker);
+
+ MPFR_TMP_MARK(marker);
+
+ MPFR_ASSERTD(MPFR_PREC(a) == MPFR_PREC(b) && MPFR_PREC(b) == MPFR_PREC(c));
+ MPFR_ASSERTD(MPFR_IS_PURE_FP(b));
+ MPFR_ASSERTD(MPFR_IS_PURE_FP(c));
+
+ /* Read prec and num of limbs */
+ p = MPFR_PREC (b);
+ n = MPFR_PREC2LIMBS (p);
+
+ /* Fast cmp of |b| and |c|*/
+ bx = MPFR_GET_EXP (b);
+ cx = MPFR_GET_EXP (c);
+ if (MPFR_UNLIKELY(bx == cx))
+ {
+ mp_size_t k = n - 1;
+ /* Check mantissa since exponent are equals */
+ bp = MPFR_MANT(b);
+ cp = MPFR_MANT(c);
+ while (k>=0 && MPFR_UNLIKELY(bp[k] == cp[k]))
+ k--;
+ if (MPFR_UNLIKELY(k < 0))
+ /* b == c ! */
+ {
+ /* Return exact number 0 */
+ if (rnd_mode == MPFR_RNDD)
+ MPFR_SET_NEG(a);
+ else
+ MPFR_SET_POS(a);
+ MPFR_SET_ZERO(a);
+ MPFR_RET(0);
+ }
+ else if (bp[k] > cp[k])
+ goto BGreater;
+ else
+ {
+ MPFR_ASSERTD(bp[k]<cp[k]);
+ goto CGreater;
+ }
+ }
+ else if (MPFR_UNLIKELY(bx < cx))
+ {
+ /* Swap b and c and set sign */
+ mpfr_srcptr t;
+ mpfr_exp_t tx;
+ CGreater:
+ MPFR_SET_OPPOSITE_SIGN(a,b);
+ t = b; b = c; c = t;
+ tx = bx; bx = cx; cx = tx;
+ }
+ else
+ {
+ /* b > c */
+ BGreater:
+ MPFR_SET_SAME_SIGN(a,b);
+ }
+
+ /* Now b > c */
+ MPFR_ASSERTD(bx >= cx);
+ d = (mpfr_uexp_t) bx - cx;
+ DEBUG (printf ("New with diff=%lu\n", (unsigned long) d));
+
+ if (MPFR_UNLIKELY(d <= 1))
+ {
+ if (MPFR_LIKELY(d < 1))
+ {
+ /* <-- b -->
+ <-- c --> : exact sub */
+ ap = MPFR_MANT(a);
+ mpn_sub_n (ap, MPFR_MANT(b), MPFR_MANT(c), n);
+ /* Normalize */
+ ExactNormalize:
+ limb = ap[n-1];
+ if (MPFR_LIKELY(limb))
+ {
+ /* First limb is not zero. */
+ count_leading_zeros(cnt, limb);
+ /* cnt could be == 0 <= SubD1Lose */
+ if (MPFR_LIKELY(cnt))
+ {
+ mpn_lshift(ap, ap, n, cnt); /* Normalize number */
+ bx -= cnt; /* Update final expo */
+ }
+ /* Last limb should be ok */
+ MPFR_ASSERTD(!(ap[0] & MPFR_LIMB_MASK((unsigned int) (-p)
+ % GMP_NUMB_BITS)));
+ }
+ else
+ {
+ /* First limb is zero */
+ mp_size_t k = n-1, len;
+ /* Find the first limb not equal to zero.
+ FIXME:It is assume it exists (since |b| > |c| and same prec)*/
+ do
+ {
+ MPFR_ASSERTD( k > 0 );
+ limb = ap[--k];
+ }
+ while (limb == 0);
+ MPFR_ASSERTD(limb != 0);
+ count_leading_zeros(cnt, limb);
+ k++;
+ len = n - k; /* Number of last limb */
+ MPFR_ASSERTD(k >= 0);
+ if (MPFR_LIKELY(cnt))
+ mpn_lshift(ap+len, ap, k, cnt); /* Normalize the High Limb*/
+ else
+ {
+ /* Must use DECR since src and dest may overlap & dest>=src*/
+ MPN_COPY_DECR(ap+len, ap, k);
+ }
+ MPN_ZERO(ap, len); /* Zeroing the last limbs */
+ bx -= cnt + len*GMP_NUMB_BITS; /* Update Expo */
+ /* Last limb should be ok */
+ MPFR_ASSERTD(!(ap[len]&MPFR_LIMB_MASK((unsigned int) (-p)
+ % GMP_NUMB_BITS)));
+ }
+ /* Check expo underflow */
+ if (MPFR_UNLIKELY(bx < __gmpfr_emin))
+ {
+ MPFR_TMP_FREE(marker);
+ /* inexact=0 */
+ DEBUG( printf("(D==0 Underflow)\n") );
+ if (rnd_mode == MPFR_RNDN &&
+ (bx < __gmpfr_emin - 1 ||
+ (/*inexact >= 0 &&*/ mpfr_powerof2_raw (a))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+ MPFR_SET_EXP (a, bx);
+ /* No rounding is necessary since the result is exact */
+ MPFR_ASSERTD(ap[n-1] > ~ap[n-1]);
+ MPFR_TMP_FREE(marker);
+ return 0;
+ }
+ else /* if (d == 1) */
+ {
+ /* | <-- b -->
+ | <-- c --> */
+ mp_limb_t c0, mask;
+ mp_size_t k;
+ MPFR_UNSIGNED_MINUS_MODULO(sh, p);
+ /* If we lose at least one bit, compute 2*b-c (Exact)
+ * else compute b-c/2 */
+ bp = MPFR_MANT(b);
+ cp = MPFR_MANT(c);
+ k = n-1;
+ limb = bp[k] - cp[k]/2;
+ if (limb > MPFR_LIMB_HIGHBIT)
+ {
+ /* We can't lose precision: compute b-c/2 */
+ /* Shift c in the allocated temporary block */
+ SubD1NoLose:
+ c0 = cp[0] & (MPFR_LIMB_ONE<<sh);
+ cp = MPFR_TMP_LIMBS_ALLOC (n);
+ mpn_rshift(cp, MPFR_MANT(c), n, 1);
+ if (MPFR_LIKELY(c0 == 0))
+ {
+ /* Result is exact: no need of rounding! */
+ ap = MPFR_MANT(a);
+ mpn_sub_n (ap, bp, cp, n);
+ MPFR_SET_EXP(a, bx); /* No expo overflow! */
+ /* No truncate or normalize is needed */
+ MPFR_ASSERTD(ap[n-1] > ~ap[n-1]);
+ /* No rounding is necessary since the result is exact */
+ MPFR_TMP_FREE(marker);
+ return 0;
+ }
+ ap = MPFR_MANT(a);
+ mask = ~MPFR_LIMB_MASK(sh);
+ cp[0] &= mask; /* Delete last bit of c */
+ mpn_sub_n (ap, bp, cp, n);
+ MPFR_SET_EXP(a, bx); /* No expo overflow! */
+ MPFR_ASSERTD( !(ap[0] & ~mask) ); /* Check last bits */
+ /* No normalize is needed */
+ MPFR_ASSERTD(ap[n-1] > ~ap[n-1]);
+ /* Rounding is necessary since c0 = 1*/
+ /* Cp =-1 and C'p+1=0 */
+ bcp = 1; bcp1 = 0;
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ {
+ /* Even Rule apply: Check Ap-1 */
+ if (MPFR_LIKELY( (ap[0] & (MPFR_LIMB_ONE<<sh)) == 0) )
+ goto truncate;
+ else
+ goto sub_one_ulp;
+ }
+ MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
+ if (rnd_mode == MPFR_RNDZ)
+ goto sub_one_ulp;
+ else
+ goto truncate;
+ }
+ else if (MPFR_LIKELY(limb < MPFR_LIMB_HIGHBIT))
+ {
+ /* We lose at least one bit of prec */
+ /* Calcul of 2*b-c (Exact) */
+ /* Shift b in the allocated temporary block */
+ SubD1Lose:
+ bp = MPFR_TMP_LIMBS_ALLOC (n);
+ mpn_lshift (bp, MPFR_MANT(b), n, 1);
+ ap = MPFR_MANT(a);
+ mpn_sub_n (ap, bp, cp, n);
+ bx--;
+ goto ExactNormalize;
+ }
+ else
+ {
+ /* Case: limb = 100000000000 */
+ /* Check while b[k] == c'[k] (C' is C shifted by 1) */
+ /* If b[k]<c'[k] => We lose at least one bit*/
+ /* If b[k]>c'[k] => We don't lose any bit */
+ /* If k==-1 => We don't lose any bit
+ AND the result is 100000000000 0000000000 00000000000 */
+ mp_limb_t carry;
+ do {
+ carry = cp[k]&MPFR_LIMB_ONE;
+ k--;
+ } while (k>=0 &&
+ bp[k]==(carry=cp[k]/2+(carry<<(GMP_NUMB_BITS-1))));
+ if (MPFR_UNLIKELY(k<0))
+ {
+ /*If carry then (sh==0 and Virtual c'[-1] > Virtual b[-1]) */
+ if (MPFR_UNLIKELY(carry)) /* carry = cp[0]&MPFR_LIMB_ONE */
+ {
+ /* FIXME: Can be faster? */
+ MPFR_ASSERTD(sh == 0);
+ goto SubD1Lose;
+ }
+ /* Result is a power of 2 */
+ ap = MPFR_MANT (a);
+ MPN_ZERO (ap, n);
+ ap[n-1] = MPFR_LIMB_HIGHBIT;
+ MPFR_SET_EXP (a, bx); /* No expo overflow! */
+ /* No Normalize is needed*/
+ /* No Rounding is needed */
+ MPFR_TMP_FREE (marker);
+ return 0;
+ }
+ /* carry = cp[k]/2+(cp[k-1]&1)<<(GMP_NUMB_BITS-1) = c'[k]*/
+ else if (bp[k] > carry)
+ goto SubD1NoLose;
+ else
+ {
+ MPFR_ASSERTD(bp[k]<carry);
+ goto SubD1Lose;
+ }
+ }
+ }
+ }
+ else if (MPFR_UNLIKELY(d >= p))
+ {
+ ap = MPFR_MANT(a);
+ MPFR_UNSIGNED_MINUS_MODULO(sh, p);
+ /* We can't set A before since we use cp for rounding... */
+ /* Perform rounding: check if a=b or a=b-ulp(b) */
+ if (MPFR_UNLIKELY(d == p))
+ {
+ /* cp == -1 and c'p+1 = ? */
+ bcp = 1;
+ /* We need Cp+1 later for a very improbable case. */
+ bbcp = (MPFR_MANT(c)[n-1] & (MPFR_LIMB_ONE<<(GMP_NUMB_BITS-2)));
+ /* We need also C'p+1 for an even more unprobable case... */
+ if (MPFR_LIKELY( bbcp ))
+ bcp1 = 1;
+ else
+ {
+ cp = MPFR_MANT(c);
+ if (MPFR_UNLIKELY(cp[n-1] == MPFR_LIMB_HIGHBIT))
+ {
+ mp_size_t k = n-1;
+ do {
+ k--;
+ } while (k>=0 && cp[k]==0);
+ bcp1 = (k>=0);
+ }
+ else
+ bcp1 = 1;
+ }
+ DEBUG( printf("(D=P) Cp=-1 Cp+1=%d C'p+1=%d \n", bbcp!=0, bcp1!=0) );
+ bp = MPFR_MANT (b);
+
+ /* Even if src and dest overlap, it is ok using MPN_COPY */
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ {
+ if (MPFR_UNLIKELY( bcp && bcp1==0 ))
+ /* Cp=-1 and C'p+1=0: Even rule Apply! */
+ /* Check Ap-1 = Bp-1 */
+ if ((bp[0] & (MPFR_LIMB_ONE<<sh)) == 0)
+ {
+ MPN_COPY(ap, bp, n);
+ goto truncate;
+ }
+ MPN_COPY(ap, bp, n);
+ goto sub_one_ulp;
+ }
+ MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
+ if (rnd_mode == MPFR_RNDZ)
+ {
+ MPN_COPY(ap, bp, n);
+ goto sub_one_ulp;
+ }
+ else
+ {
+ MPN_COPY(ap, bp, n);
+ goto truncate;
+ }
+ }
+ else
+ {
+ /* Cp=0, Cp+1=-1 if d==p+1, C'p+1=-1 */
+ bcp = 0; bbcp = (d==p+1); bcp1 = 1;
+ DEBUG( printf("(D>P) Cp=%d Cp+1=%d C'p+1=%d\n", bcp!=0,bbcp!=0,bcp1!=0) );
+ /* Need to compute C'p+2 if d==p+1 and if rnd_mode=NEAREST
+ (Because of a very improbable case) */
+ if (MPFR_UNLIKELY(d==p+1 && rnd_mode==MPFR_RNDN))
+ {
+ cp = MPFR_MANT(c);
+ if (MPFR_UNLIKELY(cp[n-1] == MPFR_LIMB_HIGHBIT))
+ {
+ mp_size_t k = n-1;
+ do {
+ k--;
+ } while (k>=0 && cp[k]==0);
+ bbcp1 = (k>=0);
+ }
+ else
+ bbcp1 = 1;
+ DEBUG( printf("(D>P) C'p+2=%d\n", bbcp1!=0) );
+ }
+ /* Copy mantissa B in A */
+ MPN_COPY(ap, MPFR_MANT(b), n);
+ /* Round */
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ goto truncate;
+ MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
+ if (rnd_mode == MPFR_RNDZ)
+ goto sub_one_ulp;
+ else /* rnd_mode = AWAY */
+ goto truncate;
+ }
+ }
+ else
+ {
+ mpfr_uexp_t dm;
+ mp_size_t m;
+ mp_limb_t mask;
+
+ /* General case: 2 <= d < p */
+ MPFR_UNSIGNED_MINUS_MODULO(sh, p);
+ cp = MPFR_TMP_LIMBS_ALLOC (n);
+
+ /* Shift c in temporary allocated place */
+ dm = d % GMP_NUMB_BITS;
+ m = d / GMP_NUMB_BITS;
+ if (MPFR_UNLIKELY(dm == 0))
+ {
+ /* dm = 0 and m > 0: Just copy */
+ MPFR_ASSERTD(m!=0);
+ MPN_COPY(cp, MPFR_MANT(c)+m, n-m);
+ MPN_ZERO(cp+n-m, m);
+ }
+ else if (MPFR_LIKELY(m == 0))
+ {
+ /* dm >=2 and m == 0: just shift */
+ MPFR_ASSERTD(dm >= 2);
+ mpn_rshift(cp, MPFR_MANT(c), n, dm);
+ }
+ else
+ {
+ /* dm > 0 and m > 0: shift and zero */
+ mpn_rshift(cp, MPFR_MANT(c)+m, n-m, dm);
+ MPN_ZERO(cp+n-m, m);
+ }
+
+ DEBUG( mpfr_print_mant_binary("Before", MPFR_MANT(c), p) );
+ DEBUG( mpfr_print_mant_binary("B= ", MPFR_MANT(b), p) );
+ DEBUG( mpfr_print_mant_binary("After ", cp, p) );
+
+ /* Compute bcp=Cp and bcp1=C'p+1 */
+ if (MPFR_LIKELY(sh))
+ {
+ /* Try to compute them from C' rather than C (FIXME: Faster?) */
+ bcp = (cp[0] & (MPFR_LIMB_ONE<<(sh-1))) ;
+ if (MPFR_LIKELY( cp[0] & MPFR_LIMB_MASK(sh-1) ))
+ bcp1 = 1;
+ else
+ {
+ /* We can't compute C'p+1 from C'. Compute it from C */
+ /* Start from bit x=p-d+sh in mantissa C
+ (+sh since we have already looked sh bits in C'!) */
+ mpfr_prec_t x = p-d+sh-1;
+ if (MPFR_LIKELY(x>p))
+ /* We are already looked at all the bits of c, so C'p+1 = 0*/
+ bcp1 = 0;
+ else
+ {
+ mp_limb_t *tp = MPFR_MANT(c);
+ mp_size_t kx = n-1 - (x / GMP_NUMB_BITS);
+ mpfr_prec_t sx = GMP_NUMB_BITS-1-(x%GMP_NUMB_BITS);
+ DEBUG (printf ("(First) x=%lu Kx=%ld Sx=%lu\n",
+ (unsigned long) x, (long) kx,
+ (unsigned long) sx));
+ /* Looks at the last bits of limb kx (if sx=0 does nothing)*/
+ if (tp[kx] & MPFR_LIMB_MASK(sx))
+ bcp1 = 1;
+ else
+ {
+ /*kx += (sx==0);*/
+ /*If sx==0, tp[kx] hasn't been checked*/
+ do {
+ kx--;
+ } while (kx>=0 && tp[kx]==0);
+ bcp1 = (kx >= 0);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Compute Cp and C'p+1 from C with sh=0 */
+ mp_limb_t *tp = MPFR_MANT(c);
+ /* Start from bit x=p-d in mantissa C */
+ mpfr_prec_t x = p-d;
+ mp_size_t kx = n-1 - (x / GMP_NUMB_BITS);
+ mpfr_prec_t sx = GMP_NUMB_BITS-1-(x%GMP_NUMB_BITS);
+ MPFR_ASSERTD(p >= d);
+ bcp = (tp[kx] & (MPFR_LIMB_ONE<<sx));
+ /* Looks at the last bits of limb kx (If sx=0, does nothing)*/
+ if (tp[kx] & MPFR_LIMB_MASK(sx))
+ bcp1 = 1;
+ else
+ {
+ /*kx += (sx==0);*/ /*If sx==0, tp[kx] hasn't been checked*/
+ do {
+ kx--;
+ } while (kx>=0 && tp[kx]==0);
+ bcp1 = (kx>=0);
+ }
+ }
+ DEBUG( printf("sh=%lu Cp=%d C'p+1=%d\n", sh, bcp!=0, bcp1!=0) );
+
+ /* Check if we can lose a bit, and if so compute Cp+1 and C'p+2 */
+ bp = MPFR_MANT(b);
+ if (MPFR_UNLIKELY((bp[n-1]-cp[n-1]) <= MPFR_LIMB_HIGHBIT))
+ {
+ /* We can lose a bit so we precompute Cp+1 and C'p+2 */
+ /* Test for trivial case: since C'p+1=0, Cp+1=0 and C'p+2 =0 */
+ if (MPFR_LIKELY(bcp1 == 0))
+ {
+ bbcp = 0;
+ bbcp1 = 0;
+ }
+ else /* bcp1 != 0 */
+ {
+ /* We can lose a bit:
+ compute Cp+1 and C'p+2 from mantissa C */
+ mp_limb_t *tp = MPFR_MANT(c);
+ /* Start from bit x=(p+1)-d in mantissa C */
+ mpfr_prec_t x = p+1-d;
+ mp_size_t kx = n-1 - (x/GMP_NUMB_BITS);
+ mpfr_prec_t sx = GMP_NUMB_BITS-1-(x%GMP_NUMB_BITS);
+ MPFR_ASSERTD(p > d);
+ DEBUG (printf ("(pre) x=%lu Kx=%ld Sx=%lu\n",
+ (unsigned long) x, (long) kx,
+ (unsigned long) sx));
+ bbcp = (tp[kx] & (MPFR_LIMB_ONE<<sx)) ;
+ /* Looks at the last bits of limb kx (If sx=0, does nothing)*/
+ /* If Cp+1=0, since C'p+1!=0, C'p+2=1 ! */
+ if (MPFR_LIKELY(bbcp==0 || (tp[kx]&MPFR_LIMB_MASK(sx))))
+ bbcp1 = 1;
+ else
+ {
+ /*kx += (sx==0);*/ /*If sx==0, tp[kx] hasn't been checked*/
+ do {
+ kx--;
+ } while (kx>=0 && tp[kx]==0);
+ bbcp1 = (kx>=0);
+ DEBUG (printf ("(Pre) Scan done for %ld\n", (long) kx));
+ }
+ } /*End of Bcp1 != 0*/
+ DEBUG( printf("(Pre) Cp+1=%d C'p+2=%d\n", bbcp!=0, bbcp1!=0) );
+ } /* End of "can lose a bit" */
+
+ /* Clean shifted C' */
+ mask = ~MPFR_LIMB_MASK (sh);
+ cp[0] &= mask;
+
+ /* Substract the mantissa c from b in a */
+ ap = MPFR_MANT(a);
+ mpn_sub_n (ap, bp, cp, n);
+ DEBUG( mpfr_print_mant_binary("Sub= ", ap, p) );
+
+ /* Normalize: we lose at max one bit*/
+ if (MPFR_UNLIKELY(MPFR_LIMB_MSB(ap[n-1]) == 0))
+ {
+ /* High bit is not set and we have to fix it! */
+ /* Ap >= 010000xxx001 */
+ mpn_lshift(ap, ap, n, 1);
+ /* Ap >= 100000xxx010 */
+ if (MPFR_UNLIKELY(bcp!=0)) /* Check if Cp = -1 */
+ /* Since Cp == -1, we have to substract one more */
+ {
+ mpn_sub_1(ap, ap, n, MPFR_LIMB_ONE<<sh);
+ MPFR_ASSERTD(MPFR_LIMB_MSB(ap[n-1]) != 0);
+ }
+ /* Ap >= 10000xxx001 */
+ /* Final exponent -1 since we have shifted the mantissa */
+ bx--;
+ /* Update bcp and bcp1 */
+ MPFR_ASSERTN(bbcp != (mp_limb_t) -1);
+ MPFR_ASSERTN(bbcp1 != (mp_limb_t) -1);
+ bcp = bbcp;
+ bcp1 = bbcp1;
+ /* We dont't have anymore a valid Cp+1!
+ But since Ap >= 100000xxx001, the final sub can't unnormalize!*/
+ }
+ MPFR_ASSERTD( !(ap[0] & ~mask) );
+
+ /* Rounding */
+ if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
+ {
+ if (MPFR_LIKELY(bcp==0))
+ goto truncate;
+ else if ((bcp1) || ((ap[0] & (MPFR_LIMB_ONE<<sh)) != 0))
+ goto sub_one_ulp;
+ else
+ goto truncate;
+ }
+
+ /* Update rounding mode */
+ MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
+ if (rnd_mode == MPFR_RNDZ && (MPFR_LIKELY(bcp || bcp1)))
+ goto sub_one_ulp;
+ goto truncate;
+ }
+ MPFR_RET_NEVER_GO_HERE ();
+
+ /* Sub one ulp to the result */
+ sub_one_ulp:
+ mpn_sub_1 (ap, ap, n, MPFR_LIMB_ONE << sh);
+ /* Result should be smaller than exact value: inexact=-1 */
+ inexact = -1;
+ /* Check normalisation */
+ if (MPFR_UNLIKELY(MPFR_LIMB_MSB(ap[n-1]) == 0))
+ {
+ /* ap was a power of 2, and we lose a bit */
+ /* Now it is 0111111111111111111[00000 */
+ mpn_lshift(ap, ap, n, 1);
+ bx--;
+ /* And the lost bit x depends on Cp+1, and Cp */
+ /* Compute Cp+1 if it isn't already compute (ie d==1) */
+ /* FIXME: Is this case possible? */
+ if (MPFR_UNLIKELY(d == 1))
+ bbcp = 0;
+ DEBUG( printf("(SubOneUlp)Cp=%d, Cp+1=%d C'p+1=%d\n", bcp!=0,bbcp!=0,bcp1!=0));
+ /* Compute the last bit (Since we have shifted the mantissa)
+ we need one more bit!*/
+ MPFR_ASSERTN(bbcp != (mp_limb_t) -1);
+ if ( (rnd_mode == MPFR_RNDZ && bcp==0)
+ || (rnd_mode==MPFR_RNDN && bbcp==0)
+ || (bcp && bcp1==0) ) /*Exact result*/
+ {
+ ap[0] |= MPFR_LIMB_ONE<<sh;
+ if (rnd_mode == MPFR_RNDN)
+ inexact = 1;
+ DEBUG( printf("(SubOneUlp) Last bit set\n") );
+ }
+ /* Result could be exact if C'p+1 = 0 and rnd == Zero
+ since we have had one more bit to the result */
+ /* Fixme: rnd_mode == MPFR_RNDZ needed ? */
+ if (bcp1==0 && rnd_mode==MPFR_RNDZ)
+ {
+ DEBUG( printf("(SubOneUlp) Exact result\n") );
+ inexact = 0;
+ }
+ }
+
+ goto end_of_sub;
+
+ truncate:
+ /* Check if the result is an exact power of 2: 100000000000
+ in which cases, we could have to do sub_one_ulp due to some nasty reasons:
+ If Result is a Power of 2:
+ + If rnd = AWAY,
+ | If Cp=-1 and C'p+1 = 0, SubOneUlp and the result is EXACT.
+ If Cp=-1 and C'p+1 =-1, SubOneUlp and the result is above.
+ Otherwise truncate
+ + If rnd = NEAREST,
+ If Cp= 0 and Cp+1 =-1 and C'p+2=-1, SubOneUlp and the result is above
+ If cp=-1 and C'p+1 = 0, SubOneUlp and the result is exact.
+ Otherwise truncate.
+ X bit should always be set if SubOneUlp*/
+ if (MPFR_UNLIKELY(ap[n-1] == MPFR_LIMB_HIGHBIT))
+ {
+ mp_size_t k = n-1;
+ do {
+ k--;
+ } while (k>=0 && ap[k]==0);
+ if (MPFR_UNLIKELY(k<0))
+ {
+ /* It is a power of 2! */
+ /* Compute Cp+1 if it isn't already compute (ie d==1) */
+ /* FIXME: Is this case possible? */
+ if (d == 1)
+ bbcp=0;
+ DEBUG( printf("(Truncate) Cp=%d, Cp+1=%d C'p+1=%d C'p+2=%d\n", \
+ bcp!=0, bbcp!=0, bcp1!=0, bbcp1!=0) );
+ MPFR_ASSERTN(bbcp != (mp_limb_t) -1);
+ MPFR_ASSERTN((rnd_mode != MPFR_RNDN) || (bcp != 0) || (bbcp == 0) || (bbcp1 != (mp_limb_t) -1));
+ if (((rnd_mode != MPFR_RNDZ) && bcp)
+ ||
+ ((rnd_mode == MPFR_RNDN) && (bcp == 0) && (bbcp) && (bbcp1)))
+ {
+ DEBUG( printf("(Truncate) Do sub\n") );
+ mpn_sub_1 (ap, ap, n, MPFR_LIMB_ONE << sh);
+ mpn_lshift(ap, ap, n, 1);
+ ap[0] |= MPFR_LIMB_ONE<<sh;
+ bx--;
+ /* FIXME: Explain why it works (or why not)... */
+ inexact = (bcp1 == 0) ? 0 : (rnd_mode==MPFR_RNDN) ? -1 : 1;
+ goto end_of_sub;
+ }
+ }
+ }
+
+ /* Calcul of Inexact flag.*/
+ inexact = MPFR_LIKELY(bcp || bcp1) ? 1 : 0;
+
+ end_of_sub:
+ /* Update Expo */
+ /* FIXME: Is this test really useful?
+ If d==0 : Exact case. This is never called.
+ if 1 < d < p : bx=MPFR_EXP(b) or MPFR_EXP(b)-1 > MPFR_EXP(c) > emin
+ if d == 1 : bx=MPFR_EXP(b). If we could lose any bits, the exact
+ normalisation is called.
+ if d >= p : bx=MPFR_EXP(b) >= MPFR_EXP(c) + p > emin
+ After SubOneUlp, we could have one bit less.
+ if 1 < d < p : bx >= MPFR_EXP(b)-2 >= MPFR_EXP(c) > emin
+ if d == 1 : bx >= MPFR_EXP(b)-1 = MPFR_EXP(c) > emin.
+ if d >= p : bx >= MPFR_EXP(b)-1 > emin since p>=2.
+ */
+ MPFR_ASSERTD( bx >= __gmpfr_emin);
+ /*
+ if (MPFR_UNLIKELY(bx < __gmpfr_emin))
+ {
+ DEBUG( printf("(Final Underflow)\n") );
+ if (rnd_mode == MPFR_RNDN &&
+ (bx < __gmpfr_emin - 1 ||
+ (inexact >= 0 && mpfr_powerof2_raw (a))))
+ rnd_mode = MPFR_RNDZ;
+ MPFR_TMP_FREE(marker);
+ return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
+ }
+ */
+ MPFR_SET_EXP (a, bx);
+
+ MPFR_TMP_FREE(marker);
+ MPFR_RET (inexact * MPFR_INT_SIGN (a));
+}
diff --git a/mpfr/src/sub_d.c b/mpfr/src/sub_d.c
new file mode 100644
index 0000000000..14922ca165
--- /dev/null
+++ b/mpfr/src/sub_d.c
@@ -0,0 +1,51 @@
+/* mpfr_sub_d -- subtract a machine double precision float from
+ a multiple precision floating-point number
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_sub_d (mpfr_ptr a, mpfr_srcptr b, double c, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t d;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("b[%Pu]=%.*Rg c=%.20g rnd=%d",
+ mpfr_get_prec (b), mpfr_log_prec, b, c, rnd_mode),
+ ("a[%Pu]=%.*Rg", mpfr_get_prec (a), mpfr_log_prec, a));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (d, IEEE_DBL_MANT_DIG);
+ inexact = mpfr_set_d (d, c, rnd_mode);
+ MPFR_ASSERTN (inexact == 0);
+
+ mpfr_clear_flags ();
+ inexact = mpfr_sub (a, b, d, rnd_mode);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
+ mpfr_clear(d);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (a, inexact, rnd_mode);
+}
diff --git a/mpfr/src/sub_ui.c b/mpfr/src/sub_ui.c
new file mode 100644
index 0000000000..8fcd530702
--- /dev/null
+++ b/mpfr/src/sub_ui.c
@@ -0,0 +1,60 @@
+/* mpfr_sub_ui -- subtract a floating-point number and a machine integer
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_sub_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mpfr_rnd_t rnd_mode)
+{
+ if (MPFR_LIKELY (u != 0)) /* if u=0, do nothing */
+ {
+ mpfr_t uu;
+ mp_limb_t up[1];
+ unsigned long cnt;
+ int inex;
+
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%lu rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec(y), mpfr_log_prec, y, inex));
+
+ MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
+ MPFR_ASSERTN (u == (mp_limb_t) u);
+ count_leading_zeros (cnt, (mp_limb_t) u);
+ *up = (mp_limb_t) u << cnt;
+
+ /* Optimization note: Exponent save/restore operations may be
+ removed if mpfr_sub works even when uu is out-of-range. */
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
+ inex = mpfr_sub (y, x, uu, rnd_mode);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inex, rnd_mode);
+ }
+ else
+ return mpfr_set (y, x, rnd_mode);
+}
diff --git a/mpfr/src/subnormal.c b/mpfr/src/subnormal.c
new file mode 100644
index 0000000000..cbf35ae8d5
--- /dev/null
+++ b/mpfr/src/subnormal.c
@@ -0,0 +1,163 @@
+/* mpfr_subnormalize -- Subnormalize a floating point number
+ emulating sub-normal numbers.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* For MPFR_RNDN, we can have a problem of double rounding.
+ In such a case, this table helps to conclude what to do (y positive):
+ Rounding Bit | Sticky Bit | inexact | Action | new inexact
+ 0 | ? | ? | Trunc | sticky
+ 1 | 0 | 1 | Trunc |
+ 1 | 0 | 0 | Trunc if even |
+ 1 | 0 | -1 | AddOneUlp |
+ 1 | 1 | ? | AddOneUlp |
+
+ For other rounding mode, there isn't such a problem.
+ Just round it again and merge the ternary values.
+
+ Set the inexact flag if the returned ternary value is non-zero.
+ Set the underflow flag if a second rounding occurred (whether this
+ rounding is exact or not). See
+ https://sympa.inria.fr/sympa/arc/mpfr/2009-06/msg00000.html
+ https://sympa.inria.fr/sympa/arc/mpfr/2009-06/msg00008.html
+ https://sympa.inria.fr/sympa/arc/mpfr/2009-06/msg00010.html
+*/
+
+int
+mpfr_subnormalize (mpfr_ptr y, int old_inexact, mpfr_rnd_t rnd)
+{
+ int sign;
+
+ /* The subnormal exponent range is [ emin, emin + MPFR_PREC(y) - 2 ] */
+ if (MPFR_LIKELY (MPFR_IS_SINGULAR (y)
+ || (MPFR_GET_EXP (y) >=
+ __gmpfr_emin + (mpfr_exp_t) MPFR_PREC (y) - 1)))
+ MPFR_RET (old_inexact);
+
+ mpfr_set_underflow ();
+ sign = MPFR_SIGN (y);
+
+ /* We have to emulate one bit rounding if EXP(y) = emin */
+ if (MPFR_GET_EXP (y) == __gmpfr_emin)
+ {
+ /* If this is a power of 2, we don't need rounding.
+ It handles cases when |y| = 0.1 * 2^emin */
+ if (mpfr_powerof2_raw (y))
+ MPFR_RET (old_inexact);
+
+ /* We keep the same sign for y.
+ Assuming Y is the real value and y the approximation
+ and since y is not a power of 2: 0.5*2^emin < Y < 1*2^emin
+ We also know the direction of the error thanks to ternary value. */
+
+ if (rnd == MPFR_RNDN)
+ {
+ mp_limb_t *mant, rb ,sb;
+ mp_size_t s;
+ /* We need the rounding bit and the sticky bit. Read them
+ and use the previous table to conclude. */
+ s = MPFR_LIMB_SIZE (y) - 1;
+ mant = MPFR_MANT (y) + s;
+ rb = *mant & (MPFR_LIMB_HIGHBIT >> 1);
+ if (rb == 0)
+ goto set_min;
+ sb = *mant & ((MPFR_LIMB_HIGHBIT >> 1) - 1);
+ while (sb == 0 && s-- != 0)
+ sb = *--mant;
+ if (sb != 0)
+ goto set_min_p1;
+ /* Rounding bit is 1 and sticky bit is 0.
+ We need to examine old inexact flag to conclude. */
+ if ((old_inexact > 0 && sign > 0) ||
+ (old_inexact < 0 && sign < 0))
+ goto set_min;
+ /* If inexact != 0, return 0.1*2^(emin+1).
+ Otherwise, rounding bit = 1, sticky bit = 0 and inexact = 0
+ So we have 0.1100000000000000000000000*2^emin exactly.
+ We return 0.1*2^(emin+1) according to the even-rounding
+ rule on subnormals. */
+ goto set_min_p1;
+ }
+ else if (MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y)))
+ {
+ set_min:
+ mpfr_setmin (y, __gmpfr_emin);
+ MPFR_RET (-sign);
+ }
+ else
+ {
+ set_min_p1:
+ /* Note: mpfr_setmin will abort if __gmpfr_emax == __gmpfr_emin. */
+ mpfr_setmin (y, __gmpfr_emin + 1);
+ MPFR_RET (sign);
+ }
+ }
+ else /* Hard case: It is more or less the same problem than mpfr_cache */
+ {
+ mpfr_t dest;
+ mpfr_prec_t q;
+ int inexact, inex2;
+
+ MPFR_ASSERTD (MPFR_GET_EXP (y) > __gmpfr_emin);
+
+ /* Compute the intermediary precision */
+ q = (mpfr_uexp_t) MPFR_GET_EXP (y) - __gmpfr_emin + 1;
+ MPFR_ASSERTD (q >= MPFR_PREC_MIN && q < MPFR_PREC (y));
+
+ /* TODO: perform the rounding in place. */
+ mpfr_init2 (dest, q);
+ /* Round y in dest */
+ MPFR_SET_EXP (dest, MPFR_GET_EXP (y));
+ MPFR_SET_SIGN (dest, sign);
+ MPFR_RNDRAW_EVEN (inexact, dest,
+ MPFR_MANT (y), MPFR_PREC (y), rnd, sign,
+ MPFR_SET_EXP (dest, MPFR_GET_EXP (dest) + 1));
+ if (MPFR_LIKELY (old_inexact != 0))
+ {
+ if (MPFR_UNLIKELY (rnd == MPFR_RNDN &&
+ (inexact == MPFR_EVEN_INEX ||
+ inexact == -MPFR_EVEN_INEX)))
+ {
+ /* if both roundings are in the same direction, we have to go
+ back in the other direction */
+ if (SAME_SIGN (inexact, old_inexact))
+ {
+ if (SAME_SIGN (inexact, MPFR_INT_SIGN (y)))
+ mpfr_nexttozero (dest);
+ else
+ mpfr_nexttoinf (dest);
+ inexact = -inexact;
+ }
+ }
+ else if (MPFR_UNLIKELY (inexact == 0))
+ inexact = old_inexact;
+ }
+
+ inex2 = mpfr_set (y, dest, rnd);
+ MPFR_ASSERTN (inex2 == 0);
+ MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
+ mpfr_clear (dest);
+
+ MPFR_RET (inexact);
+ }
+}
diff --git a/mpfr/src/sum.c b/mpfr/src/sum.c
new file mode 100644
index 0000000000..200a523e31
--- /dev/null
+++ b/mpfr/src/sum.c
@@ -0,0 +1,316 @@
+/* Sum -- efficiently sum a list of floating-point numbers
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Reference: James Demmel and Yozo Hida, Fast and accurate floating-point
+ summation with application to computational geometry, Numerical Algorithms,
+ volume 37, number 1-4, pages 101--112, 2004. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* I would really like to use "mpfr_srcptr const []" but the norm is buggy:
+ it doesn't automaticaly cast a "mpfr_ptr []" to "mpfr_srcptr const []"
+ if necessary. So the choice are:
+ mpfr_s ** : ok
+ mpfr_s *const* : ok
+ mpfr_s **const : ok
+ mpfr_s *const*const : ok
+ const mpfr_s *const* : no
+ const mpfr_s **const : no
+ const mpfr_s *const*const: no
+ VL: this is not a bug, but a feature. See the reason here:
+ http://c-faq.com/ansi/constmismatch.html
+*/
+static void heap_sort (mpfr_srcptr *const, unsigned long, mpfr_srcptr *);
+static void count_sort (mpfr_srcptr *const, unsigned long, mpfr_srcptr *,
+ mpfr_exp_t, mpfr_uexp_t);
+
+/* Either sort the tab in perm and returns 0
+ Or returns 1 for +INF, -1 for -INF and 2 for NAN */
+int
+mpfr_sum_sort (mpfr_srcptr *const tab, unsigned long n, mpfr_srcptr *perm)
+{
+ mpfr_exp_t min, max;
+ mpfr_uexp_t exp_num;
+ unsigned long i;
+ int sign_inf;
+
+ sign_inf = 0;
+ min = MPFR_EMIN_MAX;
+ max = MPFR_EMAX_MIN;
+ for (i = 0; i < n; i++)
+ {
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (tab[i])))
+ {
+ if (MPFR_IS_NAN (tab[i]))
+ return 2; /* Return NAN code */
+ else if (MPFR_IS_INF (tab[i]))
+ {
+ if (sign_inf == 0) /* No previous INF */
+ sign_inf = MPFR_SIGN (tab[i]);
+ else if (sign_inf != MPFR_SIGN (tab[i]))
+ return 2; /* Return NAN */
+ }
+ }
+ else
+ {
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (tab[i]));
+ if (MPFR_GET_EXP (tab[i]) < min)
+ min = MPFR_GET_EXP(tab[i]);
+ if (MPFR_GET_EXP (tab[i]) > max)
+ max = MPFR_GET_EXP(tab[i]);
+ }
+ }
+ if (MPFR_UNLIKELY (sign_inf != 0))
+ return sign_inf;
+
+ exp_num = max - min + 1;
+ /* FIXME : better test */
+ if (exp_num > n * MPFR_INT_CEIL_LOG2 (n))
+ heap_sort (tab, n, perm);
+ else
+ count_sort (tab, n, perm, min, exp_num);
+ return 0;
+}
+
+#define GET_EXP1(x) (MPFR_IS_ZERO (x) ? min : MPFR_GET_EXP (x))
+/* Performs a count sort of the entries */
+static void
+count_sort (mpfr_srcptr *const tab, unsigned long n,
+ mpfr_srcptr *perm, mpfr_exp_t min, mpfr_uexp_t exp_num)
+{
+ unsigned long *account;
+ unsigned long target_rank, i;
+ MPFR_TMP_DECL(marker);
+
+ /* Reserve a place for potential 0 (with EXP min-1)
+ If there is no zero, we only lose one unused entry */
+ min--;
+ exp_num++;
+
+ /* Performs a counting sort of the entries */
+ MPFR_TMP_MARK (marker);
+ account = (unsigned long *) MPFR_TMP_ALLOC (exp_num * sizeof *account);
+ for (i = 0; i < exp_num; i++)
+ account[i] = 0;
+ for (i = 0; i < n; i++)
+ account[GET_EXP1 (tab[i]) - min]++;
+ for (i = exp_num - 1; i >= 1; i--)
+ account[i - 1] += account[i];
+ for (i = 0; i < n; i++)
+ {
+ target_rank = --account[GET_EXP1 (tab[i]) - min];
+ perm[target_rank] = tab[i];
+ }
+ MPFR_TMP_FREE (marker);
+}
+
+
+#define GET_EXP2(x) (MPFR_IS_ZERO (x) ? MPFR_EMIN_MIN : MPFR_GET_EXP (x))
+
+/* Performs a heap sort of the entries */
+static void
+heap_sort (mpfr_srcptr *const tab, unsigned long n, mpfr_srcptr *perm)
+{
+ unsigned long dernier_traite;
+ unsigned long i, pere;
+ mpfr_srcptr tmp;
+ unsigned long fils_gauche, fils_droit, fils_indigne;
+ /* Reminder of a heap structure :
+ node(i) has for left son node(2i +1) and right son node(2i)
+ and father(node(i)) = node((i - 1) / 2)
+ */
+
+ /* initialize the permutation to identity */
+ for (i = 0; i < n; i++)
+ perm[i] = tab[i];
+
+ /* insertion phase */
+ for (dernier_traite = 1; dernier_traite < n; dernier_traite++)
+ {
+ i = dernier_traite;
+ while (i > 0)
+ {
+ pere = (i - 1) / 2;
+ if (GET_EXP2 (perm[pere]) > GET_EXP2 (perm[i]))
+ {
+ tmp = perm[pere];
+ perm[pere] = perm[i];
+ perm[i] = tmp;
+ i = pere;
+ }
+ else
+ break;
+ }
+ }
+
+ /* extraction phase */
+ for (dernier_traite = n - 1; dernier_traite > 0; dernier_traite--)
+ {
+ tmp = perm[0];
+ perm[0] = perm[dernier_traite];
+ perm[dernier_traite] = tmp;
+
+ i = 0;
+ while (1)
+ {
+ fils_gauche = 2 * i + 1;
+ fils_droit = fils_gauche + 1;
+ if (fils_gauche < dernier_traite)
+ {
+ if (fils_droit < dernier_traite)
+ {
+ if (GET_EXP2(perm[fils_droit]) < GET_EXP2(perm[fils_gauche]))
+ fils_indigne = fils_droit;
+ else
+ fils_indigne = fils_gauche;
+
+ if (GET_EXP2 (perm[i]) > GET_EXP2 (perm[fils_indigne]))
+ {
+ tmp = perm[i];
+ perm[i] = perm[fils_indigne];
+ perm[fils_indigne] = tmp;
+ i = fils_indigne;
+ }
+ else
+ break;
+ }
+ else /* on a un fils gauche, pas de fils droit */
+ {
+ if (GET_EXP2 (perm[i]) > GET_EXP2 (perm[fils_gauche]))
+ {
+ tmp = perm[i];
+ perm[i] = perm[fils_gauche];
+ perm[fils_gauche] = tmp;
+ }
+ break;
+ }
+ }
+ else /* on n'a pas de fils */
+ break;
+ }
+ }
+}
+
+
+/* Sum a list of float with order given by permutation perm,
+ * intermediate size set to F.
+ * Internal use function.
+ */
+static int
+sum_once (mpfr_ptr ret, mpfr_srcptr *const tab, unsigned long n, mpfr_prec_t F)
+{
+ mpfr_t sum;
+ unsigned long i;
+ int error_trap;
+
+ MPFR_ASSERTD (n >= 2);
+
+ mpfr_init2 (sum, F);
+ error_trap = mpfr_set (sum, tab[0], MPFR_RNDN);
+ for (i = 1; i < n - 1; i++)
+ {
+ MPFR_ASSERTD (!MPFR_IS_NAN (sum) && !MPFR_IS_INF (sum));
+ error_trap |= mpfr_add (sum, sum, tab[i], MPFR_RNDN);
+ }
+ error_trap |= mpfr_add (ret, sum, tab[n - 1], MPFR_RNDN);
+ mpfr_clear (sum);
+ return error_trap;
+}
+
+/* Sum a list of floating-point numbers.
+ */
+
+int
+mpfr_sum (mpfr_ptr ret, mpfr_ptr *const tab_p, unsigned long n, mpfr_rnd_t rnd)
+{
+ mpfr_t cur_sum;
+ mpfr_prec_t prec;
+ mpfr_srcptr *perm, *const tab = (mpfr_srcptr *) tab_p;
+ int k, error_trap;
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_TMP_DECL (marker);
+
+ if (MPFR_UNLIKELY (n <= 1))
+ {
+ if (n < 1)
+ {
+ MPFR_SET_ZERO (ret);
+ MPFR_SET_POS (ret);
+ return 0;
+ }
+ else
+ return mpfr_set (ret, tab[0], rnd);
+ }
+
+ /* Sort and treat special cases */
+ MPFR_TMP_MARK (marker);
+ perm = (mpfr_srcptr *) MPFR_TMP_ALLOC (n * sizeof *perm);
+ error_trap = mpfr_sum_sort (tab, n, perm);
+ /* Check if there was a NAN or a INF */
+ if (MPFR_UNLIKELY (error_trap != 0))
+ {
+ MPFR_TMP_FREE (marker);
+ if (error_trap == 2)
+ {
+ MPFR_SET_NAN (ret);
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_INF (ret);
+ MPFR_SET_SIGN (ret, error_trap);
+ MPFR_RET (0);
+ }
+
+ /* Initial precision */
+ prec = MAX (MPFR_PREC (tab[0]), MPFR_PREC (ret));
+ k = MPFR_INT_CEIL_LOG2 (n) + 1;
+ prec += k + 2;
+ mpfr_init2 (cur_sum, prec);
+
+ /* Ziv Loop */
+ MPFR_SAVE_EXPO_MARK (expo);
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ error_trap = sum_once (cur_sum, perm, n, prec + k);
+ if (MPFR_LIKELY (error_trap == 0 ||
+ (!MPFR_IS_ZERO (cur_sum) &&
+ mpfr_can_round (cur_sum,
+ MPFR_GET_EXP (cur_sum) - prec + 2,
+ MPFR_RNDN, rnd, MPFR_PREC (ret)))))
+ break;
+ MPFR_ZIV_NEXT (loop, prec);
+ mpfr_set_prec (cur_sum, prec);
+ }
+ MPFR_ZIV_FREE (loop);
+ MPFR_TMP_FREE (marker);
+
+ error_trap |= mpfr_set (ret, cur_sum, rnd);
+ mpfr_clear (cur_sum);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ error_trap |= mpfr_check_range (ret, 0, rnd);
+ return error_trap; /* It doesn't return the ternary value */
+}
+
+/* __END__ */
diff --git a/mpfr/src/swap.c b/mpfr/src/swap.c
new file mode 100644
index 0000000000..8ab213a75f
--- /dev/null
+++ b/mpfr/src/swap.c
@@ -0,0 +1,54 @@
+/* mpfr_swap (U, V) -- Swap U and V.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Using memcpy is a few slower than swapping by hand. */
+
+void
+mpfr_swap (mpfr_ptr u, mpfr_ptr v)
+{
+ mpfr_prec_t p1, p2;
+ mpfr_sign_t s1, s2;
+ mpfr_exp_t e1, e2;
+ mp_limb_t *m1, *m2;
+
+ p1 = MPFR_PREC(u);
+ p2 = MPFR_PREC(v);
+ MPFR_PREC(v) = p1;
+ MPFR_PREC(u) = p2;
+
+ s1 = MPFR_SIGN(u);
+ s2 = MPFR_SIGN(v);
+ MPFR_SIGN(v) = s1;
+ MPFR_SIGN(u) = s2;
+
+ e1 = MPFR_EXP(u);
+ e2 = MPFR_EXP(v);
+ MPFR_EXP(v) = e1;
+ MPFR_EXP(u) = e2;
+
+ m1 = MPFR_MANT(u);
+ m2 = MPFR_MANT(v);
+ MPFR_MANT(v) = m1;
+ MPFR_MANT(u) = m2;
+}
diff --git a/mpfr/src/tan.c b/mpfr/src/tan.c
new file mode 100644
index 0000000000..8cd93cdeff
--- /dev/null
+++ b/mpfr/src/tan.c
@@ -0,0 +1,89 @@
+/* mpfr_tan -- tangent of a floating-point number
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* computes tan(x) = sign(x)*sqrt(1/cos(x)^2-1) */
+int
+mpfr_tan (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_prec_t precy, m;
+ int inexact;
+ mpfr_t s, c;
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_GROUP_DECL (group);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
+ {
+ if (MPFR_IS_NAN(x) || MPFR_IS_INF(x))
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+ else /* x is zero */
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(x));
+ MPFR_SET_ZERO(y);
+ MPFR_SET_SAME_SIGN(y, x);
+ MPFR_RET(0);
+ }
+ }
+
+ /* tan(x) = x + x^3/3 + ... so the error is < 2^(3*EXP(x)-1) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -2 * MPFR_GET_EXP (x), 1, 1,
+ rnd_mode, {});
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Compute initial precision */
+ precy = MPFR_PREC (y);
+ m = precy + MPFR_INT_CEIL_LOG2 (precy) + 13;
+ MPFR_ASSERTD (m >= 2); /* needed for the error analysis in algorithms.tex */
+
+ MPFR_GROUP_INIT_2 (group, m, s, c);
+ MPFR_ZIV_INIT (loop, m);
+ for (;;)
+ {
+ /* The only way to get an overflow is to get ~ Pi/2
+ But the result will be ~ 2^Prec(y). */
+ mpfr_sin_cos (s, c, x, MPFR_RNDN); /* err <= 1/2 ulp on s and c */
+ mpfr_div (c, s, c, MPFR_RNDN); /* err <= 4 ulps */
+ MPFR_ASSERTD (!MPFR_IS_SINGULAR (c));
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (c, m - 2, precy, rnd_mode)))
+ break;
+ MPFR_ZIV_NEXT (loop, m);
+ MPFR_GROUP_REPREC_2 (group, m, s, c);
+ }
+ MPFR_ZIV_FREE (loop);
+ inexact = mpfr_set (y, c, rnd_mode);
+ MPFR_GROUP_CLEAR (group);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/tanh.c b/mpfr/src/tanh.c
new file mode 100644
index 0000000000..b1e9b7d8a4
--- /dev/null
+++ b/mpfr/src/tanh.c
@@ -0,0 +1,153 @@
+/* mpfr_tanh -- hyperbolic tangent
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_tanh (mpfr_ptr y, mpfr_srcptr xt , mpfr_rnd_t rnd_mode)
+{
+ /****** Declaration ******/
+ mpfr_t x;
+ int inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (xt), mpfr_log_prec, xt, rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d",
+ mpfr_get_prec (y), mpfr_log_prec, y, inexact));
+
+ /* Special value checking */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (xt)))
+ {
+ if (MPFR_IS_NAN (xt))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (xt))
+ {
+ /* tanh(inf) = 1 && tanh(-inf) = -1 */
+ return mpfr_set_si (y, MPFR_INT_SIGN (xt), rnd_mode);
+ }
+ else /* tanh (0) = 0 and xt is zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO(xt));
+ MPFR_SET_ZERO (y);
+ MPFR_SET_SAME_SIGN (y, xt);
+ MPFR_RET (0);
+ }
+ }
+
+ /* tanh(x) = x - x^3/3 + ... so the error is < 2^(3*EXP(x)-1) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, xt, -2 * MPFR_GET_EXP (xt), 1, 0,
+ rnd_mode, {});
+
+ MPFR_TMP_INIT_ABS (x, xt);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* General case */
+ {
+ /* Declaration of the intermediary variable */
+ mpfr_t t, te;
+ mpfr_exp_t d;
+
+ /* Declaration of the size variable */
+ mpfr_prec_t Ny = MPFR_PREC(y); /* target precision */
+ mpfr_prec_t Nt; /* working precision */
+ long int err; /* error */
+ int sign = MPFR_SIGN (xt);
+ MPFR_ZIV_DECL (loop);
+ MPFR_GROUP_DECL (group);
+
+ /* First check for BIG overflow of exp(2*x):
+ For x > 0, exp(2*x) > 2^(2*x)
+ If 2 ^(2*x) > 2^emax or x>emax/2, there is an overflow */
+ if (MPFR_UNLIKELY (mpfr_cmp_si (x, __gmpfr_emax/2) >= 0)) {
+ /* initialise of intermediary variables
+ since 'set_one' label assumes the variables have been
+ initialize */
+ MPFR_GROUP_INIT_2 (group, MPFR_PREC_MIN, t, te);
+ goto set_one;
+ }
+
+ /* Compute the precision of intermediary variable */
+ /* The optimal number of bits: see algorithms.tex */
+ Nt = Ny + MPFR_INT_CEIL_LOG2 (Ny) + 4;
+ /* if x is small, there will be a cancellation in exp(2x)-1 */
+ if (MPFR_GET_EXP (x) < 0)
+ Nt += -MPFR_GET_EXP (x);
+
+ /* initialise of intermediary variable */
+ MPFR_GROUP_INIT_2 (group, Nt, t, te);
+
+ MPFR_ZIV_INIT (loop, Nt);
+ for (;;) {
+ /* tanh = (exp(2x)-1)/(exp(2x)+1) */
+ mpfr_mul_2ui (te, x, 1, MPFR_RNDN); /* 2x */
+ /* since x > 0, we can only have an overflow */
+ mpfr_exp (te, te, MPFR_RNDN); /* exp(2x) */
+ if (MPFR_UNLIKELY (MPFR_IS_INF (te))) {
+ set_one:
+ inexact = MPFR_FROM_SIGN_TO_INT (sign);
+ mpfr_set4 (y, __gmpfr_one, MPFR_RNDN, sign);
+ if (MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG_SIGN (sign)))
+ {
+ inexact = -inexact;
+ mpfr_nexttozero (y);
+ }
+ break;
+ }
+ d = MPFR_GET_EXP (te); /* For Error calculation */
+ mpfr_add_ui (t, te, 1, MPFR_RNDD); /* exp(2x) + 1*/
+ mpfr_sub_ui (te, te, 1, MPFR_RNDU); /* exp(2x) - 1*/
+ d = d - MPFR_GET_EXP (te);
+ mpfr_div (t, te, t, MPFR_RNDN); /* (exp(2x)-1)/(exp(2x)+1)*/
+
+ /* Calculation of the error */
+ d = MAX(3, d + 1);
+ err = Nt - (d + 1);
+
+ if (MPFR_LIKELY ((d <= Nt / 2) && MPFR_CAN_ROUND (t, err, Ny, rnd_mode)))
+ {
+ inexact = mpfr_set4 (y, t, rnd_mode, sign);
+ break;
+ }
+
+ /* if t=1, we still can round since |sinh(x)| < 1 */
+ if (MPFR_GET_EXP (t) == 1)
+ goto set_one;
+
+ /* Actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, Nt);
+ MPFR_GROUP_REPREC_2 (group, Nt, t, te);
+ }
+ MPFR_ZIV_FREE (loop);
+ MPFR_GROUP_CLEAR (group);
+ }
+ MPFR_SAVE_EXPO_FREE (expo);
+ inexact = mpfr_check_range (y, inexact, rnd_mode);
+
+ return inexact;
+}
+
diff --git a/mpfr/src/uceil_exp2.c b/mpfr/src/uceil_exp2.c
new file mode 100644
index 0000000000..dd571d0ab9
--- /dev/null
+++ b/mpfr/src/uceil_exp2.c
@@ -0,0 +1,65 @@
+/* __gmpfr_ceil_exp2 - returns y >= 2^d
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* returns y >= 2^d, assuming that d <= 1024
+ for d integer, returns exactly 2^d
+*/
+double
+__gmpfr_ceil_exp2 (double d)
+{
+ long exp;
+#if _GMP_IEEE_FLOATS
+ union ieee_double_extract x;
+#else
+ struct {double d;} x;
+#endif
+
+ MPFR_ASSERTN(d <= 1024.0);
+ exp = (long) d;
+ if (d != (double) exp)
+ exp++;
+ /* now exp = ceil(d) */
+ x.d = 1.0;
+#if _GMP_IEEE_FLOATS
+ x.s.exp = exp <= -1022 ? 1 : 1023 + exp;
+#else
+ if (exp >= 0)
+ {
+ while (exp != 0)
+ {
+ x.d *= 2.0;
+ exp--;
+ }
+ }
+ else
+ {
+ while (exp != 0)
+ {
+ x.d *= (1.0 / 2.0);
+ exp++;
+ }
+ }
+#endif
+ return x.d;
+}
diff --git a/mpfr/src/uceil_log2.c b/mpfr/src/uceil_log2.c
new file mode 100644
index 0000000000..27f7d4fc78
--- /dev/null
+++ b/mpfr/src/uceil_log2.c
@@ -0,0 +1,63 @@
+/* __gmpfr_ceil_log2 - returns ceil(log(d)/log(2))
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* returns ceil(log(d)/log(2)) if d > 0,
+ -1023 if d = +0,
+ and floor(log(-d)/log(2))+1 if d < 0*/
+long
+__gmpfr_ceil_log2 (double d)
+{
+ long exp;
+#if _GMP_IEEE_FLOATS
+ union ieee_double_extract x;
+
+ x.d = d;
+ exp = x.s.exp - 1023;
+ x.s.exp = 1023; /* value for 1 <= d < 2 */
+ if (x.d != 1.0) /* d: not a power of two? */
+ exp++;
+ return exp;
+#else
+ double m;
+
+ if (d < 0.0)
+ return __gmpfr_floor_log2(-d)+1;
+ else if (d == 0.0)
+ return -1023;
+ else if (d >= 1.0)
+ {
+ exp = 0;
+ for( m= 1.0 ; m < d ; m *=2.0 )
+ exp++;
+ }
+ else
+ {
+ exp = 1;
+ for( m= 1.0 ; m >= d ; m *= (1.0/2.0) )
+ exp--;
+ }
+#endif
+ return exp;
+}
+
diff --git a/mpfr/src/ufloor_log2.c b/mpfr/src/ufloor_log2.c
new file mode 100644
index 0000000000..9200dbf001
--- /dev/null
+++ b/mpfr/src/ufloor_log2.c
@@ -0,0 +1,53 @@
+/* __gmpfr_floor_log2 - returns floor(log(d)/log(2))
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* returns floor(log2(d)) */
+long
+__gmpfr_floor_log2 (double d)
+{
+#if _GMP_IEEE_FLOATS
+ union ieee_double_extract x;
+
+ x.d = d;
+ return (long) x.s.exp - 1023;
+#else
+ long exp;
+ double m;
+
+ MPFR_ASSERTD (d >= 0);
+ if (d >= 1.0)
+ {
+ exp = -1;
+ for( m= 1.0 ; m <= d ; m *=2.0 )
+ exp++;
+ }
+ else
+ {
+ exp = 0;
+ for( m= 1.0 ; m > d ; m *= (1.0/2.0) )
+ exp--;
+ }
+ return exp;
+#endif
+}
diff --git a/mpfr/src/ui_div.c b/mpfr/src/ui_div.c
new file mode 100644
index 0000000000..223ec7977a
--- /dev/null
+++ b/mpfr/src/ui_div.c
@@ -0,0 +1,103 @@
+/* mpfr_ui_div -- divide a machine integer by a floating-point number
+ mpfr_si_div -- divide a machine number by a floating-point number
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_ui_div (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t uu;
+ mp_limb_t up[1];
+ unsigned long cnt;
+
+ MPFR_LOG_FUNC
+ (("u=%lu x[%Pu]=%.*Rg rnd=%d",
+ u, mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg", mpfr_get_prec(y), mpfr_log_prec, y));
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
+ {
+ if (MPFR_IS_NAN(x))
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF(x)) /* u/Inf = 0 */
+ {
+ MPFR_SET_ZERO(y);
+ MPFR_SET_SAME_SIGN(y,x);
+ MPFR_RET(0);
+ }
+ else /* u / 0 */
+ {
+ MPFR_ASSERTD(MPFR_IS_ZERO(x));
+ if (u)
+ {
+ /* u > 0, so y = sign(x) * Inf */
+ MPFR_SET_SAME_SIGN(y, x);
+ MPFR_SET_INF(y);
+ mpfr_set_divby0 ();
+ MPFR_RET(0);
+ }
+ else
+ {
+ /* 0 / 0 */
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+ }
+ }
+ else if (MPFR_LIKELY(u != 0))
+ {
+ MPFR_TMP_INIT1(up, uu, GMP_NUMB_BITS);
+ MPFR_ASSERTN(u == (mp_limb_t) u);
+ count_leading_zeros(cnt, (mp_limb_t) u);
+ up[0] = (mp_limb_t) u << cnt;
+ MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
+ return mpfr_div (y, uu, x, rnd_mode);
+ }
+ else /* u = 0, and x != 0 */
+ {
+ MPFR_SET_ZERO(y); /* if u=0, then set y to 0 */
+ MPFR_SET_SAME_SIGN(y, x); /* u considered as +0: sign(+0/x) = sign(x) */
+ MPFR_RET(0);
+ }
+}
+
+
+int
+mpfr_si_div (mpfr_ptr y, long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int res;
+
+ if (u >= 0)
+ res = mpfr_ui_div (y, u, x, rnd_mode);
+ else
+ {
+ res = -mpfr_ui_div (y, -u, x, MPFR_INVERT_RND(rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ }
+ return res;
+}
diff --git a/mpfr/src/ui_pow.c b/mpfr/src/ui_pow.c
new file mode 100644
index 0000000000..a566cae7f8
--- /dev/null
+++ b/mpfr/src/ui_pow.c
@@ -0,0 +1,41 @@
+/* mpfr_ui_pow -- power of n function n^x
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_ui_pow (mpfr_ptr y, unsigned long int n, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t t;
+ int inexact;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (t, sizeof(n) * CHAR_BIT);
+ inexact = mpfr_set_ui (t, n, MPFR_RNDN);
+ MPFR_ASSERTN (!inexact);
+ inexact = mpfr_pow (y, t, x, rnd_mode);
+ mpfr_clear (t);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
diff --git a/mpfr/src/ui_pow_ui.c b/mpfr/src/ui_pow_ui.c
new file mode 100644
index 0000000000..63bcb33299
--- /dev/null
+++ b/mpfr/src/ui_pow_ui.c
@@ -0,0 +1,95 @@
+/* mpfr_ui_pow_ui -- compute the power beetween two machine integer
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+int
+mpfr_ui_pow_ui (mpfr_ptr x, unsigned long int y, unsigned long int n,
+ mpfr_rnd_t rnd)
+{
+ mpfr_exp_t err;
+ unsigned long m;
+ mpfr_t res;
+ mpfr_prec_t prec;
+ int size_n;
+ int inexact;
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ if (MPFR_UNLIKELY (n <= 1))
+ {
+ if (n == 1)
+ return mpfr_set_ui (x, y, rnd); /* y^1 = y */
+ else
+ return mpfr_set_ui (x, 1, rnd); /* y^0 = 1 for any y */
+ }
+ else if (MPFR_UNLIKELY (y <= 1))
+ {
+ if (y == 1)
+ return mpfr_set_ui (x, 1, rnd); /* 1^n = 1 for any n > 0 */
+ else
+ return mpfr_set_ui (x, 0, rnd); /* 0^n = 0 for any n > 0 */
+ }
+
+ for (size_n = 0, m = n; m; size_n++, m >>= 1);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ prec = MPFR_PREC (x) + 3 + size_n;
+ mpfr_init2 (res, prec);
+
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ int i = size_n;
+
+ inexact = mpfr_set_ui (res, y, MPFR_RNDU);
+ err = 1;
+ /* now 2^(i-1) <= n < 2^i: i=1+floor(log2(n)) */
+ for (i -= 2; i >= 0; i--)
+ {
+ inexact |= mpfr_mul (res, res, res, MPFR_RNDU);
+ err++;
+ if (n & (1UL << i))
+ inexact |= mpfr_mul_ui (res, res, y, MPFR_RNDU);
+ }
+ /* since the loop is executed floor(log2(n)) times,
+ we have err = 1+floor(log2(n)).
+ Since prec >= MPFR_PREC(x) + 4 + floor(log2(n)), prec > err */
+ err = prec - err;
+
+ if (MPFR_LIKELY (inexact == 0
+ || MPFR_CAN_ROUND (res, err, MPFR_PREC (x), rnd)))
+ break;
+
+ /* Actualisation of the precision */
+ MPFR_ZIV_NEXT (loop, prec);
+ mpfr_set_prec (res, prec);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inexact = mpfr_set (x, res, rnd);
+
+ mpfr_clear (res);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (x, inexact, rnd);
+}
diff --git a/mpfr/src/ui_sub.c b/mpfr/src/ui_sub.c
new file mode 100644
index 0000000000..0b3911b05a
--- /dev/null
+++ b/mpfr/src/ui_sub.c
@@ -0,0 +1,68 @@
+/* mpfr_ui_sub -- subtract a floating-point number from an integer
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_ui_sub (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t uu;
+ mp_limb_t up[1];
+ unsigned long cnt;
+
+ MPFR_LOG_FUNC
+ (("u=%lu x[%Pu]=%.*Rg rnd=%d",
+ u, mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode),
+ ("y[%Pu]=%.*Rg", mpfr_get_prec(y), mpfr_log_prec, y));
+
+ if (MPFR_UNLIKELY (u == 0))
+ return mpfr_neg (y, x, rnd_mode);
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
+ {
+ if (MPFR_IS_NAN(x))
+ {
+ MPFR_SET_NAN(y);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF(x))
+ {
+ /* u - Inf = -Inf and u - -Inf = +Inf */
+ MPFR_SET_INF(y);
+ MPFR_SET_OPPOSITE_SIGN(y,x);
+ MPFR_RET(0); /* +/-infinity is exact */
+ }
+ else /* x is zero */
+ /* u - 0 = u */
+ return mpfr_set_ui(y, u, rnd_mode);
+ }
+ else
+ {
+ MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
+ MPFR_ASSERTN(u == (mp_limb_t) u);
+ count_leading_zeros (cnt, (mp_limb_t) u);
+ *up = (mp_limb_t) u << cnt;
+ MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
+ return mpfr_sub (y, uu, x, rnd_mode);
+ }
+}
diff --git a/mpfr/src/urandom.c b/mpfr/src/urandom.c
new file mode 100644
index 0000000000..de626f1e20
--- /dev/null
+++ b/mpfr/src/urandom.c
@@ -0,0 +1,147 @@
+/* mpfr_urandom (rop, state, rnd_mode) -- Generate a uniform pseudorandom
+ real number between 0 and 1 (exclusive) and round it to the precision of rop
+ according to the given rounding mode.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+
+/* generate one random bit */
+static int
+random_rounding_bit (gmp_randstate_t rstate)
+{
+ mp_limb_t r;
+
+ mpfr_rand_raw (&r, rstate, 1);
+ return r & MPFR_LIMB_ONE;
+}
+
+
+int
+mpfr_urandom (mpfr_ptr rop, gmp_randstate_t rstate, mpfr_rnd_t rnd_mode)
+{
+ mpfr_limb_ptr rp;
+ mpfr_prec_t nbits;
+ mp_size_t nlimbs;
+ mp_size_t n;
+ mpfr_exp_t exp;
+ mpfr_exp_t emin;
+ int cnt;
+ int inex;
+
+ rp = MPFR_MANT (rop);
+ nbits = MPFR_PREC (rop);
+ nlimbs = MPFR_LIMB_SIZE (rop);
+ MPFR_SET_POS (rop);
+ exp = 0;
+ emin = mpfr_get_emin ();
+ if (MPFR_UNLIKELY (emin > 0))
+ {
+ if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
+ || (emin == 1 && rnd_mode == MPFR_RNDN
+ && random_rounding_bit (rstate)))
+ {
+ mpfr_set_ui_2exp (rop, 1, emin - 1, rnd_mode);
+ return +1;
+ }
+ else
+ {
+ MPFR_SET_ZERO (rop);
+ return -1;
+ }
+ }
+
+ /* Exponent */
+#define DRAW_BITS 8 /* we draw DRAW_BITS at a time */
+ cnt = DRAW_BITS;
+ MPFR_ASSERTN(DRAW_BITS <= GMP_NUMB_BITS);
+ while (cnt == DRAW_BITS)
+ {
+ /* generate DRAW_BITS in rp[0] */
+ mpfr_rand_raw (rp, rstate, DRAW_BITS);
+ if (MPFR_UNLIKELY (rp[0] == 0))
+ cnt = DRAW_BITS;
+ else
+ {
+ count_leading_zeros (cnt, rp[0]);
+ cnt -= GMP_NUMB_BITS - DRAW_BITS;
+ }
+
+ if (MPFR_UNLIKELY (exp < emin + cnt))
+ {
+ /* To get here, we have been drawing more than -emin zeros
+ in a row, then return 0 or the smallest representable
+ positive number.
+
+ The rounding to nearest mode is subtle:
+ If exp - cnt == emin - 1, the rounding bit is set, except
+ if cnt == DRAW_BITS in which case the rounding bit is
+ outside rp[0] and must be generated. */
+ if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
+ || (rnd_mode == MPFR_RNDN && cnt == exp - emin - 1
+ && (cnt != DRAW_BITS || random_rounding_bit (rstate))))
+ {
+ mpfr_set_ui_2exp (rop, 1, emin - 1, rnd_mode);
+ return +1;
+ }
+ else
+ {
+ MPFR_SET_ZERO (rop);
+ return -1;
+ }
+ }
+ exp -= cnt;
+ }
+ MPFR_EXP (rop) = exp; /* Warning: may be outside the current
+ exponent range */
+
+
+ /* Significand: we need generate only nbits-1 bits, since the most
+ significant is 1 */
+ mpfr_rand_raw (rp, rstate, nbits - 1);
+ n = nlimbs * GMP_NUMB_BITS - nbits;
+ if (MPFR_LIKELY (n != 0)) /* this will put the low bits to zero */
+ mpn_lshift (rp, rp, nlimbs, n);
+
+ /* Set the msb to 1 since it was fixed by the exponent choice */
+ rp[nlimbs - 1] |= MPFR_LIMB_HIGHBIT;
+
+ /* Rounding */
+ if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
+ || (rnd_mode == MPFR_RNDN && random_rounding_bit (rstate)))
+ {
+ /* Take care of the exponent range: it may have been reduced */
+ if (exp < emin)
+ mpfr_set_ui_2exp (rop, 1, emin - 1, rnd_mode);
+ else if (exp > mpfr_get_emax ())
+ mpfr_set_inf (rop, +1); /* overflow, flag set by mpfr_check_range */
+ else
+ mpfr_nextabove (rop);
+ inex = +1;
+ }
+ else
+ inex = -1;
+
+ return mpfr_check_range (rop, inex, rnd_mode);
+}
diff --git a/mpfr/src/urandomb.c b/mpfr/src/urandomb.c
new file mode 100644
index 0000000000..5bf64f4c95
--- /dev/null
+++ b/mpfr/src/urandomb.c
@@ -0,0 +1,108 @@
+/* mpfr_urandomb (rop, state, nbits) -- Generate a uniform pseudorandom
+ real number between 0 (inclusive) and 1 (exclusive) of size NBITS,
+ using STATE as the random state previously initialized by a call to
+ gmp_randinit_lc_2exp_size().
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* generate nbits random bits into mp[], assuming mp was allocated to contain
+ a sufficient number of limbs */
+void
+mpfr_rand_raw (mpfr_limb_ptr mp, gmp_randstate_t rstate,
+ mpfr_prec_t nbits)
+{
+ mpz_t z;
+
+ MPFR_ASSERTN (nbits >= 1);
+ /* To be sure to avoid the potential allocation of mpz_urandomb */
+ ALLOC(z) = SIZ(z) = MPFR_PREC2LIMBS (nbits);
+ PTR(z) = mp;
+#if __MPFR_GMP(5,0,0)
+ /* Check for integer overflow (unless mp_bitcnt_t is signed,
+ but according to the GMP manual, this shouldn't happen).
+ Note: mp_bitcnt_t has been introduced in GMP 5.0.0. */
+ MPFR_ASSERTN ((mp_bitcnt_t) -1 < 0 || nbits <= (mp_bitcnt_t) -1);
+#endif
+ mpz_urandomb (z, rstate, nbits);
+}
+
+int
+mpfr_urandomb (mpfr_ptr rop, gmp_randstate_t rstate)
+{
+ mpfr_limb_ptr rp;
+ mpfr_prec_t nbits;
+ mp_size_t nlimbs;
+ mp_size_t k; /* number of high zero limbs */
+ mpfr_exp_t exp;
+ int cnt;
+
+ rp = MPFR_MANT (rop);
+ nbits = MPFR_PREC (rop);
+ nlimbs = MPFR_LIMB_SIZE (rop);
+ MPFR_SET_POS (rop);
+ cnt = nlimbs * GMP_NUMB_BITS - nbits;
+
+ /* Uniform non-normalized significand */
+ /* generate exactly nbits so that the random generator stays in the same
+ state, independent of the machine word size GMP_NUMB_BITS */
+ mpfr_rand_raw (rp, rstate, nbits);
+ if (MPFR_LIKELY (cnt != 0)) /* this will put the low bits to zero */
+ mpn_lshift (rp, rp, nlimbs, cnt);
+
+ /* Count the null significant limbs and remaining limbs */
+ exp = 0;
+ k = 0;
+ while (nlimbs != 0 && rp[nlimbs - 1] == 0)
+ {
+ k ++;
+ nlimbs --;
+ exp -= GMP_NUMB_BITS;
+ }
+
+ if (MPFR_LIKELY (nlimbs != 0)) /* otherwise value is zero */
+ {
+ count_leading_zeros (cnt, rp[nlimbs - 1]);
+ /* Normalization */
+ if (mpfr_set_exp (rop, exp - cnt))
+ {
+ /* If the exponent is not in the current exponent range, we
+ choose to return a NaN as this is probably a user error.
+ Indeed this can happen only if the exponent range has been
+ reduced to a very small interval and/or the precision is
+ huge (very unlikely). */
+ MPFR_SET_NAN (rop);
+ __gmpfr_flags |= MPFR_FLAGS_NAN; /* Can't use MPFR_RET_NAN */
+ return 1;
+ }
+ if (cnt != 0)
+ mpn_lshift (rp + k, rp, nlimbs, cnt);
+ if (k != 0)
+ MPN_ZERO (rp, k);
+ }
+ else
+ MPFR_SET_ZERO (rop);
+
+ return 0;
+}
diff --git a/mpfr/src/vasprintf.c b/mpfr/src/vasprintf.c
new file mode 100644
index 0000000000..31e001cb5b
--- /dev/null
+++ b/mpfr/src/vasprintf.c
@@ -0,0 +1,2086 @@
+/* mpfr_vasprintf -- main function for the printf functions family
+ plus helper macros & functions.
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* The mpfr_printf-like functions are defined only if <stdarg.h> exists */
+#ifdef HAVE_STDARG
+
+#include <stdarg.h>
+
+#ifndef HAVE_VA_COPY
+# ifdef HAVE___VA_COPY
+# define va_copy(dst,src) __va_copy(dst, src)
+# else
+/* autoconf manual advocates this fallback.
+ This is also the solution chosen by gmp */
+# define va_copy(dst,src) \
+ do { memcpy(&(dst), &(src), sizeof(va_list)); } while (0)
+# endif /* HAVE___VA_COPY */
+#endif /* HAVE_VA_COPY */
+
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#if defined (__cplusplus)
+#include <cstddef>
+#define __STDC_LIMIT_MACROS /* SIZE_MAX defined with <stdint.h> inclusion */
+#else
+#include <stddef.h> /* for ptrdiff_t */
+#endif
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-intmax.h"
+#include "mpfr-impl.h"
+
+/* Define a length modifier corresponding to mpfr_prec_t.
+ We use literal string instead of literal character so as to permit future
+ extension to long long int ("ll"). */
+#if _MPFR_PREC_FORMAT == 1
+#define MPFR_PREC_FORMAT_TYPE "h"
+#define MPFR_PREC_FORMAT_SIZE 1
+#elif _MPFR_PREC_FORMAT == 2
+#define MPFR_PREC_FORMAT_TYPE ""
+#define MPFR_PREC_FORMAT_SIZE 0
+#elif _MPFR_PREC_FORMAT == 3
+#define MPFR_PREC_FORMAT_TYPE "l"
+#define MPFR_PREC_FORMAT_SIZE 1
+#else
+#error "mpfr_prec_t size not supported"
+#endif
+
+/* Output for special values defined in the C99 standard */
+#define MPFR_NAN_STRING_LC "nan"
+#define MPFR_NAN_STRING_UC "NAN"
+#define MPFR_NAN_STRING_LENGTH 3
+#define MPFR_INF_STRING_LC "inf"
+#define MPFR_INF_STRING_UC "INF"
+#define MPFR_INF_STRING_LENGTH 3
+
+/* The implicit \0 is useless, but we do not write num_to_text[16]
+ otherwise g++ complains. */
+static const char num_to_text[] = "0123456789abcdef";
+
+/* some macro and functions for parsing format string */
+
+/* Read an integer; saturate to INT_MAX. */
+#define READ_INT(ap, format, specinfo, field, label_out) \
+ do { \
+ while (*(format)) \
+ { \
+ int _i; \
+ switch (*(format)) \
+ { \
+ case '0': \
+ case '1': \
+ case '2': \
+ case '3': \
+ case '4': \
+ case '5': \
+ case '6': \
+ case '7': \
+ case '8': \
+ case '9': \
+ specinfo.field = (specinfo.field <= INT_MAX / 10) ? \
+ specinfo.field * 10 : INT_MAX; \
+ _i = *(format) - '0'; \
+ MPFR_ASSERTN (_i >= 0 && _i <= 9); \
+ specinfo.field = (specinfo.field <= INT_MAX - _i) ? \
+ specinfo.field + _i : INT_MAX; \
+ ++(format); \
+ break; \
+ case '*': \
+ specinfo.field = va_arg ((ap), int); \
+ ++(format); \
+ default: \
+ goto label_out; \
+ } \
+ } \
+ } while (0)
+
+/* arg_t contains all the types described by the 'type' field of the
+ format string */
+enum arg_t
+ {
+ NONE,
+ CHAR_ARG,
+ SHORT_ARG,
+ LONG_ARG,
+ LONG_LONG_ARG,
+ INTMAX_ARG,
+ SIZE_ARG,
+ PTRDIFF_ARG,
+ LONG_DOUBLE_ARG,
+ MPF_ARG,
+ MPQ_ARG,
+ MP_LIMB_ARG,
+ MP_LIMB_ARRAY_ARG,
+ MPZ_ARG,
+ MPFR_PREC_ARG,
+ MPFR_ARG,
+ UNSUPPORTED
+ };
+
+/* Each conversion specification of the format string will be translated in a
+ printf_spec structure by the parser.
+ This structure is adapted from the GNU libc one. */
+struct printf_spec
+{
+ unsigned int alt:1; /* # flag */
+ unsigned int space:1; /* Space flag */
+ unsigned int left:1; /* - flag */
+ unsigned int showsign:1; /* + flag */
+ unsigned int group:1; /* ' flag */
+
+ int width; /* Width */
+ int prec; /* Precision */
+
+ enum arg_t arg_type; /* Type of argument */
+ mpfr_rnd_t rnd_mode; /* Rounding mode */
+ char spec; /* Conversion specifier */
+
+ char pad; /* Padding character */
+};
+
+static void
+specinfo_init (struct printf_spec *specinfo)
+{
+ specinfo->alt = 0;
+ specinfo->space = 0;
+ specinfo->left = 0;
+ specinfo->showsign = 0;
+ specinfo->group = 0;
+ specinfo->width = 0;
+ specinfo->prec = 0;
+ specinfo->arg_type = NONE;
+ specinfo->rnd_mode = MPFR_RNDN;
+ specinfo->spec = '\0';
+ specinfo->pad = ' ';
+}
+
+#define FLOATING_POINT_ARG_TYPE(at) \
+ ((at) == MPFR_ARG || (at) == MPF_ARG || (at) == LONG_DOUBLE_ARG)
+
+#define INTEGER_LIKE_ARG_TYPE(at) \
+ ((at) == SHORT_ARG || (at) == LONG_ARG || (at) == LONG_LONG_ARG \
+ || (at) == INTMAX_ARG || (at) == MPFR_PREC_ARG || (at) == MPZ_ARG \
+ || (at) == MPQ_ARG || (at) == MP_LIMB_ARG || (at) == MP_LIMB_ARRAY_ARG \
+ || (at) == CHAR_ARG || (at) == SIZE_ARG || (at) == PTRDIFF_ARG)
+
+static int
+specinfo_is_valid (struct printf_spec spec)
+{
+ switch (spec.spec)
+ {
+ case 'n':
+ return -1;
+
+ case 'a': case 'A':
+ case 'e': case 'E':
+ case 'f': case 'F':
+ case 'g': case 'G':
+ return (spec.arg_type == NONE
+ || FLOATING_POINT_ARG_TYPE (spec.arg_type));
+
+ case 'b':
+ return spec.arg_type == MPFR_ARG;
+
+ case 'd': case 'i':
+ case 'u': case 'o':
+ case 'x': case 'X':
+ return (spec.arg_type == NONE
+ || INTEGER_LIKE_ARG_TYPE (spec.arg_type));
+
+ case 'c':
+ case 's':
+ return (spec.arg_type == NONE || spec.arg_type == LONG_ARG);
+
+ case 'p':
+ return spec.arg_type == NONE;
+
+ default:
+ return 0;
+ }
+}
+
+static const char *
+parse_flags (const char *format, struct printf_spec *specinfo)
+{
+ while (*format)
+ {
+ switch (*format)
+ {
+ case '0':
+ specinfo->pad = '0';
+ ++format;
+ break;
+ case '#':
+ specinfo->alt = 1;
+ ++format;
+ break;
+ case '+':
+ specinfo->showsign = 1;
+ ++format;
+ break;
+ case ' ':
+ specinfo->space = 1;
+ ++format;
+ break;
+ case '-':
+ specinfo->left = 1;
+ ++format;
+ break;
+ case '\'':
+ /* Single UNIX Specification for thousand separator */
+ specinfo->group = 1;
+ ++format;
+ break;
+ default:
+ return format;
+ }
+ }
+ return format;
+}
+
+static const char *
+parse_arg_type (const char *format, struct printf_spec *specinfo)
+{
+ switch (*format)
+ {
+ case '\0':
+ break;
+ case 'h':
+ if (*++format == 'h')
+#ifndef NPRINTF_HH
+ {
+ ++format;
+ specinfo->arg_type = CHAR_ARG;
+ }
+#else
+ specinfo->arg_type = UNSUPPORTED;
+#endif
+ else
+ specinfo->arg_type = SHORT_ARG;
+ break;
+ case 'l':
+ if (*++format == 'l')
+ {
+ ++format;
+#if defined (HAVE_LONG_LONG) && !defined(NPRINTF_LL)
+ specinfo->arg_type = LONG_LONG_ARG;
+#else
+ specinfo->arg_type = UNSUPPORTED;
+#endif
+ break;
+ }
+ else
+ {
+ specinfo->arg_type = LONG_ARG;
+ break;
+ }
+ case 'j':
+ ++format;
+#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J)
+ specinfo->arg_type = INTMAX_ARG;
+#else
+ specinfo->arg_type = UNSUPPORTED;
+#endif
+ break;
+ case 'z':
+ ++format;
+ specinfo->arg_type = SIZE_ARG;
+ break;
+ case 't':
+ ++format;
+#ifndef NPRINTF_T
+ specinfo->arg_type = PTRDIFF_ARG;
+#else
+ specinfo->arg_type = UNSUPPORTED;
+#endif
+ break;
+ case 'L':
+ ++format;
+#ifndef NPRINTF_L
+ specinfo->arg_type = LONG_DOUBLE_ARG;
+#else
+ specinfo->arg_type = UNSUPPORTED;
+#endif
+ break;
+ case 'F':
+ ++format;
+ specinfo->arg_type = MPF_ARG;
+ break;
+ case 'Q':
+ ++format;
+ specinfo->arg_type = MPQ_ARG;
+ break;
+ case 'M':
+ ++format;
+ /* The 'M' specifier was added in gmp 4.2.0 */
+ specinfo->arg_type = MP_LIMB_ARG;
+ break;
+ case 'N':
+ ++format;
+ specinfo->arg_type = MP_LIMB_ARRAY_ARG;
+ break;
+ case 'Z':
+ ++format;
+ specinfo->arg_type = MPZ_ARG;
+ break;
+
+ /* mpfr specific specifiers */
+ case 'P':
+ ++format;
+ specinfo->arg_type = MPFR_PREC_ARG;
+ break;
+ case 'R':
+ ++format;
+ specinfo->arg_type = MPFR_ARG;
+ }
+ return format;
+}
+
+
+/* some macros and functions filling the buffer */
+
+/* CONSUME_VA_ARG removes from va_list AP the type expected by SPECINFO */
+
+/* With a C++ compiler wchar_t and enumeration in va_list are converted to
+ integer type : int, unsigned int, long or unsigned long (unfortunately,
+ this is implementation dependant).
+ We follow gmp which assumes in print/doprnt.c that wchar_t is converted
+ to int (because wchar_t <= int).
+ For wint_t, we assume that the case WINT_MAX < INT_MAX yields an
+ integer promotion. */
+#ifdef HAVE_WCHAR_H
+#if defined(WINT_MAX) && WINT_MAX < INT_MAX
+typedef int mpfr_va_wint; /* integer promotion */
+#else
+typedef wint_t mpfr_va_wint;
+#endif
+#define CASE_LONG_ARG(specinfo, ap) \
+ case LONG_ARG: \
+ if (((specinfo).spec == 'd') || ((specinfo).spec == 'i') \
+ || ((specinfo).spec == 'o') || ((specinfo).spec == 'u') \
+ || ((specinfo).spec == 'x') || ((specinfo).spec == 'X')) \
+ (void) va_arg ((ap), long); \
+ else if ((specinfo).spec == 'c') \
+ (void) va_arg ((ap), mpfr_va_wint); \
+ else if ((specinfo).spec == 's') \
+ (void) va_arg ((ap), int); /* we assume integer promotion */ \
+ break;
+#else
+#define CASE_LONG_ARG(specinfo, ap) \
+ case LONG_ARG: \
+ (void) va_arg ((ap), long); \
+ break;
+#endif
+
+#if defined(_MPFR_H_HAVE_INTMAX_T)
+#define CASE_INTMAX_ARG(specinfo, ap) \
+ case INTMAX_ARG: \
+ (void) va_arg ((ap), intmax_t); \
+ break;
+#else
+#define CASE_INTMAX_ARG(specinfo, ap)
+#endif
+
+#ifdef HAVE_LONG_LONG
+#define CASE_LONG_LONG_ARG(specinfo, ap) \
+ case LONG_LONG_ARG: \
+ (void) va_arg ((ap), long long); \
+ break;
+#else
+#define CASE_LONG_LONG_ARG(specinfo, ap)
+#endif
+
+#define CONSUME_VA_ARG(specinfo, ap) \
+ do { \
+ switch ((specinfo).arg_type) \
+ { \
+ case CHAR_ARG: \
+ case SHORT_ARG: \
+ (void) va_arg ((ap), int); \
+ break; \
+ CASE_LONG_ARG (specinfo, ap) \
+ CASE_LONG_LONG_ARG (specinfo, ap) \
+ CASE_INTMAX_ARG (specinfo, ap) \
+ case SIZE_ARG: \
+ (void) va_arg ((ap), size_t); \
+ break; \
+ case PTRDIFF_ARG: \
+ (void) va_arg ((ap), ptrdiff_t); \
+ break; \
+ case LONG_DOUBLE_ARG: \
+ (void) va_arg ((ap), long double); \
+ break; \
+ case MPF_ARG: \
+ (void) va_arg ((ap), mpf_srcptr); \
+ break; \
+ case MPQ_ARG: \
+ (void) va_arg ((ap), mpq_srcptr); \
+ break; \
+ case MP_LIMB_ARG: \
+ (void) va_arg ((ap), mp_limb_t); \
+ break; \
+ case MP_LIMB_ARRAY_ARG: \
+ (void) va_arg ((ap), mpfr_limb_ptr); \
+ (void) va_arg ((ap), mp_size_t); \
+ break; \
+ case MPZ_ARG: \
+ (void) va_arg ((ap), mpz_srcptr); \
+ break; \
+ default: \
+ switch ((specinfo).spec) \
+ { \
+ case 'd': \
+ case 'i': \
+ case 'o': \
+ case 'u': \
+ case 'x': \
+ case 'X': \
+ case 'c': \
+ (void) va_arg ((ap), int); \
+ break; \
+ case 'f': \
+ case 'F': \
+ case 'e': \
+ case 'E': \
+ case 'g': \
+ case 'G': \
+ case 'a': \
+ case 'A': \
+ (void) va_arg ((ap), double); \
+ break; \
+ case 's': \
+ (void) va_arg ((ap), char *); \
+ break; \
+ case 'p': \
+ (void) va_arg ((ap), void *); \
+ } \
+ } \
+ } while (0)
+
+/* process the format part which does not deal with mpfr types,
+ jump to external label 'error' if gmp_asprintf return -1. */
+#define FLUSH(flag, start, end, ap, buf_ptr) \
+ do { \
+ const size_t n = (end) - (start); \
+ if ((flag)) \
+ /* previous specifiers are understood by gmp_printf */ \
+ { \
+ MPFR_TMP_DECL (marker); \
+ char *fmt_copy; \
+ MPFR_TMP_MARK (marker); \
+ fmt_copy = (char*) MPFR_TMP_ALLOC (n + 1); \
+ strncpy (fmt_copy, (start), n); \
+ fmt_copy[n] = '\0'; \
+ if (sprntf_gmp ((buf_ptr), (fmt_copy), (ap)) == -1) \
+ { \
+ MPFR_TMP_FREE (marker); \
+ goto error; \
+ } \
+ (flag) = 0; \
+ MPFR_TMP_FREE (marker); \
+ } \
+ else if ((start) != (end)) \
+ /* no conversion specification, just simple characters */ \
+ buffer_cat ((buf_ptr), (start), n); \
+ } while (0)
+
+struct string_buffer
+{
+ char *start; /* beginning of the buffer */
+ char *curr; /* null terminating character */
+ size_t size; /* buffer capacity */
+};
+
+static void
+buffer_init (struct string_buffer *b, size_t s)
+{
+ b->start = (char *) (*__gmp_allocate_func) (s);
+ b->start[0] = '\0';
+ b->curr = b->start;
+ b->size = s;
+}
+
+/* Increase buffer size by a number of character being the least multiple of
+ 4096 greater than LEN+1. */
+static void
+buffer_widen (struct string_buffer *b, size_t len)
+{
+ const size_t pos = b->curr - b->start;
+ const size_t n = 0x1000 + (len & ~((size_t) 0xfff));
+ MPFR_ASSERTD (pos < b->size);
+
+ MPFR_ASSERTN ((len & ~((size_t) 4095)) <= (size_t)(SIZE_MAX - 4096));
+ MPFR_ASSERTN (b->size < SIZE_MAX - n);
+
+ b->start =
+ (char *) (*__gmp_reallocate_func) (b->start, b->size, b->size + n);
+ b->size += n;
+ b->curr = b->start + pos;
+
+ MPFR_ASSERTD (pos < b->size);
+ MPFR_ASSERTD (*b->curr == '\0');
+}
+
+/* Concatenate the LEN first characters of the string S to the buffer B and
+ expand it if needed. */
+static void
+buffer_cat (struct string_buffer *b, const char *s, size_t len)
+{
+ MPFR_ASSERTD (len != 0);
+ MPFR_ASSERTD (len <= strlen (s));
+
+ if (MPFR_UNLIKELY ((b->curr + len) >= (b->start + b->size)))
+ buffer_widen (b, len);
+
+ strncat (b->curr, s, len);
+ b->curr += len;
+
+ MPFR_ASSERTD (b->curr < b->start + b->size);
+ MPFR_ASSERTD (*b->curr == '\0');
+}
+
+/* Add N characters C to the end of buffer B */
+static void
+buffer_pad (struct string_buffer *b, const char c, const size_t n)
+{
+ MPFR_ASSERTD (n != 0);
+
+ MPFR_ASSERTN (b->size < SIZE_MAX - n - 1);
+ if (MPFR_UNLIKELY ((b->curr + n + 1) > (b->start + b->size)))
+ buffer_widen (b, n);
+
+ if (n == 1)
+ *b->curr = c;
+ else
+ memset (b->curr, c, n);
+ b->curr += n;
+ *b->curr = '\0';
+
+ MPFR_ASSERTD (b->curr < b->start + b->size);
+}
+
+/* Form a string by concatenating the first LEN characters of STR to TZ
+ zero(s), insert into one character C each 3 characters starting from end
+ to begining and concatenate the result to the buffer B. */
+static void
+buffer_sandwich (struct string_buffer *b, char *str, size_t len,
+ const size_t tz, const char c)
+{
+ const size_t step = 3;
+ const size_t size = len + tz;
+ const size_t r = size % step == 0 ? step : size % step;
+ const size_t q = size % step == 0 ? size / step - 1 : size / step;
+ size_t i;
+
+ MPFR_ASSERTD (size != 0);
+ if (c == '\0')
+ {
+ buffer_cat (b, str, len);
+ buffer_pad (b, '0', tz);
+ return;
+ }
+
+ MPFR_ASSERTN (b->size < SIZE_MAX - size - 1 - q);
+ MPFR_ASSERTD (len <= strlen (str));
+ if (MPFR_UNLIKELY ((b->curr + size + 1 + q) > (b->start + b->size)))
+ buffer_widen (b, size + q);
+
+ /* first R significant digits */
+ memcpy (b->curr, str, r);
+ b->curr += r;
+ str += r;
+ len -= r;
+
+ /* blocks of thousands. Warning: STR might end in the middle of a block */
+ for (i = 0; i < q; ++i)
+ {
+ *b->curr++ = c;
+ if (MPFR_LIKELY (len > 0))
+ {
+ if (MPFR_LIKELY (len >= step))
+ /* step significant digits */
+ {
+ memcpy (b->curr, str, step);
+ len -= step;
+ }
+ else
+ /* last digits in STR, fill up thousand block with zeros */
+ {
+ memcpy (b->curr, str, len);
+ memset (b->curr + len, '0', step - len);
+ len = 0;
+ }
+ }
+ else
+ /* trailing zeros */
+ memset (b->curr, '0', step);
+
+ b->curr += step;
+ str += step;
+ }
+
+ *b->curr = '\0';
+
+ MPFR_ASSERTD (b->curr < b->start + b->size);
+}
+
+/* let gmp_xprintf process the part it can understand */
+static int
+sprntf_gmp (struct string_buffer *b, const char *fmt, va_list ap)
+{
+ int length;
+ char *s;
+
+ length = gmp_vasprintf (&s, fmt, ap);
+ if (length > 0)
+ buffer_cat (b, s, length);
+
+ mpfr_free_str (s);
+ return length;
+}
+
+/* Helper struct and functions for temporary strings management */
+/* struct for easy string clearing */
+struct string_list
+{
+ char *string;
+ struct string_list *next; /* NULL in last node */
+};
+
+/* initialisation */
+static void
+init_string_list (struct string_list *sl)
+{
+ sl->string = NULL;
+ sl->next = NULL;
+}
+
+/* clear all strings in the list */
+static void
+clear_string_list (struct string_list *sl)
+{
+ struct string_list *n;
+
+ while (sl)
+ {
+ if (sl->string)
+ mpfr_free_str (sl->string);
+ n = sl->next;
+ (*__gmp_free_func) (sl, sizeof(struct string_list));
+ sl = n;
+ }
+}
+
+/* add a string in the list */
+static char *
+register_string (struct string_list *sl, char *new_string)
+{
+ /* look for the last node */
+ while (sl->next)
+ sl = sl->next;
+
+ sl->next = (struct string_list*)
+ (*__gmp_allocate_func) (sizeof (struct string_list));
+
+ sl = sl->next;
+ sl->next = NULL;
+ return sl->string = new_string;
+}
+
+/* padding type: where are the padding characters */
+enum pad_t
+ {
+ LEFT, /* spaces in left hand side for right justification */
+ LEADING_ZEROS, /* padding with '0' characters in integral part */
+ RIGHT /* spaces in right hand side for left justification */
+ };
+
+/* number_parts details how much characters are needed in each part of a float
+ print. */
+struct number_parts
+{
+ enum pad_t pad_type; /* Padding type */
+ size_t pad_size; /* Number of padding characters */
+
+ char sign; /* Sign character */
+
+ char *prefix_ptr; /* Pointer to prefix part */
+ size_t prefix_size; /* Number of characters in *prefix_ptr */
+
+ char thousands_sep; /* Thousands separator (only with style 'f') */
+
+ char *ip_ptr; /* Pointer to integral part characters*/
+ size_t ip_size; /* Number of digits in *ip_ptr */
+ int ip_trailing_zeros; /* Number of additional null digits in integral
+ part */
+
+ char point; /* Decimal point character */
+
+ int fp_leading_zeros; /* Number of additional leading zeros in fractional
+ part */
+ char *fp_ptr; /* Pointer to fractional part characters */
+ size_t fp_size; /* Number of digits in *fp_ptr */
+ int fp_trailing_zeros; /* Number of additional trailing zeros in fractional
+ part */
+
+ char *exp_ptr; /* Pointer to exponent part */
+ size_t exp_size; /* Number of characters in *exp_ptr */
+
+ struct string_list *sl; /* List of string buffers in use: we need such a
+ mechanism because fp_ptr may point into the same
+ string as ip_ptr */
+};
+
+/* For a real non zero number x, what is the base exponent f when rounding x
+ with rounding mode r to r(x) = m*b^f, where m is a digit and 1 <= m < b ?
+ Return non zero value if x is rounded up to b^f, return zero otherwise */
+static int
+next_base_power_p (mpfr_srcptr x, int base, mpfr_rnd_t rnd)
+{
+ mpfr_prec_t nbits;
+ mp_limb_t pm;
+ mp_limb_t xm;
+
+ MPFR_ASSERTD (MPFR_IS_PURE_FP (x));
+ MPFR_ASSERTD (base == 2 || base == 16);
+
+ /* Warning: the decimal point is AFTER THE FIRST DIGIT in this output
+ representation. */
+ nbits = base == 2 ? 1 : 4;
+
+ if (rnd == MPFR_RNDZ
+ || (rnd == MPFR_RNDD && MPFR_IS_POS (x))
+ || (rnd == MPFR_RNDU && MPFR_IS_NEG (x))
+ || MPFR_PREC (x) <= nbits)
+ /* no rounding when printing x with 1 digit */
+ return 0;
+
+ xm = MPFR_MANT (x) [MPFR_LIMB_SIZE (x) - 1];
+ pm = MPFR_LIMB_MASK (GMP_NUMB_BITS - nbits);
+ if ((xm & ~pm) ^ ~pm)
+ /* do no round up if some of the nbits first bits are 0s. */
+ return 0;
+
+ if (rnd == MPFR_RNDN)
+ /* mask for rounding bit */
+ pm = (MPFR_LIMB_ONE << (GMP_NUMB_BITS - nbits - 1));
+
+ /* round up if some remaining bits are 1 */
+ /* warning: the return value must be an int */
+ return xm & pm ? 1 : 0;
+}
+
+/* Record information from mpfr_get_str() so as to avoid multiple
+ calls to this expensive function. */
+struct decimal_info
+{
+ mpfr_exp_t exp;
+ char *str;
+};
+
+/* For a real non zero number x, what is the exponent f so that
+ 10^f <= x < 10^(f+1). */
+static mpfr_exp_t
+floor_log10 (mpfr_srcptr x)
+{
+ mpfr_t y;
+ mpfr_exp_t exp;
+
+ /* make sure first that y can represent a mpfr_exp_t exactly
+ and can compare with x */
+ mpfr_prec_t prec = sizeof (mpfr_exp_t) * CHAR_BIT;
+ mpfr_init2 (y, MAX (prec, MPFR_PREC (x)));
+
+ exp = mpfr_ceil_mul (MPFR_GET_EXP (x), 10, 1) - 1;
+ mpfr_set_exp_t (y, exp, MPFR_RNDU);
+ /* The following call to mpfr_ui_pow should be fast: y is an integer
+ (not too large), so that mpfr_pow_z will be used internally. */
+ mpfr_ui_pow (y, 10, y, MPFR_RNDU);
+ if (mpfr_cmpabs (x, y) < 0)
+ exp--;
+
+ mpfr_clear (y);
+ return exp;
+}
+
+/* Determine the different parts of the string representation of the regular
+ number P when SPEC.SPEC is 'a', 'A', or 'b'.
+
+ return -1 if some field > INT_MAX */
+static int
+regular_ab (struct number_parts *np, mpfr_srcptr p,
+ const struct printf_spec spec)
+{
+ int uppercase;
+ int base;
+ char *str;
+ mpfr_exp_t exp;
+
+ uppercase = spec.spec == 'A';
+
+ /* sign */
+ if (MPFR_IS_NEG (p))
+ np->sign = '-';
+ else if (spec.showsign || spec.space)
+ np->sign = spec.showsign ? '+' : ' ';
+
+ if (spec.spec == 'a' || spec.spec == 'A')
+ /* prefix part */
+ {
+ np->prefix_size = 2;
+ str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
+ str[0] = '0';
+ str[1] = uppercase ? 'X' : 'x';
+ str[2] = '\0';
+ np->prefix_ptr = register_string (np->sl, str);
+ }
+
+ /* integral part */
+ np->ip_size = 1;
+ base = (spec.spec == 'b') ? 2 : 16;
+
+ if (spec.prec != 0)
+ {
+ size_t nsd;
+
+ /* Number of significant digits:
+ - if no given precision, let mpfr_get_str determine it;
+ - if a non-zero precision is specified, then one digit before decimal
+ point plus SPEC.PREC after it. */
+ nsd = spec.prec < 0 ? 0 : spec.prec + np->ip_size;
+ str = mpfr_get_str (0, &exp, base, nsd, p, spec.rnd_mode);
+ register_string (np->sl, str);
+ np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign if any */
+
+ if (base == 16)
+ /* EXP is the exponent for radix sixteen with decimal point BEFORE the
+ first digit, we want the exponent for radix two and the decimal
+ point AFTER the first digit. */
+ {
+ MPFR_ASSERTN (exp > MPFR_EMIN_MIN /4); /* possible overflow */
+ exp = (exp - 1) * 4;
+ }
+ else
+ /* EXP is the exponent for decimal point BEFORE the first digit, we
+ want the exponent for decimal point AFTER the first digit. */
+ {
+ MPFR_ASSERTN (exp > MPFR_EMIN_MIN); /* possible overflow */
+ --exp;
+ }
+ }
+ else if (next_base_power_p (p, base, spec.rnd_mode))
+ {
+ str = (char *)(*__gmp_allocate_func) (2);
+ str[0] = '1';
+ str[1] = '\0';
+ np->ip_ptr = register_string (np->sl, str);
+
+ exp = MPFR_GET_EXP (p);
+ }
+ else if (base == 2)
+ {
+ str = (char *)(*__gmp_allocate_func) (2);
+ str[0] = '1';
+ str[1] = '\0';
+ np->ip_ptr = register_string (np->sl, str);
+
+ exp = MPFR_GET_EXP (p) - 1;
+ }
+ else
+ {
+ int digit;
+ mp_limb_t msl = MPFR_MANT (p)[MPFR_LIMB_SIZE (p) - 1];
+ int rnd_bit = GMP_NUMB_BITS - 5;
+
+ /* pick up the 4 first bits */
+ digit = msl >> (rnd_bit+1);
+ if (spec.rnd_mode == MPFR_RNDA
+ || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
+ || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
+ || (spec.rnd_mode == MPFR_RNDN
+ && (msl & (MPFR_LIMB_ONE << rnd_bit))))
+ digit++;
+ MPFR_ASSERTD ((0 <= digit) && (digit <= 15));
+
+ str = (char *)(*__gmp_allocate_func) (1 + np->ip_size);
+ str[0] = num_to_text [digit];
+ str[1] = '\0';
+ np->ip_ptr = register_string (np->sl, str);
+
+ exp = MPFR_GET_EXP (p) - 4;
+ }
+
+ if (uppercase)
+ /* All digits in upper case */
+ {
+ char *s1 = str;
+ while (*s1)
+ {
+ switch (*s1)
+ {
+ case 'a':
+ *s1 = 'A';
+ break;
+ case 'b':
+ *s1 = 'B';
+ break;
+ case 'c':
+ *s1 = 'C';
+ break;
+ case 'd':
+ *s1 = 'D';
+ break;
+ case 'e':
+ *s1 = 'E';
+ break;
+ case 'f':
+ *s1 = 'F';
+ break;
+ }
+ s1++;
+ }
+ }
+
+ if (spec.spec == 'b' || spec.prec != 0)
+ /* compute the number of digits in fractional part */
+ {
+ char *ptr;
+ size_t str_len;
+
+ /* the sign has been skipped, skip also the first digit */
+ ++str;
+ str_len = strlen (str);
+ ptr = str + str_len - 1; /* points to the end of str */
+
+ if (spec.prec < 0)
+ /* remove trailing zeros, if any */
+ {
+ while ((*ptr == '0') && (str_len != 0))
+ {
+ --ptr;
+ --str_len;
+ }
+ }
+
+ if (str_len > INT_MAX)
+ /* too many digits in fractional part */
+ return -1;
+
+ if (str_len != 0)
+ /* there are some non-zero digits in fractional part */
+ {
+ np->fp_ptr = str;
+ np->fp_size = str_len;
+ if ((int) str_len < spec.prec)
+ np->fp_trailing_zeros = spec.prec - str_len;
+ }
+ }
+
+ /* decimal point */
+ if ((np->fp_size != 0) || spec.alt)
+ np->point = MPFR_DECIMAL_POINT;
+
+ /* the exponent part contains the character 'p', or 'P' plus the sign
+ character plus at least one digit and only as many more digits as
+ necessary to represent the exponent.
+ We assume that |EXP| < 10^INT_MAX. */
+ np->exp_size = 3;
+ {
+ mpfr_uexp_t x;
+
+ x = SAFE_ABS (mpfr_uexp_t, exp);
+ while (x > 9)
+ {
+ np->exp_size++;
+ x /= 10;
+ }
+ }
+ str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
+ np->exp_ptr = register_string (np->sl, str);
+ {
+ char exp_fmt[8]; /* contains at most 7 characters like in "p%+.1i",
+ or "P%+.2li" */
+
+ exp_fmt[0] = uppercase ? 'P' : 'p';
+ exp_fmt[1] = '\0';
+ strcat (exp_fmt, "%+.1" MPFR_EXP_FSPEC "d");
+
+ if (sprintf (str, exp_fmt, (mpfr_eexp_t) exp) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Determine the different parts of the string representation of the regular
+ number P when SPEC.SPEC is 'e', 'E', 'g', or 'G'.
+ DEC_INFO contains the previously computed exponent and string or is NULL.
+
+ return -1 if some field > INT_MAX */
+static int
+regular_eg (struct number_parts *np, mpfr_srcptr p,
+ const struct printf_spec spec, struct decimal_info *dec_info)
+{
+ char *str;
+ mpfr_exp_t exp;
+
+ const int uppercase = spec.spec == 'E' || spec.spec == 'G';
+ const int spec_g = spec.spec == 'g' || spec.spec == 'G';
+ const int keep_trailing_zeros = (spec_g && spec.alt)
+ || (!spec_g && (spec.prec > 0));
+
+ /* sign */
+ if (MPFR_IS_NEG (p))
+ np->sign = '-';
+ else if (spec.showsign || spec.space)
+ np->sign = spec.showsign ? '+' : ' ';
+
+ /* integral part */
+ np->ip_size = 1;
+ if (dec_info == NULL)
+ {
+ size_t nsd;
+
+ /* Number of significant digits:
+ - if no given precision, then let mpfr_get_str determine it,
+ - if a precision is specified, then one digit before decimal point
+ plus SPEC.PREC after it.
+ We use the fact here that mpfr_get_str allows us to ask for only one
+ significant digit when the base is not a power of 2. */
+ nsd = (spec.prec < 0) ? 0 : spec.prec + np->ip_size;
+ str = mpfr_get_str (0, &exp, 10, nsd, p, spec.rnd_mode);
+ register_string (np->sl, str);
+ }
+ else
+ {
+ exp = dec_info->exp;
+ str = dec_info->str;
+ }
+ np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign if any */
+
+ if (spec.prec != 0)
+ /* compute the number of digits in fractional part */
+ {
+ char *ptr;
+ size_t str_len;
+
+ /* the sign has been skipped, skip also the first digit */
+ ++str;
+ str_len = strlen (str);
+ ptr = str + str_len - 1; /* points to the end of str */
+
+ if (!keep_trailing_zeros)
+ /* remove trailing zeros, if any */
+ {
+ while ((*ptr == '0') && (str_len != 0))
+ {
+ --ptr;
+ --str_len;
+ }
+ }
+
+ if (str_len > INT_MAX)
+ /* too many digits in fractional part */
+ return -1;
+
+ if (str_len != 0)
+ /* there are some non-zero digits in fractional part */
+ {
+ np->fp_ptr = str;
+ np->fp_size = str_len;
+ if ((!spec_g || spec.alt) && (spec.prec > 0)
+ && ((int)str_len < spec.prec))
+ /* add missing trailing zeros */
+ np->fp_trailing_zeros = spec.prec - str_len;
+ }
+ }
+
+ /* decimal point */
+ if (np->fp_size != 0 || spec.alt)
+ np->point = MPFR_DECIMAL_POINT;
+
+ /* EXP is the exponent for decimal point BEFORE the first digit, we want
+ the exponent for decimal point AFTER the first digit.
+ Here, no possible overflow because exp < MPFR_EXP (p) / 3 */
+ exp--;
+
+ /* the exponent part contains the character 'e', or 'E' plus the sign
+ character plus at least two digits and only as many more digits as
+ necessary to represent the exponent.
+ We assume that |EXP| < 10^INT_MAX. */
+ np->exp_size = 3;
+ {
+ mpfr_uexp_t x;
+
+ x = SAFE_ABS (mpfr_uexp_t, exp);
+ while (x > 9)
+ {
+ np->exp_size++;
+ x /= 10;
+ }
+ }
+ if (np->exp_size < 4)
+ np->exp_size = 4;
+
+ str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
+ np->exp_ptr = register_string (np->sl, str);
+
+ {
+ char exp_fmt[8]; /* e.g. "e%+.2i", or "E%+.2li" */
+
+ exp_fmt[0] = uppercase ? 'E' : 'e';
+ exp_fmt[1] = '\0';
+ strcat (exp_fmt, "%+.2" MPFR_EXP_FSPEC "d");
+
+ if (sprintf (str, exp_fmt, (mpfr_eexp_t) exp) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Determine the different parts of the string representation of the regular
+ number P when SPEC.SPEC is 'f', 'F', 'g', or 'G'.
+ DEC_INFO contains the previously computed exponent and string or is NULL.
+
+ return -1 if some field of number_parts is greater than INT_MAX */
+static int
+regular_fg (struct number_parts *np, mpfr_srcptr p,
+ const struct printf_spec spec, struct decimal_info *dec_info)
+{
+ mpfr_exp_t exp;
+ char * str;
+ const int spec_g = (spec.spec == 'g' || spec.spec == 'G');
+ const int keep_trailing_zeros = !spec_g || spec.alt;
+
+ /* WARNING: an empty precision field is forbidden (it means precision = 6
+ and it should have been changed to 6 before the function call) */
+ MPFR_ASSERTD (spec.prec >= 0);
+
+ /* sign */
+ if (MPFR_IS_NEG (p))
+ np->sign = '-';
+ else if (spec.showsign || spec.space)
+ np->sign = spec.showsign ? '+' : ' ';
+
+ if (MPFR_GET_EXP (p) <= 0)
+ /* 0 < |p| < 1 */
+ {
+ /* Most of the time, integral part is 0 */
+ np->ip_size = 1;
+ str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
+ str[0] = '0';
+ str[1] = '\0';
+ np->ip_ptr = register_string (np->sl, str);
+
+ if (spec.prec == 0)
+ /* only two possibilities: either 1 or 0. */
+ {
+ mpfr_t y;
+ /* y = abs(p) */
+ MPFR_ALIAS (y, p, 1, MPFR_EXP (p));
+
+ if (spec.rnd_mode == MPFR_RNDA
+ || (spec.rnd_mode == MPFR_RNDD && MPFR_IS_NEG (p))
+ || (spec.rnd_mode == MPFR_RNDU && MPFR_IS_POS (p))
+ || (spec.rnd_mode == MPFR_RNDN && mpfr_cmp_d (y, 0.5) > 0))
+ /* rounded up to 1: one digit '1' in integral part.
+ note that 0.5 is rounded to 0 with RNDN (round ties to even) */
+ np->ip_ptr[0] = '1';
+ }
+ else
+ {
+ /* exp = position of the most significant decimal digit. */
+ exp = floor_log10 (p);
+ MPFR_ASSERTD (exp < 0);
+
+ if (exp < -spec.prec)
+ /* only the last digit may be non zero */
+ {
+ int round_away;
+ switch (spec.rnd_mode)
+ {
+ case MPFR_RNDA:
+ round_away = 1;
+ break;
+ case MPFR_RNDD:
+ round_away = MPFR_IS_NEG (p);
+ break;
+ case MPFR_RNDU:
+ round_away = MPFR_IS_POS (p);
+ break;
+ case MPFR_RNDN:
+ {
+ /* compare |p| to y = 0.5*10^(-spec.prec) */
+ mpfr_t y;
+ mpfr_exp_t e = MAX (MPFR_PREC (p), 56);
+ mpfr_init2 (y, e + 8);
+ do
+ {
+ /* find a lower approximation of
+ 0.5*10^(-spec.prec) different from |p| */
+ e += 8;
+ mpfr_set_prec (y, e);
+ mpfr_set_si (y, -spec.prec, MPFR_RNDN);
+ mpfr_exp10 (y, y, MPFR_RNDD);
+ mpfr_div_2ui (y, y, 1, MPFR_RNDN);
+ } while (mpfr_cmpabs (y, p) == 0);
+
+ round_away = mpfr_cmpabs (y, p) < 0;
+ mpfr_clear (y);
+ }
+ break;
+ default:
+ round_away = 0;
+ }
+
+ if (round_away)
+ /* round away from zero: the last output digit is '1' */
+ {
+ np->fp_leading_zeros = spec.prec - 1;
+
+ np->fp_size = 1;
+ str =
+ (char *) (*__gmp_allocate_func) (1 + np->fp_size);
+ str[0] = '1';
+ str[1] = '\0';
+ np->fp_ptr = register_string (np->sl, str);
+ }
+ else
+ /* only zeros in fractional part */
+ {
+ MPFR_ASSERTD (!spec_g);
+ np->fp_leading_zeros = spec.prec;
+ }
+ }
+ else
+ /* the most significant digits are the last
+ spec.prec + exp + 1 digits in fractional part */
+ {
+ char *ptr;
+ size_t str_len;
+ if (dec_info == NULL)
+ {
+ size_t nsd = spec.prec + exp + 1;
+ /* WARNING: nsd may equal 1, but here we use the
+ fact that mpfr_get_str can return one digit with
+ base ten (undocumented feature, see comments in
+ get_str.c) */
+
+ str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode);
+ register_string (np->sl, str);
+ }
+ else
+ {
+ exp = dec_info->exp;
+ str = dec_info->str;
+ }
+ if (MPFR_IS_NEG (p))
+ /* skip sign */
+ ++str;
+ if (exp == 1)
+ /* round up to 1 */
+ {
+ MPFR_ASSERTD (str[0] == '1');
+ np->ip_ptr[0] = '1';
+ if (!spec_g || spec.alt)
+ np->fp_leading_zeros = spec.prec;
+ }
+ else
+ {
+ np->fp_ptr = str;
+ np->fp_leading_zeros = -exp;
+ MPFR_ASSERTD (exp <= 0);
+
+ str_len = strlen (str); /* the sign has been skipped */
+ ptr = str + str_len - 1; /* points to the end of str */
+
+ if (!keep_trailing_zeros)
+ /* remove trailing zeros, if any */
+ {
+ while ((*ptr == '0') && str_len)
+ {
+ --ptr;
+ --str_len;
+ }
+ }
+
+ if (str_len > INT_MAX)
+ /* too many digits in fractional part */
+ return -1;
+
+ MPFR_ASSERTD (str_len > 0);
+ np->fp_size = str_len;
+
+ if ((!spec_g || spec.alt)
+ && spec.prec > 0
+ && (np->fp_leading_zeros + np->fp_size < spec.prec))
+ /* add missing trailing zeros */
+ np->fp_trailing_zeros = spec.prec - np->fp_leading_zeros
+ - np->fp_size;
+ }
+ }
+ }
+
+ if (spec.alt || np->fp_leading_zeros != 0 || np->fp_size != 0
+ || np->fp_trailing_zeros != 0)
+ np->point = MPFR_DECIMAL_POINT;
+ }
+ else
+ /* 1 <= |p| */
+ {
+ size_t str_len;
+
+ /* Determine the position of the most significant decimal digit. */
+ exp = floor_log10 (p);
+ MPFR_ASSERTD (exp >= 0);
+ if (exp > INT_MAX)
+ /* P is too large to print all its integral part digits */
+ return -1;
+
+ if (dec_info == NULL)
+ { /* this case occurs with mpfr_printf ("%.0RUf", x) with x=9.5 */
+ str =
+ mpfr_get_str (NULL, &exp, 10, spec.prec+exp+1, p, spec.rnd_mode);
+ register_string (np->sl, str);
+ }
+ else
+ {
+ exp = dec_info->exp;
+ str = dec_info->str;
+ }
+ np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign */
+ str_len = strlen (str);
+
+ /* integral part */
+ if (exp > str_len)
+ /* mpfr_get_str gives no trailing zero when p is rounded up to the next
+ power of 10 (p integer, so no fractional part) */
+ {
+ np->ip_trailing_zeros = exp - str_len;
+ np->ip_size = str_len;
+ }
+ else
+ np->ip_size = exp;
+
+ if (spec.group)
+ /* thousands separator in integral part */
+ np->thousands_sep = MPFR_THOUSANDS_SEPARATOR;
+
+ /* fractional part */
+ str += np->ip_size;
+ str_len -= np->ip_size;
+ if (!keep_trailing_zeros)
+ /* remove trailing zeros, if any */
+ {
+ char *ptr = str + str_len - 1; /* pointer to the last digit of
+ str */
+ while ((*ptr == '0') && (str_len != 0))
+ {
+ --ptr;
+ --str_len;
+ }
+ }
+
+ if (str_len > 0)
+ /* some nonzero digits in fractional part */
+ {
+ if (str_len > INT_MAX)
+ /* too many digits in fractional part */
+ return -1;
+
+ np->point = MPFR_DECIMAL_POINT;
+ np->fp_ptr = str;
+ np->fp_size = str_len;
+ }
+
+ if (keep_trailing_zeros && str_len < spec.prec)
+ /* add missing trailing zeros */
+ {
+ np->point = MPFR_DECIMAL_POINT;
+ np->fp_trailing_zeros = spec.prec - np->fp_size;
+ }
+
+ if (spec.alt)
+ /* add decimal point even if no digits follow it */
+ np->point = MPFR_DECIMAL_POINT;
+ }
+
+ return 0;
+}
+
+/* partition_number determines the different parts of the string
+ representation of the number p according to the given specification.
+ partition_number initializes the given structure np, so all previous
+ information in that variable is lost.
+ return the total number of characters to be written.
+ return -1 if an error occured, in that case np's fields are in an undefined
+ state but all string buffers have been freed. */
+static int
+partition_number (struct number_parts *np, mpfr_srcptr p,
+ struct printf_spec spec)
+{
+ char *str;
+ long total;
+ int uppercase;
+
+ /* WARNING: left justification means right space padding */
+ np->pad_type = spec.left ? RIGHT : spec.pad == '0' ? LEADING_ZEROS : LEFT;
+ np->pad_size = 0;
+ np->sign = '\0';
+ np->prefix_ptr =NULL;
+ np->prefix_size = 0;
+ np->thousands_sep = '\0';
+ np->ip_ptr = NULL;
+ np->ip_size = 0;
+ np->ip_trailing_zeros = 0;
+ np->point = '\0';
+ np->fp_leading_zeros = 0;
+ np->fp_ptr = NULL;
+ np->fp_size = 0;
+ np->fp_trailing_zeros = 0;
+ np->exp_ptr = NULL;
+ np->exp_size = 0;
+ np->sl = (struct string_list *)
+ (*__gmp_allocate_func) (sizeof (struct string_list));
+ init_string_list (np->sl);
+
+ uppercase = spec.spec == 'A' || spec.spec == 'E' || spec.spec == 'F'
+ || spec.spec == 'G';
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (p)))
+ {
+ if (MPFR_IS_NAN (p))
+ {
+ if (np->pad_type == LEADING_ZEROS)
+ /* don't want "0000nan", change to right justification padding
+ with left spaces instead */
+ np->pad_type = LEFT;
+
+ if (uppercase)
+ {
+ np->ip_size = MPFR_NAN_STRING_LENGTH;
+ str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
+ strcpy (str, MPFR_NAN_STRING_UC);
+ np->ip_ptr = register_string (np->sl, str);
+ }
+ else
+ {
+ np->ip_size = MPFR_NAN_STRING_LENGTH;
+ str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
+ strcpy (str, MPFR_NAN_STRING_LC);
+ np->ip_ptr = register_string (np->sl, str);
+ }
+ }
+ else if (MPFR_IS_INF (p))
+ {
+ if (np->pad_type == LEADING_ZEROS)
+ /* don't want "0000inf", change to right justification padding
+ with left spaces instead */
+ np->pad_type = LEFT;
+
+ if (MPFR_IS_NEG (p))
+ np->sign = '-';
+
+ if (uppercase)
+ {
+ np->ip_size = MPFR_INF_STRING_LENGTH;
+ str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
+ strcpy (str, MPFR_INF_STRING_UC);
+ np->ip_ptr = register_string (np->sl, str);
+ }
+ else
+ {
+ np->ip_size = MPFR_INF_STRING_LENGTH;
+ str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
+ strcpy (str, MPFR_INF_STRING_LC);
+ np->ip_ptr = register_string (np->sl, str);
+ }
+ }
+ else
+ /* p == 0 */
+ {
+ /* note: for 'g' spec, zero is always displayed with 'f'-style with
+ precision spec.prec - 1 and the trailing zeros are removed unless
+ the flag '#' is used. */
+ if (MPFR_IS_NEG (p))
+ /* signed zero */
+ np->sign = '-';
+ else if (spec.showsign || spec.space)
+ np->sign = spec.showsign ? '+' : ' ';
+
+ if (spec.spec == 'a' || spec.spec == 'A')
+ /* prefix part */
+ {
+ np->prefix_size = 2;
+ str = (char *) (*__gmp_allocate_func) (1 + np->prefix_size);
+ str[0] = '0';
+ str[1] = uppercase ? 'X' : 'x';
+ str[2] = '\0';
+ np->prefix_ptr = register_string (np->sl, str);
+ }
+
+ /* integral part */
+ np->ip_size = 1;
+ str = (char *) (*__gmp_allocate_func) (1 + np->ip_size);
+ str[0] = '0';
+ str[1] = '\0';
+ np->ip_ptr = register_string (np->sl, str);
+
+ if (spec.prec > 0
+ && ((spec.spec != 'g' && spec.spec != 'G') || spec.alt))
+ /* fractional part */
+ {
+ np->point = MPFR_DECIMAL_POINT;
+ np->fp_trailing_zeros = (spec.spec == 'g' && spec.spec == 'G') ?
+ spec.prec - 1 : spec.prec;
+ }
+ else if (spec.alt)
+ np->point = MPFR_DECIMAL_POINT;
+
+ if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b'
+ || spec.spec == 'e' || spec.spec == 'E')
+ /* exponent part */
+ {
+ np->exp_size = (spec.spec == 'e' || spec.spec == 'E') ? 4 : 3;
+ str = (char *) (*__gmp_allocate_func) (1 + np->exp_size);
+ if (spec.spec == 'e' || spec.spec == 'E')
+ strcpy (str, uppercase ? "E+00" : "e+00");
+ else
+ strcpy (str, uppercase ? "P+0" : "p+0");
+ np->exp_ptr = register_string (np->sl, str);
+ }
+ }
+ }
+ else
+ /* regular p, p != 0 */
+ {
+ if (spec.spec == 'a' || spec.spec == 'A' || spec.spec == 'b')
+ {
+ if (regular_ab (np, p, spec) == -1)
+ goto error;
+ }
+ else if (spec.spec == 'f' || spec.spec == 'F')
+ {
+ if (spec.prec == -1)
+ spec.prec = 6;
+ if (regular_fg (np, p, spec, NULL) == -1)
+ goto error;
+ }
+ else if (spec.spec == 'e' || spec.spec == 'E')
+ {
+ if (regular_eg (np, p, spec, NULL) == -1)
+ goto error;
+ }
+ else
+ /* %g case */
+ {
+ /* Use the C99 rules:
+ if T > X >= -4 then the conversion is with style 'f'/'F' and
+ precision T-(X+1).
+ otherwise, the conversion is with style 'e'/'E' and
+ precision T-1.
+ where T is the threshold computed below and X is the exponent
+ that would be displayed with style 'e' and precision T-1. */
+ int threshold;
+ mpfr_exp_t x;
+ struct decimal_info dec_info;
+
+ threshold = (spec.prec < 0) ? 6 : (spec.prec == 0) ? 1 : spec.prec;
+ dec_info.str = mpfr_get_str (NULL, &dec_info.exp, 10, threshold,
+ p, spec.rnd_mode);
+ register_string (np->sl, dec_info.str);
+ /* mpfr_get_str corresponds to a significand between 0.1 and 1,
+ whereas here we want a significand between 1 and 10. */
+ x = dec_info.exp - 1;
+
+ if (threshold > x && x >= -4)
+ {
+ /* the conversion is with style 'f' */
+ spec.prec = threshold - x - 1;
+
+ if (regular_fg (np, p, spec, &dec_info) == -1)
+ goto error;
+ }
+ else
+ {
+ spec.prec = threshold - 1;
+
+ if (regular_eg (np, p, spec, &dec_info) == -1)
+ goto error;
+ }
+ }
+ }
+
+ /* compute the number of characters to be written verifying it is not too
+ much */
+ total = np->sign ? 1 : 0;
+ total += np->prefix_size;
+ total += np->ip_size;
+ if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
+ goto error;
+ total += np->ip_trailing_zeros;
+ if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
+ goto error;
+ if (np->thousands_sep)
+ /* ' flag, style f and the thousands separator in current locale is not
+ reduced to the null character */
+ total += (np->ip_size + np->ip_trailing_zeros) / 3;
+ if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
+ goto error;
+ if (np->point)
+ ++total;
+ total += np->fp_leading_zeros;
+ if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
+ goto error;
+ total += np->fp_size;
+ if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
+ goto error;
+ total += np->fp_trailing_zeros;
+ if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
+ goto error;
+ total += np->exp_size;
+ if (MPFR_UNLIKELY (total < 0 || total > INT_MAX))
+ goto error;
+
+ if (spec.width > total)
+ /* pad with spaces or zeros depending on np->pad_type */
+ {
+ np->pad_size = spec.width - total;
+ total += np->pad_size; /* here total == spec.width,
+ so 0 < total < INT_MAX */
+ }
+
+ return total;
+
+ error:
+ clear_string_list (np->sl);
+ np->prefix_ptr = NULL;
+ np->ip_ptr = NULL;
+ np->fp_ptr = NULL;
+ np->exp_ptr = NULL;
+ return -1;
+}
+
+/* sprnt_fp prints a mpfr_t according to spec.spec specification.
+
+ return the size of the string (not counting the terminating '\0')
+ return -1 if the built string is too long (i.e. has more than
+ INT_MAX characters). */
+static int
+sprnt_fp (struct string_buffer *buf, mpfr_srcptr p,
+ const struct printf_spec spec)
+{
+ int length;
+ struct number_parts np;
+
+ length = partition_number (&np, p, spec);
+ if (length < 0)
+ return -1;
+
+ /* right justification padding with left spaces */
+ if (np.pad_type == LEFT && np.pad_size != 0)
+ buffer_pad (buf, ' ', np.pad_size);
+
+ /* sign character (may be '-', '+', or ' ') */
+ if (np.sign)
+ buffer_pad (buf, np.sign, 1);
+
+ /* prefix part */
+ if (np.prefix_ptr)
+ buffer_cat (buf, np.prefix_ptr, np.prefix_size);
+
+ /* right justification padding with leading zeros */
+ if (np.pad_type == LEADING_ZEROS && np.pad_size != 0)
+ buffer_pad (buf, '0', np.pad_size);
+
+ /* integral part (may also be "nan" or "inf") */
+ MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */
+ if (MPFR_UNLIKELY (np.thousands_sep))
+ buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros,
+ np.thousands_sep);
+ else
+ {
+ buffer_cat (buf, np.ip_ptr, np.ip_size);
+
+ /* trailing zeros in integral part */
+ if (np.ip_trailing_zeros != 0)
+ buffer_pad (buf, '0', np.ip_trailing_zeros);
+ }
+
+ /* decimal point */
+ if (np.point)
+ buffer_pad (buf, np.point, 1);
+
+ /* leading zeros in fractional part */
+ if (np.fp_leading_zeros != 0)
+ buffer_pad (buf, '0', np.fp_leading_zeros);
+
+ /* significant digits in fractional part */
+ if (np.fp_ptr)
+ buffer_cat (buf, np.fp_ptr, np.fp_size);
+
+ /* trailing zeros in fractional part */
+ if (np.fp_trailing_zeros != 0)
+ buffer_pad (buf, '0', np.fp_trailing_zeros);
+
+ /* exponent part */
+ if (np.exp_ptr)
+ buffer_cat (buf, np.exp_ptr, np.exp_size);
+
+ /* left justication padding with right spaces */
+ if (np.pad_type == RIGHT && np.pad_size != 0)
+ buffer_pad (buf, ' ', np.pad_size);
+
+ clear_string_list (np.sl);
+ return length;
+}
+
+int
+mpfr_vasprintf (char **ptr, const char *fmt, va_list ap)
+{
+ struct string_buffer buf;
+ size_t nbchar;
+
+ /* informations on the conversion specification filled by the parser */
+ struct printf_spec spec;
+ /* flag raised when previous part of fmt need to be processed by
+ gmp_vsnprintf */
+ int xgmp_fmt_flag;
+ /* beginning and end of the previous unprocessed part of fmt */
+ const char *start, *end;
+ /* pointer to arguments for gmp_vasprintf */
+ va_list ap2;
+
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ nbchar = 0;
+ buffer_init (&buf, 4096);
+ xgmp_fmt_flag = 0;
+ va_copy (ap2, ap);
+ start = fmt;
+ while (*fmt)
+ {
+ /* Look for the next format specification */
+ while ((*fmt) && (*fmt != '%'))
+ ++fmt;
+
+ if (*fmt == '\0')
+ break;
+
+ if (*++fmt == '%')
+ /* %%: go one step further otherwise the second '%' would be
+ considered as a new conversion specification introducing
+ character */
+ {
+ ++fmt;
+ xgmp_fmt_flag = 1;
+ continue;
+ }
+
+ end = fmt - 1;
+
+ /* format string analysis */
+ specinfo_init (&spec);
+ fmt = parse_flags (fmt, &spec);
+
+ READ_INT (ap, fmt, spec, width, width_analysis);
+ width_analysis:
+ if (spec.width < 0)
+ {
+ spec.left = 1;
+ spec.width = -spec.width;
+ MPFR_ASSERTN (spec.width < INT_MAX);
+ }
+ if (*fmt == '.')
+ {
+ const char *f = ++fmt;
+ READ_INT (ap, fmt, spec, prec, prec_analysis);
+ prec_analysis:
+ if (f == fmt)
+ spec.prec = -1;
+ }
+ else
+ spec.prec = -1;
+
+ fmt = parse_arg_type (fmt, &spec);
+ if (spec.arg_type == UNSUPPORTED)
+ /* the current architecture doesn't support this type */
+ {
+ goto error;
+ }
+ else if (spec.arg_type == MPFR_ARG)
+ {
+ switch (*fmt)
+ {
+ case '\0':
+ break;
+ case '*':
+ ++fmt;
+ spec.rnd_mode = (mpfr_rnd_t) va_arg (ap, int);
+ break;
+ case 'D':
+ ++fmt;
+ spec.rnd_mode = MPFR_RNDD;
+ break;
+ case 'U':
+ ++fmt;
+ spec.rnd_mode = MPFR_RNDU;
+ break;
+ case 'Y':
+ ++fmt;
+ spec.rnd_mode = MPFR_RNDA;
+ break;
+ case 'Z':
+ ++fmt;
+ spec.rnd_mode = MPFR_RNDZ;
+ break;
+ case 'N':
+ ++fmt;
+ default:
+ spec.rnd_mode = MPFR_RNDN;
+ }
+ }
+
+ spec.spec = *fmt;
+ if (!specinfo_is_valid (spec))
+ goto error;
+
+ if (*fmt)
+ fmt++;
+
+ /* Format processing */
+ if (spec.spec == '\0')
+ /* end of the format string */
+ break;
+ else if (spec.spec == 'n')
+ /* put the number of characters written so far in the location pointed
+ by the next va_list argument; the types of pointer accepted are the
+ same as in GMP (except unsupported quad_t) plus pointer to a mpfr_t
+ so as to be able to accept the same format strings. */
+ {
+ void *p;
+ size_t nchar;
+
+ p = va_arg (ap, void *);
+ FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
+ va_end (ap2);
+ start = fmt;
+ nchar = buf.curr - buf.start;
+
+ switch (spec.arg_type)
+ {
+ case CHAR_ARG:
+ *(char *) p = (char) nchar;
+ break;
+ case SHORT_ARG:
+ *(short *) p = (short) nchar;
+ break;
+ case LONG_ARG:
+ *(long *) p = (long) nchar;
+ break;
+#ifdef HAVE_LONG_LONG
+ case LONG_LONG_ARG:
+ *(long long *) p = (long long) nchar;
+ break;
+#endif
+#ifdef _MPFR_H_HAVE_INTMAX_T
+ case INTMAX_ARG:
+ *(intmax_t *) p = (intmax_t) nchar;
+ break;
+#endif
+ case SIZE_ARG:
+ *(size_t *) p = nchar;
+ break;
+ case PTRDIFF_ARG:
+ *(ptrdiff_t *) p = (ptrdiff_t) nchar;
+ break;
+ case MPF_ARG:
+ mpf_set_ui ((mpf_ptr) p, (unsigned long) nchar);
+ break;
+ case MPQ_ARG:
+ mpq_set_ui ((mpq_ptr) p, (unsigned long) nchar, 1L);
+ break;
+ case MP_LIMB_ARG:
+ *(mp_limb_t *) p = (mp_limb_t) nchar;
+ break;
+ case MP_LIMB_ARRAY_ARG:
+ {
+ mp_limb_t *q = (mp_limb_t *) p;
+ mp_size_t n;
+ n = va_arg (ap, mp_size_t);
+ if (n < 0)
+ n = -n;
+ else if (n == 0)
+ break;
+
+ /* we assume here that mp_limb_t is wider than int */
+ *q = (mp_limb_t) nchar;
+ while (--n != 0)
+ {
+ q++;
+ *q = (mp_limb_t) 0;
+ }
+ }
+ break;
+ case MPZ_ARG:
+ mpz_set_ui ((mpz_ptr) p, (unsigned long) nchar);
+ break;
+
+ case MPFR_ARG:
+ mpfr_set_ui ((mpfr_ptr) p, (unsigned long) nchar,
+ spec.rnd_mode);
+ break;
+
+ default:
+ *(int *) p = (int) nchar;
+ }
+ va_copy (ap2, ap); /* after the switch, due to MP_LIMB_ARRAY_ARG
+ case */
+ }
+ else if (spec.arg_type == MPFR_PREC_ARG)
+ /* output mpfr_prec_t variable */
+ {
+ char *s;
+ char format[MPFR_PREC_FORMAT_SIZE + 6]; /* see examples below */
+ size_t length;
+ mpfr_prec_t prec;
+ prec = va_arg (ap, mpfr_prec_t);
+
+ FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
+ va_end (ap2);
+ va_copy (ap2, ap);
+ start = fmt;
+
+ /* construct format string, like "%*.*hu" "%*.*u" or "%*.*lu" */
+ format[0] = '%';
+ format[1] = '*';
+ format[2] = '.';
+ format[3] = '*';
+ format[4] = '\0';
+ strcat (format, MPFR_PREC_FORMAT_TYPE);
+ format[4 + MPFR_PREC_FORMAT_SIZE] = spec.spec;
+ format[5 + MPFR_PREC_FORMAT_SIZE] = '\0';
+ length = gmp_asprintf (&s, format, spec.width, spec.prec, prec);
+ if (buf.size <= INT_MAX - length)
+ {
+ buffer_cat (&buf, s, length);
+ mpfr_free_str (s);
+ }
+ else
+ {
+ mpfr_free_str (s);
+ goto overflow_error;
+ }
+ }
+ else if (spec.arg_type == MPFR_ARG)
+ /* output a mpfr_t variable */
+ {
+ mpfr_srcptr p;
+
+ p = va_arg (ap, mpfr_srcptr);
+
+ FLUSH (xgmp_fmt_flag, start, end, ap2, &buf);
+ va_end (ap2);
+ va_copy (ap2, ap);
+ start = fmt;
+
+ switch (spec.spec)
+ {
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ if (sprnt_fp (&buf, p, spec) < 0)
+ goto overflow_error;
+ break;
+
+ default:
+ /* unsupported specifier */
+ goto error;
+ }
+ }
+ else
+ /* gmp_printf specification, step forward in the va_list */
+ {
+ CONSUME_VA_ARG (spec, ap);
+ xgmp_fmt_flag = 1;
+ }
+ }
+
+ if (start != fmt)
+ FLUSH (xgmp_fmt_flag, start, fmt, ap2, &buf);
+
+ va_end (ap2);
+ nbchar = buf.curr - buf.start;
+ MPFR_ASSERTD (nbchar == strlen (buf.start));
+ buf.start =
+ (char *) (*__gmp_reallocate_func) (buf.start, buf.size, nbchar + 1);
+ buf.size = nbchar + 1; /* update needed for __gmp_free_func below when
+ nbchar is too large (overflow_error) */
+ *ptr = buf.start;
+
+ /* If nbchar is larger than INT_MAX, the ISO C99 standard is silent, but
+ POSIX says concerning the snprintf() function:
+ "[EOVERFLOW] The value of n is greater than {INT_MAX} or the
+ number of bytes needed to hold the output excluding the
+ terminating null is greater than {INT_MAX}." See:
+ http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
+ But it doesn't say anything concerning the other printf-like functions.
+ A defect report has been submitted to austin-review-l (item 2532).
+ So, for the time being, we return a negative value and set the erange
+ flag, and set errno to EOVERFLOW in POSIX system. */
+ if (nbchar <= INT_MAX)
+ {
+ MPFR_SAVE_EXPO_FREE (expo);
+ return nbchar;
+ }
+
+ overflow_error:
+ MPFR_SAVE_EXPO_UPDATE_FLAGS(expo, MPFR_FLAGS_ERANGE);
+#ifdef EOVERFLOW
+ errno = EOVERFLOW;
+#endif
+
+ error:
+ MPFR_SAVE_EXPO_FREE (expo);
+ *ptr = NULL;
+ (*__gmp_free_func) (buf.start, buf.size);
+
+ return -1;
+}
+
+#endif /* HAVE_STDARG */
diff --git a/mpfr/src/version.c b/mpfr/src/version.c
new file mode 100644
index 0000000000..1ae4fe241d
--- /dev/null
+++ b/mpfr/src/version.c
@@ -0,0 +1,29 @@
+/* mpfr_get_version -- MPFR version
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+const char *
+mpfr_get_version (void)
+{
+ return "3.1.2";
+}
diff --git a/mpfr/src/volatile.c b/mpfr/src/volatile.c
new file mode 100644
index 0000000000..82c82eeb24
--- /dev/null
+++ b/mpfr/src/volatile.c
@@ -0,0 +1,36 @@
+/* __gmpfr_longdouble_volatile -- support for LONGDOUBLE_NAN_ACTION.
+
+ THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
+ CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
+ FUTURE MPFR RELEASES.
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+/* Only needed sometimes. */
+#ifdef WANT_GMPFR_LONGDOUBLE_VOLATILE
+long double
+__gmpfr_longdouble_volatile (long double x)
+{
+ return x;
+}
+#endif
diff --git a/mpfr/src/x86/core2/mparam.h b/mpfr/src/x86/core2/mparam.h
new file mode 100644
index 0000000000..1f4e77b73c
--- /dev/null
+++ b/mpfr/src/x86/core2/mparam.h
@@ -0,0 +1,234 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2011-07-31, gcc 4.3.2 */
+/* gcc14.fsffrance.org (Intel(R) Xeon(R) CPU X5450 @ 3.00GHz) with gmp 5.0.2
+ configured with ABI=32 */
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,-1,-1,-1,-1,-1,-1,-1,0,-1,-1,0,10,10,0, \
+ 11,11,0,13,13,0,0,17,17,16,19,19,19,18,18,22, \
+ 20,18,19,26,26,28,23,24,28,29,26,28,29,28,30,32, \
+ 29,30,38,30,34,32,33,37,34,36,37,38,38,38,38,38, \
+ 38,44,36,52,44,48,52,56,51,52,56,56,52,52,56,58, \
+ 52,60,60,56,60,55,52,68,60,68,68,68,68,72,72,67, \
+ 68,68,68,76,76,68,75,75,68,72,76,68,68,75,72,72, \
+ 78,73,74,72,76,74,76,72,76,74,76,72,76,76,75,76, \
+ 75,74,76,76,99,99,104,76,76,111,104,102,99,99,99,104, \
+ 93,105,99,104,99,104,99,99,99,96,102,99,104,104,104,108, \
+ 104,105,111,110,110,111,111,111,109,111,110,111,111,114,108,111, \
+ 111,111,105,105,111,108,111,110,111,110,111,111,110,111,110,134, \
+ 111,141,153,153,153,140,141,165,141,153,151,153,153,153,152,152, \
+ 153,165,153,152,153,153,153,163,165,164,165,153,153,164,163,164, \
+ 165,165,153,168,168,173,174,165,176,177,177,164,176,177,165,165, \
+ 165,172,164,165,165,165,168,177,175,176,177,176,165,175,176,176, \
+ 165,177,176,177,204,204,204,204,204,203,177,218,217,220,204,219, \
+ 220,217,220,220,220,218,219,220,220,220,220,217,217,219,220,220, \
+ 217,204,217,219,220,220,217,218,218,219,220,219,220,219,219,220, \
+ 220,220,220,220,219,220,220,220,220,251,220,219,220,220,220,236, \
+ 249,220,251,250,249,249,251,248,251,251,251,250,251,251,251,249, \
+ 248,248,240,250,250,250,249,251,246,251,250,251,251,251,250,250, \
+ 251,249,249,250,251,251,249,251,250,306,305,306,306,306,306,306, \
+ 306,306,306,251,306,306,305,305,306,306,305,305,306,306,306,305, \
+ 330,305,306,305,306,306,306,330,306,306,305,305,330,330,327,330, \
+ 330,330,306,329,330,330,330,330,330,329,330,306,330,330,329,329, \
+ 329,330,329,330,330,330,330,330,330,327,328,329,330,329,329,330, \
+ 330,329,330,330,328,330,330,330,330,330,354,330,329,330,330,354, \
+ 330,329,330,353,354,330,354,354,330,353,354,354,354,354,354,354, \
+ 354,354,353,354,352,354,354,354,330,354,354,353,354,354,354,378, \
+ 353,408,408,408,408,407,408,407,407,408,408,408,408,407,408,408, \
+ 407,407,407,440,407,408,408,407,439,408,408,408,407,408,440,440, \
+ 440,440,440,440,440,439,440,437,439,440,439,439,440,440,439,440, \
+ 439,439,440,439,440,440,440,439,438,439,440,440,439,440,438,439, \
+ 440,440,440,439,440,440,440,440,438,440,439,439,440,440,440,439, \
+ 440,440,440,440,440,440,439,440,440,471,472,471,439,440,439,472, \
+ 472,472,472,472,472,472,440,472,439,440,471,472,471,471,439,472, \
+ 496,496,496,472,440,471,472,480,495,496,496,495,472,534,536,534, \
+ 534,536,536,536,536,536,536,536,536,536,535,536,536,536,536,536, \
+ 534,535,536,536,536,535,534,534,535,536,536,534,535,536,536,535, \
+ 536,536,536,536,535,536,536,536,536,536,535,536,568,535,536,536, \
+ 536,535,536,568,536,536,568,536,568,568,568,536,568,536,536,566, \
+ 567,567,535,568,568,536,535,536,535,536,536,536,567,536,568,536, \
+ 568,567,568,568,567,600,597,568,567,567,568,600,568,568,568,598, \
+ 566,567,568,568,566,568,568,568,567,568,567,568,568,568,568,568, \
+ 600,567,568,600,568,600,568,568,568,568,568,600,599,566,568,600, \
+ 568,568,600,567,568,599,567,600,599,600,568,600,567,599,600,599, \
+ 568,597,600,598,600,599,599,599,600,600,598,600,598,600,597,600, \
+ 600,600,600,600,600,599,600,600,598,599,600,599,600,639,600,600, \
+ 600,600,568,639,600,568,567,568,568,568,600,640,600,599,600,599, \
+ 600,600,600,598,600,599,568,600,598,600,600,599,600,597,639,598, \
+ 600,600,600,600,599,600,600,600,600,600,600,687,736,598,599,600, \
+ 736,600,600,688,736,736,600,688,735,736,736,734,736,736,735,736, \
+ 640,734,735,736,734,733,736,736,731,735,736,736,736,736,736,736, \
+ 736,735,736,736,736,736,784,735,784,735,784,783,783,736,736,735, \
+ 784,784,784,736,783,784,784,784,784,783,783,784,784,784,784,784, \
+ 781,782,782,784,784,784,784,784,784,734,784,783,784,784,784,736, \
+ 808,783,784,784,784,783,784,783,784,783,784,783,784,832,832,829, \
+ 832,824,823,832,824,784,784,824,831,832,784,783,784,783,784,832, \
+ 784,784,784,783,784,784,781,784,784,784,784,783,824,832,831,784, \
+ 832,831,832,830,832,807,784,832,830,784,832,808,832,824,823,832, \
+ 824,808,831,824,824,824,832,823,832,824,832,831,832,832,829,830, \
+ 831,832,832,832,831,831,832,832,830,832,832,832,832,831,831,832, \
+ 879,832,832,880,832,831,832,831,832,832,832,832,832,832,832,831 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,-1,-1,-1,-1,-1,-1,-1,8,8,8,9,9, \
+ 10,10,11,13,13,14,15,16,14,16,17,16,18,17,19,18, \
+ 20,18,19,22,21,22,23,22,23,22,25,24,25,24,25,26, \
+ 27,26,29,27,28,29,30,34,34,36,36,38,38,40,40,42, \
+ 34,44,42,46,38,42,44,38,38,44,40,42,42,50,44,46, \
+ 50,48,48,44,50,52,52,46,50,46,52,50,52,50,50,52, \
+ 52,54,52,52,54,58,58,54,57,58,58,58,56,58,58,58, \
+ 68,58,64,68,72,60,64,72,68,64,72,64,72,68,72,68, \
+ 76,76,72,76,80,76,76,76,84,80,76,88,84,84,84,84, \
+ 88,84,87,88,88,92,92,92,88,96,92,96,96,92,96,96, \
+ 100,100,100,100,96,84,92,92,88,96,92,88,99,92,96,91, \
+ 92,96,100,100,99,100,100,100,100,96,98,96,100,98,100,100, \
+ 100,100,100,117,100,123,123,135,122,123,124,129,126,122,135,123, \
+ 129,135,135,133,134,135,141,140,135,126,140,135,129,129,129,132, \
+ 146,134,129,147,150,135,152,140,135,140,141,141,147,141,147,147, \
+ 147,150,141,147,152,147,141,150,141,151,153,146,147,152,147,147, \
+ 147,152,147,153,151,153,147,147,153,150,147,152,153,150,150,152, \
+ 153,150,153,152,153,150,147,164,150,187,188,148,187,180,152,196, \
+ 187,196,180,186,187,188,196,187,196,188,196,180,195,196,188,188, \
+ 188,196,196,188,192,194,195,196,196,196,195,204,211,212,203,204, \
+ 204,196,196,203,204,220,212,203,196,204,195,204,196,187,216,188, \
+ 200,195,196,204,219,203,195,196,188,203,204,195,203,204,219,195, \
+ 196,211,212,220,196,203,196,212,204,204,220,196,203,220,220,211, \
+ 203,212,212,211,212,212,216,218,220,211,211,218,220,219,220,220, \
+ 220,220,220,220,220,220,219,220,282,282,219,276,276,282,282,275, \
+ 276,282,269,276,258,294,276,282,282,294,294,270,282,294,258,270, \
+ 258,270,294,270,258,270,282,276,306,282,282,282,282,282,276,270, \
+ 282,282,282,281,282,281,281,294,282,276,282,282,282,294,294,282, \
+ 306,306,294,282,294,282,294,294,305,288,306,294,294,294,306,294, \
+ 306,305,318,306,306,318,312,306,306,318,305,306,306,306,317,312, \
+ 311,318,311,312,324,318,317,330,330,318,318,330,323,330,329,330, \
+ 324,330,329,324,342,330,342,329,330,336,341,318,294,329,341,306, \
+ 300,305,300,299,300,305,306,306,324,305,318,318,312,317,330,306, \
+ 306,306,306,306,318,317,318,318,318,324,330,329,324,318,318,318, \
+ 323,324,306,323,324,324,329,328,328,330,330,330,318,318,318,317, \
+ 317,336,330,342,342,341,330,330,330,342,330,340,330,330,318,341, \
+ 342,426,426,341,342,425,426,426,426,342,426,425,426,425,425,426, \
+ 426,426,318,426,425,450,426,425,378,378,378,426,426,450,450,450, \
+ 402,330,449,450,449,450,450,449,450,450,402,450,450,450,450,450, \
+ 426,401,402,450,450,426,426,450,474,472,474,450,426,426,426,474, \
+ 474,474,473,425,426,450,450,426,424,425,426,426,474,449,450,450, \
+ 450,426,474,449,426,450,450,448,449,498,450,498,450,426,450,449, \
+ 448,450,450,448,449,449,474,448,449,450,450,473,474,474,473,449, \
+ 449,474,450,474,450,450,473,474,450,473,474,474,474,474,521,498, \
+ 474,474,474,474,474,474,498,498,474,474,474,473,473,474,474,498, \
+ 498,474,498,498,498,498,498,519,498,522,522,498,498,520,498,498, \
+ 498,498,498,522,522,498,521,521,520,521,522,522,474,522,521,546, \
+ 520,522,546,522,516,546,546,521,522,522,522,521,522,522,521,474, \
+ 545,545,546,546,474,522,522,522,522,474,498,546,522,546,546,544, \
+ 545,545,522,521,546,546,546,522,546,545,522,498,546,546,522,520, \
+ 522,522,522,521,521,545,546,522,521,522,600,568,522,522,521,522, \
+ 600,522,521,521,522,522,519,599,521,522,545,546,522,545,546,545, \
+ 522,599,522,521,546,545,546,546,600,598,600,546,546,545,546,600, \
+ 568,546,600,546,598,600,600,632,632,545,546,599,600,546,546,545, \
+ 546,632,632,600,632,631,632,631,600,600,632,632,598,600,632,599, \
+ 599,599,600,599,599,600,600,600,600,596,600,631,599,600,600,599, \
+ 600,600,600,600,600,600,664,631,632,600,663,664,696,664,600,664, \
+ 663,631,696,662,600,693,696,695,663,696,696,664,631,632,688,630, \
+ 632,632,696,631,695,632,632,695,696,695,695,696,696,696,632,695, \
+ 696,695,696,696,632,695,696,631,664,664,695,663,663,664,696,687, \
+ 662,664,664,663,664,663,694,695,695,727,728,728,693,728,693,695, \
+ 696,696,696,696,696,694,695,696,696,695,696,694,727,696,696,688, \
+ 695,696,696,695,696,695,695,696,696,727,696,696,695,696,695,696, \
+ 696,695,696,695,696,696,696,728,728,696,720,728,728,728,726,728 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,8,9,10,9,10,11,14,13, \
+ 14,11,16,17,13,14,15,16,16,14,16,16,16,19,20,18, \
+ 23,18,22,19,24,25,27,23,23,24,24,23,27,28,27,28, \
+ 28,33,29,30,32,29,37,32,35,33,33,39,33,33,35,38, \
+ 39,38,38,37,38,39,37,37,48,40,39,40,40,50,51,46, \
+ 47,48,48,46,50,50,50,59,52,50,51,48,56,56,54,50, \
+ 51,54,53,58,58,58,56,59,61,58,62,59,62,67,62,67, \
+ 60,64,71,68,64,64,62,68,67,72,66,72,76,72,74,72, \
+ 67,72,72,74,76,70,74,74,76,76,76,76,76,76,74,76, \
+ 76,76,80,87,78,76,88,80,79,88,88,96,94,96,88,103, \
+ 104,104,104,100,103,102,104,104,104,96,104,104,112,112,104,104, \
+ 95,104,104,103,104,104,104,112,104,104,104,103,112,104,104,112, \
+ 104,104,112,104,104,112,104,112,112,112,111,112,120,104,112,116, \
+ 112,120,112,110,120,112,120,112,120,118,116,126,119,120,128,120, \
+ 136,128,120,120,136,120,120,136,152,136,136,136,143,136,128,140, \
+ 128,152,148,152,136,144,152,152,144,152,144,152,152,152,152,152, \
+ 134,152,152,136,136,136,140,152,152,143,152,144,152,152,152,152, \
+ 152,152,144,152,152,152,144,152,152,152,152,152,152,152,152,152, \
+ 152,152,152,152,152,152,150,151,152,152,152,152,156,152,160,160, \
+ 168,156,176,159,160,160,176,160,176,174,176,176,208,176,176,174, \
+ 176,183,176,208,208,176,208,208,208,208,192,208,208,208,208,208, \
+ 208,208,208,200,208,208,208,208,208,208,208,208,208,208,208,208, \
+ 208,208,208,208,208,208,222,208,209,208,208,208,208,208,208,222, \
+ 208,208,208,208,208,208,208,208,208,208,208,208,208,207,208,208, \
+ 208,208,208,208,208,208,208,208,208,222,220,220,222,208,221,216, \
+ 208,220,208,208,208,209,208,208,220,208,208,208,208,208,222,221, \
+ 222,220,220,224,220,216,216,220,216,220,221,222,216,224,224,222, \
+ 222,221,221,222,222,224,222,222,222,222,228,240,232,224,225,225, \
+ 304,228,272,256,231,248,240,234,232,272,288,234,270,256,264,240, \
+ 240,272,256,272,270,271,272,240,303,270,304,304,272,303,304,304, \
+ 304,304,272,270,272,304,288,287,257,303,304,304,288,304,304,272, \
+ 304,304,304,272,304,305,304,303,304,304,303,302,303,304,272,303, \
+ 304,304,304,303,304,304,272,304,304,288,288,304,304,304,305,282, \
+ 304,304,303,304,304,304,304,304,303,304,304,304,302,304,304,305, \
+ 303,302,287,302,304,304,304,305,304,304,302,302,303,303,304,288, \
+ 303,304,304,304,304,302,303,304,304,288,304,303,304,304,304,303, \
+ 304,304,303,303,304,304,304,304,304,304,304,303,304,303,304,304, \
+ 304,303,304,303,304,304,320,303,304,304,304,304,304,304,305,306, \
+ 320,312,320,320,320,320,320,320,320,320,320,320,320,320,352,320, \
+ 352,320,336,320,352,320,319,320,336,336,352,348,348,344,348,348, \
+ 352,348,351,351,351,352,352,354,350,352,352,352,360,353,416,359, \
+ 352,360,416,352,352,370,416,352,353,416,352,416,416,416,352,416, \
+ 352,416,416,416,416,352,408,416,416,384,416,352,416,392,416,416, \
+ 416,401,408,416,416,416,416,416,416,416,416,407,416,408,416,416, \
+ 416,408,408,416,416,416,416,432,416,416,416,436,440,416,416,440, \
+ 440,416,416,416,432,416,440,416,440,438,440,416,440,416,440,438, \
+ 440,444,416,448,416,440,440,440,416,448,448,415,447,440,416,440, \
+ 416,416,408,408,416,416,416,448,416,416,416,416,416,416,416,416, \
+ 416,416,416,416,416,416,440,416,417,416,416,416,416,416,416,416, \
+ 416,416,416,440,416,416,440,416,416,448,416,416,416,416,416,416, \
+ 448,416,416,416,448,416,416,416,416,416,440,416,416,416,432,440, \
+ 416,416,416,416,416,432,416,432,432,440,440,416,416,416,440,440, \
+ 440,448,448,438,440,433,440,439,440,448,440,440,440,439,440,447, \
+ 444,439,440,440,440,440,448,448,448,440,440,448,444,448,443,440, \
+ 440,440,440,440,440,448,448,440,448,439,440,444,447,448,448,448, \
+ 448,448,448,448,448,448,448,447,448,448,448,448,448,448,512,608, \
+ 480,608,464,480,608,456,464,608,608,480,608,480,608,480,480,480, \
+ 608,480,512,480,608,513,512,608,512,512,608,512,608,496,480,496, \
+ 608,516,496,608,480,512,608,512,608,512,512,608,608,608,608,608, \
+ 608,576,608,607,608,608,512,608,607,609,607,608,608,609,608,608, \
+ 609,608,608,608,607,608,607,608,607,608,608,608,608,608,608,607, \
+ 607,608,608,608,608,608,607,607,608,607,608,608,608,607,608,608, \
+ 608,608,609,609,608,608,609,608,608,608,606,606,608,608,609,607, \
+ 606,607,608,608,610,608,608,609,608,608,608,608,608,608,607,608 \
+
+#define MPFR_MUL_THRESHOLD 15 /* limbs */
+#define MPFR_SQR_THRESHOLD 18 /* limbs */
+#define MPFR_DIV_THRESHOLD 22 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 649 /* bits */
+#define MPFR_EXP_THRESHOLD 10653 /* bits */
+#define MPFR_SINCOS_THRESHOLD 36331 /* bits */
+#define MPFR_AI_THRESHOLD1 -21595 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 2333
+#define MPFR_AI_THRESHOLD3 33925
+/* Tuneup completed successfully, took 1155 seconds */
diff --git a/mpfr/src/x86/mparam.h b/mpfr/src/x86/mparam.h
new file mode 100644
index 0000000000..5514690463
--- /dev/null
+++ b/mpfr/src/x86/mparam.h
@@ -0,0 +1,233 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2011-07-31, gcc 4.4.2 */
+/* contributed by Jim Cloos <cloos at jhcloos dot com> with GMP 5.0.2 on a
+ Pentium3-M, where __i386, __i686, __pentiumpro are defined */
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,-1,-1,-1,-1,-1,-1,-1,7,8,9,10,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,28,30,30,30,30,32, \
+ 32,32,34,34,34,32,34,34,34,36,36,36,36,40,40,40, \
+ 42,44,48,48,48,48,48,48,48,48,48,52,52,52,52,52, \
+ 52,52,56,56,60,56,60,60,60,60,60,64,64,64,64,64, \
+ 64,64,64,64,64,64,68,64,64,68,68,68,68,72,72,81, \
+ 81,80,81,81,87,87,87,87,87,87,87,87,87,87,93,87, \
+ 93,93,93,93,93,93,93,93,99,99,93,93,93,92,93,99, \
+ 99,99,99,99,99,99,99,99,105,105,99,105,105,104,105,105, \
+ 105,105,111,117,117,117,117,117,117,117,117,117,117,117,117,117, \
+ 123,123,123,123,141,141,141,141,141,141,141,141,141,141,141,141, \
+ 141,141,141,141,141,141,141,141,141,153,153,153,153,153,153,153, \
+ 153,153,153,153,153,165,165,165,153,165,165,165,165,165,165,165, \
+ 165,165,165,165,165,177,177,165,177,177,177,177,165,177,177,177, \
+ 177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, \
+ 177,177,189,204,189,204,204,204,204,204,204,189,204,189,204,204, \
+ 204,204,204,204,204,204,204,204,203,204,204,204,204,204,204,204, \
+ 220,204,220,220,220,220,220,220,220,220,220,220,220,220,220,220, \
+ 236,220,236,236,236,236,236,235,236,235,236,236,236,236,235,236, \
+ 236,236,236,236,236,236,236,236,236,252,252,252,252,252,252,252, \
+ 252,252,252,252,252,252,252,252,282,282,282,282,282,282,282,282, \
+ 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282, \
+ 282,282,282,282,282,282,282,306,306,282,306,306,306,306,306,306, \
+ 306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306, \
+ 306,306,306,306,306,330,330,330,329,330,330,330,330,330,330,330, \
+ 330,330,330,330,330,330,330,330,330,330,330,330,330,330,354,354, \
+ 354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354, \
+ 354,354,354,354,354,354,354,354,354,378,378,378,378,378,378,378, \
+ 378,377,378,378,378,378,378,378,378,378,378,378,378,378,378,378, \
+ 408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, \
+ 408,408,408,408,408,408,407,408,407,408,408,407,408,408,408,408, \
+ 408,408,439,408,440,440,439,440,440,440,440,439,440,440,439,440, \
+ 439,440,439,440,439,439,440,440,440,440,439,440,439,440,439,440, \
+ 440,440,439,439,440,440,472,440,472,439,440,439,440,440,440,472, \
+ 472,472,469,471,471,472,471,471,472,471,470,470,472,472,471,472, \
+ 472,504,504,463,471,455,438,501,462,497,501,503,459,471,451,467, \
+ 448,501,503,485,504,453,469,470,503,472,496,496,480,467,504,460, \
+ 504,488,488,532,535,497,480,470,504,497,504,492,497,498,536,468, \
+ 504,510,519,528,500,500,495,504,504,504,504,534,504,504,498,504, \
+ 504,511,504,504,504,503,504,563,504,511,504,504,504,504,504,504, \
+ 504,504,533,504,536,536,536,533,536,536,536,536,536,536,536,536, \
+ 536,536,536,536,536,536,536,536,536,536,536,536,536,536,566,536, \
+ 536,536,536,568,568,568,568,568,568,568,568,568,568,568,568,568, \
+ 568,568,568,568,568,568,568,568,568,568,568,568,568,568,592,592, \
+ 592,592,592,592,592,592,592,592,640,592,640,592,640,639,640,640, \
+ 640,640,640,639,640,639,640,640,640,639,640,640,640,640,640,640, \
+ 640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640, \
+ 639,640,639,639,688,688,688,639,640,639,640,640,640,687,688,688, \
+ 688,687,687,688,688,688,688,688,688,688,688,687,688,736,688,688, \
+ 688,687,636,688,688,688,688,688,688,688,688,688,688,688,688,688, \
+ 688,688,688,688,688,688,688,688,688,688,687,688,688,688,688,688, \
+ 688,688,688,688,688,688,688,688,688,688,688,688,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,688,735,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,735,736,735,736,736, \
+ 736,735,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,735,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,784,736,784,784,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 784,736,784,784,784,784,784,784,736,784,736,784,784,784,784,736, \
+ 784,783,784,784,784,784,784,784,784,784,784,784,784,784,784,784, \
+ 784,784,784,784,784,784,784,784,784,784,784,832,784,784,784,784, \
+ 832,784,832,831,832,831,832,832,832,832,832,784,784,784,784,784, \
+ 832,784,832,784,832,832,832,832,832,832,832,832,832,832,832,832 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,-1,-1,-1,-1,5,6,6,7,7,8,8,9,9, \
+ 10,11,12,11,12,13,14,13,14,15,16,15,16,16,17,17, \
+ 18,19,19,19,20,20,21,22,23,22,23,24,25,24,25,26, \
+ 27,26,27,27,28,28,29,29,30,31,32,31,32,32,33,34, \
+ 35,34,35,36,36,38,38,38,39,40,40,40,41,41,41,41, \
+ 42,43,44,44,48,48,48,48,48,50,52,50,52,52,54,54, \
+ 56,56,58,54,54,54,56,56,56,56,58,58,60,60,62,64, \
+ 64,64,62,62,64,64,64,64,64,66,66,68,68,70,68,72, \
+ 70,72,74,72,74,72,72,72,74,74,76,72,72,72,74,74, \
+ 76,76,76,76,78,78,78,80,80,80,80,80,80,80,87,90, \
+ 87,90,90,93,93,90,90,90,90,93,93,93,90,96,96,93, \
+ 96,96,96,96,96,93,99,96,102,99,99,99,96,102,102,102, \
+ 108,102,105,105,105,108,111,111,108,111,111,111,111,111,111,117, \
+ 114,117,114,117,117,120,120,120,120,120,120,120,123,126,126,126, \
+ 126,129,129,129,129,129,132,132,132,135,135,135,141,141,141,141, \
+ 141,141,148,148,148,152,148,152,152,148,152,156,156,156,156,156, \
+ 160,135,141,152,141,141,141,141,141,141,141,141,141,141,141,141, \
+ 141,141,152,141,156,152,156,156,160,160,160,152,160,156,156,156, \
+ 160,160,156,168,160,168,164,164,168,160,168,176,172,168,168,172, \
+ 172,172,176,176,188,176,176,172,188,188,188,188,188,187,188,188, \
+ 188,188,188,188,196,188,196,196,196,196,196,204,204,204,204,204, \
+ 204,204,204,212,212,212,212,212,212,212,212,220,220,220,220,220, \
+ 220,220,220,219,220,220,220,228,220,228,220,220,228,228,220,220, \
+ 220,236,236,228,228,236,228,236,228,244,244,228,244,244,236,236, \
+ 258,236,258,258,258,258,258,258,258,264,258,264,264,264,264,264, \
+ 264,264,264,264,264,258,264,258,264,282,258,264,282,282,282,282, \
+ 282,264,264,282,282,276,264,264,282,294,282,282,282,282,282,282, \
+ 282,282,282,282,282,282,282,282,282,282,282,282,294,282,282,282, \
+ 282,282,282,306,282,282,306,306,282,306,306,306,306,318,306,318, \
+ 318,318,318,318,318,318,318,318,318,318,318,330,330,318,318,318, \
+ 330,318,318,330,330,318,318,318,318,318,318,330,342,330,330,330, \
+ 330,330,330,330,330,330,330,330,330,318,330,318,318,342,342,318, \
+ 342,318,318,342,318,330,330,330,330,330,318,330,330,318,330,318, \
+ 342,330,342,342,342,342,342,342,342,330,342,342,330,342,342,342, \
+ 342,354,342,342,342,342,342,342,342,354,342,342,354,354,354,342, \
+ 354,354,354,354,354,354,354,378,366,366,366,366,378,366,366,366, \
+ 378,408,366,378,378,378,378,378,378,378,378,378,378,424,424,424, \
+ 424,424,424,424,424,408,408,408,408,408,408,408,408,408,408,408, \
+ 408,408,424,424,408,424,408,424,424,408,408,424,424,424,424,424, \
+ 424,424,424,424,424,424,408,424,424,424,424,424,440,424,440,424, \
+ 424,440,424,424,424,424,440,440,440,440,424,424,440,440,424,424, \
+ 424,424,440,424,440,456,456,424,440,440,440,440,456,424,424,424, \
+ 440,440,456,440,472,456,440,440,472,440,456,440,440,440,456,440, \
+ 440,440,456,456,456,472,471,472,456,472,440,472,488,488,455,455, \
+ 456,456,488,456,472,488,504,472,456,504,488,488,456,472,472,471, \
+ 472,502,472,472,496,488,487,503,456,504,504,503,504,456,456,487, \
+ 488,488,504,488,487,504,503,503,504,504,503,503,503,504,502,503, \
+ 502,504,519,501,504,551,502,520,520,488,504,479,517,503,488,463, \
+ 472,456,504,503,487,519,552,534,485,480,486,502,499,552,504,534, \
+ 486,440,504,511,512,533,516,472,536,567,534,494,519,440,542,534, \
+ 528,592,468,536,516,485,472,583,550,509,537,471,493,533,526,446, \
+ 558,498,499,495,487,571,500,544,471,583,545,530,470,566,520,536, \
+ 558,463,504,544,534,494,520,542,522,520,552,520,514,483,434,607, \
+ 566,538,536,552,486,607,623,606,520,453,588,476,614,497,472,504, \
+ 504,566,552,504,504,504,504,504,504,504,504,504,504,552,520,504, \
+ 520,520,520,504,520,520,504,520,536,520,520,536,536,536,536,536, \
+ 536,536,536,586,536,536,520,555,504,565,520,552,536,552,552,552, \
+ 552,552,552,552,552,552,552,552,552,552,552,552,552,552,568,552, \
+ 568,552,568,568,568,568,559,560,568,552,552,568,568,552,568,584, \
+ 552,552,552,552,552,552,568,568,552,568,568,552,568,568,552,552, \
+ 584,568,568,568,568,568,568,568,568,568,552,568,584,584,568,552, \
+ 584,584,584,584,584,584,584,568,568,568,568,616,568,568,616,568, \
+ 600,584,600,600,600,632,616,600,584,616,616,632,632,584,632,616, \
+ 616,616,616,616,616,632,632,616,616,632,632,616,616,632,616,616 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,8,7,10,9,10,11,12,13, \
+ 14,15,16,17,18,16,14,16,16,19,19,18,20,19,20,18, \
+ 24,19,20,23,24,21,21,23,27,24,28,29,28,28,28,28, \
+ 31,31,30,28,34,29,32,32,33,34,35,31,34,38,38,34, \
+ 35,36,38,38,38,40,41,43,39,42,43,42,42,43,44,43, \
+ 45,48,49,48,51,50,50,48,50,48,51,50,51,52,53,50, \
+ 55,51,53,54,56,59,56,59,58,55,57,59,59,63,64,63, \
+ 63,64,64,59,64,64,67,64,63,67,67,71,67,67,71,66, \
+ 75,75,75,75,73,75,73,75,75,75,73,75,84,73,74,73, \
+ 76,76,75,81,76,79,81,84,81,83,84,84,84,84,88,86, \
+ 83,88,96,94,96,96,96,96,96,96,96,95,96,96,96,104, \
+ 96,100,100,104,104,104,96,96,96,104,100,96,102,96,104,104, \
+ 102,104,100,104,112,104,104,112,112,112,104,112,120,112,112,112, \
+ 112,120,110,118,118,118,119,112,120,118,120,112,118,127,128,128, \
+ 128,128,128,128,128,128,128,128,128,128,128,128,128,136,128,136, \
+ 128,128,128,128,128,128,128,128,127,128,128,128,128,128,130,133, \
+ 134,136,136,135,136,136,150,136,136,138,148,140,136,143,148,150, \
+ 150,150,150,148,150,148,148,150,156,149,168,150,160,161,168,168, \
+ 168,168,168,162,168,162,167,168,168,168,168,168,162,174,168,168, \
+ 174,174,184,168,168,176,162,168,192,174,168,168,173,174,186,174, \
+ 174,168,192,174,168,174,168,168,186,192,192,180,174,176,192,192, \
+ 185,192,192,180,192,192,186,192,192,192,192,192,184,192,208,208, \
+ 208,208,190,192,190,192,192,191,186,192,192,208,192,192,192,192, \
+ 192,192,196,204,204,192,204,192,208,192,191,192,208,208,198,208, \
+ 205,220,197,218,222,208,216,199,207,220,206,224,214,204,208,219, \
+ 221,209,227,207,221,216,208,236,222,244,225,208,208,212,224,222, \
+ 229,230,225,221,222,256,227,240,221,224,240,216,240,231,224,263, \
+ 246,232,240,240,240,240,239,240,240,234,234,240,234,238,240,240, \
+ 240,240,256,256,240,256,240,240,240,234,256,240,240,256,234,256, \
+ 256,239,272,244,256,255,256,240,256,240,256,255,240,255,256,256, \
+ 256,254,254,256,244,256,256,256,256,256,256,256,256,253,272,255, \
+ 256,256,252,256,256,256,256,256,256,272,256,256,256,256,257,272, \
+ 272,272,272,272,264,270,272,288,272,280,282,282,280,280,270,282, \
+ 282,282,288,282,288,282,282,300,286,288,300,282,282,288,300,312, \
+ 300,298,306,300,304,304,304,300,300,300,316,306,300,288,306,311, \
+ 324,312,320,300,306,336,320,300,324,320,336,336,336,328,336,324, \
+ 336,336,328,336,322,328,336,336,336,336,312,336,336,336,336,336, \
+ 336,336,336,335,336,344,348,336,353,349,336,336,348,348,346,336, \
+ 352,320,336,336,336,336,352,336,336,336,336,336,336,336,336,336, \
+ 336,336,336,330,336,336,336,336,334,335,336,336,344,344,348,336, \
+ 348,336,352,336,336,348,336,348,336,348,352,351,348,336,336,336, \
+ 352,352,352,348,352,336,336,384,336,336,352,348,336,348,376,352, \
+ 352,372,384,352,384,352,352,352,348,384,348,349,384,351,384,353, \
+ 368,352,350,353,378,372,372,372,384,352,384,352,408,384,378,368, \
+ 383,384,408,356,371,368,372,371,384,376,384,408,384,407,372,384, \
+ 408,369,406,383,377,384,394,382,370,416,408,378,369,372,381,400, \
+ 378,408,376,402,417,408,376,384,382,384,384,408,384,384,384,408, \
+ 384,416,408,408,416,384,384,384,408,384,384,384,396,408,408,408, \
+ 408,408,408,406,408,408,416,416,408,408,408,408,408,416,408,416, \
+ 408,405,416,408,408,440,408,416,416,416,440,408,408,408,440,444, \
+ 408,440,440,408,415,419,440,440,444,443,436,436,440,447,448,440, \
+ 440,416,440,439,440,444,440,444,468,448,440,416,440,416,465,465, \
+ 468,436,468,440,472,439,440,468,472,448,465,468,464,439,440,480, \
+ 480,472,439,468,440,440,468,440,468,468,444,440,448,480,438,440, \
+ 504,439,440,467,480,468,448,465,466,440,468,464,440,472,448,468, \
+ 468,469,456,465,448,460,472,472,468,469,465,480,480,468,472,512, \
+ 468,464,465,469,480,468,504,466,468,480,480,480,468,512,504,469, \
+ 466,466,472,468,480,480,512,469,472,480,480,480,504,477,500,466, \
+ 504,468,480,512,504,512,504,480,480,511,512,510,492,511,503,513, \
+ 503,502,504,512,504,512,504,512,504,512,504,512,513,503,512,504, \
+ 513,504,512,512,510,501,513,503,512,513,498,504,512,510,502,512, \
+ 501,500,552,497,516,511,503,513,497,511,502,509,564,509,504,512, \
+ 503,504,512,504,504,500,512,512,512,511,512,504,557,504,564,564, \
+ 512,564,514,512,516,512,560,564,560,564,564,512,564,564,564,560 \
+
+#define MPFR_MUL_THRESHOLD 15 /* limbs */
+#define MPFR_SQR_THRESHOLD 14 /* limbs */
+#define MPFR_DIV_THRESHOLD 27 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 562 /* bits */
+#define MPFR_EXP_THRESHOLD 9671 /* bits */
+#define MPFR_SINCOS_THRESHOLD 30620 /* bits */
+#define MPFR_AI_THRESHOLD1 -28021 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 2991
+#define MPFR_AI_THRESHOLD3 37474
+/* Tuneup completed successfully, took 6469 seconds */
diff --git a/mpfr/src/x86_64/core2/mparam.h b/mpfr/src/x86_64/core2/mparam.h
new file mode 100644
index 0000000000..0cf85d0c09
--- /dev/null
+++ b/mpfr/src/x86_64/core2/mparam.h
@@ -0,0 +1,236 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2011-07-31, gcc 4.3.2 */
+/* gcc14.fsffrance.org (Intel(R) Xeon(R) CPU X5450 @ 3.00GHz) with gmp 5.0.2 */
+
+/* very similar timings were obtained on 2012-01-25 with gcc 4.1.3
+ on gcc70.fsffrance.org (Intel(R) Xeon(TM) CPU 3.20GHz) with gmp 5.0.2,
+ where GMP defines -mtune=nocona, thus we share the parameters */
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,9, \
+ 10,10,12,12,13,13,13,13,14,16,16,17,18,19,20,24, \
+ 24,24,24,24,26,26,26,26,28,28,28,30,30,32,32,28, \
+ 28,30,30,32,32,32,32,32,32,32,32,34,36,48,38,36, \
+ 40,46,48,48,48,48,48,48,48,48,48,48,48,56,56,56, \
+ 56,48,48,48,56,60,60,60,64,64,56,56,56,60,60,60, \
+ 64,69,64,64,64,69,69,69,69,69,69,69,64,64,75,81, \
+ 81,80,80,80,81,81,81,81,81,81,87,81,87,87,92,93, \
+ 92,87,93,92,87,90,93,92,93,92,90,93,92,93,92,93, \
+ 92,93,93,93,104,93,99,93,99,104,105,104,105,104,105,104, \
+ 111,104,111,110,104,117,117,117,117,117,117,104,105,141,141,140, \
+ 141,141,141,141,141,141,141,141,141,141,141,141,141,140,141,141, \
+ 141,141,141,141,141,141,141,141,140,141,141,141,141,138,140,141, \
+ 141,141,140,141,141,141,141,141,141,141,141,141,165,141,153,141, \
+ 153,165,188,188,188,188,188,188,188,188,188,188,188,188,188,188, \
+ 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, \
+ 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, \
+ 188,188,204,204,188,203,188,188,204,204,188,188,216,220,220,220, \
+ 220,204,204,220,220,220,220,220,220,220,220,220,220,220,220,220, \
+ 220,220,220,235,236,219,220,220,236,236,236,236,236,236,236,236, \
+ 236,236,236,236,236,236,236,282,282,282,282,282,282,282,282,282, \
+ 282,282,282,282,282,282,282,282,282,281,282,280,282,282,282,282, \
+ 282,282,282,282,282,282,282,281,281,282,281,281,282,282,282,282, \
+ 282,282,282,282,282,282,282,282,282,282,282,281,282,280,281,282, \
+ 282,282,282,282,306,282,306,330,330,306,281,330,282,282,330,330, \
+ 330,282,330,329,330,330,330,330,330,330,330,330,330,330,330,330, \
+ 330,330,330,330,330,330,330,330,330,330,354,354,330,330,330,329, \
+ 330,330,330,330,330,330,330,329,330,330,354,354,330,330,330,330, \
+ 330,330,378,330,354,330,354,354,354,354,354,377,378,354,354,354, \
+ 378,354,378,378,354,353,354,378,354,378,378,377,378,378,378,408, \
+ 408,408,378,408,408,408,378,416,408,408,377,378,378,408,408,407, \
+ 408,408,408,408,408,408,408,440,408,440,440,440,439,440,440,440, \
+ 432,439,440,440,440,439,440,440,440,439,440,439,440,439,440,440, \
+ 440,440,440,439,440,440,440,440,440,439,440,440,440,440,439,440, \
+ 440,440,440,439,471,440,440,440,440,440,440,439,440,440,440,440, \
+ 440,440,440,440,440,440,472,440,440,439,440,440,440,439,440,440, \
+ 440,472,439,440,440,440,472,440,471,472,472,472,472,472,472,471, \
+ 471,472,471,472,472,472,504,504,504,504,504,504,504,504,472,471, \
+ 472,472,504,472,471,472,504,504,504,504,504,503,504,504,504,504, \
+ 504,503,504,504,504,504,503,504,504,504,504,504,503,504,504,504, \
+ 504,504,503,504,504,504,504,504,504,504,504,504,504,504,504,504, \
+ 504,504,504,504,544,544,544,544,544,544,544,544,544,544,544,544, \
+ 542,543,544,544,544,544,544,544,544,544,544,544,544,544,544,544, \
+ 543,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, \
+ 544,592,544,544,592,592,544,592,592,591,592,592,632,631,592,592, \
+ 592,592,592,592,592,640,640,640,640,640,616,616,616,616,616,616, \
+ 632,592,616,616,632,630,631,632,632,632,616,632,640,632,632,640, \
+ 640,640,640,640,640,640,639,640,632,632,639,640,640,640,632,632, \
+ 640,639,640,640,632,640,640,640,640,640,640,640,640,640,640,640, \
+ 640,640,640,640,640,640,632,640,640,640,640,640,640,640,640,640, \
+ 640,640,640,640,640,640,640,640,640,640,632,688,640,640,632,632, \
+ 640,640,640,640,639,640,640,640,688,632,687,640,712,688,640,640, \
+ 640,640,640,712,640,640,640,712,736,640,640,640,711,712,736,736, \
+ 640,640,688,712,712,712,712,712,728,736,728,728,736,736,736,736, \
+ 736,736,736,736,734,736,728,736,736,736,728,736,736,736,736,736, \
+ 736,736,736,736,735,712,736,736,736,712,736,736,736,736,736,736, \
+ 736,736,736,712,736,736,712,736,728,712,736,712,736,736,736,736, \
+ 728,712,736,736,735,736,736,736,735,736,736,736,736,735,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,734,736,736, \
+ 736,736,735,736,736,736,735,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,735,736, \
+ 736,736,736,736,736,736,736,736,736,736,736,736,736,736,736,736, \
+ 824,824,832,832,832,832,824,832,832,832,832,832,824,831,832,832 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,0,0,0,0,0,0,5,6,6,7,8,8,8,10,9, \
+ 10,11,11,11,12,13,13,13,14,16,16,17,17,17,17,17, \
+ 18,19,20,21,20,23,24,21,26,23,23,24,24,24,25,28, \
+ 26,28,28,34,32,34,32,32,34,34,32,34,34,34,34,34, \
+ 34,36,40,38,38,36,42,42,40,40,40,40,42,42,42,42, \
+ 46,42,48,48,48,46,52,52,52,52,52,52,56,56,56,56, \
+ 64,56,64,64,64,64,68,56,64,64,64,68,63,64,64,68, \
+ 68,68,68,68,64,68,68,68,72,64,68,68,68,64,67,68, \
+ 68,68,68,68,68,68,72,84,80,72,72,72,72,72,76,76, \
+ 76,76,80,80,76,76,80,84,80,80,80,84,84,84,84,84, \
+ 84,84,84,96,84,84,92,92,96,96,96,99,92,92,92,95, \
+ 96,105,111,105,104,105,104,104,105,105,105,105,104,105,104,105, \
+ 99,114,105,116,117,117,117,123,117,123,116,123,116,111,123,123, \
+ 123,123,123,123,123,117,117,117,123,123,123,117,123,117,123,123, \
+ 123,123,123,123,117,123,123,123,156,123,123,141,123,123,135,135, \
+ 123,148,123,141,141,156,156,129,156,163,156,164,156,156,156,135, \
+ 156,141,155,164,156,156,164,148,148,147,141,164,164,164,164,156, \
+ 164,164,164,164,163,164,164,164,164,164,164,164,164,164,164,164, \
+ 164,156,164,164,156,164,164,164,188,163,164,164,164,164,187,188, \
+ 180,164,204,204,164,188,196,188,188,204,196,180,196,204,188,196, \
+ 220,187,204,220,204,180,220,220,204,204,196,204,220,204,220,220, \
+ 220,220,204,220,220,220,220,220,220,220,220,220,220,220,220,220, \
+ 252,220,220,220,220,220,252,220,252,220,220,220,220,252,252,252, \
+ 252,252,252,252,252,252,252,252,252,252,252,252,267,268,252,252, \
+ 252,250,252,252,252,268,251,252,268,252,268,268,268,252,252,252, \
+ 265,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268, \
+ 268,267,268,268,268,267,268,268,268,267,268,268,268,268,268,268, \
+ 268,268,252,268,252,268,268,268,268,268,268,265,268,268,268,268, \
+ 268,268,268,268,268,268,268,268,268,268,268,268,265,268,268,268, \
+ 252,268,268,266,268,268,268,328,265,282,312,268,268,268,268,268, \
+ 268,268,268,268,268,268,268,311,310,282,282,294,312,282,281,294, \
+ 282,268,312,312,268,311,312,268,268,312,268,312,312,268,312,327, \
+ 268,312,328,268,328,268,328,328,328,312,328,312,327,328,328,312, \
+ 327,328,328,327,325,327,327,359,328,328,327,328,328,328,328,328, \
+ 311,328,360,360,360,360,360,360,360,360,360,360,328,360,360,360, \
+ 328,312,328,360,327,328,328,359,360,328,359,328,312,360,360,327, \
+ 312,408,328,440,328,328,328,328,328,392,328,328,408,408,408,392, \
+ 407,408,408,408,392,407,408,408,407,407,408,408,408,392,408,408, \
+ 407,408,392,408,408,440,406,408,408,408,440,408,408,408,440,440, \
+ 440,440,440,392,440,392,440,440,440,440,440,440,440,440,440,440, \
+ 408,392,440,440,440,438,439,440,440,440,440,440,440,439,440,439, \
+ 440,440,440,504,408,504,408,408,408,472,408,408,407,408,440,439, \
+ 439,440,440,440,440,440,440,440,437,440,440,440,439,504,503,504, \
+ 504,503,504,504,440,502,504,503,503,504,504,503,504,504,504,504, \
+ 504,503,504,504,499,503,502,504,504,536,502,504,504,504,536,504, \
+ 504,504,503,504,504,503,536,504,502,536,503,504,504,504,536,536, \
+ 504,504,504,536,536,535,504,536,535,504,504,504,504,504,504,536, \
+ 536,536,503,536,504,503,536,536,504,535,536,536,504,535,520,536, \
+ 504,504,504,536,535,536,520,536,535,520,536,535,535,536,536,535, \
+ 504,536,536,535,536,535,535,536,536,536,536,536,535,504,536,536, \
+ 536,536,536,536,536,536,536,536,536,535,536,536,536,535,504,536, \
+ 536,536,536,536,504,535,536,536,536,535,535,536,536,536,536,536, \
+ 536,535,536,504,536,535,536,536,536,536,536,504,504,536,504,535, \
+ 536,504,536,535,536,504,504,504,536,536,504,536,504,536,504,536, \
+ 536,504,535,536,632,535,536,536,535,536,536,536,536,536,632,632, \
+ 536,631,536,536,535,536,536,536,536,535,536,536,536,631,632,632, \
+ 536,536,630,535,536,536,600,632,631,600,536,536,536,536,535,632, \
+ 536,598,536,600,536,631,600,568,632,568,568,568,568,568,664,566, \
+ 568,568,632,632,664,568,664,663,632,629,632,535,600,536,536,536, \
+ 632,536,536,599,536,630,536,632,631,632,600,600,600,664,600,664, \
+ 664,632,600,599,664,600,662,663,664,599,598,616,632,625,632,630, \
+ 628,627,630,631,632,663,632,631,632,630,632,631,632,626,632,632, \
+ 632,663,631,631,632,632,632,664,632,632,600,632,632,600,632,632, \
+ 600,600,632,632,632,662,663,663,663,600,664,632,664,663,664,632 \
+
+#define MPFR_DIVHIGH_TAB \
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,13, \
+ 14,15,16,13,14,14,14,15,15,17,17,17,19,19,19,19, \
+ 23,23,19,25,23,25,23,25,25,22,26,28,25,28,25,25, \
+ 28,27,31,27,29,28,33,31,32,33,31,32,33,33,35,35, \
+ 35,39,37,43,39,37,39,41,39,40,39,40,41,45,41,47, \
+ 45,45,47,43,44,45,50,54,49,46,53,47,55,56,52,55, \
+ 52,60,60,52,60,64,62,55,55,62,55,58,56,64,61,59, \
+ 63,63,64,59,60,60,63,64,64,63,64,64,68,68,66,66, \
+ 68,69,71,71,70,71,71,72,78,74,74,71,72,78,78,74, \
+ 76,77,78,79,78,80,79,79,84,83,80,80,82,95,96,83, \
+ 92,92,88,91,92,84,95,95,92,96,94,91,94,92,96,94, \
+ 96,96,96,104,94,94,112,112,104,112,112,112,96,112,112,112, \
+ 112,112,110,104,112,112,112,111,112,108,110,120,112,112,112,112, \
+ 112,112,120,112,120,120,112,120,120,120,120,120,128,120,120,116, \
+ 128,128,124,128,120,128,128,120,120,120,128,120,128,120,124,128, \
+ 128,128,128,127,128,128,126,128,128,128,128,127,136,128,138,137, \
+ 137,135,138,138,138,137,135,138,150,150,138,147,150,138,150,150, \
+ 150,150,160,160,156,150,156,148,150,158,162,160,161,160,150,160, \
+ 160,160,168,156,156,160,168,173,162,156,180,160,160,157,168,160, \
+ 160,160,162,168,168,160,184,162,184,162,160,160,174,160,184,180, \
+ 184,184,180,184,184,186,180,184,184,184,184,184,186,188,188,192, \
+ 185,184,184,186,192,192,192,186,182,192,192,185,184,184,192,208, \
+ 192,184,184,180,192,184,192,186,186,184,192,186,186,191,186,185, \
+ 192,216,192,192,208,192,191,192,192,192,204,192,207,192,216,208, \
+ 208,216,216,197,196,216,216,208,216,222,216,222,208,222,208,222, \
+ 224,208,209,216,216,209,224,207,216,222,224,224,208,223,224,224, \
+ 224,216,222,222,224,224,224,216,224,216,222,221,222,224,224,224, \
+ 224,224,224,232,224,222,224,232,225,233,224,240,224,232,256,240, \
+ 256,256,240,255,240,256,256,240,232,240,232,232,240,232,256,256, \
+ 256,256,256,256,256,256,255,256,256,240,256,240,256,240,254,252, \
+ 256,256,256,256,256,256,256,256,254,256,256,282,276,256,254,256, \
+ 256,255,282,256,255,256,255,256,255,288,256,264,264,256,274,276, \
+ 276,269,273,273,282,269,276,276,276,276,273,282,276,282,276,277, \
+ 280,312,282,281,288,282,276,282,276,276,288,312,276,288,300,276, \
+ 304,276,288,300,304,312,312,312,312,312,306,312,312,312,316,300, \
+ 324,312,320,320,300,312,312,312,312,324,312,330,300,320,312,312, \
+ 316,318,324,324,318,312,312,324,336,336,324,312,312,336,324,320, \
+ 312,336,312,324,336,336,336,368,324,348,312,336,368,312,312,320, \
+ 368,372,368,312,324,376,372,312,368,376,376,372,370,372,318,376, \
+ 320,372,372,368,372,324,376,376,376,376,368,372,376,376,376,376, \
+ 372,372,376,376,376,372,384,376,372,368,384,376,376,370,376,376, \
+ 376,371,372,368,384,336,370,370,376,372,376,376,368,376,376,372, \
+ 376,370,376,368,376,372,376,376,368,376,376,368,368,376,368,368, \
+ 370,370,372,368,372,376,376,376,376,368,370,368,368,372,376,376, \
+ 372,376,368,376,376,376,372,376,376,372,376,376,368,376,372,376, \
+ 372,368,376,370,376,372,376,372,376,376,372,370,376,376,370,372, \
+ 372,373,376,376,384,384,384,376,376,376,376,384,376,376,384,384, \
+ 384,416,384,384,408,384,416,384,384,384,384,408,416,416,416,432, \
+ 408,408,416,408,408,416,408,416,416,416,416,416,416,408,407,440, \
+ 432,408,416,408,416,440,416,408,416,416,432,416,416,440,416,416, \
+ 416,440,432,440,408,448,448,408,408,432,440,432,448,416,416,416, \
+ 440,432,432,416,448,432,465,440,432,440,480,448,416,448,432,432, \
+ 480,432,448,440,466,448,432,440,432,440,440,440,480,430,448,448, \
+ 448,439,440,432,438,447,448,440,440,440,448,448,480,432,448,448, \
+ 448,448,448,447,448,448,448,447,448,448,440,465,448,467,448,448, \
+ 448,448,464,464,448,448,466,480,480,480,468,480,448,464,480,464, \
+ 466,466,464,479,480,480,512,480,540,480,496,480,552,512,480,479, \
+ 504,480,552,552,512,480,504,552,564,512,480,480,504,561,564,564, \
+ 512,552,560,564,564,480,564,480,552,480,564,564,564,564,536,564, \
+ 540,564,552,564,564,564,564,552,564,552,564,480,564,552,552,564, \
+ 512,564,546,564,564,564,512,552,552,559,560,561,564,564,560,560, \
+ 552,561,564,564,560,564,561,564,564,564,564,564,564,564,564,560, \
+ 561,560,564,564,560,564,564,552,564,564,564,552,564,564,564,564, \
+ 564,563,564,564,564,564,560,564,564,564,564,552,564,564,560,564 \
+
+#define MPFR_MUL_THRESHOLD 7 /* limbs */
+#define MPFR_SQR_THRESHOLD 12 /* limbs */
+#define MPFR_DIV_THRESHOLD 20 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 1024 /* bits */
+#define MPFR_EXP_THRESHOLD 9670 /* bits */
+#define MPFR_SINCOS_THRESHOLD 23808 /* bits */
+#define MPFR_AI_THRESHOLD1 -13250 /* threshold for negative input of mpfr_ai */
+#define MPFR_AI_THRESHOLD2 1430
+#define MPFR_AI_THRESHOLD3 21190
+/* Tuneup completed successfully, took 770 seconds */
diff --git a/mpfr/src/x86_64/pentium4/mparam.h b/mpfr/src/x86_64/pentium4/mparam.h
new file mode 100644
index 0000000000..8412940bd1
--- /dev/null
+++ b/mpfr/src/x86_64/pentium4/mparam.h
@@ -0,0 +1,160 @@
+/* Various Thresholds of MPFR, not exported. -*- mode: C -*-
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Generated by MPFR's tuneup.c, 2009-02-09, gcc 4.3 */
+/* crumble.loria.fr with gmp-4.2.4 */
+
+
+#define MPFR_MULHIGH_TAB \
+ -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,19,20,20,24,26,0,0,24,26,28,27,26,28, \
+ 30,32,32,32,30,30,34,34,32,34,34,36,32,34,36,34, \
+ 35,0,0,36,36,0,37,48,0,0,48,48,51,0,48,52, \
+ 51,0,52,52,51,55,52,56,55,0,56,60,59,59,60,64, \
+ 63,63,64,64,67,67,68,72,63,71,72,60,67,67,60,72, \
+ 63,61,64,64,63,71,68,68,71,67,68,68,67,71,68,72, \
+ 68,68,72,72,76,76,69,69,72,72,71,103,104,72,73,96, \
+ 103,94,95,104,96,96,94,103,104,104,96,96,103,103,104,104, \
+ 120,120,103,103,104,104,120,111,103,112,104,104,120,120,109,103, \
+ 119,119,120,120,127,112,128,128,120,120,136,127,128,128,120,126, \
+ 121,129,126,134,135,135,136,120,113,113,114,118,127,127,136,120, \
+ 121,125,126,118,119,119,120,136,121,153,122,122,127,119,120,128, \
+ 165,153,162,134,163,159,136,136,153,153,134,158,135,135,136,136, \
+ 153,153,162,158,159,159,156,152,153,189,158,186,187,163,156,168, \
+ 189,159,165,165,176,176,172,172,183,173,164,174,165,165,176,176, \
+ 177,177,183,188,189,189,180,185,176,186,177,177,193,188,189,189, \
+ 200,200,201,201,177,207,188,198,199,189,200,200,186,201,207,207, \
+ 213,203,189,189,200,210,201,196,212,207,208,213,189,199,200,200, \
+ 203,209,216,204,199,223,206,200,213,225,208,208,203,203,216,204, \
+ 205,205,224,212,213,213,184,208,209,203,198,210,199,187,206,200, \
+ 201,189,208,208,203,185,216,198,187,199,200,212,213,213,202,208, \
+ 203,197,198,198,199,211,212,212,285,213,280,274,227,275,288,204, \
+ 284,284,278,285,307,216,273,308,309,309,275,219,213,311,305,284, \
+ 306,306,307,307,308,308,309,309,303,303,311,311,284,312,285,285, \
+ 307,286,287,308,309,309,303,303,304,332,305,305,306,299,328,300, \
+ 308,301,309,309,303,310,311,311,333,305,285,285,307,314,308,308, \
+ 321,305,354,322,331,355,332,308,309,333,334,334,303,303,304,312, \
+ 305,305,306,306,307,307,308,308,309,309,302,302,375,311,312,360, \
+ 353,305,330,354,307,355,380,308,357,309,358,358,359,311,312,312, \
+ 345,329,378,354,331,355,356,356,357,357,374,334,375,311,336,384, \
+ 356,329,330,357,331,358,404,332,369,333,334,334,335,353,354,354, \
+ 355,382,356,347,357,357,358,358,377,359,405,333,352,379,353,353, \
+ 354,354,355,355,356,356,357,357,358,376,359,377,369,360,379,370, \
+ 380,380,354,372,355,382,383,401,357,357,376,358,377,377,405,378, \
+ 379,379,380,380,381,381,402,402,353,403,404,404,405,405,376,376, \
+ 377,357,368,358,379,379,360,400,401,381,372,452,373,383,454,384, \
+ 405,405,456,356,357,357,358,378,379,379,490,370,381,381,492,402, \
+ 463,403,404,404,405,405,456,456,527,357,448,448,489,449,400,450, \
+ 453,453,454,454,455,455,456,456,468,490,491,491,492,404,405,482, \
+ 472,450,451,462,463,463,464,453,465,465,455,455,456,489,490,490, \
+ 491,491,492,492,405,526,483,527,484,484,452,452,486,453,454,454, \
+ 455,477,456,522,490,490,491,524,481,492,526,482,483,527,495,517, \
+ 521,533,522,474,499,523,524,524,489,489,490,526,527,527,528,528, \
+ 529,529,518,554,495,483,496,472,521,557,486,522,535,535,524,512, \
+ 525,561,526,526,491,527,528,528,529,517,518,554,531,519,544,520, \
+ 521,521,558,546,559,535,560,536,489,573,490,514,491,563,492,492, \
+ 528,489,555,555,491,491,492,596,597,545,546,546,560,599,600,600, \
+ 523,562,563,511,564,525,526,630,553,527,528,528,607,555,595,543, \
+ 544,531,532,571,559,559,599,560,535,535,562,562,563,537,564,564, \
+ 565,630,514,631,528,632,555,542,634,595,557,557,597,558,559,559, \
+ 571,599,530,530,559,545,546,616,561,547,548,534,633,563,564,564, \
+ 607,537,594,636,567,539,624,554,555,555,598,598,557,557,558,572, \
+ 559,559,560,574,603,561,562,632,563,563,578,592,593,607,580,608, \
+ 553,609,624,596,597,597,598,612,627,585,600,614,573,629,616,602, \
+ 599,599,585,585,616,616,587,632,603,603,634,634,635,605,636,621, \
+ 622,607,623,593,609,609,625,610,611,626,612,597,628,598,599,599, \
+ 600,630,631,616,602,632,633,603,634,634,635,635,636,636,607,637, \
+ 668,608,609,609,610,610,611,611,597,657,628,628,629,629,630,630, \
+ 609,625,562,626,627,563,564,628,629,629,630,630,631,599,664,632, \
+ 681,633,634,634,635,635,620,636,621,621,622,622,623,639,672,592, \
+ 609,641,594,594,595,627,596,564,629,597,598,598,631,599,600,600, \
+ 601,681,618,634,603,635,636,636,557,621,622,606,623,623,608,608 \
+
+#define MPFR_SQRHIGH_TAB \
+ -1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,8,8,9,9, \
+ 10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17, \
+ 18,18,19,19,20,20,21,21,22,22,23,23,26,24,25,25, \
+ 26,26,27,27,28,28,29,29,30,30,31,31,32,32,33,33, \
+ 34,34,35,35,36,36,37,38,39,39,39,39,40,40,41,41, \
+ 42,42,43,43,44,44,45,46,46,46,47,47,48,48,49,49, \
+ 50,50,51,51,52,52,53,53,54,54,55,55,56,56,57,57, \
+ 58,58,59,59,60,60,61,61,62,62,63,68,64,64,65,65, \
+ 66,68,67,69,68,68,71,69,70,75,76,76,72,72,73,73, \
+ 74,82,75,80,78,76,77,77,78,83,79,81,82,80,81,81, \
+ 82,82,83,85,84,84,85,85,86,86,87,87,88,88,89,89, \
+ 90,92,91,93,94,92,93,93,94,94,95,95,96,96,97,97, \
+ 98,98,99,99,100,100,101,101,102,102,103,103,104,104,105,105, \
+ 106,106,107,107,108,108,109,112,110,110,111,118,112,112,113,113, \
+ 114,114,115,122,123,116,117,117,118,118,119,119,120,120,121,121, \
+ 122,122,123,123,124,124,125,125,126,126,127,127,128,128,129,129, \
+ 130,154,135,131,132,132,133,133,134,134,135,135,136,140,151,137, \
+ 142,138,139,143,144,154,155,150,151,156,152,143,153,158,145,145, \
+ 165,146,147,147,152,162,149,149,150,150,151,151,152,171,153,153, \
+ 154,154,155,155,156,156,157,157,158,158,159,159,160,160,161,161, \
+ 162,162,163,163,164,164,165,165,166,166,167,167,168,168,169,169, \
+ 170,170,171,171,172,183,173,173,174,174,175,175,176,187,194,182, \
+ 183,178,179,179,180,180,181,181,182,182,183,183,195,184,185,185, \
+ 186,197,187,187,188,188,189,189,190,190,191,191,192,192,193,204, \
+ 207,200,201,208,209,196,197,203,204,198,199,199,200,200,201,201, \
+ 202,215,216,230,217,210,211,218,212,206,207,207,208,208,209,209, \
+ 210,230,231,231,232,225,226,226,227,227,228,242,222,257,217,217, \
+ 218,245,246,219,220,240,241,234,235,235,236,264,230,258,225,225, \
+ 226,226,227,227,228,228,229,260,261,230,231,270,247,232,233,233, \
+ 234,234,235,235,236,236,237,237,238,238,239,239,240,240,241,241, \
+ 242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249, \
+ 250,250,251,251,252,252,253,253,254,254,255,255,256,256,257,257, \
+ 258,258,259,259,260,260,261,261,262,262,263,263,264,264,265,265, \
+ 266,266,267,267,268,268,269,269,270,270,279,271,272,272,273,273, \
+ 274,274,275,275,276,276,277,277,278,278,279,279,280,280,281,281, \
+ 282,282,283,283,284,284,285,285,294,286,287,287,288,288,289,289, \
+ 290,290,291,291,292,292,293,293,294,294,295,295,296,296,297,297, \
+ 298,298,299,299,300,300,301,301,302,302,303,303,304,304,305,305, \
+ 306,306,307,307,308,308,309,309,310,310,311,311,312,312,313,313, \
+ 314,314,315,315,316,316,317,317,318,318,319,319,320,320,321,321, \
+ 322,322,323,323,324,324,325,325,326,326,327,337,349,338,329,329, \
+ 330,330,331,331,332,332,333,333,334,334,335,335,336,336,337,337, \
+ 338,338,339,360,340,340,341,341,342,342,343,343,344,354,355,345, \
+ 346,346,368,368,369,369,359,349,393,382,383,361,362,362,363,363, \
+ 365,365,366,390,367,391,380,404,358,393,406,382,383,395,396,396, \
+ 385,409,386,410,387,399,388,412,413,401,390,367,368,403,404,416, \
+ 417,405,382,406,407,407,408,408,409,409,410,410,435,411,412,412, \
+ 413,413,414,379,439,427,428,392,393,441,442,430,479,455,444,432, \
+ 437,386,451,387,465,439,427,389,390,454,455,455,404,417,444,444, \
+ 394,394,395,446,460,460,461,487,410,475,399,476,477,464,401,465, \
+ 402,492,403,403,404,404,405,405,406,406,407,419,408,408,409,409, \
+ 410,410,411,411,412,412,413,413,414,414,415,415,416,416,417,417, \
+ 418,418,419,419,420,420,421,421,422,422,423,423,424,424,425,508, \
+ 426,426,427,427,428,428,429,429,430,430,431,431,432,432,433,433, \
+ 434,434,435,435,436,436,437,437,438,438,439,536,440,440,441,441, \
+ 442,442,443,443,444,444,445,445,446,446,447,447,448,448,449,476, \
+ 450,450,451,451,452,452,482,453,454,454,455,455,456,456,457,457, \
+ 458,458,459,459,460,460,461,461,462,462,463,463,464,464,465,465, \
+ 466,466,467,467,468,468,469,469,470,470,471,471,472,472,473,473, \
+ 474,474,475,475,476,476,477,477,478,478,479,479,480,480,481,481, \
+ 482,482,483,483,484,484,485,485,486,486,487,487,488,488,489,489, \
+ 490,490,491,491,492,492,493,493,494,494,495,495,496,496,497,497, \
+ 498,498,499,499,500,500,501,501,502,502,503,503,504,504,505,505, \
+ 506,506,507,507,508,508,509,509,510,510,511,511,512,512,513,513 \
+
+#define MPFR_MUL_THRESHOLD 8 /* limbs */
+#define MPFR_EXP_2_THRESHOLD 519 /* bits */
+#define MPFR_EXP_THRESHOLD 6533 /* bits */
diff --git a/mpfr/src/yn.c b/mpfr/src/yn.c
new file mode 100644
index 0000000000..24d3e176e2
--- /dev/null
+++ b/mpfr/src/yn.c
@@ -0,0 +1,426 @@
+/* mpfr_y0, mpfr_y1, mpfr_yn -- Bessel functions of 2nd kind, integer order.
+ http://www.opengroup.org/onlinepubs/009695399/functions/y0.html
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+static int mpfr_yn_asympt (mpfr_ptr, long, mpfr_srcptr, mpfr_rnd_t);
+
+int
+mpfr_y0 (mpfr_ptr res, mpfr_srcptr z, mpfr_rnd_t r)
+{
+ return mpfr_yn (res, 0, z, r);
+}
+
+int
+mpfr_y1 (mpfr_ptr res, mpfr_srcptr z, mpfr_rnd_t r)
+{
+ return mpfr_yn (res, 1, z, r);
+}
+
+/* compute in s an approximation of S1 = sum((n-k)!/k!*y^k,k=0..n)
+ return e >= 0 the exponent difference between the maximal value of |s|
+ during the for loop and the final value of |s|.
+*/
+static mpfr_exp_t
+mpfr_yn_s1 (mpfr_ptr s, mpfr_srcptr y, unsigned long n)
+{
+ unsigned long k;
+ mpz_t f;
+ mpfr_exp_t e, emax;
+
+ mpz_init_set_ui (f, 1);
+ /* we compute n!*S1 = sum(a[k]*y^k,k=0..n) where a[k] = n!*(n-k)!/k!,
+ a[0] = (n!)^2, a[1] = n!*(n-1)!, ..., a[n-1] = n, a[n] = 1 */
+ mpfr_set_ui (s, 1, MPFR_RNDN); /* a[n] */
+ emax = MPFR_EXP(s);
+ for (k = n; k-- > 0;)
+ {
+ /* a[k]/a[k+1] = (n-k)!/k!/(n-(k+1))!*(k+1)! = (k+1)*(n-k) */
+ mpfr_mul (s, s, y, MPFR_RNDN);
+ mpz_mul_ui (f, f, n - k);
+ mpz_mul_ui (f, f, k + 1);
+ /* invariant: f = a[k] */
+ mpfr_add_z (s, s, f, MPFR_RNDN);
+ e = MPFR_EXP(s);
+ if (e > emax)
+ emax = e;
+ }
+ /* now we have f = (n!)^2 */
+ mpz_sqrt (f, f);
+ mpfr_div_z (s, s, f, MPFR_RNDN);
+ mpz_clear (f);
+ return emax - MPFR_EXP(s);
+}
+
+/* compute in s an approximation of
+ S3 = c*sum((h(k)+h(n+k))*y^k/k!/(n+k)!,k=0..infinity)
+ where h(k) = 1 + 1/2 + ... + 1/k
+ k=0: h(n)
+ k=1: 1+h(n+1)
+ k=2: 3/2+h(n+2)
+ Returns e such that the error is bounded by 2^e ulp(s).
+*/
+static mpfr_exp_t
+mpfr_yn_s3 (mpfr_ptr s, mpfr_srcptr y, mpfr_srcptr c, unsigned long n)
+{
+ unsigned long k, zz;
+ mpfr_t t, u;
+ mpz_t p, q; /* p/q will store h(k)+h(n+k) */
+ mpfr_exp_t exps, expU;
+
+ zz = mpfr_get_ui (y, MPFR_RNDU); /* y = z^2/4 */
+ MPFR_ASSERTN (zz < ULONG_MAX - 2);
+ zz += 2; /* z^2 <= 2^zz */
+ mpz_init_set_ui (p, 0);
+ mpz_init_set_ui (q, 1);
+ /* initialize p/q to h(n) */
+ for (k = 1; k <= n; k++)
+ {
+ /* p/q + 1/k = (k*p+q)/(q*k) */
+ mpz_mul_ui (p, p, k);
+ mpz_add (p, p, q);
+ mpz_mul_ui (q, q, k);
+ }
+ mpfr_init2 (t, MPFR_PREC(s));
+ mpfr_init2 (u, MPFR_PREC(s));
+ mpfr_fac_ui (t, n, MPFR_RNDN);
+ mpfr_div (t, c, t, MPFR_RNDN); /* c/n! */
+ mpfr_mul_z (u, t, p, MPFR_RNDN);
+ mpfr_div_z (s, u, q, MPFR_RNDN);
+ exps = MPFR_EXP (s);
+ expU = exps;
+ for (k = 1; ;k ++)
+ {
+ /* update t */
+ mpfr_mul (t, t, y, MPFR_RNDN);
+ mpfr_div_ui (t, t, k, MPFR_RNDN);
+ mpfr_div_ui (t, t, n + k, MPFR_RNDN);
+ /* update p/q:
+ p/q + 1/k + 1/(n+k) = [p*k*(n+k) + q*(n+k) + q*k]/(q*k*(n+k)) */
+ mpz_mul_ui (p, p, k);
+ mpz_mul_ui (p, p, n + k);
+ mpz_addmul_ui (p, q, n + 2 * k);
+ mpz_mul_ui (q, q, k);
+ mpz_mul_ui (q, q, n + k);
+ mpfr_mul_z (u, t, p, MPFR_RNDN);
+ mpfr_div_z (u, u, q, MPFR_RNDN);
+ exps = MPFR_EXP (u);
+ if (exps > expU)
+ expU = exps;
+ mpfr_add (s, s, u, MPFR_RNDN);
+ exps = MPFR_EXP (s);
+ if (exps > expU)
+ expU = exps;
+ if (MPFR_EXP (u) + (mpfr_exp_t) MPFR_PREC (u) < MPFR_EXP (s) &&
+ zz / (2 * k) < k + n)
+ break;
+ }
+ mpfr_clear (t);
+ mpfr_clear (u);
+ mpz_clear (p);
+ mpz_clear (q);
+ exps = expU - MPFR_EXP (s);
+ /* the error is bounded by (6k^2+33/2k+11) 2^exps ulps
+ <= 8*(k+2)^2 2^exps ulps */
+ return 3 + 2 * MPFR_INT_CEIL_LOG2(k + 2) + exps;
+}
+
+int
+mpfr_yn (mpfr_ptr res, long n, mpfr_srcptr z, mpfr_rnd_t r)
+{
+ int inex;
+ unsigned long absn;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC
+ (("n=%ld x[%Pu]=%.*Rg rnd=%d", n, mpfr_get_prec (z), mpfr_log_prec, z, r),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (res), mpfr_log_prec, res, inex));
+
+ absn = SAFE_ABS (unsigned long, n);
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (z)))
+ {
+ if (MPFR_IS_NAN (z))
+ {
+ MPFR_SET_NAN (res); /* y(n,NaN) = NaN */
+ MPFR_RET_NAN;
+ }
+ /* y(n,z) tends to zero when z goes to +Inf, oscillating around
+ 0. We choose to return +0 in that case. */
+ else if (MPFR_IS_INF (z))
+ {
+ if (MPFR_SIGN(z) > 0)
+ return mpfr_set_ui (res, 0, r);
+ else /* y(n,-Inf) = NaN */
+ {
+ MPFR_SET_NAN (res);
+ MPFR_RET_NAN;
+ }
+ }
+ else /* y(n,z) tends to -Inf for n >= 0 or n even, to +Inf otherwise,
+ when z goes to zero */
+ {
+ MPFR_SET_INF(res);
+ if (n >= 0 || ((unsigned long) n & 1) == 0)
+ MPFR_SET_NEG(res);
+ else
+ MPFR_SET_POS(res);
+ mpfr_set_divby0 ();
+ MPFR_RET(0);
+ }
+ }
+
+ /* for z < 0, y(n,z) is imaginary except when j(n,|z|) = 0, which we
+ assume does not happen for a rational z. */
+ if (MPFR_SIGN(z) < 0)
+ {
+ MPFR_SET_NAN (res);
+ MPFR_RET_NAN;
+ }
+
+ /* now z is not singular, and z > 0 */
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Deal with tiny arguments. We have:
+ y0(z) = 2 log(z)/Pi + 2 (euler - log(2))/Pi + O(log(z)*z^2), more
+ precisely for 0 <= z <= 1/2, with g(z) = 2/Pi + 2(euler-log(2))/Pi/log(z),
+ g(z) - 0.41*z^2 < y0(z)/log(z) < g(z)
+ thus since log(z) is negative:
+ g(z)*log(z) < y0(z) < (g(z) - z^2/2)*log(z)
+ and since |g(z)| >= 0.63 for 0 <= z <= 1/2, the relative error on
+ y0(z)/log(z) is bounded by 0.41*z^2/0.63 <= 0.66*z^2.
+ Note: we use both the main term in log(z) and the constant term, because
+ otherwise the relative error would be only in 1/log(|log(z)|).
+ */
+ if (n == 0 && MPFR_EXP(z) < - (mpfr_exp_t) (MPFR_PREC(res) / 2))
+ {
+ mpfr_t l, h, t, logz;
+ mpfr_prec_t prec;
+ int ok, inex2;
+
+ prec = MPFR_PREC(res) + 10;
+ mpfr_init2 (l, prec);
+ mpfr_init2 (h, prec);
+ mpfr_init2 (t, prec);
+ mpfr_init2 (logz, prec);
+ /* first enclose log(z) + euler - log(2) = log(z/2) + euler */
+ mpfr_log (logz, z, MPFR_RNDD); /* lower bound of log(z) */
+ mpfr_set (h, logz, MPFR_RNDU); /* exact */
+ mpfr_nextabove (h); /* upper bound of log(z) */
+ mpfr_const_euler (t, MPFR_RNDD); /* lower bound of euler */
+ mpfr_add (l, logz, t, MPFR_RNDD); /* lower bound of log(z) + euler */
+ mpfr_nextabove (t); /* upper bound of euler */
+ mpfr_add (h, h, t, MPFR_RNDU); /* upper bound of log(z) + euler */
+ mpfr_const_log2 (t, MPFR_RNDU); /* upper bound of log(2) */
+ mpfr_sub (l, l, t, MPFR_RNDD); /* lower bound of log(z/2) + euler */
+ mpfr_nextbelow (t); /* lower bound of log(2) */
+ mpfr_sub (h, h, t, MPFR_RNDU); /* upper bound of log(z/2) + euler */
+ mpfr_const_pi (t, MPFR_RNDU); /* upper bound of Pi */
+ mpfr_div (l, l, t, MPFR_RNDD); /* lower bound of (log(z/2)+euler)/Pi */
+ mpfr_nextbelow (t); /* lower bound of Pi */
+ mpfr_div (h, h, t, MPFR_RNDD); /* upper bound of (log(z/2)+euler)/Pi */
+ mpfr_mul_2ui (l, l, 1, MPFR_RNDD); /* lower bound on g(z)*log(z) */
+ mpfr_mul_2ui (h, h, 1, MPFR_RNDU); /* upper bound on g(z)*log(z) */
+ /* we now have l <= g(z)*log(z) <= h, and we need to add -z^2/2*log(z)
+ to h */
+ mpfr_mul (t, z, z, MPFR_RNDU); /* upper bound on z^2 */
+ /* since logz is negative, a lower bound corresponds to an upper bound
+ for its absolute value */
+ mpfr_neg (t, t, MPFR_RNDD);
+ mpfr_div_2ui (t, t, 1, MPFR_RNDD);
+ mpfr_mul (t, t, logz, MPFR_RNDU); /* upper bound on z^2/2*log(z) */
+ mpfr_add (h, h, t, MPFR_RNDU);
+ inex = mpfr_prec_round (l, MPFR_PREC(res), r);
+ inex2 = mpfr_prec_round (h, MPFR_PREC(res), r);
+ /* we need h=l and inex=inex2 */
+ ok = (inex == inex2) && mpfr_equal_p (l, h);
+ if (ok)
+ mpfr_set (res, h, r); /* exact */
+ mpfr_clear (l);
+ mpfr_clear (h);
+ mpfr_clear (t);
+ mpfr_clear (logz);
+ if (ok)
+ goto end;
+ }
+
+ /* small argument check for y1(z) = -2/Pi/z + O(log(z)):
+ for 0 <= z <= 1, |y1(z) + 2/Pi/z| <= 0.25 */
+ if (n == 1 && MPFR_EXP(z) + 1 < - (mpfr_exp_t) MPFR_PREC(res))
+ {
+ mpfr_t y;
+ mpfr_prec_t prec;
+ mpfr_exp_t err1;
+ int ok;
+ MPFR_BLOCK_DECL (flags);
+
+ /* since 2/Pi > 0.5, and |y1(z)| >= |2/Pi/z|, if z <= 2^(-emax-1),
+ then |y1(z)| > 2^emax */
+ prec = MPFR_PREC(res) + 10;
+ mpfr_init2 (y, prec);
+ mpfr_const_pi (y, MPFR_RNDU); /* Pi*(1+u)^2, where here and below u
+ represents a quantity <= 1/2^prec */
+ mpfr_mul (y, y, z, MPFR_RNDU); /* Pi*z * (1+u)^4, upper bound */
+ MPFR_BLOCK (flags, mpfr_ui_div (y, 2, y, MPFR_RNDZ));
+ /* 2/Pi/z * (1+u)^6, lower bound, with possible overflow */
+ if (MPFR_OVERFLOW (flags))
+ {
+ mpfr_clear (y);
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_overflow (res, r, -1);
+ }
+ mpfr_neg (y, y, MPFR_RNDN);
+ /* (1+u)^6 can be written 1+7u [for another value of u], thus the
+ error on 2/Pi/z is less than 7ulp(y). The truncation error is less
+ than 1/4, thus if ulp(y)>=1/4, the total error is less than 8ulp(y),
+ otherwise it is less than 1/4+7/8 <= 2. */
+ if (MPFR_EXP(y) + 2 >= MPFR_PREC(y)) /* ulp(y) >= 1/4 */
+ err1 = 3;
+ else /* ulp(y) <= 1/8 */
+ err1 = (mpfr_exp_t) MPFR_PREC(y) - MPFR_EXP(y) + 1;
+ ok = MPFR_CAN_ROUND (y, prec - err1, MPFR_PREC(res), r);
+ if (ok)
+ inex = mpfr_set (res, y, r);
+ mpfr_clear (y);
+ if (ok)
+ goto end;
+ }
+
+ /* we can use the asymptotic expansion as soon as z > p log(2)/2,
+ but to get some margin we use it for z > p/2 */
+ if (mpfr_cmp_ui (z, MPFR_PREC(res) / 2 + 3) > 0)
+ {
+ inex = mpfr_yn_asympt (res, n, z, r);
+ if (inex != 0)
+ goto end;
+ }
+
+ /* General case */
+ {
+ mpfr_prec_t prec;
+ mpfr_exp_t err1, err2, err3;
+ mpfr_t y, s1, s2, s3;
+ MPFR_ZIV_DECL (loop);
+
+ mpfr_init (y);
+ mpfr_init (s1);
+ mpfr_init (s2);
+ mpfr_init (s3);
+
+ prec = MPFR_PREC(res) + 2 * MPFR_INT_CEIL_LOG2 (MPFR_PREC (res)) + 13;
+ MPFR_ZIV_INIT (loop, prec);
+ for (;;)
+ {
+ mpfr_set_prec (y, prec);
+ mpfr_set_prec (s1, prec);
+ mpfr_set_prec (s2, prec);
+ mpfr_set_prec (s3, prec);
+
+ mpfr_mul (y, z, z, MPFR_RNDN);
+ mpfr_div_2ui (y, y, 2, MPFR_RNDN); /* z^2/4 */
+
+ /* store (z/2)^n temporarily in s2 */
+ mpfr_pow_ui (s2, z, absn, MPFR_RNDN);
+ mpfr_div_2si (s2, s2, absn, MPFR_RNDN);
+
+ /* compute S1 * (z/2)^(-n) */
+ if (n == 0)
+ {
+ mpfr_set_ui (s1, 0, MPFR_RNDN);
+ err1 = 0;
+ }
+ else
+ err1 = mpfr_yn_s1 (s1, y, absn - 1);
+ mpfr_div (s1, s1, s2, MPFR_RNDN); /* (z/2)^(-n) * S1 */
+ /* See algorithms.tex: the relative error on s1 is bounded by
+ (3n+3)*2^(e+1-prec). */
+ err1 = MPFR_INT_CEIL_LOG2 (3 * absn + 3) + err1 + 1;
+ /* rel_err(s1) <= 2^(err1-prec), thus err(s1) <= 2^err1 ulps */
+
+ /* compute (z/2)^n * S3 */
+ mpfr_neg (y, y, MPFR_RNDN); /* -z^2/4 */
+ err3 = mpfr_yn_s3 (s3, y, s2, absn); /* (z/2)^n * S3 */
+ /* the error on s3 is bounded by 2^err3 ulps */
+
+ /* add s1+s3 */
+ err1 += MPFR_EXP(s1);
+ mpfr_add (s1, s1, s3, MPFR_RNDN);
+ /* the error is bounded by 1/2 + 2^err1*2^(- EXP(s1))
+ + 2^err3*2^(EXP(s3) - EXP(s1)) */
+ err3 += MPFR_EXP(s3);
+ err1 = (err3 > err1) ? err3 + 1 : err1 + 1;
+ err1 -= MPFR_EXP(s1);
+ err1 = (err1 >= 0) ? err1 + 1 : 1;
+ /* now the error on s1 is bounded by 2^err1*ulp(s1) */
+
+ /* compute S2 */
+ mpfr_div_2ui (s2, z, 1, MPFR_RNDN); /* z/2 */
+ mpfr_log (s2, s2, MPFR_RNDN); /* log(z/2) */
+ mpfr_const_euler (s3, MPFR_RNDN);
+ err2 = MPFR_EXP(s2) > MPFR_EXP(s3) ? MPFR_EXP(s2) : MPFR_EXP(s3);
+ mpfr_add (s2, s2, s3, MPFR_RNDN); /* log(z/2) + gamma */
+ err2 -= MPFR_EXP(s2);
+ mpfr_mul_2ui (s2, s2, 1, MPFR_RNDN); /* 2*(log(z/2) + gamma) */
+ mpfr_jn (s3, absn, z, MPFR_RNDN); /* Jn(z) */
+ mpfr_mul (s2, s2, s3, MPFR_RNDN); /* 2*(log(z/2) + gamma)*Jn(z) */
+ err2 += 4; /* the error on s2 is bounded by 2^err2 ulps, see
+ algorithms.tex */
+
+ /* add all three sums */
+ err1 += MPFR_EXP(s1); /* the error on s1 is bounded by 2^err1 */
+ err2 += MPFR_EXP(s2); /* the error on s2 is bounded by 2^err2 */
+ mpfr_sub (s2, s2, s1, MPFR_RNDN); /* s2 - (s1+s3) */
+ err2 = (err1 > err2) ? err1 + 1 : err2 + 1;
+ err2 -= MPFR_EXP(s2);
+ err2 = (err2 >= 0) ? err2 + 1 : 1;
+ /* now the error on s2 is bounded by 2^err2*ulp(s2) */
+ mpfr_const_pi (y, MPFR_RNDN); /* error bounded by 1 ulp */
+ mpfr_div (s2, s2, y, MPFR_RNDN); /* error bounded by
+ 2^(err2+1)*ulp(s2) */
+ err2 ++;
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (s2, prec - err2, MPFR_PREC(res), r)))
+ break;
+ MPFR_ZIV_NEXT (loop, prec);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ /* Assume two's complement for the test n & 1 */
+ inex = mpfr_set4 (res, s2, r, n >= 0 || (n & 1) == 0 ?
+ MPFR_SIGN (s2) : - MPFR_SIGN (s2));
+
+ mpfr_clear (y);
+ mpfr_clear (s1);
+ mpfr_clear (s2);
+ mpfr_clear (s3);
+ }
+
+ end:
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (res, inex, r);
+}
+
+#define MPFR_YN
+#include "jyn_asympt.c"
diff --git a/mpfr/src/zeta.c b/mpfr/src/zeta.c
new file mode 100644
index 0000000000..525e7af049
--- /dev/null
+++ b/mpfr/src/zeta.c
@@ -0,0 +1,466 @@
+/* mpfr_zeta -- compute the Riemann Zeta function
+
+Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/*
+ Parameters:
+ s - the input floating-point number
+ n, p - parameters from the algorithm
+ tc - an array of p floating-point numbers tc[1]..tc[p]
+ Output:
+ b is the result, i.e.
+ sum(tc[i]*product((s+2j)*(s+2j-1)/n^2,j=1..i-1), i=1..p)*s*n^(-s-1)
+*/
+static void
+mpfr_zeta_part_b (mpfr_t b, mpfr_srcptr s, int n, int p, mpfr_t *tc)
+{
+ mpfr_t s1, d, u;
+ unsigned long n2;
+ int l, t;
+ MPFR_GROUP_DECL (group);
+
+ if (p == 0)
+ {
+ MPFR_SET_ZERO (b);
+ MPFR_SET_POS (b);
+ return;
+ }
+
+ n2 = n * n;
+ MPFR_GROUP_INIT_3 (group, MPFR_PREC (b), s1, d, u);
+
+ /* t equals 2p-2, 2p-3, ... ; s1 equals s+t */
+ t = 2 * p - 2;
+ mpfr_set (d, tc[p], MPFR_RNDN);
+ for (l = 1; l < p; l++)
+ {
+ mpfr_add_ui (s1, s, t, MPFR_RNDN); /* s + (2p-2l) */
+ mpfr_mul (d, d, s1, MPFR_RNDN);
+ t = t - 1;
+ mpfr_add_ui (s1, s, t, MPFR_RNDN); /* s + (2p-2l-1) */
+ mpfr_mul (d, d, s1, MPFR_RNDN);
+ t = t - 1;
+ mpfr_div_ui (d, d, n2, MPFR_RNDN);
+ mpfr_add (d, d, tc[p-l], MPFR_RNDN);
+ /* since s is positive and the tc[i] have alternate signs,
+ the following is unlikely */
+ if (MPFR_UNLIKELY (mpfr_cmpabs (d, tc[p-l]) > 0))
+ mpfr_set (d, tc[p-l], MPFR_RNDN);
+ }
+ mpfr_mul (d, d, s, MPFR_RNDN);
+ mpfr_add (s1, s, __gmpfr_one, MPFR_RNDN);
+ mpfr_neg (s1, s1, MPFR_RNDN);
+ mpfr_ui_pow (u, n, s1, MPFR_RNDN);
+ mpfr_mul (b, d, u, MPFR_RNDN);
+
+ MPFR_GROUP_CLEAR (group);
+}
+
+/* Input: p - an integer
+ Output: fills tc[1..p], tc[i] = bernoulli(2i)/(2i)!
+ tc[1]=1/12, tc[2]=-1/720, tc[3]=1/30240, ...
+*/
+static void
+mpfr_zeta_c (int p, mpfr_t *tc)
+{
+ mpfr_t d;
+ int k, l;
+
+ if (p > 0)
+ {
+ mpfr_init2 (d, MPFR_PREC (tc[1]));
+ mpfr_div_ui (tc[1], __gmpfr_one, 12, MPFR_RNDN);
+ for (k = 2; k <= p; k++)
+ {
+ mpfr_set_ui (d, k-1, MPFR_RNDN);
+ mpfr_div_ui (d, d, 12*k+6, MPFR_RNDN);
+ for (l=2; l < k; l++)
+ {
+ mpfr_div_ui (d, d, 4*(2*k-2*l+3)*(2*k-2*l+2), MPFR_RNDN);
+ mpfr_add (d, d, tc[l], MPFR_RNDN);
+ }
+ mpfr_div_ui (tc[k], d, 24, MPFR_RNDN);
+ MPFR_CHANGE_SIGN (tc[k]);
+ }
+ mpfr_clear (d);
+ }
+}
+
+/* Input: s - a floating-point number
+ n - an integer
+ Output: sum - a floating-point number approximating sum(1/i^s, i=1..n-1) */
+static void
+mpfr_zeta_part_a (mpfr_t sum, mpfr_srcptr s, int n)
+{
+ mpfr_t u, s1;
+ int i;
+ MPFR_GROUP_DECL (group);
+
+ MPFR_GROUP_INIT_2 (group, MPFR_PREC (sum), u, s1);
+
+ mpfr_neg (s1, s, MPFR_RNDN);
+ mpfr_ui_pow (u, n, s1, MPFR_RNDN);
+ mpfr_div_2ui (u, u, 1, MPFR_RNDN);
+ mpfr_set (sum, u, MPFR_RNDN);
+ for (i=n-1; i>1; i--)
+ {
+ mpfr_ui_pow (u, i, s1, MPFR_RNDN);
+ mpfr_add (sum, sum, u, MPFR_RNDN);
+ }
+ mpfr_add (sum, sum, __gmpfr_one, MPFR_RNDN);
+
+ MPFR_GROUP_CLEAR (group);
+}
+
+/* Input: s - a floating-point number >= 1/2.
+ rnd_mode - a rounding mode.
+ Assumes s is neither NaN nor Infinite.
+ Output: z - Zeta(s) rounded to the precision of z with direction rnd_mode
+*/
+static int
+mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t b, c, z_pre, f, s1;
+ double beta, sd, dnep;
+ mpfr_t *tc1;
+ mpfr_prec_t precz, precs, d, dint;
+ int p, n, l, add;
+ int inex;
+ MPFR_GROUP_DECL (group);
+ MPFR_ZIV_DECL (loop);
+
+ MPFR_ASSERTD (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0);
+
+ precz = MPFR_PREC (z);
+ precs = MPFR_PREC (s);
+
+ /* Zeta(x) = 1+1/2^x+1/3^x+1/4^x+1/5^x+O(1/6^x)
+ so with 2^(EXP(x)-1) <= x < 2^EXP(x)
+ So for x > 2^3, k^x > k^8, so 2/k^x < 2/k^8
+ Zeta(x) = 1 + 1/2^x*(1+(2/3)^x+(2/4)^x+...)
+ = 1 + 1/2^x*(1+sum((2/k)^x,k=3..infinity))
+ <= 1 + 1/2^x*(1+sum((2/k)^8,k=3..infinity))
+ And sum((2/k)^8,k=3..infinity) = -257+128*Pi^8/4725 ~= 0.0438035
+ So Zeta(x) <= 1 + 1/2^x*2 for x >= 8
+ The error is < 2^(-x+1) <= 2^(-2^(EXP(x)-1)+1) */
+ if (MPFR_GET_EXP (s) > 3)
+ {
+ mpfr_exp_t err;
+ err = MPFR_GET_EXP (s) - 1;
+ if (err > (mpfr_exp_t) (sizeof (mpfr_exp_t)*CHAR_BIT-2))
+ err = MPFR_EMAX_MAX;
+ else
+ err = ((mpfr_exp_t)1) << err;
+ err = 1 - (-err+1); /* GET_EXP(one) - (-err+1) = err :) */
+ MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, err, 0, 1,
+ rnd_mode, {});
+ }
+
+ d = precz + MPFR_INT_CEIL_LOG2(precz) + 10;
+
+ /* we want that s1 = s-1 is exact, i.e. we should have PREC(s1) >= EXP(s) */
+ dint = (mpfr_uexp_t) MPFR_GET_EXP (s);
+ mpfr_init2 (s1, MAX (precs, dint));
+ inex = mpfr_sub (s1, s, __gmpfr_one, MPFR_RNDN);
+ MPFR_ASSERTD (inex == 0);
+
+ /* case s=1 should have already been handled */
+ MPFR_ASSERTD (!MPFR_IS_ZERO (s1));
+
+ MPFR_GROUP_INIT_4 (group, MPFR_PREC_MIN, b, c, z_pre, f);
+
+ MPFR_ZIV_INIT (loop, d);
+ for (;;)
+ {
+ /* Principal loop: we compute, in z_pre,
+ an approximation of Zeta(s), that we send to can_round */
+ if (MPFR_GET_EXP (s1) <= -(mpfr_exp_t) ((mpfr_prec_t) (d-3)/2))
+ /* Branch 1: when s-1 is very small, one
+ uses the approximation Zeta(s)=1/(s-1)+gamma,
+ where gamma is Euler's constant */
+ {
+ dint = MAX (d + 3, precs);
+ MPFR_TRACE (printf ("branch 1\ninternal precision=%lu\n",
+ (unsigned long) dint));
+ MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f);
+ mpfr_div (z_pre, __gmpfr_one, s1, MPFR_RNDN);
+ mpfr_const_euler (f, MPFR_RNDN);
+ mpfr_add (z_pre, z_pre, f, MPFR_RNDN);
+ }
+ else /* Branch 2 */
+ {
+ size_t size;
+
+ MPFR_TRACE (printf ("branch 2\n"));
+ /* Computation of parameters n, p and working precision */
+ dnep = (double) d * LOG2;
+ sd = mpfr_get_d (s, MPFR_RNDN);
+ /* beta = dnep + 0.61 + sd * log (6.2832 / sd);
+ but a larger value is ok */
+#define LOG6dot2832 1.83787940484160805532
+ beta = dnep + 0.61 + sd * (LOG6dot2832 - LOG2 *
+ __gmpfr_floor_log2 (sd));
+ if (beta <= 0.0)
+ {
+ p = 0;
+ /* n = 1 + (int) (exp ((dnep - LOG2) / sd)); */
+ n = 1 + (int) __gmpfr_ceil_exp2 ((d - 1.0) / sd);
+ }
+ else
+ {
+ p = 1 + (int) beta / 2;
+ n = 1 + (int) ((sd + 2.0 * (double) p - 1.0) / 6.2832);
+ }
+ MPFR_TRACE (printf ("\nn=%d\np=%d\n",n,p));
+ /* add = 4 + floor(1.5 * log(d) / log (2)).
+ We should have add >= 10, which is always fulfilled since
+ d = precz + 11 >= 12, thus ceil(log2(d)) >= 4 */
+ add = 4 + (3 * MPFR_INT_CEIL_LOG2 (d)) / 2;
+ MPFR_ASSERTD(add >= 10);
+ dint = d + add;
+ if (dint < precs)
+ dint = precs;
+
+ MPFR_TRACE (printf ("internal precision=%lu\n",
+ (unsigned long) dint));
+
+ size = (p + 1) * sizeof(mpfr_t);
+ tc1 = (mpfr_t*) (*__gmp_allocate_func) (size);
+ for (l=1; l<=p; l++)
+ mpfr_init2 (tc1[l], dint);
+ MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f);
+
+ MPFR_TRACE (printf ("precision of z = %lu\n",
+ (unsigned long) precz));
+
+ /* Computation of the coefficients c_k */
+ mpfr_zeta_c (p, tc1);
+ /* Computation of the 3 parts of the fonction Zeta. */
+ mpfr_zeta_part_a (z_pre, s, n);
+ mpfr_zeta_part_b (b, s, n, p, tc1);
+ /* s1 = s-1 is already computed above */
+ mpfr_div (c, __gmpfr_one, s1, MPFR_RNDN);
+ mpfr_ui_pow (f, n, s1, MPFR_RNDN);
+ mpfr_div (c, c, f, MPFR_RNDN);
+ MPFR_TRACE (MPFR_DUMP (c));
+ mpfr_add (z_pre, z_pre, c, MPFR_RNDN);
+ mpfr_add (z_pre, z_pre, b, MPFR_RNDN);
+ for (l=1; l<=p; l++)
+ mpfr_clear (tc1[l]);
+ (*__gmp_free_func) (tc1, size);
+ /* End branch 2 */
+ }
+
+ MPFR_TRACE (MPFR_DUMP (z_pre));
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, d-3, precz, rnd_mode)))
+ break;
+ MPFR_ZIV_NEXT (loop, d);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ inex = mpfr_set (z, z_pre, rnd_mode);
+
+ MPFR_GROUP_CLEAR (group);
+ mpfr_clear (s1);
+
+ return inex;
+}
+
+int
+mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t z_pre, s1, y, p;
+ double sd, eps, m1, c;
+ long add;
+ mpfr_prec_t precz, prec1, precs, precs1;
+ int inex;
+ MPFR_GROUP_DECL (group);
+ MPFR_ZIV_DECL (loop);
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ MPFR_LOG_FUNC (
+ ("s[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (s), mpfr_log_prec, s, rnd_mode),
+ ("z[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (z), mpfr_log_prec, z, inex));
+
+ /* Zero, Nan or Inf ? */
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (s)))
+ {
+ if (MPFR_IS_NAN (s))
+ {
+ MPFR_SET_NAN (z);
+ MPFR_RET_NAN;
+ }
+ else if (MPFR_IS_INF (s))
+ {
+ if (MPFR_IS_POS (s))
+ return mpfr_set_ui (z, 1, MPFR_RNDN); /* Zeta(+Inf) = 1 */
+ MPFR_SET_NAN (z); /* Zeta(-Inf) = NaN */
+ MPFR_RET_NAN;
+ }
+ else /* s iz zero */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (s));
+ return mpfr_set_si_2exp (z, -1, -1, rnd_mode);
+ }
+ }
+
+ /* s is neither Nan, nor Inf, nor Zero */
+
+ /* check tiny s: we have zeta(s) = -1/2 - 1/2 log(2 Pi) s + ... around s=0,
+ and for |s| <= 0.074, we have |zeta(s) + 1/2| <= |s|.
+ Thus if |s| <= 1/4*ulp(1/2), we can deduce the correct rounding
+ (the 1/4 covers the case where |zeta(s)| < 1/2 and rounding to nearest).
+ A sufficient condition is that EXP(s) + 1 < -PREC(z). */
+ if (MPFR_GET_EXP (s) + 1 < - (mpfr_exp_t) MPFR_PREC(z))
+ {
+ int signs = MPFR_SIGN(s);
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_set_si_2exp (z, -1, -1, rnd_mode); /* -1/2 */
+ if (rnd_mode == MPFR_RNDA)
+ rnd_mode = MPFR_RNDD; /* the result is around -1/2, thus negative */
+ if ((rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDZ) && signs < 0)
+ {
+ mpfr_nextabove (z); /* z = -1/2 + epsilon */
+ inex = 1;
+ }
+ else if (rnd_mode == MPFR_RNDD && signs > 0)
+ {
+ mpfr_nextbelow (z); /* z = -1/2 - epsilon */
+ inex = -1;
+ }
+ else
+ {
+ if (rnd_mode == MPFR_RNDU) /* s > 0: z = -1/2 */
+ inex = 1;
+ else if (rnd_mode == MPFR_RNDD)
+ inex = -1; /* s < 0: z = -1/2 */
+ else /* (MPFR_RNDZ and s > 0) or MPFR_RNDN: z = -1/2 */
+ inex = (signs > 0) ? 1 : -1;
+ }
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (z, inex, rnd_mode);
+ }
+
+ /* Check for case s= -2n */
+ if (MPFR_IS_NEG (s))
+ {
+ mpfr_t tmp;
+ tmp[0] = *s;
+ MPFR_EXP (tmp) = MPFR_GET_EXP (s) - 1;
+ if (mpfr_integer_p (tmp))
+ {
+ MPFR_SET_ZERO (z);
+ MPFR_SET_POS (z);
+ MPFR_RET (0);
+ }
+ }
+
+ /* Check for case s= 1 before changing the exponent range */
+ if (mpfr_cmp (s, __gmpfr_one) ==0)
+ {
+ MPFR_SET_INF (z);
+ MPFR_SET_POS (z);
+ mpfr_set_divby0 ();
+ MPFR_RET (0);
+ }
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+ /* Compute Zeta */
+ if (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0) /* Case s >= 1/2 */
+ inex = mpfr_zeta_pos (z, s, rnd_mode);
+ else /* use reflection formula
+ zeta(s) = 2^s*Pi^(s-1)*sin(Pi*s/2)*gamma(1-s)*zeta(1-s) */
+ {
+ int overflow = 0;
+
+ precz = MPFR_PREC (z);
+ precs = MPFR_PREC (s);
+
+ /* Precision precs1 needed to represent 1 - s, and s + 2,
+ without any truncation */
+ precs1 = precs + 2 + MAX (0, - MPFR_GET_EXP (s));
+ sd = mpfr_get_d (s, MPFR_RNDN) - 1.0;
+ if (sd < 0.0)
+ sd = -sd; /* now sd = abs(s-1.0) */
+ /* Precision prec1 is the precision on elementary computations;
+ it ensures a final precision prec1 - add for zeta(s) */
+ /* eps = pow (2.0, - (double) precz - 14.0); */
+ eps = __gmpfr_ceil_exp2 (- (double) precz - 14.0);
+ m1 = 1.0 + MAX(1.0 / eps, 2.0 * sd) * (1.0 + eps);
+ c = (1.0 + eps) * (1.0 + eps * MAX(8.0, m1));
+ /* add = 1 + floor(log(c*c*c*(13 + m1))/log(2)); */
+ add = __gmpfr_ceil_log2 (c * c * c * (13.0 + m1));
+ prec1 = precz + add;
+ prec1 = MAX (prec1, precs1) + 10;
+
+ MPFR_GROUP_INIT_4 (group, prec1, z_pre, s1, y, p);
+ MPFR_ZIV_INIT (loop, prec1);
+ for (;;)
+ {
+ mpfr_sub (s1, __gmpfr_one, s, MPFR_RNDN);/* s1 = 1-s */
+ mpfr_zeta_pos (z_pre, s1, MPFR_RNDN); /* zeta(1-s) */
+ mpfr_gamma (y, s1, MPFR_RNDN); /* gamma(1-s) */
+ if (MPFR_IS_INF (y)) /* Zeta(s) < 0 for -4k-2 < s < -4k,
+ Zeta(s) > 0 for -4k < s < -4k+2 */
+ {
+ mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
+ mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
+ overflow = (mpfr_cmp_si_2exp (s1, -1, -1) > 0) ? -1 : 1;
+ break;
+ }
+ mpfr_mul (z_pre, z_pre, y, MPFR_RNDN); /* gamma(1-s)*zeta(1-s) */
+ mpfr_const_pi (p, MPFR_RNDD);
+ mpfr_mul (y, s, p, MPFR_RNDN);
+ mpfr_div_2ui (y, y, 1, MPFR_RNDN); /* s*Pi/2 */
+ mpfr_sin (y, y, MPFR_RNDN); /* sin(Pi*s/2) */
+ mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
+ mpfr_mul_2ui (y, p, 1, MPFR_RNDN); /* 2*Pi */
+ mpfr_neg (s1, s1, MPFR_RNDN); /* s-1 */
+ mpfr_pow (y, y, s1, MPFR_RNDN); /* (2*Pi)^(s-1) */
+ mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
+ mpfr_mul_2ui (z_pre, z_pre, 1, MPFR_RNDN);
+
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, prec1 - add, precz,
+ rnd_mode)))
+ break;
+
+ MPFR_ZIV_NEXT (loop, prec1);
+ MPFR_GROUP_REPREC_4 (group, prec1, z_pre, s1, y, p);
+ }
+ MPFR_ZIV_FREE (loop);
+ if (overflow != 0)
+ {
+ inex = mpfr_overflow (z, rnd_mode, overflow);
+ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
+ }
+ else
+ inex = mpfr_set (z, z_pre, rnd_mode);
+ MPFR_GROUP_CLEAR (group);
+ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (z, inex, rnd_mode);
+}
diff --git a/mpfr/src/zeta_ui.c b/mpfr/src/zeta_ui.c
new file mode 100644
index 0000000000..08f9f1d16f
--- /dev/null
+++ b/mpfr/src/zeta_ui.c
@@ -0,0 +1,230 @@
+/* mpfr_zeta_ui -- compute the Riemann Zeta function for integer argument.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+int
+mpfr_zeta_ui (mpfr_ptr z, unsigned long m, mpfr_rnd_t r)
+{
+ MPFR_ZIV_DECL (loop);
+
+ if (m == 0)
+ {
+ mpfr_set_ui (z, 1, r);
+ mpfr_div_2ui (z, z, 1, r);
+ MPFR_CHANGE_SIGN (z);
+ MPFR_RET (0);
+ }
+ else if (m == 1)
+ {
+ MPFR_SET_INF (z);
+ MPFR_SET_POS (z);
+ mpfr_set_divby0 ();
+ return 0;
+ }
+ else /* m >= 2 */
+ {
+ mpfr_prec_t p = MPFR_PREC(z);
+ unsigned long n, k, err, kbits;
+ mpz_t d, t, s, q;
+ mpfr_t y;
+ int inex;
+
+ if (r == MPFR_RNDA)
+ r = MPFR_RNDU; /* since the result is always positive */
+
+ if (m >= p) /* 2^(-m) < ulp(1) = 2^(1-p). This means that
+ 2^(-m) <= 1/2*ulp(1). We have 3^(-m)+4^(-m)+... < 2^(-m)
+ i.e. zeta(m) < 1+2*2^(-m) for m >= 3 */
+
+ {
+ if (m == 2) /* necessarily p=2 */
+ return mpfr_set_ui_2exp (z, 13, -3, r);
+ else if (r == MPFR_RNDZ || r == MPFR_RNDD || (r == MPFR_RNDN && m > p))
+ {
+ mpfr_set_ui (z, 1, r);
+ return -1;
+ }
+ else
+ {
+ mpfr_set_ui (z, 1, r);
+ mpfr_nextabove (z);
+ return 1;
+ }
+ }
+
+ /* now treat also the case where zeta(m) - (1+1/2^m) < 1/2*ulp(1),
+ and the result is either 1+2^(-m) or 1+2^(-m)+2^(1-p). */
+ mpfr_init2 (y, 31);
+
+ if (m >= p / 2) /* otherwise 4^(-m) > 2^(-p) */
+ {
+ /* the following is a lower bound for log(3)/log(2) */
+ mpfr_set_str_binary (y, "1.100101011100000000011010001110");
+ mpfr_mul_ui (y, y, m, MPFR_RNDZ); /* lower bound for log2(3^m) */
+ if (mpfr_cmp_ui (y, p + 2) >= 0)
+ {
+ mpfr_clear (y);
+ mpfr_set_ui (z, 1, MPFR_RNDZ);
+ mpfr_div_2ui (z, z, m, MPFR_RNDZ);
+ mpfr_add_ui (z, z, 1, MPFR_RNDZ);
+ if (r != MPFR_RNDU)
+ return -1;
+ mpfr_nextabove (z);
+ return 1;
+ }
+ }
+
+ mpz_init (s);
+ mpz_init (d);
+ mpz_init (t);
+ mpz_init (q);
+
+ p += MPFR_INT_CEIL_LOG2(p); /* account of the n term in the error */
+
+ p += MPFR_INT_CEIL_LOG2(p) + 15; /* initial value */
+
+ MPFR_ZIV_INIT (loop, p);
+ for(;;)
+ {
+ /* 0.39321985067869744 = log(2)/log(3+sqrt(8)) */
+ n = 1 + (unsigned long) (0.39321985067869744 * (double) p);
+ err = n + 4;
+
+ mpfr_set_prec (y, p);
+
+ /* computation of the d[k] */
+ mpz_set_ui (s, 0);
+ mpz_set_ui (t, 1);
+ mpz_mul_2exp (t, t, 2 * n - 1); /* t[n] */
+ mpz_set (d, t);
+ for (k = n; k > 0; k--)
+ {
+ count_leading_zeros (kbits, k);
+ kbits = GMP_NUMB_BITS - kbits;
+ /* if k^m is too large, use mpz_tdiv_q */
+ if (m * kbits > 2 * GMP_NUMB_BITS)
+ {
+ /* if we know in advance that k^m > d, then floor(d/k^m) will
+ be zero below, so there is no need to compute k^m */
+ kbits = (kbits - 1) * m + 1;
+ /* k^m has at least kbits bits */
+ if (kbits > mpz_sizeinbase (d, 2))
+ mpz_set_ui (q, 0);
+ else
+ {
+ mpz_ui_pow_ui (q, k, m);
+ mpz_tdiv_q (q, d, q);
+ }
+ }
+ else /* use several mpz_tdiv_q_ui calls */
+ {
+ unsigned long km = k, mm = m - 1;
+ while (mm > 0 && km < ULONG_MAX / k)
+ {
+ km *= k;
+ mm --;
+ }
+ mpz_tdiv_q_ui (q, d, km);
+ while (mm > 0)
+ {
+ km = k;
+ mm --;
+ while (mm > 0 && km < ULONG_MAX / k)
+ {
+ km *= k;
+ mm --;
+ }
+ mpz_tdiv_q_ui (q, q, km);
+ }
+ }
+ if (k % 2)
+ mpz_add (s, s, q);
+ else
+ mpz_sub (s, s, q);
+
+ /* we have d[k] = sum(t[i], i=k+1..n)
+ with t[i] = n*(n+i-1)!*4^i/(n-i)!/(2i)!
+ t[k-1]/t[k] = k*(2k-1)/(n-k+1)/(n+k-1)/2 */
+#if (GMP_NUMB_BITS == 32)
+#define KMAX 46341 /* max k such that k*(2k-1) < 2^32 */
+#elif (GMP_NUMB_BITS == 64)
+#define KMAX 3037000500
+#endif
+#ifdef KMAX
+ if (k <= KMAX)
+ mpz_mul_ui (t, t, k * (2 * k - 1));
+ else
+#endif
+ {
+ mpz_mul_ui (t, t, k);
+ mpz_mul_ui (t, t, 2 * k - 1);
+ }
+ mpz_fdiv_q_2exp (t, t, 1);
+ /* Warning: the test below assumes that an unsigned long
+ has no padding bits. */
+ if (n < 1UL << ((sizeof(unsigned long) * CHAR_BIT) / 2))
+ /* (n - k + 1) * (n + k - 1) < n^2 */
+ mpz_divexact_ui (t, t, (n - k + 1) * (n + k - 1));
+ else
+ {
+ mpz_divexact_ui (t, t, n - k + 1);
+ mpz_divexact_ui (t, t, n + k - 1);
+ }
+ mpz_add (d, d, t);
+ }
+
+ /* multiply by 1/(1-2^(1-m)) = 1 + 2^(1-m) + 2^(2-m) + ... */
+ mpz_fdiv_q_2exp (t, s, m - 1);
+ do
+ {
+ err ++;
+ mpz_add (s, s, t);
+ mpz_fdiv_q_2exp (t, t, m - 1);
+ }
+ while (mpz_cmp_ui (t, 0) > 0);
+
+ /* divide by d[n] */
+ mpz_mul_2exp (s, s, p);
+ mpz_tdiv_q (s, s, d);
+ mpfr_set_z (y, s, MPFR_RNDN);
+ mpfr_div_2ui (y, y, p, MPFR_RNDN);
+
+ err = MPFR_INT_CEIL_LOG2 (err);
+
+ if (MPFR_LIKELY(MPFR_CAN_ROUND (y, p - err, MPFR_PREC(z), r)))
+ break;
+
+ MPFR_ZIV_NEXT (loop, p);
+ }
+ MPFR_ZIV_FREE (loop);
+
+ mpz_clear (d);
+ mpz_clear (t);
+ mpz_clear (q);
+ mpz_clear (s);
+ inex = mpfr_set (z, y, r);
+ mpfr_clear (y);
+ return inex;
+ }
+}
diff --git a/mpfr/tests/Makefile.am b/mpfr/tests/Makefile.am
new file mode 100644
index 0000000000..2c64f9b9a6
--- /dev/null
+++ b/mpfr/tests/Makefile.am
@@ -0,0 +1,90 @@
+# Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+
+
+AUTOMAKE_OPTIONS = 1.6 gnu
+
+# tversion is run
+# * at the beginning so that the user gets a possible version error
+# before any other one (the version error may be the cause of the
+# other errors), and
+# * at the end so that the error message is also near the end of the
+# output.
+check_PROGRAMS = tversion tinternals tinits tisqrt tsgn tcheck \
+ tisnan texceptions tset_exp tset mpf_compat mpfr_compat \
+ reuse tabs tacos tacosh tadd tadd1sp tadd_d tadd_ui tagm \
+ tai tasin tasinh tatan tatanh taway tbuildopt tcan_round \
+ tcbrt tcmp tcmp2 tcmp_d tcmp_ld tcmp_ui tcmpabs \
+ tcomparisons tconst_catalan tconst_euler tconst_log2 \
+ tconst_pi tcopysign tcos tcosh tcot tcoth tcsc tcsch \
+ td_div td_sub tdigamma tdim tdiv tdiv_d tdiv_ui teint teq \
+ terf texp texp10 texp2 texpm1 tfactorial tfits tfma tfmod \
+ tfms tfprintf tfrac tfrexp tgamma tget_flt tget_d tget_d_2exp \
+ tget_f tget_ld_2exp tget_set_d64 tget_sj tget_str tget_z \
+ tgmpop tgrandom thyperbolic thypot tinp_str tj0 tj1 tjn tl2b \
+ tlgamma tli2 tlngamma tlog tlog10 tlog1p tlog2 tmin_prec \
+ tminmax tmodf tmul tmul_2exp tmul_d tmul_ui tnext \
+ tout_str toutimpl tpow tpow3 tpow_all tpow_z tprintf \
+ trandom trec_sqrt tremquo trint troot tround_prec tsec \
+ tsech tset_d tset_f tset_ld tset_q tset_si tset_sj \
+ tset_str tset_z tset_z_exp tsi_op tsin tsin_cos tsinh \
+ tsinh_cosh tsprintf tsqr tsqrt tsqrt_ui tstckintc tstdint tstrtofr \
+ tsub tsub1sp tsub_d tsub_ui tsubnormal tsum tswap ttan \
+ ttanh ttrunc tui_div tui_pow tui_sub turandom \
+ tvalist ty0 ty1 tyn tzeta tzeta_ui tversion
+
+AM_CPPFLAGS = -DSRCDIR='"$(srcdir)"'
+
+EXTRA_DIST = tgeneric.c tgeneric_ui.c mpf_compat.h inp_str.data tmul.dat
+
+LDADD = libfrtests.la $(MPFR_LIBM) $(top_builddir)/src/libmpfr.la
+INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src
+
+# LOADLIBES (documented in the "GNU make" manual and equivalent to LDLIBS)
+# enables to compile a program foo.c in the test directory by simply doing
+# "make foo".
+# Warning! This is not guaranteed to work, as libtool is not used. In
+# particular, this may not work as expected under GNU/Linux if --with-gmp
+# has been used, unless the directory is in your $LD_LIBRARY_PATH.
+# Moreover, dependencies are not tracked. Thus you may want to run
+# "make tversion" (for instance) just before, to make sure that every
+# dependency has been rebuilt.
+LOADLIBES=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(top_builddir)/tests/.libs/libfrtests.a $(top_builddir)/src/.libs/libmpfr.a $(LIBS) $(MPFR_LIBM)
+
+check_LTLIBRARIES = libfrtests.la
+libfrtests_la_SOURCES = mpfr-test.h memory.c rnd_mode.c tests.c cmp_str.c random2.c
+
+$(top_builddir)/src/libmpfr.la:
+ cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libmpfr.la
+
+TESTS = $(check_PROGRAMS)
+TESTS_ENVIRONMENT = MPFR_QUIET=1 $(VALGRIND)
+
+# The -no-install option prevents libtool from generating wrapper scripts
+# for the tests.
+# This is useful to easily run the test scripts under valgrind or gdb.
+# See discussion http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28033
+# http://article.gmane.org/gmane.comp.lib.gnulib.bugs/28140 in particular.
+#
+# The -L$(top_builddir)/src/.libs option is necessary for some platforms,
+# such as HP-UX, when --with-gmp or --with-gmp-lib is used and an old MPFR
+# library is already installed in the corresponding lib directory: its
+# purpose is to make sure that the local .libs comes first in the library
+# search path (otherwise the tests are linked against the old MPFR library
+# by the LINK command -- see the generated Makefile). See:
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00042.html
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00043.html
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00044.html
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00066.html
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00065.html
+# and
+# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9728
+#
+AM_LDFLAGS = -no-install -L$(top_builddir)/src/.libs
diff --git a/mpfr/tests/Makefile.in b/mpfr/tests/Makefile.in
new file mode 100644
index 0000000000..6322b37a88
--- /dev/null
+++ b/mpfr/tests/Makefile.in
@@ -0,0 +1,2208 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+check_PROGRAMS = tversion$(EXEEXT) tinternals$(EXEEXT) tinits$(EXEEXT) \
+ tisqrt$(EXEEXT) tsgn$(EXEEXT) tcheck$(EXEEXT) tisnan$(EXEEXT) \
+ texceptions$(EXEEXT) tset_exp$(EXEEXT) tset$(EXEEXT) \
+ mpf_compat$(EXEEXT) mpfr_compat$(EXEEXT) reuse$(EXEEXT) \
+ tabs$(EXEEXT) tacos$(EXEEXT) tacosh$(EXEEXT) tadd$(EXEEXT) \
+ tadd1sp$(EXEEXT) tadd_d$(EXEEXT) tadd_ui$(EXEEXT) \
+ tagm$(EXEEXT) tai$(EXEEXT) tasin$(EXEEXT) tasinh$(EXEEXT) \
+ tatan$(EXEEXT) tatanh$(EXEEXT) taway$(EXEEXT) \
+ tbuildopt$(EXEEXT) tcan_round$(EXEEXT) tcbrt$(EXEEXT) \
+ tcmp$(EXEEXT) tcmp2$(EXEEXT) tcmp_d$(EXEEXT) tcmp_ld$(EXEEXT) \
+ tcmp_ui$(EXEEXT) tcmpabs$(EXEEXT) tcomparisons$(EXEEXT) \
+ tconst_catalan$(EXEEXT) tconst_euler$(EXEEXT) \
+ tconst_log2$(EXEEXT) tconst_pi$(EXEEXT) tcopysign$(EXEEXT) \
+ tcos$(EXEEXT) tcosh$(EXEEXT) tcot$(EXEEXT) tcoth$(EXEEXT) \
+ tcsc$(EXEEXT) tcsch$(EXEEXT) td_div$(EXEEXT) td_sub$(EXEEXT) \
+ tdigamma$(EXEEXT) tdim$(EXEEXT) tdiv$(EXEEXT) tdiv_d$(EXEEXT) \
+ tdiv_ui$(EXEEXT) teint$(EXEEXT) teq$(EXEEXT) terf$(EXEEXT) \
+ texp$(EXEEXT) texp10$(EXEEXT) texp2$(EXEEXT) texpm1$(EXEEXT) \
+ tfactorial$(EXEEXT) tfits$(EXEEXT) tfma$(EXEEXT) \
+ tfmod$(EXEEXT) tfms$(EXEEXT) tfprintf$(EXEEXT) tfrac$(EXEEXT) \
+ tfrexp$(EXEEXT) tgamma$(EXEEXT) tget_flt$(EXEEXT) \
+ tget_d$(EXEEXT) tget_d_2exp$(EXEEXT) tget_f$(EXEEXT) \
+ tget_ld_2exp$(EXEEXT) tget_set_d64$(EXEEXT) tget_sj$(EXEEXT) \
+ tget_str$(EXEEXT) tget_z$(EXEEXT) tgmpop$(EXEEXT) \
+ tgrandom$(EXEEXT) thyperbolic$(EXEEXT) thypot$(EXEEXT) \
+ tinp_str$(EXEEXT) tj0$(EXEEXT) tj1$(EXEEXT) tjn$(EXEEXT) \
+ tl2b$(EXEEXT) tlgamma$(EXEEXT) tli2$(EXEEXT) tlngamma$(EXEEXT) \
+ tlog$(EXEEXT) tlog10$(EXEEXT) tlog1p$(EXEEXT) tlog2$(EXEEXT) \
+ tmin_prec$(EXEEXT) tminmax$(EXEEXT) tmodf$(EXEEXT) \
+ tmul$(EXEEXT) tmul_2exp$(EXEEXT) tmul_d$(EXEEXT) \
+ tmul_ui$(EXEEXT) tnext$(EXEEXT) tout_str$(EXEEXT) \
+ toutimpl$(EXEEXT) tpow$(EXEEXT) tpow3$(EXEEXT) \
+ tpow_all$(EXEEXT) tpow_z$(EXEEXT) tprintf$(EXEEXT) \
+ trandom$(EXEEXT) trec_sqrt$(EXEEXT) tremquo$(EXEEXT) \
+ trint$(EXEEXT) troot$(EXEEXT) tround_prec$(EXEEXT) \
+ tsec$(EXEEXT) tsech$(EXEEXT) tset_d$(EXEEXT) tset_f$(EXEEXT) \
+ tset_ld$(EXEEXT) tset_q$(EXEEXT) tset_si$(EXEEXT) \
+ tset_sj$(EXEEXT) tset_str$(EXEEXT) tset_z$(EXEEXT) \
+ tset_z_exp$(EXEEXT) tsi_op$(EXEEXT) tsin$(EXEEXT) \
+ tsin_cos$(EXEEXT) tsinh$(EXEEXT) tsinh_cosh$(EXEEXT) \
+ tsprintf$(EXEEXT) tsqr$(EXEEXT) tsqrt$(EXEEXT) \
+ tsqrt_ui$(EXEEXT) tstckintc$(EXEEXT) tstdint$(EXEEXT) \
+ tstrtofr$(EXEEXT) tsub$(EXEEXT) tsub1sp$(EXEEXT) \
+ tsub_d$(EXEEXT) tsub_ui$(EXEEXT) tsubnormal$(EXEEXT) \
+ tsum$(EXEEXT) tswap$(EXEEXT) ttan$(EXEEXT) ttanh$(EXEEXT) \
+ ttrunc$(EXEEXT) tui_div$(EXEEXT) tui_pow$(EXEEXT) \
+ tui_sub$(EXEEXT) turandom$(EXEEXT) tvalist$(EXEEXT) \
+ ty0$(EXEEXT) ty1$(EXEEXT) tyn$(EXEEXT) tzeta$(EXEEXT) \
+ tzeta_ui$(EXEEXT) tversion$(EXEEXT)
+subdir = tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+libfrtests_la_LIBADD =
+am_libfrtests_la_OBJECTS = memory.lo rnd_mode.lo tests.lo cmp_str.lo \
+ random2.lo
+libfrtests_la_OBJECTS = $(am_libfrtests_la_OBJECTS)
+mpf_compat_SOURCES = mpf_compat.c
+mpf_compat_OBJECTS = mpf_compat.$(OBJEXT)
+mpf_compat_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+mpf_compat_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+mpfr_compat_SOURCES = mpfr_compat.c
+mpfr_compat_OBJECTS = mpfr_compat.$(OBJEXT)
+mpfr_compat_LDADD = $(LDADD)
+mpfr_compat_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+reuse_SOURCES = reuse.c
+reuse_OBJECTS = reuse.$(OBJEXT)
+reuse_LDADD = $(LDADD)
+reuse_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tabs_SOURCES = tabs.c
+tabs_OBJECTS = tabs.$(OBJEXT)
+tabs_LDADD = $(LDADD)
+tabs_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tacos_SOURCES = tacos.c
+tacos_OBJECTS = tacos.$(OBJEXT)
+tacos_LDADD = $(LDADD)
+tacos_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tacosh_SOURCES = tacosh.c
+tacosh_OBJECTS = tacosh.$(OBJEXT)
+tacosh_LDADD = $(LDADD)
+tacosh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tadd_SOURCES = tadd.c
+tadd_OBJECTS = tadd.$(OBJEXT)
+tadd_LDADD = $(LDADD)
+tadd_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tadd1sp_SOURCES = tadd1sp.c
+tadd1sp_OBJECTS = tadd1sp.$(OBJEXT)
+tadd1sp_LDADD = $(LDADD)
+tadd1sp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tadd_d_SOURCES = tadd_d.c
+tadd_d_OBJECTS = tadd_d.$(OBJEXT)
+tadd_d_LDADD = $(LDADD)
+tadd_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tadd_ui_SOURCES = tadd_ui.c
+tadd_ui_OBJECTS = tadd_ui.$(OBJEXT)
+tadd_ui_LDADD = $(LDADD)
+tadd_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tagm_SOURCES = tagm.c
+tagm_OBJECTS = tagm.$(OBJEXT)
+tagm_LDADD = $(LDADD)
+tagm_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tai_SOURCES = tai.c
+tai_OBJECTS = tai.$(OBJEXT)
+tai_LDADD = $(LDADD)
+tai_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tasin_SOURCES = tasin.c
+tasin_OBJECTS = tasin.$(OBJEXT)
+tasin_LDADD = $(LDADD)
+tasin_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tasinh_SOURCES = tasinh.c
+tasinh_OBJECTS = tasinh.$(OBJEXT)
+tasinh_LDADD = $(LDADD)
+tasinh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tatan_SOURCES = tatan.c
+tatan_OBJECTS = tatan.$(OBJEXT)
+tatan_LDADD = $(LDADD)
+tatan_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tatanh_SOURCES = tatanh.c
+tatanh_OBJECTS = tatanh.$(OBJEXT)
+tatanh_LDADD = $(LDADD)
+tatanh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+taway_SOURCES = taway.c
+taway_OBJECTS = taway.$(OBJEXT)
+taway_LDADD = $(LDADD)
+taway_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tbuildopt_SOURCES = tbuildopt.c
+tbuildopt_OBJECTS = tbuildopt.$(OBJEXT)
+tbuildopt_LDADD = $(LDADD)
+tbuildopt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcan_round_SOURCES = tcan_round.c
+tcan_round_OBJECTS = tcan_round.$(OBJEXT)
+tcan_round_LDADD = $(LDADD)
+tcan_round_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcbrt_SOURCES = tcbrt.c
+tcbrt_OBJECTS = tcbrt.$(OBJEXT)
+tcbrt_LDADD = $(LDADD)
+tcbrt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcheck_SOURCES = tcheck.c
+tcheck_OBJECTS = tcheck.$(OBJEXT)
+tcheck_LDADD = $(LDADD)
+tcheck_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcmp_SOURCES = tcmp.c
+tcmp_OBJECTS = tcmp.$(OBJEXT)
+tcmp_LDADD = $(LDADD)
+tcmp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcmp2_SOURCES = tcmp2.c
+tcmp2_OBJECTS = tcmp2.$(OBJEXT)
+tcmp2_LDADD = $(LDADD)
+tcmp2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcmp_d_SOURCES = tcmp_d.c
+tcmp_d_OBJECTS = tcmp_d.$(OBJEXT)
+tcmp_d_LDADD = $(LDADD)
+tcmp_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcmp_ld_SOURCES = tcmp_ld.c
+tcmp_ld_OBJECTS = tcmp_ld.$(OBJEXT)
+tcmp_ld_LDADD = $(LDADD)
+tcmp_ld_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcmp_ui_SOURCES = tcmp_ui.c
+tcmp_ui_OBJECTS = tcmp_ui.$(OBJEXT)
+tcmp_ui_LDADD = $(LDADD)
+tcmp_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcmpabs_SOURCES = tcmpabs.c
+tcmpabs_OBJECTS = tcmpabs.$(OBJEXT)
+tcmpabs_LDADD = $(LDADD)
+tcmpabs_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcomparisons_SOURCES = tcomparisons.c
+tcomparisons_OBJECTS = tcomparisons.$(OBJEXT)
+tcomparisons_LDADD = $(LDADD)
+tcomparisons_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tconst_catalan_SOURCES = tconst_catalan.c
+tconst_catalan_OBJECTS = tconst_catalan.$(OBJEXT)
+tconst_catalan_LDADD = $(LDADD)
+tconst_catalan_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tconst_euler_SOURCES = tconst_euler.c
+tconst_euler_OBJECTS = tconst_euler.$(OBJEXT)
+tconst_euler_LDADD = $(LDADD)
+tconst_euler_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tconst_log2_SOURCES = tconst_log2.c
+tconst_log2_OBJECTS = tconst_log2.$(OBJEXT)
+tconst_log2_LDADD = $(LDADD)
+tconst_log2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tconst_pi_SOURCES = tconst_pi.c
+tconst_pi_OBJECTS = tconst_pi.$(OBJEXT)
+tconst_pi_LDADD = $(LDADD)
+tconst_pi_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcopysign_SOURCES = tcopysign.c
+tcopysign_OBJECTS = tcopysign.$(OBJEXT)
+tcopysign_LDADD = $(LDADD)
+tcopysign_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcos_SOURCES = tcos.c
+tcos_OBJECTS = tcos.$(OBJEXT)
+tcos_LDADD = $(LDADD)
+tcos_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcosh_SOURCES = tcosh.c
+tcosh_OBJECTS = tcosh.$(OBJEXT)
+tcosh_LDADD = $(LDADD)
+tcosh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcot_SOURCES = tcot.c
+tcot_OBJECTS = tcot.$(OBJEXT)
+tcot_LDADD = $(LDADD)
+tcot_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcoth_SOURCES = tcoth.c
+tcoth_OBJECTS = tcoth.$(OBJEXT)
+tcoth_LDADD = $(LDADD)
+tcoth_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcsc_SOURCES = tcsc.c
+tcsc_OBJECTS = tcsc.$(OBJEXT)
+tcsc_LDADD = $(LDADD)
+tcsc_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tcsch_SOURCES = tcsch.c
+tcsch_OBJECTS = tcsch.$(OBJEXT)
+tcsch_LDADD = $(LDADD)
+tcsch_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+td_div_SOURCES = td_div.c
+td_div_OBJECTS = td_div.$(OBJEXT)
+td_div_LDADD = $(LDADD)
+td_div_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+td_sub_SOURCES = td_sub.c
+td_sub_OBJECTS = td_sub.$(OBJEXT)
+td_sub_LDADD = $(LDADD)
+td_sub_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tdigamma_SOURCES = tdigamma.c
+tdigamma_OBJECTS = tdigamma.$(OBJEXT)
+tdigamma_LDADD = $(LDADD)
+tdigamma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tdim_SOURCES = tdim.c
+tdim_OBJECTS = tdim.$(OBJEXT)
+tdim_LDADD = $(LDADD)
+tdim_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tdiv_SOURCES = tdiv.c
+tdiv_OBJECTS = tdiv.$(OBJEXT)
+tdiv_LDADD = $(LDADD)
+tdiv_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tdiv_d_SOURCES = tdiv_d.c
+tdiv_d_OBJECTS = tdiv_d.$(OBJEXT)
+tdiv_d_LDADD = $(LDADD)
+tdiv_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tdiv_ui_SOURCES = tdiv_ui.c
+tdiv_ui_OBJECTS = tdiv_ui.$(OBJEXT)
+tdiv_ui_LDADD = $(LDADD)
+tdiv_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+teint_SOURCES = teint.c
+teint_OBJECTS = teint.$(OBJEXT)
+teint_LDADD = $(LDADD)
+teint_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+teq_SOURCES = teq.c
+teq_OBJECTS = teq.$(OBJEXT)
+teq_LDADD = $(LDADD)
+teq_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+terf_SOURCES = terf.c
+terf_OBJECTS = terf.$(OBJEXT)
+terf_LDADD = $(LDADD)
+terf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+texceptions_SOURCES = texceptions.c
+texceptions_OBJECTS = texceptions.$(OBJEXT)
+texceptions_LDADD = $(LDADD)
+texceptions_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+texp_SOURCES = texp.c
+texp_OBJECTS = texp.$(OBJEXT)
+texp_LDADD = $(LDADD)
+texp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+texp10_SOURCES = texp10.c
+texp10_OBJECTS = texp10.$(OBJEXT)
+texp10_LDADD = $(LDADD)
+texp10_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+texp2_SOURCES = texp2.c
+texp2_OBJECTS = texp2.$(OBJEXT)
+texp2_LDADD = $(LDADD)
+texp2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+texpm1_SOURCES = texpm1.c
+texpm1_OBJECTS = texpm1.$(OBJEXT)
+texpm1_LDADD = $(LDADD)
+texpm1_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tfactorial_SOURCES = tfactorial.c
+tfactorial_OBJECTS = tfactorial.$(OBJEXT)
+tfactorial_LDADD = $(LDADD)
+tfactorial_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tfits_SOURCES = tfits.c
+tfits_OBJECTS = tfits.$(OBJEXT)
+tfits_LDADD = $(LDADD)
+tfits_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tfma_SOURCES = tfma.c
+tfma_OBJECTS = tfma.$(OBJEXT)
+tfma_LDADD = $(LDADD)
+tfma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tfmod_SOURCES = tfmod.c
+tfmod_OBJECTS = tfmod.$(OBJEXT)
+tfmod_LDADD = $(LDADD)
+tfmod_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tfms_SOURCES = tfms.c
+tfms_OBJECTS = tfms.$(OBJEXT)
+tfms_LDADD = $(LDADD)
+tfms_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tfprintf_SOURCES = tfprintf.c
+tfprintf_OBJECTS = tfprintf.$(OBJEXT)
+tfprintf_LDADD = $(LDADD)
+tfprintf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tfrac_SOURCES = tfrac.c
+tfrac_OBJECTS = tfrac.$(OBJEXT)
+tfrac_LDADD = $(LDADD)
+tfrac_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tfrexp_SOURCES = tfrexp.c
+tfrexp_OBJECTS = tfrexp.$(OBJEXT)
+tfrexp_LDADD = $(LDADD)
+tfrexp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tgamma_SOURCES = tgamma.c
+tgamma_OBJECTS = tgamma.$(OBJEXT)
+tgamma_LDADD = $(LDADD)
+tgamma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tget_d_SOURCES = tget_d.c
+tget_d_OBJECTS = tget_d.$(OBJEXT)
+tget_d_LDADD = $(LDADD)
+tget_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tget_d_2exp_SOURCES = tget_d_2exp.c
+tget_d_2exp_OBJECTS = tget_d_2exp.$(OBJEXT)
+tget_d_2exp_LDADD = $(LDADD)
+tget_d_2exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tget_f_SOURCES = tget_f.c
+tget_f_OBJECTS = tget_f.$(OBJEXT)
+tget_f_LDADD = $(LDADD)
+tget_f_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tget_flt_SOURCES = tget_flt.c
+tget_flt_OBJECTS = tget_flt.$(OBJEXT)
+tget_flt_LDADD = $(LDADD)
+tget_flt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tget_ld_2exp_SOURCES = tget_ld_2exp.c
+tget_ld_2exp_OBJECTS = tget_ld_2exp.$(OBJEXT)
+tget_ld_2exp_LDADD = $(LDADD)
+tget_ld_2exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tget_set_d64_SOURCES = tget_set_d64.c
+tget_set_d64_OBJECTS = tget_set_d64.$(OBJEXT)
+tget_set_d64_LDADD = $(LDADD)
+tget_set_d64_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tget_sj_SOURCES = tget_sj.c
+tget_sj_OBJECTS = tget_sj.$(OBJEXT)
+tget_sj_LDADD = $(LDADD)
+tget_sj_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tget_str_SOURCES = tget_str.c
+tget_str_OBJECTS = tget_str.$(OBJEXT)
+tget_str_LDADD = $(LDADD)
+tget_str_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tget_z_SOURCES = tget_z.c
+tget_z_OBJECTS = tget_z.$(OBJEXT)
+tget_z_LDADD = $(LDADD)
+tget_z_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tgmpop_SOURCES = tgmpop.c
+tgmpop_OBJECTS = tgmpop.$(OBJEXT)
+tgmpop_LDADD = $(LDADD)
+tgmpop_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tgrandom_SOURCES = tgrandom.c
+tgrandom_OBJECTS = tgrandom.$(OBJEXT)
+tgrandom_LDADD = $(LDADD)
+tgrandom_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+thyperbolic_SOURCES = thyperbolic.c
+thyperbolic_OBJECTS = thyperbolic.$(OBJEXT)
+thyperbolic_LDADD = $(LDADD)
+thyperbolic_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+thypot_SOURCES = thypot.c
+thypot_OBJECTS = thypot.$(OBJEXT)
+thypot_LDADD = $(LDADD)
+thypot_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tinits_SOURCES = tinits.c
+tinits_OBJECTS = tinits.$(OBJEXT)
+tinits_LDADD = $(LDADD)
+tinits_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tinp_str_SOURCES = tinp_str.c
+tinp_str_OBJECTS = tinp_str.$(OBJEXT)
+tinp_str_LDADD = $(LDADD)
+tinp_str_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tinternals_SOURCES = tinternals.c
+tinternals_OBJECTS = tinternals.$(OBJEXT)
+tinternals_LDADD = $(LDADD)
+tinternals_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tisnan_SOURCES = tisnan.c
+tisnan_OBJECTS = tisnan.$(OBJEXT)
+tisnan_LDADD = $(LDADD)
+tisnan_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tisqrt_SOURCES = tisqrt.c
+tisqrt_OBJECTS = tisqrt.$(OBJEXT)
+tisqrt_LDADD = $(LDADD)
+tisqrt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tj0_SOURCES = tj0.c
+tj0_OBJECTS = tj0.$(OBJEXT)
+tj0_LDADD = $(LDADD)
+tj0_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tj1_SOURCES = tj1.c
+tj1_OBJECTS = tj1.$(OBJEXT)
+tj1_LDADD = $(LDADD)
+tj1_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tjn_SOURCES = tjn.c
+tjn_OBJECTS = tjn.$(OBJEXT)
+tjn_LDADD = $(LDADD)
+tjn_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tl2b_SOURCES = tl2b.c
+tl2b_OBJECTS = tl2b.$(OBJEXT)
+tl2b_LDADD = $(LDADD)
+tl2b_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tlgamma_SOURCES = tlgamma.c
+tlgamma_OBJECTS = tlgamma.$(OBJEXT)
+tlgamma_LDADD = $(LDADD)
+tlgamma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tli2_SOURCES = tli2.c
+tli2_OBJECTS = tli2.$(OBJEXT)
+tli2_LDADD = $(LDADD)
+tli2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tlngamma_SOURCES = tlngamma.c
+tlngamma_OBJECTS = tlngamma.$(OBJEXT)
+tlngamma_LDADD = $(LDADD)
+tlngamma_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tlog_SOURCES = tlog.c
+tlog_OBJECTS = tlog.$(OBJEXT)
+tlog_LDADD = $(LDADD)
+tlog_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tlog10_SOURCES = tlog10.c
+tlog10_OBJECTS = tlog10.$(OBJEXT)
+tlog10_LDADD = $(LDADD)
+tlog10_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tlog1p_SOURCES = tlog1p.c
+tlog1p_OBJECTS = tlog1p.$(OBJEXT)
+tlog1p_LDADD = $(LDADD)
+tlog1p_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tlog2_SOURCES = tlog2.c
+tlog2_OBJECTS = tlog2.$(OBJEXT)
+tlog2_LDADD = $(LDADD)
+tlog2_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tmin_prec_SOURCES = tmin_prec.c
+tmin_prec_OBJECTS = tmin_prec.$(OBJEXT)
+tmin_prec_LDADD = $(LDADD)
+tmin_prec_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tminmax_SOURCES = tminmax.c
+tminmax_OBJECTS = tminmax.$(OBJEXT)
+tminmax_LDADD = $(LDADD)
+tminmax_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tmodf_SOURCES = tmodf.c
+tmodf_OBJECTS = tmodf.$(OBJEXT)
+tmodf_LDADD = $(LDADD)
+tmodf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tmul_SOURCES = tmul.c
+tmul_OBJECTS = tmul.$(OBJEXT)
+tmul_LDADD = $(LDADD)
+tmul_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tmul_2exp_SOURCES = tmul_2exp.c
+tmul_2exp_OBJECTS = tmul_2exp.$(OBJEXT)
+tmul_2exp_LDADD = $(LDADD)
+tmul_2exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tmul_d_SOURCES = tmul_d.c
+tmul_d_OBJECTS = tmul_d.$(OBJEXT)
+tmul_d_LDADD = $(LDADD)
+tmul_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tmul_ui_SOURCES = tmul_ui.c
+tmul_ui_OBJECTS = tmul_ui.$(OBJEXT)
+tmul_ui_LDADD = $(LDADD)
+tmul_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tnext_SOURCES = tnext.c
+tnext_OBJECTS = tnext.$(OBJEXT)
+tnext_LDADD = $(LDADD)
+tnext_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tout_str_SOURCES = tout_str.c
+tout_str_OBJECTS = tout_str.$(OBJEXT)
+tout_str_LDADD = $(LDADD)
+tout_str_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+toutimpl_SOURCES = toutimpl.c
+toutimpl_OBJECTS = toutimpl.$(OBJEXT)
+toutimpl_LDADD = $(LDADD)
+toutimpl_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tpow_SOURCES = tpow.c
+tpow_OBJECTS = tpow.$(OBJEXT)
+tpow_LDADD = $(LDADD)
+tpow_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tpow3_SOURCES = tpow3.c
+tpow3_OBJECTS = tpow3.$(OBJEXT)
+tpow3_LDADD = $(LDADD)
+tpow3_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tpow_all_SOURCES = tpow_all.c
+tpow_all_OBJECTS = tpow_all.$(OBJEXT)
+tpow_all_LDADD = $(LDADD)
+tpow_all_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tpow_z_SOURCES = tpow_z.c
+tpow_z_OBJECTS = tpow_z.$(OBJEXT)
+tpow_z_LDADD = $(LDADD)
+tpow_z_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tprintf_SOURCES = tprintf.c
+tprintf_OBJECTS = tprintf.$(OBJEXT)
+tprintf_LDADD = $(LDADD)
+tprintf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+trandom_SOURCES = trandom.c
+trandom_OBJECTS = trandom.$(OBJEXT)
+trandom_LDADD = $(LDADD)
+trandom_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+trec_sqrt_SOURCES = trec_sqrt.c
+trec_sqrt_OBJECTS = trec_sqrt.$(OBJEXT)
+trec_sqrt_LDADD = $(LDADD)
+trec_sqrt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tremquo_SOURCES = tremquo.c
+tremquo_OBJECTS = tremquo.$(OBJEXT)
+tremquo_LDADD = $(LDADD)
+tremquo_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+trint_SOURCES = trint.c
+trint_OBJECTS = trint.$(OBJEXT)
+trint_LDADD = $(LDADD)
+trint_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+troot_SOURCES = troot.c
+troot_OBJECTS = troot.$(OBJEXT)
+troot_LDADD = $(LDADD)
+troot_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tround_prec_SOURCES = tround_prec.c
+tround_prec_OBJECTS = tround_prec.$(OBJEXT)
+tround_prec_LDADD = $(LDADD)
+tround_prec_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsec_SOURCES = tsec.c
+tsec_OBJECTS = tsec.$(OBJEXT)
+tsec_LDADD = $(LDADD)
+tsec_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsech_SOURCES = tsech.c
+tsech_OBJECTS = tsech.$(OBJEXT)
+tsech_LDADD = $(LDADD)
+tsech_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_SOURCES = tset.c
+tset_OBJECTS = tset.$(OBJEXT)
+tset_LDADD = $(LDADD)
+tset_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_d_SOURCES = tset_d.c
+tset_d_OBJECTS = tset_d.$(OBJEXT)
+tset_d_LDADD = $(LDADD)
+tset_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_exp_SOURCES = tset_exp.c
+tset_exp_OBJECTS = tset_exp.$(OBJEXT)
+tset_exp_LDADD = $(LDADD)
+tset_exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_f_SOURCES = tset_f.c
+tset_f_OBJECTS = tset_f.$(OBJEXT)
+tset_f_LDADD = $(LDADD)
+tset_f_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_ld_SOURCES = tset_ld.c
+tset_ld_OBJECTS = tset_ld.$(OBJEXT)
+tset_ld_LDADD = $(LDADD)
+tset_ld_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_q_SOURCES = tset_q.c
+tset_q_OBJECTS = tset_q.$(OBJEXT)
+tset_q_LDADD = $(LDADD)
+tset_q_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_si_SOURCES = tset_si.c
+tset_si_OBJECTS = tset_si.$(OBJEXT)
+tset_si_LDADD = $(LDADD)
+tset_si_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_sj_SOURCES = tset_sj.c
+tset_sj_OBJECTS = tset_sj.$(OBJEXT)
+tset_sj_LDADD = $(LDADD)
+tset_sj_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_str_SOURCES = tset_str.c
+tset_str_OBJECTS = tset_str.$(OBJEXT)
+tset_str_LDADD = $(LDADD)
+tset_str_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_z_SOURCES = tset_z.c
+tset_z_OBJECTS = tset_z.$(OBJEXT)
+tset_z_LDADD = $(LDADD)
+tset_z_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tset_z_exp_SOURCES = tset_z_exp.c
+tset_z_exp_OBJECTS = tset_z_exp.$(OBJEXT)
+tset_z_exp_LDADD = $(LDADD)
+tset_z_exp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsgn_SOURCES = tsgn.c
+tsgn_OBJECTS = tsgn.$(OBJEXT)
+tsgn_LDADD = $(LDADD)
+tsgn_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsi_op_SOURCES = tsi_op.c
+tsi_op_OBJECTS = tsi_op.$(OBJEXT)
+tsi_op_LDADD = $(LDADD)
+tsi_op_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsin_SOURCES = tsin.c
+tsin_OBJECTS = tsin.$(OBJEXT)
+tsin_LDADD = $(LDADD)
+tsin_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsin_cos_SOURCES = tsin_cos.c
+tsin_cos_OBJECTS = tsin_cos.$(OBJEXT)
+tsin_cos_LDADD = $(LDADD)
+tsin_cos_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsinh_SOURCES = tsinh.c
+tsinh_OBJECTS = tsinh.$(OBJEXT)
+tsinh_LDADD = $(LDADD)
+tsinh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsinh_cosh_SOURCES = tsinh_cosh.c
+tsinh_cosh_OBJECTS = tsinh_cosh.$(OBJEXT)
+tsinh_cosh_LDADD = $(LDADD)
+tsinh_cosh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsprintf_SOURCES = tsprintf.c
+tsprintf_OBJECTS = tsprintf.$(OBJEXT)
+tsprintf_LDADD = $(LDADD)
+tsprintf_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsqr_SOURCES = tsqr.c
+tsqr_OBJECTS = tsqr.$(OBJEXT)
+tsqr_LDADD = $(LDADD)
+tsqr_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsqrt_SOURCES = tsqrt.c
+tsqrt_OBJECTS = tsqrt.$(OBJEXT)
+tsqrt_LDADD = $(LDADD)
+tsqrt_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsqrt_ui_SOURCES = tsqrt_ui.c
+tsqrt_ui_OBJECTS = tsqrt_ui.$(OBJEXT)
+tsqrt_ui_LDADD = $(LDADD)
+tsqrt_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tstckintc_SOURCES = tstckintc.c
+tstckintc_OBJECTS = tstckintc.$(OBJEXT)
+tstckintc_LDADD = $(LDADD)
+tstckintc_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tstdint_SOURCES = tstdint.c
+tstdint_OBJECTS = tstdint.$(OBJEXT)
+tstdint_LDADD = $(LDADD)
+tstdint_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tstrtofr_SOURCES = tstrtofr.c
+tstrtofr_OBJECTS = tstrtofr.$(OBJEXT)
+tstrtofr_LDADD = $(LDADD)
+tstrtofr_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsub_SOURCES = tsub.c
+tsub_OBJECTS = tsub.$(OBJEXT)
+tsub_LDADD = $(LDADD)
+tsub_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsub1sp_SOURCES = tsub1sp.c
+tsub1sp_OBJECTS = tsub1sp.$(OBJEXT)
+tsub1sp_LDADD = $(LDADD)
+tsub1sp_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsub_d_SOURCES = tsub_d.c
+tsub_d_OBJECTS = tsub_d.$(OBJEXT)
+tsub_d_LDADD = $(LDADD)
+tsub_d_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsub_ui_SOURCES = tsub_ui.c
+tsub_ui_OBJECTS = tsub_ui.$(OBJEXT)
+tsub_ui_LDADD = $(LDADD)
+tsub_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsubnormal_SOURCES = tsubnormal.c
+tsubnormal_OBJECTS = tsubnormal.$(OBJEXT)
+tsubnormal_LDADD = $(LDADD)
+tsubnormal_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tsum_SOURCES = tsum.c
+tsum_OBJECTS = tsum.$(OBJEXT)
+tsum_LDADD = $(LDADD)
+tsum_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tswap_SOURCES = tswap.c
+tswap_OBJECTS = tswap.$(OBJEXT)
+tswap_LDADD = $(LDADD)
+tswap_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+ttan_SOURCES = ttan.c
+ttan_OBJECTS = ttan.$(OBJEXT)
+ttan_LDADD = $(LDADD)
+ttan_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+ttanh_SOURCES = ttanh.c
+ttanh_OBJECTS = ttanh.$(OBJEXT)
+ttanh_LDADD = $(LDADD)
+ttanh_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+ttrunc_SOURCES = ttrunc.c
+ttrunc_OBJECTS = ttrunc.$(OBJEXT)
+ttrunc_LDADD = $(LDADD)
+ttrunc_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tui_div_SOURCES = tui_div.c
+tui_div_OBJECTS = tui_div.$(OBJEXT)
+tui_div_LDADD = $(LDADD)
+tui_div_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tui_pow_SOURCES = tui_pow.c
+tui_pow_OBJECTS = tui_pow.$(OBJEXT)
+tui_pow_LDADD = $(LDADD)
+tui_pow_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tui_sub_SOURCES = tui_sub.c
+tui_sub_OBJECTS = tui_sub.$(OBJEXT)
+tui_sub_LDADD = $(LDADD)
+tui_sub_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+turandom_SOURCES = turandom.c
+turandom_OBJECTS = turandom.$(OBJEXT)
+turandom_LDADD = $(LDADD)
+turandom_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tvalist_SOURCES = tvalist.c
+tvalist_OBJECTS = tvalist.$(OBJEXT)
+tvalist_LDADD = $(LDADD)
+tvalist_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tversion_SOURCES = tversion.c
+tversion_OBJECTS = tversion.$(OBJEXT)
+tversion_LDADD = $(LDADD)
+tversion_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+ty0_SOURCES = ty0.c
+ty0_OBJECTS = ty0.$(OBJEXT)
+ty0_LDADD = $(LDADD)
+ty0_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+ty1_SOURCES = ty1.c
+ty1_OBJECTS = ty1.$(OBJEXT)
+ty1_LDADD = $(LDADD)
+ty1_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tyn_SOURCES = tyn.c
+tyn_OBJECTS = tyn.$(OBJEXT)
+tyn_LDADD = $(LDADD)
+tyn_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tzeta_SOURCES = tzeta.c
+tzeta_OBJECTS = tzeta.$(OBJEXT)
+tzeta_LDADD = $(LDADD)
+tzeta_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+tzeta_ui_SOURCES = tzeta_ui.c
+tzeta_ui_OBJECTS = tzeta_ui.$(OBJEXT)
+tzeta_ui_LDADD = $(LDADD)
+tzeta_ui_DEPENDENCIES = libfrtests.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libmpfr.la
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libfrtests_la_SOURCES) mpf_compat.c mpfr_compat.c reuse.c \
+ tabs.c tacos.c tacosh.c tadd.c tadd1sp.c tadd_d.c tadd_ui.c \
+ tagm.c tai.c tasin.c tasinh.c tatan.c tatanh.c taway.c \
+ tbuildopt.c tcan_round.c tcbrt.c tcheck.c tcmp.c tcmp2.c \
+ tcmp_d.c tcmp_ld.c tcmp_ui.c tcmpabs.c tcomparisons.c \
+ tconst_catalan.c tconst_euler.c tconst_log2.c tconst_pi.c \
+ tcopysign.c tcos.c tcosh.c tcot.c tcoth.c tcsc.c tcsch.c \
+ td_div.c td_sub.c tdigamma.c tdim.c tdiv.c tdiv_d.c tdiv_ui.c \
+ teint.c teq.c terf.c texceptions.c texp.c texp10.c texp2.c \
+ texpm1.c tfactorial.c tfits.c tfma.c tfmod.c tfms.c tfprintf.c \
+ tfrac.c tfrexp.c tgamma.c tget_d.c tget_d_2exp.c tget_f.c \
+ tget_flt.c tget_ld_2exp.c tget_set_d64.c tget_sj.c tget_str.c \
+ tget_z.c tgmpop.c tgrandom.c thyperbolic.c thypot.c tinits.c \
+ tinp_str.c tinternals.c tisnan.c tisqrt.c tj0.c tj1.c tjn.c \
+ tl2b.c tlgamma.c tli2.c tlngamma.c tlog.c tlog10.c tlog1p.c \
+ tlog2.c tmin_prec.c tminmax.c tmodf.c tmul.c tmul_2exp.c \
+ tmul_d.c tmul_ui.c tnext.c tout_str.c toutimpl.c tpow.c \
+ tpow3.c tpow_all.c tpow_z.c tprintf.c trandom.c trec_sqrt.c \
+ tremquo.c trint.c troot.c tround_prec.c tsec.c tsech.c tset.c \
+ tset_d.c tset_exp.c tset_f.c tset_ld.c tset_q.c tset_si.c \
+ tset_sj.c tset_str.c tset_z.c tset_z_exp.c tsgn.c tsi_op.c \
+ tsin.c tsin_cos.c tsinh.c tsinh_cosh.c tsprintf.c tsqr.c \
+ tsqrt.c tsqrt_ui.c tstckintc.c tstdint.c tstrtofr.c tsub.c \
+ tsub1sp.c tsub_d.c tsub_ui.c tsubnormal.c tsum.c tswap.c \
+ ttan.c ttanh.c ttrunc.c tui_div.c tui_pow.c tui_sub.c \
+ turandom.c tvalist.c tversion.c ty0.c ty1.c tyn.c tzeta.c \
+ tzeta_ui.c
+DIST_SOURCES = $(libfrtests_la_SOURCES) mpf_compat.c mpfr_compat.c \
+ reuse.c tabs.c tacos.c tacosh.c tadd.c tadd1sp.c tadd_d.c \
+ tadd_ui.c tagm.c tai.c tasin.c tasinh.c tatan.c tatanh.c \
+ taway.c tbuildopt.c tcan_round.c tcbrt.c tcheck.c tcmp.c \
+ tcmp2.c tcmp_d.c tcmp_ld.c tcmp_ui.c tcmpabs.c tcomparisons.c \
+ tconst_catalan.c tconst_euler.c tconst_log2.c tconst_pi.c \
+ tcopysign.c tcos.c tcosh.c tcot.c tcoth.c tcsc.c tcsch.c \
+ td_div.c td_sub.c tdigamma.c tdim.c tdiv.c tdiv_d.c tdiv_ui.c \
+ teint.c teq.c terf.c texceptions.c texp.c texp10.c texp2.c \
+ texpm1.c tfactorial.c tfits.c tfma.c tfmod.c tfms.c tfprintf.c \
+ tfrac.c tfrexp.c tgamma.c tget_d.c tget_d_2exp.c tget_f.c \
+ tget_flt.c tget_ld_2exp.c tget_set_d64.c tget_sj.c tget_str.c \
+ tget_z.c tgmpop.c tgrandom.c thyperbolic.c thypot.c tinits.c \
+ tinp_str.c tinternals.c tisnan.c tisqrt.c tj0.c tj1.c tjn.c \
+ tl2b.c tlgamma.c tli2.c tlngamma.c tlog.c tlog10.c tlog1p.c \
+ tlog2.c tmin_prec.c tminmax.c tmodf.c tmul.c tmul_2exp.c \
+ tmul_d.c tmul_ui.c tnext.c tout_str.c toutimpl.c tpow.c \
+ tpow3.c tpow_all.c tpow_z.c tprintf.c trandom.c trec_sqrt.c \
+ tremquo.c trint.c troot.c tround_prec.c tsec.c tsech.c tset.c \
+ tset_d.c tset_exp.c tset_f.c tset_ld.c tset_q.c tset_si.c \
+ tset_sj.c tset_str.c tset_z.c tset_z_exp.c tsgn.c tsi_op.c \
+ tsin.c tsin_cos.c tsinh.c tsinh_cosh.c tsprintf.c tsqr.c \
+ tsqrt.c tsqrt_ui.c tstckintc.c tstdint.c tstrtofr.c tsub.c \
+ tsub1sp.c tsub_d.c tsub_ui.c tsubnormal.c tsum.c tswap.c \
+ ttan.c ttanh.c ttrunc.c tui_div.c tui_pow.c tui_sub.c \
+ turandom.c tvalist.c tversion.c ty0.c ty1.c tyn.c tzeta.c \
+ tzeta_ui.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATAFILES = @DATAFILES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBMPFR_LDFLAGS = @LIBMPFR_LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPFR_LDFLAGS = @MPFR_LDFLAGS@
+MPFR_LIBM = @MPFR_LIBM@
+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@
+STRIP = @STRIP@
+TUNE_LIBS = @TUNE_LIBS@
+VERSION = @VERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+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@
+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@
+AUTOMAKE_OPTIONS = 1.6 gnu
+AM_CPPFLAGS = -DSRCDIR='"$(srcdir)"'
+EXTRA_DIST = tgeneric.c tgeneric_ui.c mpf_compat.h inp_str.data tmul.dat
+LDADD = libfrtests.la $(MPFR_LIBM) $(top_builddir)/src/libmpfr.la
+INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src
+
+# LOADLIBES (documented in the "GNU make" manual and equivalent to LDLIBS)
+# enables to compile a program foo.c in the test directory by simply doing
+# "make foo".
+# Warning! This is not guaranteed to work, as libtool is not used. In
+# particular, this may not work as expected under GNU/Linux if --with-gmp
+# has been used, unless the directory is in your $LD_LIBRARY_PATH.
+# Moreover, dependencies are not tracked. Thus you may want to run
+# "make tversion" (for instance) just before, to make sure that every
+# dependency has been rebuilt.
+LOADLIBES = $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(top_builddir)/tests/.libs/libfrtests.a $(top_builddir)/src/.libs/libmpfr.a $(LIBS) $(MPFR_LIBM)
+check_LTLIBRARIES = libfrtests.la
+libfrtests_la_SOURCES = mpfr-test.h memory.c rnd_mode.c tests.c cmp_str.c random2.c
+TESTS = $(check_PROGRAMS)
+TESTS_ENVIRONMENT = MPFR_QUIET=1 $(VALGRIND)
+
+# The -no-install option prevents libtool from generating wrapper scripts
+# for the tests.
+# This is useful to easily run the test scripts under valgrind or gdb.
+# See discussion http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28033
+# http://article.gmane.org/gmane.comp.lib.gnulib.bugs/28140 in particular.
+#
+# The -L$(top_builddir)/src/.libs option is necessary for some platforms,
+# such as HP-UX, when --with-gmp or --with-gmp-lib is used and an old MPFR
+# library is already installed in the corresponding lib directory: its
+# purpose is to make sure that the local .libs comes first in the library
+# search path (otherwise the tests are linked against the old MPFR library
+# by the LINK command -- see the generated Makefile). See:
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00042.html
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00043.html
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00044.html
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00066.html
+# https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00065.html
+# and
+# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9728
+#
+AM_LDFLAGS = -no-install -L$(top_builddir)/src/.libs
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tests/Makefile
+.PRECIOUS: 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-checkLTLIBRARIES:
+ -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES)
+ @list='$(check_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libfrtests.la: $(libfrtests_la_OBJECTS) $(libfrtests_la_DEPENDENCIES) $(EXTRA_libfrtests_la_DEPENDENCIES)
+ $(LINK) $(libfrtests_la_OBJECTS) $(libfrtests_la_LIBADD) $(LIBS)
+
+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
+mpf_compat$(EXEEXT): $(mpf_compat_OBJECTS) $(mpf_compat_DEPENDENCIES) $(EXTRA_mpf_compat_DEPENDENCIES)
+ @rm -f mpf_compat$(EXEEXT)
+ $(LINK) $(mpf_compat_OBJECTS) $(mpf_compat_LDADD) $(LIBS)
+mpfr_compat$(EXEEXT): $(mpfr_compat_OBJECTS) $(mpfr_compat_DEPENDENCIES) $(EXTRA_mpfr_compat_DEPENDENCIES)
+ @rm -f mpfr_compat$(EXEEXT)
+ $(LINK) $(mpfr_compat_OBJECTS) $(mpfr_compat_LDADD) $(LIBS)
+reuse$(EXEEXT): $(reuse_OBJECTS) $(reuse_DEPENDENCIES) $(EXTRA_reuse_DEPENDENCIES)
+ @rm -f reuse$(EXEEXT)
+ $(LINK) $(reuse_OBJECTS) $(reuse_LDADD) $(LIBS)
+tabs$(EXEEXT): $(tabs_OBJECTS) $(tabs_DEPENDENCIES) $(EXTRA_tabs_DEPENDENCIES)
+ @rm -f tabs$(EXEEXT)
+ $(LINK) $(tabs_OBJECTS) $(tabs_LDADD) $(LIBS)
+tacos$(EXEEXT): $(tacos_OBJECTS) $(tacos_DEPENDENCIES) $(EXTRA_tacos_DEPENDENCIES)
+ @rm -f tacos$(EXEEXT)
+ $(LINK) $(tacos_OBJECTS) $(tacos_LDADD) $(LIBS)
+tacosh$(EXEEXT): $(tacosh_OBJECTS) $(tacosh_DEPENDENCIES) $(EXTRA_tacosh_DEPENDENCIES)
+ @rm -f tacosh$(EXEEXT)
+ $(LINK) $(tacosh_OBJECTS) $(tacosh_LDADD) $(LIBS)
+tadd$(EXEEXT): $(tadd_OBJECTS) $(tadd_DEPENDENCIES) $(EXTRA_tadd_DEPENDENCIES)
+ @rm -f tadd$(EXEEXT)
+ $(LINK) $(tadd_OBJECTS) $(tadd_LDADD) $(LIBS)
+tadd1sp$(EXEEXT): $(tadd1sp_OBJECTS) $(tadd1sp_DEPENDENCIES) $(EXTRA_tadd1sp_DEPENDENCIES)
+ @rm -f tadd1sp$(EXEEXT)
+ $(LINK) $(tadd1sp_OBJECTS) $(tadd1sp_LDADD) $(LIBS)
+tadd_d$(EXEEXT): $(tadd_d_OBJECTS) $(tadd_d_DEPENDENCIES) $(EXTRA_tadd_d_DEPENDENCIES)
+ @rm -f tadd_d$(EXEEXT)
+ $(LINK) $(tadd_d_OBJECTS) $(tadd_d_LDADD) $(LIBS)
+tadd_ui$(EXEEXT): $(tadd_ui_OBJECTS) $(tadd_ui_DEPENDENCIES) $(EXTRA_tadd_ui_DEPENDENCIES)
+ @rm -f tadd_ui$(EXEEXT)
+ $(LINK) $(tadd_ui_OBJECTS) $(tadd_ui_LDADD) $(LIBS)
+tagm$(EXEEXT): $(tagm_OBJECTS) $(tagm_DEPENDENCIES) $(EXTRA_tagm_DEPENDENCIES)
+ @rm -f tagm$(EXEEXT)
+ $(LINK) $(tagm_OBJECTS) $(tagm_LDADD) $(LIBS)
+tai$(EXEEXT): $(tai_OBJECTS) $(tai_DEPENDENCIES) $(EXTRA_tai_DEPENDENCIES)
+ @rm -f tai$(EXEEXT)
+ $(LINK) $(tai_OBJECTS) $(tai_LDADD) $(LIBS)
+tasin$(EXEEXT): $(tasin_OBJECTS) $(tasin_DEPENDENCIES) $(EXTRA_tasin_DEPENDENCIES)
+ @rm -f tasin$(EXEEXT)
+ $(LINK) $(tasin_OBJECTS) $(tasin_LDADD) $(LIBS)
+tasinh$(EXEEXT): $(tasinh_OBJECTS) $(tasinh_DEPENDENCIES) $(EXTRA_tasinh_DEPENDENCIES)
+ @rm -f tasinh$(EXEEXT)
+ $(LINK) $(tasinh_OBJECTS) $(tasinh_LDADD) $(LIBS)
+tatan$(EXEEXT): $(tatan_OBJECTS) $(tatan_DEPENDENCIES) $(EXTRA_tatan_DEPENDENCIES)
+ @rm -f tatan$(EXEEXT)
+ $(LINK) $(tatan_OBJECTS) $(tatan_LDADD) $(LIBS)
+tatanh$(EXEEXT): $(tatanh_OBJECTS) $(tatanh_DEPENDENCIES) $(EXTRA_tatanh_DEPENDENCIES)
+ @rm -f tatanh$(EXEEXT)
+ $(LINK) $(tatanh_OBJECTS) $(tatanh_LDADD) $(LIBS)
+taway$(EXEEXT): $(taway_OBJECTS) $(taway_DEPENDENCIES) $(EXTRA_taway_DEPENDENCIES)
+ @rm -f taway$(EXEEXT)
+ $(LINK) $(taway_OBJECTS) $(taway_LDADD) $(LIBS)
+tbuildopt$(EXEEXT): $(tbuildopt_OBJECTS) $(tbuildopt_DEPENDENCIES) $(EXTRA_tbuildopt_DEPENDENCIES)
+ @rm -f tbuildopt$(EXEEXT)
+ $(LINK) $(tbuildopt_OBJECTS) $(tbuildopt_LDADD) $(LIBS)
+tcan_round$(EXEEXT): $(tcan_round_OBJECTS) $(tcan_round_DEPENDENCIES) $(EXTRA_tcan_round_DEPENDENCIES)
+ @rm -f tcan_round$(EXEEXT)
+ $(LINK) $(tcan_round_OBJECTS) $(tcan_round_LDADD) $(LIBS)
+tcbrt$(EXEEXT): $(tcbrt_OBJECTS) $(tcbrt_DEPENDENCIES) $(EXTRA_tcbrt_DEPENDENCIES)
+ @rm -f tcbrt$(EXEEXT)
+ $(LINK) $(tcbrt_OBJECTS) $(tcbrt_LDADD) $(LIBS)
+tcheck$(EXEEXT): $(tcheck_OBJECTS) $(tcheck_DEPENDENCIES) $(EXTRA_tcheck_DEPENDENCIES)
+ @rm -f tcheck$(EXEEXT)
+ $(LINK) $(tcheck_OBJECTS) $(tcheck_LDADD) $(LIBS)
+tcmp$(EXEEXT): $(tcmp_OBJECTS) $(tcmp_DEPENDENCIES) $(EXTRA_tcmp_DEPENDENCIES)
+ @rm -f tcmp$(EXEEXT)
+ $(LINK) $(tcmp_OBJECTS) $(tcmp_LDADD) $(LIBS)
+tcmp2$(EXEEXT): $(tcmp2_OBJECTS) $(tcmp2_DEPENDENCIES) $(EXTRA_tcmp2_DEPENDENCIES)
+ @rm -f tcmp2$(EXEEXT)
+ $(LINK) $(tcmp2_OBJECTS) $(tcmp2_LDADD) $(LIBS)
+tcmp_d$(EXEEXT): $(tcmp_d_OBJECTS) $(tcmp_d_DEPENDENCIES) $(EXTRA_tcmp_d_DEPENDENCIES)
+ @rm -f tcmp_d$(EXEEXT)
+ $(LINK) $(tcmp_d_OBJECTS) $(tcmp_d_LDADD) $(LIBS)
+tcmp_ld$(EXEEXT): $(tcmp_ld_OBJECTS) $(tcmp_ld_DEPENDENCIES) $(EXTRA_tcmp_ld_DEPENDENCIES)
+ @rm -f tcmp_ld$(EXEEXT)
+ $(LINK) $(tcmp_ld_OBJECTS) $(tcmp_ld_LDADD) $(LIBS)
+tcmp_ui$(EXEEXT): $(tcmp_ui_OBJECTS) $(tcmp_ui_DEPENDENCIES) $(EXTRA_tcmp_ui_DEPENDENCIES)
+ @rm -f tcmp_ui$(EXEEXT)
+ $(LINK) $(tcmp_ui_OBJECTS) $(tcmp_ui_LDADD) $(LIBS)
+tcmpabs$(EXEEXT): $(tcmpabs_OBJECTS) $(tcmpabs_DEPENDENCIES) $(EXTRA_tcmpabs_DEPENDENCIES)
+ @rm -f tcmpabs$(EXEEXT)
+ $(LINK) $(tcmpabs_OBJECTS) $(tcmpabs_LDADD) $(LIBS)
+tcomparisons$(EXEEXT): $(tcomparisons_OBJECTS) $(tcomparisons_DEPENDENCIES) $(EXTRA_tcomparisons_DEPENDENCIES)
+ @rm -f tcomparisons$(EXEEXT)
+ $(LINK) $(tcomparisons_OBJECTS) $(tcomparisons_LDADD) $(LIBS)
+tconst_catalan$(EXEEXT): $(tconst_catalan_OBJECTS) $(tconst_catalan_DEPENDENCIES) $(EXTRA_tconst_catalan_DEPENDENCIES)
+ @rm -f tconst_catalan$(EXEEXT)
+ $(LINK) $(tconst_catalan_OBJECTS) $(tconst_catalan_LDADD) $(LIBS)
+tconst_euler$(EXEEXT): $(tconst_euler_OBJECTS) $(tconst_euler_DEPENDENCIES) $(EXTRA_tconst_euler_DEPENDENCIES)
+ @rm -f tconst_euler$(EXEEXT)
+ $(LINK) $(tconst_euler_OBJECTS) $(tconst_euler_LDADD) $(LIBS)
+tconst_log2$(EXEEXT): $(tconst_log2_OBJECTS) $(tconst_log2_DEPENDENCIES) $(EXTRA_tconst_log2_DEPENDENCIES)
+ @rm -f tconst_log2$(EXEEXT)
+ $(LINK) $(tconst_log2_OBJECTS) $(tconst_log2_LDADD) $(LIBS)
+tconst_pi$(EXEEXT): $(tconst_pi_OBJECTS) $(tconst_pi_DEPENDENCIES) $(EXTRA_tconst_pi_DEPENDENCIES)
+ @rm -f tconst_pi$(EXEEXT)
+ $(LINK) $(tconst_pi_OBJECTS) $(tconst_pi_LDADD) $(LIBS)
+tcopysign$(EXEEXT): $(tcopysign_OBJECTS) $(tcopysign_DEPENDENCIES) $(EXTRA_tcopysign_DEPENDENCIES)
+ @rm -f tcopysign$(EXEEXT)
+ $(LINK) $(tcopysign_OBJECTS) $(tcopysign_LDADD) $(LIBS)
+tcos$(EXEEXT): $(tcos_OBJECTS) $(tcos_DEPENDENCIES) $(EXTRA_tcos_DEPENDENCIES)
+ @rm -f tcos$(EXEEXT)
+ $(LINK) $(tcos_OBJECTS) $(tcos_LDADD) $(LIBS)
+tcosh$(EXEEXT): $(tcosh_OBJECTS) $(tcosh_DEPENDENCIES) $(EXTRA_tcosh_DEPENDENCIES)
+ @rm -f tcosh$(EXEEXT)
+ $(LINK) $(tcosh_OBJECTS) $(tcosh_LDADD) $(LIBS)
+tcot$(EXEEXT): $(tcot_OBJECTS) $(tcot_DEPENDENCIES) $(EXTRA_tcot_DEPENDENCIES)
+ @rm -f tcot$(EXEEXT)
+ $(LINK) $(tcot_OBJECTS) $(tcot_LDADD) $(LIBS)
+tcoth$(EXEEXT): $(tcoth_OBJECTS) $(tcoth_DEPENDENCIES) $(EXTRA_tcoth_DEPENDENCIES)
+ @rm -f tcoth$(EXEEXT)
+ $(LINK) $(tcoth_OBJECTS) $(tcoth_LDADD) $(LIBS)
+tcsc$(EXEEXT): $(tcsc_OBJECTS) $(tcsc_DEPENDENCIES) $(EXTRA_tcsc_DEPENDENCIES)
+ @rm -f tcsc$(EXEEXT)
+ $(LINK) $(tcsc_OBJECTS) $(tcsc_LDADD) $(LIBS)
+tcsch$(EXEEXT): $(tcsch_OBJECTS) $(tcsch_DEPENDENCIES) $(EXTRA_tcsch_DEPENDENCIES)
+ @rm -f tcsch$(EXEEXT)
+ $(LINK) $(tcsch_OBJECTS) $(tcsch_LDADD) $(LIBS)
+td_div$(EXEEXT): $(td_div_OBJECTS) $(td_div_DEPENDENCIES) $(EXTRA_td_div_DEPENDENCIES)
+ @rm -f td_div$(EXEEXT)
+ $(LINK) $(td_div_OBJECTS) $(td_div_LDADD) $(LIBS)
+td_sub$(EXEEXT): $(td_sub_OBJECTS) $(td_sub_DEPENDENCIES) $(EXTRA_td_sub_DEPENDENCIES)
+ @rm -f td_sub$(EXEEXT)
+ $(LINK) $(td_sub_OBJECTS) $(td_sub_LDADD) $(LIBS)
+tdigamma$(EXEEXT): $(tdigamma_OBJECTS) $(tdigamma_DEPENDENCIES) $(EXTRA_tdigamma_DEPENDENCIES)
+ @rm -f tdigamma$(EXEEXT)
+ $(LINK) $(tdigamma_OBJECTS) $(tdigamma_LDADD) $(LIBS)
+tdim$(EXEEXT): $(tdim_OBJECTS) $(tdim_DEPENDENCIES) $(EXTRA_tdim_DEPENDENCIES)
+ @rm -f tdim$(EXEEXT)
+ $(LINK) $(tdim_OBJECTS) $(tdim_LDADD) $(LIBS)
+tdiv$(EXEEXT): $(tdiv_OBJECTS) $(tdiv_DEPENDENCIES) $(EXTRA_tdiv_DEPENDENCIES)
+ @rm -f tdiv$(EXEEXT)
+ $(LINK) $(tdiv_OBJECTS) $(tdiv_LDADD) $(LIBS)
+tdiv_d$(EXEEXT): $(tdiv_d_OBJECTS) $(tdiv_d_DEPENDENCIES) $(EXTRA_tdiv_d_DEPENDENCIES)
+ @rm -f tdiv_d$(EXEEXT)
+ $(LINK) $(tdiv_d_OBJECTS) $(tdiv_d_LDADD) $(LIBS)
+tdiv_ui$(EXEEXT): $(tdiv_ui_OBJECTS) $(tdiv_ui_DEPENDENCIES) $(EXTRA_tdiv_ui_DEPENDENCIES)
+ @rm -f tdiv_ui$(EXEEXT)
+ $(LINK) $(tdiv_ui_OBJECTS) $(tdiv_ui_LDADD) $(LIBS)
+teint$(EXEEXT): $(teint_OBJECTS) $(teint_DEPENDENCIES) $(EXTRA_teint_DEPENDENCIES)
+ @rm -f teint$(EXEEXT)
+ $(LINK) $(teint_OBJECTS) $(teint_LDADD) $(LIBS)
+teq$(EXEEXT): $(teq_OBJECTS) $(teq_DEPENDENCIES) $(EXTRA_teq_DEPENDENCIES)
+ @rm -f teq$(EXEEXT)
+ $(LINK) $(teq_OBJECTS) $(teq_LDADD) $(LIBS)
+terf$(EXEEXT): $(terf_OBJECTS) $(terf_DEPENDENCIES) $(EXTRA_terf_DEPENDENCIES)
+ @rm -f terf$(EXEEXT)
+ $(LINK) $(terf_OBJECTS) $(terf_LDADD) $(LIBS)
+texceptions$(EXEEXT): $(texceptions_OBJECTS) $(texceptions_DEPENDENCIES) $(EXTRA_texceptions_DEPENDENCIES)
+ @rm -f texceptions$(EXEEXT)
+ $(LINK) $(texceptions_OBJECTS) $(texceptions_LDADD) $(LIBS)
+texp$(EXEEXT): $(texp_OBJECTS) $(texp_DEPENDENCIES) $(EXTRA_texp_DEPENDENCIES)
+ @rm -f texp$(EXEEXT)
+ $(LINK) $(texp_OBJECTS) $(texp_LDADD) $(LIBS)
+texp10$(EXEEXT): $(texp10_OBJECTS) $(texp10_DEPENDENCIES) $(EXTRA_texp10_DEPENDENCIES)
+ @rm -f texp10$(EXEEXT)
+ $(LINK) $(texp10_OBJECTS) $(texp10_LDADD) $(LIBS)
+texp2$(EXEEXT): $(texp2_OBJECTS) $(texp2_DEPENDENCIES) $(EXTRA_texp2_DEPENDENCIES)
+ @rm -f texp2$(EXEEXT)
+ $(LINK) $(texp2_OBJECTS) $(texp2_LDADD) $(LIBS)
+texpm1$(EXEEXT): $(texpm1_OBJECTS) $(texpm1_DEPENDENCIES) $(EXTRA_texpm1_DEPENDENCIES)
+ @rm -f texpm1$(EXEEXT)
+ $(LINK) $(texpm1_OBJECTS) $(texpm1_LDADD) $(LIBS)
+tfactorial$(EXEEXT): $(tfactorial_OBJECTS) $(tfactorial_DEPENDENCIES) $(EXTRA_tfactorial_DEPENDENCIES)
+ @rm -f tfactorial$(EXEEXT)
+ $(LINK) $(tfactorial_OBJECTS) $(tfactorial_LDADD) $(LIBS)
+tfits$(EXEEXT): $(tfits_OBJECTS) $(tfits_DEPENDENCIES) $(EXTRA_tfits_DEPENDENCIES)
+ @rm -f tfits$(EXEEXT)
+ $(LINK) $(tfits_OBJECTS) $(tfits_LDADD) $(LIBS)
+tfma$(EXEEXT): $(tfma_OBJECTS) $(tfma_DEPENDENCIES) $(EXTRA_tfma_DEPENDENCIES)
+ @rm -f tfma$(EXEEXT)
+ $(LINK) $(tfma_OBJECTS) $(tfma_LDADD) $(LIBS)
+tfmod$(EXEEXT): $(tfmod_OBJECTS) $(tfmod_DEPENDENCIES) $(EXTRA_tfmod_DEPENDENCIES)
+ @rm -f tfmod$(EXEEXT)
+ $(LINK) $(tfmod_OBJECTS) $(tfmod_LDADD) $(LIBS)
+tfms$(EXEEXT): $(tfms_OBJECTS) $(tfms_DEPENDENCIES) $(EXTRA_tfms_DEPENDENCIES)
+ @rm -f tfms$(EXEEXT)
+ $(LINK) $(tfms_OBJECTS) $(tfms_LDADD) $(LIBS)
+tfprintf$(EXEEXT): $(tfprintf_OBJECTS) $(tfprintf_DEPENDENCIES) $(EXTRA_tfprintf_DEPENDENCIES)
+ @rm -f tfprintf$(EXEEXT)
+ $(LINK) $(tfprintf_OBJECTS) $(tfprintf_LDADD) $(LIBS)
+tfrac$(EXEEXT): $(tfrac_OBJECTS) $(tfrac_DEPENDENCIES) $(EXTRA_tfrac_DEPENDENCIES)
+ @rm -f tfrac$(EXEEXT)
+ $(LINK) $(tfrac_OBJECTS) $(tfrac_LDADD) $(LIBS)
+tfrexp$(EXEEXT): $(tfrexp_OBJECTS) $(tfrexp_DEPENDENCIES) $(EXTRA_tfrexp_DEPENDENCIES)
+ @rm -f tfrexp$(EXEEXT)
+ $(LINK) $(tfrexp_OBJECTS) $(tfrexp_LDADD) $(LIBS)
+tgamma$(EXEEXT): $(tgamma_OBJECTS) $(tgamma_DEPENDENCIES) $(EXTRA_tgamma_DEPENDENCIES)
+ @rm -f tgamma$(EXEEXT)
+ $(LINK) $(tgamma_OBJECTS) $(tgamma_LDADD) $(LIBS)
+tget_d$(EXEEXT): $(tget_d_OBJECTS) $(tget_d_DEPENDENCIES) $(EXTRA_tget_d_DEPENDENCIES)
+ @rm -f tget_d$(EXEEXT)
+ $(LINK) $(tget_d_OBJECTS) $(tget_d_LDADD) $(LIBS)
+tget_d_2exp$(EXEEXT): $(tget_d_2exp_OBJECTS) $(tget_d_2exp_DEPENDENCIES) $(EXTRA_tget_d_2exp_DEPENDENCIES)
+ @rm -f tget_d_2exp$(EXEEXT)
+ $(LINK) $(tget_d_2exp_OBJECTS) $(tget_d_2exp_LDADD) $(LIBS)
+tget_f$(EXEEXT): $(tget_f_OBJECTS) $(tget_f_DEPENDENCIES) $(EXTRA_tget_f_DEPENDENCIES)
+ @rm -f tget_f$(EXEEXT)
+ $(LINK) $(tget_f_OBJECTS) $(tget_f_LDADD) $(LIBS)
+tget_flt$(EXEEXT): $(tget_flt_OBJECTS) $(tget_flt_DEPENDENCIES) $(EXTRA_tget_flt_DEPENDENCIES)
+ @rm -f tget_flt$(EXEEXT)
+ $(LINK) $(tget_flt_OBJECTS) $(tget_flt_LDADD) $(LIBS)
+tget_ld_2exp$(EXEEXT): $(tget_ld_2exp_OBJECTS) $(tget_ld_2exp_DEPENDENCIES) $(EXTRA_tget_ld_2exp_DEPENDENCIES)
+ @rm -f tget_ld_2exp$(EXEEXT)
+ $(LINK) $(tget_ld_2exp_OBJECTS) $(tget_ld_2exp_LDADD) $(LIBS)
+tget_set_d64$(EXEEXT): $(tget_set_d64_OBJECTS) $(tget_set_d64_DEPENDENCIES) $(EXTRA_tget_set_d64_DEPENDENCIES)
+ @rm -f tget_set_d64$(EXEEXT)
+ $(LINK) $(tget_set_d64_OBJECTS) $(tget_set_d64_LDADD) $(LIBS)
+tget_sj$(EXEEXT): $(tget_sj_OBJECTS) $(tget_sj_DEPENDENCIES) $(EXTRA_tget_sj_DEPENDENCIES)
+ @rm -f tget_sj$(EXEEXT)
+ $(LINK) $(tget_sj_OBJECTS) $(tget_sj_LDADD) $(LIBS)
+tget_str$(EXEEXT): $(tget_str_OBJECTS) $(tget_str_DEPENDENCIES) $(EXTRA_tget_str_DEPENDENCIES)
+ @rm -f tget_str$(EXEEXT)
+ $(LINK) $(tget_str_OBJECTS) $(tget_str_LDADD) $(LIBS)
+tget_z$(EXEEXT): $(tget_z_OBJECTS) $(tget_z_DEPENDENCIES) $(EXTRA_tget_z_DEPENDENCIES)
+ @rm -f tget_z$(EXEEXT)
+ $(LINK) $(tget_z_OBJECTS) $(tget_z_LDADD) $(LIBS)
+tgmpop$(EXEEXT): $(tgmpop_OBJECTS) $(tgmpop_DEPENDENCIES) $(EXTRA_tgmpop_DEPENDENCIES)
+ @rm -f tgmpop$(EXEEXT)
+ $(LINK) $(tgmpop_OBJECTS) $(tgmpop_LDADD) $(LIBS)
+tgrandom$(EXEEXT): $(tgrandom_OBJECTS) $(tgrandom_DEPENDENCIES) $(EXTRA_tgrandom_DEPENDENCIES)
+ @rm -f tgrandom$(EXEEXT)
+ $(LINK) $(tgrandom_OBJECTS) $(tgrandom_LDADD) $(LIBS)
+thyperbolic$(EXEEXT): $(thyperbolic_OBJECTS) $(thyperbolic_DEPENDENCIES) $(EXTRA_thyperbolic_DEPENDENCIES)
+ @rm -f thyperbolic$(EXEEXT)
+ $(LINK) $(thyperbolic_OBJECTS) $(thyperbolic_LDADD) $(LIBS)
+thypot$(EXEEXT): $(thypot_OBJECTS) $(thypot_DEPENDENCIES) $(EXTRA_thypot_DEPENDENCIES)
+ @rm -f thypot$(EXEEXT)
+ $(LINK) $(thypot_OBJECTS) $(thypot_LDADD) $(LIBS)
+tinits$(EXEEXT): $(tinits_OBJECTS) $(tinits_DEPENDENCIES) $(EXTRA_tinits_DEPENDENCIES)
+ @rm -f tinits$(EXEEXT)
+ $(LINK) $(tinits_OBJECTS) $(tinits_LDADD) $(LIBS)
+tinp_str$(EXEEXT): $(tinp_str_OBJECTS) $(tinp_str_DEPENDENCIES) $(EXTRA_tinp_str_DEPENDENCIES)
+ @rm -f tinp_str$(EXEEXT)
+ $(LINK) $(tinp_str_OBJECTS) $(tinp_str_LDADD) $(LIBS)
+tinternals$(EXEEXT): $(tinternals_OBJECTS) $(tinternals_DEPENDENCIES) $(EXTRA_tinternals_DEPENDENCIES)
+ @rm -f tinternals$(EXEEXT)
+ $(LINK) $(tinternals_OBJECTS) $(tinternals_LDADD) $(LIBS)
+tisnan$(EXEEXT): $(tisnan_OBJECTS) $(tisnan_DEPENDENCIES) $(EXTRA_tisnan_DEPENDENCIES)
+ @rm -f tisnan$(EXEEXT)
+ $(LINK) $(tisnan_OBJECTS) $(tisnan_LDADD) $(LIBS)
+tisqrt$(EXEEXT): $(tisqrt_OBJECTS) $(tisqrt_DEPENDENCIES) $(EXTRA_tisqrt_DEPENDENCIES)
+ @rm -f tisqrt$(EXEEXT)
+ $(LINK) $(tisqrt_OBJECTS) $(tisqrt_LDADD) $(LIBS)
+tj0$(EXEEXT): $(tj0_OBJECTS) $(tj0_DEPENDENCIES) $(EXTRA_tj0_DEPENDENCIES)
+ @rm -f tj0$(EXEEXT)
+ $(LINK) $(tj0_OBJECTS) $(tj0_LDADD) $(LIBS)
+tj1$(EXEEXT): $(tj1_OBJECTS) $(tj1_DEPENDENCIES) $(EXTRA_tj1_DEPENDENCIES)
+ @rm -f tj1$(EXEEXT)
+ $(LINK) $(tj1_OBJECTS) $(tj1_LDADD) $(LIBS)
+tjn$(EXEEXT): $(tjn_OBJECTS) $(tjn_DEPENDENCIES) $(EXTRA_tjn_DEPENDENCIES)
+ @rm -f tjn$(EXEEXT)
+ $(LINK) $(tjn_OBJECTS) $(tjn_LDADD) $(LIBS)
+tl2b$(EXEEXT): $(tl2b_OBJECTS) $(tl2b_DEPENDENCIES) $(EXTRA_tl2b_DEPENDENCIES)
+ @rm -f tl2b$(EXEEXT)
+ $(LINK) $(tl2b_OBJECTS) $(tl2b_LDADD) $(LIBS)
+tlgamma$(EXEEXT): $(tlgamma_OBJECTS) $(tlgamma_DEPENDENCIES) $(EXTRA_tlgamma_DEPENDENCIES)
+ @rm -f tlgamma$(EXEEXT)
+ $(LINK) $(tlgamma_OBJECTS) $(tlgamma_LDADD) $(LIBS)
+tli2$(EXEEXT): $(tli2_OBJECTS) $(tli2_DEPENDENCIES) $(EXTRA_tli2_DEPENDENCIES)
+ @rm -f tli2$(EXEEXT)
+ $(LINK) $(tli2_OBJECTS) $(tli2_LDADD) $(LIBS)
+tlngamma$(EXEEXT): $(tlngamma_OBJECTS) $(tlngamma_DEPENDENCIES) $(EXTRA_tlngamma_DEPENDENCIES)
+ @rm -f tlngamma$(EXEEXT)
+ $(LINK) $(tlngamma_OBJECTS) $(tlngamma_LDADD) $(LIBS)
+tlog$(EXEEXT): $(tlog_OBJECTS) $(tlog_DEPENDENCIES) $(EXTRA_tlog_DEPENDENCIES)
+ @rm -f tlog$(EXEEXT)
+ $(LINK) $(tlog_OBJECTS) $(tlog_LDADD) $(LIBS)
+tlog10$(EXEEXT): $(tlog10_OBJECTS) $(tlog10_DEPENDENCIES) $(EXTRA_tlog10_DEPENDENCIES)
+ @rm -f tlog10$(EXEEXT)
+ $(LINK) $(tlog10_OBJECTS) $(tlog10_LDADD) $(LIBS)
+tlog1p$(EXEEXT): $(tlog1p_OBJECTS) $(tlog1p_DEPENDENCIES) $(EXTRA_tlog1p_DEPENDENCIES)
+ @rm -f tlog1p$(EXEEXT)
+ $(LINK) $(tlog1p_OBJECTS) $(tlog1p_LDADD) $(LIBS)
+tlog2$(EXEEXT): $(tlog2_OBJECTS) $(tlog2_DEPENDENCIES) $(EXTRA_tlog2_DEPENDENCIES)
+ @rm -f tlog2$(EXEEXT)
+ $(LINK) $(tlog2_OBJECTS) $(tlog2_LDADD) $(LIBS)
+tmin_prec$(EXEEXT): $(tmin_prec_OBJECTS) $(tmin_prec_DEPENDENCIES) $(EXTRA_tmin_prec_DEPENDENCIES)
+ @rm -f tmin_prec$(EXEEXT)
+ $(LINK) $(tmin_prec_OBJECTS) $(tmin_prec_LDADD) $(LIBS)
+tminmax$(EXEEXT): $(tminmax_OBJECTS) $(tminmax_DEPENDENCIES) $(EXTRA_tminmax_DEPENDENCIES)
+ @rm -f tminmax$(EXEEXT)
+ $(LINK) $(tminmax_OBJECTS) $(tminmax_LDADD) $(LIBS)
+tmodf$(EXEEXT): $(tmodf_OBJECTS) $(tmodf_DEPENDENCIES) $(EXTRA_tmodf_DEPENDENCIES)
+ @rm -f tmodf$(EXEEXT)
+ $(LINK) $(tmodf_OBJECTS) $(tmodf_LDADD) $(LIBS)
+tmul$(EXEEXT): $(tmul_OBJECTS) $(tmul_DEPENDENCIES) $(EXTRA_tmul_DEPENDENCIES)
+ @rm -f tmul$(EXEEXT)
+ $(LINK) $(tmul_OBJECTS) $(tmul_LDADD) $(LIBS)
+tmul_2exp$(EXEEXT): $(tmul_2exp_OBJECTS) $(tmul_2exp_DEPENDENCIES) $(EXTRA_tmul_2exp_DEPENDENCIES)
+ @rm -f tmul_2exp$(EXEEXT)
+ $(LINK) $(tmul_2exp_OBJECTS) $(tmul_2exp_LDADD) $(LIBS)
+tmul_d$(EXEEXT): $(tmul_d_OBJECTS) $(tmul_d_DEPENDENCIES) $(EXTRA_tmul_d_DEPENDENCIES)
+ @rm -f tmul_d$(EXEEXT)
+ $(LINK) $(tmul_d_OBJECTS) $(tmul_d_LDADD) $(LIBS)
+tmul_ui$(EXEEXT): $(tmul_ui_OBJECTS) $(tmul_ui_DEPENDENCIES) $(EXTRA_tmul_ui_DEPENDENCIES)
+ @rm -f tmul_ui$(EXEEXT)
+ $(LINK) $(tmul_ui_OBJECTS) $(tmul_ui_LDADD) $(LIBS)
+tnext$(EXEEXT): $(tnext_OBJECTS) $(tnext_DEPENDENCIES) $(EXTRA_tnext_DEPENDENCIES)
+ @rm -f tnext$(EXEEXT)
+ $(LINK) $(tnext_OBJECTS) $(tnext_LDADD) $(LIBS)
+tout_str$(EXEEXT): $(tout_str_OBJECTS) $(tout_str_DEPENDENCIES) $(EXTRA_tout_str_DEPENDENCIES)
+ @rm -f tout_str$(EXEEXT)
+ $(LINK) $(tout_str_OBJECTS) $(tout_str_LDADD) $(LIBS)
+toutimpl$(EXEEXT): $(toutimpl_OBJECTS) $(toutimpl_DEPENDENCIES) $(EXTRA_toutimpl_DEPENDENCIES)
+ @rm -f toutimpl$(EXEEXT)
+ $(LINK) $(toutimpl_OBJECTS) $(toutimpl_LDADD) $(LIBS)
+tpow$(EXEEXT): $(tpow_OBJECTS) $(tpow_DEPENDENCIES) $(EXTRA_tpow_DEPENDENCIES)
+ @rm -f tpow$(EXEEXT)
+ $(LINK) $(tpow_OBJECTS) $(tpow_LDADD) $(LIBS)
+tpow3$(EXEEXT): $(tpow3_OBJECTS) $(tpow3_DEPENDENCIES) $(EXTRA_tpow3_DEPENDENCIES)
+ @rm -f tpow3$(EXEEXT)
+ $(LINK) $(tpow3_OBJECTS) $(tpow3_LDADD) $(LIBS)
+tpow_all$(EXEEXT): $(tpow_all_OBJECTS) $(tpow_all_DEPENDENCIES) $(EXTRA_tpow_all_DEPENDENCIES)
+ @rm -f tpow_all$(EXEEXT)
+ $(LINK) $(tpow_all_OBJECTS) $(tpow_all_LDADD) $(LIBS)
+tpow_z$(EXEEXT): $(tpow_z_OBJECTS) $(tpow_z_DEPENDENCIES) $(EXTRA_tpow_z_DEPENDENCIES)
+ @rm -f tpow_z$(EXEEXT)
+ $(LINK) $(tpow_z_OBJECTS) $(tpow_z_LDADD) $(LIBS)
+tprintf$(EXEEXT): $(tprintf_OBJECTS) $(tprintf_DEPENDENCIES) $(EXTRA_tprintf_DEPENDENCIES)
+ @rm -f tprintf$(EXEEXT)
+ $(LINK) $(tprintf_OBJECTS) $(tprintf_LDADD) $(LIBS)
+trandom$(EXEEXT): $(trandom_OBJECTS) $(trandom_DEPENDENCIES) $(EXTRA_trandom_DEPENDENCIES)
+ @rm -f trandom$(EXEEXT)
+ $(LINK) $(trandom_OBJECTS) $(trandom_LDADD) $(LIBS)
+trec_sqrt$(EXEEXT): $(trec_sqrt_OBJECTS) $(trec_sqrt_DEPENDENCIES) $(EXTRA_trec_sqrt_DEPENDENCIES)
+ @rm -f trec_sqrt$(EXEEXT)
+ $(LINK) $(trec_sqrt_OBJECTS) $(trec_sqrt_LDADD) $(LIBS)
+tremquo$(EXEEXT): $(tremquo_OBJECTS) $(tremquo_DEPENDENCIES) $(EXTRA_tremquo_DEPENDENCIES)
+ @rm -f tremquo$(EXEEXT)
+ $(LINK) $(tremquo_OBJECTS) $(tremquo_LDADD) $(LIBS)
+trint$(EXEEXT): $(trint_OBJECTS) $(trint_DEPENDENCIES) $(EXTRA_trint_DEPENDENCIES)
+ @rm -f trint$(EXEEXT)
+ $(LINK) $(trint_OBJECTS) $(trint_LDADD) $(LIBS)
+troot$(EXEEXT): $(troot_OBJECTS) $(troot_DEPENDENCIES) $(EXTRA_troot_DEPENDENCIES)
+ @rm -f troot$(EXEEXT)
+ $(LINK) $(troot_OBJECTS) $(troot_LDADD) $(LIBS)
+tround_prec$(EXEEXT): $(tround_prec_OBJECTS) $(tround_prec_DEPENDENCIES) $(EXTRA_tround_prec_DEPENDENCIES)
+ @rm -f tround_prec$(EXEEXT)
+ $(LINK) $(tround_prec_OBJECTS) $(tround_prec_LDADD) $(LIBS)
+tsec$(EXEEXT): $(tsec_OBJECTS) $(tsec_DEPENDENCIES) $(EXTRA_tsec_DEPENDENCIES)
+ @rm -f tsec$(EXEEXT)
+ $(LINK) $(tsec_OBJECTS) $(tsec_LDADD) $(LIBS)
+tsech$(EXEEXT): $(tsech_OBJECTS) $(tsech_DEPENDENCIES) $(EXTRA_tsech_DEPENDENCIES)
+ @rm -f tsech$(EXEEXT)
+ $(LINK) $(tsech_OBJECTS) $(tsech_LDADD) $(LIBS)
+tset$(EXEEXT): $(tset_OBJECTS) $(tset_DEPENDENCIES) $(EXTRA_tset_DEPENDENCIES)
+ @rm -f tset$(EXEEXT)
+ $(LINK) $(tset_OBJECTS) $(tset_LDADD) $(LIBS)
+tset_d$(EXEEXT): $(tset_d_OBJECTS) $(tset_d_DEPENDENCIES) $(EXTRA_tset_d_DEPENDENCIES)
+ @rm -f tset_d$(EXEEXT)
+ $(LINK) $(tset_d_OBJECTS) $(tset_d_LDADD) $(LIBS)
+tset_exp$(EXEEXT): $(tset_exp_OBJECTS) $(tset_exp_DEPENDENCIES) $(EXTRA_tset_exp_DEPENDENCIES)
+ @rm -f tset_exp$(EXEEXT)
+ $(LINK) $(tset_exp_OBJECTS) $(tset_exp_LDADD) $(LIBS)
+tset_f$(EXEEXT): $(tset_f_OBJECTS) $(tset_f_DEPENDENCIES) $(EXTRA_tset_f_DEPENDENCIES)
+ @rm -f tset_f$(EXEEXT)
+ $(LINK) $(tset_f_OBJECTS) $(tset_f_LDADD) $(LIBS)
+tset_ld$(EXEEXT): $(tset_ld_OBJECTS) $(tset_ld_DEPENDENCIES) $(EXTRA_tset_ld_DEPENDENCIES)
+ @rm -f tset_ld$(EXEEXT)
+ $(LINK) $(tset_ld_OBJECTS) $(tset_ld_LDADD) $(LIBS)
+tset_q$(EXEEXT): $(tset_q_OBJECTS) $(tset_q_DEPENDENCIES) $(EXTRA_tset_q_DEPENDENCIES)
+ @rm -f tset_q$(EXEEXT)
+ $(LINK) $(tset_q_OBJECTS) $(tset_q_LDADD) $(LIBS)
+tset_si$(EXEEXT): $(tset_si_OBJECTS) $(tset_si_DEPENDENCIES) $(EXTRA_tset_si_DEPENDENCIES)
+ @rm -f tset_si$(EXEEXT)
+ $(LINK) $(tset_si_OBJECTS) $(tset_si_LDADD) $(LIBS)
+tset_sj$(EXEEXT): $(tset_sj_OBJECTS) $(tset_sj_DEPENDENCIES) $(EXTRA_tset_sj_DEPENDENCIES)
+ @rm -f tset_sj$(EXEEXT)
+ $(LINK) $(tset_sj_OBJECTS) $(tset_sj_LDADD) $(LIBS)
+tset_str$(EXEEXT): $(tset_str_OBJECTS) $(tset_str_DEPENDENCIES) $(EXTRA_tset_str_DEPENDENCIES)
+ @rm -f tset_str$(EXEEXT)
+ $(LINK) $(tset_str_OBJECTS) $(tset_str_LDADD) $(LIBS)
+tset_z$(EXEEXT): $(tset_z_OBJECTS) $(tset_z_DEPENDENCIES) $(EXTRA_tset_z_DEPENDENCIES)
+ @rm -f tset_z$(EXEEXT)
+ $(LINK) $(tset_z_OBJECTS) $(tset_z_LDADD) $(LIBS)
+tset_z_exp$(EXEEXT): $(tset_z_exp_OBJECTS) $(tset_z_exp_DEPENDENCIES) $(EXTRA_tset_z_exp_DEPENDENCIES)
+ @rm -f tset_z_exp$(EXEEXT)
+ $(LINK) $(tset_z_exp_OBJECTS) $(tset_z_exp_LDADD) $(LIBS)
+tsgn$(EXEEXT): $(tsgn_OBJECTS) $(tsgn_DEPENDENCIES) $(EXTRA_tsgn_DEPENDENCIES)
+ @rm -f tsgn$(EXEEXT)
+ $(LINK) $(tsgn_OBJECTS) $(tsgn_LDADD) $(LIBS)
+tsi_op$(EXEEXT): $(tsi_op_OBJECTS) $(tsi_op_DEPENDENCIES) $(EXTRA_tsi_op_DEPENDENCIES)
+ @rm -f tsi_op$(EXEEXT)
+ $(LINK) $(tsi_op_OBJECTS) $(tsi_op_LDADD) $(LIBS)
+tsin$(EXEEXT): $(tsin_OBJECTS) $(tsin_DEPENDENCIES) $(EXTRA_tsin_DEPENDENCIES)
+ @rm -f tsin$(EXEEXT)
+ $(LINK) $(tsin_OBJECTS) $(tsin_LDADD) $(LIBS)
+tsin_cos$(EXEEXT): $(tsin_cos_OBJECTS) $(tsin_cos_DEPENDENCIES) $(EXTRA_tsin_cos_DEPENDENCIES)
+ @rm -f tsin_cos$(EXEEXT)
+ $(LINK) $(tsin_cos_OBJECTS) $(tsin_cos_LDADD) $(LIBS)
+tsinh$(EXEEXT): $(tsinh_OBJECTS) $(tsinh_DEPENDENCIES) $(EXTRA_tsinh_DEPENDENCIES)
+ @rm -f tsinh$(EXEEXT)
+ $(LINK) $(tsinh_OBJECTS) $(tsinh_LDADD) $(LIBS)
+tsinh_cosh$(EXEEXT): $(tsinh_cosh_OBJECTS) $(tsinh_cosh_DEPENDENCIES) $(EXTRA_tsinh_cosh_DEPENDENCIES)
+ @rm -f tsinh_cosh$(EXEEXT)
+ $(LINK) $(tsinh_cosh_OBJECTS) $(tsinh_cosh_LDADD) $(LIBS)
+tsprintf$(EXEEXT): $(tsprintf_OBJECTS) $(tsprintf_DEPENDENCIES) $(EXTRA_tsprintf_DEPENDENCIES)
+ @rm -f tsprintf$(EXEEXT)
+ $(LINK) $(tsprintf_OBJECTS) $(tsprintf_LDADD) $(LIBS)
+tsqr$(EXEEXT): $(tsqr_OBJECTS) $(tsqr_DEPENDENCIES) $(EXTRA_tsqr_DEPENDENCIES)
+ @rm -f tsqr$(EXEEXT)
+ $(LINK) $(tsqr_OBJECTS) $(tsqr_LDADD) $(LIBS)
+tsqrt$(EXEEXT): $(tsqrt_OBJECTS) $(tsqrt_DEPENDENCIES) $(EXTRA_tsqrt_DEPENDENCIES)
+ @rm -f tsqrt$(EXEEXT)
+ $(LINK) $(tsqrt_OBJECTS) $(tsqrt_LDADD) $(LIBS)
+tsqrt_ui$(EXEEXT): $(tsqrt_ui_OBJECTS) $(tsqrt_ui_DEPENDENCIES) $(EXTRA_tsqrt_ui_DEPENDENCIES)
+ @rm -f tsqrt_ui$(EXEEXT)
+ $(LINK) $(tsqrt_ui_OBJECTS) $(tsqrt_ui_LDADD) $(LIBS)
+tstckintc$(EXEEXT): $(tstckintc_OBJECTS) $(tstckintc_DEPENDENCIES) $(EXTRA_tstckintc_DEPENDENCIES)
+ @rm -f tstckintc$(EXEEXT)
+ $(LINK) $(tstckintc_OBJECTS) $(tstckintc_LDADD) $(LIBS)
+tstdint$(EXEEXT): $(tstdint_OBJECTS) $(tstdint_DEPENDENCIES) $(EXTRA_tstdint_DEPENDENCIES)
+ @rm -f tstdint$(EXEEXT)
+ $(LINK) $(tstdint_OBJECTS) $(tstdint_LDADD) $(LIBS)
+tstrtofr$(EXEEXT): $(tstrtofr_OBJECTS) $(tstrtofr_DEPENDENCIES) $(EXTRA_tstrtofr_DEPENDENCIES)
+ @rm -f tstrtofr$(EXEEXT)
+ $(LINK) $(tstrtofr_OBJECTS) $(tstrtofr_LDADD) $(LIBS)
+tsub$(EXEEXT): $(tsub_OBJECTS) $(tsub_DEPENDENCIES) $(EXTRA_tsub_DEPENDENCIES)
+ @rm -f tsub$(EXEEXT)
+ $(LINK) $(tsub_OBJECTS) $(tsub_LDADD) $(LIBS)
+tsub1sp$(EXEEXT): $(tsub1sp_OBJECTS) $(tsub1sp_DEPENDENCIES) $(EXTRA_tsub1sp_DEPENDENCIES)
+ @rm -f tsub1sp$(EXEEXT)
+ $(LINK) $(tsub1sp_OBJECTS) $(tsub1sp_LDADD) $(LIBS)
+tsub_d$(EXEEXT): $(tsub_d_OBJECTS) $(tsub_d_DEPENDENCIES) $(EXTRA_tsub_d_DEPENDENCIES)
+ @rm -f tsub_d$(EXEEXT)
+ $(LINK) $(tsub_d_OBJECTS) $(tsub_d_LDADD) $(LIBS)
+tsub_ui$(EXEEXT): $(tsub_ui_OBJECTS) $(tsub_ui_DEPENDENCIES) $(EXTRA_tsub_ui_DEPENDENCIES)
+ @rm -f tsub_ui$(EXEEXT)
+ $(LINK) $(tsub_ui_OBJECTS) $(tsub_ui_LDADD) $(LIBS)
+tsubnormal$(EXEEXT): $(tsubnormal_OBJECTS) $(tsubnormal_DEPENDENCIES) $(EXTRA_tsubnormal_DEPENDENCIES)
+ @rm -f tsubnormal$(EXEEXT)
+ $(LINK) $(tsubnormal_OBJECTS) $(tsubnormal_LDADD) $(LIBS)
+tsum$(EXEEXT): $(tsum_OBJECTS) $(tsum_DEPENDENCIES) $(EXTRA_tsum_DEPENDENCIES)
+ @rm -f tsum$(EXEEXT)
+ $(LINK) $(tsum_OBJECTS) $(tsum_LDADD) $(LIBS)
+tswap$(EXEEXT): $(tswap_OBJECTS) $(tswap_DEPENDENCIES) $(EXTRA_tswap_DEPENDENCIES)
+ @rm -f tswap$(EXEEXT)
+ $(LINK) $(tswap_OBJECTS) $(tswap_LDADD) $(LIBS)
+ttan$(EXEEXT): $(ttan_OBJECTS) $(ttan_DEPENDENCIES) $(EXTRA_ttan_DEPENDENCIES)
+ @rm -f ttan$(EXEEXT)
+ $(LINK) $(ttan_OBJECTS) $(ttan_LDADD) $(LIBS)
+ttanh$(EXEEXT): $(ttanh_OBJECTS) $(ttanh_DEPENDENCIES) $(EXTRA_ttanh_DEPENDENCIES)
+ @rm -f ttanh$(EXEEXT)
+ $(LINK) $(ttanh_OBJECTS) $(ttanh_LDADD) $(LIBS)
+ttrunc$(EXEEXT): $(ttrunc_OBJECTS) $(ttrunc_DEPENDENCIES) $(EXTRA_ttrunc_DEPENDENCIES)
+ @rm -f ttrunc$(EXEEXT)
+ $(LINK) $(ttrunc_OBJECTS) $(ttrunc_LDADD) $(LIBS)
+tui_div$(EXEEXT): $(tui_div_OBJECTS) $(tui_div_DEPENDENCIES) $(EXTRA_tui_div_DEPENDENCIES)
+ @rm -f tui_div$(EXEEXT)
+ $(LINK) $(tui_div_OBJECTS) $(tui_div_LDADD) $(LIBS)
+tui_pow$(EXEEXT): $(tui_pow_OBJECTS) $(tui_pow_DEPENDENCIES) $(EXTRA_tui_pow_DEPENDENCIES)
+ @rm -f tui_pow$(EXEEXT)
+ $(LINK) $(tui_pow_OBJECTS) $(tui_pow_LDADD) $(LIBS)
+tui_sub$(EXEEXT): $(tui_sub_OBJECTS) $(tui_sub_DEPENDENCIES) $(EXTRA_tui_sub_DEPENDENCIES)
+ @rm -f tui_sub$(EXEEXT)
+ $(LINK) $(tui_sub_OBJECTS) $(tui_sub_LDADD) $(LIBS)
+turandom$(EXEEXT): $(turandom_OBJECTS) $(turandom_DEPENDENCIES) $(EXTRA_turandom_DEPENDENCIES)
+ @rm -f turandom$(EXEEXT)
+ $(LINK) $(turandom_OBJECTS) $(turandom_LDADD) $(LIBS)
+tvalist$(EXEEXT): $(tvalist_OBJECTS) $(tvalist_DEPENDENCIES) $(EXTRA_tvalist_DEPENDENCIES)
+ @rm -f tvalist$(EXEEXT)
+ $(LINK) $(tvalist_OBJECTS) $(tvalist_LDADD) $(LIBS)
+tversion$(EXEEXT): $(tversion_OBJECTS) $(tversion_DEPENDENCIES) $(EXTRA_tversion_DEPENDENCIES)
+ @rm -f tversion$(EXEEXT)
+ $(LINK) $(tversion_OBJECTS) $(tversion_LDADD) $(LIBS)
+ty0$(EXEEXT): $(ty0_OBJECTS) $(ty0_DEPENDENCIES) $(EXTRA_ty0_DEPENDENCIES)
+ @rm -f ty0$(EXEEXT)
+ $(LINK) $(ty0_OBJECTS) $(ty0_LDADD) $(LIBS)
+ty1$(EXEEXT): $(ty1_OBJECTS) $(ty1_DEPENDENCIES) $(EXTRA_ty1_DEPENDENCIES)
+ @rm -f ty1$(EXEEXT)
+ $(LINK) $(ty1_OBJECTS) $(ty1_LDADD) $(LIBS)
+tyn$(EXEEXT): $(tyn_OBJECTS) $(tyn_DEPENDENCIES) $(EXTRA_tyn_DEPENDENCIES)
+ @rm -f tyn$(EXEEXT)
+ $(LINK) $(tyn_OBJECTS) $(tyn_LDADD) $(LIBS)
+tzeta$(EXEEXT): $(tzeta_OBJECTS) $(tzeta_DEPENDENCIES) $(EXTRA_tzeta_DEPENDENCIES)
+ @rm -f tzeta$(EXEEXT)
+ $(LINK) $(tzeta_OBJECTS) $(tzeta_LDADD) $(LIBS)
+tzeta_ui$(EXEEXT): $(tzeta_ui_OBJECTS) $(tzeta_ui_DEPENDENCIES) $(EXTRA_tzeta_ui_DEPENDENCIES)
+ @rm -f tzeta_ui$(EXEEXT)
+ $(LINK) $(tzeta_ui_OBJECTS) $(tzeta_ui_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp_str.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpf_compat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpfr_compat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reuse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rnd_mode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tabs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tacos.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tacosh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd1sp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd_d.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tadd_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tagm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tai.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tasin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tasinh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tatan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tatanh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/taway.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tbuildopt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcan_round.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcbrt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcheck.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp_d.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp_ld.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmp_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmpabs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcomparisons.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconst_catalan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconst_euler.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconst_log2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tconst_pi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcopysign.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcos.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcosh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcoth.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcsc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcsch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/td_div.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/td_sub.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdigamma.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdim.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv_d.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdiv_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/teint.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/teq.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/terf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texceptions.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texp10.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texp2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texpm1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfactorial.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfma.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfmod.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfms.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfrac.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfrexp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgamma.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_d.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_d_2exp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_f.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_flt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_ld_2exp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_set_d64.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_sj.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_str.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tget_z.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgmpop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgrandom.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thyperbolic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thypot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinp_str.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinternals.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tisnan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tisqrt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tj0.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tj1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjn.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tl2b.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlgamma.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tli2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlngamma.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog10.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog1p.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlog2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmin_prec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tminmax.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmodf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_2exp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_d.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmul_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnext.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tout_str.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/toutimpl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow3.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_all.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpow_z.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trandom.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trec_sqrt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tremquo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trint.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/troot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tround_prec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsech.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_d.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_exp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_f.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_ld.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_q.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_si.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_sj.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_str.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_z.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tset_z_exp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsgn.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsi_op.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsin_cos.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsinh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsinh_cosh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsqr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsqrt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsqrt_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tstckintc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tstdint.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tstrtofr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub1sp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub_d.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsub_ui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsubnormal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsum.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tswap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttanh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttrunc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tui_div.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tui_pow.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tui_sub.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/turandom.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tvalist.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tversion.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ty0.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ty1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tyn.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tzeta.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tzeta_ui.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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_LTLIBRARIES) $(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:
+
+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-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -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 -rf ./$(DEPDIR)
+ -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 all all-am check check-TESTS check-am clean \
+ clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \
+ clean-libtool ctags 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 \
+ tags uninstall uninstall-am
+
+
+$(top_builddir)/src/libmpfr.la:
+ cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libmpfr.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/mpfr/tests/cmp_str.c b/mpfr/tests/cmp_str.c
new file mode 100644
index 0000000000..45ac3c7f22
--- /dev/null
+++ b/mpfr/tests/cmp_str.c
@@ -0,0 +1,37 @@
+/* mpfr_cmp_str -- compare a floating-point number with a string.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-test.h"
+
+int
+mpfr_cmp_str (mpfr_srcptr x, const char *s, int base, mpfr_rnd_t rnd)
+{
+ mpfr_t y;
+ int res;
+
+ MPFR_ASSERTN (!MPFR_IS_NAN (x));
+ mpfr_init2 (y, MPFR_PREC(x));
+ mpfr_set_str (y, s, base, rnd);
+ res = mpfr_cmp (x,y);
+ mpfr_clear (y);
+ return res;
+}
diff --git a/mpfr/tests/inp_str.data b/mpfr/tests/inp_str.data
new file mode 100644
index 0000000000..31e81c5cc5
--- /dev/null
+++ b/mpfr/tests/inp_str.data
@@ -0,0 +1,64 @@
+3.1415E4
+3.14160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E4
+this_is_an_invalid_float
+1.0010010100001110100101001110011010111011100001110010e226
+2.0120022122100022221001012120111010e142
+1.02110032211032122323201302e113
+1.43422433221034224112212e97
+2.245023334051130112541e87
+3.0214031231425640423e80
+2.224164516327341620e75
+2.16278308831176433e71
+1.2344999999999999e68
+2.5768519130417743@65
+1.326a50b3b9b311a@63
+1.4ca424800281ca0@61
+2.d44d2c475c1617@59
+b.4e8eae45eec494@57
+4.943a539aee1c8@56
+2.a69b19309ce43@55
+2.08b6320agf513@54
+2.18igbef497b79@53
+2.eg92a193d6jib@52
+4.bcj53i4dg133i@51
+9.7aee6ife1hgc@50
+1.065g326jbmm6@50
+2.l9dfn9kk1l6k@49
+9.jcnhb3me6c6m@48
+1.ci74dmge82kb@48
+6.f8h98p15fd2p@47
+1.57pn1af15bcb@47
+6.i3h3gqn3sp0@46
+1.bnhlsj9haq1@46
+9.h60jmhep7e9@45
+2.98eijjbn1p0@45
+i.u9r3j72f706@44
+5.2vxma61rnia@44
+1.epbr7wcjrks@44
+e.t2lm57i7hol@43
+4.KOJ1KXDLOD4@43
+1.H11SSC49aK9@43
+I.IWc1P7E0LQ8@42
+6.FBLVIEPHDc@42
+2.AV3VN4CK5A@42
+Y.MLABZPIMQ8@41
+D.6dIaKL16KV@41
+5.5RIZ3BGFbB@41
+2.1bIDPOihRN@41
+c.5SPGTF1gcJ@40
+G.60Khc9JPg1@40
+6.jNOlekhHB9@40
+3.2B39MUfSUI@40
+1.HhIJK7WJnh@40
+V.HkOThmcRf8@39
+E.aOdo3XbWH0@39
+6.qaNNZOE7Dd@39
+3.KAITW0C2kr@39
+1.ZdacKp9sIh@39
+j.ff6t2aeHht@38
+N.Jl6DgUeeZA@38
+C.3GakhvVNYH@38
+6.HTqomOD3Rh@38
+3.JSeUbAAtE@38
+1.lD6kuqhV0@38
+x.I7kYxn4IR@37
diff --git a/mpfr/tests/memory.c b/mpfr/tests/memory.c
new file mode 100644
index 0000000000..2b7465198f
--- /dev/null
+++ b/mpfr/tests/memory.c
@@ -0,0 +1,193 @@
+/* Memory allocation used during tests.
+
+Copyright 2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Note: this file comes from GMP's tests/memory.c */
+
+#include <stdio.h>
+#include <stdlib.h> /* for abort */
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+/* Each block allocated is a separate malloc, for the benefit of a redzoning
+ malloc debugger during development or when bug hunting.
+
+ Sizes passed when reallocating or freeing are checked (the default
+ routines don't care about these).
+
+ Memory leaks are checked by requiring that all blocks have been freed
+ when tests_memory_end() is called. Test programs must be sure to have
+ "clear"s for all temporary variables used. */
+
+struct header {
+ void *ptr;
+ size_t size;
+ struct header *next;
+};
+
+static struct header *tests_memory_list;
+
+/* Return a pointer to a pointer to the found block (so it can be updated
+ when unlinking). */
+static struct header **
+tests_memory_find (void *ptr)
+{
+ struct header **hp;
+
+ for (hp = &tests_memory_list; *hp != NULL; hp = &((*hp)->next))
+ if ((*hp)->ptr == ptr)
+ return hp;
+
+ return NULL;
+}
+
+/*
+static int
+tests_memory_valid (void *ptr)
+{
+ return (tests_memory_find (ptr) != NULL);
+}
+*/
+
+static void *
+tests_allocate (size_t size)
+{
+ struct header *h;
+
+ if (size == 0)
+ {
+ printf ("tests_allocate(): attempt to allocate 0 bytes\n");
+ abort ();
+ }
+
+ h = (struct header *) __gmp_default_allocate (sizeof (*h));
+ h->next = tests_memory_list;
+ tests_memory_list = h;
+
+ h->size = size;
+ h->ptr = __gmp_default_allocate (size);
+ return h->ptr;
+}
+
+static void *
+tests_reallocate (void *ptr, size_t old_size, size_t new_size)
+{
+ struct header **hp, *h;
+
+ if (new_size == 0)
+ {
+ printf ("tests_reallocate(): attempt to reallocate 0x%lX to 0 bytes\n",
+ (unsigned long) ptr);
+ abort ();
+ }
+
+ hp = tests_memory_find (ptr);
+ if (hp == NULL)
+ {
+ printf ("tests_reallocate(): attempt to reallocate bad pointer 0x%lX\n",
+ (unsigned long) ptr);
+ abort ();
+ }
+ h = *hp;
+
+ if (h->size != old_size)
+ {
+ /* Note: we should use the standard %zu to print sizes, but
+ this is not supported by old C implementations. */
+ printf ("tests_reallocate(): bad old size %lu, should be %lu\n",
+ (unsigned long) old_size, (unsigned long) h->size);
+ abort ();
+ }
+
+ h->size = new_size;
+ h->ptr = __gmp_default_reallocate (ptr, old_size, new_size);
+ return h->ptr;
+}
+
+static struct header **
+tests_free_find (void *ptr)
+{
+ struct header **hp = tests_memory_find (ptr);
+ if (hp == NULL)
+ {
+ printf ("tests_free(): attempt to free bad pointer 0x%lX\n",
+ (unsigned long) ptr);
+ abort ();
+ }
+ return hp;
+}
+
+static void
+tests_free_nosize (void *ptr)
+{
+ struct header **hp = tests_free_find (ptr);
+ struct header *h = *hp;
+
+ *hp = h->next; /* unlink */
+
+ __gmp_default_free (ptr, h->size);
+ __gmp_default_free (h, sizeof (*h));
+}
+
+static void
+tests_free (void *ptr, size_t size)
+{
+ struct header **hp = tests_free_find (ptr);
+ struct header *h = *hp;
+
+ if (h->size != size)
+ {
+ /* Note: we should use the standard %zu to print sizes, but
+ this is not supported by old C implementations. */
+ printf ("tests_free(): bad size %lu, should be %lu\n",
+ (unsigned long) size, (unsigned long) h->size);
+ abort ();
+ }
+
+ tests_free_nosize (ptr);
+}
+
+void
+tests_memory_start (void)
+{
+ tests_memory_list = NULL;
+ mp_set_memory_functions (tests_allocate, tests_reallocate, tests_free);
+}
+
+void
+tests_memory_end (void)
+{
+ if (tests_memory_list != NULL)
+ {
+ struct header *h;
+ unsigned count;
+
+ printf ("tests_memory_end(): not all memory freed\n");
+
+ count = 0;
+ for (h = tests_memory_list; h != NULL; h = h->next)
+ count++;
+
+ printf (" %u blocks remaining\n", count);
+ abort ();
+ }
+}
diff --git a/mpfr/tests/mpf_compat.c b/mpfr/tests/mpf_compat.c
new file mode 100644
index 0000000000..923be0d60c
--- /dev/null
+++ b/mpfr/tests/mpf_compat.c
@@ -0,0 +1,25 @@
+/* Test compatibility mpf-mpfr.
+
+Copyright 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPF
+#define mpf_free_str mpfr_free_str
+#include "mpf_compat.h"
diff --git a/mpfr/tests/mpf_compat.h b/mpfr/tests/mpf_compat.h
new file mode 100644
index 0000000000..3df82b5b51
--- /dev/null
+++ b/mpfr/tests/mpf_compat.h
@@ -0,0 +1,236 @@
+/* Test compatibility mpf-mpfr.
+
+Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#if defined (__cplusplus)
+#include <cstdio>
+#else
+#include <stdio.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "gmp.h"
+#include "mpfr.h"
+#ifdef MPFR
+#include "mpf2mpfr.h"
+#endif
+
+int
+main (void)
+{
+ unsigned long int prec;
+ unsigned long int prec2;
+ mpf_t x, y;
+ mpz_t z;
+ mpq_t q;
+ double d;
+ signed long int exp;
+ long l;
+ unsigned long u;
+ char *s;
+ int i;
+ FILE *f;
+ gmp_randstate_t state;
+
+ /* Initialization Functions */
+ prec = 53;
+ mpf_set_default_prec (prec);
+ prec2 = mpf_get_default_prec ();
+ if (prec2 < prec)
+ {
+ printf ("Error in get_default_prec: %lu < %lu\n", prec2, prec);
+ exit (1);
+ }
+
+ mpf_init (y);
+
+ mpf_init2 (x, prec);
+ prec2 = mpf_get_prec (x);
+ if (prec2 < prec)
+ {
+ printf ("Error in get_prec: %lu < %lu\n", prec2, prec);
+ mpf_clear (y);
+ mpf_clear (x);
+ exit (1);
+ }
+
+ mpf_set_prec (x, 2 * prec);
+ prec2 = mpf_get_prec (x);
+ if (prec2 < 2 * prec)
+ {
+ printf ("Error in set_prec: %lu < %lu\n", prec2, 2 * prec);
+ mpf_clear (y);
+ mpf_clear (x);
+ exit (1);
+ }
+
+ mpf_set_prec_raw (x, prec);
+ prec2 = mpf_get_prec (x);
+ if (prec2 < prec)
+ {
+ printf ("Error in set_prec_raw: %lu < %lu\n", prec2, prec);
+ mpf_clear (y);
+ mpf_clear (x);
+ exit (1);
+ }
+
+ /* Assignment Functions */
+
+ mpf_set (y, x);
+ mpf_set_ui (x, 1);
+ mpf_set_si (x, -1);
+ mpf_set_d (x, 1.0);
+
+ mpz_init_set_ui (z, 17);
+ mpf_set_z (x, z);
+ mpz_clear (z);
+
+ mpq_init (q);
+ mpq_set_ui (q, 2, 3);
+ mpf_set_q (x, q);
+ mpq_clear (q);
+
+ mpf_set_str (x, "3.1415e1", 10);
+ mpf_swap (x, y);
+
+ /* Combined Initialization and Assignment Functions */
+
+ mpf_clear (x);
+ mpf_init_set (x, y);
+ mpf_clear (x);
+ mpf_init_set_ui (x, 17);
+ mpf_clear (x);
+ mpf_init_set_si (x, -17);
+ mpf_clear (x);
+ mpf_init_set_d (x, 17.0);
+ mpf_clear (x);
+ mpf_init_set_str (x, "3.1415e1", 10);
+
+ /* Conversion Functions */
+
+ d = mpf_get_d (x);
+ d = mpf_get_d_2exp (&exp, x);
+ l = mpf_get_si (x);
+ u = mpf_get_ui (x);
+ s = mpf_get_str (NULL, &exp, 10, 10, x);
+ /* MPF doen't have mpf_free_str */
+ mpfr_free_str (s);
+
+ /* Use d, l and u to avoid a warning with -Wunused-but-set-variable
+ from GCC 4.6. The variables above were mainly used for prototype
+ checking. */
+ (void) d; (void) l; (void) u;
+
+ /* Arithmetic Functions */
+
+ mpf_add (y, x, x);
+ mpf_add_ui (y, x, 1);
+ mpf_sub (y, x, x);
+ mpf_ui_sub (y, 1, x);
+ mpf_sub_ui (y, x, 1);
+ mpf_mul (y, x, x);
+ mpf_mul_ui (y, x, 17);
+ mpf_div (y, x, x);
+ mpf_ui_div (y, 17, x);
+ mpf_div_ui (y, x, 17);
+ mpf_sqrt (y, x);
+ mpf_sqrt_ui (y, 17);
+ mpf_pow_ui (y, x, 2);
+ mpf_neg (y, x);
+ mpf_abs (y, x);
+ mpf_mul_2exp (y, x, 17);
+ mpf_div_2exp (y, x, 17);
+
+ /* Comparison Functions */
+
+ i = mpf_cmp (y, x);
+ i = mpf_cmp_d (y, 1.7);
+ i = mpf_cmp_ui (y, 17);
+ i = mpf_cmp_si (y, -17);
+ i = mpf_eq (y, x, 17);
+ mpf_reldiff (y, y, x);
+ i = mpf_sgn (x);
+
+ /* Input and Output Functions */
+
+ f = fopen ("/dev/null", "w");
+ if (f != NULL)
+ {
+ mpf_out_str (f, 10, 10, x);
+ fclose (f);
+ }
+
+ mpf_set_prec (x, 15);
+ mpf_set_prec (y, 15);
+ /* We may use src_fopen instead of fopen, but it is defined
+ in mpfr-test, and not in mpfr.h and gmp.h, and we want
+ to test theses includes files. */
+ f = fopen ("inp_str.data", "r");
+ if (f != NULL)
+ {
+ i = mpf_inp_str (x, f, 10);
+ if ((i == 0) || mpf_cmp_ui (x, 31415))
+ {
+ printf ("Error in reading 1st line from file inp_str.data\n");
+ exit (1);
+ }
+ fclose (f);
+ }
+
+ /* Miscellaneous Functions */
+
+ mpf_ceil (y, x);
+ mpf_floor (y, x);
+ mpf_trunc (y, x);
+
+ i = mpf_integer_p (x);
+
+ i = mpf_fits_ulong_p (x);
+ i = mpf_fits_slong_p (x);
+ i = mpf_fits_uint_p (x);
+ i = mpf_fits_sint_p (x);
+ i = mpf_fits_ushort_p (x);
+ i = mpf_fits_sshort_p (x);
+
+ gmp_randinit_lc_2exp_size (state, 128);
+ mpf_urandomb (x, state, 10);
+ gmp_randclear (state);
+
+ /* Conversion to mpz */
+ mpz_init (z);
+ mpf_set_ui (x, 17);
+ mpz_set_f (z, x);
+ mpf_set_z (x, z);
+ mpz_clear (z);
+ if (mpf_cmp_ui (x, 17) != 0)
+ {
+ fprintf (stderr, "Error in conversion to/from mpz\n");
+ fprintf (stderr, "expected 17, got %1.16e\n", mpf_get_d (x));
+ exit (1);
+ }
+
+ /* clear all variables */
+ mpf_clear (y);
+ mpf_clear (x);
+
+ return 0;
+}
diff --git a/mpfr/tests/mpfr-test.h b/mpfr/tests/mpfr-test.h
new file mode 100644
index 0000000000..7252234f27
--- /dev/null
+++ b/mpfr/tests/mpfr-test.h
@@ -0,0 +1,173 @@
+/* auxiliary functions for MPFR tests.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __MPFR_TEST_H__
+#define __MPFR_TEST_H__
+
+#include <stdio.h>
+
+#include "mpfr-impl.h"
+
+/* generates a random long int, a random double,
+ and corresponding seed initializing */
+#define DBL_RAND() ((double) randlimb() / (double) MP_LIMB_T_MAX)
+
+#define MINNORM 2.2250738585072013831e-308 /* 2^(-1022), smallest normalized */
+#define MAXNORM 1.7976931348623157081e308 /* 2^(1023)*(2-2^(-52)) */
+
+/* Generates a random rounding mode */
+#define RND_RAND() ((mpfr_rnd_t) (randlimb() % MPFR_RND_MAX))
+
+/* Generates a random sign */
+#define SIGN_RAND() ( (randlimb()%2) ? MPFR_SIGN_POS : MPFR_SIGN_NEG)
+
+/* Loop for all rounding modes */
+#define RND_LOOP(_r) for((_r) = 0 ; (_r) < MPFR_RND_MAX ; (_r)++)
+
+/* Test whether two floating-point data have the same value,
+ seen as an element of the set of the floating-point data
+ (Level 2 in the IEEE 754-2008 standard). */
+#define SAME_VAL(X,Y) \
+ ((MPFR_IS_NAN (X) && MPFR_IS_NAN (Y)) || \
+ (mpfr_equal_p ((X), (Y)) && MPFR_INT_SIGN (X) == MPFR_INT_SIGN (Y)))
+
+/* The MAX, MIN and ABS macros may already be defined if gmp-impl.h has
+ been included. They have the same semantics as in gmp-impl.h, but the
+ expressions may be slightly different. So, it's better to undefine
+ them first, as required by the ISO C standard. */
+#undef MAX
+#undef MIN
+#undef ABS
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define ABS(x) (((x)>0) ? (x) : -(x))
+
+#define FLIST mpfr_ptr, mpfr_srcptr, mpfr_rnd_t
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+void test_version _MPFR_PROTO ((void));
+
+void tests_memory_start _MPFR_PROTO ((void));
+void tests_memory_end _MPFR_PROTO ((void));
+
+void tests_start_mpfr _MPFR_PROTO ((void));
+void tests_end_mpfr _MPFR_PROTO ((void));
+
+int mpfr_set_machine_rnd_mode _MPFR_PROTO ((mpfr_rnd_t));
+void mpfr_test_init _MPFR_PROTO ((void));
+mp_limb_t randlimb _MPFR_PROTO ((void));
+void randseed _MPFR_PROTO ((unsigned int));
+void mpfr_random2 _MPFR_PROTO ((mpfr_ptr, mp_size_t, mpfr_exp_t, gmp_randstate_t));
+int ulp _MPFR_PROTO ((double, double));
+double dbl _MPFR_PROTO ((double, int));
+double Ulp _MPFR_PROTO ((double));
+int Isnan _MPFR_PROTO ((double));
+void d_trace _MPFR_PROTO ((const char *, double));
+void ld_trace _MPFR_PROTO ((const char *, long double));
+
+FILE *src_fopen _MPFR_PROTO ((const char *, const char *));
+void set_emin _MPFR_PROTO ((mpfr_exp_t));
+void set_emax _MPFR_PROTO ((mpfr_exp_t));
+void tests_default_random _MPFR_PROTO ((mpfr_ptr, int, mpfr_exp_t, mpfr_exp_t));
+void data_check _MPFR_PROTO ((const char *, int (*) (FLIST), const char *));
+void bad_cases _MPFR_PROTO ((int (*)(FLIST), int (*)(FLIST),
+ const char *, int, mpfr_exp_t, mpfr_exp_t,
+ mpfr_prec_t, mpfr_prec_t, mpfr_prec_t, int));
+void flags_out _MPFR_PROTO ((unsigned int));
+
+int mpfr_cmp_str _MPFR_PROTO ((mpfr_srcptr x, const char *, int, mpfr_rnd_t));
+#define mpfr_cmp_str1(x,s) mpfr_cmp_str(x,s,10,MPFR_RNDN)
+#define mpfr_set_str1(x,s) mpfr_set_str(x,s,10,MPFR_RNDN)
+
+#define mpfr_cmp0(x,y) (MPFR_ASSERTN (!MPFR_IS_NAN (x) && !MPFR_IS_NAN (y)), mpfr_cmp (x,y))
+#define mpfr_cmp_ui0(x,i) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), mpfr_cmp_ui (x,i))
+
+#if defined (__cplusplus)
+}
+#endif
+
+/* define CHECK_EXTERNAL if you want to check mpfr against another library
+ with correct rounding. You'll probably have to modify mpfr_print_raw()
+ and/or test_add() below:
+ * mpfr_print_raw() prints each number as "p m e" where p is the precision,
+ m the mantissa (as a binary integer with sign), and e the exponent.
+ The corresponding number is m*2^e. Example: "2 10 -6" represents
+ 2*2^(-6) with a precision of 2 bits.
+ * test_add() outputs "b c a" on one line, for each addition a <- b + c.
+ Currently it only prints such a line for rounding to nearest, when
+ the inputs b and c are not NaN and/or Inf.
+*/
+#ifdef CHECK_EXTERNAL
+static void
+mpfr_print_raw (mpfr_srcptr x)
+{
+ printf ("%lu ", MPFR_PREC (x));
+ if (MPFR_IS_NAN (x))
+ {
+ printf ("@NaN@");
+ return;
+ }
+
+ if (MPFR_SIGN (x) < 0)
+ printf ("-");
+
+ if (MPFR_IS_INF (x))
+ printf ("@Inf@");
+ else if (MPFR_IS_ZERO (x))
+ printf ("0 0");
+ else
+ {
+ mp_limb_t *mx;
+ mpfr_prec_t px;
+ mp_size_t n;
+
+ mx = MPFR_MANT (x);
+ px = MPFR_PREC (x);
+
+ for (n = (px - 1) / GMP_NUMB_BITS; ; n--)
+ {
+ mp_limb_t wd, t;
+
+ MPFR_ASSERTN (n >= 0);
+ wd = mx[n];
+ for (t = MPFR_LIMB_HIGHBIT; t != 0; t >>= 1)
+ {
+ printf ((wd & t) == 0 ? "0" : "1");
+ if (--px == 0)
+ {
+ mpfr_exp_t ex;
+
+ ex = MPFR_GET_EXP (x);
+ MPFR_ASSERTN (ex >= LONG_MIN && ex <= LONG_MAX);
+ printf (" %ld", (long) ex - (long) MPFR_PREC (x));
+ return;
+ }
+ }
+ }
+ }
+}
+#endif
+
+#endif
diff --git a/mpfr/tests/mpfr_compat.c b/mpfr/tests/mpfr_compat.c
new file mode 100644
index 0000000000..7006db8c28
--- /dev/null
+++ b/mpfr/tests/mpfr_compat.c
@@ -0,0 +1,25 @@
+/* Test compatibility mpf-mpfr.
+
+Copyright 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define MPFR
+#define mpf_free_str mpfr_free_str
+#include "mpf_compat.h"
diff --git a/mpfr/tests/random2.c b/mpfr/tests/random2.c
new file mode 100644
index 0000000000..35e5f12c32
--- /dev/null
+++ b/mpfr/tests/random2.c
@@ -0,0 +1,144 @@
+/* mpfr_random2 -- Generate a positive random mpfr_t of specified size, with
+ long runs of consecutive ones and zeros in the binary representation.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-test.h"
+
+#define LOGBITS_PER_BLOCK 4
+#if GMP_NUMB_BITS < 32
+#define BITS_PER_RANDCALL GMP_NUMB_BITS
+#else
+#define BITS_PER_RANDCALL 32
+#endif
+
+void
+mpfr_random2 (mpfr_ptr x, mp_size_t size, mpfr_exp_t exp,
+ gmp_randstate_t rstate)
+{
+ mp_size_t xn, k, ri;
+ unsigned long sh;
+ mp_limb_t *xp;
+ mp_limb_t elimb, ran, acc;
+ int ran_nbits, bit_pos, nb;
+
+ if (MPFR_UNLIKELY(size == 0))
+ {
+ MPFR_SET_ZERO (x);
+ MPFR_SET_POS (x);
+ return ;
+ }
+ else if (size > 0)
+ {
+ MPFR_SET_POS (x);
+ }
+ else
+ {
+ MPFR_SET_NEG (x);
+ size = -size;
+ }
+
+ xn = MPFR_LIMB_SIZE (x);
+ xp = MPFR_MANT (x);
+ if (size > xn)
+ size = xn;
+ k = xn - size;
+
+ /* Code extracted from GMP, function mpn_random2, to avoid the use
+ of GMP's internal random state in MPFR */
+
+ mpfr_rand_raw (&elimb, rstate, BITS_PER_RANDCALL);
+ ran = elimb;
+
+ /* Start off at a random bit position in the most significant limb. */
+ bit_pos = GMP_NUMB_BITS - 1;
+ ran >>= 6; /* Ideally log2(GMP_NUMB_BITS) */
+ ran_nbits = BITS_PER_RANDCALL - 6; /* Ideally - log2(GMP_NUMB_BITS) */
+
+ /* Bit 0 of ran chooses string of ones/string of zeroes.
+ Make most significant limb be non-zero by setting bit 0 of RAN. */
+ ran |= 1;
+ ri = xn - 1;
+
+ acc = 0;
+ while (ri >= k)
+ {
+ if (ran_nbits < LOGBITS_PER_BLOCK + 1)
+ {
+ mpfr_rand_raw (&elimb, rstate, BITS_PER_RANDCALL);
+ ran = elimb;
+ ran_nbits = BITS_PER_RANDCALL;
+ }
+
+ nb = (ran >> 1) % (1 << LOGBITS_PER_BLOCK) + 1;
+ if ((ran & 1) != 0)
+ {
+ /* Generate a string of nb ones. */
+ if (nb > bit_pos)
+ {
+ xp[ri--] = acc | (((mp_limb_t) 2 << bit_pos) - 1);
+ bit_pos += GMP_NUMB_BITS;
+ bit_pos -= nb;
+ acc = ((~(mp_limb_t) 1) << bit_pos) & GMP_NUMB_MASK;
+ }
+ else
+ {
+ bit_pos -= nb;
+ acc |= (((mp_limb_t) 2 << nb) - 2) << bit_pos;
+ }
+ }
+ else
+ {
+ /* Generate a string of nb zeroes. */
+ if (nb > bit_pos)
+ {
+ xp[ri--] = acc;
+ acc = 0;
+ bit_pos += GMP_NUMB_BITS;
+ }
+ bit_pos -= nb;
+ }
+ ran_nbits -= LOGBITS_PER_BLOCK + 1;
+ ran >>= LOGBITS_PER_BLOCK + 1;
+ }
+
+ /* Set mandatory most significant bit. */
+ /* xp[xn - 1] |= MPFR_LIMB_HIGHBIT; */
+
+ if (k != 0)
+ {
+ /* Clear last limbs */
+ MPN_ZERO (xp, k);
+ }
+ else
+ {
+ /* Mask off non significant bits in the low limb. */
+ MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (x));
+ xp[0] &= ~MPFR_LIMB_MASK (sh);
+ }
+
+ /* Generate random exponent. */
+ mpfr_rand_raw (&elimb, RANDS, GMP_NUMB_BITS);
+ exp = ABS (exp);
+ MPFR_SET_EXP (x, elimb % (2 * exp + 1) - exp);
+
+ return ;
+}
diff --git a/mpfr/tests/reuse.c b/mpfr/tests/reuse.c
new file mode 100644
index 0000000000..4c32260af0
--- /dev/null
+++ b/mpfr/tests/reuse.c
@@ -0,0 +1,685 @@
+/* Test file for in-place operations.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define DISP(s, t) {printf(s); mpfr_out_str(stdout, 2, 0, t, MPFR_RNDN); }
+#define DISP2(s,t) {DISP(s,t); putchar('\n');}
+
+#define SPECIAL_MAX 12
+
+static void
+set_special (mpfr_ptr x, unsigned int select)
+{
+ MPFR_ASSERTN (select < SPECIAL_MAX);
+ switch (select)
+ {
+ case 0:
+ MPFR_SET_NAN (x);
+ break;
+ case 1:
+ MPFR_SET_INF (x);
+ MPFR_SET_POS (x);
+ break;
+ case 2:
+ MPFR_SET_INF (x);
+ MPFR_SET_NEG (x);
+ break;
+ case 3:
+ MPFR_SET_ZERO (x);
+ MPFR_SET_POS (x);
+ break;
+ case 4:
+ MPFR_SET_ZERO (x);
+ MPFR_SET_NEG (x);
+ break;
+ case 5:
+ mpfr_set_str_binary (x, "1");
+ break;
+ case 6:
+ mpfr_set_str_binary (x, "-1");
+ break;
+ case 7:
+ mpfr_set_str_binary (x, "1e-1");
+ break;
+ case 8:
+ mpfr_set_str_binary (x, "1e+1");
+ break;
+ case 9:
+ mpfr_const_pi (x, MPFR_RNDN);
+ break;
+ case 10:
+ mpfr_const_pi (x, MPFR_RNDN);
+ MPFR_SET_EXP (x, MPFR_GET_EXP (x)-1);
+ break;
+ default:
+ mpfr_urandomb (x, RANDS);
+ if (randlimb () & 1)
+ mpfr_neg (x, x, MPFR_RNDN);
+ break;
+ }
+}
+/* same than mpfr_cmp, but returns 0 for both NaN's */
+static int
+mpfr_compare (mpfr_srcptr a, mpfr_srcptr b)
+{
+ return (MPFR_IS_NAN(a)) ? !MPFR_IS_NAN(b) :
+ (MPFR_IS_NAN(b) || mpfr_cmp(a, b));
+}
+
+static void
+test3 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t),
+ const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd)
+{
+ mpfr_t ref1, ref2, ref3;
+ mpfr_t res1;
+ int i;
+
+#ifdef DEBUG
+ printf("checking %s\n", foo);
+#endif
+ mpfr_init2 (ref1, prec);
+ mpfr_init2 (ref2, prec);
+ mpfr_init2 (ref3, prec);
+ mpfr_init2 (res1, prec);
+
+ /* for each variable, consider each of the following 6 possibilities:
+ NaN, +Infinity, -Infinity, +0, -0 or a random number */
+ for (i=0; i < SPECIAL_MAX*SPECIAL_MAX ; i++)
+ {
+ set_special (ref2, i%SPECIAL_MAX);
+ set_special (ref3, i/SPECIAL_MAX);
+
+ /* reference call: foo(a, b, c) */
+ testfunc (ref1, ref2, ref3, rnd);
+
+ /* foo(a, a, c) */
+ mpfr_set (res1, ref2, rnd); /* exact operation */
+ testfunc (res1, res1, ref3, rnd);
+
+ if (mpfr_compare (res1, ref1))
+ {
+ printf ("Error for %s(a, a, c) for ", foo);
+ DISP("a=",ref2); DISP2(", c=",ref3);
+ printf ("expected "); mpfr_print_binary (ref1); puts ("");
+ printf ("got "); mpfr_print_binary (res1); puts ("");
+ exit (1);
+ }
+
+ /* foo(a, b, a) */
+ mpfr_set (res1, ref3, rnd);
+ testfunc (res1, ref2, res1, rnd);
+ if (mpfr_compare (res1, ref1))
+ {
+ printf ("Error for %s(a, b, a) for ", foo);
+ DISP("b=",ref2); DISP2(", a=", ref3);
+ DISP("expected ", ref1); DISP2(", got ",res1);
+ exit (1);
+ }
+
+ /* foo(a, a, a) */
+ mpfr_set (ref3, ref2, rnd);
+ testfunc (ref1, ref2, ref3, rnd);
+ mpfr_set (res1, ref2, rnd);
+ testfunc (res1, res1, res1, rnd);
+
+ if (mpfr_compare (res1, ref1))
+ {
+ printf ("Error for %s(a, a, a) for ", foo);
+ DISP2("a=",ref2);
+ DISP("expected ", ref1); DISP2(", got", res1);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref2);
+ mpfr_clear (ref3);
+ mpfr_clear (res1);
+}
+
+static void
+test4 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t),
+ const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd)
+{
+ mpfr_t ref, op1, op2, op3;
+ mpfr_t res;
+ int i, j, k;
+
+#ifdef DEBUG
+ printf("checking %s\n", foo);
+#endif
+ mpfr_init2 (ref, prec);
+ mpfr_init2 (op1, prec);
+ mpfr_init2 (op2, prec);
+ mpfr_init2 (op3, prec);
+ mpfr_init2 (res, prec);
+
+ /* for each variable, consider each of the following 6 possibilities:
+ NaN, +Infinity, -Infinity, +0, -0 or a random number */
+
+ for (i=0; i<SPECIAL_MAX; i++)
+ {
+ set_special (op1, i);
+ for (j=0; j<SPECIAL_MAX; j++)
+ {
+ set_special (op2, j);
+ for (k=0; k<SPECIAL_MAX; k++)
+ {
+ set_special (op3, k);
+
+ /* reference call: foo(s, a, b, c) */
+ testfunc (ref, op1, op2, op3, rnd);
+
+ /* foo(a, a, b, c) */
+ mpfr_set (res, op1, rnd); /* exact operation */
+ testfunc (res, res, op2, op3, rnd);
+
+ if (mpfr_compare (res, ref))
+ {
+ printf ("Error for %s(a, a, b, c) for ", foo);
+ DISP("a=", op1); DISP(", b=", op2); DISP2(", c=", op3);
+ DISP("expected ", ref); DISP2(", got", res);
+ exit (1);
+ }
+
+ /* foo(b, a, b, c) */
+ mpfr_set (res, op2, rnd);
+ testfunc (res, op1, res, op3, rnd);
+
+ if (mpfr_compare (res, ref))
+ {
+ printf ("Error for %s(a, a, b, c) for ", foo);
+ DISP("a=", op1); DISP(", b=", op2); DISP2(", c=", op3);
+ DISP("expected ", ref); DISP2(", got", res);
+ exit (1);
+ }
+
+ /* foo(c, a, b, c) */
+ mpfr_set (res, op3, rnd);
+ testfunc (res, op1, op2, res, rnd);
+
+ if (mpfr_compare (res, ref))
+ {
+ printf ("Error for %s(a, a, b, c) for ", foo);
+ DISP("a=", op1); DISP(", b=", op2); DISP2(", c=", op3);
+ DISP("expected ", ref); DISP2(", got", res);
+ exit (1);
+ }
+
+ /* foo(a, a, a,c) */
+ testfunc (ref, op1, op1, op3, rnd);
+ mpfr_set (res, op1, rnd);
+ testfunc (res, res, res, op3, rnd);
+ if (mpfr_compare (res, ref))
+ {
+ printf ("Error for %s(a, a, b, c) for ", foo);
+ DISP("a=", op1); DISP(", a=", op2); DISP2(", c=", op3);
+ DISP("expected ", ref); DISP2(", got", res);
+ exit (1);
+ }
+
+ /* foo(a, a, b,a) */
+ testfunc (ref, op1, op2, op1, rnd);
+ mpfr_set (res, op1, rnd);
+ testfunc (res, res, op2, res, rnd);
+ if (mpfr_compare (res, ref))
+ {
+ printf ("Error for %s(a, a, b, c) for ", foo);
+ DISP("a=", op1); DISP(", a=", op2); DISP2(", c=", op3);
+ DISP("expected ", ref); DISP2(", got", res);
+ exit (1);
+ }
+
+ /* foo(b, a, b, b) */
+ testfunc (ref, op1, op2, op2, rnd);
+ mpfr_set (res, op2, rnd);
+ testfunc (res, op1, res, res, rnd);
+ if (mpfr_compare (res, ref))
+ {
+ printf ("Error for %s(a, a, b, c) for ", foo);
+ DISP("a=", op1); DISP(", a=", op2); DISP2(", c=", op3);
+ DISP("expected ", ref); DISP2(", got", res);
+ exit (1);
+ }
+
+ /* foo (a, a, a, a) */
+ testfunc (ref, op1, op1, op1 ,rnd);
+ mpfr_set (res, op1, rnd);
+ testfunc (res, res, res, res, rnd);
+ if (mpfr_compare (res, ref))
+ {
+ printf ("Error for %s(a, a, a, a) for ", foo);
+ DISP2("a=", op1);
+ DISP("expected ", ref); DISP2(", got", res);
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (ref);
+ mpfr_clear (op1);
+ mpfr_clear (op2);
+ mpfr_clear (op3);
+ mpfr_clear (res);
+
+}
+
+static void
+test2ui (int (*testfunc)(mpfr_ptr, mpfr_srcptr, unsigned long int, mpfr_rnd_t),
+ const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd)
+{
+ mpfr_t ref1, ref2;
+ unsigned int ref3;
+ mpfr_t res1;
+ int i;
+
+#ifdef DEBUG
+ printf("checking %s\n", foo);
+#endif
+ mpfr_init2 (ref1, prec);
+ mpfr_init2 (ref2, prec);
+ mpfr_init2 (res1, prec);
+
+ /* ref2 can be NaN, +Inf, -Inf, +0, -0 or any number
+ ref3 can be 0 or any number */
+ for (i=0; i<SPECIAL_MAX*2; i++)
+ {
+ set_special (ref2, i%SPECIAL_MAX);
+ ref3 = i/SPECIAL_MAX == 0 ? 0 : randlimb ();
+
+ /* reference call: foo(a, b, c) */
+ testfunc (ref1, ref2, ref3, rnd);
+
+ /* foo(a, a, c) */
+ mpfr_set (res1, ref2, rnd); /* exact operation */
+ testfunc (res1, res1, ref3, rnd);
+
+ if (mpfr_compare (res1, ref1))
+ {
+ printf ("Error for %s(a, a, c) for c=%u\n", foo, ref3);
+ DISP2("a=",ref2);
+ printf ("expected "); mpfr_print_binary (ref1); puts ("");
+ printf ("got "); mpfr_print_binary (res1); puts ("");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref2);
+ mpfr_clear (res1);
+}
+
+static void
+testui2 (int (*testfunc)(mpfr_ptr, unsigned long int, mpfr_srcptr, mpfr_rnd_t),
+ const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd)
+{
+ mpfr_t ref1, ref3;
+ unsigned int ref2;
+ mpfr_t res1;
+ int i;
+
+#ifdef DEBUG
+ printf("checking %s\n", foo);
+#endif
+ mpfr_init2 (ref1, prec);
+ mpfr_init2 (ref3, prec);
+ mpfr_init2 (res1, prec);
+
+ for (i=0; i<SPECIAL_MAX*2; i++)
+ {
+ set_special (ref3, i%SPECIAL_MAX);
+ ref2 = i/SPECIAL_MAX==0 ? 0 : randlimb ();
+
+ /* reference call: foo(a, b, c) */
+ testfunc (ref1, ref2, ref3, rnd);
+
+ /* foo(a, b, a) */
+ mpfr_set (res1, ref3, rnd); /* exact operation */
+ testfunc (res1, ref2, res1, rnd);
+ if (mpfr_compare (res1, ref1))
+ {
+ printf ("Error for %s(a, b, a) for b=%u \n", foo, ref2);
+ DISP2("a=", ref3);
+ DISP("expected", ref1); DISP2(", got ", res1);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref3);
+ mpfr_clear (res1);
+}
+
+/* foo(mpfr_ptr, mpfr_srcptr, mp_rndt) */
+static void
+test2 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
+ const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd)
+{
+ mpfr_t ref1, ref2;
+ mpfr_t res1;
+ int i;
+
+#ifdef DEBUG
+ printf("checking %s\n", foo);
+#endif
+ mpfr_init2 (ref1, prec);
+ mpfr_init2 (ref2, prec);
+ mpfr_init2 (res1, prec);
+
+ for (i=0; i<SPECIAL_MAX; i++)
+ {
+ set_special (ref2, i);
+
+ /* reference call: foo(a, b) */
+ testfunc (ref1, ref2, rnd);
+
+ /* foo(a, a) */
+ mpfr_set (res1, ref2, rnd); /* exact operation */
+ testfunc (res1, res1, rnd);
+ if (mpfr_compare (res1, ref1))
+ {
+ printf ("Error for %s(a, a) for ", foo);
+ DISP2("a=", ref2);
+ DISP("expected", ref1); DISP2(", got ", res1);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref2);
+ mpfr_clear (res1);
+}
+
+/* foo(mpfr_ptr, mpfr_srcptr) */
+static void
+test2a (int (*testfunc)(mpfr_ptr, mpfr_srcptr),
+ const char *foo, mpfr_prec_t prec)
+{
+ mpfr_t ref1, ref2;
+ mpfr_t res1;
+ int i;
+
+#ifdef DEBUG
+ printf ("checking %s\n", foo);
+#endif
+ mpfr_init2 (ref1, prec);
+ mpfr_init2 (ref2, prec);
+ mpfr_init2 (res1, prec);
+
+ for (i=0; i<SPECIAL_MAX; i++)
+ {
+ set_special (ref2, i);
+
+ /* reference call: foo(a, b) */
+ testfunc (ref1, ref2);
+
+ /* foo(a, a) */
+ mpfr_set (res1, ref2, MPFR_RNDN); /* exact operation */
+ testfunc (res1, res1);
+ if (mpfr_compare (res1, ref1))
+ {
+ printf ("Error for %s(a, a) for ", foo);
+ DISP2("a=",ref2);
+ DISP("expected", ref1); DISP2(", got ", res1);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref2);
+ mpfr_clear (res1);
+}
+
+/* one operand, two results */
+static void
+test3a (int (*testfunc)(mpfr_ptr, mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
+ const char *foo, mpfr_prec_t prec, mpfr_rnd_t rnd)
+{
+ mpfr_t ref1, ref2, ref3;
+ mpfr_t res1, res2;
+ int i;
+
+#ifdef DEBUG
+ printf ("checking %s\n", foo);
+#endif
+ mpfr_init2 (ref1, prec);
+ mpfr_init2 (ref2, prec);
+ mpfr_init2 (ref3, prec);
+ mpfr_init2 (res1, prec);
+ mpfr_init2 (res2, prec);
+
+ for (i=0; i<SPECIAL_MAX; i++)
+ {
+ set_special (ref3, i);
+
+ /* reference call: foo(a, b, c) */
+ testfunc (ref1, ref2, ref3, rnd);
+
+ /* foo(a, b, a) */
+ mpfr_set (res1, ref3, rnd); /* exact operation */
+ testfunc (res1, res2, res1, rnd);
+ if (mpfr_compare (res1, ref1) || mpfr_compare (res2, ref2))
+ {
+ printf ("Error for %s(a, b, a) for rnd=%s, ", foo,
+ mpfr_print_rnd_mode (rnd));
+ DISP2("a=",ref3);
+ DISP("expected (", ref1); DISP(",",ref2);
+ DISP("), got (", res1); DISP(",", res2); printf(")\n");
+ exit (1);
+ }
+
+ /* foo(a, b, b) */
+ mpfr_set (res2, ref3, rnd); /* exact operation */
+ testfunc (res1, res2, res2, rnd);
+ if (mpfr_compare (res1, ref1) || mpfr_compare (res2, ref2))
+ {
+ printf ("Error for %s(a, b, b) for ", foo);
+ DISP2("b=",ref3);
+ DISP("expected (", ref1); DISP(",",ref2);
+ DISP("), got (", res1); DISP(",", res2); printf(")\n");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref2);
+ mpfr_clear (ref3);
+ mpfr_clear (res1);
+ mpfr_clear (res2);
+}
+
+static int
+reldiff_wrapper (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ mpfr_reldiff (a, b, c, rnd_mode);
+ return 0;
+}
+
+static void
+pow_int (mpfr_rnd_t rnd)
+{
+ mpfr_t ref1, ref2, ref3;
+ mpfr_t res1;
+ int i;
+
+#ifdef DEBUG
+ printf("pow_int\n");
+#endif
+ mpfr_inits2 ((randlimb () % 200) + MPFR_PREC_MIN,
+ ref1, ref2, res1, (mpfr_ptr) 0);
+ mpfr_init2 (ref3, 1005);
+
+ for (i = 0; i <= 15; i++)
+ {
+ mpfr_urandomb (ref2, RANDS);
+ if (i & 1)
+ mpfr_neg (ref2, ref2, MPFR_RNDN);
+ mpfr_set_ui (ref3, 20, MPFR_RNDN);
+ /* We need to test huge integers because different algorithms/codes
+ are used for not-too-large integers (mpfr_pow_z) and for general
+ cases, in particular huge integers (mpfr_pow_general). [r7606] */
+ if (i & 2)
+ mpfr_mul_2ui (ref3, ref3, 1000, MPFR_RNDN);
+ if (i & 4)
+ mpfr_add_ui (ref3, ref3, 1, MPFR_RNDN); /* odd integer */
+
+ /* reference call: pow(a, b, c) */
+ mpfr_pow (ref1, ref2, ref3, rnd);
+
+ /* pow(a, a, c) */
+ mpfr_set (res1, ref2, rnd); /* exact operation */
+ mpfr_pow (res1, res1, ref3, rnd);
+
+ if (mpfr_compare (res1, ref1))
+ {
+ printf ("Error for pow_int(a, a, c) for ");
+ DISP("a=",ref2); DISP2(", c=",ref3);
+ printf ("expected "); mpfr_print_binary (ref1); puts ("");
+ printf ("got "); mpfr_print_binary (res1); puts ("");
+ exit (1);
+ }
+ }
+
+ mpfr_clears (ref1, ref2, ref3, res1, (mpfr_ptr) 0);
+}
+
+int
+main (void)
+{
+ int rnd;
+ mpfr_prec_t p;
+ tests_start_mpfr ();
+
+ p = (randlimb () % 200) + MPFR_PREC_MIN;
+ RND_LOOP (rnd)
+ {
+ test2a (mpfr_round, "mpfr_round", p);
+ test2a (mpfr_ceil, "mpfr_ceil", p);
+ test2a (mpfr_floor, "mpfr_floor", p);
+ test2a (mpfr_trunc, "mpfr_trunc", p);
+
+ test2ui (mpfr_add_ui, "mpfr_add_ui", p, (mpfr_rnd_t) rnd);
+ test2ui (mpfr_div_2exp, "mpfr_div_2exp", p, (mpfr_rnd_t) rnd);
+ test2ui (mpfr_div_ui, "mpfr_div_ui", p, (mpfr_rnd_t) rnd);
+ test2ui (mpfr_mul_2exp, "mpfr_mul_2exp", p, (mpfr_rnd_t) rnd);
+ test2ui (mpfr_mul_ui, "mpfr_mul_ui", p, (mpfr_rnd_t) rnd);
+ test2ui (mpfr_pow_ui, "mpfr_pow_ui", p, (mpfr_rnd_t) rnd);
+ test2ui (mpfr_sub_ui, "mpfr_sub_ui", p, (mpfr_rnd_t) rnd);
+
+ testui2 (mpfr_ui_div, "mpfr_ui_div", p, (mpfr_rnd_t) rnd);
+ testui2 (mpfr_ui_sub, "mpfr_ui_sub", p, (mpfr_rnd_t) rnd);
+ testui2 (mpfr_ui_pow, "mpfr_ui_pow", p, (mpfr_rnd_t) rnd);
+
+ test2 (mpfr_sqr, "mpfr_sqr", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_sqrt, "mpfr_sqrt", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_abs, "mpfr_abs", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_neg, "mpfr_neg", p, (mpfr_rnd_t) rnd);
+
+ test2 (mpfr_log, "mpfr_log", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_log2, "mpfr_log2", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_log10, "mpfr_log10", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_log1p, "mpfr_log1p", p, (mpfr_rnd_t) rnd);
+
+ test2 (mpfr_exp, "mpfr_exp", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_exp2, "mpfr_exp2", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_exp10, "mpfr_exp10", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_expm1, "mpfr_expm1", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_eint, "mpfr_eint", p, (mpfr_rnd_t) rnd);
+
+ test2 (mpfr_sinh, "mpfr_sinh", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_cosh, "mpfr_cosh", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_tanh, "mpfr_tanh", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_asinh, "mpfr_asinh", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_acosh, "mpfr_acosh", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_atanh, "mpfr_atanh", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_sech, "mpfr_sech", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_csch, "mpfr_csch", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_coth, "mpfr_coth", p, (mpfr_rnd_t) rnd);
+
+ test2 (mpfr_asin, "mpfr_asin", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_acos, "mpfr_acos", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_atan, "mpfr_atan", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_cos, "mpfr_cos", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_sin, "mpfr_sin", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_tan, "mpfr_tan", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_sec, "mpfr_sec", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_csc, "mpfr_csc", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_cot, "mpfr_cot", p, (mpfr_rnd_t) rnd);
+
+ test2 (mpfr_erf, "mpfr_erf", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_erfc, "mpfr_erfc", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_j0, "mpfr_j0", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_j1, "mpfr_j1", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_y0, "mpfr_y0", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_y1, "mpfr_y1", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_zeta, "mpfr_zeta", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_gamma, "mpfr_gamma", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_lngamma, "mpfr_lngamma", p, (mpfr_rnd_t) rnd);
+
+ test2 (mpfr_rint, "mpfr_rint", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_rint_ceil, "mpfr_rint_ceil", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_rint_floor, "mpfr_rint_floor", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_rint_round, "mpfr_rint_round", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_rint_trunc, "mpfr_rint_trunc", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_frac, "mpfr_frac", p, (mpfr_rnd_t) rnd);
+
+ test3 (mpfr_add, "mpfr_add", p, (mpfr_rnd_t) rnd);
+ test3 (mpfr_sub, "mpfr_sub", p, (mpfr_rnd_t) rnd);
+ test3 (mpfr_mul, "mpfr_mul", p, (mpfr_rnd_t) rnd);
+ test3 (mpfr_div, "mpfr_div", p, (mpfr_rnd_t) rnd);
+
+ test3 (mpfr_agm, "mpfr_agm", p, (mpfr_rnd_t) rnd);
+ test3 (mpfr_min, "mpfr_min", p, (mpfr_rnd_t) rnd);
+ test3 (mpfr_max, "mpfr_max", p, (mpfr_rnd_t) rnd);
+
+ test3 (reldiff_wrapper, "mpfr_reldiff", p, (mpfr_rnd_t) rnd);
+ test3 (mpfr_dim, "mpfr_dim", p, (mpfr_rnd_t) rnd);
+
+ test3 (mpfr_remainder, "mpfr_remainder", p, (mpfr_rnd_t) rnd);
+ test3 (mpfr_pow, "mpfr_pow", p, (mpfr_rnd_t) rnd);
+ pow_int ((mpfr_rnd_t) rnd);
+ test3 (mpfr_atan2, "mpfr_atan2", p, (mpfr_rnd_t) rnd);
+ test3 (mpfr_hypot, "mpfr_hypot", p, (mpfr_rnd_t) rnd);
+
+ test3a (mpfr_sin_cos, "mpfr_sin_cos", p, (mpfr_rnd_t) rnd);
+
+ test4 (mpfr_fma, "mpfr_fma", p, (mpfr_rnd_t) rnd);
+ test4 (mpfr_fms, "mpfr_fms", p, (mpfr_rnd_t) rnd);
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+ test2 (mpfr_li2, "mpfr_li2", p, (mpfr_rnd_t) rnd);
+ test2 (mpfr_rec_sqrt, "mpfr_rec_sqrt", p, (mpfr_rnd_t) rnd);
+ test3 (mpfr_fmod, "mpfr_fmod", p, (mpfr_rnd_t) rnd);
+ test3a (mpfr_modf, "mpfr_modf", p, (mpfr_rnd_t) rnd);
+ test3a (mpfr_sinh_cosh, "mpfr_sinh_cosh", p, (mpfr_rnd_t) rnd);
+#endif
+ }
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/rnd_mode.c b/mpfr/tests/rnd_mode.c
new file mode 100644
index 0000000000..a25fad8f83
--- /dev/null
+++ b/mpfr/tests/rnd_mode.c
@@ -0,0 +1,70 @@
+/* mpfr_set_machine_rnd_mode -- set the rounding mode for machine floats
+
+Copyright 1999, 2001, 2002, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-test.h"
+
+/* It is important to test each FE_* macro -- see the ISO C99 standard.
+ For instance, with some ARM implementations, only FE_TONEAREST may
+ be defined. */
+
+/* sets the machine rounding mode to the value rnd_mode */
+int
+mpfr_set_machine_rnd_mode (mpfr_rnd_t rnd_mode)
+{
+ switch (rnd_mode)
+ {
+ case MPFR_RNDN:
+ return
+#if defined (MPFR_HAVE_FESETROUND) && defined (FE_TONEAREST)
+ fesetround(FE_TONEAREST)
+#else
+ -1
+#endif
+ ;
+ case MPFR_RNDZ:
+ return
+#if defined (MPFR_HAVE_FESETROUND) && defined (FE_TOWARDZERO)
+ fesetround(FE_TOWARDZERO)
+#else
+ -1
+#endif
+ ;
+ case MPFR_RNDU:
+ return
+#if defined (MPFR_HAVE_FESETROUND) && defined (FE_UPWARD)
+ fesetround(FE_UPWARD)
+#else
+ -1
+#endif
+ ;
+ case MPFR_RNDD:
+ return
+#if defined (MPFR_HAVE_FESETROUND) && defined (FE_DOWNWARD)
+ fesetround(FE_DOWNWARD)
+#else
+ -1
+#endif
+ ;
+ default:
+ return -1;
+ }
+}
diff --git a/mpfr/tests/tabs.c b/mpfr/tests/tabs.c
new file mode 100644
index 0000000000..fcd6933974
--- /dev/null
+++ b/mpfr/tests/tabs.c
@@ -0,0 +1,176 @@
+/* Test file for mpfr_abs.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+static void
+check_inexact (void)
+{
+ mpfr_prec_t p, q;
+ mpfr_t x, y, absx;
+ int rnd;
+ int inexact, cmp;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (absx);
+
+ for (p=2; p<500; p++)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_set_prec (absx, p);
+ mpfr_urandomb (x, RANDS);
+ if (randlimb () % 2)
+ {
+ mpfr_set (absx, x, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ }
+ else
+ mpfr_set (absx, x, MPFR_RNDN);
+ for (q=2; q<2*p; q++)
+ {
+ mpfr_set_prec (y, q);
+ RND_LOOP (rnd)
+ {
+ inexact = mpfr_abs (y, x, (mpfr_rnd_t) rnd);
+ cmp = mpfr_cmp (y, absx);
+ if (((inexact == 0) && (cmp != 0)) ||
+ ((inexact > 0) && (cmp <= 0)) ||
+ ((inexact < 0) && (cmp >= 0)))
+ {
+ printf ("Wrong inexact flag: expected %d, got %d\n",
+ cmp, inexact);
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("absx="); mpfr_print_binary (absx); puts ("");
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (absx);
+}
+
+static void
+check_cmp (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ int n, k;
+
+ mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
+
+ mpfr_set_ui(x, 1, MPFR_RNDN);
+ (mpfr_abs) (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error in mpfr_abs(1.0)\n");
+ exit (1);
+ }
+
+ mpfr_set_si(x, -1, MPFR_RNDN);
+ mpfr_abs(x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error in mpfr_abs(1.0)\n");
+ exit (1);
+ }
+
+ mpfr_set_si(x, -1, MPFR_RNDN);
+ mpfr_abs(x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error in mpfr_abs(-1.0)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_abs (x, x, MPFR_RNDN);
+ if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0))
+ {
+ printf ("Error in mpfr_abs(Inf).\n");
+ exit (1);
+ }
+ mpfr_set_inf (x, -1);
+ mpfr_abs (x, x, MPFR_RNDN);
+ if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0))
+ {
+ printf ("Error in mpfr_abs(-Inf).\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN(x);
+ mpfr_abs (x, x, MPFR_RNDN);
+ if (!MPFR_IS_NAN(x))
+ {
+ printf ("Error in mpfr_abs(NAN).\n");
+ exit (1);
+ }
+
+ n = (argc==1) ? 25000 : atoi(argv[1]);
+ for (k = 1; k <= n; k++)
+ {
+ mpfr_rnd_t rnd;
+ int sign = SIGN_RAND ();
+
+ mpfr_urandomb (x, RANDS);
+ MPFR_SET_SIGN (x, sign);
+ rnd = RND_RAND ();
+ mpfr_abs (y, x, rnd);
+ MPFR_SET_POS (x);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Mismatch for sign=%d and x=", sign);
+ mpfr_print_binary (x);
+ printf ("\nResults=");
+ mpfr_print_binary (y);
+ putchar ('\n');
+ exit (1);
+ }
+ }
+
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+#define TEST_FUNCTION mpfr_abs
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_test_init ();
+ tests_start_mpfr ();
+
+ check_inexact ();
+ check_cmp (argc, argv);
+
+ test_generic (2, 1000, 10);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tacos.c b/mpfr/tests/tacos.c
new file mode 100644
index 0000000000..ddb518b883
--- /dev/null
+++ b/mpfr/tests/tacos.c
@@ -0,0 +1,187 @@
+/* Test file for mpfr_acos.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_acos
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int inex1, inex2;
+
+ mpfr_init2 (x, 32);
+ mpfr_init2 (y, 32);
+
+ mpfr_set_str_binary (x, "0.10001000001001011000100001E-6");
+ mpfr_acos (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "1.10001111111111110001110110001");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_acos (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "-0.01101011110111100111010011001011");
+ mpfr_acos (y, x, MPFR_RNDZ);
+ mpfr_set_str_binary (x, "10.0000000101111000011101000101");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_acos (2)\n");
+ mpfr_print_binary (y); printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inex1 = mpfr_acos (x, x, MPFR_RNDN); /* Pi/2 */
+ inex2 = mpfr_const_pi (x, MPFR_RNDN);
+ if (inex1 != inex2)
+ {
+ printf ("Error in mpfr_acos (3) for prec=2\n");
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+static void
+special_overflow (void)
+{
+ mpfr_t x, y;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ set_emin (-125);
+ set_emax (128);
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 48);
+ mpfr_set_str_binary (x, "0.101100100000000000110100E0");
+ mpfr_acos (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "0.110011010100101111000100111010111011010000001001E0",
+ 2, MPFR_RNDN))
+ {
+ printf("Special Overflow error.\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_clear (y);
+ mpfr_clear (x);
+ set_emin (emin);
+ set_emax (emax);
+}
+
+int
+main (void)
+{
+ mpfr_t x, y;
+ int r;
+
+ tests_start_mpfr ();
+
+ special_overflow ();
+ special ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ MPFR_SET_NAN(x);
+ mpfr_acos (y, x, MPFR_RNDN);
+ if (mpfr_nan_p(y) == 0)
+ {
+ printf ("Error: acos(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_acos (y, x, MPFR_RNDN);
+ if (mpfr_nan_p(y) == 0)
+ {
+ printf ("Error: acos(2) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_si (x, -2, MPFR_RNDN);
+ mpfr_acos (y, x, MPFR_RNDN);
+ if (mpfr_nan_p(y) == 0)
+ {
+ printf ("Error: acos(-2) != NaN\n");
+ exit (1);
+ }
+
+ /* acos (1) = 0 */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_acos (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: acos(1) != +0.0\n");
+ exit (1);
+ }
+
+ /* acos (0) = Pi/2 */
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* exact */
+ mpfr_acos (y, x, (mpfr_rnd_t) r);
+ mpfr_const_pi (x, (mpfr_rnd_t) r);
+ mpfr_div_2exp (x, x, 1, MPFR_RNDN); /* exact */
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: acos(0) != Pi/2 for rnd=%s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ }
+
+ /* acos (-1) = Pi */
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ mpfr_set_si (x, -1, MPFR_RNDN); /* exact */
+ mpfr_acos (y, x, (mpfr_rnd_t) r);
+ mpfr_const_pi (x, (mpfr_rnd_t) r);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: acos(1) != Pi for rnd=%s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ }
+
+ test_generic (2, 100, 7);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ data_check ("data/acos", mpfr_acos, "mpfr_acos");
+ bad_cases (mpfr_acos, mpfr_cos, "mpfr_acos", 0, -40, 2, 4, 128, 800, 30);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tacosh.c b/mpfr/tests/tacosh.c
new file mode 100644
index 0000000000..17bedca07d
--- /dev/null
+++ b/mpfr/tests/tacosh.c
@@ -0,0 +1,219 @@
+/* Test file for mpfr_acosh.
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_acosh
+#define TEST_RANDOM_POS 4
+#define TEST_RANDOM_EMIN 1
+#include "tgeneric.c"
+
+#define TEST_FUNCTION mpfr_acosh
+#define TEST_RANDOM_POS 1
+#define TEST_RANDOM_EMIN MPFR_EMAX_MAX
+#define TEST_RANDOM_EMAX MPFR_EMAX_MAX
+#define test_generic test_generic_huge
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ MPFR_SET_INF(x);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_acosh (x, y, MPFR_RNDN);
+ if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) )
+ {
+ printf ("Inf flag not clears in acosh!\n");
+ exit (1);
+ }
+ if (mpfr_cmp_ui (x, 0))
+ {
+ printf ("Error: mpfr_acosh(1) <> 0\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN(x);
+ mpfr_acosh (x, y, MPFR_RNDN);
+ if (MPFR_IS_NAN(x) || MPFR_IS_INF(x) )
+ {
+ printf ("NAN flag not clears in acosh!\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_acosh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_acosh(0) <> NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_acosh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_acosh(-1) <> NaN\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN(x);
+ mpfr_acosh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_acosh(NaN) <> NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_acosh (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: mpfr_acosh(+Inf) <> +Inf\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_acosh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_acosh(-Inf) <> NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 1, MPFR_RNDN);
+ mpfr_acosh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_acosh(1/2) <> NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (x, "1.000001101011101111001011");
+ mpfr_acosh (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.111010100101101001010001101001E-2");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_acosh (1)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+/* With MPFR 2.3.0, this yields an assertion failure in mpfr_acosh. */
+static void
+bug20070831 (void)
+{
+ mpfr_t x, y, z;
+ int inex;
+
+ mpfr_init2 (x, 256);
+ mpfr_init2 (y, 32);
+ mpfr_init2 (z, 32);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_nextabove (x);
+ inex = mpfr_acosh (y, x, MPFR_RNDZ);
+ mpfr_set_ui_2exp (z, 1, -127, MPFR_RNDN);
+ mpfr_nextbelow (z);
+ if (!mpfr_equal_p (y, z))
+ {
+ printf ("Error in bug20070831 (1):\nexpected ");
+ mpfr_dump (z);
+ printf ("got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ MPFR_ASSERTN (inex < 0);
+
+ mpfr_nextabove (x);
+ mpfr_set_prec (y, 29);
+ inex = mpfr_acosh (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (z, "1.011010100000100111100110011E-127");
+ if (!mpfr_equal_p (y, z))
+ {
+ printf ("Error in bug20070831 (2):\nexpected ");
+ mpfr_dump (z);
+ printf ("got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ MPFR_ASSERTN (inex < 0);
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+static void
+huge (void)
+{
+ mpfr_t x, y, z;
+ int inex;
+
+ /* TODO: extend the exponent range and use mpfr_get_emax (). */
+ mpfr_inits2 (32, x, y, z, (mpfr_ptr) 0);
+ mpfr_set_ui_2exp (x, 1, 1073741822, MPFR_RNDN);
+ inex = mpfr_acosh (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (z, "0.10110001011100100001011111110101E30");
+ if (!mpfr_equal_p (y, z))
+ {
+ printf ("Error in huge:\nexpected ");
+ mpfr_dump (z);
+ printf ("got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ MPFR_ASSERTN (inex < 0);
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+ bug20070831 ();
+ huge ();
+
+ test_generic (2, 100, 25);
+ test_generic_huge (2, 100, 5);
+
+ data_check ("data/acosh", mpfr_acosh, "mpfr_acosh");
+ bad_cases (mpfr_acosh, mpfr_cosh, "mpfr_acosh", 0, -128, 29,
+ 4, 128, 800, 40);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tadd.c b/mpfr/tests/tadd.c
new file mode 100644
index 0000000000..7eb5a61ec8
--- /dev/null
+++ b/mpfr/tests/tadd.c
@@ -0,0 +1,1120 @@
+/* Test file for mpfr_add and mpfr_sub.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define N 30000
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+/* If the precisions are the same, we want to test both mpfr_add1sp
+ and mpfr_add1. */
+
+static int usesp;
+
+static int
+test_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ int res;
+#ifdef CHECK_EXTERNAL
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ printf (" ");
+ mpfr_print_raw (c);
+ }
+#endif
+ if (usesp || MPFR_ARE_SINGULAR(b,c) || MPFR_SIGN(b) != MPFR_SIGN(c))
+ res = mpfr_add (a, b, c, rnd_mode);
+ else
+ {
+ if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c))
+ res = mpfr_add1(a, c, b, rnd_mode);
+ else
+ res = mpfr_add1(a, b, c, rnd_mode);
+ }
+#ifdef CHECK_EXTERNAL
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+#endif
+ return res;
+}
+
+/* checks that xs+ys gives the expected result zs */
+static void
+check (const char *xs, const char *ys, mpfr_rnd_t rnd_mode,
+ unsigned int px, unsigned int py, unsigned int pz, const char *zs)
+{
+ mpfr_t xx,yy,zz;
+
+ mpfr_init2 (xx, px);
+ mpfr_init2 (yy, py);
+ mpfr_init2 (zz, pz);
+
+ mpfr_set_str1 (xx, xs);
+ mpfr_set_str1 (yy, ys);
+ test_add (zz, xx, yy, rnd_mode);
+ if (mpfr_cmp_str1 (zz, zs) )
+ {
+ printf ("expected sum is %s, got ", zs);
+ mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
+ printf ("mpfr_add failed for x=%s y=%s with rnd_mode=%s\n",
+ xs, ys, mpfr_print_rnd_mode (rnd_mode));
+ exit (1);
+ }
+ mpfr_clears (xx, yy, zz, (mpfr_ptr) 0);
+}
+
+static void
+check2b (const char *xs, int px,
+ const char *ys, int py,
+ const char *rs, int pz,
+ mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xx, yy, zz;
+
+ mpfr_init2 (xx,px);
+ mpfr_init2 (yy,py);
+ mpfr_init2 (zz,pz);
+ mpfr_set_str_binary (xx, xs);
+ mpfr_set_str_binary (yy, ys);
+ test_add (zz, xx, yy, rnd_mode);
+ if (mpfr_cmp_str (zz, rs, 2, MPFR_RNDN))
+ {
+ printf ("(2) x=%s,%d y=%s,%d pz=%d,rnd=%s\n",
+ xs, px, ys, py, pz, mpfr_print_rnd_mode (rnd_mode));
+ printf ("got "); mpfr_print_binary(zz); puts ("");
+ mpfr_set_str(zz, rs, 2, MPFR_RNDN);
+ printf ("instead of "); mpfr_print_binary(zz); puts ("");
+ exit (1);
+ }
+ mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
+}
+
+static void
+check64 (void)
+{
+ mpfr_t x, t, u;
+
+ mpfr_init (x);
+ mpfr_init (t);
+ mpfr_init (u);
+
+ mpfr_set_prec (x, 29);
+ mpfr_set_str_binary (x, "1.1101001000101111011010010110e-3");
+ mpfr_set_prec (t, 58);
+ mpfr_set_str_binary (t, "0.11100010011111001001100110010111110110011000000100101E-1");
+ mpfr_set_prec (u, 29);
+ test_add (u, x, t, MPFR_RNDD);
+ mpfr_set_str_binary (t, "1.0101011100001000011100111110e-1");
+ if (mpfr_cmp (u, t))
+ {
+ printf ("mpfr_add(u, x, t) failed for prec(x)=29, prec(t)=58\n");
+ printf ("expected "); mpfr_out_str (stdout, 2, 29, t, MPFR_RNDN);
+ puts ("");
+ printf ("got "); mpfr_out_str (stdout, 2, 29, u, MPFR_RNDN);
+ puts ("");
+ exit(1);
+ }
+
+ mpfr_set_prec (x, 4);
+ mpfr_set_str_binary (x, "-1.0E-2");
+ mpfr_set_prec (t, 2);
+ mpfr_set_str_binary (t, "-1.1e-2");
+ mpfr_set_prec (u, 2);
+ test_add (u, x, t, MPFR_RNDN);
+ if (MPFR_MANT(u)[0] << 2)
+ {
+ printf ("result not normalized for prec=2\n");
+ mpfr_print_binary (u); puts ("");
+ exit (1);
+ }
+ mpfr_set_str_binary (t, "-1.0e-1");
+ if (mpfr_cmp (u, t))
+ {
+ printf ("mpfr_add(u, x, t) failed for prec(x)=4, prec(t)=2\n");
+ printf ("expected -1.0e-1\n");
+ printf ("got "); mpfr_out_str (stdout, 2, 4, u, MPFR_RNDN);
+ puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 8);
+ mpfr_set_str_binary (x, "-0.10011010"); /* -77/128 */
+ mpfr_set_prec (t, 4);
+ mpfr_set_str_binary (t, "-1.110e-5"); /* -7/128 */
+ mpfr_set_prec (u, 4);
+ test_add (u, x, t, MPFR_RNDN); /* should give -5/8 */
+ mpfr_set_str_binary (t, "-1.010e-1");
+ if (mpfr_cmp (u, t)) {
+ printf ("mpfr_add(u, x, t) failed for prec(x)=8, prec(t)=4\n");
+ printf ("expected -1.010e-1\n");
+ printf ("got "); mpfr_out_str (stdout, 2, 4, u, MPFR_RNDN);
+ puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 112); mpfr_set_prec (t, 98); mpfr_set_prec (u, 54);
+ mpfr_set_str_binary (x, "-0.11111100100000000011000011100000101101010001000111E-401");
+ mpfr_set_str_binary (t, "0.10110000100100000101101100011111111011101000111000101E-464");
+ test_add (u, x, t, MPFR_RNDN);
+ if (mpfr_cmp (u, x))
+ {
+ printf ("mpfr_add(u, x, t) failed for prec(x)=112, prec(t)=98\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 92); mpfr_set_prec (t, 86); mpfr_set_prec (u, 53);
+ mpfr_set_str (x, "-5.03525136761487735093e-74", 10, MPFR_RNDN);
+ mpfr_set_str (t, "8.51539046314262304109e-91", 10, MPFR_RNDN);
+ test_add (u, x, t, MPFR_RNDN);
+ if (mpfr_cmp_str1 (u, "-5.0352513676148773509283672e-74") )
+ {
+ printf ("mpfr_add(u, x, t) failed for prec(x)=92, prec(t)=86\n");
+ exit (1);
+ }
+
+ mpfr_set_prec(x, 53); mpfr_set_prec(t, 76); mpfr_set_prec(u, 76);
+ mpfr_set_str_binary(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
+ mpfr_set_str_binary(t, "-0.1011000101110010000101111111011111010001110011110111100110101011110010011111");
+ mpfr_sub(u, x, t, MPFR_RNDU);
+ mpfr_set_str_binary(t, "0.1011000101110010000101111111011100111111101010011011110110101011101000000100");
+ if (mpfr_cmp(u,t))
+ {
+ printf ("expect "); mpfr_print_binary(t); puts ("");
+ printf ("mpfr_add failed for precisions 53-76\n");
+ exit (1);
+ }
+ mpfr_set_prec(x, 53); mpfr_set_prec(t, 108); mpfr_set_prec(u, 108);
+ mpfr_set_str_binary(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
+ mpfr_set_str_binary(t, "-0.101100010111001000010111111101111101000111001111011110011010101111001001111000111011001110011000000000111111");
+ mpfr_sub(u, x, t, MPFR_RNDU);
+ mpfr_set_str_binary(t, "0.101100010111001000010111111101110011111110101001101111011010101110100000001011000010101110011000000000111111");
+ if (mpfr_cmp(u,t))
+ {
+ printf ("expect "); mpfr_print_binary(t); puts ("");
+ printf ("mpfr_add failed for precisions 53-108\n");
+ exit (1);
+ }
+ mpfr_set_prec(x, 97); mpfr_set_prec(t, 97); mpfr_set_prec(u, 97);
+ mpfr_set_str_binary(x, "0.1111101100001000000001011000110111101000001011111000100001000101010100011111110010000000000000000E-39");
+ mpfr_set_ui(t, 1, MPFR_RNDN);
+ test_add (u, x, t, MPFR_RNDN);
+ mpfr_set_str_binary(x, "0.1000000000000000000000000000000000000000111110110000100000000101100011011110100000101111100010001E1");
+ if (mpfr_cmp(u,x))
+ {
+ printf ("mpfr_add failed for precision 97\n");
+ exit (1);
+ }
+ mpfr_set_prec(x, 128); mpfr_set_prec(t, 128); mpfr_set_prec(u, 128);
+ mpfr_set_str_binary(x, "0.10101011111001001010111011001000101100111101000000111111111011010100001100011101010001010111111101111010100110111111100101100010E-4");
+ mpfr_set(t, x, MPFR_RNDN);
+ mpfr_sub(u, x, t, MPFR_RNDN);
+ mpfr_set_prec(x, 96); mpfr_set_prec(t, 96); mpfr_set_prec(u, 96);
+ mpfr_set_str_binary(x, "0.111000000001110100111100110101101001001010010011010011100111100011010100011001010011011011000010E-4");
+ mpfr_set(t, x, MPFR_RNDN);
+ mpfr_sub(u, x, t, MPFR_RNDN);
+ mpfr_set_prec(x, 85); mpfr_set_prec(t, 85); mpfr_set_prec(u, 85);
+ mpfr_set_str_binary(x, "0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4");
+ mpfr_set_str_binary(t, "0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4");
+ mpfr_sub(u, x, t, MPFR_RNDU);
+ mpfr_sub(x, x, t, MPFR_RNDU);
+ if (mpfr_cmp(x, u) != 0)
+ {
+ printf ("Error in mpfr_sub: u=x-t and x=x-t give different results\n");
+ exit (1);
+ }
+ if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] &
+ ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0)
+ {
+ printf ("Error in mpfr_sub: result is not msb-normalized (1)\n");
+ exit (1);
+ }
+ mpfr_set_prec(x, 65); mpfr_set_prec(t, 65); mpfr_set_prec(u, 65);
+ mpfr_set_str_binary(x, "0.10011010101000110101010000000011001001001110001011101011111011101E623");
+ mpfr_set_str_binary(t, "0.10011010101000110101010000000011001001001110001011101011111011100E623");
+ mpfr_sub(u, x, t, MPFR_RNDU);
+ if (mpfr_cmp_ui_2exp(u, 1, 558))
+ { /* 2^558 */
+ printf ("Error (1) in mpfr_sub\n");
+ exit (1);
+ }
+
+ mpfr_set_prec(x, 64); mpfr_set_prec(t, 64); mpfr_set_prec(u, 64);
+ mpfr_set_str_binary(x, "0.1000011110101111011110111111000011101011101111101101101100000100E-220");
+ mpfr_set_str_binary(t, "0.1000011110101111011110111111000011101011101111101101010011111101E-220");
+ test_add (u, x, t, MPFR_RNDU);
+ if ((MPFR_MANT(u)[0] & 1) != 1)
+ {
+ printf ("error in mpfr_add with rnd_mode=MPFR_RNDU\n");
+ printf ("b= "); mpfr_print_binary(x); puts ("");
+ printf ("c= "); mpfr_print_binary(t); puts ("");
+ printf ("b+c="); mpfr_print_binary(u); puts ("");
+ exit (1);
+ }
+
+ /* bug found by Norbert Mueller, 14 Sep 2000 */
+ mpfr_set_prec(x, 56); mpfr_set_prec(t, 83); mpfr_set_prec(u, 10);
+ mpfr_set_str_binary(x, "0.10001001011011001111101100110100000101111010010111010111E-7");
+ mpfr_set_str_binary(t, "0.10001001011011001111101100110100000101111010010111010111000000000111110110110000100E-7");
+ mpfr_sub(u, x, t, MPFR_RNDU);
+
+ /* array bound write found by Norbert Mueller, 26 Sep 2000 */
+ mpfr_set_prec(x, 109); mpfr_set_prec(t, 153); mpfr_set_prec(u, 95);
+ mpfr_set_str_binary(x,"0.1001010000101011101100111000110001111111111111111111111111111111111111111111111111111111111111100000000000000E33");
+ mpfr_set_str_binary(t,"-0.100101000010101110110011100011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100101101000000100100001100110111E33");
+ test_add (u, x, t, MPFR_RNDN);
+
+ /* array bound writes found by Norbert Mueller, 27 Sep 2000 */
+ mpfr_set_prec(x, 106); mpfr_set_prec(t, 53); mpfr_set_prec(u, 23);
+ mpfr_set_str_binary(x, "-0.1000011110101111111001010001000100001011000000000000000000000000000000000000000000000000000000000000000000E-59");
+ mpfr_set_str_binary(t, "-0.10000111101011111110010100010001101100011100110100000E-59");
+ mpfr_sub(u, x, t, MPFR_RNDN);
+ mpfr_set_prec(x, 177); mpfr_set_prec(t, 217); mpfr_set_prec(u, 160);
+ mpfr_set_str_binary(x, "-0.111010001011010000111001001010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E35");
+ mpfr_set_str_binary(t, "0.1110100010110100001110010010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111011010011100001111001E35");
+ test_add (u, x, t, MPFR_RNDN);
+ mpfr_set_prec(x, 214); mpfr_set_prec(t, 278); mpfr_set_prec(u, 207);
+ mpfr_set_str_binary(x, "0.1000100110100110101101101101000000010000100111000001001110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E66");
+ mpfr_set_str_binary(t, "-0.10001001101001101011011011010000000100001001110000010011100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111011111001001100011E66");
+ test_add (u, x, t, MPFR_RNDN);
+ mpfr_set_prec(x, 32); mpfr_set_prec(t, 247); mpfr_set_prec(u, 223);
+ mpfr_set_str_binary(x, "0.10000000000000000000000000000000E1");
+ mpfr_set_str_binary(t, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100000100011110000101110110011101110100110110111111011010111100100000000000000000000000000E0");
+ mpfr_sub(u, x, t, MPFR_RNDN);
+ if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] &
+ ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0)
+ {
+ printf ("Error in mpfr_sub: result is not msb-normalized (2)\n");
+ exit (1);
+ }
+
+ /* bug found by Nathalie Revol, 21 March 2001 */
+ mpfr_set_prec (x, 65);
+ mpfr_set_prec (t, 65);
+ mpfr_set_prec (u, 65);
+ mpfr_set_str_binary (x, "0.11100100101101001100111011111111110001101001000011101001001010010E-35");
+ mpfr_set_str_binary (t, "0.10000000000000000000000000000000000001110010010110100110011110000E1");
+ mpfr_sub (u, t, x, MPFR_RNDU);
+ if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] &
+ ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0)
+ {
+ printf ("Error in mpfr_sub: result is not msb-normalized (3)\n");
+ exit (1);
+ }
+
+ /* bug found by Fabrice Rouillier, 27 Mar 2001 */
+ mpfr_set_prec (x, 107);
+ mpfr_set_prec (t, 107);
+ mpfr_set_prec (u, 107);
+ mpfr_set_str_binary (x, "0.10111001001111010010001000000010111111011011011101000001001000101000000000000000000000000000000000000000000E315");
+ mpfr_set_str_binary (t, "0.10000000000000000000000000000000000101110100100101110110000001100101011111001000011101111100100100111011000E350");
+ mpfr_sub (u, x, t, MPFR_RNDU);
+ if ((MPFR_MANT(u)[(MPFR_PREC(u)-1)/mp_bits_per_limb] &
+ ((mp_limb_t)1<<(mp_bits_per_limb-1)))==0)
+ {
+ printf ("Error in mpfr_sub: result is not msb-normalized (4)\n");
+ exit (1);
+ }
+
+ /* checks that NaN flag is correctly reset */
+ mpfr_set_ui (t, 1, MPFR_RNDN);
+ mpfr_set_ui (u, 1, MPFR_RNDN);
+ mpfr_set_nan (x);
+ test_add (x, t, u, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 2))
+ {
+ printf ("Error in mpfr_add: 1+1 gives ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
+ exit (1);
+ }
+
+ mpfr_clear(x); mpfr_clear(t); mpfr_clear(u);
+}
+
+/* check case when c does not overlap with a, but both b and c count
+ for rounding */
+static void
+check_case_1b (void)
+{
+ mpfr_t a, b, c;
+ unsigned int prec_a, prec_b, prec_c, dif;
+
+ mpfr_init (a);
+ mpfr_init (b);
+ mpfr_init (c);
+
+ {
+ prec_a = MPFR_PREC_MIN + (randlimb () % 63);
+ mpfr_set_prec (a, prec_a);
+ for (prec_b = prec_a + 2; prec_b <= 64; prec_b++)
+ {
+ dif = prec_b - prec_a;
+ mpfr_set_prec (b, prec_b);
+ /* b = 1 - 2^(-prec_a) + 2^(-prec_b) */
+ mpfr_set_ui (b, 1, MPFR_RNDN);
+ mpfr_div_2exp (b, b, dif, MPFR_RNDN);
+ mpfr_sub_ui (b, b, 1, MPFR_RNDN);
+ mpfr_div_2exp (b, b, prec_a, MPFR_RNDN);
+ mpfr_add_ui (b, b, 1, MPFR_RNDN);
+ for (prec_c = dif; prec_c <= 64; prec_c++)
+ {
+ /* c = 2^(-prec_a) - 2^(-prec_b) */
+ mpfr_set_prec (c, prec_c);
+ mpfr_set_si (c, -1, MPFR_RNDN);
+ mpfr_div_2exp (c, c, dif, MPFR_RNDN);
+ mpfr_add_ui (c, c, 1, MPFR_RNDN);
+ mpfr_div_2exp (c, c, prec_a, MPFR_RNDN);
+ test_add (a, b, c, MPFR_RNDN);
+ if (mpfr_cmp_ui (a, 1) != 0)
+ {
+ printf ("case (1b) failed for prec_a=%u, prec_b=%u,"
+ " prec_c=%u\n", prec_a, prec_b, prec_c);
+ printf ("b="); mpfr_print_binary(b); puts ("");
+ printf ("c="); mpfr_print_binary(c); puts ("");
+ printf ("a="); mpfr_print_binary(a); puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+ mpfr_clear (c);
+}
+
+/* check case when c overlaps with a */
+static void
+check_case_2 (void)
+{
+ mpfr_t a, b, c, d;
+
+ mpfr_init2 (a, 300);
+ mpfr_init2 (b, 800);
+ mpfr_init2 (c, 500);
+ mpfr_init2 (d, 800);
+
+ mpfr_set_str_binary(a, "1E110"); /* a = 2^110 */
+ mpfr_set_str_binary(b, "1E900"); /* b = 2^900 */
+ mpfr_set_str_binary(c, "1E500"); /* c = 2^500 */
+ test_add (c, c, a, MPFR_RNDZ); /* c = 2^500 + 2^110 */
+ mpfr_sub (d, b, c, MPFR_RNDZ); /* d = 2^900 - 2^500 - 2^110 */
+ test_add (b, b, c, MPFR_RNDZ); /* b = 2^900 + 2^500 + 2^110 */
+ test_add (a, b, d, MPFR_RNDZ); /* a = 2^901 */
+ if (mpfr_cmp_ui_2exp (a, 1, 901))
+ {
+ printf ("b + d fails for b=2^900+2^500+2^110, d=2^900-2^500-2^110\n");
+ printf ("expected 1.0e901, got ");
+ mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+ mpfr_clear (c);
+ mpfr_clear (d);
+}
+
+/* checks when source and destination are equal */
+static void
+check_same (void)
+{
+ mpfr_t x;
+
+ mpfr_init(x); mpfr_set_ui(x, 1, MPFR_RNDZ);
+ test_add (x, x, x, MPFR_RNDZ);
+ if (mpfr_cmp_ui (x, 2))
+ {
+ printf ("Error when all 3 operands are equal\n");
+ exit (1);
+ }
+ mpfr_clear(x);
+}
+
+#define check53(x, y, r, z) check(x, y, r, 53, 53, 53, z)
+
+#define MAX_PREC 256
+
+static void
+check_inexact (void)
+{
+ mpfr_t x, y, z, u;
+ mpfr_prec_t px, py, pu, pz;
+ int inexact, cmp;
+ mpfr_rnd_t rnd;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (u);
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_str_binary (x, "0.1E-4");
+ mpfr_set_prec (u, 33);
+ mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1");
+ mpfr_set_prec (y, 31);
+ if ((inexact = test_add (y, x, u, MPFR_RNDN)))
+ {
+ printf ("Wrong inexact flag (2): expected 0, got %d\n", inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_str_binary (x, "0.1E-4");
+ mpfr_set_prec (u, 33);
+ mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1");
+ mpfr_set_prec (y, 28);
+ if ((inexact = test_add (y, x, u, MPFR_RNDN)))
+ {
+ printf ("Wrong inexact flag (1): expected 0, got %d\n", inexact);
+ exit (1);
+ }
+
+ for (px=2; px<MAX_PREC; px++)
+ {
+ mpfr_set_prec (x, px);
+ do
+ {
+ mpfr_urandomb (x, RANDS);
+ }
+ while (mpfr_cmp_ui (x, 0) == 0);
+ for (pu=2; pu<MAX_PREC; pu++)
+ {
+ mpfr_set_prec (u, pu);
+ do
+ {
+ mpfr_urandomb (u, RANDS);
+ }
+ while (mpfr_cmp_ui (u, 0) == 0);
+ {
+ py = MPFR_PREC_MIN + (randlimb () % (MAX_PREC - 1));
+ mpfr_set_prec (y, py);
+ pz = (mpfr_cmpabs (x, u) >= 0) ? MPFR_EXP(x) - MPFR_EXP(u)
+ : MPFR_EXP(u) - MPFR_EXP(x);
+ /* x + u is exactly representable with precision
+ abs(EXP(x)-EXP(u)) + max(prec(x), prec(u)) + 1 */
+ pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u)) + 1;
+ mpfr_set_prec (z, pz);
+ rnd = RND_RAND ();
+ if (test_add (z, x, u, rnd))
+ {
+ printf ("z <- x + u should be exact\n");
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("u="); mpfr_print_binary (u); puts ("");
+ printf ("z="); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+ {
+ rnd = RND_RAND ();
+ inexact = test_add (y, x, u, rnd);
+ cmp = mpfr_cmp (y, z);
+ if (((inexact == 0) && (cmp != 0)) ||
+ ((inexact > 0) && (cmp <= 0)) ||
+ ((inexact < 0) && (cmp >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s\n",
+ mpfr_print_rnd_mode(rnd));
+ printf ("expected %d, got %d\n", cmp, inexact);
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("u="); mpfr_print_binary (u); puts ("");
+ printf ("y= "); mpfr_print_binary (y); puts ("");
+ printf ("x+u="); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (u);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t s, x, y;
+
+ mpfr_init2 (x, 8L);
+ mpfr_init2 (y, 8L);
+ mpfr_init2 (s, 8L);
+
+ /* +inf + -inf == nan */
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, -1);
+ test_add (s, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (s));
+
+ /* +inf + 1 == +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_set_ui (y, 1L, MPFR_RNDN);
+ test_add (s, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (s));
+ MPFR_ASSERTN (mpfr_sgn (s) > 0);
+
+ /* -inf + 1 == -inf */
+ mpfr_set_inf (x, -1);
+ mpfr_set_ui (y, 1L, MPFR_RNDN);
+ test_add (s, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (s));
+ MPFR_ASSERTN (mpfr_sgn (s) < 0);
+
+ /* 1 + +inf == +inf */
+ mpfr_set_ui (x, 1L, MPFR_RNDN);
+ mpfr_set_inf (y, 1);
+ test_add (s, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (s));
+ MPFR_ASSERTN (mpfr_sgn (s) > 0);
+
+ /* 1 + -inf == -inf */
+ mpfr_set_ui (x, 1L, MPFR_RNDN);
+ mpfr_set_inf (y, -1);
+ test_add (s, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (s));
+ MPFR_ASSERTN (mpfr_sgn (s) < 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (s);
+}
+
+static void
+check_alloc (void)
+{
+ mpfr_t a;
+
+ mpfr_init2 (a, 10000);
+ mpfr_set_prec (a, 53);
+ mpfr_set_ui (a, 15236, MPFR_RNDN);
+ test_add (a, a, a, MPFR_RNDN);
+ mpfr_mul (a, a, a, MPFR_RNDN);
+ mpfr_div (a, a, a, MPFR_RNDN);
+ mpfr_sub (a, a, a, MPFR_RNDN);
+ mpfr_clear (a);
+}
+
+static void
+check_overflow (void)
+{
+ mpfr_t a, b, c;
+ mpfr_prec_t prec_a;
+ int r;
+
+ mpfr_init2 (a, 256);
+ mpfr_init2 (b, 256);
+ mpfr_init2 (c, 256);
+
+ mpfr_set_ui (b, 1, MPFR_RNDN);
+ mpfr_setmax (b, mpfr_get_emax ());
+ mpfr_set_ui (c, 1, MPFR_RNDN);
+ mpfr_set_exp (c, mpfr_get_emax () - 192);
+ RND_LOOP(r)
+ for (prec_a = 128; prec_a < 512; prec_a += 64)
+ {
+ mpfr_set_prec (a, prec_a);
+ mpfr_clear_overflow ();
+ test_add (a, b, c, (mpfr_rnd_t) r);
+ if (!mpfr_overflow_p ())
+ {
+ printf ("No overflow in check_overflow\n");
+ exit (1);
+ }
+ }
+
+ mpfr_set_exp (c, mpfr_get_emax () - 512);
+ mpfr_set_prec (a, 256);
+ mpfr_clear_overflow ();
+ test_add (a, b, c, MPFR_RNDU);
+ if (!mpfr_overflow_p ())
+ {
+ printf ("No overflow in check_overflow\n");
+ exit (1);
+ }
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+ mpfr_clear (c);
+}
+
+static void
+check_1111 (void)
+{
+ mpfr_t one;
+ long n;
+
+ mpfr_init2 (one, MPFR_PREC_MIN);
+ mpfr_set_ui (one, 1, MPFR_RNDN);
+ for (n = 0; n < N; n++)
+ {
+ mpfr_prec_t prec_a, prec_b, prec_c;
+ mpfr_exp_t tb=0, tc, diff;
+ mpfr_t a, b, c, s;
+ int m = 512;
+ int sb, sc;
+ int inex_a, inex_s;
+ mpfr_rnd_t rnd_mode;
+
+ prec_a = MPFR_PREC_MIN + (randlimb () % m);
+ prec_b = MPFR_PREC_MIN + (randlimb () % m);
+ prec_c = MPFR_PREC_MIN + (randlimb () % m);
+ mpfr_init2 (a, prec_a);
+ mpfr_init2 (b, prec_b);
+ mpfr_init2 (c, prec_c);
+ sb = randlimb () % 3;
+ if (sb != 0)
+ {
+ tb = 1 + (randlimb () % (prec_b - (sb != 2)));
+ mpfr_div_2ui (b, one, tb, MPFR_RNDN);
+ if (sb == 2)
+ mpfr_neg (b, b, MPFR_RNDN);
+ test_add (b, b, one, MPFR_RNDN);
+ }
+ else
+ mpfr_set (b, one, MPFR_RNDN);
+ tc = 1 + (randlimb () % (prec_c - 1));
+ mpfr_div_2ui (c, one, tc, MPFR_RNDN);
+ sc = randlimb () % 2;
+ if (sc)
+ mpfr_neg (c, c, MPFR_RNDN);
+ test_add (c, c, one, MPFR_RNDN);
+ diff = (randlimb () % (2*m)) - m;
+ mpfr_mul_2si (c, c, diff, MPFR_RNDN);
+ rnd_mode = RND_RAND ();
+ inex_a = test_add (a, b, c, rnd_mode);
+ mpfr_init2 (s, MPFR_PREC_MIN + 2*m);
+ inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */
+ if (inex_s)
+ {
+ printf ("check_1111: result should have been exact.\n");
+ exit (1);
+ }
+ inex_s = mpfr_prec_round (s, prec_a, rnd_mode);
+ if ((inex_a < 0 && inex_s >= 0) ||
+ (inex_a == 0 && inex_s != 0) ||
+ (inex_a > 0 && inex_s <= 0) ||
+ !mpfr_equal_p (a, s))
+ {
+ printf ("check_1111: results are different.\n");
+ printf ("prec_a = %d, prec_b = %d, prec_c = %d\n",
+ (int) prec_a, (int) prec_b, (int) prec_c);
+ printf ("tb = %d, tc = %d, diff = %d, rnd = %s\n",
+ (int) tb, (int) tc, (int) diff,
+ mpfr_print_rnd_mode (rnd_mode));
+ printf ("sb = %d, sc = %d\n", sb, sc);
+ printf ("a = "); mpfr_print_binary (a); puts ("");
+ printf ("s = "); mpfr_print_binary (s); puts ("");
+ printf ("inex_a = %d, inex_s = %d\n", inex_a, inex_s);
+ exit (1);
+ }
+ mpfr_clear (a);
+ mpfr_clear (b);
+ mpfr_clear (c);
+ mpfr_clear (s);
+ }
+ mpfr_clear (one);
+}
+
+static void
+check_1minuseps (void)
+{
+ static mpfr_prec_t prec_a[] = {
+ MPFR_PREC_MIN, 30, 31, 32, 33, 62, 63, 64, 65, 126, 127, 128, 129
+ };
+ static int supp_b[] = {
+ 0, 1, 2, 3, 4, 29, 30, 31, 32, 33, 34, 35, 61, 62, 63, 64, 65, 66, 67
+ };
+ mpfr_t a, b, c;
+ unsigned int ia, ib, ic;
+
+ mpfr_init2 (c, MPFR_PREC_MIN);
+
+ for (ia = 0; ia < numberof (prec_a); ia++)
+ for (ib = 0; ib < numberof(supp_b); ib++)
+ {
+ mpfr_prec_t prec_b;
+ int rnd_mode;
+
+ prec_b = prec_a[ia] + supp_b[ib];
+
+ mpfr_init2 (a, prec_a[ia]);
+ mpfr_init2 (b, prec_b);
+
+ mpfr_set_ui (c, 1, MPFR_RNDN);
+ mpfr_div_ui (b, c, prec_a[ia], MPFR_RNDN);
+ mpfr_sub (b, c, b, MPFR_RNDN); /* b = 1 - 2^(-prec_a) */
+
+ for (ic = 0; ic < numberof(supp_b); ic++)
+ for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++)
+ {
+ mpfr_t s;
+ int inex_a, inex_s;
+
+ mpfr_set_ui (c, 1, MPFR_RNDN);
+ mpfr_div_ui (c, c, prec_a[ia] + supp_b[ic], MPFR_RNDN);
+ inex_a = test_add (a, b, c, (mpfr_rnd_t) rnd_mode);
+ mpfr_init2 (s, 256);
+ inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */
+ if (inex_s)
+ {
+ printf ("check_1minuseps: result should have been exact "
+ "(ia = %u, ib = %u, ic = %u)\n", ia, ib, ic);
+ exit (1);
+ }
+ inex_s = mpfr_prec_round (s, prec_a[ia], (mpfr_rnd_t) rnd_mode);
+ if ((inex_a < 0 && inex_s >= 0) ||
+ (inex_a == 0 && inex_s != 0) ||
+ (inex_a > 0 && inex_s <= 0) ||
+ !mpfr_equal_p (a, s))
+ {
+ printf ("check_1minuseps: results are different.\n");
+ printf ("ia = %u, ib = %u, ic = %u\n", ia, ib, ic);
+ exit (1);
+ }
+ mpfr_clear (s);
+ }
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+ }
+
+ mpfr_clear (c);
+}
+
+/* Test case bk == 0 in add1.c (b has entirely been read and
+ c hasn't been taken into account). */
+static void
+coverage_bk_eq_0 (void)
+{
+ mpfr_t a, b, c;
+ int inex;
+
+ mpfr_init2 (a, GMP_NUMB_BITS);
+ mpfr_init2 (b, 2 * GMP_NUMB_BITS);
+ mpfr_init2 (c, GMP_NUMB_BITS);
+
+ mpfr_set_ui_2exp (b, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN);
+ mpfr_sub_ui (b, b, 1, MPFR_RNDN);
+ /* b = 111...111 (in base 2) where the 1's fit 2 whole limbs */
+
+ mpfr_set_ui_2exp (c, 1, -1, MPFR_RNDN); /* c = 1/2 */
+
+ inex = mpfr_add (a, b, c, MPFR_RNDU);
+ mpfr_set_ui_2exp (c, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN);
+ if (! mpfr_equal_p (a, c))
+ {
+ printf ("Error in coverage_bk_eq_0\n");
+ printf ("Expected ");
+ mpfr_dump (c);
+ printf ("Got ");
+ mpfr_dump (a);
+ exit (1);
+ }
+ MPFR_ASSERTN (inex > 0);
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+ mpfr_clear (c);
+}
+
+static void
+tests (void)
+{
+ check_alloc ();
+ check_nans ();
+ check_inexact ();
+ check_case_1b ();
+ check_case_2 ();
+ check64();
+ coverage_bk_eq_0 ();
+
+ check("293607738.0", "1.9967571564050541e-5", MPFR_RNDU, 64, 53, 53,
+ "2.9360773800002003e8");
+ check("880524.0", "-2.0769715792901673e-5", MPFR_RNDN, 64, 53, 53,
+ "8.8052399997923023e5");
+ check("1196426492.0", "-1.4218093058435347e-3", MPFR_RNDN, 64, 53, 53,
+ "1.1964264919985781e9");
+ check("982013018.0", "-8.941829477291838e-7", MPFR_RNDN, 64, 53, 53,
+ "9.8201301799999905e8");
+ check("1092583421.0", "1.0880649218158844e9", MPFR_RNDN, 64, 53, 53,
+ "2.1806483428158846e9");
+ check("1.8476886419022969e-6", "961494401.0", MPFR_RNDN, 53, 64, 53,
+ "9.6149440100000179e8");
+ check("-2.3222118418069868e5", "1229318102.0", MPFR_RNDN, 53, 64, 53,
+ "1.2290858808158193e9");
+ check("-3.0399171300395734e-6", "874924868.0", MPFR_RNDN, 53, 64, 53,
+ "8.749248679999969e8");
+ check("9.064246624706179e1", "663787413.0", MPFR_RNDN, 53, 64, 53,
+ "6.6378750364246619e8");
+ check("-1.0954322421551264e2", "281806592.0", MPFR_RNDD, 53, 64, 53,
+ "2.8180648245677572e8");
+ check("5.9836930386056659e-8", "1016217213.0", MPFR_RNDN, 53, 64, 53,
+ "1.0162172130000001e9");
+ check("-1.2772161928500301e-7", "1237734238.0", MPFR_RNDN, 53, 64, 53,
+ "1.2377342379999998e9");
+ check("-4.567291988483277e8", "1262857194.0", MPFR_RNDN, 53, 64, 53,
+ "8.0612799515167236e8");
+ check("4.7719471752925262e7", "196089880.0", MPFR_RNDN, 53, 53, 53,
+ "2.4380935175292528e8");
+ check("4.7719471752925262e7", "196089880.0", MPFR_RNDN, 53, 64, 53,
+ "2.4380935175292528e8");
+ check("-1.716113812768534e-140", "1271212614.0", MPFR_RNDZ, 53, 64, 53,
+ "1.2712126139999998e9");
+ check("-1.2927455200185474e-50", "1675676122.0", MPFR_RNDD, 53, 64, 53,
+ "1.6756761219999998e9");
+
+ check53("1.22191250737771397120e+20", "948002822.0", MPFR_RNDN,
+ "122191250738719408128.0");
+ check53("9966027674114492.0", "1780341389094537.0", MPFR_RNDN,
+ "11746369063209028.0");
+ check53("2.99280481918991653800e+272", "5.34637717585790933424e+271",
+ MPFR_RNDN, "3.5274425367757071711e272");
+ check_same();
+ check53("6.14384195492641560499e-02", "-6.14384195401037683237e-02",
+ MPFR_RNDU, "9.1603877261370314499e-12");
+ check53("1.16809465359248765399e+196", "7.92883212101990665259e+196",
+ MPFR_RNDU, "9.0969267746123943065e196");
+ check53("3.14553393112021279444e-67", "3.14553401015952024126e-67", MPFR_RNDU,
+ "6.2910679412797336946e-67");
+
+ check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDN,
+ "5.4388530464436950905e185");
+ check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDZ,
+ "5.4388530464436944867e185");
+ check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDU,
+ "5.4388530464436950905e185");
+ check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDD,
+ "5.4388530464436944867e185");
+
+ check2b("1.001010101110011000000010100101110010111001010000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e358",187,
+ "-1.11100111001101100010001111111110101101110001000000000000000000000000000000000000000000e160",87,
+ "1.001010101110011000000010100101110010111001010000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e358",178,
+ MPFR_RNDD);
+ check2b("-1.111100100011100111010101010101001010100100000111001000000000000000000e481",70,
+ "1.1111000110100011110101111110110010010000000110101000000000000000e481",65,
+ "-1.001010111111101011010000001100011101100101000000000000000000e472",61,
+ MPFR_RNDD);
+ check2b("1.0100010111010000100101000000111110011100011001011010000000000000000000000000000000e516",83,
+ "-1.1001111000100001011100000001001100110011110010111111000000e541",59,
+ "-1.1001111000100001011011110111000001001011100000011110100000110001110011010011000000000000000000000000000000000000000000000000e541",125,
+ MPFR_RNDZ);
+ check2b("-1.0010111100000100110001011011010000000011000111101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e261",155,
+ "-1.00111110100011e239",15,
+ "-1.00101111000001001100101010101110001100110001111010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e261",159,
+ MPFR_RNDD);
+ check2b("-1.110111000011111011000000001001111101101001010100111000000000000000000000000e880",76,
+ "-1.1010010e-634",8,
+ "-1.11011100001111101100000000100111110110100101010011100000000000000000000000e880",75,
+ MPFR_RNDZ);
+ check2b("1.00100100110110101001010010101111000001011100100101010000000000000000000000000000e-530",81,
+ "-1.101101111100000111000011001010110011001011101001110100000e-908",58,
+ "1.00100100110110101001010010101111000001011100100101010e-530",54,
+ MPFR_RNDN);
+ check2b("1.0101100010010111101000000001000010010010011000111011000000000000000000000000000000000000000000000000000000000000000000e374",119,
+ "1.11100101100101e358",15,
+ "1.01011000100110011000010110100100100100100110001110110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e374",150,
+ MPFR_RNDZ);
+ check2b("-1.10011001000010100000010100100110110010011111101111000000000000000000000000000000000000000000000000000000000000000000e-172",117,
+ "1.111011100000101010110000100100110100100001001000011100000000e-173",61,
+ "-1.0100010000001001010110011011101001001011101011110001000000000000000e-173",68,
+ MPFR_RNDZ);
+ check2b("-1.011110000111101011100001100110100011100101000011011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-189",175,
+ "1.1e631",2,
+ "1.011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e631",115,
+ MPFR_RNDZ);
+ check2b("-1.101011101001011101100011001000001100010100001101011000000000000000000000000000000000000000000e-449",94,
+ "-1.01111101010111000011000110011101000111001100110111100000000000000e-429",66,
+ "-1.01111101010111000100110010000110100100101111111111101100010100001101011000000000000000000000000000000000000000e-429",111,
+ MPFR_RNDU);
+ check2b("-1.101011101001011101100011001000001100010100001101011000000000000000000000000000000000000000000e-449",94,
+ "-1.01111101010111000011000110011101000111001100110111100000000000000e-429",66,
+ "-1.01111101010111000100110010000110100100101111111111101100010100001101011000000000000000000000000000000000000000e-429",111,
+ MPFR_RNDD);
+ check2b("-1.1001000011101000110000111110010100100101110101111100000000000000000000000000000000000000000000000000000000e-72",107,
+ "-1.001100011101100100010101101010101011010010111111010000000000000000000000000000e521",79,
+ "-1.00110001110110010001010110101010101101001011111101000000000000000000000000000000000000000000000001e521",99,
+ MPFR_RNDD);
+ check2b("-1.01010001111000000101010100100100110101011011100001110000000000e498",63,
+ "1.010000011010101111000100111100011100010101011110010100000000000e243",64,
+ "-1.010100011110000001010101001001001101010110111000011100000000000e498",64,
+ MPFR_RNDN);
+ check2b("1.00101100010101000011010000011000111111011110010111000000000000000000000000000000000000000000000000000000000e178",108,
+ "-1.10101101010101000110011011111001001101111111110000100000000e160",60,
+ "1.00101100010100111100100011000011111001000010011101110010000000001111100000000000000000000000000000000000e178",105,
+ MPFR_RNDN);
+ check2b("1.00110011010100111110011010110100111101110101100100110000000000000000000000000000000000000000000000e559",99,
+ "-1.011010110100111011100110100110011100000000111010011000000000000000e559",67,
+ "-1.101111111101011111111111001001100100011100001001100000000000000000000000000000000000000000000e556",94,
+ MPFR_RNDU);
+ check2b("-1.100000111100101001100111011100011011000001101001111100000000000000000000000000e843",79,
+ "-1.1101101010110000001001000100001100110011000110110111000000000000000000000000000000000000000000e414",95,
+ "-1.1000001111001010011001110111000110110000011010100000e843",53,
+ MPFR_RNDD);
+ check2b("-1.110110010110100010100011000110111001010000010111110000000000e-415",61,
+ "-1.0000100101100001111100110011111111110100011101101011000000000000000000e751",71,
+ "-1.00001001011000011111001100111111111101000111011010110e751",54,
+ MPFR_RNDN);
+ check2b("-1.1011011011110001001101010101001000010100010110111101000000000000000000000e258",74,
+ "-1.00011100010110110101001011000100100000100010101000010000000000000000000000000000000000000000000000e268",99,
+ "-1.0001110011001001000011110001000111010110101011110010011011110100000000000000000000000000000000000000e268",101,
+ MPFR_RNDD);
+ check2b("-1.1011101010011101011000000100100110101101101110000001000000000e629",62,
+ "1.111111100000011100100011100000011101100110111110111000000000000000000000000000000000000000000e525",94,
+ "-1.101110101001110101100000010010011010110110111000000011111111111111111111111111111111111111111111111111101e629",106,
+ MPFR_RNDD);
+ check2b("1.111001000010001100010000001100000110001011110111011000000000000000000000000000000000000e152",88,
+ "1.111110111001100100000100111111010111000100111111001000000000000000e152",67,
+ "1.1110111111011110000010101001011011101010000110110100e153",53,
+ MPFR_RNDN);
+ check2b("1.000001100011110010110000110100001010101101111011110100e696",55,
+ "-1.1011001111011100100001011110100101010101110111010101000000000000000000000000000000000000000000000000000000000000e730",113,
+ "-1.1011001111011100100001011110100100010100010011100010e730",53,
+ MPFR_RNDN);
+ check2b("-1.11010111100001001111000001110101010010001111111001100000000000000000000000000000000000000000000000000000000000e530",111,
+ "1.01110100010010000000010110111101011101000001111101100000000000000000000000000000000000000000000000e530",99,
+ "-1.1000110011110011101010101101111101010011011111000000000000000e528",62,
+ MPFR_RNDD);
+ check2b("-1.0001100010010100111101101011101000100100010011100011000000000000000000000000000000000000000000000000000000000e733",110,
+ "-1.001000000111110010100101010100110111001111011011001000000000000000000000000000000000000000000000000000000000e710",109,
+ "-1.000110001001010011111000111110110001110110011000110110e733",55,
+ MPFR_RNDN);
+ check2b("-1.1101011110000100111100000111010101001000111111100110000000000000000000000e530",74,
+ "1.01110100010010000000010110111101011101000001111101100000000000000000000000000000000000000000000000000000000000e530",111,
+ "-1.10001100111100111010101011011111010100110111110000000000000000000000000000e528",75,
+ MPFR_RNDU);
+ check2b("1.00110011010100111110011010110100111101110101100100110000000000000000000000000000000000000000000000e559",99,
+ "-1.011010110100111011100110100110011100000000111010011000000000000000e559",67,
+ "-1.101111111101011111111111001001100100011100001001100000000000000000000000000000000000000000000e556",94,
+ MPFR_RNDU);
+ check2b("-1.100101111110110000000110111111011010011101101111100100000000000000e-624",67,
+ "1.10111010101110100000010110101000000000010011100000100000000e-587",60,
+ "1.1011101010111010000001011010011111110100011110001011111111001000000100101100010010000011100000000000000000000e-587",110,
+ MPFR_RNDU);
+ check2b("-1.10011001000010100000010100100110110010011111101111000000000000000000000000000000000000000000000000000000000000000000e-172",117,
+ "1.111011100000101010110000100100110100100001001000011100000000e-173",61,
+ "-1.0100010000001001010110011011101001001011101011110001000000000000000e-173",68,
+ MPFR_RNDZ);
+ check2b("1.1000111000110010101001010011010011101100010110001001000000000000000000000000000000000000000000000000e167",101,
+ "1.0011110010000110000000101100100111000001110110110000000000000000000000000e167",74,
+ "1.01100101010111000101001111111111010101110001100111001000000000000000000000000000000000000000000000000000e168",105,
+ MPFR_RNDZ);
+ check2b("1.100101111111110010100101110111100001110000100001010000000000000000000000000000000000000000000000e808",97,
+ "-1.1110011001100000100000111111110000110010100111001011000000000000000000000000000000e807",83,
+ "1.01001001100110001100011111000000000001011010010111010000000000000000000000000000000000000000000e807",96,
+ MPFR_RNDN);
+ check2b("1e128",128,
+ "1e0",128,
+ "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e0",256,
+ MPFR_RNDN);
+
+ /* Checking double precision (53 bits) */
+ check53("-8.22183238641455905806e-19", "7.42227178769761587878e-19",MPFR_RNDD,
+ "-7.9956059871694317927e-20");
+ check53("5.82106394662028628236e+234","-5.21514064202368477230e+89",MPFR_RNDD,
+ "5.8210639466202855763e234");
+ check53("5.72931679569871602371e+122","-5.72886070363264321230e+122",
+ MPFR_RNDN, "4.5609206607281141508e118");
+ check53("-5.09937369394650450820e+238", "2.70203299854862982387e+250",
+ MPFR_RNDD, "2.7020329985435301323e250");
+ check53("-2.96695924472363684394e+27", "1.22842938251111500000e+16",MPFR_RNDD,
+ "-2.96695924471135255027e27");
+ check53("1.74693641655743793422e-227", "-7.71776956366861843469e-229",
+ MPFR_RNDN, "1.669758720920751867e-227");
+ /* x = -7883040437021647.0; for (i=0; i<468; i++) x = x / 2.0;*/
+ check53("-1.03432206392780011159e-125", "1.30127034799251347548e-133",
+ MPFR_RNDN,
+ "-1.0343220509150965661100887242027378881805094180354e-125");
+ check53("1.05824655795525779205e+71", "-1.06022698059744327881e+71",MPFR_RNDZ,
+ "-1.9804226421854867632e68");
+ check53("-5.84204911040921732219e+240", "7.26658169050749590763e+240",
+ MPFR_RNDD, "1.4245325800982785854e240");
+ check53("1.00944884131046636376e+221","2.33809162651471520268e+215",MPFR_RNDN,
+ "1.0094511794020929787e221");
+ /*x = 7045852550057985.0; for (i=0; i<986; i++) x = x / 2.0;*/
+ check53("4.29232078932667367325e-278",
+ "1.0773525047389793833221116707010783793203080117586e-281"
+ , MPFR_RNDU, "4.2933981418314132787e-278");
+ check53("5.27584773801377058681e-80", "8.91207657803547196421e-91", MPFR_RNDN,
+ "5.2758477381028917269e-80");
+ check53("2.99280481918991653800e+272", "5.34637717585790933424e+271",
+ MPFR_RNDN, "3.5274425367757071711e272");
+ check53("4.67302514390488041733e-184", "2.18321376145645689945e-190",
+ MPFR_RNDN, "4.6730273271186420541e-184");
+ check53("5.57294120336300389254e+71", "2.60596167942024924040e+65", MPFR_RNDZ,
+ "5.5729438093246831053e71");
+ check53("6.6052588496951015469e24", "4938448004894539.0", MPFR_RNDU,
+ "6.6052588546335505068e24");
+ check53("1.23056185051606761523e-190", "1.64589756643433857138e-181",
+ MPFR_RNDU, "1.6458975676649006598e-181");
+ check53("2.93231171510175981584e-280", "3.26266919161341483877e-273",
+ MPFR_RNDU, "3.2626694848445867288e-273");
+ check53("5.76707395945001907217e-58", "4.74752971449827687074e-51", MPFR_RNDD,
+ "4.747530291205672325e-51");
+ check53("277363943109.0", "11.0", MPFR_RNDN, "277363943120.0");
+ check53("1.44791789689198883921e-140", "-1.90982880222349071284e-121",
+ MPFR_RNDN, "-1.90982880222349071e-121");
+
+
+ /* tests for particular cases (Vincent Lefevre, 22 Aug 2001) */
+ check53("9007199254740992.0", "1.0", MPFR_RNDN, "9007199254740992.0");
+ check53("9007199254740994.0", "1.0", MPFR_RNDN, "9007199254740996.0");
+ check53("9007199254740992.0", "-1.0", MPFR_RNDN, "9007199254740991.0");
+ check53("9007199254740994.0", "-1.0", MPFR_RNDN, "9007199254740992.0");
+ check53("9007199254740996.0", "-1.0", MPFR_RNDN, "9007199254740996.0");
+
+ check_overflow ();
+ check_1111 ();
+ check_1minuseps ();
+}
+
+#define TEST_FUNCTION test_add
+#define TWO_ARGS
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ usesp = 0;
+ tests ();
+
+#ifndef CHECK_EXTERNAL /* no need to check twice */
+ usesp = 1;
+ tests ();
+#endif
+ test_generic (2, 1000, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tadd1sp.c b/mpfr/tests/tadd1sp.c
new file mode 100644
index 0000000000..1ca4444f24
--- /dev/null
+++ b/mpfr/tests/tadd1sp.c
@@ -0,0 +1,189 @@
+/* Test file for mpfr_add1sp.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void check_special (void);
+static void check_random (mpfr_prec_t p);
+
+static void
+check_overflow (void)
+{
+ mpfr_t x, y, z1, z2;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ set_emin (-1021);
+ set_emax (1024);
+
+ mpfr_inits (x, y, z1, z2, (mpfr_ptr) 0);
+
+ mpfr_set_str1 (x, "8.00468257869324898448e+307");
+ mpfr_set_str1 (y, "7.44784712422708645156e+307");
+ mpfr_add1sp (z1, x, y, MPFR_RNDN);
+ mpfr_add1 (z2, x, y, MPFR_RNDN);
+ if (mpfr_cmp (z1, z2))
+ {
+ printf ("Overflow bug in add1sp.\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
+
+ set_emin (emin);
+ set_emax (emax);
+}
+
+int
+main (void)
+{
+ mpfr_prec_t p;
+
+ tests_start_mpfr ();
+
+ check_special ();
+ for(p = 2 ; p < 200 ; p++)
+ check_random (p);
+ check_overflow ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#define STD_ERROR \
+ do \
+ { \
+ printf("ERROR: for %s and p=%lu and i=%d:\nB=", \
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \
+ mpfr_print_binary(b); \
+ printf("\nC="); mpfr_print_binary(c); \
+ printf("\nadd1 : "); mpfr_print_binary(a1); \
+ printf("\nadd1sp: "); mpfr_print_binary(a2); \
+ putchar('\n'); \
+ exit(1); \
+ } \
+ while (0)
+
+#define STD_ERROR2 \
+ do \
+ { \
+ printf("ERROR: Wrong inexact flag for %s and p=%lu and i=%d:\nB=", \
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \
+ mpfr_print_binary(b); \
+ printf("\nC="); mpfr_print_binary(c); \
+ printf("\nA="); mpfr_print_binary(a1); \
+ printf("\nAdd1: %d. Add1sp: %d\n", \
+ inexact1, inexact2); \
+ exit(1); \
+ } \
+ while (0)
+
+#define SET_PREC(_p) \
+ { \
+ p = _p; \
+ mpfr_set_prec(a1, _p); mpfr_set_prec(a2, _p); \
+ mpfr_set_prec(b, _p); mpfr_set_prec(c, _p); \
+ }
+
+static void
+check_random (mpfr_prec_t p)
+{
+ mpfr_t a1,b,c,a2;
+ int r;
+ int i, inexact1, inexact2;
+
+ mpfr_inits2 (p, a1, b, c, a2, (mpfr_ptr) 0);
+
+ for (i = 0 ; i < 500 ; i++)
+ {
+ mpfr_urandomb (b, RANDS);
+ mpfr_urandomb (c, RANDS);
+ if (MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c))
+ {
+ if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c))
+ mpfr_swap(b, c);
+ if (MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c))
+ for (r = 0 ; r < MPFR_RND_MAX ; r++)
+ {
+ inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r);
+ inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r);
+ if (mpfr_cmp(a1, a2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+ }
+ }
+ }
+
+ mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0);
+}
+
+static void
+check_special (void)
+{
+ mpfr_t a1,a2,b,c;
+ int r;
+ mpfr_prec_t p;
+ int i = -1, inexact1, inexact2;
+
+ mpfr_inits (a1, a2, b, c, (mpfr_ptr) 0);
+
+ for (r = 0 ; r < MPFR_RND_MAX ; r++)
+ {
+ SET_PREC(53);
+ mpfr_set_str1 (b, "1@100");
+ mpfr_set_str1 (c, "1@1");
+ inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r);
+ inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r);
+ if (mpfr_cmp(a1, a2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+ mpfr_set_str_binary (b, "1E53");
+ mpfr_set_str_binary (c, "1E0");
+ inexact1 = mpfr_add1(a1, b, c, (mpfr_rnd_t) r);
+ inexact2 = mpfr_add1sp(a2, b, c, (mpfr_rnd_t) r);
+ if (mpfr_cmp(a1, a2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+ }
+
+ mpfr_set_prec (c, 2);
+ mpfr_set_prec (a1, 2);
+ mpfr_set_prec (a2, 2);
+ mpfr_set_str_binary (c, "1.0e1");
+ mpfr_set_str_binary (a2, "1.1e-1");
+ mpfr_set_str_binary (a1, "0.11E2");
+ mpfr_add1sp (a2, c, a2, MPFR_RNDN);
+ if (mpfr_cmp (a1, a2))
+ {
+ printf ("Regression reuse test failed!\n");
+ exit (1);
+ }
+
+ mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0);
+}
diff --git a/mpfr/tests/tadd_d.c b/mpfr/tests/tadd_d.c
new file mode 100644
index 0000000000..533f0d374a
--- /dev/null
+++ b/mpfr/tests/tadd_d.c
@@ -0,0 +1,161 @@
+/* Test file for mpfr_add_d
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+static void
+check_regulars (void)
+{
+ mpfr_t x, y, z;
+ double d;
+ int inexact;
+
+ /* (1) check with enough precision */
+ mpfr_init2 (x, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (y, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (z, IEEE_DBL_MANT_DIG);
+
+ mpfr_set_str (y, "4096", 10, MPFR_RNDN);
+ d = 0.125;
+ mpfr_clear_flags ();
+ inexact = mpfr_add_d (x, y, d, MPFR_RNDN);
+ if (inexact != 0)
+ {
+ printf ("Inexact flag error in mpfr_add_d (1)\n");
+ exit (1);
+ }
+ mpfr_set_str (z, "4096.125", 10, MPFR_RNDN);
+ if (mpfr_cmp (z, x))
+ {
+ printf ("Error in mpfr_add_d (");
+ mpfr_out_str (stdout, 10, 7, y, MPFR_RNDN);
+ printf (" + %.20g)\nexpected ", d);
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ /* (2) check inexact flag */
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (z, 2);
+
+ mpfr_clear_flags ();
+ inexact = mpfr_add_d (x, y, d, MPFR_RNDN);
+ if (inexact == 0)
+ {
+ printf ("Inexact flag error in mpfr_add_d (2)\n");
+ exit (1);
+ }
+ mpfr_set_str (z, "4096.125", 10, MPFR_RNDN);
+ if (mpfr_cmp (z, x))
+ {
+ printf ("Error in mpfr_add_d (");
+ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
+ printf (" + %.20g)\nexpected ", d);
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+static void
+check_nans (void)
+{
+#if !defined(MPFR_ERRDIVZERO)
+ mpfr_t x, y;
+ int inexact;
+
+ mpfr_init2 (x, 123);
+ mpfr_init2 (y, 123);
+
+ /* nan + 1.0 is nan */
+ mpfr_set_nan (x);
+ mpfr_clear_flags ();
+ inexact = mpfr_add_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* +inf + 1.0 == +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_clear_flags ();
+ inexact = mpfr_add_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ /* -inf + 1.0 == -inf */
+ mpfr_set_inf (x, -1);
+ mpfr_clear_flags ();
+ inexact = mpfr_add_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+#endif
+}
+
+#define TEST_FUNCTION mpfr_add_d
+#define DOUBLE_ARG2
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+
+ check_nans ();
+ check_regulars ();
+
+ test_generic (2, 1000, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tadd_ui.c b/mpfr/tests/tadd_ui.c
new file mode 100644
index 0000000000..ab23edcf8b
--- /dev/null
+++ b/mpfr/tests/tadd_ui.c
@@ -0,0 +1,116 @@
+/* Test file for mpfr_add_ui
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+/* checks that x+y gives the right results with 53 bits of precision */
+static void
+check3 (const char *xs, unsigned long y, mpfr_rnd_t rnd_mode, const char *zs)
+{
+ mpfr_t xx, zz;
+
+ mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs);
+ mpfr_add_ui (zz, xx, y, rnd_mode);
+ if (mpfr_cmp_str1(zz, zs) )
+ {
+ printf ("expected sum is %s, got ",zs);
+ mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
+ printf ("\nmpfr_add_ui failed for x=%s y=%lu with rnd_mode=%s\n",
+ xs, y, mpfr_print_rnd_mode(rnd_mode));
+ exit (1);
+ }
+ mpfr_clears (xx, zz, (mpfr_ptr) 0);
+}
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 63);
+ mpfr_init2 (y, 63);
+ mpfr_set_str_binary (x, "0.110100000000000001110001110010111111000000000101100011100100011");
+ mpfr_add_ui (y, x, 1, MPFR_RNDD);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ /* nan + 2394875 == nan */
+ mpfr_set_nan (x);
+ mpfr_add_ui (y, x, 2394875L, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* +inf + 2394875 == +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_add_ui (y, x, 2394875L, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (mpfr_sgn (y) > 0);
+
+ /* -inf + 2394875 == -inf */
+ mpfr_set_inf (x, -1);
+ mpfr_add_ui (y, x, 2394875L, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (mpfr_sgn (y) < 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_add_ui
+#define INTEGER_TYPE unsigned long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric_ui.c"
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_nans ();
+
+ special ();
+ check3 ("-1.716113812768534e-140", 1271212614, MPFR_RNDZ,
+ "1.27121261399999976e9");
+ check3 ("1.22191250737771397120e+20", 948002822, MPFR_RNDN,
+ "122191250738719408128.0");
+ check3 ("-6.72658901114033715233e-165", 2000878121, MPFR_RNDZ,
+ "2.0008781209999997615e9");
+ check3 ("-2.0769715792901673e-5", 880524, MPFR_RNDN,
+ "8.8052399997923023e5");
+ test_generic_ui (2, 1000, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tagm.c b/mpfr/tests/tagm.c
new file mode 100644
index 0000000000..ae561aceb5
--- /dev/null
+++ b/mpfr/tests/tagm.c
@@ -0,0 +1,277 @@
+/* Test file for mpfr_agm.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define check(a,b,r) check4(a,b,r,0.0)
+
+static void
+check4 (const char *as, const char *bs, mpfr_rnd_t rnd_mode,
+ const char *res, int inex)
+{
+ mpfr_t ta, tb, tc, tres;
+ mpfr_exp_t emin, emax;
+ int i;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_inits2 (53, ta, tb, tc, tres, (mpfr_ptr) 0);
+
+ for (i = 0; i <= 2; i++)
+ {
+ unsigned int expflags, newflags;
+ int inex2;
+
+ mpfr_set_str1 (ta, as);
+ mpfr_set_str1 (tb, bs);
+ mpfr_set_str1 (tc, res);
+
+ if (i > 0)
+ {
+ mpfr_exp_t ea, eb, ec, e0;
+
+ set_emin (MPFR_EMIN_MIN);
+ set_emax (MPFR_EMAX_MAX);
+
+ ea = mpfr_get_exp (ta);
+ eb = mpfr_get_exp (tb);
+ ec = mpfr_get_exp (tc);
+
+ e0 = i == 1 ? __gmpfr_emin : __gmpfr_emax;
+ if ((i == 1 && ea < eb) || (i == 2 && ea > eb))
+ {
+ mpfr_set_exp (ta, e0);
+ mpfr_set_exp (tb, e0 + (eb - ea));
+ mpfr_set_exp (tc, e0 + (ec - ea));
+ }
+ else
+ {
+ mpfr_set_exp (ta, e0 + (ea - eb));
+ mpfr_set_exp (tb, e0);
+ mpfr_set_exp (tc, e0 + (ec - eb));
+ }
+ }
+
+ __gmpfr_flags = expflags =
+ (randlimb () & 1) ? MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE : 0;
+ inex2 = mpfr_agm (tres, ta, tb, rnd_mode);
+ newflags = __gmpfr_flags;
+ expflags |= MPFR_FLAGS_INEXACT;
+
+ if (SIGN (inex2) != inex || newflags != expflags ||
+ ! mpfr_equal_p (tres, tc))
+ {
+ printf ("mpfr_agm failed in rnd_mode=%s for\n",
+ mpfr_print_rnd_mode (rnd_mode));
+ printf (" a = ");
+ mpfr_out_str (stdout, 10, 0, ta, MPFR_RNDN);
+ printf ("\n");
+ printf (" b = ");
+ mpfr_out_str (stdout, 10, 0, tb, MPFR_RNDN);
+ printf ("\n");
+ printf ("expected inex = %d, flags = %u,\n"
+ " ", inex, expflags);
+ mpfr_dump (tc);
+ printf ("got inex = %d, flags = %u,\n"
+ " ", inex2, newflags);
+ mpfr_dump (tres);
+ exit (1);
+ }
+
+ set_emin (emin);
+ set_emax (emax);
+ }
+
+ mpfr_clears (ta, tb, tc, tres, (mpfr_ptr) 0);
+}
+
+static void
+check_large (void)
+{
+ mpfr_t a, b, agm;
+ int inex;
+
+ mpfr_init2 (a, 82);
+ mpfr_init2 (b, 82);
+ mpfr_init2 (agm, 82);
+
+ mpfr_set_ui (a, 1, MPFR_RNDN);
+ mpfr_set_str_binary (b, "0.1111101100001000000001011000110111101000001011111000100001000101010100011111110010E-39");
+ mpfr_agm (agm, a, b, MPFR_RNDN);
+ mpfr_set_str_binary (a, "0.1110001000111101101010101010101101001010001001001011100101111011110101111001111100E-4");
+ if (mpfr_cmp (agm, a))
+ {
+ printf ("mpfr_agm failed for precision 82\n");
+ exit (1);
+ }
+
+ /* problem found by Damien Fischer <damien@maths.usyd.edu.au> 4 Aug 2003:
+ produced a divide-by-zero exception */
+ mpfr_set_prec (a, 268);
+ mpfr_set_prec (b, 268);
+ mpfr_set_prec (agm, 268);
+ mpfr_set_str (a, "703.93543315330225238487276503953366664991725089988315253092140138947103394917006", 10, MPFR_RNDN);
+ mpfr_set_str (b, "703.93543315330225238487279020523738740563816490895994499256063816906728642622316", 10, MPFR_RNDN);
+ mpfr_agm (agm, a, b, MPFR_RNDN);
+
+ mpfr_set_prec (a, 18);
+ mpfr_set_prec (b, 70);
+ mpfr_set_prec (agm, 67);
+ mpfr_set_str_binary (a, "0.111001111100101000e8");
+ mpfr_set_str_binary (b, "0.1101110111100100010100110000010111011011011100110100111001010100100001e10");
+ inex = mpfr_agm (agm, a, b, MPFR_RNDN);
+ mpfr_set_str_binary (b, "0.1111110010011101101100010101011011010010010000001010100011000110011e9");
+ if (mpfr_cmp (agm, b))
+ {
+ printf ("Error in mpfr_agm (1)\n");
+ exit (1);
+ }
+ if (inex >= 0)
+ {
+ printf ("Wrong flag for mpfr_agm (1)\n");
+ exit (1);
+ }
+
+ /* test worst case: 9 consecutive ones after the last bit */
+ mpfr_set_prec (a, 2);
+ mpfr_set_prec (b, 2);
+ mpfr_set_ui (a, 1, MPFR_RNDN);
+ mpfr_set_ui (b, 2, MPFR_RNDN);
+ mpfr_set_prec (agm, 904);
+ mpfr_agm (agm, a, b, MPFR_RNDZ);
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+ mpfr_clear (agm);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y, m;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+ mpfr_init2 (m, 123L);
+
+ /* agm(1,nan) == nan */
+ mpfr_set_ui (x, 1L, MPFR_RNDN);
+ mpfr_set_nan (y);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (m));
+
+ /* agm(1,+inf) == +inf */
+ mpfr_set_ui (x, 1L, MPFR_RNDN);
+ mpfr_set_inf (y, 1);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (m));
+ MPFR_ASSERTN (mpfr_sgn (m) > 0);
+
+ /* agm(+inf,+inf) == +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, 1);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (m));
+ MPFR_ASSERTN (mpfr_sgn (m) > 0);
+
+ /* agm(-inf,+inf) == nan */
+ mpfr_set_inf (x, -1);
+ mpfr_set_inf (y, 1);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (m));
+
+ /* agm(+0,+inf) == nan */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_inf (y, 1);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (m));
+
+ /* agm(+0,1) == +0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (m) && MPFR_IS_POS(m));
+
+ /* agm(-0,1) == +0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (m) && MPFR_IS_POS(m));
+
+ /* agm(-0,+0) == +0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (m) && MPFR_IS_POS(m));
+
+ /* agm(1,1) == 1 */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (m ,1) == 0);
+
+ /* agm(-1,-2) == NaN */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_set_si (y, -2, MPFR_RNDN);
+ mpfr_agm (m, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (m));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (m);
+}
+
+#define TEST_FUNCTION mpfr_agm
+#define TWO_ARGS
+#define TEST_RANDOM_POS 4
+#define TEST_RANDOM_POS2 4
+#include "tgeneric.c"
+
+int
+main (int argc, char* argv[])
+{
+ tests_start_mpfr ();
+
+ check_nans ();
+
+ check_large ();
+ check4 ("2.0", "1.0", MPFR_RNDN, "1.456791031046906869", -1);
+ check4 ("6.0", "4.0", MPFR_RNDN, "4.949360872472608925", 1);
+ check4 ("62.0", "61.0", MPFR_RNDN, "61.498983718845075902", -1);
+ check4 ("0.5", "1.0", MPFR_RNDN, "0.72839551552345343459", -1);
+ check4 ("1.0", "2.0", MPFR_RNDN, "1.456791031046906869", -1);
+ check4 ("234375765.0", "234375000.0", MPFR_RNDN, "234375382.49984394025", 1);
+ check4 ("8.0", "1.0", MPFR_RNDU, "3.61575617759736274873", 1);
+ check4 ("1.0", "44.0", MPFR_RNDU, "13.3658354512981243907", 1);
+ check4 ("1.0", "3.7252902984619140625e-9", MPFR_RNDU,
+ "0.07553933569711989657765", 1);
+ test_generic (2, 300, 17);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tai.c b/mpfr/tests/tai.c
new file mode 100644
index 0000000000..3e7bfdd46c
--- /dev/null
+++ b/mpfr/tests/tai.c
@@ -0,0 +1,109 @@
+/* Test file for mpfr_ai.
+
+Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_ai
+#define TEST_RANDOM_EMIN -5
+#define TEST_RANDOM_EMAX 5
+#define REDUCE_EMAX 7 /* this is to avoid that test_generic() calls mpfr_ai
+ with too large inputs. FIXME: remove this once
+ mpfr_ai can handle large inputs */
+#include "tgeneric.c"
+
+static void
+check_large (void)
+{
+ mpfr_t x, y, z;
+
+ mpfr_init2 (x, 38);
+ mpfr_init2 (y, 110);
+ mpfr_init2 (z, 110);
+ mpfr_set_str_binary (x, "-1E8");
+ mpfr_ai (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (z, "-10001110100001011111110001100011101100011100010000110100100101011111011100000101110101010010000000101110011111E-112");
+ if (mpfr_equal_p (y, z) == 0)
+ {
+ printf ("Error in mpfr_ai for x=-2^8\n");
+ exit (1);
+ }
+#if 0 /* disabled since mpfr_ai does not currently handle large arguments */
+ mpfr_set_str_binary (x, "-1E26");
+ mpfr_ai (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (z, "-110001111100000011001010010101001101001011001011101011001010100100001110001101101101000010000011001000001011E-118");
+ if (mpfr_equal_p (y, z) == 0)
+ {
+ printf ("Error in mpfr_ai for x=-2^26\n");
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "-0.11111111111111111111111111111111111111E1073741823");
+ mpfr_ai (y, x, MPFR_RNDN);
+ /* FIXME: compute the correctly rounded value we should get for Ai(x),
+ and check we get this value */
+#endif
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+check_zero (void)
+{
+ mpfr_t x, y, r;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+ mpfr_init2 (r, 53);
+
+ mpfr_set_str_binary (r, "10110101110001100011110010110001001110001010110111E-51");
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_ai (y, x, MPFR_RNDN);
+ if (mpfr_equal_p (y, r) == 0)
+ {
+ printf ("Error in mpfr_ai for x=0\n");
+ printf ("Expected "); mpfr_dump (r);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (r);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_large ();
+ check_zero ();
+
+ test_generic (2, 100, 5);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tasin.c b/mpfr/tests/tasin.c
new file mode 100644
index 0000000000..c72ca0c47b
--- /dev/null
+++ b/mpfr/tests/tasin.c
@@ -0,0 +1,285 @@
+/* Test file for mpfr_asin.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_asin
+#define TEST_RANDOM_EMAX 7
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int r;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* asin(NaN) = NaN */
+ mpfr_set_nan (x);
+ mpfr_asin (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_asin (NaN) <> NaN\n");
+ exit (1);
+ }
+
+ /* asin(+/-Inf) = NaN */
+ mpfr_set_inf (x, 1);
+ mpfr_asin (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_asin (+Inf) <> NaN\n");
+ exit (1);
+ }
+ mpfr_set_inf (x, -1);
+ mpfr_asin (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_asin (-Inf) <> NaN\n");
+ exit (1);
+ }
+
+ /* asin(+/-2) = NaN */
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_asin (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_asin (+2) <> NaN\n");
+ exit (1);
+ }
+ mpfr_set_si (x, -2, MPFR_RNDN);
+ mpfr_asin (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_asin (-2) <> NaN\n");
+ exit (1);
+ }
+
+ /* asin(+/-0) = +/-0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_asin (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: mpfr_asin (+0) <> +0\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_asin (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error: mpfr_asin (-0) <> -0\n");
+ exit (1);
+ }
+
+ /* asin(1) = Pi/2 */
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ mpfr_set_ui (x, 1, MPFR_RNDN); /* exact */
+ mpfr_asin (y, x, (mpfr_rnd_t) r);
+ mpfr_const_pi (x, (mpfr_rnd_t) r);
+ mpfr_div_2exp (x, x, 1, MPFR_RNDN); /* exact */
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: asin(1) != Pi/2 for rnd=%s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ }
+
+ /* asin(-1) = -Pi/2 */
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ mpfr_set_si (x, -1, MPFR_RNDN); /* exact */
+ mpfr_asin (y, x, (mpfr_rnd_t) r);
+ mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r));
+ mpfr_neg (x, x, MPFR_RNDN); /* exact */
+ mpfr_div_2exp (x, x, 1, MPFR_RNDN); /* exact */
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: asin(-1) != -Pi/2 for rnd=%s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+
+ mpfr_set_str_binary (x, "0.1101110111111111001011101000101");
+ mpfr_asin (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "1.00001100101011000001111100111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_asin (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "-0.01110111000011101010111100000101");
+ mpfr_asin (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "-0.0111101111010100011111110101");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_asin (2)\n");
+ mpfr_print_binary (x); printf ("\n");
+ mpfr_print_binary (y); printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 9);
+ mpfr_set_prec (y, 19);
+ mpfr_set_str_binary (x, "0.110000000E-6");
+ mpfr_asin (y, x, MPFR_RNDD);
+ mpfr_set_prec (x, 19);
+ mpfr_set_str_binary (x, "0.1100000000000001001E-6");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_asin (3)\n");
+ mpfr_dump (x);
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+special_overflow (void)
+{
+ mpfr_t x, y;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ set_emin (-125);
+ set_emax (128);
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 48);
+ mpfr_set_str_binary (x, "0.101100100000000000110100E0");
+ mpfr_asin (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "0.110001001101001111110000010110001000111011001000E0",
+ 2, MPFR_RNDN))
+ {
+ printf("Special Overflow error.\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_clear (y);
+ mpfr_clear (x);
+ set_emin (emin);
+ set_emax (emax);
+}
+
+/* bug reported by Kevin Rauch on 15 December 2007 */
+static void
+test20071215 (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_asin (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_NEG(y));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_si (y, -1, MPFR_RNDN);
+ mpfr_asin (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_POS(y));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+reduced_expo_range (void)
+{
+ mpfr_exp_t emin, emax;
+ mpfr_t x, y, ex_y;
+ int inex, ex_inex;
+ unsigned int flags, ex_flags;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_inits2 (4, x, y, ex_y, (mpfr_ptr) 0);
+ mpfr_set_str (x, "-0.1e1", 2, MPFR_RNDN);
+
+ mpfr_set_emin (1);
+ mpfr_set_emax (1);
+ mpfr_clear_flags ();
+ inex = mpfr_asin (y, x, MPFR_RNDA);
+ flags = __gmpfr_flags;
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+
+ mpfr_set_str (ex_y, "-0.1101e1", 2, MPFR_RNDN);
+ ex_inex = -1;
+ ex_flags = MPFR_FLAGS_INEXACT;
+
+ if (SIGN (inex) != ex_inex || flags != ex_flags ||
+ ! mpfr_equal_p (y, ex_y))
+ {
+ printf ("Error in reduced_expo_range\non x = ");
+ mpfr_dump (x);
+ printf ("Expected y = ");
+ mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN);
+ printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags);
+ printf ("Got y = ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags);
+ exit (1);
+ }
+
+ mpfr_clears (x, y, ex_y, (mpfr_ptr) 0);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+
+ special ();
+ special_overflow ();
+ reduced_expo_range ();
+
+ test_generic (2, 100, 15);
+
+ tests_end_mpfr ();
+
+ data_check ("data/asin", mpfr_asin, "mpfr_asin");
+ bad_cases (mpfr_asin, mpfr_sin, "mpfr_asin", 256, -40, 1, 4, 128, 800, 30);
+
+ test20071215 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tasinh.c b/mpfr/tests/tasinh.c
new file mode 100644
index 0000000000..8dabcdcd1e
--- /dev/null
+++ b/mpfr/tests/tasinh.c
@@ -0,0 +1,161 @@
+/* Test file for mpfr_asinh.
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_asinh
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y, z;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ MPFR_SET_INF(x);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_asinh (x, y, MPFR_RNDN);
+ if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) )
+ {
+ printf ("Inf flag not clears in asinh!\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN(x);
+ mpfr_asinh (x, y, MPFR_RNDN);
+ if (MPFR_IS_NAN(x) || MPFR_IS_INF(x))
+ {
+ printf ("NAN flag not clears in asinh!\n");
+ exit (1);
+ }
+
+ /* asinh(+0) = +0, asinh(-0) = -0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_asinh (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: mpfr_asinh(+0) <> +0\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_asinh (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error: mpfr_asinh(-0) <> -0\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN(x);
+ mpfr_asinh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_asinh(NaN) <> NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_asinh (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: mpfr_asinh(+Inf) <> +Inf\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_asinh (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error: mpfr_asinh(-Inf) <> -Inf\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+
+ mpfr_set_str_binary (x, "0.1010100100111011001111100101E-1");
+ mpfr_asinh (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.10100110010010101101010011011101E-1");
+ if (!mpfr_equal_p (x, y))
+ {
+ printf ("Error: mpfr_asinh (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "-.10110011011010111110010001100001");
+ mpfr_asinh (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "-.10100111010000111001011100110011");
+ if (!mpfr_equal_p (x, y))
+ {
+ printf ("Error: mpfr_asinh (2)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 33);
+ mpfr_set_prec (y, 43);
+ mpfr_set_str_binary (x, "0.111001101100000110011001010000101");
+ mpfr_asinh (y, x, MPFR_RNDZ);
+ mpfr_init2 (z, 43);
+ mpfr_set_str_binary (z, "0.1100111101010101101010101110000001000111001");
+ if (!mpfr_equal_p (y, z))
+ {
+ printf ("Error: mpfr_asinh (3)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 2);
+ mpfr_set_str (x, "1.8000000000009@-6", 16, MPFR_RNDN);
+ mpfr_asinh (y, x, MPFR_RNDZ);
+ mpfr_set_prec (z, 2);
+ mpfr_set_str (z, "1.0@-6", 16, MPFR_RNDN);
+ if (!mpfr_equal_p (y, z))
+ {
+ printf ("Error: mpfr_asinh (4)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+
+ test_generic (2, 100, 25);
+
+ data_check ("data/asinh", mpfr_asinh, "mpfr_asinh");
+ bad_cases (mpfr_asinh, mpfr_sinh, "mpfr_asinh", 256, -128, 29,
+ 4, 128, 800, 40);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tatan.c b/mpfr/tests/tatan.c
new file mode 100644
index 0000000000..fa5e2b4409
--- /dev/null
+++ b/mpfr/tests/tatan.c
@@ -0,0 +1,643 @@
+/* Test file for mpfr_atan.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+special (void)
+{
+ mpfr_t x, y, z;
+ int r;
+ int i;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+ mpfr_init2 (z, 53);
+
+ mpfr_set_str_binary (x, "1.0000100110000001100111100011001110101110100111011101");
+ mpfr_set_str_binary (y, "1.1001101101110100101100110011011101101000011010111110e-1");
+ mpfr_atan (z, x, MPFR_RNDN);
+ if (mpfr_cmp (y, z))
+ {
+ printf ("Error in mpfr_atan for prec=53, rnd=MPFR_RNDN\n");
+ printf ("x=");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\nexpected ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ /* atan(+Inf) = Pi/2 */
+ for (r = 0; r < MPFR_RND_MAX ; r++)
+ {
+ mpfr_set_inf (x, 1);
+ mpfr_atan (y, x, (mpfr_rnd_t) r);
+ mpfr_const_pi (x, (mpfr_rnd_t) r);
+ mpfr_div_2exp (x, x, 1, (mpfr_rnd_t) r);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_atan(+Inf), rnd=%s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ }
+
+ /* atan(-Inf) = - Pi/2 */
+ for (r = 0; r < MPFR_RND_MAX ; r++)
+ {
+ mpfr_set_inf (x, -1);
+ mpfr_atan (y, x, (mpfr_rnd_t) r);
+ mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r));
+ mpfr_neg (x, x, (mpfr_rnd_t) r);
+ mpfr_div_2exp (x, x, 1, (mpfr_rnd_t) r);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_atan(-Inf), rnd=%s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ }
+
+ /* atan(NaN) = NaN */
+ mpfr_set_nan (x);
+ mpfr_atan (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_atan(NaN) <> NaN\n");
+ exit (1);
+ }
+
+ /* atan(+/-0) = +/-0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ MPFR_SET_NEG (y);
+ mpfr_atan (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
+ {
+ printf ("Error: mpfr_atan (+0) <> +0\n");
+ exit (1);
+ }
+ mpfr_atan (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0) || MPFR_IS_NEG (x))
+ {
+ printf ("Error: mpfr_atan (+0) <> +0 (in place)\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ MPFR_SET_POS (y);
+ mpfr_atan (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || MPFR_IS_POS (y))
+ {
+ printf ("Error: mpfr_atan (-0) <> -0\n");
+ exit (1);
+ }
+ mpfr_atan (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0) || MPFR_IS_POS (x))
+ {
+ printf ("Error: mpfr_atan (-0) <> -0 (in place)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+
+ /* test one random positive argument */
+ mpfr_set_str_binary (x, "0.10000100001100101001001001011001");
+ mpfr_atan (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.1111010000001111001111000000011E-1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_atan (1)\n");
+ exit (1);
+ }
+
+ /* test one random negative argument */
+ mpfr_set_str_binary (x, "-0.1100001110110000010101011001011");
+ mpfr_atan (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "-0.101001110001010010110001110001");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_atan (2)\n");
+ mpfr_print_binary (x); printf ("\n");
+ mpfr_print_binary (y); printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_prec (y, 192);
+ mpfr_set_prec (z, 192);
+ mpfr_set_str_binary (x, "-0.100e1");
+ mpfr_atan (z, x, MPFR_RNDD);
+ mpfr_set_str_binary (y, "-0.110010010000111111011010101000100010000101101000110000100011010011000100110001100110001010001011100000001101110000011100110100010010100100000010010011100000100010001010011001111100110001110101");
+ if (mpfr_cmp (z, y))
+ {
+ printf ("Error in mpfr_atan (3)\n");
+ printf ("Expected "); mpfr_print_binary (y); printf ("\n");
+ printf ("Got "); mpfr_print_binary (z); printf ("\n");
+ exit (1);
+ }
+
+ /* Test regression */
+ mpfr_set_prec (x, 51);
+ mpfr_set_prec (y, 51);
+ mpfr_set_str_binary (x,
+ "0.101100100000101111111010001111111000001000000000000E-11");
+ i = mpfr_atan (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y,
+ "1.01100100000101111111001110011001010110100100000000e-12", 2, MPFR_RNDN)
+ || i >= 0)
+ {
+ printf ("Wrong Regression test (%d)\n", i);
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_atan (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_NEG (x));
+
+ /* Test regression */
+ mpfr_set_prec (x, 48);
+ mpfr_set_prec (y, 48);
+ mpfr_set_str_binary (x, "1.11001110010000011111100000010000000000000000000e-19");
+ mpfr_atan (y, x, MPFR_RNDD);
+ if (mpfr_cmp_str (y, "0.111001110010000011111100000001111111110000010011E-18", 2, MPFR_RNDN))
+ {
+ printf ("Error in mpfr_atan (4)\n");
+ printf ("Input 1.11001110010000011111100000010000000000000000000e-19 [prec=48]\n");
+ printf ("Expected 0.111001110010000011111100000001111111110000010011E-18\n");
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+#define TEST_FUNCTION mpfr_atan
+#define test_generic test_generic_atan
+#define RAND_FUNCTION(x) (mpfr_urandomb (x, RANDS), mpfr_mul_2si (x, x, (randlimb () %1000-500), MPFR_RNDN))
+#include "tgeneric.c"
+
+#define TEST_FUNCTION mpfr_atan2
+#define TWO_ARGS
+#define test_generic test_generic_atan2
+#include "tgeneric.c"
+
+#define TEST_FUNCTION mpfr_atan2
+#define TWO_ARGS
+#define RAND_FUNCTION(x) (mpfr_urandomb (x, RANDS), MPFR_SET_NEG (x))
+#define test_generic test_generic_atan2_neg
+#include "tgeneric.c"
+
+static void
+special_overflow (void)
+{
+ mpfr_t x, y;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ set_emin (-125);
+ set_emax (128);
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 48);
+ mpfr_set_str_binary (x, "0.101101010001001101111010E0");
+ mpfr_atan (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "0.100111011001100111000010111101000111010101011110E0",
+ 2, MPFR_RNDN))
+ {
+ printf("Special Overflow error.\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ /* intermediate Pi overflows while atan(+Inf) = Pi/2 is representable */
+ set_emax (1);
+ mpfr_set_inf (x, +1);
+ mpfr_clear_flags ();
+ mpfr_atan (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "C90FDAA22169p-47", 16, MPFR_RNDN)
+ || mpfr_overflow_p ())
+ {
+ printf("atan(+Inf) = Pi/2 should not overflow when emax = %ld\n",
+ (long int) mpfr_get_emax ());
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ /* atan(+Inf) = Pi/2 underflows */
+ set_emax (128);
+ set_emin (3);
+ mpfr_clear_flags ();
+ mpfr_atan (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
+ {
+ printf("atan(+Inf) = Pi/2 should underflow when emin = %ld\n",
+ (long int) mpfr_get_emin ());
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ /* intermediate Pi overflows while atan(+1) = Pi/4 is representable */
+ set_emax (1);
+ set_emin (-128);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ mpfr_atan (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "C90FDAA22169p-48", 16, MPFR_RNDN)
+ || mpfr_overflow_p ())
+ {
+ printf("atan(+1) = Pi/4 should not overflow when emax = %ld\n",
+ (long int) mpfr_get_emax ());
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ /* atan(+1) = Pi/4 underflows and is rounded up to 1 */
+ set_emax (128);
+ set_emin (1);
+ mpfr_set_prec (y, 2);
+ mpfr_clear_flags ();
+ mpfr_atan (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1) || !mpfr_underflow_p ())
+ {
+ printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
+ (long int) mpfr_get_emin ());
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ /* atan(+1) = Pi/4 underflows and is rounded down to 0 */
+ mpfr_clear_flags ();
+ mpfr_atan (y, x, MPFR_RNDD);
+ if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
+ {
+ printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
+ (long int) mpfr_get_emin ());
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+ set_emin (emin);
+ set_emax (emax);
+}
+
+static void
+special_atan2 (void)
+{
+ mpfr_t x, y, z;
+
+ mpfr_inits2 (4, x, y, z, (mpfr_ptr) 0);
+
+ /* Anything with NAN should be set to NAN */
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_set_nan (x);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_NAN (z));
+ mpfr_swap (x, y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_NAN (z));
+
+ /* 0+ 0+ --> 0+ */
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
+ /* 0- 0+ --> 0- */
+ MPFR_CHANGE_SIGN (y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
+ /* 0- 0- --> -PI */
+ MPFR_CHANGE_SIGN (x);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
+ /* 0+ 0- --> +PI */
+ MPFR_CHANGE_SIGN (y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
+ /* 0+ -1 --> PI */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
+ /* 0- -1 --> -PI */
+ MPFR_CHANGE_SIGN (y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
+ /* 0- +1 --> 0- */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
+ /* 0+ +1 --> 0+ */
+ MPFR_CHANGE_SIGN (y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
+ /* +1 0+ --> PI/2 */
+ mpfr_swap (x, y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
+ /* +1 0- --> PI/2 */
+ MPFR_CHANGE_SIGN (x);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
+ /* -1 0- --> -PI/2 */
+ MPFR_CHANGE_SIGN (y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
+ /* -1 0+ --> -PI/2 */
+ MPFR_CHANGE_SIGN (x);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
+
+ /* -1 +INF --> -0 */
+ MPFR_SET_INF (x);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
+ /* +1 +INF --> +0 */
+ MPFR_CHANGE_SIGN (y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
+ /* +1 -INF --> +PI */
+ MPFR_CHANGE_SIGN (x);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
+ /* -1 -INF --> -PI */
+ MPFR_CHANGE_SIGN (y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
+ /* -INF -1 --> -PI/2 */
+ mpfr_swap (x, y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
+ /* +INF -1 --> PI/2 */
+ MPFR_CHANGE_SIGN (y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
+ /* +INF -INF --> 3*PI/4 */
+ MPFR_SET_INF (x);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "2.356194490192344928", 10, MPFR_RNDN) == 0);
+ /* +INF +INF --> PI/4 */
+ MPFR_CHANGE_SIGN (x);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "0.785375", 10, MPFR_RNDN) == 0);
+ /* -INF +INF --> -PI/4 */
+ MPFR_CHANGE_SIGN (y);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "-0.785375", 10, MPFR_RNDN) == 0);
+ /* -INF -INF --> -3*PI/4 */
+ MPFR_CHANGE_SIGN (x);
+ mpfr_atan2 (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "-2.356194490192344928", 10, MPFR_RNDN) == 0);
+ mpfr_set_prec (z, 905); /* exercises Ziv's loop */
+ mpfr_atan2 (z, y, x, MPFR_RNDZ);
+ MPFR_ASSERTN (mpfr_cmp_str (z, "-2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488496172998532038345716293667379401955609636083808771307702645389082916973346721171619778647332160823174945008459635673617534008737395340143185923642519259526145784", 10, MPFR_RNDN) == 0);
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+/* from Christopher Creutzig, 18 Jul 2007 */
+static void
+smallvals_atan2 (void)
+{
+ mpfr_t a, x, y;
+ mpfr_exp_t old_emin;
+
+ mpfr_inits (a, x, y, (mpfr_ptr) 0);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_nextbelow (y);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ /* y=-2^(-emin-1), x=1 */
+
+ mpfr_atan2 (a, y, x, MPFR_RNDD);
+ MPFR_ASSERTN (mpfr_equal_p (a, y));
+
+ mpfr_atan2 (a, y, x, MPFR_RNDU);
+ MPFR_ASSERTN (mpfr_zero_p (a) && MPFR_IS_NEG(a));
+
+ mpfr_set_prec (x, 8);
+ mpfr_set_prec (y, 8);
+ mpfr_set_prec (a, 8);
+ old_emin = mpfr_get_emin ();
+ mpfr_set_emin (MPFR_EMIN_MIN);
+
+ mpfr_set_si (y, 3, MPFR_RNDN);
+ mpfr_set_exp (y, mpfr_get_emin ());
+ mpfr_set_str_binary (x, "1.1");
+ mpfr_atan2 (a, y, x, MPFR_RNDU);
+ mpfr_set_si (y, 1, MPFR_RNDN);
+ mpfr_set_exp (y, mpfr_get_emin ());
+ MPFR_ASSERTN (mpfr_equal_p (a, y));
+
+ /* From a bug reported by Christopher Creutzig on 2007-08-28.
+ Added test in each rounding mode.
+ Segmentation fault or assertion failure due to an infinite Ziv loop. */
+ mpfr_set_si (y, 1, MPFR_RNDN);
+ mpfr_set_exp (y, mpfr_get_emin ());
+ mpfr_set_str_binary (x, "1.01");
+ mpfr_atan2 (a, y, x, MPFR_RNDZ);
+ MPFR_ASSERTN (mpfr_zero_p (a));
+ mpfr_atan2 (a, y, x, MPFR_RNDD);
+ MPFR_ASSERTN (mpfr_zero_p (a));
+ mpfr_atan2 (a, y, x, MPFR_RNDU);
+ MPFR_ASSERTN (mpfr_equal_p (a, y));
+ mpfr_atan2 (a, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_equal_p (a, y));
+
+ /* trigger underflow with rounding to nearest */
+ mpfr_set_ui (x, 4, MPFR_RNDN);
+ mpfr_atan2 (a, y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_zero_p (a));
+
+ mpfr_set_emin (old_emin);
+
+ mpfr_clears (a, x, y, (mpfr_ptr) 0);
+}
+
+/* Bug found by Robert Bajema (regression in MPFR 2.3.0).
+ The cause is the underflow flag set before the mpfr_atan2 call. */
+static void
+atan2_bug_20071003 (void)
+{
+ mpfr_t a, x, y, z;
+
+ mpfr_inits (a, x, y, z, (mpfr_ptr) 0);
+
+ mpfr_set_underflow ();
+ mpfr_set_str_binary (y,
+ "-0.10100110110100110111010110111111100110100010001110110E2");
+ mpfr_set_str_binary (x,
+ "0.10100101010110010100010010111000110110011110001011110E3");
+ mpfr_set_str_binary (z,
+ "-0.11101111001101101100111011001101000010010111101110110E-1");
+ mpfr_atan2 (a, y, x, MPFR_RNDN);
+ if (! mpfr_equal_p (a, z))
+ {
+ printf ("mpfr_atan2 fails on:\n");
+ printf (" y = ");
+ mpfr_dump (y);
+ printf (" x = ");
+ mpfr_dump (x);
+ printf ("Expected ");
+ mpfr_dump (z);
+ printf ("Got ");
+ mpfr_dump (a);
+ exit (1);
+ }
+
+ mpfr_clears (a, x, y, z, (mpfr_ptr) 0);
+}
+
+/* Bug found on 2009-04-29 by Christopher Creutzig.
+ * With r6179: atan.c:62: MPFR assertion failed: r > n
+ */
+static void
+atan2_different_prec (void)
+{
+ mpfr_t a, x, y;
+
+ mpfr_init2 (a, 59);
+ mpfr_init2 (x, 59);
+ mpfr_init2 (y, 86);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_nextbelow (y);
+ mpfr_atan2 (a, y, x, MPFR_RNDN);
+
+ mpfr_clears (a, x, y, (mpfr_ptr) 0);
+}
+
+static void
+atan2_pow_of_2 (void)
+{
+ mpfr_t x, y, r, g;
+ int i;
+ int d[] = { 0, -1, 1 };
+ int ntests = sizeof (d) / sizeof (int);
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+ mpfr_init2 (r, 53);
+ mpfr_init2 (g, 53);
+
+ /* atan(42) */
+ mpfr_set_str_binary (g, "1100011000000011110011111001100110101000011010010011E-51");
+
+ for (i = 0; i < ntests; ++i)
+ {
+ mpfr_set_ui (y, 42, MPFR_RNDN);
+ mpfr_mul_2si (y, y, d[i], MPFR_RNDN);
+ mpfr_set_ui_2exp (x, 1, d[i], MPFR_RNDN);
+ mpfr_atan2 (r, y, x, MPFR_RNDN);
+ if (mpfr_equal_p (r, g) == 0)
+ {
+ printf ("Error in mpfr_atan2 (5)\n");
+ printf ("Expected "); mpfr_print_binary (g); printf ("\n");
+ printf ("Got "); mpfr_print_binary (r); printf ("\n");
+ exit (1);
+ }
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (r);
+ mpfr_clear (g);
+}
+
+/* https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00008.html
+ * Incorrect flags (in debug mode on a 32-bit machine, assertion failure).
+ */
+static void
+reduced_expo_range (void)
+{
+ mpfr_exp_t emin, emax;
+ mpfr_t x, y, ex_y;
+ int inex, ex_inex;
+ unsigned int flags, ex_flags;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_inits2 (12, x, y, ex_y, (mpfr_ptr) 0);
+ mpfr_set_str (x, "0.1e-5", 2, MPFR_RNDN);
+
+ mpfr_set_emin (-5);
+ mpfr_set_emax (-5);
+ mpfr_clear_flags ();
+ inex = mpfr_atan (y, x, MPFR_RNDN);
+ flags = __gmpfr_flags;
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+
+ mpfr_set_str (ex_y, "0.1e-5", 2, MPFR_RNDN);
+ ex_inex = 1;
+ ex_flags = MPFR_FLAGS_INEXACT;
+
+ if (SIGN (inex) != ex_inex || flags != ex_flags ||
+ ! mpfr_equal_p (y, ex_y))
+ {
+ printf ("Error in reduced_expo_range\non x = ");
+ mpfr_dump (x);
+ printf ("Expected y = ");
+ mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN);
+ printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags);
+ printf ("Got y = ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags);
+ exit (1);
+ }
+
+ mpfr_clears (x, y, ex_y, (mpfr_ptr) 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special_overflow ();
+ special ();
+ special_atan2 ();
+ smallvals_atan2 ();
+ atan2_bug_20071003 ();
+ atan2_different_prec ();
+ reduced_expo_range ();
+
+ test_generic_atan (2, 200, 17);
+ test_generic_atan2 (2, 200, 17);
+ test_generic_atan2_neg (2, 200, 17);
+
+ data_check ("data/atan", mpfr_atan, "mpfr_atan");
+ bad_cases (mpfr_atan, mpfr_tan, "mpfr_atan", 256, -40, 1, 4, 128, 800, 40);
+ atan2_pow_of_2 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tatanh.c b/mpfr/tests/tatanh.c
new file mode 100644
index 0000000000..72e2b3db9d
--- /dev/null
+++ b/mpfr/tests/tatanh.c
@@ -0,0 +1,189 @@
+/* Test file for mpfr_atanh.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_atanh
+#define TEST_RANDOM_EMAX 7
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y, z;
+ int i;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ MPFR_SET_INF(x);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_atanh (x, y, MPFR_RNDN);
+ if (MPFR_IS_INF(x) || MPFR_IS_NAN(x) )
+ {
+ printf ("Inf flag not clears in atanh!\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN(x);
+ mpfr_atanh (x, y, MPFR_RNDN);
+ if (MPFR_IS_NAN(x) || MPFR_IS_INF(x))
+ {
+ printf ("NAN flag not clears in atanh!\n");
+ exit (1);
+ }
+
+ /* atanh(+/-x) = NaN if x > 1 */
+ for (i = 3; i <= 6; i++)
+ {
+ mpfr_set_si (x, i, MPFR_RNDN);
+ mpfr_div_2ui (x, x, 1, MPFR_RNDN);
+ mpfr_atanh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_atanh(%d/2) <> NaN\n", i);
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_atanh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_atanh(-%d/2) <> NaN\n", i);
+ exit (1);
+ }
+ }
+
+ /* atanh(+0) = +0, atanh(-0) = -0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_atanh (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: mpfr_atanh(+0) <> +0\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_atanh (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error: mpfr_atanh(-0) <> -0\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN(x);
+ mpfr_atanh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_atanh(NaN) <> NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_atanh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_atanh(+Inf) <> NaN\n");
+ mpfr_print_binary (y); printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_atanh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: mpfr_atanh(-Inf) <> NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_atanh (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: mpfr_atanh(1) <> +Inf\n");
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_atanh (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error: mpfr_atanh(-1) <> -Inf\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+
+ mpfr_set_str_binary (x, "0.10001000001001011000100001E-6");
+ mpfr_atanh (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.10001000001001100101010110100001E-6");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_atanh (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "-0.1101011110111100111010011001011E-1");
+ mpfr_atanh (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "-0.11100110000100001111101100010111E-1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_atanh (2)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 33);
+ mpfr_set_prec (y, 43);
+ mpfr_set_str_binary (x, "0.111001101100000110011001010000101");
+ mpfr_atanh (y, x, MPFR_RNDZ);
+ mpfr_init2 (z, 43);
+ mpfr_set_str_binary (z, "1.01111010110001101001000000101101011110101");
+ if (mpfr_cmp (y, z))
+ {
+ printf ("Error: mpfr_atanh (3)\n");
+ mpfr_print_binary (y); printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+
+ test_generic (2, 100, 25);
+
+ data_check ("data/atanh", mpfr_atanh, "mpfr_atanh");
+ bad_cases (mpfr_atanh, mpfr_tanh, "mpfr_atanh", 256, -128, 9,
+ 4, 128, 800, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/taway.c b/mpfr/tests/taway.c
new file mode 100644
index 0000000000..2d93553144
--- /dev/null
+++ b/mpfr/tests/taway.c
@@ -0,0 +1,497 @@
+/* Test file for round away.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define DISP(s, t) {printf(s); mpfr_out_str(stdout, 2, 0, t, MPFR_RNDN); }
+#define DISP2(s,t) {DISP(s,t); putchar('\n');}
+
+#define SPECIAL_MAX 12
+
+static void
+set_special (mpfr_ptr x, unsigned int select)
+{
+ MPFR_ASSERTN (select < SPECIAL_MAX);
+ switch (select)
+ {
+ case 0:
+ MPFR_SET_NAN (x);
+ break;
+ case 1:
+ MPFR_SET_INF (x);
+ MPFR_SET_POS (x);
+ break;
+ case 2:
+ MPFR_SET_INF (x);
+ MPFR_SET_NEG (x);
+ break;
+ case 3:
+ MPFR_SET_ZERO (x);
+ MPFR_SET_POS (x);
+ break;
+ case 4:
+ MPFR_SET_ZERO (x);
+ MPFR_SET_NEG (x);
+ break;
+ case 5:
+ mpfr_set_str_binary (x, "1");
+ break;
+ case 6:
+ mpfr_set_str_binary (x, "-1");
+ break;
+ case 7:
+ mpfr_set_str_binary (x, "1e-1");
+ break;
+ case 8:
+ mpfr_set_str_binary (x, "1e+1");
+ break;
+ case 9:
+ mpfr_const_pi (x, MPFR_RNDN);
+ break;
+ case 10:
+ mpfr_const_pi (x, MPFR_RNDN);
+ MPFR_SET_EXP (x, MPFR_GET_EXP (x)-1);
+ break;
+ default:
+ mpfr_urandomb (x, RANDS);
+ break;
+ }
+}
+/* same than mpfr_cmp, but returns 0 for both NaN's */
+static int
+mpfr_compare (mpfr_srcptr a, mpfr_srcptr b)
+{
+ return (MPFR_IS_NAN(a)) ? !MPFR_IS_NAN(b) :
+ (MPFR_IS_NAN(b) || mpfr_cmp(a, b));
+}
+
+static void
+test3 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t),
+ const char *foo)
+{
+ mpfr_t ref1, ref2, ref3;
+ mpfr_t res1;
+ mpfr_prec_t p1, p2, p3;
+ int i, inexa, inexd;
+ mpfr_rnd_t r;
+
+ p1 = (randlimb () % 200) + MPFR_PREC_MIN;
+ p2 = (randlimb () % 200) + MPFR_PREC_MIN;
+ p3 = (randlimb () % 200) + MPFR_PREC_MIN;
+
+ mpfr_init2 (ref1, p1);
+ mpfr_init2 (ref2, p2);
+ mpfr_init2 (ref3, p3);
+ mpfr_init2 (res1, p1);
+
+ /* for each variable, consider each of the following 6 possibilities:
+ NaN, +Infinity, -Infinity, +0, -0 or a random number */
+ for (i = 0; i < SPECIAL_MAX * SPECIAL_MAX; i++)
+ {
+ set_special (ref2, i%SPECIAL_MAX);
+ set_special (ref3, i/SPECIAL_MAX);
+
+ inexa = testfunc (res1, ref2, ref3, MPFR_RNDA);
+ r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD;
+ inexd = testfunc (ref1, ref2, ref3, r);
+
+ if (mpfr_compare (res1, ref1) || inexa != inexd)
+ {
+ printf ("Error with RNDA for %s with ", foo);
+ DISP("x=",ref2); DISP2(", y=",ref3);
+ printf ("inexa=%d inexd=%d\n", inexa, inexd);
+ printf ("expected "); mpfr_print_binary (ref1); puts ("");
+ printf ("got "); mpfr_print_binary (res1); puts ("");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref2);
+ mpfr_clear (ref3);
+ mpfr_clear (res1);
+}
+
+static void
+test4 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr,
+ mpfr_rnd_t), const char *foo)
+{
+ mpfr_t ref, op1, op2, op3;
+ mpfr_prec_t pout, p1, p2, p3;
+ mpfr_t res;
+ int i, j, k, inexa, inexd;
+ mpfr_rnd_t r;
+
+ pout = (randlimb () % 200) + MPFR_PREC_MIN;
+ p1 = (randlimb () % 200) + MPFR_PREC_MIN;
+ p2 = (randlimb () % 200) + MPFR_PREC_MIN;
+ p3 = (randlimb () % 200) + MPFR_PREC_MIN;
+
+ mpfr_init2 (ref, pout);
+ mpfr_init2 (res, pout);
+ mpfr_init2 (op1, p1);
+ mpfr_init2 (op2, p2);
+ mpfr_init2 (op3, p3);
+
+ /* for each variable, consider each of the following 6 possibilities:
+ NaN, +Infinity, -Infinity, +0, -0 or a random number */
+
+ for (i = 0; i < SPECIAL_MAX; i++)
+ {
+ set_special (op1, i);
+ for (j = 0; j < SPECIAL_MAX; j++)
+ {
+ set_special (op2, j);
+ for (k = 0; k < SPECIAL_MAX; k++)
+ {
+ set_special (op3, k);
+
+ inexa = testfunc (res, op1, op2, op3, MPFR_RNDA);
+ r = MPFR_SIGN(res) > 0 ? MPFR_RNDU : MPFR_RNDD;
+ inexd = testfunc (ref, op1, op2, op3, r);
+
+ if (mpfr_compare (res, ref) || inexa != inexd)
+ {
+ printf ("Error with RNDA for %s with ", foo);
+ DISP("a=", op1); DISP(", b=", op2); DISP2(", c=", op3);
+ printf ("inexa=%d inexd=%d\n", inexa, inexd);
+ DISP("expected ", ref); DISP2(", got ", res);
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (ref);
+ mpfr_clear (op1);
+ mpfr_clear (op2);
+ mpfr_clear (op3);
+ mpfr_clear (res);
+}
+
+static void
+test2ui (int (*testfunc)(mpfr_ptr, mpfr_srcptr, unsigned long int, mpfr_rnd_t),
+ const char *foo)
+{
+ mpfr_t ref1, ref2;
+ unsigned int ref3;
+ mpfr_t res1;
+ mpfr_prec_t p1, p2;
+ int i, inexa, inexd;
+ mpfr_rnd_t r;
+
+ p1 = (randlimb () % 200) + MPFR_PREC_MIN;
+ p2 = (randlimb () % 200) + MPFR_PREC_MIN;
+
+ mpfr_init2 (ref1, p1);
+ mpfr_init2 (ref2, p2);
+ mpfr_init2 (res1, p1);
+
+ /* ref2 can be NaN, +Inf, -Inf, +0, -0 or any number
+ ref3 can be 0 or any number */
+ for (i = 0; i < SPECIAL_MAX * 2; i++)
+ {
+ set_special (ref2, i % SPECIAL_MAX);
+ ref3 = i / SPECIAL_MAX == 0 ? 0 : randlimb ();
+
+ inexa = testfunc (res1, ref2, ref3, MPFR_RNDA);
+ r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD;
+ inexd = testfunc (ref1, ref2, ref3, r);
+
+ if (mpfr_compare (res1, ref1) || inexa != inexd)
+ {
+ printf ("Error with RNDA for %s for c=%u\n", foo, ref3);
+ DISP2("a=",ref2);
+ printf ("inexa=%d inexd=%d\n", inexa, inexd);
+ printf ("expected "); mpfr_print_binary (ref1); puts ("");
+ printf ("got "); mpfr_print_binary (res1); puts ("");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref2);
+ mpfr_clear (res1);
+}
+
+static void
+testui2 (int (*testfunc)(mpfr_ptr, unsigned long int, mpfr_srcptr, mpfr_rnd_t),
+ const char *foo)
+{
+ mpfr_t ref1, ref3;
+ unsigned int ref2;
+ mpfr_t res1;
+ mpfr_prec_t p1, p3;
+ int i, inexa, inexd;
+ mpfr_rnd_t r;
+
+ p1 = (randlimb () % 200) + MPFR_PREC_MIN;
+ p3 = (randlimb () % 200) + MPFR_PREC_MIN;
+
+ mpfr_init2 (ref1, p1);
+ mpfr_init2 (ref3, p3);
+ mpfr_init2 (res1, p1);
+
+ for (i = 0; i < SPECIAL_MAX * 2; i++)
+ {
+ set_special (ref3, i % SPECIAL_MAX);
+ ref2 = i / SPECIAL_MAX == 0 ? 0 : randlimb ();
+
+ inexa = testfunc (res1, ref2, ref3, MPFR_RNDA);
+ r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD;
+ inexd = testfunc (ref1, ref2, ref3, r);
+
+ if (mpfr_compare (res1, ref1) || inexa != inexd)
+ {
+ printf ("Error with RNDA for %s for b=%u\n", foo, ref2);
+ DISP2("a=", ref3);
+ printf ("inexa=%d inexd=%d\n", inexa, inexd);
+ DISP("expected ", ref1); DISP2(", got ", res1);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref3);
+ mpfr_clear (res1);
+}
+
+/* foo(mpfr_ptr, mpfr_srcptr, mp_rndt) */
+static void
+test2 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_rnd_t), const char *foo)
+{
+ mpfr_t ref1, ref2;
+ mpfr_t res1;
+ mpfr_prec_t p1, p2;
+ int i, inexa, inexd;
+ mpfr_rnd_t r;
+
+ p1 = (randlimb () % 200) + MPFR_PREC_MIN;
+ p2 = (randlimb () % 200) + MPFR_PREC_MIN;
+
+ mpfr_init2 (ref1, p1);
+ mpfr_init2 (ref2, p2);
+ mpfr_init2 (res1, p1);
+
+ for (i = 0; i < SPECIAL_MAX; i++)
+ {
+ set_special (ref2, i);
+
+ /* first round to away */
+ inexa = testfunc (res1, ref2, MPFR_RNDA);
+
+ r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD;
+ inexd = testfunc (ref1, ref2, r);
+ if (mpfr_compare (res1, ref1) || inexa != inexd)
+ {
+ printf ("Error with RNDA for %s with ", foo);
+ DISP2("x=", ref2);
+ printf ("inexa=%d inexd=%d\n", inexa, inexd);
+ DISP("expected ", ref1); DISP2(", got ", res1);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref2);
+ mpfr_clear (res1);
+}
+
+/* one operand, two results, like mpfr_sin_cos */
+static void
+test3a (int (*testfunc)(mpfr_ptr, mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
+ const char *foo)
+{
+ mpfr_t ref1, ref2, ref3;
+ mpfr_t res1, res2;
+ mpfr_prec_t p1, p2, p3;
+ int i, inexa, inexd;
+ mpfr_rnd_t r;
+
+ p1 = (randlimb () % 200) + MPFR_PREC_MIN;
+ p2 = (randlimb () % 200) + MPFR_PREC_MIN;
+ p3 = (randlimb () % 200) + MPFR_PREC_MIN;
+
+ mpfr_init2 (ref1, p1);
+ mpfr_init2 (ref2, p2);
+ mpfr_init2 (ref3, p3);
+ mpfr_init2 (res1, p1);
+ mpfr_init2 (res2, p2);
+
+ for (i = 0; i < SPECIAL_MAX; i++)
+ {
+ set_special (ref3, i);
+
+ inexa = testfunc (res1, res2, ref3, MPFR_RNDA);
+
+ /* first check wrt the first operand */
+ r = MPFR_SIGN(res1) > 0 ? MPFR_RNDU : MPFR_RNDD;
+ inexd = testfunc (ref1, ref2, ref3, r);
+ /* the low 2 bits of the inexact flag concern the 1st operand */
+ if (mpfr_compare (res1, ref1) || (inexa & 3) != (inexd & 3))
+ {
+ printf ("Error with RNDA for %s (1st operand)\n", foo);
+ DISP2("a=",ref3);
+ DISP("expected ", ref1); printf ("\n");
+ DISP("got ", res1); printf ("\n");
+ printf ("inexa=%d inexd=%d\n", inexa & 3, inexd & 3);
+ exit (1);
+ }
+
+ /* now check wrt the second operand */
+ r = MPFR_SIGN(res2) > 0 ? MPFR_RNDU : MPFR_RNDD;
+ inexd = testfunc (ref1, ref2, ref3, r);
+ /* bits 2..3 of the inexact flag concern the 2nd operand */
+ if (mpfr_compare (res2, ref2) || (inexa >> 2) != (inexd >> 2))
+ {
+ printf ("Error with RNDA for %s (2nd operand)\n", foo);
+ DISP2("a=",ref3);
+ DISP("expected ", ref2); printf ("\n");
+ DISP("got ", res2); printf ("\n");
+ printf ("inexa=%d inexd=%d\n", inexa >> 2, inexd >> 2);
+ exit (1);
+ }
+
+ }
+
+ mpfr_clear (ref1);
+ mpfr_clear (ref2);
+ mpfr_clear (ref3);
+ mpfr_clear (res1);
+ mpfr_clear (res2);
+}
+
+int
+main (void)
+{
+ int N = 20;
+
+ tests_start_mpfr ();
+
+ while (N--)
+ {
+ /* no need to test mpfr_round, mpfr_ceil, mpfr_floor, mpfr_trunc since
+ they take no rounding mode */
+
+ test2ui (mpfr_add_ui, "mpfr_add_ui");
+ test2ui (mpfr_div_2exp, "mpfr_div_2exp");
+ test2ui (mpfr_div_ui, "mpfr_div_ui");
+ test2ui (mpfr_mul_2exp, "mpfr_mul_2exp");
+ test2ui (mpfr_mul_ui, "mpfr_mul_ui");
+ test2ui (mpfr_pow_ui, "mpfr_pow_ui");
+ test2ui (mpfr_sub_ui, "mpfr_sub_ui");
+
+ testui2 (mpfr_ui_div, "mpfr_ui_div");
+ testui2 (mpfr_ui_sub, "mpfr_ui_sub");
+ testui2 (mpfr_ui_pow, "mpfr_ui_pow");
+
+ test2 (mpfr_sqr, "mpfr_sqr");
+ test2 (mpfr_sqrt, "mpfr_sqrt");
+ test2 (mpfr_abs, "mpfr_abs");
+ test2 (mpfr_neg, "mpfr_neg");
+
+ test2 (mpfr_log, "mpfr_log");
+ test2 (mpfr_log2, "mpfr_log2");
+ test2 (mpfr_log10, "mpfr_log10");
+ test2 (mpfr_log1p, "mpfr_log1p");
+
+ test2 (mpfr_exp, "mpfr_exp");
+ test2 (mpfr_exp2, "mpfr_exp2");
+ test2 (mpfr_exp10, "mpfr_exp10");
+ test2 (mpfr_expm1, "mpfr_expm1");
+ test2 (mpfr_eint, "mpfr_eint");
+
+ test2 (mpfr_sinh, "mpfr_sinh");
+ test2 (mpfr_cosh, "mpfr_cosh");
+ test2 (mpfr_tanh, "mpfr_tanh");
+ test2 (mpfr_asinh, "mpfr_asinh");
+ test2 (mpfr_acosh, "mpfr_acosh");
+ test2 (mpfr_atanh, "mpfr_atanh");
+ test2 (mpfr_sech, "mpfr_sech");
+ test2 (mpfr_csch, "mpfr_csch");
+ test2 (mpfr_coth, "mpfr_coth");
+
+ test2 (mpfr_asin, "mpfr_asin");
+ test2 (mpfr_acos, "mpfr_acos");
+ test2 (mpfr_atan, "mpfr_atan");
+ test2 (mpfr_cos, "mpfr_cos");
+ test2 (mpfr_sin, "mpfr_sin");
+ test2 (mpfr_tan, "mpfr_tan");
+ test2 (mpfr_sec, "mpfr_sec");
+ test2 (mpfr_csc, "mpfr_csc");
+ test2 (mpfr_cot, "mpfr_cot");
+
+ test2 (mpfr_erf, "mpfr_erf");
+ test2 (mpfr_erfc, "mpfr_erfc");
+ test2 (mpfr_j0, "mpfr_j0");
+ test2 (mpfr_j1, "mpfr_j1");
+ test2 (mpfr_y0, "mpfr_y0");
+ test2 (mpfr_y1, "mpfr_y1");
+ test2 (mpfr_zeta, "mpfr_zeta");
+ test2 (mpfr_gamma, "mpfr_gamma");
+ test2 (mpfr_lngamma, "mpfr_lngamma");
+
+ test2 (mpfr_rint, "mpfr_rint");
+ test2 (mpfr_rint_ceil, "mpfr_rint_ceil");
+ test2 (mpfr_rint_floor, "mpfr_rint_floor");
+ test2 (mpfr_rint_round, "mpfr_rint_round");
+ test2 (mpfr_rint_trunc, "mpfr_rint_trunc");
+ test2 (mpfr_frac, "mpfr_frac");
+
+ test3 (mpfr_add, "mpfr_add");
+ test3 (mpfr_sub, "mpfr_sub");
+ test3 (mpfr_mul, "mpfr_mul");
+ test3 (mpfr_div, "mpfr_div");
+
+ test3 (mpfr_agm, "mpfr_agm");
+ test3 (mpfr_min, "mpfr_min");
+ test3 (mpfr_max, "mpfr_max");
+
+ /* we don't test reldiff since it does not guarantee correct rounding,
+ thus we can get different results with RNDA and RNDU or RNDD. */
+ test3 (mpfr_dim, "mpfr_dim");
+
+ test3 (mpfr_remainder, "mpfr_remainder");
+ test3 (mpfr_pow, "mpfr_pow");
+ test3 (mpfr_atan2, "mpfr_atan2");
+ test3 (mpfr_hypot, "mpfr_hypot");
+
+ test3a (mpfr_sin_cos, "mpfr_sin_cos");
+
+ test4 (mpfr_fma, "mpfr_fma");
+ test4 (mpfr_fms, "mpfr_fms");
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+ test2 (mpfr_li2, "mpfr_li2");
+ test2 (mpfr_rec_sqrt, "mpfr_rec_sqrt");
+ test3 (mpfr_fmod, "mpfr_fmod");
+ test3a (mpfr_modf, "mpfr_modf");
+ test3a (mpfr_sinh_cosh, "mpfr_sinh_cosh");
+#endif
+ }
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tbuildopt.c b/mpfr/tests/tbuildopt.c
new file mode 100644
index 0000000000..f23514cb53
--- /dev/null
+++ b/mpfr/tests/tbuildopt.c
@@ -0,0 +1,89 @@
+/* tbuildopt.c -- test file for mpfr_buildopt_tls_p and
+ mpfr_buildopt_decimal_p.
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include "mpfr-test.h"
+
+static void
+check_tls_p (void)
+{
+#ifdef MPFR_USE_THREAD_SAFE
+ if (!mpfr_buildopt_tls_p())
+ {
+ printf ("Error: mpfr_buildopt_tls_p should return true\n");
+ exit (1);
+ }
+#else
+ if (mpfr_buildopt_tls_p())
+ {
+ printf ("Error: mpfr_buildopt_tls_p should return false\n");
+ exit (1);
+ }
+#endif
+}
+
+static void
+check_decimal_p (void)
+{
+#ifdef MPFR_WANT_DECIMAL_FLOATS
+ if (!mpfr_buildopt_decimal_p())
+ {
+ printf ("Error: mpfr_buildopt_decimal_p should return true\n");
+ exit (1);
+ }
+#else
+ if (mpfr_buildopt_decimal_p())
+ {
+ printf ("Error: mpfr_buildopt_decimal_p should return false\n");
+ exit (1);
+ }
+#endif
+}
+
+static void
+check_gmpinternals_p (void)
+{
+#if defined(MPFR_HAVE_GMP_IMPL) || defined(WANT_GMP_INTERNALS)
+ if (!mpfr_buildopt_gmpinternals_p())
+ {
+ printf ("Error: mpfr_buildopt_gmpinternals_p should return true\n");
+ exit (1);
+ }
+#else
+ if (mpfr_buildopt_gmpinternals_p())
+ {
+ printf ("Error: mpfr_buildopt_gmpinternals_p should return false\n");
+ exit (1);
+ }
+#endif
+}
+
+int
+main (void)
+{
+ check_tls_p();
+ check_decimal_p();
+ check_gmpinternals_p();
+
+ return 0;
+}
diff --git a/mpfr/tests/tcan_round.c b/mpfr/tests/tcan_round.c
new file mode 100644
index 0000000000..4e03fe53de
--- /dev/null
+++ b/mpfr/tests/tcan_round.c
@@ -0,0 +1,127 @@
+/* Test file for mpfr_can_round.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define MAX_LIMB_SIZE 100
+
+static void
+check_round_p (void)
+{
+ mp_limb_t buf[MAX_LIMB_SIZE];
+ mp_size_t n, i;
+ mpfr_prec_t p;
+ mpfr_exp_t err;
+ int r1, r2;
+
+ for (n = 2 ; n <= MAX_LIMB_SIZE ; n++)
+ {
+ /* avoid mpn_random which leaks memory */
+ for (i = 0; i < n; i++)
+ buf[i] = randlimb ();
+ p = randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
+ err = p + randlimb () % GMP_NUMB_BITS;
+ r1 = mpfr_round_p (buf, n, err, p);
+ r2 = mpfr_can_round_raw (buf, n, MPFR_SIGN_POS, err,
+ MPFR_RNDN, MPFR_RNDZ, p);
+ if (r1 != r2)
+ {
+ printf ("mpfr_round_p(%d) != mpfr_can_round(%d)!\n"
+ "bn = %ld, err0 = %ld, prec = %lu\nbp = ",
+ r1, r2, n, (long) err, (unsigned long) p);
+ gmp_printf ("%NX\n", buf, n);
+ exit (1);
+ }
+ }
+}
+
+int
+main (void)
+{
+ mpfr_t x;
+ mpfr_prec_t i, j;
+
+ tests_start_mpfr ();
+
+ /* checks that rounds to nearest sets the last
+ bit to zero in case of equal distance */
+ mpfr_init2 (x, 59);
+ mpfr_set_str_binary (x, "-0.10010001010111000011110010111010111110000000111101100111111E663");
+ if (mpfr_can_round (x, 54, MPFR_RNDZ, MPFR_RNDZ, 53) != 0)
+ {
+ printf ("Error (1) in mpfr_can_round\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "-Inf");
+ if (mpfr_can_round (x, 2000, MPFR_RNDZ, MPFR_RNDZ, 2000) != 0)
+ {
+ printf ("Error (2) in mpfr_can_round\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 64);
+ mpfr_set_str_binary (x, "0.1011001000011110000110000110001111101011000010001110011000000000");
+ if (mpfr_can_round (x, 65, MPFR_RNDN, MPFR_RNDN, 54))
+ {
+ printf ("Error (3) in mpfr_can_round\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 137);
+ mpfr_set_str_binary (x, "-0.10111001101001010110011000110100111010011101101010010100101100001110000100111111011101010110001010111100100101110111100001000010000000000E-97");
+ if (mpfr_can_round (x, 132, MPFR_RNDU, MPFR_RNDZ, 128) == 0)
+ {
+ printf ("Error (4) in mpfr_can_round\n");
+ exit (1);
+ }
+
+ /* in the following, we can round but cannot determine the inexact flag */
+ mpfr_set_prec (x, 86);
+ mpfr_set_str_binary (x, "-0.11100100010011001111011010100111101010011000000000000000000000000000000000000000000000E-80");
+ if (mpfr_can_round (x, 81, MPFR_RNDU, MPFR_RNDZ, 44) == 0)
+ {
+ printf ("Error (5) in mpfr_can_round\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 62);
+ mpfr_set_str (x, "0.ff4ca619c76ba69", 16, MPFR_RNDZ);
+ for (i = 30; i < 99; i++)
+ for (j = 30; j < 99; j++)
+ {
+ int r1, r2;
+ for (r1 = 0; r1 < MPFR_RND_MAX ; r1++)
+ for (r2 = 0; r2 < MPFR_RND_MAX ; r2++)
+ mpfr_can_round (x, i, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, j); /* test for assertions */
+ }
+
+ mpfr_clear (x);
+
+ check_round_p ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcbrt.c b/mpfr/tests/tcbrt.c
new file mode 100644
index 0000000000..1c96e51bfc
--- /dev/null
+++ b/mpfr/tests/tcbrt.c
@@ -0,0 +1,219 @@
+/* Test file for mpfr_cbrt.
+
+Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* cbrt(NaN) = NaN */
+ mpfr_set_nan (x);
+ mpfr_cbrt (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: cbrt(NaN) <> NaN\n");
+ exit (1);
+ }
+
+ /* cbrt(+Inf) = +Inf */
+ mpfr_set_inf (x, 1);
+ mpfr_cbrt (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: cbrt(+Inf) <> +Inf\n");
+ exit (1);
+ }
+
+ /* cbrt(-Inf) = -Inf */
+ mpfr_set_inf (x, -1);
+ mpfr_cbrt (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error: cbrt(-Inf) <> -Inf\n");
+ exit (1);
+ }
+
+ /* cbrt(+/-0) = +/-0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_cbrt (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: cbrt(+0) <> +0\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_cbrt (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error: cbrt(-0) <> -0\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_str (x, "8.39005285514734966412e-01", 10, MPFR_RNDN);
+ mpfr_cbrt (x, x, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, "9.43166207799662426048e-01"))
+ {
+ printf ("Error in crbrt (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (x, "0.10000100001100101001001001011001");
+ mpfr_cbrt (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.11001101011000100111000111111001");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in cbrt (2)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (x, "-0.1100001110110000010101011001011");
+ mpfr_cbrt (x, x, MPFR_RNDD);
+ mpfr_set_str_binary (y, "-0.11101010000100100101000101011001");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in cbrt (3)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 82);
+ mpfr_set_prec (y, 27);
+ mpfr_set_str_binary (x, "0.1010001111011101011011000111001011001101100011110110010011011011011010011001100101e-7");
+ mpfr_cbrt (y, x, MPFR_RNDD);
+ mpfr_set_str_binary (x, "0.101011110001110001000100011E-2");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in cbrt (4)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 204);
+ mpfr_set_prec (y, 38);
+ mpfr_set_str_binary (x, "0.101000000001101000000001100111111011111001110110100001111000100110100111001101100111110001110001011011010110010011100101111001111100001010010100111011101100000011011000101100010000000011000101001010001001E-5");
+ mpfr_cbrt (y, x, MPFR_RNDD);
+ mpfr_set_str_binary (x, "0.10001001111010011011101000010110110010E-1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in cbrt (5)\n");
+ exit (1);
+ }
+
+ /* Bug (in the compiler?) found on Linux/m68k with gcc 4.0.2 */
+ mpfr_set_prec (x, 5);
+ mpfr_set_prec (y, 5);
+ mpfr_set_str_binary (x, "1.1000E-2");
+ mpfr_cbrt (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "1.0111E-1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in cbrt (6)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_cbrt
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_t x;
+ int r;
+ mpfr_prec_t p;
+
+ tests_start_mpfr ();
+
+ special ();
+
+ mpfr_init (x);
+
+ for (p=2; p<100; p++)
+ {
+ mpfr_set_prec (x, p);
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_cbrt (x, x, (mpfr_rnd_t) r);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error in mpfr_cbrt for x=1, rnd=%s\ngot ",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_cbrt (x, x, (mpfr_rnd_t) r);
+ if (mpfr_cmp_si (x, -1))
+ {
+ printf ("Error in mpfr_cbrt for x=-1, rnd=%s\ngot ",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ if (p >= 5)
+ {
+ int i;
+ for (i = -12; i <= 12; i++)
+ {
+ mpfr_set_ui (x, 27, MPFR_RNDN);
+ mpfr_mul_2si (x, x, 3*i, MPFR_RNDN);
+ mpfr_cbrt (x, x, MPFR_RNDN);
+ if (mpfr_cmp_si_2exp (x, 3, i))
+ {
+ printf ("Error in mpfr_cbrt for "
+ "x = 27.0 * 2^(%d), rnd=%s\ngot ",
+ 3*i, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\ninstead of 3 * 2^(%d)\n", i);
+ exit (1);
+ }
+ }
+ }
+ }
+ }
+ mpfr_clear (x);
+
+ test_generic (2, 200, 10);
+
+ data_check ("data/cbrt", mpfr_cbrt, "mpfr_cbrt");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcheck.c b/mpfr/tests/tcheck.c
new file mode 100644
index 0000000000..300916dfad
--- /dev/null
+++ b/mpfr/tests/tcheck.c
@@ -0,0 +1,125 @@
+/* Test file for mpfr_check.
+
+Copyright 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mpfr-test.h"
+
+#define ERROR(s) \
+ (printf ("mpfr_check failed " s " Prec=%lu\n", (unsigned long) pr), \
+ exit(1))
+
+int
+main (void)
+{
+ mpfr_t a;
+ mp_limb_t *p, tmp;
+ mp_size_t s;
+ mpfr_prec_t pr;
+ int max;
+
+ tests_start_mpfr ();
+ for(pr = MPFR_PREC_MIN ; pr < 500 ; pr++)
+ {
+ mpfr_init2 (a, pr);
+ if (!mpfr_check(a)) ERROR("for init");
+ /* Check special cases */
+ MPFR_SET_NAN(a);
+ if (!mpfr_check(a)) ERROR("for nan");
+ MPFR_SET_POS(a);
+ MPFR_SET_INF(a);
+ if (!mpfr_check(a)) ERROR("for inf");
+ MPFR_SET_ZERO(a);
+ if (!mpfr_check(a)) ERROR("for zero");
+ /* Check var */
+ mpfr_set_ui(a, 2, MPFR_RNDN);
+ if (!mpfr_check(a)) ERROR("for set_ui");
+ mpfr_clear_overflow();
+ max = 1000; /* Allows max 2^1000 bits for the exponent */
+ while ((!mpfr_overflow_p()) && (max>0))
+ {
+ mpfr_mul(a, a, a, MPFR_RNDN);
+ if (!mpfr_check(a)) ERROR("for mul");
+ max--;
+ }
+ if (max==0) ERROR("can't reach overflow");
+ mpfr_set_ui(a, 2137, MPFR_RNDN);
+ /* Corrupt a and check for it */
+ MPFR_SIGN(a) = 2;
+ if (mpfr_check(a)) ERROR("sgn");
+ MPFR_SET_POS(a);
+ /* Check prec */
+ MPFR_PREC(a) = 1;
+ if (mpfr_check(a)) ERROR("precmin");
+#if MPFR_VERSION_MAJOR < 3
+ /* Disable the test with MPFR >= 3 since mpfr_prec_t is now signed.
+ The "if" below is sufficient, but the MPFR_PREC_MAX+1 generates
+ a warning with GCC 4.4.4 even though the test is always false. */
+ if ((mpfr_prec_t) 0 - 1 > 0)
+ {
+ MPFR_PREC(a) = MPFR_PREC_MAX+1;
+ if (mpfr_check(a)) ERROR("precmax");
+ }
+#endif
+ MPFR_PREC(a) = pr;
+ if (!mpfr_check(a)) ERROR("prec");
+ /* Check exponent */
+ MPFR_EXP(a) = MPFR_EXP_INVALID;
+ if (mpfr_check(a)) ERROR("exp invalid");
+ MPFR_EXP(a) = -MPFR_EXP_INVALID;
+ if (mpfr_check(a)) ERROR("-exp invalid");
+ MPFR_EXP(a) = 0;
+ if (!mpfr_check(a)) ERROR("exp 0");
+ /* Check Mantissa */
+ p = MPFR_MANT(a);
+ MPFR_MANT(a) = NULL;
+ if (mpfr_check(a)) ERROR("Mantissa Null Ptr");
+ MPFR_MANT(a) = p;
+ /* Check size */
+ s = MPFR_GET_ALLOC_SIZE(a);
+ MPFR_SET_ALLOC_SIZE(a, 0);
+ if (mpfr_check(a)) ERROR("0 size");
+ MPFR_SET_ALLOC_SIZE(a, MP_SIZE_T_MIN);
+ if (mpfr_check(a)) ERROR("min size");
+ MPFR_SET_ALLOC_SIZE(a, MPFR_LIMB_SIZE(a)-1 );
+ if (mpfr_check(a)) ERROR("size < prec");
+ MPFR_SET_ALLOC_SIZE(a, s);
+ /* Check normal form */
+ tmp = MPFR_MANT(a)[0];
+ if ((pr % GMP_NUMB_BITS) != 0)
+ {
+ MPFR_MANT(a)[0] = ~0;
+ if (mpfr_check(a)) ERROR("last bits non 0");
+ }
+ MPFR_MANT(a)[0] = tmp;
+ MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] &= MPFR_LIMB_MASK (GMP_NUMB_BITS-1);
+ if (mpfr_check(a)) ERROR("last bits non 0");
+ /* Final */
+ mpfr_set_ui(a, 2137, MPFR_RNDN);
+ if (!mpfr_check(a)) ERROR("after last set");
+ mpfr_clear (a);
+ if (mpfr_check(a)) ERROR("after clear");
+ }
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcmp.c b/mpfr/tests/tcmp.c
new file mode 100644
index 0000000000..6bf6bdc2f6
--- /dev/null
+++ b/mpfr/tests/tcmp.c
@@ -0,0 +1,220 @@
+/* Test file for mpfr_cmp.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ double x, y;
+ mpfr_t xx, yy;
+ int c;
+ long i;
+ mpfr_prec_t p;
+
+ tests_start_mpfr ();
+
+ mpfr_init (xx);
+ mpfr_init (yy);
+
+ mpfr_set_prec (xx, 2);
+ mpfr_set_prec (yy, 2);
+ mpfr_set_str_binary(xx, "-0.10E0");
+ mpfr_set_str_binary(yy, "-0.10E0");
+ if ((mpfr_cmp) (xx, yy))
+ {
+ printf ("mpfr_cmp (xx, yy) returns non-zero for prec=2\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (xx, 65);
+ mpfr_set_prec (yy, 65);
+ mpfr_set_str_binary(xx, "0.10011010101000110101010000000011001001001110001011101011111011101E623");
+ mpfr_set_str_binary(yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623");
+ p = 0;
+ if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 64)
+ {
+ printf ("Error (1) in mpfr_cmp2\n");
+ exit (1);
+ }
+ mpfr_set_str_binary(xx, "0.10100010001110110111000010001000010011111101000100011101000011100");
+ mpfr_set_str_binary(yy, "0.10100010001110110111000010001000010011111101000100011101000011011");
+ p = 0;
+ if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 64)
+ {
+ printf ("Error (2) in mpfr_cmp2\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (xx, 160); mpfr_set_prec (yy, 160);
+ mpfr_set_str_binary (xx, "0.1E1");
+ mpfr_set_str_binary (yy, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100");
+ p = 0;
+ if (mpfr_cmp2 (xx, yy, &p) <= 0 || p != 144)
+ {
+ printf ("Error (3) in mpfr_cmp2\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (xx, 53);
+ mpfr_set_prec (yy, 200);
+ mpfr_set_ui (xx, 1, (mpfr_rnd_t) 0);
+ mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0);
+ if (mpfr_cmp (xx, yy) != 0)
+ {
+ printf ("Error in mpfr_cmp: 1.0 != 1.0\n");
+ exit (1);
+ }
+ mpfr_set_prec (yy, 31);
+ mpfr_set_str (xx, "1.0000000002", 10, (mpfr_rnd_t) 0);
+ mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0);
+ if (!(mpfr_cmp (xx,yy)>0))
+ {
+ printf ("Error in mpfr_cmp: not 1.0000000002 > 1.0\n");
+ exit (1);
+ }
+ mpfr_set_prec (yy, 53);
+
+ /* bug found by Gerardo Ballabio */
+ mpfr_set_ui(xx, 0, MPFR_RNDN);
+ mpfr_set_str (yy, "0.1", 10, MPFR_RNDN);
+ if ((c = mpfr_cmp (xx, yy)) >= 0)
+ {
+ printf ("Error in mpfr_cmp(0.0, 0.1), gives %d\n", c);
+ exit (1);
+ }
+
+ mpfr_set_inf (xx, 1);
+ mpfr_set_str (yy, "-23489745.0329", 10, MPFR_RNDN);
+ if ((c = mpfr_cmp (xx, yy)) <= 0)
+ {
+ printf ("Error in mpfr_cmp(Infp, 23489745.0329), gives %d\n", c);
+ exit (1);
+ }
+
+ mpfr_set_inf (xx, 1);
+ mpfr_set_inf (yy, -1);
+ if ((c = mpfr_cmp (xx, yy)) <= 0)
+ {
+ printf ("Error in mpfr_cmp(Infp, Infm), gives %d\n", c);
+ exit (1);
+ }
+
+ mpfr_set_inf (xx, -1);
+ mpfr_set_inf (yy, 1);
+ if ((c = mpfr_cmp (xx, yy)) >= 0)
+ {
+ printf ("Error in mpfr_cmp(Infm, Infp), gives %d\n", c);
+ exit (1);
+ }
+
+ mpfr_set_inf (xx, 1);
+ mpfr_set_inf (yy, 1);
+ if ((c = mpfr_cmp (xx, yy)) != 0)
+ {
+ printf ("Error in mpfr_cmp(Infp, Infp), gives %d\n", c);
+ exit (1);
+ }
+
+ mpfr_set_inf (xx, -1);
+ mpfr_set_inf (yy, -1);
+ if ((c = mpfr_cmp (xx, yy)) != 0)
+ {
+ printf ("Error in mpfr_cmp(Infm, Infm), gives %d\n", c);
+ exit (1);
+ }
+
+ mpfr_set_inf (xx, -1);
+ mpfr_set_str (yy, "2346.09234", 10, MPFR_RNDN);
+ if ((c = mpfr_cmp (xx, yy)) >= 0)
+ {
+ printf ("Error in mpfr_cmp(Infm, 2346.09234), gives %d\n", c);
+ exit (1);
+ }
+
+ mpfr_set_ui (xx, 0, MPFR_RNDN);
+ mpfr_set_ui (yy, 1, MPFR_RNDN);
+ if ((c = mpfr_cmp3 (xx, yy, 1)) >= 0)
+ {
+ printf ("Error: mpfr_cmp3 (0, 1, 1) gives %d instead of"
+ " a negative value\n", c);
+ exit (1);
+ }
+ if ((c = mpfr_cmp3 (xx, yy, -1)) <= 0)
+ {
+ printf ("Error: mpfr_cmp3 (0, 1, -1) gives %d instead of"
+ " a positive value\n", c);
+ exit (1);
+ }
+
+ for (i=0; i<500000; )
+ {
+ x = DBL_RAND ();
+ y = DBL_RAND ();
+ if (!Isnan(x) && !Isnan(y))
+ {
+ i++;
+ mpfr_set_d (xx, x, MPFR_RNDN);
+ mpfr_set_d (yy, y, MPFR_RNDN);
+ c = mpfr_cmp (xx,yy);
+ if ((c>0 && x<=y) || (c==0 && x!=y) || (c<0 && x>=y))
+ {
+ printf ("Error in mpfr_cmp with x=%1.20e, y=%1.20e"
+ " mpfr_cmp(x,y)=%d\n", x, y, c);
+ exit (1);
+ }
+ }
+ }
+
+ /* Check for NAN */
+ mpfr_set_nan (xx);
+ mpfr_clear_erangeflag ();
+ c = (mpfr_cmp) (xx, yy);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (1)\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = (mpfr_cmp) (yy, xx);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (2)\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = (mpfr_cmp) (xx, xx);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (3)\n");
+ exit (1);
+ }
+
+ mpfr_clear (xx);
+ mpfr_clear (yy);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcmp2.c b/mpfr/tests/tcmp2.c
new file mode 100644
index 0000000000..04004cd42b
--- /dev/null
+++ b/mpfr/tests/tcmp2.c
@@ -0,0 +1,348 @@
+/* Test file for mpfr_cmp2.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* set bit n of x to b, where bit 0 is the most significant one */
+static void
+set_bit (mpfr_t x, unsigned int n, int b)
+{
+ unsigned l;
+ mp_size_t xn;
+
+ xn = (MPFR_PREC(x) - 1) / mp_bits_per_limb;
+ l = n / mp_bits_per_limb;
+ n %= mp_bits_per_limb;
+ n = mp_bits_per_limb - 1 - n;
+ if (b)
+ MPFR_MANT(x)[xn - l] |= (mp_limb_t) 1 << n;
+ else
+ MPFR_MANT(x)[xn - l] &= ~((mp_limb_t) 1 << n);
+}
+
+/* check that for x = 1.u 1 v 0^k low(x)
+ y = 1.u 0 v 1^k low(y)
+ mpfr_cmp2 (x, y) returns 1 + |u| + |v| + k for low(x) >= low(y),
+ and 1 + |u| + |v| + k + 1 otherwise */
+static void
+worst_cases (void)
+{
+ mpfr_t x, y;
+ unsigned int i, j, k, b, expected;
+ mpfr_prec_t l;
+
+ mpfr_init2 (x, 200);
+ mpfr_init2 (y, 200);
+
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ for (i = 1; i < MPFR_PREC(x); i++)
+ {
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_div_2exp (y, y, 1, MPFR_RNDN); /* y = 1/2^i */
+
+ l = 0;
+ if (mpfr_cmp2 (x, y, &l) <= 0 || l != 1)
+ {
+ printf ("Error in mpfr_cmp2:\nx=");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\ny=");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\ngot %lu instead of 1\n", (unsigned long) l);
+ exit (1);
+ }
+
+ mpfr_add (x, x, y, MPFR_RNDN); /* x = 1 + 1/2^i */
+ l = 0;
+ if (mpfr_cmp2 (x, y, &l) <= 0 || l != 0)
+ {
+ printf ("Error in mpfr_cmp2:\nx=");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\ny=");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\ngot %lu instead of 0\n", (unsigned long) l);
+ exit (1);
+ }
+ }
+
+ for (i = 0; i < 64; i++) /* |u| = i */
+ {
+ mpfr_urandomb (x, RANDS);
+ mpfr_set (y, x, MPFR_RNDN);
+ set_bit (x, i + 1, 1);
+ set_bit (y, i + 1, 0);
+ for (j = 0; j < 64; j++) /* |v| = j */
+ {
+ b = randlimb () % 2;
+ set_bit (x, i + j + 2, b);
+ set_bit (y, i + j + 2, b);
+ for (k = 0; k < 64; k++)
+ {
+ if (k)
+ set_bit (x, i + j + k + 1, 0);
+ if (k)
+ set_bit (y, i + j + k + 1, 1);
+ set_bit (x, i + j + k + 2, 1);
+ set_bit (y, i + j + k + 2, 0);
+ l = 0; mpfr_cmp2 (x, y, &l);
+ expected = i + j + k + 1;
+ if (l != expected)
+ {
+ printf ("Error in mpfr_cmp2:\nx=");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\ny=");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\ngot %lu instead of %u\n",
+ (unsigned long) l, expected);
+ exit (1);
+ }
+ set_bit (x, i + j + k + 2, 0);
+ set_bit (x, i + j + k + 3, 0);
+ set_bit (y, i + j + k + 3, 1);
+ l = 0; mpfr_cmp2 (x, y, &l);
+ expected = i + j + k + 2;
+ if (l != expected)
+ {
+ printf ("Error in mpfr_cmp2:\nx=");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\ny=");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\ngot %lu instead of %u\n",
+ (unsigned long) l, expected);
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+tcmp2 (double x, double y, int i)
+{
+ mpfr_t xx, yy;
+ mpfr_prec_t j;
+
+ if (i == -1)
+ {
+ if (x == y)
+ i = 53;
+ else
+ i = (int) (__gmpfr_floor_log2 (x) - __gmpfr_floor_log2 (x - y));
+ }
+ mpfr_init2(xx, 53); mpfr_init2(yy, 53);
+ mpfr_set_d (xx, x, MPFR_RNDN);
+ mpfr_set_d (yy, y, MPFR_RNDN);
+ j = 0;
+ if (mpfr_cmp2 (xx, yy, &j) == 0)
+ {
+ if (x != y)
+ {
+ printf ("Error in mpfr_cmp2 for\nx=");
+ mpfr_out_str (stdout, 2, 0, xx, MPFR_RNDN);
+ printf ("\ny=");
+ mpfr_out_str (stdout, 2, 0, yy, MPFR_RNDN);
+ printf ("\ngot sign 0 for x != y\n");
+ exit (1);
+ }
+ }
+ else if (j != (unsigned) i)
+ {
+ printf ("Error in mpfr_cmp2 for\nx=");
+ mpfr_out_str (stdout, 2, 0, xx, MPFR_RNDN);
+ printf ("\ny=");
+ mpfr_out_str (stdout, 2, 0, yy, MPFR_RNDN);
+ printf ("\ngot %lu instead of %d\n", (unsigned long) j, i);
+ exit (1);
+ }
+ mpfr_clear(xx); mpfr_clear(yy);
+}
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ mpfr_prec_t j;
+
+ mpfr_init (x); mpfr_init (y);
+
+ /* bug found by Nathalie Revol, 21 March 2001 */
+ mpfr_set_prec (x, 65);
+ mpfr_set_prec (y, 65);
+ mpfr_set_str_binary (x, "0.10000000000000000000000000000000000001110010010110100110011110000E1");
+ mpfr_set_str_binary (y, "0.11100100101101001100111011111111110001101001000011101001001010010E-35");
+ j = 0;
+ if (mpfr_cmp2 (x, y, &j) <= 0 || j != 1)
+ {
+ printf ("Error in mpfr_cmp2:\n");
+ printf ("x=");
+ mpfr_print_binary (x);
+ puts ("");
+ printf ("y=");
+ mpfr_print_binary (y);
+ puts ("");
+ printf ("got %lu, expected 1\n", (unsigned long) j);
+ exit (1);
+ }
+
+ mpfr_set_prec(x, 127); mpfr_set_prec(y, 127);
+ mpfr_set_str_binary(x, "0.1011010000110111111000000101011110110001000101101011011110010010011110010000101101000010011001100110010000000010110000101000101E6");
+ mpfr_set_str_binary(y, "0.1011010000110111111000000101011011111100011101000011001111000010100010100110110100110010011001100110010000110010010110000010110E6");
+ j = 0;
+ if (mpfr_cmp2(x, y, &j) <= 0 || j != 32)
+ {
+ printf ("Error in mpfr_cmp2:\n");
+ printf ("x="); mpfr_print_binary(x); puts ("");
+ printf ("y="); mpfr_print_binary(y); puts ("");
+ printf ("got %lu, expected 32\n", (unsigned long) j);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 128); mpfr_set_prec (y, 239);
+ mpfr_set_str_binary (x, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100100000000000E167");
+ mpfr_set_str_binary (y, "0.10001000110110000111011000101011111100110010010011001101000011111010010110001000000010100110100111111011011010101100011111111111111111111111111111111111111111111111011111100101011100011001101000100111000010000000000101100110000111111000101E167");
+ j = 0;
+ if (mpfr_cmp2(x, y, &j) <= 0 || j != 164)
+ {
+ printf ("Error in mpfr_cmp2:\n");
+ printf ("x="); mpfr_print_binary(x); puts ("");
+ printf ("y="); mpfr_print_binary(y); puts ("");
+ printf ("got %lu, expected 164\n", (unsigned long) j);
+ exit (1);
+ }
+
+ /* bug found by Nathalie Revol, 29 March 2001 */
+ mpfr_set_prec (x, 130); mpfr_set_prec (y, 130);
+ mpfr_set_str_binary (x, "0.1100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E2");
+ mpfr_set_str_binary (y, "0.1011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100E2");
+ j = 0;
+ if (mpfr_cmp2(x, y, &j) <= 0 || j != 127)
+ {
+ printf ("Error in mpfr_cmp2:\n");
+ printf ("x="); mpfr_print_binary(x); puts ("");
+ printf ("y="); mpfr_print_binary(y); puts ("");
+ printf ("got %lu, expected 127\n", (unsigned long) j);
+ exit (1);
+ }
+
+ /* bug found by Nathalie Revol, 2 Apr 2001 */
+ mpfr_set_prec (x, 65); mpfr_set_prec (y, 65);
+ mpfr_set_ui (x, 5, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.10011111111111111111111111111111111111111111111111111111111111101E3");
+ j = 0;
+ if (mpfr_cmp2(x, y, &j) <= 0 || j != 63)
+ {
+ printf ("Error in mpfr_cmp2:\n");
+ printf ("x="); mpfr_print_binary(x); puts ("");
+ printf ("y="); mpfr_print_binary(y); puts ("");
+ printf ("got %lu, expected 63\n", (unsigned long) j);
+ exit (1);
+ }
+
+ /* bug found by Nathalie Revol, 2 Apr 2001 */
+ mpfr_set_prec (x, 65); mpfr_set_prec (y, 65);
+ mpfr_set_str_binary (x, "0.10011011111000101001110000000000000000000000000000000000000000000E-69");
+ mpfr_set_str_binary (y, "0.10011011111000101001101111111111111111111111111111111111111111101E-69");
+ j = 0;
+ if (mpfr_cmp2(x, y, &j) <= 0 || j != 63)
+ {
+ printf ("Error in mpfr_cmp2:\n");
+ printf ("x="); mpfr_print_binary(x); puts ("");
+ printf ("y="); mpfr_print_binary(y); puts ("");
+ printf ("got %lu, expected 63\n", (unsigned long) j);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 65);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
+ mpfr_set_str_binary (y, "0.11101110111100011101110111111111");
+ if (mpfr_cmp2 (x, y, &j) <= 0 || j != 0)
+ {
+ printf ("Error in mpfr_cmp2 (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2 * GMP_NUMB_BITS);
+ mpfr_set_prec (y, GMP_NUMB_BITS);
+ mpfr_set_ui (x, 1, MPFR_RNDN); /* x = 1 */
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_nextbelow (y); /* y = 1 - 2^(-GMP_NUMB_BITS) */
+ mpfr_cmp2 (x, y, &j);
+ if (mpfr_cmp2 (x, y, &j) <= 0 || j != GMP_NUMB_BITS)
+ {
+ printf ("Error in mpfr_cmp2 (2)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (void)
+{
+ int i;
+ long j;
+ double x, y, z;
+
+ tests_start_mpfr ();
+ mpfr_test_init ();
+
+ worst_cases ();
+ special ();
+ tcmp2 (5.43885304644369510000e+185, -1.87427265794105340000e-57, 1);
+ tcmp2 (1.06022698059744327881e+71, 1.05824655795525779205e+71, -1);
+ tcmp2 (1.0, 1.0, 53);
+ /* warning: cmp2 does not allow 0 as input */
+ for (x = 0.5, i = 1; i < 54; i++)
+ {
+ tcmp2 (1.0, 1.0-x, i);
+ x /= 2.0;
+ }
+ for (x = 0.5, i = 1; i < 100; i++)
+ {
+ tcmp2 (1.0, x, 1);
+ x /= 2.0;
+ }
+ for (j = 0; j < 100000; j++)
+ {
+ x = DBL_RAND ();
+ y = DBL_RAND ();
+ if (x < y)
+ {
+ z = x;
+ x = y;
+ y = z;
+ }
+ if (y != 0.0)
+ tcmp2 (x, y, -1);
+ }
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tcmp_d.c b/mpfr/tests/tcmp_d.c
new file mode 100644
index 0000000000..809c955ca1
--- /dev/null
+++ b/mpfr/tests/tcmp_d.c
@@ -0,0 +1,104 @@
+/* Test file for mpfr_cmp_d.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ mpfr_t x;
+ int c;
+
+ tests_start_mpfr ();
+
+ mpfr_init2(x, IEEE_DBL_MANT_DIG);
+
+ mpfr_set_d (x, 2.34763465, MPFR_RNDN);
+ if (mpfr_cmp_d(x, 2.34763465)!=0) {
+ printf("Error in mpfr_cmp_d 2.34763465 and ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
+ exit(1);
+ }
+ if (mpfr_cmp_d(x, 2.345)<=0) {
+ printf("Error in mpfr_cmp_d 2.345 and ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
+ exit(1);
+ }
+ if (mpfr_cmp_d(x, 2.4)>=0) {
+ printf("Error in mpfr_cmp_d 2.4 and ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
+ exit(1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_neg (x, x, MPFR_RNDZ);
+ if (mpfr_cmp_d (x, 0.0)) {
+ printf("Error in mpfr_cmp_d 0.0 and ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
+ exit(1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_ui_div (x, 1, x, MPFR_RNDU);
+ if (mpfr_cmp_d (x, 0.0) == 0)
+ {
+ printf ("Error in mpfr_cmp_d (Inf, 0)\n");
+ exit (1);
+ }
+
+#if !defined(MPFR_ERRDIVZERO)
+ /* Check NAN */
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_d (x, DBL_NAN);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for NAN (1)\n");
+#ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "
+ "file.\n");
+#endif
+ exit (1);
+ }
+ mpfr_set_nan (x);
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_d (x, 2.0);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for NAN (2)\n");
+#ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "
+ "file.\n");
+#endif
+ exit (1);
+ }
+#endif /* MPFR_ERRDIVZERO */
+
+ mpfr_clear(x);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcmp_ld.c b/mpfr/tests/tcmp_ld.c
new file mode 100644
index 0000000000..344898370b
--- /dev/null
+++ b/mpfr/tests/tcmp_ld.c
@@ -0,0 +1,105 @@
+/* Test file for mpfr_cmp_ld.
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ mpfr_t x;
+ int c;
+
+ tests_start_mpfr ();
+
+ mpfr_init2(x, MPFR_LDBL_MANT_DIG);
+
+ mpfr_set_ld (x, 2.34763465L, MPFR_RNDN);
+ if (mpfr_cmp_ld(x, 2.34763465L)!=0) {
+ printf("Error in mpfr_cmp_ld 2.34763465 and ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
+ exit(1);
+ }
+ if (mpfr_cmp_ld(x, 2.345L)<=0) {
+ printf("Error in mpfr_cmp_ld 2.345 and ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
+ exit(1);
+ }
+ if (mpfr_cmp_ld(x, 2.4L)>=0) {
+ printf("Error in mpfr_cmp_ld 2.4 and ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
+ exit(1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_neg (x, x, MPFR_RNDZ);
+ if (mpfr_cmp_ld (x, 0.0)) {
+ printf("Error in mpfr_cmp_ld 0.0 and ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
+ exit(1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_ui_div (x, 1, x, MPFR_RNDU);
+ if (mpfr_cmp_ld (x, 0.0) == 0)
+ {
+ printf ("Error in mpfr_cmp_ld (Inf, 0)\n");
+ exit (1);
+ }
+
+#if !defined(MPFR_ERRDIVZERO)
+ /* Check NAN */
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_ld (x, DBL_NAN);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for NAN (1)\n");
+#ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "
+ "file.\n");
+#endif
+ exit (1);
+ }
+ mpfr_set_nan (x);
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_ld (x, 2.0);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for NAN (2)\n");
+#ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "
+ "file.\n");
+#endif
+ exit (1);
+ }
+#endif /* MPFR_ERRDIVZERO */
+
+ mpfr_clear(x);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+
diff --git a/mpfr/tests/tcmp_ui.c b/mpfr/tests/tcmp_ui.c
new file mode 100644
index 0000000000..012955a589
--- /dev/null
+++ b/mpfr/tests/tcmp_ui.c
@@ -0,0 +1,346 @@
+/* Test file for mpfr_cmp_ui and mpfr_cmp_si.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef TCMP_UI_CHECK_NAN
+
+mpfr_clear_erangeflag ();
+c = mpfr_cmp_si (x, TCMP_UI_CHECK_NAN);
+if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("NaN error on %d (1)\n", TCMP_UI_CHECK_NAN);
+ exit (1);
+ }
+mpfr_clear_erangeflag ();
+c = (mpfr_cmp_si) (x, TCMP_UI_CHECK_NAN);
+if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("NaN error on %d (2)\n", TCMP_UI_CHECK_NAN);
+ exit (1);
+ }
+if (TCMP_UI_CHECK_NAN >= 0)
+ {
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_ui (x, TCMP_UI_CHECK_NAN);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("NaN error on %d (3)\n", TCMP_UI_CHECK_NAN);
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = (mpfr_cmp_ui) (x, TCMP_UI_CHECK_NAN);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("NaN error on %d (4)\n", TCMP_UI_CHECK_NAN);
+ exit (1);
+ }
+ }
+
+#else
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+check_nan (void)
+{
+ mpfr_t x;
+ int c, i;
+
+ mpfr_init (x);
+ mpfr_set_nan (x);
+ /* We need constants to completely test the macros. */
+#undef TCMP_UI_CHECK_NAN
+#define TCMP_UI_CHECK_NAN -17
+#include "tcmp_ui.c"
+#undef TCMP_UI_CHECK_NAN
+#define TCMP_UI_CHECK_NAN 0
+#include "tcmp_ui.c"
+#undef TCMP_UI_CHECK_NAN
+#define TCMP_UI_CHECK_NAN 17
+#include "tcmp_ui.c"
+ for (i = -17; i <= 17; i += 17)
+ {
+#undef TCMP_UI_CHECK_NAN
+#define TCMP_UI_CHECK_NAN i
+#include "tcmp_ui.c"
+ }
+ mpfr_clear (x);
+}
+
+/* Since mpfr_cmp_ui and mpfr_cmp_si are also implemented by a macro
+ with __builtin_constant_p for GCC, check that side effects are
+ handled correctly. */
+static void
+check_macros (void)
+{
+ mpfr_t x;
+ int c;
+
+ mpfr_init2 (x, 32);
+
+ c = 0;
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 17) != 0)
+ {
+ printf ("Error 1 on mpfr_cmp_ui(x,17) in check_macros\n");
+ exit (1);
+ }
+ if (mpfr_cmp_ui (x, (c++, 17)) != 0)
+ {
+ printf ("Error 2 on mpfr_cmp_ui(x,17) in check_macros\n");
+ exit (1);
+ }
+ if (c != 1)
+ {
+ printf ("Error 3 on mpfr_cmp_ui(x,17) in check_macros\n"
+ "(c = %d instead of 1)\n", c);
+ exit (1);
+ }
+ if (mpfr_cmp_si (x, 17) != 0)
+ {
+ printf ("Error 1 on mpfr_cmp_si(x,17) in check_macros\n");
+ exit (1);
+ }
+ if (mpfr_cmp_si (x, (c++, 17)) != 0)
+ {
+ printf ("Error 2 on mpfr_cmp_si(x,17) in check_macros\n");
+ exit (1);
+ }
+ if (c != 2)
+ {
+ printf ("Error 3 on mpfr_cmp_si(x,17) in check_macros\n"
+ "(c = %d instead of 2)\n", c);
+ exit (1);
+ }
+
+ c = 0;
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0) != 0)
+ {
+ printf ("Error 1 on mpfr_cmp_ui(x,0) in check_macros\n");
+ exit (1);
+ }
+ if (mpfr_cmp_ui (x, (c++, 0)) != 0)
+ {
+ printf ("Error 2 on mpfr_cmp_ui(x,0) in check_macros\n");
+ exit (1);
+ }
+ if (c != 1)
+ {
+ printf ("Error 3 on mpfr_cmp_ui(x,0) in check_macros\n"
+ "(c = %d instead of 1)\n", c);
+ exit (1);
+ }
+ if (mpfr_cmp_si (x, 0) != 0)
+ {
+ printf ("Error 1 on mpfr_cmp_si(x,0) in check_macros\n");
+ exit (1);
+ }
+ if (mpfr_cmp_si (x, (c++, 0)) != 0)
+ {
+ printf ("Error 2 on mpfr_cmp_si(x,0) in check_macros\n");
+ exit (1);
+ }
+ if (c != 2)
+ {
+ printf ("Error 3 on mpfr_cmp_si(x,0) in check_macros\n"
+ "(c = %d instead of 2)\n", c);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+}
+
+/* Bug in r7114 */
+static void
+test_macros (void)
+{
+ mpfr_t x[3];
+ mpfr_ptr p;
+
+ mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0);
+ mpfr_set_ui (x[0], 0, MPFR_RNDN);
+ p = x[0];
+ if (mpfr_cmp_ui (p++, 0) != 0)
+ {
+ printf ("Error in mpfr_cmp_ui macro: result should be 0.\n");
+ exit (1);
+ }
+ if (p != x[1])
+ {
+ printf ("Error in mpfr_cmp_ui macro: p - x[0] = %d (expecting 1)\n",
+ (int) (p - x[0]));
+ exit (1);
+ }
+ p = x[0];
+ if (mpfr_cmp_si (p++, 0) != 0)
+ {
+ printf ("Error in mpfr_cmp_si macro: result should be 0.\n");
+ exit (1);
+ }
+ if (p != x[1])
+ {
+ printf ("Error in mpfr_cmp_si macro: p - x[0] = %d (expecting 1)\n",
+ (int) (p - x[0]));
+ exit (1);
+ }
+ mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0);
+}
+
+int
+main (void)
+{
+ mpfr_t x;
+ unsigned long i;
+ long s;
+
+ tests_start_mpfr ();
+
+ mpfr_init(x);
+
+ /* tests for cmp_ui */
+ mpfr_set_ui (x, 3, MPFR_RNDZ);
+ if ((mpfr_cmp_ui) (x, i = 3) != 0)
+ {
+ printf ("Error in mpfr_cmp_ui(3.0, 3)\n");
+ exit (1);
+ }
+ if (mpfr_cmp_ui (x, i = 2) <= 0)
+ {
+ printf ("Error in mpfr_cmp_ui(3.0,2)\n");
+ exit (1);
+ }
+ if (mpfr_cmp_ui (x, i = 4) >= 0)
+ {
+ printf ("Error in mpfr_cmp_ui(3.0,4)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_neg (x, x, MPFR_RNDZ);
+ if (mpfr_cmp_ui (x, i = 0))
+ {
+ printf ("Error in mpfr_cmp_ui(0.0,0)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 1, MPFR_RNDZ);
+ if (mpfr_cmp_ui (x, i = 0) == 0)
+ {
+ printf ("Error in mpfr_cmp_ui(1.0,0)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ if (mpfr_cmp_ui (x, 1) <= 0)
+ {
+ printf ("Error in mpfr_cmp_ui (Inf, 0)\n");
+ exit (1);
+ }
+ mpfr_set_inf (x, -1);
+ if (mpfr_cmp_ui (x, 1) >= 0)
+ {
+ printf ("Error in mpfr_cmp_ui (-Inf, 0)\n");
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 1) < 0);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) < 0);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) > 0);
+
+ /* tests for cmp_si */
+ (mpfr_set_si) (x, -3, MPFR_RNDZ);
+ if ((mpfr_cmp_si) (x, s = -3) != 0)
+ {
+ printf ("Error in mpfr_cmp_si(-3.0,-3)\n");
+ exit (1);
+ }
+ if (mpfr_cmp_si (x, s = -4) <= 0)
+ {
+ printf ("Error in mpfr_cmp_si(-3.0,-4)\n");
+ exit (1);
+ }
+ if (mpfr_cmp_si (x, s = 1) >= 0)
+ {
+ printf ("Error in mpfr_cmp_si(-3.0,1)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ if (mpfr_cmp_si (x, -1) <= 0)
+ {
+ printf ("Error in mpfr_cmp_si (Inf, 0)\n");
+ exit (1);
+ }
+ mpfr_set_inf (x, -1);
+ if (mpfr_cmp_si (x, -1) >= 0)
+ {
+ printf ("Error in mpfr_cmp_si (-Inf, 0)\n");
+ exit (1);
+ }
+
+ /* case b=0 */
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ MPFR_ASSERTN(mpfr_cmp_si (x, 0) == 0);
+ MPFR_ASSERTN(mpfr_cmp_si (x, 1) < 0);
+ MPFR_ASSERTN(mpfr_cmp_si (x, -1) > 0);
+
+ /* case i=0 */
+ mpfr_set_ui (x, 1, MPFR_RNDZ);
+ MPFR_ASSERTN(mpfr_cmp_si (x, 0) > 0);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ MPFR_ASSERTN(mpfr_cmp_si (x, 0) == 0);
+ mpfr_neg (x, x, MPFR_RNDZ);
+ MPFR_ASSERTN(mpfr_cmp_si (x, 0) == 0);
+ mpfr_set_si (x, -1, MPFR_RNDZ);
+ MPFR_ASSERTN(mpfr_cmp_si (x, 0) < 0);
+
+ /* case large x */
+ mpfr_set_str_binary (x, "1E100");
+ MPFR_ASSERTN(mpfr_cmp_si (x, 0) > 0);
+ MPFR_ASSERTN(mpfr_cmp_si (x, 1) > 0);
+ MPFR_ASSERTN(mpfr_cmp_si (x, -1) > 0);
+ mpfr_set_str_binary (x, "-1E100");
+ MPFR_ASSERTN(mpfr_cmp_si (x, 0) < 0);
+ MPFR_ASSERTN(mpfr_cmp_si (x, 1) < 0);
+ MPFR_ASSERTN(mpfr_cmp_si (x, -1) < 0);
+
+ /* corner case */
+ mpfr_set_ui (x, 1, MPFR_RNDZ);
+ mpfr_mul_2exp (x, x, GMP_NUMB_BITS - 1, MPFR_RNDZ);
+ /* now EXP(x)=GMP_NUMB_BITS */
+ MPFR_ASSERTN(mpfr_cmp_si (x, 1) > 0);
+
+ mpfr_clear (x);
+
+ check_nan ();
+ check_macros ();
+ test_macros ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tcmpabs.c b/mpfr/tests/tcmpabs.c
new file mode 100644
index 0000000000..6e1f7292c5
--- /dev/null
+++ b/mpfr/tests/tcmpabs.c
@@ -0,0 +1,149 @@
+/* Test file for mpfr_cmpabs.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define ERROR(s) do { printf(s); exit(1); } while (0)
+
+int
+main (void)
+{
+ mpfr_t xx, yy;
+ int c;
+
+ tests_start_mpfr ();
+
+ mpfr_init2 (xx, 2);
+ mpfr_init2 (yy, 2);
+
+ mpfr_clear_erangeflag ();
+ MPFR_SET_NAN (xx);
+ MPFR_SET_NAN (yy);
+ if (mpfr_cmpabs (xx, yy) != 0)
+ ERROR ("mpfr_cmpabs (NAN,NAN) returns non-zero\n");
+ if (!mpfr_erangeflag_p ())
+ ERROR ("mpfr_cmpabs (NAN,NAN) doesn't set erange flag\n");
+
+ mpfr_set_str_binary (xx, "0.10E0");
+ mpfr_set_str_binary (yy, "-0.10E0");
+ if (mpfr_cmpabs (xx, yy) != 0)
+ ERROR ("mpfr_cmpabs (xx, yy) returns non-zero for prec=2\n");
+
+ mpfr_set_prec (xx, 65);
+ mpfr_set_prec (yy, 65);
+ mpfr_set_str_binary (xx, "-0.10011010101000110101010000000011001001001110001011101011111011101E623");
+ mpfr_set_str_binary (yy, "0.10011010101000110101010000000011001001001110001011101011111011100E623");
+ if (mpfr_cmpabs (xx, yy) <= 0)
+ ERROR ("Error (1) in mpfr_cmpabs\n");
+
+ mpfr_set_str_binary (xx, "-0.10100010001110110111000010001000010011111101000100011101000011100");
+ mpfr_set_str_binary (yy, "-0.10100010001110110111000010001000010011111101000100011101000011011");
+ if (mpfr_cmpabs (xx, yy) <= 0)
+ ERROR ("Error (2) in mpfr_cmpabs\n");
+
+ mpfr_set_prec (xx, 160);
+ mpfr_set_prec (yy, 160);
+ mpfr_set_str_binary (xx, "0.1E1");
+ mpfr_set_str_binary (yy, "-0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100");
+ if (mpfr_cmpabs (xx, yy) <= 0)
+ ERROR ("Error (3) in mpfr_cmpabs\n");
+
+ mpfr_set_prec(xx, 53);
+ mpfr_set_prec(yy, 200);
+ mpfr_set_ui (xx, 1, (mpfr_rnd_t) 0);
+ mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0);
+ if (mpfr_cmpabs(xx, yy) != 0)
+ ERROR ("Error in mpfr_cmpabs: 1.0 != 1.0\n");
+
+ mpfr_set_prec (yy, 31);
+ mpfr_set_str (xx, "-1.0000000002", 10, (mpfr_rnd_t) 0);
+ mpfr_set_ui (yy, 1, (mpfr_rnd_t) 0);
+ if (!(mpfr_cmpabs(xx,yy)>0))
+ ERROR ("Error in mpfr_cmpabs: not 1.0000000002 > 1.0\n");
+ mpfr_set_prec(yy, 53);
+
+ mpfr_set_ui(xx, 0, MPFR_RNDN);
+ mpfr_set_str (yy, "-0.1", 10, MPFR_RNDN);
+ if (mpfr_cmpabs(xx, yy) >= 0)
+ ERROR ("Error in mpfr_cmpabs(0.0, 0.1)\n");
+
+ mpfr_set_inf (xx, -1);
+ mpfr_set_str (yy, "23489745.0329", 10, MPFR_RNDN);
+ if (mpfr_cmpabs(xx, yy) <= 0)
+ ERROR ("Error in mpfr_cmp(-Inf, 23489745.0329)\n");
+
+ mpfr_set_inf (xx, 1);
+ mpfr_set_inf (yy, -1);
+ if (mpfr_cmpabs(xx, yy) != 0)
+ ERROR ("Error in mpfr_cmpabs(Inf, -Inf)\n");
+
+ mpfr_set_inf (yy, -1);
+ mpfr_set_str (xx, "2346.09234", 10, MPFR_RNDN);
+ if (mpfr_cmpabs (xx, yy) >= 0)
+ ERROR ("Error in mpfr_cmpabs(-Inf, 2346.09234)\n");
+
+ mpfr_set_prec (xx, 2);
+ mpfr_set_prec (yy, 128);
+ mpfr_set_str_binary (xx, "0.1E10");
+ mpfr_set_str_binary (yy,
+ "0.100000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000001E10");
+ if (mpfr_cmpabs (xx, yy) >= 0)
+ ERROR ("Error in mpfr_cmpabs(10.235, 2346.09234)\n");
+ mpfr_swap (xx, yy);
+ if (mpfr_cmpabs(xx, yy) <= 0)
+ ERROR ("Error in mpfr_cmpabs(2346.09234, 10.235)\n");
+ mpfr_swap (xx, yy);
+
+ /* Check for NAN */
+ mpfr_set_nan (xx);
+ mpfr_clear_erangeflag ();
+ c = (mpfr_cmp) (xx, yy);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (1)\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = (mpfr_cmp) (yy, xx);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (2)\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = (mpfr_cmp) (xx, xx);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (3)\n");
+ exit (1);
+ }
+
+ mpfr_clear (xx);
+ mpfr_clear (yy);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcomparisons.c b/mpfr/tests/tcomparisons.c
new file mode 100644
index 0000000000..937633a2d7
--- /dev/null
+++ b/mpfr/tests/tcomparisons.c
@@ -0,0 +1,131 @@
+/* Test file for mpfr_greater_p, mpfr_greaterequal_p, mpfr_less_p,
+ mpfr_lessequal_p, mpfr_lessgreater_p, mpfr_equal_p, mpfr_unordered_p
+ functions.
+
+Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+cmp_tests (void)
+{
+ mpfr_t x, y;
+ long i;
+
+ mpfr_inits (x, y, (mpfr_ptr) 0);
+ for (i = 0; i < 80000; i++)
+ {
+ mpfr_prec_t precx, precy;
+ int signx, signy, cmp;
+ unsigned int cmpbool = 0;
+
+ precx = (randlimb () % 17) * 11 + MPFR_PREC_MIN;
+ precy = (randlimb () % 17) * 11 + MPFR_PREC_MIN;
+ mpfr_set_prec (x, precx);
+ mpfr_set_prec (y, precy);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (y, RANDS);
+ signx = randlimb () & 1;
+ signy = randlimb () % 256 ? signx : 1 - signx;
+ /* signy = signx most of the time (most interesting case) */
+ if (signx)
+ mpfr_neg (x, x, MPFR_RNDN);
+ if (signy)
+ mpfr_neg (y, y, MPFR_RNDN);
+ if (i <= 1)
+ mpfr_set_nan (x);
+ if (i == 0 || i == 2)
+ mpfr_set_nan (y);
+ if (mpfr_greater_p (x, y))
+ cmpbool |= 0x01;
+ if (mpfr_greaterequal_p (x, y))
+ cmpbool |= 0x02;
+ if (mpfr_less_p (x, y))
+ cmpbool |= 0x04;
+ if (mpfr_lessequal_p (x, y))
+ cmpbool |= 0x08;
+ if (mpfr_lessgreater_p (x, y))
+ cmpbool |= 0x10;
+ if (mpfr_equal_p (x, y))
+ cmpbool |= 0x20;
+ if (mpfr_unordered_p (x, y))
+ cmpbool |= 0x40;
+ if ((i <= 2 && cmpbool != 0x40) ||
+ (i > 2 && (cmp = mpfr_cmp (x, y),
+ (cmp == 0 && cmpbool != 0x2a) ||
+ (cmp < 0 && cmpbool != 0x1c) ||
+ (cmp > 0 && cmpbool != 0x13))))
+ {
+ printf ("Error in cmp_tests for\nx = ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf (" and\ny = ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+static void
+eq_tests (void)
+{
+ mpfr_t x, y;
+ long i;
+
+ mpfr_inits (x, y, (mpfr_ptr) 0);
+ for (i = 0; i < 20000; i++)
+ {
+ mpfr_prec_t precx;
+
+ precx = (randlimb () % 17) * 11 + MPFR_PREC_MIN;
+ mpfr_set_prec (x, precx);
+ mpfr_set_prec (y, precx + (randlimb () % 64));
+ mpfr_urandomb (x, RANDS);
+ if (randlimb () & 1)
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_set (y, x, MPFR_RNDN); /* exact -> x = y */
+ if (mpfr_greater_p (x, y) || !mpfr_greaterequal_p (x, y) ||
+ mpfr_less_p (x, y) || !mpfr_lessequal_p (x, y) ||
+ mpfr_lessgreater_p (x, y) || !mpfr_equal_p (x, y) ||
+ mpfr_unordered_p (x, y))
+ {
+ printf ("Error in eq_tests for x = ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+ cmp_tests ();
+ eq_tests ();
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tconst_catalan.c b/mpfr/tests/tconst_catalan.c
new file mode 100644
index 0000000000..4b6f280679
--- /dev/null
+++ b/mpfr/tests/tconst_catalan.c
@@ -0,0 +1,59 @@
+/* Test file for mpfr_const_catalan.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpfr-test.h"
+
+/* Wrapper for tgeneric */
+static int
+my_const_catalan (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r)
+{
+ return mpfr_const_catalan (x, r);
+}
+
+#define RAND_FUNCTION(x) mpfr_set_ui(x,0,MPFR_RNDN)
+#define TEST_FUNCTION my_const_catalan
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x;
+
+ tests_start_mpfr ();
+
+ mpfr_init2 (x, 32);
+ (mpfr_const_catalan) (x, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, 32, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 3934042271UL))
+ {
+ printf ("Error in const_catalan for prec=32\n");
+ exit (1);
+ }
+ mpfr_clear (x);
+
+ test_generic (2, 200, 1);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tconst_euler.c b/mpfr/tests/tconst_euler.c
new file mode 100644
index 0000000000..179b41700f
--- /dev/null
+++ b/mpfr/tests/tconst_euler.c
@@ -0,0 +1,116 @@
+/* Test file for mpfr_const_euler.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* Wrapper for tgeneric */
+static int
+my_const_euler (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r)
+{
+ return mpfr_const_euler (x, r);
+}
+
+#define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN)
+#define TEST_FUNCTION my_const_euler
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t gamma, y, z, t;
+ unsigned int err, prec, yprec, p0 = 2, p1 = 200;
+ int rnd;
+
+ tests_start_mpfr ();
+
+ prec = (argc < 2) ? 53 : atoi(argv[1]);
+
+ if (argc > 1)
+ {
+ mpfr_init2 (gamma, prec);
+ mpfr_const_euler (gamma, MPFR_RNDN);
+ printf("gamma="); mpfr_out_str (stdout, 10, 0, gamma, MPFR_RNDD);
+ puts ("");
+ mpfr_clear (gamma);
+ return 0;
+ }
+
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (t);
+
+ mpfr_set_prec (y, 32);
+ mpfr_set_prec (z, 32);
+ (mpfr_const_euler) (y, MPFR_RNDN);
+ mpfr_set_str_binary (z, "0.10010011110001000110011111100011");
+ if (mpfr_cmp (y, z))
+ {
+ printf ("Error for prec=32\n");
+ exit (1);
+ }
+
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (z, prec);
+ mpfr_set_prec (t, prec);
+ yprec = prec + 10;
+
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ mpfr_set_prec (y, yprec);
+ mpfr_const_euler (y, (mpfr_rnd_t) rnd);
+ err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec;
+ if (mpfr_can_round (y, err, (mpfr_rnd_t) rnd, (mpfr_rnd_t) rnd, prec))
+ {
+ mpfr_set (t, y, (mpfr_rnd_t) rnd);
+ mpfr_const_euler (z, (mpfr_rnd_t) rnd);
+ if (mpfr_cmp (t, z))
+ {
+ printf ("results differ for prec=%u rnd_mode=%s\n", prec,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf (" got ");
+ mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
+ puts ("");
+ printf (" expected ");
+ mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
+ puts ("");
+ printf (" approximation was ");
+ mpfr_print_binary (y);
+ puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+
+ test_generic (2, 200, 1);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tconst_log2.c b/mpfr/tests/tconst_log2.c
new file mode 100644
index 0000000000..958a22c9fa
--- /dev/null
+++ b/mpfr/tests/tconst_log2.c
@@ -0,0 +1,201 @@
+/* Test file for mpfr_const_log2.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* tlog2 [prec] [rnd] [0 = no print] */
+
+static void
+check (mpfr_prec_t p0, mpfr_prec_t p1)
+{
+ mpfr_t x, y, z;
+ mpfr_rnd_t rnd;
+ int dif;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init2 (z, p1 + 10);
+ mpfr_const_log2 (z, MPFR_RNDN);
+ mpfr_clear_cache (__gmpfr_cache_const_log2);
+
+ for (; p0<=p1; p0++)
+ {
+ mpfr_set_prec (x, p0);
+ mpfr_set_prec (y, p0);
+ {
+ rnd = RND_RAND ();
+ mpfr_const_log2 (x, rnd);
+ mpfr_set (y, z, rnd);
+ if ((dif = mpfr_cmp (x, y))
+ && mpfr_can_round (z, mpfr_get_prec(z), MPFR_RNDN,
+ rnd, p0))
+ {
+ printf ("mpfr_const_log2 fails for prec=%u, rnd=%s Diff=%d\n",
+ (unsigned int) p0, mpfr_print_rnd_mode (rnd), dif);
+ printf ("expected "), mpfr_dump (y);
+ printf ("got "), mpfr_dump (x);
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+check_large (void)
+{
+ mpfr_t x, y;
+ mpfr_init2 (x, 25000);
+ mpfr_init2 (y, 26000);
+ (mpfr_const_log2) (x, MPFR_RNDN); /* First one ! */
+ (mpfr_const_log2) (y, MPFR_RNDN); /* Then the other - cache - */
+ mpfr_prec_round (y, 25000, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("const_log2: error for large prec\n");
+ exit (1);
+ }
+
+ /* worst-case with 15 successive ones after last bit,
+ to exercise can_round loop */
+ mpfr_set_prec (x, 26249);
+ mpfr_const_log2 (x, MPFR_RNDZ);
+
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+static void
+check_cache (void)
+{
+ mpfr_t x;
+ int i;
+
+ mpfr_init2 (x, 195);
+ mpfr_free_cache ();
+ i = mpfr_const_log2 (x, MPFR_RNDN);
+ if (i == 0)
+ {
+ printf("Error for log2. Invalid ternary value (1).\n");
+ exit (1);
+ }
+ mpfr_set_prec (x, 194);
+ i = mpfr_const_log2 (x, MPFR_RNDN);
+ if (i == 0)
+ {
+ printf("Error for log2. Invalid ternary value (2).\n");
+ exit (1);
+ }
+
+ mpfr_free_cache ();
+ mpfr_set_prec (x, 9);
+ mpfr_const_log2 (x, MPFR_RNDN);
+ mpfr_set_prec (x, 8);
+ mpfr_const_log2 (x, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "0.10110001E0", 2, MPFR_RNDN))
+ {
+ printf("Error for log2. Wrong rounding.\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+}
+
+/* Wrapper for tgeneric */
+static int
+my_const_log2 (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r)
+{
+ return mpfr_const_log2 (x, r);
+}
+
+#define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN)
+#define TEST_FUNCTION my_const_log2
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x;
+ int p;
+ mpfr_rnd_t rnd;
+
+ tests_start_mpfr ();
+
+ p = (argc>1) ? atoi(argv[1]) : 53;
+ rnd = (argc>2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDZ;
+
+ mpfr_init (x);
+
+ check (2, 1000);
+
+ /* check precision of 2 bits */
+ mpfr_set_prec (x, 2);
+ mpfr_const_log2 (x, MPFR_RNDN);
+ if (mpfr_cmp_ui_2exp(x, 3, -2)) /* 3*2^-2 */
+ {
+ printf ("mpfr_const_log2 failed for prec=2, rnd=MPFR_RNDN\n"
+ "expected 0.75, got ");
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
+ putchar('\n');
+ exit (1);
+ }
+
+ if (argc>=2)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_const_log2 (x, rnd);
+ printf ("log(2)=");
+ mpfr_out_str (stdout, 10, 0, x, rnd);
+ puts ("");
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_const_log2 (x, MPFR_RNDZ);
+ if (mpfr_cmp_str1 (x, "6.9314718055994530941e-1") )
+ {
+ printf ("mpfr_const_log2 failed for prec=53\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_const_log2 (x, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, "0.69314718060195446"))
+ {
+ printf ("mpfr_const_log2 failed for prec=32\n");
+ exit (1);
+ }
+
+ mpfr_clear(x);
+
+ check_large();
+ check_cache ();
+
+ test_generic (2, 200, 1);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tconst_pi.c b/mpfr/tests/tconst_pi.c
new file mode 100644
index 0000000000..50188f4365
--- /dev/null
+++ b/mpfr/tests/tconst_pi.c
@@ -0,0 +1,186 @@
+/* Test file for mpfr_const_pi.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* tconst_pi [prec] [rnd] [0 = no print] */
+
+static void
+check_large (void)
+{
+ mpfr_t x, y, z;
+
+ mpfr_init2 (x, 20000);
+ mpfr_init2 (y, 21000);
+ mpfr_init2 (z, 11791);
+
+ /* The algo failed to round for p=11791. */
+ (mpfr_const_pi) (z, MPFR_RNDU);
+ mpfr_const_pi (x, MPFR_RNDN); /* First one ! */
+ mpfr_const_pi (y, MPFR_RNDN); /* Then the other - cache - */
+ mpfr_prec_round (y, 20000, MPFR_RNDN);
+ if (mpfr_cmp (x, y)) {
+ printf ("const_pi: error for large prec (%d)\n", 1);
+ exit (1);
+ }
+ mpfr_prec_round (y, 11791, MPFR_RNDU);
+ if (mpfr_cmp (z, y)) {
+ printf ("const_pi: error for large prec (%d)\n", 2);
+ exit (1);
+ }
+
+ /* a worst-case to exercise recomputation */
+ if (MPFR_PREC_MAX > 33440) {
+ mpfr_set_prec (x, 33440);
+ mpfr_const_pi (x, MPFR_RNDZ);
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+/* Wrapper for tgeneric */
+static int
+my_const_pi (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r)
+{
+ return mpfr_const_pi (x, r);
+}
+
+#define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN)
+#define TEST_FUNCTION my_const_pi
+#include "tgeneric.c"
+
+static void
+bug20091030 (void)
+{
+ mpfr_t x, x_ref;
+ int inex, inex_ref;
+ mpfr_prec_t p;
+ int r;
+
+ mpfr_free_cache ();
+ mpfr_init2 (x, MPFR_PREC_MIN);
+ for (p = MPFR_PREC_MIN; p <= 100; p++)
+ {
+ mpfr_set_prec (x, p);
+ inex = mpfr_const_pi (x, MPFR_RNDU);
+ if (inex < 0)
+ {
+ printf ("Error, inex < 0 for RNDU (prec=%lu)\n",
+ (unsigned long) p);
+ exit (1);
+ }
+ inex = mpfr_const_pi (x, MPFR_RNDD);
+ if (inex > 0)
+ {
+ printf ("Error, inex > 0 for RNDD (prec=%lu)\n",
+ (unsigned long) p);
+ exit (1);
+ }
+ }
+ mpfr_free_cache ();
+ mpfr_init2 (x_ref, MPFR_PREC_MIN);
+ for (p = MPFR_PREC_MIN; p <= 100; p++)
+ {
+ mpfr_set_prec (x, p + 10);
+ mpfr_const_pi (x, MPFR_RNDN);
+ mpfr_set_prec (x, p);
+ mpfr_set_prec (x_ref, p);
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ inex = mpfr_const_pi (x, (mpfr_rnd_t) r);
+ inex_ref = mpfr_const_pi_internal (x_ref, (mpfr_rnd_t) r);
+ if (inex != inex_ref || mpfr_cmp (x, x_ref) != 0)
+ {
+ printf ("mpfr_const_pi and mpfr_const_pi_internal disagree\n");
+ printf ("mpfr_const_pi gives ");
+ mpfr_dump (x);
+ printf ("mpfr_const_pi_internal gives ");
+ mpfr_dump (x_ref);
+ printf ("inex=%d inex_ref=%d\n", inex, inex_ref);
+ exit (1);
+ }
+ }
+ }
+ mpfr_clear (x);
+ mpfr_clear (x_ref);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x;
+ mpfr_prec_t p;
+ mpfr_rnd_t rnd;
+
+ tests_start_mpfr ();
+
+ p = 53;
+ if (argc > 1)
+ {
+ long a = atol (argv[1]);
+ if (a >= MPFR_PREC_MIN && a <= MPFR_PREC_MAX)
+ p = a;
+ }
+
+ rnd = (argc > 2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDZ;
+
+ mpfr_init2 (x, p);
+ mpfr_const_pi (x, rnd);
+ if (argc >= 2)
+ {
+ if (argc < 4 || atoi (argv[3]) != 0)
+ {
+ printf ("Pi=");
+ mpfr_out_str (stdout, 10, 0, x, rnd);
+ puts ("");
+ }
+ }
+ else if (mpfr_cmp_str1 (x, "3.141592653589793116") )
+ {
+ printf ("mpfr_const_pi failed for prec=53\n");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar('\n');
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_const_pi (x, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, "3.141592653468251") )
+ {
+ printf ("mpfr_const_pi failed for prec=32\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+
+ bug20091030 ();
+
+ check_large ();
+
+ test_generic (2, 200, 1);
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tcopysign.c b/mpfr/tests/tcopysign.c
new file mode 100644
index 0000000000..4c2ffee6b1
--- /dev/null
+++ b/mpfr/tests/tcopysign.c
@@ -0,0 +1,116 @@
+/* Test file for mpfr_copysign, mpfr_setsign and mpfr_signbit.
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+copysign_variant (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y,
+ mpfr_rnd_t rnd_mode, int k)
+{
+ mpfr_clear_flags ();
+ switch (k)
+ {
+ case 0:
+ mpfr_copysign (z, x, y, MPFR_RNDN);
+ return;
+ case 1:
+ (mpfr_copysign) (z, x, y, MPFR_RNDN);
+ return;
+ case 2:
+ mpfr_setsign (z, x, mpfr_signbit (y), MPFR_RNDN);
+ return;
+ case 3:
+ mpfr_setsign (z, x, (mpfr_signbit) (y), MPFR_RNDN);
+ return;
+ case 4:
+ (mpfr_setsign) (z, x, mpfr_signbit (y), MPFR_RNDN);
+ return;
+ case 5:
+ (mpfr_setsign) (z, x, (mpfr_signbit) (y), MPFR_RNDN);
+ return;
+ }
+}
+
+int
+main (void)
+{
+ mpfr_t x, y, z;
+ int i, j, k;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ for (i = 0; i <= 1; i++)
+ for (j = 0; j <= 1; j++)
+ for (k = 0; k <= 5; k++)
+ {
+ mpfr_set_nan (x);
+ i ? MPFR_SET_NEG (x) : MPFR_SET_POS (x);
+ mpfr_set_nan (y);
+ j ? MPFR_SET_NEG (y) : MPFR_SET_POS (y);
+ copysign_variant (z, x, y, MPFR_RNDN, k);
+ if (MPFR_SIGN (z) != MPFR_SIGN (y) || !mpfr_nanflag_p ())
+ {
+ printf ("Error in mpfr_copysign (%cNaN, %cNaN)\n",
+ i ? '-' : '+', j ? '-' : '+');
+ exit (1);
+ }
+
+ mpfr_set_si (x, i ? -1250 : 1250, MPFR_RNDN);
+ mpfr_set_nan (y);
+ j ? MPFR_SET_NEG (y) : MPFR_SET_POS (y);
+ copysign_variant (z, x, y, MPFR_RNDN, k);
+ if (i != j)
+ mpfr_neg (x, x, MPFR_RNDN);
+ if (! mpfr_equal_p (z, x) || mpfr_nanflag_p ())
+ {
+ printf ("Error in mpfr_copysign (%c1250, %cNaN)\n",
+ i ? '-' : '+', j ? '-' : '+');
+ exit (1);
+ }
+
+ mpfr_set_si (x, i ? -1250 : 1250, MPFR_RNDN);
+ mpfr_set_si (y, j ? -1717 : 1717, MPFR_RNDN);
+ copysign_variant (z, x, y, MPFR_RNDN, k);
+ if (i != j)
+ mpfr_neg (x, x, MPFR_RNDN);
+ if (! mpfr_equal_p (z, x) || mpfr_nanflag_p ())
+ {
+ printf ("Error in mpfr_copysign (%c1250, %c1717)\n",
+ i ? '-' : '+', j ? '-' : '+');
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcos.c b/mpfr/tests/tcos.c
new file mode 100644
index 0000000000..2ad313f127
--- /dev/null
+++ b/mpfr/tests/tcos.c
@@ -0,0 +1,383 @@
+/* Test file for mpfr_cos.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_cos (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ }
+ res = mpfr_cos (a, b, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_cos mpfr_cos
+#endif
+
+static void
+check53 (const char *xs, const char *cos_xs, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xx, c;
+
+ mpfr_inits2 (53, xx, c, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs); /* should be exact */
+ test_cos (c, xx, rnd_mode);
+ if (mpfr_cmp_str1 (c, cos_xs))
+ {
+ printf ("mpfr_cos failed for x=%s, rnd=%s\n",
+ xs, mpfr_print_rnd_mode (rnd_mode));
+ printf ("mpfr_cos gives cos(x)=");
+ mpfr_out_str(stdout, 10, 0, c, MPFR_RNDN);
+ printf(", expected %s\n", cos_xs);
+ exit (1);
+ }
+ mpfr_clears (xx, c, (mpfr_ptr) 0);
+}
+
+#define TEST_FUNCTION test_cos
+#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
+#include "tgeneric.c"
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ test_cos (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: cos(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ test_cos (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: cos(Inf) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ test_cos (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: cos(-Inf) != NaN\n");
+ exit (1);
+ }
+
+ /* cos(+/-0) = 1 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ test_cos (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error: cos(+0) != 1\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ test_cos (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error: cos(-0) != 1\n");
+ exit (1);
+ }
+
+ /* Compute ~Pi/2 to check */
+ /* FIXME: Too slow!
+ mpfr_set_prec (x, 20000);
+ mpfr_const_pi (x, MPFR_RNDD); mpfr_div_2ui (x, x, 1, MPFR_RNDN);
+ mpfr_set_prec (y, 24);
+ test_cos (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "0.111001010110100011000001E-20000", 2, MPFR_RNDN))
+ {
+ printf("Error computing cos(~Pi/2)\n");
+ mpfr_dump (y);
+ exit (1);
+ } */
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+special_overflow (void)
+{
+ mpfr_t x, y;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 73);
+
+ /* Check special case: An overflow in const_pi could occurs! */
+ set_emin (-125);
+ set_emax (128);
+ mpfr_set_str_binary (x, "0.111101010110110011101101E6");
+ test_cos (y, x, MPFR_RNDZ);
+ set_emin (emin);
+ set_emax (emax);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+overflowed_cos0 (void)
+{
+ mpfr_t x, y;
+ int emax, i, inex, rnd, err = 0;
+ mpfr_exp_t old_emax;
+
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ for (emax = -1; emax <= 0; emax++)
+ {
+ mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
+ mpfr_nextbelow (y);
+ set_emax (emax); /* 1 is not representable. */
+ /* and if emax < 0, 1 - eps is not representable either. */
+ for (i = -1; i <= 1; i++)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_cos (x, x, (mpfr_rnd_t) rnd);
+ if ((i == 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
+ ! mpfr_overflow_p ())
+ {
+ printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n"
+ " The overflow flag is not set.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ {
+ if (inex >= 0)
+ {
+ printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (x, y))
+ {
+ printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of 0.11111111E%d.\n", emax);
+ err = 1;
+ }
+ }
+ else
+ {
+ if (inex <= 0)
+ {
+ printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
+ {
+ printf ("Error in overflowed_cos0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of +Inf.\n");
+ err = 1;
+ }
+ }
+ }
+ set_emax (old_emax);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+bug20091030 (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 5);
+ mpfr_init2 (y, 2);
+ mpfr_set_str (x, "-0.11001E3", 2, MPFR_RNDN);
+ mpfr_cos (y, x, MPFR_RNDN);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ int inex;
+
+ tests_start_mpfr ();
+
+ special_overflow ();
+ check_nans ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 2);
+ mpfr_set_str (x, "9.81333845856942e-1", 10, MPFR_RNDN);
+ test_cos (y, x, MPFR_RNDN);
+
+ mpfr_set_prec (x, 30);
+ mpfr_set_prec (y, 30);
+ mpfr_set_str_binary (x, "1.00001010001101110010100010101e-1");
+ test_cos (y, x, MPFR_RNDU);
+ mpfr_set_str_binary (x, "1.10111100010101011110101010100e-1");
+ if (mpfr_cmp (y, x))
+ {
+ printf ("Error for prec=30, rnd=MPFR_RNDU\n");
+ printf ("expected "); mpfr_print_binary (x); puts ("");
+ printf (" got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 59);
+ mpfr_set_prec (y, 59);
+ mpfr_set_str_binary (x, "1.01101011101111010011111110111111111011011101100111100011e-3");
+ test_cos (y, x, MPFR_RNDU);
+ mpfr_set_str_binary (x, "1.1111011111110010001001001011100111101110100010000010010011e-1");
+ if (mpfr_cmp (y, x))
+ {
+ printf ("Error for prec=59, rnd=MPFR_RNDU\n");
+ printf ("expected "); mpfr_print_binary (x); puts ("");
+ printf (" got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 5);
+ mpfr_set_prec (y, 5);
+ mpfr_set_str_binary (x, "1.1100e-2");
+ test_cos (y, x, MPFR_RNDD);
+ mpfr_set_str_binary (x, "1.1100e-1");
+ if (mpfr_cmp (y, x))
+ {
+ printf ("Error for x=1.1100e-2, rnd=MPFR_RNDD\n");
+ printf ("expected 1.1100e-1, got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+
+ mpfr_set_str_binary (x, "0.10001000001001011000100001E-6");
+ mpfr_set_str_binary (y, "0.1111111111111101101111001100001");
+ test_cos (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for prec=32 (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "-0.1101011110111100111010011001011E-1");
+ mpfr_set_str_binary (y, "0.11101001100110111011011010100011");
+ test_cos (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for prec=32 (2)\n");
+ exit (1);
+ }
+
+ /* huge argument reduction */
+ mpfr_set_str_binary (x, "0.10000010000001101011101111001011E40");
+ mpfr_set_str_binary (y, "0.10011000001111010000101011001011E-1");
+ test_cos (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for prec=32 (3)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_prec (y, 3);
+ mpfr_set_str_binary (x, "0.110E60");
+ inex = mpfr_cos (y, x, MPFR_RNDD);
+ MPFR_ASSERTN(inex < 0);
+
+ /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */
+ check53 ("4.984987858808754279e-1", "8.783012931285841817e-1", MPFR_RNDN);
+ check53 ("4.984987858808754279e-1", "8.783012931285840707e-1", MPFR_RNDD);
+ check53 ("4.984987858808754279e-1", "8.783012931285840707e-1", MPFR_RNDZ);
+ check53 ("4.984987858808754279e-1", "8.783012931285841817e-1", MPFR_RNDU);
+ check53 ("1.00031274099908640274", "0.540039116973283217504", MPFR_RNDN);
+ check53 ("1.00229256850978698523", "0.538371757797526551137", MPFR_RNDZ);
+ check53 ("1.00288304857059840103", "0.537874062022526966409", MPFR_RNDZ);
+ check53 ("1.00591265847407274059", "0.53531755997839769456", MPFR_RNDN);
+
+ check53 ("1.00591265847407274059", "0.53531755997839769456", MPFR_RNDN);
+
+ overflowed_cos0 ();
+ test_generic (2, 100, 15);
+
+ /* check inexact flag */
+ mpfr_set_prec (x, 3);
+ mpfr_set_prec (y, 13);
+ mpfr_set_str_binary (x, "-0.100E196");
+ inex = mpfr_cos (y, x, MPFR_RNDU);
+ mpfr_set_prec (x, 13);
+ mpfr_set_str_binary (x, "0.1111111100101");
+ MPFR_ASSERTN (inex > 0 && mpfr_equal_p (x, y));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ bug20091030 ();
+
+ data_check ("data/cos", mpfr_cos, "mpfr_cos");
+ bad_cases (mpfr_cos, mpfr_acos, "mpfr_cos", 256, -40, 0, 4, 128, 800, 50);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcosh.c b/mpfr/tests/tcosh.c
new file mode 100644
index 0000000000..f9a70a157e
--- /dev/null
+++ b/mpfr/tests/tcosh.c
@@ -0,0 +1,204 @@
+/* Test file for mpfr_cosh.
+
+Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_cosh
+#define TEST_RANDOM_EMIN -36
+#define TEST_RANDOM_EMAX 36
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int i;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_nan (x);
+ mpfr_cosh (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: cosh(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_cosh (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: cosh(+Inf) != +Inf\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_cosh (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: cosh(-Inf) != +Inf\n");
+ exit (1);
+ }
+
+ /* cosh(+/-0) = 1 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_cosh (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error: cosh(+0) != 1\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_cosh (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error: cosh(-0) != 1\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+
+ mpfr_set_str_binary (x, "0.1101110111111111001011101000101");
+ mpfr_set_str_binary (y, "1.0110011001110000101100011001001");
+ mpfr_cosh (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_cosh for prec=32 (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "-0.1110111000011101010111100000101E-1");
+ mpfr_set_str_binary (y, "1.0001110000101111111111100110101");
+ mpfr_cosh (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: mpfr_cosh for prec=32 (2)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "1E1000000000");
+ i = mpfr_cosh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
+ MPFR_ASSERTN (mpfr_overflow_p ());
+ MPFR_ASSERTN (i == 1);
+
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "-1E1000000000");
+ i = mpfr_cosh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
+ MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == 1);
+
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "-1E1000000000");
+ i = mpfr_cosh (x, x, MPFR_RNDD);
+ MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
+ MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == -1);
+
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "-1E1000000000");
+ i = mpfr_cosh (x, x, MPFR_RNDU);
+ MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
+ MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == 1);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+special_overflow (void)
+{
+ /* Check for overflow in 3 cases:
+ 1. cosh(x) is representable, but not exp(x)
+ 2. cosh(x) is not representable in the selected range of exp.
+ 3. cosh(x) exp overflow even with the largest range of exp */
+ mpfr_t x, y;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ set_emin (-125);
+ set_emax (128);
+
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 24);
+
+ mpfr_set_str_binary (x, "0.101100100000000000110100E7");
+ mpfr_cosh (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "0.101010001111001010001110E128", 2, MPFR_RNDN))
+ {
+ printf("Special overflow error 1.\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "0.101100100000000000110100E8");
+ mpfr_cosh (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p(y))
+ {
+ printf("Special overflow error 2.\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ set_emin (emin);
+ set_emax (emax);
+
+ mpfr_set_str_binary (x, "0.101100100000000000110100E1000000");
+ mpfr_cosh (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p(y))
+ {
+ printf("Special overflow error 3.\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special_overflow ();
+ special ();
+
+ test_generic (2, 100, 100);
+
+ data_check ("data/cosh", mpfr_cosh, "mpfr_cosh");
+ bad_cases (mpfr_cosh, mpfr_acosh, "mpfr_cosh", 0, 1, 255, 4, 128, 800, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcot.c b/mpfr/tests/tcot.c
new file mode 100644
index 0000000000..89244743ad
--- /dev/null
+++ b/mpfr/tests/tcot.c
@@ -0,0 +1,144 @@
+/* Test file for mpfr_cot.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_cot
+#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
+#include "tgeneric.c"
+
+static void
+check_specials (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ mpfr_cot (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: cot(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_cot (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: cot(Inf) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_cot (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: cot(-Inf) != NaN\n");
+ exit (1);
+ }
+
+ /* cot(+/-0) = +/-Inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_cot (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && mpfr_sgn (y) > 0))
+ {
+ printf ("Error: cot(+0) != +Inf\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_cot (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0))
+ {
+ printf ("Error: cot(-0) != -Inf\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+two2emin (mpfr_exp_t e)
+{
+ mpfr_exp_t old_emin, old_emax;
+ mpfr_t x, y;
+ int i, rnd;
+
+ old_emin = mpfr_get_emin ();
+ old_emax = mpfr_get_emax ();
+
+ if (mpfr_set_emin (-e) || mpfr_set_emax (e))
+ {
+ printf ("Can't change exponent range\n");
+ exit (1);
+ }
+
+ mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
+ for (i = -4; i <= 4; i++)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si (y, i, MPFR_RNDN);
+ mpfr_ui_div (y, 1, y, (mpfr_rnd_t) rnd); /* no overflow/underflow */
+ mpfr_set_si_2exp (x, i, -e, MPFR_RNDN);
+ if (ABS (i) != 3) /* not a power of 2 (not 0 either) */
+ mpfr_sub (y, y, x, (mpfr_rnd_t) rnd); /* no overflow/underflow */
+ mpfr_set_ui_2exp (x, 1, -e, MPFR_RNDN);
+ mpfr_div (y, y, x, (mpfr_rnd_t) rnd); /* 1/x - SIGN(x).epsilon */
+ mpfr_set_si_2exp (x, i, -e, MPFR_RNDN);
+ mpfr_cot (x, x, (mpfr_rnd_t) rnd);
+ if (! mpfr_equal_p (x, y))
+ {
+ printf ("Error in two2emin for i = %d and rnd = %s\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("Got ");
+ mpfr_dump (x);
+ printf ("instead of ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+
+ mpfr_set_emin (old_emin);
+ mpfr_set_emax (old_emax);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_specials ();
+ two2emin (256);
+ two2emin (MPFR_EMAX_DEFAULT);
+ if (MPFR_EMAX_MAX != MPFR_EMAX_DEFAULT)
+ two2emin (MPFR_EMAX_MAX);
+ test_generic (2, 200, 5);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcoth.c b/mpfr/tests/tcoth.c
new file mode 100644
index 0000000000..70969f6773
--- /dev/null
+++ b/mpfr/tests/tcoth.c
@@ -0,0 +1,213 @@
+/* Test file for mpfr_coth.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_coth
+#include "tgeneric.c"
+
+static void
+check_specials (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ mpfr_coth (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: coth(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_coth (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error: coth(Inf) != 1\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_coth (y, x, MPFR_RNDN);
+ if (mpfr_cmp_si (y, -1))
+ {
+ printf ("Error: coth(-Inf) != -1\n");
+ exit (1);
+ }
+
+ /* coth(+/-0) = +/-Inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_coth (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && MPFR_SIGN (y) > 0))
+ {
+ printf ("Error: coth(+0) != +Inf\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_coth (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && MPFR_SIGN (y) < 0))
+ {
+ printf ("Error: coth(-0) != -Inf\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+check_bugs (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* bug found by Rob (Sisyphus) on 16 Sep 2005 */
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_set_prec (y, 2);
+ mpfr_coth (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error for coth(2), expected 1, got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_str (x, "18.368400284838550", 10, MPFR_RNDN);
+ mpfr_set_str (y, "1.0000000000000002", 10, MPFR_RNDN);
+ mpfr_coth (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for coth(18.368400284838550)\n");
+ exit (1);
+ }
+
+ mpfr_set_str (x, "18.714973875118520", 10, MPFR_RNDN);
+ mpfr_coth (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for coth(18.714973875118520)\n");
+ exit (1);
+ }
+
+ mpfr_set_str (x, "18.714973875118524", 10, MPFR_RNDN);
+ mpfr_coth (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 1) != 0)
+ {
+ printf ("Error for coth(18.714973875118524)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+underflowed_cothinf (void)
+{
+ mpfr_t x, y;
+ int i, inex, rnd, err = 0;
+ mpfr_exp_t old_emin;
+
+ old_emin = mpfr_get_emin ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ for (i = -1; i <= 1; i += 2)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_inf (x, i);
+ mpfr_clear_flags ();
+ set_emin (2); /* 1 is not representable. */
+ inex = mpfr_coth (x, x, (mpfr_rnd_t) rnd);
+ set_emin (old_emin);
+ if (! mpfr_underflow_p ())
+ {
+ printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
+ " The underflow flag is not set.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ mpfr_set_si (y, (i < 0 && (rnd == MPFR_RNDD || rnd == MPFR_RNDA)) ||
+ (i > 0 && (rnd == MPFR_RNDU || rnd == MPFR_RNDA))
+ ? 2 : 0, MPFR_RNDN);
+ if (i < 0)
+ mpfr_neg (y, y, MPFR_RNDN);
+ if (! (mpfr_equal_p (x, y) &&
+ MPFR_MULT_SIGN (MPFR_SIGN (x), MPFR_SIGN (y)) > 0))
+ {
+ printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of ");
+ mpfr_print_binary (y);
+ printf (".\n");
+ err = 1;
+ }
+ if ((rnd == MPFR_RNDD ||
+ (i > 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex >= 0)
+ {
+ printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if ((rnd == MPFR_RNDU ||
+ (i < 0 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))) && inex <= 0)
+ {
+ printf ("Error in underflowed_cothinf (i = %d, rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_specials ();
+ check_bugs ();
+ test_generic (2, 200, 10);
+ underflowed_cothinf ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcsc.c b/mpfr/tests/tcsc.c
new file mode 100644
index 0000000000..231e284069
--- /dev/null
+++ b/mpfr/tests/tcsc.c
@@ -0,0 +1,95 @@
+/* Test file for mpfr_csc.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_csc
+#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
+#include "tgeneric.c"
+
+static void
+check_specials (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ mpfr_csc (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: csc(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_csc (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: csc(Inf) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_csc (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: csc(-Inf) != NaN\n");
+ exit (1);
+ }
+
+ /* csc(+/-0) = +/-Inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_csc (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && mpfr_sgn (y) > 0))
+ {
+ printf ("Error: csc(+0) != +Inf\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_csc (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0))
+ {
+ printf ("Error: csc(-0) != -Inf\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_specials ();
+
+ test_generic (2, 100, 10);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tcsch.c b/mpfr/tests/tcsch.c
new file mode 100644
index 0000000000..7bb43549f8
--- /dev/null
+++ b/mpfr/tests/tcsch.c
@@ -0,0 +1,110 @@
+/* Test file for mpfr_csch.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_csch
+#define TEST_RANDOM_EMAX 63
+#include "tgeneric.c"
+
+static void
+check_specials (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ mpfr_csch (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: csch(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_csch (y, x, MPFR_RNDN);
+ if (! (mpfr_zero_p (y) && MPFR_SIGN (y) >0))
+ {
+ printf ("Error: csch(+Inf) != +0\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_csch (y, x, MPFR_RNDN);
+ if (! (mpfr_zero_p (y) && MPFR_SIGN (y) <0))
+ {
+ printf ("Error: csch(-0) != -0\n");
+ exit (1);
+ }
+
+ /* csc(+/-0) = +/-Inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_csch (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && mpfr_sgn (y) > 0))
+ {
+ printf ("Error: csch(+0) != +Inf\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_csch (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0))
+ {
+ printf ("Error: csch(-0) != -Inf\n");
+ exit (1);
+ }
+
+ /* check huge x */
+ mpfr_set_str (x, "8e8", 10, MPFR_RNDN);
+ mpfr_csch (y, x, MPFR_RNDN);
+ if (! (mpfr_zero_p (y) && MPFR_SIGN (y) > 0))
+ {
+ printf ("Error: csch(8e8) != +0\n");
+ exit (1);
+ }
+ mpfr_set_str (x, "-8e8", 10, MPFR_RNDN);
+ mpfr_csch (y, x, MPFR_RNDN);
+ if (! (mpfr_zero_p (y) && MPFR_SIGN (y) < 0))
+ {
+ printf ("Error: csch(-8e8) != -0\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_specials ();
+ test_generic (2, 200, 10);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/td_div.c b/mpfr/tests/td_div.c
new file mode 100644
index 0000000000..3421fa1035
--- /dev/null
+++ b/mpfr/tests/td_div.c
@@ -0,0 +1,209 @@
+/* Test file for mpfr_d_div
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+ int inexact;
+
+ mpfr_init2 (x, 123);
+ mpfr_init2 (y, 123);
+
+ /* 1.0 / nan is nan */
+ mpfr_set_nan (x);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* 1.0 / +inf == +0 */
+ mpfr_set_inf (x, 1);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_zero_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ /* 1.0 / -inf == -0 */
+ mpfr_set_inf (x, -1);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_zero_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+#if !defined(MPFR_ERRDIVZERO)
+
+ /* 1.0 / 0 == +inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ /* -1.0 / 0 == -inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, -1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ /* 1.0 / -0 == -inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, 1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ /* -1.0 / -0 == +inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, -1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ /* +inf / 0 == +inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, DBL_POS_INF, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ /* -inf / 0 == -inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, DBL_NEG_INF, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ /* +inf / -0 == -inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, DBL_POS_INF, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ /* -inf / -0 == +inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, DBL_NEG_INF, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+#endif
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_d_sub
+#define DOUBLE_ARG1
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_t x, y, z;
+ double d;
+ int inexact;
+
+ tests_start_mpfr ();
+
+ /* check with enough precision */
+ mpfr_init2 (x, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (y, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (z, IEEE_DBL_MANT_DIG);
+
+ mpfr_set_str (y, "4096", 10, MPFR_RNDN);
+ d = 0.125;
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (x, d, y, MPFR_RNDN);
+ if (inexact != 0)
+ {
+ printf ("Inexact flag error in mpfr_d_div\n");
+ exit (1);
+ }
+ mpfr_set_str (z, " 0.000030517578125", 10, MPFR_RNDN);
+ if (mpfr_cmp (z, x))
+ {
+ printf ("Error in mpfr_d_div (");
+ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
+ printf (" + %.20g)\nexpected ", d);
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+
+ check_nans ();
+
+ test_generic (2, 1000, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/td_sub.c b/mpfr/tests/td_sub.c
new file mode 100644
index 0000000000..62857febf0
--- /dev/null
+++ b/mpfr/tests/td_sub.c
@@ -0,0 +1,129 @@
+/* Test file for mpfr_d_sub
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+ int inexact;
+
+ mpfr_init2 (x, 123);
+ mpfr_init2 (y, 123);
+
+ /* 1.0 - nan is nan */
+ mpfr_set_nan (x);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_sub (y, 1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* 1.0 - +inf == -inf */
+ mpfr_set_inf (x, 1);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_sub (y, 1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ /* 1.0 - -inf == +inf */
+ mpfr_set_inf (x, -1);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_sub (y, 1.0, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_d_sub
+#define DOUBLE_ARG1
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_t x, y, z;
+ double d;
+ int inexact;
+
+ tests_start_mpfr ();
+
+ /* check with enough precision */
+ mpfr_init2 (x, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (y, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (z, IEEE_DBL_MANT_DIG);
+
+ mpfr_set_str (y, "4096", 10, MPFR_RNDN);
+ d = 0.125;
+ mpfr_clear_flags ();
+ inexact = mpfr_d_sub (x, d, y, MPFR_RNDN);
+ if (inexact != 0)
+ {
+ printf ("Inexact flag error in mpfr_d_sub\n");
+ exit (1);
+ }
+ mpfr_set_str (z, "-4095.875", 10, MPFR_RNDN);
+ if (mpfr_cmp (z, x))
+ {
+ printf ("Error in mpfr_d_sub (");
+ mpfr_out_str (stdout, 10, 7, y, MPFR_RNDN);
+ printf (" + %.20g)\nexpected ", d);
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+
+ check_nans ();
+
+ test_generic (2, 1000, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tdigamma.c b/mpfr/tests/tdigamma.c
new file mode 100644
index 0000000000..3ed568aa4d
--- /dev/null
+++ b/mpfr/tests/tdigamma.c
@@ -0,0 +1,68 @@
+/* test file for digamma function
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_digamma
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_inf (y, -1);
+ mpfr_set_inf (x, 1);
+ mpfr_digamma (y, x, MPFR_RNDN);
+ if (mpfr_inf_p (y) == 0 || mpfr_sgn (y) < 0)
+ {
+ printf ("error for Psi(+Inf)\n");
+ printf ("expected +Inf\n");
+ printf ("got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+
+ test_generic (2, 100, 2);
+
+ data_check ("data/digamma", mpfr_digamma, "mpfr_digamma");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tdim.c b/mpfr/tests/tdim.c
new file mode 100644
index 0000000000..d32add76b4
--- /dev/null
+++ b/mpfr/tests/tdim.c
@@ -0,0 +1,114 @@
+/* Test file for mpfr_dim.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_dim
+#define TWO_ARGS
+#define TEST_RANDOM_EMIN -20
+#define TEST_RANDOM_EMAX 20
+#define TGENERIC_NOWARNING 1
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_t x, y, z;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ /* case x=NaN */
+ mpfr_set_nan (x);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_dim (z, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (z))
+ {
+ printf ("Error in mpfr_dim (NaN, 0)\n");
+ exit (1);
+ }
+
+ /* case x=+Inf */
+ mpfr_set_inf (x, 1);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_dim (z, x, y, MPFR_RNDN);
+ if (!mpfr_inf_p (z) || mpfr_sgn (z) < 0)
+ {
+ printf ("Error in mpfr_dim (+Inf, 0)\n");
+ exit (1);
+ }
+
+ /* case x=-Inf */
+ mpfr_set_inf (x, -1);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_dim (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 0) || mpfr_sgn (z) < 0)
+ {
+ printf ("Error in mpfr_dim (-Inf, 0)\n");
+ exit (1);
+ }
+
+ /* case x=y=+Inf */
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, 1);
+ mpfr_dim (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 0) || mpfr_sgn (z) < 0)
+ {
+ printf ("Error in mpfr_dim (+Inf, +Inf)\n");
+ exit (1);
+ }
+
+ /* case x > y */
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_dim (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 1))
+ {
+ printf ("Error in mpfr_dim (2, 1)\n");
+ exit (1);
+ }
+
+ /* case x < y */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_ui (y, 2, MPFR_RNDN);
+ mpfr_dim (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 0))
+ {
+ printf ("Error in mpfr_dim (1, 2)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ test_generic (2, 220, 42);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tdiv.c b/mpfr/tests/tdiv.c
new file mode 100644
index 0000000000..476c35d2d9
--- /dev/null
+++ b/mpfr/tests/tdiv.c
@@ -0,0 +1,1136 @@
+/* Test file for mpfr_div (and some mpfr_div_ui, etc. tests).
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+check_equal (mpfr_srcptr a, mpfr_srcptr a2, char *s,
+ mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t r)
+{
+ if ((MPFR_IS_NAN (a) && MPFR_IS_NAN (a2)) ||
+ mpfr_equal_p (a, a2))
+ return;
+ printf ("Error in %s\n", mpfr_print_rnd_mode (r));
+ printf ("b = ");
+ mpfr_dump (b);
+ printf ("c = ");
+ mpfr_dump (c);
+ printf ("mpfr_div result: ");
+ mpfr_dump (a);
+ printf ("%s result: ", s);
+ mpfr_dump (a2);
+ exit (1);
+}
+
+static int
+mpfr_all_div (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t r)
+{
+ mpfr_t a2;
+ unsigned int oldflags, newflags;
+ int inex, inex2;
+
+ oldflags = __gmpfr_flags;
+ inex = mpfr_div (a, b, c, r);
+
+ if (a == b || a == c)
+ return inex;
+
+ newflags = __gmpfr_flags;
+
+ mpfr_init2 (a2, MPFR_PREC (a));
+
+ if (mpfr_integer_p (b) && ! (MPFR_IS_ZERO (b) && MPFR_IS_NEG (b)))
+ {
+ /* b is an integer, but not -0 (-0 is rejected as
+ it becomes +0 when converted to an integer). */
+ if (mpfr_fits_ulong_p (b, MPFR_RNDA))
+ {
+ __gmpfr_flags = oldflags;
+ inex2 = mpfr_ui_div (a2, mpfr_get_ui (b, MPFR_RNDN), c, r);
+ MPFR_ASSERTN (SAME_SIGN (inex2, inex));
+ MPFR_ASSERTN (__gmpfr_flags == newflags);
+ check_equal (a, a2, "mpfr_ui_div", b, c, r);
+ }
+ if (mpfr_fits_slong_p (b, MPFR_RNDA))
+ {
+ __gmpfr_flags = oldflags;
+ inex2 = mpfr_si_div (a2, mpfr_get_si (b, MPFR_RNDN), c, r);
+ MPFR_ASSERTN (SAME_SIGN (inex2, inex));
+ MPFR_ASSERTN (__gmpfr_flags == newflags);
+ check_equal (a, a2, "mpfr_si_div", b, c, r);
+ }
+ }
+
+ if (mpfr_integer_p (c) && ! (MPFR_IS_ZERO (c) && MPFR_IS_NEG (c)))
+ {
+ /* c is an integer, but not -0 (-0 is rejected as
+ it becomes +0 when converted to an integer). */
+ if (mpfr_fits_ulong_p (c, MPFR_RNDA))
+ {
+ __gmpfr_flags = oldflags;
+ inex2 = mpfr_div_ui (a2, b, mpfr_get_ui (c, MPFR_RNDN), r);
+ MPFR_ASSERTN (SAME_SIGN (inex2, inex));
+ MPFR_ASSERTN (__gmpfr_flags == newflags);
+ check_equal (a, a2, "mpfr_div_ui", b, c, r);
+ }
+ if (mpfr_fits_slong_p (c, MPFR_RNDA))
+ {
+ __gmpfr_flags = oldflags;
+ inex2 = mpfr_div_si (a2, b, mpfr_get_si (c, MPFR_RNDN), r);
+ MPFR_ASSERTN (SAME_SIGN (inex2, inex));
+ MPFR_ASSERTN (__gmpfr_flags == newflags);
+ check_equal (a, a2, "mpfr_div_si", b, c, r);
+ }
+ }
+
+ mpfr_clear (a2);
+
+ return inex;
+}
+
+#ifdef CHECK_EXTERNAL
+static int
+test_div (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ printf (" ");
+ mpfr_print_raw (c);
+ }
+ res = mpfr_all_div (a, b, c, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_div mpfr_all_div
+#endif
+
+#define check53(n, d, rnd, res) check4(n, d, rnd, 53, res)
+
+/* return 0 iff a and b are of the same sign */
+static int
+inex_cmp (int a, int b)
+{
+ if (a > 0)
+ return (b > 0) ? 0 : 1;
+ else if (a == 0)
+ return (b == 0) ? 0 : 1;
+ else
+ return (b < 0) ? 0 : 1;
+}
+
+static void
+check4 (const char *Ns, const char *Ds, mpfr_rnd_t rnd_mode, int p,
+ const char *Qs)
+{
+ mpfr_t q, n, d;
+
+ mpfr_inits2 (p, q, n, d, (mpfr_ptr) 0);
+ mpfr_set_str1 (n, Ns);
+ mpfr_set_str1 (d, Ds);
+ test_div(q, n, d, rnd_mode);
+ if (mpfr_cmp_str (q, Qs, ((p==53) ? 10 : 2), MPFR_RNDN) )
+ {
+ printf ("mpfr_div failed for n=%s, d=%s, p=%d, rnd_mode=%s\n",
+ Ns, Ds, p, mpfr_print_rnd_mode (rnd_mode));
+ printf ("got ");mpfr_print_binary(q);
+ mpfr_set_str (q, Qs, ((p==53) ? 10 : 2), MPFR_RNDN);
+ printf("\nexpected "); mpfr_print_binary(q);
+ putchar('\n');
+ exit (1);
+ }
+ mpfr_clears (q, n, d, (mpfr_ptr) 0);
+}
+
+static void
+check24 (const char *Ns, const char *Ds, mpfr_rnd_t rnd_mode, const char *Qs)
+{
+ mpfr_t q, n, d;
+
+ mpfr_inits2 (24, q, n, d, (mpfr_ptr) 0);
+
+ mpfr_set_str1 (n, Ns);
+ mpfr_set_str1 (d, Ds);
+ test_div(q, n, d, rnd_mode);
+ if (mpfr_cmp_str1 (q, Qs) )
+ {
+ printf ("mpfr_div failed for n=%s, d=%s, prec=24, rnd_mode=%s\n",
+ Ns, Ds, mpfr_print_rnd_mode(rnd_mode));
+ printf ("expected quotient is %s, got ", Qs);
+ mpfr_out_str(stdout,10,0,q, MPFR_RNDN); putchar('\n');
+ exit (1);
+ }
+ mpfr_clears (q, n, d, (mpfr_ptr) 0);
+}
+
+/* the following examples come from the paper "Number-theoretic Test
+ Generation for Directed Rounding" from Michael Parks, Table 2 */
+static void
+check_float(void)
+{
+ check24("70368760954880.0", "8388609.0", MPFR_RNDN, "8.388609e6");
+ check24("140737479966720.0", "16777213.0", MPFR_RNDN, "8.388609e6");
+ check24("70368777732096.0", "8388611.0", MPFR_RNDN, "8.388609e6");
+ check24("105553133043712.0", "12582911.0", MPFR_RNDN, "8.38861e6");
+ /* the exponent for the following example was forgotten in
+ the Arith'14 version of Parks' paper */
+ check24 ("12582913.0", "12582910.0", MPFR_RNDN, "1.000000238");
+ check24 ("105553124655104.0", "12582910.0", MPFR_RNDN, "8388610.0");
+ check24("140737479966720.0", "8388609.0", MPFR_RNDN, "1.6777213e7");
+ check24("70368777732096.0", "8388609.0", MPFR_RNDN, "8.388611e6");
+ check24("105553133043712.0", "8388610.0", MPFR_RNDN, "1.2582911e7");
+ check24("105553124655104.0", "8388610.0", MPFR_RNDN, "1.258291e7");
+
+ check24("70368760954880.0", "8388609.0", MPFR_RNDZ, "8.388608e6");
+ check24("140737479966720.0", "16777213.0", MPFR_RNDZ, "8.388609e6");
+ check24("70368777732096.0", "8388611.0", MPFR_RNDZ, "8.388608e6");
+ check24("105553133043712.0", "12582911.0", MPFR_RNDZ, "8.38861e6");
+ check24("12582913.0", "12582910.0", MPFR_RNDZ, "1.000000238");
+ check24 ("105553124655104.0", "12582910.0", MPFR_RNDZ, "8388610.0");
+ check24("140737479966720.0", "8388609.0", MPFR_RNDZ, "1.6777213e7");
+ check24("70368777732096.0", "8388609.0", MPFR_RNDZ, "8.38861e6");
+ check24("105553133043712.0", "8388610.0", MPFR_RNDZ, "1.2582911e7");
+ check24("105553124655104.0", "8388610.0", MPFR_RNDZ, "1.258291e7");
+
+ check24("70368760954880.0", "8388609.0", MPFR_RNDU, "8.388609e6");
+ check24("140737479966720.0", "16777213.0", MPFR_RNDU, "8.38861e6");
+ check24("70368777732096.0", "8388611.0", MPFR_RNDU, "8.388609e6");
+ check24("105553133043712.0", "12582911.0", MPFR_RNDU, "8.388611e6");
+ check24("12582913.0", "12582910.0", MPFR_RNDU, "1.000000357");
+ check24 ("105553124655104.0", "12582910.0", MPFR_RNDU, "8388611.0");
+ check24("140737479966720.0", "8388609.0", MPFR_RNDU, "1.6777214e7");
+ check24("70368777732096.0", "8388609.0", MPFR_RNDU, "8.388611e6");
+ check24("105553133043712.0", "8388610.0", MPFR_RNDU, "1.2582912e7");
+ check24("105553124655104.0", "8388610.0", MPFR_RNDU, "1.2582911e7");
+
+ check24("70368760954880.0", "8388609.0", MPFR_RNDD, "8.388608e6");
+ check24("140737479966720.0", "16777213.0", MPFR_RNDD, "8.388609e6");
+ check24("70368777732096.0", "8388611.0", MPFR_RNDD, "8.388608e6");
+ check24("105553133043712.0", "12582911.0", MPFR_RNDD, "8.38861e6");
+ check24("12582913.0", "12582910.0", MPFR_RNDD, "1.000000238");
+ check24 ("105553124655104.0", "12582910.0", MPFR_RNDD, "8388610.0");
+ check24("140737479966720.0", "8388609.0", MPFR_RNDD, "1.6777213e7");
+ check24("70368777732096.0", "8388609.0", MPFR_RNDD, "8.38861e6");
+ check24("105553133043712.0", "8388610.0", MPFR_RNDD, "1.2582911e7");
+ check24("105553124655104.0", "8388610.0", MPFR_RNDD, "1.258291e7");
+
+ check24("70368760954880.0", "8388609.0", MPFR_RNDA, "8.388609e6");
+}
+
+static void
+check_double(void)
+{
+ check53("0.0", "1.0", MPFR_RNDZ, "0.0");
+ check53("-7.4988969224688591e63", "4.8816866450288732e306", MPFR_RNDD,
+ "-1.5361282826510687291e-243");
+ check53("-1.33225773037748601769e+199", "3.63449540676937123913e+79",
+ MPFR_RNDZ, "-3.6655920045905428978e119");
+ check53("9.89438396044940256501e-134", "5.93472984109987421717e-67",MPFR_RNDU,
+ "1.6672003992376663654e-67");
+ check53("9.89438396044940256501e-134", "5.93472984109987421717e-67",MPFR_RNDA,
+ "1.6672003992376663654e-67");
+ check53("9.89438396044940256501e-134", "-5.93472984109987421717e-67",
+ MPFR_RNDU, "-1.6672003992376663654e-67");
+ check53("-4.53063926135729747564e-308", "7.02293374921793516813e-84",
+ MPFR_RNDD, "-6.4512060388748850857e-225");
+ check53("6.25089225176473806123e-01","-2.35527154824420243364e-230",
+ MPFR_RNDD, "-2.6540006635008291192e229");
+ check53("6.25089225176473806123e-01","-2.35527154824420243364e-230",
+ MPFR_RNDA, "-2.6540006635008291192e229");
+ check53("6.52308934689126e15", "-1.62063546601505417497e273", MPFR_RNDN,
+ "-4.0250194961676020848e-258");
+ check53("1.04636807108079349236e-189", "3.72295730823253012954e-292",
+ MPFR_RNDZ, "2.810583051186143125e102");
+ /* problems found by Kevin under HP-PA */
+ check53 ("2.861044553323177e-136", "-1.1120354257068143e+45", MPFR_RNDZ,
+ "-2.5727998292003016e-181");
+ check53 ("-4.0559157245809205e-127", "-1.1237723844524865e+77", MPFR_RNDN,
+ "3.6091968273068081e-204");
+ check53 ("-1.8177943561493235e-93", "-8.51233984260364e-104", MPFR_RNDU,
+ "2.1354814184595821e+10");
+}
+
+static void
+check_64(void)
+{
+ mpfr_t x,y,z;
+
+ mpfr_inits2 (64, x, y, z, (mpfr_ptr) 0);
+
+ mpfr_set_str_binary(x, "1.00100100110110101001010010101111000001011100100101010000000000E54");
+ mpfr_set_str_binary(y, "1.00000000000000000000000000000000000000000000000000000000000000E584");
+ test_div(z, x, y, MPFR_RNDU);
+ if (mpfr_cmp_str (z, "0.1001001001101101010010100101011110000010111001001010100000000000E-529", 2, MPFR_RNDN))
+ {
+ printf("Error for tdiv for MPFR_RNDU and p=64\nx=");
+ mpfr_print_binary(x);
+ printf("\ny=");
+ mpfr_print_binary(y);
+ printf("\ngot ");
+ mpfr_print_binary(z);
+ printf("\nexpected 0.1001001001101101010010100101011110000010111001001010100000000000E-529\n");
+ exit(1);
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+static void
+check_convergence (void)
+{
+ mpfr_t x, y; int i, j;
+
+ mpfr_init2(x, 130);
+ mpfr_set_str_binary(x, "0.1011111101011010101000001010011111101000011100011101010011111011000011001010000000111100100111110011001010110100100001001000111001E6944");
+ mpfr_init2(y, 130);
+ mpfr_set_ui(y, 5, MPFR_RNDN);
+ test_div(x, x, y, MPFR_RNDD); /* exact division */
+
+ mpfr_set_prec(x, 64);
+ mpfr_set_prec(y, 64);
+ mpfr_set_str_binary(x, "0.10010010011011010100101001010111100000101110010010101E55");
+ mpfr_set_str_binary(y, "0.1E585");
+ test_div(x, x, y, MPFR_RNDN);
+ mpfr_set_str_binary(y, "0.10010010011011010100101001010111100000101110010010101E-529");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_div for prec=64, rnd=MPFR_RNDN\n");
+ printf ("got "); mpfr_print_binary(x); puts ("");
+ printf ("instead of "); mpfr_print_binary(y); puts ("");
+ exit(1);
+ }
+
+ for (i=32; i<=64; i+=32)
+ {
+ mpfr_set_prec(x, i);
+ mpfr_set_prec(y, i);
+ mpfr_set_ui(x, 1, MPFR_RNDN);
+ RND_LOOP(j)
+ {
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ test_div (y, x, y, (mpfr_rnd_t) j);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("mpfr_div failed for x=1.0, y=1.0, prec=%d rnd=%s\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) j));
+ printf ("got "); mpfr_print_binary(y); puts ("");
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define KMAX 10000
+
+/* given y = o(x/u), x, u, find the inexact flag by
+ multiplying y by u */
+static int
+get_inexact (mpfr_t y, mpfr_t x, mpfr_t u)
+{
+ mpfr_t xx;
+ int inex;
+ mpfr_init2 (xx, mpfr_get_prec (y) + mpfr_get_prec (u));
+ mpfr_mul (xx, y, u, MPFR_RNDN); /* exact */
+ inex = mpfr_cmp (xx, x);
+ mpfr_clear (xx);
+ return inex;
+}
+
+static void
+check_hard (void)
+{
+ mpfr_t u, v, q, q2;
+ mpfr_prec_t precu, precv, precq;
+ int rnd;
+ int inex, inex2, i, j;
+
+ mpfr_init (q);
+ mpfr_init (q2);
+ mpfr_init (u);
+ mpfr_init (v);
+
+ for (precq = MPFR_PREC_MIN; precq <= 64; precq ++)
+ {
+ mpfr_set_prec (q, precq);
+ mpfr_set_prec (q2, precq + 1);
+ for (j = 0; j < 2; j++)
+ {
+ if (j == 0)
+ {
+ do
+ {
+ mpfr_urandomb (q2, RANDS);
+ }
+ while (mpfr_cmp_ui (q2, 0) == 0);
+ }
+ else /* use q2=1 */
+ mpfr_set_ui (q2, 1, MPFR_RNDN);
+ for (precv = precq; precv <= 10 * precq; precv += precq)
+ {
+ mpfr_set_prec (v, precv);
+ do
+ {
+ mpfr_urandomb (v, RANDS);
+ }
+ while (mpfr_cmp_ui (v, 0) == 0);
+ for (precu = precq; precu <= 10 * precq; precu += precq)
+ {
+ mpfr_set_prec (u, precu);
+ mpfr_mul (u, v, q2, MPFR_RNDN);
+ mpfr_nextbelow (u);
+ for (i = 0; i <= 2; i++)
+ {
+ RND_LOOP(rnd)
+ {
+ inex = test_div (q, u, v, (mpfr_rnd_t) rnd);
+ inex2 = get_inexact (q, u, v);
+ if (inex_cmp (inex, inex2))
+ {
+ printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex2, inex);
+ printf ("u= "); mpfr_dump (u);
+ printf ("v= "); mpfr_dump (v);
+ printf ("q= "); mpfr_dump (q);
+ mpfr_set_prec (q2, precq + precv);
+ mpfr_mul (q2, q, v, MPFR_RNDN);
+ printf ("q*v="); mpfr_dump (q2);
+ exit (1);
+ }
+ }
+ mpfr_nextabove (u);
+ }
+ }
+ }
+ }
+ }
+
+ mpfr_clear (q);
+ mpfr_clear (q2);
+ mpfr_clear (u);
+ mpfr_clear (v);
+}
+
+static void
+check_lowr (void)
+{
+ mpfr_t x, y, z, z2, z3, tmp;
+ int k, c, c2;
+
+
+ mpfr_init2 (x, 1000);
+ mpfr_init2 (y, 100);
+ mpfr_init2 (tmp, 850);
+ mpfr_init2 (z, 10);
+ mpfr_init2 (z2, 10);
+ mpfr_init2 (z3, 50);
+
+ for (k = 1; k < KMAX; k++)
+ {
+ do
+ {
+ mpfr_urandomb (z, RANDS);
+ }
+ while (mpfr_cmp_ui (z, 0) == 0);
+ do
+ {
+ mpfr_urandomb (tmp, RANDS);
+ }
+ while (mpfr_cmp_ui (tmp, 0) == 0);
+ mpfr_mul (x, z, tmp, MPFR_RNDN); /* exact */
+ c = test_div (z2, x, tmp, MPFR_RNDN);
+
+ if (c || mpfr_cmp (z2, z))
+ {
+ printf ("Error in mpfr_div rnd=MPFR_RNDN\n");
+ printf ("got "); mpfr_print_binary(z2); puts ("");
+ printf ("instead of "); mpfr_print_binary(z); puts ("");
+ printf ("inex flag = %d, expected 0\n", c);
+ exit (1);
+ }
+ }
+
+ /* x has still precision 1000, z precision 10, and tmp prec 850 */
+ mpfr_set_prec (z2, 9);
+ for (k = 1; k < KMAX; k++)
+ {
+ mpfr_urandomb (z, RANDS);
+ do
+ {
+ mpfr_urandomb (tmp, RANDS);
+ }
+ while (mpfr_cmp_ui (tmp, 0) == 0);
+ mpfr_mul (x, z, tmp, MPFR_RNDN); /* exact */
+ c = test_div (z2, x, tmp, MPFR_RNDN);
+ /* since z2 has one less bit that z, either the division is exact
+ if z is representable on 9 bits, or we have an even round case */
+
+ c2 = get_inexact (z2, x, tmp);
+ if ((mpfr_cmp (z2, z) == 0 && c) || inex_cmp (c, c2))
+ {
+ printf ("Error in mpfr_div rnd=MPFR_RNDN\n");
+ printf ("got "); mpfr_print_binary(z2); puts ("");
+ printf ("instead of "); mpfr_print_binary(z); puts ("");
+ printf ("inex flag = %d, expected %d\n", c, c2);
+ exit (1);
+ }
+ else if (c == 2)
+ {
+ mpfr_nexttoinf (z);
+ if (mpfr_cmp(z2, z))
+ {
+ printf ("Error in mpfr_div [even rnd?] rnd=MPFR_RNDN\n");
+ printf ("Dividing ");
+ printf ("got "); mpfr_print_binary(z2); puts ("");
+ printf ("instead of "); mpfr_print_binary(z); puts ("");
+ printf ("inex flag = %d\n", 1);
+ exit (1);
+ }
+ }
+ else if (c == -2)
+ {
+ mpfr_nexttozero (z);
+ if (mpfr_cmp(z2, z))
+ {
+ printf ("Error in mpfr_div [even rnd?] rnd=MPFR_RNDN\n");
+ printf ("Dividing ");
+ printf ("got "); mpfr_print_binary(z2); puts ("");
+ printf ("instead of "); mpfr_print_binary(z); puts ("");
+ printf ("inex flag = %d\n", 1);
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_set_prec(x, 1000);
+ mpfr_set_prec(y, 100);
+ mpfr_set_prec(tmp, 850);
+ mpfr_set_prec(z, 10);
+ mpfr_set_prec(z2, 10);
+
+ /* almost exact divisions */
+ for (k = 1; k < KMAX; k++)
+ {
+ do
+ {
+ mpfr_urandomb (z, RANDS);
+ }
+ while (mpfr_cmp_ui (z, 0) == 0);
+ do
+ {
+ mpfr_urandomb (tmp, RANDS);
+ }
+ while (mpfr_cmp_ui (tmp, 0) == 0);
+ mpfr_mul(x, z, tmp, MPFR_RNDN);
+ mpfr_set(y, tmp, MPFR_RNDD);
+ mpfr_nexttoinf (x);
+
+ c = test_div(z2, x, y, MPFR_RNDD);
+ test_div(z3, x, y, MPFR_RNDD);
+ mpfr_set(z, z3, MPFR_RNDD);
+
+ if (c != -1 || mpfr_cmp(z2, z))
+ {
+ printf ("Error in mpfr_div rnd=MPFR_RNDD\n");
+ printf ("got "); mpfr_print_binary(z2); puts ("");
+ printf ("instead of "); mpfr_print_binary(z); puts ("");
+ printf ("inex flag = %d\n", c);
+ exit (1);
+ }
+
+ mpfr_set (y, tmp, MPFR_RNDU);
+ test_div (z3, x, y, MPFR_RNDU);
+ mpfr_set (z, z3, MPFR_RNDU);
+ c = test_div (z2, x, y, MPFR_RNDU);
+ if (c != 1 || mpfr_cmp (z2, z))
+ {
+ printf ("Error in mpfr_div rnd=MPFR_RNDU\n");
+ printf ("u="); mpfr_dump (x);
+ printf ("v="); mpfr_dump (y);
+ printf ("got "); mpfr_print_binary (z2); puts ("");
+ printf ("instead of "); mpfr_print_binary (z); puts ("");
+ printf ("inex flag = %d\n", c);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (z2);
+ mpfr_clear (z3);
+ mpfr_clear (tmp);
+}
+
+#define MAX_PREC 128
+
+static void
+check_inexact (void)
+{
+ mpfr_t x, y, z, u;
+ mpfr_prec_t px, py, pu;
+ int inexact, cmp;
+ mpfr_rnd_t rnd;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (u);
+
+ mpfr_set_prec (x, 28);
+ mpfr_set_prec (y, 28);
+ mpfr_set_prec (z, 1023);
+ mpfr_set_str_binary (x, "0.1000001001101101111100010011E0");
+ mpfr_set_str (z, "48284762641021308813686974720835219181653367326353400027913400579340343320519877153813133510034402932651132854764198688352364361009429039801248971901380781746767119334993621199563870113045276395603170432175354501451429471578325545278975153148347684600400321033502982713296919861760382863826626093689036010394", 10, MPFR_RNDN);
+ mpfr_div (x, x, z, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.1111001011001101001001111100E-1023");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_div for prec=28, RNDN\n");
+ printf ("Expected "); mpfr_dump (y);
+ printf ("Got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_str_binary (x, "0.11101100110010100011011000000100001111011111110010101E0");
+ mpfr_set_prec (u, 127);
+ mpfr_set_str_binary (u, "0.1000001100110110110101110110101101111000110000001111111110000000011111001010110100110010111111111101000001011011101011101101000E-2");
+ mpfr_set_prec (y, 95);
+ inexact = test_div (y, x, u, MPFR_RNDN);
+ if (inexact != (cmp = get_inexact (y, x, u)))
+ {
+ printf ("Wrong inexact flag (0): expected %d, got %d\n", cmp, inexact);
+ printf ("x="); mpfr_out_str (stdout, 10, 99, x, MPFR_RNDN); printf ("\n");
+ printf ("u="); mpfr_out_str (stdout, 10, 99, u, MPFR_RNDN); printf ("\n");
+ printf ("y="); mpfr_out_str (stdout, 10, 99, y, MPFR_RNDN); printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 33);
+ mpfr_set_str_binary (x, "0.101111100011011101010011101100001E0");
+ mpfr_set_prec (u, 2);
+ mpfr_set_str_binary (u, "0.1E0");
+ mpfr_set_prec (y, 28);
+ if ((inexact = test_div (y, x, u, MPFR_RNDN) >= 0))
+ {
+ printf ("Wrong inexact flag (1): expected -1, got %d\n",
+ inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 129);
+ mpfr_set_str_binary (x, "0.111110101111001100000101011100101100110011011101010001000110110101100101000010000001110110100001101010001010100010001111001101010E-2");
+ mpfr_set_prec (u, 15);
+ mpfr_set_str_binary (u, "0.101101000001100E-1");
+ mpfr_set_prec (y, 92);
+ if ((inexact = test_div (y, x, u, MPFR_RNDN)) <= 0)
+ {
+ printf ("Wrong inexact flag for rnd=MPFR_RNDN(1): expected 1, got %d\n",
+ inexact);
+ mpfr_dump (x);
+ mpfr_dump (u);
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ for (px=2; px<MAX_PREC; px++)
+ {
+ mpfr_set_prec (x, px);
+ mpfr_urandomb (x, RANDS);
+ for (pu=2; pu<=MAX_PREC; pu++)
+ {
+ mpfr_set_prec (u, pu);
+ do { mpfr_urandomb (u, RANDS); } while (mpfr_cmp_ui (u, 0) == 0);
+ {
+ py = MPFR_PREC_MIN + (randlimb () % (MAX_PREC - MPFR_PREC_MIN));
+ mpfr_set_prec (y, py);
+ mpfr_set_prec (z, py + pu);
+ {
+ rnd = RND_RAND ();
+ inexact = test_div (y, x, u, rnd);
+ if (mpfr_mul (z, y, u, rnd))
+ {
+ printf ("z <- y * u should be exact\n");
+ exit (1);
+ }
+ cmp = mpfr_cmp (z, x);
+ if (((inexact == 0) && (cmp != 0)) ||
+ ((inexact > 0) && (cmp <= 0)) ||
+ ((inexact < 0) && (cmp >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s\n",
+ mpfr_print_rnd_mode(rnd));
+ printf ("expected %d, got %d\n", cmp, inexact);
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("u="); mpfr_print_binary (u); puts ("");
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ printf ("y*u="); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (u);
+}
+
+static void
+check_special (void)
+{
+ mpfr_t a, d, q;
+ mpfr_exp_t emax, emin;
+ int i;
+
+ mpfr_init2 (a, 100L);
+ mpfr_init2 (d, 100L);
+ mpfr_init2 (q, 100L);
+
+ /* 1/nan == nan */
+ mpfr_set_ui (a, 1L, MPFR_RNDN);
+ MPFR_SET_NAN (d);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+
+ /* nan/1 == nan */
+ MPFR_SET_NAN (a);
+ mpfr_set_ui (d, 1L, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+
+ /* +inf/1 == +inf */
+ MPFR_SET_INF (a);
+ MPFR_SET_POS (a);
+ mpfr_set_ui (d, 1L, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) > 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* +inf/-1 == -inf */
+ MPFR_SET_INF (a);
+ MPFR_SET_POS (a);
+ mpfr_set_si (d, -1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) < 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* -inf/1 == -inf */
+ MPFR_SET_INF (a);
+ MPFR_SET_NEG (a);
+ mpfr_set_ui (d, 1L, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) < 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* -inf/-1 == +inf */
+ MPFR_SET_INF (a);
+ MPFR_SET_NEG (a);
+ mpfr_set_si (d, -1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) > 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* 1/+inf == +0 */
+ mpfr_set_ui (a, 1L, MPFR_RNDN);
+ MPFR_SET_INF (d);
+ MPFR_SET_POS (d);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_number_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) == 0);
+ MPFR_ASSERTN (MPFR_IS_POS (q));
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* 1/-inf == -0 */
+ mpfr_set_ui (a, 1L, MPFR_RNDN);
+ MPFR_SET_INF (d);
+ MPFR_SET_NEG (d);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_number_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) == 0);
+ MPFR_ASSERTN (MPFR_IS_NEG (q));
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* -1/+inf == -0 */
+ mpfr_set_si (a, -1, MPFR_RNDN);
+ MPFR_SET_INF (d);
+ MPFR_SET_POS (d);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_number_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) == 0);
+ MPFR_ASSERTN (MPFR_IS_NEG (q));
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* -1/-inf == +0 */
+ mpfr_set_si (a, -1, MPFR_RNDN);
+ MPFR_SET_INF (d);
+ MPFR_SET_NEG (d);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_number_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) == 0);
+ MPFR_ASSERTN (MPFR_IS_POS (q));
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* 0/0 == nan */
+ mpfr_set_ui (a, 0L, MPFR_RNDN);
+ mpfr_set_ui (d, 0L, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+
+ /* +inf/+inf == nan */
+ MPFR_SET_INF (a);
+ MPFR_SET_POS (a);
+ MPFR_SET_INF (d);
+ MPFR_SET_POS (d);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+
+ /* 1/+0 = +inf */
+ mpfr_set_ui (a, 1, MPFR_RNDZ);
+ mpfr_set_ui (d, 0, MPFR_RNDZ);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+
+ /* 1/-0 = -inf */
+ mpfr_set_ui (a, 1, MPFR_RNDZ);
+ mpfr_set_ui (d, 0, MPFR_RNDZ);
+ mpfr_neg (d, d, MPFR_RNDZ);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+
+ /* -1/+0 = -inf */
+ mpfr_set_si (a, -1, MPFR_RNDZ);
+ mpfr_set_ui (d, 0, MPFR_RNDZ);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+
+ /* -1/-0 = +inf */
+ mpfr_set_si (a, -1, MPFR_RNDZ);
+ mpfr_set_ui (d, 0, MPFR_RNDZ);
+ mpfr_neg (d, d, MPFR_RNDZ);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+
+ /* +inf/+0 = +inf */
+ MPFR_SET_INF (a);
+ MPFR_SET_POS (a);
+ mpfr_set_ui (d, 0, MPFR_RNDZ);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* +inf/-0 = -inf */
+ MPFR_SET_INF (a);
+ MPFR_SET_POS (a);
+ mpfr_set_ui (d, 0, MPFR_RNDZ);
+ mpfr_neg (d, d, MPFR_RNDZ);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* -inf/+0 = -inf */
+ MPFR_SET_INF (a);
+ MPFR_SET_NEG (a);
+ mpfr_set_ui (d, 0, MPFR_RNDZ);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* -inf/-0 = +inf */
+ MPFR_SET_INF (a);
+ MPFR_SET_NEG (a);
+ mpfr_set_ui (d, 0, MPFR_RNDZ);
+ mpfr_neg (d, d, MPFR_RNDZ);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* check overflow */
+ emax = mpfr_get_emax ();
+ set_emax (1);
+ mpfr_set_ui (a, 1, MPFR_RNDZ);
+ mpfr_set_ui (d, 1, MPFR_RNDZ);
+ mpfr_div_2exp (d, d, 1, MPFR_RNDZ);
+ mpfr_clear_flags ();
+ test_div (q, a, d, MPFR_RNDU); /* 1 / 0.5 = 2 -> overflow */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
+ MPFR_ASSERTN (__gmpfr_flags == (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT));
+ set_emax (emax);
+
+ /* check underflow */
+ emin = mpfr_get_emin ();
+ set_emin (-1);
+ mpfr_set_ui (a, 1, MPFR_RNDZ);
+ mpfr_div_2exp (a, a, 2, MPFR_RNDZ);
+ mpfr_set_prec (d, mpfr_get_prec (q) + 8);
+ for (i = -1; i <= 1; i++)
+ {
+ int sign;
+
+ /* Test 2^(-2) / (+/- (2 + eps)), with eps < 0, eps = 0, eps > 0.
+ -> underflow.
+ With div.c r5513, this test fails for eps > 0 in MPFR_RNDN. */
+ mpfr_set_ui (d, 2, MPFR_RNDZ);
+ if (i < 0)
+ mpfr_nextbelow (d);
+ if (i > 0)
+ mpfr_nextabove (d);
+ for (sign = 0; sign <= 1; sign++)
+ {
+ mpfr_clear_flags ();
+ test_div (q, a, d, MPFR_RNDZ); /* result = 0 */
+ MPFR_ASSERTN (__gmpfr_flags ==
+ (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT));
+ MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q));
+ MPFR_ASSERTN (MPFR_IS_ZERO (q));
+ mpfr_clear_flags ();
+ test_div (q, a, d, MPFR_RNDN); /* result = 0 iff eps >= 0 */
+ MPFR_ASSERTN (__gmpfr_flags ==
+ (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT));
+ MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q));
+ if (i < 0)
+ mpfr_nexttozero (q);
+ MPFR_ASSERTN (MPFR_IS_ZERO (q));
+ mpfr_neg (d, d, MPFR_RNDN);
+ }
+ }
+ set_emin (emin);
+
+ mpfr_clear (a);
+ mpfr_clear (d);
+ mpfr_clear (q);
+}
+
+static void
+consistency (void)
+{
+ mpfr_t x, y, z1, z2;
+ int i;
+
+ mpfr_inits (x, y, z1, z2, (mpfr_ptr) 0);
+
+ for (i = 0; i < 10000; i++)
+ {
+ mpfr_rnd_t rnd;
+ mpfr_prec_t px, py, pz, p;
+ int inex1, inex2;
+
+ rnd = RND_RAND ();
+ px = (randlimb () % 256) + 2;
+ py = (randlimb () % 128) + 2;
+ pz = (randlimb () % 256) + 2;
+ mpfr_set_prec (x, px);
+ mpfr_set_prec (y, py);
+ mpfr_set_prec (z1, pz);
+ mpfr_set_prec (z2, pz);
+ mpfr_urandomb (x, RANDS);
+ do
+ mpfr_urandomb (y, RANDS);
+ while (mpfr_zero_p (y));
+ inex1 = mpfr_div (z1, x, y, rnd);
+ MPFR_ASSERTN (!MPFR_IS_NAN (z1));
+ p = MAX (MAX (px, py), pz);
+ if (mpfr_prec_round (x, p, MPFR_RNDN) != 0 ||
+ mpfr_prec_round (y, p, MPFR_RNDN) != 0)
+ {
+ printf ("mpfr_prec_round error for i = %d\n", i);
+ exit (1);
+ }
+ inex2 = mpfr_div (z2, x, y, rnd);
+ MPFR_ASSERTN (!MPFR_IS_NAN (z2));
+ if (inex1 != inex2 || mpfr_cmp (z1, z2) != 0)
+ {
+ printf ("Consistency error for i = %d\n", i);
+ exit (1);
+ }
+ }
+
+ mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
+}
+
+/* Reported by Carl Witty on 2007-06-03 */
+static void
+test_20070603 (void)
+{
+ mpfr_t n, d, q, c;
+
+ mpfr_init2 (n, 128);
+ mpfr_init2 (d, 128);
+ mpfr_init2 (q, 31);
+ mpfr_init2 (c, 31);
+
+ mpfr_set_str (n, "10384593717069655257060992206846485", 10, MPFR_RNDN);
+ mpfr_set_str (d, "10384593717069655257060992206847132", 10, MPFR_RNDN);
+ mpfr_div (q, n, d, MPFR_RNDU);
+
+ mpfr_set_ui (c, 1, MPFR_RNDN);
+ if (mpfr_cmp (q, c) != 0)
+ {
+ printf ("Error in test_20070603\nGot ");
+ mpfr_dump (q);
+ printf ("instead of ");
+ mpfr_dump (c);
+ exit (1);
+ }
+
+ /* same for 64-bit machines */
+ mpfr_set_prec (n, 256);
+ mpfr_set_prec (d, 256);
+ mpfr_set_prec (q, 63);
+ mpfr_set_str (n, "822752278660603021077484591278675252491367930877209729029898240", 10, MPFR_RNDN);
+ mpfr_set_str (d, "822752278660603021077484591278675252491367930877212507873738752", 10, MPFR_RNDN);
+ mpfr_div (q, n, d, MPFR_RNDU);
+ if (mpfr_cmp (q, c) != 0)
+ {
+ printf ("Error in test_20070603\nGot ");
+ mpfr_dump (q);
+ printf ("instead of ");
+ mpfr_dump (c);
+ exit (1);
+ }
+
+ mpfr_clear (n);
+ mpfr_clear (d);
+ mpfr_clear (q);
+ mpfr_clear (c);
+}
+
+/* Bug found while adding tests for mpfr_cot */
+static void
+test_20070628 (void)
+{
+ mpfr_exp_t old_emax;
+ mpfr_t x, y;
+ int inex, err = 0;
+
+ old_emax = mpfr_get_emax ();
+
+ if (mpfr_set_emax (256))
+ {
+ printf ("Can't change exponent range\n");
+ exit (1);
+ }
+
+ mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_set_si_2exp (y, 1, -256, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_div (x, x, y, MPFR_RNDD);
+ if (MPFR_SIGN (x) >= 0 || ! mpfr_inf_p (x))
+ {
+ printf ("Error in test_20070628: expected -Inf, got\n");
+ mpfr_dump (x);
+ err++;
+ }
+ if (inex >= 0)
+ {
+ printf ("Error in test_20070628: expected inex < 0, got %d\n", inex);
+ err++;
+ }
+ if (! mpfr_overflow_p ())
+ {
+ printf ("Error in test_20070628: overflow flag is not set\n");
+ err++;
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+ mpfr_set_emax (old_emax);
+}
+
+#define TEST_FUNCTION test_div
+#define TWO_ARGS
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_inexact ();
+ check_hard ();
+ check_special ();
+ check_lowr ();
+ check_float (); /* checks single precision */
+ check_double ();
+ check_convergence ();
+ check_64 ();
+
+ check4("4.0","4.503599627370496e15", MPFR_RNDZ, 62,
+ "0.10000000000000000000000000000000000000000000000000000000000000E-49");
+ check4("1.0","2.10263340267725788209e+187", MPFR_RNDU, 65,
+ "0.11010011111001101011111001100111110100000001101001111100111000000E-622");
+ check4("2.44394909079968374564e-150", "2.10263340267725788209e+187",MPFR_RNDU,
+ 65,
+ "0.11010011111001101011111001100111110100000001101001111100111000000E-1119");
+
+ consistency ();
+ test_20070603 ();
+ test_20070628 ();
+ test_generic (2, 800, 50);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tdiv_d.c b/mpfr/tests/tdiv_d.c
new file mode 100644
index 0000000000..d0ef13513c
--- /dev/null
+++ b/mpfr/tests/tdiv_d.c
@@ -0,0 +1,155 @@
+/* Test file for mpfr_div_d
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+ int inexact;
+
+ mpfr_init2 (x, 123);
+ mpfr_init2 (y, 123);
+
+ /* nan / 1.0 is nan */
+ mpfr_set_nan (x);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* +inf / 1.0 == +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ /* -inf / 1.0 == -inf */
+ mpfr_set_inf (x, -1);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ /* 0.0 / 0.0 is nan */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* 1.0 / 0.0 == +inf */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ /* -1.0 / 0.0 == -inf */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 0.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_sub_d
+#define DOUBLE_ARG2
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_t x, y, z;
+ double d;
+ int inexact;
+
+ tests_start_mpfr ();
+
+ /* check with enough precision */
+ mpfr_init2 (x, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (y, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (z, IEEE_DBL_MANT_DIG);
+
+ mpfr_set_str (y, "4096", 10, MPFR_RNDN);
+ d = 0.125;
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (x, y, d, MPFR_RNDN);
+ if (inexact != 0)
+ {
+ printf ("Inexact flag error in mpfr_div_d\n");
+ exit (1);
+ }
+ mpfr_set_str (z, "32768", 10, MPFR_RNDN);
+ if (mpfr_cmp (z, x))
+ {
+ printf ("Error in mpfr_div_d (");
+ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
+ printf (" + %.20g)\nexpected ", d);
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+
+ check_nans ();
+
+ test_generic (2, 1000, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tdiv_ui.c b/mpfr/tests/tdiv_ui.c
new file mode 100644
index 0000000000..dcaf342d22
--- /dev/null
+++ b/mpfr/tests/tdiv_ui.c
@@ -0,0 +1,237 @@
+/* Test file for mpfr_div_ui.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+static void
+check (const char *ds, unsigned long u, mpfr_rnd_t rnd, const char *es)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+ mpfr_set_str1 (x, ds);
+ mpfr_div_ui (y, x, u, rnd);
+ if (mpfr_cmp_str1 (y, es))
+ {
+ printf ("mpfr_div_ui failed for x=%s, u=%lu, rnd=%s\n", ds, u,
+ mpfr_print_rnd_mode (rnd));
+ printf ("expected result is %s, got", es);
+ mpfr_out_str(stdout, 10, 0, y, MPFR_RNDN);
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ unsigned xprec, yprec;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_div_ui (y, x, 3, MPFR_RNDN);
+
+ mpfr_set_prec (x, 100);
+ mpfr_set_prec (y, 100);
+ mpfr_urandomb (x, RANDS);
+ mpfr_div_ui (y, x, 123456, MPFR_RNDN);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_div_ui (y, x, 123456789, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0))
+ {
+ printf ("mpfr_div_ui gives non-zero for 0/ui\n");
+ exit (1);
+ }
+
+ /* bug found by Norbert Mueller, 21 Aug 2001 */
+ mpfr_set_prec (x, 110);
+ mpfr_set_prec (y, 60);
+ mpfr_set_str_binary (x, "0.110101110011111110011111001110011001110111000000111110001000111011000011E-44");
+ mpfr_div_ui (y, x, 17, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.11001010100101100011101110000001100001010110101001010011011E-48");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in x/17 for x=1/16!\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ /* corner case */
+ mpfr_set_prec (x, 2 * mp_bits_per_limb);
+ mpfr_set_prec (y, 2);
+ mpfr_set_ui (x, 4, MPFR_RNDN);
+ mpfr_nextabove (x);
+ mpfr_div_ui (y, x, 2, MPFR_RNDN); /* exactly in the middle */
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 2) == 0);
+
+ mpfr_set_prec (x, 3 * mp_bits_per_limb);
+ mpfr_set_prec (y, 2);
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_nextabove (x);
+ mpfr_div_ui (y, x, 2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
+
+ mpfr_set_prec (x, 3 * mp_bits_per_limb);
+ mpfr_set_prec (y, 2);
+ mpfr_set_si (x, -4, MPFR_RNDN);
+ mpfr_nextbelow (x);
+ mpfr_div_ui (y, x, 2, MPFR_RNDD);
+ MPFR_ASSERTN(mpfr_cmp_si (y, -3) == 0);
+
+ for (xprec = 53; xprec <= 128; xprec++)
+ {
+ mpfr_set_prec (x, xprec);
+ mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2");
+ for (yprec = 53; yprec <= 128; yprec++)
+ {
+ mpfr_set_prec (y, yprec);
+ mpfr_div_ui (y, x, 1, MPFR_RNDN);
+ if (mpfr_cmp(x,y))
+ {
+ printf ("division by 1.0 fails for xprec=%u, yprec=%u\n", xprec, yprec);
+ printf ("expected "); mpfr_print_binary (x); puts ("");
+ printf ("got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ }
+ }
+
+ /* Bug reported by Mark Dickinson, 6 Nov 2007 */
+ mpfr_set_si (x, 0, MPFR_RNDN);
+ mpfr_set_si (y, -1, MPFR_RNDN);
+ mpfr_div_ui (y, x, 4, MPFR_RNDN);
+ MPFR_ASSERTN(MPFR_IS_ZERO(y) && MPFR_IS_POS(y));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+check_inexact (void)
+{
+ mpfr_t x, y, z;
+ mpfr_prec_t px, py;
+ int inexact, cmp;
+ unsigned long int u;
+ int rnd;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ for (px=2; px<300; px++)
+ {
+ mpfr_set_prec (x, px);
+ mpfr_urandomb (x, RANDS);
+ do
+ {
+ u = randlimb ();
+ }
+ while (u == 0);
+ for (py=2; py<300; py++)
+ {
+ mpfr_set_prec (y, py);
+ mpfr_set_prec (z, py + mp_bits_per_limb);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ inexact = mpfr_div_ui (y, x, u, (mpfr_rnd_t) rnd);
+ if (mpfr_mul_ui (z, y, u, (mpfr_rnd_t) rnd))
+ {
+ printf ("z <- y * u should be exact for u=%lu\n", u);
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ printf ("z="); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+ cmp = mpfr_cmp (z, x);
+ if (((inexact == 0) && (cmp != 0)) ||
+ ((inexact > 0) && (cmp <= 0)) ||
+ ((inexact < 0) && (cmp >= 0)))
+ {
+ printf ("Wrong inexact flag for u=%lu, rnd=%s\n", u,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+#define TEST_FUNCTION mpfr_div_ui
+#define INTEGER_TYPE unsigned long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric_ui.c"
+
+int
+main (int argc, char **argv)
+{
+ mpfr_t x;
+
+ tests_start_mpfr ();
+
+ special ();
+
+ check_inexact ();
+
+ check("1.0", 3, MPFR_RNDN, "3.3333333333333331483e-1");
+ check("1.0", 3, MPFR_RNDZ, "3.3333333333333331483e-1");
+ check("1.0", 3, MPFR_RNDU, "3.3333333333333337034e-1");
+ check("1.0", 3, MPFR_RNDD, "3.3333333333333331483e-1");
+ check("1.0", 2116118, MPFR_RNDN, "4.7256343927890600483e-7");
+ check("1.098612288668109782", 5, MPFR_RNDN, "0.21972245773362195087");
+
+ mpfr_init2 (x, 53);
+ mpfr_set_ui (x, 3, MPFR_RNDD);
+ mpfr_log (x, x, MPFR_RNDD);
+ mpfr_div_ui (x, x, 5, MPFR_RNDD);
+ if (mpfr_cmp_str1 (x, "0.21972245773362189536"))
+ {
+ printf ("Error in mpfr_div_ui for x=ln(3), u=5\n");
+ exit (1);
+ }
+ mpfr_clear (x);
+
+ test_generic_ui (2, 200, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/teint.c b/mpfr/tests/teint.c
new file mode 100644
index 0000000000..4394e29f3f
--- /dev/null
+++ b/mpfr/tests/teint.c
@@ -0,0 +1,216 @@
+/* Test file for mpfr_eint.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_eint
+#define TEST_RANDOM_POS 8
+#define TEST_RANDOM_EMAX 40
+#include "tgeneric.c"
+
+static void
+check_specials (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ mpfr_eint (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: eint(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_eint (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && mpfr_sgn (y) > 0))
+ {
+ printf ("Error: eint(+Inf) != +Inf\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_eint (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: eint(-Inf) != NaN\n");
+ exit (1);
+ }
+
+ /* eint(+/-0) = -Inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_eint (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0))
+ {
+ printf ("Error: eint(+0) != -Inf\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_eint (y, x, MPFR_RNDN);
+ if (! (mpfr_inf_p (y) && mpfr_sgn (y) < 0))
+ {
+ printf ("Error: eint(-0) != -Inf\n");
+ exit (1);
+ }
+
+ /* eint(x) = NaN for x < 0 */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_eint (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: eint(-1) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 17);
+ mpfr_set_prec (y, 17);
+ mpfr_set_str_binary (x, "1.0111110100100110e-2");
+ mpfr_set_str_binary (y, "-1.0010101001110100e-10");
+ mpfr_eint (x, x, MPFR_RNDZ);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for x=1.0111110100100110e-2, MPFR_RNDZ\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "0.10E4");
+ mpfr_eint (x, x, MPFR_RNDN);
+ mpfr_set_str (y, "440.37989953483827", 10, MPFR_RNDN);
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for x=0.10E4, MPFR_RNDZ\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 63);
+ mpfr_set_prec (y, 63);
+ mpfr_set_str_binary (x, "1.01111101011100111000011010001000101101011000011001111101011010e-2");
+ mpfr_eint (x, x, MPFR_RNDZ);
+ mpfr_set_str_binary (y, "1.11010110001101000001010010000100001111001000100100000001011100e-17");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error (1) for MPFR_RNDZ\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ /* check large x */
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "1E6");
+ mpfr_eint (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "10100011110001101001110000110010111000100111010001E37");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for x=2^6, MPFR_RNDN\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "1E7");
+ mpfr_eint (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "11001100100011110000101001011010110111111011110011E128");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for x=2^7, MPFR_RNDN\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "1E8");
+ mpfr_eint (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "1010000110000101111111011011000101001000101011101001E310");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for x=2^8, MPFR_RNDN\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "1E9");
+ mpfr_eint (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "11001010101000001010101101110000010110011101110010101E677");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for x=2^9, MPFR_RNDN\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "1E10");
+ mpfr_eint (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "10011111111010010110110101101000101100101010101101101E1415");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for x=2^10, MPFR_RNDN\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ if (argc != 1) /* teint x [prec] */
+ {
+ mpfr_t x;
+ mpfr_prec_t p;
+ p = (argc < 3) ? 53 : atoi (argv[2]);
+ mpfr_init2 (x, p);
+ mpfr_set_str (x, argv[1], 10, MPFR_RNDN);
+ printf ("eint(");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf (")=");
+ mpfr_eint (x, x, MPFR_RNDN);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ mpfr_clear (x);
+ }
+ else
+ {
+ check_specials ();
+
+ test_generic (2, 100, 100);
+ }
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/teq.c b/mpfr/tests/teq.c
new file mode 100644
index 0000000000..5543655848
--- /dev/null
+++ b/mpfr/tests/teq.c
@@ -0,0 +1,208 @@
+/* Test file for mpfr_eq.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+teq (mpfr_t x)
+{
+ mpfr_t y;
+ unsigned long k, px, mx;
+
+ mpfr_init2 (y, MPFR_PREC(x));
+
+ mx = (MPFR_PREC(x) - 1) / mp_bits_per_limb;
+ px = mp_bits_per_limb - 2;
+
+ for (k = 2; k < MPFR_PREC(x); k++)
+ {
+ mpfr_set (y, x, MPFR_RNDN);
+
+ MPFR_MANT(y) [mx] ^= (mp_limb_t) 1 << px;
+
+ if (mpfr_eq(y, x, k) || !mpfr_eq(y, x, k - 1))
+ {
+ printf ("Error in eq.\n");
+ printf ("x = "); mpfr_print_binary (x); printf ("\n");
+ printf ("y = "); mpfr_print_binary (y); printf ("\n");
+ printf ("k = %lu\n", k);
+ printf ("mpfr_eq(y, x, k) = %d\nmpfr_eq(y, x, k - 1) = %d\n",
+ mpfr_eq (y, x, k), mpfr_eq (y, x, k - 1));
+ exit (1);
+ }
+
+ if (px)
+ {
+ --px;
+ }
+ else
+ {
+ --mx;
+ px = mp_bits_per_limb - 1;
+ }
+ }
+ mpfr_clear (y);
+}
+
+static void
+special (void)
+{
+ mpfr_t x, y, z;
+ int i, error = 0;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+ mpfr_init2 (z, 53);
+
+ mpfr_set_str (x, "1", 10, (mpfr_rnd_t) 0);
+ mpfr_set_str (y, "1e-10000", 10, (mpfr_rnd_t) 0);
+ mpfr_add (z, x, y, MPFR_RNDU);
+
+ for (i = 1; i <= 52; i++)
+ if (mpfr_eq (x, z, i) == 0)
+ error = 1;
+ for (i = 53; i <= 100; i++)
+ if (mpfr_eq (x, z, i) != 0)
+ error = 1;
+ if (mpfr_eq (x, z, 1000) != 0)
+ error = 1;
+
+ if (error)
+ {
+ printf ("Error in mpfr_eq (1, 1+1e-1000)\n");
+ exit (1);
+ }
+
+ mpfr_set_nan (x);
+ mpfr_set_nan (y);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0);
+
+ mpfr_set_inf (y, 1);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0);
+
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0);
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, 1);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1));
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, -1);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0);
+
+ mpfr_set_inf (x, -1);
+ mpfr_set_inf (y, -1);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1));
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0);
+ MPFR_ASSERTN(mpfr_eq (y, x, 1) == 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1));
+
+ mpfr_neg (y, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1));
+
+ mpfr_neg (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1));
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_neg (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0);
+
+ mpfr_set_prec (x, 2 * mp_bits_per_limb);
+ mpfr_set_prec (y, mp_bits_per_limb);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb - 1));
+ MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb));
+ MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb + 1));
+ MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb - 1));
+ MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb));
+ MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb + 1));
+
+ mpfr_nextabove (x);
+ MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb - 1));
+ MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb));
+ MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb + 1));
+ MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb - 1));
+ MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb) == 0);
+ MPFR_ASSERTN(mpfr_eq (x, y, 2 * mp_bits_per_limb + 1) == 0);
+ MPFR_ASSERTN(mpfr_eq (y, x, mp_bits_per_limb - 1));
+ MPFR_ASSERTN(mpfr_eq (y, x, mp_bits_per_limb));
+ MPFR_ASSERTN(mpfr_eq (y, x, mp_bits_per_limb + 1));
+ MPFR_ASSERTN(mpfr_eq (y, x, 2 * mp_bits_per_limb - 1));
+ MPFR_ASSERTN(mpfr_eq (y, x, 2 * mp_bits_per_limb) == 0);
+ MPFR_ASSERTN(mpfr_eq (y, x, 2 * mp_bits_per_limb + 1) == 0);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_ui (y, 2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1) == 0);
+
+ mpfr_set_prec (x, 2 * mp_bits_per_limb);
+ mpfr_set_prec (y, 2 * mp_bits_per_limb);
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_set_ui (y, 3, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_eq (x, y, 1));
+ MPFR_ASSERTN(mpfr_eq (x, y, 2) == 0);
+ MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb) == 0);
+ MPFR_ASSERTN(mpfr_eq (x, y, mp_bits_per_limb + 1) == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+int
+main (void)
+{
+ int j;
+ mpfr_t x;
+
+ tests_start_mpfr ();
+
+ special ();
+
+ mpfr_init2 (x, 500);
+
+ for (j = 0; j < 500; j++)
+ {
+ mpfr_urandomb (x, RANDS);
+ teq (x);
+ }
+
+ mpfr_clear (x);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/terf.c b/mpfr/tests/terf.c
new file mode 100644
index 0000000000..e8e5f8dbb6
--- /dev/null
+++ b/mpfr/tests/terf.c
@@ -0,0 +1,662 @@
+/* Test file for mpfr_erf and mpfr_erfc.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_erf
+#define test_generic test_generic_erf
+#include "tgeneric.c"
+
+#define TEST_FUNCTION mpfr_erfc
+#undef TEST_RANDOM_EMAX
+#define TEST_RANDOM_EMAX 63
+#define test_generic test_generic_erfc
+#include "tgeneric.c"
+
+static void
+special_erf (void)
+{
+ mpfr_t x, y;
+ int inex;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+
+ /* erf(NaN) = NaN */
+ mpfr_set_nan (x);
+ mpfr_erf (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("mpfr_erf failed for x=NaN\n");
+ exit (1);
+ }
+
+ /* erf(+Inf) = 1 */
+ mpfr_set_inf (x, 1);
+ mpfr_erf (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("mpfr_erf failed for x=+Inf\n");
+ printf ("expected 1.0, got ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ /* erf(-Inf) = -1 */
+ mpfr_set_inf (x, -1);
+ mpfr_erf (y, x, MPFR_RNDN);
+ if (mpfr_cmp_si (y, -1))
+ {
+ printf ("mpfr_erf failed for x=-Inf\n");
+ exit (1);
+ }
+
+ /* erf(+0) = +0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_erf (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("mpfr_erf failed for x=+0\n");
+ exit (1);
+ }
+
+ /* erf(-0) = -0 */
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_erf (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
+ {
+ printf ("mpfr_erf failed for x=-0\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_erf (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.11010111101110110011110100111010000010000100010001011");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("mpfr_erf failed for x=1.0, rnd=MPFR_RNDN\n");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ printf ("got ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_str (x, "6.6", 10, MPFR_RNDN);
+ mpfr_erf (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("mpfr_erf failed for x=6.6, rnd=MPFR_RNDN\n");
+ printf ("expected 1\n");
+ printf ("got ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_str (x, "-6.6", 10, MPFR_RNDN);
+ mpfr_erf (x, x, MPFR_RNDN);
+ if (mpfr_cmp_si (x, -1))
+ {
+ printf ("mpfr_erf failed for x=-6.6, rnd=MPFR_RNDN\n");
+ printf ("expected -1\n");
+ printf ("got ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_str (x, "6.6", 10, MPFR_RNDN);
+ mpfr_erf (x, x, MPFR_RNDZ);
+ mpfr_set_str_binary (y, "0.11111111111111111111111111111111111111111111111111111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("mpfr_erf failed for x=6.6, rnd=MPFR_RNDZ\n");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ printf ("got ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_str (x, "4.5", 10, MPFR_RNDN);
+ mpfr_erf (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.1111111111111111111111111111111100100111110100011");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("mpfr_erf failed for x=4.5, rnd=MPFR_RNDN\n");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ printf ("got ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 120);
+ mpfr_set_prec (y, 120);
+ mpfr_set_str_binary (x, "0.110100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011E3");
+ mpfr_erf (x, x, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.11111111111111111111111111111111111111111111111111111111111111111100111111000100111011111011010000110101111100011001101");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("mpfr_erf failed for x=6.6, rnd=MPFR_RNDN\n");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ printf ("got ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 8);
+ mpfr_set_prec (y, 8);
+ mpfr_set_ui (x, 50, MPFR_RNDN);
+ inex = mpfr_erf (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDN\n");
+ printf ("expected 1, got ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ if (inex <= 0)
+ {
+ printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDN: wrong ternary value\n"
+ "expected positive, got %d\n", inex);
+ exit (1);
+ }
+ inex = mpfr_erf (x, x, MPFR_RNDZ);
+ mpfr_nextbelow (y);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDZ\n");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ printf ("got ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ if (inex >= 0)
+ {
+ printf ("mpfr_erf failed for x=50, rnd=MPFR_RNDN: wrong ternary value\n"
+ "expected negative, got %d\n", inex);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+
+ mpfr_set_str_binary (x, "0.1010100100111011001111100101E-1");
+ mpfr_set_str_binary (y, "0.10111000001110011010110001101011E-1");
+ mpfr_erf (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for prec=32 (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "-0.10110011011010111110010001100001");
+ mpfr_set_str_binary (y, "-0.1010110110101011100010111000111");
+ mpfr_erf (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for prec=32 (2)\n");
+ mpfr_print_binary (x); printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "100.10001110011110100000110000111");
+ mpfr_set_str_binary (y, "0.11111111111111111111111111111111");
+ mpfr_erf (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for prec=32 (3)\n");
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "100.10001110011110100000110000111");
+ mpfr_erf (x, x, MPFR_RNDZ);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for prec=32 (4)\n");
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "100.10001110011110100000110000111");
+ mpfr_erf (x, x, MPFR_RNDU);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error: erf for prec=32 (5)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "100.10001110011110100000110001000");
+ mpfr_erf (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error: erf for prec=32 (6)\n");
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "100.10001110011110100000110001000");
+ mpfr_set_str_binary (y, "0.11111111111111111111111111111111");
+ mpfr_erf (x, x, MPFR_RNDZ);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for prec=32 (7)\n");
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "100.10001110011110100000110001000");
+ mpfr_erf (x, x, MPFR_RNDU);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error: erf for prec=32 (8)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 5, MPFR_RNDN);
+ mpfr_erf (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error: erf for prec=32 (9)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 5, MPFR_RNDN);
+ mpfr_erf (x, x, MPFR_RNDU);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error: erf for prec=32 (10)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 5, MPFR_RNDN);
+ mpfr_erf (x, x, MPFR_RNDZ);
+ mpfr_set_str_binary (y, "0.11111111111111111111111111111111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for prec=32 (11)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 5, MPFR_RNDN);
+ mpfr_erf (x, x, MPFR_RNDD);
+ mpfr_set_str_binary (y, "0.11111111111111111111111111111111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for prec=32 (12)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 43);
+ mpfr_set_prec (y, 64);
+ mpfr_set_str_binary (x, "-0.1101110110101111100101011101110101101001001e3");
+ mpfr_erf (y, x, MPFR_RNDU);
+ mpfr_set_prec (x, 64);
+ mpfr_set_str_binary (x, "-0.1111111111111111111111111111111111111111111111111111111111111111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for prec=43,64 (13)\n");
+ exit (1);
+ }
+
+ /* worst cases */
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "1.0000000000000000000000000000000000000110000000101101");
+ mpfr_erf (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.110101111011101100111101001110100000101011000011001");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for worst case (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "1.0000000000000000000000000000011000111010101101011010");
+ mpfr_erf (y, x, MPFR_RNDU);
+ mpfr_set_str_binary (x, "0.11010111101110110011110100111100100111100011111000110");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for worst case (2a)\n");
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "1.0000000000000000000000000000011000111010101101011010");
+ mpfr_erf (y, x, MPFR_RNDD);
+ mpfr_set_str_binary (x, "0.11010111101110110011110100111100100111100011111000101");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error: erf for worst case (2b)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+special_erfc (void)
+{
+ mpfr_t x, y;
+
+ mpfr_inits (x, y, (mpfr_ptr) 0);
+
+ /* erfc (NaN) = NaN */
+ mpfr_set_nan (x);
+ mpfr_erfc (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("mpfr_erfc failed for x=NaN\n");
+ exit (1);
+ }
+ /* erfc(+Inf) = 0+ */
+ mpfr_set_inf (x, 1);
+ mpfr_erfc (y, x, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y))
+ {
+ printf ("mpfr_erf failed for x=+Inf\n");
+ printf ("expected 0+, got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ /* erfc(-Inf) = 2 */
+ mpfr_set_inf (x, -1);
+ mpfr_erfc (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 2))
+ {
+ printf ("mpfr_erf failed for x=-Inf\n");
+ printf ("expected 2, got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ /* erf(+0) = 1 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_erfc (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("mpfr_erf failed for x=+0\n");
+ printf ("expected 1, got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+static void
+large_arg (void)
+{
+ mpfr_t x, y;
+ unsigned int flags;
+
+ mpfr_init2 (x, 88);
+ mpfr_init2 (y, 98);
+
+ mpfr_set_si_2exp (x, -1, 173, MPFR_RNDN);
+ mpfr_clear_flags ();
+ mpfr_erfc (y, x, MPFR_RNDN);
+ flags = __gmpfr_flags;
+ if (mpfr_cmp_ui (y, 2) != 0)
+ {
+ printf ("mpfr_erfc failed for large x (1)\n");
+ exit (1);
+ }
+ if (flags != MPFR_FLAGS_INEXACT)
+ {
+ printf ("mpfr_erfc sets incorrect flags for large x (1)\n");
+ printf ("Expected %u, got %u\n",
+ (unsigned int) MPFR_FLAGS_INEXACT, flags);
+ exit (1);
+ }
+
+ mpfr_set_si_2exp (x, -1, mpfr_get_emax () - 3, MPFR_RNDN);
+ mpfr_clear_flags ();
+ mpfr_erfc (y, x, MPFR_RNDN);
+ flags = __gmpfr_flags;
+ if (mpfr_cmp_ui (y, 2) != 0)
+ {
+ printf ("mpfr_erfc failed for large x (1b)\n");
+ exit (1);
+ }
+ if (flags != MPFR_FLAGS_INEXACT)
+ {
+ printf ("mpfr_erfc sets incorrect flags for large x (1b)\n");
+ printf ("Expected %u, got %u\n",
+ (unsigned int) MPFR_FLAGS_INEXACT, flags);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 33);
+ mpfr_set_prec (y, 43);
+ mpfr_set_str_binary (x, "1.11000101010111011000111100101001e6");
+ mpfr_erfc (y, x, MPFR_RNDD);
+ mpfr_set_prec (x, 43);
+ mpfr_set_str_binary (x, "100010011100101100001101100101011101101E-18579");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("mpfr_erfc failed for large x (2)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (y, 43);
+ mpfr_set_si_2exp (x, 1, 11, MPFR_RNDN);
+ mpfr_erfc (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1100000100100010101111001111010010001000110E-6051113");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("mpfr_erfc failed for large x (3)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 75);
+ mpfr_set_prec (y, 85);
+ mpfr_set_str_binary (x, "0.111110111111010011101011001100001010011110101010011111010010111101010001011E15");
+ mpfr_erfc (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("mpfr_erfc failed for large x (3b)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 21);
+ mpfr_set_str_binary (x, "-1.0e3");
+ mpfr_clear_flags ();
+ mpfr_erfc (y, x, MPFR_RNDZ);
+ flags = __gmpfr_flags;
+ mpfr_set_prec (x, 21);
+ mpfr_set_str_binary (x, "1.11111111111111111111");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("mpfr_erfc failed for large x (4)\n");
+ exit (1);
+ }
+ if (flags != MPFR_FLAGS_INEXACT)
+ {
+ printf ("mpfr_erfc sets incorrect flags for large x (4)\n");
+ printf ("Expected %u, got %u\n",
+ (unsigned int) MPFR_FLAGS_INEXACT, flags);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 31);
+ mpfr_set_str_binary (x, "-1.0e3");
+ mpfr_clear_flags ();
+ mpfr_erfc (y, x, MPFR_RNDZ);
+ flags = __gmpfr_flags;
+ mpfr_set_prec (x, 31);
+ mpfr_set_str_binary (x, "1.111111111111111111111111111111");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("mpfr_erfc failed for x=-8, prec=31 (5)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+ if (flags != MPFR_FLAGS_INEXACT)
+ {
+ printf ("mpfr_erfc sets incorrect flags for large x (5)\n");
+ printf ("Expected %u, got %u\n",
+ (unsigned int) MPFR_FLAGS_INEXACT, flags);
+ exit (1);
+ }
+
+ /* Reported by Christopher Creutzig on 2007-07-10. */
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_si_2exp (x, 54563, -1, MPFR_RNDN);
+ mpfr_erfc (y, x, MPFR_RNDZ);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ if (! mpfr_equal_p (y, x))
+ {
+ printf ("mpfr_erfc failed for x=27281.5, prec=53 (6)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ /* same test with rounding away from zero */
+ mpfr_set_si_2exp (x, 54563, -1, MPFR_RNDN);
+ mpfr_erfc (y, x, MPFR_RNDU);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_nextabove (x);
+ if (! mpfr_equal_p (y, x))
+ {
+ printf ("mpfr_erfc failed for x=27281.5, prec=53 (7)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+test_erfc (void)
+{
+ mpfr_t x, y, z;
+ int inex;
+ mpfr_exp_t emin;
+
+ mpfr_inits2 (40, x, y, z, (mpfr_ptr) 0);
+
+ mpfr_set_si_2exp (x, -1, -10, MPFR_RNDN);
+ mpfr_set_str_binary (z, "0.1000000000100100000110111010110111100000E1");
+ mpfr_erfc (y, x, MPFR_RNDN);
+ if (mpfr_cmp (y, z) != 0)
+ {
+ printf ("mpfr_erfc failed for x = ");
+ mpfr_dump (x);
+ printf ("got ");
+ mpfr_dump (y);
+ printf ("instead of ");
+ mpfr_dump (z);
+ exit (1);
+ }
+
+ /* slowness detected by Kevin Rauch on 26 Oct 2007 */
+ mpfr_set_prec (x, 128);
+ mpfr_set_si (x, -256, MPFR_RNDN);
+ inex = mpfr_erfc (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(inex > 0 && mpfr_cmp_ui (x, 2) == 0);
+
+ /* bug found by Pascal Molin on March 10, 2011 */
+ emin = mpfr_get_emin ();
+ if (! mpfr_set_emin (-1073808789))
+ {
+ /* Typically, a 64-bit machine. */
+ mpfr_set_si (x, 27282, MPFR_RNDN);
+ mpfr_erfc (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) != 0);
+ mpfr_set_emin (emin);
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+/* Failure in r7569 (2011-03-15) due to incorrect flags. */
+static void
+reduced_expo_range (void)
+{
+ mpfr_exp_t emax;
+ mpfr_t x, y, ex_y;
+ int inex, ex_inex;
+ unsigned int flags, ex_flags;
+
+ emax = mpfr_get_emax ();
+ mpfr_set_emax (3);
+ mpfr_init2 (x, 33);
+ mpfr_inits2 (110, y, ex_y, (mpfr_ptr) 0);
+ mpfr_set_str_binary (x, "-0.111100110111111111011101010101110E3");
+ mpfr_clear_flags ();
+ inex = mpfr_erfc (y, x, MPFR_RNDZ);
+ flags = __gmpfr_flags;
+ mpfr_set_str (ex_y, "1.fffffffffffffffffffffe607440", 16, MPFR_RNDN);
+ ex_inex = -1;
+ ex_flags = MPFR_FLAGS_INEXACT;
+ if (SIGN (inex) != ex_inex || flags != ex_flags ||
+ ! mpfr_equal_p (y, ex_y))
+ {
+ printf ("Error in reduced_expo_range\non x = ");
+ mpfr_dump (x);
+ printf ("Expected y = ");
+ mpfr_out_str (stdout, 16, 0, ex_y, MPFR_RNDN);
+ printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags);
+ printf ("Got y = ");
+ mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
+ printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags);
+ exit (1);
+ }
+ mpfr_clears (x, y, ex_y, (mpfr_ptr) 0);
+ mpfr_set_emax (emax);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special_erf ();
+ special_erfc ();
+ large_arg ();
+ test_erfc ();
+ reduced_expo_range ();
+
+ test_generic_erf (2, 100, 15);
+ test_generic_erfc (2, 100, 15);
+
+ data_check ("data/erf", mpfr_erf, "mpfr_erf");
+ data_check ("data/erfc", mpfr_erfc, "mpfr_erfc");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tests.c b/mpfr/tests/tests.c
new file mode 100644
index 0000000000..ef3f0ef654
--- /dev/null
+++ b/mpfr/tests/tests.c
@@ -0,0 +1,958 @@
+/* Miscellaneous support for test programs.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# if HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+# endif
+#endif
+
+#include <stdlib.h>
+#include <float.h>
+#include <errno.h>
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#ifdef MPFR_TEST_DIVBYZERO
+# include <fenv.h>
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h> /* for struct timeval */
+# include <time.h>
+#elif defined HAVE_SYS_TIME_H
+# include <sys/time.h>
+#else
+# include <time.h>
+#endif
+
+/* <sys/fpu.h> is needed to have union fpc_csr defined under IRIX64
+ (see below). Let's include it only if need be. */
+#if defined HAVE_SYS_FPU_H && defined HAVE_FPC_CSR
+# include <sys/fpu.h>
+#endif
+
+#ifdef MPFR_TESTS_TIMEOUT
+#include <sys/resource.h>
+#endif
+
+#include "mpfr-test.h"
+
+#ifdef MPFR_FPU_PREC
+/* This option allows to test MPFR on x86 processors when the FPU
+ * rounding precision has been changed. As MPFR is a library, this can
+ * occur in practice, either by the calling software or by some other
+ * library or plug-in used by the calling software. This option is
+ * mainly for developers. If it is used, then the <fpu_control.h>
+ * header is assumed to exist and work like under Linux/x86. MPFR does
+ * not need to be recompiled. So, a possible usage is the following:
+ *
+ * cd tests
+ * make clean
+ * make check CFLAGS="-g -O2 -ffloat-store -DMPFR_FPU_PREC=_FPU_SINGLE"
+ *
+ * i.e. just add -DMPFR_FPU_PREC=... to the CFLAGS found in Makefile.
+ *
+ * Notes:
+ * + SSE2 (used to implement double's on x86_64, and possibly on x86
+ * too, depending on the compiler configuration and flags) is not
+ * affected by the dynamic precision.
+ * + When the FPU is set to single precision, the behavior of MPFR
+ * functions that have a native floating-point type (float, double,
+ * long double) as argument or return value is not guaranteed.
+ */
+
+#include <fpu_control.h>
+
+static void
+set_fpu_prec (void)
+{
+ fpu_control_t cw;
+
+ _FPU_GETCW(cw);
+ cw &= ~(_FPU_EXTENDED|_FPU_DOUBLE|_FPU_SINGLE);
+ cw |= (MPFR_FPU_PREC);
+ _FPU_SETCW(cw);
+}
+
+#endif
+
+static mpfr_exp_t default_emin, default_emax;
+
+static void tests_rand_start (void);
+static void tests_rand_end (void);
+static void tests_limit_start (void);
+
+/* We want to always import the function mpfr_dump inside the test
+ suite, so that we can use it in GDB. But it doesn't work if we build
+ a Windows DLL (initializer element is not a constant) */
+#if !__GMP_LIBGMP_DLL
+extern void (*dummy_func) (mpfr_srcptr);
+void (*dummy_func)(mpfr_srcptr) = mpfr_dump;
+#endif
+
+void
+test_version (void)
+{
+ const char *version;
+
+ /* VL: I get the following error on an OpenSUSE machine, and changing
+ the value of shlibpath_overrides_runpath in the libtool file from
+ 'no' to 'yes' fixes the problem. */
+
+ version = mpfr_get_version ();
+ if (strcmp (MPFR_VERSION_STRING, version) == 0)
+ {
+ char buffer[16];
+ int i;
+
+ sprintf (buffer, "%d.%d.%d", MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR,
+ MPFR_VERSION_PATCHLEVEL);
+ for (i = 0; buffer[i] == version[i]; i++)
+ if (buffer[i] == '\0')
+ return;
+ if (buffer[i] == '\0' && version[i] == '-')
+ return;
+ printf ("MPFR_VERSION_MAJOR.MPFR_VERSION_MINOR.MPFR_VERSION_PATCHLEVEL"
+ " (%s)\nand MPFR_VERSION_STRING (%s) do not match!\nIt seems "
+ "that the mpfr.h file has been corrupted.\n", buffer, version);
+ exit (1);
+ }
+
+ printf ("Incorrect MPFR version! (%s header vs %s library)\n"
+ "Nothing else has been tested since for this reason,\n"
+ "any other test may fail. Please fix this one first.\n\n"
+ "You can try to avoid this problem by changing the value of\n"
+ "shlibpath_overrides_runpath in the libtool file and rebuild\n"
+ "MPFR (make clean && make && make check).\n"
+ "Otherwise this error may be due to a corrupted mpfr.h, an\n"
+ "incomplete build (try to rebuild MPFR from scratch and/or\n"
+ "use 'make clean'), or something wrong in the system.\n",
+ MPFR_VERSION_STRING, version);
+ exit (1);
+}
+
+void
+tests_start_mpfr (void)
+{
+ test_version ();
+
+ /* don't buffer, so output is not lost if a test causes a segv etc */
+ setbuf (stdout, NULL);
+
+#if defined HAVE_LOCALE_H && defined HAVE_SETLOCALE
+ /* Added on 2005-07-09. This allows to test MPFR under various
+ locales. New bugs will probably be found, in particular with
+ LC_ALL="tr_TR.ISO8859-9" because of the i/I character... */
+ setlocale (LC_ALL, "");
+#endif
+
+#ifdef MPFR_FPU_PREC
+ set_fpu_prec ();
+#endif
+
+#ifdef MPFR_TEST_DIVBYZERO
+ /* Define to test the use of MPFR_ERRDIVZERO */
+ feclearexcept (FE_ALL_EXCEPT);
+#endif
+
+ tests_memory_start ();
+ tests_rand_start ();
+ tests_limit_start ();
+
+ default_emin = mpfr_get_emin ();
+ default_emax = mpfr_get_emax ();
+}
+
+void
+tests_end_mpfr (void)
+{
+ int err = 0;
+
+ if (mpfr_get_emin () != default_emin)
+ {
+ printf ("Default emin value has not been restored!\n");
+ err = 1;
+ }
+
+ if (mpfr_get_emax () != default_emax)
+ {
+ printf ("Default emax value has not been restored!\n");
+ err = 1;
+ }
+
+ mpfr_free_cache ();
+ tests_rand_end ();
+ tests_memory_end ();
+
+#ifdef MPFR_TEST_DIVBYZERO
+ /* Define to test the use of MPFR_ERRDIVZERO */
+ if (fetestexcept (FE_DIVBYZERO|FE_INVALID))
+ {
+ printf ("A floating-point division by 0 or an invalid operation"
+ " occurred!\n");
+#ifdef MPFR_ERRDIVZERO
+ /* This should never occur because the purpose of defining
+ MPFR_ERRDIVZERO is to avoid all the FP divisions by 0. */
+ err = 1;
+#endif
+ }
+#endif
+
+ if (err)
+ exit (err);
+}
+
+static void
+tests_limit_start (void)
+{
+#ifdef MPFR_TESTS_TIMEOUT
+ struct rlimit rlim[1];
+ char *timeoutp;
+ int timeout;
+
+ timeoutp = getenv ("MPFR_TESTS_TIMEOUT");
+ timeout = timeoutp != NULL ? atoi (timeoutp) : MPFR_TESTS_TIMEOUT;
+ if (timeout > 0)
+ {
+ /* We need to call getrlimit first to initialize rlim_max to
+ an acceptable value for setrlimit. When enabled, timeouts
+ are regarded as important: we don't want to take too much
+ CPU time on machines shared with other users. So, if we
+ can't set the timeout, we exit immediately. */
+ if (getrlimit (RLIMIT_CPU, rlim))
+ {
+ printf ("Error: getrlimit failed\n");
+ exit (1);
+ }
+ rlim->rlim_cur = timeout;
+ if (setrlimit (RLIMIT_CPU, rlim))
+ {
+ printf ("Error: setrlimit failed\n");
+ exit (1);
+ }
+ }
+#endif
+}
+
+static void
+tests_rand_start (void)
+{
+ gmp_randstate_ptr rands;
+ char *perform_seed;
+ unsigned long seed;
+
+ if (__gmp_rands_initialized)
+ {
+ printf (
+ "Please let tests_start() initialize the global __gmp_rands, i.e.\n"
+ "ensure that function is called before the first use of RANDS.\n");
+ exit (1);
+ }
+
+ gmp_randinit_default (__gmp_rands);
+ __gmp_rands_initialized = 1;
+ rands = __gmp_rands;
+
+ perform_seed = getenv ("GMP_CHECK_RANDOMIZE");
+ if (perform_seed != NULL)
+ {
+ seed = strtoul (perform_seed, NULL, 10);
+ if (! (seed == 0 || seed == 1))
+ {
+ printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed);
+ gmp_randseed_ui (rands, seed);
+ }
+ else
+ {
+#ifdef HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ seed = tv.tv_sec + tv.tv_usec;
+#else
+ time_t tv;
+ time (&tv);
+ seed = tv;
+#endif
+ gmp_randseed_ui (rands, seed);
+ printf ("Seed GMP_CHECK_RANDOMIZE=%lu "
+ "(include this in bug reports)\n", seed);
+ }
+ }
+ else
+ gmp_randseed_ui (rands, 0x2143FEDC);
+}
+
+static void
+tests_rand_end (void)
+{
+ RANDS_CLEAR ();
+}
+
+/* initialization function for tests using the hardware floats
+ Not very useful now. */
+void
+mpfr_test_init (void)
+{
+ double d;
+#ifdef HAVE_FPC_CSR
+ /* to get denormalized numbers on IRIX64 */
+ union fpc_csr exp;
+
+ exp.fc_word = get_fpc_csr();
+ exp.fc_struct.flush = 0;
+ set_fpc_csr(exp.fc_word);
+#endif
+#ifdef HAVE_DENORMS
+ d = DBL_MIN;
+ if (2.0 * (d / 2.0) != d)
+ {
+ printf ("Error: HAVE_DENORMS defined, but no subnormals.\n");
+ exit (1);
+ }
+#endif
+
+ /* generate DBL_EPSILON with a loop to avoid that the compiler
+ optimizes the code below in non-IEEE 754 mode, deciding that
+ c = d is always false. */
+#if 0
+ for (eps = 1.0; eps != DBL_EPSILON; eps /= 2.0);
+ c = 1.0 + eps;
+ d = eps * (1.0 - eps) / 2.0;
+ d += c;
+ if (c != d)
+ {
+ printf ("Warning: IEEE 754 standard not fully supported\n"
+ " (maybe extended precision not disabled)\n"
+ " Some tests may fail\n");
+ }
+#endif
+}
+
+
+/* generate a random limb */
+mp_limb_t
+randlimb (void)
+{
+ mp_limb_t limb;
+
+ mpfr_rand_raw (&limb, RANDS, GMP_NUMB_BITS);
+ return limb;
+}
+
+/* returns ulp(x) for x a 'normal' double-precision number */
+double
+Ulp (double x)
+{
+ double y, eps;
+
+ if (x < 0) x = -x;
+
+ y = x * 2.220446049250313080847263336181640625e-16 ; /* x / 2^52 */
+
+ /* as ulp(x) <= y = x/2^52 < 2*ulp(x),
+ we have x + ulp(x) <= x + y <= x + 2*ulp(x),
+ therefore o(x + y) = x + ulp(x) or x + 2*ulp(x) */
+
+ eps = x + y;
+ eps = eps - x; /* ulp(x) or 2*ulp(x) */
+
+ return (eps > y) ? 0.5 * eps : eps;
+}
+
+/* returns the number of ulp's between a and b,
+ where a and b can be any floating-point number, except NaN
+ */
+int
+ulp (double a, double b)
+{
+ double twoa;
+
+ if (a == b) return 0; /* also deals with a=b=inf or -inf */
+
+ twoa = a + a;
+ if (twoa == a) /* a is +/-0.0 or +/-Inf */
+ return ((b < a) ? INT_MAX : -INT_MAX);
+
+ return (int) ((a - b) / Ulp (a));
+}
+
+/* return double m*2^e */
+double
+dbl (double m, int e)
+{
+ if (e >=0 )
+ while (e-- > 0)
+ m *= 2.0;
+ else
+ while (e++ < 0)
+ m /= 2.0;
+ return m;
+}
+
+/* Warning: NaN values cannot be distinguished if MPFR_NANISNAN is defined. */
+int
+Isnan (double d)
+{
+ return (d) != (d);
+}
+
+void
+d_trace (const char *name, double d)
+{
+ union {
+ double d;
+ unsigned char b[sizeof(double)];
+ } u;
+ int i;
+
+ if (name != NULL && name[0] != '\0')
+ printf ("%s=", name);
+
+ u.d = d;
+ printf ("[");
+ for (i = 0; i < (int) sizeof (u.b); i++)
+ {
+ if (i != 0)
+ printf (" ");
+ printf ("%02X", (int) u.b[i]);
+ }
+ printf ("] %.20g\n", d);
+}
+
+void
+ld_trace (const char *name, long double ld)
+{
+ union {
+ long double ld;
+ unsigned char b[sizeof(long double)];
+ } u;
+ int i;
+
+ if (name != NULL && name[0] != '\0')
+ printf ("%s=", name);
+
+ u.ld = ld;
+ printf ("[");
+ for (i = 0; i < (int) sizeof (u.b); i++)
+ {
+ if (i != 0)
+ printf (" ");
+ printf ("%02X", (int) u.b[i]);
+ }
+ printf ("] %.20Lg\n", ld);
+}
+
+/* Open a file in the src directory - can't use fopen directly */
+FILE *
+src_fopen (const char *filename, const char *mode)
+{
+#ifndef SRCDIR
+ return fopen (filename, mode);
+#else
+ const char *srcdir = SRCDIR;
+ char *buffer;
+ size_t buffsize;
+ FILE *f;
+
+ buffsize = strlen (filename) + strlen (srcdir) + 2;
+ buffer = (char *) (*__gmp_allocate_func) (buffsize);
+ if (buffer == NULL)
+ {
+ printf ("src_fopen: failed to alloc memory)\n");
+ exit (1);
+ }
+ sprintf (buffer, "%s/%s", srcdir, filename);
+ f = fopen (buffer, mode);
+ (*__gmp_free_func) (buffer, buffsize);
+ return f;
+#endif
+}
+
+void
+set_emin (mpfr_exp_t exponent)
+{
+ if (mpfr_set_emin (exponent))
+ {
+ printf ("set_emin: setting emin to %ld failed\n", (long int) exponent);
+ exit (1);
+ }
+}
+
+void
+set_emax (mpfr_exp_t exponent)
+{
+ if (mpfr_set_emax (exponent))
+ {
+ printf ("set_emax: setting emax to %ld failed\n", (long int) exponent);
+ exit (1);
+ }
+}
+
+/* pos is 512 times the proportion of negative numbers.
+ If pos=256, half of the numbers are negative.
+ If pos=0, all generated numbers are positive.
+*/
+void
+tests_default_random (mpfr_ptr x, int pos, mpfr_exp_t emin, mpfr_exp_t emax)
+{
+ MPFR_ASSERTN (emin <= emax);
+ MPFR_ASSERTN (emin >= MPFR_EMIN_MIN);
+ MPFR_ASSERTN (emax <= MPFR_EMAX_MAX);
+ /* but it isn't required that emin and emax are in the current
+ exponent range (see below), so that underflow/overflow checks
+ can be done on 64-bit machines. */
+
+ mpfr_urandomb (x, RANDS);
+ if (MPFR_IS_PURE_FP (x) && (emin >= 1 || (randlimb () & 1)))
+ {
+ mpfr_exp_t e;
+ e = MPFR_GET_EXP (x) +
+ (emin + (long) (randlimb () % (emax - emin + 1)));
+ /* Note: There should be no overflow here because both terms are
+ between MPFR_EMIN_MIN and MPFR_EMAX_MAX, but the sum e isn't
+ necessarily between MPFR_EMIN_MIN and MPFR_EMAX_MAX. */
+ if (mpfr_set_exp (x, e))
+ {
+ /* The random number doesn't fit in the current exponent range.
+ In this case, test the function in the extended exponent range,
+ which should be restored by the caller. */
+ mpfr_set_emin (MPFR_EMIN_MIN);
+ mpfr_set_emax (MPFR_EMAX_MAX);
+ mpfr_set_exp (x, e);
+ }
+ }
+ if (randlimb () % 512 < pos)
+ mpfr_neg (x, x, MPFR_RNDN);
+}
+
+/* The test_one argument is seen a boolean. If it is true and rnd is
+ a rounding mode toward infinity, then the function is tested in
+ only one rounding mode (the one provided in rnd) and the variable
+ rndnext is not used (due to the break). If it is true and rnd is a
+ rounding mode toward or away from zero, then the function is tested
+ twice, first with the provided rounding mode and second with the
+ rounding mode toward the corresponding infinity (determined by the
+ sign of the result). If it is false, then the function is tested
+ in the 5 rounding modes, and rnd must initially be MPFR_RNDZ; thus
+ rndnext will be initialized in the first iteration.
+ If the test_one argument is 2, then this means that y is exact, and
+ the ternary value is checked.
+ As examples of use, see the calls to test5rm from the data_check and
+ bad_cases functions. */
+static void
+test5rm (int (*fct) (FLIST), mpfr_srcptr x, mpfr_ptr y, mpfr_ptr z,
+ mpfr_rnd_t rnd, int test_one, const char *name)
+{
+ mpfr_prec_t yprec = MPFR_PREC (y);
+ mpfr_rnd_t rndnext = MPFR_RND_MAX; /* means uninitialized */
+
+ MPFR_ASSERTN (test_one || rnd == MPFR_RNDZ);
+ mpfr_set_prec (z, yprec);
+ while (1)
+ {
+ int inex;
+
+ MPFR_ASSERTN (rnd != MPFR_RND_MAX);
+ inex = fct (z, x, rnd);
+ if (! (mpfr_equal_p (y, z) || (mpfr_nan_p (y) && mpfr_nan_p (z))))
+ {
+ printf ("Error for %s with xprec=%lu, yprec=%lu, rnd=%s\nx = ",
+ name, (unsigned long) MPFR_PREC (x), (unsigned long) yprec,
+ mpfr_print_rnd_mode (rnd));
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ printf ("\nexpected ");
+ mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ if (test_one == 2 && inex != 0)
+ {
+ printf ("Error for %s with xprec=%lu, yprec=%lu, rnd=%s\nx = ",
+ name, (unsigned long) MPFR_PREC (x), (unsigned long) yprec,
+ mpfr_print_rnd_mode (rnd));
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ printf ("\nexact case, but non-zero ternary value (%d)\n", inex);
+ exit (1);
+ }
+ if (rnd == MPFR_RNDN)
+ break;
+
+ if (test_one)
+ {
+ if (rnd == MPFR_RNDU || rnd == MPFR_RNDD)
+ break;
+
+ if (MPFR_IS_NEG (y))
+ rnd = (rnd == MPFR_RNDA) ? MPFR_RNDD : MPFR_RNDU;
+ else
+ rnd = (rnd == MPFR_RNDA) ? MPFR_RNDU : MPFR_RNDD;
+ }
+ else if (rnd == MPFR_RNDZ)
+ {
+ rnd = MPFR_IS_NEG (y) ? MPFR_RNDU : MPFR_RNDD;
+ rndnext = MPFR_RNDA;
+ }
+ else
+ {
+ rnd = rndnext;
+ if (rnd == MPFR_RNDA)
+ {
+ mpfr_nexttoinf (y);
+ rndnext = (MPFR_IS_NEG (y)) ? MPFR_RNDD : MPFR_RNDU;
+ }
+ else if (rndnext != MPFR_RNDN)
+ rndnext = MPFR_RNDN;
+ else
+ {
+ if (yprec == MPFR_PREC_MIN)
+ break;
+ mpfr_prec_round (y, --yprec, MPFR_RNDZ);
+ mpfr_set_prec (z, yprec);
+ }
+ }
+ }
+}
+
+/* Check data in file f for function foo, with name 'name'.
+ Each line consists of the file f one:
+
+ xprec yprec rnd x y
+
+ where:
+
+ xprec is the input precision
+ yprec is the output precision
+ rnd is the rounding mode (n, z, u, d, a, Z, *)
+ x is the input (hexadecimal format)
+ y is the expected output (hexadecimal format) for foo(x) with rounding rnd
+
+ If rnd is Z, y is the expected output in round-toward-zero, and the
+ four directed rounding modes are tested, then the round-to-nearest
+ mode is tested in precision yprec-1. This is useful for worst cases,
+ where yprec is the minimum value such that one has a worst case in a
+ directed rounding mode.
+
+ If rnd is *, y must be an exact case. All the rounding modes are tested
+ and the ternary value is checked (it must be 0).
+ */
+void
+data_check (const char *f, int (*foo) (FLIST), const char *name)
+{
+ FILE *fp;
+ int xprec, yprec; /* not mpfr_prec_t because of the fscanf */
+ mpfr_t x, y, z;
+ mpfr_rnd_t rnd;
+ char r;
+ int c;
+
+ fp = fopen (f, "r");
+ if (fp == NULL)
+ fp = src_fopen (f, "r");
+ if (fp == NULL)
+ {
+ char *v = (char *) MPFR_VERSION_STRING;
+
+ /* In the '-dev' versions, assume that the data file exists and
+ return an error if the file cannot be opened to make sure
+ that such failures are detected. */
+ while (*v != '\0')
+ v++;
+ if (v[-4] == '-' && v[-3] == 'd' && v[-2] == 'e' && v[-1] == 'v')
+ {
+ printf ("Error: unable to open file '%s'\n", f);
+ exit (1);
+ }
+ else
+ return;
+ }
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ while (!feof (fp))
+ {
+ /* skip whitespace, for consistency */
+ if (fscanf (fp, " ") == EOF)
+ {
+ if (ferror (fp))
+ {
+ perror ("data_check");
+ exit (1);
+ }
+ else
+ break; /* end of file */
+ }
+
+ if ((c = getc (fp)) == EOF)
+ {
+ if (ferror (fp))
+ {
+ perror ("data_check");
+ exit (1);
+ }
+ else
+ break; /* end of file */
+ }
+
+ if (c == '#') /* comment: read entire line */
+ {
+ do
+ {
+ c = getc (fp);
+ }
+ while (!feof (fp) && c != '\n');
+ }
+ else
+ {
+ ungetc (c, fp);
+
+ c = fscanf (fp, "%d %d %c", &xprec, &yprec, &r);
+ MPFR_ASSERTN (xprec >= MPFR_PREC_MIN && xprec <= MPFR_PREC_MAX);
+ MPFR_ASSERTN (yprec >= MPFR_PREC_MIN && yprec <= MPFR_PREC_MAX);
+ if (c == EOF)
+ {
+ perror ("data_check");
+ exit (1);
+ }
+ else if (c != 3)
+ {
+ printf ("Error: corrupted line in file '%s'\n", f);
+ exit (1);
+ }
+
+ switch (r)
+ {
+ case 'n':
+ rnd = MPFR_RNDN;
+ break;
+ case 'z': case 'Z':
+ rnd = MPFR_RNDZ;
+ break;
+ case 'u':
+ rnd = MPFR_RNDU;
+ break;
+ case 'd':
+ rnd = MPFR_RNDD;
+ break;
+ case '*':
+ rnd = MPFR_RND_MAX; /* non-existing rounding mode */
+ break;
+ default:
+ printf ("Error: unexpected rounding mode"
+ " in file '%s': %c\n", f, (int) r);
+ exit (1);
+ }
+ mpfr_set_prec (x, xprec);
+ mpfr_set_prec (y, yprec);
+ if (mpfr_inp_str (x, fp, 0, MPFR_RNDN) == 0)
+ {
+ printf ("Error: corrupted argument in file '%s'\n", f);
+ exit (1);
+ }
+ if (mpfr_inp_str (y, fp, 0, MPFR_RNDN) == 0)
+ {
+ printf ("Error: corrupted result in file '%s'\n", f);
+ exit (1);
+ }
+ if (getc (fp) != '\n')
+ {
+ printf ("Error: result not followed by \\n in file '%s'\n", f);
+ exit (1);
+ }
+ /* Skip whitespace, in particular at the end of the file. */
+ if (fscanf (fp, " ") == EOF && ferror (fp))
+ {
+ perror ("data_check");
+ exit (1);
+ }
+ if (r == '*')
+ {
+ int rndint;
+ RND_LOOP (rndint)
+ test5rm (foo, x, y, z, (mpfr_rnd_t) rndint, 2, name);
+ }
+ else
+ test5rm (foo, x, y, z, rnd, r != 'Z', name);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ fclose (fp);
+}
+
+/* Test n random bad cases. A precision py in [pymin,pymax] and
+ * a number y of precision py are chosen randomly. One computes
+ * x = inv(y) in precision px = py + psup (rounded to nearest).
+ * Then (in general), y is a bad case for fct in precision py (in
+ * the directed rounding modes, but also in the rounding-to-nearest
+ * mode for some lower precision: see data_check).
+ * fct, inv, name: data related to the function.
+ * pos, emin, emax: arguments for tests_default_random.
+ */
+void
+bad_cases (int (*fct)(FLIST), int (*inv)(FLIST), const char *name,
+ int pos, mpfr_exp_t emin, mpfr_exp_t emax,
+ mpfr_prec_t pymin, mpfr_prec_t pymax, mpfr_prec_t psup,
+ int n)
+{
+ mpfr_t x, y, z;
+ char *dbgenv;
+ int i, dbg;
+ mpfr_exp_t old_emin, old_emax;
+
+ old_emin = mpfr_get_emin ();
+ old_emax = mpfr_get_emax ();
+
+ dbgenv = getenv ("MPFR_DEBUG_BADCASES");
+ dbg = dbgenv != 0 ? atoi (dbgenv) : 0; /* debug level */
+ mpfr_inits (x, y, z, (mpfr_ptr) 0);
+ for (i = 0; i < n; i++)
+ {
+ mpfr_prec_t px, py, pz;
+ int inex;
+
+ if (dbg)
+ printf ("bad_cases: i = %d\n", i);
+ py = pymin + (randlimb () % (pymax - pymin + 1));
+ mpfr_set_prec (y, py);
+ tests_default_random (y, pos, emin, emax);
+ if (dbg)
+ {
+ printf ("bad_cases: yprec =%4ld, y = ", (long) py);
+ mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
+ printf ("\n");
+ }
+ px = py + psup;
+ mpfr_set_prec (x, px);
+ mpfr_clear_flags ();
+ inv (x, y, MPFR_RNDN);
+ if (mpfr_nanflag_p () || mpfr_overflow_p () || mpfr_underflow_p ())
+ {
+ if (dbg)
+ printf ("bad_cases: no normal inverse\n");
+ goto next_i;
+ }
+ if (dbg > 1)
+ {
+ printf ("bad_cases: x = ");
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ printf ("\n");
+ }
+ pz = px;
+ do
+ {
+ pz += 32;
+ mpfr_set_prec (z, pz);
+ if (fct (z, x, MPFR_RNDN) == 0)
+ {
+ if (dbg)
+ printf ("bad_cases: exact case\n");
+ goto next_i;
+ }
+ if (dbg)
+ {
+ if (dbg > 1)
+ {
+ printf ("bad_cases: %s(x) ~= ", name);
+ mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
+ }
+ else
+ {
+ printf ("bad_cases: [MPFR_RNDZ] ~= ");
+ mpfr_out_str (stdout, 16, 40, z, MPFR_RNDZ);
+ }
+ printf ("\n");
+ }
+ inex = mpfr_prec_round (z, py, MPFR_RNDN);
+ if (mpfr_nanflag_p () || mpfr_overflow_p () || mpfr_underflow_p ()
+ || ! mpfr_equal_p (z, y))
+ {
+ if (dbg)
+ printf ("bad_cases: inverse doesn't match\n");
+ goto next_i;
+ }
+ }
+ while (inex == 0);
+ /* We really have a bad case. */
+ do
+ py--;
+ while (py >= MPFR_PREC_MIN && mpfr_prec_round (z, py, MPFR_RNDZ) == 0);
+ py++;
+ /* py is now the smallest output precision such that we have
+ a bad case in the directed rounding modes. */
+ if (mpfr_prec_round (y, py, MPFR_RNDZ) != 0)
+ {
+ printf ("Internal error for i = %d\n", i);
+ exit (1);
+ }
+ if ((inex > 0 && MPFR_IS_POS (z)) ||
+ (inex < 0 && MPFR_IS_NEG (z)))
+ {
+ mpfr_nexttozero (y);
+ if (mpfr_zero_p (y))
+ goto next_i;
+ }
+ if (dbg)
+ {
+ printf ("bad_cases: yprec =%4ld, y = ", (long) py);
+ mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
+ printf ("\n");
+ }
+ /* Note: y is now the expected result rounded toward zero. */
+ test5rm (fct, x, y, z, MPFR_RNDZ, 0, name);
+ next_i:
+ /* In case the exponent range has been changed by
+ tests_default_random()... */
+ mpfr_set_emin (old_emin);
+ mpfr_set_emax (old_emax);
+ }
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+void
+flags_out (unsigned int flags)
+{
+ int none = 1;
+
+ if (flags & MPFR_FLAGS_UNDERFLOW)
+ none = 0, printf (" underflow");
+ if (flags & MPFR_FLAGS_OVERFLOW)
+ none = 0, printf (" overflow");
+ if (flags & MPFR_FLAGS_NAN)
+ none = 0, printf (" nan");
+ if (flags & MPFR_FLAGS_INEXACT)
+ none = 0, printf (" inexact");
+ if (flags & MPFR_FLAGS_ERANGE)
+ none = 0, printf (" erange");
+ if (none)
+ printf (" none");
+ printf (" (%u)\n", flags);
+}
diff --git a/mpfr/tests/texceptions.c b/mpfr/tests/texceptions.c
new file mode 100644
index 0000000000..925ced990f
--- /dev/null
+++ b/mpfr/tests/texceptions.c
@@ -0,0 +1,446 @@
+/* Test file for exceptions.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define ERROR(s) do { printf(s"\n"); exit(1); } while(0)
+
+/* Test powerof2 */
+static void
+check_powerof2 (void)
+{
+ mpfr_t x;
+
+ mpfr_init (x);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_powerof2_raw (x));
+ mpfr_set_ui (x, 3, MPFR_RNDN);
+ MPFR_ASSERTN (!mpfr_powerof2_raw (x));
+ mpfr_clear (x);
+}
+
+/* Test default rounding mode */
+static void
+check_default_rnd (void)
+{
+ int r;
+ mpfr_rnd_t t;
+ for(r = 0 ; r < MPFR_RND_MAX ; r++)
+ {
+ mpfr_set_default_rounding_mode ((mpfr_rnd_t) r);
+ t = (mpfr_get_default_rounding_mode) ();
+ if ((mpfr_rnd_t) r != t)
+ {
+ printf ("%s %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r),
+ mpfr_print_rnd_mode (t));
+ ERROR("ERROR in setting / getting default rounding mode (1)");
+ }
+ }
+ mpfr_set_default_rounding_mode ((mpfr_rnd_t) MPFR_RND_MAX);
+ if (mpfr_get_default_rounding_mode() != MPFR_RNDA)
+ ERROR("ERROR in setting / getting default rounding mode (2)");
+ mpfr_set_default_rounding_mode((mpfr_rnd_t) -1);
+ if (mpfr_get_default_rounding_mode() != MPFR_RNDA)
+ ERROR("ERROR in setting / getting default rounding mode (3)");
+}
+
+static void
+check_emin_emax (void)
+{
+ mpfr_exp_t old_emin, old_emax;
+
+ old_emin = mpfr_get_emin ();
+ old_emax = mpfr_get_emax ();
+
+ /* Check the functions not the macros ! */
+ if ((mpfr_set_emin)(MPFR_EMIN_MIN) != 0)
+ ERROR("set_emin failed!");
+ if ((mpfr_get_emin)() != MPFR_EMIN_MIN)
+ ERROR("get_emin FAILED!");
+ if ((mpfr_set_emin)(MPFR_EMIN_MIN-1) == 0)
+ ERROR("set_emin failed! (2)");
+
+ if ((mpfr_set_emax)(MPFR_EMAX_MAX) != 0)
+ ERROR("set_emax failed!");
+ if ((mpfr_get_emax)() != MPFR_EMAX_MAX)
+ ERROR("get_emax FAILED!");
+ if ((mpfr_set_emax)(MPFR_EMAX_MAX+1) == 0)
+ ERROR("set_emax failed! (2)");
+
+ if ((mpfr_get_emin_min) () != MPFR_EMIN_MIN)
+ ERROR ("get_emin_min");
+ if ((mpfr_get_emin_max) () != MPFR_EMIN_MAX)
+ ERROR ("get_emin_max");
+ if ((mpfr_get_emax_min) () != MPFR_EMAX_MIN)
+ ERROR ("get_emax_min");
+ if ((mpfr_get_emax_max) () != MPFR_EMAX_MAX)
+ ERROR ("get_emax_max");
+
+ set_emin (old_emin);
+ set_emax (old_emax);
+}
+
+static void
+check_set_get_prec (void)
+{
+ mpfr_t x;
+
+ mpfr_init2 (x, 17);
+ if (mpfr_get_prec (x) != 17 || (mpfr_get_prec)(x) != 17)
+ ERROR ("mpfr_get_prec");
+ mpfr_clear (x);
+}
+
+static void
+mpfr_set_double_range (void)
+{
+ mpfr_set_default_prec (54);
+ if (mpfr_get_default_prec () != 54)
+ ERROR ("get_default_prec failed (1)");
+ mpfr_set_default_prec (53);
+ if ((mpfr_get_default_prec) () != 53)
+ ERROR ("get_default_prec failed (2)");
+
+ /* in double precision format, the unbiased exponent is between 0 and
+ 2047, where 0 is used for subnormal numbers, and 2047 for special
+ numbers (infinities, NaN), and the bias is 1023, thus "normal" numbers
+ have an exponent between -1022 and 1023, corresponding to numbers
+ between 2^(-1022) and previous(2^(1024)).
+ (The smallest subnormal number is 0.(0^51)1*2^(-1022)= 2^(-1074).)
+
+ The smallest normal power of two is 1.0*2^(-1022).
+ The largest normal power of two is 2^1023.
+ (We have to add one for mpfr since mantissa are between 1/2 and 1.)
+ */
+
+ set_emin (-1021);
+ set_emax (1024);
+}
+
+static void
+check_flags (void)
+{
+ mpfr_t x;
+ mpfr_exp_t old_emin, old_emax;
+
+ old_emin = mpfr_get_emin ();
+ old_emax = mpfr_get_emax ();
+ mpfr_init (x);
+
+ /* Check the functions not the macros ! */
+ (mpfr_clear_flags)();
+ mpfr_set_double_range ();
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ (mpfr_clear_overflow)();
+ mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
+ if (!(mpfr_overflow_p)())
+ ERROR("ERROR: No overflow detected!\n");
+
+ (mpfr_clear_underflow)();
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 1025, MPFR_RNDN);
+ if (!(mpfr_underflow_p)())
+ ERROR("ERROR: No underflow detected!\n");
+
+ (mpfr_clear_nanflag)();
+ MPFR_SET_NAN(x);
+ mpfr_add (x, x, x, MPFR_RNDN);
+ if (!(mpfr_nanflag_p)())
+ ERROR("ERROR: No NaN flag!\n");
+
+ (mpfr_clear_inexflag)();
+ mpfr_set_ui(x, 2, MPFR_RNDN);
+ mpfr_cos(x, x, MPFR_RNDN);
+ if (!(mpfr_inexflag_p)())
+ ERROR("ERROR: No inexact flag!\n");
+
+ (mpfr_clear_erangeflag) ();
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
+ mpfr_get_ui (x, MPFR_RNDN);
+ if (!(mpfr_erangeflag_p)())
+ ERROR ("ERROR: No erange flag!\n");
+
+ mpfr_clear (x);
+ set_emin (old_emin);
+ set_emax (old_emax);
+}
+
+static void
+test_set_underflow (void)
+{
+ mpfr_t x, zero, min;
+ mpfr_ptr r[MPFR_RND_MAX];
+ int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */
+ int i;
+ int s;
+
+ mpfr_inits (x, zero, min, (mpfr_ptr) 0);
+ mpfr_set_ui (zero, 0, MPFR_RNDN);
+ mpfr_set_ui (min, 0, MPFR_RNDN);
+ mpfr_nextabove (min);
+ r[0] = r[2] = r[4] = min; /* RNDN, RNDU, RNDA */
+ r[1] = r[3] = zero; /* RNDZ, RNDD */
+ for (s = 1; s > 0; s = -1)
+ {
+ for (i = 0; i < MPFR_RND_MAX ; i++)
+ {
+ int j;
+ int inex;
+
+ j = s < 0 && i > 1 ? 5 - i : i;
+ inex = mpfr_underflow (x, (mpfr_rnd_t) i, s);
+ if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0)
+ {
+ printf ("Error in test_set_underflow, sign = %d,"
+ " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i));
+ printf ("Got\n");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf (", inex = %d\ninstead of\n", inex);
+ mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN);
+ printf (", inex = %d\n", t[j]);
+ exit (1);
+ }
+ }
+ mpfr_neg (zero, zero, MPFR_RNDN);
+ mpfr_neg (min, min, MPFR_RNDN);
+ }
+ mpfr_clears (x, zero, min, (mpfr_ptr) 0);
+}
+
+static void
+test_set_overflow (void)
+{
+ mpfr_t x, inf, max;
+ mpfr_ptr r[MPFR_RND_MAX];
+ int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */
+ int i;
+ int s;
+
+ mpfr_inits2 (32, x, inf, max, (mpfr_ptr) 0);
+ mpfr_set_inf (inf, 1);
+ mpfr_set_inf (max, 1);
+ mpfr_nextbelow (max);
+ r[0] = r[2] = r[4] = inf; /* RNDN, RNDU, RNDA */
+ r[1] = r[3] = max; /* RNDZ, RNDD */
+ for (s = 1; s > 0; s = -1)
+ {
+ for (i = 0; i < MPFR_RND_MAX ; i++)
+ {
+ int j;
+ int inex;
+
+ j = s < 0 && i > 1 ? 5 - i : i;
+ inex = mpfr_overflow (x, (mpfr_rnd_t) i, s);
+ if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0)
+ {
+ printf ("Error in test_set_overflow, sign = %d,"
+ " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i));
+ printf ("Got\n");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf (", inex = %d\ninstead of\n", inex);
+ mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN);
+ printf (", inex = %d\n", t[j]);
+ exit (1);
+ }
+ }
+ mpfr_neg (inf, inf, MPFR_RNDN);
+ mpfr_neg (max, max, MPFR_RNDN);
+ }
+ mpfr_clears (x, inf, max, (mpfr_ptr) 0);
+}
+
+static void
+check_set (void)
+{
+ mpfr_clear_flags ();
+
+ mpfr_set_overflow ();
+ MPFR_ASSERTN ((mpfr_overflow_p) ());
+ mpfr_set_underflow ();
+ MPFR_ASSERTN ((mpfr_underflow_p) ());
+ mpfr_set_divby0 ();
+ MPFR_ASSERTN ((mpfr_divby0_p) ());
+ mpfr_set_nanflag ();
+ MPFR_ASSERTN ((mpfr_nanflag_p) ());
+ mpfr_set_inexflag ();
+ MPFR_ASSERTN ((mpfr_inexflag_p) ());
+ mpfr_set_erangeflag ();
+ MPFR_ASSERTN ((mpfr_erangeflag_p) ());
+
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL);
+
+ mpfr_clear_overflow ();
+ MPFR_ASSERTN (! (mpfr_overflow_p) ());
+ mpfr_clear_underflow ();
+ MPFR_ASSERTN (! (mpfr_underflow_p) ());
+ mpfr_clear_divby0 ();
+ MPFR_ASSERTN (! (mpfr_divby0_p) ());
+ mpfr_clear_nanflag ();
+ MPFR_ASSERTN (! (mpfr_nanflag_p) ());
+ mpfr_clear_inexflag ();
+ MPFR_ASSERTN (! (mpfr_inexflag_p) ());
+ mpfr_clear_erangeflag ();
+ MPFR_ASSERTN (! (mpfr_erangeflag_p) ());
+
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ (mpfr_set_overflow) ();
+ MPFR_ASSERTN (mpfr_overflow_p ());
+ (mpfr_set_underflow) ();
+ MPFR_ASSERTN (mpfr_underflow_p ());
+ (mpfr_set_divby0) ();
+ MPFR_ASSERTN (mpfr_divby0_p ());
+ (mpfr_set_nanflag) ();
+ MPFR_ASSERTN (mpfr_nanflag_p ());
+ (mpfr_set_inexflag) ();
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ (mpfr_set_erangeflag) ();
+ MPFR_ASSERTN (mpfr_erangeflag_p ());
+
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL);
+
+ (mpfr_clear_overflow) ();
+ MPFR_ASSERTN (! mpfr_overflow_p ());
+ (mpfr_clear_underflow) ();
+ MPFR_ASSERTN (! mpfr_underflow_p ());
+ (mpfr_clear_divby0) ();
+ MPFR_ASSERTN (! mpfr_divby0_p ());
+ (mpfr_clear_nanflag) ();
+ MPFR_ASSERTN (! mpfr_nanflag_p ());
+ (mpfr_clear_inexflag) ();
+ MPFR_ASSERTN (! mpfr_inexflag_p ());
+ (mpfr_clear_erangeflag) ();
+ MPFR_ASSERTN (! mpfr_erangeflag_p ());
+
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ mpfr_exp_t emin, emax;
+
+ tests_start_mpfr ();
+
+ test_set_underflow ();
+ test_set_overflow ();
+ check_default_rnd();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ if (emin >= emax)
+ {
+ printf ("Error: emin >= emax\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
+ mpfr_set_double_range ();
+ mpfr_check_range (x, 0, MPFR_RNDN);
+ if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
+ {
+ printf ("Error: 2^1024 rounded to nearest should give +Inf\n");
+ exit (1);
+ }
+
+ set_emax (1025);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
+ mpfr_set_double_range ();
+ mpfr_check_range (x, 0, MPFR_RNDD);
+ if (!mpfr_number_p (x))
+ {
+ printf ("Error: 2^1024 rounded down should give a normal number\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, 1023, MPFR_RNDN);
+ mpfr_add (x, x, x, MPFR_RNDN);
+ if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
+ {
+ printf ("Error: x+x rounded to nearest for x=2^1023 should give +Inf\n");
+ printf ("emax = %ld\n", (long) mpfr_get_emax ());
+ printf ("got "); mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, 1023, MPFR_RNDN);
+ mpfr_add (x, x, x, MPFR_RNDD);
+ if (!mpfr_number_p (x))
+ {
+ printf ("Error: x+x rounded down for x=2^1023 should give"
+ " a normal number\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 1022, MPFR_RNDN);
+ mpfr_set_str_binary (y, "1.1e-1022"); /* y = 3/2*x */
+ mpfr_sub (y, y, x, MPFR_RNDZ);
+ if (mpfr_cmp_ui (y, 0))
+ {
+ printf ("Error: y-x rounded to zero should give 0"
+ " for y=3/2*2^(-1022), x=2^(-1022)\n");
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+
+ set_emin (-1026);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 1025, MPFR_RNDN);
+ mpfr_set_double_range ();
+ mpfr_check_range (x, 0, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (x) )
+ {
+ printf ("Error: x rounded to nearest for x=2^-1024 should give Zero\n");
+ printf ("emin = %ld\n", (long) mpfr_get_emin ());
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ set_emin (emin);
+ set_emax (emax);
+
+ check_emin_emax();
+ check_flags();
+ check_set_get_prec ();
+ check_powerof2 ();
+ check_set ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/texp.c b/mpfr/tests/texp.c
new file mode 100644
index 0000000000..4b77b283c7
--- /dev/null
+++ b/mpfr/tests/texp.c
@@ -0,0 +1,1022 @@
+/* Test file for mpfr_exp.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_exp (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ }
+ res = mpfr_exp (a, b, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_exp mpfr_exp
+#endif
+
+/* returns the number of ulp of error */
+static void
+check3 (const char *op, mpfr_rnd_t rnd, const char *res)
+{
+ mpfr_t x, y;
+
+ mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
+ /* y negative. If we forget to set the sign in mpfr_exp, we'll see it. */
+ mpfr_set_si (y, -1, MPFR_RNDN);
+ mpfr_set_str1 (x, op);
+ test_exp (y, x, rnd);
+ if (mpfr_cmp_str1 (y, res) )
+ {
+ printf ("mpfr_exp failed for x=%s, rnd=%s\n",
+ op, mpfr_print_rnd_mode (rnd));
+ printf ("expected result is %s, got ", res);
+ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
+ putchar('\n');
+ exit (1);
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+/* expx is the value of exp(X) rounded toward -infinity */
+static void
+check_worst_case (const char *Xs, const char *expxs)
+{
+ mpfr_t x, y;
+
+ mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
+ mpfr_set_str1(x, Xs);
+ test_exp(y, x, MPFR_RNDD);
+ if (mpfr_cmp_str1 (y, expxs))
+ {
+ printf ("exp(x) rounded toward -infinity is wrong\n");
+ exit(1);
+ }
+ mpfr_set_str1(x, Xs);
+ test_exp(x, x, MPFR_RNDU);
+ mpfr_nexttoinf (y);
+ if (mpfr_cmp(x,y))
+ {
+ printf ("exp(x) rounded toward +infinity is wrong\n");
+ exit(1);
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+/* worst cases communicated by Jean-Michel Muller and Vincent Lefevre */
+static int
+check_worst_cases (void)
+{
+ mpfr_t x; mpfr_t y;
+
+ mpfr_init(x);
+ mpfr_set_prec (x, 53);
+
+ check_worst_case("4.44089209850062517562e-16", "1.00000000000000022204");
+ check_worst_case("6.39488462184069720009e-14", "1.00000000000006372680");
+ check_worst_case("1.84741111297455401935e-12", "1.00000000000184718907");
+ check_worst_case("1.76177628026265550074e-10", "1.00000000017617751702");
+ check3("1.76177628026265550074e-10", MPFR_RNDN, "1.00000000017617773906");
+ check_worst_case("7.54175277499595900852e-10", "1.00000000075417516676");
+ check3("7.54175277499595900852e-10", MPFR_RNDN, "1.00000000075417538881");
+ /* bug found by Vincent Lefe`vre on December 8, 1999 */
+ check3("-5.42410311287441459172e+02", MPFR_RNDN, "2.7176584868845723e-236");
+ /* further cases communicated by Vincent Lefe`vre on January 27, 2000 */
+ check3("-1.32920285897904911589e-10", MPFR_RNDN, "0.999999999867079769622");
+ check3("-1.44037948245738330735e-10", MPFR_RNDN, "0.9999999998559621072757");
+ check3("-1.66795910430705305937e-10", MPFR_RNDZ, "0.9999999998332040895832");
+ check3("-1.64310953745426656203e-10", MPFR_RNDN, "0.9999999998356891017792");
+ check3("-1.38323574826034659172e-10", MPFR_RNDZ, "0.9999999998616764251835");
+ check3("-1.23621668465115401498e-10", MPFR_RNDZ, "0.9999999998763783315425");
+
+ mpfr_set_prec (x, 601);
+ mpfr_set_str (x, "0.88b6ba510e10450edc258748bc9dfdd466f21b47ed264cdf24aa8f64af1f3fad9ec2301d43c0743f534b5aa20091ff6d352df458ef1ba519811ef6f5b11853534fd8fa32764a0a6d2d0dd20@0", 16, MPFR_RNDZ);
+ mpfr_init2 (y, 601);
+ mpfr_exp_2 (y, x, MPFR_RNDD);
+ mpfr_exp_3 (x, x, MPFR_RNDD);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=601\n");
+ printf ("mpfr_exp_2 gives ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\nmpfr_exp_3 gives ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 13001);
+ mpfr_set_prec (y, 13001);
+ mpfr_urandomb (x, RANDS);
+ mpfr_exp_3 (y, x, MPFR_RNDN);
+ mpfr_exp_2 (x, x, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=13001\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ return 0;
+}
+
+static void
+compare_exp2_exp3 (mpfr_prec_t p0, mpfr_prec_t p1)
+{
+ mpfr_t x, y, z;
+ mpfr_prec_t prec;
+ mpfr_rnd_t rnd;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+ for (prec = p0; prec <= p1; prec ++)
+ {
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (y, prec);
+ mpfr_set_prec (z, prec);
+ do
+ mpfr_urandomb (x, RANDS);
+ while (MPFR_IS_ZERO (x)); /* 0 is handled by mpfr_exp only */
+ rnd = RND_RAND ();
+ mpfr_exp_2 (y, x, rnd);
+ mpfr_exp_3 (z, x, rnd);
+ if (mpfr_cmp (y,z))
+ {
+ printf ("mpfr_exp_2 and mpfr_exp_3 disagree for rnd=%s and\nx=",
+ mpfr_print_rnd_mode (rnd));
+ mpfr_print_binary (x);
+ puts ("");
+ printf ("mpfr_exp_2 gives ");
+ mpfr_print_binary (y);
+ puts ("");
+ printf ("mpfr_exp_3 gives ");
+ mpfr_print_binary (z);
+ puts ("");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+check_large (void)
+{
+ mpfr_t x, z;
+ mpfr_prec_t prec;
+
+ /* bug found by Patrick Pe'lissier on 7 Jun 2004 */
+ prec = 203780;
+ mpfr_init2 (x, prec);
+ mpfr_init2 (z, prec);
+ mpfr_set_ui (x, 3, MPFR_RNDN);
+ mpfr_sqrt (x, x, MPFR_RNDN);
+ mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+ mpfr_exp_3 (z, x, MPFR_RNDN);
+ mpfr_clear (x);
+ mpfr_clear (z);
+}
+
+#define TEST_FUNCTION test_exp
+#define TEST_RANDOM_EMIN -36
+#define TEST_RANDOM_EMAX 36
+#include "tgeneric.c"
+
+static void
+check_special (void)
+{
+ mpfr_t x, y, z;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ /* check exp(NaN) = NaN */
+ mpfr_set_nan (x);
+ test_exp (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for exp(NaN)\n");
+ exit (1);
+ }
+
+ /* check exp(+inf) = +inf */
+ mpfr_set_inf (x, 1);
+ test_exp (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for exp(+inf)\n");
+ exit (1);
+ }
+
+ /* check exp(-inf) = +0 */
+ mpfr_set_inf (x, -1);
+ test_exp (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for exp(-inf)\n");
+ exit (1);
+ }
+
+ /* Check overflow. Corner case of mpfr_exp_2 */
+ mpfr_set_prec (x, 64);
+ mpfr_set_emax (MPFR_EMAX_DEFAULT);
+ mpfr_set_emin (MPFR_EMIN_DEFAULT);
+ mpfr_set_str (x,
+ "0.1011000101110010000101111111010100001100000001110001100111001101E30",
+ 2, MPFR_RNDN);
+ mpfr_exp (x, x, MPFR_RNDD);
+ if (mpfr_cmp_str (x,
+".1111111111111111111111111111111111111111111111111111111111111111E1073741823",
+ 2, MPFR_RNDN) != 0)
+ {
+ printf ("Wrong overflow detection in mpfr_exp\n");
+ mpfr_dump (x);
+ exit (1);
+ }
+ /* Check underflow. Corner case of mpfr_exp_2 */
+ mpfr_set_str (x,
+"-0.1011000101110010000101111111011111010001110011110111100110101100E30",
+ 2, MPFR_RNDN);
+ mpfr_exp (x, x, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "0.1E-1073741823", 2, MPFR_RNDN) != 0)
+ {
+ printf ("Wrong underflow (1) detection in mpfr_exp\n");
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_set_str (x,
+"-0.1011001101110010000101111111011111010001110011110111100110111101E30",
+ 2, MPFR_RNDN);
+ mpfr_exp (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0) != 0)
+ {
+ printf ("Wrong underflow (2) detection in mpfr_exp\n");
+ mpfr_dump (x);
+ exit (1);
+ }
+ /* Check overflow. Corner case of mpfr_exp_3 */
+ if (MPFR_PREC_MAX >= MPFR_EXP_THRESHOLD + 10 && MPFR_PREC_MAX >= 64)
+ {
+ /* this ensures that for small MPFR_EXP_THRESHOLD, the following
+ mpfr_set_str conversion is exact */
+ mpfr_set_prec (x, (MPFR_EXP_THRESHOLD + 10 > 64)
+ ? MPFR_EXP_THRESHOLD + 10 : 64);
+ mpfr_set_str (x,
+ "0.1011000101110010000101111111010100001100000001110001100111001101E30",
+ 2, MPFR_RNDN);
+ mpfr_clear_overflow ();
+ mpfr_exp (x, x, MPFR_RNDD);
+ if (!mpfr_overflow_p ())
+ {
+ printf ("Wrong overflow detection in mpfr_exp_3\n");
+ mpfr_dump (x);
+ exit (1);
+ }
+ /* Check underflow. Corner case of mpfr_exp_3 */
+ mpfr_set_str (x,
+ "-0.1011000101110010000101111111011111010001110011110111100110101100E30",
+ 2, MPFR_RNDN);
+ mpfr_clear_underflow ();
+ mpfr_exp (x, x, MPFR_RNDN);
+ if (!mpfr_underflow_p ())
+ {
+ printf ("Wrong underflow detection in mpfr_exp_3\n");
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_set_prec (x, 53);
+ }
+
+ /* check overflow */
+ set_emax (10);
+ mpfr_set_ui (x, 7, MPFR_RNDN);
+ test_exp (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for exp(7) for emax=10\n");
+ exit (1);
+ }
+ set_emax (emax);
+
+ /* check underflow */
+ set_emin (-10);
+ mpfr_set_si (x, -9, MPFR_RNDN);
+ test_exp (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for exp(-9) for emin=-10\n");
+ printf ("Expected +0\n");
+ printf ("Got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ set_emin (emin);
+
+ /* check case EXP(x) < -precy */
+ mpfr_set_prec (y, 2);
+ mpfr_set_str_binary (x, "-0.1E-3");
+ test_exp (y, x, MPFR_RNDD);
+ if (mpfr_cmp_ui_2exp (y, 3, -2))
+ {
+ printf ("Error for exp(-1/16), prec=2, RNDD\n");
+ printf ("expected 0.11, got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ test_exp (y, x, MPFR_RNDZ);
+ if (mpfr_cmp_ui_2exp (y, 3, -2))
+ {
+ printf ("Error for exp(-1/16), prec=2, RNDZ\n");
+ printf ("expected 0.11, got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "0.1E-3");
+ test_exp (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error for exp(1/16), prec=2, RNDN\n");
+ exit (1);
+ }
+ test_exp (y, x, MPFR_RNDU);
+ if (mpfr_cmp_ui_2exp (y, 3, -1))
+ {
+ printf ("Error for exp(1/16), prec=2, RNDU\n");
+ exit (1);
+ }
+
+ /* bug reported by Franky Backeljauw, 28 Mar 2003 */
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
+ test_exp (y, x, MPFR_RNDN);
+
+ mpfr_set_prec (x, 153);
+ mpfr_set_prec (z, 153);
+ mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
+ test_exp (z, x, MPFR_RNDN);
+ mpfr_prec_round (z, 53, MPFR_RNDN);
+
+ if (mpfr_cmp (y, z))
+ {
+ printf ("Error in mpfr_exp for large argument\n");
+ exit (1);
+ }
+
+ /* corner cases in mpfr_exp_3 */
+ mpfr_set_prec (x, 2);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_prec (y, 2);
+ mpfr_exp_3 (y, x, MPFR_RNDN);
+
+ /* Check some little things about overflow detection */
+ set_emin (-125);
+ set_emax (128);
+ mpfr_set_prec (x, 107);
+ mpfr_set_prec (y, 107);
+ mpfr_set_str_binary (x, "0.11110000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000"
+ "00000000E4");
+ test_exp (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "0.11000111100001100110010101111101011010010101010000"
+ "1101110111100010111001011111111000110111001011001101010"
+ "01E22", 2, MPFR_RNDN))
+ {
+ printf ("Special overflow error (1)\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ set_emin (emin);
+ set_emax (emax);
+
+ /* Check for overflow producing a segfault with HUGE exponent */
+ mpfr_set_ui (x, 3, MPFR_RNDN);
+ mpfr_mul_2ui (x, x, 32, MPFR_RNDN);
+ test_exp (y, x, MPFR_RNDN); /* Can't test return value: May overflow or not*/
+
+ /* Bug due to wrong approximation of (x)/log2 */
+ mpfr_set_prec (x, 163);
+
+ mpfr_set_str (x, "-4.28ac8fceeadcda06bb56359017b1c81b85b392e7", 16,
+ MPFR_RNDN);
+ mpfr_exp (x, x, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "3.fffffffffffffffffffffffffffffffffffffffe8@-2",
+ 16, MPFR_RNDN))
+ {
+ printf ("Error for x= -4.28ac8fceeadcda06bb56359017b1c81b85b392e7");
+ printf ("expected 3.fffffffffffffffffffffffffffffffffffffffe8@-2");
+ printf ("Got ");
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ }
+
+ /* bug found by Guillaume Melquiond, 13 Sep 2005 */
+ mpfr_set_prec (x, 53);
+ mpfr_set_str_binary (x, "-1E-400");
+ mpfr_exp (x, x, MPFR_RNDZ);
+ if (mpfr_cmp_ui (x, 1) == 0)
+ {
+ printf ("Error for exp(-2^(-400))\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+/* check sign of inexact flag */
+static void
+check_inexact (void)
+{
+ mpfr_t x, y;
+ int inexact;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+
+ mpfr_set_str_binary (x,
+ "1.0000000000001001000110100100101000001101101011100101e2");
+ inexact = test_exp (y, x, MPFR_RNDN);
+ if (inexact <= 0)
+ {
+ printf ("Wrong inexact flag (Got %d instead of 1)\n", inexact);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+check_exp10(void)
+{
+ mpfr_t x;
+ int inexact;
+
+ mpfr_init2 (x, 200);
+ mpfr_set_ui(x, 4, MPFR_RNDN);
+
+ inexact = mpfr_exp10 (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui(x, 10*10*10*10))
+ {
+ printf ("exp10: Wrong returned value\n");
+ exit (1);
+ }
+ if (inexact != 0)
+ {
+ printf ("exp10: Wrong inexact flag\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+}
+
+static void
+overflowed_exp0 (void)
+{
+ mpfr_t x, y;
+ int emax, i, inex, rnd, err = 0;
+ mpfr_exp_t old_emax;
+
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ for (emax = -1; emax <= 0; emax++)
+ {
+ mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
+ mpfr_nextbelow (y);
+ set_emax (emax); /* 1 is not representable. */
+ /* and if emax < 0, 1 - eps is not representable either. */
+ for (i = -1; i <= 1; i++)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_exp (x, x, (mpfr_rnd_t) rnd);
+ if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
+ ! mpfr_overflow_p ())
+ {
+ printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
+ " The overflow flag is not set.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ {
+ if (inex >= 0)
+ {
+ printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (x, y))
+ {
+ printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of 0.11111111E%d.\n", emax);
+ err = 1;
+ }
+ }
+ else
+ {
+ if (inex <= 0)
+ {
+ printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
+ {
+ printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of +Inf.\n");
+ err = 1;
+ }
+ }
+ }
+ set_emax (old_emax);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+/* This bug occurs in mpfr_exp_2 on a Linux-64 machine, r5475. */
+static void
+bug20080731 (void)
+{
+ mpfr_exp_t emin;
+ mpfr_t x, y1, y2;
+ mpfr_prec_t prec = 64;
+
+ emin = mpfr_get_emin ();
+ set_emin (MPFR_EMIN_MIN);
+
+ mpfr_init2 (x, 200);
+ mpfr_set_str (x, "-2.c5c85fdf473de6af278ece700fcbdabd03cd0cb9ca62d8b62c@7",
+ 16, MPFR_RNDN);
+
+ mpfr_init2 (y1, prec);
+ mpfr_exp (y1, x, MPFR_RNDU);
+
+ /* Compute the result with a higher internal precision. */
+ mpfr_init2 (y2, 300);
+ mpfr_exp (y2, x, MPFR_RNDU);
+ mpfr_prec_round (y2, prec, MPFR_RNDU);
+
+ if (mpfr_cmp0 (y1, y2) != 0)
+ {
+ printf ("Error in bug20080731\nExpected ");
+ mpfr_out_str (stdout, 16, 0, y2, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 16, 0, y1, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
+ set_emin (emin);
+}
+
+/* Emulate mpfr_exp with mpfr_exp_3 in the general case. */
+static int
+exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+
+ inexact = mpfr_exp_3 (y, x, rnd_mode);
+ return mpfr_check_range (y, inexact, rnd_mode);
+}
+
+static void
+underflow_up (int extended_emin)
+{
+ mpfr_t minpos, x, y, t, t2;
+ int precx, precy;
+ int inex;
+ int rnd;
+ int e3;
+ int i, j;
+
+ mpfr_init2 (minpos, 2);
+ mpfr_set_ui (minpos, 0, MPFR_RNDN);
+ mpfr_nextabove (minpos);
+
+ /* Let's test values near the underflow boundary.
+ *
+ * Minimum representable positive number: minpos = 2^(emin - 1).
+ * Let's choose an MPFR number x = log(minpos) + eps, with |eps| small
+ * (note: eps cannot be 0, and cannot be a rational number either).
+ * Then exp(x) = minpos * exp(eps) ~= minpos * (1 + eps + eps^2).
+ * We will compute y = rnd(exp(x)) in some rounding mode, precision p.
+ * 1. If eps > 0, then in any rounding mode:
+ * rnd(exp(x)) >= minpos and no underflow.
+ * So, let's take x1 = rndu(log(minpos)) in some precision.
+ * 2. If eps < 0, then exp(x) < minpos and the result will be either 0
+ * or minpos. An underflow always occurs in MPFR_RNDZ and MPFR_RNDD,
+ * but not necessarily in MPFR_RNDN and MPFR_RNDU (this is underflow
+ * after rounding in an unbounded exponent range). If -a < eps < -b,
+ * minpos * (1 - a) < exp(x) < minpos * (1 - b + b^2).
+ * - If eps > -2^(-p), no underflow in MPFR_RNDU.
+ * - If eps > -2^(-p-1), no underflow in MPFR_RNDN.
+ * - If eps < - (2^(-p-1) + 2^(-2p-1)), underflow in MPFR_RNDN.
+ * - If eps < - (2^(-p) + 2^(-2p+1)), underflow in MPFR_RNDU.
+ * - In MPFR_RNDN, result is minpos iff exp(eps) > 1/2, i.e.
+ * - log(2) < eps < ...
+ *
+ * Moreover, since precy < MPFR_EXP_THRESHOLD (to avoid tests that take
+ * too much time), mpfr_exp() always selects mpfr_exp_2(); so, we need
+ * to test mpfr_exp_3() too. This will be done via the e3 variable:
+ * e3 = 0: mpfr_exp(), thus mpfr_exp_2().
+ * e3 = 1: mpfr_exp_3(), via the exp_3() wrapper.
+ * i.e.: inex = e3 ? exp_3 (y, x, rnd) : mpfr_exp (y, x, rnd);
+ */
+
+ /* Case eps > 0. In revision 5461 (trunk) on a 64-bit Linux machine:
+ * Incorrect flags in underflow_up, eps > 0, MPFR_RNDN and extended emin
+ * for precx = 96, precy = 16, mpfr_exp_3
+ * Got 9 instead of 8.
+ * Note: testing this case in several precisions for x and y introduces
+ * some useful random. Indeed, the bug is not always triggered.
+ * Fixed in r5469.
+ */
+ for (precx = 16; precx <= 128; precx += 16)
+ {
+ mpfr_init2 (x, precx);
+ mpfr_log (x, minpos, MPFR_RNDU);
+ for (precy = 16; precy <= 128; precy += 16)
+ {
+ mpfr_init2 (y, precy);
+
+ for (e3 = 0; e3 <= 1; e3++)
+ {
+ RND_LOOP (rnd)
+ {
+ int err = 0;
+
+ mpfr_clear_flags ();
+ inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd)
+ : mpfr_exp (y, x, (mpfr_rnd_t) rnd);
+ if (__gmpfr_flags != MPFR_FLAGS_INEXACT)
+ {
+ printf ("Incorrect flags in underflow_up, eps > 0, %s",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ if (extended_emin)
+ printf (" and extended emin");
+ printf ("\nfor precx = %d, precy = %d, %s\n",
+ precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp");
+ printf ("Got %u instead of %u.\n", __gmpfr_flags,
+ (unsigned int) MPFR_FLAGS_INEXACT);
+ err = 1;
+ }
+ if (mpfr_cmp0 (y, minpos) < 0)
+ {
+ printf ("Incorrect result in underflow_up, eps > 0, %s",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ if (extended_emin)
+ printf (" and extended emin");
+ printf ("\nfor precx = %d, precy = %d, %s\n",
+ precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp");
+ mpfr_dump (y);
+ err = 1;
+ }
+ MPFR_ASSERTN (inex != 0);
+ if (rnd == MPFR_RNDD || rnd == MPFR_RNDZ)
+ MPFR_ASSERTN (inex < 0);
+ if (rnd == MPFR_RNDU)
+ MPFR_ASSERTN (inex > 0);
+ if (err)
+ exit (1);
+ }
+ }
+
+ mpfr_clear (y);
+ }
+ mpfr_clear (x);
+ }
+
+ /* Case - log(2) < eps < 0 in MPFR_RNDN, starting with small-precision x;
+ * only check the result and the ternary value.
+ * Previous to r5453 (trunk), on 32-bit and 64-bit machines, this fails
+ * for precx = 65 and precy = 16, e.g.:
+ * exp_2.c:264: assertion failed: ...
+ * because mpfr_sub (r, x, r, MPFR_RNDU); yields a null value. This is
+ * fixed in r5453 by going to next Ziv's iteration.
+ */
+ for (precx = sizeof(mpfr_exp_t) * CHAR_BIT + 1; precx <= 81; precx += 8)
+ {
+ mpfr_init2 (x, precx);
+ mpfr_log (x, minpos, MPFR_RNDD); /* |ulp| <= 1/2 */
+ for (precy = 16; precy <= 128; precy += 16)
+ {
+ mpfr_init2 (y, precy);
+ inex = mpfr_exp (y, x, MPFR_RNDN);
+ if (inex <= 0 || mpfr_cmp0 (y, minpos) != 0)
+ {
+ printf ("Error in underflow_up, - log(2) < eps < 0");
+ if (extended_emin)
+ printf (" and extended emin");
+ printf (" for prec = %d\nExpected ", precy);
+ mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN);
+ printf (" (minimum positive MPFR number) and inex > 0\nGot ");
+ mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
+ printf ("\nwith inex = %d\n", inex);
+ exit (1);
+ }
+ mpfr_clear (y);
+ }
+ mpfr_clear (x);
+ }
+
+ /* Cases eps ~ -2^(-p) and eps ~ -2^(-p-1). More precisely,
+ * _ for j = 0, eps > -2^(-(p+i)),
+ * _ for j = 1, eps < - (2^(-(p+i)) + 2^(1-2(p+i))),
+ * where i = 0 or 1.
+ */
+ mpfr_inits2 (2, t, t2, (mpfr_ptr) 0);
+ for (precy = 16; precy <= 128; precy += 16)
+ {
+ mpfr_set_ui_2exp (t, 1, - precy, MPFR_RNDN); /* 2^(-p) */
+ mpfr_set_ui_2exp (t2, 1, 1 - 2 * precy, MPFR_RNDN); /* 2^(-2p+1) */
+ precx = sizeof(mpfr_exp_t) * CHAR_BIT + 2 * precy + 8;
+ mpfr_init2 (x, precx);
+ mpfr_init2 (y, precy);
+ for (i = 0; i <= 1; i++)
+ {
+ for (j = 0; j <= 1; j++)
+ {
+ if (j == 0)
+ {
+ /* Case eps > -2^(-(p+i)). */
+ mpfr_log (x, minpos, MPFR_RNDU);
+ }
+ else /* j == 1 */
+ {
+ /* Case eps < - (2^(-(p+i)) + 2^(1-2(p+i))). */
+ mpfr_log (x, minpos, MPFR_RNDD);
+ inex = mpfr_sub (x, x, t2, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ }
+ inex = mpfr_sub (x, x, t, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+
+ RND_LOOP (rnd)
+ for (e3 = 0; e3 <= 1; e3++)
+ {
+ int err = 0;
+ unsigned int flags;
+
+ flags = MPFR_FLAGS_INEXACT |
+ (((rnd == MPFR_RNDU || rnd == MPFR_RNDA)
+ && (i == 1 || j == 0)) ||
+ (rnd == MPFR_RNDN && (i == 1 && j == 0)) ?
+ 0 : MPFR_FLAGS_UNDERFLOW);
+ mpfr_clear_flags ();
+ inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd)
+ : mpfr_exp (y, x, (mpfr_rnd_t) rnd);
+ if (__gmpfr_flags != flags)
+ {
+ printf ("Incorrect flags in underflow_up, %s",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ if (extended_emin)
+ printf (" and extended emin");
+ printf ("\nfor precx = %d, precy = %d, ",
+ precx, precy);
+ if (j == 0)
+ printf ("eps >~ -2^(-%d)", precy + i);
+ else
+ printf ("eps <~ - (2^(-%d) + 2^(%d))",
+ precy + i, 1 - 2 * (precy + i));
+ printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp");
+ printf ("Got %u instead of %u.\n",
+ __gmpfr_flags, flags);
+ err = 1;
+ }
+ if (rnd == MPFR_RNDU || rnd == MPFR_RNDA || rnd == MPFR_RNDN ?
+ mpfr_cmp0 (y, minpos) != 0 : MPFR_NOTZERO (y))
+ {
+ printf ("Incorrect result in underflow_up, %s",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ if (extended_emin)
+ printf (" and extended emin");
+ printf ("\nfor precx = %d, precy = %d, ",
+ precx, precy);
+ if (j == 0)
+ printf ("eps >~ -2^(-%d)", precy + i);
+ else
+ printf ("eps <~ - (2^(-%d) + 2^(%d))",
+ precy + i, 1 - 2 * (precy + i));
+ printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp");
+ mpfr_dump (y);
+ err = 1;
+ }
+ if (err)
+ exit (1);
+ } /* for (e3 ...) */
+ } /* for (j ...) */
+ mpfr_div_2si (t, t, 1, MPFR_RNDN);
+ mpfr_div_2si (t2, t2, 2, MPFR_RNDN);
+ } /* for (i ...) */
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+ } /* for (precy ...) */
+ mpfr_clears (t, t2, (mpfr_ptr) 0);
+
+ /* Case exp(eps) ~= 1/2, i.e. eps ~= - log(2).
+ * We choose x0 and x1 with high enough precision such that:
+ * x0 = rndd(rndd(log(minpos)) - rndu(log(2)))
+ * x1 = rndu(rndu(log(minpos)) - rndd(log(2)))
+ * In revision 5507 (trunk) on a 64-bit Linux machine, this fails:
+ * Error in underflow_up, eps >~ - log(2) and extended emin
+ * for precy = 16, mpfr_exp
+ * Expected 1.0@-1152921504606846976 (minimum positive MPFR number),
+ * inex > 0 and flags = 9
+ * Got 0
+ * with inex = -1 and flags = 9
+ * due to a double-rounding problem in mpfr_mul_2si when rescaling
+ * the result.
+ */
+ mpfr_inits2 (sizeof(mpfr_exp_t) * CHAR_BIT + 64, x, t, (mpfr_ptr) 0);
+ for (i = 0; i <= 1; i++)
+ {
+ mpfr_log (x, minpos, i ? MPFR_RNDU : MPFR_RNDD);
+ mpfr_const_log2 (t, i ? MPFR_RNDD : MPFR_RNDU);
+ mpfr_sub (x, x, t, i ? MPFR_RNDU : MPFR_RNDD);
+ for (precy = 16; precy <= 128; precy += 16)
+ {
+ mpfr_init2 (y, precy);
+ for (e3 = 0; e3 <= 1; e3++)
+ {
+ unsigned int flags, uflags =
+ MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW;
+
+ mpfr_clear_flags ();
+ inex = e3 ? exp_3 (y, x, MPFR_RNDN) : mpfr_exp (y, x, MPFR_RNDN);
+ flags = __gmpfr_flags;
+ if (flags != uflags ||
+ (i ? (inex <= 0 || mpfr_cmp0 (y, minpos) != 0)
+ : (inex >= 0 || MPFR_NOTZERO (y))))
+ {
+ printf ("Error in underflow_up, eps %c~ - log(2)",
+ i ? '>' : '<');
+ if (extended_emin)
+ printf (" and extended emin");
+ printf ("\nfor precy = %d, %s\nExpected ", precy,
+ e3 ? "mpfr_exp_3" : "mpfr_exp");
+ if (i)
+ {
+ mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN);
+ printf (" (minimum positive MPFR number),\ninex >");
+ }
+ else
+ {
+ printf ("+0, inex <");
+ }
+ printf (" 0 and flags = %u\nGot ", uflags);
+ mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
+ printf ("\nwith inex = %d and flags = %u\n", inex, flags);
+ exit (1);
+ }
+ }
+ mpfr_clear (y);
+ }
+ }
+ mpfr_clears (x, t, (mpfr_ptr) 0);
+
+ mpfr_clear (minpos);
+}
+
+static void
+underflow (void)
+{
+ mpfr_exp_t emin;
+
+ underflow_up (0);
+
+ emin = mpfr_get_emin ();
+ set_emin (MPFR_EMIN_MIN);
+ if (mpfr_get_emin () != emin)
+ {
+ underflow_up (1);
+ set_emin (emin);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ if (argc > 1)
+ check_large ();
+
+ check_inexact ();
+ check_special ();
+
+ test_generic (2, 100, 100);
+
+ compare_exp2_exp3 (20, 1000);
+ check_worst_cases();
+ check3("0.0", MPFR_RNDU, "1.0");
+ check3("-1e-170", MPFR_RNDU, "1.0");
+ check3("-1e-170", MPFR_RNDN, "1.0");
+ check3("-8.88024741073346941839e-17", MPFR_RNDU, "1.0");
+ check3("8.70772839244701057915e-01", MPFR_RNDN, "2.38875626491680437269");
+ check3("1.0", MPFR_RNDN, "2.71828182845904509080");
+ check3("-3.42135637628104173534e-07", MPFR_RNDZ, "0.999999657864420798958");
+ /* worst case for argument reduction, very near from 5*log(2),
+ thanks to Jean-Michel Muller */
+ check3("3.4657359027997265421", MPFR_RNDN, "32.0");
+ check3("3.4657359027997265421", MPFR_RNDU, "32.0");
+ check3("3.4657359027997265421", MPFR_RNDD, "31.999999999999996447");
+ check3("2.26523754332090625496e+01", MPFR_RNDD, "6.8833785261699581146e9");
+ check3("1.31478962104089092122e+01", MPFR_RNDZ, "5.12930793917860137299e+05");
+ check3("4.25637507920002378103e-01", MPFR_RNDU, "1.53056585656161181497e+00");
+ check3("6.26551618962329307459e-16", MPFR_RNDU, "1.00000000000000066613e+00");
+ check3("-3.35589513871216568383e-03",MPFR_RNDD, "9.96649729583626853291e-01");
+ check3("1.95151388850007272424e+01", MPFR_RNDU, "2.98756340674767792225e+08");
+ check3("2.45045953503350730784e+01", MPFR_RNDN, "4.38743344916128387451e+10");
+ check3("2.58165606081678085104e+01", MPFR_RNDD, "1.62925781879432281494e+11");
+ check3("-2.36539020084338638128e+01",MPFR_RNDZ, "5.33630792749924762447e-11");
+ check3("2.39211946135858077866e+01", MPFR_RNDU, "2.44817704330214385986e+10");
+ check3("-2.78190533055889162029e+01",MPFR_RNDZ, "8.2858803483596879512e-13");
+ check3("2.64028186174889789584e+01", MPFR_RNDD, "2.9281844652878973388e11");
+ check3("2.92086338843268329413e+01", MPFR_RNDZ, "4.8433797301907177734e12");
+ check3("-2.46355324071459982349e+01",MPFR_RNDZ, "1.9995129297760994791e-11");
+ check3("-2.23509444608605427618e+01",MPFR_RNDZ, "1.9638492867489702307e-10");
+ check3("-2.41175390197331687148e+01",MPFR_RNDD, "3.3564940885530624592e-11");
+ check3("2.46363885231578088053e+01", MPFR_RNDU, "5.0055014282693267822e10");
+ check3("111.1263531080090984914932050742208957672119140625", MPFR_RNDN, "1.8262572323517295459e48");
+ check3("-3.56196340354684821250e+02",MPFR_RNDN, "2.0225297096141478156e-155");
+ check3("6.59678273772710895173e+02", MPFR_RNDU, "3.1234469273830195529e286");
+ check3("5.13772529701934331570e+02", MPFR_RNDD, "1.3445427121297197752e223");
+ check3("3.57430211008718345056e+02", MPFR_RNDD, "1.6981197246857298443e155");
+ check3("3.82001814471465536371e+02", MPFR_RNDU, "7.9667300591087367805e165");
+ check3("5.92396038219384422518e+02", MPFR_RNDD, "1.880747529554661989e257");
+ check3("-5.02678550462488090034e+02",MPFR_RNDU, "4.8919201895446217839e-219");
+ check3("5.30015757134837031117e+02", MPFR_RNDD, "1.5237672861171573939e230");
+ check3("5.16239362447650933063e+02", MPFR_RNDZ, "1.5845518406744492105e224");
+ check3("6.00812634798592370977e-01", MPFR_RNDN, "1.823600119339019443");
+ check_exp10 ();
+
+ bug20080731 ();
+
+ overflowed_exp0 ();
+ underflow ();
+
+ data_check ("data/exp", mpfr_exp, "mpfr_exp");
+ bad_cases (mpfr_exp, mpfr_log, "mpfr_exp", 0, -256, 255, 4, 128, 800, 50);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/texp10.c b/mpfr/tests/texp10.c
new file mode 100644
index 0000000000..d6fa58b932
--- /dev/null
+++ b/mpfr/tests/texp10.c
@@ -0,0 +1,318 @@
+/* Test file for mpfr_exp10.
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_exp10
+#define TEST_RANDOM_EMIN -36
+#define TEST_RANDOM_EMAX 36
+#include "tgeneric.c"
+
+static void
+special_overflow (void)
+{
+ mpfr_t x, y;
+ int inex;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ set_emin (-125);
+ set_emax (128);
+
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 24);
+
+ mpfr_set_str_binary (x, "0.101100100000000000110100E15");
+ inex = mpfr_exp10 (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || inex <= 0)
+ {
+ printf ("Overflow error.\n");
+ mpfr_dump (y);
+ printf ("inex = %d\n", inex);
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+ set_emin (emin);
+ set_emax (emax);
+}
+
+static void
+emax_m_eps (void)
+{
+ if (mpfr_get_emax () <= LONG_MAX)
+ {
+ mpfr_t x, y;
+ int inex, ov;
+
+ mpfr_init2 (x, sizeof(mpfr_exp_t) * CHAR_BIT * 4);
+ mpfr_init2 (y, 8);
+ mpfr_set_si (x, mpfr_get_emax (), MPFR_RNDN);
+
+ mpfr_clear_flags ();
+ inex = mpfr_exp10 (y, x, MPFR_RNDN);
+ ov = mpfr_overflow_p ();
+ if (!ov || !mpfr_inf_p (y) || inex <= 0)
+ {
+ printf ("Overflow error for x = emax, MPFR_RNDN.\n");
+ mpfr_dump (y);
+ printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ }
+}
+
+static void
+exp_range (void)
+{
+ mpfr_t x;
+ mpfr_exp_t emin;
+
+ emin = mpfr_get_emin ();
+ set_emin (3);
+ mpfr_init2 (x, 16);
+ mpfr_set_ui (x, 4, MPFR_RNDN);
+ mpfr_exp10 (x, x, MPFR_RNDN);
+ set_emin (emin);
+ if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 10000) != 0)
+ {
+ printf ("Error in mpfr_exp10 for x = 4, with emin = 3\n");
+ printf ("Expected 10000, got ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clear (x);
+}
+
+static void
+overfl_exp10_0 (void)
+{
+ mpfr_t x, y;
+ int emax, i, inex, rnd, err = 0;
+ mpfr_exp_t old_emax;
+
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ for (emax = -1; emax <= 0; emax++)
+ {
+ mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
+ mpfr_nextbelow (y);
+ set_emax (emax); /* 1 is not representable. */
+ /* and if emax < 0, 1 - eps is not representable either. */
+ for (i = -1; i <= 1; i++)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_exp10 (x, x, (mpfr_rnd_t) rnd);
+ if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
+ ! mpfr_overflow_p ())
+ {
+ printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
+ " The overflow flag is not set.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ {
+ if (inex >= 0)
+ {
+ printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (x, y))
+ {
+ printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of 0.11111111E%d.\n", emax);
+ err = 1;
+ }
+ }
+ else
+ {
+ if (inex <= 0)
+ {
+ printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
+ {
+ printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of +Inf.\n");
+ err = 1;
+ }
+ }
+ }
+ set_emax (old_emax);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ mpfr_exp_t emin, emax;
+ int inex, ov;
+
+ tests_start_mpfr ();
+
+ special_overflow ();
+ emax_m_eps ();
+ exp_range ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_ui (x, 4, MPFR_RNDN);
+ mpfr_exp10 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 10000) != 0)
+ {
+ printf ("Error for 10^4, MPFR_RNDN\n");
+ exit (1);
+ }
+ mpfr_exp10 (y, x, MPFR_RNDD);
+ if (mpfr_cmp_ui (y, 10000) != 0)
+ {
+ printf ("Error for 10^4, MPFR_RNDD\n");
+ exit (1);
+ }
+ mpfr_exp10 (y, x, MPFR_RNDU);
+ if (mpfr_cmp_ui (y, 10000) != 0)
+ {
+ printf ("Error for 10^4, MPFR_RNDU\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 10);
+ mpfr_set_prec (y, 10);
+ /* save emin */
+ emin = mpfr_get_emin ();
+ set_emin (-11);
+ mpfr_set_si (x, -4, MPFR_RNDN);
+ mpfr_exp10 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for emin = -11, x = -4, RNDN\n");
+ printf ("Expected +0\n");
+ printf ("Got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ /* restore emin */
+ set_emin (emin);
+
+ /* save emax */
+ emax = mpfr_get_emax ();
+ set_emax (13);
+ mpfr_set_ui (x, 4, MPFR_RNDN);
+ mpfr_exp10 (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for emax = 13, x = 4, RNDN\n");
+ printf ("Expected +inf\n");
+ printf ("Got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ /* restore emax */
+ set_emax (emax);
+
+ MPFR_SET_INF (x);
+ MPFR_SET_POS (x);
+ mpfr_exp10 (y, x, MPFR_RNDN);
+ if (!MPFR_IS_INF (y))
+ {
+ printf ("evaluation of function in INF does not return INF\n");
+ exit (1);
+ }
+
+ MPFR_CHANGE_SIGN (x);
+ mpfr_exp10 (y, x, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (y))
+ {
+ printf ("evaluation of function in -INF does not return 0\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN (x);
+ mpfr_exp10 (y, x, MPFR_RNDN);
+ if (!MPFR_IS_NAN (y))
+ {
+ printf ("evaluation of function in NaN does not return NaN\n");
+ exit (1);
+ }
+
+ if ((mpfr_uexp_t) 8 << 31 != 0 ||
+ mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000)
+ {
+ /* emax <= 10000000000 */
+ mpfr_set_prec (x, 40);
+ mpfr_set_prec (y, 40);
+ mpfr_set_str (x, "3010299957", 10, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_exp10 (y, x, MPFR_RNDN);
+ ov = mpfr_overflow_p ();
+ if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && ov))
+ {
+ printf ("Overflow error for x = 3010299957, MPFR_RNDN.\n");
+ mpfr_dump (y);
+ printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
+ exit (1);
+ }
+ }
+
+ test_generic (2, 100, 100);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ overfl_exp10_0 ();
+
+ data_check ("data/exp10", mpfr_exp10, "mpfr_exp10");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/texp2.c b/mpfr/tests/texp2.c
new file mode 100644
index 0000000000..3b2fbeabdc
--- /dev/null
+++ b/mpfr/tests/texp2.c
@@ -0,0 +1,379 @@
+/* Test file for mpfr_exp2.
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_exp2
+#define TEST_RANDOM_EMIN -36
+#define TEST_RANDOM_EMAX 36
+#include "tgeneric.c"
+
+static void
+special_overflow (void)
+{
+ mpfr_t x, y;
+ int inex;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ set_emin (-125);
+ set_emax (128);
+
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 24);
+
+ mpfr_set_str_binary (x, "0.101100100000000000110100E15");
+ inex = mpfr_exp2 (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || inex <= 0)
+ {
+ printf ("Overflow error.\n");
+ mpfr_dump (y);
+ printf ("inex = %d\n", inex);
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+ set_emin (emin);
+ set_emax (emax);
+}
+
+static void
+emax_m_eps (void)
+{
+ if (mpfr_get_emax () <= LONG_MAX)
+ {
+ mpfr_t x, y;
+ int inex, ov;
+
+ mpfr_init2 (x, sizeof(mpfr_exp_t) * CHAR_BIT * 4);
+ mpfr_init2 (y, 8);
+ mpfr_set_si (x, mpfr_get_emax (), MPFR_RNDN);
+
+ mpfr_clear_flags ();
+ inex = mpfr_exp2 (y, x, MPFR_RNDN);
+ ov = mpfr_overflow_p ();
+ if (!ov || !mpfr_inf_p (y) || inex <= 0)
+ {
+ printf ("Overflow error for x = emax, MPFR_RNDN.\n");
+ mpfr_dump (y);
+ printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
+ exit (1);
+ }
+
+ mpfr_nextbelow (x);
+
+ mpfr_clear_flags ();
+ inex = mpfr_exp2 (y, x, MPFR_RNDN);
+ ov = mpfr_overflow_p ();
+ if (!ov || !mpfr_inf_p (y) || inex <= 0)
+ {
+ printf ("Overflow error for x = emax - eps, MPFR_RNDN.\n");
+ mpfr_dump (y);
+ printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
+ exit (1);
+ }
+
+ mpfr_clear_flags ();
+ inex = mpfr_exp2 (y, x, MPFR_RNDD);
+ ov = mpfr_overflow_p ();
+ if (ov || mpfr_inf_p (y) || inex >= 0 ||
+ (mpfr_nextabove (y), !mpfr_inf_p (y)))
+ {
+ printf ("Overflow error for x = emax - eps, MPFR_RNDD.\n");
+ mpfr_dump (y);
+ printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no ");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ }
+}
+
+static void
+exp_range (void)
+{
+ mpfr_t x;
+ mpfr_exp_t emin;
+
+ emin = mpfr_get_emin ();
+ set_emin (3);
+ mpfr_init2 (x, 8);
+ mpfr_set_ui (x, 5, MPFR_RNDN);
+ mpfr_exp2 (x, x, MPFR_RNDN);
+ set_emin (emin);
+ if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 32) != 0)
+ {
+ printf ("Error in mpfr_exp2 for x = 5, with emin = 3\n");
+ printf ("Expected 32, got ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clear (x);
+}
+
+static void
+overflowed_exp2_0 (void)
+{
+ mpfr_t x, y;
+ int emax, i, inex, rnd, err = 0;
+ mpfr_exp_t old_emax;
+
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ for (emax = -1; emax <= 0; emax++)
+ {
+ mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
+ mpfr_nextbelow (y);
+ set_emax (emax); /* 1 is not representable. */
+ /* and if emax < 0, 1 - eps is not representable either. */
+ for (i = -1; i <= 1; i++)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_exp2 (x, x, (mpfr_rnd_t) rnd);
+ if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
+ ! mpfr_overflow_p ())
+ {
+ printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
+ " The overflow flag is not set.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ {
+ if (inex >= 0)
+ {
+ printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (x, y))
+ {
+ printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of 0.11111111E%d.\n", emax);
+ err = 1;
+ }
+ }
+ else
+ {
+ if (inex <= 0)
+ {
+ printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
+ {
+ printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of +Inf.\n");
+ err = 1;
+ }
+ }
+ }
+ set_emax (old_emax);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ mpfr_exp_t emin, emax;
+
+ tests_start_mpfr ();
+
+ special_overflow ();
+ emax_m_eps ();
+ exp_range ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_ui (x, 4, MPFR_RNDN);
+ mpfr_exp2 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 16) != 0)
+ {
+ printf ("Error for 2^4, MPFR_RNDN\n");
+ exit (1);
+ }
+ mpfr_exp2 (y, x, MPFR_RNDD);
+ if (mpfr_cmp_ui (y, 16) != 0)
+ {
+ printf ("Error for 2^4, MPFR_RNDD\n");
+ exit (1);
+ }
+ mpfr_exp2 (y, x, MPFR_RNDU);
+ if (mpfr_cmp_ui (y, 16) != 0)
+ {
+ printf ("Error for 2^4, MPFR_RNDU\n");
+ exit (1);
+ }
+
+ mpfr_set_si (x, -4, MPFR_RNDN);
+ mpfr_exp2 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui_2exp (y, 1, -4) != 0)
+ {
+ printf ("Error for 2^(-4), MPFR_RNDN\n");
+ exit (1);
+ }
+ mpfr_exp2 (y, x, MPFR_RNDD);
+ if (mpfr_cmp_ui_2exp (y, 1, -4) != 0)
+ {
+ printf ("Error for 2^(-4), MPFR_RNDD\n");
+ exit (1);
+ }
+ mpfr_exp2 (y, x, MPFR_RNDU);
+ if (mpfr_cmp_ui_2exp (y, 1, -4) != 0)
+ {
+ printf ("Error for 2^(-4), MPFR_RNDU\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str (x, /*-1683977482443233.0 / 2199023255552.0*/
+ "-7.6578429909351734750089235603809357e2", 10, MPFR_RNDN);
+ mpfr_exp2 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str1 (y, "2.991959870867646566478e-231"))
+ {
+ printf ("Error for x=-1683977482443233/2^41\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 10);
+ mpfr_set_prec (y, 10);
+ /* save emin */
+ emin = mpfr_get_emin ();
+ set_emin (-10);
+ mpfr_set_si (x, -12, MPFR_RNDN);
+ mpfr_exp2 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for x=emin-2, RNDN\n");
+ printf ("Expected +0\n");
+ printf ("Got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ /* restore emin */
+ set_emin (emin);
+
+ /* save emax */
+ emax = mpfr_get_emax ();
+ set_emax (10);
+ mpfr_set_ui (x, 11, MPFR_RNDN);
+ mpfr_exp2 (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for x=emax+1, RNDN\n");
+ exit (1);
+ }
+ /* restore emax */
+ set_emax (emax);
+
+ MPFR_SET_INF(x);
+ MPFR_SET_POS(x);
+ mpfr_exp2 (y, x, MPFR_RNDN);
+ if(!MPFR_IS_INF(y))
+ {
+ printf ("evaluation of function in INF does not return INF\n");
+ exit (1);
+ }
+
+ MPFR_CHANGE_SIGN(x);
+ mpfr_exp2 (y, x, MPFR_RNDN);
+ if(!MPFR_IS_ZERO(y))
+ {
+ printf ("evaluation of function in -INF does not return 0\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN(x);
+ mpfr_exp2 (y, x, MPFR_RNDN);
+ if(!MPFR_IS_NAN(y))
+ {
+ printf ("evaluation of function in NaN does not return NaN\n");
+ exit (1);
+ }
+
+ if ((mpfr_uexp_t) 8 << 31 != 0 ||
+ mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000)
+ {
+ /* emax <= 10000000000 */
+ mpfr_set_prec (x, 40);
+ mpfr_set_prec (y, 40);
+ mpfr_set_str (x, "10000000000.5", 10, MPFR_RNDN);
+ mpfr_clear_flags ();
+ mpfr_exp2 (y, x, MPFR_RNDN);
+ if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && mpfr_overflow_p ()))
+ {
+ printf ("exp2(10000000000.5) should overflow.\n");
+ exit (1);
+ }
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 2);
+ mpfr_set_str_binary (x, "-1.0E-26");
+ mpfr_exp2 (y, x, MPFR_RNDD);
+ mpfr_set_str_binary (x, "1.1E-1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for exp(-2^(-26)) for prec=2\n");
+ exit (1);
+ }
+
+ test_generic (2, 100, 100);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ overflowed_exp2_0 ();
+
+ data_check ("data/exp2", mpfr_exp2, "mpfr_exp2");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/texpm1.c b/mpfr/tests/texpm1.c
new file mode 100644
index 0000000000..7f518a2c1a
--- /dev/null
+++ b/mpfr/tests/texpm1.c
@@ -0,0 +1,173 @@
+/* Test file for mpfr_expm1.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_expm1 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ }
+ res = mpfr_expm1 (a, b, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_expm1 mpfr_expm1
+#endif
+
+#define TEST_FUNCTION test_expm1
+#define TEST_RANDOM_EMIN -36
+#define TEST_RANDOM_EMAX 36
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int i;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_nan (x);
+ test_expm1 (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for expm1(NaN)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ test_expm1 (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for expm1(+Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ test_expm1 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_si (y, -1))
+ {
+ printf ("Error for expm1(-Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ test_expm1 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for expm1(+0)\n");
+ exit (1);
+ }
+
+ mpfr_neg (x, x, MPFR_RNDN);
+ test_expm1 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error for expm1(-0)\n");
+ exit (1);
+ }
+
+ /* Check overflow of expm1(x) */
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "1.1E1000000000");
+ i = test_expm1 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
+ MPFR_ASSERTN (mpfr_overflow_p ());
+ MPFR_ASSERTN (i == 1);
+
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "1.1E1000000000");
+ i = test_expm1 (x, x, MPFR_RNDU);
+ MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
+ MPFR_ASSERTN (mpfr_overflow_p ());
+ MPFR_ASSERTN (i == 1);
+
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "1.1E1000000000");
+ i = test_expm1 (x, x, MPFR_RNDD);
+ MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
+ MPFR_ASSERTN (mpfr_overflow_p ());
+ MPFR_ASSERTN (i == -1);
+
+ /* Check internal underflow of expm1 (x) */
+ mpfr_set_prec (x, 2);
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "-1.1E1000000000");
+ i = test_expm1 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0);
+ MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == -1);
+
+ mpfr_set_str_binary (x, "-1.1E1000000000");
+ i = test_expm1 (x, x, MPFR_RNDD);
+ MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0);
+ MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == -1);
+
+ mpfr_set_str_binary (x, "-1.1E1000000000");
+ i = test_expm1 (x, x, MPFR_RNDZ);
+ MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0);
+ MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == 1);
+
+ mpfr_set_str_binary (x, "-1.1E1000000000");
+ i = test_expm1 (x, x, MPFR_RNDU);
+ MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0);
+ MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == 1);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+
+ test_generic (2, 100, 100);
+
+ data_check ("data/expm1", mpfr_expm1, "mpfr_expm1");
+ bad_cases (mpfr_expm1, mpfr_log1p, "mpfr_expm1", 256, -256, 255,
+ 4, 128, 800, 40);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tfactorial.c b/mpfr/tests/tfactorial.c
new file mode 100644
index 0000000000..7579da2be4
--- /dev/null
+++ b/mpfr/tests/tfactorial.c
@@ -0,0 +1,287 @@
+/* Test file for mpfr_factorial.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_fac_ui
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int inex;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_prec (x, 21);
+ mpfr_set_prec (y, 21);
+ mpfr_fac_ui (x, 119, MPFR_RNDZ);
+ mpfr_set_str_binary (y, "0.101111101110100110110E654");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_fac_ui (119)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (y, 206);
+ inex = mpfr_fac_ui (y, 767, MPFR_RNDN);
+ mpfr_set_prec (x, 206);
+ mpfr_set_str_binary (x, "0.110111100001000001101010010001000111000100000100111000010011100011011111001100011110101000111101101100110001001100110100001001111110000101010000100100011100010011101110000001000010001100010000101001111E6250");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_fac_ui (767)\n");
+ exit (1);
+ }
+ if (inex <= 0)
+ {
+ printf ("Wrong flag for mpfr_fac_ui (767)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (y, 202);
+ mpfr_fac_ui (y, 69, MPFR_RNDU);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+test_int (void)
+{
+ unsigned long n0 = 1, n1 = 80, n;
+ mpz_t f;
+ mpfr_t x, y;
+ mpfr_prec_t prec_f, p;
+ int r;
+ int inex1, inex2;
+
+ mpz_init (f);
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpz_fac_ui (f, n0 - 1);
+ for (n = n0; n <= n1; n++)
+ {
+ mpz_mul_ui (f, f, n); /* f = n! */
+ prec_f = mpz_sizeinbase (f, 2) - mpz_scan1 (f, 0);
+ for (p = MPFR_PREC_MIN; p <= prec_f; p++)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_set_prec (y, p);
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ inex1 = mpfr_fac_ui (x, n, (mpfr_rnd_t) r);
+ inex2 = mpfr_set_z (y, f, (mpfr_rnd_t) r);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for n=%lu prec=%lu rnd=%s\n",
+ n, (unsigned long) p, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ if ((inex1 < 0 && inex2 >= 0) || (inex1 == 0 && inex2 != 0)
+ || (inex1 > 0 && inex2 <= 0))
+ {
+ printf ("Wrong inexact flag for n=%lu prec=%lu rnd=%s\n",
+ n, (unsigned long) p, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpz_clear (f);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+overflowed_fac0 (void)
+{
+ mpfr_t x, y;
+ int inex, rnd, err = 0;
+ mpfr_exp_t old_emax;
+
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_nextbelow (y);
+ set_emax (0); /* 1 is not representable. */
+ RND_LOOP (rnd)
+ {
+ mpfr_clear_flags ();
+ inex = mpfr_fac_ui (x, 0, (mpfr_rnd_t) rnd);
+ if (! mpfr_overflow_p ())
+ {
+ printf ("Error in overflowed_fac0 (rnd = %s):\n"
+ " The overflow flag is not set.\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ {
+ if (inex >= 0)
+ {
+ printf ("Error in overflowed_fac0 (rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (x, y))
+ {
+ printf ("Error in overflowed_fac0 (rnd = %s):\n"
+ " Got ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of 0.11111111E0.\n");
+ err = 1;
+ }
+ }
+ else
+ {
+ if (inex <= 0)
+ {
+ printf ("Error in overflowed_fac0 (rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
+ {
+ printf ("Error in overflowed_fac0 (rnd = %s):\n"
+ " Got ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of +Inf.\n");
+ err = 1;
+ }
+ }
+ }
+ set_emax (old_emax);
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ unsigned int prec, err, yprec, n, k, zeros;
+ int rnd;
+ mpfr_t x, y, z, t;
+ int inexact;
+
+ tests_start_mpfr ();
+
+ special ();
+
+ test_int ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (t);
+
+ mpfr_fac_ui (y, 0, MPFR_RNDN);
+
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("mpfr_fac_ui(0) does not give 1\n");
+ exit (1);
+ }
+
+ for (prec = 2; prec <= 100; prec++)
+ {
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (z, prec);
+ mpfr_set_prec (t, prec);
+ yprec = prec + 10;
+ mpfr_set_prec (y, yprec);
+
+ for (n = 0; n < 50; n++)
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ inexact = mpfr_fac_ui (y, n, (mpfr_rnd_t) rnd);
+ err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec;
+ if (mpfr_can_round (y, err, (mpfr_rnd_t) rnd, (mpfr_rnd_t) rnd, prec))
+ {
+ mpfr_set (t, y, (mpfr_rnd_t) rnd);
+ inexact = mpfr_fac_ui (z, n, (mpfr_rnd_t) rnd);
+ /* fact(n) ends with floor(n/2)+floor(n/4)+... zeros */
+ for (k=n/2, zeros=0; k; k >>= 1)
+ zeros += k;
+ if (MPFR_EXP(y) <= (mpfr_exp_t) (prec + zeros))
+ /* result should be exact */
+ {
+ if (inexact)
+ {
+ printf ("Wrong inexact flag: expected exact\n");
+ exit (1);
+ }
+ }
+ else /* result is inexact */
+ {
+ if (!inexact)
+ {
+ printf ("Wrong inexact flag: expected inexact\n");
+ printf ("n=%u prec=%u\n", n, prec);
+ mpfr_print_binary(z); puts ("");
+ exit (1);
+ }
+ }
+ if (mpfr_cmp (t, z))
+ {
+ printf ("results differ for x=");
+ mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
+ printf (" prec=%u rnd_mode=%s\n", prec,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf (" got ");
+ mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
+ puts ("");
+ printf (" expected ");
+ mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
+ puts ("");
+ printf (" approximation was ");
+ mpfr_print_binary (y);
+ puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+
+ overflowed_fac0 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tfits.c b/mpfr/tests/tfits.c
new file mode 100644
index 0000000000..8aebb4176c
--- /dev/null
+++ b/mpfr/tests/tfits.c
@@ -0,0 +1,273 @@
+/* Test file for:
+ mpfr_fits_sint_p, mpfr_fits_slong_p, mpfr_fits_sshort_p,
+ mpfr_fits_uint_p, mpfr_fits_ulong_p, mpfr_fits_ushort_p
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-intmax.h"
+#include "mpfr-test.h"
+
+#define ERROR1 { printf("Initial error for x="); mpfr_dump(x); exit(1); }
+#define ERROR2 { printf("Error for x="); mpfr_dump(x); exit(1); }
+
+static void check_intmax (void);
+
+int
+main (void)
+{
+ mpfr_t x;
+
+ tests_start_mpfr ();
+
+ mpfr_init2 (x, 256);
+
+ /* Check NAN */
+ mpfr_set_nan (x);
+ if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_slong_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_uint_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_sint_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_ushort_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_sshort_p (x, MPFR_RNDN))
+ ERROR1;
+
+ /* Check INF */
+ mpfr_set_inf (x, 1);
+ if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_slong_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_uint_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_sint_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_ushort_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_sshort_p (x, MPFR_RNDN))
+ ERROR1;
+
+ /* Check Zero */
+ MPFR_SET_ZERO (x);
+ if (!mpfr_fits_ulong_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_uint_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_ushort_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+ ERROR2;
+
+ /* Check small op */
+ mpfr_set_str1 (x, "1@-1");
+ if (!mpfr_fits_ulong_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_uint_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_ushort_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+ ERROR2;
+
+ /* Check 17 */
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ if (!mpfr_fits_ulong_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_uint_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_ushort_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+ ERROR2;
+
+ /* Check all other values */
+ mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
+ if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_slong_p (x, MPFR_RNDN))
+ ERROR1;
+ mpfr_mul_2exp (x, x, 40, MPFR_RNDN);
+ if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_uint_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_sint_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_ushort_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_sshort_p (x, MPFR_RNDN))
+ ERROR1;
+
+ mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
+ if (!mpfr_fits_ulong_p (x, MPFR_RNDN))
+ ERROR2;
+ mpfr_set_ui (x, LONG_MAX, MPFR_RNDN);
+ if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+ ERROR2;
+ mpfr_set_ui (x, UINT_MAX, MPFR_RNDN);
+ if (!mpfr_fits_uint_p (x, MPFR_RNDN))
+ ERROR2;
+ mpfr_set_ui (x, INT_MAX, MPFR_RNDN);
+ if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+ ERROR2;
+ mpfr_set_ui (x, USHRT_MAX, MPFR_RNDN);
+ if (!mpfr_fits_ushort_p (x, MPFR_RNDN))
+ ERROR2;
+ mpfr_set_ui (x, SHRT_MAX, MPFR_RNDN);
+ if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+ ERROR2;
+
+ mpfr_set_si (x, 1, MPFR_RNDN);
+ if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+ ERROR2;
+
+ /* Check negative value */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+ ERROR2;
+ if (mpfr_fits_uint_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_ushort_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+ ERROR1;
+
+ mpfr_clear (x);
+
+ check_intmax ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+static void check_intmax (void)
+{
+#ifdef _MPFR_H_HAVE_INTMAX_T
+ mpfr_t x;
+
+ mpfr_init2 (x, sizeof (uintmax_t)*CHAR_BIT);
+
+ /* Check NAN */
+ mpfr_set_nan (x);
+ if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR1;
+
+ /* Check INF */
+ mpfr_set_inf (x, 1);
+ if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR1;
+
+ /* Check Zero */
+ MPFR_SET_ZERO (x);
+ if (!mpfr_fits_uintmax_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR2;
+
+ /* Check small op */
+ mpfr_set_str1 (x, "1@-1");
+ if (!mpfr_fits_uintmax_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR2;
+
+ /* Check 17 */
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ if (!mpfr_fits_uintmax_p (x, MPFR_RNDN))
+ ERROR2;
+ if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR2;
+
+ /* Check hugest */
+ mpfr_set_ui_2exp (x, 42, sizeof (uintmax_t) * 32, MPFR_RNDN);
+ if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+ ERROR1;
+ if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR1;
+
+ /* Check all other values */
+ mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+ ERROR1;
+ mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
+ if (!mpfr_fits_uintmax_p (x, MPFR_RNDN))
+ ERROR2;
+ mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR1;
+ mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
+ if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR2;
+ mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN);
+ if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR2;
+ mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+ if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR1;
+
+ /* Check negative value */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+ ERROR2;
+ if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+ ERROR1;
+
+ mpfr_clear (x);
+#endif
+}
+
diff --git a/mpfr/tests/tfma.c b/mpfr/tests/tfma.c
new file mode 100644
index 0000000000..2d6b150bbd
--- /dev/null
+++ b/mpfr/tests/tfma.c
@@ -0,0 +1,731 @@
+/* Test file for mpfr_fma.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* When a * b is exact, the FMA is equivalent to the separate operations. */
+static void
+test_exact (void)
+{
+ const char *val[] =
+ { "@NaN@", "-@Inf@", "-2", "-1", "-0", "0", "1", "2", "@Inf@" };
+ int sv = sizeof (val) / sizeof (*val);
+ int i, j, k;
+ int rnd;
+ mpfr_t a, b, c, r1, r2;
+
+ mpfr_inits2 (8, a, b, c, r1, r2, (mpfr_ptr) 0);
+
+ for (i = 0; i < sv; i++)
+ for (j = 0; j < sv; j++)
+ for (k = 0; k < sv; k++)
+ RND_LOOP (rnd)
+ {
+ if (mpfr_set_str (a, val[i], 10, MPFR_RNDN) ||
+ mpfr_set_str (b, val[j], 10, MPFR_RNDN) ||
+ mpfr_set_str (c, val[k], 10, MPFR_RNDN) ||
+ mpfr_mul (r1, a, b, (mpfr_rnd_t) rnd) ||
+ mpfr_add (r1, r1, c, (mpfr_rnd_t) rnd))
+ {
+ printf ("test_exact internal error for (%d,%d,%d,%d)\n",
+ i, j, k, rnd);
+ exit (1);
+ }
+ if (mpfr_fma (r2, a, b, c, (mpfr_rnd_t) rnd))
+ {
+ printf ("test_exact(%d,%d,%d,%d): mpfr_fma should be exact\n",
+ i, j, k, rnd);
+ exit (1);
+ }
+ if (MPFR_IS_NAN (r1))
+ {
+ if (MPFR_IS_NAN (r2))
+ continue;
+ printf ("test_exact(%d,%d,%d,%d): mpfr_fma should be NaN\n",
+ i, j, k, rnd);
+ exit (1);
+ }
+ if (mpfr_cmp (r1, r2) || MPFR_SIGN (r1) != MPFR_SIGN (r2))
+ {
+ printf ("test_exact(%d,%d,%d,%d):\nexpected ", i, j, k, rnd);
+ mpfr_out_str (stdout, 10, 0, r1, MPFR_RNDN);
+ printf ("\n got ");
+ mpfr_out_str (stdout, 10, 0, r2, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ }
+
+ mpfr_clears (a, b, c, r1, r2, (mpfr_ptr) 0);
+}
+
+static void
+test_overflow1 (void)
+{
+ mpfr_t x, y, z, r;
+ int inex;
+
+ mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);
+ MPFR_SET_POS (x);
+ mpfr_setmax (x, mpfr_get_emax ()); /* x = 2^emax - ulp */
+ mpfr_set_ui (y, 2, MPFR_RNDN); /* y = 2 */
+ mpfr_neg (z, x, MPFR_RNDN); /* z = -x = -(2^emax - ulp) */
+ mpfr_clear_flags ();
+ /* The intermediate multiplication x * y overflows, but x * y + z = x
+ is representable. */
+ inex = mpfr_fma (r, x, y, z, MPFR_RNDN);
+ if (inex || ! mpfr_equal_p (r, x))
+ {
+ printf ("Error in test_overflow1\nexpected ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf (" with inex = 0\n got ");
+ mpfr_out_str (stdout, 2, 0, r, MPFR_RNDN);
+ printf (" with inex = %d\n", inex);
+ exit (1);
+ }
+ if (mpfr_overflow_p ())
+ {
+ printf ("Error in test_overflow1: overflow flag set\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
+}
+
+static void
+test_overflow2 (void)
+{
+ mpfr_t x, y, z, r;
+ int i, inex, rnd, err = 0;
+
+ mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);
+
+ MPFR_SET_POS (x);
+ mpfr_setmin (x, mpfr_get_emax ()); /* x = 0.1@emax */
+ mpfr_set_si (y, -2, MPFR_RNDN); /* y = -2 */
+ /* The intermediate multiplication x * y will overflow. */
+
+ for (i = -9; i <= 9; i++)
+ RND_LOOP (rnd)
+ {
+ int inf, overflow;
+
+ inf = rnd == MPFR_RNDN || rnd == MPFR_RNDD || rnd == MPFR_RNDA;
+ overflow = inf || i <= 0;
+
+ inex = mpfr_set_si_2exp (z, i, mpfr_get_emin (), MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+
+ mpfr_clear_flags ();
+ /* One has: x * y = -1@emax exactly (but not representable). */
+ inex = mpfr_fma (r, x, y, z, (mpfr_rnd_t) rnd);
+ if (overflow ^ (mpfr_overflow_p () != 0))
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): wrong overflow"
+ " flag (should be %d)\n", i,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), overflow);
+ err = 1;
+ }
+ if (mpfr_nanflag_p ())
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): NaN flag should"
+ " not be set\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (mpfr_nan_p (r))
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): got NaN\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ else if (MPFR_SIGN (r) >= 0)
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): wrong sign "
+ "(+ instead of -)\n", i,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ else if (inf && ! mpfr_inf_p (r))
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): expected -Inf,"
+ " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_dump (r);
+ err = 1;
+ }
+ else if (!inf && (mpfr_inf_p (r) ||
+ (mpfr_nextbelow (r), ! mpfr_inf_p (r))))
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): expected -MAX,"
+ " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_dump (r);
+ err = 1;
+ }
+ if (inf ? inex >= 0 : inex <= 0)
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): wrong inexact"
+ " flag (got %d)\n", i,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex);
+ err = 1;
+ }
+
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
+}
+
+static void
+test_underflow1 (void)
+{
+ mpfr_t x, y, z, r;
+ int inex, signy, signz, rnd, err = 0;
+
+ mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);
+
+ MPFR_SET_POS (x);
+ mpfr_setmin (x, mpfr_get_emin ()); /* x = 0.1@emin */
+
+ for (signy = -1; signy <= 1; signy += 2)
+ {
+ mpfr_set_si_2exp (y, signy, -1, MPFR_RNDN); /* |y| = 1/2 */
+ for (signz = -3; signz <= 3; signz += 2)
+ {
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si (z, signz, MPFR_RNDN);
+ if (ABS (signz) != 1)
+ mpfr_setmax (z, mpfr_get_emax ());
+ /* |z| = 1 or 2^emax - ulp */
+ mpfr_clear_flags ();
+ inex = mpfr_fma (r, x, y, z, (mpfr_rnd_t) rnd);
+#define ERRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n "
+ if (mpfr_nanflag_p ())
+ {
+ printf (ERRTU1 "NaN flag is set\n", signy, signz,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (signy < 0 && MPFR_IS_LIKE_RNDD(rnd, signz))
+ mpfr_nextbelow (z);
+ if (signy > 0 && MPFR_IS_LIKE_RNDU(rnd, signz))
+ mpfr_nextabove (z);
+ if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0))
+ {
+ printf (ERRTU1 "wrong overflow flag\n", signy, signz,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (mpfr_underflow_p ())
+ {
+ printf (ERRTU1 "underflow flag is set\n", signy, signz,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (r, z))
+ {
+ printf (ERRTU1 "got ", signy, signz,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (r);
+ printf (" instead of ");
+ mpfr_print_binary (z);
+ printf ("\n");
+ err = 1;
+ }
+ if (inex >= 0 && (rnd == MPFR_RNDD ||
+ (rnd == MPFR_RNDZ && signz > 0) ||
+ (rnd == MPFR_RNDN && signy > 0)))
+ {
+ printf (ERRTU1 "ternary value = %d instead of < 0\n",
+ signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
+ inex);
+ err = 1;
+ }
+ if (inex <= 0 && (rnd == MPFR_RNDU ||
+ (rnd == MPFR_RNDZ && signz < 0) ||
+ (rnd == MPFR_RNDN && signy < 0)))
+ {
+ printf (ERRTU1 "ternary value = %d instead of > 0\n",
+ signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
+ inex);
+ err = 1;
+ }
+ }
+ }
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
+}
+
+static void
+test_underflow2 (void)
+{
+ mpfr_t x, y, z, r;
+ int b, i, inex, same, err = 0;
+
+ mpfr_inits2 (32, x, y, z, r, (mpfr_ptr) 0);
+
+ mpfr_set_si_2exp (z, 1, mpfr_get_emin (), MPFR_RNDN); /* z = 2^emin */
+ mpfr_set_si_2exp (x, 1, mpfr_get_emin (), MPFR_RNDN); /* x = 2^emin */
+
+ for (b = 0; b <= 1; b++)
+ {
+ for (i = 15; i <= 17; i++)
+ {
+ mpfr_set_si_2exp (y, i, -4 - MPFR_PREC (z), MPFR_RNDN);
+ /* z = 1.000...00b
+ * xy = 01111
+ * or 10000
+ * or 10001
+ */
+ mpfr_clear_flags ();
+ inex = mpfr_fma (r, x, y, z, MPFR_RNDN);
+#define ERRTU2 "Error in test_underflow2 (b = %d, i = %d)\n "
+ if (__gmpfr_flags != MPFR_FLAGS_INEXACT)
+ {
+ printf (ERRTU2 "flags = %u instead of %u\n", b, i,
+ __gmpfr_flags, (unsigned int) MPFR_FLAGS_INEXACT);
+ err = 1;
+ }
+ same = i == 15 || (i == 16 && b == 0);
+ if (same ? (inex >= 0) : (inex <= 0))
+ {
+ printf (ERRTU2 "incorrect ternary value (%d instead of %c 0)\n",
+ b, i, inex, same ? '<' : '>');
+ err = 1;
+ }
+ mpfr_set (y, z, MPFR_RNDN);
+ if (!same)
+ mpfr_nextabove (y);
+ if (! mpfr_equal_p (r, y))
+ {
+ printf (ERRTU2 "expected ", b, i);
+ mpfr_dump (y);
+ printf (" got ");
+ mpfr_dump (r);
+ err = 1;
+ }
+ }
+ mpfr_nextabove (z);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
+}
+
+static void
+bug20101018 (void)
+{
+ mpfr_t x, y, z, t, u;
+ int i;
+
+ mpfr_init2 (x, 64);
+ mpfr_init2 (y, 64);
+ mpfr_init2 (z, 64);
+ mpfr_init2 (t, 64);
+ mpfr_init2 (u, 64);
+
+ mpfr_set_str (x, "0xf.fffffffffffffffp-14766", 16, MPFR_RNDN);
+ mpfr_set_str (y, "-0xf.fffffffffffffffp+317", 16, MPFR_RNDN);
+ mpfr_set_str (z, "0x8.3ffffffffffe3ffp-14443", 16, MPFR_RNDN);
+ mpfr_set_str (t, "0x8.7ffffffffffc7ffp-14444", 16, MPFR_RNDN);
+ i = mpfr_fma (u, x, y, z, MPFR_RNDN);
+ if (mpfr_cmp (u, t) != 0)
+ {
+ printf ("Wrong result in bug20101018 (a)\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ if (i <= 0)
+ {
+ printf ("Wrong ternary value in bug20101018 (a)\n");
+ printf ("Expected > 0\n");
+ printf ("Got %d\n", i);
+ exit (1);
+ }
+
+ mpfr_set_str (x, "-0xf.fffffffffffffffp-11420", 16, MPFR_RNDN);
+ mpfr_set_str (y, "0xf.fffffffffffffffp+9863", 16, MPFR_RNDN);
+ mpfr_set_str (z, "0x8.fffff80ffffffffp-1551", 16, MPFR_RNDN);
+ mpfr_set_str (t, "0x9.fffff01ffffffffp-1552", 16, MPFR_RNDN);
+ i = mpfr_fma (u, x, y, z, MPFR_RNDN);
+ if (mpfr_cmp (u, t) != 0)
+ {
+ printf ("Wrong result in bug20101018 (b)\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ if (i <= 0)
+ {
+ printf ("Wrong ternary value in bug20101018 (b)\n");
+ printf ("Expected > 0\n");
+ printf ("Got %d\n", i);
+ exit (1);
+ }
+
+ mpfr_set_str (x, "0xf.fffffffffffffffp-2125", 16, MPFR_RNDN);
+ mpfr_set_str (y, "-0xf.fffffffffffffffp-6000", 16, MPFR_RNDN);
+ mpfr_set_str (z, "0x8p-8119", 16, MPFR_RNDN);
+ mpfr_set_str (t, "0x8.000000000000001p-8120", 16, MPFR_RNDN);
+ i = mpfr_fma (u, x, y, z, MPFR_RNDN);
+ if (mpfr_cmp (u, t) != 0)
+ {
+ printf ("Wrong result in bug20101018 (c)\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ if (i <= 0)
+ {
+ printf ("Wrong ternary value in bug20101018 (c)\n");
+ printf ("Expected > 0\n");
+ printf ("Got %d\n", i);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+ mpfr_clear (u);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y, z, s;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ tests_start_mpfr ();
+
+ bug20101018 ();
+
+ mpfr_init (x);
+ mpfr_init (s);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ /* check special cases */
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 2);
+ mpfr_set_prec (z, 2);
+ mpfr_set_prec (s, 2);
+ mpfr_set_str (x, "-0.75", 10, MPFR_RNDN);
+ mpfr_set_str (y, "0.5", 10, MPFR_RNDN);
+ mpfr_set_str (z, "0.375", 10, MPFR_RNDN);
+ mpfr_fma (s, x, y, z, MPFR_RNDU); /* result is 0 */
+ if (mpfr_cmp_ui(s, 0))
+ {
+ printf("Error: -0.75 * 0.5 + 0.375 should be equal to 0 for prec=2\n");
+ exit(1);
+ }
+
+ mpfr_set_prec (x, 27);
+ mpfr_set_prec (y, 27);
+ mpfr_set_prec (z, 27);
+ mpfr_set_prec (s, 27);
+ mpfr_set_str_binary (x, "1.11111111111111111111111111e-1");
+ mpfr_set (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (z, "-1.00011110100011001011001001e-1");
+ if (mpfr_fma (s, x, y, z, MPFR_RNDN) >= 0)
+ {
+ printf ("Wrong inexact flag for x=y=1-2^(-27)\n");
+ exit (1);
+ }
+
+ mpfr_set_nan (x);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x=NAN does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_nan (y);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p(s))
+ {
+ printf ("evaluation of function in y=NAN does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_nan (z);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (x, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in z=NAN does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, 1);
+ mpfr_set_inf (z, 1);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("Error for (+inf) * (+inf) + (+inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_set_inf (y, -1);
+ mpfr_set_inf (z, 1);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("Error for (-inf) * (-inf) + (+inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, -1);
+ mpfr_set_inf (z, -1);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0)
+ {
+ printf ("Error for (+inf) * (-inf) + (-inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_set_inf (y, 1);
+ mpfr_set_inf (z, -1);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0)
+ {
+ printf ("Error for (-inf) * (+inf) + (-inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x=INF y=0 does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (y, 1);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x=0 y=INF does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_urandomb (y, RANDS); /* always positive */
+ mpfr_set_inf (z, -1);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x=INF y>0 z=-INF does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (y, 1);
+ mpfr_urandomb (x, RANDS);
+ mpfr_set_inf (z, -1);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x>0 y=INF z=-INF does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("evaluation of function in x=INF does not return INF");
+ exit (1);
+ }
+
+ mpfr_set_inf (y, 1);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("evaluation of function in y=INF does not return INF");
+ exit (1);
+ }
+
+ mpfr_set_inf (z, 1);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (y, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("evaluation of function in z=INF does not return INF");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (mpfr_cmp (s, z))
+ {
+ printf ("evaluation of function in x=0 does not return z\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fma (s, x, y, z, MPFR_RNDN);
+ if (mpfr_cmp (s, z))
+ {
+ printf ("evaluation of function in y=0 does not return z\n");
+ exit (1);
+ }
+
+ {
+ mpfr_prec_t prec;
+ mpfr_t t, slong;
+ mpfr_rnd_t rnd;
+ int inexact, compare;
+ unsigned int n;
+
+ mpfr_prec_t p0=2, p1=200;
+ unsigned int N=200;
+
+ mpfr_init (t);
+ mpfr_init (slong);
+
+ /* generic test */
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (y, prec);
+ mpfr_set_prec (z, prec);
+ mpfr_set_prec (s, prec);
+ mpfr_set_prec (t, prec);
+
+ for (n=0; n<N; n++)
+ {
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (z, RANDS);
+
+ if (randlimb () % 2)
+ mpfr_neg (x, x, MPFR_RNDN);
+ if (randlimb () % 2)
+ mpfr_neg (y, y, MPFR_RNDN);
+ if (randlimb () % 2)
+ mpfr_neg (z, z, MPFR_RNDN);
+
+ rnd = RND_RAND ();
+ mpfr_set_prec (slong, 2 * prec);
+ if (mpfr_mul (slong, x, y, rnd))
+ {
+ printf ("x*y should be exact\n");
+ exit (1);
+ }
+ compare = mpfr_add (t, slong, z, rnd);
+ inexact = mpfr_fma (s, x, y, z, rnd);
+ if (mpfr_cmp (s, t))
+ {
+ printf ("results differ for x=");
+ mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
+ printf (" y=");
+ mpfr_out_str (stdout, 2, prec, y, MPFR_RNDN);
+ printf (" z=");
+ mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
+ printf (" prec=%u rnd_mode=%s\n", (unsigned int) prec,
+ mpfr_print_rnd_mode (rnd));
+ printf ("got ");
+ mpfr_out_str (stdout, 2, prec, s, MPFR_RNDN);
+ puts ("");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
+ puts ("");
+ printf ("approx ");
+ mpfr_print_binary (slong);
+ puts ("");
+ exit (1);
+ }
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact < 0) && (compare >= 0)) ||
+ ((inexact > 0) && (compare <= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n",
+ mpfr_print_rnd_mode (rnd), compare, inexact);
+ printf (" x="); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf (" y="); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf (" z="); mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf (" s="); mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ }
+ }
+ mpfr_clear (t);
+ mpfr_clear (slong);
+
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (s);
+
+ test_exact ();
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ test_overflow1 ();
+ test_overflow2 ();
+ test_underflow1 ();
+ test_underflow2 ();
+ MPFR_SAVE_EXPO_FREE (expo);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tfmod.c b/mpfr/tests/tfmod.c
new file mode 100644
index 0000000000..27bed7976c
--- /dev/null
+++ b/mpfr/tests/tfmod.c
@@ -0,0 +1,384 @@
+/* tfmod -- test file for mpfr_fmod
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+#define TEST_FUNCTION mpfr_fmod
+#define TWO_ARGS
+#include "tgeneric.c"
+
+/* compute remainder as in definition:
+ r = x - n * y, where n = trunc(x/y).
+ warning: may change flags. */
+static int
+slow_fmod (mpfr_ptr r, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
+{
+ mpfr_t q;
+ int inexact;
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y)))
+ {
+ if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x)
+ || MPFR_IS_ZERO (y))
+ {
+ MPFR_SET_NAN (r);
+ MPFR_RET_NAN;
+ }
+ else /* either y is Inf and x is 0 or non-special,
+ or x is 0 and y is non-special,
+ in both cases the quotient is zero. */
+ return mpfr_set (r, x, rnd);
+ }
+ /* regular cases */
+ /* if 2^(ex-1) <= |x| < 2^ex, and 2^(ey-1) <= |y| < 2^ey,
+ then |x/y| < 2^(ex-ey+1) */
+ mpfr_init2 (q,
+ MAX (MPFR_PREC_MIN, mpfr_get_exp (x) - mpfr_get_exp (y) + 1));
+ mpfr_div (q, x, y, MPFR_RNDZ);
+ mpfr_trunc (q, q); /* may change inexact flag */
+ mpfr_prec_round (q, mpfr_get_prec (q) + mpfr_get_prec (y), MPFR_RNDZ);
+ inexact = mpfr_mul (q, q, y, MPFR_RNDZ); /* exact */
+ inexact = mpfr_sub (r, x, q, rnd);
+ mpfr_clear (q);
+ return inexact;
+}
+
+static void
+test_failed (mpfr_t erem, mpfr_t grem, int eret, int gret, mpfr_t x, mpfr_t y,
+ mpfr_rnd_t rnd)
+{
+ printf ("error: mpfr_fmod (r, x, y, rnd)\n x = ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD);
+ printf ("\n y = ");
+ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD);
+ printf ("\nrnd = %s", mpfr_print_rnd_mode (rnd));
+ if (eret != gret)
+ printf ("\nexpected %s return value, got %d",
+ (eret < 0 ? "negative" : eret > 0 ? "positive" : "zero"), gret);
+ printf ("\n expected r = ");
+ mpfr_out_str (stdout, 10, 0, erem, MPFR_RNDD);
+ printf ("\n got r = ");
+ mpfr_out_str (stdout, 10, 0, grem, MPFR_RNDD);
+ putchar ('\n');
+
+ exit (1);
+}
+
+static void
+check (mpfr_t r0, mpfr_t x, mpfr_t y, mpfr_rnd_t rnd)
+{
+ int inex0, inex1;
+ mpfr_t r1;
+ mpfr_init2 (r1, mpfr_get_prec (r0));
+
+ inex0 = mpfr_fmod (r0, x, y, rnd);
+ inex1 = slow_fmod (r1, x, y, rnd);
+ if (!mpfr_equal_p (r0, r1) || inex0 != inex1)
+ test_failed (r1, r0, inex1, inex0, x, y, rnd);
+ mpfr_clear (r1);
+}
+
+static void
+regular (void)
+{
+ mpfr_t x, y, r;
+ mpfr_inits (x, y, r, (mpfr_ptr) 0);
+
+ /* remainder = 0 */
+ mpfr_set_str (y, "FEDCBA987654321p-64", 16, MPFR_RNDN);
+ mpfr_pow_ui (x, y, 42, MPFR_RNDN);
+ check (r, x, y, MPFR_RNDN);
+
+ /* x < y */
+ mpfr_set_ui_2exp (x, 64723, -19, MPFR_RNDN);
+ mpfr_mul (x, x, y, MPFR_RNDN);
+ check (r, x, y, MPFR_RNDN);
+
+ /* sign(x) = sign (r) */
+ mpfr_set_ui (x, 123798, MPFR_RNDN);
+ mpfr_set_ui (y, 10, MPFR_RNDN);
+ check (r, x, y, MPFR_RNDN);
+
+ /* huge difference between precisions */
+ mpfr_set_prec (x, 314);
+ mpfr_set_prec (y, 8);
+ mpfr_set_prec (r, 123);
+ mpfr_const_pi (x, MPFR_RNDD); /* x = pi */
+ mpfr_set_ui_2exp (y, 1, 3, MPFR_RNDD); /* y = 1/8 */
+ check (r, x, y, MPFR_RNDD);
+
+ mpfr_clears (x, y, r, (mpfr_ptr) 0);
+}
+
+static void
+special (void)
+{
+ int inexact;
+ mpfr_t x, y, r, nan;
+ mpfr_inits (x, y, r, nan, (mpfr_ptr) 0);
+
+ mpfr_set_nan (nan);
+
+ /* fmod (NaN, NaN) is NaN */
+ mpfr_set_nan (x);
+ mpfr_set_nan (y);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (NaN, +0) is NaN */
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+1, 0) is NaN */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (0, 0) is NaN */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+inf, +0) is NaN */
+ mpfr_set_inf (x, +1);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, +0) is NaN */
+ mpfr_set_inf (x, -1);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, -0) is NaN */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, +1) is NaN */
+ mpfr_set_ui (y, +1, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+inf, +1) is NaN */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+inf, -inf) is NaN */
+ mpfr_set_inf (y, -1);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, -inf) is NaN */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, +inf) is NaN */
+ mpfr_neg (y, y, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+inf, +inf) is NaN */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (x, +inf) = x, if x is finite */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+0, +inf) = +0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-0, +inf) = -0 */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (x, -inf) = x, if x is finite */
+ mpfr_set_inf (y, -1);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+0, -inf) = +0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-0, -inf) = -0 */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+0, +0) is NaN */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+0, -0) is NaN */
+ mpfr_neg (y, y, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+ test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+0, +1) = +0 */
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+0, -1) = +0 */
+ mpfr_neg (y, y, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-0, -1) = -0 */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-0, +1) = -0 */
+ mpfr_neg (y, y, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+ mpfr_clears (x, y, r, nan, (mpfr_ptr) 0);
+ return;
+}
+
+/* bug reported by Eric Veach */
+static void
+bug20090519 (void)
+{
+ mpfr_t x, y, r;
+ int inexact;
+ mpfr_inits2 (100, x, y, r, (mpfr_ptr) 0);
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_prec (y, 3);
+ mpfr_set_prec (r, 3);
+ mpfr_set_si (x, 8, MPFR_RNDN);
+ mpfr_set_si (y, 7, MPFR_RNDN);
+ check (r, x, y, MPFR_RNDN);
+
+ mpfr_set_prec (x, 10);
+ mpfr_set_prec (y, 10);
+ mpfr_set_prec (r, 10);
+ mpfr_set_ui_2exp (x, 3, 26, MPFR_RNDN);
+ mpfr_set_si (y, (1 << 9) - 1, MPFR_RNDN);
+ check (r, x, y, MPFR_RNDN);
+
+ mpfr_set_prec (x, 100);
+ mpfr_set_prec (y, 100);
+ mpfr_set_prec (r, 100);
+ mpfr_set_str (x, "3.5", 10, MPFR_RNDN);
+ mpfr_set_str (y, "1.1", 10, MPFR_RNDN);
+ check (r, x, y, MPFR_RNDN);
+ /* double check, with a pre-computed value */
+ {
+ mpfr_t er;
+ mpfr_init2 (er, 100);
+ mpfr_set_str (er, "CCCCCCCCCCCCCCCCCCCCCCCC8p-102", 16, MPFR_RNDN);
+
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_equal_p (r, er) || inexact != 0)
+ test_failed (er, r, 0, inexact, x, y, MPFR_RNDN);
+
+ mpfr_clear (er);
+ }
+
+ mpfr_set_si (x, 20, MPFR_RNDN);
+ mpfr_set_ui_2exp (y, 1, 1, MPFR_RNDN); /* exact */
+ mpfr_sin (y, y, MPFR_RNDN);
+ check (r, x, y, MPFR_RNDN);
+
+ mpfr_clears(r, x, y, (mpfr_ptr) 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ bug20090519 ();
+
+ test_generic (2, 100, 100);
+
+ special ();
+ regular ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tfms.c b/mpfr/tests/tfms.c
new file mode 100644
index 0000000000..ee3f0921e8
--- /dev/null
+++ b/mpfr/tests/tfms.c
@@ -0,0 +1,644 @@
+/* Test file for mpfr_fms.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* When a * b is exact, the FMS is equivalent to the separate operations. */
+static void
+test_exact (void)
+{
+ const char *val[] =
+ { "@NaN@", "-@Inf@", "-2", "-1", "-0", "0", "1", "2", "@Inf@" };
+ int sv = sizeof (val) / sizeof (*val);
+ int i, j, k;
+ int rnd;
+ mpfr_t a, b, c, r1, r2;
+
+ mpfr_inits2 (8, a, b, c, r1, r2, (mpfr_ptr) 0);
+
+ for (i = 0; i < sv; i++)
+ for (j = 0; j < sv; j++)
+ for (k = 0; k < sv; k++)
+ RND_LOOP (rnd)
+ {
+ if (mpfr_set_str (a, val[i], 10, MPFR_RNDN) ||
+ mpfr_set_str (b, val[j], 10, MPFR_RNDN) ||
+ mpfr_set_str (c, val[k], 10, MPFR_RNDN) ||
+ mpfr_mul (r1, a, b, (mpfr_rnd_t) rnd) ||
+ mpfr_sub (r1, r1, c, (mpfr_rnd_t) rnd))
+ {
+ printf ("test_exact internal error for (%d,%d,%d,%d)\n",
+ i, j, k, rnd);
+ exit (1);
+ }
+ if (mpfr_fms (r2, a, b, c, (mpfr_rnd_t) rnd))
+ {
+ printf ("test_exact(%d,%d,%d,%d): mpfr_fms should be exact\n",
+ i, j, k, rnd);
+ exit (1);
+ }
+ if (MPFR_IS_NAN (r1))
+ {
+ if (MPFR_IS_NAN (r2))
+ continue;
+ printf ("test_exact(%d,%d,%d,%d): mpfr_fms should be NaN\n",
+ i, j, k, rnd);
+ exit (1);
+ }
+ if (mpfr_cmp (r1, r2) || MPFR_SIGN (r1) != MPFR_SIGN (r2))
+ {
+ printf ("test_exact(%d,%d,%d,%d):\nexpected ", i, j, k, rnd);
+ mpfr_out_str (stdout, 10, 0, r1, MPFR_RNDN);
+ printf ("\n got ");
+ mpfr_out_str (stdout, 10, 0, r2, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ }
+
+ mpfr_clears (a, b, c, r1, r2, (mpfr_ptr) 0);
+}
+
+static void
+test_overflow1 (void)
+{
+ mpfr_t x, y, z, r;
+ int inex;
+
+ mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);
+ MPFR_SET_POS (x);
+ mpfr_setmax (x, mpfr_get_emax ()); /* x = 2^emax - ulp */
+ mpfr_set_ui (y, 2, MPFR_RNDN); /* y = 2 */
+ mpfr_set (z, x, MPFR_RNDN); /* z = x = 2^emax - ulp */
+ mpfr_clear_flags ();
+ /* The intermediate multiplication x * y overflows, but x * y - z = x
+ is representable. */
+ inex = mpfr_fms (r, x, y, z, MPFR_RNDN);
+ if (inex || ! mpfr_equal_p (r, x))
+ {
+ printf ("Error in test_overflow1\nexpected ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf (" with inex = 0\n got ");
+ mpfr_out_str (stdout, 2, 0, r, MPFR_RNDN);
+ printf (" with inex = %d\n", inex);
+ exit (1);
+ }
+ if (mpfr_overflow_p ())
+ {
+ printf ("Error in test_overflow1: overflow flag set\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
+}
+
+static void
+test_overflow2 (void)
+{
+ mpfr_t x, y, z, r;
+ int i, inex, rnd, err = 0;
+
+ mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);
+
+ MPFR_SET_POS (x);
+ mpfr_setmin (x, mpfr_get_emax ()); /* x = 0.1@emax */
+ mpfr_set_si (y, -2, MPFR_RNDN); /* y = -2 */
+ /* The intermediate multiplication x * y will overflow. */
+
+ for (i = -9; i <= 9; i++)
+ RND_LOOP (rnd)
+ {
+ int inf, overflow;
+
+ inf = rnd == MPFR_RNDN || rnd == MPFR_RNDD || rnd == MPFR_RNDA;
+ overflow = inf || i <= 0;
+
+ inex = mpfr_set_si_2exp (z, -i, mpfr_get_emin (), MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+
+ mpfr_clear_flags ();
+ /* One has: x * y = -1@emax exactly (but not representable). */
+ inex = mpfr_fms (r, x, y, z, (mpfr_rnd_t) rnd);
+ if (overflow ^ (mpfr_overflow_p () != 0))
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): wrong overflow"
+ " flag (should be %d)\n", i,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), overflow);
+ err = 1;
+ }
+ if (mpfr_nanflag_p ())
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): NaN flag should"
+ " not be set\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (mpfr_nan_p (r))
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): got NaN\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ else if (MPFR_SIGN (r) >= 0)
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): wrong sign "
+ "(+ instead of -)\n", i,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ else if (inf && ! mpfr_inf_p (r))
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): expected -Inf,"
+ " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_dump (r);
+ err = 1;
+ }
+ else if (!inf && (mpfr_inf_p (r) ||
+ (mpfr_nextbelow (r), ! mpfr_inf_p (r))))
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): expected -MAX,"
+ " got\n", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_dump (r);
+ err = 1;
+ }
+ if (inf ? inex >= 0 : inex <= 0)
+ {
+ printf ("Error in test_overflow2 (i = %d, %s): wrong inexact"
+ " flag (got %d)\n", i,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex);
+ err = 1;
+ }
+
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
+}
+
+static void
+test_underflow1 (void)
+{
+ mpfr_t x, y, z, r;
+ int inex, signy, signz, rnd, err = 0;
+
+ mpfr_inits2 (8, x, y, z, r, (mpfr_ptr) 0);
+
+ MPFR_SET_POS (x);
+ mpfr_setmin (x, mpfr_get_emin ()); /* x = 0.1@emin */
+
+ for (signy = -1; signy <= 1; signy += 2)
+ {
+ mpfr_set_si_2exp (y, signy, -1, MPFR_RNDN); /* |y| = 1/2 */
+ for (signz = -3; signz <= 3; signz += 2)
+ {
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si (z, signz, MPFR_RNDN);
+ if (ABS (signz) != 1)
+ mpfr_setmax (z, mpfr_get_emax ());
+ /* |z| = 1 or 2^emax - ulp */
+ mpfr_clear_flags ();
+ inex = mpfr_fms (r, x, y, z, (mpfr_rnd_t) rnd);
+#define ERRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n "
+ if (mpfr_nanflag_p ())
+ {
+ printf (ERRTU1 "NaN flag is set\n", signy, signz,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ mpfr_neg (z, z, MPFR_RNDN);
+ if (signy < 0 && MPFR_IS_LIKE_RNDD(rnd, -signz))
+ mpfr_nextbelow (z);
+ if (signy > 0 && MPFR_IS_LIKE_RNDU(rnd, -signz))
+ mpfr_nextabove (z);
+ if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0))
+ {
+ printf (ERRTU1 "wrong overflow flag\n", signy, signz,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (mpfr_underflow_p ())
+ {
+ printf (ERRTU1 "underflow flag is set\n", signy, signz,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (r, z))
+ {
+ printf (ERRTU1 "got ", signy, signz,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (r);
+ printf (" instead of ");
+ mpfr_print_binary (z);
+ printf ("\n");
+ err = 1;
+ }
+ if (inex >= 0 && (rnd == MPFR_RNDD ||
+ (rnd == MPFR_RNDZ && signz < 0) ||
+ (rnd == MPFR_RNDN && signy > 0)))
+ {
+ printf (ERRTU1 "ternary value = %d instead of < 0\n",
+ signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
+ inex);
+ err = 1;
+ }
+ if (inex <= 0 && (rnd == MPFR_RNDU ||
+ (rnd == MPFR_RNDZ && signz > 0) ||
+ (rnd == MPFR_RNDN && signy < 0)))
+ {
+ printf (ERRTU1 "ternary value = %d instead of > 0\n",
+ signy, signz, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
+ inex);
+ err = 1;
+ }
+ }
+ }
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
+}
+
+static void
+test_underflow2 (void)
+{
+ mpfr_t x, y, z, r;
+ int b, i, inex, same, err = 0;
+
+ mpfr_inits2 (32, x, y, z, r, (mpfr_ptr) 0);
+
+ mpfr_set_si_2exp (z, -1, mpfr_get_emin (), MPFR_RNDN); /* z = -2^emin */
+ mpfr_set_si_2exp (x, 1, mpfr_get_emin (), MPFR_RNDN); /* x = 2^emin */
+
+ for (b = 0; b <= 1; b++)
+ {
+ for (i = 15; i <= 17; i++)
+ {
+ mpfr_set_si_2exp (y, i, -4 - MPFR_PREC (z), MPFR_RNDN);
+ /* z = -1.000...00b
+ * xy = 01111
+ * or 10000
+ * or 10001
+ */
+ mpfr_clear_flags ();
+ inex = mpfr_fms (r, x, y, z, MPFR_RNDN);
+#define ERRTU2 "Error in test_underflow2 (b = %d, i = %d)\n "
+ if (__gmpfr_flags != MPFR_FLAGS_INEXACT)
+ {
+ printf (ERRTU2 "flags = %u instead of %u\n", b, i,
+ __gmpfr_flags, (unsigned int) MPFR_FLAGS_INEXACT);
+ err = 1;
+ }
+ same = i == 15 || (i == 16 && b == 0);
+ if (same ? (inex >= 0) : (inex <= 0))
+ {
+ printf (ERRTU2 "incorrect ternary value (%d instead of %c 0)\n",
+ b, i, inex, same ? '<' : '>');
+ err = 1;
+ }
+ mpfr_neg (y, z, MPFR_RNDN);
+ if (!same)
+ mpfr_nextabove (y);
+ if (! mpfr_equal_p (r, y))
+ {
+ printf (ERRTU2 "expected ", b, i);
+ mpfr_dump (y);
+ printf (" got ");
+ mpfr_dump (r);
+ err = 1;
+ }
+ }
+ mpfr_nextbelow (z);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y, z, s;
+ MPFR_SAVE_EXPO_DECL (expo);
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (s);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ /* check special cases */
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 2);
+ mpfr_set_prec (z, 2);
+ mpfr_set_prec (s, 2);
+ mpfr_set_str (x, "-0.75", 10, MPFR_RNDN);
+ mpfr_set_str (y, "0.5", 10, MPFR_RNDN);
+ mpfr_set_str (z, "-0.375", 10, MPFR_RNDN);
+ mpfr_fms (s, x, y, z, MPFR_RNDU); /* result is 0 */
+ if (mpfr_cmp_ui(s, 0))
+ {
+ printf("Error: -0.75 * 0.5 - -0.375 should be equal to 0 for prec=2\n");
+ exit(1);
+ }
+
+ mpfr_set_prec (x, 27);
+ mpfr_set_prec (y, 27);
+ mpfr_set_prec (z, 27);
+ mpfr_set_prec (s, 27);
+ mpfr_set_str_binary (x, "1.11111111111111111111111111e-1");
+ mpfr_set (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (z, "1.00011110100011001011001001e-1");
+ if (mpfr_fms (s, x, y, z, MPFR_RNDN) >= 0)
+ {
+ printf ("Wrong inexact flag for x=y=1-2^(-27)\n");
+ exit (1);
+ }
+
+ mpfr_set_nan (x);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x=NAN does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_nan (y);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p(s))
+ {
+ printf ("evaluation of function in y=NAN does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_nan (z);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (x, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in z=NAN does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, 1);
+ mpfr_set_inf (z, -1);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("Error for (+inf) * (+inf) - (-inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_set_inf (y, -1);
+ mpfr_set_inf (z, -1);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("Error for (-inf) * (-inf) - (-inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, -1);
+ mpfr_set_inf (z, 1);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0)
+ {
+ printf ("Error for (+inf) * (-inf) - (+inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_set_inf (y, 1);
+ mpfr_set_inf (z, 1);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) > 0)
+ {
+ printf ("Error for (-inf) * (+inf) - (+inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x=INF y=0 does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (y, 1);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x=0 y=INF does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_urandomb (y, RANDS); /* always positive */
+ mpfr_set_inf (z, 1);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x=INF y>0 z=INF does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (y, 1);
+ mpfr_urandomb (x, RANDS);
+ mpfr_set_inf (z, 1);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_nan_p (s))
+ {
+ printf ("evaluation of function in x>0 y=INF z=INF does not return NAN");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("evaluation of function in x=INF does not return INF");
+ exit (1);
+ }
+
+ mpfr_set_inf (y, 1);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("evaluation of function in y=INF does not return INF");
+ exit (1);
+ }
+
+ mpfr_set_inf (z, -1);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (y, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ if (!mpfr_inf_p (s) || mpfr_sgn (s) < 0)
+ {
+ printf ("evaluation of function in z=-INF does not return INF");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ mpfr_neg (z, z, MPFR_RNDN);
+ if (mpfr_cmp (s, z))
+ {
+ printf ("evaluation of function in x=0 does not return -z\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (z, RANDS);
+ mpfr_fms (s, x, y, z, MPFR_RNDN);
+ mpfr_neg (z, z, MPFR_RNDN);
+ if (mpfr_cmp (s, z))
+ {
+ printf ("evaluation of function in y=0 does not return -z\n");
+ exit (1);
+ }
+
+ {
+ mpfr_prec_t prec;
+ mpfr_t t, slong;
+ mpfr_rnd_t rnd;
+ int inexact, compare;
+ unsigned int n;
+
+ mpfr_prec_t p0=2, p1=200;
+ unsigned int N=200;
+
+ mpfr_init (t);
+ mpfr_init (slong);
+
+ /* generic test */
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (y, prec);
+ mpfr_set_prec (z, prec);
+ mpfr_set_prec (s, prec);
+ mpfr_set_prec (t, prec);
+
+ for (n=0; n<N; n++)
+ {
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (z, RANDS);
+
+ if (randlimb () % 2)
+ mpfr_neg (x, x, MPFR_RNDN);
+ if (randlimb () % 2)
+ mpfr_neg (y, y, MPFR_RNDN);
+ if (randlimb () % 2)
+ mpfr_neg (z, z, MPFR_RNDN);
+
+ rnd = RND_RAND ();
+ mpfr_set_prec (slong, 2 * prec);
+ if (mpfr_mul (slong, x, y, rnd))
+ {
+ printf ("x*y should be exact\n");
+ exit (1);
+ }
+ compare = mpfr_sub (t, slong, z, rnd);
+ inexact = mpfr_fms (s, x, y, z, rnd);
+ if (mpfr_cmp (s, t))
+ {
+ printf ("results differ for x=");
+ mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
+ printf (" y=");
+ mpfr_out_str (stdout, 2, prec, y, MPFR_RNDN);
+ printf (" z=");
+ mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
+ printf (" prec=%u rnd_mode=%s\n", (unsigned int) prec,
+ mpfr_print_rnd_mode (rnd));
+ printf ("got ");
+ mpfr_out_str (stdout, 2, prec, s, MPFR_RNDN);
+ puts ("");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
+ puts ("");
+ printf ("approx ");
+ mpfr_print_binary (slong);
+ puts ("");
+ exit (1);
+ }
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact < 0) && (compare >= 0)) ||
+ ((inexact > 0) && (compare <= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n",
+ mpfr_print_rnd_mode (rnd), compare, inexact);
+ printf (" x="); mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf (" y="); mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf (" z="); mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf (" s="); mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ }
+ }
+ mpfr_clear (t);
+ mpfr_clear (slong);
+
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (s);
+
+ test_exact ();
+
+ MPFR_SAVE_EXPO_MARK (expo);
+ test_overflow1 ();
+ test_overflow2 ();
+ test_underflow1 ();
+ test_underflow2 ();
+ MPFR_SAVE_EXPO_FREE (expo);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tfprintf.c b/mpfr/tests/tfprintf.c
new file mode 100644
index 0000000000..33e25f0f67
--- /dev/null
+++ b/mpfr/tests/tfprintf.c
@@ -0,0 +1,445 @@
+/* tfprintf.c -- test file for mpfr_fprintf and mpfr_vfprintf
+
+Copyright 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_STDARG
+#include <stdarg.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+#include <stddef.h>
+
+#include "mpfr-intmax.h"
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+#define QUOTE(X) NAME(X)
+#define NAME(X) #X
+
+#define check_length(num_test, var, value, var_spec) \
+ if ((var) != (value)) \
+ { \
+ printf ("Error in test #%d: mpfr_vfprintf printed %"QUOTE(var_spec) \
+ " characters instead of %d\n", (num_test), (var), (value)); \
+ exit (1); \
+ }
+
+#define check_length_with_cmp(num_test, var, value, cmp, var_spec) \
+ if (cmp != 0) \
+ { \
+ mpfr_printf ("Error in test #%d, mpfr_vfprintf printed %" \
+ QUOTE(var_spec)" characters instead of %d\n", \
+ (num_test), (var), (value)); \
+ exit (1); \
+ }
+
+/* limit for random precision in random() */
+const int prec_max_printf = 5000;
+
+static void
+check (FILE *fout, const char *fmt, mpfr_t x)
+{
+ if (mpfr_fprintf (fout, fmt, x) == -1)
+ {
+ mpfr_printf ("Error in mpfr_fprintf(fout, \"%s\", %Re)\n",
+ fmt, x);
+ exit (1);
+ }
+ fputc ('\n', fout);
+}
+
+static void
+check_vfprintf (FILE *fout, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ if (mpfr_vfprintf (fout, fmt, ap) == -1)
+ {
+ mpfr_printf ("Error in mpfr_vfprintf(fout, \"%s\", ...)\n", fmt);
+
+ va_end (ap);
+ exit (1);
+ }
+
+ va_end (ap);
+ fputc ('\n', fout);
+}
+
+static void
+check_special (FILE *fout)
+{
+ mpfr_t x;
+
+ mpfr_init (x);
+
+ mpfr_set_inf (x, 1);
+ check (fout, "%Ra", x);
+ check (fout, "%Rb", x);
+ check (fout, "%Re", x);
+ check (fout, "%Rf", x);
+ check (fout, "%Rg", x);
+ check_vfprintf (fout, "%Ra", x);
+ check_vfprintf (fout, "%Rb", x);
+ check_vfprintf (fout, "%Re", x);
+ check_vfprintf (fout, "%Rf", x);
+ check_vfprintf (fout, "%Rg", x);
+
+ mpfr_set_inf (x, -1);
+ check (fout, "%Ra", x);
+ check (fout, "%Rb", x);
+ check (fout, "%Re", x);
+ check (fout, "%Rf", x);
+ check (fout, "%Rg", x);
+ check_vfprintf (fout, "%Ra", x);
+ check_vfprintf (fout, "%Rb", x);
+ check_vfprintf (fout, "%Re", x);
+ check_vfprintf (fout, "%Rf", x);
+ check_vfprintf (fout, "%Rg", x);
+
+ mpfr_set_nan (x);
+ check (fout, "%Ra", x);
+ check (fout, "%Rb", x);
+ check (fout, "%Re", x);
+ check (fout, "%Rf", x);
+ check (fout, "%Rg", x);
+ check_vfprintf (fout, "%Ra", x);
+ check_vfprintf (fout, "%Rb", x);
+ check_vfprintf (fout, "%Re", x);
+ check_vfprintf (fout, "%Rf", x);
+ check_vfprintf (fout, "%Rg", x);
+
+ mpfr_clear (x);
+}
+
+static void
+check_mixed (FILE *fout)
+{
+ int ch = 'a';
+#ifndef NPRINTF_HH
+ signed char sch = -1;
+ unsigned char uch = 1;
+#endif
+ short sh = -1;
+ unsigned short ush = 1;
+ int i = -1;
+ int j = 1;
+ unsigned int ui = 1;
+ long lo = -1;
+ unsigned long ulo = 1;
+ float f = -1.25;
+ double d = -1.25;
+#if !defined(NPRINTF_T) || !defined(NPRINTF_L)
+ long double ld = -1.25;
+#endif
+
+#ifndef NPRINTF_T
+ ptrdiff_t p = 1, saved_p;
+#endif
+ size_t sz = 1;
+
+ mpz_t mpz;
+ mpq_t mpq;
+ mpf_t mpf;
+ mpfr_rnd_t rnd = MPFR_RNDN;
+
+ mp_size_t limb_size = 3;
+ mp_limb_t limb[3];
+
+ mpfr_t mpfr;
+ mpfr_prec_t prec = 53;
+
+ mpz_init (mpz);
+ mpz_set_ui (mpz, ulo);
+ mpq_init (mpq);
+ mpq_set_si (mpq, lo, ulo);
+ mpf_init (mpf);
+ mpf_set_q (mpf, mpq);
+
+ mpfr_init2 (mpfr, prec);
+ mpfr_set_f (mpfr, mpf, MPFR_RNDN);
+
+ limb[0] = limb[1] = limb[2] = ~ (mp_limb_t) 0;
+
+ check_vfprintf (fout, "a. %Ra, b. %u, c. %lx%n", mpfr, ui, ulo, &j);
+ check_length (1, j, 22, d);
+ check_vfprintf (fout, "a. %c, b. %Rb, c. %u, d. %li%ln", i, mpfr, i,
+ lo, &ulo);
+ check_length (2, ulo, 36, lu);
+ check_vfprintf (fout, "a. %hi, b. %*f, c. %Re%hn", ush, 3, f, mpfr, &ush);
+ check_length (3, ush, 29, hu);
+ check_vfprintf (fout, "a. %hi, b. %f, c. %#.2Rf%n", sh, d, mpfr, &i);
+ check_length (4, i, 29, d);
+ check_vfprintf (fout, "a. %R*A, b. %Fe, c. %i%zn", rnd, mpfr, mpf, sz,
+ &sz);
+ check_length (5, (unsigned long) sz, 34, lu); /* no format specifier "%zu" in C89 */
+ check_vfprintf (fout, "a. %Pu, b. %c, c. %Zi%Zn", prec, ch, mpz, &mpz);
+ check_length_with_cmp (6, mpz, 17, mpz_cmp_ui (mpz, 17), Zi);
+ check_vfprintf (fout, "%% a. %#.0RNg, b. %Qx%Rn, c. %p", mpfr, mpq, &mpfr,
+ (void *) &i);
+ check_length_with_cmp (7, mpfr, 15, mpfr_cmp_ui (mpfr, 15), Rg);
+
+#ifndef NPRINTF_T
+ saved_p = p;
+ check_vfprintf (fout, "%% a. %RNg, b. %Qx, c. %td%tn", mpfr, mpq, p, &p);
+ if (p != 20)
+ mpfr_fprintf (stderr, "Error in test 8, got '%% a. %RNg, b. %Qx, c. %td'\n", mpfr, mpq, saved_p);
+ check_length (8, (long) p, 20, ld); /* no format specifier "%td" in C89 */
+#endif
+
+#ifndef NPRINTF_L
+ check_vfprintf (fout, "a. %RA, b. %Lf, c. %QX%zn", mpfr, ld, mpq, &sz);
+ check_length (9, (unsigned long) sz, 30, lu); /* no format specifier "%zu" in C89 */
+#endif
+
+#ifndef NPRINTF_HH
+ check_vfprintf (fout, "a. %hhi, b. %RA, c. %hhu%hhn", sch, mpfr, uch, &uch);
+ check_length (10, (unsigned int) uch, 22, u); /* no format specifier "%hhu" in C89 */
+#endif
+
+#if (__GNU_MP_VERSION * 10 + __GNU_MP_VERSION_MINOR) >= 42
+ /* The 'M' specifier was added in gmp 4.2.0 */
+ check_vfprintf (fout, "a. %Mx b. %Re%Mn", limb[0], mpfr, &limb[0]);
+ if (limb[0] != 14 + GMP_NUMB_BITS / 4 || limb[1] != ~ (mp_limb_t) 0
+ || limb[2] != ~ (mp_limb_t) 0)
+ {
+ printf ("Error in test #11: mpfr_vfprintf did not print %d characters"
+ " as expected\n", 14 + (int) GMP_NUMB_BITS / 4);
+ exit (1);
+ }
+
+ limb[0] = ~ (mp_limb_t) 0;
+ /* we tell vfprintf that limb array is 2 cells wide
+ and check it doesn't go through */
+ check_vfprintf (fout, "a. %Re .b %Nx%Nn", mpfr, limb, limb_size, limb,
+ limb_size - 1);
+ if (limb[0] != 14 + 3 * GMP_NUMB_BITS / 4 || limb[1] != (mp_limb_t) 0
+ || limb[2] != ~ (mp_limb_t) 0)
+ {
+ printf ("Error in test #12: mpfr_vfprintf did not print %d characters"
+ " as expected\n", 14 + (int) GMP_NUMB_BITS / 4);
+ exit (1);
+ }
+#endif
+
+#if defined(HAVE_LONG_LONG) && !defined(NPRINTF_LL)
+ {
+ long long llo = -1;
+ unsigned long long ullo = 1;
+
+ check_vfprintf (fout, "a. %Re, b. %llx%Qn", mpfr, ullo, &mpq);
+ check_length_with_cmp (21, mpq, 16, mpq_cmp_ui (mpq, 16, 1), Qu);
+ check_vfprintf (fout, "a. %lli, b. %Rf%Fn", llo, mpfr, &mpf);
+ check_length_with_cmp (22, mpf, 19, mpf_cmp_ui (mpf, 19), Fg);
+ }
+#endif
+
+#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J)
+ {
+ intmax_t im = -1;
+ uintmax_t uim = 1;
+
+ check_vfprintf (fout, "a. %*RA, b. %ji%Qn", 10, mpfr, im, &mpq);
+ check_length_with_cmp (31, mpq, 20, mpq_cmp_ui (mpq, 20, 1), Qu);
+ check_vfprintf (fout, "a. %.*Re, b. %jx%Fn", 10, mpfr, uim, &mpf);
+ check_length_with_cmp (32, mpf, 25, mpf_cmp_ui (mpf, 25), Fg);
+ }
+#endif
+
+ mpfr_clear (mpfr);
+ mpf_clear (mpf);
+ mpq_clear (mpq);
+ mpz_clear (mpz);
+}
+
+static void
+check_random (FILE *fout, int nb_tests)
+{
+ int i;
+ mpfr_t x;
+ mpfr_rnd_t rnd;
+ char flag[] =
+ {
+ '-',
+ '+',
+ ' ',
+ '#',
+ '0', /* no ambiguity: first zeros are flag zero*/
+ '\''
+ };
+ char specifier[] =
+ {
+ 'a',
+ 'b',
+ 'e',
+ 'f',
+ 'g'
+ };
+ mpfr_exp_t old_emin, old_emax;
+
+ old_emin = mpfr_get_emin ();
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init (x);
+
+ for (i = 0; i < nb_tests; ++i)
+ {
+ int ret;
+ int j, jmax;
+ int spec, prec;
+#define FMT_SIZE 13
+ char fmt[FMT_SIZE]; /* at most something like "%-+ #0'.*R*f" */
+ char *ptr = fmt;
+
+ tests_default_random (x, 256, MPFR_EMIN_MIN, MPFR_EMAX_MAX);
+ rnd = RND_RAND ();
+
+ spec = (int) (randlimb () % 5);
+ jmax = (spec == 3 || spec == 4) ? 6 : 5; /* ' flag only with %f or %g */
+ /* advantage small precision */
+ prec = (int) (randlimb () % ((randlimb () % 2) ? 10 : prec_max_printf));
+ if (spec == 3
+ && (mpfr_get_exp (x) > prec_max_printf
+ || mpfr_get_exp (x) < -prec_max_printf))
+ /* change style 'f' to style 'e' when number x is large */
+ --spec;
+
+ *ptr++ = '%';
+ for (j = 0; j < jmax; j++)
+ {
+ if (randlimb () % 3 == 0)
+ *ptr++ = flag[j];
+ }
+ *ptr++ = '.';
+ *ptr++ = '*';
+ *ptr++ = 'R';
+ *ptr++ = '*';
+ *ptr++ = specifier[spec];
+ *ptr = '\0';
+ MPFR_ASSERTD (ptr - fmt < FMT_SIZE);
+
+ mpfr_fprintf (fout, "mpfr_fprintf(fout, \"%s\", %d, %s, %Re)\n",
+ fmt, prec, mpfr_print_rnd_mode (rnd), x);
+ ret = mpfr_fprintf (fout, fmt, prec, rnd, x);
+ if (ret == -1)
+ {
+ if (spec == 3
+ && (MPFR_GET_EXP (x) > INT_MAX || MPFR_GET_EXP (x) < -INT_MAX))
+ /* normal failure: x is too large to be output with full precision */
+ {
+ mpfr_fprintf (fout, "too large !");
+ }
+ else
+ {
+ mpfr_printf ("Error in mpfr_fprintf(fout, \"%s\", %d, %s, %Re)\n",
+ fmt, prec, mpfr_print_rnd_mode (rnd), x);
+ exit (1);
+ }
+ }
+ mpfr_fprintf (fout, "\n");
+ }
+
+ mpfr_set_emin (old_emin);
+ mpfr_set_emax (old_emax);
+
+ mpfr_clear (x);
+}
+
+static void
+bug_20090316 (FILE *fout)
+{
+ mpfr_t x;
+
+ mpfr_init2 (x, 53);
+
+ /* bug 20090316: fixed in r6112 */
+ mpfr_set_ui_2exp (x, 0x60fa2916, -30, MPFR_RNDN);
+ check (fout, "%-#.4095RDg\n", x);
+
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ FILE *fout;
+ int N;
+
+ tests_start_mpfr ();
+
+ /* with no argument: prints to /dev/null,
+ tfprintf N: prints N tests to stdout */
+ if (argc == 1)
+ {
+ N = 1000;
+ fout = fopen ("/dev/null", "w");
+ /* If we failed to open this device, try with a dummy file */
+ if (fout == NULL)
+ {
+ fout = fopen ("mpfrtest.txt", "w");
+
+ if (fout == NULL)
+ {
+ printf ("Can't open /dev/null or a temporary file\n");
+ exit (1);
+ }
+ }
+ }
+ else
+ {
+ fout = stdout;
+ N = atoi (argv[1]);
+ }
+
+ check_special (fout);
+ check_mixed (fout);
+ check_random (fout, N);
+
+ bug_20090316 (fout);
+
+ fclose (fout);
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else /* MPFR_VERSION */
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif /* MPFR_VERSION */
+
+#else /* HAVE_STDARG */
+
+int
+main (void)
+{
+ /* We have nothing to test. */
+ return 77;
+}
+
+#endif /* HAVE_STDARG */
diff --git a/mpfr/tests/tfrac.c b/mpfr/tests/tfrac.c
new file mode 100644
index 0000000000..3d1724adb8
--- /dev/null
+++ b/mpfr/tests/tfrac.c
@@ -0,0 +1,301 @@
+/* Test file for mpfr_frac.
+
+Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define PIP 70
+#define PFP 70
+#define PMAX (PIP+2*PFP)
+
+static void
+check0 (mpfr_ptr ip, mpfr_ptr fp, mpfr_prec_t prec, mpfr_rnd_t rnd)
+{
+ mpfr_t sum, tmp, dst, fp2;
+ int inex1, inex2;
+
+ mpfr_init2 (sum, PMAX);
+ mpfr_init2 (tmp, PMAX);
+ mpfr_init2 (dst, prec);
+ mpfr_init2 (fp2, prec);
+
+ if (MPFR_SIGN (ip) != MPFR_SIGN (fp))
+ {
+ printf ("Internal error (1)\n");
+ exit (1);
+ }
+ if (mpfr_add (sum, ip, fp, MPFR_RNDZ))
+ {
+ printf ("Wrong inexact flag in mpfr_add\n");
+ exit (1);
+ }
+ if (MPFR_SIGN (sum) != MPFR_SIGN (fp))
+ {
+ printf ("Internal error (2)\n");
+ exit (1);
+ }
+
+ inex1 = mpfr_frac (dst, sum, rnd);
+ inex2 = mpfr_set (fp2, fp, rnd);
+ if (inex1 != inex2)
+ {
+ printf ("Wrong inexact flag in mpfr_frac for\n");
+ mpfr_out_str (stdout, 2, 0, sum, MPFR_RNDN);
+ printf ("\nGot %d instead of %d\n", inex1, inex2);
+ exit (1);
+ }
+ if (!mpfr_number_p (dst) ||
+ MPFR_SIGN (dst) != MPFR_SIGN (fp2) ||
+ mpfr_cmp (dst, fp2))
+ {
+ printf ("Error in mpfr_frac (y, x, %s) with\nx = ",
+ mpfr_print_rnd_mode (rnd));
+ mpfr_out_str (stdout, 2, 0, sum, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 2, 0, dst, MPFR_RNDN);
+ printf ("\ninstead of ");
+ mpfr_out_str (stdout, 2, 0, fp2, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ if (prec == PMAX)
+ {
+ inex1 = mpfr_frac (sum, sum, rnd);
+ if (inex1)
+ {
+ printf ("Wrong inexact flag in mpfr_frac\n");
+ exit (1);
+ }
+ if (!mpfr_number_p (sum) ||
+ MPFR_SIGN (sum) != MPFR_SIGN (fp) ||
+ mpfr_cmp (sum, fp))
+ {
+ printf ("Error in mpfr_frac (x, x, %s) with\nx = ",
+ mpfr_print_rnd_mode (rnd));
+ mpfr_add (tmp, ip, fp, MPFR_RNDZ);
+ mpfr_out_str (stdout, 2, 0, tmp, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 2, 0, sum, MPFR_RNDN);
+ printf ("\ninstead of ");
+ mpfr_out_str (stdout, 2, 0, fp, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (fp2);
+ mpfr_clear (dst);
+ mpfr_clear (tmp);
+ mpfr_clear (sum);
+}
+
+static void
+check1 (mpfr_ptr ip, mpfr_ptr fp)
+{
+ int rnd;
+
+ for (rnd = 0; rnd < MPFR_RND_MAX ; rnd++)
+ {
+ check0 (ip, fp, PMAX, (mpfr_rnd_t) rnd);
+ check0 (ip, fp, 70, (mpfr_rnd_t) rnd);
+ mpfr_neg (fp, fp, MPFR_RNDN);
+ mpfr_neg (ip, ip, MPFR_RNDN);
+ check0 (ip, fp, PMAX, (mpfr_rnd_t) rnd);
+ check0 (ip, fp, 70, (mpfr_rnd_t) rnd);
+ mpfr_neg (fp, fp, MPFR_RNDN);
+ mpfr_neg (ip, ip, MPFR_RNDN);
+ }
+}
+
+static void
+special (void)
+{
+ mpfr_t z, t;
+
+ mpfr_init (z);
+ mpfr_init (t);
+
+ mpfr_set_nan (z);
+ mpfr_frac (t, z, MPFR_RNDN);
+ if (!mpfr_nan_p (t))
+ {
+ printf ("Error for frac(NaN)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (z, 6);
+ mpfr_set_prec (t, 3);
+
+ mpfr_set_str_binary (z, "0.101101E3");
+ mpfr_frac (t, z, MPFR_RNDN);
+ mpfr_set_str_binary (z, "0.101");
+ if (mpfr_cmp (t, z))
+ {
+ printf ("Error in frac(0.101101E3)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (z, 34);
+ mpfr_set_prec (t, 26);
+ mpfr_set_str_binary (z, "0.101101010000010011110011001101E9");
+ mpfr_frac (t, z, MPFR_RNDN);
+ mpfr_set_str_binary (z, "0.000010011110011001101");
+ if (mpfr_cmp (t, z))
+ {
+ printf ("Error in frac(0.101101010000010011110011001101E9)\n");
+ exit (1);
+ }
+
+ mpfr_clear (z);
+ mpfr_clear (t);
+}
+
+static void
+bug20090918 (void)
+{
+ mpfr_t x, y, z;
+ mp_limb_t y0;
+ int inexy, inexz;
+ int r, i;
+ const char *s[] = { "61680.352935791015625", "61680.999999" };
+ mpfr_exp_t emin;
+
+ emin = mpfr_get_emin ();
+ mpfr_init2 (x, 32);
+ mpfr_init2 (y, 13);
+
+ for (i = 0; i <= 9; i++)
+ {
+ mpfr_set_str (x, s[i & 1], 10, MPFR_RNDZ);
+
+ RND_LOOP(r)
+ {
+ set_emin ((i >> 1) - 3);
+ inexy = mpfr_frac (y, x, (mpfr_rnd_t) r);
+ set_emin (emin);
+ y0 = MPFR_MANT(y)[0];
+ while (y0 != 0 && (y0 >> 1) << 1 == y0)
+ y0 >>= 1;
+ if (y0 > 0x2000)
+ {
+ printf ("Error in bug20090918 (significand has more than"
+ " 13 bits), i = %d, %s.\n", i,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ mpfr_init2 (z, 32);
+ inexz = mpfr_frac (z, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexz == 0); /* exact */
+ inexz = mpfr_prec_round (z, 13, (mpfr_rnd_t) r);
+ set_emin ((i >> 1) - 3);
+ inexz = mpfr_check_range (z, inexz, (mpfr_rnd_t) r);
+ set_emin (emin);
+ if (mpfr_cmp0 (y, z) != 0)
+ {
+ printf ("Error in bug20090918, i = %d, %s.\n", i,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ printf ("Expected ");
+ mpfr_dump (z);
+ printf ("Got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ if (! SAME_SIGN (inexy, inexz))
+ {
+ printf ("Incorrect ternary value in bug20090918, i = %d, %s.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ printf ("Expected %d, got %d.\n", inexz, inexy);
+ exit (1);
+ }
+ mpfr_clear (z);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_frac
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_t ip, fp;
+ int ni, nf1, nf2;
+
+ tests_start_mpfr ();
+
+ special ();
+
+ mpfr_init2 (ip, PIP);
+ mpfr_init2 (fp, PFP);
+
+ for (ni = -1; ni < PIP; ni++)
+ {
+ if (ni <= 0)
+ { /* ni + 1 */
+ mpfr_set_si (ip, ni, MPFR_RNDN);
+ mpfr_add_ui (ip, ip, 1, MPFR_RNDN);
+ }
+ else
+ { /* 2^ni + 1 */
+ mpfr_set_ui (ip, 1, MPFR_RNDN);
+ mpfr_mul_2ui (ip, ip, ni, MPFR_RNDN);
+ mpfr_add_ui (ip, ip, 1, MPFR_RNDN);
+ }
+
+ mpfr_set_ui (fp, 0, MPFR_RNDN);
+ check1 (ip, fp);
+
+ for (nf1 = 1; nf1 < PFP; nf1++)
+ {
+ mpfr_set_ui (fp, 1, MPFR_RNDN);
+ mpfr_div_2ui (fp, fp, nf1, MPFR_RNDN);
+ check1 (ip, fp);
+ nf2 = 1 + (randlimb () % (PFP - 1));
+ mpfr_set_ui (fp, 1, MPFR_RNDN);
+ mpfr_div_2ui (fp, fp, nf2, MPFR_RNDN);
+ mpfr_add_ui (fp, fp, 1, MPFR_RNDN);
+ mpfr_div_2ui (fp, fp, nf1, MPFR_RNDN);
+ check1 (ip, fp);
+ }
+ }
+
+ mpfr_set_ui (ip, 1, MPFR_RNDN);
+ mpfr_div_ui (ip, ip, 0, MPFR_RNDN);
+ mpfr_set_ui (fp, 0, MPFR_RNDN);
+ check1 (ip, fp); /* test infinities */
+
+ mpfr_clear (ip);
+ mpfr_clear (fp);
+
+ bug20090918 ();
+
+ test_generic (2, 1000, 10);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tfrexp.c b/mpfr/tests/tfrexp.c
new file mode 100644
index 0000000000..9e69cab3bf
--- /dev/null
+++ b/mpfr/tests/tfrexp.c
@@ -0,0 +1,141 @@
+/* Test file for mpfr_frexp.
+
+Copyright 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h> /* for exit */
+#include "mpfr-test.h"
+
+static void
+check_special (void)
+{
+ mpfr_t x, y;
+ int inex;
+ mpfr_exp_t exp;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+
+ mpfr_set_nan (x);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDN);
+ if (mpfr_nan_p (y) == 0 || inex != 0)
+ {
+ printf ("Error for mpfr_frexp(NaN)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDN);
+ if (mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0 || inex != 0)
+ {
+ printf ("Error for mpfr_frexp(+Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDN);
+ if (mpfr_inf_p (y) == 0 || mpfr_sgn (y) >= 0 || inex != 0)
+ {
+ printf ("Error for mpfr_frexp(-Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_zero (x, 1);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDN);
+ if (mpfr_zero_p (y) == 0 || mpfr_signbit (y) != 0 || inex != 0 || exp != 0)
+ {
+ printf ("Error for mpfr_frexp(+0)\n");
+ exit (1);
+ }
+
+ mpfr_set_zero (x, -1);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDN);
+ if (mpfr_zero_p (y) == 0 || mpfr_signbit (y) == 0 || inex != 0 || exp != 0)
+ {
+ printf ("Error for mpfr_frexp(-0)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDN);
+ /* 17 = 17/32*2^5 */
+ if (mpfr_cmp_ui_2exp (y, 17, -5) != 0 || inex != 0 || exp != 5)
+ {
+ printf ("Error for mpfr_frexp(17)\n");
+ exit (1);
+ }
+
+ mpfr_set_si (x, -17, MPFR_RNDN);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDN);
+ if (mpfr_cmp_si_2exp (y, -17, -5) != 0 || inex != 0 || exp != 5)
+ {
+ printf ("Error for mpfr_frexp(-17)\n");
+ exit (1);
+ }
+
+ /* now reduce the precision of y */
+ mpfr_set_prec (y, 4);
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDN);
+ /* 17 -> 16/32*2^5 */
+ if (mpfr_cmp_ui_2exp (y, 16, -5) != 0 || inex >= 0 || exp != 5)
+ {
+ printf ("Error for mpfr_frexp(17) with prec=4, RNDN\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDZ);
+ if (mpfr_cmp_ui_2exp (y, 16, -5) != 0 || inex >= 0 || exp != 5)
+ {
+ printf ("Error for mpfr_frexp(17) with prec=4, RNDZ\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDD);
+ if (mpfr_cmp_ui_2exp (y, 16, -5) != 0 || inex >= 0 || exp != 5)
+ {
+ printf ("Error for mpfr_frexp(17) with prec=4, RNDD\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ inex = mpfr_frexp (&exp, y, x, MPFR_RNDU);
+ if (mpfr_cmp_ui_2exp (y, 18, -5) != 0 || inex <= 0 || exp != 5)
+ {
+ printf ("Error for mpfr_frexp(17) with prec=4, RNDU\n");
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_special ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tgamma.c b/mpfr/tests/tgamma.c
new file mode 100644
index 0000000000..fd92c33708
--- /dev/null
+++ b/mpfr/tests/tgamma.c
@@ -0,0 +1,1069 @@
+/* mpfr_tgamma -- test file for gamma function
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* Note: there could be an incorrect test about suspicious overflow
+ (MPFR_SUSPICIOUS_OVERFLOW) for x = 2^(-emax) = 0.5 * 2^(emin+1) in
+ RNDZ or RNDD, but this case is never tested in the generic tests. */
+#define TEST_FUNCTION mpfr_gamma
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int inex;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_nan (x);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for gamma(NaN)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for gamma(-Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for gamma(+Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for gamma(+0)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error for gamma(-0)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error for gamma(1)\n");
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for gamma(-1)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+#define CHECK_X1 "1.0762904832837976166"
+#define CHECK_Y1 "0.96134843256452096050"
+
+ mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN);
+ if (mpfr_cmp (y, x))
+ {
+ printf ("mpfr_lngamma("CHECK_X1") is wrong:\n"
+ "expected ");
+ mpfr_print_binary (x); putchar ('\n');
+ printf ("got ");
+ mpfr_print_binary (y); putchar ('\n');
+ exit (1);
+ }
+
+#define CHECK_X2 "9.23709516716202383435e-01"
+#define CHECK_Y2 "1.0502315560291053398"
+ mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN);
+ if (mpfr_cmp (y, x))
+ {
+ printf ("mpfr_lngamma("CHECK_X2") is wrong:\n"
+ "expected ");
+ mpfr_print_binary (x); putchar ('\n');
+ printf ("got ");
+ mpfr_print_binary (y); putchar ('\n');
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 8);
+ mpfr_set_prec (y, 175);
+ mpfr_set_ui (x, 33, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDU);
+ mpfr_set_prec (x, 175);
+ mpfr_set_str_binary (x, "0.110010101011010101101000010101010111000110011101001000101011000001100010111001101001011E118");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_gamma (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 21);
+ mpfr_set_prec (y, 8);
+ mpfr_set_ui (y, 120, MPFR_RNDN);
+ mpfr_gamma (x, y, MPFR_RNDZ);
+ mpfr_set_prec (y, 21);
+ mpfr_set_str_binary (y, "0.101111101110100110110E654");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_gamma (120)\n");
+ printf ("Expected "); mpfr_print_binary (y); puts ("");
+ printf ("Got "); mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_prec (y, 206);
+ mpfr_set_str_binary (x, "0.110e10");
+ inex = mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 206);
+ mpfr_set_str_binary (x, "0.110111100001000001101010010001000111000100000100111000010011100011011111001100011110101000111101101100110001001100110100001001111110000101010000100100011100010011101110000001000010001100010000101001111E6250");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_gamma (768)\n");
+ exit (1);
+ }
+ if (inex <= 0)
+ {
+ printf ("Wrong flag for mpfr_gamma (768)\n");
+ exit (1);
+ }
+
+ /* worst case to exercise retry */
+ mpfr_set_prec (x, 1000);
+ mpfr_set_prec (y, 869);
+ mpfr_const_pi (x, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+
+ mpfr_set_prec (x, 4);
+ mpfr_set_prec (y, 4);
+ mpfr_set_str_binary (x, "-0.1100E-66");
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-0.1011E67");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for gamma(-0.1100E-66)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+special_overflow (void)
+{
+ mpfr_t x, y;
+ mpfr_exp_t emin, emax;
+ int inex;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ set_emin (-125);
+ set_emax (128);
+
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 24);
+ mpfr_set_str_binary (x, "0.101100100000000000110100E7");
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y))
+ {
+ printf ("Overflow error.\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ /* problem mentioned by Kenneth Wilder, 18 Aug 2005 */
+ mpfr_set_prec (x, 29);
+ mpfr_set_prec (y, 29);
+ mpfr_set_str (x, "-200000000.5", 10, MPFR_RNDN); /* exact */
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0))
+ {
+ printf ("Error for gamma(-200000000.5)\n");
+ printf ("expected -0");
+ printf ("got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str (x, "-200000000.1", 10, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0))
+ {
+ printf ("Error for gamma(-200000000.1), prec=53\n");
+ printf ("expected -0");
+ printf ("got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ /* another problem mentioned by Kenneth Wilder, 29 Aug 2005 */
+ mpfr_set_prec (x, 333);
+ mpfr_set_prec (y, 14);
+ mpfr_set_str (x, "-2.0000000000000000000000005", 10, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 14);
+ mpfr_set_str_binary (x, "-11010011110001E66");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for gamma(-2.0000000000000000000000005)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ /* another tests from Kenneth Wilder, 31 Aug 2005 */
+ set_emax (200);
+ set_emin (-200);
+ mpfr_set_prec (x, 38);
+ mpfr_set_prec (y, 54);
+ mpfr_set_str_binary (x, "0.11101111011100111101001001010110101001E-166");
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 54);
+ mpfr_set_str_binary (x, "0.100010001101100001110110001010111111010000100101011E167");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for gamma (test 1)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ set_emax (1000);
+ set_emin (-2000);
+ mpfr_set_prec (x, 38);
+ mpfr_set_prec (y, 71);
+ mpfr_set_str_binary (x, "10101011011100001111111000010111110010E-1034");
+ /* 184083777010*2^(-1034) */
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 71);
+ mpfr_set_str_binary (x, "10111111001000011110010001000000000000110011110000000011101011111111100E926");
+ /* 1762885132679550982140*2^926 */
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for gamma (test 2)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 38);
+ mpfr_set_prec (y, 88);
+ mpfr_set_str_binary (x, "10111100111001010000100001100100100101E-104");
+ /* 202824096037*2^(-104) */
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 88);
+ mpfr_set_str_binary (x, "1010110101111000111010111100010110101010100110111000001011000111000011101100001101110010E-21");
+ /* 209715199999500283894743922*2^(-21) */
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for gamma (test 3)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 171);
+ mpfr_set_prec (y, 38);
+ mpfr_set_str (x, "-2993155353253689176481146537402947624254601559176535", 10,
+ MPFR_RNDN);
+ mpfr_div_2exp (x, x, 170, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 38);
+ mpfr_set_str (x, "201948391737", 10, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, 92, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for gamma (test 5)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ set_emin (-500000);
+ mpfr_set_prec (x, 337);
+ mpfr_set_prec (y, 38);
+ mpfr_set_str (x, "-30000.000000000000000000000000000000000000000000001", 10,
+ MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 38);
+ mpfr_set_str (x, "-3.623795987425E-121243", 10, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for gamma (test 7)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ /* was producing infinite loop */
+ set_emin (emin);
+ mpfr_set_prec (x, 71);
+ mpfr_set_prec (y, 71);
+ mpfr_set_str (x, "-200000000.1", 10, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!(mpfr_zero_p (y) && MPFR_SIGN (y) < 0))
+ {
+ printf ("Error for gamma (test 8)\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ set_emax (1073741823);
+ mpfr_set_prec (x, 29);
+ mpfr_set_prec (y, 29);
+ mpfr_set_str (x, "423786866", 10, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for gamma(423786866)\n");
+ exit (1);
+ }
+
+ /* check exact result */
+ mpfr_set_prec (x, 2);
+ mpfr_set_ui (x, 3, MPFR_RNDN);
+ inex = mpfr_gamma (x, x, MPFR_RNDN);
+ if (inex != 0 || mpfr_cmp_ui (x, 2) != 0)
+ {
+ printf ("Error for gamma(3)\n");
+ exit (1);
+ }
+
+ mpfr_set_emax (1024);
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "101010110100110011111010000110001000111100000110101E-43");
+ mpfr_gamma (x, x, MPFR_RNDU);
+ mpfr_set_str_binary (y, "110000011110001000111110110101011110000100001111111E971");
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for gamma(4)\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ set_emin (emin);
+ set_emax (emax);
+
+ /* bug found by Kevin Rauch, 26 Oct 2007 */
+ mpfr_set_str (x, "1e19", 10, MPFR_RNDN);
+ inex = mpfr_gamma (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && inex > 0);
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+/* test gamma on some integral values (from Christopher Creutzig). */
+static void
+gamma_integer (void)
+{
+ mpz_t n;
+ mpfr_t x, y;
+ unsigned int i;
+
+ mpz_init (n);
+ mpfr_init2 (x, 149);
+ mpfr_init2 (y, 149);
+
+ for (i = 0; i < 100; i++)
+ {
+ mpz_fac_ui (n, i);
+ mpfr_set_ui (x, i+1, MPFR_RNDN);
+ mpfr_gamma (y, x, MPFR_RNDN);
+ mpfr_set_z (x, n, MPFR_RNDN);
+ if (!mpfr_equal_p (x, y))
+ {
+ printf ("Error for gamma(%u)\n", i+1);
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+ }
+ mpfr_clear (y);
+ mpfr_clear (x);
+ mpz_clear (n);
+}
+
+/* bug found by Kevin Rauch */
+static void
+test20071231 (void)
+{
+ mpfr_t x;
+ int inex;
+ mpfr_exp_t emin;
+
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (-1000000);
+
+ mpfr_init2 (x, 21);
+ mpfr_set_str (x, "-1000001.5", 10, MPFR_RNDN);
+ inex = mpfr_gamma (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_POS(x) && inex < 0);
+ mpfr_clear (x);
+
+ mpfr_set_emin (emin);
+
+ mpfr_init2 (x, 53);
+ mpfr_set_str (x, "-1000000001.5", 10, MPFR_RNDN);
+ inex = mpfr_gamma (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_POS(x) && inex < 0);
+ mpfr_clear (x);
+}
+
+/* bug found by Stathis in mpfr_gamma, only occurs on 32-bit machines;
+ the second test is for 64-bit machines. This bug reappeared due to
+ r8159. */
+static void
+test20100709 (void)
+{
+ mpfr_t x, y, z;
+ int sign;
+ int inex;
+ mpfr_exp_t emin;
+
+ mpfr_init2 (x, 100);
+ mpfr_init2 (y, 32);
+ mpfr_init2 (z, 32);
+ mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_nextabove (y);
+ mpfr_log (y, y, MPFR_RNDD);
+ mpfr_const_log2 (z, MPFR_RNDU);
+ mpfr_sub (y, y, z, MPFR_RNDD); /* log(MIN/2) = log(MIN) - log(2) */
+ mpfr_lgamma (z, &sign, x, MPFR_RNDU);
+ MPFR_ASSERTN (sign == -1);
+ MPFR_ASSERTN (mpfr_less_p (z, y)); /* thus underflow */
+ inex = mpfr_gamma (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0);
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ /* Similar test for 64-bit machines (also valid with a 32-bit exponent,
+ but will not trigger the bug). */
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (MPFR_EMIN_MIN);
+ mpfr_init2 (x, 100);
+ mpfr_init2 (y, 32);
+ mpfr_init2 (z, 32);
+ mpfr_set_str (x, "-90.6308260837372266e+15", 10, MPFR_RNDN);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_nextabove (y);
+ mpfr_log (y, y, MPFR_RNDD);
+ mpfr_const_log2 (z, MPFR_RNDU);
+ mpfr_sub (y, y, z, MPFR_RNDD); /* log(MIN/2) = log(MIN) - log(2) */
+ mpfr_lgamma (z, &sign, x, MPFR_RNDU);
+ MPFR_ASSERTN (sign == -1);
+ MPFR_ASSERTN (mpfr_less_p (z, y)); /* thus underflow */
+ inex = mpfr_gamma (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0);
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_set_emin (emin);
+}
+
+/* bug found by Giridhar Tammana */
+static void
+test20120426 (void)
+{
+ mpfr_t xa, xb;
+ int i;
+ mpfr_exp_t emin;
+
+ mpfr_init2 (xa, 53);
+ mpfr_init2 (xb, 53);
+ mpfr_set_d (xb, -168.5, MPFR_RNDN);
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (-1073);
+ i = mpfr_gamma (xa, xb, MPFR_RNDN);
+ i = mpfr_subnormalize (xa, i, MPFR_RNDN); /* new ternary value */
+ mpfr_set_str (xb, "-9.5737343987585366746184749943e-304", 10, MPFR_RNDN);
+ if (!((i > 0) && (mpfr_cmp (xa, xb) == 0)))
+ {
+ printf ("Error in test20120426, i=%d\n", i);
+ printf ("expected ");
+ mpfr_print_binary (xb); putchar ('\n');
+ printf ("got ");
+ mpfr_print_binary (xa); putchar ('\n');
+ exit (1);
+ }
+ mpfr_set_emin (emin);
+ mpfr_clear (xa);
+ mpfr_clear (xb);
+}
+
+static void
+exprange (void)
+{
+ mpfr_exp_t emin, emax;
+ mpfr_t x, y, z;
+ int inex1, inex2;
+ unsigned int flags1, flags2;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 16);
+ mpfr_inits2 (8, y, z, (mpfr_ptr) 0);
+
+ mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex1 = mpfr_gamma (y, x, MPFR_RNDN);
+ flags1 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ mpfr_set_emin (0);
+ mpfr_clear_flags ();
+ inex2 = mpfr_gamma (z, x, MPFR_RNDN);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ mpfr_set_emin (emin);
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test1)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+
+ mpfr_set_ui_2exp (x, 32769, -60, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex1 = mpfr_gamma (y, x, MPFR_RNDD);
+ flags1 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ mpfr_set_emax (45);
+ mpfr_clear_flags ();
+ inex2 = mpfr_gamma (z, x, MPFR_RNDD);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ mpfr_set_emax (emax);
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test2)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+
+ mpfr_set_emax (44);
+ mpfr_clear_flags ();
+ inex1 = mpfr_check_range (y, inex1, MPFR_RNDD);
+ flags1 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ mpfr_clear_flags ();
+ inex2 = mpfr_gamma (z, x, MPFR_RNDD);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ mpfr_set_emax (emax);
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test3)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+
+ mpfr_set_ui_2exp (x, 1, -60, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex1 = mpfr_gamma (y, x, MPFR_RNDD);
+ flags1 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ mpfr_set_emax (60);
+ mpfr_clear_flags ();
+ inex2 = mpfr_gamma (z, x, MPFR_RNDD);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ mpfr_set_emax (emax);
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test4)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+
+ MPFR_ASSERTN (MPFR_EMIN_MIN == - MPFR_EMAX_MAX);
+ mpfr_set_emin (MPFR_EMIN_MIN);
+ mpfr_set_emax (MPFR_EMAX_MAX);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_nextabove (x); /* x = 2^(emin - 1) */
+ mpfr_set_inf (y, 1);
+ inex1 = 1;
+ flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
+ mpfr_clear_flags ();
+ /* MPFR_RNDU: overflow, infinity since 1/x = 2^(emax + 1) */
+ inex2 = mpfr_gamma (z, x, MPFR_RNDU);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test5)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+ mpfr_clear_flags ();
+ /* MPFR_RNDN: overflow, infinity since 1/x = 2^(emax + 1) */
+ inex2 = mpfr_gamma (z, x, MPFR_RNDN);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test6)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+ mpfr_nextbelow (y);
+ inex1 = -1;
+ mpfr_clear_flags ();
+ /* MPFR_RNDD: overflow, maxnum since 1/x = 2^(emax + 1) */
+ inex2 = mpfr_gamma (z, x, MPFR_RNDD);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test7)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+ mpfr_mul_2ui (x, x, 1, MPFR_RNDN); /* x = 2^emin */
+ mpfr_set_inf (y, 1);
+ inex1 = 1;
+ flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
+ mpfr_clear_flags ();
+ /* MPFR_RNDU: overflow, infinity since 1/x = 2^emax */
+ inex2 = mpfr_gamma (z, x, MPFR_RNDU);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test8)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+ mpfr_clear_flags ();
+ /* MPFR_RNDN: overflow, infinity since 1/x = 2^emax */
+ inex2 = mpfr_gamma (z, x, MPFR_RNDN);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test9)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+ mpfr_nextbelow (y);
+ inex1 = -1;
+ flags1 = MPFR_FLAGS_INEXACT;
+ mpfr_clear_flags ();
+ /* MPFR_RNDD: no overflow, maxnum since 1/x = 2^emax and euler > 0 */
+ inex2 = mpfr_gamma (z, x, MPFR_RNDD);
+ flags2 = __gmpfr_flags;
+ MPFR_ASSERTN (mpfr_inexflag_p ());
+ if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in exprange (test10)\n");
+ printf ("x = ");
+ mpfr_dump (x);
+ printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
+ mpfr_dump (y);
+ printf ("Got inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
+ mpfr_dump (z);
+ exit (1);
+ }
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+static int
+tiny_aux (int stop, mpfr_exp_t e)
+{
+ mpfr_t x, y, z;
+ int r, s, spm, inex, err = 0;
+ int expected_dir[2][5] = { { 1, -1, 1, -1, 1 }, { 1, 1, 1, -1, -1 } };
+ mpfr_exp_t saved_emax;
+
+ saved_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 32);
+ mpfr_inits2 (8, y, z, (mpfr_ptr) 0);
+
+ mpfr_set_ui_2exp (x, 1, e, MPFR_RNDN);
+ spm = 1;
+ for (s = 0; s < 2; s++)
+ {
+ RND_LOOP(r)
+ {
+ mpfr_rnd_t rr = (mpfr_rnd_t) r;
+ mpfr_exp_t exponent, emax;
+
+ /* Exponent of the rounded value in unbounded exponent range. */
+ exponent = expected_dir[s][r] < 0 && s == 0 ? - e : 1 - e;
+
+ for (emax = exponent - 1; emax <= exponent; emax++)
+ {
+ unsigned int flags, expected_flags = MPFR_FLAGS_INEXACT;
+ int overflow, expected_inex = expected_dir[s][r];
+
+ if (emax > MPFR_EMAX_MAX)
+ break;
+ mpfr_set_emax (emax);
+
+ mpfr_clear_flags ();
+ inex = mpfr_gamma (y, x, rr);
+ flags = __gmpfr_flags;
+ mpfr_clear_flags ();
+ mpfr_set_si_2exp (z, spm, - e, MPFR_RNDU);
+ overflow = mpfr_overflow_p ();
+ /* z is 1/x - euler rounded toward +inf */
+
+ if (overflow && rr == MPFR_RNDN && s == 1)
+ expected_inex = -1;
+
+ if (expected_inex < 0)
+ mpfr_nextbelow (z); /* 1/x - euler rounded toward -inf */
+
+ if (exponent > emax)
+ expected_flags |= MPFR_FLAGS_OVERFLOW;
+
+ if (!(mpfr_equal_p (y, z) && flags == expected_flags
+ && SAME_SIGN (inex, expected_inex)))
+ {
+ printf ("Error in tiny for s = %d, r = %s, emax = %"
+ MPFR_EXP_FSPEC "d%s\n on ",
+ s, mpfr_print_rnd_mode (rr), emax,
+ exponent > emax ? " (overflow)" : "");
+ mpfr_dump (x);
+ printf (" expected inex = %2d, ", expected_inex);
+ mpfr_dump (z);
+ printf (" got inex = %2d, ", SIGN (inex));
+ mpfr_dump (y);
+ printf (" expected flags = %u, got %u\n",
+ expected_flags, flags);
+ if (stop)
+ exit (1);
+ err = 1;
+ }
+ }
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ spm = - spm;
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+ mpfr_set_emax (saved_emax);
+ return err;
+}
+
+static void
+tiny (int stop)
+{
+ mpfr_exp_t emin;
+ int err = 0;
+
+ emin = mpfr_get_emin ();
+
+ /* Note: in r7499, exponent -17 will select the generic code (in
+ tiny_aux, x has precision 32), while the other exponent values
+ will select special code for tiny values. */
+ err |= tiny_aux (stop, -17);
+ err |= tiny_aux (stop, -999);
+ err |= tiny_aux (stop, mpfr_get_emin ());
+
+ if (emin != MPFR_EMIN_MIN)
+ {
+ mpfr_set_emin (MPFR_EMIN_MIN);
+ err |= tiny_aux (stop, MPFR_EMIN_MIN);
+ mpfr_set_emin (emin);
+ }
+
+ if (err)
+ exit (1);
+}
+
+/* Test mpfr_gamma in precision p1 by comparing it with exp(lgamma(x))
+ computing with a working precision p2. Assume that x is not an
+ integer <= 2. */
+static void
+exp_lgamma (mpfr_t x, mpfr_prec_t p1, mpfr_prec_t p2)
+{
+ mpfr_t yd, yu, zd, zu;
+ int inexd, inexu, sign;
+ int underflow = -1, overflow = -1; /* -1: we don't know */
+ int got_underflow, got_overflow;
+
+ if (mpfr_integer_p (x) && mpfr_cmp_si (x, 2) <= 0)
+ {
+ printf ("Warning! x is an integer <= 2 in exp_lgamma: ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ return;
+ }
+ mpfr_inits2 (p2, yd, yu, (mpfr_ptr) 0);
+ inexd = mpfr_lgamma (yd, &sign, x, MPFR_RNDD);
+ mpfr_set (yu, yd, MPFR_RNDN); /* exact */
+ if (inexd)
+ mpfr_nextabove (yu);
+ mpfr_clear_flags ();
+ mpfr_exp (yd, yd, MPFR_RNDD);
+ if (! mpfr_underflow_p ())
+ underflow = 0;
+ if (mpfr_overflow_p ())
+ overflow = 1;
+ mpfr_clear_flags ();
+ mpfr_exp (yu, yu, MPFR_RNDU);
+ if (mpfr_underflow_p ())
+ underflow = 1;
+ if (! mpfr_overflow_p ())
+ overflow = 0;
+ if (sign < 0)
+ {
+ mpfr_neg (yd, yd, MPFR_RNDN); /* exact */
+ mpfr_neg (yu, yu, MPFR_RNDN); /* exact */
+ mpfr_swap (yd, yu);
+ }
+ /* yd < Gamma(x) < yu (strict inequalities since x != 1 and x != 2) */
+ mpfr_inits2 (p1, zd, zu, (mpfr_ptr) 0);
+ mpfr_clear_flags ();
+ inexd = mpfr_gamma (zd, x, MPFR_RNDD); /* zd <= Gamma(x) < yu */
+ got_underflow = underflow == -1 ? -1 : !! mpfr_underflow_p ();
+ got_overflow = overflow == -1 ? -1 : !! mpfr_overflow_p ();
+ if (! mpfr_less_p (zd, yu) || inexd > 0 ||
+ got_underflow != underflow ||
+ got_overflow != overflow)
+ {
+ printf ("Error in exp_lgamma on x = ");
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ printf ("yu = ");
+ mpfr_dump (yu);
+ printf ("zd = ");
+ mpfr_dump (zd);
+ printf ("got inexd = %d, expected <= 0\n", inexd);
+ printf ("got underflow = %d, expected %d\n", got_underflow, underflow);
+ printf ("got overflow = %d, expected %d\n", got_overflow, overflow);
+ exit (1);
+ }
+ mpfr_clear_flags ();
+ inexu = mpfr_gamma (zu, x, MPFR_RNDU); /* zu >= Gamma(x) > yd */
+ got_underflow = underflow == -1 ? -1 : !! mpfr_underflow_p ();
+ got_overflow = overflow == -1 ? -1 : !! mpfr_overflow_p ();
+ if (! mpfr_greater_p (zu, yd) || inexu < 0 ||
+ got_underflow != underflow ||
+ got_overflow != overflow)
+ {
+ printf ("Error in exp_lgamma on x = ");
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ printf ("yd = ");
+ mpfr_dump (yd);
+ printf ("zu = ");
+ mpfr_dump (zu);
+ printf ("got inexu = %d, expected >= 0\n", inexu);
+ printf ("got underflow = %d, expected %d\n", got_underflow, underflow);
+ printf ("got overflow = %d, expected %d\n", got_overflow, overflow);
+ exit (1);
+ }
+ if (mpfr_equal_p (zd, zu))
+ {
+ if (inexd != 0 || inexu != 0)
+ {
+ printf ("Error in exp_lgamma on x = ");
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ printf ("zd = zu, thus exact, but inexd = %d and inexu = %d\n",
+ inexd, inexu);
+ exit (1);
+ }
+ MPFR_ASSERTN (got_underflow == 0);
+ MPFR_ASSERTN (got_overflow == 0);
+ }
+ else if (inexd == 0 || inexu == 0)
+ {
+ printf ("Error in exp_lgamma on x = ");
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ printf ("zd != zu, thus inexact, but inexd = %d and inexu = %d\n",
+ inexd, inexu);
+ exit (1);
+ }
+ mpfr_clears (yd, yu, zd, zu, (mpfr_ptr) 0);
+}
+
+static void
+exp_lgamma_tests (void)
+{
+ mpfr_t x;
+ mpfr_exp_t emin, emax;
+ int i;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ set_emin (MPFR_EMIN_MIN);
+ set_emax (MPFR_EMAX_MAX);
+
+ mpfr_init2 (x, 96);
+ for (i = 3; i <= 8; i++)
+ {
+ mpfr_set_ui (x, i, MPFR_RNDN);
+ exp_lgamma (x, 53, 64);
+ mpfr_nextbelow (x);
+ exp_lgamma (x, 53, 64);
+ mpfr_nextabove (x);
+ mpfr_nextabove (x);
+ exp_lgamma (x, 53, 64);
+ }
+ mpfr_set_str (x, "1.7", 10, MPFR_RNDN);
+ exp_lgamma (x, 53, 64);
+ mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN);
+ exp_lgamma (x, 53, 64);
+ mpfr_set_str (x, "-90.6308260837372266e+15", 10, MPFR_RNDN);
+ exp_lgamma (x, 53, 64);
+ /* The following test gives a large positive result < +Inf */
+ mpfr_set_str (x, "1.2b13fc45a92dea1@14", 16, MPFR_RNDN);
+ exp_lgamma (x, 53, 64);
+ /* Idem for a large negative result > -Inf */
+ mpfr_set_str (x, "-1.2b13fc45a92de81@14", 16, MPFR_RNDN);
+ exp_lgamma (x, 53, 64);
+ /* The following two tests trigger an endless loop in r8186
+ on 64-bit machines (64-bit exponent). The second one (due
+ to undetected overflow) is a direct consequence of the
+ first one, due to the call of Gamma(2-x) if x < 1. */
+ mpfr_set_str (x, "1.2b13fc45a92dec8@14", 16, MPFR_RNDN);
+ exp_lgamma (x, 53, 64);
+ mpfr_set_str (x, "-1.2b13fc45a92dea8@14", 16, MPFR_RNDN);
+ exp_lgamma (x, 53, 64);
+ /* Similar tests (overflow threshold) for 32-bit machines. */
+ mpfr_set_str (x, "2ab68d8.657542f855111c61", 16, MPFR_RNDN);
+ exp_lgamma (x, 12, 64);
+ mpfr_set_str (x, "-2ab68d6.657542f855111c61", 16, MPFR_RNDN);
+ exp_lgamma (x, 12, 64);
+ /* The following test is an overflow on 32-bit and 64-bit machines.
+ Revision r8189 fails on 64-bit machines as the flag is unset. */
+ mpfr_set_str (x, "1.2b13fc45a92ded8@14", 16, MPFR_RNDN);
+ exp_lgamma (x, 53, 64);
+ /* On the following tests, with r8196, one gets an underflow on
+ 32-bit machines, while a normal result is expected (see FIXME
+ in gamma.c:382). */
+ mpfr_set_str (x, "-2ab68d6.657542f855111c6104", 16, MPFR_RNDN);
+ exp_lgamma (x, 12, 64); /* failure on 32-bit machines */
+ mpfr_set_str (x, "-12b13fc45a92deb.1c6c5bc964", 16, MPFR_RNDN);
+ exp_lgamma (x, 12, 64); /* failure on 64-bit machines */
+ mpfr_clear (x);
+
+ set_emin (emin);
+ set_emax (emax);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+ special_overflow ();
+ exprange ();
+ tiny (argc == 1);
+ test_generic (2, 100, 2);
+ gamma_integer ();
+ test20071231 ();
+ test20100709 ();
+ test20120426 ();
+ exp_lgamma_tests ();
+
+ data_check ("data/gamma", mpfr_gamma, "mpfr_gamma");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tgeneric.c b/mpfr/tests/tgeneric.c
new file mode 100644
index 0000000000..5787df4e0f
--- /dev/null
+++ b/mpfr/tests/tgeneric.c
@@ -0,0 +1,506 @@
+/* Generic test file for functions with one or two arguments (the second being
+ either mpfr_t or double).
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* define TWO_ARGS for two-argument functions like mpfr_pow
+ define DOUBLE_ARG1 or DOUBLE_ARG2 for function with a double operand in
+ first or second place like sub_d or d_sub */
+
+#ifndef TEST_RANDOM_POS
+/* For the random function: one number on two is negative. */
+#define TEST_RANDOM_POS 256
+#endif
+
+#ifndef TEST_RANDOM_POS2
+/* For the random function: one number on two is negative. */
+#define TEST_RANDOM_POS2 256
+#endif
+
+#ifndef TEST_RANDOM_EMIN
+#define TEST_RANDOM_EMIN -256
+#endif
+
+#ifndef TEST_RANDOM_EMAX
+#define TEST_RANDOM_EMAX 255
+#endif
+
+/* If the MPFR_SUSPICIOUS_OVERFLOW test fails but this is not a bug,
+ then define TGENERIC_SO_TEST with an adequate test (possibly 0) to
+ omit this particular case. */
+#ifndef TGENERIC_SO_TEST
+#define TGENERIC_SO_TEST 1
+#endif
+
+#define STR(F) #F
+#define MAKE_STR(S) STR(S)
+
+/* The (void *) below is needed to avoid a warning with gcc 4.2+ and functions
+ * with 2 arguments. See <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36299>.
+ */
+#define TGENERIC_FAIL(S, X, U) \
+ do \
+ { \
+ printf ("%s\nx = ", (S)); \
+ mpfr_out_str (stdout, 2, 0, (X), MPFR_RNDN); \
+ printf ("\n"); \
+ if ((void *) U != 0) \
+ { \
+ printf ("u = "); \
+ mpfr_out_str (stdout, 2, 0, (U), MPFR_RNDN); \
+ printf ("\n"); \
+ } \
+ printf ("yprec = %u, rnd_mode = %s, inexact = %d, flags = %u\n", \
+ (unsigned int) yprec, mpfr_print_rnd_mode (rnd), compare, \
+ (unsigned int) __gmpfr_flags); \
+ exit (1); \
+ } \
+ while (0)
+
+#define TGENERIC_CHECK_AUX(S, EXPR, U) \
+ do \
+ if (!(EXPR)) \
+ TGENERIC_FAIL (S " in " MAKE_STR(TEST_FUNCTION), x, U); \
+ while (0)
+
+#undef TGENERIC_CHECK
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+#define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, u)
+#else
+#define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, 0)
+#endif
+
+#ifdef DEBUG_TGENERIC
+#define TGENERIC_IAUX(F,P,X,U) \
+ do \
+ { \
+ printf ("tgeneric: testing function " STR(F) \
+ ", %s, target prec = %lu\nx = ", \
+ mpfr_print_rnd_mode (rnd), (unsigned long) (P)); \
+ mpfr_out_str (stdout, 2, 0, (X), MPFR_RNDN); \
+ printf ("\n"); \
+ if (U) \
+ { \
+ printf ("u = "); \
+ mpfr_out_str (stdout, 2, 0, (U), MPFR_RNDN); \
+ printf ("\n"); \
+ } \
+ } \
+ while (0)
+#undef TGENERIC_INFO
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+#define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,u)
+#else
+#define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,0)
+#endif
+#endif
+
+/* For some functions (for example cos), the argument reduction is too
+ expensive when using mpfr_get_emax(). Then simply define REDUCE_EMAX
+ to some reasonable value before including tgeneric.c. */
+#ifndef REDUCE_EMAX
+#define REDUCE_EMAX mpfr_get_emax ()
+#endif
+
+static void
+test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
+{
+ mpfr_prec_t prec, xprec, yprec;
+ mpfr_t x, y, z, t, w;
+#ifdef TWO_ARGS
+ mpfr_t u;
+#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ mpfr_t u;
+ double d;
+#endif
+ mpfr_rnd_t rnd;
+ int inexact, compare, compare2;
+ unsigned int n;
+ unsigned long ctrt = 0, ctrn = 0;
+ mpfr_exp_t old_emin, old_emax;
+
+ old_emin = mpfr_get_emin ();
+ old_emax = mpfr_get_emax ();
+
+ mpfr_inits2 (MPFR_PREC_MIN, x, y, z, t, w, (mpfr_ptr) 0);
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ mpfr_init2 (u, MPFR_PREC_MIN);
+#endif
+
+ /* generic test */
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (z, prec);
+ mpfr_set_prec (t, prec);
+ yprec = prec + 10;
+ mpfr_set_prec (y, yprec);
+ mpfr_set_prec (w, yprec);
+
+ /* Note: in precision p1, we test 4 special cases. */
+ for (n = 0; n < (prec == p1 ? nmax + 4 : nmax); n++)
+ {
+ int infinite_input = 0;
+
+ xprec = prec;
+ if (randlimb () & 1)
+ {
+ xprec *= (double) randlimb () / MP_LIMB_T_MAX;
+ if (xprec < MPFR_PREC_MIN)
+ xprec = MPFR_PREC_MIN;
+ }
+ mpfr_set_prec (x, xprec);
+#ifdef TWO_ARGS
+ mpfr_set_prec (u, xprec);
+#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
+#endif
+
+ if (n > 3 || prec < p1)
+ {
+#if defined(RAND_FUNCTION)
+ RAND_FUNCTION (x);
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ RAND_FUNCTION (u);
+#endif
+#else
+ tests_default_random (x, TEST_RANDOM_POS,
+ TEST_RANDOM_EMIN, TEST_RANDOM_EMAX);
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ tests_default_random (u, TEST_RANDOM_POS2,
+ TEST_RANDOM_EMIN, TEST_RANDOM_EMAX);
+#endif
+#endif
+ }
+ else
+ {
+ /* Special cases tested in precision p1 if n <= 3. They are
+ useful really in the extended exponent range. */
+#if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO)
+ goto next_n;
+#endif
+ set_emin (MPFR_EMIN_MIN);
+ set_emax (MPFR_EMAX_MAX);
+ if (n <= 1)
+ {
+ mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
+ mpfr_set_exp (x, mpfr_get_emin ());
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
+ mpfr_set_exp (u, mpfr_get_emin ());
+#endif
+ }
+ else /* 2 <= n <= 3 */
+ {
+ if (getenv ("MPFR_CHECK_MAX") == NULL)
+ goto next_n;
+ mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
+ mpfr_setmax (x, REDUCE_EMAX);
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
+ mpfr_setmax (u, mpfr_get_emax ());
+#endif
+ }
+ }
+
+ rnd = RND_RAND ();
+ mpfr_clear_flags ();
+#ifdef DEBUG_TGENERIC
+ TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y));
+#endif
+#if defined(TWO_ARGS)
+ compare = TEST_FUNCTION (y, x, u, rnd);
+#elif defined(DOUBLE_ARG1)
+ d = mpfr_get_d (u, rnd);
+ compare = TEST_FUNCTION (y, d, x, rnd);
+ /* d can be infinite due to overflow in mpfr_get_d */
+ infinite_input |= DOUBLE_ISINF (d);
+#elif defined(DOUBLE_ARG2)
+ d = mpfr_get_d (u, rnd);
+ compare = TEST_FUNCTION (y, x, d, rnd);
+ /* d can be infinite due to overflow in mpfr_get_d */
+ infinite_input |= DOUBLE_ISINF (d);
+#else
+ compare = TEST_FUNCTION (y, x, rnd);
+#endif
+ TGENERIC_CHECK ("Bad inexact flag",
+ (compare != 0) ^ (mpfr_inexflag_p () == 0));
+ ctrt++;
+ /* Consistency test in a reduced exponent range. Doing it
+ for the first 10 samples and for prec == p1 (which has
+ some special cases) should be sufficient. */
+ if (ctrt <= 10 || prec == p1)
+ {
+ unsigned int flags, oldflags = __gmpfr_flags;
+ mpfr_exp_t e, emin, emax, oemin, oemax;
+
+ /* Determine the smallest exponent range containing the
+ exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
+ and output (y). */
+ emin = MPFR_EMAX_MAX;
+ emax = MPFR_EMIN_MIN;
+ if (MPFR_IS_PURE_FP (x))
+ {
+ e = MPFR_GET_EXP (x);
+ if (e < emin)
+ emin = e;
+ if (e > emax)
+ emax = e;
+ }
+ if (MPFR_IS_PURE_FP (y))
+ {
+ e = MPFR_GET_EXP (y);
+ if (e < emin)
+ emin = e;
+ if (e > emax)
+ emax = e;
+ }
+#if defined(TWO_ARGS)
+ if (MPFR_IS_PURE_FP (u))
+ {
+ e = MPFR_GET_EXP (u);
+ if (e < emin)
+ emin = e;
+ if (e > emax)
+ emax = e;
+ }
+#endif
+ if (emin > emax)
+ emin = emax; /* case where all values are singular */
+ oemin = mpfr_get_emin ();
+ oemax = mpfr_get_emax ();
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+#ifdef DEBUG_TGENERIC
+ /* Useful information in case of assertion failure. */
+ printf ("tgeneric: reduced exponent range [%"
+ MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
+ (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
+#endif
+ mpfr_clear_flags ();
+#if defined(TWO_ARGS)
+ inexact = TEST_FUNCTION (w, x, u, rnd);
+#elif defined(DOUBLE_ARG1)
+ inexact = TEST_FUNCTION (w, d, x, rnd);
+#elif defined(DOUBLE_ARG2)
+ inexact = TEST_FUNCTION (w, x, d, rnd);
+#else
+ inexact = TEST_FUNCTION (w, x, rnd);
+#endif
+ flags = __gmpfr_flags;
+ mpfr_set_emin (oemin);
+ mpfr_set_emax (oemax);
+ if (! (SAME_VAL (w, y) &&
+ SAME_SIGN (inexact, compare) &&
+ flags == oldflags))
+ {
+ printf ("Error in " MAKE_STR(TEST_FUNCTION)
+ ", reduced exponent range [%"
+ MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
+ (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
+ printf ("x = ");
+ mpfr_dump (x);
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ printf ("u = ");
+ mpfr_dump (u);
+#endif
+ printf ("yprec = %u, rnd_mode = %s\n",
+ (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
+ printf ("Expected:\n y = ");
+ mpfr_dump (y);
+ printf (" inex = %d, flags = %u\n",
+ SIGN (compare), oldflags);
+ printf ("Got:\n w = ");
+ mpfr_dump (w);
+ printf (" inex = %d, flags = %u\n",
+ SIGN (inexact), flags);
+ exit (1);
+ }
+ }
+ if (MPFR_IS_SINGULAR (y))
+ {
+ if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())
+ TGENERIC_CHECK ("Bad NaN flag",
+ MPFR_IS_NAN (y) && mpfr_nanflag_p ());
+ else if (MPFR_IS_INF (y))
+ {
+ TGENERIC_CHECK ("Bad overflow flag",
+ (compare != 0) ^ (mpfr_overflow_p () == 0));
+ TGENERIC_CHECK ("Bad divide-by-zero flag",
+ (compare == 0 && !infinite_input) ^
+ (mpfr_divby0_p () == 0));
+ }
+ else if (MPFR_IS_ZERO (y))
+ TGENERIC_CHECK ("Bad underflow flag",
+ (compare != 0) ^ (mpfr_underflow_p () == 0));
+ }
+ else if (mpfr_divby0_p ())
+ {
+ TGENERIC_CHECK ("Both overflow and divide-by-zero",
+ ! mpfr_overflow_p ());
+ TGENERIC_CHECK ("Both underflow and divide-by-zero",
+ ! mpfr_underflow_p ());
+ TGENERIC_CHECK ("Bad compare value (divide-by-zero)",
+ compare == 0);
+ }
+ else if (mpfr_overflow_p ())
+ {
+ TGENERIC_CHECK ("Both underflow and overflow",
+ ! mpfr_underflow_p ());
+ TGENERIC_CHECK ("Bad compare value (overflow)", compare != 0);
+ mpfr_nexttoinf (y);
+ TGENERIC_CHECK ("Should have been max MPFR number",
+ MPFR_IS_INF (y));
+ }
+ else if (mpfr_underflow_p ())
+ {
+ TGENERIC_CHECK ("Bad compare value (underflow)", compare != 0);
+ mpfr_nexttozero (y);
+ TGENERIC_CHECK ("Should have been min MPFR number",
+ MPFR_IS_ZERO (y));
+ }
+ else if (mpfr_can_round (y, yprec, rnd, rnd, prec))
+ {
+ ctrn++;
+ mpfr_set (t, y, rnd);
+ /* Risk of failures are known when some flags are already set
+ before the function call. Do not set the erange flag, as
+ it will remain set after the function call and no checks
+ are performed in such a case (see the mpfr_erangeflag_p
+ test below). */
+ if (randlimb () & 1)
+ __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
+#ifdef DEBUG_TGENERIC
+ TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z));
+#endif
+ /* Let's increase the precision of the inputs in a random way.
+ In most cases, this doesn't make any difference, but for
+ the mpfr_fmod bug fixed in r6230, this triggers the bug. */
+ mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
+ MPFR_RNDN);
+#if defined(TWO_ARGS)
+ mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
+ MPFR_RNDN);
+ inexact = TEST_FUNCTION (z, x, u, rnd);
+#elif defined(DOUBLE_ARG1)
+ inexact = TEST_FUNCTION (z, d, x, rnd);
+#elif defined(DOUBLE_ARG2)
+ inexact = TEST_FUNCTION (z, x, d, rnd);
+#else
+ inexact = TEST_FUNCTION (z, x, rnd);
+#endif
+ if (mpfr_erangeflag_p ())
+ goto next_n;
+ if (mpfr_nan_p (z) || mpfr_cmp (t, z) != 0)
+ {
+ printf ("results differ for x=");
+ mpfr_out_str (stdout, 2, xprec, x, MPFR_RNDN);
+#ifdef TWO_ARGS
+ printf ("\nu=");
+ mpfr_out_str (stdout, 2, xprec, u, MPFR_RNDN);
+#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ printf ("\nu=");
+ mpfr_out_str (stdout, 2, IEEE_DBL_MANT_DIG, u, MPFR_RNDN);
+#endif
+ printf (" prec=%u rnd_mode=%s\n", (unsigned) prec,
+ mpfr_print_rnd_mode (rnd));
+ printf ("got ");
+ mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
+ puts ("");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
+ puts ("");
+ printf ("approx ");
+ mpfr_print_binary (y);
+ puts ("");
+ exit (1);
+ }
+ compare2 = mpfr_cmp (t, y);
+ /* if rounding to nearest, cannot know the sign of t - f(x)
+ because of composed rounding: y = o(f(x)) and t = o(y) */
+ if (compare * compare2 >= 0)
+ compare = compare + compare2;
+ else
+ compare = inexact; /* cannot determine sign(t-f(x)) */
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact > 0) && (compare <= 0)) ||
+ ((inexact < 0) && (compare >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
+ "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
+ printf ("x="); mpfr_print_binary (x); puts ("");
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ printf ("u="); mpfr_print_binary (u); puts ("");
+#endif
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ printf ("t="); mpfr_print_binary (t); puts ("");
+ exit (1);
+ }
+ }
+ else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL)
+ {
+ /* For developers only! */
+ MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
+ mpfr_nexttoinf (y);
+ if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))
+ && !mpfr_overflow_p () && TGENERIC_SO_TEST)
+ {
+ printf ("Possible bug! |y| is the maximum finite number "
+ "and has been obtained when\nrounding toward zero"
+ " (%s). Thus there is a very probable overflow,\n"
+ "but the overflow flag is not set!\n",
+ mpfr_print_rnd_mode (rnd));
+ printf ("x="); mpfr_print_binary (x); puts ("");
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ printf ("u="); mpfr_print_binary (u); puts ("");
+#endif
+ exit (1);
+ }
+ }
+
+ next_n:
+ /* In case the exponent range has been changed by
+ tests_default_random() or for special values... */
+ mpfr_set_emin (old_emin);
+ mpfr_set_emax (old_emax);
+ }
+ }
+
+#ifndef TGENERIC_NOWARNING
+ if (3 * ctrn < 2 * ctrt)
+ printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n",
+ ctrn, ctrt);
+#endif
+
+ mpfr_clears (x, y, z, t, w, (mpfr_ptr) 0);
+#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
+ mpfr_clear (u);
+#endif
+}
+
+#undef TEST_RANDOM_POS
+#undef TEST_RANDOM_POS2
+#undef TEST_RANDOM_EMIN
+#undef TEST_RANDOM_EMAX
+#undef RAND_FUNCTION
+#undef TWO_ARGS
+#undef TWO_ARGS_UI
+#undef TEST_FUNCTION
+#undef test_generic
diff --git a/mpfr/tests/tgeneric_ui.c b/mpfr/tests/tgeneric_ui.c
new file mode 100644
index 0000000000..22b6170374
--- /dev/null
+++ b/mpfr/tests/tgeneric_ui.c
@@ -0,0 +1,130 @@
+/* Generic test file for functions with one mpfr_t argument and an integer.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* define INTEGER_TYPE to what we want */
+#ifndef INTEGER_TYPE
+# define INTEGER_TYPE mp_limb_t
+#endif
+#ifndef RAND_FUNCTION
+# define RAND_FUNCTION(x) mpfr_urandomb ((x), RANDS)
+#endif
+#ifndef INT_RAND_FUNCTION
+# define INT_RAND_FUNCTION() (INTEGER_TYPE) randlimb ()
+#endif
+
+static void
+test_generic_ui (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N)
+{
+ mpfr_prec_t prec, yprec;
+ mpfr_t x, y, z, t;
+ INTEGER_TYPE u;
+ mpfr_rnd_t rnd;
+ int inexact, compare, compare2;
+ unsigned int n;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (t);
+
+ /* generic test */
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (z, prec);
+ mpfr_set_prec (t, prec);
+ yprec = prec + 10;
+
+ for (n = 0; n <= N; n++)
+ {
+ if (n > 1 || prec < p1)
+ RAND_FUNCTION (x);
+ else
+ {
+ /* Special cases tested in precision p1 if n <= 1. */
+ mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
+ mpfr_set_exp (x, mpfr_get_emin ());
+ }
+ u = INT_RAND_FUNCTION ();
+ rnd = RND_RAND ();
+ mpfr_set_prec (y, yprec);
+ compare = TEST_FUNCTION (y, x, u, rnd);
+ if (mpfr_can_round (y, yprec, rnd, rnd, prec))
+ {
+ mpfr_set (t, y, rnd);
+ inexact = TEST_FUNCTION (z, x, u, rnd);
+ if (mpfr_cmp (t, z))
+ {
+ printf ("results differ for x=");
+ mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
+ printf ("\nu=%lu", (unsigned long) u);
+ printf (" prec=%lu rnd_mode=%s\n",
+ (unsigned long ) prec, mpfr_print_rnd_mode (rnd));
+#ifdef TEST_FUNCTION_NAME
+ printf ("Function: %s\n", TEST_FUNCTION_NAME);
+#endif
+ printf ("got ");
+ mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
+ puts ("");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
+ puts ("");
+ printf ("approx ");
+ mpfr_print_binary (y);
+ puts ("");
+ exit (1);
+ }
+ compare2 = mpfr_cmp (t, y);
+ /* if rounding to nearest, cannot know the sign of t - f(x)
+ because of composed rounding: y = o(f(x)) and t = o(y) */
+ if (compare * compare2 >= 0)
+ compare = compare + compare2;
+ else
+ compare = inexact; /* cannot determine sign(t-f(x)) */
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact > 0) && (compare <= 0)) ||
+ ((inexact < 0) && (compare >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
+ "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("u=%lu", (unsigned long) u);
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ printf ("t="); mpfr_print_binary (t); puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+}
+
+#undef RAND_FUNCTION
+#undef INTEGER_TYPE
+#undef TEST_FUNCTION
+#undef TEST_FUNCTION_NAME
+#undef test_generic_ui
+#undef INT_RAND_FUNCTION
diff --git a/mpfr/tests/tget_d.c b/mpfr/tests/tget_d.c
new file mode 100644
index 0000000000..25cac5f40f
--- /dev/null
+++ b/mpfr/tests/tget_d.c
@@ -0,0 +1,294 @@
+/* Test file for mpfr_get_d
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+#include "ieee_floats.h"
+
+static int
+check_denorms (void)
+{
+ mpfr_rnd_t rnd_mode;
+ mpfr_t x;
+ double d, d2, dd, f;
+ int fail = 0, k, n;
+
+ mpfr_init2 (x, GMP_NUMB_BITS);
+
+ rnd_mode = MPFR_RNDN;
+ for (k = -17; k <= 17; k += 2)
+ {
+ d = (double) k * DBL_MIN; /* k * 2^(-1022) */
+ f = 1.0;
+ mpfr_set_si (x, k, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 1022, MPFR_RNDN); /* k * 2^(-1022) */
+ for (n = 0; n <= 58; n++)
+ {
+ d2 = d * f;
+ dd = mpfr_get_d (x, rnd_mode);
+ if (d2 != dd) /* should be k * 2^(-1022-n) for n < 53 */
+ {
+ printf ("Wrong result for %d * 2^(%d), rnd_mode %d\n",
+ k, -1022-n, rnd_mode);
+ printf ("got %.20e instead of %.20e\n", dd, d2);
+ fail = 1;
+ }
+ f *= 0.5;
+ mpfr_div_2exp (x, x, 1, MPFR_RNDN);
+ }
+ }
+
+ mpfr_set_str_binary (x, "1e-1074");
+ dd = mpfr_get_d (x, MPFR_RNDA);
+ d2 = DBL_MIN; /* 2^(-1022) */
+ for (k = 0; k < 52; k++)
+ d2 *= 0.5; /* 2^(-1074) */
+ /* we first check that d2 is not zero (it could happen on a platform with
+ no subnormals) */
+ if (d2 != 0.0 && dd != d2)
+ {
+ printf ("Error for x=1e-1074, RNDA\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "1e-1075");
+ dd = mpfr_get_d (x, MPFR_RNDA);
+ if (d2 != 0.0 && dd != d2)
+ {
+ printf ("Error for x=1e-1075, RNDA\n");
+ printf ("expected %.16e\n", d2);
+ printf ("got %.16e\n", dd);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ return fail;
+}
+
+static void
+check_inf_nan (void)
+{
+ /* only if nans and infs are available */
+#if _GMP_IEEE_FLOATS && !defined(MPFR_ERRDIVZERO)
+ mpfr_t x;
+ double d;
+
+ mpfr_init2 (x, 123);
+
+ mpfr_set_inf (x, 1);
+ d = mpfr_get_d (x, MPFR_RNDZ);
+ ASSERT_ALWAYS (d > 0);
+ ASSERT_ALWAYS (DOUBLE_ISINF (d));
+
+ mpfr_set_inf (x, -1);
+ d = mpfr_get_d (x, MPFR_RNDZ);
+ ASSERT_ALWAYS (d < 0);
+ ASSERT_ALWAYS (DOUBLE_ISINF (d));
+
+ mpfr_set_nan (x);
+ d = mpfr_get_d (x, MPFR_RNDZ);
+ ASSERT_ALWAYS (DOUBLE_ISNAN (d));
+
+ mpfr_clear (x);
+#endif
+}
+
+static void
+check_max (void)
+{
+ double d, e;
+ mpfr_t u;
+
+ d = 1.0;
+ while (d < (DBL_MAX / 2.0))
+ d += d;
+ mpfr_init (u);
+ if (mpfr_set_d (u, d, MPFR_RNDN) == 0)
+ {
+ /* If setting is exact */
+ e = (mpfr_get_d1) (u);
+ if (e != d)
+ {
+ printf ("get_d(set_d)(1): %1.20e != %1.20e\n", d, e);
+ exit (1);
+ }
+ }
+
+ mpfr_set_str_binary (u, "-1E1024");
+ d = mpfr_get_d (u, MPFR_RNDZ);
+ MPFR_ASSERTN(d == -DBL_MAX);
+ d = mpfr_get_d (u, MPFR_RNDU);
+ MPFR_ASSERTN(d == -DBL_MAX);
+#if _GMP_IEEE_FLOATS && !defined(MPFR_ERRDIVZERO)
+ d = mpfr_get_d (u, MPFR_RNDN);
+ MPFR_ASSERTN(DOUBLE_ISINF(d) && d < 0.0);
+ d = mpfr_get_d (u, MPFR_RNDD);
+ MPFR_ASSERTN(DOUBLE_ISINF(d) && d < 0.0);
+#endif
+
+ mpfr_set_str_binary (u, "1E1024");
+ d = mpfr_get_d (u, MPFR_RNDZ);
+ MPFR_ASSERTN(d == DBL_MAX);
+ d = mpfr_get_d (u, MPFR_RNDD);
+ MPFR_ASSERTN(d == DBL_MAX);
+#if _GMP_IEEE_FLOATS && !defined(MPFR_ERRDIVZERO)
+ d = mpfr_get_d (u, MPFR_RNDN);
+ MPFR_ASSERTN(DOUBLE_ISINF(d) && d > 0.0);
+ d = mpfr_get_d (u, MPFR_RNDU);
+ MPFR_ASSERTN(DOUBLE_ISINF(d) && d > 0.0);
+#endif
+
+ mpfr_clear (u);
+}
+
+static void
+check_min(void)
+{
+ double d, e;
+ mpfr_t u;
+
+ d = 1.0; while (d > (DBL_MIN * 2.0)) d /= 2.0;
+ mpfr_init(u);
+ if (mpfr_set_d(u, d, MPFR_RNDN) == 0)
+ {
+ /* If setting is exact */
+ e = mpfr_get_d1(u);
+ if (e != d)
+ {
+ printf("get_d(set_d)(2): %1.20e != %1.20e\n", d, e);
+ exit(1);
+ }
+ }
+ mpfr_clear(u);
+}
+
+static void
+check_get_d_2exp_inf_nan (void)
+{
+ double var_d;
+ long exp;
+ mpfr_t var;
+
+#if !defined(MPFR_ERRDIVZERO)
+
+ mpfr_init2 (var, MPFR_PREC_MIN);
+
+ mpfr_set_nan (var);
+ var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
+ if (!DOUBLE_ISNAN (var_d))
+ {
+ printf ("mpfr_get_d_2exp with a NAN mpfr value returned a wrong value :\n"
+ " waiting for %g got %g\n", MPFR_DBL_NAN, var_d);
+ exit (1);
+ }
+
+ mpfr_set_zero (var, 1);
+ var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
+ if ((exp != 0) || (var_d != 0.0))
+ {
+ printf ("mpfr_get_d_2exp with a +0.0 mpfr value returned a wrong value :\n"
+ " double waiting for 0.0 got %g\n exp waiting for 0 got %ld\n",
+ var_d, exp);
+ exit (1);
+ }
+
+ mpfr_set_zero (var, -1);
+ var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
+ if ((exp != 0) || (var_d != DBL_NEG_ZERO))
+ {
+ printf ("mpfr_get_d_2exp with a +0.0 mpfr value returned a wrong value :\n"
+ " double waiting for %g got %g\n exp waiting for 0 got %ld\n",
+ DBL_NEG_ZERO, var_d, exp);
+ exit (1);
+ }
+
+ mpfr_set_inf (var, 1);
+ var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
+ if (var_d != MPFR_DBL_INFP)
+ {
+ printf ("mpfr_get_d_2exp with a +Inf mpfr value returned a wrong value :\n"
+ " waiting for %g got %g\n", MPFR_DBL_INFP, var_d);
+ exit (1);
+ }
+
+ mpfr_set_inf (var, -1);
+ var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
+ if (var_d != MPFR_DBL_INFM)
+ {
+ printf ("mpfr_get_d_2exp with a -Inf mpfr value returned a wrong value :\n"
+ " waiting for %g got %g\n", MPFR_DBL_INFM, var_d);
+ exit (1);
+ }
+
+ mpfr_clear (var);
+
+#endif
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+ mpfr_test_init ();
+
+#ifndef MPFR_DOUBLE_SPEC
+ printf ("Warning! The MPFR_DOUBLE_SPEC macro is not defined. This means\n"
+ "that you do not have a conforming C implementation and problems\n"
+ "may occur with conversions between MPFR numbers and standard\n"
+ "floating-point types. Please contact the MPFR team.\n");
+#elif MPFR_DOUBLE_SPEC == 0
+ /*
+ printf ("The type 'double' of your C implementation does not seem to\n"
+ "correspond to the IEEE-754 double precision. Though code has\n"
+ "been written to support such implementations, tests have been\n"
+ "done only on IEEE-754 double-precision implementations and\n"
+ "conversions between MPFR numbers and standard floating-point\n"
+ "types may be inaccurate. You may wish to contact the MPFR team\n"
+ "for further testing.\n");
+ */
+ printf ("The type 'double' of your C implementation does not seem to\n"
+ "correspond to the IEEE-754 double precision. Such particular\n"
+ "implementations are not supported yet, and conversions between\n"
+ "MPFR numbers and standard floating-point types may be very\n"
+ "inaccurate.\n");
+ printf ("FLT_RADIX = %ld\n", (long) FLT_RADIX);
+ printf ("DBL_MANT_DIG = %ld\n", (long) DBL_MANT_DIG);
+ printf ("DBL_MIN_EXP = %ld\n", (long) DBL_MIN_EXP);
+ printf ("DBL_MAX_EXP = %ld\n", (long) DBL_MAX_EXP);
+#endif
+
+ if (check_denorms ())
+ exit (1);
+
+ check_inf_nan ();
+ check_min();
+ check_max();
+
+ check_get_d_2exp_inf_nan ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
diff --git a/mpfr/tests/tget_d_2exp.c b/mpfr/tests/tget_d_2exp.c
new file mode 100644
index 0000000000..4589c3738f
--- /dev/null
+++ b/mpfr/tests/tget_d_2exp.c
@@ -0,0 +1,121 @@
+/* Test mpfr_get_d_2exp.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+
+/* Check that hardware rounding doesn't make mpfr_get_d_2exp return a value
+ outside its defined range. */
+static void
+check_round (void)
+{
+ static const unsigned long data[] = { 1, 32, 53, 54, 64, 128, 256, 512 };
+ mpfr_t f;
+ double got;
+ long got_exp;
+ int i, rnd_mode, neg;
+
+ mpfr_init2 (f, 1024L);
+
+ for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX ; rnd_mode++)
+ {
+ for (i = 0; i < (int) numberof (data); i++)
+ {
+ mpfr_set_ui (f, 1L, MPFR_RNDZ);
+ mpfr_mul_2exp (f, f, data[i], MPFR_RNDZ);
+ mpfr_sub_ui (f, f, 1L, MPFR_RNDZ);
+
+ for (neg = 0; neg <= 1; neg++)
+ {
+ got = mpfr_get_d_2exp (&got_exp, f, (mpfr_rnd_t) rnd_mode);
+
+ if (neg == 0
+ ? (got < 0.5 || got >= 1.0)
+ : (got <= -1.0 || got > -0.5))
+ {
+ printf ("mpfr_get_d_2exp wrong on 2**%lu-1\n", data[i]);
+ printf ("result out of range, expect 0.5 <= got < 1.0\n");
+ printf (" rnd_mode = %d\n", rnd_mode);
+ printf (" data[i] = %lu\n", data[i]);
+ printf (" f ");
+ mpfr_out_str (stdout, 2, 0, f, MPFR_RNDN);
+ printf ("\n");
+ d_trace (" got ", got);
+ printf (" got exp %ld\n", got_exp);
+ exit(1);
+ }
+
+ mpfr_neg (f, f, MPFR_RNDZ);
+ }
+ }
+ }
+
+ mpfr_clear (f);
+}
+
+
+static void
+check_inf_nan (void)
+{
+ /* only if nans and infs are available */
+#if _GMP_IEEE_FLOATS
+ mpfr_t x;
+ double d;
+ long exp;
+
+ mpfr_init2 (x, 123);
+
+ mpfr_set_inf (x, 1);
+ d = mpfr_get_d_2exp (&exp, x, MPFR_RNDZ);
+ ASSERT_ALWAYS (d > 0);
+ ASSERT_ALWAYS (DOUBLE_ISINF (d));
+
+ mpfr_set_inf (x, -1);
+ d = mpfr_get_d_2exp (&exp, x, MPFR_RNDZ);
+ ASSERT_ALWAYS (d < 0);
+ ASSERT_ALWAYS (DOUBLE_ISINF (d));
+
+ mpfr_set_nan (x);
+ d = mpfr_get_d_2exp (&exp, x, MPFR_RNDZ);
+ ASSERT_ALWAYS (DOUBLE_ISNAN (d));
+
+ mpfr_clear (x);
+#endif
+}
+
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+ mpfr_test_init ();
+
+ check_round ();
+ check_inf_nan ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tget_f.c b/mpfr/tests/tget_f.c
new file mode 100644
index 0000000000..2634a4c1b8
--- /dev/null
+++ b/mpfr/tests/tget_f.c
@@ -0,0 +1,390 @@
+/* Test file for mpfr_get_f.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+/* Test that there is no lost of accuracy when converting a mpfr_t number
+ into a mpf_t number (test with various precisions and exponents). */
+static void
+prec_test (void)
+{
+ int px, py;
+
+ for (py = 3; py <= 136; py++)
+ {
+ mpfr_t y1, y2, y3;
+
+ mpfr_init2 (y1, py);
+ mpfr_init2 (y2, py);
+ mpfr_init2 (y3, py);
+
+ for (px = 32; px <= 160; px += 32)
+ {
+ mpf_t x1, x2, x3;
+ int e;
+
+ mpf_init (x1);
+ mpf_init (x2);
+ mpf_init (x3);
+ mpfr_set_ui_2exp (y1, 1, py - 1, MPFR_RNDN);
+ mpfr_get_f (x1, y1, MPFR_RNDN); /* exact (power of 2) */
+ mpf_set (x2, x1);
+ mpfr_set (y2, y1, MPFR_RNDN);
+
+ for (e = py - 2; e >= 0; e--)
+ {
+ int inex;
+ mpf_div_2exp (x2, x2, 1);
+ mpf_add (x1, x1, x2);
+ mpfr_div_2exp (y2, y2, 1, MPFR_RNDN);
+ inex = mpfr_add (y1, y1, y2, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ mpfr_set_f (y3, x1, MPFR_RNDN);
+ if (! mpfr_equal_p (y1, y3))
+ break;
+ inex = mpfr_get_f (x3, y3, MPFR_RNDN);
+ if (mpf_cmp (x1, x3) != 0)
+ {
+ printf ("Error in prec_test (px = %d, py = %d, e = %d)\n",
+ px, py, e);
+ printf ("x1 = ");
+ mpf_out_str (stdout, 16, 0, x1);
+ printf ("\nx2 = ");
+ mpf_out_str (stdout, 16, 0, x2);
+ printf ("\n");
+ exit (1);
+ }
+ if (inex != 0)
+ {
+ printf ("Error in prec_test (px = %d, py = %d, e = %d)\n",
+ px, py, e);
+ printf ("wrong ternary value got: %+d, expected: 0\n",
+ inex);
+ exit (1);
+ }
+ }
+
+ mpf_clear (x1);
+ mpf_clear (x2);
+ mpf_clear (x3);
+ }
+
+ mpfr_clear (y1);
+ mpfr_clear (y2);
+ mpfr_clear (y3);
+ }
+}
+
+static void
+special_test (void)
+{
+ int inex;
+ mpf_t x;
+ mpfr_t y;
+
+ mpfr_init (y);
+ mpf_init (x);
+
+ mpfr_set_nan (y);
+ mpfr_clear_flags ();
+ mpfr_get_f (x, y, MPFR_RNDN);
+ if (! mpfr_erangeflag_p ())
+ {
+ printf ("Error: mpfr_get_f(NaN) should raise erange flag\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (y, +1);
+ mpfr_clear_flags ();
+ inex = mpfr_get_f (x, y, MPFR_RNDN);
+ if (inex >= 0)
+ {
+ printf ("Error: mpfr_get_f(+Inf) should return a negative ternary"
+ "value\n");
+ exit (1);
+ }
+ if (! mpfr_erangeflag_p ())
+ {
+ printf ("Error: mpfr_get_f(+Inf) should raise erange flag\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (y, -1);
+ mpfr_clear_flags ();
+ inex = mpfr_get_f (x, y, MPFR_RNDN);
+ if (inex <= 0)
+ {
+ printf ("Error: mpfr_get_f(-Inf) should return a positive ternary"
+ "value\n");
+ exit (1);
+ }
+ if (! mpfr_erangeflag_p ())
+ {
+ printf ("Error: mpfr_get_f(-Inf) should raise erange flag\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_ui (x, 0))
+ {
+ printf ("Error: mpfr_get_f(+0) fails\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_neg (y, y, MPFR_RNDN);
+ if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_ui (x, 0))
+ {
+ printf ("Error: mpfr_get_f(-0) fails\n");
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpf_clear (x);
+}
+
+static void
+ternary_test (void)
+{
+ int prec;
+ int rnd;
+ int inex, expected_inex;
+ mpf_t x;
+ mpfr_t y;
+
+ mpf_init2 (x, 256);
+ mpfr_init2 (y, 256);
+
+ for (prec = 2; prec <= 256; prec++)
+ {
+
+ mpf_set_prec (x, prec);
+ mpfr_set_prec (y, PREC (x) * GMP_NUMB_BITS + 1);
+
+ /* y == 1 */
+ mpfr_set_ui_2exp (y, 1, prec, MPFR_RNDN);
+
+ RND_LOOP (rnd)
+ {
+ inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd);
+
+ if (inex != 0 || mpfr_cmp_f (y, x) !=0)
+ {
+ printf ("Error in mpfr_get_f (x, y, %s)\nx = ",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpf_out_str (stdout, 2, 0, x);
+ printf ("\ny = ");
+ mpfr_dump (y);
+ if (inex != 0)
+ printf ("got ternary value = %+d, expected: 0\n", inex);
+
+ exit (1);
+ }
+ }
+
+ /* y == 1 + epsilon */
+ mpfr_nextbelow (y);
+
+ RND_LOOP (rnd)
+ {
+ switch (rnd)
+ {
+ case MPFR_RNDU: case MPFR_RNDA:
+ case MPFR_RNDN:
+ expected_inex = +1;
+ break;
+ default :
+ expected_inex = -1;
+ }
+
+ inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd);
+
+ if (! SAME_SIGN (expected_inex, inex)
+ || SAME_SIGN (expected_inex, mpfr_cmp_f (y, x)))
+ {
+ printf ("Error in mpfr_get_f (x, y, %s)\nx = ",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpf_out_str (stdout, 2, 0, x);
+ printf ("\ny = ");
+ mpfr_dump (y);
+ if (! SAME_SIGN (expected_inex, inex))
+ printf ("got ternary value = %+d, expected: %+d\n",
+ inex, expected_inex);
+
+ exit (1);
+ }
+ }
+
+ /* y == positive random float */
+ mpfr_random2 (y, MPFR_LIMB_SIZE (y), 1024, RANDS);
+
+ RND_LOOP (rnd)
+ {
+ inex = mpfr_get_f (x, y, (mpfr_rnd_t) rnd);
+
+ if (! SAME_SIGN (inex, -mpfr_cmp_f (y, x)))
+ {
+ printf ("Error in mpfr_get_f (x, y, %s)\nx = ",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpf_out_str (stdout, 2, 0, x);
+ printf ("\ny = ");
+ mpfr_dump (y);
+ printf ("got ternary value = %+d, expected: %+d\n",
+ inex, -mpfr_cmp_f (y, x));
+
+ exit (1);
+ }
+ }
+ }
+
+ mpf_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (void)
+{
+ mpf_t x;
+ mpfr_t y, z;
+ unsigned long i;
+ mpfr_exp_t e;
+ int inex;
+
+ tests_start_mpfr ();
+
+ mpfr_init (y);
+ mpfr_init (z);
+ mpf_init (x);
+
+ i = 1;
+ while (i)
+ {
+ mpfr_set_ui (y, i, MPFR_RNDN);
+ if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_ui (x, i))
+ {
+ printf ("Error: mpfr_get_f(%lu) fails\n", i);
+ exit (1);
+ }
+ if (i <= - (unsigned long) LONG_MIN)
+ {
+ long j = i < - (unsigned long) LONG_MIN ? - (long) i : LONG_MIN;
+ mpfr_set_si (y, j, MPFR_RNDN);
+ if (mpfr_get_f (x, y, MPFR_RNDN) != 0 || mpf_cmp_si (x, j))
+ {
+ printf ("Error: mpfr_get_f(-%lu) fails\n", i);
+ exit (1);
+ }
+ }
+ i *= 2;
+ }
+
+ /* same tests, but with a larger precision for y, which requires to
+ round it */
+ mpfr_set_prec (y, 100);
+ i = 1;
+ while (i)
+ {
+ mpfr_set_ui (y, i, MPFR_RNDN);
+ inex = mpfr_get_f (x, y, MPFR_RNDN);
+ if (! SAME_SIGN (inex, - mpfr_cmp_f (y, x)) || mpf_cmp_ui (x, i))
+ {
+ printf ("Error: mpfr_get_f(%lu) fails\n", i);
+ exit (1);
+ }
+ mpfr_set_si (y, (signed long) -i, MPFR_RNDN);
+ inex = mpfr_get_f (x, y, MPFR_RNDN);
+ if (! SAME_SIGN (inex, - mpfr_cmp_f (y, x))
+ || mpf_cmp_si (x, (signed long) -i))
+ {
+ printf ("Error: mpfr_get_f(-%lu) fails\n", i);
+ exit (1);
+ }
+ i *= 2;
+ }
+
+ /* bug reported by Jim White */
+ for (e = 0; e <= 2 * GMP_NUMB_BITS; e++)
+ {
+ /* test with 2^(-e) */
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_div_2exp (y, y, e, MPFR_RNDN);
+ inex = mpfr_get_f (x, y, MPFR_RNDN);
+ mpf_mul_2exp (x, x, e);
+ if (inex != 0 || mpf_cmp_ui (x, 1) != 0)
+ {
+ printf ("Error: mpfr_get_f(x,y,MPFR_RNDN) fails\n");
+ printf ("y=");
+ mpfr_dump (y);
+ printf ("x=");
+ mpf_div_2exp (x, x, e);
+ mpf_out_str (stdout, 2, 0, x);
+ exit (1);
+ }
+
+ /* test with 2^(e) */
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_mul_2exp (y, y, e, MPFR_RNDN);
+ inex = mpfr_get_f (x, y, MPFR_RNDN);
+ mpf_div_2exp (x, x, e);
+ if (inex != 0 || mpf_cmp_ui (x, 1) != 0)
+ {
+ printf ("Error: mpfr_get_f(x,y,MPFR_RNDN) fails\n");
+ printf ("y=");
+ mpfr_dump (y);
+ printf ("x=");
+ mpf_mul_2exp (x, x, e);
+ mpf_out_str (stdout, 2, 0, x);
+ exit (1);
+ }
+ }
+
+ /* Bug reported by Yury Lukach on 2006-04-05 */
+ mpfr_set_prec (y, 32);
+ mpfr_set_prec (z, 32);
+ mpf_set_prec (x, 32);
+ mpfr_set_ui_2exp (y, 0xc1234567, -30, MPFR_RNDN);
+ mpfr_get_f (x, y, MPFR_RNDN);
+ inex = mpfr_set_f (z, x, MPFR_RNDN);
+ if (inex != 0 || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in mpfr_get_f:\n inex = %d, y = ", inex);
+ mpfr_dump (z);
+ printf ("Expected:\n inex = 0, y = ");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpf_clear (x);
+
+ special_test ();
+ prec_test ();
+ ternary_test ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tget_flt.c b/mpfr/tests/tget_flt.c
new file mode 100644
index 0000000000..cf5bd5a666
--- /dev/null
+++ b/mpfr/tests/tget_flt.c
@@ -0,0 +1,385 @@
+/* Test file for mpfr_get_flt and mpfr_set_flt
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include <float.h> /* for FLT_MIN */
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ mpfr_t x, y;
+ float f, g, infp;
+ int i;
+
+ infp = (float) DBL_POS_INF;
+ if (infp * 0.5 != infp)
+ {
+ fprintf (stderr, "Error, FLT_MAX + FLT_MAX does not yield INFP\n");
+ fprintf (stderr, "(this is probably a compiler bug, please report)\n");
+ exit (1);
+ }
+
+ tests_start_mpfr ();
+
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 24);
+
+#if !defined(MPFR_ERRDIVZERO)
+ mpfr_set_nan (x);
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ if (f == f)
+ {
+ printf ("Error for mpfr_get_flt(NaN)\n");
+ exit (1);
+ }
+ mpfr_set_flt (x, f, MPFR_RNDN);
+ if (mpfr_nan_p (x) == 0)
+ {
+ printf ("Error for mpfr_set_flt(NaN)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ mpfr_set_flt (x, f, MPFR_RNDN);
+ if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) < 0)
+ {
+ printf ("Error for mpfr_set_flt(mpfr_get_flt(+Inf)):\n");
+ printf ("f=%f, expected -Inf\n", f);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ mpfr_set_flt (x, f, MPFR_RNDN);
+ if (mpfr_inf_p (x) == 0 || mpfr_sgn (x) > 0)
+ {
+ printf ("Error for mpfr_set_flt(mpfr_get_flt(-Inf)):\n");
+ printf ("f=%f, expected -Inf\n", f);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+#endif
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ mpfr_set_flt (x, f, MPFR_RNDN);
+ if (mpfr_zero_p (x) == 0 || MPFR_SIGN (x) < 0)
+ {
+ printf ("Error for mpfr_set_flt(mpfr_get_flt(+0))\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ mpfr_set_flt (x, f, MPFR_RNDN);
+ if (mpfr_zero_p (x) == 0 || MPFR_SIGN (x) > 0)
+ {
+ printf ("Error for mpfr_set_flt(mpfr_get_flt(-0))\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ mpfr_set_flt (x, f, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 17) != 0)
+ {
+ printf ("Error for mpfr_set_flt(mpfr_get_flt(17))\n");
+ printf ("expected 17\n");
+ printf ("got ");
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -42, MPFR_RNDN);
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ mpfr_set_flt (x, f, MPFR_RNDN);
+ if (mpfr_cmp_si (x, -42) != 0)
+ {
+ printf ("Error for mpfr_set_flt(mpfr_get_flt(-42))\n");
+ printf ("expected -42\n");
+ printf ("got ");
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
+ for (i = -126; i < 128; i++)
+ {
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ mpfr_set_flt (y, f, MPFR_RNDN);
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
+ for (i = -126; i < 128; i++)
+ {
+ mpfr_nextbelow (x);
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ mpfr_nextabove (x);
+ mpfr_set_flt (y, f, MPFR_RNDN);
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
+ for (i = -126; i < 128; i++)
+ {
+ mpfr_nextabove (x);
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ mpfr_nextbelow (x);
+ mpfr_set_flt (y, f, MPFR_RNDN);
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
+ printf ("expected "); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
+ }
+
+ mpfr_set_si_2exp (x, 1, -150, MPFR_RNDN);
+ g = 0.0;
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-150),RNDN)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDZ);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-150),RNDZ)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDD);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-150),RNDD)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ g = FLT_MIN * FLT_EPSILON;
+ f = mpfr_get_flt (x, MPFR_RNDU);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-150),RNDU)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDA);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-150),RNDA)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+
+ mpfr_set_si_2exp (x, 1, -151, MPFR_RNDN);
+ g = 0.0;
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-151),RNDN)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDZ);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-151),RNDZ)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDD);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-151),RNDD)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ g = FLT_MIN * FLT_EPSILON;
+ f = mpfr_get_flt (x, MPFR_RNDU);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-151),RNDU)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDA);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-151),RNDA)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+
+ mpfr_set_si_2exp (x, 1, -149, MPFR_RNDN);
+ g = FLT_MIN * FLT_EPSILON;
+ f = mpfr_get_flt (x, MPFR_RNDN);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-149),RNDN)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDZ);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-149),RNDZ)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDD);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-149),RNDD)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDU);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-149),RNDU)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDA);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^(-149),RNDA)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+
+ mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
+ g = FLT_MAX;
+ f = mpfr_get_flt (x, MPFR_RNDZ);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128,RNDZ)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDD);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128,RNDD)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+#if !defined(MPFR_ERRDIVZERO)
+ f = mpfr_get_flt (x, MPFR_RNDN); /* 2^128 rounds to itself with extended
+ exponent range, we should get +Inf */
+ g = infp;
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128,RNDN)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDU);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128,RNDU)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDA);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128,RNDA)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+#endif
+
+ /* corner case: take x with 25 bits just below 2^128 */
+ mpfr_set_prec (x, 25);
+ mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
+ mpfr_nextbelow (x);
+ g = FLT_MAX;
+ f = mpfr_get_flt (x, MPFR_RNDZ);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDZ)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDD);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDD)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDN); /* first round to 2^128 (even rule),
+ thus we should get +Inf */
+ g = infp;
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDN)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDU);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDU)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+ f = mpfr_get_flt (x, MPFR_RNDA);
+ if (f != g)
+ {
+ printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDA)\n");
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tget_ld_2exp.c b/mpfr/tests/tget_ld_2exp.c
new file mode 100644
index 0000000000..c001adf70c
--- /dev/null
+++ b/mpfr/tests/tget_ld_2exp.c
@@ -0,0 +1,145 @@
+/* Test mpfr_get_ld_2exp.
+
+Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+/* Check that hardware rounding doesn't make mpfr_get_ld_2exp return a value
+ outside its defined range. */
+static void
+check_round (void)
+{
+ static const unsigned long data[] = {1, 32, 53, 54, 63, 64, 65, 127, 128, 256, 512 };
+ mpfr_t f;
+ long double got;
+ long got_exp;
+ int i, rnd_mode, neg;
+
+ mpfr_init2 (f, 1024L);
+
+ for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX ; rnd_mode++)
+ {
+ for (i = 0; i < (int) numberof (data); i++)
+ {
+ mpfr_set_ui (f, 1L, MPFR_RNDZ);
+ mpfr_mul_2exp (f, f, data[i], MPFR_RNDZ);
+ mpfr_sub_ui (f, f, 1L, MPFR_RNDZ);
+
+ for (neg = 0; neg <= 1; neg++)
+ {
+ got = mpfr_get_ld_2exp (&got_exp, f, (mpfr_rnd_t) rnd_mode);
+
+ if (neg == 0
+ ? (got < 0.5 || got >= 1.0)
+ : (got <= -1.0 || got > -0.5))
+ {
+ printf ("mpfr_get_ld_2exp wrong on 2**%lu-1\n", data[i]);
+ printf ("result out of range, expect 0.5 <= got < 1.0\n");
+ printf (" rnd_mode = %d\n", rnd_mode);
+ printf (" data[i] = %lu\n", data[i]);
+ printf (" f ");
+ mpfr_out_str (stdout, 2, 0, f, MPFR_RNDN);
+ printf ("\n");
+ d_trace (" got ", got);
+ printf (" got exp %ld\n", got_exp);
+ exit(1);
+ }
+
+ mpfr_neg (f, f, MPFR_RNDZ);
+ }
+ }
+ }
+
+ mpfr_clear (f);
+}
+
+
+static void
+check_inf_nan (void)
+{
+ /* only if nans and infs are available */
+#if _GMP_IEEE_FLOATS
+ mpfr_t x;
+ double d;
+ long exp;
+
+ mpfr_init2 (x, 123);
+
+ mpfr_set_inf (x, 1);
+ d = (double) mpfr_get_ld_2exp (&exp, x, MPFR_RNDZ);
+ ASSERT_ALWAYS (d > 0);
+ ASSERT_ALWAYS (DOUBLE_ISINF (d));
+
+ mpfr_set_inf (x, -1);
+ d = (double) mpfr_get_ld_2exp (&exp, x, MPFR_RNDZ);
+ ASSERT_ALWAYS (d < 0);
+ ASSERT_ALWAYS (DOUBLE_ISINF (d));
+
+ mpfr_set_nan (x);
+ d = (double) mpfr_get_ld_2exp (&exp, x, MPFR_RNDZ);
+ ASSERT_ALWAYS (DOUBLE_ISNAN (d));
+
+ mpfr_clear (x);
+#endif
+}
+
+static void
+bug20090520 (void)
+{
+ mpfr_t x;
+ long double d, e;
+ int i;
+
+ mpfr_init (x);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ d = 1.0;
+ mpfr_div_2exp (x, x, 16383, MPFR_RNDN);
+ for (i = 0; i < 16383; i++)
+ d *= 0.5;
+ e = mpfr_get_ld (x, MPFR_RNDN);
+ if (e != d)
+ {
+ printf ("mpfr_get_ld(1e-16383) failed\n");
+ printf ("expected %.20Le\n", d);
+ printf ("got %.20Le\n", e);
+ exit (1);
+ }
+ mpfr_clear (x);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+ mpfr_test_init ();
+
+ bug20090520 ();
+
+ check_round ();
+ check_inf_nan ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tget_set_d64.c b/mpfr/tests/tget_set_d64.c
new file mode 100644
index 0000000000..37fa63c6a3
--- /dev/null
+++ b/mpfr/tests/tget_set_d64.c
@@ -0,0 +1,349 @@
+/* Test file for mpfr_get_decimal64 and mpfr_set_decimal64.
+
+Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef MPFR_WANT_DECIMAL_FLOATS
+
+#include <stdlib.h> /* for exit */
+#include "mpfr-test.h"
+
+#ifndef DEC64_MAX
+# define DEC64_MAX 9.999999999999999E384dd
+#endif
+
+/* #define DEBUG */
+
+static void
+print_decimal64 (_Decimal64 d)
+{
+ union ieee_double_extract x;
+ union ieee_double_decimal64 y;
+ unsigned int Gh, i;
+
+ y.d64 = d;
+ x.d = y.d;
+ Gh = x.s.exp >> 6;
+ printf ("|%d%d%d%d%d%d", x.s.sig, Gh >> 4, (Gh >> 3) & 1,
+ (Gh >> 2) & 1, (Gh >> 1) & 1, Gh & 1);
+ printf ("%d%d%d%d%d%d", (x.s.exp >> 5) & 1, (x.s.exp >> 4) & 1,
+ (x.s.exp >> 3) & 1, (x.s.exp >> 2) & 1, (x.s.exp >> 1) & 1,
+ x.s.exp & 1);
+ for (i = 20; i > 0; i--)
+ printf ("%d", (x.s.manh >> (i - 1)) & 1);
+ for (i = 32; i > 0; i--)
+ printf ("%d", (x.s.manl >> (i - 1)) & 1);
+ printf ("|\n");
+}
+
+static void
+check_inf_nan (void)
+{
+ mpfr_t x, y;
+ _Decimal64 d;
+
+ mpfr_init2 (x, 123);
+ mpfr_init2 (y, 123);
+
+ mpfr_set_nan (x);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 1, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_nan_p (x));
+
+ mpfr_set_inf (x, 1);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 1, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+
+ mpfr_set_inf (x, -1);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 1, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_inf_p (x) && mpfr_sgn (x) < 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 1, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) > 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_neg (x, x, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 1, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) < 0);
+
+ mpfr_set_ui (x, 1, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp_ui (x, 1) == 0);
+
+ mpfr_set_si (x, -1, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp_si (x, -1) == 0);
+
+ mpfr_set_ui (x, 2, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp_ui (x, 2) == 0);
+
+ mpfr_set_ui (x, 99, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp_ui (x, 99) == 0);
+
+ mpfr_set_str (x, "9999999999999999", 10, MPFR_RNDZ);
+ mpfr_set (y, x, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
+
+ /* smallest normal number */
+ mpfr_set_str (x, "1E-383", 10, MPFR_RNDU);
+ mpfr_set (y, x, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDU);
+ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
+
+ /* smallest subnormal number */
+ mpfr_set_str (x, "1E-398", 10, MPFR_RNDU);
+ mpfr_set (y, x, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDU);
+ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
+
+ /* subnormal number with exponent change when we round back
+ from 16 digits to 1 digit */
+ mpfr_set_str (x, "9.9E-398", 10, MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, MPFR_RNDU); /* should be 1E-397 */
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDD);
+ mpfr_set_str (y, "1E-397", 10, MPFR_RNDN);
+ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
+
+ /* largest number */
+ mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ);
+ mpfr_set (y, x, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDU);
+ ASSERT_ALWAYS (d == DEC64_MAX);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
+
+ mpfr_set_str (x, "-9.999999999999999E384", 10, MPFR_RNDZ);
+ mpfr_set (y, x, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDA);
+ ASSERT_ALWAYS (d == -DEC64_MAX);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ /* largest number */
+ mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDZ);
+ mpfr_set_decimal64 (y, d, MPFR_RNDU);
+ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+check_random (void)
+{
+ mpfr_t x, y;
+ _Decimal64 d;
+ int i;
+
+ mpfr_init2 (x, 49);
+ mpfr_init2 (y, 49);
+
+ for (i = 0; i < 100000; i++)
+ {
+ mpfr_urandomb (x, RANDS); /* 0 <= x < 1 */
+ /* the normal decimal64 range contains [2^(-1272), 2^1278] */
+ mpfr_mul_2si (x, x, (i % 2550) - 1272, MPFR_RNDN);
+ if (mpfr_get_exp (x) <= -1272)
+ mpfr_mul_2exp (x, x, -1271 - mpfr_get_exp (x), MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ mpfr_set_decimal64 (y, d, MPFR_RNDN);
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("x="); mpfr_dump (x);
+ printf ("d="); print_decimal64 (d);
+ printf ("y="); mpfr_dump (y);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+/* check with native decimal formats */
+static void
+check_native (void)
+{
+ mpfr_t x;
+ _Decimal64 d;
+
+ mpfr_init2 (x, 53);
+
+ /* check important constants are correctly converted */
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN(d == 17.0dd);
+
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN(d == 42.0dd);
+
+ mpfr_set_decimal64 (x, 17.0dd, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 17) == 0);
+
+ mpfr_set_decimal64 (x, 42.0dd, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 42) == 0);
+
+ mpfr_clear (x);
+}
+
+static void
+check_overflow (void)
+{
+ mpfr_t x;
+ int err = 0, neg, rnd;
+
+ mpfr_init2 (x, 96);
+ for (neg = 0; neg < 2; neg++)
+ RND_LOOP (rnd)
+ {
+ _Decimal64 d, e;
+ mpfr_rnd_t r = (mpfr_rnd_t) rnd;
+ int sign = neg ? -1 : 1;
+
+ e = sign * (MPFR_IS_LIKE_RNDZ (r, neg) ? 1 : 2) * DEC64_MAX;
+ /* This tests the binary exponent e > 1279 case of get_d64.c */
+ mpfr_set_si_2exp (x, sign, 9999, MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, r);
+ if (d != e)
+ {
+ printf ("Error 1 in check_overflow for %s, %s\n",
+ neg ? "negative" : "positive",
+ mpfr_print_rnd_mode (r));
+ err = 1;
+ }
+ /* This tests the decimal exponent e > 385 case of get_d64.c */
+ mpfr_set_si_2exp (x, sign * 31, 1274, MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, r);
+ if (d != e)
+ {
+ printf ("Error 2 in check_overflow for %s, %s\n",
+ neg ? "negative" : "positive",
+ mpfr_print_rnd_mode (r));
+ err = 1;
+ }
+ /* This tests the last else (-382 <= e <= 385) of get_d64.c */
+ mpfr_set_decimal64 (x, e, MPFR_RNDA);
+ d = mpfr_get_decimal64 (x, r);
+ if (d != e)
+ {
+ printf ("Error 3 in check_overflow for %s, %s\n",
+ neg ? "negative" : "positive",
+ mpfr_print_rnd_mode (r));
+ err = 1;
+ }
+ }
+ mpfr_clear (x);
+ if (err)
+ exit (1);
+}
+
+static void
+check_tiny (void)
+{
+ mpfr_t x;
+ _Decimal64 d;
+
+ /* If 0.5E-398 < |x| < 1E-398 (smallest subnormal), x should round
+ to +/- 1E-398 in MPFR_RNDN. Note: the midpoint 0.5E-398 between
+ 0 and 1E-398 is not a representable binary number, so that there
+ are no tests for it. */
+ mpfr_init2 (x, 128);
+ mpfr_set_str (x, "1E-398", 10, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN (d == 1.0E-398dd);
+ mpfr_neg (x, x, MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN (d == -1.0E-398dd);
+ mpfr_set_str (x, "0.5E-398", 10, MPFR_RNDU);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN (d == 1.0E-398dd);
+ mpfr_neg (x, x, MPFR_RNDN);
+ d = mpfr_get_decimal64 (x, MPFR_RNDN);
+ MPFR_ASSERTN (d == -1.0E-398dd);
+ mpfr_clear (x);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+ mpfr_test_init ();
+
+#ifdef DEBUG
+#ifdef DPD_FORMAT
+ printf ("Using DPD format\n");
+#else
+ printf ("Using BID format\n");
+#endif
+#endif
+ check_inf_nan ();
+ check_random ();
+ check_native ();
+ check_overflow ();
+ check_tiny ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else /* MPFR_WANT_DECIMAL_FLOATS */
+
+int
+main (void)
+{
+ return 77;
+}
+
+#endif /* MPFR_WANT_DECIMAL_FLOATS */
diff --git a/mpfr/tests/tget_sj.c b/mpfr/tests/tget_sj.c
new file mode 100644
index 0000000000..d713e2e605
--- /dev/null
+++ b/mpfr/tests/tget_sj.c
@@ -0,0 +1,281 @@
+/* Test file for mpfr_get_sj and mpfr_get_uj.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-intmax.h"
+#include "mpfr-test.h"
+
+#ifndef _MPFR_H_HAVE_INTMAX_T
+
+int
+main (void)
+{
+ return 77;
+}
+
+#else
+
+static void
+check_sj (intmax_t s, mpfr_ptr x)
+{
+ mpfr_t y;
+ int i;
+
+ mpfr_init2 (y, MPFR_PREC (x));
+
+ for (i = -1; i <= 1; i++)
+ {
+ int rnd;
+
+ mpfr_set_si_2exp (y, i, -2, MPFR_RNDN);
+ mpfr_add (y, y, x, MPFR_RNDN);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ intmax_t r;
+
+ if (rnd == MPFR_RNDZ && i < 0 && s >= 0)
+ continue;
+ if (rnd == MPFR_RNDZ && i > 0 && s <= 0)
+ continue;
+ if (rnd == MPFR_RNDD && i < 0)
+ continue;
+ if (rnd == MPFR_RNDU && i > 0)
+ continue;
+ if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) ||
+ (MPFR_IS_NEG(y) && i < 0)))
+ continue;
+ /* rint (y) == x == s */
+ r = mpfr_get_sj (y, (mpfr_rnd_t) rnd);
+ if (r != s)
+ {
+ printf ("Error in check_sj for y = ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("Got %jd instead of %jd.\n", r, s);
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_clear (y);
+}
+
+static void
+check_uj (uintmax_t u, mpfr_ptr x)
+{
+ mpfr_t y;
+ int i;
+
+ mpfr_init2 (y, MPFR_PREC (x));
+
+ for (i = -1; i <= 1; i++)
+ {
+ int rnd;
+
+ mpfr_set_si_2exp (y, i, -2, MPFR_RNDN);
+ mpfr_add (y, y, x, MPFR_RNDN);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ uintmax_t r;
+
+ if (rnd == MPFR_RNDZ && i < 0)
+ continue;
+ if (rnd == MPFR_RNDD && i < 0)
+ continue;
+ if (rnd == MPFR_RNDU && i > 0)
+ continue;
+ if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) ||
+ (MPFR_IS_NEG(y) && i < 0)))
+ continue;
+ /* rint (y) == x == u */
+ r = mpfr_get_uj (y, (mpfr_rnd_t) rnd);
+ if (r != u)
+ {
+ printf ("Error in check_uj for y = ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("Got %ju instead of %ju.\n", r, u);
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_clear (y);
+}
+
+static void
+check_erange (void)
+{
+ mpfr_t x;
+ uintmax_t dl;
+ intmax_t d;
+
+ /* Test for ERANGE flag + correct behaviour if overflow */
+
+ mpfr_init2 (x, 256);
+ mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
+ mpfr_clear_erangeflag ();
+ dl = mpfr_get_uj (x, MPFR_RNDN);
+ if (dl != MPFR_UINTMAX_MAX || mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (1)\n");
+ exit (1);
+ }
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ dl = mpfr_get_uj (x, MPFR_RNDN);
+ if (dl != MPFR_UINTMAX_MAX || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (2)\n");
+ exit (1);
+ }
+ mpfr_set_sj (x, -1, MPFR_RNDN);
+ mpfr_clear_erangeflag ();
+ dl = mpfr_get_uj (x, MPFR_RNDN);
+ if (dl != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_uj + ERANGE + -1 \n");
+ exit (1);
+ }
+ mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
+ mpfr_clear_erangeflag ();
+ d = mpfr_get_sj (x, MPFR_RNDN);
+ if (d != MPFR_INTMAX_MAX || mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (1)\n");
+ exit (1);
+ }
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ d = mpfr_get_sj (x, MPFR_RNDN);
+ if (d != MPFR_INTMAX_MAX || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (2)\n");
+ exit (1);
+ }
+ mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN);
+ mpfr_clear_erangeflag ();
+ d = mpfr_get_sj (x, MPFR_RNDN);
+ if (d != MPFR_INTMAX_MIN || mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (1)\n");
+ exit (1);
+ }
+ mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+ d = mpfr_get_sj (x, MPFR_RNDN);
+ if (d != MPFR_INTMAX_MIN || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (2)\n");
+ exit (1);
+ }
+
+ mpfr_set_nan (x);
+ mpfr_clear_erangeflag ();
+ d = mpfr_get_uj (x, MPFR_RNDN);
+ if (d != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_uj + NaN\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ d = mpfr_get_sj (x, MPFR_RNDN);
+ if (d != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_sj + NaN\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+}
+
+int
+main (void)
+{
+ mpfr_prec_t prec;
+ mpfr_t x, y;
+ intmax_t s;
+ uintmax_t u;
+
+ tests_start_mpfr ();
+
+ for (u = MPFR_UINTMAX_MAX, prec = 0; u != 0; u /= 2, prec++)
+ { }
+
+ mpfr_init2 (x, prec + 4);
+ mpfr_init2 (y, prec + 4);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ check_sj (0, x);
+ check_uj (0, x);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ check_sj (1, x);
+ check_uj (1, x);
+
+ mpfr_neg (x, x, MPFR_RNDN);
+ check_sj (-1, x);
+
+ mpfr_set_si_2exp (x, 1, prec, MPFR_RNDN);
+ mpfr_sub_ui (x, x, 1, MPFR_RNDN); /* UINTMAX_MAX */
+
+ mpfr_div_ui (y, x, 2, MPFR_RNDZ);
+ mpfr_trunc (y, y); /* INTMAX_MAX */
+ for (s = MPFR_INTMAX_MAX; s != 0; s /= 17)
+ {
+ check_sj (s, y);
+ mpfr_div_ui (y, y, 17, MPFR_RNDZ);
+ mpfr_trunc (y, y);
+ }
+
+ mpfr_div_ui (y, x, 2, MPFR_RNDZ);
+ mpfr_trunc (y, y); /* INTMAX_MAX */
+ mpfr_neg (y, y, MPFR_RNDN);
+ if (MPFR_INTMAX_MIN + MPFR_INTMAX_MAX != 0)
+ mpfr_sub_ui (y, y, 1, MPFR_RNDN); /* INTMAX_MIN */
+ for (s = MPFR_INTMAX_MIN; s != 0; s /= 17)
+ {
+ check_sj (s, y);
+ mpfr_div_ui (y, y, 17, MPFR_RNDZ);
+ mpfr_trunc (y, y);
+ }
+
+ for (u = MPFR_UINTMAX_MAX; u != 0; u /= 17)
+ {
+ check_uj (u, x);
+ mpfr_div_ui (x, x, 17, MPFR_RNDZ);
+ mpfr_trunc (x, x);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ check_erange ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tget_str.c b/mpfr/tests/tget_str.c
new file mode 100644
index 0000000000..a143bdc0c1
--- /dev/null
+++ b/mpfr/tests/tget_str.c
@@ -0,0 +1,1268 @@
+/* Test file for mpfr_get_str.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+check3 (const char *d, mpfr_rnd_t rnd, const char *res)
+{
+ mpfr_t x;
+ char *str;
+ mpfr_exp_t e;
+
+ mpfr_init2 (x, 53);
+ mpfr_set_str (x, d, 10, rnd);
+ str = mpfr_get_str (NULL, &e, 10, 5, x, rnd);
+ if (strcmp (str, res))
+ {
+ printf ("Error in mpfr_get_str for x=%s\n", d);
+ printf ("got %s instead of %s\n", str, res);
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_free_str (str);
+}
+
+static void
+check_small (void)
+{
+ mpfr_t x;
+ char *s;
+ mpfr_exp_t e;
+ mpfr_prec_t p;
+
+ mpfr_init (x);
+
+ mpfr_set_prec (x, 20);
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_nexttozero (x);
+ s = mpfr_get_str (NULL, &e, 4, 2, x, MPFR_RNDU);
+ if (strcmp (s, "20") || (e != 1))
+ {
+ printf ("Error in mpfr_get_str: 2- rounded up with 2 digits"
+ " in base 4\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* check n_digits=0 */
+ mpfr_set_prec (x, 5);
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ s = mpfr_get_str (NULL, &e, 3, 0, x, MPFR_RNDN);
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 36, 0, x, MPFR_RNDN);
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 62, 0, x, MPFR_RNDN);
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 64);
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 63, MPFR_RNDN); /* x = -2^(-63) */
+ mpfr_add_ui (x, x, 1, MPFR_RNDN); /* x = 1 - 2^(-63) */
+ mpfr_mul_2exp (x, x, 32, MPFR_RNDN); /* x = 2^32 - 2^(-31) */
+ s = mpfr_get_str (NULL, &e, 3, 21, x, MPFR_RNDU);
+ if (strcmp (s, "102002022201221111211") || (e != 21))
+ {
+ printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with"
+ " 21 digits in base 3\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 3, 20, x, MPFR_RNDU);
+ if (strcmp (s, "10200202220122111122") || (e != 21))
+ {
+ printf ("Error in mpfr_get_str: 2^32-2^(-31) rounded up with"
+ " 20 digits in base 3\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* check corner case ret!=0, j0!=0 in mpfr_get_str_aux */
+ mpfr_set_prec (x, 100);
+ mpfr_set_str_binary (x, "0.1001011111010001101110010101010101111001010111111101101101100110100011110110000101110110001011110000E-9");
+ s = mpfr_get_str (NULL, &e, 3, 2, x, MPFR_RNDU);
+ if (strcmp (s, "22") || (e != -6))
+ {
+ printf ("Error in mpfr_get_str: 100-bit number rounded up with"
+ " 2 digits in base 3\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* check corner case exact=0 in mpfr_get_str_aux */
+ mpfr_set_prec (x, 100);
+ mpfr_set_str_binary (x, "0.1001001111101101111000101000110111111010101100000110010001111111011001101011101100001100110000000000E8");
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDZ);
+ if (strcmp (s, "14") || (e != 3))
+ {
+ printf ("Error in mpfr_get_str: 100-bit number rounded to zero with"
+ " 2 digits in base 10\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ for (p=4; p<=200; p++)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_set_str (x, "6.5", 10, MPFR_RNDN);
+
+ s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN);
+ if (strcmp (s, "10") || (e != 2))
+ {
+ printf ("Error in mpfr_get_str: 6.5 rounded to nearest with"
+ " 2 digits in base 6\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_nexttoinf (x);
+ s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN);
+ if (strcmp (s, "11") || (e != 2))
+ {
+ printf ("Error in mpfr_get_str: 6.5+ rounded to nearest with"
+ " 2 digits in base 6\ngot %se%d instead of 11e2\n",
+ s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str (x, "6.5", 10, MPFR_RNDN);
+ mpfr_nexttozero (x);
+ s = mpfr_get_str (NULL, &e, 6, 2, x, MPFR_RNDN);
+ if (strcmp (s, "10") || (e != 2))
+ {
+ printf ("Error in mpfr_get_str: 6.5- rounded to nearest with"
+ " 2 digits in base 6\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+ }
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_ui (x, 7, MPFR_RNDN);
+ s = mpfr_get_str (NULL, &e, 2, 2, x, MPFR_RNDU);
+ if (strcmp (s, "10") || (e != 4))
+ {
+ printf ("Error in mpfr_get_str: 7 rounded up with 2 bits should"
+ " give 0.10e3 instead of 0.%s*2^%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* problem found by Fabrice Rouillier */
+ mpfr_set_prec (x, 63);
+ mpfr_set_str (x, "5e14", 10, MPFR_RNDN);
+ s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU);
+ mpfr_free_str (s);
+
+ /* bug found by Johan Vervloet */
+ mpfr_set_prec (x, 6);
+ mpfr_set_str (x, "688.0", 10, MPFR_RNDN);
+ s = mpfr_get_str (NULL, &e, 2, 4, x, MPFR_RNDU);
+ if (strcmp (s, "1011") || (e != 10))
+ {
+ printf ("Error in mpfr_get_str: 688 printed up to 4 bits should"
+ " give 1.011e9\ninstead of ");
+ mpfr_out_str (stdout, 2, 4, x, MPFR_RNDU);
+ puts ("");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 38);
+ mpfr_set_str_binary (x, "1.0001110111110100011010100010010100110e-6");
+ s = mpfr_get_str (NULL, &e, 8, 10, x, MPFR_RNDU);
+ if (strcmp (s, "1073721522") || (e != -1))
+ {
+ printf ("Error in mpfr_get_str (3): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_str_binary (x, "0.11010111011101100010000100010101110001000000010111001E454");
+ s = mpfr_get_str (NULL, &e, 19, 12, x, MPFR_RNDU);
+ if (strcmp (s, "b1cgfa4gha0h") || (e != 107))
+ {
+ printf ("Error in mpfr_get_str (4): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 145);
+ mpfr_set_str_binary (x, "-0.1000110011000001011000010101101010110110101100101110100011111100011110011001001001010000100001000011000011000000010111011001000111101001110100110e6");
+ s = mpfr_get_str (NULL, &e, 4, 53, x, MPFR_RNDU);
+ if (strcmp (s, "-20303001120111222312230232203330132121021100201003003") || (e != 3))
+ {
+ printf ("Error in mpfr_get_str (5): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 45);
+ mpfr_set_str_binary (x, "-0.00100111010110010001011001110111010001010010010");
+ s = mpfr_get_str (NULL, &e, 32, 9, x, MPFR_RNDN);
+ if (strcmp (s, "-4tchctq54") || (e != 0))
+ {
+ printf ("Error in mpfr_get_str (6): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* worst case found by Vincent Lefe`vre */
+ mpfr_set_prec (x, 53);
+ mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E164");
+ s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
+ if (strcmp (s, "13076622631878654") || (e != 66))
+ {
+ printf ("Error in mpfr_get_str (7): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10000001001001001100011101010011011011111000011000100E93");
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
+ if (strcmp (s, "46") || e != 44)
+ {
+ printf ("Error in mpfr_get_str (8): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10010001111100000111001111010101001010000010111010101E55");
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN);
+ if (strcmp (s, "19") || e != 33)
+ {
+ printf ("Error in mpfr_get_str (9): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "11011001010010111110010101101100111110111000010110110E44");
+ s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDN);
+ if (strcmp (s, "135") || e != 30)
+ {
+ printf ("Error in mpfr_get_str (10): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "11101111101000001011100001111000011111101111011001100E72");
+ s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDN);
+ if (strcmp (s, "3981") || e != 38)
+ {
+ printf ("Error in mpfr_get_str (11): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10011001001100100010111100001101110101001001111110000E46");
+ s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDN);
+ if (strcmp (s, "37930") || e != 30)
+ {
+ printf ("Error in mpfr_get_str (12): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10001100110111001011011110011011011101100011010001011E-72");
+ s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDN);
+ if (strcmp (s, "104950") || e != -5)
+ {
+ printf ("Error in mpfr_get_str (13): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "10100100001011001000011001101101000110100110000010111E89");
+ s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDN);
+ if (strcmp (s, "3575392") || e != 43)
+ {
+ printf ("Error in mpfr_get_str (14): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "11000011011110110010100110001010000001010011001011001E-73");
+ s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDN);
+ if (strcmp (s, "72822386") || e != -6)
+ {
+ printf ("Error in mpfr_get_str (15): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "10101010001101000111001100001000100011100010010001010E78");
+ s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDN);
+ if (strcmp (s, "180992873") || e != 40)
+ {
+ printf ("Error in mpfr_get_str (16): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "10110111001000100000001101111001100101101110011011101E91");
+ s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDN);
+ if (strcmp (s, "1595312255") || e != 44)
+ {
+ printf ("Error in mpfr_get_str (17): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E93");
+ s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDN);
+ if (strcmp (s, "54835744350") || e != 44)
+ {
+ printf ("Error in mpfr_get_str (18): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E92");
+ s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDN);
+ if (strcmp (s, "274178721752") || e != 44)
+ {
+ printf ("Error in mpfr_get_str (19): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10011101010111101111000100111011101011110100110110101E91");
+ s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDN);
+ if (strcmp (s, "1370893608762") || e != 44)
+ {
+ printf ("Error in mpfr_get_str (20): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "10010011010110011100010010100101100011101000011111111E92");
+ s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDN);
+ if (strcmp (s, "25672105101864") || e != 44)
+ {
+ printf ("Error in mpfr_get_str (21): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "100110111110110001000101110100100101101000011111001E87");
+ s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDN);
+ if (strcmp (s, "212231308858721") || e != 42)
+ {
+ printf ("Error in mpfr_get_str (22): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10111010110000111000101100101111001011011100101001111E-128");
+ s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDN);
+ if (strcmp (s, "193109287087290") || e != -22)
+ {
+ printf ("Error in mpfr_get_str (22b): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "10001101101011010001111110000111010111010000110101010E80");
+ s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDN);
+ if (strcmp (s, "6026241735727920") || e != 40)
+ {
+ printf ("Error in mpfr_get_str (23): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "100010001011101001110101000110011001001000110001001E-81");
+ s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
+ if (strcmp (s, "49741483709103481") || e != -9)
+ {
+ printf ("Error in mpfr_get_str (24): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "11000100001001001110111010011001111001001010110101111E-101");
+ s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDN);
+ if (strcmp (s, "2722049") || e != -14)
+ {
+ printf ("Error in mpfr_get_str (25): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-135");
+ s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDN);
+ if (strcmp (s, "20138772") || e != -24)
+ {
+ printf ("Error in mpfr_get_str (26): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "11111001010011100101000001111111110001001001110110001E-136");
+ s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDN);
+ if (strcmp (s, "100693858") || e != -24)
+ {
+ printf ("Error in mpfr_get_str (27): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10001000001110010110001011111011111011011010000110001E-110");
+ s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDN);
+ if (strcmp (s, "36923634350619") || e != -17)
+ {
+ printf ("Error in mpfr_get_str (28): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "11001100010111000111100010000110011101110001000101111E-87");
+ s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDN);
+ if (strcmp (s, "4646636036100804") || e != -10)
+ {
+ printf ("Error in mpfr_get_str (29): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "10011111001111110100001001010111111011010101111111000E-99");
+ s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
+ if (strcmp (s, "88399901882446712") || e != -14)
+ {
+ printf ("Error in mpfr_get_str (30): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 8116315218207718*2^(-293) ~ 0.5100000000000000000015*10^(-72) */
+ mpfr_set_str_binary (x, "11100110101011011111011100101011101110110001111100110E-293");
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
+ if (strcmp (s, "52") || e != -72)
+ {
+ printf ("Error in mpfr_get_str (31u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDD);
+ if (strcmp (s, "51") || e != -72)
+ {
+ printf ("Error in mpfr_get_str (31d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 6712731423444934*2^536 ~ .151000000000000000000067*10^178 */
+ mpfr_set_str_binary (x, "10111110110010011000110010011111101111000111111000110E536");
+ s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDU);
+ if (strcmp (s, "152") || e != 178)
+ {
+ printf ("Error in mpfr_get_str (32u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 3, x, MPFR_RNDD);
+ if (strcmp (s, "151") || e != 178)
+ {
+ printf ("Error in mpfr_get_str (32d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 3356365711722467*2^540 ~ .120800000000000000000054*10^179 */
+ mpfr_set_str_binary (x, "1011111011001001100011001001111110111100011111100011E540");
+ s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDU);
+ if (strcmp (s, "1209") || e != 179)
+ {
+ printf ("Error in mpfr_get_str (33u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 4, x, MPFR_RNDD);
+ if (strcmp (s, "1208") || e != 179)
+ {
+ printf ("Error in mpfr_get_str (33d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 6475049196144587*2^100 ~ .8208099999999999999999988*10^46 */
+ mpfr_set_str_binary (x, "10111000000010000010111011111001111010100011111001011E100");
+ s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDU);
+ if (strcmp (s, "82081") || e != 46)
+ {
+ printf ("Error in mpfr_get_str (34u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 5, x, MPFR_RNDD);
+ if (strcmp (s, "82080") || e != 46)
+ {
+ printf ("Error in mpfr_get_str (34d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 6722280709661868*2^364 ~ .25260100000000000000000012*10^126 */
+ mpfr_set_str_binary (x, "10111111000011110000011110001110001111010010010101100E364");
+ s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDU);
+ if (strcmp (s, "252602") || e != 126)
+ {
+ printf ("Error in mpfr_get_str (35u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 6, x, MPFR_RNDD);
+ if (strcmp (s, "252601") || e != 126)
+ {
+ printf ("Error in mpfr_get_str (35d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 5381065484265332*2^(-455) ~ .578389299999999999999999982*10^(-121) */
+ mpfr_set_str_binary (x, "10011000111100000110011110000101100111110011101110100E-455");
+ s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDU);
+ if (strcmp (s, "5783893") || e != -121)
+ {
+ printf ("Error in mpfr_get_str (36u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 7, x, MPFR_RNDD);
+ if (strcmp (s, "5783892") || e != -121)
+ {
+ printf ("Error in mpfr_get_str (36d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 8369123604277281*2^(-852) ~ .27869147000000000000000000056*10^(-240) */
+ mpfr_set_str_binary (x, "11101101110111010110001101111100000111010100000100001E-852");
+ s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDU);
+ if (strcmp (s, "27869148") || e != -240)
+ {
+ printf ("Error in mpfr_get_str (37u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 8, x, MPFR_RNDD);
+ if (strcmp (s, "27869147") || e != -240)
+ {
+ printf ("Error in mpfr_get_str (37d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 7976538478610756*2^377 ~ .245540326999999999999999999982*10^130 */
+ mpfr_set_str_binary (x, "11100010101101001111010010110100011100000100101000100E377");
+ s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDU);
+ if (strcmp (s, "245540327") || e != 130)
+ {
+ printf ("Error in mpfr_get_str (38u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 9, x, MPFR_RNDD);
+ if (strcmp (s, "245540326") || e != 130)
+ {
+ printf ("Error in mpfr_get_str (38d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 8942832835564782*2^(-382) ~ .9078555839000000000000000000038*10^(-99) */
+ mpfr_set_str_binary (x, "11111110001010111010110000110011100110001010011101110E-382");
+ s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDU);
+ if (strcmp (s, "9078555840") || e != -99)
+ {
+ printf ("Error in mpfr_get_str (39u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 10, x, MPFR_RNDD);
+ if (strcmp (s, "9078555839") || e != -99)
+ {
+ printf ("Error in mpfr_get_str (39d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 4471416417782391*2^(-380) ~ .18157111678000000000000000000077*10^(-98) */
+ mpfr_set_str_binary (x, "1111111000101011101011000011001110011000101001110111E-380");
+ s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDU);
+ if (strcmp (s, "18157111679") || e != -98)
+ {
+ printf ("Error in mpfr_get_str (40u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 11, x, MPFR_RNDD);
+ if (strcmp (s, "18157111678") || e != -98)
+ {
+ printf ("Error in mpfr_get_str (40d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 7225450889282194*2^711 ~ .778380362292999999999999999999971*10^230 */
+ mpfr_set_str_binary (x, "11001101010111000001001100001100110010000001010010010E711");
+ s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDU);
+ if (strcmp (s, "778380362293") || e != 230)
+ {
+ printf ("Error in mpfr_get_str (41u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 12, x, MPFR_RNDD);
+ if (strcmp (s, "778380362292") || e != 230)
+ {
+ printf ("Error in mpfr_get_str (41d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 3612725444641097*2^713 ~ .1556760724585999999999999999999942*10^231 */
+ mpfr_set_str_binary (x, "1100110101011100000100110000110011001000000101001001E713");
+ s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDU);
+ if (strcmp (s, "1556760724586") || e != 231)
+ {
+ printf ("Error in mpfr_get_str (42u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 13, x, MPFR_RNDD);
+ if (strcmp (s, "1556760724585") || e != 231)
+ {
+ printf ("Error in mpfr_get_str (42d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 6965949469487146*2^(-248) ~ .15400733123779000000000000000000016*10^(-58) */
+ mpfr_set_str_binary (x, "11000101111110111111001111111101001101111000000101010E-248");
+ s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDU);
+ if (strcmp (s, "15400733123780") || e != -58)
+ {
+ printf ("Error in mpfr_get_str (43u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 14, x, MPFR_RNDD);
+ if (strcmp (s, "15400733123779") || e != -58)
+ {
+ printf ("Error in mpfr_get_str (43d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 3482974734743573*2^(-244) ~ .12320586499023200000000000000000013*10^(-57) */
+ mpfr_set_str_binary (x, "1100010111111011111100111111110100110111100000010101E-244");
+ s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDU);
+ if (strcmp (s, "123205864990233") || e != -57)
+ {
+ printf ("Error in mpfr_get_str (44u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 15, x, MPFR_RNDD);
+ if (strcmp (s, "123205864990232") || e != -57)
+ {
+ printf ("Error in mpfr_get_str (44d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 7542952370752766*2^(-919) ~ .170206189963739699999999999999999974*10^(-260) */
+ mpfr_set_str_binary (x, "11010110011000100011001110100100111011100110011111110E-919");
+ s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDU);
+ if (strcmp (s, "1702061899637397") || e != -260)
+ {
+ printf ("Error in mpfr_get_str (45u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 16, x, MPFR_RNDD);
+ if (strcmp (s, "1702061899637396") || e != -260)
+ {
+ printf ("Error in mpfr_get_str (45d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* 5592117679628511*2^165 ~ .26153245263757307000000000000000000074*10^66 */
+ mpfr_set_str_binary (x, "10011110111100000000001011011110101100010000011011111E165");
+ s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDU);
+ if (strcmp (s, "26153245263757308") || e != 66)
+ {
+ printf ("Error in mpfr_get_str (46u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDD);
+ if (strcmp (s, "26153245263757307") || e != 66)
+ {
+ printf ("Error in mpfr_get_str (46d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "11010010110111100001011010000110010000100001011011101E1223");
+ s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
+ if (strcmp (s, "10716284017294180") || e != 385)
+ {
+ printf ("Error in mpfr_get_str (47n): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU);
+ if (strcmp (s, "107162840172941805") || e != 385)
+ {
+ printf ("Error in mpfr_get_str (47u): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDD);
+ if (strcmp (s, "107162840172941804") || e != 385)
+ {
+ printf ("Error in mpfr_get_str (47d): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_str_binary (x, "11111101111011000001010100001101101000010010001111E122620");
+ s = mpfr_get_str (NULL, &e, 10, 17, x, MPFR_RNDN);
+ if (strcmp (s, "22183435284042374") || e != 36928)
+ {
+ printf ("Error in mpfr_get_str (48n): s=%s e=%ld\n", s, (long) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDU);
+ if (strcmp (s, "221834352840423736") || e != 36928)
+ {
+ printf ("Error in mpfr_get_str (48u): s=%s e=%ld\n", s, (long) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ s = mpfr_get_str (NULL, &e, 10, 18, x, MPFR_RNDD);
+ if (strcmp (s, "221834352840423735") || e != 36928)
+ {
+ printf ("Error in mpfr_get_str (48d): s=%s e=%ld\n", s, (long) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 45);
+ mpfr_set_str_binary (x, "1E45");
+ s = mpfr_get_str (NULL, &e, 32, 9, x, MPFR_RNDN);
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 7);
+ mpfr_set_str_binary (x, "0.1010101E10");
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
+ mpfr_free_str (s);
+
+ /* checks rounding of negative numbers */
+ mpfr_set_prec (x, 7);
+ mpfr_set_str (x, "-11.5", 10, MPFR_RNDN);
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDD);
+ if (strcmp (s, "-12"))
+ {
+ printf ("Error in mpfr_get_str for x=-11.5 and rnd=MPFR_RNDD\n"
+ "got %s instead of -12\n", s);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDU);
+ if (strcmp (s, "-11"))
+ {
+ printf ("Error in mpfr_get_str for x=-11.5 and rnd=MPFR_RNDU\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ /* bug found by Jean-Pierre Merlet, produced error in mpfr_get_str */
+ mpfr_set_prec (x, 128);
+ mpfr_set_str_binary (x, "0.10111001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011010E3");
+ s = mpfr_get_str (NULL, &e, 10, 0, x, MPFR_RNDU);
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 381);
+ mpfr_set_str_binary (x, "0.111111111111111111111111111111111111111111111111111111111111111111101110110000100110011101101101001010111000101111000100100011110101010110101110100000010100001000110100000100011111001000010010000010001010111001011110000001110010111101100001111000101101100000010110000101100100000101010110010110001010100111001111100011100101100000100100111001100010010011110011011010110000001000010");
+ s = mpfr_get_str (NULL, &e, 10, 0, x, MPFR_RNDD);
+ if (e != 0)
+ {
+ printf ("Error in mpfr_get_str for x=0.999999..., exponent is %d"
+ " instead of 0\n", (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 5);
+ mpfr_set_str_binary (x, "1101.1"); /* 13.5, or (16)_7 + 1/2 */
+ s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
+ /* we are in the tie case: both surrounding numbers are (16)_7 and
+ (20)_7: since (16)_7 = 13 is odd and (20)_7 = 14 is even,
+ we should have s = "20" and e = 2 */
+ if (e != 2 || strcmp (s, "20"))
+ {
+ printf ("Error in mpfr_get_str for x=13.5, base 7\n");
+ printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, (long) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ /* try the same example, with input just below or above 13.5 */
+ mpfr_set_prec (x, 1000);
+ mpfr_set_str_binary (x, "1101.1");
+ mpfr_nextabove (x);
+ s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
+ if (e != 2 || strcmp (s, "20"))
+ {
+ printf ("Error in mpfr_get_str for x=13.5+tiny, base 7\n");
+ printf ("Expected s=20, e=2, got s=%s, e=%ld\n", s, (long) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "1101.1");
+ mpfr_nextbelow (x);
+ s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
+ if (e != 2 || strcmp (s, "16"))
+ {
+ printf ("Error in mpfr_get_str for x=13.5-tiny, base 7\n");
+ printf ("Expected s=16, e=2, got s=%s, e=%ld\n", s, (long) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_prec (x, 7);
+ mpfr_set_str_binary (x, "110000.1"); /* 48.5, or (66)_7 + 1/2 */
+ s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
+ /* we are in the tie case: both surrounding numbers are (66)_7 and
+ (100)_7: since (66)_7 = 48 is even and (100)_7 is odd,
+ we should hase s = "66" and e = 2 */
+ if (e != 2 || strcmp (s, "66"))
+ {
+ printf ("Error in mpfr_get_str for x=48.5, base 7\n");
+ printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, (long) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ /* try the same example, with input just below or above 48.5 */
+ mpfr_set_prec (x, 1000);
+ mpfr_set_str_binary (x, "110000.1");
+ mpfr_nextabove (x);
+ s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
+ if (e != 3 || strcmp (s, "10"))
+ {
+ printf ("Error in mpfr_get_str for x=48.5+tiny, base 7\n");
+ printf ("Expected s=10, e=3, got s=%s, e=%ld\n", s, (long) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_set_str_binary (x, "110000.1");
+ mpfr_nextbelow (x);
+ s = mpfr_get_str (NULL, &e, 7, 2, x, MPFR_RNDN);
+ if (e != 2 || strcmp (s, "66"))
+ {
+ printf ("Error in mpfr_get_str for x=48.5-tiny, base 7\n");
+ printf ("Expected s=66, e=2, got s=%s, e=%ld\n", s, (long) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_clear (x);
+}
+
+/* bugs found by Alain Delplanque */
+static void
+check_large (void)
+{
+ mpfr_t x;
+ char *s, s1[7];
+ const char xm[] = { '1', '1', '9', '1', '3', '2', '9', '3', '7', '3',
+ '5', '8', '4', '4', '5', '4', '9', '0', '2', '9',
+ '6', '3', '4', '4', '6', '9', '9', '1', '9', '5',
+ '5', '7', '2', '0', '1', '7', '5', '2', '8', '6',
+ '1', '2', '5', '2', '5', '2', '7', '4', '0', '2',
+ '7', '9', '1', '1', '7', '4', '5', '6', '7', '5',
+ '9', '3', '1', '4', '2', '5', '5', '6', '6', '6',
+ '1', '6', '4', '3', '8', '1', '2', '8', '7', '6',
+ '2', '9', '2', '0', '8', '8', '9', '4', '3', '9',
+ '6', '2', '8', '4', '1', '1', '8', '1', '0', '6',
+ '2', '3', '7', '6', '3', '8', '1', '5', '1', '7',
+ '3', '4', '6', '1', '2', '4', '0', '1', '3', '0',
+ '8', '4', '1', '3', '9', '3', '2', '0', '1', '6',
+ '3', '6', '7', '1', '5', '1', '7', '5', '0', '1',
+ '9', '8', '4', '0', '8', '2', '7', '9', '1', '3',
+ '2', '2', '8', '3', '4', '1', '6', '2', '3', '9',
+ '6', '2', '0', '7', '3', '5', '5', '5', '3', '4',
+ '2', '1', '7', '0', '9', '7', '6', '2', '1', '0',
+ '3', '3', '5', '4', '7', '6', '0', '9', '7', '6',
+ '9', '3', '5', '1', '7', '8', '6', '8', '8', '2',
+ '8', '1', '4', '3', '7', '4', '3', '3', '2', '4',
+ '1', '5', '4', '7', '8', '1', '1', '4', '2', '1',
+ '2', '4', '2', '7', '6', '5', '9', '5', '4', '5',
+ '2', '6', '7', '3', '0', '3', '4', '0', '6', '9',
+ '1', '8', '9', '9', '9', '8', '0', '5', '7', '0',
+ '9', '3', '8', '7', '6', '2', '4', '6', '1', '6',
+ '7', '2', '0', '3', '5', '9', '3', '5', '8', '8',
+ '9', '7', '7', '9', '2', '7', '0', '8', '1', '6',
+ '8', '7', '4', '8', '5', '3', '0', '8', '4', '3',
+ '5', '6', '5', '1', '6', '6', '0', '9', '7', '9',
+ '8', '9', '2', '7', '2', '6', '8', '5', '9', '4',
+ '5', '8', '1', '3', '7', '2', '9', '3', '8', '3',
+ '7', '9', '1', '7', '9', '9', '7', '7', '2', '8',
+ '4', '6', '5', '5', '7', '3', '3', '8', '3', '6',
+ '6', '9', '7', '1', '4', '3', '3', '7', '1', '4',
+ '9', '4', '1', '2', '4', '9', '5', '1', '4', '7',
+ '2', '6', '4', '4', '8', '0', '6', '2', '6', '0',
+ '6', '9', '8', '1', '1', '7', '9', '9', '3', '9',
+ '3', '8', '4', '7', '3', '1', '9', '0', '2', '3',
+ '5', '3', '5', '4', '2', '1', '1', '7', '6', '7',
+ '4', '3', '2', '2', '0', '6', '5', '9', '9', '3',
+ '2', '6', '7', '1', '2', '0', '0', '3', '7', '3',
+ '8', '7', '4', '3', '3', '3', '3', '3', '2', '3',
+ '8', '2', '8', '6', '3', '1', '5', '5', '2', '2',
+ '5', '9', '3', '3', '7', '0', '6', '2', '8', '1',
+ '0', '3', '6', '7', '6', '9', '6', '5', '9', '0',
+ '6', '6', '6', '3', '6', '9', '9', '3', '8', '7',
+ '6', '5', '4', '5', '3', '5', '9', '4', '0', '0',
+ '7', '5', '8', '5', '4', '1', '4', '3', '1', '5',
+ '7', '6', '6', '3', '4', '4', '5', '0', '8', '7',
+ '5', '7', '5', '0', '1', '0', '1', '8', '4', '7',
+ '3', '1', '9', '9', '2', '7', '1', '1', '1', '2',
+ '3', '9', '9', '6', '5', '9', '2', '3', '2', '8',
+ '1', '5', '5', '1', '2', '6', '4', '9', '6', '6',
+ '4', '5', '1', '1', '6', '0', '0', '3', '2', '8',
+ '4', '8', '7', '1', '4', '9', '6', '8', '1', '6',
+ '5', '9', '8', '3', '4', '2', '9', '7', '0', '1',
+ '9', '2', '6', '6', '9', '1', '3', '5', '9', '3',
+ '2', '9', '6', '2', '3', '0', '6', '0', '1', '1',
+ '6', '5', '1', '7', '9', '0', '7', '5', '8', '6',
+ '8', '4', '2', '1', '0', '3', '8', '6', '6', '4',
+ '4', '9', '9', '7', '5', '8', '1', '7', '5', '7',
+ '9', '6', '6', '8', '8', '5', '8', '6', '7', '4',
+ '0', '7', '2', '0', '2', '9', '9', '4', '4', '1',
+ '9', '5', '8', '6', '5', '0', '6', '7', '4', '2',
+ '7', '3', '2', '3', '2', '7', '0', '2', '1', '3',
+ '0', '5', '9', '0', '3', '9', '1', '4', '5', '3',
+ '7', '2', '7', '0', '8', '5', '5', '4', '6', '1',
+ '1', '0', '0', '9', '2', '0', '4', '1', '6', '6',
+ '4', '6', '9', '1', '3', '2', '8', '5', '0', '3',
+ '3', '8', '9', '8', '7', '8', '5', '9', '5', '5',
+ '9', '1', '9', '3', '6', '5', '4', '1', '7', '4',
+ '0', '2', '4', '7', '2', '9', '7', '1', '2', '4',
+ '5', '8', '1', '4', '4', '6', '1', '8', '5', '8',
+ '7', '6', '9', '7', '2', '1', '2', '0', '8', '9',
+ '5', '9', '5', '5', '3', '8', '1', '2', '5', '4',
+ '3', '0', '7', '6', '5', '1', '7', '8', '2', '0',
+ '0', '7', '6', '7', '4', '8', '1', '0', '6', '3',
+ '2', '3', '0', '5', '2', '5', '0', '1', '1', '4',
+ '3', '8', '4', '5', '2', '3', '9', '5', '0', '9',
+ '8', '2', '6', '4', '7', '4', '8', '0', '1', '1',
+ '7', '1', '5', '4', '9', '0', '9', '2', '2', '3',
+ '8', '1', '6', '9', '0', '4', '6', '4', '5', '4',
+ '6', '3', '8', '7', '3', '6', '1', '7', '2', '3',
+ '4', '5', '5', '2', '0', '2', '5', '8', '1', '4',
+ '9', '3', '0', '7', '4', '1', '6', '8', '7', '8',
+ '2', '6', '2', '5', '1', '0', '7', '4', '7', '3',
+ '6', '6', '4', '5', '6', '6', '6', '6', '8', '5',
+ '1', '3', '5', '7', '1', '6', '2', '0', '9', '2',
+ '3', '2', '6', '0', '7', '9', '8', '1', '6', '2',
+ '0', '3', '8', '8', '0', '2', '8', '7', '7', '5',
+ '9', '3', '1', '0', '6', '7', '5', '7', '3', '1',
+ '2', '7', '7', '2', '0', '0', '4', '1', '2', '8',
+ '2', '0', '8', '4', '0', '5', '0', '5', '0', '1',
+ '9', '3', '3', '6', '3', '6', '9', '6', '2', '8',
+ '2', '9', '7', '5', '3', '8', '8', '9', '1', '1',
+ '4', '5', '7', '7', '5', '6', '0', '2', '7', '9',
+ '7', '2', '1', '7', '4', '3', '0', '3', '6', '7',
+ '3', '7', '2', '2', '7', '5', '6', '2', '3', '1',
+ '2', '1', '3', '1', '4', '2', '6', '9', '2', '3',
+ '\0' };
+ mpfr_exp_t e;
+
+ mpfr_init2 (x, 3322);
+ mpfr_set_str (x, xm, 10, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 4343, MPFR_RNDN);
+ s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN);
+ if (s[999] != '1') /* s must be 5.04383...689071e-309 */
+ {
+ printf ("Error in check_large: expected '689071', got '%s'\n",
+ s + 994);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_mul_2exp (x, x, 4343, MPFR_RNDN);
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN);
+ if (strcmp (s, "12") || (e != 1000))
+ {
+ printf ("Error in check_large: expected 0.12e1000\n");
+ printf ("got %se%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_set_nan (x);
+ s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN);
+ if (strcmp (s, "@NaN@"))
+ {
+ printf ("Error for NaN\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_get_str (s1, &e, 10, 1000, x, MPFR_RNDN);
+
+ mpfr_set_inf (x, 1);
+ s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN);
+ if (strcmp (s, "@Inf@"))
+ {
+ printf ("Error for Inf\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_get_str (s1, &e, 10, 1000, x, MPFR_RNDN);
+
+ mpfr_set_inf (x, -1);
+ s = mpfr_get_str (NULL, &e, 10, 1000, x, MPFR_RNDN);
+ if (strcmp (s, "-@Inf@"))
+ {
+ printf ("Error for -Inf\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+
+ mpfr_get_str (s1, &e, 10, 1000, x, MPFR_RNDN);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN);
+ if (e != 0 || strcmp (s, "00"))
+ {
+ printf ("Error for 0.0\n");
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_get_str (s1, &e, 10, 2, x, MPFR_RNDN);
+
+ mpfr_neg (x, x, MPFR_RNDN); /* -0.0 */
+ s = mpfr_get_str (NULL, &e, 10, 2, x, MPFR_RNDN);
+ if (e != 0 || strcmp (s, "-00"))
+ {
+ printf ("Error for -0.0\ngot %se%d\n", s, (int) e);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_get_str (s1, &e, 10, 2, x, MPFR_RNDN);
+
+ mpfr_clear (x);
+}
+
+#define MAX_DIGITS 100
+
+static void
+check_special (int b, mpfr_prec_t p)
+{
+ mpfr_t x;
+ int i, j;
+ char s[MAX_DIGITS + 2], s2[MAX_DIGITS + 2], c;
+ mpfr_exp_t e;
+ int r;
+ size_t m;
+
+ /* check for invalid base */
+ if (mpfr_get_str (s, &e, 1, 10, x, MPFR_RNDN) != NULL)
+ {
+ printf ("Error: mpfr_get_str should not accept base = 1\n");
+ exit (1);
+ }
+ if (mpfr_get_str (s, &e, 63, 10, x, MPFR_RNDN) != NULL)
+ {
+ printf ("Error: mpfr_get_str should not accept base = 63\n");
+ exit (1);
+ }
+
+ s2[0] = '1';
+ for (i=1; i<MAX_DIGITS+2; i++)
+ s2[i] = '0';
+
+ mpfr_init2 (x, p);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ for (i=1; i<MAX_DIGITS && mpfr_mul_ui (x, x, b, MPFR_RNDN) == 0; i++)
+ {
+ /* x = b^i (exact) */
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ for (m= (i<3)? 2 : i-1 ; (int) m <= i+1 ; m++)
+ {
+ mpfr_get_str (s, &e, b, m, x, (mpfr_rnd_t) r);
+ /* s should be 1 followed by (m-1) zeros, and e should be i+1 */
+ if ((e != i+1) || strncmp (s, s2, m) != 0)
+ {
+ printf ("Error in mpfr_get_str for %d^%d\n", b, i);
+ exit (1);
+ }
+ }
+ if (mpfr_sub_ui (x, x, 1, MPFR_RNDN) != 0)
+ break;
+ /* now x = b^i-1 (exact) */
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ if (i >= 2)
+ {
+ mpfr_get_str (s, &e, b, i, x, (mpfr_rnd_t) r);
+ /* should be i times (b-1) */
+ c = (b <= 10) ? '0' + b - 1 : 'a' + (b - 11);
+ for (j=0; (j < i) && (s[j] == c); j++);
+ if ((j < i) || (e != i))
+ {
+ printf ("Error in mpfr_get_str for %d^%d-1\n", b, i);
+ printf ("got 0.%s*2^%d\n", s, (int) e);
+ exit (1);
+ }
+ }
+ if (i >= 3)
+ {
+ mpfr_get_str (s, &e, b, i - 1, x, MPFR_RNDU);
+ /* should be b^i */
+ if ((e != i+1) || strncmp (s, s2, i - 1) != 0)
+ {
+ printf ("Error in mpfr_get_str for %d^%d-1\n", b, i);
+ printf ("got 0.%s*2^%d\n", s, (int) e);
+ exit (1);
+ }
+ }
+
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ }
+ mpfr_clear (x);
+}
+
+static void
+check_bug_base2k (void)
+{
+ /*
+ * -2.63b22b55697e800000000000@130
+ * +-0.1001100011101100100010101101010101011010010111111010000000000000000000000000+00000000000000000000001E522
+ */
+ mpfr_t xx, yy, zz;
+ char *s;
+ mpfr_exp_t e;
+
+ mpfr_init2 (xx, 107);
+ mpfr_init2 (yy, 79);
+ mpfr_init2 (zz, 99);
+
+ mpfr_set_str (xx, "-1.90e8c3e525d7c0000000000000@-18", 16, MPFR_RNDN);
+ mpfr_set_str (yy, "-2.63b22b55697e8000000@130", 16, MPFR_RNDN);
+ mpfr_add (zz, xx, yy, MPFR_RNDD);
+ s = mpfr_get_str (NULL, &e, 16, 0, zz, MPFR_RNDN);
+ if (strcmp (s, "-263b22b55697e8000000000008"))
+ {
+ printf ("Error for get_str base 16\n"
+ "Got %s expected -263b22b55697e8000000000008\n", s);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_clears (xx, yy, zz, (mpfr_ptr) 0);
+}
+
+static void
+check_reduced_exprange (void)
+{
+ mpfr_t x;
+ char *s;
+ mpfr_exp_t emax, e;
+
+ emax = mpfr_get_emax ();
+ mpfr_init2 (x, 8);
+ mpfr_set_str (x, "0.11111111E0", 2, MPFR_RNDN);
+ set_emax (0);
+ s = mpfr_get_str (NULL, &e, 16, 0, x, MPFR_RNDN);
+ set_emax (emax);
+ if (strcmp (s, "ff0"))
+ {
+ printf ("Error for mpfr_get_str on 0.11111111E0 in base 16:\n"
+ "Got \"%s\" instead of \"ff0\".\n", s);
+ exit (1);
+ }
+ mpfr_free_str (s);
+ mpfr_clear (x);
+}
+
+#define ITER 1000
+
+int
+main (int argc, char *argv[])
+{
+ int b;
+ mpfr_t x;
+ mpfr_rnd_t r;
+ char s[MAX_DIGITS + 2];
+ mpfr_exp_t e, f;
+ size_t m;
+ mpfr_prec_t p;
+ int i;
+
+ tests_start_mpfr ();
+
+ check_small ();
+
+ check_special (2, 2);
+ for (i = 0; i < ITER; i++)
+ {
+ p = 2 + (randlimb () % (MAX_DIGITS - 1));
+ b = 2 + (randlimb () % 35);
+ check_special (b, p);
+ }
+
+ mpfr_init2 (x, MAX_DIGITS);
+ for (i = 0; i < ITER; i++)
+ {
+ m = 2 + (randlimb () % (MAX_DIGITS - 1));
+ mpfr_urandomb (x, RANDS);
+ e = (mpfr_exp_t) (randlimb () % 21) - 10;
+ mpfr_set_exp (x, (e == -10) ? mpfr_get_emin () :
+ ((e == 10) ? mpfr_get_emax () : e));
+ b = 2 + (randlimb () % 35);
+ r = RND_RAND ();
+ mpfr_get_str (s, &f, b, m, x, r);
+ }
+ mpfr_clear (x);
+
+ check_large ();
+ check3 ("4.059650008e-83", MPFR_RNDN, "40597");
+ check3 ("-6.606499965302424244461355e233", MPFR_RNDN, "-66065");
+ check3 ("-7.4", MPFR_RNDN, "-74000");
+ check3 ("0.997", MPFR_RNDN, "99700");
+ check3 ("-4.53063926135729747564e-308", MPFR_RNDN, "-45306");
+ check3 ("2.14478198760196000000e+16", MPFR_RNDN, "21448");
+ check3 ("7.02293374921793516813e-84", MPFR_RNDN, "70229");
+
+ check3 ("-6.7274500420134077e-87", MPFR_RNDN, "-67275");
+ check3 ("-6.7274500420134077e-87", MPFR_RNDZ, "-67274");
+ check3 ("-6.7274500420134077e-87", MPFR_RNDU, "-67274");
+ check3 ("-6.7274500420134077e-87", MPFR_RNDD, "-67275");
+ check3 ("-6.7274500420134077e-87", MPFR_RNDA, "-67275");
+
+ check3 ("6.7274500420134077e-87", MPFR_RNDN, "67275");
+ check3 ("6.7274500420134077e-87", MPFR_RNDZ, "67274");
+ check3 ("6.7274500420134077e-87", MPFR_RNDU, "67275");
+ check3 ("6.7274500420134077e-87", MPFR_RNDD, "67274");
+ check3 ("6.7274500420134077e-87", MPFR_RNDA, "67275");
+
+ check_bug_base2k ();
+ check_reduced_exprange ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tget_z.c b/mpfr/tests/tget_z.c
new file mode 100644
index 0000000000..f21f125151
--- /dev/null
+++ b/mpfr/tests/tget_z.c
@@ -0,0 +1,201 @@
+/* Test file for mpz_set_fr / mpfr_get_z.
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+check_diff (void)
+{
+ int inex;
+ mpfr_t x;
+ mpz_t z;
+ mpfr_exp_t emin;
+
+ mpz_init (z);
+ mpfr_init2 (x, 2);
+
+ mpfr_set_ui (x, 2047, MPFR_RNDU);
+ mpz_set_fr (z, x, MPFR_RNDN);
+ if (mpz_cmp_ui (z, 2048) != 0)
+ {
+ printf ("get_z RU 2048 failed\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 6);
+ mpfr_set_str (x, "17.5", 10, MPFR_RNDN);
+ inex = mpfr_get_z (z, x, MPFR_RNDN);
+ if (inex <= 0 || mpz_cmp_ui (z, 18) != 0)
+ {
+ printf ("get_z RN 17.5 failed\n");
+ exit (1);
+ }
+
+ /* save default emin */
+ emin = mpfr_get_emin ();;
+
+ mpfr_set_emin (17);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inex = mpfr_get_z (z, x, MPFR_RNDN);
+ if (inex != 0 || mpz_cmp_ui (z, 0) != 0)
+ {
+ printf ("get_z 0 failed\n");
+ exit (1);
+ }
+
+ /* restore default emin */
+ mpfr_set_emin (emin);
+
+ mpfr_clear (x);
+ mpz_clear (z);
+}
+
+static void
+check_one (mpz_ptr z)
+{
+ int inex;
+ int sh, neg;
+ mpfr_t f;
+ mpz_t got;
+
+ mpfr_init2 (f, MAX( mpz_sizeinbase (z, 2), MPFR_PREC_MIN) );
+ mpz_init (got);
+
+ for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++)
+ {
+ for (neg = 0; neg <= 1; neg++)
+ {
+ mpz_neg (z, z);
+ mpfr_set_z (f, z, MPFR_RNDN);
+
+ if (sh < 0)
+ {
+ mpz_tdiv_q_2exp (z, z, -sh);
+ mpfr_div_2exp (f, f, -sh, MPFR_RNDN);
+ }
+ else
+ {
+ mpz_mul_2exp (z, z, sh);
+ mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
+ }
+
+ inex = mpfr_get_z (got, f, MPFR_RNDZ);
+
+ if (mpz_cmp (got, z) != 0)
+ {
+ printf ("Wrong result for shift=%d\n", sh);
+ printf (" f "); mpfr_dump (f);
+ printf (" got "); mpz_dump (got);
+ printf (" want "); mpz_dump (z);
+ exit (1);
+ }
+ if (! SAME_SIGN (inex, - mpfr_cmp_z (f, z)))
+ {
+ printf ("Wrong inexact value for shift=%d\n", sh);
+ printf (" f "); mpfr_dump (f);
+ printf (" got %+d\n", inex);
+ printf (" want %+d\n", -mpfr_cmp_z (f, z));
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_clear (f);
+ mpz_clear (got);
+}
+
+static void
+check (void)
+{
+ mpz_t z;
+
+ mpz_init (z);
+
+ mpz_set_ui (z, 0L);
+ check_one (z);
+
+ mpz_set_si (z, 123L);
+ check_one (z);
+
+ mpz_rrandomb (z, RANDS, 2*GMP_NUMB_BITS);
+ check_one (z);
+
+ mpz_rrandomb (z, RANDS, 5*GMP_NUMB_BITS);
+ check_one (z);
+
+ mpz_clear (z);
+}
+
+static void
+special (void)
+{
+ int inex;
+ mpfr_t x;
+ mpz_t z;
+ int i;
+ mpfr_exp_t e;
+
+ mpfr_init2 (x, 2);
+ mpz_init (z);
+
+ for (i = -1; i <= 1; i++)
+ {
+ if (i != 0)
+ mpfr_set_nan (x);
+ else
+ mpfr_set_inf (x, i);
+ mpfr_clear_flags ();
+ inex = mpfr_get_z (z, x, MPFR_RNDN);
+ if (!mpfr_erangeflag_p () || inex != 0 || mpz_cmp_ui (z, 0) != 0)
+ {
+ printf ("special() failed on mpfr_get_z for i = %d\n", i);
+ exit (1);
+ }
+ mpfr_clear_flags ();
+ e = mpfr_get_z_2exp (z, x);
+ if (!mpfr_erangeflag_p () || e != __gmpfr_emin ||
+ mpz_cmp_ui (z, 0) != 0)
+ {
+ printf ("special() failed on mpfr_get_z_2exp for i = %d\n", i);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+ mpz_clear (z);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+
+ check ();
+ check_diff ();
+ special ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tgmpop.c b/mpfr/tests/tgmpop.c
new file mode 100644
index 0000000000..56e9cdc9d8
--- /dev/null
+++ b/mpfr/tests/tgmpop.c
@@ -0,0 +1,1265 @@
+/* Test file for mpfr_add_[q,z], mpfr_sub_[q,z], mpfr_div_[q,z],
+ mpfr_mul_[q,z], mpfr_cmp_[f,q,z]
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpfr-test.h"
+
+#define CHECK_FOR(str, cond) \
+ if ((cond) == 0) { \
+ printf ("Special case error %s. Ternary value = %d, flags = %u\n", \
+ str, res, __gmpfr_flags); \
+ printf ("Got "); mpfr_dump (y); \
+ printf ("X = "); mpfr_dump (x); \
+ printf ("Q = "); mpz_dump (mpq_numref(q)); \
+ printf (" /"); mpz_dump (mpq_denref(q)); \
+ exit (1); \
+ }
+
+#define CHECK_FORZ(str, cond) \
+ if ((cond) == 0) { \
+ printf ("Special case error %s. Ternary value = %d, flags = %u\n", \
+ str, res, __gmpfr_flags); \
+ printf ("Got "); mpfr_dump (y); \
+ printf ("X = "); mpfr_dump (x); \
+ printf ("Z = "); mpz_dump (z); \
+ exit (1); \
+ }
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ mpq_t q;
+ mpz_t z;
+ int res = 0;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpq_init (q);
+ mpz_init (z);
+
+ /* cancellation in mpfr_add_q */
+ mpfr_set_prec (x, 60);
+ mpfr_set_prec (y, 20);
+ mpz_set_str (mpq_numref (q), "-187207494", 10);
+ mpz_set_str (mpq_denref (q), "5721", 10);
+ mpfr_set_str_binary (x, "11111111101001011011100101100011011110010011100010000100001E-44");
+ mpfr_add_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("cancelation in add_q", mpfr_cmp_ui_2exp (y, 256783, -64) == 0);
+
+ mpfr_set_prec (x, 19);
+ mpfr_set_str_binary (x, "0.1011110101110011100E0");
+ mpz_set_str (mpq_numref (q), "187207494", 10);
+ mpz_set_str (mpq_denref (q), "5721", 10);
+ mpfr_set_prec (y, 29);
+ mpfr_add_q (y, x, q, MPFR_RNDD);
+ mpfr_set_prec (x, 29);
+ mpfr_set_str_binary (x, "11111111101001110011010001001E-14");
+ CHECK_FOR ("cancelation in add_q", mpfr_cmp (x,y) == 0);
+
+ /* Inf */
+ mpfr_set_inf (x, 1);
+ mpz_set_str (mpq_numref (q), "395877315", 10);
+ mpz_set_str (mpq_denref (q), "3508975966", 10);
+ mpfr_set_prec (y, 118);
+ mpfr_add_q (y, x, q, MPFR_RNDU);
+ CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0);
+ mpfr_sub_q (y, x, q, MPFR_RNDU);
+ CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0);
+
+ /* Nan */
+ MPFR_SET_NAN (x);
+ mpfr_add_q (y, x, q, MPFR_RNDU);
+ CHECK_FOR ("nan", mpfr_nan_p (y));
+ mpfr_sub_q (y, x, q, MPFR_RNDU);
+ CHECK_FOR ("nan", mpfr_nan_p (y));
+
+ /* Exact value */
+ mpfr_set_prec (x, 60);
+ mpfr_set_prec (y, 60);
+ mpfr_set_str1 (x, "0.5");
+ mpz_set_str (mpq_numref (q), "3", 10);
+ mpz_set_str (mpq_denref (q), "2", 10);
+ res = mpfr_add_q (y, x, q, MPFR_RNDU);
+ CHECK_FOR ("0.5+3/2", mpfr_cmp_ui(y, 2)==0 && res==0);
+ res = mpfr_sub_q (y, x, q, MPFR_RNDU);
+ CHECK_FOR ("0.5-3/2", mpfr_cmp_si(y, -1)==0 && res==0);
+
+ /* Inf Rationnal */
+ mpq_set_ui (q, 1, 0);
+ mpfr_set_str1 (x, "0.5");
+ res = mpfr_add_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("0.5+1/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
+ res = mpfr_sub_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("0.5-1/0", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
+ mpq_set_si (q, -1, 0);
+ res = mpfr_add_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("0.5+ -1/0", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
+ res = mpfr_sub_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("0.5- -1/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
+ res = mpfr_div_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("0.5 / (-1/0)", mpfr_zero_p (y) && MPFR_SIGN (y) < 0 && res == 0);
+ mpq_set_ui (q, 1, 0);
+ mpfr_set_inf (x, 1);
+ res = mpfr_add_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("+Inf + +Inf", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
+ res = mpfr_sub_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("+Inf - +Inf", MPFR_IS_NAN (y) && res == 0);
+ mpfr_set_inf (x, -1);
+ res = mpfr_add_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("-Inf + +Inf", MPFR_IS_NAN (y) && res == 0);
+ res = mpfr_sub_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("-Inf - +Inf", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
+ mpq_set_si (q, -1, 0);
+ mpfr_set_inf (x, 1);
+ res = mpfr_add_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("+Inf + -Inf", MPFR_IS_NAN (y) && res == 0);
+ res = mpfr_sub_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("+Inf - -Inf", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
+ mpfr_set_inf (x, -1);
+ res = mpfr_add_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("-Inf + -Inf", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
+ res = mpfr_sub_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("-Inf - -Inf", MPFR_IS_NAN (y) && res == 0);
+
+ /* 0 */
+ mpq_set_ui (q, 0, 1);
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ res = mpfr_add_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("42+0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0);
+ res = mpfr_sub_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("42-0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0);
+ res = mpfr_mul_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("42*0/1", mpfr_zero_p (y) && MPFR_SIGN (y) > 0 && res == 0);
+ mpfr_clear_flags ();
+ res = mpfr_div_q (y, x, q, MPFR_RNDN);
+ CHECK_FOR ("42/(0/1)", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0
+ && mpfr_divby0_p ());
+ mpz_set_ui (z, 0);
+ mpfr_clear_flags ();
+ res = mpfr_div_z (y, x, z, MPFR_RNDN);
+ CHECK_FORZ ("42/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0
+ && mpfr_divby0_p ());
+
+ mpz_clear (z);
+ mpq_clear (q);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+check_for_zero (void)
+{
+ /* Check that 0 is unsigned! */
+ mpq_t q;
+ mpz_t z;
+ mpfr_t x;
+ int r;
+ mpfr_sign_t i;
+
+ mpfr_init (x);
+ mpz_init (z);
+ mpq_init (q);
+
+ mpz_set_ui (z, 0);
+ mpq_set_ui (q, 0, 1);
+
+ MPFR_SET_ZERO (x);
+ RND_LOOP (r)
+ {
+ for (i = MPFR_SIGN_NEG ; i <= MPFR_SIGN_POS ;
+ i+=MPFR_SIGN_POS-MPFR_SIGN_NEG)
+ {
+ MPFR_SET_SIGN(x, i);
+ mpfr_add_z (x, x, z, (mpfr_rnd_t) r);
+ if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
+ {
+ printf("GMP Zero errors for add_z & rnd=%s & s=%d\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_sub_z (x, x, z, (mpfr_rnd_t) r);
+ if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
+ {
+ printf("GMP Zero errors for sub_z & rnd=%s & s=%d\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_mul_z (x, x, z, (mpfr_rnd_t) r);
+ if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
+ {
+ printf("GMP Zero errors for mul_z & rnd=%s & s=%d\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_add_q (x, x, q, (mpfr_rnd_t) r);
+ if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
+ {
+ printf("GMP Zero errors for add_q & rnd=%s & s=%d\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_sub_q (x, x, q, (mpfr_rnd_t) r);
+ if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
+ {
+ printf("GMP Zero errors for sub_q & rnd=%s & s=%d\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
+ mpfr_dump (x);
+ exit (1);
+ }
+ }
+ }
+
+ mpq_clear (q);
+ mpz_clear (z);
+ mpfr_clear (x);
+}
+
+static void
+test_cmp_z (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
+{
+ mpfr_t x, z;
+ mpz_t y;
+ mpfr_prec_t p;
+ int res1, res2;
+ int n;
+
+ mpfr_init (x);
+ mpfr_init2 (z, MPFR_PREC_MIN);
+ mpz_init (y);
+
+ /* check the erange flag when x is NaN */
+ mpfr_set_nan (x);
+ mpz_set_ui (y, 17);
+ mpfr_clear_erangeflag ();
+ res1 = mpfr_cmp_z (x, y);
+ if (res1 != 0 || mpfr_erangeflag_p () == 0)
+ {
+ printf ("Error for mpfr_cmp_z (NaN, 17)\n");
+ printf ("Return value: expected 0, got %d\n", res1);
+ printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
+ exit (1);
+ }
+
+ for(p=pmin ; p < pmax ; p++)
+ {
+ mpfr_set_prec (x, p);
+ for ( n = 0; n < nmax ; n++)
+ {
+ mpfr_urandomb (x, RANDS);
+ mpz_urandomb (y, RANDS, 1024);
+ if (!MPFR_IS_SINGULAR (x))
+ {
+ mpfr_sub_z (z, x, y, MPFR_RNDN);
+ res1 = mpfr_sgn (z);
+ res2 = mpfr_cmp_z (x, y);
+ if (res1 != res2)
+ {
+ printf("Error for mpfr_cmp_z: res=%d sub_z gives %d\n",
+ res2, res1);
+ exit (1);
+ }
+ }
+ }
+ }
+ mpz_clear (y);
+ mpfr_clear (x);
+ mpfr_clear (z);
+}
+
+static void
+test_cmp_q (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
+{
+ mpfr_t x, z;
+ mpq_t y;
+ mpfr_prec_t p;
+ int res1, res2;
+ int n;
+
+ mpfr_init (x);
+ mpfr_init2 (z, MPFR_PREC_MIN);
+ mpq_init (y);
+
+ /* check the erange flag when x is NaN */
+ mpfr_set_nan (x);
+ mpq_set_ui (y, 17, 1);
+ mpfr_clear_erangeflag ();
+ res1 = mpfr_cmp_q (x, y);
+ if (res1 != 0 || mpfr_erangeflag_p () == 0)
+ {
+ printf ("Error for mpfr_cmp_q (NaN, 17)\n");
+ printf ("Return value: expected 0, got %d\n", res1);
+ printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
+ exit (1);
+ }
+
+ for(p=pmin ; p < pmax ; p++)
+ {
+ mpfr_set_prec (x, p);
+ for (n = 0 ; n < nmax ; n++)
+ {
+ mpfr_urandomb (x, RANDS);
+ mpq_set_ui (y, randlimb (), randlimb() );
+ if (!MPFR_IS_SINGULAR (x))
+ {
+ mpfr_sub_q (z, x, y, MPFR_RNDN);
+ res1 = mpfr_sgn (z);
+ res2 = mpfr_cmp_q (x, y);
+ if (res1 != res2)
+ {
+ printf("Error for mpfr_cmp_q: res=%d sub_z gives %d\n",
+ res2, res1);
+ exit (1);
+ }
+ }
+ }
+ }
+ mpq_clear (y);
+ mpfr_clear (x);
+ mpfr_clear (z);
+}
+
+static void
+test_cmp_f (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
+{
+ mpfr_t x, z;
+ mpf_t y;
+ mpfr_prec_t p;
+ int res1, res2;
+ int n;
+
+ mpfr_init (x);
+ mpfr_init2 (z, pmax+GMP_NUMB_BITS);
+ mpf_init2 (y, MPFR_PREC_MIN);
+
+ /* check the erange flag when x is NaN */
+ mpfr_set_nan (x);
+ mpf_set_ui (y, 17);
+ mpfr_clear_erangeflag ();
+ res1 = mpfr_cmp_f (x, y);
+ if (res1 != 0 || mpfr_erangeflag_p () == 0)
+ {
+ printf ("Error for mpfr_cmp_f (NaN, 17)\n");
+ printf ("Return value: expected 0, got %d\n", res1);
+ printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
+ exit (1);
+ }
+
+ for(p=pmin ; p < pmax ; p+=3)
+ {
+ mpfr_set_prec (x, p);
+ mpf_set_prec (y, p);
+ for ( n = 0; n < nmax ; n++)
+ {
+ mpfr_urandomb (x, RANDS);
+ mpf_urandomb (y, RANDS, p);
+ if (!MPFR_IS_SINGULAR (x))
+ {
+ mpfr_set_f (z, y, MPFR_RNDN);
+ mpfr_sub (z, x, z, MPFR_RNDN);
+ res1 = mpfr_sgn (z);
+ res2 = mpfr_cmp_f (x, y);
+ if (res1 != res2)
+ {
+ printf("Error for mpfr_cmp_f: res=%d sub gives %d\n",
+ res2, res1);
+ exit (1);
+ }
+ }
+ }
+ }
+ mpf_clear (y);
+ mpfr_clear (x);
+ mpfr_clear (z);
+}
+
+static void
+test_specialz (int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t),
+ void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr),
+ const char *op)
+{
+ mpfr_t x1, x2;
+ mpz_t z1, z2;
+ int res;
+
+ mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0);
+ mpz_init (z1); mpz_init(z2);
+ mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */
+ mpz_add_ui (z1, z1, 1);
+ mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */
+ mpz_add_ui (z2, z2, 1);
+
+ res = mpfr_set_z(x1, z1, MPFR_RNDN);
+ if (res)
+ {
+ printf("Specialz %s: set_z1 error\n", op);
+ exit(1);
+ }
+ mpfr_set_z (x2, z2, MPFR_RNDN);
+ if (res)
+ {
+ printf("Specialz %s: set_z2 error\n", op);
+ exit(1);
+ }
+
+ /* (19!+1) * (20!+1) fits in a 128 bits number */
+ res = mpfr_func(x1, x1, z2, MPFR_RNDN);
+ if (res)
+ {
+ printf("Specialz %s: wrong inexact flag.\n", op);
+ exit(1);
+ }
+ mpz_func(z1, z1, z2);
+ res = mpfr_set_z (x2, z1, MPFR_RNDN);
+ if (res)
+ {
+ printf("Specialz %s: set_z2 error\n", op);
+ exit(1);
+ }
+ if (mpfr_cmp(x1, x2))
+ {
+ printf("Specialz %s: results differ.\nx1=", op);
+ mpfr_print_binary(x1);
+ printf("\nx2=");
+ mpfr_print_binary(x2);
+ printf ("\nZ2=");
+ mpz_out_str (stdout, 2, z1);
+ putchar('\n');
+ exit(1);
+ }
+
+ mpz_set_ui (z1, 1);
+ mpz_set_ui (z2, 0);
+ mpfr_set_ui (x1, 1, MPFR_RNDN);
+ mpz_func (z1, z1, z2);
+ res = mpfr_func(x1, x1, z2, MPFR_RNDN);
+ mpfr_set_z (x2, z1, MPFR_RNDN);
+ if (mpfr_cmp(x1, x2))
+ {
+ printf("Specialz %s: results differ(2).\nx1=", op);
+ mpfr_print_binary(x1);
+ printf("\nx2=");
+ mpfr_print_binary(x2);
+ putchar('\n');
+ exit(1);
+ }
+
+ mpz_clear (z1); mpz_clear(z2);
+ mpfr_clears (x1, x2, (mpfr_ptr) 0);
+}
+
+static void
+test_special2z (int (*mpfr_func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t),
+ void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr),
+ const char *op)
+{
+ mpfr_t x1, x2;
+ mpz_t z1, z2;
+ int res;
+
+ mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0);
+ mpz_init (z1); mpz_init(z2);
+ mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */
+ mpz_add_ui (z1, z1, 1);
+ mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */
+ mpz_add_ui (z2, z2, 1);
+
+ res = mpfr_set_z(x1, z1, MPFR_RNDN);
+ if (res)
+ {
+ printf("Special2z %s: set_z1 error\n", op);
+ exit(1);
+ }
+ mpfr_set_z (x2, z2, MPFR_RNDN);
+ if (res)
+ {
+ printf("Special2z %s: set_z2 error\n", op);
+ exit(1);
+ }
+
+ /* (19!+1) * (20!+1) fits in a 128 bits number */
+ res = mpfr_func(x1, z1, x2, MPFR_RNDN);
+ if (res)
+ {
+ printf("Special2z %s: wrong inexact flag.\n", op);
+ exit(1);
+ }
+ mpz_func(z1, z1, z2);
+ res = mpfr_set_z (x2, z1, MPFR_RNDN);
+ if (res)
+ {
+ printf("Special2z %s: set_z2 error\n", op);
+ exit(1);
+ }
+ if (mpfr_cmp(x1, x2))
+ {
+ printf("Special2z %s: results differ.\nx1=", op);
+ mpfr_print_binary(x1);
+ printf("\nx2=");
+ mpfr_print_binary(x2);
+ printf ("\nZ2=");
+ mpz_out_str (stdout, 2, z1);
+ putchar('\n');
+ exit(1);
+ }
+
+ mpz_set_ui (z1, 0);
+ mpz_set_ui (z2, 1);
+ mpfr_set_ui (x2, 1, MPFR_RNDN);
+ res = mpfr_func(x1, z1, x2, MPFR_RNDN);
+ mpz_func (z1, z1, z2);
+ mpfr_set_z (x2, z1, MPFR_RNDN);
+ if (mpfr_cmp(x1, x2))
+ {
+ printf("Special2z %s: results differ(2).\nx1=", op);
+ mpfr_print_binary(x1);
+ printf("\nx2=");
+ mpfr_print_binary(x2);
+ putchar('\n');
+ exit(1);
+ }
+
+ mpz_clear (z1); mpz_clear(z2);
+ mpfr_clears (x1, x2, (mpfr_ptr) 0);
+}
+
+static void
+test_genericz (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
+ int (*func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t),
+ const char *op)
+{
+ mpfr_prec_t prec;
+ mpfr_t arg1, dst_big, dst_small, tmp;
+ mpz_t arg2;
+ mpfr_rnd_t rnd;
+ int inexact, compare, compare2;
+ unsigned int n;
+
+ mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
+ mpz_init (arg2);
+
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (arg1, prec);
+ mpfr_set_prec (tmp, prec);
+ mpfr_set_prec (dst_small, prec);
+
+ for (n=0; n<N; n++)
+ {
+ mpfr_urandomb (arg1, RANDS);
+ mpz_urandomb (arg2, RANDS, 1024);
+ rnd = RND_RAND ();
+ mpfr_set_prec (dst_big, 2*prec);
+ compare = func(dst_big, arg1, arg2, rnd);
+ if (mpfr_can_round (dst_big, 2*prec, rnd, rnd, prec))
+ {
+ mpfr_set (tmp, dst_big, rnd);
+ inexact = func(dst_small, arg1, arg2, rnd);
+ if (mpfr_cmp (tmp, dst_small))
+ {
+ printf ("Results differ for prec=%u rnd_mode=%s and %s_z:\n"
+ "arg1=",
+ (unsigned) prec, mpfr_print_rnd_mode (rnd), op);
+ mpfr_print_binary (arg1);
+ printf("\narg2=");
+ mpz_out_str (stdout, 10, arg2);
+ printf ("\ngot ");
+ mpfr_dump (dst_small);
+ printf ("expected ");
+ mpfr_dump (tmp);
+ printf ("approx ");
+ mpfr_dump (dst_big);
+ exit (1);
+ }
+ compare2 = mpfr_cmp (tmp, dst_big);
+ /* if rounding to nearest, cannot know the sign of t - f(x)
+ because of composed rounding: y = o(f(x)) and t = o(y) */
+ if (compare * compare2 >= 0)
+ compare = compare + compare2;
+ else
+ compare = inexact; /* cannot determine sign(t-f(x)) */
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact > 0) && (compare <= 0)) ||
+ ((inexact < 0) && (compare >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s and %s_z:\n"
+ "expected %d, got %d\n",
+ mpfr_print_rnd_mode (rnd), op, compare, inexact);
+ printf ("\narg1="); mpfr_print_binary (arg1);
+ printf ("\narg2="); mpz_out_str(stdout, 2, arg2);
+ printf ("\ndstl="); mpfr_print_binary (dst_big);
+ printf ("\ndsts="); mpfr_print_binary (dst_small);
+ printf ("\ntmp ="); mpfr_dump (tmp);
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpz_clear (arg2);
+ mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
+}
+
+static void
+test_generic2z (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
+ int (*func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t),
+ const char *op)
+{
+ mpfr_prec_t prec;
+ mpfr_t arg1, dst_big, dst_small, tmp;
+ mpz_t arg2;
+ mpfr_rnd_t rnd;
+ int inexact, compare, compare2;
+ unsigned int n;
+
+ mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
+ mpz_init (arg2);
+
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (arg1, prec);
+ mpfr_set_prec (tmp, prec);
+ mpfr_set_prec (dst_small, prec);
+
+ for (n=0; n<N; n++)
+ {
+ mpfr_urandomb (arg1, RANDS);
+ mpz_urandomb (arg2, RANDS, 1024);
+ rnd = RND_RAND ();
+ mpfr_set_prec (dst_big, 2*prec);
+ compare = func(dst_big, arg2, arg1, rnd);
+ if (mpfr_can_round (dst_big, 2*prec, rnd, rnd, prec))
+ {
+ mpfr_set (tmp, dst_big, rnd);
+ inexact = func(dst_small, arg2, arg1, rnd);
+ if (mpfr_cmp (tmp, dst_small))
+ {
+ printf ("Results differ for prec=%u rnd_mode=%s and %s_z:\n"
+ "arg1=",
+ (unsigned) prec, mpfr_print_rnd_mode (rnd), op);
+ mpfr_print_binary (arg1);
+ printf("\narg2=");
+ mpz_out_str (stdout, 10, arg2);
+ printf ("\ngot ");
+ mpfr_dump (dst_small);
+ printf ("expected ");
+ mpfr_dump (tmp);
+ printf ("approx ");
+ mpfr_dump (dst_big);
+ exit (1);
+ }
+ compare2 = mpfr_cmp (tmp, dst_big);
+ /* if rounding to nearest, cannot know the sign of t - f(x)
+ because of composed rounding: y = o(f(x)) and t = o(y) */
+ if (compare * compare2 >= 0)
+ compare = compare + compare2;
+ else
+ compare = inexact; /* cannot determine sign(t-f(x)) */
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact > 0) && (compare <= 0)) ||
+ ((inexact < 0) && (compare >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s and %s_z:\n"
+ "expected %d, got %d\n",
+ mpfr_print_rnd_mode (rnd), op, compare, inexact);
+ printf ("\narg1="); mpfr_print_binary (arg1);
+ printf ("\narg2="); mpz_out_str(stdout, 2, arg2);
+ printf ("\ndstl="); mpfr_print_binary (dst_big);
+ printf ("\ndsts="); mpfr_print_binary (dst_small);
+ printf ("\ntmp ="); mpfr_dump (tmp);
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpz_clear (arg2);
+ mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
+}
+
+static void
+test_genericq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
+ int (*func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t),
+ const char *op)
+{
+ mpfr_prec_t prec;
+ mpfr_t arg1, dst_big, dst_small, tmp;
+ mpq_t arg2;
+ mpfr_rnd_t rnd;
+ int inexact, compare, compare2;
+ unsigned int n;
+
+ mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
+ mpq_init (arg2);
+
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (arg1, prec);
+ mpfr_set_prec (tmp, prec);
+ mpfr_set_prec (dst_small, prec);
+
+ for (n=0; n<N; n++)
+ {
+ mpfr_urandomb (arg1, RANDS);
+ mpq_set_ui (arg2, randlimb (), randlimb() );
+ mpq_canonicalize (arg2);
+ rnd = RND_RAND ();
+ mpfr_set_prec (dst_big, prec+10);
+ compare = func(dst_big, arg1, arg2, rnd);
+ if (mpfr_can_round (dst_big, prec+10, rnd, rnd, prec))
+ {
+ mpfr_set (tmp, dst_big, rnd);
+ inexact = func(dst_small, arg1, arg2, rnd);
+ if (mpfr_cmp (tmp, dst_small))
+ {
+ printf ("Results differ for prec=%u rnd_mode=%s and %s_q:\n"
+ "arg1=",
+ (unsigned) prec, mpfr_print_rnd_mode (rnd), op);
+ mpfr_print_binary (arg1);
+ printf("\narg2=");
+ mpq_out_str(stdout, 2, arg2);
+ printf ("\ngot ");
+ mpfr_print_binary (dst_small);
+ printf ("\nexpected ");
+ mpfr_print_binary (tmp);
+ printf ("\napprox ");
+ mpfr_print_binary (dst_big);
+ putchar('\n');
+ exit (1);
+ }
+ compare2 = mpfr_cmp (tmp, dst_big);
+ /* if rounding to nearest, cannot know the sign of t - f(x)
+ because of composed rounding: y = o(f(x)) and t = o(y) */
+ if (compare * compare2 >= 0)
+ compare = compare + compare2;
+ else
+ compare = inexact; /* cannot determine sign(t-f(x)) */
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact > 0) && (compare <= 0)) ||
+ ((inexact < 0) && (compare >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s and %s_q:\n"
+ "expected %d, got %d",
+ mpfr_print_rnd_mode (rnd), op, compare, inexact);
+ printf ("\narg1="); mpfr_print_binary (arg1);
+ printf ("\narg2="); mpq_out_str(stdout, 2, arg2);
+ printf ("\ndstl="); mpfr_print_binary (dst_big);
+ printf ("\ndsts="); mpfr_print_binary (dst_small);
+ printf ("\ntmp ="); mpfr_print_binary (tmp);
+ putchar('\n');
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpq_clear (arg2);
+ mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
+}
+
+static void
+test_specialq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
+ int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t),
+ void (*mpq_func)(mpq_ptr, mpq_srcptr, mpq_srcptr),
+ const char *op)
+{
+ mpfr_t fra, frb, frq;
+ mpq_t q1, q2, qr;
+ unsigned int n;
+ mpfr_prec_t prec;
+
+ for (prec = p0 ; prec < p1 ; prec++)
+ {
+ mpfr_inits2 (prec, fra, frb, frq, (mpfr_ptr) 0);
+ mpq_init (q1); mpq_init(q2); mpq_init (qr);
+
+ for( n = 0 ; n < N ; n++)
+ {
+ mpq_set_ui(q1, randlimb(), randlimb() );
+ mpq_set_ui(q2, randlimb(), randlimb() );
+ mpq_canonicalize (q1);
+ mpq_canonicalize (q2);
+ mpq_func (qr, q1, q2);
+ mpfr_set_q (fra, q1, MPFR_RNDD);
+ mpfr_func (fra, fra, q2, MPFR_RNDD);
+ mpfr_set_q (frb, q1, MPFR_RNDU);
+ mpfr_func (frb, frb, q2, MPFR_RNDU);
+ mpfr_set_q (frq, qr, MPFR_RNDN);
+ /* We should have fra <= qr <= frb */
+ if ( (mpfr_cmp(fra, frq) > 0) || (mpfr_cmp (frq, frb) > 0))
+ {
+ printf("Range error for prec=%lu and %s",
+ (unsigned long) prec, op);
+ printf ("\nq1="); mpq_out_str(stdout, 2, q1);
+ printf ("\nq2="); mpq_out_str(stdout, 2, q2);
+ printf ("\nfr_dn="); mpfr_print_binary (fra);
+ printf ("\nfr_q ="); mpfr_print_binary (frq);
+ printf ("\nfr_up="); mpfr_print_binary (frb);
+ putchar('\n');
+ exit (1);
+ }
+ }
+
+ mpq_clear (q1); mpq_clear (q2); mpq_clear (qr);
+ mpfr_clears (fra, frb, frq, (mpfr_ptr) 0);
+ }
+}
+
+static void
+bug_mul_q_20100810 (void)
+{
+ mpfr_t x;
+ mpfr_t y;
+ mpq_t q;
+ int inexact;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpq_init (q);
+
+ /* mpfr_mul_q: the inexact value must be set in case of overflow */
+ mpq_set_ui (q, 4096, 3);
+ mpfr_set_inf (x, +1);
+ mpfr_nextbelow (x);
+ inexact = mpfr_mul_q (y, x, q, MPFR_RNDU);
+
+ if (inexact <= 0)
+ {
+ printf ("Overflow error in mpfr_mul_q. ");
+ printf ("Wrong inexact flag: got %d, should be positive.\n", inexact);
+
+ exit (1);
+ }
+ if (!mpfr_inf_p (y))
+ {
+ printf ("Overflow error in mpfr_mul_q (y, x, q, MPFR_RNDD). ");
+ printf ("\nx = ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD);
+ printf ("\nq = ");
+ mpq_out_str (stdout, 10, q);
+ printf ("\ny = ");
+ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD);
+ printf (" (should be +infinity)\n");
+
+ exit (1);
+ }
+
+ mpq_clear (q);
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+static void
+bug_div_q_20100810 (void)
+{
+ mpfr_t x;
+ mpfr_t y;
+ mpq_t q;
+ int inexact;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpq_init (q);
+
+ /* mpfr_div_q: the inexact value must be set in case of overflow */
+ mpq_set_ui (q, 3, 4096);
+ mpfr_set_inf (x, +1);
+ mpfr_nextbelow (x);
+ inexact = mpfr_div_q (y, x, q, MPFR_RNDU);
+
+ if (inexact <= 0)
+ {
+ printf ("Overflow error in mpfr_div_q. ");
+ printf ("Wrong inexact flag: got %d, should be positive.\n", inexact);
+
+ exit (1);
+ }
+ if (!mpfr_inf_p (y))
+ {
+ printf ("Overflow error in mpfr_div_q (y, x, q, MPFR_RNDD). ");
+ printf ("\nx = ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD);
+ printf ("\nq = ");
+ mpq_out_str (stdout, 10, q);
+ printf ("\ny = ");
+ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD);
+ printf (" (should be +infinity)\n");
+
+ exit (1);
+ }
+
+ mpq_clear (q);
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+static void
+bug_mul_div_q_20100818 (void)
+{
+ mpq_t qa, qb;
+ mpfr_t x1, x2, y1, y2, y3;
+ mpfr_exp_t emin, emax, e;
+ int inex;
+ int rnd;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ set_emin (MPFR_EMIN_MIN);
+ set_emax (MPFR_EMAX_MAX);
+
+ mpq_init (qa);
+ mpq_init (qb);
+ mpfr_inits2 (32, x1, x2, y1, y2, y3, (mpfr_ptr) 0);
+
+ mpq_set_ui (qa, 3, 17);
+ mpq_set_ui (qb, 17, 3);
+ inex = mpfr_set_ui (x1, 7, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+
+ e = MPFR_EMAX_MAX - 3;
+ inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN); /* x2 = x1 * 2^e */
+ MPFR_ASSERTN (inex == 0);
+
+ RND_LOOP(rnd)
+ {
+ mpfr_mul_q (y1, x1, qa, (mpfr_rnd_t) rnd);
+ mpfr_div_q (y3, x1, qb, (mpfr_rnd_t) rnd);
+ MPFR_ASSERTN (mpfr_equal_p (y1, y3));
+ inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ inex = mpfr_mul (y3, y3, y1, MPFR_RNDN); /* y3 = y1 * 2^e */
+ MPFR_ASSERTN (inex == 0);
+ mpfr_mul_q (y2, x2, qa, (mpfr_rnd_t) rnd);
+ if (! mpfr_equal_p (y2, y3))
+ {
+ printf ("Error 1 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
+ printf ("Expected "); mpfr_dump (y3);
+ printf ("Got "); mpfr_dump (y2);
+ exit (1);
+ }
+ mpfr_div_q (y2, x2, qb, (mpfr_rnd_t) rnd);
+ if (! mpfr_equal_p (y2, y3))
+ {
+ printf ("Error 2 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
+ printf ("Expected "); mpfr_dump (y3);
+ printf ("Got "); mpfr_dump (y2);
+ exit (1);
+ }
+ }
+
+ e = MPFR_EMIN_MIN;
+ inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN); /* x2 = x1 * 2^e */
+ MPFR_ASSERTN (inex == 0);
+
+ RND_LOOP(rnd)
+ {
+ mpfr_div_q (y1, x1, qa, (mpfr_rnd_t) rnd);
+ mpfr_mul_q (y3, x1, qb, (mpfr_rnd_t) rnd);
+ MPFR_ASSERTN (mpfr_equal_p (y1, y3));
+ inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ inex = mpfr_mul (y3, y3, y1, MPFR_RNDN); /* y3 = y1 * 2^e */
+ MPFR_ASSERTN (inex == 0);
+ mpfr_div_q (y2, x2, qa, (mpfr_rnd_t) rnd);
+ if (! mpfr_equal_p (y2, y3))
+ {
+ printf ("Error 3 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
+ printf ("Expected "); mpfr_dump (y3);
+ printf ("Got "); mpfr_dump (y2);
+ exit (1);
+ }
+ mpfr_mul_q (y2, x2, qb, (mpfr_rnd_t) rnd);
+ if (! mpfr_equal_p (y2, y3))
+ {
+ printf ("Error 4 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
+ printf ("Expected "); mpfr_dump (y3);
+ printf ("Got "); mpfr_dump (y2);
+ exit (1);
+ }
+ }
+
+ mpq_clear (qa);
+ mpq_clear (qb);
+ mpfr_clears (x1, x2, y1, y2, y3, (mpfr_ptr) 0);
+
+ set_emin (emin);
+ set_emax (emax);
+}
+
+static void
+reduced_expo_range (void)
+{
+ mpfr_t x;
+ mpz_t z;
+ mpq_t q;
+ mpfr_exp_t emin;
+ int inex;
+
+ emin = mpfr_get_emin ();
+ set_emin (4);
+
+ mpfr_init2 (x, 32);
+
+ mpz_init (z);
+ mpfr_clear_flags ();
+ inex = mpfr_set_ui (x, 17, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ mpz_set_ui (z, 3);
+ inex = mpfr_mul_z (x, x, z, MPFR_RNDN);
+ if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 51) != 0)
+ {
+ printf ("Error 1 in reduce_expo_range: expected 51 with inex = 0,"
+ " got\n");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("with inex = %d\n", inex);
+ exit (1);
+ }
+ inex = mpfr_div_z (x, x, z, MPFR_RNDN);
+ if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0)
+ {
+ printf ("Error 2 in reduce_expo_range: expected 17 with inex = 0,"
+ " got\n");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("with inex = %d\n", inex);
+ exit (1);
+ }
+ inex = mpfr_add_z (x, x, z, MPFR_RNDN);
+ if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 20) != 0)
+ {
+ printf ("Error 3 in reduce_expo_range: expected 20 with inex = 0,"
+ " got\n");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("with inex = %d\n", inex);
+ exit (1);
+ }
+ inex = mpfr_sub_z (x, x, z, MPFR_RNDN);
+ if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0)
+ {
+ printf ("Error 4 in reduce_expo_range: expected 17 with inex = 0,"
+ " got\n");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("with inex = %d\n", inex);
+ exit (1);
+ }
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ if (mpfr_cmp_z (x, z) <= 0)
+ {
+ printf ("Error 5 in reduce_expo_range: expected a positive value.\n");
+ exit (1);
+ }
+ mpz_clear (z);
+
+ mpq_init (q);
+ mpq_set_ui (q, 1, 1);
+ mpfr_set_ui (x, 16, MPFR_RNDN);
+ inex = mpfr_add_q (x, x, q, MPFR_RNDN);
+ if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0)
+ {
+ printf ("Error in reduce_expo_range for 16 + 1/1,"
+ " got inex = %d and\nx = ", inex);
+ mpfr_dump (x);
+ exit (1);
+ }
+ inex = mpfr_sub_q (x, x, q, MPFR_RNDN);
+ if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 16) != 0)
+ {
+ printf ("Error in reduce_expo_range for 17 - 1/1,"
+ " got inex = %d and\nx = ", inex);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpq_clear (q);
+
+ mpfr_clear (x);
+
+ set_emin (emin);
+}
+
+static void
+addsubq_overflow_aux (mpfr_exp_t e)
+{
+ mpfr_t x, y;
+ mpq_t q;
+ mpfr_exp_t emax;
+ int inex;
+ int rnd;
+ int sign, sub;
+
+ MPFR_ASSERTN (e <= LONG_MAX);
+ emax = mpfr_get_emax ();
+ set_emax (e);
+ mpfr_inits2 (16, x, y, (mpfr_ptr) 0);
+ mpq_init (q);
+
+ mpfr_set_inf (x, 1);
+ mpfr_nextbelow (x);
+ mpq_set_ui (q, 1, 1);
+
+ for (sign = 0; sign <= 1; sign++)
+ {
+ for (sub = 0; sub <= 1; sub++)
+ {
+ RND_LOOP(rnd)
+ {
+ unsigned int flags, ex_flags;
+ int inf;
+
+ inf = rnd == MPFR_RNDA ||
+ rnd == (sign ? MPFR_RNDD : MPFR_RNDU);
+ ex_flags = MPFR_FLAGS_INEXACT | (inf ? MPFR_FLAGS_OVERFLOW : 0);
+ mpfr_clear_flags ();
+ inex = sub ?
+ mpfr_sub_q (y, x, q, (mpfr_rnd_t) rnd) :
+ mpfr_add_q (y, x, q, (mpfr_rnd_t) rnd);
+ flags = __gmpfr_flags;
+ if (inex == 0 || flags != ex_flags ||
+ (inf ? ! mpfr_inf_p (y) : ! mpfr_equal_p (x, y)))
+ {
+ printf ("Error in addsubq_overflow_aux(%ld),"
+ " sign = %d, %s\n", (long) e, sign,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("Got inex = %d, y = ", inex);
+ mpfr_dump (y);
+ printf ("Expected flags:");
+ flags_out (ex_flags);
+ printf ("Got flags: ");
+ flags_out (flags);
+ exit (1);
+ }
+ }
+ mpq_neg (q, q);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpq_neg (q, q);
+ }
+
+ mpq_clear (q);
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+ set_emax (emax);
+}
+
+static void
+addsubq_overflow (void)
+{
+ addsubq_overflow_aux (4913);
+ addsubq_overflow_aux (MPFR_EMAX_MAX);
+}
+
+static void
+coverage_mpfr_mul_q_20110218 (void)
+{
+ mpfr_t cmp, res, op1;
+ mpq_t op2;
+ int status;
+
+ mpfr_init2 (cmp, MPFR_PREC_MIN);
+ mpfr_init2 (res, MPFR_PREC_MIN);
+ mpfr_init_set_si (op1, 1, MPFR_RNDN);
+
+ mpq_init (op2);
+ mpq_set_si (op2, 0, 0);
+ mpz_set_si (mpq_denref (op2), 0);
+
+ status = mpfr_mul_q (res, op1, op2, MPFR_RNDN);
+
+ if ((status != 0) || (mpfr_cmp (cmp, res) != 0))
+ {
+ printf ("Results differ %d.\nres=", status);
+ mpfr_print_binary (res);
+ printf ("\ncmp=");
+ mpfr_print_binary (cmp);
+ putchar ('\n');
+ exit (1);
+ }
+
+ mpfr_set_si (op1, 1, MPFR_RNDN);
+ mpq_set_si (op2, -1, 0);
+
+ status = mpfr_mul_q (res, op1, op2, MPFR_RNDN);
+
+ mpfr_set_inf (cmp, -1);
+ if ((status != 0) || (mpfr_cmp(res, cmp) != 0))
+ {
+ printf ("mpfr_mul_q 1 * (-1/0) returned a wrong value :\n waiting for ");
+ mpfr_print_binary (cmp);
+ printf (" got ");
+ mpfr_print_binary (res);
+ printf ("\n trinary value is %d\n", status);
+ exit (1);
+ }
+
+ mpq_clear (op2);
+ mpfr_clear (op1);
+ mpfr_clear (res);
+ mpfr_clear (cmp);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+
+ test_specialz (mpfr_add_z, mpz_add, "add");
+ test_specialz (mpfr_sub_z, mpz_sub, "sub");
+ test_specialz (mpfr_mul_z, mpz_mul, "mul");
+ test_genericz (2, 100, 100, mpfr_add_z, "add");
+ test_genericz (2, 100, 100, mpfr_sub_z, "sub");
+ test_genericz (2, 100, 100, mpfr_mul_z, "mul");
+ test_genericz (2, 100, 100, mpfr_div_z, "div");
+ test_special2z (mpfr_z_sub, mpz_sub, "sub");
+ test_generic2z (2, 100, 100, mpfr_z_sub, "sub");
+
+ test_genericq (2, 100, 100, mpfr_add_q, "add");
+ test_genericq (2, 100, 100, mpfr_sub_q, "sub");
+ test_genericq (2, 100, 100, mpfr_mul_q, "mul");
+ test_genericq (2, 100, 100, mpfr_div_q, "div");
+ test_specialq (2, 100, 100, mpfr_mul_q, mpq_mul, "mul");
+ test_specialq (2, 100, 100, mpfr_div_q, mpq_div, "div");
+ test_specialq (2, 100, 100, mpfr_add_q, mpq_add, "add");
+ test_specialq (2, 100, 100, mpfr_sub_q, mpq_sub, "sub");
+
+ test_cmp_z (2, 100, 100);
+ test_cmp_q (2, 100, 100);
+ test_cmp_f (2, 100, 100);
+
+ check_for_zero ();
+
+ bug_mul_q_20100810 ();
+ bug_div_q_20100810 ();
+ bug_mul_div_q_20100818 ();
+ reduced_expo_range ();
+ addsubq_overflow ();
+
+ coverage_mpfr_mul_q_20110218 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
diff --git a/mpfr/tests/tgrandom.c b/mpfr/tests/tgrandom.c
new file mode 100644
index 0000000000..ee484cb024
--- /dev/null
+++ b/mpfr/tests/tgrandom.c
@@ -0,0 +1,140 @@
+/* Test file for mpfr_grandom
+
+Copyright 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+test_special (mpfr_prec_t p)
+{
+ mpfr_t x;
+ int inexact;
+
+ mpfr_init2 (x, p);
+
+ inexact = mpfr_grandom (x, NULL, RANDS, MPFR_RNDN);
+ if ((inexact & 3) == 0)
+ {
+ printf ("Error: mpfr_grandom() returns a zero ternary value.\n");
+ exit (1);
+ }
+ if ((inexact & (3 << 2)) != 0)
+ {
+ printf ("Error: the second ternary value of mpfr_grandom(x, NULL, ...)"
+ " must be 0.\n");
+ exit (1);
+ }
+
+ mpfr_clear(x);
+}
+
+
+static void
+test_grandom (long nbtests, mpfr_prec_t prec, mpfr_rnd_t rnd,
+ int verbose)
+{
+ mpfr_t *t;
+ mpfr_t av, va, tmp;
+ int i, inexact;
+
+ nbtests = (nbtests & 1) ? (nbtests + 1) : nbtests;
+ t = (mpfr_t *) malloc (nbtests * sizeof (mpfr_t));
+ if (t == NULL)
+ {
+ fprintf (stderr, "tgrandom: can't allocate memory in test_grandom\n");
+ exit (1);
+ }
+
+ for (i = 0; i < nbtests; ++i)
+ mpfr_init2 (t[i], prec);
+
+ for (i = 0; i < nbtests; i += 2)
+ {
+ inexact = mpfr_grandom (t[i], t[i + 1], RANDS, MPFR_RNDN);
+ if ((inexact & 3) == 0 || (inexact & (3 << 2)) == 0)
+ {
+ /* one call in the loop pretended to return an exact number! */
+ printf ("Error: mpfr_grandom() returns a zero ternary value.\n");
+ exit (1);
+ }
+ }
+
+#ifdef HAVE_STDARG
+ if (verbose)
+ {
+ mpfr_init2 (av, prec);
+ mpfr_init2 (va, prec);
+ mpfr_init2 (tmp, prec);
+
+ mpfr_set_ui (av, 0, MPFR_RNDN);
+ mpfr_set_ui (va, 0, MPFR_RNDN);
+ for (i = 0; i < nbtests; ++i)
+ {
+ mpfr_add (av, av, t[i], MPFR_RNDN);
+ mpfr_sqr (tmp, t[i], MPFR_RNDN);
+ mpfr_add (va, va, tmp, MPFR_RNDN);
+ }
+ mpfr_div_ui (av, av, nbtests, MPFR_RNDN);
+ mpfr_div_ui (va, va, nbtests, MPFR_RNDN);
+ mpfr_sqr (tmp, av, MPFR_RNDN);
+ mpfr_sub (va, va, av, MPFR_RNDN);
+
+ mpfr_printf ("Average = %.5Rf\nVariance = %.5Rf\n", av, va);
+ mpfr_clear (av);
+ mpfr_clear (va);
+ mpfr_clear (tmp);
+ }
+#endif /* HAVE_STDARG */
+
+ for (i = 0; i < nbtests; ++i)
+ mpfr_clear (t[i]);
+ free (t);
+ return;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ long nbtests;
+ int verbose;
+ tests_start_mpfr ();
+
+ verbose = 0;
+ nbtests = 10;
+ if (argc > 1)
+ {
+ long a = atol (argv[1]);
+ verbose = 1;
+ if (a != 0)
+ nbtests = a;
+ }
+
+ test_grandom (nbtests, 420, MPFR_RNDN, verbose);
+ test_special (2);
+ test_special (42000);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/thyperbolic.c b/mpfr/tests/thyperbolic.c
new file mode 100644
index 0000000000..abf511855e
--- /dev/null
+++ b/mpfr/tests/thyperbolic.c
@@ -0,0 +1,385 @@
+/* Test file for hyperbolic function : mpfr_cosh, mpfr_sinh, mpfr_tanh, mpfr_acosh, mpfr_asinh, mpfr_atanh.
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mpfr-test.h"
+
+static int
+check_NAN (void)
+{
+ mpfr_t t, ch,sh,th,ach,ash,ath;
+ int tester;
+ int fail = 0;
+
+ mpfr_init2(t,200);
+ mpfr_init2(ch,200);
+ mpfr_init2(sh,200);
+ mpfr_init2(th,200);
+ mpfr_init2(ach,200);
+ mpfr_init2(ash,200);
+ mpfr_init2(ath,200);
+
+ MPFR_SET_NAN(t);
+
+ /******cosh********/
+
+ tester=mpfr_cosh(ch,t,MPFR_RNDD);
+ if (!MPFR_IS_NAN(ch) || tester!=0)
+ {
+ printf("cosh NAN \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******sinh********/
+
+ tester=mpfr_sinh(sh,t,MPFR_RNDD);
+ if (!MPFR_IS_NAN(sh) || tester!=0)
+ {
+ printf("sinh NAN \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******tanh********/
+
+ tester=mpfr_tanh(th,t,MPFR_RNDD);
+ if (!MPFR_IS_NAN(th) || tester!=0)
+ {
+ printf("tanh NAN \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******acosh********/
+
+ tester=mpfr_acosh(ach,t,MPFR_RNDD);
+ if (!MPFR_IS_NAN(ach) || tester!=0)
+ {
+ printf("acosh NAN \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******asinh********/
+
+ tester=mpfr_asinh(ash,t,MPFR_RNDD);
+ if (!MPFR_IS_NAN(ash) || tester!=0)
+ {
+ printf("asinh NAN \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******atanh********/
+
+ tester=mpfr_atanh(ath,t,MPFR_RNDD);
+ if (!MPFR_IS_NAN(ath) || tester!=0)
+ {
+ printf("atanh NAN \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ clean_up:
+ mpfr_clear(t);
+ mpfr_clear(ch);
+ mpfr_clear(sh);
+ mpfr_clear(th);
+ mpfr_clear(ach);
+ mpfr_clear(ash);
+ mpfr_clear(ath);
+
+ return fail;
+}
+
+static int
+check_zero (void)
+{
+ mpfr_t t, ch,sh,th,ach,ash,ath;
+ int tester;
+ int fail = 0;
+
+ mpfr_init2(t,200);
+ mpfr_init2(ch,200);
+ mpfr_init2(sh,200);
+ mpfr_init2(th,200);
+ mpfr_init2(ach,200);
+ mpfr_init2(ash,200);
+ mpfr_init2(ath,200);
+
+ mpfr_set_ui(t,0,MPFR_RNDD);
+
+ /******cosh********/
+
+ tester = mpfr_cosh (ch, t, MPFR_RNDD);
+ if (mpfr_cmp_ui(ch, 1) || tester)
+ {
+ printf("cosh(0) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******sinh********/
+
+ tester = mpfr_sinh (sh, t, MPFR_RNDD);
+ if (!MPFR_IS_ZERO(sh) || tester)
+ {
+ printf("sinh(0) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******tanh********/
+
+ tester = mpfr_tanh (th, t, MPFR_RNDD);
+ if (!MPFR_IS_ZERO(th) || tester)
+ {
+ printf("tanh(0) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******acosh********/
+
+ tester=mpfr_acosh(ach,t,MPFR_RNDD);
+ if (!MPFR_IS_NAN(ach) || tester)
+ {
+ printf("acosh(0) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******asinh********/
+
+ tester=mpfr_asinh(ash,t,MPFR_RNDD);
+ if (!MPFR_IS_ZERO(ash) || tester)
+ {
+ printf("asinh(0) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******atanh********/
+
+ tester=mpfr_atanh(ath,t,MPFR_RNDD);
+ if (!MPFR_IS_ZERO(ath) || tester)
+ {
+ printf("atanh(0) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ clean_up:
+ mpfr_clear(t);
+ mpfr_clear(ch);
+ mpfr_clear(sh);
+ mpfr_clear(th);
+ mpfr_clear(ach);
+ mpfr_clear(ash);
+ mpfr_clear(ath);
+
+ return fail;
+}
+
+static int
+check_INF (void)
+{
+ mpfr_t t, ch, sh, th, ach, ash, ath;
+ int tester;
+ int fail = 0;
+
+ mpfr_init2 (t, 200);
+ mpfr_init2 (ch, 200);
+ mpfr_init2 (sh, 200);
+ mpfr_init2 (th, 200);
+ mpfr_init2 (ach, 200);
+ mpfr_init2 (ash, 200);
+ mpfr_init2 (ath, 200);
+
+ MPFR_SET_INF(t);
+
+ if(MPFR_SIGN(t)<0)
+ MPFR_CHANGE_SIGN(t);
+
+ /******cosh********/
+
+ tester = mpfr_cosh(ch,t,MPFR_RNDD);
+ if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester!=0)
+ {
+ printf("cosh(INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******sinh********/
+
+ tester=mpfr_sinh(sh,t,MPFR_RNDD);
+ if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) < 0 || tester!=0)
+ {
+ printf("sinh(INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******tanh********/
+
+ tester=mpfr_tanh(th,t,MPFR_RNDD);
+ if (mpfr_cmp_ui(th,1) != 0 || tester!=0)
+ {
+ printf("tanh(INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******acosh********/
+
+ tester=mpfr_acosh(ach,t,MPFR_RNDD);
+ if (!MPFR_IS_INF(ach) || MPFR_SIGN(ach) < 0 || tester!=0)
+ {
+ printf("acosh(INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******asinh********/
+
+ tester=mpfr_asinh(ash,t,MPFR_RNDD);
+ if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) < 0 || tester!=0)
+ {
+ printf("asinh(INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******atanh********/
+
+ tester = mpfr_atanh (ath, t, MPFR_RNDD);
+ if (!MPFR_IS_NAN(ath) || tester != 0)
+ {
+ printf("atanh(INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ MPFR_CHANGE_SIGN(t);
+
+ /******cosh********/
+
+ tester=mpfr_cosh(ch,t,MPFR_RNDD);
+ if (!MPFR_IS_INF(ch) || MPFR_SIGN(ch) < 0 || tester!=0)
+ {
+ printf("cosh(-INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******sinh********/
+
+ tester=mpfr_sinh(sh,t,MPFR_RNDD);
+ if (!MPFR_IS_INF(sh) || MPFR_SIGN(sh) > 0 || tester!=0)
+ {
+ printf("sinh(-INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******tanh********/
+
+ tester=mpfr_tanh(th,t,MPFR_RNDD);
+ if (!mpfr_cmp_ui(th,-1) || tester!=0)
+ {
+ printf("tanh(-INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******acosh********/
+
+ tester=mpfr_acosh(ach,t,MPFR_RNDD);
+ if (!MPFR_IS_NAN(ach) || tester!=0)
+ {
+ printf("acosh(-INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******asinh********/
+
+ tester=mpfr_asinh(ash,t,MPFR_RNDD);
+ if (!MPFR_IS_INF(ash) || MPFR_SIGN(ash) > 0 || tester!=0)
+ {
+ printf("asinh(-INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ /******atanh********/
+
+ tester = mpfr_atanh (ath, t, MPFR_RNDD);
+ if (!MPFR_IS_NAN(ath) || tester != 0)
+ {
+ printf("atanh(-INF) \n");
+ fail = 1;
+ goto clean_up;
+ }
+
+ clean_up:
+ mpfr_clear(t);
+ mpfr_clear(ch);
+ mpfr_clear(sh);
+ mpfr_clear(th);
+ mpfr_clear(ach);
+ mpfr_clear(ash);
+ mpfr_clear(ath);
+
+ return fail;
+}
+
+int
+main(void)
+{
+ tests_start_mpfr ();
+
+ if (check_zero ())
+ {
+ printf ("Error in evaluation at 0\n");
+ exit (1);
+ }
+
+ if (check_INF ())
+ {
+ printf ("Error in evaluation of INF\n");
+ exit (1);
+ }
+
+ if (check_NAN ())
+ {
+ printf ("Error in evaluation of NAN\n");
+ exit (1);
+ }
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/thypot.c b/mpfr/tests/thypot.c
new file mode 100644
index 0000000000..6ec7cef8f6
--- /dev/null
+++ b/mpfr/tests/thypot.c
@@ -0,0 +1,326 @@
+/* Test file for mpfr_hypot.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* Non-zero when extended exponent range */
+static int ext = 0;
+
+static void
+special (void)
+{
+ mpfr_t x, y, z;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ mpfr_set_nan (x);
+ mpfr_hypot (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (z));
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_inf (y, -1);
+ mpfr_hypot (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
+
+ mpfr_set_inf (x, -1);
+ mpfr_set_nan (y);
+ mpfr_hypot (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
+
+ mpfr_set_nan (x);
+ mpfr_set_inf (y, -1);
+ mpfr_hypot (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+test_large (void)
+{
+ mpfr_t x, y, z, t;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (t);
+
+ mpfr_set_ui (x, 21, MPFR_RNDN);
+ mpfr_set_ui (y, 28, MPFR_RNDN);
+ mpfr_set_ui (z, 35, MPFR_RNDN);
+
+ mpfr_mul_2ui (x, x, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
+ mpfr_mul_2ui (y, y, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
+ mpfr_mul_2ui (z, z, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
+
+ mpfr_hypot (t, x, y, MPFR_RNDN);
+ if (mpfr_cmp (z, t))
+ {
+ printf ("Error in test_large: got\n");
+ mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
+ printf ("\ninstead of\n");
+ mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (t, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "0.11101100011110000011101000010101010011001101000001100E-1021");
+ mpfr_set_str_binary (y, "0.11111001010011000001110110001101011100001000010010100E-1021");
+ mpfr_hypot (t, x, y, MPFR_RNDN);
+ mpfr_set_str_binary (z, "0.101010111100110111101110111110100110010011001010111E-1020");
+ if (mpfr_cmp (z, t))
+ {
+ printf ("Error in test_large: got\n");
+ mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
+ printf ("\ninstead of\n");
+ mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 240);
+ mpfr_set_prec (y, 22);
+ mpfr_set_prec (z, 2);
+ mpfr_set_prec (t, 2);
+ mpfr_set_str_binary (x, "0.100111011010010010110100000100000001100010011100110101101111111101011110111011011101010110100101111000111100010100110000100101011110111011100110100110100101110101101100011000001100000001111101110100100100011011011010110111100110010101000111e-7");
+ mpfr_set_str_binary (y, "0.1111000010000011000111E-10");
+ mpfr_hypot (t, x, y, MPFR_RNDN);
+ mpfr_set_str_binary (z, "0.11E-7");
+ if (mpfr_cmp (z, t))
+ {
+ printf ("Error in test_large: got\n");
+ mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
+ printf ("\ninstead of\n");
+ mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+}
+
+static void
+test_small (void)
+{
+ mpfr_t x, y, z1, z2;
+ int inex1, inex2;
+ unsigned int flags;
+
+ /* Test hypot(x,x) with x = 2^(emin-1). Result is x * sqrt(2). */
+ mpfr_inits2 (8, x, y, z1, z2, (mpfr_ptr) 0);
+ mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN);
+ mpfr_set_si_2exp (y, 1, mpfr_get_emin () - 1, MPFR_RNDN);
+ mpfr_set_ui (z1, 2, MPFR_RNDN);
+ inex1 = mpfr_sqrt (z1, z1, MPFR_RNDN);
+ inex2 = mpfr_mul (z1, z1, x, MPFR_RNDN);
+ MPFR_ASSERTN (inex2 == 0);
+ mpfr_clear_flags ();
+ inex2 = mpfr_hypot (z2, x, y, MPFR_RNDN);
+ flags = __gmpfr_flags;
+ if (mpfr_cmp (z1, z2) != 0)
+ {
+ printf ("Error in test_small%s\nExpected ",
+ ext ? ", extended exponent range" : "");
+ mpfr_out_str (stdout, 2, 0, z1, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 2, 0, z2, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ if (! SAME_SIGN (inex1, inex2))
+ {
+ printf ("Bad ternary value in test_small%s\nExpected %d, got %d\n",
+ ext ? ", extended exponent range" : "", inex1, inex2);
+ exit (1);
+ }
+ if (flags != MPFR_FLAGS_INEXACT)
+ {
+ printf ("Bad flags in test_small%s\nExpected %u, got %u\n",
+ ext ? ", extended exponent range" : "",
+ (unsigned int) MPFR_FLAGS_INEXACT, flags);
+ exit (1);
+ }
+ mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
+}
+
+static void
+test_large_small (void)
+{
+ mpfr_t x, y, z;
+ int inexact, inex2, r;
+
+ mpfr_init2 (x, 3);
+ mpfr_init2 (y, 2);
+ mpfr_init2 (z, 2);
+
+ mpfr_set_ui_2exp (x, 1, mpfr_get_emax () / 2, MPFR_RNDN);
+ mpfr_set_ui_2exp (y, 1, -1, MPFR_RNDN);
+ inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
+ if (inexact >= 0 || mpfr_cmp (x, z))
+ {
+ printf ("Error 1 in test_large_small%s\n",
+ ext ? ", extended exponent range" : "");
+ exit (1);
+ }
+
+ mpfr_mul_ui (x, x, 5, MPFR_RNDN);
+ inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp (x, z) >= 0)
+ {
+ printf ("Error 2 in test_large_small%s\n",
+ ext ? ", extended exponent range" : "");
+ printf ("x = ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ printf ("y = ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ printf ("z = ");
+ mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf (" (in precision 2) instead of\n ");
+ mpfr_out_str (stdout, 2, 2, x, MPFR_RNDU);
+ printf ("\n");
+ exit (1);
+ }
+
+ RND_LOOP(r)
+ {
+ mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
+ mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN);
+ inexact = mpfr_hypot (z, x, y, (mpfr_rnd_t) r);
+ inex2 = mpfr_add_ui (y, x, 1, (mpfr_rnd_t) r);
+ if (! mpfr_equal_p (y, z) || ! SAME_SIGN (inexact, inex2))
+ {
+ printf ("Error 3 in test_large_small, %s%s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r),
+ ext ? ", extended exponent range" : "");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf (", inex = %d\n", inex2);
+ printf ("Got ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf (", inex = %d\n", inexact);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+check_overflow (void)
+{
+ mpfr_t x, y;
+ int inex, r;
+
+ mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_setmax (x, mpfr_get_emax ());
+
+ RND_LOOP(r)
+ {
+ mpfr_clear_overflow ();
+ inex = mpfr_hypot (y, x, x, (mpfr_rnd_t) r);
+ if (!mpfr_overflow_p ())
+ {
+ printf ("No overflow in check_overflow for %s%s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r),
+ ext ? ", extended exponent range" : "");
+ exit (1);
+ }
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+ if (r == MPFR_RNDZ || r == MPFR_RNDD)
+ {
+ MPFR_ASSERTN (inex < 0);
+ MPFR_ASSERTN (!mpfr_inf_p (y));
+ mpfr_nexttoinf (y);
+ }
+ else
+ {
+ MPFR_ASSERTN (inex > 0);
+ }
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ }
+
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+#define TWO_ARGS
+#define TEST_FUNCTION mpfr_hypot
+#include "tgeneric.c"
+
+static void
+alltst (void)
+{
+ mpfr_exp_t emin, emax;
+
+ ext = 0;
+ test_small ();
+ test_large_small ();
+ check_overflow ();
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ set_emin (MPFR_EMIN_MIN);
+ set_emax (MPFR_EMAX_MAX);
+ if (mpfr_get_emin () != emin || mpfr_get_emax () != emax)
+ {
+ ext = 1;
+ test_small ();
+ test_large_small ();
+ check_overflow ();
+ set_emin (emin);
+ set_emax (emax);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+
+ test_large ();
+ alltst ();
+
+ test_generic (2, 100, 10);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tinits.c b/mpfr/tests/tinits.c
new file mode 100644
index 0000000000..5a19bb088b
--- /dev/null
+++ b/mpfr/tests/tinits.c
@@ -0,0 +1,62 @@
+/* Test file for mpfr_init2, mpfr_inits, mpfr_inits2 and mpfr_clears.
+
+Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ mpfr_t a, b, c;
+ long large_prec;
+
+ tests_start_mpfr ();
+
+ mpfr_inits (a, b, c, (mpfr_ptr) 0);
+ mpfr_clears (a, b, c, (mpfr_ptr) 0);
+ mpfr_inits2 (200, a, b, c, (mpfr_ptr) 0);
+ mpfr_clears (a, b, c, (mpfr_ptr) 0);
+
+ /* test for precision 2^31-1, see
+ https://gforge.inria.fr/tracker/index.php?func=detail&aid=13918 */
+ large_prec = 2147483647;
+ if (getenv ("MPFR_CHECK_LARGEMEM") != NULL)
+ {
+ /* We assume that the precision won't be increased internally. */
+ if (large_prec > MPFR_PREC_MAX)
+ large_prec = MPFR_PREC_MAX;
+ mpfr_inits2 (large_prec, a, b, (mpfr_ptr) 0);
+ mpfr_set_ui (a, 17, MPFR_RNDN);
+ mpfr_set (b, a, MPFR_RNDN);
+ if (mpfr_get_ui (a, MPFR_RNDN) != 17)
+ {
+ printf ("Error in mpfr_init2 with precision 2^31-1\n");
+ exit (1);
+ }
+ mpfr_clears (a, b, (mpfr_ptr) 0);
+ }
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tinp_str.c b/mpfr/tests/tinp_str.c
new file mode 100644
index 0000000000..151f9bb02d
--- /dev/null
+++ b/mpfr/tests/tinp_str.c
@@ -0,0 +1,94 @@
+/* Test file for mpfr_inp_str.
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x;
+ mpfr_t y;
+ FILE *f;
+ int i;
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_prec (x, 15);
+ f = src_fopen ("inp_str.data", "r");
+ if (f == NULL)
+ {
+ printf ("Error, can't open inp_str.data\n");
+ exit (1);
+ }
+ i = mpfr_inp_str (x, f, 10, MPFR_RNDN);
+ if (i == 0 || mpfr_cmp_ui (x, 31415))
+ {
+ printf ("Error in reading 1st line from file inp_str.data (%d)\n", i);
+ mpfr_dump (x);
+ exit (1);
+ }
+ getc (f);
+ i = mpfr_inp_str (x, f, 10, MPFR_RNDN);
+ if ((i == 0) || mpfr_cmp_ui (x, 31416))
+ {
+ printf ("Error in reading 2nd line from file inp_str.data (%d)\n", i);
+ mpfr_dump (x);
+ exit (1);
+ }
+ getc (f);
+ i = mpfr_inp_str (x, f, 10, MPFR_RNDN);
+ if (i != 0)
+ {
+ printf ("Error in reading 3rd line from file inp_str.data (%d)\n", i);
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str (y, "1.0010010100001110100101001110011010111011100001110010e226",
+ 2, MPFR_RNDN);
+ for (i = 2; i < 63; i++)
+ {
+ getc (f);
+ if (mpfr_inp_str (x, f, i, MPFR_RNDN) == 0 || !mpfr_equal_p (x, y))
+ {
+ printf ("Error in reading %dth line from file inp_str.data\n", i+2);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ }
+
+ fclose (f);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tinternals.c b/mpfr/tests/tinternals.c
new file mode 100644
index 0000000000..60d08a3841
--- /dev/null
+++ b/mpfr/tests/tinternals.c
@@ -0,0 +1,161 @@
+/* tinternals -- Test for internals.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-test.h"
+
+static void
+test_int_ceil_log2 (void)
+{
+ int i;
+ int val[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
+
+ for (i = 1; i < 17; i++)
+ {
+ if (MPFR_INT_CEIL_LOG2 (i) != val[i-1])
+ {
+ printf ("Error 1 in test_int_ceil_log2 for i = %d\n", i);
+ exit (1);
+ }
+ if (MPFR_INT_CEIL_LOG2 (i) != __gmpfr_int_ceil_log2 (i))
+ {
+ printf ("Error 2 in test_int_ceil_log2 for i = %d\n", i);
+ exit (1);
+ }
+ }
+}
+
+static void
+test_round_near_x (void)
+{
+ mpfr_t x, y, z, eps;
+ mpfr_exp_t e;
+ int failures = 0, mx, neg, err, dir, r, inex, inex2;
+ char buffer[7], *p;
+
+ mpfr_inits (x, y, z, eps, (mpfr_ptr) 0);
+ mpfr_set_prec (x, 5);
+ mpfr_set_prec (y, 3);
+ mpfr_set_prec (z, 3);
+ mpfr_set_prec (eps, 2);
+ mpfr_set_ui_2exp (eps, 1, -32, MPFR_RNDN);
+
+ for (mx = 16; mx < 32; mx++)
+ {
+ mpfr_set_ui_2exp (x, mx, -2, MPFR_RNDN);
+ for (p = buffer, neg = 0;
+ neg <= 1;
+ mpfr_neg (x, x, MPFR_RNDN), p++, neg++)
+ for (err = 2; err <= 6; err++)
+ for (dir = 0; dir <= 1; dir++)
+ RND_LOOP(r)
+ {
+ inex = mpfr_round_near_x (y, x, err, dir, (mpfr_rnd_t) r);
+
+ if (inex == 0 && err < 6)
+ {
+ /* The test is more restrictive than necessary.
+ So, no failure in this case. */
+ continue;
+ }
+
+ inex2 = ((dir ^ neg) ? mpfr_add : mpfr_sub)
+ (z, x, eps, (mpfr_rnd_t) r);
+ if (inex * inex2 <= 0)
+ printf ("Bad return value (%d instead of %d) for:\n",
+ inex, inex2);
+ else if (mpfr_equal_p (y, z))
+ continue; /* correct inex and y */
+ else
+ {
+ printf ("Bad MPFR value (should have got ");
+ mpfr_out_str (stdout, 2, 3, z, MPFR_RNDZ);
+ printf (") for:\n");
+ }
+
+ if (!mpfr_get_str (buffer, &e, 2, 5, x, MPFR_RNDZ) || e != 3)
+ {
+ printf ("mpfr_get_str failed in test_round_near_x\n");
+ exit (1);
+ }
+ printf ("x = %c%c%c%c.%c%c, ", neg ? '-' : '+',
+ p[0], p[1], p[2], p[3], p[4]);
+ printf ("err = %d, dir = %d, r = %s --> inex = %2d",
+ err, dir, mpfr_print_rnd_mode ((mpfr_rnd_t) r), inex);
+ if (inex != 0)
+ {
+ printf (", y = ");
+ mpfr_out_str (stdout, 2, 3, y, MPFR_RNDZ);
+ }
+ printf ("\n");
+ if (inex == 0)
+ printf ("Rounding was possible!\n");
+ if (++failures == 10) /* show at most 10 failures */
+ exit (1);
+ }
+ }
+
+ if (failures)
+ exit (1);
+
+ mpfr_clears (x, y, z, eps, (mpfr_ptr) 0);
+}
+
+static void
+test_set_prec_raw (void)
+{
+ mpfr_t x;
+ int i;
+
+ mpfr_init2 (x, 53);
+ for (i = 2; i < 11; i++)
+ {
+ mpfr_set_prec_raw (x, i);
+ if (MPFR_PREC (x) != i)
+ {
+ printf ("[ERROR]: mpfr_set_prec_raw %d\n", i);
+ exit (1);
+ }
+ }
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char **argv)
+{
+ tests_start_mpfr ();
+
+ /* The tested function and macro exist in MPFR 2.2.0, but with a
+ different (incorrect, but with no effect in 2.2.0) behavior. */
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
+ test_int_ceil_log2 ();
+#endif
+
+ test_round_near_x ();
+ test_set_prec_raw ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tisnan.c b/mpfr/tests/tisnan.c
new file mode 100644
index 0000000000..1bd611eab4
--- /dev/null
+++ b/mpfr/tests/tisnan.c
@@ -0,0 +1,212 @@
+/* Test file for mpfr_nan_p, mpfr_inf_p, mpfr_number_p, mpfr_zero_p and
+ mpfr_regular_p.
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ mpfr_t x;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+
+ /* check +infinity gives non-zero for mpfr_inf_p only */
+ mpfr_set_ui (x, 1L, MPFR_RNDZ);
+ mpfr_div_ui (x, x, 0L, MPFR_RNDZ);
+ if (mpfr_nan_p (x) || (mpfr_nan_p) (x) )
+ {
+ printf ("Error: mpfr_nan_p(+Inf) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_inf_p (x) == 0)
+ {
+ printf ("Error: mpfr_inf_p(+Inf) gives zero\n");
+ exit (1);
+ }
+ if (mpfr_number_p (x) || (mpfr_number_p) (x) )
+ {
+ printf ("Error: mpfr_number_p(+Inf) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_zero_p (x) || (mpfr_zero_p) (x) )
+ {
+ printf ("Error: mpfr_zero_p(+Inf) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_regular_p (x) || (mpfr_regular_p) (x) )
+ {
+ printf ("Error: mpfr_regular_p(+Inf) gives non-zero\n");
+ exit (1);
+ }
+
+ /* same for -Inf */
+ mpfr_neg (x, x, MPFR_RNDN);
+ if (mpfr_nan_p (x) || (mpfr_nan_p(x)))
+ {
+ printf ("Error: mpfr_nan_p(-Inf) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_inf_p (x) == 0)
+ {
+ printf ("Error: mpfr_inf_p(-Inf) gives zero\n");
+ exit (1);
+ }
+ if (mpfr_number_p (x) || (mpfr_number_p)(x) )
+ {
+ printf ("Error: mpfr_number_p(-Inf) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_zero_p (x) || (mpfr_zero_p)(x) )
+ {
+ printf ("Error: mpfr_zero_p(-Inf) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_regular_p (x) || (mpfr_regular_p) (x) )
+ {
+ printf ("Error: mpfr_regular_p(-Inf) gives non-zero\n");
+ exit (1);
+ }
+
+ /* same for NaN */
+ mpfr_sub (x, x, x, MPFR_RNDN);
+ if (mpfr_nan_p (x) == 0)
+ {
+ printf ("Error: mpfr_nan_p(NaN) gives zero\n");
+ exit (1);
+ }
+ if (mpfr_inf_p (x) || (mpfr_inf_p)(x) )
+ {
+ printf ("Error: mpfr_inf_p(NaN) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_number_p (x) || (mpfr_number_p) (x) )
+ {
+ printf ("Error: mpfr_number_p(NaN) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_zero_p (x) || (mpfr_zero_p)(x) )
+ {
+ printf ("Error: mpfr_number_p(NaN) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_regular_p (x) || (mpfr_regular_p) (x) )
+ {
+ printf ("Error: mpfr_regular_p(NaN) gives non-zero\n");
+ exit (1);
+ }
+
+ /* same for a regular number */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ if (mpfr_nan_p (x) || (mpfr_nan_p)(x))
+ {
+ printf ("Error: mpfr_nan_p(1) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_inf_p (x) || (mpfr_inf_p)(x) )
+ {
+ printf ("Error: mpfr_inf_p(1) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_number_p (x) == 0)
+ {
+ printf ("Error: mpfr_number_p(1) gives zero\n");
+ exit (1);
+ }
+ if (mpfr_zero_p (x) || (mpfr_zero_p) (x) )
+ {
+ printf ("Error: mpfr_zero_p(1) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_regular_p (x) == 0 || (mpfr_regular_p) (x) == 0)
+ {
+ printf ("Error: mpfr_regular_p(1) gives zero\n");
+ exit (1);
+ }
+
+ /* Same for +0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ if (mpfr_nan_p (x) || (mpfr_nan_p)(x))
+ {
+ printf ("Error: mpfr_nan_p(+0) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_inf_p (x) || (mpfr_inf_p)(x) )
+ {
+ printf ("Error: mpfr_inf_p(+0) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_number_p (x) == 0)
+ {
+ printf ("Error: mpfr_number_p(+0) gives zero\n");
+ exit (1);
+ }
+ if (mpfr_zero_p (x) == 0 )
+ {
+ printf ("Error: mpfr_zero_p(+0) gives zero\n");
+ exit (1);
+ }
+ if (mpfr_regular_p (x) || (mpfr_regular_p) (x) )
+ {
+ printf ("Error: mpfr_regular_p(+0) gives non-zero\n");
+ exit (1);
+ }
+
+ /* Same for -0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ if (mpfr_nan_p (x) || (mpfr_nan_p)(x))
+ {
+ printf ("Error: mpfr_nan_p(-0) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_inf_p (x) || (mpfr_inf_p)(x) )
+ {
+ printf ("Error: mpfr_inf_p(-0) gives non-zero\n");
+ exit (1);
+ }
+ if (mpfr_number_p (x) == 0)
+ {
+ printf ("Error: mpfr_number_p(-0) gives zero\n");
+ exit (1);
+ }
+ if (mpfr_zero_p (x) == 0 )
+ {
+ printf ("Error: mpfr_zero_p(-0) gives zero\n");
+ exit (1);
+ }
+ if (mpfr_regular_p (x) || (mpfr_regular_p) (x) )
+ {
+ printf ("Error: mpfr_regular_p(-0) gives non-zero\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tisqrt.c b/mpfr/tests/tisqrt.c
new file mode 100644
index 0000000000..9e4ec6c6e1
--- /dev/null
+++ b/mpfr/tests/tisqrt.c
@@ -0,0 +1,94 @@
+/* Test file for __gmpfr_isqrt and __gmpfr_cuberoot internal functions.
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+tst_isqrt (unsigned long n, unsigned long r)
+{
+ unsigned long i;
+
+ i = __gmpfr_isqrt (n);
+ if (i != r)
+ {
+ printf ("Error in __gmpfr_isqrt (%lu): got %lu instead of %lu\n",
+ n, i, r);
+ exit (1);
+ }
+}
+
+static void
+tst_icbrt (unsigned long n, unsigned long r)
+{
+ unsigned long i;
+
+ i = __gmpfr_cuberoot (n);
+ if (i != r)
+ {
+ printf ("Error in __gmpfr_cuberoot (%lu): got %lu instead of %lu\n",
+ n, i, r);
+ exit (1);
+ }
+}
+
+int
+main (void)
+{
+ unsigned long c, i;
+
+ tests_start_mpfr ();
+
+ tst_isqrt (0, 0);
+ tst_isqrt (1, 1);
+ tst_isqrt (2, 1);
+ for (i = 2; i <= 65535; i++)
+ {
+ tst_isqrt (i * i - 1, i - 1);
+ tst_isqrt (i * i, i);
+ }
+ tst_isqrt (4294967295UL, 65535);
+
+ tst_icbrt (0, 0);
+ tst_icbrt (1, 1);
+ tst_icbrt (2, 1);
+ tst_icbrt (3, 1);
+ for (i = 2; i <= 1625; i++)
+ {
+ c = i * i * i;
+ tst_icbrt (c - 4, i - 1);
+ tst_icbrt (c - 3, i - 1);
+ tst_icbrt (c - 2, i - 1);
+ tst_icbrt (c - 1, i - 1);
+ tst_icbrt (c, i);
+ tst_icbrt (c + 1, i);
+ tst_icbrt (c + 2, i);
+ tst_icbrt (c + 3, i);
+ tst_icbrt (c + 4, i);
+ }
+ tst_icbrt (4294967295UL, 1625);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tj0.c b/mpfr/tests/tj0.c
new file mode 100644
index 0000000000..ac5de28d63
--- /dev/null
+++ b/mpfr/tests/tj0.c
@@ -0,0 +1,135 @@
+/* tj0 -- test file for the Bessel function of first kind (order 0)
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_j0
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 8, RANDS)
+#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ int inex;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* special values */
+ mpfr_set_nan (x);
+ mpfr_j0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_inf (x, 1); /* +Inf */
+ mpfr_j0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));
+
+ mpfr_set_inf (x, -1); /* -Inf */
+ mpfr_j0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */
+ mpfr_j0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(+0)=1 */
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN); /* -0 */
+ mpfr_j0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(-0)=1 */
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_j0 (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_j0 for x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_j0 (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_j0 for x=-1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ /* Bug reported on 2007-07-03 by Sisyphus (assertion failed in r4619) */
+ mpfr_set_si (x, 70000, MPFR_RNDN);
+ mpfr_j0 (y, x, MPFR_RNDN);
+
+ /* Bug reported by Kevin Rauch on 27 Oct 2007 */
+ mpfr_set_prec (x, 7);
+ mpfr_set_prec (y, 7);
+ mpfr_set_si (x, -100, MPFR_RNDN);
+ mpfr_j0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (! mpfr_nan_p (y) && mpfr_cmp_ui_2exp (y, 41, -11) == 0);
+
+ /* Case for which s = 0 in mpfr_jn */
+ mpfr_set_prec (x, 44);
+ mpfr_set_prec (y, 44);
+ mpfr_set_si (x, 2, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_j0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_INEXACT);
+ mpfr_set_str (x, "0x.e5439fd9267p-2", 0, MPFR_RNDN);
+ if (! mpfr_equal_p (y, x))
+ {
+ printf ("Error on 2:\n");
+ printf ("Expected ");
+ mpfr_dump (x);
+ printf ("Got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ if (inex >= 0)
+ {
+ printf ("Bad ternary value on 2: expected negative, got %d\n", inex);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ test_generic (2, 100, 10);
+
+ data_check ("data/j0", mpfr_j0, "mpfr_j0");
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tj1.c b/mpfr/tests/tj1.c
new file mode 100644
index 0000000000..715cf27f83
--- /dev/null
+++ b/mpfr/tests/tj1.c
@@ -0,0 +1,88 @@
+/* tj1 -- test file for the Bessel function of first kind (order 1)
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_j1
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 8, RANDS)
+#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* special values */
+ mpfr_set_nan (x);
+ mpfr_j1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_inf (x, 1); /* +Inf */
+ mpfr_j1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));
+
+ mpfr_set_inf (x, -1); /* -Inf */
+ mpfr_j1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */
+ mpfr_j1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j1(+0)=+0 */
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN); /* -0 */
+ mpfr_j1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG (y)); /* j1(-0)=-0 */
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_j1 (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.0111000010100111001001111011101001011100001100011011");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_j1 for x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ test_generic (2, 100, 10);
+
+ data_check ("data/j1", mpfr_j1, "mpfr_j1");
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tjn.c b/mpfr/tests/tjn.c
new file mode 100644
index 0000000000..54067a83d2
--- /dev/null
+++ b/mpfr/tests/tjn.c
@@ -0,0 +1,307 @@
+/* tjn -- test file for the Bessel function of first kind
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h> /* for LONG_MAX */
+
+#include "mpfr-test.h"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ long n;
+
+ if (argc > 1)
+ {
+ mpfr_init2 (x, atoi (argv[1]));
+ mpfr_set_str (x, argv[3], 10, MPFR_RNDN);
+ mpfr_jn (x, atoi (argv[2]), x, MPFR_RNDN);
+ mpfr_out_str (stdout, 10, 10, x, MPFR_RNDN);
+ printf ("\n");
+ mpfr_clear (x);
+ return 0;
+ }
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* special values */
+ mpfr_set_nan (x);
+ mpfr_jn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_inf (x, 1); /* +Inf */
+ mpfr_jn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));
+
+ mpfr_set_inf (x, -1); /* -Inf */
+ mpfr_jn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */
+ mpfr_jn (y, 0, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(+0)=1 */
+ mpfr_jn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j17(+0)=+0 */
+ mpfr_jn (y, -17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG (y)); /* j-17(+0)=-0 */
+ mpfr_jn (y, 42, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j42(+0)=+0 */
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN); /* -0 */
+ mpfr_jn (y, 0, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); /* j0(-0)=1 */
+ mpfr_jn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG (y)); /* j17(-0)=-0 */
+ mpfr_jn (y, -17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j-17(-0)=+0 */
+ mpfr_jn (y, 42, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y)); /* j42(-0)=+0 */
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_jn (y, 0, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=0, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_jn (y, 0, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1100001111100011111111101101111010111101110001111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=0, x=-1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_jn (y, 1, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.0111000010100111001001111011101001011100001100011011");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=1, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_jn (y, 17, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1100011111001010101001001001000110110000010001011E-65");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=17, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_jn (y, 42, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=42, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_jn (y, -42, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=-42, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_jn (y, 42, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=42, x=-1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_jn (y, -42, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10000111100011010100111011100111101101000100000001001E-211");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=-42, x=-1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_jn (y, 4, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-0.0001110001011001100010100111100111100000111110111011111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=4, x=17, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_jn (y, 16, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.0011101111100111101111010100000111111001111001001010011");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=16, x=17, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_jn (y, 256, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.11111101111100110000000010111101101011101011110001011E-894");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=256, x=17, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_jn (y, 65536, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "100010010010011010110101100001000100011100010111011E-751747");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=65536, x=17, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_jn (y, 131072, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "1000001001110011111001110110000010011010000001001101E-1634508");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=131072, x=17, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_jn (y, 262144, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "1010011011000100111011001011110001000010000010111111E-3531100");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=262144, x=17, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_jn (y, 524288, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "110000001010001111011011000011001011010100010001011E-7586426");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=524288, x=17, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ n = LONG_MAX;
+ /* ensures n is odd */
+ if (n % 2 == 0)
+ n --;
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_jn (y, n, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.0");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=%ld, x=17, rnd=MPFR_RNDN\n", n);
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -17, MPFR_RNDN);
+ mpfr_jn (y, n, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-0.0");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=%ld, x=-17, rnd=MPFR_RNDN\n", n);
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_jn (y, -n, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-0.0");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=%ld, x=17, rnd=MPFR_RNDN\n", -n);
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -17, MPFR_RNDN);
+ mpfr_jn (y, -n, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.0");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_jn for n=%ld, x=-17, rnd=MPFR_RNDN\n", -n);
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tl2b.c b/mpfr/tests/tl2b.c
new file mode 100644
index 0000000000..ca51906a48
--- /dev/null
+++ b/mpfr/tests/tl2b.c
@@ -0,0 +1,174 @@
+/* Test file for l2b constants.
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Execute this program with an argument to generate code that initializes
+ the l2b constants. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpfr-test.h"
+
+/* Must be a multiple of 4 */
+static const int bits2use[] = {16, 32, 64, 96, 128, 256};
+#define size_of_bits2use ((sizeof bits2use) / sizeof bits2use[0])
+
+static __mpfr_struct l2b[BASE_MAX-1][2];
+
+static void
+print_mpfr (mpfr_srcptr x, const char *name)
+{
+ unsigned char temp[16]; /* buffer for the base-256 string */
+ unsigned char *ptr; /* pointer to its first non-zero byte */
+ int size; /* size of the string */
+ int i; /* bits2use index */
+ int j; /* output limb index */
+ int k; /* byte index (in output limb) */
+ int r; /* digit index, relative to ptr */
+
+ if (printf ("#if 0\n") < 0)
+ { fprintf (stderr, "Error in printf\n"); exit (1); }
+ for (i = 0; i < size_of_bits2use; i++)
+ {
+ if (printf ("#elif GMP_NUMB_BITS == %d\n"
+ "const mp_limb_t %s__tab[] = { 0x", bits2use[i], name) < 0)
+ { fprintf (stderr, "Error in printf\n"); exit (1); }
+ size = mpn_get_str (temp, 256, MPFR_MANT (x), MPFR_LIMB_SIZE (x));
+ MPFR_ASSERTN (size <= 16);
+ ptr = temp;
+ /* Skip leading zeros. */
+ while (*ptr == 0)
+ {
+ ptr++;
+ size--;
+ MPFR_ASSERTN (size > 0);
+ }
+ MPFR_ASSERTN (*ptr >= 128);
+ for (j = (MPFR_PREC (x) - 1) / bits2use[i]; j >= 0; j--)
+ {
+ r = j * (bits2use[i] / 8);
+ for (k = 0; k < bits2use[i] / 8; k++)
+ if (printf ("%02x", r < size ? ptr[r++] : 0) < 0)
+ { fprintf (stderr, "Error in printf\n"); exit (1); }
+ if (printf (j == 0 ? " };\n" : ", 0x") < 0)
+ { fprintf (stderr, "Error in printf\n"); exit (1); }
+ }
+ }
+ if (printf ("#endif\n\n") < 0)
+ { fprintf (stderr, "Error in printf\n"); exit (1); }
+}
+
+static void
+compute_l2b (int output)
+{
+ mpfr_ptr p;
+ mpfr_srcptr t;
+ int beta, i;
+ int error = 0;
+ char buffer[30];
+
+ for (beta = 2; beta <= BASE_MAX; beta++)
+ {
+ for (i = 0; i < 2; i++)
+ {
+ p = &l2b[beta-2][i];
+
+ /* Compute the value */
+ if (i == 0)
+ {
+ /* 23-bit upper approximation to log(b)/log(2) */
+ mpfr_init2 (p, 23);
+ mpfr_set_ui (p, beta, MPFR_RNDU);
+ mpfr_log2 (p, p, MPFR_RNDU);
+ }
+ else
+ {
+ /* 76-bit upper approximation to log(2)/log(b) */
+ mpfr_init2 (p, 77);
+ mpfr_set_ui (p, beta, MPFR_RNDD);
+ mpfr_log2 (p, p, MPFR_RNDD);
+ mpfr_ui_div (p, 1, p, MPFR_RNDU);
+ }
+
+ sprintf (buffer, "mpfr_l2b_%d_%d", beta, i);
+ if (output)
+ print_mpfr (p, buffer);
+
+ /* Check the value */
+ t = &__gmpfr_l2b[beta-2][i];
+ if (t == NULL || MPFR_PREC (t) == 0 || !mpfr_equal_p (p, t))
+ {
+ if (!output)
+ {
+ error = 1;
+ printf ("Error for constant %s\n", buffer);
+ }
+ }
+
+ if (!output)
+ mpfr_clear (p);
+ }
+ }
+
+ if (output)
+ {
+ if (printf ("const __mpfr_struct __gmpfr_l2b[BASE_MAX-1][2] = {\n")
+ < 0)
+ { fprintf (stderr, "Error in printf\n"); exit (1); }
+ for (beta = 2; beta <= BASE_MAX; beta++)
+ {
+ for (i = 0; i < 2; i++)
+ {
+ p = &l2b[beta-2][i];
+ if (printf (" %c {%3d,%2d,%3ld, (mp_limb_t *) "
+ "mpfr_l2b_%d_%d__tab }%s\n", i == 0 ? '{' : ' ',
+ (int) MPFR_PREC (p), MPFR_SIGN (p),
+ (long) MPFR_GET_EXP (p), beta, i,
+ i == 0 ? "," : beta < BASE_MAX ? " }," : " } };")
+ < 0)
+ { fprintf (stderr, "Error in printf\n"); exit (1); }
+ mpfr_clear (p);
+ }
+ }
+ }
+
+ /* If there was an error, the test fails. */
+ if (error)
+ exit (1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (argc != 1)
+ {
+ /* Generate code that initializes the l2b constants. */
+ compute_l2b (1);
+ }
+ else
+ {
+ /* Check the l2b constants. */
+ tests_start_mpfr ();
+ compute_l2b (0);
+ tests_end_mpfr ();
+ }
+ return 0;
+}
diff --git a/mpfr/tests/tlgamma.c b/mpfr/tests/tlgamma.c
new file mode 100644
index 0000000000..faa62763ad
--- /dev/null
+++ b/mpfr/tests/tlgamma.c
@@ -0,0 +1,403 @@
+/* mpfr_tlgamma -- test file for lgamma function
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static int
+mpfr_lgamma_nosign (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
+{
+ int inex, sign;
+
+ inex = mpfr_lgamma (y, &sign, x, rnd);
+ if (!MPFR_IS_SINGULAR (y))
+ {
+ MPFR_ASSERTN (sign == 1 || sign == -1);
+ if (sign == -1 && (rnd == MPFR_RNDN || rnd == MPFR_RNDZ))
+ {
+ mpfr_neg (y, y, MPFR_RNDN);
+ inex = -inex;
+ /* This is a way to check with the generic tests, that the value
+ returned in the sign variable is consistent, but warning! The
+ tested function depends on the rounding mode: it is
+ * lgamma(x) = log(|Gamma(x)|) in MPFR_RNDD and MPFR_RNDU;
+ * lgamma(x) * sign(Gamma(x)) in MPFR_RNDN and MPFR_RNDZ. */
+ }
+ }
+
+ return inex;
+}
+
+#define TEST_FUNCTION mpfr_lgamma_nosign
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int inex;
+ int sign;
+ mpfr_exp_t emin, emax;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_nan (x);
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for lgamma(NaN)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for lgamma(-Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != 1)
+ {
+ printf ("Error for lgamma(+Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != 1)
+ {
+ printf ("Error for lgamma(+0)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || sign != -1)
+ {
+ printf ("Error for lgamma(-0)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y) || sign != 1)
+ {
+ printf ("Error for lgamma(1)\n");
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for lgamma(-1)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y) || sign != 1)
+ {
+ printf ("Error for lgamma(2)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+#define CHECK_X1 "1.0762904832837976166"
+#define CHECK_Y1 "-0.039418362817587634939"
+
+ mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN);
+ if (mpfr_equal_p (y, x) == 0 || sign != 1)
+ {
+ printf ("mpfr_lgamma("CHECK_X1") is wrong:\n"
+ "expected ");
+ mpfr_print_binary (x); putchar ('\n');
+ printf ("got ");
+ mpfr_print_binary (y); putchar ('\n');
+ exit (1);
+ }
+
+#define CHECK_X2 "9.23709516716202383435e-01"
+#define CHECK_Y2 "0.049010669407893718563"
+ mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN);
+ if (mpfr_equal_p (y, x) == 0 || sign != 1)
+ {
+ printf ("mpfr_lgamma("CHECK_X2") is wrong:\n"
+ "expected ");
+ mpfr_print_binary (x); putchar ('\n');
+ printf ("got ");
+ mpfr_print_binary (y); putchar ('\n');
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 8);
+ mpfr_set_prec (y, 175);
+ mpfr_set_ui (x, 33, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDU);
+ mpfr_set_prec (x, 175);
+ mpfr_set_str_binary (x, "0.1010001100011101101011001101110010100001000001000001110011000001101100001111001001000101011011100100010101011110100111110101010100010011010010000101010111001100011000101111E7");
+ if (mpfr_equal_p (x, y) == 0 || sign != 1)
+ {
+ printf ("Error in mpfr_lgamma (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 21);
+ mpfr_set_prec (y, 8);
+ mpfr_set_ui (y, 120, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (x, &sign, y, MPFR_RNDZ);
+ mpfr_set_prec (y, 21);
+ mpfr_set_str_binary (y, "0.111000101000001100101E9");
+ if (mpfr_equal_p (x, y) == 0 || sign != 1)
+ {
+ printf ("Error in mpfr_lgamma (120)\n");
+ printf ("Expected "); mpfr_print_binary (y); puts ("");
+ printf ("Got "); mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_prec (y, 206);
+ mpfr_set_str_binary (x, "0.110e10");
+ sign = -17;
+ inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_prec (x, 206);
+ mpfr_set_str_binary (x, "0.10000111011000000011100010101001100110001110000111100011000100100110110010001011011110101001111011110110000001010100111011010000000011100110110101100111000111010011110010000100010111101010001101000110101001E13");
+ if (mpfr_equal_p (x, y) == 0 || sign != 1)
+ {
+ printf ("Error in mpfr_lgamma (768)\n");
+ exit (1);
+ }
+ if (inex >= 0)
+ {
+ printf ("Wrong flag for mpfr_lgamma (768)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 4);
+ mpfr_set_prec (y, 4);
+ mpfr_set_str_binary (x, "0.1100E-66");
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1100E6");
+ if (mpfr_equal_p (x, y) == 0 || sign != 1)
+ {
+ printf ("Error for lgamma(0.1100E-66)\n");
+ printf ("Expected ");
+ mpfr_dump (x);
+ printf ("Got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 256);
+ mpfr_set_prec (y, 32);
+ mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN);
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ mpfr_div_2ui (x, x, 1, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_prec (x, 32);
+ mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207");
+ if (mpfr_equal_p (x, y) == 0 || sign != 1)
+ {
+ printf ("Error for lgamma(-2^199+0.5)\n");
+ printf ("Got ");
+ mpfr_dump (y);
+ printf ("instead of ");
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 256);
+ mpfr_set_prec (y, 32);
+ mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN);
+ mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+ mpfr_div_2ui (x, x, 1, MPFR_RNDN);
+ sign = -17;
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_prec (x, 32);
+ mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207");
+ if (mpfr_equal_p (x, y) == 0 || sign != -1)
+ {
+ printf ("Error for lgamma(-2^199-0.5)\n");
+ printf ("Got ");
+ mpfr_dump (y);
+ printf ("with sign %d instead of ", sign);
+ mpfr_dump (x);
+ printf ("with sign -1.\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 10);
+ mpfr_set_prec (y, 10);
+ mpfr_set_str_binary (x, "-0.1101111000E-3");
+ inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "10.01001011");
+ if (mpfr_equal_p (x, y) == 0 || sign != -1 || inex >= 0)
+ {
+ printf ("Error for lgamma(-0.1101111000E-3)\n");
+ printf ("Got ");
+ mpfr_dump (y);
+ printf ("instead of ");
+ mpfr_dump (x);
+ printf ("with sign %d instead of -1 (inex=%d).\n", sign, inex);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 18);
+ mpfr_set_prec (y, 28);
+ mpfr_set_str_binary (x, "-1.10001101010001101e-196");
+ inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_prec (x, 28);
+ mpfr_set_str_binary (x, "0.100001110110101011011010011E8");
+ MPFR_ASSERTN (mpfr_equal_p (x, y) && inex < 0);
+
+ /* values reported by Kaveh Ghazi on 14 Jul 2007, where mpfr_lgamma()
+ takes forever */
+#define VAL1 "-0.11100001001010110111001010001001001011110100110000110E-55"
+#define OUT1 "100110.01000000010111001110110101110101001001100110111"
+#define VAL2 "-0.11100001001010110111001010001001001011110011111111100E-55"
+#define OUT2 "100110.0100000001011100111011010111010100100110011111"
+#define VAL3 "-0.11100001001010110111001010001001001001110101101010100E-55"
+#define OUT3 "100110.01000000010111001110110101110101001011110111011"
+#define VAL4 "-0.10001111110110110100100100000000001111110001001001011E-57"
+#define OUT4 "101000.0001010111110011101101000101111111010001100011"
+#define VAL5 "-0.10001111110110110100100100000000001111011111100001000E-57"
+#define OUT5 "101000.00010101111100111011010001011111110100111000001"
+#define VAL6 "-0.10001111110110110100100100000000001111011101100011001E-57"
+#define OUT6 "101000.0001010111110011101101000101111111010011101111"
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_str_binary (x, VAL1);
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, OUT1);
+ MPFR_ASSERTN(sign == -1 && mpfr_equal_p(x, y));
+
+ mpfr_set_str_binary (x, VAL2);
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, OUT2);
+ MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));
+
+ mpfr_set_str_binary (x, VAL3);
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, OUT3);
+ MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));
+
+ mpfr_set_str_binary (x, VAL4);
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, OUT4);
+ MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));
+
+ mpfr_set_str_binary (x, VAL5);
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, OUT5);
+ MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));
+
+ mpfr_set_str_binary (x, VAL6);
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, OUT6);
+ MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));
+
+ /* further test from Kaveh Ghazi */
+ mpfr_set_str_binary (x, "-0.10011010101001010010001110010111010111011101010111001E-53");
+ mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "100101.00111101101010000000101010111010001111001101111");
+ MPFR_ASSERTN(sign == -1 && mpfr_equal_p (x, y));
+
+ /* bug found by Kevin Rauch on 26 Oct 2007 */
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ mpfr_set_emin (-1000000000);
+ mpfr_set_emax (1000000000);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_lgamma (x, &sign, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_get_emin () == -1000000000);
+ MPFR_ASSERTN(mpfr_get_emax () == 1000000000);
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+
+ /* two other bugs reported by Kevin Rauch on 27 Oct 2007 */
+ mpfr_set_prec (x, 128);
+ mpfr_set_prec (y, 128);
+ mpfr_set_str_binary (x, "0.11000110011110111111110010100110000000000000000000000000000000000000000000000000000000000000000001000011000110100100110111101010E-765689");
+ inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "10000001100100101111011011010000111010001001110000111010011000101001011111011111110011011010110100101111110111001001010100011101E-108");
+ MPFR_ASSERTN(inex < 0 && mpfr_cmp (y, x) == 0 && sign > 0);
+
+ mpfr_set_prec (x, 128);
+ mpfr_set_prec (y, 256);
+ mpfr_set_str_binary (x, "0.1011111111111111100000111011111E-31871");
+ inex = mpfr_lgamma (y, &sign, x, MPFR_RNDN);
+ mpfr_set_prec (x, 256);
+ mpfr_set_str (x, "AC9729B83707E6797612D0D76DAF42B1240A677FF1B6E3783FD4E53037143B1P-237", 16, MPFR_RNDN);
+ MPFR_ASSERTN(inex < 0 && mpfr_cmp (y, x) == 0 && sign > 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static int
+mpfr_lgamma1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r)
+{
+ int sign;
+
+ return mpfr_lgamma (y, &sign, x, r);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+
+ special ();
+ test_generic (2, 100, 2);
+
+ data_check ("data/lgamma", mpfr_lgamma1, "mpfr_lgamma");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tli2.c b/mpfr/tests/tli2.c
new file mode 100644
index 0000000000..f8a5b4a8cd
--- /dev/null
+++ b/mpfr/tests/tli2.c
@@ -0,0 +1,208 @@
+/* mpfr_tli2 -- test file for dilogarithm function
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+#define TEST_FUNCTION mpfr_li2
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_nan (x);
+ mpfr_li2 (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for li2(NaN)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_li2 (y, x, MPFR_RNDN);
+ if (!MPFR_IS_INF (y) || MPFR_IS_POS (y))
+ {
+ printf ("Error for li2(-Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_li2 (y, x, MPFR_RNDN);
+ if (!MPFR_IS_INF (y) || MPFR_IS_POS (y))
+ {
+ printf ("Error for li2(+Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_li2 (y, x, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (y) || MPFR_IS_NEG (y))
+ {
+ printf ("Error for li2(+0)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_li2 (y, x, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (y) || MPFR_IS_POS (y))
+ {
+ printf ("Error for li2(-0)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+normal (void)
+{
+ int inexact;
+ mpfr_t x, y;
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* x1 = 2^-3 */
+ mpfr_set_str (x, "1p-3", 2, MPFR_RNDD);
+ mpfr_li2 (x, x, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "0x1087a7a9e42141p-55", 16, MPFR_RNDN) != 0)
+ {
+ printf ("Error for li2(x1)\n");
+ exit (1);
+ }
+
+ /* check MPFR_FAST_COMPUTE_IF_SMALL_INPUT */
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 20);
+ mpfr_set_ui_2exp (x, 1, -21, MPFR_RNDN);
+ mpfr_li2 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
+
+ mpfr_set_si_2exp (x, -1, -21, MPFR_RNDN);
+ mpfr_li2 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
+
+ /* worst case */
+ /* x2 = 0x7F18EA6537E00E983196CDDC6EFAC57Fp-129
+ Li2(x2) = 2^-2 + 2^-6 + 2^-120 */
+ mpfr_set_prec (x, 128);
+ mpfr_set_str (x, "7F18EA6537E00E983196CDDC6EFAC57Fp-129", 16, MPFR_RNDN);
+
+ /* round to nearest mode and 4 bits of precision,
+ it should be rounded to 2^-2 + 2^-5 and */
+ mpfr_set_prec (y, 4);
+ inexact = mpfr_li2 (y, x, MPFR_RNDN);
+ if (inexact != 1 || mpfr_cmp_str (y, "0.1001p-1", 2, MPFR_RNDN) != 0)
+ {
+ printf ("Error for li2(x2, RNDN)\n");
+ exit (1);
+ }
+
+ /* round toward zero mode and 5 bits of precision,
+ it should be rounded to 2^-2 + 2^-6 */
+ mpfr_set_prec (y, 5);
+ inexact = mpfr_li2 (y, x, MPFR_RNDZ);
+ if (inexact != -1 || mpfr_cmp_str (y, "0.10001p-1", 2, MPFR_RNDN) != 0)
+ {
+ printf ("Error for li2(x2, RNDZ)\n");
+ exit (1);
+ }
+
+ /* round away from zero mode and 5 bits of precision,
+ it should be rounded to 2^-2 + 2^-5 */
+ inexact = mpfr_li2 (y, x, MPFR_RNDU);
+ if (inexact != 1 || mpfr_cmp_str (y, "0.10010p-1", 2, MPFR_RNDN) != 0)
+ {
+ printf ("Error for li2(x2, RNDU)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+bug20091013 (void)
+{
+ mpfr_t x, y;
+ int inex;
+
+ mpfr_init2 (x, 17);
+ mpfr_init2 (y, 2);
+ mpfr_set_str_binary (x, "0.10000000000000000E-16");
+ inex = mpfr_li2 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui_2exp (y, 1, -17) != 0)
+ {
+ printf ("Error in bug20091013()\n");
+ printf ("expected 2^(-17)\n");
+ printf ("got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ if (inex >= 0)
+ {
+ printf ("Error in bug20091013()\n");
+ printf ("expected negative ternary value, got %d\n", inex);
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ bug20091013 ();
+
+ special ();
+
+ normal ();
+
+ test_generic (2, 100, 2);
+
+ data_check ("data/li2", mpfr_li2, "mpfr_li2");
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tlngamma.c b/mpfr/tests/tlngamma.c
new file mode 100644
index 0000000000..500b9a2c54
--- /dev/null
+++ b/mpfr/tests/tlngamma.c
@@ -0,0 +1,238 @@
+/* mpfr_tlngamma -- test file for lngamma function
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_lngamma
+#define TEST_RANDOM_POS 16
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int inex;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_nan (x);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for lngamma(NaN)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for lngamma(-Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for lngamma(+Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error for lngamma(+0)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for lngamma(-0)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
+ {
+ printf ("Error for lngamma(1)\n");
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for lngamma(-1)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
+ {
+ printf ("Error for lngamma(2)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+#define CHECK_X1 "1.0762904832837976166"
+#define CHECK_Y1 "-0.039418362817587634939"
+
+ mpfr_set_str (x, CHECK_X1, 10, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ mpfr_set_str (x, CHECK_Y1, 10, MPFR_RNDN);
+ if (MPFR_IS_NAN (y) || mpfr_cmp (y, x))
+ {
+ printf ("mpfr_lngamma("CHECK_X1") is wrong:\n"
+ "expected ");
+ mpfr_print_binary (x); putchar ('\n');
+ printf ("got ");
+ mpfr_print_binary (y); putchar ('\n');
+ exit (1);
+ }
+
+#define CHECK_X2 "9.23709516716202383435e-01"
+#define CHECK_Y2 "0.049010669407893718563"
+ mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN);
+ if (MPFR_IS_NAN (y) || mpfr_cmp (y, x))
+ {
+ printf ("mpfr_lngamma("CHECK_X2") is wrong:\n"
+ "expected ");
+ mpfr_print_binary (x); putchar ('\n');
+ printf ("got ");
+ mpfr_print_binary (y); putchar ('\n');
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 8);
+ mpfr_set_prec (y, 175);
+ mpfr_set_ui (x, 33, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDU);
+ mpfr_set_prec (x, 175);
+ mpfr_set_str_binary (x, "0.1010001100011101101011001101110010100001000001000001110011000001101100001111001001000101011011100100010101011110100111110101010100010011010010000101010111001100011000101111E7");
+ if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_lngamma (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 21);
+ mpfr_set_prec (y, 8);
+ mpfr_set_ui (y, 120, MPFR_RNDN);
+ mpfr_lngamma (x, y, MPFR_RNDZ);
+ mpfr_set_prec (y, 21);
+ mpfr_set_str_binary (y, "0.111000101000001100101E9");
+ if (MPFR_IS_NAN (x) || mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_lngamma (120)\n");
+ printf ("Expected "); mpfr_print_binary (y); puts ("");
+ printf ("Got "); mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_prec (y, 206);
+ mpfr_set_str_binary (x, "0.110e10");
+ inex = mpfr_lngamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 206);
+ mpfr_set_str_binary (x, "0.10000111011000000011100010101001100110001110000111100011000100100110110010001011011110101001111011110110000001010100111011010000000011100110110101100111000111010011110010000100010111101010001101000110101001E13");
+ if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_lngamma (768)\n");
+ exit (1);
+ }
+ if (inex >= 0)
+ {
+ printf ("Wrong flag for mpfr_lngamma (768)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 4);
+ mpfr_set_prec (y, 4);
+ mpfr_set_str_binary (x, "0.1100E-66");
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1100E6");
+ if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
+ {
+ printf ("Error for lngamma(0.1100E-66)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 256);
+ mpfr_set_prec (y, 32);
+ mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN);
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ mpfr_div_2ui (x, x, 1, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 32);
+ mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207");
+ if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
+ {
+ printf ("Error for lngamma(-2^199+0.5)\n");
+ printf ("Got ");
+ mpfr_dump (y);
+ printf ("instead of ");
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 256);
+ mpfr_set_prec (y, 32);
+ mpfr_set_si_2exp (x, -1, 200, MPFR_RNDN);
+ mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+ mpfr_div_2ui (x, x, 1, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error for lngamma(-2^199-0.5)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+
+ special ();
+ test_generic (2, 100, 2);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tlog.c b/mpfr/tests/tlog.c
new file mode 100644
index 0000000000..f056d91f3f
--- /dev/null
+++ b/mpfr/tests/tlog.c
@@ -0,0 +1,361 @@
+/* Test file for mpfr_log.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_log (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ }
+ res = mpfr_log (a, b, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_log mpfr_log
+#endif
+
+static void
+check2 (const char *as, mpfr_rnd_t rnd_mode, const char *res1s)
+{
+ mpfr_t ta, tres;
+
+ mpfr_inits2 (53, ta, tres, (mpfr_ptr) 0);
+ mpfr_set_str1 (ta, as);
+ test_log (tres, ta, rnd_mode);
+
+ if (mpfr_cmp_str1 (tres, res1s))
+ {
+ printf ("mpfr_log failed for a=%s, rnd_mode=%s\n",
+ as, mpfr_print_rnd_mode (rnd_mode));
+ printf ("correct result is %s\n mpfr_log gives ",
+ res1s);
+ mpfr_out_str(stdout, 10, 0, tres, MPFR_RNDN);
+ exit (1);
+ }
+ mpfr_clears (ta, tres, (mpfr_ptr) 0);
+}
+
+static void
+check3 (double d, unsigned long prec, mpfr_rnd_t rnd)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, prec);
+ mpfr_init2 (y, prec);
+ mpfr_set_d (x, d, rnd);
+ test_log (y, x, rnd);
+ mpfr_out_str (stdout, 10, 0, y, rnd);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+/* examples from Jean-Michel Muller and Vincent Lefevre
+ Cf http://www.ens-lyon.fr/~jmmuller/Intro-to-TMD.htm
+*/
+
+static void
+check_worst_cases (void)
+{
+ check2("1.00089971802309629645", MPFR_RNDD, "8.99313519443722736088e-04");
+ check2("1.00089971802309629645", MPFR_RNDN, "8.99313519443722844508e-04");
+ check2("1.00089971802309629645", MPFR_RNDU, "8.99313519443722844508e-04");
+
+ check2("1.01979300812244555452", MPFR_RNDD, "1.95996734891603630047e-02");
+ check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02");
+ check2("1.01979300812244555452", MPFR_RNDU, "1.95996734891603664741e-02");
+
+ check2("1.02900871924604464525", MPFR_RNDD, "2.85959303301472726744e-02");
+ check2("1.02900871924604464525", MPFR_RNDN, "2.85959303301472761438e-02");
+ check2("1.02900871924604464525", MPFR_RNDU, "2.85959303301472761438e-02");
+
+ check2("1.27832870030418943585", MPFR_RNDD, "2.45553521871417795852e-01");
+ check2("1.27832870030418943585", MPFR_RNDN, "2.45553521871417823608e-01");
+ check2("1.27832870030418943585", MPFR_RNDU, "2.45553521871417823608e-01");
+
+ check2("1.31706530746788241792", MPFR_RNDD, "2.75406009586277422674e-01");
+ check2("1.31706530746788241792", MPFR_RNDN, "2.75406009586277478185e-01");
+ check2("1.31706530746788241792", MPFR_RNDU, "2.75406009586277478185e-01");
+
+ check2("1.47116981099449883885", MPFR_RNDD, "3.86057874110010412760e-01");
+ check2("1.47116981099449883885", MPFR_RNDN, "3.86057874110010412760e-01");
+ check2("1.47116981099449883885", MPFR_RNDU, "3.86057874110010468272e-01");
+
+ check2("1.58405446812987782401", MPFR_RNDD, "4.59987679246663727639e-01");
+ check2("1.58405446812987782401", MPFR_RNDN, "4.59987679246663783150e-01");
+ check2("1.58405446812987782401", MPFR_RNDU, "4.59987679246663783150e-01");
+
+ check2("1.67192331263391547047", MPFR_RNDD, "5.13974647961076613889e-01");
+ check2("1.67192331263391547047", MPFR_RNDN, "5.13974647961076724911e-01");
+ check2("1.67192331263391547047", MPFR_RNDU, "5.13974647961076724911e-01");
+
+ check2("1.71101198068990645318", MPFR_RNDD, "5.37084997042120315669e-01");
+ check2("1.71101198068990645318", MPFR_RNDN, "5.37084997042120315669e-01");
+ check2("1.71101198068990645318", MPFR_RNDU, "5.37084997042120426691e-01");
+
+ check2("1.72634853551388700588", MPFR_RNDD, "5.46008504786553605648e-01");
+ check2("1.72634853551388700588", MPFR_RNDN, "5.46008504786553716670e-01");
+ check2("1.72634853551388700588", MPFR_RNDU, "5.46008504786553716670e-01");
+
+ check2("2.00028876593004323325", MPFR_RNDD, "6.93291553102749702475e-01");
+ check2("2.00028876593004323325", MPFR_RNDN, "6.93291553102749813497e-01");
+ check2("2.00028876593004323325", MPFR_RNDU, "6.93291553102749813497e-01");
+
+ check2("6.27593230200363105808", MPFR_RNDD, "1.83672204800630312072");
+ check2("6.27593230200363105808", MPFR_RNDN, "1.83672204800630334276");
+ check2("6.27593230200363105808", MPFR_RNDU, "1.83672204800630334276");
+
+ check2("7.47216682321367997588", MPFR_RNDD, "2.01118502712453661729");
+ check2("7.47216682321367997588", MPFR_RNDN, "2.01118502712453706138");
+ check2("7.47216682321367997588", MPFR_RNDU, "2.01118502712453706138");
+
+ check2("9.34589857718275318632", MPFR_RNDD, "2.23493759221664944903");
+ check2("9.34589857718275318632", MPFR_RNDN, "2.23493759221664989312");
+ check2("9.34589857718275318632", MPFR_RNDU, "2.23493759221664989312");
+
+ check2("10.6856587560831854944", MPFR_RNDD, "2.36890253928838445674");
+ check2("10.6856587560831854944", MPFR_RNDN, "2.36890253928838445674");
+ check2("10.6856587560831854944", MPFR_RNDU, "2.36890253928838490083");
+
+ check2("12.4646345033981766903", MPFR_RNDD, "2.52289539471636015122");
+ check2("12.4646345033981766903", MPFR_RNDN, "2.52289539471636015122");
+ check2("12.4646345033981766903", MPFR_RNDU, "2.52289539471636059531");
+
+ check2("17.0953275851761752335", MPFR_RNDD, "2.83880518553861849185");
+ check2("17.0953275851761752335", MPFR_RNDN, "2.83880518553861893594");
+ check2("17.0953275851761752335", MPFR_RNDU, "2.83880518553861893594");
+
+ check2("19.8509496207496916043", MPFR_RNDD, "2.98825184582516722998");
+ check2("19.8509496207496916043", MPFR_RNDN, "2.98825184582516722998");
+ check2("19.8509496207496916043", MPFR_RNDU, "2.98825184582516767406");
+
+ check2("23.9512076062771335216", MPFR_RNDD, "3.17601874455977206679");
+ check2("23.9512076062771335216", MPFR_RNDN, "3.17601874455977206679");
+ check2("23.9512076062771335216", MPFR_RNDU, "3.17601874455977251088");
+
+ check2("428.315247165198229595", MPFR_RNDD, "6.05985948325268264369");
+ check2("428.315247165198229595", MPFR_RNDN, "6.05985948325268353187");
+ check2("428.315247165198229595", MPFR_RNDU, "6.05985948325268353187");
+}
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int inex;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+
+ /* Check special case: An overflow in const_pi could occurs! */
+ set_emin (-125);
+ set_emax (128);
+ mpfr_set_prec (y, 24*2);
+ mpfr_set_prec (x, 24);
+ mpfr_set_str_binary (x, "0.111110101010101011110101E0");
+ test_log (y, x, MPFR_RNDN);
+ set_emin (emin);
+ set_emax (emax);
+
+ mpfr_set_prec (y, 53);
+ mpfr_set_prec (x, 53);
+ mpfr_set_ui (x, 3, MPFR_RNDD);
+ test_log (y, x, MPFR_RNDD);
+ if (mpfr_cmp_str1 (y, "1.09861228866810956"))
+ {
+ printf ("Error in mpfr_log(3) for MPFR_RNDD\n");
+ exit (1);
+ }
+
+ /* check large precision */
+ mpfr_set_prec (x, 3322);
+ mpfr_set_prec (y, 3322);
+ mpfr_set_ui (x, 3, MPFR_RNDN);
+ mpfr_sqrt (x, x, MPFR_RNDN);
+ test_log (y, x, MPFR_RNDN);
+
+ /* negative argument */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ test_log (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ /* infinite loop when */
+ set_emax (128);
+ mpfr_set_prec (x, 251);
+ mpfr_set_prec (y, 251);
+ mpfr_set_str_binary (x, "0.10010111000000000001101E8");
+ /* x = 4947981/32768, log(x) ~ 5.017282... */
+ test_log (y, x, MPFR_RNDN);
+
+ set_emax (emax);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inex = test_log (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (mpfr_sgn (y) < 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ inex = test_log (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (mpfr_sgn (y) < 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+x_near_one (void)
+{
+ mpfr_t x, y;
+ int inex;
+
+ mpfr_init2 (x, 32);
+ mpfr_init2 (y, 16);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_nextbelow (x);
+ inex = mpfr_log (y, x, MPFR_RNDD);
+ if (mpfr_cmp_str (y, "-0.1000000000000001E-31", 2, MPFR_RNDN)
+ || inex >= 0)
+ {
+ printf ("Failure in x_near_one, got inex = %d and\ny = ", inex);
+ mpfr_dump (y);
+ }
+
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+#define TEST_FUNCTION test_log
+#define TEST_RANDOM_POS 8
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ if (argc==4)
+ { /* tlog x prec rnd */
+ check3 (atof(argv[1]), atoi(argv[2]), (mpfr_rnd_t) atoi(argv[3]));
+ goto done;
+ }
+
+ special ();
+ check_worst_cases();
+
+ check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02");
+ check2("10.0",MPFR_RNDU,"2.30258509299404590110e+00");
+ check2("6.0",MPFR_RNDU,"1.79175946922805517936");
+ check2("1.0",MPFR_RNDZ,"0.0");
+ check2("62.0",MPFR_RNDU,"4.12713438504509166905");
+ check2("0.5",MPFR_RNDZ,"-6.93147180559945286226e-01");
+ check2("3.0",MPFR_RNDZ,"1.09861228866810956006e+00");
+ check2("234375765.0",MPFR_RNDU,"1.92724362186836231104e+01");
+ check2("8.0",MPFR_RNDZ,"2.07944154167983574765e+00");
+ check2("44.0",MPFR_RNDU,"3.78418963391826146392e+00");
+ check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02");
+
+ /* bugs found by Vincent Lefe`vre */
+ check2("0.99999599881598921769", MPFR_RNDN, "-0.0000040011920155404072924737977900999652547398000024259090423583984375");
+ check2("9.99995576063808955247e-01",MPFR_RNDZ,"-4.42394597667932383816e-06");
+ check2("9.99993687357856209097e-01",MPFR_RNDN,"-6.31266206860017342601e-06");
+ check2("9.99995223520736886691e-01",MPFR_RNDN,"-4.77649067052670982220e-06");
+ check2("9.99993025794720935551e-01",MPFR_RNDN,"-6.97422959894716163837e-06");
+ check2("9.99987549017837484833e-01",MPFR_RNDN,"-1.24510596766369924330e-05");
+ check2("9.99985901426543311032e-01",MPFR_RNDN,"-1.40986728425098585229e-05");
+ check2("9.99986053947420794330e-01",MPFR_RNDN, "-0.000013946149826301084938555592540598837558718514628708362579345703125");
+ check2("9.99971938247442126979e-01",MPFR_RNDN,"-2.80621462962173414790e-05");
+
+ /* other bugs found by Vincent Lefe`vre */
+ check2("1.18615436389927785905e+77",MPFR_RNDN,"1.77469768607706015473e+02");
+ check2("9.48868723578399476187e+77",MPFR_RNDZ,"1.79549152432275803903e+02");
+ check2("2.31822210096938820854e+89",MPFR_RNDN,"2.05770873832573869322e+02");
+
+ /* further bugs found by Vincent Lefe`vre */
+ check2("9.99999989485669482647e-01",MPFR_RNDZ,"-1.05143305726283042331e-08");
+ check2("9.99999989237970177136e-01",MPFR_RNDZ,"-1.07620298807745377934e-08");
+ check2("9.99999989239339082125e-01",MPFR_RNDN,"-1.07606609757704445430e-08");
+
+ check2("7.3890560989306504",MPFR_RNDU,"2.0000000000000004"); /* exp(2.0) */
+ check2("7.3890560989306495",MPFR_RNDU,"2.0"); /* exp(2.0) */
+ check2("7.53428236571286402512e+34",MPFR_RNDZ,"8.03073567492226345621e+01");
+ check2("6.18784121531737948160e+19",MPFR_RNDZ,"4.55717030391710693493e+01");
+ check2("1.02560267603047283735e+00",MPFR_RNDD,"2.52804164149448735987e-02");
+ check2("7.53428236571286402512e+34",MPFR_RNDZ,"8.03073567492226345621e+01");
+ check2("1.42470900831881198052e+49",MPFR_RNDZ,"113.180637144887668910087086260318756103515625");
+
+ check2("1.08013816255293777466e+11",MPFR_RNDN,"2.54055249841782604392e+01");
+ check2("6.72783635300509015581e-37",MPFR_RNDU,"-8.32893948416799503320e+01");
+ check2("2.25904918906057891180e-52",MPFR_RNDU,"-1.18919480823735682406e+02");
+ check2("1.48901209246462951085e+00",MPFR_RNDD,"3.98112874867437460668e-01");
+ check2("1.70322470467612341327e-01",MPFR_RNDN,"-1.77006175364294615626");
+ check2("1.94572026316065240791e+01",MPFR_RNDD,"2.96821731676437838842");
+ check2("4.01419512207026418764e+04",MPFR_RNDD,"1.06001772315501128218e+01");
+ check2("9.47077365236487591672e-04",MPFR_RNDZ,"-6.96212977303956748187e+00");
+ check2("3.95906157687589643802e-109",MPFR_RNDD,"-2.49605768114704119399e+02");
+ check2("2.73874914516503004113e-02",MPFR_RNDD,"-3.59766888618655977794e+00");
+ check2("9.18989072589566467669e-17",MPFR_RNDZ,"-3.69258425351464083519e+01");
+ check2("7706036453608191045959753324430048151991964994788917248.0",MPFR_RNDZ,"126.3815989984199177342816255986690521240234375");
+ check2("1.74827399630587801934e-23",MPFR_RNDZ,"-5.24008281254547156891e+01");
+ check2("4.35302958401482307665e+22",MPFR_RNDD,"5.21277441046519527390e+01");
+ check2("9.70791868689332915209e+00",MPFR_RNDD,"2.27294191194272210410e+00");
+ check2("2.22183639799464011100e-01",MPFR_RNDN,"-1.50425103275253957413e+00");
+ check2("2.27313466156682375540e+00",MPFR_RNDD,"8.21159787095675608448e-01");
+ check2("6.58057413965851156767e-01",MPFR_RNDZ,"-4.18463096196088235600e-01");
+ check2 ("7.34302197248998461006e+43",MPFR_RNDZ,"101.0049094695131799426235374994575977325439453125");
+ check2("6.09969788341579732815e+00",MPFR_RNDD,"1.80823924264386204363e+00");
+
+ x_near_one ();
+
+ test_generic (2, 100, 40);
+
+ data_check ("data/log", mpfr_log, "mpfr_log");
+ bad_cases (mpfr_log, mpfr_exp, "mpfr_log", 256, -30, 30, 4, 128, 800, 50);
+
+ done:
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tlog10.c b/mpfr/tests/tlog10.c
new file mode 100644
index 0000000000..eb8a587a45
--- /dev/null
+++ b/mpfr/tests/tlog10.c
@@ -0,0 +1,122 @@
+/* Test file for mpfr_log10.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_log10 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ }
+ res = mpfr_log10 (a, b, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_log10 mpfr_log10
+#endif
+
+#define TEST_FUNCTION test_log10
+#define TEST_RANDOM_POS 8
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ unsigned int n;
+ int inex;
+
+ tests_start_mpfr ();
+
+ test_generic (2, 100, 20);
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+
+ /* check NaN */
+ mpfr_set_nan (x);
+ inex = test_log10 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0);
+
+ /* check Inf */
+ mpfr_set_inf (x, -1);
+ inex = test_log10 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0);
+
+ mpfr_set_inf (x, 1);
+ inex = test_log10 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0 && inex == 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inex = test_log10 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ inex = test_log10 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0);
+
+ /* check negative argument */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ inex = test_log10 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0);
+
+ /* check log10(1) = 0 */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ inex = test_log10 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y) && inex == 0);
+
+ /* check log10(10^n)=n */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ for (n = 1; n <= 15; n++)
+ {
+ mpfr_mul_ui (x, x, 10, MPFR_RNDN); /* x = 10^n */
+ inex = test_log10 (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, n))
+ {
+ printf ("log10(10^n) <> n for n=%u\n", n);
+ exit (1);
+ }
+ MPFR_ASSERTN (inex == 0);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ data_check ("data/log10", mpfr_log10, "mpfr_log10");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tlog1p.c b/mpfr/tests/tlog1p.c
new file mode 100644
index 0000000000..7c6320ea28
--- /dev/null
+++ b/mpfr/tests/tlog1p.c
@@ -0,0 +1,150 @@
+/* Test file for mpfr_log1p.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_log1p (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ }
+ res = mpfr_log1p (a, b, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_log1p mpfr_log1p
+#endif
+
+#define TEST_FUNCTION test_log1p
+#define TEST_RANDOM_EMAX 80
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x;
+ int inex;
+
+ mpfr_init (x);
+
+ mpfr_set_nan (x);
+ mpfr_clear_flags ();
+ inex = test_log1p (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+
+ mpfr_set_inf (x, -1);
+ mpfr_clear_flags ();
+ inex = test_log1p (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+
+ mpfr_set_inf (x, 1);
+ mpfr_clear_flags ();
+ inex = test_log1p (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) > 0 && inex == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = test_log1p (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS (x) && inex == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = test_log1p (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG (x) && inex == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = test_log1p (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+
+ mpfr_set_si (x, -2, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = test_log1p (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+
+ mpfr_clear (x);
+}
+
+static void
+other (void)
+{
+ mpfr_t x, y;
+
+ /* Bug reported by Guillaume Melquiond on 2006-08-14. */
+ mpfr_init2 (x, 53);
+ mpfr_set_str (x, "-1.5e4f72873ed9a@-100", 16, MPFR_RNDN);
+ mpfr_init2 (y, 57);
+ mpfr_log1p (y, x, MPFR_RNDU);
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error in tlog1p for x = ");
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ printf (", rnd = MPFR_RNDU\nExpected ");
+ mpfr_out_str (stdout, 16, 15, x, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 16, 15, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+ return;
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+ other ();
+
+ test_generic (2, 100, 50);
+
+ data_check ("data/log1p", mpfr_log1p, "mpfr_log1p");
+ bad_cases (mpfr_log1p, mpfr_expm1, "mpfr_log1p", 256, -64, 40,
+ 4, 128, 800, 40);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tlog2.c b/mpfr/tests/tlog2.c
new file mode 100644
index 0000000000..b64c809781
--- /dev/null
+++ b/mpfr/tests/tlog2.c
@@ -0,0 +1,84 @@
+/* Test file for mpfr_log2.
+
+Copyright 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_log2
+#define TEST_RANDOM_POS 8
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x;
+ int inex;
+
+ mpfr_init (x);
+
+ mpfr_set_nan (x);
+ inex = mpfr_log2 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0);
+
+ mpfr_set_inf (x, -1);
+ inex = mpfr_log2 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0);
+
+ mpfr_set_inf (x, 1);
+ inex = mpfr_log2 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) > 0 && inex == 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inex = mpfr_log2 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ inex = mpfr_log2 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0);
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ inex = mpfr_log2 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (x) && inex == 0);
+
+ mpfr_set_si (x, 1, MPFR_RNDN);
+ inex = mpfr_log2 (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x) && inex == 0);
+
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+
+ test_generic (2, 100, 30);
+
+ data_check ("data/log2", mpfr_log2, "mpfr_log2");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tmin_prec.c b/mpfr/tests/tmin_prec.c
new file mode 100644
index 0000000000..451504b02d
--- /dev/null
+++ b/mpfr/tests/tmin_prec.c
@@ -0,0 +1,102 @@
+/* Test file for mpfr_min_prec.
+
+Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x;
+ mpfr_prec_t ret;
+ unsigned long i;
+
+ tests_start_mpfr ();
+
+ mpfr_init2 (x, 53);
+
+ /* Check special values */
+ mpfr_set_nan (x);
+ ret = mpfr_min_prec (x);
+ MPFR_ASSERTN (ret == 0);
+
+ mpfr_set_inf (x, 1);
+ ret = mpfr_min_prec (x);
+ MPFR_ASSERTN (ret == 0);
+
+ mpfr_set_inf (x, -1);
+ ret = mpfr_min_prec (x);
+ MPFR_ASSERTN (ret == 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ ret = mpfr_min_prec (x);
+ MPFR_ASSERTN (ret == 0);
+
+ /* Some constants */
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ ret = mpfr_min_prec (x);
+ MPFR_ASSERTN (ret == 1);
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ ret = mpfr_min_prec (x);
+ MPFR_ASSERTN (ret == 5);
+
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ ret = mpfr_min_prec (x);
+ MPFR_ASSERTN (ret == 5);
+
+ mpfr_set_prec (x, 256);
+ for (i = 0; i <= 255; i++)
+ {
+ mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN);
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ ret = mpfr_min_prec (x);
+ if (ret != i + 1)
+ {
+ printf ("Error for x = 2^%lu + 1\n", i);
+ printf ("Expected %lu, got %lu\n", i + 1, (unsigned long) ret);
+ exit (1);
+ }
+ }
+
+ for (i = MPFR_PREC_MIN; i <= 255; i++)
+ {
+ mpfr_set_prec (x, i);
+ mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN);
+ mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+ ret = mpfr_min_prec (x);
+ if (ret != i)
+ {
+ printf ("Error for x = 2^%lu - 1\n", i);
+ printf ("Expected %lu, got %lu\n", i, (unsigned long) ret);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tminmax.c b/mpfr/tests/tminmax.c
new file mode 100644
index 0000000000..cdd9b4aab4
--- /dev/null
+++ b/mpfr/tests/tminmax.c
@@ -0,0 +1,171 @@
+/* Test file for mpfr_min & mpfr_max.
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ mpfr_t x, y, z;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ /* case x=NaN && y=NAN */
+ mpfr_set_nan (x);
+ mpfr_set_nan (y);
+ mpfr_min (z, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (z))
+ {
+ printf ("Error in mpfr_min (NaN, NaN)\n");
+ exit (1);
+ }
+ mpfr_max (z, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (z))
+ {
+ printf ("Error in mpfr_max (NaN, NaN)\n");
+ exit (1);
+ }
+ /* case x=NaN */
+ mpfr_set_nan (x);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_min (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 0))
+ {
+ printf ("Error in mpfr_min (NaN, 0)\n");
+ exit (1);
+ }
+ mpfr_min (z, y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 0))
+ {
+ printf ("Error in mpfr_min (0, NaN)\n");
+ exit (1);
+ }
+ mpfr_max (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 0))
+ {
+ printf ("Error in mpfr_max (NaN, 0)\n");
+ exit (1);
+ }
+ mpfr_max (z, y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 0))
+ {
+ printf ("Error in mpfr_max (0, NaN)\n");
+ exit (1);
+ }
+ /* Case x=0+ and x=0- */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_ui (y, 0, MPFR_RNDN); MPFR_SET_NEG(y);
+ mpfr_max (z, x, y, MPFR_RNDN);
+ if (!MPFR_IS_ZERO(z) || MPFR_IS_NEG(z))
+ {
+ printf ("Error in mpfr_max (0+, 0-)\n");
+ exit (1);
+ }
+ mpfr_min (z, x, y, MPFR_RNDN);
+ if (!MPFR_IS_ZERO(z) || MPFR_IS_POS(z))
+ {
+ printf ("Error in mpfr_min (0+, 0-)\n");
+ exit (1);
+ }
+ /* Case x=0- and y=0+ */
+ mpfr_set_ui (x, 0, MPFR_RNDN); MPFR_SET_NEG(x);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_max (z, x, y, MPFR_RNDN);
+ if (!MPFR_IS_ZERO(z) || MPFR_IS_NEG(z))
+ {
+ printf ("Error in mpfr_max (0+, 0-)\n");
+ exit (1);
+ }
+ mpfr_min (z, x, y, MPFR_RNDN);
+ if (!MPFR_IS_ZERO(z) || MPFR_IS_POS(z))
+ {
+ printf ("Error in mpfr_min (0+, 0-)\n");
+ exit (1);
+ }
+
+ /* case x=+Inf */
+ mpfr_set_inf (x, 1);
+ mpfr_set_si (y, -12, MPFR_RNDN);
+ mpfr_min (z, x, y, MPFR_RNDN);
+ if ( mpfr_cmp_si (z, -12) )
+ {
+ printf ("Error in mpfr_min (+Inf, -12)\n");
+ exit (1);
+ }
+ mpfr_max (z, x, y, MPFR_RNDN);
+ if ( !MPFR_IS_INF(z) || MPFR_IS_NEG(z) )
+ {
+ printf ("Error in mpfr_max (+Inf, 12)\n");
+ exit (1);
+ }
+ /* case x=-Inf */
+ mpfr_set_inf (x, -1);
+ mpfr_set_ui (y, 12, MPFR_RNDN);
+ mpfr_max (z, x, y, MPFR_RNDN);
+ if ( mpfr_cmp_ui (z, 12) )
+ {
+ printf ("Error in mpfr_max (-Inf, 12)\n");
+ exit (1);
+ }
+ mpfr_min (z, x, y, MPFR_RNDN);
+ if ( !MPFR_IS_INF(z) || MPFR_IS_POS(z) )
+ {
+ printf ("Error in mpfr_min (-Inf, 12)\n");
+ exit (1);
+ }
+
+ /* case x=17 and y=42 */
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_set_ui (y, 42, MPFR_RNDN);
+ mpfr_max (z, x, y, MPFR_RNDN);
+ if ( mpfr_cmp_ui (z, 42) )
+ {
+ printf ("Error in mpfr_max (17, 42)\n");
+ exit (1);
+ }
+ mpfr_max (z, y, x, MPFR_RNDN);
+ if ( mpfr_cmp_ui (z, 42) )
+ {
+ printf ("Error in mpfr_max (42, 17)\n");
+ exit (1);
+ }
+ mpfr_min (z, y, x, MPFR_RNDN);
+ if ( mpfr_cmp_ui (z, 17) )
+ {
+ printf ("Error in mpfr_min (42, 17)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tmodf.c b/mpfr/tests/tmodf.c
new file mode 100644
index 0000000000..c89ade81b4
--- /dev/null
+++ b/mpfr/tests/tmodf.c
@@ -0,0 +1,236 @@
+/* Test file for mpfr_modf.
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+static void
+check (const char *xis, const char *xfs, const char *xs,
+ mpfr_prec_t xip, mpfr_prec_t xfp, mpfr_prec_t xp,
+ int expected_return, mpfr_rnd_t rnd_mode)
+{
+ int inexact;
+ mpfr_t xi, xf, x;
+
+ mpfr_init2 (xi, xip);
+ mpfr_init2 (xf, xfp);
+ mpfr_init2 (x, xp);
+ mpfr_set_str1 (x, xs);
+ inexact = mpfr_modf (xi, xf, x, rnd_mode);
+ if (mpfr_cmp_str1 (xi, xis))
+ {
+ printf ("mpfr_modf failed for x=%s, rnd=%s\n",
+ xs, mpfr_print_rnd_mode(rnd_mode));
+ printf ("got integer value: ");
+ mpfr_out_str (stdout, 10, 0, xi, MPFR_RNDN);
+ printf ("\nexpected %s\n", xis);
+ exit (1);
+ }
+ if (mpfr_cmp_str1 (xf, xfs))
+ {
+ printf ("mpfr_modf failed for x=%s, rnd=%s\n",
+ xs, mpfr_print_rnd_mode(rnd_mode));
+ printf ("got fractional value: ");
+ mpfr_out_str (stdout, 10, 0, xf, MPFR_RNDN);
+ printf ("\nexpected %s\n", xfs);
+ exit (1);
+ }
+ if (inexact != expected_return)
+ {
+ printf ("mpfr_modf failed for x=%s, rnd=%s\n",
+ xs, mpfr_print_rnd_mode(rnd_mode));
+ printf ("got return value: %d, expected %d\n", inexact, expected_return);
+ exit (1);
+ }
+ mpfr_clears (xi, xf, x, (mpfr_ptr) 0);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t x, xi, xf;
+
+ mpfr_init2 (x, 123);
+ mpfr_init2 (xi, 123);
+ mpfr_init2 (xf, 123);
+
+ /* nan */
+ mpfr_set_nan (x);
+ mpfr_modf (xi, xf, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (xi));
+ MPFR_ASSERTN (mpfr_nan_p (xf));
+
+ /* +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_modf (xi, xf, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (xi));
+ MPFR_ASSERTN (mpfr_sgn (xi) > 0);
+ MPFR_ASSERTN (mpfr_zero_p (xf));
+
+ /* -inf */
+ mpfr_set_inf (x, -1);
+ mpfr_modf (xi ,xf, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (xi));
+ MPFR_ASSERTN (mpfr_sgn (xi) < 0);
+ MPFR_ASSERTN (mpfr_zero_p (xf));
+
+ mpfr_clear (x);
+ mpfr_clear (xi);
+ mpfr_clear (xf);
+}
+
+static void
+check_special_exprange (void)
+{
+ int inexact, ov;
+ unsigned int eflags, gflags;
+ mpfr_t xi, xf, x;
+ mpfr_exp_t emax;
+
+ emax = mpfr_get_emax ();
+ mpfr_init2 (xi, 7);
+ mpfr_init2 (xf, 7);
+ mpfr_init2 (x, 8);
+
+ mpfr_set_str (x, "0.11111111", 2, MPFR_RNDN);
+ for (ov = 0; ov <= 1; ov++)
+ {
+ const char *s = ov ? "@Inf@" : "1";
+
+ if (ov)
+ set_emax (0);
+ mpfr_clear_flags ();
+ inexact = mpfr_modf (xi, xf, x, MPFR_RNDN);
+ gflags = __gmpfr_flags;
+ set_emax (emax);
+ if (MPFR_NOTZERO (xi) || MPFR_IS_NEG (xi) ||
+ mpfr_cmp_str1 (xf, s) != 0)
+ {
+ printf ("Error in check_special_exprange (ov = %d):"
+ " expected 0 and %s, got\n", ov, s);
+ mpfr_out_str (stdout, 2, 0, xi, MPFR_RNDN);
+ printf (" and ");
+ mpfr_out_str (stdout, 2, 0, xf, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ if (inexact != 4)
+ {
+ printf ("Bad inexact value in check_special_exprange (ov = %d):"
+ " expected 4, got %d\n", ov, inexact);
+ exit (1);
+ }
+ eflags = MPFR_FLAGS_INEXACT | (ov ? MPFR_FLAGS_OVERFLOW : 0);
+ if (gflags != eflags)
+ {
+ printf ("Bad flags in check_special_exprange (ov = %d):"
+ " expected %u, got %u\n", ov, eflags, gflags);
+ exit (1);
+ }
+ }
+
+ /* Test if an overflow occurs in mpfr_set for ope >= opq. */
+ mpfr_set_emax (MPFR_EMAX_MAX);
+ mpfr_set_inf (x, 1);
+ mpfr_nextbelow (x);
+ mpfr_clear_flags ();
+ inexact = mpfr_modf (xi, xf, x, MPFR_RNDN);
+ gflags = __gmpfr_flags;
+ if (mpfr_cmp_str1 (xi, "@Inf@") != 0 ||
+ MPFR_NOTZERO (xf) || MPFR_IS_NEG (xf))
+ {
+ printf ("Error in check_special_exprange:"
+ " expected 0 and @Inf@, got\n");
+ mpfr_out_str (stdout, 2, 0, xi, MPFR_RNDN);
+ printf (" and ");
+ mpfr_out_str (stdout, 2, 0, xf, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ if (inexact != 1)
+ {
+ printf ("Bad inexact value in check_special_exprange:"
+ " expected 1, got %d\n", inexact);
+ exit (1);
+ }
+ eflags = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
+ if (gflags != eflags)
+ {
+ printf ("Bad flags in check_special_exprange:"
+ " expected %u, got %u\n", eflags, gflags);
+ exit (1);
+ }
+ set_emax (emax);
+
+ /* Test if an underflow occurs in the general case. TODO */
+
+ mpfr_clears (xi, xf, x, (mpfr_ptr) 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_nans ();
+
+ /* integer part is exact, frac. part is exact: return value should be 0 */
+ check ("61680","3.52935791015625e-1", "61680.352935791015625",
+ 53, 53, 53, 0, MPFR_RNDZ);
+ /* integer part is rounded up, fractional part is rounded up: return value
+ should be 1+4*1=5 */
+ check ("-53968","-3.529052734375e-1", "-53970.352935791015625",
+ 13, 13, 53, 5, MPFR_RNDZ);
+ /* integer part is rounded down, fractional part is rounded down:
+ return value should be 2+4*2=10 */
+ check ("61632","3.525390625e-1", "61648.352935791015625",
+ 10, 10, 53, 10, MPFR_RNDZ);
+ check ("61680", "0", "61680", 53, 53, 53, 0, MPFR_RNDZ);
+ /* integer part is rounded up, fractional part is exact: 1 */
+ check ("-53968","0", "-53970", 13, 13, 53, 1, MPFR_RNDZ);
+ /* integer part is rounded up, fractional part is exact: 1 */
+ check ("-43392","0", "-43399", 13, 13, 53, 1, MPFR_RNDU);
+ /* integer part is rounded down, fractional part is exact: 2 */
+ check ("-52720","0", "-52719", 13, 13, 53, 2, MPFR_RNDD);
+ /* integer part is rounded down, fractional part is exact: 2 */
+ check ("61632", "0", "61648", 10, 10, 53, 2, MPFR_RNDZ);
+
+ check_special_exprange ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tmul.c b/mpfr/tests/tmul.c
new file mode 100644
index 0000000000..fa5f158ac6
--- /dev/null
+++ b/mpfr/tests/tmul.c
@@ -0,0 +1,697 @@
+/* Test file for mpfr_mul.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ printf (" ");
+ mpfr_print_raw (c);
+ }
+ res = mpfr_mul (a, b, c, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_mul mpfr_mul
+#endif
+
+/* checks that xs * ys gives the expected result res */
+static void
+check (const char *xs, const char *ys, mpfr_rnd_t rnd_mode,
+ unsigned int px, unsigned int py, unsigned int pz, const char *res)
+{
+ mpfr_t xx, yy, zz;
+
+ mpfr_init2 (xx, px);
+ mpfr_init2 (yy, py);
+ mpfr_init2 (zz, pz);
+ mpfr_set_str1 (xx, xs);
+ mpfr_set_str1 (yy, ys);
+ test_mul(zz, xx, yy, rnd_mode);
+ if (mpfr_cmp_str1 (zz, res) )
+ {
+ printf ("(1)mpfr_mul failed for x=%s y=%s with rnd=%s\n",
+ xs, ys, mpfr_print_rnd_mode (rnd_mode));
+ printf ("correct is %s, mpfr_mul gives ", res);
+ mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
+ /*
+ printf("\nBinary forms:\nxx=");
+ mpfr_print_binary (xx);
+ printf("\nyy=");
+ mpfr_print_binary (yy);
+ printf("\nzz=");
+ mpfr_print_binary(zz);
+ printf("\nre=");
+ mpfr_set_str1 (zz, res);
+ mpfr_print_binary(zz);
+ putchar('\n');*/
+ exit (1);
+ }
+ mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
+}
+
+static void
+check53 (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, const char *zs)
+{
+ mpfr_t xx, yy, zz;
+
+ mpfr_inits2 (53, xx, yy, zz, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs);
+ mpfr_set_str1 (yy, ys);
+ test_mul (zz, xx, yy, rnd_mode);
+ if (mpfr_cmp_str1 (zz, zs) )
+ {
+ printf ("(2) mpfr_mul failed for x=%s y=%s with rnd=%s\n",
+ xs, ys, mpfr_print_rnd_mode(rnd_mode));
+ printf ("correct result is %s,\n mpfr_mul gives ", zs);
+ mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
+ /*
+ printf("\nBinary forms:\nxx=");
+ mpfr_print_binary (xx);
+ printf("\nyy=");
+ mpfr_print_binary (yy);
+ printf("\nzz=");
+ mpfr_print_binary(zz);
+ printf("\nre=");
+ mpfr_set_str1 (zz, zs);
+ mpfr_print_binary(zz);
+ putchar('\n'); */
+ exit (1);
+ }
+ mpfr_clears (xx, yy, zz, (mpfr_ptr) 0);
+}
+
+/* checks that x*y gives the right result with 24 bits of precision */
+static void
+check24 (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, const char *zs)
+{
+ mpfr_t xx, yy, zz;
+
+ mpfr_inits2 (24, xx, yy, zz, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs);
+ mpfr_set_str1 (yy, ys);
+ test_mul (zz, xx, yy, rnd_mode);
+ if (mpfr_cmp_str1 (zz, zs) )
+ {
+ printf ("(3) mpfr_mul failed for x=%s y=%s with "
+ "rnd=%s\n", xs, ys, mpfr_print_rnd_mode(rnd_mode));
+ printf ("correct result is gives %s, mpfr_mul gives ", zs);
+ mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
+ putchar('\n');
+ exit (1);
+ }
+ mpfr_clears (xx, yy, zz, (mpfr_ptr) 0);
+}
+
+/* the following examples come from the paper "Number-theoretic Test
+ Generation for Directed Rounding" from Michael Parks, Table 1 */
+static void
+check_float (void)
+{
+ check24("8388609.0", "8388609.0", MPFR_RNDN, "70368760954880.0");
+ check24("16777213.0", "8388609.0", MPFR_RNDN, "140737479966720.0");
+ check24("8388611.0", "8388609.0", MPFR_RNDN, "70368777732096.0");
+ check24("12582911.0", "8388610.0", MPFR_RNDN, "105553133043712.0");
+ check24("12582914.0", "8388610.0", MPFR_RNDN, "105553158209536.0");
+ check24("13981013.0", "8388611.0", MPFR_RNDN, "117281279442944.0");
+ check24("11184811.0", "8388611.0", MPFR_RNDN, "93825028587520.0");
+ check24("11184810.0", "8388611.0", MPFR_RNDN, "93825020198912.0");
+ check24("13981014.0", "8388611.0", MPFR_RNDN, "117281287831552.0");
+
+ check24("8388609.0", "8388609.0", MPFR_RNDZ, "70368760954880.0");
+ check24("16777213.0", "8388609.0", MPFR_RNDZ, "140737471578112.0");
+ check24("8388611.0", "8388609.0", MPFR_RNDZ, "70368777732096.0");
+ check24("12582911.0", "8388610.0", MPFR_RNDZ, "105553124655104.0");
+ check24("12582914.0", "8388610.0", MPFR_RNDZ, "105553158209536.0");
+ check24("13981013.0", "8388611.0", MPFR_RNDZ, "117281271054336.0");
+ check24("11184811.0", "8388611.0", MPFR_RNDZ, "93825028587520.0");
+ check24("11184810.0", "8388611.0", MPFR_RNDZ, "93825011810304.0");
+ check24("13981014.0", "8388611.0", MPFR_RNDZ, "117281287831552.0");
+
+ check24("8388609.0", "8388609.0", MPFR_RNDU, "70368769343488.0");
+ check24("16777213.0", "8388609.0", MPFR_RNDU, "140737479966720.0");
+ check24("8388611.0", "8388609.0", MPFR_RNDU, "70368786120704.0");
+ check24("12582911.0", "8388610.0", MPFR_RNDU, "105553133043712.0");
+ check24("12582914.0", "8388610.0", MPFR_RNDU, "105553166598144.0");
+ check24("13981013.0", "8388611.0", MPFR_RNDU, "117281279442944.0");
+ check24("11184811.0", "8388611.0", MPFR_RNDU, "93825036976128.0");
+ check24("11184810.0", "8388611.0", MPFR_RNDU, "93825020198912.0");
+ check24("13981014.0", "8388611.0", MPFR_RNDU, "117281296220160.0");
+
+ check24("8388609.0", "8388609.0", MPFR_RNDD, "70368760954880.0");
+ check24("16777213.0", "8388609.0", MPFR_RNDD, "140737471578112.0");
+ check24("8388611.0", "8388609.0", MPFR_RNDD, "70368777732096.0");
+ check24("12582911.0", "8388610.0", MPFR_RNDD, "105553124655104.0");
+ check24("12582914.0", "8388610.0", MPFR_RNDD, "105553158209536.0");
+ check24("13981013.0", "8388611.0", MPFR_RNDD, "117281271054336.0");
+ check24("11184811.0", "8388611.0", MPFR_RNDD, "93825028587520.0");
+ check24("11184810.0", "8388611.0", MPFR_RNDD, "93825011810304.0");
+ check24("13981014.0", "8388611.0", MPFR_RNDD, "117281287831552.0");
+}
+
+/* check sign of result */
+static void
+check_sign (void)
+{
+ mpfr_t a, b;
+
+ mpfr_init2 (a, 53);
+ mpfr_init2 (b, 53);
+ mpfr_set_si (a, -1, MPFR_RNDN);
+ mpfr_set_ui (b, 2, MPFR_RNDN);
+ test_mul(a, b, b, MPFR_RNDN);
+ if (mpfr_cmp_ui (a, 4) )
+ {
+ printf ("2.0*2.0 gives \n");
+ mpfr_out_str(stdout, 10, 0, a, MPFR_RNDN);
+ putchar('\n');
+ exit (1);
+ }
+ mpfr_clear(a); mpfr_clear(b);
+}
+
+/* checks that the inexact return value is correct */
+static void
+check_exact (void)
+{
+ mpfr_t a, b, c, d;
+ mpfr_prec_t prec;
+ int i, inexact;
+ mpfr_rnd_t rnd;
+
+ mpfr_init (a);
+ mpfr_init (b);
+ mpfr_init (c);
+ mpfr_init (d);
+
+ mpfr_set_prec (a, 17);
+ mpfr_set_prec (b, 17);
+ mpfr_set_prec (c, 32);
+ mpfr_set_str_binary (a, "1.1000111011000100e-1");
+ mpfr_set_str_binary (b, "1.0010001111100111e-1");
+ if (test_mul (c, a, b, MPFR_RNDZ))
+ {
+ printf ("wrong return value (1)\n");
+ exit (1);
+ }
+
+ for (prec = 2; prec < 100; prec++)
+ {
+ mpfr_set_prec (a, prec);
+ mpfr_set_prec (b, prec);
+ mpfr_set_prec (c, 2 * prec - 2);
+ mpfr_set_prec (d, 2 * prec);
+ for (i = 0; i < 1000; i++)
+ {
+ mpfr_urandomb (a, RANDS);
+ mpfr_urandomb (b, RANDS);
+ rnd = RND_RAND ();
+ inexact = test_mul (c, a, b, rnd);
+ if (test_mul (d, a, b, rnd)) /* should be always exact */
+ {
+ printf ("unexpected inexact return value\n");
+ exit (1);
+ }
+ if ((inexact == 0) && mpfr_cmp (c, d))
+ {
+ printf ("inexact=0 but results differ\n");
+ exit (1);
+ }
+ else if (inexact && (mpfr_cmp (c, d) == 0))
+ {
+ printf ("inexact!=0 but results agree\n");
+ printf ("prec=%u rnd=%s a=", (unsigned int) prec,
+ mpfr_print_rnd_mode (rnd));
+ mpfr_out_str (stdout, 2, 0, a, rnd);
+ printf ("\nb=");
+ mpfr_out_str (stdout, 2, 0, b, rnd);
+ printf ("\nc=");
+ mpfr_out_str (stdout, 2, 0, c, rnd);
+ printf ("\nd=");
+ mpfr_out_str (stdout, 2, 0, d, rnd);
+ printf ("\n");
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+ mpfr_clear (c);
+ mpfr_clear (d);
+}
+
+static void
+check_max(void)
+{
+ mpfr_t xx, yy, zz;
+ mpfr_exp_t emin;
+
+ mpfr_init2(xx, 4);
+ mpfr_init2(yy, 4);
+ mpfr_init2(zz, 4);
+ mpfr_set_str1 (xx, "0.68750");
+ mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, MPFR_RNDN);
+ mpfr_set_str1 (yy, "0.68750");
+ mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, MPFR_RNDN);
+ mpfr_clear_flags();
+ test_mul(zz, xx, yy, MPFR_RNDU);
+ if (!(mpfr_overflow_p() && MPFR_IS_INF(zz)))
+ {
+ printf("check_max failed (should be an overflow)\n");
+ exit(1);
+ }
+
+ mpfr_clear_flags();
+ test_mul(zz, xx, yy, MPFR_RNDD);
+ if (mpfr_overflow_p() || MPFR_IS_INF(zz))
+ {
+ printf("check_max failed (should NOT be an overflow)\n");
+ exit(1);
+ }
+ mpfr_set_str1 (xx, "0.93750");
+ mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, MPFR_RNDN);
+ if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz)))
+ {
+ printf("check_max failed (internal error)\n");
+ exit(1);
+ }
+ if (mpfr_cmp(xx, zz) != 0)
+ {
+ printf("check_max failed: got ");
+ mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ);
+ printf(" instead of ");
+ mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ);
+ printf("\n");
+ exit(1);
+ }
+
+ /* check underflow */
+ emin = mpfr_get_emin ();
+ set_emin (0);
+ mpfr_set_str_binary (xx, "0.1E0");
+ mpfr_set_str_binary (yy, "0.1E0");
+ test_mul (zz, xx, yy, MPFR_RNDN);
+ /* exact result is 0.1E-1, which should round to 0 */
+ MPFR_ASSERTN(mpfr_cmp_ui (zz, 0) == 0 && MPFR_IS_POS(zz));
+ set_emin (emin);
+
+ /* coverage test for mpfr_powerof2_raw */
+ emin = mpfr_get_emin ();
+ set_emin (0);
+ mpfr_set_prec (xx, mp_bits_per_limb + 1);
+ mpfr_set_str_binary (xx, "0.1E0");
+ mpfr_nextabove (xx);
+ mpfr_set_str_binary (yy, "0.1E0");
+ test_mul (zz, xx, yy, MPFR_RNDN);
+ /* exact result is just above 0.1E-1, which should round to minfloat */
+ MPFR_ASSERTN(mpfr_cmp (zz, yy) == 0);
+ set_emin (emin);
+
+ mpfr_clear(xx);
+ mpfr_clear(yy);
+ mpfr_clear(zz);
+}
+
+static void
+check_min(void)
+{
+ mpfr_t xx, yy, zz;
+
+ mpfr_init2(xx, 4);
+ mpfr_init2(yy, 4);
+ mpfr_init2(zz, 3);
+ mpfr_set_str1(xx, "0.9375");
+ mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT/2, MPFR_RNDN);
+ mpfr_set_str1(yy, "0.9375");
+ mpfr_mul_2si(yy, yy, MPFR_EMIN_DEFAULT - MPFR_EMIN_DEFAULT/2 - 1, MPFR_RNDN);
+ test_mul(zz, xx, yy, MPFR_RNDD);
+ if (mpfr_sgn(zz) != 0)
+ {
+ printf("check_min failed: got ");
+ mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ);
+ printf(" instead of 0\n");
+ exit(1);
+ }
+
+ test_mul(zz, xx, yy, MPFR_RNDU);
+ mpfr_set_str1 (xx, "0.5");
+ mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT, MPFR_RNDN);
+ if (mpfr_sgn(xx) <= 0)
+ {
+ printf("check_min failed (internal error)\n");
+ exit(1);
+ }
+ if (mpfr_cmp(xx, zz) != 0)
+ {
+ printf("check_min failed: got ");
+ mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ);
+ printf(" instead of ");
+ mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ);
+ printf("\n");
+ exit(1);
+ }
+
+ mpfr_clear(xx);
+ mpfr_clear(yy);
+ mpfr_clear(zz);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t p, x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+ mpfr_init2 (p, 123L);
+
+ /* nan * 0 == nan */
+ mpfr_set_nan (x);
+ mpfr_set_ui (y, 0L, MPFR_RNDN);
+ test_mul (p, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (p));
+
+ /* 1 * nan == nan */
+ mpfr_set_ui (x, 1L, MPFR_RNDN);
+ mpfr_set_nan (y);
+ test_mul (p, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (p));
+
+ /* 0 * +inf == nan */
+ mpfr_set_ui (x, 0L, MPFR_RNDN);
+ mpfr_set_nan (y);
+ test_mul (p, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (p));
+
+ /* +1 * +inf == +inf */
+ mpfr_set_ui (x, 1L, MPFR_RNDN);
+ mpfr_set_inf (y, 1);
+ test_mul (p, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (p));
+ MPFR_ASSERTN (mpfr_sgn (p) > 0);
+
+ /* -1 * +inf == -inf */
+ mpfr_set_si (x, -1L, MPFR_RNDN);
+ mpfr_set_inf (y, 1);
+ test_mul (p, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (p));
+ MPFR_ASSERTN (mpfr_sgn (p) < 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (p);
+}
+
+#define BUFSIZE 1552
+
+static void
+get_string (char *s, FILE *fp)
+{
+ int c, n = BUFSIZE;
+
+ while ((c = getc (fp)) != '\n')
+ {
+ if (c == EOF)
+ {
+ printf ("Error in get_string: end of file\n");
+ exit (1);
+ }
+ *(unsigned char *)s++ = c;
+ if (--n == 0)
+ {
+ printf ("Error in get_string: buffer is too small\n");
+ exit (1);
+ }
+ }
+ *s = '\0';
+}
+
+static void
+check_regression (void)
+{
+ mpfr_t x, y, z;
+ int i;
+ FILE *fp;
+ char s[BUFSIZE];
+
+ mpfr_inits2 (6177, x, y, z, (mpfr_ptr) 0);
+ /* we read long strings from a file since ISO C90 does not support strings of
+ length > 509 */
+ fp = src_fopen ("tmul.dat", "r");
+ if (fp == NULL)
+ {
+ fprintf (stderr, "Error, cannot open tmul.dat in srcdir\n");
+ exit (1);
+ }
+ get_string (s, fp);
+ mpfr_set_str (y, s, 16, MPFR_RNDN);
+ get_string (s, fp);
+ mpfr_set_str (z, s, 16, MPFR_RNDN);
+ i = mpfr_mul (x, y, z, MPFR_RNDN);
+ get_string (s, fp);
+ if (mpfr_cmp_str (x, s, 16, MPFR_RNDN) != 0 || i != -1)
+ {
+ printf ("Regression test 1 failed (i=%d, expected -1)\nx=", i);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ fclose (fp);
+
+ mpfr_set_prec (x, 606);
+ mpfr_set_prec (y, 606);
+ mpfr_set_prec (z, 606);
+
+ mpfr_set_str (y, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN);
+ mpfr_set_str (z, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN);
+ i = mpfr_mul (x, y, z, MPFR_RNDU);
+ mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff25b5df87f00a5953eb0e6cac9b3d27cc5a64c@-1", 16, MPFR_RNDN);
+ if (mpfr_cmp (x, y) || i <= 0)
+ {
+ printf ("Regression test (2) failed! (i=%d - Expected 1)\n", i);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 184);
+ mpfr_set_prec (y, 92);
+ mpfr_set_prec (z, 1023);
+
+ mpfr_set_str (y, "6.9b8c8498882770d8038c3b0@-1", 16, MPFR_RNDN);
+ mpfr_set_str (z, "7.44e24b986e7fb296f1e936ce749fec3504cbf0d5ba769466b1c9f1578115efd5d29b4c79271191a920a99280c714d3a657ad6e3afbab77ffce9d697e9bb9110e26d676069afcea8b69f1d1541f2365042d80a97c21dcccd8ace4f1bb58b49922003e738e6f37bb82ef653cb2e87f763974e6ae50ae54e7724c38b80653e3289@255", 16, MPFR_RNDN);
+ i = mpfr_mul (x, y, z, MPFR_RNDU);
+ mpfr_set_prec (y, 184);
+ mpfr_set_str (y, "3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255",
+ 16, MPFR_RNDN);
+ if (mpfr_cmp (x, y) || i <= 0)
+ {
+ printf ("Regression test (4) failed! (i=%d - expected 1)\n", i);
+ printf ("Ref: 3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255\n"
+ "Got: ");
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 908);
+ mpfr_set_prec (y, 908);
+ mpfr_set_prec (z, 908);
+ mpfr_set_str (y, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+"ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42"
+"e6e9a327230345ea6@-1", 16, MPFR_RNDN);
+ mpfr_set_str (z, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+"ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42"
+ "e6e9a327230345ea6@-1", 16, MPFR_RNDN);
+ i = mpfr_mul (x, y, z, MPFR_RNDU);
+ mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+"fffffffffffffffffffffffffffffffffffffffffffffffffffff337d23f07d8de1da5147a85c"
+"dd3464e46068bd4d@-1", 16, MPFR_RNDN);
+ if (mpfr_cmp (x, y) || i <= 0)
+ {
+ printf ("Regression test (5) failed! (i=%d - expected 1)\n", i);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+
+ mpfr_set_prec (x, 50);
+ mpfr_set_prec (y, 40);
+ mpfr_set_prec (z, 53);
+ mpfr_set_str (y, "4.1ffffffff8", 16, MPFR_RNDN);
+ mpfr_set_str (z, "4.2000000ffe0000@-4", 16, MPFR_RNDN);
+ i = mpfr_mul (x, y, z, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "1.104000041d6c0@-3", 16, MPFR_RNDN) != 0
+ || i <= 0)
+ {
+ printf ("Regression test (6) failed! (i=%d - expected 1)\nx=", i);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ printf ("\nMore prec=");
+ mpfr_set_prec (x, 93);
+ mpfr_mul (x, y, z, MPFR_RNDN);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 439);
+ mpfr_set_prec (y, 393);
+ mpfr_set_str (y, "-1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d"
+ "4c76273644a29410f31c6809bbdf2a33679a748636600",
+ 16, MPFR_RNDN);
+ i = mpfr_mul (x, y, y, MPFR_RNDU);
+ if (mpfr_cmp_str (x, "2.77a79937c8bbcb495b89b36602306b1c2159a8ff834288a19a08"
+ "84094f1cda3dc426da61174c4544a173de83c2500f8bfea2e0569e3698",
+ 16, MPFR_RNDN) != 0
+ || i <= 0)
+ {
+ printf ("Regression test (7) failed! (i=%d - expected 1)\nx=", i);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 1023);
+ mpfr_set_prec (y, 1023);
+ mpfr_set_prec (z, 511);
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_set_ui (y, 42, MPFR_RNDN);
+ i = mpfr_mul (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 17*42) != 0 || i != 0)
+ {
+ printf ("Regression test (8) failed! (i=%d - expected 0)\nz=", i);
+ mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+#define TEST_FUNCTION test_mul
+#define TWO_ARGS
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
+#include "tgeneric.c"
+
+/* multiplies x by 53-bit approximation of Pi */
+static int
+mpfr_mulpi (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r)
+{
+ mpfr_t z;
+ int inex;
+
+ mpfr_init2 (z, 53);
+ mpfr_set_str_binary (z, "11.001001000011111101101010100010001000010110100011");
+ inex = mpfr_mul (y, x, z, r);
+ mpfr_clear (z);
+ return inex;
+}
+
+static void
+valgrind20110503 (void)
+{
+ mpfr_t a, b, c;
+
+ mpfr_init2 (a, 2);
+ mpfr_init2 (b, 2005);
+ mpfr_init2 (c, 2);
+
+ mpfr_set_ui (b, 5, MPFR_RNDN);
+ mpfr_nextabove (b);
+ mpfr_set_ui (c, 1, MPFR_RNDN);
+ mpfr_mul (a, b, c, MPFR_RNDZ);
+ /* After the call to mpfr_mulhigh_n, valgrind complains:
+ Conditional jump or move depends on uninitialised value(s) */
+
+ mpfr_clears (a, b, c, (mpfr_ptr) 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_nans ();
+ check_exact ();
+ check_float ();
+
+ check53("6.9314718055994530941514e-1", "0.0", MPFR_RNDZ, "0.0");
+ check53("0.0", "6.9314718055994530941514e-1", MPFR_RNDZ, "0.0");
+ check_sign();
+ check53("-4.165000000e4", "-0.00004801920768307322868063274915", MPFR_RNDN,
+ "2.0");
+ check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165",
+ MPFR_RNDZ, "-1.8251348697787782844e-172");
+ check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165",
+ MPFR_RNDA, "-1.8251348697787786e-172");
+ check53("0.31869277231188065", "0.88642843322303122", MPFR_RNDZ,
+ "2.8249833483992453642e-1");
+ check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDU,
+ 28, 45, 2, "0.375");
+ check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDA,
+ 28, 45, 2, "0.375");
+ check("2.63978122803639081440e-01", "6.8378615379333496093e-1", MPFR_RNDN,
+ 34, 23, 31, "0.180504585267044603");
+ check("1.0", "0.11835170935876249132", MPFR_RNDU, 6, 41, 36,
+ "0.1183517093595583");
+ check53("67108865.0", "134217729.0", MPFR_RNDN, "9.007199456067584e15");
+ check("1.37399642157394197284e-01", "2.28877275604219221350e-01", MPFR_RNDN,
+ 49, 15, 32, "0.0314472340833162888");
+ check("4.03160720978664954828e-01", "5.854828e-1"
+ /*"5.85483042917246621073e-01"*/, MPFR_RNDZ,
+ 51, 22, 32, "0.2360436821472831");
+ check("3.90798504668055102229e-14", "9.85394674650308388664e-04", MPFR_RNDN,
+ 46, 22, 12, "0.385027296503914762e-16");
+ check("4.58687081072827851358e-01", "2.20543551472118792844e-01", MPFR_RNDN,
+ 49, 3, 2, "0.09375");
+ check_max();
+ check_min();
+
+ check_regression ();
+ test_generic (2, 500, 100);
+
+ data_check ("data/mulpi", mpfr_mulpi, "mpfr_mulpi");
+
+ valgrind20110503 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tmul.dat b/mpfr/tests/tmul.dat
new file mode 100644
index 0000000000..3551efe5a9
--- /dev/null
+++ b/mpfr/tests/tmul.dat
@@ -0,0 +1,3 @@
+5.17cc1b727220a94fe13abe8fa9a6ee06db14acc9e21c820ff28b1d5ef5de2b0db92371d2126e9700324977504e8c90e7f0ef58e5894d39f74411afa975da24274ce38135a2fbf209cc8eb1cc1a99cfa4e422fc5defc941d8ffc4bffef02cc07f79788c5ad05368fb69b3f6793e584dba7a31fb34f2ff516ba93dd63f5f2f8bd9e839cfbc529497535fdafd88fc6ae842b0198237e3db5d5f867de104d7a1b0ed4f1c8b0af730d8432ccc2af8a50342046ffec4026b9939883030aab6539d464b0713de04635a3e20ce1b3e6ee74049541ace23b45cb0e536ed7a268ab8c829f52ff83829fbf19f419616f27cc193edde19e9377b58f2f7c4f9d0f9ae5793f8ec3f890c83e3e12357d376abb9698219d8ae30a5ace8ce1e16256a0a6962e8006233ec316b8f1cd634d803119be695a4bd3da6aaa9bfb1f6b8c0851fe3b26954eb255ebb87c3e31abd83d738a8bab24e06ceb1d9c4253e591923bc56b11aa2d5c8f800d8578efe70cff98cfb50f3330abcca3fdd66c3fbf5bb29144f419305ff366e277849b366a1faeebef0b6f1dac494def14116974431426ac711965630b718465bef028600bd38ef9adf00c1a099731094180a441adc77abfd856f9748f21a52469b3886c6ed5212fd76730b55214055a4ce9f953033fbbae41e151c41e30bc39c52d4657deebb7b1d316e5dffa77c0c6b3e09322e52a9b6ce569541446b0e13be4890a13024da309622ce22262e448d926f98b8056a1ea72a494886afefe5f00664a0f7767387a9f09c078f661f3d9947c63ca02c99f38e0d9849779a285ce09443d9055cfda9761492397993db6aa864853b90ff3b5cb6598a50b3cf13ca0c4effa4bca744273714b98ccb5f6c41b2faf877eddda4d24365233a13938992ec6dc0acf84f2de1298c69cba7b8e0298008606b40425ac77164855238173ba126b5ed33efbb92437778b4fd34a477b48da28a9e8f9056799cc103f25fab431d92f9f6e81aea03fc4c294a92ae0321b886c369924193aa62dea38a7372a22e08485b4fa956ab30a4e8393a8022eed9dda62bb750bfcc3beb5a4dd138e94b4cb000000000@1535
+3.243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89452821e638d01377be5466cf34e90c6cc0ac29b7c97c50dd3f84d5b5b54709179216d5d98979fb1bd1310ba698dfb5ac2ffd72dbd01adfb7b8e1afed6a267e96ba7c9045f12c7f9924a19947b3916cf70801f2e2858efc16636920d871574e69a458fea3f4933d7e0d95748f728eb658718bcd5882154aee7b54a41dc25a59b59c30d5392af26013c5d1b023286085f0ca417918b8db38ef8e79dcb0603a180e6c9e0e8bb01e8a3ed71577c1bd314b2778af2fda55605c60e65525f3aa55ab945748986263e8144055ca396a2aab10b6b4cc5c341141e8cea15486af7c72e993b3ee1411636fbc2a2ba9c55d741831f6ce5c3e169b87931eafd6ba336c24cf5c7a325381289586773b8f48986b4bb9afc4bfe81b6628219361d809ccfb21a991487cac605dec8032ef845d5de98575b1dc262302eb651b8823893e81d396acc50f6d6ff383f442392e0b4482a484200469c8f04a9e1f9b5e21c66842f6e96c9a670c9c61abd388f06a51a0d2d8542f68960fa728ab5133a36eef0b6c137a3be4ba3bf0507efb2a98a1f1651d39af017666ca593e82430e888cee8619456f9fb47d84a5c33b8b5ebee06f75d885c12073401a449f56c16aa64ed3aa62363f77061bfedf72429b023d37d0d724d00a1248db0fead349f1c09b075372c980991b7b25d479d8f6e8def7e3fe501ab6794c3b976ce0bd04c006bac1a94fb6409f60c45e5c9ec2196a246368fb6faf3e6c53b51339b2eb3b52ec6f6dfc511f9b30952ccc814544af5ebd09bee3d004de334afd660f2807192e4bb3c0cba85745c8740fd20b5f39b9d3fbdb5579c0bd1a60320ad6a100c6402c7279679f25fefb1fa3cc8ea5e9f8db3222f83c7516dffd616b152f501ec8ad0552ab323db5fafd23876053317b483e00df829e5c57bbca6f8ca01a87562edf1769dbd542a8f6287effc3ac6732c68c4f5573695b27b0bbca58c8e1ffa35db8f011a010fa3d98fd2183b84afcb56c2dd1d35b9a53e479b6f84565d28e49bc4bfb9790e1ddf2daa4cb7e3362fb1342
+f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef09109690@1535
diff --git a/mpfr/tests/tmul_2exp.c b/mpfr/tests/tmul_2exp.c
new file mode 100644
index 0000000000..9dd4ad5297
--- /dev/null
+++ b/mpfr/tests/tmul_2exp.c
@@ -0,0 +1,339 @@
+/* Test file for mpfr_{mul,div}_2{ui,si}.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static const char * const val[] = {
+ "1.0001@100","4.0004000000000@102", "4.0004000000000@97",
+ "1.ABF012345@-100","6.afc048d140000@-98","6.afc048d140000@-103",
+ "F.FFFFFFFFF@10000","3.fffffffffc000@10003","3.fffffffffc000@9998",
+ "1.23456789ABCDEF@42","4.8d159e26af37c@44","4.8d159e26af37c@39",
+ "17@42","5.c000000000000@45","5.c000000000000@40",
+ "42@-17","1.0800000000000@-13","1.0800000000000@-18"
+};
+
+static int
+test_mul (int i, int div, mpfr_ptr y, mpfr_srcptr x,
+ unsigned long int n, mpfr_rnd_t r)
+{
+ return
+ i == 0 ? (div ? mpfr_div_2ui : mpfr_mul_2ui) (y, x, n, r) :
+ i == 1 ? (div ? mpfr_div_2si : mpfr_mul_2si) (y, x, n, r) :
+ i == 2 ? (div ? mpfr_mul_2si : mpfr_div_2si) (y, x, -n, r) :
+ (exit (1), 0);
+}
+
+static void
+underflow (mpfr_exp_t e)
+{
+ mpfr_t x, y, z1, z2;
+ mpfr_exp_t emin;
+ int i, k;
+ int prec;
+ int rnd;
+ int div;
+ int inex1, inex2;
+ unsigned int flags1, flags2;
+
+ /* Test mul_2si(x, e - k), div_2si(x, k - e) and div_2ui(x, k - e)
+ * with emin = e, x = 1 + i/16, i in { -1, 0, 1 }, and k = 1 to 4,
+ * by comparing the result with the one of a simple division.
+ */
+ emin = mpfr_get_emin ();
+ set_emin (e);
+ mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
+ for (i = 15; i <= 17; i++)
+ {
+ inex1 = mpfr_set_ui_2exp (x, i, -4, MPFR_RNDN);
+ MPFR_ASSERTN (inex1 == 0);
+ for (prec = 6; prec >= 3; prec -= 3)
+ {
+ mpfr_inits2 (prec, z1, z2, (mpfr_ptr) 0);
+ RND_LOOP (rnd)
+ for (k = 1; k <= 4; k++)
+ {
+ /* The following one is assumed to be correct. */
+ inex1 = mpfr_mul_2si (y, x, e, MPFR_RNDN);
+ MPFR_ASSERTN (inex1 == 0);
+ inex1 = mpfr_set_ui (z1, 1 << k, MPFR_RNDN);
+ MPFR_ASSERTN (inex1 == 0);
+ mpfr_clear_flags ();
+ /* Do not use mpfr_div_ui to avoid the optimization
+ by mpfr_div_2si. */
+ inex1 = mpfr_div (z1, y, z1, (mpfr_rnd_t) rnd);
+ flags1 = __gmpfr_flags;
+
+ for (div = 0; div <= 2; div++)
+ {
+ mpfr_clear_flags ();
+ inex2 = div == 0 ?
+ mpfr_mul_2si (z2, x, e - k, (mpfr_rnd_t) rnd) : div == 1 ?
+ mpfr_div_2si (z2, x, k - e, (mpfr_rnd_t) rnd) :
+ mpfr_div_2ui (z2, x, k - e, (mpfr_rnd_t) rnd);
+ flags2 = __gmpfr_flags;
+ if (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
+ mpfr_equal_p (z1, z2))
+ continue;
+ printf ("Error in underflow(");
+ if (e == MPFR_EMIN_MIN)
+ printf ("MPFR_EMIN_MIN");
+ else if (e == emin)
+ printf ("default emin");
+ else if (e >= LONG_MIN)
+ printf ("%ld", (long) e);
+ else
+ printf ("<LONG_MIN");
+ printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d, "
+ "%s\n", div == 0 ? "mul_2si" : div == 1 ?
+ "div_2si" : "div_2ui", i, prec, k,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("Expected ");
+ mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN);
+ printf (", inex = %d, flags = %u\n", SIGN (inex1), flags1);
+ printf ("Got ");
+ mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN);
+ printf (", inex = %d, flags = %u\n", SIGN (inex2), flags2);
+ exit (1);
+ } /* div */
+ } /* k */
+ mpfr_clears (z1, z2, (mpfr_ptr) 0);
+ } /* prec */
+ } /* i */
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+ set_emin (emin);
+}
+
+static void
+underflow0 (void)
+{
+ underflow (-256);
+ if (mpfr_get_emin () != MPFR_EMIN_MIN)
+ underflow (mpfr_get_emin ());
+ underflow (MPFR_EMIN_MIN);
+}
+
+static void
+large (mpfr_exp_t e)
+{
+ mpfr_t x, y, z;
+ mpfr_exp_t emax;
+ int inex;
+ unsigned int flags;
+
+ emax = mpfr_get_emax ();
+ set_emax (e);
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+ mpfr_init2 (z, 4);
+
+ mpfr_set_inf (x, 1);
+ mpfr_nextbelow (x);
+
+ mpfr_mul_2si (y, x, -1, MPFR_RNDU);
+ mpfr_prec_round (y, 4, MPFR_RNDU);
+
+ mpfr_clear_flags ();
+ inex = mpfr_mul_2si (z, x, -1, MPFR_RNDU);
+ flags = __gmpfr_flags;
+
+ if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in large(");
+ if (e == MPFR_EMAX_MAX)
+ printf ("MPFR_EMAX_MAX");
+ else if (e == emax)
+ printf ("default emax");
+ else if (e <= LONG_MAX)
+ printf ("%ld", (long) e);
+ else
+ printf (">LONG_MAX");
+ printf (") for mpfr_mul_2si\n");
+ printf ("Expected inex > 0, flags = %u,\n y = ",
+ (unsigned int) MPFR_FLAGS_INEXACT);
+ mpfr_dump (y);
+ printf ("Got inex = %d, flags = %u,\n y = ",
+ inex, flags);
+ mpfr_dump (z);
+ exit (1);
+ }
+
+ mpfr_clear_flags ();
+ inex = mpfr_div_2si (z, x, 1, MPFR_RNDU);
+ flags = __gmpfr_flags;
+
+ if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in large(");
+ if (e == MPFR_EMAX_MAX)
+ printf ("MPFR_EMAX_MAX");
+ else if (e == emax)
+ printf ("default emax");
+ else if (e <= LONG_MAX)
+ printf ("%ld", (long) e);
+ else
+ printf (">LONG_MAX");
+ printf (") for mpfr_div_2si\n");
+ printf ("Expected inex > 0, flags = %u,\n y = ",
+ (unsigned int) MPFR_FLAGS_INEXACT);
+ mpfr_dump (y);
+ printf ("Got inex = %d, flags = %u,\n y = ",
+ inex, flags);
+ mpfr_dump (z);
+ exit (1);
+ }
+
+ mpfr_clear_flags ();
+ inex = mpfr_div_2ui (z, x, 1, MPFR_RNDU);
+ flags = __gmpfr_flags;
+
+ if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z))
+ {
+ printf ("Error in large(");
+ if (e == MPFR_EMAX_MAX)
+ printf ("MPFR_EMAX_MAX");
+ else if (e == emax)
+ printf ("default emax");
+ else if (e <= LONG_MAX)
+ printf ("%ld", (long) e);
+ else
+ printf (">LONG_MAX");
+ printf (") for mpfr_div_2ui\n");
+ printf ("Expected inex > 0, flags = %u,\n y = ",
+ (unsigned int) MPFR_FLAGS_INEXACT);
+ mpfr_dump (y);
+ printf ("Got inex = %d, flags = %u,\n y = ",
+ inex, flags);
+ mpfr_dump (z);
+ exit (1);
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+ set_emax (emax);
+}
+
+static void
+large0 (void)
+{
+ large (256);
+ if (mpfr_get_emax () != MPFR_EMAX_MAX)
+ large (mpfr_get_emax ());
+ large (MPFR_EMAX_MAX);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t w,z;
+ unsigned long k;
+ int i;
+
+ tests_start_mpfr ();
+
+ mpfr_inits2 (53, w, z, (mpfr_ptr) 0);
+
+ for (i = 0; i < 3; i++)
+ {
+ mpfr_set_inf (w, 1);
+ test_mul (i, 0, w, w, 10, MPFR_RNDZ);
+ if (!MPFR_IS_INF(w))
+ {
+ printf ("Result is not Inf (i = %d)\n", i);
+ exit (1);
+ }
+
+ mpfr_set_nan (w);
+ test_mul (i, 0, w, w, 10, MPFR_RNDZ);
+ if (!MPFR_IS_NAN(w))
+ {
+ printf ("Result is not NaN (i = %d)\n", i);
+ exit (1);
+ }
+
+ for (k = 0 ; k < numberof(val) ; k+=3)
+ {
+ mpfr_set_str (w, val[k], 16, MPFR_RNDN);
+ test_mul (i, 0, z, w, 10, MPFR_RNDZ);
+ if (mpfr_cmp_str (z, val[k+1], 16, MPFR_RNDN))
+ {
+ printf ("ERROR for x * 2^n (i = %d) for %s\n", i, val[k]);
+ printf ("Expected: %s\n"
+ "Got : ", val[k+1]);
+ mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ test_mul (i, 1, z, w, 10, MPFR_RNDZ);
+ if (mpfr_cmp_str (z, val[k+2], 16, MPFR_RNDN))
+ {
+ printf ("ERROR for x / 2^n (i = %d) for %s\n", i, val[k]);
+ printf ("Expected: %s\n"
+ "Got : ", val[k+2]);
+ mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ }
+
+ mpfr_set_inf (w, 1);
+ mpfr_nextbelow (w);
+ test_mul (i, 0, w, w, 1, MPFR_RNDN);
+ if (!mpfr_inf_p (w))
+ {
+ printf ("Overflow error (i = %d)!\n", i);
+ exit (1);
+ }
+ mpfr_set_ui (w, 0, MPFR_RNDN);
+ mpfr_nextabove (w);
+ test_mul (i, 1, w, w, 1, MPFR_RNDN);
+ if (mpfr_cmp_ui (w, 0))
+ {
+ printf ("Underflow error (i = %d)!\n", i);
+ exit (1);
+ }
+ }
+
+ if (MPFR_EXP_MAX >= LONG_MAX/2 && MPFR_EXP_MIN <= LONG_MAX/2-LONG_MAX-1)
+ {
+ unsigned long lmp1 = (unsigned long) LONG_MAX + 1;
+
+ mpfr_set_ui (w, 1, MPFR_RNDN);
+ mpfr_mul_2ui (w, w, LONG_MAX/2, MPFR_RNDZ);
+ mpfr_div_2ui (w, w, lmp1, MPFR_RNDZ);
+ mpfr_mul_2ui (w, w, lmp1 - LONG_MAX/2, MPFR_RNDZ);
+ if (!mpfr_cmp_ui (w, 1))
+ {
+ printf ("Underflow LONG_MAX error!\n");
+ exit (1);
+ }
+ }
+
+ mpfr_clears (w, z, (mpfr_ptr) 0);
+
+ underflow0 ();
+ large0 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tmul_d.c b/mpfr/tests/tmul_d.c
new file mode 100644
index 0000000000..ec4b4c1814
--- /dev/null
+++ b/mpfr/tests/tmul_d.c
@@ -0,0 +1,136 @@
+/* Test file for mpfr_mul_d
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+ int inexact;
+
+ mpfr_init2 (x, 123);
+ mpfr_init2 (y, 123);
+
+ /* nan * 1.0 is nan */
+ mpfr_set_nan (x);
+ mpfr_clear_flags();
+ inexact = mpfr_mul_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* +inf * 1.0 == +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_clear_flags();
+ inexact = mpfr_mul_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ /* +inf * 0.0 is nan */
+ mpfr_clear_flags();
+ inexact = mpfr_mul_d (y, x, 0.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* -inf * 1.0 == -inf */
+ mpfr_set_inf (x, -1);
+ mpfr_clear_flags();
+ inexact = mpfr_mul_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_mul_d
+#define DOUBLE_ARG2
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_t x, y, z;
+ double d;
+ int inexact;
+
+ tests_start_mpfr ();
+
+ /* check with enough precision */
+ mpfr_init2 (x, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (y, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (z, IEEE_DBL_MANT_DIG);
+
+ mpfr_set_str (y, "4096", 10, MPFR_RNDN);
+ d = 0.125;
+ mpfr_clear_flags ();
+ inexact = mpfr_mul_d (x, y, d, MPFR_RNDN);
+ if (inexact != 0)
+ {
+ printf ("Inexact flag error in mpfr_mul_d\n");
+ exit (1);
+ }
+ mpfr_set_str (z, "512", 10, MPFR_RNDN);
+ if (mpfr_cmp (z, x))
+ {
+ printf ("Error in mpfr_mul_d (");
+ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
+ printf (" + %.20g)\nexpected ", d);
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+
+ check_nans ();
+
+ test_generic (2, 1000, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tmul_ui.c b/mpfr/tests/tmul_ui.c
new file mode 100644
index 0000000000..66afa5ccd4
--- /dev/null
+++ b/mpfr/tests/tmul_ui.c
@@ -0,0 +1,282 @@
+/* Test file for mpfr_mul_ui.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+check_inexact (mpfr_prec_t p)
+{
+ mpfr_t x, y, z;
+ unsigned long u;
+ mpfr_prec_t q;
+ int inexact, cmp;
+ int rnd;
+
+ mpfr_init2 (x, p);
+ mpfr_init (y);
+ mpfr_init2 (z, p + mp_bits_per_limb);
+ mpfr_urandomb (x, RANDS);
+ u = randlimb ();
+ if (mpfr_mul_ui (z, x, u, MPFR_RNDN))
+ {
+ printf ("Error: result should be exact\n");
+ exit (1);
+ }
+
+ for (q = 2; q <= p; q++)
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ mpfr_set_prec (y, q);
+ inexact = mpfr_mul_ui (y, x, u, (mpfr_rnd_t) rnd);
+ cmp = mpfr_cmp (y, z);
+ if (((inexact == 0) && (cmp != 0)) ||
+ ((inexact < 0) && (cmp >= 0)) ||
+ ((inexact > 0) && (cmp <= 0)))
+ {
+ printf ("Wrong inexact flag for p=%u, q=%u, rnd=%s\n",
+ (unsigned int) p, (unsigned int) q,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ exit (1);
+ }
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ if (mpfr_mul_ui (x, x, 5, MPFR_RNDZ) == 0)
+ {
+ printf ("mul_ui(1, 5) cannot be exact with prec=2\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+#define TEST_FUNCTION mpfr_mul_ui
+#define INTEGER_TYPE unsigned long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric_ui.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ unsigned int xprec, yprec, i;
+ mpfr_prec_t p;
+ mpfr_exp_t emax;
+
+ tests_start_mpfr ();
+
+ for (p=2; p<100; p++)
+ for (i=1; i<50; i++)
+ check_inexact (p);
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+
+ /* checks that result is normalized */
+ mpfr_set_str (y, "6.93147180559945286227e-01", 10, MPFR_RNDZ);
+ mpfr_mul_ui (x, y, 1, MPFR_RNDZ);
+ if (MPFR_MANT(x)[MPFR_PREC(x)/mp_bits_per_limb] >> (mp_bits_per_limb-1) == 0)
+ {
+ printf ("Error in mpfr_mul_ui: result not normalized\n");
+ exit (1);
+ }
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_mul_ui: 1*y != y\n");
+ printf ("y= "); mpfr_print_binary (y); puts ("");
+ printf ("1*y="); mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_mul_ui (x, x, 3, MPFR_RNDU);
+ if (!mpfr_inf_p (x) || (mpfr_sgn (x) <= 0))
+ {
+ printf ("Error in mpfr_mul_ui: +Inf*3 does not give +Inf\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_mul_ui (x, x, 3, MPFR_RNDU);
+ if (!mpfr_inf_p (x) || (mpfr_sgn (x) >= 0))
+ {
+ printf ("Error in mpfr_mul_ui: -Inf*3 does not give -Inf\n");
+ exit (1);
+ }
+
+ mpfr_set_nan (x);
+ mpfr_mul_ui (x, x, 3, MPFR_RNDU);
+ if (!mpfr_nan_p(x))
+ {
+ printf ("Error in mpfr_mul_ui: NaN*3 does not give NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_mul_ui (x, x, 0, MPFR_RNDU);
+ MPFR_ASSERTN(mpfr_nan_p (x));
+
+ mpfr_set_ui (x, 1, MPFR_RNDU);
+ mpfr_mul_ui (x, x, 0, MPFR_RNDU);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
+
+ emax = mpfr_get_emax ();
+ set_emax (0);
+ mpfr_set_str_binary (x, "0.1E0");
+ mpfr_mul_ui (x, x, 2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x));
+ set_emax (emax);
+
+ mpfr_set_str (x, /*1.0/3.0*/
+ "0.333333333333333333333333333333333", 10, MPFR_RNDZ);
+ mpfr_mul_ui (x, x, 3, MPFR_RNDU);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error in mpfr_mul_ui: U(Z(1/3)*3) does not give 1\n");
+ exit (1);
+ }
+
+ /* checks sign is correct */
+ mpfr_set_si (x, -2, MPFR_RNDZ);
+ mpfr_set_si (y, 3, MPFR_RNDZ);
+ mpfr_mul_ui(x, y, 4, MPFR_RNDZ);
+ if (mpfr_cmp_ui(x, 0) <= 0)
+ {
+ printf("Error in mpfr_mul_ui: 4*3.0 does not give a positive result:\n");
+ mpfr_print_binary(x); puts ("");
+ printf("mpfr_cmp_ui(x, 0) = %d\n", mpfr_cmp_ui(x, 0));
+ exit(1);
+ }
+
+ mpfr_set_prec (x, 9);
+ mpfr_set_prec (y, 9);
+ mpfr_set_str_binary (y, "0.100001111E9"); /* 271 */
+ mpfr_mul_ui (x, y, 1335, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.101100001E19"); /* 361472 */
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mul_ui for 1335*(0.100001111E9)\n");
+ printf ("got "); mpfr_print_binary (x); puts ("");
+ exit(1);
+ }
+
+ mpfr_set_prec(y, 100);
+ mpfr_set_prec(x, 100);
+ /* y = 1199781142214086656 */
+ mpfr_set_str_binary(y, "0.1000010100110011110101001011110010101111000100001E61");
+ mpfr_mul_ui(x, y, 121, MPFR_RNDD);
+ /* 121*y = 145173518207904485376, representable exactly */
+ mpfr_set_str_binary(y, "0.1111101111010101111111100011010010111010111110110011001E67");
+ if (mpfr_cmp(x, y))
+ {
+ printf("Error for 121*y: expected result is:\n");
+ mpfr_print_binary(y); puts ("");
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_str_binary (x, "0.10000000000000000000000000000000E1");
+ mpfr_set_prec (y, 93);
+ mpfr_mul_ui (y, x, 1, MPFR_RNDN);
+
+ mpfr_set_prec (x, 287);
+ mpfr_set_str_binary (x, "0.1111E7");
+ mpfr_set_prec (y, 289);
+ mpfr_mul_ui (y, x, 6, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.101101E10");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for 6 * 120\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 68);
+ mpfr_set_prec (y, 64);
+ mpfr_set_str (x, "2143861251406875.0", 10, MPFR_RNDN);
+ mpfr_mul_ui (y, x, 23, MPFR_RNDN);
+ mpfr_set_str_binary (x, "10101111001011100001100110101111110001010010011001101101.0");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for 23 * 2143861251406875.0\n");
+ printf ("expected "); mpfr_print_binary (x); puts ("");
+ printf ("got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+
+
+ for (xprec = 53; xprec <= 128; xprec++)
+ {
+ mpfr_set_prec (x, xprec);
+ mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2");
+ for (yprec = 53; yprec <= 128; yprec++)
+ {
+ mpfr_set_prec (y, yprec);
+ mpfr_mul_ui (y, x, 1, MPFR_RNDN);
+ if (mpfr_cmp(x,y))
+ {
+ printf ("multiplication by 1.0 fails for xprec=%u, yprec=%u\n",
+ xprec, yprec);
+ printf ("expected "); mpfr_print_binary (x); puts ("");
+ printf ("got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_set_prec (x, 128);
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_mul_ui (x, x, ULONG_HIGHBIT, MPFR_RNDN);
+ mpfr_set_prec (y, 128);
+ mpfr_set_ui (y, ULONG_HIGHBIT, MPFR_RNDN);
+ mpfr_mul_ui (y, y, 17, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for 17 * ULONG_HIGHBIT\n");
+ exit (1);
+ }
+
+ /* Check regression */
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 96);
+ mpfr_set_ui (x, 1742175942, MPFR_RNDN);
+ mpfr_mul_ui (y, x, 59, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "0.10111111011101010101000110111101000100000000000000"
+ "0000000000000000000000000000000000000000000000E37",
+ 2, MPFR_RNDN))
+ {
+ printf ("Regression tested failed for x=1742175942 * 59\n");
+ exit (1);
+ }
+
+ mpfr_clear(x);
+ mpfr_clear(y);
+
+ test_generic_ui (2, 500, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tnext.c b/mpfr/tests/tnext.c
new file mode 100644
index 0000000000..b84131dab9
--- /dev/null
+++ b/mpfr/tests/tnext.c
@@ -0,0 +1,168 @@
+/* Test file for mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward.
+
+Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* Generic tests for mpfr_nextabove and mpfr_nextbelow */
+static void
+generic_abovebelow (void)
+{
+ int i;
+
+ for (i = 0; i < 20000; i++)
+ {
+ mpfr_t x, y, z, t;
+ mpfr_prec_t prec;
+ int neg, below;
+
+ prec = (randlimb () % 300) + MPFR_PREC_MIN;
+ mpfr_inits2 (prec, x, y, z, (mpfr_ptr) 0);
+ mpfr_init2 (t, 3);
+
+ /* special tests (executed once is enough) */
+ if (i == 0)
+ {
+ mpfr_set_nan (x);
+ mpfr_nextabove (x);
+ MPFR_ASSERTN(mpfr_nan_p (x));
+ mpfr_nextbelow (x);
+ MPFR_ASSERTN(mpfr_nan_p (x));
+ mpfr_nexttoward (x, y);
+ MPFR_ASSERTN(mpfr_nan_p (x));
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_nexttoward (y, x);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_nexttoward (x, y);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);
+ }
+
+ do
+ mpfr_urandomb (x, RANDS);
+ while (mpfr_cmp_ui (x, 0) == 0);
+ neg = randlimb () & 1;
+ if (neg)
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_set (y, x, MPFR_RNDN);
+ below = randlimb () & 1;
+ if (below)
+ mpfr_nextbelow (y);
+ else
+ mpfr_nextabove (y);
+ mpfr_set_si (t, below ? -5 : 5, MPFR_RNDN);
+ mpfr_mul_2si (t, t, (mpfr_get_exp) (x) - prec - 3, MPFR_RNDN);
+ /* t = (1/2 + 1/8) ulp(x) */
+ mpfr_add (z, x, t, MPFR_RNDN);
+ if (!mpfr_number_p (y) || mpfr_cmp (y, z) != 0)
+ {
+ printf ("Error in mpfr_next%s for\n",
+ below ? "below" : "above");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf (", got\n");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf (" instead of\n");
+ mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z, t, (mpfr_ptr) 0);
+ }
+}
+
+static void
+inverse_test (void)
+{
+ static const char *tests[] = { "0", "1", "2", "3.1", "Inf" };
+ int i, neg, below;
+ mpfr_prec_t prec;
+
+ for (i = 0; i < (int) (sizeof(tests) / sizeof(tests[0])); i++)
+ for (neg = 0; neg <= 1; neg++)
+ for (below = 0; below <= 1; below++)
+ for (prec = MPFR_PREC_MIN; prec < 200; prec += 3)
+ {
+ mpfr_t x, y;
+ int sign;
+
+ mpfr_inits2 (prec, x, y, (mpfr_ptr) 0);
+ mpfr_set_str (x, tests[i], 10, MPFR_RNDN);
+ if (neg)
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_set (y, x, MPFR_RNDN);
+ if (below)
+ mpfr_nextbelow (y);
+ else
+ mpfr_nextabove (y);
+ sign = MPFR_SIGN (y);
+ if (!(neg == below && mpfr_inf_p (x))) /* then x = y */
+ {
+ if (mpfr_cmp (x, y) == 0)
+ {
+ printf ("Error in inverse_test for %s, neg = %d,"
+ " below = %d, prec = %d: x = y", tests[i],
+ neg, below, (int) prec);
+ printf ("\nx = ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\ny = ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_nexttoward (y, x);
+ if (mpfr_cmp_ui (y, 0) == 0 && MPFR_SIGN (y) != sign)
+ {
+ printf ("Sign error in inverse_test for %s, neg = %d,"
+ " below = %d, prec = %d\n", tests[i], neg,
+ below, (int) prec);
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ }
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error in inverse_test for %s, neg = %d, below = %d,"
+ " prec = %d", tests[i], neg, below, (int) prec);
+ printf ("\nx = ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\ny = ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+ }
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+ generic_abovebelow ();
+ inverse_test ();
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tout_str.c b/mpfr/tests/tout_str.c
new file mode 100644
index 0000000000..edbfb025fd
--- /dev/null
+++ b/mpfr/tests/tout_str.c
@@ -0,0 +1,171 @@
+/* Test file for mpfr_out_str.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <float.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+FILE *fout;
+
+#define check(d,r,b) check4(d,r,b,53)
+
+static void
+check4 (double d, mpfr_rnd_t rnd, int base, int prec)
+{
+ mpfr_t x;
+
+ mpfr_init2 (x, prec);
+ mpfr_set_d (x, d, rnd);
+ fprintf (fout, "%1.19e base %d rnd %d:\n ", d, base, rnd);
+ mpfr_out_str (fout, base, (base == 2) ? prec : 0, x, rnd);
+ fputc ('\n', fout);
+ mpfr_clear (x);
+}
+
+static void
+special (void)
+{
+ mpfr_t x;
+ unsigned int n;
+
+ mpfr_init (x);
+
+ mpfr_set_nan (x);
+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
+ if (n != 5)
+ {
+ printf ("Error: mpfr_out_str (file, 10, 0, NaN, MPFR_RNDN) wrote %u "
+ "characters instead of 5.\n", n);
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
+ if (n != 5)
+ {
+ printf ("Error: mpfr_out_str (file, 10, 0, +Inf, MPFR_RNDN) wrote %u "
+ "characters instead of 5.\n", n);
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
+ if (n != 6)
+ {
+ printf ("Error: mpfr_out_str (file, 10, 0, -Inf, MPFR_RNDN) wrote %u "
+ "characters instead of 6.\n", n);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
+ if (n != 1)
+ {
+ printf ("Error: mpfr_out_str (file, 10, 0, +0, MPFR_RNDN) wrote %u "
+ "characters instead of 1.\n", n);
+ exit (1);
+ }
+
+ mpfr_neg (x, x, MPFR_RNDN);
+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
+ if (n != 2)
+ {
+ printf ("Error: mpfr_out_str (file, 10, 0, -0, MPFR_RNDN) wrote %u "
+ "characters instead of 2.\n", n);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i, N=10000, p;
+ mpfr_rnd_t rnd;
+ double d;
+
+ tests_start_mpfr ();
+
+ /* with no argument: prints to /dev/null,
+ tout_str N: prints N tests to stdout */
+ if (argc == 1)
+ {
+ fout = fopen ("/dev/null", "w");
+ /* If we failed to open this device, try with a dummy file */
+ if (fout == NULL)
+ fout = fopen ("mpfrtest.txt", "w");
+ }
+ else
+ {
+ fout = stdout;
+ N = atoi (argv[1]);
+ }
+
+ if (fout == NULL)
+ {
+ printf ("Can't open /dev/null or stdout\n");
+ exit (1);
+ }
+
+ special ();
+
+ check (-1.37247529013405550000e+15, MPFR_RNDN, 7);
+ check (-1.5674376729569697500e+15, MPFR_RNDN, 19);
+ check (-5.71262771772792640000e-79, MPFR_RNDU, 16);
+ check (DBL_NEG_ZERO, MPFR_RNDU, 7);
+ check (-4.5306392613572974756e-308, MPFR_RNDN, 8);
+ check (-6.7265890111403371523e-165, MPFR_RNDN, 4);
+ check (-1.3242553591261807653e+156, MPFR_RNDN, 16);
+ check (-6.606499965302424244461355e233, MPFR_RNDN, 10);
+ check4 (1.0, MPFR_RNDN, 10, 120);
+ check (1.0, MPFR_RNDU, 10);
+ check (4.059650008e-83, MPFR_RNDN, 10);
+ check (-7.4, MPFR_RNDN, 10);
+ check (0.997, MPFR_RNDN, 10);
+ check (-4.53063926135729747564e-308, MPFR_RNDN, 10);
+ check (2.14478198760196000000e+16, MPFR_RNDN, 10);
+ check (7.02293374921793516813e-84, MPFR_RNDN, 10);
+
+ /* random tests */
+ for (i=0;i<N;i++)
+ {
+ do
+ {
+ d = DBL_RAND ();
+ }
+#ifdef HAVE_DENORMS
+ while (0);
+#else
+ while (ABS(d) < DBL_MIN);
+#endif
+ rnd = RND_RAND ();
+ p = 2 + randlimb () % 61;
+ check (d, rnd, p);
+ }
+
+ fclose (fout);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/toutimpl.c b/mpfr/tests/toutimpl.c
new file mode 100644
index 0000000000..6800ad4e76
--- /dev/null
+++ b/mpfr/tests/toutimpl.c
@@ -0,0 +1,122 @@
+/* Test file for internal debugging-out functions:
+ mpfr_dump, mpfr_print_binary, mpfr_print_rnd_mode.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include "mpfr-test.h"
+
+/* We output stdout to a file to check if it is correct
+ Is it a good idea?
+ We can't use tmpname since it is insecure */
+#define FILE_NAME "dummy.tmp"
+
+static const char Buffer[] =
+"@NaN@\n"
+"-@Inf@\n"
+"-0\n"
+"0.10101010101011111001000110001100010000100000000000000E32\n";
+
+int
+main (void)
+{
+ mpfr_t x;
+ FILE *f;
+ int i;
+
+ tests_start_mpfr ();
+
+ /* Check RND_MODE */
+ if (strcmp (mpfr_print_rnd_mode(MPFR_RNDN), "MPFR_RNDN"))
+ {
+ printf ("Error for printing MPFR_RNDN\n");
+ exit (1);
+ }
+ if (strcmp (mpfr_print_rnd_mode(MPFR_RNDU), "MPFR_RNDU"))
+ {
+ printf ("Error for printing MPFR_RNDU\n");
+ exit (1);
+ }
+ if (strcmp (mpfr_print_rnd_mode(MPFR_RNDD), "MPFR_RNDD"))
+ {
+ printf ("Error for printing MPFR_RNDD\n");
+ exit (1);
+ }
+ if (strcmp (mpfr_print_rnd_mode(MPFR_RNDZ), "MPFR_RNDZ"))
+ {
+ printf ("Error for printing MPFR_RNDZ\n");
+ exit (1);
+ }
+ if (mpfr_print_rnd_mode ((mpfr_rnd_t) -1) != NULL ||
+ mpfr_print_rnd_mode (MPFR_RND_MAX) != NULL)
+ {
+ printf ("Error for illegal rounding mode values.\n");
+ exit (1);
+ }
+
+ /* Reopen stdout to a file. All errors will be put to stderr
+ Can't use tmpname since it is unsecure */
+ if (freopen (FILE_NAME, "w", stdout) == NULL)
+ {
+ printf ("Error can't redirect stdout\n");
+ exit (1);
+ }
+ mpfr_init (x);
+ mpfr_set_nan (x);
+ mpfr_dump (x);
+ mpfr_set_inf (x, -1);
+ mpfr_dump (x);
+ MPFR_SET_ZERO (x); MPFR_SET_NEG (x);
+ mpfr_dump (x);
+ mpfr_set_str_binary (x, "0.101010101010111110010001100011000100001E32");
+ mpfr_dump (x);
+ mpfr_print_mant_binary ("x=",MPFR_MANT(x), MPFR_PREC(x));
+
+
+ mpfr_clear (x);
+ fclose (stdout);
+ /* Open it and check for it */
+ f = fopen (FILE_NAME, "r");
+ if (f == NULL)
+ {
+ fprintf (stderr, "Can't reopen file!\n");
+ exit (1);
+ }
+ for(i = 0 ; i < sizeof(Buffer)-1 ; i++)
+ {
+ if (feof (f))
+ {
+ fprintf (stderr, "Error EOF\n");
+ exit (1);
+ }
+ if (Buffer[i] != fgetc (f))
+ {
+ fprintf (stderr, "Character mismatch for i=%d / %lu\n",
+ i, (unsigned long) sizeof(Buffer));
+ exit (1);
+ }
+ }
+ fclose (f);
+
+ remove (FILE_NAME);
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tpow.c b/mpfr/tests/tpow.c
new file mode 100644
index 0000000000..63805f860f
--- /dev/null
+++ b/mpfr/tests/tpow.c
@@ -0,0 +1,1588 @@
+/* Test file for mpfr_pow, mpfr_pow_ui and mpfr_pow_si.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+#include <math.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_pow (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c)
+ && mpfr_get_prec (a) >= 53;
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ printf (" ");
+ mpfr_print_raw (c);
+ }
+ res = mpfr_pow (a, b, c, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_pow mpfr_pow
+#endif
+
+#define TEST_FUNCTION test_pow
+#define TWO_ARGS
+#define TEST_RANDOM_POS 16
+#define TGENERIC_NOWARNING 1
+#include "tgeneric.c"
+
+#define TEST_FUNCTION mpfr_pow_ui
+#define INTEGER_TYPE unsigned long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric_ui.c"
+
+#define TEST_FUNCTION mpfr_pow_si
+#define INTEGER_TYPE long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#define test_generic_ui test_generic_si
+#include "tgeneric_ui.c"
+
+static void
+check_pow_ui (void)
+{
+ mpfr_t a, b;
+ unsigned long n;
+ int res;
+
+ mpfr_init2 (a, 53);
+ mpfr_init2 (b, 53);
+
+ /* check in-place operations */
+ mpfr_set_str (b, "0.6926773", 10, MPFR_RNDN);
+ mpfr_pow_ui (a, b, 10, MPFR_RNDN);
+ mpfr_pow_ui (b, b, 10, MPFR_RNDN);
+ if (mpfr_cmp (a, b))
+ {
+ printf ("Error for mpfr_pow_ui (b, b, ...)\n");
+ exit (1);
+ }
+
+ /* check large exponents */
+ mpfr_set_ui (b, 1, MPFR_RNDN);
+ mpfr_pow_ui (a, b, 4294967295UL, MPFR_RNDN);
+
+ mpfr_set_inf (a, -1);
+ mpfr_pow_ui (a, a, 4049053855UL, MPFR_RNDN);
+ if (!mpfr_inf_p (a) || (mpfr_sgn (a) >= 0))
+ {
+ printf ("Error for (-Inf)^4049053855\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (a, -1);
+ mpfr_pow_ui (a, a, (unsigned long) 30002752, MPFR_RNDN);
+ if (!mpfr_inf_p (a) || (mpfr_sgn (a) <= 0))
+ {
+ printf ("Error for (-Inf)^30002752\n");
+ exit (1);
+ }
+
+ /* Check underflow */
+ mpfr_set_str_binary (a, "1E-1");
+ res = mpfr_pow_ui (a, a, -mpfr_get_emin (), MPFR_RNDN);
+ if (MPFR_GET_EXP (a) != mpfr_get_emin () + 1)
+ {
+ printf ("Error for (1e-1)^MPFR_EMAX_MAX\n");
+ mpfr_dump (a);
+ exit (1);
+ }
+
+ mpfr_set_str_binary (a, "1E-10");
+ res = mpfr_pow_ui (a, a, -mpfr_get_emin (), MPFR_RNDZ);
+ if (!MPFR_IS_ZERO (a))
+ {
+ printf ("Error for (1e-10)^MPFR_EMAX_MAX\n");
+ mpfr_dump (a);
+ exit (1);
+ }
+
+ /* Check overflow */
+ mpfr_set_str_binary (a, "1E10");
+ res = mpfr_pow_ui (a, a, ULONG_MAX, MPFR_RNDN);
+ if (!MPFR_IS_INF (a) || MPFR_SIGN (a) < 0)
+ {
+ printf ("Error for (1e10)^ULONG_MAX\n");
+ exit (1);
+ }
+
+ /* Bug in pow_ui.c from r3214 to r5107: if x = y (same mpfr_t argument),
+ the input argument is negative, n is odd, an overflow or underflow
+ occurs, and the temporary result res is positive, then the result
+ gets a wrong sign (positive instead of negative). */
+ mpfr_set_str_binary (a, "-1E10");
+ n = (ULONG_MAX ^ (ULONG_MAX >> 1)) + 1;
+ res = mpfr_pow_ui (a, a, n, MPFR_RNDN);
+ if (!MPFR_IS_INF (a) || MPFR_SIGN (a) > 0)
+ {
+ printf ("Error for (-1e10)^%lu, expected -Inf,\ngot ", n);
+ mpfr_dump (a);
+ exit (1);
+ }
+
+ /* Check 0 */
+ MPFR_SET_ZERO (a);
+ MPFR_SET_POS (a);
+ mpfr_set_si (b, -1, MPFR_RNDN);
+ res = mpfr_pow_ui (b, a, 1, MPFR_RNDN);
+ if (res != 0 || MPFR_IS_NEG (b))
+ {
+ printf ("Error for (0+)^1\n");
+ exit (1);
+ }
+ MPFR_SET_ZERO (a);
+ MPFR_SET_NEG (a);
+ mpfr_set_ui (b, 1, MPFR_RNDN);
+ res = mpfr_pow_ui (b, a, 5, MPFR_RNDN);
+ if (res != 0 || MPFR_IS_POS (b))
+ {
+ printf ("Error for (0-)^5\n");
+ exit (1);
+ }
+ MPFR_SET_ZERO (a);
+ MPFR_SET_NEG (a);
+ mpfr_set_si (b, -1, MPFR_RNDN);
+ res = mpfr_pow_ui (b, a, 6, MPFR_RNDN);
+ if (res != 0 || MPFR_IS_NEG (b))
+ {
+ printf ("Error for (0-)^6\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (a, 122);
+ mpfr_set_prec (b, 122);
+ mpfr_set_str_binary (a, "0.10000010010000111101001110100101101010011110011100001111000001001101000110011001001001001011001011010110110110101000111011E1");
+ mpfr_set_str_binary (b, "0.11111111100101001001000001000001100011100000001110111111100011111000111011100111111111110100011000111011000100100011001011E51290375");
+ mpfr_pow_ui (a, a, 2026876995UL, MPFR_RNDU);
+ if (mpfr_cmp (a, b) != 0)
+ {
+ printf ("Error for x^2026876995\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (a, 29);
+ mpfr_set_prec (b, 29);
+ mpfr_set_str_binary (a, "1.0000000000000000000000001111");
+ mpfr_set_str_binary (b, "1.1001101111001100111001010111e165");
+ mpfr_pow_ui (a, a, 2055225053, MPFR_RNDZ);
+ if (mpfr_cmp (a, b) != 0)
+ {
+ printf ("Error for x^2055225053\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 2, 0, b, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ /* worst case found by Vincent Lefevre, 25 Nov 2006 */
+ mpfr_set_prec (a, 53);
+ mpfr_set_prec (b, 53);
+ mpfr_set_str_binary (a, "1.0000010110000100001000101101101001011101101011010111");
+ mpfr_set_str_binary (b, "1.0000110111101111011010110100001100010000001010110100E1");
+ mpfr_pow_ui (a, a, 35, MPFR_RNDN);
+ if (mpfr_cmp (a, b) != 0)
+ {
+ printf ("Error in mpfr_pow_ui for worst case (1)\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 2, 0, b, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ /* worst cases found on 2006-11-26 */
+ mpfr_set_str_binary (a, "1.0110100111010001101001010111001110010100111111000011");
+ mpfr_set_str_binary (b, "1.1111010011101110001111010110000101110000110110101100E17");
+ mpfr_pow_ui (a, a, 36, MPFR_RNDD);
+ if (mpfr_cmp (a, b) != 0)
+ {
+ printf ("Error in mpfr_pow_ui for worst case (2)\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 2, 0, b, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_set_str_binary (a, "1.1001010100001110000110111111100011011101110011000100");
+ mpfr_set_str_binary (b, "1.1100011101101101100010110001000001110001111110010001E23");
+ mpfr_pow_ui (a, a, 36, MPFR_RNDU);
+ if (mpfr_cmp (a, b) != 0)
+ {
+ printf ("Error in mpfr_pow_ui for worst case (3)\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 2, 0, b, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+}
+
+static void
+check_pow_si (void)
+{
+ mpfr_t x;
+
+ mpfr_init (x);
+
+ mpfr_set_nan (x);
+ mpfr_pow_si (x, x, -1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (x));
+
+ mpfr_set_inf (x, 1);
+ mpfr_pow_si (x, x, -1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
+
+ mpfr_set_inf (x, -1);
+ mpfr_pow_si (x, x, -1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG(x));
+
+ mpfr_set_inf (x, -1);
+ mpfr_pow_si (x, x, -2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_pow_si (x, x, -1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_pow_si (x, x, -1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_pow_si (x, x, -2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+
+ mpfr_set_si (x, 2, MPFR_RNDN);
+ mpfr_pow_si (x, x, LONG_MAX, MPFR_RNDN); /* 2^LONG_MAX */
+ if (LONG_MAX > mpfr_get_emax () - 1) /* LONG_MAX + 1 > emax */
+ {
+ MPFR_ASSERTN (mpfr_inf_p (x));
+ }
+ else
+ {
+ MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, (mpfr_exp_t) LONG_MAX));
+ }
+
+ mpfr_set_si (x, 2, MPFR_RNDN);
+ mpfr_pow_si (x, x, LONG_MIN, MPFR_RNDN); /* 2^LONG_MIN */
+ if (LONG_MIN + 1 < mpfr_get_emin ())
+ {
+ MPFR_ASSERTN (mpfr_zero_p (x));
+ }
+ else
+ {
+ MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, (mpfr_exp_t) LONG_MIN));
+ }
+
+ mpfr_set_si (x, 2, MPFR_RNDN);
+ mpfr_pow_si (x, x, LONG_MIN + 1, MPFR_RNDN); /* 2^(LONG_MIN+1) */
+ if (mpfr_nan_p (x))
+ {
+ printf ("Error in pow_si(2, LONG_MIN+1): got NaN\n");
+ exit (1);
+ }
+ if (LONG_MIN + 2 < mpfr_get_emin ())
+ {
+ MPFR_ASSERTN (mpfr_zero_p (x));
+ }
+ else
+ {
+ MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 1, (mpfr_exp_t) (LONG_MIN + 1)));
+ }
+
+ mpfr_set_si_2exp (x, 1, -1, MPFR_RNDN); /* 0.5 */
+ mpfr_pow_si (x, x, LONG_MIN, MPFR_RNDN); /* 2^(-LONG_MIN) */
+ if (LONG_MIN < 1 - mpfr_get_emax ()) /* 1 - LONG_MIN > emax */
+ {
+ MPFR_ASSERTN (mpfr_inf_p (x));
+ }
+ else
+ {
+ MPFR_ASSERTN (mpfr_cmp_si_2exp (x, 2, (mpfr_exp_t) - (LONG_MIN + 1)));
+ }
+
+ mpfr_clear (x);
+}
+
+static void
+check_special_pow_si (void)
+{
+ mpfr_t a, b;
+ mpfr_exp_t emin;
+
+ mpfr_init (a);
+ mpfr_init (b);
+ mpfr_set_str (a, "2E100000000", 10, MPFR_RNDN);
+ mpfr_set_si (b, -10, MPFR_RNDN);
+ test_pow (b, a, b, MPFR_RNDN);
+ if (!MPFR_IS_ZERO(b))
+ {
+ printf("Pow(2E10000000, -10) failed\n");
+ mpfr_dump (a);
+ mpfr_dump (b);
+ exit(1);
+ }
+
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (-10);
+ mpfr_set_si (a, -2, MPFR_RNDN);
+ mpfr_pow_si (b, a, -10000, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (b))
+ {
+ printf ("Pow_so (1, -10000) doesn't underflow if emin=-10.\n");
+ mpfr_dump (a);
+ mpfr_dump (b);
+ exit (1);
+ }
+ mpfr_set_emin (emin);
+ mpfr_clear (a);
+ mpfr_clear (b);
+}
+
+static void
+pow_si_long_min (void)
+{
+ mpfr_t x, y, z;
+ int inex;
+
+ mpfr_inits2 (sizeof(long) * CHAR_BIT + 32, x, y, z, (mpfr_ptr) 0);
+ mpfr_set_si_2exp (x, 3, -1, MPFR_RNDN); /* 1.5 */
+
+ inex = mpfr_set_si (y, LONG_MIN, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ mpfr_nextbelow (y);
+ mpfr_pow (y, x, y, MPFR_RNDD);
+
+ inex = mpfr_set_si (z, LONG_MIN, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ mpfr_nextabove (z);
+ mpfr_pow (z, x, z, MPFR_RNDU);
+
+ mpfr_pow_si (x, x, LONG_MIN, MPFR_RNDN); /* 1.5^LONG_MIN */
+ if (mpfr_cmp (x, y) < 0 || mpfr_cmp (x, z) > 0)
+ {
+ printf ("Error in pow_si_long_min\n");
+ exit (1);
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+static void
+check_inexact (mpfr_prec_t p)
+{
+ mpfr_t x, y, z, t;
+ unsigned long u;
+ mpfr_prec_t q;
+ int inexact, cmp;
+ int rnd;
+
+ mpfr_init2 (x, p);
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (t);
+ mpfr_urandomb (x, RANDS);
+ u = randlimb () % 2;
+ for (q = 2; q <= p; q++)
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ mpfr_set_prec (y, q);
+ mpfr_set_prec (z, q + 10);
+ mpfr_set_prec (t, q);
+ inexact = mpfr_pow_ui (y, x, u, (mpfr_rnd_t) rnd);
+ cmp = mpfr_pow_ui (z, x, u, (mpfr_rnd_t) rnd);
+ if (mpfr_can_round (z, q + 10, (mpfr_rnd_t) rnd, (mpfr_rnd_t) rnd, q))
+ {
+ cmp = mpfr_set (t, z, (mpfr_rnd_t) rnd) || cmp;
+ if (mpfr_cmp (y, t))
+ {
+ printf ("results differ for u=%lu rnd=%s\n",
+ u, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ printf ("t="); mpfr_print_binary (t); puts ("");
+ printf ("z="); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+ if (((inexact == 0) && (cmp != 0)) ||
+ ((inexact != 0) && (cmp == 0)))
+ {
+ printf ("Wrong inexact flag for p=%u, q=%u, rnd=%s\n",
+ (unsigned int) p, (unsigned int) q,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("expected %d, got %d\n", cmp, inexact);
+ printf ("u=%lu x=", u); mpfr_print_binary (x); puts ("");
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ }
+ }
+
+ /* check exact power */
+ mpfr_set_prec (x, p);
+ mpfr_set_prec (y, p);
+ mpfr_set_prec (z, p);
+ mpfr_set_ui (x, 4, MPFR_RNDN);
+ mpfr_set_str (y, "0.5", 10, MPFR_RNDN);
+ test_pow (z, x, y, MPFR_RNDZ);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+}
+
+static void
+special (void)
+{
+ mpfr_t x, y, z, t;
+ mpfr_exp_t emin, emax;
+ int inex;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+ mpfr_init2 (z, 53);
+ mpfr_init2 (t, 2);
+
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_pow_si (x, x, -2, MPFR_RNDN);
+ if (mpfr_cmp_ui_2exp (x, 1, -2))
+ {
+ printf ("Error in pow_si(x,x,-2) for x=2\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_set_si (y, -2, MPFR_RNDN);
+ test_pow (x, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui_2exp (x, 1, -2))
+ {
+ printf ("Error in pow(x,x,y) for x=2, y=-2\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_str_binary (x, "1.0e-1");
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (y, "0.11010110011100101010110011001010100111000001000101110E-1");
+ mpfr_set_prec (z, 2);
+ test_pow (z, x, y, MPFR_RNDZ);
+ mpfr_set_str_binary (x, "1.0e-1");
+ if (mpfr_cmp (x, z))
+ {
+ printf ("Error in mpfr_pow (1)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 64);
+ mpfr_set_prec (y, 64);
+ mpfr_set_prec (z, 64);
+ mpfr_set_prec (t, 64);
+ mpfr_set_str_binary (x, "0.111011000111100000111010000101010100110011010000011");
+ mpfr_set_str_binary (y, "0.111110010100110000011101100011010111000010000100101");
+ mpfr_set_str_binary (t, "0.1110110011110110001000110100100001001111010011111000010000011001");
+
+ test_pow (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp (z, t))
+ {
+ printf ("Error in mpfr_pow for prec=64, rnd=MPFR_RNDN\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_prec (z, 53);
+ mpfr_set_str (x, "5.68824667828621954868e-01", 10, MPFR_RNDN);
+ mpfr_set_str (y, "9.03327850535952658895e-01", 10, MPFR_RNDN);
+ test_pow (z, x, y, MPFR_RNDZ);
+ if (mpfr_cmp_str1 (z, "0.60071044650456473235"))
+ {
+ printf ("Error in mpfr_pow for prec=53, rnd=MPFR_RNDZ\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (t, 2);
+ mpfr_set_prec (x, 30);
+ mpfr_set_prec (y, 30);
+ mpfr_set_prec (z, 30);
+ mpfr_set_str (x, "1.00000000001010111110001111011e1", 2, MPFR_RNDN);
+ mpfr_set_str (t, "-0.5", 10, MPFR_RNDN);
+ test_pow (z, x, t, MPFR_RNDN);
+ mpfr_set_str (y, "1.01101001111010101110000101111e-1", 2, MPFR_RNDN);
+ if (mpfr_cmp (z, y))
+ {
+ printf ("Error in mpfr_pow for prec=30, rnd=MPFR_RNDN\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 21);
+ mpfr_set_prec (y, 21);
+ mpfr_set_prec (z, 21);
+ mpfr_set_str (x, "1.11111100100001100101", 2, MPFR_RNDN);
+ test_pow (z, x, t, MPFR_RNDZ);
+ mpfr_set_str (y, "1.01101011010001100000e-1", 2, MPFR_RNDN);
+ if (mpfr_cmp (z, y))
+ {
+ printf ("Error in mpfr_pow for prec=21, rnd=MPFR_RNDZ\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ /* From http://www.terra.es/personal9/ismaeljc/hall.htm */
+ mpfr_set_prec (x, 113);
+ mpfr_set_prec (y, 2);
+ mpfr_set_prec (z, 169);
+ mpfr_set_str1 (x, "6078673043126084065007902175846955");
+ mpfr_set_ui_2exp (y, 3, -1, MPFR_RNDN);
+ test_pow (z, x, y, MPFR_RNDZ);
+ if (mpfr_cmp_str1 (z, "473928882491000966028828671876527456070714790264144"))
+ {
+ printf ("Error in mpfr_pow for 6078673043126084065007902175846955");
+ printf ("^(3/2), MPFR_RNDZ\nExpected ");
+ printf ("4.73928882491000966028828671876527456070714790264144e50");
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ test_pow (z, x, y, MPFR_RNDU);
+ if (mpfr_cmp_str1 (z, "473928882491000966028828671876527456070714790264145"))
+ {
+ printf ("Error in mpfr_pow for 6078673043126084065007902175846955");
+ printf ("^(3/2), MPFR_RNDU\nExpected ");
+ printf ("4.73928882491000966028828671876527456070714790264145e50");
+ printf ("\nGot ");
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_set_prec (y, 2);
+ mpfr_set_str_binary (y, "1E10");
+ test_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
+ mpfr_set_inf (x, -1);
+ test_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
+ mpfr_set_prec (y, 10);
+ mpfr_set_str_binary (y, "1.000000001E9");
+ test_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_NEG(z));
+ mpfr_set_str_binary (y, "1.000000001E8");
+ test_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
+
+ mpfr_set_inf (x, -1);
+ mpfr_set_prec (y, 2 * mp_bits_per_limb);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_mul_2exp (y, y, mp_bits_per_limb - 1, MPFR_RNDN);
+ /* y = 2^(mp_bits_per_limb - 1) */
+ test_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
+ mpfr_nextabove (y);
+ test_pow (z, x, y, MPFR_RNDN);
+ /* y = 2^(mp_bits_per_limb - 1) + epsilon */
+ MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
+ mpfr_nextbelow (y);
+ mpfr_div_2exp (y, y, 1, MPFR_RNDN);
+ mpfr_nextabove (y);
+ test_pow (z, x, y, MPFR_RNDN);
+ /* y = 2^(mp_bits_per_limb - 2) + epsilon */
+ MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS(z));
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_set_prec (y, 2);
+ mpfr_set_str_binary (y, "1E10");
+ test_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (z, 1) == 0);
+
+ /* Check (-0)^(17.0001) */
+ mpfr_set_prec (x, 6);
+ mpfr_set_prec (y, 640);
+ MPFR_SET_ZERO (x); MPFR_SET_NEG (x);
+ mpfr_set_ui (y, 17, MPFR_RNDN); mpfr_nextabove (y);
+ test_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
+
+ /* Bugs reported by Kevin Rauch on 29 Oct 2007 */
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ mpfr_set_emin (-1000000);
+ mpfr_set_emax ( 1000000);
+ mpfr_set_prec (x, 64);
+ mpfr_set_prec (y, 64);
+ mpfr_set_prec (z, 64);
+ mpfr_set_str (x, "-0.5", 10, MPFR_RNDN);
+ mpfr_set_str (y, "-0.ffffffffffffffff", 16, MPFR_RNDN);
+ mpfr_set_exp (y, mpfr_get_emax ());
+ inex = mpfr_pow (z, x, y, MPFR_RNDN);
+ /* (-0.5)^(-n) = 1/2^n for n even */
+ MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS (z) && inex > 0);
+
+ /* (-1)^(-n) = 1 for n even */
+ mpfr_set_str (x, "-1", 10, MPFR_RNDN);
+ inex = mpfr_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (z, 1) == 0 && inex == 0);
+
+ /* (-1)^n = 1 for n even */
+ mpfr_set_str (x, "-1", 10, MPFR_RNDN);
+ mpfr_neg (y, y, MPFR_RNDN);
+ inex = mpfr_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (z, 1) == 0 && inex == 0);
+
+ /* (-1.5)^n = +Inf for n even */
+ mpfr_set_str (x, "-1.5", 10, MPFR_RNDN);
+ inex = mpfr_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (z) && MPFR_IS_POS (z) && inex > 0);
+
+ /* (-n)^1.5 = NaN for n even */
+ mpfr_neg (y, y, MPFR_RNDN);
+ mpfr_set_str (x, "1.5", 10, MPFR_RNDN);
+ inex = mpfr_pow (z, y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (z));
+
+ /* x^(-1.5) = NaN for x small < 0 */
+ mpfr_set_str (x, "-0.8", 16, MPFR_RNDN);
+ mpfr_set_exp (x, mpfr_get_emin ());
+ mpfr_set_str (y, "-1.5", 10, MPFR_RNDN);
+ inex = mpfr_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (z));
+
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+}
+
+static void
+particular_cases (void)
+{
+ mpfr_t t[11], r, r2;
+ mpz_t z;
+ long si;
+
+ static const char *name[11] = {
+ "NaN", "+inf", "-inf", "+0", "-0", "+1", "-1", "+2", "-2", "+0.5", "-0.5"};
+ int i, j;
+ int error = 0;
+
+ mpz_init (z);
+
+ for (i = 0; i < 11; i++)
+ mpfr_init2 (t[i], 2);
+ mpfr_init2 (r, 6);
+ mpfr_init2 (r2, 6);
+
+ mpfr_set_nan (t[0]);
+ mpfr_set_inf (t[1], 1);
+ mpfr_set_ui (t[3], 0, MPFR_RNDN);
+ mpfr_set_ui (t[5], 1, MPFR_RNDN);
+ mpfr_set_ui (t[7], 2, MPFR_RNDN);
+ mpfr_div_2ui (t[9], t[5], 1, MPFR_RNDN);
+ for (i = 1; i < 11; i += 2)
+ mpfr_neg (t[i+1], t[i], MPFR_RNDN);
+
+ for (i = 0; i < 11; i++)
+ for (j = 0; j < 11; j++)
+ {
+ double d;
+ int p;
+ static const int q[11][11] = {
+ /* NaN +inf -inf +0 -0 +1 -1 +2 -2 +0.5 -0.5 */
+ /* NaN */ { 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0 },
+ /* +inf */ { 0, 1, 2, 128, 128, 1, 2, 1, 2, 1, 2 },
+ /* -inf */ { 0, 1, 2, 128, 128, -1, -2, 1, 2, 1, 2 },
+ /* +0 */ { 0, 2, 1, 128, 128, 2, 1, 2, 1, 2, 1 },
+ /* -0 */ { 0, 2, 1, 128, 128, -2, -1, 2, 1, 2, 1 },
+ /* +1 */ {128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+ /* -1 */ { 0, 128, 128, 128, 128,-128,-128, 128, 128, 0, 0 },
+ /* +2 */ { 0, 1, 2, 128, 128, 256, 64, 512, 32, 180, 90 },
+ /* -2 */ { 0, 1, 2, 128, 128,-256, -64, 512, 32, 0, 0 },
+ /* +0.5 */ { 0, 2, 1, 128, 128, 64, 256, 32, 512, 90, 180 },
+ /* -0.5 */ { 0, 2, 1, 128, 128, -64,-256, 32, 512, 0, 0 }
+ };
+ /* This define is used to make the following table readable */
+#define N MPFR_FLAGS_NAN
+#define I MPFR_FLAGS_INEXACT
+#define D MPFR_FLAGS_DIVBY0
+ static const unsigned int f[11][11] = {
+ /* NaN +inf -inf +0 -0 +1 -1 +2 -2 +0.5 -0.5 */
+ /* NaN */ { N, N, N, 0, 0, N, N, N, N, N, N },
+ /* +inf */ { N, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* -inf */ { N, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* +0 */ { N, 0, 0, 0, 0, 0, D, 0, D, 0, D },
+ /* -0 */ { N, 0, 0, 0, 0, 0, D, 0, D, 0, D },
+ /* +1 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* -1 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, N, N },
+ /* +2 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, I, I },
+ /* -2 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, N, N },
+ /* +0.5 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, I, I },
+ /* -0.5 */ { N, 0, 0, 0, 0, 0, 0, 0, 0, N, N }
+ };
+#undef N
+#undef I
+#undef D
+ mpfr_clear_flags ();
+ test_pow (r, t[i], t[j], MPFR_RNDN);
+ p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 :
+ mpfr_cmp_ui (r, 0) == 0 ? 2 :
+ (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0));
+ if (p != 0 && MPFR_IS_NEG (r))
+ p = -p;
+ if (p != q[i][j])
+ {
+ printf ("Error in mpfr_pow for (%s)^(%s) (%d,%d):\n"
+ "got %d instead of %d\n",
+ name[i], name[j], i, j, p, q[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ if (__gmpfr_flags != f[i][j])
+ {
+ printf ("Error in mpfr_pow for (%s)^(%s) (%d,%d):\n"
+ "Flags = %u instead of expected %u\n",
+ name[i], name[j], i, j, __gmpfr_flags, f[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ /* Perform the same tests with pow_z & pow_si & pow_ui
+ if t[j] is an integer */
+ if (mpfr_integer_p (t[j]))
+ {
+ /* mpfr_pow_z */
+ mpfr_clear_flags ();
+ mpfr_get_z (z, t[j], MPFR_RNDN);
+ mpfr_pow_z (r, t[i], z, MPFR_RNDN);
+ p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 :
+ mpfr_cmp_ui (r, 0) == 0 ? 2 :
+ (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0));
+ if (p != 0 && MPFR_IS_NEG (r))
+ p = -p;
+ if (p != q[i][j])
+ {
+ printf ("Error in mpfr_pow_z for (%s)^(%s) (%d,%d):\n"
+ "got %d instead of %d\n",
+ name[i], name[j], i, j, p, q[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ if (__gmpfr_flags != f[i][j])
+ {
+ printf ("Error in mpfr_pow_z for (%s)^(%s) (%d,%d):\n"
+ "Flags = %u instead of expected %u\n",
+ name[i], name[j], i, j, __gmpfr_flags, f[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ /* mpfr_pow_si */
+ mpfr_clear_flags ();
+ si = mpfr_get_si (t[j], MPFR_RNDN);
+ mpfr_pow_si (r, t[i], si, MPFR_RNDN);
+ p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 :
+ mpfr_cmp_ui (r, 0) == 0 ? 2 :
+ (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0));
+ if (p != 0 && MPFR_IS_NEG (r))
+ p = -p;
+ if (p != q[i][j])
+ {
+ printf ("Error in mpfr_pow_si for (%s)^(%s) (%d,%d):\n"
+ "got %d instead of %d\n",
+ name[i], name[j], i, j, p, q[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ if (__gmpfr_flags != f[i][j])
+ {
+ printf ("Error in mpfr_pow_si for (%s)^(%s) (%d,%d):\n"
+ "Flags = %u instead of expected %u\n",
+ name[i], name[j], i, j, __gmpfr_flags, f[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ /* if si >= 0, test mpfr_pow_ui */
+ if (si >= 0)
+ {
+ mpfr_clear_flags ();
+ mpfr_pow_ui (r, t[i], si, MPFR_RNDN);
+ p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 :
+ mpfr_cmp_ui (r, 0) == 0 ? 2 :
+ (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0));
+ if (p != 0 && MPFR_IS_NEG (r))
+ p = -p;
+ if (p != q[i][j])
+ {
+ printf ("Error in mpfr_pow_ui for (%s)^(%s) (%d,%d):\n"
+ "got %d instead of %d\n",
+ name[i], name[j], i, j, p, q[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ if (__gmpfr_flags != f[i][j])
+ {
+ printf ("Error in mpfr_pow_ui for (%s)^(%s) (%d,%d):\n"
+ "Flags = %u instead of expected %u\n",
+ name[i], name[j], i, j, __gmpfr_flags, f[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ }
+ } /* integer_p */
+ /* Perform the same tests with mpfr_ui_pow */
+ if (mpfr_integer_p (t[i]) && MPFR_IS_POS (t[i]))
+ {
+ /* mpfr_ui_pow */
+ mpfr_clear_flags ();
+ si = mpfr_get_si (t[i], MPFR_RNDN);
+ mpfr_ui_pow (r, si, t[j], MPFR_RNDN);
+ p = mpfr_nan_p (r) ? 0 : mpfr_inf_p (r) ? 1 :
+ mpfr_cmp_ui (r, 0) == 0 ? 2 :
+ (d = mpfr_get_d (r, MPFR_RNDN), (int) (ABS(d) * 128.0));
+ if (p != 0 && MPFR_IS_NEG (r))
+ p = -p;
+ if (p != q[i][j])
+ {
+ printf ("Error in mpfr_ui_pow for (%s)^(%s) (%d,%d):\n"
+ "got %d instead of %d\n",
+ name[i], name[j], i, j, p, q[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ if (__gmpfr_flags != f[i][j])
+ {
+ printf ("Error in mpfr_ui_pow for (%s)^(%s) (%d,%d):\n"
+ "Flags = %u instead of expected %u\n",
+ name[i], name[j], i, j, __gmpfr_flags, f[i][j]);
+ mpfr_dump (r);
+ error = 1;
+ }
+ }
+ }
+
+ for (i = 0; i < 11; i++)
+ mpfr_clear (t[i]);
+ mpfr_clear (r);
+ mpfr_clear (r2);
+ mpz_clear (z);
+
+ if (error)
+ exit (1);
+}
+
+static void
+underflows (void)
+{
+ mpfr_t x, y, z;
+ int err = 0;
+ int inexact;
+ int i;
+ mpfr_exp_t emin;
+
+ mpfr_init2 (x, 64);
+ mpfr_init2 (y, 64);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_exp (x, mpfr_get_emin());
+
+ for (i = 3; i < 10; i++)
+ {
+ mpfr_set_ui (y, i, MPFR_RNDN);
+ mpfr_div_2ui (y, y, 1, MPFR_RNDN);
+ test_pow (y, x, y, MPFR_RNDN);
+ if (!MPFR_IS_FP(y) || mpfr_cmp_ui (y, 0))
+ {
+ printf ("Error in mpfr_pow for ");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf (" ^ (%d/2)\nGot ", i);
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf (" instead of 0.\n");
+ exit (1);
+ }
+ }
+
+ mpfr_init2 (z, 55);
+ mpfr_set_str (x, "0.110011010011101001110001110100010000110111101E0",
+ 2, MPFR_RNDN);
+ mpfr_set_str (y, "0.101110010011111001011010100011011100111110011E40",
+ 2, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_pow (z, x, y, MPFR_RNDU);
+ if (!mpfr_underflow_p ())
+ {
+ printf ("Underflow flag is not set for special underflow test.\n");
+ err = 1;
+ }
+ if (inexact <= 0)
+ {
+ printf ("Ternary value is wrong for special underflow test.\n");
+ err = 1;
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_nextabove (x);
+ if (mpfr_cmp (x, z) != 0)
+ {
+ printf ("Wrong value for special underflow test.\nGot ");
+ mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf ("\ninstead of ");
+ mpfr_out_str (stdout, 2, 2, x, MPFR_RNDN);
+ printf ("\n");
+ err = 1;
+ }
+ if (err)
+ exit (1);
+
+ /* MPFR currently (2006-08-19) segfaults on the following code (and
+ possibly makes other programs crash due to the lack of memory),
+ because y is converted into an mpz_t, and the required precision
+ is too high. */
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 2);
+ mpfr_set_prec (z, 12);
+ mpfr_set_ui_2exp (x, 3, -2, MPFR_RNDN);
+ mpfr_set_ui_2exp (y, 1, mpfr_get_emax () - 1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ mpfr_pow (z, x, y, MPFR_RNDN);
+ if (!mpfr_underflow_p () || MPFR_NOTZERO (z))
+ {
+ printf ("Underflow test with large y fails.\n");
+ exit (1);
+ }
+
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (-256);
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 2);
+ mpfr_set_prec (z, 12);
+ mpfr_set_ui_2exp (x, 3, -2, MPFR_RNDN);
+ mpfr_set_ui_2exp (y, 1, 38, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_pow (z, x, y, MPFR_RNDN);
+ if (!mpfr_underflow_p () || MPFR_NOTZERO (z) || inexact >= 0)
+ {
+ printf ("Bad underflow detection for 0.75^(2^38). Obtained:\n"
+ "Underflow flag... %-3s (should be 'yes')\n"
+ "Zero result...... %-3s (should be 'yes')\n"
+ "Inexact value.... %-3d (should be negative)\n",
+ mpfr_underflow_p () ? "yes" : "no",
+ MPFR_IS_ZERO (z) ? "yes" : "no", inexact);
+ exit (1);
+ }
+ mpfr_set_emin (emin);
+
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (-256);
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 40);
+ mpfr_set_prec (z, 12);
+ mpfr_set_ui_2exp (x, 3, -1, MPFR_RNDN);
+ mpfr_set_si_2exp (y, -1, 38, MPFR_RNDN);
+ for (i = 0; i < 4; i++)
+ {
+ if (i == 2)
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_pow (z, x, y, MPFR_RNDN);
+ if (!mpfr_underflow_p () || MPFR_NOTZERO (z) ||
+ (i == 3 ? (inexact <= 0) : (inexact >= 0)))
+ {
+ printf ("Bad underflow detection for (");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf (")^(-2^38-%d). Obtained:\n"
+ "Overflow flag.... %-3s (should be 'no')\n"
+ "Underflow flag... %-3s (should be 'yes')\n"
+ "Zero result...... %-3s (should be 'yes')\n"
+ "Inexact value.... %-3d (should be %s)\n", i,
+ mpfr_overflow_p () ? "yes" : "no",
+ mpfr_underflow_p () ? "yes" : "no",
+ MPFR_IS_ZERO (z) ? "yes" : "no", inexact,
+ i == 3 ? "positive" : "negative");
+ exit (1);
+ }
+ inexact = mpfr_sub_ui (y, y, 1, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ }
+ mpfr_set_emin (emin);
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+static void
+overflows (void)
+{
+ mpfr_t a, b;
+
+ /* bug found by Ming J. Tsai <mingjt@delvron.us>, 4 Oct 2003 */
+
+ mpfr_init_set_str (a, "5.1e32", 10, MPFR_RNDN);
+ mpfr_init (b);
+
+ test_pow (b, a, a, MPFR_RNDN);
+ if (!(mpfr_inf_p (b) && mpfr_sgn (b) > 0))
+ {
+ printf ("Error for a^a for a=5.1e32\n");
+ printf ("Expected +Inf, got ");
+ mpfr_out_str (stdout, 10, 0, b, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clear(a);
+ mpfr_clear(b);
+}
+
+static void
+overflows2 (void)
+{
+ mpfr_t x, y, z;
+ mpfr_exp_t emin, emax;
+ int e;
+
+ /* x^y in reduced exponent range, where x = 2^b and y is not an integer
+ (so that mpfr_pow_z is not used). */
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ set_emin (-128);
+
+ mpfr_inits2 (16, x, y, z, (mpfr_ptr) 0);
+
+ mpfr_set_si_2exp (x, 1, -64, MPFR_RNDN); /* 2^(-64) */
+ mpfr_set_si_2exp (y, -1, -1, MPFR_RNDN); /* -0.5 */
+ for (e = 2; e <= 32; e += 17)
+ {
+ set_emax (e);
+ mpfr_clear_flags ();
+ mpfr_pow (z, x, y, MPFR_RNDN);
+ if (MPFR_IS_NEG (z) || ! mpfr_inf_p (z))
+ {
+ printf ("Error in overflows2 (e = %d): expected +Inf, got ", e);
+ mpfr_dump (z);
+ exit (1);
+ }
+ if (__gmpfr_flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT))
+ {
+ printf ("Error in overflows2 (e = %d): bad flags (%u)\n",
+ e, __gmpfr_flags);
+ exit (1);
+ }
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+
+ set_emin (emin);
+ set_emax (emax);
+}
+
+static void
+overflows3 (void)
+{
+ /* x^y where x = 2^b, y is not an integer (so that mpfr_pow_z is not used)
+ and b * y = emax in the extended exponent range. If emax is divisible
+ by 3, we choose x = 2^(-2*emax/3) and y = -3/2.
+ Test also with nextbelow(x). */
+
+ if (MPFR_EMAX_MAX % 3 == 0)
+ {
+ mpfr_t x, y, z, t;
+ mpfr_exp_t emin, emax;
+ unsigned int flags;
+ int i;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ set_emin (MPFR_EMIN_MIN);
+ set_emax (MPFR_EMAX_MAX);
+
+ mpfr_inits2 (16, x, y, z, t, (mpfr_ptr) 0);
+
+ mpfr_set_si_2exp (x, 1, -2 * (MPFR_EMAX_MAX / 3), MPFR_RNDN);
+ for (i = 0; i <= 1; i++)
+ {
+ mpfr_set_si_2exp (y, -3, -1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ mpfr_pow (z, x, y, MPFR_RNDN);
+ if (MPFR_IS_NEG (z) || ! mpfr_inf_p (z))
+ {
+ printf ("Error in overflows3 (RNDN, i = %d): expected +Inf,"
+ " got ", i);
+ mpfr_dump (z);
+ exit (1);
+ }
+ if (__gmpfr_flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT))
+ {
+ printf ("Error in overflows3 (RNDN, i = %d): bad flags (%u)\n",
+ i, __gmpfr_flags);
+ exit (1);
+ }
+
+ mpfr_clear_flags ();
+ mpfr_pow (z, x, y, MPFR_RNDZ);
+ flags = __gmpfr_flags;
+ mpfr_set (t, z, MPFR_RNDN);
+ mpfr_nextabove (t);
+ if (MPFR_IS_NEG (z) || mpfr_inf_p (z) || ! mpfr_inf_p (t))
+ {
+ printf ("Error in overflows3 (RNDZ, i = %d):\nexpected ", i);
+ mpfr_set_inf (t, 1);
+ mpfr_nextbelow (t);
+ mpfr_dump (t);
+ printf ("got ");
+ mpfr_dump (z);
+ exit (1);
+ }
+ if (flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT))
+ {
+ printf ("Error in overflows3 (RNDZ, i = %d): bad flags (%u)\n",
+ i, flags);
+ exit (1);
+ }
+ mpfr_nextbelow (x);
+ }
+
+ mpfr_clears (x, y, z, t, (mpfr_ptr) 0);
+
+ set_emin (emin);
+ set_emax (emax);
+ }
+}
+
+static void
+x_near_one (void)
+{
+ mpfr_t x, y, z;
+ int inex;
+
+ mpfr_init2 (x, 32);
+ mpfr_init2 (y, 4);
+ mpfr_init2 (z, 33);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_nextbelow (x);
+ mpfr_set_ui_2exp (y, 11, -2, MPFR_RNDN);
+ inex = mpfr_pow (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_str (z, "0.111111111111111111111111111111011E0", 2, MPFR_RNDN)
+ || inex <= 0)
+ {
+ printf ("Failure in x_near_one, got inex = %d and\nz = ", inex);
+ mpfr_dump (z);
+ }
+
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+static int
+mpfr_pow275 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r)
+{
+ mpfr_t z;
+ int inex;
+
+ mpfr_init2 (z, 4);
+ mpfr_set_ui_2exp (z, 11, -2, MPFR_RNDN);
+ inex = mpfr_pow (y, x, z, MPFR_RNDN);
+ mpfr_clear (z);
+ return inex;
+}
+
+/* Bug found by Kevin P. Rauch */
+static void
+bug20071103 (void)
+{
+ mpfr_t x, y, z;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ mpfr_set_emin (-1000000);
+ mpfr_set_emax ( 1000000);
+
+ mpfr_inits2 (64, x, y, z, (mpfr_ptr) 0);
+ mpfr_set_si_2exp (x, -3, -1, MPFR_RNDN); /* x = -1.5 */
+ mpfr_set_str (y, "-0.ffffffffffffffff", 16, MPFR_RNDN);
+ mpfr_set_exp (y, mpfr_get_emax ());
+ mpfr_clear_flags ();
+ mpfr_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_zero_p (z) && MPFR_SIGN (z) > 0 &&
+ __gmpfr_flags == (MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT));
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+
+ set_emin (emin);
+ set_emax (emax);
+}
+
+/* Bug found by Kevin P. Rauch */
+static void
+bug20071104 (void)
+{
+ mpfr_t x, y, z;
+ mpfr_exp_t emin, emax;
+ int inex;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ mpfr_set_emin (-1000000);
+ mpfr_set_emax ( 1000000);
+
+ mpfr_inits2 (20, x, y, z, (mpfr_ptr) 0);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_nextbelow (x); /* x = -2^(emin-1) */
+ mpfr_set_si (y, -2, MPFR_RNDN); /* y = -2 */
+ mpfr_clear_flags ();
+ inex = mpfr_pow (z, x, y, MPFR_RNDN);
+ if (! mpfr_inf_p (z) || MPFR_SIGN (z) < 0)
+ {
+ printf ("Error in bug20071104: expected +Inf, got ");
+ mpfr_dump (z);
+ exit (1);
+ }
+ if (inex <= 0)
+ {
+ printf ("Error in bug20071104: bad ternary value (%d)\n", inex);
+ exit (1);
+ }
+ if (__gmpfr_flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT))
+ {
+ printf ("Error in bug20071104: bad flags (%u)\n", __gmpfr_flags);
+ exit (1);
+ }
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+
+ set_emin (emin);
+ set_emax (emax);
+}
+
+/* Bug found by Kevin P. Rauch */
+static void
+bug20071127 (void)
+{
+ mpfr_t x, y, z;
+ int i, tern;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ mpfr_set_emin (-1000000);
+ mpfr_set_emax ( 1000000);
+
+ mpfr_init2 (x, 128);
+ mpfr_init2 (y, 128);
+ mpfr_init2 (z, 128);
+
+ mpfr_set_str (x, "0.80000000000000000000000000000001", 16, MPFR_RNDN);
+
+ for (i = 1; i < 9; i *= 2)
+ {
+ mpfr_set_str (y, "8000000000000000", 16, MPFR_RNDN);
+ mpfr_add_si (y, y, i, MPFR_RNDN);
+ tern = mpfr_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_zero_p (z) && MPFR_IS_POS (z) && tern < 0);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+}
+
+/* Bug found by Kevin P. Rauch */
+static void
+bug20071128 (void)
+{
+ mpfr_t max_val, x, y, z;
+ int i, tern;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ mpfr_set_emin (-1000000);
+ mpfr_set_emax ( 1000000);
+
+ mpfr_init2 (max_val, 64);
+ mpfr_init2 (x, 64);
+ mpfr_init2 (y, 64);
+ mpfr_init2 (z, 64);
+
+ mpfr_set_str (max_val, "0.ffffffffffffffff", 16, MPFR_RNDN);
+ mpfr_set_exp (max_val, mpfr_get_emax ());
+
+ mpfr_neg (x, max_val, MPFR_RNDN);
+
+ /* on 64-bit machines */
+ for (i = 41; i < 45; i++)
+ {
+ mpfr_set_si_2exp (y, -1, i, MPFR_RNDN);
+ mpfr_add_si (y, y, 1, MPFR_RNDN);
+ tern = mpfr_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_zero_p (z) && MPFR_IS_NEG (z) && tern > 0);
+ }
+
+ /* on 32-bit machines */
+ for (i = 9; i < 13; i++)
+ {
+ mpfr_set_si_2exp (y, -1, i, MPFR_RNDN);
+ mpfr_add_si (y, y, 1, MPFR_RNDN);
+ tern = mpfr_pow (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_zero_p (z) && MPFR_SIGN(z) < 0);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (max_val);
+
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+}
+
+/* Bug found by Kevin P. Rauch */
+static void
+bug20071218 (void)
+{
+ mpfr_t x, y, z, t;
+ int tern;
+
+ mpfr_inits2 (64, x, y, z, t, (mpfr_ptr) 0);
+ mpfr_set_str (x, "0x.80000000000002P-1023", 0, MPFR_RNDN);
+ mpfr_set_str (y, "100000.000000002", 16, MPFR_RNDN);
+ mpfr_set_ui (t, 0, MPFR_RNDN);
+ mpfr_nextabove (t);
+ tern = mpfr_pow (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp0 (z, t) != 0)
+ {
+ printf ("Error in bug20071218 (1): Expected\n");
+ mpfr_dump (t);
+ printf ("Got\n");
+ mpfr_dump (z);
+ exit (1);
+ }
+ if (tern <= 0)
+ {
+ printf ("Error in bug20071218 (1): bad ternary value"
+ " (%d instead of positive)\n", tern);
+ exit (1);
+ }
+ mpfr_mul_2ui (y, y, 32, MPFR_RNDN);
+ tern = mpfr_pow (z, x, y, MPFR_RNDN);
+ if (MPFR_NOTZERO (z) || MPFR_IS_NEG (z))
+ {
+ printf ("Error in bug20071218 (2): expected 0, got\n");
+ mpfr_dump (z);
+ exit (1);
+ }
+ if (tern >= 0)
+ {
+ printf ("Error in bug20071218 (2): bad ternary value"
+ " (%d instead of negative)\n", tern);
+ exit (1);
+ }
+ mpfr_clears (x, y, z, t, (mpfr_ptr) 0);
+}
+
+/* With revision 5429, this gives:
+ * pow.c:43: assertion failed: !mpfr_integer_p (y)
+ * This is fixed in revision 5432.
+ */
+static void
+bug20080721 (void)
+{
+ mpfr_t x, y, z, t[2];
+ int inex;
+ int rnd;
+ int err = 0;
+
+ /* Note: input values have been chosen in a way to select the
+ * general case. If mpfr_pow is modified, in particular line
+ * if (y_is_integer && (MPFR_GET_EXP (y) <= 256))
+ * make sure that this test still does what we want.
+ */
+ mpfr_inits2 (4913, x, y, (mpfr_ptr) 0);
+ mpfr_inits2 (8, z, t[0], t[1], (mpfr_ptr) 0);
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_nextbelow (x);
+ mpfr_set_ui_2exp (y, 1, mpfr_get_prec (y) - 1, MPFR_RNDN);
+ inex = mpfr_add_ui (y, y, 1, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ mpfr_set_str_binary (t[0], "-0.10101101e2");
+ mpfr_set_str_binary (t[1], "-0.10101110e2");
+ RND_LOOP (rnd)
+ {
+ int i, inex0;
+
+ i = (rnd == MPFR_RNDN || rnd == MPFR_RNDD || rnd == MPFR_RNDA);
+ inex0 = i ? -1 : 1;
+ mpfr_clear_flags ();
+ inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd);
+ if (__gmpfr_flags != MPFR_FLAGS_INEXACT || ! SAME_SIGN (inex, inex0)
+ || MPFR_IS_NAN (z) || mpfr_cmp (z, t[i]) != 0)
+ {
+ unsigned int flags = __gmpfr_flags;
+
+ printf ("Error in bug20080721 with %s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, 0, t[i], MPFR_RNDN);
+ printf (", inex = %d, flags = %u\n", inex0,
+ (unsigned int) MPFR_FLAGS_INEXACT);
+ printf ("got ");
+ mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
+ printf (", inex = %d, flags = %u\n", inex, flags);
+ err = 1;
+ }
+ }
+ mpfr_clears (x, y, z, t[0], t[1], (mpfr_ptr) 0);
+ if (err)
+ exit (1);
+}
+
+/* The following test fails in r5552 (32-bit and 64-bit). This is due to:
+ * mpfr_log (t, absx, MPFR_RNDU);
+ * mpfr_mul (t, y, t, MPFR_RNDU);
+ * in pow.c, that is supposed to compute an upper bound on exp(y*ln|x|),
+ * but this is incorrect if y is negative.
+ */
+static void
+bug20080820 (void)
+{
+ mpfr_exp_t emin;
+ mpfr_t x, y, z1, z2;
+
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (MPFR_EMIN_MIN);
+ mpfr_init2 (x, 80);
+ mpfr_init2 (y, sizeof (mpfr_exp_t) * CHAR_BIT + 32);
+ mpfr_init2 (z1, 2);
+ mpfr_init2 (z2, 80);
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_nextbelow (x);
+ mpfr_set_exp_t (y, mpfr_get_emin () - 2, MPFR_RNDN);
+ mpfr_nextabove (y);
+ mpfr_pow (z1, x, y, MPFR_RNDN);
+ mpfr_pow (z2, x, y, MPFR_RNDN);
+ /* As x > 0, the rounded value of x^y to nearest in precision p is equal
+ to 0 iff x^y <= 2^(emin - 2). In particular, this does not depend on
+ the precision p. Hence the following test. */
+ if (MPFR_IS_ZERO (z1) && MPFR_NOTZERO (z2))
+ {
+ printf ("Error in bug20080820\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
+ set_emin (emin);
+}
+
+static void
+bug20110320 (void)
+{
+ mpfr_exp_t emin;
+ mpfr_t x, y, z1, z2;
+ int inex;
+ unsigned int flags;
+
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (11);
+ mpfr_inits2 (2, x, y, z1, z2, (mpfr_ptr) 0);
+ mpfr_set_ui_2exp (x, 1, 215, MPFR_RNDN);
+ mpfr_set_ui (y, 1024, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_pow (z1, x, y, MPFR_RNDN);
+ flags = __gmpfr_flags;
+ mpfr_set_ui_2exp (z2, 1, 215*1024, MPFR_RNDN);
+ if (inex != 0 || flags != 0 || ! mpfr_equal_p (z1, z2))
+ {
+ printf ("Error in bug20110320\n");
+ printf ("Expected inex = 0, flags = 0, z = ");
+ mpfr_dump (z2);
+ printf ("Got inex = %d, flags = %u, z = ", inex, flags);
+ mpfr_dump (z1);
+ exit (1);
+ }
+ mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
+ set_emin (emin);
+}
+
+int
+main (int argc, char **argv)
+{
+ mpfr_prec_t p;
+
+ tests_start_mpfr ();
+
+ bug20071127 ();
+ special ();
+ particular_cases ();
+ check_pow_ui ();
+ check_pow_si ();
+ check_special_pow_si ();
+ pow_si_long_min ();
+ for (p = 2; p < 100; p++)
+ check_inexact (p);
+ underflows ();
+ overflows ();
+ overflows2 ();
+ overflows3 ();
+ x_near_one ();
+ bug20071103 ();
+ bug20071104 ();
+ bug20071128 ();
+ bug20071218 ();
+ bug20080721 ();
+ bug20080820 ();
+ bug20110320 ();
+
+ test_generic (2, 100, 100);
+ test_generic_ui (2, 100, 100);
+ test_generic_si (2, 100, 100);
+
+ data_check ("data/pow275", mpfr_pow275, "mpfr_pow275");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tpow3.c b/mpfr/tests/tpow3.c
new file mode 100644
index 0000000000..95350a8ede
--- /dev/null
+++ b/mpfr/tests/tpow3.c
@@ -0,0 +1,126 @@
+/* Test file for mpfr_pow.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y, z;
+
+ mpfr_prec_t prec, yprec;
+ mpfr_t t, s;
+ mpfr_rnd_t rnd;
+ int inexact, compare, compare2;
+ unsigned int n, err;
+
+ mpfr_prec_t p0=2, p1=100;
+ unsigned int N=25;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init2 (y,sizeof(unsigned long int)*CHAR_BIT);
+ mpfr_init (z);
+
+ mpfr_init (s);
+ mpfr_init (t);
+
+ /* generic test */
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (s, sizeof(unsigned long int)*CHAR_BIT);
+ mpfr_set_prec (z, prec);
+ mpfr_set_prec (t, prec);
+ yprec = prec + 10;
+
+ for (n=0; n<N; n++)
+ {
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (s, RANDS);
+ if (randlimb () % 2)
+ mpfr_neg (s, s, MPFR_RNDN);
+ rnd = RND_RAND ();
+ mpfr_set_prec (y, yprec);
+ compare = mpfr_pow (y, x, s, rnd);
+ err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec;
+ if (mpfr_can_round (y, err, rnd, rnd, prec))
+ {
+ mpfr_set (t, y, rnd);
+ inexact = mpfr_pow (z, x, s, rnd);
+ if (mpfr_cmp (t, z))
+ {
+ printf ("results differ for x^y with x=");
+ mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
+ printf (" y=");
+ mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN);
+ printf (" prec=%u rnd_mode=%s\n", (unsigned int) prec,
+ mpfr_print_rnd_mode (rnd));
+ printf ("got ");
+ mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
+ puts ("");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
+ puts ("");
+ printf ("approx ");
+ mpfr_print_binary (y);
+ puts ("");
+ exit (1);
+ }
+ compare2 = mpfr_cmp (t, y);
+ /* if rounding to nearest, cannot know the sign of t - f(x)
+ because of composed rounding: y = o(f(x)) and t = o(y) */
+ if ((rnd != MPFR_RNDN) && (compare * compare2 >= 0))
+ compare = compare + compare2;
+ else
+ compare = inexact; /* cannot determine sign(t-f(x)) */
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact > 0) && (compare <= 0)) ||
+ ((inexact < 0) && (compare >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
+ "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ printf ("t="); mpfr_print_binary (t); puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (s);
+ mpfr_clear (t);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tpow_all.c b/mpfr/tests/tpow_all.c
new file mode 100644
index 0000000000..1fdee7faf4
--- /dev/null
+++ b/mpfr/tests/tpow_all.c
@@ -0,0 +1,778 @@
+/* Test file for the various power functions
+
+Copyright 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Note: some tests of the other tpow* test files could be moved there.
+ The main goal of this test file is to test _all_ the power functions
+ on special values, to make sure that they are consistent and give the
+ expected result, in particular because such special cases are handled
+ in different ways in each function. */
+
+/* Execute with at least an argument to report all the errors found by
+ comparisons. */
+
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* Behavior of cmpres (called by test_others):
+ * 0: stop as soon as an error is found.
+ * 1: report all errors found by test_others.
+ * -1: the 1 is changed to this value as soon as an error has been found.
+ */
+static int all_cmpres_errors;
+
+/* Non-zero when extended exponent range */
+static int ext = 0;
+
+static const char *val[] =
+ { "min", "min+", "max", "@NaN@", "-@Inf@", "-4", "-3", "-2", "-1.5",
+ "-1", "-0.5", "-0", "0", "0.5", "1", "1.5", "2", "3", "4", "@Inf@" };
+
+static void
+err (const char *s, int i, int j, int rnd, mpfr_srcptr z, int inex)
+{
+ puts (s);
+ if (ext)
+ puts ("extended exponent range");
+ printf ("x = %s, y = %s, %s\n", val[i], val[j],
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("z = ");
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\ninex = %d\n", inex);
+ exit (1);
+}
+
+/* Arguments:
+ * spx: non-zero if px is a stringm zero if px is a MPFR number.
+ * px: value of x (string or MPFR number).
+ * sy: value of y (string).
+ * rnd: rounding mode.
+ * z1: expected result (null pointer if unknown pure FP value).
+ * inex1: expected ternary value (if z1 is not a null pointer).
+ * z2: computed result.
+ * inex2: computed ternary value.
+ * flags1: expected flags (computed flags in __gmpfr_flags).
+ * s1, s2: strings about the context.
+ */
+static void
+cmpres (int spx, const void *px, const char *sy, mpfr_rnd_t rnd,
+ mpfr_srcptr z1, int inex1, mpfr_srcptr z2, int inex2,
+ unsigned int flags1, const char *s1, const char *s2)
+{
+ unsigned int flags2 = __gmpfr_flags;
+
+ if (flags1 == flags2)
+ {
+ /* Note: the test on the sign of z1 and z2 is needed
+ in case they are both zeros. */
+ if (z1 == NULL)
+ {
+ if (MPFR_IS_PURE_FP (z2))
+ return;
+ }
+ else if (SAME_SIGN (inex1, inex2) &&
+ ((MPFR_IS_NAN (z1) && MPFR_IS_NAN (z2)) ||
+ ((MPFR_IS_NEG (z1) ^ MPFR_IS_NEG (z2)) == 0 &&
+ mpfr_equal_p (z1, z2))))
+ return;
+ }
+
+ printf ("Error in %s\nwith %s%s\nx = ", s1, s2,
+ ext ? ", extended exponent range" : "");
+ if (spx)
+ printf ("%s, ", (char *) px);
+ else
+ {
+ mpfr_out_str (stdout, 16, 0, (mpfr_ptr) px, MPFR_RNDN);
+ puts (",");
+ }
+ printf ("y = %s, %s\n", sy, mpfr_print_rnd_mode (rnd));
+ printf ("Expected ");
+ if (z1 == NULL)
+ {
+ printf ("pure FP value, flags = %u\n", flags1);
+ }
+ else
+ {
+ mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN);
+ printf (", inex = %d, flags = %u\n", SIGN (inex1), flags1);
+ }
+ printf ("Got ");
+ mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN);
+ printf (", inex = %d, flags = %u\n", SIGN (inex2), flags2);
+ if (all_cmpres_errors != 0)
+ all_cmpres_errors = -1;
+ else
+ exit (1);
+}
+
+static int
+is_odd (mpfr_srcptr x)
+{
+ /* works only with the values from val[] */
+ return mpfr_integer_p (x) && mpfr_fits_slong_p (x, MPFR_RNDN) &&
+ (mpfr_get_si (x, MPFR_RNDN) & 1);
+}
+
+/* Compare the result (z1,inex1) of mpfr_pow with all flags cleared
+ with those of mpfr_pow with all flags set and of the other power
+ functions. Arguments x and y are the input values; sx and sy are
+ their string representations (sx may be null); rnd contains the
+ rounding mode; s is a string containing the function that called
+ test_others. */
+static void
+test_others (const void *sx, const char *sy, mpfr_rnd_t rnd,
+ mpfr_srcptr x, mpfr_srcptr y, mpfr_srcptr z1,
+ int inex1, unsigned int flags, const char *s)
+{
+ mpfr_t z2;
+ int inex2;
+ int spx = sx != NULL;
+
+ if (!spx)
+ sx = x;
+
+ mpfr_init2 (z2, mpfr_get_prec (z1));
+
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_pow (z2, x, y, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_pow, flags set");
+
+ /* If y is an integer that fits in an unsigned long and is not -0,
+ we can test mpfr_pow_ui. */
+ if (MPFR_IS_POS (y) && mpfr_integer_p (y) &&
+ mpfr_fits_ulong_p (y, MPFR_RNDN))
+ {
+ unsigned long yy = mpfr_get_ui (y, MPFR_RNDN);
+
+ mpfr_clear_flags ();
+ inex2 = mpfr_pow_ui (z2, x, yy, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_pow_ui, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_pow_ui (z2, x, yy, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_pow_ui, flags set");
+
+ /* If x is an integer that fits in an unsigned long and is not -0,
+ we can also test mpfr_ui_pow_ui. */
+ if (MPFR_IS_POS (x) && mpfr_integer_p (x) &&
+ mpfr_fits_ulong_p (x, MPFR_RNDN))
+ {
+ unsigned long xx = mpfr_get_ui (x, MPFR_RNDN);
+
+ mpfr_clear_flags ();
+ inex2 = mpfr_ui_pow_ui (z2, xx, yy, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_ui_pow_ui, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_ui_pow_ui (z2, xx, yy, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_ui_pow_ui, flags set");
+ }
+ }
+
+ /* If y is an integer but not -0 and not huge, we can test mpfr_pow_z,
+ and possibly mpfr_pow_si (and possibly mpfr_ui_div). */
+ if (MPFR_IS_ZERO (y) ? MPFR_IS_POS (y) :
+ (mpfr_integer_p (y) && MPFR_GET_EXP (y) < 256))
+ {
+ mpz_t yyy;
+
+ /* If y fits in a long, we can test mpfr_pow_si. */
+ if (mpfr_fits_slong_p (y, MPFR_RNDN))
+ {
+ long yy = mpfr_get_si (y, MPFR_RNDN);
+
+ mpfr_clear_flags ();
+ inex2 = mpfr_pow_si (z2, x, yy, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_pow_si, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_pow_si (z2, x, yy, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_pow_si, flags set");
+
+ /* If y = -1, we can test mpfr_ui_div. */
+ if (yy == -1)
+ {
+ mpfr_clear_flags ();
+ inex2 = mpfr_ui_div (z2, 1, x, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_ui_div, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_ui_div (z2, 1, x, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_ui_div, flags set");
+ }
+
+ /* If y = 2, we can test mpfr_sqr. */
+ if (yy == 2)
+ {
+ mpfr_clear_flags ();
+ inex2 = mpfr_sqr (z2, x, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_sqr, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_sqr (z2, x, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_sqr, flags set");
+ }
+ }
+
+ /* Test mpfr_pow_z. */
+ mpz_init (yyy);
+ mpfr_get_z (yyy, y, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex2 = mpfr_pow_z (z2, x, yyy, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_pow_z, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_pow_z (z2, x, yyy, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_pow_z, flags set");
+ mpz_clear (yyy);
+ }
+
+ /* If y = 0.5, we can test mpfr_sqrt, except if x is -0 or -Inf (because
+ the rule for mpfr_pow on these special values is different). */
+ if (MPFR_IS_PURE_FP (y) && mpfr_cmp_str1 (y, "0.5") == 0 &&
+ ! ((MPFR_IS_ZERO (x) || MPFR_IS_INF (x)) && MPFR_IS_NEG (x)))
+ {
+ mpfr_clear_flags ();
+ inex2 = mpfr_sqrt (z2, x, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_sqrt, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_sqrt (z2, x, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_sqrt, flags set");
+ }
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+ /* If y = -0.5, we can test mpfr_rec_sqrt, except if x = -Inf
+ (because the rule for mpfr_pow on -Inf is different). */
+ if (MPFR_IS_PURE_FP (y) && mpfr_cmp_str1 (y, "-0.5") == 0 &&
+ ! (MPFR_IS_INF (x) && MPFR_IS_NEG (x)))
+ {
+ mpfr_clear_flags ();
+ inex2 = mpfr_rec_sqrt (z2, x, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_rec_sqrt, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_rec_sqrt (z2, x, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_rec_sqrt, flags set");
+ }
+#endif
+
+ /* If x is an integer that fits in an unsigned long and is not -0,
+ we can test mpfr_ui_pow. */
+ if (MPFR_IS_POS (x) && mpfr_integer_p (x) &&
+ mpfr_fits_ulong_p (x, MPFR_RNDN))
+ {
+ unsigned long xx = mpfr_get_ui (x, MPFR_RNDN);
+
+ mpfr_clear_flags ();
+ inex2 = mpfr_ui_pow (z2, xx, y, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_ui_pow, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_ui_pow (z2, xx, y, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_ui_pow, flags set");
+
+ /* If x = 2, we can test mpfr_exp2. */
+ if (xx == 2)
+ {
+ mpfr_clear_flags ();
+ inex2 = mpfr_exp2 (z2, y, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_exp2, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_exp2 (z2, y, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_exp2, flags set");
+ }
+
+ /* If x = 10, we can test mpfr_exp10. */
+ if (xx == 10)
+ {
+ mpfr_clear_flags ();
+ inex2 = mpfr_exp10 (z2, y, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, flags,
+ s, "mpfr_exp10, flags cleared");
+ __gmpfr_flags = MPFR_FLAGS_ALL;
+ inex2 = mpfr_exp10 (z2, y, rnd);
+ cmpres (spx, sx, sy, rnd, z1, inex1, z2, inex2, MPFR_FLAGS_ALL,
+ s, "mpfr_exp10, flags set");
+ }
+ }
+
+ mpfr_clear (z2);
+}
+
+static int
+my_setstr (mpfr_ptr t, const char *s)
+{
+ if (strcmp (s, "min") == 0)
+ {
+ mpfr_setmin (t, mpfr_get_emin ());
+ MPFR_SET_POS (t);
+ return 0;
+ }
+ if (strcmp (s, "min+") == 0)
+ {
+ mpfr_setmin (t, mpfr_get_emin ());
+ MPFR_SET_POS (t);
+ mpfr_nextabove (t);
+ return 0;
+ }
+ if (strcmp (s, "max") == 0)
+ {
+ mpfr_setmax (t, mpfr_get_emax ());
+ MPFR_SET_POS (t);
+ return 0;
+ }
+ return mpfr_set_str (t, s, 10, MPFR_RNDN);
+}
+
+static void
+tst (void)
+{
+ int sv = sizeof (val) / sizeof (*val);
+ int i, j;
+ int rnd;
+ mpfr_t x, y, z, tmp;
+
+ mpfr_inits2 (53, x, y, z, tmp, (mpfr_ptr) 0);
+
+ for (i = 0; i < sv; i++)
+ for (j = 0; j < sv; j++)
+ RND_LOOP (rnd)
+ {
+ int exact, inex;
+ unsigned int flags;
+
+ if (my_setstr (x, val[i]) || my_setstr (y, val[j]))
+ {
+ printf ("internal error for (%d,%d,%d)\n", i, j, rnd);
+ exit (1);
+ }
+ mpfr_clear_flags ();
+ inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd);
+ flags = __gmpfr_flags;
+ if (! MPFR_IS_NAN (z) && mpfr_nanflag_p ())
+ err ("got NaN flag without NaN value", i, j, rnd, z, inex);
+ if (MPFR_IS_NAN (z) && ! mpfr_nanflag_p ())
+ err ("got NaN value without NaN flag", i, j, rnd, z, inex);
+ if (inex != 0 && ! mpfr_inexflag_p ())
+ err ("got non-zero ternary value without inexact flag",
+ i, j, rnd, z, inex);
+ if (inex == 0 && mpfr_inexflag_p ())
+ err ("got null ternary value with inexact flag",
+ i, j, rnd, z, inex);
+ if (i >= 3 && j >= 3)
+ {
+ if (mpfr_underflow_p ())
+ err ("got underflow", i, j, rnd, z, inex);
+ if (mpfr_overflow_p ())
+ err ("got overflow", i, j, rnd, z, inex);
+ exact = MPFR_IS_SINGULAR (z) ||
+ (mpfr_mul_2ui (tmp, z, 16, MPFR_RNDN), mpfr_integer_p (tmp));
+ if (exact && inex != 0)
+ err ("got exact value with ternary flag different from 0",
+ i, j, rnd, z, inex);
+ if (! exact && inex == 0)
+ err ("got inexact value with ternary flag equal to 0",
+ i, j, rnd, z, inex);
+ }
+ if (MPFR_IS_ZERO (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y))
+ {
+ if (MPFR_IS_NEG (y) && ! MPFR_IS_INF (z))
+ err ("expected an infinity", i, j, rnd, z, inex);
+ if (MPFR_IS_POS (y) && ! MPFR_IS_ZERO (z))
+ err ("expected a zero", i, j, rnd, z, inex);
+ if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z))
+ err ("wrong sign", i, j, rnd, z, inex);
+ }
+ if (! MPFR_IS_NAN (x) && mpfr_cmp_si (x, -1) == 0)
+ {
+ /* x = -1 */
+ if (! (MPFR_IS_INF (y) || mpfr_integer_p (y)) &&
+ ! MPFR_IS_NAN (z))
+ err ("expected NaN", i, j, rnd, z, inex);
+ if ((MPFR_IS_INF (y) || (mpfr_integer_p (y) && ! is_odd (y)))
+ && ! mpfr_equal_p (z, __gmpfr_one))
+ err ("expected 1", i, j, rnd, z, inex);
+ if (is_odd (y) &&
+ (MPFR_IS_NAN (z) || mpfr_cmp_si (z, -1) != 0))
+ err ("expected -1", i, j, rnd, z, inex);
+ }
+ if ((mpfr_equal_p (x, __gmpfr_one) || MPFR_IS_ZERO (y)) &&
+ ! mpfr_equal_p (z, __gmpfr_one))
+ err ("expected 1", i, j, rnd, z, inex);
+ if (MPFR_IS_PURE_FP (x) && MPFR_IS_NEG (x) &&
+ MPFR_IS_FP (y) && ! mpfr_integer_p (y) &&
+ ! MPFR_IS_NAN (z))
+ err ("expected NaN", i, j, rnd, z, inex);
+ if (MPFR_IS_INF (y) && MPFR_NOTZERO (x))
+ {
+ int cmpabs1 = mpfr_cmpabs (x, __gmpfr_one);
+
+ if ((MPFR_IS_NEG (y) ? (cmpabs1 < 0) : (cmpabs1 > 0)) &&
+ ! (MPFR_IS_POS (z) && MPFR_IS_INF (z)))
+ err ("expected +Inf", i, j, rnd, z, inex);
+ if ((MPFR_IS_NEG (y) ? (cmpabs1 > 0) : (cmpabs1 < 0)) &&
+ ! (MPFR_IS_POS (z) && MPFR_IS_ZERO (z)))
+ err ("expected +0", i, j, rnd, z, inex);
+ }
+ if (MPFR_IS_INF (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y))
+ {
+ if (MPFR_IS_POS (y) && ! MPFR_IS_INF (z))
+ err ("expected an infinity", i, j, rnd, z, inex);
+ if (MPFR_IS_NEG (y) && ! MPFR_IS_ZERO (z))
+ err ("expected a zero", i, j, rnd, z, inex);
+ if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z))
+ err ("wrong sign", i, j, rnd, z, inex);
+ }
+ test_others (val[i], val[j], (mpfr_rnd_t) rnd, x, y, z, inex, flags,
+ "tst");
+ }
+ mpfr_clears (x, y, z, tmp, (mpfr_ptr) 0);
+}
+
+static void
+underflow_up1 (void)
+{
+ mpfr_t delta, x, y, z, z0;
+ mpfr_exp_t n;
+ int inex;
+ int rnd;
+ int i;
+
+ n = mpfr_get_emin ();
+ if (n < LONG_MIN)
+ return;
+
+ mpfr_init2 (delta, 2);
+ inex = mpfr_set_ui_2exp (delta, 1, -2, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+
+ mpfr_init2 (x, 8);
+ inex = mpfr_set_ui (x, 2, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+
+ mpfr_init2 (y, sizeof (long) * CHAR_BIT + 4);
+ inex = mpfr_set_si (y, n, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+
+ mpfr_init2 (z0, 2);
+ mpfr_set_ui (z0, 0, MPFR_RNDN);
+
+ mpfr_init2 (z, 32);
+
+ for (i = 0; i <= 12; i++)
+ {
+ unsigned int flags = 0;
+ char sy[16];
+
+ /* Test 2^(emin - i/4).
+ * --> Underflow iff i > 4.
+ * --> Zero in MPFR_RNDN iff i >= 8.
+ */
+
+ if (i != 0 && i != 4)
+ flags |= MPFR_FLAGS_INEXACT;
+ if (i > 4)
+ flags |= MPFR_FLAGS_UNDERFLOW;
+
+ sprintf (sy, "emin - %d/4", i);
+
+ RND_LOOP (rnd)
+ {
+ int zero;
+
+ zero = (i > 4 && (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)) ||
+ (i >= 8 && rnd == MPFR_RNDN);
+
+ mpfr_clear_flags ();
+ inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd);
+ cmpres (1, "2", sy, (mpfr_rnd_t) rnd, zero ? z0 : (mpfr_ptr) NULL,
+ -1, z, inex, flags, "underflow_up1", "mpfr_pow");
+ test_others ("2", sy, (mpfr_rnd_t) rnd, x, y, z, inex, flags,
+ "underflow_up1");
+ }
+
+ inex = mpfr_sub (y, y, delta, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ }
+
+ mpfr_clears (delta, x, y, z, z0, (mpfr_ptr) 0);
+}
+
+/* With pow.c r5497, the following test fails on a 64-bit Linux machine
+ * due to a double-rounding problem when rescaling the result:
+ * Error with underflow_up2 and extended exponent range
+ * x = 7.fffffffffffffff0@-1,
+ * y = 4611686018427387904, MPFR_RNDN
+ * Expected 1.0000000000000000@-1152921504606846976, inex = 1, flags = 9
+ * Got 0, inex = -1, flags = 9
+ * With pow_ui.c r5423, the following test fails on a 64-bit Linux machine
+ * as underflows and overflows are not handled correctly (the approximation
+ * error is ignored):
+ * Error with mpfr_pow_ui, flags cleared
+ * x = 7.fffffffffffffff0@-1,
+ * y = 4611686018427387904, MPFR_RNDN
+ * Expected 1.0000000000000000@-1152921504606846976, inex = 1, flags = 9
+ * Got 0, inex = -1, flags = 9
+ */
+static void
+underflow_up2 (void)
+{
+ mpfr_t x, y, z, z0, eps;
+ mpfr_exp_t n;
+ int inex;
+ int rnd;
+
+ n = 1 - mpfr_get_emin ();
+ MPFR_ASSERTN (n > 1);
+ if (n > ULONG_MAX)
+ return;
+
+ mpfr_init2 (eps, 2);
+ mpfr_set_ui_2exp (eps, 1, -1, MPFR_RNDN); /* 1/2 */
+ mpfr_div_ui (eps, eps, n, MPFR_RNDZ); /* 1/(2n) rounded toward zero */
+
+ mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT + 1);
+ inex = mpfr_ui_sub (x, 1, eps, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0); /* since n < 2^(size_of_long_in_bits) */
+ inex = mpfr_div_2ui (x, x, 1, MPFR_RNDN); /* 1/2 - eps/2 exactly */
+ MPFR_ASSERTN (inex == 0);
+
+ mpfr_init2 (y, sizeof (unsigned long) * CHAR_BIT);
+ inex = mpfr_set_ui (y, n, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+
+ /* 0 < eps < 1 / (2n), thus (1 - eps)^n > 1/2,
+ and 1/2 (1/2)^n < (1/2 - eps/2)^n < (1/2)^n. */
+ mpfr_inits2 (64, z, z0, (mpfr_ptr) 0);
+ RND_LOOP (rnd)
+ {
+ unsigned int ufinex = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
+ int expected_inex;
+ char sy[256];
+
+ mpfr_set_ui (z0, 0, MPFR_RNDN);
+ expected_inex = rnd == MPFR_RNDN || rnd == MPFR_RNDU || rnd == MPFR_RNDA ?
+ (mpfr_nextabove (z0), 1) : -1;
+ sprintf (sy, "%lu", (unsigned long) n);
+
+ mpfr_clear_flags ();
+ inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd);
+ cmpres (0, x, sy, (mpfr_rnd_t) rnd, z0, expected_inex, z, inex, ufinex,
+ "underflow_up2", "mpfr_pow");
+ test_others (NULL, sy, (mpfr_rnd_t) rnd, x, y, z, inex, ufinex,
+ "underflow_up2");
+ }
+
+ mpfr_clears (x, y, z, z0, eps, (mpfr_ptr) 0);
+}
+
+static void
+underflow_up3 (void)
+{
+ mpfr_t x, y, z, z0;
+ int inex;
+ int rnd;
+ int i;
+
+ mpfr_init2 (x, 64);
+ mpfr_init2 (y, sizeof (mpfr_exp_t) * CHAR_BIT);
+ mpfr_init2 (z, 32);
+ mpfr_init2 (z0, 2);
+
+ inex = mpfr_set_exp_t (y, mpfr_get_emin () - 2, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ for (i = -1; i <= 1; i++)
+ RND_LOOP (rnd)
+ {
+ unsigned int ufinex = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
+ int expected_inex;
+
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ if (i < 0)
+ mpfr_nextbelow (x);
+ if (i > 0)
+ mpfr_nextabove (x);
+ /* x = 2 + i * eps, y = emin - 2, x^y ~= 2^(emin - 2) */
+
+ expected_inex = rnd == MPFR_RNDU || rnd == MPFR_RNDA
+ || (rnd == MPFR_RNDN && i < 0) ? 1 : -1;
+
+ mpfr_set_ui (z0, 0, MPFR_RNDN);
+ if (expected_inex > 0)
+ mpfr_nextabove (z0);
+
+ mpfr_clear_flags ();
+ inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd);
+ cmpres (0, x, "emin - 2", (mpfr_rnd_t) rnd, z0, expected_inex, z, inex,
+ ufinex, "underflow_up3", "mpfr_pow");
+ test_others (NULL, "emin - 2", (mpfr_rnd_t) rnd, x, y, z, inex, ufinex,
+ "underflow_up3");
+ }
+
+ mpfr_clears (x, y, z, z0, (mpfr_ptr) 0);
+}
+
+static void
+underflow_up (void)
+{
+ underflow_up1 ();
+ underflow_up2 ();
+ underflow_up3 ();
+}
+
+static void
+overflow_inv (void)
+{
+ mpfr_t x, y, z;
+ int precx;
+ int s, t;
+ int inex;
+ int rnd;
+
+ mpfr_init2 (y, 2);
+ mpfr_init2 (z, 8);
+
+ mpfr_set_si (y, -1, MPFR_RNDN);
+ for (precx = 10; precx <= 100; precx += 90)
+ {
+ const char *sp = precx == 10 ?
+ "overflow_inv (precx = 10)" : "overflow_inv (precx = 100)";
+
+ mpfr_init2 (x, precx);
+ for (s = -1; s <= 1; s += 2)
+ {
+ inex = mpfr_set_si_2exp (x, s, - mpfr_get_emax (), MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0);
+ for (t = 0; t <= 5; t++)
+ {
+ /* If precx = 10:
+ * x = s * 2^(-emax) * (1 + t * 2^(-9)), so that
+ * 1/x = s * 2^emax * (1 - t * 2^(-9) + eps) with eps > 0.
+ * Values of (1/x) / 2^emax and overflow condition for x > 0:
+ * t = 0: 1 o: always
+ * t = 1: 0.11111111 100000000011... o: MPFR_RNDN and MPFR_RNDU
+ * t = 2: 0.11111111 000000001111... o: MPFR_RNDU
+ * t = 3: 0.11111110 100000100011... o: never
+ *
+ * If precx = 100:
+ * t = 0: always overflow
+ * t > 0: overflow for MPFR_RNDN and MPFR_RNDU.
+ */
+ RND_LOOP (rnd)
+ {
+ int inf, overflow;
+ mpfr_rnd_t rnd2;
+
+ if (rnd == MPFR_RNDA)
+ rnd2 = s < 0 ? MPFR_RNDD : MPFR_RNDU;
+ else
+ rnd2 = (mpfr_rnd_t) rnd;
+
+ overflow = t == 0 ||
+ ((mpfr_rnd_t) rnd == MPFR_RNDN &&
+ (precx > 10 || t == 1)) ||
+ (rnd2 == (s < 0 ? MPFR_RNDD : MPFR_RNDU) &&
+ (precx > 10 || t <= 2));
+ inf = overflow &&
+ ((mpfr_rnd_t) rnd == MPFR_RNDN ||
+ rnd2 == (s < 0 ? MPFR_RNDD : MPFR_RNDU));
+ mpfr_clear_flags ();
+ inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd);
+ if (overflow ^ !! mpfr_overflow_p ())
+ {
+ printf ("Bad overflow flag in %s\nfor mpfr_pow%s\n"
+ "s = %d, t = %d, %s\n", sp,
+ ext ? ", extended exponent range" : "",
+ s, t, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ exit (1);
+ }
+ if (overflow && (inf ^ !! MPFR_IS_INF (z)))
+ {
+ printf ("Bad value in %s\nfor mpfr_pow%s\n"
+ "s = %d, t = %d, %s\nGot ", sp,
+ ext ? ", extended exponent range" : "",
+ s, t, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
+ printf (" instead of %s value.\n",
+ inf ? "infinite" : "finite");
+ exit (1);
+ }
+ test_others (NULL, "-1", (mpfr_rnd_t) rnd, x, y, z,
+ inex, __gmpfr_flags, sp);
+ } /* RND_LOOP */
+ mpfr_nexttoinf (x);
+ } /* for (t = ...) */
+ } /* for (s = ...) */
+ mpfr_clear (x);
+ } /* for (precx = ...) */
+
+ mpfr_clears (y, z, (mpfr_ptr) 0);
+}
+
+static void
+alltst (void)
+{
+ mpfr_exp_t emin, emax;
+
+ ext = 0;
+ tst ();
+ underflow_up ();
+ overflow_inv ();
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ set_emin (MPFR_EMIN_MIN);
+ set_emax (MPFR_EMAX_MAX);
+ if (mpfr_get_emin () != emin || mpfr_get_emax () != emax)
+ {
+ ext = 1;
+ tst ();
+ underflow_up ();
+ overflow_inv ();
+ set_emin (emin);
+ set_emax (emax);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+ all_cmpres_errors = argc > 1;
+ alltst ();
+ tests_end_mpfr ();
+ return all_cmpres_errors < 0;
+}
diff --git a/mpfr/tests/tpow_z.c b/mpfr/tests/tpow_z.c
new file mode 100644
index 0000000000..8afdd414c8
--- /dev/null
+++ b/mpfr/tests/tpow_z.c
@@ -0,0 +1,379 @@
+/* Test file for mpfr_pow_z -- power function x^z with z a MPZ
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include <float.h>
+#include <math.h>
+
+#include "mpfr-test.h"
+
+#define ERROR(str) do { printf("Error for "str"\n"); exit (1); } while (0)
+
+static void
+check_special (void)
+{
+ mpfr_t x, y;
+ mpz_t z;
+ int res;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpz_init (z);
+
+ /* x^0 = 1 except for NAN */
+ mpfr_set_ui (x, 23, MPFR_RNDN);
+ mpz_set_ui (z, 0);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (y, 1) != 0)
+ ERROR ("23^0");
+ mpfr_set_nan (x);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_nan_p (y) || mpfr_cmp_si (y, 1) != 0)
+ ERROR ("NAN^0");
+ mpfr_set_inf (x, 1);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (y, 1) != 0)
+ ERROR ("INF^0");
+
+ /* sINF^N = INF if s==1 or n even if N > 0*/
+ mpz_set_ui (z, 42);
+ mpfr_set_inf (x, 1);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0)
+ ERROR ("INF^42");
+ mpfr_set_inf (x, -1);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0)
+ ERROR ("-INF^42");
+ mpz_set_ui (z, 17);
+ mpfr_set_inf (x, 1);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) <= 0)
+ ERROR ("INF^17");
+ mpfr_set_inf (x, -1);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_inf_p (y) == 0 || mpfr_sgn (y) >= 0)
+ ERROR ("-INF^17");
+
+ mpz_set_si (z, -42);
+ mpfr_set_inf (x, 1);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0)
+ ERROR ("INF^-42");
+ mpfr_set_inf (x, -1);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0)
+ ERROR ("-INF^-42");
+ mpz_set_si (z, -17);
+ mpfr_set_inf (x, 1);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0)
+ ERROR ("INF^-17");
+ mpfr_set_inf (x, -1);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) >= 0)
+ ERROR ("-INF^-17");
+
+ /* s0^N = +0 if s==+ or n even if N > 0*/
+ mpz_set_ui (z, 42);
+ MPFR_SET_ZERO (x); MPFR_SET_POS (x);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0)
+ ERROR ("+0^42");
+ MPFR_SET_NEG (x);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0)
+ ERROR ("-0^42");
+ mpz_set_ui (z, 17);
+ MPFR_SET_POS (x);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) <= 0)
+ ERROR ("+0^17");
+ MPFR_SET_NEG (x);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_zero_p (y) == 0 || MPFR_SIGN (y) >= 0)
+ ERROR ("-0^17");
+
+ mpz_set_si (z, -42);
+ MPFR_SET_ZERO (x); MPFR_SET_POS (x);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) <= 0)
+ ERROR ("+0^-42");
+ MPFR_SET_NEG (x);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) <= 0)
+ ERROR ("-0^-42");
+ mpz_set_si (z, -17);
+ MPFR_SET_POS (x);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) <= 0)
+ ERROR ("+0^-17");
+ MPFR_SET_NEG (x);
+ res = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (res != 0 || mpfr_inf_p (y) == 0 || MPFR_SIGN (y) >= 0)
+ ERROR ("-0^-17");
+
+ mpz_clear (z);
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+static void
+check_integer (mpfr_prec_t begin, mpfr_prec_t end, unsigned long max)
+{
+ mpfr_t x, y1, y2;
+ mpz_t z;
+ unsigned long i, n;
+ mpfr_prec_t p;
+ int res1, res2;
+ mpfr_rnd_t rnd;
+
+ mpfr_inits2 (begin, x, y1, y2, (mpfr_ptr) 0);
+ mpz_init (z);
+ for (p = begin ; p < end ; p+=4)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_set_prec (y1, p);
+ mpfr_set_prec (y2, p);
+ for (i = 0 ; i < max ; i++)
+ {
+ mpz_urandomb (z, RANDS, GMP_NUMB_BITS);
+ if ((i & 1) != 0)
+ mpz_neg (z, z);
+ mpfr_urandomb (x, RANDS);
+ mpfr_mul_2ui (x, x, 1, MPFR_RNDN); /* 0 <= x < 2 */
+ rnd = RND_RAND ();
+ if (mpz_fits_slong_p (z))
+ {
+ n = mpz_get_si (z);
+ /* printf ("New test for x=%ld\nCheck Pow_si\n", n); */
+ res1 = mpfr_pow_si (y1, x, n, rnd);
+ /* printf ("Check pow_z\n"); */
+ res2 = mpfr_pow_z (y2, x, z, rnd);
+ if (mpfr_cmp (y1, y2) != 0)
+ {
+ printf ("Error for p = %lu, z = %lu, rnd = %s and x = ",
+ (unsigned long) p, n, mpfr_print_rnd_mode (rnd));
+ mpfr_dump (x);
+ printf ("Ypowsi = "); mpfr_dump (y1);
+ printf ("Ypowz = "); mpfr_dump (y2);
+ exit (1);
+ }
+ if (res1 != res2)
+ {
+ printf ("Wrong inexact flags for p = %lu, z = %lu, rnd = %s"
+ " and x = ", (unsigned long) p, n,
+ mpfr_print_rnd_mode (rnd));
+ mpfr_dump (x);
+ printf ("Ypowsi(inex = %2d) = ", res1); mpfr_dump (y1);
+ printf ("Ypowz (inex = %2d) = ", res2); mpfr_dump (y2);
+ exit (1);
+ }
+ }
+ } /* for i */
+ } /* for p */
+ mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
+ mpz_clear (z);
+}
+
+static void
+check_regression (void)
+{
+ mpfr_t x, y;
+ mpz_t z;
+ int res1, res2;
+
+ mpz_init_set_ui (z, 2026876995);
+ mpfr_init2 (x, 122);
+ mpfr_init2 (y, 122);
+
+ mpfr_set_str_binary (x, "0.10000010010000111101001110100101101010011110011100001111000001001101000110011001001001001011001011010110110110101000111011E1");
+ res1 = mpfr_pow_z (y, x, z, MPFR_RNDU);
+ res2 = mpfr_pow_ui (x, x, 2026876995UL, MPFR_RNDU);
+ if (mpfr_cmp (x, y) || res1 != res2)
+ {
+ printf ("Regression (1) tested failed (%d=?%d)\n",res1, res2);
+ printf ("pow_ui: "); mpfr_dump (x);
+ printf ("pow_z: "); mpfr_dump (y);
+
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpz_clear (z);
+}
+
+/* Bug found by Kevin P. Rauch */
+static void
+bug20071104 (void)
+{
+ mpfr_t x, y;
+ mpz_t z;
+ int inex;
+
+ mpz_init_set_si (z, -2);
+ mpfr_inits2 (20, x, y, (mpfr_ptr) 0);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_nextbelow (x); /* x = -2^(emin-1) */
+ mpfr_clear_flags ();
+ inex = mpfr_pow_z (y, x, z, MPFR_RNDN);
+ if (! mpfr_inf_p (y) || MPFR_SIGN (y) < 0)
+ {
+ printf ("Error in bug20071104: expected +Inf, got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ if (inex <= 0)
+ {
+ printf ("Error in bug20071104: bad ternary value (%d)\n", inex);
+ exit (1);
+ }
+ if (__gmpfr_flags != (MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT))
+ {
+ printf ("Error in bug20071104: bad flags (%u)\n", __gmpfr_flags);
+ exit (1);
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+ mpz_clear (z);
+}
+
+static void
+check_overflow (void)
+{
+ mpfr_t a;
+ mpz_t z;
+ unsigned long n;
+ int res;
+
+ mpfr_init2 (a, 53);
+
+ mpfr_set_str_binary (a, "1E10");
+ mpz_init_set_ui (z, ULONG_MAX);
+ res = mpfr_pow_z (a, a, z, MPFR_RNDN);
+ if (! MPFR_IS_INF (a) || MPFR_SIGN (a) < 0 || res <= 0)
+ {
+ printf ("Error for (1e10)^ULONG_MAX, expected +Inf,\ngot ");
+ mpfr_dump (a);
+ exit (1);
+ }
+
+ /* Bug in pow_z.c up to r5109: if x = y (same mpfr_t argument), the
+ input argument is negative and not a power of two, z is positive
+ and odd, an overflow or underflow occurs, and the temporary result
+ res is positive, then the result gets a wrong sign (positive
+ instead of negative). */
+ mpfr_set_str_binary (a, "-1.1E10");
+ n = (ULONG_MAX ^ (ULONG_MAX >> 1)) + 1;
+ mpz_set_ui (z, n);
+ res = mpfr_pow_z (a, a, z, MPFR_RNDN);
+ if (! MPFR_IS_INF (a) || MPFR_SIGN (a) > 0 || res >= 0)
+ {
+ printf ("Error for (-1e10)^%lu, expected -Inf,\ngot ", n);
+ mpfr_dump (a);
+ exit (1);
+ }
+
+ mpfr_clear (a);
+ mpz_clear (z);
+}
+
+/* bug reported by Carl Witty (32-bit architecture) */
+static void
+bug20080223 (void)
+{
+ mpfr_t a, exp, answer;
+
+ mpfr_init2 (a, 53);
+ mpfr_init2 (exp, 53);
+ mpfr_init2 (answer, 53);
+
+ mpfr_set_si (exp, -1073741824, MPFR_RNDN);
+
+ mpfr_set_str (a, "1.999999999", 10, MPFR_RNDN);
+ /* a = 562949953139837/2^48 */
+ mpfr_pow (answer, a, exp, MPFR_RNDN);
+ mpfr_set_str_binary (a, "0.110110101111011001110000111111100011101000111011101E-1073741823");
+ MPFR_ASSERTN(mpfr_cmp0 (answer, a) == 0);
+
+ mpfr_clear (a);
+ mpfr_clear (exp);
+ mpfr_clear (answer);
+}
+
+static void
+bug20080904 (void)
+{
+ mpz_t exp;
+ mpfr_t a, answer;
+ mpfr_exp_t emin_default;
+
+ mpz_init (exp);
+ mpfr_init2 (a, 70);
+ mpfr_init2 (answer, 70);
+
+ emin_default = mpfr_get_emin ();
+ mpfr_set_emin (MPFR_EMIN_MIN);
+
+ mpz_set_str (exp, "-4eb92f8c7b7bf81e", 16);
+ mpfr_set_str_binary (a, "1.110000101110100110100011111000011110111101000011111001111001010011100");
+
+ mpfr_pow_z (answer, a, exp, MPFR_RNDN);
+ /* The correct result is near 2^(-2^62), so it underflows when
+ MPFR_EMIN_MIN > -2^62 (i.e. with 32 and 64 bits machines). */
+ mpfr_set_str (a, "AA500C0D7A69275DBp-4632850503556296886", 16, MPFR_RNDN);
+ if (! mpfr_equal_p (answer, a))
+ {
+ printf ("Error in bug20080904:\n");
+ printf ("Expected ");
+ mpfr_out_str (stdout, 16, 0, a, MPFR_RNDN);
+ putchar ('\n');
+ printf ("Got ");
+ mpfr_out_str (stdout, 16, 0, answer, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+
+ mpfr_set_emin (emin_default);
+
+ mpz_clear (exp);
+ mpfr_clear (a);
+ mpfr_clear (answer);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+
+ check_special ();
+
+ check_integer (2, 163, 100);
+ check_regression ();
+ bug20071104 ();
+ bug20080223 ();
+ bug20080904 ();
+ check_overflow ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tprintf.c b/mpfr/tests/tprintf.c
new file mode 100644
index 0000000000..d63b3a4b5e
--- /dev/null
+++ b/mpfr/tests/tprintf.c
@@ -0,0 +1,505 @@
+/* tprintf.c -- test file for mpfr_printf and mpfr_vprintf
+
+Copyright 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#if HAVE_STDARG
+#include <stdarg.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#include "mpfr-intmax.h"
+#include "mpfr-test.h"
+#define STDOUT_FILENO 1
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+#define QUOTE(X) NAME(X)
+#define NAME(X) #X
+
+/* unlike other tests, we print out errors to stderr because stdout might be
+ redirected */
+#define check_length(num_test, var, value, var_spec) \
+ if ((var) != (value)) \
+ { \
+ fprintf (stderr, "Error in test #%d: mpfr_printf printed %" \
+ QUOTE(var_spec)" characters instead of %d\n", \
+ (num_test), (var), (value)); \
+ exit (1); \
+ }
+
+#define check_length_with_cmp(num_test, var, value, cmp, var_spec) \
+ if (cmp != 0) \
+ { \
+ mpfr_fprintf (stderr, "Error in test #%d, mpfr_printf printed %" \
+ QUOTE(var_spec)" characters instead of %d\n", \
+ (num_test), (var), (value)); \
+ exit (1); \
+ }
+
+/* limit for random precision in random() */
+const int prec_max_printf = 5000;
+/* boolean: is stdout redirected to a file ? */
+int stdout_redirect;
+
+static void
+check (const char *fmt, mpfr_t x)
+{
+ if (mpfr_printf (fmt, x) == -1)
+ {
+ fprintf (stderr, "Error in mpfr_printf(\"%s\", ...)\n", fmt);
+
+ exit (1);
+ }
+ putchar ('\n');
+}
+
+static void
+check_vprintf (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ if (mpfr_vprintf (fmt, ap) == -1)
+ {
+ fprintf (stderr, "Error in mpfr_vprintf(\"%s\", ...)\n", fmt);
+
+ va_end (ap);
+ exit (1);
+ }
+ putchar ('\n');
+ va_end (ap);
+}
+
+static void
+check_vprintf_failure (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ if (mpfr_vprintf (fmt, ap) != -1)
+ {
+ putchar ('\n');
+ fprintf (stderr, "Error in mpfr_vprintf(\"%s\", ...)\n", fmt);
+
+ va_end (ap);
+ exit (1);
+ }
+ putchar ('\n');
+ va_end (ap);
+}
+
+static void
+check_invalid_format (void)
+{
+ int i = 0;
+
+ /* format in disorder */
+ check_vprintf_failure ("blah %l2.1d blah", i);
+ check_vprintf_failure ("blah %2.1#d blah", i);
+
+ /* incomplete format */
+ check_vprintf_failure ("%", i);
+ check_vprintf_failure ("% (missing conversion specifier)", i);
+ check_vprintf_failure ("missing conversion specifier %h", i);
+ check_vprintf_failure ("this should fail %.l because of missing conversion specifier "
+ "(or doubling %%)", i);
+ check_vprintf_failure ("%L", i);
+ check_vprintf_failure ("%hh. ", i);
+ check_vprintf_failure ("blah %j.");
+ check_vprintf_failure ("%ll blah");
+ check_vprintf_failure ("blah%t blah");
+ check_vprintf_failure ("%z ");
+ check_vprintf_failure ("%F (missing conversion specifier)");
+ check_vprintf_failure ("%Q (missing conversion specifier)");
+ check_vprintf_failure ("%M (missing conversion specifier)");
+ check_vprintf_failure ("%N (missing conversion specifier)");
+ check_vprintf_failure ("%Z (missing conversion specifier)");
+ check_vprintf_failure ("%R (missing conversion specifier)");
+ check_vprintf_failure ("%R");
+ check_vprintf_failure ("%P (missing conversion specifier)");
+
+ /* conversion specifier with wrong length specifier */
+ check_vprintf_failure ("%ha", i);
+ check_vprintf_failure ("%hhe", i);
+ check_vprintf_failure ("%jf", i);
+ check_vprintf_failure ("%lg", i);
+ check_vprintf_failure ("%tA", i);
+ check_vprintf_failure ("%zE", i);
+ check_vprintf_failure ("%Ld", i);
+ check_vprintf_failure ("%Qf", i);
+ check_vprintf_failure ("%MG", i);
+ check_vprintf_failure ("%Na", i);
+ check_vprintf_failure ("%ZE", i);
+ check_vprintf_failure ("%PG", i);
+ check_vprintf_failure ("%Fu", i);
+ check_vprintf_failure ("%Rx", i);
+}
+
+static void
+check_long_string (void)
+{
+ /* this test is VERY expensive both in time (~1 min on core2 @ 2.40GHz) and
+ in memory (~2.5 GB) */
+ mpfr_t x;
+
+ mpfr_init2 (x, INT_MAX);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_nextabove (x);
+
+ check_vprintf_failure ("%Rb", x);
+ check_vprintf_failure ("%RA %RA %Ra %Ra", x, x, x, x);
+
+ mpfr_clear (x);
+}
+
+static void
+check_special (void)
+{
+ mpfr_t x;
+
+ mpfr_init (x);
+
+ mpfr_set_inf (x, 1);
+ check ("%Ra", x);
+ check ("%Rb", x);
+ check ("%Re", x);
+ check ("%Rf", x);
+ check ("%Rg", x);
+ check_vprintf ("%Ra", x);
+ check_vprintf ("%Rb", x);
+ check_vprintf ("%Re", x);
+ check_vprintf ("%Rf", x);
+ check_vprintf ("%Rg", x);
+
+ mpfr_set_inf (x, -1);
+ check ("%Ra", x);
+ check ("%Rb", x);
+ check ("%Re", x);
+ check ("%Rf", x);
+ check ("%Rg", x);
+ check_vprintf ("%Ra", x);
+ check_vprintf ("%Rb", x);
+ check_vprintf ("%Re", x);
+ check_vprintf ("%Rf", x);
+ check_vprintf ("%Rg", x);
+
+ mpfr_set_nan (x);
+ check ("%Ra", x);
+ check ("%Rb", x);
+ check ("%Re", x);
+ check ("%Rf", x);
+ check ("%Rg", x);
+ check_vprintf ("%Ra", x);
+ check_vprintf ("%Rb", x);
+ check_vprintf ("%Re", x);
+ check_vprintf ("%Rf", x);
+ check_vprintf ("%Rg", x);
+
+ mpfr_clear (x);
+}
+
+static void
+check_mixed (void)
+{
+ int ch = 'a';
+#ifndef NPRINTF_HH
+ signed char sch = -1;
+ unsigned char uch = 1;
+#endif
+ short sh = -1;
+ unsigned short ush = 1;
+ int i = -1;
+ int j = 1;
+ unsigned int ui = 1;
+ long lo = -1;
+ unsigned long ulo = 1;
+ float f = -1.25;
+ double d = -1.25;
+#if !defined(NPRINTF_T) || !defined(NPRINTF_L)
+ long double ld = -1.25;
+#endif
+
+#ifndef NPRINTF_T
+ ptrdiff_t p = 1, saved_p;
+#endif
+ size_t sz = 1;
+
+ mpz_t mpz;
+ mpq_t mpq;
+ mpf_t mpf;
+ mpfr_rnd_t rnd = MPFR_RNDN;
+
+ mpfr_t mpfr;
+ mpfr_prec_t prec;
+
+ mpz_init (mpz);
+ mpz_set_ui (mpz, ulo);
+ mpq_init (mpq);
+ mpq_set_si (mpq, lo, ulo);
+ mpf_init (mpf);
+ mpf_set_q (mpf, mpq);
+ mpfr_init (mpfr);
+ mpfr_set_f (mpfr, mpf, MPFR_RNDN);
+ prec = mpfr_get_prec (mpfr);
+
+ check_vprintf ("a. %Ra, b. %u, c. %lx%n", mpfr, ui, ulo, &j);
+ check_length (1, j, 22, d);
+ check_vprintf ("a. %c, b. %Rb, c. %u, d. %li%ln", i, mpfr, i, lo, &ulo);
+ check_length (2, ulo, 36, lu);
+ check_vprintf ("a. %hi, b. %*f, c. %Re%hn", ush, 3, f, mpfr, &ush);
+ check_length (3, ush, 29, hu);
+ check_vprintf ("a. %hi, b. %f, c. %#.2Rf%n", sh, d, mpfr, &i);
+ check_length (4, i, 29, d);
+ check_vprintf ("a. %R*A, b. %Fe, c. %i%zn", rnd, mpfr, mpf, sz, &sz);
+ check_length (5, (unsigned long) sz, 34, lu); /* no format specifier '%zu' in C89 */
+ check_vprintf ("a. %Pu, b. %c, c. %RUG, d. %Zi%Zn", prec, ch, mpfr, mpz, &mpz);
+ check_length_with_cmp (6, mpz, 24, mpz_cmp_ui (mpz, 24), Zi);
+ check_vprintf ("%% a. %#.0RNg, b. %Qx%Rn c. %p",
+ mpfr, mpq, &mpfr, (void *) &i);
+ check_length_with_cmp (7, mpfr, 15, mpfr_cmp_ui (mpfr, 15), Rg);
+
+#ifndef NPRINTF_T
+ saved_p = p;
+ check_vprintf ("%% a. %RNg, b. %Qx, c. %td%tn", mpfr, mpq, p, &p);
+ if (p != 20)
+ mpfr_fprintf (stderr, "Error in test 8, got '%% a. %RNg, b. %Qx, c. %td'\n", mpfr, mpq, saved_p);
+ check_length (8, (long) p, 20, ld); /* no format specifier '%td' in C89 */
+#endif
+
+#ifndef NPRINTF_L
+ check_vprintf ("a. %RA, b. %Lf, c. %QX%zn", mpfr, ld, mpq, &sz);
+ check_length (9, (unsigned long) sz, 30, lu); /* no format specifier '%zu' in C89 */
+#endif
+
+#ifndef NPRINTF_HH
+ check_vprintf ("a. %hhi, b. %Ra, c. %hhu%hhn", sch, mpfr, uch, &uch);
+ check_length (10, (unsigned int) uch, 22, u); /* no format specifier '%hhu' in C89 */
+#endif
+
+#if defined(HAVE_LONG_LONG) && !defined(NPRINTF_LL)
+ {
+ long long llo = -1;
+ unsigned long long ullo = 1;
+
+ check_vprintf ("a. %Re, b. %llx%Qn", mpfr, ullo, &mpq);
+ check_length_with_cmp (11, mpq, 16, mpq_cmp_ui (mpq, 16, 1), Qu);
+ check_vprintf ("a. %lli, b. %Rf%lln", llo, mpfr, &ullo);
+ check_length (12, ullo, 19, llu);
+ }
+#endif
+
+#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J)
+ {
+ intmax_t im = -1;
+ uintmax_t uim = 1;
+
+ check_vprintf ("a. %*RA, b. %ji%Fn", 10, mpfr, im, &mpf);
+ check_length_with_cmp (31, mpf, 20, mpf_cmp_ui (mpf, 20), Fg);
+ check_vprintf ("a. %.*Re, b. %jx%jn", 10, mpfr, uim, &im);
+ check_length (32, (long) im, 25, li); /* no format specifier "%ji" in C89 */
+ }
+#endif
+
+ mpfr_clear (mpfr);
+ mpf_clear (mpf);
+ mpq_clear (mpq);
+ mpz_clear (mpz);
+}
+
+static void
+check_random (int nb_tests)
+{
+ int i;
+ mpfr_t x;
+ mpfr_rnd_t rnd;
+ char flag[] =
+ {
+ '-',
+ '+',
+ ' ',
+ '#',
+ '0', /* no ambiguity: first zeros are flag zero*/
+ '\''
+ };
+ char specifier[] =
+ {
+ 'a',
+ 'b',
+ 'e',
+ 'f',
+ 'g'
+ };
+ mpfr_exp_t old_emin, old_emax;
+
+ old_emin = mpfr_get_emin ();
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init (x);
+
+ for (i = 0; i < nb_tests; ++i)
+ {
+ int ret;
+ int j, jmax;
+ int spec, prec;
+#define FMT_SIZE 13
+ char fmt[FMT_SIZE]; /* at most something like "%-+ #0'.*R*f" */
+ char *ptr = fmt;
+
+ tests_default_random (x, 256, MPFR_EMIN_MIN, MPFR_EMAX_MAX);
+ rnd = (mpfr_rnd_t) RND_RAND ();
+
+ spec = (int) (randlimb () % 5);
+ jmax = (spec == 3 || spec == 4) ? 6 : 5; /* ' flag only with %f or %g */
+ /* advantage small precision */
+ prec = (randlimb () % 2) ? 10 : prec_max_printf;
+ prec = (int) (randlimb () % prec);
+ if (spec == 3
+ && (mpfr_get_exp (x) > prec_max_printf
+ || mpfr_get_exp (x) < -prec_max_printf))
+ /* change style 'f' to style 'e' when number x is very large or very
+ small*/
+ --spec;
+
+ *ptr++ = '%';
+ for (j = 0; j < jmax; j++)
+ {
+ if (randlimb () % 3 == 0)
+ *ptr++ = flag[j];
+ }
+ *ptr++ = '.';
+ *ptr++ = '*';
+ *ptr++ = 'R';
+ *ptr++ = '*';
+ *ptr++ = specifier[spec];
+ *ptr = '\0';
+ MPFR_ASSERTD (ptr - fmt < FMT_SIZE);
+
+ mpfr_printf ("mpfr_printf(\"%s\", %d, %s, %Re)\n", fmt, prec,
+ mpfr_print_rnd_mode (rnd), x);
+ ret = mpfr_printf (fmt, prec, rnd, x);
+ if (ret == -1)
+ {
+ if (spec == 3
+ && (MPFR_GET_EXP (x) > INT_MAX || MPFR_GET_EXP (x) < -INT_MAX))
+ /* normal failure: x is too large to be output with full precision */
+ {
+ mpfr_printf ("too large !");
+ }
+ else
+ {
+ printf ("Error in mpfr_printf(\"%s\", %d, %s, ...)",
+ fmt, prec, mpfr_print_rnd_mode (rnd));
+
+ if (stdout_redirect)
+ {
+ if ((fflush (stdout) == EOF) || (fclose (stdout) == -1))
+ {
+ perror ("check_random");
+ exit (1);
+ }
+ }
+ exit (1);
+ }
+ }
+ putchar ('\n');
+ }
+
+ mpfr_set_emin (old_emin);
+ mpfr_set_emax (old_emax);
+
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int N;
+
+ tests_start_mpfr ();
+
+ /* with no argument: prints to /dev/null,
+ tprintf N: prints N tests to stdout */
+ if (argc == 1)
+ {
+ N = 1000;
+ stdout_redirect = 1;
+ if (freopen ("/dev/null", "w", stdout) == NULL)
+ {
+ /* We failed to open this device, try with a dummy file */
+ if (freopen ("mpfrtest.txt", "w", stdout) == NULL)
+ {
+ /* Output the error message to stderr since it is not
+ a message about a wrong result in MPFR. Anyway the
+ stdandard output may have changed. */
+ fprintf (stderr, "Can't open /dev/null or a temporary file\n");
+ exit (1);
+ }
+ }
+ }
+ else
+ {
+ stdout_redirect = 0;
+ N = atoi (argv[1]);
+ }
+
+ check_invalid_format ();
+ check_special ();
+ check_mixed ();
+
+ /* expensive tests */
+ if (getenv ("MPFR_CHECK_LARGEMEM") != NULL)
+ check_long_string();
+
+ check_random (N);
+
+ if (stdout_redirect)
+ {
+ if ((fflush (stdout) == EOF) || (fclose (stdout) == -1))
+ perror ("main");
+ }
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else /* MPFR_VERSION */
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif /* MPFR_VERSION */
+
+#else /* HAVE_STDARG */
+
+int
+main (void)
+{
+ /* We have nothing to test. */
+ return 77;
+}
+
+#endif /* HAVE_STDARG */
diff --git a/mpfr/tests/trandom.c b/mpfr/tests/trandom.c
new file mode 100644
index 0000000000..a4f075f0a2
--- /dev/null
+++ b/mpfr/tests/trandom.c
@@ -0,0 +1,184 @@
+/* Test file for mpfr_urandomb
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+
+static void
+test_urandomb (long nbtests, mpfr_prec_t prec, int verbose)
+{
+ mpfr_t x;
+ int *tab, size_tab, k, sh, xn;
+ double d, av = 0, var = 0, chi2 = 0, th;
+ mpfr_exp_t emin;
+
+ size_tab = (nbtests >= 1000 ? nbtests / 50 : 20);
+ tab = (int *) calloc (size_tab, sizeof(int));
+ if (tab == NULL)
+ {
+ fprintf (stderr, "trandom: can't allocate memory in test_urandomb\n");
+ exit (1);
+ }
+
+ mpfr_init2 (x, prec);
+ xn = 1 + (prec - 1) / mp_bits_per_limb;
+ sh = xn * mp_bits_per_limb - prec;
+
+ for (k = 0; k < nbtests; k++)
+ {
+ mpfr_urandomb (x, RANDS);
+ /* check that lower bits are zero */
+ if (MPFR_MANT(x)[0] & MPFR_LIMB_MASK(sh))
+ {
+ printf ("Error: mpfr_urandomb() returns invalid numbers:\n");
+ mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+ d = mpfr_get_d1 (x); av += d; var += d*d;
+ tab[(int)(size_tab * d)]++;
+ }
+
+ /* coverage test */
+ emin = mpfr_get_emin ();
+ set_emin (1); /* the generated number in [0,1[ is not in the exponent
+ range, except if it is zero */
+ k = mpfr_urandomb (x, RANDS);
+ if (MPFR_IS_ZERO(x) == 0 && (k == 0 || mpfr_nan_p (x) == 0))
+ {
+ printf ("Error in mpfr_urandomb, expected NaN, got ");
+ mpfr_dump (x);
+ exit (1);
+ }
+ set_emin (emin);
+
+ mpfr_clear (x);
+ if (!verbose)
+ {
+ free(tab);
+ return;
+ }
+
+ av /= nbtests;
+ var = (var / nbtests) - av * av;
+
+ th = (double)nbtests / size_tab;
+ printf("Average = %.5f\nVariance = %.5f\n", av, var);
+ printf("Repartition for urandomb. Each integer should be close to %d.\n",
+ (int)th);
+
+ for (k = 0; k < size_tab; k++)
+ {
+ chi2 += (tab[k] - th) * (tab[k] - th) / th;
+ printf("%d ", tab[k]);
+ if (((k+1) & 7) == 0)
+ printf("\n");
+ }
+
+ printf("\nChi2 statistics value (with %d degrees of freedom) : %.5f\n\n",
+ size_tab - 1, chi2);
+
+ free(tab);
+ return;
+}
+
+/* Problem reported by Carl Witty: check mpfr_urandomb give similar results
+ on 32-bit and 64-bit machines.
+ We assume the default GMP random generator does not depend on the machine
+ word size, not on the GMP version.
+*/
+static void
+bug20100914 (void)
+{
+ mpfr_t x;
+ gmp_randstate_t s;
+
+#if __MPFR_GMP(4,2,0)
+# define C1 "0.895943"
+# define C2 "0.848824"
+#else
+# define C1 "0.479652"
+# define C2 "0.648529"
+#endif
+
+ gmp_randinit_default (s);
+ gmp_randseed_ui (s, 42);
+ mpfr_init2 (x, 17);
+ mpfr_urandomb (x, s);
+ if (mpfr_cmp_str1 (x, C1) != 0)
+ {
+ printf ("Error in bug20100914, expected " C1 ", got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_urandomb (x, s);
+ if (mpfr_cmp_str1 (x, C2) != 0)
+ {
+ printf ("Error in bug20100914, expected " C2 ", got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clear (x);
+ gmp_randclear (s);
+}
+
+int
+main (int argc, char *argv[])
+{
+ long nbtests;
+ mpfr_prec_t prec;
+ int verbose = 0;
+
+ tests_start_mpfr ();
+
+ if (argc > 1)
+ verbose = 1;
+
+ nbtests = 10000;
+ if (argc > 1)
+ {
+ long a = atol(argv[1]);
+ if (a != 0)
+ nbtests = a;
+ }
+
+ if (argc <= 2)
+ prec = 1000;
+ else
+ prec = atol(argv[2]);
+
+ test_urandomb (nbtests, prec, verbose);
+
+ if (argc == 1) /* check also small precision */
+ {
+ test_urandomb (nbtests, 2, 0);
+ }
+
+ bug20100914 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/trec_sqrt.c b/mpfr/tests/trec_sqrt.c
new file mode 100644
index 0000000000..9d069c7ab6
--- /dev/null
+++ b/mpfr/tests/trec_sqrt.c
@@ -0,0 +1,210 @@
+/* Test file for mpfr_rec_sqrt.
+
+Copyright 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+#define TEST_FUNCTION mpfr_rec_sqrt
+#define TEST_RANDOM_POS 8 /* 8/512 = 1/64 of the tested numbers are negative */
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int inex;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* rec_sqrt(NaN) = NaN */
+ mpfr_set_nan (x);
+ inex = mpfr_rec_sqrt (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (x) && inex == 0);
+
+ /* rec_sqrt(+Inf) = +0 */
+ mpfr_set_inf (x, 1);
+ inex = mpfr_rec_sqrt (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_zero_p (x) && MPFR_IS_POS(x) && inex == 0);
+
+ /* rec_sqrt(-Inf) = NaN */
+ mpfr_set_inf (x, -1);
+ inex = mpfr_rec_sqrt (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (x) && inex == 0);
+
+ /* rec_sqrt(+0) = +Inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inex = mpfr_rec_sqrt (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x) && inex == 0);
+
+ /* rec_sqrt(-0) = +Inf */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ inex = mpfr_rec_sqrt (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x) && inex == 0);
+
+ /* rec_sqrt(-1) = NaN */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ inex = mpfr_rec_sqrt (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (x) && inex == 0);
+
+ /* rec_sqrt(1) = 1 */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ inex = mpfr_rec_sqrt (x, x, MPFR_RNDN);
+ MPFR_ASSERTN((mpfr_cmp_ui (x, 1) == 0) && (inex == 0));
+
+ mpfr_set_prec (x, 23);
+ mpfr_set_prec (y, 33);
+ mpfr_set_str_binary (x, "1.0001110110101001010100e-1");
+ inex = mpfr_rec_sqrt (y, x, MPFR_RNDU);
+ mpfr_set_prec (x, 33);
+ mpfr_set_str_binary (x, "1.01010110101110100100100101011");
+ MPFR_ASSERTN (inex > 0 && mpfr_cmp (x, y) == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+/* Worst case incorrectly rounded in r5573, found with the bad_cases test */
+static void
+bad_case1 (void)
+{
+ mpfr_t x, y, z;
+
+ mpfr_init2 (x, 72);
+ mpfr_inits2 (6, y, z, (mpfr_ptr) 0);
+ mpfr_set_str (x, "1.08310518720928b30e@-120", 16, MPFR_RNDN);
+ mpfr_set_str (z, "f.8@59", 16, MPFR_RNDN);
+ /* z = rec_sqrt(x) rounded on 6 bits toward 0, the exact value
+ being ~= f.bffffffffffffffffa11@59. */
+ mpfr_rec_sqrt (y, x, MPFR_RNDZ);
+ if (mpfr_cmp0 (y, z) != 0)
+ {
+ printf ("Error in bad_case1\nexpected ");
+ mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+static int
+pm2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
+{
+ return mpfr_pow_si (y, x, -2, rnd_mode);
+}
+
+/* exercises corner cases with inputs around 1 or 2 */
+static void
+bad_case2 (void)
+{
+ mpfr_t r, u;
+ mpfr_prec_t pr, pu;
+ int rnd;
+
+ for (pr = MPFR_PREC_MIN; pr <= 192; pr++)
+ for (pu = MPFR_PREC_MIN; pu <= 192; pu++)
+ {
+ mpfr_init2 (r, pr);
+ mpfr_init2 (u, pu);
+
+ mpfr_set_ui (u, 1, MPFR_RNDN);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_nextbelow (u);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_nextbelow (u);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_set_ui (u, 1, MPFR_RNDN);
+ mpfr_nextabove (u);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_nextabove (u);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_set_ui (u, 2, MPFR_RNDN);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_nextbelow (u);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_nextbelow (u);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_set_ui (u, 2, MPFR_RNDN);
+ mpfr_nextabove (u);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_nextabove (u);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd);
+
+ mpfr_clear (r);
+ mpfr_clear (u);
+ }
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+
+ special ();
+ bad_case1 ();
+ bad_case2 ();
+ test_generic (2, 300, 15);
+
+ data_check ("data/rec_sqrt", mpfr_rec_sqrt, "mpfr_rec_sqrt");
+ bad_cases (mpfr_rec_sqrt, pm2, "mpfr_rec_sqrt", 8, -256, 255, 4, 128,
+ 800, 50);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else /* MPFR_VERSION */
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif /* MPFR_VERSION */
diff --git a/mpfr/tests/tremquo.c b/mpfr/tests/tremquo.c
new file mode 100644
index 0000000000..a496239400
--- /dev/null
+++ b/mpfr/tests/tremquo.c
@@ -0,0 +1,291 @@
+/* tremquo -- test file for mpfr_remquo and mpfr_remainder
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+bug20090227 (void)
+{
+ mpfr_t x, y, r1, r2;
+
+ mpfr_init2 (x, 118);
+ mpfr_init2 (y, 181);
+ mpfr_init2 (r1, 140);
+ mpfr_init2 (r2, 140);
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_set_str_binary (y, "1.100100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111000001000100010100110011111010");
+ mpfr_remainder (r1, x, y, MPFR_RNDU);
+ /* since the quotient is -1, r1 is the rounding of x+y */
+ mpfr_add (r2, x, y, MPFR_RNDU);
+ if (mpfr_cmp (r1, r2))
+ {
+ printf ("Error in mpfr_remainder (bug20090227)\n");
+ printf ("Expected ");
+ mpfr_dump (r2);
+ printf ("Got ");
+ mpfr_dump (r1);
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (r1);
+ mpfr_clear (r2);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y, r;
+ long q[1];
+
+ if (argc == 3) /* usage: tremquo x y (rnd=MPFR_RNDN implicit) */
+ {
+ mpfr_init2 (x, GMP_NUMB_BITS);
+ mpfr_init2 (y, GMP_NUMB_BITS);
+ mpfr_init2 (r, GMP_NUMB_BITS);
+ mpfr_set_str (x, argv[1], 10, MPFR_RNDN);
+ mpfr_set_str (y, argv[2], 10, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ printf ("r=");
+ mpfr_out_str (stdout, 10, 0, r, MPFR_RNDN);
+ printf (" q=%ld\n", q[0]);
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (r);
+ return 0;
+ }
+
+ tests_start_mpfr ();
+
+ bug20090227 ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (r);
+
+ /* special values */
+ mpfr_set_nan (x);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (r));
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_nan (y);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (r));
+
+ mpfr_set_inf (x, 1); /* +Inf */
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (r));
+
+ mpfr_set_inf (x, 1); /* +Inf */
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (r));
+
+ mpfr_set_inf (x, 1); /* +Inf */
+ mpfr_set_inf (y, 1);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (r));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_inf (y, 1);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_POS (r));
+ MPFR_ASSERTN (q[0] == (long) 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN); /* -0 */
+ mpfr_set_inf (y, 1);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_NEG (r));
+ MPFR_ASSERTN (q[0] == (long) 0);
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_set_inf (y, 1);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp (r, x) == 0);
+ MPFR_ASSERTN (q[0] == (long) 0);
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (r));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_ui (y, 17, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_POS (r));
+ MPFR_ASSERTN (q[0] == (long) 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_set_ui (y, 17, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_NEG (r));
+ MPFR_ASSERTN (q[0] == (long) 0);
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ /* check four possible sign combinations */
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ mpfr_set_ui (y, 17, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (r, 8) == 0);
+ MPFR_ASSERTN (q[0] == (long) 2);
+ mpfr_set_si (x, -42, MPFR_RNDN);
+ mpfr_set_ui (y, 17, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_si (r, -8) == 0);
+ MPFR_ASSERTN (q[0] == (long) -2);
+ mpfr_set_si (x, -42, MPFR_RNDN);
+ mpfr_set_si (y, -17, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_si (r, -8) == 0);
+ MPFR_ASSERTN (q[0] == (long) 2);
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ mpfr_set_si (y, -17, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (r, 8) == 0);
+ MPFR_ASSERTN (q[0] == (long) -2);
+
+ mpfr_set_prec (x, 100);
+ mpfr_set_prec (y, 50);
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ mpfr_nextabove (x); /* 42 + 2^(-94) */
+ mpfr_set_ui (y, 21, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -94) == 0);
+ MPFR_ASSERTN (q[0] == (long) 2);
+
+ mpfr_set_prec (x, 50);
+ mpfr_set_prec (y, 100);
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ mpfr_nextabove (x); /* 42 + 2^(-44) */
+ mpfr_set_ui (y, 21, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -44) == 0);
+ MPFR_ASSERTN (q[0] == (long) 2);
+
+ mpfr_set_prec (x, 100);
+ mpfr_set_prec (y, 50);
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ mpfr_set_ui (y, 21, MPFR_RNDN);
+ mpfr_nextabove (y); /* 21 + 2^(-45) */
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ /* r should be 42 - 2*(21 + 2^(-45)) = -2^(-44) */
+ MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -44) == 0);
+ MPFR_ASSERTN (q[0] == (long) 2);
+
+ mpfr_set_prec (x, 50);
+ mpfr_set_prec (y, 100);
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ mpfr_set_ui (y, 21, MPFR_RNDN);
+ mpfr_nextabove (y); /* 21 + 2^(-95) */
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ /* r should be 42 - 2*(21 + 2^(-95)) = -2^(-94) */
+ MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -94) == 0);
+ MPFR_ASSERTN (q[0] == (long) 2);
+
+ /* exercise large quotient */
+ mpfr_set_ui_2exp (x, 1, 65, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ /* quotient is 2^65 */
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_si (r, 0) == 0);
+ MPFR_ASSERTN (q[0] % 1073741824L == 0L);
+
+ /* another large quotient */
+ mpfr_set_prec (x, 65);
+ mpfr_set_prec (y, 65);
+ mpfr_const_pi (x, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, 63, MPFR_RNDN);
+ mpfr_const_log2 (y, MPFR_RNDN);
+ mpfr_set_prec (r, 10);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ /* q should be 41803643793084085130, r should be 605/2048 */
+ MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 605, -11) == 0);
+ MPFR_ASSERTN ((q[0] > 0) && ((q[0] % 1073741824L) == 733836170L));
+
+ /* check cases where quotient is 1.5 +/- eps */
+ mpfr_set_prec (x, 65);
+ mpfr_set_prec (y, 65);
+ mpfr_set_prec (r, 63);
+ mpfr_set_ui (x, 3, MPFR_RNDN);
+ mpfr_set_ui (y, 2, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ /* x/y = 1.5, quotient should be 2 (even rule), remainder should be -1 */
+ MPFR_ASSERTN (mpfr_cmp_si (r, -1) == 0);
+ MPFR_ASSERTN (q[0] == 2L);
+ mpfr_set_ui (x, 3, MPFR_RNDN);
+ mpfr_nextabove (x); /* 3 + 2^(-63) */
+ mpfr_set_ui (y, 2, MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ /* x/y = 1.5 + 2^(-64), quo should be 2, r should be -1 + 2^(-63) */
+ MPFR_ASSERTN (mpfr_add_ui (r, r, 1, MPFR_RNDN) == 0);
+ MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -63) == 0);
+ MPFR_ASSERTN (q[0] == 2L);
+ mpfr_set_ui (x, 3, MPFR_RNDN);
+ mpfr_set_ui (y, 2, MPFR_RNDN);
+ mpfr_nextabove (y); /* 2 + 2^(-63) */
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ /* x/y = 1.5 - eps, quo should be 1, r should be 1 - 2^(-63) */
+ MPFR_ASSERTN (mpfr_sub_ui (r, r, 1, MPFR_RNDN) == 0);
+ MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -63) == 0);
+ MPFR_ASSERTN (q[0] == 1L);
+
+ /* bug founds by Kaveh Ghazi, 3 May 2007 */
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_set_ui (y, 3, MPFR_RNDN);
+ mpfr_remainder (r, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_si (r, -1) == 0);
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_remainder (r, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_si (r, 0) == 0 && MPFR_SIGN (r) < 0);
+
+ /* check argument reuse */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_remainder (x, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_si (x, 0) == 0 && MPFR_SIGN (x) < 0);
+
+ mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
+ mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN);
+ mpfr_remquo (r, q, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_zero_p (r) && MPFR_SIGN (r) > 0);
+ MPFR_ASSERTN (q[0] == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (r);
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/trint.c b/mpfr/tests/trint.c
new file mode 100644
index 0000000000..5382d21d01
--- /dev/null
+++ b/mpfr/tests/trint.c
@@ -0,0 +1,448 @@
+/* Test file for mpfr_rint, mpfr_trunc, mpfr_floor, mpfr_ceil, mpfr_round.
+
+Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#if __MPFR_STDC (199901L)
+# include <math.h>
+#endif
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ mpfr_exp_t emax;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_nan (x);
+ mpfr_rint (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_inf (x, 1);
+ mpfr_rint (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
+
+ mpfr_set_inf (x, -1);
+ mpfr_rint (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) < 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_rint (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_rint (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG(y));
+
+ /* coverage test */
+ mpfr_set_prec (x, 2);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_mul_2exp (x, x, mp_bits_per_limb, MPFR_RNDN);
+ mpfr_rint (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
+
+ /* another coverage test */
+ emax = mpfr_get_emax ();
+ set_emax (1);
+ mpfr_set_prec (x, 3);
+ mpfr_set_str_binary (x, "1.11E0");
+ mpfr_set_prec (y, 2);
+ mpfr_rint (y, x, MPFR_RNDU); /* x rounds to 1.0E1=0.1E2 which overflows */
+ MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
+ set_emax (emax);
+
+ /* yet another */
+ mpfr_set_prec (x, 97);
+ mpfr_set_prec (y, 96);
+ mpfr_set_str_binary (x, "-0.1011111001101111000111011100011100000110110110110000000111010001000101001111101010101011010111100E97");
+ mpfr_rint (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "0.10101100000000101001010101111111000000011111010000010E-1");
+ mpfr_rint (y, x, MPFR_RNDU);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
+ mpfr_rint (y, x, MPFR_RNDD);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y));
+
+ mpfr_set_prec (x, 36);
+ mpfr_set_prec (y, 2);
+ mpfr_set_str_binary (x, "-11000110101010111111110111001.0000100");
+ mpfr_rint (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-11E27");
+ MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
+
+ mpfr_set_prec (x, 39);
+ mpfr_set_prec (y, 29);
+ mpfr_set_str_binary (x, "-0.100010110100011010001111001001001100111E39");
+ mpfr_rint (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-0.10001011010001101000111100101E39");
+ MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
+
+ mpfr_set_prec (x, 46);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (x, "-0.1011100110100101000001011111101011001001101001E32");
+ mpfr_rint (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-0.10111001101001010000010111111011E32");
+ MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
+
+ /* coverage test for mpfr_round */
+ mpfr_set_prec (x, 3);
+ mpfr_set_str_binary (x, "1.01E1"); /* 2.5 */
+ mpfr_set_prec (y, 2);
+ mpfr_round (y, x);
+ /* since mpfr_round breaks ties away, should give 3 and not 2 as with
+ the "round to even" rule */
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0);
+ /* same test for the function */
+ (mpfr_round) (y, x);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0);
+
+ mpfr_set_prec (x, 6);
+ mpfr_set_prec (y, 3);
+ mpfr_set_str_binary (x, "110.111");
+ mpfr_round (y, x);
+ if (mpfr_cmp_ui (y, 7))
+ {
+ printf ("Error in round(110.111)\n");
+ exit (1);
+ }
+
+ /* Bug found by Mark J Watkins */
+ mpfr_set_prec (x, 84);
+ mpfr_set_str_binary (x,
+ "0.110011010010001000000111101101001111111100101110010000000000000" \
+ "000000000000000000000E32");
+ mpfr_round (x, x);
+ if (mpfr_cmp_str (x, "0.1100110100100010000001111011010100000000000000" \
+ "00000000000000000000000000000000000000E32", 2, MPFR_RNDN))
+ {
+ printf ("Rounding error when dest=src\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#if __MPFR_STDC (199901L)
+
+static void
+test_fct (double (*f)(double), int (*g)(), char *s, mpfr_rnd_t r)
+{
+ double d, y;
+ mpfr_t dd, yy;
+
+ mpfr_init2 (dd, 53);
+ mpfr_init2 (yy, 53);
+ for (d = -5.0; d <= 5.0; d += 0.25)
+ {
+ mpfr_set_d (dd, d, r);
+ y = (*f)(d);
+ if (g == &mpfr_rint)
+ mpfr_rint (yy, dd, r);
+ else
+ (*g)(yy, dd);
+ mpfr_set_d (dd, y, r);
+ if (mpfr_cmp (yy, dd))
+ {
+ printf ("test_against_libc: incorrect result for %s, rnd = %s,"
+ " d = %g\ngot ", s, mpfr_print_rnd_mode (r), d);
+ mpfr_out_str (stdout, 10, 0, yy, MPFR_RNDN);
+ printf (" instead of %g\n", y);
+ exit (1);
+ }
+ }
+ mpfr_clear (dd);
+ mpfr_clear (yy);
+}
+
+#define TEST_FCT(F) test_fct (&F, &mpfr_##F, #F, r)
+
+static void
+test_against_libc (void)
+{
+ mpfr_rnd_t r = MPFR_RNDN;
+
+#if HAVE_ROUND
+ TEST_FCT (round);
+#endif
+#if HAVE_TRUNC
+ TEST_FCT (trunc);
+#endif
+#if HAVE_FLOOR
+ TEST_FCT (floor);
+#endif
+#if HAVE_CEIL
+ TEST_FCT (ceil);
+#endif
+#if HAVE_NEARBYINT
+ for (r = 0; r < MPFR_RND_MAX ; r++)
+ if (mpfr_set_machine_rnd_mode (r) == 0)
+ test_fct (&nearbyint, &mpfr_rint, "rint", r);
+#endif
+}
+
+#endif
+
+static void
+err (const char *str, mp_size_t s, mpfr_t x, mpfr_t y, mpfr_prec_t p,
+ mpfr_rnd_t r, int trint, int inexact)
+{
+ printf ("Error: %s\ns = %u, p = %u, r = %s, trint = %d, inexact = %d\nx = ",
+ str, (unsigned int) s, (unsigned int) p, mpfr_print_rnd_mode (r),
+ trint, inexact);
+ mpfr_print_binary (x);
+ printf ("\ny = ");
+ mpfr_print_binary (y);
+ printf ("\n");
+ exit (1);
+}
+
+static void
+coverage_03032011 (void)
+{
+ mpfr_t in, out, cmp;
+ int status;
+ int precIn;
+ char strData[(GMP_NUMB_BITS * 4)+256];
+
+ precIn = GMP_NUMB_BITS * 4;
+
+ mpfr_init2 (in, precIn);
+ mpfr_init2 (out, GMP_NUMB_BITS);
+ mpfr_init2 (cmp, GMP_NUMB_BITS);
+
+ /* cmp = "0.1EprecIn+2" */
+ /* The buffer size is sufficient, as precIn is small in practice. */
+ sprintf (strData, "0.1E%d", precIn+2);
+ mpfr_set_str_binary (cmp, strData);
+
+ /* in = "0.10...01EprecIn+2" use all (precIn) significand bits */
+ memset ((void *)strData, '0', precIn+2);
+ strData[1] = '.';
+ strData[2] = '1';
+ sprintf (&strData[precIn+1], "1E%d", precIn+2);
+ mpfr_set_str_binary (in, strData);
+
+ status = mpfr_rint (out, in, MPFR_RNDN);
+ if ((mpfr_cmp (out, cmp) != 0) || (status >= 0))
+ {
+ printf("mpfr_rint error :\n status is %d instead of 0\n", status);
+ printf(" out value is ");
+ mpfr_dump(out);
+ printf(" instead of ");
+ mpfr_dump(cmp);
+ exit (1);
+ }
+
+ mpfr_clear (cmp);
+ mpfr_clear (out);
+
+ mpfr_init2 (out, GMP_NUMB_BITS);
+ mpfr_init2 (cmp, GMP_NUMB_BITS);
+
+ /* cmp = "0.10...01EprecIn+2" use all (GMP_NUMB_BITS) significand bits */
+ strcpy (&strData[GMP_NUMB_BITS+1], &strData[precIn+1]);
+ mpfr_set_str_binary (cmp, strData);
+
+ (MPFR_MANT(in))[2] = MPFR_LIMB_HIGHBIT;
+ status = mpfr_rint (out, in, MPFR_RNDN);
+
+ if ((mpfr_cmp (out, cmp) != 0) || (status <= 0))
+ {
+ printf("mpfr_rint error :\n status is %d instead of 0\n", status);
+ printf(" out value is\n");
+ mpfr_dump(out);
+ printf(" instead of\n");
+ mpfr_dump(cmp);
+ exit (1);
+ }
+
+ mpfr_clear (cmp);
+ mpfr_clear (out);
+ mpfr_clear (in);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mp_size_t s;
+ mpz_t z;
+ mpfr_prec_t p;
+ mpfr_t x, y, t, u, v;
+ int r;
+ int inexact, sign_t;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpz_init (z);
+ mpfr_init (t);
+ mpfr_init (u);
+ mpfr_init (v);
+ mpz_set_ui (z, 1);
+ for (s = 2; s < 100; s++)
+ {
+ /* z has exactly s bits */
+
+ mpz_mul_2exp (z, z, 1);
+ if (randlimb () % 2)
+ mpz_add_ui (z, z, 1);
+ mpfr_set_prec (x, s);
+ mpfr_set_prec (t, s);
+ mpfr_set_prec (u, s);
+ if (mpfr_set_z (x, z, MPFR_RNDN))
+ {
+ printf ("Error: mpfr_set_z should be exact (s = %u)\n",
+ (unsigned int) s);
+ exit (1);
+ }
+ if (randlimb () % 2)
+ mpfr_neg (x, x, MPFR_RNDN);
+ if (randlimb () % 2)
+ mpfr_div_2ui (x, x, randlimb () % s, MPFR_RNDN);
+ for (p = 2; p < 100; p++)
+ {
+ int trint;
+ mpfr_set_prec (y, p);
+ mpfr_set_prec (v, p);
+ for (r = 0; r < MPFR_RND_MAX ; r++)
+ for (trint = 0; trint < 3; trint++)
+ {
+ if (trint == 2)
+ inexact = mpfr_rint (y, x, (mpfr_rnd_t) r);
+ else if (r == MPFR_RNDN)
+ inexact = mpfr_round (y, x);
+ else if (r == MPFR_RNDZ)
+ inexact = (trint ? mpfr_trunc (y, x) :
+ mpfr_rint_trunc (y, x, MPFR_RNDZ));
+ else if (r == MPFR_RNDU)
+ inexact = (trint ? mpfr_ceil (y, x) :
+ mpfr_rint_ceil (y, x, MPFR_RNDU));
+ else /* r = MPFR_RNDD */
+ inexact = (trint ? mpfr_floor (y, x) :
+ mpfr_rint_floor (y, x, MPFR_RNDD));
+ if (mpfr_sub (t, y, x, MPFR_RNDN))
+ err ("subtraction 1 should be exact",
+ s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ sign_t = mpfr_cmp_ui (t, 0);
+ if (trint != 0 &&
+ (((inexact == 0) && (sign_t != 0)) ||
+ ((inexact < 0) && (sign_t >= 0)) ||
+ ((inexact > 0) && (sign_t <= 0))))
+ err ("wrong inexact flag", s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ if (inexact == 0)
+ continue; /* end of the test for exact results */
+
+ if (((r == MPFR_RNDD || (r == MPFR_RNDZ && MPFR_SIGN (x) > 0))
+ && inexact > 0) ||
+ ((r == MPFR_RNDU || (r == MPFR_RNDZ && MPFR_SIGN (x) < 0))
+ && inexact < 0))
+ err ("wrong rounding direction",
+ s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ if (inexact < 0)
+ {
+ mpfr_add_ui (v, y, 1, MPFR_RNDU);
+ if (mpfr_cmp (v, x) <= 0)
+ err ("representable integer between x and its "
+ "rounded value", s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ }
+ else
+ {
+ mpfr_sub_ui (v, y, 1, MPFR_RNDD);
+ if (mpfr_cmp (v, x) >= 0)
+ err ("representable integer between x and its "
+ "rounded value", s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ }
+ if (r == MPFR_RNDN)
+ {
+ int cmp;
+ if (mpfr_sub (u, v, x, MPFR_RNDN))
+ err ("subtraction 2 should be exact",
+ s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ cmp = mpfr_cmp_abs (t, u);
+ if (cmp > 0)
+ err ("faithful rounding, but not the nearest integer",
+ s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ if (cmp < 0)
+ continue;
+ /* |t| = |u|: x is the middle of two consecutive
+ representable integers. */
+ if (trint == 2)
+ {
+ /* halfway case for mpfr_rint in MPFR_RNDN rounding
+ mode: round to an even integer or significand. */
+ mpfr_div_2ui (y, y, 1, MPFR_RNDZ);
+ if (!mpfr_integer_p (y))
+ err ("halfway case for mpfr_rint, result isn't an"
+ " even integer", s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ /* If floor(x) and ceil(x) aren't both representable
+ integers, the significand must be even. */
+ mpfr_sub (v, v, y, MPFR_RNDN);
+ mpfr_abs (v, v, MPFR_RNDN);
+ if (mpfr_cmp_ui (v, 1) != 0)
+ {
+ mpfr_div_2si (y, y, MPFR_EXP (y) - MPFR_PREC (y)
+ + 1, MPFR_RNDN);
+ if (!mpfr_integer_p (y))
+ err ("halfway case for mpfr_rint, significand isn't"
+ " even", s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ }
+ }
+ else
+ { /* halfway case for mpfr_round: x must have been
+ rounded away from zero. */
+ if ((MPFR_SIGN (x) > 0 && inexact < 0) ||
+ (MPFR_SIGN (x) < 0 && inexact > 0))
+ err ("halfway case for mpfr_round, bad rounding"
+ " direction", s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
+ }
+ }
+ }
+ }
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpz_clear (z);
+ mpfr_clear (t);
+ mpfr_clear (u);
+ mpfr_clear (v);
+
+ special ();
+ coverage_03032011 ();
+
+#if __MPFR_STDC (199901L)
+ if (argc > 1 && strcmp (argv[1], "-s") == 0)
+ test_against_libc ();
+#endif
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/troot.c b/mpfr/tests/troot.c
new file mode 100644
index 0000000000..f2117b4d36
--- /dev/null
+++ b/mpfr/tests/troot.c
@@ -0,0 +1,334 @@
+/* Test file for mpfr_root.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+special (void)
+{
+ mpfr_t x, y;
+ int i;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* root(NaN) = NaN */
+ mpfr_set_nan (x);
+ mpfr_root (y, x, 17, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: root(NaN,17) <> NaN\n");
+ exit (1);
+ }
+
+ /* root(+Inf) = +Inf */
+ mpfr_set_inf (x, 1);
+ mpfr_root (y, x, 42, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: root(+Inf,42) <> +Inf\n");
+ exit (1);
+ }
+
+ /* root(-Inf, 17) = -Inf */
+ mpfr_set_inf (x, -1);
+ mpfr_root (y, x, 17, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error: root(-Inf,17) <> -Inf\n");
+ exit (1);
+ }
+ /* root(-Inf, 42) = NaN */
+ mpfr_set_inf (x, -1);
+ mpfr_root (y, x, 42, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error: root(-Inf,42) <> -Inf\n");
+ exit (1);
+ }
+
+ /* root(+/-0) = +/-0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_root (y, x, 17, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+ {
+ printf ("Error: root(+0,17) <> +0\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_root (y, x, 42, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) > 0)
+ {
+ printf ("Error: root(-0,42) <> -0\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_str (x, "8.39005285514734966412e-01", 10, MPFR_RNDN);
+ mpfr_root (x, x, 3, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, "9.43166207799662426048e-01"))
+ {
+ printf ("Error in root3 (1)\n");
+ printf ("expected 9.43166207799662426048e-01\n");
+ printf ("got ");
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (x, "0.10000100001100101001001001011001");
+ mpfr_root (x, x, 3, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.11001101011000100111000111111001");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in root3 (2)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (x, "-0.1100001110110000010101011001011");
+ mpfr_root (x, x, 3, MPFR_RNDD);
+ mpfr_set_str_binary (y, "-0.11101010000100100101000101011001");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in root3 (3)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 82);
+ mpfr_set_prec (y, 27);
+ mpfr_set_str_binary (x, "0.1010001111011101011011000111001011001101100011110110010011011011011010011001100101e-7");
+ mpfr_root (y, x, 3, MPFR_RNDD);
+ mpfr_set_str_binary (x, "0.101011110001110001000100011E-2");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in root3 (4)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 204);
+ mpfr_set_prec (y, 38);
+ mpfr_set_str_binary (x, "0.101000000001101000000001100111111011111001110110100001111000100110100111001101100111110001110001011011010110010011100101111001111100001010010100111011101100000011011000101100010000000011000101001010001001E-5");
+ mpfr_root (y, x, 3, MPFR_RNDD);
+ mpfr_set_str_binary (x, "0.10001001111010011011101000010110110010E-1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in root3 (5)\n");
+ exit (1);
+ }
+
+ /* Worst case found on 2006-11-25 */
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "1.0100001101101101001100110001001000000101001101100011E28");
+ mpfr_root (y, x, 35, MPFR_RNDN);
+ mpfr_set_str_binary (x, "1.1100000010110101100011101011000010100001101100100011E0");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_root (y, x, 35, MPFR_RNDN) for\n"
+ "x = 1.0100001101101101001100110001001000000101001101100011E28\n"
+ "Expected ");
+ mpfr_dump (x);
+ printf ("Got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ /* Worst cases found on 2006-11-26 */
+ mpfr_set_str_binary (x, "1.1111010011101110001111010110000101110000110110101100E17");
+ mpfr_root (y, x, 36, MPFR_RNDD);
+ mpfr_set_str_binary (x, "1.0110100111010001101001010111001110010100111111000010E0");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_root (y, x, 36, MPFR_RNDD) for\n"
+ "x = 1.1111010011101110001111010110000101110000110110101100E17\n"
+ "Expected ");
+ mpfr_dump (x);
+ printf ("Got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "1.1100011101101101100010110001000001110001111110010000E23");
+ mpfr_root (y, x, 36, MPFR_RNDU);
+ mpfr_set_str_binary (x, "1.1001010100001110000110111111100011011101110011000100E0");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_root (y, x, 36, MPFR_RNDU) for\n"
+ "x = 1.1100011101101101100010110001000001110001111110010000E23\n"
+ "Expected ");
+ mpfr_dump (x);
+ printf ("Got ");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ /* Check for k = 1 */
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ i = mpfr_root (y, x, 1, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 17) || i != 0)
+ {
+ printf ("Error in root (17^(1/1))\n");
+ exit (1);
+ }
+
+#if 0
+ /* Check for k == 0:
+ For 0 <= x < 1 => +0.
+ For x = 1 => 1.
+ For x > 1, => +Inf.
+ For x < 0 => NaN. */
+ i = mpfr_root (y, x, 0, MPFR_RNDN);
+ if (!MPFR_IS_INF (y) || !MPFR_IS_POS (y) || i != 0)
+ {
+ printf ("Error in root 17^(1/0)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ i = mpfr_root (y, x, 0, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1) || i != 0)
+ {
+ printf ("Error in root 1^(1/0)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ i = mpfr_root (y, x, 0, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y) || i != 0)
+ {
+ printf ("Error in root 0+^(1/0)\n");
+ exit (1);
+ }
+ MPFR_CHANGE_SIGN (x);
+ i = mpfr_root (y, x, 0, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y) || i != 0)
+ {
+ printf ("Error in root 0-^(1/0)\n");
+ exit (1);
+ }
+ mpfr_set_ui_2exp (x, 17, -5, MPFR_RNDD);
+ i = mpfr_root (y, x, 0, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y) || i != 0)
+ {
+ printf ("Error in root (17/2^5)^(1/0)\n");
+ exit (1);
+ }
+#endif
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ i = mpfr_root (y, x, 0, MPFR_RNDN);
+ if (!MPFR_IS_NAN (y) || i != 0)
+ {
+ printf ("Error in root 0+^(1/0)\n");
+ exit (1);
+ }
+ /* Check for k==2 */
+ mpfr_set_si (x, -17, MPFR_RNDD);
+ i = mpfr_root (y, x, 2, MPFR_RNDN);
+ if (!MPFR_IS_NAN (y) || i != 0)
+ {
+ printf ("Error in root (-17)^(1/2)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_root
+#define INTEGER_TYPE unsigned long
+#define INT_RAND_FUNCTION() (INTEGER_TYPE) (randlimb () % 3 +2)
+#include "tgeneric_ui.c"
+
+int
+main (void)
+{
+ mpfr_t x;
+ int r;
+ mpfr_prec_t p;
+ unsigned long k;
+
+ tests_start_mpfr ();
+
+ special ();
+
+ mpfr_init (x);
+
+ for (p = 2; p < 100; p++)
+ {
+ mpfr_set_prec (x, p);
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ k = 2 + randlimb () % 4; /* 2 <= k <= 5 */
+ mpfr_root (x, x, k, (mpfr_rnd_t) r);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error in mpfr_root(%lu) for x=1, rnd=%s\ngot ",
+ k, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ if (k % 2)
+ {
+ mpfr_root (x, x, k, (mpfr_rnd_t) r);
+ if (mpfr_cmp_si (x, -1))
+ {
+ printf ("Error in mpfr_root(%lu) for x=-1, rnd=%s\ngot ",
+ k, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ }
+
+ if (p >= 5)
+ {
+ int i;
+ for (i = -12; i <= 12; i++)
+ {
+ mpfr_set_ui (x, 27, MPFR_RNDN);
+ mpfr_mul_2si (x, x, 3*i, MPFR_RNDN);
+ mpfr_root (x, x, 3, MPFR_RNDN);
+ if (mpfr_cmp_si_2exp (x, 3, i))
+ {
+ printf ("Error in mpfr_root(3) for "
+ "x = 27.0 * 2^(%d), rnd=%s\ngot ",
+ 3*i, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\ninstead of 3 * 2^(%d)\n", i);
+ exit (1);
+ }
+ }
+ }
+ }
+ }
+ mpfr_clear (x);
+
+ test_generic_ui (2, 200, 30);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tround_prec.c b/mpfr/tests/tround_prec.c
new file mode 100644
index 0000000000..39f6ca1377
--- /dev/null
+++ b/mpfr/tests/tround_prec.c
@@ -0,0 +1,124 @@
+/* Test file for mpfr_prec_round.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ mpfr_t x;
+ mpfr_exp_t emax;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+
+ mpfr_set_nan (x);
+ mpfr_prec_round (x, 2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (x));
+
+ mpfr_set_inf (x, 1);
+ mpfr_prec_round (x, 2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+
+ mpfr_set_inf (x, -1);
+ mpfr_prec_round (x, 2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_prec_round (x, 2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_prec_round (x, 2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_NEG(x));
+
+ emax = mpfr_get_emax ();
+ set_emax (0);
+ mpfr_set_prec (x, 3);
+ mpfr_set_str_binary (x, "0.111");
+ mpfr_prec_round (x, 2, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ set_emax (emax);
+
+ mpfr_set_prec (x, mp_bits_per_limb + 2);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_nextbelow (x);
+ mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_ui (x, 5, MPFR_RNDN);
+ mpfr_prec_round (x, 2, MPFR_RNDN);
+ if (mpfr_cmp_ui(x, 4))
+ {
+ printf ("Error in tround: got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf (" instead of 4\n");
+ exit (1);
+ }
+
+ /* check case when reallocation is needed */
+ mpfr_set_prec (x, 3);
+ mpfr_set_ui (x, 5, MPFR_RNDN); /* exact */
+ mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN);
+ if (mpfr_cmp_ui(x, 5))
+ {
+ printf ("Error in tround: got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf (" instead of 5\n");
+ exit (1);
+ }
+
+ mpfr_clear(x);
+ mpfr_init2 (x, 3);
+ mpfr_set_si (x, -5, MPFR_RNDN); /* exact */
+ mpfr_prec_round (x, mp_bits_per_limb + 1, MPFR_RNDN);
+ if (mpfr_cmp_si(x, -5))
+ {
+ printf ("Error in tround: got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf (" instead of -5\n");
+ exit (1);
+ }
+
+ /* check case when new precision needs less limbs */
+ mpfr_set_prec (x, mp_bits_per_limb + 1);
+ mpfr_set_ui (x, 5, MPFR_RNDN); /* exact */
+ mpfr_prec_round (x, 3, MPFR_RNDN); /* exact */
+ if (mpfr_cmp_ui(x, 5))
+ {
+ printf ("Error in tround: got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf (" instead of 5\n");
+ exit (1);
+ }
+
+ mpfr_clear(x);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsec.c b/mpfr/tests/tsec.c
new file mode 100644
index 0000000000..4c2c7e94dd
--- /dev/null
+++ b/mpfr/tests/tsec.c
@@ -0,0 +1,172 @@
+/* Test file for mpfr_sec.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_sec
+#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
+#include "tgeneric.c"
+
+static void
+check_specials (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ mpfr_sec (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: sec(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_sec (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: sec(Inf) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_sec (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: sec(-Inf) != NaN\n");
+ exit (1);
+ }
+
+ /* sec(+/-0) = 1 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_sec (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error: sec(+0) != 1\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_sec (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error: sec(-0) != 1\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+overflowed_sec0 (void)
+{
+ mpfr_t x, y;
+ int emax, i, inex, rnd, err = 0;
+ mpfr_exp_t old_emax;
+
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ for (emax = -1; emax <= 0; emax++)
+ {
+ mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
+ mpfr_nextbelow (y);
+ set_emax (emax); /* 1 is not representable. */
+ for (i = -1; i <= 1; i++)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_sec (x, x, (mpfr_rnd_t) rnd);
+ if (! mpfr_overflow_p ())
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " The overflow flag is not set.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ {
+ if (inex >= 0)
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (x, y))
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of 0.11111111E%d.\n", emax);
+ err = 1;
+ }
+ }
+ else
+ {
+ if (inex <= 0)
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
+ {
+ printf ("Error in overflowed_sec0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of +Inf.\n");
+ err = 1;
+ }
+ }
+ }
+ set_emax (old_emax);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_specials ();
+
+ test_generic (2, 200, 10);
+ overflowed_sec0 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsech.c b/mpfr/tests/tsech.c
new file mode 100644
index 0000000000..98c02358ef
--- /dev/null
+++ b/mpfr/tests/tsech.c
@@ -0,0 +1,190 @@
+/* Test file for mpfr_sech.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_sech
+#define TEST_RANDOM_EMIN -64
+#define TEST_RANDOM_EMAX 36
+#include "tgeneric.c"
+
+static void
+check_specials (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ mpfr_sech (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: sech(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_sech (y, x, MPFR_RNDN);
+ if (! (MPFR_IS_ZERO (y) && MPFR_SIGN (y) > 0))
+ {
+ printf ("Error: sech(+Inf) != +0\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_sech (y, x, MPFR_RNDN);
+ if (! (MPFR_IS_ZERO (y) && MPFR_SIGN (y) > 0))
+ {
+ printf ("Error: sech(-Inf) != +0\n");
+ exit (1);
+ }
+
+ /* sec(+/-0) = 1 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_sech (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error: sech(+0) != 1\n");
+ exit (1);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_sech (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error: sech(-0) != 1\n");
+ exit (1);
+ }
+
+ /* check huge x */
+ mpfr_set_str (x, "8e8", 10, MPFR_RNDN);
+ mpfr_sech (y, x, MPFR_RNDN);
+ if (! (mpfr_zero_p (y) && MPFR_SIGN (y) > 0))
+ {
+ printf ("Error: sech(8e8) != +0\n");
+ exit (1);
+ }
+ mpfr_set_str (x, "-8e8", 10, MPFR_RNDN);
+ mpfr_sech (y, x, MPFR_RNDN);
+ if (! (mpfr_zero_p (y) && MPFR_SIGN (y) > 0))
+ {
+ printf ("Error: sech(-8e8) != +0\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+overflowed_sech0 (void)
+{
+ mpfr_t x, y;
+ int emax, i, inex, rnd, err = 0;
+ mpfr_exp_t old_emax;
+
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+
+ for (emax = -1; emax <= 0; emax++)
+ {
+ mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
+ mpfr_nextbelow (y);
+ set_emax (emax); /* 1 is not representable. */
+ /* and if emax < 0, 1 - eps is not representable either. */
+ for (i = -1; i <= 1; i++)
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_sech (x, x, (mpfr_rnd_t) rnd);
+ if ((i == 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
+ ! mpfr_overflow_p ())
+ {
+ printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n"
+ " The overflow flag is not set.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ {
+ if (inex >= 0)
+ {
+ printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n"
+ " The inexact value must be negative.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (x, y))
+ {
+ printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of 0.11111111E%d.\n", emax);
+ err = 1;
+ }
+ }
+ else
+ {
+ if (inex <= 0)
+ {
+ printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n"
+ " The inexact value must be positive.\n",
+ i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
+ {
+ printf ("Error in overflowed_sech0 (i = %d, rnd = %s):\n"
+ " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of +Inf.\n");
+ err = 1;
+ }
+ }
+ }
+ set_emax (old_emax);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_specials ();
+ test_generic (2, 200, 10);
+ overflowed_sech0 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tset.c b/mpfr/tests/tset.c
new file mode 100644
index 0000000000..79d038523f
--- /dev/null
+++ b/mpfr/tests/tset.c
@@ -0,0 +1,209 @@
+/* Test file for mpfr_set.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int error;
+
+#define PRINT_ERROR_IF(condition, text) \
+ do { \
+ if (condition) \
+ { \
+ printf ("%s", text); \
+ error = 1; \
+ } \
+ } while (0)
+
+
+/* Maybe better create its own test file ? */
+static void
+check_neg_special (void)
+{
+ mpfr_t x;
+ mpfr_init (x);
+ MPFR_SET_NAN (x);
+ mpfr_clear_nanflag ();
+ mpfr_neg (x, x, MPFR_RNDN);
+ PRINT_ERROR_IF (!mpfr_nanflag_p (),
+ "ERROR: neg (NaN) doesn't set Nan flag.\n");
+ mpfr_clear (x);
+}
+
+static void
+check_special (void)
+{
+ mpfr_t x, y;
+ int inexact;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_inf (x, 1);
+ PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) < 0,
+ "ERROR: mpfr_set_inf failed to set variable to +infinity.\n");
+ inexact = mpfr_set (y, x, MPFR_RNDN);
+ PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || inexact != 0,
+ "ERROR: mpfr_set failed to set variable to +infinity.\n");
+
+ inexact = mpfr_set_ui (y, 0, MPFR_RNDN);
+ PRINT_ERROR_IF (!mpfr_zero_p (y) || mpfr_sgn (y) < 0 || inexact != 0,
+ "ERROR: mpfr_set_ui failed to set variable to +0.\n");
+
+ mpfr_set_inf (x, -1);
+ PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) > 0,
+ "ERROR: mpfr_set_inf failed to set variable to -infinity.\n");
+ inexact = mpfr_set (y, x, MPFR_RNDN);
+ PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) > 0 || inexact != 0,
+ "ERROR: mpfr_set failed to set variable to -infinity.\n");
+
+ mpfr_set_zero (x, 1);
+ PRINT_ERROR_IF (!mpfr_zero_p (x) || mpfr_sgn (x) < 0,
+ "ERROR: mpfr_set_zero failed to set variable to +0.\n");
+ inexact = mpfr_set (y, x, MPFR_RNDN);
+ PRINT_ERROR_IF (!mpfr_zero_p (y) || mpfr_sgn (y) < 0 || inexact != 0,
+ "ERROR: mpfr_set failed to set variable to +0.\n");
+
+ mpfr_set_zero (x, -1);
+ PRINT_ERROR_IF (!mpfr_zero_p (x) || mpfr_sgn (x) > 0,
+ "ERROR: mpfr_set_zero failed to set variable to -0.\n");
+ inexact = mpfr_set (y, x, MPFR_RNDN);
+ PRINT_ERROR_IF (!mpfr_zero_p (y) || mpfr_sgn (y) > 0 || inexact != 0,
+ "ERROR: mpfr_set failed to set variable to -0.\n");
+
+ mpfr_set_nan (x);
+ PRINT_ERROR_IF (!mpfr_nan_p (x),
+ "ERROR: mpfr_set_nan failed to set variable to NaN.\n");
+ inexact = mpfr_set (y, x, MPFR_RNDN);
+ PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0,
+ "ERROR: mpfr_set failed to set variable to NaN.\n");
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+check_ternary_value (void)
+{
+ int p, q, rnd;
+ int inexact, cmp;
+ mpfr_t x, y;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ for (p=2; p<500; p++)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_urandomb (x, RANDS);
+ if (randlimb () % 2)
+ mpfr_neg (x, x, MPFR_RNDN);
+ for (q=2; q<2*p; q++)
+ {
+ mpfr_set_prec (y, q);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ inexact = mpfr_set (y, x, (mpfr_rnd_t) rnd);
+ cmp = mpfr_cmp (y, x);
+ if (((inexact == 0) && (cmp != 0)) ||
+ ((inexact > 0) && (cmp <= 0)) ||
+ ((inexact < 0) && (cmp >= 0)))
+ {
+ printf ("Wrong ternary value in mpfr_set: expected %d,"
+ " got %d\n", cmp, inexact);
+ exit (1);
+ }
+ }
+ }
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_set
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_t x, y, z, u;
+ int inexact;
+ mpfr_exp_t emax;
+
+ tests_start_mpfr ();
+
+ /* Default : no error */
+ error = 0;
+
+ /* check prototypes of mpfr_init_set_* */
+ inexact = mpfr_init_set_si (x, -1, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ inexact = mpfr_init_set (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ inexact = mpfr_init_set_ui (z, 1, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ inexact = mpfr_init_set_d (u, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+
+ emax = mpfr_get_emax ();
+ set_emax (0);
+ mpfr_set_prec (x, 3);
+ mpfr_set_str_binary (x, "0.111");
+ mpfr_set_prec (y, 2);
+ mpfr_set (y, x, MPFR_RNDU);
+ if (!(MPFR_IS_INF (y) && MPFR_SIGN (y) > 0))
+ {
+ printf ("Error for y=x=0.111 with px=3, py=2 and emax=0\nx=");
+ mpfr_dump (x);
+ printf ("y=");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ set_emax (emax);
+
+ mpfr_set_prec (y, 11);
+ mpfr_set_str_binary (y, "0.11111111100E-8");
+ mpfr_set_prec (x, 2);
+ mpfr_set (x, y, MPFR_RNDN);
+ mpfr_set_str_binary (y, "1.0E-8");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for y=0.11111111100E-8, prec=2, rnd=MPFR_RNDN\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (u);
+
+ check_ternary_value ();
+ check_special ();
+ check_neg_special ();
+
+ test_generic (2, 1000, 10);
+
+ tests_end_mpfr ();
+ return error;
+}
diff --git a/mpfr/tests/tset_d.c b/mpfr/tests/tset_d.c
new file mode 100644
index 0000000000..74ec69771c
--- /dev/null
+++ b/mpfr/tests/tset_d.c
@@ -0,0 +1,225 @@
+/* Test file for mpfr_set_d and mpfr_get_d.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y, z;
+ unsigned long k, n;
+ volatile double d;
+ double dd;
+
+ tests_start_mpfr ();
+ mpfr_test_init ();
+
+#ifndef MPFR_DOUBLE_SPEC
+ printf ("Warning! The MPFR_DOUBLE_SPEC macro is not defined. This means\n"
+ "that you do not have a conforming C implementation and problems\n"
+ "may occur with conversions between MPFR numbers and standard\n"
+ "floating-point types. Please contact the MPFR team.\n");
+#elif MPFR_DOUBLE_SPEC == 0
+ /*
+ printf ("The type 'double' of your C implementation does not seem to\n"
+ "correspond to the IEEE-754 double precision. Though code has\n"
+ "been written to support such implementations, tests have been\n"
+ "done only on IEEE-754 double-precision implementations and\n"
+ "conversions between MPFR numbers and standard floating-point\n"
+ "types may be inaccurate. You may wish to contact the MPFR team\n"
+ "for further testing.\n");
+ */
+ printf ("The type 'double' of your C implementation does not seem to\n"
+ "correspond to the IEEE-754 double precision. Such particular\n"
+ "implementations are not supported yet, and conversions between\n"
+ "MPFR numbers and standard floating-point types may be very\n"
+ "inaccurate.\n");
+ printf ("FLT_RADIX = %ld\n", (long) FLT_RADIX);
+ printf ("DBL_MANT_DIG = %ld\n", (long) DBL_MANT_DIG);
+ printf ("DBL_MIN_EXP = %ld\n", (long) DBL_MIN_EXP);
+ printf ("DBL_MAX_EXP = %ld\n", (long) DBL_MAX_EXP);
+#endif
+
+ mpfr_init (x);
+
+#if !defined(MPFR_ERRDIVZERO)
+ mpfr_set_nan (x);
+ d = mpfr_get_d (x, MPFR_RNDN);
+ if (! DOUBLE_ISNAN (d))
+ {
+ printf ("ERROR for NAN (1)\n");
+#ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "
+ "file.\n");
+#endif
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_d (x, d, MPFR_RNDN);
+ if (! mpfr_nan_p (x))
+ {
+ printf ("ERROR for NAN (2)\n");
+#ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "
+ "file.\n");
+#endif
+ exit (1);
+ }
+#endif /* MPFR_ERRDIVZERO */
+
+ d = 0.0;
+ mpfr_set_d (x, d, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
+ d = -d;
+ mpfr_set_d (x, d, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0) != 0 || MPFR_IS_POS(x))
+ {
+ printf ("Error in mpfr_set_d on -0\n");
+ exit (1);
+ }
+
+#if !defined(MPFR_ERRDIVZERO)
+ mpfr_set_inf (x, 1);
+ d = mpfr_get_d (x, MPFR_RNDN);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_d (x, d, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+
+ mpfr_set_inf (x, -1);
+ d = mpfr_get_d (x, MPFR_RNDN);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_set_d (x, d, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);
+#endif /* MPFR_ERRDIVZERO */
+
+ mpfr_set_prec (x, 2);
+
+ /* checks that denormalized are not flushed to zero */
+ d = DBL_MIN; /* 2^(-1022) */
+ for (n=0; n<52; n++, d /= 2.0)
+ if (d != 0.0) /* should be 2^(-1022-n) */
+ {
+ mpfr_set_d (x, d, MPFR_RNDN);
+ if (mpfr_cmp_ui_2exp (x, 1, -1022-n))
+ {
+ printf ("Wrong result for d=2^(%ld), ", -1022-n);
+ printf ("got ");
+ mpfr_out_str (stdout, 10, 10, x, MPFR_RNDN);
+ printf ("\n");
+ mpfr_print_binary (x);
+ puts ("");
+ exit (1);
+ }
+ }
+
+ /* checks that rounds to nearest sets the last
+ bit to zero in case of equal distance */
+ mpfr_set_d (x, 5.0, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 4))
+ {
+ printf ("Error in tset_d: expected 4.0, got ");
+ mpfr_print_binary (x); putchar('\n');
+ exit (1);
+ }
+ mpfr_set_d (x, -5.0, MPFR_RNDN);
+ if (mpfr_cmp_si (x, -4))
+ {
+ printf ("Error in tset_d: expected -4.0, got ");
+ mpfr_print_binary (x); putchar('\n');
+ exit (1);
+ }
+
+ mpfr_set_d (x, 9.84891017624509146344e-01, MPFR_RNDU);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error in tset_d: expected 1.0, got ");
+ mpfr_print_binary (x); putchar('\n');
+ exit (1);
+ }
+
+ mpfr_init2 (z, 32);
+ mpfr_set_d (z, 1.0, (mpfr_rnd_t) 0);
+ if (mpfr_cmp_ui (z, 1))
+ {
+ mpfr_print_binary (z); puts ("");
+ printf ("Error: 1.0 != 1.0\n");
+ exit (1);
+ }
+ mpfr_set_prec (x, 53);
+ mpfr_init2 (y, 53);
+ mpfr_set_d (x, d=-1.08007920352320089721e+150, (mpfr_rnd_t) 0);
+ if (mpfr_get_d1 (x) != d)
+ {
+ mpfr_print_binary (x); puts ("");
+ printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
+ d, mpfr_get_d1 (x));
+ exit (1);
+ }
+
+ mpfr_set_d (x, 8.06294740693074521573e-310, (mpfr_rnd_t) 0);
+ d = -6.72658901114033715233e-165;
+ mpfr_set_d (x, d, (mpfr_rnd_t) 0);
+ if (d != mpfr_get_d1 (x))
+ {
+ mpfr_print_binary (x);
+ puts ("");
+ printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
+ d, mpfr_get_d1 (x));
+ exit (1);
+ }
+
+ n = (argc==1) ? 500000 : atoi(argv[1]);
+ for (k = 1; k <= n; k++)
+ {
+ do
+ {
+ d = DBL_RAND ();
+ }
+#ifdef HAVE_DENORMS
+ while (0);
+#else
+ while (ABS(d) < DBL_MIN);
+#endif
+ mpfr_set_d (x, d, (mpfr_rnd_t) 0);
+ dd = mpfr_get_d1 (x);
+ if (d != dd && !(Isnan(d) && Isnan(dd)))
+ {
+ printf ("Mismatch on : %1.18g != %1.18g\n", d, mpfr_get_d1 (x));
+ mpfr_print_binary (x);
+ puts ("");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tset_exp.c b/mpfr/tests/tset_exp.c
new file mode 100644
index 0000000000..2939db894c
--- /dev/null
+++ b/mpfr/tests/tset_exp.c
@@ -0,0 +1,67 @@
+/* Test file for mpfr_set_exp.
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x;
+ int ret;
+ mpfr_exp_t emin, emax;
+
+ tests_start_mpfr ();
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_init (x);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ ret = mpfr_set_exp (x, 2);
+ MPFR_ASSERTN(ret == 0 && mpfr_cmp_ui (x, 2) == 0);
+
+ set_emin (-1);
+ ret = mpfr_set_exp (x, -1);
+ MPFR_ASSERTN(ret == 0 && mpfr_cmp_ui_2exp (x, 1, -2) == 0);
+
+ set_emax (1);
+ ret = mpfr_set_exp (x, 1);
+ MPFR_ASSERTN(ret == 0 && mpfr_cmp_ui (x, 1) == 0);
+
+ ret = mpfr_set_exp (x, -2);
+ MPFR_ASSERTN(ret != 0 && mpfr_cmp_ui (x, 1) == 0);
+
+ ret = mpfr_set_exp (x, 2);
+ MPFR_ASSERTN(ret != 0 && mpfr_cmp_ui (x, 1) == 0);
+
+ mpfr_clear (x);
+
+ set_emin (emin);
+ set_emax (emax);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tset_f.c b/mpfr/tests/tset_f.c
new file mode 100644
index 0000000000..ea9c2aca29
--- /dev/null
+++ b/mpfr/tests/tset_f.c
@@ -0,0 +1,207 @@
+/* Test file for mpfr_set_f.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h> /* for ULONG_MAX */
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ mpfr_t x, u;
+ mpf_t y, z;
+ mpfr_exp_t emax;
+ unsigned long k, pr;
+ int r, inexact;
+
+ tests_start_mpfr ();
+
+ mpf_init (y);
+ mpf_init (z);
+
+ mpf_set_d (y, 0.0);
+
+ /* check prototype of mpfr_init_set_f */
+ mpfr_init_set_f (x, y, MPFR_RNDN);
+ mpfr_set_prec (x, 100);
+ mpfr_set_f (x, y, MPFR_RNDN);
+
+ mpf_urandomb (y, RANDS, 10 * GMP_NUMB_BITS);
+ mpfr_set_f (x, y, RND_RAND ());
+
+ /* bug found by Jean-Pierre Merlet */
+ mpfr_set_prec (x, 256);
+ mpf_set_prec (y, 256);
+ mpfr_init2 (u, 256);
+ mpfr_set_str (u,
+ "7.f10872b020c49ba5e353f7ced916872b020c49ba5e353f7ced916872b020c498@2",
+ 16, MPFR_RNDN);
+ mpf_set_str (y, "2033033E-3", 10); /* avoid 2033.033 which is
+ locale-sensitive */
+ mpfr_set_f (x, y, MPFR_RNDN);
+ if (mpfr_cmp (x, u))
+ {
+ printf ("mpfr_set_f failed for y=2033033E-3\n");
+ exit (1);
+ }
+ mpf_set_str (y, "-2033033E-3", 10); /* avoid -2033.033 which is
+ locale-sensitive */
+ mpfr_set_f (x, y, MPFR_RNDN);
+ mpfr_neg (u, u, MPFR_RNDN);
+ if (mpfr_cmp (x, u))
+ {
+ printf ("mpfr_set_f failed for y=-2033033E-3\n");
+ exit (1);
+ }
+
+ mpf_set_prec (y, 300);
+ mpf_set_str (y, "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", -2);
+ mpf_mul_2exp (y, y, 600);
+ mpfr_set_prec (x, 300);
+ mpfr_set_f (x, y, MPFR_RNDN);
+ if (mpfr_check (x) == 0)
+ {
+ printf ("Error in mpfr_set_f: corrupted result\n");
+ mpfr_dump (x);
+ exit (1);
+ }
+ MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, 901) == 0);
+
+ /* random values */
+ for (k = 1; k <= 1000; k++)
+ {
+ pr = 2 + (randlimb () & 255);
+ mpf_set_prec (z, pr);
+ mpf_urandomb (z, RANDS, z->_mp_prec);
+ mpfr_set_prec (u, ((pr / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS));
+ mpfr_set_f (u, z, MPFR_RNDN);
+ if (mpfr_cmp_f (u , z) != 0)
+ {
+ printf ("Error in mpfr_set_f:\n");
+ printf ("mpf (precision=%lu)=", pr);
+ mpf_out_str (stdout, 16, 0, z);
+ printf ("\nmpfr(precision=%lu)=",
+ ((pr / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS));
+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ mpfr_set_prec (x, pr);
+ mpfr_set_f (x, z, MPFR_RNDN);
+ mpfr_sub (u, u, x, MPFR_RNDN);
+ mpfr_abs (u, u, MPFR_RNDN);
+ if (mpfr_cmp_ui_2exp (u, 1, -pr - 1) > 0)
+ {
+ printf ("Error in mpfr_set_f: precision=%lu\n", pr);
+ printf ("mpf =");
+ mpf_out_str (stdout, 16, 0, z);
+ printf ("\nmpfr=");
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ }
+
+ /* Check for +0 */
+ mpfr_set_prec (x, 53);
+ mpf_set_prec (y, 53);
+ mpf_set_ui (y, 0);
+ for (r = 0 ; r < MPFR_RND_MAX ; r++)
+ {
+ int i;
+ for (i = -1; i <= 1; i++)
+ {
+ if (i)
+ mpfr_set_si (x, i, MPFR_RNDN);
+ inexact = mpfr_set_f (x, y, (mpfr_rnd_t) r);
+ if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact)
+ {
+ printf ("mpfr_set_f(x,0) failed for %s, i = %d\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
+ exit (1);
+ }
+ }
+ }
+
+ /* coverage test */
+ mpf_set_prec (y, 2);
+ mpfr_set_prec (x, 3 * mp_bits_per_limb);
+ mpf_set_ui (y, 1);
+ for (r = 0; r < mp_bits_per_limb; r++)
+ {
+ mpfr_urandomb (x, RANDS); /* to fill low limbs with random data */
+ inexact = mpfr_set_f (x, y, MPFR_RNDN);
+ MPFR_ASSERTN(inexact == 0 && mpfr_cmp_ui_2exp (x, 1, r) == 0);
+ mpf_mul_2exp (y, y, 1);
+ }
+
+ mpf_set_ui (y, 1);
+ mpf_mul_2exp (y, y, ULONG_MAX);
+ mpfr_set_f (x, y, MPFR_RNDN);
+ mpfr_set_ui (u, 1, MPFR_RNDN);
+ mpfr_mul_2ui (u, u, ULONG_MAX, MPFR_RNDN);
+ if (!mpfr_equal_p (x, u))
+ {
+ printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^ULONG_MAX\n");
+ exit (1);
+ }
+
+ emax = mpfr_get_emax ();
+
+ /* For mpf_mul_2exp, emax must fit in an unsigned long! */
+ if (emax >= 0 && emax <= ULONG_MAX)
+ {
+ mpf_set_ui (y, 1);
+ mpf_mul_2exp (y, y, emax);
+ mpfr_set_f (x, y, MPFR_RNDN);
+ mpfr_set_ui_2exp (u, 1, emax, MPFR_RNDN);
+ if (!mpfr_equal_p (x, u))
+ {
+ printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^emax\n");
+ exit (1);
+ }
+ }
+
+ /* For mpf_mul_2exp, emax - 1 must fit in an unsigned long! */
+ if (emax >= 1 && emax - 1 <= ULONG_MAX)
+ {
+ mpf_set_ui (y, 1);
+ mpf_mul_2exp (y, y, emax - 1);
+ mpfr_set_f (x, y, MPFR_RNDN);
+ mpfr_set_ui_2exp (u, 1, emax - 1, MPFR_RNDN);
+ if (!mpfr_equal_p (x, u))
+ {
+ printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^(emax-1)\n");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (u);
+ mpf_clear (y);
+ mpf_clear (z);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tset_ld.c b/mpfr/tests/tset_ld.c
new file mode 100644
index 0000000000..1e025aa928
--- /dev/null
+++ b/mpfr/tests/tset_ld.c
@@ -0,0 +1,312 @@
+/* Test file for mpfr_set_ld and mpfr_get_ld.
+
+Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+#include <limits.h>
+#ifdef WITH_FPU_CONTROL
+#include <fpu_control.h>
+#endif
+
+#include "mpfr-test.h"
+
+static void
+check_gcc33_bug (void)
+{
+ volatile long double x;
+ x = (long double) 9007199254740992.0 + 1.0;
+ if (x != 0.0)
+ return; /* OK */
+ printf
+ ("Detected optimization bug of gcc 3.3 on Alpha concerning long double\n"
+ "comparisons; set_ld tests might fail (set_ld won't work correctly).\n"
+ "See http://gcc.gnu.org/ml/gcc-bugs/2003-10/msg00853.html for more\n"
+ "information.\n");
+}
+
+static int
+Isnan_ld (long double d)
+{
+ double e = (double) d;
+ if (DOUBLE_ISNAN (e))
+ return 1;
+ LONGDOUBLE_NAN_ACTION (d, goto yes);
+ return 0;
+ yes:
+ return 1;
+}
+
+/* checks that a long double converted to a mpfr (with precision >=113),
+ then converted back to a long double gives the initial value,
+ or in other words mpfr_get_ld(mpfr_set_ld(d)) = d.
+*/
+static void
+check_set_get (long double d, mpfr_t x)
+{
+ int r;
+ long double e;
+ int inex;
+
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ inex = mpfr_set_ld (x, d, (mpfr_rnd_t) r);
+ if (inex != 0)
+ {
+ mpfr_exp_t emin, emax;
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+ printf ("Error: mpfr_set_ld should be exact\n");
+ printf ("d=%1.30Le inex=%d\n", d, inex);
+ if (emin >= LONG_MIN)
+ printf ("emin=%ld\n", (long) emin);
+ if (emax <= LONG_MAX)
+ printf ("emax=%ld\n", (long) emax);
+ mpfr_dump (x);
+ exit (1);
+ }
+ e = mpfr_get_ld (x, (mpfr_rnd_t) r);
+ if ((Isnan_ld(d) && ! Isnan_ld(e)) ||
+ (Isnan_ld(e) && ! Isnan_ld(d)) ||
+ (e != d && !(Isnan_ld(e) && Isnan_ld(d))))
+ {
+ printf ("Error: mpfr_get_ld o mpfr_set_ld <> Id\n");
+ printf (" r=%d\n", r);
+ printf (" d=%1.30Le get_ld(set_ld(d))=%1.30Le\n", d, e);
+ ld_trace (" d", d);
+ printf (" x="); mpfr_out_str (NULL, 16, 0, x, MPFR_RNDN);
+ printf ("\n");
+ ld_trace (" e", e);
+#ifdef MPFR_NANISNAN
+ if (Isnan_ld(d) || Isnan_ld(e))
+ printf ("The reason is that NAN == NAN. Please look at the "
+ "configure output\nand Section \"In case of problem\" "
+ "of the INSTALL file.\n");
+#endif
+ exit (1);
+ }
+ }
+}
+
+static void
+test_small (void)
+{
+ mpfr_t x, y, z;
+ long double d;
+
+ mpfr_init2 (x, 64);
+ mpfr_init2 (y, 64);
+ mpfr_init2 (z, 64);
+
+ /* x = 11906603631607553907/2^(16381+64) */
+ mpfr_set_str (x, "0.1010010100111100110000001110101101000111010110000001111101110011E-16381", 2, MPFR_RNDN);
+ d = mpfr_get_ld (x, MPFR_RNDN); /* infinite loop? */
+ mpfr_set_ld (y, d, MPFR_RNDN);
+ mpfr_sub (z, x, y, MPFR_RNDN);
+ mpfr_abs (z, z, MPFR_RNDN);
+ mpfr_clear_erangeflag ();
+ /* If long double = double, d should be equal to 0;
+ in this case, everything is OK. */
+ if (d != 0 && (mpfr_cmp_str (z, "1E-16434", 2, MPFR_RNDN) > 0 ||
+ mpfr_erangeflag_p ()))
+ {
+ printf ("Error with x = ");
+ mpfr_out_str (NULL, 10, 21, x, MPFR_RNDN);
+ printf (" = ");
+ mpfr_out_str (NULL, 16, 0, x, MPFR_RNDN);
+ printf ("\n -> d = %.21Lg", d);
+ printf ("\n -> y = ");
+ mpfr_out_str (NULL, 10, 21, y, MPFR_RNDN);
+ printf (" = ");
+ mpfr_out_str (NULL, 16, 0, y, MPFR_RNDN);
+ printf ("\n -> |x-y| = ");
+ mpfr_out_str (NULL, 16, 0, z, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+test_fixed_bugs (void)
+{
+ mpfr_t x;
+ long double l, m;
+
+ /* bug found by Steve Kargl (2009-03-14) */
+ mpfr_init2 (x, 64);
+ mpfr_set_ui_2exp (x, 1, -16447, MPFR_RNDN);
+ mpfr_get_ld (x, MPFR_RNDN); /* an assertion failed in init2.c:50 */
+
+ /* bug reported by Jakub Jelinek (2010-10-17)
+ https://gforge.inria.fr/tracker/?func=detail&aid=11300 */
+ mpfr_set_prec (x, MPFR_LDBL_MANT_DIG);
+ /* l = 0x1.23456789abcdef0123456789abcdp-914L; */
+ l = 8.215640181713713164092636634579e-276;
+ mpfr_set_ld (x, l, MPFR_RNDN);
+ m = mpfr_get_ld (x, MPFR_RNDN);
+ if (m != l)
+ {
+ printf ("Error in get_ld o set_ld for l=%Le\n", l);
+ printf ("Got m=%Le instead of l\n", m);
+ exit (1);
+ }
+
+ /* another similar test which failed with extended double precision and the
+ generic code for mpfr_set_ld */
+ /* l = 0x1.23456789abcdef0123456789abcdp-968L; */
+ l = 4.560596445887084662336528403703e-292;
+ mpfr_set_ld (x, l, MPFR_RNDN);
+ m = mpfr_get_ld (x, MPFR_RNDN);
+ if (m != l)
+ {
+ printf ("Error in get_ld o set_ld for l=%Le\n", l);
+ printf ("Got m=%Le instead of l\n", m);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ long double d, e;
+ mpfr_t x;
+ int i;
+ mpfr_exp_t emax;
+#ifdef WITH_FPU_CONTROL
+ fpu_control_t cw;
+
+ if (argc > 1)
+ {
+ cw = strtol(argv[1], NULL, 0);
+ printf ("FPU control word: 0x%x\n", (unsigned int) cw);
+ _FPU_SETCW (cw);
+ }
+#endif
+
+ check_gcc33_bug ();
+ test_fixed_bugs ();
+
+ tests_start_mpfr ();
+ mpfr_test_init ();
+
+ mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
+
+#if !defined(MPFR_ERRDIVZERO)
+ /* check NaN */
+ mpfr_set_nan (x);
+ d = mpfr_get_ld (x, MPFR_RNDN);
+ check_set_get (d, x);
+#endif
+
+ /* check +0.0 and -0.0 */
+ d = 0.0;
+ check_set_get (d, x);
+ d = DBL_NEG_ZERO;
+ check_set_get (d, x);
+
+ /* check that the sign of -0.0 is set */
+ mpfr_set_ld (x, DBL_NEG_ZERO, MPFR_RNDN);
+ if (MPFR_SIGN(x) > 0)
+ {
+ printf ("Error: sign of -0.0 is not set correctly\n");
+#if _GMP_IEEE_FLOATS
+ exit (1);
+ /* Non IEEE doesn't support negative zero yet */
+#endif
+ }
+
+#if !defined(MPFR_ERRDIVZERO)
+ /* check +Inf */
+ mpfr_set_inf (x, 1);
+ d = mpfr_get_ld (x, MPFR_RNDN);
+ check_set_get (d, x);
+
+ /* check -Inf */
+ mpfr_set_inf (x, -1);
+ d = mpfr_get_ld (x, MPFR_RNDN);
+ check_set_get (d, x);
+#endif
+
+ /* check the largest power of two */
+ d = 1.0; while (d < LDBL_MAX / 2.0) d += d;
+ check_set_get (d, x);
+ check_set_get (-d, x);
+
+ /* check largest long double */
+ d = LDBL_MAX;
+ check_set_get (d, x);
+ check_set_get (-d, x);
+
+ /* check the smallest power of two */
+ d = 1.0;
+ while ((e = d / 2.0) != (long double) 0.0 && e != d)
+ d = e;
+ check_set_get (d, x);
+ check_set_get (-d, x);
+
+ /* check largest 2^(2^k) that is representable as a long double */
+ d = (LDBL_MAX / 2) + (LDBL_MAX / 4 * LDBL_EPSILON);
+ check_set_get (d, x);
+
+ /* check that 2^i, 2^i+1 and 2^i-1 are correctly converted */
+ d = 1.0;
+ for (i = 1; i < MPFR_LDBL_MANT_DIG; i++)
+ {
+ d = 2.0 * d; /* d = 2^i */
+ check_set_get (d, x);
+ check_set_get (d + 1.0, x);
+ check_set_get (d - 1.0, x);
+ }
+
+ for (i = 0; i < 10000; i++)
+ {
+ mpfr_urandomb (x, RANDS);
+ d = mpfr_get_ld (x, MPFR_RNDN);
+ check_set_get (d, x);
+ }
+
+ /* check with reduced emax to exercise overflow */
+ emax = mpfr_get_emax ();
+ mpfr_set_prec (x, 2);
+ set_emax (1);
+ mpfr_set_ld (x, (long double) 2.0, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ for (d = (long double) 2.0, i = 0; i < 13; i++, d *= d);
+ /* now d = 2^8192 */
+ mpfr_set_ld (x, d, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ set_emax (emax);
+
+ mpfr_clear (x);
+
+ test_small ();
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tset_q.c b/mpfr/tests/tset_q.c
new file mode 100644
index 0000000000..905b877c98
--- /dev/null
+++ b/mpfr/tests/tset_q.c
@@ -0,0 +1,170 @@
+/* Test file for mpfr_set_q.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+check (long int n, long int d, mpfr_rnd_t rnd, const char *ys)
+{
+ mpq_t q;
+ mpfr_t x, t;
+ int inexact, compare;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (t, mpfr_get_prec (x) + mp_bits_per_limb);
+ mpq_init (q);
+ mpq_set_si (q, n, d);
+ inexact = mpfr_set_q (x, q, rnd);
+
+ /* check values */
+ if (mpfr_cmp_str1(x, ys))
+ {
+ printf ("Error for q=%ld/%ld and rnd=%s\n", n, d,
+ mpfr_print_rnd_mode (rnd));
+ printf ("correct result is %s, mpfr_set_q gives ", ys);
+ mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
+ putchar('\n');
+ exit (1);
+ }
+
+ /* check inexact flag */
+ if (mpfr_mul_ui (t, x, (d < 0) ? (-d) : d, rnd))
+ {
+ printf ("t <- x * d should be exact\n");
+ exit (1);
+ }
+ compare = mpfr_cmp_si (t, n);
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact < 0) && (compare >= 0)) ||
+ ((inexact > 0) && (compare <= 0)))
+ {
+ printf ("wrong inexact flag: expected %d, got %d\n", compare,
+ inexact);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (t);
+ mpq_clear (q);
+}
+
+static void
+check0 (void)
+{
+ mpq_t y;
+ mpfr_t x;
+ int inexact;
+ int r;
+
+ /* Check for +0 */
+ mpfr_init (x);
+ mpq_init (y);
+ mpq_set_si (y, 0, 1);
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ inexact = mpfr_set_q(x, y, (mpfr_rnd_t) r);
+ if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact)
+ {
+ printf("mpfr_set_q(x,0) failed for %s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit(1);
+ }
+ }
+ mpfr_clear (x);
+ mpq_clear (y);
+}
+
+static void
+check_nan_inf_mpq (void)
+{
+ mpfr_t mpfr_value, mpfr_cmp;
+ mpq_t mpq_value;
+ int status;
+
+ mpfr_init2 (mpfr_value, MPFR_PREC_MIN);
+ mpq_init (mpq_value);
+ mpq_set_si (mpq_value, 0, 0);
+ mpz_set_si (mpq_denref (mpq_value), 0);
+
+ status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN);
+
+ if ((status != 0) || (!MPFR_IS_NAN (mpfr_value)))
+ {
+ mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN);
+ mpfr_set_nan (mpfr_cmp);
+ printf ("mpfr_set_q with a NAN mpq value returned a wrong value :\n"
+ " waiting for ");
+ mpfr_print_binary (mpfr_cmp);
+ printf (" got ");
+ mpfr_print_binary (mpfr_value);
+ printf ("\n trinary value is %d\n", status);
+ exit (1);
+ }
+
+ mpq_set_si (mpq_value, -1, 0);
+ mpz_set_si (mpq_denref (mpq_value), 0);
+
+ status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN);
+
+ if ((status != 0) || (!MPFR_IS_INF (mpfr_value)) ||
+ (MPFR_SIGN(mpfr_value) != mpq_sgn(mpq_value)))
+ {
+ mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN);
+ mpfr_set_inf (mpfr_cmp, -1);
+ printf ("mpfr_set_q with a -INF mpq value returned a wrong value :\n"
+ " waiting for ");
+ mpfr_print_binary (mpfr_cmp);
+ printf (" got ");
+ mpfr_print_binary (mpfr_value);
+ printf ("\n trinary value is %d\n", status);
+ exit (1);
+ }
+
+ mpq_clear (mpq_value);
+ mpfr_clear (mpfr_value);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+
+ check(-1647229822, 40619231, MPFR_RNDZ, "-4.055295438754120596e1");
+ check(-148939696, 1673285490, MPFR_RNDZ, "-8.9010331404953485501e-2");
+ check(-441322590, 273662545, MPFR_RNDZ, "-1.6126525096812205362");
+ check(-1631156895, 1677687197, MPFR_RNDU, "-9.722652100563177191e-1");
+ check(2141332571, 3117601, MPFR_RNDZ, "6.8685267004982347316e2");
+ check(75504803, 400207282, MPFR_RNDU, "1.8866424074712365155e-1");
+ check(643562308, 23100894, MPFR_RNDD, "2.7858762002890447462e1");
+ check(632549085, 1831935802, MPFR_RNDN, "3.4528998467600230393e-1");
+ check (1, 1, MPFR_RNDN, "1.0");
+
+ check0();
+
+ check_nan_inf_mpq ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tset_si.c b/mpfr/tests/tset_si.c
new file mode 100644
index 0000000000..b9ca0eabea
--- /dev/null
+++ b/mpfr/tests/tset_si.c
@@ -0,0 +1,464 @@
+/* Test file for mpfr_set_si and mpfr_set_ui.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+#define ERROR(str) {printf("Error for "str"\n"); exit(1);}
+
+static void
+test_2exp (void)
+{
+ mpfr_t x;
+ int res;
+
+ mpfr_init2 (x, 32);
+
+ mpfr_set_ui_2exp (x, 1, 0, MPFR_RNDN);
+ if (mpfr_cmp_ui(x, 1))
+ ERROR("(1U,0)");
+
+ mpfr_set_ui_2exp (x, 1024, -10, MPFR_RNDN);
+ if (mpfr_cmp_ui(x, 1))
+ ERROR("(1024U,-10)");
+
+ mpfr_set_ui_2exp (x, 1024, 10, MPFR_RNDN);
+ if (mpfr_cmp_ui(x, 1024*1024))
+ ERROR("(1024U,+10)");
+
+ mpfr_set_si_2exp (x, -1024L * 1024L, -10, MPFR_RNDN);
+ if (mpfr_cmp_si(x, -1024))
+ ERROR("(1M,-10)");
+
+ mpfr_set_ui_2exp (x, 0x92345678, 16, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "92345678@4", 16, MPFR_RNDN))
+ ERROR("(x92345678U,+16)");
+
+ mpfr_set_si_2exp (x, -0x1ABCDEF0, -256, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "-1ABCDEF0@-64", 16, MPFR_RNDN))
+ ERROR("(-x1ABCDEF0,-256)");
+
+ mpfr_set_prec (x, 2);
+ res = mpfr_set_si_2exp (x, 7, 10, MPFR_RNDU);
+ if (mpfr_cmp_ui (x, 1<<13) || res <= 0)
+ ERROR ("Prec 2 + si_2exp");
+
+ res = mpfr_set_ui_2exp (x, 7, 10, MPFR_RNDU);
+ if (mpfr_cmp_ui (x, 1<<13) || res <= 0)
+ ERROR ("Prec 2 + ui_2exp");
+
+ mpfr_clear_flags ();
+ mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
+ if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
+ ERROR ("mpfr_set_ui_2exp and overflow (bad result)");
+ if (!mpfr_overflow_p ())
+ ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)");
+
+ mpfr_clear_flags ();
+ mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
+ if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
+ ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)");
+ if (!mpfr_overflow_p ())
+ ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)");
+
+ mpfr_clear_flags ();
+ mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, MPFR_RNDN);
+ if (!mpfr_inf_p (x) || MPFR_IS_POS (x))
+ ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)");
+ if (!mpfr_overflow_p ())
+ ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)");
+
+ mpfr_clear (x);
+}
+
+static void
+test_macros (void)
+{
+ mpfr_t x[3];
+ mpfr_ptr p;
+ int r;
+
+ mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0);
+ p = x[0];
+ r = 0;
+ mpfr_set_ui (p++, 0, (mpfr_rnd_t) r++);
+ if (p != x[1] || r != 1)
+ {
+ printf ("Error in mpfr_set_ui macro: p - x[0] = %d (expecting 1), "
+ "r = %d (expecting 1)\n", (int) (p - x[0]), r);
+ exit (1);
+ }
+ p = x[0];
+ r = 0;
+ mpfr_set_si (p++, 0, (mpfr_rnd_t) r++);
+ if (p != x[1] || r != 1)
+ {
+ printf ("Error in mpfr_set_si macro: p - x[0] = %d (expecting 1), "
+ "r = %d (expecting 1)\n", (int) (p - x[0]), r);
+ exit (1);
+ }
+ mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0);
+}
+
+static void
+test_macros_keyword (void)
+{
+ mpfr_t x;
+ unsigned long i;
+
+ mpfr_init2 (x, 64);
+#define MKN 0x1000000
+#define long short
+ mpfr_set_ui (x, MKN, MPFR_RNDN);
+#undef long
+ i = mpfr_get_ui (x, MPFR_RNDN);
+ if (i != MKN)
+ {
+ printf ("Error in test_macros_keyword: expected 0x%lx, got 0x%lx.\n",
+ (unsigned long) MKN, i);
+ exit (1);
+ }
+ mpfr_clear (x);
+}
+
+/* FIXME: Comparing against mpfr_get_si/ui is not ideal, it'd be better to
+ have all tests examine the bits in mpfr_t for what should come out. */
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x;
+ long k, z, d, N;
+ unsigned long zl, dl;
+ int inex;
+ int r;
+ mpfr_exp_t emin, emax;
+ int flag;
+
+ tests_start_mpfr ();
+
+ mpfr_init2 (x, 100);
+
+ N = (argc==1) ? 100000 : atol (argv[1]);
+
+ for (k = 1; k <= N; k++)
+ {
+ z = (long) (randlimb () & LONG_MAX) + LONG_MIN / 2;
+ inex = mpfr_set_si (x, z, MPFR_RNDZ);
+ d = mpfr_get_si (x, MPFR_RNDZ);
+ if (d != z)
+ {
+ printf ("Error in mpfr_set_si: expected %ld got %ld\n", z, d);
+ exit (1);
+ }
+ if (inex)
+ {
+ printf ("Error in mpfr_set_si: inex value incorrect for %ld: %d\n",
+ z, inex);
+ exit (1);
+ }
+ }
+
+ for (k = 1; k <= N; k++)
+ {
+ zl = randlimb ();
+ inex = mpfr_set_ui (x, zl, MPFR_RNDZ);
+ dl = mpfr_get_ui (x, MPFR_RNDZ);
+ if (dl != zl)
+ {
+ printf ("Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl);
+ exit (1);
+ }
+ if (inex)
+ {
+ printf ("Error in mpfr_set_ui: inex value incorrect for %lu: %d\n",
+ zl, inex);
+ exit (1);
+ }
+ }
+
+ mpfr_set_prec (x, 2);
+ if (mpfr_set_si (x, 5, MPFR_RNDZ) >= 0)
+ {
+ printf ("Wrong inexact flag for x=5, rnd=MPFR_RNDZ\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ if (mpfr_set_si (x, -5, MPFR_RNDZ) <= 0)
+ {
+ printf ("Wrong inexact flag for x=-5, rnd=MPFR_RNDZ\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 3);
+ inex = mpfr_set_si (x, 77617, MPFR_RNDD); /* should be 65536 */
+ if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
+ || inex >= 0)
+ {
+ printf ("Error in mpfr_set_si(x:3, 77617, MPFR_RNDD)\n");
+ mpfr_print_binary (x);
+ puts ("");
+ exit (1);
+ }
+ inex = mpfr_set_ui (x, 77617, MPFR_RNDD); /* should be 65536 */
+ if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
+ || inex >= 0)
+ {
+ printf ("Error in mpfr_set_ui(x:3, 77617, MPFR_RNDD)\n");
+ mpfr_print_binary (x);
+ puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ inex = mpfr_set_si (x, 33096, MPFR_RNDU);
+ if (mpfr_get_si (x, MPFR_RNDZ) != 49152 || inex <= 0)
+ {
+ printf ("Error in mpfr_set_si, exp. 49152, got %ld, inex %d\n",
+ mpfr_get_si (x, MPFR_RNDZ), inex);
+ exit (1);
+ }
+ inex = mpfr_set_ui (x, 33096, MPFR_RNDU);
+ if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
+ {
+ printf ("Error in mpfr_set_ui, exp. 49152, got %ld, inex %d\n",
+ mpfr_get_si (x, MPFR_RNDZ), inex);
+ exit (1);
+ }
+ /* Also test the mpfr_set_ui function (instead of macro). */
+ inex = (mpfr_set_ui) (x, 33096, MPFR_RNDU);
+ if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
+ {
+ printf ("Error in mpfr_set_ui function, exp. 49152, got %ld, inex %d\n",
+ mpfr_get_si (x, MPFR_RNDZ), inex);
+ exit (1);
+ }
+
+ for (r = 0 ; r < MPFR_RND_MAX ; r++)
+ {
+ mpfr_set_si (x, -1, (mpfr_rnd_t) r);
+ mpfr_set_ui (x, 0, (mpfr_rnd_t) r);
+ if (MPFR_IS_NEG (x) || mpfr_get_ui (x, (mpfr_rnd_t) r) != 0)
+ {
+ printf ("mpfr_set_ui (x, 0) gives -0 for %s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, (mpfr_rnd_t) r);
+ mpfr_set_si (x, 0, (mpfr_rnd_t) r);
+ if (MPFR_IS_NEG (x) || mpfr_get_si (x, (mpfr_rnd_t) r) != 0)
+ {
+ printf ("mpfr_set_si (x, 0) gives -0 for %s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ }
+
+ /* check potential bug in case mp_limb_t is unsigned */
+ emax = mpfr_get_emax ();
+ set_emax (0);
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ if (mpfr_sgn (x) >= 0)
+ {
+ printf ("mpfr_set_si (x, -1) fails\n");
+ exit (1);
+ }
+ set_emax (emax);
+
+ emax = mpfr_get_emax ();
+ set_emax (5);
+ mpfr_set_prec (x, 2);
+ mpfr_set_si (x, -31, MPFR_RNDN);
+ if (mpfr_sgn (x) >= 0)
+ {
+ printf ("mpfr_set_si (x, -31) fails\n");
+ exit (1);
+ }
+ set_emax (emax);
+
+ /* test for get_ui */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_get_ui (x, MPFR_RNDN) == 0);
+ mpfr_set_ui (x, ULONG_MAX, MPFR_RNDU);
+ mpfr_nextabove (x);
+ mpfr_get_ui (x, MPFR_RNDU);
+
+ /* another test for get_ui */
+ mpfr_set_prec (x, 10);
+ mpfr_set_str_binary (x, "10.101");
+ dl = mpfr_get_ui (x, MPFR_RNDN);
+ MPFR_ASSERTN (dl == 3);
+
+ mpfr_set_str_binary (x, "-1.0");
+ mpfr_get_ui (x, MPFR_RNDN);
+
+ mpfr_set_str_binary (x, "0.1");
+ dl = mpfr_get_ui (x, MPFR_RNDN);
+ MPFR_ASSERTN (dl == 0);
+ dl = mpfr_get_ui (x, MPFR_RNDZ);
+ MPFR_ASSERTN (dl == 0);
+ dl = mpfr_get_ui (x, MPFR_RNDD);
+ MPFR_ASSERTN (dl == 0);
+ dl = mpfr_get_ui (x, MPFR_RNDU);
+ MPFR_ASSERTN (dl == 1);
+
+ /* coverage tests */
+ mpfr_set_prec (x, 2);
+ mpfr_set_si (x, -7, MPFR_RNDD);
+ MPFR_ASSERTN(mpfr_cmp_si (x, -8) == 0);
+ mpfr_set_prec (x, 2);
+ mpfr_set_ui (x, 7, MPFR_RNDU);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 8) == 0);
+ emax = mpfr_get_emax ();
+ set_emax (3);
+ mpfr_set_ui (x, 7, MPFR_RNDU);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ set_emax (1);
+ MPFR_ASSERTN( mpfr_set_ui (x, 7, MPFR_RNDU) );
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ set_emax (emax);
+ mpfr_set_ui_2exp (x, 17, -50, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_get_ui (x, MPFR_RNDD) == 0);
+ MPFR_ASSERTN (mpfr_get_si (x, MPFR_RNDD) == 0);
+
+ /* Test for ERANGE flag + correct behaviour if overflow */
+ mpfr_set_prec (x, 256);
+ mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
+ mpfr_clear_erangeflag ();
+ dl = mpfr_get_ui (x, MPFR_RNDN);
+ if (dl != ULONG_MAX || mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_ui + ERANGE + ULONG_MAX (1)\n");
+ exit (1);
+ }
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ dl = mpfr_get_ui (x, MPFR_RNDN);
+ if (dl != ULONG_MAX || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_ui + ERANGE + ULONG_MAX (2)\n");
+ exit (1);
+ }
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_clear_erangeflag ();
+ dl = mpfr_get_ui (x, MPFR_RNDN);
+ if (dl != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_ui + ERANGE + -1 \n");
+ exit (1);
+ }
+ mpfr_set_si (x, LONG_MAX, MPFR_RNDN);
+ mpfr_clear_erangeflag ();
+ d = mpfr_get_si (x, MPFR_RNDN);
+ if (d != LONG_MAX || mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_si + ERANGE + LONG_MAX (1): %ld\n", d);
+ exit (1);
+ }
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ d = mpfr_get_si (x, MPFR_RNDN);
+ if (d != LONG_MAX || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_si + ERANGE + LONG_MAX (2)\n");
+ exit (1);
+ }
+ mpfr_set_si (x, LONG_MIN, MPFR_RNDN);
+ mpfr_clear_erangeflag ();
+ d = mpfr_get_si (x, MPFR_RNDN);
+ if (d != LONG_MIN || mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_si + ERANGE + LONG_MIN (1)\n");
+ exit (1);
+ }
+ mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+ d = mpfr_get_si (x, MPFR_RNDN);
+ if (d != LONG_MIN || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_si + ERANGE + LONG_MIN (2)\n");
+ exit (1);
+ }
+
+ mpfr_set_nan (x);
+ mpfr_clear_erangeflag ();
+ d = mpfr_get_ui (x, MPFR_RNDN);
+ if (d != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_ui + NaN\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ d = mpfr_get_si (x, MPFR_RNDN);
+ if (d != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for get_si + NaN\n");
+ exit (1);
+ }
+
+ emin = mpfr_get_emin ();
+ mpfr_set_prec (x, 2);
+
+ mpfr_set_emin (4);
+ mpfr_clear_flags ();
+ mpfr_set_ui (x, 7, MPFR_RNDU);
+ flag = mpfr_underflow_p ();
+ mpfr_set_emin (emin);
+ if (mpfr_cmp_ui (x, 8) != 0)
+ {
+ printf ("Error for mpfr_set_ui (x, 7, MPFR_RNDU), prec = 2, emin = 4\n");
+ exit (1);
+ }
+ if (flag)
+ {
+ printf ("mpfr_set_ui (x, 7, MPFR_RNDU) should not underflow "
+ "with prec = 2, emin = 4\n");
+ exit (1);
+ }
+
+ mpfr_set_emin (4);
+ mpfr_clear_flags ();
+ mpfr_set_si (x, -7, MPFR_RNDD);
+ flag = mpfr_underflow_p ();
+ mpfr_set_emin (emin);
+ if (mpfr_cmp_si (x, -8) != 0)
+ {
+ printf ("Error for mpfr_set_si (x, -7, MPFR_RNDD), prec = 2, emin = 4\n");
+ exit (1);
+ }
+ if (flag)
+ {
+ printf ("mpfr_set_si (x, -7, MPFR_RNDD) should not underflow "
+ "with prec = 2, emin = 4\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+
+ test_2exp ();
+ test_macros ();
+ test_macros_keyword ();
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tset_sj.c b/mpfr/tests/tset_sj.c
new file mode 100644
index 0000000000..4ed0031051
--- /dev/null
+++ b/mpfr/tests/tset_sj.c
@@ -0,0 +1,195 @@
+/* Test file for
+ mpfr_set_sj, mpfr_set_uj, mpfr_set_sj_2exp and mpfr_set_uj_2exp.
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" /* for a build within gmp */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-intmax.h"
+#include "mpfr-test.h"
+
+#ifndef _MPFR_H_HAVE_INTMAX_T
+
+int
+main (void)
+{
+ return 77;
+}
+
+#else
+
+#define ERROR(str) {printf("Error for "str"\n"); exit(1);}
+
+static int
+inexact_sign (int x)
+{
+ return (x < 0) ? -1 : (x > 0);
+}
+
+static void
+check_set_uj (mpfr_prec_t pmin, mpfr_prec_t pmax, int N)
+{
+ mpfr_t x, y;
+ mpfr_prec_t p;
+ int inex1, inex2, n;
+ mp_limb_t limb;
+
+ mpfr_inits2 (pmax, x, y, (mpfr_ptr) 0);
+
+ for ( p = pmin ; p < pmax ; p++)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_set_prec (y, p);
+ for (n = 0 ; n < N ; n++)
+ {
+ /* mp_limb_t may be unsigned long long */
+ limb = (unsigned long) randlimb ();
+ inex1 = mpfr_set_uj (x, limb, MPFR_RNDN);
+ inex2 = mpfr_set_ui (y, limb, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("ERROR for mpfr_set_uj and j=%lu and p=%lu\n",
+ (unsigned long) limb, (unsigned long) p);
+ printf ("X="); mpfr_dump (x);
+ printf ("Y="); mpfr_dump (y);
+ exit (1);
+ }
+ if (inexact_sign (inex1) != inexact_sign (inex2))
+ {
+ printf ("ERROR for inexact(set_uj): j=%lu p=%lu\n"
+ "Inexact1= %d Inexact2= %d\n",
+ (unsigned long) limb, (unsigned long) p, inex1, inex2);
+ exit (1);
+ }
+ }
+ }
+ /* Special case */
+ mpfr_set_prec (x, sizeof(uintmax_t)*CHAR_BIT);
+ inex1 = mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
+ if (inex1 != 0 || mpfr_sgn(x) <= 0)
+ ERROR ("inexact / UINTMAX_MAX");
+ inex1 = mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ if (inex1 != 0 || !mpfr_powerof2_raw (x)
+ || MPFR_EXP (x) != (sizeof(uintmax_t)*CHAR_BIT+1) )
+ ERROR ("power of 2");
+ mpfr_set_uj (x, 0, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (x))
+ ERROR ("Setting 0");
+
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+static void
+check_set_uj_2exp (void)
+{
+ mpfr_t x;
+ int inex;
+
+ mpfr_init2 (x, sizeof(uintmax_t)*CHAR_BIT);
+
+ inex = mpfr_set_uj_2exp (x, 1, 0, MPFR_RNDN);
+ if (inex || mpfr_cmp_ui(x, 1))
+ ERROR("(1U,0)");
+
+ inex = mpfr_set_uj_2exp (x, 1024, -10, MPFR_RNDN);
+ if (inex || mpfr_cmp_ui(x, 1))
+ ERROR("(1024U,-10)");
+
+ inex = mpfr_set_uj_2exp (x, 1024, 10, MPFR_RNDN);
+ if (inex || mpfr_cmp_ui(x, 1024L * 1024L))
+ ERROR("(1024U,+10)");
+
+ inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, 1000, MPFR_RNDN);
+ inex |= mpfr_div_2ui (x, x, 1000, MPFR_RNDN);
+ inex |= mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ if (inex || !mpfr_powerof2_raw (x)
+ || MPFR_EXP (x) != (sizeof(uintmax_t)*CHAR_BIT+1) )
+ ERROR("(UINTMAX_MAX)");
+
+ inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, MPFR_EMAX_MAX-10, MPFR_RNDN);
+ if (inex == 0 || !mpfr_inf_p (x))
+ ERROR ("Overflow");
+
+ inex = mpfr_set_uj_2exp (x, MPFR_UINTMAX_MAX, MPFR_EMIN_MIN-1000, MPFR_RNDN);
+ if (inex == 0 || !MPFR_IS_ZERO (x))
+ ERROR ("Underflow");
+
+ mpfr_clear (x);
+}
+
+static void
+check_set_sj (void)
+{
+ mpfr_t x;
+ int inex;
+
+ mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
+
+ inex = mpfr_set_sj (x, -MPFR_INTMAX_MAX, MPFR_RNDN);
+ inex |= mpfr_add_si (x, x, -1, MPFR_RNDN);
+ if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
+ || MPFR_EXP (x) != (sizeof(intmax_t)*CHAR_BIT) )
+ ERROR("set_sj (-INTMAX_MAX)");
+
+ inex = mpfr_set_sj (x, 1742, MPFR_RNDN);
+ if (inex || mpfr_cmp_ui (x, 1742))
+ ERROR ("set_sj (1742)");
+
+ mpfr_clear (x);
+}
+
+static void
+check_set_sj_2exp (void)
+{
+ mpfr_t x;
+ int inex;
+
+ mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
+
+ inex = mpfr_set_sj_2exp (x, MPFR_INTMAX_MIN, 1000, MPFR_RNDN);
+ if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
+ || MPFR_EXP (x) != (sizeof(intmax_t)*CHAR_BIT+1000) )
+ ERROR("set_sj_2exp (INTMAX_MIN)");
+
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_set_uj (2, 128, 50);
+ check_set_uj_2exp ();
+ check_set_sj ();
+ check_set_sj_2exp ();
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tset_str.c b/mpfr/tests/tset_str.c
new file mode 100644
index 0000000000..023f862b11
--- /dev/null
+++ b/mpfr/tests/tset_str.c
@@ -0,0 +1,870 @@
+/* Test file for mpfr_set_str.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define N 30000
+
+#define CHECK53(y, s, r, x, t, n) \
+ mpfr_set_str (y, s, 10, r); \
+ mpfr_set_str_binary (x, t); \
+ if (mpfr_cmp (x, y)) \
+ { \
+ printf ("Error in mpfr_set_str (%d):\n", n); \
+ mpfr_print_binary (x); \
+ puts (""); \
+ mpfr_print_binary (y); \
+ puts (""); \
+ mpfr_clear (x); \
+ mpfr_clear (y); \
+ exit (1); \
+ }
+
+static void
+check_underflow (void)
+{
+ mpfr_t a;
+ mpfr_exp_t emin, emax;
+ int res;
+
+ mpfr_init (a);
+
+ /* Check underflow */
+ emin = mpfr_get_emin ();
+ set_emin (-20);
+ res = mpfr_set_str (a, "0.00000000001", 10, MPFR_RNDZ);
+ if (!MPFR_IS_ZERO (a))
+ {
+ printf("ERROR for mpfr_set_str (a, \"0.00000000001\", 10, MPFR_RNDN)\n"
+ " with emin=-20\n"
+ "res=%d\n", res);
+ mpfr_dump (a);
+ exit (1);
+ }
+ set_emin (emin);
+
+ /* check overflow */
+ emax = mpfr_get_emax ();
+ set_emax (1073741823); /* 2^30-1 */
+ mpfr_set_str (a, "2E1000000000", 10, MPFR_RNDN);
+ if (!mpfr_inf_p (a) || mpfr_sgn (a) < 0)
+ {
+ printf("ERROR for mpfr_set_str (a, \"2E1000000000\", 10, MPFR_RNDN);\n");
+ exit (1);
+ }
+ set_emax (emax);
+
+ mpfr_clear (a);
+}
+
+/* Bug found by Christoph Lauter. */
+static void
+bug20081028 (void)
+{
+ mpfr_t x;
+ const char *s = "0.10000000000000000000000000000001E1";
+
+ mpfr_init2 (x, 32);
+ mpfr_set_str (x, "1.00000000000000000006", 10, MPFR_RNDU);
+ if (! mpfr_greater_p (x, __gmpfr_one))
+ {
+ printf ("Error in bug20081028:\nExpected %s\nGot ", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ unsigned long k, bd, nc, i;
+ char *str, *str2;
+ mpfr_exp_t e;
+ int base, logbase, prec, baseprec, ret, obase;
+
+ tests_start_mpfr ();
+
+ if (argc >= 2) /* tset_str <string> [<prec>] [<ibase>] [<obase>] */
+ {
+ prec = (argc >= 3) ? atoi (argv[2]) : 53;
+ base = (argc >= 4) ? atoi (argv[3]) : 2;
+ obase = (argc >= 5) ? atoi (argv[4]) : 10;
+ mpfr_init2 (x, prec);
+ mpfr_set_str (x, argv[1], base, MPFR_RNDN);
+ mpfr_out_str (stdout, obase, 0, x, MPFR_RNDN);
+ puts ("");
+ mpfr_clear (x);
+ return 0;
+ }
+
+ mpfr_init2 (x, 2);
+
+ nc = (argc > 1) ? atoi(argv[1]) : 53;
+ if (nc < 100)
+ nc = 100;
+
+ bd = randlimb () & 8;
+
+ str2 = str = (char*) (*__gmp_allocate_func) (nc);
+
+ if (bd)
+ {
+ for(k = 1; k <= bd; k++)
+ *(str2++) = (randlimb () & 1) + '0';
+ }
+ else
+ *(str2++) = '0';
+
+ *(str2++) = '.';
+
+ for (k = 1; k < nc - 17 - bd; k++)
+ *(str2++) = '0' + (char) (randlimb () & 1);
+
+ *(str2++) = 'e';
+ sprintf (str2, "%d", (int) (randlimb () & INT_MAX) + INT_MIN/2);
+
+ mpfr_set_prec (x, nc + 10);
+ mpfr_set_str_binary (x, str);
+
+ mpfr_set_prec (x, 54);
+ mpfr_set_str_binary (x, "0.100100100110110101001010010101111000001011100100101010E-529");
+ mpfr_init2 (y, 54);
+ mpfr_set_str (y, "4.936a52bc17254@-133", 16, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (1a):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "0.111111101101110010111010100110000111011001010100001101E-529");
+ mpfr_set_str (y, "0.fedcba98765434P-529", 16, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (1b):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ (*__gmp_free_func) (str, nc);
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_str_binary (x, "+110101100.01010000101101000000100111001000101011101110E00");
+
+ mpfr_set_str_binary (x, "1.0");
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error in mpfr_set_str_binary for s=1.0\n");
+ mpfr_clear(x);
+ mpfr_clear(y);
+ exit(1);
+ }
+
+ mpfr_set_str_binary (x, "+0000");
+ mpfr_set_str_binary (x, "+0000E0");
+ mpfr_set_str_binary (x, "0000E0");
+ if (mpfr_cmp_ui (x, 0))
+ {
+ printf ("Error in mpfr_set_str_binary for s=0.0\n");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (x, "+243495834958.53452345E1", 10, MPFR_RNDN);
+ mpfr_set_str (x, "9007199254740993", 10, MPFR_RNDN);
+ mpfr_set_str (x, "9007199254740992", 10, MPFR_RNDU);
+ mpfr_set_str (x, "9007199254740992", 10, MPFR_RNDD);
+ mpfr_set_str (x, "9007199254740992", 10, MPFR_RNDZ);
+
+ /* check a random number printed and read is not modified */
+ prec = 53;
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (y, prec);
+ for (i=0;i<N;i++)
+ {
+ mpfr_rnd_t rnd;
+
+ mpfr_urandomb (x, RANDS);
+ rnd = RND_RAND ();
+ logbase = (randlimb () % 5) + 1;
+ base = 1 << logbase;
+ /* Warning: the number of bits needed to print exactly a number of
+ 'prec' bits in base 2^logbase may be greater than ceil(prec/logbase),
+ for example 0.11E-1 in base 2 cannot be written exactly with only
+ one digit in base 4 */
+ if (base == 2)
+ baseprec = prec;
+ else
+ baseprec = 1 + (prec - 2 + logbase) / logbase;
+ str = mpfr_get_str (NULL, &e, base, baseprec, x, rnd);
+ mpfr_set_str (y, str, base, rnd);
+ MPFR_EXP(y) += logbase * (e - strlen (str));
+ if (mpfr_cmp (x, y))
+ {
+ printf ("mpfr_set_str o mpfr_get_str <> id for rnd_mode=%s\n",
+ mpfr_print_rnd_mode (rnd));
+ printf ("x=");
+ mpfr_print_binary (x);
+ puts ("");
+ printf ("s=%s, exp=%d, base=%d\n", str, (int) e, base);
+ printf ("y=");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+ (*__gmp_free_func) (str, strlen (str) + 1);
+ }
+
+ for (i = 2; i <= 62; i++)
+ {
+ if (mpfr_set_str (x, "@NaN@(garbage)", i, MPFR_RNDN) != 0 ||
+ !mpfr_nan_p(x))
+ {
+ printf ("mpfr_set_str failed on @NaN@(garbage)\n");
+ exit (1);
+ }
+
+ /*
+ if (mpfr_set_str (x, "@Inf@garbage", i, MPFR_RNDN) != 0 ||
+ !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
+ {
+ printf ("mpfr_set_str failed on @Inf@garbage\n");
+ exit (1);
+ }
+
+ if (mpfr_set_str (x, "-@Inf@garbage", i, MPFR_RNDN) != 0 ||
+ !mpfr_inf_p(x) || MPFR_SIGN(x) > 0)
+ {
+ printf ("mpfr_set_str failed on -@Inf@garbage\n");
+ exit (1);
+ }
+
+ if (mpfr_set_str (x, "+@Inf@garbage", i, MPFR_RNDN) != 0 ||
+ !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
+ {
+ printf ("mpfr_set_str failed on +@Inf@garbage\n");
+ exit (1);
+ }
+ */
+
+ if (i > 16)
+ continue;
+
+ if (mpfr_set_str (x, "NaN", i, MPFR_RNDN) != 0 ||
+ !mpfr_nan_p(x))
+ {
+ printf ("mpfr_set_str failed on NaN\n");
+ exit (1);
+ }
+
+ if (mpfr_set_str (x, "Inf", i, MPFR_RNDN) != 0 ||
+ !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
+ {
+ printf ("mpfr_set_str failed on Inf\n");
+ exit (1);
+ }
+
+ if (mpfr_set_str (x, "-Inf", i, MPFR_RNDN) != 0 ||
+ !mpfr_inf_p(x) || MPFR_SIGN(x) > 0)
+ {
+ printf ("mpfr_set_str failed on -Inf\n");
+ exit (1);
+ }
+
+ if (mpfr_set_str (x, "+Inf", i, MPFR_RNDN) != 0 ||
+ !mpfr_inf_p(x) || MPFR_SIGN(x) < 0)
+ {
+ printf ("mpfr_set_str failed on +Inf\n");
+ exit (1);
+ }
+ }
+
+ /* check that mpfr_set_str works for uppercase letters too */
+ mpfr_set_prec (x, 10);
+ mpfr_set_str (x, "B", 16, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 11) != 0)
+ {
+ printf ("mpfr_set_str does not work for uppercase letters\n");
+ exit (1);
+ }
+
+ /* start of tests added by Alain Delplanque */
+
+ /* in this example an overflow can occur */
+ mpfr_set_prec (x, 64);
+ mpfr_set_prec (y, 64);
+ mpfr_set_str_binary (x, "1.0E-532");
+ mpfr_set_str (y, "0.71128279983522479470@-160", 10, MPFR_RNDU);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (2):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ /* in this example, I think there was a pb in the old function :
+ result of mpfr_set_str_old for the same number , but with more
+ precision is: 1.111111111110000000000000000111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100111000100001100000010101100111010e184
+ this result is the same as mpfr_set_str */
+ mpfr_set_prec (x, 64);
+ mpfr_set_prec (y, 64);
+ mpfr_set_str_binary (x, "1.111111111110000000000000000111111111111111111111111110000000001E184");
+ mpfr_set_str (y, "0.jo08hg31hc5mmpj5mjjmgn55p2h35g@39", 27, MPFR_RNDU);
+ /* y = 49027884868983130654865109690613178467841148597221480052 */
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (3):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ /* not exact rounding in mpfr_set_str
+ same number with more precision is : 1.111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011011111101000001101110110010101101000010100110011101110010001110e195
+ this result is the same as mpfr_set_str */
+ /* problem was : can_round was call with MPFR_RNDN round mode,
+ so can_round use an error : 1/2 * 2^err * ulp(y)
+ instead of 2^err * ulp(y)
+ I have increase err by 1 */
+ mpfr_set_prec (x, 64); /* it was round down instead of up */
+ mpfr_set_prec (y, 64);
+ mpfr_set_str_binary (x, "1.111111111111111111111111111000000000000000000000000000000000001e195");
+ mpfr_set_str (y, "0.6e23ekb6acgh96abk10b6c9f2ka16i@45", 21, MPFR_RNDU);
+ /* y = 100433627392042473064661483711179345482301462325708736552078 */
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (4):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ /* may be an error in mpfr_set_str_old
+ with more precision : 1.111111100000001111110000000000011111011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110111101010001110111011000010111001011100110110e180 */
+ mpfr_set_prec (x, 64); /* it was round down instead of up */
+ mpfr_set_prec (y, 64);
+ mpfr_set_str_binary (x, "1.111111100000001111110000000000011111011111111111111111111111111e180");
+ mpfr_set_str (y, "0.10j8j2k82ehahha56390df0a1de030@41", 23, MPFR_RNDZ);
+ /* y = 3053110535624388280648330929253842828159081875986159414 */
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (5):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 64);
+ mpfr_set_prec (y, 64);
+ mpfr_set_str (y, "0.jrchfhpp9en7hidqm9bmcofid9q3jg@39", 28, MPFR_RNDU);
+ /* y = 196159429139499688661464718784226062699788036696626429952 */
+ mpfr_set_str_binary (x, "0.1111111111111111111111111111111000000000000011100000001111100001E187");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (6):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 64);
+ mpfr_set_prec (y, 64);
+ mpfr_set_str (y, "0.h148m5ld5cf8gk1kd70b6ege92g6ba@47", 24, MPFR_RNDZ);
+ /* y = 52652933527468502324759448399183654588831274530295083078827114496 */
+ mpfr_set_str_binary (x, "0.1111111111111100000000001000000000000000000011111111111111101111E215");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (7):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ /* worst cases for rounding to nearest in double precision */
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_str (y, "5e125", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10111101000101110110011000100000101001010000000111111E418");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (8):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "69e267", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10000101101111100101101100000110010011001010011011010E894");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (9):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "623e100", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10110010000001010011000101111001110101000001111011111E342");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (10):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "3571e263", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10110001001100100010011000110000111010100000110101010E886");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (11):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "75569e-254", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10101101001000110001011011001000111000110101010110011E-827");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (12):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "920657e-23", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10101001110101001100110000101110110111101111001101100E-56");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (13):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "9210917e80", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.11101101000100011001000110100011111100110000000110010E289");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (14):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "87575437e-309", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.11110000001110011001000000110000000100000010101101100E-1000");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (15):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "245540327e122", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10001101101100010001100011110000110001100010111001011E434");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (16):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "491080654e122", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10001101101100010001100011110000110001100010111001011E435");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (17):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ mpfr_set_str (y, "83356057653e193", 10, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.10101010001001110011011011010111011100010101000011000E678");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_str (18):\n");
+ mpfr_print_binary (x);
+ puts ("");
+ mpfr_print_binary (y);
+ puts ("");
+ mpfr_clear (x);
+ mpfr_clear (y);
+ exit (1);
+ }
+
+ CHECK53(y, "83356057653e193", MPFR_RNDN, x,
+ "0.10101010001001110011011011010111011100010101000011000E678",
+ 18);
+
+ CHECK53(y, "619534293513e124", MPFR_RNDN, x,
+ "0.10001000011000010000000110000001111111110000011110001e452",
+ 19);
+
+ CHECK53(y, "3142213164987e-294", MPFR_RNDN, x,
+ "0.11101001101000000100111011111101111001010001001101111e-935",
+ 20);
+
+ CHECK53(y, "36167929443327e-159", MPFR_RNDN, x,
+ "0.11100111001110111110000101011001100110010100011111100e-483",
+ 21);
+
+ CHECK53(y, "904198236083175e-161", MPFR_RNDN, x,
+ "0.11100111001110111110000101011001100110010100011111100e-485",
+ 22);
+
+ CHECK53(y, "3743626360493413e-165", MPFR_RNDN, x,
+ "0.11000100000100011101001010111101011011011111011111001e-496",
+ 23);
+
+ CHECK53(y, "94080055902682397e-242", MPFR_RNDN, x,
+ "0.10110010010011000000111100011100111100110011011001010e-747",
+ 24);
+
+ CHECK53(y, "7e-303", MPFR_RNDD, x,
+ "0.10011001100111001000100110001110001000110111110001011e-1003",
+ 25);
+ CHECK53(y, "7e-303", MPFR_RNDU, x,
+ "0.10011001100111001000100110001110001000110111110001100e-1003",
+ 26);
+
+ CHECK53(y, "93e-234", MPFR_RNDD, x,
+ "0.10010011110110010111001001111001000010000000001110101E-770",
+ 27);
+ CHECK53(y, "93e-234", MPFR_RNDU, x,
+ "0.10010011110110010111001001111001000010000000001110110E-770",
+ 28);
+
+ CHECK53(y, "755e174", MPFR_RNDD, x,
+ "0.10111110110010011000110010011111101111000111111000101E588",
+ 29);
+ CHECK53(y, "755e174", MPFR_RNDU, x,
+ "0.10111110110010011000110010011111101111000111111000110E588",
+ 30);
+
+ CHECK53(y, "8699e-276", MPFR_RNDD, x,
+ "0.10010110100101101111100100100011011101100110100101100E-903",
+ 31);
+ CHECK53(y, "8699e-276", MPFR_RNDU, x,
+ "0.10010110100101101111100100100011011101100110100101101E-903",
+ 32);
+
+ CHECK53(y, "82081e41", MPFR_RNDD, x,
+ "0.10111000000010000010111011111001111010100011111001011E153",
+ 33);
+ CHECK53(y, "82081e41", MPFR_RNDU, x,
+ "0.10111000000010000010111011111001111010100011111001100E153",
+ 34);
+
+ CHECK53(y, "584169e229", MPFR_RNDD, x,
+ "0.11101011001010111000001011001110111000111100110101010E780",
+ 35);
+ CHECK53(y, "584169e229", MPFR_RNDU, x,
+ "0.11101011001010111000001011001110111000111100110101011E780",
+ 36);
+
+ CHECK53(y, "5783893e-128", MPFR_RNDD, x,
+ "0.10011000111100000110011110000101100111110011101110100E-402",
+ 37);
+ CHECK53(y, "5783893e-128", MPFR_RNDU, x,
+ "0.10011000111100000110011110000101100111110011101110101E-402",
+ 38);
+
+ CHECK53(y, "87575437e-310", MPFR_RNDD, x,
+ "0.11000000001011100000110011110011010000000010001010110E-1003",
+ 39);
+ CHECK53(y, "87575437e-310", MPFR_RNDU, x,
+ "0.11000000001011100000110011110011010000000010001010111E-1003",
+ 40);
+
+ CHECK53(y, "245540327e121", MPFR_RNDD, x,
+ "0.11100010101101001111010010110100011100000100101000100E430",
+ 41);
+ CHECK53(y, "245540327e121", MPFR_RNDU, x,
+ "0.11100010101101001111010010110100011100000100101000101E430",
+ 42);
+
+ CHECK53(y, "9078555839e-109", MPFR_RNDD, x,
+ "0.11111110001010111010110000110011100110001010011101101E-329",
+ 43);
+ CHECK53(y, "9078555839e-109", MPFR_RNDU, x,
+ "0.11111110001010111010110000110011100110001010011101110E-329",
+ 44);
+
+ CHECK53(y, "42333842451e201", MPFR_RNDD, x,
+ "0.10000000110001001101000100110110111110101011101011111E704",
+ 45);
+ CHECK53(y, "42333842451e201", MPFR_RNDU, x,
+ "0.10000000110001001101000100110110111110101011101100000E704",
+ 46);
+
+ CHECK53(y, "778380362293e218", MPFR_RNDD, x,
+ "0.11001101010111000001001100001100110010000001010010010E764",
+ 47);
+ CHECK53(y, "778380362293e218", MPFR_RNDU, x,
+ "0.11001101010111000001001100001100110010000001010010011E764",
+ 48);
+
+ CHECK53(y, "7812878489261e-179", MPFR_RNDD, x,
+ "0.10010011011011010111001111011101111101101101001110100E-551",
+ 49);
+ CHECK53(y, "7812878489261e-179", MPFR_RNDU, x,
+ "0.10010011011011010111001111011101111101101101001110101E-551",
+ 50);
+
+ CHECK53(y, "77003665618895e-73", MPFR_RNDD, x,
+ "0.11000101111110111111001111111101001101111000000101001E-196",
+ 51);
+ CHECK53(y, "77003665618895e-73", MPFR_RNDU, x,
+ "0.11000101111110111111001111111101001101111000000101010E-196",
+ 52);
+
+ CHECK53(y, "834735494917063e-300", MPFR_RNDD, x,
+ "0.11111110001101100001001101111100010011001110111010001E-947",
+ 53);
+ CHECK53(y, "834735494917063e-300", MPFR_RNDU, x,
+ "0.11111110001101100001001101111100010011001110111010010E-947",
+ 54);
+
+ CHECK53(y, "6182410494241627e-119", MPFR_RNDD, x,
+ "0.10001101110010110010001011000010001000101110100000111E-342",
+ 55);
+ CHECK53(y, "6182410494241627e-119", MPFR_RNDU, x,
+ "0.10001101110010110010001011000010001000101110100001000E-342",
+ 56);
+
+ CHECK53(y, "26153245263757307e49", MPFR_RNDD, x,
+ "0.10011110111100000000001011011110101100010000011011110E218",
+ 57);
+ CHECK53(y, "26153245263757307e49", MPFR_RNDU, x,
+ "0.10011110111100000000001011011110101100010000011011111E218",
+ 58);
+
+ /* to check this problem : I convert limb (10--0 or 101--1) into base b
+ with more than mp_bits_per_limb digits,
+ so when convert into base 2 I should have
+ the limb that I have choose */
+ /* this use mpfr_get_str */
+ {
+ size_t nb_digit = mp_bits_per_limb;
+ mp_limb_t check_limb[2] = {MPFR_LIMB_HIGHBIT, ~(MPFR_LIMB_HIGHBIT >> 1)};
+ int base[3] = {10, 16, 19};
+ mpfr_rnd_t rnd[3] = {MPFR_RNDU, MPFR_RNDN, MPFR_RNDD};
+ int cbase, climb, crnd;
+ char *str;
+
+ mpfr_set_prec (x, mp_bits_per_limb); /* x and y have only one limb */
+ mpfr_set_prec (y, mp_bits_per_limb);
+
+ str = (char*) (*__gmp_allocate_func) (N + 20);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN); /* ensures that x is not NaN or Inf */
+ for (; nb_digit < N; nb_digit *= 10)
+ for (cbase = 0; cbase < 3; cbase++)
+ for (climb = 0; climb < 2; climb++)
+ for (crnd = 0; crnd < 3; crnd++)
+ {
+ char *str1;
+ mpfr_exp_t exp;
+
+ *(MPFR_MANT(x)) = check_limb[climb];
+ MPFR_EXP(x) = 0;
+
+ mpfr_get_str (str + 2, &exp, base[cbase],
+ nb_digit, x, rnd[crnd]);
+ str[0] = '-';
+ str[(str[2] == '-')] = '0';
+ str[(str[2] == '-') + 1] = '.';
+
+ for (str1 = str; *str1 != 0; str1++)
+ ;
+ sprintf (str1, "@%i", (int) exp);
+
+ mpfr_set_str (y, str, base[cbase], rnd[2 - crnd]);
+
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("Error in mpfr_set_str for nb_digit=%u, base=%d, "
+ "rnd=%s:\n", (unsigned int) nb_digit, base[cbase],
+ mpfr_print_rnd_mode (rnd[crnd]));
+ printf ("instead of: ");
+ mpfr_print_binary (x);
+ puts ("");
+ printf ("return : ");
+ mpfr_print_binary (y);
+ puts ("");
+ exit (1);
+ }
+ }
+
+ (*__gmp_free_func) (str, N + 20);
+ }
+
+ /* end of tests added by Alain Delplanque */
+
+ /* check that flags are correctly cleared */
+ mpfr_set_nan (x);
+ mpfr_set_str (x, "+0.0", 10, MPFR_RNDN);
+ if (!mpfr_number_p(x) || mpfr_cmp_ui (x, 0) != 0 || mpfr_sgn (x) < 0)
+ {
+ printf ("x <- +0.0 failed after x=NaN\n");
+ exit (1);
+ }
+ mpfr_set_str (x, "-0.0", 10, MPFR_RNDN);
+ if (!mpfr_number_p(x) || mpfr_cmp_ui (x, 0) != 0 || mpfr_sgn (x) > 0)
+ {
+ printf ("x <- -0.0 failed after x=NaN\n");
+ exit (1);
+ }
+
+ /* check invalid input */
+ ret = mpfr_set_str (x, "1E10toto", 10, MPFR_RNDN);
+ MPFR_ASSERTN (ret == -1);
+ ret = mpfr_set_str (x, "1p10toto", 16, MPFR_RNDN);
+ MPFR_ASSERTN (ret == -1);
+ ret = mpfr_set_str (x, "", 16, MPFR_RNDN);
+ MPFR_ASSERTN (ret == -1);
+ ret = mpfr_set_str (x, "+", 16, MPFR_RNDN);
+ MPFR_ASSERTN (ret == -1);
+ ret = mpfr_set_str (x, "-", 16, MPFR_RNDN);
+ MPFR_ASSERTN (ret == -1);
+ ret = mpfr_set_str (x, "this_is_an_invalid_number_in_base_36", 36, MPFR_RNDN);
+ MPFR_ASSERTN (ret == -1);
+ ret = mpfr_set_str (x, "1.2.3", 10, MPFR_RNDN);
+ MPFR_ASSERTN (ret == -1);
+ mpfr_set_prec (x, 135);
+ ret = mpfr_set_str (x, "thisisavalidnumberinbase36", 36, MPFR_RNDN);
+ mpfr_set_prec (y, 135);
+ mpfr_set_str (y, "23833565676460972739462619524519814462546", 10, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp (x, y) == 0 && ret == 0);
+
+ /* coverage test for set_str_binary */
+ mpfr_set_str_binary (x, "NaN");
+ MPFR_ASSERTN(mpfr_nan_p (x));
+ mpfr_set_str_binary (x, "Inf");
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ mpfr_set_str_binary (x, "+Inf");
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ mpfr_set_str_binary (x, "-Inf");
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);
+ mpfr_set_prec (x, 3);
+ mpfr_set_str_binary (x, "0.01E2");
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);
+ mpfr_set_str_binary (x, "-0.01E2");
+ MPFR_ASSERTN(mpfr_cmp_si (x, -1) == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ check_underflow ();
+ bug20081028 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tset_z.c b/mpfr/tests/tset_z.c
new file mode 100644
index 0000000000..e1e522c4a9
--- /dev/null
+++ b/mpfr/tests/tset_z.c
@@ -0,0 +1,142 @@
+/* Test file for mpfr_set_z.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+static void check0(void)
+{
+ mpz_t y;
+ mpfr_t x;
+ int inexact, r;
+
+ /* Check for +0 */
+ mpfr_init (x);
+ mpz_init (y);
+ mpz_set_si (y, 0);
+ for(r = 0; r < MPFR_RND_MAX; r++)
+ {
+ inexact = mpfr_set_z (x, y, (mpfr_rnd_t) r);
+ if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact)
+ {
+ printf("mpfr_set_z(x,0) failed for %s\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit(1);
+ }
+ }
+ mpfr_clear(x);
+ mpz_clear(y);
+}
+
+/* FIXME: It'd be better to examine the actual data in an mpfr_t to see that
+ it's as expected. Comparing mpfr_set_z with mpfr_cmp or against
+ mpfr_get_si is a rather indirect test of a low level routine. */
+
+static void
+check (long i, mpfr_rnd_t rnd)
+{
+ mpfr_t f;
+ mpz_t z;
+
+ mpfr_init2 (f, 8 * sizeof(long));
+ mpz_init (z);
+ mpz_set_ui (z, i);
+ mpfr_set_z (f, z, rnd);
+ if (mpfr_get_si (f, MPFR_RNDZ) != i)
+ {
+ printf ("Error in mpfr_set_z for i=%ld rnd_mode=%d\n", i, rnd);
+ exit (1);
+ }
+ mpfr_clear (f);
+ mpz_clear (z);
+}
+
+static void
+check_large (void)
+{
+ mpz_t z;
+ mpfr_t x, y;
+ mpfr_exp_t emax, emin;
+
+ mpz_init (z);
+ mpfr_init2 (x, 160);
+ mpfr_init2 (y, 160);
+
+ mpz_set_str (z, "77031627725494291259359895954016675357279104942148788042", 10);
+ mpfr_set_z (x, z, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.1100100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111000001001E186");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_set_z on large input\n");
+ exit (1);
+ }
+
+ /* check overflow */
+ emax = mpfr_get_emax ();
+ set_emax (2);
+ mpz_set_str (z, "7", 10);
+ mpfr_set_z (x, z, MPFR_RNDU);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ set_emax (3);
+ mpfr_set_prec (x, 2);
+ mpz_set_str (z, "7", 10);
+ mpfr_set_z (x, z, MPFR_RNDU);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ set_emax (emax);
+
+ /* check underflow */
+ emin = mpfr_get_emin ();
+ set_emin (3);
+ mpz_set_str (z, "1", 10);
+ mpfr_set_z (x, z, MPFR_RNDZ);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
+ set_emin (2);
+ mpfr_set_z (x, z, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
+ set_emin (emin);
+
+ mpz_clear (z);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ long j;
+
+ tests_start_mpfr ();
+
+ check_large ();
+ check (0, MPFR_RNDN);
+ for (j = 0; j < 200000; j++)
+ check (randlimb () & LONG_MAX, RND_RAND ());
+ check0 ();
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tset_z_exp.c b/mpfr/tests/tset_z_exp.c
new file mode 100644
index 0000000000..7917839980
--- /dev/null
+++ b/mpfr/tests/tset_z_exp.c
@@ -0,0 +1,132 @@
+/* Test file for mpfr_set_z_2exp.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+static mpfr_exp_t
+randexp (void)
+{
+ return (mpfr_exp_t) (randlimb () % (__gmpfr_emax - __gmpfr_emin))
+ + __gmpfr_emin;
+}
+
+static void
+check0 (void)
+{
+ mpz_t y;
+ mpfr_t x;
+ int inexact, r;
+ mpfr_exp_t e;
+
+ /* Check for +0 */
+ mpfr_init (x);
+ mpz_init (y);
+ mpz_set_si (y, 0);
+ for (r = 0; r < MPFR_RND_MAX; r++)
+ {
+ e = randexp ();
+ inexact = mpfr_set_z_2exp (x, y, e, (mpfr_rnd_t) r);
+ if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact)
+ {
+ printf ("mpfr_set_z_2exp(x,0,e) failed for e=");
+ if (e < LONG_MIN)
+ printf ("(<LONG_MIN)");
+ else if (e > LONG_MAX)
+ printf ("(>LONG_MAX)");
+ else
+ printf ("%ld", (long) e);
+ printf (", rnd=%s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r));
+ exit (1);
+ }
+ }
+ mpfr_clear(x);
+ mpz_clear(y);
+}
+
+/* FIXME: It'd be better to examine the actual data in an mpfr_t to see that
+ it's as expected. Comparing mpfr_set_z with mpfr_cmp or against
+ mpfr_get_si is a rather indirect test of a low level routine. */
+
+static void
+check (long i, mpfr_rnd_t rnd)
+{
+ mpfr_t f;
+ mpz_t z;
+ mpfr_exp_t e;
+ int inex;
+
+ /* using CHAR_BIT * sizeof(long) bits of precision ensures that
+ mpfr_set_z_2exp is exact below */
+ mpfr_init2 (f, CHAR_BIT * sizeof(long));
+ mpz_init (z);
+ mpz_set_ui (z, i);
+ /* the following loop ensures that no overflow occurs */
+ do
+ e = randexp ();
+ while (e > mpfr_get_emax () - CHAR_BIT * sizeof(long));
+ inex = mpfr_set_z_2exp (f, z, e, rnd);
+ if (inex != 0)
+ {
+ printf ("Error in mpfr_set_z_2exp for i=%ld, e=%ld,"
+ " wrong ternary value\n", i, (long) e);
+ printf ("expected 0, got %d\n", inex);
+ exit (1);
+ }
+ mpfr_div_2si (f, f, e, rnd);
+ if (mpfr_get_si (f, MPFR_RNDZ) != i)
+ {
+ printf ("Error in mpfr_set_z_2exp for i=%ld e=", i);
+ if (e < LONG_MIN)
+ printf ("(<LONG_MIN)");
+ else if (e > LONG_MAX)
+ printf ("(>LONG_MAX)");
+ else
+ printf ("%ld", (long) e);
+ printf (" rnd_mode=%d\n", rnd);
+ printf ("expected %ld\n", i);
+ printf ("got "); mpfr_dump (f);
+ exit (1);
+ }
+ mpfr_clear (f);
+ mpz_clear (z);
+}
+
+int
+main (int argc, char *argv[])
+{
+ long j;
+
+ tests_start_mpfr ();
+
+ check (0, MPFR_RNDN);
+ for (j = 0; j < 200000; j++)
+ check (randlimb () & LONG_MAX, RND_RAND ());
+ check0 ();
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tsgn.c b/mpfr/tests/tsgn.c
new file mode 100644
index 0000000000..ad7967cd68
--- /dev/null
+++ b/mpfr/tests/tsgn.c
@@ -0,0 +1,131 @@
+/* tsgn -- Test for the sign of a floating point number.
+
+Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+check_special (void)
+{
+ mpfr_t x;
+ int ret = 0;
+
+ mpfr_init (x);
+ MPFR_SET_ZERO (x);
+ if ((mpfr_sgn) (x) != 0 || mpfr_sgn (x) != 0)
+ {
+ printf("Sgn error for 0.\n");
+ ret = 1;
+ }
+ MPFR_SET_INF (x);
+ MPFR_SET_POS (x);
+ if ((mpfr_sgn) (x) != 1 || mpfr_sgn (x) != 1)
+ {
+ printf("Sgn error for +Inf.\n");
+ ret = 1;
+ }
+ MPFR_SET_INF (x);
+ MPFR_SET_NEG (x);
+ if ((mpfr_sgn) (x) != -1 || mpfr_sgn (x) != -1)
+ {
+ printf("Sgn error for -Inf.\n");
+ ret = 1;
+ }
+ MPFR_SET_NAN (x);
+ mpfr_clear_flags ();
+ if ((mpfr_sgn) (x) != 0 || !mpfr_erangeflag_p ())
+ {
+ printf("Sgn error for NaN.\n");
+ ret = 1;
+ }
+ mpfr_clear_flags ();
+ if (mpfr_sgn (x) != 0 || !mpfr_erangeflag_p ())
+ {
+ printf("Sgn error for NaN.\n");
+ ret = 1;
+ }
+ mpfr_clear (x);
+ if (ret)
+ exit (ret);
+}
+
+static void
+check_sgn(void)
+{
+ mpfr_t x;
+ int i, s1, s2;
+
+ mpfr_init(x);
+ for(i = 0 ; i < 100 ; i++)
+ {
+ mpfr_urandomb (x, RANDS);
+ if (i&1)
+ {
+ MPFR_SET_POS(x);
+ s2 = 1;
+ }
+ else
+ {
+ MPFR_SET_NEG(x);
+ s2 = -1;
+ }
+ s1 = mpfr_sgn(x);
+ if (s1 < -1 || s1 > 1)
+ {
+ printf("Error for sgn: out of range.\n");
+ goto lexit;
+ }
+ else if (MPFR_IS_NAN(x) || MPFR_IS_ZERO(x))
+ {
+ if (s1 != 0)
+ {
+ printf("Error for sgn: Nan or Zero should return 0.\n");
+ goto lexit;
+ }
+ }
+ else if (s1 != s2)
+ {
+ printf("Error for sgn. Return %d instead of %d.\n", s1, s2);
+ goto lexit;
+ }
+ }
+ mpfr_clear(x);
+ return;
+
+ lexit:
+ mpfr_clear(x);
+ exit(1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_special ();
+ check_sgn ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsi_op.c b/mpfr/tests/tsi_op.c
new file mode 100644
index 0000000000..1422ca5f1f
--- /dev/null
+++ b/mpfr/tests/tsi_op.c
@@ -0,0 +1,146 @@
+/* Test file for mpfr_add_si, mpfr_sub_si, mpfr_si_sub, mpfr_mul_si,
+ mpfr_div_si, mpfr_si_div
+
+Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define ERROR1(s, i, z, exp) \
+{\
+ printf("Error for "s" and i=%d\n", i);\
+ printf("Expected %s\n", exp);\
+ printf("Got "); mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);\
+ putchar ('\n');\
+ exit(1);\
+}
+
+const struct {
+ const char * op1;
+ long int op2;
+ const char * res_add;
+ const char * res_sub;
+ const char * res_mul;
+ const char * res_div;
+} tab[] = {
+ {"10", 0x1, "11", "0F", "10", "10"},
+ {"1", -1, "0", "2", "-1", "-1"},
+ {"17.42", -0x17, "0.42", "2E.42", "-216.ee", "-1.02de9bd37a6f4"},
+ {"-1024.0", -0x16, "-103A", "-100E", "16318", "bb.d1745d1745d0"}
+};
+
+static void
+check_invert (void)
+{
+ mpfr_t x;
+ mpfr_init2 (x, MPFR_PREC_MIN);
+
+ mpfr_set_ui (x, 0xC, MPFR_RNDN);
+ mpfr_si_sub (x, -1, x, MPFR_RNDD); /* -0001 - 1100 = - 1101 --> -1 0000 */
+ if (mpfr_cmp_si (x, -0x10) )
+ {
+ printf ("Special rounding error\n");
+ exit (1);
+ }
+ mpfr_clear (x);
+}
+
+#define TEST_FUNCTION mpfr_add_si
+#define TEST_FUNCTION_NAME "mpfr_add_si"
+#define INTEGER_TYPE long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#define test_generic_ui test_generic_add_si
+#include "tgeneric_ui.c"
+
+#define TEST_FUNCTION mpfr_sub_si
+#define TEST_FUNCTION_NAME "mpfr_sub_si"
+#define INTEGER_TYPE long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#define test_generic_ui test_generic_sub_si
+#include "tgeneric_ui.c"
+
+#define TEST_FUNCTION mpfr_mul_si
+#define TEST_FUNCTION_NAME "mpfr_mul_si"
+#define INTEGER_TYPE long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#define test_generic_ui test_generic_mul_si
+#include "tgeneric_ui.c"
+
+#define TEST_FUNCTION mpfr_div_si
+#define TEST_FUNCTION_NAME "mpfr_div_si"
+#define INTEGER_TYPE long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#define test_generic_ui test_generic_div_si
+#include "tgeneric_ui.c"
+
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, z;
+ int y;
+ int i;
+
+ tests_start_mpfr ();
+ mpfr_inits2 (53, x, z, (mpfr_ptr) 0);
+ for(i = 0 ; i < numberof (tab) ; i++)
+ {
+ mpfr_set_str (x, tab[i].op1, 16, MPFR_RNDN);
+ y = tab[i].op2;
+ mpfr_add_si (z, x, y, MPFR_RNDZ);
+ if (mpfr_cmp_str (z, tab[i].res_add, 16, MPFR_RNDN))
+ ERROR1("add_si", i, z, tab[i].res_add);
+ mpfr_sub_si (z, x, y, MPFR_RNDZ);
+ if (mpfr_cmp_str (z, tab[i].res_sub, 16, MPFR_RNDN))
+ ERROR1("sub_si", i, z, tab[i].res_sub);
+ mpfr_si_sub (z, y, x, MPFR_RNDZ);
+ mpfr_neg (z, z, MPFR_RNDZ);
+ if (mpfr_cmp_str (z, tab[i].res_sub, 16, MPFR_RNDN))
+ ERROR1("si_sub", i, z, tab[i].res_sub);
+ mpfr_mul_si (z, x, y, MPFR_RNDZ);
+ if (mpfr_cmp_str (z, tab[i].res_mul, 16, MPFR_RNDN))
+ ERROR1("mul_si", i, z, tab[i].res_mul);
+ mpfr_div_si (z, x, y, MPFR_RNDZ);
+ if (mpfr_cmp_str (z, tab[i].res_div, 16, MPFR_RNDN))
+ ERROR1("div_si", i, z, tab[i].res_div);
+ }
+ mpfr_set_str1 (x, "1");
+ mpfr_si_div (z, 1024, x, MPFR_RNDN);
+ if (mpfr_cmp_str1 (z, "1024"))
+ ERROR1("si_div", i, z, "1024");
+ mpfr_si_div (z, -1024, x, MPFR_RNDN);
+ if (mpfr_cmp_str1 (z, "-1024"))
+ ERROR1("si_div", i, z, "-1024");
+
+ mpfr_clears (x, z, (mpfr_ptr) 0);
+
+ check_invert ();
+
+ test_generic_add_si (2, 200, 17);
+ test_generic_sub_si (2, 200, 17);
+ test_generic_mul_si (2, 200, 17);
+ test_generic_div_si (2, 200, 17);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsin.c b/mpfr/tests/tsin.c
new file mode 100644
index 0000000000..b8a20cd09e
--- /dev/null
+++ b/mpfr/tests/tsin.c
@@ -0,0 +1,377 @@
+/* Test file for mpfr_sin.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_sin (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ }
+ res = mpfr_sin (a, b, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_sin mpfr_sin
+#endif
+
+static void
+check53 (const char *xs, const char *sin_xs, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xx, s;
+
+ mpfr_init2 (xx, 53);
+ mpfr_init2 (s, 53);
+ mpfr_set_str1 (xx, xs); /* should be exact */
+ test_sin (s, xx, rnd_mode);
+ if (mpfr_cmp_str1 (s, sin_xs))
+ {
+ printf ("mpfr_sin failed for x=%s, rnd=%s\n",
+ xs, mpfr_print_rnd_mode (rnd_mode));
+ printf ("mpfr_sin gives sin(x)=");
+ mpfr_out_str (stdout, 10, 0, s, MPFR_RNDN);
+ printf (", expected %s\n", sin_xs);
+ exit (1);
+ }
+ mpfr_clear (xx);
+ mpfr_clear (s);
+}
+
+static void
+check53b (const char *xs, const char *sin_xs, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xx, s;
+
+ mpfr_init2 (xx, 53);
+ mpfr_init2 (s, 53);
+ mpfr_set_str (xx, xs, 2, MPFR_RNDN); /* should be exact */
+ test_sin (s, xx, rnd_mode);
+ if (mpfr_cmp_str (s, sin_xs, 2, MPFR_RNDN))
+ {
+ printf ("mpfr_sin failed in rounding mode %s for\n x = %s\n",
+ mpfr_print_rnd_mode (rnd_mode), xs);
+ printf (" got ");
+ mpfr_out_str (stdout, 2, 0, s, MPFR_RNDN);
+ printf ("\nexpected %s\n", sin_xs);
+ exit (1);
+ }
+ mpfr_clear (xx);
+ mpfr_clear (s);
+}
+
+static void
+test_sign (void)
+{
+ mpfr_t pid, piu, x, y;
+ int p, k;
+
+ mpfr_init2 (pid, 4096);
+ mpfr_const_pi (pid, MPFR_RNDD);
+ mpfr_init2 (piu, 4096);
+ mpfr_const_pi (piu, MPFR_RNDU);
+ mpfr_init (x);
+ mpfr_init2 (y, 2);
+ for (p = 8; p <= 128; p++)
+ for (k = 2; k <= 6; k += 2)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_mul_ui (x, pid, k, MPFR_RNDD);
+ test_sin (y, x, MPFR_RNDN);
+ if (MPFR_SIGN(y) > 0)
+ {
+ printf ("Error in test_sign for sin(%dpi-epsilon), prec = %d"
+ " for argument.\nResult should have been negative.\n",
+ k, p);
+ exit (1);
+ }
+ mpfr_mul_ui (x, piu, k, MPFR_RNDU);
+ test_sin (y, x, MPFR_RNDN);
+ if (MPFR_SIGN(y) < 0)
+ {
+ printf ("Error in test_sign for sin(%dpi+epsilon), prec = %d"
+ " for argument.\nResult should have been positive.\n",
+ k, p);
+ exit (1);
+ }
+ }
+
+ /* worst case on 53 bits */
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str (x, "6134899525417045", 10, MPFR_RNDN);
+ test_sin (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "11011010111101011110111100010101010101110000000001011E-106");
+ MPFR_ASSERTN(mpfr_cmp (x, y) == 0);
+
+ /* Bug on Special cases */
+ mpfr_set_str_binary (x, "0.100011011010111101E-32");
+ test_sin (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "0.10001101101011110100000000000000000000000000000000000E-32", 2, MPFR_RNDN))
+ {
+ printf("sin special 97 error:\nx=");
+ mpfr_dump (x); printf("y=");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "1.1001001000011111101101010100010001000010110100010011");
+ mpfr_set_str_binary (y, "1.1111111111111111111111111111111111111111111111111111e-1");
+ test_sin (x, x, MPFR_RNDZ);
+ MPFR_ASSERTN(mpfr_cmp (x, y) == 0);
+
+ mpfr_clear (pid);
+ mpfr_clear (piu);
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ test_sin (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: sin(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ test_sin (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: sin(Inf) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ test_sin (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: sin(-Inf) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION test_sin
+#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
+#include "tgeneric.c"
+
+const char xs[] = "0.111011111110110000111000001100000111110E-1";
+
+static void
+check_regression (void)
+{
+ mpfr_t x, y;
+ mpfr_prec_t p;
+ int i;
+
+ p = strlen (xs) - 2 - 3;
+ mpfr_inits2 (p, x, y, (mpfr_ptr) 0);
+
+ mpfr_set_str (x, xs, 2, MPFR_RNDN);
+ i = mpfr_sin (y, x, MPFR_RNDN);
+ if (i >= 0
+ || mpfr_cmp_str (y, "0.111001110011110011110001010110011101110E-1",
+ 2, MPFR_RNDN))
+ {
+ printf ("Regression test failed (1) i=%d\ny=", i);
+ mpfr_dump (y);
+ exit (1);
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+/* Test provided by Christopher Creutzig, 2007-05-21. */
+static void
+check_tiny (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_exp (x, mpfr_get_emin ());
+ mpfr_sin (y, x, MPFR_RNDD);
+ if (mpfr_cmp (x, y) < 0)
+ {
+ printf ("Error in check_tiny: got sin(x) > x for x = 2^(emin-1)\n");
+ exit (1);
+ }
+
+ mpfr_sin (y, x, MPFR_RNDU);
+ mpfr_mul_2ui (y, y, 1, MPFR_RNDU);
+ if (mpfr_cmp (x, y) > 0)
+ {
+ printf ("Error in check_tiny: got sin(x) < x/2 for x = 2^(emin-1)\n");
+ exit (1);
+ }
+
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_sin (y, x, MPFR_RNDU);
+ if (mpfr_cmp (x, y) > 0)
+ {
+ printf ("Error in check_tiny: got sin(x) < x for x = -2^(emin-1)\n");
+ exit (1);
+ }
+
+ mpfr_sin (y, x, MPFR_RNDD);
+ mpfr_mul_2ui (y, y, 1, MPFR_RNDD);
+ if (mpfr_cmp (x, y) < 0)
+ {
+ printf ("Error in check_tiny: got sin(x) > x/2 for x = -2^(emin-1)\n");
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, c, s, c2, s2;
+
+ tests_start_mpfr ();
+
+ check_regression ();
+ check_nans ();
+
+ /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */
+ check53 ("4.984987858808754279e-1", "4.781075595393330379e-1", MPFR_RNDN);
+ check53 ("4.984987858808754279e-1", "4.781075595393329824e-1", MPFR_RNDD);
+ check53 ("4.984987858808754279e-1", "4.781075595393329824e-1", MPFR_RNDZ);
+ check53 ("4.984987858808754279e-1", "4.781075595393330379e-1", MPFR_RNDU);
+ check53 ("1.00031274099908640274", "8.416399183372403892e-1", MPFR_RNDN);
+ check53 ("1.00229256850978698523", "8.427074524447979442e-1", MPFR_RNDZ);
+ check53 ("1.00288304857059840103", "8.430252033025980029e-1", MPFR_RNDZ);
+ check53 ("1.00591265847407274059", "8.446508805292128885e-1", MPFR_RNDN);
+
+ /* Other worst cases showing a bug introduced on 2005-01-29 in rev 3248 */
+ check53b ("1.0111001111010111010111111000010011010001110001111011e-21",
+ "1.0111001111010111010111111000010011010001101001110001e-21",
+ MPFR_RNDU);
+ check53b ("1.1011101111111010000001010111000010000111100100101101",
+ "1.1111100100101100001111100000110011110011010001010101e-1",
+ MPFR_RNDU);
+
+ mpfr_init2 (x, 2);
+
+ mpfr_set_str (x, "0.5", 10, MPFR_RNDN);
+ test_sin (x, x, MPFR_RNDD);
+ if (mpfr_cmp_ui_2exp (x, 3, -3)) /* x != 0.375 = 3/8 */
+ {
+ printf ("mpfr_sin(0.5, MPFR_RNDD) failed with precision=2\n");
+ exit (1);
+ }
+
+ /* bug found by Kevin Ryde */
+ mpfr_const_pi (x, MPFR_RNDN);
+ mpfr_mul_ui (x, x, 3L, MPFR_RNDN);
+ mpfr_div_ui (x, x, 2L, MPFR_RNDN);
+ test_sin (x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0) >= 0)
+ {
+ printf ("Error: wrong sign for sin(3*Pi/2)\n");
+ exit (1);
+ }
+
+ /* Can fail on an assert */
+ mpfr_set_prec (x, 53);
+ mpfr_set_str (x, "77291789194529019661184401408", 10, MPFR_RNDN);
+ mpfr_init2 (c, 4); mpfr_init2 (s, 42);
+ mpfr_init2 (c2, 4); mpfr_init2 (s2, 42);
+
+ test_sin (s, x, MPFR_RNDN);
+ mpfr_cos (c, x, MPFR_RNDN);
+ mpfr_sin_cos (s2, c2, x, MPFR_RNDN);
+ if (mpfr_cmp (c2, c))
+ {
+ printf("cos differs for x=77291789194529019661184401408");
+ exit (1);
+ }
+ if (mpfr_cmp (s2, s))
+ {
+ printf("sin differs for x=77291789194529019661184401408");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (x, "1.1001001000011111101101010100010001000010110100010011");
+ test_sin (x, x, MPFR_RNDZ);
+ if (mpfr_cmp_str (x, "1.1111111111111111111111111111111111111111111111111111e-1", 2, MPFR_RNDN))
+ {
+ printf ("Error for x= 1.1001001000011111101101010100010001000010110100010011\nGot ");
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_prec (s, 9);
+ mpfr_set_prec (x, 190);
+ mpfr_const_pi (x, MPFR_RNDN);
+ mpfr_sin (s, x, MPFR_RNDZ);
+ if (mpfr_cmp_str (s, "0.100000101e-196", 2, MPFR_RNDN))
+ {
+ printf ("Error for x ~= pi\n");
+ mpfr_dump (s);
+ exit (1);
+ }
+
+ mpfr_clear (s2);
+ mpfr_clear (c2);
+ mpfr_clear (s);
+ mpfr_clear (c);
+ mpfr_clear (x);
+
+ test_generic (2, 100, 15);
+ test_sign ();
+ check_tiny ();
+
+ data_check ("data/sin", mpfr_sin, "mpfr_sin");
+ bad_cases (mpfr_sin, mpfr_asin, "mpfr_sin", 256, -40, 0, 4, 128, 800, 50);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsin_cos.c b/mpfr/tests/tsin_cos.c
new file mode 100644
index 0000000000..380a333181
--- /dev/null
+++ b/mpfr/tests/tsin_cos.c
@@ -0,0 +1,725 @@
+/* Test file for mpfr_sin_cos.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+large_test (char *X, int prec, int N)
+{
+ int i;
+ mpfr_t x, s, c;
+
+ mpfr_init2 (x, prec);
+ mpfr_init2 (s, prec);
+ mpfr_init2 (c, prec);
+ mpfr_set_str (x, X, 10, MPFR_RNDN);
+
+ for (i = 0; i < N; i++)
+ mpfr_sin_cos (s, c, x, MPFR_RNDN);
+
+ mpfr_clear (x);
+ mpfr_clear (s);
+ mpfr_clear (c);
+}
+
+static void
+check53 (const char *xs, const char *sin_xs, const char *cos_xs,
+ mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xx, s, c;
+
+ mpfr_inits2 (53, xx, s, c, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs); /* should be exact */
+ mpfr_sin_cos (s, c, xx, rnd_mode);
+ if (mpfr_cmp_str1 (s, sin_xs))
+ {
+ printf ("mpfr_sin_cos failed for x=%s, rnd=%s\n",
+ xs, mpfr_print_rnd_mode (rnd_mode));
+ printf ("mpfr_sin_cos gives sin(x)=");
+ mpfr_out_str(stdout, 10, 0, s, MPFR_RNDN);
+ printf(", expected %s\n", sin_xs);
+ exit (1);
+ }
+ if (mpfr_cmp_str1 (c, cos_xs))
+ {
+ printf ("mpfr_sin_cos failed for x=%s, rnd=%s\n",
+ xs, mpfr_print_rnd_mode (rnd_mode));
+ printf ("mpfr_sin_cos gives cos(x)=");
+ mpfr_out_str(stdout, 10, 0, c, MPFR_RNDN);
+ printf(", expected %s\n", cos_xs);
+ exit (1);
+ }
+ mpfr_clears (xx, s, c, (mpfr_ptr) 0);
+}
+
+static void
+check53sin (const char *xs, const char *sin_xs, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xx, s, c;
+
+ mpfr_inits2 (53, xx, s, c, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs); /* should be exact */
+ mpfr_sin_cos (s, c, xx, rnd_mode);
+ if (mpfr_cmp_str1 (s, sin_xs))
+ {
+ printf ("mpfr_sin_cos failed for x=%s, rnd=%s\n",
+ xs, mpfr_print_rnd_mode (rnd_mode));
+ printf ("mpfr_sin_cos gives sin(x)=");
+ mpfr_out_str(stdout, 10, 0, s, MPFR_RNDN);
+ printf(", expected %s\n", sin_xs);
+ exit (1);
+ }
+ mpfr_clears (xx, s, c, (mpfr_ptr) 0);
+}
+
+static void
+check53cos (const char *xs, const char *cos_xs, mpfr_rnd_t rnd_mode)
+{
+ mpfr_t xx, c, s;
+
+ mpfr_inits2 (53, xx, s, c, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs); /* should be exact */
+ mpfr_sin_cos (s, c, xx, rnd_mode);
+ if (mpfr_cmp_str1 (c, cos_xs))
+ {
+ printf ("mpfr_sin_cos failed for x=%s, rnd=%s\n",
+ xs, mpfr_print_rnd_mode (rnd_mode));
+ printf ("mpfr_sin_cos gives cos(x)=");
+ mpfr_out_str(stdout, 10, 0, c, MPFR_RNDN);
+ printf(", expected %s\n", cos_xs);
+ exit (1);
+ }
+ mpfr_clears (xx, s, c, (mpfr_ptr) 0);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t x, s, c;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (s, 123L);
+ mpfr_init2 (c, 123L);
+
+ /* sin(NaN)==NaN, cos(NaN)==NaN */
+ mpfr_set_nan (x);
+ mpfr_sin_cos (s, c, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (s));
+ MPFR_ASSERTN (mpfr_nan_p (c));
+
+ /* sin(+Inf)==NaN, cos(+Inf)==NaN */
+ mpfr_set_inf (x, 1);
+ mpfr_sin_cos (s, c, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (s));
+ MPFR_ASSERTN (mpfr_nan_p (c));
+
+ /* sin(-Inf)==NaN, cos(-Inf)==NaN */
+ mpfr_set_inf (x, -1);
+ mpfr_sin_cos (s, c, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (s));
+ MPFR_ASSERTN (mpfr_nan_p (c));
+
+ /* check zero */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_sin_cos (s, c, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (s, 0) == 0 && MPFR_IS_POS (s));
+ MPFR_ASSERTN (mpfr_cmp_ui (c, 1) == 0);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_sin_cos (s, c, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_ui (s, 0) == 0 && MPFR_IS_NEG (s));
+ MPFR_ASSERTN (mpfr_cmp_ui (c, 1) == 0);
+
+ /* coverage test */
+ mpfr_set_prec (x, 2);
+ mpfr_set_ui (x, 4, MPFR_RNDN);
+ mpfr_set_prec (s, 2);
+ mpfr_set_prec (c, 2);
+ mpfr_sin_cos (s, c, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_cmp_si_2exp (s, -3, -2) == 0);
+ MPFR_ASSERTN (mpfr_cmp_si_2exp (c, -3, -2) == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (s);
+ mpfr_clear (c);
+}
+
+static void
+overflowed_sin_cos0 (void)
+{
+ mpfr_t x, y, z;
+ int emax, inex, rnd, err = 0;
+ mpfr_exp_t old_emax;
+
+ old_emax = mpfr_get_emax ();
+
+ mpfr_init2 (x, 8);
+ mpfr_init2 (y, 8);
+ mpfr_init2 (z, 8);
+
+ for (emax = -1; emax <= 0; emax++)
+ {
+ mpfr_set_ui_2exp (z, 1, emax, MPFR_RNDN);
+ mpfr_nextbelow (z);
+ set_emax (emax); /* 1 is not representable. */
+ /* and if emax < 0, 1 - eps is not representable either. */
+ RND_LOOP (rnd)
+ {
+ mpfr_set_si (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_clear_flags ();
+ inex = mpfr_sin_cos (x, y, x, (mpfr_rnd_t) rnd);
+ if (! mpfr_overflow_p ())
+ {
+ printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
+ " The overflow flag is not set.\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! (mpfr_zero_p (x) && MPFR_SIGN (x) < 0))
+ {
+ printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
+ " Got sin = ", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (x);
+ printf (" instead of -0.\n");
+ err = 1;
+ }
+ if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ {
+ if (inex == 0)
+ {
+ printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
+ " The inexact value must be non-zero.\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! mpfr_equal_p (y, z))
+ {
+ printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
+ " Got cos = ",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (y);
+ printf (" instead of 0.11111111E%d.\n", emax);
+ err = 1;
+ }
+ }
+ else
+ {
+ if (inex == 0)
+ {
+ printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
+ " The inexact value must be non-zero.\n",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ err = 1;
+ }
+ if (! (mpfr_inf_p (y) && MPFR_SIGN (y) > 0))
+ {
+ printf ("Error in overflowed_sin_cos0 (rnd = %s):\n"
+ " Got cos = ",
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ mpfr_print_binary (y);
+ printf (" instead of +Inf.\n");
+ err = 1;
+ }
+ }
+ }
+ set_emax (old_emax);
+ }
+
+ if (err)
+ exit (1);
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+tiny (void)
+{
+ mpfr_t x, s, c;
+ int i, inex;
+
+ mpfr_inits2 (64, x, s, c, (mpfr_ptr) 0);
+
+ for (i = -1; i <= 1; i += 2)
+ {
+ mpfr_set_si (x, i, MPFR_RNDN);
+ mpfr_set_exp (x, mpfr_get_emin ());
+ inex = mpfr_sin_cos (s, c, x, MPFR_RNDN);
+ MPFR_ASSERTN (inex != 0);
+ MPFR_ASSERTN (mpfr_equal_p (s, x));
+ MPFR_ASSERTN (!mpfr_nan_p (c) && mpfr_cmp_ui (c, 1) == 0);
+ }
+
+ mpfr_clears (x, s, c, (mpfr_ptr) 0);
+}
+
+/* bug found in nightly tests */
+static void
+test20071214 (void)
+{
+ mpfr_t a, b;
+ int inex;
+
+ mpfr_init2 (a, 4);
+ mpfr_init2 (b, 4);
+
+ mpfr_set_ui_2exp (a, 3, -4, MPFR_RNDN);
+ inex = mpfr_sin_cos (a, b, a, MPFR_RNDD);
+ MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 11, -6) == 0);
+ MPFR_ASSERTN(mpfr_cmp_ui_2exp (b, 15, -4) == 0);
+ MPFR_ASSERTN(inex == 10);
+
+ mpfr_set_ui_2exp (a, 3, -4, MPFR_RNDN);
+ inex = mpfr_sin_cos (a, b, a, MPFR_RNDU);
+ MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 3, -4) == 0);
+ MPFR_ASSERTN(mpfr_cmp_ui (b, 1) == 0);
+ MPFR_ASSERTN(inex == 5);
+
+ mpfr_set_ui_2exp (a, 3, -4, MPFR_RNDN);
+ inex = mpfr_sin_cos (a, b, a, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 3, -4) == 0);
+ MPFR_ASSERTN(mpfr_cmp_ui (b, 1) == 0);
+ MPFR_ASSERTN(inex == 5);
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+}
+
+/* check that mpfr_sin_cos and test_mpfr_sincos_fast agree */
+static void
+test_mpfr_sincos_fast (void)
+{
+ mpfr_t x, y, z, yref, zref, h;
+ mpfr_prec_t p = 1000;
+ int i, inex, inexref;
+ mpfr_rnd_t r;
+
+ mpfr_init2 (x, p);
+ mpfr_init2 (y, p);
+ mpfr_init2 (z, p);
+ mpfr_init2 (yref, p);
+ mpfr_init2 (zref, p);
+ mpfr_init2 (h, p);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ /* we generate a random value x, compute sin(x) and cos(x) with both
+ mpfr_sin_cos and mpfr_sincos_fast, and check the values and the flags
+ agree */
+ for (i = 0; i < 100; i++)
+ {
+ mpfr_urandomb (h, RANDS);
+ mpfr_add (x, x, h, MPFR_RNDN);
+ r = RND_RAND ();
+ inexref = mpfr_sin_cos (yref, zref, x, r);
+ inex = mpfr_sincos_fast (y, z, x, r);
+ if (mpfr_cmp (y, yref))
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n");
+ printf ("x="); mpfr_dump (x);
+ printf ("rnd=%s\n", mpfr_print_rnd_mode (r));
+ printf ("yref="); mpfr_dump (yref);
+ printf ("y="); mpfr_dump (y);
+ exit (1);
+ }
+ if (mpfr_cmp (z, zref))
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n");
+ printf ("x="); mpfr_dump (x);
+ printf ("rnd=%s\n", mpfr_print_rnd_mode (r));
+ printf ("zref="); mpfr_dump (zref);
+ printf ("z="); mpfr_dump (z);
+ exit (1);
+ }
+ if (inex != inexref)
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree\n");
+ printf ("x="); mpfr_dump (x);
+ printf ("rnd=%s\n", mpfr_print_rnd_mode (r));
+ printf ("inexref=%d inex=%d\n", inexref, inex);
+ exit (1);
+ }
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (yref);
+ mpfr_clear (zref);
+ mpfr_clear (h);
+}
+
+static void
+bug20091007 (void)
+{
+ mpfr_t x, y, z, yref, zref;
+ mpfr_prec_t p = 1000;
+ int inex, inexref;
+ mpfr_rnd_t r = MPFR_RNDZ;
+
+ mpfr_init2 (x, p);
+ mpfr_init2 (y, p);
+ mpfr_init2 (z, p);
+ mpfr_init2 (yref, p);
+ mpfr_init2 (zref, p);
+
+ mpfr_set_str (x, "1.9ecdc22ba77a5ab2560f7e84289e2a328906f47377ea3fd4c82d1bb2f13ee05c032cffc1933eadab7b0a5498e03e3bd0508968e59c25829d97a0b54f20cd4662c8dfffa54e714de41fc8ee3e0e0b244d110a194db05b70022b7d77f88955d415b09f17dd404576098dc51a583a3e49c35839551646e880c7eb790a01a4@1", 16, MPFR_RNDN);
+ inexref = mpfr_sin_cos (yref, zref, x, r);
+ inex = mpfr_sincos_fast (y, z, x, r);
+
+ if (mpfr_cmp (y, yref))
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091007)\n");
+ printf ("yref="); mpfr_dump (yref);
+ printf ("y="); mpfr_dump (y);
+ exit (1);
+ }
+ if (mpfr_cmp (z, zref))
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091007)\n");
+ printf ("zref="); mpfr_dump (zref);
+ printf ("z="); mpfr_dump (z);
+ exit (1);
+ }
+ if (inex != inexref)
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091007)\n");
+ printf ("inexref=%d inex=%d\n", inexref, inex);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (yref);
+ mpfr_clear (zref);
+}
+
+/* Note: with the sin_cos.c code before r6507, the disagreement occurs
+ only on the return ("inexact") value, which is new in r6444. */
+static void
+bug20091008 (void)
+{
+ mpfr_t x, y, z, yref, zref;
+ mpfr_prec_t p = 1000;
+ int inex, inexref;
+ mpfr_rnd_t r = MPFR_RNDN;
+
+ mpfr_init2 (x, p);
+ mpfr_init2 (y, p);
+ mpfr_init2 (z, p);
+ mpfr_init2 (yref, p);
+ mpfr_init2 (zref, p);
+
+ mpfr_set_str (x, "c.91813724e28ef6a711d33e6505984699daef7fe93636c1ed5d0168bc96989cc6802f7f9e405c902ec62fb90cd39c9d21084c8ad8b5af4c4aa87bf402e2e4a78e6fe1ffeb6dbbbdbbc2983c196c518966ccc1e094ed39ee77984ef2428069d65de37928e75247edbe7007245e682616b5ebbf05f2fdefc74ad192024f10", 16, MPFR_RNDN);
+ inexref = mpfr_sin_cos (yref, zref, x, r);
+ inex = mpfr_sincos_fast (y, z, x, r);
+
+ if (mpfr_cmp (y, yref))
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091008)\n");
+ printf ("yref="); mpfr_dump (yref);
+ printf ("y="); mpfr_dump (y);
+ exit (1);
+ }
+ if (mpfr_cmp (z, zref))
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091008)\n");
+ printf ("zref="); mpfr_dump (zref);
+ printf ("z="); mpfr_dump (z);
+ exit (1);
+ }
+ /* sin(x) is rounded up, cos(x) is rounded up too, thus we should get 5
+ for the return value */
+ if (inex != inexref)
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091008)\n");
+ printf ("inexref=%d inex=%d (5 expected)\n", inexref, inex);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (yref);
+ mpfr_clear (zref);
+}
+
+static void
+bug20091013 (void)
+{
+ mpfr_t x, y, z, yref, zref;
+ mpfr_prec_t p = 1000;
+ int inex, inexref;
+ mpfr_rnd_t r = MPFR_RNDN;
+
+ mpfr_init2 (x, p);
+ mpfr_init2 (y, p);
+ mpfr_init2 (z, p);
+ mpfr_init2 (yref, p);
+ mpfr_init2 (zref, p);
+
+ mpfr_set_str (x, "3.240ff3fdcb1ee7cd667b96287593ae24e20fb63ed7c2d5bf4bd0f2cc5509283b04e7628e66382605f14ed5967cef15296041539a1bdaa626c777c7fbb6f2068414759b78cee14f37848689b3a170f583656be4e0837f464d8210556a3a822d4ecfdd59f4e0d5fdb76bf7e15b8a57234e2160b98e14c17bbdf27c4643b8@1", 16, MPFR_RNDN);
+ inexref = mpfr_sin_cos (yref, zref, x, r);
+ inex = mpfr_sincos_fast (y, z, x, r);
+
+ if (mpfr_cmp (y, yref))
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091013)\n");
+ printf ("yref="); mpfr_dump (yref);
+ printf ("y="); mpfr_dump (y);
+ exit (1);
+ }
+ if (mpfr_cmp (z, zref))
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091013)\n");
+ printf ("zref="); mpfr_dump (zref);
+ printf ("z="); mpfr_dump (z);
+ exit (1);
+ }
+ /* sin(x) is rounded down and cos(x) is rounded down, thus we should get
+ 2+4*2 = 10 as return value */
+ if (inex != inexref)
+ {
+ printf ("mpfr_sin_cos and mpfr_sincos_fast disagree (bug20091013)\n");
+ printf ("inexref=%d inex=%d (10 expected)\n", inexref, inex);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (yref);
+ mpfr_clear (zref);
+}
+
+/* Bug reported by Laurent Fousse for the 2.4 branch.
+ No problem in the trunk.
+ https://sympa.inria.fr/sympa/arc/mpfr/2009-11/msg00044.html */
+static void
+bug20091122 (void)
+{
+ mpfr_t x, y, z, yref, zref;
+ mpfr_prec_t p = 3;
+ mpfr_rnd_t r = MPFR_RNDN;
+
+ mpfr_init2 (x, 5);
+ mpfr_init2 (y, p);
+ mpfr_init2 (z, p);
+ mpfr_init2 (yref, p);
+ mpfr_init2 (zref, p);
+
+ mpfr_set_str (x, "0.11111E49", 2, MPFR_RNDN);
+ mpfr_sin_cos (yref, zref, x, r);
+
+ mpfr_sin (y, x, r);
+ mpfr_cos (z, x, r);
+
+ if (! mpfr_equal_p (y, yref))
+ {
+ printf ("mpfr_sin_cos and mpfr_sin disagree (bug20091122)\n");
+ printf ("yref = "); mpfr_dump (yref);
+ printf ("y = "); mpfr_dump (y);
+ exit (1);
+ }
+ if (! mpfr_equal_p (z, zref))
+ {
+ printf ("mpfr_sin_cos and mpfr_cos disagree (bug20091122)\n");
+ printf ("zref = "); mpfr_dump (zref);
+ printf ("z = "); mpfr_dump (z);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (yref);
+ mpfr_clear (zref);
+}
+
+static void
+consistency (void)
+{
+ mpfr_t x, s1, s2, c1, c2;
+ mpfr_exp_t emin, emax;
+ mpfr_rnd_t rnd;
+ unsigned int flags_sin, flags_cos, flags, flags_before, flags_ref;
+ int inex_sin, is, inex_cos, ic, inex, inex_ref;
+ int i;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ for (i = 0; i <= 10000; i++)
+ {
+ mpfr_init2 (x, MPFR_PREC_MIN + (randlimb () % 8));
+ mpfr_inits2 (MPFR_PREC_MIN + (randlimb () % 8), s1, s2, c1, c2,
+ (mpfr_ptr) 0);
+ if (i < 8 * MPFR_RND_MAX)
+ {
+ int j = i / MPFR_RND_MAX;
+ if (j & 1)
+ mpfr_set_emin (MPFR_EMIN_MIN);
+ mpfr_set_si (x, (j & 2) ? 1 : -1, MPFR_RNDN);
+ mpfr_set_exp (x, mpfr_get_emin ());
+ rnd = (mpfr_rnd_t) (i % MPFR_RND_MAX);
+ flags_before = 0;
+ if (j & 4)
+ mpfr_set_emax (-17);
+ }
+ else
+ {
+ tests_default_random (x, 256, -5, 50);
+ rnd = RND_RAND ();
+ flags_before = (randlimb () & 1) ?
+ (unsigned int) (MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE) :
+ (unsigned int) 0;
+ }
+ __gmpfr_flags = flags_before;
+ inex_sin = mpfr_sin (s1, x, rnd);
+ is = inex_sin < 0 ? 2 : inex_sin > 0 ? 1 : 0;
+ flags_sin = __gmpfr_flags;
+ __gmpfr_flags = flags_before;
+ inex_cos = mpfr_cos (c1, x, rnd);
+ ic = inex_cos < 0 ? 2 : inex_cos > 0 ? 1 : 0;
+ flags_cos = __gmpfr_flags;
+ __gmpfr_flags = flags_before;
+ inex = mpfr_sin_cos (s2, c2, x, rnd);
+ flags = __gmpfr_flags;
+ inex_ref = is + 4 * ic;
+ flags_ref = flags_sin | flags_cos;
+ if (!(mpfr_equal_p (s1, s2) && mpfr_equal_p (c1, c2)) ||
+ inex != inex_ref || flags != flags_ref)
+ {
+ printf ("mpfr_sin_cos and mpfr_sin/mpfr_cos disagree on %s,"
+ " i = %d\nx = ", mpfr_print_rnd_mode (rnd), i);
+ mpfr_dump (x);
+ printf ("s1 = ");
+ mpfr_dump (s1);
+ printf ("s2 = ");
+ mpfr_dump (s2);
+ printf ("c1 = ");
+ mpfr_dump (c1);
+ printf ("c2 = ");
+ mpfr_dump (c2);
+ printf ("inex_sin = %d (s = %d), inex_cos = %d (c = %d), "
+ "inex = %d (expected %d)\n",
+ inex_sin, is, inex_cos, ic, inex, inex_ref);
+ printf ("flags_sin = 0x%x, flags_cos = 0x%x, "
+ "flags = 0x%x (expected 0x%x)\n",
+ flags_sin, flags_cos, flags, flags_ref);
+ exit (1);
+ }
+ mpfr_clears (x, s1, s2, c1, c2, (mpfr_ptr) 0);
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+ }
+}
+
+static void
+coverage_01032011 (void)
+{
+ mpfr_t val, cval, sval, svalf;
+ int status_f, status;
+
+ mpfr_init2 (val, MPFR_PREC_MIN);
+ mpfr_init2 (cval, MPFR_PREC_MIN);
+ mpfr_init2 (sval, MPFR_PREC_MIN);
+ mpfr_init2 (svalf, MPFR_PREC_MIN);
+
+ mpfr_set_str1 (val, "-0.7");
+
+ status_f = mpfr_sincos_fast (svalf, NULL, val, MPFR_RNDN);
+ status = mpfr_sin_cos (sval, cval, val, MPFR_RNDN);
+ if (! mpfr_equal_p (svalf, sval) || SIGN (status_f) != SIGN (status))
+ {
+ printf ("mpfr_sincos_fast differ from mpfr_sin_cos result:\n"
+ " sin fast is ");
+ mpfr_dump (svalf);
+ printf (" sin is ");
+ mpfr_dump (sval);
+ printf ("status_f = %d, status = %d\n", status_f, status);
+ exit (1);
+ }
+
+ mpfr_clears(val, cval, sval, svalf, (mpfr_ptr) 0);
+}
+
+/* tsin_cos prec [N] performs N tests with prec bits */
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ if (argc > 1)
+ {
+ if (argc != 3 && argc != 4)
+ {
+ fprintf (stderr, "Usage: tsin_cos x prec [n]\n");
+ exit (1);
+ }
+ large_test (argv[1], atoi (argv[2]), (argc > 3) ? atoi (argv[3]) : 1);
+ goto end;
+ }
+
+ bug20091013 ();
+ bug20091008 ();
+ bug20091007 ();
+ bug20091122 ();
+ consistency ();
+
+ test_mpfr_sincos_fast ();
+
+ check_nans ();
+
+ /* worst case from PhD thesis of Vincent Lefe`vre: x=8980155785351021/2^54 */
+ check53 ("4.984987858808754279e-1", "4.781075595393330379e-1",
+ "8.783012931285841817e-1", MPFR_RNDN);
+ check53 ("4.984987858808754279e-1", "4.781075595393329824e-1",
+ "8.783012931285840707e-1", MPFR_RNDD);
+ check53 ("4.984987858808754279e-1", "4.781075595393329824e-1",
+ "8.783012931285840707e-1", MPFR_RNDZ);
+ check53 ("4.984987858808754279e-1", "4.781075595393330379e-1",
+ "8.783012931285841817e-1", MPFR_RNDU);
+ check53 ("1.00031274099908640274", "8.416399183372403892e-1",
+ "0.540039116973283217504", MPFR_RNDN);
+ check53 ("1.00229256850978698523", "8.427074524447979442e-1",
+ "0.538371757797526551137", MPFR_RNDZ);
+ check53 ("1.00288304857059840103", "8.430252033025980029e-1",
+ "0.537874062022526966409", MPFR_RNDZ);
+ check53 ("1.00591265847407274059", "8.446508805292128885e-1",
+ "0.53531755997839769456", MPFR_RNDN);
+
+ /* check one argument only */
+ check53sin ("1.00591265847407274059", "8.446508805292128885e-1", MPFR_RNDN);
+ check53cos ("1.00591265847407274059", "0.53531755997839769456", MPFR_RNDN);
+
+ overflowed_sin_cos0 ();
+ tiny ();
+ test20071214 ();
+
+ coverage_01032011 ();
+
+ end:
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsinh.c b/mpfr/tests/tsinh.c
new file mode 100644
index 0000000000..65a006ee38
--- /dev/null
+++ b/mpfr/tests/tsinh.c
@@ -0,0 +1,109 @@
+/* Test file for mpfr_sinh.
+
+Copyright 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_sinh
+#define TEST_RANDOM_EMIN -36
+#define TEST_RANDOM_EMAX 36
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x;
+ int i;
+
+ mpfr_init (x);
+
+ mpfr_set_nan (x);
+ mpfr_sinh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (x));
+
+ mpfr_set_inf (x, 1);
+ mpfr_sinh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
+ mpfr_set_inf (x, -1);
+ mpfr_sinh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);
+
+ mpfr_set_prec (x, 10);
+ mpfr_set_str_binary (x, "-0.1001011001");
+ mpfr_sinh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_si_2exp (x, -159, -8) == 0);
+
+ /* corner case */
+ mpfr_set_prec (x, 2);
+ mpfr_set_str_binary (x, "1E-6");
+ mpfr_sinh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -6) == 0);
+
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "1E1000000000");
+ i = mpfr_sinh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) > 0);
+ MPFR_ASSERTN (mpfr_overflow_p ());
+ MPFR_ASSERTN (i == 1);
+
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "-1E1000000000");
+ i = mpfr_sinh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) < 0);
+ MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == -1);
+
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "-1E1000000000");
+ i = mpfr_sinh (x, x, MPFR_RNDD);
+ MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_SIGN (x) < 0);
+ MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == -1);
+
+ mpfr_clear_flags ();
+ mpfr_set_str_binary (x, "-1E1000000000");
+ i = mpfr_sinh (x, x, MPFR_RNDU);
+ MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_SIGN (x) < 0);
+ MPFR_ASSERTN (mpfr_overflow_p () && !mpfr_underflow_p ());
+ MPFR_ASSERTN (i == 1);
+
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special ();
+
+ test_generic (2, 100, 100);
+
+ data_check ("data/sinh", mpfr_sinh, "mpfr_sinh");
+ bad_cases (mpfr_sinh, mpfr_asinh, "mpfr_sinh", 256, -256, 255,
+ 4, 128, 800, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsinh_cosh.c b/mpfr/tests/tsinh_cosh.c
new file mode 100644
index 0000000000..2b3d6e8cea
--- /dev/null
+++ b/mpfr/tests/tsinh_cosh.c
@@ -0,0 +1,143 @@
+/* Test file for mpfr_sinh_cosh.
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+static void
+failed (mpfr_t x, mpfr_t esh, mpfr_t gsh, mpfr_t ech, mpfr_t gch)
+{
+ printf ("error : mpfr_sinh_cosh (x) x = ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD);
+ printf ("\nsinh(x) expected ");
+ mpfr_out_str (stdout, 10, 0, esh, MPFR_RNDD);
+ printf ("\n got ");
+ mpfr_out_str (stdout, 10, 0, gsh, MPFR_RNDD);
+ printf ("\ncosh(x) expected ");
+ mpfr_out_str (stdout, 10, 0, ech, MPFR_RNDD);
+ printf ("\n got ");
+ mpfr_out_str (stdout, 10, 0, gch, MPFR_RNDD);
+ putchar ('\n');
+
+ mpfr_clears (x, esh, gsh, ech, gch, (mpfr_ptr) 0);
+ exit (1);
+}
+
+/* check against sinh, cosh */
+static void
+check (mpfr_t x, mpfr_rnd_t rnd)
+{
+ mpfr_t s, c, sx, cx;
+ int isc, is, ic;
+
+ mpfr_inits2 (MPFR_PREC(x), s, c, sx, cx, (mpfr_ptr) 0);
+
+ isc = mpfr_sinh_cosh (sx, cx, x, rnd);
+ is = mpfr_sinh (s, x, rnd);
+ ic = mpfr_cosh (c, x, rnd);
+
+ if (!mpfr_equal_p (s, sx) || !mpfr_equal_p (c, cx))
+ failed (x, s, sx, c, cx);
+ MPFR_ASSERTN (isc = is || ic);
+
+ mpfr_clears (s, c, sx, cx, (mpfr_ptr) 0);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t x, sh, ch;
+
+ mpfr_init2 (x, 123);
+ mpfr_init2 (sh, 123);
+ mpfr_init2 (ch, 123);
+
+ /* nan */
+ mpfr_set_nan (x);
+ mpfr_sinh_cosh (sh, ch, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (sh));
+ MPFR_ASSERTN (mpfr_nan_p (ch));
+
+ /* +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_sinh_cosh (sh, ch, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (sh));
+ MPFR_ASSERTN (mpfr_sgn (sh) > 0);
+ MPFR_ASSERTN (mpfr_inf_p (ch));
+ MPFR_ASSERTN (mpfr_sgn (ch) > 0);
+
+ /* -inf */
+ mpfr_set_inf (x, -1);
+ mpfr_sinh_cosh (sh, ch, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (sh));
+ MPFR_ASSERTN (mpfr_sgn (sh) < 0);
+ MPFR_ASSERTN (mpfr_inf_p (ch));
+ MPFR_ASSERTN (mpfr_sgn (ch) > 0);
+
+ mpfr_clear (x);
+ mpfr_clear (sh);
+ mpfr_clear (ch);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ mpfr_t x;
+
+ tests_start_mpfr ();
+
+ check_nans ();
+
+ /* check against values given by sinh(x), cosh(x) */
+ mpfr_init2 (x, 53);
+ mpfr_set_str (x, "FEDCBA987654321p-48", 16, MPFR_RNDN);
+ for (i = 0; i < 10; ++i)
+ {
+ /* x = i - x / 2 : boggle sign and bits */
+ mpfr_ui_sub (x, i, x, MPFR_RNDD);
+ mpfr_div_2ui (x, x, 2, MPFR_RNDD);
+
+ check (x, MPFR_RNDN);
+ check (x, MPFR_RNDU);
+ check (x, MPFR_RNDD);
+ }
+ mpfr_clear (x);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tsprintf.c b/mpfr/tests/tsprintf.c
new file mode 100644
index 0000000000..ae67eb689d
--- /dev/null
+++ b/mpfr/tests/tsprintf.c
@@ -0,0 +1,1239 @@
+/* tsprintf.c -- test file for mpfr_sprintf, mpfr_vsprintf, mpfr_snprintf,
+ and mpfr_vsnprintf
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifdef HAVE_STDARG
+#include <stdarg.h>
+
+#include <stdlib.h>
+#include <float.h>
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+const int prec_max_printf = 5000; /* limit for random precision in
+ random_double() */
+#define BUF_SIZE 65536
+
+const char pinf_str[] = "inf";
+const char pinf_uc_str[] = "INF";
+const char minf_str[] = "-inf";
+const char minf_uc_str[] = "-INF";
+const char nan_str[] = "nan";
+const char nan_uc_str[] = "NAN";
+
+/* 1. compare expected string with the string BUFFER returned by
+ mpfr_sprintf(buffer, fmt, x)
+ 2. then test mpfr_snprintf (buffer, p, fmt, x) with a random p. */
+static int
+check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x)
+{
+ int n0, n1, p;
+ char buffer[BUF_SIZE];
+
+ /* test mpfr_sprintf */
+ n0 = mpfr_sprintf (buffer, fmt, x);
+ if (strcmp (buffer, expected) != 0)
+ {
+ printf ("Error in mpfr_sprintf (s, \"%s\", x);\n", fmt);
+ printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer);
+
+ exit (1);
+ }
+
+ /* test mpfr_snprintf */
+ p = (int) (randlimb () % n0);
+ if (p == 0 && (randlimb () & 1) == 0)
+ {
+ n1 = mpfr_snprintf (NULL, 0, fmt, x);
+ }
+ else
+ {
+ buffer[p] = 17;
+ n1 = mpfr_snprintf (buffer, p, fmt, x);
+ if (buffer[p] != 17)
+ {
+ printf ("Buffer overflow in mpfr_snprintf for p = %d!\n", p);
+ exit (1);
+ }
+ }
+ if (n0 != n1)
+ {
+ printf ("Error in mpfr_snprintf (s, %d, \"%s\", x) return value\n",
+ p, fmt);
+ printf ("expected: %d\ngot: %d\n", n0, n1);
+ exit (1);
+ }
+ if ((p > 1 && strncmp (expected, buffer, p-1) != 0)
+ || (p == 1 && buffer[0] != '\0'))
+ {
+ char part_expected[BUF_SIZE];
+ strncpy (part_expected, expected, p);
+ part_expected[p-1] = '\0';
+ printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", p, fmt);
+ printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer);
+ exit (1);
+ }
+ return n0;
+}
+
+/* 1. compare expected string with the string BUFFER returned by
+ mpfr_vsprintf(buffer, fmt, ...)
+ 2. then, test mpfr_vsnprintf. */
+static int
+check_vsprintf (const char *expected, const char *fmt, ...)
+{
+ int n0, n1, p;
+ char buffer[BUF_SIZE];
+ va_list ap0, ap1;
+ va_start (ap0, fmt);
+ va_start (ap1, fmt);
+
+ n0 = mpfr_vsprintf (buffer, fmt, ap0);
+ if (strcmp (buffer, expected) != 0)
+ {
+ printf ("Error in mpfr_vsprintf (s, \"%s\", ...);\n", fmt);
+ printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer);
+
+ va_end (ap0);
+ va_end (ap1);
+ exit (1);
+ }
+ va_end (ap0);
+
+ /* test mpfr_snprintf */
+ p = (int) (randlimb () % n0);
+ if (p == 0 && (randlimb () & 1) == 0)
+ {
+ n1 = mpfr_vsnprintf (NULL, 0, fmt, ap1);
+ }
+ else
+ {
+ buffer[p] = 17;
+ n1 = mpfr_vsnprintf (buffer, p, fmt, ap1);
+ if (buffer[p] != 17)
+ {
+ printf ("Buffer overflow in mpfr_vsnprintf for p = %d!\n", p);
+ exit (1);
+ }
+ }
+ if (n0 != n1)
+ {
+ printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...) return value\n",
+ p, fmt);
+ printf ("expected: %d\ngot: %d\n", n0, n1);
+
+ va_end (ap1);
+ exit (1);
+ }
+ if ((p > 1 && strncmp (expected, buffer, p-1) != 0)
+ || (p == 1 && buffer[0] != '\0'))
+ {
+ char part_expected[BUF_SIZE];
+ strncpy (part_expected, expected, p);
+ part_expected[p-1] = '\0';
+ printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", p, fmt);
+ printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer);
+
+ va_end (ap1);
+ exit (1);
+ }
+
+ va_end (ap1);
+ return n0;
+}
+
+static void
+native_types (void)
+{
+ int c = 'a';
+ int i = -1;
+ unsigned int ui = 1;
+ double d = -1.25;
+ char s[] = "test";
+
+ char buf[255];
+
+ sprintf (buf, "%c", c);
+ check_vsprintf (buf, "%c", c);
+
+ sprintf (buf, "%d", i);
+ check_vsprintf (buf, "%d", i);
+
+ sprintf (buf, "%e", d);
+ check_vsprintf (buf, "%e", d);
+
+ sprintf (buf, "%f", d);
+ check_vsprintf (buf, "%f", d);
+
+ sprintf (buf, "%i", i);
+ check_vsprintf (buf, "%i", i);
+
+ sprintf (buf, "%g", d);
+ check_vsprintf (buf, "%g", d);
+
+ sprintf (buf, "%o", i);
+ check_vsprintf (buf, "%o", i);
+
+ sprintf (buf, "%s", s);
+ check_vsprintf (buf, "%s", s);
+
+ sprintf (buf, "--%s++", "");
+ check_vsprintf (buf, "--%s++", "");
+
+ sprintf (buf, "%u", ui);
+ check_vsprintf (buf, "%u", ui);
+
+ sprintf (buf, "%x", ui);
+ check_vsprintf (buf, "%x", ui);
+}
+
+static int
+decimal (void)
+{
+ mpfr_prec_t p = 128;
+ mpfr_t x;
+ mpfr_t z;
+ mpfr_init (z);
+ mpfr_init2 (x, p);
+
+ /* specifier 'P' for precision */
+ check_vsprintf ("128", "%Pu", p);
+ check_vsprintf ("00128", "%.5Pu", p);
+
+ /* special numbers */
+ mpfr_set_inf (x, 1);
+ check_sprintf (pinf_str, "%Re", x);
+ check_sprintf (pinf_str, "%RUe", x);
+ check_sprintf (pinf_uc_str, "%RE", x);
+ check_sprintf (pinf_uc_str, "%RDE", x);
+ check_sprintf (pinf_str, "%Rf", x);
+ check_sprintf (pinf_str, "%RYf", x);
+ check_sprintf (pinf_uc_str, "%RF", x);
+ check_sprintf (pinf_uc_str, "%RZF", x);
+ check_sprintf (pinf_str, "%Rg", x);
+ check_sprintf (pinf_str, "%RNg", x);
+ check_sprintf (pinf_uc_str, "%RG", x);
+ check_sprintf (pinf_uc_str, "%RUG", x);
+ check_sprintf (" inf", "%010Re", x);
+ check_sprintf (" inf", "%010RDe", x);
+
+ mpfr_set_inf (x, -1);
+ check_sprintf (minf_str, "%Re", x);
+ check_sprintf (minf_str, "%RYe", x);
+ check_sprintf (minf_uc_str, "%RE", x);
+ check_sprintf (minf_uc_str, "%RZE", x);
+ check_sprintf (minf_str, "%Rf", x);
+ check_sprintf (minf_str, "%RNf", x);
+ check_sprintf (minf_uc_str, "%RF", x);
+ check_sprintf (minf_uc_str, "%RUF", x);
+ check_sprintf (minf_str, "%Rg", x);
+ check_sprintf (minf_str, "%RDg", x);
+ check_sprintf (minf_uc_str, "%RG", x);
+ check_sprintf (minf_uc_str, "%RYG", x);
+ check_sprintf (" -inf", "%010Re", x);
+ check_sprintf (" -inf", "%010RZe", x);
+
+ mpfr_set_nan (x);
+ check_sprintf (nan_str, "%Re", x);
+ check_sprintf (nan_str, "%RNe", x);
+ check_sprintf (nan_uc_str, "%RE", x);
+ check_sprintf (nan_uc_str, "%RUE", x);
+ check_sprintf (nan_str, "%Rf", x);
+ check_sprintf (nan_str, "%RDf", x);
+ check_sprintf (nan_uc_str, "%RF", x);
+ check_sprintf (nan_uc_str, "%RYF", x);
+ check_sprintf (nan_str, "%Rg", x);
+ check_sprintf (nan_str, "%RZg", x);
+ check_sprintf (nan_uc_str, "%RG", x);
+ check_sprintf (nan_uc_str, "%RNG", x);
+ check_sprintf (" nan", "%010Re", x);
+
+ /* positive numbers */
+ mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN);
+ mpfr_set_ui (z, 0, MPFR_RNDD);
+
+ /* simplest case right justified */
+ check_sprintf (" 1.899347461279296875e+07", "%30Re", x);
+ check_sprintf (" 2e+07", "%30.0Re", x);
+ check_sprintf (" 18993474.612793", "%30Rf", x);
+ check_sprintf (" 18993474.6127930", "%30.7Rf", x);
+ check_sprintf (" 1.89935e+07", "%30Rg", x);
+ check_sprintf (" 2e+07", "%30.0Rg", x);
+ check_sprintf (" 18993474.61279296875", "%30.19Rg", x);
+ check_sprintf (" 0e+00", "%30.0Re", z);
+ check_sprintf (" 0", "%30.0Rf", z);
+ check_sprintf (" 0.0000", "%30.4Rf", z);
+ check_sprintf (" 0", "%30.0Rg", z);
+ check_sprintf (" 0", "%30.4Rg", z);
+ /* sign or space, pad with leading zeros */
+ check_sprintf (" 000001.899347461279296875E+07", "% 030RE", x);
+ check_sprintf (" 0000000000000000001.89935E+07", "% 030RG", x);
+ check_sprintf (" 0000000000000000000000002E+07", "% 030.0RE", x);
+ check_sprintf (" 0000000000000000000000000E+00", "% 030.0RE", z);
+ check_sprintf (" 00000000000000000000000000000", "% 030.0RF", z);
+ /* sign + or -, left justified */
+ check_sprintf ("+1.899347461279296875e+07 ", "%+-30Re", x);
+ check_sprintf ("+2e+07 ", "%+-30.0Re", x);
+ check_sprintf ("+0e+00 ", "%+-30.0Re", z);
+ check_sprintf ("+0 ", "%+-30.0Rf", z);
+ /* decimal point, left justified, precision and rounding parameter */
+ check_vsprintf ("1.9E+07 ", "%#-10.*R*E", 1, MPFR_RNDN, x);
+ check_vsprintf ("2.E+07 ", "%#*.*R*E", -10, 0, MPFR_RNDN, x);
+ check_vsprintf ("2.E+07 ", "%#-10.*R*G", 0, MPFR_RNDN, x);
+ check_vsprintf ("0.E+00 ", "%#-10.*R*E", 0, MPFR_RNDN, z);
+ check_vsprintf ("0. ", "%#-10.*R*F", 0, MPFR_RNDN, z);
+ check_vsprintf ("0. ", "%#-10.*R*G", 0, MPFR_RNDN, z);
+ /* sign or space */
+ check_sprintf (" 1.899e+07", "% .3RNe", x);
+ check_sprintf (" 2e+07", "% .0RNe", x);
+ /* sign + or -, decimal point, pad with leading zeros */
+ check_sprintf ("+0001.8E+07", "%0+#11.1RZE", x);
+ check_sprintf ("+00001.E+07", "%0+#11.0RZE", x);
+ check_sprintf ("+0000.0E+00", "%0+#11.1RZE", z);
+ check_sprintf ("+00000000.0", "%0+#11.1RZF", z);
+ /* pad with leading zero */
+ check_sprintf ("0000001.899347461279296875e+07", "%030RDe", x);
+ check_sprintf ("00000000000000000000000001e+07", "%030.0RDe", x);
+ /* sign or space, decimal point, left justified */
+ check_sprintf (" 1.8E+07 ", "%- #11.1RDE", x);
+ check_sprintf (" 1.E+07 ", "%- #11.0RDE", x);
+
+ /* negative numbers */
+ mpfr_mul_si (x, x, -1, MPFR_RNDD);
+ mpfr_mul_si (z, z, -1, MPFR_RNDD);
+
+ /* sign + or - */
+ check_sprintf (" -1.8e+07", "%+10.1RUe", x);
+ check_sprintf (" -1e+07", "%+10.0RUe", x);
+ check_sprintf (" -0e+00", "%+10.0RUe", z);
+ check_sprintf (" -0", "%+10.0RUf", z);
+
+
+ /* neighborhood of 1 */
+ mpfr_set_str (x, "0.99993896484375", 10, MPFR_RNDN);
+ check_sprintf ("9.9993896484375E-01 ", "%-20RE", x);
+ check_sprintf ("9.9993896484375E-01 ", "%-20.RE", x);
+ check_sprintf ("1E+00 ", "%-20.0RE", x);
+ check_sprintf ("1.0E+00 ", "%-20.1RE", x);
+ check_sprintf ("1.00E+00 ", "%-20.2RE", x);
+ check_sprintf ("9.999E-01 ", "%-20.3RE", x);
+ check_sprintf ("9.9994E-01 ", "%-20.4RE", x);
+ check_sprintf ("0.999939 ", "%-20RF", x);
+ check_sprintf ("0.999939 ", "%-20.RF", x);
+ check_sprintf ("1 ", "%-20.0RF", x);
+ check_sprintf ("1.0 ", "%-20.1RF", x);
+ check_sprintf ("1.00 ", "%-20.2RF", x);
+ check_sprintf ("1.000 ", "%-20.3RF", x);
+ check_sprintf ("0.9999 ", "%-20.4RF", x);
+ check_sprintf ("0.999939 ", "%-#20RF", x);
+ check_sprintf ("0.999939 ", "%-#20.RF", x);
+ check_sprintf ("1. ", "%-#20.0RF", x);
+ check_sprintf ("1.0 ", "%-#20.1RF", x);
+ check_sprintf ("1.00 ", "%-#20.2RF", x);
+ check_sprintf ("1.000 ", "%-#20.3RF", x);
+ check_sprintf ("0.9999 ", "%-#20.4RF", x);
+ check_sprintf ("1 ", "%-20.0RG", x);
+ check_sprintf ("1 ", "%-20.1RG", x);
+ check_sprintf ("1 ", "%-20.2RG", x);
+ check_sprintf ("1 ", "%-20.3RG", x);
+ check_sprintf ("0.9999 ", "%-20.4RG", x);
+ check_sprintf ("0.999939 ", "%-#20RG", x);
+ check_sprintf ("0.999939 ", "%-#20.RG", x);
+ check_sprintf ("1. ", "%-#20.0RG", x);
+ check_sprintf ("1. ", "%-#20.1RG", x);
+ check_sprintf ("1.0 ", "%-#20.2RG", x);
+ check_sprintf ("1.00 ", "%-#20.3RG", x);
+ check_sprintf ("0.9999 ", "%-#20.4RG", x);
+
+ /* multiple of 10 */
+ mpfr_set_str (x, "1e17", 10, MPFR_RNDN);
+ check_sprintf ("1e+17", "%Re", x);
+ check_sprintf ("1.000e+17", "%.3Re", x);
+ check_sprintf ("100000000000000000", "%.0Rf", x);
+ check_sprintf ("100000000000000000.0", "%.1Rf", x);
+ check_sprintf ("100000000000000000.000000", "%'Rf", x);
+ check_sprintf ("100000000000000000.0", "%'.1Rf", x);
+
+ mpfr_ui_div (x, 1, x, MPFR_RNDN); /* x=1e-17 */
+ check_sprintf ("1e-17", "%Re", x);
+ check_sprintf ("0.000000", "%Rf", x);
+ check_sprintf ("1e-17", "%Rg", x);
+ check_sprintf ("0.0", "%.1RDf", x);
+ check_sprintf ("0.0", "%.1RZf", x);
+ check_sprintf ("0.1", "%.1RUf", x);
+ check_sprintf ("0.1", "%.1RYf", x);
+ check_sprintf ("0", "%.0RDf", x);
+ check_sprintf ("0", "%.0RZf", x);
+ check_sprintf ("1", "%.0RUf", x);
+ check_sprintf ("1", "%.0RYf", x);
+
+ /* multiple of 10 with 'g' style */
+ mpfr_set_str (x, "10", 10, MPFR_RNDN);
+ check_sprintf ("10", "%Rg", x);
+ check_sprintf ("1e+01", "%.0Rg", x);
+ check_sprintf ("1e+01", "%.1Rg", x);
+ check_sprintf ("10", "%.2Rg", x);
+
+ mpfr_ui_div (x, 1, x, MPFR_RNDN);
+ check_sprintf ("0.1", "%Rg", x);
+ check_sprintf ("0.1", "%.0Rg", x);
+ check_sprintf ("0.1", "%.1Rg", x);
+
+ mpfr_set_str (x, "1000", 10, MPFR_RNDN);
+ check_sprintf ("1000", "%Rg", x);
+ check_sprintf ("1e+03", "%.0Rg", x);
+ check_sprintf ("1e+03", "%.3Rg", x);
+ check_sprintf ("1000", "%.4Rg", x);
+
+ mpfr_ui_div (x, 1, x, MPFR_RNDN);
+ check_sprintf ("0.001", "%Rg", x);
+ check_sprintf ("0.001", "%.0Rg", x);
+ check_sprintf ("0.001", "%.1Rg", x);
+
+ mpfr_set_str (x, "100000", 10, MPFR_RNDN);
+ check_sprintf ("100000", "%Rg", x);
+ check_sprintf ("1e+05", "%.0Rg", x);
+ check_sprintf ("1e+05", "%.5Rg", x);
+ check_sprintf ("100000", "%.6Rg", x);
+
+ mpfr_ui_div (x, 1, x, MPFR_RNDN);
+ check_sprintf ("1e-05", "%Rg", x);
+ check_sprintf ("1e-05", "%.0Rg", x);
+ check_sprintf ("1e-05", "%.1Rg", x);
+
+ /* check rounding mode */
+ mpfr_set_str (x, "0.0076", 10, MPFR_RNDN);
+ check_sprintf ("0.007", "%.3RDF", x);
+ check_sprintf ("0.007", "%.3RZF", x);
+ check_sprintf ("0.008", "%.3RF", x);
+ check_sprintf ("0.008", "%.3RUF", x);
+ check_sprintf ("0.008", "%.3RYF", x);
+ check_vsprintf ("0.008", "%.3R*F", MPFR_RNDA, x);
+
+ /* check limit between %f-style and %g-style */
+ mpfr_set_str (x, "0.0000999", 10, MPFR_RNDN);
+ check_sprintf ("0.0001", "%.0Rg", x);
+ check_sprintf ("9e-05", "%.0RDg", x);
+ check_sprintf ("0.0001", "%.1Rg", x);
+ check_sprintf ("0.0001", "%.2Rg", x);
+ check_sprintf ("9.99e-05", "%.3Rg", x);
+
+ /* trailing zeros */
+ mpfr_set_si_2exp (x, -1, -15, MPFR_RNDN); /* x=-2^-15 */
+ check_sprintf ("-3.0517578125e-05", "%.30Rg", x);
+ check_sprintf ("-3.051757812500000000000000000000e-05", "%.30Re", x);
+ check_sprintf ("-3.05175781250000000000000000000e-05", "%#.30Rg", x);
+ check_sprintf ("-0.000030517578125000000000000000", "%.30Rf", x);
+
+ /* bug 20081023 */
+ check_sprintf ("-3.0517578125e-05", "%.30Rg", x);
+ mpfr_set_str (x, "1.9999", 10, MPFR_RNDN);
+ check_sprintf ("1.999900 ", "%-#10.7RG", x);
+ check_sprintf ("1.9999 ", "%-10.7RG", x);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ check_sprintf ("1.00000000000000000000000000000", "%#.30Rg", x);
+ check_sprintf ("1", "%.30Rg", x);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ check_sprintf ("0.000000000000000000000000000000", "%#.30Rg", x);
+ check_sprintf ("0", "%.30Rg", x);
+
+ /* following tests with precision 53 bits */
+ mpfr_set_prec (x, 53);
+
+ /* Exponent zero has a plus sign */
+ mpfr_set_str (x, "-9.95645044213728791504536275169812142849e-01", 10,
+ MPFR_RNDN);
+ check_sprintf ("-1.0e+00", "%- #0.1Re", x);
+
+ /* Decimal point and no figure after it with '#' flag and 'G' style */
+ mpfr_set_str (x, "-9.90597761233942053494e-01", 10, MPFR_RNDN);
+ check_sprintf ("-1.", "%- #0.1RG", x);
+
+ /* precision zero */
+ mpfr_set_d (x, 9.5, MPFR_RNDN);
+ check_sprintf ("9", "%.0RDf", x);
+ check_sprintf ("10", "%.0RUf", x);
+
+ mpfr_set_d (x, 19.5, MPFR_RNDN);
+ check_sprintf ("19", "%.0RDf", x);
+ check_sprintf ("20", "%.0RUf", x);
+
+ mpfr_set_d (x, 99.5, MPFR_RNDN);
+ check_sprintf ("99", "%.0RDf", x);
+ check_sprintf ("100", "%.0RUf", x);
+
+ mpfr_set_d (x, -9.5, MPFR_RNDN);
+ check_sprintf ("-10", "%.0RDf", x);
+ check_sprintf ("-10", "%.0RYf", x);
+ check_sprintf ("-10", "%.0Rf", x);
+ check_sprintf ("-1e+01", "%.0Re", x);
+ check_sprintf ("-1e+01", "%.0Rg", x);
+ mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN);
+ check_sprintf ("0", "%.0Rf", x);
+ check_sprintf ("5e-01", "%.0Re", x);
+ check_sprintf ("0.5", "%.0Rg", x);
+ mpfr_set_ui_2exp (x, 3, -1, MPFR_RNDN);
+ check_sprintf ("2", "%.0Rf", x);
+ mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN);
+ check_sprintf ("2", "%.0Rf", x);
+ mpfr_set_ui (x, 0x1f, MPFR_RNDN);
+ check_sprintf ("0x1p+5", "%.0Ra", x);
+ mpfr_set_ui (x, 3, MPFR_RNDN);
+ check_sprintf ("1p+2", "%.0Rb", x);
+
+ /* round to next ten power with %f but not with %g */
+ mpfr_set_str (x, "-6.64464380544039223686e-02", 10, MPFR_RNDN);
+ check_sprintf ("-0.1", "%.1Rf", x);
+ check_sprintf ("-0.0", "%.1RZf", x);
+ check_sprintf ("-0.07", "%.1Rg", x);
+ check_sprintf ("-0.06", "%.1RZg", x);
+
+ /* round to next ten power and do not remove trailing zeros */
+ mpfr_set_str (x, "9.98429393291486722006e-02", 10, MPFR_RNDN);
+ check_sprintf ("0.1", "%#.1Rg", x);
+ check_sprintf ("0.10", "%#.2Rg", x);
+ check_sprintf ("0.099", "%#.2RZg", x);
+
+ /* Halfway cases */
+ mpfr_set_str (x, "1.5", 10, MPFR_RNDN);
+ check_sprintf ("2e+00", "%.0Re", x);
+ mpfr_set_str (x, "2.5", 10, MPFR_RNDN);
+ check_sprintf ("2e+00", "%.0Re", x);
+ mpfr_set_str (x, "9.5", 10, MPFR_RNDN);
+ check_sprintf ("1e+01", "%.0Re", x);
+ mpfr_set_str (x, "1.25", 10, MPFR_RNDN);
+ check_sprintf ("1.2e+00", "%.1Re", x);
+ mpfr_set_str (x, "1.75", 10, MPFR_RNDN);
+ check_sprintf ("1.8e+00", "%.1Re", x);
+ mpfr_set_str (x, "-0.5", 10, MPFR_RNDN);
+ check_sprintf ("-0", "%.0Rf", x);
+ mpfr_set_str (x, "1.25", 10, MPFR_RNDN);
+ check_sprintf ("1.2", "%.1Rf", x);
+ mpfr_set_str (x, "1.75", 10, MPFR_RNDN);
+ check_sprintf ("1.8", "%.1Rf", x);
+ mpfr_set_str (x, "1.5", 10, MPFR_RNDN);
+ check_sprintf ("2", "%.1Rg", x);
+ mpfr_set_str (x, "2.5", 10, MPFR_RNDN);
+ check_sprintf ("2", "%.1Rg", x);
+ mpfr_set_str (x, "9.25", 10, MPFR_RNDN);
+ check_sprintf ("9.2", "%.2Rg", x);
+ mpfr_set_str (x, "9.75", 10, MPFR_RNDN);
+ check_sprintf ("9.8", "%.2Rg", x);
+
+ /* assertion failure in r6320 */
+ mpfr_set_str (x, "-9.996", 10, MPFR_RNDN);
+ check_sprintf ("-10.0", "%.1Rf", x);
+
+ mpfr_clears (x, z, (mpfr_ptr) 0);
+ return 0;
+}
+
+static int
+hexadecimal (void)
+{
+ mpfr_t x, z;
+ mpfr_inits2 (64, x, z, (mpfr_ptr) 0);
+
+ /* special */
+ mpfr_set_inf (x, 1);
+ check_sprintf (pinf_str, "%Ra", x);
+ check_sprintf (pinf_str, "%RUa", x);
+ check_sprintf (pinf_str, "%RDa", x);
+ check_sprintf (pinf_uc_str, "%RA", x);
+ check_sprintf (pinf_uc_str, "%RYA", x);
+ check_sprintf (pinf_uc_str, "%RZA", x);
+ check_sprintf (pinf_uc_str, "%RNA", x);
+
+ mpfr_set_inf (x, -1);
+ check_sprintf (minf_str, "%Ra", x);
+ check_sprintf (minf_str, "%RYa", x);
+ check_sprintf (minf_str, "%RZa", x);
+ check_sprintf (minf_str, "%RNa", x);
+ check_sprintf (minf_uc_str, "%RA", x);
+ check_sprintf (minf_uc_str, "%RUA", x);
+ check_sprintf (minf_uc_str, "%RDA", x);
+
+ mpfr_set_nan (x);
+ check_sprintf (nan_str, "%Ra", x);
+ check_sprintf (nan_uc_str, "%RA", x);
+
+ /* regular numbers */
+ mpfr_set_str (x, "FEDCBA9.87654321", 16, MPFR_RNDN);
+ mpfr_set_ui (z, 0, MPFR_RNDZ);
+
+ /* simplest case right justified */
+ check_sprintf (" 0xf.edcba987654321p+24", "%25Ra", x);
+ check_sprintf (" 0xf.edcba987654321p+24", "%25RUa", x);
+ check_sprintf (" 0xf.edcba987654321p+24", "%25RDa", x);
+ check_sprintf (" 0xf.edcba987654321p+24", "%25RYa", x);
+ check_sprintf (" 0xf.edcba987654321p+24", "%25RZa", x);
+ check_sprintf (" 0xf.edcba987654321p+24", "%25RNa", x);
+ check_sprintf (" 0x1p+28", "%25.0Ra", x);
+ check_sprintf (" 0x0p+0", "%25.0Ra", z);
+ /* sign or space, pad with leading zeros */
+ check_sprintf (" 0X00F.EDCBA987654321P+24", "% 025RA", x);
+ check_sprintf (" 0X000000000000000001P+28", "% 025.0RA", x);
+ check_sprintf (" 0X0000000000000000000P+0", "% 025.0RA", z);
+ /* sign + or -, left justified */
+ check_sprintf ("+0xf.edcba987654321p+24 ", "%+-25Ra", x);
+ check_sprintf ("+0x1p+28 ", "%+-25.0Ra", x);
+ check_sprintf ("+0x0p+0 ", "%+-25.0Ra", z);
+ /* decimal point, left justified, precision and rounding parameter */
+ check_vsprintf ("0XF.FP+24 ", "%#-10.*R*A", 1, MPFR_RNDN, x);
+ check_vsprintf ("0X1.P+28 ", "%#-10.*R*A", 0, MPFR_RNDN, x);
+ check_vsprintf ("0X0.P+0 ", "%#-10.*R*A", 0, MPFR_RNDN, z);
+ /* sign or space */
+ check_sprintf (" 0xf.eddp+24", "% .3RNa", x);
+ check_sprintf (" 0x1p+28", "% .0RNa", x);
+ /* sign + or -, decimal point, pad with leading zeros */
+ check_sprintf ("+0X0F.EP+24", "%0+#11.1RZA", x);
+ check_sprintf ("+0X00F.P+24", "%0+#11.0RZA", x);
+ check_sprintf ("+0X000.0P+0", "%0+#11.1RZA", z);
+ /* pad with leading zero */
+ check_sprintf ("0x0000f.edcba987654321p+24", "%026RDa", x);
+ check_sprintf ("0x0000000000000000000fp+24", "%026.0RDa", x);
+ /* sign or space, decimal point, left justified */
+ check_sprintf (" 0XF.EP+24 " , "%- #11.1RDA", x);
+ check_sprintf (" 0XF.P+24 " , "%- #11.0RDA", x);
+
+ mpfr_mul_si (x, x, -1, MPFR_RNDD);
+ mpfr_mul_si (z, z, -1, MPFR_RNDD);
+
+ /* sign + or - */
+ check_sprintf ("-0xf.ep+24", "%+10.1RUa", x);
+ check_sprintf (" -0xfp+24", "%+10.0RUa", x);
+ check_sprintf (" -0x0p+0", "%+10.0RUa", z);
+
+ /* rounding bit is zero */
+ mpfr_set_str (x, "0xF.7", 16, MPFR_RNDN);
+ check_sprintf ("0XFP+0", "%.0RNA", x);
+ /* tie case in round to nearest mode */
+ mpfr_set_str (x, "0x0.8800000000000000p+3", 16, MPFR_RNDN);
+ check_sprintf ("0x9.p-1", "%#.0RNa", x);
+ mpfr_set_str (x, "-0x0.9800000000000000p+3", 16, MPFR_RNDN);
+ check_sprintf ("-0xap-1", "%.0RNa", x);
+ /* trailing zeros in fractional part */
+ check_sprintf ("-0X4.C0000000000000000000P+0", "%.20RNA", x);
+ /* rounding bit is one and the first non zero bit is far away */
+ mpfr_set_prec (x, 1024);
+ mpfr_set_ui_2exp (x, 29, -1, MPFR_RNDN);
+ mpfr_nextabove (x);
+ check_sprintf ("0XFP+0", "%.0RNA", x);
+
+ /* with more than one limb */
+ mpfr_set_prec (x, 300);
+ mpfr_set_str (x, "0xf.ffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffff", 16, MPFR_RNDN);
+ check_sprintf ("0x1p+4 [300]", "%.0RNa [300]", x);
+ check_sprintf ("0xfp+0 [300]", "%.0RZa [300]", x);
+ check_sprintf ("0x1p+4 [300]", "%.0RYa [300]", x);
+ check_sprintf ("0xfp+0 [300]", "%.0RDa [300]", x);
+ check_sprintf ("0x1p+4 [300]", "%.0RUa [300]", x);
+ check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
+ "%.40RNa", x);
+ check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
+ "%.40RZa", x);
+ check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
+ "%.40RYa", x);
+ check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
+ "%.40RDa", x);
+ check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
+ "%.40RUa", x);
+
+ mpfr_set_str (x, "0xf.7fffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "ffffffffffffffffff", 16, MPFR_RNDN);
+ check_sprintf ("0XFP+0", "%.0RNA", x);
+ check_sprintf ("0XFP+0", "%.0RZA", x);
+ check_sprintf ("0X1P+4", "%.0RYA", x);
+ check_sprintf ("0XFP+0", "%.0RDA", x);
+ check_sprintf ("0X1P+4", "%.0RUA", x);
+ check_sprintf ("0XF.8P+0", "%.1RNA", x);
+ check_sprintf ("0XF.7P+0", "%.1RZA", x);
+ check_sprintf ("0XF.8P+0", "%.1RYA", x);
+ check_sprintf ("0XF.7P+0", "%.1RDA", x);
+ check_sprintf ("0XF.8P+0", "%.1RUA", x);
+
+ /* do not round up to the next power of the base */
+ mpfr_set_str (x, "0xf.fffffffffffffffffffffffffffffffffffffeffffffffffffff"
+ "ffffffffffffffffff", 16, MPFR_RNDN);
+ check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
+ "%.40RNa", x);
+ check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
+ "%.40RZa", x);
+ check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
+ "%.40RYa", x);
+ check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
+ "%.40RDa", x);
+ check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
+ "%.40RUa", x);
+
+ mpfr_clears (x, z, (mpfr_ptr) 0);
+ return 0;
+}
+
+static int
+binary (void)
+{
+ mpfr_t x;
+ mpfr_t z;
+ mpfr_inits2 (64, x, z, (mpfr_ptr) 0);
+
+ /* special */
+ mpfr_set_inf (x, 1);
+ check_sprintf (pinf_str, "%Rb", x);
+
+ mpfr_set_inf (x, -1);
+ check_sprintf (minf_str, "%Rb", x);
+
+ mpfr_set_nan (x);
+ check_sprintf (nan_str, "%Rb", x);
+
+ /* regular numbers */
+ mpfr_set_str (x, "1110010101.1001101", 2, MPFR_RNDN);
+ mpfr_set_ui (z, 0, MPFR_RNDN);
+
+ /* simplest case: right justified */
+ check_sprintf (" 1.1100101011001101p+9", "%25Rb", x);
+ check_sprintf (" 0p+0", "%25Rb", z);
+ /* sign or space, pad with leading zeros */
+ check_sprintf (" 0001.1100101011001101p+9", "% 025Rb", x);
+ check_sprintf (" 000000000000000000000p+0", "% 025Rb", z);
+ /* sign + or -, left justified */
+ check_sprintf ("+1.1100101011001101p+9 ", "%+-25Rb", x);
+ check_sprintf ("+0p+0 ", "%+-25Rb", z);
+ /* sign or space */
+ check_sprintf (" 1.110p+9", "% .3RNb", x);
+ check_sprintf (" 1.1101p+9", "% .4RNb", x);
+ check_sprintf (" 0.0000p+0", "% .4RNb", z);
+ /* sign + or -, decimal point, pad with leading zeros */
+ check_sprintf ("+00001.1p+9", "%0+#11.1RZb", x);
+ check_sprintf ("+0001.0p+10", "%0+#11.1RNb", x);
+ check_sprintf ("+000000.p+0", "%0+#11.0RNb", z);
+ /* pad with leading zero */
+ check_sprintf ("00001.1100101011001101p+9", "%025RDb", x);
+ /* sign or space, decimal point (unused), left justified */
+ check_sprintf (" 1.1p+9 ", "%- #11.1RDb", x);
+ check_sprintf (" 1.p+9 ", "%- #11.0RDb", x);
+ check_sprintf (" 1.p+10 ", "%- #11.0RUb", x);
+ check_sprintf (" 1.p+9 ", "%- #11.0RZb", x);
+ check_sprintf (" 1.p+10 ", "%- #11.0RYb", x);
+ check_sprintf (" 1.p+10 ", "%- #11.0RNb", x);
+
+ mpfr_mul_si (x, x, -1, MPFR_RNDD);
+ mpfr_mul_si (z, z, -1, MPFR_RNDD);
+
+ /* sign + or - */
+ check_sprintf (" -1.1p+9", "%+10.1RUb", x);
+ check_sprintf (" -0.0p+0", "%+10.1RUb", z);
+
+ /* precision 0 */
+ check_sprintf ("-1p+10", "%.0RNb", x);
+ check_sprintf ("-1p+10", "%.0RDb", x);
+ check_sprintf ("-1p+9", "%.0RUb", x);
+ check_sprintf ("-1p+9", "%.0RZb", x);
+ check_sprintf ("-1p+10", "%.0RYb", x);
+ /* round to next base power */
+ check_sprintf ("-1.0p+10", "%.1RNb", x);
+ check_sprintf ("-1.0p+10", "%.1RDb", x);
+ check_sprintf ("-1.0p+10", "%.1RYb", x);
+ /* do not round to next base power */
+ check_sprintf ("-1.1p+9", "%.1RUb", x);
+ check_sprintf ("-1.1p+9", "%.1RZb", x);
+ /* rounding bit is zero */
+ check_sprintf ("-1.11p+9", "%.2RNb", x);
+ /* tie case in round to nearest mode */
+ check_sprintf ("-1.1100101011001101p+9", "%.16RNb", x);
+ /* trailing zeros in fractional part */
+ check_sprintf ("-1.110010101100110100000000000000p+9", "%.30RNb", x);
+
+ mpfr_clears (x, z, (mpfr_ptr) 0);
+ return 0;
+}
+
+static int
+mixed (void)
+{
+ int n1;
+ int n2;
+ int i = 121;
+#ifndef NPRINTF_L
+ long double d = 1. / 31.;
+#endif
+ mpf_t mpf;
+ mpq_t mpq;
+ mpz_t mpz;
+ mpfr_t x;
+ mpfr_rnd_t rnd;
+
+ mpf_init (mpf);
+ mpf_set_ui (mpf, 40);
+ mpf_div_ui (mpf, mpf, 31); /* mpf = 40.0 / 31.0 */
+ mpq_init (mpq);
+ mpq_set_ui (mpq, 123456, 4567890);
+ mpz_init (mpz);
+ mpz_fib_ui (mpz, 64);
+ mpfr_init (x);
+ mpfr_set_str (x, "-12345678.875", 10, MPFR_RNDN);
+ rnd = MPFR_RNDD;
+
+ check_vsprintf ("121%", "%i%%", i);
+ check_vsprintf ("121% -1.2345678875E+07", "%i%% %RNE", i, x);
+ check_vsprintf ("121, -12345679", "%i, %.0Rf", i, x);
+ check_vsprintf ("10610209857723, -1.2345678875e+07", "%Zi, %R*e", mpz, rnd,
+ x);
+ check_vsprintf ("-12345678.9, 121", "%.1Rf, %i", x, i);
+ check_vsprintf ("-12345678, 1e240/45b352", "%.0R*f, %Qx", MPFR_RNDZ, x, mpq);
+ n1 = check_vsprintf ("121, -12345678.875000000000, 1.290323", "%i, %.*Rf, %Ff%n",
+ i, 12, x, mpf, &n2);
+ if (n1 != n2)
+ {
+ printf ("error in number of characters written by mpfr_vsprintf\n");
+ printf ("expected: %d\n", n2);
+ printf (" got: %d\n", n1);
+ exit (1);
+ }
+
+#ifndef NPRINTF_L
+ check_vsprintf ("00000010610209857723, -1.2345678875e+07, 0.032258",
+ "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d);
+#endif
+
+ mpf_clear (mpf);
+ mpq_clear (mpq);
+ mpz_clear (mpz);
+ mpfr_clear (x);
+ return 0;
+}
+
+/* Check with locale "da_DK". On most platforms, decimal point is ','
+ and thousands separator is '.'; the test is not performed if this
+ is not the case or if the locale doesn't exist. */
+static int
+locale_da_DK (void)
+{
+ mpfr_prec_t p = 128;
+ mpfr_t x;
+
+ if (setlocale (LC_ALL, "da_DK") == 0 ||
+ localeconv()->decimal_point[0] != ',' ||
+ localeconv()->thousands_sep[0] != '.')
+ return 0;
+
+ mpfr_init2 (x, p);
+
+ /* positive numbers */
+ mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN);
+
+ /* simplest case right justified with thousands separator */
+ check_sprintf (" 1,899347461279296875e+07", "%'30Re", x);
+ check_sprintf (" 1,89935e+07", "%'30Rg", x);
+ check_sprintf (" 18.993.474,61279296875", "%'30.19Rg", x);
+ check_sprintf (" 18.993.474,612793", "%'30Rf", x);
+
+ /* sign or space, pad, thousands separator with leading zeros */
+ check_sprintf (" 000001,899347461279296875E+07", "%' 030RE", x);
+ check_sprintf (" 0000000000000000001,89935E+07", "%' 030RG", x);
+ check_sprintf (" 000000018.993.474,61279296875", "%' 030.19RG", x);
+ check_sprintf (" 00000000000018.993.474,612793", "%' 030RF", x);
+
+ mpfr_set_ui (x, 50, MPFR_RNDN);
+ mpfr_exp10 (x, x, MPFR_RNDN);
+ check_sprintf ("100000000000000000000000000000000000000000000000000", "%.0Rf",
+ x);
+ check_sprintf
+ ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,",
+ "%'#.0Rf", x);
+ check_sprintf
+ ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,0000",
+ "%'.4Rf", x);
+
+ mpfr_clear (x);
+ return 0;
+}
+
+/* check concordance between mpfr_asprintf result with a regular mpfr float
+ and with a regular double float */
+static int
+random_double (void)
+{
+ mpfr_t x; /* random regular mpfr float */
+ double y; /* regular double float (equal to x) */
+
+ char flag[] =
+ {
+ '-',
+ '+',
+ ' ',
+ '#',
+ '0', /* no ambiguity: first zeros are flag zero*/
+ '\''
+ };
+ /* no 'a': mpfr and glibc do not have the same semantic */
+ char specifier[] =
+ {
+ 'e',
+ 'f',
+ 'g',
+ 'E',
+ 'f', /* SUSv2 doesn't accept %F, but %F and %f are the same for
+ regular numbers */
+ 'G',
+ };
+ int spec; /* random index in specifier[] */
+ int prec; /* random value for precision field */
+
+ /* in the format string for mpfr_t variable, the maximum length is
+ reached by something like "%-+ #0'.*Rf", that is 12 characters. */
+#define FMT_MPFR_SIZE 12
+ char fmt_mpfr[FMT_MPFR_SIZE];
+ char *ptr_mpfr;
+
+ /* in the format string for double variable, the maximum length is
+ reached by something like "%-+ #0'.*f", that is 11 characters. */
+#define FMT_SIZE 11
+ char fmt[FMT_SIZE];
+ char *ptr;
+
+ int xi;
+ char *xs;
+ int yi;
+ char *ys;
+
+ int i, j, jmax;
+
+ mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
+
+ for (i = 0; i < 1000; ++i)
+ {
+ /* 1. random double */
+ do
+ {
+ y = DBL_RAND ();
+ }
+#ifdef HAVE_DENORMS
+ while (0);
+#else
+ while (ABS(y) < DBL_MIN);
+#endif
+
+ if (randlimb () % 2 == 0)
+ y = -y;
+
+ mpfr_set_d (x, y, MPFR_RNDN);
+ if (y != mpfr_get_d (x, MPFR_RNDN))
+ /* conversion error: skip this one */
+ continue;
+
+ /* 2. build random format strings fmt_mpfr and fmt */
+ ptr_mpfr = fmt_mpfr;
+ ptr = fmt;
+ *ptr_mpfr++ = *ptr++ = '%';
+ /* random specifier 'e', 'f', 'g', 'E', 'F', or 'G' */
+ spec = (int) (randlimb() % 6);
+ /* random flags, but no ' flag with %e */
+ jmax = (spec == 0 || spec == 3) ? 5 : 6;
+ for (j = 0; j < jmax; j++)
+ {
+ if (randlimb() % 3 == 0)
+ *ptr_mpfr++ = *ptr++ = flag[j];
+ }
+ *ptr_mpfr++ = *ptr++ = '.';
+ *ptr_mpfr++ = *ptr++ = '*';
+ *ptr_mpfr++ = 'R';
+ *ptr_mpfr++ = *ptr++ = specifier[spec];
+ *ptr_mpfr = *ptr = '\0';
+ MPFR_ASSERTN (ptr - fmt < FMT_SIZE);
+ MPFR_ASSERTN (ptr_mpfr - fmt_mpfr < FMT_MPFR_SIZE);
+
+ /* advantage small precision */
+ if (randlimb() % 2 == 0)
+ prec = (int) (randlimb() % 10);
+ else
+ prec = (int) (randlimb() % prec_max_printf);
+
+ /* 3. calls and checks */
+ /* the double float case is handled by the libc asprintf through
+ gmp_asprintf */
+ xi = mpfr_asprintf (&xs, fmt_mpfr, prec, x);
+ yi = mpfr_asprintf (&ys, fmt, prec, y);
+
+ /* test if XS and YS differ, beware that ISO C99 doesn't specify
+ the sign of a zero exponent (the C99 rationale says: "The sign
+ of a zero exponent in %e format is unspecified. The committee
+ knows of different implementations and choose not to require
+ implementations to document their behaviour in this case
+ (by making this be implementation defined behaviour). Most
+ implementations use a "+" sign, e.g., 1.2e+00; but there is at
+ least one implementation that uses the sign of the unlimited
+ precision result, e.g., the 0.987 would be 9.87e-01, so could
+ end up as 1e-00 after rounding to one digit of precision."),
+ while mpfr always uses '+' */
+ if (xi != yi
+ || ((strcmp (xs, ys) != 0)
+ && (spec == 1 || spec == 4
+ || ((strstr (xs, "e+00") == NULL
+ || strstr (ys, "e-00") == NULL)
+ && (strstr (xs, "E+00") == NULL
+ || strstr (ys, "E-00") == NULL)))))
+ {
+ mpfr_printf ("Error in mpfr_asprintf(\"%s\", %d, %Re)\n",
+ fmt_mpfr, prec, x);
+ printf ("expected: %s\n", ys);
+ printf (" got: %s\n", xs);
+ printf ("xi=%d yi=%d spec=%d\n", xi, yi, spec);
+
+ exit (1);
+ }
+
+ mpfr_free_str (xs);
+ mpfr_free_str (ys);
+ }
+
+ mpfr_clear (x);
+ return 0;
+}
+
+static void
+bug20080610 (void)
+{
+ /* bug on icc found on June 10, 2008 */
+ /* this is not a bug but a different implementation choice: ISO C99 doesn't
+ specify the sign of a zero exponent (see note in random_double above). */
+ mpfr_t x;
+ double y;
+ int xi;
+ char *xs;
+ int yi;
+ char *ys;
+
+ mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
+
+ y = -9.95645044213728791504536275169812142849e-01;
+ mpfr_set_d (x, y, MPFR_RNDN);
+
+ xi = mpfr_asprintf (&xs, "%- #0.*Re", 1, x);
+ yi = mpfr_asprintf (&ys, "%- #0.*e", 1, y);
+
+ if (xi != yi || strcmp (xs, ys) != 0)
+ {
+ printf ("Error in bug20080610\n");
+ printf ("expected: %s\n", ys);
+ printf (" got: %s\n", xs);
+ printf ("xi=%d yi=%d\n", xi, yi);
+
+ exit (1);
+ }
+
+ mpfr_free_str (xs);
+ mpfr_free_str (ys);
+ mpfr_clear (x);
+}
+
+static void
+bug20081214 (void)
+{
+ /* problem with glibc 2.3.6, December 14, 2008:
+ the system asprintf outputs "-1.0" instead of "-1.". */
+ mpfr_t x;
+ double y;
+ int xi;
+ char *xs;
+ int yi;
+ char *ys;
+
+ mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
+
+ y = -9.90597761233942053494e-01;
+ mpfr_set_d (x, y, MPFR_RNDN);
+
+ xi = mpfr_asprintf (&xs, "%- #0.*RG", 1, x);
+ yi = mpfr_asprintf (&ys, "%- #0.*G", 1, y);
+
+ if (xi != yi || strcmp (xs, ys) != 0)
+ {
+ mpfr_printf ("Error in bug20081214\n"
+ "mpfr_asprintf(\"%- #0.*Re\", 1, %Re)\n", x);
+ printf ("expected: %s\n", ys);
+ printf (" got: %s\n", xs);
+ printf ("xi=%d yi=%d\n", xi, yi);
+
+ exit (1);
+ }
+
+ mpfr_free_str (xs);
+ mpfr_free_str (ys);
+ mpfr_clear (x);
+}
+
+static void
+bug20111102 (void)
+{
+ mpfr_t t;
+ char s[100];
+
+ mpfr_init2 (t, 84);
+ mpfr_set_str (t, "999.99999999999999999999", 10, MPFR_RNDN);
+ mpfr_sprintf (s, "%.20RNg", t);
+ if (strcmp (s, "1000") != 0)
+ {
+ printf ("Error in bug20111102, expected 1000, got %s\n", s);
+ exit (1);
+ }
+ mpfr_clear (t);
+}
+
+/* In particular, the following test makes sure that the rounding
+ * for %Ra and %Rb is not done on the MPFR number itself (as it
+ * would overflow). Note: it has been reported on comp.std.c that
+ * some C libraries behave differently on %a, but this is a bug.
+ */
+static void
+check_emax_aux (mpfr_exp_t e)
+{
+ mpfr_t x;
+ char *s1, s2[256];
+ int i;
+ mpfr_exp_t emax;
+
+ MPFR_ASSERTN (e <= LONG_MAX);
+ emax = mpfr_get_emax ();
+ set_emax (e);
+
+ mpfr_init2 (x, 16);
+
+ mpfr_set_inf (x, 1);
+ mpfr_nextbelow (x);
+
+ i = mpfr_asprintf (&s1, "%Ra %.2Ra", x, x);
+ MPFR_ASSERTN (i > 0);
+
+ mpfr_snprintf (s2, 256, "0x7.fff8p+%ld 0x8.00p+%ld", e-3, e-3);
+
+ if (strcmp (s1, s2) != 0)
+ {
+ printf ("Error in check_emax_aux for emax = ");
+ if (e > LONG_MAX)
+ printf ("(>LONG_MAX)\n");
+ else
+ printf ("%ld\n", (long) e);
+ printf ("Expected %s\n", s2);
+ printf ("Got %s\n", s1);
+ exit (1);
+ }
+
+ mpfr_free_str (s1);
+
+ i = mpfr_asprintf (&s1, "%Rb %.2Rb", x, x);
+ MPFR_ASSERTN (i > 0);
+
+ mpfr_snprintf (s2, 256, "1.111111111111111p+%ld 1.00p+%ld", e-1, e);
+
+ if (strcmp (s1, s2) != 0)
+ {
+ printf ("Error in check_emax_aux for emax = ");
+ if (e > LONG_MAX)
+ printf ("(>LONG_MAX)\n");
+ else
+ printf ("%ld\n", (long) e);
+ printf ("Expected %s\n", s2);
+ printf ("Got %s\n", s1);
+ exit (1);
+ }
+
+ mpfr_free_str (s1);
+
+ mpfr_clear (x);
+ set_emax (emax);
+}
+
+static void
+check_emax (void)
+{
+ check_emax_aux (15);
+ check_emax_aux (MPFR_EMAX_MAX);
+}
+
+int
+main (int argc, char **argv)
+{
+ char *locale;
+
+ tests_start_mpfr ();
+
+#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
+ /* currently, we just check with 'C' locale */
+ locale = setlocale (LC_ALL, "C");
+#endif
+
+ bug20111102 ();
+ native_types ();
+ hexadecimal ();
+ binary ();
+ decimal ();
+ mixed ();
+ check_emax ();
+
+#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
+ locale_da_DK ();
+
+ setlocale (LC_ALL, locale);
+#endif
+
+ if (getenv ("MPFR_CHECK_LIBC_PRINTF"))
+ {
+ /* check against libc */
+ random_double ();
+ bug20081214 ();
+ bug20080610 ();
+ }
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else /* MPFR_VERSION */
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif /* MPFR_VERSION */
+
+#else /* HAVE_STDARG */
+
+int
+main (void)
+{
+ /* We have nothing to test. */
+ return 77;
+}
+
+#endif /* HAVE_STDARG */
diff --git a/mpfr/tests/tsqr.c b/mpfr/tests/tsqr.c
new file mode 100644
index 0000000000..15b249523d
--- /dev/null
+++ b/mpfr/tests/tsqr.c
@@ -0,0 +1,178 @@
+/* Test file for mpfr_sqr.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_sqr
+#include "tgeneric.c"
+
+static int
+inexact_sign (int x)
+{
+ return (x < 0) ? -1 : (x > 0);
+}
+
+static void
+error1 (mpfr_rnd_t rnd, mpfr_prec_t prec,
+ mpfr_t in, mpfr_t outmul, mpfr_t outsqr)
+{
+ printf("ERROR: for %s and prec=%lu\nINPUT=", mpfr_print_rnd_mode(rnd),
+ (unsigned long) prec);
+ mpfr_dump(in);
+ printf("OutputMul="); mpfr_dump(outmul);
+ printf("OutputSqr="); mpfr_dump(outsqr);
+ exit(1);
+}
+
+static void
+error2 (mpfr_rnd_t rnd, mpfr_prec_t prec, mpfr_t in, mpfr_t out,
+ int inexactmul, int inexactsqr)
+{
+ printf("ERROR: for %s and prec=%lu\nINPUT=", mpfr_print_rnd_mode(rnd),
+ (unsigned long) prec);
+ mpfr_dump(in);
+ printf("Output="); mpfr_dump(out);
+ printf("InexactMul= %d InexactSqr= %d\n", inexactmul, inexactsqr);
+ exit(1);
+}
+
+static void
+check_random (mpfr_prec_t p)
+{
+ mpfr_t x,y,z;
+ int r;
+ int i, inexact1, inexact2;
+
+ mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
+ for(i = 0 ; i < 500 ; i++)
+ {
+ mpfr_urandomb (x, RANDS);
+ if (MPFR_IS_PURE_FP(x))
+ for (r = 0 ; r < MPFR_RND_MAX ; r++)
+ {
+ inexact1 = mpfr_mul (y, x, x, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sqr (z, x, (mpfr_rnd_t) r);
+ if (mpfr_cmp (y, z))
+ error1 ((mpfr_rnd_t) r,p,x,y,z);
+ if (inexact_sign (inexact1) != inexact_sign (inexact2))
+ error2 ((mpfr_rnd_t) r,p,x,y,inexact1,inexact2);
+ }
+ }
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+}
+
+static void
+check_special (void)
+{
+ mpfr_t x, y;
+ mpfr_exp_t emin;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ mpfr_set_nan (x);
+ mpfr_sqr (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ mpfr_set_inf (x, 1);
+ mpfr_sqr (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0);
+
+ mpfr_set_inf (x, -1);
+ mpfr_sqr (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0);
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_sqr (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_zero_p (y));
+
+ emin = mpfr_get_emin ();
+ mpfr_set_emin (0);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_div_2ui (x, x, 1, MPFR_RNDN);
+ MPFR_ASSERTN (!mpfr_zero_p (x));
+ mpfr_sqr (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_zero_p (y));
+ mpfr_set_emin (emin);
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+/* Test of a bug seen with GCC 4.5.2 and GMP 5.0.1 on m68k (m68000 target).
+ https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00003.html
+ https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00041.html
+*/
+static void
+check_mpn_sqr (void)
+{
+#if GMP_NUMB_BITS == 32 && __GNU_MP_VERSION >= 5
+ /* Note: since we test a low-level bug, src is initialized
+ without using a GMP function, just in case. */
+ mp_limb_t src[5] =
+ { 0x90000000, 0xbaa55f4f, 0x2cbec4d9, 0xfcef3242, 0xda827999 };
+ mp_limb_t exd[10] =
+ { 0x00000000, 0x31000000, 0xbd4bc59a, 0x41fbe2b5, 0x33471e7e,
+ 0x90e826a7, 0xbaa55f4f, 0x2cbec4d9, 0xfcef3242, 0xba827999 };
+ mp_limb_t dst[10];
+ int i;
+
+ mpn_sqr (dst, src, 5); /* new in GMP 5 */
+ for (i = 0; i < 10; i++)
+ {
+ if (dst[i] != exd[i])
+ {
+ printf ("Error in check_mpn_sqr\n");
+ printf ("exd[%d] = 0x%08lx\n", i, (unsigned long) exd[i]);
+ printf ("dst[%d] = 0x%08lx\n", i, (unsigned long) dst[i]);
+ printf ("Note: This is not a bug in MPFR, but a bug in"
+ " either GMP or, more\nprobably, in the compiler."
+ " It may cause other tests to fail.\n");
+ exit (1);
+ }
+ }
+#endif
+}
+
+int
+main (void)
+{
+ mpfr_prec_t p;
+
+ tests_start_mpfr ();
+
+ check_mpn_sqr ();
+
+ check_special ();
+ for (p = 2; p < 200; p++)
+ check_random (p);
+
+ test_generic (2, 200, 15);
+ data_check ("data/sqr", mpfr_sqr, "mpfr_sqr");
+ bad_cases (mpfr_sqr, mpfr_sqrt, "mpfr_sqr", 8, -256, 255, 4, 128, 800, 50);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsqrt.c b/mpfr/tests/tsqrt.c
new file mode 100644
index 0000000000..f2f0d89002
--- /dev/null
+++ b/mpfr/tests/tsqrt.c
@@ -0,0 +1,709 @@
+/* Test file for mpfr_sqrt.
+
+Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_sqrt (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b);
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ }
+ res = mpfr_sqrt (a, b, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_sqrt mpfr_sqrt
+#endif
+
+static void
+check3 (const char *as, mpfr_rnd_t rnd_mode, const char *qs)
+{
+ mpfr_t q;
+
+ mpfr_init2 (q, 53);
+ mpfr_set_str1 (q, as);
+ test_sqrt (q, q, rnd_mode);
+ if (mpfr_cmp_str1 (q, qs) )
+ {
+ printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n",
+ as, mpfr_print_rnd_mode (rnd_mode));
+ printf ("expected sqrt is %s, got ",qs);
+ mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ mpfr_clear (q);
+}
+
+static void
+check4 (const char *as, mpfr_rnd_t rnd_mode, const char *Qs)
+{
+ mpfr_t q;
+
+ mpfr_init2 (q, 53);
+ mpfr_set_str1 (q, as);
+ test_sqrt (q, q, rnd_mode);
+ if (mpfr_cmp_str (q, Qs, 16, MPFR_RNDN))
+ {
+ printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n",
+ as, mpfr_print_rnd_mode(rnd_mode));
+ printf ("expected ");
+ mpfr_out_str (stdout, 16, 0, q, MPFR_RNDN);
+ printf ("\ngot %s\n", Qs);
+ mpfr_clear (q);
+ exit (1);
+ }
+ mpfr_clear (q);
+}
+
+static void
+check24 (const char *as, mpfr_rnd_t rnd_mode, const char *qs)
+{
+ mpfr_t q;
+
+ mpfr_init2 (q, 24);
+ mpfr_set_str1 (q, as);
+ test_sqrt (q, q, rnd_mode);
+ if (mpfr_cmp_str1 (q, qs))
+ {
+ printf ("mpfr_sqrt failed for a=%s, prec=24, rnd_mode=%s\n",
+ as, mpfr_print_rnd_mode(rnd_mode));
+ printf ("expected sqrt is %s, got ",qs);
+ mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clear (q);
+}
+
+static void
+check_diverse (const char *as, mpfr_prec_t p, const char *qs)
+{
+ mpfr_t q;
+
+ mpfr_init2 (q, p);
+ mpfr_set_str1 (q, as);
+ test_sqrt (q, q, MPFR_RNDN);
+ if (mpfr_cmp_str1 (q, qs))
+ {
+ printf ("mpfr_sqrt failed for a=%s, prec=%lu, rnd_mode=%s\n",
+ as, (unsigned long) p, mpfr_print_rnd_mode (MPFR_RNDN));
+ printf ("expected sqrt is %s, got ", qs);
+ mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clear (q);
+}
+
+/* the following examples come from the paper "Number-theoretic Test
+ Generation for Directed Rounding" from Michael Parks, Table 3 */
+static void
+check_float (void)
+{
+ check24("70368760954880.0", MPFR_RNDN, "8.388609e6");
+ check24("281474943156224.0", MPFR_RNDN, "1.6777215e7");
+ check24("70368777732096.0", MPFR_RNDN, "8.388610e6");
+ check24("281474909601792.0", MPFR_RNDN, "1.6777214e7");
+ check24("100216216748032.0", MPFR_RNDN, "1.0010805e7");
+ check24("120137273311232.0", MPFR_RNDN, "1.0960715e7");
+ check24("229674600890368.0", MPFR_RNDN, "1.5155019e7");
+ check24("70368794509312.0", MPFR_RNDN, "8.388611e6");
+ check24("281474876047360.0", MPFR_RNDN, "1.6777213e7");
+ check24("91214552498176.0", MPFR_RNDN, "9.550631e6");
+
+ check24("70368760954880.0", MPFR_RNDZ, "8.388608e6");
+ check24("281474943156224.0", MPFR_RNDZ, "1.6777214e7");
+ check24("70368777732096.0", MPFR_RNDZ, "8.388609e6");
+ check24("281474909601792.0", MPFR_RNDZ, "1.6777213e7");
+ check24("100216216748032.0", MPFR_RNDZ, "1.0010805e7");
+ check24("120137273311232.0", MPFR_RNDZ, "1.0960715e7");
+ check24("229674600890368.0", MPFR_RNDZ, "1.5155019e7");
+ check24("70368794509312.0", MPFR_RNDZ, "8.38861e6");
+ check24("281474876047360.0", MPFR_RNDZ, "1.6777212e7");
+ check24("91214552498176.0", MPFR_RNDZ, "9.550631e6");
+
+ check24("70368760954880.0", MPFR_RNDU, "8.388609e6");
+ check24("281474943156224.0",MPFR_RNDU, "1.6777215e7");
+ check24("70368777732096.0", MPFR_RNDU, "8.388610e6");
+ check24("281474909601792.0", MPFR_RNDU, "1.6777214e7");
+ check24("100216216748032.0", MPFR_RNDU, "1.0010806e7");
+ check24("120137273311232.0", MPFR_RNDU, "1.0960716e7");
+ check24("229674600890368.0", MPFR_RNDU, "1.515502e7");
+ check24("70368794509312.0", MPFR_RNDU, "8.388611e6");
+ check24("281474876047360.0", MPFR_RNDU, "1.6777213e7");
+ check24("91214552498176.0", MPFR_RNDU, "9.550632e6");
+
+ check24("70368760954880.0", MPFR_RNDD, "8.388608e6");
+ check24("281474943156224.0", MPFR_RNDD, "1.6777214e7");
+ check24("70368777732096.0", MPFR_RNDD, "8.388609e6");
+ check24("281474909601792.0", MPFR_RNDD, "1.6777213e7");
+ check24("100216216748032.0", MPFR_RNDD, "1.0010805e7");
+ check24("120137273311232.0", MPFR_RNDD, "1.0960715e7");
+ check24("229674600890368.0", MPFR_RNDD, "1.5155019e7");
+ check24("70368794509312.0", MPFR_RNDD, "8.38861e6");
+ check24("281474876047360.0", MPFR_RNDD, "1.6777212e7");
+ check24("91214552498176.0", MPFR_RNDD, "9.550631e6");
+
+ /* check that rounding away is just rounding toward plus infinity */
+ check24("91214552498176.0", MPFR_RNDA, "9.550632e6");
+}
+
+static void
+special (void)
+{
+ mpfr_t x, y, z;
+ int inexact;
+ mpfr_prec_t p;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ mpfr_set_prec (x, 64);
+ mpfr_set_str_binary (x, "1010000010100011011001010101010010001100001101011101110001011001E-1");
+ mpfr_set_prec (y, 32);
+ test_sqrt (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 2405743844UL))
+ {
+ printf ("Error for n^2+n+1/2 with n=2405743843\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 65);
+ mpfr_set_str_binary (x, "10100000101000110110010101010100100011000011010111011100010110001E-2");
+ mpfr_set_prec (y, 32);
+ test_sqrt (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 2405743844UL))
+ {
+ printf ("Error for n^2+n+1/4 with n=2405743843\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 66);
+ mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100011E-3");
+ mpfr_set_prec (y, 32);
+ test_sqrt (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 2405743844UL))
+ {
+ printf ("Error for n^2+n+1/4+1/8 with n=2405743843\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 66);
+ mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100001E-3");
+ mpfr_set_prec (y, 32);
+ test_sqrt (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 2405743843UL))
+ {
+ printf ("Error for n^2+n+1/8 with n=2405743843\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 27);
+ mpfr_set_str_binary (x, "0.110100111010101000010001011");
+ if ((inexact = test_sqrt (x, x, MPFR_RNDZ)) >= 0)
+ {
+ printf ("Wrong inexact flag: expected -1, got %d\n", inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ for (p=2; p<1000; p++)
+ {
+ mpfr_set_prec (z, p);
+ mpfr_set_ui (z, 1, MPFR_RNDN);
+ mpfr_nexttoinf (z);
+ test_sqrt (x, z, MPFR_RNDU);
+ if (mpfr_cmp_ui_2exp(x, 3, -1))
+ {
+ printf ("Error: sqrt(1+ulp(1), up) should give 1.5 (prec=%u)\n",
+ (unsigned int) p);
+ printf ("got "); mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+ }
+
+ /* check inexact flag */
+ mpfr_set_prec (x, 5);
+ mpfr_set_str_binary (x, "1.1001E-2");
+ if ((inexact = test_sqrt (x, x, MPFR_RNDN)))
+ {
+ printf ("Wrong inexact flag: expected 0, got %d\n", inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (z, 2);
+
+ /* checks the sign is correctly set */
+ mpfr_set_si (x, 1, MPFR_RNDN);
+ mpfr_set_si (z, -1, MPFR_RNDN);
+ test_sqrt (z, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 0) < 0)
+ {
+ printf ("Error: square root of 1 gives ");
+ mpfr_print_binary(z);
+ putchar('\n');
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 192);
+ mpfr_set_prec (z, 160);
+ mpfr_set_str_binary (z, "0.1011010100000100100100100110011001011100100100000011000111011001011101101101110000110100001000100001100001011000E1");
+ mpfr_set_prec (x, 160);
+ test_sqrt(x, z, MPFR_RNDN);
+ test_sqrt(z, x, MPFR_RNDN);
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_str (x, "8093416094703476.0", 10, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 1075, MPFR_RNDN);
+ test_sqrt (x, x, MPFR_RNDN);
+ mpfr_set_str (z, "1e55596835b5ef@-141", 16, MPFR_RNDN);
+ if (mpfr_cmp (x, z))
+ {
+ printf ("Error: square root of 8093416094703476*2^(-1075)\n");
+ printf ("expected "); mpfr_dump (z);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 33);
+ mpfr_set_str_binary (x, "0.111011011011110001100111111001000e-10");
+ mpfr_set_prec (z, 157);
+ inexact = test_sqrt (z, x, MPFR_RNDN);
+ mpfr_set_prec (x, 157);
+ mpfr_set_str_binary (x, "0.11110110101100101111001011100011100011100001101010111011010000100111011000111110100001001011110011111100101110010110010110011001011011010110010000011001101E-5");
+ if (mpfr_cmp (x, z))
+ {
+ printf ("Error: square root (1)\n");
+ exit (1);
+ }
+ if (inexact <= 0)
+ {
+ printf ("Error: wrong inexact flag (1)\n");
+ exit (1);
+ }
+
+ /* case prec(result) << prec(input) */
+ mpfr_set_prec (z, 2);
+ for (p = 2; p < 1000; p++)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_nextabove (x);
+ /* 1.0 < x <= 1.5 thus 1 < sqrt(x) <= 1.23 */
+ inexact = test_sqrt (z, x, MPFR_RNDN);
+ MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
+ inexact = test_sqrt (z, x, MPFR_RNDZ);
+ MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
+ inexact = test_sqrt (z, x, MPFR_RNDU);
+ MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
+ inexact = test_sqrt (z, x, MPFR_RNDD);
+ MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
+ inexact = test_sqrt (z, x, MPFR_RNDA);
+ MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
+ }
+
+ /* corner case rw = 0 in rounding to nearest */
+ mpfr_set_prec (z, GMP_NUMB_BITS - 1);
+ mpfr_set_prec (y, GMP_NUMB_BITS - 1);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_mul_2exp (y, y, GMP_NUMB_BITS - 1, MPFR_RNDN);
+ mpfr_nextabove (y);
+ for (p = 2 * GMP_NUMB_BITS - 1; p <= 1000; p++)
+ {
+ mpfr_set_prec (x, p);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_exp (x, GMP_NUMB_BITS);
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ /* now x = 2^(GMP_NUMB_BITS - 1) + 1 (GMP_NUMB_BITS bits) */
+ MPFR_ASSERTN (mpfr_mul (x, x, x, MPFR_RNDN) == 0); /* exact */
+ inexact = test_sqrt (z, x, MPFR_RNDN);
+ /* even rule: z should be 2^(GMP_NUMB_BITS - 1) */
+ MPFR_ASSERTN (inexact < 0);
+ MPFR_ASSERTN (mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0);
+ mpfr_nextbelow (x);
+ /* now x is just below [2^(GMP_NUMB_BITS - 1) + 1]^2 */
+ inexact = test_sqrt (z, x, MPFR_RNDN);
+ MPFR_ASSERTN(inexact < 0 &&
+ mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0);
+ mpfr_nextabove (x);
+ mpfr_nextabove (x);
+ /* now x is just above [2^(GMP_NUMB_BITS - 1) + 1]^2 */
+ inexact = test_sqrt (z, x, MPFR_RNDN);
+ if (mpfr_cmp (z, y))
+ {
+ printf ("Error for sqrt(x) in rounding to nearest\n");
+ printf ("x="); mpfr_dump (x);
+ printf ("Expected "); mpfr_dump (y);
+ printf ("Got "); mpfr_dump (z);
+ exit (1);
+ }
+ if (inexact <= 0)
+ {
+ printf ("Wrong inexact flag in corner case for p = %lu\n", (unsigned long) p);
+ exit (1);
+ }
+ }
+
+ mpfr_set_prec (x, 1000);
+ mpfr_set_ui (x, 9, MPFR_RNDN);
+ mpfr_set_prec (y, 10);
+ inexact = test_sqrt (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 3) || inexact != 0)
+ {
+ printf ("Error in sqrt(9:1000) for prec=10\n");
+ exit (1);
+ }
+ mpfr_set_prec (y, GMP_NUMB_BITS);
+ mpfr_nextabove (x);
+ inexact = test_sqrt (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 3) || inexact >= 0)
+ {
+ printf ("Error in sqrt(9:1000) for prec=%d\n", (int) GMP_NUMB_BITS);
+ exit (1);
+ }
+ mpfr_set_prec (x, 2 * GMP_NUMB_BITS);
+ mpfr_set_prec (y, GMP_NUMB_BITS);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_nextabove (y);
+ mpfr_set (x, y, MPFR_RNDN);
+ inexact = test_sqrt (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1) || inexact >= 0)
+ {
+ printf ("Error in sqrt(1) for prec=%d\n", (int) GMP_NUMB_BITS);
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+check_inexact (mpfr_prec_t p)
+{
+ mpfr_t x, y, z;
+ mpfr_rnd_t rnd;
+ int inexact, sign;
+
+ mpfr_init2 (x, p);
+ mpfr_init2 (y, p);
+ mpfr_init2 (z, 2*p);
+ mpfr_urandomb (x, RANDS);
+ rnd = RND_RAND ();
+ inexact = test_sqrt (y, x, rnd);
+ if (mpfr_mul (z, y, y, rnd)) /* exact since prec(z) = 2*prec(y) */
+ {
+ printf ("Error: multiplication should be exact\n");
+ exit (1);
+ }
+ mpfr_sub (z, z, x, rnd); /* exact also */
+ sign = mpfr_cmp_ui (z, 0);
+ if (((inexact == 0) && (sign)) ||
+ ((inexact > 0) && (sign <= 0)) ||
+ ((inexact < 0) && (sign >= 0)))
+ {
+ printf ("Error: wrong inexact flag, expected %d, got %d\n",
+ sign, inexact);
+ printf ("x=");
+ mpfr_print_binary (x);
+ printf (" rnd=%s\n", mpfr_print_rnd_mode (rnd));
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+check_singular (void)
+{
+ mpfr_t x, got;
+
+ mpfr_init2 (x, 100L);
+ mpfr_init2 (got, 100L);
+
+ /* sqrt(NaN) == NaN */
+ MPFR_SET_NAN (x);
+ MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_nan_p (got));
+
+ /* sqrt(-1) == NaN */
+ mpfr_set_si (x, -1L, MPFR_RNDZ);
+ MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_nan_p (got));
+
+ /* sqrt(+inf) == +inf */
+ MPFR_SET_INF (x);
+ MPFR_SET_POS (x);
+ MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (got));
+
+ /* sqrt(-inf) == NaN */
+ MPFR_SET_INF (x);
+ MPFR_SET_NEG (x);
+ MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_nan_p (got));
+
+ /* sqrt(+0) == +0 */
+ mpfr_set_si (x, 0L, MPFR_RNDZ);
+ MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_number_p (got));
+ MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0);
+ MPFR_ASSERTN (MPFR_IS_POS (got));
+
+ /* sqrt(-0) == -0 */
+ mpfr_set_si (x, 0L, MPFR_RNDZ);
+ MPFR_SET_NEG (x);
+ MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_number_p (got));
+ MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0);
+ MPFR_ASSERTN (MPFR_IS_NEG (got));
+
+ mpfr_clear (x);
+ mpfr_clear (got);
+}
+
+/* check that -1 <= x/sqrt(x^2+s*y^2) <= 1 for rounding to nearest or up
+ with s = 0 and s = 1 */
+static void
+test_property1 (mpfr_prec_t p, mpfr_rnd_t r, int s)
+{
+ mpfr_t x, y, z, t;
+
+ mpfr_init2 (x, p);
+ mpfr_init2 (y, p);
+ mpfr_init2 (z, p);
+ mpfr_init2 (t, p);
+
+ mpfr_urandomb (x, RANDS);
+ mpfr_mul (z, x, x, r);
+ if (s)
+ {
+ mpfr_urandomb (y, RANDS);
+ mpfr_mul (t, y, y, r);
+ mpfr_add (z, z, t, r);
+ }
+ mpfr_sqrt (z, z, r);
+ mpfr_div (z, x, z, r);
+ /* Note: if both x and y are 0, z is NAN, but the test below will
+ be false. So, everything is fine. */
+ if (mpfr_cmp_si (z, -1) < 0 || mpfr_cmp_ui (z, 1) > 0)
+ {
+ printf ("Error, -1 <= x/sqrt(x^2+y^2) <= 1 does not hold for r=%s\n",
+ mpfr_print_rnd_mode (r));
+ printf ("x="); mpfr_dump (x);
+ printf ("y="); mpfr_dump (y);
+ printf ("got "); mpfr_dump (z);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+}
+
+/* check sqrt(x^2) = x */
+static void
+test_property2 (mpfr_prec_t p, mpfr_rnd_t r)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, p);
+ mpfr_init2 (y, p);
+
+ mpfr_urandomb (x, RANDS);
+ mpfr_mul (y, x, x, r);
+ mpfr_sqrt (y, y, r);
+ if (mpfr_cmp (y, x))
+ {
+ printf ("Error, sqrt(x^2) = x does not hold for r=%s\n",
+ mpfr_print_rnd_mode (r));
+ printf ("x="); mpfr_dump (x);
+ printf ("got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION test_sqrt
+#define TEST_RANDOM_POS 8
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_prec_t p;
+ int k;
+
+ tests_start_mpfr ();
+
+ for (p = MPFR_PREC_MIN; p <= 128; p++)
+ {
+ test_property1 (p, MPFR_RNDN, 0);
+ test_property1 (p, MPFR_RNDU, 0);
+ test_property1 (p, MPFR_RNDA, 0);
+ test_property1 (p, MPFR_RNDN, 1);
+ test_property1 (p, MPFR_RNDU, 1);
+ test_property1 (p, MPFR_RNDA, 1);
+ test_property2 (p, MPFR_RNDN);
+ }
+
+ check_diverse ("635030154261163106768013773815762607450069292760790610550915652722277604820131530404842415587328", 160, "796887792767063979679855997149887366668464780637");
+ special ();
+ check_singular ();
+
+ for (p=2; p<200; p++)
+ for (k=0; k<200; k++)
+ check_inexact (p);
+ check_float();
+
+ check3 ("-0.0", MPFR_RNDN, "0.0");
+ check4 ("6.37983013646045901440e+32", MPFR_RNDN, "5.9bc5036d09e0c@13");
+ check4 ("1.0", MPFR_RNDN, "1");
+ check4 ("1.0", MPFR_RNDZ, "1");
+ check4 ("3.725290298461914062500000e-9", MPFR_RNDN, "4@-4");
+ check4 ("3.725290298461914062500000e-9", MPFR_RNDZ, "4@-4");
+ check4 ("1190456976439861.0", MPFR_RNDZ, "2.0e7957873529a@6");
+ check4 ("1219027943874417664.0", MPFR_RNDZ, "4.1cf2af0e6a534@7");
+ /* the following examples are bugs in Cygnus compiler/system, found by
+ Fabrice Rouillier while porting mpfr to Windows */
+ check4 ("9.89438396044940256501e-134", MPFR_RNDU, "8.7af7bf0ebbee@-56");
+ check4 ("7.86528588050363751914e+31", MPFR_RNDZ, "1.f81fc40f32062@13");
+ check4 ("0.99999999999999988897", MPFR_RNDN, "f.ffffffffffff8@-1");
+ check4 ("1.00000000000000022204", MPFR_RNDN, "1");
+ /* the following examples come from the paper "Number-theoretic Test
+ Generation for Directed Rounding" from Michael Parks, Table 4 */
+
+ check4 ("78652858805036375191418371571712.0", MPFR_RNDN,
+ "1.f81fc40f32063@13");
+ check4 ("38510074998589467860312736661504.0", MPFR_RNDN,
+ "1.60c012a92fc65@13");
+ check4 ("35318779685413012908190921129984.0", MPFR_RNDN,
+ "1.51d17526c7161@13");
+ check4 ("26729022595358440976973142425600.0", MPFR_RNDN,
+ "1.25e19302f7e51@13");
+ check4 ("22696567866564242819241453027328.0", MPFR_RNDN,
+ "1.0ecea7dd2ec3d@13");
+ check4 ("22696888073761729132924856434688.0", MPFR_RNDN,
+ "1.0ecf250e8e921@13");
+ check4 ("36055652513981905145251657416704.0", MPFR_RNDN,
+ "1.5552f3eedcf33@13");
+ check4 ("30189856268896404997497182748672.0", MPFR_RNDN,
+ "1.3853ee10c9c99@13");
+ check4 ("36075288240584711210898775080960.0", MPFR_RNDN,
+ "1.556abe212b56f@13");
+ check4 ("72154663483843080704304789585920.0", MPFR_RNDN,
+ "1.e2d9a51977e6e@13");
+
+ check4 ("78652858805036375191418371571712.0", MPFR_RNDZ,
+ "1.f81fc40f32062@13");
+ check4 ("38510074998589467860312736661504.0", MPFR_RNDZ,
+ "1.60c012a92fc64@13");
+ check4 ("35318779685413012908190921129984.0", MPFR_RNDZ, "1.51d17526c716@13");
+ check4 ("26729022595358440976973142425600.0", MPFR_RNDZ, "1.25e19302f7e5@13");
+ check4 ("22696567866564242819241453027328.0", MPFR_RNDZ,
+ "1.0ecea7dd2ec3c@13");
+ check4 ("22696888073761729132924856434688.0", MPFR_RNDZ, "1.0ecf250e8e92@13");
+ check4 ("36055652513981905145251657416704.0", MPFR_RNDZ,
+ "1.5552f3eedcf32@13");
+ check4 ("30189856268896404997497182748672.0", MPFR_RNDZ,
+ "1.3853ee10c9c98@13");
+ check4 ("36075288240584711210898775080960.0", MPFR_RNDZ,
+ "1.556abe212b56e@13");
+ check4 ("72154663483843080704304789585920.0", MPFR_RNDZ,
+ "1.e2d9a51977e6d@13");
+
+ check4 ("78652858805036375191418371571712.0", MPFR_RNDU,
+ "1.f81fc40f32063@13");
+ check4 ("38510074998589467860312736661504.0", MPFR_RNDU,
+ "1.60c012a92fc65@13");
+ check4 ("35318779685413012908190921129984.0", MPFR_RNDU,
+ "1.51d17526c7161@13");
+ check4 ("26729022595358440976973142425600.0", MPFR_RNDU,
+ "1.25e19302f7e51@13");
+ check4 ("22696567866564242819241453027328.0", MPFR_RNDU,
+ "1.0ecea7dd2ec3d@13");
+ check4 ("22696888073761729132924856434688.0", MPFR_RNDU,
+ "1.0ecf250e8e921@13");
+ check4 ("36055652513981905145251657416704.0", MPFR_RNDU,
+ "1.5552f3eedcf33@13");
+ check4 ("30189856268896404997497182748672.0", MPFR_RNDU,
+ "1.3853ee10c9c99@13");
+ check4 ("36075288240584711210898775080960.0", MPFR_RNDU,
+ "1.556abe212b56f@13");
+ check4 ("72154663483843080704304789585920.0", MPFR_RNDU,
+ "1.e2d9a51977e6e@13");
+
+ check4 ("78652858805036375191418371571712.0", MPFR_RNDD,
+ "1.f81fc40f32062@13");
+ check4 ("38510074998589467860312736661504.0", MPFR_RNDD,
+ "1.60c012a92fc64@13");
+ check4 ("35318779685413012908190921129984.0", MPFR_RNDD, "1.51d17526c716@13");
+ check4 ("26729022595358440976973142425600.0", MPFR_RNDD, "1.25e19302f7e5@13");
+ check4 ("22696567866564242819241453027328.0", MPFR_RNDD,
+ "1.0ecea7dd2ec3c@13");
+ check4 ("22696888073761729132924856434688.0", MPFR_RNDD, "1.0ecf250e8e92@13");
+ check4 ("36055652513981905145251657416704.0", MPFR_RNDD,
+ "1.5552f3eedcf32@13");
+ check4 ("30189856268896404997497182748672.0", MPFR_RNDD,
+ "1.3853ee10c9c98@13");
+ check4 ("36075288240584711210898775080960.0", MPFR_RNDD,
+ "1.556abe212b56e@13");
+ check4 ("72154663483843080704304789585920.0", MPFR_RNDD,
+ "1.e2d9a51977e6d@13");
+
+ /* check that rounding away is just rounding toward plus infinity */
+ check4 ("72154663483843080704304789585920.0", MPFR_RNDA,
+ "1.e2d9a51977e6e@13");
+
+ test_generic (2, 300, 15);
+ data_check ("data/sqrt", mpfr_sqrt, "mpfr_sqrt");
+ bad_cases (mpfr_sqrt, mpfr_sqr, "mpfr_sqrt", 8, -256, 255, 4, 128, 800, 50);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsqrt_ui.c b/mpfr/tests/tsqrt_ui.c
new file mode 100644
index 0000000000..28e2c1402f
--- /dev/null
+++ b/mpfr/tests/tsqrt_ui.c
@@ -0,0 +1,56 @@
+/* Test file for mpfr_sqrt_ui.
+
+Copyright 2000, 2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+check (unsigned long a, mpfr_rnd_t rnd_mode, const char *qs)
+{
+ mpfr_t q;
+
+ mpfr_init2 (q, 53);
+ mpfr_sqrt_ui (q, a, rnd_mode);
+ if (mpfr_cmp_str1 (q, qs))
+ {
+ printf ("mpfr_sqrt_ui failed for a=%lu, rnd_mode=%s\n",
+ a, mpfr_print_rnd_mode (rnd_mode));
+ printf ("sqrt gives %s, mpfr_sqrt_ui gives ", qs);
+ mpfr_out_str(stdout, 10, 0, q, MPFR_RNDN);
+ exit (1);
+ }
+ mpfr_clear (q);
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+
+ check (0, MPFR_RNDN, "0.0");
+ check (2116118, MPFR_RNDU, "1.45468828276026215e3");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tstckintc.c b/mpfr/tests/tstckintc.c
new file mode 100644
index 0000000000..dd5e0d9dfe
--- /dev/null
+++ b/mpfr/tests/tstckintc.c
@@ -0,0 +1,228 @@
+/* Test file for mpfr_custom_*
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define BUFFER_SIZE 250
+#define PREC_TESTED 200
+
+long Buffer[BUFFER_SIZE];
+char *stack = (char *) Buffer;
+mpfr_prec_t p = PREC_TESTED;
+
+#define ALIGNED(s) (((s) + sizeof (long) - 1) / sizeof (long) * sizeof (long))
+
+static void *
+new_st (size_t s)
+{
+ void *p = (void *) stack;
+ stack += ALIGNED (s);
+ if (MPFR_UNLIKELY (stack > (char *) &Buffer[BUFFER_SIZE]))
+ {
+ printf ("Stack overflow.\n");
+ exit (1);
+ }
+ return p;
+}
+
+ /* Alloc a new mpfr_t on the main stack */
+static mpfr_ptr
+new_mpfr (mpfr_prec_t p)
+{
+ mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t));
+ void *mantissa = new_st (mpfr_custom_get_size (p));
+ mpfr_custom_init (mantissa, p);
+ mpfr_custom_init_set (x, 0, 0, p, mantissa);
+ return x;
+}
+
+ /* Garbage the stack by keeping only x */
+static mpfr_ptr
+return_mpfr (mpfr_ptr x, char *old_stack)
+{
+ void *mantissa = mpfr_custom_get_significand (x);
+ size_t size_mantissa = mpfr_custom_get_size (mpfr_get_prec (x));
+ mpfr_ptr newx;
+
+ memmove (old_stack, x, sizeof (mpfr_t));
+ memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa);
+ newx = (mpfr_ptr) old_stack;
+ mpfr_custom_move (newx, old_stack + ALIGNED (sizeof (mpfr_t)));
+ stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa);
+ return newx;
+}
+
+static void
+test1 (void)
+{
+ mpfr_ptr x, y;
+ char *org;
+
+ org = stack;
+ x = new_mpfr (p);
+ y = new_mpfr (p);
+ mpfr_set_ui (x, 42, MPFR_RNDN);
+ mpfr_set_ui (y, 17, MPFR_RNDN);
+ mpfr_add (y, x, y, MPFR_RNDN);
+ y = return_mpfr (y, org);
+ if (y != x || mpfr_cmp_ui (y, 59) != 0)
+ {
+ printf ("Compact (1) failed!\n");
+ exit (1);
+ }
+ stack = org;
+}
+
+/* We build the MPFR variable each time it is needed */
+/* a[0] is the kind, a[1] is the exponent, &a[2] is the mantissa */
+static long *
+dummy_new (void)
+{
+ long *r;
+
+ r = (long *) new_st (ALIGNED (2 * sizeof (long)) +
+ ALIGNED (mpfr_custom_get_size (p)));
+ MPFR_ASSERTN (r != NULL);
+ (mpfr_custom_init) (&r[2], p);
+ r[0] = (int) MPFR_NAN_KIND;
+ r[1] = 0;
+ return r;
+}
+
+static long *
+dummy_set_si (long si)
+{
+ mpfr_t x;
+ long * r = dummy_new ();
+ (mpfr_custom_init_set) (x, 0, 0, p, &r[2]);
+ mpfr_set_si (x, si, MPFR_RNDN);
+ r[0] = mpfr_custom_get_kind (x);
+ r[1] = mpfr_custom_get_exp (x);
+ return r;
+}
+
+static long *
+dummy_add (long *a, long *b)
+{
+ mpfr_t x, y, z;
+ long *r = dummy_new ();
+ mpfr_custom_init_set (x, 0, 0, p, &r[2]);
+ (mpfr_custom_init_set) (y, a[0], a[1], p, &a[2]);
+ mpfr_custom_init_set (z, b[0], b[1], p, &b[2]);
+ mpfr_add (x, y, z, MPFR_RNDN);
+ r[0] = (mpfr_custom_get_kind) (x);
+ r[1] = (mpfr_custom_get_exp) (x);
+ return r;
+}
+
+static long *
+dummy_compact (long *r, char *org_stack)
+{
+ memmove (org_stack, r,
+ ALIGNED (2*sizeof (long)) + ALIGNED ((mpfr_custom_get_size) (p)));
+ return (long *) org_stack;
+}
+
+static void
+test2 (void)
+{
+ mpfr_t x;
+ char *org = stack;
+ long *a, *b, *c;
+
+ a = dummy_set_si (42);
+ b = dummy_set_si (17);
+ c = dummy_add (a, b);
+ c = dummy_compact (c, org);
+ (mpfr_custom_init_set) (x, c[0], c[1], p, &c[2]);
+ if (c != a || mpfr_cmp_ui (x, 59) != 0)
+ {
+ printf ("Compact (2) failed! c=%p a=%p\n", (void *) c, (void *) a);
+ mpfr_dump (x);
+ exit (1);
+ }
+ stack = org;
+}
+
+static void
+test_nan_inf_zero (void)
+{
+ mpfr_ptr val;
+ int sign;
+ int kind;
+ char *org = stack;
+
+ val = new_mpfr (MPFR_PREC_MIN);
+
+ mpfr_set_nan (val);
+ kind = (mpfr_custom_get_kind) (val);
+ if (kind != MPFR_NAN_KIND)
+ {
+ printf ("mpfr_custom_get_kind error : ");
+ mpfr_dump (val);
+ printf (" is kind %d instead of %d\n", kind, MPFR_NAN_KIND);
+ exit (1);
+ }
+
+ sign = 1;
+ mpfr_set_inf (val, sign);
+ kind = (mpfr_custom_get_kind) (val);
+ if ((ABS (kind) != MPFR_INF_KIND) || (SIGN (kind) != SIGN (sign)))
+ {
+ printf ("mpfr_custom_get_kind error : ");
+ mpfr_dump (val);
+ printf (" is kind %d instead of %d\n", kind, MPFR_INF_KIND);
+ printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign));
+ exit (1);
+ }
+
+ sign = -1;
+ mpfr_set_zero (val, sign);
+ kind = (mpfr_custom_get_kind) (val);
+ if ((ABS (kind) != MPFR_ZERO_KIND) || (SIGN (kind) != SIGN (sign)))
+ {
+ printf ("mpfr_custom_get_kind error : ");
+ mpfr_dump (val);
+ printf (" is kind %d instead of %d\n", kind, MPFR_ZERO_KIND);
+ printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign));
+ exit (1);
+ }
+
+ stack = org;
+}
+
+int
+main (void)
+{
+ tests_start_mpfr ();
+ /* We test iff long = mp_limb_t */
+ if (sizeof (long) == sizeof (mp_limb_t))
+ {
+ test1 ();
+ test2 ();
+ test_nan_inf_zero ();
+ }
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tstdint.c b/mpfr/tests/tstdint.c
new file mode 100644
index 0000000000..73ea022e4f
--- /dev/null
+++ b/mpfr/tests/tstdint.c
@@ -0,0 +1,63 @@
+/* Test file for multiple mpfr.h inclusion and intmax_t related functions
+
+Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#if HAVE_STDINT_H
+
+#if _MPFR_EXP_FORMAT == 4
+/* If mpfr_exp_t is defined as intmax_t, intmax_t must be defined before
+ the inclusion of mpfr.h (this test doesn't use mpfr-impl.h). */
+# include <stdint.h>
+#endif
+
+/* Assume that this is in fact a header inclusion for some library
+ that uses MPFR, i.e. this inclusion is hidden in another one.
+ MPFR currently (rev 6704) fails to handle this case. */
+#include <mpfr.h>
+
+#include <stdint.h>
+
+#define MPFR_USE_INTMAX_T
+#include <mpfr.h>
+
+int
+main (void)
+{
+ mpfr_t x;
+ intmax_t j;
+
+ mpfr_init_set_ui (x, 1, MPFR_RNDN);
+ j = mpfr_get_uj (x, MPFR_RNDN);
+ mpfr_clear (x);
+ return j == 1 ? 0 : 1;
+}
+
+#else /* HAVE_STDINT_H */
+
+/* The test is disabled. */
+
+int
+main (void)
+{
+ return 77;
+}
+
+#endif /* HAVE_STDINT_H */
diff --git a/mpfr/tests/tstrtofr.c b/mpfr/tests/tstrtofr.c
new file mode 100644
index 0000000000..cefce22e27
--- /dev/null
+++ b/mpfr/tests/tstrtofr.c
@@ -0,0 +1,1211 @@
+/* Test file for mpfr_set_str.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+check_special (void)
+{
+ mpfr_t x, y;
+ int res;
+ char *s;
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* Check dummy case */
+ res = mpfr_strtofr (x, "1234567.89E1", NULL, 10, MPFR_RNDN);
+ mpfr_set_str (y, "1234567.89E1", 10, MPFR_RNDN);
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Results differ between strtofr and set_str.\n"
+ " set_str gives: ");
+ mpfr_dump (y);
+ printf (" strtofr gives: ");
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ /* Check NAN */
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
+ res = mpfr_strtofr (x, "NaN", &s, 10, MPFR_RNDN);
+ if (res != 0 || !mpfr_nan_p (x) || *s != 0)
+ {
+ printf ("Error for setting NAN (1)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
+ res = mpfr_strtofr (x, "+NaN", &s, 10, MPFR_RNDN);
+ if (res != 0 || !mpfr_nan_p (x) || *s != 0)
+ {
+ printf ("Error for setting +NAN (1)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
+ res = mpfr_strtofr (x, " -NaN", &s, 10, MPFR_RNDN);
+ if (res != 0 || !mpfr_nan_p (x) || *s != 0)
+ {
+ printf ("Error for setting -NAN (1)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
+ res = mpfr_strtofr (x, "@nAn@xx", &s, 16, MPFR_RNDN);
+ if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "xx") )
+ {
+ printf ("Error for setting NAN (2)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
+ res = mpfr_strtofr (x, "NAN(abcdEDF__1256)Hello", &s, 10, MPFR_RNDN);
+ if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "Hello") )
+ {
+ printf ("Error for setting NAN (3)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
+ res = mpfr_strtofr (x, "NAN(abcdEDF)__1256)Hello", &s, 10, MPFR_RNDN);
+ if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "__1256)Hello") )
+ {
+ printf ("Error for setting NAN (4)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
+ res = mpfr_strtofr (x, "NAN(abc%dEDF)__1256)Hello", &s, 10, MPFR_RNDN);
+ if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "(abc%dEDF)__1256)Hello") )
+ {
+ printf ("Error for setting NAN (5)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
+ res = mpfr_strtofr (x, "NAN((abc))", &s, 10, MPFR_RNDN);
+ if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "((abc))") )
+ {
+ printf ("Error for setting NAN (6)\n");
+ exit (1);
+ }
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
+ res = mpfr_strtofr (x, "NAN()foo", &s, 10, MPFR_RNDN);
+ if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "foo") )
+ {
+ printf ("Error for setting NAN (7)\n");
+ exit (1);
+ }
+
+ /* Check INF */
+ res = mpfr_strtofr (x, "INFINITY", &s, 8, MPFR_RNDN);
+ if (res != 0 || !mpfr_inf_p (x) || *s != 0)
+ {
+ printf ("Error for setting INFINITY (1)\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "INFANITY", &s, 8, MPFR_RNDN);
+ if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "ANITY"))
+ {
+ printf ("Error for setting INFINITY (2)\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "@INF@*2", &s, 11, MPFR_RNDN);
+ if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "*2"))
+ {
+ printf ("Error for setting INFINITY (3)\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ /* Check Zero */
+ res = mpfr_strtofr (x, " 00000", &s, 11, MPFR_RNDN);
+ if (res != 0 || !mpfr_zero_p (x) || s[0] != 0)
+ {
+ printf ("Error for setting ZERO (1)\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ /* Check base 62 */
+ res = mpfr_strtofr (x, "A", NULL, 62, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 10))
+ {
+ printf ("Error for setting 'A' in base 62\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "a", NULL, 62, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 36))
+ {
+ printf ("Error for setting 'a' in base 62\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "Z", NULL, 62, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 35))
+ {
+ printf ("Error for setting 'Z' in base 62\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "z", NULL, 62, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 61))
+ {
+ printf ("Error for setting 'z' in base 62\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "ZA", NULL, 62, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 2180))
+ {
+ printf ("Error for setting 'ZA' in base 62\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "za", NULL, 62, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 3818))
+ {
+ printf ("Error for setting 'za' in base 62\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "aZ", NULL, 62, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 2267))
+ {
+ printf ("Error for setting 'aZ' in base 62\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "Az", NULL, 62, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 681))
+ {
+ printf ("Error for setting 'Az' in base 62\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+
+ /* Check base 60 */
+ res = mpfr_strtofr (x, "Aa", NULL, 60, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 636))
+ {
+ printf ("Error for setting 'Aa' in base 60\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ res = mpfr_strtofr (x, "Zz", &s, 60, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 35) || strcmp(s, "z") )
+ {
+ printf ("Error for setting 'Zz' in base 60\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+
+ /* Check base 61 */
+ res = mpfr_strtofr (x, "z", &s, 61, MPFR_RNDN);
+ if (res != 0 || mpfr_cmp_ui (x, 0) || strcmp(s, "z") )
+ {
+ printf ("Error for setting 'z' in base 61\n x=");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+/* The following RefTable has been generated by this following code */
+#if 0
+#define MAX_NUM 100
+
+int randomab (int a, int b)
+{
+ return a + rand () % (b-a);
+}
+
+int
+main (void)
+{
+ int i, base;
+ mpfr_t x;
+ mpfr_prec_t p;
+ mpfr_exp_t e;
+
+ mpfr_init (x);
+ printf ("struct dymmy_test { \n"
+ " mpfr_prec_t prec; \n"
+ " int base; \n"
+ " const char *str; \n"
+ " const char *binstr; \n"
+ " } RefTable[] = { \n");
+ for (i = 0 ; i < MAX_NUM ; i++)
+ {
+ p = randomab(2, 180);
+ base = randomab (2, 30);
+ e = randomab (-1<<15, 1<<15);
+ mpfr_set_prec (x, p);
+ mpfr_urandomb (x, RANDS);
+ mpfr_mul_2si (x, x, e, MPFR_RNDN);
+ printf("{%lu, %d,\n\"", p, base);
+ mpfr_out_str (stdout, base, p, x, MPFR_RNDN);
+ printf ("\",\n\"");
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
+ printf ("\"}%c\n", i == MAX_NUM-1 ? ' ' : ',' );
+ }
+ printf("};\n");
+ mpfr_clear (x);
+}
+#endif
+
+static struct dymmy_test {
+ mpfr_prec_t prec;
+ int base;
+ const char *str;
+ const char *binstr;
+ } RefTable[] = {
+{39, 20,
+"1.1c9jeh9jg12d8iiggf26b8ce2cig24agai51d9@1445",
+"1.00111010111010001110110001101011101011e6245"},
+{119, 3,
+"1.2210112120221020220021000020101121120011021202212101222000011110211211122222001001221110102220122021121021101010120101e-5655",
+"1.1111101110011110001101011100011000011100001011011100010011010010001000000111001010000001110111010100011000110010000000e-8963"},
+{166, 18,
+"3.ecg67g31434b74d8hhbe2dbbb46g9546cae72cae0cfghfh00ed7gebe9ca63b47h08bgbdeb880a76dea12he31e1ccd67e9dh22a911b46h517b745169b2g43egg2e4eah820cdb2132d6a4f9c63505dd4a0dafbc@-5946",
+"1.011110010000110011111011111100110110010110000010100001101111111000010000011111110101100000010110011001100000010001100101000001101000010010001011001011000110100011001e-24793"},
+{139, 4,
+"1.020302230021023320300300101212330121100031233000032101123133120221012000000000000000000000000000000000000000000000000000000000000000000000e11221",
+"1.001000110010101100001001001011111000110000110000010001100110111100011001010000001101101111000000001110010001011011011111011000101001000110e22442"},
+{126, 13,
+"4.a3cb351c6c548a0475218519514c6c54366681447019ac70a387862c39c86546ab27608c9c2863328860aa2464288070a76c0773882728c5213a335289259@2897",
+"1.01011010000001110001100001101111100111011010010111000011000101111011000100001010010100110111101001001001000000011100010000000e10722"},
+{6, 26,
+"1.j79f6@-1593",
+"1.00000e-7487"},
+{26, 18,
+"3.5e99682hh310aa89hb2fb4h88@-5704",
+"1.0110010100010101000101100e-23784"},
+{12, 21,
+"4.j7f3e2ccdfa@-3524",
+"1.10110101011e-15477"},
+{38, 28,
+"o.agr0m367b9bmm76rplg7b53qlj7f02g717cab@6452",
+"1.1001010011101100110100111000111010001e31021"},
+{75, 17,
+"4.00abd9gc99902e1cae2caa7647gcc029g01370e96d3f8e9g02f814d3ge5faa29d40b9db470@5487",
+"1.11100000110101010111101001110001001010111111010100000100001010100111011101e22429"},
+{91, 16,
+"1.0a812a627160014a3bda1f00000000000000000000000000000000000000000000000000000000000000000000@7897",
+"1.000010101000000100101010011000100111000101100000000000010100101000111011110110100001111100e31588"},
+{154, 19,
+"1.989279dda02a8ic15e936ahig3c695f6059a3i01b7d1ge6a418bf84gd87e36061hb2bi62ciagcgb9226fafea41d2ig1e2f0a10ea3i40d6dahf598bdbh372bdf5901gh276866804ah53b6338bi@5285",
+"1.110101101101101111110010001011110001100000010100011101101001000100110100000011110111000011011101011110010100110101011011111100101101001100000101101000010e22450"},
+{53, 2,
+"1.0100010111100111001010000100011011111011011100110111e-20319",
+"1.0100010111100111001010000100011011111011011100110111e-20319"},
+{76, 3,
+"2.101212121100222100012112101120011222102000021110201110000202111122221100001e1511",
+"1.000110101010111000011001011111110000001001101001011011111110111111010000111e2396"},
+{31, 9,
+"1.171774371505084376877631528681e3258",
+"1.110101101011111011111000110011e10327"},
+{175, 8,
+"4.506242760242070533035566017365410474451421355546570157251400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3483",
+"1.001010001100101000101111100000101000100001110001010110110000111011011101100000011110111101011000010001001111001001010011000100010111011011011001101011110000011011110101010011e10451"},
+{103, 24,
+"8.0hmlm3g183cj358fn4bimn5bie1l89k95m647474mm8jg5kh1c011gi0m7de9j7b48c595g1bki4n32kll7b882eg7klgga0h0gf11@4510",
+"1.001000110101001101011010101001111010110100010100110101010101110000001011001101110110010111000101010111e20681"},
+{12, 9,
+"3.00221080453e2479",
+"1.11000111010e7859"},
+{86, 11,
+"6.873680186953174a274754118026423965415553a088387303452447389287133a0956111602a5a085446@5035",
+"1.0000000000110100010110000111010001010100101011000100101010010011101010000110011110001e17421"},
+{68, 10,
+"6.1617378719016284192718392572980535262609909598793237475124371481233e481",
+"1.0110001011000101110010111101100101111110001100001011110011001101111e1600"},
+{11, 15,
+"5.ab10c18d45@907",
+"1.0000101111e3546"},
+{77, 26,
+"6.e6kl84g6h30o3nfnj7fjjff4n1ee6e5iop76gabj23e7hgan9o6724domc7bp4hdll95g817519f@5114",
+"1.1011000101111111111110011011101100000100101000001001100000001011010001001000e24040"},
+{28, 27,
+"d.odiqp9kgh84o8d2aoqg4c21hemi@3566",
+"1.101001111001111111110011110e16959"},
+{45, 14,
+"7.cddc6295a576980adbc8c16111d6301bad3146a1143c@-6227",
+"1.10000000110011000000101100110001011100010111e-23706"},
+{54, 19,
+"1.b6e67i2124hfga2g819g1d6527g2b603eg3cd8hhca9gecig8geg1@4248",
+"1.11010100100010101101110110010100000010111010010101110e18045"},
+{49, 20,
+"1.jj68bj6idadg44figi10d2ji99g6ddi6c6ich96a5h86i529@-3149",
+"1.001011111101100100001010001000011100000000101110e-13609"},
+{171, 16,
+"6.22cf0e566d8ff11359d70bd9200065cfd72600b12e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@5602",
+"1.10001000101100111100001110010101100110110110001111111100010001001101011001110101110000101111011001001000000000000001100101110011111101011100100110000000001011000100101110e22410"},
+{144, 14,
+"1.425d9709b4c125651ab88bb1a0370c14270d067a9a74a612dad48d5c025531c175c1b905201d0d9773aa686c8249db9c0b841b10821791c02baa2525a4aa7571850439c2cc965cd@-3351",
+"1.11100111110001001101010111010000101010011000111001101011000001011110101110011011100100111001101101111011001001101011001101001011011101101111011e-12759"},
+{166, 6,
+"3.324252232403440543134003140400220120040245215204322153511143504542403430152410543444455151104314552352030352125540101550151410414122051500201022252511512332523431554e8340",
+"1.010101111101111101001001110010111110010000001111010101100110011011010110011001001100001111010101100000010111011111101110110111101110010001110001111000001010001111000e21560"},
+{141, 24,
+"2.i3c88lkm2958l9ncb9f85kk35namjli84clek5j6jjkli82kb9m4e4i2g39me63db2094cif80gcba8ie6l15ia0d667kn9i1f77bdak599e1ach0j05cdn8kf6c6kfd82j2k6hj2c4d@4281",
+"1.10011100001010110111001000000000101011100010101011001010001101110100110111011000111101000001111101100000110100100010101011001100100011001011e19629"},
+{84, 6,
+"2.41022133512503223022555143021524424430350133500020112434301542311050052304150111243e982",
+"1.11010001111111001010011100011000011100100111111010001111010010101001001000011100001e2539"},
+{56, 9,
+"1.5305472255016741401411184703518332515066156086511016413e2936",
+"1.0111110010001101000000110101110000110101001011001100111e9307"},
+{18, 8,
+"3.63542400000000000e-599",
+"1.11100111011000101e-1796"},
+{111, 13,
+"8.b693ac7a24679b98708a0057a6202c867bc146740ab1971b380756a24c99804b63436419239ba0510030b819933771a636c57c5747b883@-6160",
+"1.01011011111110100101110010100100000110000011011101001110010110000011101110111111010111000011011101101001100100e-22792"},
+{162, 16,
+"4.f2abe958a313566adbf3169e55cdcff3785dbd5c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@382",
+"1.00111100101010101111101001010110001010001100010011010101100110101011011011111100110001011010011110010101011100110111001111111100110111100001011101101111010101110e1530"},
+{117, 23,
+"2.4b6kk3ag3if217ih1hggkk69bmcecfil1cd38dijh35j8e6ckhd335a4gj7l05bedk19473i8449b1ajc3jd3ka95eceheh72lh2jh17jamlm1142gll@-3628",
+"1.10010010001010001110011000010000011111011101111100110101100100101111101110010011101001111010100010001111110100101111e-16411"},
+{179, 2,
+"1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203",
+"1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203"},
+{18, 27,
+"4.ll743n2f654gh3154@-6039",
+"1.01101001111010011e-28713"},
+{178, 15,
+"1.e5443105cad2d014b700c42aa3de854c4b95322420695d07db3564ec07473da83bde123b74c794139265a838ebeca745ad3dc97d7c356271ca935ea8e83306562c2a8edc6e886c1b6b2d3e17038379c33826526770985c068@821",
+"1.011100001000101100111111111111000100110111110011101010001111011001111101111001010011100100100101100011101001000000101001010100011111001011001010011101101001000111111010101101011e3208"},
+{161, 22,
+"2.46ikji624bg042877h8g2jdki4ece6ede62841j7li843a4becdkkii86c54192jkefehikkb3kcb26ij1b3k9agfbb07dih88d6ej0ee0d63i8hedc7f0g0i9g7jf9gf6423j70h421bg5hf2bja9j0a432lb10@-5125",
+"1.0111011000111110000010011100001100100110001011101001011110111010100000011100000010011101011100101100111100110000001101010101011110100011101111001011001111100000e-22854"},
+{62, 19,
+"7.bgd1g0886a6c3a9ee67cc7g3bgf718i98d90788idi5587358e660iffc0ic6@3257",
+"1.0101100100001110000100010110100100000111110001111001011110100e13838"},
+{127, 19,
+"1.413bgf99eidba75ged25f7187080bce3h7ebdeghea4ig6c79g94di7b42a3e4cdi4ic6a53i71d2e4hdbe50ih0a0egf2fi469732131ig6g496bf7h8g3c86ie7h@-4465",
+"1.001101111000011011100010010010010110111001001001110011110101111111000001110101111110001110010000110011111101000011000101111101e-18967"},
+{17, 21,
+"4.7d5b70gh4k0gj4fj@-116",
+"1.1000100010000110e-508"},
+{141, 13,
+"2.2b4988c5cb57072a6a1a9c42224794a1cbc175a9bc673bb28aa045c3182b9396ca8bb8590969672b0239608a845a2c35c08908a58c2a83748c89241a6561422c7cc4866c8454@4358",
+"1.10010110101000001000001001111001000100111110100010100110111011111011010010101000110101110000111100010000101101000110000000000001111110110011e16127"},
+{39, 7,
+"3.00350342452505221136410100232265245244e202",
+"1.10011000111110011010100110101101010010e568"},
+{119, 24,
+"5.2aene587kc2d9a55mm8clhn4dn0a551de58b1fcli8e8hf1jlm7i0376dl5fhb2k8acka03077mnbn9d4dmi0641dce871c81g2b3ge76m3kngm4a9g5gh@-892",
+"1.0111101010010100001001111110000000100101110010010111111100100101100001010010100110111000101100101010111000101111000010e-4088"},
+{41, 14,
+"5.c3dc5c49373d0c0075624931133022185bd08b16@-5294",
+"1.0101011000010111111111000010100110011111e-20154"},
+{41, 6,
+"3.2411143454422033245255450304104450302500e2250",
+"1.1110111101010101001001100000100011110111e5817"},
+{17, 13,
+"3.65789aa26aa273b1@-4490",
+"1.1100011101010111e-16614"},
+{10, 26,
+"1.5p4hag1fl@6017",
+"1.110010111e28282"},
+{130, 11,
+"2.606a72601843700427667823172635a47055021a0a68a99326875195a179483948407aa13726244552332114a1784aaa7239956521604460876871a65708458aa@-6285",
+"1.110001001110111110110111000010101000110010011110010101100100001000101011010010000001000101000110111111110101000100000111100010100e-21742"},
+{29, 20,
+"j.4356d9b7i38i955jjj1j442501bj@163",
+"1.1010101011110011100000100100e708"},
+{140, 21,
+"9.2f5k7aid6bj2b2g5bff29i73hk3a8d8g0i7ifa07hkb79g4hd3c7j6g4hjj2jbhai01gkje3h9g3gj3i34f0194kaed32iea9dcgcj8h7i1khdkf965c1ak97gf3h03fcab3ggi03fa@4864",
+"1.0101011100011101000110101001010011111111010011000111111111100000011011100111010001100101100110001110001001100101001100110000011110100101101e21367"},
+{133, 13,
+"2.3721a9107307a71c75c07c83b70a25a9853619030b5bcb55101ca5c2060bca46c331b92b33aa957c3ac7c817335287c6917999c38c3806b6b5919623023ac52063bb@6602",
+"1.011001101111100001100100110100010100010011100010111110110100100000000010011101001011000100000110011011101001010010011110111100010010e24431"},
+{118, 2,
+"1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960",
+"1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960"},
+{102, 23,
+"l.26lhk42clcm9g940eihakhi32gb3331lld488cf1j4f73ge051bfl8gcmcg78gkjc2iibjf752eag0dee6dafa97k79jlh11j3270@-2160",
+"1.01101011011000100101110111110001011000101101011001011111001101000110111010000010011111101110101100010e-9767"},
+{156, 18,
+"b.eb927dd4g48abee3cc2begehb9c3b8h83cae152db850ac2f3g816d6787825122c8h3aa3g8023h23000a8hg61065b3e367ac59ca373067730f96dd0d3b73b3c43fef91750b333gd497b8ce9228e7@5504",
+"1.11000110111100011101100011001001110011101100011111010100101110010010010011111001100000011010011111111011001011111010001001011001110001100001101000000110000e22954"},
+{158, 5,
+"3.0112043214104344433122444210142004032004444213123303302023242414000243311324332203224340334422234000104132020124210141322013240010134130441413233111204013422e-10468",
+"1.1001011000111111110100100101110011100001110100101001101110011001101001101011010010111010111111101010100011100010101100110111011101000110110100000111001100011e-24305"},
+{7, 9,
+"2.141540e-146",
+"1.001111e-462"},
+{111, 5,
+"3.21233234110011204313222402442032333320324004133424222041314021020411320312421014434003440431230413141402230403e7641",
+"1.10010000000101010000101010101011011010000100010010010000010110001111000111111111000110111001100101101110101101e17743"},
+{76, 13,
+"7.1c0861453a4ac156b6119ba7548251b5cb00b7c409c2bb8138214676468c9949676226013c1@4639",
+"1.001000011000000011101101101010100010010001010111100110010101111110110010111e17169"},
+{6, 25,
+"c.aj660@-6978",
+"1.11000e-32402"},
+{156, 3,
+"2.22101000022222000012110122210202211110020121210120112102122121111210000211020001020201202200011021211102012110220222110022001121011022011202000110120021012e-14744",
+"1.11010001111000101111110000010011001101000100010010110011100100110001100111011101011111111100011111001100001111100101100000001000001100000000010010001011101e-23368"},
+{7, 23,
+"1.4hclk2@2148",
+"1.110110e9716"},
+{69, 11,
+"2.77684920493191632416690544493465617a187218365952a6740034288687745a26@3263",
+"1.01111000111000001111001110000110000110001111110011101100101111011100e11289"},
+{146, 21,
+"3.agg4d0dj636d526d4i8643ch5jee4ge2c3i46k121857dbedagd98cjifaf0fgc09ca739g2fkfbfh06i687kic2kb8c7i48gda57bb6d9bh81eh49h0d8e3i7ad2kgb1ek86b86g3589k27d@3562",
+"1.0010111111111100101010101010001100110101010011011100001110111000101101001110001110010100000001010001000111010000010011110100010010101100101000001e15647"},
+{20, 3,
+"1.2000000021102111102e-16642",
+"1.1011101011111110000e-26377"},
+{68, 13,
+"1.a43205b2164676727806614acc0398925569c3962a3ba419881a5c63b651aa3ab46@-618",
+"1.1111011000001110010100111000110010110110011001110001100101011111000e-2287"},
+{129, 4,
+"2.22033002012102010122130132103000303000120122313322000222121000300000000000000000000000000000000000000000000000000000000000000000e13222",
+"1.01010001111000010000110010010000100011010011100011110010011000000110011000000011000011010110111111010000000101010011001000000110e26445"},
+{22, 6,
+"1.420033001013011530142e11704",
+"1.001000110010110110001e30255"},
+{108, 6,
+"1.03345424443433104422104400512453214240453335230205104304115343030341144544051005432030344054100542125304500e7375",
+"1.00101101110001011101101111000010101011101000001111001110001101100000111100010101010101101100011110111010000e19064"},
+{91, 27,
+"2.ao077kf8oqoihn5pm6f5eqdcgnd2132d7p6n7di8ep82a1a9be99pm36g1emacbenaeiqphpgpdjhmm9ke3pn4pdea@-5482",
+"1.111101100001000011101010001000000111000100100111110010101101110001101101101101101010111110e-26066"},
+{96, 9,
+"8.25805186310703506315505842015248775712246416686874260383701323213202658278523870037877823670166e-8134",
+"1.11010111111000011100111001011010001110010001011101011101110101000101100100100010110011001010000e-25782"},
+{161, 16,
+"7.3a7627c1e42ef738698e292f0b81728c4b14fe8c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-3342",
+"1.1100111010011101100010011111000001111001000010111011110111001110000110100110001110001010010010111100001011100000010111001010001100010010110001010011111110100011e-13366"},
+{90, 3,
+"2.10212200011211012002002221112120210222002020100202111000211012122020011102022112222021001e-3447",
+"1.11100010111011011000101111110001000101000111110001100001010111101101011011110001000010001e-5463"},
+{100, 27,
+"a.f81hjjakdnc021op6ffh530ec8ige6n2fqc8f8j7ia7qelebgqkm4ic5ohh652hq1kgpag6pp0ldin6ce1fg6mj34077f5qc5oe@6576",
+"1.011101001010010011110001100011111111010001110110100100101001010000101011101011110010010011111100000e31271"},
+{152, 16,
+"e.37ac48a0303f903c9d20883eddea4300d1190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-1388",
+"1.1100011011110101100010010001010000000110000001111111001000000111100100111010010000010001000001111101101110111101010010000110000000011010001000110010000e-5549"},
+{106, 20,
+"1.3g2h7i2776d50gjibi937f8cdci3idecdeh3j2gba0j8d1ghgg3eg609ji55h5g7jeai1bii3a4f9jhjfij6jd1g3cg0f6024e252gc3e@6422",
+"1.100110000101011010100111100110000000100101000110110011010010000101000100110010001110011110111100010000111e27755"},
+{23, 17,
+"9.f72e724454d1g0f60g93g6@-6563",
+"1.0011100011110110010001e-26823"},
+{98, 6,
+"1.2444223304453415235424343034030405514010421403514410005234221430055051205523402412055242134042045e-8535",
+"1.1101110011010001101001001111100101111010100111001011110001000010100101101110011011101100000111011e-22063"},
+{4, 18,
+"1.gec@-6711",
+"1.100e-27984"},
+{69, 24,
+"8.d45gdfnhkhb7a20nj96dnggic83imhjne0cceldechn1m4e9fbd9db0ablngjf9n7810@6975",
+"1.00100111111100101100110011110110110000110110110010100101011111000100e31983"},
+{122, 8,
+"4.0227760456667717717077553523466457265600000000000000000000000000000000000000000000000000000000000000000000000000000000000e-1767",
+"1.0000001001011111111000010010111011011011111100111111100111100011111110110101110101001110011011010010111101011010111000000e-5299"},
+{144, 23,
+"8.b01c48dg20bek9a5k376clc501aecg92bdjaeji2dm9230i7j3k36jm50b0c5a0753i2b18534cji34bcl2li033cc534m52k2gbegc25a5g30lf4calag58026i5d7li61jg9digj5ceb1@-4456",
+"1.00010000110011010111011011110111001101111001010110001101011100100101101110110000010011011111100000100110001001001111111011010110000000001111110e-20154"},
+{111, 4,
+"2.23100111310122202021232133233012212012232222323230133100000000000000000000000000000000000000000000000000000000e-10458",
+"1.01011010000010101110100011010100010001001101110011111101111000110100110000110101110101010111011101100011111010e-20915"},
+{117, 10,
+"1.61207328685870427963864999744776917701013812304254540861834226053316419217753608451422967376154318603744156166920074e-6440",
+"1.01100011000100111001100010000000110010100001001011111010100001101111100100101100111010100011101110001010011010010010e-21393"},
+{106, 16,
+"1.dd30a1d24091263243ca1c144f0000000000000000000000000000000000000000000000000000000000000000000000000000000@354",
+"1.110111010011000010100001110100100100000010010001001001100011001001000011110010100001110000010100010011110e1416"},
+{77, 14,
+"4.90d6913ba57b149d8d85a58c311b4d537c10bd7d3c10d69c62bc08d32269760126a58115a105@-7311",
+"1.1001000000111100000111001001011000110101001111100001100111010100010000011111e-27834"},
+{8, 4,
+"3.2230000e15197",
+"1.1101011e30395"},
+{81, 24,
+"1.84ni25h558abmhg2dk7bl2jbbmkf4i8i2bemc5cgmk9jf301c00k24271m9h7mgm4301be1lnldn4364@2573",
+"1.01110010011000110110100101011001011111101111101100010110101101011101100001000010e11797"},
+{94, 2,
+"1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427",
+"1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427"},
+{77, 21,
+"1.87e4k9df85g50ead6fcj4h86820ikdjdjg93d90ca406g470hhkh7ciaba1aggg753g36553ebh5@2538",
+"1.0010001100011000111010000010011001010011000000100101010001100000111101000111e11148"},
+{80, 17,
+"1.923gga999230g94fce02efg753ce001045a35e0264c9c2cb17850e32484fc3526dcg38ed874g5f2@3392",
+"1.0011100111101001001101111001110100001100111110011110110001100110101010111001110e13865"},
+{99, 7,
+"4.53646362336126606650465342500160461331562113222506144210636341332436342025203333264316511653025011e-5540",
+"1.01101101111001001100001101101101010011001001100110111000010000101000011001001001101000011101011001e-15551"},
+{119, 20,
+"1.c8966iabcf4de94ad15f9e83j407i3he7fch54h5jh0g5d74e06c057gg72a107didj8d1j8geibbfec5j36c3fgd5e12edjb9g10j7c9i03f33hi80ce0@7153",
+"1.0101110101100011110001001110100110011000100000001001000110111110011111100011111010011101011111101101010011110111110100e30915"},
+{93, 13,
+"2.c749cb562c3a758b1a21a650666a4c6c53c76ca58a1a75a0358c9ac3866887972b3551a03aa6c150856531258508@193",
+"1.10101111101001011010111101100100111110011111010110111101100100010011001001100011110100111110e715"},
+{145, 14,
+"1.c61614b64261d22c62cb9d16163ca4d144ac23351b708506b3b610b1b67b764ca974448d7a2c6515a6bc97503d4b2a530c75b2b677a464c6629c69b6c3d7860d7749b4b653c434d5@2050",
+"1.111111100001101111100011001111100010010000101000011110000001110100111001011010100001001010111111010001111101000110011000011101110110001001100101e7805"},
+{159, 23,
+"4.bj9l07l0215e7l6lf1dkf62i056l37jaa0gdih717656f1kk1a77883jf99jg31le43em76bmcg4lddl782ihkla0m392886d8lm67d6c3a1l4j12kg0l1k52ee77lmk0gech11g8jeei680k85bi460c7el17@-1539",
+"1.01010100110100100101100001011100000001100011110001001101000010000001000010000110000110010001110100001101011101101001001101101111001101101111101001010010010100e-6960"},
+{24, 25,
+"g.m749al09kflg5b42jnn4a7b@-2820",
+"1.01010010101011010111011e-13092"},
+{88, 18,
+"3.5ed0gad0bhhb7aa9ge2ad1dhcg6833f3e068936hghf23gd2aa69f13539f15hfce50aa64achfee49bfg7249g@-4058",
+"1.001000010110011011000101100000101111101001100011101101001111110111000010010110010001100e-16920"}
+};
+
+static void
+check_reftable (void)
+{
+ int i, base;
+ mpfr_t x, y;
+ mpfr_prec_t p;
+ char *s;
+
+ mpfr_init2 (x, 200);
+ mpfr_init2 (y, 200);
+ for (i = 0 ; i < numberof (RefTable) ; i++)
+ {
+ base = RefTable[i].base;
+ p = RefTable[i].prec;
+ mpfr_set_prec (x, p);
+ mpfr_set_prec (y, p);
+ mpfr_set_str_binary (x, RefTable[i].binstr);
+ mpfr_strtofr (y, RefTable[i].str, &s, base, MPFR_RNDN);
+ if (s == NULL || *s != 0)
+ {
+ printf ("strtofr didn't parse entire input for i=%d:\n"
+ " Str=%s", i, RefTable[i].str);
+ exit (1);
+ }
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Results differ between strtofr and set_binary for i=%d:\n"
+ " Set binary gives: ", i);
+ mpfr_dump (x);
+ printf (" strtofr gives: ");
+ mpfr_dump (y);
+ printf (" setstr gives: ");
+ mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN);
+ mpfr_dump (x);
+ mpfr_set_prec (x, 2*p);
+ mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN);
+ printf (" setstr ++ gives: ");
+ mpfr_dump (x);
+ exit (1);
+ }
+ }
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+static void
+check_parse (void)
+{
+ mpfr_t x;
+ char *s;
+ int res;
+
+ mpfr_init (x);
+
+ /* Invalid data */
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ res = mpfr_strtofr (x, " invalid", NULL, 10, MPFR_RNDN);
+ if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x))
+ {
+ printf ("Failed parsing ' invalid' (1)\n X=");
+ mpfr_dump (x);
+ exit (1);
+ }
+ MPFR_ASSERTN (res == 0);
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ res = mpfr_strtofr (x, " invalid", &s, 0, MPFR_RNDN);
+ if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x) || strcmp (s, " invalid"))
+ {
+ printf ("Failed parsing ' invalid' (2)\n S=%s\n X=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ MPFR_ASSERTN (res == 0);
+ /* Check if it stops correctly */
+ mpfr_strtofr (x, "15*x", &s, 10, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 15) || strcmp (s, "*x"))
+ {
+ printf ("Failed parsing '15*x'\n S=%s\n X=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ /* Check for leading spaces */
+ mpfr_strtofr (x, " 1.5E-10 *x^2", &s, 10, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, "1.5E-10") || strcmp (s, " *x^2"))
+ {
+ printf ("Failed parsing '1.5E-10*x^2'\n S=%s\n X=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ /* Check for leading sign */
+ mpfr_strtofr (x, " +17.5E-42E ", &s, 10, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, "17.5E-42") || strcmp (s, "E "))
+ {
+ printf ("Failed parsing '+17.5E-42E '\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "-17.5E+42E\n", &s, 10, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, "-17.5E42") || strcmp (s, "E\n"))
+ {
+ printf ("Failed parsing '-17.5E+42\\n'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ /* P form */
+ mpfr_strtofr (x, "0x42P17", &s, 16, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '0x42P17' (base = 16)\n S='%s'\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "-0X42p17", &s, 16, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '-0x42p17' (base = 16)\n S='%s'\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "42p17", &s, 16, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '42p17' (base = 16)\n S='%s'\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "-42P17", &s, 16, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '-42P17' (base = 16)\n S='%s'\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "0b1001P17", &s, 2, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '0b1001P17' (base = 2)\n S='%s'\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "-0B1001p17", &s, 2, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '-0B1001p17' (base = 2)\n S='%s'\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "1001p17", &s, 2, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '1001p17' (base = 2)\n S='%s'\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "-1001P17", &s, 2, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '-1001P17' (base = 2)\n S='%s'\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ /* Check for auto-detection of the base */
+ mpfr_strtofr (x, "+0x42P17", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "42P17", 16, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "-42E17", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "-42E17", 10, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '-42E17'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "-42P17", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "-42", 10, MPFR_RNDN) || strcmp (s, "P17"))
+ {
+ printf ("Failed parsing '-42P17' (base = 0)\n S='%s'\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, " 0b0101.011@42", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, " 0b0101.011P42", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "+0x42@17", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "4.2@18", 16, MPFR_RNDN) || *s != 0)
+ {
+ printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+
+
+ /* Check for space inside the mantissa */
+ mpfr_strtofr (x, "+0x4 2@17", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 4) || strcmp(s," 2@17"))
+ {
+ printf ("Failed parsing '+0x4 2@17'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "+0x42 P17", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0x42) || strcmp(s," P17"))
+ {
+ printf ("Failed parsing '+0x42 P17'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ /* Space between mantissa and exponent */
+ mpfr_strtofr (x, " -0b0101P 17", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_si (x, -5) || strcmp(s,"P 17"))
+ {
+ printf ("Failed parsing '-0b0101P 17'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ /* Check for Invalid exponent. */
+ mpfr_strtofr (x, " -0b0101PF17", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_si (x, -5) || strcmp(s,"PF17"))
+ {
+ printf ("Failed parsing '-0b0101PF17'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ /* At least one digit in the mantissa. */
+ mpfr_strtofr (x, " .E10", &s, 0, MPFR_RNDN);
+ if (strcmp(s," .E10"))
+ {
+ printf ("Failed parsing ' .E10'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ /* Check 2 '.': 2.3.4 */
+ mpfr_strtofr (x, "-1.2.3E4", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, "-1.2") || strcmp(s,".3E4"))
+ {
+ printf ("Failed parsing '-1.2.3E4'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ /* Check for 0x and 0b */
+ mpfr_strtofr (x, " 0xG", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0) || strcmp(s,"xG"))
+ {
+ printf ("Failed parsing ' 0xG'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, " 0b2", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0) || strcmp(s,"b2"))
+ {
+ printf ("Failed parsing ' 0b2'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, "-0x.23@2Z33", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_si (x, -0x23) || strcmp(s,"Z33"))
+ {
+ printf ("Failed parsing '-0x.23@2Z33'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+ mpfr_strtofr (x, " 0x", &s, 0, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 0) || strcmp(s,"x"))
+ {
+ printf ("Failed parsing ' 0x'\n S=%s\n X=", s);
+ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
+ exit (1);
+ }
+
+ mpfr_clear (x);
+}
+
+static void
+check_overflow (void)
+{
+ mpfr_t x;
+ char *s;
+
+ mpfr_init (x);
+
+ /* Huge overflow */
+ mpfr_strtofr (x, "123456789E2147483646", &s, 0, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
+ {
+ printf ("Check overflow failed (1) with:\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_strtofr (x, "123456789E9223372036854775807", &s, 0, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
+ {
+ printf ("Check overflow failed (2) with:\n s='%s'\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_strtofr (x, "123456789E170141183460469231731687303715884105728",
+ &s, 0, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
+ {
+ printf ("Check overflow failed (3) with:\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ /* Limit overflow */
+ mpfr_strtofr (x, "12E2147483646", &s, 0, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
+ {
+ printf ("Check overflow failed (4) with:\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_strtofr (x, "12E2147483645", &s, 0, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
+ {
+ printf ("Check overflow failed (5) with:\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_strtofr (x, "0123456789ABCDEF@2147483640", &s, 16, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
+ {
+ printf ("Check overflow failed (6) with:\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_strtofr (x, "0123456789ABCDEF@540000000", &s, 16, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
+ {
+ printf ("Check overflow failed (7) with:\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ /* Check underflow */
+ mpfr_strtofr (x, "123456789E-2147483646", &s, 0, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) )
+ {
+ printf ("Check underflow failed (1) with:\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_strtofr (x, "123456789E-9223372036854775807", &s, 0, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) )
+ {
+ printf ("Check underflow failed (2) with:\n s='%s'\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_strtofr (x, "-123456789E-170141183460469231731687303715884105728",
+ &s, 0, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_NEG (x) )
+ {
+ printf ("Check underflow failed (3) with:\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_strtofr (x, "0123456789ABCDEF@-540000000", &s, 16, MPFR_RNDN);
+ if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x))
+ {
+ printf ("Check overflow failed (7) with:\n s=%s\n x=", s);
+ mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+}
+
+static void
+check_retval (void)
+{
+ mpfr_t x;
+ int res;
+
+ mpfr_init2 (x, 10);
+
+ res = mpfr_strtofr (x, "01011000111", NULL, 2, MPFR_RNDN);
+ MPFR_ASSERTN (res == 0);
+ res = mpfr_strtofr (x, "11011000111", NULL, 2, MPFR_RNDN);
+ MPFR_ASSERTN (res > 0);
+ res = mpfr_strtofr (x, "110110001101", NULL, 2, MPFR_RNDN);
+ MPFR_ASSERTN (res < 0);
+
+ mpfr_clear (x);
+}
+
+/* Bug found by Christoph Lauter (in mpfr_set_str). */
+static struct bug20081025_test {
+ mpfr_rnd_t rnd;
+ int inexact;
+ const char *str;
+ const char *binstr;
+} Bug20081028Table[] = {
+ {MPFR_RNDN, -1, "1.00000000000000000006", "1"},
+ {MPFR_RNDZ, -1, "1.00000000000000000006", "1"},
+ {MPFR_RNDU, +1, "1.00000000000000000006",
+ "10000000000000000000000000000001e-31"},
+ {MPFR_RNDD, -1, "1.00000000000000000006", "1"},
+
+
+ {MPFR_RNDN, +1, "-1.00000000000000000006", "-1"},
+ {MPFR_RNDZ, +1, "-1.00000000000000000006", "-1"},
+ {MPFR_RNDU, +1, "-1.00000000000000000006", "-1"},
+ {MPFR_RNDD, -1, "-1.00000000000000000006",
+ "-10000000000000000000000000000001e-31"},
+
+ {MPFR_RNDN, +1, "0.999999999999999999999999999999999999999999999", "1"},
+ {MPFR_RNDZ, -1, "0.999999999999999999999999999999999999999999999",
+ "11111111111111111111111111111111e-32"},
+ {MPFR_RNDU, +1, "0.999999999999999999999999999999999999999999999", "1"},
+ {MPFR_RNDD, -1, "0.999999999999999999999999999999999999999999999",
+ "11111111111111111111111111111111e-32"},
+
+ {MPFR_RNDN, -1, "-0.999999999999999999999999999999999999999999999", "-1"},
+ {MPFR_RNDZ, +1, "-0.999999999999999999999999999999999999999999999",
+ "-11111111111111111111111111111111e-32"},
+ {MPFR_RNDU, +1, "-0.999999999999999999999999999999999999999999999",
+ "-11111111111111111111111111111111e-32"},
+ {MPFR_RNDD, -1, "-0.999999999999999999999999999999999999999999999", "-1"}
+};
+
+static void
+bug20081028 (void)
+{
+ int i;
+ int inexact, res;
+ mpfr_rnd_t rnd;
+ mpfr_t x, y;
+ char *s;
+
+ mpfr_init2 (x, 32);
+ mpfr_init2 (y, 32);
+ for (i = 0 ; i < numberof (Bug20081028Table) ; i++)
+ {
+ rnd = Bug20081028Table[i].rnd;
+ inexact = Bug20081028Table[i].inexact;
+ mpfr_set_str_binary (x, Bug20081028Table[i].binstr);
+ res = mpfr_strtofr (y, Bug20081028Table[i].str, &s, 10, rnd);
+ if (s == NULL || *s != 0)
+ {
+ printf ("Error in Bug20081028: strtofr didn't parse entire input\n"
+ "for (i=%d) Str=\"%s\"", i, Bug20081028Table[i].str);
+ exit (1);
+ }
+ if (! SAME_SIGN (res, inexact))
+ {
+ printf ("Error in Bug20081028: expected %s ternary value, "
+ "got %d\nfor (i=%d) Rnd=%s Str=\"%s\"\n Set binary gives: ",
+ inexact > 0 ? "positive" : "negative",
+ res, i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
+ mpfr_dump (x);
+ printf (" strtofr gives: ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in Bug20081028: Results differ between strtofr and "
+ "set_binary\nfor (i=%d) Rnd=%s Str=\"%s\"\n"
+ " Set binary gives: ",
+ i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
+ mpfr_dump (x);
+ printf (" strtofr gives: ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ }
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+/* check that 1.23e is correctly parsed, cf
+ http://gmplib.org/list-archives/gmp-bugs/2010-March/001898.html */
+static void
+test20100310 (void)
+{
+ mpfr_t x, y;
+ char str[] = "1.23e", *endptr;
+
+ mpfr_init2 (x, 53);
+ mpfr_init2 (y, 53);
+ mpfr_strtofr (x, str, &endptr, 10, MPFR_RNDN);
+ mpfr_strtofr (y, "1.23", NULL, 10, MPFR_RNDN);
+ if (mpfr_cmp (x, y) != 0)
+ {
+ printf ("x <> y in test20100310\n");
+ exit (1);
+ }
+ if (endptr != str + 4) /* strtofr should take into account '1.23',
+ not '1.23e' */
+ {
+ printf ("endptr <> str + 4 in test20100310\n");
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+/* From a bug reported by Joseph S. Myers
+ https://sympa.inria.fr/sympa/arc/mpfr/2012-08/msg00005.html */
+static void
+bug20120814 (void)
+{
+ mpfr_exp_t emin = -30, e;
+ mpfr_t x, y;
+ int r;
+ char s[64], *p;
+
+ mpfr_init2 (x, 2);
+ mpfr_set_ui_2exp (x, 3, emin - 2, MPFR_RNDN);
+ mpfr_get_str (s + 1, &e, 10, 19, x, MPFR_RNDD);
+ s[0] = s[1];
+ s[1] = '.';
+ for (p = s; *p != 0; p++) ;
+ *p = 'e';
+ sprintf (p + 1, "%d", (int) e - 1);
+
+ mpfr_init2 (y, 4);
+ r = mpfr_strtofr (y, s, NULL, 0, MPFR_RNDN);
+ if (r <= 0 || ! mpfr_equal_p (x, y))
+ {
+ printf ("Error in bug20120814\n");
+ printf ("mpfr_strtofr failed on string \"%s\"\n", s);
+ printf ("Expected inex > 0 and y = 0.1100E%d\n", (int) emin);
+ printf ("Got inex = %-6d and y = ", r);
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static void
+bug20120829 (void)
+{
+ mpfr_t x1, x2, e;
+ int inex1, inex2, i, r;
+ char s[48] = "1e-1";
+
+ mpfr_init2 (e, 128);
+ mpfr_inits2 (4, x1, x2, (mpfr_ptr) 0);
+
+ inex1 = mpfr_set_si (e, -1, MPFR_RNDN);
+ MPFR_ASSERTN (inex1 == 0);
+
+ for (i = 1; i <= sizeof(s) - 5; i++)
+ {
+ s[3+i] = '0';
+ s[4+i] = 0;
+ inex1 = mpfr_mul_ui (e, e, 10, MPFR_RNDN);
+ MPFR_ASSERTN (inex1 == 0);
+ RND_LOOP(r)
+ {
+ mpfr_rnd_t rnd = (mpfr_rnd_t) r;
+
+ inex1 = mpfr_exp10 (x1, e, rnd);
+ inex1 = SIGN (inex1);
+ inex2 = mpfr_strtofr (x2, s, NULL, 0, rnd);
+ inex2 = SIGN (inex2);
+ /* On 32-bit machines, for i = 7, r8389, r8391 and r8394 do:
+ strtofr.c:...: MPFR assertion failed: cy == 0
+ r8396 is OK.
+ On 64-bit machines, for i = 15,
+ r8389 does: strtofr.c:678: MPFR assertion failed: err < (64 - 0)
+ r8391 does: strtofr.c:680: MPFR assertion failed: h < ysize
+ r8394 and r8396 are OK.
+ */
+ if (! mpfr_equal_p (x1, x2) || inex1 != inex2)
+ {
+ printf ("Error in bug20120829 for i = %d, rnd = %s\n",
+ i, mpfr_print_rnd_mode (rnd));
+ printf ("Expected inex = %d, x = ", inex1);
+ mpfr_dump (x1);
+ printf ("Got inex = %d, x = ", inex2);
+ mpfr_dump (x2);
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_clears (e, x1, x2, (mpfr_ptr) 0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_special();
+ check_reftable ();
+ check_parse ();
+ check_overflow ();
+ check_retval ();
+ bug20081028 ();
+ test20100310 ();
+ bug20120814 ();
+ bug20120829 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsub.c b/mpfr/tests/tsub.c
new file mode 100644
index 0000000000..52238baca9
--- /dev/null
+++ b/mpfr/tests/tsub.c
@@ -0,0 +1,658 @@
+/* Test file for mpfr_sub.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#ifdef CHECK_EXTERNAL
+static int
+test_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
+{
+ int res;
+ int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
+ if (ok)
+ {
+ mpfr_print_raw (b);
+ printf (" ");
+ mpfr_print_raw (c);
+ }
+ res = mpfr_sub (a, b, c, rnd_mode);
+ if (ok)
+ {
+ printf (" ");
+ mpfr_print_raw (a);
+ printf ("\n");
+ }
+ return res;
+}
+#else
+#define test_sub mpfr_sub
+#endif
+
+static void
+check_diverse (void)
+{
+ mpfr_t x, y, z;
+ int inexact;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ /* check corner case cancel=0, but add_exp=1 */
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 4);
+ mpfr_set_prec (z, 2);
+ mpfr_setmax (y, __gmpfr_emax);
+ mpfr_set_str_binary (z, "0.1E-10"); /* tiny */
+ test_sub (x, y, z, MPFR_RNDN); /* should round to 2^emax, i.e. overflow */
+ if (!mpfr_inf_p (x) || mpfr_sgn (x) < 0)
+ {
+ printf ("Error in mpfr_sub(a,b,c,RNDN) for b=maxfloat, prec(a)<prec(b), c tiny\n");
+ exit (1);
+ }
+
+ /* other coverage test */
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 2);
+ mpfr_set_prec (z, 2);
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ mpfr_set_si (z, -2, MPFR_RNDN);
+ test_sub (x, y, z, MPFR_RNDD);
+ if (mpfr_cmp_ui (x, 3))
+ {
+ printf ("Error in mpfr_sub(1,-2,RNDD)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 288);
+ mpfr_set_prec (y, 288);
+ mpfr_set_prec (z, 288);
+ mpfr_set_str_binary (y, "0.111000110011000001000111101010111011110011101001101111111110000011100101000001001010110010101010011001010100000001110011110001010101101010001011101110100100001011110100110000101101100011010001001011011010101010000010001101001000110010010111111011110001111101001000101101001100101100101000E80");
+ mpfr_set_str_binary (z, "0.100001111111101001011010001100110010100111001110000110011101001011010100001000000100111011010110110010000000000010101101011000010000110001110010100001100101011100100100001011000100011110000001010101000100011101001000010111100000111000111011001000100100011000100000010010111000000100100111E-258");
+ inexact = test_sub (x, y, z, MPFR_RNDN);
+ if (inexact <= 0)
+ {
+ printf ("Wrong inexact flag for prec=288\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 63);
+ mpfr_set_prec (z, 63);
+ mpfr_set_str_binary (x, "0.101101111011011100100100100111E31");
+ mpfr_set_str_binary (y, "0.111110010010100100110101101010001001100101110001000101110111111E-1");
+ test_sub (z, x, y, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.1011011110110111001001001001101100000110110101101100101001011E31");
+ if (mpfr_cmp (z, y))
+ {
+ printf ("Error in mpfr_sub (5)\n");
+ printf ("expected "); mpfr_print_binary (y); puts ("");
+ printf ("got "); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (y, 63);
+ mpfr_set_prec (z, 63);
+ mpfr_set_str_binary (y, "0.1011011110110111001001001001101100000110110101101100101001011E31");
+ mpfr_sub_ui (z, y, 1541116494, MPFR_RNDN);
+ mpfr_set_str_binary (y, "-0.11111001001010010011010110101E-1");
+ if (mpfr_cmp (z, y))
+ {
+ printf ("Error in mpfr_sub (7)\n");
+ printf ("expected "); mpfr_print_binary (y); puts ("");
+ printf ("got "); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (y, 63);
+ mpfr_set_prec (z, 63);
+ mpfr_set_str_binary (y, "0.1011011110110111001001001001101100000110110101101100101001011E31");
+ mpfr_sub_ui (z, y, 1541116494, MPFR_RNDN);
+ mpfr_set_str_binary (y, "-0.11111001001010010011010110101E-1");
+ if (mpfr_cmp (z, y))
+ {
+ printf ("Error in mpfr_sub (6)\n");
+ printf ("expected "); mpfr_print_binary (y); puts ("");
+ printf ("got "); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (x, "0.10110111101001110100100101111000E0");
+ mpfr_set_str_binary (y, "0.10001100100101000100110111000100E0");
+ if ((inexact = test_sub (x, x, y, MPFR_RNDN)))
+ {
+ printf ("Wrong inexact flag (2): got %d instead of 0\n", inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (x, "0.11111000110111011000100111011010E0");
+ mpfr_set_str_binary (y, "0.10011111101111000100001000000000E-3");
+ if ((inexact = test_sub (x, x, y, MPFR_RNDN)))
+ {
+ printf ("Wrong inexact flag (1): got %d instead of 0\n", inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 33);
+ mpfr_set_prec (y, 33);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_str_binary (y, "-0.1E-32");
+ mpfr_add (x, x, y, MPFR_RNDN);
+ mpfr_set_str_binary (y, "0.111111111111111111111111111111111E0");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_sub (1 - 1E-33) with prec=33\n");
+ printf ("Expected "); mpfr_print_binary (y); puts ("");
+ printf ("got "); mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 33);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_set_str_binary (y, "-0.1E-32");
+ mpfr_add (x, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 1))
+ {
+ printf ("Error in mpfr_sub (1 - 1E-33) with prec=32\n");
+ printf ("Expected 1.0, got "); mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 65);
+ mpfr_set_prec (y, 65);
+ mpfr_set_prec (z, 64);
+ mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
+ mpfr_set_str_binary (y, "0.1110111011110001110111011111111111101000011001011100101100101100");
+ test_sub (z, x, y, MPFR_RNDZ);
+ if (mpfr_cmp_ui (z, 1))
+ {
+ printf ("Error in mpfr_sub (1)\n");
+ exit (1);
+ }
+ test_sub (z, x, y, MPFR_RNDU);
+ mpfr_set_str_binary (x, "1.000000000000000000000000000000000000000000000000000000000000001");
+ if (mpfr_cmp (z, x))
+ {
+ printf ("Error in mpfr_sub (2)\n");
+ printf ("Expected "); mpfr_print_binary (x); puts ("");
+ printf ("Got "); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
+ test_sub (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 1))
+ {
+ printf ("Error in mpfr_sub (3)\n");
+ exit (1);
+ }
+ inexact = test_sub (z, x, y, MPFR_RNDA);
+ mpfr_set_str_binary (x, "1.000000000000000000000000000000000000000000000000000000000000001");
+ if (mpfr_cmp (z, x) || inexact <= 0)
+ {
+ printf ("Error in mpfr_sub (4)\n");
+ exit (1);
+ }
+ mpfr_set_prec (x, 66);
+ mpfr_set_str_binary (x, "1.11101110111100011101110111111111111010000110010111001011001010111");
+ test_sub (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_ui (z, 1))
+ {
+ printf ("Error in mpfr_sub (5)\n");
+ exit (1);
+ }
+
+ /* check in-place operations */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ test_sub (x, x, x, MPFR_RNDN);
+ if (mpfr_cmp_ui(x, 0))
+ {
+ printf ("Error for mpfr_sub (x, x, x, MPFR_RNDN) with x=1.0\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_prec (z, 53);
+ mpfr_set_str1 (x, "1.229318102e+09");
+ mpfr_set_str1 (y, "2.32221184180698677665e+05");
+ test_sub (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp_str1 (z, "1229085880.815819263458251953125"))
+ {
+ printf ("Error in mpfr_sub (1.22e9 - 2.32e5)\n");
+ printf ("expected 1229085880.815819263458251953125, got ");
+ mpfr_out_str(stdout, 10, 0, z, MPFR_RNDN);
+ putchar('\n');
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 112);
+ mpfr_set_prec (y, 98);
+ mpfr_set_prec (z, 54);
+ mpfr_set_str_binary (x, "0.11111100100000000011000011100000101101010001000111E-401");
+ mpfr_set_str_binary (y, "0.10110000100100000101101100011111111011101000111000101E-464");
+ test_sub (z, x, y, MPFR_RNDN);
+ if (mpfr_cmp (z, x)) {
+ printf ("mpfr_sub(z, x, y) failed for prec(x)=112, prec(y)=98\n");
+ printf ("expected "); mpfr_print_binary (x); puts ("");
+ printf ("got "); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 33);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 32, MPFR_RNDN);
+ mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+
+ mpfr_set_prec (x, 5);
+ mpfr_set_prec (y, 5);
+ mpfr_set_str_binary (x, "1e-12");
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+ test_sub (x, y, x, MPFR_RNDD);
+ mpfr_set_str_binary (y, "0.11111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_sub (x, y, x, MPFR_RNDD) for x=2^(-12), y=1\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 24);
+ mpfr_set_prec (y, 24);
+ mpfr_set_str_binary (x, "-0.100010000000000000000000E19");
+ mpfr_set_str_binary (y, "0.100000000000000000000100E15");
+ mpfr_add (x, x, y, MPFR_RNDD);
+ mpfr_set_str_binary (y, "-0.1E19");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_add (2)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 10);
+ mpfr_set_prec (z, 10);
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ mpfr_set_str_binary (z, "0.10001");
+ if (test_sub (x, y, z, MPFR_RNDN) <= 0)
+ {
+ printf ("Wrong inexact flag in x=mpfr_sub(0,z) for prec(z)>prec(x)\n");
+ exit (1);
+ }
+ if (test_sub (x, z, y, MPFR_RNDN) >= 0)
+ {
+ printf ("Wrong inexact flag in x=mpfr_sub(z,0) for prec(z)>prec(x)\n");
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+bug_ddefour(void)
+{
+ mpfr_t ex, ex1, ex2, ex3, tot, tot1;
+
+ mpfr_init2(ex, 53);
+ mpfr_init2(ex1, 53);
+ mpfr_init2(ex2, 53);
+ mpfr_init2(ex3, 53);
+ mpfr_init2(tot, 150);
+ mpfr_init2(tot1, 150);
+
+ mpfr_set_ui( ex, 1, MPFR_RNDN);
+ mpfr_mul_2exp( ex, ex, 906, MPFR_RNDN);
+ mpfr_log( tot, ex, MPFR_RNDN);
+ mpfr_set( ex1, tot, MPFR_RNDN); /* ex1 = high(tot) */
+ test_sub( ex2, tot, ex1, MPFR_RNDN); /* ex2 = high(tot - ex1) */
+ test_sub( tot1, tot, ex1, MPFR_RNDN); /* tot1 = tot - ex1 */
+ mpfr_set( ex3, tot1, MPFR_RNDN); /* ex3 = high(tot - ex1) */
+
+ if (mpfr_cmp(ex2, ex3))
+ {
+ printf ("Error in ddefour test.\n");
+ printf ("ex2="); mpfr_print_binary (ex2); puts ("");
+ printf ("ex3="); mpfr_print_binary (ex3); puts ("");
+ exit (1);
+ }
+
+ mpfr_clear (ex);
+ mpfr_clear (ex1);
+ mpfr_clear (ex2);
+ mpfr_clear (ex3);
+ mpfr_clear (tot);
+ mpfr_clear (tot1);
+}
+
+/* if u = o(x-y), v = o(u-x), w = o(v+y), then x-y = u-w */
+static void
+check_two_sum (mpfr_prec_t p)
+{
+ mpfr_t x, y, u, v, w;
+ mpfr_rnd_t rnd;
+ int inexact;
+
+ mpfr_init2 (x, p);
+ mpfr_init2 (y, p);
+ mpfr_init2 (u, p);
+ mpfr_init2 (v, p);
+ mpfr_init2 (w, p);
+ mpfr_urandomb (x, RANDS);
+ mpfr_urandomb (y, RANDS);
+ if (mpfr_cmpabs (x, y) < 0)
+ mpfr_swap (x, y);
+ rnd = MPFR_RNDN;
+ inexact = test_sub (u, x, y, rnd);
+ test_sub (v, u, x, rnd);
+ mpfr_add (w, v, y, rnd);
+ /* as u = (x-y) - w, we should have inexact and w of opposite signs */
+ if (((inexact == 0) && mpfr_cmp_ui (w, 0)) ||
+ ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) ||
+ ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0)))
+ {
+ printf ("Wrong inexact flag for prec=%u, rnd=%s\n", (unsigned)p,
+ mpfr_print_rnd_mode (rnd));
+ printf ("x="); mpfr_print_binary(x); puts ("");
+ printf ("y="); mpfr_print_binary(y); puts ("");
+ printf ("u="); mpfr_print_binary(u); puts ("");
+ printf ("v="); mpfr_print_binary(v); puts ("");
+ printf ("w="); mpfr_print_binary(w); puts ("");
+ printf ("inexact = %d\n", inexact);
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (u);
+ mpfr_clear (v);
+ mpfr_clear (w);
+}
+
+#define MAX_PREC 200
+
+static void
+check_inexact (void)
+{
+ mpfr_t x, y, z, u;
+ mpfr_prec_t px, py, pu, pz;
+ int inexact, cmp;
+ mpfr_rnd_t rnd;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (u);
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_ui (x, 6, MPFR_RNDN);
+ mpfr_div_2exp (x, x, 4, MPFR_RNDN); /* x = 6/16 */
+ mpfr_set_prec (y, 2);
+ mpfr_set_si (y, -1, MPFR_RNDN);
+ mpfr_div_2exp (y, y, 4, MPFR_RNDN); /* y = -1/16 */
+ inexact = test_sub (y, y, x, MPFR_RNDN); /* y = round(-7/16) = -1/2 */
+ if (inexact >= 0)
+ {
+ printf ("Error: wrong inexact flag for -1/16 - (6/16)\n");
+ exit (1);
+ }
+
+ for (px=2; px<MAX_PREC; px++)
+ {
+ mpfr_set_prec (x, px);
+ do
+ {
+ mpfr_urandomb (x, RANDS);
+ }
+ while (mpfr_cmp_ui (x, 0) == 0);
+ for (pu=2; pu<MAX_PREC; pu++)
+ {
+ mpfr_set_prec (u, pu);
+ do
+ {
+ mpfr_urandomb (u, RANDS);
+ }
+ while (mpfr_cmp_ui (u, 0) == 0);
+ {
+ py = 2 + (randlimb () % (MAX_PREC - 2));
+ mpfr_set_prec (y, py);
+ /* warning: MPFR_EXP is undefined for 0 */
+ pz = (mpfr_cmpabs (x, u) >= 0) ? MPFR_EXP(x) - MPFR_EXP(u)
+ : MPFR_EXP(u) - MPFR_EXP(x);
+ pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u));
+ mpfr_set_prec (z, pz);
+ rnd = RND_RAND ();
+ if (test_sub (z, x, u, rnd))
+ {
+ printf ("z <- x - u should be exact\n");
+ exit (1);
+ }
+ {
+ rnd = RND_RAND ();
+ inexact = test_sub (y, x, u, rnd);
+ cmp = mpfr_cmp (y, z);
+ if (((inexact == 0) && (cmp != 0)) ||
+ ((inexact > 0) && (cmp <= 0)) ||
+ ((inexact < 0) && (cmp >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s\n",
+ mpfr_print_rnd_mode(rnd));
+ printf ("expected %d, got %d\n", cmp, inexact);
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("u="); mpfr_print_binary (u); puts ("");
+ printf ("y= "); mpfr_print_binary (y); puts ("");
+ printf ("x-u="); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (u);
+}
+
+/* Bug found by Jakub Jelinek
+ * http://bugzilla.redhat.com/643657
+ * https://gforge.inria.fr/tracker/index.php?func=detail&aid=11301
+ * The consequence can be either an assertion failure (i = 2 in the
+ * testcase below, in debug mode) or an incorrectly rounded value.
+ */
+static void
+bug20101017 (void)
+{
+ mpfr_t a, b, c;
+ int inex;
+ int i;
+
+ mpfr_init2 (a, GMP_NUMB_BITS * 2);
+ mpfr_init2 (b, GMP_NUMB_BITS);
+ mpfr_init2 (c, GMP_NUMB_BITS);
+
+ /* a = 2^(2N) + k.2^(2N-1) + 2^N and b = 1
+ with N = GMP_NUMB_BITS and k = 0 or 1.
+ c = a - b should round to the same value as a. */
+
+ for (i = 2; i <= 3; i++)
+ {
+ mpfr_set_ui_2exp (a, i, GMP_NUMB_BITS - 1, MPFR_RNDN);
+ mpfr_add_ui (a, a, 1, MPFR_RNDN);
+ mpfr_mul_2ui (a, a, GMP_NUMB_BITS, MPFR_RNDN);
+ mpfr_set_ui (b, 1, MPFR_RNDN);
+ inex = mpfr_sub (c, a, b, MPFR_RNDN);
+ mpfr_set (b, a, MPFR_RNDN);
+ if (! mpfr_equal_p (c, b))
+ {
+ printf ("Error in bug20101017 for i = %d.\n", i);
+ printf ("Expected ");
+ mpfr_out_str (stdout, 16, 0, b, MPFR_RNDN);
+ putchar ('\n');
+ printf ("Got ");
+ mpfr_out_str (stdout, 16, 0, c, MPFR_RNDN);
+ putchar ('\n');
+ exit (1);
+ }
+ if (inex >= 0)
+ {
+ printf ("Error in bug20101017 for i = %d: bad inex value.\n", i);
+ printf ("Expected negative, got %d.\n", inex);
+ exit (1);
+ }
+ }
+
+ mpfr_set_prec (a, 64);
+ mpfr_set_prec (b, 129);
+ mpfr_set_prec (c, 2);
+ mpfr_set_str_binary (b, "0.100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001E65");
+ mpfr_set_str_binary (c, "0.10E1");
+ inex = mpfr_sub (a, b, c, MPFR_RNDN);
+ if (mpfr_cmp_ui_2exp (a, 1, 64) != 0 || inex >= 0)
+ {
+ printf ("Error in mpfr_sub for b-c for b=2^64+1+2^(-64), c=1\n");
+ printf ("Expected result 2^64 with inex < 0\n");
+ printf ("Got "); mpfr_print_binary (a);
+ printf (" with inex=%d\n", inex);
+ exit (1);
+ }
+
+ mpfr_clears (a, b, c, (mpfr_ptr) 0);
+}
+
+/* hard test of rounding */
+static void
+check_rounding (void)
+{
+ mpfr_t a, b, c, res;
+ mpfr_prec_t p;
+ long k, l;
+ int i;
+
+#define MAXKL (2 * GMP_NUMB_BITS)
+ for (p = MPFR_PREC_MIN; p <= GMP_NUMB_BITS; p++)
+ {
+ mpfr_init2 (a, p);
+ mpfr_init2 (res, p);
+ mpfr_init2 (b, p + 1 + MAXKL);
+ mpfr_init2 (c, MPFR_PREC_MIN);
+
+ /* b = 2^p + 1 + 2^(-k), c = 2^(-l) */
+ for (k = 0; k <= MAXKL; k++)
+ for (l = 0; l <= MAXKL; l++)
+ {
+ mpfr_set_ui_2exp (b, 1, p, MPFR_RNDN);
+ mpfr_add_ui (b, b, 1, MPFR_RNDN);
+ mpfr_mul_2ui (b, b, k, MPFR_RNDN);
+ mpfr_add_ui (b, b, 1, MPFR_RNDN);
+ mpfr_div_2ui (b, b, k, MPFR_RNDN);
+ mpfr_set_ui_2exp (c, 1, -l, MPFR_RNDN);
+ i = mpfr_sub (a, b, c, MPFR_RNDN);
+ /* b - c = 2^p + 1 + 2^(-k) - 2^(-l), should be rounded to
+ 2^p for l <= k, and 2^p+2 for l < k */
+ if (l <= k)
+ {
+ if (mpfr_cmp_ui_2exp (a, 1, p) != 0)
+ {
+ printf ("Wrong result in check_rounding\n");
+ printf ("p=%lu k=%ld l=%ld\n", (unsigned long) p, k, l);
+ printf ("b="); mpfr_print_binary (b); puts ("");
+ printf ("c="); mpfr_print_binary (c); puts ("");
+ printf ("Expected 2^%lu\n", (unsigned long) p);
+ printf ("Got "); mpfr_print_binary (a); puts ("");
+ exit (1);
+ }
+ if (i >= 0)
+ {
+ printf ("Wrong ternary value in check_rounding\n");
+ printf ("p=%lu k=%ld l=%ld\n", (unsigned long) p, k, l);
+ printf ("b="); mpfr_print_binary (b); puts ("");
+ printf ("c="); mpfr_print_binary (c); puts ("");
+ printf ("a="); mpfr_print_binary (a); puts ("");
+ printf ("Expected < 0, got %d\n", i);
+ exit (1);
+ }
+ }
+ else /* l < k */
+ {
+ mpfr_set_ui_2exp (res, 1, p, MPFR_RNDN);
+ mpfr_add_ui (res, res, 2, MPFR_RNDN);
+ if (mpfr_cmp (a, res) != 0)
+ {
+ printf ("Wrong result in check_rounding\n");
+ printf ("b="); mpfr_print_binary (b); puts ("");
+ printf ("c="); mpfr_print_binary (c); puts ("");
+ printf ("Expected "); mpfr_print_binary (res); puts ("");
+ printf ("Got "); mpfr_print_binary (a); puts ("");
+ exit (1);
+ }
+ if (i <= 0)
+ {
+ printf ("Wrong ternary value in check_rounding\n");
+ printf ("b="); mpfr_print_binary (b); puts ("");
+ printf ("c="); mpfr_print_binary (c); puts ("");
+ printf ("Expected > 0, got %d\n", i);
+ exit (1);
+ }
+ }
+ }
+
+ mpfr_clear (a);
+ mpfr_clear (res);
+ mpfr_clear (b);
+ mpfr_clear (c);
+ }
+}
+
+#define TEST_FUNCTION test_sub
+#define TWO_ARGS
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_prec_t p;
+ unsigned int i;
+
+ tests_start_mpfr ();
+
+ bug20101017 ();
+ check_rounding ();
+ check_diverse ();
+ check_inexact ();
+ bug_ddefour ();
+ for (p=2; p<200; p++)
+ for (i=0; i<50; i++)
+ check_two_sum (p);
+ test_generic (2, 800, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsub1sp.c b/mpfr/tests/tsub1sp.c
new file mode 100644
index 0000000000..3f222eca13
--- /dev/null
+++ b/mpfr/tests/tsub1sp.c
@@ -0,0 +1,515 @@
+/* Test file for mpfr_sub1sp.
+
+Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void check_special (void);
+static void check_random (mpfr_prec_t p);
+
+int
+main (void)
+{
+ mpfr_prec_t p;
+
+ tests_start_mpfr ();
+
+ check_special ();
+ for (p = 2 ; p < 200 ; p++)
+ check_random (p);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#define STD_ERROR \
+ do \
+ { \
+ printf("ERROR: for %s and p=%lu and i=%d:\nY=", \
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \
+ mpfr_print_binary(y); \
+ printf("\nZ="); mpfr_print_binary(z); \
+ printf("\nReal: "); mpfr_print_binary(x2); \
+ printf("\nGot : "); mpfr_print_binary(x); \
+ putchar('\n'); \
+ exit(1); \
+ } \
+ while (0)
+
+#define STD_ERROR2 \
+ do \
+ { \
+ printf("ERROR: for %s and p=%lu and i=%d:\nY=", \
+ mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \
+ mpfr_print_binary(y); \
+ printf("\nZ="); mpfr_print_binary(z); \
+ printf("\nR="); mpfr_print_binary(x); \
+ printf("\nWrong inexact flag. Real: %d. Got: %d\n", \
+ inexact1, inexact2); \
+ exit(1); \
+ } \
+ while (0)
+
+static void
+check_random (mpfr_prec_t p)
+{
+ mpfr_t x,y,z,x2;
+ int r;
+ int i, inexact1, inexact2;
+
+ mpfr_inits2 (p, x, y, z, x2, (mpfr_ptr) 0);
+
+ for (i = 0 ; i < 500 ; i++)
+ {
+ mpfr_urandomb (y, RANDS);
+ mpfr_urandomb (z, RANDS);
+ if (MPFR_IS_PURE_FP(y) && MPFR_IS_PURE_FP(z))
+ for(r = 0 ; r < MPFR_RND_MAX ; r++)
+ {
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+ }
+ }
+
+ mpfr_clears (x, y, z, x2, (mpfr_ptr) 0);
+}
+
+static void
+check_special (void)
+{
+ mpfr_t x,y,z,x2;
+ int r;
+ mpfr_prec_t p;
+ int i = -1, inexact1, inexact2;
+ mpfr_exp_t es;
+
+ mpfr_inits (x, y, z, x2, (mpfr_ptr) 0);
+
+ for (r = 0 ; r < MPFR_RND_MAX ; r++)
+ {
+ p = 53;
+ mpfr_set_prec(x, 53);
+ mpfr_set_prec(x2, 53);
+ mpfr_set_prec(y, 53);
+ mpfr_set_prec(z, 53);
+
+ mpfr_set_str_binary (y,
+ "0.10110111101101110010010010011011000001101101011011001E31");
+
+ mpfr_sub1sp (x, y, y, (mpfr_rnd_t) r);
+ if (mpfr_cmp_ui(x, 0))
+ {
+ printf("Error for x-x with p=%lu. Expected 0. Got:",
+ (unsigned long) p);
+ mpfr_print_binary(x);
+ exit(1);
+ }
+
+ mpfr_set(z, y, (mpfr_rnd_t) r);
+ mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp_ui(x, 0))
+ {
+ printf("Error for x-y with y=x and p=%lu. Expected 0. Got:",
+ (unsigned long) p);
+ mpfr_print_binary(x);
+ exit(1);
+ }
+ /* diff = 0 */
+ mpfr_set_str_binary (y,
+ "0.10110111101101110010010010011011001001101101011011001E31");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ /* Diff = 1 */
+ mpfr_set_str_binary (y,
+ "0.10110111101101110010010010011011000001101101011011001E30");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ /* Diff = 2 */
+ mpfr_set_str_binary (y,
+ "0.10110111101101110010010010011011000101101101011011001E32");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ /* Diff = 32 */
+ mpfr_set_str_binary (y,
+ "0.10110111101101110010010010011011000001101101011011001E63");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ /* Diff = 52 */
+ mpfr_set_str_binary (y,
+ "0.10110111101101110010010010011011010001101101011011001E83");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ /* Diff = 53 */
+ mpfr_set_str_binary (y,
+ "0.10110111101101110010010010011111000001101101011011001E31");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ /* Diff > 200 */
+ mpfr_set_str_binary (y,
+ "0.10110111101101110010010010011011000001101101011011001E331");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.10000000000000000000000000000000000000000000000000000E31");
+ mpfr_set_str_binary (z,
+ "0.11111111111111111111111111111111111111111111111111111E30");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.10000000000000000000000000000000000000000000000000000E31");
+ mpfr_set_str_binary (z,
+ "0.11111111111111111111111111111111111111111111111111111E29");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.10000000000000000000000000000000000000000000000000000E52");
+ mpfr_set_str_binary (z,
+ "0.10000000000010000000000000000000000000000000000000000E00");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.11100000000000000000000000000000000000000000000000000E53");
+ mpfr_set_str_binary (z,
+ "0.10000000000000000000000000000000000000000000000000000E00");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(z, y, z, (mpfr_rnd_t) r);
+ mpfr_set(x, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.10000000000000000000000000000000000000000000000000000E53");
+ mpfr_set_str_binary (z,
+ "0.10100000000000000000000000000000000000000000000000000E00");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.10000000000000000000000000000000000000000000000000000E54");
+ mpfr_set_str_binary (z,
+ "0.10100000000000000000000000000000000000000000000000000E00");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ p = 63;
+ mpfr_set_prec(x, p);
+ mpfr_set_prec(x2, p);
+ mpfr_set_prec(y, p);
+ mpfr_set_prec(z, p);
+ mpfr_set_str_binary (y,
+ "0.100000000000000000000000000000000000000000000000000000000000000E62");
+ mpfr_set_str_binary (z,
+ "0.110000000000000000000000000000000000000000000000000000000000000E00");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ p = 64;
+ mpfr_set_prec(x, 64);
+ mpfr_set_prec(x2, 64);
+ mpfr_set_prec(y, 64);
+ mpfr_set_prec(z, 64);
+
+ mpfr_set_str_binary (y,
+ "0.1100000000000000000000000000000000000000000000000000000000000000E31");
+ mpfr_set_str_binary (z,
+ "0.1111111111111111111111111110000000000000000000000000011111111111E29");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.1000000000000000000000000000000000000000000000000000000000000000E63");
+ mpfr_set_str_binary (z,
+ "0.1011000000000000000000000000000000000000000000000000000000000000E00");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.1000000000000000000000000000000000000000000000000000000000000000E63");
+ mpfr_set_str_binary (z,
+ "0.1110000000000000000000000000000000000000000000000000000000000000E00");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.10000000000000000000000000000000000000000000000000000000000000E63");
+ mpfr_set_str_binary (z,
+ "0.10000000000000000000000000000000000000000000000000000000000000E00");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.1000000000000000000000000000000000000000000000000000000000000000E64");
+ mpfr_set_str_binary (z,
+ "0.1010000000000000000000000000000000000000000000000000000000000000E00");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ MPFR_SET_NAN(x);
+ MPFR_SET_NAN(x2);
+ mpfr_set_str_binary (y,
+ "0.1000000000000000000000000000000000000000000000000000000000000000"
+ "E-1073741823");
+ mpfr_set_str_binary (z,
+ "0.1100000000000000000000000000000000000000000000000000000000000000"
+ "E-1073741823");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ p = 9;
+ mpfr_set_prec(x, p);
+ mpfr_set_prec(x2, p);
+ mpfr_set_prec(y, p);
+ mpfr_set_prec(z, p);
+
+ mpfr_set_str_binary (y, "0.100000000E1");
+ mpfr_set_str_binary (z, "0.100000000E-8");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ p = 34;
+ mpfr_set_prec(x, p);
+ mpfr_set_prec(x2, p);
+ mpfr_set_prec(y, p);
+ mpfr_set_prec(z, p);
+
+ mpfr_set_str_binary (y, "-0.1011110000111100010111011100110100E-18");
+ mpfr_set_str_binary (z, "0.1000101010110011010101011110000000E-14");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ p = 124;
+ mpfr_set_prec(x, p);
+ mpfr_set_prec(x2, p);
+ mpfr_set_prec(y, p);
+ mpfr_set_prec(z, p);
+
+ mpfr_set_str_binary (y,
+"0.1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1");
+ mpfr_set_str_binary (z,
+"0.1011111000100111000011001000011101010101101100101010101001000001110100001101110110001110111010000011101001100010111110001100E-31");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ p = 288;
+ mpfr_set_prec(x, p);
+ mpfr_set_prec(x2, p);
+ mpfr_set_prec(y, p);
+ mpfr_set_prec(z, p);
+
+ mpfr_set_str_binary (y,
+ "0.111000110011000001000111101010111011110011101001101111111110000011100101000001001010110010101010011001010100000001110011110001010101101010001011101110100100001011110100110000101101100011010001001011011010101010000010001101001000110010010111111011110001111101001000101101001100101100101000E80");
+ mpfr_set_str_binary (z,
+ "-0.100001111111101001011010001100110010100111001110000110011101001011010100001000000100111011010110110010000000000010101101011000010000110001110010100001100101011100100100001011000100011110000001010101000100011101001000010111100000111000111011001000100100011000100000010010111000000100100111E-258");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ p = 85;
+ mpfr_set_prec(x, p);
+ mpfr_set_prec(x2, p);
+ mpfr_set_prec(y, p);
+ mpfr_set_prec(z, p);
+
+ mpfr_set_str_binary (y,
+"0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4");
+ mpfr_set_str_binary (z,
+"0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ p = 64;
+ mpfr_set_prec(x, p); mpfr_set_prec(x2, p);
+ mpfr_set_prec(y, p); mpfr_set_prec(z, p);
+
+ mpfr_set_str_binary (y,
+ "0.11000000000000000000000000000000"
+ "00000000000000000000000000000000E1");
+ mpfr_set_str_binary (z,
+ "0.10000000000000000000000000000000"
+ "00000000000000000000000000000001E0");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.11000000000000000000000000000000"
+ "000000000000000000000000000001E1");
+ mpfr_set_str_binary (z,
+ "0.10000000000000000000000000000000"
+ "00000000000000000000000000000001E0");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ es = mpfr_get_emin ();
+ set_emin (-1024);
+
+ mpfr_set_str_binary (y,
+ "0.10000000000000000000000000000000"
+ "000000000000000000000000000000E-1023");
+ mpfr_set_str_binary (z,
+ "0.10000000000000000000000000000000"
+ "00000000000000000000000000000001E-1023");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ mpfr_set_str_binary (y,
+ "0.10000000000000000000000000000000"
+ "000000000000000000000000000000E-1023");
+ mpfr_set_str_binary (z,
+ "0.1000000000000000000000000000000"
+ "000000000000000000000000000000E-1023");
+ inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
+ inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
+ if (mpfr_cmp(x, x2))
+ STD_ERROR;
+ if (inexact1 != inexact2)
+ STD_ERROR2;
+
+ set_emin (es);
+ }
+
+ mpfr_clears (x, y, z, x2, (mpfr_ptr) 0);
+}
diff --git a/mpfr/tests/tsub_d.c b/mpfr/tests/tsub_d.c
new file mode 100644
index 0000000000..0bb727a31c
--- /dev/null
+++ b/mpfr/tests/tsub_d.c
@@ -0,0 +1,128 @@
+/* Test file for mpfr_sub_d
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+ int inexact;
+
+ mpfr_init2 (x, 123);
+ mpfr_init2 (y, 123);
+
+ /* nan - 1.0 is nan */
+ mpfr_set_nan (x);
+ mpfr_clear_flags ();
+ inexact = mpfr_sub_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* +inf - 1.0 == +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_clear_flags ();
+ inexact = mpfr_sub_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
+
+ /* -inf - 1.0 == -inf */
+ mpfr_set_inf (x, -1);
+ mpfr_clear_flags ();
+ inexact = mpfr_sub_d (y, x, 1.0, MPFR_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_sub_d
+#define DOUBLE_ARG2
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric.c"
+
+int
+main (void)
+{
+ mpfr_t x, y, z;
+ double d;
+ int inexact;
+ tests_start_mpfr ();
+
+ /* check with enough precision */
+ mpfr_init2 (x, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (y, IEEE_DBL_MANT_DIG);
+ mpfr_init2 (z, IEEE_DBL_MANT_DIG);
+
+ mpfr_set_str (y, "4096", 10, MPFR_RNDN);
+ d = 0.125;
+ mpfr_clear_flags ();
+ inexact = mpfr_sub_d (x, y, d, MPFR_RNDN);
+ if (inexact != 0)
+ {
+ printf ("Inexact flag error in mpfr_sub_d\n");
+ exit (1);
+ }
+ mpfr_set_str (z, "4095.875", 10, MPFR_RNDN);
+ if (mpfr_cmp (z, x))
+ {
+ printf ("Error in mpfr_sub_d (");
+ mpfr_out_str (stdout, 10, 7, y, MPFR_RNDN);
+ printf (" + %.20g)\nexpected ", d);
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\ngot ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clears (x, y, z, (mpfr_ptr) 0);
+
+ check_nans ();
+
+ test_generic (2, 1000, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
+
+#else
+
+int
+main (void)
+{
+ printf ("Warning! Test disabled for this MPFR version.\n");
+ return 0;
+}
+
+#endif
diff --git a/mpfr/tests/tsub_ui.c b/mpfr/tests/tsub_ui.c
new file mode 100644
index 0000000000..1d27fd9c7b
--- /dev/null
+++ b/mpfr/tests/tsub_ui.c
@@ -0,0 +1,144 @@
+/* Test file for mpfr_sub_ui
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+/* checks that x-y gives the right results with 53 bits of precision */
+static void
+check3 (const char *xs, unsigned long y, mpfr_rnd_t rnd_mode, const char *zs)
+{
+ mpfr_t xx,zz;
+
+ mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs);
+ mpfr_sub_ui (zz, xx, y, rnd_mode);
+ if (mpfr_cmp_str1(zz, zs))
+ {
+ printf ("expected sum is %s, got ", zs);
+ mpfr_print_binary(zz);
+ printf ("\nmpfr_sub_ui failed for x=%s y=%lu with rnd_mode=%s\n",
+ xs, y, mpfr_print_rnd_mode (rnd_mode));
+ exit (1);
+ }
+ mpfr_clears (xx, zz, (mpfr_ptr) 0);
+}
+
+/* FastTwoSum: if EXP(x) >= EXP(y), u = o(x+y), v = o(u-x), w = o(y-v),
+ then x + y = u + w
+thus if u = o(y-x), v = o(u+x), w = o(v-y), then y-x = u-w */
+static void
+check_two_sum (mpfr_prec_t p)
+{
+ unsigned int x;
+ mpfr_t y, u, v, w;
+ mpfr_rnd_t rnd;
+ int inexact;
+
+ mpfr_inits2 (p, y, u, v, w, (mpfr_ptr) 0);
+ do
+ {
+ x = randlimb ();
+ }
+ while (x < 1);
+ mpfr_urandomb (y, RANDS);
+ rnd = MPFR_RNDN;
+ inexact = mpfr_sub_ui (u, y, x, rnd);
+ mpfr_add_ui (v, u, x, rnd);
+ mpfr_sub (w, v, y, rnd);
+ /* as u - (y-x) = w, we should have inexact and w of same sign */
+ if (((inexact == 0) && mpfr_cmp_ui (w, 0)) ||
+ ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) ||
+ ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0)))
+ {
+ printf ("Wrong inexact flag for prec=%u, rnd=%s\n",
+ (unsigned int) p, mpfr_print_rnd_mode (rnd));
+ printf ("x=%u\n", x);
+ printf ("y="); mpfr_print_binary(y); puts ("");
+ printf ("u="); mpfr_print_binary(u); puts ("");
+ printf ("v="); mpfr_print_binary(v); puts ("");
+ printf ("w="); mpfr_print_binary(w); puts ("");
+ printf ("inexact = %d\n", inexact);
+ exit (1);
+ }
+ mpfr_clears (y, u, v, w, (mpfr_ptr) 0);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ /* nan - 1 == nan */
+ mpfr_set_nan (x);
+ mpfr_sub_ui (y, x, 1L, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* +inf - 1 == +inf */
+ mpfr_set_inf (x, 1);
+ mpfr_sub_ui (y, x, 1L, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (mpfr_sgn (y) > 0);
+
+ /* -inf - 1 == -inf */
+ mpfr_set_inf (x, -1);
+ mpfr_sub_ui (y, x, 1L, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (mpfr_sgn (y) < 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+#define TEST_FUNCTION mpfr_sub_ui
+#define INTEGER_TYPE unsigned long
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
+#include "tgeneric_ui.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_prec_t p;
+ int k;
+
+ tests_start_mpfr ();
+
+ check_nans ();
+
+ for (p=2; p<200; p++)
+ for (k=0; k<200; k++)
+ check_two_sum (p);
+
+ check3 ("0.9999999999", 1, MPFR_RNDN,
+ "-10000000827403709990903735160827636718750e-50");
+
+ test_generic_ui (2, 1000, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsubnormal.c b/mpfr/tests/tsubnormal.c
new file mode 100644
index 0000000000..5e8e275856
--- /dev/null
+++ b/mpfr/tests/tsubnormal.c
@@ -0,0 +1,222 @@
+/* Test file for mpfr_subnormalize.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+static const struct {
+ const char *in;
+ int i;
+ mpfr_rnd_t rnd;
+ const char *out;
+ int j;
+} tab[] = { /* 4th field: use the mpfr_dump format, in case of error. */
+ {"1E1", 0, MPFR_RNDN, "0.100000000E2", 0},
+ {"1E1", -1, MPFR_RNDZ, "0.100000000E2", -1},
+ {"1E1", -1, MPFR_RNDD, "0.100000000E2", -1},
+ {"1E1", 1, MPFR_RNDU, "0.100000000E2", 1},
+ {"0.10000E-10", 0, MPFR_RNDN, "0.100000000E-10", 0},
+ {"0.10001E-10", 0, MPFR_RNDN, "0.100000000E-10", -1},
+ {"0.11001E-10", 0, MPFR_RNDN, "0.100000000E-9", 1},
+ {"0.11001E-10", 0, MPFR_RNDZ, "0.100000000E-10", -1},
+ {"0.11001E-10", 0, MPFR_RNDU, "0.100000000E-9", 1},
+ {"0.11000E-10", 0, MPFR_RNDN, "0.100000000E-9", 1},
+ {"0.11000E-10", -1, MPFR_RNDN, "0.100000000E-9", 1},
+ {"0.11000E-10", 1, MPFR_RNDN, "0.100000000E-10", -1},
+ {"0.11111E-8", 0, MPFR_RNDN, "0.100000000E-7", 1},
+ {"0.10111E-8", 0, MPFR_RNDN, "0.110000000E-8", 1},
+ {"0.11110E-8", -1, MPFR_RNDN, "0.100000000E-7", 1},
+ {"0.10110E-8", 1, MPFR_RNDN, "0.101000000E-8", -1}
+};
+
+static void
+check1 (void)
+{
+ mpfr_t x;
+ int i, j, k, s, old_inex, tiny, expj;
+ mpfr_exp_t emin, emax;
+ unsigned int expflags, flags;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_set_default_prec (9);
+ mpfr_set_emin (-10);
+ mpfr_set_emax (10);
+
+ mpfr_init (x);
+ for (i = 0; i < (sizeof (tab) / sizeof (tab[0])); i++)
+ for (s = 0; s <= (tab[i].rnd == MPFR_RNDN); s++)
+ for (k = 0; k <= 1; k++)
+ {
+ mpfr_set_str (x, tab[i].in, 2, MPFR_RNDN);
+ old_inex = tab[i].i;
+ expj = tab[i].j;
+ if (s)
+ {
+ mpfr_neg (x, x, MPFR_RNDN);
+ old_inex = - old_inex;
+ expj = - expj;
+ }
+ if (k && old_inex)
+ old_inex = old_inex < 0 ? INT_MIN : INT_MAX;
+ tiny = MPFR_GET_EXP (x) <= -3;
+ mpfr_clear_flags ();
+ j = mpfr_subnormalize (x, old_inex, tab[i].rnd);
+ expflags =
+ (tiny ? MPFR_FLAGS_UNDERFLOW : 0) |
+ (expj ? MPFR_FLAGS_INEXACT : 0);
+ flags = __gmpfr_flags;
+ if (s)
+ mpfr_neg (x, x, MPFR_RNDN);
+ if (mpfr_cmp_str (x, tab[i].out, 2, MPFR_RNDN) != 0 ||
+ flags != expflags || ! SAME_SIGN (j, expj))
+ {
+ const char *sgn = s ? "-" : "";
+ printf ("Error for i = %d (old_inex = %d), k = %d, x = %s%s\n"
+ "Expected: %s%s\nGot: ", i, old_inex, k,
+ sgn, tab[i].in, sgn, tab[i].out);
+ if (s)
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_dump (x);
+ printf ("Expected flags = %u, got %u\n", expflags, flags);
+ printf ("Expected ternary value = %d, got %d\n", expj, j);
+ exit (1);
+ }
+ }
+ mpfr_clear (x);
+
+ MPFR_ASSERTN (mpfr_get_emin () == -10);
+ MPFR_ASSERTN (mpfr_get_emax () == 10);
+
+ set_emin (emin);
+ set_emax (emax);
+}
+
+/* bug found by Kevin P. Rauch on 22 Oct 2007 */
+static void
+check2 (void)
+{
+ mpfr_t x, y, z;
+ int tern;
+ mpfr_exp_t emin;
+
+ emin = mpfr_get_emin ();
+
+ mpfr_init2 (x, 32);
+ mpfr_init2 (y, 32);
+ mpfr_init2 (z, 32);
+
+ mpfr_set_ui (x, 0xC0000000U, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
+ mpfr_set_ui (y, 0xFFFFFFFEU, MPFR_RNDN);
+ mpfr_set_exp (x, 0);
+ mpfr_set_exp (y, 0);
+ mpfr_set_emin (-29);
+
+ tern = mpfr_mul (z, x, y, MPFR_RNDN);
+ /* z = -0.BFFFFFFE, tern > 0 */
+
+ tern = mpfr_subnormalize (z, tern, MPFR_RNDN);
+ /* z should be -0.75 */
+ MPFR_ASSERTN (tern < 0 && mpfr_cmp_si_2exp (z, -3, -2) == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ MPFR_ASSERTN (mpfr_get_emin () == -29);
+
+ set_emin (emin);
+}
+
+/* bug found by Kevin P. Rauch on 22 Oct 2007 */
+static void
+check3 (void)
+{
+ mpfr_t x, y, z;
+ int tern;
+ mpfr_exp_t emin;
+
+ emin = mpfr_get_emin ();
+
+ mpfr_init2 (x, 32);
+ mpfr_init2 (y, 32);
+ mpfr_init2 (z, 32);
+
+ mpfr_set_ui (x, 0xBFFFFFFFU, MPFR_RNDN); /* 3221225471/2^32 */
+ mpfr_set_ui (y, 0x80000001U, MPFR_RNDN); /* 2147483649/2^32 */
+ mpfr_set_exp (x, 0);
+ mpfr_set_exp (y, 0);
+ mpfr_set_emin (-1);
+
+ /* the exact product is 6917529028714823679/2^64, which is rounded to
+ 3/8 = 0.375, which is smaller, thus tern < 0 */
+ tern = mpfr_mul (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0);
+
+ tern = mpfr_subnormalize (z, tern, MPFR_RNDN);
+ /* since emin = -1, and EXP(z)=-1, z should be rounded to precision
+ EXP(z)-emin+1 = 1, i.e., z should be a multiple of the smallest possible
+ positive representable value with emin=-1, which is 1/4. The two
+ possible values are 1/4 and 2/4, which are at equal distance of z.
+ But since tern < 0, we should choose the largest value, i.e., 2/4. */
+ MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0);
+
+ /* here is another test for the alternate case, where z was rounded up
+ first, thus we have to round down */
+ mpfr_set_str_binary (x, "0.11111111111010110101011011011011");
+ mpfr_set_str_binary (y, "0.01100000000001111100000000001110");
+ tern = mpfr_mul (z, x, y, MPFR_RNDN);
+ MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 3, -3) == 0);
+ tern = mpfr_subnormalize (z, tern, MPFR_RNDN);
+ MPFR_ASSERTN (tern < 0 && mpfr_cmp_ui_2exp (z, 1, -2) == 0);
+
+ /* finally the case where z was exact, which we simulate here */
+ mpfr_set_ui_2exp (z, 3, -3, MPFR_RNDN);
+ tern = mpfr_subnormalize (z, 0, MPFR_RNDN);
+ MPFR_ASSERTN (tern > 0 && mpfr_cmp_ui_2exp (z, 1, -1) == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ MPFR_ASSERTN (mpfr_get_emin () == -1);
+
+ set_emin (emin);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check1 ();
+ check2 ();
+ check3 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tsum.c b/mpfr/tests/tsum.c
new file mode 100644
index 0000000000..04fdab140e
--- /dev/null
+++ b/mpfr/tests/tsum.c
@@ -0,0 +1,320 @@
+/* tsum -- test file for the list summation function
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "mpfr-test.h"
+
+static int
+check_is_sorted (unsigned long n, mpfr_srcptr *perm)
+{
+ unsigned long i;
+
+ for (i = 0; i < n - 1; i++)
+ if (MPFR_GET_EXP(perm[i]) < MPFR_GET_EXP(perm[i+1]))
+ return 0;
+ return 1;
+}
+
+static int
+sum_tab (mpfr_ptr ret, mpfr_t *tab, unsigned long n, mpfr_rnd_t rnd)
+{
+ mpfr_ptr *tabtmp;
+ unsigned long i;
+ int inexact;
+ MPFR_TMP_DECL(marker);
+
+ MPFR_TMP_MARK(marker);
+ tabtmp = (mpfr_ptr *) MPFR_TMP_ALLOC(n * sizeof(mpfr_srcptr));
+ for (i = 0; i < n; i++)
+ tabtmp[i] = tab[i];
+
+ inexact = mpfr_sum (ret, tabtmp, n, rnd);
+ MPFR_TMP_FREE(marker);
+ return inexact;
+}
+
+
+static mpfr_prec_t
+get_prec_max (mpfr_t *tab, unsigned long n, mpfr_prec_t f)
+{
+ mpfr_prec_t res;
+ mpfr_exp_t min, max;
+ unsigned long i;
+
+ i = 0;
+ while (MPFR_IS_ZERO (tab[i]))
+ {
+ i++;
+ if (i == n)
+ return MPFR_PREC_MIN; /* all values are 0 */
+ }
+
+ if (! mpfr_check (tab[i]))
+ {
+ printf ("tab[%lu] is not valid.\n", i);
+ exit (1);
+ }
+ MPFR_ASSERTN (MPFR_IS_FP (tab[i]));
+ min = max = MPFR_GET_EXP(tab[i]);
+ for (i++; i < n; i++)
+ {
+ if (! mpfr_check (tab[i]))
+ {
+ printf ("tab[%lu] is not valid.\n", i);
+ exit (1);
+ }
+ MPFR_ASSERTN (MPFR_IS_FP (tab[i]));
+ if (! MPFR_IS_ZERO (tab[i]))
+ {
+ if (MPFR_GET_EXP(tab[i]) > max)
+ max = MPFR_GET_EXP(tab[i]);
+ if (MPFR_GET_EXP(tab[i]) < min)
+ min = MPFR_GET_EXP(tab[i]);
+ }
+ }
+ res = max - min;
+ res += f;
+ res += __gmpfr_ceil_log2 (n) + 1;
+ return res;
+}
+
+
+static void
+algo_exact (mpfr_t somme, mpfr_t *tab, unsigned long n, mpfr_prec_t f)
+{
+ unsigned long i;
+ mpfr_prec_t prec_max;
+
+ prec_max = get_prec_max(tab, n, f);
+ mpfr_set_prec (somme, prec_max);
+ mpfr_set_ui (somme, 0, MPFR_RNDN);
+ for (i = 0; i < n; i++)
+ {
+ if (mpfr_add(somme, somme, tab[i], MPFR_RNDN))
+ {
+ printf ("FIXME: algo_exact is buggy.\n");
+ exit (1);
+ }
+ }
+}
+
+/* Test the sorting function */
+static void
+test_sort (mpfr_prec_t f, unsigned long n)
+{
+ mpfr_t *tab;
+ mpfr_ptr *tabtmp;
+ mpfr_srcptr *perm;
+ unsigned long i;
+
+ /* Init stuff */
+ tab = (mpfr_t *) (*__gmp_allocate_func) (n * sizeof (mpfr_t));
+ for (i = 0; i < n; i++)
+ mpfr_init2 (tab[i], f);
+ tabtmp = (mpfr_ptr *) (*__gmp_allocate_func) (n * sizeof(mpfr_ptr));
+ perm = (mpfr_srcptr *) (*__gmp_allocate_func) (n * sizeof(mpfr_srcptr));
+
+ for (i = 0; i < n; i++)
+ {
+ mpfr_urandomb (tab[i], RANDS);
+ tabtmp[i] = tab[i];
+ }
+
+ mpfr_sum_sort ((mpfr_srcptr *)tabtmp, n, perm);
+
+ if (check_is_sorted (n, perm) == 0)
+ {
+ printf ("mpfr_sum_sort incorrect.\n");
+ for (i = 0; i < n; i++)
+ mpfr_dump (perm[i]);
+ exit (1);
+ }
+
+ /* Clear stuff */
+ for (i = 0; i < n; i++)
+ mpfr_clear (tab[i]);
+ (*__gmp_free_func) (tab, n * sizeof (mpfr_t));
+ (*__gmp_free_func) (tabtmp, n * sizeof(mpfr_ptr));
+ (*__gmp_free_func) (perm, n * sizeof(mpfr_srcptr));
+}
+
+static void
+test_sum (mpfr_prec_t f, unsigned long n)
+{
+ mpfr_t sum, real_sum, real_non_rounded;
+ mpfr_t *tab;
+ unsigned long i;
+ int rnd_mode;
+
+ /* Init */
+ tab = (mpfr_t *) (*__gmp_allocate_func) (n * sizeof(mpfr_t));
+ for (i = 0; i < n; i++)
+ mpfr_init2 (tab[i], f);
+ mpfr_inits2 (f, sum, real_sum, real_non_rounded, (mpfr_ptr) 0);
+
+ /* First Uniform */
+ for (i = 0; i < n; i++)
+ mpfr_urandomb (tab[i], RANDS);
+ algo_exact (real_non_rounded, tab, n, f);
+ for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++)
+ {
+ sum_tab (sum, tab, n, (mpfr_rnd_t) rnd_mode);
+ mpfr_set (real_sum, real_non_rounded, (mpfr_rnd_t) rnd_mode);
+ if (mpfr_cmp (real_sum, sum) != 0)
+ {
+ printf ("mpfr_sum incorrect.\n");
+ mpfr_dump (real_sum);
+ mpfr_dump (sum);
+ exit (1);
+ }
+ }
+
+ /* Then non uniform */
+ for (i = 0; i < n; i++)
+ {
+ mpfr_urandomb (tab[i], RANDS);
+ if (! mpfr_zero_p (tab[i]))
+ mpfr_set_exp (tab[i], randlimb () % 1000);
+ }
+ algo_exact (real_non_rounded, tab, n, f);
+ for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++)
+ {
+ sum_tab (sum, tab, n, (mpfr_rnd_t) rnd_mode);
+ mpfr_set (real_sum, real_non_rounded, (mpfr_rnd_t) rnd_mode);
+ if (mpfr_cmp (real_sum, sum) != 0)
+ {
+ printf ("mpfr_sum incorrect.\n");
+ mpfr_dump (real_sum);
+ mpfr_dump (sum);
+ exit (1);
+ }
+ }
+
+ /* Clear stuff */
+ for (i = 0; i < n; i++)
+ mpfr_clear (tab[i]);
+ mpfr_clears (sum, real_sum, real_non_rounded, (mpfr_ptr) 0);
+ (*__gmp_free_func) (tab, n * sizeof(mpfr_t));
+}
+
+static
+void check_special (void)
+{
+ mpfr_t tab[3], r;
+ mpfr_ptr tabp[3];
+ int i;
+
+ mpfr_inits (tab[0], tab[1], tab[2], r, (mpfr_ptr) 0);
+ tabp[0] = tab[0];
+ tabp[1] = tab[1];
+ tabp[2] = tab[2];
+
+ i = mpfr_sum (r, tabp, 0, MPFR_RNDN);
+ if (!MPFR_IS_ZERO (r) || !MPFR_IS_POS (r) || i != 0)
+ {
+ printf ("Special case n==0 failed!\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (tab[0], 42, MPFR_RNDN);
+ i = mpfr_sum (r, tabp, 1, MPFR_RNDN);
+ if (mpfr_cmp_ui (r, 42) || i != 0)
+ {
+ printf ("Special case n==1 failed!\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (tab[1], 17, MPFR_RNDN);
+ MPFR_SET_NAN (tab[2]);
+ i = mpfr_sum (r, tabp, 3, MPFR_RNDN);
+ if (!MPFR_IS_NAN (r) || i != 0)
+ {
+ printf ("Special case NAN failed!\n");
+ exit (1);
+ }
+
+ MPFR_SET_INF (tab[2]);
+ MPFR_SET_POS (tab[2]);
+ i = mpfr_sum (r, tabp, 3, MPFR_RNDN);
+ if (!MPFR_IS_INF (r) || !MPFR_IS_POS (r) || i != 0)
+ {
+ printf ("Special case +INF failed!\n");
+ exit (1);
+ }
+
+ MPFR_SET_INF (tab[2]);
+ MPFR_SET_NEG (tab[2]);
+ i = mpfr_sum (r, tabp, 3, MPFR_RNDN);
+ if (!MPFR_IS_INF (r) || !MPFR_IS_NEG (r) || i != 0)
+ {
+ printf ("Special case -INF failed!\n");
+ exit (1);
+ }
+
+ MPFR_SET_ZERO (tab[1]);
+ i = mpfr_sum (r, tabp, 2, MPFR_RNDN);
+ if (mpfr_cmp_ui (r, 42) || i != 0)
+ {
+ printf ("Special case 42+0 failed!\n");
+ exit (1);
+ }
+
+ MPFR_SET_NAN (tab[0]);
+ i = mpfr_sum (r, tabp, 3, MPFR_RNDN);
+ if (!MPFR_IS_NAN (r) || i != 0)
+ {
+ printf ("Special case NAN+0+-INF failed!\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (tab[0], 1);
+ mpfr_set_ui (tab[1], 59, MPFR_RNDN);
+ mpfr_set_inf (tab[2], -1);
+ i = mpfr_sum (r, tabp, 3, MPFR_RNDN);
+ if (!MPFR_IS_NAN (r) || i != 0)
+ {
+ printf ("Special case +INF + 59 +-INF failed!\n");
+ exit (1);
+ }
+
+ mpfr_clears (tab[0], tab[1], tab[2], r, (mpfr_ptr) 0);
+}
+
+
+int
+main (void)
+{
+ mpfr_prec_t p;
+ unsigned long n;
+
+ tests_start_mpfr ();
+
+ check_special ();
+ test_sort (1764, 1026);
+ for (p = 2 ; p < 444 ; p += 17)
+ for (n = 2 ; n < 1026 ; n += 42 + p)
+ test_sum (p, n);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tswap.c b/mpfr/tests/tswap.c
new file mode 100644
index 0000000000..edb7cb1f47
--- /dev/null
+++ b/mpfr/tests/tswap.c
@@ -0,0 +1,51 @@
+/* Test file for mpfr_swap.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ mpfr_t u, v;
+
+ tests_start_mpfr ();
+
+ mpfr_init2 (u, 24);
+ mpfr_init2 (v, 53);
+ mpfr_set_ui (u, 16777215, MPFR_RNDN); /* 2^24 - 1 */
+ mpfr_set_str1 (v, "9007199254740991.0"); /* 2^53 - 1 */
+ mpfr_swap (u, v);
+ mpfr_swap (u, v);
+ if (mpfr_cmp_ui (u, 16777215) || mpfr_cmp_str1 (v, "9007199254740991.0"))
+ {
+ printf ("Error in mpfr_swap\n");
+ exit (1);
+ }
+ mpfr_clear (u);
+ mpfr_clear (v);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/ttan.c b/mpfr/tests/ttan.c
new file mode 100644
index 0000000000..cc35d78595
--- /dev/null
+++ b/mpfr/tests/ttan.c
@@ -0,0 +1,163 @@
+/* Test file for mpfr_tan.
+
+Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_tan
+#define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
+#include "tgeneric.c"
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ mpfr_set_nan (x);
+ mpfr_tan (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: tan(NaN) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, 1);
+ mpfr_tan (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: tan(Inf) != NaN\n");
+ exit (1);
+ }
+
+ mpfr_set_inf (x, -1);
+ mpfr_tan (y, x, MPFR_RNDN);
+ if (! mpfr_nan_p (y))
+ {
+ printf ("Error: tan(-Inf) != NaN\n");
+ exit (1);
+ }
+
+ /* exercise recomputation */
+ mpfr_set_prec (x, 14);
+ mpfr_set_str_binary (x, "0.10100000101010E0");
+ mpfr_set_prec (y, 24);
+ mpfr_tan (y, x, MPFR_RNDU);
+ mpfr_set_prec (x, 24);
+ mpfr_set_str_binary (x, "101110011011001100100001E-24");
+ MPFR_ASSERTN(mpfr_cmp (x, y) == 0);
+
+ /* Compute ~Pi/2 to check overflow */
+ mpfr_set_prec (x, 20000);
+ mpfr_const_pi (x, MPFR_RNDD);
+ mpfr_div_2ui (x, x, 1, MPFR_RNDN);
+ mpfr_set_prec (y, 24);
+ mpfr_tan (y, x, MPFR_RNDN);
+ if (mpfr_cmp_str (y, "0.100011101101011000100011E20001", 2, MPFR_RNDN))
+ {
+ printf("Error computing tan(~Pi/2)\n");
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ /* bug found by Kaveh Ghazi on 13 Jul 2007 */
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_str_binary (x, "0.10011100110111000001000010110100101000000000000000000E34");
+ mpfr_tan (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1000010011001010001000010100000110100111000011010101E41");
+ MPFR_ASSERTN(mpfr_cmp (x, y) == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x;
+ unsigned int i;
+ unsigned int prec[10] = {14, 15, 19, 22, 23, 24, 25, 40, 41, 52};
+ unsigned int prec2[10] = {4, 5, 6, 19, 70, 95, 100, 106, 107, 108};
+
+ tests_start_mpfr ();
+
+ check_nans ();
+
+ mpfr_init (x);
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_str (x, "0.5", 10, MPFR_RNDN);
+ mpfr_tan (x, x, MPFR_RNDD);
+ if (mpfr_cmp_ui_2exp(x, 1, -1))
+ {
+ printf ("mpfr_tan(0.5, MPFR_RNDD) failed\n"
+ "expected 0.5, got");
+ mpfr_print_binary(x);
+ putchar('\n');
+ exit (1);
+ }
+
+ /* check that tan(3*Pi/4) ~ -1 */
+ for (i=0; i<10; i++)
+ {
+ mpfr_set_prec (x, prec[i]);
+ mpfr_const_pi (x, MPFR_RNDN);
+ mpfr_mul_ui (x, x, 3, MPFR_RNDN);
+ mpfr_div_ui (x, x, 4, MPFR_RNDN);
+ mpfr_tan (x, x, MPFR_RNDN);
+ if (mpfr_cmp_si (x, -1))
+ {
+ printf ("tan(3*Pi/4) fails for prec=%u\n", prec[i]);
+ exit (1);
+ }
+ }
+
+ /* check that tan(7*Pi/4) ~ -1 */
+ for (i=0; i<10; i++)
+ {
+ mpfr_set_prec (x, prec2[i]);
+ mpfr_const_pi (x, MPFR_RNDN);
+ mpfr_mul_ui (x, x, 7, MPFR_RNDN);
+ mpfr_div_ui (x, x, 4, MPFR_RNDN);
+ mpfr_tan (x, x, MPFR_RNDN);
+ if (mpfr_cmp_si (x, -1))
+ {
+ printf ("tan(3*Pi/4) fails for prec=%u\n", prec2[i]);
+ exit (1);
+ }
+ }
+
+ mpfr_clear (x);
+
+ test_generic (2, 100, 10);
+
+ data_check ("data/tan", mpfr_tan, "mpfr_tan");
+ bad_cases (mpfr_tan, mpfr_atan, "mpfr_tan", 256, -256, 255, 4, 128, 800, 40);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/ttanh.c b/mpfr/tests/ttanh.c
new file mode 100644
index 0000000000..47d4a9e5bd
--- /dev/null
+++ b/mpfr/tests/ttanh.c
@@ -0,0 +1,138 @@
+/* Test file for mpfr_tanh.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_tanh
+#define TEST_RANDOM_EMIN -36
+#define TEST_RANDOM_EMAX 36
+#include "tgeneric.c"
+
+static void
+special (void)
+{
+ mpfr_t x;
+
+ mpfr_init (x);
+
+ mpfr_set_nan (x);
+ mpfr_tanh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (x));
+
+ mpfr_set_inf (x, 1);
+ mpfr_tanh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);
+
+ mpfr_set_inf (x, -1);
+ mpfr_tanh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_si (x, -1) == 0);
+
+ mpfr_set_prec (x, 10);
+ mpfr_set_str_binary (x, "-0.1001011001");
+ mpfr_tanh (x, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_si_2exp (x, -135, -8) == 0);
+
+ mpfr_clear (x);
+}
+
+static void
+special_overflow (void)
+{
+ mpfr_t x, y;
+ int i;
+ mpfr_exp_t emin, emax;
+
+ emin = mpfr_get_emin ();
+ emax = mpfr_get_emax ();
+
+ mpfr_clear_overflow ();
+ set_emin (-125);
+ set_emax (128);
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 24);
+
+ mpfr_set_str_binary (x, "0.101100100000000000110100E7");
+ i = mpfr_tanh (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1) || i != 1)
+ {
+ printf("Overflow error (1). i=%d\ny=", i);
+ mpfr_dump (y);
+ exit (1);
+ }
+ MPFR_ASSERTN (!mpfr_overflow_p ());
+
+ i = mpfr_tanh (y, x, MPFR_RNDZ);
+ if (mpfr_cmp_str (y, "0.111111111111111111111111E0", 2, MPFR_RNDN)
+ || i != -1)
+ {
+ printf("Overflow error (2).i=%d\ny=", i);
+ mpfr_dump (y);
+ exit (1);
+ }
+ MPFR_ASSERTN (!mpfr_overflow_p ());
+
+ set_emin (emin);
+ set_emax (emax);
+
+ mpfr_set_str_binary (x, "0.1E1000000000");
+ i = mpfr_tanh (y, x, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 1) || i != 1)
+ {
+ printf("Overflow error (3). i=%d\ny=", i);
+ mpfr_dump (y);
+ exit (1);
+ }
+ MPFR_ASSERTN (!mpfr_overflow_p ());
+ mpfr_set_str_binary (x, "-0.1E1000000000");
+ i = mpfr_tanh (y, x, MPFR_RNDU);
+ if (mpfr_cmp_str (y, "-0.111111111111111111111111E0", 2, MPFR_RNDN)
+ || i != 1)
+ {
+ printf("Overflow error (4). i=%d\ny=", i);
+ mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ special_overflow ();
+ special ();
+
+ test_generic (2, 100, 100);
+
+ data_check ("data/tanh", mpfr_tanh, "mpfr_tanh");
+ bad_cases (mpfr_tanh, mpfr_atanh, "mpfr_tanh", 256, -128, 0,
+ 4, 128, 800, 100);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/ttrunc.c b/mpfr/tests/ttrunc.c
new file mode 100644
index 0000000000..8ff16013bc
--- /dev/null
+++ b/mpfr/tests/ttrunc.c
@@ -0,0 +1,133 @@
+/* Test file for mpfr_trunc, mpfr_ceil, mpfr_floor.
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define SIZEX 100
+
+int
+main (void)
+{
+ int j, k;
+ mpfr_t x, y, z, t, y2, z2, t2;
+
+ tests_start_mpfr ();
+
+ mpfr_inits2 (SIZEX, x, y, z, t, y2, z2, t2, (mpfr_ptr) 0);
+
+ mpfr_set_str1 (x, "0.5");
+ mpfr_ceil(y, x);
+ if (mpfr_cmp_ui (y, 1))
+ {
+ printf ("Error in mpfr_ceil for x=0.5: expected 1.0, got ");
+ mpfr_print_binary(y);
+ putchar('\n');
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_ceil(y, x);
+ if (mpfr_cmp_ui(y,0))
+ {
+ printf ("Error in mpfr_ceil for x=0.0: expected 0.0, got ");
+ mpfr_print_binary(y);
+ putchar('\n');
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_ceil(y, x);
+ if (mpfr_cmp_ui(y,1))
+ {
+ printf ("Error in mpfr_ceil for x=1.0: expected 1.0, got ");
+ mpfr_print_binary(y);
+ putchar('\n');
+ exit (1);
+ }
+
+ for (j=0;j<1000;j++)
+ {
+ mpfr_urandomb (x, RANDS);
+ MPFR_EXP (x) = 2;
+
+ for (k = 2; k <= SIZEX; k++)
+ {
+ mpfr_set_prec(y, k);
+ mpfr_set_prec(y2, k);
+ mpfr_set_prec(z, k);
+ mpfr_set_prec(z2, k);
+ mpfr_set_prec(t, k);
+ mpfr_set_prec(t2, k);
+
+ mpfr_floor(y, x);
+ mpfr_set(y2, x, MPFR_RNDD);
+
+ mpfr_trunc(z, x);
+ mpfr_set(z2, x, MPFR_RNDZ);
+
+ mpfr_ceil(t, x);
+ mpfr_set(t2, x, MPFR_RNDU);
+
+ if (!mpfr_eq(y, y2, k))
+ {
+ printf("Error in floor, x = "); mpfr_print_binary(x);
+ printf("\n");
+ printf("floor(x) = "); mpfr_print_binary(y);
+ printf("\n");
+ printf("round(x, RNDD) = "); mpfr_print_binary(y2);
+ printf("\n");
+ exit(1);
+ }
+
+ if (!mpfr_eq(z, z2, k))
+ {
+ printf("Error in trunc, x = "); mpfr_print_binary(x);
+ printf("\n");
+ printf("trunc(x) = "); mpfr_print_binary(z);
+ printf("\n");
+ printf("round(x, RNDZ) = "); mpfr_print_binary(z2);
+ printf("\n");
+ exit(1);
+ }
+
+ if (!mpfr_eq(y, y2, k))
+ {
+ printf("Error in ceil, x = "); mpfr_print_binary(x);
+ printf("\n");
+ printf("ceil(x) = "); mpfr_print_binary(t);
+ printf("\n");
+ printf("round(x, RNDU) = "); mpfr_print_binary(t2);
+ printf("\n");
+ exit(1);
+ }
+ MPFR_EXP(x)++;
+ }
+ }
+
+ mpfr_clears (x, y, z, t, y2, z2, t2, (mpfr_ptr) 0);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tui_div.c b/mpfr/tests/tui_div.c
new file mode 100644
index 0000000000..ac97775626
--- /dev/null
+++ b/mpfr/tests/tui_div.c
@@ -0,0 +1,206 @@
+/* Test file for mpfr_ui_div.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+/* checks that y/x gives the right result with 53 bits of precision */
+static void
+check (unsigned long y, const char *xs, mpfr_rnd_t rnd_mode, const char *zs)
+{
+ mpfr_t xx, zz;
+
+ mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs);
+ mpfr_ui_div (zz, y, xx, rnd_mode);
+ if (mpfr_cmp_str1(zz, zs))
+ {
+ printf ("expected quotient is %s, got ", zs);
+ mpfr_out_str (stdout, 10, 0, zz, MPFR_RNDN);
+ printf ("mpfr_ui_div failed for y=%lu x=%s with rnd_mode=%s\n",
+ y, xs, mpfr_print_rnd_mode (rnd_mode));
+ exit (1);
+ }
+ mpfr_clears (xx, zz, (mpfr_ptr) 0);
+}
+
+static void
+check_inexact (void)
+{
+ mpfr_t x, y, z;
+ mpfr_prec_t px, py;
+ int inexact, cmp;
+ unsigned long int u;
+ int rnd;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+
+ for (px=2; px<300; px++)
+ {
+ mpfr_set_prec (x, px);
+ do
+ {
+ mpfr_urandomb (x, RANDS);
+ }
+ while (mpfr_cmp_ui (x, 0) == 0);
+ u = randlimb ();
+ for (py=2; py<300; py++)
+ {
+ mpfr_set_prec (y, py);
+ mpfr_set_prec (z, py + px);
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ inexact = mpfr_ui_div (y, u, x, (mpfr_rnd_t) rnd);
+ if (mpfr_mul (z, y, x, (mpfr_rnd_t) rnd))
+ {
+ printf ("z <- y * x should be exact\n");
+ exit (1);
+ }
+ cmp = mpfr_cmp_ui (z, u);
+ if (((inexact == 0) && (cmp != 0)) ||
+ ((inexact > 0) && (cmp <= 0)) ||
+ ((inexact < 0) && (cmp >= 0)))
+ {
+ printf ("Wrong inexact flag for u=%lu, rnd=%s\n",
+ u, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf ("expected %d, got %d\n", cmp, inexact);
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ printf ("y*x="); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+}
+
+static void
+check_special (void)
+{
+ mpfr_t d, q;
+
+ mpfr_init2 (d, 100L);
+ mpfr_init2 (q, 100L);
+
+ /* 1/+inf == 0 */
+ MPFR_SET_INF (d);
+ MPFR_SET_POS (d);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_number_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* 1/-inf == -0 */
+ MPFR_SET_INF (d);
+ MPFR_SET_NEG (d);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_number_p (q));
+ MPFR_ASSERTN (mpfr_sgn (q) == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* 1/nan == nan */
+ MPFR_SET_NAN (d);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_nan_p (q));
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+
+ /* 0/0 == nan */
+ mpfr_set_ui (d, 0L, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_nan_p (q));
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
+
+ /* 1/+0 = +inf */
+ mpfr_set_ui (d, 0L, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+
+ /* 1/-0 = -inf */
+ mpfr_set_ui (d, 0L, MPFR_RNDN);
+ mpfr_neg (d, d, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
+ MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
+
+ /* 0/1 = +0 */
+ mpfr_set_ui (d, 1L, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_cmp_ui (q, 0) == 0 && MPFR_IS_POS (q));
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ /* 0/-1 = -0 */
+ mpfr_set_si (d, -1, MPFR_RNDN);
+ mpfr_clear_flags ();
+ MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */
+ MPFR_ASSERTN (mpfr_cmp_ui (q, 0) == 0 && MPFR_IS_NEG (q));
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+
+ mpfr_clear (d);
+ mpfr_clear (q);
+}
+
+static int
+mpfr_inv (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r)
+{
+ return mpfr_ui_div (y, 1, x, r);
+}
+
+int
+main (int argc, char *argv[])
+{
+ tests_start_mpfr ();
+
+ check_special ();
+ check_inexact ();
+ check(948002822, "1.22191250737771397120e+20", MPFR_RNDN,
+ "7.758352715731357946e-12");
+ check(1976245324, "1.25296395864546893357e+232", MPFR_RNDZ,
+ "1.5772563211925444801e-223");
+ check(740454110, "2.11496253355831863313e+183", MPFR_RNDZ,
+ "3.5010270784996976041e-175");
+ check(1690540942, "1.28278599852446657468e-276", MPFR_RNDU,
+ "1.3178666932321966062e285");
+ check(1476599377, "-2.14191393656148625995e+305", MPFR_RNDD,
+ "-6.8938315017943889615e-297");
+
+ /* inv is for 1/x */
+ data_check ("data/inv", mpfr_inv, "mpfr_ui_div(1,x)");
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tui_pow.c b/mpfr/tests/tui_pow.c
new file mode 100644
index 0000000000..c2d9ca6829
--- /dev/null
+++ b/mpfr/tests/tui_pow.c
@@ -0,0 +1,262 @@
+/* Test file for mpfr_ui_pow and mpfr_ui_pow_ui.
+
+Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "mpfr-test.h"
+
+static void
+test1 (void)
+{
+ mpfr_t x, y, z, a;
+ int res1, res2;
+
+ mpfr_init2 (x, 32);
+ mpfr_init2 (y, 65);
+ mpfr_init2 (z, 17);
+ mpfr_init2 (a, 17);
+
+ mpfr_set_str_binary (x, "-0.101110001001011011011e-9");
+ mpfr_ui_pow (y, 7, x, MPFR_RNDN);
+
+ mpfr_set_prec (x, 40);
+ mpfr_set_str_binary (x, "-0.1100101100101111011001010010110011110110E-1");
+ mpfr_set_prec (y, 74);
+ mpfr_ui_pow (y, 8, x, MPFR_RNDN);
+ mpfr_set_prec (x, 74);
+ mpfr_set_str_binary (x, "0.11100000010100111101000011111011011010011000011000101011010011010101000011E-1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for input of 40 bits, output of 74 bits\n");
+ exit (1);
+ }
+
+ /* Check for ui_pow_ui */
+ mpfr_ui_pow_ui (x, 0, 1, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS (x));
+ mpfr_ui_pow_ui (x, 0, 4, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS (x));
+ res1 = mpfr_ui_pow_ui (z, 17, 42, MPFR_RNDD);
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_set_ui (y, 42, MPFR_RNDN);
+ res2 = mpfr_pow (a, x, y, MPFR_RNDD);
+ if (mpfr_cmp (z, a) || res1 != res2)
+ {
+ printf ("Error for ui_pow_ui for 17^42\n"
+ "Inexact1 = %d Inexact2 = %d\n", res1, res2);
+ mpfr_dump (z);
+ mpfr_dump (a);
+ exit (1);
+ }
+ mpfr_set_prec (x, 2);
+ mpfr_ui_pow_ui (x, 65537, 65535, MPFR_RNDN);
+ if (mpfr_cmp_str (x, "0.11E1048562", 2, MPFR_RNDN) != 0)
+ {
+ printf ("Error for ui_pow_ui for 65537 ^65535 with 2 bits of precision\n");
+ mpfr_dump (x);
+ exit (1);
+ }
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (a);
+}
+
+static void
+check1 (mpfr_ptr x, mpfr_prec_t prec, unsigned long nt, mpfr_rnd_t rnd)
+{
+ mpfr_t y, z, t;
+ int inexact, compare, compare2;
+ mpfr_prec_t yprec;
+ mpfr_exp_t err;
+
+ yprec = prec + 10;
+
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (t);
+ mpfr_set_prec (y, yprec);
+ mpfr_set_prec (z, prec);
+ mpfr_set_prec (t, prec);
+
+ compare = mpfr_ui_pow (y, nt, x, rnd);
+ err = (rnd == MPFR_RNDN) ? yprec + 1 : yprec;
+ if (mpfr_can_round (y, err, rnd, rnd, prec))
+ {
+ mpfr_set (t, y, rnd);
+ inexact = mpfr_ui_pow (z, nt, x, rnd);
+ if (mpfr_cmp (t, z))
+ {
+ printf ("results differ for x=");
+ mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
+ printf (" n=%lu", nt);
+ printf (" prec=%u rnd_mode=%s\n", (unsigned) prec,
+ mpfr_print_rnd_mode (rnd));
+ printf ("got ");
+ mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
+ puts ("");
+ printf ("expected ");
+ mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
+ puts ("");
+ printf ("approx ");
+ mpfr_print_binary (y);
+ puts ("");
+ exit (1);
+ }
+ compare2 = mpfr_cmp (t, y);
+ /* if rounding to nearest, cannot know the sign of t - f(x)
+ because of composed rounding: y = o(f(x)) and t = o(y) */
+ if ((rnd != MPFR_RNDN) && (compare * compare2 >= 0))
+ compare = compare + compare2;
+ else
+ compare = inexact; /* cannot determine sign(t-f(x)) */
+ if (((inexact == 0) && (compare != 0)) ||
+ ((inexact > 0) && (compare <= 0)) ||
+ ((inexact < 0) && (compare >= 0)))
+ {
+ printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n",
+ mpfr_print_rnd_mode (rnd), compare, inexact);
+ printf ("x="); mpfr_print_binary (x); puts ("");
+ printf ("y="); mpfr_print_binary (y); puts ("");
+ printf ("t="); mpfr_print_binary (t); puts ("");
+ exit (1);
+ }
+ }
+
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ unsigned long int n;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ n = randlimb ();
+
+ MPFR_SET_INF(x);
+ mpfr_ui_pow (y, n, x, MPFR_RNDN);
+ if(!MPFR_IS_INF(y))
+ {
+ printf ("evaluation of function in INF does not return INF\n");
+ exit (1);
+ }
+
+ MPFR_CHANGE_SIGN(x);
+ mpfr_ui_pow (y, n, x, MPFR_RNDN);
+ if(!MPFR_IS_ZERO(y))
+ {
+ printf ("evaluation of function in -INF does not return 0");
+ exit (1);
+ }
+
+ MPFR_SET_NAN(x);
+ mpfr_ui_pow (y, n, x, MPFR_RNDN);
+ if(!MPFR_IS_NAN(y))
+ {
+ printf ("evaluation of function in NAN does not return NAN");
+ exit (1);
+ }
+
+ test1 ();
+
+ {
+ mpfr_t z, t;
+ mpfr_prec_t prec;
+ mpfr_rnd_t rnd;
+ unsigned int n;
+
+ mpfr_prec_t p0=2, p1=100;
+ unsigned int N=20;
+
+ mpfr_init2 (z, 38);
+ mpfr_init2 (t, 6);
+
+ /* check exact power */
+ mpfr_set_str_binary (t, "0.110000E5");
+ mpfr_ui_pow (z, 3, t, MPFR_RNDN);
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 2);
+ mpfr_set_str (x, "-0.5", 10, MPFR_RNDZ);
+ mpfr_ui_pow (y, 4, x, MPFR_RNDD);
+ if (mpfr_cmp_ui_2exp(y, 1, -1))
+ {
+ fprintf (stderr, "Error for 4^(-0.5), prec=2, MPFR_RNDD\n");
+ fprintf (stderr, "expected 0.5, got ");
+ mpfr_out_str (stderr, 2, 0, y, MPFR_RNDN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+
+ /* problem found by Kevin on spe175.testdrive.compaq.com
+ (03 Sep 2003), ia64 under HP-UX */
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 2);
+ mpfr_set_str (x, "0.5", 10, MPFR_RNDN);
+ mpfr_ui_pow (y, 398441521, x, MPFR_RNDN);
+ if (mpfr_cmp_ui_2exp(y, 1, 14))
+ {
+ fprintf (stderr, "Error for 398441521^(0.5), prec=2, MPFR_RNDN\n");
+ fprintf (stderr, "expected 1.0e14, got ");
+ mpfr_out_str (stderr, 2, 0, y, MPFR_RNDN);
+ fprintf (stderr, "\n");
+ exit (1);
+ }
+
+ mpfr_clear (z);
+ mpfr_clear (t);
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_str (x, "0.5", 10, MPFR_RNDN);
+ check1 (x, 2, 398441521, MPFR_RNDN); /* 398441521 = 19961^2 */
+
+ /* generic test */
+ for (prec = p0; prec <= p1; prec++)
+ {
+ mpfr_set_prec (x, prec);
+ for (n=0; n<N; n++)
+ {
+ int nt;
+ nt = randlimb () & INT_MAX;
+ mpfr_urandomb (x, RANDS);
+ rnd = RND_RAND ();
+ check1 (x, prec, nt, rnd);
+ }
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tui_sub.c b/mpfr/tests/tui_sub.c
new file mode 100644
index 0000000000..9d6b1e1c8b
--- /dev/null
+++ b/mpfr/tests/tui_sub.c
@@ -0,0 +1,301 @@
+/* Test file for mpfr_ui_sub.
+
+Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "mpfr-test.h"
+
+static void
+special (void)
+{
+ mpfr_t x, y, res;
+ int inexact;
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (res);
+
+ mpfr_set_prec (x, 24);
+ mpfr_set_prec (y, 24);
+ mpfr_set_str_binary (y, "0.111100110001011010111");
+ inexact = mpfr_ui_sub (x, 1, y, MPFR_RNDN);
+ if (inexact)
+ {
+ printf ("Wrong inexact flag: got %d, expected 0\n", inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 24);
+ mpfr_set_prec (y, 24);
+ mpfr_set_str_binary (y, "0.111100110001011010111");
+ if ((inexact = mpfr_ui_sub (x, 38181761, y, MPFR_RNDN)) >= 0)
+ {
+ printf ("Wrong inexact flag: got %d, expected -1\n", inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 63);
+ mpfr_set_prec (y, 63);
+ mpfr_set_str_binary (y, "0.111110010010100100110101101010001001100101110001000101110111111E-1");
+ if ((inexact = mpfr_ui_sub (x, 1541116494, y, MPFR_RNDN)) <= 0)
+ {
+ printf ("Wrong inexact flag: got %d, expected +1\n", inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 32);
+ mpfr_set_prec (y, 32);
+ mpfr_set_str_binary (y, "0.11011000110111010001011100011100E-1");
+ if ((inexact = mpfr_ui_sub (x, 2000375416, y, MPFR_RNDN)) >= 0)
+ {
+ printf ("Wrong inexact flag: got %d, expected -1\n", inexact);
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 24);
+ mpfr_set_prec (y, 24);
+ mpfr_set_str_binary (y, "0.110011011001010011110111E-2");
+ if ((inexact = mpfr_ui_sub (x, 927694848, y, MPFR_RNDN)) <= 0)
+ {
+ printf ("Wrong inexact flag: got %d, expected +1\n", inexact);
+ exit (1);
+ }
+
+ /* bug found by Mathieu Dutour, 12 Apr 2001 */
+ mpfr_set_prec (x, 5);
+ mpfr_set_prec (y, 5);
+ mpfr_set_prec (res, 5);
+ mpfr_set_str_binary (x, "1e-12");
+
+ mpfr_ui_sub (y, 1, x, MPFR_RNDD);
+ mpfr_set_str_binary (res, "0.11111");
+ if (mpfr_cmp (y, res))
+ {
+ printf ("Error in mpfr_ui_sub (y, 1, x, MPFR_RNDD) for x=2^(-12)\nexpected 1.1111e-1, got ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_ui_sub (y, 1, x, MPFR_RNDU);
+ mpfr_set_str_binary (res, "1.0");
+ if (mpfr_cmp (y, res))
+ {
+ printf ("Error in mpfr_ui_sub (y, 1, x, MPFR_RNDU) for x=2^(-12)\n"
+ "expected 1.0, got ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_ui_sub (y, 1, x, MPFR_RNDN);
+ mpfr_set_str_binary (res, "1.0");
+ if (mpfr_cmp (y, res))
+ {
+ printf ("Error in mpfr_ui_sub (y, 1, x, MPFR_RNDN) for x=2^(-12)\n"
+ "expected 1.0, got ");
+ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 10);
+ mpfr_set_prec (y, 10);
+ mpfr_urandomb (x, RANDS);
+ mpfr_ui_sub (y, 0, x, MPFR_RNDN);
+ if (MPFR_IS_ZERO(x))
+ MPFR_ASSERTN(MPFR_IS_ZERO(y));
+ else
+ MPFR_ASSERTN(mpfr_cmpabs (x, y) == 0 && mpfr_sgn (x) != mpfr_sgn (y));
+
+ mpfr_set_prec (x, 73);
+ mpfr_set_str_binary (x, "0.1101111010101011011011100011010000000101110001011111001011011000101111101E-99");
+ mpfr_ui_sub (x, 1, x, MPFR_RNDZ);
+ mpfr_nextabove (x);
+ MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (res);
+}
+
+/* checks that (y-x) gives the right results with 53 bits of precision */
+static void
+check (unsigned long y, const char *xs, mpfr_rnd_t rnd_mode, const char *zs)
+{
+ mpfr_t xx, zz;
+
+ mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0);
+ mpfr_set_str1 (xx, xs);
+ mpfr_ui_sub (zz, y, xx, rnd_mode);
+ if (mpfr_cmp_str1 (zz, zs) )
+ {
+ printf ("expected difference is %s, got\n",zs);
+ mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
+ printf ("mpfr_ui_sub failed for y=%lu x=%s with rnd_mode=%s\n",
+ y, xs, mpfr_print_rnd_mode (rnd_mode));
+ exit (1);
+ }
+ mpfr_clears (xx, zz, (mpfr_ptr) 0);
+}
+
+/* if u = o(x-y), v = o(u-x), w = o(v+y), then x-y = u-w */
+static void
+check_two_sum (mpfr_prec_t p)
+{
+ unsigned int x;
+ mpfr_t y, u, v, w;
+ mpfr_rnd_t rnd;
+ int inexact;
+
+ mpfr_inits2 (p, y, u, v, w, (mpfr_ptr) 0);
+ do
+ {
+ x = randlimb ();
+ }
+ while (x < 1);
+ mpfr_urandomb (y, RANDS);
+ rnd = MPFR_RNDN;
+ inexact = mpfr_ui_sub (u, x, y, rnd);
+ mpfr_sub_ui (v, u, x, rnd);
+ mpfr_add (w, v, y, rnd);
+ /* as u = (x-y) + w, we should have inexact and w of same sign */
+ if (((inexact == 0) && mpfr_cmp_ui (w, 0)) ||
+ ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) ||
+ ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0)))
+ {
+ printf ("Wrong inexact flag for prec=%u, rnd=%s\n",
+ (unsigned int) p, mpfr_print_rnd_mode (rnd));
+ printf ("x=%u\n", x);
+ printf ("y="); mpfr_print_binary(y); puts ("");
+ printf ("u="); mpfr_print_binary(u); puts ("");
+ printf ("v="); mpfr_print_binary(v); puts ("");
+ printf ("w="); mpfr_print_binary(w); puts ("");
+ printf ("inexact = %d\n", inexact);
+ exit (1);
+ }
+ mpfr_clears (y, u, v, w, (mpfr_ptr) 0);
+}
+
+static void
+check_nans (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 123L);
+ mpfr_init2 (y, 123L);
+
+ /* 1 - nan == nan */
+ mpfr_set_nan (x);
+ mpfr_ui_sub (y, 1L, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_nan_p (y));
+
+ /* 1 - +inf == -inf */
+ mpfr_set_inf (x, 1);
+ mpfr_ui_sub (y, 1L, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (mpfr_sgn (y) < 0);
+
+ /* 1 - -inf == +inf */
+ mpfr_set_inf (x, -1);
+ mpfr_ui_sub (y, 1L, x, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (mpfr_sgn (y) > 0);
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+/* Check mpfr_ui_sub with u = 0 (unsigned). */
+static void check_neg (void)
+{
+ mpfr_t x, yneg, ysub;
+ int i, s;
+ int r;
+
+ mpfr_init2 (x, 64);
+ mpfr_init2 (yneg, 32);
+ mpfr_init2 (ysub, 32);
+
+ for (i = 0; i <= 25; i++)
+ {
+ mpfr_sqrt_ui (x, i, MPFR_RNDN);
+ for (s = 0; s <= 1; s++)
+ {
+ RND_LOOP (r)
+ {
+ int tneg, tsub;
+
+ tneg = mpfr_neg (yneg, x, (mpfr_rnd_t) r);
+ tsub = mpfr_ui_sub (ysub, 0, x, (mpfr_rnd_t) r);
+ MPFR_ASSERTN (mpfr_equal_p (yneg, ysub));
+ MPFR_ASSERTN (!(MPFR_IS_POS (yneg) ^ MPFR_IS_POS (ysub)));
+ MPFR_ASSERTN (tneg == tsub);
+ }
+ mpfr_neg (x, x, MPFR_RNDN);
+ }
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (yneg);
+ mpfr_clear (ysub);
+}
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_prec_t p;
+ unsigned k;
+
+ tests_start_mpfr ();
+
+ check_nans ();
+
+ special ();
+ for (p=2; p<100; p++)
+ for (k=0; k<100; k++)
+ check_two_sum (p);
+
+ check(1196426492, "1.4218093058435347e-3", MPFR_RNDN,
+ "1.1964264919985781e9");
+ check(1092583421, "-1.0880649218158844e9", MPFR_RNDN,
+ "2.1806483428158845901e9");
+ check(948002822, "1.22191250737771397120e+20", MPFR_RNDN,
+ "-1.2219125073682338611e20");
+ check(832100416, "4.68311314939691330000e-215", MPFR_RNDD,
+ "8.3210041599999988079e8");
+ check(1976245324, "1.25296395864546893357e+232", MPFR_RNDZ,
+ "-1.2529639586454686577e232");
+ check(2128997392, "-1.08496826129284207724e+187", MPFR_RNDU,
+ "1.0849682612928422704e187");
+ check(293607738, "-1.9967571564050541e-5", MPFR_RNDU,
+ "2.9360773800002003e8");
+ check(354270183, "2.9469161763489528e3", MPFR_RNDN,
+ "3.5426723608382362e8");
+
+ check_neg ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/turandom.c b/mpfr/tests/turandom.c
new file mode 100644
index 0000000000..b99587be0b
--- /dev/null
+++ b/mpfr/tests/turandom.c
@@ -0,0 +1,249 @@
+/* Test file for mpfr_urandom
+
+Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+test_urandom (long nbtests, mpfr_prec_t prec, mpfr_rnd_t rnd, long bit_index,
+ int verbose)
+{
+ mpfr_t x;
+ int *tab, size_tab, k, sh, xn;
+ double d, av = 0, var = 0, chi2 = 0, th;
+ mpfr_exp_t emin;
+ mp_size_t limb_index = 0;
+ mp_limb_t limb_mask = 0;
+ long count = 0;
+ int i;
+ int inex = 1;
+
+ size_tab = (nbtests >= 1000 ? nbtests / 50 : 20);
+ tab = (int *) calloc (size_tab, sizeof(int));
+ if (tab == NULL)
+ {
+ fprintf (stderr, "trandom: can't allocate memory in test_urandom\n");
+ exit (1);
+ }
+
+ mpfr_init2 (x, prec);
+ xn = 1 + (prec - 1) / mp_bits_per_limb;
+ sh = xn * mp_bits_per_limb - prec;
+ if (bit_index >= 0 && bit_index < prec)
+ {
+ /* compute the limb index and limb mask to fetch the bit #bit_index */
+ limb_index = (prec - bit_index) / mp_bits_per_limb;
+ i = 1 + bit_index - (bit_index / mp_bits_per_limb) * mp_bits_per_limb;
+ limb_mask = MPFR_LIMB_ONE << (mp_bits_per_limb - i);
+ }
+
+ for (k = 0; k < nbtests; k++)
+ {
+ i = mpfr_urandom (x, RANDS, rnd);
+ inex = (i != 0) && inex;
+ /* check that lower bits are zero */
+ if (MPFR_MANT(x)[0] & MPFR_LIMB_MASK(sh) && !MPFR_IS_ZERO (x))
+ {
+ printf ("Error: mpfr_urandom() returns invalid numbers:\n");
+ mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+ /* check that the value is in [0,1] */
+ if (mpfr_cmp_ui (x, 0) < 0 || mpfr_cmp_ui (x, 1) > 0)
+ {
+ printf ("Error: mpfr_urandom() returns number outside [0, 1]:\n");
+ mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+
+ d = mpfr_get_d1 (x); av += d; var += d*d;
+ i = (int)(size_tab * d);
+ if (d == 1.0) i --;
+ tab[i]++;
+
+ if (limb_mask && (MPFR_MANT (x)[limb_index] & limb_mask))
+ count ++;
+ }
+
+ if (inex == 0)
+ {
+ /* one call in the loop pretended to return an exact number! */
+ printf ("Error: mpfr_urandom() returns a zero ternary value.\n");
+ exit (1);
+ }
+
+ /* coverage test */
+ emin = mpfr_get_emin ();
+ for (k = 0; k < 5; k++)
+ {
+ set_emin (k+1);
+ inex = mpfr_urandom (x, RANDS, rnd);
+ if (( (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
+ && (!MPFR_IS_ZERO (x) || inex != -1))
+ || ((rnd == MPFR_RNDU || rnd == MPFR_RNDA)
+ && (mpfr_cmp_ui (x, 1 << k) != 0 || inex != +1))
+ || (rnd == MPFR_RNDN
+ && (k > 0 || mpfr_cmp_ui (x, 1 << k) != 0 || inex != +1)
+ && (!MPFR_IS_ZERO (x) || inex != -1)))
+ {
+ printf ("Error: mpfr_urandom() do not handle correctly a restricted"
+ " exponent range.\nrounding mode: %s\nternary value: %d\n"
+ "random value: ", mpfr_print_rnd_mode (rnd), inex);
+ mpfr_print_binary (x); puts ("");
+ exit (1);
+ }
+ }
+ set_emin (emin);
+
+ mpfr_clear (x);
+ if (!verbose)
+ {
+ free(tab);
+ return;
+ }
+
+ av /= nbtests;
+ var = (var / nbtests) - av * av;
+
+ th = (double)nbtests / size_tab;
+ printf ("Average = %.5f\nVariance = %.5f\n", av, var);
+ printf ("Repartition for urandom with rounding mode %s. "
+ "Each integer should be close to %d.\n",
+ mpfr_print_rnd_mode (rnd), (int)th);
+
+ for (k = 0; k < size_tab; k++)
+ {
+ chi2 += (tab[k] - th) * (tab[k] - th) / th;
+ printf("%d ", tab[k]);
+ if (((k+1) & 7) == 0)
+ printf("\n");
+ }
+
+ printf("\nChi2 statistics value (with %d degrees of freedom) : %.5f\n",
+ size_tab - 1, chi2);
+
+ if (limb_mask)
+ printf ("Bit #%ld is set %ld/%ld = %.1f %% of time\n",
+ bit_index, count, nbtests, count * 100.0 / nbtests);
+
+ puts ("");
+
+ free(tab);
+ return;
+}
+
+/* problem reported by Carl Witty */
+static void
+bug20100914 (void)
+{
+ mpfr_t x;
+ gmp_randstate_t s;
+
+#if __MPFR_GMP(4,2,0)
+# define C1 "0.8488312"
+# define C2 "0.8156509"
+#else
+# define C1 "0.6485367"
+# define C2 "0.9362717"
+#endif
+
+ gmp_randinit_default (s);
+ gmp_randseed_ui (s, 42);
+ mpfr_init2 (x, 17);
+ mpfr_urandom (x, s, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, C1) != 0)
+ {
+ printf ("Error in bug20100914, expected " C1 ", got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_urandom (x, s, MPFR_RNDN);
+ if (mpfr_cmp_str1 (x, C2) != 0)
+ {
+ printf ("Error in bug20100914, expected " C2 ", got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_clear (x);
+ gmp_randclear (s);
+}
+
+int
+main (int argc, char *argv[])
+{
+ long nbtests;
+ mpfr_prec_t prec;
+ int verbose = 0;
+ int rnd;
+ long bit_index;
+
+ tests_start_mpfr ();
+
+ if (argc > 1)
+ verbose = 1;
+
+ nbtests = 10000;
+ if (argc > 1)
+ {
+ long a = atol(argv[1]);
+ if (a != 0)
+ nbtests = a;
+ }
+
+ if (argc <= 2)
+ prec = 1000;
+ else
+ prec = atol(argv[2]);
+
+ if (argc <= 3)
+ bit_index = -1;
+ else
+ {
+ bit_index = atol(argv[3]);
+ if (bit_index >= prec)
+ {
+ printf ("Warning. Cannot compute the bit frequency: the given bit "
+ "index (= %ld) is not less than the precision (= %ld).\n",
+ bit_index, (long) prec);
+ bit_index = -1;
+ }
+ }
+
+ RND_LOOP(rnd)
+ {
+ test_urandom (nbtests, prec, (mpfr_rnd_t) rnd, bit_index, verbose);
+
+ if (argc == 1) /* check also small precision */
+ {
+ test_urandom (nbtests, 2, (mpfr_rnd_t) rnd, -1, 0);
+ }
+ }
+
+ bug20100914 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tvalist.c b/mpfr/tests/tvalist.c
new file mode 100644
index 0000000000..a8f3dfd8e1
--- /dev/null
+++ b/mpfr/tests/tvalist.c
@@ -0,0 +1,76 @@
+/* Test file for multiple mpfr.h inclusion and va_list related functions
+
+Copyright 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#if HAVE_STDARG
+
+#if _MPFR_EXP_FORMAT == 4
+/* If mpfr_exp_t is defined as intmax_t, intmax_t must be defined before
+ the inclusion of mpfr.h (this test doesn't use mpfr-impl.h). */
+# include <stdint.h>
+#endif
+
+/* Assume that this is in fact a header inclusion for some library
+ that uses MPFR, i.e. this inclusion is hidden in another one.
+ MPFR currently (rev 6704) fails to handle this case. */
+#include <mpfr.h>
+
+#include <stdarg.h>
+#define MPFR_USE_VA_LIST /* necessary due to GMP bug concerning inclusions */
+#include <mpfr.h>
+
+#include <stdio.h>
+#define MPFR_USE_FILE /* necessary due to GMP bug concerning inclusions */
+#include <mpfr.h>
+
+static void
+test (FILE *fout, const char *fmt, ...)
+{
+ int (*fct) (FILE*, __gmp_const char*, va_list);
+
+ fct = mpfr_vfprintf;
+ if (0)
+ {
+ va_list ap;
+ va_start (ap, fmt);
+ fct (fout, fmt, ap);
+ va_end (ap);
+ }
+}
+
+int
+main (void)
+{
+ test (stdout, "%d\n", 0);
+ return 0;
+}
+
+#else /* HAVE_STDARG */
+
+/* The test is disabled. */
+
+int
+main (void)
+{
+ return 77;
+}
+
+#endif /* HAVE_STDARG */
diff --git a/mpfr/tests/tversion.c b/mpfr/tests/tversion.c
new file mode 100644
index 0000000000..f3bc07e331
--- /dev/null
+++ b/mpfr/tests/tversion.c
@@ -0,0 +1,84 @@
+/* Test file for mpfr_version.
+
+Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (void)
+{
+ char buffer[256];
+
+#ifdef __MPIR_VERSION
+ printf ("[tversion] MPIR: header %d.%d.%d, library %s\n",
+ __MPIR_VERSION, __MPIR_VERSION_MINOR, __MPIR_VERSION_PATCHLEVEL,
+ mpir_version);
+#else
+ printf ("[tversion] GMP: header %d.%d.%d, library %s\n",
+ __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL,
+ gmp_version);
+#endif
+ printf ("[tversion] MPFR tuning parameters from %s\n", MPFR_TUNE_CASE);
+
+ /* Test the MPFR version. */
+ test_version ();
+
+ sprintf (buffer, "%d.%d.%d", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR,
+ __GNU_MP_VERSION_PATCHLEVEL);
+ if (strcmp (buffer, gmp_version) == 0)
+ return 0;
+ if (__GNU_MP_VERSION_PATCHLEVEL == 0)
+ {
+ sprintf (buffer, "%d.%d", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR);
+ if (strcmp (buffer, gmp_version) == 0)
+ return 0;
+ }
+
+ /* In some cases, it may be acceptable to have different versions for
+ the header and the library, in particular when shared libraries are
+ used (e.g., after a bug-fix upgrade of the library, and versioning
+ ensures that this can be done only when the binary interface is
+ compatible). However, when recompiling software like here, this
+ should never happen (except if GMP has been upgraded between two
+ "make check" runs, but there's no reason for that). A difference
+ between the versions of gmp.h and libgmp probably indicates either
+ a bad configuration or some other inconsistency in the development
+ environment, and it is better to fail (in particular for automatic
+ installations). */
+ printf ("ERROR! The versions of gmp.h (%s) and libgmp (%s) do not "
+ "match.\nThe possible causes are:\n", buffer, gmp_version);
+ printf (" * A bad configuration in your include/library search paths.\n"
+ " * An inconsistency in the include/library search paths of\n"
+ " your development environment; an example:\n"
+ " http://gcc.gnu.org/ml/gcc-help/2010-11/msg00359.html\n"
+ " * GMP has been upgraded after the first \"make check\".\n"
+ " In such a case, try again after a \"make clean\".\n"
+ " * A new or non-standard version naming is used in GMP.\n"
+ " In this case, a patch may already be available on the\n"
+ " MPFR web site. Otherwise please report the problem.\n");
+ printf ("In the first two cases, this may lead to errors, in particular"
+ " with MPFR.\nIf some other tests fail, please solve that"
+ " problem first.\n");
+
+ return 1;
+}
diff --git a/mpfr/tests/ty0.c b/mpfr/tests/ty0.c
new file mode 100644
index 0000000000..87485d953b
--- /dev/null
+++ b/mpfr/tests/ty0.c
@@ -0,0 +1,98 @@
+/* ty0 -- test file for the Bessel function of second kind (order 0)
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_y0
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 8, RANDS)
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* special values */
+ mpfr_set_nan (x);
+ mpfr_y0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_inf (x, 1); /* +Inf */
+ mpfr_y0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));
+
+ mpfr_set_inf (x, -1); /* -Inf */
+ mpfr_y0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */
+ mpfr_y0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(+0)=-Inf */
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN); /* -0 */
+ mpfr_y0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(-0)=-Inf */
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_y0 (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.00010110100110000000001000100110111100110101100011011111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_y0 for x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_y0 (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error in mpfr_y0 for x=-1, rnd=MPFR_RNDN\n");
+ printf ("Expected NaN\n");
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ test_generic (2, 100, 1);
+
+ data_check ("data/y0", mpfr_y0, "mpfr_y0");
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/ty1.c b/mpfr/tests/ty1.c
new file mode 100644
index 0000000000..233e0e8939
--- /dev/null
+++ b/mpfr/tests/ty1.c
@@ -0,0 +1,98 @@
+/* ty1 -- test file for the Bessel function of second kind (order 1)
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_y1
+#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 8, RANDS)
+#include "tgeneric.c"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ /* special values */
+ mpfr_set_nan (x);
+ mpfr_y1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_inf (x, 1); /* +Inf */
+ mpfr_y1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));
+
+ mpfr_set_inf (x, -1); /* -Inf */
+ mpfr_y1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */
+ mpfr_y1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y1(+0)=-Inf */
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN); /* -0 */
+ mpfr_y1 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y1(-0)=-Inf */
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_y1 (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-0.110001111111110110010000001111101011001101011100101");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_y1 for x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_si (x, -1, MPFR_RNDN);
+ mpfr_y1 (y, x, MPFR_RNDN);
+ if (!mpfr_nan_p (y))
+ {
+ printf ("Error in mpfr_y1 for x=-1, rnd=MPFR_RNDN\n");
+ printf ("Expected NaN\n");
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ test_generic (2, 100, 1);
+
+ data_check ("data/y1", mpfr_y1, "mpfr_y1");
+
+ tests_end_mpfr ();
+
+ return 0;
+}
diff --git a/mpfr/tests/tyn.c b/mpfr/tests/tyn.c
new file mode 100644
index 0000000000..93ea4f6d63
--- /dev/null
+++ b/mpfr/tests/tyn.c
@@ -0,0 +1,192 @@
+/* tyn -- test file for the Bessel function of second kind
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+int
+main (int argc, char *argv[])
+{
+ mpfr_t x, y;
+ long n;
+ mpfr_prec_t prec = 53;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+
+ if (argc != 1)
+ {
+ if (argc != 4)
+ {
+ printf ("Usage: tyn n x prec\n");
+ exit (1);
+ }
+ n = atoi (argv[1]);
+ prec = atoi (argv[3]);
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (y, prec);
+ mpfr_set_str (x, argv[2], 10, MPFR_RNDN);
+ mpfr_yn (y, n, x, MPFR_RNDN);
+ printf ("Y(%ld,", n);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf (")=");
+ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
+ printf ("\n");
+ goto end;
+ }
+
+ /* special values */
+ mpfr_set_nan (x);
+ mpfr_yn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_inf (x, 1); /* +Inf */
+ mpfr_yn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS (y));
+
+ mpfr_set_inf (x, -1); /* -Inf */
+ mpfr_yn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_ui (x, 0, MPFR_RNDN); /* +0 */
+ mpfr_yn (y, 0, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(+0)=-Inf */
+ mpfr_yn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y17(+0)=-Inf */
+ mpfr_yn (y, -17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_POS (y)); /* y(-17,+0)=+Inf */
+ mpfr_yn (y, -42, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y(-42,+0)=-Inf */
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN); /* -0 */
+ mpfr_yn (y, 0, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y0(-0)=-Inf */
+ mpfr_yn (y, 17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y17(-0)=-Inf */
+ mpfr_yn (y, -17, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_POS (y)); /* y(-17,-0)=+Inf */
+ mpfr_yn (y, -42, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_inf_p (y) && MPFR_IS_NEG (y)); /* y(-42,-0)=-Inf */
+
+ mpfr_set_prec (x, 53);
+ mpfr_set_prec (y, 53);
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_yn (y, 0, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.00010110100110000000001000100110111100110101100011011111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_yn for n=0, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_yn (y, 1, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-0.110001111111110110010000001111101011001101011100101");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_yn for n=1, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_yn (y, -1, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.110001111111110110010000001111101011001101011100101");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_yn for n=-1, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_yn (y, 2, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-1.101001101001001100100010101001000101101000010010001");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_yn for n=2, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_yn (y, -2, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-1.101001101001001100100010101001000101101000010010001");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_yn for n=-2, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_yn (y, 17, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "-0.11000100111000100010101101011000110011001101100001011E60");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_yn for n=17, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ mpfr_yn (y, -17, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.11000100111000100010101101011000110011001101100001011E60");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_yn for n=-17, x=1, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+ mpfr_yn (y, 1, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.00101010110011011111001100000001101011011001111111");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_yn for n=1, x=17, rnd=MPFR_RNDN\n");
+ printf ("Expected "); mpfr_dump (x);
+ printf ("Got "); mpfr_dump (y);
+ exit (1);
+ }
+
+ end:
+ mpfr_clear (x);
+ mpfr_clear (y);
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tzeta.c b/mpfr/tests/tzeta.c
new file mode 100644
index 0000000000..f279bfb6d1
--- /dev/null
+++ b/mpfr/tests/tzeta.c
@@ -0,0 +1,406 @@
+/* tzeta -- test file for the Riemann Zeta function
+
+Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+static void
+test1 (void)
+{
+ mpfr_t x, y;
+
+ mpfr_init2 (x, 32);
+ mpfr_init2 (y, 42);
+
+ mpfr_set_str_binary (x, "1.1111111101000111011010010010100e-1");
+ mpfr_zeta (y, x, MPFR_RNDN); /* shouldn't crash */
+
+ mpfr_set_prec (x, 40);
+ mpfr_set_prec (y, 50);
+ mpfr_set_str_binary (x, "1.001101001101000010011010110100110000101e-1");
+ mpfr_zeta (y, x, MPFR_RNDU);
+ mpfr_set_prec (x, 50);
+ mpfr_set_str_binary (x, "-0.11111100011100111111101111100011110111001111111111E1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for input on 40 bits, output on 50 bits\n");
+ printf ("Expected "); mpfr_print_binary (x); puts ("");
+ printf ("Got "); mpfr_print_binary (y); puts ("");
+ mpfr_set_str_binary (x, "1.001101001101000010011010110100110000101e-1");
+ mpfr_zeta (y, x, MPFR_RNDU);
+ mpfr_print_binary (x); puts ("");
+ mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 2);
+ mpfr_set_prec (y, 55);
+ mpfr_set_str_binary (x, "0.11e3");
+ mpfr_zeta (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 55);
+ mpfr_set_str_binary (x, "0.1000001000111000010011000010011000000100100100100010010E1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_zeta (1)\n");
+ printf ("Expected "); mpfr_print_binary (x); puts ("");
+ printf ("Got "); mpfr_print_binary (y); puts ("");
+ exit (1);
+ }
+
+ mpfr_set_prec (x, 3);
+ mpfr_set_prec (y, 47);
+ mpfr_set_str_binary (x, "0.111e4");
+ mpfr_zeta (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 47);
+ mpfr_set_str_binary (x, "1.0000000000000100000000111001001010111100101011");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error in mpfr_zeta (2)\n");
+ exit (1);
+ }
+
+ /* coverage test */
+ mpfr_set_prec (x, 7);
+ mpfr_set_str_binary (x, "1.000001");
+ mpfr_set_prec (y, 2);
+ mpfr_zeta (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 64) == 0);
+
+ /* another coverage test */
+ mpfr_set_prec (x, 24);
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_set_prec (y, 2);
+ mpfr_zeta (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui_2exp (y, 3, -1) == 0);
+
+ mpfr_set_nan (x);
+ mpfr_zeta (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_set_inf (x, 1);
+ mpfr_zeta (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
+
+ mpfr_set_inf (x, -1);
+ mpfr_zeta (y, x, MPFR_RNDN);
+ MPFR_ASSERTN(mpfr_nan_p (y));
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+}
+
+static const char *const val[] = {
+ "-2000", "0.0",
+ "-2.0", "0.0",
+ "-1.0", "-0.000101010101010101010101010101010101010101010101010101010101010",
+ "-0.9", "-0.000110011110011111010001010001100010111101001010100110001110110",
+ /* "-0.8", "-0.000111110011101010001011100011010010000001010011110100010001110",
+ "-0.7", "-0.00100101011011111100110011110011111010111111000110110100010110",
+ "-0.6", "-0.00101100101100100100110111111000110010111010110010111000001100",
+ "-0.5", "-0.00110101001110000000100000011001100100010000111100010001111100",
+ "-0.4", "-0.00111111010001100011110001010010111110010001010101111101110001",
+ "-0.3", "-0.0100101100110111010101010100111011000001001010111010110101010",
+ "-0.2", "-0.0101100110000011101110101011011110101111000010000010110101111",
+ "-0.1", "-0.0110101011001111011101001111011000010001111010110011011111011",
+ "-0.0", "-0.100000000000000000000000000000000000000000000000000000000000",
+ "0.1", "-0.100110100110000010101010101110100000101100100011011001000101",
+ "0.2", "-0.10111011111000100011110111100010010001111010010010010100010110",
+ "0.3", "-0.11100111100100010011001000001011001100110010110101101110110110",
+ "0.4", "-1.0010001010000010000110111000100101001000001011101010110101011",
+ "0.5", "-1.0111010111011001110010110000011111100111001111111110111000110",
+ "0.6", "-1.1111001111100001100111101110010001001000001101100110110000100",
+ "0.7", "-10.110001110100010001110111000101010011110011000110010100101000",
+ "0.8", "-100.01110000000000101000010010000011000000111101100101100011010",
+ "0.9", "-1001.0110111000011011111100111100111011100010001111111010000100",
+ "0.99","-0.11000110110110001101011010110001011010011000110001011100101110E7",
+ "0.997", "-0.10100110011000001100111110011111100011110000111011101110001010E9",
+ "0.9995", "-0.11111001111011011000011110111111010111101001000110001111110010E11",
+ "0.99998", "-0.11000011010011110110110000111011101100001000101101011001110100E16",
+ "1.00001", "0.11000011010100000100100111100010001110100000110101110011111011E17",
+ "1.0002", "0.10011100010001001001111000101010111000011011011111110010110100E13",
+ "1.003","0.10100110111101001001010000000110101101110100001010100000110000E9",
+ "1.04", "11001.100101001000001011000111010110011010000001000010111101101",
+ "1.1", "1010.1001010110011110011010100010001100101001001111111101100001",
+ "1.2", "101.10010111011100011111001001100101101111110000110001101100010",
+ "1.3", "11.111011101001010000111001001110100100000101000101101011010100",
+ "1.4", "11.000110110000010100100101011110110001100001110100100100111111",
+ "1.5", "10.100111001100010010100001011111110111101100010011101011011100",
+ "1.6", "10.010010010010011111110000010011000110101001110011101010100110",
+ "1.7", "10.000011011110010111011110001100110010100010011100011111110010",
+ "1.8", "1.1110000111011001110011001101110101010000011011101100010111001",
+ "1.9", "1.1011111111101111011000011110001100100111100110111101101000101",
+ "2.0", "1.1010010100011010011001100010010100110000011111010011001000110",
+ "42.17", "1.0000000000000000000000000000000000000000001110001110001011001",
+ "-17.42", "-11.101110101010101000000001001000001111111101000100001100101100",
+ "-24.17", "-0.10001111010010011111000010001011111010010111101011000010010011E13"*/
+};
+
+static void
+test2 (void)
+{
+ mpfr_t x, y;
+ int i, n = numberof(val);
+
+ mpfr_inits2 (55, x, y, (mpfr_ptr) 0);
+
+ for(i = 0 ; i < n ; i+=2)
+ {
+ mpfr_set_str1 (x, val[i]);
+ mpfr_zeta(y, x, MPFR_RNDZ);
+ if (mpfr_cmp_str (y, val[i+1] , 2, MPFR_RNDZ))
+ {
+ printf("Wrong result for zeta(%s=", val[i]);
+ mpfr_print_binary (x);
+ printf (").\nGot : ");
+ mpfr_print_binary(y); putchar('\n');
+ printf("Expected: ");
+ mpfr_set_str (y, val[i+1], 2, MPFR_RNDZ);
+ mpfr_print_binary(y); putchar('\n');
+ mpfr_set_prec(y, 65);
+ mpfr_zeta(y, x, MPFR_RNDZ);
+ printf("+ Prec : ");
+ mpfr_print_binary(y); putchar('\n');
+ exit(1);
+ }
+ }
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+}
+
+#define TEST_FUNCTION mpfr_zeta
+#define TEST_RANDOM_EMIN -48
+#define TEST_RANDOM_EMAX 31
+#include "tgeneric.c"
+
+/* Usage: tzeta - generic tests
+ tzeta s prec rnd_mode - compute zeta(s) with precision 'prec'
+ and rounding mode 'mode' */
+int
+main (int argc, char *argv[])
+{
+ mpfr_t s, y, z;
+ mpfr_prec_t prec;
+ mpfr_rnd_t rnd_mode;
+ int inex;
+
+ tests_start_mpfr ();
+
+ if (argc != 1 && argc != 4)
+ {
+ printf ("Usage: tzeta\n"
+ " or tzeta s prec rnd_mode\n");
+ exit (1);
+ }
+
+ if (argc == 4)
+ {
+ prec = atoi(argv[2]);
+ mpfr_init2 (s, prec);
+ mpfr_init2 (z, prec);
+ mpfr_set_str (s, argv[1], 10, MPFR_RNDN);
+ rnd_mode = (mpfr_rnd_t) atoi(argv[3]);
+
+ mpfr_zeta (z, s, rnd_mode);
+ mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
+ printf ("\n");
+
+ mpfr_clear (s);
+ mpfr_clear (z);
+
+ return 0;
+ }
+
+ test1();
+
+ mpfr_init2 (s, MPFR_PREC_MIN);
+ mpfr_init2 (y, MPFR_PREC_MIN);
+ mpfr_init2 (z, MPFR_PREC_MIN);
+
+
+ /* the following seems to loop */
+ mpfr_set_prec (s, 6);
+ mpfr_set_prec (z, 6);
+ mpfr_set_str_binary (s, "1.10010e4");
+ mpfr_zeta (z, s, MPFR_RNDZ);
+
+
+ mpfr_set_prec (s, 53);
+ mpfr_set_prec (y, 53);
+ mpfr_set_prec (z, 53);
+
+ mpfr_set_ui (s, 1, MPFR_RNDN);
+ mpfr_clear_divby0();
+ mpfr_zeta (z, s, MPFR_RNDN);
+ if (!mpfr_inf_p (z) || MPFR_SIGN (z) < 0 || !mpfr_divby0_p())
+ {
+ printf ("Error in mpfr_zeta for s = 1 (should be +inf) with divby0 flag\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (s, "0.1100011101110111111111111010000110010111001011001011");
+ mpfr_set_str_binary (y, "-0.11111101111011001001001111111000101010000100000100100E2");
+ mpfr_zeta (z, s, MPFR_RNDN);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (1,RNDN)\n");
+ exit (1);
+ }
+ mpfr_zeta (z, s, MPFR_RNDZ);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (1,RNDZ)\n");
+ exit (1);
+ }
+ mpfr_zeta (z, s, MPFR_RNDU);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (1,RNDU)\n");
+ exit (1);
+ }
+ mpfr_zeta (z, s, MPFR_RNDD);
+ mpfr_nexttoinf (y);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (1,RNDD)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (s, "0.10001011010011100110010001100100001011000010011001011");
+ mpfr_set_str_binary (y, "-0.11010011010010101101110111011010011101111101111010110E1");
+ mpfr_zeta (z, s, MPFR_RNDN);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (2,RNDN)\n");
+ exit (1);
+ }
+ mpfr_zeta (z, s, MPFR_RNDZ);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (2,RNDZ)\n");
+ exit (1);
+ }
+ mpfr_zeta (z, s, MPFR_RNDU);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (2,RNDU)\n");
+ exit (1);
+ }
+ mpfr_zeta (z, s, MPFR_RNDD);
+ mpfr_nexttoinf (y);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (2,RNDD)\n");
+ exit (1);
+ }
+
+ mpfr_set_str_binary (s, "0.1100111110100001111110111000110101111001011101000101");
+ mpfr_set_str_binary (y, "-0.10010111010110000111011111001101100001111011000001010E3");
+ mpfr_zeta (z, s, MPFR_RNDN);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (3,RNDN)\n");
+ exit (1);
+ }
+ mpfr_zeta (z, s, MPFR_RNDD);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (3,RNDD)\n");
+ exit (1);
+ }
+ mpfr_nexttozero (y);
+ mpfr_zeta (z, s, MPFR_RNDZ);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (3,RNDZ)\n");
+ exit (1);
+ }
+ mpfr_zeta (z, s, MPFR_RNDU);
+ if (mpfr_cmp (z, y) != 0)
+ {
+ printf ("Error in mpfr_zeta (3,RNDU)\n");
+ exit (1);
+ }
+
+ mpfr_set_str (s, "-400000001", 10, MPFR_RNDZ);
+ mpfr_zeta (z, s, MPFR_RNDN);
+ if (!(mpfr_inf_p (z) && MPFR_SIGN(z) < 0))
+ {
+ printf ("Error in mpfr_zeta (-400000001)\n");
+ exit (1);
+ }
+ mpfr_set_str (s, "-400000003", 10, MPFR_RNDZ);
+ mpfr_zeta (z, s, MPFR_RNDN);
+ if (!(mpfr_inf_p (z) && MPFR_SIGN(z) > 0))
+ {
+ printf ("Error in mpfr_zeta (-400000003)\n");
+ exit (1);
+ }
+
+ mpfr_set_prec (s, 34);
+ mpfr_set_prec (z, 34);
+ mpfr_set_str_binary (s, "-1.111111100001011110000010001010000e-35");
+ mpfr_zeta (z, s, MPFR_RNDD);
+ mpfr_set_str_binary (s, "-1.111111111111111111111111111111111e-2");
+ if (mpfr_cmp (s, z))
+ {
+ printf ("Error in mpfr_zeta, prec=34, MPFR_RNDD\n");
+ mpfr_dump (z);
+ exit (1);
+ }
+
+ /* bug found by nightly tests on June 7, 2007 */
+ mpfr_set_prec (s, 23);
+ mpfr_set_prec (z, 25);
+ mpfr_set_str_binary (s, "-1.0110110110001000000000e-27");
+ mpfr_zeta (z, s, MPFR_RNDN);
+ mpfr_set_prec (s, 25);
+ mpfr_set_str_binary (s, "-1.111111111111111111111111e-2");
+ if (mpfr_cmp (s, z))
+ {
+ printf ("Error in mpfr_zeta, prec=25, MPFR_RNDN\n");
+ printf ("expected "); mpfr_dump (s);
+ printf ("got "); mpfr_dump (z);
+ exit (1);
+ }
+
+ /* bug reported by Kevin Rauch on 26 Oct 2007 */
+ mpfr_set_prec (s, 128);
+ mpfr_set_prec (z, 128);
+ mpfr_set_str_binary (s, "-0.1000000000000000000000000000000000000000000000000000000000000001E64");
+ inex = mpfr_zeta (z, s, MPFR_RNDN);
+ MPFR_ASSERTN (mpfr_inf_p (z) && MPFR_SIGN (z) < 0 && inex < 0);
+ inex = mpfr_zeta (z, s, MPFR_RNDU);
+ mpfr_set_inf (s, -1);
+ mpfr_nextabove (s);
+ MPFR_ASSERTN (mpfr_equal_p (z, s) && inex > 0);
+
+ mpfr_clear (s);
+ mpfr_clear (y);
+ mpfr_clear (z);
+
+ test_generic (2, 70, 5);
+ test2 ();
+
+ tests_end_mpfr ();
+ return 0;
+}
diff --git a/mpfr/tests/tzeta_ui.c b/mpfr/tests/tzeta_ui.c
new file mode 100644
index 0000000000..b9b569b140
--- /dev/null
+++ b/mpfr/tests/tzeta_ui.c
@@ -0,0 +1,122 @@
+/* Test file for mpfr_zeta_ui.
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpfr-test.h"
+
+#define TEST_FUNCTION mpfr_zeta_ui
+
+int
+main (int argc, char *argv[])
+{
+#if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
+ unsigned int prec, yprec;
+ int rnd;
+ mpfr_t x, y, z, t;
+ unsigned long n;
+ int inex;
+
+ tests_start_mpfr ();
+
+ mpfr_init (x);
+ mpfr_init (y);
+ mpfr_init (z);
+ mpfr_init (t);
+
+ if (argc >= 3) /* tzeta_ui n prec [rnd] */
+ {
+ mpfr_set_prec (x, atoi (argv[2]));
+ mpfr_zeta_ui (x, atoi (argv[1]),
+ argc > 3 ? (mpfr_rnd_t) atoi (argv[3]) : MPFR_RNDN);
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ goto clear_and_exit;
+ }
+
+ mpfr_set_prec (x, 33);
+ mpfr_set_prec (y, 33);
+ mpfr_zeta_ui (x, 3, MPFR_RNDZ);
+ mpfr_set_str_binary (y, "0.100110011101110100000000001001111E1");
+ if (mpfr_cmp (x, y))
+ {
+ printf ("Error for zeta(3), prec=33, MPFR_RNDZ\n");
+ printf ("expected "); mpfr_dump (y);
+ printf ("got "); mpfr_dump (x);
+ exit (1);
+ }
+
+ mpfr_clear_divby0 ();
+ inex = mpfr_zeta_ui (x, 0, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0 && mpfr_cmp_si_2exp (x, -1, -1) == 0
+ && !mpfr_divby0_p ());
+
+ mpfr_clear_divby0 ();
+ inex = mpfr_zeta_ui (x, 1, MPFR_RNDN);
+ MPFR_ASSERTN (inex == 0 && MPFR_IS_INF (x) && MPFR_IS_POS (x)
+ && mpfr_divby0_p ());
+
+ for (prec = MPFR_PREC_MIN; prec <= 100; prec++)
+ {
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (z, prec);
+ mpfr_set_prec (t, prec);
+ yprec = prec + 10;
+ mpfr_set_prec (y, yprec);
+
+ for (n = 0; n < 50; n++)
+ for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
+ {
+ mpfr_zeta_ui (y, n, MPFR_RNDN);
+ if (mpfr_can_round (y, yprec, MPFR_RNDN, MPFR_RNDZ, prec
+ + (rnd == MPFR_RNDN)))
+ {
+ mpfr_set (t, y, (mpfr_rnd_t) rnd);
+ mpfr_zeta_ui (z, n, (mpfr_rnd_t) rnd);
+ if (mpfr_cmp (t, z))
+ {
+ printf ("results differ for n=%lu", n);
+ printf (" prec=%u rnd_mode=%s\n", prec,
+ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+ printf (" got ");
+ mpfr_dump (z);
+ printf (" expected ");
+ mpfr_dump (t);
+ printf (" approx ");
+ mpfr_dump (y);
+ exit (1);
+ }
+ }
+ }
+ }
+
+ clear_and_exit:
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (z);
+ mpfr_clear (t);
+
+ tests_end_mpfr ();
+#endif
+ return 0;
+}
diff --git a/mpfr/tools/ck-copyright-notice b/mpfr/tools/ck-copyright-notice
new file mode 100755
index 0000000000..aec58317fd
--- /dev/null
+++ b/mpfr/tools/ck-copyright-notice
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+# Copyright 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This script 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.
+
+# ck-copyright-notice can be run from the tools directory
+dir=`pwd`
+[ -d src ] || [ "`basename "$dir"`" != tools ] || cd ..
+
+# Note: if paragraphs are reformatted, this may need to be updated.
+
+lgpl="`sed -n '/version [0-9.]* or any later version/ {
+ s/.*version //
+ s/ or.*//
+ p
+ q
+ }' doc/mpfr.texi`"
+
+# Do not use "find ... | while read file do ... done" because the "do"
+# part needs to be run in the current shell, and some shells behave in
+# a different way.
+srctests=`find src tests -name '*.[ch]'`
+
+err=0
+for file in $srctests
+do
+ y=""
+ case $file in
+ tests/RRTest.c)
+ # This file doesn't have a copyright notice, but isn't distributed.
+ continue ;;
+ src/mpfr-longlong.h)
+ # This file (which comes from GMP) has a specific copyright notice.
+ continue ;;
+ src/get_patches.c)
+ file="tools/get_patches.sh" ;;
+ */mparam.h)
+ y="2005," ;;
+ esac
+ grep -q "Copyright $y.* Free Software Foundation" "$file" && \
+ grep -q "GNU MPFR Library" "$file" && \
+ grep -q "either version $lgpl of the License" "$file" && continue
+ echo "Possibly missing or incorrect copyright notice in $file"
+ err=1
+done
+
+exit $err
diff --git a/mpfr/tools/ck-version-info b/mpfr/tools/ck-version-info
new file mode 100755
index 0000000000..7d39d8ac78
--- /dev/null
+++ b/mpfr/tools/ck-version-info
@@ -0,0 +1,67 @@
+#!/usr/bin/env perl
+
+# Note: this script must not be used to build MPFR due to the
+# dependency on perl, but this is OK for "make dist".
+
+# Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This script 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.
+
+use strict;
+use Cwd;
+
+if (! -d 'src')
+ {
+ getcwd() =~ m,/tools$,
+ or die "Execute $0 from the MPFR source directory\n";
+ chdir '..' or die "$!\n$0: can't change cwd\n";
+ }
+
+open VERSION, '<', 'VERSION'
+ or die "$!\n$0: can't open VERSION file\n";
+my $version = do { local $/; <VERSION> };
+close VERSION or die "$!\n$0: can't close VERSION file\n";
+
+my ($mv,$pl,$suf) = $version =~ /^(\d+\.\d+)\.(\d+)(-\S+)?/
+ or die "$0: bad VERSION format\n";
+
+open MF, '<', 'src/Makefile.am'
+ or die "$!\n$0: can't open Makefile.am file\n";
+my $cur = 0;
+my $age = -1;
+my $vinfo; # expected -version-info value
+while (<MF>)
+ {
+ last if $cur && ! /^\s*(#.*)$/;
+ /^#\s+(\d+\.\d+)\.x\s+(\d+):x:(\d+)/ or next;
+ $2 == ++$cur or die "$0: bad CURRENT ($2)";
+ $3 == 0 || $3 == $age + 1 or die "$0: bad AGE ($3)";
+ $age = $3;
+ $mv eq $1 and $vinfo = "$cur:$pl:$age";
+ }
+/^libmpfr_la_LDFLAGS\s+=.*\s-version-info\s+(\d+:\d+:\d+)\s/
+ or die "$0: missing correct libmpfr_la_LDFLAGS line";
+close MF or die "$!\n$0: can't close Makefile.am file\n";
+$suf eq '-dev' || $vinfo eq $1
+ or die "$0: bad -version-info value ($1 instead of $vinfo)\n";
+
+open CONFIGURE, '<', 'configure.ac'
+ or die "$!\n$0: can't open configure.ac file\n";
+my $dllversion = $cur - $age;
+my $dllvinconf;
+while (<CONFIGURE>)
+ {
+ /^\s*LIBMPFR_LDFLAGS\s*=.*-Wl,--output-def,\.libs\/libmpfr-(\d+)\.dll\.def/
+ and $dllvinconf = $1, last;
+ }
+close CONFIGURE or die "$!\n$0: can't close configure.ac file\n";
+defined $dllvinconf or die "$0: missing correct LIBMPFR_LDFLAGS line\n";
+$suf eq '-dev' || $dllversion eq $dllvinconf
+ or die "$0: bad libmpfr.dll-version value (libmpfr-$dllvinconf.dll.def".
+ " instead of libmpfr-$dllversion.dll.def)\n";
diff --git a/mpfr/tools/get_patches.sh b/mpfr/tools/get_patches.sh
new file mode 100755
index 0000000000..872b0067e9
--- /dev/null
+++ b/mpfr/tools/get_patches.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+cat <<EOF
+/* mpfr_get_patches -- Patches that have been applied
+
+Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "mpfr-impl.h"
+
+const char *
+mpfr_get_patches (void)
+{
+EOF
+
+echo ' return "'`cat PATCHES`'";'
+echo '}'
diff --git a/mpfr/tune/Makefile.am b/mpfr/tune/Makefile.am
new file mode 100644
index 0000000000..f33045698e
--- /dev/null
+++ b/mpfr/tune/Makefile.am
@@ -0,0 +1,38 @@
+# Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+
+
+EXTRA_PROGRAMS = tuneup speed bidimensional_sample
+
+tuneup_SOURCES = tuneup.c
+tuneup_LDADD = -lspeed $(top_builddir)/src/libmpfr.la $(TUNE_LIBS)
+tuneup_LDFLAGS = -static
+
+speed_SOURCES = speed.c
+speed_LDADD = -lspeed $(top_builddir)/src/libmpfr.la $(TUNE_LIBS)
+speed_LDFLAGS = -static
+
+bidimensional_sample_SOURCES = bidimensional_sample.c
+bidimensional_sample_LDADD = -lspeed $(top_builddir)/src/libmpfr.la $(TUNE_LIBS)
+bidimensional_sample_LDFLAGS = -static
+
+INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src
+
+tune:
+ $(MAKE) $(AM_MAKEFLAGS) tuneup$(EXEEXT)
+ ./tuneup$(EXEEXT) -v
+ mv mparam.h $(top_builddir)/src/
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) clean
+ cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libmpfr.la
+
+$(top_builddir)/src/libmpfr.la:
+ cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libmpfr.la
+
+CLEANFILES = $(EXTRA_PROGRAMS) mparam.h
diff --git a/mpfr/tune/Makefile.in b/mpfr/tune/Makefile.in
new file mode 100644
index 0000000000..df87228cbd
--- /dev/null
+++ b/mpfr/tune/Makefile.in
@@ -0,0 +1,553 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+# This Makefile.am 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.
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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@
+EXTRA_PROGRAMS = tuneup$(EXEEXT) speed$(EXEEXT) \
+ bidimensional_sample$(EXEEXT)
+subdir = tune
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am_bidimensional_sample_OBJECTS = bidimensional_sample.$(OBJEXT)
+bidimensional_sample_OBJECTS = $(am_bidimensional_sample_OBJECTS)
+am__DEPENDENCIES_1 =
+bidimensional_sample_DEPENDENCIES = $(top_builddir)/src/libmpfr.la \
+ $(am__DEPENDENCIES_1)
+bidimensional_sample_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(bidimensional_sample_LDFLAGS) $(LDFLAGS) -o $@
+am_speed_OBJECTS = speed.$(OBJEXT)
+speed_OBJECTS = $(am_speed_OBJECTS)
+speed_DEPENDENCIES = $(top_builddir)/src/libmpfr.la \
+ $(am__DEPENDENCIES_1)
+speed_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(speed_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_tuneup_OBJECTS = tuneup.$(OBJEXT)
+tuneup_OBJECTS = $(am_tuneup_OBJECTS)
+tuneup_DEPENDENCIES = $(top_builddir)/src/libmpfr.la \
+ $(am__DEPENDENCIES_1)
+tuneup_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(tuneup_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(bidimensional_sample_SOURCES) $(speed_SOURCES) \
+ $(tuneup_SOURCES)
+DIST_SOURCES = $(bidimensional_sample_SOURCES) $(speed_SOURCES) \
+ $(tuneup_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATAFILES = @DATAFILES@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBMPFR_LDFLAGS = @LIBMPFR_LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MPFR_LDFLAGS = @MPFR_LDFLAGS@
+MPFR_LIBM = @MPFR_LIBM@
+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@
+STRIP = @STRIP@
+TUNE_LIBS = @TUNE_LIBS@
+VERSION = @VERSION@
+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_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+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@
+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@
+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@
+tuneup_SOURCES = tuneup.c
+tuneup_LDADD = -lspeed $(top_builddir)/src/libmpfr.la $(TUNE_LIBS)
+tuneup_LDFLAGS = -static
+speed_SOURCES = speed.c
+speed_LDADD = -lspeed $(top_builddir)/src/libmpfr.la $(TUNE_LIBS)
+speed_LDFLAGS = -static
+bidimensional_sample_SOURCES = bidimensional_sample.c
+bidimensional_sample_LDADD = -lspeed $(top_builddir)/src/libmpfr.la $(TUNE_LIBS)
+bidimensional_sample_LDFLAGS = -static
+INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src
+CLEANFILES = $(EXTRA_PROGRAMS) mparam.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 tune/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tune/Makefile
+.PRECIOUS: 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):
+bidimensional_sample$(EXEEXT): $(bidimensional_sample_OBJECTS) $(bidimensional_sample_DEPENDENCIES) $(EXTRA_bidimensional_sample_DEPENDENCIES)
+ @rm -f bidimensional_sample$(EXEEXT)
+ $(bidimensional_sample_LINK) $(bidimensional_sample_OBJECTS) $(bidimensional_sample_LDADD) $(LIBS)
+speed$(EXEEXT): $(speed_OBJECTS) $(speed_DEPENDENCIES) $(EXTRA_speed_DEPENDENCIES)
+ @rm -f speed$(EXEEXT)
+ $(speed_LINK) $(speed_OBJECTS) $(speed_LDADD) $(LIBS)
+tuneup$(EXEEXT): $(tuneup_OBJECTS) $(tuneup_DEPENDENCIES) $(EXTRA_tuneup_DEPENDENCIES)
+ @rm -f tuneup$(EXEEXT)
+ $(tuneup_LINK) $(tuneup_OBJECTS) $(tuneup_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bidimensional_sample.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/speed.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tuneup.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+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:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -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 -rf ./$(DEPDIR)
+ -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: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool ctags 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 \
+ tags uninstall uninstall-am
+
+
+tune:
+ $(MAKE) $(AM_MAKEFLAGS) tuneup$(EXEEXT)
+ ./tuneup$(EXEEXT) -v
+ mv mparam.h $(top_builddir)/src/
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) clean
+ cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libmpfr.la
+
+$(top_builddir)/src/libmpfr.la:
+ cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) libmpfr.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/mpfr/tune/bidimensional_sample.c b/mpfr/tune/bidimensional_sample.c
new file mode 100644
index 0000000000..64a21d8899
--- /dev/null
+++ b/mpfr/tune/bidimensional_sample.c
@@ -0,0 +1,468 @@
+/* [Description]
+
+Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include <time.h>
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#undef _PROTO
+#define _PROTO __GMP_PROTO
+#include "speed.h"
+
+/* Let f be a function for which we have several implementations f1, f2... */
+/* We wish to have a quick overview of which implementation is the best */
+/* in function of the point x where f(x) is computed and of the prectision */
+/* prec requested by the user. */
+/* This is performed by drawing a 2D graphic with color indicating which */
+/* method is the best. */
+/* For building this graphic, the following structur is used (see the core */
+/* of generate_2D_sample for an explanation of each field. */
+struct speed_params2D
+{
+ /* x-window: [min_x, max_x] or [2^min_x, 2^max_x] */
+ /* or [-2^(max_x), -2^(min_x)] U [2^min_x, 2^max_x] */
+ /* depending on the value of logarithmic_scale_x */
+ double min_x;
+ double max_x;
+
+ /* prec-window: [min_prec, max_prec] */
+ mpfr_prec_t min_prec;
+ mpfr_prec_t max_prec;
+
+ /* number of sample points for the x-axis and the prec-axis */
+ int nb_points_x;
+ int nb_points_prec;
+
+ /* should the sample points be logarithmically scaled or not */
+ int logarithmic_scale_x;
+ int logarithmic_scale_prec;
+
+ /* list of functions g1, g2... measuring the execution time of f1, f2... */
+ /* when given a point x and a precision prec stored in s. */
+ /* We use s->xp to store the significant of x, s->r to store its exponent */
+ /* s->align_xp to store its sign, and s->size to store prec. */
+ double (**speed_funcs) (struct speed_params *s);
+};
+
+/* Given an array t of nb_functions double indicating the timings of several */
+/* implementations, return i, such that t[i] is the best timing. */
+int
+find_best (double *t, int nb_functions)
+{
+ int i, ibest;
+ double best;
+
+ if (nb_functions<=0)
+ {
+ fprintf (stderr, "There is no function\n");
+ abort ();
+ }
+
+ ibest = 0;
+ best = t[0];
+ for (i=1; i<nb_functions; i++)
+ {
+ if (t[i]<best)
+ {
+ best = t[i];
+ ibest = i;
+ }
+ }
+
+ return ibest;
+}
+
+void generate_2D_sample (FILE *output, struct speed_params2D param)
+{
+ mpfr_t temp;
+ double incr_prec;
+ mpfr_t incr_x;
+ mpfr_t x, x2;
+ double prec;
+ struct speed_params s;
+ int i;
+ int test;
+ int nb_functions;
+ double *t; /* store the timing of each implementation */
+
+ /* We first determine how many implementations we have */
+ nb_functions = 0;
+ while (param.speed_funcs[nb_functions] != NULL)
+ nb_functions++;
+
+ t = malloc (nb_functions * sizeof (double));
+ if (t == NULL)
+ {
+ fprintf (stderr, "Can't allocate memory.\n");
+ abort ();
+ }
+
+
+ mpfr_init2 (temp, MPFR_SMALL_PRECISION);
+
+ /* The precision is sampled from min_prec to max_prec with */
+ /* approximately nb_points_prec points. If logarithmic_scale_prec */
+ /* is true, the precision is multiplied by incr_prec at each */
+ /* step. Otherwise, incr_prec is added at each step. */
+ if (param.logarithmic_scale_prec)
+ {
+ mpfr_set_ui (temp, (unsigned long int)param.max_prec, MPFR_RNDU);
+ mpfr_div_ui (temp, temp, (unsigned long int)param.min_prec, MPFR_RNDU);
+ mpfr_root (temp, temp,
+ (unsigned long int)param.nb_points_prec, MPFR_RNDU);
+ incr_prec = mpfr_get_d (temp, MPFR_RNDU);
+ }
+ else
+ {
+ incr_prec = (double)param.max_prec - (double)param.min_prec;
+ incr_prec = incr_prec/((double)param.nb_points_prec);
+ }
+
+ /* The points x are sampled according to the following rule: */
+ /* If logarithmic_scale_x = 0: */
+ /* nb_points_x points are equally distributed between min_x and max_x */
+ /* If logarithmic_scale_x = 1: */
+ /* nb_points_x points are sampled from 2^(min_x) to 2^(max_x). At */
+ /* each step, the current point is multiplied by incr_x. */
+ /* If logarithmic_scale_x = -1: */
+ /* nb_points_x/2 points are sampled from -2^(max_x) to -2^(min_x) */
+ /* (at each step, the current point is divided by incr_x); and */
+ /* nb_points_x/2 points are sampled from 2^(min_x) to 2^(max_x) */
+ /* (at each step, the current point is multiplied by incr_x). */
+ mpfr_init2 (incr_x, param.max_prec);
+ if (param.logarithmic_scale_x == 0)
+ {
+ mpfr_set_d (incr_x,
+ (param.max_x - param.min_x)/(double)param.nb_points_x,
+ MPFR_RNDU);
+ }
+ else if (param.logarithmic_scale_x == -1)
+ {
+ mpfr_set_d (incr_x,
+ 2.*(param.max_x - param.min_x)/(double)param.nb_points_x,
+ MPFR_RNDU);
+ mpfr_exp2 (incr_x, incr_x, MPFR_RNDU);
+ }
+ else
+ { /* other values of param.logarithmic_scale_x are considered as 1 */
+ mpfr_set_d (incr_x,
+ (param.max_x - param.min_x)/(double)param.nb_points_x,
+ MPFR_RNDU);
+ mpfr_exp2 (incr_x, incr_x, MPFR_RNDU);
+ }
+
+ /* Main loop */
+ mpfr_init2 (x, param.max_prec);
+ mpfr_init2 (x2, param.max_prec);
+ prec = (double)param.min_prec;
+ while (prec <= param.max_prec)
+ {
+ printf ("prec = %d\n", (int)prec);
+ if (param.logarithmic_scale_x == 0)
+ mpfr_set_d (temp, param.min_x, MPFR_RNDU);
+ else if (param.logarithmic_scale_x == -1)
+ {
+ mpfr_set_d (temp, param.max_x, MPFR_RNDD);
+ mpfr_exp2 (temp, temp, MPFR_RNDD);
+ mpfr_neg (temp, temp, MPFR_RNDU);
+ }
+ else
+ {
+ mpfr_set_d (temp, param.min_x, MPFR_RNDD);
+ mpfr_exp2 (temp, temp, MPFR_RNDD);
+ }
+
+ /* We perturb x a little bit, in order to avoid trailing zeros that */
+ /* might change the behavior of algorithms. */
+ mpfr_const_pi (x, MPFR_RNDN);
+ mpfr_div_2ui (x, x, 7, MPFR_RNDN);
+ mpfr_add_ui (x, x, 1, MPFR_RNDN);
+ mpfr_mul (x, x, temp, MPFR_RNDN);
+
+ test = 1;
+ while (test)
+ {
+ mpfr_fprintf (output, "%e\t", mpfr_get_d (x, MPFR_RNDN));
+ mpfr_fprintf (output, "%Pu\t", (mpfr_prec_t)prec);
+
+ s.r = (mp_limb_t)mpfr_get_exp (x);
+ s.size = (mpfr_prec_t)prec;
+ s.align_xp = (mpfr_sgn (x) > 0)?1:2;
+ mpfr_set_prec (x2, (mpfr_prec_t)prec);
+ mpfr_set (x2, x, MPFR_RNDU);
+ s.xp = x2->_mpfr_d;
+
+ for (i=0; i<nb_functions; i++)
+ {
+ t[i] = speed_measure (param.speed_funcs[i], &s);
+ mpfr_fprintf (output, "%e\t", t[i]);
+ }
+ fprintf (output, "%d\n", 1 + find_best (t, nb_functions));
+
+ if (param.logarithmic_scale_x == 0)
+ {
+ mpfr_add (x, x, incr_x, MPFR_RNDU);
+ if (mpfr_cmp_d (x, param.max_x) > 0)
+ test=0;
+ }
+ else
+ {
+ if (mpfr_sgn (x) < 0 )
+ { /* if x<0, it means that logarithmic_scale_x=-1 */
+ mpfr_div (x, x, incr_x, MPFR_RNDU);
+ mpfr_abs (temp, x, MPFR_RNDD);
+ mpfr_log2 (temp, temp, MPFR_RNDD);
+ if (mpfr_cmp_d (temp, param.min_x) < 0)
+ mpfr_neg (x, x, MPFR_RNDN);
+ }
+ else
+ {
+ mpfr_mul (x, x, incr_x, MPFR_RNDU);
+ mpfr_set (temp, x, MPFR_RNDD);
+ mpfr_log2 (temp, temp, MPFR_RNDD);
+ if (mpfr_cmp_d (temp, param.max_x) > 0)
+ test=0;
+ }
+ }
+ }
+
+ prec = ( (param.logarithmic_scale_prec) ? (prec * incr_prec)
+ : (prec + incr_prec) );
+ fprintf (output, "\n");
+ }
+
+ free (t);
+ mpfr_clear (incr_x);
+ mpfr_clear (x);
+ mpfr_clear (x2);
+ mpfr_clear (temp);
+
+ return;
+}
+
+#define SPEED_MPFR_FUNC_2D(mean_func) \
+ do \
+ { \
+ double t; \
+ unsigned i; \
+ mpfr_t w, x; \
+ mp_size_t size; \
+ \
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN); \
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX); \
+ \
+ size = (s->size-1)/GMP_NUMB_BITS+1; \
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->xp, x, s->size); \
+ MPFR_SET_EXP (x, (mpfr_exp_t) s->r); \
+ if (s->align_xp == 2) MPFR_SET_NEG (x); \
+ \
+ mpfr_init2 (w, s->size); \
+ speed_starttime (); \
+ i = s->reps; \
+ \
+ do \
+ mean_func (w, x, MPFR_RNDN); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ mpfr_clear (w); \
+ return t; \
+ } \
+ while (0)
+
+mpfr_prec_t mpfr_exp_2_threshold;
+mpfr_prec_t old_threshold = MPFR_EXP_2_THRESHOLD;
+#undef MPFR_EXP_2_THRESHOLD
+#define MPFR_EXP_2_THRESHOLD mpfr_exp_2_threshold
+#include "exp_2.c"
+
+double
+timing_exp1 (struct speed_params *s)
+{
+ mpfr_exp_2_threshold = s->size+1;
+ SPEED_MPFR_FUNC_2D (mpfr_exp_2);
+}
+
+double
+timing_exp2 (struct speed_params *s)
+{
+ mpfr_exp_2_threshold = s->size-1;
+ SPEED_MPFR_FUNC_2D (mpfr_exp_2);
+}
+
+double
+timing_exp3 (struct speed_params *s)
+{
+ SPEED_MPFR_FUNC_2D (mpfr_exp_3);
+}
+
+
+#include "ai.c"
+double
+timing_ai1 (struct speed_params *s)
+{
+ SPEED_MPFR_FUNC_2D (mpfr_ai1);
+}
+
+double
+timing_ai2 (struct speed_params *s)
+{
+ SPEED_MPFR_FUNC_2D (mpfr_ai2);
+}
+
+/* These functions are for testing purpose only */
+/* They are used to draw which method is actually used */
+double
+virtual_timing_ai1 (struct speed_params *s)
+{
+ double t;
+ unsigned i;
+ mpfr_t w, x;
+ mp_size_t size;
+ mpfr_t temp1, temp2;
+
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN);
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX);
+
+ size = (s->size-1)/GMP_NUMB_BITS+1;
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT;
+ MPFR_TMP_INIT1 (s->xp, x, s->size);
+ MPFR_SET_EXP (x, (mpfr_exp_t) s->r);
+ if (s->align_xp == 2) MPFR_SET_NEG (x);
+
+ mpfr_init2 (w, s->size);
+ speed_starttime ();
+ i = s->reps;
+
+ mpfr_init2 (temp1, MPFR_SMALL_PRECISION);
+ mpfr_init2 (temp2, MPFR_SMALL_PRECISION);
+
+ mpfr_set (temp1, x, MPFR_SMALL_PRECISION);
+ mpfr_set_si (temp2, MPFR_AI_THRESHOLD2, MPFR_RNDN);
+ mpfr_mul_ui (temp2, temp2, (unsigned int)MPFR_PREC (w), MPFR_RNDN);
+
+ if (MPFR_IS_NEG (x))
+ mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD1, MPFR_RNDN);
+ else
+ mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD3, MPFR_RNDN);
+
+ mpfr_add (temp1, temp1, temp2, MPFR_RNDN);
+
+ if (mpfr_cmp_si (temp1, MPFR_AI_SCALE) > 0)
+ t = 1000.;
+ else
+ t = 1.;
+
+ mpfr_clear (temp1);
+ mpfr_clear (temp2);
+
+ return t;
+}
+
+double
+virtual_timing_ai2 (struct speed_params *s)
+{
+ double t;
+ unsigned i;
+ mpfr_t w, x;
+ mp_size_t size;
+ mpfr_t temp1, temp2;
+
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN);
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX);
+
+ size = (s->size-1)/GMP_NUMB_BITS+1;
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT;
+ MPFR_TMP_INIT1 (s->xp, x, s->size);
+ MPFR_SET_EXP (x, (mpfr_exp_t) s->r);
+ if (s->align_xp == 2) MPFR_SET_NEG (x);
+
+ mpfr_init2 (w, s->size);
+ speed_starttime ();
+ i = s->reps;
+
+ mpfr_init2 (temp1, MPFR_SMALL_PRECISION);
+ mpfr_init2 (temp2, MPFR_SMALL_PRECISION);
+
+ mpfr_set (temp1, x, MPFR_SMALL_PRECISION);
+ mpfr_set_si (temp2, MPFR_AI_THRESHOLD2, MPFR_RNDN);
+ mpfr_mul_ui (temp2, temp2, (unsigned int)MPFR_PREC (w), MPFR_RNDN);
+
+ if (MPFR_IS_NEG (x))
+ mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD1, MPFR_RNDN);
+ else
+ mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD3, MPFR_RNDN);
+
+ mpfr_add (temp1, temp1, temp2, MPFR_RNDN);
+
+ if (mpfr_cmp_si (temp1, MPFR_AI_SCALE) > 0)
+ t = 1.;
+ else
+ t = 1000.;
+
+ mpfr_clear (temp1);
+ mpfr_clear (temp2);
+
+ return t;
+}
+
+int
+main (void)
+{
+ FILE *output;
+ struct speed_params2D param;
+ double (*speed_funcs[3]) (struct speed_params *s);
+
+ /* char filename[256] = "virtual_timing_ai.dat"; */
+ /* speed_funcs[0] = virtual_timing_ai1; */
+ /* speed_funcs[1] = virtual_timing_ai2; */
+
+ char filename[256] = "airy.dat";
+ speed_funcs[0] = timing_ai1;
+ speed_funcs[1] = timing_ai2;
+
+ speed_funcs[2] = NULL;
+ output = fopen (filename, "w");
+ if (output == NULL)
+ {
+ fprintf (stderr, "Can't open file '%s' for writing.\n", filename);
+ abort ();
+ }
+ param.min_x = -80;
+ param.max_x = 60;
+ param.min_prec = 50;
+ param.max_prec = 1500;
+ param.nb_points_x = 200;
+ param.nb_points_prec = 200;
+ param.logarithmic_scale_x = 0;
+ param.logarithmic_scale_prec = 0;
+ param.speed_funcs = speed_funcs;
+
+ generate_2D_sample (output, param);
+
+ fclose (output);
+ mpfr_free_cache ();
+ return 0;
+}
diff --git a/mpfr/tune/speed.c b/mpfr/tune/speed.c
new file mode 100644
index 0000000000..10531986a9
--- /dev/null
+++ b/mpfr/tune/speed.c
@@ -0,0 +1,283 @@
+/* Tune various threshold of MPFR
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include <time.h>
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+/* extracted from mulders.c */
+#ifdef MPFR_MULHIGH_TAB_SIZE
+static short mulhigh_ktab[MPFR_MULHIGH_TAB_SIZE];
+#else
+static short mulhigh_ktab[] = {MPFR_MULHIGH_TAB};
+#define MPFR_MULHIGH_TAB_SIZE \
+ ((mp_size_t) (sizeof(mulhigh_ktab) / sizeof(mulhigh_ktab[0])))
+#endif
+
+#undef _PROTO
+#define _PROTO __GMP_PROTO
+#include "speed.h"
+
+int verbose;
+
+/* s->size: precision of both input and output
+ s->xp : Mantissa of first input
+ s->yp : mantissa of second input */
+
+#define SPEED_MPFR_FUNC(mean_fun) do { \
+ unsigned i; \
+ mpfr_limb_ptr wp; \
+ double t; \
+ mpfr_t w, x; \
+ mp_size_t size; \
+ MPFR_TMP_DECL (marker); \
+ \
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN); \
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX); \
+ MPFR_TMP_MARK (marker); \
+ \
+ size = (s->size-1)/GMP_NUMB_BITS+1; \
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->xp, x, s->size); \
+ MPFR_SET_EXP (x, 0); \
+ \
+ MPFR_TMP_INIT (wp, w, s->size, size); \
+ \
+ speed_operand_src (s, s->xp, size); \
+ speed_operand_dst (s, wp, size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ mean_fun (w, x, MPFR_RNDN); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ MPFR_TMP_FREE (marker); \
+ return t; \
+} while (0)
+
+#define SPEED_MPFR_OP(mean_fun) do { \
+ unsigned i; \
+ mpfr_limb_ptr wp; \
+ double t; \
+ mpfr_t w, x, y; \
+ mp_size_t size; \
+ MPFR_TMP_DECL (marker); \
+ \
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN); \
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX); \
+ MPFR_TMP_MARK (marker); \
+ \
+ size = (s->size-1)/GMP_NUMB_BITS+1; \
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->xp, x, s->size); \
+ MPFR_SET_EXP (x, 0); \
+ s->yp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->yp, y, s->size); \
+ MPFR_SET_EXP (y, 0); \
+ \
+ MPFR_TMP_INIT (wp, w, s->size, size); \
+ \
+ speed_operand_src (s, s->xp, size); \
+ speed_operand_src (s, s->yp, size); \
+ speed_operand_dst (s, wp, size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ mean_fun (w, x, y, MPFR_RNDN); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ MPFR_TMP_FREE (marker); \
+ return t; \
+} while (0)
+
+
+/* First we include all the functions we want to tune inside this program.
+ We can't use GNU MPFR library since the THRESHOLD can't vary */
+
+/* Setup mpfr_mul */
+mpfr_prec_t mpfr_mul_threshold = MPFR_MUL_THRESHOLD;
+static double speed_mpfr_mul (struct speed_params *s) {
+ SPEED_MPFR_OP (mpfr_mul);
+}
+
+
+
+/************************************************
+ * Common functions (inspired by GMP function) *
+ ************************************************/
+#define THRESHOLD_WINDOW 16
+#define THRESHOLD_FINAL_WINDOW 128
+static double domeasure (mpfr_prec_t *threshold,
+ double (*func) (struct speed_params *),
+ mpfr_prec_t p)
+{
+ struct speed_params s;
+ mp_size_t size;
+ double t;
+
+ s.align_xp = s.align_yp = s.align_wp = 64;
+ s.size = p;
+ size = (p - 1)/GMP_NUMB_BITS+1;
+ s.xp = malloc (2*size*sizeof (mp_limb_t));
+ if (s.xp == NULL)
+ {
+ fprintf (stderr, "Can't allocate memory.\n");
+ abort ();
+ }
+ mpn_random (s.xp, size);
+ s.yp = s.xp + size;
+ mpn_random (s.yp, size);
+ t = speed_measure (func, &s);
+ if (t == -1.0)
+ {
+ fprintf (stderr, "Failed to measure function!\n");
+ abort ();
+ }
+ free (s.xp);
+ return t;
+}
+
+/* Tune a function with a simple THRESHOLD
+ The function doesn't depend on another threshold.
+ It assumes that it uses algo1 if p < THRESHOLD
+ and algo2 otherwise.
+ if algo2 is better for low prec, and algo1 better for high prec,
+ the behaviour of this function is undefined. */
+static void
+tune_simple_func (mpfr_prec_t *threshold,
+ double (*func) (struct speed_params *),
+ mpfr_prec_t pstart, mpfr_prec_t pend)
+{
+ double measure;
+ mpfr_prec_t p = pstart;
+ mp_size_t k, n;
+
+ while (p <= pend)
+ {
+ measure = domeasure (threshold, func, p);
+ printf ("prec=%lu mpfr_mul=%e ", p, measure);
+ n = 1 + (p - 1) / GMP_NUMB_BITS;
+ if (n <= MPFR_MUL_THRESHOLD)
+ k = MUL_FFT_THRESHOLD + 1;
+ else if (n < MPFR_MULHIGH_TAB_SIZE)
+ k = mulhigh_ktab[n];
+ else
+ k = 2*n/3;
+ if (k < 0)
+ printf ("[mpn_mul_basecase]\n");
+ else if (k == 0)
+ printf ("[mpfr_mulhigh_n_basecase]\n");
+ else if (k > MUL_FFT_THRESHOLD)
+ printf ("[mpn_mul_n]\n");
+ else
+ printf ("[mpfr_mulhigh_n]\n");
+ p = p + p / 10;
+ }
+}
+
+/*******************************************************
+ * Tune all the threshold of MPFR *
+ * Warning: tune the function in their dependent order!*
+ *******************************************************/
+static void
+all (void)
+{
+ FILE *f = stdout;
+ time_t start_time, end_time;
+ struct tm *tp;
+
+ speed_time_init ();
+ if (verbose) {
+ printf ("Using: %s\n", speed_time_string);
+ printf ("speed_precision %d", speed_precision);
+ if (speed_unittime == 1.0)
+ printf (", speed_unittime 1 cycle");
+ else
+ printf (", speed_unittime %.2e secs", speed_unittime);
+ if (speed_cycletime == 1.0 || speed_cycletime == 0.0)
+ printf (", CPU freq unknown\n");
+ else
+ printf (", CPU freq %.2f MHz\n\n", 1e-6/speed_cycletime);
+ }
+
+ time (&start_time);
+ tp = localtime (&start_time);
+ fprintf (f, "/* Generated by MPFR's tuneup.c, %d-%02d-%02d, ",
+ tp->tm_year+1900, tp->tm_mon+1, tp->tm_mday);
+
+#ifdef __ICC
+ fprintf (f, "icc %d.%d.%d */\n", __ICC / 100, __ICC / 10 % 10, __ICC % 10);
+#elif defined(__GNUC__)
+ fprintf (f, "gcc %d.%d */\n", __GNUC__, __GNUC_MINOR__);
+#elif defined (__SUNPRO_C)
+ fprintf (f, "Sun C %d.%d */\n", __SUNPRO_C / 0x100, __SUNPRO_C % 0x100);
+#elif defined (__sgi) && defined (_COMPILER_VERSION)
+ fprintf (f, "MIPSpro C %d.%d.%d */\n",
+ _COMPILER_VERSION / 100,
+ _COMPILER_VERSION / 10 % 10,
+ _COMPILER_VERSION % 10);
+#elif defined (__DECC) && defined (__DECC_VER)
+ fprintf (f, "DEC C %d */\n", __DECC_VER);
+#else
+ fprintf (f, "system compiler */\n");
+#endif
+ fprintf (f, "\n");
+
+ /* Tune mpfr_mul (threshold is in limbs, but it doesn't matter too much) */
+ if (verbose)
+ printf ("Measuring mpfr_mul with mpfr_mul_threshold=%lu...\n",
+ mpfr_mul_threshold);
+ tune_simple_func (&mpfr_mul_threshold, speed_mpfr_mul,
+ 2*GMP_NUMB_BITS+1, 1000);
+
+ /* End of tuning */
+ time (&end_time);
+ if (verbose)
+ printf ("Complete (took %ld seconds).\n", end_time - start_time);
+}
+
+
+/* Main function */
+int main (int argc, char *argv[])
+{
+ /* Unbuffered so if output is redirected to a file it isn't lost if the
+ program is killed part way through. */
+ setbuf (stdout, NULL);
+ setbuf (stderr, NULL);
+
+ verbose = argc > 1;
+
+ if (verbose)
+ printf ("Tuning MPFR (Coffee time?)...\n");
+
+ all ();
+
+ return 0;
+}
diff --git a/mpfr/tune/tuneup.c b/mpfr/tune/tuneup.c
new file mode 100644
index 0000000000..2f116338aa
--- /dev/null
+++ b/mpfr/tune/tuneup.c
@@ -0,0 +1,1187 @@
+/* Tune various threshold of MPFR
+
+Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+Contributed by the AriC and Caramel projects, INRIA.
+
+This file is part of the GNU MPFR Library.
+
+The GNU MPFR Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MPFR Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
+http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <stdlib.h>
+#include <time.h>
+
+#define MPFR_NEED_LONGLONG_H
+#include "mpfr-impl.h"
+
+#undef _PROTO
+#define _PROTO __GMP_PROTO
+#include "speed.h"
+
+int verbose;
+
+/* template for an unary function */
+/* s->size: precision of both input and output
+ s->xp : Mantissa of first input
+ s->yp : mantissa of second input */
+#define SPEED_MPFR_FUNC(mean_fun) \
+ do \
+ { \
+ unsigned i; \
+ mpfr_limb_ptr wp; \
+ double t; \
+ mpfr_t w, x; \
+ mp_size_t size; \
+ MPFR_TMP_DECL (marker); \
+ \
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN); \
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX); \
+ MPFR_TMP_MARK (marker); \
+ \
+ size = (s->size-1)/GMP_NUMB_BITS+1; \
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->xp, x, s->size); \
+ MPFR_SET_EXP (x, 0); \
+ \
+ MPFR_TMP_INIT (wp, w, s->size, size); \
+ \
+ speed_operand_src (s, s->xp, size); \
+ speed_operand_dst (s, wp, size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ mean_fun (w, x, MPFR_RNDN); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ MPFR_TMP_FREE (marker); \
+ return t; \
+ } \
+ while (0)
+
+/* same as SPEED_MPFR_FUNC, but for say mpfr_sin_cos (y, z, x, r) */
+#define SPEED_MPFR_FUNC2(mean_fun) \
+ do \
+ { \
+ unsigned i; \
+ mpfr_limb_ptr vp, wp; \
+ double t; \
+ mpfr_t v, w, x; \
+ mp_size_t size; \
+ MPFR_TMP_DECL (marker); \
+ \
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN); \
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX); \
+ MPFR_TMP_MARK (marker); \
+ \
+ size = (s->size-1)/GMP_NUMB_BITS+1; \
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->xp, x, s->size); \
+ MPFR_SET_EXP (x, 0); \
+ \
+ MPFR_TMP_INIT (vp, v, s->size, size); \
+ MPFR_TMP_INIT (wp, w, s->size, size); \
+ \
+ speed_operand_src (s, s->xp, size); \
+ speed_operand_dst (s, vp, size); \
+ speed_operand_dst (s, wp, size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ mean_fun (v, w, x, MPFR_RNDN); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ MPFR_TMP_FREE (marker); \
+ return t; \
+ } \
+ while (0)
+
+/* template for a function like mpfr_mul */
+#define SPEED_MPFR_OP(mean_fun) \
+ do \
+ { \
+ unsigned i; \
+ mpfr_limb_ptr wp; \
+ double t; \
+ mpfr_t w, x, y; \
+ mp_size_t size; \
+ MPFR_TMP_DECL (marker); \
+ \
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN); \
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX); \
+ MPFR_TMP_MARK (marker); \
+ \
+ size = (s->size-1)/GMP_NUMB_BITS+1; \
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->xp, x, s->size); \
+ MPFR_SET_EXP (x, 0); \
+ s->yp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->yp, y, s->size); \
+ MPFR_SET_EXP (y, 0); \
+ \
+ MPFR_TMP_INIT (wp, w, s->size, size); \
+ \
+ speed_operand_src (s, s->xp, size); \
+ speed_operand_src (s, s->yp, size); \
+ speed_operand_dst (s, wp, size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ mean_fun (w, x, y, MPFR_RNDN); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ MPFR_TMP_FREE (marker); \
+ return t; \
+ } \
+ while (0)
+
+/* special template for mpfr_mul(a,b,b) */
+#define SPEED_MPFR_SQR(mean_fun) \
+ do \
+ { \
+ unsigned i; \
+ mpfr_limb_ptr wp; \
+ double t; \
+ mpfr_t w, x; \
+ mp_size_t size; \
+ MPFR_TMP_DECL (marker); \
+ \
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN); \
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX); \
+ MPFR_TMP_MARK (marker); \
+ \
+ size = (s->size-1)/GMP_NUMB_BITS+1; \
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->xp, x, s->size); \
+ MPFR_SET_EXP (x, 0); \
+ \
+ MPFR_TMP_INIT (wp, w, s->size, size); \
+ \
+ speed_operand_src (s, s->xp, size); \
+ speed_operand_dst (s, wp, size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ mean_fun (w, x, x, MPFR_RNDN); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ MPFR_TMP_FREE (marker); \
+ return t; \
+ } \
+ while (0)
+
+/* s->size: precision of both input and output
+ s->xp : Mantissa of first input
+ s->r : exponent
+ s->align_xp : sign (1 means positive, 2 means negative)
+*/
+#define SPEED_MPFR_FUNC_WITH_EXPONENT(mean_fun) \
+ do \
+ { \
+ unsigned i; \
+ mpfr_limb_ptr wp; \
+ double t; \
+ mpfr_t w, x; \
+ mp_size_t size; \
+ MPFR_TMP_DECL (marker); \
+ \
+ SPEED_RESTRICT_COND (s->size >= MPFR_PREC_MIN); \
+ SPEED_RESTRICT_COND (s->size <= MPFR_PREC_MAX); \
+ MPFR_TMP_MARK (marker); \
+ \
+ size = (s->size-1)/GMP_NUMB_BITS+1; \
+ s->xp[size-1] |= MPFR_LIMB_HIGHBIT; \
+ MPFR_TMP_INIT1 (s->xp, x, s->size); \
+ MPFR_SET_EXP (x, s->r); \
+ if (s->align_xp == 2) MPFR_SET_NEG (x); \
+ \
+ MPFR_TMP_INIT (wp, w, s->size, size); \
+ \
+ speed_operand_src (s, s->xp, size); \
+ speed_operand_dst (s, wp, size); \
+ speed_cache_fill (s); \
+ \
+ speed_starttime (); \
+ i = s->reps; \
+ do \
+ mean_fun (w, x, MPFR_RNDN); \
+ while (--i != 0); \
+ t = speed_endtime (); \
+ \
+ MPFR_TMP_FREE (marker); \
+ return t; \
+ } \
+ while (0)
+
+/* First we include all the functions we want to tune inside this program.
+ We can't use the GNU MPFR library since the thresholds are fixed macros. */
+
+/* Setup mpfr_exp_2 */
+mpfr_prec_t mpfr_exp_2_threshold;
+#undef MPFR_EXP_2_THRESHOLD
+#define MPFR_EXP_2_THRESHOLD mpfr_exp_2_threshold
+#include "exp_2.c"
+static double
+speed_mpfr_exp_2 (struct speed_params *s)
+{
+ SPEED_MPFR_FUNC (mpfr_exp_2);
+}
+
+/* Setup mpfr_exp */
+mpfr_prec_t mpfr_exp_threshold;
+#undef MPFR_EXP_THRESHOLD
+#define MPFR_EXP_THRESHOLD mpfr_exp_threshold
+#include "exp.c"
+static double
+speed_mpfr_exp (struct speed_params *s)
+{
+ SPEED_MPFR_FUNC (mpfr_exp);
+}
+
+/* Setup mpfr_sin_cos */
+mpfr_prec_t mpfr_sincos_threshold;
+#undef MPFR_SINCOS_THRESHOLD
+#define MPFR_SINCOS_THRESHOLD mpfr_sincos_threshold
+#include "sin_cos.c"
+#include "cos.c"
+static double
+speed_mpfr_sincos (struct speed_params *s)
+{
+ SPEED_MPFR_FUNC2 (mpfr_sin_cos);
+}
+
+/* Setup mpfr_mul, mpfr_sqr and mpfr_div */
+mpfr_prec_t mpfr_mul_threshold;
+mpfr_prec_t mpfr_sqr_threshold;
+mpfr_prec_t mpfr_div_threshold;
+#undef MPFR_MUL_THRESHOLD
+#define MPFR_MUL_THRESHOLD mpfr_mul_threshold
+#undef MPFR_SQR_THRESHOLD
+#define MPFR_SQR_THRESHOLD mpfr_sqr_threshold
+#undef MPFR_DIV_THRESHOLD
+#define MPFR_DIV_THRESHOLD mpfr_div_threshold
+#include "mul.c"
+#include "div.c"
+static double
+speed_mpfr_mul (struct speed_params *s)
+{
+ SPEED_MPFR_OP (mpfr_mul);
+}
+static double
+speed_mpfr_sqr (struct speed_params *s)
+{
+ SPEED_MPFR_SQR (mpfr_mul);
+}
+static double
+speed_mpfr_div (struct speed_params *s)
+{
+ SPEED_MPFR_OP (mpfr_div);
+}
+
+/************************************************
+ * Common functions (inspired by GMP function) *
+ ************************************************/
+static int
+analyze_data (double *dat, int ndat)
+{
+ double x, min_x;
+ int j, min_j;
+
+ x = 0.0;
+ for (j = 0; j < ndat; j++)
+ if (dat[j] > 0.0)
+ x += dat[j];
+
+ min_x = x;
+ min_j = 0;
+
+ for (j = 0; j < ndat; x -= dat[j], j++)
+ {
+ if (x < min_x)
+ {
+ min_x = x;
+ min_j = j;
+ }
+ }
+ return min_j;
+}
+
+static double
+mpfr_speed_measure (speed_function_t fun, struct speed_params *s, char *m)
+{
+ double t = -1.0;
+ int i;
+ int number_of_iterations = 30;
+ for (i = 1; i <= number_of_iterations && t == -1.0; i++)
+ {
+ t = speed_measure (fun, s);
+ if ( (t == -1.0) && (i+1 <= number_of_iterations) )
+ printf("speed_measure failed for size %lu. Trying again... (%d/%d)\n",
+ s->size, i+1, number_of_iterations);
+ }
+ if (t == -1.0)
+ {
+ fprintf (stderr, "Failed to measure %s!\n", m);
+ fprintf (stderr, "If CPU frequency scaling is enabled, please disable it:\n");
+ fprintf (stderr, " under Linux: cpufreq-selector -g performance\n");
+ fprintf (stderr, "On a multi-core processor, you might also try to load all the cores\n");
+ abort ();
+ }
+ return t;
+}
+
+#define THRESHOLD_WINDOW 16
+#define THRESHOLD_FINAL_WINDOW 128
+static double
+domeasure (mpfr_prec_t *threshold,
+ double (*func) (struct speed_params *),
+ mpfr_prec_t p)
+{
+ struct speed_params s;
+ mp_size_t size;
+ double t1, t2, d;
+
+ s.align_xp = s.align_yp = s.align_wp = 64;
+ s.size = p;
+ size = (p - 1)/GMP_NUMB_BITS+1;
+ s.xp = malloc (2*size*sizeof (mp_limb_t));
+ if (s.xp == NULL)
+ {
+ fprintf (stderr, "Can't allocate memory.\n");
+ abort ();
+ }
+ mpn_random (s.xp, size);
+ s.yp = s.xp + size;
+ mpn_random (s.yp, size);
+ *threshold = MPFR_PREC_MAX;
+ t1 = mpfr_speed_measure (func, &s, "function 1");
+ *threshold = 1;
+ t2 = mpfr_speed_measure (func, &s, "function 2");
+ free (s.xp);
+ /* t1 is the time of the first algo (used for low prec) */
+ if (t2 >= t1)
+ d = (t2 - t1) / t2;
+ else
+ d = (t2 - t1) / t1;
+ /* d > 0 if we have to use algo 1.
+ d < 0 if we have to use algo 2 */
+ return d;
+}
+
+/* Performs measures when both the precision and the point of evaluation
+ shall vary. s.yp is ignored and not initialized.
+ It assumes that func depends on three thresholds with a boundary of the
+ form threshold1*x + threshold2*p = some scaling factor, if x<0,
+ and threshold3*x + threshold2*p = some scaling factor, if x>=0.
+*/
+static double
+domeasure2 (long int *threshold1, long int *threshold2, long int *threshold3,
+ double (*func) (struct speed_params *),
+ mpfr_prec_t p,
+ mpfr_t x)
+{
+ struct speed_params s;
+ mp_size_t size;
+ double t1, t2, d;
+ mpfr_t xtmp;
+
+ if (MPFR_IS_SINGULAR (x))
+ {
+ mpfr_fprintf (stderr, "x=%RNf is not a regular number.\n");
+ abort ();
+ }
+ if (MPFR_IS_NEG (x))
+ s.align_xp = 2;
+ else
+ s.align_xp = 1;
+
+ s.align_yp = s.align_wp = 64;
+ s.size = p;
+ size = (p - 1)/GMP_NUMB_BITS+1;
+
+ mpfr_init2 (xtmp, p);
+ mpn_random (xtmp->_mpfr_d, size);
+ xtmp->_mpfr_d[size-1] |= MPFR_LIMB_HIGHBIT;
+ MPFR_SET_EXP (xtmp, -53);
+ mpfr_add_ui (xtmp, xtmp, 1, MPFR_RNDN);
+ mpfr_mul (xtmp, xtmp, x, MPFR_RNDN); /* xtmp = x*(1+perturb) */
+ /* where perturb ~ 2^(-53) is */
+ /* randomly chosen. */
+ s.xp = xtmp->_mpfr_d;
+ s.r = MPFR_GET_EXP (xtmp);
+
+ *threshold1 = 0;
+ *threshold2 = 0;
+ *threshold3 = 0;
+ t1 = mpfr_speed_measure (func, &s, "function 1");
+
+ if (MPFR_IS_NEG (x))
+ *threshold1 = INT_MIN;
+ else
+ *threshold3 = INT_MAX;
+ *threshold2 = INT_MAX;
+ t2 = mpfr_speed_measure (func, &s, "function 2");
+
+ /* t1 is the time of the first algo (used for low prec) */
+ if (t2 >= t1)
+ d = (t2 - t1) / t2;
+ else
+ d = (t2 - t1) / t1;
+ /* d > 0 if we have to use algo 1.
+ d < 0 if we have to use algo 2 */
+ mpfr_clear (xtmp);
+ return d;
+}
+
+/* Tune a function with a simple THRESHOLD
+ The function doesn't depend on another threshold.
+ It assumes that it uses algo1 if p < THRESHOLD
+ and algo2 otherwise.
+ if algo2 is better for low prec, and algo1 better for high prec,
+ the behaviour of this function is undefined. */
+static void
+tune_simple_func (mpfr_prec_t *threshold,
+ double (*func) (struct speed_params *),
+ mpfr_prec_t pstart)
+{
+ double measure[THRESHOLD_FINAL_WINDOW+1];
+ double d;
+ mpfr_prec_t pstep;
+ int i, numpos, numneg, try;
+ mpfr_prec_t pmin, pmax, p;
+
+ /* first look for a lower bound within 10% */
+ pmin = p = pstart;
+ d = domeasure (threshold, func, pmin);
+ if (d < 0.0)
+ {
+ if (verbose)
+ printf ("Oops: even for %lu, algo 2 seems to be faster!\n",
+ (unsigned long) pmin);
+ *threshold = MPFR_PREC_MIN;
+ return;
+ }
+ if (d >= 1.00)
+ for (;;)
+ {
+ d = domeasure (threshold, func, pmin);
+ if (d < 1.00)
+ break;
+ p = pmin;
+ pmin += pmin/2;
+ }
+ pmin = p;
+ for (;;)
+ {
+ d = domeasure (threshold, func, pmin);
+ if (d < 0.10)
+ break;
+ pmin += GMP_NUMB_BITS;
+ }
+
+ /* then look for an upper bound within 20% */
+ pmax = pmin * 2;
+ for (;;)
+ {
+ d = domeasure (threshold, func, pmax);
+ if (d < -0.20)
+ break;
+ pmax += pmin / 2; /* don't increase too rapidly */
+ }
+
+ /* The threshold is between pmin and pmax. Affine them */
+ try = 0;
+ while ((pmax-pmin) >= THRESHOLD_FINAL_WINDOW)
+ {
+ pstep = MAX(MIN(GMP_NUMB_BITS/2,(pmax-pmin)/(2*THRESHOLD_WINDOW)),1);
+ if (verbose)
+ printf ("Pmin = %8lu Pmax = %8lu Pstep=%lu\n", pmin, pmax, pstep);
+ p = (pmin + pmax) / 2;
+ for (i = numpos = numneg = 0 ; i < THRESHOLD_WINDOW + 1 ; i++)
+ {
+ measure[i] = domeasure (threshold, func,
+ p+(i-THRESHOLD_WINDOW/2)*pstep);
+ if (measure[i] > 0)
+ numpos ++;
+ else if (measure[i] < 0)
+ numneg ++;
+ }
+ if (numpos > numneg)
+ /* We use more often algo 1 than algo 2 */
+ pmin = p - THRESHOLD_WINDOW/2*pstep;
+ else if (numpos < numneg)
+ pmax = p + THRESHOLD_WINDOW/2*pstep;
+ else
+ /* numpos == numneg ... */
+ if (++ try > 2)
+ {
+ *threshold = p;
+ if (verbose)
+ printf ("Quick find: %lu\n", *threshold);
+ return ;
+ }
+ }
+
+ /* Final tune... */
+ if (verbose)
+ printf ("Finalizing in [%lu, %lu]... ", pmin, pmax);
+ for (i = 0 ; i < THRESHOLD_FINAL_WINDOW+1 ; i++)
+ measure[i] = domeasure (threshold, func, pmin+i);
+ i = analyze_data (measure, THRESHOLD_FINAL_WINDOW+1);
+ *threshold = pmin + i;
+ if (verbose)
+ printf ("%lu\n", *threshold);
+ return;
+}
+
+/* Tune a function which behavior depends on both p and x,
+ in a given direction.
+ It assumes that for (x,p) close to zero, algo1 is used
+ and algo2 is used when (x,p) is far from zero.
+ If algo2 is better for low prec, and algo1 better for high prec,
+ the behaviour of this function is undefined.
+ This tuning function tries couples (x,p) of the form (ell*dirx, ell*dirp)
+ until it finds a point on the boundary. It returns ell.
+ */
+static void
+tune_simple_func_in_some_direction (long int *threshold1,
+ long int *threshold2,
+ long int *threshold3,
+ double (*func) (struct speed_params *),
+ mpfr_prec_t pstart,
+ int dirx, int dirp,
+ mpfr_t xres, mpfr_prec_t *pres)
+{
+ double measure[THRESHOLD_FINAL_WINDOW+1];
+ double d;
+ mpfr_prec_t pstep;
+ int i, numpos, numneg, try;
+ mpfr_prec_t pmin, pmax, p;
+ mpfr_t xmin, xmax, x;
+ mpfr_t ratio;
+
+ mpfr_init2 (ratio, MPFR_SMALL_PRECISION);
+ mpfr_set_si (ratio, dirx, MPFR_RNDN);
+ mpfr_div_si (ratio, ratio, dirp, MPFR_RNDN);
+
+ mpfr_init2 (xmin, MPFR_SMALL_PRECISION);
+ mpfr_init2 (xmax, MPFR_SMALL_PRECISION);
+ mpfr_init2 (x, MPFR_SMALL_PRECISION);
+
+ /* first look for a lower bound within 10% */
+ pmin = p = pstart;
+ mpfr_mul_ui (xmin, ratio, (unsigned int)pmin, MPFR_RNDN);
+ mpfr_set (x, xmin, MPFR_RNDN);
+
+ d = domeasure2 (threshold1, threshold2, threshold3, func, pmin, xmin);
+ if (d < 0.0)
+ {
+ if (verbose)
+ printf ("Oops: even for %lu, algo 2 seems to be faster!\n",
+ (unsigned long) pmin);
+ *pres = MPFR_PREC_MIN;
+ mpfr_mul_ui (xres, ratio, (unsigned int)*pres, MPFR_RNDN);
+ mpfr_clear (ratio); mpfr_clear (x); mpfr_clear (xmin); mpfr_clear (xmax);
+ return;
+ }
+ if (d >= 1.00)
+ for (;;)
+ {
+ d = domeasure2 (threshold1, threshold2, threshold3, func, pmin, xmin);
+ if (d < 1.00)
+ break;
+ p = pmin;
+ mpfr_set (x, xmin, MPFR_RNDN);
+ pmin += pmin/2;
+ mpfr_mul_ui (xmin, ratio, (unsigned int)pmin, MPFR_RNDN);
+ }
+ pmin = p;
+ mpfr_set (xmin, x, MPFR_RNDN);
+ for (;;)
+ {
+ d = domeasure2 (threshold1, threshold2, threshold3, func, pmin, xmin);
+ if (d < 0.10)
+ break;
+ pmin += GMP_NUMB_BITS;
+ mpfr_mul_ui (xmin, ratio, (unsigned int)pmin, MPFR_RNDN);
+ }
+
+ /* then look for an upper bound within 20% */
+ pmax = pmin * 2;
+ mpfr_mul_ui (xmax, ratio, (unsigned int)pmax, MPFR_RNDN);
+ for (;;)
+ {
+ d = domeasure2 (threshold1, threshold2, threshold3, func, pmax, xmax);
+ if (d < -0.20)
+ break;
+ pmax += pmin / 2; /* don't increase too rapidly */
+ mpfr_mul_ui (xmax, ratio, (unsigned int)pmax, MPFR_RNDN);
+ }
+
+ /* The threshold is between pmin and pmax. Affine them */
+ try = 0;
+ while ((pmax-pmin) >= THRESHOLD_FINAL_WINDOW)
+ {
+ pstep = MAX(MIN(GMP_NUMB_BITS/2,(pmax-pmin)/(2*THRESHOLD_WINDOW)),1);
+ if (verbose)
+ printf ("Pmin = %8lu Pmax = %8lu Pstep=%lu\n", pmin, pmax, pstep);
+ p = (pmin + pmax) / 2;
+ mpfr_mul_ui (x, ratio, (unsigned int)p, MPFR_RNDN);
+ for (i = numpos = numneg = 0 ; i < THRESHOLD_WINDOW + 1 ; i++)
+ {
+ *pres = p+(i-THRESHOLD_WINDOW/2)*pstep;
+ mpfr_mul_ui (xres, ratio, (unsigned int)*pres, MPFR_RNDN);
+ measure[i] = domeasure2 (threshold1, threshold2, threshold3,
+ func, *pres, xres);
+ if (measure[i] > 0)
+ numpos ++;
+ else if (measure[i] < 0)
+ numneg ++;
+ }
+ if (numpos > numneg)
+ {
+ /* We use more often algo 1 than algo 2 */
+ pmin = p - THRESHOLD_WINDOW/2*pstep;
+ mpfr_mul_ui (xmin, ratio, (unsigned int)pmin, MPFR_RNDN);
+ }
+ else if (numpos < numneg)
+ {
+ pmax = p + THRESHOLD_WINDOW/2*pstep;
+ mpfr_mul_ui (xmax, ratio, (unsigned int)pmax, MPFR_RNDN);
+ }
+ else
+ /* numpos == numneg ... */
+ if (++ try > 2)
+ {
+ *pres = p;
+ mpfr_mul_ui (xres, ratio, (unsigned int)*pres, MPFR_RNDN);
+ if (verbose)
+ printf ("Quick find: %lu\n", *pres);
+ mpfr_clear (ratio);
+ mpfr_clear (x); mpfr_clear (xmin); mpfr_clear (xmax);
+ return ;
+ }
+ }
+
+ /* Final tune... */
+ if (verbose)
+ printf ("Finalizing in [%lu, %lu]... ", pmin, pmax);
+ for (i = 0 ; i < THRESHOLD_FINAL_WINDOW+1 ; i++)
+ {
+ *pres = pmin+i;
+ mpfr_mul_ui (xres, ratio, (unsigned int)*pres, MPFR_RNDN);
+ measure[i] = domeasure2 (threshold1, threshold2, threshold3,
+ func, *pres, xres);
+ }
+ i = analyze_data (measure, THRESHOLD_FINAL_WINDOW+1);
+ *pres = pmin + i;
+ mpfr_mul_ui (xres, ratio, (unsigned int)*pres, MPFR_RNDN);
+ if (verbose)
+ printf ("%lu\n", *pres);
+ mpfr_clear (ratio); mpfr_clear (x); mpfr_clear (xmin); mpfr_clear (xmax);
+ return;
+}
+
+/************************************
+ * Tune Mulders' mulhigh function *
+ ************************************/
+#define TOLERANCE 1.00
+#define MULDERS_TABLE_SIZE 1024
+#ifndef MPFR_MULHIGH_SIZE
+# define MPFR_MULHIGH_SIZE MULDERS_TABLE_SIZE
+#endif
+#ifndef MPFR_SQRHIGH_SIZE
+# define MPFR_SQRHIGH_SIZE MULDERS_TABLE_SIZE
+#endif
+#ifndef MPFR_DIVHIGH_SIZE
+# define MPFR_DIVHIGH_SIZE MULDERS_TABLE_SIZE
+#endif
+#define MPFR_MULHIGH_TAB_SIZE MPFR_MULHIGH_SIZE
+#define MPFR_SQRHIGH_TAB_SIZE MPFR_SQRHIGH_SIZE
+#define MPFR_DIVHIGH_TAB_SIZE MPFR_DIVHIGH_SIZE
+#include "mulders.c"
+
+static double
+speed_mpfr_mulhigh (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_MUL_N (mpfr_mulhigh_n);
+}
+
+static double
+speed_mpfr_sqrhigh (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_SQR (mpfr_sqrhigh_n);
+}
+
+static double
+speed_mpfr_divhigh (struct speed_params *s)
+{
+ SPEED_ROUTINE_MPN_DC_DIVREM_CALL (mpfr_divhigh_n (q, a, d, s->size));
+}
+
+#define MAX_STEPS 513 /* maximum number of values of k tried for a given n */
+
+/* Tune mpfr_mulhigh_n for size n */
+static mp_size_t
+tune_mul_mulders_upto (mp_size_t n)
+{
+ struct speed_params s;
+ mp_size_t k, kbest, step;
+ double t, tbest;
+ MPFR_TMP_DECL (marker);
+
+ if (n == 0)
+ return -1;
+
+ MPFR_TMP_MARK (marker);
+ s.align_xp = s.align_yp = s.align_wp = 64;
+ s.size = n;
+ s.xp = MPFR_TMP_ALLOC (n * sizeof (mp_limb_t));
+ s.yp = MPFR_TMP_ALLOC (n * sizeof (mp_limb_t));
+ mpn_random (s.xp, n);
+ mpn_random (s.yp, n);
+
+ /* Check k == -1, mpn_mul_basecase */
+ mulhigh_ktab[n] = -1;
+ kbest = -1;
+ tbest = mpfr_speed_measure (speed_mpfr_mulhigh, &s, "mpfr_mulhigh");
+
+ /* Check k == 0, mpn_mulhigh_n_basecase */
+ mulhigh_ktab[n] = 0;
+ t = mpfr_speed_measure (speed_mpfr_mulhigh, &s, "mpfr_mulhigh");
+ if (t * TOLERANCE < tbest)
+ kbest = 0, tbest = t;
+
+ /* Check Mulders with cutoff point k */
+ step = 1 + n / (2 * MAX_STEPS);
+ /* we need k >= (n+3)/2, which translates into k >= (n+4)/2 in C */
+ for (k = (n + 4) / 2 ; k < n ; k += step)
+ {
+ mulhigh_ktab[n] = k;
+ t = mpfr_speed_measure (speed_mpfr_mulhigh, &s, "mpfr_mulhigh");
+ if (t * TOLERANCE < tbest)
+ kbest = k, tbest = t;
+ }
+
+ mulhigh_ktab[n] = kbest;
+
+ MPFR_TMP_FREE (marker);
+ return kbest;
+}
+
+/* Tune mpfr_sqrhigh_n for size n */
+static mp_size_t
+tune_sqr_mulders_upto (mp_size_t n)
+{
+ struct speed_params s;
+ mp_size_t k, kbest, step;
+ double t, tbest;
+ MPFR_TMP_DECL (marker);
+
+ if (n == 0)
+ return -1;
+
+ MPFR_TMP_MARK (marker);
+ s.align_xp = s.align_wp = 64;
+ s.size = n;
+ s.xp = MPFR_TMP_ALLOC (n * sizeof (mp_limb_t));
+ mpn_random (s.xp, n);
+
+ /* Check k == -1, mpn_sqr_basecase */
+ sqrhigh_ktab[n] = -1;
+ kbest = -1;
+ tbest = mpfr_speed_measure (speed_mpfr_sqrhigh, &s, "mpfr_sqrhigh");
+
+ /* Check k == 0, mpfr_mulhigh_n_basecase */
+ sqrhigh_ktab[n] = 0;
+ t = mpfr_speed_measure (speed_mpfr_sqrhigh, &s, "mpfr_sqrhigh");
+ if (t * TOLERANCE < tbest)
+ kbest = 0, tbest = t;
+
+ /* Check Mulders */
+ step = 1 + n / (2 * MAX_STEPS);
+ /* we need k >= (n+3)/2, which translates into k >= (n+4)/2 in C */
+ for (k = (n + 4) / 2 ; k < n ; k += step)
+ {
+ sqrhigh_ktab[n] = k;
+ t = mpfr_speed_measure (speed_mpfr_sqrhigh, &s, "mpfr_sqrhigh");
+ if (t * TOLERANCE < tbest)
+ kbest = k, tbest = t;
+ }
+
+ sqrhigh_ktab[n] = kbest;
+
+ MPFR_TMP_FREE (marker);
+ return kbest;
+}
+
+/* Tune mpfr_divhigh_n for size n */
+static mp_size_t
+tune_div_mulders_upto (mp_size_t n)
+{
+ struct speed_params s;
+ mp_size_t k, kbest, step;
+ double t, tbest;
+ MPFR_TMP_DECL (marker);
+
+ if (n == 0)
+ return 0;
+
+ MPFR_TMP_MARK (marker);
+ s.align_xp = s.align_yp = s.align_wp = s.align_wp2 = 64;
+ s.size = n;
+ s.xp = MPFR_TMP_ALLOC (n * sizeof (mp_limb_t));
+ s.yp = MPFR_TMP_ALLOC (n * sizeof (mp_limb_t));
+ mpn_random (s.xp, n);
+ mpn_random (s.yp, n);
+
+ /* Check k == n, i.e., mpn_divrem */
+ divhigh_ktab[n] = n;
+ kbest = n;
+ tbest = mpfr_speed_measure (speed_mpfr_divhigh, &s, "mpfr_divhigh");
+
+ /* Check k == 0, i.e., mpfr_divhigh_n_basecase */
+#if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_SBPI1_DIVAPPR_Q)
+ if (n > 2) /* mpn_sbpi1_divappr_q requires dn > 2 */
+#endif
+ {
+ divhigh_ktab[n] = 0;
+ t = mpfr_speed_measure (speed_mpfr_divhigh, &s, "mpfr_divhigh");
+ if (t * TOLERANCE < tbest)
+ kbest = 0, tbest = t;
+ }
+
+ /* Check Mulders */
+ step = 1 + n / (2 * MAX_STEPS);
+ /* we should have (n+3)/2 <= k < n, which translates into
+ (n+4)/2 <= k < n in C */
+ for (k = (n + 4) / 2 ; k < n ; k += step)
+ {
+ divhigh_ktab[n] = k;
+ t = mpfr_speed_measure (speed_mpfr_divhigh, &s, "mpfr_divhigh");
+ if (t * TOLERANCE < tbest)
+ kbest = k, tbest = t;
+ }
+
+ divhigh_ktab[n] = kbest;
+
+ MPFR_TMP_FREE (marker);
+
+ return kbest;
+}
+
+static void
+tune_mul_mulders (FILE *f)
+{
+ mp_size_t k;
+
+ if (verbose)
+ printf ("Tuning mpfr_mulhigh_n[%d]", (int) MPFR_MULHIGH_TAB_SIZE);
+ fprintf (f, "#define MPFR_MULHIGH_TAB \\\n ");
+ for (k = 0 ; k < MPFR_MULHIGH_TAB_SIZE ; k++)
+ {
+ fprintf (f, "%d", (int) tune_mul_mulders_upto (k));
+ if (k != MPFR_MULHIGH_TAB_SIZE-1)
+ fputc (',', f);
+ if ((k+1) % 16 == 0)
+ fprintf (f, " \\\n ");
+ if (verbose)
+ putchar ('.');
+ }
+ fprintf (f, " \n");
+ if (verbose)
+ putchar ('\n');
+}
+
+static void
+tune_sqr_mulders (FILE *f)
+{
+ mp_size_t k;
+
+ if (verbose)
+ printf ("Tuning mpfr_sqrhigh_n[%d]", (int) MPFR_SQRHIGH_TAB_SIZE);
+ fprintf (f, "#define MPFR_SQRHIGH_TAB \\\n ");
+ for (k = 0 ; k < MPFR_SQRHIGH_TAB_SIZE ; k++)
+ {
+ fprintf (f, "%d", (int) tune_sqr_mulders_upto (k));
+ if (k != MPFR_SQRHIGH_TAB_SIZE-1)
+ fputc (',', f);
+ if ((k+1) % 16 == 0)
+ fprintf (f, " \\\n ");
+ if (verbose)
+ putchar ('.');
+ }
+ fprintf (f, " \n");
+ if (verbose)
+ putchar ('\n');
+}
+
+static void
+tune_div_mulders (FILE *f)
+{
+ mp_size_t k;
+
+ if (verbose)
+ printf ("Tuning mpfr_divhigh_n[%d]", (int) MPFR_DIVHIGH_TAB_SIZE);
+ fprintf (f, "#define MPFR_DIVHIGH_TAB \\\n ");
+ for (k = 0 ; k < MPFR_DIVHIGH_TAB_SIZE ; k++)
+ {
+ fprintf (f, "%d", (int) tune_div_mulders_upto (k));
+ if (k != MPFR_DIVHIGH_TAB_SIZE - 1)
+ fputc (',', f);
+ if ((k+1) % 16 == 0)
+ fprintf (f, " /*%zu-%zu*/ \\\n ", k - 15, k);
+ if (verbose)
+ putchar ('.');
+ }
+ fprintf (f, " \n");
+ if (verbose)
+ putchar ('\n');
+}
+
+/*******************************************************
+ * Tuning functions for mpfr_ai *
+ *******************************************************/
+
+long int mpfr_ai_threshold1;
+long int mpfr_ai_threshold2;
+long int mpfr_ai_threshold3;
+#undef MPFR_AI_THRESHOLD1
+#define MPFR_AI_THRESHOLD1 mpfr_ai_threshold1
+#undef MPFR_AI_THRESHOLD2
+#define MPFR_AI_THRESHOLD2 mpfr_ai_threshold2
+#undef MPFR_AI_THRESHOLD3
+#define MPFR_AI_THRESHOLD3 mpfr_ai_threshold3
+
+#include "ai.c"
+
+static double
+speed_mpfr_ai (struct speed_params *s)
+{
+ SPEED_MPFR_FUNC_WITH_EXPONENT (mpfr_ai);
+}
+
+
+/*******************************************************
+ * Tune all the threshold of MPFR *
+ * Warning: tune the function in their dependent order!*
+ *******************************************************/
+static void
+all (const char *filename)
+{
+ FILE *f;
+ time_t start_time, end_time;
+ struct tm *tp;
+ mpfr_t x1, x2, x3, tmp1, tmp2;
+ mpfr_prec_t p1, p2, p3;
+
+ f = fopen (filename, "w");
+ if (f == NULL)
+ {
+ fprintf (stderr, "Can't open file '%s' for writing.\n", filename);
+ abort ();
+ }
+
+ speed_time_init ();
+ if (verbose)
+ {
+ printf ("Using: %s\n", speed_time_string);
+ printf ("speed_precision %d", speed_precision);
+ if (speed_unittime == 1.0)
+ printf (", speed_unittime 1 cycle");
+ else
+ printf (", speed_unittime %.2e secs", speed_unittime);
+ if (speed_cycletime == 1.0 || speed_cycletime == 0.0)
+ printf (", CPU freq unknown\n");
+ else
+ printf (", CPU freq %.2f MHz\n\n", 1e-6/speed_cycletime);
+ }
+
+ time (&start_time);
+ tp = localtime (&start_time);
+ fprintf (f, "/* Generated by MPFR's tuneup.c, %d-%02d-%02d, ",
+ tp->tm_year+1900, tp->tm_mon+1, tp->tm_mday);
+
+#ifdef __ICC
+ fprintf (f, "icc %d.%d.%d */\n", __ICC / 100, __ICC / 10 % 10, __ICC % 10);
+#elif defined(__GNUC__)
+#ifdef __GNUC_PATCHLEVEL__
+ fprintf (f, "gcc %d.%d.%d */\n", __GNUC__, __GNUC_MINOR__,
+ __GNUC_PATCHLEVEL__);
+#else
+ fprintf (f, "gcc %d.%d */\n", __GNUC__, __GNUC_MINOR__);
+#endif
+#elif defined (__SUNPRO_C)
+ fprintf (f, "Sun C %d.%d */\n", __SUNPRO_C / 0x100, __SUNPRO_C % 0x100);
+#elif defined (__sgi) && defined (_COMPILER_VERSION)
+ fprintf (f, "MIPSpro C %d.%d.%d */\n",
+ _COMPILER_VERSION / 100,
+ _COMPILER_VERSION / 10 % 10,
+ _COMPILER_VERSION % 10);
+#elif defined (__DECC) && defined (__DECC_VER)
+ fprintf (f, "DEC C %d */\n", __DECC_VER);
+#else
+ fprintf (f, "system compiler */\n");
+#endif
+ fprintf (f, "\n\n");
+ fprintf (f, "#ifndef MPFR_TUNE_CASE\n");
+ fprintf (f, "#define MPFR_TUNE_CASE \"src/mparam.h\"\n");
+ fprintf (f, "#endif\n\n");
+
+ /* Tune mulhigh */
+ tune_mul_mulders (f);
+
+ /* Tune sqrhigh */
+ tune_sqr_mulders (f);
+
+ /* Tune divhigh */
+ tune_div_mulders (f);
+ fflush (f);
+
+ /* Tune mpfr_mul (threshold is in limbs, but it doesn't matter too much) */
+ if (verbose)
+ printf ("Tuning mpfr_mul...\n");
+ tune_simple_func (&mpfr_mul_threshold, speed_mpfr_mul,
+ 2*GMP_NUMB_BITS+1);
+ fprintf (f, "#define MPFR_MUL_THRESHOLD %lu /* limbs */\n",
+ (unsigned long) (mpfr_mul_threshold - 1) / GMP_NUMB_BITS + 1);
+
+ /* Tune mpfr_sqr (threshold is in limbs, but it doesn't matter too much) */
+ if (verbose)
+ printf ("Tuning mpfr_sqr...\n");
+ tune_simple_func (&mpfr_sqr_threshold, speed_mpfr_sqr,
+ 2*GMP_NUMB_BITS+1);
+ fprintf (f, "#define MPFR_SQR_THRESHOLD %lu /* limbs */\n",
+ (unsigned long) (mpfr_sqr_threshold - 1) / GMP_NUMB_BITS + 1);
+
+ /* Tune mpfr_div (threshold is in limbs, but it doesn't matter too much) */
+ if (verbose)
+ printf ("Tuning mpfr_div...\n");
+ tune_simple_func (&mpfr_div_threshold, speed_mpfr_div,
+ 2*GMP_NUMB_BITS+1);
+ fprintf (f, "#define MPFR_DIV_THRESHOLD %lu /* limbs */\n",
+ (unsigned long) (mpfr_div_threshold - 1) / GMP_NUMB_BITS + 1);
+
+ /* Tune mpfr_exp_2 */
+ if (verbose)
+ printf ("Tuning mpfr_exp_2...\n");
+ tune_simple_func (&mpfr_exp_2_threshold, speed_mpfr_exp_2, GMP_NUMB_BITS);
+ fprintf (f, "#define MPFR_EXP_2_THRESHOLD %lu /* bits */\n",
+ (unsigned long) mpfr_exp_2_threshold);
+
+ /* Tune mpfr_exp */
+ if (verbose)
+ printf ("Tuning mpfr_exp...\n");
+ tune_simple_func (&mpfr_exp_threshold, speed_mpfr_exp,
+ MPFR_PREC_MIN+3*GMP_NUMB_BITS);
+ fprintf (f, "#define MPFR_EXP_THRESHOLD %lu /* bits */\n",
+ (unsigned long) mpfr_exp_threshold);
+
+ /* Tune mpfr_sin_cos */
+ if (verbose)
+ printf ("Tuning mpfr_sin_cos...\n");
+ tune_simple_func (&mpfr_sincos_threshold, speed_mpfr_sincos,
+ MPFR_PREC_MIN+3*GMP_NUMB_BITS);
+ fprintf (f, "#define MPFR_SINCOS_THRESHOLD %lu /* bits */\n",
+ (unsigned long) mpfr_sincos_threshold);
+
+ /* Tune mpfr_ai */
+ if (verbose)
+ printf ("Tuning mpfr_ai...\n");
+ mpfr_init2 (x1, MPFR_SMALL_PRECISION);
+ mpfr_init2 (x2, MPFR_SMALL_PRECISION);
+ mpfr_init2 (x3, MPFR_SMALL_PRECISION);
+ mpfr_init2 (tmp1, MPFR_SMALL_PRECISION);
+ mpfr_init2 (tmp2, MPFR_SMALL_PRECISION);
+
+ tune_simple_func_in_some_direction (&mpfr_ai_threshold1, &mpfr_ai_threshold2,
+ &mpfr_ai_threshold3, speed_mpfr_ai,
+ MPFR_PREC_MIN+GMP_NUMB_BITS,
+ -60, 200, x1, &p1);
+ tune_simple_func_in_some_direction (&mpfr_ai_threshold1, &mpfr_ai_threshold2,
+ &mpfr_ai_threshold3, speed_mpfr_ai,
+ MPFR_PREC_MIN+GMP_NUMB_BITS,
+ -20, 500, x2, &p2);
+ tune_simple_func_in_some_direction (&mpfr_ai_threshold1, &mpfr_ai_threshold2,
+ &mpfr_ai_threshold3, speed_mpfr_ai,
+ MPFR_PREC_MIN+GMP_NUMB_BITS,
+ 40, 200, x3, &p3);
+
+ mpfr_mul_ui (tmp1, x2, (unsigned long)p1, MPFR_RNDN);
+ mpfr_mul_ui (tmp2, x1, (unsigned long)p2, MPFR_RNDN);
+ mpfr_sub (tmp1, tmp1, tmp2, MPFR_RNDN);
+ mpfr_div_ui (tmp1, tmp1, MPFR_AI_SCALE, MPFR_RNDN);
+
+ mpfr_set_ui (tmp2, (unsigned long)p1, MPFR_RNDN);
+ mpfr_sub_ui (tmp2, tmp2, (unsigned long)p2, MPFR_RNDN);
+ mpfr_div (tmp2, tmp2, tmp1, MPFR_RNDN);
+ mpfr_ai_threshold1 = mpfr_get_si (tmp2, MPFR_RNDN);
+
+ mpfr_sub (tmp2, x2, x1, MPFR_RNDN);
+ mpfr_div (tmp2, tmp2, tmp1, MPFR_RNDN);
+ mpfr_ai_threshold2 = mpfr_get_si (tmp2, MPFR_RNDN);
+
+ mpfr_set_ui (tmp1, (unsigned long)p3, MPFR_RNDN);
+ mpfr_mul_si (tmp1, tmp1, mpfr_ai_threshold2, MPFR_RNDN);
+ mpfr_ui_sub (tmp1, MPFR_AI_SCALE, tmp1, MPFR_RNDN);
+ mpfr_div (tmp1, tmp1, x3, MPFR_RNDN);
+ mpfr_ai_threshold3 = mpfr_get_si (tmp1, MPFR_RNDN);
+
+ fprintf (f, "#define MPFR_AI_THRESHOLD1 %ld /* threshold for negative input of mpfr_ai */\n", mpfr_ai_threshold1);
+ fprintf (f, "#define MPFR_AI_THRESHOLD2 %ld\n", mpfr_ai_threshold2);
+ fprintf (f, "#define MPFR_AI_THRESHOLD3 %ld\n", mpfr_ai_threshold3);
+
+ mpfr_clear (x1); mpfr_clear (x2); mpfr_clear (x3);
+ mpfr_clear (tmp1); mpfr_clear (tmp2);
+
+ /* End of tuning */
+ time (&end_time);
+ fprintf (f, "/* Tuneup completed successfully, took %ld seconds */\n",
+ (long) (end_time - start_time));
+ if (verbose)
+ printf ("Complete (took %ld seconds).\n", (long) (end_time - start_time));
+
+ fclose (f);
+}
+
+
+/* Main function */
+int main (int argc, char *argv[])
+{
+ /* Unbuffered so if output is redirected to a file it isn't lost if the
+ program is killed part way through. */
+ setbuf (stdout, NULL);
+ setbuf (stderr, NULL);
+
+ verbose = argc > 1;
+
+ if (verbose)
+ printf ("Tuning MPFR (Coffee time?)...\n");
+
+ all ("mparam.h");
+
+ return 0;
+}